././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1646921593.319265 astropy-5.0.2/0000755000175100001710000000000000000000000012245 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/.astropy-root0000644000175100001710000000000000000000000014716 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1646921593.071243 astropy-5.0.2/.circleci/0000755000175100001710000000000000000000000014100 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/.circleci/config.yml0000644000175100001710000000266400000000000016100 0ustar00vstsdockerversion: 2 # NOTE: We run these in CircleCI because it has better artifacts support # and it is possible to publish image diffs as HTML like pytest-mpl in the future. jobs: image-tests-mpl311: docker: - image: circleci/python:3.9 steps: - checkout - run: name: Install dependencies command: | sudo apt install texlive texlive-latex-extra texlive-fonts-recommended dvipng cm-super pip install pip tox --upgrade - run: name: Run tests command: tox -e py39-test-image-mpl311 -- -P visualization --remote-data=astropy --open-files --mpl --mpl-results-path=$PWD/results -W ignore:np.asscalar -W ignore::DeprecationWarning -k "not test_no_numpy_warnings" - store_artifacts: path: results image-tests-mpldev: docker: - image: circleci/python:3.9 steps: - checkout - run: name: Install dependencies command: | sudo apt install texlive texlive-latex-extra texlive-fonts-recommended dvipng cm-super pip install pip tox --upgrade - run: name: Run tests command: tox -e py39-test-image-mpldev -- -P visualization --remote-data=astropy --open-files --mpl-results-path=$PWD/results -W ignore:np.asscalar - store_artifacts: path: results workflows: version: 2 tests: jobs: - image-tests-mpl311 - image-tests-mpldev ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/.gitattributes0000644000175100001710000000002000000000000015130 0ustar00vstsdocker*.fits -text ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1646921593.071243 astropy-5.0.2/.github/0000755000175100001710000000000000000000000013605 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1646921593.071243 astropy-5.0.2/.github/ISSUE_TEMPLATE/0000755000175100001710000000000000000000000015770 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/.github/ISSUE_TEMPLATE/bug_report.md0000644000175100001710000000401600000000000020463 0ustar00vstsdocker--- name: Bug report about: Create a report describing unexpected or incorrect behavior in astropy. labels: Bug --- ### Description ### Expected behavior ### Actual behavior ### Steps to Reproduce 1. [First Step] 2. [Second Step] 3. [and so on...] ```python # Put your Python code snippet here. ``` ### System Details ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/.github/ISSUE_TEMPLATE/feature_request.md0000644000175100001710000000201000000000000021506 0ustar00vstsdocker--- name: Feature request about: Suggest an idea to improve astropy labels: "Feature Request" --- ### Description ### Additional context ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/.github/PULL_REQUEST_TEMPLATE.md0000644000175100001710000000754600000000000017422 0ustar00vstsdocker ### Description This pull request is to address ... Fixes # ### Checklist for package maintainer(s) This checklist is meant to remind the package maintainer(s) who will review this pull request of some common things to look for. This list is not exhaustive. - [ ] Do the proposed changes actually accomplish desired goals? - [ ] Do the proposed changes follow the [Astropy coding guidelines](https://docs.astropy.org/en/latest/development/codeguide.html)? - [ ] Are tests added/updated as required? If so, do they follow the [Astropy testing guidelines](https://docs.astropy.org/en/latest/development/testguide.html)? - [ ] Are docs added/updated as required? If so, do they follow the [Astropy documentation guidelines](https://docs.astropy.org/en/latest/development/docguide.html#astropy-documentation-rules-and-guidelines)? - [ ] Is rebase and/or squash necessary? If so, please provide the author with appropriate instructions. Also see ["When to rebase and squash commits"](https://docs.astropy.org/en/latest/development/when_to_rebase.html). - [ ] Did the CI pass? If no, are the failures related? If you need to run daily and weekly cron jobs as part of the PR, please apply the `Extra CI` label. - [ ] Is a change log needed? If yes, did the change log check pass? If no, add the `no-changelog-entry-needed` label. If this is a manual backport, use the `skip-changelog-checks` label unless special changelog handling is necessary. - [ ] Is a milestone set? Milestone must be set but `astropy-bot` check might be missing; do not let the green checkmark fool you. - [ ] At the time of adding the milestone, if the milestone set requires a backport to release branch(es), apply the appropriate `backport-X.Y.x` label(s) *before* merge. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/.github/labeler.yml0000644000175100001710000000445200000000000015743 0ustar00vstsdockerDocs: - docs/* - docs/_static/* - docs/_templates/* - docs/development/**/* - docs/whatsnew/* - examples/**/* - licenses/* - CITATION - .mailmap - readthedocs.yml - '*.md' - any: ['*.rst', '!CHANGES.rst'] testing: - astropy/tests/**/* - codecov.yml - conftest.py - '**/conftest.py' - azure-pipelines.yml - tox.ini - .circleci/* - .github/**/*.yml - .pep8speaks.yml - .pyinstaller/**/* external: - astropy/extern/**/* - cextern/**/* installation: - docs/install.rst - MANIFEST.in - pip-requirements - pyproject.toml - setup.* Release: - docs/development/releasing.rst config: - '**/config/**/*' - astropy/extern/configobj/**/* constants: - '**/constants/**/*' convolution: - '**/convolution/**/*' coordinates: - '**/coordinates/**/*' cosmology: - '**/cosmology/**/*' io.ascii: - '**/io/ascii/**/*' io.fits: - '**/io/fits/**/*' - cextern/cfitsio/**/* io.misc: - astropy/io/misc/* - astropy/io/misc/pandas/**/* - astropy/io/misc/tests/**/* - docs/io/misc.rst io.misc.asdf: - astropy/io/misc/asdf/**/* - docs/io/asdf-schemas.rst io.registry: - astropy/io/* - astropy/io/tests/* - docs/io/registry.rst io.votable: - '**/io/votable/**/*' logging: - astropy/logger.py - astropy/tests/test_logger.py - docs/logging.rst modeling: - '**/modeling/**/*' nddata: - '**/nddata/**/*' samp: - '**/samp/**/*' stats: - '**/stats/**/*' table: - '**/table/**/*' - astropy/extern/jquery/**/* time: - '**/time/**/*' timeseries: - '**/timeseries/**/*' uncertainty: - '**/uncertainty/**/*' unified-io: - docs/io/unified.rst units: - '**/units/**/*' - astropy/extern/ply/**/* utils: - cextern/expat/**/* - any: ['**/utils/**/*', '!astropy/utils/iers/**/*', '!docs/utils/iers.rst', '!astropy/utils/masked/**/*', '!docs/utils/masked/**/*'] utils.iers: - astropy/utils/iers/**/* - docs/utils/iers.rst utils.masked: - astropy/utils/masked/**/* - docs/utils/masked/**/* visualization: - any: ['**/visualization/**/*', '!**/visualization/wcsaxes/**/*'] visualization.wcsaxes: - '**/visualization/wcsaxes/**/*' wcs: - cextern/wcslib/**/* - any: ['**/wcs/**/*', '!astropy/wcs/wcsapi/**/*', '!docs/wcs/wcsapi.rst'] wcs.wcsapi: - astropy/wcs/wcsapi/**/* - docs/wcs/wcsapi.rst ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1646921593.071243 astropy-5.0.2/.github/workflows/0000755000175100001710000000000000000000000015642 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/.github/workflows/cancel_workflows.yml0000644000175100001710000000073100000000000021730 0ustar00vstsdockername: Cancel duplicate workflows on: workflow_run: workflows: ["CI", "Daily cron", "Weekly cron", "Check PR change log"] types: - requested # Note: This has to be in workflow_run so it works for PRs from forks. jobs: cancel: runs-on: ubuntu-latest steps: - name: Cancel previous runs uses: styfle/cancel-workflow-action@3d86a7cc43670094ac248017207be0295edbc31d # 0.8.0 with: workflow_id: ${{ github.event.workflow.id }} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/.github/workflows/check_changelog.yml0000644000175100001710000000062200000000000021451 0ustar00vstsdockername: Check PR change log on: # So it cannot be skipped. pull_request_target: types: [opened, synchronize, labeled, unlabeled] jobs: changelog_checker: name: Check if towncrier change log entry is correct runs-on: ubuntu-latest steps: - uses: pllim/actions-towncrier-changelog@main env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} BOT_USERNAME: gilesbot ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/.github/workflows/ci_cron_daily.yml0000644000175100001710000000174700000000000021174 0ustar00vstsdockername: Daily cron on: push: branches: - v5.0.x pull_request: branches: - v5.0.x env: ARCH_ON_CI: "normal" IS_CRON: "true" jobs: tests: runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: include: - name: Bundling with pyinstaller os: ubuntu-latest python: 3.8 toxenv: pyinstaller steps: - name: Checkout code uses: actions/checkout@v2 with: fetch-depth: 0 - name: Set up Python uses: actions/setup-python@v2 with: python-version: ${{ matrix.python }} - name: Install language-pack-de and tzdata if: ${{ matrix.os == 'ubuntu-latest' }} run: | sudo apt-get update sudo apt-get install language-pack-de tzdata - name: Install Python dependencies run: python -m pip install --upgrade tox - name: Run tests run: tox ${{ matrix.toxargs}} -e ${{ matrix.toxenv}} -- ${{ matrix.toxposargs}} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/.github/workflows/ci_cron_weekly.yml0000644000175100001710000000720700000000000021367 0ustar00vstsdockername: Weekly cron on: push: branches: - v5.0.x pull_request: branches: - v5.0.x env: IS_CRON: 'true' jobs: tests: runs-on: ${{ matrix.os }} env: ARCH_ON_CI: "normal" strategy: fail-fast: false matrix: include: # We check numpy-dev also in a job that only runs from cron, so that # we can spot issues sooner. We do not use remote data here, since # that gives too many false positives due to URL timeouts. We also # install all dependencies via pip here so we pick up the latest # releases. - name: Python 3.10 with dev version of key dependencies os: ubuntu-latest python: '3.10' toxenv: py310-test-devdeps - name: Documentation link check os: ubuntu-latest python: 3.8 toxenv: linkcheck # TODO: Uncomment when 3.10 is more mature. Should we use devdeps? # Test against Python dev in cron job. #- name: Python dev with basic dependencies # os: ubuntu-latest # python: 3.10-dev # toxenv: pydev-test steps: - name: Checkout code uses: actions/checkout@v2 with: fetch-depth: 0 - name: Set up Python uses: actions/setup-python@v2 with: python-version: ${{ matrix.python }} - name: Install language-pack-de and tzdata if: ${{ matrix.os == 'ubuntu-latest' }} run: | sudo apt-get update sudo apt-get install language-pack-de tzdata - name: Install graphviz if: ${{ matrix.toxenv == 'linkcheck' }} run: sudo apt-get install graphviz - name: Install Python dependencies run: python -m pip install --upgrade tox - name: Run tests run: tox ${{ matrix.toxargs}} -e ${{ matrix.toxenv}} -- ${{ matrix.toxposargs}} tests_more_architectures: # The following architectures are emulated and are therefore slow, so # we include them just in the weekly cron. These also serve as a test # of using system libraries and using pytest directly. runs-on: ubuntu-20.04 name: Python 3.9 env: ARCH_ON_CI: ${{ matrix.arch }} strategy: fail-fast: false matrix: include: - arch: aarch64 - arch: s390x # Uncomment when we ready to fix the failures, see PR 11697 #- arch: ppc64le steps: - uses: actions/checkout@v2 with: fetch-depth: 0 - uses: uraimo/run-on-arch-action@v2.1.1 name: Run tests id: build with: arch: ${{ matrix.arch }} distro: bullseye shell: /bin/bash install: | echo "deb http://deb.debian.org/debian bullseye-backports main" >> /etc/apt/sources.list apt-get update -q -y apt-get install -q -y git \ g++ \ pkg-config \ python3 \ python3-configobj \ python3-numpy \ python3-ply \ python3-venv \ cython3 \ libwcs7/bullseye-backports \ wcslib-dev/bullseye-backports \ libcfitsio-dev \ liberfa1 run: | python3 -m venv --system-site-packages tests source tests/bin/activate ASTROPY_USE_SYSTEM_ALL=1 pip3 install -e .[test] python3 -m pytest ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/.github/workflows/ci_workflows.yml0000644000175100001710000001504000000000000021075 0ustar00vstsdockername: CI on: push: branches: - v5.0.x pull_request: branches: - v5.0.x env: ARCH_ON_CI: "normal" IS_CRON: "false" jobs: initial_checks: name: Mandatory checks before CI runs-on: ubuntu-latest steps: - name: Check base branch uses: actions/github-script@v3 if: github.event_name == 'pull_request' with: script: | const skip_label = 'skip-basebranch-check'; const { default_branch: allowed_basebranch } = context.payload.repository; const pr = context.payload.pull_request; if (pr.user.login === 'meeseeksmachine') { core.info(`Base branch check is skipped since this is auto-backport by ${pr.user.login}`); return; } if (pr.labels.find(lbl => lbl.name === skip_label)) { core.info(`Base branch check is skipped due to the presence of ${skip_label} label`); return; } if (pr.base.ref !== allowed_basebranch) { core.setFailed(`PR opened against ${pr.base.ref}, not ${allowed_basebranch}`); } else { core.info(`PR opened correctly against ${allowed_basebranch}`); } tests: name: ${{ matrix.name }} runs-on: ${{ matrix.os }} needs: initial_checks strategy: fail-fast: true matrix: include: - name: Code style checks os: ubuntu-latest python: 3.x toxenv: codestyle toxposargs: --all-files -v # NOTE: this 2nd coverage test is needed for tests and code that # run only with minimal dependencies. - name: Python 3.9 with minimal dependencies and full coverage os: ubuntu-latest python: 3.9 toxenv: py39-test-cov - name: Python 3.10 with minimal dependencies os: ubuntu-latest python: '3.10' toxenv: py310-test # NOTE: In the build below we also check that tests do not open and # leave open any files. This has a performance impact on running the # tests, hence why it is not enabled by default. - name: Python 3.8 with all optional dependencies os: ubuntu-latest python: 3.8 toxenv: py38-test-alldeps toxargs: -v --develop toxposargs: --open-files - name: Python 3.8 with oldest supported version of all dependencies os: ubuntu-18.04 python: 3.8 toxenv: py38-test-oldestdeps - name: Python 3.8 with numpy 1.18 and full coverage os: ubuntu-latest python: 3.8 toxenv: py38-test-alldeps-numpy118-cov-clocale toxposargs: --remote-data=astropy - name: Python 3.8 with all optional dependencies (Windows) os: windows-latest python: 3.8 toxenv: py38-test-alldeps toxposargs: --durations=50 - name: Python 3.8 with all optional dependencies (MacOS X) os: macos-latest python: 3.8 toxenv: py38-test-alldeps toxposargs: --durations=50 steps: - name: Checkout code uses: actions/checkout@v2 with: fetch-depth: 0 - name: Set up Python uses: actions/setup-python@v2 with: python-version: ${{ matrix.python }} - name: Install language-pack-fr and tzdata if: startsWith(matrix.os, 'ubuntu') run: | sudo apt-get update sudo apt-get install language-pack-fr tzdata - name: Install Python dependencies run: python -m pip install --upgrade tox codecov - name: Run tests run: tox ${{ matrix.toxargs }} -e ${{ matrix.toxenv }} -- ${{ matrix.toxposargs }} # TODO: Do we need --gcov-glob "*cextern*" ? - name: Upload coverage to codecov if: ${{ contains(matrix.toxenv,'-cov') }} uses: codecov/codecov-action@v2 with: file: ./coverage.xml allowed_failures: name: ${{ matrix.name }} runs-on: ${{ matrix.os }} needs: initial_checks strategy: fail-fast: false matrix: include: - name: (Allowed Failure) Python 3.8 with remote data and dev version of key dependencies os: ubuntu-latest python: 3.8 toxenv: py38-test-devdeps toxposargs: --remote-data=any steps: - name: Checkout code uses: actions/checkout@v2 with: fetch-depth: 0 - name: Set up Python uses: actions/setup-python@v2 with: python-version: ${{ matrix.python }} - name: Install language-pack-de and tzdata if: startsWith(matrix.os, 'ubuntu') run: | sudo apt-get update sudo apt-get install language-pack-de tzdata - name: Install Python dependencies run: python -m pip install --upgrade tox codecov - name: Run tests run: tox ${{ matrix.toxargs }} -e ${{ matrix.toxenv }} -- ${{ matrix.toxposargs }} parallel_and_32bit: name: 32-bit and parallel runs-on: ubuntu-latest needs: initial_checks container: image: quay.io/pypa/manylinux2014_i686 steps: # TODO: Use newer checkout actions when https://github.com/actions/checkout/issues/334 fixed - name: Checkout code uses: actions/checkout@v1 with: fetch-depth: 0 - name: Write configuration items to standard location to make sure they are ignored in parallel mode run: | mkdir -p $HOME/.astropy/config/ printf "unicode_output = True\nmax_width = 500" > $HOME/.astropy/config/astropy.cfg # In addition to testing 32-bit, we also use the 3.8 builds to # test the ability to run the test suite in parallel. # Numpy is pinned to avoid building it from source for numpy 1.21.5 - name: Install dependencies for Python 3.8 run: /opt/python/cp38-cp38/bin/pip install tox - name: Run tests for Python 3.8 run: /opt/python/cp38-cp38/bin/python -m tox -e py38-numpy120-test -- -n=4 --durations=50 # We use the 3.8 build to check that running tests twice in a row in the # same Python session works without issues. This catches cases where # running the tests changes the module state permanently. Note that we # shouldn't also test the parallel build here since that enforces a degree # of isolation of tests which will interfere with what we are trying to do # here. # Numpy is pinned to avoid building it from source for numpy 1.21.5 - name: Run tests for Python 3.8 run: /opt/python/cp38-cp38/bin/python -m tox -e py38-numpy120-test-double ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/.github/workflows/codeql-analysis.yml0000644000175100001710000000512000000000000021453 0ustar00vstsdocker# For most projects, this workflow file will not need changing; you simply need # to commit it to your repository. # # You may wish to alter this file to override the set of languages analyzed, # or to provide custom queries or build logic. # # ******** NOTE ******** # We have attempted to detect the languages in your repository. Please check # the `language` matrix defined below to confirm you have the correct set of # supported CodeQL languages. # name: "CodeQL" on: schedule: # run every Wednesday at 6am UTC - cron: '0 6 * * 3' jobs: analyze: name: Analyze runs-on: ubuntu-latest strategy: fail-fast: false matrix: language: ['cpp', 'python'] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] # Learn more: # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed steps: - name: Checkout repository uses: actions/checkout@v2 with: fetch-depth: 0 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v1 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. # By default, queries listed here will override any specified in a config file. # Prefix the list here with "+" to use these queries and those in the config file. # queries: ./path/to/local/query, your-org/your-repo/queries@main # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild if: matrix.language != 'cpp' uses: github/codeql-action/autobuild@v1 # â„šī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl # âœī¸ If the Autobuild fails above, remove it and uncomment the following three lines # and modify them (or add more) to build your code if your project # uses a compiled language - name: Set up Python uses: actions/setup-python@v2 if: matrix.language == 'cpp' with: python-version: 3.9 - name: Manual build if: matrix.language == 'cpp' run: | pip install -U pip setuptools_scm wheel pip install extension-helpers jinja2 cython numpy pyerfa python setup.py build_ext --inplace - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v1 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/.github/workflows/open_actions.yml0000644000175100001710000000704600000000000021055 0ustar00vstsdockername: "When Opened" on: issues: types: - opened pull_request_target: types: - opened jobs: triage: runs-on: ubuntu-latest steps: - name: Label PR uses: actions/labeler@main if: github.event_name == 'pull_request_target' && github.event.pull_request.user.login != 'meeseeksmachine' with: repo-token: "${{ secrets.GITHUB_TOKEN }}" - name: Greet new contributors uses: actions/first-interaction@v1 with: repo-token: "${{ secrets.GITHUB_TOKEN }}" issue-message: > Welcome to Astropy 👋 and thank you for your first issue! A project member will respond to you as soon as possible; in the meantime, please double-check the [guidelines for submitting issues](https://github.com/astropy/astropy/blob/main/CONTRIBUTING.md#reporting-issues) and make sure you've provided the requested details. GitHub issues in the Astropy repository are used to track bug reports and feature requests; If your issue poses a question about how to use Astropy, please instead raise your question in the [Astropy Discourse user forum](https://community.openastronomy.org/c/astropy/8) and close this issue. If you feel that this issue has not been responded to in a timely manner, please leave a comment mentioning our software support engineer @embray, or send a message directly to the [development mailing list](http://groups.google.com/group/astropy-dev). If the issue is urgent or sensitive in nature (e.g., a security vulnerability) please send an e-mail directly to the private e-mail feedback@astropy.org. pr-message: > Welcome to Astropy 👋 and congratulations on your first pull request! 🎉 A project member will respond to you as soon as possible; in the meantime, please have a look over the [Checklist for Contributed Code](https://github.com/astropy/astropy/blob/main/CONTRIBUTING.md#checklist-for-contributed-code) and make sure you've addressed as many of the questions there as possible. If you feel that this pull request has not been responded to in a timely manner, please leave a comment mentioning our software support engineer @embray, or send a message directly to the [development mailing list](http://groups.google.com/group/astropy-dev). If the issue is urgent or sensitive in nature (e.g., a security vulnerability) please send an e-mail directly to the private e-mail feedback@astropy.org. - name: 'Comment Draft PR' uses: actions/github-script@v3 if: github.event.pull_request.draft == true with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | github.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: '👋 Thank you for your draft pull request! Do you know that you can use `[ci skip]` or `[skip ci]` in your commit messages to skip running continuous integration tests until you are ready?' }) # We can take this out when astropy-bot comes back online, maybe... Until next year! #- name: Special comment # uses: pllim/action-special_pr_comment@main # with: # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/.github/workflows/stalebot.yml0000644000175100001710000000077100000000000020207 0ustar00vstsdockername: Astropy stalebot on: schedule: # * is a special character in YAML so you have to quote this string # run every day at 5:30 am UTC - cron: '30 5 * * *' workflow_dispatch: jobs: stalebot: runs-on: ubuntu-latest if: github.repository == 'astropy/astropy' steps: - uses: pllim/action-astropy-stalebot@main env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} STALEBOT_MAX_ISSUES: -1 STALEBOT_MAX_PRS: -1 STALEBOT_SLEEP: 10 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/.gitignore0000644000175100001710000000230200000000000014232 0ustar00vstsdocker# Compiled files *.py[cod] *.a *.o *.so *.pyd *.dll __pycache__ # Ignore .c files by default to avoid including generated code. If you want to # add a non-generated .c extension, put that into the src/ subdirectory of a # package or else use `git add -f filename.c`. *.c !astropy/*/src/*.c astropy/modeling/src/projections.c # Other generated files MANIFEST astropy/cython_version.py astropy/wcs/include/wcsconfig.h astropy/_erfa/core.py astropy/_version.py # Sphinx _build _generated docs/api docs/generated docs/visualization/ngc6976.jpeg docs/visualization/ngc6976-default.jpeg # Packages/installer info *.egg *.egg-info dist build eggs .eggs parts bin var sdist develop-eggs .installed.cfg distribute-*.tar.gz .venv venv # we are not currently using pipenv directly, but people who # install astropy with pipenv will have these files generated Pipfile Pipfile.lock # pyinstaller files .pyinstaller/astropy_tests/ .pyinstaller/run_astropy_tests .pyinstaller/run_astropy_tests.spec # Other .cache .tox .*.swp .*.swo *~ .project .pydevproject .settings .coverage cover htmlcov .hypothesis .github_cache # Mac OSX .DS_Store # PyCharm .idea # Pytest v .pytest_cache # VSCode .vscode .tmp pip-wheel-metadata ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/.mailmap0000644000175100001710000004701100000000000013671 0ustar00vstsdockerAarya Patil Aarya Patil Adam Ginsburg Adam Ginsburg Adam Ginsburg Adele Plunkett Adrian Price-Whelan Adrian Price-Whelan Albert Y. Shih Aleh Khvalko Aleksi Suutarinen Alex Conley Alex Conley Alex Hagen Alex Rudy Alexander Bakanov Alexandre Beelen Alexandre Beelen Amit Kumar Ana Posses Anany Shrey Jain <31594632+ananyashreyjain@users.noreply.github.com> Andy Casey Aniket Kulkarni Aniket Sanghi Anirudh Katipally Anne Archibald Anne Archibald Anthony Horton Asish Panda Asra Nizami Asra Nizami Austen Groener Austen Groener Axel Donath Axel Donath Benjamin Alan Weaver Benjamin Alan Weaver Benjamin Roulston Benjamin Winkel Bhavya Khandelwal Bogdan Nicula Brett Morris Brett Morris Brett Morris Brian Soto Brian Svoboda Brigitta Sipőcz Brigitta Sipőcz Brigitta Sipőcz Bruce Merry Bruce Merry Bryce Nordgren Chiara Marmo Chiara Marmo Chiara Marmo Chris Osborne <2087801o@student.gla.ac.uk> Chris Simpson Christian Clauss Christoph Gohlke Christopher Bonnett Clara Brasseur ClÊment Robert ClÊment Robert Craig Jones Craig Jones Curtis McCully Dan Foreman-Mackey Dan Foreman-Mackey Dan P. Cunningham Dan Taranu Daniel Bell Daniel Bell Daniel D'Avella Daniel D'Avella Daniel Datsev Daniel Datsev Daniel Lenz Daniel Ryan Dan Ryan Daniel Ryan DanRyanIrish Daria Cara Daria Cara <36781821+daria-cara@users.noreply.github.com> David Collom David Collom David Collom David Collom David Grant <33813984+DavoGrant@users.noreply.github.com> David Kirkby David PÊrez-SuÃĄrez David Shupe Demitri Muna Demitri Muna Demitri Muna Derek Homeier Diego Asterio de Zaballa Douglas Burke Dylan Gregersen Edward Gomez Ed Slavich Ed Slavich Edward Slavich Elijah Bernstein-Cooper Emily Deibert Emma Hogan Eric Depagne Eric Koch E. Madison Bray E. Madison Bray E. Madison Bray E. Rykoff Emir Karamehmetoglu Emir Karamehmetoglu Emir Esteban Pardo SÃĄnchez Francesco Montesano Gabriel Perren Gabriel Perren Geert Barentsen George Galvin Gerrit Schellenberger Giorgio Calderone Graham Kanarek Guillaume Pernot Guillaume Pernot Gustavo Bragança Hannes Breytenbach Hans Moritz GÃŧnther Hans Moritz GÃŧnther Harry Ferguson Henrik Norman Henrik Norman Himanshu Pathak Humna Awan Ivo Busko Ivo Busko Jaime AndrÊs Jake VanderPlas Jake VanderPlas Jake VanderPlas James McCormac James Tocknell James Tocknell James Turner Jane Rigby Jani Å umak Jason Segnini <47617351+JasonS09@users.noreply.github.com> Javier Blasco Javier Duran Javier Duran Javier Duran Javier Duran Javier Duran Javier Duran Javier Duran Javier Pascual Granado Jeff Taylor Jennifer Karr Joe Hunkeler Johannes Zeman John Parejko John Parejko Johnny Greco Johnny Greco Jonathan Foster Jonathan Foster Jonathan Gagne Jordan Mirocha Joseph Long Joseph Long Joseph Schlitz Juan Carlos Segovia Juan Luis Cano Rodríguez Juan Luis Cano Rodríguez Juan Luis Cano Rodríguez Juan Luis Cano Rodríguez Julien Woillez Julien Woillez Jurien Huisman Kacper Kowalik Kacper Kowalik Karan Grover Karl Vyhmeister Kelle Cruz Kevin Gullikson Kirill Tchernyshyov Kris Stern Kris Stern Kyle Barbary Kyle Oman Larry Bradley Larry Bradley Laura Watkins Lauren Glattly <44421608+lglattly@users.noreply.github.com> Lennard Kiehl Leo Singer Leonardo Ferreira <[leonardo.ferreira.furg@gmail.com]> Lia Corrales Lingyi Hu Lisa Martin <48742903+lisamartin72@users.noreply.github.com> Lisa Walter Loïc SÊguin-C Luke G. Bouma Luke Kelley Madhura Parikh Magali Mebsout Magnus Persson Maneesh Yadav Mangala Gowri Krishnamoorthy Marten van Kerkwijk Matt Davis Matteo Bachetti Matthew Craig Matthieu Baumann Mavani Bhautik Michael Brewer Michael Brewer Michael Hirsch Michael Lindner-D'Addario <38199062+MDAddario@users.noreply.github.com> Michael Mommert Michael Mommert Michael Seifert Michele Costa Michele Costa Miguel de Val-Borro Mihai Cara Mihai Cara Mike Alexandersen Mikhail Minin Moataz Hisham Nabil Freij Nadia Dencheva Nadia Dencheva Nathaniel Starkman Nathaniel Starkman Neil Crighton Nicholas Earl Nicholas Earl Nicholas Earl Nick Lloyd Nora Luetzgendorf Ole Streicher Ole Streicher Parikshit Sakurikar Patricio Rojo Pauline Barmby Perry Greenfield Pey Lian Lim Pey Lian Lim <2090236+pllim@users.noreply.github.com> Pratik Patel Pritish Chakraborty Ricardo Fonseca Ricardo Fonseca Richard R Richard R <58728519+rrjbca@users.noreply.github.com> Ricky O'Steen <39831871+rosteen@users.noreply.github.com> Ritiek Malhotra Ritwick DSouza Rohan Rajpal Rohit Kapoor Rohit Patil Rohit Patil Roman Tolesnikov Ryan Cooke Sam Verstocken Sanjeev Dubey Sara Ogaz Sarah Graves Sergio Pascual Shantanu Srivastava Shilpi Jain Shivansh Mishra Shivansh Mishra Simon Conseil Simon Conseil Simon Conseil Simon Conseil Simon Conseil Simon Liedtke Sourabh Cheedella Steve Crawford Steve Crawford Steve Crawford Stuart Littlefair Stuart Mumford Sudheesh Singanamalla Sudheesh Singanamalla Sushobhana Patra Thomas Erben Thompson Le Blanc Thompson Le Blanc Tim Jenness Tim Jenness Tom Aldcroft Tom Donaldson Tom J Wilson Tyler Finethy VSN Reddy Janga Vishnunarayan K I Vital FernÃĄndez Yannick Copin Yash Kumar Yash Sharma Yingqi Ying <33911276+dyq0811@users.noreply.github.com> Zach Edwards Zac Hatfield-Dodds ZÊ Vinicius ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/.pep8speaks.yml0000644000175100001710000000401000000000000015124 0ustar00vstsdockerscanner: diff_only: True linter: flake8 flake8: max-line-length: 100 select: - E101 # mix of tabs and spaces - W191 # use of tabs - E201 # whitespace after '(' - E202 # whitespace before ')' - W291 # trailing whitespace - W292 # no newline at end of file - W293 # trailing whitespace - W391 # blank line at end of file - E111 # 4 spaces per indentation level - E112 # 4 spaces per indentation level - E113 # 4 spaces per indentation level - E301 # expected 1 blank line, found 0 - E302 # expected 2 blank lines, found 0 - E303 # too many blank lines (3) - E304 # blank lines found after function decorator - E305 # expected 2 blank lines after class or function definition - E306 # expected 1 blank line before a nested definition - E502 # the backslash is redundant between brackets - E722 # do not use bare except - E901 # SyntaxError or IndentationError - E902 # IOError - E999 # SyntaxError -- failed to compile a file into an Abstract Syntax Tree - F822 # undefined name in __all__ - F823 # local variable name referenced before assignment no_blank_comment: True descending_issues_order: False message: opened: header: > Hello @{name} :wave:! Thanks for opening this pull request, we are very grateful for your contribution! I'm a friendly :robot: that checks for style issues in this pull request, since this project follows the [PEP8](https://www.python.org/dev/peps/pep-0008/) style guidelines. I've listed some small issues I found below, but please don't hesitate to ask if any of them are unclear! updated: header: > Hello @{name} :wave:! It looks like you've made some changes in your pull request, so I've checked the code again for style. no_errors: "There are no PEP8 style issues with this pull request - thanks! :tada:" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/.pre-commit-config.yaml0000644000175100001710000000534400000000000016534 0ustar00vstsdockerrepos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.0.1 hooks: - id: check-added-large-files - id: check-case-conflict - id: check-yaml - id: debug-statements - id: end-of-file-fixer exclude: ".*(data.*|extern.*|licenses.*|_parsetab.py)$" - id: trailing-whitespace exclude: ".*(data.*|extern.*|licenses.*|_parsetab.py|test_cds.py)$" # - repo: https://github.com/timothycrosley/isort # rev: 5.9.2 # hooks: # - id: isort # - repo: https://github.com/asottile/pyupgrade # rev: v2.21.0 # hooks: # - id: pyupgrade # We list the warnings/errors to check for here rather than in setup.cfg because # we don't want these options to apply whenever anyone calls flake8 from the # command-line or their code editor - in this case all warnings/errors should be # checked for. The warnings/errors we check for here are: # E101 - mix of tabs and spaces # W191 - use of tabs # E201 - whitespace after '(' # E202 - whitespace before ')' # W291 - trailing whitespace # W292 - no newline at end of file # W293 - trailing whitespace # W391 - blank line at end of file # E111 - 4 spaces per indentation level # E112 - 4 spaces per indentation level # E113 - 4 spaces per indentation level # E301 - expected 1 blank line, found 0 # E302 - expected 2 blank lines, found 0 # E303 - too many blank lines (3) # E304 - blank lines found after function decorator # E305 - expected 2 blank lines after class or function definition # E306 - expected 1 blank line before a nested definition # E502 - the backslash is redundant between brackets # E722 - do not use bare except # E901 - SyntaxError or IndentationError # E902 - IOError # E999: SyntaxError -- failed to compile a file into an Abstract Syntax Tree # F822: undefined name in __all__ # F823: local variable name referenced before assignment - repo: https://gitlab.com/pycqa/flake8 rev: 3.9.2 hooks: - id: flake8 args: ['--count', '--select', 'E101,W191,E201,E202,W291,W292,W293,W391,E111,E112,E113,E30,E502,E722,E901,E902,E999,F822,F823'] exclude: ".*(data.*|extern.*|cextern)$" - repo: local hooks: - id: changelogs-rst name: changelog filenames language: fail entry: >- changelog files must be named /####.(bugfix|feature|api).rst or ####.other.rst (in the root directory only) exclude: >- ^docs/changes/[\w\.]+/(\d+\.(bugfix|feature|api)(\.\d)?.rst|.gitkeep) files: ^docs/changes/[\w\.]+/ - id: changelogs-rst-other name: changelog filenames for other category language: fail entry: >- only "other" changelog files must be placed in the root directory exclude: >- ^docs/changes/(\d+\.other.rst|README.rst|template.rst) files: ^docs/changes/\d+.\w+.rst ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1646921593.071243 astropy-5.0.2/.pyinstaller/0000755000175100001710000000000000000000000014671 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1646921593.071243 astropy-5.0.2/.pyinstaller/hooks/0000755000175100001710000000000000000000000016014 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/.pyinstaller/hooks/hook-skyfield.py0000644000175100001710000000036000000000000021135 0ustar00vstsdocker# NOTE: this hook should be added to # https://github.com/pyinstaller/pyinstaller-hooks-contrib # once that repository is ready for pull requests from PyInstaller.utils.hooks import collect_data_files datas = collect_data_files('skyfield') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/.pyinstaller/run_astropy_tests.py0000644000175100001710000001074300000000000021057 0ustar00vstsdockerimport os import sys import pytest import shutil import erfa # noqa import astropy # noqa if len(sys.argv) == 3 and sys.argv[1] == '--astropy-root': ROOT = sys.argv[2] else: # Make sure we don't allow any arguments to be passed - some tests call # sys.executable which becomes this script when producing a pyinstaller # bundle, but we should just error in this case since this is not the # regular Python interpreter. if len(sys.argv) > 1: print("Extra arguments passed, exiting early") sys.exit(1) for root, dirnames, files in os.walk(os.path.join(ROOT, 'astropy')): # NOTE: we can't simply use # test_root = root.replace('astropy', 'astropy_tests') # as we only want to change the one which is for the module, so instead # we search for the last occurrence and replace that. pos = root.rfind('astropy') test_root = root[:pos] + 'astropy_tests' + root[pos + 7:] # Copy over the astropy 'tests' directories and their contents for dirname in dirnames: final_dir = os.path.relpath(os.path.join(test_root, dirname), ROOT) # We only copy over 'tests' directories, but not astropy/tests (only # astropy/tests/tests) since that is not just a directory with tests. if dirname == 'tests' and not root.endswith('astropy'): shutil.copytree(os.path.join(root, dirname), final_dir, dirs_exist_ok=True) else: # Create empty __init__.py files so that 'astropy_tests' still # behaves like a single package, otherwise pytest gets confused # by the different conftest.py files. init_filename = os.path.join(final_dir, '__init__.py') if not os.path.exists(os.path.join(final_dir, '__init__.py')): os.makedirs(final_dir, exist_ok=True) with open(os.path.join(final_dir, '__init__.py'), 'w') as f: f.write("#") # Copy over all conftest.py files for file in files: if file == 'conftest.py': final_file = os.path.relpath(os.path.join(test_root, file), ROOT) shutil.copy2(os.path.join(root, file), final_file) # Add the top-level __init__.py file with open(os.path.join('astropy_tests', '__init__.py'), 'w') as f: f.write("#") # Remove test file that tries to import all sub-packages at collection time os.remove(os.path.join('astropy_tests', 'utils', 'iers', 'tests', 'test_leap_second.py')) # Remove convolution tests for now as there are issues with the loading of the C extension. # FIXME: one way to fix this would be to migrate the convolution C extension away from using # ctypes and using the regular extension mechanism instead. shutil.rmtree(os.path.join('astropy_tests', 'convolution')) os.remove(os.path.join('astropy_tests', 'modeling', 'tests', 'test_convolution.py')) os.remove(os.path.join('astropy_tests', 'modeling', 'tests', 'test_core.py')) os.remove(os.path.join('astropy_tests', 'visualization', 'tests', 'test_lupton_rgb.py')) # FIXME: The following tests rely on the fully qualified name of classes which # don't seem to be the same. os.remove(os.path.join('astropy_tests', 'table', 'mixins', 'tests', 'test_registry.py')) # Copy the top-level conftest.py shutil.copy2(os.path.join(ROOT, 'astropy', 'conftest.py'), os.path.join('astropy_tests', 'conftest.py')) # We skip a few tests, which are generally ones that rely on explicitly # checking the name of the current module (which ends up starting with # astropy_tests rather than astropy). SKIP_TESTS = ['test_exception_logging_origin', 'test_log', 'test_configitem', 'test_config_noastropy_fallback', 'test_no_home', 'test_path', 'test_rename_path', 'test_data_name_third_party_package', 'test_pkg_finder', 'test_wcsapi_extension', 'test_find_current_module_bundle', 'test_minversion', 'test_imports', 'test_generate_config', 'test_generate_config2', 'test_create_config_file', 'test_download_parallel_fills_cache'] # Run the tests! sys.exit(pytest.main(['astropy_tests', '-k ' + ' and '.join('not ' + test for test in SKIP_TESTS)], plugins=['pytest_doctestplus.plugin', 'pytest_openfiles.plugin', 'pytest_remotedata.plugin', 'pytest_astropy_header.display'])) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/.readthedocs.yml0000644000175100001710000000065100000000000015335 0ustar00vstsdockerversion: 2 build: os: ubuntu-20.04 apt_packages: - graphviz tools: python: "3.9" sphinx: builder: html configuration: docs/conf.py fail_on_warning: true # Install regular dependencies. # Then, install special pinning for RTD. python: system_packages: false install: - method: pip path: . extra_requirements: - docs - all # Don't build any extra formats formats: [] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/CHANGES.rst0000644000175100001710000173443200000000000014065 0ustar00vstsdocker5.0.2 (2022-03-10) ================== Bug Fixes --------- astropy.io.ascii ^^^^^^^^^^^^^^^^ - Bugfix to add backwards compatibility for reading ECSV version 0.9 files with non-standard column datatypes (such as ``object``, ``str``, ``datetime64``, etc.), which would raise a ValueError in ECSV version 1.0. [#12880] astropy.io.misc ^^^^^^^^^^^^^^^ - Bugfix for ``units_mapping`` schema's property name conflicts. Changes: * ``inputs`` to ``unit_inputs`` * ``outputs`` to ``unit_outputs`` [#12800] astropy.io.votable ^^^^^^^^^^^^^^^^^^ - Fixed a bug where ``astropy.io.votable.validate`` was printing output to ``sys.stdout`` when the ``output`` paramter was set to ``None``. ``validate`` now returns a string when ``output`` is set to ``None``, as documented. [#12604] astropy.modeling ^^^^^^^^^^^^^^^^ - Fix handling of units on ``scale`` parameter in BlackBody model. [#12318] - Indexing on models can now be used with all types of integers (like ``numpy.int64``) instead of just ``int``. [#12561] - Fix computation of the separability of a ``CompoundModel`` where another ``CompoundModel`` is on the right hand side of the ``&`` operator. [#12907] - Provide a hook (``Model._calculate_separability_matrix``) to allow subclasses of ``Model`` to define how to compute their separability matrix. [#12900] astropy.stats ^^^^^^^^^^^^^ - Fixed a bug in which running ``kuiper_false_positive_probability(D,N)`` on distributions with many data points could produce NaN values for the false positive probability of the Kuiper statistic. [#12896] astropy.wcs ^^^^^^^^^^^ - Fixed a bug due to which ``naxis``, ``pixel_shape``, and ``pixel_bounds`` attributes of ``astropy.wcs.WCS`` were not restored when an ``astropy.wcs.WCS`` object was unpickled. This fix also eliminates ``FITSFixedWarning`` warning issued during unpiclikng of the WCS objects related to the number of axes. This fix also eliminates errors when unpickling WCS objects originally created using non-default values for ``key``, ``colsel``, and ``keysel`` parameters. [#12844] 5.0.1 (2022-01-26) ================== Bug Fixes --------- astropy.coordinates ^^^^^^^^^^^^^^^^^^^ - Trying to create an instance of ``astropy.coordinates.Distance`` by providing both ``z`` and ``parallax`` now raises the expected ``ValueError``. [#12531] - Fixed a bug where changing the wrap angle of the longitude component of a representation could raise a warning or error in certain situations. [#12556] - ``astropy.coordinates.Distance`` constructor no longer ignores the ``unit`` keyword when ``parallax`` is provided. [#12569] astropy.cosmology ^^^^^^^^^^^^^^^^^ - ``astropy.cosmology.utils.aszarr`` can now convert ``Column`` objects. [#12525] - Reading a cosmology from an ECSV will load redshift and Hubble parameter units from the cosmology units module. [#12636] astropy.io.fits ^^^^^^^^^^^^^^^ - Fix formatting issue in ``_dump_coldefs`` and add tests for ``tabledump`` and ``tableload`` convenience functions. [#12526] astropy.io.misc ^^^^^^^^^^^^^^^ - YAML can now also represent quantities and arrays with structured dtype, as well as structured scalars based on ``np.void``. [#12509] astropy.modeling ^^^^^^^^^^^^^^^^ - Fixes error when fitting multiplication or division based compound models where the sub-models have different output units. [#12475] - Bugfix for incorrectly initialized and filled ``parameters`` data for ``Spline1D`` model. [#12523] - Bugfix for ``keyerror`` thrown by ``Model.input_units_equivalencies`` when used on ``fix_inputs`` models which have no set unit equivalencies. [#12597] astropy.table ^^^^^^^^^^^^^ - ``astropy.table.Table.keep_columns()`` and ``astropy.table.Table.remove_columns()`` now work with generators of column names. [#12529] - Avoid duplicate storage of info in serialized columns if the column used to serialize already can hold that information. [#12607] astropy.timeseries ^^^^^^^^^^^^^^^^^^ - Fixed edge case bugs which emerged when using ``aggregate_downsample`` with custom bins. [#12527] astropy.units ^^^^^^^^^^^^^ - Structured units can be serialized to/from yaml. [#12492] - Fix bad typing problems by removing interaction with ``NDArray.__class_getitem__``. [#12511] - Ensure that ``Quantity.to_string(format='latex')`` properly typesets exponents also when ``u.quantity.conf.latex_array_threshold = -1`` (i.e., when the threshold is taken from numpy). [#12573] - Structured units can now be copied with ``copy.copy`` and ``copy.deepcopy`` and also pickled and unpicked also for ``protocol`` >= 2. This does not work for big-endian architecture with older ``numpy<1.21.1``. [#12583] astropy.utils ^^^^^^^^^^^^^ - Ensure that a ``Masked`` instance can be used to initialize (or viewed as) a ``numpy.ma.Maskedarray``. [#12482] - Ensure ``Masked`` also works with numpy >=1.22, which has a keyword argument name change for ``np.quantile``. [#12511] - ``astropy.utils.iers.LeapSeconds.auto_open()`` no longer emits unnecessary warnings when ``astropy.utils.iers.conf.auto_max_age`` is set to ``None``. [#12713] 5.0 (2021-11-15) ================ New Features ------------ astropy.convolution ^^^^^^^^^^^^^^^^^^^ - Added dealiasing support to ``convolve_fft``. [#11495] astropy.coordinates ^^^^^^^^^^^^^^^^^^^ - Added missing coordinate transformations where the starting and ending frames are the same (i.e., loopback transformations). [#10909] - Allow negation, multiplication and division also of representations that include a differential (e.g., ``SphericalRepresentation`` with a ``SphericalCosLatDifferential``). For all operations, the outcome is equivalent to transforming the representation and differential to cartesian, then operating on those, and transforming back to the original representation (except for ``UnitSphericalRepresentation``, which will return a ``SphericalRepresentation`` if there is a scale change). [#11470] - ``RadialRepresentation.transform`` can work with a multiplication matrix only. All other matrices still raise an exception. [#11576] - ``transform`` methods are added to ``BaseDifferential`` and ``CartesianDifferential``. All transform methods on Representations now delegate transforming differentials to the differential objects. [#11654] - Adds new ``HADec`` built-in frame with transformations to/from ``ICRS`` and ``CIRS``. This frame complements ``AltAz`` to give observed coordinates (hour angle and declination) in the ``ITRS`` for an equatorially mounted telescope. [#11676] - ``SkyCoord`` objects now have a ``to_table()`` method, which allows them to be converted to a ``QTable``. [#11743] astropy.cosmology ^^^^^^^^^^^^^^^^^ - Cosmologies now store metadata in a mutable parameter ``meta``. The initialization arguments ``name`` and ``meta`` are keyword-only. [#11542] - A new unit, ``redshift``, is defined. It is a dimensionless unit to distinguish redshift quantities from other non-redshift values. For compatibility with dimensionless quantities the equivalency ``dimensionless_redshift`` is added. This equivalency is enabled by default. [#11786] - Add equality operator for comparing Cosmology instances. Comparison is done on all immutable fields (this excludes 'meta'). Now the following will work: .. code-block:: python >>> from astropy.cosmology import Planck13, Planck18 >>> Planck13 == Planck18 False >>> Planck18 == Planck18 True [#11813] - Added ``read/write`` methods to Cosmology using the Unified I/O registry. Now custom file format readers, writers, and format-identifier functions can be registered to read, write, and identify, respectively, Cosmology objects. Details are discussed in an addition to the docs. [#11948] - Added ``to_format/from_format`` methods to Cosmology using the Unified I/O registry. Now custom format converters and format-identifier functions can be registered to transform Cosmology objects. The transformation between Cosmology and dictionaries is pre-registered. Details are discussed in an addition to the docs. [#11998] - Added units module for defining and collecting cosmological units and equivalencies. [#12092] - Flat cosmologies are now set by a mixin class, ``FlatCosmologyMixin`` and its FLRW-specific subclass ``FlatFLRWMixin``. All ``FlatCosmologyMixin`` are flat, but not all flat cosmologies are instances of ``FlatCosmologyMixin``. As example, ``LambdaCDM`` **may** be flat (for the a specific set of parameter values), but ``FlatLambdaCDM`` **will** be flat. Cosmology parameters are now descriptors. When accessed from a class they transparently stores information, like the units and accepted equivalencies. On a cosmology instance, the descriptor will return the parameter value. Parameters can have custom ``getter`` methods. Cosmological equality is refactored to check Parameters (and the name) A new method, ``is_equivalent``, is added to check Cosmology equivalence, so a ``FlatLambdaCDM`` and flat ``LambdaCDM`` are equivalent. [#12136] - Replaced ``z = np.asarray(z)`` with ``z = u.Quantity(z, u.dimensionless_unscaled).value`` in Cosmology methods. Input of values with incorrect units raises a UnitConversionError or TypeError. [#12145] - Cosmology Parameters allow for custom value setters. Values can be set once, but will error if set a second time. If not specified, the default setter is used, which will assign units using the Parameters ``units`` and ``equivalencies`` (if present). Alternate setters may be registered with Parameter to be specified by a str, not a decorator on the Cosmology. [#12190] - Cosmology instance conversion to dict now accepts keyword argument ``cls`` to determine dict type, e.g. ``OrderedDict``. [#12209] - A new equivalency is added between redshift and the Hubble parameter and values with units of little-h. This equivalency is also available in the catch-all equivalency ``with_redshift``. [#12211] - A new equivalency is added between redshift and distance -- comoving, lookback, and luminosity. This equivalency is also available in the catch-all equivalency ``with_redshift``. [#12212] - Register Astropy Table into Cosmology's ``to/from_format`` I/O, allowing a Cosmology instance to be parsed from or converted to a Table instance. Also adds the ``__astropy_table__`` method allowing ``Table(cosmology)``. [#12213] - The WMAP1 and WMAP3 are accessible as builtin cosmologies. [#12248] - Register Astropy Model into Cosmology's ``to/from_format`` I/O, allowing a Cosmology instance to be parsed from or converted to a Model instance. [#12269] - Register an ECSV reader and writer into Cosmology's I/O, allowing a Cosmology instance to be read from from or written to an ECSV file. [#12321] astropy.io.ascii ^^^^^^^^^^^^^^^^ - Added new way to specify the dtype for tables that are read: ``converters`` can specify column names with wildcards. [#11892] - Added a new ``astropy.io.ascii.Mrt`` class to write tables in the American Astronomical Society Machine-Readable Table format, including documentation and tests for the same. [#11897, #12301, #12302] - When writing, the input data are no longer copied, improving performance. Metadata that might be changed, such as format and serialization information, is copied, hence users can continue to count on no changes being made to the input data. [#11919] astropy.io.misc ^^^^^^^^^^^^^^^ - Add Parquet serialization of Tables with pyarrow, including metadata support and columnar access. [#12215] astropy.modeling ^^^^^^^^^^^^^^^^ - Added fittable spline models to ``modeling``. [#11634] - Extensive refactor of ``BoundingBox`` for better usability and maintainability. [#11930] - Added ``CompoundBoundingBox`` feature to ``~astropy.modeling``, which allows more flexibility in defining bounding boxes for models that are applied to images with many slices. [#11942] - Improved parameter support for ``astropy.modeling.core.custom_model`` created models. [#11984] - Added the following trigonometric models and linked them to their appropriate inverse models: * ``Cosine1D`` [#12158] * ``Tangent1D`` * ``ArcSine1D`` * ``ArcCosine1D`` * ``ArcTangent1D`` [#12185] astropy.table ^^^^^^^^^^^^^ - Added a new method ``Table.update()`` which does a dictionary-style update of a ``Table`` by adding or replacing columns. [#11904] - Masked quantities are now fully supported in tables. This includes ``QTable`` automatically converting ``MaskedColumn`` instances to ``MaskedQuantity``, and ``Table`` doing the reverse. [#11914] - Added new keyword arguments ``keys_left`` and ``keys_right`` to the table ``join`` function to support joining tables on key columns with different names. In addition the new keywords can accept a list of column-like objects which are used as the match keys. This allows joining on arbitrary data which are not part of the tables being joined. [#11954] - Formatting of any numerical values in the output of ``Table.info()`` and ``Column.info()`` has been improved. [#12022] - It is now possible to add dask arrays as columns in tables and have them remain as dask arrays rather than be converted to Numpy arrays. [#12219] - Added a new registry for mixin handlers, which can be used to automatically convert array-like Python objects into mixin columns when assigned to a table column. [#12219] astropy.time ^^^^^^^^^^^^ - Adds a new method ``earth_rotation_angle`` to calculate the Local Earth Rotation Angle. Also adjusts Local Sidereal Time for the Terrestrial Intermediate Origin (``TIO``) and adds a rigorous correction for polar motion. The ``TIO`` adjustment is approximately 3 microseconds per century from ``J2000`` and the polar motion correction is at most about +/-50 nanoseconds. For models ``IAU1982`` and ``IAU1994``, no such adjustments are made as they pre-date the TIO concept. [#11680] astropy.timeseries ^^^^^^^^^^^^^^^^^^ - A custom binning scheme is now available in ``aggregate_downsample``. It allows ``time_bin_start`` and ``time_bin_size`` to be arrays, and adds an optional ``time_bin_end``. This scheme mirrors the API for ``BinnedTimeSeries``. [#11266] astropy.units ^^^^^^^^^^^^^ - ``Quantity`` gains a ``__class_getitem__`` to create unit-aware annotations with the syntax ``Quantity[unit or physical_type, shape, numpy.dtype]``. If the python version is 3.9+ or ``typing_extensions`` is installed, these are valid static type annotations. [#10662] - Each physical type is added to ``astropy.units.physical`` (e.g., ``physical.length`` or ``physical.electrical_charge_ESU``). The attribute-accessible names (underscored, without parenthesis) also work with ``astropy.units.physical.get_physical_type``. [#11691] - It is now possible to have quantities based on structured arrays in which the unit has matching structure, giving each field its own unit, using units constructed like ``Unit('AU,AU/day')``. [#11775] - The milli- prefix has been added to ``astropy.units.Angstrom``. [#11788] - Added attributes ``base``, ``coords``, and ``index`` and method ``copy()`` to ``QuantityIterator`` to match ``numpy.ndarray.flatiter``. [#11796] - Added "angular frequency" and "angular velocity" as aliases for the "angular speed" physical type. [#11865] - Add light-second to units of length [#12128] astropy.utils ^^^^^^^^^^^^^ - The ``astropy.utils.deprecated_renamed_argument()`` decorator now supports custom warning messages. [#12305] - The NaN-aware numpy functions such as ``np.nansum`` now work on Masked arrays, with masked values being treated as NaN, but without raising warnings or exceptions. [#12454] astropy.visualization ^^^^^^^^^^^^^^^^^^^^^ - Added a feature so that SphericalCircle will accept center parameter as a SkyCoord object. [#11790] astropy.wcs ^^^^^^^^^^^ - ``astropy.wcs.utils.obsgeo_to_frame`` has been added to convert the obsgeo coordinate array on ``astropy.wcs.WCS`` objects to an ``ITRS`` coordinate frame instance. [#11716] - Updated bundled ``WCSLIB`` to version 7.7 with several bugfixes. [#12034] API Changes ----------- astropy.config ^^^^^^^^^^^^^^ - ``update_default_config`` and ``ConfigurationMissingWarning`` are deprecated. [#11502] astropy.constants ^^^^^^^^^^^^^^^^^ - Removed deprecated ``astropy.constants.set_enabled_constants`` context manager. [#12105] astropy.coordinates ^^^^^^^^^^^^^^^^^^^ - Positions for the Moon using the 'builtin' ephemeris now use the new ``erfa.moon98`` function instead of our own implementation of the Meeus algorithm. As this also corrects a misunderstanding of the frame returned by the Meeus, this improves the agreement with the JPL ephemeris from about 30 to about 6 km rms. [#11753] - Removed deprecated ``representation`` attribute from ``astropy.coordinates.BaseCoordinateFrame`` class. [#12257] - ``SpectralQuantity`` and ``SpectralCoord`` ``.to_value`` method can now be called without ``unit`` argument in order to maintain a consistent interface with ``Quantity.to_value`` [#12440] astropy.cosmology ^^^^^^^^^^^^^^^^^ - ``z_at_value`` now works with arrays for all arguments (except ``func``, ``verbose``, and ``method``). Consequently, ``coordinates.Distance.z`` can be used when Distance is an array. [#11778] - Remove deprecation warning and error remapping in ``Cosmology.clone``. Now unknown arguments will raise a ``TypeError``, not an ``AttributeError``. [#11785] - The ``read/write`` and ``to/from_format`` Unified I/O registries are separated and apply only to ``Cosmology``. [#12015] - Cosmology parameters in ``cosmology.parameters.py`` now have units, where applicable. [#12116] - The function ``astropy.cosmology.utils.inf_like()`` is deprecated. [#12175] - The function ``astropy.cosmology.utils.vectorize_if_needed()`` is deprecated. A new function ``astropy.cosmology.utils.vectorize_redshift_method()`` is added as replacement. [#12176] - Cosmology base class constructor now only accepts arguments ``name`` and ``meta``. Subclasses should add relevant arguments and not pass them to the base class. [#12191] astropy.io ^^^^^^^^^^ - When ``astropy`` raises an ``OSError`` because a file it was told to write already exists, the error message now always suggests the use of the ``overwrite=True`` argument. The wording is now consistent for all I/O formats. [#12179] astropy.io.ascii ^^^^^^^^^^^^^^^^ - Removed deprecated ``overwrite=None`` option for ``astropy.io.ascii.ui.write()``. Overwriting existing files now only happens if ``overwrite=True``. [#12171] astropy.io.fits ^^^^^^^^^^^^^^^ - The internal class _CardAccessor is no longer registered as a subclass of the Sequence or Mapping ABCs. [#11923] - The deprecated ``clobber`` argument will be removed from the ``astropy.io.fits`` functions in version 5.1, and the deprecation warnings now announce that too. [#12311] astropy.io.registry ^^^^^^^^^^^^^^^^^^^ - The ``write`` function now is allowed to return possible content results, which means that custom writers could, for example, create and return an instance of some container class rather than a file on disk. [#11916] - The registry functions are refactored into a class-based system. New Read-only, write-only, and read/write registries can be created. All functions accept a new argument ``registry``, which if not specified, defaults to the global default registry. [#12015] astropy.io.votable ^^^^^^^^^^^^^^^^^^ - Deprecated the ``pedantic`` keyword argument in the ``astropy.io.votable.table.parse`` function and the corresponding configuration setting. It has been replaced by the ``verify`` option. [#12129] astropy.modeling ^^^^^^^^^^^^^^^^ - Refactored how ``astropy.modeling.Model`` handles model evaluation in order to better organize the code. [#11931] - Removed the following deprecated modeling features: ``astropy.modeling.utils.ExpressionTree`` class, ``astropy.modeling.functional_models.MexicanHat1D`` model, ``astropy.modeling.functional_models.MexicanHat2D`` model, ``astropy.modeling.core.Model.inputs`` setting in model initialize, ``astropy.modeling.core.CompoundModel.inverse`` setting in model initialize, and ``astropy.modeling.core.CompoundModel.both_inverses_exist()`` method. [#11978] - Deprecated the ``AliasDict`` class in ``modeling.utils``. [#12411] astropy.nddata ^^^^^^^^^^^^^^ - Removed ``block_reduce`` and ``block_replicate`` functions from ``nddata.utils``. These deprecated functions in ``nddata.utils`` were moved to ``nddata.blocks``. [#12288] astropy.stats ^^^^^^^^^^^^^ - Removed the following deprecated features from ``astropy.stats``: * ``conf`` argument for ``funcs.binom_conf_interval()`` and ``funcs.binned_binom_proportion()``, * ``conflevel`` argument for ``funcs.poisson_conf_interval()``, and * ``conf_lvl`` argument for ``jackknife.jackknife_stats()``. [#12200] astropy.table ^^^^^^^^^^^^^ - Printing a ``Table`` now shows the qualified class name of mixin columns in the dtype header row instead of "object". This applies to all the ``Table`` formatted output methods whenever ``show_dtype=True`` is selected. [#11660] - The 'overwrite' argument has been added to the jsviewer table writer. Overwriting an existing file requires 'overwrite' to be True. [#11853] - The 'overwrite' argument has been added to the pandas table writers. Overwriting an existing file requires 'overwrite' to be True. [#11854] - The table ``join`` function now accepts only the first four arguments ``left``, ``right``, ``keys``, and ``join_type`` as positional arguments. All other arguments must be supplied as keyword arguments. [#11954] - Adding a dask array to a Table will no longer convert that dask to a Numpy array, so accessing t['dask_column'] will now return a dask array instead of a Numpy array. [#12219] astropy.time ^^^^^^^^^^^^ - Along with the new method ``earth_rotation_angle``, ``sidereal_time`` now accepts an ``EarthLocation`` as the ``longitude`` argument. [#11680] astropy.units ^^^^^^^^^^^^^ - Unit ``littleh`` and equivalency ``with_H0`` have been moved to the ``cosmology`` module and are deprecated from ``astropy.units``. [#12092] astropy.utils ^^^^^^^^^^^^^ - ``astropy.utils.introspection.minversion()`` now uses ``importlib.metadata.version()``. Therefore, its ``version_path`` keyword is no longer used and deprecated. This keyword will be removed in a future release. [#11714] - Updated ``utils.console.Spinner`` to better resemble the API of ``utils.console.ProgressBar``, including an ``update()`` method and iterator support. [#11772] - Removed deprecated ``check_hashes`` in ``check_download_cache()``. The function also no longer returns anything. [#12293] - Removed unused ``download_cache_lock_attempts`` configuration item in ``astropy.utils.data``. Deprecation was not possible. [#12293] - Removed deprecated ``hexdigest`` keyword from ``import_file_to_cache()``. [#12293] - Setting ``remote_timeout`` configuration item in ``astropy.utils.data`` to 0 will no longer disable download from the Internet; Set ``allow_internet`` configuration item to ``False`` instead. [#12293] astropy.visualization ^^^^^^^^^^^^^^^^^^^^^ - Removed deprecated ``imshow_only_kwargs`` keyword from ``imshow_norm``. [#12290] astropy.wcs ^^^^^^^^^^^ - Move complex logic from ``HighLevelWCSMixin.pixel_to_world`` and ``HighLevelWCSMixin.world_to_pixel`` into the helper functions ``astropy.wcs.wcsapi.high_level_api.high_level_objects_to_values`` and ``astropy.wcs.wcsapi.high_level_api.values_to_high_level_objects`` to allow reuse in other places. [#11950] Bug Fixes --------- astropy.config ^^^^^^^^^^^^^^ - ``generate_config`` no longer outputs wrong syntax for list type. [#12037] astropy.constants ^^^^^^^^^^^^^^^^^ - Fixed a bug where an older constants version cannot be set directly after astropy import. [#12084] astropy.convolution ^^^^^^^^^^^^^^^^^^^ - Passing an ``array`` argument for any Kernel1D or Kernel2D subclasses (with the exception of CustomKernel) will now raise a ``TypeError``. [#11969] astropy.coordinates ^^^^^^^^^^^^^^^^^^^ - If a ``Table`` containing a ``SkyCoord`` object as a column is written to a FITS, ECSV or HDF5 file then any velocity information that might be present will be retained. [#11750] - The output of ``SkyCoord.apply_space_motion()`` now always has the same differential type as the ``SkyCoord`` itself. [#11932] - Fixed bug where Angle, Latitude and Longitude with NaN values could not be printed. [#11943] - Fixed a bug with the transformation from ``PrecessedGeocentric`` to ``GCRS`` where changes in ``obstime``, ``obsgeoloc``, or ``obsgeovel`` were ignored. This bug would also affect loopback transformations from one ``PrecessedGeocentric`` frame to another ``PrecessedGeocentric`` frame. [#12152] - Fixed a bug with the transformations between ``TEME`` and ``ITRS`` or between ``TEME`` and itself where a change in ``obstime`` was ignored. [#12152] - Avoid unnecessary transforms through CIRS for AltAz and HADec and use ICRS as intermediate frame for these transformations instead. [#12203] - Fixed a bug where instantiating a representation with a longitude component could mutate input provided for that component even when copying is specified. [#12307] - Wrapping an ``Angle`` array will now ignore NaN values instead of attempting to wrap them, which would produce unexpected warnings/errors when working with coordinates and representations due to internal broadcasting. [#12317] astropy.cosmology ^^^^^^^^^^^^^^^^^ - Dictionaries for in-built cosmology realizations are not altered by creating the realization and are also made immutable. [#12278] astropy.io.fits ^^^^^^^^^^^^^^^ - Prevent zero-byte writes for FITS binary tables to speed up writes on the Lustre filesystem. [#11955] - Enable ``json.dump`` for FITS_rec with variable length (VLF) arrays. [#11957] - Add support for reading and writing int8 images [#11996] - Ensure header passed to ``astropy.io.fits.CompImageHDU`` does not need to contain standard cards that can be automatically generated, such as ``BITPIX`` and ``NAXIS``. [#12061] - Fixed a bug where ``astropy.io.fits.HDUDiff`` would ignore the ``ignore_blank_cards`` keyword argument. [#12122] - Open uncompressed file even if extension says it's compressed [#12135] - Fix the computation of the DATASUM in a ``CompImageHDU`` when the data is >1D. [#12138] - Reading files where the SIMPLE card is present but with an invalid format now issues a warning instead of raising an exception [#12234] - Convert UNDEFINED to None when iterating over card values. [#12310] astropy.io.misc ^^^^^^^^^^^^^^^ - Update ASDF tag versions in ExtensionType subclasses to match ASDF Standard 1.5.0. [#11986] - Fix ASDF serialization of model inputs and outputs and add relevant assertion to test helper. [#12381] - Fix bug preventing ASDF serialization of bounding box for models with only one input. [#12385] astropy.io.votable ^^^^^^^^^^^^^^^^^^ - Now accepting UCDs containing phot.color. [#11982] astropy.modeling ^^^^^^^^^^^^^^^^ - Added ``Parameter`` descriptions to the implemented models which were missing. [#11232] - The ``separable`` property is now correctly set on models constructed with ``astropy.modeling.custom_model``. [#11744] - Minor bugfixes and improvements to modeling including the following: * Fixed typos and clarified several errors and their messages throughout modeling. * Removed incorrect try/except blocks around scipy code in ``convolution.py`` and ``functional_models.py``. * Fixed ``Ring2D`` model's init to properly accept all combinations of ``r_in``, ``r_out``, and ``width``. * Fixed bug in ``tau`` validator for the ``Logarithmic1D`` and ``Exponential1D`` models when using them as model sets. * Fixed ``copy`` method for ``Parameter`` in order to prevent an automatic ``KeyError``, and fixed ``bool`` for ``Parameter`` so that it functions with vector values. * Removed unreachable code from ``Parameter``, the ``_Tabular`` model, and the ``Drude1D`` model. * Fixed validators in ``Drude1D`` model so that it functions in a model set. * Removed duplicated code from ``polynomial.py`` for handing of ``domain`` and ``window``. * Fixed the ``Pix2Sky_HEALPixPolar`` and ``Sky2Pix_HEALPixPolar`` modes so that their ``evaluate`` and ``inverse`` methods actually work without raising an error. [#12232] astropy.nddata ^^^^^^^^^^^^^^ - Ensure that the ``wcs=`` argument to ``NDData`` is always parsed into a high level WCS object. [#11985] astropy.stats ^^^^^^^^^^^^^ - Fixed a bug in sigma clipping where the bounds would not be returned for completely empty or masked data. [#11994] - Fixed a bug in ``biweight_midvariance`` and ``biweight_scale`` where output data units would be dropped for constant data and where the result was a scalar NaN. [#12146] astropy.table ^^^^^^^^^^^^^ - Ensured that ``MaskedColumn.info`` is propagated in all cases, so that when tables are sliced, writing will still be as requested on ``info.serialize_method``. [#11917] - ``table.conf.replace_warnings`` and ``table.jsviewer.conf.css_urls`` configuration items now have correct ``'string_list'`` type. [#12037] - Fixed an issue where initializing from a list of dict-like rows (Mappings) did not work unless the row values were instances of ``dict``. Now any object that is an instance of the more general ``collections.abc.Mapping`` will work. [#12417] astropy.uncertainty ^^^^^^^^^^^^^^^^^^^ - Ensure that scalar ``QuantityDistribution`` unit conversion in ufuncs works properly again. [#12471] astropy.units ^^^^^^^^^^^^^ - Add quantity support for ``scipy.special`` dimensionless functions erfinv, erfcinv, gammaln and loggamma. [#10934] - ``VOUnit.to_string`` output is now compliant with IVOA VOUnits 1.0 standards. [#11565] - Units initialization with unicode has been expanded to include strings such as 'M☉' and 'eâģ'. [#11827] - Give a more informative ``NotImplementedError`` when trying to parse a unit using an output-only format such as 'unicode' or 'latex'. [#11829] astropy.utils ^^^^^^^^^^^^^ - Fixed a bug in ``get_readable_fileobj`` that prevented the unified file read interface from closing ASCII files. [#11809] - The function ``astropy.utils.decorators.deprecated_attribute()`` no longer ignores its ``message``, ``alternative``, and ``pending`` arguments. [#12184] - Ensure that when taking the minimum or maximum of a ``Masked`` array, any masked NaN values are ignored. [#12454] astropy.visualization ^^^^^^^^^^^^^^^^^^^^^ - The tick labelling for radians has been fixed to remove a redundant ``.0`` in the label for integer multiples of pi at 2pi and above. [#12221] - Fix a bug where non-``astropy.wcs.WCS`` WCS instances were not accepted in ``WCSAxes.get_transform``. [#12286] - Fix compatibility with Matplotlib 3.5 when using the ``grid_type='contours'`` mode for drawing grid lines. [#12447] astropy.wcs ^^^^^^^^^^^ - Enabled ``SlicedLowLevelWCS.pixel_to_world_values`` to handle slices including non-``int`` integers, e.g. ``numpy.int64``. [#11980] Other Changes and Additions --------------------------- - In docstrings, Sphinx cross-reference targets now use intersphinx, even if the target is an internal link (``link`` is now ``'astropy:link``). When built in Astropy these links are interpreted as internal links. When built in affiliate packages, the link target is set by the key 'astropy' in the intersphinx mapping. [#11690] - Made PyYaml >= 3.13 a strict runtime dependency. [#11903] - Minimum version of required Python is now 3.8. [#11934] - Minimum version of required Scipy is now 1.3. [#11934] - Minimum version of required Matplotlib is now 3.1. [#11934] - Minimum version of required Numpy is now 1.18. [#11935] - Fix deprecation warnings with Python 3.10 [#11962] - Speed up ``minversion()`` in cases where a module with a ``__version__`` attribute is passed. [#12174] - ``astropy`` now requires ``packaging``. [#12199] - Updated the bundled CFITSIO library to 4.0.0. When compiling with an external library, version 3.35 or later is required. [#12272] 4.3.1 (2021-08-11) ================== Bug Fixes --------- astropy.io.fits ^^^^^^^^^^^^^^^ - In ``fits.io.getdata`` do not fall back to first non-primary extension when user explicitly specifies an extension. [#11860] - Ensure multidimensional masked columns round-trip properly to FITS. [#11911] - Ensure masked times round-trip to FITS, even if multi-dimensional. [#11913] - Raise ``ValueError`` if an ``np.float32`` NaN/Inf value is assigned to a header keyword. [#11922] astropy.modeling ^^^^^^^^^^^^^^^^ - Fixed bug in ``fix_inputs`` handling of bounding boxes. [#11908] astropy.table ^^^^^^^^^^^^^ - Fix an error when converting to pandas any ``Table`` subclass that automatically adds a table index when the table is created. An example is a binned ``TimeSeries`` table. [#12018] astropy.units ^^^^^^^^^^^^^ - Ensure that unpickling quantities and units in new sessions does not change hashes and thus cause problems with (de)composition such as getting different answers from the ``.si`` attribute. [#11879] - Fixed cannot import name imperial from astropy.units namespace. [#11977] astropy.utils ^^^^^^^^^^^^^ - Ensure any ``.info`` on ``Masked`` instances is propagated correctly when viewing or slicing. As a consequence, ``MaskedQuantity`` can now be correctly written to, e.g., ECSV format with ``serialize_method='data_mask'``. [#11910] 4.3 (2021-07-26) ================ New Features ------------ astropy.convolution ^^^^^^^^^^^^^^^^^^^ - Change padding sizes for ``fft_pad`` in ``convolve_fft`` from powers of 2 only to scipy-optimized numbers, applied separately to each dimension; yielding some performance gains and avoiding potential large memory impact for certain multi-dimensional inputs. [#11533] astropy.coordinates ^^^^^^^^^^^^^^^^^^^ - Adds the ability to create topocentric ``CIRS`` frames. Using these, ``AltAz`` calculations are now accurate down to the milli-arcsecond level. [#10994] - Adds a direct transformation from ``ICRS`` to ``AltAz`` frames. This provides a modest speedup of approximately 10 percent. [#11079] - Adds new ``WGS84GeodeticRepresentation``, ``WGS72GeodeticRepresentation``, and ``GRS80GeodeticRepresentation``. These are mostly for use inside ``EarthLocation`` but can also be used to convert between geocentric (cartesian) and different geodetic representations directly. [#11086] - ``SkyCoord.guess_from_table`` now also searches for differentials in the table. In addition, multiple regex matches can be resolved when they are exact component names, e.g. having both columns “dec” and “pm_dec” no longer errors and will be included in the SkyCoord. [#11417] - All representations now have a ``transform`` method, which allows them to be transformed by a 3x3 matrix in a Cartesian basis. By default, transformations are routed through ``CartesianRepresentation``. ``SphericalRepresentation`` and ``PhysicssphericalRepresentation`` override this for speed and to prevent NaN leakage from the distance to the angular components. Also, the functions ``is_O3`` and ``is_rotation`` have been added to ``matrix_utities`` for checking whether a matrix is in the O(3) group or is a rotation (proper or improper), respectively. [#11444] - Moved angle formatting and parsing utilities to ``astropy.coordinates.angle_formats``. Added new functionality to ``astropy.coordinates.angle_utilities`` for generating points on or in spherical surfaces, either randomly or on a grid. [#11628] - Added a new method to ``SkyCoord``, ``spherical_offsets_by()``, which is the conceptual inverse of ``spherical_offsets_to()``: Given angular offsets in longitude and latitude, this method returns a new coordinate with the offsets applied. [#11635] - Refactor conversions between ``GCRS`` and ``CIRS,TETE`` for better accuracy and substantially improved speed. [#11069] - Also refactor ``EarthLocation.get_gcrs`` for an increase in performance of an order of magnitude, which enters as well in getting observed positions of planets using ``get_body``. [#11073] - Refactored the usage of metaclasses in ``astropy.coordinates`` to instead use ``__init_subclass__`` where possible. [#11090] - Removed duplicate calls to ```transform_to``` from ```match_to_catalog_sky``` and ```match_to_catalog_3d```, improving their performance. [#11449] - The new DE440 and DE440s ephemerides are now available via shortcuts 'de440' and 'de440s'. The DE 440s ephemeris will probably become the default ephemeris when chosing 'jpl' in 5.0. [#11601] astropy.cosmology ^^^^^^^^^^^^^^^^^ - Cosmology parameter dictionaries now also specify the Cosmology class to which the parameters correspond. For example, the dictionary for ``astropy.cosmology.parameters.Planck18`` has the added key-value pair ("cosmology", "FlatLambdaCDM"). [#11530] astropy.io.ascii ^^^^^^^^^^^^^^^^ - Added support for reading and writing ASCII tables in QDP (Quick and Dandy Plotter) format. [#11256] - Added support for reading and writing multidimensional column data (masked and unmasked) to ECSV. Also added formal support for reading and writing object-type column data which can contain items consisting of lists, dicts, and basic scalar types. This can be used to store columns of variable-length arrays. Both of these features use JSON to convert the object to a string that is stored in the ECSV output. [#11569, #11662, #11720] astropy.io.fits ^^^^^^^^^^^^^^^ - Added ``append`` keyword to append table objects to an existing FITS file [#2632, #11149] - Check that the SIMPLE card is present when opening a file, to ensure that the file is a valid FITS file and raise a better error when opening a non FITS one. ``ignore_missing_simple`` can be used to skip this verification. [#10895] - Expose ``Header.strip`` as a public method, to remove the most common structural keywords. [#11174] - Enable the use of ``os.PathLike`` objects when dealing with (mainly FITS) files. [#11580] astropy.io.registry ^^^^^^^^^^^^^^^^^^^ - Readers and writers can now set a priority, to assist with resolving which format to use. [#11214] astropy.io.votable ^^^^^^^^^^^^^^^^^^ - Version 1.4 VOTables now use the VOUnit format specification. [#11032] - When reading VOTables using the Unified File Read/Write Interface (i.e. using the ``Table.read()`` or ``QTable.read()`` functions) it is now possible to specify all keyword arguments that are valid for ``astropy.io.votable.table.parse()``. [#11643] astropy.modeling ^^^^^^^^^^^^^^^^ - Added a state attribute to models to allow preventing the synching of constraint values from the constituent models. This synching can greatly slow down fitting if there are large numbers of fit parameters. model.sync_constraints = True means check constituent model constraints for compound models every time the constraint is accessed, False, do not. Fitters that support constraints will set this to False on the model copy and then set back to True when the fit is complete before returning. [#11365] - The ``convolve_models_fft`` function implements model convolution so that one insures that the convolution remains consistent across multiple different inputs. [#11456] astropy.nddata ^^^^^^^^^^^^^^ - Prevent unnecessary copies of the data during ``NDData`` arithmetic when units need to be added. [#11107] - NDData str representations now show units, if present. [#11553] astropy.stats ^^^^^^^^^^^^^ - Added the ability to specify stdfunc='mad_std' when doing sigma clipping, which will use a built-in function and lead to significant performance improvements if cenfunc is 'mean' or 'median'. [#11664] - Significantly improved the performance of sigma clipping when cenfunc and stdfunc are passed as strings and the ``grow`` option is not used. [#11219] - Improved performance of ``bayesian_blocks()`` by removing one ``np.log()`` call [#11356] astropy.table ^^^^^^^^^^^^^ - Add table attributes to include or exclude columns from the output when printing a table. This functionality includes a context manager to include/exclude columns temporarily. [#11190] - Improved the string representation of objects related to ``Table.indices`` so they now indicate the object type and relevant attributes. [#11333] astropy.timeseries ^^^^^^^^^^^^^^^^^^ - An exception is raised when ``n_bins`` is passed as an argument while any of the parameters ``time_bin_start`` or ``time_bin_size`` is not scalar. [#11463] astropy.units ^^^^^^^^^^^^^ - The ``physical_type`` attributes of each unit are now objects of the (new) ``astropy.units.physical.PhysicalType`` class instead of strings and the function ``astropy.units.physical.get_physical_type`` can now translate strings to these objects. [#11204] - The function ``astropy.units.physical.def_physical_type`` was created to either define entirely new physical types, or to add more physical type names to an existing physical types. [#11204] - ``PhysicalType``'s can be operated on using operations multiplication, division, and exponentiation are to facilitate dimensional analysis. [#11204] - It is now possible to define aliases for units using ``astropy.units.set_enabled_aliases``. This can be used when reading files that have misspelled units. [#11258] - Add a new "DN" unit, ``units.dn`` or ``units.DN``, representing data number for a detector. [#11591] astropy.utils ^^^^^^^^^^^^^ - Added ``ssl_context`` and ``allow_insecure`` options to ``download_file``, as well as the ability to optionally use the ``certifi`` package to provide root CA certificates when downloading from sites secured with TLS/SSL. [#10434] - ``astropy.utils.data.get_pkg_data_path`` is publicly scoped (previously the private function ``_find_pkg_data_path``) for obtaining file paths without checking if the file/directory exists, as long as the package and module do. [#11006] - Deprecated ``astropy.utils.OrderedDescriptor`` and ``astropy.utils.OrderedDescriptorContainer``, as new features in Python 3 make their use less compelling. [#11094, #11099] - ``astropy.utils.masked`` provides a new ``Masked`` class/factory that can be used to represent masked ``ndarray`` and all its subclasses, including ``Quantity`` and its subclasses. These classes can be used inside coordinates, but the mask is not yet exposed. Generally, the interface should be considered experimental. [#11127, #11792] - Add new ``utils.parsing`` module to with helper wrappers around ``ply``. [#11227] - Change the Time and IERS leap second handling so that the leap second table is updated only when a Time transform involving UTC is performed. Previously this update check was done the first time a ``Time`` object was created, which in practice occured when importing common astropy subpackages like ``astropy.coordinates``. Now you can prevent querying internet resources (for instance on a cluster) by setting ``iers.conf.auto_download = False``. This can be done after importing astropy but prior to performing any ``Time`` scale transformations related to UTC. [#11638] - Added a new module at ``astropy.utils.compat.optional_deps`` to consolidate the definition of ``HAS_x`` optional dependency flag variables, like ``HAS_SCIPY``. [#11490] astropy.wcs ^^^^^^^^^^^ - Add IVOA UCD mappings for some FITS WCS keywords commonly used in solar physics. [#10965] - Add ``STOKES`` FITS WCS keyword to the IVOA UCD mapping. [#11236] - Updated bundled version of WCSLIB to version 7.6. See https://www.atnf.csiro.au/people/mcalabre/WCS/CHANGES for a list of included changes. [#11549] API Changes ----------- astropy.coordinates ^^^^^^^^^^^^^^^^^^^ - For input to representations, subclasses of the class required for a given attribute will now be allowed in. [#11113] - Except for ``UnitSphericalRepresentation``, shortcuts in representations now allow for attached differentials. [#11467] - Allow coordinate name strings as input to ``SkyCoord.is_transformable_to``. [#11552] astropy.cosmology ^^^^^^^^^^^^^^^^^ - Change ``z_at_value`` to use ``scipy.optimize.minimize_scalar`` with default method ``Brent`` (other options ``Bounded`` and ``Golden``) and accept ``bracket`` option to set initial search region. [#11080] - Clarified definition of inputs to ``angular_diameter_distance_z1z2``. The function now emits ``AstropyUserWarning`` when ``z2`` is less than ``z1``. [#11197] - Split cosmology realizations from core classes, moving the former to new file ``realizations``. [#11345] - Since cosmologies are immutable, the initialization signature and values can be stored, greatly simplifying cloning logic and extending it to user-defined cosmology classes that do not have attributes with the same name as each initialization argument. [#11515] - Cloning a cosmology with changed parameter(s) now appends "(modified)" to the new instance's name, unless a name is explicitly passed to ``clone``. [#11536] - Allow ``m_nu`` to be input as any quantity-like or array-like -- Quantity, array, float, str, etc. Input is passed to the Quantity constructor and converted to eV, still with the prior mass-energy equivalence enabled. [#11640] astropy.io.fits ^^^^^^^^^^^^^^^ - For conversion between FITS tables and astropy ``Table``, the standard mask values of ``NaN`` for float and null string for string are now properly recognized, leading to a ``MaskedColumn`` with appropriately set mask instead of a ``Column`` with those values exposed. Conversely, when writing an astropy ``Table`` to a FITS tables, masked values are now consistently converted to the standard FITS mask values of ``NaN`` for float and null string for string (i.e., not just for tables with ``masked=True``, which no longer is guaranteed to signal the presence of ``MaskedColumn``). [#11222] astropy.io.votable ^^^^^^^^^^^^^^^^^^ - The use of ``version='1.0'`` is now fully deprecated in constructing a ``astropy.io.votable.tree.VOTableFile``. [#11659] astropy.modeling ^^^^^^^^^^^^^^^^ - Removed deprecated ``astropy.modeling.blackbody`` module. [#10972] astropy.table ^^^^^^^^^^^^^ - Added ``Column.value`` as an alias for the existing ``Column.data`` attribute. This makes accessing a column's underlying data array consistent with the ``.value`` attribute available for ``Time`` and ``Quantity`` objects. [#10962] - In reading from a FITS tables, the standard mask values of ``NaN`` for float and null string for string are properly recognized, leading to a ``MaskedColumn`` with appropriately set mask. [#11222] - Changed the implementation of the ``table.index.Index`` class so instantiating from this class now returns an ``Index`` object as expected instead of a ``SlicedIndex`` object. [#11333] astropy.units ^^^^^^^^^^^^^ - The ``physical_type`` attribute of units now returns an instance of ``astropy.units.physical.PhysicalType`` instead of a string. Because ``PhysicalType`` instances can be compared to strings, no code changes should be necessary when making comparisons. The string representations of different physical types will differ from previous releases. [#11204] - Calling ``Unit()`` with no argument now returns a dimensionless unit, as was documented but not implemented. [#11295] astropy.utils ^^^^^^^^^^^^^ - Removed deprecated ``utils.misc.InheritDocstrings`` and ``utils.timer``. [#10281] - Removed usage of deprecated ``ipython`` stream in ``utils.console``. [#10942] astropy.wcs ^^^^^^^^^^^ - Deprecate ``accuracy`` argument in ``all_world2pix`` which was mistakenly *documented*, in the case ``accuracy`` was ever used. [#11055] Bug Fixes --------- astropy.convolution ^^^^^^^^^^^^^^^^^^^ - Fixes for ``convolve_fft`` documentation examples. [#11510] astropy.coordinates ^^^^^^^^^^^^^^^^^^^ - Allow ``Distance`` instances with negative distance values as input for ``SphericalRepresentation``. This was always noted as allowed in an exception message when a negative ``Quantity`` with length units was passed in, but was not actually possible to do. [#11113] - Makes the ``Angle.to_string`` method to follow the format described in the docstring with up to 8 significant decimals instead of 4. [#11153] - Ensure that proper motions can be calculated when converting a ``SkyCoord`` with cartesian representation to unit-spherical, by fixing the conversion of ``CartesianDifferential`` to ``UnitSphericalDifferential``. [#11469] - When re-representing coordinates from spherical to unit-spherical and vice versa, the type of differential will now be preserved. For instance, if only a radial velocity was present, that will remain the case (previously, a zero proper motion component was added). [#11482] - Ensure that wrapping of ``Angle`` does not raise a warning even if ``nan`` are present. Also try to make sure that the result is within the wrapped range even in the presence of rounding errors. [#11568] - Comparing a non-SkyCoord object to a ``SkyCoord`` using ``==`` no longer raises an error. [#11666] - Different ``SkyOffsetFrame`` classes no longer interfere with each other, causing difficult to debug problems with the ``origin`` attribute. The ``origin`` attribute now no longer is propagated, so while it remains available on a ``SkyCoord`` that is an offset, it no longer is available once that coordinate is transformed to another frame. [#11730] [#11730] astropy.cosmology ^^^^^^^^^^^^^^^^^ - Cosmology instance names are now immutable. [#11535] astropy.io.ascii ^^^^^^^^^^^^^^^^ - Fixed bug where writing a table that has comments defined (via ``tbl.meta['comments']``) with the 'csv' format was failing. Since the formally defined CSV format does not support comments, the comments are now just ignored unless ``comment=`` is supplied to the ``write()`` call. [#11475] - Fixed the issue where the CDS reader failed to treat columns as nullable if the ReadMe file contains a limits specifier. [#11531] - Made sure that the CDS reader does not ignore an order specifier that may be present after the null specifier '?'. Also made sure that it checks null values only when an '=' symbol is present and reads description text even if there is no whitespace after '?'. [#11593] astropy.io.fits ^^^^^^^^^^^^^^^ - Fix ``ColDefs.add_col/del_col`` to allow in-place addition or removal of a column. [#11338] - Fix indexing of ``fits.Header`` with Numpy integers. [#11387] - Do not delete ``EXTNAME`` for compressed image header if a default and non-default ``EXTNAME`` are present. [#11396] - Prevent warnings about ``HIERARCH`` with ``CompImageHeader`` class. [#11404] - Fixed regression introduced in Astropy 4.0.5 and 4.2.1 with verification of FITS headers with HISTORY or COMMENT cards with long (> 72 characters) values. [#11487] - Fix reading variable-length arrays when there is a gap between the data and the heap. [#11688] astropy.io.votable ^^^^^^^^^^^^^^^^^^ - ``NumericArray`` converter now properly broadcasts scalar mask to array. [#11157] - VOTables are now written with the correct namespace and schema location attributes. [#11659] astropy.modeling ^^^^^^^^^^^^^^^^ - Fixes the improper propagation of ``bounding_box`` from ``astropy.modeling.models`` to their inverses. For cases in which the inverses ``bounding_box`` can be determined, the proper calculation has been implemented. [#11414] - Bugfix to allow rotation models to accept arbitrarily-shaped inputs. [#11435] - Bugfixes for ``astropy.modeling`` to allow ``fix_inputs`` to accept empty dictionaries and dictionaries with ``numpy`` integer keys. [#11443] - Bugfix for how ``SPECIAL_OPERATORS`` are handled. [#11512] - Fixes ``Model`` crashes when some inputs are scalars and during some types of output reshaping. [#11548] - Fixed bug in ``LevMarLSQFitter`` when using weights and vector inputs. [#11603] astropy.stats ^^^^^^^^^^^^^ - Fixed a bug with the ``copy=False`` option when carrying out sigma clipping - previously if ``masked=False`` this still copied the data, but this will now change the array in-place. [#11219] astropy.table ^^^^^^^^^^^^^ - Ensure that adding a ``Quantity`` or other mixin column to a ``Table`` does not have side effects, such as creating an associated ``info`` instance (which would lead to slow-down of, e.g., slicing afterwards). [#11077] - When writing to a FITS tables, masked values are again always converted to the standard FITS mask values of ``NaN`` for float and null string for string, not just for table with ``masked=True``. [#11222] - Using ``Table.to_pandas()`` on an indexed ``Table`` with masked integer values now correctly construct the ``pandas.DataFrame``. [#11432] - Fixed ``Table`` HTML representation in Jupyter notebooks so that it is horizontally scrollable within Visual Studio Code. This was done by wrapping the ```` in a ``
`` element. [#11476] - Fix a bug where a string-valued ``Column`` that happened to have a ``unit`` attribute could not be added to a ``QTable``. Such columns are now simply kept as ``Column`` instances (with a warning). [#11585] - Fix an issue in ``Table.to_pandas(index=)`` where the index column name was not being set properly for the ``DataFrame`` index. This was introduced by an API change in pandas version 1.3.0. Previously when creating a ``DataFrame`` with the index set to an astropy ``Column``, the ``DataFrame`` index name was automatically set to the column name. [#11921] astropy.time ^^^^^^^^^^^^ - Fix a thread-safety issue with initialization of the leap-second table (which is only an issue when ERFA's built-in table is out of date). [#11234] - Fixed converting a zero-length time object from UTC to UT1 when an empty array is passed. [#11516] astropy.uncertainty ^^^^^^^^^^^^^^^^^^^ - ``Distribution`` instances can now be used as input to ``Quantity`` to initialize ``QuantityDistribution``. Hence, ``distribution * unit`` and ``distribution << unit`` will work too. [#11210] astropy.units ^^^^^^^^^^^^^ - Move non-astronomy units from astrophys.py to a new misc.py file. [#11142] - The physical type of ``astropy.units.mol / astropy.units.m ** 3`` is now defined as molar concentration. It was previously incorrectly defined as molar volume. [#11204] - Make ufunc helper lookup thread-safe. [#11226] - Make ``Unit`` string parsing (as well as ``Angle`` parsing) thread-safe. [#11227] - Decorator ``astropy.units.decorators.quantity_input`` now only evaluates return type annotations based on ``UnitBase`` or ``FunctionUnitBase`` types. Other annotations are skipped over and are not attempted to convert to the correct type. [#11506] astropy.utils ^^^^^^^^^^^^^ - Make ``lazyproperty`` and ``classdecorator`` thread-safe. This should fix a number of thread safety issues. [#11224] astropy.visualization ^^^^^^^^^^^^^^^^^^^^^ - Fixed a bug that resulted in some parts of grid lines being visible when they should have been hidden. [#11380] - Fixed a bug that resulted in ``time_support()`` failing for intervals of a few months if one of the ticks was the month December. [#11615] astropy.wcs ^^^^^^^^^^^ - ``fit_wcs_from_points`` now produces a WCS with integer ``NAXIXn`` values. [#10865] - Updated bundled version of ``WCSLIB`` to v7.4, fixing a bug that caused the coefficients of the TPD distortion function to not be written to the header. [#11260] - Fixed a bug in assigning type when converting ``colsel`` to ``numpy.ndarray``. [#11431] - Added ``WCSCOMPARE_*`` constants to the list of WCSLIB constants available/exposed through the ``astropy.wcs`` module. [#11647] - Fix a bug that caused APE 14 WCS transformations for FITS WCS with ZOPT, BETA, VELO, VOPT, or VRAD CTYPE to not work correctly. [#11781] Other Changes and Additions --------------------------- - The configuration file is no longer created by default when importing astropy and its existence is no longer required. Affiliated packages should update their ``__init__.py`` module to remove the block using ``update_default_config`` and ``ConfigurationDefaultMissingWarning``. [#10877] - Replace ``pkg_resources`` (from setuptools) with ``importlib.metadata`` which comes from the stdlib, except for Python 3.7 where the backport package is added as a new dependency. [#11091] - Turn on numpydoc's ``numpydoc_xref_param_type`` to create cross-references for the parameter types in the Parameters, Other Parameters, Returns and Yields sections of the docstrings. [#11118] - Docstrings across the package are standardized to enable references. Also added is an Astropy glossary-of-terms to define standard inputs, e.g. ``quantity-like`` indicates an input that can be interpreted by ``astropy.units.Quantity``. [#11118] - Binary wheels are now built to the manylinux2010 specification. These wheels should be supported on all versions of pip shipped with Python 3.7+. [#11377] - The name of the default branch for the astropy git repository has been renamed to ``main``, and the documentation and tooling has been updated accordingly. If you have made a local clone you may wish to update it following the instructions in the repository's README. [#11379] - Sphinx cross-reference link targets are added for every ``PhysicalType``. Now in the parameter types in the Parameters, Other Parameters, Returns and Yields sections of the docstring, the physical type of a quantity can be annotated in square brackets. E.g. `` distance : `~astropy.units.Quantity` ['length'] `` [#11595] - The minimum supported version of ``ipython`` is now 4.2. [#10942] - The minimum supported version of ``pyerfa`` is now 1.7.3. [#11637] 4.2.1 (2021-04-01) ================== Bug Fixes --------- astropy.cosmology ^^^^^^^^^^^^^^^^^ - Fixed an issue where specializations of the comoving distance calculation for certain cosmologies could not handle redshift arrays. [#10980] astropy.io.fits ^^^^^^^^^^^^^^^ - Fix bug where manual fixes to invalid header cards were not preserved when saving a FITS file. [#11108] astropy.io.votable ^^^^^^^^^^^^^^^^^^ - ``NumericArray`` converter now properly broadcasts scalar mask to array. [#11157] astropy.table ^^^^^^^^^^^^^ - Fix bug when initializing a ``Table`` subclass that uses ``TableAttribute``'s. If the data were an instance of the table then attributes provided in the table initialization call could be ignored. [#11217] astropy.time ^^^^^^^^^^^^ - Change epoch of ``TimeUnixTAI`` (``"unix_tai"``) from ``1970-01-01T00:00:00 UTC`` to ``1970-01-01T00:00:00 TAI`` to match the intended and documented behaviour. This essentially changes the resulting times by 8.000082 seconds, the initial offset between TAI and UTC. [#11249] astropy.units ^^^^^^^^^^^^^ - Fixed a bug with the ``quantity_input`` decorator where allowing dimensionless inputs for an argument inadvertently disabled any checking of compatible units for that argument. [#11283] astropy.utils ^^^^^^^^^^^^^ - Fix a bug so that ``np.shape``, ``np.ndim`` and ``np.size`` again work on classes that use ``ShapedLikeNDArray``, like representations, frames, sky coordinates, and times. [#11133] astropy.wcs ^^^^^^^^^^^ - Fix error when a user defined ``proj_point`` parameter is passed to ``fit_wcs_from_points``. [#11139] Other Changes and Additions --------------------------- - Change epoch of ``TimeUnixTAI`` (``"unix_tai"``) from ``1970-01-01T00:00:00 UTC`` to ``1970-01-01T00:00:00 TAI`` to match the intended and documented behaviour. This essentially changes the resulting times by 8.000082 seconds, the initial offset between TAI and UTC. [#11249] 4.2 (2020-11-24) ================ New Features ------------ astropy.convolution ^^^^^^^^^^^^^^^^^^^ - Methods ``convolve`` and ``convolve_fft`` both now return Quantity arrays if user input is given in one. [#10822] astropy.coordinates ^^^^^^^^^^^^^^^^^^^ - Numpy functions that broadcast, change shape, or index (like ``np.broadcast_to``, ``np.rot90``, or ``np.roll``) now work on coordinates, frames, and representations. [#10337] - Add a new science state ``astropy.coordinates.erfa_astrom.erfa_astrom`` and two classes ``ErfaAstrom``, ``ErfaAstromInterpolator`` as wrappers to the ``pyerfa`` astrometric functions used in the coordinate transforms. Using ``ErfaAstromInterpolator``, which interpolates astrometric properties for ``SkyCoord`` instances with arrays of obstime, can dramatically speed up coordinate transformations while keeping microarcsecond resolution. Depending on needed precision and the obstime array in question, speed ups reach factors of 10x to >100x. [#10647] - ``galactocentric_frame_defaults`` can now also be used as a registry, with user-defined parameter values and metadata. [#10624] - Method ``.realize_frame`` from coordinate frames now accepts ``**kwargs``, including ``representation_type``. [#10727] - Avoid an unnecessary call to ``erfa.epv00`` in transformations between ``CIRS`` and ``ICRS``, improving performance by 50 %. [#10814] - A new equatorial coordinate frame, with RA and Dec measured w.r.t to the True Equator and Equinox (TETE). This frame is commonly known as "apparent place" and is the correct frame for coordinates returned from JPL Horizons. [#10867] - Added a context manager ``impose_finite_difference_dt`` to the ``TransformGraph`` class to override the finite-difference time step attribute (``finite_difference_dt``) for all transformations in the graph with that attribute. [#10341] - Improve performance of ``SpectralCoord`` by refactoring internal implementation. [#10398] astropy.cosmology ^^^^^^^^^^^^^^^^^ - The final version of the Planck 2018 cosmological parameters are included as the ``Planck18`` object, which is now the default cosmology. The parameters are identical to those of the ``Planck18_arXiv_v2`` object, which is now deprecated and will be removed in a future release. [#10915] astropy.modeling ^^^^^^^^^^^^^^^^ - Added NFW profile and tests to modeling package [#10505] - Added missing logic for evaluate to compound models [#10002] - Stop iteration in ``FittingWithOutlierRemoval`` before reaching ``niter`` if the masked points are no longer changing. [#10642] - Keep a (shallow) copy of ``fit_info`` from the last iteration of the wrapped fitter in ``FittingWithOutlierRemoval`` and also record the actual number of iterations performed in it. [#10642] - Added attributes for fitting uncertainties (covariance matrix, standard deviations) to models. Parameter covariance matrix can be accessed via ``model.cov_matrix``, standard deviations by ``model.stds`` or individually for each parameter by ``parameter.std``. Currently implemented for ``LinearLSQFitter`` and ``LevMarLSQFitter``. [#10552] - N-dimensional least-squares statistic and specific 1,2,3-D methods [#10670] astropy.stats ^^^^^^^^^^^^^ - Added ``circstd`` function to obtain a circular standard deviation. [#10690] astropy.table ^^^^^^^^^^^^^ - Allow initializing a ``Table`` using a list of ``names`` in conjunction with a ``dtype`` from a numpy structured array. The list of ``names`` overrides the names specified in the ``dtype``. [#10419] astropy.time ^^^^^^^^^^^^ - Add new ``isclose()`` method to ``Time`` and ``TimeDelta`` classes to allow comparison of time objects to within a specified tolerance. [#10646] - Improve initialization time by a factor of four when creating a scalar ``Time`` object in a format like ``unix`` or ``cxcsec`` (time delta from a reference epoch time). [#10406] - Improve initialization time by a factor of ~25 or more for large arrays of string times in ISO, ISOT or year day-of-year formats. This is done with a new C-based time parser that can be adapted for other fixed-format custom time formats. [#10360] - Numpy functions that broadcast, change shape, or index (like ``np.broadcast_to``, ``np.rot90``, or ``np.roll``) now work on times. [#10337, #10502] astropy.timeseries ^^^^^^^^^^^^^^^^^^ - Improve memory and speed performance when iterating over the entire time column of a ``TimeSeries`` object. Previously this involved O(N^2) operations and memory. [#10889] astropy.units ^^^^^^^^^^^^^ - ``Quantity.to`` has gained a ``copy`` option to allow copies to be avoided when the units do not change. [#10517] - Added the ``spat`` unit of solid angle that represents the full sphere. [#10726] astropy.utils ^^^^^^^^^^^^^ - ``ShapedLikeNDArray`` has gained the capability to use numpy functions that broadcast, change shape, or index. [#10337] - ``get_free_space_in_dir`` now takes a new ``unit`` keyword and ``check_free_space_in_dir`` takes ``size`` defined as ``Quantity``. [#10627] - New ``astropy.utils.data.conf.allow_internet`` configuration item to control downloading data from the Internet. Setting ``allow_internet=False`` is the same as ``remote_timeout=0``. Using ``remote_timeout=0`` to control internet access will stop working in a future release. [#10632] - New ``is_url`` function so downstream packages do not have to secretly use the hidden ``_is_url`` anymore. [#10684] astropy.visualization ^^^^^^^^^^^^^^^^^^^^^ - Added the ``Quadrangle`` patch for ``WCSAxes`` for a latitude-longitude quadrangle. Unlike ``matplotlib.patches.Rectangle``, the edges of this patch will be rendered as curved lines if appropriate for the WCS transformation. [#10862] - The position of tick labels are now only calculated when needed. If any text parameters are changed (color, font weight, size etc.) that don't effect the tick label position, the positions are not recomputed, improving performance. [#10806] astropy.wcs ^^^^^^^^^^^ - ``WCS.to_header()`` now appends comments to SIP coefficients. [#10480] - A new property ``dropped_world_dimensions`` has been added to ``SlicedLowLevelWCS`` to record information about any world axes removed by slicing a WCS. [#10195] - New ``WCS.proj_plane_pixel_scales()`` and ``WCS.proj_plane_pixel_area()`` methods to return pixel scales and area, respectively, as Quantity. [#10872] API Changes ----------- astropy.config ^^^^^^^^^^^^^^ - ``set_temp_config`` now preserves the existing cache rather than deleting it and relying on reloading it from the previous config file. This ensures that any programmatically made changes are preserved as well. [#10474] - Configuration path detection logic has changed: Now, it looks for ``~`` first before falling back to older logic. In addition, ``HOMESHARE`` is no longer used in Windows. [#10705] astropy.coordinates ^^^^^^^^^^^^^^^^^^^ - The passing of frame classes (as opposed to frame instances) to the ``transform_to()`` methods of low-level coordinate-frame classes has been deprecated. Frame classes can still be passed to the ``transform_to()`` method of the high-level ``SkyCoord`` class, and using ``SkyCoord`` is recommended for all typical use cases of transforming coordinates. [#10475] astropy.stats ^^^^^^^^^^^^^ - Added a ``grow`` parameter to ``SigmaClip``, ``sigma_clip`` and ``sigma_clipped_stats``, to allow expanding the masking of each deviant value to its neighbours within a specified radius. [#10613] - Passing float ``n`` to ``poisson_conf_interval`` when using ``interval='kraft-burrows-nousek'`` now raises ``TypeError`` as its value must be an integer. [#10838] astropy.table ^^^^^^^^^^^^^ - Change ``Table.columns.keys()`` and ``Table.columns.values()`` to both return generators instead of a list. This matches the behavior for Python ``dict`` objects. [#10543] - Removed the ``FastBST`` and ``FastRBT`` indexing engines because they depend on the ``bintrees`` package, which is no longer maintained and is deprecated. Instead, use the ``SCEngine`` indexing engine, which is similar in performance and relies on the ``sortedcontainers`` package. [#10622] - When slicing a mixin column in a table that had indices, the indices are no longer copied since they generally are not useful, having the wrong shape. With this, the behaviour becomes the same as that for a regular ``Column``. (Note that this does not affect slicing of a table; sliced columns in those will continue to carry a sliced version of any indices). [#10890] - Change behavior so that when getting a single item out of a mixin column such as ``Time``, ``TimeDelta``, ``SkyCoord`` or ``Quantity``, the ``info`` attribute is no longer copied. This improves performance, especially when the object is an indexed column in a ``Table``. [#10889] - Raise a TypeError when a scalar column is added to an unsized table. [#10476] - The order of columns when creating a table from a ``list`` of ``dict`` may be changed. Previously, the order was alphabetical because the ``dict`` keys were assumed to be in random order. Since Python 3.7, the keys are always in order of insertion, so ``Table`` now uses the order of keys in the first row to set the column order. To alphabetize the columns to match the previous behavior, use ``t = t[sorted(t.colnames)]``. [#10900] astropy.time ^^^^^^^^^^^^ - Refactor ``Time`` and ``TimeDelta`` classes to inherit from a common ``TimeBase`` class. The ``TimeDelta`` class no longer inherits from ``Time``. A number of methods that only apply to ``Time`` (e.g. ``light_travel_time``) are no longer available in the ``TimeDelta`` class. [#10656] astropy.units ^^^^^^^^^^^^^ - The ``bar`` unit is no longer wrongly considered an SI unit, meaning that SI decompositions like ``(u.kg*u.s**-2* u.sr**-1 * u.nm**-1).si`` will no longer include it. [#10586] astropy.utils ^^^^^^^^^^^^^ - Shape-related items from ``astropy.utils.misc`` -- ``ShapedLikeNDArray``, ``check_broadcast``, ``unbroadcast``, and ``IncompatibleShapeError`` -- have been moved to their own module, ``astropy.utils.shapes``. They remain importable from ``astropy.utils``. [#10337] - ``check_hashes`` keyword in ``check_download_cache`` is deprecated and will be removed in a future release. [#10628] - ``hexdigest`` keyword in ``import_file_to_cache`` is deprecated and will be removed in a future release. [#10628] Bug Fixes --------- astropy.config ^^^^^^^^^^^^^^ - Fix a few issues with ``generate_config`` when used with other packages. [#10893] astropy.coordinates ^^^^^^^^^^^^^^^^^^^ - Fixed a bug in the coordinate-frame attribute ``CoordinateAttribute`` where the internal transformation could behave differently depending on whether the input was a low-level coordinate frame or a high-level ``SkyCoord``. ``CoordinateAttribute`` now always performs a ``SkyCoord``-style internal transformation, including the by-default merging of frame attributes. [#10475] astropy.modeling ^^^^^^^^^^^^^^^^ - Fixed an issue of ``Model.render`` when the input ``out`` datatype is not float64. [#10542] astropy.visualization ^^^^^^^^^^^^^^^^^^^^^ - Fix support for referencing WCSAxes coordinates by their world axes names. [#10484] astropy.wcs ^^^^^^^^^^^ - Objective functions called by ``astropy.wcs.fit_wcs_from_points`` were treating longitude and latitude distances equally. Now longitude scaled properly. [#10759] Other Changes and Additions --------------------------- - Minimum version of required Python is now 3.7. [#10900] - Minimum version of required Numpy is now 1.17. [#10664] - Minimum version of required Scipy is now 1.1. [#10900] - Minimum version of required PyYAML is now 3.13. [#10900] - Minimum version of required Matplotlib is now 3.0. [#10900] - The private ``_erfa`` module has been converted to its own package, ``pyerfa``, which is a required dependency for astropy, and can be imported with ``import erfa``. Importing ``_erfa`` from ``astropy`` will give a deprecation warning. [#10329] - Added ``optimize=True`` flag to calls of ``yacc.yacc`` (as already done for ``lex.lex``) to allow running in ``python -OO`` session without raising an exception in ``astropy.units.format``. [#10379] - Shortened FITS comment strings for some D2IM and CPDIS FITS keywords to reduce the number of FITS ``VerifyWarning`` warnings when working with WCSes containing lookup table distortions. [#10513] - When importing astropy without first building the extension modules first, raise an error directly instead of trying to auto-build. [#10883] 4.1 (2020-10-21) ================ New Features ------------ astropy.config ^^^^^^^^^^^^^^ - Add new function ``generate_config`` to generate the configuration file and include it in the documentation. [#10148] - ``ConfigNamespace.__iter__`` and ``ConfigNamespace.keys`` now yield ``ConfigItem`` names defined within it. Similarly, ``items`` and ``values`` would yield like a Python dictionary would. [#10139] astropy.coordinates ^^^^^^^^^^^^^^^^^^^ - Added a new ``SpectralCoord`` class that can be used to define spectral coordinates and transform them between different velocity frames. [#10185] - Angle parsing now supports ``cardinal direction`` in the cases where angles are initialized as ``string`` instances. eg ``"17°53'27"W"``.[#9859] - Allow in-place modification of array-valued ``Frame`` and ``SkyCoord`` objects. This provides limited support for updating coordinate data values from another coordinate object of the same class and equivalent frame attributes. [#9857] - Added a robust equality operator for comparing ``SkyCoord``, frame, and representation objects. A comparison like ``sc1 == sc2`` will now return a boolean or boolean array where the objects are strictly equal in all relevant frame attributes and coordinate representation values. [#10154] - Added the True Equator Mean Equinox (TEME) frame. [#10149] - The ``Galactocentric`` frame will now use the "latest" parameter definitions by default. This currently corresponds to the values defined in v4.0, but will change with future releases. [#10238] - The ``SkyCoord.from_name()`` and Sesame name resolving functionality now is able to cache results locally and will do so by default. [#9162] - Allow in-place modification of array-valued ``Representation`` and ``Differential`` objects, including of representations with attached differentials. [#10210] astropy.io.ascii ^^^^^^^^^^^^^^^^ - Functional Units can now be processed in CDS-tables. [#9971] - Allow reading in ASCII tables which have duplicate column names. [#9939] - Fixed failure of ASCII ``fast_reader`` to handle ``names``, ``include_names``, ``exclude_names`` arguments for ``RDB`` formatted tables. Homogenised checks and exceptions for invalid ``names`` arguments. Improved performance when parsing "wide" tables with many columns. [#10306] - Added type validation of key arguments in calls to ``io.ascii.read()`` and ``io.ascii.write()`` functions. [#10005] astropy.io.misc ^^^^^^^^^^^^^^^ - Added serialization of parameter constraints fixed and bounds. [#10082] - Added 'functional_models.py' and 'physical_models.py' to asdf/tags/transform, with to allow serialization of all functional and physical models. [#10028, #10293] - Fix ASDF serialization of circular model inverses, and remove explicit calls to ``asdf.yamlutil`` functions that became unnecessary in asdf 2.6.0. [#10189, #10384] astropy.io.fits ^^^^^^^^^^^^^^^ - Added support for writing Dask arrays to disk efficiently for ``ImageHDU`` and ``PrimaryHDU``. [#9742] - Add HDU name and ver to FITSDiff report where appropriate [#10197] astropy.io.votable ^^^^^^^^^^^^^^^^^^ - New ``exceptions.conf.max_warnings`` configuration item to control the number of times a type of warning appears before being suppressed. [#10152] - No longer ignore attributes whose values were specified as empty strings. [#10583] astropy.modeling ^^^^^^^^^^^^^^^^ - Added Plummer1D model to ``functional_models``. [#9896] - Added ``UnitsMapping`` model and ``Model.coerce_units`` to support units on otherwise unitless models. [#9936] - Added ``domain`` and ``window`` attributes to ``repr`` and ``str``. Fixed bug with ``_format_repr`` in core.py. [#9941] - Polynomial attributes ``domain`` and ``window`` are now tuples of size 2 and are validated. `repr` and `print` show only their non-default values. [#10145] - Added ``replace_submodel()`` method to ``CompoundModel`` to modify an existing instance. [#10176] - Delay construction of ``CompoundModel`` inverse until property is accessed, to support ASDF deserialization of circular inverses in component models. [#10384] astropy.nddata ^^^^^^^^^^^^^^ - Added support in the ``bitmask`` module for using mnemonic bit flag names when specifying the bit flags to be used or ignored when converting a bit field to a boolean. [#10095, #10208] - Added ``reshape_as_blocks`` function to reshape a data array into blocks, which is useful to efficiently apply functions on block subsets of the data instead of using loops. The reshaped array is a view of the input data array. [#10214] - Added a ``cache`` keyword option to allow caching for ``CCDData.read`` if filename is a URL. [#10265] astropy.table ^^^^^^^^^^^^^ - Added ability to specify a custom matching function for table joins. In particular this makes it possible to do cross-match table joins on ``SkyCoord``, ``Quantity``, or standard columns, where column entries within a specified distance are considered to be matched. [#10169] - Added ``units`` and ``descriptions`` keyword arguments to the Table object initialization and ``Table.read()`` methods. This allows directly setting the ``unit`` and ``description`` for the table columns at the time of creating or reading the table. [#9671] - Make table ``Row`` work as mappings, by adding ``.keys()`` and ``.values()`` methods. With this ``**row`` becomes possible, as does, more simply, turning a ``Row`` into a dictionary with ``dict(row)``. [#9712] - Added two new ``Table`` methods ``.items()`` and ``.values()``, which return respectively ``tbl.columns.items()`` (iterator over name, column tuples) and ``tbl.columns.values()`` (list of columns) for a ``Table`` object ``tbl``. [#9780] - Added new ``Table`` method ``.round()``, which rounds numeric columns to the specified number of decimals. [#9862] - Updated ``to_pandas()`` and ``from_pandas()`` to use and support Pandas nullable integer data type for masked integer data. [#9541] - The HDF5 writer, ``write_table_hdf5()``, now allows passing through additional keyword arguments to the ``h5py.Group.create_dataset()``. [#9602] - Added capability to add custom table attributes to a ``Table`` subclass. These attributes are persistent and can be set during table creation. [#10097] - Added support for ``SkyCoord`` mixin columns in ``dstack``, ``vstack`` and ``insert_row`` functions. [#9857] - Added support for coordinate ``Representation`` and ``Differential`` mixin columns. [#10210] astropy.time ^^^^^^^^^^^^ - Added a new time format ``unix_tai`` which is essentially Unix time but with leap seconds included. More precisely, this is the number of seconds since ``1970-01-01 00:00:08 TAI`` and corresponds to the ``CLOCK_TAI`` clock available on some linux platforms. [#10081] astropy.units ^^^^^^^^^^^^^ - Added ``torr`` pressure unit. [#9787] - Added the ``equal_nan`` keyword argument to ``isclose`` and ``allclose``, and updated the docstrings. [#9849] - Added ``Rankine`` temperature unit. [#9916] - Added integrated flux unit conversion to ``spectral_density`` equivalency. [#10015] - Changed ``pixel_scale`` equivalency to allow scales defined in any unit. [#10123] - The ``quantity_input`` decorator now optionally allows passing through numeric values or numpy arrays with numeric dtypes to arguments where ``dimensionless_unscaled`` is an allowed unit. [#10232] astropy.utils ^^^^^^^^^^^^^ - Added a new ``MetaAttribute`` class to support easily adding custom attributes to a subclass of classes like ``Table`` or ``NDData`` that have a ``meta`` attribute. [#10097] astropy.visualization ^^^^^^^^^^^^^^^^^^^^^ - Added ``invalid`` keyword to ``SqrtStretch``, ``LogStretch``, ``PowerStretch``, and ``ImageNormalize`` classes and the ``simple_norm`` function. This keyword is used to replace generated NaN values. [#10182] - Fixed an issue where ticks were sometimes not drawn at the edges of a spherical projection on a WCSAxes. [#10442] astropy.wcs ^^^^^^^^^^^ - WCS objects with a spectral axis will now return ``SpectralCoord`` objects when calling ``pixel_to_world`` instead of ``Quantity``, and can now take either ``Quantity`` or ``SpectralCoord`` as input to ``pixel_to_world``. [#10185] - Implemented support for the ``-TAB`` algorithm (WCS Paper III). [#9641] - Added an ``_as_mpl_axes`` method to the ``HightLevelWCSWrapper`` class. [#10138] - Add .upper() to ctype or ctype names to wcsapi/fitwcs.py to mitigate bugs from unintended lower/upper case issues [#10557] API Changes ----------- astropy.coordinates ^^^^^^^^^^^^^^^^^^^ - The equality operator for comparing ``SkyCoord``, frame, and representation objects was changed. A comparison like ``sc1 == sc2`` was previously equivalent to ``sc1 is sc2``. It will now return a boolean or boolean array where the objects are strictly equal in all relevant frame attributes and coordinate representation values. If the objects have different frame attributes or representation types then an exception will be raised. [#10154] - ```SkyCoord.radial_velocity_correction``` now allows you to pass an ```obstime``` directly when the ```SkyCoord``` also has an ```obstime``` set. In this situation, the position of the ```SkyCoord``` has space motion applied to correct to the passed ```obstime```. This allows mm/s radial velocity precision for objects with large space motion. [#10094] - For consistency with other astropy classes, coordinate ``Representations`` and ``Differentials`` can now be initialized with an instance of their own class if that instance is passed in as the first argument. [#10210] astropy.io.ascii ^^^^^^^^^^^^^^^^ - Changed the behavior when reading a table where both the ``names`` argument is provided (to specify the output column names) and the ``converters`` argument is provided (to specify column conversion functions). Previously the ``converters`` dict names referred to the *input* table column names, but now they refer to the *output* table column names. [#9739] astropy.io.votable ^^^^^^^^^^^^^^^^^^ - For FIELDs with datatype="char", store the values as strings instead of bytes. [#9505] astropy.table ^^^^^^^^^^^^^ - ``Table.from_pandas`` now supports a ``units`` dictionary as argument to pass units for columns in the ``DataFrame``. [#9472] astropy.time ^^^^^^^^^^^^ - Require that ``in_subfmt`` and ``out_subfmt`` properties of a ``Time`` object have allowed values at the time of being set, either when creating the object or when setting those properties on an existing ``Time`` instance. Previously the validation of those properties was not strictly enforced. [#9868] astropy.utils ^^^^^^^^^^^^^ - Changed the exception raised by ``get_readable_fileobj`` on missing compression modules (for ``bz2`` or ``lzma``/``xz`` support) to ``ModuleNotFoundError``, consistent with ``io.fits`` file handlers. [#9761] astropy.visualization ^^^^^^^^^^^^^^^^^^^^^ - Deprecated the ``imshow_only_kwargs`` keyword in ``imshow_norm``. [#9915] - Non-finite input values are now automatically excluded in ``HistEqStretch`` and ``InvertedHistEqStretch``. [#10177] - The ``PowerDistStretch`` and ``InvertedPowerDistStretch`` ``a`` value is restricted to be ``a >= 0`` in addition to ``a != 1``. [#10177] - The ``PowerStretch``, ``LogStretch``, and ``InvertedLogStretch`` ``a`` value is restricted to be ``a > 0``. [#10177] - The ``AsinhStretch`` and ``SinhStretch`` ``a`` value is restricted to be ``0 < a <= 1``. [#10177] Bug Fixes --------- astropy.coordinates ^^^^^^^^^^^^^^^^^^^ - Fix a bug where for light deflection by the Sun it was always assumed that the source was at infinite distance, which in the (rare and) absolute worst-case scenario could lead to errors up to 3 arcsec. [#10666] astropy.io.votable ^^^^^^^^^^^^^^^^^^ - For FIELDs with datatype="char", store the values as strings instead of bytes. [#9505] astropy.table ^^^^^^^^^^^^^ - Fix a bug that prevented ``Time`` columns from being used to sort a table. [#10824] astropy.wcs ^^^^^^^^^^^ - WCS objects with a spectral axis will now return ``SpectralCoord`` objects when calling ``pixel_to_world`` instead of ``Quantity`` (note that ``SpectralCoord`` is a sub-class of ``Quantity``). [#10185] - Add .upper() to ctype or ctype names to wcsapi/fitwcs.py to mitigate bugs from unintended lower/upper case issues [#10557] - Added bounds to ``fit_wcs_from_points`` to ensure CRPIX is on input image. [#10346] Other Changes and Additions --------------------------- - The way in which users can specify whether to build astropy against existing installations of C libraries rather than the bundled one has changed, and should now be done via environment variables rather than setup.py flags (e.g. --use-system-erfa). The available variables are ``ASTROPY_USE_SYSTEM_CFITSIO``, ``ASTROPY_USE_SYSTEM_ERFA``, ``ASTROPY_USE_SYSTEM_EXPAT``, ``ASTROPY_USE_SYSTEM_WCSLIB``, and ``ASTROPY_USE_SYSTEM_ALL``. These should be set to ``1`` to build against the system libraries. [#9730] - The infrastructure of the package has been updated in line with the APE 17 roadmap (https://github.com/astropy/astropy-APEs/blob/master/APE17.rst). The main changes are that the ``python setup.py test`` and ``python setup.py build_docs`` commands will no longer work. The easiest way to replicate these commands is to install the tox (https://tox.readthedocs.io) package and run ``tox -e test`` and ``tox -e build_docs``. It is also possible to run pytest and sphinx directly. Other significant changes include switching to setuptools_scm to manage the version number, and adding a ``pyproject.toml`` to opt in to isolated builds as described in PEP 517/518. [#9726] - Bundled ``expat`` is updated to version 2.2.9. [#10038] - Increase minimum asdf version to 2.6.0. [#10189] - The bundled version of PLY was updated to 3.11. [#10258] - Removed dependency on scikit-image. [#10214] 4.0.5 (2021-03-26) ================== Bug Fixes --------- astropy.io.fits ^^^^^^^^^^^^^^^ - Fix bug where manual fixes to invalid header cards were not preserved when saving a FITS file. [#11108] - Fix parsing of RVKC header card patterns that were not recognised where multiple spaces were separating field-specifier and value like "DP1.AXIS.1: 1". [#11301] - Fix misleading missing END card error when extra data are found at the end of the file. [#11285] - Fix incorrect wrapping of long card values as CONTINUE cards when some words in the value are longer than a single card. [#11304] astropy.io.misc ^^^^^^^^^^^^^^^ - Fixed problem when writing serialized metadata to HDF5 using h5py >= 3.0. With the newer h5py this was writing the metadata table as a variable-length string array instead of the previous fixed-length bytes array. Fixed astropy to force using a fixed-length bytes array. [#11359] astropy.modeling ^^^^^^^^^^^^^^^^ - Change ``Voigt1D`` function to use Humlicek's approximation to avoid serious inaccuracies + option to use (compiled) ``scipy.special.wofz`` error function for yet more accurate results. [#11177] astropy.table ^^^^^^^^^^^^^ - Fixed bug when initializing a ``Table`` with a column as list of ``Quantity``, for example ``Table({'x': [1*u.m, 2*u.m]})``. Previously this resulted in an ``object`` dtype with no column ``unit`` set, but now gives a float array with the correct unit. [#11329] - Fixed byteorder conversion in ``to_pandas()``, which had incorrectly triggered swapping when native endianness was stored with explicit ``dtype`` code ``'<'`` (or ``'>'``) instead of ``'='``. [#11288, #11294] - Fixed a compatibility issue with numpy 1.21. Initializing a Table with a column like ``['str', np.ma.masked]`` was failing in tests due to a change in numpy. [#11364] - Fixed bug when validating the inputs to ``table.hstack``, ``table.vstack``, and ``table.dstack``. Previously, mistakenly calling ``table.hstack(t1, t2)`` (instead of ``table.hstack([t1, t2]))`` would return ``t1`` instead of raising an exception. [#11336] - Fixed byteorder conversion in ``to_pandas()``, which had incorrectly triggered swapping when native endianness was stored with explicit ``dtype`` code ``'<'`` (or ``'>'``) instead of ``'='``. [#11288] astropy.time ^^^^^^^^^^^^ - Fix leap second update when using a non english locale. [#11062] - Fix default assumed location to be the geocenter when transforming times to and from solar-system barycenter scales. [#11134] - Fix inability to write masked times with ``formatted_value``. [#11195] astropy.units ^^^^^^^^^^^^^ - Ensure ``keepdims`` works for taking ``mean``, ``std``, and ``var`` of ``Quantity``. [#11198] - For ``Quantity.to_string()``, ensure that the precision argument is also used when the format is not latex. [#11145] astropy.wcs ^^^^^^^^^^^ - Allow "un-setting" of auxiliary WCS parameters in the ``aux`` attribute of ``Wcsprm``. [#11166] 4.0.4 (2020-11-24) ================== Bug Fixes --------- astropy.coordinates ^^^^^^^^^^^^^^^^^^^ - The ``norm()`` method for ``RadialDifferential`` no longer requires ``base`` to be specified. The ``norm()`` method for other non-Cartesian differential classes now gives a clearer error message if ``base`` is not specified. [#10969] - The transformations between ``ICRS`` and any of the heliocentric ecliptic frames (``HeliocentricMeanEcliptic``, ``HeliocentricTrueEcliptic``, and ``HeliocentricEclipticIAU76``) now correctly account for the small motion of the Sun when transforming a coordinate with velocity information. [#10970] astropy.io.ascii ^^^^^^^^^^^^^^^^ - Partially fixed a performance issue when reading in parallel mode. Parallel reading currently has substantially worse performance than the default serial reading, so we now ignore the parallel option and fall back to serial reading. [#10880] - Fixed a bug where "" (blank string) as input data for a boolean type column was causing an exception instead of indicating a masked value. As a consequence of the fix, the values "0" and "1" are now also allowed as valid inputs for boolean type columns. These new allowed values apply for both ECSV and for basic character-delimited data files ('basic' format with appropriate ``converters`` specified). [#10995] astropy.modeling ^^^^^^^^^^^^^^^^ - Fixed use of weights with ``LinearLSQFitter``. [#10687] astropy.stats ^^^^^^^^^^^^^ - Fixed an issue in biweight stats when MAD=0 to give the same output with and without an input ``axis``. [#10912] astropy.time ^^^^^^^^^^^^ - Fix a problem with the ``plot_date`` format for matplotlib >= 3.3 caused by a change in the matplotlib plot date default reference epoch in that release. [#10876] - Improve initialization time by a factor of four when creating a scalar ``Time`` object in a format like ``unix`` or ``cxcsec`` (time delta from a reference epoch time). [#10406] astropy.visualization ^^^^^^^^^^^^^^^^^^^^^ - Fixed the calculation of the tight bounding box of a ``WCSAxes``. This should also significantly improve the application of ``tight_layout()`` to figures containing ``WCSAxes``. [#10797] 4.0.3 (2020-10-14) ================== Bug Fixes --------- astropy.table ^^^^^^^^^^^^^ - Fixed a small bug where initializing an empty ``Column`` with a structured dtype with a length and a shape failed to give the requested dtype. [#10819] Other Changes and Additions --------------------------- - Fixed installation of the source distribution with pip<19. [#10837, #10852] 4.0.2 (2020-10-10) ================== New Features ------------ astropy.utils ^^^^^^^^^^^^^ - ``astropy.utils.data.download_file`` now supports FTPS/FTP over TLS. [#9964] - ``astropy.utils.data`` now uses a lock-free mechanism for caching. This new mechanism uses a new cache layout and so ignores caches created using earlier mechanisms (which were causing lockups on clusters). The two cache formats can coexist but do not share any files. [#10437, #10683] - ``astropy.utils.data`` now ignores the config item ``astropy.utils.data.conf.download_cache_lock_attempts`` since no locking is done. [#10437, #10683] - ``astropy.utils.data.download_file`` and related functions now interpret the parameter or config file setting ``timeout=0`` to mean they should make no attempt to download files. [#10437, #10683] - ``astropy.utils.import_file_to_cache`` now accepts a keyword-only argument ``replace``, defaulting to True, to determine whether it should replace existing files in the cache, in a way as close to atomic as possible. [#10437, #10683] - ``astropy.utils.data.download_file`` and related functions now treat ``http://example.com`` and ``http://example.com/`` as equivalent. [#10631] astropy.wcs ^^^^^^^^^^^ - The new auxiliary WCS parameters added in WCSLIB 7.1 are now exposed as the ``aux`` attribute of ``Wcsprm``. [#10333] - Updated bundled version of ``WCSLIB`` to v7.3. [#10433] Bug fixes --------- astropy.config ^^^^^^^^^^^^^^ - Added an extra fallback to ``os.expanduser('~')`` when trying to find the user home directory. [#10570] astropy.constants ^^^^^^^^^^^^^^^^^ - Corrected definition of parsec to 648 000 / pi AU following IAU 2015 B2 [#10569] astropy.convolution ^^^^^^^^^^^^^^^^^^^ - Fixed a bug where a float-typed integers in the argument ``x_range`` of ``astropy.convolution.utils.discretize_oversample_1D`` (and the 2D version as well) fails because it uses ``numpy.linspace``, which requires an ``int``. [#10696] astropy.coordinates ^^^^^^^^^^^^^^^^^^^ - Ensure that for size-1 array ``SkyCoord`` and coordinate frames the attributes also properly become scalars when indexed with 0. [#10113] - Fixed a bug where ``SkyCoord.separation()`` and ``SkyCoord.separation_3d`` were not accepting a frame object. [#10332] - Ensure that the ``lon`` values in ``SkyOffsetFrame`` are wrapped correctly at 180 degree regardless of how the underlying data is represented. [#10163] - Fixed an error in the obliquity of the ecliptic when transforming to/from the ``*TrueEcliptic`` coordinate frames. The error would primarily result in an inaccuracy in the ecliptic latitude on the order of arcseconds. [#10129] - Fixed an error in the computation of the location of solar system bodies where the Earth location of the observer was ignored during the correction for light travel time. [#10292] - Ensure that coordinates with proper motion that are transformed to other coordinate frames still can be represented properly. [#10276] - Improve the error message given when trying to get a cartesian representation for coordinates that have both proper motion and radial velocity, but no distance. [#10276] - Fixed an error where ``SkyCoord.apply_space_motion`` would return incorrect results when no distance is set and proper motion is high. [#10296] - Make the parsing of angles thread-safe so that ``Angle`` can be used in Python multithreading. [#10556] - Fixed reporting of ``EarthLocation.info`` which previously raised an exception. [#10592] astropy.io.ascii ^^^^^^^^^^^^^^^^ - Fixed a bug with the C ``fast_reader`` not correctly parsing newlines when ``delimiter`` was also set to ``\n`` or ``\r``; ensured consistent handling of input strings without newline characters. [#9929] astropy.io.fits ^^^^^^^^^^^^^^^ - Fix integer formats of ``TFORMn=Iw`` columns in ASCII tables to correctly read values exceeding int32 - setting int16, int32 or int64 according to ``w``. [#9901] - Fix unclosed memory-mapped FITS files in ``FITSDiff`` when difference found. [#10159] - Fix crash when reading an invalid table file. [#10171] - Fix duplication issue when setting a keyword ending with space. [#10482] - Fix ResourceWarning with ``fits.writeto`` and ``pathlib.Path`` object. [#10599] - Fix repr for commentary cards and strip spaces for commentary keywords. [#10640] - Fix compilation of cfitsio with Xcode 12. [#10772] - Fix handling of 1-dimensional arrays with a single element in ``BinTableHDU`` [#10768] astropy.io.misc ^^^^^^^^^^^^^^^ - Fix id URL in ``baseframe-1.0.0`` ASDF schema. [#10223] - Write keys to ASDF only if the value is present, to account for a change in behavior in asdf 2.8. [#10674] astropy.io.registry ^^^^^^^^^^^^^^^^^^^ - Fix ``Table.(read|write).help`` when reader or writer has no docstring. [#10460] astropy.io.votable ^^^^^^^^^^^^^^^^^^ - Fixed parsing failure of VOTable with no fields. When detecting a non-empty table with no fields, the following warning/exception is issued: E25 "No FIELDs are defined; DATA section will be ignored." [#10192] astropy.modeling ^^^^^^^^^^^^^^^^ - Fixed a problem with mapping ``input_units`` and ``return_units`` of a ``CompoundModel`` to the units of the constituent models. [#10158] - Removed hard-coded names of inputs and outputs. [#10174] - Fixed a problem where slicing a ``CompoundModel`` by name will crash if there ``fix_inputs`` operators are present. [#10224] - Removed a limitation of fitting of data with units with compound models without units when the expression involves operators other than addition and subtraction. [#10415] - Fixed a problem with fitting ``Linear1D`` and ``Planar2D`` in model sets. [#10623] - Fixed reported module name of ``math_functions`` model classes. [#10694] - Fixed reported module name of ``tabular`` model classes. [#10709] - Do not create new ``math_functions`` models for ufuncs that are only aliases (divide and mod). [#10697] - Fix calculation of the ``Moffat2D`` derivative with respect to gamma. [#10784] astropy.stats ^^^^^^^^^^^^^ - Fixed an API regression where ``SigmaClip.__call__`` would convert masked elements to ``nan`` and upcast the dtype to ``float64`` in its output ``MaskedArray`` when using the ``axis`` parameter along with the defaults ``masked=True`` and ``copy=True``. [#10610] - Fixed an issue where fully masked ``MaskedArray`` input to ``sigma_clipped_stats`` gave incorrect results. [#10099] - Fixed an issue where ``sigma_clip`` and ``SigmaClip.__call__`` would return a masked array instead of a ``ndarray`` when ``masked=False`` and the input was a full-masked ``MaskedArray``. [#10099] - Fixed bug with ``funcs.poisson_conf_interval`` where an integer for N with ``interval='kraft-burrows-nousek'`` would throw an error with mpmath backend. [#10427] - Fixed bug in ``funcs.poisson_conf_interval`` with ``interval='kraft-burrows-nousek'`` where certain combinations of source and background count numbers led to ``ValueError`` due to the choice of starting value for numerical optimization. [#10618] astropy.table ^^^^^^^^^^^^^ - Fixed a bug when writing a table with mixin columns to FITS, ECSV or HDF5. If one of the data attributes of the mixin (e.g. ``skycoord.ra``) had the same name as one of the table column names (``ra``), the column (``ra``) would be dropped when reading the table back. [#10222] - Fixed a bug when sorting an indexed table on the indexed column after first sorting on another column. [#10103] - Fixed a bug in table argsort when called with ``reverse=True`` for an indexed table. [#10103] - Fixed a performance regression introduced in #9048 when initializing a table from Python lists. Also fixed incorrect behavior (for data types other than float) when those lists contain ``np.ma.masked`` elements to indicate masked data. [#10636] - Avoid modifying ``.meta`` when serializing columns to FITS. [#10485] - Avoid crash when reading a FITS table that contains mixin info and PyYAML is missing. [#10485] astropy.time ^^^^^^^^^^^^ - Ensure that for size-1 array ``Time``, the location also properly becomes a scalar when indexed with 0. [#10113] astropy.units ^^^^^^^^^^^^^ - Refined test_parallax to resolve difference between 2012 and 2015 definitions. [#10569] astropy.utils ^^^^^^^^^^^^^ - The default IERS server has been updated to use the FTPS server hosted by CDDIS. [#9964] - Fixed memory allocation on 64-bit systems within ``xml.iterparse`` [#10076] - Fix case where ``None`` could be used in a numerical computation. [#10126] astropy.visualization ^^^^^^^^^^^^^^^^^^^^^ - Fixed a bug where the ``ImageNormalize`` ``clip`` keyword was ignored when used with calling the object on data. [#10098] - Fixed a bug where ``axes.xlabel``/``axes.ylabel`` where not correctly set nor returned on an ``EllipticalFrame`` class ``WCSAxes`` plot. [#10446] astropy.wcs ^^^^^^^^^^^ - Handled WCS 360 -> 0 deg crossover in ``fit_wcs_from_points`` [#10155] - Do not issue ``DATREF`` warning when ``MJDREF`` has default value. [#10440] - Fixed a bug due to which ``naxis`` argument was ignored if ``header`` was supplied during the initialization of a WCS object. [#10532] Other Changes and Additions --------------------------- - Improved the speed of sorting a large ``Table`` on a single column by a factor of around 5. [#10103] - Ensure that astropy can be used inside Application bundles built with pyinstaller. [#8795] - Updated the bundled CFITSIO library to 3.49. See ``cextern/cfitsio/docs/changes.txt`` for additional information. [#10256, #10665] - ``extract_array`` raises a ``ValueError`` if the data type of the input array is inconsistent with the ``fill_value``. [#10602] 4.0.1 (2020-03-27) ================== Bug fixes --------- astropy.config ^^^^^^^^^^^^^^ - Fixed a bug where importing a development version of a package that uses ``astropy`` configuration system can result in a ``~/.astropy/config/package..cfg`` file. [#9975] astropy.coordinates ^^^^^^^^^^^^^^^^^^^ - Fixed a bug where a vestigal trace of a frame class could persist in the transformation graph even after the removal of all transformations involving that frame class. [#9815] - Fixed a bug with ``TransformGraph.remove_transform()`` when the "from" and "to" frame classes are not explicitly specified. [#9815] - Read-only longitudes can now be passed in to ``EarthLocation`` even if they include angles outside of the range of -180 to 180 degrees. [#9900] - ```SkyCoord.radial_velocity_correction``` no longer raises an Exception when space motion information is present on the SkyCoord. [#9980] astropy.io ^^^^^^^^^^ - Fixed a bug that prevented the unified I/O infrastructure from working with datasets that are represented by directories rather than files. [#9866] astropy.io.ascii ^^^^^^^^^^^^^^^^ - Fixed a bug in the ``fast_reader`` C parsers incorrectly returning entries of isolated positive/negative signs as ``float`` instead of ``str``. [#9918] - Fixed a segmentation fault in the ``fast_reader`` C parsers when parsing an invalid file with ``guess=True`` and the file contains inconsistent column numbers in combination with a quoted field; e.g., ``"1 2\n 3 4 '5'"``. [#9923] - Magnitude, decibel, and dex can now be stored in ``ecsv`` files. [#9933] astropy.io.misc ^^^^^^^^^^^^^^^ - Magnitude, decibel, and dex can now be stored in ``hdf5`` files. [#9933] - Fixed serialization of polynomial models to include non default values of domain and window values. [#9956, #9961] - Fixed a bug which affected overwriting tables within ``hdf5`` files. Overwriting an existing path with associated column meta data now also overwrites the meta data associated with the table. [#9950] - Fixed serialization of Time objects with location under time-1.0.0 ASDF schema. [#9983] astropy.io.fits ^^^^^^^^^^^^^^^ - Fix regression with ``GroupsHDU`` which needs to modify the header to handle invalid headers, and fix accessing ``.data`` for empty HDU. [#9711, #9934] - Fix ``fitsdiff`` when its arguments are directories that contain other directories. [#9711] - Fix writing noncontiguous data to a compressed HDU. [#9958] - Added verification of ``disp`` (``TDISP``) keyword to ``fits.Column`` and extended tests for ``TFORM`` and ``TDISP`` validation. [#9978] - Fix checksum verification to process all HDUs instead of only the first one because of the lazy loading feature. [#10012] - Allow passing ``output_verify`` to ``.close`` when using the context manager. [#10030] - Prevent instantiation of ``PrimaryHDU`` and ``ImageHDU`` with a scalar. [#10041] - Fix column access by attribute with FITS_rec: columns with scaling or columns from ASCII tables where not properly converted when accessed by attribute name. [#10069] astropy.io.misc ^^^^^^^^^^^^^^^ - Magnitude, decibel, and dex can now be stored in ``hdf5`` files. [#9933] - Fixed serialization of polynomial models to include non default values of domain and window values. [#9956, #9961] - Fixed a bug which affected overwriting tables within ``hdf5`` files. Overwriting an existing path with associated column meta data now also overwrites the meta data associated with the table. [#9950] - Fixed serialization of Time objects with location under time-1.0.0 ASDF schema. [#9983] astropy.modeling ^^^^^^^^^^^^^^^^ - Fixed a bug in setting default values of parameters of orthonormal polynomials when constructing a model set. [#9987] astropy.table ^^^^^^^^^^^^^ - Fixed bug in ``Table.reverse`` for tables that contain non-mutable mixin columns (like ``SkyCoord``) for which in-place item update is not allowed. [#9839] - Tables containing Magnitude, decibel, and dex columns can now be saved to ``ecsv`` files. [#9933] - Fixed bug where adding or inserting a row fails on a table with an index defined on a column that is not the first one. [#10027] - Ensured that ``table.show_in_browser`` also worked for mixin columns like ``Time`` and ``SkyCoord``. [#10068] astropy.time ^^^^^^^^^^^^ - Fix inaccuracy when converting between TimeDelta and datetime.timedelta. [#9679] - Fixed exception when changing ``format`` in the case when ``out_subfmt`` is defined and is incompatible with the new format. [#9812] - Fixed exceptions in ``Time.to_value()``: when supplying any ``subfmt`` argument for string-based formats like 'iso', and for ``subfmt='long'`` for the formats 'byear', 'jyear', and 'decimalyear'. [#9812] - Fixed bug where the location attribute was lost when creating a new ``Time`` object from an existing ``Time`` or list of ``Time`` objects. [#9969] - Fixed a bug where an exception occurred when creating a ``Time`` object if the ``val1`` argument was a regular double and the ``val2`` argument was a ``longdouble``. [#10034] astropy.timeseries ^^^^^^^^^^^^^^^^^^ - Fixed issue with reference time for the ``transit_time`` parameter returned by the ``BoxLeastSquares`` periodogram. Now, the ``transit_time`` will be within the range of the input data and arbitrary time offsets/zero points no longer affect results. [#10013] astropy.units ^^^^^^^^^^^^^ - Fix for ``quantity_input`` annotation raising an exception on iterable types that don't define a general ``__contains__`` for checking if ``None`` is contained (e.g. Enum as of python3.8), by instead checking for instance of Sequence. [#9948] - Fix for ``u.Quantity`` not taking into account ``ndmin`` if constructed from another ``u.Quantity`` instance with different but convertible unit [#10066] astropy.utils ^^^^^^^^^^^^^ - Fixed ``deprecated_renamed_argument`` not passing in user value to deprecated keyword when the keyword has no new name. [#9981] - Fixed ``deprecated_renamed_argument`` not issuing a deprecation warning when deprecated keyword without new name is passed in as positional argument. [#9985] - Fixed detection of read-only filesystems in the caching code. [#10007] astropy.visualization ^^^^^^^^^^^^^^^^^^^^^ - Fixed bug from matplotlib >=3.1 where an empty Quantity array is sent for unit conversion as an empty list. [#9848] - Fix bug in ``ZScaleInterval`` to return the array minimum and maximum when there are less then ``min_npixels`` in the input array. [#9913] - Fix a bug in simplifying axis labels that affected non-rectangular frames. [#8004, #9991] Other Changes and Additions --------------------------- - Increase minimum asdf version to 2.5.2. [#9996, #9819] - Updated bundled version of ``WCSLIB`` to v7.2. [#10021] 4.0 (2019-12-16) ================ New Features ------------ astropy.config ^^^^^^^^^^^^^^ - The config and cache directories and the name of the config file are now customizable. This allows affiliated packages to put their configuration files in locations other than ``CONFIG_DIR/.astropy/``. [#8237] astropy.constants ^^^^^^^^^^^^^^^^^ - The version of constants can be specified via ScienceState in a way that ``constants`` and ``units`` will be consistent. [#8517] - Default constants now use CODATA 2018 and IAU 2015 definitions. [#8761] - Constants can be pickled and unpickled. [#9377] astropy.convolution ^^^^^^^^^^^^^^^^^^^ - Fixed a bug [#9168] where having a kernel defined using unitless astropy quantity objects would result in a crash [#9300] astropy.coordinates ^^^^^^^^^^^^^^^^^^^ - Changed ``coordinates.solar_system_ephemeris`` to also accept local files as input. The ephemeris can now be selected by either keyword (e.g. 'jpl', 'de430'), URL or file path. [#8767] - Added a ``cylindrical`` property to ``SkyCoord`` for shorthand access to a ``CylindricalRepresentation`` of the coordinate, as is already available for other common representations. [#8857] - The default parameters for the ``Galactocentric`` frame are now controlled by a ``ScienceState`` subclass, ``galactocentric_frame_defaults``. New parameter sets will be added to this object periodically to keep up with ever-improved measurements of the solar position and motion. [#9346] - Coordinate frame classes can now have multiple aliases by assigning a list of aliases to the class variable ``name``. Any of the aliases can be used for attribute-style access or as the target of ``tranform_to()`` calls. [#8834] - Passing a NaN to ``Distance`` no longer raises a warning. [#9598] astropy.cosmology ^^^^^^^^^^^^^^^^^ - The pre-publication Planck 2018 cosmological parameters are included as the ``Planck2018_arXiv_v2`` object. Please note that the values are preliminary, and when the paper is accepted a final version will be included as ``Planck18``. [#8111] astropy.io.ascii ^^^^^^^^^^^^^^^^ - Removed incorrect warnings on ``Overflow`` when reading in ``FloatType`` 0.0 with ``use_fast_converter``; synchronised ``IntType`` ``Overflow`` warning messages. [#9082] astropy.io.misc ^^^^^^^^^^^^^^^ - Eliminate deprecated compatibility mode when writing ``Table`` metadata to HDF5 format. [#8899] - Add support for orthogonal polynomial models to ASDF. [#9107] astropy.io.fits ^^^^^^^^^^^^^^^ - Changed the ``fitscheck`` and ``fitsdiff`` script to use the ``argparse`` module instead of ``optparse``. [#9148] - Allow writing of ``Table`` objects with ``Time`` columns that are also table indices to FITS files. [#8077] astropy.io.votable ^^^^^^^^^^^^^^^^^^ - Support VOTable version 1.4. The main addition is the new element, TIMESYS, which allows defining of metadata for temporal coordinates much like COOSYS defines metadata for celestial coordinates. [#9475] astropy.logger ^^^^^^^^^^^^^^ - Added a configuration option to specify the text encoding of the log file, with the default behavior being the platform-preferred encoding. [#9203] astropy.modeling ^^^^^^^^^^^^^^^^ - Major rework of modeling internals. `See modeling documentation for details. `_ . [#8769] - Add ``Tabular1D.inverse``. [#9083] - ``Model.rename`` was changed to add the ability to rename ``Model.inputs`` and ``Model.outputs``. [#9220] - New function ``fix_inputs`` to generate new models from others by fixing specific inputs variable values to constants. [#9135] - ``inputs`` and ``outputs`` are now model instance attributes, and ``n_inputs`` and ``n_outputs`` are class attributes. Backwards compatible default values of ``inputs`` and ``outputs`` are generated. ``Model.inputs`` and ``Model.outputs`` are now settable which allows renaming them on per user case. [#9298] - Add a new model representing a sequence of rotations in 3D around an arbitrary number of axes. [#9369] - Add many of the numpy ufunc functions as models. [#9401] - Add ``BlackBody`` model. [#9282] - Add ``Drude1D`` model. [#9452] - Added analytical King model (KingProjectedAnalytic1D). [#9084] - Added Exponential1D and Logarithmic1D models. [#9351] astropy.nddata ^^^^^^^^^^^^^^ - Add a way for technically invalid but unambiguous units in a fits header to be parsed by ``CCDData``. [#9397] - ``NDData`` now only accepts WCS objects which implement either the high, or low level APE 14 WCS API. All WCS objects are converted to a high level WCS object, so ``NDData.wcs`` now always returns a high level APE 14 object. Not all array slices are valid for wcs objects, so some slicing operations which used to work may now fail. [#9067] astropy.stats ^^^^^^^^^^^^^ - The ``biweight_location``, ``biweight_scale``, and ``biweight_midvariance`` functions now allow for the ``axis`` keyword to be a tuple of integers. [#9309] - Added an ``ignore_nan`` option to the ``biweight_location``, ``biweight_scale``, and ``biweight_midvariance`` functions. [#9457] - A numpy ``MaskedArray`` can now be input to the ``biweight_location``, ``biweight_scale``, and ``biweight_midvariance`` functions. [#9466] - Removed the warning related to p0 in the Bayesian blocks algorithm. The caveat related to p0 is described in the docstring for ``Events``. [#9567] astropy.table ^^^^^^^^^^^^^ - Improved the implementation of ``Table.replace_column()`` to provide a speed-up of 5 to 10 times for wide tables. The method can now accept any input which convertible to a column of the correct length, not just ``Column`` subclasses. [#8902] - Improved the implementation of ``Table.add_column()`` to provide a speed-up of 2 to 10 (or more) when adding a column to tables, with increasing benefit as the number of columns increases. The method can now accept any input which is convertible to a column of the correct length, not just ``Column`` subclasses. [#8933] - Changed the implementation of ``Table.add_columns()`` to use the new ``Table.add_column()`` method. In most cases the performance is similar or slightly faster to the previous implementation. [#8933] - ``MaskedColumn.data`` will now return a plain ``MaskedArray`` rather than the previous (unintended) ``masked_BaseColumn``. [#8855] - Added depth-wise stacking ``dstack()`` in higher level table operation. It help will in stacking table column depth-wise. [#8939] - Added a new table equality method ``values_equal()`` which allows comparison table values to another table, list, or value, and returns an element-by-element equality table. [#9068] - Added new ``join_type='cartesian'`` option to the ``join`` operation. [#9288] - Allow adding a table column as a list of mixin-type objects, for instance ``t['q'] = [1 * u.m, 2 * u.m]``. [#9165] - Allow table ``join()`` using any sortable key column (e.g. Time), not just ndarray subclasses. A column is considered sortable if there is a ``.info.get_sortable_arrays()`` method that is implemented. [#9340] - Added ``Table.iterrows()`` for making row-wise iteration faster. [#8969] - Allow table to be initialized with a list of dict where the dict keys are not the same in every row. The table column names are the set of all keys found in the input data, and any missing key/value pairs are turned into missing data in the table. [#9425] - Prevent unnecessary ERFA warnings when indexing by ``Time`` columns. [#9545] - Added support for sorting tables which contain non-mutable mixin columns (like ``SkyCoord``) for which in-place item update is not allowed. [#9549] - Ensured that inserting ``np.ma.masked`` (or any other value with a mask) into a ``MaskedColumn`` causes a masked entry to be inserted. [#9623] - Fixed a bug that caused an exception when initializing a ``MaskedColumn`` from another ``MaskedColumn`` that has a structured dtype. [#9651] astropy.tests ^^^^^^^^^^^^^ - The plugin that handles the custom header in the test output has been moved to the ``pytest-astropy-header plugin`` package. `See the README at `__ for information about using this new plugin. [#9214] astropy.time ^^^^^^^^^^^^ - Added a new time format ``ymdhms`` for representing times via year, month, day, hour, minute, and second attributes. [#7644] - ``TimeDelta`` gained a ``to_value`` method, so that it becomes easier to use it wherever a ``Quantity`` with units of time could be used. [#8762] - Made scalar ``Time`` and ``TimeDelta`` objects hashable based on JD, time scale, and location attributes. [#8912] - Improved error message when bad input is used to initialize a ``Time`` or ``TimeDelta`` object and the format is specified. [#9296] - Allow numeric time formats to be initialized with numpy ``longdouble``, ``Decimal`` instances, and strings. One can select just one of these using ``in_subfmt``. The output can be similarly set using ``out_subfmt``. [#9361] - Introduce a new ``.to_value()`` method for ``Time`` (and adjusted the existing method for ``TimeDelta``) so that one can get values in a given ``format`` and possible ``subfmt`` (e.g., ``to_value('mjd', 'str')``. [#9361] - Prevent unnecessary ERFA warnings when sorting ``Time`` objects. [#9545] astropy.timeseries ^^^^^^^^^^^^^^^^^^ - Adding ``epoch_phase``, ``wrap_phase`` and ``normalize_phase`` keywords to ``TimeSeries.fold()`` to control the phase of the epoch and to return normalized phase rather than time for the folded TimeSeries. [#9455] astropy.uncertainty ^^^^^^^^^^^^^^^^^^^ - ``Distribution`` was rewritten such that it deals better with subclasses. As a result, Quantity distributions now behave correctly with ``to`` methods yielding new distributions of the kind expected for the starting distribution, and ``to_value`` yielding ``NdarrayDistribution`` instances. [#9429, #9442] - The ``pdf_*`` properties that were used to calculate statistical properties of ``Distrubution`` instances were changed into methods. This allows one to pass parameters such as ``ddof`` to ``pdf_std`` and ``pdf_var`` (which generally should equal 1 instead of the default 0), and reflects that these are fairly involved calculations, not just "properties". [#9613] astropy.units ^^^^^^^^^^^^^ - Support for unicode parsing. Currently supported are superscripts, Ohm, ÅngstrÃļm, and the micro-sign. [#9348] - Accept non-unit type annotations in @quantity_input. [#8984] - For numpy 1.17 and later, the new ``__array_function__`` protocol is used to ensure that all top-level numpy functions interact properly with ``Quantity``, preserving units also in operations like ``np.concatenate``. [#8808] - Add equivalencies for surface brightness units to spectral_density. [#9282] astropy.utils ^^^^^^^^^^^^^ - ``astropy.utils.data.download_file`` and ``astropy.utils.data.get_readable_fileobj`` now provides an ``http_headers`` keyword to pass in specific request headers for the download. It also now defaults to providing ``User-Agent: Astropy`` and ``Accept: */*`` headers. The default ``User-Agent`` value can be set with a new ``astropy.data.conf.default_http_user_agent`` configuration item. [#9508, #9564] - Added a new ``astropy.utils.misc.unbroadcast`` function which can be used to return the smallest array that can be broadcasted back to the initial array. [#9209] - The specific IERS Earth rotation parameter table used for time and coordinate transformations can now be set, either in a context or per session, using ``astropy.utils.iers.earth_rotation_table``. [#9244] - Added ``export_cache`` and ``import_cache`` to permit transporting downloaded data to machines with no Internet connection. Several new functions are available to investigate the cache contents; e.g., ``check_download_cache`` can be used to confirm that the persistent cache has not become damaged. [#9182] - A new ``astropy.utils.iers.LeapSeconds`` class has been added to track leap seconds. [#9365] astropy.visualization ^^^^^^^^^^^^^^^^^^^^^ - Added a new ``time_support`` context manager/function for making it easy to plot and format ``Time`` objects in Matplotlib. [#8782] - Added support for plotting any WCS compliant with the generalized (APE 14) WCS API with WCSAxes. [#8885, #9098] - Improved display of information when inspecting ``WCSAxes.coords``. [#9098] - Improved error checking for the ``slices=`` argument to ``WCSAxes``. [#9098] - Added support for more solar frames in WCSAxes. [#9275] - Add support for one dimensional plots to ``WCSAxes``. [#9266] - Add a ``get_format_unit`` to ``wcsaxes.CoordinateHelper``. [#9392] - ``WCSAxes`` now, by default, sets a default label for plot axes which is the WCS physical type (and unit) for that axis. This can be disabled using the ``coords[i].set_auto_axislabel(False)`` or by explicitly setting an axis label. [#9392] - Fixed the display of tick labels when plotting all sky images that have a coord_wrap less than 360. [#9542] astropy.wcs ^^^^^^^^^^^ - Added a ``astropy.wcs.wcsapi.pixel_to_pixel`` function that can be used to transform pixel coordinates in one dataset with a WCS to pixel coordinates in another dataset with a different WCS. This function is designed to be efficient when the input arrays are broadcasted views of smaller arrays. [#9209] - Added a ``local_partial_pixel_derivatives`` function that can be used to determine a matrix of partial derivatives of each world coordinate with respect to each pixel coordinate. [#9392] - Updated wcslib to v6.4. [#9125] - Improved the ``SlicedLowLevelWCS`` class in ``astropy.wcs.wcsapi`` to avoid storing chains of nested ``SlicedLowLevelWCS`` objects when applying multiple slicing operations in turn. [#9210] - Added a ``wcs_info_str`` function to ``astropy.wcs.wcsapi`` to show a summary of an APE-14-compliant WCS as a string. [#8546, #9207] - Added two new optional attributes to the APE 14 low-level WCS: ``pixel_axis_names`` and ``world_axis_names``. [#9156] - Updated the WCS class to now correctly take and return ``Time`` objects in the high-level APE 14 API (e.g. ``pixel_to_world``. [#9376] - ``SlicedLowLevelWCS`` now raises ``IndexError`` rather than ``ValueError`` on an invalid slice. [#9067] - Added ``fit_wcs_from_points`` function to ``astropy.wcs.utils``. Fits a WCS object to set of matched detector/sky coordinates. [#9469] - Fix various bugs in ``SlicedLowLevelWCS`` when the WCS being sliced was one dimensional. [#9693] API Changes ----------- astropy.constants ^^^^^^^^^^^^^^^^^ - Deprecated ``set_enabled_constants`` context manager. Use ``astropy.physical_constants`` and ``astropy.astronomical_constants``. [#9025] astropy.convolution ^^^^^^^^^^^^^^^^^^^ - Removed the deprecated keyword argument ``interpolate_nan`` from ``convolve_fft``. [#9356] - Removed the deprecated keyword argument ``stddev`` from ``Gaussian2DKernel``. [#9356] - Deprecated and renamed ``MexicanHat1DKernel`` and ``MexicanHat2DKernel`` to ``RickerWavelet1DKernel`` and ``RickerWavelet2DKernel``. [#9445] astropy.coordinates ^^^^^^^^^^^^^^^^^^^ - Removed the ``recommended_units`` attribute from Representations; it was deprecated since 3.0. [#8892] - Removed the deprecated frame attribute classes, ``FrameAttribute``, ``TimeFrameAttribute``, ``QuantityFrameAttribute``, ``CartesianRepresentationFrameAttribute``; deprecated since 3.0. [#9326] - Removed ``longitude`` and ``latitude`` attributes from ``EarthLocation``; deprecated since 2.0. [#9326] - The ``DifferentialAttribute`` for frame classes now passes through any input to the ``allowed_classes`` if only one allowed class is specified, i.e. this now allows passing a quantity in for frame attributes that use ``DifferentialAttribute``. [#9325] - Removed the deprecated ``galcen_ra`` and ``galcen_dec`` attributes from the ``Galactocentric`` frame. [#9346] astropy.extern ^^^^^^^^^^^^^^ - Remove the bundled ``six`` module. [#8315] astropy.io.ascii ^^^^^^^^^^^^^^^^ - Masked column handling has changed, see ``astropy.table`` entry below. [#8789] astropy.io.misc ^^^^^^^^^^^^^^^ - Masked column handling has changed, see ``astropy.table`` entry below. [#8789] - Removed deprecated ``usecPickle`` kwarg from ``fnunpickle`` and ``fnpickle``. [#8890] astropy.io.fits ^^^^^^^^^^^^^^^ - Masked column handling has changed, see ``astropy.table`` entry below. [#8789] - ``io.fits.Header`` has been made safe for subclasses for copying and slicing. As a result of this change, the private subclass ``CompImageHeader`` now always should be passed an explicit ``image_header``. [#9229] - Removed the deprecated ``tolerance`` option in ``fitsdiff`` and ``io.fits.diff`` classes. [#9520] - Removed deprecated keyword arguments for ``CompImageHDU``: ``compressionType``, ``tileSize``, ``hcompScale``, ``hcompSmooth``, ``quantizeLevel``. [#9520] astropy.io.votable ^^^^^^^^^^^^^^^^^^ - Changed ``pedantic`` argument to ``verify`` and change it to have three string-based options (``ignore``, ``warn``, and ``exception``) instead of just being a boolean. In addition, changed default to ``ignore``, which means that warnings will not be shown by default when loading VO tables. [#8715] astropy.modeling ^^^^^^^^^^^^^^^^ - Eliminates support for compound classes (but not compound instances!) [#8769] - Slicing compound models more restrictive. [#8769] - Shape of parameters now includes n_models as dimension. [#8769] - Parameter instances now hold values instead of models. [#8769] - Compound model parameters now share instance and value with constituent models. [#8769] - No longer possible to assign slices of parameter values to model parameters attribute (it is possible to replace it with a complete array). [#8769] - Many private attributes and methods have changed (see documentation). [#8769] - Deprecated ``BlackBody1D`` model and ``blackbody_nu`` and ``blackbody_lambda`` functions. [#9282] - The deprecated ``rotations.rotation_matrix_from_angle`` was removed. [#9363] - Deprecated and renamed ``MexicanHat1D`` and ``MexicanHat2D`` to ``RickerWavelet1D`` and ``RickerWavelet2D``. [#9445] - Deprecated ``modeling.utils.ExpressionTree``. [#9576] astropy.stats ^^^^^^^^^^^^^ - Removed the ``iters`` keyword from sigma clipping stats functions. [#8948] - Renamed the ``a`` parameter to ``data`` in biweight stat functions. [#8948] - Renamed the ``a`` parameter to ``data`` in ``median_absolute_deviation``. [#9011] - Renamed the ``conflevel`` keyword to ``confidence_level`` in ``poisson_conf_interval``. Usage of ``conflevel`` now issues ``AstropyDeprecationWarning``. [#9408] - Renamed the ``conf`` keyword to ``confidence_level`` in ``binom_conf_interval`` and ``binned_binom_proportion``. Usage of ``conf`` now issues ``AstropyDeprecationWarning``. [#9408] - Renamed the ``conf_lvl`` keyword to ``confidence_level`` in ``jackknife_stats``. Usage of ``conf_lvl`` now issues ``AstropyDeprecationWarning``. [#9408] astropy.table ^^^^^^^^^^^^^ - The handling of masked columns in the ``Table`` class has changed in a way that may impact program behavior. Now a ``Table`` with ``masked=False`` may contain both ``Column`` and ``MaskedColumn`` objects, and adding a masked column or row to a table no longer "upgrades" the table and columns to masked. This means that tables with masked data which are read via ``Table.read()`` will now always have ``masked=False``, though specific columns will be masked as needed. Two new table properties ``has_masked_columns`` and ``has_masked_values`` were added. See the `Masking change in astropy 4.0 section within `_ for details. [#8789] - Table operation functions such as ``join``, ``vstack``, ``hstack``, etc now always return a table with ``masked=False``, though the individual columns may be masked as necessary. [#8957] - Changed implementation of ``Table.add_column()`` and ``Table.add_columns()`` methods. Now it is possible add any object(s) which can be converted or broadcasted to a valid column for the table. ``Table.__setitem__`` now just calls ``add_column``. [#8933] - Changed default table configuration setting ``replace_warnings`` from ``['slice']`` to ``[]``. This removes the default warning when replacing a table column that is a slice of another column. [#9144] - Removed the non-public method ``astropy.table.np_utils.recarray_fromrecords``. [#9165] astropy.tests ^^^^^^^^^^^^^ - In addition to ``DeprecationWarning``, now ``FutureWarning`` and ``ImportWarning`` would also be turned into exceptions. [#8506] - ``warnings_to_ignore_by_pyver`` option in ``enable_deprecations_as_exceptions()`` has changed. Please refer to API documentation. [#8506] - Default settings for ``warnings_to_ignore_by_pyver`` are updated to remove very old warnings that are no longer relevant and to add a new warning caused by ``pytest-doctestplus``. [#8506] astropy.time ^^^^^^^^^^^^ - ``Time.get_ut1_utc`` now uses the auto-updated ``IERS_Auto`` by default, instead of the bundled ``IERS_B`` file. [#9226] - Time formats that do not use ``val2`` now raise ValueError instead of silently ignoring a provided value. [#9373] - Custom time formats can now accept floating-point types with extended precision. Existing time formats raise exceptions rather than discarding extended precision through conversion to ordinary floating-point. [#9368] - Time formats (implemented in subclasses of ``TimeFormat``) now have their input and output routines more thoroughly validated, making it more difficult to create damaged ``Time`` objects. [#9375] - The ``TimeDelta.to_value()`` method now can also take the ``format`` name as its argument, in which case the value will be calculated using the ``TimeFormat`` machinery. For this case, one can also pass a ``subfmt`` argument to retrieve the value in another form than ``float``. [#9361] astropy.timeseries ^^^^^^^^^^^^^^^^^^ - Keyword ``midpoint_epoch`` is renamed to ``epoch_time``. [#9455] astropy.uncertainty ^^^^^^^^^^^^^^^^^^^ - ``Distribution`` was rewritten such that it deals better with subclasses. As a result, Quantity distributions now behave correctly with ``to`` methods yielding new distributions of the kind expected for the starting distribution, and ``to_value`` yielding ``NdarrayDistribution`` instances. [#9442] astropy.units ^^^^^^^^^^^^^ - For consistency with ``ndarray``, scalar ``Quantity.value`` will now return a numpy scalar rather than a python one. This should help keep track of precision better, but may lead to unexpected results for the rare cases where numpy scalars behave differently than python ones (e.g., taking the square root of a negative number). [#8876] - Removed the ``magnitude_zero_points`` module, which was deprecated in favour of ``astropy.units.photometric`` since 3.1. [#9353] - ``EquivalentUnitsList`` now has a ``_repr_html_`` method to output a HTML table on a call to ``find_equivalent_units`` in Jupyter notebooks. [#9495] astropy.utils ^^^^^^^^^^^^^ - ``download_file`` and related functions now accept a list of fallback sources, and they are able to update the cache at the user's request. [#9182] - Allow ``astropy.utils.console.ProgressBarOrSpinner.map`` and ``.map_unordered`` to take an argument ``multiprocessing_start_method`` to control how subprocesses are started; the different methods (``fork``, ``spawn``, and ``forkserver``) have different implications in terms of security, efficiency, and behavioural anomalies. The option is useful in particular for cross-platform testing because Windows supports only ``spawn`` while Linux defaults to ``fork``. [#9182] - All operations that act on the astropy download cache now take an argument ``pkgname`` that allows one to specify which package's cache to use. [#8237, #9182] - Removed deprecated ``funcsigs`` and ``futures`` from ``astropy.utils.compat``. [#8909] - Removed the deprecated ``astropy.utils.compat.numpy`` module. [#8910] - Deprecated ``InheritDocstrings`` as it is natively supported by Sphinx 1.7 or higher. [#8881] - Deprecated ``astropy.utils.timer`` module, which has been moved to ``astroquery.utils.timer`` and will be part of ``astroquery`` 0.4.0. [#9038] - Deprecated ``astropy.utils.misc.set_locale`` function, as it is meant for internal use only. [#9471] - The implementation of ``data_info.DataInfo`` has changed (for a considerable performance boost). Generally, this should not affect simple subclasses, but because the class now uses ``__slots__`` any attributes on the class have to be explicitly given a slot. [#8998] - ``IERS`` tables now use ``nan`` to mark missing values (rather than ``1e20``). [#9226] astropy.visualization ^^^^^^^^^^^^^^^^^^^^^ - The default ``clip`` value is now ``False`` in ``ImageNormalize``. [#9478] - The default ``clip`` value is now ``False`` in ``simple_norm``. [#9698] - Infinite values are now excluded when calculating limits in ``ManualInterval`` and ``MinMaxInterval``. They were already excluded in all other interval classes. [#9480] Bug Fixes --------- astropy.convolution ^^^^^^^^^^^^^^^^^^^ - Fixed ``nan_treatment='interpolate'`` option to ``convolve_fft`` to properly take into account ``fill_value``. [#8122] astropy.coordinates ^^^^^^^^^^^^^^^^^^^ - The ``QuantityAttribute`` class now supports a None default value if a unit is specified. [#9345] - When ``Representation`` classes with the same name are defined, this no longer leads to a ``ValueError``, but instead to a warning and the removal of both from the name registry (i.e., one either has to use the class itself to set, e.g., ``representation_type``, or refer to the class by its fully qualified name). [#8561] astropy.io.fits ^^^^^^^^^^^^^^^ - Implemented skip (after warning) of header cards with reserved keywords in ``table_to_hdu``. [#9390] - Add ``AstropyDeprecationWarning`` to ``read_table_fits`` when ``hdu=`` is selected, but does not match single present table HDU. [#9512] astropy.io.votable ^^^^^^^^^^^^^^^^^^ - Address issue #8995 by ignoring BINARY2 null mask bits for string values on parsing a VOTable. In this way, the reader should never create masked values for string types. [#9057] - Corrected a spurious warning issued for the ``value`` attribute of the ``
... """ if not issubclass(cls, Table): raise TypeError(f"'cls' must be a (sub)class of Table, not {type(cls)}") # start by getting a map representation. This requires minimal repackaging. p = to_mapping(cosmology) p["cosmology"] = p["cosmology"].__qualname__ # create metadata from mapping meta = p.pop("meta") if cosmology_in_meta: # move class to Table meta meta["cosmology"] = p.pop("cosmology") # package parameters into lists for Table parsing params = {k: [v] for k, v in p.items()} tbl = cls(params, meta=meta) tbl.add_index("name", unique=True) return tbl def table_identify(origin, format, *args, **kwargs): """Identify if object uses the Table format. Returns ------- bool """ itis = False if origin == "read": itis = isinstance(args[1], Table) and (format in (None, "astropy.table")) return itis # =================================================================== # Register convert_registry.register_reader("astropy.table", Cosmology, from_table) convert_registry.register_writer("astropy.table", Cosmology, to_table) convert_registry.register_identifier("astropy.table", Cosmology, table_identify) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.0952451 astropy-5.0.2/astropy/cosmology/io/tests/0000755000175100001710000000000000000000000017532 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/io/tests/__init__.py0000644000175100001710000000000000000000000021631 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/io/tests/base.py0000644000175100001710000000764000000000000021025 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst # THIRD PARTY import pytest # LOCAL import astropy.units as u from astropy.cosmology import Cosmology, Parameter, realizations from astropy.cosmology.core import _COSMOLOGY_CLASSES from astropy.cosmology.parameters import available cosmo_instances = [getattr(realizations, name) for name in available] ############################################################################## class IOTestMixinBase: """ Tests for a Cosmology[To/From]Format with some ``format``. This class will not be directly called by :mod:`pytest` since its name does not begin with ``Test``. To activate the contained tests this class must be inherited in a subclass. Subclasses must define a :func:`pytest.fixture` ``cosmo`` that returns/yields an instance of a |Cosmology|. See ``TestCosmology`` for an example. """ @pytest.fixture def from_format(self): """Convert to Cosmology using ``Cosmology.from_format()``.""" return Cosmology.from_format @pytest.fixture def to_format(self, cosmo): """Convert Cosmology instance using ``.to_format()``.""" return cosmo.to_format @pytest.fixture def read(self): """Read Cosmology instance using ``Cosmology.read()``.""" return Cosmology.read @pytest.fixture def write(self, cosmo): """Write Cosmology using ``.write()``.""" return cosmo.write class IOFormatTestBase(IOTestMixinBase): """ Directly test ``to/from_``. These are not public API and are discouraged from public use, in favor of ``Cosmology.to/from_format(..., format="")``. Subclasses should have an attribute ``functions`` which is a dictionary containing two items: ``"to"=`` and ``"from"=``. """ @pytest.fixture(scope="class", autouse=True) def setup(self): """Setup and teardown for tests.""" class CosmologyWithKwargs(Cosmology): Tcmb0 = Parameter(unit=u.K) def __init__(self, Tcmb0=0, name="cosmology with kwargs", meta=None, **kwargs): super().__init__(name=name, meta=meta) self._Tcmb0 = Tcmb0 << u.K yield # run tests # pop CosmologyWithKwargs from registered classes # but don't error b/c it can fail in parallel _COSMOLOGY_CLASSES.pop(CosmologyWithKwargs.__qualname__, None) @pytest.fixture(params=cosmo_instances) def cosmo(self, request): """Cosmology instance.""" if isinstance(request.param, str): # CosmologyWithKwargs return _COSMOLOGY_CLASSES[request.param](Tcmb0=3) return request.param @pytest.fixture def cosmo_cls(self, cosmo): """Cosmology classes.""" return cosmo.__class__ # ------------------------------------------- @pytest.fixture def from_format(self): """Convert to Cosmology using function ``from``.""" def use_from_format(*args, **kwargs): kwargs.pop("format", None) # specific to Cosmology.from_format return self.functions["from"](*args, **kwargs) return use_from_format @pytest.fixture def to_format(self, cosmo): """Convert Cosmology to format using function ``to``.""" return lambda *args, **kwargs: self.functions["to"](cosmo, *args, **kwargs) # ------------------------------------------- @pytest.fixture def read(self): """Read Cosmology from file using function ``read``.""" def use_read(*args, **kwargs): kwargs.pop("format", None) # specific to Cosmology.from_format return self.functions["read"](*args, **kwargs) return use_read @pytest.fixture def write(self, cosmo): """Write Cosmology to file using function ``write``.""" return lambda *args, **kwargs: self.functions["write"](cosmo, *args, **kwargs) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/io/tests/test_ecsv.py0000644000175100001710000001757100000000000022116 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst # THIRD PARTY import pytest # LOCAL import astropy.cosmology.units as cu import astropy.units as u from astropy import cosmology from astropy.cosmology import Cosmology, realizations from astropy.cosmology.core import _COSMOLOGY_CLASSES from astropy.cosmology.io.ecsv import read_ecsv, write_ecsv from astropy.table import QTable, Table, vstack from astropy.cosmology.parameters import available from .base import IOTestMixinBase, IOFormatTestBase cosmo_instances = [getattr(realizations, name) for name in available] cosmo_instances.append("TestReadWriteECSV.setup..CosmologyWithKwargs") ############################################################################### class ReadWriteECSVTestMixin(IOTestMixinBase): """ Tests for a Cosmology[Read/Write] with ``format="ascii.ecsv"``. This class will not be directly called by :mod:`pytest` since its name does not begin with ``Test``. To activate the contained tests this class must be inherited in a subclass. Subclasses must dfine a :func:`pytest.fixture` ``cosmo`` that returns/yields an instance of a |Cosmology|. See ``TestCosmology`` for an example. """ @pytest.fixture def add_cu(self): # TODO! autoenable 'cu' if cosmology is imported? with u.add_enabled_units(cu): yield # =============================================================== def test_to_ecsv_bad_index(self, read, write, tmp_path): """Test if argument ``index`` is incorrect""" fp = tmp_path / "test_to_ecsv_bad_index.ecsv" write(fp, format="ascii.ecsv") # single-row table and has a non-0/None index with pytest.raises(IndexError, match="index 2 out of range"): read(fp, index=2, format="ascii.ecsv") # string index where doesn't match with pytest.raises(KeyError, match="No matches found for key"): read(fp, index="row 0", format="ascii.ecsv") # ----------------------- def test_to_ecsv_failed_cls(self, write, tmp_path): """Test failed table type.""" fp = tmp_path / "test_to_ecsv_failed_cls.ecsv" with pytest.raises(TypeError, match="'cls' must be"): write(fp, format='ascii.ecsv', cls=list) @pytest.mark.parametrize("tbl_cls", [QTable, Table]) def test_to_ecsv_cls(self, write, tbl_cls, tmp_path): fp = tmp_path / "test_to_ecsv_cls.ecsv" write(fp, format='ascii.ecsv', cls=tbl_cls) # ----------------------- @pytest.mark.parametrize("in_meta", [True, False]) def test_to_ecsv_in_meta(self, cosmo_cls, write, in_meta, tmp_path, add_cu): """Test where the cosmology class is placed.""" fp = tmp_path / "test_to_ecsv_in_meta.ecsv" write(fp, format='ascii.ecsv', cosmology_in_meta=in_meta) # if it's in metadata, it's not a column. And vice versa. tbl = QTable.read(fp) if in_meta: assert tbl.meta["cosmology"] == cosmo_cls.__qualname__ assert "cosmology" not in tbl.colnames # not also a column else: assert tbl["cosmology"][0] == cosmo_cls.__qualname__ assert "cosmology" not in tbl.meta # ----------------------- def test_tofrom_ecsv_instance(self, cosmo_cls, cosmo, read, write, tmp_path, add_cu): """Test cosmology -> ascii.ecsv -> cosmology.""" fp = tmp_path / "test_tofrom_ecsv_instance.ecsv" # ------------ # To Table write(fp, format="ascii.ecsv") # some checks on the saved file tbl = QTable.read(fp) assert tbl.meta["cosmology"] == cosmo_cls.__qualname__ assert tbl["name"] == cosmo.name # ------------ # From Table tbl["mismatching"] = "will error" tbl.write(fp, format="ascii.ecsv", overwrite=True) # tests are different if the last argument is a **kwarg if tuple(cosmo._init_signature.parameters.values())[-1].kind == 4: got = read(fp, format="ascii.ecsv") assert got.__class__ is cosmo_cls assert got.name == cosmo.name assert "mismatching" not in got.meta return # don't continue testing # read with mismatching parameters errors with pytest.raises(TypeError, match="there are unused parameters"): read(fp, format="ascii.ecsv") # unless mismatched are moved to meta got = read(fp, format="ascii.ecsv", move_to_meta=True) assert got == cosmo assert got.meta["mismatching"] == "will error" # it won't error if everything matches up tbl.remove_column("mismatching") tbl.write(fp, format="ascii.ecsv", overwrite=True) got = read(fp, format="ascii.ecsv") assert got == cosmo # and it will also work if the cosmology is a class # Note this is not the default output of ``write``. tbl.meta["cosmology"] = _COSMOLOGY_CLASSES[tbl.meta["cosmology"]] got = read(fp, format="ascii.ecsv") assert got == cosmo # also it auto-identifies 'format' got = read(fp) assert got == cosmo def test_fromformat_ecsv_subclass_partial_info(self, cosmo_cls, cosmo, read, write, tmp_path, add_cu): """ Test writing from an instance and reading from that class. This works with missing information. """ fp = tmp_path / "test_fromformat_ecsv_subclass_partial_info.ecsv" # test write write(fp, format="ascii.ecsv") # partial information tbl = QTable.read(fp) tbl.meta.pop("cosmology", None) del tbl["Tcmb0"] tbl.write(fp, overwrite=True) # read with the same class that wrote fills in the missing info with # the default value got = cosmo_cls.read(fp, format="ascii.ecsv") got2 = read(fp, format="ascii.ecsv", cosmology=cosmo_cls) got3 = read(fp, format="ascii.ecsv", cosmology=cosmo_cls.__qualname__) assert (got == got2) and (got2 == got3) # internal consistency # not equal, because Tcmb0 is changed assert got != cosmo assert got.Tcmb0 == cosmo_cls._init_signature.parameters["Tcmb0"].default assert got.clone(name=cosmo.name, Tcmb0=cosmo.Tcmb0) == cosmo # but the metadata is the same assert got.meta == cosmo.meta def test_tofrom_ecsv_mutlirow(self, cosmo, read, write, tmp_path, add_cu): """Test if table has multiple rows.""" fp = tmp_path / "test_tofrom_ecsv_mutlirow.ecsv" # Make cosmo1 = cosmo.clone(name="row 0") cosmo2 = cosmo.clone(name="row 2") tbl = vstack([c.to_format("astropy.table") for c in (cosmo1, cosmo, cosmo2)], metadata_conflicts='silent') tbl.write(fp, format="ascii.ecsv") # ------------ # From Table # it will error on a multi-row table with pytest.raises(ValueError, match="need to select a specific row"): read(fp, format="ascii.ecsv") # unless the index argument is provided got = read(fp, index=1, format="ascii.ecsv") assert got == cosmo # the index can be a string got = read(fp, index=cosmo.name, format="ascii.ecsv") assert got == cosmo # it's better if the table already has an index # this will be identical to the previous ``got`` tbl.add_index("name") got2 = read(fp, index=cosmo.name, format="ascii.ecsv") assert got2 == cosmo class TestReadWriteECSV(IOFormatTestBase, ReadWriteECSVTestMixin): """ Directly test ``read/write``. These are not public API and are discouraged from use, in favor of ``Cosmology.read/write(..., format="ascii.ecsv")``, but should be tested regardless b/c they are used internally. """ def setup_class(self): self.functions = {"read": read_ecsv, "write": write_ecsv} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/io/tests/test_mapping.py0000644000175100001710000001135400000000000022602 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst # STDLIB import copy from collections import OrderedDict # THIRD PARTY import pytest # LOCAL import astropy.units as u from astropy.cosmology import Cosmology, realizations from astropy.cosmology.core import _COSMOLOGY_CLASSES, Parameter from astropy.cosmology.io.mapping import from_mapping, to_mapping from astropy.cosmology.parameters import available from astropy.table import QTable, vstack from .base import IOTestMixinBase, IOFormatTestBase cosmo_instances = [getattr(realizations, name) for name in available] cosmo_instances.append("TestToFromMapping.setup..CosmologyWithKwargs") ############################################################################### class ToFromMappingTestMixin(IOTestMixinBase): """ Tests for a Cosmology[To/From]Format with ``format="mapping"``. This class will not be directly called by :mod:`pytest` since its name does not begin with ``Test``. To activate the contained tests this class must be inherited in a subclass. Subclasses must define a :func:`pytest.fixture` ``cosmo`` that returns/yields an instance of a |Cosmology|. See ``TestCosmology`` for an example. """ def test_failed_cls_to_mapping(self, cosmo, to_format): """Test incorrect argument ``cls`` in ``to_mapping()``.""" with pytest.raises(TypeError, match="'cls' must be"): to_format('mapping', cls=list) @pytest.mark.parametrize("map_cls", [dict, OrderedDict]) def test_to_mapping_cls(self, cosmo, to_format, map_cls): """Test argument ``cls`` in ``to_mapping()``.""" params = to_format('mapping', cls=map_cls) assert isinstance(params, map_cls) # test type def test_tofrom_mapping_instance(self, cosmo, to_format, from_format): """Test cosmology -> Mapping -> cosmology.""" # ------------ # To Mapping params = to_format('mapping') assert isinstance(params, dict) # test type assert params["cosmology"] is cosmo.__class__ assert params["name"] == cosmo.name # ------------ # From Mapping params["mismatching"] = "will error" # tests are different if the last argument is a **kwarg if tuple(cosmo._init_signature.parameters.values())[-1].kind == 4: got = from_format(params, format="mapping") assert got.name == cosmo.name assert "mismatching" not in got.meta return # don't continue testing # read with mismatching parameters errors with pytest.raises(TypeError, match="there are unused parameters"): from_format(params, format="mapping") # unless mismatched are moved to meta got = from_format(params, format="mapping", move_to_meta=True) assert got == cosmo assert got.meta["mismatching"] == "will error" # it won't error if everything matches up params.pop("mismatching") got = from_format(params, format="mapping") assert got == cosmo assert got.meta == cosmo.meta # and it will also work if the cosmology is a string params["cosmology"] = params["cosmology"].__qualname__ got = from_format(params, format="mapping") assert got == cosmo assert got.meta == cosmo.meta # also it auto-identifies 'format' got = from_format(params) assert got == cosmo assert got.meta == cosmo.meta def test_fromformat_subclass_partial_info_mapping(self, cosmo): """ Test writing from an instance and reading from that class. This works with missing information. """ # test to_format m = cosmo.to_format("mapping") assert isinstance(m, dict) # partial information m.pop("cosmology", None) m.pop("Tcmb0", None) # read with the same class that wrote fills in the missing info with # the default value got = cosmo.__class__.from_format(m, format="mapping") got2 = Cosmology.from_format(m, format="mapping", cosmology=cosmo.__class__) got3 = Cosmology.from_format(m, format="mapping", cosmology=cosmo.__class__.__qualname__) assert (got == got2) and (got2 == got3) # internal consistency # not equal, because Tcmb0 is changed assert got != cosmo assert got.Tcmb0 == cosmo.__class__._init_signature.parameters["Tcmb0"].default assert got.clone(name=cosmo.name, Tcmb0=cosmo.Tcmb0) == cosmo # but the metadata is the same assert got.meta == cosmo.meta class TestToFromMapping(IOFormatTestBase, ToFromMappingTestMixin): """Directly test ``to/from_mapping``.""" def setup_class(self): self.functions = {"to": to_mapping, "from": from_mapping} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/io/tests/test_model.py0000644000175100001710000001442600000000000022252 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst # STDLIB import inspect import random # THIRD PARTY import pytest import numpy as np # LOCAL import astropy.units as u from astropy import cosmology from astropy.cosmology import Cosmology, Planck18, realizations from astropy.cosmology.core import _COSMOLOGY_CLASSES, Parameter from astropy.cosmology.io.model import _CosmologyModel, from_model, to_model from astropy.cosmology.parameters import available from astropy.modeling import FittableModel from astropy.modeling.models import Gaussian1D from astropy.utils.compat.optional_deps import HAS_SCIPY from .base import IOTestMixinBase, IOFormatTestBase cosmo_instances = [getattr(realizations, name) for name in available] cosmo_instances.append("TestToFromTable.setup..CosmologyWithKwargs") ############################################################################### class ToFromModelTestMixin(IOTestMixinBase): """ Tests for a Cosmology[To/From]Format with ``format="astropy.model"``. This class will not be directly called by :mod:`pytest` since its name does not begin with ``Test``. To activate the contained tests this class must be inherited in a subclass. Subclasses must define a :func:`pytest.fixture` ``cosmo`` that returns/yields an instance of a |Cosmology|. See ``TestCosmologyToFromFormat`` or ``TestCosmology`` for examples. """ @pytest.fixture def method_name(self, cosmo): # get methods, ignoring private and dunder methods = {n for n in dir(cosmo) if (callable(getattr(cosmo, n)) and not n.startswith("_"))} # sieve out incompatible methods for n in tuple(methods): # remove non-introspectable methods try: sig = inspect.signature(getattr(cosmo, n)) except ValueError: methods.discard(n) continue params = list(sig.parameters.keys()) # remove non redshift methods if len(params) == 0 or not params[0].startswith("z"): methods.discard(n) continue # dynamically detect ABC and optional dependencies ERROR_SEIVE = (NotImplementedError, ValueError) # # ABC can't introspect for good input if not HAS_SCIPY: ERROR_SEIVE = ERROR_SEIVE + (ModuleNotFoundError, ) args = np.arange(len(params)) + 1 try: getattr(cosmo, n)(*args) except ERROR_SEIVE: methods.discard(n) # TODO! pytest doesn't currently allow multiple yields (`cosmo`) so # testing with 1 random method # yield from methods return random.choice(tuple(methods)) if methods else None # =============================================================== def test_fromformat_model_wrong_cls(self, from_format): """Test when Model is not the correct class.""" model = Gaussian1D(amplitude=10, mean=14) with pytest.raises(TypeError, match="`model` must be"): from_format(model) def test_toformat_model_not_method(self, to_format): """Test when method is not a method.""" with pytest.raises(AttributeError): to_format("astropy.model", method="this is definitely not a method.") def test_toformat_model_not_callable(self, to_format): """Test when method is actually an attribute.""" with pytest.raises(ValueError): to_format("astropy.model", method="name") def test_toformat_model(self, cosmo, to_format, method_name): """Test cosmology -> astropy.model.""" if method_name is None: # no test if no method return model = to_format("astropy.model", method=method_name) assert isinstance(model, _CosmologyModel) # Parameters expect = tuple([n for n in cosmo.__parameters__ if getattr(cosmo, n) is not None]) assert model.param_names == expect # scalar result args = np.arange(model.n_inputs) + 1 got = model.evaluate(*args) expected = getattr(cosmo, method_name)(*args) assert np.all(got == expected) got = model(*args) expected = getattr(cosmo, method_name)(*args) assert np.all(got == expected) # vector result if "scalar" not in method_name: args = (np.ones((model.n_inputs, 3)).T + np.arange(model.n_inputs)).T got = model.evaluate(*args) expected = getattr(cosmo, method_name)(*args) assert np.all(got == expected) got = model(*args) expected = getattr(cosmo, method_name)(*args) assert np.all(got == expected) def test_tofromformat_model_instance(self, cosmo_cls, cosmo, method_name, to_format, from_format): """Test cosmology -> astropy.model -> cosmology.""" if method_name is None: # no test if no method return # ------------ # To Model # this also serves as a test of all added methods / attributes # in _CosmologyModel. model = to_format("astropy.model", method=method_name) assert isinstance(model, _CosmologyModel) assert model.cosmology_class is cosmo_cls assert model.cosmology == cosmo assert model.method_name == method_name # ------------ # From Model # it won't error if everything matches up got = from_format(model, format="astropy.model") assert got == cosmo assert set(cosmo.meta.keys()).issubset(got.meta.keys()) # Note: model adds parameter attributes to the metadata # also it auto-identifies 'format' got = from_format(model) assert got == cosmo assert set(cosmo.meta.keys()).issubset(got.meta.keys()) def test_fromformat_model_subclass_partial_info(self): """ Test writing from an instance and reading from that class. This works with missing information. """ pass # there's no partial information with a Model class TestToFromModel(IOFormatTestBase, ToFromModelTestMixin): """Directly test ``to/from_model``.""" def setup_class(self): self.functions = {"to": to_model, "from": from_model} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/io/tests/test_table.py0000644000175100001710000001664700000000000022250 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst # THIRD PARTY import pytest # LOCAL import astropy.units as u from astropy import cosmology from astropy.cosmology import Cosmology, Planck18, realizations from astropy.cosmology.core import _COSMOLOGY_CLASSES, Parameter from astropy.cosmology.io.table import from_table, to_table from astropy.cosmology.parameters import available from astropy.table import QTable, Table, vstack from .base import IOTestMixinBase, IOFormatTestBase cosmo_instances = [getattr(realizations, name) for name in available] cosmo_instances.append("TestToFromTable.setup..CosmologyWithKwargs") ############################################################################### class ToFromTableTestMixin(IOTestMixinBase): """ Tests for a Cosmology[To/From]Format with ``format="astropy.table"``. This class will not be directly called by :mod:`pytest` since its name does not begin with ``Test``. To activate the contained tests this class must be inherited in a subclass. Subclasses must define a :func:`pytest.fixture` ``cosmo`` that returns/yields an instance of a |Cosmology|. See ``TestCosmology`` for an example. """ def test_to_table_bad_index(self, from_format, to_format): """Test if argument ``index`` is incorrect""" tbl = to_format("astropy.table") # single-row table and has a non-0/None index with pytest.raises(IndexError, match="index 2 out of range"): from_format(tbl, index=2, format="astropy.table") # string index where doesn't match with pytest.raises(KeyError, match="No matches found for key"): from_format(tbl, index="row 0", format="astropy.table") # ----------------------- def test_to_table_failed_cls(self, to_format): """Test failed table type.""" with pytest.raises(TypeError, match="'cls' must be"): to_format('astropy.table', cls=list) @pytest.mark.parametrize("tbl_cls", [QTable, Table]) def test_to_table_cls(self, to_format, tbl_cls): tbl = to_format('astropy.table', cls=tbl_cls) assert isinstance(tbl, tbl_cls) # test type # ----------------------- @pytest.mark.parametrize("in_meta", [True, False]) def test_to_table_in_meta(self, cosmo_cls, to_format, in_meta): """Test where the cosmology class is placed.""" tbl = to_format('astropy.table', cosmology_in_meta=in_meta) # if it's in metadata, it's not a column. And vice versa. if in_meta: assert tbl.meta["cosmology"] == cosmo_cls.__qualname__ assert "cosmology" not in tbl.colnames # not also a column else: assert tbl["cosmology"][0] == cosmo_cls.__qualname__ assert "cosmology" not in tbl.meta # ----------------------- def test_tofrom_table_instance(self, cosmo_cls, cosmo, from_format, to_format): """Test cosmology -> astropy.table -> cosmology.""" # ------------ # To Table tbl = to_format("astropy.table") assert isinstance(tbl, QTable) assert tbl.meta["cosmology"] == cosmo_cls.__qualname__ assert tbl["name"] == cosmo.name assert tbl.indices # indexed! # ------------ # From Table tbl["mismatching"] = "will error" # tests are different if the last argument is a **kwarg if tuple(cosmo._init_signature.parameters.values())[-1].kind == 4: got = from_format(tbl, format="astropy.table") assert got.__class__ is cosmo_cls assert got.name == cosmo.name assert "mismatching" not in got.meta return # don't continue testing # read with mismatching parameters errors with pytest.raises(TypeError, match="there are unused parameters"): from_format(tbl, format="astropy.table") # unless mismatched are moved to meta got = from_format(tbl, format="astropy.table", move_to_meta=True) assert got == cosmo assert got.meta["mismatching"] == "will error" # it won't error if everything matches up tbl.remove_column("mismatching") got = from_format(tbl, format="astropy.table") assert got == cosmo # and it will also work if the cosmology is a class # Note this is not the default output of ``to_format``. tbl.meta["cosmology"] = _COSMOLOGY_CLASSES[tbl.meta["cosmology"]] got = from_format(tbl, format="astropy.table") assert got == cosmo # also it auto-identifies 'format' got = from_format(tbl) assert got == cosmo def test_fromformat_table_subclass_partial_info(self, cosmo_cls, cosmo, from_format, to_format): """ Test writing from an instance and reading from that class. This works with missing information. """ # test to_format tbl = to_format("astropy.table") assert isinstance(tbl, QTable) # partial information tbl.meta.pop("cosmology", None) del tbl["Tcmb0"] # read with the same class that wrote fills in the missing info with # the default value got = cosmo_cls.from_format(tbl, format="astropy.table") got2 = from_format(tbl, format="astropy.table", cosmology=cosmo_cls) got3 = from_format(tbl, format="astropy.table", cosmology=cosmo_cls.__qualname__) assert (got == got2) and (got2 == got3) # internal consistency # not equal, because Tcmb0 is changed assert got != cosmo assert got.Tcmb0 == cosmo_cls._init_signature.parameters["Tcmb0"].default assert got.clone(name=cosmo.name, Tcmb0=cosmo.Tcmb0) == cosmo # but the metadata is the same assert got.meta == cosmo.meta @pytest.mark.parametrize("add_index", [True, False]) def test_tofrom_table_mutlirow(self, cosmo_cls, cosmo, to_format, from_format, add_index): """Test if table has multiple rows.""" # ------------ # To Table cosmo1 = cosmo.clone(name="row 0") cosmo2 = cosmo.clone(name="row 2") tbl = vstack([c.to_format("astropy.table") for c in (cosmo1, cosmo, cosmo2)], metadata_conflicts='silent') assert isinstance(tbl, QTable) assert tbl.meta["cosmology"] == cosmo_cls.__qualname__ assert tbl[1]["name"] == cosmo.name # whether to add an index. `from_format` can work with or without. if add_index: tbl.add_index("name", unique=True) # ------------ # From Table # it will error on a multi-row table with pytest.raises(ValueError, match="need to select a specific row"): from_format(tbl, format="astropy.table") # unless the index argument is provided got = from_format(tbl, index=1, format="astropy.table") assert got == cosmo # the index can be a string got = from_format(tbl, index=cosmo.name, format="astropy.table") assert got == cosmo # when there's more than one cosmology found tbls = vstack([tbl, tbl], metadata_conflicts="silent") with pytest.raises(ValueError, match="more than one"): from_format(tbls, index=cosmo.name, format="astropy.table") class TestToFromTable(IOFormatTestBase, ToFromTableTestMixin): """Directly test ``to/from_table``.""" def setup_class(self): self.functions = {"to": to_table, "from": from_table} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/parameter.py0000644000175100001710000002037500000000000020322 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import astropy.units as u from astropy.utils.decorators import classproperty __all__ = ["Parameter"] class Parameter: r"""Cosmological parameter (descriptor). Should only be used with a :class:`~astropy.cosmology.Cosmology` subclass. Parameters ---------- fvalidate : callable[[object, object, Any], Any] or str, optional Function to validate the Parameter value from instances of the cosmology class. If "default", uses default validator to assign units (with equivalencies), if Parameter has units. For other valid string options, see ``Parameter._registry_validators``. 'fvalidate' can also be set through a decorator with :meth:`~astropy.cosmology.Parameter.validator`. doc : str or None, optional Parameter description. unit : unit-like or None (optional, keyword-only) The `~astropy.units.Unit` for the Parameter. If None (default) no unit as assumed. equivalencies : `~astropy.units.Equivalency` or sequence thereof Unit equivalencies for this Parameter. fmt : str (optional, keyword-only) `format` specification, used when making string representation of the containing Cosmology. See https://docs.python.org/3/library/string.html#formatspec derived : bool (optional, keyword-only) Whether the Parameter is 'derived', default `False`. Derived parameters behave similarly to normal parameters, but are not sorted by the |Cosmology| signature (probably not there) and are not included in all methods. For reference, see ``Ode0`` in ``FlatFLRWMixin``, which removes :math:`\Omega_{de,0}`` as an independent parameter (:math:`\Omega_{de,0} \equiv 1 - \Omega_{tot}`). Examples -------- For worked examples see :class:`~astropy.cosmology.FLRW`. """ _registry_validators = {} def __init__(self, fvalidate="default", doc=None, *, unit=None, equivalencies=[], fmt=".3g", derived=False): # parse registered fvalidate if callable(fvalidate): pass elif fvalidate in self._registry_validators: fvalidate = self._registry_validators[fvalidate] elif isinstance(fvalidate, str): raise ValueError("`fvalidate`, if str, must be in " f"{self._registry_validators.keys()}") else: raise TypeError("`fvalidate` must be a function or " f"{self._registry_validators.keys()}") self.__doc__ = doc self._fvalidate = fvalidate # units stuff self._unit = u.Unit(unit) if unit is not None else None self._equivalencies = equivalencies # misc self._fmt = str(fmt) self._derived = derived def __set_name__(self, cosmo_cls, name): # attribute name self._attr_name = name self._attr_name_private = "_" + name @property def name(self): """Parameter name.""" return self._attr_name @property def unit(self): """Parameter unit.""" return self._unit @property def equivalencies(self): """Equivalencies used when initializing Parameter.""" return self._equivalencies @property def format_spec(self): """String format specification.""" return self._fmt @property def derived(self): """Whether the Parameter is derived; true parameters are not.""" return self._derived # ------------------------------------------- # descriptor and property-like methods def __get__(self, cosmology, cosmo_cls=None): # get from class if cosmology is None: return self return getattr(cosmology, self._attr_name_private) def __set__(self, cosmology, value): """Allows attribute setting once. Raises AttributeError subsequently.""" # raise error if setting 2nd time. if hasattr(cosmology, self._attr_name_private): raise AttributeError("can't set attribute") # validate value, generally setting units if present value = self.validate(cosmology, value) setattr(cosmology, self._attr_name_private, value) # ------------------------------------------- # validate value @property def fvalidate(self): """Function to validate a potential value of this Parameter..""" return self._fvalidate def validator(self, fvalidate): """Make new Parameter with custom ``fvalidate``. Note: ``Parameter.fvalidator`` must be the top-most descriptor decorator. Parameters ---------- fvalidate : callable[[type, type, Any], Any] Returns ------- `~astropy.cosmology.Parameter` Copy of this Parameter but with custom ``fvalidate``. """ desc = type(self)(fvalidate=fvalidate, doc=self.__doc__, fmt=self.format_spec, unit=self.unit, equivalencies=self.equivalencies, derived=self.derived) return desc def validate(self, cosmology, value): """Run the validator on this Parameter. Parameters ---------- cosmology : `~astropy.cosmology.Cosmology` instance value : Any The object to validate. Returns ------- Any The output of calling ``fvalidate(cosmology, self, value)`` (yes, that parameter order). """ return self.fvalidate(cosmology, self, value) @classmethod def register_validator(cls, key, fvalidate=None): """Decorator to register a new kind of validator function. Parameters ---------- key : str fvalidate : callable[[object, object, Any], Any] or None, optional Value validation function. Returns ------- ``validator`` or callable[``validator``] if validator is None returns a function that takes and registers a validator. This allows ``register_validator`` to be used as a decorator. """ if key in cls._registry_validators: raise KeyError(f"validator {key!r} already registered with Parameter.") # fvalidate directly passed if fvalidate is not None: cls._registry_validators[key] = fvalidate return fvalidate # for use as a decorator def register(fvalidate): """Register validator function. Parameters ---------- fvalidate : callable[[object, object, Any], Any] Validation function. Returns ------- ``validator`` """ cls._registry_validators[key] = fvalidate return fvalidate return register # ------------------------------------------- def __repr__(self): return f"" # =================================================================== # Built-in validators @Parameter.register_validator("default") def _validate_with_unit(cosmology, param, value): """ Default Parameter value validator. Adds/converts units if Parameter has a unit. """ if param.unit is not None: with u.add_enabled_equivalencies(param.equivalencies): value = u.Quantity(value, param.unit) return value @Parameter.register_validator("float") def _validate_to_float(cosmology, param, value): """Parameter value validator with units, and converted to float.""" value = _validate_with_unit(cosmology, param, value) return float(value) @Parameter.register_validator("scalar") def _validate_to_scalar(cosmology, param, value): """""" value = _validate_with_unit(cosmology, param, value) if not value.isscalar: raise ValueError(f"{param.name} is a non-scalar quantity") return value @Parameter.register_validator("non-negative") def _validate_non_negative(cosmology, param, value): """Parameter value validator where value is a positive float.""" value = _validate_to_float(cosmology, param, value) if value < 0.0: raise ValueError(f"{param.name} cannot be negative.") return value ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/parameters.py0000644000175100001710000001775600000000000020516 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """This module contains dictionaries with sets of parameters for a given cosmology. Each cosmology has the following parameters defined: ========== ===================================== Oc0 Omega cold dark matter at z=0 Ob0 Omega baryon at z=0 Om0 Omega matter at z=0 flat Is this assumed flat? If not, Ode0 must be specified Ode0 Omega dark energy at z=0 if flat is False H0 Hubble parameter at z=0 in km/s/Mpc n Density perturbation spectral index Tcmb0 Current temperature of the CMB Neff Effective number of neutrino species m_nu Assumed mass of neutrino species, in eV. sigma8 Density perturbation amplitude tau Ionisation optical depth z_reion Redshift of hydrogen reionisation t0 Age of the universe in Gyr reference Reference for the parameters ========== ===================================== The list of cosmologies available are given by the tuple `available`. Current cosmologies available: Planck 2018 (Planck18) parameters from Planck Collaboration 2020, A&A, 641, A6 (Paper VI), Table 2 (TT, TE, EE + lowE + lensing + BAO) Planck 2018 (Planck18_arXiv_v2) parameters from Planck Collaboration 2018, arXiv:1807.06209v2 (Paper VI), Table 2 (TT, TE, EE + lowE + lensing + BAO) Planck 2015 (Planck15) parameters from Planck Collaboration 2016, A&A, 594, A13 (Paper XIII), Table 4 (TT, TE, EE + lowP + lensing + ext) Planck 2013 (Planck13) parameters from Planck Collaboration 2014, A&A, 571, A16 (Paper XVI), Table 5 (Planck + WP + highL + BAO) WMAP 9 year (WMAP9) parameters from Hinshaw et al. 2013, ApJS, 208, 19, doi: 10.1088/0067-0049/208/2/19. Table 4 (WMAP9 + eCMB + BAO + H0) WMAP 7 year (WMAP7) parameters from Komatsu et al. 2011, ApJS, 192, 18, doi: 10.1088/0067-0049/192/2/18. Table 1 (WMAP + BAO + H0 ML). WMAP 5 year (WMAP5) parameters from Komatsu et al. 2009, ApJS, 180, 330, doi: 10.1088/0067-0049/180/2/330. Table 1 (WMAP + BAO + SN ML). WMAP 3 year (WMAP3) parameters from Spergel et al. 2007, ApJS, 170, 377, doi: 10.1086/513700. Table 6. (WMAP + SNGold) Obtained from https://lambda.gsfc.nasa.gov/product/map/dr2/params/lcdm_wmap_sngold.cfm Tcmb0 and Neff are the standard values as also used for WMAP5, 7, 9. Pending WMAP team approval and subject to change. WMAP 1 year (WMAP1) parameters from Spergel et al. 2003, ApJS, 148, 175, doi: 10.1086/377226. Table 7 (WMAP + CBI + ACBAR + 2dFGRS + Lya) Tcmb0 and Neff are the standard values as also used for WMAP5, 7, 9. Pending WMAP team approval and subject to change. """ # STDLIB from types import MappingProxyType # LOCAL import astropy.units as u # Note: if you add a new cosmology, please also update the table # in the 'Built-in Cosmologies' section of astropy/docs/cosmology/index.rst # in addition to the list above. You also need to add them to the 'available' # list at the bottom of this file. # Planck 2018 paper VI # Unlike Planck 2015, the paper includes massive neutrinos in Om0, which here # are included in m_nu. Hence, the Om0 value differs slightly from the paper. Planck18 = MappingProxyType(dict( cosmology="FlatLambdaCDM", Oc0=0.2607, Ob0=0.04897, Om0=0.30966, H0=67.66 * (u.km / u.s / u.Mpc), n=0.9665, sigma8=0.8102, tau=0.0561, z_reion=7.82, t0=13.787 * u.Gyr, Tcmb0=2.7255 * u.K, Neff=3.046, flat=True, m_nu=[0., 0., 0.06] * u.eV, reference=("Planck Collaboration 2018, 2020, A&A, 641, A6 (Paper VI)," " Table 2 (TT, TE, EE + lowE + lensing + BAO)") )) # Planck 2018 paper VI v2. Identical to Planck18 above. # Warning: deprecated and will be removed in future versions. Planck18_arXiv_v2 = MappingProxyType(dict( cosmology="FlatLambdaCDM", Oc0=0.2607, Ob0=0.04897, Om0=0.30966, H0=67.66 * (u.km / u.s / u.Mpc), n=0.9665, sigma8=0.8102, tau=0.0561, z_reion=7.82, t0=13.787 * u.Gyr, Tcmb0=2.7255 * u.K, Neff=3.046, flat=True, m_nu=[0., 0., 0.06] * u.eV, reference=("DEPRECATED: Planck Collaboration 2018, arXiv:1807.06209 v2 (Paper VI)," " Table 2 (TT, TE, EE + lowE + lensing + BAO)") )) # Planck 2015 paper XII Table 4 final column (best fit) Planck15 = MappingProxyType(dict( cosmology="FlatLambdaCDM", Oc0=0.2589, Ob0=0.04860, Om0=0.3075, H0=67.74 * (u.km / u.s / u.Mpc), n=0.9667, sigma8=0.8159, tau=0.066, z_reion=8.8, t0=13.799 * u.Gyr, Tcmb0=2.7255 * u.K, Neff=3.046, flat=True, m_nu=[0., 0., 0.06] * u.eV, reference=("Planck Collaboration 2016, A&A, 594, A13 (Paper XIII)," " Table 4 (TT, TE, EE + lowP + lensing + ext)") )) # Planck 2013 paper XVI Table 5 penultimate column (best fit) Planck13 = MappingProxyType(dict( cosmology="FlatLambdaCDM", Oc0=0.25886, Ob0=0.048252, Om0=0.30712, H0=67.77 * (u.km / u.s / u.Mpc), n=0.9611, sigma8=0.8288, tau=0.0952, z_reion=11.52, t0=13.7965 * u.Gyr, Tcmb0=2.7255 * u.K, Neff=3.046, flat=True, m_nu=[0., 0., 0.06] * u.eV, reference=("Planck Collaboration 2014, A&A, 571, A16 (Paper XVI)," " Table 5 (Planck + WP + highL + BAO)") )) WMAP9 = MappingProxyType(dict( cosmology="FlatLambdaCDM", Oc0=0.2402, Ob0=0.04628, Om0=0.2865, H0=69.32 * (u.km / u.s / u.Mpc), n=0.9608, sigma8=0.820, tau=0.081, z_reion=10.1, t0=13.772 * u.Gyr, Tcmb0=2.725 * u.K, Neff=3.04, m_nu=0.0 * u.eV, flat=True, reference=("Hinshaw et al. 2013, ApJS, 208, 19, " "doi: 10.1088/0067-0049/208/2/19. " "Table 4 (WMAP9 + eCMB + BAO + H0, last column)") )) WMAP7 = MappingProxyType(dict( cosmology="FlatLambdaCDM", Oc0=0.226, Ob0=0.0455, Om0=0.272, H0=70.4 * (u.km / u.s / u.Mpc), n=0.967, sigma8=0.810, tau=0.085, z_reion=10.3, t0=13.76 * u.Gyr, Tcmb0=2.725 * u.K, Neff=3.04, m_nu=0.0 * u.eV, flat=True, reference=("Komatsu et al. 2011, ApJS, 192, 18, " "doi: 10.1088/0067-0049/192/2/18. " "Table 1 (WMAP + BAO + H0 ML).") )) WMAP5 = MappingProxyType(dict( cosmology="FlatLambdaCDM", Oc0=0.231, Ob0=0.0459, Om0=0.277, H0=70.2 * (u.km / u.s / u.Mpc), n=0.962, sigma8=0.817, tau=0.088, z_reion=11.3, t0=13.72 * u.Gyr, Tcmb0=2.725 * u.K, Neff=3.04, m_nu=0.0 * u.eV, flat=True, reference=("Komatsu et al. 2009, ApJS, 180, 330, " "doi: 10.1088/0067-0049/180/2/330. " "Table 1 (WMAP + BAO + SN ML).") )) WMAP3 = MappingProxyType(dict( cosmology="FlatLambdaCDM", Oc0=0.230, Ob0=0.0454, Om0=0.276, H0=70.1 * (u.km / u.s / u.Mpc), n=0.946, sigma8=0.784, tau=0.079, z_reion=10.3, t0=13.78 * u.Gyr, Tcmb0=2.725 * u.K, Neff=3.04, m_nu=0.0 * u.eV, flat=True, reference=(r"Spergel et al. 2007, ApJS, 170, 377, " r"doi: 10.1086/513700. " r"Table 6 (WMAP + SNGold) " r"obtained from: https://lambda.gsfc.nasa.gov/product/map/dr2/params/lcdm_wmap_sngold.cfm" r"\nPending WMAP team approval and subject to change.") )) WMAP1 = MappingProxyType(dict( cosmology="FlatLambdaCDM", Oc0=0.213, Ob0=0.0436, Om0=0.257, H0=72. * (u.km / u.s / u.Mpc), n=0.96, sigma8=0.75, tau=0.117, z_reion=17.0, # Only from WMAP1. Does not exist in the combined analysis. t0=13.4 * u.Gyr, Tcmb0=2.725 * u.K, Neff=3.04, m_nu=0.0 * u.eV, flat=True, reference=(r"Spergel et al. 2003, ApJS, 148, 175, " r"doi: 10.1086/377226. " r"Table 7 (WMAP + CBI + ACBAR + 2dFGRS + Lya)." r"\nPending WMAP team approval and subject to change.") )) # If new parameters are added, this list must be updated available = ('Planck18', 'Planck18_arXiv_v2', 'Planck15', 'Planck13', 'WMAP9', 'WMAP7', 'WMAP5', 'WMAP3', 'WMAP1') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/realizations.py0000644000175100001710000000544000000000000021042 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import sys import warnings from astropy import units as u from astropy.utils.exceptions import AstropyDeprecationWarning from astropy.utils.state import ScienceState from . import parameters from .core import _COSMOLOGY_CLASSES, Cosmology __all__ = ["default_cosmology"] + list(parameters.available) __doctest_requires__ = {"*": ["scipy"]} # Pre-defined cosmologies. This loops over the parameter sets in the # parameters module and creates a corresponding cosmology instance for key in parameters.available: params = dict(getattr(parameters, key)) # get parameters dict (copy) params.setdefault("name", key) # make cosmology cosmo = Cosmology.from_format(params, format="mapping", move_to_meta=True) cosmo.__doc__ = (f"{key} instance of {cosmo.__class__.__qualname__} " f"cosmology\n(from {cosmo.meta['reference']})") # put in this namespace setattr(sys.modules[__name__], key, cosmo) del key, params, cosmo # clean the namespace ######################################################################### # The science state below contains the current cosmology. ######################################################################### class default_cosmology(ScienceState): """ The default cosmology to use. To change it:: >>> from astropy.cosmology import default_cosmology, WMAP7 >>> with default_cosmology.set(WMAP7): ... # WMAP7 cosmology in effect ... pass Or, you may use a string:: >>> with default_cosmology.set('WMAP7'): ... # WMAP7 cosmology in effect ... pass """ _value = "Planck18" @staticmethod def get_cosmology_from_string(arg): """ Return a cosmology instance from a string. """ if arg == "no_default": cosmo = None else: try: cosmo = getattr(sys.modules[__name__], arg) except AttributeError: s = "Unknown cosmology '{}'. Valid cosmologies:\n{}".format( arg, parameters.available ) raise ValueError(s) return cosmo @classmethod def validate(cls, value): if value is None: value = "Planck18" if isinstance(value, str): if value == "Planck18_arXiv_v2": warnings.warn( f"{value} is deprecated in astropy 4.2, use Planck18 instead", AstropyDeprecationWarning, ) return cls.get_cosmology_from_string(value) elif isinstance(value, Cosmology): return value else: raise TypeError( "default_cosmology must be a string or Cosmology instance." ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/scalar_inv_efuncs.pyx0000644000175100001710000002163300000000000022214 0ustar00vstsdocker#cython: language_level=3, boundscheck=False """ Cython inverse efuncs for cosmology integrals""" cimport cython from libc.math cimport exp, pow ## Inverse efunc methods for various dark energy subclasses ## These take only scalar arguments since that is what the integral ## routines give them. ## Implementation notes: ## * Using a python list for nu_y seems to be faster than a ndarray, ## given that nu_y generally has a small number of elements, ## even when you turn off bounds checking, etc. ## * Using pow(x, -0.5) is slightly faster than x**(-0.5) and ## even more so than 1.0 / sqrt(x) ## * Hardwiring in the p, 1/p, k, prefac values in nufunc is ## nontrivially faster than declaring them with cdef ######### LambdaCDM # No relativistic species def lcdm_inv_efunc_norel(double z, double Om0, double Ode0, double Ok0): cdef double opz = 1.0 + z return pow(opz**2 * (opz * Om0 + Ok0) + Ode0, -0.5) # Massless neutrinos def lcdm_inv_efunc_nomnu(double z, double Om0, double Ode0, double Ok0, double Or0): cdef double opz = 1.0 + z return pow((((opz * Or0 + Om0) * opz) + Ok0) * opz**2 + Ode0, -0.5) # With massive neutrinos def lcdm_inv_efunc(double z, double Om0, double Ode0, double Ok0, double Ogamma0, double NeffPerNu, int nmasslessnu, list nu_y): cdef double opz = 1.0 + z cdef double Or0 = Ogamma0 * (1.0 + nufunc(opz, NeffPerNu, nmasslessnu, nu_y)) return pow((((opz * Or0 + Om0) * opz) + Ok0) * opz**2 + Ode0, -0.5) ######## FlatLambdaCDM # No relativistic species def flcdm_inv_efunc_norel(double z, double Om0, double Ode0): return pow((1. + z)**3 * Om0 + Ode0, -0.5) # Massless neutrinos def flcdm_inv_efunc_nomnu(double z, double Om0, double Ode0, double Or0): cdef double opz = 1.0 + z return pow(opz**3 * (opz * Or0 + Om0) + Ode0, -0.5) # With massive neutrinos def flcdm_inv_efunc(double z, double Om0, double Ode0, double Ogamma0, double NeffPerNu, int nmasslessnu, list nu_y): cdef double opz = 1.0 + z cdef double Or0 = Ogamma0 * (1.0 + nufunc(opz, NeffPerNu, nmasslessnu, nu_y)) return pow(opz**3 * (opz * Or0 + Om0) + Ode0, -0.5) ######## wCDM # No relativistic species def wcdm_inv_efunc_norel(double z, double Om0, double Ode0, double Ok0, double w0): cdef double opz = 1.0 + z return pow(opz**2 * (opz * Om0 + Ok0) + Ode0 * opz**(3. * (1.0 + w0)), -0.5) # Massless neutrinos def wcdm_inv_efunc_nomnu(double z, double Om0, double Ode0, double Ok0, double Or0, double w0): cdef double opz = 1.0 + z return pow((((opz * Or0 + Om0) * opz) + Ok0) * opz**2 + Ode0 * opz**(3. * (1.0 + w0)), -0.5) # With massive neutrinos def wcdm_inv_efunc(double z, double Om0, double Ode0, double Ok0, double Ogamma0, double NeffPerNu, int nmasslessnu, list nu_y, double w0): cdef double opz = 1.0 + z cdef double Or0 = Ogamma0 * (1.0 + nufunc(opz, NeffPerNu, nmasslessnu, nu_y)) return pow((((opz * Or0 + Om0) * opz) + Ok0) * opz**2 + Ode0 * opz**(3. * (1.0 + w0)), -0.5) ######## Flat wCDM # No relativistic species def fwcdm_inv_efunc_norel(double z, double Om0, double Ode0, double w0): cdef double opz = 1.0 + z return pow(opz**3 * Om0 + Ode0 * opz**(3. * (1.0 + w0)), -0.5) # Massless neutrinos def fwcdm_inv_efunc_nomnu(double z, double Om0, double Ode0, double Or0, double w0): cdef double opz = 1.0 + z return pow(opz**3 * (opz * Or0 + Om0) + Ode0 * opz**(3. * (1.0 + w0)), -0.5) # With massive neutrinos def fwcdm_inv_efunc(double z, double Om0, double Ode0, double Ogamma0, double NeffPerNu, int nmasslessnu, list nu_y, double w0): cdef double opz = 1.0 + z cdef double Or0 = Ogamma0 * (1.0 + nufunc(opz, NeffPerNu, nmasslessnu, nu_y)) return pow(opz**3 * (opz * Or0 + Om0) + Ode0 * opz**(3. * (1.0 + w0)), -0.5) ######## w0waCDM # No relativistic species def w0wacdm_inv_efunc_norel(double z, double Om0, double Ode0, double Ok0, double w0, double wa): cdef double opz = 1.0 + z cdef Odescl = opz**(3. * (1 + w0 + wa)) * exp(-3.0 * wa * z / opz) return pow(opz**2 * (opz * Om0 + Ok0) + Ode0 * Odescl, -0.5) # Massless neutrinos def w0wacdm_inv_efunc_nomnu(double z, double Om0, double Ode0, double Ok0, double Or0, double w0, double wa): cdef double opz = 1.0 + z cdef Odescl = opz**(3. * (1 + w0 + wa)) * exp(-3.0 * wa * z / opz) return pow((((opz * Or0 + Om0) * opz) + Ok0) * opz**2 + Ode0 * Odescl, -0.5) def w0wacdm_inv_efunc(double z, double Om0, double Ode0, double Ok0, double Ogamma0, double NeffPerNu, int nmasslessnu, list nu_y, double w0, double wa): cdef double opz = 1.0 + z cdef double Or0 = Ogamma0 * (1.0 + nufunc(opz, NeffPerNu, nmasslessnu, nu_y)) cdef Odescl = opz**(3. * (1 + w0 + wa)) * exp(-3.0 * wa * z / opz) return pow((((opz * Or0 + Om0) * opz) + Ok0) * opz**2 + Ode0 * Odescl, -0.5) ######## Flatw0waCDM # No relativistic species def fw0wacdm_inv_efunc_norel(double z, double Om0, double Ode0, double w0, double wa): cdef double opz = 1.0 + z cdef Odescl = opz**(3. * (1 + w0 + wa)) * exp(-3.0 * wa * z / opz) return pow(opz**3 * Om0 + Ode0 * Odescl, -0.5) # Massless neutrinos def fw0wacdm_inv_efunc_nomnu(double z, double Om0, double Ode0, double Or0, double w0, double wa): cdef double opz = 1.0 + z cdef Odescl = opz**(3. * (1 + w0 + wa)) * exp(-3.0 * wa * z / opz) return pow((opz * Or0 + Om0) * opz**3 + Ode0 * Odescl, -0.5) # With massive neutrinos def fw0wacdm_inv_efunc(double z, double Om0, double Ode0, double Ogamma0, double NeffPerNu, int nmasslessnu, list nu_y, double w0, double wa): cdef double opz = 1.0 + z cdef double Or0 = Ogamma0 * (1.0 + nufunc(opz, NeffPerNu, nmasslessnu, nu_y)) cdef Odescl = opz**(3. * (1 + w0 + wa)) * exp(-3.0 * wa * z / opz) return pow((opz * Or0 + Om0) * opz**3 + Ode0 * Odescl, -0.5) ######## wpwaCDM # No relativistic species def wpwacdm_inv_efunc_norel(double z, double Om0, double Ode0, double Ok0, double wp, double apiv, double wa): cdef double opz = 1.0 + z cdef Odescl = opz**(3. * (1. + wp + apiv * wa)) * exp(-3. * wa * z / opz) return pow(opz**2 * (opz * Om0 + Ok0) + Ode0 * Odescl, -0.5) # Massless neutrinos def wpwacdm_inv_efunc_nomnu(double z, double Om0, double Ode0, double Ok0, double Or0, double wp, double apiv, double wa): cdef double opz = 1.0 + z cdef Odescl = opz**(3. * (1. + wp + apiv * wa)) * exp(-3. * wa * z / opz) return pow((((opz * Or0 + Om0) * opz) + Ok0) * opz**2 + Ode0 * Odescl, -0.5) # With massive neutrinos def wpwacdm_inv_efunc(double z, double Om0, double Ode0, double Ok0, double Ogamma0, double NeffPerNu, int nmasslessnu, list nu_y, double wp, double apiv, double wa): cdef double opz = 1.0 + z cdef double Or0 = Ogamma0 * (1.0 + nufunc(opz, NeffPerNu, nmasslessnu, nu_y)) cdef Odescl = opz**(3. * (1. + wp + apiv * wa)) * exp(-3. * wa * z / opz) return pow((((opz * Or0 + Om0) * opz) + Ok0) * opz**2 + Ode0 * Odescl, -0.5) ######## w0wzCDM # No relativistic species def w0wzcdm_inv_efunc_norel(double z, double Om0, double Ode0, double Ok0, double w0, double wz): cdef double opz = 1.0 + z cdef Odescl = opz**(3. * (1. + w0 - wz)) * exp(-3. * wz * z) return pow(opz**2 * (opz * Om0 + Ok0) + Ode0 * Odescl, -0.5) # Massless neutrinos def w0wzcdm_inv_efunc_nomnu(double z, double Om0, double Ode0, double Ok0, double Or0, double w0, double wz): cdef double opz = 1.0 + z cdef Odescl = opz**(3. * (1. + w0 - wz)) * exp(-3. * wz * z) return pow((((opz * Or0 + Om0) * opz) + Ok0) * opz**2 + Ode0 * Odescl, -0.5) # With massive neutrinos def w0wzcdm_inv_efunc(double z, double Om0, double Ode0, double Ok0, double Ogamma0, double NeffPerNu, int nmasslessnu, list nu_y, double w0, double wz): cdef double opz = 1.0 + z cdef double Or0 = Ogamma0 * (1.0 + nufunc(opz, NeffPerNu, nmasslessnu, nu_y)) cdef Odescl = opz**(3. * (1. + w0 - wz)) * exp(-3. * wz * z) return pow((((opz * Or0 + Om0) * opz) + Ok0) * opz**2 + Ode0 * Odescl, -0.5) ######## Neutrino relative density function # Scalar equivalent to FLRW.nu_realative_density in core.py # Please see that for further discussion. # This should only be called with massive neutrinos (e.g., nu_y is not empty) # Briefly, this is just a numerical fitting function to the true relationship, # which is too expensive to want to evaluate directly. The # constants which appear are: # p = 1.83 -> numerical fitting constant from Komatsu et al. # 1/p = 0.54644... -> same constant # k = 0.3173 -> another fitting constant # 7/8 (4/11)^(4/3) = 0.2271... -> fermion/boson constant for neutrino # contribution -- see any cosmology book # The Komatsu reference is: Komatsu et al. 2011, ApJS 192, 18 cdef nufunc(double opz, double NeffPerNu, int nmasslessnu, list nu_y): cdef int N = len(nu_y) cdef double k = 0.3173 / opz cdef double rel_mass_sum = nmasslessnu cdef unsigned int i for i in range(N): rel_mass_sum += pow(1.0 + (k * nu_y[i])**1.83, 0.54644808743) return 0.22710731766 * NeffPerNu * rel_mass_sum ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.0952451 astropy-5.0.2/astropy/cosmology/tests/0000755000175100001710000000000000000000000017123 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/tests/__init__.py0000644000175100001710000000020400000000000021230 0ustar00vstsdockerimport os import sys sys.path.insert(0, os.path.dirname(__file__)) # allows import of "mypackage" # isort split import mypackage ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/tests/conftest.py0000644000175100001710000000610600000000000021325 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """Configure the tests for :mod:`astropy.cosmology`.""" ############################################################################## # IMPORTS # STDLIB import json import os import pytest import astropy.cosmology.units as cu import astropy.units as u from astropy.cosmology import core from astropy.cosmology.core import Cosmology from astropy.utils.misc import isiterable ############################################################################### # FUNCTIONS def read_json(filename, **kwargs): """Read JSON. Parameters ---------- filename : str **kwargs Keyword arguments into :meth:`~astropy.cosmology.Cosmology.from_format` Returns ------- `~astropy.cosmology.Cosmology` instance """ # read if isinstance(filename, (str, bytes, os.PathLike)): with open(filename, "r") as file: data = file.read() else: # file-like : this also handles errors in dumping data = filename.read() mapping = json.loads(data) # parse json mappable to dict # deserialize Quantity with u.add_enabled_units(cu.redshift): for k, v in mapping.items(): if isinstance(v, dict) and "value" in v and "unit" in v: mapping[k] = u.Quantity(v["value"], v["unit"]) for k, v in mapping.get("meta", {}).items(): # also the metadata if isinstance(v, dict) and "value" in v and "unit" in v: mapping["meta"][k] = u.Quantity(v["value"], v["unit"]) return Cosmology.from_format(mapping, **kwargs) def write_json(cosmology, file, *, overwrite=False): """Write Cosmology to JSON. Parameters ---------- cosmology : `astropy.cosmology.Cosmology` subclass instance file : path-like or file-like overwrite : bool (optional, keyword-only) """ data = cosmology.to_format("mapping") # start by turning into dict data["cosmology"] = data["cosmology"].__qualname__ # serialize Quantity for k, v in data.items(): if isinstance(v, u.Quantity): data[k] = {"value": v.value.tolist(), "unit": str(v.unit)} for k, v in data.get("meta", {}).items(): # also serialize the metadata if isinstance(v, u.Quantity): data["meta"][k] = {"value": v.value.tolist(), "unit": str(v.unit)} # check that file exists and whether to overwrite. if os.path.exists(file) and not overwrite: raise IOError(f"{file} exists. Set 'overwrite' to write over.") with open(file, "w") as write_file: json.dump(data, write_file) def json_identify(origin, filepath, fileobj, *args, **kwargs): return filepath is not None and filepath.endswith(".json") ############################################################################### # FIXTURES @pytest.fixture def clean_registry(): # TODO! with monkeypatch instead for thread safety. ORIGINAL_COSMOLOGY_CLASSES = core._COSMOLOGY_CLASSES core._COSMOLOGY_CLASSES = {} # set as empty dict yield core._COSMOLOGY_CLASSES core._COSMOLOGY_CLASSES = ORIGINAL_COSMOLOGY_CLASSES ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.0952451 astropy-5.0.2/astropy/cosmology/tests/mypackage/0000755000175100001710000000000000000000000021064 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/tests/mypackage/__init__.py0000644000175100001710000000003400000000000023172 0ustar00vstsdockerfrom . import cosmology, io ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/tests/mypackage/cosmology.py0000644000175100001710000000246600000000000023461 0ustar00vstsdocker# -*- coding: utf-8 -*- """Cosmology classes and instances for package ``mypackage``.""" # STDLIB from collections import UserDict # THIRD PARTY import numpy as np class MyCosmology(UserDict): """Cosmology, from ``mypackage``. Parameters ---------- **kw values for `MyCosmology`. """ def __init__(self, **kw): super().__init__() self.update(kw) def __getattr__(self, key): """Get attributes like items.""" if key in self: return self[key] super().__getattribute__(key) def age_in_Gyr(z): """Cosmology age in Gyr. Returns `NotImplemented`.""" return NotImplemented def __eq__(self, other): """Equality check.""" if not isinstance(other, MyCosmology): return NotImplemented return all(np.all(v == other[k]) for k, v in self.items()) myplanck = MyCosmology( name="planck", hubble_parameter=67.66, # km/s/Mpc initial_dm_density=0.2607, # X/rho_critical initial_baryon_density=0.04897, # X/rho_critical initial_matter_density=0.30966, # X/rho_critical n=0.9665, sigma8=0.8102, z_reionization=7.82, # redshift current_age=13.787, # Gyr initial_temperature=2.7255, # Kelvin Neff=3.046, neutrino_masses=[0., 0., 0.06], # eV ) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.0952451 astropy-5.0.2/astropy/cosmology/tests/mypackage/io/0000755000175100001710000000000000000000000021473 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/tests/mypackage/io/__init__.py0000644000175100001710000000144500000000000023610 0ustar00vstsdocker# -*- coding: utf-8 -*- """ Readers, Writers, and I/O Miscellany. """ __all__ = ["file_reader", "file_writer"] # from `mypackage` # e.g. a file reader and writer for ``myformat`` # this will be used in ``astropy_io.py`` from .core import file_reader, file_writer # Register read and write methods into Astropy: # determine if it is 1) installed and 2) the correct version (v5.0+) try: import astropy from astropy.utils.introspection import minversion except ImportError: ASTROPY_GE_5 = False else: ASTROPY_GE_5 = minversion(astropy, "5.0") if ASTROPY_GE_5: # Astropy is installed and v5.0+ so we import the following modules # to register "myformat" with Cosmology read/write and "mypackage" # with Cosmology to/from_format. from . import astropy_convert, astropy_io ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/tests/mypackage/io/astropy_convert.py0000644000175100001710000001051000000000000025303 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see Astropy LICENSE.rst """ Register conversion methods for cosmology objects with Astropy Cosmology. With this registered, we can start with a Cosmology from ``mypackage`` and convert it to an astropy Cosmology instance. >>> from mypackage.cosmology import myplanck >>> from astropy.cosmology import Cosmology >>> cosmo = Cosmology.from_format(myplanck, format="mypackage") >>> cosmo We can also do the reverse: start with an astropy Cosmology and convert it to a ``mypackage`` object. >>> from astropy.cosmology import Planck18 >>> myplanck = Planck18.to_format("mypackage") >>> myplanck """ # THIRD PARTY import astropy.cosmology.units as cu import astropy.units as u from astropy.cosmology import FLRW, Cosmology, FlatLambdaCDM from astropy.cosmology.connect import convert_registry # LOCAL from mypackage.cosmology import MyCosmology __doctest_skip__ = ['*'] def from_mypackage(mycosmo): """Load `~astropy.cosmology.Cosmology` from ``mypackage`` object. Parameters ---------- mycosmo : `~mypackage.cosmology.MyCosmology` Returns ------- `~astropy.cosmology.Cosmology` """ m = dict(mycosmo) m["name"] = mycosmo.name # ---------------- # remap Parameters m["H0"] = m.pop("hubble_parameter") * (u.km / u.s / u.Mpc) m["Om0"] = m.pop("initial_matter_density") m["Tcmb0"] = m.pop("initial_temperature") * u.K # m["Neff"] = m.pop("Neff") # skip b/c unchanged m["m_nu"] = m.pop("neutrino_masses") * u.eV m["Ob0"] = m.pop("initial_baryon_density") # ---------------- # remap metadata m["t0"] = m.pop("current_age") * u.Gyr # optional if "reionization_redshift" in m: m["z_reion"] = m.pop("reionization_redshift") # ... # keep building `m` # ---------------- # Detect which type of Astropy cosmology to build. # TODO! CUSTOMIZE FOR DETECTION # Here we just force FlatLambdaCDM, but if your package allows for # non-flat cosmologies... m["cosmology"] = FlatLambdaCDM # build cosmology return Cosmology.from_format(m, format="mapping", move_to_meta=True) def to_mypackage(cosmology, *args): """Return the cosmology as a ``mycosmo``. Parameters ---------- cosmology : `~astropy.cosmology.Cosmology` Returns ------- `~mypackage.cosmology.MyCosmology` """ if not isinstance(cosmology, FLRW): raise TypeError("format 'mypackage' only supports FLRW cosmologies.") # ---------------- # Cosmology provides a nice method "mapping", so all that needs to # be done here is initialize from the dictionary m = cosmology.to_format("mapping") # Detect which type of MyCosmology to build. # Here we have forced FlatLambdaCDM, but if your package allows for # non-flat cosmologies... m.pop("cosmology") # MyCosmology doesn't support metadata. If your cosmology class does... meta = m.pop("meta") m = {**meta, **m} # merge, preferring current values # ---------------- # remap values # MyCosmology doesn't support units, so take values. m["hubble_parameter"] = m.pop("H0").to_value(u.km/u.s/u.Mpc) m["initial_matter_density"] = m.pop("Om0") m["initial_temperature"] = m.pop("Tcmb0").to_value(u.K) # m["Neff"] = m.pop("Neff") # skip b/c unchanged m["neutrino_masses"] = m.pop("m_nu").to_value(u.eV) m["initial_baryon_density"] = m.pop("Ob0") m["current_age"] = m.pop("t0", cosmology.age(0 * cu.redshift)).to_value(u.Gyr) # optional if "z_reion" in m: m["reionization_redshift"] = (m.pop("z_reion") << cu.redshift).value # ... # keep remapping return MyCosmology(**m) def mypackage_identify(origin, format, *args, **kwargs): """Identify if object uses format "mypackage".""" itis = False if origin == "read": itis = isinstance(args[1], MyCosmology) and (format in (None, "mypackage")) return itis # ------------------------------------------------------------------- # Register to/from_format & identify methods with Astropy Unified I/O convert_registry.register_reader("mypackage", Cosmology, from_mypackage, force=True) convert_registry.register_writer("mypackage", Cosmology, to_mypackage, force=True) convert_registry.register_identifier("mypackage", Cosmology, mypackage_identify, force=True) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/tests/mypackage/io/astropy_io.py0000644000175100001710000000525100000000000024240 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see Astropy LICENSE.rst """ Register Read/Write methods for "myformat" (JSON) with Astropy Cosmology. With this format registered, we can start with a Cosmology from ``mypackage``, write it to a file, and read it with Astropy to create an astropy Cosmology instance. >>> from mypackage.cosmology import myplanck >>> from mypackage.io import file_writer >>> file_writer('', myplanck) >>> from astropy.cosmology import Cosmology >>> cosmo = Cosmology.read('', format="myformat") >>> cosmo We can also do the reverse: start with an astropy Cosmology, save it and read it with ``mypackage``. >>> from astropy.cosmology import Planck18 >>> Planck18.write('', format="myformat") >>> from mypackage.io import file_reader >>> cosmo2 = file_reader('') >>> cosmo2 """ # STDLIB import json import os # THIRD PARTY import astropy.units as u from astropy.cosmology import Cosmology from astropy.cosmology.connect import readwrite_registry # LOCAL from .core import file_reader, file_writer __doctest_skip__ = ['*'] def read_myformat(filename, **kwargs): """Read files in format 'myformat'. Parameters ---------- filename : str **kwargs Keyword arguments into `astropy.cosmology.Cosmology.from_format` with ``format="mypackage"``. Returns ------- `~mypackage.cosmology.MyCosmology` instance """ mycosmo = file_reader(filename) # ← read file ↓ build Cosmology return Cosmology.from_format(mycosmo, format="mypackage", **kwargs) def write_myformat(cosmology, file, *, overwrite=False): """Write files in format 'myformat'. Parameters ---------- cosmology : `~astropy.cosmology.Cosmology` instance file : str, bytes, or `~os.PathLike` overwrite : bool (optional, keyword-only) Whether to overwrite an existing file. Default is False. """ cosmo = cosmology.to_format("mypackage") # ← convert Cosmology ↓ write file file_writer(file, cosmo, overwrite=overwrite) def myformat_identify(origin, filepath, fileobj, *args, **kwargs): """Identify if object uses ``myformat`` (JSON).""" return filepath is not None and filepath.endswith(".myformat") # ------------------------------------------------------------------- # Register read/write/identify methods with Astropy Unified I/O readwrite_registry.register_reader("myformat", Cosmology, read_myformat, force=True) readwrite_registry.register_writer("myformat", Cosmology, write_myformat, force=True) readwrite_registry.register_identifier("myformat", Cosmology, myformat_identify, force=True) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/tests/mypackage/io/core.py0000644000175100001710000000330300000000000022774 0ustar00vstsdocker# -*- coding: utf-8 -*- # STDLIB import json import os # THIRD PARTY import numpy as np # LOCAL from mypackage.cosmology import MyCosmology def file_reader(filename): """Read files in format 'myformat'. Parameters ---------- filename : str, bytes, or `~os.PathLike` Returns ------- `~mypackage.cosmology.MyCosmology` instance """ # read if isinstance(filename, (str, bytes, os.PathLike)): with open(filename, "r") as file: data = file.read() else: # file-like : this also handles errors in dumping data = filename.read() mapping = json.loads(data) # parse json mappable to dict # deserialize list to ndarray for k, v in mapping.items(): if isinstance(v, list): mapping[k] = np.array(v) return MyCosmology(**mapping) def file_writer(file, cosmo, overwrite=False): """Write files in format 'myformat'. Parameters ---------- file : str, bytes, `~os.PathLike`, or file-like cosmo : `~mypackage.cosmology.MyCosmology` instance overwrite : bool (optional, keyword-only) Whether to overwrite an existing file. Default is False. """ output = dict(cosmo) # serialize ndarray for k, v in output.items(): if isinstance(v, np.ndarray): output[k] = v.tolist() # write if isinstance(file, (str, bytes, os.PathLike)): # check that file exists and whether to overwrite. if os.path.exists(file) and not overwrite: raise IOError(f"{file} exists. Set 'overwrite' to write over.") with open(file, "w") as write_file: json.dump(output, write_file) else: # file-like json.dump(output, file) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.0952451 astropy-5.0.2/astropy/cosmology/tests/mypackage/io/tests/0000755000175100001710000000000000000000000022635 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/tests/mypackage/io/tests/__init__.py0000644000175100001710000000000000000000000024734 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/tests/mypackage/io/tests/conftest.py0000644000175100001710000000155200000000000025037 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst # THIRD PARTY import pytest # LOCAL from mypackage.io import ASTROPY_GE_5 @pytest.fixture(scope="session", autouse=True) def teardown_mypackage(): """Clean up module after tests.""" yield # to let all tests within the scope run if ASTROPY_GE_5: from astropy.cosmology import Cosmology from astropy.cosmology.connect import convert_registry, readwrite_registry readwrite_registry.unregister_reader("myformat", Cosmology) readwrite_registry.unregister_writer("myformat", Cosmology) readwrite_registry.unregister_identifier("myformat", Cosmology) convert_registry.unregister_reader("mypackage", Cosmology) convert_registry.unregister_writer("mypackage", Cosmology) convert_registry.unregister_identifier("mypackage", Cosmology) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/tests/mypackage/io/tests/test_astropy_convert.py0000644000175100001710000000516400000000000027515 0ustar00vstsdocker# -*- coding: utf-8 -*- """ Test that the conversion interface with Astropy works as expected. """ # STDLIB import os # THIRD PARTY import pytest # LOCAL from mypackage.cosmology import MyCosmology, myplanck # skip all tests in module if import is missing astropy = pytest.importorskip("astropy", minversion="4.3") # isort: skip # can now import freely from astropy from astropy import cosmology from astropy.cosmology import Cosmology from astropy.io import registry as io_registry from astropy.utils.compat.optional_deps import HAS_SCIPY # cosmology instances to test reading and writing astropy_cosmos = [ getattr(cosmology.realizations, n) for n in cosmology.parameters.available ] mypackage_cosmos = [myplanck] # list of ``mypackage`` cosmology realizations @pytest.mark.skipif(not HAS_SCIPY, reason="test requires scipy.") class TestAstropyCosmologyConvert: """Test conversion to/from Astropy.""" @pytest.mark.parametrize("expected", astropy_cosmos) def test_roundtrip_from_astropy(self, expected): # convert to ``mypackage`` mycosmo = expected.to_format("mypackage") # Read back got = Cosmology.from_format(mycosmo, format="mypackage") # test round-tripped as expected assert got == expected # tests immutable parameters, e.g. H0 # NOTE: if your package's cosmology supports metadata # assert got.meta == expected.meta # (metadata not tested above) @pytest.mark.parametrize("expected", mypackage_cosmos) def test_roundtrip_from_mypackage(self, expected): # convert to Astropy acosmo = Cosmology.from_format(expected, format="mypackage") # convert back to ``mypackage``` got = acosmo.to_format("mypackage") # test round-tripped as expected assert isinstance(got, MyCosmology) assert got == expected # assuming ``MyCosmology`` has an __eq__ method ... # more equality tests @pytest.mark.parametrize("acosmo", astropy_cosmos) def test_package_equality(self, acosmo): """ The most important test: are the ``mypackage`` and ``astropy`` cosmologies equivalent!? They should be if read from the same source file. """ # convert to ``mypacakge`` mycosmo = acosmo.to_format("mypackage") # ------------ # test that the mypackage and astropy cosmologies are equivalent assert mycosmo.name == acosmo.name assert mycosmo.hubble_parameter == acosmo.H0.value ... # continue with the tests # e.g. test some methods # assert mycosmo.age_in_Gyr(1100) == acosmo.age(1100).to_value(u.Gyr) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/tests/mypackage/io/tests/test_astropy_io.py0000644000175100001710000000622700000000000026445 0ustar00vstsdocker# -*- coding: utf-8 -*- """ Test that the interface with Astropy works as expected. """ # STDLIB import os # THIRD PARTY import pytest # LOCAL from mypackage.cosmology import myplanck from mypackage.io import file_reader # skip all tests in module if import is missing astropy = pytest.importorskip("astropy", minversion="4.3") # isort: skip # can now import freely from astropy import astropy.units as u from astropy import cosmology from astropy.cosmology import Cosmology from astropy.io import registry as io_registry from astropy.utils.compat.optional_deps import HAS_SCIPY # the formats being registered with Astropy readwrite_formats = ["myformat"] # cosmology instances to test reading and writing astropy_cosmos = cosmology.parameters.available # list of ``mypackage`` cosmology realizations mypackage_cosmos = [myplanck] @pytest.mark.skipif(not HAS_SCIPY, reason="test requires scipy.") class TestAstropyCosmologyIO: """Test read/write interoperability with Astropy.""" @pytest.mark.parametrize("format", readwrite_formats) @pytest.mark.parametrize("instance", astropy_cosmos) def test_roundtrip_from_astropy(self, tmp_path, instance, format): cosmo = getattr(cosmology.realizations, instance) fname = tmp_path / f"{instance}.{format}" # write to file cosmo.write(str(fname), format=format) # also test kwarg "overwrite" assert os.path.exists(str(fname)) # file exists with pytest.raises(IOError): cosmo.write(str(fname), format=format, overwrite=False) assert os.path.exists(str(fname)) # overwrite file existing file cosmo.write(str(fname), format=format, overwrite=True) # Read back got = Cosmology.read(fname, format=format) # test round-tripped as expected assert got == cosmo # tests immutable parameters, e.g. H0 # NOTE: if your package's cosmology supports metadata # assert got.meta == expected.meta # (metadata not tested above) @pytest.mark.parametrize("format", readwrite_formats) @pytest.mark.parametrize("instance", astropy_cosmos) def test_package_equality(self, tmp_path, instance, format): """ The most important test: are the ``mypackage`` and ``astropy`` cosmologies equivalent!? They should be if read from the same source file. """ original = getattr(cosmology.realizations, instance) fname = tmp_path / f"{instance}.{format}" # write with Astropy original.write(str(fname), format=format) # Read back with ``myformat`` cosmo = file_reader(str(fname)) # read to instance from mypackage # and a read comparison from Astropy cosmo2 = cosmology.Cosmology.read(str(fname), format=format) # ------------ # test that the mypackage and astropy cosmologies are equivalent assert original.H0.value == cosmo.hubble_parameter assert cosmo2.H0.value == cosmo.hubble_parameter ... # continue with the tests # e.g. test some methods # assert original.age(1100).to_value(u.Gyr) == cosmo.age_in_Gyr(1100) # assert cosmo2.age(1100) == cosmo.age(1100) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/tests/test_connect.py0000644000175100001710000002563500000000000022200 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import copy import inspect import os import pytest from astropy import cosmology from astropy.cosmology import Cosmology, w0wzCDM from astropy.cosmology.connect import CosmologyRead, readwrite_registry from astropy.cosmology.core import Cosmology from astropy.cosmology.io.tests import test_ecsv, test_mapping, test_model, test_table from astropy.table import QTable from .conftest import json_identify, read_json, write_json ############################################################################### # SETUP cosmo_instances = cosmology.parameters.available readwrite_formats = ["json"] tofrom_formats = [("mapping", dict), ("astropy.table", QTable)] # (format, data type) ############################################################################### class ReadWriteTestMixin: """ Tests for a CosmologyRead/Write on a |Cosmology|. This class will not be directly called by :mod:`pytest` since its name does not begin with ``Test``. To activate the contained tests this class must be inherited in a subclass. Subclasses must define a :func:`pytest.fixture` ``cosmo`` that returns/yields an instance of a |Cosmology|. See ``TestReadWriteCosmology`` or ``TestCosmology`` for examples. """ @pytest.fixture(scope="class", autouse=True) def setup_readwrite(self): """Setup & teardown for read/write tests.""" # register readwrite_registry.register_reader("json", Cosmology, read_json, force=True) readwrite_registry.register_writer("json", Cosmology, write_json, force=True) readwrite_registry.register_identifier("json", Cosmology, json_identify, force=True) yield # run all tests in class # unregister readwrite_registry.unregister_reader("json", Cosmology) readwrite_registry.unregister_writer("json", Cosmology) readwrite_registry.unregister_identifier("json", Cosmology) # =============================================================== # Method & Attribute Tests @pytest.mark.parametrize("format", readwrite_formats) def test_readwrite_complete_info(self, cosmo, tmpdir, format): """ Test writing from an instance and reading from the base class. This requires full information. """ fname = tmpdir / f"{cosmo.name}.{format}" cosmo.write(str(fname), format=format) # Also test kwarg "overwrite" assert os.path.exists(str(fname)) # file exists with pytest.raises(IOError): cosmo.write(str(fname), format=format, overwrite=False) assert os.path.exists(str(fname)) # overwrite file existing file cosmo.write(str(fname), format=format, overwrite=True) # Read back got = Cosmology.read(fname, format=format) assert got == cosmo assert got.meta == cosmo.meta @pytest.mark.parametrize("format", readwrite_formats) def test_readwrite_from_subclass_complete_info(self, cosmo, tmpdir, format): """ Test writing from an instance and reading from that class, when there's full information saved. """ fname = tmpdir / f"{cosmo.name}.{format}" cosmo.write(str(fname), format=format) # read with the same class that wrote. got = cosmo.__class__.read(fname, format=format) assert got == cosmo assert got.meta == cosmo.meta # this should be equivalent to got = Cosmology.read(fname, format=format, cosmology=cosmo.__class__) assert got == cosmo assert got.meta == cosmo.meta # and also got = Cosmology.read(fname, format=format, cosmology=cosmo.__class__.__qualname__) assert got == cosmo assert got.meta == cosmo.meta @pytest.mark.skip("TODO: generalize over all save formats for this test.") def test_readwrite_from_subclass_partial_info(self, cosmo, tmpdir): """ Test writing from an instance and reading from that class. This requires partial information. .. todo:: - generalize over all save formats for this test. - remove the method defined in subclass """ class TestCosmologyReadWrite(ReadWriteTestMixin): """Test the classes CosmologyRead/Write.""" @pytest.fixture(params=cosmo_instances) def cosmo(self, request): return getattr(cosmology.realizations, request.param) # ============================================================== @pytest.mark.parametrize("format", readwrite_formats) def test_write_methods_have_explicit_kwarg_overwrite(self, format): writer = readwrite_registry.get_writer(format, Cosmology) # test in signature sig = inspect.signature(writer) assert "overwrite" in sig.parameters # also in docstring assert "overwrite : bool" in writer.__doc__ # @pytest.mark.parametrize("format", readwrite_formats) @pytest.mark.parametrize("instance", cosmo_instances) def test_readwrite_from_subclass_partial_info(self, instance, tmpdir): """ Test writing from an instance and reading from that class. This requires partial information. .. todo:: remove when fix method in super """ cosmo = getattr(cosmology.realizations, instance) format = "json" fname = tmpdir / f"{cosmo.name}.{format}" cosmo.write(str(fname), format=format) # partial information with open(fname, "r") as file: L = file.readlines()[0] L = L[: L.index('"cosmology":')] + L[L.index(", ") + 2 :] # remove cosmology i = L.index('"Tcmb0":') # delete Tcmb0 L = L[:i] + L[L.index(", ", L.index(", ", i) + 1) + 2 :] # second occurence tempfname = tmpdir / f"{cosmo.name}_temp.{format}" with open(tempfname, "w") as file: file.writelines([L]) # read with the same class that wrote fills in the missing info with # the default value got = cosmo.__class__.read(tempfname, format=format) got2 = Cosmology.read(tempfname, format=format, cosmology=cosmo.__class__) got3 = Cosmology.read(tempfname, format=format, cosmology=cosmo.__class__.__qualname__) assert (got == got2) and (got2 == got3) # internal consistency # not equal, because Tcmb0 is changed assert got != cosmo assert got.Tcmb0 == cosmo.__class__._init_signature.parameters["Tcmb0"].default assert got.clone(name=cosmo.name, Tcmb0=cosmo.Tcmb0) == cosmo # but the metadata is the same assert got.meta == cosmo.meta @pytest.mark.parametrize("format", readwrite_formats) def test_readwrite_reader_class_mismatch(self, cosmo, tmpdir, format): """Test when the reader class doesn't match the file.""" fname = tmpdir / f"{cosmo.name}.{format}" cosmo.write(str(fname), format=format) # class mismatch # when reading directly with pytest.raises(TypeError, match="missing 1 required"): w0wzCDM.read(fname, format=format) with pytest.raises(TypeError, match="missing 1 required"): Cosmology.read(fname, format=format, cosmology=w0wzCDM) # when specifying the class with pytest.raises(ValueError, match="`cosmology` must be either"): w0wzCDM.read(fname, format=format, cosmology="FlatLambdaCDM") ############################################################################### # To/From_Format Tests class ToFromFormatTestMixin( # convert test_mapping.ToFromMappingTestMixin, test_model.ToFromModelTestMixin, test_table.ToFromTableTestMixin, # read/write test_ecsv.ReadWriteECSVTestMixin, ): """ Tests for a Cosmology[To/From]Format on a |Cosmology|. This class will not be directly called by :mod:`pytest` since its name does not begin with ``Test``. To activate the contained tests this class must be inherited in a subclass. Subclasses must define a :func:`pytest.fixture` ``cosmo`` that returns/yields an instance of a |Cosmology|. See ``TestCosmology`` for an example. """ @pytest.mark.parametrize("format_type", tofrom_formats) def test_tofromformat_complete_info(self, cosmo, format_type): """Read tests happen later.""" format, objtype = format_type # test to_format obj = cosmo.to_format(format) assert isinstance(obj, objtype) # test from_format got = Cosmology.from_format(obj, format=format) # and autodetect got2 = Cosmology.from_format(obj) assert got2 == got # internal consistency assert got == cosmo # external consistency assert got.meta == cosmo.meta @pytest.mark.parametrize("format_type", tofrom_formats) def test_fromformat_subclass_complete_info(self, cosmo, format_type): """ Test transforming an instance and parsing from that class, when there's full information available. Partial information tests are handled in the Mixin super classes. """ format, objtype = format_type # test to_format obj = cosmo.to_format(format) assert isinstance(obj, objtype) # read with the same class that wrote. got = cosmo.__class__.from_format(obj, format=format) got2 = Cosmology.from_format(obj) # and autodetect assert got2 == got # internal consistency assert got == cosmo # external consistency assert got.meta == cosmo.meta # this should be equivalent to got = Cosmology.from_format(obj, format=format, cosmology=cosmo.__class__) assert got == cosmo assert got.meta == cosmo.meta # and also got = Cosmology.from_format(obj, format=format, cosmology=cosmo.__class__.__qualname__) assert got == cosmo assert got.meta == cosmo.meta class TestCosmologyToFromFormat(ToFromFormatTestMixin): """Test Cosmology[To/From]Format classes.""" @pytest.fixture(params=cosmo_instances) def cosmo(self, request): return getattr(cosmology.realizations, request.param) @pytest.fixture def cosmo_cls(self, cosmo): return cosmo.__class__ # ============================================================== @pytest.mark.parametrize("format_type", tofrom_formats) def test_fromformat_class_mismatch(self, cosmo, format_type): format, objtype = format_type # test to_format obj = cosmo.to_format(format) assert isinstance(obj, objtype) # class mismatch with pytest.raises(TypeError, match="missing 1 required"): w0wzCDM.from_format(obj, format=format) with pytest.raises(TypeError, match="missing 1 required"): Cosmology.from_format(obj, format=format, cosmology=w0wzCDM) # when specifying the class with pytest.raises(ValueError, match="`cosmology` must be either"): w0wzCDM.from_format(obj, format=format, cosmology="FlatLambdaCDM") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/tests/test_core.py0000644000175100001710000002631100000000000021467 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """Testing :mod:`astropy.cosmology.core`.""" ############################################################################## # IMPORTS # STDLIB import abc import inspect from types import MappingProxyType # THIRD PARTY import pytest import numpy as np # LOCAL import astropy.units as u from astropy.cosmology import Cosmology, core from astropy.cosmology.core import _COSMOLOGY_CLASSES from astropy.cosmology.parameter import Parameter from astropy.table import QTable, Table from astropy.utils.metadata import MetaData from .test_connect import ReadWriteTestMixin, ToFromFormatTestMixin from .test_parameter import ParameterTestMixin ############################################################################## # TESTS ############################################################################## class MetaTestMixin: """Tests for a :class:`astropy.utils.metadata.MetaData` on a Cosmology.""" def test_meta_on_class(self, cosmo_cls): assert isinstance(cosmo_cls.meta, MetaData) def test_meta_on_instance(self, cosmo): assert isinstance(cosmo.meta, dict) class TestCosmology(ParameterTestMixin, MetaTestMixin, ReadWriteTestMixin, ToFromFormatTestMixin, metaclass=abc.ABCMeta): """Test :class:`astropy.cosmology.Cosmology`. Subclasses should define tests for: - ``.test_clone_change_param()`` - ``test_repr()`` """ def setup_class(self): """ Setup for testing. Cosmology should not be instantiated, so tests are done on a subclass. """ class SubCosmology(Cosmology): H0 = Parameter(unit=u.km / u.s / u.Mpc) Tcmb0 = Parameter(unit=u.K) def __init__(self, H0, Tcmb0=0*u.K, name=None, meta=None): super().__init__(name=name, meta=meta) self._H0 = H0 self._Tcmb0 = Tcmb0 self.cls = SubCosmology self.cls_args = (70 * (u.km / u.s / u.Mpc), 2.7 * u.K) self.cls_kwargs = dict(name=self.__class__.__name__, meta={"a": "b"}) def teardown_class(self): _COSMOLOGY_CLASSES.pop("TestCosmology.setup_class..SubCosmology", None) @pytest.fixture def cosmo_cls(self): return self.cls @pytest.fixture def cosmo(self): """The cosmology instance with which to test.""" return self.cls(*self.cls_args, **self.cls_kwargs) # =============================================================== # Method & Attribute Tests # --------------------------------------------------------------- # class-level def test_init_subclass(self, cosmo_cls): """Test creating subclasses registers classes and manages Parameters.""" class InitSubclassTest(cosmo_cls): pass # test parameters assert InitSubclassTest.__parameters__ == cosmo_cls.__parameters__ # test and cleanup registry registrant = _COSMOLOGY_CLASSES.pop(InitSubclassTest.__qualname__) assert registrant is InitSubclassTest def test_init_signature(self, cosmo_cls, cosmo): """Test class-property ``_init_signature``.""" # test presence assert hasattr(cosmo_cls, "_init_signature") assert hasattr(cosmo, "_init_signature") # test internal consistency, so following tests can use either cls or instance. assert cosmo_cls._init_signature == cosmo._init_signature # test matches __init__, but without 'self' sig = inspect.signature(cosmo.__init__) # (instances don't have self) assert set(sig.parameters.keys()) == set(cosmo._init_signature.parameters.keys()) assert all(np.all(sig.parameters[k].default == p.default) for k, p in cosmo._init_signature.parameters.items()) # --------------------------------------------------------------- # instance-level def test_new(self, cosmo_cls): """Test method ``__new__``""" # before calling new assert hasattr(cosmo_cls, "_init_signature") # actually a class property assert not hasattr(cosmo_cls, "_init_arguments") # after calling new (doing this in a way that doesn't call __init__) c = cosmo_cls.__new__(cosmo_cls) assert isinstance(c, cosmo_cls) assert hasattr(c, "_init_arguments") assert isinstance(c._init_arguments, dict) assert c._init_arguments["name"] == None assert c._init_arguments["meta"] == None # do again, but with arguments. don't need to repeat all tests c = cosmo_cls.__new__(cosmo_cls, name="test", meta=dict(a=1)) assert c._init_arguments["name"] == "test" assert c._init_arguments["meta"] == dict(a=1) def test_init(self, cosmo_cls): """Test initialization.""" # Cosmology only does name and meta, but this subclass adds H0 & Tcmb0. cosmo = cosmo_cls(*self.cls_args, name="test_init", meta={"m": 1}) assert cosmo.name == "test_init" assert cosmo.meta["m"] == 1 # if meta is None, it is changed to a dict cosmo = cosmo_cls(*self.cls_args, name="test_init", meta=None) assert cosmo.meta == {} def test_name(self, cosmo): """Test property ``name``.""" assert cosmo.name is cosmo._name # accesses private attribute assert cosmo.name is None or isinstance(cosmo.name, str) # type assert cosmo.name == self.cls_kwargs["name"] # test has expected value # ------------------------------------------------ # clone def test_clone_identical(self, cosmo): """Test method ``.clone()`` if no (kw)args.""" assert cosmo.clone() is cosmo def test_clone_name(self, cosmo): """Test method ``.clone()`` name argument.""" # test changing name. clone treats 'name' differently (see next test) c = cosmo.clone(name="cloned cosmo") assert c.name == "cloned cosmo" # changed # show name is the only thing changed c._name = cosmo.name # first change name back assert c == cosmo assert c.meta == cosmo.meta # now change a different parameter and see how 'name' changes c = cosmo.clone(meta={}) assert c.name == cosmo.name + " (modified)" def test_clone_meta(self, cosmo): """Test method ``.clone()`` meta argument: updates meta, doesn't clear.""" # start with no change c = cosmo.clone(meta=None) assert c.meta == cosmo.meta # add something c = cosmo.clone(meta=dict(test_clone_meta=True)) assert c.meta["test_clone_meta"] is True c.meta.pop("test_clone_meta") # remove from meta assert c.meta == cosmo.meta # now they match def test_clone_change_param(self, cosmo): """ Test method ``.clone()`` changing a(many) Parameter(s). Nothing here b/c no Parameters. """ pass def test_clone_fail_unexpected_arg(self, cosmo): """Test when ``.clone()`` gets an unexpected argument.""" with pytest.raises(TypeError, match="unexpected keyword argument"): newclone = cosmo.clone(not_an_arg=4) def test_clone_fail_positional_arg(self, cosmo): with pytest.raises(TypeError, match="1 positional argument"): cosmo.clone(None) # --------------------------------------------------------------- # comparison methods def test_is_equivalent(self, cosmo): """Test :meth:`astropy.cosmology.Cosmology.is_equivalent`.""" # to self assert cosmo.is_equivalent(cosmo) # same class, different instance newclone = cosmo.clone(name="test_is_equivalent") assert cosmo.is_equivalent(newclone) assert newclone.is_equivalent(cosmo) # different class assert not cosmo.is_equivalent(2) def test_equality(self, cosmo): """Test method ``.__eq__().""" # wrong class assert (cosmo != 2) and (2 != cosmo) # correct assert cosmo == cosmo # different name <= not equal, but equivalent assert cosmo != cosmo.clone(name="test_equality") assert cosmo.__equiv__(cosmo.clone(name="test_equality")) # --------------------------------------------------------------- def test_repr(self, cosmo_cls, cosmo): """Test method ``.__repr__()``. This is a very general test and it is probably good to have a hard-coded comparison. """ r = repr(cosmo) # class in string rep assert cosmo_cls.__qualname__ in r assert r.index(cosmo_cls.__qualname__) == 0 # it's the first thing r = r[len(cosmo_cls.__qualname__) + 1:] # remove # name in string rep if cosmo.name is not None: assert f"name=\"{cosmo.name}\"" in r assert r.index("name=") == 0 r = r[6 + len(cosmo.name) + 3:] # remove # parameters in string rep ps = {k: getattr(cosmo, k) for k in cosmo.__parameters__} cps = {k: getattr(cosmo_cls, k) for k in cosmo.__parameters__} for k, v in ps.items(): sv = format(v, cps[k].format_spec if v is not None else '') assert (k + '=' + sv) in r assert r.index(k) == 0 r = r[len((k + '=' + sv)) + 2:] # remove # ------------------------------------------------ @pytest.mark.parametrize("in_meta", [True, False]) @pytest.mark.parametrize("table_cls", [Table, QTable]) def test_astropy_table(self, cosmo, table_cls, in_meta): """Test ``astropy.table.Table(cosmology)``.""" tbl = table_cls(cosmo, cosmology_in_meta=in_meta) assert isinstance(tbl, table_cls) # the name & all parameters are columns for n in ("name", *cosmo.__parameters__): assert n in tbl.colnames assert all(tbl[n] == getattr(cosmo, n)) # check if Cosmology is in metadata or a column if in_meta: assert tbl.meta["cosmology"] == cosmo.__class__.__qualname__ assert "cosmology" not in tbl.colnames else: assert "cosmology" not in tbl.meta assert tbl["cosmology"][0] == cosmo.__class__.__qualname__ # the metadata is transferred for k, v in cosmo.meta.items(): assert np.all(tbl.meta[k] == v) class CosmologySubclassTest(TestCosmology): """ Test subclasses of :class:`astropy.cosmology.Cosmology`. This is broken away from ``TestCosmology``, because |Cosmology| is/will be an ABC and subclasses must override some methods. """ @abc.abstractmethod def setup_class(self): """Setup for testing.""" pass # ----------------------------------------------------------------------------- class FlatCosmologyMixinTest: """Test :class:`astropy.cosmology.core.FlatCosmologyMixin`.""" def test_is_equivalent(self, cosmo): """Test :meth:`astropy.cosmology.core.FlatCosmologyMixin.is_equivalent`. normally this would pass up via super(), but ``__equiv__`` is meant to be overridden, so we skip super(). e.g. FlatFLRWMixinTest -> FlatCosmologyMixinTest -> TestCosmology vs FlatFLRWMixinTest -> FlatCosmologyMixinTest -> TestFLRW -> TestCosmology """ CosmologySubclassTest.test_is_equivalent(self, cosmo) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/tests/test_cosmology.py0000644000175100001710000017403500000000000022561 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst from io import StringIO import pytest import numpy as np import astropy.constants as const import astropy.units as u from astropy.cosmology import Cosmology, flrw, funcs from astropy.cosmology.realizations import Planck13, Planck18, default_cosmology from astropy.units import allclose from astropy.utils.compat.optional_deps import HAS_SCIPY from astropy.utils.exceptions import AstropyDeprecationWarning, AstropyUserWarning def test_flrw_moved_deprecation(): """Test the deprecation warning about the move of FLRW classes.""" with pytest.warns(AstropyDeprecationWarning): from astropy.cosmology.core import FLRW assert FLRW is flrw.FLRW def test_init(): """ Tests to make sure the code refuses inputs it is supposed to""" with pytest.raises(ValueError): cosmo = flrw.FlatLambdaCDM(H0=70, Om0=-0.27) with pytest.raises(ValueError): cosmo = flrw.FlatLambdaCDM(H0=70, Om0=0.27, Neff=-1) with pytest.raises(ValueError): cosmo = flrw.FlatLambdaCDM(H0=70, Om0=0.27, Tcmb0=u.Quantity([0.0, 2], u.K)) with pytest.raises(ValueError): h0bad = u.Quantity([70, 100], u.km / u.s / u.Mpc) cosmo = flrw.FlatLambdaCDM(H0=h0bad, Om0=0.27) with pytest.raises(ValueError): bad_mnu = u.Quantity([-0.3, 0.2, 0.1], u.eV) cosmo = flrw.FlatLambdaCDM(H0=70, Om0=0.2, Tcmb0=3, m_nu=bad_mnu) with pytest.raises(ValueError): bad_mnu = u.Quantity([0.15, 0.2, 0.1], u.eV) cosmo = flrw.FlatLambdaCDM(H0=70, Om0=0.2, Tcmb0=3, Neff=2, m_nu=bad_mnu) with pytest.raises(ValueError): bad_mnu = u.Quantity([-0.3, 0.2], u.eV) # 2, expecting 3 cosmo = flrw.FlatLambdaCDM(H0=70, Om0=0.2, Tcmb0=3, m_nu=bad_mnu) with pytest.raises(ValueError): cosmo = flrw.FlatLambdaCDM(H0=70, Om0=0.27, Ob0=-0.04) with pytest.raises(ValueError): cosmo = flrw.FlatLambdaCDM(H0=70, Om0=0.27, Ob0=0.4) with pytest.raises(ValueError): cosmo = flrw.FlatLambdaCDM(H0=70, Om0=0.27) cosmo.Ob(1) with pytest.raises(ValueError): cosmo = flrw.FlatLambdaCDM(H0=70, Om0=0.27) cosmo.Odm(1) with pytest.raises(TypeError): default_cosmology.validate(4) def test_immutability(): """Test immutability of cosmologies.""" cosmo = flrw.FlatLambdaCDM(70, 0.3) for attr in [*cosmo.__parameters__, "name"]: with pytest.raises(AttributeError): setattr(cosmo, attr, None) # The metadata is NOT immutable assert "a" not in cosmo.meta cosmo.meta["a"] = 1 assert "a" in cosmo.meta def test_basic(): cosmo = flrw.FlatLambdaCDM(H0=70, Om0=0.27, Tcmb0=2.0, Neff=3.04, Ob0=0.05, name="test", meta={"a": "b"}) assert allclose(cosmo.Om0, 0.27) assert allclose(cosmo.Ode0, 0.729975, rtol=1e-4) assert allclose(cosmo.Ob0, 0.05) assert allclose(cosmo.Odm0, 0.27 - 0.05) # This next test will fail if astropy.const starts returning non-mks # units by default; see the comment at the top of core.py assert allclose(cosmo.Ogamma0, 1.463285e-5, rtol=1e-4) assert allclose(cosmo.Onu0, 1.01026e-5, rtol=1e-4) assert allclose(cosmo.Ok0, 0.0) assert allclose(cosmo.Om0 + cosmo.Ode0 + cosmo.Ogamma0 + cosmo.Onu0, 1.0, rtol=1e-6) assert allclose(cosmo.Om(1) + cosmo.Ode(1) + cosmo.Ogamma(1) + cosmo.Onu(1), 1.0, rtol=1e-6) assert allclose(cosmo.Tcmb0, 2.0 * u.K) assert allclose(cosmo.Tnu0, 1.4275317 * u.K, rtol=1e-5) assert allclose(cosmo.Neff, 3.04) assert allclose(cosmo.h, 0.7) assert allclose(cosmo.H0, 70.0 * u.km / u.s / u.Mpc) assert cosmo.name == "test" assert cosmo.meta == {"a": "b"} # Make sure setting them as quantities gives the same results H0 = u.Quantity(70, u.km / (u.s * u.Mpc)) T = u.Quantity(2.0, u.K) cosmo = flrw.FlatLambdaCDM(H0=H0, Om0=0.27, Tcmb0=T, Neff=3.04, Ob0=0.05) assert allclose(cosmo.Om0, 0.27) assert allclose(cosmo.Ode0, 0.729975, rtol=1e-4) assert allclose(cosmo.Ob0, 0.05) assert allclose(cosmo.Odm0, 0.27 - 0.05) assert allclose(cosmo.Ogamma0, 1.463285e-5, rtol=1e-4) assert allclose(cosmo.Onu0, 1.01026e-5, rtol=1e-4) assert allclose(cosmo.Ok0, 0.0) assert allclose(cosmo.Om0 + cosmo.Ode0 + cosmo.Ogamma0 + cosmo.Onu0, 1.0, rtol=1e-6) assert allclose(cosmo.Om(1) + cosmo.Ode(1) + cosmo.Ogamma(1) + cosmo.Onu(1), 1.0, rtol=1e-6) assert allclose(cosmo.Tcmb0, 2.0 * u.K) assert allclose(cosmo.Tnu0, 1.4275317 * u.K, rtol=1e-5) assert allclose(cosmo.Neff, 3.04) assert allclose(cosmo.h, 0.7) assert allclose(cosmo.H0, 70.0 * u.km / u.s / u.Mpc) @pytest.mark.skipif('not HAS_SCIPY') def test_units(): """ Test if the right units are being returned""" cosmo = flrw.FlatLambdaCDM(H0=70, Om0=0.27, Tcmb0=2.0) assert cosmo.comoving_distance(1.0).unit == u.Mpc assert cosmo._comoving_distance_z1z2(1.0, 2.0).unit == u.Mpc assert cosmo.comoving_transverse_distance(1.0).unit == u.Mpc assert cosmo._comoving_transverse_distance_z1z2(1.0, 2.0).unit == u.Mpc assert cosmo.angular_diameter_distance(1.0).unit == u.Mpc assert cosmo.angular_diameter_distance_z1z2(1.0, 2.0).unit == u.Mpc assert cosmo.luminosity_distance(1.0).unit == u.Mpc assert cosmo.lookback_time(1.0).unit == u.Gyr assert cosmo.lookback_distance(1.0).unit == u.Mpc assert cosmo.H0.unit == u.km / u.Mpc / u.s assert cosmo.H(1.0).unit == u.km / u.Mpc / u.s assert cosmo.Tcmb0.unit == u.K assert cosmo.Tcmb(1.0).unit == u.K assert cosmo.Tcmb([0.0, 1.0]).unit == u.K assert cosmo.Tnu0.unit == u.K assert cosmo.Tnu(1.0).unit == u.K assert cosmo.Tnu([0.0, 1.0]).unit == u.K assert cosmo.arcsec_per_kpc_comoving(1.0).unit == u.arcsec / u.kpc assert cosmo.arcsec_per_kpc_proper(1.0).unit == u.arcsec / u.kpc assert cosmo.kpc_comoving_per_arcmin(1.0).unit == u.kpc / u.arcmin assert cosmo.kpc_proper_per_arcmin(1.0).unit == u.kpc / u.arcmin assert cosmo.critical_density(1.0).unit == u.g / u.cm ** 3 assert cosmo.comoving_volume(1.0).unit == u.Mpc ** 3 assert cosmo.age(1.0).unit == u.Gyr assert cosmo.distmod(1.0).unit == u.mag @pytest.mark.skipif('not HAS_SCIPY') def test_distance_broadcast(): """ Test array shape broadcasting for functions with single redshift inputs""" cosmo = flrw.FlatLambdaCDM(H0=70, Om0=0.27, m_nu=u.Quantity([0.0, 0.1, 0.011], u.eV)) z = np.linspace(0.1, 1, 6) z_reshape2d = z.reshape(2, 3) z_reshape3d = z.reshape(3, 2, 1) # Things with units methods = ['comoving_distance', 'luminosity_distance', 'comoving_transverse_distance', 'angular_diameter_distance', 'distmod', 'lookback_time', 'age', 'comoving_volume', 'differential_comoving_volume', 'kpc_comoving_per_arcmin'] for method in methods: g = getattr(cosmo, method) value_flat = g(z) assert value_flat.shape == z.shape value_2d = g(z_reshape2d) assert value_2d.shape == z_reshape2d.shape value_3d = g(z_reshape3d) assert value_3d.shape == z_reshape3d.shape assert value_flat.unit == value_2d.unit assert value_flat.unit == value_3d.unit assert allclose(value_flat, value_2d.flatten()) assert allclose(value_flat, value_3d.flatten()) # Also test unitless ones methods = ['absorption_distance', 'Om', 'Ode', 'Ok', 'H', 'w', 'de_density_scale', 'Onu', 'Ogamma', 'nu_relative_density'] for method in methods: g = getattr(cosmo, method) value_flat = g(z) assert value_flat.shape == z.shape value_2d = g(z_reshape2d) assert value_2d.shape == z_reshape2d.shape value_3d = g(z_reshape3d) assert value_3d.shape == z_reshape3d.shape assert allclose(value_flat, value_2d.flatten()) assert allclose(value_flat, value_3d.flatten()) # Test some dark energy models methods = ['Om', 'Ode', 'w', 'de_density_scale'] for tcosmo in [flrw.LambdaCDM(H0=70, Om0=0.27, Ode0=0.5), flrw.wCDM(H0=70, Om0=0.27, Ode0=0.5, w0=-1.2), flrw.w0waCDM(H0=70, Om0=0.27, Ode0=0.5, w0=-1.2, wa=-0.2), flrw.wpwaCDM(H0=70, Om0=0.27, Ode0=0.5, wp=-1.2, wa=-0.2, zp=0.9), flrw.w0wzCDM(H0=70, Om0=0.27, Ode0=0.5, w0=-1.2, wz=0.1)]: for method in methods: g = getattr(cosmo, method) value_flat = g(z) assert value_flat.shape == z.shape value_2d = g(z_reshape2d) assert value_2d.shape == z_reshape2d.shape value_3d = g(z_reshape3d) assert value_3d.shape == z_reshape3d.shape assert allclose(value_flat, value_2d.flatten()) assert allclose(value_flat, value_3d.flatten()) def test_equality(): """Test equality and equivalence.""" # Equality assert Planck18 == Planck18 assert Planck13 != Planck18 # just wrong assert Planck18 != 2 assert 2 != Planck18 # mismatched signatures, both directions. newcosmo = flrw.w0waCDM(**Planck18._init_arguments, Ode0=0.6) assert newcosmo != Planck18 assert Planck18 != newcosmo # different arguments newcosmo = Planck18.clone(name="modified") assert Planck18 != newcosmo # the name was changed! assert newcosmo != Planck18 # double check directions. def test_xtfuncs(): """ Test of absorption and lookback integrand""" cosmo = flrw.LambdaCDM(70, 0.3, 0.5, Tcmb0=2.725) z = np.array([2.0, 3.2]) assert allclose(cosmo.lookback_time_integrand(3), 0.052218976654969378, rtol=1e-4) assert allclose(cosmo.lookback_time_integrand(z), [0.10333179, 0.04644541], rtol=1e-4) assert allclose(cosmo.abs_distance_integrand(3), 3.3420145059180402, rtol=1e-4) assert allclose(cosmo.abs_distance_integrand(z), [2.7899584, 3.44104758], rtol=1e-4) @pytest.mark.skipif('not HAS_SCIPY') def test_flat_z1(): """ Test a flat cosmology at z=1 against several other on-line calculators. """ cosmo = flrw.FlatLambdaCDM(H0=70, Om0=0.27, Tcmb0=0.0) z = 1 # Test values were taken from the following web cosmology # calculators on 27th Feb 2012: # Wright: http://www.astro.ucla.edu/~wright/CosmoCalc.html # (https://ui.adsabs.harvard.edu/abs/2006PASP..118.1711W) # Kempner: http://www.kempner.net/cosmic.php # iCosmos: http://www.icosmos.co.uk/index.html # The order of values below is Wright, Kempner, iCosmos' assert allclose(cosmo.comoving_distance(z), [3364.5, 3364.8, 3364.7988] * u.Mpc, rtol=1e-4) assert allclose(cosmo.angular_diameter_distance(z), [1682.3, 1682.4, 1682.3994] * u.Mpc, rtol=1e-4) assert allclose(cosmo.luminosity_distance(z), [6729.2, 6729.6, 6729.5976] * u.Mpc, rtol=1e-4) assert allclose(cosmo.lookback_time(z), [7.841, 7.84178, 7.843] * u.Gyr, rtol=1e-3) assert allclose(cosmo.lookback_distance(z), [2404.0, 2404.24, 2404.4] * u.Mpc, rtol=1e-3) def test_zeroing(): """ Tests if setting params to 0s always respects that""" # Make sure Ode = 0 behaves that way cosmo = flrw.LambdaCDM(H0=70, Om0=0.27, Ode0=0.0) assert allclose(cosmo.Ode([0, 1, 2, 3]), [0, 0, 0, 0]) assert allclose(cosmo.Ode(1), 0) # Ogamma0 and Onu cosmo = flrw.FlatLambdaCDM(H0=70, Om0=0.27, Tcmb0=0.0) assert allclose(cosmo.Ogamma(1.5), [0, 0, 0, 0]) assert allclose(cosmo.Ogamma([0, 1, 2, 3]), [0, 0, 0, 0]) assert allclose(cosmo.Onu(1.5), [0, 0, 0, 0]) assert allclose(cosmo.Onu([0, 1, 2, 3]), [0, 0, 0, 0]) # Obaryon cosmo = flrw.LambdaCDM(H0=70, Om0=0.27, Ode0=0.73, Ob0=0.0) assert allclose(cosmo.Ob([0, 1, 2, 3]), [0, 0, 0, 0]) # This class is to test whether the routines work correctly # if one only overloads w(z) class test_cos_sub(flrw.FLRW): def __init__(self): super().__init__(70.0, 0.27, 0.73, Tcmb0=0.0, name="test_cos") self._w0 = -0.9 def w(self, z): return self._w0 * np.ones_like(z) # Similar, but with neutrinos class test_cos_subnu(flrw.FLRW): def __init__(self): super().__init__(70.0, 0.27, 0.73, Tcmb0=3.0, m_nu=0.1 * u.eV, name="test_cos_nu") self._w0 = -0.8 def w(self, z): return self._w0 * np.ones_like(z) @pytest.mark.skipif('not HAS_SCIPY') def test_de_subclass(): # This is the comparison object z = [0.2, 0.4, 0.6, 0.9] cosmo = flrw.wCDM(H0=70, Om0=0.27, Ode0=0.73, w0=-0.9, Tcmb0=0.0) # Values taken from Ned Wrights advanced cosmo calculator, Aug 17 2012 assert allclose(cosmo.luminosity_distance(z), [975.5, 2158.2, 3507.3, 5773.1] * u.Mpc, rtol=1e-3) # Now try the subclass that only gives w(z) cosmo = test_cos_sub() assert allclose(cosmo.luminosity_distance(z), [975.5, 2158.2, 3507.3, 5773.1] * u.Mpc, rtol=1e-3) # Test efunc assert allclose(cosmo.efunc(1.0), 1.7489240754, rtol=1e-5) assert allclose(cosmo.efunc([0.5, 1.0]), [1.31744953, 1.7489240754], rtol=1e-5) assert allclose(cosmo.inv_efunc([0.5, 1.0]), [0.75904236, 0.57178011], rtol=1e-5) # Test de_density_scale assert allclose(cosmo.de_density_scale(1.0), 1.23114444, rtol=1e-4) assert allclose(cosmo.de_density_scale([0.5, 1.0]), [1.12934694, 1.23114444], rtol=1e-4) # Add neutrinos for efunc, inv_efunc @pytest.mark.skipif('not HAS_SCIPY') def test_varyde_lumdist_mathematica(): """Tests a few varying dark energy EOS models against a mathematica computation""" # w0wa models z = np.array([0.2, 0.4, 0.9, 1.2]) cosmo = flrw.w0waCDM(H0=70, Om0=0.2, Ode0=0.8, w0=-1.1, wa=0.2, Tcmb0=0.0) assert allclose(cosmo.w0, -1.1) assert allclose(cosmo.wa, 0.2) assert allclose(cosmo.luminosity_distance(z), [1004.0, 2268.62, 6265.76, 9061.84] * u.Mpc, rtol=1e-4) assert allclose(cosmo.de_density_scale(0.0), 1.0, rtol=1e-5) assert allclose(cosmo.de_density_scale([0.0, 0.5, 1.5]), [1.0, 0.9246310669529021, 0.9184087000251957]) cosmo = flrw.w0waCDM(H0=70, Om0=0.3, Ode0=0.7, w0=-0.9, wa=0.0, Tcmb0=0.0) assert allclose(cosmo.luminosity_distance(z), [971.667, 2141.67, 5685.96, 8107.41] * u.Mpc, rtol=1e-4) cosmo = flrw.w0waCDM(H0=70, Om0=0.3, Ode0=0.7, w0=-0.9, wa=-0.5, Tcmb0=0.0) assert allclose(cosmo.luminosity_distance(z), [974.087, 2157.08, 5783.92, 8274.08] * u.Mpc, rtol=1e-4) # wpwa models cosmo = flrw.wpwaCDM(H0=70, Om0=0.2, Ode0=0.8, wp=-1.1, wa=0.2, zp=0.5, Tcmb0=0.0) assert allclose(cosmo.wp, -1.1) assert allclose(cosmo.wa, 0.2) assert allclose(cosmo.zp, 0.5) assert allclose(cosmo.luminosity_distance(z), [1010.81, 2294.45, 6369.45, 9218.95] * u.Mpc, rtol=1e-4) cosmo = flrw.wpwaCDM(H0=70, Om0=0.2, Ode0=0.8, wp=-1.1, wa=0.2, zp=0.9, Tcmb0=0.0) assert allclose(cosmo.wp, -1.1) assert allclose(cosmo.wa, 0.2) assert allclose(cosmo.zp, 0.9) assert allclose(cosmo.luminosity_distance(z), [1013.68, 2305.3, 6412.37, 9283.33] * u.Mpc, rtol=1e-4) @pytest.mark.skipif('not HAS_SCIPY') def test_matter(): # Test non-relativistic matter evolution tcos = flrw.FlatLambdaCDM(70.0, 0.3, Ob0=0.045) assert allclose(tcos.Om0, 0.3) assert allclose(tcos.H0, 70.0 * u.km / u.s / u.Mpc) assert allclose(tcos.Om(0), 0.3) assert allclose(tcos.Ob(0), 0.045) z = np.array([0.0, 0.5, 1.0, 2.0]) assert allclose(tcos.Om(z), [0.3, 0.59124088, 0.77419355, 0.92045455], rtol=1e-4) assert allclose(tcos.Ob(z), [0.045, 0.08868613, 0.11612903, 0.13806818], rtol=1e-4) assert allclose(tcos.Odm(z), [0.255, 0.50255474, 0.65806452, 0.78238636], rtol=1e-4) # Consistency of dark and baryonic matter evolution with all # non-relativistic matter assert allclose(tcos.Ob(z) + tcos.Odm(z), tcos.Om(z)) @pytest.mark.skipif('not HAS_SCIPY') def test_ocurv(): # Test Ok evolution # Flat, boring case tcos = flrw.FlatLambdaCDM(70.0, 0.3) assert allclose(tcos.Ok0, 0.0) assert allclose(tcos.Ok(0), 0.0) z = np.array([0.0, 0.5, 1.0, 2.0]) assert allclose(tcos.Ok(z), [0.0, 0.0, 0.0, 0.0], rtol=1e-6) # Not flat tcos = flrw.LambdaCDM(70.0, 0.3, 0.5, Tcmb0=u.Quantity(0.0, u.K)) assert allclose(tcos.Ok0, 0.2) assert allclose(tcos.Ok(0), 0.2) assert allclose(tcos.Ok(z), [0.2, 0.22929936, 0.21621622, 0.17307692], rtol=1e-4) # Test the sum; note that Ogamma/Onu are 0 assert allclose(tcos.Ok(z) + tcos.Om(z) + tcos.Ode(z), [1.0, 1.0, 1.0, 1.0], rtol=1e-5) @pytest.mark.skipif('not HAS_SCIPY') def test_ode(): # Test Ode evolution, turn off neutrinos, cmb tcos = flrw.FlatLambdaCDM(70.0, 0.3, Tcmb0=0) assert allclose(tcos.Ode0, 0.7) assert allclose(tcos.Ode(0), 0.7) z = np.array([0.0, 0.5, 1.0, 2.0]) assert allclose(tcos.Ode(z), [0.7, 0.408759, 0.2258065, 0.07954545], rtol=1e-5) @pytest.mark.skipif('not HAS_SCIPY') def test_ogamma(): """Tests the effects of changing the temperature of the CMB""" # Tested against Ned Wright's advanced cosmology calculator, # Sep 7 2012. The accuracy of our comparison is limited by # how many digits it outputs, which limits our test to about # 0.2% accuracy. The NWACC does not allow one # to change the number of nuetrino species, fixing that at 3. # Also, inspection of the NWACC code shows it uses inaccurate # constants at the 0.2% level (specifically, a_B), # so we shouldn't expect to match it that well. The integral is # also done rather crudely. Therefore, we should not expect # the NWACC to be accurate to better than about 0.5%, which is # unfortunate, but reflects a problem with it rather than this code. # More accurate tests below using Mathematica z = np.array([1.0, 10.0, 500.0, 1000.0]) cosmo = flrw.FlatLambdaCDM(H0=70, Om0=0.3, Tcmb0=0, Neff=3) assert allclose(cosmo.angular_diameter_distance(z), [1651.9, 858.2, 26.855, 13.642] * u.Mpc, rtol=5e-4) cosmo = flrw.FlatLambdaCDM(H0=70, Om0=0.3, Tcmb0=2.725, Neff=3) assert allclose(cosmo.angular_diameter_distance(z), [1651.8, 857.9, 26.767, 13.582] * u.Mpc, rtol=5e-4) cosmo = flrw.FlatLambdaCDM(H0=70, Om0=0.3, Tcmb0=4.0, Neff=3) assert allclose(cosmo.angular_diameter_distance(z), [1651.4, 856.6, 26.489, 13.405] * u.Mpc, rtol=5e-4) # Next compare with doing the integral numerically in Mathematica, # which allows more precision in the test. It is at least as # good as 0.01%, possibly better cosmo = flrw.FlatLambdaCDM(H0=70, Om0=0.3, Tcmb0=0, Neff=3.04) assert allclose(cosmo.angular_diameter_distance(z), [1651.91, 858.205, 26.8586, 13.6469] * u.Mpc, rtol=1e-5) cosmo = flrw.FlatLambdaCDM(H0=70, Om0=0.3, Tcmb0=2.725, Neff=3.04) assert allclose(cosmo.angular_diameter_distance(z), [1651.76, 857.817, 26.7688, 13.5841] * u.Mpc, rtol=1e-5) cosmo = flrw.FlatLambdaCDM(H0=70, Om0=0.3, Tcmb0=4.0, Neff=3.04) assert allclose(cosmo.angular_diameter_distance(z), [1651.21, 856.411, 26.4845, 13.4028] * u.Mpc, rtol=1e-5) # Just to be really sure, we also do a version where the integral # is analytic, which is a Ode = 0 flat universe. In this case # Integrate(1/E(x),{x,0,z}) = 2 ( sqrt((1+Or z)/(1+z)) - 1 )/(Or - 1) # Recall that c/H0 * Integrate(1/E) is FLRW.comoving_distance. Ogamma0h2 = 4 * 5.670373e-8 / 299792458.0 ** 3 * 2.725 ** 4 / 1.87837e-26 Onu0h2 = Ogamma0h2 * 7.0 / 8.0 * (4.0 / 11.0) ** (4.0 / 3.0) * 3.04 Or0 = (Ogamma0h2 + Onu0h2) / 0.7 ** 2 Om0 = 1.0 - Or0 hubdis = (299792.458 / 70.0) * u.Mpc cosmo = flrw.FlatLambdaCDM(H0=70, Om0=Om0, Tcmb0=2.725, Neff=3.04) targvals = 2.0 * hubdis * \ (np.sqrt((1.0 + Or0 * z) / (1.0 + z)) - 1.0) / (Or0 - 1.0) assert allclose(cosmo.comoving_distance(z), targvals, rtol=1e-5) # And integers for z assert allclose(cosmo.comoving_distance(z.astype(int)), targvals, rtol=1e-5) # Try Tcmb0 = 4 Or0 *= (4.0 / 2.725) ** 4 Om0 = 1.0 - Or0 cosmo = flrw.FlatLambdaCDM(H0=70, Om0=Om0, Tcmb0=4.0, Neff=3.04) targvals = 2.0 * hubdis * \ (np.sqrt((1.0 + Or0 * z) / (1.0 + z)) - 1.0) / (Or0 - 1.0) assert allclose(cosmo.comoving_distance(z), targvals, rtol=1e-5) @pytest.mark.skipif('not HAS_SCIPY') def test_tcmb(): cosmo = flrw.FlatLambdaCDM(70.4, 0.272, Tcmb0=2.5) assert allclose(cosmo.Tcmb0, 2.5 * u.K) assert allclose(cosmo.Tcmb(2), 7.5 * u.K) z = [0.0, 1.0, 2.0, 3.0, 9.0] assert allclose(cosmo.Tcmb(z), [2.5, 5.0, 7.5, 10.0, 25.0] * u.K, rtol=1e-6) # Make sure it's the same for integers z = [0, 1, 2, 3, 9] assert allclose(cosmo.Tcmb(z), [2.5, 5.0, 7.5, 10.0, 25.0] * u.K, rtol=1e-6) @pytest.mark.skipif('not HAS_SCIPY') def test_tnu(): cosmo = flrw.FlatLambdaCDM(70.4, 0.272, Tcmb0=3.0) assert allclose(cosmo.Tnu0, 2.1412975665108247 * u.K, rtol=1e-6) assert allclose(cosmo.Tnu(2), 6.423892699532474 * u.K, rtol=1e-6) z = [0.0, 1.0, 2.0, 3.0] expected = [2.14129757, 4.28259513, 6.4238927, 8.56519027] * u.K assert allclose(cosmo.Tnu(z), expected, rtol=1e-6) # Test for integers z = [0, 1, 2, 3] assert allclose(cosmo.Tnu(z), expected, rtol=1e-6) @pytest.mark.skipif('not HAS_SCIPY') def test_efunc_vs_invefunc_flrw(): """ Test that efunc and inv_efunc give inverse values""" z0 = 0.5 z = np.array([0.5, 1.0, 2.0, 5.0]) # FLRW is abstract, so requires test_cos_sub defined earlier # This requires scipy, unlike the built-ins, because it # calls de_density_scale, which has an integral in it cosmo = test_cos_sub() assert allclose(cosmo.efunc(z0), 1.0 / cosmo.inv_efunc(z0)) assert allclose(cosmo.efunc(z), 1.0 / cosmo.inv_efunc(z)) # Add neutrinos cosmo = test_cos_subnu() assert allclose(cosmo.efunc(z0), 1.0 / cosmo.inv_efunc(z0)) assert allclose(cosmo.efunc(z), 1.0 / cosmo.inv_efunc(z)) @pytest.mark.skipif('not HAS_SCIPY') def test_kpc_methods(): cosmo = flrw.FlatLambdaCDM(70.4, 0.272, Tcmb0=0.0) assert allclose(cosmo.arcsec_per_kpc_comoving(3), 0.0317179167 * u.arcsec / u.kpc) assert allclose(cosmo.arcsec_per_kpc_proper(3), 0.1268716668 * u.arcsec / u.kpc) assert allclose(cosmo.kpc_comoving_per_arcmin(3), 1891.6753126 * u.kpc / u.arcmin) assert allclose(cosmo.kpc_proper_per_arcmin(3), 472.918828 * u.kpc / u.arcmin) @pytest.mark.skipif('not HAS_SCIPY') def test_comoving_volume(): c_flat = flrw.LambdaCDM(H0=70, Om0=0.27, Ode0=0.73, Tcmb0=0.0) c_open = flrw.LambdaCDM(H0=70, Om0=0.27, Ode0=0.0, Tcmb0=0.0) c_closed = flrw.LambdaCDM(H0=70, Om0=2, Ode0=0.0, Tcmb0=0.0) # test against ned wright's calculator (cubic Gpc) redshifts = np.array([0.5, 1, 2, 3, 5, 9]) wright_flat = np.array([29.123, 159.529, 630.427, 1178.531, 2181.485, 3654.802]) * u.Gpc**3 wright_open = np.array([20.501, 99.019, 380.278, 747.049, 1558.363, 3123.814]) * u.Gpc**3 wright_closed = np.array([12.619, 44.708, 114.904, 173.709, 258.82, 358.992]) * u.Gpc**3 # The wright calculator isn't very accurate, so we use a rather # modest precision assert allclose(c_flat.comoving_volume(redshifts), wright_flat, rtol=1e-2) assert allclose(c_open.comoving_volume(redshifts), wright_open, rtol=1e-2) assert allclose(c_closed.comoving_volume(redshifts), wright_closed, rtol=1e-2) @pytest.mark.skipif('not HAS_SCIPY') def test_differential_comoving_volume(): from scipy.integrate import quad c_flat = flrw.LambdaCDM(H0=70, Om0=0.27, Ode0=0.73, Tcmb0=0.0) c_open = flrw.LambdaCDM(H0=70, Om0=0.27, Ode0=0.0, Tcmb0=0.0) c_closed = flrw.LambdaCDM(H0=70, Om0=2, Ode0=0.0, Tcmb0=0.0) # test that integration of differential_comoving_volume() # yields same as comoving_volume() redshifts = np.array([0.5, 1, 2, 3, 5, 9]) wright_flat = np.array([29.123, 159.529, 630.427, 1178.531, 2181.485, 3654.802]) * u.Gpc**3 wright_open = np.array([20.501, 99.019, 380.278, 747.049, 1558.363, 3123.814]) * u.Gpc**3 wright_closed = np.array([12.619, 44.708, 114.904, 173.709, 258.82, 358.992]) * u.Gpc**3 # The wright calculator isn't very accurate, so we use a rather # modest precision. ftemp = lambda x: c_flat.differential_comoving_volume(x).value otemp = lambda x: c_open.differential_comoving_volume(x).value ctemp = lambda x: c_closed.differential_comoving_volume(x).value # Multiply by solid_angle (4 * pi) assert allclose(np.array([4.0 * np.pi * quad(ftemp, 0, redshift)[0] for redshift in redshifts]) * u.Mpc**3, wright_flat, rtol=1e-2) assert allclose(np.array([4.0 * np.pi * quad(otemp, 0, redshift)[0] for redshift in redshifts]) * u.Mpc**3, wright_open, rtol=1e-2) assert allclose(np.array([4.0 * np.pi * quad(ctemp, 0, redshift)[0] for redshift in redshifts]) * u.Mpc**3, wright_closed, rtol=1e-2) @pytest.mark.skipif('not HAS_SCIPY') def test_flat_open_closed_icosmo(): """ Test against the tabulated values generated from icosmo.org with three example cosmologies (flat, open and closed). """ cosmo_flat = """\ # from icosmo (icosmo.org) # Om 0.3 w -1 h 0.7 Ol 0.7 # z comoving_transvers_dist angular_diameter_dist luminosity_dist 0.0000000 0.0000000 0.0000000 0.0000000 0.16250000 669.77536 576.15085 778.61386 0.32500000 1285.5964 970.26143 1703.4152 0.50000000 1888.6254 1259.0836 2832.9381 0.66250000 2395.5489 1440.9317 3982.6000 0.82500000 2855.5732 1564.6976 5211.4210 1.0000000 3303.8288 1651.9144 6607.6577 1.1625000 3681.1867 1702.2829 7960.5663 1.3250000 4025.5229 1731.4077 9359.3408 1.5000000 4363.8558 1745.5423 10909.640 1.6625000 4651.4830 1747.0359 12384.573 1.8250000 4916.5970 1740.3883 13889.387 2.0000000 5179.8621 1726.6207 15539.586 2.1625000 5406.0204 1709.4136 17096.540 2.3250000 5616.5075 1689.1752 18674.888 2.5000000 5827.5418 1665.0120 20396.396 2.6625000 6010.4886 1641.0890 22013.414 2.8250000 6182.1688 1616.2533 23646.796 3.0000000 6355.6855 1588.9214 25422.742 3.1625000 6507.2491 1563.3031 27086.425 3.3250000 6650.4520 1537.6768 28763.205 3.5000000 6796.1499 1510.2555 30582.674 3.6625000 6924.2096 1485.0852 32284.127 3.8250000 7045.8876 1460.2876 33996.408 4.0000000 7170.3664 1434.0733 35851.832 4.1625000 7280.3423 1410.2358 37584.767 4.3250000 7385.3277 1386.9160 39326.870 4.5000000 7493.2222 1362.4040 41212.722 4.6625000 7588.9589 1340.2135 42972.480 """ cosmo_open = """\ # from icosmo (icosmo.org) # Om 0.3 w -1 h 0.7 Ol 0.1 # z comoving_transvers_dist angular_diameter_dist luminosity_dist 0.0000000 0.0000000 0.0000000 0.0000000 0.16250000 643.08185 553.18868 747.58265 0.32500000 1200.9858 906.40441 1591.3062 0.50000000 1731.6262 1154.4175 2597.4393 0.66250000 2174.3252 1307.8648 3614.8157 0.82500000 2578.7616 1413.0201 4706.2399 1.0000000 2979.3460 1489.6730 5958.6920 1.1625000 3324.2002 1537.2024 7188.5829 1.3250000 3646.8432 1568.5347 8478.9104 1.5000000 3972.8407 1589.1363 9932.1017 1.6625000 4258.1131 1599.2913 11337.226 1.8250000 4528.5346 1603.0211 12793.110 2.0000000 4804.9314 1601.6438 14414.794 2.1625000 5049.2007 1596.5852 15968.097 2.3250000 5282.6693 1588.7727 17564.875 2.5000000 5523.0914 1578.0261 19330.820 2.6625000 5736.9813 1566.4113 21011.694 2.8250000 5942.5803 1553.6158 22730.370 3.0000000 6155.4289 1538.8572 24621.716 3.1625000 6345.6997 1524.4924 26413.975 3.3250000 6529.3655 1509.6799 28239.506 3.5000000 6720.2676 1493.3928 30241.204 3.6625000 6891.5474 1478.0799 32131.840 3.8250000 7057.4213 1462.6780 34052.058 4.0000000 7230.3723 1446.0745 36151.862 4.1625000 7385.9998 1430.7021 38130.224 4.3250000 7537.1112 1415.4199 40135.117 4.5000000 7695.0718 1399.1040 42322.895 4.6625000 7837.5510 1384.1150 44380.133 """ cosmo_closed = """\ # from icosmo (icosmo.org) # Om 2 w -1 h 0.7 Ol 0.1 # z comoving_transvers_dist angular_diameter_dist luminosity_dist 0.0000000 0.0000000 0.0000000 0.0000000 0.16250000 601.80160 517.67879 699.59436 0.32500000 1057.9502 798.45297 1401.7840 0.50000000 1438.2161 958.81076 2157.3242 0.66250000 1718.6778 1033.7912 2857.3019 0.82500000 1948.2400 1067.5288 3555.5381 1.0000000 2152.7954 1076.3977 4305.5908 1.1625000 2312.3427 1069.2914 5000.4410 1.3250000 2448.9755 1053.3228 5693.8681 1.5000000 2575.6795 1030.2718 6439.1988 1.6625000 2677.9671 1005.8092 7130.0873 1.8250000 2768.1157 979.86398 7819.9270 2.0000000 2853.9222 951.30739 8561.7665 2.1625000 2924.8116 924.84161 9249.7167 2.3250000 2988.5333 898.80701 9936.8732 2.5000000 3050.3065 871.51614 10676.073 2.6625000 3102.1909 847.01459 11361.774 2.8250000 3149.5043 823.39982 12046.854 3.0000000 3195.9966 798.99915 12783.986 3.1625000 3235.5334 777.30533 13467.908 3.3250000 3271.9832 756.52790 14151.327 3.5000000 3308.1758 735.15017 14886.791 3.6625000 3339.2521 716.19347 15569.263 3.8250000 3368.1489 698.06195 16251.319 4.0000000 3397.0803 679.41605 16985.401 4.1625000 3422.1142 662.87926 17666.664 4.3250000 3445.5542 647.05243 18347.576 4.5000000 3469.1805 630.76008 19080.493 4.6625000 3489.7534 616.29199 19760.729 """ redshifts, dm, da, dl = np.loadtxt(StringIO(cosmo_flat), unpack=1) dm = dm * u.Mpc da = da * u.Mpc dl = dl * u.Mpc cosmo = flrw.LambdaCDM(H0=70, Om0=0.3, Ode0=0.70, Tcmb0=0.0) assert allclose(cosmo.comoving_transverse_distance(redshifts), dm) assert allclose(cosmo.angular_diameter_distance(redshifts), da) assert allclose(cosmo.luminosity_distance(redshifts), dl) redshifts, dm, da, dl = np.loadtxt(StringIO(cosmo_open), unpack=1) dm = dm * u.Mpc da = da * u.Mpc dl = dl * u.Mpc cosmo = flrw.LambdaCDM(H0=70, Om0=0.3, Ode0=0.1, Tcmb0=0.0) assert allclose(cosmo.comoving_transverse_distance(redshifts), dm) assert allclose(cosmo.angular_diameter_distance(redshifts), da) assert allclose(cosmo.luminosity_distance(redshifts), dl) redshifts, dm, da, dl = np.loadtxt(StringIO(cosmo_closed), unpack=1) dm = dm * u.Mpc da = da * u.Mpc dl = dl * u.Mpc cosmo = flrw.LambdaCDM(H0=70, Om0=2, Ode0=0.1, Tcmb0=0.0) assert allclose(cosmo.comoving_transverse_distance(redshifts), dm) assert allclose(cosmo.angular_diameter_distance(redshifts), da) assert allclose(cosmo.luminosity_distance(redshifts), dl) @pytest.mark.skipif('not HAS_SCIPY') def test_integral(): # Test integer vs. floating point inputs cosmo = flrw.LambdaCDM(H0=73.2, Om0=0.3, Ode0=0.50) assert allclose(cosmo.comoving_distance(3), cosmo.comoving_distance(3.0), rtol=1e-7) assert allclose(cosmo.comoving_distance([1, 2, 3, 5]), cosmo.comoving_distance([1.0, 2.0, 3.0, 5.0]), rtol=1e-7) assert allclose(cosmo.efunc(6), cosmo.efunc(6.0), rtol=1e-7) assert allclose(cosmo.efunc([1, 2, 6]), cosmo.efunc([1.0, 2.0, 6.0]), rtol=1e-7) assert allclose(cosmo.inv_efunc([1, 2, 6]), cosmo.inv_efunc([1.0, 2.0, 6.0]), rtol=1e-7) def test_wz(): cosmo = flrw.LambdaCDM(H0=70, Om0=0.3, Ode0=0.70) assert allclose(cosmo.w(1.0), -1.) assert allclose(cosmo.w([0.1, 0.2, 0.5, 1.5, 2.5, 11.5]), [-1., -1, -1, -1, -1, -1]) cosmo = flrw.wCDM(H0=70, Om0=0.3, Ode0=0.70, w0=-0.5) assert allclose(cosmo.w(1.0), -0.5) assert allclose(cosmo.w([0.1, 0.2, 0.5, 1.5, 2.5, 11.5]), [-0.5, -0.5, -0.5, -0.5, -0.5, -0.5]) assert allclose(cosmo.w0, -0.5) cosmo = flrw.w0wzCDM(H0=70, Om0=0.3, Ode0=0.70, w0=-1, wz=0.5) assert allclose(cosmo.w(1.0), -0.5) assert allclose(cosmo.w([0.0, 0.5, 1.0, 1.5, 2.3]), [-1.0, -0.75, -0.5, -0.25, 0.15]) assert allclose(cosmo.w0, -1.0) assert allclose(cosmo.wz, 0.5) cosmo = flrw.w0waCDM(H0=70, Om0=0.3, Ode0=0.70, w0=-1, wa=-0.5) assert allclose(cosmo.w0, -1.0) assert allclose(cosmo.wa, -0.5) assert allclose(cosmo.w(1.0), -1.25) assert allclose(cosmo.w([0.0, 0.5, 1.0, 1.5, 2.3]), [-1, -1.16666667, -1.25, -1.3, -1.34848485]) cosmo = flrw.wpwaCDM(H0=70, Om0=0.3, Ode0=0.70, wp=-0.9, wa=0.2, zp=0.5) assert allclose(cosmo.wp, -0.9) assert allclose(cosmo.wa, 0.2) assert allclose(cosmo.zp, 0.5) assert allclose(cosmo.w(0.5), -0.9) assert allclose(cosmo.w([0.1, 0.2, 0.5, 1.5, 2.5, 11.5]), [-0.94848485, -0.93333333, -0.9, -0.84666667, -0.82380952, -0.78266667]) @pytest.mark.skipif('not HAS_SCIPY') def test_de_densityscale(): cosmo = flrw.LambdaCDM(H0=70, Om0=0.3, Ode0=0.70) z = np.array([0.1, 0.2, 0.5, 1.5, 2.5]) assert allclose(cosmo.de_density_scale(z), [1.0, 1.0, 1.0, 1.0, 1.0]) # Integer check assert allclose(cosmo.de_density_scale(3), cosmo.de_density_scale(3.0), rtol=1e-7) assert allclose(cosmo.de_density_scale([1, 2, 3]), cosmo.de_density_scale([1., 2., 3.]), rtol=1e-7) cosmo = flrw.wCDM(H0=70, Om0=0.3, Ode0=0.60, w0=-0.5) assert allclose(cosmo.de_density_scale(z), [1.15369, 1.31453, 1.83712, 3.95285, 6.5479], rtol=1e-4) assert allclose(cosmo.de_density_scale(3), cosmo.de_density_scale(3.0), rtol=1e-7) assert allclose(cosmo.de_density_scale([1, 2, 3]), cosmo.de_density_scale([1., 2., 3.]), rtol=1e-7) cosmo = flrw.w0wzCDM(H0=70, Om0=0.3, Ode0=0.50, w0=-1, wz=0.5) assert allclose(cosmo.de_density_scale(z), [0.746048, 0.5635595, 0.25712378, 0.026664129, 0.0035916468], rtol=1e-4) assert allclose(cosmo.de_density_scale(3), cosmo.de_density_scale(3.0), rtol=1e-7) assert allclose(cosmo.de_density_scale([1, 2, 3]), cosmo.de_density_scale([1., 2., 3.]), rtol=1e-7) cosmo = flrw.w0waCDM(H0=70, Om0=0.3, Ode0=0.70, w0=-1, wa=-0.5) assert allclose(cosmo.de_density_scale(z), [0.9934201, 0.9767912, 0.897450, 0.622236, 0.4458753], rtol=1e-4) assert allclose(cosmo.de_density_scale(3), cosmo.de_density_scale(3.0), rtol=1e-7) assert allclose(cosmo.de_density_scale([1, 2, 3]), cosmo.de_density_scale([1., 2., 3.]), rtol=1e-7) cosmo = flrw.wpwaCDM(H0=70, Om0=0.3, Ode0=0.70, wp=-0.9, wa=0.2, zp=0.5) assert allclose(cosmo.de_density_scale(z), [1.012246048, 1.0280102, 1.087439, 1.324988, 1.565746], rtol=1e-4) assert allclose(cosmo.de_density_scale(3), cosmo.de_density_scale(3.0), rtol=1e-7) assert allclose(cosmo.de_density_scale([1, 2, 3]), cosmo.de_density_scale([1., 2., 3.]), rtol=1e-7) @pytest.mark.skipif('not HAS_SCIPY') def test_age(): # WMAP7 but with Omega_relativisitic = 0 tcos = flrw.FlatLambdaCDM(70.4, 0.272, Tcmb0=0.0) assert allclose(tcos.hubble_time, 13.889094057856937 * u.Gyr) assert allclose(tcos.age(4), 1.5823603508870991 * u.Gyr) assert allclose(tcos.age([1., 5.]), [5.97113193, 1.20553129] * u.Gyr) assert allclose(tcos.age([1, 5]), [5.97113193, 1.20553129] * u.Gyr) # Add relativistic species tcos = flrw.FlatLambdaCDM(70.4, 0.272, Tcmb0=3.0) assert allclose(tcos.age(4), 1.5773003779230699 * u.Gyr) assert allclose(tcos.age([1, 5]), [5.96344942, 1.20093077] * u.Gyr) # And massive neutrinos tcos = flrw.FlatLambdaCDM(70.4, 0.272, Tcmb0=3.0, m_nu=0.1 * u.eV) assert allclose(tcos.age(4), 1.5546485439853412 * u.Gyr) assert allclose(tcos.age([1, 5]), [5.88448152, 1.18383759] * u.Gyr) @pytest.mark.skipif('not HAS_SCIPY') def test_distmod(): # WMAP7 but with Omega_relativisitic = 0 tcos = flrw.FlatLambdaCDM(70.4, 0.272, Tcmb0=0.0) assert allclose(tcos.hubble_distance, 4258.415596590909 * u.Mpc) assert allclose(tcos.distmod([1, 5]), [44.124857, 48.40167258] * u.mag) assert allclose(tcos.distmod([1., 5.]), [44.124857, 48.40167258] * u.mag) @pytest.mark.skipif('not HAS_SCIPY') def test_neg_distmod(): # Cosmology with negative luminosity distances (perfectly okay, # if obscure) tcos = flrw.LambdaCDM(70, 0.2, 1.3, Tcmb0=0) assert allclose(tcos.luminosity_distance([50, 100]), [16612.44047622, -46890.79092244] * u.Mpc) assert allclose(tcos.distmod([50, 100]), [46.102167189, 48.355437790944] * u.mag) @pytest.mark.skipif('not HAS_SCIPY') def test_critical_density(): from astropy.constants import codata2014 # WMAP7 but with Omega_relativistic = 0 # These tests will fail if astropy.const starts returning non-mks # units by default; see the comment at the top of core.py. # critical_density0 is inversely proportional to G. tcos = flrw.FlatLambdaCDM(70.4, 0.272, Tcmb0=0.0) fac = (const.G / codata2014.G).to(u.dimensionless_unscaled).value assert allclose(tcos.critical_density0 * fac, 9.309668456020899e-30 * (u.g / u.cm**3)) assert allclose(tcos.critical_density0, tcos.critical_density(0)) assert allclose( tcos.critical_density([1, 5]) * fac, [2.70352772e-29, 5.53739080e-28] * (u.g / u.cm**3)) assert allclose( tcos.critical_density([1., 5.]) * fac, [2.70352772e-29, 5.53739080e-28] * (u.g / u.cm**3)) @pytest.mark.skipif('not HAS_SCIPY') def test_comoving_distance_z1z2(): tcos = flrw.LambdaCDM(100, 0.3, 0.8, Tcmb0=0.0) with pytest.raises(ValueError): # test diff size z1, z2 fail tcos._comoving_distance_z1z2((1, 2), (3, 4, 5)) # Comoving distances are invertible assert allclose(tcos._comoving_distance_z1z2(1, 2), -tcos._comoving_distance_z1z2(2, 1)) z1 = 0, 0, 2, 0.5, 1 z2 = 2, 1, 1, 2.5, 1.1 results = (3767.90579253, 2386.25591391, -1381.64987862, 2893.11776663, 174.1524683) * u.Mpc assert allclose(tcos._comoving_distance_z1z2(z1, z2), results) @pytest.mark.skipif('not HAS_SCIPY') def test_age_in_special_cosmologies(): """Check that age in de Sitter and Einstein-de Sitter Universes work. Some analytic solutions fail at these critical points. """ c_dS = flrw.FlatLambdaCDM(100, 0, Tcmb0=0) assert allclose(c_dS.age(z=0), np.inf * u.Gyr) assert allclose(c_dS.age(z=1), np.inf * u.Gyr) assert allclose(c_dS.lookback_time(z=0), 0 * u.Gyr) assert allclose(c_dS.lookback_time(z=1), 6.777539216261741 * u.Gyr) c_EdS = flrw.FlatLambdaCDM(100, 1, Tcmb0=0) assert allclose(c_EdS.age(z=0), 6.518614811154189 * u.Gyr) assert allclose(c_EdS.age(z=1), 2.3046783684542738 * u.Gyr) assert allclose(c_EdS.lookback_time(z=0), 0 * u.Gyr) assert allclose(c_EdS.lookback_time(z=1), 4.213936442699092 * u.Gyr) @pytest.mark.skipif('not HAS_SCIPY') def test_distance_in_special_cosmologies(): """Check that de Sitter and Einstein-de Sitter Universes both work. Some analytic solutions fail at these critical points. """ c_dS = flrw.FlatLambdaCDM(100, 0, Tcmb0=0) assert allclose(c_dS.comoving_distance(z=0), 0 * u.Mpc) assert allclose(c_dS.comoving_distance(z=1), 2997.92458 * u.Mpc) c_EdS = flrw.FlatLambdaCDM(100, 1, Tcmb0=0) assert allclose(c_EdS.comoving_distance(z=0), 0 * u.Mpc) assert allclose(c_EdS.comoving_distance(z=1), 1756.1435599923348 * u.Mpc) c_dS = flrw.LambdaCDM(100, 0, 1, Tcmb0=0) assert allclose(c_dS.comoving_distance(z=0), 0 * u.Mpc) assert allclose(c_dS.comoving_distance(z=1), 2997.92458 * u.Mpc) c_EdS = flrw.LambdaCDM(100, 1, 0, Tcmb0=0) assert allclose(c_EdS.comoving_distance(z=0), 0 * u.Mpc) assert allclose(c_EdS.comoving_distance(z=1), 1756.1435599923348 * u.Mpc) @pytest.mark.skipif('not HAS_SCIPY') def test_comoving_transverse_distance_z1z2(): tcos = flrw.FlatLambdaCDM(100, 0.3, Tcmb0=0.0) with pytest.raises(ValueError): # test diff size z1, z2 fail tcos._comoving_transverse_distance_z1z2((1, 2), (3, 4, 5)) # Tests that should actually work, target values computed with # http://www.astro.multivax.de:8000/phillip/angsiz_prog/README.HTML # Kayser, Helbig, and Schramm (Astron.Astrophys. 318 (1997) 680-686) assert allclose(tcos._comoving_transverse_distance_z1z2(1, 2), 1313.2232194828466 * u.Mpc) # In a flat universe comoving distance and comoving transverse # distance are identical z1 = 0, 0, 2, 0.5, 1 z2 = 2, 1, 1, 2.5, 1.1 assert allclose(tcos._comoving_distance_z1z2(z1, z2), tcos._comoving_transverse_distance_z1z2(z1, z2)) # Test Flat Universe with Omega_M > 1. Rarely used, but perfectly valid. tcos = flrw.FlatLambdaCDM(100, 1.5, Tcmb0=0.0) results = (2202.72682564, 1559.51679971, -643.21002593, 1408.36365679, 85.09286258) * u.Mpc assert allclose(tcos._comoving_transverse_distance_z1z2(z1, z2), results) # In a flat universe comoving distance and comoving transverse # distance are identical z1 = 0, 0, 2, 0.5, 1 z2 = 2, 1, 1, 2.5, 1.1 assert allclose(tcos._comoving_distance_z1z2(z1, z2), tcos._comoving_transverse_distance_z1z2(z1, z2)) # Test non-flat cases to avoid simply testing # comoving_distance_z1z2. Test array, array case. tcos = flrw.LambdaCDM(100, 0.3, 0.5, Tcmb0=0.0) results = (3535.931375645655, 2226.430046551708, -1208.6817970036532, 2595.567367601969, 151.36592003406884) * u.Mpc assert allclose(tcos._comoving_transverse_distance_z1z2(z1, z2), results) # Test positive curvature with scalar, array combination. tcos = flrw.LambdaCDM(100, 1.0, 0.2, Tcmb0=0.0) z1 = 0.1 z2 = 0, 0.1, 0.2, 0.5, 1.1, 2 results = (-281.31602666724865, 0., 248.58093707820436, 843.9331377460543, 1618.6104987686672, 2287.5626543279927) * u.Mpc assert allclose(tcos._comoving_transverse_distance_z1z2(z1, z2), results) @pytest.mark.skipif('not HAS_SCIPY') def test_angular_diameter_distance_z1z2(): tcos = flrw.FlatLambdaCDM(70.4, 0.272, Tcmb0=0.0) with pytest.raises(ValueError): # test diff size z1, z2 fail tcos.angular_diameter_distance_z1z2([1, 2], [3, 4, 5]) # Tests that should actually work assert allclose(tcos.angular_diameter_distance_z1z2(1, 2), 646.22968662822018 * u.Mpc) z1 = 2 # Separate test for z2.SubFLRW", None) @pytest.fixture def nonflatcosmo(self): """A non-flat cosmology used in equivalence tests.""" return LambdaCDM(70, 0.4, 0.8) # =============================================================== # Method & Attribute Tests # --------------------------------------------------------------- # Parameters def test_H0(self, cosmo_cls, cosmo): """Test Parameter ``H0``.""" # on the class assert isinstance(cosmo_cls.H0, Parameter) assert "Hubble constant" in cosmo_cls.H0.__doc__ assert cosmo_cls.H0.unit == u.Unit("km/(s Mpc)") # validation assert cosmo_cls.H0.validate(cosmo, 1) == 1 * u.Unit("km/(s Mpc)") assert cosmo_cls.H0.validate(cosmo, 10 * u.Unit("km/(s Mpc)")) == 10 * u.Unit("km/(s Mpc)") with pytest.raises(ValueError, match="H0 is a non-scalar quantity"): cosmo_cls.H0.validate(cosmo, [1, 2]) # on the instance assert cosmo.H0 is cosmo._H0 assert cosmo.H0 == 70 * (u.km / u.s / u.Mpc) def test_Om0(self, cosmo_cls, cosmo): """Test Parameter ``Om0``.""" # on the class assert isinstance(cosmo_cls.Om0, Parameter) assert "Omega matter" in cosmo_cls.Om0.__doc__ assert cosmo_cls.Tcmb0.format_spec == "0.4g" # validation assert cosmo_cls.Om0.validate(cosmo, 1) == 1 assert cosmo_cls.Om0.validate(cosmo, 10 * u.one) == 10 with pytest.raises(ValueError, match="Om0 cannot be negative"): cosmo_cls.Om0.validate(cosmo, -1) # on the instance assert cosmo.Om0 is cosmo._Om0 assert isinstance(cosmo.Om0, float) # from fset assert cosmo.Om0 == 0.27 def test_Ode0(self, cosmo_cls, cosmo): """Test Parameter ``Ode0``.""" # on the class assert isinstance(cosmo_cls.Ode0, Parameter) assert "Omega dark energy" in cosmo_cls.Ode0.__doc__ # validation assert cosmo_cls.Ode0.validate(cosmo, 1) == 1 assert cosmo_cls.Ode0.validate(cosmo, 10 * u.one) == 10 # on the instance assert cosmo.Ode0 is cosmo._Ode0 assert isinstance(cosmo.Ode0, float) # from setter def test_Tcmb0(self, cosmo_cls, cosmo): """Test Parameter ``Tcmb0``.""" # on the class assert isinstance(cosmo_cls.Tcmb0, Parameter) assert "Temperature of the CMB" in cosmo_cls.Tcmb0.__doc__ assert cosmo_cls.Tcmb0.unit == u.K # validation assert cosmo_cls.Tcmb0.validate(cosmo, 1) == 1 * u.K assert cosmo_cls.Tcmb0.validate(cosmo, 10 * u.K) == 10 * u.K with pytest.raises(ValueError, match="Tcmb0 is a non-scalar quantity"): cosmo_cls.Tcmb0.validate(cosmo, [1, 2]) # on the instance assert cosmo.Tcmb0 is cosmo._Tcmb0 assert cosmo.Tcmb0 == 3 * u.K def test_Neff(self, cosmo_cls, cosmo): """Test Parameter ``Neff``.""" # on the class assert isinstance(cosmo_cls.Neff, Parameter) assert "Number of effective neutrino species" in cosmo_cls.Neff.__doc__ # validation assert cosmo_cls.Neff.validate(cosmo, 1) == 1 assert cosmo_cls.Neff.validate(cosmo, 10 * u.one) == 10 with pytest.raises(ValueError, match="Neff cannot be negative"): cosmo_cls.Neff.validate(cosmo, -1) # on the instance assert cosmo.Neff is cosmo._Neff assert cosmo.Neff == 3.04 def test_m_nu(self, cosmo_cls, cosmo): """Test Parameter ``m_nu``.""" # on the class assert isinstance(cosmo_cls.m_nu, Parameter) assert "Mass of neutrino species" in cosmo_cls.m_nu.__doc__ assert cosmo_cls.m_nu.unit == u.eV assert cosmo_cls.m_nu.equivalencies == u.mass_energy() assert cosmo_cls.m_nu.format_spec == "" # on the instance # assert cosmo.m_nu is cosmo._m_nu assert u.allclose(cosmo.m_nu, [0.0, 0.0, 0.0] * u.eV) # set differently depending on the other inputs if cosmo.Tnu0.value == 0: assert cosmo.m_nu is None elif not cosmo._massivenu: # only massless assert u.allclose(cosmo.m_nu, 0 * u.eV) elif self._nmasslessnu == 0: # only massive assert cosmo.m_nu == cosmo._massivenu_mass else: # a mix -- the most complicated case assert u.allclose(cosmo.m_nu[:self._nmasslessnu], 0 * u.eV) assert u.allclose(cosmo.m_nu[self._nmasslessnu], cosmo._massivenu_mass) def test_Ob0(self, cosmo_cls, cosmo): """Test Parameter ``Ob0``.""" # on the class assert isinstance(cosmo_cls.Ob0, Parameter) assert "Omega baryon;" in cosmo_cls.Ob0.__doc__ # validation assert cosmo_cls.Ob0.validate(cosmo, None) is None assert cosmo_cls.Ob0.validate(cosmo, 0.1) == 0.1 assert cosmo_cls.Ob0.validate(cosmo, 0.1 * u.one) == 0.1 with pytest.raises(ValueError, match="Ob0 cannot be negative"): cosmo_cls.Ob0.validate(cosmo, -1) with pytest.raises(ValueError, match="baryonic density can not be larger"): cosmo_cls.Ob0.validate(cosmo, cosmo.Om0 + 1) # on the instance assert cosmo.Ob0 is cosmo._Ob0 assert cosmo.Ob0 is None # --------------------------------------------------------------- def test_init(self, cosmo_cls): """Test initialization.""" super().test_init(cosmo_cls) # TODO! transfer tests for initializing neutrinos # --------------------------------------------------------------- # from Cosmology def test_clone_change_param(self, cosmo): """Test method ``.clone()`` changing a(many) Parameter(s).""" super().test_clone_change_param(cosmo) # don't change any values kwargs = cosmo._init_arguments.copy() kwargs.pop("name", None) # make sure not setting name c = cosmo.clone(**kwargs) assert c.__class__ == cosmo.__class__ assert c.name == cosmo.name + " (modified)" assert c.is_equivalent(cosmo) # change ``H0`` # Note that H0 affects Ode0 because it changes Ogamma0 c = cosmo.clone(H0=100) assert c.__class__ == cosmo.__class__ assert c.name == cosmo.name + " (modified)" assert c.H0.value == 100 for n in ("Om0", "Ode0", "Tcmb0", "Neff", "m_nu", "Ok0", "Ob0"): v = getattr(c, n) if v is None: assert v is getattr(cosmo, n) continue assert u.allclose(v, getattr(cosmo, n), atol=1e-4 * getattr(v, "unit", 1)) assert not u.allclose(c.Ogamma0, cosmo.Ogamma0) assert not u.allclose(c.Onu0, cosmo.Onu0) # change multiple things c = cosmo.clone(name="new name", H0=100, Tcmb0=2.8, meta=dict(zz="tops")) assert c.__class__ == cosmo.__class__ assert c.name == "new name" assert c.H0.value == 100 assert c.Tcmb0.value == 2.8 assert c.meta == {**cosmo.meta, **dict(zz="tops")} for n in ("Om0", "Ode0", "Neff", "m_nu", "Ok0", "Ob0"): v = getattr(c, n) if v is None: assert v is getattr(cosmo, n) continue assert u.allclose(v, getattr(cosmo, n), atol=1e-4 * getattr(v, "unit", 1)) assert not u.allclose(c.Ogamma0, cosmo.Ogamma0) assert not u.allclose(c.Onu0, cosmo.Onu0) assert not u.allclose(c.Tcmb0.value, cosmo.Tcmb0.value) def test_is_equivalent(self, cosmo): """Test :meth:`astropy.cosmology.FLRW.is_equivalent`.""" super().test_is_equivalent(cosmo) # pass to CosmologySubclassTest # test against a FlatFLRWMixin # case (3) in FLRW.is_equivalent if isinstance(cosmo, FlatLambdaCDM): assert cosmo.is_equivalent(Planck18) assert Planck18.is_equivalent(cosmo) else: assert not cosmo.is_equivalent(Planck18) assert not Planck18.is_equivalent(cosmo) # --------------------------------------------------------------- def test_efunc_vs_invefunc(self, cosmo): """ Test that efunc and inv_efunc give inverse values. Here they just fail b/c no ``w(z)`` or no scipy. """ exception = NotImplementedError if HAS_SCIPY else ModuleNotFoundError with pytest.raises(exception): cosmo.efunc(0.5) with pytest.raises(exception): cosmo.inv_efunc(0.5) class FLRWSubclassTest(TestFLRW): """ Test subclasses of :class:`astropy.cosmology.FLRW`. This is broken away from ``TestFLRW``, because ``FLRW`` is an ABC and subclasses must override some methods. """ @abc.abstractmethod def setup_class(self): """Setup for testing.""" pass # =============================================================== def test_efunc_vs_invefunc(self, cosmo): """Test that ``efunc`` and ``inv_efunc`` give inverse values. Note that the test doesn't need scipy because it doesn't need to call ``de_density_scale``. """ # super().test_efunc_vs_invefunc(cosmo) # NOT b/c abstract `w(z)` z0 = 0.5 z = np.array([0.5, 1.0, 2.0, 5.0]) assert np.allclose(cosmo.efunc(z0), 1.0 / cosmo.inv_efunc(z0)) assert np.allclose(cosmo.efunc(z), 1.0 / cosmo.inv_efunc(z)) # ----------------------------------------------------------------------------- class FlatFLRWMixinTest(FlatCosmologyMixinTest): """Tests for :class:`astropy.cosmology.FlatFLRWMixin`.""" # --------------------------------------------------------------- # class-level def test_init_subclass(self, cosmo_cls): """Test initializing subclass, mostly that can't have Ode0 in init.""" super().test_init_subclass(cosmo_cls) with pytest.raises(TypeError, match="subclasses of"): class HASOde0SubClass(cosmo_cls): def __init__(self, Ode0): pass _COSMOLOGY_CLASSES.pop(HASOde0SubClass.__qualname__, None) # --------------------------------------------------------------- # instance-level def test_init(self, cosmo_cls): super().test_init(cosmo_cls) cosmo = cosmo_cls(*self.cls_args, **self.cls_kwargs) assert cosmo._Ode0 == 1.0 - cosmo._Om0 - cosmo._Ogamma0 - cosmo._Onu0 assert cosmo._Ok0 == 0.0 def test_is_equivalent(self, cosmo, nonflatcosmo): """Test :meth:`astropy.cosmology.FLRW.is_equivalent`.""" super().test_is_equivalent(cosmo) # pass to TestFLRW # against non-flat Cosmology assert not cosmo.is_equivalent(nonflatcosmo) assert not nonflatcosmo.is_equivalent(cosmo) # non-flat version of class nonflat_cosmo_cls = cosmo.__class__.mro()[3] # keys check in `test_is_equivalent_nonflat_class_different_params` # non-flat nonflat = nonflat_cosmo_cls(*self.cls_args, Ode0=0.9, **self.cls_kwargs) assert not nonflat.is_equivalent(cosmo) assert not cosmo.is_equivalent(nonflat) # flat, but not FlatFLRWMixin flat = nonflat_cosmo_cls(*self.cls_args, Ode0=1.0 - cosmo.Om0 - cosmo.Ogamma0 - cosmo.Onu0, **self.cls_kwargs) flat._Ok0 = 0.0 assert flat.is_equivalent(cosmo) assert cosmo.is_equivalent(flat) def test_repr(self, cosmo_cls, cosmo): """ Test method ``.__repr__()``. Skip non-flat superclass test. e.g. `TestFlatLambdaCDDM` -> `FlatFLRWMixinTest` vs `TestFlatLambdaCDDM` -> `TestLambdaCDDM` -> `FlatFLRWMixinTest` """ FLRWSubclassTest.test_repr(self, cosmo_cls, cosmo) # test eliminated Ode0 from parameters assert "Ode0" not in repr(cosmo) # ----------------------------------------------------------------------------- class TestLambdaCDM(FLRWSubclassTest): """Test :class:`astropy.cosmology.LambdaCDM`.""" def setup_class(self): """Setup for testing.""" self.cls = LambdaCDM self.cls_args = (70 * (u.km / u.s / u.Mpc), 0.27, 0.73) # H0, Om0, Ode0 self.cls_kwargs = dict(Tcmb0=3 * u.K, name=self.__class__.__name__, meta={"a": "b"}) def test_repr(self, cosmo_cls, cosmo): """Test method ``.__repr__()``.""" super().test_repr(cosmo_cls, cosmo) expected = ("LambdaCDM(name=\"ABCMeta\", H0=70 km / (Mpc s), Om0=0.27," " Ode0=0.73, Tcmb0=3 K, Neff=3.04, m_nu=[0. 0. 0.] eV," " Ob0=None)") assert repr(cosmo) == expected # ----------------------------------------------------------------------------- class TestFlatLambdaCDM(FlatFLRWMixinTest, TestLambdaCDM): """Test :class:`astropy.cosmology.FlatLambdaCDM`.""" def setup_class(self): """Setup for testing.""" self.cls = FlatLambdaCDM self.cls_args = (70 * (u.km / u.s / u.Mpc), 0.27) # H0, Om0, Ode0 self.cls_kwargs = dict(Tcmb0=3 * u.K, name=self.__class__.__name__, meta={"a": "b"}) def test_repr(self, cosmo_cls, cosmo): """Test method ``.__repr__()``.""" super().test_repr(cosmo_cls, cosmo) expected = ("FlatLambdaCDM(name=\"ABCMeta\", H0=70 km / (Mpc s)," " Om0=0.27, Tcmb0=3 K, Neff=3.04, m_nu=[0. 0. 0.] eV," " Ob0=None)") assert repr(cosmo) == expected # ----------------------------------------------------------------------------- class TestwCDM(FLRWSubclassTest): """Test :class:`astropy.cosmology.wCDM`.""" def setup_class(self): """Setup for testing.""" self.cls = wCDM self.cls_args = (70 * (u.km / u.s / u.Mpc), 0.27, 0.73) # H0, Om0, Ode0 self.cls_kwargs = dict(Tcmb0=3 * u.K, name=self.__class__.__name__, meta={"a": "b"}) def test_clone_change_param(self, cosmo): """Test method ``.clone()`` changing a(many) Parameter(s).""" super().test_clone_change_param(cosmo) # `w` params c = cosmo.clone(w0=0.1) assert c.w0 == 0.1 for n in ("H0", "Om0", "Ode0", "Tcmb0", "Neff", "m_nu", "Ok0", "Ob0"): v = getattr(c, n) if v is None: assert v is getattr(cosmo, n) continue assert u.allclose(v, getattr(cosmo, n), atol=1e-4 * getattr(v, "unit", 1)) def test_repr(self, cosmo_cls, cosmo): """Test method ``.__repr__()``.""" super().test_repr(cosmo_cls, cosmo) expected = ("wCDM(name=\"ABCMeta\", H0=70 km / (Mpc s), Om0=0.27," " Ode0=0.73, w0=-1, Tcmb0=3 K, Neff=3.04," " m_nu=[0. 0. 0.] eV, Ob0=None)") assert repr(cosmo) == expected # ----------------------------------------------------------------------------- class TestFlatwCDM(FlatFLRWMixinTest, TestwCDM): """Test :class:`astropy.cosmology.FlatwCDM`.""" def setup_class(self): """Setup for testing.""" self.cls = FlatwCDM self.cls_args = (70 * (u.km / u.s / u.Mpc), 0.27) # H0, Om0 self.cls_kwargs = dict(Tcmb0=3 * u.K, name=self.__class__.__name__, meta={"a": "b"}) def test_repr(self, cosmo_cls, cosmo): """Test method ``.__repr__()``.""" super().test_repr(cosmo_cls, cosmo) expected = ("FlatwCDM(name=\"ABCMeta\", H0=70 km / (Mpc s), Om0=0.27," " w0=-1, Tcmb0=3 K, Neff=3.04, m_nu=[0. 0. 0.] eV," " Ob0=None)") assert repr(cosmo) == expected # ----------------------------------------------------------------------------- class Testw0waCDM(FLRWSubclassTest): """Test :class:`astropy.cosmology.w0waCDM`.""" def setup_class(self): """Setup for testing.""" self.cls = w0waCDM self.cls_args = (70 * (u.km / u.s / u.Mpc), 0.27, 0.73) # H0, Om0, Ode0 self.cls_kwargs = dict(Tcmb0=3 * u.K, name=self.__class__.__name__, meta={"a": "b"}) def test_clone_change_param(self, cosmo): """Test method ``.clone()`` changing a(many) Parameter(s).""" super().test_clone_change_param(cosmo) # `w` params c = cosmo.clone(w0=0.1, wa=0.2) assert c.w0 == 0.1 assert c.wa == 0.2 for n in ("H0", "Om0", "Ode0", "Tcmb0", "Neff", "m_nu", "Ok0", "Ob0"): v = getattr(c, n) if v is None: assert v is getattr(cosmo, n) continue assert u.allclose(v, getattr(cosmo, n), atol=1e-4 * getattr(v, "unit", 1)) def test_repr(self, cosmo_cls, cosmo): """Test method ``.__repr__()``.""" super().test_repr(cosmo_cls, cosmo) expected = ("w0waCDM(name=\"ABCMeta\", H0=70 km / (Mpc s), Om0=0.27," " Ode0=0.73, w0=-1, wa=0, Tcmb0=3 K, Neff=3.04," " m_nu=[0. 0. 0.] eV, Ob0=None)") assert repr(cosmo) == expected # ----------------------------------------------------------------------------- class TestFlatw0waCDM(FlatFLRWMixinTest, Testw0waCDM): """Test :class:`astropy.cosmology.Flatw0waCDM`.""" def setup_class(self): """Setup for testing.""" self.cls = Flatw0waCDM self.cls_args = (70 * (u.km / u.s / u.Mpc), 0.27) # H0, Om0 self.cls_kwargs = dict(Tcmb0=3 * u.K, name=self.__class__.__name__, meta={"a": "b"}) def test_repr(self, cosmo_cls, cosmo): """Test method ``.__repr__()``.""" super().test_repr(cosmo_cls, cosmo) expected = ("Flatw0waCDM(name=\"ABCMeta\", H0=70 km / (Mpc s)," " Om0=0.27, w0=-1, wa=0, Tcmb0=3 K, Neff=3.04," " m_nu=[0. 0. 0.] eV, Ob0=None)") assert repr(cosmo) == expected # ----------------------------------------------------------------------------- class TestwpwaCDM(FLRWSubclassTest): """Test :class:`astropy.cosmology.wpwaCDM`.""" def setup_class(self): """Setup for testing.""" self.cls = wpwaCDM self.cls_args = (70 * (u.km / u.s / u.Mpc), 0.27, 0.73) # H0, Om0, Ode0 self.cls_kwargs = dict(Tcmb0=3 * u.K, name=self.__class__.__name__, meta={"a": "b"}) def test_clone_change_param(self, cosmo): """Test method ``.clone()`` changing a(many) Parameter(s).""" super().test_clone_change_param(cosmo) # `w` params c = cosmo.clone(wp=0.1, wa=0.2, zp=14) assert c.wp == 0.1 assert c.wa == 0.2 assert c.zp == 14 for n in ("H0", "Om0", "Ode0", "Tcmb0", "Neff", "m_nu", "Ok0", "Ob0"): v = getattr(c, n) if v is None: assert v is getattr(cosmo, n) continue assert u.allclose(v, getattr(cosmo, n), atol=1e-4 * getattr(v, "unit", 1)) def test_repr(self, cosmo_cls, cosmo): """Test method ``.__repr__()``.""" super().test_repr(cosmo_cls, cosmo) expected = ("wpwaCDM(name=\"ABCMeta\", H0=70 km / (Mpc s), Om0=0.27," " Ode0=0.73, wp=-1, wa=0, zp=0 redshift, Tcmb0=3 K," " Neff=3.04, m_nu=[0. 0. 0.] eV, Ob0=None)") assert repr(cosmo) == expected # ----------------------------------------------------------------------------- class Testw0wzCDM(FLRWSubclassTest): """Test :class:`astropy.cosmology.w0wzCDM`.""" def setup_class(self): """Setup for testing.""" self.cls = w0wzCDM self.cls_args = (70 * (u.km / u.s / u.Mpc), 0.27, 0.73) # H0, Om0, Ode0 self.cls_kwargs = dict(Tcmb0=3 * u.K, name=self.__class__.__name__, meta={"a": "b"}) def test_clone_change_param(self, cosmo): """Test method ``.clone()`` changing a(many) Parameter(s).""" super().test_clone_change_param(cosmo) # `w` params c = cosmo.clone(w0=0.1, wz=0.2) assert c.w0 == 0.1 assert c.wz == 0.2 for n in ("H0", "Om0", "Ode0", "Tcmb0", "Neff", "m_nu", "Ok0", "Ob0"): v = getattr(c, n) if v is None: assert v is getattr(cosmo, n) continue assert u.allclose(v, getattr(cosmo, n), atol=1e-4 * getattr(v, "unit", 1)) def test_repr(self, cosmo_cls, cosmo): """Test method ``.__repr__()``.""" super().test_repr(cosmo_cls, cosmo) expected = ("w0wzCDM(name=\"ABCMeta\", H0=70 km / (Mpc s), Om0=0.27," " Ode0=0.73, w0=-1, wz=0, Tcmb0=3 K, Neff=3.04," " m_nu=[0. 0. 0.] eV, Ob0=None)") assert repr(cosmo) == expected ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/tests/test_funcs.py0000644000175100001710000002654100000000000021662 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import inspect import sys from io import StringIO import pytest import numpy as np from astropy import units as u from astropy.cosmology import core, flrw from astropy.cosmology.funcs import _z_at_scalar_value, z_at_value from astropy.cosmology.realizations import WMAP1, WMAP3, WMAP5, WMAP7, WMAP9, Planck13, Planck15, Planck18 from astropy.units import allclose from astropy.utils.compat.optional_deps import HAS_SCIPY # noqa from astropy.utils.exceptions import AstropyUserWarning @pytest.mark.skipif('not HAS_SCIPY') def test_z_at_value_scalar(): # These are tests of expected values, and hence have less precision # than the roundtrip tests below (test_z_at_value_roundtrip); # here we have to worry about the cosmological calculations # giving slightly different values on different architectures, # there we are checking internal consistency on the same architecture # and so can be more demanding cosmo = Planck13 assert allclose(z_at_value(cosmo.age, 2 * u.Gyr), 3.19812268, rtol=1e-6) assert allclose(z_at_value(cosmo.lookback_time, 7 * u.Gyr), 0.795198375, rtol=1e-6) assert allclose(z_at_value(cosmo.distmod, 46 * u.mag), 1.991389168, rtol=1e-6) assert allclose(z_at_value(cosmo.luminosity_distance, 1e4 * u.Mpc), 1.36857907, rtol=1e-6) assert allclose(z_at_value(cosmo.luminosity_distance, 26.037193804 * u.Gpc, ztol=1e-10), 3, rtol=1e-9) assert allclose(z_at_value(cosmo.angular_diameter_distance, 1500*u.Mpc, zmax=2), 0.681277696, rtol=1e-6) assert allclose(z_at_value(cosmo.angular_diameter_distance, 1500*u.Mpc, zmin=2.5), 3.7914908, rtol=1e-6) # test behavior when the solution is outside z limits (should # raise a CosmologyError) with pytest.raises(core.CosmologyError): with pytest.warns(AstropyUserWarning, match=r'fval is not bracketed'): z_at_value(cosmo.angular_diameter_distance, 1500*u.Mpc, zmax=0.5) with pytest.raises(core.CosmologyError): with pytest.warns(AstropyUserWarning, match=r'fval is not bracketed'): z_at_value(cosmo.angular_diameter_distance, 1500*u.Mpc, zmin=4.) @pytest.mark.skipif('not HAS_SCIPY') class Test_ZatValue: def setup_class(self): self.cosmo = Planck13 def test_broadcast_arguments(self): """Test broadcast of arguments.""" # broadcasting main argument assert allclose( z_at_value(self.cosmo.age, [2, 7] * u.Gyr), [3.1981206134773115, 0.7562044333305182], rtol=1e-6) # basic broadcast of secondary arguments assert allclose( z_at_value(self.cosmo.angular_diameter_distance, 1500 * u.Mpc, zmin=[0, 2.5], zmax=[2, 4]), [0.681277696, 3.7914908], rtol=1e-6) # more interesting broadcast assert allclose( z_at_value(self.cosmo.angular_diameter_distance, 1500 * u.Mpc, zmin=[[0, 2.5]], zmax=[2, 4]), [[0.681277696, 3.7914908]], rtol=1e-6) def test_broadcast_bracket(self): """`bracket` has special requirements.""" # start with an easy one assert allclose( z_at_value(self.cosmo.age, 2 * u.Gyr, bracket=None), 3.1981206134773115, rtol=1e-6) # now actually have a bracket assert allclose( z_at_value(self.cosmo.age, 2 * u.Gyr, bracket=[0, 4]), 3.1981206134773115, rtol=1e-6) # now a bad length with pytest.raises(ValueError, match="sequence"): z_at_value(self.cosmo.age, 2 * u.Gyr, bracket=[0, 4, 4, 5]) # now the wrong dtype : an ndarray, but not an object array with pytest.raises(TypeError, match="dtype"): z_at_value(self.cosmo.age, 2 * u.Gyr, bracket=np.array([0, 4])) # now an object array of brackets bracket=np.array([[0, 4], [0, 3, 4]], dtype=object) assert allclose( z_at_value(self.cosmo.age, 2 * u.Gyr, bracket=bracket), [3.1981206134773115, 3.1981206134773115], rtol=1e-6) def test_bad_broadcast(self): """Shapes mismatch as expected""" with pytest.raises(ValueError, match="broadcast"): z_at_value(self.cosmo.angular_diameter_distance, 1500 * u.Mpc, zmin=[0, 2.5, 0.1], zmax=[2, 4]) def test_scalar_input_to_output(self): """Test scalar input returns a scalar.""" z = z_at_value(self.cosmo.angular_diameter_distance, 1500 * u.Mpc, zmin=0, zmax=2) assert isinstance(z, u.Quantity) assert z.dtype == np.float64 assert z.shape == () @pytest.mark.skipif('not HAS_SCIPY') def test_z_at_value_numpyvectorize(): """Test that numpy vectorize fails on Quantities. If this test starts failing then numpy vectorize can be used instead of the home-brewed vectorization. Please submit a PR making the change. """ z_at_value = np.vectorize(_z_at_scalar_value, excluded=["func", "method", "verbose"]) with pytest.raises(u.UnitConversionError, match="dimensionless quantities"): z_at_value(Planck15.age, 10*u.Gyr) @pytest.mark.skipif('not HAS_SCIPY') def test_z_at_value_verbose(monkeypatch): cosmo = Planck13 # Test the "verbose" flag. Since this uses "print", need to mod stdout mock_stdout = StringIO() monkeypatch.setattr(sys, 'stdout', mock_stdout) resx = z_at_value(cosmo.age, 2 * u.Gyr, verbose=True) assert str(resx.value) in mock_stdout.getvalue() # test "verbose" prints res @pytest.mark.skipif('not HAS_SCIPY') @pytest.mark.parametrize('method', ['Brent', 'Golden', 'Bounded']) def test_z_at_value_bracketed(method): """ Test 2 solutions for angular diameter distance by not constraining zmin, zmax, but setting `bracket` on the appropriate side of the turning point z. Setting zmin / zmax should override `bracket`. """ cosmo = Planck13 if method == 'Bounded': with pytest.warns(AstropyUserWarning, match=r'fval is not bracketed'): z = z_at_value(cosmo.angular_diameter_distance, 1500*u.Mpc, method=method) if z > 1.6: z = 3.7914908 bracket = (0.9, 1.5) else: z = 0.6812777 bracket = (1.6, 2.0) with pytest.warns(UserWarning, match=r"Option 'bracket' is ignored"): assert allclose(z_at_value(cosmo.angular_diameter_distance, 1500*u.Mpc, method=method, bracket=bracket), z, rtol=1e-6) else: assert allclose(z_at_value(cosmo.angular_diameter_distance, 1500*u.Mpc, method=method, bracket=(0.3, 1.0)), 0.6812777, rtol=1e-6) assert allclose(z_at_value(cosmo.angular_diameter_distance, 1500*u.Mpc, method=method, bracket=(2.0, 4.0)), 3.7914908, rtol=1e-6) assert allclose(z_at_value(cosmo.angular_diameter_distance, 1500*u.Mpc, method=method, bracket=(0.1, 1.5)), 0.6812777, rtol=1e-6) assert allclose(z_at_value(cosmo.angular_diameter_distance, 1500*u.Mpc, method=method, bracket=(0.1, 1.0, 2.0)), 0.6812777, rtol=1e-6) with pytest.warns(AstropyUserWarning, match=r'fval is not bracketed'): assert allclose(z_at_value(cosmo.angular_diameter_distance, 1500*u.Mpc, method=method, bracket=(0.9, 1.5)), 0.6812777, rtol=1e-6) assert allclose(z_at_value(cosmo.angular_diameter_distance, 1500*u.Mpc, method=method, bracket=(1.6, 2.0)), 3.7914908, rtol=1e-6) assert allclose(z_at_value(cosmo.angular_diameter_distance, 1500*u.Mpc, method=method, bracket=(1.6, 2.0), zmax=1.6), 0.6812777, rtol=1e-6) assert allclose(z_at_value(cosmo.angular_diameter_distance, 1500*u.Mpc, method=method, bracket=(0.9, 1.5), zmin=1.5), 3.7914908, rtol=1e-6) with pytest.raises(core.CosmologyError): with pytest.warns(AstropyUserWarning, match=r'fval is not bracketed'): z_at_value(cosmo.angular_diameter_distance, 1500*u.Mpc, method=method, bracket=(3.9, 5.0), zmin=4.) @pytest.mark.skipif('not HAS_SCIPY') @pytest.mark.parametrize('method', ['Brent', 'Golden', 'Bounded']) def test_z_at_value_unconverged(method): """ Test warnings on non-converged solution when setting `maxfun` to too small iteration number - only 'Bounded' returns status value and specific message. """ cosmo = Planck18 ztol = {'Brent': [1e-4, 1e-4], 'Golden': [1e-3, 1e-2], 'Bounded': [1e-3, 1e-1]} if method == 'Bounded': ctx = pytest.warns(AstropyUserWarning, match='Solver returned 1: Maximum number of ' 'function calls reached') else: ctx = pytest.warns(AstropyUserWarning, match='Solver returned None') with ctx: z0 = z_at_value(cosmo.angular_diameter_distance, 1*u.Gpc, zmax=2, maxfun=13, method=method) with ctx: z1 = z_at_value(cosmo.angular_diameter_distance, 1*u.Gpc, zmin=2, maxfun=13, method=method) assert allclose(z0, 0.32442, rtol=ztol[method][0]) assert allclose(z1, 8.18551, rtol=ztol[method][1]) @pytest.mark.skipif('not HAS_SCIPY') @pytest.mark.parametrize('cosmo', [Planck13, Planck15, Planck18, WMAP1, WMAP3, WMAP5, WMAP7, WMAP9, flrw.LambdaCDM, flrw.FlatLambdaCDM, flrw.wpwaCDM, flrw.w0wzCDM, flrw.wCDM, flrw.FlatwCDM, flrw.w0waCDM, flrw.Flatw0waCDM]) def test_z_at_value_roundtrip(cosmo): """ Calculate values from a known redshift, and then check that z_at_value returns the right answer. """ z = 0.5 # Skip Ok, w, de_density_scale because in the Planck cosmologies # they are redshift independent and hence uninvertable, # *_distance_z1z2 methods take multiple arguments, so require # special handling # clone is not a redshift-dependent method # nu_relative_density is not redshift-dependent in the WMAP cosmologies skip = ('Ok', 'angular_diameter_distance_z1z2', 'clone', 'is_equivalent', 'de_density_scale', 'w') if str(cosmo.name).startswith('WMAP'): skip += ('nu_relative_density', ) methods = inspect.getmembers(cosmo, predicate=inspect.ismethod) for name, func in methods: if name.startswith('_') or name in skip: continue fval = func(z) # we need zmax here to pick the right solution for # angular_diameter_distance and related methods. # Be slightly more generous with rtol than the default 1e-8 # used in z_at_value got = z_at_value(func, fval, bracket=[0.3, 1.0], ztol=1e-12) assert allclose(got, z, rtol=2e-11), f'Round-trip testing {name} failed' # Test distance functions between two redshifts; only for realizations if isinstance(cosmo.name, str): z2 = 2.0 func_z1z2 = [ lambda z1: cosmo._comoving_distance_z1z2(z1, z2), lambda z1: cosmo._comoving_transverse_distance_z1z2(z1, z2), lambda z1: cosmo.angular_diameter_distance_z1z2(z1, z2) ] for func in func_z1z2: fval = func(z) assert allclose(z, z_at_value(func, fval, zmax=1.5, ztol=1e-12), rtol=2e-11) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/tests/test_parameter.py0000644000175100001710000004010200000000000022511 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """Testing :mod:`astropy.cosmology.parameter`.""" ############################################################################## # IMPORTS # STDLIB import inspect # THIRD PARTY import pytest import numpy as np # LOCAL import astropy.units as u from astropy.cosmology import Cosmology from astropy.cosmology.core import _COSMOLOGY_CLASSES from astropy.cosmology.parameter import Parameter, _validate_to_float, _validate_with_unit ############################################################################## # TESTS ############################################################################## class ParameterTestMixin: """Tests for a :class:`astropy.cosmology.Parameter` on a Cosmology. :class:`astropy.cosmology.Parameter` is a descriptor and this test suite tests descriptors by class inheritance, so ``ParameterTestMixin`` is mixed into ``TestCosmology`` (tests :class:`astropy.cosmology.Cosmology`). """ @pytest.fixture def parameter(self, cosmo_cls): """Cosmological Parameters""" # I wish this would work # yield from {getattr(cosmo_cls, n) for n in cosmo_cls.__parameters__} # just return one parameter at random yield getattr(cosmo_cls, set(cosmo_cls.__parameters__).pop()) @pytest.fixture def all_parameter(self, cosmo_cls): """Cosmological All Parameter instances""" # I wish this would work # yield from {getattr(cosmo_cls, n) for n in cosmo_cls.__all_parameters__} # just return one parameter at random yield getattr(cosmo_cls, set(cosmo_cls.__all_parameters__).pop()) # =============================================================== # Method Tests def test_Parameter_class_attributes(self, all_parameter): """Test :class:`astropy.cosmology.Parameter` attributes on class.""" # _registry_validators assert hasattr(all_parameter, "_registry_validators") assert isinstance(all_parameter._registry_validators, dict) assert all(isinstance(k, str) for k in all_parameter._registry_validators.keys()) assert all(callable(v) for v in all_parameter._registry_validators.values()) def test_Parameter_init(self): """Test :class:`astropy.cosmology.Parameter` instantiation.""" # defaults parameter = Parameter() assert parameter.fvalidate is _validate_with_unit assert parameter.unit is None assert parameter.equivalencies == [] assert parameter.format_spec == ".3g" assert parameter.derived is False # setting all kwargs parameter = Parameter(fvalidate="float", doc="DOCSTRING", unit="km", equivalencies=[u.mass_energy()], fmt=".4f", derived=True) assert parameter.fvalidate is _validate_to_float assert parameter.unit is u.km assert parameter.equivalencies == [u.mass_energy()] assert parameter.format_spec == ".4f" assert parameter.derived is True def test_Parameter_instance_attributes(self, all_parameter): """Test :class:`astropy.cosmology.Parameter` attributes from init.""" assert hasattr(all_parameter, "fvalidate") assert callable(all_parameter.fvalidate) assert hasattr(all_parameter, "__doc__") # Parameter assert hasattr(all_parameter, "_unit") assert hasattr(all_parameter, "_equivalencies") assert hasattr(all_parameter, "_fmt") assert hasattr(all_parameter, "_derived") # __set_name__ assert hasattr(all_parameter, "_attr_name") assert hasattr(all_parameter, "_attr_name_private") def test_Parameter_fvalidate(self, all_parameter): """Test :attr:`astropy.cosmology.Parameter.fvalidate`.""" assert hasattr(all_parameter, "fvalidate") assert callable(all_parameter.fvalidate) def test_Parameter_name(self, all_parameter): """Test :attr:`astropy.cosmology.Parameter.name`.""" assert hasattr(all_parameter, "name") assert isinstance(all_parameter.name, str) assert all_parameter.name is all_parameter._attr_name def test_Parameter_unit(self, all_parameter): """Test :attr:`astropy.cosmology.Parameter.unit`.""" assert hasattr(all_parameter, "unit") assert isinstance(all_parameter.unit, (u.UnitBase, type(None))) assert all_parameter.unit is all_parameter._unit def test_Parameter_equivalencies(self, all_parameter): """Test :attr:`astropy.cosmology.Parameter.equivalencies`.""" assert hasattr(all_parameter, "equivalencies") assert isinstance(all_parameter.equivalencies, (list, u.Equivalency)) assert all_parameter.equivalencies is all_parameter._equivalencies def test_Parameter_format_spec(self, all_parameter): """Test :attr:`astropy.cosmology.Parameter.format_spec`.""" assert hasattr(all_parameter, "format_spec") assert isinstance(all_parameter.format_spec, str) assert all_parameter.format_spec is all_parameter._fmt def test_Parameter_derived(self, cosmo_cls, all_parameter): """Test :attr:`astropy.cosmology.Parameter.derived`.""" assert hasattr(all_parameter, "derived") assert isinstance(all_parameter.derived, bool) assert all_parameter.derived is all_parameter._derived # test value if all_parameter.name in cosmo_cls.__parameters__: assert all_parameter.derived is False else: assert all_parameter.derived is True # ------------------------------------------- # descriptor methods def test_Parameter_descriptor_get(self, cosmo_cls, cosmo, all_parameter): """Test :attr:`astropy.cosmology.Parameter.__get__`.""" # from class parameter = getattr(cosmo_cls, all_parameter.name) assert isinstance(parameter, Parameter) assert parameter is all_parameter # from instance parameter = getattr(cosmo, all_parameter.name) assert np.all(parameter == getattr(cosmo, all_parameter._attr_name_private)) def test_Parameter_descriptor_set(self, cosmo, all_parameter): """Test :attr:`astropy.cosmology.Parameter.__set__`.""" # test it's already set assert hasattr(cosmo, all_parameter._attr_name_private) # and raises an error if set again with pytest.raises(AttributeError, match="can't set attribute"): setattr(cosmo, all_parameter._attr_name, None) # ------------------------------------------- # validate value # tested later. # ------------------------------------------- def test_Parameter_repr(self, cosmo_cls, all_parameter): """Test Parameter repr.""" r = repr(getattr(cosmo_cls, all_parameter.name)) assert all_parameter._attr_name in r assert hex(id(all_parameter)) in r # =============================================================== # Usage Tests def test_Parameter_listed(self, cosmo_cls, all_parameter): """Test each `astropy.cosmology.Parameter` attached to Cosmology.""" # just double check that each entry is a Parameter assert isinstance(all_parameter, Parameter) # the reverse: check that if it is a Parameter, it's listed. # note have to check the more inclusive ``__all_parameters__`` assert all_parameter.name in cosmo_cls.__all_parameters__ if not all_parameter.derived: assert all_parameter.name in cosmo_cls.__parameters__ def test_parameter_related_attributes_on_Cosmology(self, cosmo_cls): """Test `astropy.cosmology.Parameter`-related on Cosmology.""" # establish has expected attribute assert hasattr(cosmo_cls, "__parameters__") assert hasattr(cosmo_cls, "__all_parameters__") def test_Parameter_not_unique(self, cosmo_cls, clean_registry): """Cosmology Parameter not unique to class when subclass defined.""" # define subclass to show param is same class ExampleBase(cosmo_cls): param = Parameter() class Example(ExampleBase): pass assert Example.param is ExampleBase.param assert Example.__parameters__ == ExampleBase.__parameters__ def test_Parameters_reorder_by_signature(self, cosmo_cls, clean_registry): """Test parameters are reordered.""" class Example(cosmo_cls): param = Parameter() def __init__(self, param, *, name=None, meta=None): pass # never actually initialized # param should be 1st, all other parameters next Example.__parameters__[0] == "param" # Check the other parameters are as expected. # only run this test if "param" is not already on the cosmology if cosmo_cls.__parameters__[0] != "param": assert set(Example.__parameters__[1:]) == set(cosmo_cls.__parameters__) def test_make_from_Parameter(self, cosmo_cls, clean_registry): """Test the parameter creation process. Uses ``__set__``.""" class Example(cosmo_cls): param = Parameter(unit=u.eV, equivalencies=u.mass_energy()) def __init__(self, param, *, name=None, meta=None): self.param = param assert Example(1).param == 1 * u.eV assert Example(1 * u.eV).param == 1 * u.eV assert Example(1 * u.J).param == (1 * u.J).to(u.eV) assert Example(1 * u.kg).param == (1 * u.kg).to(u.eV, u.mass_energy()) # ======================================================================== class TestParameter(ParameterTestMixin): """ Test `astropy.cosmology.Parameter` directly. Adds a lot of specific tests that wouldn't be covered by the per-cosmology tests. """ def setup_class(self): class Example1(Cosmology): param = Parameter(doc="example parameter", unit=u.m, equivalencies=u.mass_energy()) def __init__(self, param=15): self.param = param # with validator class Example2(Example1): def __init__(self, param=15 * u.m): self.param = param @Example1.param.validator def param(self, param, value): return value.to(u.km) # attributes self.classes = {"Example1": Example1, "Example2": Example2} def teardown_class(self): for cls in self.classes.values(): _COSMOLOGY_CLASSES.pop(cls.__qualname__) @pytest.fixture(params=["Example1", "Example2"]) def cosmo_cls(self, request): """Cosmology class.""" return self.classes[request.param] @pytest.fixture def cosmo(self, cosmo_cls): """Cosmology instance""" return cosmo_cls() @pytest.fixture def param(self, cosmo_cls): """Get Parameter 'param' from cosmology class.""" return cosmo_cls.param # ============================================================== def test_Parameter_instance_attributes(self, param): """Test :class:`astropy.cosmology.Parameter` attributes from init.""" super().test_Parameter_instance_attributes(param) # property assert param.__doc__ == "example parameter" # custom from init assert param._unit == u.m assert param._equivalencies == u.mass_energy() assert param._fmt == ".3g" assert param._derived == False # custom from set_name assert param._attr_name == "param" assert param._attr_name_private == "_param" def test_Parameter_fvalidate(self, cosmo, param): """Test :attr:`astropy.cosmology.Parameter.fvalidate`.""" super().test_Parameter_fvalidate(param) value = param.fvalidate(cosmo, param, 1000 * u.m) assert value == 1 * u.km def test_Parameter_name(self, param): """Test :attr:`astropy.cosmology.Parameter.name`.""" super().test_Parameter_name(param) assert param.name == "param" def test_Parameter_unit(self, param): """Test :attr:`astropy.cosmology.Parameter.unit`.""" super().test_Parameter_unit(param) assert param.unit == u.m def test_Parameter_equivalencies(self, param): """Test :attr:`astropy.cosmology.Parameter.equivalencies`.""" super().test_Parameter_equivalencies(param) assert param.equivalencies == u.mass_energy() def test_Parameter_format_spec(self, param): """Test :attr:`astropy.cosmology.Parameter.format_spec`.""" super().test_Parameter_format_spec(param) assert param.format_spec == ".3g" def test_Parameter_derived(self, cosmo_cls, param): """Test :attr:`astropy.cosmology.Parameter.derived`.""" super().test_Parameter_derived(cosmo_cls, param) assert param.derived is False # ------------------------------------------- # descriptor methods def test_Parameter_descriptor_get(self, cosmo_cls, cosmo, param): """Test :meth:`astropy.cosmology.Parameter.__get__`.""" super().test_Parameter_descriptor_get(cosmo_cls, cosmo, param) # from instance value = getattr(cosmo, param.name) assert value == 15 * u.m # ------------------------------------------- # validation def test_Parameter_validator(self, param): """Test :meth:`astropy.cosmology.Parameter.validator`.""" for k in Parameter._registry_validators: newparam = param.validator(k) assert newparam.fvalidate == newparam._registry_validators[k] # error for non-registered str with pytest.raises(ValueError, match="`fvalidate`, if str"): Parameter(fvalidate="NOT REGISTERED") # error if wrong type with pytest.raises(TypeError, match="`fvalidate` must be a function or"): Parameter(fvalidate=object()) def test_Parameter_validate(self, cosmo, param): """Test :meth:`astropy.cosmology.Parameter.validate`.""" value = param.validate(cosmo, 1000 * u.m) # whether has custom validator if param.fvalidate is param._registry_validators["default"]: assert value.unit == u.m assert value.value == 1000 else: assert value.unit == u.km assert value.value == 1 def test_Parameter_register_validator(self, param): """Test :meth:`astropy.cosmology.Parameter.register_validator`.""" # already registered with pytest.raises(KeyError, match="validator 'default' already"): param.__class__.register_validator("default", None) # validator not None try: func = lambda x: x validator = param.__class__.register_validator("newvalidator", func) assert validator is func finally: param.__class__._registry_validators.pop("newvalidator", None) # used as decorator try: @param.__class__.register_validator("newvalidator") def func(cosmology, param, value): return value assert param.__class__._registry_validators["newvalidator"] is func finally: param.__class__._registry_validators.pop("newvalidator", None) # ============================================================== def test_Parameter_doesnt_change_with_generic_class(self): """Descriptors are initialized once and not updated on subclasses.""" class ExampleBase: def __init__(self, param=15): self._param = param sig = inspect.signature(__init__) _init_signature = sig.replace(parameters=list(sig.parameters.values())[1:]) param = Parameter(doc="example parameter") class Example(ExampleBase): pass assert Example.param is ExampleBase.param def test_Parameter_doesnt_change_with_cosmology(self, cosmo_cls): """Cosmology reinitializes all descriptors when a subclass is defined.""" # define subclass to show param is same class Example(cosmo_cls): pass assert Example.param is cosmo_cls.param # unregister _COSMOLOGY_CLASSES.pop(Example.__qualname__) assert Example.__qualname__ not in _COSMOLOGY_CLASSES ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/tests/test_pickle.py0000644000175100001710000000204500000000000022004 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import pickle import pytest from astropy import cosmology from astropy.cosmology import FLRW from astropy.tests.helper import check_pickling_recovery, pickle_protocol originals = [FLRW] xfails = [False] @pytest.mark.parametrize(("original", "xfail"), zip(originals, xfails)) def test_flrw(pickle_protocol, original, xfail): if xfail: pytest.xfail() check_pickling_recovery(original, pickle_protocol) @pytest.mark.parametrize("name", cosmology.parameters.available) @pytest.mark.parametrize("protocol", [0, 1, 2, 3, 4]) # add [5] when drop 3.7 def test_builtin_realizations(name, protocol): """ Test in-built realizations can pickle and unpickle. Also a regression test for #12008. """ # get class instance original = getattr(cosmology, name) # pickle and unpickle f = pickle.dumps(original, protocol=protocol) unpickled = pickle.loads(f) # test equality assert unpickled == original assert unpickled.meta == original.meta ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/tests/test_realizations.py0000644000175100001710000000400400000000000023236 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import pytest from astropy.cosmology import parameters, realizations from astropy.cosmology.realizations import Planck13, default_cosmology from astropy.utils.exceptions import AstropyDeprecationWarning cosmo_realz = [s for s in parameters.available if s != "Planck18_arXiv_v2"] class Test_default_cosmology(object): """Tests for :class:`~astropy.cosmology.realizations.default_cosmology`.""" @staticmethod def test_get_cosmology_from_string(): """Test method ``get_cosmology_from_string``.""" cosmo = default_cosmology.get_cosmology_from_string("no_default") assert cosmo is None cosmo = default_cosmology.get_cosmology_from_string("Planck13") assert cosmo is Planck13 with pytest.raises(ValueError): cosmo = default_cosmology.get_cosmology_from_string("fail!") @staticmethod def test_validate_specific(): """Test method ``validate`` for specific values.""" value = default_cosmology.validate(None) assert value is realizations.Planck18 with pytest.warns(AstropyDeprecationWarning) as e: value = default_cosmology.validate("Planck18_arXiv_v2") assert "use Planck18 instead" in str(e.list[0].message) assert value is realizations.Planck18_arXiv_v2 with pytest.raises(TypeError) as e: default_cosmology.validate(TypeError) assert "string or Cosmology instance" in str(e.value) @pytest.mark.parametrize("name", cosmo_realz) def test_validate_str(self, name): """Test method ``validate`` for string input.""" value = default_cosmology.validate(name) assert value is getattr(realizations, name) @pytest.mark.parametrize("name", cosmo_realz) def test_validate_cosmo(self, name): """Test method ``validate`` for cosmology instance input.""" cosmo = getattr(realizations, name) value = default_cosmology.validate(cosmo) assert value is cosmo ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/tests/test_units.py0000644000175100001710000004514400000000000021706 0ustar00vstsdocker# -*- coding: utf-8 -*- """Testing :mod:`astropy.cosmology.units`.""" ############################################################################## # IMPORTS import contextlib import pytest import astropy.cosmology.units as cu import astropy.units as u from astropy.cosmology import Planck13, default_cosmology, flrw from astropy.tests.helper import assert_quantity_allclose from astropy.utils.compat.optional_deps import HAS_ASDF, HAS_SCIPY from astropy.utils.exceptions import AstropyDeprecationWarning ############################################################################## # TESTS ############################################################################## def test_has_expected_units(): """ Test that this module has the expected set of units. Some of the units are imported from :mod:`astropy.units`, or vice versa. Here we test presence, not usage. Units from :mod:`astropy.units` are tested in that module. Units defined in :mod:`astropy.cosmology` will be tested subsequently. """ with pytest.warns(AstropyDeprecationWarning, match="`littleh`"): assert u.astrophys.littleh is cu.littleh def test_has_expected_equivalencies(): """ Test that this module has the expected set of equivalencies. Many of the equivalencies are imported from :mod:`astropy.units`, so here we test presence, not usage. Equivalencies from :mod:`astropy.units` are tested in that module. Equivalencies defined in :mod:`astropy.cosmology` will be tested subsequently. """ with pytest.warns(AstropyDeprecationWarning, match="`with_H0`"): assert u.equivalencies.with_H0 is cu.with_H0 def test_littleh(): """Test :func:`astropy.cosmology.units.with_H0`.""" H0_70 = 70 * u.km / u.s / u.Mpc h70dist = 70 * u.Mpc / cu.littleh assert_quantity_allclose(h70dist.to(u.Mpc, cu.with_H0(H0_70)), 100 * u.Mpc) # make sure using the default cosmology works cosmodist = default_cosmology.get().H0.value * u.Mpc / cu.littleh assert_quantity_allclose(cosmodist.to(u.Mpc, cu.with_H0()), 100 * u.Mpc) # Now try a luminosity scaling h1lum = 0.49 * u.Lsun * cu.littleh ** -2 assert_quantity_allclose(h1lum.to(u.Lsun, cu.with_H0(H0_70)), 1 * u.Lsun) # And the trickiest one: magnitudes. Using H0=10 here for the round numbers H0_10 = 10 * u.km / u.s / u.Mpc # assume the "true" magnitude M = 12. # Then M - 5*log_10(h) = M + 5 = 17 withlittlehmag = 17 * (u.mag - u.MagUnit(cu.littleh ** 2)) assert_quantity_allclose(withlittlehmag.to(u.mag, cu.with_H0(H0_10)), 12 * u.mag) @pytest.mark.skipif(not HAS_SCIPY, reason="Cosmology needs scipy") def test_dimensionless_redshift(): """Test :func:`astropy.cosmology.units.dimensionless_redshift`.""" z = 3 * cu.redshift val = 3 * u.one # show units not equal assert z.unit == cu.redshift assert z.unit != u.one # test equivalency enabled by default assert z == val # also test that it works for powers assert (3 * cu.redshift ** 3) == val # and in composite units assert (3 * u.km / cu.redshift ** 3) == 3 * u.km # test it also works as an equivalency with u.set_enabled_equivalencies([]): # turn off default equivalencies assert z.to(u.one, equivalencies=cu.dimensionless_redshift()) == val with pytest.raises(ValueError): z.to(u.one) # if this fails, something is really wrong with u.add_enabled_equivalencies(cu.dimensionless_redshift()): assert z == val @pytest.mark.skipif(not HAS_SCIPY, reason="Cosmology needs scipy") def test_redshift_temperature(): """Test :func:`astropy.cosmology.units.redshift_temperature`.""" cosmo = Planck13.clone(Tcmb0=3 * u.K) default_cosmo = default_cosmology.get() z = 15 * cu.redshift Tcmb = cosmo.Tcmb(z) # 1) Default (without specifying the cosmology) with default_cosmology.set(cosmo): equivalency = cu.redshift_temperature() assert_quantity_allclose(z.to(u.K, equivalency), Tcmb) assert_quantity_allclose(Tcmb.to(cu.redshift, equivalency), z) # showing the answer changes if the cosmology changes # this test uses the default cosmology equivalency = cu.redshift_temperature() assert_quantity_allclose(z.to(u.K, equivalency), default_cosmo.Tcmb(z)) assert default_cosmo.Tcmb(z) != Tcmb # 2) Specifying the cosmology equivalency = cu.redshift_temperature(cosmo) assert_quantity_allclose(z.to(u.K, equivalency), Tcmb) assert_quantity_allclose(Tcmb.to(cu.redshift, equivalency), z) # Test `atzkw` equivalency = cu.redshift_temperature(cosmo, ztol=1e-10) assert_quantity_allclose(Tcmb.to(cu.redshift, equivalency), z) @pytest.mark.skipif(not HAS_SCIPY, reason="Cosmology needs scipy") def test_redshift_hubble(): """Test :func:`astropy.cosmology.units.redshift_hubble`.""" unit = u.km / u.s / u.Mpc cosmo = Planck13.clone(H0=100 * unit) default_cosmo = default_cosmology.get() z = 15 * cu.redshift H = cosmo.H(z) h = H.to_value(u.km/u.s/u.Mpc) / 100 * cu.littleh # 1) Default (without specifying the cosmology) with default_cosmology.set(cosmo): equivalency = cu.redshift_hubble() # H assert_quantity_allclose(z.to(unit, equivalency), H) assert_quantity_allclose(H.to(cu.redshift, equivalency), z) # little-h assert_quantity_allclose(z.to(cu.littleh, equivalency), h) assert_quantity_allclose(h.to(cu.redshift, equivalency), z) # showing the answer changes if the cosmology changes # this test uses the default cosmology equivalency = cu.redshift_hubble() assert_quantity_allclose(z.to(unit, equivalency), default_cosmo.H(z)) assert default_cosmo.H(z) != H # 2) Specifying the cosmology equivalency = cu.redshift_hubble(cosmo) # H assert_quantity_allclose(z.to(unit, equivalency), H) assert_quantity_allclose(H.to(cu.redshift, equivalency), z) # little-h assert_quantity_allclose(z.to(cu.littleh, equivalency), h) assert_quantity_allclose(h.to(cu.redshift, equivalency), z) # Test `atzkw` equivalency = cu.redshift_hubble(cosmo, ztol=1e-10) assert_quantity_allclose(H.to(cu.redshift, equivalency), z) # H assert_quantity_allclose(h.to(cu.redshift, equivalency), z) # little-h @pytest.mark.skipif(not HAS_SCIPY, reason="Cosmology needs scipy") @pytest.mark.parametrize( "kind", [cu.redshift_distance.__defaults__[-1], "comoving", "lookback", "luminosity"] ) def test_redshift_distance(kind): """Test :func:`astropy.cosmology.units.redshift_distance`.""" z = 15 * cu.redshift d = getattr(Planck13, kind + "_distance")(z) equivalency = cu.redshift_distance(cosmology=Planck13, kind=kind) # properties of Equivalency assert equivalency.name[0] == "redshift_distance" assert equivalency.kwargs[0]["cosmology"] == Planck13 assert equivalency.kwargs[0]["distance"] == kind # roundtrip assert_quantity_allclose(z.to(u.Mpc, equivalency), d) assert_quantity_allclose(d.to(cu.redshift, equivalency), z) def test_redshift_distance_wrong_kind(): """Test :func:`astropy.cosmology.units.redshift_distance` wrong kind.""" with pytest.raises(ValueError, match="`kind`"): cu.redshift_distance(kind=None) @pytest.mark.skipif(not HAS_SCIPY, reason="Cosmology needs scipy") class Test_with_redshift: """Test `astropy.cosmology.units.with_redshift`.""" @pytest.fixture def cosmo(self): """Test cosmology.""" return Planck13.clone(Tcmb0=3 * u.K) # =========================================== def test_cosmo_different(self, cosmo): """The default is different than the test cosmology.""" default_cosmo = default_cosmology.get() assert default_cosmo != cosmo # shows changing default def test_no_equivalency(self, cosmo): """Test the equivalency ``with_redshift`` without any enabled.""" equivalency = cu.with_redshift(distance=None, hubble=False, Tcmb=False) assert len(equivalency) == 0 # ------------------------------------------- def test_temperature_off(self, cosmo): """Test ``with_redshift`` with the temperature off.""" default_cosmo = default_cosmology.get() z = 15 * cu.redshift Tcmb = cosmo.Tcmb(z) # 1) Default (without specifying the cosmology) with default_cosmology.set(cosmo): equivalency = cu.with_redshift(Tcmb=False) with pytest.raises(u.UnitConversionError, match="'redshift' and 'K'"): z.to(u.K, equivalency) # 2) Specifying the cosmology equivalency = cu.with_redshift(cosmo, Tcmb=False) with pytest.raises(u.UnitConversionError, match="'redshift' and 'K'"): z.to(u.K, equivalency) def test_temperature(self, cosmo): """Test temperature equivalency component.""" default_cosmo = default_cosmology.get() z = 15 * cu.redshift Tcmb = cosmo.Tcmb(z) # 1) Default (without specifying the cosmology) with default_cosmology.set(cosmo): equivalency = cu.with_redshift(Tcmb=True) assert_quantity_allclose(z.to(u.K, equivalency), Tcmb) assert_quantity_allclose(Tcmb.to(cu.redshift, equivalency), z) # showing the answer changes if the cosmology changes # this test uses the default cosmology equivalency = cu.with_redshift(Tcmb=True) assert_quantity_allclose(z.to(u.K, equivalency), default_cosmo.Tcmb(z)) assert default_cosmo.Tcmb(z) != Tcmb # 2) Specifying the cosmology equivalency = cu.with_redshift(cosmo, Tcmb=True) assert_quantity_allclose(z.to(u.K, equivalency), Tcmb) assert_quantity_allclose(Tcmb.to(cu.redshift, equivalency), z) # Test `atzkw` # this is really just a test that 'atzkw' doesn't fail equivalency = cu.with_redshift(cosmo, Tcmb=True, atzkw={"ztol": 1e-10}) assert_quantity_allclose(Tcmb.to(cu.redshift, equivalency), z) # ------------------------------------------- def test_hubble_off(self, cosmo): """Test ``with_redshift`` with Hubble off.""" unit = u.km / u.s / u.Mpc default_cosmo = default_cosmology.get() z = 15 * cu.redshift H = cosmo.H(z) # 1) Default (without specifying the cosmology) with default_cosmology.set(cosmo): equivalency = cu.with_redshift(hubble=False) with pytest.raises(u.UnitConversionError, match="'redshift' and 'km / "): z.to(unit, equivalency) # 2) Specifying the cosmology equivalency = cu.with_redshift(cosmo, hubble=False) with pytest.raises(u.UnitConversionError, match="'redshift' and 'km / "): z.to(unit, equivalency) def test_hubble(self, cosmo): """Test Hubble equivalency component.""" unit = u.km/u.s/u.Mpc default_cosmo = default_cosmology.get() z = 15 * cu.redshift H = cosmo.H(z) h = H.to_value(u.km / u.s / u.Mpc) / 100 * cu.littleh # 1) Default (without specifying the cosmology) with default_cosmology.set(cosmo): equivalency = cu.with_redshift(hubble=True) # H assert_quantity_allclose(z.to(unit, equivalency), H) assert_quantity_allclose(H.to(cu.redshift, equivalency), z) # little-h assert_quantity_allclose(z.to(cu.littleh, equivalency), h) assert_quantity_allclose(h.to(cu.redshift, equivalency), z) # showing the answer changes if the cosmology changes # this test uses the default cosmology equivalency = cu.with_redshift(hubble=True) assert_quantity_allclose(z.to(unit, equivalency), default_cosmo.H(z)) assert default_cosmo.H(z) != H # 2) Specifying the cosmology equivalency = cu.with_redshift(cosmo, hubble=True) # H assert_quantity_allclose(z.to(unit, equivalency), H) assert_quantity_allclose(H.to(cu.redshift, equivalency), z) # little-h assert_quantity_allclose(z.to(cu.littleh, equivalency), h) assert_quantity_allclose(h.to(cu.redshift, equivalency), z) # Test `atzkw` # this is really just a test that 'atzkw' doesn't fail equivalency = cu.with_redshift(cosmo, hubble=True, atzkw={"ztol": 1e-10}) assert_quantity_allclose(H.to(cu.redshift, equivalency), z) # H assert_quantity_allclose(h.to(cu.redshift, equivalency), z) # h # ------------------------------------------- def test_distance_off(self, cosmo): """Test ``with_redshift`` with the distance off.""" default_cosmo = default_cosmology.get() z = 15 * cu.redshift # 1) Default (without specifying the cosmology) with default_cosmology.set(cosmo): equivalency = cu.with_redshift(distance=None) with pytest.raises(u.UnitConversionError, match="'redshift' and 'Mpc'"): z.to(u.Mpc, equivalency) # 2) Specifying the cosmology equivalency = cu.with_redshift(cosmo, distance=None) with pytest.raises(u.UnitConversionError, match="'redshift' and 'Mpc'"): z.to(u.Mpc, equivalency) def test_distance_default(self): """Test distance equivalency default.""" z = 15 * cu.redshift d = default_cosmology.get().comoving_distance(z) equivalency = cu.with_redshift() assert_quantity_allclose(z.to(u.Mpc, equivalency), d) assert_quantity_allclose(d.to(cu.redshift, equivalency), z) def test_distance_wrong_kind(self): """Test distance equivalency, but the wrong kind.""" with pytest.raises(ValueError, match="`kind`"): cu.with_redshift(distance=ValueError) @pytest.mark.parametrize("kind", ["comoving", "lookback", "luminosity"]) def test_distance(self, kind): """Test distance equivalency.""" cosmo = Planck13 z = 15 * cu.redshift dist = getattr(cosmo, kind + "_distance")(z) default_cosmo = default_cosmology.get() assert default_cosmo != cosmo # shows changing default # 1) without specifying the cosmology with default_cosmology.set(cosmo): equivalency = cu.with_redshift(distance=kind) assert_quantity_allclose(z.to(u.Mpc, equivalency), dist) # showing the answer changes if the cosmology changes # this test uses the default cosmology equivalency = cu.with_redshift(distance=kind) assert_quantity_allclose(z.to(u.Mpc, equivalency), getattr(default_cosmo, kind + "_distance")(z)) assert not u.allclose(getattr(default_cosmo, kind + "_distance")(z), dist) # 2) Specifying the cosmology equivalency = cu.with_redshift(cosmo, distance=kind) assert_quantity_allclose(z.to(u.Mpc, equivalency), dist) assert_quantity_allclose(dist.to(cu.redshift, equivalency), z) # Test atzkw # this is really just a test that 'atzkw' doesn't fail equivalency = cu.with_redshift(cosmo, distance=kind, atzkw={"ztol": 1e-10}) assert_quantity_allclose(dist.to(cu.redshift, equivalency), z) # FIXME! get "dimensionless_redshift", "with_redshift" to work in this # they are not in ``astropy.units.equivalencies``, so the following fails @pytest.mark.skipif(not HAS_ASDF, reason="requires ASDF") @pytest.mark.parametrize("equiv", [cu.with_H0]) def test_equivalencies_asdf(tmpdir, equiv, recwarn): from asdf.tests import helpers tree = {"equiv": equiv()} helpers.assert_roundtrip_tree(tree, tmpdir) def test_equivalency_context_manager(): base_registry = u.get_current_unit_registry() # check starting with only the dimensionless_redshift equivalency. assert len(base_registry.equivalencies) == 1 assert str(base_registry.equivalencies[0][0]) == "redshift" @pytest.mark.skipif(not HAS_SCIPY, reason = "Cosmology needs scipy") class Test_unsuitable_units: """Ensure that unsuitable units are rejected""" def test_scalar(self): with pytest.raises(u.UnitConversionError): Planck13.Om(0. * u.m) @pytest.mark.parametrize('method', ['Om', 'Ob', 'Odm', 'Ode', 'Ogamma', 'Onu', 'Tcmb', 'Tnu', 'scale_factor', 'angular_diameter_distance', 'luminosity_distance']) def test_unit_exception(self, method): with pytest.raises(u.UnitConversionError): getattr(Planck13, method)([0., 1.] * u.m) @pytest.mark.parametrize('method', ['_EdS_age', '_flat_age', '_dS_lookback_time', 'efunc', 'inv_efunc', 'Ok']) def test_LambdaCDM_unit_exception(self, method): LambdaCDMTest = flrw.LambdaCDM(70.0, 0.3, 0.5) with pytest.raises(u.UnitConversionError): getattr(LambdaCDMTest, method)([0., 1.] * u.m) @pytest.mark.parametrize('method', ['efunc', 'inv_efunc']) def test_FlatLambdaCDM_unit_exception(self, method): FlatLambdaCDMTest = flrw.FlatLambdaCDM(70.0, 0.3) with pytest.raises(u.UnitConversionError): getattr(FlatLambdaCDMTest, method)([0., 1.] * u.m) @pytest.mark.parametrize('method', ['de_density_scale', 'efunc', 'inv_efunc']) def test_wCDM_unit_exception(self, method): wCDMTest = flrw.wCDM(60.0, 0.27, 0.6, w0 = -0.8) with pytest.raises(u.UnitConversionError): getattr(wCDMTest, method)([0., 1.] * u.m) @pytest.mark.parametrize('method', ['efunc', 'inv_efunc']) def test_FlatwCDM_unit_exception(self, method): FlatwCDMTest = flrw.FlatwCDM(65.0, 0.27, w0 = -0.6) with pytest.raises(u.UnitConversionError): getattr(FlatwCDMTest, method)([0., 1.] * u.m) @pytest.mark.parametrize('method', ['w', 'de_density_scale']) def test_w0waCDM_unit_exception(self, method): w0waCDMTest = flrw.w0waCDM(H0 = 70, Om0 = 0.27, Ode0 = 0.5, w0 = -1.2, wa = -0.2) with pytest.raises(u.UnitConversionError): getattr(w0waCDMTest, method)([0., 1.] * u.m) @pytest.mark.parametrize('method', ['w', 'de_density_scale']) def test_wpwaCDM_unit_exception(self, method): wpwaCDMTest = flrw.wpwaCDM(H0 = 70, Om0 = 0.27, Ode0 = 0.5, wp = -1.2, wa = -0.2, zp = 0.9) with pytest.raises(u.UnitConversionError): getattr(wpwaCDMTest, method)([0., 1.] * u.m) @pytest.mark.parametrize('method', ['w', 'de_density_scale']) def test_w0wzCDM14_unit_exception(self, method): w0wzCDMTest = flrw.w0wzCDM(H0 = 70, Om0 = 0.27, Ode0 = 0.5, w0 = -1.2, wz = 0.1) with pytest.raises(u.UnitConversionError): getattr(w0wzCDMTest, method)([0., 1.] * u.m) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/tests/test_utils.py0000644000175100001710000000443000000000000021675 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst from math import inf import pytest import numpy as np from astropy.cosmology.utils import inf_like, vectorize_if_needed, vectorize_redshift_method from astropy.utils.exceptions import AstropyDeprecationWarning def test_vectorize_redshift_method(): """Test :func:`astropy.cosmology.utils.vectorize_redshift_method`.""" class Class: @vectorize_redshift_method def method(self, z): return z c = Class() assert hasattr(c.method, "__vectorized__") assert isinstance(c.method.__vectorized__, np.vectorize) # calling with Number assert c.method(1) == 1 assert isinstance(c.method(1), int) # calling with a numpy scalar assert c.method(np.float64(1)) == np.float64(1) assert isinstance(c.method(np.float64(1)), np.float64) # numpy array assert all(c.method(np.array([1, 2])) == np.array([1, 2])) assert isinstance(c.method(np.array([1, 2])), np.ndarray) # non-scalar assert all(c.method([1, 2]) == np.array([1, 2])) assert isinstance(c.method([1, 2]), np.ndarray) def test_vectorize_if_needed(): """ Test :func:`astropy.cosmology.utils.vectorize_if_needed`. There's no need to test 'veckw' because that is directly pasased to `numpy.vectorize` which thoroughly tests the various inputs. """ func = lambda x: x ** 2 with pytest.warns(AstropyDeprecationWarning): # not vectorized assert vectorize_if_needed(func, 2) == 4 # vectorized assert all(vectorize_if_needed(func, [2, 3]) == [4, 9]) @pytest.mark.parametrize("arr, expected", [(0.0, inf), # float scalar (1, inf), # integer scalar should give float output ([0.0, 1.0, 2.0, 3.0], (inf, inf, inf, inf)), ([0, 1, 2, 3], (inf, inf, inf, inf)), # integer list ]) def test_inf_like(arr, expected): """ Test :func:`astropy.cosmology.utils.inf_like`. All inputs should give a float output. These tests are also in the docstring, but it's better to have them also in one consolidated location. """ with pytest.warns(AstropyDeprecationWarning): assert np.all(inf_like(arr) == expected) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/units.py0000644000175100001710000003125200000000000017500 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """Cosmological units and equivalencies. """ # (newline needed for unit summary) import astropy.units as u from astropy.units.utils import generate_unit_summary as _generate_unit_summary __all__ = ["littleh", "redshift", # redshift equivalencies "dimensionless_redshift", "with_redshift", "redshift_distance", "redshift_hubble", "redshift_temperature", # other equivalencies "with_H0"] __doctest_requires__ = {('with_redshift', 'redshift_distance'): ['scipy']} _ns = globals() ############################################################################### # Cosmological Units # This is not formally a unit, but is used in that way in many contexts, and # an appropriate equivalency is only possible if it's treated as a unit. redshift = u.def_unit(['redshift'], prefixes=False, namespace=_ns, doc="Cosmological redshift.", format={'latex': r''}) # This is not formally a unit, but is used in that way in many contexts, and # an appropriate equivalency is only possible if it's treated as a unit (see # https://arxiv.org/pdf/1308.4150.pdf for more) # Also note that h or h100 or h_100 would be a better name, but they either # conflict or have numbers in them, which is disallowed littleh = u.def_unit(['littleh'], namespace=_ns, prefixes=False, doc='Reduced/"dimensionless" Hubble constant', format={'latex': r'h_{100}'}) ############################################################################### # Equivalencies def dimensionless_redshift(): """Allow redshift to be 1-to-1 equivalent to dimensionless. It is special compared to other equivalency pairs in that it allows this independent of the power to which the redshift is raised, and independent of whether it is part of a more complicated unit. It is similar to u.dimensionless_angles() in this respect. """ return u.Equivalency([(redshift, None)], "dimensionless_redshift") def redshift_distance(cosmology=None, kind="comoving", **atzkw): """Convert quantities between redshift and distance. Care should be taken to not misinterpret a relativistic, gravitational, etc redshift as a cosmological one. Parameters ---------- cosmology : `~astropy.cosmology.Cosmology`, str, or None, optional A cosmology realization or built-in cosmology's name (e.g. 'Planck18'). If None, will use the default cosmology (controlled by :class:`~astropy.cosmology.default_cosmology`). kind : {'comoving', 'lookback', 'luminosity'} or None, optional The distance type for the Equivalency. Note this does NOT include the angular diameter distance as this distance measure is not monotonic. **atzkw keyword arguments for :func:`~astropy.cosmology.z_at_value` Returns ------- `~astropy.units.equivalencies.Equivalency` Equivalency between redshift and temperature. Examples -------- >>> import astropy.units as u >>> import astropy.cosmology.units as cu >>> from astropy.cosmology import WMAP9 >>> z = 1100 * cu.redshift >>> z.to(u.Mpc, cu.redshift_distance(WMAP9, kind="comoving")) # doctest: +FLOAT_CMP """ from astropy.cosmology import default_cosmology, z_at_value # get cosmology: None -> default and process str / class cosmology = cosmology if cosmology is not None else default_cosmology.get() with default_cosmology.set(cosmology): # if already cosmo, passes through cosmology = default_cosmology.get() allowed_kinds = ('comoving', 'lookback', 'luminosity') if kind not in allowed_kinds: raise ValueError(f"`kind` is not one of {allowed_kinds}") method = getattr(cosmology, kind + "_distance") def z_to_distance(z): """Redshift to distance.""" return method(z) def distance_to_z(d): """Distance to redshift.""" return z_at_value(method, d << u.Mpc, **atzkw) return u.Equivalency([(redshift, u.Mpc, z_to_distance, distance_to_z)], "redshift_distance", {'cosmology': cosmology, "distance": kind}) def redshift_hubble(cosmology=None, **atzkw): """Convert quantities between redshift and Hubble parameter and little-h. Care should be taken to not misinterpret a relativistic, gravitational, etc redshift as a cosmological one. Parameters ---------- cosmology : `~astropy.cosmology.Cosmology`, str, or None, optional A cosmology realization or built-in cosmology's name (e.g. 'Planck18'). If None, will use the default cosmology (controlled by :class:`~astropy.cosmology.default_cosmology`). **atzkw keyword arguments for :func:`~astropy.cosmology.z_at_value` Returns ------- `~astropy.units.equivalencies.Equivalency` Equivalency between redshift and Hubble parameter and little-h unit. Examples -------- >>> import astropy.units as u >>> import astropy.cosmology.units as cu >>> from astropy.cosmology import WMAP9 >>> z = 1100 * cu.redshift >>> equivalency = cu.redshift_hubble(WMAP9) # construct equivalency >>> z.to(u.km / u.s / u.Mpc, equivalency) # doctest: +FLOAT_CMP >>> z.to(cu.littleh, equivalency) # doctest: +FLOAT_CMP """ from astropy.cosmology import default_cosmology, z_at_value # get cosmology: None -> default and process str / class cosmology = cosmology if cosmology is not None else default_cosmology.get() with default_cosmology.set(cosmology): # if already cosmo, passes through cosmology = default_cosmology.get() def z_to_hubble(z): """Redshift to Hubble parameter.""" return cosmology.H(z) def hubble_to_z(H): """Hubble parameter to redshift.""" return z_at_value(cosmology.H, H << (u.km / u.s / u.Mpc), **atzkw) def z_to_littleh(z): """Redshift to :math:`h`-unit Quantity.""" return z_to_hubble(z).to_value(u.km / u.s / u.Mpc) / 100 * littleh def littleh_to_z(h): """:math:`h`-unit Quantity to redshift.""" return hubble_to_z(h * 100) return u.Equivalency([(redshift, u.km / u.s / u.Mpc, z_to_hubble, hubble_to_z), (redshift, littleh, z_to_littleh, littleh_to_z)], "redshift_hubble", {'cosmology': cosmology}) def redshift_temperature(cosmology=None, **atzkw): """Convert quantities between redshift and CMB temperature. Care should be taken to not misinterpret a relativistic, gravitational, etc redshift as a cosmological one. Parameters ---------- cosmology : `~astropy.cosmology.Cosmology`, str, or None, optional A cosmology realization or built-in cosmology's name (e.g. 'Planck18'). If None, will use the default cosmology (controlled by :class:`~astropy.cosmology.default_cosmology`). **atzkw keyword arguments for :func:`~astropy.cosmology.z_at_value` Returns ------- `~astropy.units.equivalencies.Equivalency` Equivalency between redshift and temperature. Examples -------- >>> import astropy.units as u >>> import astropy.cosmology.units as cu >>> from astropy.cosmology import WMAP9 >>> z = 1100 * cu.redshift >>> z.to(u.K, cu.redshift_temperature(WMAP9)) """ from astropy.cosmology import default_cosmology, z_at_value # get cosmology: None -> default and process str / class cosmology = cosmology if cosmology is not None else default_cosmology.get() with default_cosmology.set(cosmology): # if already cosmo, passes through cosmology = default_cosmology.get() def z_to_Tcmb(z): return cosmology.Tcmb(z) def Tcmb_to_z(T): return z_at_value(cosmology.Tcmb, T << u.K, **atzkw) return u.Equivalency([(redshift, u.K, z_to_Tcmb, Tcmb_to_z)], "redshift_temperature", {'cosmology': cosmology}) def with_redshift(cosmology=None, *, distance="comoving", hubble=True, Tcmb=True, atzkw=None): """Convert quantities between measures of cosmological distance. Note: by default all equivalencies are on and must be explicitly turned off. Care should be taken to not misinterpret a relativistic, gravitational, etc redshift as a cosmological one. Parameters ---------- cosmology : `~astropy.cosmology.Cosmology`, str, or None, optional A cosmology realization or built-in cosmology's name (e.g. 'Planck18'). If `None`, will use the default cosmology (controlled by :class:`~astropy.cosmology.default_cosmology`). distance : {'comoving', 'lookback', 'luminosity'} or None (optional, keyword-only) The type of distance equivalency to create or `None`. Default is 'comoving'. hubble : bool (optional, keyword-only) Whether to create a Hubble parameter <-> redshift equivalency, using ``Cosmology.H``. Default is `True`. Tcmb : bool (optional, keyword-only) Whether to create a CMB temperature <-> redshift equivalency, using ``Cosmology.Tcmb``. Default is `True`. atzkw : dict or None (optional, keyword-only) keyword arguments for :func:`~astropy.cosmology.z_at_value` Returns ------- `~astropy.units.equivalencies.Equivalency` With equivalencies between redshift and distance / Hubble / temperature. Examples -------- >>> import astropy.units as u >>> import astropy.cosmology.units as cu >>> from astropy.cosmology import WMAP9 >>> equivalency = cu.with_redshift(WMAP9) >>> z = 1100 * cu.redshift Redshift to (comoving) distance: >>> z.to(u.Mpc, equivalency) # doctest: +FLOAT_CMP Redshift to the Hubble parameter: >>> z.to(u.km / u.s / u.Mpc, equivalency) # doctest: +FLOAT_CMP >>> z.to(cu.littleh, equivalency) # doctest: +FLOAT_CMP Redshift to CMB temperature: >>> z.to(u.K, equivalency) """ from astropy.cosmology import default_cosmology, z_at_value # get cosmology: None -> default and process str / class cosmology = cosmology if cosmology is not None else default_cosmology.get() with default_cosmology.set(cosmology): # if already cosmo, passes through cosmology = default_cosmology.get() atzkw = atzkw if atzkw is not None else {} equivs = [] # will append as built # Hubble <-> Redshift if hubble: equivs.extend(redshift_hubble(cosmology, **atzkw)) # CMB Temperature <-> Redshift if Tcmb: equivs.extend(redshift_temperature(cosmology, **atzkw)) # Distance <-> Redshift, but need to choose which distance if distance is not None: equivs.extend(redshift_distance(cosmology, kind=distance, **atzkw)) # ----------- return u.Equivalency(equivs, "with_redshift", {'cosmology': cosmology, 'distance': distance, 'hubble': hubble, 'Tcmb': Tcmb}) # =================================================================== def with_H0(H0=None): """ Convert between quantities with little-h and the equivalent physical units. Parameters ---------- H0 : None or `~astropy.units.Quantity` ['frequency'] The value of the Hubble constant to assume. If a `~astropy.units.Quantity`, will assume the quantity *is* ``H0``. If `None` (default), use the ``H0`` attribute from :mod:`~astropy.cosmology.default_cosmology`. References ---------- For an illuminating discussion on why you may or may not want to use little-h at all, see https://arxiv.org/pdf/1308.4150.pdf """ if H0 is None: from .realizations import default_cosmology H0 = default_cosmology.get().H0 h100_val_unit = u.Unit(100/(H0.to_value(u.km / u.s / u.Mpc)) * littleh) return u.Equivalency([(h100_val_unit, None)], "with_H0", kwargs={"H0": H0}) # =================================================================== # Enable the set of default equivalencies. # If the cosmology package is imported, this is added to the list astropy-wide. u.add_enabled_equivalencies(dimensionless_redshift()) # ============================================================================= # DOCSTRING # This generates a docstring for this module that describes all of the # standard units defined here. if __doc__ is not None: __doc__ += _generate_unit_summary(_ns) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/cosmology/utils.py0000644000175100001710000001053100000000000017473 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import functools from math import inf from numbers import Number import numpy as np from astropy.units import Quantity from astropy.utils import isiterable from astropy.utils.decorators import deprecated from . import units as cu __all__ = [] # nothing is publicly scoped __doctest_skip__ = ["inf_like", "vectorize_if_needed"] def vectorize_redshift_method(func=None, nin=1): """Vectorize a method of redshift(s). Parameters ---------- func : callable or None method to wrap. If `None` returns a :func:`functools.partial` with ``nin`` loaded. nin : int Number of positional redshift arguments. Returns ------- wrapper : callable :func:`functools.wraps` of ``func`` where the first ``nin`` arguments are converted from |Quantity| to :class:`numpy.ndarray`. """ # allow for pie-syntax & setting nin if func is None: return functools.partial(vectorize_redshift_method, nin=nin) @functools.wraps(func) def wrapper(self, *args, **kwargs): """ :func:`functools.wraps` of ``func`` where the first ``nin`` arguments are converted from |Quantity| to `numpy.ndarray` or scalar. """ # process inputs # TODO! quantity-aware vectorization can simplify this. zs = [z if not isinstance(z, Quantity) else z.to_value(cu.redshift) for z in args[:nin]] # scalar inputs if all(isinstance(z, (Number, np.generic)) for z in zs): return func(self, *zs, *args[nin:], **kwargs) # non-scalar. use vectorized func return wrapper.__vectorized__(self, *zs, *args[nin:], **kwargs) wrapper.__vectorized__ = np.vectorize(func) # attach vectorized function # TODO! use frompyfunc when can solve return type errors return wrapper @deprecated( since="5.0", message="vectorize_if_needed has been removed because it constructs a new ufunc on each call", alternative="use a pre-vectorized function instead for a target array 'z'" ) def vectorize_if_needed(f, *x, **vkw): """Helper function to vectorize scalar functions on array inputs. Parameters ---------- f : callable 'f' must accept positional arguments and no mandatory keyword arguments. *x Arguments into ``f``. **vkw Keyword arguments into :class:`numpy.vectorize`. Examples -------- >>> func = lambda x: x ** 2 >>> vectorize_if_needed(func, 2) 4 >>> vectorize_if_needed(func, [2, 3]) array([4, 9]) """ return np.vectorize(f, **vkw)(*x) if any(map(isiterable, x)) else f(*x) @deprecated( since="5.0", message="inf_like has been removed because it duplicates functionality provided by numpy.full_like()", alternative="Use numpy.full_like(z, numpy.inf) instead for a target array 'z'" ) def inf_like(x): """Return the shape of x with value infinity and dtype='float'. Preserves 'shape' for both array and scalar inputs. But always returns a float array, even if x is of integer type. Parameters ---------- x : scalar or array-like Must work with functions `numpy.isscalar` and `numpy.full_like` (if `x` is not a scalar` Returns ------- `math.inf` or ndarray[float] thereof Returns a scalar `~math.inf` if `x` is a scalar, an array of floats otherwise. Examples -------- >>> inf_like(0.) # float scalar inf >>> inf_like(1) # integer scalar should give float output inf >>> inf_like([0., 1., 2., 3.]) # float list array([inf, inf, inf, inf]) >>> inf_like([0, 1, 2, 3]) # integer list should give float output array([inf, inf, inf, inf]) """ return inf if np.isscalar(x) else np.full_like(x, inf, dtype=float) def aszarr(z): """ Redshift as a `~numbers.Number` or `~numpy.ndarray` / |Quantity| / |Column|. Allows for any ndarray ducktype by checking for attribute "shape". """ if isinstance(z, (Number, np.generic)): # scalars return z elif hasattr(z, "shape"): # ducktypes NumPy array if hasattr(z, "unit"): # Quantity Column return (z << cu.redshift).value # for speed only use enabled equivs return z # not one of the preferred types: Number / array ducktype return Quantity(z, cu.redshift).value ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.0952451 astropy-5.0.2/astropy/extern/0000755000175100001710000000000000000000000015253 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/extern/README.rst0000644000175100001710000000567100000000000016753 0ustar00vstsdockerastropy.extern ============== This sub-package contains third-party Python packages/modules that are required for some of Astropy's core functionality. It also contains third- party JavaScript libraries used for browser-based features. In particular, this currently includes for Python: - ConfigObj_: This provides the core config file handling for Astropy's configuration system. - PLY_: This is a parser generator providing lex/yacc-like tools in Python. It is used for Astropy's unit parsing and angle/coordinate string parsing. And for JavaScript: - jQuery_: This is used currently for the browser-based table viewer feature. - DataTables_: This is a plug-in for jQuery used also for the browser-based table viewer. Notes for developers -------------------- jQuery/DataTables ^^^^^^^^^^^^^^^^^ The minified files are the ones that are used in the table viewer feature, but the non-minified versions are also present in the ``js/`` sub-directory for packaging reasons. These files must also be distributed, to provide the source files from which the minified ones can be compiled. This is a requirement for Linux distributions such as Debian and Fedora. Notes for third-party packagers ------------------------------- Packagers preparing Astropy for inclusion in packaging frameworks have different options for how to handle these third-party extern packages, if they would prefer to use their system packages rather than the bundled versions. jQuery/DataTables ^^^^^^^^^^^^^^^^^ Packagers may either use system copies of these JavaScript modules, or require use of online versions (perhaps via URLs of cloud-hosted versions of these modules). It is possible to change the default urls for the remote versions of these files by using the Astropy `Configuration system `_. The default configuration file (``$HOME/.astropy/config``) contains a commented section ``[table.jsviewer]`` with two items for jQuery and DataTables. It is also possible to display the default value and modify it by importing the configuration module:: In [1]: from astropy.table.jsviewer import conf In [2]: conf.jquery_url Out[2]: u'https://code.jquery.com/jquery-1.11.3.min.js' In [3]: conf.jquery_url = '...' Third-party packagers can override the defaults for these configuration items (by modifying the configuration objects in ``astropy/table/jsviewer.py``, or provide astropy config files that include the overrides appropriate for the packaged version. They would *also* need to set the default ``use_local_files`` option to ``False`` for these settings to be read. Other ^^^^^ To replace any of the other Python modules included in this package, simply remove them and update any imports in Astropy to import the system versions rather than the bundled copies. .. _ConfigObj: https://github.com/DiffSK/configobj .. _PLY: http://www.dabeaz.com/ply/ .. _jQuery: http://jquery.com/ .. _DataTables: http://www.datatables.net/ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/extern/__init__.py0000644000175100001710000000071100000000000017363 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This packages contains python packages that are bundled with Astropy but are external to Astropy, and hence are developed in a separate source tree. Note that this package is distinct from the /cextern directory of the source code distribution, as that directory only contains C extension code. See the README.rst in this directory of the Astropy source repository for more details. """ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/extern/_strptime.py0000644000175100001710000005376400000000000017652 0ustar00vstsdocker"""Strptime-related classes and functions. CLASSES: LocaleTime -- Discovers and stores locale-specific time information TimeRE -- Creates regexes for pattern matching a string of text containing time information FUNCTIONS: _getlang -- Figure out what language is being used for the locale strptime -- Calculates the time struct represented by the passed-in string """ # ----------------------------------------------------------------------------- # _strptime.py # # Licensed under PYTHON SOFTWARE FOUNDATION LICENSE # See licenses/PYTHON.rst # # Copied from https://github.com/python/cpython/blob/3.5/Lib/_strptime.py # ----------------------------------------------------------------------------- import time import locale import calendar from re import compile as re_compile from re import IGNORECASE from re import escape as re_escape from datetime import (date as datetime_date, timedelta as datetime_timedelta, timezone as datetime_timezone) try: from _thread import allocate_lock as _thread_allocate_lock except ImportError: from _dummy_thread import allocate_lock as _thread_allocate_lock __all__ = [] def _getlang(): # Figure out what the current language is set to. return locale.getlocale(locale.LC_TIME) class LocaleTime(object): """Stores and handles locale-specific information related to time. ATTRIBUTES: f_weekday -- full weekday names (7-item list) a_weekday -- abbreviated weekday names (7-item list) f_month -- full month names (13-item list; dummy value in [0], which is added by code) a_month -- abbreviated month names (13-item list, dummy value in [0], which is added by code) am_pm -- AM/PM representation (2-item list) LC_date_time -- format string for date/time representation (string) LC_date -- format string for date representation (string) LC_time -- format string for time representation (string) timezone -- daylight- and non-daylight-savings timezone representation (2-item list of sets) lang -- Language used by instance (2-item tuple) """ def __init__(self): """Set all attributes. Order of methods called matters for dependency reasons. The locale language is set at the offset and then checked again before exiting. This is to make sure that the attributes were not set with a mix of information from more than one locale. This would most likely happen when using threads where one thread calls a locale-dependent function while another thread changes the locale while the function in the other thread is still running. Proper coding would call for locks to prevent changing the locale while locale-dependent code is running. The check here is done in case someone does not think about doing this. Only other possible issue is if someone changed the timezone and did not call tz.tzset . That is an issue for the programmer, though, since changing the timezone is worthless without that call. """ self.lang = _getlang() self.__calc_weekday() self.__calc_month() self.__calc_am_pm() self.__calc_timezone() self.__calc_date_time() if _getlang() != self.lang: raise ValueError("locale changed during initialization") if time.tzname != self.tzname or time.daylight != self.daylight: raise ValueError("timezone changed during initialization") def __pad(self, seq, front): # Add '' to seq to either the front (is True), else the back. seq = list(seq) if front: seq.insert(0, '') else: seq.append('') return seq def __calc_weekday(self): # Set self.a_weekday and self.f_weekday using the calendar # module. a_weekday = [calendar.day_abbr[i].lower() for i in range(7)] f_weekday = [calendar.day_name[i].lower() for i in range(7)] self.a_weekday = a_weekday self.f_weekday = f_weekday def __calc_month(self): # Set self.f_month and self.a_month using the calendar module. a_month = [calendar.month_abbr[i].lower() for i in range(13)] f_month = [calendar.month_name[i].lower() for i in range(13)] self.a_month = a_month self.f_month = f_month def __calc_am_pm(self): # Set self.am_pm by using time.strftime(). # The magic date (1999,3,17,hour,44,55,2,76,0) is not really that # magical; just happened to have used it everywhere else where a # static date was needed. am_pm = [] for hour in (1, 22): time_tuple = time.struct_time((1999,3,17,hour,44,55,2,76,0)) am_pm.append(time.strftime("%p", time_tuple).lower()) self.am_pm = am_pm def __calc_date_time(self): # Set self.date_time, self.date, & self.time by using # time.strftime(). # Use (1999,3,17,22,44,55,2,76,0) for magic date because the amount of # overloaded numbers is minimized. The order in which searches for # values within the format string is very important; it eliminates # possible ambiguity for what something represents. time_tuple = time.struct_time((1999,3,17,22,44,55,2,76,0)) date_time = [None, None, None] date_time[0] = time.strftime("%c", time_tuple).lower() date_time[1] = time.strftime("%x", time_tuple).lower() date_time[2] = time.strftime("%X", time_tuple).lower() replacement_pairs = [('%', '%%'), (self.f_weekday[2], '%A'), (self.f_month[3], '%B'), (self.a_weekday[2], '%a'), (self.a_month[3], '%b'), (self.am_pm[1], '%p'), ('1999', '%Y'), ('99', '%y'), ('22', '%H'), ('44', '%M'), ('55', '%S'), ('76', '%j'), ('17', '%d'), ('03', '%m'), ('3', '%m'), # '3' needed for when no leading zero. ('2', '%w'), ('10', '%I')] replacement_pairs.extend([(tz, "%Z") for tz_values in self.timezone for tz in tz_values]) for offset,directive in ((0,'%c'), (1,'%x'), (2,'%X')): current_format = date_time[offset] for old, new in replacement_pairs: # Must deal with possible lack of locale info # manifesting itself as the empty string (e.g., Swedish's # lack of AM/PM info) or a platform returning a tuple of empty # strings (e.g., MacOS 9 having timezone as ('','')). if old: current_format = current_format.replace(old, new) # If %W is used, then Sunday, 2005-01-03 will fall on week 0 since # 2005-01-03 occurs before the first Monday of the year. Otherwise # %U is used. time_tuple = time.struct_time((1999,1,3,1,1,1,6,3,0)) if '00' in time.strftime(directive, time_tuple): U_W = '%W' else: U_W = '%U' date_time[offset] = current_format.replace('11', U_W) self.LC_date_time = date_time[0] self.LC_date = date_time[1] self.LC_time = date_time[2] def __calc_timezone(self): # Set self.timezone by using time.tzname. # Do not worry about possibility of time.tzname[0] == time.tzname[1] # and time.daylight; handle that in strptime. try: time.tzset() except AttributeError: pass self.tzname = time.tzname self.daylight = time.daylight no_saving = frozenset({"utc", "gmt", self.tzname[0].lower()}) if self.daylight: has_saving = frozenset({self.tzname[1].lower()}) else: has_saving = frozenset() self.timezone = (no_saving, has_saving) class TimeRE(dict): """Handle conversion from format directives to regexes.""" def __init__(self, locale_time=None): """Create keys/values. Order of execution is important for dependency reasons. """ if locale_time: self.locale_time = locale_time else: self.locale_time = LocaleTime() base = super() base.__init__({ # The " \d" part of the regex is to make %c from ANSI C work 'd': r"(?P3[0-1]|[1-2]\d|0[1-9]|[1-9]| [1-9])", 'f': r"(?P[0-9]{1,6})", 'H': r"(?P2[0-3]|[0-1]\d|\d)", 'I': r"(?P1[0-2]|0[1-9]|[1-9])", 'j': r"(?P36[0-6]|3[0-5]\d|[1-2]\d\d|0[1-9]\d|00[1-9]|[1-9]\d|0[1-9]|[1-9])", 'm': r"(?P1[0-2]|0[1-9]|[1-9])", 'M': r"(?P[0-5]\d|\d)", 'S': r"(?P6[0-1]|[0-5]\d|\d)", 'U': r"(?P5[0-3]|[0-4]\d|\d)", 'w': r"(?P[0-6])", # W is set below by using 'U' 'y': r"(?P\d\d)", #XXX: Does 'Y' need to worry about having less or more than # 4 digits? 'Y': r"(?P\d\d\d\d)", 'z': r"(?P[+-]\d\d[0-5]\d)", 'A': self.__seqToRE(self.locale_time.f_weekday, 'A'), 'a': self.__seqToRE(self.locale_time.a_weekday, 'a'), 'B': self.__seqToRE(self.locale_time.f_month[1:], 'B'), 'b': self.__seqToRE(self.locale_time.a_month[1:], 'b'), 'p': self.__seqToRE(self.locale_time.am_pm, 'p'), 'Z': self.__seqToRE((tz for tz_names in self.locale_time.timezone for tz in tz_names), 'Z'), '%': '%'}) base.__setitem__('W', base.__getitem__('U').replace('U', 'W')) base.__setitem__('c', self.pattern(self.locale_time.LC_date_time)) base.__setitem__('x', self.pattern(self.locale_time.LC_date)) base.__setitem__('X', self.pattern(self.locale_time.LC_time)) def __seqToRE(self, to_convert, directive): """Convert a list to a regex string for matching a directive. Want possible matching values to be from longest to shortest. This prevents the possibility of a match occurring for a value that also a substring of a larger value that should have matched (e.g., 'abc' matching when 'abcdef' should have been the match). """ to_convert = sorted(to_convert, key=len, reverse=True) for value in to_convert: if value != '': break else: return '' regex = '|'.join(re_escape(stuff) for stuff in to_convert) regex = '(?P<%s>%s' % (directive, regex) return '%s)' % regex def pattern(self, format): """Return regex pattern for the format string. Need to make sure that any characters that might be interpreted as regex syntax are escaped. """ processed_format = '' # The sub() call escapes all characters that might be misconstrued # as regex syntax. Cannot use re.escape since we have to deal with # format directives (%m, etc.). regex_chars = re_compile(r"([\\.^$*+?\(\){}\[\]|])") format = regex_chars.sub(r"\\\1", format) whitespace_replacement = re_compile(r'\s+') format = whitespace_replacement.sub(r'\\s+', format) while '%' in format: directive_index = format.index('%')+1 processed_format = "%s%s%s" % (processed_format, format[:directive_index-1], self[format[directive_index]]) format = format[directive_index+1:] return "%s%s" % (processed_format, format) def compile(self, format): """Return a compiled re object for the format string.""" return re_compile(self.pattern(format), IGNORECASE) _cache_lock = _thread_allocate_lock() # DO NOT modify _TimeRE_cache or _regex_cache without acquiring the cache lock # first! _TimeRE_cache = TimeRE() _CACHE_MAX_SIZE = 5 # Max number of regexes stored in _regex_cache _regex_cache = {} def _calc_julian_from_U_or_W(year, week_of_year, day_of_week, week_starts_Mon): """Calculate the Julian day based on the year, week of the year, and day of the week, with week_start_day representing whether the week of the year assumes the week starts on Sunday or Monday (6 or 0).""" first_weekday = datetime_date(year, 1, 1).weekday() # If we are dealing with the %U directive (week starts on Sunday), it's # easier to just shift the view to Sunday being the first day of the # week. if not week_starts_Mon: first_weekday = (first_weekday + 1) % 7 day_of_week = (day_of_week + 1) % 7 # Need to watch out for a week 0 (when the first day of the year is not # the same as that specified by %U or %W). week_0_length = (7 - first_weekday) % 7 if week_of_year == 0: return 1 + day_of_week - first_weekday else: days_to_week = week_0_length + (7 * (week_of_year - 1)) return 1 + days_to_week + day_of_week def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"): """Return a 2-tuple consisting of a time struct and an int containing the number of microseconds based on the input string and the format string.""" for index, arg in enumerate([data_string, format]): if not isinstance(arg, str): msg = "strptime() argument {} must be str, not {}" raise TypeError(msg.format(index, type(arg))) global _TimeRE_cache, _regex_cache with _cache_lock: locale_time = _TimeRE_cache.locale_time if (_getlang() != locale_time.lang or time.tzname != locale_time.tzname or time.daylight != locale_time.daylight): _TimeRE_cache = TimeRE() _regex_cache.clear() locale_time = _TimeRE_cache.locale_time if len(_regex_cache) > _CACHE_MAX_SIZE: _regex_cache.clear() format_regex = _regex_cache.get(format) if not format_regex: try: format_regex = _TimeRE_cache.compile(format) # KeyError raised when a bad format is found; can be specified as # \\, in which case it was a stray % but with a space after it except KeyError as err: bad_directive = err.args[0] if bad_directive == "\\": bad_directive = "%" del err raise ValueError("'%s' is a bad directive in format '%s'" % (bad_directive, format)) from None # IndexError only occurs when the format string is "%" except IndexError: raise ValueError("stray %% in format '%s'" % format) from None _regex_cache[format] = format_regex found = format_regex.match(data_string) if not found: raise ValueError("time data %r does not match format %r" % (data_string, format)) if len(data_string) != found.end(): raise ValueError("unconverted data remains: %s" % data_string[found.end():]) year = None month = day = 1 hour = minute = second = fraction = 0 tz = -1 tzoffset = None # Default to -1 to signify that values not known; not critical to have, # though week_of_year = -1 week_of_year_start = -1 # weekday and julian defaulted to None so as to signal need to calculate # values weekday = julian = None found_dict = found.groupdict() for group_key in found_dict.keys(): # Directives not explicitly handled below: # c, x, X # handled by making out of other directives # U, W # worthless without day of the week if group_key == 'y': year = int(found_dict['y']) # Open Group specification for strptime() states that a %y #value in the range of [00, 68] is in the century 2000, while #[69,99] is in the century 1900 if year <= 68: year += 2000 else: year += 1900 elif group_key == 'Y': year = int(found_dict['Y']) elif group_key == 'm': month = int(found_dict['m']) elif group_key == 'B': month = locale_time.f_month.index(found_dict['B'].lower()) elif group_key == 'b': month = locale_time.a_month.index(found_dict['b'].lower()) elif group_key == 'd': day = int(found_dict['d']) elif group_key == 'H': hour = int(found_dict['H']) elif group_key == 'I': hour = int(found_dict['I']) ampm = found_dict.get('p', '').lower() # If there was no AM/PM indicator, we'll treat this like AM if ampm in ('', locale_time.am_pm[0]): # We're in AM so the hour is correct unless we're # looking at 12 midnight. # 12 midnight == 12 AM == hour 0 if hour == 12: hour = 0 elif ampm == locale_time.am_pm[1]: # We're in PM so we need to add 12 to the hour unless # we're looking at 12 noon. # 12 noon == 12 PM == hour 12 if hour != 12: hour += 12 elif group_key == 'M': minute = int(found_dict['M']) elif group_key == 'S': second = int(found_dict['S']) elif group_key == 'f': s = found_dict['f'] # Pad to always return microseconds. s += "0" * (6 - len(s)) fraction = int(s) elif group_key == 'A': weekday = locale_time.f_weekday.index(found_dict['A'].lower()) elif group_key == 'a': weekday = locale_time.a_weekday.index(found_dict['a'].lower()) elif group_key == 'w': weekday = int(found_dict['w']) if weekday == 0: weekday = 6 else: weekday -= 1 elif group_key == 'j': julian = int(found_dict['j']) elif group_key in ('U', 'W'): week_of_year = int(found_dict[group_key]) if group_key == 'U': # U starts week on Sunday. week_of_year_start = 6 else: # W starts week on Monday. week_of_year_start = 0 elif group_key == 'z': z = found_dict['z'] tzoffset = int(z[1:3]) * 60 + int(z[3:5]) if z.startswith("-"): tzoffset = -tzoffset elif group_key == 'Z': # Since -1 is default value only need to worry about setting tz if # it can be something other than -1. found_zone = found_dict['Z'].lower() for value, tz_values in enumerate(locale_time.timezone): if found_zone in tz_values: # Deal with bad locale setup where timezone names are the # same and yet time.daylight is true; too ambiguous to # be able to tell what timezone has daylight savings if (time.tzname[0] == time.tzname[1] and time.daylight and found_zone not in ("utc", "gmt")): break else: tz = value break leap_year_fix = False if year is None and month == 2 and day == 29: year = 1904 # 1904 is first leap year of 20th century leap_year_fix = True elif year is None: year = 1900 # If we know the week of the year and what day of that week, we can figure # out the Julian day of the year. if julian is None and week_of_year != -1 and weekday is not None: week_starts_Mon = True if week_of_year_start == 0 else False julian = _calc_julian_from_U_or_W(year, week_of_year, weekday, week_starts_Mon) if julian <= 0: year -= 1 yday = 366 if calendar.isleap(year) else 365 julian += yday # Cannot pre-calculate datetime_date() since can change in Julian # calculation and thus could have different value for the day of the week # calculation. if julian is None: # Need to add 1 to result since first day of the year is 1, not 0. julian = datetime_date(year, month, day).toordinal() - \ datetime_date(year, 1, 1).toordinal() + 1 else: # Assume that if they bothered to include Julian day it will # be accurate. datetime_result = datetime_date.fromordinal((julian - 1) + datetime_date(year, 1, 1).toordinal()) year = datetime_result.year month = datetime_result.month day = datetime_result.day if weekday is None: weekday = datetime_date(year, month, day).weekday() # Add timezone info tzname = found_dict.get("Z") if tzoffset is not None: gmtoff = tzoffset * 60 else: gmtoff = None if leap_year_fix: # the caller didn't supply a year but asked for Feb 29th. We couldn't # use the default of 1900 for computations. We set it back to ensure # that February 29th is smaller than March 1st. year = 1900 return (year, month, day, hour, minute, second, weekday, julian, tz, tzname, gmtoff), fraction def _strptime_time(data_string, format="%a %b %d %H:%M:%S %Y"): """Return a time struct based on the input string and the format string.""" tt = _strptime(data_string, format)[0] return time.struct_time(tt[:time._STRUCT_TM_ITEMS]) def _strptime_datetime(cls, data_string, format="%a %b %d %H:%M:%S %Y"): """Return a class cls instance based on the input string and the format string.""" tt, fraction = _strptime(data_string, format) tzname, gmtoff = tt[-2:] args = tt[:6] + (fraction,) if gmtoff is not None: tzdelta = datetime_timedelta(seconds=gmtoff) if tzname: tz = datetime_timezone(tzdelta, tzname) else: tz = datetime_timezone(tzdelta) args += (tz,) return cls(*args) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.0952451 astropy-5.0.2/astropy/extern/configobj/0000755000175100001710000000000000000000000017213 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/extern/configobj/__init__.py0000644000175100001710000000000000000000000021312 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/extern/configobj/configobj.py0000755000175100001710000025314400000000000021541 0ustar00vstsdocker# configobj.py # A config file reader/writer that supports nested sections in config files. # Copyright (C) 2005-2014: # (name) : (email) # Michael Foord: fuzzyman AT voidspace DOT org DOT uk # Nicola Larosa: nico AT tekNico DOT net # Rob Dennis: rdennis AT gmail DOT com # Eli Courtwright: eli AT courtwright DOT org # This software is licensed under the terms of the BSD license. # http://opensource.org/licenses/BSD-3-Clause # ConfigObj 5 - main repository for documentation and issue tracking: # https://github.com/DiffSK/configobj import os import re import sys from collections.abc import Mapping from codecs import BOM_UTF8, BOM_UTF16, BOM_UTF16_BE, BOM_UTF16_LE # imported lazily to avoid startup performance hit if it isn't used compiler = None # A dictionary mapping BOM to # the encoding to decode with, and what to set the # encoding attribute to. BOMS = { BOM_UTF8: ('utf_8', None), BOM_UTF16_BE: ('utf16_be', 'utf_16'), BOM_UTF16_LE: ('utf16_le', 'utf_16'), BOM_UTF16: ('utf_16', 'utf_16'), } # All legal variants of the BOM codecs. # TODO: the list of aliases is not meant to be exhaustive, is there a # better way ? BOM_LIST = { 'utf_16': 'utf_16', 'u16': 'utf_16', 'utf16': 'utf_16', 'utf-16': 'utf_16', 'utf16_be': 'utf16_be', 'utf_16_be': 'utf16_be', 'utf-16be': 'utf16_be', 'utf16_le': 'utf16_le', 'utf_16_le': 'utf16_le', 'utf-16le': 'utf16_le', 'utf_8': 'utf_8', 'u8': 'utf_8', 'utf': 'utf_8', 'utf8': 'utf_8', 'utf-8': 'utf_8', } # Map of encodings to the BOM to write. BOM_SET = { 'utf_8': BOM_UTF8, 'utf_16': BOM_UTF16, 'utf16_be': BOM_UTF16_BE, 'utf16_le': BOM_UTF16_LE, None: BOM_UTF8 } def match_utf8(encoding): return BOM_LIST.get(encoding.lower()) == 'utf_8' # Quote strings used for writing values squot = "'%s'" dquot = '"%s"' noquot = "%s" wspace_plus = ' \r\n\v\t\'"' tsquot = '"""%s"""' tdquot = "'''%s'''" # Sentinel for use in getattr calls to replace hasattr MISSING = object() __all__ = ( 'DEFAULT_INDENT_TYPE', 'DEFAULT_INTERPOLATION', 'ConfigObjError', 'NestingError', 'ParseError', 'DuplicateError', 'ConfigspecError', 'ConfigObj', 'SimpleVal', 'InterpolationError', 'InterpolationLoopError', 'MissingInterpolationOption', 'RepeatSectionError', 'ReloadError', 'UnreprError', 'UnknownType', 'flatten_errors', 'get_extra_values' ) DEFAULT_INTERPOLATION = 'configparser' DEFAULT_INDENT_TYPE = ' ' MAX_INTERPOL_DEPTH = 10 OPTION_DEFAULTS = { 'interpolation': True, 'raise_errors': False, 'list_values': True, 'create_empty': False, 'file_error': False, 'configspec': None, 'stringify': True, # option may be set to one of ('', ' ', '\t') 'indent_type': None, 'encoding': None, 'default_encoding': None, 'unrepr': False, 'write_empty_values': False, } # this could be replaced if six is used for compatibility, or there are no # more assertions about items being a string def getObj(s): global compiler if compiler is None: import compiler s = "a=" + s p = compiler.parse(s) return p.getChildren()[1].getChildren()[0].getChildren()[1] class UnknownType(Exception): pass class Builder(object): def build(self, o): if m is None: raise UnknownType(o.__class__.__name__) return m(o) def build_List(self, o): return list(map(self.build, o.getChildren())) def build_Const(self, o): return o.value def build_Dict(self, o): d = {} i = iter(map(self.build, o.getChildren())) for el in i: d[el] = next(i) return d def build_Tuple(self, o): return tuple(self.build_List(o)) def build_Name(self, o): if o.name == 'None': return None if o.name == 'True': return True if o.name == 'False': return False # An undefined Name raise UnknownType('Undefined Name') def build_Add(self, o): real, imag = list(map(self.build_Const, o.getChildren())) try: real = float(real) except TypeError: raise UnknownType('Add') if not isinstance(imag, complex) or imag.real != 0.0: raise UnknownType('Add') return real+imag def build_Getattr(self, o): parent = self.build(o.expr) return getattr(parent, o.attrname) def build_UnarySub(self, o): return -self.build_Const(o.getChildren()[0]) def build_UnaryAdd(self, o): return self.build_Const(o.getChildren()[0]) _builder = Builder() def unrepr(s): if not s: return s # this is supposed to be safe import ast return ast.literal_eval(s) class ConfigObjError(SyntaxError): """ This is the base class for all errors that ConfigObj raises. It is a subclass of SyntaxError. """ def __init__(self, message='', line_number=None, line=''): self.line = line self.line_number = line_number SyntaxError.__init__(self, message) class NestingError(ConfigObjError): """ This error indicates a level of nesting that doesn't match. """ class ParseError(ConfigObjError): """ This error indicates that a line is badly written. It is neither a valid ``key = value`` line, nor a valid section marker line. """ class ReloadError(IOError): """ A 'reload' operation failed. This exception is a subclass of ``IOError``. """ def __init__(self): IOError.__init__(self, 'reload failed, filename is not set.') class DuplicateError(ConfigObjError): """ The keyword or section specified already exists. """ class ConfigspecError(ConfigObjError): """ An error occured whilst parsing a configspec. """ class InterpolationError(ConfigObjError): """Base class for the two interpolation errors.""" class InterpolationLoopError(InterpolationError): """Maximum interpolation depth exceeded in string interpolation.""" def __init__(self, option): InterpolationError.__init__( self, 'interpolation loop detected in value "%s".' % option) class RepeatSectionError(ConfigObjError): """ This error indicates additional sections in a section with a ``__many__`` (repeated) section. """ class MissingInterpolationOption(InterpolationError): """A value specified for interpolation was missing.""" def __init__(self, option): msg = 'missing option "%s" in interpolation.' % option InterpolationError.__init__(self, msg) class UnreprError(ConfigObjError): """An error parsing in unrepr mode.""" class InterpolationEngine(object): """ A helper class to help perform string interpolation. This class is an abstract base class; its descendants perform the actual work. """ # compiled regexp to use in self.interpolate() _KEYCRE = re.compile(r"%\(([^)]*)\)s") _cookie = '%' def __init__(self, section): # the Section instance that "owns" this engine self.section = section def interpolate(self, key, value): # short-cut if not self._cookie in value: return value def recursive_interpolate(key, value, section, backtrail): """The function that does the actual work. ``value``: the string we're trying to interpolate. ``section``: the section in which that string was found ``backtrail``: a dict to keep track of where we've been, to detect and prevent infinite recursion loops This is similar to a depth-first-search algorithm. """ # Have we been here already? if (key, section.name) in backtrail: # Yes - infinite loop detected raise InterpolationLoopError(key) # Place a marker on our backtrail so we won't come back here again backtrail[(key, section.name)] = 1 # Now start the actual work match = self._KEYCRE.search(value) while match: # The actual parsing of the match is implementation-dependent, # so delegate to our helper function k, v, s = self._parse_match(match) if k is None: # That's the signal that no further interpolation is needed replacement = v else: # Further interpolation may be needed to obtain final value replacement = recursive_interpolate(k, v, s, backtrail) # Replace the matched string with its final value start, end = match.span() value = ''.join((value[:start], replacement, value[end:])) new_search_start = start + len(replacement) # Pick up the next interpolation key, if any, for next time # through the while loop match = self._KEYCRE.search(value, new_search_start) # Now safe to come back here again; remove marker from backtrail del backtrail[(key, section.name)] return value # Back in interpolate(), all we have to do is kick off the recursive # function with appropriate starting values value = recursive_interpolate(key, value, self.section, {}) return value def _fetch(self, key): """Helper function to fetch values from owning section. Returns a 2-tuple: the value, and the section where it was found. """ # switch off interpolation before we try and fetch anything ! save_interp = self.section.main.interpolation self.section.main.interpolation = False # Start at section that "owns" this InterpolationEngine current_section = self.section while True: # try the current section first val = current_section.get(key) if val is not None and not isinstance(val, Section): break # try "DEFAULT" next val = current_section.get('DEFAULT', {}).get(key) if val is not None and not isinstance(val, Section): break # move up to parent and try again # top-level's parent is itself if current_section.parent is current_section: # reached top level, time to give up break current_section = current_section.parent # restore interpolation to previous value before returning self.section.main.interpolation = save_interp if val is None: raise MissingInterpolationOption(key) return val, current_section def _parse_match(self, match): """Implementation-dependent helper function. Will be passed a match object corresponding to the interpolation key we just found (e.g., "%(foo)s" or "$foo"). Should look up that key in the appropriate config file section (using the ``_fetch()`` helper function) and return a 3-tuple: (key, value, section) ``key`` is the name of the key we're looking for ``value`` is the value found for that key ``section`` is a reference to the section where it was found ``key`` and ``section`` should be None if no further interpolation should be performed on the resulting value (e.g., if we interpolated "$$" and returned "$"). """ raise NotImplementedError() class ConfigParserInterpolation(InterpolationEngine): """Behaves like ConfigParser.""" _cookie = '%' _KEYCRE = re.compile(r"%\(([^)]*)\)s") def _parse_match(self, match): key = match.group(1) value, section = self._fetch(key) return key, value, section class TemplateInterpolation(InterpolationEngine): """Behaves like string.Template.""" _cookie = '$' _delimiter = '$' _KEYCRE = re.compile(r""" \$(?: (?P\$) | # Two $ signs (?P[_a-z][_a-z0-9]*) | # $name format {(?P[^}]*)} # ${name} format ) """, re.IGNORECASE | re.VERBOSE) def _parse_match(self, match): # Valid name (in or out of braces): fetch value from section key = match.group('named') or match.group('braced') if key is not None: value, section = self._fetch(key) return key, value, section # Escaped delimiter (e.g., $$): return single delimiter if match.group('escaped') is not None: # Return None for key and section to indicate it's time to stop return None, self._delimiter, None # Anything else: ignore completely, just return it unchanged return None, match.group(), None interpolation_engines = { 'configparser': ConfigParserInterpolation, 'template': TemplateInterpolation, } def __newobj__(cls, *args): # Hack for pickle return cls.__new__(cls, *args) class Section(dict): """ A dictionary-like object that represents a section in a config file. It does string interpolation if the 'interpolation' attribute of the 'main' object is set to True. Interpolation is tried first from this object, then from the 'DEFAULT' section of this object, next from the parent and its 'DEFAULT' section, and so on until the main object is reached. A Section will behave like an ordered dictionary - following the order of the ``scalars`` and ``sections`` attributes. You can use this to change the order of members. Iteration follows the order: scalars, then sections. """ def __setstate__(self, state): dict.update(self, state[0]) self.__dict__.update(state[1]) def __reduce__(self): state = (dict(self), self.__dict__) return (__newobj__, (self.__class__,), state) def __init__(self, parent, depth, main, indict=None, name=None): """ * parent is the section above * depth is the depth level of this section * main is the main ConfigObj * indict is a dictionary to initialise the section with """ if indict is None: indict = {} dict.__init__(self) # used for nesting level *and* interpolation self.parent = parent # used for the interpolation attribute self.main = main # level of nesting depth of this Section self.depth = depth # purely for information self.name = name # self._initialise() # we do this explicitly so that __setitem__ is used properly # (rather than just passing to ``dict.__init__``) for entry, value in indict.items(): self[entry] = value def _initialise(self): # the sequence of scalar values in this Section self.scalars = [] # the sequence of sections in this Section self.sections = [] # for comments :-) self.comments = {} self.inline_comments = {} # the configspec self.configspec = None # for defaults self.defaults = [] self.default_values = {} self.extra_values = [] self._created = False def _interpolate(self, key, value): try: # do we already have an interpolation engine? engine = self._interpolation_engine except AttributeError: # not yet: first time running _interpolate(), so pick the engine name = self.main.interpolation if name == True: # note that "if name:" would be incorrect here # backwards-compatibility: interpolation=True means use default name = DEFAULT_INTERPOLATION name = name.lower() # so that "Template", "template", etc. all work class_ = interpolation_engines.get(name, None) if class_ is None: # invalid value for self.main.interpolation self.main.interpolation = False return value else: # save reference to engine so we don't have to do this again engine = self._interpolation_engine = class_(self) # let the engine do the actual work return engine.interpolate(key, value) def __getitem__(self, key): """Fetch the item and do string interpolation.""" val = dict.__getitem__(self, key) if self.main.interpolation: if isinstance(val, str): return self._interpolate(key, val) if isinstance(val, list): def _check(entry): if isinstance(entry, str): return self._interpolate(key, entry) return entry new = [_check(entry) for entry in val] if new != val: return new return val def __setitem__(self, key, value, unrepr=False): """ Correctly set a value. Making dictionary values Section instances. (We have to special case 'Section' instances - which are also dicts) Keys must be strings. Values need only be strings (or lists of strings) if ``main.stringify`` is set. ``unrepr`` must be set when setting a value to a dictionary, without creating a new sub-section. """ if not isinstance(key, str): raise ValueError('The key "%s" is not a string.' % key) # add the comment if key not in self.comments: self.comments[key] = [] self.inline_comments[key] = '' # remove the entry from defaults if key in self.defaults: self.defaults.remove(key) # if isinstance(value, Section): if key not in self: self.sections.append(key) dict.__setitem__(self, key, value) elif isinstance(value, Mapping) and not unrepr: # First create the new depth level, # then create the section if key not in self: self.sections.append(key) new_depth = self.depth + 1 dict.__setitem__( self, key, Section( self, new_depth, self.main, indict=value, name=key)) else: if key not in self: self.scalars.append(key) if not self.main.stringify: if isinstance(value, str): pass elif isinstance(value, (list, tuple)): for entry in value: if not isinstance(entry, str): raise TypeError('Value is not a string "%s".' % entry) else: raise TypeError('Value is not a string "%s".' % value) dict.__setitem__(self, key, value) def __delitem__(self, key): """Remove items from the sequence when deleting.""" dict. __delitem__(self, key) if key in self.scalars: self.scalars.remove(key) else: self.sections.remove(key) del self.comments[key] del self.inline_comments[key] def get(self, key, default=None): """A version of ``get`` that doesn't bypass string interpolation.""" try: return self[key] except KeyError: return default def update(self, indict): """ A version of update that uses our ``__setitem__``. """ for entry in indict: self[entry] = indict[entry] def pop(self, key, default=MISSING): """ 'D.pop(k[,d]) -> v, remove specified key and return the corresponding value. If key is not found, d is returned if given, otherwise KeyError is raised' """ try: val = self[key] except KeyError: if default is MISSING: raise val = default else: del self[key] return val def popitem(self): """Pops the first (key,val)""" sequence = (self.scalars + self.sections) if not sequence: raise KeyError(": 'popitem(): dictionary is empty'") key = sequence[0] val = self[key] del self[key] return key, val def clear(self): """ A version of clear that also affects scalars/sections Also clears comments and configspec. Leaves other attributes alone : depth/main/parent are not affected """ dict.clear(self) self.scalars = [] self.sections = [] self.comments = {} self.inline_comments = {} self.configspec = None self.defaults = [] self.extra_values = [] def setdefault(self, key, default=None): """A version of setdefault that sets sequence if appropriate.""" try: return self[key] except KeyError: self[key] = default return self[key] def items(self): """D.items() -> list of D's (key, value) pairs, as 2-tuples""" return list(zip((self.scalars + self.sections), list(self.values()))) def keys(self): """D.keys() -> list of D's keys""" return (self.scalars + self.sections) def values(self): """D.values() -> list of D's values""" return [self[key] for key in (self.scalars + self.sections)] def iteritems(self): """D.iteritems() -> an iterator over the (key, value) items of D""" return iter(list(self.items())) def iterkeys(self): """D.iterkeys() -> an iterator over the keys of D""" return iter((self.scalars + self.sections)) __iter__ = iterkeys def itervalues(self): """D.itervalues() -> an iterator over the values of D""" return iter(list(self.values())) def __repr__(self): """x.__repr__() <==> repr(x)""" def _getval(key): try: return self[key] except MissingInterpolationOption: return dict.__getitem__(self, key) return '{%s}' % ', '.join([('%s: %s' % (repr(key), repr(_getval(key)))) for key in (self.scalars + self.sections)]) __str__ = __repr__ __str__.__doc__ = "x.__str__() <==> str(x)" # Extra methods - not in a normal dictionary def dict(self): """ Return a deepcopy of self as a dictionary. All members that are ``Section`` instances are recursively turned to ordinary dictionaries - by calling their ``dict`` method. >>> n = a.dict() >>> n == a 1 >>> n is a 0 """ newdict = {} for entry in self: this_entry = self[entry] if isinstance(this_entry, Section): this_entry = this_entry.dict() elif isinstance(this_entry, list): # create a copy rather than a reference this_entry = list(this_entry) elif isinstance(this_entry, tuple): # create a copy rather than a reference this_entry = tuple(this_entry) newdict[entry] = this_entry return newdict def merge(self, indict): """ A recursive update - useful for merging config files. >>> a = '''[section1] ... option1 = True ... [[subsection]] ... more_options = False ... # end of file'''.splitlines() >>> b = '''# File is user.ini ... [section1] ... option1 = False ... # end of file'''.splitlines() >>> c1 = ConfigObj(b) >>> c2 = ConfigObj(a) >>> c2.merge(c1) >>> c2 ConfigObj({'section1': {'option1': 'False', 'subsection': {'more_options': 'False'}}}) """ for key, val in list(indict.items()): if (key in self and isinstance(self[key], Mapping) and isinstance(val, Mapping)): self[key].merge(val) else: self[key] = val def rename(self, oldkey, newkey): """ Change a keyname to another, without changing position in sequence. Implemented so that transformations can be made on keys, as well as on values. (used by encode and decode) Also renames comments. """ if oldkey in self.scalars: the_list = self.scalars elif oldkey in self.sections: the_list = self.sections else: raise KeyError('Key "%s" not found.' % oldkey) pos = the_list.index(oldkey) # val = self[oldkey] dict.__delitem__(self, oldkey) dict.__setitem__(self, newkey, val) the_list.remove(oldkey) the_list.insert(pos, newkey) comm = self.comments[oldkey] inline_comment = self.inline_comments[oldkey] del self.comments[oldkey] del self.inline_comments[oldkey] self.comments[newkey] = comm self.inline_comments[newkey] = inline_comment def walk(self, function, raise_errors=True, call_on_sections=False, **keywargs): """ Walk every member and call a function on the keyword and value. Return a dictionary of the return values If the function raises an exception, raise the errror unless ``raise_errors=False``, in which case set the return value to ``False``. Any unrecognized keyword arguments you pass to walk, will be pased on to the function you pass in. Note: if ``call_on_sections`` is ``True`` then - on encountering a subsection, *first* the function is called for the *whole* subsection, and then recurses into it's members. This means your function must be able to handle strings, dictionaries and lists. This allows you to change the key of subsections as well as for ordinary members. The return value when called on the whole subsection has to be discarded. See the encode and decode methods for examples, including functions. .. admonition:: caution You can use ``walk`` to transform the names of members of a section but you mustn't add or delete members. >>> config = '''[XXXXsection] ... XXXXkey = XXXXvalue'''.splitlines() >>> cfg = ConfigObj(config) >>> cfg ConfigObj({'XXXXsection': {'XXXXkey': 'XXXXvalue'}}) >>> def transform(section, key): ... val = section[key] ... newkey = key.replace('XXXX', 'CLIENT1') ... section.rename(key, newkey) ... if isinstance(val, (tuple, list, dict)): ... pass ... else: ... val = val.replace('XXXX', 'CLIENT1') ... section[newkey] = val >>> cfg.walk(transform, call_on_sections=True) {'CLIENT1section': {'CLIENT1key': None}} >>> cfg ConfigObj({'CLIENT1section': {'CLIENT1key': 'CLIENT1value'}}) """ out = {} # scalars first for i in range(len(self.scalars)): entry = self.scalars[i] try: val = function(self, entry, **keywargs) # bound again in case name has changed entry = self.scalars[i] out[entry] = val except Exception: if raise_errors: raise else: entry = self.scalars[i] out[entry] = False # then sections for i in range(len(self.sections)): entry = self.sections[i] if call_on_sections: try: function(self, entry, **keywargs) except Exception: if raise_errors: raise else: entry = self.sections[i] out[entry] = False # bound again in case name has changed entry = self.sections[i] # previous result is discarded out[entry] = self[entry].walk( function, raise_errors=raise_errors, call_on_sections=call_on_sections, **keywargs) return out def as_bool(self, key): """ Accepts a key as input. The corresponding value must be a string or the objects (``True`` or 1) or (``False`` or 0). We allow 0 and 1 to retain compatibility with Python 2.2. If the string is one of ``True``, ``On``, ``Yes``, or ``1`` it returns ``True``. If the string is one of ``False``, ``Off``, ``No``, or ``0`` it returns ``False``. ``as_bool`` is not case sensitive. Any other input will raise a ``ValueError``. >>> a = ConfigObj() >>> a['a'] = 'fish' >>> a.as_bool('a') Traceback (most recent call last): ValueError: Value "fish" is neither True nor False >>> a['b'] = 'True' >>> a.as_bool('b') 1 >>> a['b'] = 'off' >>> a.as_bool('b') 0 """ val = self[key] if val == True: return True elif val == False: return False else: try: if not isinstance(val, str): # TODO: Why do we raise a KeyError here? raise KeyError() else: return self.main._bools[val.lower()] except KeyError: raise ValueError('Value "%s" is neither True nor False' % val) def as_int(self, key): """ A convenience method which coerces the specified value to an integer. If the value is an invalid literal for ``int``, a ``ValueError`` will be raised. >>> a = ConfigObj() >>> a['a'] = 'fish' >>> a.as_int('a') Traceback (most recent call last): ValueError: invalid literal for int() with base 10: 'fish' >>> a['b'] = '1' >>> a.as_int('b') 1 >>> a['b'] = '3.2' >>> a.as_int('b') Traceback (most recent call last): ValueError: invalid literal for int() with base 10: '3.2' """ return int(self[key]) def as_float(self, key): """ A convenience method which coerces the specified value to a float. If the value is an invalid literal for ``float``, a ``ValueError`` will be raised. >>> a = ConfigObj() >>> a['a'] = 'fish' >>> a.as_float('a') #doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ValueError: invalid literal for float(): fish >>> a['b'] = '1' >>> a.as_float('b') 1.0 >>> a['b'] = '3.2' >>> a.as_float('b') #doctest: +ELLIPSIS 3.2... """ return float(self[key]) def as_list(self, key): """ A convenience method which fetches the specified value, guaranteeing that it is a list. >>> a = ConfigObj() >>> a['a'] = 1 >>> a.as_list('a') [1] >>> a['a'] = (1,) >>> a.as_list('a') [1] >>> a['a'] = [1] >>> a.as_list('a') [1] """ result = self[key] if isinstance(result, (tuple, list)): return list(result) return [result] def restore_default(self, key): """ Restore (and return) default value for the specified key. This method will only work for a ConfigObj that was created with a configspec and has been validated. If there is no default value for this key, ``KeyError`` is raised. """ default = self.default_values[key] dict.__setitem__(self, key, default) if key not in self.defaults: self.defaults.append(key) return default def restore_defaults(self): """ Recursively restore default values to all members that have them. This method will only work for a ConfigObj that was created with a configspec and has been validated. It doesn't delete or modify entries without default values. """ for key in self.default_values: self.restore_default(key) for section in self.sections: self[section].restore_defaults() class ConfigObj(Section): """An object to read, create, and write config files.""" _keyword = re.compile(r'''^ # line start (\s*) # indentation ( # keyword (?:".*?")| # double quotes (?:'.*?')| # single quotes (?:[^'"=].*?) # no quotes ) \s*=\s* # divider (.*) # value (including list values and comments) $ # line end ''', re.VERBOSE) _sectionmarker = re.compile(r'''^ (\s*) # 1: indentation ((?:\[\s*)+) # 2: section marker open ( # 3: section name open (?:"\s*\S.*?\s*")| # at least one non-space with double quotes (?:'\s*\S.*?\s*')| # at least one non-space with single quotes (?:[^'"\s].*?) # at least one non-space unquoted ) # section name close ((?:\s*\])+) # 4: section marker close \s*(\#.*)? # 5: optional comment $''', re.VERBOSE) # this regexp pulls list values out as a single string # or single values and comments # FIXME: this regex adds a '' to the end of comma terminated lists # workaround in ``_handle_value`` _valueexp = re.compile(r'''^ (?: (?: ( (?: (?: (?:".*?")| # double quotes (?:'.*?')| # single quotes (?:[^'",\#][^,\#]*?) # unquoted ) \s*,\s* # comma )* # match all list items ending in a comma (if any) ) ( (?:".*?")| # double quotes (?:'.*?')| # single quotes (?:[^'",\#\s][^,]*?)| # unquoted (?:(? 1: msg = "Parsing failed with several errors.\nFirst error %s" % info error = ConfigObjError(msg) else: error = self._errors[0] # set the errors attribute; it's a list of tuples: # (error_type, message, line_number) error.errors = self._errors # set the config attribute error.config = self raise error # delete private attributes del self._errors if configspec is None: self.configspec = None else: self._handle_configspec(configspec) def _initialise(self, options=None): if options is None: options = OPTION_DEFAULTS # initialise a few variables self.filename = None self._errors = [] self.raise_errors = options['raise_errors'] self.interpolation = options['interpolation'] self.list_values = options['list_values'] self.create_empty = options['create_empty'] self.file_error = options['file_error'] self.stringify = options['stringify'] self.indent_type = options['indent_type'] self.encoding = options['encoding'] self.default_encoding = options['default_encoding'] self.BOM = False self.newlines = None self.write_empty_values = options['write_empty_values'] self.unrepr = options['unrepr'] self.initial_comment = [] self.final_comment = [] self.configspec = None if self._inspec: self.list_values = False # Clear section attributes as well Section._initialise(self) def __repr__(self): def _getval(key): try: return self[key] except MissingInterpolationOption: return dict.__getitem__(self, key) return ('%s({%s})' % (self.__class__.__name__, ', '.join([('%s: %s' % (repr(key), repr(_getval(key)))) for key in (self.scalars + self.sections)]))) def _handle_bom(self, infile): """ Handle any BOM, and decode if necessary. If an encoding is specified, that *must* be used - but the BOM should still be removed (and the BOM attribute set). (If the encoding is wrongly specified, then a BOM for an alternative encoding won't be discovered or removed.) If an encoding is not specified, UTF8 or UTF16 BOM will be detected and removed. The BOM attribute will be set. UTF16 will be decoded to unicode. NOTE: This method must not be called with an empty ``infile``. Specifying the *wrong* encoding is likely to cause a ``UnicodeDecodeError``. ``infile`` must always be returned as a list of lines, but may be passed in as a single string. """ if ((self.encoding is not None) and (self.encoding.lower() not in BOM_LIST)): # No need to check for a BOM # the encoding specified doesn't have one # just decode return self._decode(infile, self.encoding) if isinstance(infile, (list, tuple)): line = infile[0] else: line = infile if isinstance(line, str): # it's already decoded and there's no need to do anything # else, just use the _decode utility method to handle # listifying appropriately return self._decode(infile, self.encoding) if self.encoding is not None: # encoding explicitly supplied # And it could have an associated BOM # TODO: if encoding is just UTF16 - we ought to check for both # TODO: big endian and little endian versions. enc = BOM_LIST[self.encoding.lower()] if enc == 'utf_16': # For UTF16 we try big endian and little endian for BOM, (encoding, final_encoding) in list(BOMS.items()): if not final_encoding: # skip UTF8 continue if infile.startswith(BOM): ### BOM discovered ##self.BOM = True # Don't need to remove BOM return self._decode(infile, encoding) # If we get this far, will *probably* raise a DecodeError # As it doesn't appear to start with a BOM return self._decode(infile, self.encoding) # Must be UTF8 BOM = BOM_SET[enc] if not line.startswith(BOM): return self._decode(infile, self.encoding) newline = line[len(BOM):] # BOM removed if isinstance(infile, (list, tuple)): infile[0] = newline else: infile = newline self.BOM = True return self._decode(infile, self.encoding) # No encoding specified - so we need to check for UTF8/UTF16 for BOM, (encoding, final_encoding) in list(BOMS.items()): if not isinstance(line, bytes) or not line.startswith(BOM): # didn't specify a BOM, or it's not a bytestring continue else: # BOM discovered self.encoding = final_encoding if not final_encoding: self.BOM = True # UTF8 # remove BOM newline = line[len(BOM):] if isinstance(infile, (list, tuple)): infile[0] = newline else: infile = newline # UTF-8 if isinstance(infile, str): return infile.splitlines(True) elif isinstance(infile, bytes): return infile.decode('utf-8').splitlines(True) else: return self._decode(infile, 'utf-8') # UTF16 - have to decode return self._decode(infile, encoding) # No BOM discovered and no encoding specified, default to UTF-8 if isinstance(infile, bytes): return infile.decode('utf-8').splitlines(True) else: return self._decode(infile, 'utf-8') def _a_to_u(self, aString): """Decode ASCII strings to unicode if a self.encoding is specified.""" if isinstance(aString, bytes) and self.encoding: return aString.decode(self.encoding) else: return aString def _decode(self, infile, encoding): """ Decode infile to unicode. Using the specified encoding. if is a string, it also needs converting to a list. """ if isinstance(infile, str): return infile.splitlines(True) if isinstance(infile, bytes): # NOTE: Could raise a ``UnicodeDecodeError`` if encoding: return infile.decode(encoding).splitlines(True) else: return infile.splitlines(True) if encoding: for i, line in enumerate(infile): if isinstance(line, bytes): # NOTE: The isinstance test here handles mixed lists of unicode/string # NOTE: But the decode will break on any non-string values # NOTE: Or could raise a ``UnicodeDecodeError`` infile[i] = line.decode(encoding) return infile def _decode_element(self, line): """Decode element to unicode if necessary.""" if isinstance(line, bytes) and self.default_encoding: return line.decode(self.default_encoding) else: return line # TODO: this may need to be modified def _str(self, value): """ Used by ``stringify`` within validate, to turn non-string values into strings. """ if not isinstance(value, str): # intentially 'str' because it's just whatever the "normal" # string type is for the python version we're dealing with return str(value) else: return value def _parse(self, infile): """Actually parse the config file.""" temp_list_values = self.list_values if self.unrepr: self.list_values = False comment_list = [] done_start = False this_section = self maxline = len(infile) - 1 cur_index = -1 reset_comment = False while cur_index < maxline: if reset_comment: comment_list = [] cur_index += 1 line = infile[cur_index] sline = line.strip() # do we have anything on the line ? if not sline or sline.startswith('#'): reset_comment = False comment_list.append(line) continue if not done_start: # preserve initial comment self.initial_comment = comment_list comment_list = [] done_start = True reset_comment = True # first we check if it's a section marker mat = self._sectionmarker.match(line) if mat is not None: # is a section line (indent, sect_open, sect_name, sect_close, comment) = mat.groups() if indent and (self.indent_type is None): self.indent_type = indent cur_depth = sect_open.count('[') if cur_depth != sect_close.count(']'): self._handle_error("Cannot compute the section depth", NestingError, infile, cur_index) continue if cur_depth < this_section.depth: # the new section is dropping back to a previous level try: parent = self._match_depth(this_section, cur_depth).parent except SyntaxError: self._handle_error("Cannot compute nesting level", NestingError, infile, cur_index) continue elif cur_depth == this_section.depth: # the new section is a sibling of the current section parent = this_section.parent elif cur_depth == this_section.depth + 1: # the new section is a child the current section parent = this_section else: self._handle_error("Section too nested", NestingError, infile, cur_index) continue sect_name = self._unquote(sect_name) if sect_name in parent: self._handle_error('Duplicate section name', DuplicateError, infile, cur_index) continue # create the new section this_section = Section( parent, cur_depth, self, name=sect_name) parent[sect_name] = this_section parent.inline_comments[sect_name] = comment parent.comments[sect_name] = comment_list continue # # it's not a section marker, # so it should be a valid ``key = value`` line mat = self._keyword.match(line) if mat is None: self._handle_error( 'Invalid line ({0!r}) (matched as neither section nor keyword)'.format(line), ParseError, infile, cur_index) else: # is a keyword value # value will include any inline comment (indent, key, value) = mat.groups() if indent and (self.indent_type is None): self.indent_type = indent # check for a multiline value if value[:3] in ['"""', "'''"]: try: value, comment, cur_index = self._multiline( value, infile, cur_index, maxline) except SyntaxError: self._handle_error( 'Parse error in multiline value', ParseError, infile, cur_index) continue else: if self.unrepr: comment = '' try: value = unrepr(value) except Exception as e: if type(e) == UnknownType: msg = 'Unknown name or type in value' else: msg = 'Parse error from unrepr-ing multiline value' self._handle_error(msg, UnreprError, infile, cur_index) continue else: if self.unrepr: comment = '' try: value = unrepr(value) except Exception as e: if isinstance(e, UnknownType): msg = 'Unknown name or type in value' else: msg = 'Parse error from unrepr-ing value' self._handle_error(msg, UnreprError, infile, cur_index) continue else: # extract comment and lists try: (value, comment) = self._handle_value(value) except SyntaxError: self._handle_error( 'Parse error in value', ParseError, infile, cur_index) continue # key = self._unquote(key) if key in this_section: self._handle_error( 'Duplicate keyword name', DuplicateError, infile, cur_index) continue # add the key. # we set unrepr because if we have got this far we will never # be creating a new section this_section.__setitem__(key, value, unrepr=True) this_section.inline_comments[key] = comment this_section.comments[key] = comment_list continue # if self.indent_type is None: # no indentation used, set the type accordingly self.indent_type = '' # preserve the final comment if not self and not self.initial_comment: self.initial_comment = comment_list elif not reset_comment: self.final_comment = comment_list self.list_values = temp_list_values def _match_depth(self, sect, depth): """ Given a section and a depth level, walk back through the sections parents to see if the depth level matches a previous section. Return a reference to the right section, or raise a SyntaxError. """ while depth < sect.depth: if sect is sect.parent: # we've reached the top level already raise SyntaxError() sect = sect.parent if sect.depth == depth: return sect # shouldn't get here raise SyntaxError() def _handle_error(self, text, ErrorClass, infile, cur_index): """ Handle an error according to the error settings. Either raise the error or store it. The error will have occured at ``cur_index`` """ line = infile[cur_index] cur_index += 1 message = '{0} at line {1}.'.format(text, cur_index) error = ErrorClass(message, cur_index, line) if self.raise_errors: # raise the error - parsing stops here raise error # store the error # reraise when parsing has finished self._errors.append(error) def _unquote(self, value): """Return an unquoted version of a value""" if not value: # should only happen during parsing of lists raise SyntaxError if (value[0] == value[-1]) and (value[0] in ('"', "'")): value = value[1:-1] return value def _quote(self, value, multiline=True): """ Return a safely quoted version of a value. Raise a ConfigObjError if the value cannot be safely quoted. If multiline is ``True`` (default) then use triple quotes if necessary. * Don't quote values that don't need it. * Recursively quote members of a list and return a comma joined list. * Multiline is ``False`` for lists. * Obey list syntax for empty and single member lists. If ``list_values=False`` then the value is only quoted if it contains a ``\\n`` (is multiline) or '#'. If ``write_empty_values`` is set, and the value is an empty string, it won't be quoted. """ if multiline and self.write_empty_values and value == '': # Only if multiline is set, so that it is used for values not # keys, and not values that are part of a list return '' if multiline and isinstance(value, (list, tuple)): if not value: return ',' elif len(value) == 1: return self._quote(value[0], multiline=False) + ',' return ', '.join([self._quote(val, multiline=False) for val in value]) if not isinstance(value, str): if self.stringify: # intentially 'str' because it's just whatever the "normal" # string type is for the python version we're dealing with value = str(value) else: raise TypeError('Value "%s" is not a string.' % value) if not value: return '""' no_lists_no_quotes = not self.list_values and '\n' not in value and '#' not in value need_triple = multiline and ((("'" in value) and ('"' in value)) or ('\n' in value )) hash_triple_quote = multiline and not need_triple and ("'" in value) and ('"' in value) and ('#' in value) check_for_single = (no_lists_no_quotes or not need_triple) and not hash_triple_quote if check_for_single: if not self.list_values: # we don't quote if ``list_values=False`` quot = noquot # for normal values either single or double quotes will do elif '\n' in value: # will only happen if multiline is off - e.g. '\n' in key raise ConfigObjError('Value "%s" cannot be safely quoted.' % value) elif ((value[0] not in wspace_plus) and (value[-1] not in wspace_plus) and (',' not in value)): quot = noquot else: quot = self._get_single_quote(value) else: # if value has '\n' or "'" *and* '"', it will need triple quotes quot = self._get_triple_quote(value) if quot == noquot and '#' in value and self.list_values: quot = self._get_single_quote(value) return quot % value def _get_single_quote(self, value): if ("'" in value) and ('"' in value): raise ConfigObjError('Value "%s" cannot be safely quoted.' % value) elif '"' in value: quot = squot else: quot = dquot return quot def _get_triple_quote(self, value): if (value.find('"""') != -1) and (value.find("'''") != -1): raise ConfigObjError('Value "%s" cannot be safely quoted.' % value) if value.find('"""') == -1: quot = tdquot else: quot = tsquot return quot def _handle_value(self, value): """ Given a value string, unquote, remove comment, handle lists. (including empty and single member lists) """ if self._inspec: # Parsing a configspec so don't handle comments return (value, '') # do we look for lists in values ? if not self.list_values: mat = self._nolistvalue.match(value) if mat is None: raise SyntaxError() # NOTE: we don't unquote here return mat.groups() # mat = self._valueexp.match(value) if mat is None: # the value is badly constructed, probably badly quoted, # or an invalid list raise SyntaxError() (list_values, single, empty_list, comment) = mat.groups() if (list_values == '') and (single is None): # change this if you want to accept empty values raise SyntaxError() # NOTE: note there is no error handling from here if the regex # is wrong: then incorrect values will slip through if empty_list is not None: # the single comma - meaning an empty list return ([], comment) if single is not None: # handle empty values if list_values and not single: # FIXME: the '' is a workaround because our regex now matches # '' at the end of a list if it has a trailing comma single = None else: single = single or '""' single = self._unquote(single) if list_values == '': # not a list value return (single, comment) the_list = self._listvalueexp.findall(list_values) the_list = [self._unquote(val) for val in the_list] if single is not None: the_list += [single] return (the_list, comment) def _multiline(self, value, infile, cur_index, maxline): """Extract the value, where we are in a multiline situation.""" quot = value[:3] newvalue = value[3:] single_line = self._triple_quote[quot][0] multi_line = self._triple_quote[quot][1] mat = single_line.match(value) if mat is not None: retval = list(mat.groups()) retval.append(cur_index) return retval elif newvalue.find(quot) != -1: # somehow the triple quote is missing raise SyntaxError() # while cur_index < maxline: cur_index += 1 newvalue += '\n' line = infile[cur_index] if line.find(quot) == -1: newvalue += line else: # end of multiline, process it break else: # we've got to the end of the config, oops... raise SyntaxError() mat = multi_line.match(line) if mat is None: # a badly formed line raise SyntaxError() (value, comment) = mat.groups() return (newvalue + value, comment, cur_index) def _handle_configspec(self, configspec): """Parse the configspec.""" # FIXME: Should we check that the configspec was created with the # correct settings ? (i.e. ``list_values=False``) if not isinstance(configspec, ConfigObj): try: configspec = ConfigObj(configspec, raise_errors=True, file_error=True, _inspec=True) except ConfigObjError as e: # FIXME: Should these errors have a reference # to the already parsed ConfigObj ? raise ConfigspecError('Parsing configspec failed: %s' % e) except IOError as e: raise IOError('Reading configspec failed: %s' % e) self.configspec = configspec def _set_configspec(self, section, copy): """ Called by validate. Handles setting the configspec on subsections including sections to be validated by __many__ """ configspec = section.configspec many = configspec.get('__many__') if isinstance(many, dict): for entry in section.sections: if entry not in configspec: section[entry].configspec = many for entry in configspec.sections: if entry == '__many__': continue if entry not in section: section[entry] = {} section[entry]._created = True if copy: # copy comments section.comments[entry] = configspec.comments.get(entry, []) section.inline_comments[entry] = configspec.inline_comments.get(entry, '') # Could be a scalar when we expect a section if isinstance(section[entry], Section): section[entry].configspec = configspec[entry] def _write_line(self, indent_string, entry, this_entry, comment): """Write an individual line, for the write method""" # NOTE: the calls to self._quote here handles non-StringType values. if not self.unrepr: val = self._decode_element(self._quote(this_entry)) else: val = repr(this_entry) return '%s%s%s%s%s' % (indent_string, self._decode_element(self._quote(entry, multiline=False)), self._a_to_u(' = '), val, self._decode_element(comment)) def _write_marker(self, indent_string, depth, entry, comment): """Write a section marker line""" return '%s%s%s%s%s' % (indent_string, self._a_to_u('[' * depth), self._quote(self._decode_element(entry), multiline=False), self._a_to_u(']' * depth), self._decode_element(comment)) def _handle_comment(self, comment): """Deal with a comment.""" if not comment: return '' start = self.indent_type if not comment.startswith('#'): start += self._a_to_u(' # ') return (start + comment) # Public methods def write(self, outfile=None, section=None): """ Write the current ConfigObj as a file tekNico: FIXME: use StringIO instead of real files >>> filename = a.filename >>> a.filename = 'test.ini' >>> a.write() >>> a.filename = filename >>> a == ConfigObj('test.ini', raise_errors=True) 1 >>> import os >>> os.remove('test.ini') """ if self.indent_type is None: # this can be true if initialised from a dictionary self.indent_type = DEFAULT_INDENT_TYPE out = [] cs = self._a_to_u('#') csp = self._a_to_u('# ') if section is None: int_val = self.interpolation self.interpolation = False section = self for line in self.initial_comment: line = self._decode_element(line) stripped_line = line.strip() if stripped_line and not stripped_line.startswith(cs): line = csp + line out.append(line) indent_string = self.indent_type * section.depth for entry in (section.scalars + section.sections): if entry in section.defaults: # don't write out default values continue for comment_line in section.comments[entry]: comment_line = self._decode_element(comment_line.lstrip()) if comment_line and not comment_line.startswith(cs): comment_line = csp + comment_line out.append(indent_string + comment_line) this_entry = section[entry] comment = self._handle_comment(section.inline_comments[entry]) if isinstance(this_entry, Section): # a section out.append(self._write_marker( indent_string, this_entry.depth, entry, comment)) out.extend(self.write(section=this_entry)) else: out.append(self._write_line( indent_string, entry, this_entry, comment)) if section is self: for line in self.final_comment: line = self._decode_element(line) stripped_line = line.strip() if stripped_line and not stripped_line.startswith(cs): line = csp + line out.append(line) self.interpolation = int_val if section is not self: return out if (self.filename is None) and (outfile is None): # output a list of lines # might need to encode # NOTE: This will *screw* UTF16, each line will start with the BOM if self.encoding: out = [l.encode(self.encoding) for l in out] if (self.BOM and ((self.encoding is None) or (BOM_LIST.get(self.encoding.lower()) == 'utf_8'))): # Add the UTF8 BOM if not out: out.append('') out[0] = BOM_UTF8 + out[0] return out # Turn the list to a string, joined with correct newlines newline = self.newlines or os.linesep if (getattr(outfile, 'mode', None) is not None and outfile.mode == 'w' and sys.platform == 'win32' and newline == '\r\n'): # Windows specific hack to avoid writing '\r\r\n' newline = '\n' output = self._a_to_u(newline).join(out) if not output.endswith(newline): output += newline if isinstance(output, bytes): output_bytes = output else: output_bytes = output.encode(self.encoding or self.default_encoding or 'ascii') if self.BOM and ((self.encoding is None) or match_utf8(self.encoding)): # Add the UTF8 BOM output_bytes = BOM_UTF8 + output_bytes if outfile is not None: outfile.write(output_bytes) else: with open(self.filename, 'wb') as h: h.write(output_bytes) def validate(self, validator, preserve_errors=False, copy=False, section=None): """ Test the ConfigObj against a configspec. It uses the ``validator`` object from *validate.py*. To run ``validate`` on the current ConfigObj, call: :: test = config.validate(validator) (Normally having previously passed in the configspec when the ConfigObj was created - you can dynamically assign a dictionary of checks to the ``configspec`` attribute of a section though). It returns ``True`` if everything passes, or a dictionary of pass/fails (True/False). If every member of a subsection passes, it will just have the value ``True``. (It also returns ``False`` if all members fail). In addition, it converts the values from strings to their native types if their checks pass (and ``stringify`` is set). If ``preserve_errors`` is ``True`` (``False`` is default) then instead of a marking a fail with a ``False``, it will preserve the actual exception object. This can contain info about the reason for failure. For example the ``VdtValueTooSmallError`` indicates that the value supplied was too small. If a value (or section) is missing it will still be marked as ``False``. You must have the validate module to use ``preserve_errors=True``. You can then use the ``flatten_errors`` function to turn your nested results dictionary into a flattened list of failures - useful for displaying meaningful error messages. """ if section is None: if self.configspec is None: raise ValueError('No configspec supplied.') if preserve_errors: # We do this once to remove a top level dependency on the validate module # Which makes importing configobj faster from .validate import VdtMissingValue self._vdtMissingValue = VdtMissingValue section = self if copy: section.initial_comment = section.configspec.initial_comment section.final_comment = section.configspec.final_comment section.encoding = section.configspec.encoding section.BOM = section.configspec.BOM section.newlines = section.configspec.newlines section.indent_type = section.configspec.indent_type # # section.default_values.clear() #?? configspec = section.configspec self._set_configspec(section, copy) def validate_entry(entry, spec, val, missing, ret_true, ret_false): section.default_values.pop(entry, None) try: section.default_values[entry] = validator.get_default_value(configspec[entry]) except (KeyError, AttributeError, validator.baseErrorClass): # No default, bad default or validator has no 'get_default_value' # (e.g. SimpleVal) pass try: check = validator.check(spec, val, missing=missing ) except validator.baseErrorClass as e: if not preserve_errors or isinstance(e, self._vdtMissingValue): out[entry] = False else: # preserve the error out[entry] = e ret_false = False ret_true = False else: ret_false = False out[entry] = True if self.stringify or missing: # if we are doing type conversion # or the value is a supplied default if not self.stringify: if isinstance(check, (list, tuple)): # preserve lists check = [self._str(item) for item in check] elif missing and check is None: # convert the None from a default to a '' check = '' else: check = self._str(check) if (check != val) or missing: section[entry] = check if not copy and missing and entry not in section.defaults: section.defaults.append(entry) return ret_true, ret_false # out = {} ret_true = True ret_false = True unvalidated = [k for k in section.scalars if k not in configspec] incorrect_sections = [k for k in configspec.sections if k in section.scalars] incorrect_scalars = [k for k in configspec.scalars if k in section.sections] for entry in configspec.scalars: if entry in ('__many__', '___many___'): # reserved names continue if (not entry in section.scalars) or (entry in section.defaults): # missing entries # or entries from defaults missing = True val = None if copy and entry not in section.scalars: # copy comments section.comments[entry] = ( configspec.comments.get(entry, [])) section.inline_comments[entry] = ( configspec.inline_comments.get(entry, '')) # else: missing = False val = section[entry] ret_true, ret_false = validate_entry(entry, configspec[entry], val, missing, ret_true, ret_false) many = None if '__many__' in configspec.scalars: many = configspec['__many__'] elif '___many___' in configspec.scalars: many = configspec['___many___'] if many is not None: for entry in unvalidated: val = section[entry] ret_true, ret_false = validate_entry(entry, many, val, False, ret_true, ret_false) unvalidated = [] for entry in incorrect_scalars: ret_true = False if not preserve_errors: out[entry] = False else: ret_false = False msg = 'Value %r was provided as a section' % entry out[entry] = validator.baseErrorClass(msg) for entry in incorrect_sections: ret_true = False if not preserve_errors: out[entry] = False else: ret_false = False msg = 'Section %r was provided as a single value' % entry out[entry] = validator.baseErrorClass(msg) # Missing sections will have been created as empty ones when the # configspec was read. for entry in section.sections: # FIXME: this means DEFAULT is not copied in copy mode if section is self and entry == 'DEFAULT': continue if section[entry].configspec is None: unvalidated.append(entry) continue if copy: section.comments[entry] = configspec.comments.get(entry, []) section.inline_comments[entry] = configspec.inline_comments.get(entry, '') check = self.validate(validator, preserve_errors=preserve_errors, copy=copy, section=section[entry]) out[entry] = check if check == False: ret_true = False elif check == True: ret_false = False else: ret_true = False section.extra_values = unvalidated if preserve_errors and not section._created: # If the section wasn't created (i.e. it wasn't missing) # then we can't return False, we need to preserve errors ret_false = False # if ret_false and preserve_errors and out: # If we are preserving errors, but all # the failures are from missing sections / values # then we can return False. Otherwise there is a # real failure that we need to preserve. ret_false = not any(out.values()) if ret_true: return True elif ret_false: return False return out def reset(self): """Clear ConfigObj instance and restore to 'freshly created' state.""" self.clear() self._initialise() # FIXME: Should be done by '_initialise', but ConfigObj constructor (and reload) # requires an empty dictionary self.configspec = None # Just to be sure ;-) self._original_configspec = None def reload(self): """ Reload a ConfigObj from file. This method raises a ``ReloadError`` if the ConfigObj doesn't have a filename attribute pointing to a file. """ if not isinstance(self.filename, str): raise ReloadError() filename = self.filename current_options = {} for entry in OPTION_DEFAULTS: if entry == 'configspec': continue current_options[entry] = getattr(self, entry) configspec = self._original_configspec current_options['configspec'] = configspec self.clear() self._initialise(current_options) self._load(filename, configspec) class SimpleVal(object): """ A simple validator. Can be used to check that all members expected are present. To use it, provide a configspec with all your members in (the value given will be ignored). Pass an instance of ``SimpleVal`` to the ``validate`` method of your ``ConfigObj``. ``validate`` will return ``True`` if all members are present, or a dictionary with True/False meaning present/missing. (Whole missing sections will be replaced with ``False``) """ def __init__(self): self.baseErrorClass = ConfigObjError def check(self, check, member, missing=False): """A dummy check method, always returns the value unchanged.""" if missing: raise self.baseErrorClass() return member def flatten_errors(cfg, res, levels=None, results=None): """ An example function that will turn a nested dictionary of results (as returned by ``ConfigObj.validate``) into a flat list. ``cfg`` is the ConfigObj instance being checked, ``res`` is the results dictionary returned by ``validate``. (This is a recursive function, so you shouldn't use the ``levels`` or ``results`` arguments - they are used by the function.) Returns a list of keys that failed. Each member of the list is a tuple:: ([list of sections...], key, result) If ``validate`` was called with ``preserve_errors=False`` (the default) then ``result`` will always be ``False``. *list of sections* is a flattened list of sections that the key was found in. If the section was missing (or a section was expected and a scalar provided - or vice-versa) then key will be ``None``. If the value (or section) was missing then ``result`` will be ``False``. If ``validate`` was called with ``preserve_errors=True`` and a value was present, but failed the check, then ``result`` will be the exception object returned. You can use this as a string that describes the failure. For example *The value "3" is of the wrong type*. """ if levels is None: # first time called levels = [] results = [] if res == True: return sorted(results) if res == False or isinstance(res, Exception): results.append((levels[:], None, res)) if levels: levels.pop() return sorted(results) for (key, val) in list(res.items()): if val == True: continue if isinstance(cfg.get(key), Mapping): # Go down one level levels.append(key) flatten_errors(cfg[key], val, levels, results) continue results.append((levels[:], key, val)) # # Go up one level if levels: levels.pop() # return sorted(results) def get_extra_values(conf, _prepend=()): """ Find all the values and sections not in the configspec from a validated ConfigObj. ``get_extra_values`` returns a list of tuples where each tuple represents either an extra section, or an extra value. The tuples contain two values, a tuple representing the section the value is in and the name of the extra values. For extra values in the top level section the first member will be an empty tuple. For values in the 'foo' section the first member will be ``('foo',)``. For members in the 'bar' subsection of the 'foo' section the first member will be ``('foo', 'bar')``. NOTE: If you call ``get_extra_values`` on a ConfigObj instance that hasn't been validated it will return an empty list. """ out = [] out.extend([(_prepend, name) for name in conf.extra_values]) for name in conf.sections: if name not in conf.extra_values: out.extend(get_extra_values(conf[name], _prepend + (name,))) return out """*A programming language is a medium of expression.* - Paul Graham""" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/extern/configobj/validate.py0000755000175100001710000013312000000000000021361 0ustar00vstsdocker# validate.py # A Validator object # Copyright (C) 2005-2014: # (name) : (email) # Michael Foord: fuzzyman AT voidspace DOT org DOT uk # Mark Andrews: mark AT la-la DOT com # Nicola Larosa: nico AT tekNico DOT net # Rob Dennis: rdennis AT gmail DOT com # Eli Courtwright: eli AT courtwright DOT org # This software is licensed under the terms of the BSD license. # http://opensource.org/licenses/BSD-3-Clause # ConfigObj 5 - main repository for documentation and issue tracking: # https://github.com/DiffSK/configobj """ The Validator object is used to check that supplied values conform to a specification. The value can be supplied as a string - e.g. from a config file. In this case the check will also *convert* the value to the required type. This allows you to add validation as a transparent layer to access data stored as strings. The validation checks that the data is correct *and* converts it to the expected type. Some standard checks are provided for basic data types. Additional checks are easy to write. They can be provided when the ``Validator`` is instantiated or added afterwards. The standard functions work with the following basic data types : * integers * floats * booleans * strings * ip_addr plus lists of these datatypes Adding additional checks is done through coding simple functions. The full set of standard checks are : * 'integer': matches integer values (including negative) Takes optional 'min' and 'max' arguments : :: integer() integer(3, 9) # any value from 3 to 9 integer(min=0) # any positive value integer(max=9) * 'float': matches float values Has the same parameters as the integer check. * 'boolean': matches boolean values - ``True`` or ``False`` Acceptable string values for True are : true, on, yes, 1 Acceptable string values for False are : false, off, no, 0 Any other value raises an error. * 'ip_addr': matches an Internet Protocol address, v.4, represented by a dotted-quad string, i.e. '1.2.3.4'. * 'string': matches any string. Takes optional keyword args 'min' and 'max' to specify min and max lengths of the string. * 'list': matches any list. Takes optional keyword args 'min', and 'max' to specify min and max sizes of the list. (Always returns a list.) * 'tuple': matches any tuple. Takes optional keyword args 'min', and 'max' to specify min and max sizes of the tuple. (Always returns a tuple.) * 'int_list': Matches a list of integers. Takes the same arguments as list. * 'float_list': Matches a list of floats. Takes the same arguments as list. * 'bool_list': Matches a list of boolean values. Takes the same arguments as list. * 'ip_addr_list': Matches a list of IP addresses. Takes the same arguments as list. * 'string_list': Matches a list of strings. Takes the same arguments as list. * 'mixed_list': Matches a list with different types in specific positions. List size must match the number of arguments. Each position can be one of : 'integer', 'float', 'ip_addr', 'string', 'boolean' So to specify a list with two strings followed by two integers, you write the check as : :: mixed_list('string', 'string', 'integer', 'integer') * 'pass': This check matches everything ! It never fails and the value is unchanged. It is also the default if no check is specified. * 'option': This check matches any from a list of options. You specify this check with : :: option('option 1', 'option 2', 'option 3') You can supply a default value (returned if no value is supplied) using the default keyword argument. You specify a list argument for default using a list constructor syntax in the check : :: checkname(arg1, arg2, default=list('val 1', 'val 2', 'val 3')) A badly formatted set of arguments will raise a ``VdtParamError``. """ __version__ = '1.0.1' __all__ = ( '__version__', 'dottedQuadToNum', 'numToDottedQuad', 'ValidateError', 'VdtUnknownCheckError', 'VdtParamError', 'VdtTypeError', 'VdtValueError', 'VdtValueTooSmallError', 'VdtValueTooBigError', 'VdtValueTooShortError', 'VdtValueTooLongError', 'VdtMissingValue', 'Validator', 'is_integer', 'is_float', 'is_boolean', 'is_list', 'is_tuple', 'is_ip_addr', 'is_string', 'is_int_list', 'is_bool_list', 'is_float_list', 'is_string_list', 'is_ip_addr_list', 'is_mixed_list', 'is_option', '__docformat__', ) import re import sys from pprint import pprint #TODO - #21 - six is part of the repo now, but we didn't switch over to it here # this could be replaced if six is used for compatibility, or there are no # more assertions about items being a string if sys.version_info < (3,): string_type = basestring else: string_type = str # so tests that care about unicode on 2.x can specify unicode, and the same # tests when run on 3.x won't complain about a undefined name "unicode" # since all strings are unicode on 3.x we just want to pass it through # unchanged unicode = lambda x: x # in python 3, all ints are equivalent to python 2 longs, and they'll # never show "L" in the repr long = int _list_arg = re.compile(r''' (?: ([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*list\( ( (?: \s* (?: (?:".*?")| # double quotes (?:'.*?')| # single quotes (?:[^'",\s\)][^,\)]*?) # unquoted ) \s*,\s* )* (?: (?:".*?")| # double quotes (?:'.*?')| # single quotes (?:[^'",\s\)][^,\)]*?) # unquoted )? # last one ) \) ) ''', re.VERBOSE | re.DOTALL) # two groups _list_members = re.compile(r''' ( (?:".*?")| # double quotes (?:'.*?')| # single quotes (?:[^'",\s=][^,=]*?) # unquoted ) (?: (?:\s*,\s*)|(?:\s*$) # comma ) ''', re.VERBOSE | re.DOTALL) # one group _paramstring = r''' (?: ( (?: [a-zA-Z_][a-zA-Z0-9_]*\s*=\s*list\( (?: \s* (?: (?:".*?")| # double quotes (?:'.*?')| # single quotes (?:[^'",\s\)][^,\)]*?) # unquoted ) \s*,\s* )* (?: (?:".*?")| # double quotes (?:'.*?')| # single quotes (?:[^'",\s\)][^,\)]*?) # unquoted )? # last one \) )| (?: (?:".*?")| # double quotes (?:'.*?')| # single quotes (?:[^'",\s=][^,=]*?)| # unquoted (?: # keyword argument [a-zA-Z_][a-zA-Z0-9_]*\s*=\s* (?: (?:".*?")| # double quotes (?:'.*?')| # single quotes (?:[^'",\s=][^,=]*?) # unquoted ) ) ) ) (?: (?:\s*,\s*)|(?:\s*$) # comma ) ) ''' _matchstring = '^%s*' % _paramstring # Python pre 2.2.1 doesn't have bool try: bool except NameError: def bool(val): """Simple boolean equivalent function. """ if val: return 1 else: return 0 def dottedQuadToNum(ip): """ Convert decimal dotted quad string to long integer >>> int(dottedQuadToNum('1 ')) 1 >>> int(dottedQuadToNum(' 1.2')) 16777218 >>> int(dottedQuadToNum(' 1.2.3 ')) 16908291 >>> int(dottedQuadToNum('1.2.3.4')) 16909060 >>> dottedQuadToNum('255.255.255.255') 4294967295 >>> dottedQuadToNum('255.255.255.256') Traceback (most recent call last): ValueError: Not a good dotted-quad IP: 255.255.255.256 """ # import here to avoid it when ip_addr values are not used import socket, struct try: return struct.unpack('!L', socket.inet_aton(ip.strip()))[0] except socket.error: raise ValueError('Not a good dotted-quad IP: %s' % ip) return def numToDottedQuad(num): """ Convert int or long int to dotted quad string >>> numToDottedQuad(long(-1)) Traceback (most recent call last): ValueError: Not a good numeric IP: -1 >>> numToDottedQuad(long(1)) '0.0.0.1' >>> numToDottedQuad(long(16777218)) '1.0.0.2' >>> numToDottedQuad(long(16908291)) '1.2.0.3' >>> numToDottedQuad(long(16909060)) '1.2.3.4' >>> numToDottedQuad(long(4294967295)) '255.255.255.255' >>> numToDottedQuad(long(4294967296)) Traceback (most recent call last): ValueError: Not a good numeric IP: 4294967296 >>> numToDottedQuad(-1) Traceback (most recent call last): ValueError: Not a good numeric IP: -1 >>> numToDottedQuad(1) '0.0.0.1' >>> numToDottedQuad(16777218) '1.0.0.2' >>> numToDottedQuad(16908291) '1.2.0.3' >>> numToDottedQuad(16909060) '1.2.3.4' >>> numToDottedQuad(4294967295) '255.255.255.255' >>> numToDottedQuad(4294967296) Traceback (most recent call last): ValueError: Not a good numeric IP: 4294967296 """ # import here to avoid it when ip_addr values are not used import socket, struct # no need to intercept here, 4294967295L is fine if num > long(4294967295) or num < 0: raise ValueError('Not a good numeric IP: %s' % num) try: return socket.inet_ntoa( struct.pack('!L', long(num))) except (socket.error, struct.error, OverflowError): raise ValueError('Not a good numeric IP: %s' % num) class ValidateError(Exception): """ This error indicates that the check failed. It can be the base class for more specific errors. Any check function that fails ought to raise this error. (or a subclass) >>> raise ValidateError Traceback (most recent call last): ValidateError """ class VdtMissingValue(ValidateError): """No value was supplied to a check that needed one.""" class VdtUnknownCheckError(ValidateError): """An unknown check function was requested""" def __init__(self, value): """ >>> raise VdtUnknownCheckError('yoda') Traceback (most recent call last): VdtUnknownCheckError: the check "yoda" is unknown. """ ValidateError.__init__(self, 'the check "%s" is unknown.' % (value,)) class VdtParamError(SyntaxError): """An incorrect parameter was passed""" def __init__(self, name, value): """ >>> raise VdtParamError('yoda', 'jedi') Traceback (most recent call last): VdtParamError: passed an incorrect value "jedi" for parameter "yoda". """ SyntaxError.__init__(self, 'passed an incorrect value "%s" for parameter "%s".' % (value, name)) class VdtTypeError(ValidateError): """The value supplied was of the wrong type""" def __init__(self, value): """ >>> raise VdtTypeError('jedi') Traceback (most recent call last): VdtTypeError: the value "jedi" is of the wrong type. """ ValidateError.__init__(self, 'the value "%s" is of the wrong type.' % (value,)) class VdtValueError(ValidateError): """The value supplied was of the correct type, but was not an allowed value.""" def __init__(self, value): """ >>> raise VdtValueError('jedi') Traceback (most recent call last): VdtValueError: the value "jedi" is unacceptable. """ ValidateError.__init__(self, 'the value "%s" is unacceptable.' % (value,)) class VdtValueTooSmallError(VdtValueError): """The value supplied was of the correct type, but was too small.""" def __init__(self, value): """ >>> raise VdtValueTooSmallError('0') Traceback (most recent call last): VdtValueTooSmallError: the value "0" is too small. """ ValidateError.__init__(self, 'the value "%s" is too small.' % (value,)) class VdtValueTooBigError(VdtValueError): """The value supplied was of the correct type, but was too big.""" def __init__(self, value): """ >>> raise VdtValueTooBigError('1') Traceback (most recent call last): VdtValueTooBigError: the value "1" is too big. """ ValidateError.__init__(self, 'the value "%s" is too big.' % (value,)) class VdtValueTooShortError(VdtValueError): """The value supplied was of the correct type, but was too short.""" def __init__(self, value): """ >>> raise VdtValueTooShortError('jed') Traceback (most recent call last): VdtValueTooShortError: the value "jed" is too short. """ ValidateError.__init__( self, 'the value "%s" is too short.' % (value,)) class VdtValueTooLongError(VdtValueError): """The value supplied was of the correct type, but was too long.""" def __init__(self, value): """ >>> raise VdtValueTooLongError('jedie') Traceback (most recent call last): VdtValueTooLongError: the value "jedie" is too long. """ ValidateError.__init__(self, 'the value "%s" is too long.' % (value,)) class Validator(object): """ Validator is an object that allows you to register a set of 'checks'. These checks take input and test that it conforms to the check. This can also involve converting the value from a string into the correct datatype. The ``check`` method takes an input string which configures which check is to be used and applies that check to a supplied value. An example input string would be: 'int_range(param1, param2)' You would then provide something like: >>> def int_range_check(value, min, max): ... # turn min and max from strings to integers ... min = int(min) ... max = int(max) ... # check that value is of the correct type. ... # possible valid inputs are integers or strings ... # that represent integers ... if not isinstance(value, (int, long, string_type)): ... raise VdtTypeError(value) ... elif isinstance(value, string_type): ... # if we are given a string ... # attempt to convert to an integer ... try: ... value = int(value) ... except ValueError: ... raise VdtValueError(value) ... # check the value is between our constraints ... if not min <= value: ... raise VdtValueTooSmallError(value) ... if not value <= max: ... raise VdtValueTooBigError(value) ... return value >>> fdict = {'int_range': int_range_check} >>> vtr1 = Validator(fdict) >>> vtr1.check('int_range(20, 40)', '30') 30 >>> vtr1.check('int_range(20, 40)', '60') Traceback (most recent call last): VdtValueTooBigError: the value "60" is too big. New functions can be added with : :: >>> vtr2 = Validator() >>> vtr2.functions['int_range'] = int_range_check Or by passing in a dictionary of functions when Validator is instantiated. Your functions *can* use keyword arguments, but the first argument should always be 'value'. If the function doesn't take additional arguments, the parentheses are optional in the check. It can be written with either of : :: keyword = function_name keyword = function_name() The first program to utilise Validator() was Michael Foord's ConfigObj, an alternative to ConfigParser which supports lists and can validate a config file using a config schema. For more details on using Validator with ConfigObj see: https://configobj.readthedocs.org/en/latest/configobj.html """ # this regex does the initial parsing of the checks _func_re = re.compile(r'(.+?)\((.*)\)', re.DOTALL) # this regex takes apart keyword arguments _key_arg = re.compile(r'^([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.*)$', re.DOTALL) # this regex finds keyword=list(....) type values _list_arg = _list_arg # this regex takes individual values out of lists - in one pass _list_members = _list_members # These regexes check a set of arguments for validity # and then pull the members out _paramfinder = re.compile(_paramstring, re.VERBOSE | re.DOTALL) _matchfinder = re.compile(_matchstring, re.VERBOSE | re.DOTALL) def __init__(self, functions=None): """ >>> vtri = Validator() """ self.functions = { '': self._pass, 'integer': is_integer, 'float': is_float, 'boolean': is_boolean, 'ip_addr': is_ip_addr, 'string': is_string, 'list': is_list, 'tuple': is_tuple, 'int_list': is_int_list, 'float_list': is_float_list, 'bool_list': is_bool_list, 'ip_addr_list': is_ip_addr_list, 'string_list': is_string_list, 'mixed_list': is_mixed_list, 'pass': self._pass, 'option': is_option, 'force_list': force_list, } if functions is not None: self.functions.update(functions) # tekNico: for use by ConfigObj self.baseErrorClass = ValidateError self._cache = {} def check(self, check, value, missing=False): """ Usage: check(check, value) Arguments: check: string representing check to apply (including arguments) value: object to be checked Returns value, converted to correct type if necessary If the check fails, raises a ``ValidateError`` subclass. >>> vtor.check('yoda', '') Traceback (most recent call last): VdtUnknownCheckError: the check "yoda" is unknown. >>> vtor.check('yoda()', '') Traceback (most recent call last): VdtUnknownCheckError: the check "yoda" is unknown. >>> vtor.check('string(default="")', '', missing=True) '' """ fun_name, fun_args, fun_kwargs, default = self._parse_with_caching(check) if missing: if default is None: # no information needed here - to be handled by caller raise VdtMissingValue() value = self._handle_none(default) if value is None: return None return self._check_value(value, fun_name, fun_args, fun_kwargs) def _handle_none(self, value): if value == 'None': return None elif value in ("'None'", '"None"'): # Special case a quoted None value = self._unquote(value) return value def _parse_with_caching(self, check): if check in self._cache: fun_name, fun_args, fun_kwargs, default = self._cache[check] # We call list and dict below to work with *copies* of the data # rather than the original (which are mutable of course) fun_args = list(fun_args) fun_kwargs = dict(fun_kwargs) else: fun_name, fun_args, fun_kwargs, default = self._parse_check(check) fun_kwargs = dict([(str(key), value) for (key, value) in list(fun_kwargs.items())]) self._cache[check] = fun_name, list(fun_args), dict(fun_kwargs), default return fun_name, fun_args, fun_kwargs, default def _check_value(self, value, fun_name, fun_args, fun_kwargs): try: fun = self.functions[fun_name] except KeyError: raise VdtUnknownCheckError(fun_name) else: return fun(value, *fun_args, **fun_kwargs) def _parse_check(self, check): fun_match = self._func_re.match(check) if fun_match: fun_name = fun_match.group(1) arg_string = fun_match.group(2) arg_match = self._matchfinder.match(arg_string) if arg_match is None: # Bad syntax raise VdtParamError('Bad syntax in check "%s".' % check) fun_args = [] fun_kwargs = {} # pull out args of group 2 for arg in self._paramfinder.findall(arg_string): # args may need whitespace removing (before removing quotes) arg = arg.strip() listmatch = self._list_arg.match(arg) if listmatch: key, val = self._list_handle(listmatch) fun_kwargs[key] = val continue keymatch = self._key_arg.match(arg) if keymatch: val = keymatch.group(2) if not val in ("'None'", '"None"'): # Special case a quoted None val = self._unquote(val) fun_kwargs[keymatch.group(1)] = val continue fun_args.append(self._unquote(arg)) else: # allows for function names without (args) return check, (), {}, None # Default must be deleted if the value is specified too, # otherwise the check function will get a spurious "default" keyword arg default = fun_kwargs.pop('default', None) return fun_name, fun_args, fun_kwargs, default def _unquote(self, val): """Unquote a value if necessary.""" if (len(val) >= 2) and (val[0] in ("'", '"')) and (val[0] == val[-1]): val = val[1:-1] return val def _list_handle(self, listmatch): """Take apart a ``keyword=list('val, 'val')`` type string.""" out = [] name = listmatch.group(1) args = listmatch.group(2) for arg in self._list_members.findall(args): out.append(self._unquote(arg)) return name, out def _pass(self, value): """ Dummy check that always passes >>> vtor.check('', 0) 0 >>> vtor.check('', '0') '0' """ return value def get_default_value(self, check): """ Given a check, return the default value for the check (converted to the right type). If the check doesn't specify a default value then a ``KeyError`` will be raised. """ fun_name, fun_args, fun_kwargs, default = self._parse_with_caching(check) if default is None: raise KeyError('Check "%s" has no default value.' % check) value = self._handle_none(default) if value is None: return value return self._check_value(value, fun_name, fun_args, fun_kwargs) def _is_num_param(names, values, to_float=False): """ Return numbers from inputs or raise VdtParamError. Lets ``None`` pass through. Pass in keyword argument ``to_float=True`` to use float for the conversion rather than int. >>> _is_num_param(('', ''), (0, 1.0)) [0, 1] >>> _is_num_param(('', ''), (0, 1.0), to_float=True) [0.0, 1.0] >>> _is_num_param(('a'), ('a')) Traceback (most recent call last): VdtParamError: passed an incorrect value "a" for parameter "a". """ fun = to_float and float or int out_params = [] for (name, val) in zip(names, values): if val is None: out_params.append(val) elif isinstance(val, (int, long, float, string_type)): try: out_params.append(fun(val)) except ValueError as e: raise VdtParamError(name, val) else: raise VdtParamError(name, val) return out_params # built in checks # you can override these by setting the appropriate name # in Validator.functions # note: if the params are specified wrongly in your input string, # you will also raise errors. def is_integer(value, min=None, max=None): """ A check that tests that a given value is an integer (int, or long) and optionally, between bounds. A negative value is accepted, while a float will fail. If the value is a string, then the conversion is done - if possible. Otherwise a VdtError is raised. >>> vtor.check('integer', '-1') -1 >>> vtor.check('integer', '0') 0 >>> vtor.check('integer', 9) 9 >>> vtor.check('integer', 'a') Traceback (most recent call last): VdtTypeError: the value "a" is of the wrong type. >>> vtor.check('integer', '2.2') Traceback (most recent call last): VdtTypeError: the value "2.2" is of the wrong type. >>> vtor.check('integer(10)', '20') 20 >>> vtor.check('integer(max=20)', '15') 15 >>> vtor.check('integer(10)', '9') Traceback (most recent call last): VdtValueTooSmallError: the value "9" is too small. >>> vtor.check('integer(10)', 9) Traceback (most recent call last): VdtValueTooSmallError: the value "9" is too small. >>> vtor.check('integer(max=20)', '35') Traceback (most recent call last): VdtValueTooBigError: the value "35" is too big. >>> vtor.check('integer(max=20)', 35) Traceback (most recent call last): VdtValueTooBigError: the value "35" is too big. >>> vtor.check('integer(0, 9)', False) 0 """ (min_val, max_val) = _is_num_param(('min', 'max'), (min, max)) if not isinstance(value, (int, long, string_type)): raise VdtTypeError(value) if isinstance(value, string_type): # if it's a string - does it represent an integer ? try: value = int(value) except ValueError: raise VdtTypeError(value) if (min_val is not None) and (value < min_val): raise VdtValueTooSmallError(value) if (max_val is not None) and (value > max_val): raise VdtValueTooBigError(value) return value def is_float(value, min=None, max=None): """ A check that tests that a given value is a float (an integer will be accepted), and optionally - that it is between bounds. If the value is a string, then the conversion is done - if possible. Otherwise a VdtError is raised. This can accept negative values. >>> vtor.check('float', '2') 2.0 From now on we multiply the value to avoid comparing decimals >>> vtor.check('float', '-6.8') * 10 -68.0 >>> vtor.check('float', '12.2') * 10 122.0 >>> vtor.check('float', 8.4) * 10 84.0 >>> vtor.check('float', 'a') Traceback (most recent call last): VdtTypeError: the value "a" is of the wrong type. >>> vtor.check('float(10.1)', '10.2') * 10 102.0 >>> vtor.check('float(max=20.2)', '15.1') * 10 151.0 >>> vtor.check('float(10.0)', '9.0') Traceback (most recent call last): VdtValueTooSmallError: the value "9.0" is too small. >>> vtor.check('float(max=20.0)', '35.0') Traceback (most recent call last): VdtValueTooBigError: the value "35.0" is too big. """ (min_val, max_val) = _is_num_param( ('min', 'max'), (min, max), to_float=True) if not isinstance(value, (int, long, float, string_type)): raise VdtTypeError(value) if not isinstance(value, float): # if it's a string - does it represent a float ? try: value = float(value) except ValueError: raise VdtTypeError(value) if (min_val is not None) and (value < min_val): raise VdtValueTooSmallError(value) if (max_val is not None) and (value > max_val): raise VdtValueTooBigError(value) return value bool_dict = { True: True, 'on': True, '1': True, 'true': True, 'yes': True, False: False, 'off': False, '0': False, 'false': False, 'no': False, } def is_boolean(value): """ Check if the value represents a boolean. >>> vtor.check('boolean', 0) 0 >>> vtor.check('boolean', False) 0 >>> vtor.check('boolean', '0') 0 >>> vtor.check('boolean', 'off') 0 >>> vtor.check('boolean', 'false') 0 >>> vtor.check('boolean', 'no') 0 >>> vtor.check('boolean', 'nO') 0 >>> vtor.check('boolean', 'NO') 0 >>> vtor.check('boolean', 1) 1 >>> vtor.check('boolean', True) 1 >>> vtor.check('boolean', '1') 1 >>> vtor.check('boolean', 'on') 1 >>> vtor.check('boolean', 'true') 1 >>> vtor.check('boolean', 'yes') 1 >>> vtor.check('boolean', 'Yes') 1 >>> vtor.check('boolean', 'YES') 1 >>> vtor.check('boolean', '') Traceback (most recent call last): VdtTypeError: the value "" is of the wrong type. >>> vtor.check('boolean', 'up') Traceback (most recent call last): VdtTypeError: the value "up" is of the wrong type. """ if isinstance(value, string_type): try: return bool_dict[value.lower()] except KeyError: raise VdtTypeError(value) # we do an equality test rather than an identity test # this ensures Python 2.2 compatibilty # and allows 0 and 1 to represent True and False if value == False: return False elif value == True: return True else: raise VdtTypeError(value) def is_ip_addr(value): """ Check that the supplied value is an Internet Protocol address, v.4, represented by a dotted-quad string, i.e. '1.2.3.4'. >>> vtor.check('ip_addr', '1 ') '1' >>> vtor.check('ip_addr', ' 1.2') '1.2' >>> vtor.check('ip_addr', ' 1.2.3 ') '1.2.3' >>> vtor.check('ip_addr', '1.2.3.4') '1.2.3.4' >>> vtor.check('ip_addr', '0.0.0.0') '0.0.0.0' >>> vtor.check('ip_addr', '255.255.255.255') '255.255.255.255' >>> vtor.check('ip_addr', '255.255.255.256') Traceback (most recent call last): VdtValueError: the value "255.255.255.256" is unacceptable. >>> vtor.check('ip_addr', '1.2.3.4.5') Traceback (most recent call last): VdtValueError: the value "1.2.3.4.5" is unacceptable. >>> vtor.check('ip_addr', 0) Traceback (most recent call last): VdtTypeError: the value "0" is of the wrong type. """ if not isinstance(value, string_type): raise VdtTypeError(value) value = value.strip() try: dottedQuadToNum(value) except ValueError: raise VdtValueError(value) return value def is_list(value, min=None, max=None): """ Check that the value is a list of values. You can optionally specify the minimum and maximum number of members. It does no check on list members. >>> vtor.check('list', ()) [] >>> vtor.check('list', []) [] >>> vtor.check('list', (1, 2)) [1, 2] >>> vtor.check('list', [1, 2]) [1, 2] >>> vtor.check('list(3)', (1, 2)) Traceback (most recent call last): VdtValueTooShortError: the value "(1, 2)" is too short. >>> vtor.check('list(max=5)', (1, 2, 3, 4, 5, 6)) Traceback (most recent call last): VdtValueTooLongError: the value "(1, 2, 3, 4, 5, 6)" is too long. >>> vtor.check('list(min=3, max=5)', (1, 2, 3, 4)) [1, 2, 3, 4] >>> vtor.check('list', 0) Traceback (most recent call last): VdtTypeError: the value "0" is of the wrong type. >>> vtor.check('list', '12') Traceback (most recent call last): VdtTypeError: the value "12" is of the wrong type. """ (min_len, max_len) = _is_num_param(('min', 'max'), (min, max)) if isinstance(value, string_type): raise VdtTypeError(value) try: num_members = len(value) except TypeError: raise VdtTypeError(value) if min_len is not None and num_members < min_len: raise VdtValueTooShortError(value) if max_len is not None and num_members > max_len: raise VdtValueTooLongError(value) return list(value) def is_tuple(value, min=None, max=None): """ Check that the value is a tuple of values. You can optionally specify the minimum and maximum number of members. It does no check on members. >>> vtor.check('tuple', ()) () >>> vtor.check('tuple', []) () >>> vtor.check('tuple', (1, 2)) (1, 2) >>> vtor.check('tuple', [1, 2]) (1, 2) >>> vtor.check('tuple(3)', (1, 2)) Traceback (most recent call last): VdtValueTooShortError: the value "(1, 2)" is too short. >>> vtor.check('tuple(max=5)', (1, 2, 3, 4, 5, 6)) Traceback (most recent call last): VdtValueTooLongError: the value "(1, 2, 3, 4, 5, 6)" is too long. >>> vtor.check('tuple(min=3, max=5)', (1, 2, 3, 4)) (1, 2, 3, 4) >>> vtor.check('tuple', 0) Traceback (most recent call last): VdtTypeError: the value "0" is of the wrong type. >>> vtor.check('tuple', '12') Traceback (most recent call last): VdtTypeError: the value "12" is of the wrong type. """ return tuple(is_list(value, min, max)) def is_string(value, min=None, max=None): """ Check that the supplied value is a string. You can optionally specify the minimum and maximum number of members. >>> vtor.check('string', '0') '0' >>> vtor.check('string', 0) Traceback (most recent call last): VdtTypeError: the value "0" is of the wrong type. >>> vtor.check('string(2)', '12') '12' >>> vtor.check('string(2)', '1') Traceback (most recent call last): VdtValueTooShortError: the value "1" is too short. >>> vtor.check('string(min=2, max=3)', '123') '123' >>> vtor.check('string(min=2, max=3)', '1234') Traceback (most recent call last): VdtValueTooLongError: the value "1234" is too long. """ if not isinstance(value, string_type): raise VdtTypeError(value) (min_len, max_len) = _is_num_param(('min', 'max'), (min, max)) try: num_members = len(value) except TypeError: raise VdtTypeError(value) if min_len is not None and num_members < min_len: raise VdtValueTooShortError(value) if max_len is not None and num_members > max_len: raise VdtValueTooLongError(value) return value def is_int_list(value, min=None, max=None): """ Check that the value is a list of integers. You can optionally specify the minimum and maximum number of members. Each list member is checked that it is an integer. >>> vtor.check('int_list', ()) [] >>> vtor.check('int_list', []) [] >>> vtor.check('int_list', (1, 2)) [1, 2] >>> vtor.check('int_list', [1, 2]) [1, 2] >>> vtor.check('int_list', [1, 'a']) Traceback (most recent call last): VdtTypeError: the value "a" is of the wrong type. """ return [is_integer(mem) for mem in is_list(value, min, max)] def is_bool_list(value, min=None, max=None): """ Check that the value is a list of booleans. You can optionally specify the minimum and maximum number of members. Each list member is checked that it is a boolean. >>> vtor.check('bool_list', ()) [] >>> vtor.check('bool_list', []) [] >>> check_res = vtor.check('bool_list', (True, False)) >>> check_res == [True, False] 1 >>> check_res = vtor.check('bool_list', [True, False]) >>> check_res == [True, False] 1 >>> vtor.check('bool_list', [True, 'a']) Traceback (most recent call last): VdtTypeError: the value "a" is of the wrong type. """ return [is_boolean(mem) for mem in is_list(value, min, max)] def is_float_list(value, min=None, max=None): """ Check that the value is a list of floats. You can optionally specify the minimum and maximum number of members. Each list member is checked that it is a float. >>> vtor.check('float_list', ()) [] >>> vtor.check('float_list', []) [] >>> vtor.check('float_list', (1, 2.0)) [1.0, 2.0] >>> vtor.check('float_list', [1, 2.0]) [1.0, 2.0] >>> vtor.check('float_list', [1, 'a']) Traceback (most recent call last): VdtTypeError: the value "a" is of the wrong type. """ return [is_float(mem) for mem in is_list(value, min, max)] def is_string_list(value, min=None, max=None): """ Check that the value is a list of strings. You can optionally specify the minimum and maximum number of members. Each list member is checked that it is a string. >>> vtor.check('string_list', ()) [] >>> vtor.check('string_list', []) [] >>> vtor.check('string_list', ('a', 'b')) ['a', 'b'] >>> vtor.check('string_list', ['a', 1]) Traceback (most recent call last): VdtTypeError: the value "1" is of the wrong type. >>> vtor.check('string_list', 'hello') Traceback (most recent call last): VdtTypeError: the value "hello" is of the wrong type. """ if isinstance(value, string_type): raise VdtTypeError(value) return [is_string(mem) for mem in is_list(value, min, max)] def is_ip_addr_list(value, min=None, max=None): """ Check that the value is a list of IP addresses. You can optionally specify the minimum and maximum number of members. Each list member is checked that it is an IP address. >>> vtor.check('ip_addr_list', ()) [] >>> vtor.check('ip_addr_list', []) [] >>> vtor.check('ip_addr_list', ('1.2.3.4', '5.6.7.8')) ['1.2.3.4', '5.6.7.8'] >>> vtor.check('ip_addr_list', ['a']) Traceback (most recent call last): VdtValueError: the value "a" is unacceptable. """ return [is_ip_addr(mem) for mem in is_list(value, min, max)] def force_list(value, min=None, max=None): """ Check that a value is a list, coercing strings into a list with one member. Useful where users forget the trailing comma that turns a single value into a list. You can optionally specify the minimum and maximum number of members. A minumum of greater than one will fail if the user only supplies a string. >>> vtor.check('force_list', ()) [] >>> vtor.check('force_list', []) [] >>> vtor.check('force_list', 'hello') ['hello'] """ if not isinstance(value, (list, tuple)): value = [value] return is_list(value, min, max) fun_dict = { 'integer': is_integer, 'float': is_float, 'ip_addr': is_ip_addr, 'string': is_string, 'boolean': is_boolean, } def is_mixed_list(value, *args): """ Check that the value is a list. Allow specifying the type of each member. Work on lists of specific lengths. You specify each member as a positional argument specifying type Each type should be one of the following strings : 'integer', 'float', 'ip_addr', 'string', 'boolean' So you can specify a list of two strings, followed by two integers as : mixed_list('string', 'string', 'integer', 'integer') The length of the list must match the number of positional arguments you supply. >>> mix_str = "mixed_list('integer', 'float', 'ip_addr', 'string', 'boolean')" >>> check_res = vtor.check(mix_str, (1, 2.0, '1.2.3.4', 'a', True)) >>> check_res == [1, 2.0, '1.2.3.4', 'a', True] 1 >>> check_res = vtor.check(mix_str, ('1', '2.0', '1.2.3.4', 'a', 'True')) >>> check_res == [1, 2.0, '1.2.3.4', 'a', True] 1 >>> vtor.check(mix_str, ('b', 2.0, '1.2.3.4', 'a', True)) Traceback (most recent call last): VdtTypeError: the value "b" is of the wrong type. >>> vtor.check(mix_str, (1, 2.0, '1.2.3.4', 'a')) Traceback (most recent call last): VdtValueTooShortError: the value "(1, 2.0, '1.2.3.4', 'a')" is too short. >>> vtor.check(mix_str, (1, 2.0, '1.2.3.4', 'a', 1, 'b')) Traceback (most recent call last): VdtValueTooLongError: the value "(1, 2.0, '1.2.3.4', 'a', 1, 'b')" is too long. >>> vtor.check(mix_str, 0) Traceback (most recent call last): VdtTypeError: the value "0" is of the wrong type. >>> vtor.check('mixed_list("yoda")', ('a')) Traceback (most recent call last): VdtParamError: passed an incorrect value "KeyError('yoda',)" for parameter "'mixed_list'" """ try: length = len(value) except TypeError: raise VdtTypeError(value) if length < len(args): raise VdtValueTooShortError(value) elif length > len(args): raise VdtValueTooLongError(value) try: return [fun_dict[arg](val) for arg, val in zip(args, value)] except KeyError as e: raise VdtParamError('mixed_list', e) def is_option(value, *options): """ This check matches the value to any of a set of options. >>> vtor.check('option("yoda", "jedi")', 'yoda') 'yoda' >>> vtor.check('option("yoda", "jedi")', 'jed') Traceback (most recent call last): VdtValueError: the value "jed" is unacceptable. >>> vtor.check('option("yoda", "jedi")', 0) Traceback (most recent call last): VdtTypeError: the value "0" is of the wrong type. """ if not isinstance(value, string_type): raise VdtTypeError(value) if not value in options: raise VdtValueError(value) return value def _test(value, *args, **keywargs): """ A function that exists for test purposes. >>> checks = [ ... '3, 6, min=1, max=3, test=list(a, b, c)', ... '3', ... '3, 6', ... '3,', ... 'min=1, test="a b c"', ... 'min=5, test="a, b, c"', ... 'min=1, max=3, test="a, b, c"', ... 'min=-100, test=-99', ... 'min=1, max=3', ... '3, 6, test="36"', ... '3, 6, test="a, b, c"', ... '3, max=3, test=list("a", "b", "c")', ... '''3, max=3, test=list("'a'", 'b', "x=(c)")''', ... "test='x=fish(3)'", ... ] >>> v = Validator({'test': _test}) >>> for entry in checks: ... pprint(v.check(('test(%s)' % entry), 3)) (3, ('3', '6'), {'max': '3', 'min': '1', 'test': ['a', 'b', 'c']}) (3, ('3',), {}) (3, ('3', '6'), {}) (3, ('3',), {}) (3, (), {'min': '1', 'test': 'a b c'}) (3, (), {'min': '5', 'test': 'a, b, c'}) (3, (), {'max': '3', 'min': '1', 'test': 'a, b, c'}) (3, (), {'min': '-100', 'test': '-99'}) (3, (), {'max': '3', 'min': '1'}) (3, ('3', '6'), {'test': '36'}) (3, ('3', '6'), {'test': 'a, b, c'}) (3, ('3',), {'max': '3', 'test': ['a', 'b', 'c']}) (3, ('3',), {'max': '3', 'test': ["'a'", 'b', 'x=(c)']}) (3, (), {'test': 'x=fish(3)'}) >>> v = Validator() >>> v.check('integer(default=6)', '3') 3 >>> v.check('integer(default=6)', None, True) 6 >>> v.get_default_value('integer(default=6)') 6 >>> v.get_default_value('float(default=6)') 6.0 >>> v.get_default_value('pass(default=None)') >>> v.get_default_value("string(default='None')") 'None' >>> v.get_default_value('pass') Traceback (most recent call last): KeyError: 'Check "pass" has no default value.' >>> v.get_default_value('pass(default=list(1, 2, 3, 4))') ['1', '2', '3', '4'] >>> v = Validator() >>> v.check("pass(default=None)", None, True) >>> v.check("pass(default='None')", None, True) 'None' >>> v.check('pass(default="None")', None, True) 'None' >>> v.check('pass(default=list(1, 2, 3, 4))', None, True) ['1', '2', '3', '4'] Bug test for unicode arguments >>> v = Validator() >>> v.check(unicode('string(min=4)'), unicode('test')) == unicode('test') True >>> v = Validator() >>> v.get_default_value(unicode('string(min=4, default="1234")')) == unicode('1234') True >>> v.check(unicode('string(min=4, default="1234")'), unicode('test')) == unicode('test') True >>> v = Validator() >>> default = v.get_default_value('string(default=None)') >>> default == None 1 """ return (value, args, keywargs) def _test2(): """ >>> >>> v = Validator() >>> v.get_default_value('string(default="#ff00dd")') '#ff00dd' >>> v.get_default_value('integer(default=3) # comment') 3 """ def _test3(): r""" >>> vtor.check('string(default="")', '', missing=True) '' >>> vtor.check('string(default="\n")', '', missing=True) '\n' >>> print(vtor.check('string(default="\n")', '', missing=True)) >>> vtor.check('string()', '\n') '\n' >>> vtor.check('string(default="\n\n\n")', '', missing=True) '\n\n\n' >>> vtor.check('string()', 'random \n text goes here\n\n') 'random \n text goes here\n\n' >>> vtor.check('string(default=" \nrandom text\ngoes \n here\n\n ")', ... '', missing=True) ' \nrandom text\ngoes \n here\n\n ' >>> vtor.check("string(default='\n\n\n')", '', missing=True) '\n\n\n' >>> vtor.check("option('\n','a','b',default='\n')", '', missing=True) '\n' >>> vtor.check("string_list()", ['foo', '\n', 'bar']) ['foo', '\n', 'bar'] >>> vtor.check("string_list(default=list('\n'))", '', missing=True) ['\n'] """ if __name__ == '__main__': # run the code tests in doctest format import sys import doctest m = sys.modules.get('__main__') globs = m.__dict__.copy() globs.update({ 'vtor': Validator(), }) failures, tests = doctest.testmod( m, globs=globs, optionflags=doctest.IGNORE_EXCEPTION_DETAIL | doctest.ELLIPSIS) assert not failures, '{} failures out of {} tests'.format(failures, tests) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.0992455 astropy-5.0.2/astropy/extern/jquery/0000755000175100001710000000000000000000000016572 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/extern/jquery/__init__.py0000644000175100001710000000000000000000000020671 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.0552416 astropy-5.0.2/astropy/extern/jquery/data/0000755000175100001710000000000000000000000017503 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.0992455 astropy-5.0.2/astropy/extern/jquery/data/css/0000755000175100001710000000000000000000000020273 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/extern/jquery/data/css/jquery.dataTables.css0000644000175100001710000003607700000000000024404 0ustar00vstsdocker/* * Table styles */ table.dataTable { width: 100%; margin: 0 auto; clear: both; border-collapse: separate; border-spacing: 0; /* * Header and footer styles */ /* * Body styles */ } table.dataTable thead th, table.dataTable tfoot th { font-weight: bold; } table.dataTable thead th, table.dataTable thead td { padding: 10px 18px; border-bottom: 1px solid #111; } table.dataTable thead th:active, table.dataTable thead td:active { outline: none; } table.dataTable tfoot th, table.dataTable tfoot td { padding: 10px 18px 6px 18px; border-top: 1px solid #111; } table.dataTable thead .sorting, table.dataTable thead .sorting_asc, table.dataTable thead .sorting_desc { cursor: pointer; *cursor: hand; } table.dataTable thead .sorting, table.dataTable thead .sorting_asc, table.dataTable thead .sorting_desc, table.dataTable thead .sorting_asc_disabled, table.dataTable thead .sorting_desc_disabled { background-repeat: no-repeat; background-position: center right; } table.dataTable thead .sorting { background-image: url("../images/sort_both.png"); } table.dataTable thead .sorting_asc { background-image: url("../images/sort_asc.png"); } table.dataTable thead .sorting_desc { background-image: url("../images/sort_desc.png"); } table.dataTable thead .sorting_asc_disabled { background-image: url("../images/sort_asc_disabled.png"); } table.dataTable thead .sorting_desc_disabled { background-image: url("../images/sort_desc_disabled.png"); } table.dataTable tbody tr { background-color: #ffffff; } table.dataTable tbody tr.selected { background-color: #B0BED9; } table.dataTable tbody th, table.dataTable tbody td { padding: 8px 10px; } table.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td { border-top: 1px solid #ddd; } table.dataTable.row-border tbody tr:first-child th, table.dataTable.row-border tbody tr:first-child td, table.dataTable.display tbody tr:first-child th, table.dataTable.display tbody tr:first-child td { border-top: none; } table.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td { border-top: 1px solid #ddd; border-right: 1px solid #ddd; } table.dataTable.cell-border tbody tr th:first-child, table.dataTable.cell-border tbody tr td:first-child { border-left: 1px solid #ddd; } table.dataTable.cell-border tbody tr:first-child th, table.dataTable.cell-border tbody tr:first-child td { border-top: none; } table.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd { background-color: #f9f9f9; } table.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected { background-color: #acbad4; } table.dataTable.hover tbody tr:hover, table.dataTable.display tbody tr:hover { background-color: #f6f6f6; } table.dataTable.hover tbody tr:hover.selected, table.dataTable.display tbody tr:hover.selected { background-color: #aab7d1; } table.dataTable.order-column tbody tr > .sorting_1, table.dataTable.order-column tbody tr > .sorting_2, table.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1, table.dataTable.display tbody tr > .sorting_2, table.dataTable.display tbody tr > .sorting_3 { background-color: #fafafa; } table.dataTable.order-column tbody tr.selected > .sorting_1, table.dataTable.order-column tbody tr.selected > .sorting_2, table.dataTable.order-column tbody tr.selected > .sorting_3, table.dataTable.display tbody tr.selected > .sorting_1, table.dataTable.display tbody tr.selected > .sorting_2, table.dataTable.display tbody tr.selected > .sorting_3 { background-color: #acbad5; } table.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 { background-color: #f1f1f1; } table.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 { background-color: #f3f3f3; } table.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 { background-color: whitesmoke; } table.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 { background-color: #a6b4cd; } table.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 { background-color: #a8b5cf; } table.dataTable.display tbody tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 { background-color: #a9b7d1; } table.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 { background-color: #fafafa; } table.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 { background-color: #fcfcfc; } table.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 { background-color: #fefefe; } table.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 { background-color: #acbad5; } table.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 { background-color: #aebcd6; } table.dataTable.display tbody tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 { background-color: #afbdd8; } table.dataTable.display tbody tr:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1 { background-color: #eaeaea; } table.dataTable.display tbody tr:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2 { background-color: #ececec; } table.dataTable.display tbody tr:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3 { background-color: #efefef; } table.dataTable.display tbody tr:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1 { background-color: #a2aec7; } table.dataTable.display tbody tr:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2 { background-color: #a3b0c9; } table.dataTable.display tbody tr:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3 { background-color: #a5b2cb; } table.dataTable.no-footer { border-bottom: 1px solid #111; } table.dataTable.nowrap th, table.dataTable.nowrap td { white-space: nowrap; } table.dataTable.compact thead th, table.dataTable.compact thead td { padding: 4px 17px 4px 4px; } table.dataTable.compact tfoot th, table.dataTable.compact tfoot td { padding: 4px; } table.dataTable.compact tbody th, table.dataTable.compact tbody td { padding: 4px; } table.dataTable th.dt-left, table.dataTable td.dt-left { text-align: left; } table.dataTable th.dt-center, table.dataTable td.dt-center, table.dataTable td.dataTables_empty { text-align: center; } table.dataTable th.dt-right, table.dataTable td.dt-right { text-align: right; } table.dataTable th.dt-justify, table.dataTable td.dt-justify { text-align: justify; } table.dataTable th.dt-nowrap, table.dataTable td.dt-nowrap { white-space: nowrap; } table.dataTable thead th.dt-head-left, table.dataTable thead td.dt-head-left, table.dataTable tfoot th.dt-head-left, table.dataTable tfoot td.dt-head-left { text-align: left; } table.dataTable thead th.dt-head-center, table.dataTable thead td.dt-head-center, table.dataTable tfoot th.dt-head-center, table.dataTable tfoot td.dt-head-center { text-align: center; } table.dataTable thead th.dt-head-right, table.dataTable thead td.dt-head-right, table.dataTable tfoot th.dt-head-right, table.dataTable tfoot td.dt-head-right { text-align: right; } table.dataTable thead th.dt-head-justify, table.dataTable thead td.dt-head-justify, table.dataTable tfoot th.dt-head-justify, table.dataTable tfoot td.dt-head-justify { text-align: justify; } table.dataTable thead th.dt-head-nowrap, table.dataTable thead td.dt-head-nowrap, table.dataTable tfoot th.dt-head-nowrap, table.dataTable tfoot td.dt-head-nowrap { white-space: nowrap; } table.dataTable tbody th.dt-body-left, table.dataTable tbody td.dt-body-left { text-align: left; } table.dataTable tbody th.dt-body-center, table.dataTable tbody td.dt-body-center { text-align: center; } table.dataTable tbody th.dt-body-right, table.dataTable tbody td.dt-body-right { text-align: right; } table.dataTable tbody th.dt-body-justify, table.dataTable tbody td.dt-body-justify { text-align: justify; } table.dataTable tbody th.dt-body-nowrap, table.dataTable tbody td.dt-body-nowrap { white-space: nowrap; } table.dataTable, table.dataTable th, table.dataTable td { -webkit-box-sizing: content-box; box-sizing: content-box; } /* * Control feature layout */ .dataTables_wrapper { position: relative; clear: both; *zoom: 1; zoom: 1; } .dataTables_wrapper .dataTables_length { float: left; } .dataTables_wrapper .dataTables_filter { float: right; text-align: right; } .dataTables_wrapper .dataTables_filter input { margin-left: 0.5em; } .dataTables_wrapper .dataTables_info { clear: both; float: left; padding-top: 0.755em; } .dataTables_wrapper .dataTables_paginate { float: right; text-align: right; padding-top: 0.25em; } .dataTables_wrapper .dataTables_paginate .paginate_button { box-sizing: border-box; display: inline-block; min-width: 1.5em; padding: 0.5em 1em; margin-left: 2px; text-align: center; text-decoration: none !important; cursor: pointer; *cursor: hand; color: #333 !important; border: 1px solid transparent; border-radius: 2px; } .dataTables_wrapper .dataTables_paginate .paginate_button.current, .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover { color: #333 !important; border: 1px solid #979797; background-color: white; background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, #dcdcdc)); /* Chrome,Safari4+ */ background: -webkit-linear-gradient(top, white 0%, #dcdcdc 100%); /* Chrome10+,Safari5.1+ */ background: -moz-linear-gradient(top, white 0%, #dcdcdc 100%); /* FF3.6+ */ background: -ms-linear-gradient(top, white 0%, #dcdcdc 100%); /* IE10+ */ background: -o-linear-gradient(top, white 0%, #dcdcdc 100%); /* Opera 11.10+ */ background: linear-gradient(to bottom, white 0%, #dcdcdc 100%); /* W3C */ } .dataTables_wrapper .dataTables_paginate .paginate_button.disabled, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active { cursor: default; color: #666 !important; border: 1px solid transparent; background: transparent; box-shadow: none; } .dataTables_wrapper .dataTables_paginate .paginate_button:hover { color: white !important; border: 1px solid #111; background-color: #585858; background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111)); /* Chrome,Safari4+ */ background: -webkit-linear-gradient(top, #585858 0%, #111 100%); /* Chrome10+,Safari5.1+ */ background: -moz-linear-gradient(top, #585858 0%, #111 100%); /* FF3.6+ */ background: -ms-linear-gradient(top, #585858 0%, #111 100%); /* IE10+ */ background: -o-linear-gradient(top, #585858 0%, #111 100%); /* Opera 11.10+ */ background: linear-gradient(to bottom, #585858 0%, #111 100%); /* W3C */ } .dataTables_wrapper .dataTables_paginate .paginate_button:active { outline: none; background-color: #2b2b2b; background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c)); /* Chrome,Safari4+ */ background: -webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); /* Chrome10+,Safari5.1+ */ background: -moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); /* FF3.6+ */ background: -ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); /* IE10+ */ background: -o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); /* Opera 11.10+ */ background: linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%); /* W3C */ box-shadow: inset 0 0 3px #111; } .dataTables_wrapper .dataTables_paginate .ellipsis { padding: 0 1em; } .dataTables_wrapper .dataTables_processing { position: absolute; top: 50%; left: 50%; width: 100%; height: 40px; margin-left: -50%; margin-top: -25px; padding-top: 20px; text-align: center; font-size: 1.2em; background-color: white; background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0))); background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); } .dataTables_wrapper .dataTables_length, .dataTables_wrapper .dataTables_filter, .dataTables_wrapper .dataTables_info, .dataTables_wrapper .dataTables_processing, .dataTables_wrapper .dataTables_paginate { color: #333; } .dataTables_wrapper .dataTables_scroll { clear: both; } .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody { *margin-top: -1px; -webkit-overflow-scrolling: touch; } .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td { vertical-align: middle; } .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th > div.dataTables_sizing, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td > div.dataTables_sizing { height: 0; overflow: hidden; margin: 0 !important; padding: 0 !important; } .dataTables_wrapper.no-footer .dataTables_scrollBody { border-bottom: 1px solid #111; } .dataTables_wrapper.no-footer div.dataTables_scrollHead table, .dataTables_wrapper.no-footer div.dataTables_scrollBody table { border-bottom: none; } .dataTables_wrapper:after { visibility: hidden; display: block; content: ""; clear: both; height: 0; } @media screen and (max-width: 767px) { .dataTables_wrapper .dataTables_info, .dataTables_wrapper .dataTables_paginate { float: none; text-align: center; } .dataTables_wrapper .dataTables_paginate { margin-top: 0.5em; } } @media screen and (max-width: 640px) { .dataTables_wrapper .dataTables_length, .dataTables_wrapper .dataTables_filter { float: none; text-align: center; } .dataTables_wrapper .dataTables_filter { margin-top: 0.5em; } } ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.0992455 astropy-5.0.2/astropy/extern/jquery/data/js/0000755000175100001710000000000000000000000020117 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/extern/jquery/data/js/jquery-3.1.1.js0000644000175100001710000101167200000000000022442 0ustar00vstsdocker/*! * jQuery JavaScript Library v3.1.1 * https://jquery.com/ * * Includes Sizzle.js * https://sizzlejs.com/ * * Copyright jQuery Foundation and other contributors * Released under the MIT license * https://jquery.org/license * * Date: 2016-09-22T22:30Z */ ( function( global, factory ) { "use strict"; if ( typeof module === "object" && typeof module.exports === "object" ) { // For CommonJS and CommonJS-like environments where a proper `window` // is present, execute the factory and get jQuery. // For environments that do not have a `window` with a `document` // (such as Node.js), expose a factory as module.exports. // This accentuates the need for the creation of a real `window`. // e.g. var jQuery = require("jquery")(window); // See ticket #14549 for more info. module.exports = global.document ? factory( global, true ) : function( w ) { if ( !w.document ) { throw new Error( "jQuery requires a window with a document" ); } return factory( w ); }; } else { factory( global ); } // Pass this if window is not defined yet } )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { // Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 // throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode // arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common // enough that all such attempts are guarded in a try block. "use strict"; var arr = []; var document = window.document; var getProto = Object.getPrototypeOf; var slice = arr.slice; var concat = arr.concat; var push = arr.push; var indexOf = arr.indexOf; var class2type = {}; var toString = class2type.toString; var hasOwn = class2type.hasOwnProperty; var fnToString = hasOwn.toString; var ObjectFunctionString = fnToString.call( Object ); var support = {}; function DOMEval( code, doc ) { doc = doc || document; var script = doc.createElement( "script" ); script.text = code; doc.head.appendChild( script ).parentNode.removeChild( script ); } /* global Symbol */ // Defining this global in .eslintrc.json would create a danger of using the global // unguarded in another place, it seems safer to define global only for this module var version = "3.1.1", // Define a local copy of jQuery jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' // Need init if jQuery is called (just allow error to be thrown if not included) return new jQuery.fn.init( selector, context ); }, // Support: Android <=4.0 only // Make sure we trim BOM and NBSP rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, // Matches dashed string for camelizing rmsPrefix = /^-ms-/, rdashAlpha = /-([a-z])/g, // Used by jQuery.camelCase as callback to replace() fcamelCase = function( all, letter ) { return letter.toUpperCase(); }; jQuery.fn = jQuery.prototype = { // The current version of jQuery being used jquery: version, constructor: jQuery, // The default length of a jQuery object is 0 length: 0, toArray: function() { return slice.call( this ); }, // Get the Nth element in the matched element set OR // Get the whole matched element set as a clean array get: function( num ) { // Return all the elements in a clean array if ( num == null ) { return slice.call( this ); } // Return just the one element from the set return num < 0 ? this[ num + this.length ] : this[ num ]; }, // Take an array of elements and push it onto the stack // (returning the new matched element set) pushStack: function( elems ) { // Build a new jQuery matched element set var ret = jQuery.merge( this.constructor(), elems ); // Add the old object onto the stack (as a reference) ret.prevObject = this; // Return the newly-formed element set return ret; }, // Execute a callback for every element in the matched set. each: function( callback ) { return jQuery.each( this, callback ); }, map: function( callback ) { return this.pushStack( jQuery.map( this, function( elem, i ) { return callback.call( elem, i, elem ); } ) ); }, slice: function() { return this.pushStack( slice.apply( this, arguments ) ); }, first: function() { return this.eq( 0 ); }, last: function() { return this.eq( -1 ); }, eq: function( i ) { var len = this.length, j = +i + ( i < 0 ? len : 0 ); return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); }, end: function() { return this.prevObject || this.constructor(); }, // For internal use only. // Behaves like an Array's method, not like a jQuery method. push: push, sort: arr.sort, splice: arr.splice }; jQuery.extend = jQuery.fn.extend = function() { var options, name, src, copy, copyIsArray, clone, target = arguments[ 0 ] || {}, i = 1, length = arguments.length, deep = false; // Handle a deep copy situation if ( typeof target === "boolean" ) { deep = target; // Skip the boolean and the target target = arguments[ i ] || {}; i++; } // Handle case when target is a string or something (possible in deep copy) if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { target = {}; } // Extend jQuery itself if only one argument is passed if ( i === length ) { target = this; i--; } for ( ; i < length; i++ ) { // Only deal with non-null/undefined values if ( ( options = arguments[ i ] ) != null ) { // Extend the base object for ( name in options ) { src = target[ name ]; copy = options[ name ]; // Prevent never-ending loop if ( target === copy ) { continue; } // Recurse if we're merging plain objects or arrays if ( deep && copy && ( jQuery.isPlainObject( copy ) || ( copyIsArray = jQuery.isArray( copy ) ) ) ) { if ( copyIsArray ) { copyIsArray = false; clone = src && jQuery.isArray( src ) ? src : []; } else { clone = src && jQuery.isPlainObject( src ) ? src : {}; } // Never move original objects, clone them target[ name ] = jQuery.extend( deep, clone, copy ); // Don't bring in undefined values } else if ( copy !== undefined ) { target[ name ] = copy; } } } } // Return the modified object return target; }; jQuery.extend( { // Unique for each copy of jQuery on the page expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), // Assume jQuery is ready without the ready module isReady: true, error: function( msg ) { throw new Error( msg ); }, noop: function() {}, isFunction: function( obj ) { return jQuery.type( obj ) === "function"; }, isArray: Array.isArray, isWindow: function( obj ) { return obj != null && obj === obj.window; }, isNumeric: function( obj ) { // As of jQuery 3.0, isNumeric is limited to // strings and numbers (primitives or objects) // that can be coerced to finite numbers (gh-2662) var type = jQuery.type( obj ); return ( type === "number" || type === "string" ) && // parseFloat NaNs numeric-cast false positives ("") // ...but misinterprets leading-number strings, particularly hex literals ("0x...") // subtraction forces infinities to NaN !isNaN( obj - parseFloat( obj ) ); }, isPlainObject: function( obj ) { var proto, Ctor; // Detect obvious negatives // Use toString instead of jQuery.type to catch host objects if ( !obj || toString.call( obj ) !== "[object Object]" ) { return false; } proto = getProto( obj ); // Objects with no prototype (e.g., `Object.create( null )`) are plain if ( !proto ) { return true; } // Objects with prototype are plain iff they were constructed by a global Object function Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; }, isEmptyObject: function( obj ) { /* eslint-disable no-unused-vars */ // See https://github.com/eslint/eslint/issues/6125 var name; for ( name in obj ) { return false; } return true; }, type: function( obj ) { if ( obj == null ) { return obj + ""; } // Support: Android <=2.3 only (functionish RegExp) return typeof obj === "object" || typeof obj === "function" ? class2type[ toString.call( obj ) ] || "object" : typeof obj; }, // Evaluates a script in a global context globalEval: function( code ) { DOMEval( code ); }, // Convert dashed to camelCase; used by the css and data modules // Support: IE <=9 - 11, Edge 12 - 13 // Microsoft forgot to hump their vendor prefix (#9572) camelCase: function( string ) { return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); }, nodeName: function( elem, name ) { return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); }, each: function( obj, callback ) { var length, i = 0; if ( isArrayLike( obj ) ) { length = obj.length; for ( ; i < length; i++ ) { if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { break; } } } else { for ( i in obj ) { if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { break; } } } return obj; }, // Support: Android <=4.0 only trim: function( text ) { return text == null ? "" : ( text + "" ).replace( rtrim, "" ); }, // results is for internal usage only makeArray: function( arr, results ) { var ret = results || []; if ( arr != null ) { if ( isArrayLike( Object( arr ) ) ) { jQuery.merge( ret, typeof arr === "string" ? [ arr ] : arr ); } else { push.call( ret, arr ); } } return ret; }, inArray: function( elem, arr, i ) { return arr == null ? -1 : indexOf.call( arr, elem, i ); }, // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit merge: function( first, second ) { var len = +second.length, j = 0, i = first.length; for ( ; j < len; j++ ) { first[ i++ ] = second[ j ]; } first.length = i; return first; }, grep: function( elems, callback, invert ) { var callbackInverse, matches = [], i = 0, length = elems.length, callbackExpect = !invert; // Go through the array, only saving the items // that pass the validator function for ( ; i < length; i++ ) { callbackInverse = !callback( elems[ i ], i ); if ( callbackInverse !== callbackExpect ) { matches.push( elems[ i ] ); } } return matches; }, // arg is for internal usage only map: function( elems, callback, arg ) { var length, value, i = 0, ret = []; // Go through the array, translating each of the items to their new values if ( isArrayLike( elems ) ) { length = elems.length; for ( ; i < length; i++ ) { value = callback( elems[ i ], i, arg ); if ( value != null ) { ret.push( value ); } } // Go through every key on the object, } else { for ( i in elems ) { value = callback( elems[ i ], i, arg ); if ( value != null ) { ret.push( value ); } } } // Flatten any nested arrays return concat.apply( [], ret ); }, // A global GUID counter for objects guid: 1, // Bind a function to a context, optionally partially applying any // arguments. proxy: function( fn, context ) { var tmp, args, proxy; if ( typeof context === "string" ) { tmp = fn[ context ]; context = fn; fn = tmp; } // Quick check to determine if target is callable, in the spec // this throws a TypeError, but we will just return undefined. if ( !jQuery.isFunction( fn ) ) { return undefined; } // Simulated bind args = slice.call( arguments, 2 ); proxy = function() { return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); }; // Set the guid of unique handler to the same of original handler, so it can be removed proxy.guid = fn.guid = fn.guid || jQuery.guid++; return proxy; }, now: Date.now, // jQuery.support is not used in Core but other projects attach their // properties to it so it needs to exist. support: support } ); if ( typeof Symbol === "function" ) { jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; } // Populate the class2type map jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), function( i, name ) { class2type[ "[object " + name + "]" ] = name.toLowerCase(); } ); function isArrayLike( obj ) { // Support: real iOS 8.2 only (not reproducible in simulator) // `in` check used to prevent JIT error (gh-2145) // hasOwn isn't used here due to false negatives // regarding Nodelist length in IE var length = !!obj && "length" in obj && obj.length, type = jQuery.type( obj ); if ( type === "function" || jQuery.isWindow( obj ) ) { return false; } return type === "array" || length === 0 || typeof length === "number" && length > 0 && ( length - 1 ) in obj; } var Sizzle = /*! * Sizzle CSS Selector Engine v2.3.3 * https://sizzlejs.com/ * * Copyright jQuery Foundation and other contributors * Released under the MIT license * http://jquery.org/license * * Date: 2016-08-08 */ (function( window ) { var i, support, Expr, getText, isXML, tokenize, compile, select, outermostContext, sortInput, hasDuplicate, // Local document vars setDocument, document, docElem, documentIsHTML, rbuggyQSA, rbuggyMatches, matches, contains, // Instance-specific data expando = "sizzle" + 1 * new Date(), preferredDoc = window.document, dirruns = 0, done = 0, classCache = createCache(), tokenCache = createCache(), compilerCache = createCache(), sortOrder = function( a, b ) { if ( a === b ) { hasDuplicate = true; } return 0; }, // Instance methods hasOwn = ({}).hasOwnProperty, arr = [], pop = arr.pop, push_native = arr.push, push = arr.push, slice = arr.slice, // Use a stripped-down indexOf as it's faster than native // https://jsperf.com/thor-indexof-vs-for/5 indexOf = function( list, elem ) { var i = 0, len = list.length; for ( ; i < len; i++ ) { if ( list[i] === elem ) { return i; } } return -1; }, booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", // Regular expressions // http://www.w3.org/TR/css3-selectors/#whitespace whitespace = "[\\x20\\t\\r\\n\\f]", // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + // Operator (capture 2) "*([*^$|!~]?=)" + whitespace + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + "*\\]", pseudos = ":(" + identifier + ")(?:\\((" + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: // 1. quoted (capture 3; capture 4 or capture 5) "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + // 2. simple (capture 6) "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + // 3. anything else (capture 2) ".*" + ")\\)|)", // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter rwhitespace = new RegExp( whitespace + "+", "g" ), rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), rpseudo = new RegExp( pseudos ), ridentifier = new RegExp( "^" + identifier + "$" ), matchExpr = { "ID": new RegExp( "^#(" + identifier + ")" ), "CLASS": new RegExp( "^\\.(" + identifier + ")" ), "TAG": new RegExp( "^(" + identifier + "|[*])" ), "ATTR": new RegExp( "^" + attributes ), "PSEUDO": new RegExp( "^" + pseudos ), "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), // For use in libraries implementing .is() // We use this for POS matching in `select` "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) }, rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\d$/i, rnative = /^[^{]+\{\s*\[native \w/, // Easily-parseable/retrievable ID or TAG or CLASS selectors rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, rsibling = /[+~]/, // CSS escapes // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), funescape = function( _, escaped, escapedWhitespace ) { var high = "0x" + escaped - 0x10000; // NaN means non-codepoint // Support: Firefox<24 // Workaround erroneous numeric interpretation of +"0x" return high !== high || escapedWhitespace ? escaped : high < 0 ? // BMP codepoint String.fromCharCode( high + 0x10000 ) : // Supplemental Plane codepoint (surrogate pair) String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); }, // CSS string/identifier serialization // https://drafts.csswg.org/cssom/#common-serializing-idioms rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, fcssescape = function( ch, asCodePoint ) { if ( asCodePoint ) { // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER if ( ch === "\0" ) { return "\uFFFD"; } // Control characters and (dependent upon position) numbers get escaped as code points return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; } // Other potentially-special ASCII characters get backslash-escaped return "\\" + ch; }, // Used for iframes // See setDocument() // Removing the function wrapper causes a "Permission Denied" // error in IE unloadHandler = function() { setDocument(); }, disabledAncestor = addCombinator( function( elem ) { return elem.disabled === true && ("form" in elem || "label" in elem); }, { dir: "parentNode", next: "legend" } ); // Optimize for push.apply( _, NodeList ) try { push.apply( (arr = slice.call( preferredDoc.childNodes )), preferredDoc.childNodes ); // Support: Android<4.0 // Detect silently failing push.apply arr[ preferredDoc.childNodes.length ].nodeType; } catch ( e ) { push = { apply: arr.length ? // Leverage slice if possible function( target, els ) { push_native.apply( target, slice.call(els) ); } : // Support: IE<9 // Otherwise append directly function( target, els ) { var j = target.length, i = 0; // Can't trust NodeList.length while ( (target[j++] = els[i++]) ) {} target.length = j - 1; } }; } function Sizzle( selector, context, results, seed ) { var m, i, elem, nid, match, groups, newSelector, newContext = context && context.ownerDocument, // nodeType defaults to 9, since context defaults to document nodeType = context ? context.nodeType : 9; results = results || []; // Return early from calls with invalid selector or context if ( typeof selector !== "string" || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { return results; } // Try to shortcut find operations (as opposed to filters) in HTML documents if ( !seed ) { if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { setDocument( context ); } context = context || document; if ( documentIsHTML ) { // If the selector is sufficiently simple, try using a "get*By*" DOM method // (excepting DocumentFragment context, where the methods don't exist) if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { // ID selector if ( (m = match[1]) ) { // Document context if ( nodeType === 9 ) { if ( (elem = context.getElementById( m )) ) { // Support: IE, Opera, Webkit // TODO: identify versions // getElementById can match elements by name instead of ID if ( elem.id === m ) { results.push( elem ); return results; } } else { return results; } // Element context } else { // Support: IE, Opera, Webkit // TODO: identify versions // getElementById can match elements by name instead of ID if ( newContext && (elem = newContext.getElementById( m )) && contains( context, elem ) && elem.id === m ) { results.push( elem ); return results; } } // Type selector } else if ( match[2] ) { push.apply( results, context.getElementsByTagName( selector ) ); return results; // Class selector } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { push.apply( results, context.getElementsByClassName( m ) ); return results; } } // Take advantage of querySelectorAll if ( support.qsa && !compilerCache[ selector + " " ] && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { if ( nodeType !== 1 ) { newContext = context; newSelector = selector; // qSA looks outside Element context, which is not what we want // Thanks to Andrew Dupont for this workaround technique // Support: IE <=8 // Exclude object elements } else if ( context.nodeName.toLowerCase() !== "object" ) { // Capture the context ID, setting it first if necessary if ( (nid = context.getAttribute( "id" )) ) { nid = nid.replace( rcssescape, fcssescape ); } else { context.setAttribute( "id", (nid = expando) ); } // Prefix every selector in the list groups = tokenize( selector ); i = groups.length; while ( i-- ) { groups[i] = "#" + nid + " " + toSelector( groups[i] ); } newSelector = groups.join( "," ); // Expand context for sibling selectors newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; } if ( newSelector ) { try { push.apply( results, newContext.querySelectorAll( newSelector ) ); return results; } catch ( qsaError ) { } finally { if ( nid === expando ) { context.removeAttribute( "id" ); } } } } } } // All others return select( selector.replace( rtrim, "$1" ), context, results, seed ); } /** * Create key-value caches of limited size * @returns {function(string, object)} Returns the Object data after storing it on itself with * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) * deleting the oldest entry */ function createCache() { var keys = []; function cache( key, value ) { // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) if ( keys.push( key + " " ) > Expr.cacheLength ) { // Only keep the most recent entries delete cache[ keys.shift() ]; } return (cache[ key + " " ] = value); } return cache; } /** * Mark a function for special use by Sizzle * @param {Function} fn The function to mark */ function markFunction( fn ) { fn[ expando ] = true; return fn; } /** * Support testing using an element * @param {Function} fn Passed the created element and returns a boolean result */ function assert( fn ) { var el = document.createElement("fieldset"); try { return !!fn( el ); } catch (e) { return false; } finally { // Remove from its parent by default if ( el.parentNode ) { el.parentNode.removeChild( el ); } // release memory in IE el = null; } } /** * Adds the same handler for all of the specified attrs * @param {String} attrs Pipe-separated list of attributes * @param {Function} handler The method that will be applied */ function addHandle( attrs, handler ) { var arr = attrs.split("|"), i = arr.length; while ( i-- ) { Expr.attrHandle[ arr[i] ] = handler; } } /** * Checks document order of two siblings * @param {Element} a * @param {Element} b * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b */ function siblingCheck( a, b ) { var cur = b && a, diff = cur && a.nodeType === 1 && b.nodeType === 1 && a.sourceIndex - b.sourceIndex; // Use IE sourceIndex if available on both nodes if ( diff ) { return diff; } // Check if b follows a if ( cur ) { while ( (cur = cur.nextSibling) ) { if ( cur === b ) { return -1; } } } return a ? 1 : -1; } /** * Returns a function to use in pseudos for input types * @param {String} type */ function createInputPseudo( type ) { return function( elem ) { var name = elem.nodeName.toLowerCase(); return name === "input" && elem.type === type; }; } /** * Returns a function to use in pseudos for buttons * @param {String} type */ function createButtonPseudo( type ) { return function( elem ) { var name = elem.nodeName.toLowerCase(); return (name === "input" || name === "button") && elem.type === type; }; } /** * Returns a function to use in pseudos for :enabled/:disabled * @param {Boolean} disabled true for :disabled; false for :enabled */ function createDisabledPseudo( disabled ) { // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable return function( elem ) { // Only certain elements can match :enabled or :disabled // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled if ( "form" in elem ) { // Check for inherited disabledness on relevant non-disabled elements: // * listed form-associated elements in a disabled fieldset // https://html.spec.whatwg.org/multipage/forms.html#category-listed // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled // * option elements in a disabled optgroup // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled // All such elements have a "form" property. if ( elem.parentNode && elem.disabled === false ) { // Option elements defer to a parent optgroup if present if ( "label" in elem ) { if ( "label" in elem.parentNode ) { return elem.parentNode.disabled === disabled; } else { return elem.disabled === disabled; } } // Support: IE 6 - 11 // Use the isDisabled shortcut property to check for disabled fieldset ancestors return elem.isDisabled === disabled || // Where there is no isDisabled, check manually /* jshint -W018 */ elem.isDisabled !== !disabled && disabledAncestor( elem ) === disabled; } return elem.disabled === disabled; // Try to winnow out elements that can't be disabled before trusting the disabled property. // Some victims get caught in our net (label, legend, menu, track), but it shouldn't // even exist on them, let alone have a boolean value. } else if ( "label" in elem ) { return elem.disabled === disabled; } // Remaining elements are neither :enabled nor :disabled return false; }; } /** * Returns a function to use in pseudos for positionals * @param {Function} fn */ function createPositionalPseudo( fn ) { return markFunction(function( argument ) { argument = +argument; return markFunction(function( seed, matches ) { var j, matchIndexes = fn( [], seed.length, argument ), i = matchIndexes.length; // Match elements found at the specified indexes while ( i-- ) { if ( seed[ (j = matchIndexes[i]) ] ) { seed[j] = !(matches[j] = seed[j]); } } }); }); } /** * Checks a node for validity as a Sizzle context * @param {Element|Object=} context * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value */ function testContext( context ) { return context && typeof context.getElementsByTagName !== "undefined" && context; } // Expose support vars for convenience support = Sizzle.support = {}; /** * Detects XML nodes * @param {Element|Object} elem An element or a document * @returns {Boolean} True iff elem is a non-HTML XML node */ isXML = Sizzle.isXML = function( elem ) { // documentElement is verified for cases where it doesn't yet exist // (such as loading iframes in IE - #4833) var documentElement = elem && (elem.ownerDocument || elem).documentElement; return documentElement ? documentElement.nodeName !== "HTML" : false; }; /** * Sets document-related variables once based on the current document * @param {Element|Object} [doc] An element or document object to use to set the document * @returns {Object} Returns the current document */ setDocument = Sizzle.setDocument = function( node ) { var hasCompare, subWindow, doc = node ? node.ownerDocument || node : preferredDoc; // Return early if doc is invalid or already selected if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { return document; } // Update global variables document = doc; docElem = document.documentElement; documentIsHTML = !isXML( document ); // Support: IE 9-11, Edge // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) if ( preferredDoc !== document && (subWindow = document.defaultView) && subWindow.top !== subWindow ) { // Support: IE 11, Edge if ( subWindow.addEventListener ) { subWindow.addEventListener( "unload", unloadHandler, false ); // Support: IE 9 - 10 only } else if ( subWindow.attachEvent ) { subWindow.attachEvent( "onunload", unloadHandler ); } } /* Attributes ---------------------------------------------------------------------- */ // Support: IE<8 // Verify that getAttribute really returns attributes and not properties // (excepting IE8 booleans) support.attributes = assert(function( el ) { el.className = "i"; return !el.getAttribute("className"); }); /* getElement(s)By* ---------------------------------------------------------------------- */ // Check if getElementsByTagName("*") returns only elements support.getElementsByTagName = assert(function( el ) { el.appendChild( document.createComment("") ); return !el.getElementsByTagName("*").length; }); // Support: IE<9 support.getElementsByClassName = rnative.test( document.getElementsByClassName ); // Support: IE<10 // Check if getElementById returns elements by name // The broken getElementById methods don't pick up programmatically-set names, // so use a roundabout getElementsByName test support.getById = assert(function( el ) { docElem.appendChild( el ).id = expando; return !document.getElementsByName || !document.getElementsByName( expando ).length; }); // ID filter and find if ( support.getById ) { Expr.filter["ID"] = function( id ) { var attrId = id.replace( runescape, funescape ); return function( elem ) { return elem.getAttribute("id") === attrId; }; }; Expr.find["ID"] = function( id, context ) { if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { var elem = context.getElementById( id ); return elem ? [ elem ] : []; } }; } else { Expr.filter["ID"] = function( id ) { var attrId = id.replace( runescape, funescape ); return function( elem ) { var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); return node && node.value === attrId; }; }; // Support: IE 6 - 7 only // getElementById is not reliable as a find shortcut Expr.find["ID"] = function( id, context ) { if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { var node, i, elems, elem = context.getElementById( id ); if ( elem ) { // Verify the id attribute node = elem.getAttributeNode("id"); if ( node && node.value === id ) { return [ elem ]; } // Fall back on getElementsByName elems = context.getElementsByName( id ); i = 0; while ( (elem = elems[i++]) ) { node = elem.getAttributeNode("id"); if ( node && node.value === id ) { return [ elem ]; } } } return []; } }; } // Tag Expr.find["TAG"] = support.getElementsByTagName ? function( tag, context ) { if ( typeof context.getElementsByTagName !== "undefined" ) { return context.getElementsByTagName( tag ); // DocumentFragment nodes don't have gEBTN } else if ( support.qsa ) { return context.querySelectorAll( tag ); } } : function( tag, context ) { var elem, tmp = [], i = 0, // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too results = context.getElementsByTagName( tag ); // Filter out possible comments if ( tag === "*" ) { while ( (elem = results[i++]) ) { if ( elem.nodeType === 1 ) { tmp.push( elem ); } } return tmp; } return results; }; // Class Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { return context.getElementsByClassName( className ); } }; /* QSA/matchesSelector ---------------------------------------------------------------------- */ // QSA and matchesSelector support // matchesSelector(:active) reports false when true (IE9/Opera 11.5) rbuggyMatches = []; // qSa(:focus) reports false when true (Chrome 21) // We allow this because of a bug in IE8/9 that throws an error // whenever `document.activeElement` is accessed on an iframe // So, we allow :focus to pass through QSA all the time to avoid the IE error // See https://bugs.jquery.com/ticket/13378 rbuggyQSA = []; if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { // Build QSA regex // Regex strategy adopted from Diego Perini assert(function( el ) { // Select is set to empty string on purpose // This is to test IE's treatment of not explicitly // setting a boolean content attribute, // since its presence should be enough // https://bugs.jquery.com/ticket/12359 docElem.appendChild( el ).innerHTML = "" + ""; // Support: IE8, Opera 11-12.16 // Nothing should be selected when empty strings follow ^= or $= or *= // The test attribute must be unknown in Opera but "safe" for WinRT // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section if ( el.querySelectorAll("[msallowcapture^='']").length ) { rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); } // Support: IE8 // Boolean attributes and "value" are not treated correctly if ( !el.querySelectorAll("[selected]").length ) { rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); } // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { rbuggyQSA.push("~="); } // Webkit/Opera - :checked should return selected option elements // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked // IE8 throws error here and will not see later tests if ( !el.querySelectorAll(":checked").length ) { rbuggyQSA.push(":checked"); } // Support: Safari 8+, iOS 8+ // https://bugs.webkit.org/show_bug.cgi?id=136851 // In-page `selector#id sibling-combinator selector` fails if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { rbuggyQSA.push(".#.+[+~]"); } }); assert(function( el ) { el.innerHTML = "" + ""; // Support: Windows 8 Native Apps // The type and name attributes are restricted during .innerHTML assignment var input = document.createElement("input"); input.setAttribute( "type", "hidden" ); el.appendChild( input ).setAttribute( "name", "D" ); // Support: IE8 // Enforce case-sensitivity of name attribute if ( el.querySelectorAll("[name=d]").length ) { rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); } // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) // IE8 throws error here and will not see later tests if ( el.querySelectorAll(":enabled").length !== 2 ) { rbuggyQSA.push( ":enabled", ":disabled" ); } // Support: IE9-11+ // IE's :disabled selector does not pick up the children of disabled fieldsets docElem.appendChild( el ).disabled = true; if ( el.querySelectorAll(":disabled").length !== 2 ) { rbuggyQSA.push( ":enabled", ":disabled" ); } // Opera 10-11 does not throw on post-comma invalid pseudos el.querySelectorAll("*,:x"); rbuggyQSA.push(",.*:"); }); } if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || docElem.webkitMatchesSelector || docElem.mozMatchesSelector || docElem.oMatchesSelector || docElem.msMatchesSelector) )) ) { assert(function( el ) { // Check to see if it's possible to do matchesSelector // on a disconnected node (IE 9) support.disconnectedMatch = matches.call( el, "*" ); // This should fail with an exception // Gecko does not error, returns false instead matches.call( el, "[s!='']:x" ); rbuggyMatches.push( "!=", pseudos ); }); } rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); /* Contains ---------------------------------------------------------------------- */ hasCompare = rnative.test( docElem.compareDocumentPosition ); // Element contains another // Purposefully self-exclusive // As in, an element does not contain itself contains = hasCompare || rnative.test( docElem.contains ) ? function( a, b ) { var adown = a.nodeType === 9 ? a.documentElement : a, bup = b && b.parentNode; return a === bup || !!( bup && bup.nodeType === 1 && ( adown.contains ? adown.contains( bup ) : a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 )); } : function( a, b ) { if ( b ) { while ( (b = b.parentNode) ) { if ( b === a ) { return true; } } } return false; }; /* Sorting ---------------------------------------------------------------------- */ // Document order sorting sortOrder = hasCompare ? function( a, b ) { // Flag for duplicate removal if ( a === b ) { hasDuplicate = true; return 0; } // Sort on method existence if only one input has compareDocumentPosition var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; if ( compare ) { return compare; } // Calculate position if both inputs belong to the same document compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? a.compareDocumentPosition( b ) : // Otherwise we know they are disconnected 1; // Disconnected nodes if ( compare & 1 || (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { // Choose the first element that is related to our preferred document if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { return -1; } if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { return 1; } // Maintain original order return sortInput ? ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 0; } return compare & 4 ? -1 : 1; } : function( a, b ) { // Exit early if the nodes are identical if ( a === b ) { hasDuplicate = true; return 0; } var cur, i = 0, aup = a.parentNode, bup = b.parentNode, ap = [ a ], bp = [ b ]; // Parentless nodes are either documents or disconnected if ( !aup || !bup ) { return a === document ? -1 : b === document ? 1 : aup ? -1 : bup ? 1 : sortInput ? ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 0; // If the nodes are siblings, we can do a quick check } else if ( aup === bup ) { return siblingCheck( a, b ); } // Otherwise we need full lists of their ancestors for comparison cur = a; while ( (cur = cur.parentNode) ) { ap.unshift( cur ); } cur = b; while ( (cur = cur.parentNode) ) { bp.unshift( cur ); } // Walk down the tree looking for a discrepancy while ( ap[i] === bp[i] ) { i++; } return i ? // Do a sibling check if the nodes have a common ancestor siblingCheck( ap[i], bp[i] ) : // Otherwise nodes in our document sort first ap[i] === preferredDoc ? -1 : bp[i] === preferredDoc ? 1 : 0; }; return document; }; Sizzle.matches = function( expr, elements ) { return Sizzle( expr, null, null, elements ); }; Sizzle.matchesSelector = function( elem, expr ) { // Set document vars if needed if ( ( elem.ownerDocument || elem ) !== document ) { setDocument( elem ); } // Make sure that attribute selectors are quoted expr = expr.replace( rattributeQuotes, "='$1']" ); if ( support.matchesSelector && documentIsHTML && !compilerCache[ expr + " " ] && ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { try { var ret = matches.call( elem, expr ); // IE 9's matchesSelector returns false on disconnected nodes if ( ret || support.disconnectedMatch || // As well, disconnected nodes are said to be in a document // fragment in IE 9 elem.document && elem.document.nodeType !== 11 ) { return ret; } } catch (e) {} } return Sizzle( expr, document, null, [ elem ] ).length > 0; }; Sizzle.contains = function( context, elem ) { // Set document vars if needed if ( ( context.ownerDocument || context ) !== document ) { setDocument( context ); } return contains( context, elem ); }; Sizzle.attr = function( elem, name ) { // Set document vars if needed if ( ( elem.ownerDocument || elem ) !== document ) { setDocument( elem ); } var fn = Expr.attrHandle[ name.toLowerCase() ], // Don't get fooled by Object.prototype properties (jQuery #13807) val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? fn( elem, name, !documentIsHTML ) : undefined; return val !== undefined ? val : support.attributes || !documentIsHTML ? elem.getAttribute( name ) : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null; }; Sizzle.escape = function( sel ) { return (sel + "").replace( rcssescape, fcssescape ); }; Sizzle.error = function( msg ) { throw new Error( "Syntax error, unrecognized expression: " + msg ); }; /** * Document sorting and removing duplicates * @param {ArrayLike} results */ Sizzle.uniqueSort = function( results ) { var elem, duplicates = [], j = 0, i = 0; // Unless we *know* we can detect duplicates, assume their presence hasDuplicate = !support.detectDuplicates; sortInput = !support.sortStable && results.slice( 0 ); results.sort( sortOrder ); if ( hasDuplicate ) { while ( (elem = results[i++]) ) { if ( elem === results[ i ] ) { j = duplicates.push( i ); } } while ( j-- ) { results.splice( duplicates[ j ], 1 ); } } // Clear input after sorting to release objects // See https://github.com/jquery/sizzle/pull/225 sortInput = null; return results; }; /** * Utility function for retrieving the text value of an array of DOM nodes * @param {Array|Element} elem */ getText = Sizzle.getText = function( elem ) { var node, ret = "", i = 0, nodeType = elem.nodeType; if ( !nodeType ) { // If no nodeType, this is expected to be an array while ( (node = elem[i++]) ) { // Do not traverse comment nodes ret += getText( node ); } } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { // Use textContent for elements // innerText usage removed for consistency of new lines (jQuery #11153) if ( typeof elem.textContent === "string" ) { return elem.textContent; } else { // Traverse its children for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { ret += getText( elem ); } } } else if ( nodeType === 3 || nodeType === 4 ) { return elem.nodeValue; } // Do not include comment or processing instruction nodes return ret; }; Expr = Sizzle.selectors = { // Can be adjusted by the user cacheLength: 50, createPseudo: markFunction, match: matchExpr, attrHandle: {}, find: {}, relative: { ">": { dir: "parentNode", first: true }, " ": { dir: "parentNode" }, "+": { dir: "previousSibling", first: true }, "~": { dir: "previousSibling" } }, preFilter: { "ATTR": function( match ) { match[1] = match[1].replace( runescape, funescape ); // Move the given value to match[3] whether quoted or unquoted match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); if ( match[2] === "~=" ) { match[3] = " " + match[3] + " "; } return match.slice( 0, 4 ); }, "CHILD": function( match ) { /* matches from matchExpr["CHILD"] 1 type (only|nth|...) 2 what (child|of-type) 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 4 xn-component of xn+y argument ([+-]?\d*n|) 5 sign of xn-component 6 x of xn-component 7 sign of y-component 8 y of y-component */ match[1] = match[1].toLowerCase(); if ( match[1].slice( 0, 3 ) === "nth" ) { // nth-* requires argument if ( !match[3] ) { Sizzle.error( match[0] ); } // numeric x and y parameters for Expr.filter.CHILD // remember that false/true cast respectively to 0/1 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); // other types prohibit arguments } else if ( match[3] ) { Sizzle.error( match[0] ); } return match; }, "PSEUDO": function( match ) { var excess, unquoted = !match[6] && match[2]; if ( matchExpr["CHILD"].test( match[0] ) ) { return null; } // Accept quoted arguments as-is if ( match[3] ) { match[2] = match[4] || match[5] || ""; // Strip excess characters from unquoted arguments } else if ( unquoted && rpseudo.test( unquoted ) && // Get excess from tokenize (recursively) (excess = tokenize( unquoted, true )) && // advance to the next closing parenthesis (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { // excess is a negative index match[0] = match[0].slice( 0, excess ); match[2] = unquoted.slice( 0, excess ); } // Return only captures needed by the pseudo filter method (type and argument) return match.slice( 0, 3 ); } }, filter: { "TAG": function( nodeNameSelector ) { var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); return nodeNameSelector === "*" ? function() { return true; } : function( elem ) { return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; }; }, "CLASS": function( className ) { var pattern = classCache[ className + " " ]; return pattern || (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && classCache( className, function( elem ) { return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); }); }, "ATTR": function( name, operator, check ) { return function( elem ) { var result = Sizzle.attr( elem, name ); if ( result == null ) { return operator === "!="; } if ( !operator ) { return true; } result += ""; return operator === "=" ? result === check : operator === "!=" ? result !== check : operator === "^=" ? check && result.indexOf( check ) === 0 : operator === "*=" ? check && result.indexOf( check ) > -1 : operator === "$=" ? check && result.slice( -check.length ) === check : operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : false; }; }, "CHILD": function( type, what, argument, first, last ) { var simple = type.slice( 0, 3 ) !== "nth", forward = type.slice( -4 ) !== "last", ofType = what === "of-type"; return first === 1 && last === 0 ? // Shortcut for :nth-*(n) function( elem ) { return !!elem.parentNode; } : function( elem, context, xml ) { var cache, uniqueCache, outerCache, node, nodeIndex, start, dir = simple !== forward ? "nextSibling" : "previousSibling", parent = elem.parentNode, name = ofType && elem.nodeName.toLowerCase(), useCache = !xml && !ofType, diff = false; if ( parent ) { // :(first|last|only)-(child|of-type) if ( simple ) { while ( dir ) { node = elem; while ( (node = node[ dir ]) ) { if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { return false; } } // Reverse direction for :only-* (if we haven't yet done so) start = dir = type === "only" && !start && "nextSibling"; } return true; } start = [ forward ? parent.firstChild : parent.lastChild ]; // non-xml :nth-child(...) stores cache data on `parent` if ( forward && useCache ) { // Seek `elem` from a previously-cached index // ...in a gzip-friendly way node = parent; outerCache = node[ expando ] || (node[ expando ] = {}); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ node.uniqueID ] || (outerCache[ node.uniqueID ] = {}); cache = uniqueCache[ type ] || []; nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; diff = nodeIndex && cache[ 2 ]; node = nodeIndex && parent.childNodes[ nodeIndex ]; while ( (node = ++nodeIndex && node && node[ dir ] || // Fallback to seeking `elem` from the start (diff = nodeIndex = 0) || start.pop()) ) { // When found, cache indexes on `parent` and break if ( node.nodeType === 1 && ++diff && node === elem ) { uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; break; } } } else { // Use previously-cached element index if available if ( useCache ) { // ...in a gzip-friendly way node = elem; outerCache = node[ expando ] || (node[ expando ] = {}); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ node.uniqueID ] || (outerCache[ node.uniqueID ] = {}); cache = uniqueCache[ type ] || []; nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; diff = nodeIndex; } // xml :nth-child(...) // or :nth-last-child(...) or :nth(-last)?-of-type(...) if ( diff === false ) { // Use the same loop as above to seek `elem` from the start while ( (node = ++nodeIndex && node && node[ dir ] || (diff = nodeIndex = 0) || start.pop()) ) { if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { // Cache the index of each encountered element if ( useCache ) { outerCache = node[ expando ] || (node[ expando ] = {}); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ node.uniqueID ] || (outerCache[ node.uniqueID ] = {}); uniqueCache[ type ] = [ dirruns, diff ]; } if ( node === elem ) { break; } } } } } // Incorporate the offset, then check against cycle size diff -= last; return diff === first || ( diff % first === 0 && diff / first >= 0 ); } }; }, "PSEUDO": function( pseudo, argument ) { // pseudo-class names are case-insensitive // http://www.w3.org/TR/selectors/#pseudo-classes // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters // Remember that setFilters inherits from pseudos var args, fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || Sizzle.error( "unsupported pseudo: " + pseudo ); // The user may use createPseudo to indicate that // arguments are needed to create the filter function // just as Sizzle does if ( fn[ expando ] ) { return fn( argument ); } // But maintain support for old signatures if ( fn.length > 1 ) { args = [ pseudo, pseudo, "", argument ]; return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? markFunction(function( seed, matches ) { var idx, matched = fn( seed, argument ), i = matched.length; while ( i-- ) { idx = indexOf( seed, matched[i] ); seed[ idx ] = !( matches[ idx ] = matched[i] ); } }) : function( elem ) { return fn( elem, 0, args ); }; } return fn; } }, pseudos: { // Potentially complex pseudos "not": markFunction(function( selector ) { // Trim the selector passed to compile // to avoid treating leading and trailing // spaces as combinators var input = [], results = [], matcher = compile( selector.replace( rtrim, "$1" ) ); return matcher[ expando ] ? markFunction(function( seed, matches, context, xml ) { var elem, unmatched = matcher( seed, null, xml, [] ), i = seed.length; // Match elements unmatched by `matcher` while ( i-- ) { if ( (elem = unmatched[i]) ) { seed[i] = !(matches[i] = elem); } } }) : function( elem, context, xml ) { input[0] = elem; matcher( input, null, xml, results ); // Don't keep the element (issue #299) input[0] = null; return !results.pop(); }; }), "has": markFunction(function( selector ) { return function( elem ) { return Sizzle( selector, elem ).length > 0; }; }), "contains": markFunction(function( text ) { text = text.replace( runescape, funescape ); return function( elem ) { return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; }; }), // "Whether an element is represented by a :lang() selector // is based solely on the element's language value // being equal to the identifier C, // or beginning with the identifier C immediately followed by "-". // The matching of C against the element's language value is performed case-insensitively. // The identifier C does not have to be a valid language name." // http://www.w3.org/TR/selectors/#lang-pseudo "lang": markFunction( function( lang ) { // lang value must be a valid identifier if ( !ridentifier.test(lang || "") ) { Sizzle.error( "unsupported lang: " + lang ); } lang = lang.replace( runescape, funescape ).toLowerCase(); return function( elem ) { var elemLang; do { if ( (elemLang = documentIsHTML ? elem.lang : elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { elemLang = elemLang.toLowerCase(); return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; } } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); return false; }; }), // Miscellaneous "target": function( elem ) { var hash = window.location && window.location.hash; return hash && hash.slice( 1 ) === elem.id; }, "root": function( elem ) { return elem === docElem; }, "focus": function( elem ) { return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); }, // Boolean properties "enabled": createDisabledPseudo( false ), "disabled": createDisabledPseudo( true ), "checked": function( elem ) { // In CSS3, :checked should return both checked and selected elements // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked var nodeName = elem.nodeName.toLowerCase(); return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); }, "selected": function( elem ) { // Accessing this property makes selected-by-default // options in Safari work properly if ( elem.parentNode ) { elem.parentNode.selectedIndex; } return elem.selected === true; }, // Contents "empty": function( elem ) { // http://www.w3.org/TR/selectors/#empty-pseudo // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), // but not by others (comment: 8; processing instruction: 7; etc.) // nodeType < 6 works because attributes (2) do not appear as children for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { if ( elem.nodeType < 6 ) { return false; } } return true; }, "parent": function( elem ) { return !Expr.pseudos["empty"]( elem ); }, // Element/input types "header": function( elem ) { return rheader.test( elem.nodeName ); }, "input": function( elem ) { return rinputs.test( elem.nodeName ); }, "button": function( elem ) { var name = elem.nodeName.toLowerCase(); return name === "input" && elem.type === "button" || name === "button"; }, "text": function( elem ) { var attr; return elem.nodeName.toLowerCase() === "input" && elem.type === "text" && // Support: IE<8 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); }, // Position-in-collection "first": createPositionalPseudo(function() { return [ 0 ]; }), "last": createPositionalPseudo(function( matchIndexes, length ) { return [ length - 1 ]; }), "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { return [ argument < 0 ? argument + length : argument ]; }), "even": createPositionalPseudo(function( matchIndexes, length ) { var i = 0; for ( ; i < length; i += 2 ) { matchIndexes.push( i ); } return matchIndexes; }), "odd": createPositionalPseudo(function( matchIndexes, length ) { var i = 1; for ( ; i < length; i += 2 ) { matchIndexes.push( i ); } return matchIndexes; }), "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { var i = argument < 0 ? argument + length : argument; for ( ; --i >= 0; ) { matchIndexes.push( i ); } return matchIndexes; }), "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { var i = argument < 0 ? argument + length : argument; for ( ; ++i < length; ) { matchIndexes.push( i ); } return matchIndexes; }) } }; Expr.pseudos["nth"] = Expr.pseudos["eq"]; // Add button/input type pseudos for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { Expr.pseudos[ i ] = createInputPseudo( i ); } for ( i in { submit: true, reset: true } ) { Expr.pseudos[ i ] = createButtonPseudo( i ); } // Easy API for creating new setFilters function setFilters() {} setFilters.prototype = Expr.filters = Expr.pseudos; Expr.setFilters = new setFilters(); tokenize = Sizzle.tokenize = function( selector, parseOnly ) { var matched, match, tokens, type, soFar, groups, preFilters, cached = tokenCache[ selector + " " ]; if ( cached ) { return parseOnly ? 0 : cached.slice( 0 ); } soFar = selector; groups = []; preFilters = Expr.preFilter; while ( soFar ) { // Comma and first run if ( !matched || (match = rcomma.exec( soFar )) ) { if ( match ) { // Don't consume trailing commas as valid soFar = soFar.slice( match[0].length ) || soFar; } groups.push( (tokens = []) ); } matched = false; // Combinators if ( (match = rcombinators.exec( soFar )) ) { matched = match.shift(); tokens.push({ value: matched, // Cast descendant combinators to space type: match[0].replace( rtrim, " " ) }); soFar = soFar.slice( matched.length ); } // Filters for ( type in Expr.filter ) { if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || (match = preFilters[ type ]( match ))) ) { matched = match.shift(); tokens.push({ value: matched, type: type, matches: match }); soFar = soFar.slice( matched.length ); } } if ( !matched ) { break; } } // Return the length of the invalid excess // if we're just parsing // Otherwise, throw an error or return tokens return parseOnly ? soFar.length : soFar ? Sizzle.error( selector ) : // Cache the tokens tokenCache( selector, groups ).slice( 0 ); }; function toSelector( tokens ) { var i = 0, len = tokens.length, selector = ""; for ( ; i < len; i++ ) { selector += tokens[i].value; } return selector; } function addCombinator( matcher, combinator, base ) { var dir = combinator.dir, skip = combinator.next, key = skip || dir, checkNonElements = base && key === "parentNode", doneName = done++; return combinator.first ? // Check against closest ancestor/preceding element function( elem, context, xml ) { while ( (elem = elem[ dir ]) ) { if ( elem.nodeType === 1 || checkNonElements ) { return matcher( elem, context, xml ); } } return false; } : // Check against all ancestor/preceding elements function( elem, context, xml ) { var oldCache, uniqueCache, outerCache, newCache = [ dirruns, doneName ]; // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching if ( xml ) { while ( (elem = elem[ dir ]) ) { if ( elem.nodeType === 1 || checkNonElements ) { if ( matcher( elem, context, xml ) ) { return true; } } } } else { while ( (elem = elem[ dir ]) ) { if ( elem.nodeType === 1 || checkNonElements ) { outerCache = elem[ expando ] || (elem[ expando ] = {}); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); if ( skip && skip === elem.nodeName.toLowerCase() ) { elem = elem[ dir ] || elem; } else if ( (oldCache = uniqueCache[ key ]) && oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { // Assign to newCache so results back-propagate to previous elements return (newCache[ 2 ] = oldCache[ 2 ]); } else { // Reuse newcache so results back-propagate to previous elements uniqueCache[ key ] = newCache; // A match means we're done; a fail means we have to keep checking if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { return true; } } } } } return false; }; } function elementMatcher( matchers ) { return matchers.length > 1 ? function( elem, context, xml ) { var i = matchers.length; while ( i-- ) { if ( !matchers[i]( elem, context, xml ) ) { return false; } } return true; } : matchers[0]; } function multipleContexts( selector, contexts, results ) { var i = 0, len = contexts.length; for ( ; i < len; i++ ) { Sizzle( selector, contexts[i], results ); } return results; } function condense( unmatched, map, filter, context, xml ) { var elem, newUnmatched = [], i = 0, len = unmatched.length, mapped = map != null; for ( ; i < len; i++ ) { if ( (elem = unmatched[i]) ) { if ( !filter || filter( elem, context, xml ) ) { newUnmatched.push( elem ); if ( mapped ) { map.push( i ); } } } } return newUnmatched; } function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { if ( postFilter && !postFilter[ expando ] ) { postFilter = setMatcher( postFilter ); } if ( postFinder && !postFinder[ expando ] ) { postFinder = setMatcher( postFinder, postSelector ); } return markFunction(function( seed, results, context, xml ) { var temp, i, elem, preMap = [], postMap = [], preexisting = results.length, // Get initial elements from seed or context elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), // Prefilter to get matcher input, preserving a map for seed-results synchronization matcherIn = preFilter && ( seed || !selector ) ? condense( elems, preMap, preFilter, context, xml ) : elems, matcherOut = matcher ? // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, postFinder || ( seed ? preFilter : preexisting || postFilter ) ? // ...intermediate processing is necessary [] : // ...otherwise use results directly results : matcherIn; // Find primary matches if ( matcher ) { matcher( matcherIn, matcherOut, context, xml ); } // Apply postFilter if ( postFilter ) { temp = condense( matcherOut, postMap ); postFilter( temp, [], context, xml ); // Un-match failing elements by moving them back to matcherIn i = temp.length; while ( i-- ) { if ( (elem = temp[i]) ) { matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); } } } if ( seed ) { if ( postFinder || preFilter ) { if ( postFinder ) { // Get the final matcherOut by condensing this intermediate into postFinder contexts temp = []; i = matcherOut.length; while ( i-- ) { if ( (elem = matcherOut[i]) ) { // Restore matcherIn since elem is not yet a final match temp.push( (matcherIn[i] = elem) ); } } postFinder( null, (matcherOut = []), temp, xml ); } // Move matched elements from seed to results to keep them synchronized i = matcherOut.length; while ( i-- ) { if ( (elem = matcherOut[i]) && (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { seed[temp] = !(results[temp] = elem); } } } // Add elements to results, through postFinder if defined } else { matcherOut = condense( matcherOut === results ? matcherOut.splice( preexisting, matcherOut.length ) : matcherOut ); if ( postFinder ) { postFinder( null, results, matcherOut, xml ); } else { push.apply( results, matcherOut ); } } }); } function matcherFromTokens( tokens ) { var checkContext, matcher, j, len = tokens.length, leadingRelative = Expr.relative[ tokens[0].type ], implicitRelative = leadingRelative || Expr.relative[" "], i = leadingRelative ? 1 : 0, // The foundational matcher ensures that elements are reachable from top-level context(s) matchContext = addCombinator( function( elem ) { return elem === checkContext; }, implicitRelative, true ), matchAnyContext = addCombinator( function( elem ) { return indexOf( checkContext, elem ) > -1; }, implicitRelative, true ), matchers = [ function( elem, context, xml ) { var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( (checkContext = context).nodeType ? matchContext( elem, context, xml ) : matchAnyContext( elem, context, xml ) ); // Avoid hanging onto element (issue #299) checkContext = null; return ret; } ]; for ( ; i < len; i++ ) { if ( (matcher = Expr.relative[ tokens[i].type ]) ) { matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; } else { matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); // Return special upon seeing a positional matcher if ( matcher[ expando ] ) { // Find the next relative operator (if any) for proper handling j = ++i; for ( ; j < len; j++ ) { if ( Expr.relative[ tokens[j].type ] ) { break; } } return setMatcher( i > 1 && elementMatcher( matchers ), i > 1 && toSelector( // If the preceding token was a descendant combinator, insert an implicit any-element `*` tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) ).replace( rtrim, "$1" ), matcher, i < j && matcherFromTokens( tokens.slice( i, j ) ), j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), j < len && toSelector( tokens ) ); } matchers.push( matcher ); } } return elementMatcher( matchers ); } function matcherFromGroupMatchers( elementMatchers, setMatchers ) { var bySet = setMatchers.length > 0, byElement = elementMatchers.length > 0, superMatcher = function( seed, context, xml, results, outermost ) { var elem, j, matcher, matchedCount = 0, i = "0", unmatched = seed && [], setMatched = [], contextBackup = outermostContext, // We must always have either seed elements or outermost context elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), // Use integer dirruns iff this is the outermost matcher dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), len = elems.length; if ( outermost ) { outermostContext = context === document || context || outermost; } // Add elements passing elementMatchers directly to results // Support: IE<9, Safari // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id for ( ; i !== len && (elem = elems[i]) != null; i++ ) { if ( byElement && elem ) { j = 0; if ( !context && elem.ownerDocument !== document ) { setDocument( elem ); xml = !documentIsHTML; } while ( (matcher = elementMatchers[j++]) ) { if ( matcher( elem, context || document, xml) ) { results.push( elem ); break; } } if ( outermost ) { dirruns = dirrunsUnique; } } // Track unmatched elements for set filters if ( bySet ) { // They will have gone through all possible matchers if ( (elem = !matcher && elem) ) { matchedCount--; } // Lengthen the array for every element, matched or not if ( seed ) { unmatched.push( elem ); } } } // `i` is now the count of elements visited above, and adding it to `matchedCount` // makes the latter nonnegative. matchedCount += i; // Apply set filters to unmatched elements // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` // equals `i`), unless we didn't visit _any_ elements in the above loop because we have // no element matchers and no seed. // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that // case, which will result in a "00" `matchedCount` that differs from `i` but is also // numerically zero. if ( bySet && i !== matchedCount ) { j = 0; while ( (matcher = setMatchers[j++]) ) { matcher( unmatched, setMatched, context, xml ); } if ( seed ) { // Reintegrate element matches to eliminate the need for sorting if ( matchedCount > 0 ) { while ( i-- ) { if ( !(unmatched[i] || setMatched[i]) ) { setMatched[i] = pop.call( results ); } } } // Discard index placeholder values to get only actual matches setMatched = condense( setMatched ); } // Add matches to results push.apply( results, setMatched ); // Seedless set matches succeeding multiple successful matchers stipulate sorting if ( outermost && !seed && setMatched.length > 0 && ( matchedCount + setMatchers.length ) > 1 ) { Sizzle.uniqueSort( results ); } } // Override manipulation of globals by nested matchers if ( outermost ) { dirruns = dirrunsUnique; outermostContext = contextBackup; } return unmatched; }; return bySet ? markFunction( superMatcher ) : superMatcher; } compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { var i, setMatchers = [], elementMatchers = [], cached = compilerCache[ selector + " " ]; if ( !cached ) { // Generate a function of recursive functions that can be used to check each element if ( !match ) { match = tokenize( selector ); } i = match.length; while ( i-- ) { cached = matcherFromTokens( match[i] ); if ( cached[ expando ] ) { setMatchers.push( cached ); } else { elementMatchers.push( cached ); } } // Cache the compiled function cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); // Save selector and tokenization cached.selector = selector; } return cached; }; /** * A low-level selection function that works with Sizzle's compiled * selector functions * @param {String|Function} selector A selector or a pre-compiled * selector function built with Sizzle.compile * @param {Element} context * @param {Array} [results] * @param {Array} [seed] A set of elements to match against */ select = Sizzle.select = function( selector, context, results, seed ) { var i, tokens, token, type, find, compiled = typeof selector === "function" && selector, match = !seed && tokenize( (selector = compiled.selector || selector) ); results = results || []; // Try to minimize operations if there is only one selector in the list and no seed // (the latter of which guarantees us context) if ( match.length === 1 ) { // Reduce context if the leading compound selector is an ID tokens = match[0] = match[0].slice( 0 ); if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) { context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; if ( !context ) { return results; // Precompiled matchers will still verify ancestry, so step up a level } else if ( compiled ) { context = context.parentNode; } selector = selector.slice( tokens.shift().value.length ); } // Fetch a seed set for right-to-left matching i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; while ( i-- ) { token = tokens[i]; // Abort if we hit a combinator if ( Expr.relative[ (type = token.type) ] ) { break; } if ( (find = Expr.find[ type ]) ) { // Search, expanding context for leading sibling combinators if ( (seed = find( token.matches[0].replace( runescape, funescape ), rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context )) ) { // If seed is empty or no tokens remain, we can return early tokens.splice( i, 1 ); selector = seed.length && toSelector( tokens ); if ( !selector ) { push.apply( results, seed ); return results; } break; } } } } // Compile and execute a filtering function if one is not provided // Provide `match` to avoid retokenization if we modified the selector above ( compiled || compile( selector, match ) )( seed, context, !documentIsHTML, results, !context || rsibling.test( selector ) && testContext( context.parentNode ) || context ); return results; }; // One-time assignments // Sort stability support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; // Support: Chrome 14-35+ // Always assume duplicates if they aren't passed to the comparison function support.detectDuplicates = !!hasDuplicate; // Initialize against the default document setDocument(); // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) // Detached nodes confoundingly follow *each other* support.sortDetached = assert(function( el ) { // Should return 1, but returns 4 (following) return el.compareDocumentPosition( document.createElement("fieldset") ) & 1; }); // Support: IE<8 // Prevent attribute/property "interpolation" // https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx if ( !assert(function( el ) { el.innerHTML = ""; return el.firstChild.getAttribute("href") === "#" ; }) ) { addHandle( "type|href|height|width", function( elem, name, isXML ) { if ( !isXML ) { return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); } }); } // Support: IE<9 // Use defaultValue in place of getAttribute("value") if ( !support.attributes || !assert(function( el ) { el.innerHTML = ""; el.firstChild.setAttribute( "value", "" ); return el.firstChild.getAttribute( "value" ) === ""; }) ) { addHandle( "value", function( elem, name, isXML ) { if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { return elem.defaultValue; } }); } // Support: IE<9 // Use getAttributeNode to fetch booleans when getAttribute lies if ( !assert(function( el ) { return el.getAttribute("disabled") == null; }) ) { addHandle( booleans, function( elem, name, isXML ) { var val; if ( !isXML ) { return elem[ name ] === true ? name.toLowerCase() : (val = elem.getAttributeNode( name )) && val.specified ? val.value : null; } }); } return Sizzle; })( window ); jQuery.find = Sizzle; jQuery.expr = Sizzle.selectors; // Deprecated jQuery.expr[ ":" ] = jQuery.expr.pseudos; jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; jQuery.text = Sizzle.getText; jQuery.isXMLDoc = Sizzle.isXML; jQuery.contains = Sizzle.contains; jQuery.escapeSelector = Sizzle.escape; var dir = function( elem, dir, until ) { var matched = [], truncate = until !== undefined; while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { if ( elem.nodeType === 1 ) { if ( truncate && jQuery( elem ).is( until ) ) { break; } matched.push( elem ); } } return matched; }; var siblings = function( n, elem ) { var matched = []; for ( ; n; n = n.nextSibling ) { if ( n.nodeType === 1 && n !== elem ) { matched.push( n ); } } return matched; }; var rneedsContext = jQuery.expr.match.needsContext; var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); var risSimple = /^.[^:#\[\.,]*$/; // Implement the identical functionality for filter and not function winnow( elements, qualifier, not ) { if ( jQuery.isFunction( qualifier ) ) { return jQuery.grep( elements, function( elem, i ) { return !!qualifier.call( elem, i, elem ) !== not; } ); } // Single element if ( qualifier.nodeType ) { return jQuery.grep( elements, function( elem ) { return ( elem === qualifier ) !== not; } ); } // Arraylike of elements (jQuery, arguments, Array) if ( typeof qualifier !== "string" ) { return jQuery.grep( elements, function( elem ) { return ( indexOf.call( qualifier, elem ) > -1 ) !== not; } ); } // Simple selector that can be filtered directly, removing non-Elements if ( risSimple.test( qualifier ) ) { return jQuery.filter( qualifier, elements, not ); } // Complex selector, compare the two sets, removing non-Elements qualifier = jQuery.filter( qualifier, elements ); return jQuery.grep( elements, function( elem ) { return ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1; } ); } jQuery.filter = function( expr, elems, not ) { var elem = elems[ 0 ]; if ( not ) { expr = ":not(" + expr + ")"; } if ( elems.length === 1 && elem.nodeType === 1 ) { return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; } return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { return elem.nodeType === 1; } ) ); }; jQuery.fn.extend( { find: function( selector ) { var i, ret, len = this.length, self = this; if ( typeof selector !== "string" ) { return this.pushStack( jQuery( selector ).filter( function() { for ( i = 0; i < len; i++ ) { if ( jQuery.contains( self[ i ], this ) ) { return true; } } } ) ); } ret = this.pushStack( [] ); for ( i = 0; i < len; i++ ) { jQuery.find( selector, self[ i ], ret ); } return len > 1 ? jQuery.uniqueSort( ret ) : ret; }, filter: function( selector ) { return this.pushStack( winnow( this, selector || [], false ) ); }, not: function( selector ) { return this.pushStack( winnow( this, selector || [], true ) ); }, is: function( selector ) { return !!winnow( this, // If this is a positional/relative selector, check membership in the returned set // so $("p:first").is("p:last") won't return true for a doc with two "p". typeof selector === "string" && rneedsContext.test( selector ) ? jQuery( selector ) : selector || [], false ).length; } } ); // Initialize a jQuery object // A central reference to the root jQuery(document) var rootjQuery, // A simple way to check for HTML strings // Prioritize #id over to avoid XSS via location.hash (#9521) // Strict HTML recognition (#11290: must start with <) // Shortcut simple #id case for speed rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, init = jQuery.fn.init = function( selector, context, root ) { var match, elem; // HANDLE: $(""), $(null), $(undefined), $(false) if ( !selector ) { return this; } // Method init() accepts an alternate rootjQuery // so migrate can support jQuery.sub (gh-2101) root = root || rootjQuery; // Handle HTML strings if ( typeof selector === "string" ) { if ( selector[ 0 ] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) { // Assume that strings that start and end with <> are HTML and skip the regex check match = [ null, selector, null ]; } else { match = rquickExpr.exec( selector ); } // Match html or make sure no context is specified for #id if ( match && ( match[ 1 ] || !context ) ) { // HANDLE: $(html) -> $(array) if ( match[ 1 ] ) { context = context instanceof jQuery ? context[ 0 ] : context; // Option to run scripts is true for back-compat // Intentionally let the error be thrown if parseHTML is not present jQuery.merge( this, jQuery.parseHTML( match[ 1 ], context && context.nodeType ? context.ownerDocument || context : document, true ) ); // HANDLE: $(html, props) if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { for ( match in context ) { // Properties of context are called as methods if possible if ( jQuery.isFunction( this[ match ] ) ) { this[ match ]( context[ match ] ); // ...and otherwise set as attributes } else { this.attr( match, context[ match ] ); } } } return this; // HANDLE: $(#id) } else { elem = document.getElementById( match[ 2 ] ); if ( elem ) { // Inject the element directly into the jQuery object this[ 0 ] = elem; this.length = 1; } return this; } // HANDLE: $(expr, $(...)) } else if ( !context || context.jquery ) { return ( context || root ).find( selector ); // HANDLE: $(expr, context) // (which is just equivalent to: $(context).find(expr) } else { return this.constructor( context ).find( selector ); } // HANDLE: $(DOMElement) } else if ( selector.nodeType ) { this[ 0 ] = selector; this.length = 1; return this; // HANDLE: $(function) // Shortcut for document ready } else if ( jQuery.isFunction( selector ) ) { return root.ready !== undefined ? root.ready( selector ) : // Execute immediately if ready is not present selector( jQuery ); } return jQuery.makeArray( selector, this ); }; // Give the init function the jQuery prototype for later instantiation init.prototype = jQuery.fn; // Initialize central reference rootjQuery = jQuery( document ); var rparentsprev = /^(?:parents|prev(?:Until|All))/, // Methods guaranteed to produce a unique set when starting from a unique set guaranteedUnique = { children: true, contents: true, next: true, prev: true }; jQuery.fn.extend( { has: function( target ) { var targets = jQuery( target, this ), l = targets.length; return this.filter( function() { var i = 0; for ( ; i < l; i++ ) { if ( jQuery.contains( this, targets[ i ] ) ) { return true; } } } ); }, closest: function( selectors, context ) { var cur, i = 0, l = this.length, matched = [], targets = typeof selectors !== "string" && jQuery( selectors ); // Positional selectors never match, since there's no _selection_ context if ( !rneedsContext.test( selectors ) ) { for ( ; i < l; i++ ) { for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { // Always skip document fragments if ( cur.nodeType < 11 && ( targets ? targets.index( cur ) > -1 : // Don't pass non-elements to Sizzle cur.nodeType === 1 && jQuery.find.matchesSelector( cur, selectors ) ) ) { matched.push( cur ); break; } } } } return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); }, // Determine the position of an element within the set index: function( elem ) { // No argument, return index in parent if ( !elem ) { return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; } // Index in selector if ( typeof elem === "string" ) { return indexOf.call( jQuery( elem ), this[ 0 ] ); } // Locate the position of the desired element return indexOf.call( this, // If it receives a jQuery object, the first element is used elem.jquery ? elem[ 0 ] : elem ); }, add: function( selector, context ) { return this.pushStack( jQuery.uniqueSort( jQuery.merge( this.get(), jQuery( selector, context ) ) ) ); }, addBack: function( selector ) { return this.add( selector == null ? this.prevObject : this.prevObject.filter( selector ) ); } } ); function sibling( cur, dir ) { while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} return cur; } jQuery.each( { parent: function( elem ) { var parent = elem.parentNode; return parent && parent.nodeType !== 11 ? parent : null; }, parents: function( elem ) { return dir( elem, "parentNode" ); }, parentsUntil: function( elem, i, until ) { return dir( elem, "parentNode", until ); }, next: function( elem ) { return sibling( elem, "nextSibling" ); }, prev: function( elem ) { return sibling( elem, "previousSibling" ); }, nextAll: function( elem ) { return dir( elem, "nextSibling" ); }, prevAll: function( elem ) { return dir( elem, "previousSibling" ); }, nextUntil: function( elem, i, until ) { return dir( elem, "nextSibling", until ); }, prevUntil: function( elem, i, until ) { return dir( elem, "previousSibling", until ); }, siblings: function( elem ) { return siblings( ( elem.parentNode || {} ).firstChild, elem ); }, children: function( elem ) { return siblings( elem.firstChild ); }, contents: function( elem ) { return elem.contentDocument || jQuery.merge( [], elem.childNodes ); } }, function( name, fn ) { jQuery.fn[ name ] = function( until, selector ) { var matched = jQuery.map( this, fn, until ); if ( name.slice( -5 ) !== "Until" ) { selector = until; } if ( selector && typeof selector === "string" ) { matched = jQuery.filter( selector, matched ); } if ( this.length > 1 ) { // Remove duplicates if ( !guaranteedUnique[ name ] ) { jQuery.uniqueSort( matched ); } // Reverse order for parents* and prev-derivatives if ( rparentsprev.test( name ) ) { matched.reverse(); } } return this.pushStack( matched ); }; } ); var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); // Convert String-formatted options into Object-formatted ones function createOptions( options ) { var object = {}; jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { object[ flag ] = true; } ); return object; } /* * Create a callback list using the following parameters: * * options: an optional list of space-separated options that will change how * the callback list behaves or a more traditional option object * * By default a callback list will act like an event callback list and can be * "fired" multiple times. * * Possible options: * * once: will ensure the callback list can only be fired once (like a Deferred) * * memory: will keep track of previous values and will call any callback added * after the list has been fired right away with the latest "memorized" * values (like a Deferred) * * unique: will ensure a callback can only be added once (no duplicate in the list) * * stopOnFalse: interrupt callings when a callback returns false * */ jQuery.Callbacks = function( options ) { // Convert options from String-formatted to Object-formatted if needed // (we check in cache first) options = typeof options === "string" ? createOptions( options ) : jQuery.extend( {}, options ); var // Flag to know if list is currently firing firing, // Last fire value for non-forgettable lists memory, // Flag to know if list was already fired fired, // Flag to prevent firing locked, // Actual callback list list = [], // Queue of execution data for repeatable lists queue = [], // Index of currently firing callback (modified by add/remove as needed) firingIndex = -1, // Fire callbacks fire = function() { // Enforce single-firing locked = options.once; // Execute callbacks for all pending executions, // respecting firingIndex overrides and runtime changes fired = firing = true; for ( ; queue.length; firingIndex = -1 ) { memory = queue.shift(); while ( ++firingIndex < list.length ) { // Run callback and check for early termination if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && options.stopOnFalse ) { // Jump to end and forget the data so .add doesn't re-fire firingIndex = list.length; memory = false; } } } // Forget the data if we're done with it if ( !options.memory ) { memory = false; } firing = false; // Clean up if we're done firing for good if ( locked ) { // Keep an empty list if we have data for future add calls if ( memory ) { list = []; // Otherwise, this object is spent } else { list = ""; } } }, // Actual Callbacks object self = { // Add a callback or a collection of callbacks to the list add: function() { if ( list ) { // If we have memory from a past run, we should fire after adding if ( memory && !firing ) { firingIndex = list.length - 1; queue.push( memory ); } ( function add( args ) { jQuery.each( args, function( _, arg ) { if ( jQuery.isFunction( arg ) ) { if ( !options.unique || !self.has( arg ) ) { list.push( arg ); } } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) { // Inspect recursively add( arg ); } } ); } )( arguments ); if ( memory && !firing ) { fire(); } } return this; }, // Remove a callback from the list remove: function() { jQuery.each( arguments, function( _, arg ) { var index; while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { list.splice( index, 1 ); // Handle firing indexes if ( index <= firingIndex ) { firingIndex--; } } } ); return this; }, // Check if a given callback is in the list. // If no argument is given, return whether or not list has callbacks attached. has: function( fn ) { return fn ? jQuery.inArray( fn, list ) > -1 : list.length > 0; }, // Remove all callbacks from the list empty: function() { if ( list ) { list = []; } return this; }, // Disable .fire and .add // Abort any current/pending executions // Clear all callbacks and values disable: function() { locked = queue = []; list = memory = ""; return this; }, disabled: function() { return !list; }, // Disable .fire // Also disable .add unless we have memory (since it would have no effect) // Abort any pending executions lock: function() { locked = queue = []; if ( !memory && !firing ) { list = memory = ""; } return this; }, locked: function() { return !!locked; }, // Call all callbacks with the given context and arguments fireWith: function( context, args ) { if ( !locked ) { args = args || []; args = [ context, args.slice ? args.slice() : args ]; queue.push( args ); if ( !firing ) { fire(); } } return this; }, // Call all the callbacks with the given arguments fire: function() { self.fireWith( this, arguments ); return this; }, // To know if the callbacks have already been called at least once fired: function() { return !!fired; } }; return self; }; function Identity( v ) { return v; } function Thrower( ex ) { throw ex; } function adoptValue( value, resolve, reject ) { var method; try { // Check for promise aspect first to privilege synchronous behavior if ( value && jQuery.isFunction( ( method = value.promise ) ) ) { method.call( value ).done( resolve ).fail( reject ); // Other thenables } else if ( value && jQuery.isFunction( ( method = value.then ) ) ) { method.call( value, resolve, reject ); // Other non-thenables } else { // Support: Android 4.0 only // Strict mode functions invoked without .call/.apply get global-object context resolve.call( undefined, value ); } // For Promises/A+, convert exceptions into rejections // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in // Deferred#then to conditionally suppress rejection. } catch ( value ) { // Support: Android 4.0 only // Strict mode functions invoked without .call/.apply get global-object context reject.call( undefined, value ); } } jQuery.extend( { Deferred: function( func ) { var tuples = [ // action, add listener, callbacks, // ... .then handlers, argument index, [final state] [ "notify", "progress", jQuery.Callbacks( "memory" ), jQuery.Callbacks( "memory" ), 2 ], [ "resolve", "done", jQuery.Callbacks( "once memory" ), jQuery.Callbacks( "once memory" ), 0, "resolved" ], [ "reject", "fail", jQuery.Callbacks( "once memory" ), jQuery.Callbacks( "once memory" ), 1, "rejected" ] ], state = "pending", promise = { state: function() { return state; }, always: function() { deferred.done( arguments ).fail( arguments ); return this; }, "catch": function( fn ) { return promise.then( null, fn ); }, // Keep pipe for back-compat pipe: function( /* fnDone, fnFail, fnProgress */ ) { var fns = arguments; return jQuery.Deferred( function( newDefer ) { jQuery.each( tuples, function( i, tuple ) { // Map tuples (progress, done, fail) to arguments (done, fail, progress) var fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; // deferred.progress(function() { bind to newDefer or newDefer.notify }) // deferred.done(function() { bind to newDefer or newDefer.resolve }) // deferred.fail(function() { bind to newDefer or newDefer.reject }) deferred[ tuple[ 1 ] ]( function() { var returned = fn && fn.apply( this, arguments ); if ( returned && jQuery.isFunction( returned.promise ) ) { returned.promise() .progress( newDefer.notify ) .done( newDefer.resolve ) .fail( newDefer.reject ); } else { newDefer[ tuple[ 0 ] + "With" ]( this, fn ? [ returned ] : arguments ); } } ); } ); fns = null; } ).promise(); }, then: function( onFulfilled, onRejected, onProgress ) { var maxDepth = 0; function resolve( depth, deferred, handler, special ) { return function() { var that = this, args = arguments, mightThrow = function() { var returned, then; // Support: Promises/A+ section 2.3.3.3.3 // https://promisesaplus.com/#point-59 // Ignore double-resolution attempts if ( depth < maxDepth ) { return; } returned = handler.apply( that, args ); // Support: Promises/A+ section 2.3.1 // https://promisesaplus.com/#point-48 if ( returned === deferred.promise() ) { throw new TypeError( "Thenable self-resolution" ); } // Support: Promises/A+ sections 2.3.3.1, 3.5 // https://promisesaplus.com/#point-54 // https://promisesaplus.com/#point-75 // Retrieve `then` only once then = returned && // Support: Promises/A+ section 2.3.4 // https://promisesaplus.com/#point-64 // Only check objects and functions for thenability ( typeof returned === "object" || typeof returned === "function" ) && returned.then; // Handle a returned thenable if ( jQuery.isFunction( then ) ) { // Special processors (notify) just wait for resolution if ( special ) { then.call( returned, resolve( maxDepth, deferred, Identity, special ), resolve( maxDepth, deferred, Thrower, special ) ); // Normal processors (resolve) also hook into progress } else { // ...and disregard older resolution values maxDepth++; then.call( returned, resolve( maxDepth, deferred, Identity, special ), resolve( maxDepth, deferred, Thrower, special ), resolve( maxDepth, deferred, Identity, deferred.notifyWith ) ); } // Handle all other returned values } else { // Only substitute handlers pass on context // and multiple values (non-spec behavior) if ( handler !== Identity ) { that = undefined; args = [ returned ]; } // Process the value(s) // Default process is resolve ( special || deferred.resolveWith )( that, args ); } }, // Only normal processors (resolve) catch and reject exceptions process = special ? mightThrow : function() { try { mightThrow(); } catch ( e ) { if ( jQuery.Deferred.exceptionHook ) { jQuery.Deferred.exceptionHook( e, process.stackTrace ); } // Support: Promises/A+ section 2.3.3.3.4.1 // https://promisesaplus.com/#point-61 // Ignore post-resolution exceptions if ( depth + 1 >= maxDepth ) { // Only substitute handlers pass on context // and multiple values (non-spec behavior) if ( handler !== Thrower ) { that = undefined; args = [ e ]; } deferred.rejectWith( that, args ); } } }; // Support: Promises/A+ section 2.3.3.3.1 // https://promisesaplus.com/#point-57 // Re-resolve promises immediately to dodge false rejection from // subsequent errors if ( depth ) { process(); } else { // Call an optional hook to record the stack, in case of exception // since it's otherwise lost when execution goes async if ( jQuery.Deferred.getStackHook ) { process.stackTrace = jQuery.Deferred.getStackHook(); } window.setTimeout( process ); } }; } return jQuery.Deferred( function( newDefer ) { // progress_handlers.add( ... ) tuples[ 0 ][ 3 ].add( resolve( 0, newDefer, jQuery.isFunction( onProgress ) ? onProgress : Identity, newDefer.notifyWith ) ); // fulfilled_handlers.add( ... ) tuples[ 1 ][ 3 ].add( resolve( 0, newDefer, jQuery.isFunction( onFulfilled ) ? onFulfilled : Identity ) ); // rejected_handlers.add( ... ) tuples[ 2 ][ 3 ].add( resolve( 0, newDefer, jQuery.isFunction( onRejected ) ? onRejected : Thrower ) ); } ).promise(); }, // Get a promise for this deferred // If obj is provided, the promise aspect is added to the object promise: function( obj ) { return obj != null ? jQuery.extend( obj, promise ) : promise; } }, deferred = {}; // Add list-specific methods jQuery.each( tuples, function( i, tuple ) { var list = tuple[ 2 ], stateString = tuple[ 5 ]; // promise.progress = list.add // promise.done = list.add // promise.fail = list.add promise[ tuple[ 1 ] ] = list.add; // Handle state if ( stateString ) { list.add( function() { // state = "resolved" (i.e., fulfilled) // state = "rejected" state = stateString; }, // rejected_callbacks.disable // fulfilled_callbacks.disable tuples[ 3 - i ][ 2 ].disable, // progress_callbacks.lock tuples[ 0 ][ 2 ].lock ); } // progress_handlers.fire // fulfilled_handlers.fire // rejected_handlers.fire list.add( tuple[ 3 ].fire ); // deferred.notify = function() { deferred.notifyWith(...) } // deferred.resolve = function() { deferred.resolveWith(...) } // deferred.reject = function() { deferred.rejectWith(...) } deferred[ tuple[ 0 ] ] = function() { deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); return this; }; // deferred.notifyWith = list.fireWith // deferred.resolveWith = list.fireWith // deferred.rejectWith = list.fireWith deferred[ tuple[ 0 ] + "With" ] = list.fireWith; } ); // Make the deferred a promise promise.promise( deferred ); // Call given func if any if ( func ) { func.call( deferred, deferred ); } // All done! return deferred; }, // Deferred helper when: function( singleValue ) { var // count of uncompleted subordinates remaining = arguments.length, // count of unprocessed arguments i = remaining, // subordinate fulfillment data resolveContexts = Array( i ), resolveValues = slice.call( arguments ), // the master Deferred master = jQuery.Deferred(), // subordinate callback factory updateFunc = function( i ) { return function( value ) { resolveContexts[ i ] = this; resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; if ( !( --remaining ) ) { master.resolveWith( resolveContexts, resolveValues ); } }; }; // Single- and empty arguments are adopted like Promise.resolve if ( remaining <= 1 ) { adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject ); // Use .then() to unwrap secondary thenables (cf. gh-3000) if ( master.state() === "pending" || jQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { return master.then(); } } // Multiple arguments are aggregated like Promise.all array elements while ( i-- ) { adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); } return master.promise(); } } ); // These usually indicate a programmer mistake during development, // warn about them ASAP rather than swallowing them by default. var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; jQuery.Deferred.exceptionHook = function( error, stack ) { // Support: IE 8 - 9 only // Console exists when dev tools are open, which can happen at any time if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); } }; jQuery.readyException = function( error ) { window.setTimeout( function() { throw error; } ); }; // The deferred used on DOM ready var readyList = jQuery.Deferred(); jQuery.fn.ready = function( fn ) { readyList .then( fn ) // Wrap jQuery.readyException in a function so that the lookup // happens at the time of error handling instead of callback // registration. .catch( function( error ) { jQuery.readyException( error ); } ); return this; }; jQuery.extend( { // Is the DOM ready to be used? Set to true once it occurs. isReady: false, // A counter to track how many items to wait for before // the ready event fires. See #6781 readyWait: 1, // Hold (or release) the ready event holdReady: function( hold ) { if ( hold ) { jQuery.readyWait++; } else { jQuery.ready( true ); } }, // Handle when the DOM is ready ready: function( wait ) { // Abort if there are pending holds or we're already ready if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { return; } // Remember that the DOM is ready jQuery.isReady = true; // If a normal DOM Ready event fired, decrement, and wait if need be if ( wait !== true && --jQuery.readyWait > 0 ) { return; } // If there are functions bound, to execute readyList.resolveWith( document, [ jQuery ] ); } } ); jQuery.ready.then = readyList.then; // The ready event handler and self cleanup method function completed() { document.removeEventListener( "DOMContentLoaded", completed ); window.removeEventListener( "load", completed ); jQuery.ready(); } // Catch cases where $(document).ready() is called // after the browser event has already occurred. // Support: IE <=9 - 10 only // Older IE sometimes signals "interactive" too soon if ( document.readyState === "complete" || ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { // Handle it asynchronously to allow scripts the opportunity to delay ready window.setTimeout( jQuery.ready ); } else { // Use the handy event callback document.addEventListener( "DOMContentLoaded", completed ); // A fallback to window.onload, that will always work window.addEventListener( "load", completed ); } // Multifunctional method to get and set values of a collection // The value/s can optionally be executed if it's a function var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { var i = 0, len = elems.length, bulk = key == null; // Sets many values if ( jQuery.type( key ) === "object" ) { chainable = true; for ( i in key ) { access( elems, fn, i, key[ i ], true, emptyGet, raw ); } // Sets one value } else if ( value !== undefined ) { chainable = true; if ( !jQuery.isFunction( value ) ) { raw = true; } if ( bulk ) { // Bulk operations run against the entire set if ( raw ) { fn.call( elems, value ); fn = null; // ...except when executing function values } else { bulk = fn; fn = function( elem, key, value ) { return bulk.call( jQuery( elem ), value ); }; } } if ( fn ) { for ( ; i < len; i++ ) { fn( elems[ i ], key, raw ? value : value.call( elems[ i ], i, fn( elems[ i ], key ) ) ); } } } if ( chainable ) { return elems; } // Gets if ( bulk ) { return fn.call( elems ); } return len ? fn( elems[ 0 ], key ) : emptyGet; }; var acceptData = function( owner ) { // Accepts only: // - Node // - Node.ELEMENT_NODE // - Node.DOCUMENT_NODE // - Object // - Any return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); }; function Data() { this.expando = jQuery.expando + Data.uid++; } Data.uid = 1; Data.prototype = { cache: function( owner ) { // Check if the owner object already has a cache var value = owner[ this.expando ]; // If not, create one if ( !value ) { value = {}; // We can accept data for non-element nodes in modern browsers, // but we should not, see #8335. // Always return an empty object. if ( acceptData( owner ) ) { // If it is a node unlikely to be stringify-ed or looped over // use plain assignment if ( owner.nodeType ) { owner[ this.expando ] = value; // Otherwise secure it in a non-enumerable property // configurable must be true to allow the property to be // deleted when data is removed } else { Object.defineProperty( owner, this.expando, { value: value, configurable: true } ); } } } return value; }, set: function( owner, data, value ) { var prop, cache = this.cache( owner ); // Handle: [ owner, key, value ] args // Always use camelCase key (gh-2257) if ( typeof data === "string" ) { cache[ jQuery.camelCase( data ) ] = value; // Handle: [ owner, { properties } ] args } else { // Copy the properties one-by-one to the cache object for ( prop in data ) { cache[ jQuery.camelCase( prop ) ] = data[ prop ]; } } return cache; }, get: function( owner, key ) { return key === undefined ? this.cache( owner ) : // Always use camelCase key (gh-2257) owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ]; }, access: function( owner, key, value ) { // In cases where either: // // 1. No key was specified // 2. A string key was specified, but no value provided // // Take the "read" path and allow the get method to determine // which value to return, respectively either: // // 1. The entire cache object // 2. The data stored at the key // if ( key === undefined || ( ( key && typeof key === "string" ) && value === undefined ) ) { return this.get( owner, key ); } // When the key is not a string, or both a key and value // are specified, set or extend (existing objects) with either: // // 1. An object of properties // 2. A key and value // this.set( owner, key, value ); // Since the "set" path can have two possible entry points // return the expected data based on which path was taken[*] return value !== undefined ? value : key; }, remove: function( owner, key ) { var i, cache = owner[ this.expando ]; if ( cache === undefined ) { return; } if ( key !== undefined ) { // Support array or space separated string of keys if ( jQuery.isArray( key ) ) { // If key is an array of keys... // We always set camelCase keys, so remove that. key = key.map( jQuery.camelCase ); } else { key = jQuery.camelCase( key ); // If a key with the spaces exists, use it. // Otherwise, create an array by matching non-whitespace key = key in cache ? [ key ] : ( key.match( rnothtmlwhite ) || [] ); } i = key.length; while ( i-- ) { delete cache[ key[ i ] ]; } } // Remove the expando if there's no more data if ( key === undefined || jQuery.isEmptyObject( cache ) ) { // Support: Chrome <=35 - 45 // Webkit & Blink performance suffers when deleting properties // from DOM nodes, so set to undefined instead // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) if ( owner.nodeType ) { owner[ this.expando ] = undefined; } else { delete owner[ this.expando ]; } } }, hasData: function( owner ) { var cache = owner[ this.expando ]; return cache !== undefined && !jQuery.isEmptyObject( cache ); } }; var dataPriv = new Data(); var dataUser = new Data(); // Implementation Summary // // 1. Enforce API surface and semantic compatibility with 1.9.x branch // 2. Improve the module's maintainability by reducing the storage // paths to a single mechanism. // 3. Use the same single mechanism to support "private" and "user" data. // 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) // 5. Avoid exposing implementation details on user objects (eg. expando properties) // 6. Provide a clear path for implementation upgrade to WeakMap in 2014 var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, rmultiDash = /[A-Z]/g; function getData( data ) { if ( data === "true" ) { return true; } if ( data === "false" ) { return false; } if ( data === "null" ) { return null; } // Only convert to a number if it doesn't change the string if ( data === +data + "" ) { return +data; } if ( rbrace.test( data ) ) { return JSON.parse( data ); } return data; } function dataAttr( elem, key, data ) { var name; // If nothing was found internally, try to fetch any // data from the HTML5 data-* attribute if ( data === undefined && elem.nodeType === 1 ) { name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); data = elem.getAttribute( name ); if ( typeof data === "string" ) { try { data = getData( data ); } catch ( e ) {} // Make sure we set the data so it isn't changed later dataUser.set( elem, key, data ); } else { data = undefined; } } return data; } jQuery.extend( { hasData: function( elem ) { return dataUser.hasData( elem ) || dataPriv.hasData( elem ); }, data: function( elem, name, data ) { return dataUser.access( elem, name, data ); }, removeData: function( elem, name ) { dataUser.remove( elem, name ); }, // TODO: Now that all calls to _data and _removeData have been replaced // with direct calls to dataPriv methods, these can be deprecated. _data: function( elem, name, data ) { return dataPriv.access( elem, name, data ); }, _removeData: function( elem, name ) { dataPriv.remove( elem, name ); } } ); jQuery.fn.extend( { data: function( key, value ) { var i, name, data, elem = this[ 0 ], attrs = elem && elem.attributes; // Gets all values if ( key === undefined ) { if ( this.length ) { data = dataUser.get( elem ); if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { i = attrs.length; while ( i-- ) { // Support: IE 11 only // The attrs elements can be null (#14894) if ( attrs[ i ] ) { name = attrs[ i ].name; if ( name.indexOf( "data-" ) === 0 ) { name = jQuery.camelCase( name.slice( 5 ) ); dataAttr( elem, name, data[ name ] ); } } } dataPriv.set( elem, "hasDataAttrs", true ); } } return data; } // Sets multiple values if ( typeof key === "object" ) { return this.each( function() { dataUser.set( this, key ); } ); } return access( this, function( value ) { var data; // The calling jQuery object (element matches) is not empty // (and therefore has an element appears at this[ 0 ]) and the // `value` parameter was not undefined. An empty jQuery object // will result in `undefined` for elem = this[ 0 ] which will // throw an exception if an attempt to read a data cache is made. if ( elem && value === undefined ) { // Attempt to get data from the cache // The key will always be camelCased in Data data = dataUser.get( elem, key ); if ( data !== undefined ) { return data; } // Attempt to "discover" the data in // HTML5 custom data-* attrs data = dataAttr( elem, key ); if ( data !== undefined ) { return data; } // We tried really hard, but the data doesn't exist. return; } // Set the data... this.each( function() { // We always store the camelCased key dataUser.set( this, key, value ); } ); }, null, value, arguments.length > 1, null, true ); }, removeData: function( key ) { return this.each( function() { dataUser.remove( this, key ); } ); } } ); jQuery.extend( { queue: function( elem, type, data ) { var queue; if ( elem ) { type = ( type || "fx" ) + "queue"; queue = dataPriv.get( elem, type ); // Speed up dequeue by getting out quickly if this is just a lookup if ( data ) { if ( !queue || jQuery.isArray( data ) ) { queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); } else { queue.push( data ); } } return queue || []; } }, dequeue: function( elem, type ) { type = type || "fx"; var queue = jQuery.queue( elem, type ), startLength = queue.length, fn = queue.shift(), hooks = jQuery._queueHooks( elem, type ), next = function() { jQuery.dequeue( elem, type ); }; // If the fx queue is dequeued, always remove the progress sentinel if ( fn === "inprogress" ) { fn = queue.shift(); startLength--; } if ( fn ) { // Add a progress sentinel to prevent the fx queue from being // automatically dequeued if ( type === "fx" ) { queue.unshift( "inprogress" ); } // Clear up the last queue stop function delete hooks.stop; fn.call( elem, next, hooks ); } if ( !startLength && hooks ) { hooks.empty.fire(); } }, // Not public - generate a queueHooks object, or return the current one _queueHooks: function( elem, type ) { var key = type + "queueHooks"; return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { empty: jQuery.Callbacks( "once memory" ).add( function() { dataPriv.remove( elem, [ type + "queue", key ] ); } ) } ); } } ); jQuery.fn.extend( { queue: function( type, data ) { var setter = 2; if ( typeof type !== "string" ) { data = type; type = "fx"; setter--; } if ( arguments.length < setter ) { return jQuery.queue( this[ 0 ], type ); } return data === undefined ? this : this.each( function() { var queue = jQuery.queue( this, type, data ); // Ensure a hooks for this queue jQuery._queueHooks( this, type ); if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { jQuery.dequeue( this, type ); } } ); }, dequeue: function( type ) { return this.each( function() { jQuery.dequeue( this, type ); } ); }, clearQueue: function( type ) { return this.queue( type || "fx", [] ); }, // Get a promise resolved when queues of a certain type // are emptied (fx is the type by default) promise: function( type, obj ) { var tmp, count = 1, defer = jQuery.Deferred(), elements = this, i = this.length, resolve = function() { if ( !( --count ) ) { defer.resolveWith( elements, [ elements ] ); } }; if ( typeof type !== "string" ) { obj = type; type = undefined; } type = type || "fx"; while ( i-- ) { tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); if ( tmp && tmp.empty ) { count++; tmp.empty.add( resolve ); } } resolve(); return defer.promise( obj ); } } ); var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; var isHiddenWithinTree = function( elem, el ) { // isHiddenWithinTree might be called from jQuery#filter function; // in that case, element will be second argument elem = el || elem; // Inline style trumps all return elem.style.display === "none" || elem.style.display === "" && // Otherwise, check computed style // Support: Firefox <=43 - 45 // Disconnected elements can have computed display: none, so first confirm that elem is // in the document. jQuery.contains( elem.ownerDocument, elem ) && jQuery.css( elem, "display" ) === "none"; }; var swap = function( elem, options, callback, args ) { var ret, name, old = {}; // Remember the old values, and insert the new ones for ( name in options ) { old[ name ] = elem.style[ name ]; elem.style[ name ] = options[ name ]; } ret = callback.apply( elem, args || [] ); // Revert the old values for ( name in options ) { elem.style[ name ] = old[ name ]; } return ret; }; function adjustCSS( elem, prop, valueParts, tween ) { var adjusted, scale = 1, maxIterations = 20, currentValue = tween ? function() { return tween.cur(); } : function() { return jQuery.css( elem, prop, "" ); }, initial = currentValue(), unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), // Starting value computation is required for potential unit mismatches initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && rcssNum.exec( jQuery.css( elem, prop ) ); if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { // Trust units reported by jQuery.css unit = unit || initialInUnit[ 3 ]; // Make sure we update the tween properties later on valueParts = valueParts || []; // Iteratively approximate from a nonzero starting point initialInUnit = +initial || 1; do { // If previous iteration zeroed out, double until we get *something*. // Use string for doubling so we don't accidentally see scale as unchanged below scale = scale || ".5"; // Adjust and apply initialInUnit = initialInUnit / scale; jQuery.style( elem, prop, initialInUnit + unit ); // Update scale, tolerating zero or NaN from tween.cur() // Break the loop if scale is unchanged or perfect, or if we've just had enough. } while ( scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations ); } if ( valueParts ) { initialInUnit = +initialInUnit || +initial || 0; // Apply relative offset (+=/-=) if specified adjusted = valueParts[ 1 ] ? initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : +valueParts[ 2 ]; if ( tween ) { tween.unit = unit; tween.start = initialInUnit; tween.end = adjusted; } } return adjusted; } var defaultDisplayMap = {}; function getDefaultDisplay( elem ) { var temp, doc = elem.ownerDocument, nodeName = elem.nodeName, display = defaultDisplayMap[ nodeName ]; if ( display ) { return display; } temp = doc.body.appendChild( doc.createElement( nodeName ) ); display = jQuery.css( temp, "display" ); temp.parentNode.removeChild( temp ); if ( display === "none" ) { display = "block"; } defaultDisplayMap[ nodeName ] = display; return display; } function showHide( elements, show ) { var display, elem, values = [], index = 0, length = elements.length; // Determine new display value for elements that need to change for ( ; index < length; index++ ) { elem = elements[ index ]; if ( !elem.style ) { continue; } display = elem.style.display; if ( show ) { // Since we force visibility upon cascade-hidden elements, an immediate (and slow) // check is required in this first loop unless we have a nonempty display value (either // inline or about-to-be-restored) if ( display === "none" ) { values[ index ] = dataPriv.get( elem, "display" ) || null; if ( !values[ index ] ) { elem.style.display = ""; } } if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { values[ index ] = getDefaultDisplay( elem ); } } else { if ( display !== "none" ) { values[ index ] = "none"; // Remember what we're overwriting dataPriv.set( elem, "display", display ); } } } // Set the display of the elements in a second loop to avoid constant reflow for ( index = 0; index < length; index++ ) { if ( values[ index ] != null ) { elements[ index ].style.display = values[ index ]; } } return elements; } jQuery.fn.extend( { show: function() { return showHide( this, true ); }, hide: function() { return showHide( this ); }, toggle: function( state ) { if ( typeof state === "boolean" ) { return state ? this.show() : this.hide(); } return this.each( function() { if ( isHiddenWithinTree( this ) ) { jQuery( this ).show(); } else { jQuery( this ).hide(); } } ); } } ); var rcheckableType = ( /^(?:checkbox|radio)$/i ); var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i ); var rscriptType = ( /^$|\/(?:java|ecma)script/i ); // We have to close these tags to support XHTML (#13200) var wrapMap = { // Support: IE <=9 only option: [ 1, "" ], // XHTML parsers do not magically insert elements in the // same way that tag soup parsers do. So we cannot shorten // this by omitting or other required elements. thead: [ 1, "
", "
" ], col: [ 2, "", "
" ], tr: [ 2, "", "
" ], td: [ 3, "", "
" ], _default: [ 0, "", "" ] }; // Support: IE <=9 only wrapMap.optgroup = wrapMap.option; wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; wrapMap.th = wrapMap.td; function getAll( context, tag ) { // Support: IE <=9 - 11 only // Use typeof to avoid zero-argument method invocation on host objects (#15151) var ret; if ( typeof context.getElementsByTagName !== "undefined" ) { ret = context.getElementsByTagName( tag || "*" ); } else if ( typeof context.querySelectorAll !== "undefined" ) { ret = context.querySelectorAll( tag || "*" ); } else { ret = []; } if ( tag === undefined || tag && jQuery.nodeName( context, tag ) ) { return jQuery.merge( [ context ], ret ); } return ret; } // Mark scripts as having already been evaluated function setGlobalEval( elems, refElements ) { var i = 0, l = elems.length; for ( ; i < l; i++ ) { dataPriv.set( elems[ i ], "globalEval", !refElements || dataPriv.get( refElements[ i ], "globalEval" ) ); } } var rhtml = /<|&#?\w+;/; function buildFragment( elems, context, scripts, selection, ignored ) { var elem, tmp, tag, wrap, contains, j, fragment = context.createDocumentFragment(), nodes = [], i = 0, l = elems.length; for ( ; i < l; i++ ) { elem = elems[ i ]; if ( elem || elem === 0 ) { // Add nodes directly if ( jQuery.type( elem ) === "object" ) { // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); // Convert non-html into a text node } else if ( !rhtml.test( elem ) ) { nodes.push( context.createTextNode( elem ) ); // Convert html into DOM nodes } else { tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); // Deserialize a standard representation tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); wrap = wrapMap[ tag ] || wrapMap._default; tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; // Descend through wrappers to the right content j = wrap[ 0 ]; while ( j-- ) { tmp = tmp.lastChild; } // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit jQuery.merge( nodes, tmp.childNodes ); // Remember the top-level container tmp = fragment.firstChild; // Ensure the created nodes are orphaned (#12392) tmp.textContent = ""; } } } // Remove wrapper from fragment fragment.textContent = ""; i = 0; while ( ( elem = nodes[ i++ ] ) ) { // Skip elements already in the context collection (trac-4087) if ( selection && jQuery.inArray( elem, selection ) > -1 ) { if ( ignored ) { ignored.push( elem ); } continue; } contains = jQuery.contains( elem.ownerDocument, elem ); // Append to fragment tmp = getAll( fragment.appendChild( elem ), "script" ); // Preserve script evaluation history if ( contains ) { setGlobalEval( tmp ); } // Capture executables if ( scripts ) { j = 0; while ( ( elem = tmp[ j++ ] ) ) { if ( rscriptType.test( elem.type || "" ) ) { scripts.push( elem ); } } } } return fragment; } ( function() { var fragment = document.createDocumentFragment(), div = fragment.appendChild( document.createElement( "div" ) ), input = document.createElement( "input" ); // Support: Android 4.0 - 4.3 only // Check state lost if the name is set (#11217) // Support: Windows Web Apps (WWA) // `name` and `type` must use .setAttribute for WWA (#14901) input.setAttribute( "type", "radio" ); input.setAttribute( "checked", "checked" ); input.setAttribute( "name", "t" ); div.appendChild( input ); // Support: Android <=4.1 only // Older WebKit doesn't clone checked state correctly in fragments support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; // Support: IE <=11 only // Make sure textarea (and checkbox) defaultValue is properly cloned div.innerHTML = ""; support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; } )(); var documentElement = document.documentElement; var rkeyEvent = /^key/, rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, rtypenamespace = /^([^.]*)(?:\.(.+)|)/; function returnTrue() { return true; } function returnFalse() { return false; } // Support: IE <=9 only // See #13393 for more info function safeActiveElement() { try { return document.activeElement; } catch ( err ) { } } function on( elem, types, selector, data, fn, one ) { var origFn, type; // Types can be a map of types/handlers if ( typeof types === "object" ) { // ( types-Object, selector, data ) if ( typeof selector !== "string" ) { // ( types-Object, data ) data = data || selector; selector = undefined; } for ( type in types ) { on( elem, type, selector, data, types[ type ], one ); } return elem; } if ( data == null && fn == null ) { // ( types, fn ) fn = selector; data = selector = undefined; } else if ( fn == null ) { if ( typeof selector === "string" ) { // ( types, selector, fn ) fn = data; data = undefined; } else { // ( types, data, fn ) fn = data; data = selector; selector = undefined; } } if ( fn === false ) { fn = returnFalse; } else if ( !fn ) { return elem; } if ( one === 1 ) { origFn = fn; fn = function( event ) { // Can use an empty set, since event contains the info jQuery().off( event ); return origFn.apply( this, arguments ); }; // Use same guid so caller can remove using origFn fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); } return elem.each( function() { jQuery.event.add( this, types, fn, data, selector ); } ); } /* * Helper functions for managing events -- not part of the public interface. * Props to Dean Edwards' addEvent library for many of the ideas. */ jQuery.event = { global: {}, add: function( elem, types, handler, data, selector ) { var handleObjIn, eventHandle, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, elemData = dataPriv.get( elem ); // Don't attach events to noData or text/comment nodes (but allow plain objects) if ( !elemData ) { return; } // Caller can pass in an object of custom data in lieu of the handler if ( handler.handler ) { handleObjIn = handler; handler = handleObjIn.handler; selector = handleObjIn.selector; } // Ensure that invalid selectors throw exceptions at attach time // Evaluate against documentElement in case elem is a non-element node (e.g., document) if ( selector ) { jQuery.find.matchesSelector( documentElement, selector ); } // Make sure that the handler has a unique ID, used to find/remove it later if ( !handler.guid ) { handler.guid = jQuery.guid++; } // Init the element's event structure and main handler, if this is the first if ( !( events = elemData.events ) ) { events = elemData.events = {}; } if ( !( eventHandle = elemData.handle ) ) { eventHandle = elemData.handle = function( e ) { // Discard the second event of a jQuery.event.trigger() and // when an event is called after a page has unloaded return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? jQuery.event.dispatch.apply( elem, arguments ) : undefined; }; } // Handle multiple events separated by a space types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; t = types.length; while ( t-- ) { tmp = rtypenamespace.exec( types[ t ] ) || []; type = origType = tmp[ 1 ]; namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); // There *must* be a type, no attaching namespace-only handlers if ( !type ) { continue; } // If event changes its type, use the special event handlers for the changed type special = jQuery.event.special[ type ] || {}; // If selector defined, determine special event api type, otherwise given type type = ( selector ? special.delegateType : special.bindType ) || type; // Update special based on newly reset type special = jQuery.event.special[ type ] || {}; // handleObj is passed to all event handlers handleObj = jQuery.extend( { type: type, origType: origType, data: data, handler: handler, guid: handler.guid, selector: selector, needsContext: selector && jQuery.expr.match.needsContext.test( selector ), namespace: namespaces.join( "." ) }, handleObjIn ); // Init the event handler queue if we're the first if ( !( handlers = events[ type ] ) ) { handlers = events[ type ] = []; handlers.delegateCount = 0; // Only use addEventListener if the special events handler returns false if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { if ( elem.addEventListener ) { elem.addEventListener( type, eventHandle ); } } } if ( special.add ) { special.add.call( elem, handleObj ); if ( !handleObj.handler.guid ) { handleObj.handler.guid = handler.guid; } } // Add to the element's handler list, delegates in front if ( selector ) { handlers.splice( handlers.delegateCount++, 0, handleObj ); } else { handlers.push( handleObj ); } // Keep track of which events have ever been used, for event optimization jQuery.event.global[ type ] = true; } }, // Detach an event or set of events from an element remove: function( elem, types, handler, selector, mappedTypes ) { var j, origCount, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); if ( !elemData || !( events = elemData.events ) ) { return; } // Once for each type.namespace in types; type may be omitted types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; t = types.length; while ( t-- ) { tmp = rtypenamespace.exec( types[ t ] ) || []; type = origType = tmp[ 1 ]; namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); // Unbind all events (on this namespace, if provided) for the element if ( !type ) { for ( type in events ) { jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); } continue; } special = jQuery.event.special[ type ] || {}; type = ( selector ? special.delegateType : special.bindType ) || type; handlers = events[ type ] || []; tmp = tmp[ 2 ] && new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); // Remove matching events origCount = j = handlers.length; while ( j-- ) { handleObj = handlers[ j ]; if ( ( mappedTypes || origType === handleObj.origType ) && ( !handler || handler.guid === handleObj.guid ) && ( !tmp || tmp.test( handleObj.namespace ) ) && ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { handlers.splice( j, 1 ); if ( handleObj.selector ) { handlers.delegateCount--; } if ( special.remove ) { special.remove.call( elem, handleObj ); } } } // Remove generic event handler if we removed something and no more handlers exist // (avoids potential for endless recursion during removal of special event handlers) if ( origCount && !handlers.length ) { if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { jQuery.removeEvent( elem, type, elemData.handle ); } delete events[ type ]; } } // Remove data and the expando if it's no longer used if ( jQuery.isEmptyObject( events ) ) { dataPriv.remove( elem, "handle events" ); } }, dispatch: function( nativeEvent ) { // Make a writable jQuery.Event from the native event object var event = jQuery.event.fix( nativeEvent ); var i, j, ret, matched, handleObj, handlerQueue, args = new Array( arguments.length ), handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], special = jQuery.event.special[ event.type ] || {}; // Use the fix-ed jQuery.Event rather than the (read-only) native event args[ 0 ] = event; for ( i = 1; i < arguments.length; i++ ) { args[ i ] = arguments[ i ]; } event.delegateTarget = this; // Call the preDispatch hook for the mapped type, and let it bail if desired if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { return; } // Determine handlers handlerQueue = jQuery.event.handlers.call( this, event, handlers ); // Run delegates first; they may want to stop propagation beneath us i = 0; while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { event.currentTarget = matched.elem; j = 0; while ( ( handleObj = matched.handlers[ j++ ] ) && !event.isImmediatePropagationStopped() ) { // Triggered event must either 1) have no namespace, or 2) have namespace(s) // a subset or equal to those in the bound event (both can have no namespace). if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { event.handleObj = handleObj; event.data = handleObj.data; ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || handleObj.handler ).apply( matched.elem, args ); if ( ret !== undefined ) { if ( ( event.result = ret ) === false ) { event.preventDefault(); event.stopPropagation(); } } } } } // Call the postDispatch hook for the mapped type if ( special.postDispatch ) { special.postDispatch.call( this, event ); } return event.result; }, handlers: function( event, handlers ) { var i, handleObj, sel, matchedHandlers, matchedSelectors, handlerQueue = [], delegateCount = handlers.delegateCount, cur = event.target; // Find delegate handlers if ( delegateCount && // Support: IE <=9 // Black-hole SVG instance trees (trac-13180) cur.nodeType && // Support: Firefox <=42 // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click // Support: IE 11 only // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) !( event.type === "click" && event.button >= 1 ) ) { for ( ; cur !== this; cur = cur.parentNode || this ) { // Don't check non-elements (#13208) // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { matchedHandlers = []; matchedSelectors = {}; for ( i = 0; i < delegateCount; i++ ) { handleObj = handlers[ i ]; // Don't conflict with Object.prototype properties (#13203) sel = handleObj.selector + " "; if ( matchedSelectors[ sel ] === undefined ) { matchedSelectors[ sel ] = handleObj.needsContext ? jQuery( sel, this ).index( cur ) > -1 : jQuery.find( sel, this, null, [ cur ] ).length; } if ( matchedSelectors[ sel ] ) { matchedHandlers.push( handleObj ); } } if ( matchedHandlers.length ) { handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); } } } } // Add the remaining (directly-bound) handlers cur = this; if ( delegateCount < handlers.length ) { handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); } return handlerQueue; }, addProp: function( name, hook ) { Object.defineProperty( jQuery.Event.prototype, name, { enumerable: true, configurable: true, get: jQuery.isFunction( hook ) ? function() { if ( this.originalEvent ) { return hook( this.originalEvent ); } } : function() { if ( this.originalEvent ) { return this.originalEvent[ name ]; } }, set: function( value ) { Object.defineProperty( this, name, { enumerable: true, configurable: true, writable: true, value: value } ); } } ); }, fix: function( originalEvent ) { return originalEvent[ jQuery.expando ] ? originalEvent : new jQuery.Event( originalEvent ); }, special: { load: { // Prevent triggered image.load events from bubbling to window.load noBubble: true }, focus: { // Fire native event if possible so blur/focus sequence is correct trigger: function() { if ( this !== safeActiveElement() && this.focus ) { this.focus(); return false; } }, delegateType: "focusin" }, blur: { trigger: function() { if ( this === safeActiveElement() && this.blur ) { this.blur(); return false; } }, delegateType: "focusout" }, click: { // For checkbox, fire native event so checked state will be right trigger: function() { if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { this.click(); return false; } }, // For cross-browser consistency, don't fire native .click() on links _default: function( event ) { return jQuery.nodeName( event.target, "a" ); } }, beforeunload: { postDispatch: function( event ) { // Support: Firefox 20+ // Firefox doesn't alert if the returnValue field is not set. if ( event.result !== undefined && event.originalEvent ) { event.originalEvent.returnValue = event.result; } } } } }; jQuery.removeEvent = function( elem, type, handle ) { // This "if" is needed for plain objects if ( elem.removeEventListener ) { elem.removeEventListener( type, handle ); } }; jQuery.Event = function( src, props ) { // Allow instantiation without the 'new' keyword if ( !( this instanceof jQuery.Event ) ) { return new jQuery.Event( src, props ); } // Event object if ( src && src.type ) { this.originalEvent = src; this.type = src.type; // Events bubbling up the document may have been marked as prevented // by a handler lower down the tree; reflect the correct value. this.isDefaultPrevented = src.defaultPrevented || src.defaultPrevented === undefined && // Support: Android <=2.3 only src.returnValue === false ? returnTrue : returnFalse; // Create target properties // Support: Safari <=6 - 7 only // Target should not be a text node (#504, #13143) this.target = ( src.target && src.target.nodeType === 3 ) ? src.target.parentNode : src.target; this.currentTarget = src.currentTarget; this.relatedTarget = src.relatedTarget; // Event type } else { this.type = src; } // Put explicitly provided properties onto the event object if ( props ) { jQuery.extend( this, props ); } // Create a timestamp if incoming event doesn't have one this.timeStamp = src && src.timeStamp || jQuery.now(); // Mark it as fixed this[ jQuery.expando ] = true; }; // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html jQuery.Event.prototype = { constructor: jQuery.Event, isDefaultPrevented: returnFalse, isPropagationStopped: returnFalse, isImmediatePropagationStopped: returnFalse, isSimulated: false, preventDefault: function() { var e = this.originalEvent; this.isDefaultPrevented = returnTrue; if ( e && !this.isSimulated ) { e.preventDefault(); } }, stopPropagation: function() { var e = this.originalEvent; this.isPropagationStopped = returnTrue; if ( e && !this.isSimulated ) { e.stopPropagation(); } }, stopImmediatePropagation: function() { var e = this.originalEvent; this.isImmediatePropagationStopped = returnTrue; if ( e && !this.isSimulated ) { e.stopImmediatePropagation(); } this.stopPropagation(); } }; // Includes all common event props including KeyEvent and MouseEvent specific props jQuery.each( { altKey: true, bubbles: true, cancelable: true, changedTouches: true, ctrlKey: true, detail: true, eventPhase: true, metaKey: true, pageX: true, pageY: true, shiftKey: true, view: true, "char": true, charCode: true, key: true, keyCode: true, button: true, buttons: true, clientX: true, clientY: true, offsetX: true, offsetY: true, pointerId: true, pointerType: true, screenX: true, screenY: true, targetTouches: true, toElement: true, touches: true, which: function( event ) { var button = event.button; // Add which for key events if ( event.which == null && rkeyEvent.test( event.type ) ) { return event.charCode != null ? event.charCode : event.keyCode; } // Add which for click: 1 === left; 2 === middle; 3 === right if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { if ( button & 1 ) { return 1; } if ( button & 2 ) { return 3; } if ( button & 4 ) { return 2; } return 0; } return event.which; } }, jQuery.event.addProp ); // Create mouseenter/leave events using mouseover/out and event-time checks // so that event delegation works in jQuery. // Do the same for pointerenter/pointerleave and pointerover/pointerout // // Support: Safari 7 only // Safari sends mouseenter too often; see: // https://bugs.chromium.org/p/chromium/issues/detail?id=470258 // for the description of the bug (it existed in older Chrome versions as well). jQuery.each( { mouseenter: "mouseover", mouseleave: "mouseout", pointerenter: "pointerover", pointerleave: "pointerout" }, function( orig, fix ) { jQuery.event.special[ orig ] = { delegateType: fix, bindType: fix, handle: function( event ) { var ret, target = this, related = event.relatedTarget, handleObj = event.handleObj; // For mouseenter/leave call the handler if related is outside the target. // NB: No relatedTarget if the mouse left/entered the browser window if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { event.type = handleObj.origType; ret = handleObj.handler.apply( this, arguments ); event.type = fix; } return ret; } }; } ); jQuery.fn.extend( { on: function( types, selector, data, fn ) { return on( this, types, selector, data, fn ); }, one: function( types, selector, data, fn ) { return on( this, types, selector, data, fn, 1 ); }, off: function( types, selector, fn ) { var handleObj, type; if ( types && types.preventDefault && types.handleObj ) { // ( event ) dispatched jQuery.Event handleObj = types.handleObj; jQuery( types.delegateTarget ).off( handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler ); return this; } if ( typeof types === "object" ) { // ( types-object [, selector] ) for ( type in types ) { this.off( type, selector, types[ type ] ); } return this; } if ( selector === false || typeof selector === "function" ) { // ( types [, fn] ) fn = selector; selector = undefined; } if ( fn === false ) { fn = returnFalse; } return this.each( function() { jQuery.event.remove( this, types, fn, selector ); } ); } } ); var /* eslint-disable max-len */ // See https://github.com/eslint/eslint/issues/3229 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, /* eslint-enable */ // Support: IE <=10 - 11, Edge 12 - 13 // In IE/Edge using regex groups here causes severe slowdowns. // See https://connect.microsoft.com/IE/feedback/details/1736512/ rnoInnerhtml = /\s*$/g; function manipulationTarget( elem, content ) { if ( jQuery.nodeName( elem, "table" ) && jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { return elem.getElementsByTagName( "tbody" )[ 0 ] || elem; } return elem; } // Replace/restore the type attribute of script elements for safe DOM manipulation function disableScript( elem ) { elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; return elem; } function restoreScript( elem ) { var match = rscriptTypeMasked.exec( elem.type ); if ( match ) { elem.type = match[ 1 ]; } else { elem.removeAttribute( "type" ); } return elem; } function cloneCopyEvent( src, dest ) { var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; if ( dest.nodeType !== 1 ) { return; } // 1. Copy private data: events, handlers, etc. if ( dataPriv.hasData( src ) ) { pdataOld = dataPriv.access( src ); pdataCur = dataPriv.set( dest, pdataOld ); events = pdataOld.events; if ( events ) { delete pdataCur.handle; pdataCur.events = {}; for ( type in events ) { for ( i = 0, l = events[ type ].length; i < l; i++ ) { jQuery.event.add( dest, type, events[ type ][ i ] ); } } } } // 2. Copy user data if ( dataUser.hasData( src ) ) { udataOld = dataUser.access( src ); udataCur = jQuery.extend( {}, udataOld ); dataUser.set( dest, udataCur ); } } // Fix IE bugs, see support tests function fixInput( src, dest ) { var nodeName = dest.nodeName.toLowerCase(); // Fails to persist the checked state of a cloned checkbox or radio button. if ( nodeName === "input" && rcheckableType.test( src.type ) ) { dest.checked = src.checked; // Fails to return the selected option to the default selected state when cloning options } else if ( nodeName === "input" || nodeName === "textarea" ) { dest.defaultValue = src.defaultValue; } } function domManip( collection, args, callback, ignored ) { // Flatten any nested arrays args = concat.apply( [], args ); var fragment, first, scripts, hasScripts, node, doc, i = 0, l = collection.length, iNoClone = l - 1, value = args[ 0 ], isFunction = jQuery.isFunction( value ); // We can't cloneNode fragments that contain checked, in WebKit if ( isFunction || ( l > 1 && typeof value === "string" && !support.checkClone && rchecked.test( value ) ) ) { return collection.each( function( index ) { var self = collection.eq( index ); if ( isFunction ) { args[ 0 ] = value.call( this, index, self.html() ); } domManip( self, args, callback, ignored ); } ); } if ( l ) { fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); first = fragment.firstChild; if ( fragment.childNodes.length === 1 ) { fragment = first; } // Require either new content or an interest in ignored elements to invoke the callback if ( first || ignored ) { scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); hasScripts = scripts.length; // Use the original fragment for the last item // instead of the first because it can end up // being emptied incorrectly in certain situations (#8070). for ( ; i < l; i++ ) { node = fragment; if ( i !== iNoClone ) { node = jQuery.clone( node, true, true ); // Keep references to cloned scripts for later restoration if ( hasScripts ) { // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit jQuery.merge( scripts, getAll( node, "script" ) ); } } callback.call( collection[ i ], node, i ); } if ( hasScripts ) { doc = scripts[ scripts.length - 1 ].ownerDocument; // Reenable scripts jQuery.map( scripts, restoreScript ); // Evaluate executable scripts on first document insertion for ( i = 0; i < hasScripts; i++ ) { node = scripts[ i ]; if ( rscriptType.test( node.type || "" ) && !dataPriv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) { if ( node.src ) { // Optional AJAX dependency, but won't run scripts if not present if ( jQuery._evalUrl ) { jQuery._evalUrl( node.src ); } } else { DOMEval( node.textContent.replace( rcleanScript, "" ), doc ); } } } } } } return collection; } function remove( elem, selector, keepData ) { var node, nodes = selector ? jQuery.filter( selector, elem ) : elem, i = 0; for ( ; ( node = nodes[ i ] ) != null; i++ ) { if ( !keepData && node.nodeType === 1 ) { jQuery.cleanData( getAll( node ) ); } if ( node.parentNode ) { if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { setGlobalEval( getAll( node, "script" ) ); } node.parentNode.removeChild( node ); } } return elem; } jQuery.extend( { htmlPrefilter: function( html ) { return html.replace( rxhtmlTag, "<$1>" ); }, clone: function( elem, dataAndEvents, deepDataAndEvents ) { var i, l, srcElements, destElements, clone = elem.cloneNode( true ), inPage = jQuery.contains( elem.ownerDocument, elem ); // Fix IE cloning issues if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) { // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 destElements = getAll( clone ); srcElements = getAll( elem ); for ( i = 0, l = srcElements.length; i < l; i++ ) { fixInput( srcElements[ i ], destElements[ i ] ); } } // Copy the events from the original to the clone if ( dataAndEvents ) { if ( deepDataAndEvents ) { srcElements = srcElements || getAll( elem ); destElements = destElements || getAll( clone ); for ( i = 0, l = srcElements.length; i < l; i++ ) { cloneCopyEvent( srcElements[ i ], destElements[ i ] ); } } else { cloneCopyEvent( elem, clone ); } } // Preserve script evaluation history destElements = getAll( clone, "script" ); if ( destElements.length > 0 ) { setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); } // Return the cloned set return clone; }, cleanData: function( elems ) { var data, elem, type, special = jQuery.event.special, i = 0; for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { if ( acceptData( elem ) ) { if ( ( data = elem[ dataPriv.expando ] ) ) { if ( data.events ) { for ( type in data.events ) { if ( special[ type ] ) { jQuery.event.remove( elem, type ); // This is a shortcut to avoid jQuery.event.remove's overhead } else { jQuery.removeEvent( elem, type, data.handle ); } } } // Support: Chrome <=35 - 45+ // Assign undefined instead of using delete, see Data#remove elem[ dataPriv.expando ] = undefined; } if ( elem[ dataUser.expando ] ) { // Support: Chrome <=35 - 45+ // Assign undefined instead of using delete, see Data#remove elem[ dataUser.expando ] = undefined; } } } } } ); jQuery.fn.extend( { detach: function( selector ) { return remove( this, selector, true ); }, remove: function( selector ) { return remove( this, selector ); }, text: function( value ) { return access( this, function( value ) { return value === undefined ? jQuery.text( this ) : this.empty().each( function() { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { this.textContent = value; } } ); }, null, value, arguments.length ); }, append: function() { return domManip( this, arguments, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { var target = manipulationTarget( this, elem ); target.appendChild( elem ); } } ); }, prepend: function() { return domManip( this, arguments, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { var target = manipulationTarget( this, elem ); target.insertBefore( elem, target.firstChild ); } } ); }, before: function() { return domManip( this, arguments, function( elem ) { if ( this.parentNode ) { this.parentNode.insertBefore( elem, this ); } } ); }, after: function() { return domManip( this, arguments, function( elem ) { if ( this.parentNode ) { this.parentNode.insertBefore( elem, this.nextSibling ); } } ); }, empty: function() { var elem, i = 0; for ( ; ( elem = this[ i ] ) != null; i++ ) { if ( elem.nodeType === 1 ) { // Prevent memory leaks jQuery.cleanData( getAll( elem, false ) ); // Remove any remaining nodes elem.textContent = ""; } } return this; }, clone: function( dataAndEvents, deepDataAndEvents ) { dataAndEvents = dataAndEvents == null ? false : dataAndEvents; deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; return this.map( function() { return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); } ); }, html: function( value ) { return access( this, function( value ) { var elem = this[ 0 ] || {}, i = 0, l = this.length; if ( value === undefined && elem.nodeType === 1 ) { return elem.innerHTML; } // See if we can take a shortcut and just use innerHTML if ( typeof value === "string" && !rnoInnerhtml.test( value ) && !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { value = jQuery.htmlPrefilter( value ); try { for ( ; i < l; i++ ) { elem = this[ i ] || {}; // Remove element nodes and prevent memory leaks if ( elem.nodeType === 1 ) { jQuery.cleanData( getAll( elem, false ) ); elem.innerHTML = value; } } elem = 0; // If using innerHTML throws an exception, use the fallback method } catch ( e ) {} } if ( elem ) { this.empty().append( value ); } }, null, value, arguments.length ); }, replaceWith: function() { var ignored = []; // Make the changes, replacing each non-ignored context element with the new content return domManip( this, arguments, function( elem ) { var parent = this.parentNode; if ( jQuery.inArray( this, ignored ) < 0 ) { jQuery.cleanData( getAll( this ) ); if ( parent ) { parent.replaceChild( elem, this ); } } // Force callback invocation }, ignored ); } } ); jQuery.each( { appendTo: "append", prependTo: "prepend", insertBefore: "before", insertAfter: "after", replaceAll: "replaceWith" }, function( name, original ) { jQuery.fn[ name ] = function( selector ) { var elems, ret = [], insert = jQuery( selector ), last = insert.length - 1, i = 0; for ( ; i <= last; i++ ) { elems = i === last ? this : this.clone( true ); jQuery( insert[ i ] )[ original ]( elems ); // Support: Android <=4.0 only, PhantomJS 1 only // .get() because push.apply(_, arraylike) throws on ancient WebKit push.apply( ret, elems.get() ); } return this.pushStack( ret ); }; } ); var rmargin = ( /^margin/ ); var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); var getStyles = function( elem ) { // Support: IE <=11 only, Firefox <=30 (#15098, #14150) // IE throws on elements created in popups // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" var view = elem.ownerDocument.defaultView; if ( !view || !view.opener ) { view = window; } return view.getComputedStyle( elem ); }; ( function() { // Executing both pixelPosition & boxSizingReliable tests require only one layout // so they're executed at the same time to save the second computation. function computeStyleTests() { // This is a singleton, we need to execute it only once if ( !div ) { return; } div.style.cssText = "box-sizing:border-box;" + "position:relative;display:block;" + "margin:auto;border:1px;padding:1px;" + "top:1%;width:50%"; div.innerHTML = ""; documentElement.appendChild( container ); var divStyle = window.getComputedStyle( div ); pixelPositionVal = divStyle.top !== "1%"; // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 reliableMarginLeftVal = divStyle.marginLeft === "2px"; boxSizingReliableVal = divStyle.width === "4px"; // Support: Android 4.0 - 4.3 only // Some styles come back with percentage values, even though they shouldn't div.style.marginRight = "50%"; pixelMarginRightVal = divStyle.marginRight === "4px"; documentElement.removeChild( container ); // Nullify the div so it wouldn't be stored in the memory and // it will also be a sign that checks already performed div = null; } var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal, container = document.createElement( "div" ), div = document.createElement( "div" ); // Finish early in limited (non-browser) environments if ( !div.style ) { return; } // Support: IE <=9 - 11 only // Style of cloned element affects source element cloned (#8908) div.style.backgroundClip = "content-box"; div.cloneNode( true ).style.backgroundClip = ""; support.clearCloneStyle = div.style.backgroundClip === "content-box"; container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" + "padding:0;margin-top:1px;position:absolute"; container.appendChild( div ); jQuery.extend( support, { pixelPosition: function() { computeStyleTests(); return pixelPositionVal; }, boxSizingReliable: function() { computeStyleTests(); return boxSizingReliableVal; }, pixelMarginRight: function() { computeStyleTests(); return pixelMarginRightVal; }, reliableMarginLeft: function() { computeStyleTests(); return reliableMarginLeftVal; } } ); } )(); function curCSS( elem, name, computed ) { var width, minWidth, maxWidth, ret, style = elem.style; computed = computed || getStyles( elem ); // Support: IE <=9 only // getPropertyValue is only needed for .css('filter') (#12537) if ( computed ) { ret = computed.getPropertyValue( name ) || computed[ name ]; if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { ret = jQuery.style( elem, name ); } // A tribute to the "awesome hack by Dean Edwards" // Android Browser returns percentage for some values, // but width seems to be reliably pixels. // This is against the CSSOM draft spec: // https://drafts.csswg.org/cssom/#resolved-values if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) { // Remember the original values width = style.width; minWidth = style.minWidth; maxWidth = style.maxWidth; // Put in the new values to get a computed value out style.minWidth = style.maxWidth = style.width = ret; ret = computed.width; // Revert the changed values style.width = width; style.minWidth = minWidth; style.maxWidth = maxWidth; } } return ret !== undefined ? // Support: IE <=9 - 11 only // IE returns zIndex value as an integer. ret + "" : ret; } function addGetHookIf( conditionFn, hookFn ) { // Define the hook, we'll check on the first run if it's really needed. return { get: function() { if ( conditionFn() ) { // Hook not needed (or it's not possible to use it due // to missing dependency), remove it. delete this.get; return; } // Hook needed; redefine it so that the support test is not executed again. return ( this.get = hookFn ).apply( this, arguments ); } }; } var // Swappable if display is none or starts with table // except "table", "table-cell", or "table-caption" // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display rdisplayswap = /^(none|table(?!-c[ea]).+)/, cssShow = { position: "absolute", visibility: "hidden", display: "block" }, cssNormalTransform = { letterSpacing: "0", fontWeight: "400" }, cssPrefixes = [ "Webkit", "Moz", "ms" ], emptyStyle = document.createElement( "div" ).style; // Return a css property mapped to a potentially vendor prefixed property function vendorPropName( name ) { // Shortcut for names that are not vendor prefixed if ( name in emptyStyle ) { return name; } // Check for vendor prefixed names var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), i = cssPrefixes.length; while ( i-- ) { name = cssPrefixes[ i ] + capName; if ( name in emptyStyle ) { return name; } } } function setPositiveNumber( elem, value, subtract ) { // Any relative (+/-) values have already been // normalized at this point var matches = rcssNum.exec( value ); return matches ? // Guard against undefined "subtract", e.g., when used as in cssHooks Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : value; } function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { var i, val = 0; // If we already have the right measurement, avoid augmentation if ( extra === ( isBorderBox ? "border" : "content" ) ) { i = 4; // Otherwise initialize for horizontal or vertical properties } else { i = name === "width" ? 1 : 0; } for ( ; i < 4; i += 2 ) { // Both box models exclude margin, so add it if we want it if ( extra === "margin" ) { val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); } if ( isBorderBox ) { // border-box includes padding, so remove it if we want content if ( extra === "content" ) { val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); } // At this point, extra isn't border nor margin, so remove border if ( extra !== "margin" ) { val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); } } else { // At this point, extra isn't content, so add padding val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); // At this point, extra isn't content nor padding, so add border if ( extra !== "padding" ) { val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); } } } return val; } function getWidthOrHeight( elem, name, extra ) { // Start with offset property, which is equivalent to the border-box value var val, valueIsBorderBox = true, styles = getStyles( elem ), isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; // Support: IE <=11 only // Running getBoundingClientRect on a disconnected node // in IE throws an error. if ( elem.getClientRects().length ) { val = elem.getBoundingClientRect()[ name ]; } // Some non-html elements return undefined for offsetWidth, so check for null/undefined // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 if ( val <= 0 || val == null ) { // Fall back to computed then uncomputed css if necessary val = curCSS( elem, name, styles ); if ( val < 0 || val == null ) { val = elem.style[ name ]; } // Computed unit is not pixels. Stop here and return. if ( rnumnonpx.test( val ) ) { return val; } // Check for style in case a browser which returns unreliable values // for getComputedStyle silently falls back to the reliable elem.style valueIsBorderBox = isBorderBox && ( support.boxSizingReliable() || val === elem.style[ name ] ); // Normalize "", auto, and prepare for extra val = parseFloat( val ) || 0; } // Use the active box-sizing model to add/subtract irrelevant styles return ( val + augmentWidthOrHeight( elem, name, extra || ( isBorderBox ? "border" : "content" ), valueIsBorderBox, styles ) ) + "px"; } jQuery.extend( { // Add in style property hooks for overriding the default // behavior of getting and setting a style property cssHooks: { opacity: { get: function( elem, computed ) { if ( computed ) { // We should always get a number back from opacity var ret = curCSS( elem, "opacity" ); return ret === "" ? "1" : ret; } } } }, // Don't automatically add "px" to these possibly-unitless properties cssNumber: { "animationIterationCount": true, "columnCount": true, "fillOpacity": true, "flexGrow": true, "flexShrink": true, "fontWeight": true, "lineHeight": true, "opacity": true, "order": true, "orphans": true, "widows": true, "zIndex": true, "zoom": true }, // Add in properties whose names you wish to fix before // setting or getting the value cssProps: { "float": "cssFloat" }, // Get and set the style property on a DOM Node style: function( elem, name, value, extra ) { // Don't set styles on text and comment nodes if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { return; } // Make sure that we're working with the right name var ret, type, hooks, origName = jQuery.camelCase( name ), style = elem.style; name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName ); // Gets hook for the prefixed version, then unprefixed version hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; // Check if we're setting a value if ( value !== undefined ) { type = typeof value; // Convert "+=" or "-=" to relative numbers (#7345) if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { value = adjustCSS( elem, name, ret ); // Fixes bug #9237 type = "number"; } // Make sure that null and NaN values aren't set (#7116) if ( value == null || value !== value ) { return; } // If a number was passed in, add the unit (except for certain CSS properties) if ( type === "number" ) { value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); } // background-* props affect original clone's values if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { style[ name ] = "inherit"; } // If a hook was provided, use that value, otherwise just set the specified value if ( !hooks || !( "set" in hooks ) || ( value = hooks.set( elem, value, extra ) ) !== undefined ) { style[ name ] = value; } } else { // If a hook was provided get the non-computed value from there if ( hooks && "get" in hooks && ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { return ret; } // Otherwise just get the value from the style object return style[ name ]; } }, css: function( elem, name, extra, styles ) { var val, num, hooks, origName = jQuery.camelCase( name ); // Make sure that we're working with the right name name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName ); // Try prefixed name followed by the unprefixed name hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; // If a hook was provided get the computed value from there if ( hooks && "get" in hooks ) { val = hooks.get( elem, true, extra ); } // Otherwise, if a way to get the computed value exists, use that if ( val === undefined ) { val = curCSS( elem, name, styles ); } // Convert "normal" to computed value if ( val === "normal" && name in cssNormalTransform ) { val = cssNormalTransform[ name ]; } // Make numeric if forced or a qualifier was provided and val looks numeric if ( extra === "" || extra ) { num = parseFloat( val ); return extra === true || isFinite( num ) ? num || 0 : val; } return val; } } ); jQuery.each( [ "height", "width" ], function( i, name ) { jQuery.cssHooks[ name ] = { get: function( elem, computed, extra ) { if ( computed ) { // Certain elements can have dimension info if we invisibly show them // but it must have a current display style that would benefit return rdisplayswap.test( jQuery.css( elem, "display" ) ) && // Support: Safari 8+ // Table columns in Safari have non-zero offsetWidth & zero // getBoundingClientRect().width unless display is changed. // Support: IE <=11 only // Running getBoundingClientRect on a disconnected node // in IE throws an error. ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? swap( elem, cssShow, function() { return getWidthOrHeight( elem, name, extra ); } ) : getWidthOrHeight( elem, name, extra ); } }, set: function( elem, value, extra ) { var matches, styles = extra && getStyles( elem ), subtract = extra && augmentWidthOrHeight( elem, name, extra, jQuery.css( elem, "boxSizing", false, styles ) === "border-box", styles ); // Convert to pixels if value adjustment is needed if ( subtract && ( matches = rcssNum.exec( value ) ) && ( matches[ 3 ] || "px" ) !== "px" ) { elem.style[ name ] = value; value = jQuery.css( elem, name ); } return setPositiveNumber( elem, value, subtract ); } }; } ); jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, function( elem, computed ) { if ( computed ) { return ( parseFloat( curCSS( elem, "marginLeft" ) ) || elem.getBoundingClientRect().left - swap( elem, { marginLeft: 0 }, function() { return elem.getBoundingClientRect().left; } ) ) + "px"; } } ); // These hooks are used by animate to expand properties jQuery.each( { margin: "", padding: "", border: "Width" }, function( prefix, suffix ) { jQuery.cssHooks[ prefix + suffix ] = { expand: function( value ) { var i = 0, expanded = {}, // Assumes a single number if not a string parts = typeof value === "string" ? value.split( " " ) : [ value ]; for ( ; i < 4; i++ ) { expanded[ prefix + cssExpand[ i ] + suffix ] = parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; } return expanded; } }; if ( !rmargin.test( prefix ) ) { jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; } } ); jQuery.fn.extend( { css: function( name, value ) { return access( this, function( elem, name, value ) { var styles, len, map = {}, i = 0; if ( jQuery.isArray( name ) ) { styles = getStyles( elem ); len = name.length; for ( ; i < len; i++ ) { map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); } return map; } return value !== undefined ? jQuery.style( elem, name, value ) : jQuery.css( elem, name ); }, name, value, arguments.length > 1 ); } } ); function Tween( elem, options, prop, end, easing ) { return new Tween.prototype.init( elem, options, prop, end, easing ); } jQuery.Tween = Tween; Tween.prototype = { constructor: Tween, init: function( elem, options, prop, end, easing, unit ) { this.elem = elem; this.prop = prop; this.easing = easing || jQuery.easing._default; this.options = options; this.start = this.now = this.cur(); this.end = end; this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); }, cur: function() { var hooks = Tween.propHooks[ this.prop ]; return hooks && hooks.get ? hooks.get( this ) : Tween.propHooks._default.get( this ); }, run: function( percent ) { var eased, hooks = Tween.propHooks[ this.prop ]; if ( this.options.duration ) { this.pos = eased = jQuery.easing[ this.easing ]( percent, this.options.duration * percent, 0, 1, this.options.duration ); } else { this.pos = eased = percent; } this.now = ( this.end - this.start ) * eased + this.start; if ( this.options.step ) { this.options.step.call( this.elem, this.now, this ); } if ( hooks && hooks.set ) { hooks.set( this ); } else { Tween.propHooks._default.set( this ); } return this; } }; Tween.prototype.init.prototype = Tween.prototype; Tween.propHooks = { _default: { get: function( tween ) { var result; // Use a property on the element directly when it is not a DOM element, // or when there is no matching style property that exists. if ( tween.elem.nodeType !== 1 || tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { return tween.elem[ tween.prop ]; } // Passing an empty string as a 3rd parameter to .css will automatically // attempt a parseFloat and fallback to a string if the parse fails. // Simple values such as "10px" are parsed to Float; // complex values such as "rotate(1rad)" are returned as-is. result = jQuery.css( tween.elem, tween.prop, "" ); // Empty strings, null, undefined and "auto" are converted to 0. return !result || result === "auto" ? 0 : result; }, set: function( tween ) { // Use step hook for back compat. // Use cssHook if its there. // Use .style if available and use plain properties where available. if ( jQuery.fx.step[ tween.prop ] ) { jQuery.fx.step[ tween.prop ]( tween ); } else if ( tween.elem.nodeType === 1 && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); } else { tween.elem[ tween.prop ] = tween.now; } } } }; // Support: IE <=9 only // Panic based approach to setting things on disconnected nodes Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { set: function( tween ) { if ( tween.elem.nodeType && tween.elem.parentNode ) { tween.elem[ tween.prop ] = tween.now; } } }; jQuery.easing = { linear: function( p ) { return p; }, swing: function( p ) { return 0.5 - Math.cos( p * Math.PI ) / 2; }, _default: "swing" }; jQuery.fx = Tween.prototype.init; // Back compat <1.8 extension point jQuery.fx.step = {}; var fxNow, timerId, rfxtypes = /^(?:toggle|show|hide)$/, rrun = /queueHooks$/; function raf() { if ( timerId ) { window.requestAnimationFrame( raf ); jQuery.fx.tick(); } } // Animations created synchronously will run synchronously function createFxNow() { window.setTimeout( function() { fxNow = undefined; } ); return ( fxNow = jQuery.now() ); } // Generate parameters to create a standard animation function genFx( type, includeWidth ) { var which, i = 0, attrs = { height: type }; // If we include width, step value is 1 to do all cssExpand values, // otherwise step value is 2 to skip over Left and Right includeWidth = includeWidth ? 1 : 0; for ( ; i < 4; i += 2 - includeWidth ) { which = cssExpand[ i ]; attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; } if ( includeWidth ) { attrs.opacity = attrs.width = type; } return attrs; } function createTween( value, prop, animation ) { var tween, collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), index = 0, length = collection.length; for ( ; index < length; index++ ) { if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { // We're done with this property return tween; } } } function defaultPrefilter( elem, props, opts ) { var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, isBox = "width" in props || "height" in props, anim = this, orig = {}, style = elem.style, hidden = elem.nodeType && isHiddenWithinTree( elem ), dataShow = dataPriv.get( elem, "fxshow" ); // Queue-skipping animations hijack the fx hooks if ( !opts.queue ) { hooks = jQuery._queueHooks( elem, "fx" ); if ( hooks.unqueued == null ) { hooks.unqueued = 0; oldfire = hooks.empty.fire; hooks.empty.fire = function() { if ( !hooks.unqueued ) { oldfire(); } }; } hooks.unqueued++; anim.always( function() { // Ensure the complete handler is called before this completes anim.always( function() { hooks.unqueued--; if ( !jQuery.queue( elem, "fx" ).length ) { hooks.empty.fire(); } } ); } ); } // Detect show/hide animations for ( prop in props ) { value = props[ prop ]; if ( rfxtypes.test( value ) ) { delete props[ prop ]; toggle = toggle || value === "toggle"; if ( value === ( hidden ? "hide" : "show" ) ) { // Pretend to be hidden if this is a "show" and // there is still data from a stopped show/hide if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { hidden = true; // Ignore all other no-op show/hide data } else { continue; } } orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); } } // Bail out if this is a no-op like .hide().hide() propTween = !jQuery.isEmptyObject( props ); if ( !propTween && jQuery.isEmptyObject( orig ) ) { return; } // Restrict "overflow" and "display" styles during box animations if ( isBox && elem.nodeType === 1 ) { // Support: IE <=9 - 11, Edge 12 - 13 // Record all 3 overflow attributes because IE does not infer the shorthand // from identically-valued overflowX and overflowY opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; // Identify a display type, preferring old show/hide data over the CSS cascade restoreDisplay = dataShow && dataShow.display; if ( restoreDisplay == null ) { restoreDisplay = dataPriv.get( elem, "display" ); } display = jQuery.css( elem, "display" ); if ( display === "none" ) { if ( restoreDisplay ) { display = restoreDisplay; } else { // Get nonempty value(s) by temporarily forcing visibility showHide( [ elem ], true ); restoreDisplay = elem.style.display || restoreDisplay; display = jQuery.css( elem, "display" ); showHide( [ elem ] ); } } // Animate inline elements as inline-block if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { if ( jQuery.css( elem, "float" ) === "none" ) { // Restore the original display value at the end of pure show/hide animations if ( !propTween ) { anim.done( function() { style.display = restoreDisplay; } ); if ( restoreDisplay == null ) { display = style.display; restoreDisplay = display === "none" ? "" : display; } } style.display = "inline-block"; } } } if ( opts.overflow ) { style.overflow = "hidden"; anim.always( function() { style.overflow = opts.overflow[ 0 ]; style.overflowX = opts.overflow[ 1 ]; style.overflowY = opts.overflow[ 2 ]; } ); } // Implement show/hide animations propTween = false; for ( prop in orig ) { // General show/hide setup for this element animation if ( !propTween ) { if ( dataShow ) { if ( "hidden" in dataShow ) { hidden = dataShow.hidden; } } else { dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); } // Store hidden/visible for toggle so `.stop().toggle()` "reverses" if ( toggle ) { dataShow.hidden = !hidden; } // Show elements before animating them if ( hidden ) { showHide( [ elem ], true ); } /* eslint-disable no-loop-func */ anim.done( function() { /* eslint-enable no-loop-func */ // The final step of a "hide" animation is actually hiding the element if ( !hidden ) { showHide( [ elem ] ); } dataPriv.remove( elem, "fxshow" ); for ( prop in orig ) { jQuery.style( elem, prop, orig[ prop ] ); } } ); } // Per-property setup propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); if ( !( prop in dataShow ) ) { dataShow[ prop ] = propTween.start; if ( hidden ) { propTween.end = propTween.start; propTween.start = 0; } } } } function propFilter( props, specialEasing ) { var index, name, easing, value, hooks; // camelCase, specialEasing and expand cssHook pass for ( index in props ) { name = jQuery.camelCase( index ); easing = specialEasing[ name ]; value = props[ index ]; if ( jQuery.isArray( value ) ) { easing = value[ 1 ]; value = props[ index ] = value[ 0 ]; } if ( index !== name ) { props[ name ] = value; delete props[ index ]; } hooks = jQuery.cssHooks[ name ]; if ( hooks && "expand" in hooks ) { value = hooks.expand( value ); delete props[ name ]; // Not quite $.extend, this won't overwrite existing keys. // Reusing 'index' because we have the correct "name" for ( index in value ) { if ( !( index in props ) ) { props[ index ] = value[ index ]; specialEasing[ index ] = easing; } } } else { specialEasing[ name ] = easing; } } } function Animation( elem, properties, options ) { var result, stopped, index = 0, length = Animation.prefilters.length, deferred = jQuery.Deferred().always( function() { // Don't match elem in the :animated selector delete tick.elem; } ), tick = function() { if ( stopped ) { return false; } var currentTime = fxNow || createFxNow(), remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), // Support: Android 2.3 only // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) temp = remaining / animation.duration || 0, percent = 1 - temp, index = 0, length = animation.tweens.length; for ( ; index < length; index++ ) { animation.tweens[ index ].run( percent ); } deferred.notifyWith( elem, [ animation, percent, remaining ] ); if ( percent < 1 && length ) { return remaining; } else { deferred.resolveWith( elem, [ animation ] ); return false; } }, animation = deferred.promise( { elem: elem, props: jQuery.extend( {}, properties ), opts: jQuery.extend( true, { specialEasing: {}, easing: jQuery.easing._default }, options ), originalProperties: properties, originalOptions: options, startTime: fxNow || createFxNow(), duration: options.duration, tweens: [], createTween: function( prop, end ) { var tween = jQuery.Tween( elem, animation.opts, prop, end, animation.opts.specialEasing[ prop ] || animation.opts.easing ); animation.tweens.push( tween ); return tween; }, stop: function( gotoEnd ) { var index = 0, // If we are going to the end, we want to run all the tweens // otherwise we skip this part length = gotoEnd ? animation.tweens.length : 0; if ( stopped ) { return this; } stopped = true; for ( ; index < length; index++ ) { animation.tweens[ index ].run( 1 ); } // Resolve when we played the last frame; otherwise, reject if ( gotoEnd ) { deferred.notifyWith( elem, [ animation, 1, 0 ] ); deferred.resolveWith( elem, [ animation, gotoEnd ] ); } else { deferred.rejectWith( elem, [ animation, gotoEnd ] ); } return this; } } ), props = animation.props; propFilter( props, animation.opts.specialEasing ); for ( ; index < length; index++ ) { result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); if ( result ) { if ( jQuery.isFunction( result.stop ) ) { jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = jQuery.proxy( result.stop, result ); } return result; } } jQuery.map( props, createTween, animation ); if ( jQuery.isFunction( animation.opts.start ) ) { animation.opts.start.call( elem, animation ); } jQuery.fx.timer( jQuery.extend( tick, { elem: elem, anim: animation, queue: animation.opts.queue } ) ); // attach callbacks from options return animation.progress( animation.opts.progress ) .done( animation.opts.done, animation.opts.complete ) .fail( animation.opts.fail ) .always( animation.opts.always ); } jQuery.Animation = jQuery.extend( Animation, { tweeners: { "*": [ function( prop, value ) { var tween = this.createTween( prop, value ); adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); return tween; } ] }, tweener: function( props, callback ) { if ( jQuery.isFunction( props ) ) { callback = props; props = [ "*" ]; } else { props = props.match( rnothtmlwhite ); } var prop, index = 0, length = props.length; for ( ; index < length; index++ ) { prop = props[ index ]; Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; Animation.tweeners[ prop ].unshift( callback ); } }, prefilters: [ defaultPrefilter ], prefilter: function( callback, prepend ) { if ( prepend ) { Animation.prefilters.unshift( callback ); } else { Animation.prefilters.push( callback ); } } } ); jQuery.speed = function( speed, easing, fn ) { var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { complete: fn || !fn && easing || jQuery.isFunction( speed ) && speed, duration: speed, easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing }; // Go to the end state if fx are off or if document is hidden if ( jQuery.fx.off || document.hidden ) { opt.duration = 0; } else { if ( typeof opt.duration !== "number" ) { if ( opt.duration in jQuery.fx.speeds ) { opt.duration = jQuery.fx.speeds[ opt.duration ]; } else { opt.duration = jQuery.fx.speeds._default; } } } // Normalize opt.queue - true/undefined/null -> "fx" if ( opt.queue == null || opt.queue === true ) { opt.queue = "fx"; } // Queueing opt.old = opt.complete; opt.complete = function() { if ( jQuery.isFunction( opt.old ) ) { opt.old.call( this ); } if ( opt.queue ) { jQuery.dequeue( this, opt.queue ); } }; return opt; }; jQuery.fn.extend( { fadeTo: function( speed, to, easing, callback ) { // Show any hidden elements after setting opacity to 0 return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() // Animate to the value specified .end().animate( { opacity: to }, speed, easing, callback ); }, animate: function( prop, speed, easing, callback ) { var empty = jQuery.isEmptyObject( prop ), optall = jQuery.speed( speed, easing, callback ), doAnimation = function() { // Operate on a copy of prop so per-property easing won't be lost var anim = Animation( this, jQuery.extend( {}, prop ), optall ); // Empty animations, or finishing resolves immediately if ( empty || dataPriv.get( this, "finish" ) ) { anim.stop( true ); } }; doAnimation.finish = doAnimation; return empty || optall.queue === false ? this.each( doAnimation ) : this.queue( optall.queue, doAnimation ); }, stop: function( type, clearQueue, gotoEnd ) { var stopQueue = function( hooks ) { var stop = hooks.stop; delete hooks.stop; stop( gotoEnd ); }; if ( typeof type !== "string" ) { gotoEnd = clearQueue; clearQueue = type; type = undefined; } if ( clearQueue && type !== false ) { this.queue( type || "fx", [] ); } return this.each( function() { var dequeue = true, index = type != null && type + "queueHooks", timers = jQuery.timers, data = dataPriv.get( this ); if ( index ) { if ( data[ index ] && data[ index ].stop ) { stopQueue( data[ index ] ); } } else { for ( index in data ) { if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { stopQueue( data[ index ] ); } } } for ( index = timers.length; index--; ) { if ( timers[ index ].elem === this && ( type == null || timers[ index ].queue === type ) ) { timers[ index ].anim.stop( gotoEnd ); dequeue = false; timers.splice( index, 1 ); } } // Start the next in the queue if the last step wasn't forced. // Timers currently will call their complete callbacks, which // will dequeue but only if they were gotoEnd. if ( dequeue || !gotoEnd ) { jQuery.dequeue( this, type ); } } ); }, finish: function( type ) { if ( type !== false ) { type = type || "fx"; } return this.each( function() { var index, data = dataPriv.get( this ), queue = data[ type + "queue" ], hooks = data[ type + "queueHooks" ], timers = jQuery.timers, length = queue ? queue.length : 0; // Enable finishing flag on private data data.finish = true; // Empty the queue first jQuery.queue( this, type, [] ); if ( hooks && hooks.stop ) { hooks.stop.call( this, true ); } // Look for any active animations, and finish them for ( index = timers.length; index--; ) { if ( timers[ index ].elem === this && timers[ index ].queue === type ) { timers[ index ].anim.stop( true ); timers.splice( index, 1 ); } } // Look for any animations in the old queue and finish them for ( index = 0; index < length; index++ ) { if ( queue[ index ] && queue[ index ].finish ) { queue[ index ].finish.call( this ); } } // Turn off finishing flag delete data.finish; } ); } } ); jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) { var cssFn = jQuery.fn[ name ]; jQuery.fn[ name ] = function( speed, easing, callback ) { return speed == null || typeof speed === "boolean" ? cssFn.apply( this, arguments ) : this.animate( genFx( name, true ), speed, easing, callback ); }; } ); // Generate shortcuts for custom animations jQuery.each( { slideDown: genFx( "show" ), slideUp: genFx( "hide" ), slideToggle: genFx( "toggle" ), fadeIn: { opacity: "show" }, fadeOut: { opacity: "hide" }, fadeToggle: { opacity: "toggle" } }, function( name, props ) { jQuery.fn[ name ] = function( speed, easing, callback ) { return this.animate( props, speed, easing, callback ); }; } ); jQuery.timers = []; jQuery.fx.tick = function() { var timer, i = 0, timers = jQuery.timers; fxNow = jQuery.now(); for ( ; i < timers.length; i++ ) { timer = timers[ i ]; // Checks the timer has not already been removed if ( !timer() && timers[ i ] === timer ) { timers.splice( i--, 1 ); } } if ( !timers.length ) { jQuery.fx.stop(); } fxNow = undefined; }; jQuery.fx.timer = function( timer ) { jQuery.timers.push( timer ); if ( timer() ) { jQuery.fx.start(); } else { jQuery.timers.pop(); } }; jQuery.fx.interval = 13; jQuery.fx.start = function() { if ( !timerId ) { timerId = window.requestAnimationFrame ? window.requestAnimationFrame( raf ) : window.setInterval( jQuery.fx.tick, jQuery.fx.interval ); } }; jQuery.fx.stop = function() { if ( window.cancelAnimationFrame ) { window.cancelAnimationFrame( timerId ); } else { window.clearInterval( timerId ); } timerId = null; }; jQuery.fx.speeds = { slow: 600, fast: 200, // Default speed _default: 400 }; // Based off of the plugin by Clint Helfers, with permission. // https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ jQuery.fn.delay = function( time, type ) { time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; type = type || "fx"; return this.queue( type, function( next, hooks ) { var timeout = window.setTimeout( next, time ); hooks.stop = function() { window.clearTimeout( timeout ); }; } ); }; ( function() { var input = document.createElement( "input" ), select = document.createElement( "select" ), opt = select.appendChild( document.createElement( "option" ) ); input.type = "checkbox"; // Support: Android <=4.3 only // Default value for a checkbox should be "on" support.checkOn = input.value !== ""; // Support: IE <=11 only // Must access selectedIndex to make default options select support.optSelected = opt.selected; // Support: IE <=11 only // An input loses its value after becoming a radio input = document.createElement( "input" ); input.value = "t"; input.type = "radio"; support.radioValue = input.value === "t"; } )(); var boolHook, attrHandle = jQuery.expr.attrHandle; jQuery.fn.extend( { attr: function( name, value ) { return access( this, jQuery.attr, name, value, arguments.length > 1 ); }, removeAttr: function( name ) { return this.each( function() { jQuery.removeAttr( this, name ); } ); } } ); jQuery.extend( { attr: function( elem, name, value ) { var ret, hooks, nType = elem.nodeType; // Don't get/set attributes on text, comment and attribute nodes if ( nType === 3 || nType === 8 || nType === 2 ) { return; } // Fallback to prop when attributes are not supported if ( typeof elem.getAttribute === "undefined" ) { return jQuery.prop( elem, name, value ); } // Attribute hooks are determined by the lowercase version // Grab necessary hook if one is defined if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { hooks = jQuery.attrHooks[ name.toLowerCase() ] || ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); } if ( value !== undefined ) { if ( value === null ) { jQuery.removeAttr( elem, name ); return; } if ( hooks && "set" in hooks && ( ret = hooks.set( elem, value, name ) ) !== undefined ) { return ret; } elem.setAttribute( name, value + "" ); return value; } if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { return ret; } ret = jQuery.find.attr( elem, name ); // Non-existent attributes return null, we normalize to undefined return ret == null ? undefined : ret; }, attrHooks: { type: { set: function( elem, value ) { if ( !support.radioValue && value === "radio" && jQuery.nodeName( elem, "input" ) ) { var val = elem.value; elem.setAttribute( "type", value ); if ( val ) { elem.value = val; } return value; } } } }, removeAttr: function( elem, value ) { var name, i = 0, // Attribute names can contain non-HTML whitespace characters // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 attrNames = value && value.match( rnothtmlwhite ); if ( attrNames && elem.nodeType === 1 ) { while ( ( name = attrNames[ i++ ] ) ) { elem.removeAttribute( name ); } } } } ); // Hooks for boolean attributes boolHook = { set: function( elem, value, name ) { if ( value === false ) { // Remove boolean attributes when set to false jQuery.removeAttr( elem, name ); } else { elem.setAttribute( name, name ); } return name; } }; jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { var getter = attrHandle[ name ] || jQuery.find.attr; attrHandle[ name ] = function( elem, name, isXML ) { var ret, handle, lowercaseName = name.toLowerCase(); if ( !isXML ) { // Avoid an infinite loop by temporarily removing this function from the getter handle = attrHandle[ lowercaseName ]; attrHandle[ lowercaseName ] = ret; ret = getter( elem, name, isXML ) != null ? lowercaseName : null; attrHandle[ lowercaseName ] = handle; } return ret; }; } ); var rfocusable = /^(?:input|select|textarea|button)$/i, rclickable = /^(?:a|area)$/i; jQuery.fn.extend( { prop: function( name, value ) { return access( this, jQuery.prop, name, value, arguments.length > 1 ); }, removeProp: function( name ) { return this.each( function() { delete this[ jQuery.propFix[ name ] || name ]; } ); } } ); jQuery.extend( { prop: function( elem, name, value ) { var ret, hooks, nType = elem.nodeType; // Don't get/set properties on text, comment and attribute nodes if ( nType === 3 || nType === 8 || nType === 2 ) { return; } if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { // Fix name and attach hooks name = jQuery.propFix[ name ] || name; hooks = jQuery.propHooks[ name ]; } if ( value !== undefined ) { if ( hooks && "set" in hooks && ( ret = hooks.set( elem, value, name ) ) !== undefined ) { return ret; } return ( elem[ name ] = value ); } if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { return ret; } return elem[ name ]; }, propHooks: { tabIndex: { get: function( elem ) { // Support: IE <=9 - 11 only // elem.tabIndex doesn't always return the // correct value when it hasn't been explicitly set // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ // Use proper attribute retrieval(#12072) var tabindex = jQuery.find.attr( elem, "tabindex" ); if ( tabindex ) { return parseInt( tabindex, 10 ); } if ( rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ) { return 0; } return -1; } } }, propFix: { "for": "htmlFor", "class": "className" } } ); // Support: IE <=11 only // Accessing the selectedIndex property // forces the browser to respect setting selected // on the option // The getter ensures a default option is selected // when in an optgroup // eslint rule "no-unused-expressions" is disabled for this code // since it considers such accessions noop if ( !support.optSelected ) { jQuery.propHooks.selected = { get: function( elem ) { /* eslint no-unused-expressions: "off" */ var parent = elem.parentNode; if ( parent && parent.parentNode ) { parent.parentNode.selectedIndex; } return null; }, set: function( elem ) { /* eslint no-unused-expressions: "off" */ var parent = elem.parentNode; if ( parent ) { parent.selectedIndex; if ( parent.parentNode ) { parent.parentNode.selectedIndex; } } } }; } jQuery.each( [ "tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable" ], function() { jQuery.propFix[ this.toLowerCase() ] = this; } ); // Strip and collapse whitespace according to HTML spec // https://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace function stripAndCollapse( value ) { var tokens = value.match( rnothtmlwhite ) || []; return tokens.join( " " ); } function getClass( elem ) { return elem.getAttribute && elem.getAttribute( "class" ) || ""; } jQuery.fn.extend( { addClass: function( value ) { var classes, elem, cur, curValue, clazz, j, finalValue, i = 0; if ( jQuery.isFunction( value ) ) { return this.each( function( j ) { jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); } ); } if ( typeof value === "string" && value ) { classes = value.match( rnothtmlwhite ) || []; while ( ( elem = this[ i++ ] ) ) { curValue = getClass( elem ); cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); if ( cur ) { j = 0; while ( ( clazz = classes[ j++ ] ) ) { if ( cur.indexOf( " " + clazz + " " ) < 0 ) { cur += clazz + " "; } } // Only assign if different to avoid unneeded rendering. finalValue = stripAndCollapse( cur ); if ( curValue !== finalValue ) { elem.setAttribute( "class", finalValue ); } } } } return this; }, removeClass: function( value ) { var classes, elem, cur, curValue, clazz, j, finalValue, i = 0; if ( jQuery.isFunction( value ) ) { return this.each( function( j ) { jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); } ); } if ( !arguments.length ) { return this.attr( "class", "" ); } if ( typeof value === "string" && value ) { classes = value.match( rnothtmlwhite ) || []; while ( ( elem = this[ i++ ] ) ) { curValue = getClass( elem ); // This expression is here for better compressibility (see addClass) cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); if ( cur ) { j = 0; while ( ( clazz = classes[ j++ ] ) ) { // Remove *all* instances while ( cur.indexOf( " " + clazz + " " ) > -1 ) { cur = cur.replace( " " + clazz + " ", " " ); } } // Only assign if different to avoid unneeded rendering. finalValue = stripAndCollapse( cur ); if ( curValue !== finalValue ) { elem.setAttribute( "class", finalValue ); } } } } return this; }, toggleClass: function( value, stateVal ) { var type = typeof value; if ( typeof stateVal === "boolean" && type === "string" ) { return stateVal ? this.addClass( value ) : this.removeClass( value ); } if ( jQuery.isFunction( value ) ) { return this.each( function( i ) { jQuery( this ).toggleClass( value.call( this, i, getClass( this ), stateVal ), stateVal ); } ); } return this.each( function() { var className, i, self, classNames; if ( type === "string" ) { // Toggle individual class names i = 0; self = jQuery( this ); classNames = value.match( rnothtmlwhite ) || []; while ( ( className = classNames[ i++ ] ) ) { // Check each className given, space separated list if ( self.hasClass( className ) ) { self.removeClass( className ); } else { self.addClass( className ); } } // Toggle whole class name } else if ( value === undefined || type === "boolean" ) { className = getClass( this ); if ( className ) { // Store className if set dataPriv.set( this, "__className__", className ); } // If the element has a class name or if we're passed `false`, // then remove the whole classname (if there was one, the above saved it). // Otherwise bring back whatever was previously saved (if anything), // falling back to the empty string if nothing was stored. if ( this.setAttribute ) { this.setAttribute( "class", className || value === false ? "" : dataPriv.get( this, "__className__" ) || "" ); } } } ); }, hasClass: function( selector ) { var className, elem, i = 0; className = " " + selector + " "; while ( ( elem = this[ i++ ] ) ) { if ( elem.nodeType === 1 && ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { return true; } } return false; } } ); var rreturn = /\r/g; jQuery.fn.extend( { val: function( value ) { var hooks, ret, isFunction, elem = this[ 0 ]; if ( !arguments.length ) { if ( elem ) { hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; if ( hooks && "get" in hooks && ( ret = hooks.get( elem, "value" ) ) !== undefined ) { return ret; } ret = elem.value; // Handle most common string cases if ( typeof ret === "string" ) { return ret.replace( rreturn, "" ); } // Handle cases where value is null/undef or number return ret == null ? "" : ret; } return; } isFunction = jQuery.isFunction( value ); return this.each( function( i ) { var val; if ( this.nodeType !== 1 ) { return; } if ( isFunction ) { val = value.call( this, i, jQuery( this ).val() ); } else { val = value; } // Treat null/undefined as ""; convert numbers to string if ( val == null ) { val = ""; } else if ( typeof val === "number" ) { val += ""; } else if ( jQuery.isArray( val ) ) { val = jQuery.map( val, function( value ) { return value == null ? "" : value + ""; } ); } hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; // If set returns undefined, fall back to normal setting if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { this.value = val; } } ); } } ); jQuery.extend( { valHooks: { option: { get: function( elem ) { var val = jQuery.find.attr( elem, "value" ); return val != null ? val : // Support: IE <=10 - 11 only // option.text throws exceptions (#14686, #14858) // Strip and collapse whitespace // https://html.spec.whatwg.org/#strip-and-collapse-whitespace stripAndCollapse( jQuery.text( elem ) ); } }, select: { get: function( elem ) { var value, option, i, options = elem.options, index = elem.selectedIndex, one = elem.type === "select-one", values = one ? null : [], max = one ? index + 1 : options.length; if ( index < 0 ) { i = max; } else { i = one ? index : 0; } // Loop through all the selected options for ( ; i < max; i++ ) { option = options[ i ]; // Support: IE <=9 only // IE8-9 doesn't update selected after form reset (#2551) if ( ( option.selected || i === index ) && // Don't return options that are disabled or in a disabled optgroup !option.disabled && ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { // Get the specific value for the option value = jQuery( option ).val(); // We don't need an array for one selects if ( one ) { return value; } // Multi-Selects return an array values.push( value ); } } return values; }, set: function( elem, value ) { var optionSet, option, options = elem.options, values = jQuery.makeArray( value ), i = options.length; while ( i-- ) { option = options[ i ]; /* eslint-disable no-cond-assign */ if ( option.selected = jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 ) { optionSet = true; } /* eslint-enable no-cond-assign */ } // Force browsers to behave consistently when non-matching value is set if ( !optionSet ) { elem.selectedIndex = -1; } return values; } } } } ); // Radios and checkboxes getter/setter jQuery.each( [ "radio", "checkbox" ], function() { jQuery.valHooks[ this ] = { set: function( elem, value ) { if ( jQuery.isArray( value ) ) { return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); } } }; if ( !support.checkOn ) { jQuery.valHooks[ this ].get = function( elem ) { return elem.getAttribute( "value" ) === null ? "on" : elem.value; }; } } ); // Return jQuery for attributes-only inclusion var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/; jQuery.extend( jQuery.event, { trigger: function( event, data, elem, onlyHandlers ) { var i, cur, tmp, bubbleType, ontype, handle, special, eventPath = [ elem || document ], type = hasOwn.call( event, "type" ) ? event.type : event, namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; cur = tmp = elem = elem || document; // Don't do events on text and comment nodes if ( elem.nodeType === 3 || elem.nodeType === 8 ) { return; } // focus/blur morphs to focusin/out; ensure we're not firing them right now if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { return; } if ( type.indexOf( "." ) > -1 ) { // Namespaced trigger; create a regexp to match event type in handle() namespaces = type.split( "." ); type = namespaces.shift(); namespaces.sort(); } ontype = type.indexOf( ":" ) < 0 && "on" + type; // Caller can pass in a jQuery.Event object, Object, or just an event type string event = event[ jQuery.expando ] ? event : new jQuery.Event( type, typeof event === "object" && event ); // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) event.isTrigger = onlyHandlers ? 2 : 3; event.namespace = namespaces.join( "." ); event.rnamespace = event.namespace ? new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : null; // Clean up the event in case it is being reused event.result = undefined; if ( !event.target ) { event.target = elem; } // Clone any incoming data and prepend the event, creating the handler arg list data = data == null ? [ event ] : jQuery.makeArray( data, [ event ] ); // Allow special events to draw outside the lines special = jQuery.event.special[ type ] || {}; if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { return; } // Determine event propagation path in advance, per W3C events spec (#9951) // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { bubbleType = special.delegateType || type; if ( !rfocusMorph.test( bubbleType + type ) ) { cur = cur.parentNode; } for ( ; cur; cur = cur.parentNode ) { eventPath.push( cur ); tmp = cur; } // Only add window if we got to document (e.g., not plain obj or detached DOM) if ( tmp === ( elem.ownerDocument || document ) ) { eventPath.push( tmp.defaultView || tmp.parentWindow || window ); } } // Fire handlers on the event path i = 0; while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { event.type = i > 1 ? bubbleType : special.bindType || type; // jQuery handler handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] && dataPriv.get( cur, "handle" ); if ( handle ) { handle.apply( cur, data ); } // Native handler handle = ontype && cur[ ontype ]; if ( handle && handle.apply && acceptData( cur ) ) { event.result = handle.apply( cur, data ); if ( event.result === false ) { event.preventDefault(); } } } event.type = type; // If nobody prevented the default action, do it now if ( !onlyHandlers && !event.isDefaultPrevented() ) { if ( ( !special._default || special._default.apply( eventPath.pop(), data ) === false ) && acceptData( elem ) ) { // Call a native DOM method on the target with the same name as the event. // Don't do default actions on window, that's where global variables be (#6170) if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) { // Don't re-trigger an onFOO event when we call its FOO() method tmp = elem[ ontype ]; if ( tmp ) { elem[ ontype ] = null; } // Prevent re-triggering of the same event, since we already bubbled it above jQuery.event.triggered = type; elem[ type ](); jQuery.event.triggered = undefined; if ( tmp ) { elem[ ontype ] = tmp; } } } } return event.result; }, // Piggyback on a donor event to simulate a different one // Used only for `focus(in | out)` events simulate: function( type, elem, event ) { var e = jQuery.extend( new jQuery.Event(), event, { type: type, isSimulated: true } ); jQuery.event.trigger( e, null, elem ); } } ); jQuery.fn.extend( { trigger: function( type, data ) { return this.each( function() { jQuery.event.trigger( type, data, this ); } ); }, triggerHandler: function( type, data ) { var elem = this[ 0 ]; if ( elem ) { return jQuery.event.trigger( type, data, elem, true ); } } } ); jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + "change select submit keydown keypress keyup contextmenu" ).split( " " ), function( i, name ) { // Handle event binding jQuery.fn[ name ] = function( data, fn ) { return arguments.length > 0 ? this.on( name, null, data, fn ) : this.trigger( name ); }; } ); jQuery.fn.extend( { hover: function( fnOver, fnOut ) { return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); } } ); support.focusin = "onfocusin" in window; // Support: Firefox <=44 // Firefox doesn't have focus(in | out) events // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 // // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 // focus(in | out) events fire after focus & blur events, // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 if ( !support.focusin ) { jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { // Attach a single capturing handler on the document while someone wants focusin/focusout var handler = function( event ) { jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); }; jQuery.event.special[ fix ] = { setup: function() { var doc = this.ownerDocument || this, attaches = dataPriv.access( doc, fix ); if ( !attaches ) { doc.addEventListener( orig, handler, true ); } dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); }, teardown: function() { var doc = this.ownerDocument || this, attaches = dataPriv.access( doc, fix ) - 1; if ( !attaches ) { doc.removeEventListener( orig, handler, true ); dataPriv.remove( doc, fix ); } else { dataPriv.access( doc, fix, attaches ); } } }; } ); } var location = window.location; var nonce = jQuery.now(); var rquery = ( /\?/ ); // Cross-browser xml parsing jQuery.parseXML = function( data ) { var xml; if ( !data || typeof data !== "string" ) { return null; } // Support: IE 9 - 11 only // IE throws on parseFromString with invalid input. try { xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); } catch ( e ) { xml = undefined; } if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { jQuery.error( "Invalid XML: " + data ); } return xml; }; var rbracket = /\[\]$/, rCRLF = /\r?\n/g, rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, rsubmittable = /^(?:input|select|textarea|keygen)/i; function buildParams( prefix, obj, traditional, add ) { var name; if ( jQuery.isArray( obj ) ) { // Serialize array item. jQuery.each( obj, function( i, v ) { if ( traditional || rbracket.test( prefix ) ) { // Treat each array item as a scalar. add( prefix, v ); } else { // Item is non-scalar (array or object), encode its numeric index. buildParams( prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", v, traditional, add ); } } ); } else if ( !traditional && jQuery.type( obj ) === "object" ) { // Serialize object item. for ( name in obj ) { buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); } } else { // Serialize scalar item. add( prefix, obj ); } } // Serialize an array of form elements or a set of // key/values into a query string jQuery.param = function( a, traditional ) { var prefix, s = [], add = function( key, valueOrFunction ) { // If value is a function, invoke it and use its return value var value = jQuery.isFunction( valueOrFunction ) ? valueOrFunction() : valueOrFunction; s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value == null ? "" : value ); }; // If an array was passed in, assume that it is an array of form elements. if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { // Serialize the form elements jQuery.each( a, function() { add( this.name, this.value ); } ); } else { // If traditional, encode the "old" way (the way 1.3.2 or older // did it), otherwise encode params recursively. for ( prefix in a ) { buildParams( prefix, a[ prefix ], traditional, add ); } } // Return the resulting serialization return s.join( "&" ); }; jQuery.fn.extend( { serialize: function() { return jQuery.param( this.serializeArray() ); }, serializeArray: function() { return this.map( function() { // Can add propHook for "elements" to filter or add form elements var elements = jQuery.prop( this, "elements" ); return elements ? jQuery.makeArray( elements ) : this; } ) .filter( function() { var type = this.type; // Use .is( ":disabled" ) so that fieldset[disabled] works return this.name && !jQuery( this ).is( ":disabled" ) && rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && ( this.checked || !rcheckableType.test( type ) ); } ) .map( function( i, elem ) { var val = jQuery( this ).val(); if ( val == null ) { return null; } if ( jQuery.isArray( val ) ) { return jQuery.map( val, function( val ) { return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; } ); } return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; } ).get(); } } ); var r20 = /%20/g, rhash = /#.*$/, rantiCache = /([?&])_=[^&]*/, rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, // #7653, #8125, #8152: local protocol detection rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, rnoContent = /^(?:GET|HEAD)$/, rprotocol = /^\/\//, /* Prefilters * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) * 2) These are called: * - BEFORE asking for a transport * - AFTER param serialization (s.data is a string if s.processData is true) * 3) key is the dataType * 4) the catchall symbol "*" can be used * 5) execution will start with transport dataType and THEN continue down to "*" if needed */ prefilters = {}, /* Transports bindings * 1) key is the dataType * 2) the catchall symbol "*" can be used * 3) selection will start with transport dataType and THEN go to "*" if needed */ transports = {}, // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression allTypes = "*/".concat( "*" ), // Anchor tag for parsing the document origin originAnchor = document.createElement( "a" ); originAnchor.href = location.href; // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport function addToPrefiltersOrTransports( structure ) { // dataTypeExpression is optional and defaults to "*" return function( dataTypeExpression, func ) { if ( typeof dataTypeExpression !== "string" ) { func = dataTypeExpression; dataTypeExpression = "*"; } var dataType, i = 0, dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; if ( jQuery.isFunction( func ) ) { // For each dataType in the dataTypeExpression while ( ( dataType = dataTypes[ i++ ] ) ) { // Prepend if requested if ( dataType[ 0 ] === "+" ) { dataType = dataType.slice( 1 ) || "*"; ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); // Otherwise append } else { ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); } } } }; } // Base inspection function for prefilters and transports function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { var inspected = {}, seekingTransport = ( structure === transports ); function inspect( dataType ) { var selected; inspected[ dataType ] = true; jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) { options.dataTypes.unshift( dataTypeOrTransport ); inspect( dataTypeOrTransport ); return false; } else if ( seekingTransport ) { return !( selected = dataTypeOrTransport ); } } ); return selected; } return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); } // A special extend for ajax options // that takes "flat" options (not to be deep extended) // Fixes #9887 function ajaxExtend( target, src ) { var key, deep, flatOptions = jQuery.ajaxSettings.flatOptions || {}; for ( key in src ) { if ( src[ key ] !== undefined ) { ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; } } if ( deep ) { jQuery.extend( true, target, deep ); } return target; } /* Handles responses to an ajax request: * - finds the right dataType (mediates between content-type and expected dataType) * - returns the corresponding response */ function ajaxHandleResponses( s, jqXHR, responses ) { var ct, type, finalDataType, firstDataType, contents = s.contents, dataTypes = s.dataTypes; // Remove auto dataType and get content-type in the process while ( dataTypes[ 0 ] === "*" ) { dataTypes.shift(); if ( ct === undefined ) { ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); } } // Check if we're dealing with a known content-type if ( ct ) { for ( type in contents ) { if ( contents[ type ] && contents[ type ].test( ct ) ) { dataTypes.unshift( type ); break; } } } // Check to see if we have a response for the expected dataType if ( dataTypes[ 0 ] in responses ) { finalDataType = dataTypes[ 0 ]; } else { // Try convertible dataTypes for ( type in responses ) { if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { finalDataType = type; break; } if ( !firstDataType ) { firstDataType = type; } } // Or just use first one finalDataType = finalDataType || firstDataType; } // If we found a dataType // We add the dataType to the list if needed // and return the corresponding response if ( finalDataType ) { if ( finalDataType !== dataTypes[ 0 ] ) { dataTypes.unshift( finalDataType ); } return responses[ finalDataType ]; } } /* Chain conversions given the request and the original response * Also sets the responseXXX fields on the jqXHR instance */ function ajaxConvert( s, response, jqXHR, isSuccess ) { var conv2, current, conv, tmp, prev, converters = {}, // Work with a copy of dataTypes in case we need to modify it for conversion dataTypes = s.dataTypes.slice(); // Create converters map with lowercased keys if ( dataTypes[ 1 ] ) { for ( conv in s.converters ) { converters[ conv.toLowerCase() ] = s.converters[ conv ]; } } current = dataTypes.shift(); // Convert to each sequential dataType while ( current ) { if ( s.responseFields[ current ] ) { jqXHR[ s.responseFields[ current ] ] = response; } // Apply the dataFilter if provided if ( !prev && isSuccess && s.dataFilter ) { response = s.dataFilter( response, s.dataType ); } prev = current; current = dataTypes.shift(); if ( current ) { // There's only work to do if current dataType is non-auto if ( current === "*" ) { current = prev; // Convert response if prev dataType is non-auto and differs from current } else if ( prev !== "*" && prev !== current ) { // Seek a direct converter conv = converters[ prev + " " + current ] || converters[ "* " + current ]; // If none found, seek a pair if ( !conv ) { for ( conv2 in converters ) { // If conv2 outputs current tmp = conv2.split( " " ); if ( tmp[ 1 ] === current ) { // If prev can be converted to accepted input conv = converters[ prev + " " + tmp[ 0 ] ] || converters[ "* " + tmp[ 0 ] ]; if ( conv ) { // Condense equivalence converters if ( conv === true ) { conv = converters[ conv2 ]; // Otherwise, insert the intermediate dataType } else if ( converters[ conv2 ] !== true ) { current = tmp[ 0 ]; dataTypes.unshift( tmp[ 1 ] ); } break; } } } } // Apply converter (if not an equivalence) if ( conv !== true ) { // Unless errors are allowed to bubble, catch and return them if ( conv && s.throws ) { response = conv( response ); } else { try { response = conv( response ); } catch ( e ) { return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; } } } } } } return { state: "success", data: response }; } jQuery.extend( { // Counter for holding the number of active queries active: 0, // Last-Modified header cache for next request lastModified: {}, etag: {}, ajaxSettings: { url: location.href, type: "GET", isLocal: rlocalProtocol.test( location.protocol ), global: true, processData: true, async: true, contentType: "application/x-www-form-urlencoded; charset=UTF-8", /* timeout: 0, data: null, dataType: null, username: null, password: null, cache: null, throws: false, traditional: false, headers: {}, */ accepts: { "*": allTypes, text: "text/plain", html: "text/html", xml: "application/xml, text/xml", json: "application/json, text/javascript" }, contents: { xml: /\bxml\b/, html: /\bhtml/, json: /\bjson\b/ }, responseFields: { xml: "responseXML", text: "responseText", json: "responseJSON" }, // Data converters // Keys separate source (or catchall "*") and destination types with a single space converters: { // Convert anything to text "* text": String, // Text to html (true = no transformation) "text html": true, // Evaluate text as a json expression "text json": JSON.parse, // Parse text as xml "text xml": jQuery.parseXML }, // For options that shouldn't be deep extended: // you can add your own custom options here if // and when you create one that shouldn't be // deep extended (see ajaxExtend) flatOptions: { url: true, context: true } }, // Creates a full fledged settings object into target // with both ajaxSettings and settings fields. // If target is omitted, writes into ajaxSettings. ajaxSetup: function( target, settings ) { return settings ? // Building a settings object ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : // Extending ajaxSettings ajaxExtend( jQuery.ajaxSettings, target ); }, ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), ajaxTransport: addToPrefiltersOrTransports( transports ), // Main method ajax: function( url, options ) { // If url is an object, simulate pre-1.5 signature if ( typeof url === "object" ) { options = url; url = undefined; } // Force options to be an object options = options || {}; var transport, // URL without anti-cache param cacheURL, // Response headers responseHeadersString, responseHeaders, // timeout handle timeoutTimer, // Url cleanup var urlAnchor, // Request state (becomes false upon send and true upon completion) completed, // To know if global events are to be dispatched fireGlobals, // Loop variable i, // uncached part of the url uncached, // Create the final options object s = jQuery.ajaxSetup( {}, options ), // Callbacks context callbackContext = s.context || s, // Context for global events is callbackContext if it is a DOM node or jQuery collection globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ? jQuery( callbackContext ) : jQuery.event, // Deferreds deferred = jQuery.Deferred(), completeDeferred = jQuery.Callbacks( "once memory" ), // Status-dependent callbacks statusCode = s.statusCode || {}, // Headers (they are sent all at once) requestHeaders = {}, requestHeadersNames = {}, // Default abort message strAbort = "canceled", // Fake xhr jqXHR = { readyState: 0, // Builds headers hashtable if needed getResponseHeader: function( key ) { var match; if ( completed ) { if ( !responseHeaders ) { responseHeaders = {}; while ( ( match = rheaders.exec( responseHeadersString ) ) ) { responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ]; } } match = responseHeaders[ key.toLowerCase() ]; } return match == null ? null : match; }, // Raw string getAllResponseHeaders: function() { return completed ? responseHeadersString : null; }, // Caches the header setRequestHeader: function( name, value ) { if ( completed == null ) { name = requestHeadersNames[ name.toLowerCase() ] = requestHeadersNames[ name.toLowerCase() ] || name; requestHeaders[ name ] = value; } return this; }, // Overrides response content-type header overrideMimeType: function( type ) { if ( completed == null ) { s.mimeType = type; } return this; }, // Status-dependent callbacks statusCode: function( map ) { var code; if ( map ) { if ( completed ) { // Execute the appropriate callbacks jqXHR.always( map[ jqXHR.status ] ); } else { // Lazy-add the new callbacks in a way that preserves old ones for ( code in map ) { statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; } } } return this; }, // Cancel the request abort: function( statusText ) { var finalText = statusText || strAbort; if ( transport ) { transport.abort( finalText ); } done( 0, finalText ); return this; } }; // Attach deferreds deferred.promise( jqXHR ); // Add protocol if not provided (prefilters might expect it) // Handle falsy url in the settings object (#10093: consistency with old signature) // We also use the url parameter if available s.url = ( ( url || s.url || location.href ) + "" ) .replace( rprotocol, location.protocol + "//" ); // Alias method option to type as per ticket #12004 s.type = options.method || options.type || s.method || s.type; // Extract dataTypes list s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; // A cross-domain request is in order when the origin doesn't match the current origin. if ( s.crossDomain == null ) { urlAnchor = document.createElement( "a" ); // Support: IE <=8 - 11, Edge 12 - 13 // IE throws exception on accessing the href property if url is malformed, // e.g. http://example.com:80x/ try { urlAnchor.href = s.url; // Support: IE <=8 - 11 only // Anchor's host property isn't correctly set when s.url is relative urlAnchor.href = urlAnchor.href; s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== urlAnchor.protocol + "//" + urlAnchor.host; } catch ( e ) { // If there is an error parsing the URL, assume it is crossDomain, // it can be rejected by the transport if it is invalid s.crossDomain = true; } } // Convert data if not already a string if ( s.data && s.processData && typeof s.data !== "string" ) { s.data = jQuery.param( s.data, s.traditional ); } // Apply prefilters inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); // If request was aborted inside a prefilter, stop there if ( completed ) { return jqXHR; } // We can fire global events as of now if asked to // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) fireGlobals = jQuery.event && s.global; // Watch for a new set of requests if ( fireGlobals && jQuery.active++ === 0 ) { jQuery.event.trigger( "ajaxStart" ); } // Uppercase the type s.type = s.type.toUpperCase(); // Determine if request has content s.hasContent = !rnoContent.test( s.type ); // Save the URL in case we're toying with the If-Modified-Since // and/or If-None-Match header later on // Remove hash to simplify url manipulation cacheURL = s.url.replace( rhash, "" ); // More options handling for requests with no content if ( !s.hasContent ) { // Remember the hash so we can put it back uncached = s.url.slice( cacheURL.length ); // If data is available, append data to url if ( s.data ) { cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; // #9682: remove data so that it's not used in an eventual retry delete s.data; } // Add or update anti-cache param if needed if ( s.cache === false ) { cacheURL = cacheURL.replace( rantiCache, "$1" ); uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached; } // Put hash and anti-cache on the URL that will be requested (gh-1732) s.url = cacheURL + uncached; // Change '%20' to '+' if this is encoded form body content (gh-2658) } else if ( s.data && s.processData && ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { s.data = s.data.replace( r20, "+" ); } // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if ( s.ifModified ) { if ( jQuery.lastModified[ cacheURL ] ) { jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); } if ( jQuery.etag[ cacheURL ] ) { jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); } } // Set the correct header, if data is being sent if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { jqXHR.setRequestHeader( "Content-Type", s.contentType ); } // Set the Accepts header for the server, depending on the dataType jqXHR.setRequestHeader( "Accept", s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? s.accepts[ s.dataTypes[ 0 ] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : s.accepts[ "*" ] ); // Check for headers option for ( i in s.headers ) { jqXHR.setRequestHeader( i, s.headers[ i ] ); } // Allow custom headers/mimetypes and early abort if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { // Abort if not done already and return return jqXHR.abort(); } // Aborting is no longer a cancellation strAbort = "abort"; // Install callbacks on deferreds completeDeferred.add( s.complete ); jqXHR.done( s.success ); jqXHR.fail( s.error ); // Get transport transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); // If no transport, we auto-abort if ( !transport ) { done( -1, "No Transport" ); } else { jqXHR.readyState = 1; // Send global event if ( fireGlobals ) { globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); } // If request was aborted inside ajaxSend, stop there if ( completed ) { return jqXHR; } // Timeout if ( s.async && s.timeout > 0 ) { timeoutTimer = window.setTimeout( function() { jqXHR.abort( "timeout" ); }, s.timeout ); } try { completed = false; transport.send( requestHeaders, done ); } catch ( e ) { // Rethrow post-completion exceptions if ( completed ) { throw e; } // Propagate others as results done( -1, e ); } } // Callback for when everything is done function done( status, nativeStatusText, responses, headers ) { var isSuccess, success, error, response, modified, statusText = nativeStatusText; // Ignore repeat invocations if ( completed ) { return; } completed = true; // Clear timeout if it exists if ( timeoutTimer ) { window.clearTimeout( timeoutTimer ); } // Dereference transport for early garbage collection // (no matter how long the jqXHR object will be used) transport = undefined; // Cache response headers responseHeadersString = headers || ""; // Set readyState jqXHR.readyState = status > 0 ? 4 : 0; // Determine if successful isSuccess = status >= 200 && status < 300 || status === 304; // Get response data if ( responses ) { response = ajaxHandleResponses( s, jqXHR, responses ); } // Convert no matter what (that way responseXXX fields are always set) response = ajaxConvert( s, response, jqXHR, isSuccess ); // If successful, handle type chaining if ( isSuccess ) { // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if ( s.ifModified ) { modified = jqXHR.getResponseHeader( "Last-Modified" ); if ( modified ) { jQuery.lastModified[ cacheURL ] = modified; } modified = jqXHR.getResponseHeader( "etag" ); if ( modified ) { jQuery.etag[ cacheURL ] = modified; } } // if no content if ( status === 204 || s.type === "HEAD" ) { statusText = "nocontent"; // if not modified } else if ( status === 304 ) { statusText = "notmodified"; // If we have data, let's convert it } else { statusText = response.state; success = response.data; error = response.error; isSuccess = !error; } } else { // Extract error from statusText and normalize for non-aborts error = statusText; if ( status || !statusText ) { statusText = "error"; if ( status < 0 ) { status = 0; } } } // Set data for the fake xhr object jqXHR.status = status; jqXHR.statusText = ( nativeStatusText || statusText ) + ""; // Success/Error if ( isSuccess ) { deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); } else { deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); } // Status-dependent callbacks jqXHR.statusCode( statusCode ); statusCode = undefined; if ( fireGlobals ) { globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", [ jqXHR, s, isSuccess ? success : error ] ); } // Complete completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); if ( fireGlobals ) { globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); // Handle the global AJAX counter if ( !( --jQuery.active ) ) { jQuery.event.trigger( "ajaxStop" ); } } } return jqXHR; }, getJSON: function( url, data, callback ) { return jQuery.get( url, data, callback, "json" ); }, getScript: function( url, callback ) { return jQuery.get( url, undefined, callback, "script" ); } } ); jQuery.each( [ "get", "post" ], function( i, method ) { jQuery[ method ] = function( url, data, callback, type ) { // Shift arguments if data argument was omitted if ( jQuery.isFunction( data ) ) { type = type || callback; callback = data; data = undefined; } // The url can be an options object (which then must have .url) return jQuery.ajax( jQuery.extend( { url: url, type: method, dataType: type, data: data, success: callback }, jQuery.isPlainObject( url ) && url ) ); }; } ); jQuery._evalUrl = function( url ) { return jQuery.ajax( { url: url, // Make this explicit, since user can override this through ajaxSetup (#11264) type: "GET", dataType: "script", cache: true, async: false, global: false, "throws": true } ); }; jQuery.fn.extend( { wrapAll: function( html ) { var wrap; if ( this[ 0 ] ) { if ( jQuery.isFunction( html ) ) { html = html.call( this[ 0 ] ); } // The elements to wrap the target around wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); if ( this[ 0 ].parentNode ) { wrap.insertBefore( this[ 0 ] ); } wrap.map( function() { var elem = this; while ( elem.firstElementChild ) { elem = elem.firstElementChild; } return elem; } ).append( this ); } return this; }, wrapInner: function( html ) { if ( jQuery.isFunction( html ) ) { return this.each( function( i ) { jQuery( this ).wrapInner( html.call( this, i ) ); } ); } return this.each( function() { var self = jQuery( this ), contents = self.contents(); if ( contents.length ) { contents.wrapAll( html ); } else { self.append( html ); } } ); }, wrap: function( html ) { var isFunction = jQuery.isFunction( html ); return this.each( function( i ) { jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html ); } ); }, unwrap: function( selector ) { this.parent( selector ).not( "body" ).each( function() { jQuery( this ).replaceWith( this.childNodes ); } ); return this; } } ); jQuery.expr.pseudos.hidden = function( elem ) { return !jQuery.expr.pseudos.visible( elem ); }; jQuery.expr.pseudos.visible = function( elem ) { return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); }; jQuery.ajaxSettings.xhr = function() { try { return new window.XMLHttpRequest(); } catch ( e ) {} }; var xhrSuccessStatus = { // File protocol always yields status code 0, assume 200 0: 200, // Support: IE <=9 only // #1450: sometimes IE returns 1223 when it should be 204 1223: 204 }, xhrSupported = jQuery.ajaxSettings.xhr(); support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); support.ajax = xhrSupported = !!xhrSupported; jQuery.ajaxTransport( function( options ) { var callback, errorCallback; // Cross domain only allowed if supported through XMLHttpRequest if ( support.cors || xhrSupported && !options.crossDomain ) { return { send: function( headers, complete ) { var i, xhr = options.xhr(); xhr.open( options.type, options.url, options.async, options.username, options.password ); // Apply custom fields if provided if ( options.xhrFields ) { for ( i in options.xhrFields ) { xhr[ i ] = options.xhrFields[ i ]; } } // Override mime type if needed if ( options.mimeType && xhr.overrideMimeType ) { xhr.overrideMimeType( options.mimeType ); } // X-Requested-With header // For cross-domain requests, seeing as conditions for a preflight are // akin to a jigsaw puzzle, we simply never set it to be sure. // (it can always be set on a per-request basis or even using ajaxSetup) // For same-domain requests, won't change header if already provided. if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { headers[ "X-Requested-With" ] = "XMLHttpRequest"; } // Set headers for ( i in headers ) { xhr.setRequestHeader( i, headers[ i ] ); } // Callback callback = function( type ) { return function() { if ( callback ) { callback = errorCallback = xhr.onload = xhr.onerror = xhr.onabort = xhr.onreadystatechange = null; if ( type === "abort" ) { xhr.abort(); } else if ( type === "error" ) { // Support: IE <=9 only // On a manual native abort, IE9 throws // errors on any property access that is not readyState if ( typeof xhr.status !== "number" ) { complete( 0, "error" ); } else { complete( // File: protocol always yields status 0; see #8605, #14207 xhr.status, xhr.statusText ); } } else { complete( xhrSuccessStatus[ xhr.status ] || xhr.status, xhr.statusText, // Support: IE <=9 only // IE9 has no XHR2 but throws on binary (trac-11426) // For XHR2 non-text, let the caller handle it (gh-2498) ( xhr.responseType || "text" ) !== "text" || typeof xhr.responseText !== "string" ? { binary: xhr.response } : { text: xhr.responseText }, xhr.getAllResponseHeaders() ); } } }; }; // Listen to events xhr.onload = callback(); errorCallback = xhr.onerror = callback( "error" ); // Support: IE 9 only // Use onreadystatechange to replace onabort // to handle uncaught aborts if ( xhr.onabort !== undefined ) { xhr.onabort = errorCallback; } else { xhr.onreadystatechange = function() { // Check readyState before timeout as it changes if ( xhr.readyState === 4 ) { // Allow onerror to be called first, // but that will not handle a native abort // Also, save errorCallback to a variable // as xhr.onerror cannot be accessed window.setTimeout( function() { if ( callback ) { errorCallback(); } } ); } }; } // Create the abort callback callback = callback( "abort" ); try { // Do send the request (this may raise an exception) xhr.send( options.hasContent && options.data || null ); } catch ( e ) { // #14683: Only rethrow if this hasn't been notified as an error yet if ( callback ) { throw e; } } }, abort: function() { if ( callback ) { callback(); } } }; } } ); // Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) jQuery.ajaxPrefilter( function( s ) { if ( s.crossDomain ) { s.contents.script = false; } } ); // Install script dataType jQuery.ajaxSetup( { accepts: { script: "text/javascript, application/javascript, " + "application/ecmascript, application/x-ecmascript" }, contents: { script: /\b(?:java|ecma)script\b/ }, converters: { "text script": function( text ) { jQuery.globalEval( text ); return text; } } } ); // Handle cache's special case and crossDomain jQuery.ajaxPrefilter( "script", function( s ) { if ( s.cache === undefined ) { s.cache = false; } if ( s.crossDomain ) { s.type = "GET"; } } ); // Bind script tag hack transport jQuery.ajaxTransport( "script", function( s ) { // This transport only deals with cross domain requests if ( s.crossDomain ) { var script, callback; return { send: function( _, complete ) { script = jQuery( " with w.tag('body'): if 'js' in self.html: with w.xml_cleaning_method('none'): with w.tag('script'): w.data(self.html['js']) if isinstance(self.html['table_id'], str): html_table_id = self.html['table_id'] else: html_table_id = None if 'table_class' in self.html: html_table_class = self.html['table_class'] attrib = {"class": html_table_class} else: attrib = {} with w.tag('table', id=html_table_id, attrib=attrib): with w.tag('thead'): with w.tag('tr'): for col in cols: if len(col.shape) > 1 and self.html['multicol']: # Set colspan attribute for multicolumns w.start('th', colspan=col.shape[1]) else: w.start('th') w.data(col.info.name.strip()) w.end(indent=False) col_str_iters = [] new_cols_escaped = [] # Make a container to hold any new_col objects created # below for multicolumn elements. This is purely to # maintain a reference for these objects during # subsequent iteration to format column values. This # requires that the weakref info._parent be maintained. new_cols = [] for col, col_escaped in zip(cols, cols_escaped): if len(col.shape) > 1 and self.html['multicol']: span = col.shape[1] for i in range(span): # Split up multicolumns into separate columns new_col = Column([el[i] for el in col]) new_col_iter_str_vals = self.fill_values( col, new_col.info.iter_str_vals()) col_str_iters.append(new_col_iter_str_vals) new_cols_escaped.append(col_escaped) new_cols.append(new_col) else: col_iter_str_vals = self.fill_values(col, col.info.iter_str_vals()) col_str_iters.append(col_iter_str_vals) new_cols_escaped.append(col_escaped) for row in zip(*col_str_iters): with w.tag('tr'): for el, col_escaped in zip(row, new_cols_escaped): # Potentially disable HTML escaping for column method = ('escape_xml' if col_escaped else 'bleach_clean') with w.xml_cleaning_method(method, **raw_html_clean_kwargs): w.start('td') w.data(el.strip()) w.end(indent=False) # Fixes XMLWriter's insertion of unwanted line breaks return [''.join(lines)] def fill_values(self, col, col_str_iters): """ Return an iterator of the values with replacements based on fill_values """ # check if the col is a masked column and has fill values is_masked_column = hasattr(col, 'mask') has_fill_values = hasattr(col, 'fill_values') for idx, col_str in enumerate(col_str_iters): if is_masked_column and has_fill_values: if col.mask[idx]: yield col.fill_values[core.masked] continue if has_fill_values: if col_str in col.fill_values: yield col.fill_values[col_str] continue yield col_str ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/ipac.py0000644000175100001710000005115500000000000016742 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """An extensible ASCII table reader and writer. ipac.py: Classes to read IPAC table format :Copyright: Smithsonian Astrophysical Observatory (2011) :Author: Tom Aldcroft (aldcroft@head.cfa.harvard.edu) """ import re from collections import defaultdict, OrderedDict from textwrap import wrap from warnings import warn from . import core from . import fixedwidth from . import basic from astropy.utils.exceptions import AstropyUserWarning from astropy.table.pprint import get_auto_format_func class IpacFormatErrorDBMS(Exception): def __str__(self): return '{}\nSee {}'.format( super().__str__(), 'https://irsa.ipac.caltech.edu/applications/DDGEN/Doc/DBMSrestriction.html') class IpacFormatError(Exception): def __str__(self): return '{}\nSee {}'.format( super().__str__(), 'https://irsa.ipac.caltech.edu/applications/DDGEN/Doc/ipac_tbl.html') class IpacHeaderSplitter(core.BaseSplitter): '''Splitter for Ipac Headers. This splitter is similar its parent when reading, but supports a fixed width format (as required for Ipac table headers) for writing. ''' process_line = None process_val = None delimiter = '|' delimiter_pad = '' skipinitialspace = False comment = r'\s*\\' write_comment = r'\\' col_starts = None col_ends = None def join(self, vals, widths): pad = self.delimiter_pad or '' delimiter = self.delimiter or '' padded_delim = pad + delimiter + pad bookend_left = delimiter + pad bookend_right = pad + delimiter vals = [' ' * (width - len(val)) + val for val, width in zip(vals, widths)] return bookend_left + padded_delim.join(vals) + bookend_right class IpacHeader(fixedwidth.FixedWidthHeader): """IPAC table header""" splitter_class = IpacHeaderSplitter # Defined ordered list of possible types. Ordering is needed to # distinguish between "d" (double) and "da" (date) as defined by # the IPAC standard for abbreviations. This gets used in get_col_type(). col_type_list = (('integer', core.IntType), ('long', core.IntType), ('double', core.FloatType), ('float', core.FloatType), ('real', core.FloatType), ('char', core.StrType), ('date', core.StrType)) definition = 'ignore' start_line = None def process_lines(self, lines): """Generator to yield IPAC header lines, i.e. those starting and ending with delimiter character (with trailing whitespace stripped)""" delim = self.splitter.delimiter for line in lines: line = line.rstrip() if line.startswith(delim) and line.endswith(delim): yield line.strip(delim) def update_meta(self, lines, meta): """ Extract table-level comments and keywords for IPAC table. See: https://irsa.ipac.caltech.edu/applications/DDGEN/Doc/ipac_tbl.html#kw """ def process_keyword_value(val): """ Take a string value and convert to float, int or str, and strip quotes as needed. """ val = val.strip() try: val = int(val) except Exception: try: val = float(val) except Exception: # Strip leading/trailing quote. The spec says that a matched pair # of quotes is required, but this code will allow a non-quoted value. for quote in ('"', "'"): if val.startswith(quote) and val.endswith(quote): val = val[1:-1] break return val table_meta = meta['table'] table_meta['comments'] = [] table_meta['keywords'] = OrderedDict() keywords = table_meta['keywords'] re_keyword = re.compile(r'\\' r'(?P \w+)' r'\s* = (?P .+) $', re.VERBOSE) for line in lines: # Keywords and comments start with "\". Once the first non-slash # line is seen then bail out. if not line.startswith('\\'): break m = re_keyword.match(line) if m: name = m.group('name') val = process_keyword_value(m.group('value')) # IPAC allows for continuation keywords, e.g. # \SQL = 'WHERE ' # \SQL = 'SELECT (25 column names follow in next row.)' if name in keywords and isinstance(val, str): prev_val = keywords[name]['value'] if isinstance(prev_val, str): val = prev_val + val keywords[name] = {'value': val} else: # Comment is required to start with "\ " if line.startswith('\\ '): val = line[2:].strip() if val: table_meta['comments'].append(val) def get_col_type(self, col): for (col_type_key, col_type) in self.col_type_list: if col_type_key.startswith(col.raw_type.lower()): return col_type else: raise ValueError('Unknown data type ""{}"" for column "{}"'.format( col.raw_type, col.name)) def get_cols(self, lines): """ Initialize the header Column objects from the table ``lines``. Based on the previously set Header attributes find or create the column names. Sets ``self.cols`` with the list of Columns. Parameters ---------- lines : list List of table lines """ header_lines = self.process_lines(lines) # generator returning valid header lines header_vals = [vals for vals in self.splitter(header_lines)] if len(header_vals) == 0: raise ValueError('At least one header line beginning and ending with ' 'delimiter required') elif len(header_vals) > 4: raise ValueError('More than four header lines were found') # Generate column definitions cols = [] start = 1 for i, name in enumerate(header_vals[0]): col = core.Column(name=name.strip(' -')) col.start = start col.end = start + len(name) if len(header_vals) > 1: col.raw_type = header_vals[1][i].strip(' -') col.type = self.get_col_type(col) if len(header_vals) > 2: col.unit = header_vals[2][i].strip() or None # Can't strip dashes here if len(header_vals) > 3: # The IPAC null value corresponds to the io.ascii bad_value. # In this case there isn't a fill_value defined, so just put # in the minimal entry that is sure to convert properly to the # required type. # # Strip spaces but not dashes (not allowed in NULL row per # https://github.com/astropy/astropy/issues/361) null = header_vals[3][i].strip() fillval = '' if issubclass(col.type, core.StrType) else '0' self.data.fill_values.append((null, fillval, col.name)) start = col.end + 1 cols.append(col) # Correct column start/end based on definition if self.ipac_definition == 'right': col.start -= 1 elif self.ipac_definition == 'left': col.end += 1 self.names = [x.name for x in cols] self.cols = cols def str_vals(self): if self.DBMS: IpacFormatE = IpacFormatErrorDBMS else: IpacFormatE = IpacFormatError namelist = self.colnames if self.DBMS: countnamelist = defaultdict(int) for name in self.colnames: countnamelist[name.lower()] += 1 doublenames = [x for x in countnamelist if countnamelist[x] > 1] if doublenames != []: raise IpacFormatE('IPAC DBMS tables are not case sensitive. ' 'This causes duplicate column names: {}'.format(doublenames)) for name in namelist: m = re.match(r'\w+', name) if m.end() != len(name): raise IpacFormatE('{} - Only alphanumeric characters and _ ' 'are allowed in column names.'.format(name)) if self.DBMS and not(name[0].isalpha() or (name[0] == '_')): raise IpacFormatE(f'Column name cannot start with numbers: {name}') if self.DBMS: if name in ['x', 'y', 'z', 'X', 'Y', 'Z']: raise IpacFormatE('{} - x, y, z, X, Y, Z are reserved names and ' 'cannot be used as column names.'.format(name)) if len(name) > 16: raise IpacFormatE( f'{name} - Maximum length for column name is 16 characters') else: if len(name) > 40: raise IpacFormatE( f'{name} - Maximum length for column name is 40 characters.') dtypelist = [] unitlist = [] nullist = [] for col in self.cols: col_dtype = col.info.dtype col_unit = col.info.unit col_format = col.info.format if col_dtype.kind in ['i', 'u']: if col_dtype.itemsize <= 2: dtypelist.append('int') else: dtypelist.append('long') elif col_dtype.kind == 'f': if col_dtype.itemsize <= 4: dtypelist.append('float') else: dtypelist.append('double') else: dtypelist.append('char') if col_unit is None: unitlist.append('') else: unitlist.append(str(col.info.unit)) # This may be incompatible with mixin columns null = col.fill_values[core.masked] try: auto_format_func = get_auto_format_func(col) format_func = col.info._format_funcs.get(col_format, auto_format_func) nullist.append((format_func(col_format, null)).strip()) except Exception: # It is possible that null and the column values have different # data types (e.g. number and null = 'null' (i.e. a string). # This could cause all kinds of exceptions, so a catch all # block is needed here nullist.append(str(null).strip()) return [namelist, dtypelist, unitlist, nullist] def write(self, lines, widths): '''Write header. The width of each column is determined in Ipac.write. Writing the header must be delayed until that time. This function is called from there, once the width information is available.''' for vals in self.str_vals(): lines.append(self.splitter.join(vals, widths)) return lines class IpacDataSplitter(fixedwidth.FixedWidthSplitter): delimiter = ' ' delimiter_pad = '' bookend = True class IpacData(fixedwidth.FixedWidthData): """IPAC table data reader""" comment = r'[|\\]' start_line = 0 splitter_class = IpacDataSplitter fill_values = [(core.masked, 'null')] def write(self, lines, widths, vals_list): """ IPAC writer, modified from FixedWidth writer """ for vals in vals_list: lines.append(self.splitter.join(vals, widths)) return lines class Ipac(basic.Basic): r"""IPAC format table. See: https://irsa.ipac.caltech.edu/applications/DDGEN/Doc/ipac_tbl.html Example:: \\name=value \\ Comment | column1 | column2 | column3 | column4 | column5 | | double | double | int | double | char | | unit | unit | unit | unit | unit | | null | null | null | null | null | 2.0978 29.09056 73765 2.06000 B8IVpMnHg Or:: |-----ra---|----dec---|---sao---|------v---|----sptype--------| 2.09708 29.09056 73765 2.06000 B8IVpMnHg The comments and keywords defined in the header are available via the output table ``meta`` attribute:: >>> import os >>> from astropy.io import ascii >>> filename = os.path.join(ascii.__path__[0], 'tests/data/ipac.dat') >>> data = ascii.read(filename) >>> print(data.meta['comments']) ['This is an example of a valid comment'] >>> for name, keyword in data.meta['keywords'].items(): ... print(name, keyword['value']) ... intval 1 floatval 2300.0 date Wed Sp 20 09:48:36 1995 key_continue IPAC keywords can continue across lines Note that there are different conventions for characters occurring below the position of the ``|`` symbol in IPAC tables. By default, any character below a ``|`` will be ignored (since this is the current standard), but if you need to read files that assume characters below the ``|`` symbols belong to the column before or after the ``|``, you can specify ``definition='left'`` or ``definition='right'`` respectively when reading the table (the default is ``definition='ignore'``). The following examples demonstrate the different conventions: * ``definition='ignore'``:: | ra | dec | | float | float | 1.2345 6.7890 * ``definition='left'``:: | ra | dec | | float | float | 1.2345 6.7890 * ``definition='right'``:: | ra | dec | | float | float | 1.2345 6.7890 IPAC tables can specify a null value in the header that is shown in place of missing or bad data. On writing, this value defaults to ``null``. To specify a different null value, use the ``fill_values`` option to replace masked values with a string or number of your choice as described in :ref:`astropy:io_ascii_write_parameters`:: >>> from astropy.io.ascii import masked >>> fill = [(masked, 'N/A', 'ra'), (masked, -999, 'sptype')] >>> ascii.write(data, format='ipac', fill_values=fill) \ This is an example of a valid comment ... | ra| dec| sai| v2| sptype| | double| double| long| double| char| | unit| unit| unit| unit| ergs| | N/A| null| null| null| -999| N/A 29.09056 null 2.06 -999 2345678901.0 3456789012.0 456789012 4567890123.0 567890123456789012 When writing a table with a column of integers, the data type is output as ``int`` when the column ``dtype.itemsize`` is less than or equal to 2; otherwise the data type is ``long``. For a column of floating-point values, the data type is ``float`` when ``dtype.itemsize`` is less than or equal to 4; otherwise the data type is ``double``. Parameters ---------- definition : str, optional Specify the convention for characters in the data table that occur directly below the pipe (``|``) symbol in the header column definition: * 'ignore' - Any character beneath a pipe symbol is ignored (default) * 'right' - Character is associated with the column to the right * 'left' - Character is associated with the column to the left DBMS : bool, optional If true, this verifies that written tables adhere (semantically) to the `IPAC/DBMS `_ definition of IPAC tables. If 'False' it only checks for the (less strict) `IPAC `_ definition. """ _format_name = 'ipac' _io_registry_format_aliases = ['ipac'] _io_registry_can_write = True _description = 'IPAC format table' data_class = IpacData header_class = IpacHeader def __init__(self, definition='ignore', DBMS=False): super().__init__() # Usually the header is not defined in __init__, but here it need a keyword if definition in ['ignore', 'left', 'right']: self.header.ipac_definition = definition else: raise ValueError("definition should be one of ignore/left/right") self.header.DBMS = DBMS def write(self, table): """ Write ``table`` as list of strings. Parameters ---------- table : `~astropy.table.Table` Input table data Returns ------- lines : list List of strings corresponding to ASCII table """ # Set a default null value for all columns by adding at the end, which # is the position with the lowest priority. # We have to do it this late, because the fill_value # defined in the class can be overwritten by ui.write self.data.fill_values.append((core.masked, 'null')) # Check column names before altering self.header.cols = list(table.columns.values()) self.header.check_column_names(self.names, self.strict_names, self.guessing) core._apply_include_exclude_names(table, self.names, self.include_names, self.exclude_names) # Check that table has only 1-d columns. self._check_multidim_table(table) # Now use altered columns new_cols = list(table.columns.values()) # link information about the columns to the writer object (i.e. self) self.header.cols = new_cols self.data.cols = new_cols # Write header and data to lines list lines = [] # Write meta information if 'comments' in table.meta: for comment in table.meta['comments']: if len(str(comment)) > 78: warn('Comment string > 78 characters was automatically wrapped.', AstropyUserWarning) for line in wrap(str(comment), 80, initial_indent='\\ ', subsequent_indent='\\ '): lines.append(line) if 'keywords' in table.meta: keydict = table.meta['keywords'] for keyword in keydict: try: val = keydict[keyword]['value'] lines.append(f'\\{keyword.strip()}={val!r}') # meta is not standardized: Catch some common Errors. except TypeError: warn("Table metadata keyword {0} has been skipped. " "IPAC metadata must be in the form {{'keywords':" "{{'keyword': {{'value': value}} }}".format(keyword), AstropyUserWarning) ignored_keys = [key for key in table.meta if key not in ('keywords', 'comments')] if any(ignored_keys): warn("Table metadata keyword(s) {0} were not written. " "IPAC metadata must be in the form {{'keywords':" "{{'keyword': {{'value': value}} }}".format(ignored_keys), AstropyUserWarning ) # Usually, this is done in data.write, but since the header is written # first, we need that here. self.data._set_fill_values(self.data.cols) # get header and data as strings to find width of each column for i, col in enumerate(table.columns.values()): col.headwidth = max([len(vals[i]) for vals in self.header.str_vals()]) # keep data_str_vals because they take some time to make data_str_vals = [] col_str_iters = self.data.str_vals() for vals in zip(*col_str_iters): data_str_vals.append(vals) for i, col in enumerate(table.columns.values()): # FIXME: In Python 3.4, use max([], default=0). # See: https://docs.python.org/3/library/functions.html#max if data_str_vals: col.width = max([len(vals[i]) for vals in data_str_vals]) else: col.width = 0 widths = [max(col.width, col.headwidth) for col in table.columns.values()] # then write table self.header.write(lines, widths) self.data.write(lines, widths, data_str_vals) return lines ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/latex.py0000644000175100001710000004103300000000000017135 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """An extensible ASCII table reader and writer. latex.py: Classes to read and write LaTeX tables :Copyright: Smithsonian Astrophysical Observatory (2011) :Author: Tom Aldcroft (aldcroft@head.cfa.harvard.edu) """ import re from . import core latexdicts = {'AA': {'tabletype': 'table', 'header_start': r'\hline \hline', 'header_end': r'\hline', 'data_end': r'\hline'}, 'doublelines': {'tabletype': 'table', 'header_start': r'\hline \hline', 'header_end': r'\hline\hline', 'data_end': r'\hline\hline'}, 'template': {'tabletype': 'tabletype', 'caption': 'caption', 'tablealign': 'tablealign', 'col_align': 'col_align', 'preamble': 'preamble', 'header_start': 'header_start', 'header_end': 'header_end', 'data_start': 'data_start', 'data_end': 'data_end', 'tablefoot': 'tablefoot', 'units': {'col1': 'unit of col1', 'col2': 'unit of col2'}} } RE_COMMENT = re.compile(r'(?`_ some header keywords differ from standard LaTeX. This header is modified to take that into account. ''' header_start = r'\tablehead' splitter_class = AASTexHeaderSplitter def start_line(self, lines): return find_latex_line(lines, r'\tablehead') def write(self, lines): if 'col_align' not in self.latex: self.latex['col_align'] = len(self.cols) * 'c' if 'tablealign' in self.latex: align = '[' + self.latex['tablealign'] + ']' else: align = '' lines.append(r'\begin{' + self.latex['tabletype'] + r'}{' + self.latex['col_align'] + r'}' + align) add_dictval_to_list(self.latex, 'preamble', lines) if 'caption' in self.latex: lines.append(r'\tablecaption{' + self.latex['caption'] + '}') tablehead = ' & '.join([r'\colhead{' + name + '}' for name in self.colnames]) units = self._get_units() if 'units' in self.latex: units.update(self.latex['units']) if units: tablehead += r'\\ ' + self.splitter.join([units.get(name, ' ') for name in self.colnames]) lines.append(r'\tablehead{' + tablehead + '}') class AASTexData(LatexData): r'''In a `deluxetable`_ the data is enclosed in `\startdata` and `\enddata` ''' data_start = r'\startdata' data_end = r'\enddata' def start_line(self, lines): return find_latex_line(lines, self.data_start) + 1 def write(self, lines): lines.append(self.data_start) lines_length_initial = len(lines) core.BaseData.write(self, lines) # To remove extra space(s) and // appended which creates an extra new line # in the end. if len(lines) > lines_length_initial: # we compile separately because py2.6 doesn't have a flags keyword in re.sub re_final_line = re.compile(r'\s* \\ \\ \s* $', flags=re.VERBOSE) lines[-1] = re.sub(re_final_line, '', lines[-1]) lines.append(self.data_end) add_dictval_to_list(self.latex, 'tablefoot', lines) lines.append(r'\end{' + self.latex['tabletype'] + r'}') class AASTex(Latex): '''AASTeX format table. This class implements some AASTeX specific commands. AASTeX is used for the AAS (American Astronomical Society) publications like ApJ, ApJL and AJ. It derives from the ``Latex`` reader and accepts the same keywords. However, the keywords ``header_start``, ``header_end``, ``data_start`` and ``data_end`` in ``latexdict`` have no effect. ''' _format_name = 'aastex' _io_registry_format_aliases = ['aastex'] _io_registry_suffix = '' # AASTex inherits from Latex, so override this class attr _description = 'AASTeX deluxetable used for AAS journals' header_class = AASTexHeader data_class = AASTexData def __init__(self, **kwargs): super().__init__(**kwargs) # check if tabletype was explicitly set by the user if not (('latexdict' in kwargs) and ('tabletype' in kwargs['latexdict'])): self.latex['tabletype'] = 'deluxetable' ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/misc.py0000644000175100001710000001004700000000000016754 0ustar00vstsdocker"""A Collection of useful miscellaneous functions. misc.py: Collection of useful miscellaneous functions. :Author: Hannes Breytenbach (hannes@saao.ac.za) """ import collections.abc import itertools import operator def first_true_index(iterable, pred=None, default=None): """find the first index position for the which the callable pred returns True""" if pred is None: func = operator.itemgetter(1) else: func = lambda x: pred(x[1]) ii = next(filter(func, enumerate(iterable)), default) # either index-item pair or default return ii[0] if ii else default def first_false_index(iterable, pred=None, default=None): """find the first index position for the which the callable pred returns False""" if pred is None: func = operator.not_ else: func = lambda x: not pred(x) return first_true_index(iterable, func, default) def sortmore(*args, **kw): """ Sorts any number of lists according to: optionally given item sorting key function(s) and/or a global sorting key function. Parameters ---------- One or more lists Keywords -------- globalkey : None revert to sorting by key function globalkey : callable Sort by evaluated value for all items in the lists (call signature of this function needs to be such that it accepts an argument tuple of items from each list. eg.: ``globalkey = lambda *l: sum(l)`` will order all the lists by the sum of the items from each list if key: None sorting done by value of first input list (in this case the objects in the first iterable need the comparison methods __lt__ etc...) if key: callable sorting done by value of key(item) for items in first iterable if key: tuple sorting done by value of (key(item_0), ..., key(item_n)) for items in the first n iterables (where n is the length of the key tuple) i.e. the first callable is the primary sorting criterion, and the rest act as tie-breakers. Returns ------- Sorted lists Examples -------- Capture sorting indices:: l = list('CharacterS') In [1]: sortmore( l, range(len(l)) ) Out[1]: (['C', 'S', 'a', 'a', 'c', 'e', 'h', 'r', 'r', 't'], [0, 9, 2, 4, 5, 7, 1, 3, 8, 6]) In [2]: sortmore( l, range(len(l)), key=str.lower ) Out[2]: (['a', 'a', 'C', 'c', 'e', 'h', 'r', 'r', 'S', 't'], [2, 4, 0, 5, 7, 1, 3, 8, 9, 6]) """ first = list(args[0]) if not len(first): return args globalkey = kw.get('globalkey') key = kw.get('key') if key is None: if globalkey: # if global sort function given and no local (secondary) key given, ==> no tiebreakers key = lambda x: 0 else: key = lambda x: x # if no global sort and no local sort keys given, sort by item values if globalkey is None: globalkey = lambda *x: 0 if not isinstance(globalkey, collections.abc.Callable): raise ValueError('globalkey needs to be callable') if isinstance(key, collections.abc.Callable): k = lambda x: (globalkey(*x), key(x[0])) elif isinstance(key, tuple): key = (k if k else lambda x: 0 for k in key) k = lambda x: (globalkey(*x),) + tuple(f(z) for (f, z) in zip(key, x)) else: raise KeyError( "kw arg 'key' should be None, callable, or a sequence of callables, not {}" .format(type(key))) res = sorted(list(zip(*args)), key=k) if 'order' in kw: if kw['order'].startswith(('descend', 'reverse')): res = reversed(res) return tuple(map(list, zip(*res))) def groupmore(func=None, *its): """Extends the itertools.groupby functionality to arbitrary number of iterators.""" if not func: func = lambda x: x its = sortmore(*its, key=func) nfunc = lambda x: func(x[0]) zipper = itertools.groupby(zip(*its), nfunc) unzipper = ((key, zip(*groups)) for key, groups in zipper) return unzipper ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/mrt.py0000644000175100001710000006653600000000000016641 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """Classes to read AAS MRT table format Ref: https://journals.aas.org/mrt-standards :Copyright: Smithsonian Astrophysical Observatory (2021) :Author: Tom Aldcroft (aldcroft@head.cfa.harvard.edu), \ Suyog Garg (suyog7130@gmail.com) """ import re import math import warnings import numpy as np from io import StringIO from . import core from . import fixedwidth, cds from astropy import units as u from astropy.table import Table from astropy.table import Column, MaskedColumn from string import Template from textwrap import wrap MAX_SIZE_README_LINE = 80 MAX_COL_INTLIMIT = 100000 __doctest_skip__ = ['*'] BYTE_BY_BYTE_TEMPLATE = [ "Byte-by-byte Description of file: $file", "--------------------------------------------------------------------------------", " Bytes Format Units Label Explanations", "--------------------------------------------------------------------------------", "$bytebybyte", "--------------------------------------------------------------------------------"] MRT_TEMPLATE = [ "Title:", "Authors:", "Table:", "================================================================================", "$bytebybyte", "Notes:", "--------------------------------------------------------------------------------"] class MrtSplitter(fixedwidth.FixedWidthSplitter): """ Contains the join function to left align the MRT columns when writing to a file. """ def join(self, vals, widths): vals = [val + ' ' * (width - len(val)) for val, width in zip(vals, widths)] return self.delimiter.join(vals) class MrtHeader(cds.CdsHeader): _subfmt = 'MRT' def _split_float_format(self, value): """ Splits a Float string into different parts to find number of digits after decimal and check if the value is in Scientific notation. Parameters ---------- value : str String containing the float value to split. Returns ------- fmt: (int, int, int, bool, bool) List of values describing the Float sting. (size, dec, ent, sign, exp) size, length of the given string. ent, number of digits before decimal point. dec, number of digits after decimal point. sign, whether or not given value signed. exp, is value in Scientific notation? """ regfloat = re.compile(r"""(?P [+-]*) (?P [^eE.]+) (?P [.]*) (?P [0-9]*) (?P [eE]*-*)[0-9]*""", re.VERBOSE) mo = regfloat.match(value) if mo is None: raise Exception(f'{value} is not a float number') return (len(value), len(mo.group('ent')), len(mo.group('decimals')), mo.group('sign') != "", mo.group('exp') != "") def _set_column_val_limits(self, col): """ Sets the ``col.min`` and ``col.max`` column attributes, taking into account columns with Null values. """ col.max = max(col) col.min = min(col) if col.max is np.ma.core.MaskedConstant: col.max = None if col.min is np.ma.core.MaskedConstant: col.min = None def column_float_formatter(self, col): """ String formatter function for a column containing Float values. Checks if the values in the given column are in Scientific notation, by spliting the value string. It is assumed that the column either has float values or Scientific notation. A ``col.formatted_width`` attribute is added to the column. It is not added if such an attribute is already present, say when the ``formats`` argument is passed to the writer. A properly formatted format string is also added as the ``col.format`` attribute. Parameters ---------- col : A ``Table.Column`` object. """ # maxsize: maximum length of string containing the float value. # maxent: maximum number of digits places before decimal point. # maxdec: maximum number of digits places after decimal point. # maxprec: maximum precision of the column values, sum of maxent and maxdec. maxsize, maxprec, maxent, maxdec = 1, 0, 1, 0 sign = False fformat = 'F' # Find maximum sized value in the col for val in col.str_vals: # Skip null values if val is None or val == '': continue # Find format of the Float string fmt = self._split_float_format(val) # If value is in Scientific notation if fmt[4] is True: # if the previous column value was in normal Float format # set maxsize, maxprec and maxdec to default. if fformat == 'F': maxsize, maxprec, maxdec = 1, 0, 0 # Designate the column to be in Scientific notation. fformat = 'E' else: # Move to next column value if # current value is not in Scientific notation # but the column is designated as such because # one of the previous values was. if fformat == 'E': continue if maxsize < fmt[0]: maxsize = fmt[0] if maxent < fmt[1]: maxent = fmt[1] if maxdec < fmt[2]: maxdec = fmt[2] if fmt[3]: sign = True if maxprec < fmt[1] + fmt[2]: maxprec = fmt[1] + fmt[2] if fformat == 'E': if getattr(col, 'formatted_width', None) is None: # If ``formats`` not passed. col.formatted_width = maxsize if sign: col.formatted_width += 1 # Number of digits after decimal is replaced by the precision # for values in Scientific notation, when writing that Format. col.fortran_format = fformat + str(col.formatted_width) + "." + str(maxprec) col.format = str(col.formatted_width) + "." + str(maxdec) + "e" else: lead = '' if getattr(col, 'formatted_width', None) is None: # If ``formats`` not passed. col.formatted_width = maxent + maxdec + 1 if sign: col.formatted_width += 1 elif col.format.startswith('0'): # Keep leading zero, if already set in format - primarily for `seconds` columns # in coordinates; may need extra case if this is to be also supported with `sign`. lead = '0' col.fortran_format = fformat + str(col.formatted_width) + "." + str(maxdec) col.format = lead + col.fortran_format[1:] + "f" def write_byte_by_byte(self): """ Writes the Byte-By-Byte description of the table. Columns that are `astropy.coordinates.SkyCoord` or `astropy.time.TimeSeries` objects or columns with values that are such objects are recognized as such, and some predefined labels and description is used for them. See the Vizier MRT Standard documentation in the link below for more details on these. An example Byte-By-Byte table is shown here. See: http://vizier.u-strasbg.fr/doc/catstd-3.1.htx Example:: -------------------------------------------------------------------------------- Byte-by-byte Description of file: table.dat -------------------------------------------------------------------------------- Bytes Format Units Label Explanations -------------------------------------------------------------------------------- 1- 8 A8 --- names Description of names 10-14 E5.1 --- e [-3160000.0/0.01] Description of e 16-23 F8.5 --- d [22.25/27.25] Description of d 25-31 E7.1 --- s [-9e+34/2.0] Description of s 33-35 I3 --- i [-30/67] Description of i 37-39 F3.1 --- sameF [5.0/5.0] Description of sameF 41-42 I2 --- sameI [20] Description of sameI 44-45 I2 h RAh Right Ascension (hour) 47-48 I2 min RAm Right Ascension (minute) 50-67 F18.15 s RAs Right Ascension (second) 69 A1 --- DE- Sign of Declination 70-71 I2 deg DEd Declination (degree) 73-74 I2 arcmin DEm Declination (arcmin) 76-91 F16.13 arcsec DEs Declination (arcsec) -------------------------------------------------------------------------------- """ # Get column widths vals_list = [] col_str_iters = self.data.str_vals() for vals in zip(*col_str_iters): vals_list.append(vals) for i, col in enumerate(self.cols): col.width = max([len(vals[i]) for vals in vals_list]) if self.start_line is not None: col.width = max(col.width, len(col.info.name)) widths = [col.width for col in self.cols] startb = 1 # Byte count starts at 1. # Set default width of the Bytes count column of the Byte-By-Byte table. # This ``byte_count_width`` value helps align byte counts with respect # to the hyphen using a format string. byte_count_width = len(str(sum(widths) + len(self.cols) - 1)) # Format string for Start Byte and End Byte singlebfmt = "{:" + str(byte_count_width) + "d}" fmtb = singlebfmt + "-" + singlebfmt # Add trailing single whitespaces to Bytes column for better visibility. singlebfmt += " " fmtb += " " # Set default width of Label and Description Byte-By-Byte columns. max_label_width, max_descrip_size = 7, 16 bbb = Table(names=['Bytes', 'Format', 'Units', 'Label', 'Explanations'], dtype=[str] * 5) # Iterate over the columns to write Byte-By-Byte rows. for i, col in enumerate(self.cols): # Check if column is MaskedColumn col.has_null = isinstance(col, MaskedColumn) if col.format is not None: col.formatted_width = max([len(sval) for sval in col.str_vals]) # Set MRTColumn type, size and format. if np.issubdtype(col.dtype, np.integer): # Integer formatter self._set_column_val_limits(col) if getattr(col, 'formatted_width', None) is None: # If ``formats`` not passed. col.formatted_width = max(len(str(col.max)), len(str(col.min))) col.fortran_format = "I" + str(col.formatted_width) if col.format is None: col.format = ">" + col.fortran_format[1:] elif np.issubdtype(col.dtype, np.dtype(float).type): # Float formatter self._set_column_val_limits(col) self.column_float_formatter(col) else: # String formatter, ``np.issubdtype(col.dtype, str)`` is ``True``. dtype = col.dtype.str if col.has_null: mcol = col mcol.fill_value = "" coltmp = Column(mcol.filled(), dtype=str) dtype = coltmp.dtype.str if getattr(col, 'formatted_width', None) is None: # If ``formats`` not passed. col.formatted_width = int(re.search(r'(\d+)$', dtype).group(1)) col.fortran_format = "A" + str(col.formatted_width) col.format = str(col.formatted_width) + "s" endb = col.formatted_width + startb - 1 # ``mixin`` columns converted to string valued columns will not have a name # attribute. In those cases, a ``Unknown`` column label is put, indicating that # such columns can be better formatted with some manipulation before calling # the MRT writer. if col.name is None: col.name = "Unknown" # Set column description. if col.description is not None: description = col.description else: description = "Description of " + col.name # Set null flag in column description nullflag = "" if col.has_null: nullflag = "?" # Set column unit if col.unit is not None: col_unit = col.unit.to_string("cds") elif col.name.lower().find("magnitude") > -1: # ``col.unit`` can still be ``None``, if the unit of column values # is ``Magnitude``, because ``astropy.units.Magnitude`` is actually a class. # Unlike other units which are instances of ``astropy.units.Unit``, # application of the ``Magnitude`` unit calculates the logarithm # of the values. Thus, the only way to check for if the column values # have ``Magnitude`` unit is to check the column name. col_unit = "mag" else: col_unit = "---" # Add col limit values to col description lim_vals = "" if (col.min and col.max and not any(x in col.name for x in ['RA', 'DE', 'LON', 'LAT', 'PLN', 'PLT'])): # No col limit values for coordinate columns. if col.fortran_format[0] == 'I': if abs(col.min) < MAX_COL_INTLIMIT and abs(col.max) < MAX_COL_INTLIMIT: if col.min == col.max: lim_vals = "[{0}]".format(col.min) else: lim_vals = "[{0}/{1}]".format(col.min, col.max) elif col.fortran_format[0] in ('E', 'F'): lim_vals = "[{0}/{1}]".format(math.floor(col.min * 100) / 100., math.ceil(col.max * 100) / 100.) if lim_vals != '' or nullflag != '': description = "{0}{1} {2}".format(lim_vals, nullflag, description) # Find the maximum label and description column widths. if len(col.name) > max_label_width: max_label_width = len(col.name) if len(description) > max_descrip_size: max_descrip_size = len(description) # Add a row for the Sign of Declination in the bbb table if col.name == 'DEd': bbb.add_row([singlebfmt.format(startb), "A1", "---", "DE-", "Sign of Declination"]) col.fortran_format = 'I2' startb += 1 # Add Byte-By-Byte row to bbb table bbb.add_row([singlebfmt.format(startb) if startb == endb else fmtb.format(startb, endb), "" if col.fortran_format is None else col.fortran_format, col_unit, "" if col.name is None else col.name, description]) startb = endb + 2 # Properly format bbb columns bbblines = StringIO() bbb.write(bbblines, format='ascii.fixed_width_no_header', delimiter=' ', bookend=False, delimiter_pad=None, formats={'Format': '<6s', 'Units': '<6s', 'Label': '<' + str(max_label_width) + 's', 'Explanations': '' + str(max_descrip_size) + 's'}) # Get formatted bbb lines bbblines = bbblines.getvalue().splitlines() # ``nsplit`` is the number of whitespaces to prefix to long description # lines in order to wrap them. It is the sum of the widths of the # previous 4 columns plus the number of single spacing between them. # The hyphen in the Bytes column is also counted. nsplit = byte_count_width * 2 + 1 + 12 + max_label_width + 4 # Wrap line if it is too long buff = "" for newline in bbblines: if len(newline) > MAX_SIZE_README_LINE: buff += ("\n").join(wrap(newline, subsequent_indent=" " * nsplit, width=MAX_SIZE_README_LINE)) buff += "\n" else: buff += newline + "\n" # Last value of ``endb`` is the sum of column widths after formatting. self.linewidth = endb # Remove the last extra newline character from Byte-By-Byte. buff = buff[:-1] return buff def write(self, lines): """ Writes the Header of the MRT table, aka ReadMe, which also contains the Byte-By-Byte description of the table. """ from astropy.coordinates import SkyCoord # Recognised ``SkyCoord.name`` forms with their default column names (helio* require SunPy). coord_systems = {'galactic': ('GLAT', 'GLON', 'b', 'l'), 'ecliptic': ('ELAT', 'ELON', 'lat', 'lon'), # 'geocentric*ecliptic' 'heliographic': ('HLAT', 'HLON', 'lat', 'lon'), # '_carrington|stonyhurst' 'helioprojective': ('HPLT', 'HPLN', 'Ty', 'Tx')} eqtnames = ['RAh', 'RAm', 'RAs', 'DEd', 'DEm', 'DEs'] # list to store indices of columns that are modified. to_pop = [] # For columns that are instances of ``SkyCoord`` and other ``mixin`` columns # or whose values are objects of these classes. for i, col in enumerate(self.cols): # If col is a ``Column`` object but its values are ``SkyCoord`` objects, # convert the whole column to ``SkyCoord`` object, which helps in applying # SkyCoord methods directly. if not isinstance(col, SkyCoord) and isinstance(col[0], SkyCoord): try: col = SkyCoord(col) except (ValueError, TypeError): # If only the first value of the column is a ``SkyCoord`` object, # the column cannot be converted to a ``SkyCoord`` object. # These columns are converted to ``Column`` object and then converted # to string valued column. if not isinstance(col, Column): col = Column(col) col = Column([str(val) for val in col]) self.cols[i] = col continue # Replace single ``SkyCoord`` column by its coordinate components if no coordinate # columns of the correspoding type exist yet. if isinstance(col, SkyCoord): # If coordinates are given in RA/DEC, divide each them into hour/deg, # minute/arcminute, second/arcsecond columns. if ('ra' in col.representation_component_names.keys() and len(set(eqtnames) - set(self.colnames)) == 6): ra_c, dec_c = col.ra.hms, col.dec.dms coords = [ra_c.h.round().astype('i1'), ra_c.m.round().astype('i1'), ra_c.s, dec_c.d.round().astype('i1'), dec_c.m.round().astype('i1'), dec_c.s] coord_units = [u.h, u.min, u.second, u.deg, u.arcmin, u.arcsec] coord_descrip = ['Right Ascension (hour)', 'Right Ascension (minute)', 'Right Ascension (second)', 'Declination (degree)', 'Declination (arcmin)', 'Declination (arcsec)'] for coord, name, coord_unit, descrip in zip( coords, eqtnames, coord_units, coord_descrip): # Have Sign of Declination only in the DEd column. if name in ['DEm', 'DEs']: coord_col = Column(list(np.abs(coord)), name=name, unit=coord_unit, description=descrip) else: coord_col = Column(list(coord), name=name, unit=coord_unit, description=descrip) # Set default number of digits after decimal point for the # second values, and deg-min to (signed) 2-digit zero-padded integer. if name == 'RAs': coord_col.format = '013.10f' elif name == 'DEs': coord_col.format = '012.9f' elif name == 'RAh': coord_col.format = '2d' elif name == 'DEd': coord_col.format = '+03d' elif name.startswith(('RA', 'DE')): coord_col.format = '02d' self.cols.append(coord_col) to_pop.append(i) # Delete original ``SkyCoord`` column. # For all other coordinate types, simply divide into two columns # for latitude and longitude resp. with the unit used been as it is. else: frminfo = '' for frame, latlon in coord_systems.items(): if frame in col.name and len(set(latlon[:2]) - set(self.colnames)) == 2: if frame != col.name: frminfo = f' ({col.name})' lon_col = Column(getattr(col, latlon[3]), name=latlon[1], description=f'{frame.capitalize()} Longitude{frminfo}', unit=col.representation_component_units[latlon[3]], format='.12f') lat_col = Column(getattr(col, latlon[2]), name=latlon[0], description=f'{frame.capitalize()} Latitude{frminfo}', unit=col.representation_component_units[latlon[2]], format='+.12f') self.cols.append(lon_col) self.cols.append(lat_col) to_pop.append(i) # Delete original ``SkyCoord`` column. # Convert all other ``SkyCoord`` columns that are not in the above three # representations to string valued columns. Those could either be types not # supported yet (e.g. 'helioprojective'), or already present and converted. # If there were any extra ``SkyCoord`` columns of one kind after the first one, # then their decomposition into their component columns has been skipped. # This is done in order to not create duplicate component columns. # Explicit renaming of the extra coordinate component columns by appending some # suffix to their name, so as to distinguish them, is not yet implemented. if i not in to_pop: warnings.warn(f"Coordinate system of type '{col.name}' already stored in table " f"as CDS/MRT-syle columns or of unrecognized type. So column {i} " f"is being skipped with designation of a string valued column " f"`{self.colnames[i]}`.", UserWarning) self.cols.append(Column(col.to_string(), name=self.colnames[i])) to_pop.append(i) # Delete original ``SkyCoord`` column. # Convert all other ``mixin`` columns to ``Column`` objects. # Parsing these may still lead to errors! elif not isinstance(col, Column): col = Column(col) # If column values are ``object`` types, convert them to string. if np.issubdtype(col.dtype, np.dtype(object).type): col = Column([str(val) for val in col]) self.cols[i] = col # Delete original ``SkyCoord`` columns, if there were any. for i in to_pop[::-1]: self.cols.pop(i) # Check for any left over extra coordinate columns. if any(x in self.colnames for x in ['RAh', 'DEd', 'ELON', 'GLAT']): # At this point any extra ``SkyCoord`` columns should have been converted to string # valued columns, together with issuance of a warning, by the coordinate parser above. # This test is just left here as a safeguard. for i, col in enumerate(self.cols): if isinstance(col, SkyCoord): self.cols[i] = Column(col.to_string(), name=self.colnames[i]) message = ('Table already has coordinate system in CDS/MRT-syle columns. ' f'So column {i} should have been replaced already with ' f'a string valued column `{self.colnames[i]}`.') raise core.InconsistentTableError(message) # Get Byte-By-Byte description and fill the template bbb_template = Template('\n'.join(BYTE_BY_BYTE_TEMPLATE)) byte_by_byte = bbb_template.substitute({'file': 'table.dat', 'bytebybyte': self.write_byte_by_byte()}) # Fill up the full ReadMe rm_template = Template('\n'.join(MRT_TEMPLATE)) readme_filled = rm_template.substitute({'bytebybyte': byte_by_byte}) lines.append(readme_filled) class MrtData(cds.CdsData): """MRT table data reader """ _subfmt = 'MRT' splitter_class = MrtSplitter def write(self, lines): self.splitter.delimiter = ' ' fixedwidth.FixedWidthData.write(self, lines) class Mrt(core.BaseReader): """AAS MRT (Machine-Readable Table) format table. **Reading** :: >>> from astropy.io import ascii >>> table = ascii.read('data.mrt', format='mrt') **Writing** Use ``ascii.write(table, 'data.mrt', format='mrt')`` to write tables to Machine Readable Table (MRT) format. Note that the metadata of the table, apart from units, column names and description, will not be written. These have to be filled in by hand later. See also: :ref:`cds_mrt_format`. Caveats: * The Units and Explanations are available in the column ``unit`` and ``description`` attributes, respectively. * The other metadata defined by this format is not available in the output table. """ _format_name = 'mrt' _io_registry_format_aliases = ['mrt'] _io_registry_can_write = True _description = 'MRT format table' data_class = MrtData header_class = MrtHeader def write(self, table=None): # Construct for writing empty table is not yet done. if len(table) == 0: raise NotImplementedError self.data.header = self.header self.header.position_line = None self.header.start_line = None # Create a copy of the ``table``, so that it the copy gets modified and # written to the file, while the original table remains as it is. table = table.copy() return super().write(table) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/qdp.py0000644000175100001710000004737500000000000016623 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This package contains functions for reading and writing QDP tables that are not meant to be used directly, but instead are available as readers/writers in `astropy.table`. See :ref:`astropy:table_io` for more details. """ import re import copy from collections.abc import Iterable import numpy as np import warnings from astropy.utils.exceptions import AstropyUserWarning from astropy.table import Table from . import core, basic def _line_type(line, delimiter=None): """Interpret a QDP file line Parameters ---------- line : str a single line of the file Returns ------- type : str Line type: "comment", "command", or "data" Examples -------- >>> _line_type("READ SERR 3") 'command' >>> _line_type(" \\n !some gibberish") 'comment' >>> _line_type(" ") 'comment' >>> _line_type(" 21345.45") 'data,1' >>> _line_type(" 21345.45 1.53e-3 1e-3 .04 NO nan") 'data,6' >>> _line_type(" 21345.45,1.53e-3,1e-3,.04,NO,nan", delimiter=',') 'data,6' >>> _line_type(" 21345.45 ! a comment to disturb") 'data,1' >>> _line_type("NO NO NO NO NO") 'new' >>> _line_type("NO,NO,NO,NO,NO", delimiter=',') 'new' >>> _line_type("N O N NOON OON O") Traceback (most recent call last): ... ValueError: Unrecognized QDP line... >>> _line_type(" some non-comment gibberish") Traceback (most recent call last): ... ValueError: Unrecognized QDP line... """ _decimal_re = r'[+-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?' _command_re = r'READ [TS]ERR(\s+[0-9]+)+' sep = delimiter if delimiter is None: sep = r'\s+' _new_re = rf'NO({sep}NO)+' _data_re = rf'({_decimal_re}|NO|[-+]?nan)({sep}({_decimal_re}|NO|[-+]?nan))*)' _type_re = rf'^\s*((?P{_command_re})|(?P{_new_re})|(?P{_data_re})?\s*(\!(?P.*))?\s*$' _line_type_re = re.compile(_type_re) line = line.strip() if not line: return 'comment' match = _line_type_re.match(line) if match is None: raise ValueError(f'Unrecognized QDP line: {line}') for type_, val in match.groupdict().items(): if val is None: continue if type_ == 'data': return f'data,{len(val.split(sep=delimiter))}' else: return type_ def _get_type_from_list_of_lines(lines, delimiter=None): """Read through the list of QDP file lines and label each line by type Parameters ---------- lines : list List containing one file line in each entry Returns ------- contents : list List containing the type for each line (see `line_type_and_data`) ncol : int The number of columns in the data lines. Must be the same throughout the file Examples -------- >>> line0 = "! A comment" >>> line1 = "543 12 456.0" >>> lines = [line0, line1] >>> types, ncol = _get_type_from_list_of_lines(lines) >>> types[0] 'comment' >>> types[1] 'data,3' >>> ncol 3 >>> lines.append("23") >>> _get_type_from_list_of_lines(lines) Traceback (most recent call last): ... ValueError: Inconsistent number of columns """ types = [_line_type(line, delimiter=delimiter) for line in lines] current_ncol = None for type_ in types: if type_.startswith('data', ): ncol = int(type_[5:]) if current_ncol is None: current_ncol = ncol elif ncol != current_ncol: raise ValueError('Inconsistent number of columns') return types, current_ncol def _get_lines_from_file(qdp_file): if "\n" in qdp_file: lines = qdp_file.split("\n") elif isinstance(qdp_file, str): with open(qdp_file) as fobj: lines = [line.strip() for line in fobj.readlines()] elif isinstance(qdp_file, Iterable): lines = qdp_file else: raise ValueError('invalid value of qdb_file') return lines def _interpret_err_lines(err_specs, ncols, names=None): """Give list of column names from the READ SERR and TERR commands Parameters ---------- err_specs : dict ``{'serr': [n0, n1, ...], 'terr': [n2, n3, ...]}`` Error specifications for symmetric and two-sided errors ncols : int Number of data columns Other parameters ---------------- names : list of str Name of data columns (defaults to ['col1', 'col2', ...]), _not_ including error columns. Returns ------- colnames : list List containing the column names. Error columns will have the name of the main column plus ``_err`` for symmetric errors, and ``_perr`` and ``_nerr`` for positive and negative errors respectively Examples -------- >>> col_in = ['MJD', 'Rate'] >>> cols = _interpret_err_lines(None, 2, names=col_in) >>> cols[0] 'MJD' >>> err_specs = {'terr': [1], 'serr': [2]} >>> ncols = 5 >>> cols = _interpret_err_lines(err_specs, ncols, names=col_in) >>> cols[0] 'MJD' >>> cols[2] 'MJD_nerr' >>> cols[4] 'Rate_err' >>> _interpret_err_lines(err_specs, 6, names=col_in) Traceback (most recent call last): ... ValueError: Inconsistent number of input colnames """ colnames = ["" for i in range(ncols)] if err_specs is None: serr_cols = terr_cols = [] else: # I don't want to empty the original one when using `pop` below err_specs = copy.deepcopy(err_specs) serr_cols = err_specs.pop("serr", []) terr_cols = err_specs.pop("terr", []) if names is not None: all_error_cols = len(serr_cols) + len(terr_cols) * 2 if all_error_cols + len(names) != ncols: raise ValueError("Inconsistent number of input colnames") shift = 0 for i in range(ncols): col_num = i + 1 - shift if colnames[i] != "": continue colname_root = f"col{col_num}" if names is not None: colname_root = names[col_num - 1] colnames[i] = f"{colname_root}" if col_num in serr_cols: colnames[i + 1] = f"{colname_root}_err" shift += 1 continue if col_num in terr_cols: colnames[i + 1] = f"{colname_root}_perr" colnames[i + 2] = f"{colname_root}_nerr" shift += 2 continue assert not np.any([c == "" for c in colnames]) return colnames def _get_tables_from_qdp_file(qdp_file, input_colnames=None, delimiter=None): """Get all tables from a QDP file Parameters ---------- qdp_file : str Input QDP file name Other parameters ---------------- input_colnames : list of str Name of data columns (defaults to ['col1', 'col2', ...]), _not_ including error columns. delimiter : str Delimiter for the values in the table. Returns ------- list of `~astropy.table.Table` List containing all the tables present inside the QDP file """ lines = _get_lines_from_file(qdp_file) contents, ncol = _get_type_from_list_of_lines(lines, delimiter=delimiter) table_list = [] err_specs = {} colnames = None comment_text = "" initial_comments = "" command_lines = "" current_rows = None for line, datatype in zip(lines, contents): line = line.strip().lstrip('!') # Is this a comment? if datatype == "comment": comment_text += line + '\n' continue if datatype == "command": # The first time I find commands, I save whatever comments into # The initial comments. if command_lines == "": initial_comments = comment_text comment_text = "" if err_specs != {}: warnings.warn( "This file contains multiple command blocks. Please verify", AstropyUserWarning ) command_lines += line + '\n' continue if datatype.startswith("data"): # The first time I find data, I define err_specs if err_specs == {} and command_lines != "": for cline in command_lines.strip().split('\n'): command = cline.strip().split() # This should never happen, but just in case. if len(command) < 3: continue err_specs[command[1].lower()] = [int(c) for c in command[2:]] if colnames is None: colnames = _interpret_err_lines( err_specs, ncol, names=input_colnames ) if current_rows is None: current_rows = [] values = [] for v in line.split(delimiter): if v == "NO": values.append(np.ma.masked) else: # Understand if number is int or float try: values.append(int(v)) except ValueError: values.append(float(v)) current_rows.append(values) continue if datatype == "new": # Save table to table_list and reset if current_rows is not None: new_table = Table(names=colnames, rows=current_rows) new_table.meta["initial_comments"] = initial_comments.strip().split("\n") new_table.meta["comments"] = comment_text.strip().split("\n") # Reset comments comment_text = "" table_list.append(new_table) current_rows = None continue # At the very end, if there is still a table being written, let's save # it to the table_list if current_rows is not None: new_table = Table(names=colnames, rows=current_rows) new_table.meta["initial_comments"] = initial_comments.strip().split("\n") new_table.meta["comments"] = comment_text.strip().split("\n") table_list.append(new_table) return table_list def _understand_err_col(colnames): """Get which column names are error columns Examples -------- >>> colnames = ['a', 'a_err', 'b', 'b_perr', 'b_nerr'] >>> serr, terr = _understand_err_col(colnames) >>> np.allclose(serr, [1]) True >>> np.allclose(terr, [2]) True >>> serr, terr = _understand_err_col(['a', 'a_nerr']) Traceback (most recent call last): ... ValueError: Missing positive error... >>> serr, terr = _understand_err_col(['a', 'a_perr']) Traceback (most recent call last): ... ValueError: Missing negative error... """ shift = 0 serr = [] terr = [] for i, col in enumerate(colnames): if col.endswith("_err"): # The previous column, but they're numbered from 1! # Plus, take shift into account serr.append(i - shift) shift += 1 elif col.endswith("_perr"): terr.append(i - shift) if len(colnames) == i + 1 or not colnames[i + 1].endswith('_nerr'): raise ValueError("Missing negative error") shift += 2 elif col.endswith("_nerr") and not colnames[i - 1].endswith('_perr'): raise ValueError("Missing positive error") return serr, terr def _read_table_qdp(qdp_file, names=None, table_id=None, delimiter=None): """Read a table from a QDP file Parameters ---------- qdp_file : str Input QDP file name Other parameters ---------------- names : list of str Name of data columns (defaults to ['col1', 'col2', ...]), _not_ including error columns. table_id : int, default 0 Number of the table to be read from the QDP file. This is useful when multiple tables present in the file. By default, the first is read. delimiter : str Any delimiter accepted by the `sep` argument of str.split() Returns ------- tables : list of `~astropy.table.Table` List containing all the tables present inside the QDP file """ if table_id is None: warnings.warn("table_id not specified. Reading the first available " "table", AstropyUserWarning) table_id = 0 tables = _get_tables_from_qdp_file(qdp_file, input_colnames=names, delimiter=delimiter) return tables[table_id] def _write_table_qdp(table, filename=None, err_specs=None): """Write a table to a QDP file Parameters ---------- table : :class:`~astropy.table.Table` Input table to be written filename : str Output QDP file name Other parameters ---------------- err_specs : dict Dictionary of the format {'serr': [1], 'terr': [2, 3]}, specifying which columns have symmetric and two-sided errors (see QDP format specification) """ import io fobj = io.StringIO() if 'initial_comments' in table.meta and table.meta['initial_comments'] != []: for line in table.meta['initial_comments']: line = line.strip() if not line.startswith("!"): line = "!" + line print(line, file=fobj) if err_specs is None: serr_cols, terr_cols = _understand_err_col(table.colnames) else: serr_cols = err_specs.pop("serr", []) terr_cols = err_specs.pop("terr", []) if serr_cols != []: col_string = " ".join([str(val) for val in serr_cols]) print(f"READ SERR {col_string}", file=fobj) if terr_cols != []: col_string = " ".join([str(val) for val in terr_cols]) print(f"READ TERR {col_string}", file=fobj) if 'comments' in table.meta and table.meta['comments'] != []: for line in table.meta['comments']: line = line.strip() if not line.startswith("!"): line = "!" + line print(line, file=fobj) colnames = table.colnames print("!" + " ".join(colnames), file=fobj) for row in table: values = [] for val in row: if not np.ma.is_masked(val): rep = str(val) else: rep = "NO" values.append(rep) print(" ".join(values), file=fobj) full_string = fobj.getvalue() fobj.close() if filename is not None: with open(filename, 'w') as fobj: print(full_string, file=fobj) return full_string.split("\n") class QDPSplitter(core.DefaultSplitter): """ Split on space for QDP tables """ delimiter = ' ' class QDPHeader(basic.CommentedHeaderHeader): """ Header that uses the :class:`astropy.io.ascii.basic.QDPSplitter` """ splitter_class = QDPSplitter comment = "!" write_comment = "!" class QDPData(basic.BasicData): """ Data that uses the :class:`astropy.io.ascii.basic.CsvSplitter` """ splitter_class = QDPSplitter fill_values = [(core.masked, 'NO')] comment = "!" write_comment = None class QDP(basic.Basic): """Quick and Dandy Plot table. Example:: ! Initial comment line 1 ! Initial comment line 2 READ TERR 1 READ SERR 3 ! Table 0 comment !a a(pos) a(neg) b be c d 53000.5 0.25 -0.5 1 1.5 3.5 2 54000.5 1.25 -1.5 2 2.5 4.5 3 NO NO NO NO NO ! Table 1 comment !a a(pos) a(neg) b be c d 54000.5 2.25 -2.5 NO 3.5 5.5 5 55000.5 3.25 -3.5 4 4.5 6.5 nan The input table above contains some initial comments, the error commands, then two tables. This file format can contain multiple tables, separated by a line full of ``NO``s. Comments are exclamation marks, and missing values are single ``NO`` entries. The delimiter is usually whitespace, more rarely a comma. The QDP format differentiates between data and error columns. The table above has commands:: READ TERR 1 READ SERR 3 which mean that after data column 1 there will be two error columns containing its positive and engative error bars, then data column 2 without error bars, then column 3, then a column with the symmetric error of column 3, then the remaining data columns. As explained below, table headers are highly inconsistent. Possible comments containing column names will be ignored and columns will be called ``col1``, ``col2``, etc. unless the user specifies their names with the ``names=`` keyword argument, When passing column names, pass **only the names of the data columns, not the error columns.** Error information will be encoded in the names of the table columns. (e.g. ``a_perr`` and ``a_nerr`` for the positive and negative error of column ``a``, ``b_err`` the symmetric error of column ``b``.) When writing tables to this format, users can pass an ``err_specs`` keyword passing a dictionary ``{'serr': [3], 'terr': [1, 2]}``, meaning that data columns 1 and two will have two additional columns each with their positive and negative errors, and data column 3 will have an additional column with a symmetric error (just like the ``READ SERR`` and ``READ TERR`` commands above) Headers are just comments, and tables distributed by various missions can differ greatly in their use of conventions. For example, light curves distributed by the Swift-Gehrels mission have an extra space in one header entry that makes the number of labels inconsistent with the number of cols. For this reason, we ignore the comments that might encode the column names and leave the name specification to the user. Example:: > Extra space > | > v >! MJD Err (pos) Err(neg) Rate Error >53000.123456 2.378e-05 -2.378472e-05 NO 0.212439 These readers and writer classes will strive to understand which of the comments belong to all the tables, and which ones to each single table. General comments will be stored in the ``initial_comments`` meta of each table. The comments of each table will be stored in the ``comments`` meta. Example:: t = Table.read(example_qdp, format='ascii.qdp', table_id=1, names=['a', 'b', 'c', 'd']) reads the second table (``table_id=1``) in file ``example.qdp`` containing the table above. There are four column names but seven data columns, why? Because the ``READ SERR`` and ``READ TERR`` commands say that there are three error columns. ``t.meta['initial_comments']`` will contain the initial two comment lines in the file, while ``t.meta['comments']`` will contain ``Table 1 comment`` The table can be written to another file, preserving the same information, as:: t.write(test_file, err_specs={'terr': [1], 'serr': [3]}) Note how the ``terr`` and ``serr`` commands are passed to the writer. """ _format_name = 'qdp' _io_registry_can_write = True _io_registry_suffix = '.qdp' _description = 'Quick and Dandy Plotter' header_class = QDPHeader data_class = QDPData def __init__(self, table_id=None, names=None, err_specs=None, sep=None): super().__init__() self.table_id = table_id self.names = names self.err_specs = err_specs self.delimiter = sep def read(self, table): self.lines = self.inputter.get_lines(table, newline="\n") return _read_table_qdp(self.lines, table_id=self.table_id, names=self.names, delimiter=self.delimiter) def write(self, table): self._check_multidim_table(table) lines = _write_table_qdp(table, err_specs=self.err_specs) return lines ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/rst.py0000644000175100001710000000325000000000000016627 0ustar00vstsdocker# Licensed under a 3-clause BSD style license """ :Author: Simon Gibbons (simongibbons@gmail.com) """ from .core import DefaultSplitter from .fixedwidth import (FixedWidth, FixedWidthData, FixedWidthHeader, FixedWidthTwoLineDataSplitter) class SimpleRSTHeader(FixedWidthHeader): position_line = 0 start_line = 1 splitter_class = DefaultSplitter position_char = '=' def get_fixedwidth_params(self, line): vals, starts, ends = super().get_fixedwidth_params(line) # The right hand column can be unbounded ends[-1] = None return vals, starts, ends class SimpleRSTData(FixedWidthData): start_line = 3 end_line = -1 splitter_class = FixedWidthTwoLineDataSplitter class RST(FixedWidth): """reStructuredText simple format table. See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#simple-tables Example:: ==== ===== ====== Col1 Col2 Col3 ==== ===== ====== 1 2.3 Hello 2 4.5 Worlds ==== ===== ====== Currently there is no support for reading tables which utilize continuation lines, or for ones which define column spans through the use of an additional line of dashes in the header. """ _format_name = 'rst' _description = 'reStructuredText simple table' data_class = SimpleRSTData header_class = SimpleRSTHeader def __init__(self): super().__init__(delimiter_pad=None, bookend=False) def write(self, lines): lines = super().write(lines) lines = [lines[1]] + lines + [lines[1]] return lines ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/setup_package.py0000644000175100001710000000067600000000000020643 0ustar00vstsdocker# Licensed under a 3-clause BSD style license import os from setuptools import Extension import numpy ROOT = os.path.relpath(os.path.dirname(__file__)) def get_extensions(): sources = [os.path.join(ROOT, 'cparser.pyx'), os.path.join(ROOT, 'src', 'tokenizer.c')] ascii_ext = Extension( name="astropy.io.ascii.cparser", include_dirs=[numpy.get_include()], sources=sources) return [ascii_ext] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/sextractor.py0000644000175100001710000001431100000000000020215 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ sextractor.py: Classes to read SExtractor table format Built on daophot.py: :Copyright: Smithsonian Astrophysical Observatory (2011) :Author: Tom Aldcroft (aldcroft@head.cfa.harvard.edu) """ import re from . import core class SExtractorHeader(core.BaseHeader): """Read the header from a file produced by SExtractor.""" comment = r'^\s*#\s*\S\D.*' # Find lines that don't have "# digit" def get_cols(self, lines): """ Initialize the header Column objects from the table ``lines`` for a SExtractor header. The SExtractor header is specialized so that we just copy the entire BaseHeader get_cols routine and modify as needed. Parameters ---------- lines : list List of table lines """ # This assumes that the columns are listed in order, one per line with a # header comment string of the format: "# 1 ID short description [unit]" # However, some may be missing and must be inferred from skipped column numbers columns = {} # E.g. '# 1 ID identification number' (no units) or '# 2 MAGERR magnitude of error [mag]' # Updated along with issue #4603, for more robust parsing of unit re_name_def = re.compile(r"""^\s* \# \s* # possible whitespace around # (?P [0-9]+)\s+ # number of the column in table (?P [-\w]+) # name of the column # column description, match any character until... (?:\s+(?P \w .+) # ...until [non-space][space][unit] or [not-right-bracket][end] (?:(?.+)\])?.* # match units in brackets """, re.VERBOSE) dataline = None for line in lines: if not line.startswith('#'): dataline = line # save for later to infer the actual number of columns break # End of header lines else: match = re_name_def.search(line) if match: colnumber = int(match.group('colnumber')) colname = match.group('colname') coldescr = match.group('coldescr') colunit = match.group('colunit') # If no units are given, colunit = None columns[colnumber] = (colname, coldescr, colunit) # Handle skipped column numbers colnumbers = sorted(columns) # Handle the case where the last column is array-like by append a pseudo column # If there are more data columns than the largest column number # then add a pseudo-column that will be dropped later. This allows # the array column logic below to work in all cases. if dataline is not None: n_data_cols = len(dataline.split()) else: # handles no data, where we have to rely on the last column number n_data_cols = colnumbers[-1] # sextractor column number start at 1. columns[n_data_cols + 1] = (None, None, None) colnumbers.append(n_data_cols + 1) if len(columns) > 1: # only fill in skipped columns when there is genuine column initially previous_column = 0 for n in colnumbers: if n != previous_column + 1: for c in range(previous_column + 1, n): column_name = (columns[previous_column][0] + f"_{c - previous_column}") column_descr = columns[previous_column][1] column_unit = columns[previous_column][2] columns[c] = (column_name, column_descr, column_unit) previous_column = n # Add the columns in order to self.names colnumbers = sorted(columns)[:-1] # drop the pseudo column self.names = [] for n in colnumbers: self.names.append(columns[n][0]) if not self.names: raise core.InconsistentTableError('No column names found in SExtractor header') self.cols = [] for n in colnumbers: col = core.Column(name=columns[n][0]) col.description = columns[n][1] col.unit = columns[n][2] self.cols.append(col) class SExtractorData(core.BaseData): start_line = 0 delimiter = ' ' comment = r'\s*#' class SExtractor(core.BaseReader): """SExtractor format table. SExtractor is a package for faint-galaxy photometry (Bertin & Arnouts 1996, A&A Supp. 317, 393.) See: https://sextractor.readthedocs.io/en/latest/ Example:: # 1 NUMBER # 2 ALPHA_J2000 # 3 DELTA_J2000 # 4 FLUX_RADIUS # 7 MAG_AUTO [mag] # 8 X2_IMAGE Variance along x [pixel**2] # 9 X_MAMA Barycenter position along MAMA x axis [m**(-6)] # 10 MU_MAX Peak surface brightness above background [mag * arcsec**(-2)] 1 32.23222 10.1211 0.8 1.2 1.4 18.1 1000.0 0.00304 -3.498 2 38.12321 -88.1321 2.2 2.4 3.1 17.0 1500.0 0.00908 1.401 Note the skipped numbers since flux_radius has 3 columns. The three FLUX_RADIUS columns will be named FLUX_RADIUS, FLUX_RADIUS_1, FLUX_RADIUS_2 Also note that a post-ID description (e.g. "Variance along x") is optional and that units may be specified at the end of a line in brackets. """ _format_name = 'sextractor' _io_registry_can_write = False _description = 'SExtractor format table' header_class = SExtractorHeader data_class = SExtractorData inputter_class = core.ContinuationLinesInputter def read(self, table): """ Read input data (file-like object, filename, list of strings, or single string) into a Table and return the result. """ out = super().read(table) # remove the comments if 'comments' in out.meta: del out.meta['comments'] return out def write(self, table): raise NotImplementedError ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1032457 astropy-5.0.2/astropy/io/ascii/src/0000755000175100001710000000000000000000000016234 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/src/tokenizer.c0000644000175100001710000010276000000000000020420 0ustar00vstsdocker// Licensed under a 3-clause BSD style license - see LICENSE.rst #include "tokenizer.h" tokenizer_t *create_tokenizer(char delimiter, char comment, char quotechar, char expchar, int fill_extra_cols, int strip_whitespace_lines, int strip_whitespace_fields, int use_fast_converter) { // Create the tokenizer in memory tokenizer_t *tokenizer = (tokenizer_t *) malloc(sizeof(tokenizer_t)); // Initialize the tokenizer fields tokenizer->source = NULL; tokenizer->source_len = 0; tokenizer->source_pos = 0; tokenizer->delimiter = delimiter; tokenizer->comment = comment; tokenizer->quotechar = quotechar; tokenizer->expchar = expchar; tokenizer->newline = '\n'; tokenizer->output_cols = NULL; tokenizer->col_ptrs = NULL; tokenizer->output_len = NULL; tokenizer->num_cols = 0; tokenizer->num_rows = 0; tokenizer->fill_extra_cols = fill_extra_cols; tokenizer->state = START_LINE; tokenizer->code = NO_ERROR; tokenizer->iter_col = 0; tokenizer->curr_pos = NULL; tokenizer->strip_whitespace_lines = strip_whitespace_lines; tokenizer->strip_whitespace_fields = strip_whitespace_fields; tokenizer->use_fast_converter = use_fast_converter; tokenizer->comment_lines = (char *) malloc(INITIAL_COMMENT_LEN); tokenizer->comment_pos = 0; tokenizer->comment_lines_len = 0; // This is a bit of a hack -- buf holds an empty string to represent // empty field values tokenizer->buf = calloc(2, sizeof(char)); // By default both \n and \r are accepted as newline, unless one of // them has also been specified as field delimiter if (tokenizer->delimiter == '\n') tokenizer->newline = '\r'; return tokenizer; } void delete_data(tokenizer_t *tokenizer) { // Don't free tokenizer->source because it points to part of // an already freed Python object int i; if (tokenizer->output_cols) { for (i = 0; i < tokenizer->num_cols; ++i) { free(tokenizer->output_cols[i]); } } free(tokenizer->output_cols); free(tokenizer->col_ptrs); free(tokenizer->output_len); // Set pointers to 0 so we don't use freed memory when reading over again tokenizer->output_cols = 0; tokenizer->col_ptrs = 0; tokenizer->output_len = 0; } void delete_tokenizer(tokenizer_t *tokenizer) { delete_data(tokenizer); free(tokenizer->comment_lines); free(tokenizer->buf); free(tokenizer); } void resize_col(tokenizer_t *self, int index) { // Temporarily store the position in output_cols[index] to // which col_ptrs[index] points long diff = self->col_ptrs[index] - self->output_cols[index]; // Double the size of the column string self->output_cols[index] = (char *) realloc(self->output_cols[index], 2 * self->output_len[index] * sizeof(char)); // Set the second (newly allocated) half of the column string to all zeros memset(self->output_cols[index] + self->output_len[index] * sizeof(char), 0, self->output_len[index] * sizeof(char)); self->output_len[index] *= 2; // realloc() might move the address in memory, so we have to move // col_ptrs[index] to an offset of the new address self->col_ptrs[index] = self->output_cols[index] + diff; } void resize_comments(tokenizer_t *self) { // Double the size of the comments string self->comment_lines = (char *) realloc(self->comment_lines, self->comment_pos + 1); // Set the second (newly allocated) half of the column string to all zeros memset(self->comment_lines + self->comment_lines_len * sizeof(char), 0, (self->comment_pos + 1 - self->comment_lines_len) * sizeof(char)); self->comment_lines_len = self->comment_pos + 1; } /* Resize the column string if necessary and then append c to the end of the column string, incrementing the column position pointer. */ static inline void push(tokenizer_t *self, char c, int col) { if (self->col_ptrs[col] - self->output_cols[col] >= self->output_len[col]) { resize_col(self, col); } *self->col_ptrs[col]++ = c; } /* Resize the comment string if necessary and then append c to the end of the comment string. */ static inline void push_comment(tokenizer_t *self, char c) { if (self->comment_pos >= self->comment_lines_len) { resize_comments(self); } self->comment_lines[self->comment_pos++] = c; } static inline void end_comment(tokenizer_t *self) { // Signal empty comment by inserting \x01 if (self->comment_pos == 0 || self->comment_lines[self->comment_pos - 1] == '\x00') { push_comment(self, '\x01'); } push_comment(self, '\x00'); } #define PUSH(c) push(self, c, col) /* Set the state to START_FIELD and begin with the assumption that the field is entirely whitespace in order to handle the possibility that the comment character is found before any non-whitespace even if whitespace stripping is disabled. */ #define BEGIN_FIELD() \ self->state = START_FIELD; \ whitespace = 1 /* First, backtrack to eliminate trailing whitespace if strip_whitespace_fields is true. If the field is empty, push '\x01' as a marker. Append a null byte to the end of the column string as a field delimiting marker. Increment the variable col if we are tokenizing data. */ static inline void end_field(tokenizer_t *self, int *col, int header) { if (self->strip_whitespace_fields && self->col_ptrs[*col] != self->output_cols[*col]) { --self->col_ptrs[*col]; while (*self->col_ptrs[*col] == ' ' || *self->col_ptrs[*col] == '\t') { *self->col_ptrs[*col]-- = '\x00'; } ++self->col_ptrs[*col]; } if (self->col_ptrs[*col] == self->output_cols[*col] || self->col_ptrs[*col][-1] == '\x00') { push(self, '\x01', *col); } push(self, '\x00', *col); if (!header) { ++*col; } } #define END_FIELD() end_field(self, &col, header) // Set the error code to c for later retrieval and return c #define RETURN(c) \ do { \ self->code = c; \ return c; \ } while (0) /* If we are tokenizing the header, end after the first line. Handle the possibility of insufficient columns appropriately; if fill_extra_cols=1, then append empty fields, but otherwise return an error. Increment our row count and possibly end if all the necessary rows have already been parsed. */ static inline int end_line(tokenizer_t *self, int col, int header, int end, tokenizer_state *old_state) { if (header) { ++self->source_pos; RETURN(NO_ERROR); } else if (self->fill_extra_cols) { while (col < self->num_cols) { PUSH('\x01'); END_FIELD(); } } else if (col < self->num_cols) { RETURN(NOT_ENOUGH_COLS); } ++self->num_rows; *old_state = START_LINE; if (end != -1 && self->num_rows == end) { ++self->source_pos; RETURN(NO_ERROR); } return -1; } #define END_LINE() if (end_line(self, col, header, end, &old_state) != -1) return self->code int skip_lines(tokenizer_t *self, int offset, int header) { int signif_chars = 0; int comment = 0; int i = 0; char c; while (i < offset) { if (self->source_pos >= self->source_len) { if (header) RETURN(INVALID_LINE); // header line is required else RETURN(NO_ERROR); // no data in input } c = self->source[self->source_pos]; if ((c == '\r' || c == '\n') && c != self->delimiter) { if (c == '\r' && self->source_pos < self->source_len - 1 && self->source[self->source_pos + 1] == '\n') { ++self->source_pos; // skip \n in \r\n } if (!comment && signif_chars > 0) ++i; else if (comment && !header) end_comment(self); // Start by assuming a line is empty and non-commented signif_chars = 0; comment = 0; } else if ((c != ' ' && c != '\t') || !self->strip_whitespace_lines) { // Comment line if (!signif_chars && self->comment != 0 && c == self->comment) comment = 1; else if (comment && !header) push_comment(self, c); // Significant character encountered ++signif_chars; } else if (comment && !header) { push_comment(self, c); } ++self->source_pos; } RETURN(NO_ERROR); } int tokenize(tokenizer_t *self, int end, int header, int num_cols) { char c; // Input character int col = 0; // Current column ignoring possibly excluded columns tokenizer_state old_state = START_LINE; // Last state the tokenizer was in before CR mode int i = 0; int whitespace = 1; delete_data(self); // Clear old reading data self->num_rows = 0; self->comment_lines_len = INITIAL_COMMENT_LEN; if (header) self->num_cols = 1; // Store header output in one column else self->num_cols = num_cols; // Allocate memory for structures used during tokenization self->output_cols = (char **) malloc(self->num_cols * sizeof(char *)); self->col_ptrs = (char **) malloc(self->num_cols * sizeof(char *)); self->output_len = (size_t *) malloc(self->num_cols * sizeof(size_t)); for (i = 0; i < self->num_cols; ++i) { self->output_cols[i] = (char *) calloc(1, INITIAL_COL_SIZE * sizeof(char)); // Make each col_ptrs pointer point to the beginning of the // column string self->col_ptrs[i] = self->output_cols[i]; self->output_len[i] = INITIAL_COL_SIZE; } if (end == 0) RETURN(NO_ERROR); // Don't read if end == 0 self->state = START_LINE; // Loop until all of self->source has been read while (self->source_pos < self->source_len + 1) { if (self->source_pos == self->source_len) c = self->newline; else c = self->source[self->source_pos]; if (c == '\r' && c != self->delimiter && c != self->newline) c = '\n'; switch (self->state) { case START_LINE: if (c == self->newline) break; else if ((c == ' ' || c == '\t') && self->strip_whitespace_lines) break; else if (self->comment != 0 && c == self->comment) { // Comment line; ignore self->state = COMMENT; break; } // Initialize variables for the beginning of line parsing col = 0; BEGIN_FIELD(); // Parse in mode START_FIELD case START_FIELD: // Strip whitespace before field begins if ((c == ' ' || c == '\t') && self->strip_whitespace_fields) break; else if (!self->strip_whitespace_lines && self->comment != 0 && c == self->comment) { // Comment line, not caught earlier because of no stripping self->state = COMMENT; break; } // Handle newline characters first else if (c == self->newline) { if (self->strip_whitespace_lines) { // Move on if the delimiter is whitespace, e.g. // '1 2 3 '->['1','2','3'] if (self->delimiter == ' ' || self->delimiter == '\t') ; // Register an empty field if non-whitespace delimiter, // e.g. '1,2, '->['1','2',''] else { if (col >= self->num_cols) RETURN(TOO_MANY_COLS); END_FIELD(); } } else if (!self->strip_whitespace_lines) { // In this case we don't want to left-strip the field, // so we backtrack size_t tmp = self->source_pos; --self->source_pos; while (self->source_pos >= 0 && self->source[self->source_pos] != self->delimiter && self->source[self->source_pos] != '\n' && self->source[self->source_pos] != '\r') { --self->source_pos; } // Backtracked to line beginning if (self->source_pos == -1 || self->source[self->source_pos] == '\n' || self->source[self->source_pos] == '\r') { self->source_pos = tmp; } else { ++self->source_pos; if (self->source_pos == tmp) // No whitespace, just an empty field ; else while (self->source_pos < tmp) { // Append whitespace characters PUSH(self->source[self->source_pos]); ++self->source_pos; } if (col >= self->num_cols) RETURN(TOO_MANY_COLS); END_FIELD(); // Whitespace counts as a field } } END_LINE(); self->state = START_LINE; break; } // Before proceeding with a new field check column does not exceed // number defined in header or from auto-detect to avoid segfaults // such as https://github.com/astropy/astropy/issues/9922 else if (col >= self->num_cols) RETURN(TOO_MANY_COLS); else if (c == self->delimiter) // Field ends before it begins { END_FIELD(); BEGIN_FIELD(); break; } else if (c == self->quotechar) // Start parsing quoted field { self->state = START_QUOTED_FIELD; break; } else // Valid field character, parse again in FIELD mode self->state = FIELD; case FIELD: if (self->comment != 0 && c == self->comment && whitespace && col == 0) // No whitespace stripping, but the comment char is found // before any data, e.g. ' # a b c' self->state = COMMENT; else if (c == self->delimiter && self->source_pos < self->source_len) { // End of field, look for new field END_FIELD(); BEGIN_FIELD(); } else if (c == self->newline) { // Line ending, stop parsing both field and line END_FIELD(); END_LINE(); self->state = START_LINE; } else { if (c != ' ' && c != '\t') whitespace = 0; // Field is not all whitespace PUSH(c); } break; case START_QUOTED_FIELD: if ((c == ' ' || c == '\t') && self->strip_whitespace_fields) { // Ignore initial whitespace break; } else if (c == self->quotechar) { // Lookahead check for double quote inside quoted field, // e.g. """cd" => "cd if (self->source_pos < self->source_len - 1) { if (self->source[self->source_pos + 1] == self->quotechar) { self->state = QUOTED_FIELD_DOUBLE_QUOTE; PUSH(c); break; } } // Parse rest of field normally, e.g. ""c self->state = FIELD; } else { // Valid field character, parse again in QUOTED_FIELD mode self->state = QUOTED_FIELD; } case QUOTED_FIELD_NEWLINE: if (self->state == QUOTED_FIELD) ; // fall through // Ignore initial whitespace if strip_whitespace_lines and // newlines regardless else if (((c == ' ' || c == '\t') && self->strip_whitespace_lines) || c == self->newline) break; else if (c == self->quotechar) { self->state = FIELD; break; } else { // Once data begins, parse it as a normal quoted field self->state = QUOTED_FIELD; } case QUOTED_FIELD: if (c == self->quotechar) { // Lookahead check for double quote inside quoted field, // e.g. "ab""cd" => ab"cd if (self->source_pos < self->source_len - 1) { if (self->source[self->source_pos + 1] == self->quotechar) { self->state = QUOTED_FIELD_DOUBLE_QUOTE; PUSH(c); break; } } // Parse rest of field normally, e.g. "ab"c self->state = FIELD; } else if (c == self->newline) self->state = QUOTED_FIELD_NEWLINE; else { PUSH(c); } break; case QUOTED_FIELD_DOUBLE_QUOTE: // Ignore the second double quote from "ab""cd" and parse rest of // field normally as quoted field. self->state = QUOTED_FIELD; break; case COMMENT: if (c == self->newline) { self->state = START_LINE; if (!header) end_comment(self); } else if (!header) push_comment(self, c); break; // Keep looping until we find a newline } ++self->source_pos; } RETURN(0); } static int ascii_strncasecmp(const char *str1, const char *str2, size_t n) { int char1, char2; do { char1 = tolower(*(str1++)); char2 = tolower(*(str2++)); n--; } while (n && char1 != '\0' && char1 == char2); return (char1 - char2); } long str_to_long(tokenizer_t *self, char *str) { char *tmp; long ret; errno = 0; ret = strtol(str, &tmp, 10); if (tmp == str || *tmp != '\0') self->code = CONVERSION_ERROR; else if (errno == ERANGE) self->code = OVERFLOW_ERROR; return ret; } double str_to_double(tokenizer_t *self, char *str) { char *tmp; double val; errno = 0; if (self->use_fast_converter) { val = xstrtod(str, &tmp, '.', self->expchar, ',', 1); if (errno == EINVAL || tmp == str || *tmp != '\0') { goto conversion_error; } else if (errno == ERANGE) { self->code = OVERFLOW_ERROR; } else if (errno == EDOM) // xstrtod signalling invalid exponents { self->code = CONVERSION_ERROR; } return val; } else { val = strtod(str, &tmp); if (errno == EINVAL || tmp == str || *tmp != '\0') { goto conversion_error; } else if (errno == ERANGE) { self->code = OVERFLOW_ERROR; } else if (errno == EDOM) { self->code = CONVERSION_ERROR; } return val; } conversion_error: // Handle inf and nan values for xstrtod and platforms whose strtod // doesn't support this val = 1.0; tmp = str; if (*tmp == '+') { tmp++; } else if (*tmp == '-') { tmp++; val = -1.0; } if (0 == ascii_strncasecmp(tmp, "nan", 3)) { // Handle optional nan type specifier; this is ignored tmp += 3; val = NAN; } else if (0 == ascii_strncasecmp(tmp, "inf", 3)) { tmp += 3; if (0 == ascii_strncasecmp(tmp, "inity", 5)) { tmp += 5; } val *= INFINITY; } else { // Original (tmp == str || *tmp != '\0') case, no NaN or inf found self->code = CONVERSION_ERROR; val = 0; } return val; } // --------------------------------------------------------------------------- // Implementation of xstrtod // // strtod.c // // Convert string to double // // Copyright (C) 2002 Michael Ringgaard. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // 3. Neither the name of the project nor the names of its contributors // may be used to endorse or promote products derived from this software // without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF // SUCH DAMAGE. // // ----------------------------------------------------------------------- // Modifications by Warren Weckesser, March 2011: // * Rename strtod() to xstrtod(). // * Added decimal and sci arguments. // * Skip trailing spaces. // * Commented out the other functions. // Modifications by Richard T Guy, August 2013: // * Add tsep argument for thousands separator // Modifications by Michael Mueller, August 2014: // * Cache powers of 10 in memory to avoid rounding errors // * Stop parsing decimals after 17 significant figures // Modifications by Derek Homeier, August 2015: // * Recognise alternative exponent characters passed in 'sci'; try automatic // detection of allowed Fortran formats with sci='A' // * Require exactly 3 digits in exponent for Fortran-type format '8.7654+321' // Modifications by Derek Homeier, September-December 2016: // * Fixed some corner cases of very large or small exponents; proper return // * do not increment num_digits until nonzero digit read in // double xstrtod(const char *str, char **endptr, char decimal, char expchar, char tsep, int skip_trailing) { double number; int exponent; int negative; char *p = (char *) str; char exp; char sci; int num_digits; int num_decimals; int max_digits = 17; int num_exp = 3; int non_zero; int n; // Cache powers of 10 in memory static double e[] = {1., 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29, 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39, 1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, 1e48, 1e49, 1e50, 1e51, 1e52, 1e53, 1e54, 1e55, 1e56, 1e57, 1e58, 1e59, 1e60, 1e61, 1e62, 1e63, 1e64, 1e65, 1e66, 1e67, 1e68, 1e69, 1e70, 1e71, 1e72, 1e73, 1e74, 1e75, 1e76, 1e77, 1e78, 1e79, 1e80, 1e81, 1e82, 1e83, 1e84, 1e85, 1e86, 1e87, 1e88, 1e89, 1e90, 1e91, 1e92, 1e93, 1e94, 1e95, 1e96, 1e97, 1e98, 1e99, 1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109, 1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119, 1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129, 1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139, 1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149, 1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159, 1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169, 1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179, 1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189, 1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199, 1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209, 1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219, 1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229, 1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239, 1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249, 1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259, 1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269, 1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279, 1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289, 1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299, 1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308}; // Cache additional negative powers of 10 /* static double m[] = {1e-309, 1e-310, 1e-311, 1e-312, 1e-313, 1e-314, 1e-315, 1e-316, 1e-317, 1e-318, 1e-319, 1e-320, 1e-321, 1e-322, 1e-323}; */ errno = 0; // Skip leading whitespace while (isspace(*p)) p++; // Handle optional sign negative = 0; switch (*p) { case '-': negative = 1; // Fall through to increment position case '+': p++; } // No numerical value following sign - make no conversion and return zero, // resetting endptr to beginning of str (consistent with strtod behaviour) // E.g. -1.e0 and -.0e1 are valid, -.e0 is not! if (!(isdigit(*p) || (*p == decimal && isdigit(*(p + 1))))) { if (endptr) *endptr = (char *) str; return 0e0; } number = 0.; exponent = 0; num_digits = 0; num_decimals = 0; non_zero = 0; // Process string of digits while (isdigit(*p)) { if (num_digits < max_digits) { number = number * 10. + (*p - '0'); non_zero += (*p != '0'); if(non_zero) num_digits++; } else ++exponent; p++; p += (tsep != '\0' && *p == tsep); } // Process decimal part if (*p == decimal) { p++; while (num_digits < max_digits && isdigit(*p)) { number = number * 10. + (*p - '0'); non_zero += (*p != '0'); if(non_zero) num_digits++; num_decimals++; p++; } if (num_digits >= max_digits) // consume extra decimal digits while (isdigit(*p)) ++p; exponent -= num_decimals; } // Exactly 0 - no precision loss/OverflowError if (num_digits == 0) number = 0.0; // Correct for sign if (negative) number = -number; // Process an exponent string sci = toupper(expchar); if (sci == 'A') { // check for possible Fortran exponential notations, including // triple-digits with no character exp = toupper(*p); if (exp == 'E' || exp == 'D' || exp == 'Q' || *p == '+' || *p == '-') { // Handle optional sign negative = 0; switch (exp) { case '-': negative = 1; // Fall through to increment pos case '+': p++; break; case 'E': case 'D': case 'Q': switch (*++p) { case '-': negative = 1; // Fall through to increment pos case '+': p++; } } // Process string of digits n = 0; while (isdigit(*p)) { n = n * 10 + (*p - '0'); num_exp--; p++; } // Trigger error if not exactly three digits if (num_exp != 0 && (exp == '+' || exp == '-')) { errno = EDOM; number = 0.0; } if (negative) exponent -= n; else exponent += n; } } else if (toupper(*p) == sci) { // Handle optional sign negative = 0; switch (*++p) { case '-': negative = 1; // Fall through to increment pos case '+': p++; } // Process string of digits n = 0; while (isdigit(*p)) { n = n * 10 + (*p - '0'); p++; } if (negative) exponent -= n; else exponent += n; } // largest representable float64 is 1.7977e+308, closest to 0 ~4.94e-324, // but multiplying exponents in in two steps gives slightly better precision if (number != 0.0) { if (exponent > 305) { if (exponent > 308) // leading zeros already subtracted from exp number *= HUGE_VAL; else { number *= e[exponent-300]; number *= 1.e300; } } else if (exponent < -308) // subnormal { if (exponent < -616) // prevent invalid array access number = 0.; else { number /= e[-308-exponent]; number *= 1.e-308; } // trigger warning if resolution is > ~1.e-15; // strtod does so for |number| <~ 2.25e-308 // if (number > -4.94e-309 && number < 4.94e-309) errno = ERANGE; } else if (exponent > 0) number *= e[exponent]; else if (exponent < 0) number /= e[-exponent]; if (number >= HUGE_VAL || number <= -HUGE_VAL) errno = ERANGE; } if (skip_trailing) { // Skip trailing whitespace while (isspace(*p)) p++; } if (endptr) *endptr = p; return number; } void start_iteration(tokenizer_t *self, int col) { // Begin looping over the column string with index col self->iter_col = col; // Start at the initial pointer position self->curr_pos = self->output_cols[col]; } char *next_field(tokenizer_t *self, int *size) { char *tmp = self->curr_pos; // pass through the entire field until reaching the delimiter while (*self->curr_pos != '\x00') ++self->curr_pos; ++self->curr_pos; // next field begins after the delimiter if (*tmp == '\x01') // empty field; this is a hack { if (size) *size = 0; return self->buf; } else { if (size) *size = self->curr_pos - tmp - 1; return tmp; } } char *get_line(char *ptr, size_t *len, size_t map_len) { size_t pos = 0; while (pos < map_len) { if (ptr[pos] == '\r') { *len = pos; // Windows line break (\r\n) if (pos != map_len - 1 && ptr[pos + 1] == '\n') return ptr + pos + 2; // skip newline character else // Carriage return line break return ptr + pos + 1; } else if (ptr[pos] == '\n') { *len = pos; return ptr + pos + 1; } ++pos; } // done with input return 0; } void reset_comments(tokenizer_t *self) { free(self->comment_lines); self->comment_pos = 0; self->comment_lines_len = INITIAL_COMMENT_LEN; self->comment_lines = (char *) malloc(INITIAL_COMMENT_LEN); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/src/tokenizer.h0000644000175100001710000000767500000000000020436 0ustar00vstsdocker// Licensed under a 3-clause BSD style license - see LICENSE.rst #ifndef TOKENIZER_H #define TOKENIZER_H #include #include #include #include #include #include #include #include #ifdef _MSC_VER #define inline __inline #ifndef NAN static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff}; #define NAN (*(const double *) __nan) #endif #ifndef INFINITY static const unsigned long __infinity[2] = {0x00000000, 0x7ff00000}; #define INFINITY (*(const double *) __infinity) #endif #else #ifndef INFINITY #define INFINITY (1.0/0.0) #endif #ifndef NAN #define NAN (INFINITY-INFINITY) #endif #endif typedef enum { START_LINE = 0, START_FIELD, START_QUOTED_FIELD, FIELD, QUOTED_FIELD, QUOTED_FIELD_NEWLINE, QUOTED_FIELD_DOUBLE_QUOTE, COMMENT, } tokenizer_state; typedef enum { NO_ERROR, INVALID_LINE, TOO_MANY_COLS, NOT_ENOUGH_COLS, CONVERSION_ERROR, OVERFLOW_ERROR } err_code; typedef struct { char *source; // single string containing all of the input size_t source_len; // length of the input size_t source_pos; // current index in source for tokenization char delimiter; // delimiter character char comment; // comment character char quotechar; // quote character char expchar; // exponential character in scientific notation char newline; // EOL character char **output_cols; // array of output strings for each column char **col_ptrs; // array of pointers to current output position for each col size_t *output_len; // length of each output column string int num_cols; // number of table columns int num_rows; // number of table rows int fill_extra_cols; // represents whether or not to fill rows with too few values tokenizer_state state; // current state of the tokenizer err_code code; // represents the latest error that has occurred int iter_col; // index of the column being iterated over char *curr_pos; // current iteration position char *buf; // buffer for empty data int strip_whitespace_lines; // whether to strip whitespace at the beginning and end of lines int strip_whitespace_fields; // whether to strip whitespace at the beginning and end of fields int use_fast_converter; // whether to use the fast converter for floats char *comment_lines; // single null-delimited string containing comment lines int comment_lines_len; // length of comment_lines in memory int comment_pos; // current index in comment_lines } tokenizer_t; /* Example input/output -------------------- source: "A,B,C\n10,5.,6\n1,2,3" output_cols: ["A\x0010\x001", "B\x005.\x002", "C\x006\x003"] */ #define INITIAL_COL_SIZE 500 #define INITIAL_COMMENT_LEN 50 tokenizer_t *create_tokenizer(char delimiter, char comment, char quotechar, char expchar, int fill_extra_cols, int strip_whitespace_lines, int strip_whitespace_fields, int use_fast_converter); void delete_tokenizer(tokenizer_t *tokenizer); void delete_data(tokenizer_t *tokenizer); void resize_col(tokenizer_t *self, int index); void resize_comments(tokenizer_t *self); int skip_lines(tokenizer_t *self, int offset, int header); int tokenize(tokenizer_t *self, int end, int header, int num_cols); long str_to_long(tokenizer_t *self, char *str); double str_to_double(tokenizer_t *self, char *str); double xstrtod(const char *str, char **endptr, char decimal, char expchar, char tsep, int skip_trailing); void start_iteration(tokenizer_t *self, int col); char *next_field(tokenizer_t *self, int *size); long file_len(FILE *fhandle); char *get_line(char *ptr, size_t *len, size_t map_len); void reset_comments(tokenizer_t *self); #endif ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1032457 astropy-5.0.2/astropy/io/ascii/tests/0000755000175100001710000000000000000000000016607 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/__init__.py0000644000175100001710000000000000000000000020706 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/common.py0000644000175100001710000000523400000000000020455 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import os import numpy as np __all__ = ['raises', 'assert_equal', 'assert_almost_equal', 'assert_true', 'setup_function', 'teardown_function', 'has_isnan'] CWD = os.getcwd() TEST_DIR = os.path.dirname(__file__) has_isnan = True try: from math import isnan # noqa except ImportError: try: from numpy import isnan # noqa except ImportError: has_isnan = False print('Tests requiring isnan will fail') def setup_function(function): os.chdir(TEST_DIR) def teardown_function(function): os.chdir(CWD) # Compatibility functions to convert from nose to pytest def assert_equal(a, b): assert a == b def assert_almost_equal(a, b, **kwargs): assert np.allclose(a, b, **kwargs) def assert_true(a): assert a def make_decorator(func): """ Wraps a test decorator so as to properly replicate metadata of the decorated function, including nose's additional stuff (namely, setup and teardown). """ def decorate(newfunc): if hasattr(func, 'compat_func_name'): name = func.compat_func_name else: name = func.__name__ newfunc.__dict__ = func.__dict__ newfunc.__doc__ = func.__doc__ newfunc.__module__ = func.__module__ if not hasattr(newfunc, 'compat_co_firstlineno'): try: newfunc.compat_co_firstlineno = func.func_code.co_firstlineno except AttributeError: newfunc.compat_co_firstlineno = func.__code__.co_firstlineno try: newfunc.__name__ = name except TypeError: # can't set func name in 2.3 newfunc.compat_func_name = name return newfunc return decorate def raises(*exceptions): """Test must raise one of expected exceptions to pass. Example use:: @raises(TypeError, ValueError) def test_raises_type_error(): raise TypeError("This test passes") @raises(Exception) def test_that_fails_by_passing(): pass If you want to test many assertions about exceptions in a single test, you may want to use `assert_raises` instead. """ valid = ' or '.join([e.__name__ for e in exceptions]) def decorate(func): name = func.__name__ def newfunc(*arg, **kw): try: func(*arg, **kw) except exceptions: pass else: message = f"{name}() did not raise {valid}" raise AssertionError(message) newfunc = make_decorator(func)(newfunc) return newfunc return decorate ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1112466 astropy-5.0.2/astropy/io/ascii/tests/data/0000755000175100001710000000000000000000000017520 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/apostrophe.rdb0000644000175100001710000000013400000000000022373 0ustar00vstsdocker# first comment agasc_id n_noids n_obs 11S N N jean's 1 1 # second comment 335416352 3 8 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/apostrophe.tab0000644000175100001710000000006100000000000022371 0ustar00vstsdockeragasc_id n_noids n_obs jean's 1 1 335416352 3 8 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/bad.txt0000644000175100001710000000023100000000000021003 0ustar00vstsdocker# Extra column in last line "test 1a" test2 test3 test4 # fun1 fun2 fun3 fun4 top1 top2 top3 top4 hat1 hat2 hat3 hat4 hat5 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/bars_at_ends.txt0000644000175100001710000000037500000000000022712 0ustar00vstsdocker|obsid | redshift | X | Y | object | rad| |3102 | 0.32 | 4167 | 4085 | Q1250+568-A | 9| |3102 | 0.32 | 4706 | 3916 | Q1250+568-B | 14 | |877 | 0.22 | 4378 | 3892 | 'Source 82' | 12.5 | ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.0552416 astropy-5.0.2/astropy/io/ascii/tests/data/cds/0000755000175100001710000000000000000000000020271 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1112466 astropy-5.0.2/astropy/io/ascii/tests/data/cds/description/0000755000175100001710000000000000000000000022614 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/cds/description/ReadMe0000644000175100001710000000710100000000000023673 0ustar00vstsdockerJ/A+A/511/A56 Abundances of five open clusters (Pancino+, 2010) ================================================================================ Chemical abundance analysis of the open clusters Cr 110, NGC 2420, NGC 7789, and M 67 (NGC 2682). Pancino E., Carrera R., Rossetti, E., Gallart C. =2010A&A...511A..56P ================================================================================ ADC_Keywords: Clusters, open ; Stars, giant ; Equivalent widths ; Spectroscopy Keywords: stars: abundances - Galaxy: disk - open clusters and associations: general Abstract: The present number of Galactic open clusters that have high resolution abundance determinations, not only of [Fe/H], but also of other key elements, is largely insufficient to enable a clear modeling of the Galactic disk chemical evolution. To increase the number of Galactic open clusters with high quality measurements, we obtained high resolution (R~30000), high quality (S/N~50-100 per pixel), echelle spectra with the fiber spectrograph FOCES, at Calar Alto, Spain, for three red clump stars in each of five Open Clusters. We used the classical equivalent width analysis method to obtain accurate abundances of sixteen elements: Al, Ba, Ca, Co, Cr, Fe, La, Mg, Na, Nd, Ni, Sc, Si, Ti, V, and Y. We also derived the oxygen abundance using spectral synthesis of the 6300{AA} forbidden line. Description: Atomic data and equivalent widths for 15 red clump giants in 5 open clusters: Cr 110, NGC 2099, NGC 2420, M 67, NGC 7789. File Summary: -------------------------------------------------------------------------------- FileName Lrecl Records Explanations -------------------------------------------------------------------------------- ReadMe 80 . This file table1.dat 103 15 Observing logs and programme stars information table5.dat 56 5265 Atomic data and equivalent widths -------------------------------------------------------------------------------- See also: J/A+A/455/271 : Abundances of red giants in NGC 6441 (Gratton+, 2006) J/A+A/464/953 : Abundances of red giants in NGC 6441 (Gratton+, 2007) J/A+A/505/117 : Abund. of red giants in 15 globular clusters (Carretta+, 2009) Byte-by-byte Description of file: table.dat -------------------------------------------------------------------------------- Bytes Format Units Label Explanations -------------------------------------------------------------------------------- 1- 7 A7 --- Cluster Cluster name 9- 12 I4 --- Star 14- 20 F7.2 0.1nm Wave wave ? Wavelength in Angstroms 22- 23 A2 --- El a 24 I1 --- ion ?=0 - Ionization stage (1 for neutral element) 26- 30 F5.2 eV chiEx Excitation potential 32- 37 F6.2 --- loggf Logarithm of the oscillator strength 39- 43 F5.1 0.1pm EW ?=-9.9 Equivalent width (in mA) 46- 49 F4.1 0.1pm e_EW ?=-9.9 rms uncertainty on EW 51- 56 F6.3 --- Q ?=-9.999 DAOSPEC quality parameter Q (large values are bad) -------------------------------------------------------------------------------- Acknowledgements: Elena Pancino, elena.pancino(at)oabo.inaf.it ================================================================================ (End) Elena Pancino [INAF-OABo, Italy], Patricia Vannier [CDS] 23-Nov-2009 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/cds/description/table.dat0000644000175100001710000000016200000000000024374 0ustar00vstsdockerCr110 2108 6696.79 Al1 4.02 -1.42 29.5 2.2 0.289 Cr110 2108 6698.67 Al1 3.14 -1.65 58.0 2.0 0.325 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1112466 astropy-5.0.2/astropy/io/ascii/tests/data/cds/glob/0000755000175100001710000000000000000000000021214 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/cds/glob/ReadMe0000644000175100001710000007532100000000000022304 0ustar00vstsdockerB/cb Cataclysmic Binaries, LMXBs, and related objects (Ritter+, 2011) ================================================================================ Catalogue of cataclysmic binaries, low-mass X-ray binaries and related objects (7th Edition, rev. 7.14, September 2010) Ritter H., Kolb U. =2003A&A...404..301R ================================================================================ ADC_Keywords: Binaries, cataclysmic ; Binaries, X-ray ; Novae Keywords: catalogues - stars: novae, cataclysmic variables - stars: binaries: close Description (Release 7.15): Cataclysmic Binaries are semi-detached binaries consisting of a white dwarf or a white dwarf precursor primary and a low-mass secondary which is filling its critical Roche lobe. The secondary is not necessarily unevolved, it may even be a highly evolved star as for example in the case of the AM CVn-type stars. Low-Mass X-Ray Binaries are semi-detached binaries consisting of either a neutron star or a black hole primary, and a low-mass secondary which is filling its critical Roche lobe. Related Objects are detached binaries consisting of either a white dwarf or a white dwarf precursor primary and of a low-mass secondary. The secondary may also be a highly evolved star. The catalogue lists coordinates, apparent magnitudes, orbital parameters, and stellar parameters of the components and other characteristic properties of 880 cataclysmic binaries, 98 low-mass X-ray binaries and 319 related objects with known or suspected orbital periods together with a comprehensive selection of the relevant recent literature. In addition the catalogue contains a list of references to published finding charts for 1259 of the 1297 objects, and a cross- reference list of alias object designations. Literature published before 1 July 2010 has, as far as possible, been taken into account. Updated information will be provided regularly, currently every six months. Old editions include catalogue (5th edition), (6th edition) and (7th edition); the successive versions of the 7th edition are available in dedicated subdirectories (v7.00 tp v7.13) File Summary: -------------------------------------------------------------------------------- FileName Lrecl Records Explanations -------------------------------------------------------------------------------- ReadMe 80 . This file cbdata.dat 226 880 Catalogue of Cataclysmic Binaries lmxbdata.dat 228 98 Catalogue of Low-Mass X-Ray Binaries pcbdata.dat 216 319 Catalogue of Related Objects findrefs.dat 274 3230 References for finding charts cbrefs.dat 257 1937 References for cbdata.dat lmxbrefs.dat 236 291 References for lmxbdata.dat pcbrefs.dat 302 655 References for pcbdata.dat whoswho.txt 72 8927 *Names of objects, and references of designations whoswho1.dat 199 5052 *Alternative names in lexigraphical order whoswho2.dat 100 3595 *Provisional and Common designations whoswho5.dat 73 1453 *References to the catalogue acronyms -------------------------------------------------------------------------------- Note on whoswho.txt: contains the 3 parts whoswho1.dat to whoswho5.dat (without the bibcodes) Note on whoswho1.dat, whoswho2.dat, whoswho5.dat: formatted files corresponding to whoswho.txt -------------------------------------------------------------------------------- See also: http://www.MPA-Garching.MPG.DE/RKcat/ : Catalog Home page or http://physics.open.ac.uk/RKcat/ : Catalog Home page Byte-by-byte Description of file: cbdata.dat -------------------------------------------------------------------------------- Bytes Format Units Label Explanations -------------------------------------------------------------------------------- 1- 12 A12 --- Name Object name (G1) 14 A1 --- whoswho [*] * indicating that further alternative designations are in the whoswho1.dat file 16- 27 A12 --- AltName A frequently used alternative name (G2) 30- 31 I2 h RAh Right Ascension J2000 (hours) 33- 34 I2 min RAm Right Ascension J2000 (minutes) 36- 39 F4.1 s RAs [0,60]? Right Ascension J2000 (seconds) 41 A1 --- DE- Declination J2000 (sign) 42- 43 I2 deg DEd Declination J2000 (degrees) 45- 46 I2 arcmin DEm Declination J2000 (minutes of arc) 48- 49 I2 arcsec DEs [0,60]? Declination J2000 (seconds of arc) 51 A1 arcsec epos [0-9] Position accuracy in (G3) 53- 54 A2 --- Type1 Object type (3) 55 A1 --- u_Type1 [?:] Uncertainty flag for object type 57- 58 A2 --- Type2 Object type (3) 59 A1 --- u_Type2 [?:] Uncertainty flag for object type 61- 62 A2 --- Type3 Object type (3) 63 A1 --- u_Type3 [?:] Uncertainty flag for Object type 65- 66 A2 --- Type4 Object type (3) 67 A1 --- u_Type4 [?] Uncertainty flag for Object type 69 A1 --- l_mag1 [><] Limit flag for magnitude mag1 70- 73 F4.1 mag mag1 ? Apparent V (or B, b, g, R, I) magnitude at maximum brightness (4) 74 A1 --- f_mag1 [:BbgRiIJKprw] uncertainty flag/band for mag1 (w="white light") 76 A1 --- l_mag2 [><] Limit flag for magnitude mag2 77- 80 F4.1 mag mag2 ? Apparent V (or B, g, R) magnitude at mideclipse (5) 81 A1 --- f_mag2 [:?BbgRiKpw] uncertainty flag/band for mag2 83 A1 --- l_mag3 [><] Limit flag for magnitude mag3 84- 87 F4.1 mag mag3 ? Apparent V (or B, g, R) magnitude of outbursts (6) 88 A1 --- f_mag3 [:?BbgpRrw] uncertainty flag/band for mag3 90 A1 --- l_mag4 [><] Limit flag for magnitude mag4 91- 94 F4.1 mag mag4 ? Apparent V (or B, R) magnitude in superoutburst (7) 95 A1 --- f_mag4 [:?BgRUIpw] uncertainty flag/band for mag4 97-101 A5 d T1 Time interval between two subsequent outbursts (8) 103-107 A5 d T2 Time interval between two subsequent superoutbursts (8) 109-116 F8.6 d Orb.Per ? Orbital period, in case of object type DQ: spectroscopic period, if it is different from the photometric one 117 A1 --- u_Orb.Per [:*] Uncertainty flag for Orb.Per (9) 119-126 F8.6 d 2.__Per ? Second period (10) 127 A1 --- u_2.__Per Uncertainty flag for 2.__Per 128-137 F10.3 s 3.__Per ? Additional period in the system (11) 138 A1 --- f_3.__Per [:TQ] Flag for 3.__Per (12) 139-148 F10.3 s 4.__Per ? Additional period in the system (13) 149 A1 --- f_4.__Per [:T] ":" uncertainty flag for 4.__Per "T" flag indicating transient pulsations 151 A1 --- EB [D21 ] Flag indicating the occurrence of eclipses (G4) 152 A1 --- u_EB [?:] Uncertainty flag for EB 154 I1 --- SB [1,2]? Flag specifying the type of spectroscopic binary (G5) 155 A1 --- u_SB [:] Uncertainty flag for SB 157-163 A7 --- SpType2 Spectral type of the secondary (G6) 165-171 A7 --- SpType1 Spectral type of the primary (G6) 174 A1 --- l_M1/M2 Limit flag for M1/M2 175-179 F5.2 --- M1/M2 ? Mass ratio M1/M2 180 A1 --- u_M1/M2 Uncertainty flag for M1/M2 183-186 F4.2 --- e_M1/M2 ? Error of M1/M2 188 A1 --- l_Incl Limit flag for the orbital inclination 189-192 F4.1 deg Incl ? Orbital inclination 193 A1 --- u_Incl Uncertainty flag for the inclination 195-198 F4.1 deg e_Incl ? Error of orbital inclination 200 A1 --- l_M1 Limit flag for primary mass M1 201-205 F5.3 solMass M1 ? Primary mass M1 206 A1 --- u_M1 Uncertainty flag for primary mass M1 208-212 F5.3 solMass e_M1 ? Error of primary mass M1 214 A1 --- l_M2 Limit flag for secondary mass M2 215-219 F5.3 solMass M2 ? Secondary mass M2 220 A1 --- u_M2 Uncertainty flag for secondary mass M2 222-226 F5.3 solMass e_M2 ? Error of secondary mass M2 -------------------------------------------------------------------------------- Note (3): Object type coarsely characterised using the following abbreviations: AC = AM CVn star, spectrum devoid of hydrogen lines, subtype of NL AM = polar = AM Her system, subtype of NL, contains a synchronously or nearly synchronously rotating, magnetized white dwarf AS = subtype of AM, with a slowly asynchronously rotating, magnetized white dwarf BD = secondary star is a brown dwarf CP = coherent pulsator, contains a coherently pulsating white dwarf CV = cataclysmic variable of unspecified subtype DA = non-magnetic direct accretor DN = dwarf nova DQ = DQ Her star, contains a non-synchronously rotating, magnetized white dwarf; usually not seen in X-rays EG = extragalactic source ER = ER UMa star = SU UMa star with an extremely short supercycle GC = source in a globular cluster GW = contains a pulsating white dwarf of the GW Vir = PG 1159-035 type IP = intermediate polar, shows coherent X-ray period from a non-synchronously spinning, magnetized white dwarf; usually a strong X-ray source LA = low accretion rate polar (LARP), i.e. a somewhat detached magnetic CV/pre-CV N = classical nova Na = fast nova (decline from max. by 3mag in less than about 100days) Nb = slow nova (decline from max. by 3mag in more than about 100days) Nc = extremely slow nova (typical time scale of the decline from maximum: decades) NL = nova-like variable Nr = recurrent nova NS = system showing negative (nodal) superhumps PW = precessing white dwarf SH = non-SU UMa star showing either permanent or transient positive (apsidal) superhumps SS = supersoft X-ray source; CV with stationary hydrogen burning on the white dwarf SU = SU UMa star, subtype of DN SW = SW Sex star, subtype of NL UG = dwarf nova of either U Gem or SS Cyg subtype UL = ultra-luminous X-ray source UX = UX UMa star, subtype of NL VY = VY Scl star (anti dwarf nova), subtype of NL WZ = WZ Sge star = SU UMa star with an extremely long supercycle ZC = Z Cam star, subtype of DN ZZ = white dwarf shows ZZ Ceti-type pulsations Note (4): Apparent V magnitude at maximum brightness of: novae (N,Na,Nb,Nc,Nr) in minimum DN (UG,ZC,SU) in minimum NL (UX,AC) in normal state NL (DQ,IP,AM,VY) in high state. SS in high state. Note (5): In case of eclipses magnitude at mideclipse, of: novae (N,Na,Nb,Nc,Nr) in minimum DN (UG,ZC,SU) in minimum NL (UX,AC) in normal state NL (DQ,IP,AM,VY) in high state. SS in high state. Note (6): Apparent magnitude at maximum brightness of: novae (N,Na,Nb,Nc,Nr) in outburst DN (UG,ZC) in outburst DN (SU) in normal outburst DN (WZ) in echo outburst NL (AM,VY) in low state NL (DQ,IP) in low state SS in low state. Note (7): Apparent magnitude at maximum brightness of: DN (ZC) in standstill DN (SU) in superoutburst WZ in superoutburst NL (DQ,IP) in flaring state or outburst iNL (AM, VY) in low state SS in low state Note (8): Time interval between outbursts is defined: - for dwarf novae of subtype UG or ZC: the typical time interval between two subsequent outbursts; - for dwarf novae of subtype SU: T1 is the typical time interval between two subsequent normal outburst, and T2 is the typical time interval between subsequent superoutbursts. Note (9): the * indicates, in case of object type SU, that the orbital period has been estimated from the known superhump period using the empirical relation given by B. Stolz and R. Schoembs (1984A&A...132..187S). Note (10): The second period is, in case of object type: DQ or IP: photometric period if it is different from the spectroscopic one AM: polarization period = spin period of the white dwarf, if it is different from the presumed orbital period (subtype AS) SU: superhump period, wherever possible, at the beginning of a superoutburst SH: photometric period, presumably superhump period of either permanent or transient superhumps NS: photometric period, period of either permanent or transient negative superhumps if 2.__Per. < Orb.Per. Note (11): This additional period is, in case of object type: CP: period of coherent pulsation, (transient if f_3.__Per=T) DQ: spin period of the white dwarf IP: spin period of the white dwarf, usually detected in X-Rays SW: probably the spin period of the white dwarf Note (12): the flag takes the values: ':' uncertainty flag 'T' indicating transient pulsations 'Q' indicating the occurrence of quasi- periodic oscillations (QPO) in objects of type N, DN, NL. Note (13): This additional period is, in case of object type: CP: second period of coherent pulsation, (transient if f_4.__Per=T) DQ: additional period, presumably due to reprocessed X-Rays IP: additional period, usually seen in the optical and presumably due to reprocessed X-Rays -------------------------------------------------------------------------------- Byte-by-byte Description of file: lmxbdata.dat -------------------------------------------------------------------------------- Bytes Format Units Label Explanations -------------------------------------------------------------------------------- 1- 12 A12 --- Name Object name (G1) 14 A1 --- whoswho [*] * indicating that further alternative designations are in the whoswho1.dat file 16- 27 A12 --- AltName A frequently used alternative name (G2) 30- 31 I2 h RAh Right Ascension J2000 (hours) 33- 34 I2 min RAm Right Ascension J2000 (minutes) 36- 39 F4.1 s RAs Right Ascension J2000 (seconds) 41 A1 --- DE- Declination J2000 (sign) 42- 43 I2 deg DEd Declination J2000 (degrees) 45- 46 I2 arcmin DEm Declination J2000 (minutes of arc) 48- 49 I2 arcsec DEs Declination J2000 (seconds of arc) 51 A1 arcsec epos [0-9] Position accuracy in (G3) 53- 54 A2 --- Type1 Object type (3) 55 A1 --- u_Type1 [?] Uncertainty flag for object type 57- 58 A2 --- Type2 Object type (3) 59 A1 --- u_Type2 [?] Uncertainty flag for object type 61- 62 A2 --- Type3 Object type (3) 63 A1 --- u_Type3 [?] Uncertainty flag for Object type 65- 66 A2 --- Type4 Object type (3) 67 A1 --- u_Type4 [?] Uncertainty flag for Object type 69 A1 --- l_mag1 [><] Limit flag for magnitude mag1 70- 73 F4.1 mag mag1 ? Apparent V (or B, g, R, I, K) magnitude at maximum brightness, in case of XT in quiescence 74 A1 --- f_mag1 [:UBgRIJK] uncertainty flag/band for mag1 76 A1 --- l_mag2 [><] Limit flag for magnitude mag2 77- 80 F4.1 mag mag2 ? Apparent V (or B, R, I) magnitude at mid-eclipse (4) 81 A1 --- f_mag2 [:BRIJK] Uncertainty flag/band for mag2 84- 87 F4.1 mag mag3 ? Apparent V (or other) magnitude at outburst (5) 88 A1 --- f_mag3 [:BRI] Uncertainty flag/band for mag3 90 A1 --- l_mag4 Limit flag of magnitude mag4 91- 94 F4.1 mag mag4 ? Apparent V (or other) magnitude at superoutburst (5) 96 A1 --- l_LX/Lopt Limit flag on LX/Lopt 97-103 F7.1 --- LX/Lopt ? The ratio of X-ray to optical luminosity 106-108 I3 d T1 ? Typical time interval between two subsequent X-ray active states in case of subtype XT 110-118 F9.6 d Orb.Per ? Orbital period 119 A1 --- u_Orb.Per [:*] Uncertainty flag for Orb.Per (6) 120-128 F9.6 d 2.__Per ? Second period, in case of object type SH: photometric period, presumably superhump period of either permanent or transient superhumps 129 A1 --- u_2.__Per Uncertainty flag for 2.__Per 130-140 F11.7 s 3.__Per ? Additional period in the system, in case of object type BO: period of burst oscillations = rotation period of the neutron star; XP: pulse period of the pulsar 141 A1 --- u_3.__Per Uncertainty flag for 3.__Per 142-146 F5.1 s 4.__Per ? Additional period in the system, in case of object type XP: optical period, presumably due to e_processed X-Rays 152 A1 --- EB [D1 ] Occurrence of eclipses (G4) 153 A1 --- u_EB [?] Uncertainty flag on EB 155 I1 --- SB [1,2]? Flag specifying the type of spectroscopic binary (G5) 158-164 A7 --- SpType2 Spectral type of the secondary (G6) 167-173 A7 --- SpType1 Spectral type of the primary (G6) 175 A1 --- l_M1/M2 Limit flag for M1/M2 176-180 F5.2 --- M1/M2 ? Mass ratio M1/M2 181 A1 --- u_M1/M2 Uncertainty flag for M1/M2 182-186 F5.2 --- e_M1/M2 ? Error of M1/M2 189 A1 --- l_Incl Limit flag for the orbital inclination 190-193 F4.1 deg Incl ? Orbital inclination 194 A1 --- u_Incl Uncertainty flag (:) on Incl 196-199 F4.1 deg e_Incl ? Error of orbital inclination 201 A1 --- l_M1 Limit flag on M1 202-206 F5.2 solMass M1 ? Primary mass M1 207 A1 --- u_M1 Uncertainty flag (:) on M1 209-213 F5.2 solMass e_M1 ? Error of primary mass M1 215 A1 --- l_M2 Limit flag for secondary mass M2 216-221 F6.3 solMass M2 ? Secondary mass M2 222 A1 --- u_M2 Uncertainty flag (:) on M2 223-228 F6.3 solMass e_M2 ? Error of secondary mass M2 -------------------------------------------------------------------------------- Note (3): the object type is coarsely characterised using the following abbreviations: AS = atoll source, subtype of the LMXBs BH = black hole candidate, subtype of the LMXBs BO = X-ray burster with coherent burst oscillations at the neutron star spin period DC = source with an accretion disc corona, subtype of the LMXBs GC = source in a globular cluster MQ = microquasar, source of relativistic jets NS = system showing negative (nodal) superhumps QN = quiescent neutron star LMXB RP = primary is also seen as a radio pulsar SH = system showing either permanent or transient superhumps SS = supersoft X-ray source UL = ultra-luminous X-ray source XB = X-ray burst source XP = X-ray pulsar XT = transient X-ray source ZS = Z-source, subtype of the LMXBs Note (4): in case of eclipses magnitude at mideclipse, in case of XT in quiescence Note (5): in case of XL (XB, XT) in outburst Note (6): the * indicates, in case of object type SU, that the orbital period has been estimated from the known superhump period using the empirical relation given by B. Stolz and R. Schoembs (1984A&A...132..187S). -------------------------------------------------------------------------------- Byte-by-byte Description of file: pcbdata.dat -------------------------------------------------------------------------------- Bytes Format Units Label Explanations -------------------------------------------------------------------------------- 1- 12 A12 --- Name Object name (G1) 14 A1 --- whoswho [*] * indicating that further alternative designations are in the whoswho1.dat file 16- 27 A12 --- AltName A frequently used alternative name (G2) 30- 31 I2 h RAh ? Right Ascension J2000 (hours) 33- 34 I2 min RAm ? Right Ascension J2000 (minutes) 36- 39 F4.1 s RAs ? Right Ascension J2000 (seconds) 41 A1 --- DE- ? Declination J2000 (sign) 42- 43 I2 deg DEd ? Declination J2000 (degrees) 45- 46 I2 arcmin DEm ? Declination J2000 (minutes of arc) 48- 49 I2 arcsec DEs ? Declination J2000 (seconds of arc) 51 A1 arcsec epos [0-9P] Position accuracy (G3) 53- 54 A2 --- Type1 Object type (3) 55 A1 --- u_Type1 [?] Uncertainty flag for object type 57- 58 A2 --- Type2 Object type (3) 59 A1 --- u_Type2 [?] Uncertainty flag for object type 61- 62 A2 --- Type3 Object type (3) 63 A1 --- u_Type3 [?] Uncertainty flag for object type 65- 66 A2 --- Type4 Object type (3) 70- 73 F4.1 mag mag1 ? Apparent V (or other) magnitude at maximum brightness outside eclipse 74 A1 --- f_mag1 [:BbpgRiIK] uncertainty flag/band for mag1 76 A1 --- l_mag2 [><] Limit flag for magnitude mag2 77- 80 F4.1 mag mag2 ? Apparent V (or other) magnitude at minimum brightness, in case of eclipses magnitude at mideclipse. 81 A1 --- f_mag2 [:BgRiI] uncertainty flag/band for mag2 82- 90 F9.6 d Orb.Per Orbital period 91 A1 --- u_Orb.Per Uncertainty flag for Orb.Per 92-101 F10.4 s 2.__Per ? Spin period of the accretor (white dwarf or neutron star). 103 I1 --- EB [1,2]? Flag indicating the occurrence of eclipses (G4) 104 A1 --- u_EB [?] Uncertainty flag for EB 106 I1 --- SB [1,2]? Flag specifying the type of spectroscopic binary (G5) 109-115 A7 --- SpType2 Spectral type of the secondary (G6) 117-123 A7 --- SpType1 Spectral type of the primary (G6) 125 A1 --- l_E [><] Limit flag for the orbital eccentricity 126-129 F4.2 --- E ? Orbital eccentricity 130 A1 --- u_E Uncertainty flag on orbital eccentricity 132-135 F4.2 --- e_E ? Error of orbital eccentricity 137 A1 --- l_M1/M2 Limit flag for mass ratio M1/M2 138-141 F4.2 --- M1/M2 ? Mass ratio M1/M2 142 A1 --- u_M1/M2 Uncertainty flag on mass ratio M1/M2 144-147 F4.2 --- e_M1/M2 ? Error of M1/M2 149 A1 --- l_Incl Limit flag for the orbital inclination 150-153 F4.1 deg Incl ? Orbital inclination 154 A1 --- u_Incl Uncertainty flag for the inclination 156-159 F4.1 deg e_Incl ? Error of orbital inclination 161 A1 --- l_M1 Limit flag for primary mass M1 162-166 F5.3 solMass M1 ? Primary mass M1 167 A1 --- u_M1 Uncertainty flag for primary mass M1 169-173 F5.3 solMass e_M1 ? Error of primary mass M1 175 A1 --- l_R1 Limit flag for primary radius R1 176-180 F5.3 solRad R1 ? Primary radius 181 A1 --- u_R1 Uncertainty flag [:] for primary radius R1 183-187 F5.3 solRad e_R1 ? Error of primary radius R1 189 A1 --- l_M2 Limit flag for secondary mass M2 190-194 F5.3 solMass M2 ? Secondary mass M2 195 A1 --- u_M2 Uncertainty flag for secondary mass M2 197-201 F5.3 solMass e_M2 ? Error of secondary mass M2 203 A1 --- l_R2 Limit flag on secondary radius R2 204-209 F6.4 solRad R2 ? Secondary radius R2 210 A1 --- u_R2 Uncertainty flag [:] for secondary radius R2 212-217 F6.4 solRad e_R2 ? Error of secondary radius -------------------------------------------------------------------------------- Note (3): Object type coarsely characterised using the following abbreviations: CP = coherent pulsator, contains a coherently pulsating white dwarf or subdwarf DD = system consists of two degenerate components DS = detached system EC = contains a pulsating sdB star of the EC 14026-2647 type GC = source in a globular cluster GP = sdB-star with g-mode pulsations GW = contains a pulsating white dwarf of the GW Vir = PG 1159-035 type PN = central star of a planetary nebula RS = system shows RS CVn-like chromospheric activity SC = sub-stellar companion -------------------------------------------------------------------------------- Byte-by-byte Description of file: *refs.dat -------------------------------------------------------------------------------- Bytes Format Units Label Explanations -------------------------------------------------------------------------------- 1- 12 A12 --- Name Object name 14- 32 A19 --- BibCode BibCode 34-302 A269 --- Text Text of reference -------------------------------------------------------------------------------- Byte-by-byte Description of file: whoswho1.dat -------------------------------------------------------------------------------- Bytes Format Units Label Explanations -------------------------------------------------------------------------------- 1 A1 --- B [B] when the name is based on B1950 position 2- 25 A24 --- Name Object name 27 A1 --- --- [=] 29-212 A184 --- AltName Other name, or comment (1) -------------------------------------------------------------------------------- Note (1): Catalogue designations involving the equatorial coordinates are given in the following format: HHMM+DDMM (catalogue acronyms) if the position is given in B1950 coordinates -- a 'B' is then present in byte 1. JHHMM+DDMM (catalogue acronyms) if the position is given in J2000 coordinates. Here HHMM is the truncated right ascension in hours (HH) and minutes (MM), DDMM the truncated declination in degrees (DD) and arcminutes (MM), and + the sign of the declination. -------------------------------------------------------------------------------- Byte-by-byte Description of file: whoswho2.dat -------------------------------------------------------------------------------- Bytes Format Units Label Explanations -------------------------------------------------------------------------------- 1 A1 --- B [B] when the name is based on B1950 position 2- 53 A52 --- cName Common or Provisional designation (G2) 55- 56 A2 --- --- [->] 58-101 A44 --- Name Usual name -------------------------------------------------------------------------------- Byte-by-byte Description of file: whoswho5.dat -------------------------------------------------------------------------------- Bytes Format Units Label Explanations -------------------------------------------------------------------------------- 1- 10 A10 --- Abbr Catalogue abbreviation 14- 73 A60 --- Text Text of References -------------------------------------------------------------------------------- Global Notes: Note (G1): Wherever possible, the designation of the object given in the General Catalogue of Variable Stars (Cat. ) is used here. Note (G2): The acronyms used in lists are detailed in the last part of the file "whoswho.txt" Note (G3): The number indicates the accuracy of position in seconds of arc. If the positional error is larger than 9arcsec, or unknown, this field is left blank. The letter [P] indicates an object with a large proper motion. Note (G4): The EB flag means: EB= : (blank) no eclipses observed. EB=1: 1 eclipse per orbital revolution observed. EB=2: 2 eclipses per orbital revolution observed. EB=D: periodic eclipse-like dips observed. Note (G5): The SB flag means: SB=1: single-line spectroscopic binary SB=2: double-line spectroscopic binary Note (G6): Spectral types are given in the following format: [Spectral class/Luminosity class], where the usual roman numerals for the latter are replaced by the corresponding arabic numerals, i.e. I = 1, II = 2, III = 3, IV = 4, V = 5, VI = 6. -------------------------------------------------------------------------------- History: * 16-Apr-2003: 7th Edition * 28-Aug-2003: 7.1 Edition * 12-Mar-2004: 7.2 Edition * 01-Sep-2004: 7.3 Edition * 24-Mar-2005: 7.4 Edition * 25-Jul-2005: 7.5 Edition * 01-Feb-2006: 7.6 Edition * 29-May-2006: 7.6rev1 Edition (no new object) * 07-Dec-2006: 7.7 Edition * 17-Aug-2007: 7.8 Edition * 18-Mar-2008: 7.9 Edition * 26-Jul-2008: 7.10 Edition * 06-Apr-2009: 7.11 Edition * 18-Sep-2009: 7.12 Edition * 20-Mar-2010: 7.13 Edition * 05-Nov-2010: 7.14 Edition * 23-Mar-2011: 7.15 Edition References: Ritter H., 1984A&AS...57..385R (3rd edition) Ritter H., 1987A&AS...70..335R (4th edition) Ritter H., 1990A&AS...85.1179R (5th edition) (Catalogue: V/59) Ritter H., Kolb U., 1995, in "X-ray Binaries", Lewin W.H.G, van Paradijs J., van den Heuvel E.P. (eds), Cambridge Univ. Press, p. 578 (Cat. ) ================================================================================ (End) H. Ritter, U. Kolb [MPA Garching], Francois Ochsenbein [CDS] 05-Nov-2010 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/cds/glob/lmxbrefs.dat0000644000175100001710000007645000000000000023544 0ustar00vstsdockerLZ Aqr 2002ApJ...581..570T Tomsick, J.A., Heindl, W.A., Chakrabarty, D., Kaaret, P. 2002, ApJ 581, 570 (Orb.Per., Spectr2) LZ Aqr 2003ApJ...585..443S Shahbaz, T., et al. (7 authors) 2003, ApJ 585, 443 (M1/M2, Incl, M1, M2) LZ Aqr 2004ApJ...610..933T Tomsick, J.A., Gelino, D.M., Halpern, J.P., Kaaret, P. 2004, ApJ 610, 933 V1333 Aql 1998IAUC.6806Q...1M Chevalier, C., Ilovaisky, S.A. 1998, IAU Circ. No. 6806 (Orb.Per.) V1333 Aql 1999A&A...347L..51C Chevalier, C., Ilovaisky, S.A., Leisy, P., Patat, F. 1999, A&A 347, L51 (Spectr2) V1333 Aql 2007MNRAS.375.1463C Cornelisse, R., et al. (7 authors) 2007, MNRAS 375, 1463 (M1) V1333 Aql 2008ApJ...674L..41C Casella, P., Altamirano, D., Wijnands, R., van der Klis, M. 2008, ApJ 674, L41 (3. Per.) V1405 Aql 2001ApJ...549L..85G Galloway, D.K., Chakrabarty, D., Muno, M.P., Savov, P. 2001, ApJ 549, L85 (3. Per.) V1405 Aql 2001MNRAS.322..827H Homer, L., et al. (7 authors) 2001, MNRAS 322, 827 (Orb.Per., 2. Per.) V1405 Aql 2006ApJ...647.1341I Iaria, R., Di Salvo, T., Lavagetto, G., Robba, N.R., Burderi, L. 2006, ApJ 647, 1341 V1405 Aql 2006MNRAS.370..255N Nelemans, G., Jonker, P.G., Steeghs, D. 2006, MNRAS 370, 255 V1405 Aql 2008ApJ...680.1405H Hu, C.-P., Chou, Y., Chung, Y.-Y. 2008, ApJ 680, 1405 (Orb.Per.) V1408 Aql 2010MNRAS.402.2671R Russell, D.M., et al. (6 authors) 2010, MNRAS 402, 2671 V1408 Aql ................... Bayless, A., Robinson, E.L., Mason, P.A., Robertson, P. 2011, ApJ, in press = arXiv:1004.4904 (Orb.Per.) V1487 Aql 1994Natur.371...46M Mirabel, I.F., Rodriguez, L.F. 1994, Nat 371, 46 (Incl) V1487 Aql 2004A&A...414L..13H Harlaftis, E.T., Greiner, J. 2004, A&A 414, L13 (Spectr2, M1/M2, Incl, M1, M2) V1487 Aql 2007ApJ...668..430D Dhawan, V., Mirabel, I.F., Ribo, M., Rodrigues, I. 2007, ApJ 668, 430 V1487 Aql 2007ApJ...657..409N Neil, E.T., Bailyn, C.D., Cobb, B.E. 2007, ApJ 657, 409 (Orb.Per., 2. Per.) V801 Ara 1986ApJ...305..246F Fujimoto, M.Y., Taam, R.E. 1986, ApJ 305, 246 (M1) V801 Ara 2002ApJ...568..279G Giles, A.B., Hill, K.M., Strohmayer, T.E., Cummings, N. 2002, ApJ 568, 279 (Orb.Per., 3. Per) V801 Ara 2002ApJ...577..377M Strohmayer, T.E., Markwardt, C.B. 2002, ApJ 577, 377 (3. Per.) V801 Ara 2006MNRAS.373.1235C Casares, J., et al. (7 authors) 2006, MNRAS 373, 1235 (Orb.Per.) V821 Ara 2002MNRAS.331.1065C Chaty, S., et al. (7 authors) 2002, MNRAS 331, 1065 (Spectr2) V821 Ara 2003ApJ...583L..95H Hynes, R.I., Steeghs, D., Casares, J., Charles, P.A., O'Brien, K. 2003, ApJ 583, L95 (Orb.Per., M1/M2, M1) V821 Ara 2008ApJ...679L.113M Miller, J.M., et al. (9 authors) 2008, ApJ 679, L113 V821 Ara 2008MNRAS.385.2205M Munoz-Darias, T., Casares, J., Martinez-Pais, I.G. 2008, MNRAS 385, 2205 V395 Car 1999A&A...344..101S Shahbaz, T., et al. (6 authors) 1999, A&A 344, 101 (Spectr2) V395 Car 2004ApJ...616L.123S Shahbaz, T., et al. (7 authors) 2004, ApJ 616, L123 (Orb.Per.) V395 Car 2005MNRAS.356..621J Jonker, P.G., Steeghs, D., Nelemans, G., van der Klis, M. 2005, MNRAS 356, 621 (Orb.Per.) V395 Car 2007A&A...474..969S Shahbaz, T., Watson, C.A. 2007, A&A 474, 969 V395 Car 2007ApJ...669L..85S Steeghs, D., Jonker, P.G. 2007, ApJ 669, L85 (M1/M2, Incl, M1, M2) V822 Cen 2007A&A...470.1033C Casares, J., Bonifacio, P., Gonzalez Hernandez, J.I., Molaro, P., Zoccali, M. 2007, A&A 470, 1033 (Orb.Per., M1/M2, Incl, M1, M2) V822 Cen 2010ApJ...716.1105K Khargaria, J., Froning, C.S., Robinson, E.L. 2010, ApJ 716, 1105 (Spectr2, Incl, M1) BW Cir 2004ApJ...613L.133C Casares, J., Zurita, C., Shahbaz, T., Charles, P.A., Fender, R. 2004, ApJ 613, L133 ( Spectr2) BW Cir 2009ApJS..181..238C Casares, J., et al. (11 authors) 2009, ApJS 181, 238 (Orb.Per., M1/M2, Incl, M1, M2) V691 CrA 2003MNRAS.339..663J Jonker, P.G., van der Klis, M., Groot, P.J. 2002, MNRAS 339, 663 (Incl) V691 CrA 2005ApJ...635..502M Munoz-Darias, T., Casares, J., Martinez-Pais, I.G. 2005, ApJ 635, 502 (M1/M2, M1, M2) V691 CrA 2010ApJ...709..251B Bayless, A.J., Robinson, E.L., Cornell, M.E., Hynes, R.I., Ashcraft, T.A. 2010, ApJ 709, 251 (Orb.Per.) V691 CrA 2010A&A...515A...1A Burderi, L., et al. (7 authors) 2010, A&A 515, A44 (Orb.Per.) V691 CrA 2010MNRAS.409..755J Jain, C., Paul, B., Dutta, A. 2010, MNRAS 409, 755 (Orb.Per., 3. Per.) UW CrB 2008ApJ...685..428M Mason, P.A., Robinson, E.L., Gray, C.L., Hynes, R.I. 2008, ApJ 685, 428 (Orb.Per., 2. Per.) UW CrB 2009MNRAS.394..892H Hakala, P., Hjalmarsdotter, L., Hannikainen, D., Muhli, P. 2009, MNRAS 394, 892 (Orb.Per., 2. Per.) UW CrB 2009ApJ...690.1145N Narita, T., Palmieri, J.B., Tow, E.S. 2009, ApJ 690, 1145 V404 Cyg 1993MNRAS.265..834C Casares, J., Charles, P.A., Naylor, T., Pavlenko, E.P. 1993, MNRAS 265, 834 (2. Per.) V404 Cyg 1994MNRAS.271L...5C Casares, J., Charles, P.A. 1994, MNRAS 271, L5 (Orb.Per., M1/M2) V404 Cyg 1994MNRAS.271L..10S Shahbaz, T., et al. (6 authors) 1994, MNRAS 271, L10 (Incl, M2) V404 Cyg 1996MNRAS.282..977S Shahbaz, T., Bandyopadhyay, R., Charles, P.A., Naylor, T. 1996, MNRAS 282, 977 (M1) V404 Cyg 2009ApJ...706L.230M Miller-Jones, J.C.A., et al. (7 authors) 2009, ApJ 706, L230 V404 Cyg 2010ApJ...716.1105K Khargaria, J., Froning, C.S., Robinson, E.L. 2010, ApJ 716, 1105 (Spectr2, Incl, M1) V1341 Cyg 1998ApJ...493L..39C Casares, J., Charles, P.A., Kuulkers, E. 1997, ApJ 493, L39 (Spectr2) V1341 Cyg 2009MNRAS.395.2029E Elebert, P., Callanan, P.J., Torres, M.A.P., Garcia, M.R. 2009, MNRAS 395, 2029 V1341 Cyg 2010MNRAS.401.2517C Casares, J., Gonzalez Hernandez, J.I., Israelian, G., Rebolo, R. 2010, MNRAS 401, 2517 (Orb.Per., M1/M2, Incl, M1, M2) V1341 Cyg ................... Sazonov, A.N. 2010, arXiv:1011.3980 V1727 Cyg 1996MNRAS.282.1437S Shahbaz, T. et al. (7 authors) 1996, MNRAS 282, 1437 (Spectr2) V1727 Cyg 2007A&A...476..301B Bozzo, E., et al. (11 authors) 2007, A&A 476, 301 (Orb.Per.) V1727 Cyg 2008A&A...485..773B Bothwell, M.S., Torres, M.A.P., Garcia, M.R., Charles, P.A. 2008, A&A 485, 773 V1727 Cyg 2009ApJ...706.1069L Lin, J., Nowak, M.A., Chakrabarty, D. 2009, ApJ 706, 1069 (Orb.Per.) IL Lup 1998ApJ...499..375O Orosz, J.A., Jain, R.K., Bailyn, C.D., McClintock, J.E., Remillard, J.A. 1998, ApJ 499, 375 (Spectr2, M2) IL Lup ................... Orosz, J.A. 2003, in: A Massive Star Odyssey: From Main Sequence to Supernova, K.A. van der Hucht, A. Herrero, C. Esteban (eds.), IAU Symp. No. 212, ASP, San Francisco, p. 365 (Orb.Per., M1/M2, Incl, M1) IL Lup 2004ApJ...615..880B Buxton, M.M., Bailyn, C.D. 2004, ApJ 615, 880 IL Lup 2004ApJ...610..378P Park, S.Q., et al. (11 authors) 2004, ApJ 610, 378 V616 Mon 2007ApJ...663.1215F Froning, C.S., Robinson, E.L., Bitner, M.A. 2007, ApJ 663, 1215 (Spectr2, Incl) V616 Mon 2007AJ....133..162H Harrison, T.E., Howell, S.B., Szkody, P., Cordova, F.A. 2007, AJ 133, 162 (Spectr2) V616 Mon 2008ApJ...673L.159C Cantrell, A.G., Bailyn, C.D., McClintock, J.E., Orosz, J.A. 2008, ApJ 673, L159 V616 Mon 2008MNRAS.384..849N Neilsen, J., Steeghs, D., Vrtilek, S.D. 2008, MNRAS 384, 849 V616 Mon 2010ApJ...710.1127C Cantrell, A.G., et al. (9 authors) 2010, ApJ 710, 1127 (Spectr2, M1/M2, Incl, M1, M2) V616 Mon 2010A&A...516A...1L Gonzalez Hernandez, J.I., Casares, J. 2010, A&A 516, A58 (Orb.Per.) GR Mus 1987ApJ...313..792M Motch, C., Pedersen, H., Beuermann, K., Pakull, M.W., Courvoisier, T.J.-L. 1987, ApJ 313, 792 (Incl) GR Mus 2007MNRAS.380.1182B Barnes, A.D., et al. (7 authors) 2007, MNRAS 380, 1182 (M1/M2, M1, M2) GR Mus 2007MNRAS.377..198B Bhattacharyya, S. 2007, MNRAS 377, 198 (3. Per.) GR Mus 2009A&A...493..145D Diaz Trigo, M., et al. (6 authors) 2009, A&A 493, 145 (Orb.Per.) GU Mus 1994ApJ...436..848O Orosz, J., Bailyn, C.D., Remillard, R.A., McClintock, J.E., Foltz, C.B. 1994, ApJ 436, 848 (M1/M2) GU Mus 1996MNRAS.282..191O O'Donoghue, D., Charles, P.A. 1996, MNRAS 282, 191 (2. Per.) GU Mus 1996ApJ...468..380O Orosz, J.A., Bailyn, C.D., McClintock, J.E., Remillard, R.A. 1996, ApJ 468, 380 (Orb.Per., M2) GU Mus 1997NewA....1..299C Casares, J., Martin, E.L., Charles, P.A., Molaro, P., Rebolo, R. 1997, New Astron. 1, 299 (Orb.Per., Spectr2) GU Mus 2001AJ....122..971G Gelino, D.M., Harrison, T.E., McNamara, B.J. 2001, AJ 122, 971 (Incl, M1) GU Mus 2002A&A...391..993S Sutaria, F.K., et al. (10 authors) 2002, A&A 391, 993 GU Mus 2003MNRAS.340..447H Hynes, R.I., et al. (6 authors) 2003, MNRAS 340, 447 QX Nor 2002ApJ...568..901W Wachter, S., Hoard, D.W., Bailyn, C.D., Corbel, S., Kaaret, P. 2002, ApJ 568, 901 (Orb.Per.) QX Nor ................... Strohmayer, T., Bildsten, L. 2006, in: Compact Stellar X-Ray Sources, W.H.G. Lewin, and M. van der Klis (eds.), Cambridge Astrophysics Series 39, Cambridge University Press, Cambridge, p. 113 (3. Per.) QX Nor 2008A&A...479..177K Keek, L., et al. (6 authors) 2008, A&A 479, 177 QX Nor 2010ApJ...712..964G Guever, T., Oezel, F., Cabrera-Lavers, A., Wroblewski, P. 2010, ApJ 712, 964 (M1) V381 Nor 2002ApJ...568..845O Orosz, J.A., et al. (9 authors) 2002, ApJ 568, 845 (Orb.Per, Spectr2, M1/M2, Incl, M1, M2) V381 Nor 2004MNRAS.353..980K Kubota, A., Done, C. 2004, MNRAS 353, 980 V2107 Oph 1996ApJ...459..226R Remillard, R.A., Orosz, J.A., McClintock, J.E., Bailyn, C.D. 1996, ApJ 459, 226 (Orb.Per.) V2107 Oph 1997PASP..109..461F Filippenko, A.V., Matheson, T., Leonard, D.C., Barth, A.J., van Dyk, S.D. 1997, PASP 109, 461 (Incl, M1, M2) V2107 Oph 1997AJ....114.1170H Harlaftis, E.T., Steeghs, D., Horne, K., Filippenko, A.V. 1997, AJ 114, 1170 (Spectr2, M1/M2) V2134 Oph 1984ApJ...283..765C Cominsky, L.R., Wood, K.S. 1984, ApJ 283, 765 (Incl) V2134 Oph 2001A&A...376..532O Oosterbroek, T., Parmar, A.N., Sidoli, L., in 't Zand, J.J.M., Heise, J. 2001, A&A 376, 532 (Orb.Per.) V2134 Oph 2006MNRAS.372..479C Cackett, E.M., et al. (6 authors) 2006, MNRAS 372, 479 V2216 Oph 2006MNRAS.368..781K Kong, A.K.H., Charles, P.A., Homer, L., Kuulkers, E., O'Donoghue, D. 2006, MNRAS 368, 781 (Orb.Per.) V2216 Oph 2007MNRAS.380.1219C Cornelisse, R., et al. (7 authors) 2007, MNRAS 380, 1219 (Orb.Per.) V2216 Oph 2009ApJ...696.1987H Harris, R.J., et al. (6 authors) 2009, ApJ 696, 1987 (Orb.Per.) V2293 Oph 1996A&A...314..123M Masetti, N., Bianchini, A., Bonibaker, J., Della Valle, M., Vio, R. 1996, A&A 314, 123 (2. Per.) V2293 Oph 2002MNRAS.331.1065C Chaty, S., et al. (7 authors) 2002, MNRAS 331, 1065 (Spectr2) V1055 Ori 2006MNRAS.370..255N Nelemans, G., Jonker, P.G., Steeghs, D. 2006, MNRAS 370, 255 (Orb.Per., 2. Per.) V1055 Ori 2008PASP..120..848S Shahbaz, T., Watson, C.A., Zurita, C., Villaver, E., Hernandez-Peralta, H. 2008, PASP 120, 848 V1055 Ori 2008ApJ...672L..37S Strohmayer, T.E., Markwardt, C.B., Kuulkers, E. 2008, ApJ 672, L37 (3. Per.) V518 Per 2000MNRAS.317..528W Webb, N.A., Naylor, T., Ioannou, Z., Charles, P.A., Shahbaz, T. 2000, MNRAS 317, 528 (Orb. Per., M1/M2) V518 Per 2003ApJ...599.1254G Gelino, D.M., Harrison, T.E. 2003, ApJ 599, 1254 (Spectr2, Incl, M1, M2) V518 Per 2007MNRAS.374..657R Reynolds, M.T., Callanan, P.J., Fillipenko, A.V. 2007, MNRAS 374, 657 V518 Per 2009PASJ...61....1I Kato, T., et al. (130 authors) 2009, PASJ 61, S395 (2. Per.) V4134 Sgr 1985MNRAS.216.1033M Mason, K.O., Parmar, A.N., White, N.E. 1985, MNRAS 216, 1033 (Orb.Per.) V4134 Sgr 2006ApJ...641..410K Kaaret, P., et al. (7 authors) 2006, ApJ 641,410 V4580 Sgr 2008MNRAS.391.1619D Deloye, C.J., Heinke, C.O., Taam, R.E., Jonker, P.G. 2008, MNRAS 391, 1619 V4580 Sgr 2008MNRAS.389.1851S Di Salvo, T., Burderi, L., Riggio, A., Papitto, A., Menna, M.T. 2008, MNRAS 389, 1851 V4580 Sgr 2008ApJ...675.1468H Hartman, J.M., et al. (9 authors) 2008, ApJ 675, 1468 (Orb.Per., 3. Per.) V4580 Sgr 2009A&A...496L..17B Burderi, L., et al. (7 authors) 2009, A&A 496, L17 (Orb.Per., 3. Per.) V4580 Sgr 2009ApJ...694L..21C Cackett, E.M., et al. (7 authors) 2009, ApJ 694, L21 (Incl) V4580 Sgr 2009A&A...495L...1C Cornelisse, R., et al. (9 authors) 2009, A&A 495, L1 V4580 Sgr 2009MNRAS.395..884E Elebert, P., et al. (11 authors) 2009, MNRAS 395, 884 (M1/M2, M1, M2) V4580 Sgr 2009ApJ...702.1673H Hartman, J.M., et al. (7 authors) 2009, ApJ 702, 1673 (Orb.Per., 3. Per.) V4580 Sgr 2009ApJ...691.1035H Heinke, C.O., Jonker, P.G., Wijnands, R., Deloye, C.J., Taam, R.E. 2009, ApJ 691, 1035 V4580 Sgr 2009MNRAS.400..492I Ibragimov, A., Poutanen, J. 2009, MNRAS 400, 492 (Incl) V4580 Sgr 2009ApJ...698L..60P Patruno, A., Wijnands, R., van der Klis, M. 2009, ApJ 698, L60 (3. Per.) V4580 Sgr 2009ApJ...694.1115W Wang, Z., Bassa, C., Cumming, A., Kaspi, V.M. 2009, ApJ 694, 1115 V4634 Sgr 2005ApJ...634.1261T Thompson, T.W.J., Rothschild, R.E., Tomsick, J.A., Marshall, H.L. 2005, ApJ 634, 1261 (3. Per.) V4634 Sgr 2010AstL...36..738M Meshcheryakov, A.V., Revnivtsev, M.G., Pavlinsky, M.N., Khamitov, I., Bikmaev, I.F. 2010, Astron. Letters 36, 738 (Orb.Per.) V4641 Sgr 2001IBVS.5068....1G Goranskij, V.P. 2001, IBVS No. 5068 (Orb.Per.) V4641 Sgr 2001ApJ...555..489O Orosz, J., et al. (9 authors) 2001, ApJ 555, 489 (Orb.Per.) V4641 Sgr ................... Orosz, J.A. 2003, in: A Massive Star Odyssey: From Main Sequence to Supernova, K.A. van der Hucht, A. Herrero, C. Esteban (eds.), IAU Symp. No. 212, ASP, San Francisco, P. 365 (M1/M2, Incl, M1, M2) V4641 Sgr 2006PASJ...58..595S Sadakane, K, et al. (13 authors) 2006, PASJ, 58, 595 V5511 Sgr 2007MNRAS.375..971P Papitto, A., et al. (6 authors) 2006, MNRAS 375, 971 (Orb.Per., 3. Per.) V5511 Sgr 2008MNRAS.391..254C Chung, C.T.Y., Galloway, D.K., Melatos, A. 2008, MNRAS 391, 254 (Orb.Per., 3. Per.) V5511 Sgr 2009ApJ...698L..60P Patruno, A., Wijnands, R., van der Klis, M. 2009, ApJ 698, L60 (3. Per.) V818 Sco 2003A&A...398L..25M Mirabel, I.F., Rodrigues, I. 2003, A&A 398, L25 V818 Sco 2003PASP..115..739V Vanderlinde, K.W., Levine, A.M., Rappaport, S.A. 2003, PASP 115, 739 (Orb.Per.) V926 Sco 1998A&A...332..561A Augusteijn, T., van der Hooft, F., de Jong, J.A., van Kerkwijk, M.H., van Paradijs, J. 1998, A&A 332, 561 (Orb.Per.) V926 Sco 2006MNRAS.373.1235C Casares, J., et al. (7 authors) 2006, MNRAS 373, 1235 (Orb.Per.) V1033 Sco 2001ApJ...554.1290G Greene, J., Bailyn, C.D., Orosz, J.A. 2001, ApJ 554, 1290 (Orb.Per.) V1033 Sco 2003MNRAS.339.1031S Shahbaz, T. 2003, MNRAS 339, 1031 (M1/M2, Incl, M1, M2) V1033 Sco 2006A&A...457..249F Foellmi, C., Depagne, E., Dall, T.H., Mirabel, I.F. 2006, A&A 457, 249 (Spectr2) V1033 Sco 2008A&A...478..203G Gonzalez Hernandez, J.I., Rebolo, R., Israelian, G. 2008, A&A 478, 203; Erratum in A&A 499, 891 (2009) (Orb.Per.) V1101 Sco 1997A&A...325.1035B Barziv, O., et al. (8 authors) 1997, A&A 325, 1035 V1101 Sco 1997ApJ...490..401W Wachter, S. 1997, ApJ 490, 401 (Orb.Per.) MM Ser ................... Ponman, T.J. 1981, Space Sci. Rev. 30, 353 (2. Per.) MM Ser ................... Mason, K.O. 1986, in: Physics of Accretion onto Compact Objects, K.O. Mason, M.G. Watson and N.E. White (eds.), Lecture Notes in Physics 266, Springer Verlag, Heidelberg, p. 29 (Orb.Per.) MM Ser 2004MNRAS.348..100H Hynes, R.I., et al. (7 authors) 2004, MNRAS 348, 100 KZ TrA 1981ApJ...244.1001M Middleditch, J., Mason, K.O., Nelson, J.E., White, N.E. 1981, ApJ 244, 1001 (Orb.Per.) KZ TrA 2007ApJ...660..605K Krauss, M.I., Schulz, N.S., Chakrabarty, D., Juett, A.M., Cottam, J. 2007, ApJ 660, 605 (3. Per.) KZ TrA 2010ApJ...708.1500C Camero-Arranz, A., Finger, M.H., Ikhsanov, N.R., Wilson-Hodge, C.A., Beklen, E. 2010, ApJ 708, 1500 (3. Per.) LU TrA ................... Brammer, G., Wachter, S., Hoard, D.W., Smale, A.P. 2001, BAAS 33(4), Abstr. 6.1 (Orb.Per.) LU TrA 2006MNRAS.370..255N Nelemans, G., Jonker, P.G., Steeghs, D. 2006, MNRAS 370, 255 KV UMa 2006ApJ...642..438G Gelino, D.M., et al. (6 authors) 2006, ApJ 642, 438 (Spectr2, M1/M2, Incl, M1, M2) KV UMa 2008ApJ...679..732H Gonzalez-Hernandez, J.I., et al. (8 authors) 2008, ApJ 679, 732 (Orb.Per., Spectr2) KV UMa 2009MNRAS.399..539C Calvelo, D.E., et al. (7 authors) 2009, MNRAS 399, 539 (M1/M2) KV UMa 2009PASJ...61....1I Kato, T., et al. (130 authors) 2009, PASJ 61, S395 (2. Per.) MM Vel 1999PASP..111..969F Filippenko, A.V., et al. (6 authors) 1999, PASP 111, 969 (Orb.Per., M1/M2, Incl, M1, M2) MM Vel 2003MNRAS.340..447H Hynes, R.I., et al. (6 authors) 2003, MNRAS 340, 447 MM Vel ................... Macias, P., et al. (8 authors) 2011, BAAS 43, abstract 143.04 UY Vol 2009MNRAS.399.2055B Bassa, C.G., Jonker, P.G., Steeghs, D., Torres, M.A.P. 2009, MNRAS 399, 2055 (M1) UY Vol ................... Galloway, D.K., Chakrabarty, D., Lin, J.R. 2009, ATel #2094 (3. Per.) UY Vol 2010ApJ...711L.148G Galloway, D.K., Chakrabarty, D., Lin, J.R., Hartman, J.M. 2010, ApJ 711, L148 (3. Per.) UY Vol 2009ApJ...697L..14H Hynes, R.I., Jones, E.D. 2009, ApJ 697, L14 UY Vol 2009MNRAS.394L.136M Munoz-Darias, T., et al. (7 authors) 2009, MNRAS 394, L136 UY Vol 2009ApJS..183..156W Wolff, M.T., Ray, P.S., Wood, K.S., Hertz, P.L. 2009, ApJS 183, 156 (Orb.Per.) QZ Vul 1996PASP..108..762H Harlaftis, E., Horne, K., Filippenko, A.V. 1996, PASP 108, 762 (Spectr2) QZ Vul 1996MNRAS.282..191O O'Donoghue, D., Charles, P.A. 1996, MNRAS 282, 191 (2. Per.) QZ Vul ................... Orosz, J.A. 2003, in: A Massive Star Odyssey: From Main Sequence to Supernova, K.A. van der Hucht, A. Herrero, C. Esteban (eds.), IAU Symp. No. 212, ASP, San Francisco, p. 365 (M1/M2, Incl, M1, M2) QZ Vul 2004AJ....127..481I Ioannou, Z., Robinson, E.L., Welsh, W.F., Haswell, C.A. 2004, AJ 127, 481 (Orb.Per) V406 Vul 2001IAUC.7644....1C Filippenko, A.V., Chornock, R. 2001, IAU Circ. No. 7644 (Orb.Per., Spectr2, M1) V406 Vul 2004PASJ...56....1S Uemura, M., et al. (7 authors) 2004, PASJ 56, S147 (2. Per.) AC 211 2003A&A...399..211I Ioannou, Z., et al. (7 authors) 2003, A&A 399, 211 (Orb.Per.) AC 211 2004MNRAS.350..649V van Zyl, L., et al. (6 authors) 2004, MNRAS 350, 649 (M1/M2, Incl, M1, M2) AC 211 2006ApJS..163..372W Wen, L., Levine, A.M., Corbet, R.H.D., Bradt, H.V. 2006, ApJS 163, 372 (Orb.Per.) LMC X-2 1991ApJ...373..228C Cowley, A.P., Schmidtke, P.C., Crampton, D., Hutchings, J.B., Bolte, M. 1991, ApJ 373, 228 (2. Per.) LMC X-2 2007MNRAS.381..194C Cornelisse, R., et al. (7 authors) 2007, MNRAS 381, 194 (Orb.Per.) M 51 X-7 2002ApJ...581L..93L Liu, J.-F., Bregman, J.N., Irwin, J., Seitzer, P. 2002, ApJ 581, L93 M 51 X-7 2005ApJ...635..198D Dewangan, G.C., Griffiths, R.E., Choudhuey, M., Miyaji, T., Schurch, N.J. 2005, ApJ 635, 198 (Orb.Per.) NGC 104-W37 2005ApJ...622..556H Heinke, C.O., Grindaly, J.E., Edmonds, P.D. 2005, ApJ 622, 556 (Orb.Per.) NGC 104-X5 2002ApJ...564L..17E Edmonds, P.D., Heinke, C.O., Grindaly, J.E., Gilliland, R.L. 2002, ApJ 564, L17 (Orb.Per.) NGC 104-X5 2003ApJ...588..452H Heinke, C.O., Grindlay, J.E., Lloyd, D.A., Edmonds, P.D. 2003, ApJ 588, 452 (Orb.Per.) NGC 104-X7 2002ApJ...564L..17E Edmonds, P.D., Heinke, C.O., Grindaly, J.E., Gilliland, R.L. 2002, ApJ 564, L17 (Orb.Per.) NGC 104-X7 2003ApJ...588..452H Heinke, C.O., Grindlay, J.E., Lloyd, D.A., Edmonds, P.D. 2003, ApJ 588, 452 NGC 7078-X2 2005ApJ...634L.105D Dieball, A., et al. (8 authors) 2005, ApJ 634, L105 (Orb.Per.) J0029+5934 2008ApJ...680..615J Jonker, P.G., Torres, M.A.P., Steeghs, D. 2008, ApJ 680, 615 J0029+5934 2008ApJ...672.1079T Torres, M.A.P., et al. (13 authors) 2008, ApJ 672, 1079 J0029+5934 2009ApJ...698L..60P Patruno, A., Wijnands, R., van der Klis, M. 2009, ApJ 698, L60 (3. Per.) J0029+5934 2010A&A...517A...1H Lewis, F., et al. (21 authors) 2010, A&A 517, A72 J0029+5934 2010ApJ...722..909P Patruno, A. 2010, ApJ 722, 909 (Orb.Per., 3. Per.) J0029+5934 2011ApJ...726...26H Hartman, J.M., Galloway, D.K., Chakrabarty, D. 2011, ApJ 726, 26 (Orb.Per., 3. Per.) J0029+5934 ................... Papitto, A., et al. (6 authors) 2011, A&A, subm. = arXiv:1006.1303 (Orb.Per., 3. Per.) 0042+3244 ................... Charles, P., Thorstensen, J., Bowyer, S. 1978, MNRAS 183, 29P 0042+3244 ................... Watson, M.G., Ricketts, M.J. 1978, MNRAS 183, 35P (Orb.Per.) J0042+4118 ................... Barnard, R., Kolb, U., Osborne, J.P. 2002, in: New Visions of the X-ray Universe in the XMM-Newton and Chandra Era, F. Jensen (ed.), ESA SP-488, (has not been published), = astro-ph/0203475 (Orb.Per.) J0043+4107 2002ApJ...581L..27T Trudolyubov, S.P., et al. (7 authors) 2002, ApJ 581, L27 (Orb.Per.) J0043+4107 2006MNRAS.366..287B Barnard, R., et al. (6 authors) 2006, MNRAS 366, 287 J0043+4112 2004A&A...419.1045M Mangano, V., Israel, G.L., Stella, L. 2004, A&A 419, 1045 (Orb.Per.) J0055-3738 2003ApJ...590L..13K Kong, A.K.H., Di Stefano, R. 2003, ApJ 590, L13 (Orb.Per.) 0512-4006 2009ApJ...699.1113Z Zurek, D.R., Knigge, C., Maccarone, T.J., Dieball, A., Long, K.S. 2009, ApJ 699, 1113 (Orb.Per.) 0512-4006 2010MNRAS.406.2087M Maccarone, T.J., Long, K.S., Knigge, C., Dieball, A., Zurek, D.R. 2010, MNRAS 406, 2087 0918-5459 ................... Zhong, J., Wang, Z. 2010, ApJ, subm. = arXiv:1006.3980 (Orb.Per.) J0929-3123 2002ApJ...576L.137G Galloway, D.K., Chackrabarty, D., Morgan, E.H., Remillard, R.A. 2002, ApJ 576, L137 (Orb.Per., 3. Per.) J0929-3123 2009A&A...497..445I Iacolina, M.N., Burgay, M., Burderi, L., Posenti, A., Di Salvo, T. 2009, A&A 497, 445 J0929-3123 2009ApJ...698L..60P Patruno, A., Wijnands, R., van der Klis, M. 2009, ApJ 698, L60 (3. Per.) J1023+0038 2005AJ....130..759T Thorstensen, J.R., Armstrong, E. 2005, AJ 130, 759 (Spectr2) J1023+0038 ................... Archibald, A.M., et al. (18 authors) 2009, Sci 324, 1411 (Orb.Per., 3. Per., M1/M2, Incl) J1023+0038 2009ApJ...703.2017W Wang, Z., et al. (7 authors) 2009, ApJ 703, 2017 J1047+1234 2006ApJ...650..879F Fabbiano, G., et al. (12 authors) 2006, ApJ 650, 879 (Orb.Per.) J1227-4853 2008A&A...487..271B Butters, O.W., Norton, A.J., Hakala, P., Mukai, K., Barlow, E.J. 2008, A&A 487, 271 (3. Per.) J1227-4853 2009MNRAS.395..386P Pretorius, M.L. 2009, MNRAS 395, 386 J1227-4853 2009PASJ...61L..13S Saitou, K., Tsujimoto, M., Ebisawa, K., Ishida, M. 2009, PASJ 61, L13 J1227-4853 2010A&A...515A...1A de Martino, D., et al. (10 authors) 2010, A&A 515, A25 (Orb.Per.) J1242+3232 2007A&A...471L..55C Carpano, S., Pollock, A.M.T., King, A.R., Wilms, J., Ehle, M. 2007, A&A 471, L55 (Orb.Per.) 1323-6152 2005A&A...436..195B Boirin, L., Mendez, M., Diaz Trigo, M., Parmar, A.N., Kaastra, J.S. 2005, A&A 436, 195 1323-6152 ................... Levine, A.M., Corbet, R. 2006, ATel #940 (Orb.Per.) 1323-6152 2009A&A...500..873B Balucinska-Church, M., Dotani, T., Hirotsu, T., Church, M.J. 2009, A&A 500, 873 J1538-5542 ................... Kennea, J.A., et al. (12 authors) 2007, ATel #1209 (Orb.Per.) 1543-6224 2004MNRAS.348L...7N Nelemans, G., Jonker, P.G., Marsh, T.R., van der Klis, M. 2004, MNRAS 348, L7 1543-6224 2004ApJ...616L.139W Wang, Z., Chakrabarty, D. 2004, ApJ 616, L139 (Orb.Per.) 1624-4904 2001A&A...378..847B Balucinska-Church, M., Barnard, R., Church, M.J., Smale, A.P. 2001, A&A 378, 847 1624-4904 2001ApJ...550..962S Smale, A.P., Church, M.J., Balucinska-Church, M. 2001, ApJ 550, 962 (Orb.Per.) J1650-4957 2003ApJ...586..419K Kalemci, E., et al. (8 authors) 2003, ApJ 586, 419 J1650-4957 2003ApJ...592.1100T Tomsick, J.A., Kalemci, E., Corbel, S., Kaaret, P. 2003, ApJ 592, 1100 J1650-4957 2004ApJ...616..376O Orosz, J.A., McClintock, J.E., Remiilard, R.A., Corbel, S. 2004, ApJ 616, 376 (Orb.Per., Spectr2, Incl, M1) J1659-1515 ................... Belloni, T.M., Munoz-Darias, T., Kuulkers, E. 2010, ATel #2926 (Orb.Per.) 1705-4402 1987ApJ...323..288L Langmeier, M., Sztajno, M., Hasinger, G., Truemper, J., Gottwald, M. 1987, ApJ 323, 288 (Orb.Per.) 1705-4402 2009ApJ...692...73H Homan, J., Kaplan, D.L., van den Berg, M., Young, A.J. 2009, ApJ 692, 73 J1710-2807 2009A&A...502..905Y Younes, G., Boirin, L., Sabra, B. 2009, A&A 502, 905 J1710-2807 ................... Jain, C., Paul. B. 2011, MNRAS, in press = arXiv:1011.6054 (Orb.Per.) 1728-3347 1999ApJ...516L..81S Strohmayer, T.E., Markwardt, C.B. 1999, ApJ 516, L81 (3. Per.) 1728-3347 2001ApJ...551..907V van Straaten, S., van der Klis, M., Kuulkers, E., Mendez, M. 2001, ApJ 551, 907 (3. Per.) 1728-3347 2010ApJ...724..417G Galloway, D.K., Yao, Y., Marshall, H., Misanovic, Z., Weinberg, N. 2010, ApJ 724, 417 (Orb.Per.) 1740-2943 1997A&A...319..184A Marti, J., Mirabel, I.F., Chaty, S., Rodriguez, L.F. 2000, A&A 319, 184 1740-2943 2002ApJ...578L.129S Smith, D.M., Heindl, W.A., Swank, J.H. 2002, ApJ 578, L129 (Orb.Per.) J1744-2844 1997IAUC.6530Q...1K Finger, M.H., Robinson, C.R., Harmon, B.A., Vaughan, B.A. 1997, IAU Circ. No. 6530 (Orb.Per., 3. Per.) J1744-2844 2007MNRAS.380.1511G Gosling, A.J., Bandyopadhyay, R.M., Miller-Jones, J.C.A., Farrell, S.A. 2007, MNRAS 380, 1511 J1745-2901 2009A&A...495..547D Degenaar, N., Wijnands, R. 2009, A&A 495, 547 J1745-2901 2009PASJ...61....1I Hyodo, Y., et al. (6 authors) 2009, PASJ 61, S99 (Orb.Per.) J1745-2900 2005ApJ...622L.113M Muno, M.P., et al. (7 authors) 2005, ApJ 622, L113 J1745-2900 2005A&A...443..571P Porquet, D., et al. (7 authors) 2005, A&A 443, 571 (Orb.Per.) 1746-3702 2002AJ....123.3255H Homer, L., Anderson, S.F., Margon, B., Downes, R.A., Deutsch, E.W. 2002, AJ 123, 3255 1746-3702 2004MNRAS.347..334B Baluchinska-Church, M., Church, M.J., Smale, A.P. 2004, MNRAS 347, 334 (Orb.Per.) 1746-3702 ................... Levine, A.M., Corbet, R. 2006, ATel #940 (Orb.Per.) 1747-3116 2003A&A...406..233I in 't Zand, J.J.M., et al. (9 authors) 2003, A&A 406, 233 (Orb.Per.) 1747-3116 2003A&A...409..659I in 't Zand, J.J.M., Strohmayer, T.E., Markwardt, C.B., Swank, J. 2003, A&A 409, 659 J1748-3607 2006ApJ...639L..31B Bhattacharyya, S., Strohmayer, T.E., Markwardt, C.B., Swank, J.H. 2006, ApJ 639, L31 (3. Per.) J1748-3607 ................... Gavriil, F.P., Strohmayer, T.E., Bhattacharyya, S. 2009, ApJ, subm. = arXiv:0909.1607 (Orb.Per.) J1748-2446 2011A&A...526L...3P Papitto, A., et al. (8 authors) 2011, A&A 526, L3 (Orb.Per., 3. Per) J1748-2446 ................... Strohmayer, T.E., Markwardt, C.B., Pereira, D., Smith, E.A. 2010, ATel #2946 J1748-2021#1 2007ApJ...669L..29G Gavriil, F.P., Strohmayer, T.E., Swank, J.H., Markwardt, C.B. 2007, ApJ 669, L29 (3. Per.) J1748-2021#1 2008ApJ...674L..45A Altamirano, D., Casella, P., Patruno, A., Wijnands, R., van der Klis, M. 2008, ApJ 674, L45 (M2) J1748-2021#1 2009ApJ...690.1856P Patruno, A., et al. (6 authors) 2009, ApJ 690, 1856 (Orb.Per., 3. Per.) J1748-2021#2 2010ApJ...714..894H Heinke, C.O., et al. (14 authors) 2009, ApJ 714, 894 J1748-2021#2 2010ApJ...712L..58A Altamirano, D., et al. (9 authors) 2010, ApJ 712, L58 (Orb.Per., 3. Per., M2) J1749-2808 2011A&A...525A...1P Ferrigno, C., et al. (10 authors) 2010, A&A 525, A48 (Orb.Per., 3. Per.) J1749-2808 ................... Markwardt, C.B., Strohmayer, T.E. 2010, ApJ 717, L49 (Orb.Per., 3. Per., Incl, M2) J1749-2808 2011ApJ...727L..18A Altamirano, D., et al. (15 authors) 2011, ApJ 727, L18 J1751-3057 2010MNRAS.409.1136A Altamirano, D., et al. (6 authors) 2010, MNRAS 409, 1136 J1751-3057 2010MNRAS.407.2575P Papitto, A., et al. (8 authors) 2010, MNRAS 407, 2575 (Orb.Per., 3. Per., M2) J1751-3057 2011A&A...526A...1D Riggio, A., et al. (8 authors) 2011, A&A 526, A95 (Orb.Per., 3. Per.) J1751-3037 2002ApJ...575L..21M Markwardt, C.B., Swank, J., Strohmayer, T.E., in 't Zand, J.J.M. 2002, ApJ 575, L21, Erratum in ApJ 667, L211 (2007) (Orb.Per., 3. Per., M2) J1751-3037 2008MNRAS.383..411P Papitto, A., Menna, M.T., Burderi, L., Di Salvo, T., Riggio, A. 2008, MNRAS 383, 411 (Orb.Per., 3. Per.) J1751-3037 2009ApJ...698L..60P Patruno, A., Wijnands, R., van der Klis, M. 2009, ApJ 698, L60 (3. Per.) J1753-0127 2008ApJ...681.1458Z Zurita, C., et al. (6 authors) 2008, ApJ 681, 1458 (2. Per.) J1753-0127 2009MNRAS.392..309D Durant, M., Gandhi, P., Shahbaz, T., Peralta, H.H., Dhillon, V.S. 2009, MNRAS 392, 309 J1753-0127 2009MNRAS.399..281H Hynes, R.I., O'Brien, K., Mullally, F., Ashcraft, T. 2009, MNRAS 399, 281 J1753-0127 2009MNRAS.395.1257R Reis, R.C., Fabian, A.C., Ross, R.R., Miller, J.M. 2009, MNRAS 395, 1257 J1756-2506 2007ApJ...668L.147K Krimm, H.A., et al. (13 authors) 2007, ApJ 668, L147; erratum in ApJ 703, L183 (2009) (Orb.Per, 3. Per., M2) J1756-2506 2010MNRAS.403.1426P Patruno, A., Altamirano, D., Messenger, C. 2009, MNRAS 403, 1426 (Orb.Per., 3. Per.) 1758-2544 2002ApJ...580L..61R Rothstein, D.M., et al. (6 authors) 2002, ApJ 580, L61 (Spectr2) 1758-2544 2002ApJ...578L.129S Smith, D.M., Heindl, W.A., Swank, J.H. 2002, ApJ 578, L129 (Orb.Per.) 1758-2544 2010A&A...519A...1L Munoz-Arjonilla, A.J., et al. (7 authors) 2010, A&A 519, A15 J1806-2924 2007MNRAS.382.1751R Riggio, A., et al. (7 authors) 2007, MNRAS 382, 1751 (Orb.Per., 3. Per.) J1806-2924 2008ApJ...678.1316C Chou, Y., Chung, Y., Hu, C.P., Yang, T.C. 2008, ApJ 678, 1316 (Orb.Per., 3. Per.) J1806-2924 2008ApJ...678.1273R Riggio, A., et al. (7 authors) 2008, ApJ 678, 1273 J1806-2924 2009A&A...508..297D D'Avanzo, P., et al. (6 authors) 2009, A&A 508, 297 J1806-2924 2009ApJ...698L..60P Patruno, A., Wijnands, R., van der Klis, M. 2009, ApJ 698, L60 (3. Per.) J1806-2924 2010ApJ...717.1253P Patruno, A., Hartman, J.M., Wijnands, R., Chakrabarty, D., van der Klis, M. 2010, ApJ 717, 1253 (Orb.Per., 3. Per.) 1811-1710 1999MNRAS.306..417B Bandyopadhyay, R.M., Shahbaz, T., Charles, P.A., Naylor, T. 1999, MNRAS 306,417 (Spectr2) 1811-1710 2003ApJ...595.1086C Corbet, R.H.D. 2003, ApJ 595, 1086 (Orb.Per.) 1811-1710 2010ApJ...719..979C Corbet, R.H.D., Pearlman, A.B., Buxton, M., Levine, A.M. 2010, ApJ 719, 979 1813-1403 1986IAUC.4235....0H Hertz, P., Wood, K.S. 1986, IAU Circ. No. 4235 (Orb.Per.) 1813-1403 2002ApJ...574L.143C Callanan, P.J., et al. (9 authors) 2002, ApJ 574, L143 1813-1403 2002A&A...382..947K Kuulkers, E., Homan, J., van der Klis, M., Lewin, W.H.G., Mendez, M. 2002, A&A 382, 947 1820-3023 1997ApJ...482L..69A Anderson, S.F., Margon, B., Deutsch, E.W., Downes, R.A., Allen, R.G. 1997, ApJ 482, L69 (Orb.Per.) 1820-3023 ................... Levine, A.M., Corbet, R. 2006, ATel #940 (Orb.Per.) 1820-3023 2010ApJ...719.1807G Guever, T., Wroblewski, P., Camarota, L., Oezel, F. 2010, ApJ 719, 1807 1820-3023 2010ApJ...712..653W Wang, Z., Chakrabarty, D. 2010, ApJ 712, 653 (2. Per.) 1822-0002 2005ApJ...627..926J Juett, A.M., Chakrabarty, D. 2005, ApJ 627, 926 1822-0002 2007MNRAS.376.1886S Shahbaz, T., Watson, C.A., Hernandez-Peralta, H. 2007, MNRAS 376, 1886 (Orb.Per.) 1850-0846 1996MNRAS.282L..37H Homer, L., et al. (6 authors) 1996, MNRAS 282, L37 (Orb.Per.) 1850-0846 2005A&A...443..223S Sidoli, L., La Palombara, N., Oosterbroek, T., Parmar, A.N. 2005, A&A 443, 223 J1900-2455 2006ApJ...638..963K Kaaret, P., Morgan, E.H., Vanderspeck, R., Tomsick, J.A. 2006, ApJ 638, 963 (Orb.Per., 3. Per.) J1900-2455 2008MNRAS.383.1581E Elebert, P., et al. (7 authors) 2008, MNRAS 383, 1581 J1900-2455 2009ApJ...698L.174W Watts, A., et al. (11 authors) 2009, ApJ 698, L174 J1910-5959 2009AcA....59..273K Kaluzny, J., Thompson, I.B. 2009, AA 59, 273 (Orb.Per.) J1914+0953 ................... Corbet, R.H.D., Hannikainen, D.C., Remillard, R. 2004, ATel #269 (Orb.Per.) J1914+0953 2004A&A...423L..17H Hannikainen, D.C., et al. (8 authors) 2004, A&A 423, L17 J1914+0953 2005A&A...432..235R Rodriguez, J., et al. (6 authors) 2004, A&A 432, 235 J1914+0953 ................... Schultz, J., et al. (8 authors) 2004, in: The INTEGRAL Universe, V. Schoenfelder, G. Lichti, C. Winkler (eds.), ESA SP-552, p. 243 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1112466 astropy-5.0.2/astropy/io/ascii/tests/data/cds/multi/0000755000175100001710000000000000000000000021423 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/cds/multi/ReadMe0000644000175100001710000000650300000000000022507 0ustar00vstsdockerJ/MNRAS/301/1031 High resolution spectra of VLM stars (Tinney+ 1998) ================================================================================ High resolution spectra of Very Low-Mass Stars Tinney C.G., Reid I.N. =1998MNRAS.301.1031T ================================================================================ ADC_Keywords: Stars, dwarfs ; Stars, late-type ; Spectroscopy Description: A high resolution optical spectral atlas for three very low-mass stars are provided, along with a high resolution observation of an atmospheric absorption calibrator. This is the data used to produce Figures 4-9 in the paper. These data were acquired with CASPEC on the ESO3.6m telescope. The FWHM resolution is 16km/s (eg. 0.043nm at 800nm), at a dispersion of 9km/s. Incomplete wavelength coverage produces inter-order gaps at wavelengths longer than 804.5nm. Objects: --------------------------------------------------------------------- RA (2000) DE Designation(s) (File) --------------------------------------------------------------------- 16 55 35.7 -08 23 36 VB 8 = LHS 429 = Gl 644 C (vb8.dat) 08 53 36 -03 29 30 LHS 2065 = LP 666-9 (lhs2065.dat) 03 39 34.6 -35 25 51 LP 944-20 (lp944-20.dat) 05 45 59.9 -32 18 23 {mu} Col = HR 1996 = HD 38666 (mucol.dat) --------------------------------------------------------------------- File Summary: --------------------------------------------------------------------- FileName Lrecl Records Explanations --------------------------------------------------------------------- ReadMe 80 . This file vb8.dat 26 14390 Spectrum for VB8 lhs2065.dat 26 14390 Spectrum for LHS2065 lp944-20.dat 26 14390 Spectrum for LP944-20 mucol.dat 23 14390 Atmospheric Spectrum for Mu Columbae --------------------------------------------------------------------- Byte-by-byte Description of file: vb8.dat, lhs2065.dat Byte-by-byte Description of file: lp944-20.dat ------------------------------------------------------------------------- Bytes Format Units Label Explanations ------------------------------------------------------------------------- 1- 12 F12.2 0.1nm Lambda Central wavelength of the flux bin 13- 26 A14.9 mJy Fnu Data in interorder gaps has value 0.0 ------------------------------------------------------------------------- Byte-by-byte Description of file: mucol.dat ------------------------------------------------------------------------- Bytes Format Units Label Explanations ------------------------------------------------------------------------- 1- 12 F12.2 0.1nm Lambda Central wavelength of the flux bin 13- 23 F11.6 --- Fnu *Data in interorder gaps has value 0.0 ------------------------------------------------------------------------- Note on Fnu: mJy which have been normalised to value 1.0 in the continuum of the atmospheric standard star ------------------------------------------------------------------------- ================================================================================ (End) C.G. Tinney [AAO] 04-Feb-1999 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/cds/multi/lhs2065.dat0000644000175100001710000000066000000000000023222 0ustar00vstsdocker 6476.09 0.383329 6476.28 0.515559 6476.47 0.288042 6476.66 0.373343 6476.85 0.472194 6477.04 0.352547 6477.23 0.215444 6477.42 0.371470 6477.61 0.382175 6477.80 0.300221 6477.99 0.252524 6478.18 0.346887 6478.37 0.389587 6478.56 0.328543 6478.75 0.328281 6478.94 0.294363 6479.13 0.336826 6479.32 0.285937 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/cds/multi/lp944-20.dat0000644000175100001710000000066200000000000023214 0ustar00vstsdocker 6476.09 0.342236 6476.28 0.380582 6476.47 0.429476 6476.66 0.463431 6476.85 0.475528 6477.04 0.387025 6477.23 0.304608 6477.42 0.404995 6477.61 0.388829 6477.80 0.264535 6477.99 0.715199 6478.18 0.656017 6478.37 0.327062 6478.56 0.245733 6478.75 0.403018 6478.94 7.89686E-02 6479.13 0.321100 6479.32 0.489005././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1112466 astropy-5.0.2/astropy/io/ascii/tests/data/cds/null/0000755000175100001710000000000000000000000021243 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/cds/null/ReadMe0000644000175100001710000000714400000000000022331 0ustar00vstsdockerJ/A+A/511/A56 Abundances of five open clusters (Pancino+, 2010) ================================================================================ Chemical abundance analysis of the open clusters Cr 110, NGC 2420, NGC 7789, and M 67 (NGC 2682). Pancino E., Carrera R., Rossetti, E., Gallart C. =2010A&A...511A..56P ================================================================================ ADC_Keywords: Clusters, open ; Stars, giant ; Equivalent widths ; Spectroscopy Keywords: stars: abundances - Galaxy: disk - open clusters and associations: general Abstract: The present number of Galactic open clusters that have high resolution abundance determinations, not only of [Fe/H], but also of other key elements, is largely insufficient to enable a clear modeling of the Galactic disk chemical evolution. To increase the number of Galactic open clusters with high quality measurements, we obtained high resolution (R~30000), high quality (S/N~50-100 per pixel), echelle spectra with the fiber spectrograph FOCES, at Calar Alto, Spain, for three red clump stars in each of five Open Clusters. We used the classical equivalent width analysis method to obtain accurate abundances of sixteen elements: Al, Ba, Ca, Co, Cr, Fe, La, Mg, Na, Nd, Ni, Sc, Si, Ti, V, and Y. We also derived the oxygen abundance using spectral synthesis of the 6300{AA} forbidden line. Description: Atomic data and equivalent widths for 15 red clump giants in 5 open clusters: Cr 110, NGC 2099, NGC 2420, M 67, NGC 7789. File Summary: -------------------------------------------------------------------------------- FileName Lrecl Records Explanations -------------------------------------------------------------------------------- ReadMe 80 . This file table1.dat 103 15 Observing logs and programme stars information table5.dat 56 5265 Atomic data and equivalent widths -------------------------------------------------------------------------------- See also: J/A+A/455/271 : Abundances of red giants in NGC 6441 (Gratton+, 2006) J/A+A/464/953 : Abundances of red giants in NGC 6441 (Gratton+, 2007) J/A+A/505/117 : Abund. of red giants in 15 globular clusters (Carretta+, 2009) Byte-by-byte Description of file: table.dat -------------------------------------------------------------------------------- Bytes Format Units Label Explanations -------------------------------------------------------------------------------- 1- 7 A7 --- Cluster Cluster name 9- 12 I4 --- Star 14- 20 F7.2 0.1nm Wave wave ? Wavelength in Angstroms 22- 23 A2 --- El a 24 I1 --- ion ?=0 - Ionization stage (1 for neutral element) 26- 30 F5.2 eV chiEx [-180/180]? Pericenter position angle (18) 32- 37 F6.2 --- loggf ]0/140[? Temperature class codified (10) 39- 43 F5.1 0.1pm EW ?=-9.9 Equivalent width (in mA) 46- 49 F4.1 0.1pm e_EW [1/6]? Luminosity class codified (11) 51- 56 F6.3 --- Q ?=-9.999 DAOSPEC quality parameter Q (large values are bad) -------------------------------------------------------------------------------- Acknowledgements: Elena Pancino, elena.pancino(at)oabo.inaf.it ================================================================================ (End) Elena Pancino [INAF-OABo, Italy], Patricia Vannier [CDS] 23-Nov-2009 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/cds/null/ReadMe10000644000175100001710000000757000000000000022415 0ustar00vstsdockerJ/A+A/511/A56 Abundances of five open clusters (Pancino+, 2010) ================================================================================ Chemical abundance analysis of the open clusters Cr 110, NGC 2420, NGC 7789, and M 67 (NGC 2682). Pancino E., Carrera R., Rossetti, E., Gallart C. =2010A&A...511A..56P ================================================================================ ADC_Keywords: Clusters, open ; Stars, giant ; Equivalent widths ; Spectroscopy Keywords: stars: abundances - Galaxy: disk - open clusters and associations: general Abstract: Tables modified for testing. Added order specifiers "+=", "-=" and "+" to cols 5, 8 and 9 respectively and removed whitespace after "?" in col 6. Beginning of original abstract follows: The present number of Galactic open clusters that have high resolution abundance determinations, not only of [Fe/H], but also of other key elements, is largely insufficient to enable a clear modeling of the Galactic disk chemical evolution. To increase the number of Galactic open clusters with high quality measurements, we obtained high resolution (R~30000), high quality (S/N~50-100 per pixel), echelle spectra with the fiber spectrograph FOCES, at Calar Alto, Spain, for three red clump stars in each of five Open Clusters. We used the classical equivalent width analysis method to obtain accurate abundances of sixteen elements: Al, Ba, Ca, Co, Cr, Fe, La, Mg, Na, Nd, Ni, Sc, Si, Ti, V, and Y. We also derived the oxygen abundance using spectral synthesis of the 6300{AA} forbidden line. Description: Atomic data and equivalent widths for 15 red clump giants in 5 open clusters: Cr 110, NGC 2099, NGC 2420, M 67, NGC 7789. File Summary: -------------------------------------------------------------------------------- FileName Lrecl Records Explanations -------------------------------------------------------------------------------- ReadMe 80 . This file table1.dat 103 15 Observing logs and programme stars information table5.dat 56 5265 Atomic data and equivalent widths -------------------------------------------------------------------------------- See also: J/A+A/455/271 : Abundances of red giants in NGC 6441 (Gratton+, 2006) J/A+A/464/953 : Abundances of red giants in NGC 6441 (Gratton+, 2007) J/A+A/505/117 : Abund. of red giants in 15 globular clusters (Carretta+, 2009) Byte-by-byte Description of file: table.dat -------------------------------------------------------------------------------- Bytes Format Units Label Explanations -------------------------------------------------------------------------------- 1- 7 A7 --- Cluster Cluster name 9- 12 I4 --- Star 14- 20 F7.2 0.1nm Wave wave ? Wavelength in Angstroms 22- 23 A2 --- El a 24 I1 --- ion ?=0 - Ionization stage (1 for neutral element) 26- 30 F5.2 eV chiEx [1/20843]?+= Catalogue Identification Number 32- 37 F6.2 --- loggf ]0/140[?Temperature class codified (10) 39- 43 F5.1 0.1pm EW ?=-9.9 Equivalent width (in mA) 44- 45 F5.1 0.1pm EW [1/52]?-= Equivalent width (in mA) 46- 49 F4.1 0.1pm e_EW [1/6]?+ Luminosity class codified (11) 51- 56 F6.3 --- Q ?=-9.999 DAOSPEC quality parameter Q (large values are bad) -------------------------------------------------------------------------------- Acknowledgements: Elena Pancino, elena.pancino(at)oabo.inaf.it ================================================================================ (End) Elena Pancino [INAF-OABo, Italy], Patricia Vannier [CDS] 23-Nov-2009 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/cds/null/table.dat0000644000175100001710000000016200000000000023023 0ustar00vstsdockerCr110 2108 6696.79 Al1 4.02 -1.42 29.5 2.2 0.289 Cr110 2108 6698.67 Al1 3.14 -1.65 58.0 2.0 0.325 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/cds.dat0000644000175100001710000000462100000000000020766 0ustar00vstsdocker Title: Spitzer Observations of NGC 1333: A Study of Structure and Evolution in a Nearby Embedded Cluster Authors: Gutermuth R.A., Myers P.C., Megeath S.T., Allen L.E., Pipher J.L., Muzerolle J., Porras A., Winston E., Fazio G. Table: Spitzer-identified YSOs: Addendum ================================================================================ Byte-by-byte Description of file: datafile3.txt -------------------------------------------------------------------------------- Bytes Format Units Label Explanations -------------------------------------------------------------------------------- 1- 3 I3 --- Index Running identification number 5- 6 I2 h RAh Hour of Right Ascension (J2000) 8- 9 I2 min RAm Minute of Right Ascension (J2000) 11- 15 F5.2 s RAs Second of Right Ascension (J2000) - continuation of description 17 A1 --- DE- Sign of the Declination (J2000) 18- 19 I2 deg DEd Degree of Declination (J2000) 21- 22 I2 arcmin DEm Arcminute of Declination (J2000) 24- 27 F4.1 arcsec DEs Arcsecond of Declination (J2000) 29- 68 A40 --- Match Literature match 70- 75 A6 --- Class Source classification (1) 77-80 F4.2 mag AK ? The K band extinction (2) 82-86 F5.2 GMsun Fit ? Fit of IRAC photometry with bogus unit (3) -------------------------------------------------------------------------------- Note (1): Asterisks mark "deeply embedded" sources with questionable IRAC colors or incomplete IRAC photometry and relatively bright MIPS 24 micron photometry. Note (2): Only provided for sources with valid JHK_S_ photometry. Note (3): Defined as the slope of the linear least squares fit to the 3.6 - 8.0 micron SEDs in log{lambda} F_{lambda} vs log{lambda} space. Extinction is not accounted for in these values. High extinction can bias Fit to higher values. -------------------------------------------------------------------------------- 1 03 28 39.09 +31 06 01.9 I* 1.35 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/cds2.dat0000644000175100001710000012333200000000000021051 0ustar00vstsdockerTitle: The Taurus Spitzer Survey: New Candidate Taurus Members Selected Using Sensitive Mid-Infrared Photometry Authors: Rebull L.M., Padgett D.L., McCabe C.-E., Hillenbrand L.A., Stapelfeldt K.R., Noriega-Crespo A., Carey S.J., Brooke T., Huard T., Terebey S., Audard M., Monin J.-L., Fukagawa M., Gudel M., Knapp G.R., Menard F., Allen L.E., Angione J.R., Baldovin-Saavedra C., Bouvier J., Briggs K., Dougados C., Evans N.J., Flagey N., Guieu S., Grosso N., Glauser A.M., Harvey P., Hines D., Latter W.B., Skinner S.L., Strom S., Tromp J., Wolf S. Table: Spitzer measurements for sample of previously identified Taurus members ================================================================================ Byte-by-byte Description of file: apjs326455t4_mrt.txt -------------------------------------------------------------------------------- Bytes Format Units Label Explanations -------------------------------------------------------------------------------- 1- 15 A15 --- SST Spitzer Tau name 17- 39 A23 --- CName Common name 41 A1 --- l_3.6mag Limit flag on 3.6mag 42- 47 F6.2 mag 3.6mag Spitzer/IRAC 3.6 micron band magnitude (1) 49- 52 F4.2 mag e_3.6mag ? Uncertainty in 3.6mag 54 A1 --- l_4.5mag Limit flag on 4.5mag 55- 60 F6.2 mag 4.5mag ? Spitzer/IRAC 4.5 micron band magnitude (1) 62- 65 F4.2 mag e_4.5mag ? Uncertainty in 4.5mag 67 A1 --- l_5.8mag Limit flag on 5.8mag 68- 73 F6.2 mag 5.8mag Spitzer/IRAC 5.8 micron band magnitude (1) 75- 78 F4.2 mag e_5.8mag ? Uncertainty in 5.8mag 80 A1 --- l_8mag Limit flag on 8.0mag 81- 86 F6.2 mag 8mag ? Spitzer/IRAC 8.0 micron band magnitude (1) 88- 91 F4.2 mag e_8mag ? Uncertainty in 8mag 93 A1 --- l_24mag Limit flag on 24mag 94-100 F7.2 mag 24mag ? Spitzer/MIPS 24 micron band magnitude (1) 102-105 F4.2 mag e_24mag ? Uncertainty in 24mag 107 A1 --- l_70mag Limit flag on 70mag 108-114 F7.2 mag 70mag ? Spitzer/MIPS 70 micron band magnitude (1) 116-119 F4.2 mag e_70mag ? Uncertainty in 70mag 121 A1 --- l_160mag Limit flag on 160mag 122-128 F7.2 mag 160mag ? Spitzer/MIPS 160 micron band magnitude (1) 130-133 F4.2 mag e_160mag ? Uncertainty in 160mag 135-137 A3 --- ID24/70 Identification in 24/70 micron color-magnitude diagram 139-147 A9 --- IDKS/24 Identification in Ks/70 micron color-magnitude diagram 149-157 A9 --- ID8/24 Identification in 8/24 micron color-magnitude diagram 159-167 A9 --- ID4.5/8 Identification in 4.5/8 micron color-magnitude diagram 169-171 A3 --- IDIRAC Identification in IRAC color-color diagram 173-175 A3 --- Note Additional note (2) -------------------------------------------------------------------------------- Note (1): To convert between magnitudes and flux densities, we use M= 2.5 log(F_zeropt_/F) where the zero-point flux densities for the seven Spitzer bands are 280.9, 179.7, 115.0, and 64.13 Jy for IRAC and 7.14, 0.775, and 0.159 Jy for MIPS. IRAC effective wavelengths are 3.6, 4.5, 5.8, and 8.0 microns; MIPS effective wavelengths are 24, 70, and 160 microns. Note (2): b = MIPS-160 flux density for this object is subject to confusion with a nearby source or sources. c = MIPS-160 flux density for this object is compromised by missing and/or saturated data. d = MIPS-160 flux density for this object is hard saturated. e = IRAC flux densities for 043835.4+261041=HV Tau C do not appear in our automatically-extracted catalog. Flux densities here are those from Hartmann et al. (2005); since their observations have more redundancy at IRAC bands, they are able to obtain reliable flux densities for this object at IRAC bands. MIPS flux densities are determined from our data. f = The image morphology around 041426.2+280603 is complex; careful PSF subtraction and modeling will be required to apportion flux densities among the three local maxima seen in close proximity in the IRAC images, which may or may not be three physically distinct sources. -------------------------------------------------------------------------------- 041314.1+281910 LkCa 1 8.54 0.05 8.50 0.05 8.41 0.05 8.43 0.05 8.28 0.08 > 1.30 no no no no 041327.2+281624 Anon 1 7.23 0.05 7.24 0.05 7.17 0.05 7.08 0.05 6.95 0.05 > 1.27 no no no no 041353.2+281123 IRAS04108+2803 A 9.02 0.05 8.37 0.05 7.67 0.05 6.57 0.05 3.44 0.04 > 0.19 > -2.05 yes yes yes yes b 041354.7+281132 IRAS04108+2803 B 9.38 0.05 8.03 0.05 6.96 0.05 5.78 0.05 1.38 0.04 -1.84 0.22 > -1.94 yes yes yes yes yes b 041357.3+291819 IRAS04108+2910 7.48 0.05 6.84 0.05 6.26 0.05 5.54 0.05 3.13 0.04 1.15 0.22 > -3.39 yes yes yes yes yes 041411.8+281153 J04141188+2811535 10.93 0.06 10.40 0.05 10.12 0.07 8.99 0.06 5.76 0.01 > 1.03 yes yes yes yes 041412.2+280837 IRAS04111+2800G 13.19 0.06 11.90 0.06 11.19 0.06 10.39 0.06 3.47 0.04 -0.33 0.22 yes yes-faint yes-faint yes 041412.9+281212 V773 Tau ABC < 6.62 < 6.10 5.13 0.05 4.38 0.05 1.69 0.04 0.27 0.22 yes yes yes 041413.5+281249 FM Tau 8.09 0.05 7.67 0.05 7.36 0.05 6.42 0.05 2.92 0.04 1.07 0.22 yes yes yes yes yes 041414.5+282758 FN Tau 7.59 0.05 7.17 0.05 6.71 0.05 5.75 0.05 2.03 0.04 -0.25 0.22 yes yes yes yes yes 041417.0+281057 CW Tau < 6.62 < 6.10 5.08 0.05 4.51 0.05 1.75 0.04 -0.42 0.22 yes yes yes 041417.6+280609 CIDA-1 8.67 0.05 8.13 0.05 7.59 0.05 6.71 0.05 3.53 0.04 1.28 0.22 yes yes yes yes yes 041426.2+280603 IRAS04113+2758 A < 6.62 < 6.10 4.63 0.05 3.79 0.05 < 0.45 -2.54 0.22 -4.35 0.34 f 041430.5+280514 MHO-3 7.22 0.05 6.49 0.05 5.75 0.05 4.53 0.05 < 0.45 -1.06 0.22 -4.15 0.34 yes yes 041447.3+264626 FP Tau 8.11 0.05 7.86 0.05 7.60 0.05 7.27 0.05 4.25 0.04 1.22 0.22 yes yes yes yes yes 041447.8+264811 CX Tau 8.48 0.05 8.13 0.05 7.68 0.05 6.63 0.05 3.35 0.04 1.23 0.22 yes yes yes yes yes 041447.9+275234 LkCa 3 AB 7.28 0.05 7.33 0.05 7.27 0.05 7.23 0.05 7.07 0.05 > 1.17 no no no no 041449.2+281230 FO Tau AB 7.53 0.05 7.17 0.05 6.72 0.05 5.92 0.05 2.83 0.04 0.79 0.22 yes yes yes yes yes 041505.1+280846 CIDA-2 8.90 0.05 8.79 0.05 8.71 0.05 8.68 0.05 8.45 0.11 > 1.31 no no no no 041514.7+280009 KPNO-1 13.23 0.13 12.72 0.22 12.94 0.09 12.81 0.10 > 10.61 > 0.90 no no 041524.0+291043 J04152409+2910434 11.86 0.05 11.79 0.05 11.66 0.06 11.48 0.06 > 10.06 > 1.14 no no 041612.1+275638 J04161210+2756385 9.38 0.05 9.04 0.05 8.71 0.05 8.30 0.05 5.37 0.04 1.55 0.22 yes yes yes yes yes 041618.8+275215 J04161885+2752155 10.88 0.05 10.78 0.05 10.67 0.06 10.68 0.06 > 9.95 > 1.26 no no 041628.1+280735 LkCa 4 8.18 0.05 8.17 0.05 8.04 0.05 8.05 0.05 7.94 0.07 > 1.20 no no no no 041639.1+285849 J04163911+2858491 10.50 0.05 10.14 0.05 9.86 0.05 9.41 0.05 7.22 0.05 > 1.24 yes yes yes yes 041733.7+282046 CY Tau 7.87 0.05 7.53 0.05 7.27 0.05 6.72 0.05 4.42 0.04 1.87 0.22 > -1.41 yes yes yes yes yes 041738.9+283300 LkCa 5 8.93 0.05 8.80 0.05 8.66 0.09 > 1.61 no 041749.5+281331 KPNO-10 10.82 0.05 10.36 0.05 9.81 0.05 8.89 0.05 5.96 0.04 1.92 0.22 yes yes yes yes yes 041749.6+282936 V410 X-ray 1 8.41 0.05 7.85 0.05 7.42 0.05 6.47 0.05 3.78 0.04 2.95 0.22 yes yes yes yes yes 041807.9+282603 V410 X-ray 3 10.04 0.05 9.94 0.05 9.90 0.06 9.80 0.05 9.27 0.21 > 1.79 yes yes-faint no no 041817.1+282841 V410 Anon 13 10.23 0.05 9.94 0.05 9.49 0.05 8.81 0.05 6.04 0.04 > -0.57 yes yes yes yes 041822.3+282437 V410 Anon 24 9.84 0.05 9.54 0.05 9.34 0.05 9.38 0.05 9.29 0.10 > 1.60 > 1.50 yes no no no 041829.0+282619 V410 Anon 25 8.87 0.05 8.64 0.05 8.46 0.05 8.39 0.05 8.15 0.08 > 1.67 > 0.12 yes no no no 041830.3+274320 KPNO-11 10.71 0.05 10.59 0.05 10.60 0.06 10.50 0.06 > 10.01 > 1.46 no no 041831.1+282716 V410 Tau ABC 7.36 0.05 7.34 0.05 7.34 0.05 7.25 0.05 7.14 0.06 > 1.65 no no no no 041831.1+281629 DD Tau AB < 6.62 < 6.10 5.29 0.05 4.48 0.05 1.75 0.04 -0.04 0.22 yes yes yes 041831.5+281658 CZ Tau AB 8.46 0.05 7.63 0.05 6.62 0.05 5.00 0.05 1.96 0.04 1.45 0.22 yes yes yes yes yes 041832.0+283115 IRAS04154+2823 7.57 0.05 7.07 0.05 6.12 0.05 5.52 0.05 1.91 0.04 -0.38 0.22 yes yes yes yes yes 041834.4+283030 V410 X-ray 2 8.35 0.05 8.09 0.05 7.80 0.05 7.55 0.05 3.41 0.04 0.31 0.22 yes yes yes yes no 041840.2+282424 V410 X-ray 4 8.91 0.05 8.64 0.05 8.44 0.05 8.43 0.05 8.09 0.08 > 1.60 > -2.59 yes no no no 041840.6+281915 V892 Tau < 6.62 < 6.10 3.61 0.05 < 3.52 < 0.45 < -2.30 < -4.90 c d 041841.3+282725 LR1 9.50 0.05 8.92 0.05 8.44 0.05 7.95 0.05 4.65 0.04 0.38 0.22 > -0.29 yes yes yes yes yes 041842.5+281849 V410 X-ray 7 8.73 0.05 8.61 0.05 8.35 0.05 8.09 0.07 5.15 0.01 > -0.30 > -2.88 yes yes yes no 041845.0+282052 V410 Anon 20 11.01 0.05 10.74 0.05 10.55 0.06 10.57 0.06 > 10.20 > 0.49 > -3.20 no no 041847.0+282007 Hubble 4 7.09 0.05 7.04 0.05 6.95 0.05 6.96 0.05 6.78 0.01 > 0.18 > -4.19 no no no no 041851.1+281433 KPNO-2 12.25 0.05 12.11 0.06 12.02 0.06 11.84 0.07 > 9.59 > 1.59 no no 041851.4+282026 CoKu Tau/1 10.22 0.05 9.02 0.05 7.72 0.05 5.87 0.05 1.07 0.04 -0.98 0.22 < -2.55 yes yes yes yes yes c 041858.1+281223 IRAS04158+2805 9.23 0.05 8.54 0.05 7.85 0.06 6.84 0.05 2.73 0.04 -0.07 0.22 -2.51 0.22 yes yes yes yes yes 041901.1+281942 V410 X-ray 6 8.76 0.05 8.67 0.05 8.54 0.05 8.26 0.05 3.82 0.04 0.69 0.22 yes yes yes yes no 041901.2+280248 KPNO-12 13.97 0.06 13.61 0.06 13.23 0.08 12.75 0.08 > 10.13 > 1.74 > -0.54 no no 041901.9+282233 V410 Tau X-ray 5a 9.64 0.05 9.55 0.05 9.43 0.05 9.39 0.05 8.88 0.12 > 1.59 > -1.28 yes yes no no 041912.8+282933 FQ Tau AB 8.78 0.05 8.42 0.05 8.12 0.05 7.41 0.05 4.85 0.04 2.16 0.22 yes yes yes yes yes 041915.8+290626 BP Tau 7.27 0.05 6.90 0.05 6.65 0.05 5.71 0.05 2.52 0.04 0.71 0.22 yes yes yes yes yes 041926.2+282614 V819 Tau 8.20 0.05 8.29 0.05 8.11 0.05 8.06 0.05 6.29 0.05 yes yes no no 041935.4+282721 FR Tau 9.42 0.05 8.93 0.05 8.25 0.05 7.27 0.05 4.84 0.04 3.14 0.22 yes yes yes yes yes 041941.2+274948 LkCa 7 AB 8.11 0.05 8.11 0.05 8.04 0.05 7.99 0.05 7.75 0.06 > 1.94 no no no no 041942.5+271336 IRAS04166+2706 12.84 0.06 11.32 0.05 10.49 0.06 9.75 0.06 2.93 0.04 -1.92 0.22 -4.53 0.34 yes yes-faint yes-faint yes 041958.4+270957 IRAS04169+2702 8.41 0.05 7.15 0.05 6.29 0.05 5.33 0.05 0.66 0.04 < -2.30 -5.40 0.34 yes yes yes yes 042025.5+270035 J04202555+2700355 10.99 0.05 10.77 0.05 10.44 0.06 9.74 0.05 6.13 0.04 2.49 0.22 yes yes yes-faint yes yes 042039.1+271731 2MASS J04203918+2717317 9.42 0.05 9.39 0.05 9.35 0.05 9.29 0.05 8.83 0.10 > 1.50 no no no no 042107.9+270220 CFHT-19 7.54 0.05 6.66 0.05 6.01 0.05 5.10 0.05 1.61 0.04 -1.18 0.22 < -3.27 yes yes yes yes yes c 042110.3+270137 IRAS04181+2654B 9.03 0.05 8.24 0.05 7.60 0.05 6.70 0.05 2.69 0.04 -0.47 0.22 < -3.97 yes yes yes yes yes b c 042111.4+270109 IRAS04181+2654A 8.60 0.05 7.56 0.05 6.71 0.05 5.71 0.05 1.64 0.04 -1.04 0.22 -4.21 0.34 yes yes yes yes yes b 042134.5+270138 J04213459+2701388 9.86 0.05 9.65 0.05 9.35 0.05 8.98 0.05 7.18 0.05 > 1.64 yes yes yes yes 042146.3+265929 CFHT-10 11.54 0.05 11.32 0.05 11.05 0.06 10.45 0.06 7.26 0.05 > 1.45 yes no yes-faint yes 042154.5+265231 J04215450+2652315 13.22 0.06 13.12 0.06 12.90 0.07 12.80 0.08 10.50 0.22 > 1.66 yes-faint no no no 042155.6+275506 DE Tau 7.07 0.05 6.73 0.05 6.40 0.05 5.78 0.05 2.58 0.04 -0.19 0.22 yes yes yes yes yes 042157.4+282635 RY Tau < 6.62 < 6.10 3.60 0.05 < 3.52 < 0.45 < -2.30 -4.24 0.34 042158.8+281806 HD283572 6.86 0.05 6.86 0.05 6.81 0.05 6.78 0.05 6.76 0.05 > 1.24 no no no no 042200.6+265732 FS Tau B 9.66 0.05 8.40 0.05 7.23 0.05 5.95 0.05 1.58 0.04 -0.68 0.22 < -4.14 yes yes yes yes yes b c 042202.1+265730 FS Tau Aab 6.75 0.05 6.30 0.05 5.81 0.05 4.99 0.05 1.33 0.04 > 0.05 yes yes yes yes 042203.1+282538 LkCa 21 8.26 0.05 8.22 0.05 8.14 0.05 8.06 0.05 8.06 0.09 > 1.23 no no no no 042216.4+254911 CFHT-14 11.48 0.05 11.34 0.05 11.28 0.06 11.23 0.06 > 9.51 > 1.16 no no 042216.7+265457 CFHT-21 7.77 0.05 7.26 0.05 6.85 0.05 6.30 0.05 3.29 0.04 1.18 0.22 yes yes yes yes yes 042224.0+264625 2MASS J04222404+2646258 9.52 0.05 9.40 0.05 9.34 0.05 9.33 0.05 9.07 0.12 > 1.56 no no no no 042307.7+280557 IRAS04200+2759 8.43 0.05 7.81 0.05 7.28 0.05 6.44 0.05 3.23 0.04 0.76 0.22 yes yes yes yes yes 042339.1+245614 FT Tau 7.93 0.05 7.46 0.05 7.19 0.05 6.29 0.05 3.15 0.04 0.28 0.22 yes yes yes yes yes 042426.4+264950 CFHT-9 11.16 0.05 10.88 0.05 10.51 0.06 9.83 0.05 6.78 0.05 > 0.77 yes yes-faint yes yes 042444.5+261014 IRAS04216+2603 8.08 0.05 7.57 0.05 7.14 0.05 6.32 0.05 3.53 0.04 0.16 0.22 -2.47 0.22 yes yes yes yes yes 042445.0+270144 J1-4423 10.21 0.05 10.15 0.05 10.06 0.06 10.11 0.06 > 9.49 > 1.05 no no 042449.0+264310 RXJ0424.8 7.73 0.05 7.70 0.05 7.69 0.05 7.65 0.05 7.40 0.06 > 1.02 no no no no 042457.0+271156 IP Tau 7.77 0.05 7.45 0.05 7.24 0.05 6.60 0.05 3.48 0.04 0.74 0.22 yes yes yes yes yes 042517.6+261750 J1-4872 AB 8.21 0.05 8.20 0.05 8.08 0.05 8.06 0.05 7.77 0.07 > 1.10 no no no no 042629.3+262413 KPNO-3 11.41 0.05 10.99 0.05 10.49 0.06 9.72 0.05 6.86 0.05 > 1.09 yes yes-faint yes yes 042630.5+244355 J04263055+2443558 12.57 0.05 12.21 0.06 11.76 0.06 11.08 0.06 8.87 0.15 > 1.09 yes no no yes 042653.5+260654 FV Tau AB < 6.62 < 6.10 5.23 0.05 4.56 0.05 1.54 0.04 -0.45 0.22 yes yes yes 042654.4+260651 FV Tau/c AB 8.01 0.05 7.58 0.05 7.05 0.05 6.29 0.05 3.88 0.04 > 0.72 > -1.64 yes yes yes yes 042656.2+244335 IRAS04239+2436 7.61 0.05 6.32 0.05 5.38 0.05 4.50 0.05 < 0.45 -2.25 0.22 -4.63 0.34 yes yes 042657.3+260628 KPNO-13 8.75 0.05 8.33 0.05 7.99 0.06 7.35 0.05 5.32 0.04 > 0.93 > -2.25 yes yes yes yes 042702.6+260530 DG Tau B 8.77 0.05 5.88 0.05 5.24 0.05 0.78 0.04 -2.24 0.22 -5.12 0.34 yes yes yes b 042702.8+254222 DF Tau AB < 6.62 < 6.10 5.08 0.05 4.50 0.05 2.19 0.04 0.70 0.22 yes yes yes 042704.6+260616 DG Tau A < 6.62 < 6.10 4.67 0.05 3.55 0.05 < 0.45 < -2.30 < -4.46 b c 042727.9+261205 KPNO-4 12.57 0.05 12.37 0.06 12.21 0.06 12.08 0.06 10.66 0.28 > 1.05 yes no no no 042745.3+235724 CFHT-15 13.24 0.06 13.15 0.06 13.25 0.07 13.05 0.10 > 10.55 > 1.06 no no 042757.3+261918 IRAS04248+2612 AB 9.83 0.06 9.10 0.05 8.28 0.05 7.10 0.05 2.27 0.04 -1.52 0.22 -4.39 0.34 yes yes yes yes yes 042838.9+265135 LDN 1521F-IRS 15.33 0.08 14.25 0.07 13.45 0.10 12.04 0.07 6.16 0.04 0.57 0.22 -4.28 0.34 yes yes-faint no no 042842.6+271403 J04284263+2714039 AB 9.76 0.05 9.53 0.05 9.21 0.05 8.83 0.05 6.21 0.05 > 0.88 yes yes yes yes 042900.6+275503 J04290068+2755033 12.30 0.05 11.99 0.05 11.60 0.06 10.92 0.06 8.06 0.07 > 0.88 yes no no yes 042904.9+264907 IRAS04260+2642 10.08 0.05 9.40 0.05 8.83 0.05 8.07 0.05 3.60 0.04 0.06 0.22 yes yes yes yes yes 042920.7+263340 J1-507 8.56 0.05 8.55 0.05 8.47 0.05 8.46 0.05 8.29 0.10 > 1.04 no no no no 042921.6+270125 IRAS04263+2654 8.06 0.05 7.67 0.05 7.31 0.05 6.69 0.05 3.41 0.04 1.11 0.22 yes yes yes yes yes 042923.7+243300 GV Tau AB < 6.62 < 6.10 < 3.49 < 3.52 < 0.45 < -2.30 < -1.49 c d 042929.7+261653 FW Tau ABC 9.09 0.05 9.01 0.05 8.88 0.05 8.88 0.05 7.52 0.06 > 1.07 yes yes no no 042930.0+243955 IRAS04264+2433 10.21 0.05 9.43 0.05 8.60 0.05 6.72 0.05 1.12 0.04 -1.37 0.22 > -1.94 yes yes yes yes yes 042941.5+263258 DH Tau AB 7.63 0.05 7.33 0.05 7.20 0.05 6.86 0.05 3.37 0.04 0.82 0.22 yes yes yes yes yes 042942.4+263249 DI Tau AB 8.21 0.05 8.22 0.05 8.14 0.05 8.11 0.05 > 0.72 no no 042945.6+263046 KPNO-5 11.05 0.05 11.02 0.05 10.94 0.06 10.83 0.06 > 9.71 > 0.90 no no 042951.5+260644 IQ Tau 6.81 0.05 6.37 0.05 6.07 0.05 5.53 0.05 2.82 0.04 0.32 0.22 yes yes yes yes yes 042959.5+243307 CFHT-20 9.02 0.05 8.55 0.05 8.32 0.05 7.84 0.05 4.91 0.04 2.06 0.22 yes yes yes yes yes 043007.2+260820 KPNO-6 13.12 0.06 12.77 0.06 12.42 0.06 11.58 0.06 9.20 0.19 > 1.01 yes-faint no no yes 043023.6+235912 CFHT-16 13.23 0.06 13.15 0.06 13.04 0.08 12.99 0.09 > 10.54 > 1.00 no no 043029.6+242645 FX Tau AB 7.22 0.05 6.96 0.05 6.69 0.05 5.97 0.05 3.03 0.04 1.09 0.22 yes yes yes yes yes 043044.2+260124 DK Tau AB < 6.62 < 6.10 5.52 0.05 4.78 0.05 1.85 0.04 0.08 0.22 0.57 0.22 yes yes yes 043050.2+230008 IRAS04278+2253 < 6.62 < 6.10 < 3.49 < 3.52 < 0.45 -1.87 0.22 -3.88 0.34 043051.3+244222 ZZ Tau AB 8.08 0.05 7.90 0.05 7.61 0.05 6.94 0.05 4.53 0.04 > 0.72 > -4.46 yes yes yes yes b 043051.7+244147 ZZ Tau IRS 8.11 0.05 7.38 0.05 6.73 0.05 5.78 0.05 2.01 0.04 -0.99 0.22 -3.61 0.22 yes yes yes yes yes b 043057.1+255639 KPNO-7 12.62 0.05 12.28 0.05 11.99 0.06 11.25 0.06 8.62 0.12 > 1.23 yes no no yes 043114.4+271017 JH56 8.72 0.05 8.75 0.05 8.66 0.05 8.60 0.05 6.76 0.02 > 0.75 yes yes no no 043119.0+233504 J04311907+2335047 11.66 0.05 11.53 0.05 11.56 0.06 11.46 0.06 > 10.59 > 0.86 no no 043123.8+241052 V927 Tau AB 8.52 0.05 8.47 0.05 8.38 0.05 8.38 0.05 8.19 0.09 > 0.91 no no no no 043126.6+270318 CFHT-13 12.90 0.06 12.75 0.06 12.72 0.07 12.70 0.07 10.72 0.29 > 0.68 yes no no no 043150.5+242418 HK Tau AB 7.71 0.05 7.35 0.05 7.10 0.05 6.58 0.05 2.31 0.04 -0.81 0.22 -3.02 0.22 yes yes yes yes yes 043158.4+254329 J1-665 9.35 0.05 9.29 0.05 9.24 0.05 9.22 0.05 9.04 0.17 > 1.08 no no no no 043203.2+252807 J04320329+2528078 10.30 0.05 10.20 0.05 10.13 0.06 10.09 0.06 > 9.67 > 1.03 no no 043215.4+242859 Haro6-13 < 6.62 < 6.10 5.49 0.05 4.85 0.05 0.88 0.04 -1.43 0.22 -4.02 0.34 yes yes yes 043217.8+242214 CFHT-7 AB 9.98 0.05 9.87 0.05 9.76 0.05 9.72 0.05 9.30 0.28 > 0.86 yes no no no 043218.8+242227 V928 Tau AB 7.86 0.05 7.82 0.05 7.72 0.05 7.64 0.05 7.54 0.06 > 0.84 no no no no 043223.2+240301 J04322329+2403013 10.89 0.05 10.83 0.05 10.79 0.06 10.67 0.06 > 9.82 > 0.91 no no 043230.5+241957 FY Tau 7.18 0.05 6.76 0.05 6.50 0.05 5.99 0.05 3.67 0.04 yes yes yes yes 043231.7+242002 FZ Tau < 6.62 < 6.10 5.27 0.05 4.58 0.05 2.06 0.04 0.31 0.22 yes yes yes 043232.0+225726 IRAS04295+2251 8.63 0.05 7.72 0.05 6.83 0.05 5.32 0.05 1.40 0.04 -1.32 0.22 -3.93 0.34 yes yes yes yes yes 043243.0+255231 UZ Tau Aab < 6.62 < 6.10 5.63 0.05 4.79 0.05 1.54 0.04 -0.69 0.22 -2.15 0.22 yes yes yes b 043249.1+225302 JH112 7.41 0.05 7.12 0.05 6.83 0.05 5.89 0.05 2.53 0.04 0.72 0.22 yes yes yes yes yes 043250.2+242211 CFHT-5 10.46 0.05 10.27 0.05 10.09 0.06 10.07 0.06 9.56 0.29 > 1.16 > -1.44 yes no no no 043301.9+242100 MHO-8 9.32 0.05 9.21 0.05 9.14 0.05 9.09 0.05 8.92 0.15 > 0.88 no no no no 043306.2+240933 GH Tau AB 7.08 0.05 6.77 0.05 6.50 0.05 6.03 0.05 3.17 0.04 0.43 0.22 yes yes yes yes yes 043306.6+240954 V807 Tau AB < 6.62 6.21 0.05 5.96 0.05 5.57 0.05 2.96 0.04 0.36 0.22 yes yes yes yes 043307.8+261606 KPNO-14 9.78 0.05 9.67 0.06 9.60 0.05 9.58 0.05 9.04 0.12 > 1.44 > -1.91 yes yes-faint no no 043309.4+224648 CFHT-12 10.86 0.05 10.63 0.05 10.34 0.06 9.95 0.06 8.25 0.07 > 1.16 yes yes-faint yes yes 043310.0+243343 V830 Tau 8.41 0.05 8.41 0.05 8.37 0.05 8.32 0.05 8.14 0.08 > 1.03 no no no no 043314.3+261423 IRAS04301+2608 12.05 0.05 11.72 0.05 11.29 0.06 9.54 0.05 3.28 0.04 1.12 0.22 > -0.95 yes yes yes-faint yes-faint yes 043316.5+225320 IRAS04302+2247 10.29 0.05 9.88 0.05 9.72 0.05 9.71 0.06 3.57 0.04 -1.88 0.22 -4.51 0.34 yes yes yes-faint no no 043319.0+224634 IRAS04303+2240 < 6.62 < 6.10 4.77 0.05 3.73 0.05 1.43 0.04 -0.11 0.22 yes yes yes 043334.0+242117 GI Tau 6.87 0.05 6.31 0.05 5.79 0.05 5.12 0.05 2.15 0.04 yes yes yes yes 043334.5+242105 GK Tau < 6.62 < 6.10 5.79 0.05 5.14 0.05 1.70 0.04 -0.23 0.22 yes yes yes 043336.7+260949 IS Tau AB 7.85 0.05 7.46 0.05 6.94 0.05 6.03 0.05 3.65 0.04 2.08 0.22 > -0.83 yes yes yes yes yes 043339.0+252038 DL Tau 6.95 0.05 6.37 0.05 5.92 0.05 5.13 0.05 2.19 0.04 -0.25 0.22 -2.44 0.22 yes yes yes yes yes 043342.9+252647 J04334291+2526470 12.76 0.06 12.63 0.06 12.52 0.07 12.47 0.07 > 11.05 > 1.43 no no 043352.0+225030 CI Tau 6.99 0.05 6.53 0.05 6.17 0.05 5.33 0.05 2.37 0.04 -0.80 0.22 yes yes yes yes yes 043352.5+225626 2MASS J04335252+2256269 8.79 0.05 8.71 0.05 8.63 0.05 8.60 0.05 8.32 0.09 > 1.41 no no no no 043354.7+261327 IT Tau AB 7.35 0.05 6.98 0.05 6.63 0.05 6.05 0.05 3.53 0.04 0.83 0.22 > -1.28 yes yes yes yes yes 043410.9+225144 JH108 9.30 0.05 9.27 0.05 9.19 0.05 9.17 0.05 8.88 0.12 > 1.15 no no no no 043415.2+225030 CFHT-1 11.23 0.05 11.10 0.05 10.98 0.06 11.02 0.06 > 9.94 > 1.00 no no 043439.2+250101 Wa Tau 1 7.83 0.05 7.79 0.05 7.75 0.05 7.73 0.05 7.67 0.07 > 0.85 no no no no 043455.4+242853 AA Tau 7.29 0.05 6.84 0.05 6.44 0.05 5.65 0.05 2.81 0.04 -0.14 0.22 -2.47 0.22 yes yes yes yes yes 043508.5+231139 CFHT-11 11.19 0.05 11.12 0.05 11.04 0.06 10.99 0.06 10.23 0.20 > 0.37 yes no no no 043520.2+223214 HO Tau 8.90 0.05 8.52 0.05 8.38 0.05 7.73 0.05 4.85 0.04 2.43 0.22 yes yes yes yes yes 043520.8+225424 FF Tau AB 8.45 0.05 8.44 0.05 8.42 0.05 8.36 0.05 8.15 0.09 > 1.26 no no no no 043527.3+241458 DN Tau 7.47 0.05 7.16 0.05 6.78 0.05 6.03 0.05 3.04 0.04 0.44 0.22 > 0.04 yes yes yes yes yes 043535.3+240819 IRAS04325+2402 A 9.93 0.05 9.28 0.05 9.06 0.05 8.54 0.05 1.43 0.04 -2.26 0.22 -5.07 0.34 yes yes yes yes yes 043540.9+241108 CoKu Tau/3 AB 7.43 0.05 6.95 0.05 6.48 0.05 5.64 0.05 3.31 0.04 1.33 0.22 > -2.14 yes yes yes yes yes 043541.8+223411 KPNO-8 11.64 0.05 11.54 0.05 11.43 0.06 11.46 0.06 > 10.71 > 1.12 no no 043545.2+273713 J04354526+2737130 13.18 0.06 13.11 0.06 12.93 0.07 13.07 0.11 > 10.62 > 1.47 no no 043547.3+225021 HQ Tau < 6.62 < 6.10 5.61 0.05 4.47 0.05 1.65 0.04 -0.18 0.22 yes yes yes 043551.0+225240 KPNO-15 9.79 0.05 9.72 0.05 9.66 0.05 9.65 0.05 9.71 0.11 > 0.72 no no no no 043551.4+224911 KPNO-9 13.63 0.06 13.52 0.06 13.70 0.12 13.41 0.17 > 10.93 > 0.86 no no 043552.0+225503 2MASS J04355209+2255039 9.56 0.05 9.52 0.05 9.39 0.05 9.35 0.06 > 0.50 no no 043552.7+225423 HP Tau AB < 6.62 6.20 0.05 5.65 0.05 4.88 0.05 1.49 0.04 -1.93 0.22 -4.48 0.34 yes yes yes yes 043552.8+225058 2MASS J04355286+2250585 9.46 0.05 9.36 0.05 9.28 0.05 9.29 0.05 9.10 0.13 > 0.93 no no no no 043553.4+225408 HP Tau/G3 AB 8.62 0.05 8.60 0.05 8.51 0.05 8.47 0.06 > -0.03 > -2.19 no no 043554.1+225413 HP Tau/G2 7.19 0.05 7.17 0.05 7.11 0.05 7.02 0.05 > -0.03 > -2.35 no no 043556.8+225436 Haro 6-28 AB 8.61 0.05 8.18 0.05 7.85 0.05 7.14 0.05 4.39 0.04 > 0.70 > -2.24 yes yes yes yes 043558.9+223835 2MASS J04355892+2238353 8.15 0.05 8.19 0.05 8.10 0.05 8.06 0.05 > 1.12 no no 043610.3+215936 J04361030+2159364 13.02 0.06 12.74 0.06 12.41 0.06 11.74 0.06 9.01 0.18 > 1.07 yes-faint no no yes 043610.3+225956 CFHT-2 11.63 0.05 11.43 0.05 11.34 0.06 11.32 0.06 > 10.61 > 1.48 > -3.51 no no 043619.0+254258 LkCa 14 8.52 0.05 8.54 0.05 8.51 0.05 8.45 0.05 8.24 0.10 > 0.99 > -0.98 no no no no 043638.9+225811 CFHT-3 11.79 0.05 11.69 0.05 11.59 0.06 11.57 0.06 > 8.55 > 1.12 no no 043649.1+241258 HD 283759 8.32 0.05 8.25 0.05 8.30 0.05 8.20 0.05 6.64 0.05 1.10 0.22 > 0.51 yes yes yes no no 043800.8+255857 ITG 2 9.60 0.05 9.47 0.05 9.37 0.05 9.31 0.05 9.17 0.19 > 0.96 > -2.05 no no no no 043814.8+261139 J04381486+2611399 10.80 0.05 10.21 0.05 9.64 0.05 8.92 0.05 4.98 0.04 > 0.80 > -1.11 yes yes yes yes 043815.6+230227 RXJ0438.2+2302 9.69 0.05 9.69 0.05 9.64 0.05 9.60 0.05 > 9.35 > 1.08 no no 043821.3+260913 GM Tau 9.27 0.05 8.77 0.05 8.43 0.05 7.81 0.05 5.33 0.04 > 0.97 > -1.31 yes yes yes yes 043828.5+261049 DO Tau < 6.62 < 6.10 5.26 0.05 4.77 0.05 1.09 0.04 -1.37 0.22 -3.92 0.34 yes yes yes 043835.2+261038 HV Tau AB 7.65 0.05 7.59 0.05 7.49 0.05 7.46 0.05 > 0.72 > -3.65 no no 043835.4+261041 HV Tau C 11.33 0.14 10.74 0.05 10.22 0.05 9.38 0.04 3.52 0.04 -0.09 0.22 yes no yes yes yes e 043858.5+233635 J0438586+2336352 10.51 0.05 9.84 0.05 6.39 0.05 > 0.85 yes 043901.6+233602 J0439016+2336030 9.76 0.05 9.18 0.05 6.28 0.05 > 2.30 yes 043903.9+254426 CFHT-6 10.75 0.05 10.45 0.05 10.02 0.06 9.14 0.05 6.51 0.05 > 0.47 > -0.54 yes yes yes yes c 043906.3+233417 J0439064+2334179 10.73 0.05 10.62 0.06 > 9.32 043913.8+255320 IRAS04361+2547 AB 8.00 0.05 7.08 0.05 6.46 0.05 4.82 0.05 < 0.45 < -2.30 < -4.73 yes yes 043917.7+222103 LkCa 15 7.61 0.05 7.41 0.05 7.23 0.05 6.64 0.05 3.11 0.04 -0.40 0.22 -2.47 0.22 yes yes yes yes yes 043920.9+254502 GN Tau B 6.99 0.05 6.58 0.05 6.21 0.05 5.42 0.05 2.82 0.04 1.59 0.22 > -2.43 yes yes yes yes yes 043935.1+254144 IRAS04365+2535 7.22 0.05 < 6.10 4.87 0.05 4.16 0.05 < 0.45 -2.17 0.22 < -3.82 c 043947.4+260140 CFHT-4 9.54 0.05 9.07 0.05 8.60 0.05 7.78 0.05 4.95 0.04 > 0.91 > -4.76 yes yes yes yes 043953.9+260309 IRAS 04368+2557 13.39 0.11 11.15 0.08 10.09 0.07 9.73 0.08 2.69 0.04 < -2.30 < -4.40 yes-faint yes-faint yes c d 043955.7+254502 IC2087 IRS < 6.62 < 6.10 < 3.49 < 3.52 < 0.45 -2.17 0.22 > -5.41 c 044001.7+255629 CFHT-17 AB 10.15 0.05 9.96 0.05 9.87 0.05 9.82 0.06 9.10 0.18 > 0.74 > -2.26 yes yes-faint no no 044008.0+260525 IRAS 04370+2559 7.96 0.05 7.38 0.05 6.93 0.05 5.93 0.05 2.43 0.04 0.75 0.22 > -1.78 yes yes yes yes yes 044039.7+251906 J04403979+2519061 AB 9.84 0.05 9.68 0.06 9.62 0.05 9.57 0.05 7.55 0.05 > 1.00 > -2.43 yes yes-faint no no 044049.5+255119 JH223 8.90 0.05 8.60 0.05 8.24 0.05 7.74 0.05 5.13 0.04 2.20 0.22 > 0.93 yes yes yes yes yes 044104.2+255756 Haro 6-32 9.66 0.05 9.56 0.06 9.49 0.05 9.46 0.06 9.59 0.33 > 0.70 > -0.83 no no no no 044104.7+245106 IW Tau AB 8.13 0.05 8.15 0.05 8.08 0.05 8.03 0.05 7.97 0.07 > 1.08 no no no no 044108.2+255607 ITG 33 A 9.68 0.05 9.05 0.05 8.49 0.05 7.73 0.05 4.60 0.04 > 0.67 > 0.73 yes yes yes yes 044110.7+255511 ITG 34 10.78 0.05 10.35 0.05 9.92 0.06 9.22 0.05 6.48 0.05 > 0.74 > -1.25 yes yes yes yes 044112.6+254635 IRAS04381+2540 9.15 0.05 7.76 0.05 6.72 0.05 5.75 0.05 1.43 0.04 -1.92 0.22 -4.33 0.34 yes yes yes yes yes 044138.8+255626 IRAS04385+2550 8.24 0.05 7.74 0.05 7.13 0.05 6.05 0.05 1.86 0.04 -0.90 0.22 -2.73 0.22 yes yes yes yes yes 044148.2+253430 J04414825+2534304 11.43 0.05 10.93 0.05 10.50 0.06 9.54 0.05 6.33 0.05 > 1.02 > -4.57 yes yes-faint yes yes 044205.4+252256 LkHa332/G2 AB 7.99 0.05 7.87 0.05 7.74 0.05 7.70 0.05 7.18 0.05 > -4.69 yes yes no no b 044207.3+252303 LkHa332/G1 AB 7.65 0.05 7.62 0.05 7.53 0.05 7.51 0.06 > 0.51 > -2.34 no no b 044207.7+252311 V955 Tau Ab 6.99 0.05 6.58 0.05 6.15 0.05 5.40 0.05 2.76 0.04 -0.56 0.22 > -2.07 yes yes yes yes yes b 044221.0+252034 CIDA-7 9.51 0.05 9.11 0.05 8.65 0.05 7.79 0.05 4.20 0.04 1.13 0.22 > -1.18 yes yes yes yes yes 044237.6+251537 DP Tau 7.57 0.05 6.90 0.05 6.34 0.05 5.37 0.05 1.90 0.04 0.54 0.22 > -1.70 yes yes yes yes yes 044303.0+252018 GO Tau 8.90 0.05 8.64 0.05 8.21 0.05 7.42 0.05 4.30 0.04 1.03 0.22 > 0.53 yes yes yes yes yes 044427.1+251216 IRAS04414+2506 9.56 0.05 9.00 0.05 8.36 0.05 7.43 0.05 4.25 0.04 1.76 0.22 > 0.05 yes yes yes yes yes 044642.6+245903 RXJ04467+2459 10.05 0.05 9.97 0.05 9.87 0.06 9.90 0.05 9.53 0.26 > 0.96 no no no no ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/cdsFunctional.dat0000644000175100001710000000713700000000000023016 0ustar00vstsdockerJ/A+A/557/A19 Mass and age of extreme low-mass white dwarfs (Althaus+, 2013) ================================================================================ New evolutionary sequences for extremely low-mass white dwarfs: Homogeneous mass and age determinations and asteroseismic prospects. Althaus L.G., Miller Bertolami M.M., Corsico A.H. =2013A&A...557A..19A ================================================================================ ADC_Keywords: Stars, white dwarf ; Models, evolutionary ; Stars, masses ; Stars, ages ; Effective temperatures Keywords: white dwarfs - binaries: general - stars: evolution - stars: oscillations - stars: interiors Abstract: The number of detected extremely low mass (ELM) white dwarf stars has increased drastically in recent year thanks to the results of many surveys. In addition, some of these stars have been found to exhibit pulsations, making them potential targets for asteroseismology. We provide a fine and homogeneous grid of evolutionary sequences for helium (He) core white dwarfs for the whole range of their expected masses (0.15<~M_*_/M_{sun}_<~0.45), including the mass range for ELM white dwarfs (M_*_/M_{sun}_<~0.20). The grid is appropriate for mass and age determination of these stars, as well as to study their adiatabic pulsational properties. White dwarf sequences have been computed by performing full evolutionary calculations that consider the main energy sources and processes of chemical abundance changes during white dwarf evolution. Description: In file elm.dat are data presented in the middle and lower panels of Fig. 5 and 6. File Summary: -------------------------------------------------------------------------------- FileName Lrecl Records Explanations -------------------------------------------------------------------------------- ReadMe 80 . This file elm.dat 133 4183 Interpolated M(logTeff, logg) relation -------------------------------------------------------------------------------- See also: III/235 : Spectroscopically Identified White Dwarfs (McCook+, 2008) J/ApJ/730/67 : Radial velocities of low-mass white dwarfs (Brown+, 2011) J/ApJ/731/17 : Variability of low-mass stars in SDSS Stripe 82 (Becker+ 2011) J/ApJ/723/1072 : The ELM survey. I. Low-mass white dwarfs (Brown+, 2010) Byte-by-byte Description of file: table2.dat -------------------------------------------------------------------------------- Bytes Format Units Label Explanations -------------------------------------------------------------------------------- 1- 18 F18.16 [K] logTe [3.85,4.79] Log of effective temperature 20- 37 F18.16 [cm/s2] logg [3,7.7] Surface gravity 39- 58 F20.17 Msun Mass [0.1/0.6]?=-1 Mass fit 60- 83 E24.18 Msun e_Mass ?=-1 Mass fit error 85-108 E24.18 Myr Age ?=-1 Age fit 110-133 E24.18 Myr e_Age ?=-1 Age fit error -------------------------------------------------------------------------------- Acknowledgements: Leandro G. Althaus, althaus( at )fcaglp.unlp.edu.ar, Universidad Nacional de La Plata ================================================================================ (End) Emmanuelle Perret [CDS] 16-Jul-2013 -------------------------------------------------------------------------------- 3.8500000000000001|3.0000000000000000| 0.24458909000000001|3.78770000000000018E-003| 34.946352740000002| 8.2766551100000001 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/cdsFunctional2.dat0000644000175100001710000000436600000000000023101 0ustar00vstsdockerJ/A+A/642/A176 Chemical evolution of dSph galaxy Sextans (Theler+, 2020) ================================================================================ The chemical evolution of the dwarf spheroidal galaxy Sextans. Theler R., Jablonka P., Lucchesi R., Lardo C., North P., Irwin M., Battaglia G., Hill V., Tolstoy E., Venn K., Helmi A., Kaufer A., Primas F., Shetrone M. =2020A&A...642A.176T (SIMBAD/NED BibCode) ================================================================================ ADC_Keywords: Galaxies, nearby ; Abundances ; Equivalent widths ; Radial velocities ; Effective temperatures Keywords: stars: abundances - galaxies: dwarf - galaxies: evolution Abstract: [--- snip ---] Description: [--- snip ---] File Summary: -------------------------------------------------------------------------------- FileName Lrecl Records Explanations -------------------------------------------------------------------------------- ReadMe 80 . This file table6.dat 33 89 Four stellar parameters for the probables members -------------------------------------------------------------------------------- See also: [--- snip ---] Byte-by-byte Description of file: table6.dat -------------------------------------------------------------------------------- Bytes Format Units Label Explanations -------------------------------------------------------------------------------- 1- 7 A7 --- ID Star ID 9- 12 I4 K Teff Effective temperature 14- 17 F4.2 [cm/s2] logg Surface gravity 19- 22 F4.2 km/s vturb Micro-turbulence velocity 24- 28 F5.2 [-] [Fe/H] Metallicity 30- 33 F4.2 [-] e_[Fe/H] ? rms uncertainty on [Fe/H] -------------------------------------------------------------------------------- ================================================================================ (End) Patricia Vannier [CDS] 09-Jun-2020 -------------------------------------------------------------------------------- S05-5 4337 0.77 1.8 -2.07 S08-229 4625 1.23 1.23 -1.50 S05-10 4342 0.91 1.82 -2.11 0.14 S05-47 4654 1.28 1.74 -1.64 0.16 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/cds_malformed.dat0000644000175100001710000000446000000000000023015 0ustar00vstsdocker Title: Spitzer Observations of NGC 1333: A Study of Structure and Evolution in a Nearby Embedded Cluster Authors: Gutermuth R.A., Myers P.C., Megeath S.T., Allen L.E., Pipher J.L., Muzerolle J., Porras A., Winston E., Fazio G. Table: Spitzer-identified YSOs: Addendum ================================================================================ Byte-by-byte Description of file: datafile3.txt -------------------------------------------------------------------------------- Bytes Format Units Label Explanations -------------------------------------------------------------------------------- 1- 3 I3 --- Index Running identification number 5- 6 I2 h RAh Hour of Right Ascension (J2000) 8- 9 I2 min RAm Minute of Right Ascension (J2000) 11- 15 F5.2 s RAs Second of Right Ascension (J2000) - continuation of description 17 A1 --- DE- Sign of the Declination (J2000) 18- 19 I2 deg DEd Degree of Declination (J2000) 21- 22 I2 arcmin DEm Arcminute of Declination (J2000) 24- 27 F4.1 arcsec DEs Arcsecond of Declination (J2000) 29- 68 A40 --- Match Literature match 70- 75 A6 --- Class Source classification (1) 77-80 F4.2 mag AK ? The K band extinction (2) 82-86 F5.2 --- Fit ? Fit of IRAC photometry (3) -------------------------------------------------------------------------------- Note (1): Asterisks mark "deeply embedded" sources with questionable IRAC colors or incomplete IRAC photometry and relatively bright MIPS 24 micron photometry. Note (2): Only provided for sources with valid JHK_S_ photometry. Note (3): Defined as the slope of the linear least squares fit to the 3.6 - 8.0 micron SEDs in log{lambda} F_{lambda} vs log{lambda} space. Extinction is not accounted for in these values. High extinction can bias Fit to higher values. 1 03 28 39.09 +31 06 01.9 I* 1.35 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/commented_header.dat0000644000175100001710000000004500000000000023474 0ustar00vstsdocker# a b c # A comment line 1 2 3 4 5 6 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/commented_header2.dat0000644000175100001710000000007400000000000023560 0ustar00vstsdocker# A comment line # Another comment line # a b c 1 2 3 4 5 6 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/conf_py.txt0000644000175100001710000000050100000000000021712 0ustar00vstsdockerimport os import sys sys.path.insert(0, os.path.abspath('..')) project = 'manno' master_doc = 'index' extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.coverage', 'sphinx.ext.mathjax', 'numpydoc', ] intersphinx_mapping = { "python": ("https://docs.python.org/3/", None), } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/continuation.dat0000644000175100001710000000004600000000000022724 0ustar00vstsdocker1 3 5 \ hello world 4 6 8 next \ line ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/daophot.dat0000644000175100001710000000360300000000000021652 0ustar00vstsdocker#K MERGERAD = INDEF scaleunit %-23.7g #K IRAF = NOAO/IRAFV2.10EXPORT version %-23s #K USER = name %-23s #K HOST = tucana computer %-23s #K DATE = 05-28-93 mm-dd-yy %-23s #K TIME = 14:46:13 hh:mm:ss %-23s #K PACKAGE = daophot name %-23s #K TASK = nstar name %-23s #K IMAGE = test imagename %-23s #K GRPFILE = test.psg.1 filename %-23s #K PSFIMAGE = test.psf.1 imagename %-23s #K NSTARFILE = test.nst.1 filename %-23s #K REJFILE = "hello world" filename %-23s #K SCALE = 1. units/pix %-23.7g #K DATAMIN = 50. counts %-23.7g #K DATAMAX = 24500. counts %-23.7g #K GAIN = 1. number %-23.7g #K READNOISE = 0. electrons %-23.7g #K OTIME = 00:07:59.0 timeunit %-23s #K XAIRMASS = 1.238106 number %-23.7g #K IFILTER = V filter %-23s #K RECENTER = yes switch %-23b #K FITSKY = no switch %-23b #K PSFMAG = 16.594 magnitude %-23.7g #K PSFRAD = 5. scaleunit %-23.7g #K FITRAD = 3. scaleunit %-23.7g #K MAXITER = 50 number %-23d #K MAXGROUP = 60 number %-23d #K FLATERROR = 0.75 percentage %-23.7g #K PROFERROR = 5. percentage %-23.7g #K CLIPEXP = 6 number %-23d #K CLIPRANGE = 2.5 sigma %-23.7g # #N ID XCENTER YCENTER MAG MERR MSKY NITER \ #U ## pixels pixels magnitudes magnitudes counts ## \ #F %-9d %-10.3f %-10.3f %-12.3f %-14.3f %-15.7g %-6d # #N SHARPNESS CHI PIER PERROR \ #U ## ## ## perrors \ #F %-23.3f %-12.3f %-6d %-13s # 14 138.538 256.405 15.461 0.003 34.85955 4 \ -0.032 0.802 0 No_error 18 18.114 280.170 22.329 0.206 30.12784 4 \ -2.544 1.104 0 No_error ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/daophot.dat.gz0000644000175100001710000000143100000000000022266 0ustar00vstsdocker‹tˇPdaophot.dat•U[oĸ@~ī¯8ŠŲG§ÃMŅd& –ĩhc“M6Th%0‚íößī™Ä[Ķė<˜ßwÎų΅ą7‡…ÅggSø Ž;ĩl¸<å*Ú$û<­~ôU ßnzsp8ŗŅÍõ˜w'ė'•(ÔZúá=Ų•i‘K‡R‹#9ŽŪĶō(K:čŪ B„Ēũ*Ę#XŲv_%ģŸ˛ĐBœ}Õė4Ȳ~÷??;Fč,CŅĮú`Ŧh°^ŗl\–Ãg“9›YRAą]ՙ†s힊vgŗ¨̤Ŧ ÍĸˇäŸqßvZŲ–oD×tsFķû8ō^‘w%ž„ŒGDQW#rëWCģ]'›MÅnß^a&y 1Įōn›ūmgŲt˜-%8}^•8["ŽęŊJ™1éō}öԌ¯Á¸ÅĻŽįrŠ’M˛ĒvE~âī53¤tL‡ccD(TiV¯ŨĄŽ%sø‚L¤jĻBWŌ9ؕPnۓčÅÉ.qkbš5ø™”P~¤Õj-áÛN˟Å"į'Rˆ1Ō'‡âöqrœIâsÂF’Ŗī戀j‚öûėÔ z\\܀3î=úˆ.QûŋÎ=.û<4`›ėVI^ኝhäžŨŌPæuŌäÁņņ[‰.ōŒ3Wî˛J (͎,ęœoz.8âJeĶl€įƒ%zØŧ~xwĪ,Dëģã:ĩüžé=B¯'LÜÛdSžZ‡9”§6´[ڞ:DĐFšŖX\h %Ú+œYjmI[omųdČë¯}ÄĩUŨžāžqßĩpO&÷ÎáŊīˆ‚üē÷ßYô…ōĢ6pWėē:ŋ Ø]îrV]‰GåęĻh߅Y´ĸ7ļĸ™ÄĐL´Tc@tjˆwŅJSBŠvđÔtb#ÃhÛ ¨ņ(|}4ĩu7ic•ŋnņG–ũFÅlšDŠåĒ&%ĘP„QąpuÔĻPņ69(DŠ:4[e_(Äå×HÁ˙ž–õ ˙Āŋ“÷‡././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/daophot2.dat0000644000175100001710000000376400000000000021744 0ustar00vstsdocker#N IMAGE XINIT YINIT ID COORDS LID \ #U imagename pixels pixels ## filename ## \ #F %-23s %-10.3f %-10.3f %-6d %-23s %-6.0f # #N XCENTER YCENTER XSHIFT YSHIFT XERR YERR CIER CERROR \ #U pixels pixels pixels pixels pixels pixels ## cerrors \ #F %-14.3f %-11.3f %-8.3f %-8.3f %-8.3f %-15.3f %-5d %-9s # #N MSKY STDEV SSKEW NSKY NSREJ SIER SERROR \ #U counts counts counts npix npix ## serrors \ #F %-18.7g %-15.7g %-15.7g %-7d %-9d %-5d %-9s # #N ITIME XAIRMASS IFILTER OTIME \ #U timeunit number name timeunit \ #F %-18.7g %-15.7g %-23s %-23s # #N RAPERT SUM AREA FLUX MAG MERR PIER PERROR \ #U scale counts pixels counts mag mag ## perrors \ #F %-12.2f %-14.7g %-11.7g %-14.7g %-7.3f %-6.3f %-5s %-9s # n8q624e8q12_cal.fits[1]76.102 2.280 1 test.stars 1 \ 76.150 2.182 0.048 -0.098 0.016 0.014 108 BadPixels \ 0.5378259 0.1369367 0.1002712 604 176 0 NoError \ 1407.892 INDEF F160W INDEF \ 4.00 0. 0. 0. INDEF INDEF 301 OffImage n8q624e8q12_cal.fits[1]81.730 3.167 2 test.stars 2 \ 76.150 2.182 -5.580 -0.985 0.016 0.014 108 BadPixels \ 0.5378259 0.1369367 0.1002712 604 176 0 NoError \ 1407.892 INDEF F160W INDEF \ 4.00 0. 0. 0. INDEF INDEF 301 OffImage ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/daophot3.dat0000644000175100001710000001736000000000000021742 0ustar00vstsdocker#K IRAF = NOAO/IRAFV2.16 version %-23s #K USER = joe name %-23s #K HOST = porteus-ATMA computer %-23s #K DATE = 2014-06-24 yyyy-mm-dd %-23s #K TIME = 00:20:18 hh:mm:ss %-23s #K PACKAGE = apphot name %-23s #K TASK = phot name %-23s # #K SCALE = 1. units %-23.7g #K FWHMPSF = 6.1 scaleunit %-23.7g #K EMISSION = yes switch %-23b #K DATAMIN = 93.232 counts %-23.7g #K DATAMAX = 4000. counts %-23.7g #K EXPOSURE = "" keyword %-23s #K AIRMASS = "" keyword %-23s #K FILTER = "" keyword %-23s #K OBSTIME = "" keyword %-23s # #K NOISE = poisson model %-23s #K SIGMA = 0.132 counts %-23.7g #K GAIN = "" keyword %-23s #K EPADU = 1152. e-/adu %-23.7g #K CCDREAD = "" keyword %-23s #K READNOISE = 0.05 e- %-23.7g # #K CALGORITHM = centroid algorithm %-23s #K CBOXWIDTH = 5. scaleunit %-23.7g #K CTHRESHOLD = 0. sigma %-23.7g #K MINSNRATIO = 1. number %-23.7g #K CMAXITER = 10 number %-23d #K MAXSHIFT = 1. scaleunit %-23.7g #K CLEAN = no switch %-23b #K RCLEAN = 1. scaleunit %-23.7g #K RCLIP = 2. scaleunit %-23.7g #K KCLEAN = 3. sigma %-23.7g # #K SALGORITHM = centroid algorithm %-23s #K ANNULUS = 24.4 scaleunit %-23.7g #K DANNULUS = 15. scaleunit %-23.7g #K SKYVALUE = 0. counts %-23.7g #K KHIST = 3. sigma %-23.7g #K BINSIZE = 0.1 sigma %-23.7g #K SMOOTH = no switch %-23b #K SMAXITER = 10 number %-23d #K SLOCLIP = 0. percent %-23.7g #K SHICLIP = 0. percent %-23.7g #K SNREJECT = 50 number %-23d #K SLOREJECT = 3. sigma %-23.7g #K SHIREJECT = 3. sigma %-23.7g #K RGROW = 0. scaleunit %-23.7g # #K WEIGHTING = constant model %-23s #K APERTURES = 23.3,6:25:5 scaleunit %-23s #K ZMAG = 25. zeropoint %-23.7g # #N IMAGE XINIT YINIT ID COORDS LID \ #U imagename pixels pixels ## filename ## \ #F %-23s %-10.3f %-10.3f %-6d %-23s %-6d # #N XCENTER YCENTER XSHIFT YSHIFT XERR YERR CIER CERROR \ #U pixels pixels pixels pixels pixels pixels ## cerrors \ #F %-14.3f %-11.3f %-8.3f %-8.3f %-8.3f %-15.3f %-5d %-9s # #N MSKY STDEV SSKEW NSKY NSREJ SIER SERROR \ #U counts counts counts npix npix ## serrors \ #F %-18.7g %-15.7g %-15.7g %-7d %-9d %-5d %-9s # #N ITIME XAIRMASS IFILTER OTIME \ #U timeunit number name timeunit \ #F %-18.7g %-15.7g %-23s %-23s # #N RAPERT SUM AREA FLUX MAG MERR PIER PERROR \ #U scale counts pixels counts mag mag ## perrors \ #F %-12.2f %-14.7g %-11.7g %-14.7g %-7.3f %-6.3f %-5d %-9s # Slope-AS40-435_median_S299.929 49.652 366 Slope-AS40-435_median_S366 \ 300.120 49.969 0.191 0.317 0.011 0.012 0 NoError \ 94.57384 0.1865725 0.09473237 2064 938 0 NoError \ 1. INDEF INDEF INDEF \ 6.00 10709.69 113.2273 1.350839 24.673 1.639 0 NoError *\ 11.00 35964.65 380.2424 3.670495 23.588 1.171 0 NoError *\ 16.00 76082.82 804.4385 3.982883 23.500 1.701 0 NoError *\ 21.00 131202.7 1385.878 134.9305 INDEF INDEF 305 BadPixels*\ 23.30 162159.5 1706.24 793.8187 INDEF INDEF 305 BadPixels* Slope-AS40-435_median_S85.452 55.434 367 Slope-AS40-435_median_S367 \ 85.458 55.484 0.006 0.050 0.008 0.006 0 NoError \ 94.59016 0.2281704 0.1264289 1623 1378 0 NoError \ 1. INDEF INDEF INDEF \ 6.00 10761.49 112.8701 85.08714 20.175 0.032 0 NoError *\ 11.00 36058.47 380.1428 100.7009 19.992 0.053 0 NoError *\ 16.00 76216.4 804.6936 100.2974 19.997 0.086 0 NoError *\ 21.00 130393.5 1386.111 -719.0389 INDEF INDEF 305 BadPixels*\ 23.30 158316.8 1706.482 -3099.61 INDEF INDEF 305 BadPixels* Slope-AS40-435_median_S848.186 56.486 368 Slope-AS40-435_median_S368 \ 848.380 56.544 0.194 0.058 0.013 0.009 0 NoError \ 94.59234 0.1647499 0.06409879 2098 903 0 NoError \ 1. INDEF INDEF INDEF \ 6.00 10735.4 113.059 40.88579 20.971 0.048 0 NoError *\ 11.00 36009.39 380.2245 43.06569 20.915 0.088 0 NoError *\ 16.00 76169.49 804.6198 58.62642 20.580 0.102 0 NoError *\ 21.00 131348.9 1386.085 235.8676 INDEF INDEF 305 BadPixels*\ 23.30 161839.2 1706.263 439.7652 INDEF INDEF 305 BadPixels* Slope-AS40-435_median_S464.199 59.384 369 Slope-AS40-435_median_S369 \ 464.273 59.617 0.074 0.233 0.010 0.011 0 NoError \ 94.60605 0.1613172 0.04022013 2314 686 0 NoError \ 1. INDEF INDEF INDEF \ 6.00 10732.46 113.3501 8.849111 22.633 0.216 0 NoError *\ 11.00 35991.75 380.3943 4.148174 23.455 0.889 0 NoError *\ 16.00 76101.38 804.4529 -4.720454 INDEF INDEF 0 NoError *\ 21.00 131053.2 1385.598 -32.75801 INDEF INDEF 0 NoError *\ 23.30 161354.6 1705.858 -29.88808 INDEF INDEF 0 NoError * Slope-AS40-435_median_S688.924 61.839 370 Slope-AS40-435_median_S370 \ 689.056 61.637 0.132 -0.202 0.009 0.017 0 NoError \ 94.56474 0.1917982 -0.04442054 2363 646 0 NoError \ 1. INDEF INDEF INDEF \ 6.00 10761.45 113.5188 26.56977 21.439 0.086 0 NoError *\ 11.00 36012.39 380.5187 28.73899 21.354 0.152 0 NoError *\ 16.00 76101.65 804.5662 18.05782 21.858 0.379 0 NoError *\ 21.00 131029.3 1385.578 2.4874 24.011 3.925 0 NoError *\ 23.30 161285.7 1705.41 14.05488 22.130 0.803 0 NoError * ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/daophot4.dat0000644000175100001710000001627100000000000021743 0ustar00vstsdocker#K IRAF = NOAO/IRAFV2.14.1 version %-23s #K USER = hannes name %-23s #K HOST = prometheus computer %-23s #K DATE = 2015-03-11 yyyy-mm-dd %-23s #K TIME = 15:26:26 hh:mm:ss %-23s #K PACKAGE = apphot name %-23s #K TASK = phot name %-23s # #K SCALE = 1. units %-23.7g #K FWHMPSF = 4.119713 scaleunit %-23.7g #K EMISSION = yes switch %-23b #K DATAMIN = INDEF counts %-23.7g #K DATAMAX = 65536. counts %-23.7g #K EXPOSURE = exposure keyword %-23s #K AIRMASS = airmass keyword %-23s #K FILTER = filter keyword %-23s #K OBSTIME = utc-obs keyword %-23s # #K NOISE = poisson model %-23s #K SIGMA = 41.66582 counts %-23.7g #K GAIN = "" keyword %-23s #K EPADU = 1. e-/adu %-23.7g #K CCDREAD = "" keyword %-23s #K READNOISE = 7.49 e- %-23.7g # #K CALGORITHM = centroid algorithm %-23s #K CBOXWIDTH = 12. scaleunit %-23.7g #K CTHRESHOLD = 3. sigma %-23.7g #K MINSNRATIO = 1. number %-23.7g #K CMAXITER = 10 number %-23d #K MAXSHIFT = 5. scaleunit %-23.7g #K CLEAN = no switch %-23b #K RCLEAN = 1. scaleunit %-23.7g #K RCLIP = 2. scaleunit %-23.7g #K KCLEAN = 3. sigma %-23.7g # #K SALGORITHM = centroid algorithm %-23s #K ANNULUS = 7.17957 scaleunit %-23.7g #K DANNULUS = 7.82043 scaleunit %-23.7g #K SKYVALUE = 0. counts %-23.7g #K KHIST = 3. sigma %-23.7g #K BINSIZE = 0.1 sigma %-23.7g #K SMOOTH = no switch %-23b #K SMAXITER = 10 number %-23d #K SLOCLIP = 3. percent %-23.7g #K SHICLIP = 3. percent %-23.7g #K SNREJECT = 50 number %-23d #K SLOREJECT = 3. sigma %-23.7g #K SHIREJECT = 3. sigma %-23.7g #K RGROW = 0. scaleunit %-23.7g # #K WEIGHTING = constant model %-23s #K APERTURES = 1.0, 2.0, 3.0, 4.0, 5.0 scaleunit %-23s #K ZMAG = 0. zeropoint %-23.7g # #N IMAGE XINIT YINIT ID COORDS LID \ #U imagename pixels pixels ## filename ## \ #F %-23s %-10.3f %-10.3f %-6d %-23s %-6d # #N XCENTER YCENTER XSHIFT YSHIFT XERR YERR CIER CERROR \ #U pixels pixels pixels pixels pixels pixels ## cerrors \ #F %-14.3f %-11.3f %-8.3f %-8.3f %-8.3f %-15.3f %-5d %-9s # #N MSKY STDEV SSKEW NSKY NSREJ SIER SERROR \ #U counts counts counts npix npix ## serrors \ #F %-18.7g %-15.7g %-15.7g %-7d %-9d %-5d %-9s # #N ITIME XAIRMASS IFILTER OTIME \ #U timeunit number name timeunit \ #F %-18.7g %-15.7g %-23s %-23s # #N RAPERT SUM AREA FLUX MAG MERR PIER PERROR \ #U scale counts pixels counts mag mag ## perrors \ #F %-12.2f %-14.7g %-11.7g %-14.7g %-7.3f %-6.3f %-5d %-9s # 20150224.010.bff.fits[*106.579 106.934 1 20150224.010.bff.coo 1 \ 106.559 108.018 -0.020 1.084 0.101 0.074 0 NoError \ 2274.581 35.8673 11.2252 507 34 0 NoError \ 15. INDEF WL 18.25805367777778 \ 1.00 9109.85 3.522305 1098.081 -4.661 0.074 0 NoError *\ 2.00 31801.22 12.6082 3122.852 -5.796 0.049 0 NoError *\ 3.00 70478.22 28.76358 5053.117 -6.319 0.045 0 NoError *\ 4.00 121419. 50.47698 6604.971 -6.609 0.046 0 NoError *\ 5.00 186154.5 78.6758 7199.989 -6.703 0.053 0 NoError *\ 6.00 266042.9 113.531 7807.418 -6.791 0.060 0 NoError *\ 7.00 358247.2 153.8083 8397.668 -6.870 0.067 0 NoError *\ 8.00 467542.2 201.7787 8580.032 -6.893 0.077 0 NoError *\ 9.00 587422. 254.4993 8542.593 -6.889 0.090 0 NoError *\ 10.00 724023.7 314.4823 8708.25 -6.910 0.102 0 NoError *\ 11.00 874403.1 380.5716 8762.004 -6.916 0.115 0 NoError *\ 12.00 1036954. 452.126 8556.425 -6.891 0.134 0 NoError *\ 13.00 1217921. 531.7312 8455.69 -6.878 0.152 0 NoError *\ 14.00 1408227. 615.5404 8130.7 -6.835 0.177 0 NoError *\ 15.00 1617583. 707.5204 8270.082 -6.854 0.194 0 NoError * 20150224.010.bff.fits[*28.377 105.125 2 20150224.010.bff.coo 2 \ 28.334 106.194 -0.043 1.069 0.057 0.057 0 NoError \ 2255.277 33.60751 14.9162 503 47 0 NoError \ 15. INDEF WL 18.25805367777778 \ 1.00 9725.537 3.433434 1982.191 -5.303 0.042 0 NoError *\ 2.00 34708.58 12.786 5872.618 -6.482 0.027 0 NoError *\ 3.00 73724.14 28.56388 9304.661 -6.982 0.024 0 NoError *\ 4.00 125125.7 50.50517 11222.5 -7.185 0.026 0 NoError *\ 5.00 189990.9 78.80913 12254.43 -7.281 0.030 0 NoError *\ 6.00 268543.3 113.428 12731.67 -7.322 0.035 0 NoError *\ 7.00 360879.8 154.1563 13214.47 -7.362 0.040 0 NoError *\ 8.00 467521.8 201.3365 13452.14 -7.382 0.046 0 NoError *\ 9.00 588086.8 254.6784 13716.38 -7.403 0.053 0 NoError *\ 10.00 723155.3 314.422 14046.6 -7.429 0.059 0 NoError *\ 11.00 872591.1 380.4647 14537.59 -7.466 0.066 0 NoError *\ 12.00 1035008. 452.6064 14254.72 -7.445 0.076 0 NoError *\ 13.00 1212656. 531.2477 14544.82 -7.467 0.083 0 NoError *\ 14.00 1404271. 615.9114 15220.43 -7.516 0.089 0 NoError *\ 15.00 1610992. 707.2085 16040.83 -7.573 0.094 0 NoError * ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/fill_values.txt0000644000175100001710000000002200000000000022560 0ustar00vstsdockera,b,c 1,2,3 a,a,4 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/fixed_width_2_line.txt0000644000175100001710000000014400000000000024006 0ustar00vstsdockerCol1 Col2 Col3 Col4 ---- --------- ---- ---- 1.2 "hello" 1 a 2.4 's worlds 2 2 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/html.html0000644000175100001710000000143200000000000021352 0ustar00vstsdocker
Column 1Column 2Column 3
1a1.05
2b2.75
3c-1.25
Column AColumn BColumn C
4d10.5
5e27.5
6f-12.5
C1C2C3
7g105.0
8h275.0
9i-125.0
././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/html2.html0000644000175100001710000000057200000000000021440 0ustar00vstsdocker Row with no data elements Some junk
A B
1 2.5000000000000000001 3
1a 1 3.5
././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/ipac.dat0000644000175100001710000000105000000000000021122 0ustar00vstsdocker\intval = 1 \floatval=2.3e3 \date = "Wed Sp 20 09:48:36 1995" \key_continue = 'IPAC keywords ' \key_continue = 'can continue across lines' \ This is an example of a valid comment | ra | dec | sai |-----v2---| sptype | | real | real | int | real | char | | unit | unit | unit | unit | ergs | | null | null | -999 | null | -999 | null 29.09056 -999 2.06000 -999 12345678901234567890123456789012345678901234567890123456789012345 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/ipac.dat.bz20000644000175100001710000000060100000000000021617 0ustar00vstsdockerBZh91AY&SYÆ "Z´ß€vPãō( L„/īßä0Yύ5O(ɨõ6IŊD4 PˆĻ$õ24ɂ`Œ„0 ŒĻŅ’Ÿĸš4Pze7ĒmũR¤•­p—oĪekm`ŽlaŽ€paûį>Ũ¨dŅĪŌäg܃[•Čëßé´ōÂ"ŗ|—yG:SÕ|ūî´ ŽÛz´rw(Rī9A]Äoü†ŒÃTÂÔI¨žlŲ–˜ËUQēÉ(ļŽ`üë,mŧŽ‚™6“’L…$|(ˆN›â°ĘŖ{‚ Đ]3âj:ŗ•äËįWmČŦĮ-Rž…’jfĻwpßP=(kÖ`Į¸ˇ~8ĖĐŅØ}›éĶ`ÅܑN$1‚Č–€././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/ipac.dat.xz0000644000175100001710000000050000000000000021561 0ustar00vstsdockerũ7zXZæÖ´F!t/åŖā&].IĮxBØFęÕčO’đŦĮT4?“ÕCm(e7)&yЖÁåĘøĖsFķ´ėGŊŨILxĨ–9;ÎÃėN"čVĄE^ŨPLr7‘ņ`ĒíRÍ9dģÂН$JŪNÂķ䟱hú#Ë\†Ą¸ ͌ÔráNāF9U­ÄŠ›Žų XŅB#ģĘČ(ÕQ îÆÕMŅÆíj†Ôæg4×öj°l ]ß~ûŪ(īũīÅ[ĒclŽq#Ž$YôĢ‹Ėļ7*n<čŖ=$¤oų3ķ–ŽK(V׿5×[á$ģđVb֙ĩļAˇ&[Äqš3MÂ2ī Ę<ķ†WL°Ēfå–Ōõr>.Fĩ`œ§娄ąÄgûYZ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/latex1.tex0000644000175100001710000000042700000000000021443 0ustar00vstsdocker\begin{table} \caption{\ion{Ne}{ix} Ly series and \ion{Mg}{xi} triplet fluxes (errors are 5$1\sigma$ confidence intervals) \label{tab:nely}} \begin{tabular}{lrr}\hline cola & colb & colc\\ \hline a & 1 & 2\\ b & 3 & 4\\ \hline \end{tabular} \end{table} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/latex1.tex.gz0000644000175100001710000000030600000000000022056 0ustar00vstsdocker‹pPlatex1.texEMÂ@…÷=‹ÆčŌŋgPOĀf:Ĩ•iC§ĻÍdîîTM]ŧXQËƒĢ„RŪõ;¸¤;ĨČS‚ë ĶNkø [›âÄ ‚q/ ‘qĘ|Kfå=#8—{¸}ē|§ פž€5Ŋœ ;@qÉb}Q’9eûõ˜QœĨ(f ÂJ…īÄÁ&+Iõ-ąøąėsōhĄĮ§?FŌzÕ\ģüîágŠûü././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/latex2.tex0000644000175100001710000000072100000000000021441 0ustar00vstsdocker\begin{deluxetable}{llrl} %\tabletypesize{\scriptsize} %\rotate \tablecaption{Log of observations\label{tab:obslog}} \tablewidth{0pt} \tablehead{\colhead{Facility} & \colhead{Id} & \colhead{exposure} & \colhead{date}} \startdata \toprule Chandra & \dataset[ADS/Sa.CXO#obs/06438]{ObsId 6438} & 23 ks & 2006-12-10\\ \midrule Spitzer & AOR 3656448 & 41.6 s & 2004-06-09\\ \midrule FLWO & filter: $B$ & 600 s & 2009-11-18\\ \bottomrule \enddata \end{deluxetable} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/latex3.tex0000644000175100001710000000015500000000000021443 0ustar00vstsdocker\begin{tabular}{lrr}\hline cola & colb & colc\\ \hline a & 1 & 2\\ \midrule b & 3 & 4\\ \hline \end{tabular} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/nls1_stackinfo.dbout0000644000175100001710000004773000000000000023510 0ustar00vstsdocker |objID |osrcid |xsrcid |SpecObjID |ra |dec |obsid |ccdid |z |modelMag_i |modelMagErr_i |modelMag_r |modelMagErr_r |expo |theta |rad_ecf_39 |detlim90 |fBlim90 |-----------------------|-----------------|---------------|-----------------------|--------------------|--------------------|-----------|-----------|--------------------|--------------------|--------------------|--------------------|--------------------|--------------------|--------------------|--------------------|--------------------|-------------------- | 277955213|S000.7044P00.7513|XS04861B6_005 | 10943136| 0.704453| 0.751336| 4861| 6| 0.086550| 15.462060| 0.003840| 16.063650| 0.003888| 5104.621261| 0.105533| 3.022382| 15.117712| 0.311318 | 889974380|S002.9051P14.7003|XS03957B7_004 | 21189832| 2.905195| 14.700391| 3957| 7| 0.131820| 16.466050| 0.004807| 16.992690| 0.004917| 1479.207035| 0.118550| 3.016342| 17.364280| 0.880407 | 661258793|S005.7709M01.1287|XS04079B7_003 | 10999832| 5.770986| -1.128731| 4079| 7| 0.166355| 17.232030| 0.008332| 17.549760| 0.007209| 1540.924685| 0.073783| 1.489627| 11.915912| 0.561011 | 809266720|S006.9683P00.4376|XS04080B7_003 | 11027112| 6.968335| 0.437687| 4080| 7| 0.205337| 17.600880| 0.007790| 18.047560| 0.007439| 1373.690631| 0.073017| 1.489627| 15.480587| 0.807865 | 275803698|S014.7729P00.1143|XS02179B6_001 | 11140928| 14.772956| 0.114358| 2179| 6| 0.718880| 17.487000| 0.006978| 17.441360| 0.005979| 2043.570572| 0.091283| 1.453126| 13.288200| 0.676781 | 610324605|S029.2184M00.2061|XS04081B7_004 | 11365768| 29.218458| -0.206140| 4081| 7| 0.163040| 17.522280| 0.006957| 17.821940| 0.006828| 1513.497218| 0.073333| 1.489627| 12.188137| 0.580337 | 819359440|S029.9901P00.5529|XS05777B1_005 | 11365080| 29.990162| 0.552903| 5777| 1| 0.311778| 18.508300| 0.013120| 18.822060| 0.011235| 16875.600510| 0.173000| 5.127182| 29.849694| 0.201770 | 359375943|S037.1728P00.8690|XS04083B7_002 | 11478640| 37.172803| 0.869065| 4083| 7| 0.186225| 17.741220| 0.008360| 18.157300| 0.007994| 1600.672011| 0.074100| 1.489627| 12.060426| 0.546492 | 680002094|S048.6144M01.1978|XS04084B7_001 | 11619072| 48.614411| -1.197867| 4084| 7| 0.387004| 18.084100| 0.008811| 18.047740| 0.007107| 1688.844386| 0.074850| 1.489627| 14.418508| 0.665490 | 207476987|S122.0691P21.1492|XS03785B1_003 | 54178104| 122.069156| 21.149206| 3785| 1| 0.142121| 18.795740| 0.014157| 19.272550| 0.014808| 15935.690359| 0.148833| 5.116525| 25.744492| 0.182462 | 314622107|S124.9642P36.8307|XS04119B3_002 | 25158064| 124.964241| 36.830793| 4119| 3| 0.736540| 19.246110| 0.015329| 19.180730| 0.011400| 6686.525810| 0.191800| 7.738524| 30.212630| 0.663496 | 499048612|S128.7287P55.5725|XS04940B7_008 | 50209680| 128.728748| 55.572530| 4940| 7| 0.241157| 16.196610| 0.006701| 16.845690| 0.008232| 85385.450431| 0.021583| 0.327020| 25.359343| 0.022349 | 509872023|S130.2167P13.2152|NULL | 68308384| 130.216762| 13.215295| 2130| 7| 0.170352| 17.437750| 0.009265| 17.989470| 0.010459| 22105.895051| 0.010694| 0.232184| 8.703367| 0.030060 | 337394906|S134.7069P27.8194|NULL | 54460872| 134.706929| 27.819409| 5821| 3| 0.090713| 15.495630| 0.004090| 15.933850| 0.004758| 20139.691101| 0.153217| 5.127182| 26.899264| 0.175787 | 204612149|S140.7808P30.9906|XS04122B5_001 | 54657400| 140.780817| 30.990687| 4122| 5| 0.629145| 18.845160| 0.012765| 18.948480| 0.010724| 4173.745162| 0.192050| 7.739623| 37.336536| 0.819048 | 731490396|S147.5151P17.1590|XS03274B2_001 | 66732256| 147.515194| 17.159084| 3274| 2| 0.195364| 17.472340| 0.006327| 17.783260| 0.006028| 14096.036370| 0.032833| 0.366684| 9.702502| 0.075172 | 138368206|S147.6362P59.8164|NULL | 12773752| 147.636280| 59.816408| 3036| 2| 0.652411| 19.914220| 0.029210| 20.094790| 0.024926| 4012.606072| 0.167283| 5.127182| 21.727958| 0.697762 | 561051767|S151.8587P12.8156|XS05606B7_004 | 49112864| 151.858761| 12.815617| 5606| 7| 0.240653| 15.175160| 0.004690| 15.348870| 0.004204| 33943.906753| 0.008806| 0.243602| 8.594830| 0.019169 | 827223175|S153.3119M00.8760|XS04085B7_001 | 7622024| 153.311933| -0.876011| 4085| 7| 0.275749| 17.638600| 0.006945| 17.638410| 0.005750| 1769.308133| 0.074400| 1.489627| 12.371362| 0.512717 | 125920375|S160.6255P01.0399|XS04086B7_004 | 7762256| 160.625571| 1.039913| 4086| 7| 0.115493| 16.476400| 0.006180| 16.952690| 0.005979| 1351.602676| 0.074017| 1.489627| 12.388117| 0.674828 | 126051412|S160.8870P01.0191|XS04086B2_001 | 7762456| 160.887017| 1.019120| 4086| 2| 0.071893| 15.403520| 0.003958| 15.830900| 0.003798| 1470.312820| 0.188000| 7.763980| 24.843778| 2.297003 | 199471676|S169.6261P40.4316|XS00868B3_001 | 40555520| 169.626193| 40.431669| 868| 3| 0.154596| 15.520440| 0.003612| 15.843520| 0.003574| 15875.864312| 0.039917| 0.409867| 10.331539| 0.069317 | 911117410|S174.3501P30.0602|XS04161B7_011 | 62510944| 174.350159| 30.060294| 4161| 7| 0.695136| 19.910250| 0.032209| 20.022840| 0.021641| 14988.033880| 0.062233| 0.614561| 11.836136| 0.055041 | 302536231|S179.8826P29.2455|XS00874B3_007 | 62651000| 179.882670| 29.245515| 874| 3| 0.724488| 17.965190| 0.007865| 18.090560| 0.007281| 94375.899791| 0.004833| 0.230755| 8.240796| 0.009124 | 302601830|S179.9533P29.1580|XS00874B2_001 | 62623640| 179.953385| 29.158023| 874| 2| 0.083344| 15.802610| 0.004156| 16.238050| 0.004098| 84775.542942| 0.105917| 3.022382| 21.690631| 0.026736 | 115261957|S180.7950P57.6803|XS05757B0_022 | 37008112| 180.795062| 57.680354| 5757| 0| 0.759025| 18.066390| 0.008409| 18.060240| 0.006947| 40390.627482| 0.178917| 5.125388| 34.575626| 0.096856 | 607275593|S183.4289P02.8802|XS04934B3_004 | 14602336| 183.428996| 2.880256| 4934| 3| 0.641174| 19.083390| 0.016683| 19.264170| 0.014156| 17374.807609| 0.067033| 1.489627| 12.291123| 0.078403 | 425979958|S183.5631P00.9198|XS04087B7_004 | 8100808| 183.563163| 0.919874| 4087| 7| 0.395653| 18.254720| 0.010882| 18.328170| 0.008583| 1743.376400| 0.075183| 1.489627| 12.265030| 0.491269 | 189855768|S184.4790P58.6599|XS03558B3_002 | 37036288| 184.479077| 58.659912| 3558| 3| 0.023181| 14.626880| 0.002469| 14.904420| 0.002339| 6129.941952| 0.003750| 0.232403| 7.666659| 0.136118 | 619169285|S187.0751P44.2172|NULL | 38612200| 187.075137| 44.217228| 938| 0| 0.662250| 17.907240| 0.007109| 18.053730| 0.006975| 2298.154599| 0.172200| 5.125388| 20.352558| 0.848250 | 325588542|S187.5646P03.0485|XS04040B7_001 | 14659784| 187.564673| 3.048508| 4040| 7| 0.137670| 16.402290| 0.004927| 17.103210| 0.005467| 3409.797684| 0.010833| 0.243602| 7.851051| 0.160035 | 574503609|S187.6176P47.8825|NULL | 40921304| 187.617696| 47.882592| 3071| 3| 0.259120| 18.357610| 0.011731| 18.646700| 0.010925| 6222.550176| 0.197167| 7.763595| 30.051725| 0.668981 | 101878322|S188.4820P13.0754|XS02107B7_001 | 45509408| 188.482006| 13.075423| 2107| 7| 0.480211| 18.623910| 0.015033| 19.178470| 0.015434| 5550.153407| 0.015417| 0.276499| 8.218379| 0.089948 | 834099774|S188.5555P47.8975|XS03055B7_001 | 40921752| 188.555591| 47.897583| 3055| 7| 0.372812| 16.768010| 0.004767| 16.822040| 0.004038| 4452.821575| 0.009889| 0.243602| 8.075360| 0.119255 | 528223925|S191.3095P01.1419|NULL | 8213952| 191.309592| 1.141912| 2974| 2| 0.091196| 16.407150| 0.006573| 16.882680| 0.006505| 5665.430694| 0.160700| 5.127182| 21.105785| 0.481827 | 430960732|S194.9316P01.0486|XS04088B7_005 | 8269800| 194.931643| 1.048622| 4088| 7| 0.394569| 18.230550| 0.009419| 18.305880| 0.007674| 1532.367693| 0.075000| 1.489627| 11.697405| 0.529051 | 040450702|S196.9301P46.7193|NULL | 41090688| 196.930172| 46.719346| 3244| 6| 0.600141| 19.711200| 0.021784| 20.631250| 0.030904| 8481.301760| 0.184333| 5.111493| 28.487300| 0.409704 | 895335014|S197.7853P00.5310|XS04089B7_006 | 8297720| 197.785328| 0.531036| 4089| 7| 0.429236| 17.838440| 0.007412| 17.883200| 0.006128| 1342.669846| 0.075917| 1.489627| 11.975790| 0.622564 | 362199556|S206.2204P00.0889|NULL | 8438656| 206.220450| 0.088956| 2251| 6| 0.087128| 15.878880| 0.003993| 16.339870| 0.003999| 7732.826167| 0.146900| 5.125388| 24.196409| 0.276815 | 390308579|S213.1444M00.5833|XS04090B7_001 | 8550616| 213.144471| -0.583347| 4090| 7| 0.126940| 16.924460| 0.008082| 17.337560| 0.007611| 1850.463370| 0.074433| 1.489627| 12.129062| 0.475026 | 444464848|S213.7065P36.2111|XS04163B1_002 | 46269424| 213.706536| 36.211187| 4163| 1| 0.180925| 17.916410| 0.009867| 18.346860| 0.009661| 81178.124219| 0.092700| 1.460516| 17.286353| 0.023684 | 222587913|S216.7550P44.2825|XS06112B2_004 | 36276768| 216.755074| 44.282505| 6112| 2| 0.735436| 19.039310| 0.015654| 19.133000| 0.012307| 7202.822662| 0.137533| 3.019678| 17.903948| 0.270855 | 929145428|S217.6259M00.1875|XS04091B7_004 | 8607176| 217.625904| -0.187530| 4091| 7| 0.103307| 17.334130| 0.007846| 17.791860| 0.007610| 1362.631234| 0.075700| 1.489627| 11.674970| 0.622522 | 428847268|S217.6691P36.8177|XS04126B7_001 | 38894856| 217.669106| 36.817754| 4126| 7| 0.566053| 18.744800| 0.010372| 19.168410| 0.011316| 2834.413800| 0.009583| 0.243602| 7.405304| 0.178125 | 440484921|S219.7460P03.5965|XS03290B1_006 | 16516928| 219.746065| 3.596520| 3290| 1| 0.733848| 18.461360| 0.009410| 18.429130| 0.008255| 48647.675049| 0.137250| 3.014202| 26.440169| 0.059182 | 468047975|S222.3062P00.4019|XS04092B7_004 | 8691936| 222.306273| 0.401911| 4092| 7| 0.440801| 18.675470| 0.012882| 18.855400| 0.010686| 1574.467045| 0.052750| 0.607436| 10.031873| 0.470555 | 468113483|S222.3862P00.3767|XS04092B7_001 | 8691984| 222.386270| 0.376752| 4092| 7| 0.080563| 16.388650| 0.004431| 16.884420| 0.004493| 1920.873200| 0.074717| 1.489627| 12.712145| 0.488745 | 931439168|S222.8459M00.1071|XS04093B7_001 | 8691960| 222.845909| -0.107191| 4093| 7| 0.138627| 17.058580| 0.006735| 17.488910| 0.006241| 1898.411113| 0.075567| 1.489627| 11.967944| 0.467229 | 262643238|S235.8184P54.0905|XS00822B6_002 | 17361832| 235.818430| 54.090581| 822| 6| 0.245121| 17.540910| 0.006667| 17.778130| 0.006324| 3636.411721| 0.140183| 3.019678| 18.358903| 0.439665 | 926158050|S240.8326P42.3631|NULL | 37599160| 240.832606| 42.363127| 5609| 6| 0.245845| 18.507290| 0.014520| 18.790040| 0.011571| 11325.862421| 0.133133| 3.019841| 18.982950| 0.171760 | 608676499|S245.9044P31.1722|XS05607B7_001 | 39992048| 245.904431| 31.172231| 5607| 7| 0.235655| 18.073020| 0.012637| 18.487890| 0.011318| 16902.229821| 0.033283| 0.375642| 10.006948| 0.042823 | 960066205|S246.4348P15.8271|XS03229B1_001 | 62172624| 246.434806| 15.827186| 3229| 1| 0.798335| 18.653970| 0.012212| 18.576130| 0.008949| 42261.803686| 0.138833| 3.014202| 25.770130| 0.068354 | 134019205|S256.4454P63.1831|XS04094B7_002 | 9845344| 256.445484| 63.183108| 4094| 7| 0.119156| 17.496630| 0.006940| 17.887740| 0.006407| 1714.376381| 0.075200| 1.489627| 11.843095| 0.497777 | 134609053|S257.3217P61.8895|XS04864B6_004 | 9902624| 257.321721| 61.889546| 4864| 6| 0.292492| 18.075020| 0.010429| 18.285270| 0.008331| 3266.690360| 0.109617| 3.019678| 16.988875| 0.540981 | 213815608|S260.0418P26.6255|XS04361B3_014 | 27578480| 260.041831| 26.625566| 4361| 3| 0.159240| 14.936350| 0.003416| 15.449310| 0.003666| 23666.399953| 0.037933| 0.399900| 23.603727| 0.111820 | 849702763|S264.1609P53.9090|XS04863B6_002 | 10155040| 264.160900| 53.909041| 4863| 6| 0.407487| 18.748560| 0.014215| 19.233860| 0.015527| 4649.657613| 0.107100| 3.022382| 16.279548| 0.369717 | 801664702|S349.5880P00.4935|NULL | 10774344| 349.588069| 0.493526| 4938| 7| 0.376296| 18.852000| 0.018428| 19.022390| 0.013564| 28181.469589| 0.117017| 3.046228| 21.942945| 0.059519 | 275333773|S354.7242P00.8034|XS04095B7_002 | 10859368| 354.724289| 0.803473| 4095| 7| 0.169759| 17.812580| 0.009228| 18.205800| 0.008355| 1513.825375| 0.075283| 1.489627| 12.057631| 0.593043 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/no_data_cds.dat0000644000175100001710000000445100000000000022454 0ustar00vstsdocker Title: Spitzer Observations of NGC 1333: A Study of Structure and Evolution in a Nearby Embedded Cluster Authors: Gutermuth R.A., Myers P.C., Megeath S.T., Allen L.E., Pipher J.L., Muzerolle J., Porras A., Winston E., Fazio G. Table: Spitzer-identified YSOs: Addendum ================================================================================ Byte-by-byte Description of file: datafile3.txt -------------------------------------------------------------------------------- Bytes Format Units Label Explanations -------------------------------------------------------------------------------- 1- 3 I3 --- Index Running identification number 5- 6 I2 h RAh Hour of Right Ascension (J2000) 8- 9 I2 min RAm Minute of Right Ascension (J2000) 11- 15 F5.2 s RAs Second of Right Ascension (J2000) - continuation of description 17 A1 --- DE- Sign of the Declination (J2000) 18- 19 I2 deg DEd Degree of Declination (J2000) 21- 22 I2 arcmin DEm Arcminute of Declination (J2000) 24- 27 F4.1 arcsec DEs Arcsecond of Declination (J2000) 29- 68 A40 --- Match Literature match 70- 75 A6 --- Class Source classification (1) 77-80 F4.2 mag AK ? The K band extinction (2) 82-86 F5.2 --- Fit ? Fit of IRAC photometry (3) -------------------------------------------------------------------------------- Note (1): Asterisks mark "deeply embedded" sources with questionable IRAC colors or incomplete IRAC photometry and relatively bright MIPS 24 micron photometry. Note (2): Only provided for sources with valid JHK_S_ photometry. Note (3): Defined as the slope of the linear least squares fit to the 3.6 - 8.0 micron SEDs in log{lambda} F_{lambda} vs log{lambda} space. Extinction is not accounted for in these values. High extinction can bias Fit to higher values. -------------------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/no_data_daophot.dat0000644000175100001710000000104100000000000023331 0ustar00vstsdocker#K MERGERAD = INDEF scaleunit %-23.7g #N ID XCENTER YCENTER MAG MERR MSKY NITER \ #U ## pixels pixels magnitudes magnitudes counts ## \ #F %-9d %-10.3f %-10.3f %-12.3f %-14.3f %-15.7g %-6d #N SHARPNESS CHI PIER PERROR \ #U ## ## ## perrors \ #F %-23.3f %-12.3f %-6d %-13s ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/no_data_ipac.dat0000644000175100001710000000100500000000000022607 0ustar00vstsdocker\catalog = sao \date = "Wed Sp 20 09:48:36 1995" \mykeyword = 'Another way for defining keyvalue string' \ This is an example of a valid comment. \ The 2nd data line is used to verify the exact column parsing \ (unclear if this is a valid for the IPAC format) | ra | dec | sai |-----v2---| sptype | | real | real | int | real | char | | unit | unit | unit | unit | ergs | | null | null | null | null | -999 | ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/no_data_sextractor.dat0000644000175100001710000000017200000000000024075 0ustar00vstsdocker# 1 NUMBER Galaxy ID number # 2 FLUX_ISO # 3 FLUXERR_ISO # 4 VALUES Note column 5 is missing # 6 FLAG ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/no_data_with_header.dat0000644000175100001710000000000600000000000024156 0ustar00vstsdockera b c ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/no_data_without_header.dat0000644000175100001710000000002500000000000024707 0ustar00vstsdocker# blank data table ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/sextractor.dat0000644000175100001710000000056100000000000022412 0ustar00vstsdocker# 1 NUMBER Galaxy ID number # 2 FLUX_ISO # 3 FLUXERR_ISO # 4 VALU-ES Note column 5 is missing # 6 FLAG 1 0.02580616000000000 0.03974229000000000 1.6770000000000000 0.2710000000000000 0 2 5.72769100000000009 0.20643300000000001 2.6250000000000000 2.5219999999999998 0 3 88.31933999999999685 0.59369850000000002 5.9249999999999998 4.7140000000000004 0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/sextractor2.dat0000644000175100001710000000134300000000000022473 0ustar00vstsdocker# 1 NUMBER Running object number # 2 XWIN_IMAGE Windowed position estimate along x [pixel] # 3 YWIN_IMAGE Windowed position estimate along y [pixel] # 4 MAG_AUTO Kron-like elliptical aperture magnitude [mag] # 5 MAGERR_AUTO RMS error for AUTO magnitude [mag] # 6 FLAGS Extraction flags # 7 X2_IMAGE [pixel**2] # 8 X_MAMA Barycenter position along MAMA x axis [m**(-6)] # 9 MU_MAX Peak surface brightness above background [mag * arcsec**(-2)] 1 100.523 11.911 -5.3246 0.0416 19 1000.0 0.00304 -3.498 2 100.660 4.872 -6.4538 0.0214 27 1500.0 0.00908 1.401 3 131.046 10.382 -4.6836 0.0524 17 500.0 0.01004 2.512 4 338.959 4.966 -7.1747 0.0173 25 1200.0 0.00792 2.901 5 166.280 3.956 -4.0865 0.0621 25 800.0 0.00699 -6.489 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/sextractor3.dat0000644000175100001710000000212600000000000022474 0ustar00vstsdocker# 1 X_IMAGE Object position along x [pixel] # 2 Y_IMAGE [pixel] # 3 ALPHA_J2000 Right ascension of barycenter (J2000) [deg] # 4 DELTA_J2000 Declination of barycenter (J2000) [deg] # 5 MAG_AUTO Kron-like elliptical aperture magnitude [mag] # 6 MAGERR_AUTO RMS error for AUTO magnitude [mag] # 7 MAG_APER Fixed aperture magnitude vector [mag] # 14 MAGERR_APER RMS error vector for fixed aperture mag. [mag] 1367.000 184.404 265.1445228 +68.7507679 22.9929 0.2218 24.1804 23.4541 22.9567 22.5162 22.1912 21.5363 21.0361 0.3262 0.2675 0.2203 0.1856 0.1683 0.1621 0.1673 1380.235 189.444 265.1384412 +68.7516124 20.9258 0.0569 22.2374 21.5987 21.2943 21.1244 20.9838 20.6672 20.0695 0.0645 0.0497 0.0495 0.0520 0.0533 0.0602 0.0515 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/short.rdb0000644000175100001710000000023400000000000021347 0ustar00vstsdocker # blank lines agasc_id n_noids n_obs N N N 115345072 1 1 # comment 335416352 3 8 266612160 1 1 645803280 1 1 117309912 1 1 114950920 1 1 335025040 2 24 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/short.rdb.bz20000644000175100001710000000022200000000000022040 0ustar00vstsdockerBZh91AY&SY–@D _€0Hāž¯Œ r"š6Ēdx ÔÁ0¤Úž§¨ĸá­{0øxÚN ˜š—âfg‡å˛ĨldXE´û‰“Ņ<ē&Ļ‘ÕCĩ2ĸÁĩR)!ąAېH$‹Æ,íŸĢ؝f"É3ĄGŽR?ÅܑN$e././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/short.rdb.gz0000644000175100001710000000022400000000000021765 0ustar00vstsdocker‹pPshort.rdb-ŒË Ã0DĪģUÜĀ~´˛ÔDZ0ō‡ bKĨ"ė0‡áņ†ÁÉ­gŽw–ztÄüÎ}[ĘuŠ­ė}t[;ž`™MŊŅ,ĀĀč&ˇĩë:ęUÍsPPˆ(!tĪ‚ˇH*ņ!æY)%–?ųd”äqã…ÄČˆGüā¨ü7œ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/short.rdb.xz0000644000175100001710000000030000000000000022001 0ustar00vstsdockerũ7zXZæÖ´F!t/åŖā›€] Œ•yhëfÖŧØã)Ã_ĀČNųŇ:|uÅėĀ'öoáuķŌXŲzŖ×HÛ_Îh$BīœÛ?h0ĩÔ ûąVvl•ĢÄ,ŽéS]ĐÔ"7î7Ø xĄŗč9žõf`Œ,x ņ•Õĩîû…'ÄĪŊ&¤Œ ]ÅŪĢž­ÕõB“)ú™<œœ~ÅbąÄgûYZ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/short.tab0000644000175100001710000000017200000000000021347 0ustar00vstsdockeragasc_id n_noids n_obs 115345072 1 1 335416352 3 8 266612160 1 1 645803280 1 1 117309912 1 1 114950920 1 1 335025040 2 24 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/simple.txt0000644000175100001710000000017500000000000021555 0ustar00vstsdocker 'test 1a' test2 test3 test4 # fun1 fun2 fun3 fun4 fun5 top1 top2 top3 top4 hat1 hat2 hat3 hat4 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/simple2.txt0000644000175100001710000000036500000000000021640 0ustar00vstsdockerobsid | redshift | X | Y | object | rad 3102 | 0.32 | 4167 | 4085 | Q1250+568-A | 9 3102 | 0.32 | 4706 | 3916 | Q1250+568-B | 14 877 | 0.22 | 4378 | 3892 | 'Source 82' | 12.5 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/simple3.txt0000644000175100001710000000014400000000000021634 0ustar00vstsdockerobsid|redshift|X|Y|object|rad 877|0.22|4378|3892|'Sou,rce82'|12.5 3102|0.32|4167|4085|Q1250+568-A|9 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/simple4.txt0000644000175100001710000000027000000000000021635 0ustar00vstsdocker3102 | 0.32 | 4167 | 4085 | Q1250+568-A | 9 3102 | 0.32 | 4706 | 3916 | Q1250+568-B | 14 877 | 0.22 | 4378 | 3892 | 'Source 82' | 12.5 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/simple5.txt0000644000175100001710000000035700000000000021644 0ustar00vstsdocker# Purposely make an ill-formed data file (in last row) 3102 | 0.32 | 4167 | 4085 | Q1250+568-A | 9 3102 | 0.32 | 4706 | 3916 | Q1250+568-B | 14 877 | 4378 | 3892 | 'Source 82' | 12.5 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/simple_csv.csv0000644000175100001710000000002100000000000022372 0ustar00vstsdockera,b,c 1,2,3 4,5,6././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/simple_csv_missing.csv0000644000175100001710000000001600000000000024127 0ustar00vstsdockera,b,c 1 4,5,6 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/space_delim_blank_lines.txt0000644000175100001710000000035300000000000025070 0ustar00vstsdockerobsid offset x y name oaa 3102 0.32 4167 4085 Q1250+568-A 9 3102 0.32 4706 3916 Q1250+568-B 14 877 0.22 4378 3892 "Source 82" 12.5 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/space_delim_no_header.dat0000644000175100001710000000003000000000000024454 0ustar00vstsdocker1 3.4 hello 2 6.4 world ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/space_delim_no_names.dat0000644000175100001710000000001000000000000024325 0ustar00vstsdocker1 2 3 4 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/subtypes.ecsv0000644000175100001710000001533600000000000022270 0ustar00vstsdocker# %ECSV 1.0 # --- # delimiter: ',' # datatype: # - # name: i_index # datatype: int32 # description: Row index # - # name: s_byte # datatype: int8 # - # name: s_short # datatype: int16 # - # name: s_int # datatype: int32 # - # name: s_long # datatype: int64 # - # name: s_float # datatype: float32 # - # name: s_double # datatype: float64 # - # name: s_string # datatype: string # - # name: s_boolean # datatype: bool # - # name: f_byte # datatype: string # subtype: 'int8[3]' # - # name: f_short # datatype: string # subtype: 'int16[3]' # - # name: f_int # datatype: string # subtype: 'int32[3]' # - # name: f_long # datatype: string # subtype: 'int64[3]' # - # name: f_float # datatype: string # subtype: 'float32[3]' # - # name: f_double # datatype: string # subtype: 'float64[3]' # - # name: f_string # datatype: string # subtype: 'string[3]' # - # name: f_boolean # datatype: string # subtype: 'bool[3]' # - # name: v_byte # datatype: string # subtype: 'int8[null]' # - # name: v_short # datatype: string # subtype: 'int16[null]' # - # name: v_int # datatype: string # subtype: 'int32[null]' # - # name: v_long # datatype: string # subtype: 'int64[null]' # - # name: v_float # datatype: string # subtype: 'float32[null]' # - # name: v_double # datatype: string # subtype: 'float64[null]' # - # name: v_string # datatype: string # subtype: 'string[null]' # - # name: v_boolean # datatype: string # subtype: 'bool[null]' # - # name: m_int # datatype: string # subtype: 'int32[4,2]' # - # name: m_double # datatype: string # subtype: 'float64[2,3]' i_index,s_byte,s_short,s_int,s_long,s_float,s_double,s_string,s_boolean,f_byte,f_short,f_int,f_long,f_float,f_double,f_string,f_boolean,v_byte,v_short,v_int,v_long,v_float,v_double,v_string,v_boolean,m_int,m_double 0,0,0,0,0,0.0,0.0,zero,False,"[0,1,2]","[0,1,2]","[0,1,2]","[0,1,2]","[0.0,null,2.5]","[0.0,null,2.5]","[""foo"",null,""zero""]","[false,false,false]","[0,1,2]","[0,1,2]","[0,1,2]","[0,1,2]","[0.0,null,2.5]","[0.0,null,2.5]","[""foo"",null,""zero""]","[false,false,false]","[[1000,1001],[2000,2001],[3000,3001],[4000,4001]]","[[0.25,0.5,0.75],[-0.25,-0.5,-0.75]]" 1,,1,1,1,1.0,,one,True,,"[1,2,3]","[1,2,3]","[1,2,3]","[1.0,null,3.5]","[1.0,null,3.5]","[""foo"",null,""one""]","[true,false,false]",,"[1,2]","[1,2]","[1,2]","[1.0,null]","[1.0,null]","[""foo"",null]","[true,false]",,"[[1.25,1.5,1.75],[-1.25,-1.5,-1.75]]" 2,2,,2,2,,2.0,two,False,"[2,3,4]",,"[2,3,4]","[2,3,4]","[2.0,null,4.5]","[2.0,null,4.5]","[""foo"",null,""two""]","[false,true,false]",[2],,[2],[2],[2.0],[2.0],"[""foo""]",[false],"[[1002,1003],[2002,2003],[3002,3003],[4002,4003]]", 3,3,3,,3,3.0,3.0,three,True,"[3,4,5]","[3,4,5]",,"[3,4,5]","[3.0,null,5.5]","[3.0,null,5.5]","[""foo"",null,""three""]","[true,true,false]",[],[],,[],[],[],[],[],"[[1003,1004],[2003,2004],[3003,3004],[4003,4004]]","[[3.25,3.5,3.75],[-3.25,-3.5,-3.75]]" 4,4,4,4,,4.0,4.0,four,False,"[4,5,6]","[4,5,6]","[4,5,6]",,"[4.0,null,6.5]","[4.0,null,6.5]","[""foo"",null,""four""]","[false,false,true]","[4,5,6]","[4,5,6]","[4,5,6]",,"[4.0,null,6.5]","[4.0,null,6.5]","[""foo"",null,""four""]","[false,false,true]","[[1004,1005],[2004,2005],[3004,3005],[4004,4005]]","[[4.25,4.5,4.75],[-4.25,-4.5,-4.75]]" 5,5,5,5,5,nan,5.0,five,True,"[5,6,7]","[5,6,7]","[5,6,7]","[5,6,7]",,"[5.0,null,7.5]","[""foo"",null,""five""]","[true,false,true]","[5,6]","[5,6]","[5,6]","[5,6]",,"[5.0,null]","[""foo"",null]","[true,false]","[[1005,1006],[2005,2006],[3005,3006],[4005,4006]]","[[5.25,5.5,5.75],[-5.25,-5.5,-5.75]]" 6,6,6,6,6,6.0,nan,six,False,"[6,7,8]","[6,7,8]","[6,7,8]","[6,7,8]","[6.0,null,8.5]",,"[""foo"",null,""six""]","[false,true,true]",[6],[6],[6],[6],[6.0],,"[""foo""]",[false],"[[1006,1007],[2006,2007],[3006,3007],[4006,4007]]","[[6.25,6.5,6.75],[-6.25,-6.5,-6.75]]" 7,7,7,7,7,7.0,7.0,,True,"[7,8,9]","[7,8,9]","[7,8,9]","[7,8,9]","[7.0,null,9.5]","[7.0,null,9.5]",,"[true,true,true]",[],[],[],[],[],[],,[],"[[1007,1008],[2007,2008],[3007,3008],[4007,4008]]","[[7.25,7.5,7.75],[-7.25,-7.5,-7.75]]" 8,8,8,8,8,8.0,8.0,"' ""\""""' ; '&<>",,"[8,9,10]","[8,9,10]","[8,9,10]","[8,9,10]","[8.0,null,10.5]","[8.0,null,10.5]","[""foo"",null,""' \""\\\""\""' ; '&<>""]",,"[8,9,10]","[8,9,10]","[8,9,10]","[8,9,10]","[8.0,null,10.5]","[8.0,null,10.5]","[""foo"",null,""' \""\\\""\""' ; '&<>""]",,"[[1008,1009],[2008,2009],[3008,3009],[4008,4009]]","[[8.25,8.5,8.75],[-8.25,-8.5,-8.75]]" 9,9,9,9,9,nan,nan,,True,"[9,10,11]","[9,10,11]","[9,10,11]","[9,10,11]","[9.0,null,11.5]","[9.0,null,11.5]","[""foo"",null,""""]","[true,false,false]","[9,10]","[9,10]","[9,10]","[9,10]","[9.0,null]","[9.0,null]","[""foo"",null]","[true,false]","[[1009,1010],[2009,2010],[3009,3010],[4009,4010]]","[[9.25,9.5,9.75],[-9.25,-9.5,-9.75]]" 10,-10,-10,-10,-10,-10.0,-10.0,10,False,"[10,11,12]","[10,11,12]","[10,11,12]","[10,11,12]","[10.0,null,12.5]","[10.0,null,12.5]","[""foo"",null,""10""]","[false,true,false]",[10],[10],[10],[10],[10.0],[10.0],"[""foo""]",[false],"[[1010,1011],[2010,2011],[3010,3011],[4010,4011]]","[[10.25,10.5,10.75],[-10.25,-10.5,-10.75]]" 11,,-11,-11,-11,-11.0,-11.0,10 + one,True,,"[11,12,13]","[11,12,13]","[11,12,13]","[11.0,null,13.5]","[11.0,null,13.5]","[""foo"",null,""10 + one""]","[true,true,false]",,[],[],[],[],[],[],[],,"[[11.25,11.5,11.75],[-11.25,-11.5,-11.75]]" 12,-12,,-12,-12,-12.0,-12.0,10 + two,False,"[12,13,14]",,"[12,13,14]","[12,13,14]","[12.0,null,14.5]","[12.0,null,14.5]","[""foo"",null,""10 + two""]","[false,false,true]","[12,13,14]",,"[12,13,14]","[12,13,14]","[12.0,null,14.5]","[12.0,null,14.5]","[""foo"",null,""10 + two""]","[false,false,true]","[[1012,1013],[2012,2013],[3012,3013],[4012,4013]]", 13,-13,-13,,-13,-13.0,-13.0,10 + three,True,"[13,14,15]","[13,14,15]",,"[13,14,15]","[13.0,null,15.5]","[13.0,null,15.5]","[""foo"",null,""10 + three""]","[true,false,true]","[13,14]","[13,14]",,"[13,14]","[13.0,null]","[13.0,null]","[""foo"",null]","[true,false]","[[1013,1014],[2013,2014],[3013,3014],[4013,4014]]","[[13.25,13.5,13.75],[-13.25,-13.5,-13.75]]" 14,-14,-14,-14,,-14.0,-14.0,10 + four,False,"[14,15,16]","[14,15,16]","[14,15,16]",,"[14.0,null,16.5]","[14.0,null,16.5]","[""foo"",null,""10 + four""]","[false,true,true]",[14],[14],[14],,[14.0],[14.0],"[""foo""]",[false],"[[1014,1015],[2014,2015],[3014,3015],[4014,4015]]","[[14.25,14.5,14.75],[-14.25,-14.5,-14.75]]" 15,-15,-15,-15,-15,nan,-15.0,10 + five,True,"[15,16,17]","[15,16,17]","[15,16,17]","[15,16,17]",,"[15.0,null,17.5]","[""foo"",null,""10 + five""]","[true,true,true]",[],[],[],[],,[],[],[],"[[1015,1016],[2015,2016],[3015,3016],[4015,4016]]","[[15.25,15.5,15.75],[-15.25,-15.5,-15.75]]" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/test4.dat0000644000175100001710000000134000000000000021253 0ustar00vstsdocker# whitespace separated zabs1.nh p1.gamma p1.ampl statname statval 0.0872113431031 1.26764500000 0.000699751823872 input 0.0 0.0863775314648 1.26769713012 0.000698799851356 chi2constvar 494.396534577 0.0839710433091 1.25997502704 0.000696444029148 chi2modvar 497.56468441 0.0867933991271 1.27045571779 0.000699526507899 cash -579508.340504 # comment here 0.0913252611282 1.28738450369 0.000703999531569 chi2gehrels 416.904139981 0.0943815607455 1.29839188657 0.000708725775733 chi2datavar 572.734008 0.0943792771442 1.29837677223 0.00070871697621 chi2xspecvar 572.734013473 0.0867953584196 1.27046735536 0.000699532088738 cstat 512.433488994 0.0846479114132 1.26584338176 0.000697063608605 chi2constvar 440.651434041 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/test5.dat0000644000175100001710000000267700000000000021272 0ustar00vstsdocker# whitespace separated with lines to skip ------------------------------------------ zabs1.nh p1.gamma p1.ampl statname statval ------------------------------------------ 0.095196313612 1.29238107724 0.000709438701165 chi2xspecvar 455.385700456 0.0898827896112 1.27317260145 0.000703680688865 cstat 450.402806957 0.0845373292976 1.26032264432 0.000697817633266 chi2constvar 427.888401816 0.0813955290921 1.25278166998 0.000694773889339 chi2modvar 422.655226097 0.0837813193374 1.26108631851 0.000697168659777 cash -582096.060739 0.0877788113875 1.27498889089 0.000700963122261 chi2gehrels 336.255262001 0.0886095763534 1.27831934755 0.000702152760295 chi2datavar 427.87097831 0.0886062881606 1.27831561342 0.000702152575029 chi2xspecvar 427.870972282 0.0837839157029 1.26109967845 0.000697177275745 cstat 423.869897301 0.0848856095291 1.26216881055 0.000697245258092 chi2constvar 495.692552206 0.0834040516574 1.25034791909 0.000694504650678 chi2modvar 448.488349352 0.0863275923367 1.25920642303 0.000697302969088 cash -581109.867406 0.0910593842926 1.27434931431 0.000701687557965 chi2gehrels 362.107884887 0.0925984360666 1.27857224315 0.000703586368322 chi2datavar 467.653055046 0.0926057133247 1.27858701992 0.000703594356786 chi2xspecvar 467.653060082 0.0863257498551 1.259192667 0.000697300429366 cstat 451.536967896 0.0880503692681 1.2588289844 0.000698437310968 chi2constvar 439.513117058 0.0852962921333 1.25214407357 0.000696223065852 chi2modvar 443.456904712 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1112466 astropy-5.0.2/astropy/io/ascii/tests/data/vizier/0000755000175100001710000000000000000000000021030 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/vizier/ReadMe0000644000175100001710000001145100000000000022112 0ustar00vstsdockerJ/A+A/511/A56 Abundances of five open clusters (Pancino+, 2010) ================================================================================ Chemical abundance analysis of the open clusters Cr 110, NGC 2420, NGC 7789, and M 67 (NGC 2682). Pancino E., Carrera R., Rossetti, E., Gallart C. =2010A&A...511A..56P ================================================================================ ADC_Keywords: Clusters, open ; Stars, giant ; Equivalent widths ; Spectroscopy Keywords: stars: abundances - Galaxy: disk - open clusters and associations: general Abstract: The present number of Galactic open clusters that have high resolution abundance determinations, not only of [Fe/H], but also of other key elements, is largely insufficient to enable a clear modeling of the Galactic disk chemical evolution. To increase the number of Galactic open clusters with high quality measurements, we obtained high resolution (R~30000), high quality (S/N~50-100 per pixel), echelle spectra with the fiber spectrograph FOCES, at Calar Alto, Spain, for three red clump stars in each of five Open Clusters. We used the classical equivalent width analysis method to obtain accurate abundances of sixteen elements: Al, Ba, Ca, Co, Cr, Fe, La, Mg, Na, Nd, Ni, Sc, Si, Ti, V, and Y. We also derived the oxygen abundance using spectral synthesis of the 6300{AA} forbidden line. Description: Atomic data and equivalent widths for 15 red clump giants in 5 open clusters: Cr 110, NGC 2099, NGC 2420, M 67, NGC 7789. File Summary: -------------------------------------------------------------------------------- FileName Lrecl Records Explanations -------------------------------------------------------------------------------- ReadMe 80 . This file table1.dat 103 15 Observing logs and programme stars information table5.dat 56 5265 Atomic data and equivalent widths -------------------------------------------------------------------------------- See also: J/A+A/455/271 : Abundances of red giants in NGC 6441 (Gratton+, 2006) J/A+A/464/953 : Abundances of red giants in NGC 6441 (Gratton+, 2007) J/A+A/505/117 : Abund. of red giants in 15 globular clusters (Carretta+, 2009) Byte-by-byte Description of file: table1.dat -------------------------------------------------------------------------------- Bytes Format Units Label Explanations -------------------------------------------------------------------------------- 1- 7 A7 --- Cluster Cluster name 9- 12 I4 --- Star Star number within the cluster 14- 15 I2 h RAh Right ascension (J2000) 17- 18 I2 min RAm Right ascension (J2000) 20- 23 F4.1 s RAs Right ascension (J2000) 25 A1 --- DE- Declination sign (J2000) 26- 27 I2 deg DEd Declination (J2000) 29- 30 I2 arcmin DEm Declination (J2000) 32- 35 F4.1 arcsec DEs Declination (J2000) 37- 41 F5.2 mag Bmag B magnitude 43- 47 F5.2 mag Vmag V magnitude 49- 53 F5.2 mag Icmag ?=- Cousins I magnitude 55- 59 F5.2 mag Rmag ?=- R magnitude 61- 65 F5.2 mag Ksmag Ks magnitude 67 I1 --- NExp Number of exposures 69- 73 I5 s TExp Total exposure time 75- 77 I3 --- S/N Signal-to-nois ratio 79-103 A25 --- SName Simbad name -------------------------------------------------------------------------------- Byte-by-byte Description of file: table5.dat -------------------------------------------------------------------------------- Bytes Format Units Label Explanations -------------------------------------------------------------------------------- 1- 7 A7 --- Cluster Cluster name 9- 12 I4 --- Star Star number within the cluster 14- 20 F7.2 0.1nm Wave Wavelength in Angstroms 22- 23 A2 --- El Element name 24 I1 --- ion Ionization stage (1 for neutral element) 26- 30 F5.2 eV chiEx Excitation potential 32- 37 F6.2 --- loggf Logarithm of the oscillator strength 39- 43 F5.1 0.1pm EW ?=-9.9 Equivalent width (in mA) 46- 49 F4.1 0.1pm e_EW ?=-9.9 rms uncertainty on EW 51- 56 F6.3 --- Q ?=-9.999 DAOSPEC quality parameter Q (large values are bad) -------------------------------------------------------------------------------- Acknowledgements: Elena Pancino, elena.pancino(at)oabo.inaf.it ================================================================================ (End) Elena Pancino [INAF-OABo, Italy], Patricia Vannier [CDS] 23-Nov-2009 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/vizier/table1.dat0000644000175100001710000000266100000000000022677 0ustar00vstsdockerCr110 2108 06 38 52.5 +02 01 58.4 14.79 13.35 -- --- 9.76 6 16200 70 Cl* Collinder 110 DI 2108 Cr110 2129 06 38 41.1 +02 01 05.5 15.00 13.66 12.17 12.94 10.29 7 18900 70 Cl* Collinder 110 DI 2129 Cr110 3144 06 38 30.3 +02 03 03.0 14.80 13.49 12.04 12.72 10.19 6 16195 65 Cl* Collinder 110 DI 3144 NGC2099 67 05 52 16.6 +32 34 45.6 12.38 11.12 9.87 --- 8.17 3 3600 95 NGC 2099 67 NGC2099 148 05 52 08.1 +32 30 33.1 12.36 11.09 - --- 8.05 3 3600 105 NGC 2099 148 NGC2099 508 05 52 33.2 +32 27 43.5 12.24 10.98 -- --- 7.92 3 3900 85 NGC 2099 508 NGC2420 41 07 38 06.2 +21 36 54.7 13.75 12.67 11.61 12.13 10.13 5 9000 70 NGC 2420 41 NGC2420 76 07 38 15.5 +21 38 01.8 13.65 12.66 11.65 12.14 10.31 5 9000 75 NGC 2420 76 NGC2420 174 07 38 26.9 +21 38 24.8 13.41 12.40 ---- --- 9.98 5 9000 60 NGC 2420 174 NGC2682 141 08 51 22.8 +11 48 01.7 11.59 10.48 9.40 9.92 7.92 3 2700 85 Cl* NGC 2682 MMU 141 NGC2682 223 08 51 43.9 +11 56 42.3 11.68 10.58 9.50 10.02 8.00 3 2700 85 Cl* NGC 2682 MMU 223 NGC2682 286 08 52 18.6 +11 44 26.3 11.53 10.47 9.43 9.93 7.92 3 2700 105 Cl* NGC 2682 MMU 286 NGC7789 5237 23 56 50.6 +56 49 20.9 13.92 12.81 11.52 --- 9.89 5 9000 70 Cl* NGC 7789 G 5237 NGC7789 7840 23 57 19.3 +56 40 51.5 14.03 12.82 11.49 --- 9.83 6 9000 75 Cl* NGC 7789 G 7840 NGC7789 8556 23 57 27.6 +56 45 39.2 14.18 12.97 11.65 --- 10.03 3 5400 45 Cl* NGC 7789 G 8556 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/vizier/table5.dat0000644000175100001710000000535100000000000022702 0ustar00vstsdockerCr110 2108 6696.79 Al1 4.02 -1.42 29.5 2.2 0.289 Cr110 2108 6698.67 Al1 3.14 -1.65 58.0 2.0 0.325 Cr110 2108 7361.57 Al1 4.02 -0.90 44.1 4.0 0.510 Cr110 2108 7362.30 Al1 4.02 -0.75 62.7 3.9 0.577 Cr110 2108 7835.31 Al1 4.02 -0.65 73.7 6.6 0.539 Cr110 2108 7836.13 Al1 4.02 -0.49 87.6 4.1 0.390 Cr110 2108 8772.86 Al1 4.02 -0.32 87.6 5.1 0.957 Cr110 2108 8773.90 Al1 4.02 -0.16 118.6 14.6 0.736 Cr110 2108 5853.67 Ba2 0.60 -1.00 121.9 5.5 1.435 Cr110 2108 6141.71 Ba2 0.70 -0.08 191.0 8.7 1.117 Cr110 2108 6496.90 Ba2 0.60 -0.38 175.8 6.8 1.473 Cr110 2108 5261.70 Ca1 2.52 -0.59 149.1 5.3 0.808 Cr110 2108 5512.98 Ca1 2.93 -0.71 106.7 6.2 1.416 Cr110 2108 5857.45 Ca1 2.93 0.26 163.8 19.8 2.209 Cr110 2108 6156.02 Ca1 2.52 -2.50 42.0 4.0 0.617 Cr110 2108 6166.44 Ca1 2.52 -1.16 110.7 3.3 1.046 Cr110 2108 6169.04 Ca1 2.52 -0.80 127.3 5.5 1.604 Cr110 2108 6169.56 Ca1 2.53 -0.53 148.2 6.0 1.419 Cr110 2108 6471.66 Ca1 2.53 -0.65 130.4 5.0 1.431 Cr110 2108 6499.65 Ca1 2.52 -0.72 129.0 5.4 1.183 Cr110 2108 5230.20 Co1 1.74 -1.84 60.4 6.7 1.210 Cr110 2108 5530.77 Co1 1.71 -2.06 73.2 4.3 1.005 Cr110 2108 5590.72 Co1 2.04 -1.87 69.9 3.2 0.706 Cr110 2108 5935.38 Co1 1.88 -2.68 33.0 4.4 0.665 Cr110 2108 6429.91 Co1 2.14 -2.41 28.2 1.3 0.340 Cr110 2108 6490.34 Co1 2.04 -2.52 33.6 3.5 0.323 Cr110 2108 6632.43 Co1 2.28 -2.00 50.9 2.1 0.391 Cr110 2108 7154.67 Co1 2.04 -2.42 45.9 1.9 0.280 Cr110 2108 7388.69 Co1 2.72 -1.65 36.6 1.8 0.343 Cr110 2108 7417.37 Co1 2.04 -2.07 71.4 1.9 0.369 Cr110 2108 7838.13 Co1 3.97 -0.30 32.7 2.7 0.495 Cr110 2108 5243.36 Cr1 3.40 -0.57 47.9 4.0 0.828 Cr110 2108 5329.14 Cr1 2.91 -0.06 110.4 4.9 1.113 Cr110 2108 5442.37 Cr1 3.42 -1.06 33.3 2.5 0.499 Cr110 2108 5712.75 Cr1 3.01 -1.30 49.4 5.3 1.038 Cr110 2108 5788.39 Cr1 3.01 -1.83 26.1 1.3 0.260 Cr110 2108 5844.59 Cr1 3.01 -1.76 26.2 3.9 0.863 Cr110 2108 6330.09 Cr1 0.94 -2.92 94.4 6.6 1.638 Cr110 2108 6537.93 Cr1 1.00 -4.07 33.0 2.4 0.479 Cr110 2108 6630.01 Cr1 1.03 -3.56 60.7 1.5 0.232 Cr110 2108 6661.08 Cr1 4.19 -0.19 33.5 6.4 0.627 Cr110 2108 7355.94 Cr1 2.89 -0.28 126.7 4.1 0.671 Cr110 2108 5055.99 Fe1 4.31 -2.01 41.2 3.3 0.371 Cr110 2108 5178.80 Fe1 4.39 -1.84 45.4 7.1 0.851 Cr110 2108 5285.13 Fe1 4.43 -1.64 50.1 5.2 0.607 Cr110 2108 5294.55 Fe1 3.64 -2.86 -9.9 -9.9 -9.999 Cr110 2108 5295.31 Fe1 4.42 -1.69 38.3 9.5 1.958 Cr110 2108 5373.71 Fe1 4.47 -0.86 91.5 5.3 1.416 Cr110 2108 5386.33 Fe1 4.15 -1.77 55.9 6.6 0.949 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/vots_spec.dat0000644000175100001710000001347300000000000022227 0ustar00vstsdocker#################################################################################### ## ## VOTable-Simple Specification ## ## This is the specification of the VOTable-Simple (VOTS) format, given as an ## example data table with comments and references. This data table format is ## intended to provide a way of specifying metadata and data for simple tabular ## data sets. This specification is intended as a subset of the VOTable data ## model and allow easy generation of a VOTable-compliant data structure. This ## provides a uniform starting point for generating table documentation and ## performing database table creation and ingest. ## ## A python application is available which uses the STILTS java package to ## convert from a VOTS format to any of the (many) output formats supported by ## STILTS. This application can also generate a documentation file (in ## reStructured Text format) or a Django model definition from a VOTS table. ## ## Key VOTable and STILTS references: ## Full spec: http://www.ivoa.net/Documents/latest/VOT.html ## Datatypes: http://www.ivoa.net/Documents/REC/VOTable/VOTable-20040811.html#ToC11 ## FIELD def: http://www.ivoa.net/Documents/REC/VOTable/VOTable-20040811.html#ToC25 ## STILTS : http://www.star.bris.ac.uk/~mbt/stilts/ ## ## The VOTable-Simple format consists of header information followed by the tabular ## data elements. The VOTS header lines are all preceded by a single '#' character. ## Comments are preceded by '##' at the beginning of a line. ## ## The VOTS header defines the metadata associated with the table. In the ## VOTable-Simple format words in all CAPS (followed by ::) refer to the ## corresponding metadata elements in the VOTable specification. For instance ## the DESCRIPTION:: keyword precedes the lines that are used in the VOTable ## element. The COOSYS::, PARAM::, and FIELD:: keywords are ## each followed by a whitespace-delimited table that defines the corresponding ## VOTable elements and attributes. ## ## The actual table data must follow the header and consist of space or tab delimited ## data fields. The chosen delimiter must be used consistently throughout the table. ## ##---------------------------------------------------------------------------------- ## Table description, corresponding to the VOTable TABLE::DESCRIPTION element. ##---------------------------------------------------------------------------------- # DESCRIPTION:: # This is a sample table that shows a proposed format for generation of tables # for the C-COSMOS collaboration. This format is compatible with simple 'awk' or # S-mongo style processing but also allows full self-documentation and conversion # to more robust data formats (FITS, VOTable, postgres database ingest, etc). # ##---------------------------------------------------------------------------------- ## Coordinate system specification COOSYS. This is a "future" feature, as the ## current conversion code does not use this field. ##---------------------------------------------------------------------------------- # COOSYS:: # ID equinox epoch system # J2000 J2000. J2000. eq_FK5 # ##---------------------------------------------------------------------------------- ## Set the TABLE::PARAM values, which are values that apply for the entire table. ##---------------------------------------------------------------------------------- # PARAM:: # name datatype value description # version string 1.1 'Table version' # date string 2007/12/01 'Table release date' # ##---------------------------------------------------------------------------------- ## Define the column names via the FIELD element. The attributes 'name', ## 'datatype', 'unit', and 'description' are required. Optional attributes are: ## 'width', 'precision', 'ucd', 'utype', 'ref', and 'type'. ## See http://www.ivoa.net/Documents/REC/VOTable/VOTable-20040811.html#ToC25 for ## the VOTable definitions. ## Allowed values of datatype are: ## boolean, unsignedByte, short, int, long, string, float, double ## Units: (from http://www.ivoa.net/Documents/REC/VOTable/VOTable-20040811.html#sec:unit) ## The quantities in a column of the table may be expressed in some physical ## unit, which is specified by the unit attribute of the FIELD. The syntax of ## the unit string is defined in reference [3]; it is basically written as a ## string without blanks or spaces, where the symbols . or * indicate a ## multiplication, / stands for the division, and no special symbol is ## required for a power. Examples are unit="m2" for m2, unit="cm-2.s-1.keV-1" ## for cm-2s-1keV-1, or unit="erg/s" for erg s-1. The references [3] provide ## also the list of the valid symbols, which is essentially restricted to the ## Systeme International (SI) conventions, plus a few astronomical extensions ## concerning units used for time, angular, distance and energy measurements. ##---------------------------------------------------------------------------------- # FIELD:: # name datatype unit ucd description # id int '' 'meta.id' 'C-COSMOS short identifier number' # name string '' '' 'C-COSMOS long identifier name' # ra double deg 'meta.cryptic' 'Right Ascension' # dec double deg '' Declination # flux float erg/cm2/s '' Flux # ##---------------------------------------------------------------------------------- ## Now the actual field data in the order specified by the FIELD:: list. ## The data fields can be separated by tabs or spaces. If using spaces, ## any fields that contain a space must be enclosed in single quotes. ## 12 'CXOCS J193423+022312' 150.01212 2.52322 1.21e-13 13 'CXOCS J193322+024444' 150.02323 2.54444 1.21e-14 14 'CXOCS J195555+025555' 150.04444 2.55555 1.21e-15 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/data/whitespace.dat0000644000175100001710000000015600000000000022350 0ustar00vstsdocker "quoted colname with tab inside" col2 col3 val1 "val2 with tab" 2 val3 val4 3 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/test_c_reader.py0000644000175100001710000017304200000000000021773 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import os import functools from contextlib import nullcontext from io import BytesIO from textwrap import dedent import pytest import numpy as np from numpy import ma from astropy.table import Table, MaskedColumn from astropy.io import ascii from astropy.io.ascii.core import ParameterError, FastOptionsError, InconsistentTableError from astropy.io.ascii.fastbasic import ( FastBasic, FastCsv, FastTab, FastCommentedHeader, FastRdb, FastNoHeader) from astropy.utils.data import get_pkg_data_filename from astropy.utils.exceptions import AstropyWarning from .common import assert_equal, assert_almost_equal, assert_true StringIO = lambda x: BytesIO(x.encode('ascii')) # noqa CI = os.environ.get('CI', False) def assert_table_equal(t1, t2, check_meta=False, rtol=1.e-15, atol=1.e-300): """ Test equality of all columns in a table, with stricter tolerances for float columns than the np.allclose default. """ assert_equal(len(t1), len(t2)) assert_equal(t1.colnames, t2.colnames) if check_meta: assert_equal(t1.meta, t2.meta) for name in t1.colnames: if len(t1) != 0: assert_equal(t1[name].dtype.kind, t2[name].dtype.kind) if not isinstance(t1[name], MaskedColumn): for i, el in enumerate(t1[name]): try: if not isinstance(el, str) and np.isnan(el): assert_true(not isinstance(t2[name][i], str) and np.isnan(t2[name][i])) elif isinstance(el, str): assert_equal(el, t2[name][i]) else: assert_almost_equal(el, t2[name][i], rtol=rtol, atol=atol) except (TypeError, NotImplementedError): pass # ignore for now # Use this counter to create a unique filename for each file created in a test # if this function is called more than once in a single test _filename_counter = 0 def _read(tmpdir, table, Reader=None, format=None, parallel=False, check_meta=False, **kwargs): # make sure we have a newline so table can't be misinterpreted as a filename global _filename_counter table += '\n' reader = Reader(**kwargs) t1 = reader.read(table) t2 = reader.read(StringIO(table)) t3 = reader.read(table.splitlines()) t4 = ascii.read(table, format=format, guess=False, **kwargs) t5 = ascii.read(table, format=format, guess=False, fast_reader=False, **kwargs) assert_table_equal(t1, t2, check_meta=check_meta) assert_table_equal(t2, t3, check_meta=check_meta) assert_table_equal(t3, t4, check_meta=check_meta) assert_table_equal(t4, t5, check_meta=check_meta) if parallel: if CI: pytest.xfail("Multiprocessing can sometimes fail on CI") t6 = ascii.read(table, format=format, guess=False, fast_reader={ 'parallel': True}, **kwargs) assert_table_equal(t1, t6, check_meta=check_meta) filename = str(tmpdir.join(f'table{_filename_counter}.txt')) _filename_counter += 1 with open(filename, 'wb') as f: f.write(table.encode('ascii')) f.flush() t7 = ascii.read(filename, format=format, guess=False, **kwargs) if parallel: t8 = ascii.read(filename, format=format, guess=False, fast_reader={ 'parallel': True}, **kwargs) assert_table_equal(t1, t7, check_meta=check_meta) if parallel: assert_table_equal(t1, t8, check_meta=check_meta) return t1 @pytest.fixture(scope='function') def read_basic(tmpdir, request): return functools.partial(_read, tmpdir, Reader=FastBasic, format='basic') @pytest.fixture(scope='function') def read_csv(tmpdir, request): return functools.partial(_read, tmpdir, Reader=FastCsv, format='csv') @pytest.fixture(scope='function') def read_tab(tmpdir, request): return functools.partial(_read, tmpdir, Reader=FastTab, format='tab') @pytest.fixture(scope='function') def read_commented_header(tmpdir, request): return functools.partial(_read, tmpdir, Reader=FastCommentedHeader, format='commented_header') @pytest.fixture(scope='function') def read_rdb(tmpdir, request): return functools.partial(_read, tmpdir, Reader=FastRdb, format='rdb') @pytest.fixture(scope='function') def read_no_header(tmpdir, request): return functools.partial(_read, tmpdir, Reader=FastNoHeader, format='no_header') @pytest.mark.parametrize("parallel", [True, False]) def test_simple_data(parallel, read_basic): """ Make sure the fast reader works with basic input data. """ table = read_basic("A B C\n1 2 3\n4 5 6", parallel=parallel) expected = Table([[1, 4], [2, 5], [3, 6]], names=('A', 'B', 'C')) assert_table_equal(table, expected) def test_read_types(): """ Make sure that the read() function takes filenames, strings, and lists of strings in addition to file-like objects. """ t1 = ascii.read("a b c\n1 2 3\n4 5 6", format='fast_basic', guess=False) # TODO: also read from file t2 = ascii.read(StringIO("a b c\n1 2 3\n4 5 6"), format='fast_basic', guess=False) t3 = ascii.read(["a b c", "1 2 3", "4 5 6"], format='fast_basic', guess=False) assert_table_equal(t1, t2) assert_table_equal(t2, t3) @pytest.mark.parametrize("parallel", [True, False]) def test_supplied_names(parallel, read_basic): """ If passed as a parameter, names should replace any column names found in the header. """ table = read_basic("A B C\n1 2 3\n4 5 6", names=('X', 'Y', 'Z'), parallel=parallel) expected = Table([[1, 4], [2, 5], [3, 6]], names=('X', 'Y', 'Z')) assert_table_equal(table, expected) @pytest.mark.parametrize("parallel", [True, False]) def test_no_header(parallel, read_basic, read_no_header): """ The header should not be read when header_start=None. Unless names is passed, the column names should be auto-generated. """ # Cannot set header_start=None for basic format with pytest.raises(ValueError): read_basic("A B C\n1 2 3\n4 5 6", header_start=None, data_start=0, parallel=parallel) t2 = read_no_header("A B C\n1 2 3\n4 5 6", parallel=parallel) expected = Table([['A', '1', '4'], ['B', '2', '5'], ['C', '3', '6']], names=('col1', 'col2', 'col3')) assert_table_equal(t2, expected) @pytest.mark.parametrize("parallel", [True, False]) def test_no_header_supplied_names(parallel, read_basic, read_no_header): """ If header_start=None and names is passed as a parameter, header data should not be read and names should be used instead. """ table = read_no_header("A B C\n1 2 3\n4 5 6", names=('X', 'Y', 'Z'), parallel=parallel) expected = Table([['A', '1', '4'], ['B', '2', '5'], ['C', '3', '6']], names=('X', 'Y', 'Z')) assert_table_equal(table, expected) @pytest.mark.parametrize("parallel", [True, False]) def test_comment(parallel, read_basic): """ Make sure that line comments are ignored by the C reader. """ table = read_basic("# comment\nA B C\n # another comment\n1 2 3\n4 5 6", parallel=parallel) expected = Table([[1, 4], [2, 5], [3, 6]], names=('A', 'B', 'C')) assert_table_equal(table, expected) @pytest.mark.parametrize("parallel", [True, False]) def test_empty_lines(parallel, read_basic): """ Make sure that empty lines are ignored by the C reader. """ table = read_basic("\n\nA B C\n1 2 3\n\n\n4 5 6\n\n\n\n", parallel=parallel) expected = Table([[1, 4], [2, 5], [3, 6]], names=('A', 'B', 'C')) assert_table_equal(table, expected) @pytest.mark.parametrize("parallel", [True, False]) def test_lstrip_whitespace(parallel, read_basic): """ Test to make sure the reader ignores whitespace at the beginning of fields. """ text = """ 1, 2, \t3 A,\t\t B, C a, b, c """ + ' \n' table = read_basic(text, delimiter=',', parallel=parallel) expected = Table([['A', 'a'], ['B', 'b'], ['C', 'c']], names=('1', '2', '3')) assert_table_equal(table, expected) @pytest.mark.parametrize("parallel", [True, False]) def test_rstrip_whitespace(parallel, read_basic): """ Test to make sure the reader ignores whitespace at the end of fields. """ text = ' 1 ,2 \t,3 \nA\t,B ,C\t \t \n \ta ,b , c \n' table = read_basic(text, delimiter=',', parallel=parallel) expected = Table([['A', 'a'], ['B', 'b'], ['C', 'c']], names=('1', '2', '3')) assert_table_equal(table, expected) @pytest.mark.parametrize("parallel", [True, False]) def test_conversion(parallel, read_basic): """ The reader should try to convert each column to ints. If this fails, the reader should try to convert to floats. Failing this, i.e. on parsing non-numeric input including isolated positive/negative signs, it should fall back to strings. """ text = """ A B C D E F G H 1 a 3 4 5 6 7 8 2. 1 9 -.1e1 10.0 8.7 6 -5.3e4 4 2 -12 .4 +.e1 - + six """ table = read_basic(text, parallel=parallel) assert_equal(table['A'].dtype.kind, 'f') assert table['B'].dtype.kind in ('S', 'U') assert_equal(table['C'].dtype.kind, 'i') assert_equal(table['D'].dtype.kind, 'f') assert table['E'].dtype.kind in ('S', 'U') assert table['F'].dtype.kind in ('S', 'U') assert table['G'].dtype.kind in ('S', 'U') assert table['H'].dtype.kind in ('S', 'U') @pytest.mark.parametrize("parallel", [True, False]) def test_delimiter(parallel, read_basic): """ Make sure that different delimiters work as expected. """ text = dedent(""" COL1 COL2 COL3 1 A -1 2 B -2 """) expected = Table([[1, 2], ['A', 'B'], [-1, -2]], names=('COL1', 'COL2', 'COL3')) for sep in ' ,\t#;': table = read_basic(text.replace(' ', sep), delimiter=sep, parallel=parallel) assert_table_equal(table, expected) @pytest.mark.parametrize("parallel", [True, False]) def test_include_names(parallel, read_basic): """ If include_names is not None, the parser should read only those columns in include_names. """ table = read_basic("A B C D\n1 2 3 4\n5 6 7 8", include_names=['A', 'D'], parallel=parallel) expected = Table([[1, 5], [4, 8]], names=('A', 'D')) assert_table_equal(table, expected) @pytest.mark.parametrize("parallel", [True, False]) def test_exclude_names(parallel, read_basic): """ If exclude_names is not None, the parser should exclude the columns in exclude_names. """ table = read_basic("A B C D\n1 2 3 4\n5 6 7 8", exclude_names=['A', 'D'], parallel=parallel) expected = Table([[2, 6], [3, 7]], names=('B', 'C')) assert_table_equal(table, expected) @pytest.mark.parametrize("parallel", [True, False]) def test_include_exclude_names(parallel, read_basic): """ Make sure that include_names is applied before exclude_names if both are specified. """ text = dedent(""" A B C D E F G H 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 """) table = read_basic(text, include_names=['A', 'B', 'D', 'F', 'H'], exclude_names=['B', 'F'], parallel=parallel) expected = Table([[1, 9], [4, 12], [8, 16]], names=('A', 'D', 'H')) assert_table_equal(table, expected) def test_doubled_quotes(read_csv): """ Test #8283 (fix for #8281), parsing doubled-quotes "ab""cd" in a quoted field was incorrect. """ tbl = '\n'.join(['a,b', '"d""","d""q"', '"""q",""""']) expected = Table([['d"', '"q'], ['d"q', '"']], names=('a', 'b')) dat = read_csv(tbl) assert_table_equal(dat, expected) # In addition to the local read_csv wrapper, check that default # parsing with guessing gives the right answer. for fast_reader in True, False: dat = ascii.read(tbl, fast_reader=fast_reader) assert_table_equal(dat, expected) @pytest.mark.filterwarnings("ignore:OverflowError converting to IntType in column TIMESTAMP") def test_doubled_quotes_segv(): """ Test the exact example from #8281 which resulted in SEGV prior to #8283 (in contrast to the tests above that just gave the wrong answer). Attempts to produce a more minimal example were unsuccessful, so the whole thing is included. """ tbl = dedent(""" "ID","TIMESTAMP","addendum_id","bib_reference","bib_reference_url","client_application","client_category","client_sort_key","color","coordsys","creator","creator_did","data_pixel_bitpix","dataproduct_subtype","dataproduct_type","em_max","em_min","format","hips_builder","hips_copyright","hips_creation_date","hips_creation_date_1","hips_creator","hips_data_range","hips_estsize","hips_frame","hips_glu_tag","hips_hierarchy","hips_initial_dec","hips_initial_fov","hips_initial_ra","hips_lon_asc","hips_master_url","hips_order","hips_order_1","hips_order_4","hips_order_min","hips_overlay","hips_pixel_bitpix","hips_pixel_cut","hips_pixel_scale","hips_progenitor_url","hips_publisher","hips_release_date","hips_release_date_1","hips_rgb_blue","hips_rgb_green","hips_rgb_red","hips_sampling","hips_service_url","hips_service_url_1","hips_service_url_2","hips_service_url_3","hips_service_url_4","hips_service_url_5","hips_service_url_6","hips_service_url_7","hips_service_url_8","hips_skyval","hips_skyval_method","hips_skyval_value","hips_status","hips_status_1","hips_status_2","hips_status_3","hips_status_4","hips_status_5","hips_status_6","hips_status_7","hips_status_8","hips_tile_format","hips_tile_format_1","hips_tile_format_4","hips_tile_width","hips_version","hipsgen_date","hipsgen_date_1","hipsgen_date_10","hipsgen_date_11","hipsgen_date_12","hipsgen_date_2","hipsgen_date_3","hipsgen_date_4","hipsgen_date_5","hipsgen_date_6","hipsgen_date_7","hipsgen_date_8","hipsgen_date_9","hipsgen_params","hipsgen_params_1","hipsgen_params_10","hipsgen_params_11","hipsgen_params_12","hipsgen_params_2","hipsgen_params_3","hipsgen_params_4","hipsgen_params_5","hipsgen_params_6","hipsgen_params_7","hipsgen_params_8","hipsgen_params_9","label","maxOrder","moc_access_url","moc_order","moc_release_date","moc_sky_fraction","obs_ack","obs_collection","obs_copyrigh_url","obs_copyright","obs_copyright_1","obs_copyright_url","obs_copyright_url_1","obs_description","obs_description_url","obs_descrition_url","obs_id","obs_initial_dec","obs_initial_fov","obs_initial_ra","obs_provenance","obs_regime","obs_title","ohips_frame","pixelCut","pixelRange","prov_did","prov_progenitor","prov_progenitor_url","publisher_did","publisher_id","s_pixel_scale","t_max","t_min" "CDS/P/2MASS/H","1524123841000","","2006AJ....131.1163S","http://cdsbib.u-strasbg.fr/cgi-bin/cdsbib?2006AJ....131.1163S","AladinDesktop","Image/Infrared/2MASS","04-001-03","","","","ivo://CDS/P/2MASS/H","","","image","1.798E-6","1.525E-6","","Aladin/HipsGen v9.017","CNRS/Unistra","2013-05-06T20:36Z","","CDS (A.Oberto)","","","equatorial","","mean","","","","","","9","","","","","","0 60","2.236E-4","","","2016-04-22T13:48Z","","","","","","http://alasky.u-strasbg.fr/2MASS/H","https://irsa.ipac.caltech.edu/data/hips/CDS/2MASS/H","http://alaskybis.u-strasbg.fr/2MASS/H","https://alaskybis.u-strasbg.fr/2MASS/H","","","","","","","","","public master clonableOnce","public mirror unclonable","public mirror clonableOnce","public mirror clonableOnce","","","","","","jpeg fits","","","512","1.31","","","","","","","","","","","","","","","","","","","","","","","","","","","","","http://alasky.u-strasbg.fr/2MASS/H/Moc.fits","9","","1","University of Massachusetts & IPAC/Caltech","The Two Micron All Sky Survey - H band (2MASS H)","","University of Massachusetts & IPAC/Caltech","","http://www.ipac.caltech.edu/2mass/","","2MASS has uniformly scanned the entire sky in three near-infrared bands to detect and characterize point sources brighter than about 1 mJy in each band, with signal-to-noise ratio (SNR) greater than 10, using a pixel size of 2.0"". This has achieved an 80,000-fold improvement in sensitivity relative to earlier surveys. 2MASS used two highly-automated 1.3-m telescopes, one at Mt. Hopkins, AZ, and one at CTIO, Chile. Each telescope was equipped with a three-channel camera, each channel consisting of a 256x256 array of HgCdTe detectors, capable of observing the sky simultaneously at J (1.25 microns), H (1.65 microns), and Ks (2.17 microns). The University of Massachusetts (UMass) was responsible for the overall management of the project, and for developing the infrared cameras and on-site computing systems at both facilities. The Infrared Processing and Analysis Center (IPAC) is responsible for all data processing through the Production Pipeline, and construction and distribution of the data products. Funding is provided primarily by NASA and the NSF","","","","+0","0.11451621372724685","0","","Infrared","2MASS H (1.66um)","","","","","IPAC/NASA","","","","","51941","50600" """) # noqa ascii.read(tbl, format='csv', fast_reader=True, guess=False) @pytest.mark.parametrize("parallel", [True, False]) def test_quoted_fields(parallel, read_basic): """ The character quotechar (default '"') should denote the start of a field which can contain the field delimiter and newlines. """ if parallel: pytest.xfail("Multiprocessing can fail with quoted fields") text = dedent(""" "A B" C D 1.5 2.1 -37.1 a b " c d" """) table = read_basic(text, parallel=parallel) expected = Table([['1.5', 'a'], ['2.1', 'b'], ['-37.1', 'cd']], names=('A B', 'C', 'D')) assert_table_equal(table, expected) table = read_basic(text.replace('"', "'"), quotechar="'", parallel=parallel) assert_table_equal(table, expected) @pytest.mark.parametrize("key,val", [ ('delimiter', ',,'), # multi-char delimiter ('comment', '##'), # multi-char comment ('data_start', None), # data_start=None ('data_start', -1), # data_start negative ('quotechar', '##'), # multi-char quote signifier ('header_start', -1), # negative header_start ('converters', dict((i + 1, ascii.convert_numpy(np.uint)) for i in range(3))), # passing converters ('Inputter', ascii.ContinuationLinesInputter), # passing Inputter ('header_Splitter', ascii.DefaultSplitter), # passing Splitter ('data_Splitter', ascii.DefaultSplitter)]) def test_invalid_parameters(key, val): """ Make sure the C reader raises an error if passed parameters it can't handle. """ with pytest.raises(ParameterError): FastBasic(**{key: val}).read('1 2 3\n4 5 6') with pytest.raises(ParameterError): ascii.read('1 2 3\n4 5 6', format='fast_basic', guess=False, **{key: val}) def test_invalid_parameters_other(): with pytest.raises(TypeError): FastBasic(foo=7).read('1 2 3\n4 5 6') # unexpected argument with pytest.raises(FastOptionsError): # don't fall back on the slow reader ascii.read('1 2 3\n4 5 6', format='basic', fast_reader={'foo': 7}) with pytest.raises(ParameterError): # Outputter cannot be specified in constructor FastBasic(Outputter=ascii.TableOutputter).read('1 2 3\n4 5 6') def test_too_many_cols1(): """ If a row contains too many columns, the C reader should raise an error. """ text = dedent(""" A B C 1 2 3 4 5 6 7 8 9 10 11 12 13 """) with pytest.raises(InconsistentTableError) as e: FastBasic().read(text) assert 'Number of header columns (3) ' \ 'inconsistent with data columns in data line 2' in str(e.value) def test_too_many_cols2(): text = """\ aaa,bbb 1,2, 3,4, """ with pytest.raises(InconsistentTableError) as e: FastCsv().read(text) assert 'Number of header columns (2) ' \ 'inconsistent with data columns in data line 0' in str(e.value) def test_too_many_cols3(): text = """\ aaa,bbb 1,2,, 3,4, """ with pytest.raises(InconsistentTableError) as e: FastCsv().read(text) assert 'Number of header columns (2) ' \ 'inconsistent with data columns in data line 0' in str(e.value) def test_too_many_cols4(): # https://github.com/astropy/astropy/issues/9922 with pytest.raises(InconsistentTableError) as e: ascii.read(get_pkg_data_filename('data/conf_py.txt'), fast_reader=True, guess=True) assert 'Unable to guess table format with the guesses listed below' in str(e.value) @pytest.mark.parametrize("parallel", [True, False]) def test_not_enough_cols(parallel, read_csv): """ If a row does not have enough columns, the FastCsv reader should add empty fields while the FastBasic reader should raise an error. """ text = """ A,B,C 1,2,3 4,5 6,7,8 """ table = read_csv(text, parallel=parallel) assert table['B'][1] is not ma.masked assert table['C'][1] is ma.masked with pytest.raises(InconsistentTableError): table = FastBasic(delimiter=',').read(text) @pytest.mark.parametrize("parallel", [True, False]) def test_data_end(parallel, read_basic, read_rdb): """ The parameter data_end should specify where data reading ends. """ text = """ A B C 1 2 3 4 5 6 7 8 9 10 11 12 """ table = read_basic(text, data_end=3, parallel=parallel) expected = Table([[1, 4], [2, 5], [3, 6]], names=('A', 'B', 'C')) assert_table_equal(table, expected) # data_end supports negative indexing table = read_basic(text, data_end=-2, parallel=parallel) assert_table_equal(table, expected) text = """ A\tB\tC N\tN\tS 1\t2\ta 3\t4\tb 5\t6\tc """ # make sure data_end works with RDB table = read_rdb(text, data_end=-1, parallel=parallel) expected = Table([[1, 3], [2, 4], ['a', 'b']], names=('A', 'B', 'C')) assert_table_equal(table, expected) # positive index table = read_rdb(text, data_end=3, parallel=parallel) expected = Table([[1], [2], ['a']], names=('A', 'B', 'C')) assert_table_equal(table, expected) # empty table if data_end is too small table = read_rdb(text, data_end=1, parallel=parallel) expected = Table([[], [], []], names=('A', 'B', 'C')) assert_table_equal(table, expected) @pytest.mark.parametrize("parallel", [True, False]) def test_inf_nan(parallel, read_basic): """ Test that inf and nan-like values are correctly parsed on all platforms. Regression test for https://github.com/astropy/astropy/pull/3525 """ text = dedent("""\ A nan +nan -nan inf infinity +inf +infinity -inf -infinity """) expected = Table({'A': [np.nan, np.nan, np.nan, np.inf, np.inf, np.inf, np.inf, -np.inf, -np.inf]}) table = read_basic(text, parallel=parallel) assert table['A'].dtype.kind == 'f' assert_table_equal(table, expected) @pytest.mark.parametrize("parallel", [True, False]) def test_fill_values(parallel, read_basic): """ Make sure that the parameter fill_values works as intended. If fill_values is not specified, the default behavior should be to convert '' to 0. """ text = """ A, B, C , 2, nan a, -999, -3.4 nan, 5, -9999 8, nan, 7.6e12 """ table = read_basic(text, delimiter=',', parallel=parallel) # The empty value in row A should become a masked '0' assert isinstance(table['A'], MaskedColumn) assert table['A'][0] is ma.masked # '0' rather than 0 because there is a string in the column assert_equal(table['A'].data.data[0], '0') assert table['A'][1] is not ma.masked table = read_basic(text, delimiter=',', fill_values=('-999', '0'), parallel=parallel) assert isinstance(table['B'], MaskedColumn) assert table['A'][0] is not ma.masked # empty value unaffected assert table['C'][2] is not ma.masked # -9999 is not an exact match assert table['B'][1] is ma.masked # Numeric because the rest of the column contains numeric data assert_equal(table['B'].data.data[1], 0.0) assert table['B'][0] is not ma.masked table = read_basic(text, delimiter=',', fill_values=[], parallel=parallel) # None of the columns should be masked for name in 'ABC': assert not isinstance(table[name], MaskedColumn) table = read_basic(text, delimiter=',', fill_values=[('', '0', 'A'), ('nan', '999', 'A', 'C')], parallel=parallel) assert np.isnan(table['B'][3]) # nan filling skips column B assert table['B'][3] is not ma.masked # should skip masking as well as replacing nan assert table['A'][0] is ma.masked assert table['A'][2] is ma.masked assert_equal(table['A'].data.data[0], '0') assert_equal(table['A'].data.data[2], '999') assert table['C'][0] is ma.masked assert_almost_equal(table['C'].data.data[0], 999.0) assert_almost_equal(table['C'][1], -3.4) # column is still of type float @pytest.mark.parametrize("parallel", [True, False]) def test_fill_include_exclude_names(parallel, read_csv): """ fill_include_names and fill_exclude_names should filter missing/empty value handling in the same way that include_names and exclude_names filter output columns. """ text = """ A, B, C , 1, 2 3, , 4 5, 5, """ table = read_csv(text, fill_include_names=['A', 'B'], parallel=parallel) assert table['A'][0] is ma.masked assert table['B'][1] is ma.masked assert table['C'][2] is not ma.masked # C not in fill_include_names table = read_csv(text, fill_exclude_names=['A', 'B'], parallel=parallel) assert table['C'][2] is ma.masked assert table['A'][0] is not ma.masked assert table['B'][1] is not ma.masked # A and B excluded from fill handling table = read_csv(text, fill_include_names=['A', 'B'], fill_exclude_names=['B'], parallel=parallel) assert table['A'][0] is ma.masked assert table['B'][1] is not ma.masked # fill_exclude_names applies after fill_include_names assert table['C'][2] is not ma.masked @pytest.mark.parametrize("parallel", [True, False]) def test_many_rows(parallel, read_basic): """ Make sure memory reallocation works okay when the number of rows is large (so that each column string is longer than INITIAL_COL_SIZE). """ text = 'A B C\n' for i in range(500): # create 500 rows text += ' '.join([str(i) for i in range(3)]) text += '\n' table = read_basic(text, parallel=parallel) expected = Table([[0] * 500, [1] * 500, [2] * 500], names=('A', 'B', 'C')) assert_table_equal(table, expected) @pytest.mark.parametrize("parallel", [True, False]) def test_many_columns(parallel, read_basic): """ Make sure memory reallocation works okay when the number of columns is large (so that each header string is longer than INITIAL_HEADER_SIZE). """ # create a string with 500 columns and two data rows text = ' '.join([str(i) for i in range(500)]) text += ('\n' + text + '\n' + text) table = read_basic(text, parallel=parallel) expected = Table([[i, i] for i in range(500)], names=[str(i) for i in range(500)]) assert_table_equal(table, expected) def test_fast_reader(): """ Make sure that ascii.read() works as expected by default and with fast_reader specified. """ text = 'a b c\n1 2 3\n4 5 6' with pytest.raises(ParameterError): # C reader can't handle regex comment ascii.read(text, format='fast_basic', guess=False, comment='##') # Enable multiprocessing and the fast converter try: ascii.read(text, format='basic', guess=False, fast_reader={'parallel': True, 'use_fast_converter': True}) except NotImplementedError: # Might get this on Windows, try without parallel... if os.name == 'nt': ascii.read(text, format='basic', guess=False, fast_reader={'parallel': False, 'use_fast_converter': True}) else: raise # Should raise an error if fast_reader has an invalid key with pytest.raises(FastOptionsError): ascii.read(text, format='fast_basic', guess=False, fast_reader={'foo': True}) # Use the slow reader instead ascii.read(text, format='basic', guess=False, comment='##', fast_reader=False) # Will try the slow reader afterwards by default ascii.read(text, format='basic', guess=False, comment='##') @pytest.mark.parametrize("parallel", [True, False]) def test_read_tab(parallel, read_tab): """ The fast reader for tab-separated values should not strip whitespace, unlike the basic reader. """ if parallel: pytest.xfail("Multiprocessing can fail with quoted fields") text = '1\t2\t3\n a\t b \t\n c\t" d\n e"\t ' table = read_tab(text, parallel=parallel) assert_equal(table['1'][0], ' a') # preserve line whitespace assert_equal(table['2'][0], ' b ') # preserve field whitespace assert table['3'][0] is ma.masked # empty value should be masked assert_equal(table['2'][1], ' d e') # preserve whitespace in quoted fields assert_equal(table['3'][1], ' ') # preserve end-of-line whitespace @pytest.mark.parametrize("parallel", [True, False]) def test_default_data_start(parallel, read_basic): """ If data_start is not explicitly passed to read(), data processing should beginning right after the header. """ text = 'ignore this line\na b c\n1 2 3\n4 5 6' table = read_basic(text, header_start=1, parallel=parallel) expected = Table([[1, 4], [2, 5], [3, 6]], names=('a', 'b', 'c')) assert_table_equal(table, expected) @pytest.mark.parametrize("parallel", [True, False]) def test_commented_header(parallel, read_commented_header): """ The FastCommentedHeader reader should mimic the behavior of the CommentedHeader by overriding the default header behavior of FastBasic. """ text = """ # A B C 1 2 3 4 5 6 """ t1 = read_commented_header(text, parallel=parallel) expected = Table([[1, 4], [2, 5], [3, 6]], names=('A', 'B', 'C')) assert_table_equal(t1, expected) text = '# first commented line\n # second commented line\n\n' + text t2 = read_commented_header(text, header_start=2, data_start=0, parallel=parallel) assert_table_equal(t2, expected) t3 = read_commented_header(text, header_start=-1, data_start=0, parallel=parallel) # negative indexing allowed assert_table_equal(t3, expected) text += '7 8 9' t4 = read_commented_header(text, header_start=2, data_start=2, parallel=parallel) expected = Table([[7], [8], [9]], names=('A', 'B', 'C')) assert_table_equal(t4, expected) with pytest.raises(ParameterError): read_commented_header(text, header_start=-1, data_start=-1, parallel=parallel) # data_start cannot be negative @pytest.mark.parametrize("parallel", [True, False]) def test_rdb(parallel, read_rdb): """ Make sure the FastRdb reader works as expected. """ text = """ A\tB\tC 1n\tS\t4N 1\t 9\t4.3 """ table = read_rdb(text, parallel=parallel) expected = Table([[1], [' 9'], [4.3]], names=('A', 'B', 'C')) assert_table_equal(table, expected) assert_equal(table['A'].dtype.kind, 'i') assert table['B'].dtype.kind in ('S', 'U') assert_equal(table['C'].dtype.kind, 'f') with pytest.raises(ValueError) as e: text = 'A\tB\tC\nN\tS\tN\n4\tb\ta' # C column contains non-numeric data read_rdb(text, parallel=parallel) assert 'Column C failed to convert' in str(e.value) with pytest.raises(ValueError) as e: text = 'A\tB\tC\nN\tN\n1\t2\t3' # not enough types specified read_rdb(text, parallel=parallel) assert 'mismatch between number of column names and column types' in str(e.value) with pytest.raises(ValueError) as e: text = 'A\tB\tC\nN\tN\t5\n1\t2\t3' # invalid type for column C read_rdb(text, parallel=parallel) assert 'type definitions do not all match [num](N|S)' in str(e.value) @pytest.mark.parametrize("parallel", [True, False]) def test_data_start(parallel, read_basic): """ Make sure that data parsing begins at data_start (ignoring empty and commented lines but not taking quoted values into account). """ if parallel: pytest.xfail("Multiprocessing can fail with quoted fields") text = """ A B C 1 2 3 4 5 6 7 8 "9 \t1" # comment 10 11 12 """ table = read_basic(text, data_start=2, parallel=parallel) expected = Table([[4, 7, 10], [5, 8, 11], [6, 91, 12]], names=('A', 'B', 'C')) assert_table_equal(table, expected) table = read_basic(text, data_start=3, parallel=parallel) # ignore empty line expected = Table([[7, 10], [8, 11], [91, 12]], names=('A', 'B', 'C')) assert_table_equal(table, expected) with pytest.raises(InconsistentTableError) as e: # tries to begin in the middle of quoted field read_basic(text, data_start=4, parallel=parallel) assert 'header columns (3) inconsistent with data columns in data line 0' \ in str(e.value) table = read_basic(text, data_start=5, parallel=parallel) # ignore commented line expected = Table([[10], [11], [12]], names=('A', 'B', 'C')) assert_table_equal(table, expected) text = """ A B C 1 2 3 4 5 6 7 8 9 # comment 10 11 12 """ # make sure reading works as expected in parallel table = read_basic(text, data_start=2, parallel=parallel) expected = Table([[4, 7, 10], [5, 8, 11], [6, 9, 12]], names=('A', 'B', 'C')) assert_table_equal(table, expected) @pytest.mark.parametrize("parallel", [True, False]) def test_quoted_empty_values(parallel, read_basic): """ Quoted empty values spanning multiple lines should be treated correctly. """ if parallel: pytest.xfail("Multiprocessing can fail with quoted fields") text = 'a b c\n1 2 " \n "' table = read_basic(text, parallel=parallel) assert table['c'][0] is ma.masked # empty value masked by default @pytest.mark.parametrize("parallel", [True, False]) def test_csv_comment_default(parallel, read_csv): """ Unless the comment parameter is specified, the CSV reader should not treat any lines as comments. """ text = 'a,b,c\n#1,2,3\n4,5,6' table = read_csv(text, parallel=parallel) expected = Table([['#1', '4'], [2, 5], [3, 6]], names=('a', 'b', 'c')) assert_table_equal(table, expected) @pytest.mark.parametrize("parallel", [True, False]) def test_whitespace_before_comment(parallel, read_tab): """ Readers that don't strip whitespace from data (Tab, RDB) should still treat lines with leading whitespace and then the comment char as comment lines. """ text = 'a\tb\tc\n # comment line\n1\t2\t3' table = read_tab(text, parallel=parallel) expected = Table([[1], [2], [3]], names=('a', 'b', 'c')) assert_table_equal(table, expected) @pytest.mark.parametrize("parallel", [True, False]) def test_strip_line_trailing_whitespace(parallel, read_basic): """ Readers that strip whitespace from lines should ignore trailing whitespace after the last data value of each row. """ text = 'a b c\n1 2 \n3 4 5' with pytest.raises(InconsistentTableError) as e: ascii.read(StringIO(text), format='fast_basic', guess=False) assert 'header columns (3) inconsistent with data columns in data line 0' \ in str(e.value) text = 'a b c\n 1 2 3 \t \n 4 5 6 ' table = read_basic(text, parallel=parallel) expected = Table([[1, 4], [2, 5], [3, 6]], names=('a', 'b', 'c')) assert_table_equal(table, expected) @pytest.mark.parametrize("parallel", [True, False]) def test_no_data(parallel, read_basic): """ As long as column names are supplied, the C reader should return an empty table in the absence of data. """ table = read_basic('a b c', parallel=parallel) expected = Table([[], [], []], names=('a', 'b', 'c')) assert_table_equal(table, expected) table = read_basic('a b c\n1 2 3', data_start=2, parallel=parallel) assert_table_equal(table, expected) @pytest.mark.parametrize("parallel", [True, False]) def test_line_endings(parallel, read_basic, read_commented_header, read_rdb): """ Make sure the fast reader accepts CR and CR+LF as newlines. """ text = 'a b c\n1 2 3\n4 5 6\n7 8 9\n' expected = Table([[1, 4, 7], [2, 5, 8], [3, 6, 9]], names=('a', 'b', 'c')) for newline in ('\r\n', '\r'): table = read_basic(text.replace('\n', newline), parallel=parallel) assert_table_equal(table, expected) # Make sure the splitlines() method of FileString # works with CR/CR+LF line endings text = '#' + text for newline in ('\r\n', '\r'): table = read_commented_header(text.replace('\n', newline), parallel=parallel) assert_table_equal(table, expected) expected = Table([MaskedColumn([1, 4, 7]), [2, 5, 8], MaskedColumn([3, 6, 9])], names=('a', 'b', 'c')) expected['a'][0] = np.ma.masked expected['c'][0] = np.ma.masked text = 'a\tb\tc\nN\tN\tN\n\t2\t\n4\t5\t6\n7\t8\t9\n' for newline in ('\r\n', '\r'): table = read_rdb(text.replace('\n', newline), parallel=parallel) assert_table_equal(table, expected) assert np.all(table == expected) @pytest.mark.parametrize("parallel", [True, False]) def test_store_comments(parallel, read_basic): """ Make sure that the output Table produced by the fast reader stores any comment lines in its meta attribute. """ text = """ # header comment a b c # comment 2 # comment 3 1 2 3 4 5 6 """ table = read_basic(text, parallel=parallel, check_meta=True) assert_equal(table.meta['comments'], ['header comment', 'comment 2', 'comment 3']) @pytest.mark.parametrize("parallel", [True, False]) def test_empty_quotes(parallel, read_basic): """ Make sure the C reader doesn't segfault when the input data contains empty quotes. [#3407] """ table = read_basic('a b\n1 ""\n2 ""', parallel=parallel) expected = Table([[1, 2], [0, 0]], names=('a', 'b')) assert_table_equal(table, expected) @pytest.mark.parametrize("parallel", [True, False]) def test_fast_tab_with_names(parallel, read_tab): """ Make sure the C reader doesn't segfault when the header for the first column is missing [#3545] """ content = """# \tdecDeg\tRate_pn_offAxis\tRate_mos2_offAxis\tObsID\tSourceID\tRADeg\tversion\tCounts_pn\tRate_pn\trun\tRate_mos1\tRate_mos2\tInserted_pn\tInserted_mos2\tbeta\tRate_mos1_offAxis\trcArcsec\tname\tInserted\tCounts_mos1\tInserted_mos1\tCounts_mos2\ty\tx\tCounts\toffAxis\tRot -3.007559\t0.0000\t0.0010\t0013140201\t0\t213.462574\t0\t2\t0.0002\t0\t0.0001\t0.0001\t0\t1\t0.66\t0.0217\t3.0\tfakeXMMXCS J1413.8-0300\t3\t1\t2\t1\t398.000\t127.000\t5\t13.9\t72.3\t""" # noqa head = [f'A{i}' for i in range(28)] read_tab(content, data_start=1, parallel=parallel, names=head) @pytest.mark.skipif(not os.getenv('TEST_READ_HUGE_FILE'), reason='Environment variable TEST_READ_HUGE_FILE must be ' 'defined to run this test') def test_read_big_table(tmpdir): """Test reading of a huge file. This test generates a huge CSV file (~2.3Gb) before reading it (see https://github.com/astropy/astropy/pull/5319). The test is run only if the environment variable ``TEST_READ_HUGE_FILE`` is defined. Note that running the test requires quite a lot of memory (~18Gb when reading the file) !! """ NB_ROWS = 250000 NB_COLS = 500 filename = str(tmpdir.join("big_table.csv")) print(f"Creating a {NB_ROWS} rows table ({NB_COLS} columns).") data = np.random.random(NB_ROWS) t = Table(data=[data] * NB_COLS, names=[str(i) for i in range(NB_COLS)]) data = None print(f"Saving the table to {filename}") t.write(filename, format='ascii.csv', overwrite=True) t = None print("Counting the number of lines in the csv, it should be {NB_ROWS} + 1 (header).") with open(filename, 'r') as f: assert sum(1 for line in f) == NB_ROWS + 1 print("Reading the file with astropy.") t = Table.read(filename, format='ascii.csv', fast_reader=True) assert len(t) == NB_ROWS @pytest.mark.skipif(not os.getenv('TEST_READ_HUGE_FILE'), reason='Environment variable TEST_READ_HUGE_FILE must be ' 'defined to run this test') def test_read_big_table2(tmpdir): """Test reading of a file with a huge column. """ # (2**32 // 2) : max value for int # // 10 : we use a value for rows that have 10 chars (1e9) # + 5 : add a few lines so the length cannot be stored by an int NB_ROWS = 2**32 // 2 // 10 + 5 filename = str(tmpdir.join("big_table.csv")) print(f"Creating a {NB_ROWS} rows table.") data = np.full(NB_ROWS, int(1e9), dtype=np.int32) t = Table(data=[data], names=['a'], copy=False) print(f"Saving the table to {filename}") t.write(filename, format='ascii.csv', overwrite=True) t = None print("Counting the number of lines in the csv, it should be {NB_ROWS} + 1 (header).") with open(filename, 'r') as f: assert sum(1 for line in f) == NB_ROWS + 1 print("Reading the file with astropy.") t = Table.read(filename, format='ascii.csv', fast_reader=True) assert len(t) == NB_ROWS # Test these both with guessing turned on and off @pytest.mark.parametrize("guess", [True, False]) # fast_reader configurations: False| 'use_fast_converter'=False|True @pytest.mark.parametrize('fast_reader', [False, dict(use_fast_converter=False), dict(use_fast_converter=True)]) @pytest.mark.parametrize("parallel", [False, True]) def test_data_out_of_range(parallel, fast_reader, guess): """ Numbers with exponents beyond float64 range (|~4.94e-324 to 1.7977e+308|) shall be returned as 0 and +-inf respectively by the C parser, just like the Python parser. Test fast converter only to nominal accuracy. """ # Python reader and strtod() are expected to return precise results rtol = 1.e-30 # Update fast_reader dict; adapt relative precision for fast_converter if fast_reader: fast_reader['parallel'] = parallel if fast_reader.get('use_fast_converter'): rtol = 1.e-15 elif np.iinfo(np.int_).dtype == np.dtype(np.int32): # On 32bit the standard C parser (strtod) returns strings for these pytest.xfail("C parser cannot handle float64 on 32bit systems") if parallel: if not fast_reader: pytest.skip("Multiprocessing only available in fast reader") elif CI: pytest.xfail("Multiprocessing can sometimes fail on CI") test_for_warnings = fast_reader and not parallel if not parallel and not fast_reader: ctx = nullcontext() else: ctx = pytest.warns() fields = ['10.1E+199', '3.14e+313', '2048e+306', '0.6E-325', '-2.e345'] values = np.array([1.01e200, np.inf, np.inf, 0.0, -np.inf]) # NOTE: Warning behavior varies for the parameters being passed in. with ctx as w: t = ascii.read(StringIO(' '.join(fields)), format='no_header', guess=guess, fast_reader=fast_reader) if test_for_warnings: # Assert precision warnings for cols 2-5 assert len(w) == 4 for i in range(len(w)): assert (f"OverflowError converting to FloatType in column col{i+2}" in str(w[i].message)) read_values = np.array([col[0] for col in t.itercols()]) assert_almost_equal(read_values, values, rtol=rtol, atol=1.e-324) # Test some additional corner cases fields = ['.0101E202', '0.000000314E+314', '1777E+305', '-1799E+305', '0.2e-323', '5200e-327', ' 0.0000000000000000000001024E+330'] values = np.array([1.01e200, 3.14e307, 1.777e308, -np.inf, 0.0, 4.94e-324, 1.024e308]) with ctx as w: t = ascii.read(StringIO(' '.join(fields)), format='no_header', guess=guess, fast_reader=fast_reader) if test_for_warnings: # Assert precision warnings for cols 4-6 assert len(w) == 3 for i in range(len(w)): assert (f"OverflowError converting to FloatType in column col{i+4}" in str(w[i].message)) read_values = np.array([col[0] for col in t.itercols()]) assert_almost_equal(read_values, values, rtol=rtol, atol=1.e-324) # Test corner cases again with non-standard exponent_style (auto-detection) if fast_reader and fast_reader.get('use_fast_converter'): fast_reader.update({'exponent_style': 'A'}) else: pytest.skip("Fortran exponent style only available in fast converter") fields = ['.0101D202', '0.000000314d+314', '1777+305', '-1799E+305', '0.2e-323', '2500-327', ' 0.0000000000000000000001024Q+330'] with ctx as w: t = ascii.read(StringIO(' '.join(fields)), format='no_header', guess=guess, fast_reader=fast_reader) if test_for_warnings: assert len(w) == 3 read_values = np.array([col[0] for col in t.itercols()]) assert_almost_equal(read_values, values, rtol=rtol, atol=1.e-324) @pytest.mark.parametrize("guess", [True, False]) # fast_reader configurations: False| 'use_fast_converter'=False|True @pytest.mark.parametrize('fast_reader', [False, dict(use_fast_converter=False), dict(use_fast_converter=True)]) @pytest.mark.parametrize("parallel", [False, True]) def test_data_at_range_limit(parallel, fast_reader, guess): """ Test parsing of fixed-format float64 numbers near range limits (|~4.94e-324 to 1.7977e+308|) - within limit for full precision (|~2.5e-307| for strtod C parser, factor 10 better for fast_converter) exact numbers shall be returned, beyond that an Overflow warning raised. Input of exactly 0.0 must not raise an OverflowError. """ # Python reader and strtod() are expected to return precise results rtol = 1.e-30 # Update fast_reader dict; adapt relative precision for fast_converter if fast_reader: fast_reader['parallel'] = parallel if fast_reader.get('use_fast_converter'): rtol = 1.e-15 elif np.iinfo(np.int_).dtype == np.dtype(np.int32): # On 32bit the standard C parser (strtod) returns strings for these pytest.xfail("C parser cannot handle float64 on 32bit systems") if parallel: if not fast_reader: pytest.skip("Multiprocessing only available in fast reader") elif CI: pytest.xfail("Multiprocessing can sometimes fail on CI") # Test very long fixed-format strings (to strtod range limit w/o Overflow) for D in 99, 202, 305: t = ascii.read(StringIO(99 * '0' + '.' + D * '0' + '1'), format='no_header', guess=guess, fast_reader=fast_reader) assert_almost_equal(t['col1'][0], 10.**-(D + 1), rtol=rtol, atol=1.e-324) for D in 99, 202, 308: t = ascii.read(StringIO('1' + D * '0' + '.0'), format='no_header', guess=guess, fast_reader=fast_reader) assert_almost_equal(t['col1'][0], 10.**D, rtol=rtol, atol=1.e-324) # 0.0 is always exact (no Overflow warning)! for s in '0.0', '0.0e+0', 399 * '0' + '.' + 365 * '0': t = ascii.read(StringIO(s), format='no_header', guess=guess, fast_reader=fast_reader) assert t['col1'][0] == 0.0 # Test OverflowError at precision limit with laxer rtol if parallel: pytest.skip("Catching warnings broken in parallel mode") elif not fast_reader: pytest.skip("Python/numpy reader does not raise on Overflow") with pytest.warns() as warning_lines: t = ascii.read(StringIO('0.' + 314 * '0' + '1'), format='no_header', guess=guess, fast_reader=fast_reader) n_warns = len(warning_lines) assert n_warns in (0, 1), f'Expected 0 or 1 warning, found {n_warns}' if n_warns == 1: assert 'OverflowError converting to FloatType in column col1, possibly resulting in degraded precision' in str(warning_lines[0].message) # noqa assert_almost_equal(t['col1'][0], 1.e-315, rtol=1.e-10, atol=1.e-324) @pytest.mark.parametrize("guess", [True, False]) @pytest.mark.parametrize("parallel", [False, True]) def test_int_out_of_range(parallel, guess): """ Integer numbers outside int range shall be returned as string columns consistent with the standard (Python) parser (no 'upcasting' to float). """ imin = np.iinfo(int).min + 1 imax = np.iinfo(int).max - 1 huge = f'{imax+2:d}' text = f'P M S\n {imax:d} {imin:d} {huge:s}' expected = Table([[imax], [imin], [huge]], names=('P', 'M', 'S')) # NOTE: Warning behavior varies for the parameters being passed in. with pytest.warns() as w: table = ascii.read(text, format='basic', guess=guess, fast_reader={'parallel': parallel}) if not parallel: assert len(w) == 1 assert ("OverflowError converting to IntType in column S, reverting to String" in str(w[0].message)) assert_table_equal(table, expected) # Check with leading zeroes to make sure strtol does not read them as octal text = f'P M S\n000{imax:d} -0{-imin:d} 00{huge:s}' expected = Table([[imax], [imin], ['00' + huge]], names=('P', 'M', 'S')) with pytest.warns() as w: table = ascii.read(text, format='basic', guess=guess, fast_reader={'parallel': parallel}) if not parallel: assert len(w) == 1 assert ("OverflowError converting to IntType in column S, reverting to String" in str(w[0].message)) assert_table_equal(table, expected) @pytest.mark.parametrize("guess", [True, False]) def test_int_out_of_order(guess): """ Mixed columns should be returned as float, but if the out-of-range integer shows up first, it will produce a string column - with both readers. Broken with the parallel fast_reader. """ imax = np.iinfo(int).max - 1 text = f'A B\n 12.3 {imax:d}0\n {imax:d}0 45.6e7' expected = Table([[12.3, 10. * imax], [f'{imax:d}0', '45.6e7']], names=('A', 'B')) with pytest.warns(AstropyWarning, match=r'OverflowError converting to ' r'IntType in column B, reverting to String'): table = ascii.read(text, format='basic', guess=guess, fast_reader=True) assert_table_equal(table, expected) with pytest.warns(AstropyWarning, match=r'OverflowError converting to ' r'IntType in column B, reverting to String'): table = ascii.read(text, format='basic', guess=guess, fast_reader=False) assert_table_equal(table, expected) @pytest.mark.parametrize("guess", [True, False]) @pytest.mark.parametrize("parallel", [False, True]) def test_fortran_reader(parallel, guess): """ Make sure that ascii.read() can read Fortran-style exponential notation using the fast_reader. """ # Check for nominal np.float64 precision rtol = 1.e-15 atol = 0.0 text = 'A B C D\n100.01{:s}99 2.0 2.0{:s}-103 3\n' + \ ' 4.2{:s}-1 5.0{:s}-1 0.6{:s}4 .017{:s}+309' expc = Table([[1.0001e101, 0.42], [2, 0.5], [2.e-103, 6.e3], [3, 1.7e307]], names=('A', 'B', 'C', 'D')) expstyles = {'e': 6 * ('E'), 'D': ('D', 'd', 'd', 'D', 'd', 'D'), 'Q': 3 * ('q', 'Q'), 'Fortran': ('E', '0', 'D', 'Q', 'd', '0')} # C strtod (not-fast converter) can't handle Fortran exp with pytest.raises(FastOptionsError) as e: ascii.read(text.format(*(6 * ('D'))), format='basic', guess=guess, fast_reader={'use_fast_converter': False, 'parallel': parallel, 'exponent_style': 'D'}) assert 'fast_reader: exponent_style requires use_fast_converter' in str(e.value) # Enable multiprocessing and the fast converter iterate over # all style-exponent combinations, with auto-detection for s, c in expstyles.items(): table = ascii.read(text.format(*c), guess=guess, fast_reader={'parallel': parallel, 'exponent_style': s}) assert_table_equal(table, expc, rtol=rtol, atol=atol) # Additional corner-case checks including triple-exponents without # any character and mixed whitespace separators text = 'A B\t\t C D\n1.0001+101 2.0+000\t 0.0002-099 3\n ' + \ '0.42-000 \t 0.5 6.+003 0.000000000000000000000017+330' table = ascii.read(text, guess=guess, fast_reader={'parallel': parallel, 'exponent_style': 'A'}) assert_table_equal(table, expc, rtol=rtol, atol=atol) @pytest.mark.parametrize("guess", [True, False]) @pytest.mark.parametrize("parallel", [False, True]) def test_fortran_invalid_exp(parallel, guess): """ Test Fortran-style exponential notation in the fast_reader with invalid exponent-like patterns (no triple-digits) to make sure they are returned as strings instead, as with the standard C parser. """ if parallel and CI: pytest.xfail("Multiprocessing can sometimes fail on CI") formats = {'basic': ' ', 'tab': '\t', 'csv': ','} header = ['S1', 'F2', 'S2', 'F3', 'S3', 'F4', 'F5', 'S4', 'I1', 'F6', 'F7'] # Tested entries and expected returns, first for auto-detect, # then for different specified exponents fields = ['1.0001+1', '.42d1', '2.3+10', '0.5', '3+1001', '3000.', '2', '4.56e-2.3', '8000', '4.2-022', '.00000145e314'] vals_e = ['1.0001+1', '.42d1', '2.3+10', 0.5, '3+1001', 3.e3, 2, '4.56e-2.3', 8000, '4.2-022', 1.45e308] vals_d = ['1.0001+1', 4.2, '2.3+10', 0.5, '3+1001', 3.e3, 2, '4.56e-2.3', 8000, '4.2-022', '.00000145e314'] vals_a = ['1.0001+1', 4.2, '2.3+10', 0.5, '3+1001', 3.e3, 2, '4.56e-2.3', 8000, 4.2e-22, 1.45e308] vals_v = ['1.0001+1', 4.2, '2.3+10', 0.5, '3+1001', 3.e3, 2, '4.56e-2.3', 8000, '4.2-022', 1.45e308] # Iterate over supported format types and separators for f, s in formats.items(): t1 = ascii.read(StringIO(s.join(header) + '\n' + s.join(fields)), format=f, guess=guess, fast_reader={'parallel': parallel, 'exponent_style': 'A'}) assert_table_equal(t1, Table([[col] for col in vals_a], names=header)) # Non-basic separators require guessing enabled to be detected if guess: formats['bar'] = '|' else: formats = {'basic': ' '} for s in formats.values(): t2 = ascii.read(StringIO(s.join(header) + '\n' + s.join(fields)), guess=guess, fast_reader={'parallel': parallel, 'exponent_style': 'a'}) assert_table_equal(t2, Table([[col] for col in vals_a], names=header)) # Iterate for (default) expchar 'E' for s in formats.values(): t3 = ascii.read(StringIO(s.join(header) + '\n' + s.join(fields)), guess=guess, fast_reader={'parallel': parallel, 'use_fast_converter': True}) assert_table_equal(t3, Table([[col] for col in vals_e], names=header)) # Iterate for expchar 'D' for s in formats.values(): t4 = ascii.read(StringIO(s.join(header) + '\n' + s.join(fields)), guess=guess, fast_reader={'parallel': parallel, 'exponent_style': 'D'}) assert_table_equal(t4, Table([[col] for col in vals_d], names=header)) # Iterate for regular converter (strtod) for s in formats.values(): t5 = ascii.read(StringIO(s.join(header) + '\n' + s.join(fields)), guess=guess, fast_reader={'parallel': parallel, 'use_fast_converter': False}) read_values = [col[0] for col in t5.itercols()] if os.name == 'nt': # Apparently C strtod() on (some?) MSVC recognizes 'd' exponents! assert read_values == vals_v or read_values == vals_e else: assert read_values == vals_e def test_fortran_reader_notbasic(): """ Check if readers without a fast option raise a value error when a fast_reader is asked for (implies the default 'guess=True'). """ tabstr = dedent(""" a b 1 1.23D4 2 5.67D-8 """)[1:-1] t1 = ascii.read(tabstr.split('\n'), fast_reader=dict(exponent_style='D')) assert t1['b'].dtype.kind == 'f' tabrdb = dedent(""" a\tb # A simple RDB table N\tN 1\t 1.23D4 2\t 5.67-008 """)[1:-1] t2 = ascii.read(tabrdb.split('\n'), format='rdb', fast_reader=dict(exponent_style='fortran')) assert t2['b'].dtype.kind == 'f' tabrst = dedent(""" = ======= a b = ======= 1 1.23E4 2 5.67E-8 = ======= """)[1:-1] t3 = ascii.read(tabrst.split('\n'), format='rst') assert t3['b'].dtype.kind == 'f' t4 = ascii.read(tabrst.split('\n'), guess=True) assert t4['b'].dtype.kind == 'f' # In the special case of fast_converter=True (the default), # incompatibility is ignored t5 = ascii.read(tabrst.split('\n'), format='rst', fast_reader=True) assert t5['b'].dtype.kind == 'f' with pytest.raises(ParameterError): ascii.read(tabrst.split('\n'), format='rst', guess=False, fast_reader='force') with pytest.raises(ParameterError): ascii.read(tabrst.split('\n'), format='rst', guess=False, fast_reader=dict(use_fast_converter=False)) tabrst = tabrst.replace('E', 'D') with pytest.raises(ParameterError): ascii.read(tabrst.split('\n'), format='rst', guess=False, fast_reader=dict(exponent_style='D')) @pytest.mark.parametrize("guess", [True, False]) @pytest.mark.parametrize('fast_reader', [dict(exponent_style='D'), dict(exponent_style='A')]) def test_dict_kwarg_integrity(fast_reader, guess): """ Check if dictionaries passed as kwargs (fast_reader in this test) are left intact by ascii.read() """ expstyle = fast_reader.get('exponent_style', 'E') fields = ['10.1D+199', '3.14d+313', '2048d+306', '0.6D-325', '-2.d345'] ascii.read(StringIO(' '.join(fields)), guess=guess, fast_reader=fast_reader) assert fast_reader.get('exponent_style', None) == expstyle @pytest.mark.parametrize('fast_reader', [False, dict(parallel=True), dict(parallel=False)]) def test_read_empty_basic_table_with_comments(fast_reader): """ Test for reading a "basic" format table that has no data but has comments. Tests the fix for #8267. """ dat = """ # comment 1 # comment 2 col1 col2 """ t = ascii.read(dat, fast_reader=fast_reader) assert t.meta['comments'] == ['comment 1', 'comment 2'] assert len(t) == 0 assert t.colnames == ['col1', 'col2'] @pytest.mark.parametrize('fast_reader', [dict(use_fast_converter=True), dict(exponent_style='A')]) def test_conversion_fast(fast_reader): """ The reader should try to convert each column to ints. If this fails, the reader should try to convert to floats. Failing this, i.e. on parsing non-numeric input including isolated positive/negative signs, it should fall back to strings. """ text = """ A B C D E F G H 1 a 3 4 5 6 7 8 2. 1 9 -.1e1 10.0 8.7 6 -5.3e4 4 2 -12 .4 +.e1 - + six """ table = ascii.read(text, fast_reader=fast_reader) assert_equal(table['A'].dtype.kind, 'f') assert table['B'].dtype.kind in ('S', 'U') assert_equal(table['C'].dtype.kind, 'i') assert_equal(table['D'].dtype.kind, 'f') assert table['E'].dtype.kind in ('S', 'U') assert table['F'].dtype.kind in ('S', 'U') assert table['G'].dtype.kind in ('S', 'U') assert table['H'].dtype.kind in ('S', 'U') @pytest.mark.parametrize('delimiter', ['\n', '\r']) @pytest.mark.parametrize('fast_reader', [False, True, 'force']) def test_newline_as_delimiter(delimiter, fast_reader): """ Check that newline characters are correctly handled as delimiters. Tests the fix for #9928. """ if delimiter == '\r': eol = '\n' else: eol = '\r' inp0 = ["a | b | c ", " 1 | '2' | 3.00000 "] inp1 = "a {0:s} b {0:s}c{1:s} 1 {0:s}'2'{0:s} 3.0".format(delimiter, eol) inp2 = [f"a {delimiter} b{delimiter} c", f"1{delimiter} '2' {delimiter} 3.0"] t0 = ascii.read(inp0, delimiter='|', fast_reader=fast_reader) t1 = ascii.read(inp1, delimiter=delimiter, fast_reader=fast_reader) t2 = ascii.read(inp2, delimiter=delimiter, fast_reader=fast_reader) assert t1.colnames == t2.colnames == ['a', 'b', 'c'] assert len(t1) == len(t2) == 1 assert t1['b'].dtype.kind in ('S', 'U') assert t2['b'].dtype.kind in ('S', 'U') assert_table_equal(t1, t0) assert_table_equal(t2, t0) inp0 = 'a {0:s} b {0:s} c{1:s} 1 {0:s}"2"{0:s} 3.0'.format('|', eol) inp1 = 'a {0:s} b {0:s} c{1:s} 1 {0:s}"2"{0:s} 3.0'.format(delimiter, eol) t0 = ascii.read(inp0, delimiter='|', fast_reader=fast_reader) t1 = ascii.read(inp1, delimiter=delimiter, fast_reader=fast_reader) if not fast_reader: pytest.xfail("Quoted fields are not parsed correctly by BaseSplitter") assert_equal(t1['b'].dtype.kind, 'i') @pytest.mark.parametrize('delimiter', [' ', '|', '\n', '\r']) @pytest.mark.parametrize('fast_reader', [False, True, 'force']) def test_single_line_string(delimiter, fast_reader): """ String input without a newline character is interpreted as filename, unless element of an iterable. Maybe not logical, but test that it is at least treated consistently. """ expected = Table([[1], [2], [3.00]], names=('col1', 'col2', 'col3')) text = "1{0:s}2{0:s}3.0".format(delimiter) if delimiter in ('\r', '\n'): t1 = ascii.read(text, format='no_header', delimiter=delimiter, fast_reader=fast_reader) assert_table_equal(t1, expected) else: # Windows raises OSError, but not the other OSes. with pytest.raises((FileNotFoundError, OSError)): t1 = ascii.read(text, format='no_header', delimiter=delimiter, fast_reader=fast_reader) t2 = ascii.read([text], format='no_header', delimiter=delimiter, fast_reader=fast_reader) assert_table_equal(t2, expected) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/test_cds.py0000644000175100001710000006534400000000000021005 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This module tests some methods related to ``CDS`` format reader/writer. Requires `pyyaml `_ to be installed. """ import numpy as np import pytest from io import StringIO from astropy.io import ascii from astropy import units as u from astropy.table import Table from astropy.table import Column, MaskedColumn from astropy.coordinates import SkyCoord from astropy.time import Time from astropy.utils.data import get_pkg_data_filename from astropy.utils.exceptions import AstropyWarning from .common import assert_almost_equal test_dat = ['names e d s i', 'HD81809 1E-7 22.25608 +2 67', 'HD103095 -31.6e5 +27.2500 -9E34 -30'] def test_roundtrip_mrt_table(): """ Tests whether or not the CDS writer can roundtrip a table, i.e. read a table to ``Table`` object and write it exactly as it is back to a file. Since, presently CDS uses a MRT format template while writing, only the Byte-By-Byte and the data section of the table can be compared between original and the newly written table. Further, the CDS Reader does not have capability to recognize column format from the header of a CDS/MRT table, so this test can work for a limited set of simple tables, which don't have whitespaces in the column values or mix-in columns. Because of this the written table output cannot be directly matched with the original file and have to be checked against a list of lines. Masked columns are read properly though, and thus are being tested during round-tripping. The difference between ``cdsFunctional2.dat`` file and ``exp_output`` is the following: * Metadata is different because MRT template is used for writing. * Spacing between ``Label`` and ``Explanations`` column in the Byte-By-Byte. * Units are written as ``[cm.s-2]`` and not ``[cm/s2]``, since both are valid according to CDS/MRT standard. """ exp_output = [ '================================================================================', 'Byte-by-byte Description of file: table.dat', '--------------------------------------------------------------------------------', ' Bytes Format Units Label Explanations', '--------------------------------------------------------------------------------', ' 1- 7 A7 --- ID Star ID ', ' 9-12 I4 K Teff [4337/4654] Effective temperature ', '14-17 F4.2 [cm.s-2] logg [0.77/1.28] Surface gravity ', '19-22 F4.2 km.s-1 vturb [1.23/1.82] Micro-turbulence velocity', '24-28 F5.2 [-] [Fe/H] [-2.11/-1.5] Metallicity ', '30-33 F4.2 [-] e_[Fe/H] ? rms uncertainty on [Fe/H] ', '--------------------------------------------------------------------------------', 'Notes:', '--------------------------------------------------------------------------------', 'S05-5 4337 0.77 1.80 -2.07 ', 'S08-229 4625 1.23 1.23 -1.50 ', 'S05-10 4342 0.91 1.82 -2.11 0.14', 'S05-47 4654 1.28 1.74 -1.64 0.16'] dat = get_pkg_data_filename('data/cdsFunctional2.dat', package='astropy.io.ascii.tests') t = Table.read(dat, format='ascii.mrt') out = StringIO() t.write(out, format='ascii.mrt') lines = out.getvalue().splitlines() i_bbb = lines.index('=' * 80) lines = lines[i_bbb:] # Select Byte-By-Byte section and later lines. assert lines == exp_output def test_write_byte_by_byte_units(): t = ascii.read(test_dat) col_units = [None, u.C, u.kg, u.m / u.s, u.year] t._set_column_attribute('unit', col_units) # Add a column with magnitude units. # Note that magnitude has to be assigned for each value explicitly. t['magnitude'] = [u.Magnitude(25), u.Magnitude(-9)] col_units.append(u.mag) out = StringIO() t.write(out, format='ascii.mrt') # Read written table. tRead = ascii.read(out.getvalue(), format='cds') assert [tRead[col].unit for col in tRead.columns] == col_units def test_write_readme_with_default_options(): exp_output = [ 'Title:', 'Authors:', 'Table:', '================================================================================', 'Byte-by-byte Description of file: table.dat', '--------------------------------------------------------------------------------', ' Bytes Format Units Label Explanations', '--------------------------------------------------------------------------------', ' 1- 8 A8 --- names Description of names ', '10-14 E5.1 --- e [-3160000.0/0.01] Description of e', '16-23 F8.5 --- d [22.25/27.25] Description of d ', '25-31 E7.1 --- s [-9e+34/2.0] Description of s ', '33-35 I3 --- i [-30/67] Description of i ', '--------------------------------------------------------------------------------', 'Notes:', '--------------------------------------------------------------------------------', 'HD81809 1e-07 22.25608 2e+00 67', 'HD103095 -3e+06 27.25000 -9e+34 -30'] t = ascii.read(test_dat) out = StringIO() t.write(out, format='ascii.mrt') assert out.getvalue().splitlines() == exp_output def test_write_empty_table(): out = StringIO() import pytest with pytest.raises(NotImplementedError): Table().write(out, format='ascii.mrt') def test_write_null_data_values(): exp_output = ['HD81809 1e-07 22.25608 2.0e+00 67', 'HD103095 -3e+06 27.25000 -9.0e+34 -30', 'Sun 5.3e+27 '] t = ascii.read(test_dat) t.add_row(['Sun', '3.25', '0', '5.3e27', '2'], mask=[False, True, True, False, True]) out = StringIO() t.write(out, format='ascii.mrt') lines = out.getvalue().splitlines() i_secs = [i for i, s in enumerate(lines) if s.startswith(('------', '======='))] lines = lines[i_secs[-1] + 1:] # Last section is the data. assert lines == exp_output def test_write_byte_by_byte_for_masked_column(): """ This test differs from the ``test_write_null_data_values`` above in that it tests the column value limits in the Byte-By-Byte description section for columns whose values are masked. It also checks the description for columns with same values. """ exp_output = [ '================================================================================', 'Byte-by-byte Description of file: table.dat', '--------------------------------------------------------------------------------', ' Bytes Format Units Label Explanations', '--------------------------------------------------------------------------------', ' 1- 8 A8 --- names Description of names ', '10-14 E5.1 --- e [0.0/0.01]? Description of e ', '16-17 F2.0 --- d ? Description of d ', '19-25 E7.1 --- s [-9e+34/2.0] Description of s ', '27-29 I3 --- i [-30/67] Description of i ', '31-33 F3.1 --- sameF [5.0/5.0] Description of sameF', '35-36 I2 --- sameI [20] Description of sameI ', '--------------------------------------------------------------------------------', 'Notes:', '--------------------------------------------------------------------------------', 'HD81809 1e-07 2e+00 67 5.0 20', 'HD103095 -9e+34 -30 5.0 20'] t = ascii.read(test_dat) t.add_column([5.0, 5.0], name='sameF') t.add_column([20, 20], name='sameI') t['e'] = MaskedColumn(t['e'], mask=[False, True]) t['d'] = MaskedColumn(t['d'], mask=[True, True]) out = StringIO() t.write(out, format='ascii.mrt') lines = out.getvalue().splitlines() i_bbb = lines.index('=' * 80) lines = lines[i_bbb:] # Select Byte-By-Byte section and later lines. assert lines == exp_output exp_coord_cols_output = dict(generic=[ '================================================================================', 'Byte-by-byte Description of file: table.dat', '--------------------------------------------------------------------------------', ' Bytes Format Units Label Explanations', '--------------------------------------------------------------------------------', ' 1- 8 A8 --- names Description of names ', '10-14 E5.1 --- e [-3160000.0/0.01] Description of e', '16-23 F8.5 --- d [22.25/27.25] Description of d ', '25-31 E7.1 --- s [-9e+34/2.0] Description of s ', '33-35 I3 --- i [-30/67] Description of i ', '37-39 F3.1 --- sameF [5.0/5.0] Description of sameF ', '41-42 I2 --- sameI [20] Description of sameI ', '44-45 I2 h RAh Right Ascension (hour) ', '47-48 I2 min RAm Right Ascension (minute) ', '50-62 F13.10 s RAs Right Ascension (second) ', ' 64 A1 --- DE- Sign of Declination ', '65-66 I2 deg DEd Declination (degree) ', '68-69 I2 arcmin DEm Declination (arcmin) ', '71-82 F12.9 arcsec DEs Declination (arcsec) ', '--------------------------------------------------------------------------------', 'Notes:', '--------------------------------------------------------------------------------', 'HD81809 1e-07 22.25608 2e+00 67 5.0 20 22 02 15.4500000000 -61 39 34.599996000', 'HD103095 -3e+06 27.25000 -9e+34 -30 5.0 20 12 48 15.2244072000 +17 46 26.496624000'], positive_de=[ '================================================================================', 'Byte-by-byte Description of file: table.dat', '--------------------------------------------------------------------------------', ' Bytes Format Units Label Explanations', '--------------------------------------------------------------------------------', ' 1- 8 A8 --- names Description of names ', '10-14 E5.1 --- e [-3160000.0/0.01] Description of e', '16-23 F8.5 --- d [22.25/27.25] Description of d ', '25-31 E7.1 --- s [-9e+34/2.0] Description of s ', '33-35 I3 --- i [-30/67] Description of i ', '37-39 F3.1 --- sameF [5.0/5.0] Description of sameF ', '41-42 I2 --- sameI [20] Description of sameI ', '44-45 I2 h RAh Right Ascension (hour) ', '47-48 I2 min RAm Right Ascension (minute) ', '50-62 F13.10 s RAs Right Ascension (second) ', ' 64 A1 --- DE- Sign of Declination ', '65-66 I2 deg DEd Declination (degree) ', '68-69 I2 arcmin DEm Declination (arcmin) ', '71-82 F12.9 arcsec DEs Declination (arcsec) ', '--------------------------------------------------------------------------------', 'Notes:', '--------------------------------------------------------------------------------', 'HD81809 1e-07 22.25608 2e+00 67 5.0 20 12 48 15.2244072000 +17 46 26.496624000', 'HD103095 -3e+06 27.25000 -9e+34 -30 5.0 20 12 48 15.2244072000 +17 46 26.496624000'], galactic=[ '================================================================================', 'Byte-by-byte Description of file: table.dat', '--------------------------------------------------------------------------------', ' Bytes Format Units Label Explanations', '--------------------------------------------------------------------------------', ' 1- 8 A8 --- names Description of names ', '10-14 E5.1 --- e [-3160000.0/0.01] Description of e', '16-23 F8.5 --- d [22.25/27.25] Description of d ', '25-31 E7.1 --- s [-9e+34/2.0] Description of s ', '33-35 I3 --- i [-30/67] Description of i ', '37-39 F3.1 --- sameF [5.0/5.0] Description of sameF ', '41-42 I2 --- sameI [20] Description of sameI ', '44-59 F16.12 deg GLON Galactic Longitude ', '61-76 F16.12 deg GLAT Galactic Latitude ', '--------------------------------------------------------------------------------', 'Notes:', '--------------------------------------------------------------------------------', 'HD81809 1e-07 22.25608 2e+00 67 5.0 20 330.071639591690 -45.548080484609', 'HD103095 -3e+06 27.25000 -9e+34 -30 5.0 20 330.071639591690 -45.548080484609'], ecliptic=[ '================================================================================', 'Byte-by-byte Description of file: table.dat', '--------------------------------------------------------------------------------', ' Bytes Format Units Label Explanations', '--------------------------------------------------------------------------------', ' 1- 8 A8 --- names Description of names ', '10-14 E5.1 --- e [-3160000.0/0.01] Description of e ', '16-23 F8.5 --- d [22.25/27.25] Description of d ', '25-31 E7.1 --- s [-9e+34/2.0] Description of s ', '33-35 I3 --- i [-30/67] Description of i ', '37-39 F3.1 --- sameF [5.0/5.0] Description of sameF ', '41-42 I2 --- sameI [20] Description of sameI ', '44-59 F16.12 deg ELON Ecliptic Longitude (geocentrictrueecliptic)', '61-76 F16.12 deg ELAT Ecliptic Latitude (geocentrictrueecliptic) ', '--------------------------------------------------------------------------------', 'Notes:', '--------------------------------------------------------------------------------', 'HD81809 1e-07 22.25608 2e+00 67 5.0 20 306.224208650096 -45.621789850825', 'HD103095 -3e+06 27.25000 -9e+34 -30 5.0 20 306.224208650096 -45.621789850825'], ) def test_write_coord_cols(): """ There can only be one such coordinate column in a single table, because division of columns into individual component columns requires iterating over the table columns, which will have to be done again if additional such coordinate columns are present. """ t = ascii.read(test_dat) t.add_column([5.0, 5.0], name='sameF') t.add_column([20, 20], name='sameI') # Coordinates of ASASSN-15lh coord = SkyCoord(330.564375, -61.65961111, unit=u.deg) # Coordinates of ASASSN-14li coordp = SkyCoord(192.06343503, 17.77402684, unit=u.deg) cols = [Column([coord, coordp]), # Generic coordinate column coordp, # Coordinate column with positive DEC coord.galactic, # Galactic coordinates coord.geocentrictrueecliptic # Ecliptic coordinates ] # Loop through different types of coordinate columns. for col, coord_type in zip(cols, exp_coord_cols_output): exp_output = exp_coord_cols_output[coord_type] t['coord'] = col out = StringIO() t.write(out, format='ascii.mrt') lines = out.getvalue().splitlines() i_bbb = lines.index('=' * 80) lines = lines[i_bbb:] # Select Byte-By-Byte section and later lines. # Check the written table. assert lines == exp_output # Check if the original table columns remains unmodified. assert t.colnames == ['names', 'e', 'd', 's', 'i', 'sameF', 'sameI', 'coord'] def test_write_byte_by_byte_bytes_col_format(): """ Tests the alignment of Byte counts with respect to hyphen in the Bytes column of Byte-By-Byte. The whitespace around the hyphen is govered by the number of digits in the total Byte count. Single Byte columns should have a single Byte count without the hyphen. """ exp_output = [ '================================================================================', 'Byte-by-byte Description of file: table.dat', '--------------------------------------------------------------------------------', ' Bytes Format Units Label Explanations', '--------------------------------------------------------------------------------', ' 1- 8 A8 --- names Description of names ', '10-21 E12.6 --- e [-3160000.0/0.01] Description of e', '23-30 F8.5 --- d [22.25/27.25] Description of d ', '32-38 E7.1 --- s [-9e+34/2.0] Description of s ', '40-42 I3 --- i [-30/67] Description of i ', '44-46 F3.1 --- sameF [5.0/5.0] Description of sameF ', '48-49 I2 --- sameI [20] Description of sameI ', ' 51 I1 --- singleByteCol [2] Description of singleByteCol ', '53-54 I2 h RAh Right Ascension (hour) ', '56-57 I2 min RAm Right Ascension (minute) ', '59-71 F13.10 s RAs Right Ascension (second) ', ' 73 A1 --- DE- Sign of Declination ', '74-75 I2 deg DEd Declination (degree) ', '77-78 I2 arcmin DEm Declination (arcmin) ', '80-91 F12.9 arcsec DEs Declination (arcsec) ', '--------------------------------------------------------------------------------'] t = ascii.read(test_dat) t.add_column([5.0, 5.0], name='sameF') t.add_column([20, 20], name='sameI') t['coord'] = SkyCoord(330.564375, -61.65961111, unit=u.deg) t['singleByteCol'] = [2, 2] t['e'].format = '.5E' out = StringIO() t.write(out, format='ascii.mrt') lines = out.getvalue().splitlines() i_secs = [i for i, s in enumerate(lines) if s.startswith(('------', '======='))] # Select only the Byte-By-Byte section. lines = lines[i_secs[0]:i_secs[-2]] lines.append('-' * 80) # Append a separator line. assert lines == exp_output def test_write_byte_by_byte_wrapping(): """ Test line wrapping in the description column of the Byte-By-Byte section of the ReadMe. """ exp_output = '''\ ================================================================================ Byte-by-byte Description of file: table.dat -------------------------------------------------------------------------------- Bytes Format Units Label Explanations -------------------------------------------------------------------------------- 1- 8 A8 --- thisIsALongColumnLabel This is a tediously long description. But they do sometimes have them. Better to put extra details in the notes. This is a tediously long description. But they do sometimes have them. Better to put extra details in the notes. 10-14 E5.1 --- e [-3160000.0/0.01] Description of e 16-23 F8.5 --- d [22.25/27.25] Description of d -------------------------------------------------------------------------------- ''' # noqa: W291 t = ascii.read(test_dat) t.remove_columns(['s', 'i']) description = 'This is a tediously long description.' \ + ' But they do sometimes have them.' \ + ' Better to put extra details in the notes. ' t['names'].description = description * 2 t['names'].name = 'thisIsALongColumnLabel' out = StringIO() t.write(out, format='ascii.mrt') lines = out.getvalue().splitlines() i_secs = [i for i, s in enumerate(lines) if s.startswith(('------', '======='))] # Select only the Byte-By-Byte section. lines = lines[i_secs[0]:i_secs[-2]] lines.append('-' * 80) # Append a separator line. assert lines == exp_output.splitlines() def test_write_mixin_and_broken_cols(): """ Tests convertion to string values for ``mix-in`` columns other than ``SkyCoord`` and for columns with only partial ``SkyCoord`` values. """ exp_output = [ '================================================================================', 'Byte-by-byte Description of file: table.dat', # noqa '--------------------------------------------------------------------------------', # noqa ' Bytes Format Units Label Explanations', # noqa '--------------------------------------------------------------------------------', # noqa ' 1- 7 A7 --- name Description of name ', # noqa ' 9- 74 A66 --- Unknown Description of Unknown', # noqa ' 76-114 A39 --- Unknown Description of Unknown', # noqa '116-138 A23 --- Unknown Description of Unknown', # noqa '--------------------------------------------------------------------------------', # noqa 'Notes:', # noqa '--------------------------------------------------------------------------------', # noqa 'HD81809 (0.41342785, -0.23329341, -0.88014294) 2019-01-01 00:00:00.000', # noqa 'random 12 (0.41342785, -0.23329341, -0.88014294) 2019-01-01 00:00:00.000'] # noqa t = Table() t['name'] = ['HD81809'] coord = SkyCoord(330.564375, -61.65961111, unit=u.deg) t['coord'] = Column(coord) t.add_row(['random', 12]) t['cart'] = coord.cartesian t['time'] = Time('2019-1-1') out = StringIO() t.write(out, format='ascii.mrt') lines = out.getvalue().splitlines() i_bbb = lines.index('=' * 80) lines = lines[i_bbb:] # Select Byte-By-Byte section and later lines. # Check the written table. assert lines == exp_output def test_write_extra_skycoord_cols(): """ Tests output for cases when table contains multiple ``SkyCoord`` columns. """ exp_output = '''\ ================================================================================ Byte-by-byte Description of file: table.dat -------------------------------------------------------------------------------- Bytes Format Units Label Explanations -------------------------------------------------------------------------------- 1- 7 A7 --- name Description of name 9-10 I2 h RAh Right Ascension (hour) 12-13 I2 min RAm Right Ascension (minute) 15-27 F13.10 s RAs Right Ascension (second) 29 A1 --- DE- Sign of Declination 30-31 I2 deg DEd Declination (degree) 33-34 I2 arcmin DEm Declination (arcmin) 36-47 F12.9 arcsec DEs Declination (arcsec) 49-62 A14 --- coord2 Description of coord2 -------------------------------------------------------------------------------- Notes: -------------------------------------------------------------------------------- HD4760 0 49 39.9000000000 +06 24 07.999200000 12.4163 6.407 HD81809 22 02 15.4500000000 -61 39 34.599996000 330.564 -61.66 ''' # noqa: W291 t = Table() t['name'] = ['HD4760', 'HD81809'] t['coord1'] = SkyCoord([12.41625, 330.564375], [6.402222, -61.65961111], unit=u.deg) t['coord2'] = SkyCoord([12.41630, 330.564400], [6.407, -61.66], unit=u.deg) out = StringIO() with pytest.warns(UserWarning, match=r'column 2 is being skipped with designation of a ' r'string valued column `coord2`'): t.write(out, format='ascii.mrt') lines = out.getvalue().splitlines() i_bbb = lines.index('=' * 80) lines = lines[i_bbb:] # Select Byte-By-Byte section and following lines. # Check the written table. assert lines[:-2] == exp_output.splitlines()[:-2] for a, b in zip(lines[-2:], exp_output.splitlines()[-2:]): assert a[:18] == b[:18] assert a[30:42] == b[30:42] assert_almost_equal(np.fromstring(a[2:], sep=' '), np.fromstring(b[2:], sep=' ')) def test_write_skycoord_with_format(): """ Tests output with custom setting for ``SkyCoord`` (second) columns. """ exp_output = '''\ ================================================================================ Byte-by-byte Description of file: table.dat -------------------------------------------------------------------------------- Bytes Format Units Label Explanations -------------------------------------------------------------------------------- 1- 7 A7 --- name Description of name 9-10 I2 h RAh Right Ascension (hour) 12-13 I2 min RAm Right Ascension (minute) 15-19 F5.2 s RAs Right Ascension (second) 21 A1 --- DE- Sign of Declination 22-23 I2 deg DEd Declination (degree) 25-26 I2 arcmin DEm Declination (arcmin) 28-31 F4.1 arcsec DEs Declination (arcsec) -------------------------------------------------------------------------------- Notes: -------------------------------------------------------------------------------- HD4760 0 49 39.90 +06 24 08.0 HD81809 22 02 15.45 -61 39 34.6 ''' # noqa: W291 t = Table() t['name'] = ['HD4760', 'HD81809'] t['coord'] = SkyCoord([12.41625, 330.564375], [6.402222, -61.65961111], unit=u.deg) out = StringIO() # This will raise a warning because `formats` is checked before the writer creating the # final list of columns is called. with pytest.warns(AstropyWarning, match=r"The key.s. {'[RD][AE]s', '[RD][AE]s'} specified in " r"the formats argument do not match a column name."): t.write(out, format='ascii.mrt', formats={'RAs': '05.2f', 'DEs': '04.1f'}) lines = out.getvalue().splitlines() i_bbb = lines.index('=' * 80) lines = lines[i_bbb:] # Select Byte-By-Byte section and following lines. # Check the written table. assert lines == exp_output.splitlines() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/test_cds_header_from_readme.py0000644000175100001710000001677000000000000024654 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import pytest import numpy as np from astropy.io import ascii from .common import (assert_equal, assert_almost_equal, # noqa setup_function, teardown_function) # noqa from astropy import units as u def read_table1(readme, data): reader = ascii.Cds(readme) return reader.read(data) def read_table2(readme, data): reader = ascii.get_reader(Reader=ascii.Cds, readme=readme) reader.outputter = ascii.TableOutputter() return reader.read(data) def read_table3(readme, data): return ascii.read(data, readme=readme) def test_description(): readme = 'data/cds/description/ReadMe' data = 'data/cds/description/table.dat' for read_table in (read_table1, read_table2, read_table3): table = read_table(readme, data) assert_equal(len(table), 2) assert_equal(table['Cluster'].description, 'Cluster name') assert_equal(table['Star'].description, '') assert_equal(table['Wave'].description, 'wave? Wavelength in Angstroms') assert_equal(table['El'].description, 'a') assert_equal(table['ion'].description, '- Ionization stage (1 for neutral element)') assert_equal(table['EW'].description, 'Equivalent width (in mA)') assert_equal(table['Q'].description, 'DAOSPEC quality parameter Q(large values are bad)') def test_multi_header(): readme = 'data/cds/multi/ReadMe' data = 'data/cds/multi/lhs2065.dat' for read_table in (read_table1, read_table2, read_table3): table = read_table(readme, data) assert_equal(len(table), 18) assert_almost_equal(table['Lambda'][-1], 6479.32) assert_equal(table['Fnu'][-1], '0.285937') data = 'data/cds/multi/lp944-20.dat' for read_table in (read_table1, read_table2, read_table3): table = read_table(readme, data) assert_equal(len(table), 18) assert_almost_equal(table['Lambda'][0], 6476.09) assert_equal(table['Fnu'][-1], '0.489005') def test_glob_header(): readme = 'data/cds/glob/ReadMe' data = 'data/cds/glob/lmxbrefs.dat' for read_table in (read_table1, read_table2, read_table3): table = read_table(readme, data) assert_equal(len(table), 291) assert_equal(table['Name'][-1], 'J1914+0953') assert_equal(table['BibCode'][-2], '2005A&A...432..235R') def test_header_from_readme(): r = ascii.Cds("data/vizier/ReadMe") table = r.read("data/vizier/table1.dat") assert len(r.data.data_lines) == 15 assert len(table) == 15 assert len(table.keys()) == 18 Bmag = [14.79, 15.00, 14.80, 12.38, 12.36, 12.24, 13.75, 13.65, 13.41, 11.59, 11.68, 11.53, 13.92, 14.03, 14.18] for i, val in enumerate(table.field('Bmag')): assert val == Bmag[i] table = r.read("data/vizier/table5.dat") assert len(r.data.data_lines) == 49 assert len(table) == 49 assert len(table.keys()) == 10 Q = [0.289, 0.325, 0.510, 0.577, 0.539, 0.390, 0.957, 0.736, 1.435, 1.117, 1.473, 0.808, 1.416, 2.209, 0.617, 1.046, 1.604, 1.419, 1.431, 1.183, 1.210, 1.005, 0.706, 0.665, 0.340, 0.323, 0.391, 0.280, 0.343, 0.369, 0.495, 0.828, 1.113, 0.499, 1.038, 0.260, 0.863, 1.638, 0.479, 0.232, 0.627, 0.671, 0.371, 0.851, 0.607, -9.999, 1.958, 1.416, 0.949] for i, val in enumerate(table.field('Q')): if val is np.ma.masked: # text value for a missing value in that table assert Q[i] == -9.999 else: assert val == Q[i] @pytest.mark.parametrize('reader_cls', (ascii.Cds, ascii.Mrt)) def test_cds_units(reader_cls): from astropy import units data_and_readme = 'data/cds.dat' reader = ascii.get_reader(reader_cls) table = reader.read(data_and_readme) # column unit is GMsun (giga solar masses) # make sure this is parsed correctly, not as a "string" unit assert table['Fit'].to(units.solMass).unit == units.solMass @pytest.mark.parametrize('reader_cls', (ascii.Cds, ascii.Mrt)) def test_cds_function_units(reader_cls): data_and_readme = 'data/cdsFunctional.dat' reader = ascii.get_reader(reader_cls) table = reader.read(data_and_readme) assert table['logg'].unit == u.dex(u.cm/u.s**2) assert table['logTe'].unit == u.dex(u.K) assert table['Mass'].unit == u.Msun assert table['e_Mass'].unit == u.Msun assert table['Age'].unit == u.Myr assert table['e_Age'].unit == u.Myr @pytest.mark.parametrize('reader_cls', (ascii.Cds, ascii.Mrt)) def test_cds_function_units2(reader_cls): # This one includes some dimensionless dex. data_and_readme = 'data/cdsFunctional2.dat' reader = ascii.get_reader(reader_cls) table = reader.read(data_and_readme) assert table['Teff'].unit == u.K assert table['logg'].unit == u.dex(u.cm/u.s**2) assert table['vturb'].unit == u.km/u.s assert table['[Fe/H]'].unit == u.dex(u.one) assert table['e_[Fe/H]'].unit == u.dex(u.one) assert_almost_equal(table['[Fe/H]'].to(u.one), 10.**(np.array([-2.07, -1.50, -2.11, -1.64]))) def test_cds_ignore_nullable(): # Make sure CDS Reader does not ignore nullabilty for columns # with a limit specifier readme = 'data/cds/null/ReadMe' data = 'data/cds/null/table.dat' r = ascii.Cds(readme) r.read(data) assert_equal(r.header.cols[6].description, 'Temperature class codified (10)') assert_equal(r.header.cols[8].description, 'Luminosity class codified (11)') assert_equal(r.header.cols[5].description, 'Pericenter position angle (18)') def test_cds_no_whitespace(): # Make sure CDS Reader only checks null values when an '=' symbol is present, # and read description text even if there is no whitespace after '?'. readme = 'data/cds/null/ReadMe1' data = 'data/cds/null/table.dat' r = ascii.Cds(readme) r.read(data) assert_equal(r.header.cols[6].description, 'Temperature class codified (10)') assert_equal(r.header.cols[6].null, '') assert_equal(r.header.cols[7].description, 'Equivalent width (in mA)') assert_equal(r.header.cols[7].null, '-9.9') assert_equal(r.header.cols[10].description, 'DAOSPEC quality parameter Q(large values are bad)') assert_equal(r.header.cols[10].null, '-9.999') def test_cds_order(): # Make sure CDS Reader does not ignore order specifier that maybe present after # the null specifier '?' readme = 'data/cds/null/ReadMe1' data = 'data/cds/null/table.dat' r = ascii.Cds(readme) r.read(data) assert_equal(r.header.cols[5].description, 'Catalogue Identification Number') assert_equal(r.header.cols[8].description, 'Equivalent width (in mA)') assert_equal(r.header.cols[9].description, 'Luminosity class codified (11)') if __name__ == "__main__": # run from main directory; not from test/ test_header_from_readme() test_multi_header() test_glob_header() test_description() test_cds_units() test_cds_ignore_nullable() test_cds_no_whitespace() test_cds_order() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/test_compressed.py0000644000175100001710000000270100000000000022364 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import pytest import numpy as np from astropy.io.ascii import read from astropy.utils.data import get_pkg_data_filename # NOTE: Python can be built without bz2 or lzma from astropy.utils.compat.optional_deps import HAS_BZ2, HAS_LZMA # noqa @pytest.mark.parametrize('filename', ['data/daophot.dat.gz', 'data/latex1.tex.gz', 'data/short.rdb.gz']) def test_gzip(filename): t_comp = read(get_pkg_data_filename(filename)) t_uncomp = read(get_pkg_data_filename(filename.replace('.gz', ''))) assert t_comp.dtype.names == t_uncomp.dtype.names assert np.all(t_comp.as_array() == t_uncomp.as_array()) @pytest.mark.xfail('not HAS_BZ2') @pytest.mark.parametrize('filename', ['data/short.rdb.bz2', 'data/ipac.dat.bz2']) def test_bzip2(filename): t_comp = read(get_pkg_data_filename(filename)) t_uncomp = read(get_pkg_data_filename(filename.replace('.bz2', ''))) assert t_comp.dtype.names == t_uncomp.dtype.names assert np.all(t_comp.as_array() == t_uncomp.as_array()) @pytest.mark.xfail('not HAS_LZMA') @pytest.mark.parametrize('filename', ['data/short.rdb.xz', 'data/ipac.dat.xz']) def test_xz(filename): t_comp = read(get_pkg_data_filename(filename)) t_uncomp = read(get_pkg_data_filename(filename.replace('.xz', ''))) assert t_comp.dtype.names == t_uncomp.dtype.names assert np.all(t_comp.as_array() == t_uncomp.as_array()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/test_connect.py0000644000175100001710000000730500000000000021656 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import pytest from astropy.table import Table, Column from astropy.table.table_helpers import simple_table from astropy.utils.data import get_pkg_data_filename from astropy.utils.compat.optional_deps import HAS_BS4 # noqa import numpy as np files = ['data/cds.dat', 'data/ipac.dat', 'data/daophot.dat', 'data/latex1.tex', 'data/simple_csv.csv'] if HAS_BS4: files.append('data/html.html') @pytest.mark.parametrize('filename', files) def test_read_generic(filename): Table.read(get_pkg_data_filename(filename), format='ascii') def test_write_generic(tmpdir): t = Table() t.add_column(Column(name='a', data=[1, 2, 3])) t.add_column(Column(name='b', data=['a', 'b', 'c'])) t.write(str(tmpdir.join("test")), format='ascii') def test_read_ipac(): Table.read(get_pkg_data_filename('data/ipac.dat'), format='ipac') def test_read_cds(): Table.read(get_pkg_data_filename('data/cds.dat'), format='cds') def test_read_dapphot(): Table.read(get_pkg_data_filename('data/daophot.dat'), format='daophot') def test_read_latex(): Table.read(get_pkg_data_filename('data/latex1.tex'), format='latex') def test_read_latex_noformat(): Table.read(get_pkg_data_filename('data/latex1.tex')) def test_write_latex(tmpdir): t = Table() t.add_column(Column(name='a', data=[1, 2, 3])) t.add_column(Column(name='b', data=['a', 'b', 'c'])) path = str(tmpdir.join("data.tex")) t.write(path, format='latex') def test_write_latex_noformat(tmpdir): t = Table() t.add_column(Column(name='a', data=[1, 2, 3])) t.add_column(Column(name='b', data=['a', 'b', 'c'])) path = str(tmpdir.join("data.tex")) t.write(path) @pytest.mark.skipif('not HAS_BS4') def test_read_html(): Table.read(get_pkg_data_filename('data/html.html'), format='html') @pytest.mark.skipif('not HAS_BS4') def test_read_html_noformat(): Table.read(get_pkg_data_filename('data/html.html')) def test_write_html(tmpdir): t = Table() t.add_column(Column(name='a', data=[1, 2, 3])) t.add_column(Column(name='b', data=['a', 'b', 'c'])) path = str(tmpdir.join("data.html")) t.write(path, format='html') def test_write_html_noformat(tmpdir): t = Table() t.add_column(Column(name='a', data=[1, 2, 3])) t.add_column(Column(name='b', data=['a', 'b', 'c'])) path = str(tmpdir.join("data.html")) t.write(path) def test_read_rdb(): Table.read(get_pkg_data_filename('data/short.rdb'), format='rdb') def test_read_rdb_noformat(): Table.read(get_pkg_data_filename('data/short.rdb')) def test_write_rdb(tmpdir): t = Table() t.add_column(Column(name='a', data=[1, 2, 3])) t.add_column(Column(name='b', data=['a', 'b', 'c'])) path = str(tmpdir.join("data.rdb")) t.write(path, format='rdb') def test_write_rdb_noformat(tmpdir): t = Table() t.add_column(Column(name='a', data=[1, 2, 3])) t.add_column(Column(name='b', data=['a', 'b', 'c'])) path = str(tmpdir.join("data.rdb")) t.write(path) def test_read_csv(): '''If properly registered, filename should be sufficient to specify format #3189 ''' Table.read(get_pkg_data_filename('data/simple_csv.csv')) def test_write_csv(tmpdir): '''If properly registered, filename should be sufficient to specify format #3189 ''' t = Table() t.add_column(Column(name='a', data=[1, 2, 3])) t.add_column(Column(name='b', data=['a', 'b', 'c'])) path = str(tmpdir.join("data.csv")) t.write(path) def test_auto_identify_ecsv(tmpdir): tbl = simple_table() tmpfile = str(tmpdir.join('/tmpFile.ecsv')) tbl.write(tmpfile) tbl2 = Table.read(tmpfile) assert np.all(tbl == tbl2) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/test_ecsv.py0000644000175100001710000010660700000000000021172 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This module tests some of the methods related to the ``ECSV`` reader/writer. """ from astropy.table.column import MaskedColumn import os import copy import sys from io import StringIO from contextlib import nullcontext import pytest import numpy as np import yaml from astropy.table import Table, Column, QTable, NdarrayMixin from astropy.table.table_helpers import simple_table from astropy.coordinates import (SkyCoord, Latitude, Longitude, Angle, EarthLocation, SphericalRepresentation, CartesianRepresentation, SphericalCosLatDifferential) from astropy.time import Time, TimeDelta from astropy.units import allclose as quantity_allclose from astropy.units import QuantityInfo from astropy.utils.exceptions import AstropyUserWarning from astropy.utils.compat import NUMPY_LT_1_19_1 from astropy.io.ascii.ecsv import DELIMITERS from astropy.io import ascii from astropy import units as u from .common import TEST_DIR DTYPES = ['bool', 'int8', 'int16', 'int32', 'int64', 'uint8', 'uint16', 'uint32', 'uint64', 'float16', 'float32', 'float64', 'float128', 'str'] if not hasattr(np, 'float128') or os.name == 'nt' or sys.maxsize <= 2**32: DTYPES.remove('float128') T_DTYPES = Table() for dtype in DTYPES: if dtype == 'bool': data = np.array([False, True, False]) elif dtype == 'str': data = np.array(['ab 0', 'ab, 1', 'ab2']) else: data = np.arange(3, dtype=dtype) c = Column(data, unit='m / s', description='descr_' + dtype, meta={'meta ' + dtype: 1}) T_DTYPES[dtype] = c T_DTYPES.meta['comments'] = ['comment1', 'comment2'] # Corresponds to simple_table() SIMPLE_LINES = ['# %ECSV 1.0', '# ---', '# datatype:', '# - {name: a, datatype: int64}', '# - {name: b, datatype: float64}', '# - {name: c, datatype: string}', '# schema: astropy-2.0', 'a b c', '1 1.0 c', '2 2.0 d', '3 3.0 e'] def test_write_simple(): """ Write a simple table with common types. This shows the compact version of serialization with one line per column. """ t = simple_table() out = StringIO() t.write(out, format='ascii.ecsv') assert out.getvalue().splitlines() == SIMPLE_LINES def test_write_full(): """ Write a full-featured table with common types and explicitly checkout output """ t = T_DTYPES['bool', 'int64', 'float64', 'str'] lines = ['# %ECSV 1.0', '# ---', '# datatype:', '# - name: bool', '# unit: m / s', '# datatype: bool', '# description: descr_bool', '# meta: {meta bool: 1}', '# - name: int64', '# unit: m / s', '# datatype: int64', '# description: descr_int64', '# meta: {meta int64: 1}', '# - name: float64', '# unit: m / s', '# datatype: float64', '# description: descr_float64', '# meta: {meta float64: 1}', '# - name: str', '# unit: m / s', '# datatype: string', '# description: descr_str', '# meta: {meta str: 1}', '# meta: !!omap', '# - comments: [comment1, comment2]', '# schema: astropy-2.0', 'bool int64 float64 str', 'False 0 0.0 "ab 0"', 'True 1 1.0 "ab, 1"', 'False 2 2.0 ab2'] out = StringIO() t.write(out, format='ascii.ecsv') assert out.getvalue().splitlines() == lines def test_write_read_roundtrip(): """ Write a full-featured table with all types and see that it round-trips on readback. Use both space and comma delimiters. """ t = T_DTYPES for delimiter in DELIMITERS: out = StringIO() t.write(out, format='ascii.ecsv', delimiter=delimiter) t2s = [Table.read(out.getvalue(), format='ascii.ecsv'), Table.read(out.getvalue(), format='ascii'), ascii.read(out.getvalue()), ascii.read(out.getvalue(), format='ecsv', guess=False), ascii.read(out.getvalue(), format='ecsv')] for t2 in t2s: assert t.meta == t2.meta for name in t.colnames: assert t[name].attrs_equal(t2[name]) assert np.all(t[name] == t2[name]) def test_bad_delimiter(): """ Passing a delimiter other than space or comma gives an exception """ out = StringIO() with pytest.raises(ValueError) as err: T_DTYPES.write(out, format='ascii.ecsv', delimiter='|') assert 'only space and comma are allowed' in str(err.value) def test_bad_header_start(): """ Bad header without initial # %ECSV x.x """ lines = copy.copy(SIMPLE_LINES) lines[0] = '# %ECV 0.9' with pytest.raises(ascii.InconsistentTableError): Table.read('\n'.join(lines), format='ascii.ecsv', guess=False) def test_bad_delimiter_input(): """ Illegal delimiter in input """ lines = copy.copy(SIMPLE_LINES) lines.insert(2, '# delimiter: |') with pytest.raises(ValueError) as err: Table.read('\n'.join(lines), format='ascii.ecsv', guess=False) assert 'only space and comma are allowed' in str(err.value) def test_multidim_input(): """ Multi-dimensional column in input """ t = Table() t['a'] = np.arange(24).reshape(2, 3, 4) t['a'].info.description = 'description' t['a'].info.meta = {1: 2} t['b'] = [1, 2] out = StringIO() t.write(out, format='ascii.ecsv') t2 = Table.read(out.getvalue(), format='ascii.ecsv') assert np.all(t2['a'] == t['a']) assert t2['a'].shape == t['a'].shape assert t2['a'].dtype == t['a'].dtype assert t2['a'].info.description == t['a'].info.description assert t2['a'].info.meta == t['a'].info.meta assert np.all(t2['b'] == t['b']) def test_round_trip_empty_table(): """Test fix in #5010 for issue #5009 (ECSV fails for empty type with bool type)""" t = Table(dtype=[bool, 'i', 'f'], names=['a', 'b', 'c']) out = StringIO() t.write(out, format='ascii.ecsv') t2 = Table.read(out.getvalue(), format='ascii.ecsv') assert t.dtype == t2.dtype assert len(t2) == 0 def test_csv_ecsv_colnames_mismatch(): """ Test that mismatch in column names from normal CSV header vs. ECSV YAML header raises the expected exception. """ lines = copy.copy(SIMPLE_LINES) header_index = lines.index('a b c') lines[header_index] = 'a b d' with pytest.raises(ValueError) as err: ascii.read(lines, format='ecsv') assert "column names from ECSV header ['a', 'b', 'c']" in str(err.value) def test_regression_5604(): """ See https://github.com/astropy/astropy/issues/5604 for more. """ t = Table() t.meta = {"foo": 5 * u.km, "foo2": u.s} t["bar"] = [7] * u.km out = StringIO() t.write(out, format="ascii.ecsv") assert '!astropy.units.Unit' in out.getvalue() assert '!astropy.units.Quantity' in out.getvalue() def assert_objects_equal(obj1, obj2, attrs, compare_class=True): if compare_class: assert obj1.__class__ is obj2.__class__ # For a column that is a native astropy Column, ignore the specified # `attrs`. This happens for a mixin like Quantity that is stored in a # `Table` (not QTable). if isinstance(obj1, Column): attrs = [] assert obj1.shape == obj2.shape info_attrs = ['info.name', 'info.format', 'info.unit', 'info.description'] for attr in attrs + info_attrs: a1 = obj1 a2 = obj2 for subattr in attr.split('.'): try: a1 = getattr(a1, subattr) a2 = getattr(a2, subattr) except AttributeError: a1 = a1[subattr] a2 = a2[subattr] if isinstance(a1, np.ndarray) and a1.dtype.kind == 'f': assert quantity_allclose(a1, a2, rtol=1e-10) else: assert np.all(a1 == a2) # For no attrs that means we just compare directly. if not attrs: if isinstance(obj1, np.ndarray) and obj1.dtype.kind == 'f': assert quantity_allclose(obj1, obj2, rtol=1e-15) else: assert np.all(obj1 == obj2) # TODO: unify with the very similar tests in fits/tests/test_connect.py # and misc/tests/test_hd5f.py. el = EarthLocation(x=[1, 2] * u.km, y=[3, 4] * u.km, z=[5, 6] * u.km) sr = SphericalRepresentation( [0, 1]*u.deg, [2, 3]*u.deg, 1*u.kpc) cr = CartesianRepresentation( [0, 1]*u.pc, [4, 5]*u.pc, [8, 6]*u.pc) sd = SphericalCosLatDifferential( [0, 1]*u.mas/u.yr, [0, 1]*u.mas/u.yr, 10*u.km/u.s) srd = SphericalRepresentation(sr, differentials=sd) sc = SkyCoord([1, 2], [3, 4], unit='deg,deg', frame='fk4', obstime='J1990.5') scd = SkyCoord([1, 2], [3, 4], [5, 6], unit='deg,deg,m', frame='fk4', obstime=['J1990.5'] * 2) scdc = scd.copy() scdc.representation_type = 'cartesian' scpm = SkyCoord([1, 2], [3, 4], [5, 6], unit='deg,deg,pc', pm_ra_cosdec=[7, 8]*u.mas/u.yr, pm_dec=[9, 10]*u.mas/u.yr) scpmrv = SkyCoord([1, 2], [3, 4], [5, 6], unit='deg,deg,pc', pm_ra_cosdec=[7, 8]*u.mas/u.yr, pm_dec=[9, 10]*u.mas/u.yr, radial_velocity=[11, 12]*u.km/u.s) scrv = SkyCoord([1, 2], [3, 4], [5, 6], unit='deg,deg,pc', radial_velocity=[11, 12]*u.km/u.s) tm = Time([51000.5, 51001.5], format='mjd', scale='tai', precision=5, location=el[0]) tm2 = Time(tm, format='iso') tm3 = Time(tm, location=el) tm3.info.serialize_method['ecsv'] = 'jd1_jd2' obj = Column([{'a': 1}, {'b': [2]}], dtype='object') # NOTE: in the test below the name of the column "x" for the Quantity is # important since it tests the fix for #10215 (namespace clash, where "x" # clashes with "el.x"). mixin_cols = { 'tm': tm, 'tm2': tm2, 'tm3': tm3, 'dt': TimeDelta([1, 2] * u.day), 'sc': sc, 'scd': scd, 'scdc': scdc, 'scpm': scpm, 'scpmrv': scpmrv, 'scrv': scrv, 'x': [1, 2] * u.m, 'qdb': [10, 20] * u.dB(u.mW), 'qdex': [4.5, 5.5] * u.dex(u.cm / u.s**2), 'qmag': [21, 22] * u.ABmag, 'lat': Latitude([1, 2] * u.deg), 'lon': Longitude([1, 2] * u.deg, wrap_angle=180. * u.deg), 'ang': Angle([1, 2] * u.deg), 'el': el, 'sr': sr, 'cr': cr, 'sd': sd, 'srd': srd, 'nd': NdarrayMixin([1, 2]), 'obj': obj } time_attrs = ['value', 'shape', 'format', 'scale', 'precision', 'in_subfmt', 'out_subfmt', 'location'] compare_attrs = { 'c1': ['data'], 'c2': ['data'], 'tm': time_attrs, 'tm2': time_attrs, 'tm3': time_attrs, 'dt': ['shape', 'value', 'format', 'scale'], 'sc': ['ra', 'dec', 'representation_type', 'frame.name'], 'scd': ['ra', 'dec', 'distance', 'representation_type', 'frame.name'], 'scdc': ['x', 'y', 'z', 'representation_type', 'frame.name'], 'scpm': ['ra', 'dec', 'distance', 'pm_ra_cosdec', 'pm_dec', 'representation_type', 'frame.name'], 'scpmrv': ['ra', 'dec', 'distance', 'pm_ra_cosdec', 'pm_dec', 'radial_velocity', 'representation_type', 'frame.name'], 'scrv': ['ra', 'dec', 'distance', 'radial_velocity', 'representation_type', 'frame.name'], 'x': ['value', 'unit'], 'qdb': ['value', 'unit'], 'qdex': ['value', 'unit'], 'qmag': ['value', 'unit'], 'lon': ['value', 'unit', 'wrap_angle'], 'lat': ['value', 'unit'], 'ang': ['value', 'unit'], 'el': ['x', 'y', 'z', 'ellipsoid'], 'nd': ['data'], 'sr': ['lon', 'lat', 'distance'], 'cr': ['x', 'y', 'z'], 'sd': ['d_lon_coslat', 'd_lat', 'd_distance'], 'srd': ['lon', 'lat', 'distance', 'differentials.s.d_lon_coslat', 'differentials.s.d_lat', 'differentials.s.d_distance'], 'obj': [] } def test_ecsv_mixins_ascii_read_class(): """Ensure that ascii.read(ecsv_file) returns the correct class (QTable if any Quantity subclasses, Table otherwise). """ # Make a table with every mixin type except Quantities t = QTable({name: col for name, col in mixin_cols.items() if not isinstance(col.info, QuantityInfo)}) out = StringIO() t.write(out, format="ascii.ecsv") t2 = ascii.read(out.getvalue(), format='ecsv') assert type(t2) is Table # Add a single quantity column t['lon'] = mixin_cols['lon'] out = StringIO() t.write(out, format="ascii.ecsv") t2 = ascii.read(out.getvalue(), format='ecsv') assert type(t2) is QTable def test_ecsv_mixins_qtable_to_table(): """Test writing as QTable and reading as Table. Ensure correct classes come out. """ names = sorted(mixin_cols) t = QTable([mixin_cols[name] for name in names], names=names) out = StringIO() t.write(out, format="ascii.ecsv") t2 = Table.read(out.getvalue(), format='ascii.ecsv') assert t.colnames == t2.colnames for name, col in t.columns.items(): col2 = t2[name] attrs = compare_attrs[name] compare_class = True if isinstance(col.info, QuantityInfo): # Downgrade Quantity to Column + unit assert type(col2) is Column # Class-specific attributes like `value` or `wrap_angle` are lost. attrs = ['unit'] compare_class = False # Compare data values here (assert_objects_equal doesn't know how in this case) assert np.allclose(col.value, col2, rtol=1e-10) assert_objects_equal(col, col2, attrs, compare_class) @pytest.mark.parametrize('table_cls', (Table, QTable)) def test_ecsv_mixins_as_one(table_cls): """Test write/read all cols at once and validate intermediate column names""" names = sorted(mixin_cols) serialized_names = ['ang', 'cr.x', 'cr.y', 'cr.z', 'dt', 'el.x', 'el.y', 'el.z', 'lat', 'lon', 'nd', 'obj', 'qdb', 'qdex', 'qmag', 'sc.ra', 'sc.dec', 'scd.ra', 'scd.dec', 'scd.distance', 'scd.obstime', 'scdc.x', 'scdc.y', 'scdc.z', 'scdc.obstime', 'scpm.ra', 'scpm.dec', 'scpm.distance', 'scpm.pm_ra_cosdec', 'scpm.pm_dec', 'scpmrv.ra', 'scpmrv.dec', 'scpmrv.distance', 'scpmrv.pm_ra_cosdec', 'scpmrv.pm_dec', 'scpmrv.radial_velocity', 'scrv.ra', 'scrv.dec', 'scrv.distance', 'scrv.radial_velocity', 'sd.d_lon_coslat', 'sd.d_lat', 'sd.d_distance', 'sr.lon', 'sr.lat', 'sr.distance', 'srd.lon', 'srd.lat', 'srd.distance', 'srd.differentials.s.d_lon_coslat', 'srd.differentials.s.d_lat', 'srd.differentials.s.d_distance', 'tm', # serialize_method is formatted_value 'tm2', # serialize_method is formatted_value 'tm3.jd1', 'tm3.jd2', # serialize is jd1_jd2 'tm3.location.x', 'tm3.location.y', 'tm3.location.z', 'x'] t = table_cls([mixin_cols[name] for name in names], names=names) out = StringIO() t.write(out, format="ascii.ecsv") t2 = table_cls.read(out.getvalue(), format='ascii.ecsv') assert t.colnames == t2.colnames # Read as a ascii.basic table (skip all the ECSV junk) t3 = table_cls.read(out.getvalue(), format='ascii.basic') assert t3.colnames == serialized_names def make_multidim(col, ndim): """Take a col with length=2 and make it N-d by repeating elements. For the special case of ndim==1 just return the original. The output has shape [3] * ndim. By using 3 we can be sure that repeating the two input elements gives an output that is sufficiently unique for the multidim tests. """ if ndim > 1: import itertools idxs = [idx for idx, _ in zip(itertools.cycle([0, 1]), range(3 ** ndim))] col = col[idxs].reshape([3] * ndim) return col @pytest.mark.parametrize('name_col', list(mixin_cols.items())) @pytest.mark.parametrize('table_cls', (Table, QTable)) @pytest.mark.parametrize('ndim', (1, 2, 3)) def test_ecsv_mixins_per_column(table_cls, name_col, ndim): """Test write/read one col at a time and do detailed validation. This tests every input column type as 1-d, 2-d and 3-d. """ name, col = name_col c = make_multidim(np.array([1.0, 2.0]), ndim) col = make_multidim(col, ndim) t = table_cls([c, col, c], names=['c1', name, 'c2']) t[name].info.description = 'description' out = StringIO() t.write(out, format="ascii.ecsv") t2 = table_cls.read(out.getvalue(), format='ascii.ecsv') assert t.colnames == t2.colnames for colname in t.colnames: assert len(t2[colname].shape) == ndim assert_objects_equal(t[colname], t2[colname], compare_attrs[colname]) # Special case to make sure Column type doesn't leak into Time class data if name.startswith('tm'): assert t2[name]._time.jd1.__class__ is np.ndarray assert t2[name]._time.jd2.__class__ is np.ndarray def test_round_trip_masked_table_default(tmpdir): """Test (mostly) round-trip of MaskedColumn through ECSV using default serialization that uses an empty string "" to mark NULL values. Note: >>> simple_table(masked=True) a b c int64 float64 str1 ----- ------- ---- -- 1.0 c 2 2.0 -- 3 -- e """ filename = str(tmpdir.join('test.ecsv')) t = simple_table(masked=True) # int, float, and str cols with one masked element t.write(filename) t2 = Table.read(filename) assert t2.masked is False assert t2.colnames == t.colnames for name in t2.colnames: # From formal perspective the round-trip columns are the "same" assert np.all(t2[name].mask == t[name].mask) assert np.all(t2[name] == t[name]) # But peeking under the mask shows that the underlying data are changed # because by default ECSV uses "" to represent masked elements. t[name].mask = False t2[name].mask = False assert not np.all(t2[name] == t[name]) # Expected diff def test_round_trip_masked_table_serialize_mask(tmpdir): """Same as prev but set the serialize_method to 'data_mask' so mask is written out""" filename = str(tmpdir.join('test.ecsv')) t = simple_table(masked=True) # int, float, and str cols with one masked element t['c'][0] = '' # This would come back as masked for default "" NULL marker # MaskedColumn with no masked elements. See table the MaskedColumnInfo class # _represent_as_dict() method for info about how we test a column with no masked elements. t['d'] = [1, 2, 3] t.write(filename, serialize_method='data_mask') t2 = Table.read(filename) assert t2.masked is False assert t2.colnames == t.colnames for name in t2.colnames: assert np.all(t2[name].mask == t[name].mask) assert np.all(t2[name] == t[name]) # Data under the mask round-trips also (unmask data to show this). t[name].mask = False t2[name].mask = False assert np.all(t2[name] == t[name]) @pytest.mark.parametrize('table_cls', (Table, QTable)) def test_ecsv_round_trip_user_defined_unit(table_cls, tmpdir): """Ensure that we can read-back enabled user-defined units.""" # Test adapted from #8897, where it was noted that this works # but was not tested. filename = str(tmpdir.join('test.ecsv')) unit = u.def_unit('bandpass_sol_lum') t = table_cls() t['l'] = np.arange(5) * unit t.write(filename) # without the unit enabled, get UnrecognizedUnit if table_cls is QTable: ctx = pytest.warns(u.UnitsWarning, match=r"'bandpass_sol_lum' did not parse .*") else: ctx = nullcontext() # Note: The read might also generate ResourceWarning, in addition to UnitsWarning with ctx: t2 = table_cls.read(filename) assert isinstance(t2['l'].unit, u.UnrecognizedUnit) assert str(t2['l'].unit) == 'bandpass_sol_lum' if table_cls is QTable: assert np.all(t2['l'].value == t['l'].value) else: assert np.all(t2['l'] == t['l']) # But with it enabled, it works. with u.add_enabled_units(unit): t3 = table_cls.read(filename) assert t3['l'].unit is unit assert np.all(t3['l'] == t['l']) # Just to be sure, aloso try writing with unit enabled. filename2 = str(tmpdir.join('test2.ecsv')) t3.write(filename2) t4 = table_cls.read(filename) assert t4['l'].unit is unit assert np.all(t4['l'] == t['l']) def test_read_masked_bool(): txt = """\ # %ECSV 1.0 # --- # datatype: # - {name: col0, datatype: bool} # schema: astropy-2.0 col0 1 0 True "" False """ dat = ascii.read(txt, format='ecsv') col = dat['col0'] assert isinstance(col, MaskedColumn) assert np.all(col.mask == [False, False, False, True, False]) assert np.all(col == [True, False, True, False, False]) @pytest.mark.parametrize('serialize_method', ['null_value', 'data_mask']) @pytest.mark.parametrize('dtype', [np.int64, np.float64, bool, str]) @pytest.mark.parametrize('delimiter', [',', ' ']) def test_roundtrip_multidim_masked_array(serialize_method, dtype, delimiter): # TODO also test empty string with null value t = Table() col = MaskedColumn(np.arange(12).reshape(2, 3, 2), dtype=dtype) if dtype is str: # np does something funny and gives a dtype of U21. col = col.astype('U2') col.mask[0, 0, 0] = True col.mask[1, 1, 1] = True t['a'] = col t['b'] = ['x', 'y'] # Add another column for kicks out = StringIO() t.write(out, format='ascii.ecsv', serialize_method=serialize_method) t2 = Table.read(out.getvalue(), format='ascii.ecsv') assert t2.masked is False assert t2.colnames == t.colnames for name in t2.colnames: assert t2[name].dtype == t[name].dtype if hasattr(t[name], 'mask'): assert np.all(t2[name].mask == t[name].mask) assert np.all(t2[name] == t[name]) @pytest.mark.parametrize('subtype', ['some-user-type', 'complex']) def test_multidim_unknown_subtype(subtype): """Test an ECSV file with a string type but unknown subtype""" txt = f"""\ # %ECSV 1.0 # --- # datatype: # - name: a # datatype: string # subtype: {subtype} # schema: astropy-2.0 a [1,2] [3,4]""" with pytest.warns(AstropyUserWarning, match=rf"unexpected subtype '{subtype}' set for column 'a'"): t = ascii.read(txt, format='ecsv') assert t['a'].dtype.kind == 'U' assert t['a'][0] == '[1,2]' def test_multidim_bad_shape(): """Test a malformed ECSV file""" txt = """\ # %ECSV 1.0 # --- # datatype: # - name: a # datatype: string # subtype: int64[3] # schema: astropy-2.0 a [1,2] [3,4]""" with pytest.raises(ValueError, match="column 'a' failed to convert: shape mismatch"): Table.read(txt, format='ascii.ecsv') def test_write_not_json_serializable(): t = Table() t['a'] = np.array([set([1, 2]), 1], dtype=object) match = "could not convert column 'a' to string: Object of type set is not JSON serializable" out = StringIO() with pytest.raises(TypeError, match=match): t.write(out, format='ascii.ecsv') def test_read_not_json_serializable(): """Test a malformed ECSV file""" txt = """\ # %ECSV 1.0 # --- # datatype: # - {name: a, datatype: string, subtype: json} # schema: astropy-2.0 a fail [3,4]""" match = "column 'a' failed to convert: column value is not valid JSON" with pytest.raises(ValueError, match=match): Table.read(txt, format='ascii.ecsv') def test_read_complex(): """Test an ECSV file with a complex column""" txt = """\ # %ECSV 1.0 # --- # datatype: # - {name: a, datatype: complex} # schema: astropy-2.0 a 1+1j 2+2j""" match = "datatype 'complex' of column 'a' is not in allowed values" with pytest.raises(ValueError, match=match): Table.read(txt, format='ascii.ecsv') @pytest.mark.skipif(NUMPY_LT_1_19_1, reason="numpy<=1.19.0 cannot parse 'complex' as string") def test_read_complex_v09(): """Test an ECSV file with a complex column for version 0.9 Note: ECSV Version <=0.9 files should not raise ValueError for complex datatype to maintain backwards compatibility. """ txt = """\ # %ECSV 0.9 # --- # datatype: # - {name: a, datatype: complex} # schema: astropy-2.0 a 1+1j 2+2j""" t = Table.read(txt, format='ascii.ecsv') assert t['a'].dtype.type is np.complex128 def test_read_bad_datatype_for_object_subtype(): """Test a malformed ECSV file""" txt = """\ # %ECSV 1.0 # --- # datatype: # - {name: a, datatype: int64, subtype: json} # schema: astropy-2.0 a fail [3,4]""" match = "column 'a' failed to convert: datatype of column 'a' must be \"string\"" with pytest.raises(ValueError, match=match): Table.read(txt, format='ascii.ecsv') def test_read_bad_datatype(): """Test a malformed ECSV file""" txt = """\ # %ECSV 1.0 # --- # datatype: # - {name: a, datatype: object} # schema: astropy-2.0 a fail [3,4]""" match = r"column 'a' is not in allowed values \('bool', 'int8', 'int16', 'int32'" with pytest.raises(ValueError, match=match): Table.read(txt, format='ascii.ecsv') def test_read_bad_datatype_v09(): """Test a malformed ECSV file for version 0.9 Note: ECSV Version <=0.9 files should not raise ValueError for malformed datatypes to maintain backwards compatibility. """ txt = """\ # %ECSV 0.9 # --- # datatype: # - {name: a, datatype: object} # schema: astropy-2.0 a fail [3,4]""" t = Table.read(txt, format='ascii.ecsv') assert t['a'][0] == "fail" assert type(t['a'][1]) is str assert type(t['a'].dtype) == np.dtype("O") def test_full_repr_roundtrip(): """Test round-trip of float values to full precision even with format specified""" t = Table() t['a'] = np.array([np.pi, 1/7], dtype=np.float64) t['a'].info.format = '.2f' out = StringIO() t.write(out, format='ascii.ecsv') t2 = Table.read(out.getvalue(), format='ascii.ecsv') assert np.all(t['a'] == t2['a']) assert t2['a'].info.format == '.2f' ############################################################################# # Define a number of specialized columns for testing and the expected values # of `datatype` for each column. ############################################################################# # First here is some helper code used to make the expected outputs code. def _get_ecsv_header_dict(text): lines = [line.strip() for line in text.splitlines()] lines = [line[2:] for line in lines if line.startswith('#')] lines = lines[2:] # Get rid of the header out = yaml.safe_load('\n'.join(lines)) return out def _make_expected_values(cols): from pprint import pformat for name, col in cols.items(): t = Table() t[name] = col out = StringIO() t.write(out, format='ascii.ecsv') hdr = _get_ecsv_header_dict(out.getvalue()) fmt_hdr = pformat(hdr['datatype']) print(f'exps[{name!r}] =', fmt_hdr[:1]) print(fmt_hdr[1:]) print() # Expected values of `datatype` for each column exps = {} cols = {} # Run of the mill scalar for completeness cols['scalar'] = np.array([1, 2], dtype=np.int16) exps['scalar'] = [ {'datatype': 'int16', 'name': 'scalar'}] # Array of lists that works as a 2-d variable array. This is just treated # as an object. cols['2-d variable array lists'] = c = np.empty(shape=(2,), dtype=object) c[0] = [[1, 2], ["a", 4]] c[1] = [[1, 2, 3], [4, 5.25, 6]] exps['2-d variable array lists'] = [ {'datatype': 'string', 'name': '2-d variable array lists', 'subtype': 'json'}] # Array of numpy arrays that is a 2-d variable array cols['2-d variable array numpy'] = c = np.empty(shape=(2,), dtype=object) c[0] = np.array([[1, 2], [3, 4]], dtype=np.float32) c[1] = np.array([[1, 2, 3], [4, 5.5, 6]], dtype=np.float32) exps['2-d variable array numpy'] = [ {'datatype': 'string', 'name': '2-d variable array numpy', 'subtype': 'float32[2,null]'}] cols['1-d variable array lists'] = np.array([[1, 2], [3, 4, 5]], dtype=object) exps['1-d variable array lists'] = [ {'datatype': 'string', 'name': '1-d variable array lists', 'subtype': 'json'}] # Variable-length array cols['1-d variable array numpy'] = np.array( [np.array([1, 2], dtype=np.uint8), np.array([3, 4, 5], dtype=np.uint8)], dtype=object) exps['1-d variable array numpy'] = [ {'datatype': 'string', 'name': '1-d variable array numpy', 'subtype': 'uint8[null]'}] cols['1-d variable array numpy str'] = np.array( [np.array(['a', 'b']), np.array(['c', 'd', 'e'])], dtype=object) exps['1-d variable array numpy str'] = [ {'datatype': 'string', 'name': '1-d variable array numpy str', 'subtype': 'string[null]'}] cols['1-d variable array numpy bool'] = np.array( [np.array([True, False]), np.array([True, False, True])], dtype=object) exps['1-d variable array numpy bool'] = [ {'datatype': 'string', 'name': '1-d variable array numpy bool', 'subtype': 'bool[null]'}] cols['1-d regular array'] = np.array([[1, 2], [3, 4]], dtype=np.int8) exps['1-d regular array'] = [ {'datatype': 'string', 'name': '1-d regular array', 'subtype': 'int8[2]'}] cols['2-d regular array'] = np.arange(8, dtype=np.float16).reshape(2, 2, 2) exps['2-d regular array'] = [ {'datatype': 'string', 'name': '2-d regular array', 'subtype': 'float16[2,2]'}] cols['scalar object'] = np.array([{'a': 1}, {'b':2}], dtype=object) exps['scalar object'] = [ {'datatype': 'string', 'name': 'scalar object', 'subtype': 'json'}] cols['1-d object'] = np.array( [[{'a': 1}, {'b':2}], [{'a': 1}, {'b':2}]], dtype=object) exps['1-d object'] = [ {'datatype': 'string', 'name': '1-d object', 'subtype': 'json[2]'}] @pytest.mark.parametrize('name,col,exp', list(zip(cols, cols.values(), exps.values()))) def test_specialized_columns(name, col, exp): """Test variable length lists, multidim columns, object columns. """ t = Table() t[name] = col out = StringIO() t.write(out, format='ascii.ecsv') hdr = _get_ecsv_header_dict(out.getvalue()) assert hdr['datatype'] == exp t2 = Table.read(out.getvalue(), format='ascii.ecsv') assert t2.colnames == t.colnames for name in t2.colnames: assert t2[name].dtype == t[name].dtype for val1, val2 in zip(t2[name], t[name]): if isinstance(val1, np.ndarray): assert val1.dtype == val2.dtype assert np.all(val1 == val2) def test_full_subtypes(): """Read ECSV file created by M. Taylor that includes scalar, fixed array, variable array for all datatypes. This file has missing values for all columns as both per-value null and blank entries for the entire column value. Note: original file was modified to include blank values in f_float and f_double columns. """ t = Table.read(os.path.join(TEST_DIR, 'data', 'subtypes.ecsv')) colnames = ('i_index,' 's_byte,s_short,s_int,s_long,s_float,s_double,s_string,s_boolean,' 'f_byte,f_short,f_int,f_long,f_float,f_double,f_string,f_boolean,' 'v_byte,v_short,v_int,v_long,v_float,v_double,v_string,v_boolean,' 'm_int,m_double').split(',') assert t.colnames == colnames type_map = {'byte': 'int8', 'short': 'int16', 'int': 'int32', 'long': 'int64', 'float': 'float32', 'double': 'float64', 'string': 'str', 'boolean': 'bool'} for col in t.itercols(): info = col.info if info.name == 'i_index': continue assert isinstance(col, MaskedColumn) type_name = info.name[2:] # short, int, etc subtype = info.name[:1] if subtype == 's': # Scalar assert col.shape == (16,) if subtype == 'f': # Fixed array assert col.shape == (16, 3) if subtype == 'v': # Variable array assert col.shape == (16,) assert info.dtype.name == 'object' for val in col: assert isinstance(val, np.ndarray) assert val.dtype.name.startswith(type_map[type_name]) assert len(val) in [0, 1, 2, 3] else: assert info.dtype.name.startswith(type_map[type_name]) def test_masked_empty_subtypes(): """Test blank field in subtypes. Similar to previous test but with explicit checks of values""" txt = """ # %ECSV 1.0 # --- # datatype: # - {name: o, datatype: string, subtype: json} # - {name: f, datatype: string, subtype: 'int64[2]'} # - {name: v, datatype: string, subtype: 'int64[null]'} # schema: astropy-2.0 o f v null [0,1] [1] "" "" "" [1,2] [2,3] [2,3] """ t = Table.read(txt, format='ascii.ecsv') assert np.all(t['o'] == np.array([None, -1, [1, 2]], dtype=object)) assert np.all(t['o'].mask == [False, True, False]) exp = np.ma.array([[0, 1], [-1, -1], [2, 3]], mask=[[0, 0], [1, 1], [0, 0]]) assert np.all(t['f'] == exp) assert np.all(t['f'].mask == exp.mask) assert np.all(t['v'][0] == [1]) assert np.all(t['v'][2] == [2, 3]) assert np.all(t['v'].mask == [False, True, False]) def test_masked_vals_in_array_subtypes(): """Test null values in fixed and variable array subtypes.""" t = Table() t['f'] = np.ma.array([[1, 2], [3, 4]], mask=[[0, 1], [1, 0]], dtype=np.int64) t['v'] = np.empty(2, dtype=object) t['v'][0] = np.ma.array([1, 2], mask=[0, 1], dtype=np.int64) t['v'][1] = np.ma.array([3, 4, 5], mask=[1, 0, 0], dtype=np.int64) out = StringIO() t.write(out, format='ascii.ecsv') txt = """ # %ECSV 1.0 # --- # datatype: # - {name: f, datatype: string, subtype: 'int64[2]'} # - {name: v, datatype: string, subtype: 'int64[null]'} # schema: astropy-2.0 f v [1,null] [1,null] [null,4] [null,4,5] """ hdr = _get_ecsv_header_dict(out.getvalue()) hdr_exp = _get_ecsv_header_dict(txt) assert hdr == hdr_exp t2 = Table.read(out.getvalue(), format='ascii.ecsv') assert t2.colnames == t.colnames for name in t2.colnames: assert t2[name].dtype == t[name].dtype assert type(t2[name]) is type(t[name]) for val1, val2 in zip(t2[name], t[name]): if isinstance(val1, np.ndarray): assert val1.dtype == val2.dtype if isinstance(val1, np.ma.MaskedArray): assert np.all(val1.mask == val2.mask) assert np.all(val1 == val2) def test_guess_ecsv_with_one_column(): """Except for ECSV, guessing always requires at least 2 columns""" txt = """ # %ECSV 1.0 # --- # datatype: # - {name: col, datatype: string, description: hello} # schema: astropy-2.0 col 1 2 """ t = ascii.read(txt) assert t['col'].dtype.kind == 'U' # would be int with basic format assert t['col'].description == 'hello' ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/test_fixedwidth.py0000644000175100001710000003645700000000000022376 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst from io import StringIO import numpy as np import pytest from astropy.io import ascii from astropy.io.ascii.core import InconsistentTableError from .common import (assert_equal, assert_almost_equal) def assert_equal_splitlines(arg1, arg2): assert_equal(arg1.splitlines(), arg2.splitlines()) def test_read_normal(): """Nice, typical fixed format table""" table = """ # comment (with blank line above) | Col1 | Col2 | | 1.2 | "hello" | | 2.4 |'s worlds| """ reader = ascii.get_reader(Reader=ascii.FixedWidth) dat = reader.read(table) assert_equal(dat.colnames, ['Col1', 'Col2']) assert_almost_equal(dat[1][0], 2.4) assert_equal(dat[0][1], '"hello"') assert_equal(dat[1][1], "'s worlds") def test_read_normal_names(): """Nice, typical fixed format table with col names provided""" table = """ # comment (with blank line above) | Col1 | Col2 | | 1.2 | "hello" | | 2.4 |'s worlds| """ reader = ascii.get_reader(Reader=ascii.FixedWidth, names=('name1', 'name2')) dat = reader.read(table) assert_equal(dat.colnames, ['name1', 'name2']) assert_almost_equal(dat[1][0], 2.4) def test_read_normal_names_include(): """Nice, typical fixed format table with col names provided""" table = """ # comment (with blank line above) | Col1 | Col2 | Col3 | | 1.2 | "hello" | 3 | | 2.4 |'s worlds| 7 | """ reader = ascii.get_reader(Reader=ascii.FixedWidth, names=('name1', 'name2', 'name3'), include_names=('name1', 'name3')) dat = reader.read(table) assert_equal(dat.colnames, ['name1', 'name3']) assert_almost_equal(dat[1][0], 2.4) assert_equal(dat[0][1], 3) def test_read_normal_exclude(): """Nice, typical fixed format table with col name excluded""" table = """ # comment (with blank line above) | Col1 | Col2 | | 1.2 | "hello" | | 2.4 |'s worlds| """ reader = ascii.get_reader(Reader=ascii.FixedWidth, exclude_names=('Col1',)) dat = reader.read(table) assert_equal(dat.colnames, ['Col2']) assert_equal(dat[1][0], "'s worlds") def test_read_weird(): """Weird input table with data values chopped by col extent """ table = """ Col1 | Col2 | 1.2 "hello" 2.4 sdf's worlds """ reader = ascii.get_reader(Reader=ascii.FixedWidth) dat = reader.read(table) assert_equal(dat.colnames, ['Col1', 'Col2']) assert_almost_equal(dat[1][0], 2.4) assert_equal(dat[0][1], '"hel') assert_equal(dat[1][1], "df's wo") def test_read_double(): """Table with double delimiters""" table = """ || Name || Phone || TCP|| | John | 555-1234 |192.168.1.10X| | Mary | 555-2134 |192.168.1.12X| | Bob | 555-4527 | 192.168.1.9X| """ dat = ascii.read(table, Reader=ascii.FixedWidth, guess=False) assert_equal(tuple(dat.dtype.names), ('Name', 'Phone', 'TCP')) assert_equal(dat[1][0], "Mary") assert_equal(dat[0][1], "555-1234") assert_equal(dat[2][2], "192.168.1.9") def test_read_space_delimiter(): """Table with space delimiter""" table = """ Name --Phone- ----TCP----- John 555-1234 192.168.1.10 Mary 555-2134 192.168.1.12 Bob 555-4527 192.168.1.9 """ dat = ascii.read(table, Reader=ascii.FixedWidth, guess=False, delimiter=' ') assert_equal(tuple(dat.dtype.names), ('Name', '--Phone-', '----TCP-----')) assert_equal(dat[1][0], "Mary") assert_equal(dat[0][1], "555-1234") assert_equal(dat[2][2], "192.168.1.9") def test_read_no_header_autocolumn(): """Table with no header row and auto-column naming""" table = """ | John | 555-1234 |192.168.1.10| | Mary | 555-2134 |192.168.1.12| | Bob | 555-4527 | 192.168.1.9| """ dat = ascii.read(table, Reader=ascii.FixedWidth, guess=False, header_start=None, data_start=0) assert_equal(tuple(dat.dtype.names), ('col1', 'col2', 'col3')) assert_equal(dat[1][0], "Mary") assert_equal(dat[0][1], "555-1234") assert_equal(dat[2][2], "192.168.1.9") def test_read_no_header_names(): """Table with no header row and with col names provided. Second and third rows also have hanging spaces after final |.""" table = """ | John | 555-1234 |192.168.1.10| | Mary | 555-2134 |192.168.1.12| | Bob | 555-4527 | 192.168.1.9| """ dat = ascii.read(table, Reader=ascii.FixedWidth, guess=False, header_start=None, data_start=0, names=('Name', 'Phone', 'TCP')) assert_equal(tuple(dat.dtype.names), ('Name', 'Phone', 'TCP')) assert_equal(dat[1][0], "Mary") assert_equal(dat[0][1], "555-1234") assert_equal(dat[2][2], "192.168.1.9") def test_read_no_header_autocolumn_NoHeader(): """Table with no header row and auto-column naming""" table = """ | John | 555-1234 |192.168.1.10| | Mary | 555-2134 |192.168.1.12| | Bob | 555-4527 | 192.168.1.9| """ dat = ascii.read(table, Reader=ascii.FixedWidthNoHeader) assert_equal(tuple(dat.dtype.names), ('col1', 'col2', 'col3')) assert_equal(dat[1][0], "Mary") assert_equal(dat[0][1], "555-1234") assert_equal(dat[2][2], "192.168.1.9") def test_read_no_header_names_NoHeader(): """Table with no header row and with col names provided. Second and third rows also have hanging spaces after final |.""" table = """ | John | 555-1234 |192.168.1.10| | Mary | 555-2134 |192.168.1.12| | Bob | 555-4527 | 192.168.1.9| """ dat = ascii.read(table, Reader=ascii.FixedWidthNoHeader, names=('Name', 'Phone', 'TCP')) assert_equal(tuple(dat.dtype.names), ('Name', 'Phone', 'TCP')) assert_equal(dat[1][0], "Mary") assert_equal(dat[0][1], "555-1234") assert_equal(dat[2][2], "192.168.1.9") def test_read_col_starts(): """Table with no delimiter with column start and end values specified.""" table = """ # 5 9 17 18 28 # | | || | John 555- 1234 192.168.1.10 Mary 555- 2134 192.168.1.12 Bob 555- 4527 192.168.1.9 """ dat = ascii.read(table, Reader=ascii.FixedWidthNoHeader, names=('Name', 'Phone', 'TCP'), col_starts=(0, 9, 18), col_ends=(5, 17, 28), ) assert_equal(tuple(dat.dtype.names), ('Name', 'Phone', 'TCP')) assert_equal(dat[0][1], "555- 1234") assert_equal(dat[1][0], "Mary") assert_equal(dat[1][2], "192.168.1.") assert_equal(dat[2][2], "192.168.1") # col_end=28 cuts this column off def test_read_detect_col_starts_or_ends(): """Table with no delimiter with only column start or end values specified""" table = """ #1 9 19 <== Column start indexes #| | | <== Column start positions #<------><--------><-------------> <== Inferred column positions John 555- 1234 192.168.1.10 Mary 555- 2134 192.168.1.123 Bob 555- 4527 192.168.1.9 Bill 555-9875 192.255.255.255 """ for kwargs in ({'col_starts': (1, 9, 19)}, {'col_ends': (8, 18, 33)}): dat = ascii.read(table, Reader=ascii.FixedWidthNoHeader, names=('Name', 'Phone', 'TCP'), **kwargs) assert_equal(tuple(dat.dtype.names), ('Name', 'Phone', 'TCP')) assert_equal(dat[0][1], "555- 1234") assert_equal(dat[1][0], "Mary") assert_equal(dat[1][2], "192.168.1.123") assert_equal(dat[3][2], "192.255.255.255") table = """\ | Col1 | Col2 | Col3 | Col4 | | 1.2 | "hello" | 1 | a | | 2.4 | 's worlds | 2 | 2 | """ dat = ascii.read(table, Reader=ascii.FixedWidth) def test_write_normal(): """Write a table as a normal fixed width table.""" out = StringIO() ascii.write(dat, out, Writer=ascii.FixedWidth) assert_equal_splitlines(out.getvalue(), """\ | Col1 | Col2 | Col3 | Col4 | | 1.2 | "hello" | 1 | a | | 2.4 | 's worlds | 2 | 2 | """) def test_write_fill_values(): """Write a table as a normal fixed width table.""" out = StringIO() ascii.write(dat, out, Writer=ascii.FixedWidth, fill_values=('a', 'N/A')) assert_equal_splitlines(out.getvalue(), """\ | Col1 | Col2 | Col3 | Col4 | | 1.2 | "hello" | 1 | N/A | | 2.4 | 's worlds | 2 | 2 | """) def test_write_no_pad(): """Write a table as a fixed width table with no padding.""" out = StringIO() ascii.write(dat, out, Writer=ascii.FixedWidth, delimiter_pad=None) assert_equal_splitlines(out.getvalue(), """\ |Col1| Col2|Col3|Col4| | 1.2| "hello"| 1| a| | 2.4|'s worlds| 2| 2| """) def test_write_no_bookend(): """Write a table as a fixed width table with no bookend.""" out = StringIO() ascii.write(dat, out, Writer=ascii.FixedWidth, bookend=False) assert_equal_splitlines(out.getvalue(), """\ Col1 | Col2 | Col3 | Col4 1.2 | "hello" | 1 | a 2.4 | 's worlds | 2 | 2 """) def test_write_no_delimiter(): """Write a table as a fixed width table with no delimiter.""" out = StringIO() ascii.write(dat, out, Writer=ascii.FixedWidth, bookend=False, delimiter=None) assert_equal_splitlines(out.getvalue(), """\ Col1 Col2 Col3 Col4 1.2 "hello" 1 a 2.4 's worlds 2 2 """) def test_write_noheader_normal(): """Write a table as a normal fixed width table.""" out = StringIO() ascii.write(dat, out, Writer=ascii.FixedWidthNoHeader) assert_equal_splitlines(out.getvalue(), """\ | 1.2 | "hello" | 1 | a | | 2.4 | 's worlds | 2 | 2 | """) def test_write_noheader_no_pad(): """Write a table as a fixed width table with no padding.""" out = StringIO() ascii.write(dat, out, Writer=ascii.FixedWidthNoHeader, delimiter_pad=None) assert_equal_splitlines(out.getvalue(), """\ |1.2| "hello"|1|a| |2.4|'s worlds|2|2| """) def test_write_noheader_no_bookend(): """Write a table as a fixed width table with no bookend.""" out = StringIO() ascii.write(dat, out, Writer=ascii.FixedWidthNoHeader, bookend=False) assert_equal_splitlines(out.getvalue(), """\ 1.2 | "hello" | 1 | a 2.4 | 's worlds | 2 | 2 """) def test_write_noheader_no_delimiter(): """Write a table as a fixed width table with no delimiter.""" out = StringIO() ascii.write(dat, out, Writer=ascii.FixedWidthNoHeader, bookend=False, delimiter=None) assert_equal_splitlines(out.getvalue(), """\ 1.2 "hello" 1 a 2.4 's worlds 2 2 """) def test_write_formats(): """Write a table as a fixed width table with no delimiter.""" out = StringIO() ascii.write(dat, out, Writer=ascii.FixedWidth, formats={'Col1': '%-8.3f', 'Col2': '%-15s'}) assert_equal_splitlines(out.getvalue(), """\ | Col1 | Col2 | Col3 | Col4 | | 1.200 | "hello" | 1 | a | | 2.400 | 's worlds | 2 | 2 | """) def test_read_twoline_normal(): """Typical fixed format table with two header lines (with some cruft thrown in to test column positioning""" table = """ Col1 Col2 ---- --------- 1.2xx"hello" 2.4 's worlds """ dat = ascii.read(table, Reader=ascii.FixedWidthTwoLine) assert_equal(dat.dtype.names, ('Col1', 'Col2')) assert_almost_equal(dat[1][0], 2.4) assert_equal(dat[0][1], '"hello"') assert_equal(dat[1][1], "'s worlds") def test_read_twoline_ReST(): """Read restructured text table""" table = """ ======= =========== Col1 Col2 ======= =========== 1.2 "hello" 2.4 's worlds ======= =========== """ dat = ascii.read(table, Reader=ascii.FixedWidthTwoLine, header_start=1, position_line=2, data_end=-1) assert_equal(dat.dtype.names, ('Col1', 'Col2')) assert_almost_equal(dat[1][0], 2.4) assert_equal(dat[0][1], '"hello"') assert_equal(dat[1][1], "'s worlds") def test_read_twoline_human(): """Read text table designed for humans and test having position line before the header line""" table = """ +------+----------+ | Col1 | Col2 | +------|----------+ | 1.2 | "hello" | | 2.4 | 's worlds| +------+----------+ """ dat = ascii.read(table, Reader=ascii.FixedWidthTwoLine, delimiter='+', header_start=1, position_line=0, data_start=3, data_end=-1) assert_equal(dat.dtype.names, ('Col1', 'Col2')) assert_almost_equal(dat[1][0], 2.4) assert_equal(dat[0][1], '"hello"') assert_equal(dat[1][1], "'s worlds") def test_read_twoline_fail(): """Test failure if too many different character are on position line. The position line shall consist of only one character in addition to the delimiter. """ table = """ | Col1 | Col2 | |------|==========| | 1.2 | "hello" | | 2.4 | 's worlds| """ with pytest.raises(InconsistentTableError) as excinfo: ascii.read(table, Reader=ascii.FixedWidthTwoLine, delimiter='|', guess=False) assert 'Position line should only contain delimiters and one other character' in str( excinfo.value) def test_read_twoline_wrong_marker(): '''Test failure when position line uses characters prone to ambiguity Characters in position line must be part an allowed set because normal letters or numbers will lead to ambiguous tables. ''' table = """ | Col1 | Col2 | |aaaaaa|aaaaaaaaaa| | 1.2 | "hello" | | 2.4 | 's worlds| """ with pytest.raises(InconsistentTableError) as excinfo: ascii.read(table, Reader=ascii.FixedWidthTwoLine, delimiter='|', guess=False) assert 'Characters in position line must be part' in str(excinfo.value) def test_write_twoline_normal(): """Write a table as a normal fixed width table.""" out = StringIO() ascii.write(dat, out, Writer=ascii.FixedWidthTwoLine) assert_equal_splitlines(out.getvalue(), """\ Col1 Col2 Col3 Col4 ---- --------- ---- ---- 1.2 "hello" 1 a 2.4 's worlds 2 2 """) def test_write_twoline_no_pad(): """Write a table as a fixed width table with no padding.""" out = StringIO() ascii.write(dat, out, Writer=ascii.FixedWidthTwoLine, delimiter_pad=' ', position_char='=') assert_equal_splitlines(out.getvalue(), """\ Col1 Col2 Col3 Col4 ==== ========= ==== ==== 1.2 "hello" 1 a 2.4 's worlds 2 2 """) def test_write_twoline_no_bookend(): """Write a table as a fixed width table with no bookend.""" out = StringIO() ascii.write(dat, out, Writer=ascii.FixedWidthTwoLine, bookend=True, delimiter='|') assert_equal_splitlines(out.getvalue(), """\ |Col1| Col2|Col3|Col4| |----|---------|----|----| | 1.2| "hello"| 1| a| | 2.4|'s worlds| 2| 2| """) def test_fixedwidthnoheader_splitting(): """Test fix in #8511 where data_start is being ignored""" tbl = """\ AAA y z 1 2 3 4 5 6 7 8 9 """ names = ['a', 'b', 'c'] dat = ascii.read(tbl, data_start=1, data_end=3, delimiter=' ', names=names, format='fixed_width_no_header') assert dat.colnames == names assert np.all(dat['a'] == [1, 4]) assert np.all(dat['b'] == [2, 5]) assert np.all(dat['c'] == [3, 6]) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/io/ascii/tests/test_html.py0000644000175100001710000005355300000000000021177 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """ This module tests some of the methods related to the ``HTML`` reader/writer and aims to document its functionality. Requires `BeautifulSoup `_ to be installed. """ from io import StringIO from astropy.io.ascii import html from astropy.io.ascii import core from astropy.table import Table import pytest import numpy as np from .common import setup_function, teardown_function # noqa from astropy.io import ascii from astropy.utils.compat.optional_deps import HAS_BLEACH, HAS_BS4 # noqa if HAS_BS4: from bs4 import BeautifulSoup, FeatureNotFound @pytest.mark.skipif('not HAS_BS4') def test_soupstring(): """ Test to make sure the class SoupString behaves properly. """ soup = BeautifulSoup('

foo

', 'html.parser') soup_str = html.SoupString(soup) assert isinstance(soup_str, str) assert isinstance(soup_str, html.SoupString) assert soup_str == '

foo

' assert soup_str.soup is soup def test_listwriter(): """ Test to make sure the class ListWriter behaves properly. """ lst = [] writer = html.ListWriter(lst) for i in range(5): writer.write(i) for ch in 'abcde': writer.write(ch) assert lst == [0, 1, 2, 3, 4, 'a', 'b', 'c', 'd', 'e'] @pytest.mark.skipif('not HAS_BS4') def test_identify_table(): """ Test to make sure that identify_table() returns whether the given BeautifulSoup tag is the correct table to process. """ # Should return False on non-
tags and None soup = BeautifulSoup('', 'html.parser') assert html.identify_table(soup, {}, 0) is False assert html.identify_table(None, {}, 0) is False soup = BeautifulSoup('
' '
A
B
', 'html.parser').table assert html.identify_table(soup, {}, 2) is False assert html.identify_table(soup, {}, 1) is True # Default index of 1 # Same tests, but with explicit parameter assert html.identify_table(soup, {'table_id': 2}, 1) is False assert html.identify_table(soup, {'table_id': 1}, 1) is True # Test identification by string ID assert html.identify_table(soup, {'table_id': 'bar'}, 1) is False assert html.identify_table(soup, {'table_id': 'foo'}, 1) is True @pytest.mark.skipif('not HAS_BS4') def test_missing_data(): """ Test reading a table with missing data """ # First with default where blank => '0' table_in = ['', '', '', '', '
A
1
'] dat = Table.read(table_in, format='ascii.html') assert dat.masked is False assert np.all(dat['A'].mask == [True, False]) assert dat['A'].dtype.kind == 'i' # Now with a specific value '...' => missing table_in = ['', '', '', '', '
A
...
1
'] dat = Table.read(table_in, format='ascii.html', fill_values=[('...', '0')]) assert dat.masked is False assert np.all(dat['A'].mask == [True, False]) assert dat['A'].dtype.kind == 'i' @pytest.mark.skipif('not HAS_BS4') def test_rename_cols(): """ Test reading a table and renaming cols """ table_in = ['', '', '', '
A B
12
'] # Swap column names dat = Table.read(table_in, format='ascii.html', names=['B', 'A']) assert dat.colnames == ['B', 'A'] assert len(dat) == 1 # Swap column names and only include A (the renamed version) dat = Table.read(table_in, format='ascii.html', names=['B', 'A'], include_names=['A']) assert dat.colnames == ['A'] assert len(dat) == 1 assert np.all(dat['A'] == 2) @pytest.mark.skipif('not HAS_BS4') def test_no_names(): """ Test reading a table with no column header """ table_in = ['', '', '', '
1
2
'] dat = Table.read(table_in, format='ascii.html') assert dat.colnames == ['col1'] assert len(dat) == 2 dat = Table.read(table_in, format='ascii.html', names=['a']) assert dat.colnames == ['a'] assert len(dat) == 2 @pytest.mark.skipif('not HAS_BS4') def test_identify_table_fail(): """ Raise an exception with an informative error message if table_id is not found. """ table_in = ['', '
A
B
'] with pytest.raises(core.InconsistentTableError) as err: Table.read(table_in, format='ascii.html', htmldict={'table_id': 'bad_id'}, guess=False) assert err.match("ERROR: HTML table id 'bad_id' not found$") with pytest.raises(core.InconsistentTableError) as err: Table.read(table_in, format='ascii.html', htmldict={'table_id': 3}, guess=False) assert err.match("ERROR: HTML table number 3 not found$") @pytest.mark.skipif('not HAS_BS4') def test_backend_parsers(): """ Make sure the user can specify which back-end parser to use and that an error is raised if the parser is invalid. """ for parser in ('lxml', 'xml', 'html.parser', 'html5lib'): try: Table.read('data/html2.html', format='ascii.html', htmldict={'parser': parser}, guess=False) except FeatureNotFound: if parser == 'html.parser': raise # otherwise ignore if the dependency isn't present # reading should fail if the parser is invalid with pytest.raises(FeatureNotFound): Table.read('data/html2.html', format='ascii.html', htmldict={'parser': 'foo'}, guess=False) @pytest.mark.skipif('HAS_BS4') def test_htmlinputter_no_bs4(): """ This should return an OptionalTableImportError if BeautifulSoup is not installed. """ inputter = html.HTMLInputter() with pytest.raises(core.OptionalTableImportError): inputter.process_lines([]) @pytest.mark.skipif('not HAS_BS4') def test_htmlinputter(): """ Test to ensure that HTMLInputter correctly converts input into a list of SoupStrings representing table elements. """ f = 'data/html.html' with open(f) as fd: table = fd.read() inputter = html.HTMLInputter() inputter.html = {} # In absence of table_id, defaults to the first table expected = ['Column 1Column 2Column 3', '1a1.05', '2b2.75', '3c-1.25'] assert [str(x) for x in inputter.get_lines(table)] == expected # Should raise an InconsistentTableError if the table is not found inputter.html = {'table_id': 4} with pytest.raises(core.InconsistentTableError): inputter.get_lines(table) # Identification by string ID inputter.html['table_id'] = 'second' expected = ['Column AColumn BColumn C', '4d10.5', '5e27.5', '6f-12.5'] assert [str(x) for x in inputter.get_lines(table)] == expected # Identification by integer index inputter.html['table_id'] = 3 expected = ['C1C2C3', '7g105.0', '8h275.0', '9i-125.0'] assert [str(x) for x in inputter.get_lines(table)] == expected @pytest.mark.skipif('not HAS_BS4') def test_htmlsplitter(): """ Test to make sure that HTMLSplitter correctly inputs lines of type SoupString to return a generator that gives all header and data elements. """ splitter = html.HTMLSplitter() lines = [html.SoupString(BeautifulSoup('
Col 1Col 2
', 'html.parser').tr), html.SoupString(BeautifulSoup('
Data 1Data 2
', 'html.parser').tr)] expected_data = [['Col 1', 'Col 2'], ['Data 1', 'Data 2']] assert list(splitter(lines)) == expected_data # Make sure the presence of a non-SoupString triggers a TypeError lines.append('Data 3Data 4') with pytest.raises(TypeError): list(splitter(lines)) # Make sure that passing an empty list triggers an error with pytest.raises(core.InconsistentTableError): list(splitter([])) @pytest.mark.skipif('not HAS_BS4') def test_htmlheader_start(): """ Test to ensure that the start_line method of HTMLHeader returns the first line of header data. Uses t/html.html for sample input. """ f = 'data/html.html' with open(f) as fd: table = fd.read() inputter = html.HTMLInputter() inputter.html = {} header = html.HTMLHeader() lines = inputter.get_lines(table) assert str(lines[header.start_line(lines)]) == \ 'Column 1Column 2Column 3' inputter.html['table_id'] = 'second' lines = inputter.get_lines(table) assert str(lines[header.start_line(lines)]) == \ 'Column AColumn BColumn C' inputter.html['table_id'] = 3 lines = inputter.get_lines(table) assert str(lines[header.start_line(lines)]) == \ 'C1C2C3' # start_line should return None if no valid header is found lines = [html.SoupString(BeautifulSoup('
Data
', 'html.parser').tr), html.SoupString(BeautifulSoup('

Text

', 'html.parser').p)] assert header.start_line(lines) is None # Should raise an error if a non-SoupString is present lines.append('Header') with pytest.raises(TypeError): header.start_line(lines) @pytest.mark.skipif('not HAS_BS4') def test_htmldata(): """ Test to ensure that the start_line and end_lines methods of HTMLData returns the first line of table data. Uses t/html.html for sample input. """ f = 'data/html.html' with open(f) as fd: table = fd.read() inputter = html.HTMLInputter() inputter.html = {} data = html.HTMLData() lines = inputter.get_lines(table) assert str(lines[data.start_line(lines)]) == \ '1a1.05' # end_line returns the index of the last data element + 1 assert str(lines[data.end_line(lines) - 1]) == \ '3c-1.25' inputter.html['table_id'] = 'second' lines = inputter.get_lines(table) assert str(lines[data.start_line(lines)]) == \ '4d10.5' assert str(lines[data.end_line(lines) - 1]) == \ '6f-12.5' inputter.html['table_id'] = 3 lines = inputter.get_lines(table) assert str(lines[data.start_line(lines)]) == \ '7g105.0' assert str(lines[data.end_line(lines) - 1]) == \ '9i-125.0' # start_line should raise an error if no table data exists lines = [html.SoupString(BeautifulSoup('
', 'html.parser').div), html.SoupString(BeautifulSoup('

Text

', 'html.parser').p)] with pytest.raises(core.InconsistentTableError): data.start_line(lines) # end_line should return None if no table data exists assert data.end_line(lines) is None # Should raise an error if a non-SoupString is present lines.append('Data') with pytest.raises(TypeError): data.start_line(lines) with pytest.raises(TypeError): data.end_line(lines) def test_multicolumn_write(): """ Test to make sure that the HTML writer writes multidimensional columns (those with iterable elements) using the colspan attribute of . """ col1 = [1, 2, 3] col2 = [(1.0, 1.0), (2.0, 2.0), (3.0, 3.0)] col3 = [('a', 'a', 'a'), ('b', 'b', 'b'), ('c', 'c', 'c')] table = Table([col1, col2, col3], names=('C1', 'C2', 'C3')) expected = """\
C1 C2 C3
1 1.0 1.0 a a a
2 2.0 2.0 b b b
3 3.0 3.0 c c c
""" out = html.HTML().write(table)[0].strip() assert out == expected.strip() @pytest.mark.skipif('not HAS_BLEACH') def test_multicolumn_write_escape(): """ Test to make sure that the HTML writer writes multidimensional columns (those with iterable elements) using the colspan attribute of . """ col1 = [1, 2, 3] col2 = [(1.0, 1.0), (2.0, 2.0), (3.0, 3.0)] col3 = [('', '', 'a'), ('', 'b', 'b'), ('c', 'c', 'c')] table = Table([col1, col2, col3], names=('C1', 'C2', 'C3')) expected = """\
C1 C2 C3
1 1.0 1.0 a
2 2.0 2.0 b b
3 3.0 3.0 c c c
""" out = html.HTML(htmldict={'raw_html_cols': 'C3'}).write(table)[0].strip() assert out == expected.strip() def test_write_no_multicols(): """ Test to make sure that the HTML writer will not use multi-dimensional columns if the multicol parameter is False. """ col1 = [1, 2, 3] col2 = [(1.0, 1.0), (2.0, 2.0), (3.0, 3.0)] col3 = [('a', 'a', 'a'), ('b', 'b', 'b'), ('c', 'c', 'c')] table = Table([col1, col2, col3], names=('C1', 'C2', 'C3')) expected = """\
C1 C2 C3
1 1.0 .. 1.0 a .. a
2 2.0 .. 2.0 b .. b
3 3.0 .. 3.0 c .. c
""" assert html.HTML({'multicol': False}).write(table)[0].strip() == \ expected.strip() @pytest.mark.skipif('not HAS_BS4') def test_multicolumn_read(): """ Test to make sure that the HTML reader inputs multidimensional columns (those with iterable elements) using the colspan attribute of . Ensure that any string element within a multidimensional column casts all elements to string prior to type conversion operations. """ table = Table.read('data/html2.html', format='ascii.html') str_type = np.dtype((str, 21)) expected = Table(np.array([(['1', '2.5000000000000000001'], 3), (['1a', '1'], 3.5)], dtype=[('A', str_type, (2,)), ('B', 'x'], ['y']], names=['a', 'b']) # One column contains raw HTML (string input) out = StringIO() t.write(out, format='ascii.html', htmldict={'raw_html_cols': 'a'}) expected = """\ x <em>y</em> """ assert expected in out.getvalue() # One column contains raw HTML (list input) out = StringIO() t.write(out, format='ascii.html', htmldict={'raw_html_cols': ['a']}) assert expected in out.getvalue() # Two columns contains raw HTML (list input) out = StringIO() t.write(out, format='ascii.html', htmldict={'raw_html_cols': ['a', 'b']}) expected = """\ x y """ assert expected in out.getvalue() @pytest.mark.skipif('not HAS_BLEACH') def test_raw_html_write_clean(): """ Test that columns can contain raw HTML which is not escaped. """ import bleach # noqa t = Table([[''], ['

y

'], ['y']], names=['a', 'b', 'c']) # Confirm that """ % dict(sorting_script1=_SORTING_SCRIPT_PART_1, sorting_script2=_SORTING_SCRIPT_PART_2) HTML_JS_SCRIPT = _SORTING_SCRIPT_PART_1 + _SORTING_SCRIPT_PART_2 + """ $(document).ready(function() {{ $('#{tid}').dataTable({{ order: [], pageLength: {display_length}, lengthMenu: {display_length_menu}, pagingType: "full_numbers", columnDefs: [{{targets: {sort_columns}, type: "optionalnum"}}] }}); }} ); """ # Default CSS for the JSViewer writer DEFAULT_CSS = """\ body {font-family: sans-serif;} table.dataTable {width: auto !important; margin: 0 !important;} .dataTables_filter, .dataTables_paginate {float: left !important; margin-left:1em} """ # Default CSS used when rendering a table in the IPython notebook DEFAULT_CSS_NB = """\ table.dataTable {clear: both; width: auto !important; margin: 0 !important;} .dataTables_info, .dataTables_length, .dataTables_filter, .dataTables_paginate{ display: inline-block; margin-right: 1em; } .paginate_button { margin-right: 5px; } """ class JSViewer: """Provides an interactive HTML export of a Table. This class provides an interface to the `DataTables `_ library, which allow to visualize interactively an HTML table. It is used by the `~astropy.table.Table.show_in_browser` method. Parameters ---------- use_local_files : bool, optional Use local files or a CDN for JavaScript libraries. Default False. display_length : int, optional Number or rows to show. Default to 50. """ def __init__(self, use_local_files=False, display_length=50): self._use_local_files = use_local_files self.display_length_menu = [[10, 25, 50, 100, 500, 1000, -1], [10, 25, 50, 100, 500, 1000, "All"]] self.display_length = display_length for L in self.display_length_menu: if display_length not in L: L.insert(0, display_length) @property def jquery_urls(self): if self._use_local_files: return ['file://' + join(EXTERN_JS_DIR, 'jquery-3.1.1.min.js'), 'file://' + join(EXTERN_JS_DIR, 'jquery.dataTables.min.js')] else: return [conf.jquery_url, conf.datatables_url] @property def css_urls(self): if self._use_local_files: return ['file://' + join(EXTERN_CSS_DIR, 'jquery.dataTables.css')] else: return conf.css_urls def _jstable_file(self): if self._use_local_files: return 'file://' + join(EXTERN_JS_DIR, 'jquery.dataTables.min') else: return conf.datatables_url[:-3] def ipynb(self, table_id, css=None, sort_columns='[]'): html = f'' html += IPYNB_JS_SCRIPT.format( display_length=self.display_length, display_length_menu=self.display_length_menu, datatables_url=self._jstable_file(), tid=table_id, sort_columns=sort_columns) return html def html_js(self, table_id='table0', sort_columns='[]'): return HTML_JS_SCRIPT.format( display_length=self.display_length, display_length_menu=self.display_length_menu, tid=table_id, sort_columns=sort_columns).strip() def write_table_jsviewer(table, filename, table_id=None, max_lines=5000, table_class="display compact", jskwargs=None, css=DEFAULT_CSS, htmldict=None, overwrite=False): if table_id is None: table_id = f'table{id(table)}' jskwargs = jskwargs or {} jsv = JSViewer(**jskwargs) sortable_columns = [i for i, col in enumerate(table.columns.values()) if col.info.dtype.kind in 'iufc'] html_options = { 'table_id': table_id, 'table_class': table_class, 'css': css, 'cssfiles': jsv.css_urls, 'jsfiles': jsv.jquery_urls, 'js': jsv.html_js(table_id=table_id, sort_columns=sortable_columns) } if htmldict: html_options.update(htmldict) if max_lines < len(table): table = table[:max_lines] table.write(filename, format='html', htmldict=html_options, overwrite=overwrite) io_registry.register_writer('jsviewer', Table, write_table_jsviewer) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/meta.py0000644000175100001710000003310200000000000016334 0ustar00vstsdockerimport json import textwrap import copy from collections import OrderedDict import numpy as np import yaml __all__ = ['get_header_from_yaml', 'get_yaml_from_header', 'get_yaml_from_table'] class ColumnOrderList(list): """ List of tuples that sorts in a specific order that makes sense for astropy table column attributes. """ def sort(self, *args, **kwargs): super().sort() column_keys = ['name', 'unit', 'datatype', 'format', 'description', 'meta'] in_dict = dict(self) out_list = [] for key in column_keys: if key in in_dict: out_list.append((key, in_dict[key])) for key, val in self: if key not in column_keys: out_list.append((key, val)) # Clear list in-place del self[:] self.extend(out_list) class ColumnDict(dict): """ Specialized dict subclass to represent attributes of a Column and return items() in a preferred order. This is only for use in generating a YAML map representation that has a fixed order. """ def items(self): """ Return items as a ColumnOrderList, which sorts in the preferred way for column attributes. """ return ColumnOrderList(super().items()) def _construct_odict(load, node): """ Construct OrderedDict from !!omap in yaml safe load. Source: https://gist.github.com/weaver/317164 License: Unspecified This is the same as SafeConstructor.construct_yaml_omap(), except the data type is changed to OrderedDict() and setitem is used instead of append in the loop Examples -------- :: >>> yaml.load(''' # doctest: +SKIP ... !!omap ... - foo: bar ... - mumble: quux ... - baz: gorp ... ''') OrderedDict([('foo', 'bar'), ('mumble', 'quux'), ('baz', 'gorp')]) >>> yaml.load('''!!omap [ foo: bar, mumble: quux, baz : gorp ]''') # doctest: +SKIP OrderedDict([('foo', 'bar'), ('mumble', 'quux'), ('baz', 'gorp')]) """ omap = OrderedDict() yield omap if not isinstance(node, yaml.SequenceNode): raise yaml.constructor.ConstructorError( "while constructing an ordered map", node.start_mark, f"expected a sequence, but found {node.id}", node.start_mark) for subnode in node.value: if not isinstance(subnode, yaml.MappingNode): raise yaml.constructor.ConstructorError( "while constructing an ordered map", node.start_mark, f"expected a mapping of length 1, but found {subnode.id}", subnode.start_mark) if len(subnode.value) != 1: raise yaml.constructor.ConstructorError( "while constructing an ordered map", node.start_mark, f"expected a single mapping item, but found {len(subnode.value)} items", subnode.start_mark) key_node, value_node = subnode.value[0] key = load.construct_object(key_node) value = load.construct_object(value_node) omap[key] = value def _repr_pairs(dump, tag, sequence, flow_style=None): """ This is the same code as BaseRepresenter.represent_sequence(), but the value passed to dump.represent_data() in the loop is a dictionary instead of a tuple. Source: https://gist.github.com/weaver/317164 License: Unspecified """ value = [] node = yaml.SequenceNode(tag, value, flow_style=flow_style) if dump.alias_key is not None: dump.represented_objects[dump.alias_key] = node best_style = True for (key, val) in sequence: item = dump.represent_data({key: val}) if not (isinstance(item, yaml.ScalarNode) and not item.style): best_style = False value.append(item) if flow_style is None: if dump.default_flow_style is not None: node.flow_style = dump.default_flow_style else: node.flow_style = best_style return node def _repr_odict(dumper, data): """ Represent OrderedDict in yaml dump. Source: https://gist.github.com/weaver/317164 License: Unspecified >>> data = OrderedDict([('foo', 'bar'), ('mumble', 'quux'), ('baz', 'gorp')]) >>> yaml.dump(data, default_flow_style=False) # doctest: +SKIP '!!omap\\n- foo: bar\\n- mumble: quux\\n- baz: gorp\\n' >>> yaml.dump(data, default_flow_style=True) # doctest: +SKIP '!!omap [foo: bar, mumble: quux, baz: gorp]\\n' """ return _repr_pairs(dumper, 'tag:yaml.org,2002:omap', data.items()) def _repr_column_dict(dumper, data): """ Represent ColumnDict in yaml dump. This is the same as an ordinary mapping except that the keys are written in a fixed order that makes sense for astropy table columns. """ return dumper.represent_mapping('tag:yaml.org,2002:map', data) def _get_variable_length_array_shape(col): """Check if object-type ``col`` is really a variable length list. That is true if the object consists purely of list of nested lists, where the shape of every item can be represented as (m, n, ..., *) where the (m, n, ...) are constant and only the lists in the last axis have variable shape. If so the returned value of shape will be a tuple in the form (m, n, ..., None). If ``col`` is a variable length array then the return ``dtype`` corresponds to the type found by numpy for all the individual values. Otherwise it will be ``np.dtype(object)``. Parameters ========== col : column-like Input table column, assumed to be object-type Returns ======= shape : tuple Inferred variable length shape or None dtype : np.dtype Numpy dtype that applies to col """ class ConvertError(ValueError): """Local conversion error used below""" # Numpy types supported as variable-length arrays np_classes = (np.floating, np.integer, np.bool_, np.unicode_) try: if len(col) == 0 or not all(isinstance(val, np.ndarray) for val in col): raise ConvertError dtype = col[0].dtype shape = col[0].shape[:-1] for val in col: if not issubclass(val.dtype.type, np_classes) or val.shape[:-1] != shape: raise ConvertError dtype = np.promote_types(dtype, val.dtype) shape = shape + (None,) except ConvertError: # `col` is not a variable length array, return shape and dtype to # the original. Note that this function is only called if # col.shape[1:] was () and col.info.dtype is object. dtype = col.info.dtype shape = () return shape, dtype def _get_datatype_from_dtype(dtype): """Return string version of ``dtype`` for writing to ECSV ``datatype``""" datatype = dtype.name if datatype.startswith(('bytes', 'str')): datatype = 'string' if datatype.endswith('_'): datatype = datatype[:-1] # string_ and bool_ lose the final _ for ECSV return datatype def _get_col_attributes(col): """ Extract information from a column (apart from the values) that is required to fully serialize the column. Parameters ---------- col : column-like Input Table column Returns ------- attrs : dict Dict of ECSV attributes for ``col`` """ dtype = col.info.dtype # Type of column values that get written subtype = None # Type of data for object columns serialized with JSON shape = col.shape[1:] # Shape of multidim / variable length columns if dtype.name == 'object': if shape == (): # 1-d object type column might be a variable length array dtype = np.dtype(str) shape, subtype = _get_variable_length_array_shape(col) else: # N-d object column is subtype object but serialized as JSON string dtype = np.dtype(str) subtype = np.dtype(object) elif shape: # N-d column which is not object is serialized as JSON string dtype = np.dtype(str) subtype = col.info.dtype datatype = _get_datatype_from_dtype(dtype) # Set the output attributes attrs = ColumnDict() attrs['name'] = col.info.name attrs['datatype'] = datatype for attr, nontrivial, xform in (('unit', lambda x: x is not None, str), ('format', lambda x: x is not None, None), ('description', lambda x: x is not None, None), ('meta', lambda x: x, None)): col_attr = getattr(col.info, attr) if nontrivial(col_attr): attrs[attr] = xform(col_attr) if xform else col_attr if subtype: attrs['subtype'] = _get_datatype_from_dtype(subtype) # Numpy 'object' maps to 'subtype' of 'json' in ECSV if attrs['subtype'] == 'object': attrs['subtype'] = 'json' if shape: attrs['subtype'] += json.dumps(list(shape), separators=(',', ':')) return attrs def get_yaml_from_table(table): """ Return lines with a YAML representation of header content from the ``table``. Parameters ---------- table : `~astropy.table.Table` object Table for which header content is output Returns ------- lines : list List of text lines with YAML header content """ header = {'cols': list(table.columns.values())} if table.meta: header['meta'] = table.meta return get_yaml_from_header(header) def get_yaml_from_header(header): """ Return lines with a YAML representation of header content from a Table. The ``header`` dict must contain these keys: - 'cols' : list of table column objects (required) - 'meta' : table 'meta' attribute (optional) Other keys included in ``header`` will be serialized in the output YAML representation. Parameters ---------- header : dict Table header content Returns ------- lines : list List of text lines with YAML header content """ from astropy.io.misc.yaml import AstropyDumper class TableDumper(AstropyDumper): """ Custom Dumper that represents OrderedDict as an !!omap object. """ def represent_mapping(self, tag, mapping, flow_style=None): """ This is a combination of the Python 2 and 3 versions of this method in the PyYAML library to allow the required key ordering via the ColumnOrderList object. The Python 3 version insists on turning the items() mapping into a list object and sorting, which results in alphabetical order for the column keys. """ value = [] node = yaml.MappingNode(tag, value, flow_style=flow_style) if self.alias_key is not None: self.represented_objects[self.alias_key] = node best_style = True if hasattr(mapping, 'items'): mapping = mapping.items() if hasattr(mapping, 'sort'): mapping.sort() else: mapping = list(mapping) try: mapping = sorted(mapping) except TypeError: pass for item_key, item_value in mapping: node_key = self.represent_data(item_key) node_value = self.represent_data(item_value) if not (isinstance(node_key, yaml.ScalarNode) and not node_key.style): best_style = False if not (isinstance(node_value, yaml.ScalarNode) and not node_value.style): best_style = False value.append((node_key, node_value)) if flow_style is None: if self.default_flow_style is not None: node.flow_style = self.default_flow_style else: node.flow_style = best_style return node TableDumper.add_representer(OrderedDict, _repr_odict) TableDumper.add_representer(ColumnDict, _repr_column_dict) header = copy.copy(header) # Don't overwrite original header['datatype'] = [_get_col_attributes(col) for col in header['cols']] del header['cols'] lines = yaml.dump(header, default_flow_style=None, Dumper=TableDumper, width=130).splitlines() return lines class YamlParseError(Exception): pass def get_header_from_yaml(lines): """ Get a header dict from input ``lines`` which should be valid YAML. This input will typically be created by get_yaml_from_header. The output is a dictionary which describes all the table and column meta. The get_cols() method in the io/ascii/ecsv.py file should be used as a guide to using the information when constructing a table using this header dict information. Parameters ---------- lines : list List of text lines with YAML header content Returns ------- header : dict Dictionary describing table and column meta """ from astropy.io.misc.yaml import AstropyLoader class TableLoader(AstropyLoader): """ Custom Loader that constructs OrderedDict from an !!omap object. This does nothing but provide a namespace for adding the custom odict constructor. """ TableLoader.add_constructor('tag:yaml.org,2002:omap', _construct_odict) # Now actually load the YAML data structure into `meta` header_yaml = textwrap.dedent('\n'.join(lines)) try: header = yaml.load(header_yaml, Loader=TableLoader) except Exception as err: raise YamlParseError() from err return header ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1632512 astropy-5.0.2/astropy/table/mixins/0000755000175100001710000000000000000000000016344 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/mixins/__init__.py0000644000175100001710000000000000000000000020443 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/mixins/dask.py0000644000175100001710000000201700000000000017640 0ustar00vstsdockerimport dask.array as da from astropy.utils.data_info import ParentDtypeInfo __all__ = ['as_dask_column'] class DaskInfo(ParentDtypeInfo): @staticmethod def default_format(val): return f'{val.compute()}' class DaskColumn(da.Array): info = DaskInfo() def copy(self): # Array hard-codes the resulting copied array as Array, so need to # overload this since Table tries to copy the array. return as_dask_column(self, info=self.info) def __getitem__(self, item): result = super().__getitem__(item) if isinstance(item, int): return result else: return as_dask_column(result, info=self.info) def insert(self, obj, values, axis=0): return as_dask_column(da.insert(self, obj, values, axis=axis), info=self.info) def as_dask_column(array, info=None): result = DaskColumn(array.dask, array.name, array.chunks, meta=array) if info is not None: result.info = info return result ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/mixins/registry.py0000644000175100001710000000521300000000000020567 0ustar00vstsdocker# This module handles the definition of mixin 'handlers' which are functions # that given an arbitrary object (e.g. a dask array) will return an object that # can be used as a mixin column. This is useful because it means that users can # then add objects to tables that are not formally mixin columns and where # adding an info attribute is beyond our control. __all__ = ['MixinRegistryError', 'register_mixin_handler', 'get_mixin_handler'] # The internal dictionary of handlers maps fully qualified names of classes # to a function that can take an object and return a mixin-compatible object. _handlers = {} class MixinRegistryError(Exception): pass def register_mixin_handler(fully_qualified_name, handler, force=False): """ Register a mixin column 'handler'. A mixin column handler is a function that given an arbitrary Python object, will return an object with the .info attribute that can then be used as a mixin column (this can be e.g. a copy of the object with a new attribute, a subclass instance, or a wrapper class - this is left up to the handler). The handler will be used on classes that have an exactly matching fully qualified name. Parameters ---------- fully_qualified_name : str The fully qualified name of the class that the handler can operate on, such as e.g. ``dask.array.core.Array``. handler : func The handler function. force : bool, optional Whether to overwrite any previous handler if there is already one for the same fully qualified name. """ if fully_qualified_name not in _handlers or force: _handlers[fully_qualified_name] = handler else: raise MixinRegistryError(f"Handler for class {fully_qualified_name} is already defined") def get_mixin_handler(obj): """ Given an arbitrary object, return the matching mixin handler (if any). Parameters ---------- obj : object or str The object to find a mixin handler for, or a fully qualified name. Returns ------- handler : None or func Then matching handler, if found, or `None` """ if isinstance(obj, str): return _handlers.get(obj, None) else: return _handlers.get(obj.__class__.__module__ + '.' + obj.__class__.__name__, None) # Add built-in handlers to registry. Note that any third-party package imports # required by the handlers should go inside the handler function to delay # the imports until they are actually needed. def dask_handler(arr): from astropy.table.mixins.dask import as_dask_column return as_dask_column(arr) register_mixin_handler('dask.array.core.Array', dask_handler) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1672513 astropy-5.0.2/astropy/table/mixins/tests/0000755000175100001710000000000000000000000017506 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/mixins/tests/__init__.py0000644000175100001710000000000000000000000021605 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/mixins/tests/test_dask.py0000644000175100001710000000366400000000000022052 0ustar00vstsdockerimport pytest import numpy as np from numpy.testing import assert_equal from astropy.table import Table da = pytest.importorskip('dask.array') class TestDaskHandler: def setup_method(self, method): self.t = Table() self.t['a'] = da.arange(10) def test_add_row(self): self.t.add_row(self.t[0]) assert_equal(self.t['a'].compute(), np.hstack([np.arange(10), 0])) def test_get_column(self): assert isinstance(self.t['a'], da.Array) assert_equal(self.t['a'].compute(), np.arange(10)) def test_slicing_row_single(self): sub = self.t[5] assert isinstance(sub['a'], da.Array) assert not hasattr(sub['a'], 'info') # should be a plain dask array assert sub['a'].compute() == 5 def test_slicing_row_range(self): sub = self.t[5:] assert isinstance(sub['a'], da.Array) assert hasattr(sub['a'], 'info') # should be a mixin column assert_equal(sub['a'].compute(), np.arange(5, 10)) def test_slicing_column_range(self): sub = self.t[('a',)] assert isinstance(sub['a'], da.Array) assert hasattr(sub['a'], 'info') # should be a mixin column assert_equal(sub['a'].compute(), np.arange(10)) def test_pformat(self): assert self.t.pformat_all() == [' a ', '---', ' 0', ' 1', ' 2', ' 3', ' 4', ' 5', ' 6', ' 7', ' 8', ' 9'] def test_info_preserved(self): self.t['a'].info.description = 'A dask column' sub = self.t[1:3] assert sub['a'].info.name == 'a' assert sub['a'].info.description == 'A dask column' col = self.t['a'].copy() assert col.info.name == 'a' assert col.info.description == 'A dask column' self.t.add_row(self.t[0]) assert self.t['a'].info.name == 'a' assert self.t['a'].info.description == 'A dask column' ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/mixins/tests/test_registry.py0000644000175100001710000000470000000000000022770 0ustar00vstsdockerfrom copy import copy from unittest.mock import MagicMock import pytest import numpy as np from numpy.testing import assert_equal from astropy.table import Table from astropy.table.table_helpers import ArrayWrapper from astropy.table.mixins.registry import (_handlers, register_mixin_handler, MixinRegistryError, get_mixin_handler) ORIGINAL = {} def setup_function(function): ORIGINAL['handlers'] = copy(_handlers) _handlers.clear() def teardown_function(function): _handlers.clear() _handlers.update(ORIGINAL['handlers']) class SpamData: pass class SpamWrapper(ArrayWrapper): def __init__(self): super().__init__([0, 1, 3, 4, 5]) FULL_QUALNAME = 'astropy.table.mixins.tests.test_registry.SpamData' def handle_spam(obj): return SpamWrapper() def handle_spam_alt(obj): return SpamWrapper() def test_no_handler(): data = SpamData() assert get_mixin_handler(data) is None def test_register_handler(): register_mixin_handler(FULL_QUALNAME, handle_spam) assert get_mixin_handler(SpamData()) is handle_spam def test_register_handler_override(): register_mixin_handler(FULL_QUALNAME, handle_spam) with pytest.raises(MixinRegistryError) as exc: register_mixin_handler(FULL_QUALNAME, handle_spam_alt) assert exc.value.args[0] == 'Handler for class astropy.table.mixins.tests.test_registry.SpamData is already defined' register_mixin_handler(FULL_QUALNAME, handle_spam_alt, force=True) assert get_mixin_handler(SpamData()) is handle_spam_alt def test_get_mixin_handler_str(): # Check that we can also pass a fully qualified name to get_mixin_handler register_mixin_handler(FULL_QUALNAME, handle_spam) assert get_mixin_handler(FULL_QUALNAME) is handle_spam def test_add_column(): t = Table() with pytest.raises(TypeError): t['a'] = SpamData() register_mixin_handler(FULL_QUALNAME, handle_spam) t['a'] = SpamData() assert len(t) == 5 assert isinstance(t['a'], SpamWrapper) assert_equal(t['a'].data, [0, 1, 3, 4, 5]) def invalid_handler(obj): return 'invalid' def test_invalid_handler(): t = Table() register_mixin_handler(FULL_QUALNAME, invalid_handler) with pytest.raises(TypeError) as exc: t['a'] = SpamData() assert exc.value.args[0] == (f'Mixin handler for object of type {FULL_QUALNAME} ' f'did not return a valid mixin column') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/ndarray_mixin.py0000644000175100001710000000417200000000000020257 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import numpy as np from astropy.utils.data_info import ParentDtypeInfo class NdarrayMixinInfo(ParentDtypeInfo): _represent_as_dict_primary_data = 'data' def _represent_as_dict(self): """Represent Column as a dict that can be serialized.""" col = self._parent out = {'data': col.view(np.ndarray)} return out def _construct_from_dict(self, map): """Construct Column from ``map``.""" data = map.pop('data') out = self._parent_cls(data, **map) return out class NdarrayMixin(np.ndarray): """ Mixin column class to allow storage of arbitrary numpy ndarrays within a Table. This is a subclass of numpy.ndarray and has the same initialization options as ``np.array()``. """ info = NdarrayMixinInfo() def __new__(cls, obj, *args, **kwargs): self = np.array(obj, *args, **kwargs).view(cls) if 'info' in getattr(obj, '__dict__', ()): self.info = obj.info return self def __array_finalize__(self, obj): if obj is None: return if callable(super().__array_finalize__): super().__array_finalize__(obj) # Self was created from template (e.g. obj[slice] or (obj * 2)) # or viewcast e.g. obj.view(Column). In either case we want to # init Column attributes for self from obj if possible. if 'info' in getattr(obj, '__dict__', ()): self.info = obj.info def __reduce__(self): # patch to pickle NdArrayMixin objects (ndarray subclasses), see # http://www.mail-archive.com/numpy-discussion@scipy.org/msg02446.html object_state = list(super().__reduce__()) object_state[2] = (object_state[2], self.__dict__) return tuple(object_state) def __setstate__(self, state): # patch to unpickle NdarrayMixin objects (ndarray subclasses), see # http://www.mail-archive.com/numpy-discussion@scipy.org/msg02446.html nd_state, own_state = state super().__setstate__(nd_state) self.__dict__.update(own_state) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/np_utils.py0000644000175100001710000001430300000000000017245 0ustar00vstsdocker""" High-level operations for numpy structured arrays. Some code and inspiration taken from numpy.lib.recfunctions.join_by(). Redistribution license restrictions apply. """ import collections from collections import OrderedDict, Counter from collections.abc import Sequence import numpy as np __all__ = ['TableMergeError'] class TableMergeError(ValueError): pass def get_col_name_map(arrays, common_names, uniq_col_name='{col_name}_{table_name}', table_names=None): """ Find the column names mapping when merging the list of structured ndarrays ``arrays``. It is assumed that col names in ``common_names`` are to be merged into a single column while the rest will be uniquely represented in the output. The args ``uniq_col_name`` and ``table_names`` specify how to rename columns in case of conflicts. Returns a dict mapping each output column name to the input(s). This takes the form {outname : (col_name_0, col_name_1, ...), ... }. For key columns all of input names will be present, while for the other non-key columns the value will be (col_name_0, None, ..) or (None, col_name_1, ..) etc. """ col_name_map = collections.defaultdict(lambda: [None] * len(arrays)) col_name_list = [] if table_names is None: table_names = [str(ii + 1) for ii in range(len(arrays))] for idx, array in enumerate(arrays): table_name = table_names[idx] for name in array.dtype.names: out_name = name if name in common_names: # If name is in the list of common_names then insert into # the column name list, but just once. if name not in col_name_list: col_name_list.append(name) else: # If name is not one of the common column outputs, and it collides # with the names in one of the other arrays, then rename others = list(arrays) others.pop(idx) if any(name in other.dtype.names for other in others): out_name = uniq_col_name.format(table_name=table_name, col_name=name) col_name_list.append(out_name) col_name_map[out_name][idx] = name # Check for duplicate output column names col_name_count = Counter(col_name_list) repeated_names = [name for name, count in col_name_count.items() if count > 1] if repeated_names: raise TableMergeError('Merging column names resulted in duplicates: {}. ' 'Change uniq_col_name or table_names args to fix this.' .format(repeated_names)) # Convert col_name_map to a regular dict with tuple (immutable) values col_name_map = OrderedDict((name, col_name_map[name]) for name in col_name_list) return col_name_map def get_descrs(arrays, col_name_map): """ Find the dtypes descrs resulting from merging the list of arrays' dtypes, using the column name mapping ``col_name_map``. Return a list of descrs for the output. """ out_descrs = [] for out_name, in_names in col_name_map.items(): # List of input arrays that contribute to this output column in_cols = [arr[name] for arr, name in zip(arrays, in_names) if name is not None] # List of names of the columns that contribute to this output column. names = [name for name in in_names if name is not None] # Output dtype is the superset of all dtypes in in_arrays try: dtype = common_dtype(in_cols) except TableMergeError as tme: # Beautify the error message when we are trying to merge columns with incompatible # types by including the name of the columns that originated the error. raise TableMergeError("The '{}' columns have incompatible types: {}" .format(names[0], tme._incompat_types)) from tme # Make sure all input shapes are the same uniq_shapes = set(col.shape[1:] for col in in_cols) if len(uniq_shapes) != 1: raise TableMergeError('Key columns have different shape') shape = uniq_shapes.pop() out_descrs.append((fix_column_name(out_name), dtype, shape)) return out_descrs def common_dtype(cols): """ Use numpy to find the common dtype for a list of structured ndarray columns. Only allow columns within the following fundamental numpy data types: np.bool_, np.object_, np.number, np.character, np.void """ np_types = (np.bool_, np.object_, np.number, np.character, np.void) uniq_types = set(tuple(issubclass(col.dtype.type, np_type) for np_type in np_types) for col in cols) if len(uniq_types) > 1: # Embed into the exception the actual list of incompatible types. incompat_types = [col.dtype.name for col in cols] tme = TableMergeError(f'Columns have incompatible types {incompat_types}') tme._incompat_types = incompat_types raise tme arrs = [np.empty(1, dtype=col.dtype) for col in cols] # For string-type arrays need to explicitly fill in non-zero # values or the final arr_common = .. step is unpredictable. for arr in arrs: if arr.dtype.kind in ('S', 'U'): arr[0] = '0' * arr.itemsize arr_common = np.array([arr[0] for arr in arrs]) return arr_common.dtype.str def _check_for_sequence_of_structured_arrays(arrays): err = '`arrays` arg must be a sequence (e.g. list) of structured arrays' if not isinstance(arrays, Sequence): raise TypeError(err) for array in arrays: # Must be structured array if not isinstance(array, np.ndarray) or array.dtype.names is None: raise TypeError(err) if len(arrays) == 0: raise ValueError('`arrays` arg must include at least one array') def fix_column_name(val): """ Fixes column names so that they are compatible with Numpy on Python 2. Raises a ValueError exception if the column name contains Unicode characters, which can not reasonably be used as a column name. """ if val is not None: try: val = str(val) except UnicodeEncodeError: raise return val ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/operations.py0000644000175100001710000016227500000000000017607 0ustar00vstsdocker""" High-level table operations: - join() - setdiff() - hstack() - vstack() - dstack() """ # Licensed under a 3-clause BSD style license - see LICENSE.rst from copy import deepcopy import collections import itertools from collections import OrderedDict, Counter from collections.abc import Mapping, Sequence import numpy as np from astropy.utils import metadata from astropy.utils.masked import Masked from .table import Table, QTable, Row, Column, MaskedColumn from astropy.units import Quantity from . import _np_utils from .np_utils import fix_column_name, TableMergeError __all__ = ['join', 'setdiff', 'hstack', 'vstack', 'unique', 'join_skycoord', 'join_distance'] __doctest_requires__ = {'join_skycoord': ['scipy'], 'join_distance': ['scipy']} def _merge_table_meta(out, tables, metadata_conflicts='warn'): out_meta = deepcopy(tables[0].meta) for table in tables[1:]: out_meta = metadata.merge(out_meta, table.meta, metadata_conflicts=metadata_conflicts) out.meta.update(out_meta) def _get_list_of_tables(tables): """ Check that tables is a Table or sequence of Tables. Returns the corresponding list of Tables. """ # Make sure we have a list of things if not isinstance(tables, Sequence): tables = [tables] # Make sure there is something to stack if len(tables) == 0: raise ValueError('no values provided to stack.') # Convert inputs (Table, Row, or anything column-like) to Tables. # Special case that Quantity converts to a QTable. for ii, val in enumerate(tables): if isinstance(val, Table): pass elif isinstance(val, Row): tables[ii] = Table(val) elif isinstance(val, Quantity): tables[ii] = QTable([val]) else: try: tables[ii] = Table([val]) except (ValueError, TypeError) as err: raise TypeError(f'Cannot convert {val} to table column.') from err return tables def _get_out_class(objs): """ From a list of input objects ``objs`` get merged output object class. This is just taken as the deepest subclass. This doesn't handle complicated inheritance schemes, but as a special case, classes which share ``info`` are taken to be compatible. """ out_class = objs[0].__class__ for obj in objs[1:]: if issubclass(obj.__class__, out_class): out_class = obj.__class__ if any(not (issubclass(out_class, obj.__class__) or out_class.info is obj.__class__.info) for obj in objs): raise ValueError('unmergeable object classes {}' .format([obj.__class__.__name__ for obj in objs])) return out_class def join_skycoord(distance, distance_func='search_around_sky'): """Helper function to join on SkyCoord columns using distance matching. This function is intended for use in ``table.join()`` to allow performing a table join where the key columns are both ``SkyCoord`` objects, matched by computing the distance between points and accepting values below ``distance``. The distance cross-matching is done using either `~astropy.coordinates.search_around_sky` or `~astropy.coordinates.search_around_3d`, depending on the value of ``distance_func``. The default is ``'search_around_sky'``. One can also provide a function object for ``distance_func``, in which case it must be a function that follows the same input and output API as `~astropy.coordinates.search_around_sky`. In this case the function will be called with ``(skycoord1, skycoord2, distance)`` as arguments. Parameters ---------- distance : `~astropy.units.Quantity` ['angle', 'length'] Maximum distance between points to be considered a join match. Must have angular or distance units. distance_func : str or function Specifies the function for performing the cross-match based on ``distance``. If supplied as a string this specifies the name of a function in `astropy.coordinates`. If supplied as a function then that function is called directly. Returns ------- join_func : function Function that accepts two ``SkyCoord`` columns (col1, col2) and returns the tuple (ids1, ids2) of pair-matched unique identifiers. Examples -------- This example shows an inner join of two ``SkyCoord`` columns, taking any sources within 0.2 deg to be a match. Note the new ``sc_id`` column which is added and provides a unique source identifier for the matches. >>> from astropy.coordinates import SkyCoord >>> import astropy.units as u >>> from astropy.table import Table, join_skycoord >>> from astropy import table >>> sc1 = SkyCoord([0, 1, 1.1, 2], [0, 0, 0, 0], unit='deg') >>> sc2 = SkyCoord([0.5, 1.05, 2.1], [0, 0, 0], unit='deg') >>> join_func = join_skycoord(0.2 * u.deg) >>> join_func(sc1, sc2) # Associate each coordinate with unique source ID (array([3, 1, 1, 2]), array([4, 1, 2])) >>> t1 = Table([sc1], names=['sc']) >>> t2 = Table([sc2], names=['sc']) >>> t12 = table.join(t1, t2, join_funcs={'sc': join_skycoord(0.2 * u.deg)}) >>> print(t12) # Note new `sc_id` column with the IDs from join_func() sc_id sc_1 sc_2 deg,deg deg,deg ----- ------- -------- 1 1.0,0.0 1.05,0.0 1 1.1,0.0 1.05,0.0 2 2.0,0.0 2.1,0.0 """ if isinstance(distance_func, str): import astropy.coordinates as coords try: distance_func = getattr(coords, distance_func) except AttributeError as err: raise ValueError('distance_func must be a function in astropy.coordinates') from err else: from inspect import isfunction if not isfunction(distance_func): raise ValueError('distance_func must be a str or function') def join_func(sc1, sc2): # Call the appropriate SkyCoord method to find pairs within distance idxs1, idxs2, d2d, d3d = distance_func(sc1, sc2, distance) # Now convert that into unique identifiers for each near-pair. This is # taken to be transitive, so that if points 1 and 2 are "near" and points # 1 and 3 are "near", then 1, 2, and 3 are all given the same identifier. # This identifier will then be used in the table join matching. # Identifiers for each column, initialized to all zero. ids1 = np.zeros(len(sc1), dtype=int) ids2 = np.zeros(len(sc2), dtype=int) # Start the identifier count at 1 id_ = 1 for idx1, idx2 in zip(idxs1, idxs2): # If this col1 point is previously identified then set corresponding # col2 point to same identifier. Likewise for col2 and col1. if ids1[idx1] > 0: ids2[idx2] = ids1[idx1] elif ids2[idx2] > 0: ids1[idx1] = ids2[idx2] else: # Not yet seen so set identifier for col1 and col2 ids1[idx1] = id_ ids2[idx2] = id_ id_ += 1 # Fill in unique identifiers for points with no near neighbor for ids in (ids1, ids2): for idx in np.flatnonzero(ids == 0): ids[idx] = id_ id_ += 1 # End of enclosure join_func() return ids1, ids2 return join_func def join_distance(distance, kdtree_args=None, query_args=None): """Helper function to join table columns using distance matching. This function is intended for use in ``table.join()`` to allow performing a table join where the key columns are matched by computing the distance between points and accepting values below ``distance``. This numerical "fuzzy" match can apply to 1-D or 2-D columns, where in the latter case the distance is a vector distance. The distance cross-matching is done using `scipy.spatial.cKDTree`. If necessary you can tweak the default behavior by providing ``dict`` values for the ``kdtree_args`` or ``query_args``. Parameters ---------- distance : float or `~astropy.units.Quantity` ['length'] Maximum distance between points to be considered a join match kdtree_args : dict, None Optional extra args for `~scipy.spatial.cKDTree` query_args : dict, None Optional extra args for `~scipy.spatial.cKDTree.query_ball_tree` Returns ------- join_func : function Function that accepts (skycoord1, skycoord2) and returns the tuple (ids1, ids2) of pair-matched unique identifiers. Examples -------- >>> from astropy.table import Table, join_distance >>> from astropy import table >>> c1 = [0, 1, 1.1, 2] >>> c2 = [0.5, 1.05, 2.1] >>> t1 = Table([c1], names=['col']) >>> t2 = Table([c2], names=['col']) >>> t12 = table.join(t1, t2, join_type='outer', join_funcs={'col': join_distance(0.2)}) >>> print(t12) col_id col_1 col_2 ------ ----- ----- 1 1.0 1.05 1 1.1 1.05 2 2.0 2.1 3 0.0 -- 4 -- 0.5 """ try: from scipy.spatial import cKDTree except ImportError as exc: raise ImportError('scipy is required to use join_distance()') from exc if kdtree_args is None: kdtree_args = {} if query_args is None: query_args = {} def join_func(col1, col2): if col1.ndim > 2 or col2.ndim > 2: raise ValueError('columns for isclose_join must be 1- or 2-dimensional') if isinstance(distance, Quantity): # Convert to np.array with common unit col1 = col1.to_value(distance.unit) col2 = col2.to_value(distance.unit) dist = distance.value else: # Convert to np.array to allow later in-place shape changing col1 = np.asarray(col1) col2 = np.asarray(col2) dist = distance # Ensure columns are pure np.array and are 2-D for use with KDTree if col1.ndim == 1: col1.shape = col1.shape + (1,) if col2.ndim == 1: col2.shape = col2.shape + (1,) # Cross-match col1 and col2 within dist using KDTree kd1 = cKDTree(col1, **kdtree_args) kd2 = cKDTree(col2, **kdtree_args) nears = kd1.query_ball_tree(kd2, r=dist, **query_args) # Output of above is nears which is a list of lists, where the outer # list corresponds to each item in col1, and where the inner lists are # indexes into col2 of elements within the distance tolerance. This # identifies col1 / col2 near pairs. # Now convert that into unique identifiers for each near-pair. This is # taken to be transitive, so that if points 1 and 2 are "near" and points # 1 and 3 are "near", then 1, 2, and 3 are all given the same identifier. # This identifier will then be used in the table join matching. # Identifiers for each column, initialized to all zero. ids1 = np.zeros(len(col1), dtype=int) ids2 = np.zeros(len(col2), dtype=int) # Start the identifier count at 1 id_ = 1 for idx1, idxs2 in enumerate(nears): for idx2 in idxs2: # If this col1 point is previously identified then set corresponding # col2 point to same identifier. Likewise for col2 and col1. if ids1[idx1] > 0: ids2[idx2] = ids1[idx1] elif ids2[idx2] > 0: ids1[idx1] = ids2[idx2] else: # Not yet seen so set identifier for col1 and col2 ids1[idx1] = id_ ids2[idx2] = id_ id_ += 1 # Fill in unique identifiers for points with no near neighbor for ids in (ids1, ids2): for idx in np.flatnonzero(ids == 0): ids[idx] = id_ id_ += 1 # End of enclosure join_func() return ids1, ids2 return join_func def join(left, right, keys=None, join_type='inner', *, keys_left=None, keys_right=None, uniq_col_name='{col_name}_{table_name}', table_names=['1', '2'], metadata_conflicts='warn', join_funcs=None): """ Perform a join of the left table with the right table on specified keys. Parameters ---------- left : `~astropy.table.Table`-like object Left side table in the join. If not a Table, will call ``Table(left)`` right : `~astropy.table.Table`-like object Right side table in the join. If not a Table, will call ``Table(right)`` keys : str or list of str Name(s) of column(s) used to match rows of left and right tables. Default is to use all columns which are common to both tables. join_type : str Join type ('inner' | 'outer' | 'left' | 'right' | 'cartesian'), default is 'inner' keys_left : str or list of str or list of column-like, optional Left column(s) used to match rows instead of ``keys`` arg. This can be be a single left table column name or list of column names, or a list of column-like values with the same lengths as the left table. keys_right : str or list of str or list of column-like, optional Same as ``keys_left``, but for the right side of the join. uniq_col_name : str or None String generate a unique output column name in case of a conflict. The default is '{col_name}_{table_name}'. table_names : list of str or None Two-element list of table names used when generating unique output column names. The default is ['1', '2']. metadata_conflicts : str How to proceed with metadata conflicts. This should be one of: * ``'silent'``: silently pick the last conflicting meta-data value * ``'warn'``: pick the last conflicting meta-data value, but emit a warning (default) * ``'error'``: raise an exception. join_funcs : dict, None Dict of functions to use for matching the corresponding key column(s). See `~astropy.table.join_skycoord` for an example and details. Returns ------- joined_table : `~astropy.table.Table` object New table containing the result of the join operation. """ # Try converting inputs to Table as needed if not isinstance(left, Table): left = Table(left) if not isinstance(right, Table): right = Table(right) col_name_map = OrderedDict() out = _join(left, right, keys, join_type, uniq_col_name, table_names, col_name_map, metadata_conflicts, join_funcs, keys_left=keys_left, keys_right=keys_right) # Merge the column and table meta data. Table subclasses might override # these methods for custom merge behavior. _merge_table_meta(out, [left, right], metadata_conflicts=metadata_conflicts) return out def setdiff(table1, table2, keys=None): """ Take a set difference of table rows. The row set difference will contain all rows in ``table1`` that are not present in ``table2``. If the keys parameter is not defined, all columns in ``table1`` will be included in the output table. Parameters ---------- table1 : `~astropy.table.Table` ``table1`` is on the left side of the set difference. table2 : `~astropy.table.Table` ``table2`` is on the right side of the set difference. keys : str or list of str Name(s) of column(s) used to match rows of left and right tables. Default is to use all columns in ``table1``. Returns ------- diff_table : `~astropy.table.Table` New table containing the set difference between tables. If the set difference is none, an empty table will be returned. Examples -------- To get a set difference between two tables:: >>> from astropy.table import setdiff, Table >>> t1 = Table({'a': [1, 4, 9], 'b': ['c', 'd', 'f']}, names=('a', 'b')) >>> t2 = Table({'a': [1, 5, 9], 'b': ['c', 'b', 'f']}, names=('a', 'b')) >>> print(t1) a b --- --- 1 c 4 d 9 f >>> print(t2) a b --- --- 1 c 5 b 9 f >>> print(setdiff(t1, t2)) a b --- --- 4 d >>> print(setdiff(t2, t1)) a b --- --- 5 b """ if keys is None: keys = table1.colnames # Check that all keys are in table1 and table2 for tbl, tbl_str in ((table1, 'table1'), (table2, 'table2')): diff_keys = np.setdiff1d(keys, tbl.colnames) if len(diff_keys) != 0: raise ValueError("The {} columns are missing from {}, cannot take " "a set difference.".format(diff_keys, tbl_str)) # Make a light internal copy of both tables t1 = table1.copy(copy_data=False) t1.meta = {} t1.keep_columns(keys) t1['__index1__'] = np.arange(len(table1)) # Keep track of rows indices # Make a light internal copy to avoid touching table2 t2 = table2.copy(copy_data=False) t2.meta = {} t2.keep_columns(keys) # Dummy column to recover rows after join t2['__index2__'] = np.zeros(len(t2), dtype=np.uint8) # dummy column t12 = _join(t1, t2, join_type='left', keys=keys, metadata_conflicts='silent') # If t12 index2 is masked then that means some rows were in table1 but not table2. if hasattr(t12['__index2__'], 'mask'): # Define bool mask of table1 rows not in table2 diff = t12['__index2__'].mask # Get the row indices of table1 for those rows idx = t12['__index1__'][diff] # Select corresponding table1 rows straight from table1 to ensure # correct table and column types. t12_diff = table1[idx] else: t12_diff = table1[[]] return t12_diff def dstack(tables, join_type='outer', metadata_conflicts='warn'): """ Stack columns within tables depth-wise A ``join_type`` of 'exact' means that the tables must all have exactly the same column names (though the order can vary). If ``join_type`` is 'inner' then the intersection of common columns will be the output. A value of 'outer' (default) means the output will have the union of all columns, with table values being masked where no common values are available. Parameters ---------- tables : `~astropy.table.Table` or `~astropy.table.Row` or list thereof Table(s) to stack along depth-wise with the current table Table columns should have same shape and name for depth-wise stacking join_type : str Join type ('inner' | 'exact' | 'outer'), default is 'outer' metadata_conflicts : str How to proceed with metadata conflicts. This should be one of: * ``'silent'``: silently pick the last conflicting meta-data value * ``'warn'``: pick the last conflicting meta-data value, but emit a warning (default) * ``'error'``: raise an exception. Returns ------- stacked_table : `~astropy.table.Table` object New table containing the stacked data from the input tables. Examples -------- To stack two tables along rows do:: >>> from astropy.table import vstack, Table >>> t1 = Table({'a': [1, 2], 'b': [3, 4]}, names=('a', 'b')) >>> t2 = Table({'a': [5, 6], 'b': [7, 8]}, names=('a', 'b')) >>> print(t1) a b --- --- 1 3 2 4 >>> print(t2) a b --- --- 5 7 6 8 >>> print(dstack([t1, t2])) a [2] b [2] ------ ------ 1 .. 5 3 .. 7 2 .. 6 4 .. 8 """ _check_join_type(join_type, 'dstack') tables = _get_list_of_tables(tables) if len(tables) == 1: return tables[0] # no point in stacking a single table n_rows = set(len(table) for table in tables) if len(n_rows) != 1: raise ValueError('Table lengths must all match for dstack') n_row = n_rows.pop() out = vstack(tables, join_type, metadata_conflicts) for name, col in out.columns.items(): col = out[name] # Reshape to so each original column is now in a row. # If entries are not 0-dim then those additional shape dims # are just carried along. # [x x x y y y] => [[x x x], # [y y y]] new_shape = (len(tables), n_row) + col.shape[1:] try: col.shape = (len(tables), n_row) + col.shape[1:] except AttributeError: col = col.reshape(new_shape) # Transpose the table and row axes to get to # [[x, y], # [x, y] # [x, y]] axes = np.arange(len(col.shape)) axes[:2] = [1, 0] # This temporarily makes `out` be corrupted (columns of different # length) but it all works out in the end. out.columns.__setitem__(name, col.transpose(axes), validated=True) return out def vstack(tables, join_type='outer', metadata_conflicts='warn'): """ Stack tables vertically (along rows) A ``join_type`` of 'exact' means that the tables must all have exactly the same column names (though the order can vary). If ``join_type`` is 'inner' then the intersection of common columns will be the output. A value of 'outer' (default) means the output will have the union of all columns, with table values being masked where no common values are available. Parameters ---------- tables : `~astropy.table.Table` or `~astropy.table.Row` or list thereof Table(s) to stack along rows (vertically) with the current table join_type : str Join type ('inner' | 'exact' | 'outer'), default is 'outer' metadata_conflicts : str How to proceed with metadata conflicts. This should be one of: * ``'silent'``: silently pick the last conflicting meta-data value * ``'warn'``: pick the last conflicting meta-data value, but emit a warning (default) * ``'error'``: raise an exception. Returns ------- stacked_table : `~astropy.table.Table` object New table containing the stacked data from the input tables. Examples -------- To stack two tables along rows do:: >>> from astropy.table import vstack, Table >>> t1 = Table({'a': [1, 2], 'b': [3, 4]}, names=('a', 'b')) >>> t2 = Table({'a': [5, 6], 'b': [7, 8]}, names=('a', 'b')) >>> print(t1) a b --- --- 1 3 2 4 >>> print(t2) a b --- --- 5 7 6 8 >>> print(vstack([t1, t2])) a b --- --- 1 3 2 4 5 7 6 8 """ _check_join_type(join_type, 'vstack') tables = _get_list_of_tables(tables) # validates input if len(tables) == 1: return tables[0] # no point in stacking a single table col_name_map = OrderedDict() out = _vstack(tables, join_type, col_name_map, metadata_conflicts) # Merge table metadata _merge_table_meta(out, tables, metadata_conflicts=metadata_conflicts) return out def hstack(tables, join_type='outer', uniq_col_name='{col_name}_{table_name}', table_names=None, metadata_conflicts='warn'): """ Stack tables along columns (horizontally) A ``join_type`` of 'exact' means that the tables must all have exactly the same number of rows. If ``join_type`` is 'inner' then the intersection of rows will be the output. A value of 'outer' (default) means the output will have the union of all rows, with table values being masked where no common values are available. Parameters ---------- tables : `~astropy.table.Table` or `~astropy.table.Row` or list thereof Tables to stack along columns (horizontally) with the current table join_type : str Join type ('inner' | 'exact' | 'outer'), default is 'outer' uniq_col_name : str or None String generate a unique output column name in case of a conflict. The default is '{col_name}_{table_name}'. table_names : list of str or None Two-element list of table names used when generating unique output column names. The default is ['1', '2', ..]. metadata_conflicts : str How to proceed with metadata conflicts. This should be one of: * ``'silent'``: silently pick the last conflicting meta-data value * ``'warn'``: pick the last conflicting meta-data value, but emit a warning (default) * ``'error'``: raise an exception. Returns ------- stacked_table : `~astropy.table.Table` object New table containing the stacked data from the input tables. See Also -------- Table.add_columns, Table.replace_column, Table.update Examples -------- To stack two tables horizontally (along columns) do:: >>> from astropy.table import Table, hstack >>> t1 = Table({'a': [1, 2], 'b': [3, 4]}, names=('a', 'b')) >>> t2 = Table({'c': [5, 6], 'd': [7, 8]}, names=('c', 'd')) >>> print(t1) a b --- --- 1 3 2 4 >>> print(t2) c d --- --- 5 7 6 8 >>> print(hstack([t1, t2])) a b c d --- --- --- --- 1 3 5 7 2 4 6 8 """ _check_join_type(join_type, 'hstack') tables = _get_list_of_tables(tables) # validates input if len(tables) == 1: return tables[0] # no point in stacking a single table col_name_map = OrderedDict() out = _hstack(tables, join_type, uniq_col_name, table_names, col_name_map) _merge_table_meta(out, tables, metadata_conflicts=metadata_conflicts) return out def unique(input_table, keys=None, silent=False, keep='first'): """ Returns the unique rows of a table. Parameters ---------- input_table : table-like keys : str or list of str Name(s) of column(s) used to create unique rows. Default is to use all columns. keep : {'first', 'last', 'none'} Whether to keep the first or last row for each set of duplicates. If 'none', all rows that are duplicate are removed, leaving only rows that are already unique in the input. Default is 'first'. silent : bool If `True`, masked value column(s) are silently removed from ``keys``. If `False`, an exception is raised when ``keys`` contains masked value column(s). Default is `False`. Returns ------- unique_table : `~astropy.table.Table` object New table containing only the unique rows of ``input_table``. Examples -------- >>> from astropy.table import unique, Table >>> import numpy as np >>> table = Table(data=[[1,2,3,2,3,3], ... [2,3,4,5,4,6], ... [3,4,5,6,7,8]], ... names=['col1', 'col2', 'col3'], ... dtype=[np.int32, np.int32, np.int32]) >>> table col1 col2 col3 int32 int32 int32 ----- ----- ----- 1 2 3 2 3 4 3 4 5 2 5 6 3 4 7 3 6 8 >>> unique(table, keys='col1')
col1 col2 col3 int32 int32 int32 ----- ----- ----- 1 2 3 2 3 4 3 4 5 >>> unique(table, keys=['col1'], keep='last')
col1 col2 col3 int32 int32 int32 ----- ----- ----- 1 2 3 2 5 6 3 6 8 >>> unique(table, keys=['col1', 'col2'])
col1 col2 col3 int32 int32 int32 ----- ----- ----- 1 2 3 2 3 4 2 5 6 3 4 5 3 6 8 >>> unique(table, keys=['col1', 'col2'], keep='none')
col1 col2 col3 int32 int32 int32 ----- ----- ----- 1 2 3 2 3 4 2 5 6 3 6 8 >>> unique(table, keys=['col1'], keep='none')
col1 col2 col3 int32 int32 int32 ----- ----- ----- 1 2 3 """ if keep not in ('first', 'last', 'none'): raise ValueError("'keep' should be one of 'first', 'last', 'none'") if isinstance(keys, str): keys = [keys] if keys is None: keys = input_table.colnames else: if len(set(keys)) != len(keys): raise ValueError("duplicate key names") # Check for columns with masked values for key in keys[:]: col = input_table[key] if hasattr(col, 'mask') and np.any(col.mask): if not silent: raise ValueError( "cannot use columns with masked values as keys; " "remove column '{}' from keys and rerun " "unique()".format(key)) del keys[keys.index(key)] if len(keys) == 0: raise ValueError("no column remained in ``keys``; " "unique() cannot work with masked value " "key columns") grouped_table = input_table.group_by(keys) indices = grouped_table.groups.indices if keep == 'first': indices = indices[:-1] elif keep == 'last': indices = indices[1:] - 1 else: indices = indices[:-1][np.diff(indices) == 1] return grouped_table[indices] def get_col_name_map(arrays, common_names, uniq_col_name='{col_name}_{table_name}', table_names=None): """ Find the column names mapping when merging the list of tables ``arrays``. It is assumed that col names in ``common_names`` are to be merged into a single column while the rest will be uniquely represented in the output. The args ``uniq_col_name`` and ``table_names`` specify how to rename columns in case of conflicts. Returns a dict mapping each output column name to the input(s). This takes the form {outname : (col_name_0, col_name_1, ...), ... }. For key columns all of input names will be present, while for the other non-key columns the value will be (col_name_0, None, ..) or (None, col_name_1, ..) etc. """ col_name_map = collections.defaultdict(lambda: [None] * len(arrays)) col_name_list = [] if table_names is None: table_names = [str(ii + 1) for ii in range(len(arrays))] for idx, array in enumerate(arrays): table_name = table_names[idx] for name in array.colnames: out_name = name if name in common_names: # If name is in the list of common_names then insert into # the column name list, but just once. if name not in col_name_list: col_name_list.append(name) else: # If name is not one of the common column outputs, and it collides # with the names in one of the other arrays, then rename others = list(arrays) others.pop(idx) if any(name in other.colnames for other in others): out_name = uniq_col_name.format(table_name=table_name, col_name=name) col_name_list.append(out_name) col_name_map[out_name][idx] = name # Check for duplicate output column names col_name_count = Counter(col_name_list) repeated_names = [name for name, count in col_name_count.items() if count > 1] if repeated_names: raise TableMergeError('Merging column names resulted in duplicates: {}. ' 'Change uniq_col_name or table_names args to fix this.' .format(repeated_names)) # Convert col_name_map to a regular dict with tuple (immutable) values col_name_map = OrderedDict((name, col_name_map[name]) for name in col_name_list) return col_name_map def get_descrs(arrays, col_name_map): """ Find the dtypes descrs resulting from merging the list of arrays' dtypes, using the column name mapping ``col_name_map``. Return a list of descrs for the output. """ out_descrs = [] for out_name, in_names in col_name_map.items(): # List of input arrays that contribute to this output column in_cols = [arr[name] for arr, name in zip(arrays, in_names) if name is not None] # List of names of the columns that contribute to this output column. names = [name for name in in_names if name is not None] # Output dtype is the superset of all dtypes in in_arrays try: dtype = common_dtype(in_cols) except TableMergeError as tme: # Beautify the error message when we are trying to merge columns with incompatible # types by including the name of the columns that originated the error. raise TableMergeError("The '{}' columns have incompatible types: {}" .format(names[0], tme._incompat_types)) from tme # Make sure all input shapes are the same uniq_shapes = set(col.shape[1:] for col in in_cols) if len(uniq_shapes) != 1: raise TableMergeError(f'Key columns {names!r} have different shape') shape = uniq_shapes.pop() out_descrs.append((fix_column_name(out_name), dtype, shape)) return out_descrs def common_dtype(cols): """ Use numpy to find the common dtype for a list of columns. Only allow columns within the following fundamental numpy data types: np.bool_, np.object_, np.number, np.character, np.void """ try: return metadata.common_dtype(cols) except metadata.MergeConflictError as err: tme = TableMergeError(f'Columns have incompatible types {err._incompat_types}') tme._incompat_types = err._incompat_types raise tme from err def _get_join_sort_idxs(keys, left, right): # Go through each of the key columns in order and make columns for # a new structured array that represents the lexical ordering of those # key columns. This structured array is then argsort'ed. The trick here # is that some columns (e.g. Time) may need to be expanded into multiple # columns for ordering here. ii = 0 # Index for uniquely naming the sort columns sort_keys_dtypes = [] # sortable_table dtypes as list of (name, dtype_str, shape) tuples sort_keys = [] # sortable_table (structured ndarray) column names sort_left = {} # sortable ndarrays from left table sort_right = {} # sortable ndarray from right table for key in keys: # get_sortable_arrays() returns a list of ndarrays that can be lexically # sorted to represent the order of the column. In most cases this is just # a single element of the column itself. left_sort_cols = left[key].info.get_sortable_arrays() right_sort_cols = right[key].info.get_sortable_arrays() if len(left_sort_cols) != len(right_sort_cols): # Should never happen because cols are screened beforehand for compatibility raise RuntimeError('mismatch in sort cols lengths') for left_sort_col, right_sort_col in zip(left_sort_cols, right_sort_cols): # Check for consistency of shapes. Mismatch should never happen. shape = left_sort_col.shape[1:] if shape != right_sort_col.shape[1:]: raise RuntimeError('mismatch in shape of left vs. right sort array') if shape != (): raise ValueError(f'sort key column {key!r} must be 1-d') sort_key = str(ii) sort_keys.append(sort_key) sort_left[sort_key] = left_sort_col sort_right[sort_key] = right_sort_col # Build up dtypes for the structured array that gets sorted. dtype_str = common_dtype([left_sort_col, right_sort_col]) sort_keys_dtypes.append((sort_key, dtype_str)) ii += 1 # Make the empty sortable table and fill it len_left = len(left) sortable_table = np.empty(len_left + len(right), dtype=sort_keys_dtypes) for key in sort_keys: sortable_table[key][:len_left] = sort_left[key] sortable_table[key][len_left:] = sort_right[key] # Finally do the (lexical) argsort and make a new sorted version idx_sort = sortable_table.argsort(order=sort_keys) sorted_table = sortable_table[idx_sort] # Get indexes of unique elements (i.e. the group boundaries) diffs = np.concatenate(([True], sorted_table[1:] != sorted_table[:-1], [True])) idxs = np.flatnonzero(diffs) return idxs, idx_sort def _apply_join_funcs(left, right, keys, join_funcs): """Apply join_funcs """ # Make light copies of left and right, then add new index columns. left = left.copy(copy_data=False) right = right.copy(copy_data=False) for key, join_func in join_funcs.items(): ids1, ids2 = join_func(left[key], right[key]) # Define a unique id_key name, and keep adding underscores until we have # a name not yet present. id_key = key + '_id' while id_key in left.columns or id_key in right.columns: id_key = id_key[:-2] + '_id' keys = tuple(id_key if orig_key == key else orig_key for orig_key in keys) left.add_column(ids1, index=0, name=id_key) # [id_key] = ids1 right.add_column(ids2, index=0, name=id_key) # [id_key] = ids2 return left, right, keys def _join(left, right, keys=None, join_type='inner', uniq_col_name='{col_name}_{table_name}', table_names=['1', '2'], col_name_map=None, metadata_conflicts='warn', join_funcs=None, keys_left=None, keys_right=None): """ Perform a join of the left and right Tables on specified keys. Parameters ---------- left : Table Left side table in the join right : Table Right side table in the join keys : str or list of str Name(s) of column(s) used to match rows of left and right tables. Default is to use all columns which are common to both tables. join_type : str Join type ('inner' | 'outer' | 'left' | 'right' | 'cartesian'), default is 'inner' uniq_col_name : str or None String generate a unique output column name in case of a conflict. The default is '{col_name}_{table_name}'. table_names : list of str or None Two-element list of table names used when generating unique output column names. The default is ['1', '2']. col_name_map : empty dict or None If passed as a dict then it will be updated in-place with the mapping of output to input column names. metadata_conflicts : str How to proceed with metadata conflicts. This should be one of: * ``'silent'``: silently pick the last conflicting meta-data value * ``'warn'``: pick the last conflicting meta-data value, but emit a warning (default) * ``'error'``: raise an exception. join_funcs : dict, None Dict of functions to use for matching the corresponding key column(s). See `~astropy.table.join_skycoord` for an example and details. Returns ------- joined_table : `~astropy.table.Table` object New table containing the result of the join operation. """ # Store user-provided col_name_map until the end _col_name_map = col_name_map # Special column name for cartesian join, should never collide with real column cartesian_index_name = '__table_cartesian_join_temp_index__' if join_type not in ('inner', 'outer', 'left', 'right', 'cartesian'): raise ValueError("The 'join_type' argument should be in 'inner', " "'outer', 'left', 'right', or 'cartesian' " "(got '{}' instead)". format(join_type)) if join_type == 'cartesian': if keys: raise ValueError('cannot supply keys for a cartesian join') if join_funcs: raise ValueError('cannot supply join_funcs for a cartesian join') # Make light copies of left and right, then add temporary index columns # with all the same value so later an outer join turns into a cartesian join. left = left.copy(copy_data=False) right = right.copy(copy_data=False) left[cartesian_index_name] = np.uint8(0) right[cartesian_index_name] = np.uint8(0) keys = (cartesian_index_name, ) # Handle the case of join key columns that are different between left and # right via keys_left/keys_right args. This is done by saving the original # input tables and making new left and right tables that contain only the # key cols but with common column names ['0', '1', etc]. This sets `keys` to # those fake key names in the left and right tables if keys_left is not None or keys_right is not None: left_orig = left right_orig = right left, right, keys = _join_keys_left_right( left, right, keys, keys_left, keys_right, join_funcs) if keys is None: keys = tuple(name for name in left.colnames if name in right.colnames) if len(keys) == 0: raise TableMergeError('No keys in common between left and right tables') elif isinstance(keys, str): # If we have a single key, put it in a tuple keys = (keys,) # Check the key columns for arr, arr_label in ((left, 'Left'), (right, 'Right')): for name in keys: if name not in arr.colnames: raise TableMergeError('{} table does not have key column {!r}' .format(arr_label, name)) if hasattr(arr[name], 'mask') and np.any(arr[name].mask): raise TableMergeError('{} key column {!r} has missing values' .format(arr_label, name)) if join_funcs is not None: if not all(key in keys for key in join_funcs): raise ValueError(f'join_funcs keys {join_funcs.keys()} must be a ' f'subset of join keys {keys}') left, right, keys = _apply_join_funcs(left, right, keys, join_funcs) len_left, len_right = len(left), len(right) if len_left == 0 or len_right == 0: raise ValueError('input tables for join must both have at least one row') try: idxs, idx_sort = _get_join_sort_idxs(keys, left, right) except NotImplementedError: raise TypeError('one or more key columns are not sortable') # Now that we have idxs and idx_sort, revert to the original table args to # carry on with making the output joined table. `keys` is set to to an empty # list so that all original left and right columns are included in the # output table. if keys_left is not None or keys_right is not None: keys = [] left = left_orig right = right_orig # Joined array dtype as a list of descr (name, type_str, shape) tuples col_name_map = get_col_name_map([left, right], keys, uniq_col_name, table_names) out_descrs = get_descrs([left, right], col_name_map) # Main inner loop in Cython to compute the cartesian product # indices for the given join type int_join_type = {'inner': 0, 'outer': 1, 'left': 2, 'right': 3, 'cartesian': 1}[join_type] masked, n_out, left_out, left_mask, right_out, right_mask = \ _np_utils.join_inner(idxs, idx_sort, len_left, int_join_type) out = _get_out_class([left, right])() for out_name, dtype, shape in out_descrs: if out_name == cartesian_index_name: continue left_name, right_name = col_name_map[out_name] if left_name and right_name: # this is a key which comes from left and right cols = [left[left_name], right[right_name]] col_cls = _get_out_class(cols) if not hasattr(col_cls.info, 'new_like'): raise NotImplementedError('join unavailable for mixin column type(s): {}' .format(col_cls.__name__)) out[out_name] = col_cls.info.new_like(cols, n_out, metadata_conflicts, out_name) out[out_name][:] = np.where(right_mask, left[left_name].take(left_out), right[right_name].take(right_out)) continue elif left_name: # out_name came from the left table name, array, array_out, array_mask = left_name, left, left_out, left_mask elif right_name: name, array, array_out, array_mask = right_name, right, right_out, right_mask else: raise TableMergeError('Unexpected column names (maybe one is ""?)') # Select the correct elements from the original table col = array[name][array_out] # If the output column is masked then set the output column masking # accordingly. Check for columns that don't support a mask attribute. if masked and np.any(array_mask): # If col is a Column but not MaskedColumn then upgrade at this point # because masking is required. if isinstance(col, Column) and not isinstance(col, MaskedColumn): col = out.MaskedColumn(col, copy=False) if isinstance(col, Quantity) and not isinstance(col, Masked): col = Masked(col, copy=False) # array_mask is 1-d corresponding to length of output column. We need # make it have the correct shape for broadcasting, i.e. (length, 1, 1, ..). # Mixin columns might not have ndim attribute so use len(col.shape). array_mask.shape = (col.shape[0],) + (1,) * (len(col.shape) - 1) # Now broadcast to the correct final shape array_mask = np.broadcast_to(array_mask, col.shape) try: col[array_mask] = col.info.mask_val except Exception as err: # Not clear how different classes will fail here raise NotImplementedError( "join requires masking column '{}' but column" " type {} does not support masking" .format(out_name, col.__class__.__name__)) from err # Set the output table column to the new joined column out[out_name] = col # If col_name_map supplied as a dict input, then update. if isinstance(_col_name_map, Mapping): _col_name_map.update(col_name_map) return out def _join_keys_left_right(left, right, keys, keys_left, keys_right, join_funcs): """Do processing to handle keys_left / keys_right args for join. This takes the keys_left/right inputs and turns them into a list of left/right columns corresponding to those inputs (which can be column names or column data values). It also generates the list of fake key column names (strings of "1", "2", etc.) that correspond to the input keys. """ def _keys_to_cols(keys, table, label): # Process input `keys`, which is a str or list of str column names in # `table` or a list of column-like objects. The `label` is just for # error reporting. if isinstance(keys, str): keys = [keys] cols = [] for key in keys: if isinstance(key, str): try: cols.append(table[key]) except KeyError: raise ValueError(f'{label} table does not have key column {key!r}') else: if len(key) != len(table): raise ValueError(f'{label} table has different length from key {key}') cols.append(key) return cols if join_funcs is not None: raise ValueError('cannot supply join_funcs arg and keys_left / keys_right') if keys_left is None or keys_right is None: raise ValueError('keys_left and keys_right must both be provided') if keys is not None: raise ValueError('keys arg must be None if keys_left and keys_right are supplied') cols_left = _keys_to_cols(keys_left, left, 'left') cols_right = _keys_to_cols(keys_right, right, 'right') if len(cols_left) != len(cols_right): raise ValueError('keys_left and keys_right args must have same length') # Make two new temp tables for the join with only the join columns and # key columns in common. keys = [f'{ii}' for ii in range(len(cols_left))] left = left.__class__(cols_left, names=keys, copy=False) right = right.__class__(cols_right, names=keys, copy=False) return left, right, keys def _check_join_type(join_type, func_name): """Check join_type arg in hstack and vstack. This specifically checks for the common mistake of call vstack(t1, t2) instead of vstack([t1, t2]). The subsequent check of ``join_type in ('inner', ..)`` does not raise in this case. """ if not isinstance(join_type, str): msg = '`join_type` arg must be a string' if isinstance(join_type, Table): msg += ('. Did you accidentally ' f'call {func_name}(t1, t2, ..) instead of ' f'{func_name}([t1, t2], ..)?') raise TypeError(msg) if join_type not in ('inner', 'exact', 'outer'): raise ValueError("`join_type` arg must be one of 'inner', 'exact' or 'outer'") def _vstack(arrays, join_type='outer', col_name_map=None, metadata_conflicts='warn'): """ Stack Tables vertically (by rows) A ``join_type`` of 'exact' (default) means that the arrays must all have exactly the same column names (though the order can vary). If ``join_type`` is 'inner' then the intersection of common columns will be the output. A value of 'outer' means the output will have the union of all columns, with array values being masked where no common values are available. Parameters ---------- arrays : list of Tables Tables to stack by rows (vertically) join_type : str Join type ('inner' | 'exact' | 'outer'), default is 'outer' col_name_map : empty dict or None If passed as a dict then it will be updated in-place with the mapping of output to input column names. Returns ------- stacked_table : `~astropy.table.Table` object New table containing the stacked data from the input tables. """ # Store user-provided col_name_map until the end _col_name_map = col_name_map # Trivial case of one input array if len(arrays) == 1: return arrays[0] # Start by assuming an outer match where all names go to output names = set(itertools.chain(*[arr.colnames for arr in arrays])) col_name_map = get_col_name_map(arrays, names) # If require_match is True then the output must have exactly the same # number of columns as each input array if join_type == 'exact': for names in col_name_map.values(): if any(x is None for x in names): raise TableMergeError('Inconsistent columns in input arrays ' "(use 'inner' or 'outer' join_type to " "allow non-matching columns)") join_type = 'outer' # For an inner join, keep only columns where all input arrays have that column if join_type == 'inner': col_name_map = OrderedDict((name, in_names) for name, in_names in col_name_map.items() if all(x is not None for x in in_names)) if len(col_name_map) == 0: raise TableMergeError('Input arrays have no columns in common') lens = [len(arr) for arr in arrays] n_rows = sum(lens) out = _get_out_class(arrays)() for out_name, in_names in col_name_map.items(): # List of input arrays that contribute to this output column cols = [arr[name] for arr, name in zip(arrays, in_names) if name is not None] col_cls = _get_out_class(cols) if not hasattr(col_cls.info, 'new_like'): raise NotImplementedError('vstack unavailable for mixin column type(s): {}' .format(col_cls.__name__)) try: col = col_cls.info.new_like(cols, n_rows, metadata_conflicts, out_name) except metadata.MergeConflictError as err: # Beautify the error message when we are trying to merge columns with incompatible # types by including the name of the columns that originated the error. raise TableMergeError("The '{}' columns have incompatible types: {}" .format(out_name, err._incompat_types)) from err idx0 = 0 for name, array in zip(in_names, arrays): idx1 = idx0 + len(array) if name in array.colnames: col[idx0:idx1] = array[name] else: # If col is a Column but not MaskedColumn then upgrade at this point # because masking is required. if isinstance(col, Column) and not isinstance(col, MaskedColumn): col = out.MaskedColumn(col, copy=False) if isinstance(col, Quantity) and not isinstance(col, Masked): col = Masked(col, copy=False) try: col[idx0:idx1] = col.info.mask_val except Exception as err: raise NotImplementedError( "vstack requires masking column '{}' but column" " type {} does not support masking" .format(out_name, col.__class__.__name__)) from err idx0 = idx1 out[out_name] = col # If col_name_map supplied as a dict input, then update. if isinstance(_col_name_map, Mapping): _col_name_map.update(col_name_map) return out def _hstack(arrays, join_type='outer', uniq_col_name='{col_name}_{table_name}', table_names=None, col_name_map=None): """ Stack tables horizontally (by columns) A ``join_type`` of 'exact' (default) means that the arrays must all have exactly the same number of rows. If ``join_type`` is 'inner' then the intersection of rows will be the output. A value of 'outer' means the output will have the union of all rows, with array values being masked where no common values are available. Parameters ---------- arrays : List of tables Tables to stack by columns (horizontally) join_type : str Join type ('inner' | 'exact' | 'outer'), default is 'outer' uniq_col_name : str or None String generate a unique output column name in case of a conflict. The default is '{col_name}_{table_name}'. table_names : list of str or None Two-element list of table names used when generating unique output column names. The default is ['1', '2', ..]. Returns ------- stacked_table : `~astropy.table.Table` object New table containing the stacked data from the input tables. """ # Store user-provided col_name_map until the end _col_name_map = col_name_map if table_names is None: table_names = [f'{ii + 1}' for ii in range(len(arrays))] if len(arrays) != len(table_names): raise ValueError('Number of arrays must match number of table_names') # Trivial case of one input arrays if len(arrays) == 1: return arrays[0] col_name_map = get_col_name_map(arrays, [], uniq_col_name, table_names) # If require_match is True then all input arrays must have the same length arr_lens = [len(arr) for arr in arrays] if join_type == 'exact': if len(set(arr_lens)) > 1: raise TableMergeError("Inconsistent number of rows in input arrays " "(use 'inner' or 'outer' join_type to allow " "non-matching rows)") join_type = 'outer' # For an inner join, keep only the common rows if join_type == 'inner': min_arr_len = min(arr_lens) if len(set(arr_lens)) > 1: arrays = [arr[:min_arr_len] for arr in arrays] arr_lens = [min_arr_len for arr in arrays] # If there are any output rows where one or more input arrays are missing # then the output must be masked. If any input arrays are masked then # output is masked. n_rows = max(arr_lens) out = _get_out_class(arrays)() for out_name, in_names in col_name_map.items(): for name, array, arr_len in zip(in_names, arrays, arr_lens): if name is None: continue if n_rows > arr_len: indices = np.arange(n_rows) indices[arr_len:] = 0 col = array[name][indices] # If col is a Column but not MaskedColumn then upgrade at this point # because masking is required. if isinstance(col, Column) and not isinstance(col, MaskedColumn): col = out.MaskedColumn(col, copy=False) if isinstance(col, Quantity) and not isinstance(col, Masked): col = Masked(col, copy=False) try: col[arr_len:] = col.info.mask_val except Exception as err: raise NotImplementedError( "hstack requires masking column '{}' but column" " type {} does not support masking" .format(out_name, col.__class__.__name__)) from err else: col = array[name][:n_rows] out[out_name] = col # If col_name_map supplied as a dict input, then update. if isinstance(_col_name_map, Mapping): _col_name_map.update(col_name_map) return out ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/pandas.py0000644000175100001710000000336000000000000016657 0ustar00vstsdocker# -*- coding: utf-8 -*- ascii_coded = ('Ò♙♙♙♙♙♙♙♙♌♐♐♌♙♙♙♙♙♙♌♌♙♙Ò♙♙♙♙♙♙♙♘♐♐♐♈♙♙♙♙♙♌♐♐♐♔Ò♙♙♌♈♙♙♌♐♈♈♙♙♙♙♙♙♙♙♈♐♐♙Ò♙♐♙♙♙♐♐♙♙♙' '♙♙♙♙♙♙♙♙♙♙♙♙Ò♐♔♙♙♘♐♐♙♙♌♐♐♔♙♙♌♌♌♙♙♙♌Ò♐♐♙♙♘♐♐♌♙♈♐♈♙♙♙♈♐♐♙♙♘♔Ò♐♐♌♙♘♐♐♐♌♌♙♙♌♌♌♙♈♈♙♌♐' '♐Ò♘♐♐♐♌♐♐♐♐♐♐♌♙♈♙♌♐♐♐♐♐♔Ò♘♐♐♐♐♐♐♐♐♐♐♐♐♈♈♐♐♐♐♐♐♙Ò♙♘♐♐♐♐♈♐♐♐♐♐♐♙♙♐♐♐♐♐♙♙Ò♙♙♙♈♈♈♙♙♐' '♐♐♐♐♔♙♐♐♐♐♈♙♙Ò♙♙♙♙♙♙♙♙♙♈♈♐♐♐♙♈♈♈♙♙♙♙Ò') ascii_uncoded = ''.join([chr(ord(c) - 200) for c in ascii_coded]) url = 'https://media.giphy.com/media/e24Q8FKE2mxRS/giphy.gif' message_coded = 'ĘĊÄļÄŦÄŠÄģÃˇÄœÄŠÄĒÄ´Ä­Ã¨ÄąÄļÄŧÄ­ÄēÄŠÄĢÄŧĹġÄļ' message_uncoded = ''.join([chr(ord(c) - 200) for c in message_coded]) try: from IPython import display html = display.Image(url=url)._repr_html_() class HTMLWithBackup(display.HTML): def __init__(self, data, backup_text): super().__init__(data) self.backup_text = backup_text def __repr__(self): if self.backup_text is None: return super().__repr__() else: return self.backup_text dhtml = HTMLWithBackup(html, ascii_uncoded) display.display(dhtml) except ImportError: print(ascii_uncoded) except (UnicodeEncodeError, SyntaxError): pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/pprint.py0000644000175100001710000007001400000000000016725 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import os import sys import re import fnmatch import numpy as np from astropy import log from astropy.utils.console import Getch, color_print, terminal_size, conf from astropy.utils.data_info import dtype_info_name __all__ = [] def default_format_func(format_, val): if isinstance(val, bytes): return val.decode('utf-8', errors='replace') else: return str(val) # The first three functions are helpers for _auto_format_func def _use_str_for_masked_values(format_func): """Wrap format function to trap masked values. String format functions and most user functions will not be able to deal with masked values, so we wrap them to ensure they are passed to str(). """ return lambda format_, val: (str(val) if val is np.ma.masked else format_func(format_, val)) def _possible_string_format_functions(format_): """Iterate through possible string-derived format functions. A string can either be a format specifier for the format built-in, a new-style format string, or an old-style format string. """ yield lambda format_, val: format(val, format_) yield lambda format_, val: format_.format(val) yield lambda format_, val: format_ % val def get_auto_format_func( col=None, possible_string_format_functions=_possible_string_format_functions): """ Return a wrapped ``auto_format_func`` function which is used in formatting table columns. This is primarily an internal function but gets used directly in other parts of astropy, e.g. `astropy.io.ascii`. Parameters ---------- col_name : object, optional Hashable object to identify column like id or name. Default is None. possible_string_format_functions : func, optional Function that yields possible string formatting functions (defaults to internal function to do this). Returns ------- Wrapped ``auto_format_func`` function """ def _auto_format_func(format_, val): """Format ``val`` according to ``format_`` for a plain format specifier, old- or new-style format strings, or using a user supplied function. More importantly, determine and cache (in _format_funcs) a function that will do this subsequently. In this way this complicated logic is only done for the first value. Returns the formatted value. """ if format_ is None: return default_format_func(format_, val) if format_ in col.info._format_funcs: return col.info._format_funcs[format_](format_, val) if callable(format_): format_func = lambda format_, val: format_(val) # noqa try: out = format_func(format_, val) if not isinstance(out, str): raise ValueError('Format function for value {} returned {} ' 'instead of string type' .format(val, type(val))) except Exception as err: # For a masked element, the format function call likely failed # to handle it. Just return the string representation for now, # and retry when a non-masked value comes along. if val is np.ma.masked: return str(val) raise ValueError(f'Format function for value {val} failed.') from err # If the user-supplied function handles formatting masked elements, use # it directly. Otherwise, wrap it in a function that traps them. try: format_func(format_, np.ma.masked) except Exception: format_func = _use_str_for_masked_values(format_func) else: # For a masked element, we cannot set string-based format functions yet, # as all tests below will fail. Just return the string representation # of masked for now, and retry when a non-masked value comes along. if val is np.ma.masked: return str(val) for format_func in possible_string_format_functions(format_): try: # Does this string format method work? out = format_func(format_, val) # Require that the format statement actually did something. if out == format_: raise ValueError('the format passed in did nothing.') except Exception: continue else: break else: # None of the possible string functions passed muster. raise ValueError('unable to parse format string {} for its ' 'column.'.format(format_)) # String-based format functions will fail on masked elements; # wrap them in a function that traps them. format_func = _use_str_for_masked_values(format_func) col.info._format_funcs[format_] = format_func return out return _auto_format_func def _get_pprint_include_names(table): """Get the set of names to show in pprint from the table pprint_include_names and pprint_exclude_names attributes. These may be fnmatch unix-style globs. """ def get_matches(name_globs, default): match_names = set() if name_globs: # For None or () use the default for name in table.colnames: for name_glob in name_globs: if fnmatch.fnmatch(name, name_glob): match_names.add(name) break else: match_names.update(default) return match_names include_names = get_matches(table.pprint_include_names(), table.colnames) exclude_names = get_matches(table.pprint_exclude_names(), []) return include_names - exclude_names class TableFormatter: @staticmethod def _get_pprint_size(max_lines=None, max_width=None): """Get the output size (number of lines and character width) for Column and Table pformat/pprint methods. If no value of ``max_lines`` is supplied then the height of the screen terminal is used to set ``max_lines``. If the terminal height cannot be determined then the default will be determined using the ``astropy.table.conf.max_lines`` configuration item. If a negative value of ``max_lines`` is supplied then there is no line limit applied. The same applies for max_width except the configuration item is ``astropy.table.conf.max_width``. Parameters ---------- max_lines : int or None Maximum lines of output (header + data rows) max_width : int or None Maximum width (characters) output Returns ------- max_lines, max_width : int """ # Declare to keep static type checker happy. lines = None width = None if max_lines is None: max_lines = conf.max_lines if max_width is None: max_width = conf.max_width if max_lines is None or max_width is None: lines, width = terminal_size() if max_lines is None: max_lines = lines elif max_lines < 0: max_lines = sys.maxsize if max_lines < 8: max_lines = 8 if max_width is None: max_width = width elif max_width < 0: max_width = sys.maxsize if max_width < 10: max_width = 10 return max_lines, max_width def _pformat_col(self, col, max_lines=None, show_name=True, show_unit=None, show_dtype=False, show_length=None, html=False, align=None): """Return a list of formatted string representation of column values. Parameters ---------- max_lines : int Maximum lines of output (header + data rows) show_name : bool Include column name. Default is True. show_unit : bool Include a header row for unit. Default is to show a row for units only if one or more columns has a defined value for the unit. show_dtype : bool Include column dtype. Default is False. show_length : bool Include column length at end. Default is to show this only if the column is not shown completely. html : bool Output column as HTML align : str Left/right alignment of columns. Default is '>' (right) for all columns. Other allowed values are '<', '^', and '0=' for left, centered, and 0-padded, respectively. Returns ------- lines : list List of lines with formatted column values outs : dict Dict which is used to pass back additional values defined within the iterator. """ if show_unit is None: show_unit = col.info.unit is not None outs = {} # Some values from _pformat_col_iter iterator that are needed here col_strs_iter = self._pformat_col_iter(col, max_lines, show_name=show_name, show_unit=show_unit, show_dtype=show_dtype, show_length=show_length, outs=outs) col_strs = list(col_strs_iter) if len(col_strs) > 0: col_width = max(len(x) for x in col_strs) if html: from astropy.utils.xml.writer import xml_escape n_header = outs['n_header'] for i, col_str in enumerate(col_strs): # _pformat_col output has a header line '----' which is not needed here if i == n_header - 1: continue td = 'th' if i < n_header else 'td' val = f'<{td}>{xml_escape(col_str.strip())}' row = ('' + val + '') if i < n_header: row = ('' + row + '') col_strs[i] = row if n_header > 0: # Get rid of '---' header line col_strs.pop(n_header - 1) col_strs.insert(0, '
') col_strs.append('
') # Now bring all the column string values to the same fixed width else: col_width = max(len(x) for x in col_strs) if col_strs else 1 # Center line header content and generate dashed headerline for i in outs['i_centers']: col_strs[i] = col_strs[i].center(col_width) if outs['i_dashes'] is not None: col_strs[outs['i_dashes']] = '-' * col_width # Format columns according to alignment. `align` arg has precedent, otherwise # use `col.format` if it starts as a legal alignment string. If neither applies # then right justify. re_fill_align = re.compile(r'(?P.?)(?P[<^>=])') match = None if align: # If there is an align specified then it must match match = re_fill_align.match(align) if not match: raise ValueError("column align must be one of '<', '^', '>', or '='") elif isinstance(col.info.format, str): # col.info.format need not match, in which case rjust gets used match = re_fill_align.match(col.info.format) if match: fill_char = match.group('fill') align_char = match.group('align') if align_char == '=': if fill_char != '0': raise ValueError("fill character must be '0' for '=' align") fill_char = '' # str.zfill gets used which does not take fill char arg else: fill_char = '' align_char = '>' justify_methods = {'<': 'ljust', '^': 'center', '>': 'rjust', '=': 'zfill'} justify_method = justify_methods[align_char] justify_args = (col_width, fill_char) if fill_char else (col_width,) for i, col_str in enumerate(col_strs): col_strs[i] = getattr(col_str, justify_method)(*justify_args) if outs['show_length']: col_strs.append(f'Length = {len(col)} rows') return col_strs, outs def _pformat_col_iter(self, col, max_lines, show_name, show_unit, outs, show_dtype=False, show_length=None): """Iterator which yields formatted string representation of column values. Parameters ---------- max_lines : int Maximum lines of output (header + data rows) show_name : bool Include column name. Default is True. show_unit : bool Include a header row for unit. Default is to show a row for units only if one or more columns has a defined value for the unit. outs : dict Must be a dict which is used to pass back additional values defined within the iterator. show_dtype : bool Include column dtype. Default is False. show_length : bool Include column length at end. Default is to show this only if the column is not shown completely. """ max_lines, _ = self._get_pprint_size(max_lines, -1) multidims = getattr(col, 'shape', [0])[1:] if multidims: multidim0 = tuple(0 for n in multidims) multidim1 = tuple(n - 1 for n in multidims) trivial_multidims = np.prod(multidims) == 1 i_dashes = None i_centers = [] # Line indexes where content should be centered n_header = 0 if show_name: i_centers.append(n_header) # Get column name (or 'None' if not set) col_name = str(col.info.name) if multidims: col_name += f" [{','.join(str(n) for n in multidims)}]" n_header += 1 yield col_name if show_unit: i_centers.append(n_header) n_header += 1 yield str(col.info.unit or '') if show_dtype: i_centers.append(n_header) n_header += 1 try: dtype = dtype_info_name(col.dtype) except AttributeError: dtype = col.__class__.__qualname__ or 'object' yield str(dtype) if show_unit or show_name or show_dtype: i_dashes = n_header n_header += 1 yield '---' max_lines -= n_header n_print2 = max_lines // 2 n_rows = len(col) # This block of code is responsible for producing the function that # will format values for this column. The ``format_func`` function # takes two args (col_format, val) and returns the string-formatted # version. Some points to understand: # # - col_format could itself be the formatting function, so it will # actually end up being called with itself as the first arg. In # this case the function is expected to ignore its first arg. # # - auto_format_func is a function that gets called on the first # column value that is being formatted. It then determines an # appropriate formatting function given the actual value to be # formatted. This might be deterministic or it might involve # try/except. The latter allows for different string formatting # options like %f or {:5.3f}. When auto_format_func is called it: # 1. Caches the function in the _format_funcs dict so for subsequent # values the right function is called right away. # 2. Returns the formatted value. # # - possible_string_format_functions is a function that yields a # succession of functions that might successfully format the # value. There is a default, but Mixin methods can override this. # See Quantity for an example. # # - get_auto_format_func() returns a wrapped version of auto_format_func # with the column id and possible_string_format_functions as # enclosed variables. col_format = col.info.format or getattr(col.info, 'default_format', None) pssf = (getattr(col.info, 'possible_string_format_functions', None) or _possible_string_format_functions) auto_format_func = get_auto_format_func(col, pssf) format_func = col.info._format_funcs.get(col_format, auto_format_func) if len(col) > max_lines: if show_length is None: show_length = True i0 = n_print2 - (1 if show_length else 0) i1 = n_rows - n_print2 - max_lines % 2 indices = np.concatenate([np.arange(0, i0 + 1), np.arange(i1 + 1, len(col))]) else: i0 = -1 indices = np.arange(len(col)) def format_col_str(idx): if multidims: # Prevents columns like Column(data=[[(1,)],[(2,)]], name='a') # with shape (n,1,...,1) from being printed as if there was # more than one element in a row if trivial_multidims: return format_func(col_format, col[(idx,) + multidim0]) else: left = format_func(col_format, col[(idx,) + multidim0]) right = format_func(col_format, col[(idx,) + multidim1]) return f'{left} .. {right}' else: return format_func(col_format, col[idx]) # Add formatted values if within bounds allowed by max_lines for idx in indices: if idx == i0: yield '...' else: try: yield format_col_str(idx) except ValueError: raise ValueError( 'Unable to parse format string "{}" for entry "{}" ' 'in column "{}"'.format(col_format, col[idx], col.info.name)) outs['show_length'] = show_length outs['n_header'] = n_header outs['i_centers'] = i_centers outs['i_dashes'] = i_dashes def _pformat_table(self, table, max_lines=None, max_width=None, show_name=True, show_unit=None, show_dtype=False, html=False, tableid=None, tableclass=None, align=None): """Return a list of lines for the formatted string representation of the table. Parameters ---------- max_lines : int or None Maximum number of rows to output max_width : int or None Maximum character width of output show_name : bool Include a header row for column names. Default is True. show_unit : bool Include a header row for unit. Default is to show a row for units only if one or more columns has a defined value for the unit. show_dtype : bool Include a header row for column dtypes. Default is False. html : bool Format the output as an HTML table. Default is False. tableid : str or None An ID tag for the table; only used if html is set. Default is "table{id}", where id is the unique integer id of the table object, id(table) tableclass : str or list of str or None CSS classes for the table; only used if html is set. Default is none align : str or list or tuple Left/right alignment of columns. Default is '>' (right) for all columns. Other allowed values are '<', '^', and '0=' for left, centered, and 0-padded, respectively. A list of strings can be provided for alignment of tables with multiple columns. Returns ------- rows : list Formatted table as a list of strings outs : dict Dict which is used to pass back additional values defined within the iterator. """ # "Print" all the values into temporary lists by column for subsequent # use and to determine the width max_lines, max_width = self._get_pprint_size(max_lines, max_width) if show_unit is None: show_unit = any(col.info.unit for col in table.columns.values()) # Coerce align into a correctly-sized list of alignments (if possible) n_cols = len(table.columns) if align is None or isinstance(align, str): align = [align] * n_cols elif isinstance(align, (list, tuple)): if len(align) != n_cols: raise ValueError('got {} alignment values instead of ' 'the number of columns ({})' .format(len(align), n_cols)) else: raise TypeError('align keyword must be str or list or tuple (got {})' .format(type(align))) # Process column visibility from table pprint_include_names and # pprint_exclude_names attributes and get the set of columns to show. pprint_include_names = _get_pprint_include_names(table) cols = [] outs = None # Initialize so static type checker is happy for align_, col in zip(align, table.columns.values()): if col.info.name not in pprint_include_names: continue lines, outs = self._pformat_col(col, max_lines, show_name=show_name, show_unit=show_unit, show_dtype=show_dtype, align=align_) if outs['show_length']: lines = lines[:-1] cols.append(lines) if not cols: return [''], {'show_length': False} # Use the values for the last column since they are all the same n_header = outs['n_header'] n_rows = len(cols[0]) def outwidth(cols): return sum(len(c[0]) for c in cols) + len(cols) - 1 dots_col = ['...'] * n_rows middle = len(cols) // 2 while outwidth(cols) > max_width: if len(cols) == 1: break if len(cols) == 2: cols[1] = dots_col break if cols[middle] is dots_col: cols.pop(middle) middle = len(cols) // 2 cols[middle] = dots_col # Now "print" the (already-stringified) column values into a # row-oriented list. rows = [] if html: from astropy.utils.xml.writer import xml_escape if tableid is None: tableid = f'table{id(table)}' if tableclass is not None: if isinstance(tableclass, list): tableclass = ' '.join(tableclass) rows.append(f'') else: rows.append(f'
') for i in range(n_rows): # _pformat_col output has a header line '----' which is not needed here if i == n_header - 1: continue td = 'th' if i < n_header else 'td' vals = (f'<{td}>{xml_escape(col[i].strip())}' for col in cols) row = ('' + ''.join(vals) + '') if i < n_header: row = ('' + row + '') rows.append(row) rows.append('
') else: for i in range(n_rows): row = ' '.join(col[i] for col in cols) rows.append(row) return rows, outs def _more_tabcol(self, tabcol, max_lines=None, max_width=None, show_name=True, show_unit=None, show_dtype=False): """Interactive "more" of a table or column. Parameters ---------- max_lines : int or None Maximum number of rows to output max_width : int or None Maximum character width of output show_name : bool Include a header row for column names. Default is True. show_unit : bool Include a header row for unit. Default is to show a row for units only if one or more columns has a defined value for the unit. show_dtype : bool Include a header row for column dtypes. Default is False. """ allowed_keys = 'f br<>qhpn' # Count the header lines n_header = 0 if show_name: n_header += 1 if show_unit: n_header += 1 if show_dtype: n_header += 1 if show_name or show_unit or show_dtype: n_header += 1 # Set up kwargs for pformat call. Only Table gets max_width. kwargs = dict(max_lines=-1, show_name=show_name, show_unit=show_unit, show_dtype=show_dtype) if hasattr(tabcol, 'columns'): # tabcol is a table kwargs['max_width'] = max_width # If max_lines is None (=> query screen size) then increase by 2. # This is because get_pprint_size leaves 6 extra lines so that in # ipython you normally see the last input line. max_lines1, max_width = self._get_pprint_size(max_lines, max_width) if max_lines is None: max_lines1 += 2 delta_lines = max_lines1 - n_header # Set up a function to get a single character on any platform inkey = Getch() i0 = 0 # First table/column row to show showlines = True while True: i1 = i0 + delta_lines # Last table/col row to show if showlines: # Don't always show the table (e.g. after help) try: os.system('cls' if os.name == 'nt' else 'clear') except Exception: pass # No worries if clear screen call fails lines = tabcol[i0:i1].pformat(**kwargs) colors = ('red' if i < n_header else 'default' for i in range(len(lines))) for color, line in zip(colors, lines): color_print(line, color) showlines = True print() print("-- f, , b, r, p, n, <, >, q h (help) --", end=' ') # Get a valid key while True: try: key = inkey().lower() except Exception: print("\n") log.error('Console does not support getting a character' ' as required by more(). Use pprint() instead.') return if key in allowed_keys: break print(key) if key.lower() == 'q': break elif key == ' ' or key == 'f': i0 += delta_lines elif key == 'b': i0 = i0 - delta_lines elif key == 'r': pass elif key == '<': i0 = 0 elif key == '>': i0 = len(tabcol) elif key == 'p': i0 -= 1 elif key == 'n': i0 += 1 elif key == 'h': showlines = False print(""" Browsing keys: f, : forward one page b : back one page r : refresh same page n : next row p : previous row < : go to beginning > : go to end q : quit browsing h : print this help""", end=' ') if i0 < 0: i0 = 0 if i0 >= len(tabcol) - delta_lines: i0 = len(tabcol) - delta_lines print("\n") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/row.py0000644000175100001710000001500700000000000016221 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import collections from collections import OrderedDict from operator import index as operator_index import numpy as np class Row: """A class to represent one row of a Table object. A Row object is returned when a Table object is indexed with an integer or when iterating over a table:: >>> from astropy.table import Table >>> table = Table([(1, 2), (3, 4)], names=('a', 'b'), ... dtype=('int32', 'int32')) >>> row = table[1] >>> row a b int32 int32 ----- ----- 2 4 >>> row['a'] 2 >>> row[1] 4 """ def __init__(self, table, index): # Ensure that the row index is a valid index (int) index = operator_index(index) n = len(table) if index < -n or index >= n: raise IndexError('index {} out of range for table with length {}' .format(index, len(table))) # Finally, ensure the index is positive [#8422] and set Row attributes self._index = index % n self._table = table def __getitem__(self, item): try: # Try the most common use case of accessing a single column in the Row. # Bypass the TableColumns __getitem__ since that does more testing # and allows a list of tuple or str, which is not the right thing here. out = OrderedDict.__getitem__(self._table.columns, item)[self._index] except (KeyError, TypeError): if self._table._is_list_or_tuple_of_str(item): cols = [self._table[name] for name in item] out = self._table.__class__(cols, copy=False)[self._index] else: # This is only to raise an exception out = self._table.columns[item][self._index] return out def __setitem__(self, item, val): if self._table._is_list_or_tuple_of_str(item): self._table._set_row(self._index, colnames=item, vals=val) else: self._table.columns[item][self._index] = val def _ipython_key_completions_(self): return self.colnames def __eq__(self, other): if self._table.masked: # Sent bug report to numpy-discussion group on 2012-Oct-21, subject: # "Comparing rows in a structured masked array raises exception" # No response, so this is still unresolved. raise ValueError('Unable to compare rows for masked table due to numpy.ma bug') return self.as_void() == other def __ne__(self, other): if self._table.masked: raise ValueError('Unable to compare rows for masked table due to numpy.ma bug') return self.as_void() != other def __array__(self, dtype=None): """Support converting Row to np.array via np.array(table). Coercion to a different dtype via np.array(table, dtype) is not supported and will raise a ValueError. If the parent table is masked then the mask information is dropped. """ if dtype is not None: raise ValueError('Datatype coercion is not allowed') return np.asarray(self.as_void()) def __len__(self): return len(self._table.columns) def __iter__(self): index = self._index for col in self._table.columns.values(): yield col[index] def keys(self): return self._table.columns.keys() def values(self): return self.__iter__() @property def table(self): return self._table @property def index(self): return self._index def as_void(self): """ Returns a *read-only* copy of the row values in the form of np.void or np.ma.mvoid objects. This corresponds to the object types returned for row indexing of a pure numpy structured array or masked array. This method is slow and its use is discouraged when possible. Returns ------- void_row : ``numpy.void`` or ``numpy.ma.mvoid`` Copy of row values. ``numpy.void`` if unmasked, ``numpy.ma.mvoid`` else. """ index = self._index cols = self._table.columns.values() vals = tuple(np.asarray(col)[index] for col in cols) if self._table.masked: # The logic here is a little complicated to work around # bug in numpy < 1.8 (numpy/numpy#483). Need to build up # a np.ma.mvoid object by hand. from .table import descr # Make np.void version of masks. Use the table dtype but # substitute bool for data type masks = tuple(col.mask[index] if hasattr(col, 'mask') else False for col in cols) descrs = (descr(col) for col in cols) mask_dtypes = [(name, bool, shape) for name, type_, shape in descrs] row_mask = np.array([masks], dtype=mask_dtypes)[0] # Make np.void version of values, and then the final mvoid row row_vals = np.array([vals], dtype=self.dtype)[0] void_row = np.ma.mvoid(data=row_vals, mask=row_mask) else: void_row = np.array([vals], dtype=self.dtype)[0] return void_row @property def meta(self): return self._table.meta @property def columns(self): return self._table.columns @property def colnames(self): return self._table.colnames @property def dtype(self): return self._table.dtype def _base_repr_(self, html=False): """ Display row as a single-line table but with appropriate header line. """ index = self.index if (self.index >= 0) else self.index + len(self._table) table = self._table[index:index + 1] descr_vals = [self.__class__.__name__, f'index={self.index}'] if table.masked: descr_vals.append('masked=True') return table._base_repr_(html, descr_vals, max_width=-1, tableid=f'table{id(self._table)}') def _repr_html_(self): return self._base_repr_(html=True) def __repr__(self): return self._base_repr_(html=False) def __str__(self): index = self.index if (self.index >= 0) else self.index + len(self._table) return '\n'.join(self.table[index:index + 1].pformat(max_width=-1)) def __bytes__(self): return str(self).encode('utf-8') collections.abc.Sequence.register(Row) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1672513 astropy-5.0.2/astropy/table/scripts/0000755000175100001710000000000000000000000016524 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/scripts/__init__.py0000644000175100001710000000000000000000000020623 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/scripts/showtable.py0000644000175100001710000001252600000000000021074 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ ``showtable`` is a command-line script based on ``astropy.io`` and ``astropy.table`` for printing ASCII, FITS, HDF5 or VOTable files(s) to the standard output. Example usage of ``showtable``: 1. FITS:: $ showtable astropy/io/fits/tests/data/table.fits target V_mag ------- ----- NGC1001 11.1 NGC1002 12.3 NGC1003 15.2 2. ASCII:: $ showtable astropy/io/ascii/tests/t/simple_csv.csv a b c --- --- --- 1 2 3 4 5 6 3. XML:: $ showtable astropy/io/votable/tests/data/names.xml --max-width 70 col1 col2 col3 ... col15 col16 col17 --- deg deg ... mag mag --- ------------------------- -------- ------- ... ----- ----- ----- SSTGLMC G000.0000+00.1611 0.0000 0.1611 ... -- -- AA 4. Print all the FITS tables in the current directory:: $ showtable *.fits """ import argparse import textwrap import warnings from astropy import log from astropy.table import Table from astropy.utils.exceptions import AstropyUserWarning def showtable(filename, args): """ Read a table and print to the standard output. Parameters ---------- filename : str The path to a FITS file. """ if args.info and args.stats: warnings.warn('--info and --stats cannot be used together', AstropyUserWarning) if (any((args.max_lines, args.max_width, args.hide_unit, args.show_dtype)) and (args.info or args.stats)): warnings.warn('print parameters are ignored if --info or --stats is ' 'used', AstropyUserWarning) # these parameters are passed to Table.read if they are specified in the # command-line read_kwargs = ('hdu', 'format', 'table_id', 'delimiter') kwargs = {k: v for k, v in vars(args).items() if k in read_kwargs and v is not None} try: table = Table.read(filename, **kwargs) if args.info: table.info('attributes') elif args.stats: table.info('stats') else: formatter = table.more if args.more else table.pprint formatter(max_lines=args.max_lines, max_width=args.max_width, show_unit=(False if args.hide_unit else None), show_dtype=args.show_dtype) except IOError as e: log.error(str(e)) def main(args=None): """The main function called by the `showtable` script.""" parser = argparse.ArgumentParser( description=textwrap.dedent(""" Print tables from ASCII, FITS, HDF5, VOTable file(s). The tables are read with 'astropy.table.Table.read' and are printed with 'astropy.table.Table.pprint'. The default behavior is to make the table output fit onto a single screen page. For a long and wide table this will mean cutting out inner rows and columns. To print **all** the rows or columns use ``--max-lines=-1`` or ``max-width=-1``, respectively. The complete list of supported formats can be found at http://astropy.readthedocs.io/en/latest/io/unified.html#built-in-table-readers-writers """)) addarg = parser.add_argument addarg('filename', nargs='+', help='path to one or more files') addarg('--format', help='input table format, should be specified if it ' 'cannot be automatically detected') addarg('--more', action='store_true', help='use the pager mode from Table.more') addarg('--info', action='store_true', help='show information about the table columns') addarg('--stats', action='store_true', help='show statistics about the table columns') # pprint arguments pprint_args = parser.add_argument_group('pprint arguments') addarg = pprint_args.add_argument addarg('--max-lines', type=int, help='maximum number of lines in table output (default=screen ' 'length, -1 for no limit)') addarg('--max-width', type=int, help='maximum width in table output (default=screen width, ' '-1 for no limit)') addarg('--hide-unit', action='store_true', help='hide the header row for unit (which is shown ' 'only if one or more columns has a unit)') addarg('--show-dtype', action='store_true', help='include a header row for column dtypes') # ASCII-specific arguments ascii_args = parser.add_argument_group('ASCII arguments') addarg = ascii_args.add_argument addarg('--delimiter', help='column delimiter string') # FITS-specific arguments fits_args = parser.add_argument_group('FITS arguments') addarg = fits_args.add_argument addarg('--hdu', help='name of the HDU to show') # HDF5-specific arguments hdf5_args = parser.add_argument_group('HDF5 arguments') addarg = hdf5_args.add_argument addarg('--path', help='the path from which to read the table') # VOTable-specific arguments votable_args = parser.add_argument_group('VOTable arguments') addarg = votable_args.add_argument addarg('--table-id', help='the table to read in') args = parser.parse_args(args) for idx, filename in enumerate(args.filename): if idx > 0: print() showtable(filename, args) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/serialize.py0000644000175100001710000003767400000000000017417 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst from importlib import import_module import re from copy import deepcopy from collections import OrderedDict import numpy as np from astropy.utils.data_info import MixinInfo from .column import Column, MaskedColumn from .table import Table, QTable, has_info_class from astropy.units.quantity import QuantityInfo # TODO: some of this might be better done programmatically, through # code like # __construct_mixin_classes += tuple( # f'astropy.coordinates.representation.{cls.__name__}' # for cls in (list(coorep.REPRESENTATION_CLASSES.values()) # + list(coorep.DIFFERENTIAL_CLASSES.values())) # if cls.__name__ in coorep.__all__) # However, to avoid very hard to track import issues, the definition # should then be done at the point where it is actually needed, # using local imports. See also # https://github.com/astropy/astropy/pull/10210#discussion_r419087286 __construct_mixin_classes = ( 'astropy.time.core.Time', 'astropy.time.core.TimeDelta', 'astropy.units.quantity.Quantity', 'astropy.units.function.logarithmic.Magnitude', 'astropy.units.function.logarithmic.Decibel', 'astropy.units.function.logarithmic.Dex', 'astropy.coordinates.angles.Latitude', 'astropy.coordinates.angles.Longitude', 'astropy.coordinates.angles.Angle', 'astropy.coordinates.distances.Distance', 'astropy.coordinates.earth.EarthLocation', 'astropy.coordinates.sky_coordinate.SkyCoord', 'astropy.table.ndarray_mixin.NdarrayMixin', 'astropy.table.table_helpers.ArrayWrapper', 'astropy.table.column.MaskedColumn', 'astropy.coordinates.representation.CartesianRepresentation', 'astropy.coordinates.representation.UnitSphericalRepresentation', 'astropy.coordinates.representation.RadialRepresentation', 'astropy.coordinates.representation.SphericalRepresentation', 'astropy.coordinates.representation.PhysicsSphericalRepresentation', 'astropy.coordinates.representation.CylindricalRepresentation', 'astropy.coordinates.representation.CartesianDifferential', 'astropy.coordinates.representation.UnitSphericalDifferential', 'astropy.coordinates.representation.SphericalDifferential', 'astropy.coordinates.representation.UnitSphericalCosLatDifferential', 'astropy.coordinates.representation.SphericalCosLatDifferential', 'astropy.coordinates.representation.RadialDifferential', 'astropy.coordinates.representation.PhysicsSphericalDifferential', 'astropy.coordinates.representation.CylindricalDifferential', 'astropy.utils.masked.core.MaskedNDArray', ) class SerializedColumn(dict): """ Subclass of dict that is a used in the representation to contain the name (and possible other info) for a mixin attribute (either primary data or an array-like attribute) that is serialized as a column in the table. Normally contains the single key ``name`` with the name of the column in the table. """ pass def _represent_mixin_as_column(col, name, new_cols, mixin_cols, exclude_classes=()): """Carry out processing needed to serialize ``col`` in an output table consisting purely of plain ``Column`` or ``MaskedColumn`` columns. This relies on the object determine if any transformation is required and may depend on the ``serialize_method`` and ``serialize_context`` context variables. For instance a ``MaskedColumn`` may be stored directly to FITS, but can also be serialized as separate data and mask columns. This function builds up a list of plain columns in the ``new_cols`` arg (which is passed as a persistent list). This includes both plain columns from the original table and plain columns that represent data from serialized columns (e.g. ``jd1`` and ``jd2`` arrays from a ``Time`` column). For serialized columns the ``mixin_cols`` dict is updated with required attributes and information to subsequently reconstruct the table. Table mixin columns are always serialized and get represented by one or more data columns. In earlier versions of the code *only* mixin columns were serialized, hence the use within this code of "mixin" to imply serialization. Starting with version 3.1, the non-mixin ``MaskedColumn`` can also be serialized. """ obj_attrs = col.info._represent_as_dict() # If serialization is not required (see function docstring above) # or explicitly specified as excluded, then treat as a normal column. if not obj_attrs or col.__class__ in exclude_classes: new_cols.append(col) return # Subtlety here is handling mixin info attributes. The basic list of such # attributes is: 'name', 'unit', 'dtype', 'format', 'description', 'meta'. # - name: handled directly [DON'T store] # - unit: DON'T store if this is a parent attribute # - dtype: captured in plain Column if relevant [DON'T store] # - format: possibly irrelevant but settable post-object creation [DO store] # - description: DO store # - meta: DO store info = {} for attr, nontrivial in (('unit', lambda x: x is not None and x != ''), ('format', lambda x: x is not None), ('description', lambda x: x is not None), ('meta', lambda x: x)): col_attr = getattr(col.info, attr) if nontrivial(col_attr): info[attr] = col_attr # Find column attributes that have the same length as the column itself. # These will be stored in the table as new columns (aka "data attributes"). # Examples include SkyCoord.ra (what is typically considered the data and is # always an array) and Skycoord.obs_time (which can be a scalar or an # array). data_attrs = [key for key, value in obj_attrs.items() if getattr(value, 'shape', ())[:1] == col.shape[:1]] for data_attr in data_attrs: data = obj_attrs[data_attr] # New column name combines the old name and attribute # (e.g. skycoord.ra, skycoord.dec).unless it is the primary data # attribute for the column (e.g. value for Quantity or data for # MaskedColumn). For primary data, we attempt to store any info on # the format, etc., on the column, but not for ancillary data (e.g., # no sense to use a float format for a mask). is_primary = data_attr == col.info._represent_as_dict_primary_data if is_primary: new_name = name new_info = info else: new_name = name + '.' + data_attr new_info = {} if not has_info_class(data, MixinInfo): col_cls = MaskedColumn if (hasattr(data, 'mask') and np.any(data.mask)) else Column new_cols.append(col_cls(data, name=new_name, **new_info)) obj_attrs[data_attr] = SerializedColumn({'name': new_name}) if is_primary: # Don't store info in the __serialized_columns__ dict for this column # since this is redundant with info stored on the new column. info = {} else: # recurse. This will define obj_attrs[new_name]. _represent_mixin_as_column(data, new_name, new_cols, obj_attrs) obj_attrs[data_attr] = SerializedColumn(obj_attrs.pop(new_name)) # Strip out from info any attributes defined by the parent, # and store whatever remains. for attr in col.info.attrs_from_parent: if attr in info: del info[attr] if info: obj_attrs['__info__'] = info # Store the fully qualified class name obj_attrs.setdefault('__class__', col.__module__ + '.' + col.__class__.__name__) mixin_cols[name] = obj_attrs def represent_mixins_as_columns(tbl, exclude_classes=()): """Represent input Table ``tbl`` using only `~astropy.table.Column` or `~astropy.table.MaskedColumn` objects. This function represents any mixin columns like `~astropy.time.Time` in ``tbl`` to one or more plain ``~astropy.table.Column`` objects and returns a new Table. A single mixin column may be split into multiple column components as needed for fully representing the column. This includes the possibility of recursive splitting, as shown in the example below. The new column names are formed as ``.``, e.g. ``sc.ra`` for a `~astropy.coordinates.SkyCoord` column named ``sc``. In addition to splitting columns, this function updates the table ``meta`` dictionary to include a dict named ``__serialized_columns__`` which provides additional information needed to construct the original mixin columns from the split columns. This function is used by astropy I/O when writing tables to ECSV, FITS, HDF5 formats. Note that if the table does not include any mixin columns then the original table is returned with no update to ``meta``. Parameters ---------- tbl : `~astropy.table.Table` or subclass Table to represent mixins as Columns exclude_classes : tuple of class Exclude any mixin columns which are instannces of any classes in the tuple Returns ------- tbl : `~astropy.table.Table` New Table with updated columns, or else the original input ``tbl`` Examples -------- >>> from astropy.table import Table, represent_mixins_as_columns >>> from astropy.time import Time >>> from astropy.coordinates import SkyCoord >>> x = [100.0, 200.0] >>> obstime = Time([1999.0, 2000.0], format='jyear') >>> sc = SkyCoord([1, 2], [3, 4], unit='deg', obstime=obstime) >>> tbl = Table([sc, x], names=['sc', 'x']) >>> represent_mixins_as_columns(tbl) sc.ra sc.dec sc.obstime.jd1 sc.obstime.jd2 x deg deg float64 float64 float64 float64 float64 ------- ------- -------------- -------------- ------- 1.0 3.0 2451180.0 -0.25 100.0 2.0 4.0 2451545.0 0.0 200.0 """ # Dict of metadata for serializing each column, keyed by column name. # Gets filled in place by _represent_mixin_as_column(). mixin_cols = {} # List of columns for the output table. For plain Column objects # this will just be the original column object. new_cols = [] # Go through table columns and represent each column as one or more # plain Column objects (in new_cols) + metadata (in mixin_cols). for col in tbl.itercols(): _represent_mixin_as_column(col, col.info.name, new_cols, mixin_cols, exclude_classes=exclude_classes) # If no metadata was created then just return the original table. if mixin_cols: meta = deepcopy(tbl.meta) meta['__serialized_columns__'] = mixin_cols out = Table(new_cols, meta=meta, copy=False) else: out = tbl for col in out.itercols(): if not isinstance(col, Column) and col.__class__ not in exclude_classes: # This catches columns for which info has not been set up right and # therefore were not converted. See the corresponding test in # test_mixin.py for an example. raise TypeError( 'failed to represent column ' f'{col.info.name!r} ({col.__class__.__name__}) as one ' 'or more Column subclasses. This looks like a mixin class ' 'that does not have the correct _represent_as_dict() method ' 'in the class `info` attribute.') return out def _construct_mixin_from_obj_attrs_and_info(obj_attrs, info): cls_full_name = obj_attrs.pop('__class__') # If this is a supported class then import the class and run # the _construct_from_col method. Prevent accidentally running # untrusted code by only importing known astropy classes. if cls_full_name not in __construct_mixin_classes: raise ValueError(f'unsupported class for construct {cls_full_name}') mod_name, cls_name = re.match(r'(.+)\.(\w+)', cls_full_name).groups() module = import_module(mod_name) cls = getattr(module, cls_name) for attr, value in info.items(): if attr in cls.info.attrs_from_parent: obj_attrs[attr] = value mixin = cls.info._construct_from_dict(obj_attrs) for attr, value in info.items(): if attr not in obj_attrs: setattr(mixin.info, attr, value) return mixin class _TableLite(OrderedDict): """ Minimal table-like object for _construct_mixin_from_columns. This allows manipulating the object like a Table but without the actual overhead for a full Table. More pressing, there is an issue with constructing MaskedColumn, where the encoded Column components (data, mask) are turned into a MaskedColumn. When this happens in a real table then all other columns are immediately Masked and a warning is issued. This is not desirable. """ def add_column(self, col, index=0): colnames = self.colnames self[col.info.name] = col for ii, name in enumerate(colnames): if ii >= index: self.move_to_end(name) @property def colnames(self): return list(self.keys()) def itercols(self): return self.values() def _construct_mixin_from_columns(new_name, obj_attrs, out): data_attrs_map = {} for name, val in obj_attrs.items(): if isinstance(val, SerializedColumn): if 'name' in val: data_attrs_map[val['name']] = name else: out_name = f'{new_name}.{name}' _construct_mixin_from_columns(out_name, val, out) data_attrs_map[out_name] = name for name in data_attrs_map.values(): del obj_attrs[name] # Get the index where to add new column idx = min(out.colnames.index(name) for name in data_attrs_map) # Name is the column name in the table (e.g. "coord.ra") and # data_attr is the object attribute name (e.g. "ra"). A different # example would be a formatted time object that would have (e.g.) # "time_col" and "value", respectively. for name, data_attr in data_attrs_map.items(): obj_attrs[data_attr] = out[name] del out[name] info = obj_attrs.pop('__info__', {}) if len(data_attrs_map) == 1: # col is the first and only serialized column; in that case, use info # stored on the column. First step is to get that first column which # has been moved from `out` to `obj_attrs` above. data_attr = next(iter(data_attrs_map.values())) col = obj_attrs[data_attr] # Now copy the relevant attributes for attr, nontrivial in (('unit', lambda x: x not in (None, '')), ('format', lambda x: x is not None), ('description', lambda x: x is not None), ('meta', lambda x: x)): col_attr = getattr(col.info, attr) if nontrivial(col_attr): info[attr] = col_attr info['name'] = new_name col = _construct_mixin_from_obj_attrs_and_info(obj_attrs, info) out.add_column(col, index=idx) def _construct_mixins_from_columns(tbl): if '__serialized_columns__' not in tbl.meta: return tbl meta = tbl.meta.copy() mixin_cols = meta.pop('__serialized_columns__') out = _TableLite(tbl.columns) for new_name, obj_attrs in mixin_cols.items(): _construct_mixin_from_columns(new_name, obj_attrs, out) # If no quantity subclasses are in the output then output as Table. # For instance ascii.read(file, format='ecsv') doesn't specify an # output class and should return the minimal table class that # represents the table file. has_quantities = any(isinstance(col.info, QuantityInfo) for col in out.itercols()) out_cls = QTable if has_quantities else Table return out_cls(list(out.values()), names=out.colnames, copy=False, meta=meta) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/setup_package.py0000644000175100001710000000102300000000000020216 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import os from setuptools import Extension import numpy ROOT = os.path.relpath(os.path.dirname(__file__)) def get_extensions(): sources = ["_np_utils.pyx", "_column_mixins.pyx"] include_dirs = [numpy.get_include()] exts = [ Extension(name='astropy.table.' + os.path.splitext(source)[0], sources=[os.path.join(ROOT, source)], include_dirs=include_dirs) for source in sources ] return exts ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/soco.py0000644000175100001710000001171400000000000016356 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ The SCEngine class uses the ``sortedcontainers`` package to implement an Index engine for Tables. """ from collections import OrderedDict from itertools import starmap from astropy.utils.compat.optional_deps import HAS_SORTEDCONTAINERS if HAS_SORTEDCONTAINERS: from sortedcontainers import SortedList class Node(object): __slots__ = ('key', 'value') def __init__(self, key, value): self.key = key self.value = value def __lt__(self, other): if other.__class__ is Node: return (self.key, self.value) < (other.key, other.value) return self.key < other def __le__(self, other): if other.__class__ is Node: return (self.key, self.value) <= (other.key, other.value) return self.key <= other def __eq__(self, other): if other.__class__ is Node: return (self.key, self.value) == (other.key, other.value) return self.key == other def __ne__(self, other): if other.__class__ is Node: return (self.key, self.value) != (other.key, other.value) return self.key != other def __gt__(self, other): if other.__class__ is Node: return (self.key, self.value) > (other.key, other.value) return self.key > other def __ge__(self, other): if other.__class__ is Node: return (self.key, self.value) >= (other.key, other.value) return self.key >= other __hash__ = None def __repr__(self): return f'Node({self.key!r}, {self.value!r})' class SCEngine: ''' Fast tree-based implementation for indexing, using the ``sortedcontainers`` package. Parameters ---------- data : Table Sorted columns of the original table row_index : Column object Row numbers corresponding to data columns unique : bool Whether the values of the index must be unique. Defaults to False. ''' def __init__(self, data, row_index, unique=False): node_keys = map(tuple, data) self._nodes = SortedList(starmap(Node, zip(node_keys, row_index))) self._unique = unique def add(self, key, value): ''' Add a key, value pair. ''' if self._unique and (key in self._nodes): message = f'duplicate {key!r} in unique index' raise ValueError(message) self._nodes.add(Node(key, value)) def find(self, key): ''' Find rows corresponding to the given key. ''' return [node.value for node in self._nodes.irange(key, key)] def remove(self, key, data=None): ''' Remove data from the given key. ''' if data is not None: item = Node(key, data) try: self._nodes.remove(item) except ValueError: return False return True items = list(self._nodes.irange(key, key)) for item in items: self._nodes.remove(item) return bool(items) def shift_left(self, row): ''' Decrement rows larger than the given row. ''' for node in self._nodes: if node.value > row: node.value -= 1 def shift_right(self, row): ''' Increment rows greater than or equal to the given row. ''' for node in self._nodes: if node.value >= row: node.value += 1 def items(self): ''' Return a list of key, data tuples. ''' result = OrderedDict() for node in self._nodes: if node.key in result: result[node.key].append(node.value) else: result[node.key] = [node.value] return result.items() def sort(self): ''' Make row order align with key order. ''' for index, node in enumerate(self._nodes): node.value = index def sorted_data(self): ''' Return a list of rows in order sorted by key. ''' return [node.value for node in self._nodes] def range(self, lower, upper, bounds=(True, True)): ''' Return row values in the given range. ''' iterator = self._nodes.irange(lower, upper, bounds) return [node.value for node in iterator] def replace_rows(self, row_map): ''' Replace rows with the values in row_map. ''' nodes = [node for node in self._nodes if node.value in row_map] for node in nodes: node.value = row_map[node.value] self._nodes.clear() self._nodes.update(nodes) def __repr__(self): if len(self._nodes) > 6: nodes = list(self._nodes[:3]) + ['...'] + list(self._nodes[-3:]) else: nodes = self._nodes nodes_str = ', '.join(str(node) for node in nodes) return f'<{self.__class__.__name__} nodes={nodes_str}>' ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/sorted_array.py0000644000175100001710000002210500000000000020105 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import numpy as np def _searchsorted(array, val, side='left'): ''' Call np.searchsorted or use a custom binary search if necessary. ''' if hasattr(array, 'searchsorted'): return array.searchsorted(val, side=side) # Python binary search begin = 0 end = len(array) while begin < end: mid = (begin + end) // 2 if val > array[mid]: begin = mid + 1 elif val < array[mid]: end = mid elif side == 'right': begin = mid + 1 else: end = mid return begin class SortedArray: ''' Implements a sorted array container using a list of numpy arrays. Parameters ---------- data : Table Sorted columns of the original table row_index : Column object Row numbers corresponding to data columns unique : bool Whether the values of the index must be unique. Defaults to False. ''' def __init__(self, data, row_index, unique=False): self.data = data self.row_index = row_index self.num_cols = len(getattr(data, 'colnames', [])) self.unique = unique @property def cols(self): return list(self.data.columns.values()) def add(self, key, row): ''' Add a new entry to the sorted array. Parameters ---------- key : tuple Column values at the given row row : int Row number ''' pos = self.find_pos(key, row) # first >= key if self.unique and 0 <= pos < len(self.row_index) and \ all(self.data[pos][i] == key[i] for i in range(len(key))): # already exists raise ValueError(f'Cannot add duplicate value "{key}" in a unique index') self.data.insert_row(pos, key) self.row_index = self.row_index.insert(pos, row) def _get_key_slice(self, i, begin, end): ''' Retrieve the ith slice of the sorted array from begin to end. ''' if i < self.num_cols: return self.cols[i][begin:end] else: return self.row_index[begin:end] def find_pos(self, key, data, exact=False): ''' Return the index of the largest key in data greater than or equal to the given key, data pair. Parameters ---------- key : tuple Column key data : int Row number exact : bool If True, return the index of the given key in data or -1 if the key is not present. ''' begin = 0 end = len(self.row_index) num_cols = self.num_cols if not self.unique: # consider the row value as well key = key + (data,) num_cols += 1 # search through keys in lexicographic order for i in range(num_cols): key_slice = self._get_key_slice(i, begin, end) t = _searchsorted(key_slice, key[i]) # t is the smallest index >= key[i] if exact and (t == len(key_slice) or key_slice[t] != key[i]): # no match return -1 elif t == len(key_slice) or (t == 0 and len(key_slice) > 0 and key[i] < key_slice[0]): # too small or too large return begin + t end = begin + _searchsorted(key_slice, key[i], side='right') begin += t if begin >= len(self.row_index): # greater than all keys return begin return begin def find(self, key): ''' Find all rows matching the given key. Parameters ---------- key : tuple Column values Returns ------- matching_rows : list List of rows matching the input key ''' begin = 0 end = len(self.row_index) # search through keys in lexicographic order for i in range(self.num_cols): key_slice = self._get_key_slice(i, begin, end) t = _searchsorted(key_slice, key[i]) # t is the smallest index >= key[i] if t == len(key_slice) or key_slice[t] != key[i]: # no match return [] elif t == 0 and len(key_slice) > 0 and key[i] < key_slice[0]: # too small or too large return [] end = begin + _searchsorted(key_slice, key[i], side='right') begin += t if begin >= len(self.row_index): # greater than all keys return [] return self.row_index[begin:end] def range(self, lower, upper, bounds): ''' Find values in the given range. Parameters ---------- lower : tuple Lower search bound upper : tuple Upper search bound bounds : (2,) tuple of bool Indicates whether the search should be inclusive or exclusive with respect to the endpoints. The first argument corresponds to an inclusive lower bound, and the second argument to an inclusive upper bound. ''' lower_pos = self.find_pos(lower, 0) upper_pos = self.find_pos(upper, 0) if lower_pos == len(self.row_index): return [] lower_bound = tuple([col[lower_pos] for col in self.cols]) if not bounds[0] and lower_bound == lower: lower_pos += 1 # data[lower_pos] > lower # data[lower_pos] >= lower # data[upper_pos] >= upper if upper_pos < len(self.row_index): upper_bound = tuple([col[upper_pos] for col in self.cols]) if not bounds[1] and upper_bound == upper: upper_pos -= 1 # data[upper_pos] < upper elif upper_bound > upper: upper_pos -= 1 # data[upper_pos] <= upper return self.row_index[lower_pos:upper_pos + 1] def remove(self, key, data): ''' Remove the given entry from the sorted array. Parameters ---------- key : tuple Column values data : int Row number Returns ------- successful : bool Whether the entry was successfully removed ''' pos = self.find_pos(key, data, exact=True) if pos == -1: # key not found return False self.data.remove_row(pos) keep_mask = np.ones(len(self.row_index), dtype=bool) keep_mask[pos] = False self.row_index = self.row_index[keep_mask] return True def shift_left(self, row): ''' Decrement all row numbers greater than the input row. Parameters ---------- row : int Input row number ''' self.row_index[self.row_index > row] -= 1 def shift_right(self, row): ''' Increment all row numbers greater than or equal to the input row. Parameters ---------- row : int Input row number ''' self.row_index[self.row_index >= row] += 1 def replace_rows(self, row_map): ''' Replace all rows with the values they map to in the given dictionary. Any rows not present as keys in the dictionary will have their entries deleted. Parameters ---------- row_map : dict Mapping of row numbers to new row numbers ''' num_rows = len(row_map) keep_rows = np.zeros(len(self.row_index), dtype=bool) tagged = 0 for i, row in enumerate(self.row_index): if row in row_map: keep_rows[i] = True tagged += 1 if tagged == num_rows: break self.data = self.data[keep_rows] self.row_index = np.array( [row_map[x] for x in self.row_index[keep_rows]]) def items(self): ''' Retrieve all array items as a list of pairs of the form [(key, [row 1, row 2, ...]), ...] ''' array = [] last_key = None for i, key in enumerate(zip(*self.data.columns.values())): row = self.row_index[i] if key == last_key: array[-1][1].append(row) else: last_key = key array.append((key, [row])) return array def sort(self): ''' Make row order align with key order. ''' self.row_index = np.arange(len(self.row_index)) def sorted_data(self): ''' Return rows in sorted order. ''' return self.row_index def __getitem__(self, item): ''' Return a sliced reference to this sorted array. Parameters ---------- item : slice Slice to use for referencing ''' return SortedArray(self.data[item], self.row_index[item]) def __repr__(self): t = self.data.copy() t['rows'] = self.row_index return f'<{self.__class__.__name__} length={len(t)}>\n{t}' ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/table.py0000644000175100001710000044613200000000000016510 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst from .index import SlicedIndex, TableIndices, TableLoc, TableILoc, TableLocIndices import sys from collections import OrderedDict, defaultdict from collections.abc import Mapping import warnings from copy import deepcopy import types import itertools import weakref import numpy as np from numpy import ma from astropy import log from astropy.units import Quantity, QuantityInfo from astropy.utils import isiterable, ShapedLikeNDArray from astropy.utils.console import color_print from astropy.utils.exceptions import AstropyUserWarning from astropy.utils.masked import Masked from astropy.utils.metadata import MetaData, MetaAttribute from astropy.utils.data_info import BaseColumnInfo, MixinInfo, DataInfo from astropy.utils.decorators import format_doc from astropy.io.registry import UnifiedReadWriteMethod from . import groups from .pprint import TableFormatter from .column import (BaseColumn, Column, MaskedColumn, _auto_names, FalseArray, col_copy, _convert_sequence_data_to_array) from .row import Row from .np_utils import fix_column_name from .info import TableInfo from .index import Index, _IndexModeContext, get_index from .connect import TableRead, TableWrite from .ndarray_mixin import NdarrayMixin from .mixins.registry import get_mixin_handler from . import conf _implementation_notes = """ This string has informal notes concerning Table implementation for developers. Things to remember: - Table has customizable attributes ColumnClass, Column, MaskedColumn. Table.Column is normally just column.Column (same w/ MaskedColumn) but in theory they can be different. Table.ColumnClass is the default class used to create new non-mixin columns, and this is a function of the Table.masked attribute. Column creation / manipulation in a Table needs to respect these. - Column objects that get inserted into the Table.columns attribute must have the info.parent_table attribute set correctly. Beware just dropping an object into the columns dict since an existing column may be part of another Table and have parent_table set to point at that table. Dropping that column into `columns` of this Table will cause a problem for the old one so the column object needs to be copied (but not necessarily the data). Currently replace_column is always making a copy of both object and data if parent_table is set. This could be improved but requires a generic way to copy a mixin object but not the data. - Be aware of column objects that have indices set. - `cls.ColumnClass` is a property that effectively uses the `masked` attribute to choose either `cls.Column` or `cls.MaskedColumn`. """ __doctest_skip__ = ['Table.read', 'Table.write', 'Table._read', 'Table.convert_bytestring_to_unicode', 'Table.convert_unicode_to_bytestring', ] __doctest_requires__ = {'*pandas': ['pandas>=1.1']} _pprint_docs = """ {__doc__} Parameters ---------- max_lines : int or None Maximum number of lines in table output. max_width : int or None Maximum character width of output. show_name : bool Include a header row for column names. Default is True. show_unit : bool Include a header row for unit. Default is to show a row for units only if one or more columns has a defined value for the unit. show_dtype : bool Include a header row for column dtypes. Default is True. align : str or list or tuple or None Left/right alignment of columns. Default is right (None) for all columns. Other allowed values are '>', '<', '^', and '0=' for right, left, centered, and 0-padded, respectively. A list of strings can be provided for alignment of tables with multiple columns. """ _pformat_docs = """ {__doc__} Parameters ---------- max_lines : int or None Maximum number of rows to output max_width : int or None Maximum character width of output show_name : bool Include a header row for column names. Default is True. show_unit : bool Include a header row for unit. Default is to show a row for units only if one or more columns has a defined value for the unit. show_dtype : bool Include a header row for column dtypes. Default is True. html : bool Format the output as an HTML table. Default is False. tableid : str or None An ID tag for the table; only used if html is set. Default is "table{id}", where id is the unique integer id of the table object, id(self) align : str or list or tuple or None Left/right alignment of columns. Default is right (None) for all columns. Other allowed values are '>', '<', '^', and '0=' for right, left, centered, and 0-padded, respectively. A list of strings can be provided for alignment of tables with multiple columns. tableclass : str or list of str or None CSS classes for the table; only used if html is set. Default is None. Returns ------- lines : list Formatted table as a list of strings. """ class TableReplaceWarning(UserWarning): """ Warning class for cases when a table column is replaced via the Table.__setitem__ syntax e.g. t['a'] = val. This does not inherit from AstropyWarning because we want to use stacklevel=3 to show the user where the issue occurred in their code. """ pass def descr(col): """Array-interface compliant full description of a column. This returns a 3-tuple (name, type, shape) that can always be used in a structured array dtype definition. """ col_dtype = 'O' if (col.info.dtype is None) else col.info.dtype col_shape = col.shape[1:] if hasattr(col, 'shape') else () return (col.info.name, col_dtype, col_shape) def has_info_class(obj, cls): """Check if the object's info is an instance of cls.""" # We check info on the class of the instance, since on the instance # itself accessing 'info' has side effects in that it sets # obj.__dict__['info'] if it does not exist already. return isinstance(getattr(obj.__class__, 'info', None), cls) def _get_names_from_list_of_dict(rows): """Return list of column names if ``rows`` is a list of dict that defines table data. If rows is not a list of dict then return None. """ if rows is None: return None names = set() for row in rows: if not isinstance(row, Mapping): return None names.update(row) return list(names) # Note to future maintainers: when transitioning this to dict # be sure to change the OrderedDict ref(s) in Row and in __len__(). class TableColumns(OrderedDict): """OrderedDict subclass for a set of columns. This class enhances item access to provide convenient access to columns by name or index, including slice access. It also handles renaming of columns. The initialization argument ``cols`` can be a list of ``Column`` objects or any structure that is valid for initializing a Python dict. This includes a dict, list of (key, val) tuples or [key, val] lists, etc. Parameters ---------- cols : dict, list, tuple; optional Column objects as data structure that can init dict (see above) """ def __init__(self, cols={}): if isinstance(cols, (list, tuple)): # `cols` should be a list of two-tuples, but it is allowed to have # columns (BaseColumn or mixins) in the list. newcols = [] for col in cols: if has_info_class(col, BaseColumnInfo): newcols.append((col.info.name, col)) else: newcols.append(col) cols = newcols super().__init__(cols) def __getitem__(self, item): """Get items from a TableColumns object. :: tc = TableColumns(cols=[Column(name='a'), Column(name='b'), Column(name='c')]) tc['a'] # Column('a') tc[1] # Column('b') tc['a', 'b'] # tc[1:3] # """ if isinstance(item, str): return OrderedDict.__getitem__(self, item) elif isinstance(item, (int, np.integer)): return list(self.values())[item] elif (isinstance(item, np.ndarray) and item.shape == () and item.dtype.kind == 'i'): return list(self.values())[item.item()] elif isinstance(item, tuple): return self.__class__([self[x] for x in item]) elif isinstance(item, slice): return self.__class__([self[x] for x in list(self)[item]]) else: raise IndexError('Illegal key or index value for {} object' .format(self.__class__.__name__)) def __setitem__(self, item, value, validated=False): """ Set item in this dict instance, but do not allow directly replacing an existing column unless it is already validated (and thus is certain to not corrupt the table). NOTE: it is easily possible to corrupt a table by directly *adding* a new key to the TableColumns attribute of a Table, e.g. ``t.columns['jane'] = 'doe'``. """ if item in self and not validated: raise ValueError("Cannot replace column '{}'. Use Table.replace_column() instead." .format(item)) super().__setitem__(item, value) def __repr__(self): names = (f"'{x}'" for x in self.keys()) return f"<{self.__class__.__name__} names=({','.join(names)})>" def _rename_column(self, name, new_name): if name == new_name: return if new_name in self: raise KeyError(f"Column {new_name} already exists") # Rename column names in pprint include/exclude attributes as needed parent_table = self[name].info.parent_table if parent_table is not None: parent_table.pprint_exclude_names._rename(name, new_name) parent_table.pprint_include_names._rename(name, new_name) mapper = {name: new_name} new_names = [mapper.get(name, name) for name in self] cols = list(self.values()) self.clear() self.update(list(zip(new_names, cols))) def __delitem__(self, name): # Remove column names from pprint include/exclude attributes as needed. # __delitem__ also gets called for pop() and popitem(). parent_table = self[name].info.parent_table if parent_table is not None: # _remove() method does not require that `name` is in the attribute parent_table.pprint_exclude_names._remove(name) parent_table.pprint_include_names._remove(name) return super().__delitem__(name) def isinstance(self, cls): """ Return a list of columns which are instances of the specified classes. Parameters ---------- cls : class or tuple thereof Column class (including mixin) or tuple of Column classes. Returns ------- col_list : list of `Column` List of Column objects which are instances of given classes. """ cols = [col for col in self.values() if isinstance(col, cls)] return cols def not_isinstance(self, cls): """ Return a list of columns which are not instances of the specified classes. Parameters ---------- cls : class or tuple thereof Column class (including mixin) or tuple of Column classes. Returns ------- col_list : list of `Column` List of Column objects which are not instances of given classes. """ cols = [col for col in self.values() if not isinstance(col, cls)] return cols class TableAttribute(MetaAttribute): """ Descriptor to define a custom attribute for a Table subclass. The value of the ``TableAttribute`` will be stored in a dict named ``__attributes__`` that is stored in the table ``meta``. The attribute can be accessed and set in the usual way, and it can be provided when creating the object. Defining an attribute by this mechanism ensures that it will persist if the table is sliced or serialized, for example as a pickle or ECSV file. See the `~astropy.utils.metadata.MetaAttribute` documentation for additional details. Parameters ---------- default : object Default value for attribute Examples -------- >>> from astropy.table import Table, TableAttribute >>> class MyTable(Table): ... identifier = TableAttribute(default=1) >>> t = MyTable(identifier=10) >>> t.identifier 10 >>> t.meta OrderedDict([('__attributes__', {'identifier': 10})]) """ class PprintIncludeExclude(TableAttribute): """Maintain tuple that controls table column visibility for print output. This is a descriptor that inherits from MetaAttribute so that the attribute value is stored in the table meta['__attributes__']. This gets used for the ``pprint_include_names`` and ``pprint_exclude_names`` Table attributes. """ def __get__(self, instance, owner_cls): """Get the attribute. This normally returns an instance of this class which is stored on the owner object. """ # For getting from class not an instance if instance is None: return self # If not already stored on `instance`, make a copy of the class # descriptor object and put it onto the instance. value = instance.__dict__.get(self.name) if value is None: value = deepcopy(self) instance.__dict__[self.name] = value # We set _instance_ref on every call, since if one makes copies of # instances, this attribute will be copied as well, which will lose the # reference. value._instance_ref = weakref.ref(instance) return value def __set__(self, instance, names): """Set value of ``instance`` attribute to ``names``. Parameters ---------- instance : object Instance that owns the attribute names : None, str, list, tuple Column name(s) to store, or None to clear """ if isinstance(names, str): names = [names] if names is None: # Remove attribute value from the meta['__attributes__'] dict. # Subsequent access will just return None. delattr(instance, self.name) else: # This stores names into instance.meta['__attributes__'] as tuple return super().__set__(instance, tuple(names)) def __call__(self): """Get the value of the attribute. Returns ------- names : None, tuple Include/exclude names """ # Get the value from instance.meta['__attributes__'] instance = self._instance_ref() return super().__get__(instance, instance.__class__) def __repr__(self): if hasattr(self, '_instance_ref'): out = f'<{self.__class__.__name__} name={self.name} value={self()}>' else: out = super().__repr__() return out def _add_remove_setup(self, names): """Common setup for add and remove. - Coerce attribute value to a list - Coerce names into a list - Get the parent table instance """ names = [names] if isinstance(names, str) else list(names) # Get the value. This is the same as self() but we need `instance` here. instance = self._instance_ref() value = super().__get__(instance, instance.__class__) value = [] if value is None else list(value) return instance, names, value def add(self, names): """Add ``names`` to the include/exclude attribute. Parameters ---------- names : str, list, tuple Column name(s) to add """ instance, names, value = self._add_remove_setup(names) value.extend(name for name in names if name not in value) super().__set__(instance, tuple(value)) def remove(self, names): """Remove ``names`` from the include/exclude attribute. Parameters ---------- names : str, list, tuple Column name(s) to remove """ self._remove(names, raise_exc=True) def _remove(self, names, raise_exc=False): """Remove ``names`` with optional checking if they exist""" instance, names, value = self._add_remove_setup(names) # Return now if there are no attributes and thus no action to be taken. if not raise_exc and '__attributes__' not in instance.meta: return # Remove one by one, optionally raising an exception if name is missing. for name in names: if name in value: value.remove(name) # Using the list.remove method elif raise_exc: raise ValueError(f'{name} not in {self.name}') # Change to either None or a tuple for storing back to attribute value = None if value == [] else tuple(value) self.__set__(instance, value) def _rename(self, name, new_name): """Rename ``name`` to ``new_name`` if ``name`` is in the list""" names = self() or () if name in names: new_names = list(names) new_names[new_names.index(name)] = new_name self.set(new_names) def set(self, names): """Set value of include/exclude attribute to ``names``. Parameters ---------- names : None, str, list, tuple Column name(s) to store, or None to clear """ class _Context: def __init__(self, descriptor_self): self.descriptor_self = descriptor_self self.names_orig = descriptor_self() def __enter__(self): pass def __exit__(self, type, value, tb): descriptor_self = self.descriptor_self instance = descriptor_self._instance_ref() descriptor_self.__set__(instance, self.names_orig) def __repr__(self): return repr(self.descriptor_self) ctx = _Context(descriptor_self=self) instance = self._instance_ref() self.__set__(instance, names) return ctx class Table: """A class to represent tables of heterogeneous data. `~astropy.table.Table` provides a class for heterogeneous tabular data. A key enhancement provided by the `~astropy.table.Table` class over e.g. a `numpy` structured array is the ability to easily modify the structure of the table by adding or removing columns, or adding new rows of data. In addition table and column metadata are fully supported. `~astropy.table.Table` differs from `~astropy.nddata.NDData` by the assumption that the input data consists of columns of homogeneous data, where each column has a unique identifier and may contain additional metadata such as the data unit, format, and description. See also: https://docs.astropy.org/en/stable/table/ Parameters ---------- data : numpy ndarray, dict, list, table-like object, optional Data to initialize table. masked : bool, optional Specify whether the table is masked. names : list, optional Specify column names. dtype : list, optional Specify column data types. meta : dict, optional Metadata associated with the table. copy : bool, optional Copy the input data. If the input is a Table the ``meta`` is always copied regardless of the ``copy`` parameter. Default is True. rows : numpy ndarray, list of list, optional Row-oriented data for table instead of ``data`` argument. copy_indices : bool, optional Copy any indices in the input data. Default is True. units : list, dict, optional List or dict of units to apply to columns. descriptions : list, dict, optional List or dict of descriptions to apply to columns. **kwargs : dict, optional Additional keyword args when converting table-like object. """ meta = MetaData(copy=False) # Define class attributes for core container objects to allow for subclass # customization. Row = Row Column = Column MaskedColumn = MaskedColumn TableColumns = TableColumns TableFormatter = TableFormatter # Unified I/O read and write methods from .connect read = UnifiedReadWriteMethod(TableRead) write = UnifiedReadWriteMethod(TableWrite) pprint_exclude_names = PprintIncludeExclude() pprint_include_names = PprintIncludeExclude() def as_array(self, keep_byteorder=False, names=None): """ Return a new copy of the table in the form of a structured np.ndarray or np.ma.MaskedArray object (as appropriate). Parameters ---------- keep_byteorder : bool, optional By default the returned array has all columns in native byte order. However, if this option is `True` this preserves the byte order of all columns (if any are non-native). names : list, optional: List of column names to include for returned structured array. Default is to include all table columns. Returns ------- table_array : array or `~numpy.ma.MaskedArray` Copy of table as a numpy structured array. ndarray for unmasked or `~numpy.ma.MaskedArray` for masked. """ masked = self.masked or self.has_masked_columns or self.has_masked_values empty_init = ma.empty if masked else np.empty if len(self.columns) == 0: return empty_init(0, dtype=None) dtype = [] cols = self.columns.values() if names is not None: cols = [col for col in cols if col.info.name in names] for col in cols: col_descr = descr(col) if not (col.info.dtype.isnative or keep_byteorder): new_dt = np.dtype(col_descr[1]).newbyteorder('=') col_descr = (col_descr[0], new_dt, col_descr[2]) dtype.append(col_descr) data = empty_init(len(self), dtype=dtype) for col in cols: # When assigning from one array into a field of a structured array, # Numpy will automatically swap those columns to their destination # byte order where applicable data[col.info.name] = col # For masked out, masked mixin columns need to set output mask attribute. if masked and has_info_class(col, MixinInfo) and hasattr(col, 'mask'): data[col.info.name].mask = col.mask return data def __init__(self, data=None, masked=False, names=None, dtype=None, meta=None, copy=True, rows=None, copy_indices=True, units=None, descriptions=None, **kwargs): # Set up a placeholder empty table self._set_masked(masked) self.columns = self.TableColumns() self.formatter = self.TableFormatter() self._copy_indices = True # copy indices from this Table by default self._init_indices = copy_indices # whether to copy indices in init self.primary_key = None # Must copy if dtype are changing if not copy and dtype is not None: raise ValueError('Cannot specify dtype when copy=False') # Specifies list of names found for the case of initializing table with # a list of dict. If data are not list of dict then this is None. names_from_list_of_dict = None # Row-oriented input, e.g. list of lists or list of tuples, list of # dict, Row instance. Set data to something that the subsequent code # will parse correctly. if rows is not None: if data is not None: raise ValueError('Cannot supply both `data` and `rows` values') if isinstance(rows, types.GeneratorType): # Without this then the all(..) test below uses up the generator rows = list(rows) # Get column names if `rows` is a list of dict, otherwise this is None names_from_list_of_dict = _get_names_from_list_of_dict(rows) if names_from_list_of_dict: data = rows elif isinstance(rows, self.Row): data = rows else: data = list(zip(*rows)) # Infer the type of the input data and set up the initialization # function, number of columns, and potentially the default col names default_names = None # Handle custom (subclass) table attributes that are stored in meta. # These are defined as class attributes using the TableAttribute # descriptor. Any such attributes get removed from kwargs here and # stored for use after the table is otherwise initialized. Any values # provided via kwargs will have precedence over existing values from # meta (e.g. from data as a Table or meta via kwargs). meta_table_attrs = {} if kwargs: for attr in list(kwargs): descr = getattr(self.__class__, attr, None) if isinstance(descr, TableAttribute): meta_table_attrs[attr] = kwargs.pop(attr) if hasattr(data, '__astropy_table__'): # Data object implements the __astropy_table__ interface method. # Calling that method returns an appropriate instance of # self.__class__ and respects the `copy` arg. The returned # Table object should NOT then be copied. data = data.__astropy_table__(self.__class__, copy, **kwargs) copy = False elif kwargs: raise TypeError('__init__() got unexpected keyword argument {!r}' .format(list(kwargs.keys())[0])) if (isinstance(data, np.ndarray) and data.shape == (0,) and not data.dtype.names): data = None if isinstance(data, self.Row): data = data._table[data._index:data._index + 1] if isinstance(data, (list, tuple)): # Get column names from `data` if it is a list of dict, otherwise this is None. # This might be previously defined if `rows` was supplied as an init arg. names_from_list_of_dict = (names_from_list_of_dict or _get_names_from_list_of_dict(data)) if names_from_list_of_dict: init_func = self._init_from_list_of_dicts n_cols = len(names_from_list_of_dict) else: init_func = self._init_from_list n_cols = len(data) elif isinstance(data, np.ndarray): if data.dtype.names: init_func = self._init_from_ndarray # _struct n_cols = len(data.dtype.names) default_names = data.dtype.names else: init_func = self._init_from_ndarray # _homog if data.shape == (): raise ValueError('Can not initialize a Table with a scalar') elif len(data.shape) == 1: data = data[np.newaxis, :] n_cols = data.shape[1] elif isinstance(data, Mapping): init_func = self._init_from_dict default_names = list(data) n_cols = len(default_names) elif isinstance(data, Table): # If user-input meta is None then use data.meta (if non-trivial) if meta is None and data.meta: # At this point do NOT deepcopy data.meta as this will happen after # table init_func() is called. But for table input the table meta # gets a key copy here if copy=False because later a direct object ref # is used. meta = data.meta if copy else data.meta.copy() # Handle indices on input table. Copy primary key and don't copy indices # if the input Table is in non-copy mode. self.primary_key = data.primary_key self._init_indices = self._init_indices and data._copy_indices # Extract default names, n_cols, and then overwrite ``data`` to be the # table columns so we can use _init_from_list. default_names = data.colnames n_cols = len(default_names) data = list(data.columns.values()) init_func = self._init_from_list elif data is None: if names is None: if dtype is None: # Table was initialized as `t = Table()`. Set up for empty # table with names=[], data=[], and n_cols=0. # self._init_from_list() will simply return, giving the # expected empty table. names = [] else: try: # No data nor names but dtype is available. This must be # valid to initialize a structured array. dtype = np.dtype(dtype) names = dtype.names dtype = [dtype[name] for name in names] except Exception: raise ValueError('dtype was specified but could not be ' 'parsed for column names') # names is guaranteed to be set at this point init_func = self._init_from_list n_cols = len(names) data = [[]] * n_cols else: raise ValueError(f'Data type {type(data)} not allowed to init Table') # Set up defaults if names and/or dtype are not specified. # A value of None means the actual value will be inferred # within the appropriate initialization routine, either from # existing specification or auto-generated. if dtype is None: dtype = [None] * n_cols elif isinstance(dtype, np.dtype): if default_names is None: default_names = dtype.names # Convert a numpy dtype input to a list of dtypes for later use. dtype = [dtype[name] for name in dtype.names] if names is None: names = default_names or [None] * n_cols # Numpy does not support bytes column names on Python 3, so fix them # up now. names = [fix_column_name(name) for name in names] self._check_names_dtype(names, dtype, n_cols) # Finally do the real initialization init_func(data, names, dtype, n_cols, copy) # Set table meta. If copy=True then deepcopy meta otherwise use the # user-supplied meta directly. if meta is not None: self.meta = deepcopy(meta) if copy else meta # Update meta with TableAttributes supplied as kwargs in Table init. # This takes precedence over previously-defined meta. if meta_table_attrs: for attr, value in meta_table_attrs.items(): setattr(self, attr, value) # Whatever happens above, the masked property should be set to a boolean if self.masked not in (None, True, False): raise TypeError("masked property must be None, True or False") self._set_column_attribute('unit', units) self._set_column_attribute('description', descriptions) def _set_column_attribute(self, attr, values): """Set ``attr`` for columns to ``values``, which can be either a dict (keyed by column name) or a dict of name: value pairs. This is used for handling the ``units`` and ``descriptions`` kwargs to ``__init__``. """ if not values: return if isinstance(values, Row): # For a Row object transform to an equivalent dict. values = {name: values[name] for name in values.colnames} if not isinstance(values, Mapping): # If not a dict map, assume iterable and map to dict if the right length if len(values) != len(self.columns): raise ValueError(f'sequence of {attr} values must match number of columns') values = dict(zip(self.colnames, values)) for name, value in values.items(): if name not in self.columns: raise ValueError(f'invalid column name {name} for setting {attr} attribute') # Special case: ignore unit if it is an empty or blank string if attr == 'unit' and isinstance(value, str): if value.strip() == '': value = None if value not in (np.ma.masked, None): setattr(self[name].info, attr, value) def __getstate__(self): columns = OrderedDict((key, col if isinstance(col, BaseColumn) else col_copy(col)) for key, col in self.columns.items()) return (columns, self.meta) def __setstate__(self, state): columns, meta = state self.__init__(columns, meta=meta) @property def mask(self): # Dynamic view of available masks if self.masked or self.has_masked_columns or self.has_masked_values: mask_table = Table([getattr(col, 'mask', FalseArray(col.shape)) for col in self.itercols()], names=self.colnames, copy=False) # Set hidden attribute to force inplace setitem so that code like # t.mask['a'] = [1, 0, 1] will correctly set the underlying mask. # See #5556 for discussion. mask_table._setitem_inplace = True else: mask_table = None return mask_table @mask.setter def mask(self, val): self.mask[:] = val @property def _mask(self): """This is needed so that comparison of a masked Table and a MaskedArray works. The requirement comes from numpy.ma.core so don't remove this property.""" return self.as_array().mask def filled(self, fill_value=None): """Return copy of self, with masked values filled. If input ``fill_value`` supplied then that value is used for all masked entries in the table. Otherwise the individual ``fill_value`` defined for each table column is used. Parameters ---------- fill_value : str If supplied, this ``fill_value`` is used for all masked entries in the entire table. Returns ------- filled_table : `~astropy.table.Table` New table with masked values filled """ if self.masked or self.has_masked_columns or self.has_masked_values: # Get new columns with masked values filled, then create Table with those # new cols (copy=False) but deepcopy the meta. data = [col.filled(fill_value) if hasattr(col, 'filled') else col for col in self.itercols()] return self.__class__(data, meta=deepcopy(self.meta), copy=False) else: # Return copy of the original object. return self.copy() @property def indices(self): ''' Return the indices associated with columns of the table as a TableIndices object. ''' lst = [] for column in self.columns.values(): for index in column.info.indices: if sum([index is x for x in lst]) == 0: # ensure uniqueness lst.append(index) return TableIndices(lst) @property def loc(self): ''' Return a TableLoc object that can be used for retrieving rows by index in a given data range. Note that both loc and iloc work only with single-column indices. ''' return TableLoc(self) @property def loc_indices(self): """ Return a TableLocIndices object that can be used for retrieving the row indices corresponding to given table index key value or values. """ return TableLocIndices(self) @property def iloc(self): ''' Return a TableILoc object that can be used for retrieving indexed rows in the order they appear in the index. ''' return TableILoc(self) def add_index(self, colnames, engine=None, unique=False): ''' Insert a new index among one or more columns. If there are no indices, make this index the primary table index. Parameters ---------- colnames : str or list List of column names (or a single column name) to index engine : type or None Indexing engine class to use, from among SortedArray, BST, and SCEngine. If the supplied argument is None (by default), use SortedArray. unique : bool Whether the values of the index must be unique. Default is False. ''' if isinstance(colnames, str): colnames = (colnames,) columns = self.columns[tuple(colnames)].values() # make sure all columns support indexing for col in columns: if not getattr(col.info, '_supports_indexing', False): raise ValueError('Cannot create an index on column "{}", of ' 'type "{}"'.format(col.info.name, type(col))) is_primary = not self.indices index = Index(columns, engine=engine, unique=unique) sliced_index = SlicedIndex(index, slice(0, 0, None), original=True) if is_primary: self.primary_key = colnames for col in columns: col.info.indices.append(sliced_index) def remove_indices(self, colname): ''' Remove all indices involving the given column. If the primary index is removed, the new primary index will be the most recently added remaining index. Parameters ---------- colname : str Name of column ''' col = self.columns[colname] for index in self.indices: try: index.col_position(col.info.name) except ValueError: pass else: for c in index.columns: c.info.indices.remove(index) def index_mode(self, mode): ''' Return a context manager for an indexing mode. Parameters ---------- mode : str Either 'freeze', 'copy_on_getitem', or 'discard_on_copy'. In 'discard_on_copy' mode, indices are not copied whenever columns or tables are copied. In 'freeze' mode, indices are not modified whenever columns are modified; at the exit of the context, indices refresh themselves based on column values. This mode is intended for scenarios in which one intends to make many additions or modifications in an indexed column. In 'copy_on_getitem' mode, indices are copied when taking column slices as well as table slices, so col[i0:i1] will preserve indices. ''' return _IndexModeContext(self, mode) def __array__(self, dtype=None): """Support converting Table to np.array via np.array(table). Coercion to a different dtype via np.array(table, dtype) is not supported and will raise a ValueError. """ if dtype is not None: raise ValueError('Datatype coercion is not allowed') # This limitation is because of the following unexpected result that # should have made a table copy while changing the column names. # # >>> d = astropy.table.Table([[1,2],[3,4]]) # >>> np.array(d, dtype=[('a', 'i8'), ('b', 'i8')]) # array([(0, 0), (0, 0)], # dtype=[('a', ' 1): data = data.view(NdarrayMixin) data_is_mixin = True # Get the final column name using precedence. Some objects may not # have an info attribute. Also avoid creating info as a side effect. if not name: if isinstance(data, Column): name = data.name or default_name elif 'info' in getattr(data, '__dict__', ()): name = data.info.name or default_name else: name = default_name if isinstance(data, Column): # If self.ColumnClass is a subclass of col, then "upgrade" to ColumnClass, # otherwise just use the original class. The most common case is a # table with masked=True and ColumnClass=MaskedColumn. Then a Column # gets upgraded to MaskedColumn, but the converse (pre-4.0) behavior # of downgrading from MaskedColumn to Column (for non-masked table) # does not happen. col_cls = self._get_col_cls_for_table(data) elif data_is_mixin: # Copy the mixin column attributes if they exist since the copy below # may not get this attribute. col = col_copy(data, copy_indices=self._init_indices) if copy else data col.info.name = name return col elif data0_is_mixin: # Handle case of a sequence of a mixin, e.g. [1*u.m, 2*u.m]. try: col = data[0].__class__(data) col.info.name = name return col except Exception: # If that didn't work for some reason, just turn it into np.array of object data = np.array(data, dtype=object) col_cls = self.ColumnClass elif isinstance(data, (np.ma.MaskedArray, Masked)): # Require that col_cls be a subclass of MaskedColumn, remembering # that ColumnClass could be a user-defined subclass (though more-likely # could be MaskedColumn). col_cls = masked_col_cls elif data is None: # Special case for data passed as the None object (for broadcasting # to an object column). Need to turn data into numpy `None` scalar # object, otherwise `Column` interprets data=None as no data instead # of a object column of `None`. data = np.array(None) col_cls = self.ColumnClass elif not hasattr(data, 'dtype'): # `data` is none of the above, convert to numpy array or MaskedArray # assuming only that it is a scalar or sequence or N-d nested # sequence. This function is relatively intricate and tries to # maintain performance for common cases while handling things like # list input with embedded np.ma.masked entries. If `data` is a # scalar then it gets returned unchanged so the original object gets # passed to `Column` later. data = _convert_sequence_data_to_array(data, dtype) copy = False # Already made a copy above col_cls = masked_col_cls if isinstance(data, np.ma.MaskedArray) else self.ColumnClass else: col_cls = self.ColumnClass try: col = col_cls(name=name, data=data, dtype=dtype, copy=copy, copy_indices=self._init_indices) except Exception: # Broad exception class since we don't know what might go wrong raise ValueError('unable to convert data to Column for Table') col = self._convert_col_for_table(col) return col def _init_from_ndarray(self, data, names, dtype, n_cols, copy): """Initialize table from an ndarray structured array""" data_names = data.dtype.names or _auto_names(n_cols) struct = data.dtype.names is not None names = [name or data_names[i] for i, name in enumerate(names)] cols = ([data[name] for name in data_names] if struct else [data[:, i] for i in range(n_cols)]) self._init_from_list(cols, names, dtype, n_cols, copy) def _init_from_dict(self, data, names, dtype, n_cols, copy): """Initialize table from a dictionary of columns""" data_list = [data[name] for name in names] self._init_from_list(data_list, names, dtype, n_cols, copy) def _get_col_cls_for_table(self, col): """Get the correct column class to use for upgrading any Column-like object. For a masked table, ensure any Column-like object is a subclass of the table MaskedColumn. For unmasked table, ensure any MaskedColumn-like object is a subclass of the table MaskedColumn. If not a MaskedColumn, then ensure that any Column-like object is a subclass of the table Column. """ col_cls = col.__class__ if self.masked: if isinstance(col, Column) and not isinstance(col, self.MaskedColumn): col_cls = self.MaskedColumn else: if isinstance(col, MaskedColumn): if not isinstance(col, self.MaskedColumn): col_cls = self.MaskedColumn elif isinstance(col, Column) and not isinstance(col, self.Column): col_cls = self.Column return col_cls def _convert_col_for_table(self, col): """ Make sure that all Column objects have correct base class for this type of Table. For a base Table this most commonly means setting to MaskedColumn if the table is masked. Table subclasses like QTable override this method. """ if isinstance(col, Column) and not isinstance(col, self.ColumnClass): col_cls = self._get_col_cls_for_table(col) if col_cls is not col.__class__: col = col_cls(col, copy=False) return col def _init_from_cols(self, cols): """Initialize table from a list of Column or mixin objects""" lengths = set(len(col) for col in cols) if len(lengths) > 1: raise ValueError(f'Inconsistent data column lengths: {lengths}') # Make sure that all Column-based objects have correct class. For # plain Table this is self.ColumnClass, but for instance QTable will # convert columns with units to a Quantity mixin. newcols = [self._convert_col_for_table(col) for col in cols] self._make_table_from_cols(self, newcols) # Deduplicate indices. It may happen that after pickling or when # initing from an existing table that column indices which had been # references to a single index object got *copied* into an independent # object. This results in duplicates which will cause downstream problems. index_dict = {} for col in self.itercols(): for i, index in enumerate(col.info.indices or []): names = tuple(ind_col.info.name for ind_col in index.columns) if names in index_dict: col.info.indices[i] = index_dict[names] else: index_dict[names] = index def _new_from_slice(self, slice_): """Create a new table as a referenced slice from self.""" table = self.__class__(masked=self.masked) if self.meta: table.meta = self.meta.copy() # Shallow copy for slice table.primary_key = self.primary_key newcols = [] for col in self.columns.values(): newcol = col[slice_] # Note in line below, use direct attribute access to col.indices for Column # instances instead of the generic col.info.indices. This saves about 4 usec # per column. if (col if isinstance(col, Column) else col.info).indices: # TODO : as far as I can tell the only purpose of setting _copy_indices # here is to communicate that to the initial test in `slice_indices`. # Why isn't that just sent as an arg to the function? col.info._copy_indices = self._copy_indices newcol = col.info.slice_indices(newcol, slice_, len(col)) # Don't understand why this is forcing a value on the original column. # Normally col.info does not even have a _copy_indices attribute. Tests # still pass if this line is deleted. (Each col.info attribute access # is expensive). col.info._copy_indices = True newcols.append(newcol) self._make_table_from_cols(table, newcols, verify=False, names=self.columns.keys()) return table @staticmethod def _make_table_from_cols(table, cols, verify=True, names=None): """ Make ``table`` in-place so that it represents the given list of ``cols``. """ if names is None: names = [col.info.name for col in cols] # Note: we do not test for len(names) == len(cols) if names is not None. In that # case the function is being called by from "trusted" source (e.g. right above here) # that is assumed to provide valid inputs. In that case verify=False. if verify: if None in names: raise TypeError('Cannot have None for column name') if len(set(names)) != len(names): raise ValueError('Duplicate column names') table.columns = table.TableColumns((name, col) for name, col in zip(names, cols)) for col in cols: table._set_col_parent_table_and_mask(col) def _set_col_parent_table_and_mask(self, col): """ Set ``col.parent_table = self`` and force ``col`` to have ``mask`` attribute if the table is masked and ``col.mask`` does not exist. """ # For Column instances it is much faster to do direct attribute access # instead of going through .info col_info = col if isinstance(col, Column) else col.info col_info.parent_table = self # Legacy behavior for masked table if self.masked and not hasattr(col, 'mask'): col.mask = FalseArray(col.shape) def itercols(self): """ Iterate over the columns of this table. Examples -------- To iterate over the columns of a table:: >>> t = Table([[1], [2]]) >>> for col in t.itercols(): ... print(col) col0 ---- 1 col1 ---- 2 Using ``itercols()`` is similar to ``for col in t.columns.values()`` but is syntactically preferred. """ for colname in self.columns: yield self[colname] def _base_repr_(self, html=False, descr_vals=None, max_width=None, tableid=None, show_dtype=True, max_lines=None, tableclass=None): if descr_vals is None: descr_vals = [self.__class__.__name__] if self.masked: descr_vals.append('masked=True') descr_vals.append(f'length={len(self)}') descr = ' '.join(descr_vals) if html: from astropy.utils.xml.writer import xml_escape descr = f'{xml_escape(descr)}\n' else: descr = f'<{descr}>\n' if tableid is None: tableid = f'table{id(self)}' data_lines, outs = self.formatter._pformat_table( self, tableid=tableid, html=html, max_width=max_width, show_name=True, show_unit=None, show_dtype=show_dtype, max_lines=max_lines, tableclass=tableclass) out = descr + '\n'.join(data_lines) return out def _repr_html_(self): out = self._base_repr_(html=True, max_width=-1, tableclass=conf.default_notebook_table_class) # Wrap
in
. This follows the pattern in pandas and allows # table to be scrollable horizontally in VS Code notebook display. out = f'
{out}
' return out def __repr__(self): return self._base_repr_(html=False, max_width=None) def __str__(self): return '\n'.join(self.pformat()) def __bytes__(self): return str(self).encode('utf-8') @property def has_mixin_columns(self): """ True if table has any mixin columns (defined as columns that are not Column subclasses). """ return any(has_info_class(col, MixinInfo) for col in self.columns.values()) @property def has_masked_columns(self): """True if table has any ``MaskedColumn`` columns. This does not check for mixin columns that may have masked values, use the ``has_masked_values`` property in that case. """ return any(isinstance(col, MaskedColumn) for col in self.itercols()) @property def has_masked_values(self): """True if column in the table has values which are masked. This may be relatively slow for large tables as it requires checking the mask values of each column. """ for col in self.itercols(): if hasattr(col, 'mask') and np.any(col.mask): return True else: return False def _is_mixin_for_table(self, col): """ Determine if ``col`` should be added to the table directly as a mixin column. """ if isinstance(col, BaseColumn): return False # Is it a mixin but not [Masked]Quantity (which gets converted to # [Masked]Column with unit set). return has_info_class(col, MixinInfo) and not has_info_class(col, QuantityInfo) @format_doc(_pprint_docs) def pprint(self, max_lines=None, max_width=None, show_name=True, show_unit=None, show_dtype=False, align=None): """Print a formatted string representation of the table. If no value of ``max_lines`` is supplied then the height of the screen terminal is used to set ``max_lines``. If the terminal height cannot be determined then the default is taken from the configuration item ``astropy.conf.max_lines``. If a negative value of ``max_lines`` is supplied then there is no line limit applied. The same applies for max_width except the configuration item is ``astropy.conf.max_width``. """ lines, outs = self.formatter._pformat_table(self, max_lines, max_width, show_name=show_name, show_unit=show_unit, show_dtype=show_dtype, align=align) if outs['show_length']: lines.append(f'Length = {len(self)} rows') n_header = outs['n_header'] for i, line in enumerate(lines): if i < n_header: color_print(line, 'red') else: print(line) @format_doc(_pprint_docs) def pprint_all(self, max_lines=-1, max_width=-1, show_name=True, show_unit=None, show_dtype=False, align=None): """Print a formatted string representation of the entire table. This method is the same as `astropy.table.Table.pprint` except that the default ``max_lines`` and ``max_width`` are both -1 so that by default the entire table is printed instead of restricting to the size of the screen terminal. """ return self.pprint(max_lines, max_width, show_name, show_unit, show_dtype, align) def _make_index_row_display_table(self, index_row_name): if index_row_name not in self.columns: idx_col = self.ColumnClass(name=index_row_name, data=np.arange(len(self))) return self.__class__([idx_col] + list(self.columns.values()), copy=False) else: return self def show_in_notebook(self, tableid=None, css=None, display_length=50, table_class='astropy-default', show_row_index='idx'): """Render the table in HTML and show it in the IPython notebook. Parameters ---------- tableid : str or None An html ID tag for the table. Default is ``table{id}-XXX``, where id is the unique integer id of the table object, id(self), and XXX is a random number to avoid conflicts when printing the same table multiple times. table_class : str or None A string with a list of HTML classes used to style the table. The special default string ('astropy-default') means that the string will be retrieved from the configuration item ``astropy.table.default_notebook_table_class``. Note that these table classes may make use of bootstrap, as this is loaded with the notebook. See `this page `_ for the list of classes. css : str A valid CSS string declaring the formatting for the table. Defaults to ``astropy.table.jsviewer.DEFAULT_CSS_NB``. display_length : int, optional Number or rows to show. Defaults to 50. show_row_index : str or False If this does not evaluate to False, a column with the given name will be added to the version of the table that gets displayed. This new column shows the index of the row in the table itself, even when the displayed table is re-sorted by another column. Note that if a column with this name already exists, this option will be ignored. Defaults to "idx". Notes ----- Currently, unlike `show_in_browser` (with ``jsviewer=True``), this method needs to access online javascript code repositories. This is due to modern browsers' limitations on accessing local files. Hence, if you call this method while offline (and don't have a cached version of jquery and jquery.dataTables), you will not get the jsviewer features. """ from .jsviewer import JSViewer from IPython.display import HTML if tableid is None: tableid = f'table{id(self)}-{np.random.randint(1, 1e6)}' jsv = JSViewer(display_length=display_length) if show_row_index: display_table = self._make_index_row_display_table(show_row_index) else: display_table = self if table_class == 'astropy-default': table_class = conf.default_notebook_table_class html = display_table._base_repr_(html=True, max_width=-1, tableid=tableid, max_lines=-1, show_dtype=False, tableclass=table_class) columns = display_table.columns.values() sortable_columns = [i for i, col in enumerate(columns) if col.info.dtype.kind in 'iufc'] html += jsv.ipynb(tableid, css=css, sort_columns=sortable_columns) return HTML(html) def show_in_browser(self, max_lines=5000, jsviewer=False, browser='default', jskwargs={'use_local_files': True}, tableid=None, table_class="display compact", css=None, show_row_index='idx'): """Render the table in HTML and show it in a web browser. Parameters ---------- max_lines : int Maximum number of rows to export to the table (set low by default to avoid memory issues, since the browser view requires duplicating the table in memory). A negative value of ``max_lines`` indicates no row limit. jsviewer : bool If `True`, prepends some javascript headers so that the table is rendered as a `DataTables `_ data table. This allows in-browser searching & sorting. browser : str Any legal browser name, e.g. ``'firefox'``, ``'chrome'``, ``'safari'`` (for mac, you may need to use ``'open -a "/Applications/Google Chrome.app" {}'`` for Chrome). If ``'default'``, will use the system default browser. jskwargs : dict Passed to the `astropy.table.JSViewer` init. Defaults to ``{'use_local_files': True}`` which means that the JavaScript libraries will be served from local copies. tableid : str or None An html ID tag for the table. Default is ``table{id}``, where id is the unique integer id of the table object, id(self). table_class : str or None A string with a list of HTML classes used to style the table. Default is "display compact", and other possible values can be found in https://www.datatables.net/manual/styling/classes css : str A valid CSS string declaring the formatting for the table. Defaults to ``astropy.table.jsviewer.DEFAULT_CSS``. show_row_index : str or False If this does not evaluate to False, a column with the given name will be added to the version of the table that gets displayed. This new column shows the index of the row in the table itself, even when the displayed table is re-sorted by another column. Note that if a column with this name already exists, this option will be ignored. Defaults to "idx". """ import os import webbrowser import tempfile from .jsviewer import DEFAULT_CSS from urllib.parse import urljoin from urllib.request import pathname2url if css is None: css = DEFAULT_CSS # We can't use NamedTemporaryFile here because it gets deleted as # soon as it gets garbage collected. tmpdir = tempfile.mkdtemp() path = os.path.join(tmpdir, 'table.html') with open(path, 'w') as tmp: if jsviewer: if show_row_index: display_table = self._make_index_row_display_table(show_row_index) else: display_table = self display_table.write(tmp, format='jsviewer', css=css, max_lines=max_lines, jskwargs=jskwargs, table_id=tableid, table_class=table_class) else: self.write(tmp, format='html') try: br = webbrowser.get(None if browser == 'default' else browser) except webbrowser.Error: log.error(f"Browser '{browser}' not found.") else: br.open(urljoin('file:', pathname2url(path))) @format_doc(_pformat_docs, id="{id}") def pformat(self, max_lines=None, max_width=None, show_name=True, show_unit=None, show_dtype=False, html=False, tableid=None, align=None, tableclass=None): """Return a list of lines for the formatted string representation of the table. If no value of ``max_lines`` is supplied then the height of the screen terminal is used to set ``max_lines``. If the terminal height cannot be determined then the default is taken from the configuration item ``astropy.conf.max_lines``. If a negative value of ``max_lines`` is supplied then there is no line limit applied. The same applies for ``max_width`` except the configuration item is ``astropy.conf.max_width``. """ lines, outs = self.formatter._pformat_table( self, max_lines, max_width, show_name=show_name, show_unit=show_unit, show_dtype=show_dtype, html=html, tableid=tableid, tableclass=tableclass, align=align) if outs['show_length']: lines.append(f'Length = {len(self)} rows') return lines @format_doc(_pformat_docs, id="{id}") def pformat_all(self, max_lines=-1, max_width=-1, show_name=True, show_unit=None, show_dtype=False, html=False, tableid=None, align=None, tableclass=None): """Return a list of lines for the formatted string representation of the entire table. If no value of ``max_lines`` is supplied then the height of the screen terminal is used to set ``max_lines``. If the terminal height cannot be determined then the default is taken from the configuration item ``astropy.conf.max_lines``. If a negative value of ``max_lines`` is supplied then there is no line limit applied. The same applies for ``max_width`` except the configuration item is ``astropy.conf.max_width``. """ return self.pformat(max_lines, max_width, show_name, show_unit, show_dtype, html, tableid, align, tableclass) def more(self, max_lines=None, max_width=None, show_name=True, show_unit=None, show_dtype=False): """Interactively browse table with a paging interface. Supported keys:: f, : forward one page b : back one page r : refresh same page n : next row p : previous row < : go to beginning > : go to end q : quit browsing h : print this help Parameters ---------- max_lines : int Maximum number of lines in table output max_width : int or None Maximum character width of output show_name : bool Include a header row for column names. Default is True. show_unit : bool Include a header row for unit. Default is to show a row for units only if one or more columns has a defined value for the unit. show_dtype : bool Include a header row for column dtypes. Default is True. """ self.formatter._more_tabcol(self, max_lines, max_width, show_name=show_name, show_unit=show_unit, show_dtype=show_dtype) def __getitem__(self, item): if isinstance(item, str): return self.columns[item] elif isinstance(item, (int, np.integer)): return self.Row(self, item) elif (isinstance(item, np.ndarray) and item.shape == () and item.dtype.kind == 'i'): return self.Row(self, item.item()) elif self._is_list_or_tuple_of_str(item): out = self.__class__([self[x] for x in item], copy_indices=self._copy_indices) out._groups = groups.TableGroups(out, indices=self.groups._indices, keys=self.groups._keys) out.meta = self.meta.copy() # Shallow copy for meta return out elif ((isinstance(item, np.ndarray) and item.size == 0) or (isinstance(item, (tuple, list)) and not item)): # If item is an empty array/list/tuple then return the table with no rows return self._new_from_slice([]) elif (isinstance(item, slice) or isinstance(item, np.ndarray) or isinstance(item, list) or isinstance(item, tuple) and all(isinstance(x, np.ndarray) for x in item)): # here for the many ways to give a slice; a tuple of ndarray # is produced by np.where, as in t[np.where(t['a'] > 2)] # For all, a new table is constructed with slice of all columns return self._new_from_slice(item) else: raise ValueError(f'Illegal type {type(item)} for table item access') def __setitem__(self, item, value): # If the item is a string then it must be the name of a column. # If that column doesn't already exist then create it now. if isinstance(item, str) and item not in self.colnames: self.add_column(value, name=item, copy=True) else: n_cols = len(self.columns) if isinstance(item, str): # Set an existing column by first trying to replace, and if # this fails do an in-place update. See definition of mask # property for discussion of the _setitem_inplace attribute. if (not getattr(self, '_setitem_inplace', False) and not conf.replace_inplace): try: self._replace_column_warnings(item, value) return except Exception: pass self.columns[item][:] = value elif isinstance(item, (int, np.integer)): self._set_row(idx=item, colnames=self.colnames, vals=value) elif (isinstance(item, slice) or isinstance(item, np.ndarray) or isinstance(item, list) or (isinstance(item, tuple) # output from np.where and all(isinstance(x, np.ndarray) for x in item))): if isinstance(value, Table): vals = (col for col in value.columns.values()) elif isinstance(value, np.ndarray) and value.dtype.names: vals = (value[name] for name in value.dtype.names) elif np.isscalar(value): vals = itertools.repeat(value, n_cols) else: # Assume this is an iterable that will work if len(value) != n_cols: raise ValueError('Right side value needs {} elements (one for each column)' .format(n_cols)) vals = value for col, val in zip(self.columns.values(), vals): col[item] = val else: raise ValueError(f'Illegal type {type(item)} for table item access') def __delitem__(self, item): if isinstance(item, str): self.remove_column(item) elif isinstance(item, (int, np.integer)): self.remove_row(item) elif (isinstance(item, (list, tuple, np.ndarray)) and all(isinstance(x, str) for x in item)): self.remove_columns(item) elif (isinstance(item, (list, np.ndarray)) and np.asarray(item).dtype.kind == 'i'): self.remove_rows(item) elif isinstance(item, slice): self.remove_rows(item) else: raise IndexError('illegal key or index value') def _ipython_key_completions_(self): return self.colnames def field(self, item): """Return column[item] for recarray compatibility.""" return self.columns[item] @property def masked(self): return self._masked @masked.setter def masked(self, masked): raise Exception('Masked attribute is read-only (use t = Table(t, masked=True)' ' to convert to a masked table)') def _set_masked(self, masked): """ Set the table masked property. Parameters ---------- masked : bool State of table masking (`True` or `False`) """ if masked in [True, False, None]: self._masked = masked else: raise ValueError("masked should be one of True, False, None") self._column_class = self.MaskedColumn if self._masked else self.Column @property def ColumnClass(self): if self._column_class is None: return self.Column else: return self._column_class @property def dtype(self): return np.dtype([descr(col) for col in self.columns.values()]) @property def colnames(self): return list(self.columns.keys()) @staticmethod def _is_list_or_tuple_of_str(names): """Check that ``names`` is a tuple or list of strings""" return (isinstance(names, (tuple, list)) and names and all(isinstance(x, str) for x in names)) def keys(self): return list(self.columns.keys()) def values(self): return self.columns.values() def items(self): return self.columns.items() def __len__(self): # For performance reasons (esp. in Row) cache the first column name # and use that subsequently for the table length. If might not be # available yet or the column might be gone now, in which case # try again in the except block. try: return len(OrderedDict.__getitem__(self.columns, self._first_colname)) except (AttributeError, KeyError): if len(self.columns) == 0: return 0 # Get the first column name self._first_colname = next(iter(self.columns)) return len(self.columns[self._first_colname]) def index_column(self, name): """ Return the positional index of column ``name``. Parameters ---------- name : str column name Returns ------- index : int Positional index of column ``name``. Examples -------- Create a table with three columns 'a', 'b' and 'c':: >>> t = Table([[1, 2, 3], [0.1, 0.2, 0.3], ['x', 'y', 'z']], ... names=('a', 'b', 'c')) >>> print(t) a b c --- --- --- 1 0.1 x 2 0.2 y 3 0.3 z Get index of column 'b' of the table:: >>> t.index_column('b') 1 """ try: return self.colnames.index(name) except ValueError: raise ValueError(f"Column {name} does not exist") def add_column(self, col, index=None, name=None, rename_duplicate=False, copy=True, default_name=None): """ Add a new column to the table using ``col`` as input. If ``index`` is supplied then insert column before ``index`` position in the list of columns, otherwise append column to the end of the list. The ``col`` input can be any data object which is acceptable as a `~astropy.table.Table` column object or can be converted. This includes mixin columns and scalar or length=1 objects which get broadcast to match the table length. To add several columns at once use ``add_columns()`` or simply call ``add_column()`` for each one. There is very little performance difference in the two approaches. Parameters ---------- col : object Data object for the new column index : int or None Insert column before this position or at end (default). name : str Column name rename_duplicate : bool Uniquify column name if it already exist. Default is False. copy : bool Make a copy of the new column. Default is True. default_name : str or None Name to use if both ``name`` and ``col.info.name`` are not available. Defaults to ``col{number_of_columns}``. Examples -------- Create a table with two columns 'a' and 'b', then create a third column 'c' and append it to the end of the table:: >>> t = Table([[1, 2], [0.1, 0.2]], names=('a', 'b')) >>> col_c = Column(name='c', data=['x', 'y']) >>> t.add_column(col_c) >>> print(t) a b c --- --- --- 1 0.1 x 2 0.2 y Add column 'd' at position 1. Note that the column is inserted before the given index:: >>> t.add_column(['a', 'b'], name='d', index=1) >>> print(t) a d b c --- --- --- --- 1 a 0.1 x 2 b 0.2 y Add second column named 'b' with rename_duplicate:: >>> t = Table([[1, 2], [0.1, 0.2]], names=('a', 'b')) >>> t.add_column(1.1, name='b', rename_duplicate=True) >>> print(t) a b b_1 --- --- --- 1 0.1 1.1 2 0.2 1.1 Add an unnamed column or mixin object in the table using a default name or by specifying an explicit name with ``name``. Name can also be overridden:: >>> t = Table([[1, 2], [0.1, 0.2]], names=('a', 'b')) >>> t.add_column(['a', 'b']) >>> t.add_column(col_c, name='d') >>> print(t) a b col2 d --- --- ---- --- 1 0.1 a x 2 0.2 b y """ if default_name is None: default_name = f'col{len(self.columns)}' # Convert col data to acceptable object for insertion into self.columns. # Note that along with the lines above and below, this allows broadcasting # of scalars to the correct shape for adding to table. col = self._convert_data_to_col(col, name=name, copy=copy, default_name=default_name) # Assigning a scalar column to an empty table should result in an # exception (see #3811). if col.shape == () and len(self) == 0: raise TypeError('Empty table cannot have column set to scalar value') # Make col data shape correct for scalars. The second test is to allow # broadcasting an N-d element to a column, e.g. t['new'] = [[1, 2]]. elif (col.shape == () or col.shape[0] == 1) and len(self) > 0: new_shape = (len(self),) + getattr(col, 'shape', ())[1:] if isinstance(col, np.ndarray): col = np.broadcast_to(col, shape=new_shape, subok=True) elif isinstance(col, ShapedLikeNDArray): col = col._apply(np.broadcast_to, shape=new_shape, subok=True) # broadcast_to() results in a read-only array. Apparently it only changes # the view to look like the broadcasted array. So copy. col = col_copy(col) name = col.info.name # Ensure that new column is the right length if len(self.columns) > 0 and len(col) != len(self): raise ValueError('Inconsistent data column lengths') if rename_duplicate: orig_name = name i = 1 while name in self.columns: # Iterate until a unique name is found name = orig_name + '_' + str(i) i += 1 col.info.name = name # Set col parent_table weakref and ensure col has mask attribute if table.masked self._set_col_parent_table_and_mask(col) # Add new column as last column self.columns[name] = col if index is not None: # Move the other cols to the right of the new one move_names = self.colnames[index:-1] for move_name in move_names: self.columns.move_to_end(move_name, last=True) def add_columns(self, cols, indexes=None, names=None, copy=True, rename_duplicate=False): """ Add a list of new columns the table using ``cols`` data objects. If a corresponding list of ``indexes`` is supplied then insert column before each ``index`` position in the *original* list of columns, otherwise append columns to the end of the list. The ``cols`` input can include any data objects which are acceptable as `~astropy.table.Table` column objects or can be converted. This includes mixin columns and scalar or length=1 objects which get broadcast to match the table length. From a performance perspective there is little difference between calling this method once or looping over the new columns and calling ``add_column()`` for each column. Parameters ---------- cols : list of object List of data objects for the new columns indexes : list of int or None Insert column before this position or at end (default). names : list of str Column names copy : bool Make a copy of the new columns. Default is True. rename_duplicate : bool Uniquify new column names if they duplicate the existing ones. Default is False. See Also -------- astropy.table.hstack, update, replace_column Examples -------- Create a table with two columns 'a' and 'b', then create columns 'c' and 'd' and append them to the end of the table:: >>> t = Table([[1, 2], [0.1, 0.2]], names=('a', 'b')) >>> col_c = Column(name='c', data=['x', 'y']) >>> col_d = Column(name='d', data=['u', 'v']) >>> t.add_columns([col_c, col_d]) >>> print(t) a b c d --- --- --- --- 1 0.1 x u 2 0.2 y v Add column 'c' at position 0 and column 'd' at position 1. Note that the columns are inserted before the given position:: >>> t = Table([[1, 2], [0.1, 0.2]], names=('a', 'b')) >>> t.add_columns([['x', 'y'], ['u', 'v']], names=['c', 'd'], ... indexes=[0, 1]) >>> print(t) c a d b --- --- --- --- x 1 u 0.1 y 2 v 0.2 Add second column 'b' and column 'c' with ``rename_duplicate``:: >>> t = Table([[1, 2], [0.1, 0.2]], names=('a', 'b')) >>> t.add_columns([[1.1, 1.2], ['x', 'y']], names=('b', 'c'), ... rename_duplicate=True) >>> print(t) a b b_1 c --- --- --- --- 1 0.1 1.1 x 2 0.2 1.2 y Add unnamed columns or mixin objects in the table using default names or by specifying explicit names with ``names``. Names can also be overridden:: >>> t = Table() >>> col_b = Column(name='b', data=['u', 'v']) >>> t.add_columns([[1, 2], col_b]) >>> t.add_columns([[3, 4], col_b], names=['c', 'd']) >>> print(t) col0 b c d ---- --- --- --- 1 u 3 u 2 v 4 v """ if indexes is None: indexes = [len(self.columns)] * len(cols) elif len(indexes) != len(cols): raise ValueError('Number of indexes must match number of cols') if names is None: names = (None,) * len(cols) elif len(names) != len(cols): raise ValueError('Number of names must match number of cols') default_names = [f'col{ii + len(self.columns)}' for ii in range(len(cols))] for ii in reversed(np.argsort(indexes)): self.add_column(cols[ii], index=indexes[ii], name=names[ii], default_name=default_names[ii], rename_duplicate=rename_duplicate, copy=copy) def _replace_column_warnings(self, name, col): """ Same as replace_column but issues warnings under various circumstances. """ warns = conf.replace_warnings refcount = None old_col = None if 'refcount' in warns and name in self.colnames: refcount = sys.getrefcount(self[name]) if name in self.colnames: old_col = self[name] # This may raise an exception (e.g. t['a'] = 1) in which case none of # the downstream code runs. self.replace_column(name, col) if 'always' in warns: warnings.warn(f"replaced column '{name}'", TableReplaceWarning, stacklevel=3) if 'slice' in warns: try: # Check for ndarray-subclass slice. An unsliced instance # has an ndarray for the base while sliced has the same class # as parent. if isinstance(old_col.base, old_col.__class__): msg = ("replaced column '{}' which looks like an array slice. " "The new column no longer shares memory with the " "original array.".format(name)) warnings.warn(msg, TableReplaceWarning, stacklevel=3) except AttributeError: pass if 'refcount' in warns: # Did reference count change? new_refcount = sys.getrefcount(self[name]) if refcount != new_refcount: msg = ("replaced column '{}' and the number of references " "to the column changed.".format(name)) warnings.warn(msg, TableReplaceWarning, stacklevel=3) if 'attributes' in warns: # Any of the standard column attributes changed? changed_attrs = [] new_col = self[name] # Check base DataInfo attributes that any column will have for attr in DataInfo.attr_names: if getattr(old_col.info, attr) != getattr(new_col.info, attr): changed_attrs.append(attr) if changed_attrs: msg = ("replaced column '{}' and column attributes {} changed." .format(name, changed_attrs)) warnings.warn(msg, TableReplaceWarning, stacklevel=3) def replace_column(self, name, col, copy=True): """ Replace column ``name`` with the new ``col`` object. The behavior of ``copy`` for Column objects is: - copy=True: new class instance with a copy of data and deep copy of meta - copy=False: new class instance with same data and a key-only copy of meta For mixin columns: - copy=True: new class instance with copy of data and deep copy of meta - copy=False: original instance (no copy at all) Parameters ---------- name : str Name of column to replace col : `~astropy.table.Column` or `~numpy.ndarray` or sequence New column object to replace the existing column. copy : bool Make copy of the input ``col``, default=True See Also -------- add_columns, astropy.table.hstack, update Examples -------- Replace column 'a' with a float version of itself:: >>> t = Table([[1, 2, 3], [0.1, 0.2, 0.3]], names=('a', 'b')) >>> float_a = t['a'].astype(float) >>> t.replace_column('a', float_a) """ if name not in self.colnames: raise ValueError(f'column name {name} is not in the table') if self[name].info.indices: raise ValueError('cannot replace a table index column') col = self._convert_data_to_col(col, name=name, copy=copy) self._set_col_parent_table_and_mask(col) # Ensure that new column is the right length, unless it is the only column # in which case re-sizing is allowed. if len(self.columns) > 1 and len(col) != len(self[name]): raise ValueError('length of new column must match table length') self.columns.__setitem__(name, col, validated=True) def remove_row(self, index): """ Remove a row from the table. Parameters ---------- index : int Index of row to remove Examples -------- Create a table with three columns 'a', 'b' and 'c':: >>> t = Table([[1, 2, 3], [0.1, 0.2, 0.3], ['x', 'y', 'z']], ... names=('a', 'b', 'c')) >>> print(t) a b c --- --- --- 1 0.1 x 2 0.2 y 3 0.3 z Remove row 1 from the table:: >>> t.remove_row(1) >>> print(t) a b c --- --- --- 1 0.1 x 3 0.3 z To remove several rows at the same time use remove_rows. """ # check the index against the types that work with np.delete if not isinstance(index, (int, np.integer)): raise TypeError("Row index must be an integer") self.remove_rows(index) def remove_rows(self, row_specifier): """ Remove rows from the table. Parameters ---------- row_specifier : slice or int or array of int Specification for rows to remove Examples -------- Create a table with three columns 'a', 'b' and 'c':: >>> t = Table([[1, 2, 3], [0.1, 0.2, 0.3], ['x', 'y', 'z']], ... names=('a', 'b', 'c')) >>> print(t) a b c --- --- --- 1 0.1 x 2 0.2 y 3 0.3 z Remove rows 0 and 2 from the table:: >>> t.remove_rows([0, 2]) >>> print(t) a b c --- --- --- 2 0.2 y Note that there are no warnings if the slice operator extends outside the data:: >>> t = Table([[1, 2, 3], [0.1, 0.2, 0.3], ['x', 'y', 'z']], ... names=('a', 'b', 'c')) >>> t.remove_rows(slice(10, 20, 1)) >>> print(t) a b c --- --- --- 1 0.1 x 2 0.2 y 3 0.3 z """ # Update indices for index in self.indices: index.remove_rows(row_specifier) keep_mask = np.ones(len(self), dtype=bool) keep_mask[row_specifier] = False columns = self.TableColumns() for name, col in self.columns.items(): newcol = col[keep_mask] newcol.info.parent_table = self columns[name] = newcol self._replace_cols(columns) # Revert groups to default (ungrouped) state if hasattr(self, '_groups'): del self._groups def iterrows(self, *names): """ Iterate over rows of table returning a tuple of values for each row. This method is especially useful when only a subset of columns are needed. The ``iterrows`` method can be substantially faster than using the standard Table row iteration (e.g. ``for row in tbl:``), since that returns a new ``~astropy.table.Row`` object for each row and accessing a column in that row (e.g. ``row['col0']``) is slower than tuple access. Parameters ---------- names : list List of column names (default to all columns if no names provided) Returns ------- rows : iterable Iterator returns tuples of row values Examples -------- Create a table with three columns 'a', 'b' and 'c':: >>> t = Table({'a': [1, 2, 3], ... 'b': [1.0, 2.5, 3.0], ... 'c': ['x', 'y', 'z']}) To iterate row-wise using column names:: >>> for a, c in t.iterrows('a', 'c'): ... print(a, c) 1 x 2 y 3 z """ if len(names) == 0: names = self.colnames else: for name in names: if name not in self.colnames: raise ValueError(f'{name} is not a valid column name') cols = (self[name] for name in names) out = zip(*cols) return out def _set_of_names_in_colnames(self, names): """Return ``names`` as a set if valid, or raise a `KeyError`. ``names`` is valid if all elements in it are in ``self.colnames``. If ``names`` is a string then it is interpreted as a single column name. """ names = {names} if isinstance(names, str) else set(names) invalid_names = names.difference(self.colnames) if len(invalid_names) == 1: raise KeyError(f'column "{invalid_names.pop()}" does not exist') elif len(invalid_names) > 1: raise KeyError(f'columns {invalid_names} do not exist') return names def remove_column(self, name): """ Remove a column from the table. This can also be done with:: del table[name] Parameters ---------- name : str Name of column to remove Examples -------- Create a table with three columns 'a', 'b' and 'c':: >>> t = Table([[1, 2, 3], [0.1, 0.2, 0.3], ['x', 'y', 'z']], ... names=('a', 'b', 'c')) >>> print(t) a b c --- --- --- 1 0.1 x 2 0.2 y 3 0.3 z Remove column 'b' from the table:: >>> t.remove_column('b') >>> print(t) a c --- --- 1 x 2 y 3 z To remove several columns at the same time use remove_columns. """ self.remove_columns([name]) def remove_columns(self, names): ''' Remove several columns from the table. Parameters ---------- names : str or iterable of str Names of the columns to remove Examples -------- Create a table with three columns 'a', 'b' and 'c':: >>> t = Table([[1, 2, 3], [0.1, 0.2, 0.3], ['x', 'y', 'z']], ... names=('a', 'b', 'c')) >>> print(t) a b c --- --- --- 1 0.1 x 2 0.2 y 3 0.3 z Remove columns 'b' and 'c' from the table:: >>> t.remove_columns(['b', 'c']) >>> print(t) a --- 1 2 3 Specifying only a single column also works. Remove column 'b' from the table:: >>> t = Table([[1, 2, 3], [0.1, 0.2, 0.3], ['x', 'y', 'z']], ... names=('a', 'b', 'c')) >>> t.remove_columns('b') >>> print(t) a c --- --- 1 x 2 y 3 z This gives the same as using remove_column. ''' for name in self._set_of_names_in_colnames(names): self.columns.pop(name) def _convert_string_dtype(self, in_kind, out_kind, encode_decode_func): """ Convert string-like columns to/from bytestring and unicode (internal only). Parameters ---------- in_kind : str Input dtype.kind out_kind : str Output dtype.kind """ for col in self.itercols(): if col.dtype.kind == in_kind: try: # This requires ASCII and is faster by a factor of up to ~8, so # try that first. newcol = col.__class__(col, dtype=out_kind) except (UnicodeEncodeError, UnicodeDecodeError): newcol = col.__class__(encode_decode_func(col, 'utf-8')) # Quasi-manually copy info attributes. Unfortunately # DataInfo.__set__ does not do the right thing in this case # so newcol.info = col.info does not get the old info attributes. for attr in col.info.attr_names - col.info._attrs_no_copy - set(['dtype']): value = deepcopy(getattr(col.info, attr)) setattr(newcol.info, attr, value) self[col.name] = newcol def convert_bytestring_to_unicode(self): """ Convert bytestring columns (dtype.kind='S') to unicode (dtype.kind='U') using UTF-8 encoding. Internally this changes string columns to represent each character in the string with a 4-byte UCS-4 equivalent, so it is inefficient for memory but allows scripts to manipulate string arrays with natural syntax. """ self._convert_string_dtype('S', 'U', np.char.decode) def convert_unicode_to_bytestring(self): """ Convert unicode columns (dtype.kind='U') to bytestring (dtype.kind='S') using UTF-8 encoding. When exporting a unicode string array to a file, it may be desirable to encode unicode columns as bytestrings. """ self._convert_string_dtype('U', 'S', np.char.encode) def keep_columns(self, names): ''' Keep only the columns specified (remove the others). Parameters ---------- names : str or iterable of str The columns to keep. All other columns will be removed. Examples -------- Create a table with three columns 'a', 'b' and 'c':: >>> t = Table([[1, 2, 3],[0.1, 0.2, 0.3],['x', 'y', 'z']], ... names=('a', 'b', 'c')) >>> print(t) a b c --- --- --- 1 0.1 x 2 0.2 y 3 0.3 z Keep only column 'a' of the table:: >>> t.keep_columns('a') >>> print(t) a --- 1 2 3 Keep columns 'a' and 'c' of the table:: >>> t = Table([[1, 2, 3],[0.1, 0.2, 0.3],['x', 'y', 'z']], ... names=('a', 'b', 'c')) >>> t.keep_columns(['a', 'c']) >>> print(t) a c --- --- 1 x 2 y 3 z ''' names = self._set_of_names_in_colnames(names) for colname in self.colnames: if colname not in names: self.columns.pop(colname) def rename_column(self, name, new_name): ''' Rename a column. This can also be done directly with by setting the ``name`` attribute for a column:: table[name].name = new_name TODO: this won't work for mixins Parameters ---------- name : str The current name of the column. new_name : str The new name for the column Examples -------- Create a table with three columns 'a', 'b' and 'c':: >>> t = Table([[1,2],[3,4],[5,6]], names=('a','b','c')) >>> print(t) a b c --- --- --- 1 3 5 2 4 6 Renaming column 'a' to 'aa':: >>> t.rename_column('a' , 'aa') >>> print(t) aa b c --- --- --- 1 3 5 2 4 6 ''' if name not in self.keys(): raise KeyError(f"Column {name} does not exist") self.columns[name].info.name = new_name def rename_columns(self, names, new_names): ''' Rename multiple columns. Parameters ---------- names : list, tuple A list or tuple of existing column names. new_names : list, tuple A list or tuple of new column names. Examples -------- Create a table with three columns 'a', 'b', 'c':: >>> t = Table([[1,2],[3,4],[5,6]], names=('a','b','c')) >>> print(t) a b c --- --- --- 1 3 5 2 4 6 Renaming columns 'a' to 'aa' and 'b' to 'bb':: >>> names = ('a','b') >>> new_names = ('aa','bb') >>> t.rename_columns(names, new_names) >>> print(t) aa bb c --- --- --- 1 3 5 2 4 6 ''' if not self._is_list_or_tuple_of_str(names): raise TypeError("input 'names' must be a tuple or a list of column names") if not self._is_list_or_tuple_of_str(new_names): raise TypeError("input 'new_names' must be a tuple or a list of column names") if len(names) != len(new_names): raise ValueError("input 'names' and 'new_names' list arguments must be the same length") for name, new_name in zip(names, new_names): self.rename_column(name, new_name) def _set_row(self, idx, colnames, vals): try: assert len(vals) == len(colnames) except Exception: raise ValueError('right hand side must be a sequence of values with ' 'the same length as the number of selected columns') # Keep track of original values before setting each column so that # setting row can be transactional. orig_vals = [] cols = self.columns try: for name, val in zip(colnames, vals): orig_vals.append(cols[name][idx]) cols[name][idx] = val except Exception: # If anything went wrong first revert the row update then raise for name, val in zip(colnames, orig_vals[:-1]): cols[name][idx] = val raise def add_row(self, vals=None, mask=None): """Add a new row to the end of the table. The ``vals`` argument can be: sequence (e.g. tuple or list) Column values in the same order as table columns. mapping (e.g. dict) Keys corresponding to column names. Missing values will be filled with np.zeros for the column dtype. `None` All values filled with np.zeros for the column dtype. This method requires that the Table object "owns" the underlying array data. In particular one cannot add a row to a Table that was initialized with copy=False from an existing array. The ``mask`` attribute should give (if desired) the mask for the values. The type of the mask should match that of the values, i.e. if ``vals`` is an iterable, then ``mask`` should also be an iterable with the same length, and if ``vals`` is a mapping, then ``mask`` should be a dictionary. Parameters ---------- vals : tuple, list, dict or None Use the specified values in the new row mask : tuple, list, dict or None Use the specified mask values in the new row Examples -------- Create a table with three columns 'a', 'b' and 'c':: >>> t = Table([[1,2],[4,5],[7,8]], names=('a','b','c')) >>> print(t) a b c --- --- --- 1 4 7 2 5 8 Adding a new row with entries '3' in 'a', '6' in 'b' and '9' in 'c':: >>> t.add_row([3,6,9]) >>> print(t) a b c --- --- --- 1 4 7 2 5 8 3 6 9 """ self.insert_row(len(self), vals, mask) def insert_row(self, index, vals=None, mask=None): """Add a new row before the given ``index`` position in the table. The ``vals`` argument can be: sequence (e.g. tuple or list) Column values in the same order as table columns. mapping (e.g. dict) Keys corresponding to column names. Missing values will be filled with np.zeros for the column dtype. `None` All values filled with np.zeros for the column dtype. The ``mask`` attribute should give (if desired) the mask for the values. The type of the mask should match that of the values, i.e. if ``vals`` is an iterable, then ``mask`` should also be an iterable with the same length, and if ``vals`` is a mapping, then ``mask`` should be a dictionary. Parameters ---------- vals : tuple, list, dict or None Use the specified values in the new row mask : tuple, list, dict or None Use the specified mask values in the new row """ colnames = self.colnames N = len(self) if index < -N or index > N: raise IndexError("Index {} is out of bounds for table with length {}" .format(index, N)) if index < 0: index += N if isinstance(vals, Mapping) or vals is None: # From the vals and/or mask mappings create the corresponding lists # that have entries for each table column. if mask is not None and not isinstance(mask, Mapping): raise TypeError("Mismatch between type of vals and mask") # Now check that the mask is specified for the same keys as the # values, otherwise things get really confusing. if mask is not None and set(vals.keys()) != set(mask.keys()): raise ValueError('keys in mask should match keys in vals') if vals and any(name not in colnames for name in vals): raise ValueError('Keys in vals must all be valid column names') vals_list = [] mask_list = [] for name in colnames: if vals and name in vals: vals_list.append(vals[name]) mask_list.append(False if mask is None else mask[name]) else: col = self[name] if hasattr(col, 'dtype'): # Make a placeholder zero element of the right type which is masked. # This assumes the appropriate insert() method will broadcast a # numpy scalar to the right shape. vals_list.append(np.zeros(shape=(), dtype=col.dtype)) # For masked table any unsupplied values are masked by default. mask_list.append(self.masked and vals is not None) else: raise ValueError(f"Value must be supplied for column '{name}'") vals = vals_list mask = mask_list if isiterable(vals): if mask is not None and (not isiterable(mask) or isinstance(mask, Mapping)): raise TypeError("Mismatch between type of vals and mask") if len(self.columns) != len(vals): raise ValueError('Mismatch between number of vals and columns') if mask is not None: if len(self.columns) != len(mask): raise ValueError('Mismatch between number of masks and columns') else: mask = [False] * len(self.columns) else: raise TypeError('Vals must be an iterable or mapping or None') # Insert val at index for each column columns = self.TableColumns() for name, col, val, mask_ in zip(colnames, self.columns.values(), vals, mask): try: # If new val is masked and the existing column does not support masking # then upgrade the column to a mask-enabled type: either the table-level # default ColumnClass or else MaskedColumn. if mask_ and isinstance(col, Column) and not isinstance(col, MaskedColumn): col_cls = (self.ColumnClass if issubclass(self.ColumnClass, self.MaskedColumn) else self.MaskedColumn) col = col_cls(col, copy=False) newcol = col.insert(index, val, axis=0) if len(newcol) != N + 1: raise ValueError('Incorrect length for column {} after inserting {}' ' (expected {}, got {})' .format(name, val, len(newcol), N + 1)) newcol.info.parent_table = self # Set mask if needed and possible if mask_: if hasattr(newcol, 'mask'): newcol[index] = np.ma.masked else: raise TypeError("mask was supplied for column '{}' but it does not " "support masked values".format(col.info.name)) columns[name] = newcol except Exception as err: raise ValueError("Unable to insert row because of exception in column '{}':\n{}" .format(name, err)) from err for table_index in self.indices: table_index.insert_row(index, vals, self.columns.values()) self._replace_cols(columns) # Revert groups to default (ungrouped) state if hasattr(self, '_groups'): del self._groups def _replace_cols(self, columns): for col, new_col in zip(self.columns.values(), columns.values()): new_col.info.indices = [] for index in col.info.indices: index.columns[index.col_position(col.info.name)] = new_col new_col.info.indices.append(index) self.columns = columns def update(self, other, copy=True): """ Perform a dictionary-style update and merge metadata. The argument ``other`` must be a |Table|, or something that can be used to initialize a table. Columns from (possibly converted) ``other`` are added to this table. In case of matching column names the column from this table is replaced with the one from ``other``. Parameters ---------- other : table-like Data to update this table with. copy : bool Whether the updated columns should be copies of or references to the originals. See Also -------- add_columns, astropy.table.hstack, replace_column Examples -------- Update a table with another table:: >>> t1 = Table({'a': ['foo', 'bar'], 'b': [0., 0.]}, meta={'i': 0}) >>> t2 = Table({'b': [1., 2.], 'c': [7., 11.]}, meta={'n': 2}) >>> t1.update(t2) >>> t1
a b c str3 float64 float64 ---- ------- ------- foo 1.0 7.0 bar 2.0 11.0 >>> t1.meta {'i': 0, 'n': 2} Update a table with a dictionary:: >>> t = Table({'a': ['foo', 'bar'], 'b': [0., 0.]}) >>> t.update({'b': [1., 2.]}) >>> t
a b str3 float64 ---- ------- foo 1.0 bar 2.0 """ from .operations import _merge_table_meta if not isinstance(other, Table): other = self.__class__(other, copy=copy) common_cols = set(self.colnames).intersection(other.colnames) for name, col in other.items(): if name in common_cols: self.replace_column(name, col, copy=copy) else: self.add_column(col, name=name, copy=copy) _merge_table_meta(self, [self, other], metadata_conflicts='silent') def argsort(self, keys=None, kind=None, reverse=False): """ Return the indices which would sort the table according to one or more key columns. This simply calls the `numpy.argsort` function on the table with the ``order`` parameter set to ``keys``. Parameters ---------- keys : str or list of str The column name(s) to order the table by kind : {'quicksort', 'mergesort', 'heapsort'}, optional Sorting algorithm. reverse : bool Sort in reverse order (default=False) Returns ------- index_array : ndarray, int Array of indices that sorts the table by the specified key column(s). """ if isinstance(keys, str): keys = [keys] # use index sorted order if possible if keys is not None: index = get_index(self, names=keys) if index is not None: idx = np.asarray(index.sorted_data()) return idx[::-1] if reverse else idx kwargs = {} if keys: # For multiple keys return a structured array which gets sorted, # while for a single key return a single ndarray. Sorting a # one-column structured array is slower than ndarray (e.g. a # factor of ~6 for a 10 million long random array), and much slower # for in principle sortable columns like Time, which get stored as # object arrays. if len(keys) > 1: kwargs['order'] = keys data = self.as_array(names=keys) else: data = self[keys[0]] else: # No keys provided so sort on all columns. data = self.as_array() if kind: kwargs['kind'] = kind # np.argsort will look for a possible .argsort method (e.g., for Time), # and if that fails cast to an array and try sorting that way. idx = np.argsort(data, **kwargs) return idx[::-1] if reverse else idx def sort(self, keys=None, reverse=False): ''' Sort the table according to one or more keys. This operates on the existing table and does not return a new table. Parameters ---------- keys : str or list of str The key(s) to order the table by. If None, use the primary index of the Table. reverse : bool Sort in reverse order (default=False) Examples -------- Create a table with 3 columns:: >>> t = Table([['Max', 'Jo', 'John'], ['Miller', 'Miller', 'Jackson'], ... [12, 15, 18]], names=('firstname', 'name', 'tel')) >>> print(t) firstname name tel --------- ------- --- Max Miller 12 Jo Miller 15 John Jackson 18 Sorting according to standard sorting rules, first 'name' then 'firstname':: >>> t.sort(['name', 'firstname']) >>> print(t) firstname name tel --------- ------- --- John Jackson 18 Jo Miller 15 Max Miller 12 Sorting according to standard sorting rules, first 'firstname' then 'tel', in reverse order:: >>> t.sort(['firstname', 'tel'], reverse=True) >>> print(t) firstname name tel --------- ------- --- Max Miller 12 John Jackson 18 Jo Miller 15 ''' if keys is None: if not self.indices: raise ValueError("Table sort requires input keys or a table index") keys = [x.info.name for x in self.indices[0].columns] if isinstance(keys, str): keys = [keys] indexes = self.argsort(keys) if reverse: indexes = indexes[::-1] with self.index_mode('freeze'): for name, col in self.columns.items(): # Make a new sorted column. This requires that take() also copies # relevant info attributes for mixin columns. new_col = col.take(indexes, axis=0) # First statement in try: will succeed if the column supports an in-place # update, and matches the legacy behavior of astropy Table. However, # some mixin classes may not support this, so in that case just drop # in the entire new column. See #9553 and #9536 for discussion. try: col[:] = new_col except Exception: # In-place update failed for some reason, exception class not # predictable for arbitrary mixin. self[col.info.name] = new_col def reverse(self): ''' Reverse the row order of table rows. The table is reversed in place and there are no function arguments. Examples -------- Create a table with three columns:: >>> t = Table([['Max', 'Jo', 'John'], ['Miller','Miller','Jackson'], ... [12,15,18]], names=('firstname','name','tel')) >>> print(t) firstname name tel --------- ------- --- Max Miller 12 Jo Miller 15 John Jackson 18 Reversing order:: >>> t.reverse() >>> print(t) firstname name tel --------- ------- --- John Jackson 18 Jo Miller 15 Max Miller 12 ''' for col in self.columns.values(): # First statement in try: will succeed if the column supports an in-place # update, and matches the legacy behavior of astropy Table. However, # some mixin classes may not support this, so in that case just drop # in the entire new column. See #9836, #9553, and #9536 for discussion. new_col = col[::-1] try: col[:] = new_col except Exception: # In-place update failed for some reason, exception class not # predictable for arbitrary mixin. self[col.info.name] = new_col for index in self.indices: index.reverse() def round(self, decimals=0): ''' Round numeric columns in-place to the specified number of decimals. Non-numeric columns will be ignored. Examples -------- Create three columns with different types: >>> t = Table([[1, 4, 5], [-25.55, 12.123, 85], ... ['a', 'b', 'c']], names=('a', 'b', 'c')) >>> print(t) a b c --- ------ --- 1 -25.55 a 4 12.123 b 5 85.0 c Round them all to 0: >>> t.round(0) >>> print(t) a b c --- ----- --- 1 -26.0 a 4 12.0 b 5 85.0 c Round column 'a' to -1 decimal: >>> t.round({'a':-1}) >>> print(t) a b c --- ----- --- 0 -26.0 a 0 12.0 b 0 85.0 c Parameters ---------- decimals: int, dict Number of decimals to round the columns to. If a dict is given, the columns will be rounded to the number specified as the value. If a certain column is not in the dict given, it will remain the same. ''' if isinstance(decimals, Mapping): decimal_values = decimals.values() column_names = decimals.keys() elif isinstance(decimals, int): decimal_values = itertools.repeat(decimals) column_names = self.colnames else: raise ValueError("'decimals' argument must be an int or a dict") for colname, decimal in zip(column_names, decimal_values): col = self.columns[colname] if np.issubdtype(col.info.dtype, np.number): try: np.around(col, decimals=decimal, out=col) except TypeError: # Bug in numpy see https://github.com/numpy/numpy/issues/15438 col[()] = np.around(col, decimals=decimal) def copy(self, copy_data=True): ''' Return a copy of the table. Parameters ---------- copy_data : bool If `True` (the default), copy the underlying data array. Otherwise, use the same data array. The ``meta`` is always deepcopied regardless of the value for ``copy_data``. ''' out = self.__class__(self, copy=copy_data) # If the current table is grouped then do the same in the copy if hasattr(self, '_groups'): out._groups = groups.TableGroups(out, indices=self._groups._indices, keys=self._groups._keys) return out def __deepcopy__(self, memo=None): return self.copy(True) def __copy__(self): return self.copy(False) def __lt__(self, other): return super().__lt__(other) def __gt__(self, other): return super().__gt__(other) def __le__(self, other): return super().__le__(other) def __ge__(self, other): return super().__ge__(other) def __eq__(self, other): return self._rows_equal(other) def __ne__(self, other): return ~self.__eq__(other) def _rows_equal(self, other): """ Row-wise comparison of table with any other object. This is actual implementation for __eq__. Returns a 1-D boolean numpy array showing result of row-wise comparison. This is the same as the ``==`` comparison for tables. Parameters ---------- other : Table or DataFrame or ndarray An object to compare with table Examples -------- Comparing one Table with other:: >>> t1 = Table([[1,2],[4,5],[7,8]], names=('a','b','c')) >>> t2 = Table([[1,2],[4,5],[7,8]], names=('a','b','c')) >>> t1._rows_equal(t2) array([ True, True]) """ if isinstance(other, Table): other = other.as_array() if self.has_masked_columns: if isinstance(other, np.ma.MaskedArray): result = self.as_array() == other else: # If mask is True, then by definition the row doesn't match # because the other array is not masked. false_mask = np.zeros(1, dtype=[(n, bool) for n in self.dtype.names]) result = (self.as_array().data == other) & (self.mask == false_mask) else: if isinstance(other, np.ma.MaskedArray): # If mask is True, then by definition the row doesn't match # because the other array is not masked. false_mask = np.zeros(1, dtype=[(n, bool) for n in other.dtype.names]) result = (self.as_array() == other.data) & (other.mask == false_mask) else: result = self.as_array() == other return result def values_equal(self, other): """ Element-wise comparison of table with another table, list, or scalar. Returns a ``Table`` with the same columns containing boolean values showing result of comparison. Parameters ---------- other : table-like object or list or scalar Object to compare with table Examples -------- Compare one Table with other:: >>> t1 = Table([[1, 2], [4, 5], [-7, 8]], names=('a', 'b', 'c')) >>> t2 = Table([[1, 2], [-4, 5], [7, 8]], names=('a', 'b', 'c')) >>> t1.values_equal(t2)
a b c bool bool bool ---- ----- ----- True False False True True True """ if isinstance(other, Table): names = other.colnames else: try: other = Table(other, copy=False) names = other.colnames except Exception: # Broadcast other into a dict, so e.g. other = 2 will turn into # other = {'a': 2, 'b': 2} and then equality does a # column-by-column broadcasting. names = self.colnames other = {name: other for name in names} # Require column names match but do not require same column order if set(self.colnames) != set(names): raise ValueError('cannot compare tables with different column names') eqs = [] for name in names: try: np.broadcast(self[name], other[name]) # Check if broadcast-able # Catch the numpy FutureWarning related to equality checking, # "elementwise comparison failed; returning scalar instead, but # in the future will perform elementwise comparison". Turn this # into an exception since the scalar answer is not what we want. with warnings.catch_warnings(record=True) as warns: warnings.simplefilter('always') eq = self[name] == other[name] if (warns and issubclass(warns[-1].category, FutureWarning) and 'elementwise comparison failed' in str(warns[-1].message)): raise FutureWarning(warns[-1].message) except Exception as err: raise ValueError(f'unable to compare column {name}') from err # Be strict about the result from the comparison. E.g. SkyCoord __eq__ is just # broken and completely ignores that it should return an array. if not (isinstance(eq, np.ndarray) and eq.dtype is np.dtype('bool') and len(eq) == len(self)): raise TypeError(f'comparison for column {name} returned {eq} ' f'instead of the expected boolean ndarray') eqs.append(eq) out = Table(eqs, names=names) return out @property def groups(self): if not hasattr(self, '_groups'): self._groups = groups.TableGroups(self) return self._groups def group_by(self, keys): """ Group this table by the specified ``keys`` This effectively splits the table into groups which correspond to unique values of the ``keys`` grouping object. The output is a new `~astropy.table.TableGroups` which contains a copy of this table but sorted by row according to ``keys``. The ``keys`` input to `group_by` can be specified in different ways: - String or list of strings corresponding to table column name(s) - Numpy array (homogeneous or structured) with same length as this table - `~astropy.table.Table` with same length as this table Parameters ---------- keys : str, list of str, numpy array, or `~astropy.table.Table` Key grouping object Returns ------- out : `~astropy.table.Table` New table with groups set """ return groups.table_group_by(self, keys) def to_pandas(self, index=None, use_nullable_int=True): """ Return a :class:`pandas.DataFrame` instance The index of the created DataFrame is controlled by the ``index`` argument. For ``index=True`` or the default ``None``, an index will be specified for the DataFrame if there is a primary key index on the Table *and* if it corresponds to a single column. If ``index=False`` then no DataFrame index will be specified. If ``index`` is the name of a column in the table then that will be the DataFrame index. In addition to vanilla columns or masked columns, this supports Table mixin columns like Quantity, Time, or SkyCoord. In many cases these objects have no analog in pandas and will be converted to a "encoded" representation using only Column or MaskedColumn. The exception is Time or TimeDelta columns, which will be converted to the corresponding representation in pandas using ``np.datetime64`` or ``np.timedelta64``. See the example below. Parameters ---------- index : None, bool, str Specify DataFrame index mode use_nullable_int : bool, default=True Convert integer MaskedColumn to pandas nullable integer type. If ``use_nullable_int=False`` or the pandas version does not support nullable integer types (version < 0.24), then the column is converted to float with NaN for missing elements and a warning is issued. Returns ------- dataframe : :class:`pandas.DataFrame` A pandas :class:`pandas.DataFrame` instance Raises ------ ImportError If pandas is not installed ValueError If the Table has multi-dimensional columns Examples -------- Here we convert a table with a few mixins to a :class:`pandas.DataFrame` instance. >>> import pandas as pd >>> from astropy.table import QTable >>> import astropy.units as u >>> from astropy.time import Time, TimeDelta >>> from astropy.coordinates import SkyCoord >>> q = [1, 2] * u.m >>> tm = Time([1998, 2002], format='jyear') >>> sc = SkyCoord([5, 6], [7, 8], unit='deg') >>> dt = TimeDelta([3, 200] * u.s) >>> t = QTable([q, tm, sc, dt], names=['q', 'tm', 'sc', 'dt']) >>> df = t.to_pandas(index='tm') >>> with pd.option_context('display.max_columns', 20): ... print(df) q sc.ra sc.dec dt tm 1998-01-01 1.0 5.0 7.0 0 days 00:00:03 2002-01-01 2.0 6.0 8.0 0 days 00:03:20 """ from pandas import DataFrame, Series if index is not False: if index in (None, True): # Default is to use the table primary key if available and a single column if self.primary_key and len(self.primary_key) == 1: index = self.primary_key[0] else: index = False else: if index not in self.colnames: raise ValueError('index must be None, False, True or a table ' 'column name') def _encode_mixins(tbl): """Encode a Table ``tbl`` that may have mixin columns to a Table with only astropy Columns + appropriate meta-data to allow subsequent decoding. """ from . import serialize from astropy.time import TimeBase, TimeDelta # Convert any Time or TimeDelta columns and pay attention to masking time_cols = [col for col in tbl.itercols() if isinstance(col, TimeBase)] if time_cols: # Make a light copy of table and clear any indices new_cols = [] for col in tbl.itercols(): new_col = col_copy(col, copy_indices=False) if col.info.indices else col new_cols.append(new_col) tbl = tbl.__class__(new_cols, copy=False) # Certain subclasses (e.g. TimeSeries) may generate new indices on # table creation, so make sure there are no indices on the table. for col in tbl.itercols(): col.info.indices.clear() for col in time_cols: if isinstance(col, TimeDelta): # Convert to nanoseconds (matches astropy datetime64 support) new_col = (col.sec * 1e9).astype('timedelta64[ns]') nat = np.timedelta64('NaT') else: new_col = col.datetime64.copy() nat = np.datetime64('NaT') if col.masked: new_col[col.mask] = nat tbl[col.info.name] = new_col # Convert the table to one with no mixins, only Column objects. encode_tbl = serialize.represent_mixins_as_columns(tbl) return encode_tbl tbl = _encode_mixins(self) badcols = [name for name, col in self.columns.items() if len(col.shape) > 1] if badcols: raise ValueError( f'Cannot convert a table with multidimensional columns to a ' f'pandas DataFrame. Offending columns are: {badcols}\n' f'One can filter out such columns using:\n' f'names = [name for name in tbl.colnames if len(tbl[name].shape) <= 1]\n' f'tbl[names].to_pandas(...)') out = OrderedDict() for name, column in tbl.columns.items(): if getattr(column.dtype, 'isnative', True): out[name] = column else: out[name] = column.data.byteswap().newbyteorder('=') if isinstance(column, MaskedColumn) and np.any(column.mask): if column.dtype.kind in ['i', 'u']: pd_dtype = column.dtype.name if use_nullable_int: # Convert int64 to Int64, uint32 to UInt32, etc for nullable types pd_dtype = pd_dtype.replace('i', 'I').replace('u', 'U') out[name] = Series(out[name], dtype=pd_dtype) # If pandas is older than 0.24 the type may have turned to float if column.dtype.kind != out[name].dtype.kind: warnings.warn( f"converted column '{name}' from {column.dtype} to {out[name].dtype}", TableReplaceWarning, stacklevel=3) elif column.dtype.kind not in ['f', 'c']: out[name] = column.astype(object).filled(np.nan) kwargs = {} if index: idx = out.pop(index) kwargs['index'] = idx # We add the table index to Series inputs (MaskedColumn with int values) to override # its default RangeIndex, see #11432 for v in out.values(): if isinstance(v, Series): v.index = idx df = DataFrame(out, **kwargs) if index: # Explicitly set the pandas DataFrame index to the original table # index name. df.index.name = idx.info.name return df @classmethod def from_pandas(cls, dataframe, index=False, units=None): """ Create a `~astropy.table.Table` from a :class:`pandas.DataFrame` instance In addition to converting generic numeric or string columns, this supports conversion of pandas Date and Time delta columns to `~astropy.time.Time` and `~astropy.time.TimeDelta` columns, respectively. Parameters ---------- dataframe : :class:`pandas.DataFrame` A pandas :class:`pandas.DataFrame` instance index : bool Include the index column in the returned table (default=False) units: dict A dict mapping column names to to a `~astropy.units.Unit`. The columns will have the specified unit in the Table. Returns ------- table : `~astropy.table.Table` A `~astropy.table.Table` (or subclass) instance Raises ------ ImportError If pandas is not installed Examples -------- Here we convert a :class:`pandas.DataFrame` instance to a `~astropy.table.QTable`. >>> import numpy as np >>> import pandas as pd >>> from astropy.table import QTable >>> time = pd.Series(['1998-01-01', '2002-01-01'], dtype='datetime64[ns]') >>> dt = pd.Series(np.array([1, 300], dtype='timedelta64[s]')) >>> df = pd.DataFrame({'time': time}) >>> df['dt'] = dt >>> df['x'] = [3., 4.] >>> with pd.option_context('display.max_columns', 20): ... print(df) time dt x 0 1998-01-01 0 days 00:00:01 3.0 1 2002-01-01 0 days 00:05:00 4.0 >>> QTable.from_pandas(df) time dt x Time TimeDelta float64 ----------------------- --------- ------- 1998-01-01T00:00:00.000 1.0 3.0 2002-01-01T00:00:00.000 300.0 4.0 """ out = OrderedDict() names = list(dataframe.columns) columns = [dataframe[name] for name in names] datas = [np.array(column) for column in columns] masks = [np.array(column.isnull()) for column in columns] if index: index_name = dataframe.index.name or 'index' while index_name in names: index_name = '_' + index_name + '_' names.insert(0, index_name) columns.insert(0, dataframe.index) datas.insert(0, np.array(dataframe.index)) masks.insert(0, np.zeros(len(dataframe), dtype=bool)) if units is None: units = [None] * len(names) else: if not isinstance(units, Mapping): raise TypeError('Expected a Mapping "column-name" -> "unit"') not_found = set(units.keys()) - set(names) if not_found: warnings.warn(f'`units` contains additional columns: {not_found}') units = [units.get(name) for name in names] for name, column, data, mask, unit in zip(names, columns, datas, masks, units): if column.dtype.kind in ['u', 'i'] and np.any(mask): # Special-case support for pandas nullable int np_dtype = str(column.dtype).lower() data = np.zeros(shape=column.shape, dtype=np_dtype) data[~mask] = column[~mask] out[name] = MaskedColumn(data=data, name=name, mask=mask, unit=unit, copy=False) continue if data.dtype.kind == 'O': # If all elements of an object array are string-like or np.nan # then coerce back to a native numpy str/unicode array. string_types = (str, bytes) nan = np.nan if all(isinstance(x, string_types) or x is nan for x in data): # Force any missing (null) values to b''. Numpy will # upcast to str/unicode as needed. data[mask] = b'' # When the numpy object array is represented as a list then # numpy initializes to the correct string or unicode type. data = np.array([x for x in data]) # Numpy datetime64 if data.dtype.kind == 'M': from astropy.time import Time out[name] = Time(data, format='datetime64') if np.any(mask): out[name][mask] = np.ma.masked out[name].format = 'isot' # Numpy timedelta64 elif data.dtype.kind == 'm': from astropy.time import TimeDelta data_sec = data.astype('timedelta64[ns]').astype(np.float64) / 1e9 out[name] = TimeDelta(data_sec, format='sec') if np.any(mask): out[name][mask] = np.ma.masked else: if np.any(mask): out[name] = MaskedColumn(data=data, name=name, mask=mask, unit=unit) else: out[name] = Column(data=data, name=name, unit=unit) return cls(out) info = TableInfo() class QTable(Table): """A class to represent tables of heterogeneous data. `~astropy.table.QTable` provides a class for heterogeneous tabular data which can be easily modified, for instance adding columns or new rows. The `~astropy.table.QTable` class is identical to `~astropy.table.Table` except that columns with an associated ``unit`` attribute are converted to `~astropy.units.Quantity` objects. See also: - https://docs.astropy.org/en/stable/table/ - https://docs.astropy.org/en/stable/table/mixin_columns.html Parameters ---------- data : numpy ndarray, dict, list, table-like object, optional Data to initialize table. masked : bool, optional Specify whether the table is masked. names : list, optional Specify column names. dtype : list, optional Specify column data types. meta : dict, optional Metadata associated with the table. copy : bool, optional Copy the input data. Default is True. rows : numpy ndarray, list of list, optional Row-oriented data for table instead of ``data`` argument. copy_indices : bool, optional Copy any indices in the input data. Default is True. **kwargs : dict, optional Additional keyword args when converting table-like object. """ def _is_mixin_for_table(self, col): """ Determine if ``col`` should be added to the table directly as a mixin column. """ return has_info_class(col, MixinInfo) def _convert_col_for_table(self, col): if isinstance(col, Column) and getattr(col, 'unit', None) is not None: # We need to turn the column into a quantity; use subok=True to allow # Quantity subclasses identified in the unit (such as u.mag()). q_cls = Masked(Quantity) if isinstance(col, MaskedColumn) else Quantity try: qcol = q_cls(col.data, col.unit, copy=False, subok=True) except Exception as exc: warnings.warn(f"column {col.info.name} has a unit but is kept as " f"a {col.__class__.__name__} as an attempt to " f"convert it to Quantity failed with:\n{exc!r}", AstropyUserWarning) else: qcol.info = col.info qcol.info.indices = col.info.indices col = qcol else: col = super()._convert_col_for_table(col) return col ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/table_helpers.py0000644000175100001710000001425700000000000020231 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ Helper functions for table development, mostly creating useful tables for testing. """ from itertools import cycle import string import numpy as np from .table import Table, Column from astropy.utils.data_info import ParentDtypeInfo class TimingTables: """ Object which contains two tables and various other attributes that are useful for timing and other API tests. """ def __init__(self, size=1000, masked=False): self.masked = masked # Initialize table self.table = Table(masked=self.masked) # Create column with mixed types np.random.seed(12345) self.table['i'] = np.arange(size) self.table['a'] = np.random.random(size) # float self.table['b'] = np.random.random(size) > 0.5 # bool self.table['c'] = np.random.random((size, 10)) # 2d column self.table['d'] = np.random.choice(np.array(list(string.ascii_letters)), size) self.extra_row = {'a': 1.2, 'b': True, 'c': np.repeat(1, 10), 'd': 'Z'} self.extra_column = np.random.randint(0, 100, size) self.row_indices = np.where(self.table['a'] > 0.9)[0] self.table_grouped = self.table.group_by('d') # Another table for testing joining self.other_table = Table(masked=self.masked) self.other_table['i'] = np.arange(1, size, 3) self.other_table['f'] = np.random.random() self.other_table.sort('f') # Another table for testing hstack self.other_table_2 = Table(masked=self.masked) self.other_table_2['g'] = np.random.random(size) self.other_table_2['h'] = np.random.random((size, 10)) self.bool_mask = self.table['a'] > 0.6 def simple_table(size=3, cols=None, kinds='ifS', masked=False): """ Return a simple table for testing. Example -------- :: >>> from astropy.table.table_helpers import simple_table >>> print(simple_table(3, 6, masked=True, kinds='ifOS')) a b c d e f --- --- -------- --- --- --- -- 1.0 {'c': 2} -- 5 5.0 2 2.0 -- e 6 -- 3 -- {'e': 4} f -- 7.0 Parameters ---------- size : int Number of table rows cols : int, optional Number of table columns. Defaults to number of kinds. kinds : str String consisting of the column dtype.kinds. This string will be cycled through to generate the column dtype. The allowed values are 'i', 'f', 'S', 'O'. Returns ------- out : `Table` New table with appropriate characteristics """ if cols is None: cols = len(kinds) if cols > 26: raise ValueError("Max 26 columns in SimpleTable") columns = [] names = [chr(ord('a') + ii) for ii in range(cols)] letters = np.array([c for c in string.ascii_letters]) for jj, kind in zip(range(cols), cycle(kinds)): if kind == 'i': data = np.arange(1, size + 1, dtype=np.int64) + jj elif kind == 'f': data = np.arange(size, dtype=np.float64) + jj elif kind == 'S': indices = (np.arange(size) + jj) % len(letters) data = letters[indices] elif kind == 'O': indices = (np.arange(size) + jj) % len(letters) vals = letters[indices] data = [{val: index} for val, index in zip(vals, indices)] else: raise ValueError('Unknown data kind') columns.append(Column(data)) table = Table(columns, names=names, masked=masked) if masked: for ii, col in enumerate(table.columns.values()): mask = np.array((np.arange(size) + ii) % 3, dtype=bool) col.mask = ~mask return table def complex_table(): """ Return a masked table from the io.votable test set that has a wide variety of stressing types. """ from astropy.utils.data import get_pkg_data_filename from astropy.io.votable.table import parse import warnings with warnings.catch_warnings(): warnings.simplefilter("ignore") votable = parse(get_pkg_data_filename('../io/votable/tests/data/regression.xml'), pedantic=False) first_table = votable.get_first_table() table = first_table.to_table() return table class ArrayWrapperInfo(ParentDtypeInfo): _represent_as_dict_primary_data = 'data' def _represent_as_dict(self): """Represent Column as a dict that can be serialized.""" col = self._parent out = {'data': col.data} return out def _construct_from_dict(self, map): """Construct Column from ``map``.""" data = map.pop('data') out = self._parent_cls(data, **map) return out class ArrayWrapper: """ Minimal mixin using a simple wrapper around a numpy array TODO: think about the future of this class as it is mostly for demonstration purposes (of the mixin protocol). Consider taking it out of core and putting it into a tutorial. One advantage of having this in core is that it is getting tested in the mixin testing though it doesn't work for multidim data. """ info = ArrayWrapperInfo() def __init__(self, data): self.data = np.array(data) if 'info' in getattr(data, '__dict__', ()): self.info = data.info def __getitem__(self, item): if isinstance(item, (int, np.integer)): out = self.data[item] else: out = self.__class__(self.data[item]) if 'info' in self.__dict__: out.info = self.info return out def __setitem__(self, item, value): self.data[item] = value def __len__(self): return len(self.data) def __eq__(self, other): """Minimal equality testing, mostly for mixin unit tests""" if isinstance(other, ArrayWrapper): return self.data == other.data else: return self.data == other @property def dtype(self): return self.data.dtype @property def shape(self): return self.data.shape def __repr__(self): return f"<{self.__class__.__name__} name='{self.info.name}' data={self.data}>" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1712518 astropy-5.0.2/astropy/table/tests/0000755000175100001710000000000000000000000016177 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/tests/__init__.py0000644000175100001710000000000000000000000020276 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/tests/conftest.py0000644000175100001710000001520400000000000020400 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ All of the pytest fixtures used by astropy.table are defined here. `conftest.py` is a "special" module name for pytest that is always imported, but is not looked in for tests, and it is the recommended place to put fixtures that are shared between modules. These fixtures can not be defined in a module by a different name and still be shared between modules. """ from copy import deepcopy from collections import OrderedDict import pickle import pytest import numpy as np from astropy import table from astropy.table import Table, QTable from astropy.table.table_helpers import ArrayWrapper from astropy import time from astropy import units as u from astropy import coordinates from astropy.table import pprint @pytest.fixture(params=[table.Column, table.MaskedColumn]) def Column(request): # Fixture to run all the Column tests for both an unmasked (ndarray) # and masked (MaskedArray) column. return request.param class MaskedTable(table.Table): def __init__(self, *args, **kwargs): kwargs['masked'] = True table.Table.__init__(self, *args, **kwargs) class MyRow(table.Row): pass class MyColumn(table.Column): pass class MyMaskedColumn(table.MaskedColumn): pass class MyTableColumns(table.TableColumns): pass class MyTableFormatter(pprint.TableFormatter): pass class MyTable(table.Table): Row = MyRow Column = MyColumn MaskedColumn = MyMaskedColumn TableColumns = MyTableColumns TableFormatter = MyTableFormatter # Fixture to run all the Column tests for both an unmasked (ndarray) # and masked (MaskedArray) column. @pytest.fixture(params=['unmasked', 'masked', 'subclass']) def table_types(request): class TableTypes: def __init__(self, request): if request.param == 'unmasked': self.Table = table.Table self.Column = table.Column elif request.param == 'masked': self.Table = MaskedTable self.Column = table.MaskedColumn elif request.param == 'subclass': self.Table = MyTable self.Column = MyColumn return TableTypes(request) # Fixture to run all the Column tests for both an unmasked (ndarray) # and masked (MaskedArray) column. @pytest.fixture(params=[False, True]) def table_data(request): class TableData: def __init__(self, request): self.Table = MaskedTable if request.param else table.Table self.Column = table.MaskedColumn if request.param else table.Column self.COLS = [ self.Column(name='a', data=[1, 2, 3], description='da', format='%i', meta={'ma': 1}, unit='ua'), self.Column(name='b', data=[4, 5, 6], description='db', format='%d', meta={'mb': 1}, unit='ub'), self.Column(name='c', data=[7, 8, 9], description='dc', format='%f', meta={'mc': 1}, unit='ub')] self.DATA = self.Table(self.COLS) return TableData(request) class SubclassTable(table.Table): pass @pytest.fixture(params=[True, False]) def tableclass(request): return table.Table if request.param else SubclassTable @pytest.fixture(params=list(range(0, pickle.HIGHEST_PROTOCOL + 1))) def protocol(request): """ Fixture to run all the tests for all available pickle protocols. """ return request.param # Fixture to run all tests for both an unmasked (ndarray) and masked # (MaskedArray) column. @pytest.fixture(params=[False, True]) def table_type(request): return MaskedTable if request.param else table.Table # Stuff for testing mixin columns MIXIN_COLS = {'quantity': [0, 1, 2, 3] * u.m, 'longitude': coordinates.Longitude([0., 1., 5., 6.] * u.deg, wrap_angle=180. * u.deg), 'latitude': coordinates.Latitude([5., 6., 10., 11.] * u.deg), 'time': time.Time([2000, 2001, 2002, 2003], format='jyear'), 'timedelta': time.TimeDelta([1, 2, 3, 4], format='jd'), 'skycoord': coordinates.SkyCoord(ra=[0, 1, 2, 3] * u.deg, dec=[0, 1, 2, 3] * u.deg), 'sphericalrep': coordinates.SphericalRepresentation( [0, 1, 2, 3]*u.deg, [0, 1, 2, 3]*u.deg, 1*u.kpc), 'cartesianrep': coordinates.CartesianRepresentation( [0, 1, 2, 3]*u.pc, [4, 5, 6, 7]*u.pc, [9, 8, 8, 6]*u.pc), 'sphericaldiff': coordinates.SphericalCosLatDifferential( [0, 1, 2, 3]*u.mas/u.yr, [0, 1, 2, 3]*u.mas/u.yr, 10*u.km/u.s), 'arraywrap': ArrayWrapper([0, 1, 2, 3]), 'arrayswap': ArrayWrapper(np.arange(4, dtype='i').byteswap().newbyteorder()), 'ndarraylil': np.array([(7, 'a'), (8, 'b'), (9, 'c'), (9, 'c')], dtype='\n1\n2\n3" def test_format(self, Column): """Show that the formatted output from str() works""" from astropy import conf with conf.set_temp('max_lines', 8): c1 = Column(np.arange(2000), name='a', dtype=float, format='%6.2f') assert str(c1).splitlines() == [' a ', '-------', ' 0.00', ' 1.00', ' ...', '1998.00', '1999.00', 'Length = 2000 rows'] def test_convert_numpy_array(self, Column): d = Column([1, 2, 3], name='a', dtype='i8') np_data = np.array(d) assert np.all(np_data == d) np_data = np.array(d, copy=False) assert np.all(np_data == d) np_data = np.array(d, dtype='i4') assert np.all(np_data == d) def test_convert_unit(self, Column): d = Column([1, 2, 3], name='a', dtype="f8", unit="m") d.convert_unit_to("km") assert np.all(d.data == [0.001, 0.002, 0.003]) def test_array_wrap(self): """Test that the __array_wrap__ method converts a reduction ufunc output that has a different shape into an ndarray view. Without this a method call like c.mean() returns a Column array object with length=1.""" # Mean and sum for a 1-d float column c = table.Column(name='a', data=[1., 2., 3.]) assert np.allclose(c.mean(), 2.0) assert isinstance(c.mean(), (np.floating, float)) assert np.allclose(c.sum(), 6.) assert isinstance(c.sum(), (np.floating, float)) # Non-reduction ufunc preserves Column class assert isinstance(np.cos(c), table.Column) # Sum for a 1-d int column c = table.Column(name='a', data=[1, 2, 3]) assert np.allclose(c.sum(), 6) assert isinstance(c.sum(), (np.integer, int)) # Sum for a 2-d int column c = table.Column(name='a', data=[[1, 2, 3], [4, 5, 6]]) assert c.sum() == 21 assert isinstance(c.sum(), (np.integer, int)) assert np.all(c.sum(axis=0) == [5, 7, 9]) assert c.sum(axis=0).shape == (3,) assert isinstance(c.sum(axis=0), np.ndarray) # Sum and mean for a 1-d masked column c = table.MaskedColumn(name='a', data=[1., 2., 3.], mask=[0, 0, 1]) assert np.allclose(c.mean(), 1.5) assert isinstance(c.mean(), (np.floating, float)) assert np.allclose(c.sum(), 3.) assert isinstance(c.sum(), (np.floating, float)) def test_name_none(self, Column): """Can create a column without supplying name, which defaults to None""" c = Column([1, 2]) assert c.name is None assert np.all(c == np.array([1, 2])) def test_quantity_init(self, Column): c = Column(data=np.array([1, 2, 3]) * u.m) assert np.all(c.data == np.array([1, 2, 3])) assert np.all(c.unit == u.m) c = Column(data=np.array([1, 2, 3]) * u.m, unit=u.cm) assert np.all(c.data == np.array([100, 200, 300])) assert np.all(c.unit == u.cm) def test_quantity_comparison(self, Column): # regression test for gh-6532 c = Column([1, 2100, 3], unit='Hz') q = 2 * u.kHz check = c < q assert np.all(check == [True, False, True]) # This already worked, but just in case. check = q >= c assert np.all(check == [True, False, True]) def test_attrs_survive_getitem_after_change(self, Column): """ Test for issue #3023: when calling getitem with a MaskedArray subclass the original object attributes are not copied. """ c1 = Column([1, 2, 3], name='a', unit='m', format='%i', description='aa', meta={'a': 1}) c1.name = 'b' c1.unit = 'km' c1.format = '%d' c1.description = 'bb' c1.meta = {'bbb': 2} for item in (slice(None, None), slice(None, 1), np.array([0, 2]), np.array([False, True, False])): c2 = c1[item] assert c2.name == 'b' assert c2.unit is u.km assert c2.format == '%d' assert c2.description == 'bb' assert c2.meta == {'bbb': 2} # Make sure that calling getitem resulting in a scalar does # not copy attributes. val = c1[1] for attr in ('name', 'unit', 'format', 'description', 'meta'): assert not hasattr(val, attr) def test_to_quantity(self, Column): d = Column([1, 2, 3], name='a', dtype="f8", unit="m") assert np.all(d.quantity == ([1, 2, 3.] * u.m)) assert np.all(d.quantity.value == ([1, 2, 3.] * u.m).value) assert np.all(d.quantity == d.to('m')) assert np.all(d.quantity.value == d.to('m').value) np.testing.assert_allclose(d.to(u.km).value, ([.001, .002, .003] * u.km).value) np.testing.assert_allclose(d.to('km').value, ([.001, .002, .003] * u.km).value) np.testing.assert_allclose(d.to(u.MHz, u.equivalencies.spectral()).value, [299.792458, 149.896229, 99.93081933]) d_nounit = Column([1, 2, 3], name='a', dtype="f8", unit=None) with pytest.raises(u.UnitsError): d_nounit.to(u.km) assert np.all(d_nounit.to(u.dimensionless_unscaled) == np.array([1, 2, 3])) # make sure the correct copy/no copy behavior is happening q = [1, 3, 5] * u.km # to should always make a copy d.to(u.km)[:] = q np.testing.assert_allclose(d, [1, 2, 3]) # explicit copying of the quantity should not change the column d.quantity.copy()[:] = q np.testing.assert_allclose(d, [1, 2, 3]) # but quantity directly is a "view", accessing the underlying column d.quantity[:] = q np.testing.assert_allclose(d, [1000, 3000, 5000]) # view should also work for integers d2 = Column([1, 2, 3], name='a', dtype=int, unit="m") d2.quantity[:] = q np.testing.assert_allclose(d2, [1000, 3000, 5000]) # but it should fail for strings or other non-numeric tables d3 = Column(['arg', 'name', 'stuff'], name='a', unit="m") with pytest.raises(TypeError): d3.quantity def test_to_funcunit_quantity(self, Column): """ Tests for #8424, check if function-unit can be retrieved from column. """ d = Column([1, 2, 3], name='a', dtype="f8", unit="dex(AA)") assert np.all(d.quantity == ([1, 2, 3] * u.dex(u.AA))) assert np.all(d.quantity.value == ([1, 2, 3] * u.dex(u.AA)).value) assert np.all(d.quantity == d.to("dex(AA)")) assert np.all(d.quantity.value == d.to("dex(AA)").value) # make sure, casting to linear unit works q = [10, 100, 1000] * u.AA np.testing.assert_allclose(d.to(u.AA), q) def test_item_access_type(self, Column): """ Tests for #3095, which forces integer item access to always return a plain ndarray or MaskedArray, even in the case of a multi-dim column. """ integer_types = (int, np.int_) for int_type in integer_types: c = Column([[1, 2], [3, 4]]) i0 = int_type(0) i1 = int_type(1) assert np.all(c[i0] == [1, 2]) assert type(c[i0]) == (np.ma.MaskedArray if hasattr(Column, 'mask') else np.ndarray) assert c[i0].shape == (2,) c01 = c[i0:i1] assert np.all(c01 == [[1, 2]]) assert isinstance(c01, Column) assert c01.shape == (1, 2) c = Column([1, 2]) assert np.all(c[i0] == 1) assert isinstance(c[i0], np.integer) assert c[i0].shape == () c01 = c[i0:i1] assert np.all(c01 == [1]) assert isinstance(c01, Column) assert c01.shape == (1,) def test_insert_basic(self, Column): c = Column([0, 1, 2], name='a', dtype=int, unit='mJy', format='%i', description='test column', meta={'c': 8, 'd': 12}) # Basic insert c1 = c.insert(1, 100) assert np.all(c1 == [0, 100, 1, 2]) assert c1.attrs_equal(c) assert type(c) is type(c1) if hasattr(c1, 'mask'): assert c1.data.shape == c1.mask.shape c1 = c.insert(-1, 100) assert np.all(c1 == [0, 1, 100, 2]) c1 = c.insert(3, 100) assert np.all(c1 == [0, 1, 2, 100]) c1 = c.insert(-3, 100) assert np.all(c1 == [100, 0, 1, 2]) c1 = c.insert(1, [100, 200, 300]) if hasattr(c1, 'mask'): assert c1.data.shape == c1.mask.shape # Out of bounds index with pytest.raises((ValueError, IndexError)): c1 = c.insert(-4, 100) with pytest.raises((ValueError, IndexError)): c1 = c.insert(4, 100) def test_insert_axis(self, Column): """Insert with non-default axis kwarg""" c = Column([[1, 2], [3, 4]]) c1 = c.insert(1, [5, 6], axis=None) assert np.all(c1 == [1, 5, 6, 2, 3, 4]) c1 = c.insert(1, [5, 6], axis=1) assert np.all(c1 == [[1, 5, 2], [3, 6, 4]]) def test_insert_string_expand(self, Column): c = Column(['a', 'b']) c1 = c.insert(0, 'abc') assert np.all(c1 == ['abc', 'a', 'b']) c = Column(['a', 'b']) c1 = c.insert(0, ['c', 'def']) assert np.all(c1 == ['c', 'def', 'a', 'b']) def test_insert_string_masked_values(self): c = table.MaskedColumn(['a', 'b']) c1 = c.insert(0, np.ma.masked) assert np.all(c1 == ['', 'a', 'b']) assert np.all(c1.mask == [True, False, False]) assert c1.dtype == 'U1' c2 = c.insert(1, np.ma.MaskedArray(['ccc', 'dd'], mask=[True, False])) assert np.all(c2 == ['a', 'ccc', 'dd', 'b']) assert np.all(c2.mask == [False, True, False, False]) assert c2.dtype == 'U3' def test_insert_string_type_error(self, Column): c = Column([1, 2]) with pytest.raises(ValueError, match='invalid literal for int'): c.insert(0, 'string') c = Column(['a', 'b']) with pytest.raises(TypeError, match='string operation on non-string array'): c.insert(0, 1) def test_insert_multidim(self, Column): c = Column([[1, 2], [3, 4]], name='a', dtype=int) # Basic insert c1 = c.insert(1, [100, 200]) assert np.all(c1 == [[1, 2], [100, 200], [3, 4]]) # Broadcast c1 = c.insert(1, 100) assert np.all(c1 == [[1, 2], [100, 100], [3, 4]]) # Wrong shape with pytest.raises(ValueError): c1 = c.insert(1, [100, 200, 300]) def test_insert_object(self, Column): c = Column(['a', 1, None], name='a', dtype=object) # Basic insert c1 = c.insert(1, [100, 200]) assert np.all(c1 == np.array(['a', [100, 200], 1, None], dtype=object)) def test_insert_masked(self): c = table.MaskedColumn([0, 1, 2], name='a', fill_value=9999, mask=[False, True, False]) # Basic insert c1 = c.insert(1, 100) assert np.all(c1.data.data == [0, 100, 1, 2]) assert c1.fill_value == 9999 assert np.all(c1.data.mask == [False, False, True, False]) assert type(c) is type(c1) for mask in (False, True): c1 = c.insert(1, 100, mask=mask) assert np.all(c1.data.data == [0, 100, 1, 2]) assert np.all(c1.data.mask == [False, mask, True, False]) def test_masked_multidim_as_list(self): data = np.ma.MaskedArray([1, 2], mask=[True, False]) c = table.MaskedColumn([data]) assert c.shape == (1, 2) assert np.all(c[0].mask == [True, False]) def test_insert_masked_multidim(self): c = table.MaskedColumn([[1, 2], [3, 4]], name='a', dtype=int) c1 = c.insert(1, [100, 200], mask=True) assert np.all(c1.data.data == [[1, 2], [100, 200], [3, 4]]) assert np.all(c1.data.mask == [[False, False], [True, True], [False, False]]) c1 = c.insert(1, [100, 200], mask=[True, False]) assert np.all(c1.data.data == [[1, 2], [100, 200], [3, 4]]) assert np.all(c1.data.mask == [[False, False], [True, False], [False, False]]) with pytest.raises(ValueError): c1 = c.insert(1, [100, 200], mask=[True, False, True]) def test_mask_on_non_masked_table(self): """ When table is not masked and trying to set mask on column then it's Raise AttributeError. """ t = table.Table([[1, 2], [3, 4]], names=('a', 'b'), dtype=('i4', 'f8')) with pytest.raises(AttributeError): t['a'].mask = [True, False] class TestAttrEqual(): """Bunch of tests originally from ATpy that test the attrs_equal method.""" def test_5(self, Column): c1 = Column(name='a', dtype=int, unit='mJy') c2 = Column(name='a', dtype=int, unit='mJy') assert c1.attrs_equal(c2) def test_6(self, Column): c1 = Column(name='a', dtype=int, unit='mJy', format='%i', description='test column', meta={'c': 8, 'd': 12}) c2 = Column(name='a', dtype=int, unit='mJy', format='%i', description='test column', meta={'c': 8, 'd': 12}) assert c1.attrs_equal(c2) def test_7(self, Column): c1 = Column(name='a', dtype=int, unit='mJy', format='%i', description='test column', meta={'c': 8, 'd': 12}) c2 = Column(name='b', dtype=int, unit='mJy', format='%i', description='test column', meta={'c': 8, 'd': 12}) assert not c1.attrs_equal(c2) def test_8(self, Column): c1 = Column(name='a', dtype=int, unit='mJy', format='%i', description='test column', meta={'c': 8, 'd': 12}) c2 = Column(name='a', dtype=float, unit='mJy', format='%i', description='test column', meta={'c': 8, 'd': 12}) assert not c1.attrs_equal(c2) def test_9(self, Column): c1 = Column(name='a', dtype=int, unit='mJy', format='%i', description='test column', meta={'c': 8, 'd': 12}) c2 = Column(name='a', dtype=int, unit='erg.cm-2.s-1.Hz-1', format='%i', description='test column', meta={'c': 8, 'd': 12}) assert not c1.attrs_equal(c2) def test_10(self, Column): c1 = Column(name='a', dtype=int, unit='mJy', format='%i', description='test column', meta={'c': 8, 'd': 12}) c2 = Column(name='a', dtype=int, unit='mJy', format='%g', description='test column', meta={'c': 8, 'd': 12}) assert not c1.attrs_equal(c2) def test_11(self, Column): c1 = Column(name='a', dtype=int, unit='mJy', format='%i', description='test column', meta={'c': 8, 'd': 12}) c2 = Column(name='a', dtype=int, unit='mJy', format='%i', description='another test column', meta={'c': 8, 'd': 12}) assert not c1.attrs_equal(c2) def test_12(self, Column): c1 = Column(name='a', dtype=int, unit='mJy', format='%i', description='test column', meta={'c': 8, 'd': 12}) c2 = Column(name='a', dtype=int, unit='mJy', format='%i', description='test column', meta={'e': 8, 'd': 12}) assert not c1.attrs_equal(c2) def test_13(self, Column): c1 = Column(name='a', dtype=int, unit='mJy', format='%i', description='test column', meta={'c': 8, 'd': 12}) c2 = Column(name='a', dtype=int, unit='mJy', format='%i', description='test column', meta={'c': 9, 'd': 12}) assert not c1.attrs_equal(c2) def test_col_and_masked_col(self): c1 = table.Column(name='a', dtype=int, unit='mJy', format='%i', description='test column', meta={'c': 8, 'd': 12}) c2 = table.MaskedColumn(name='a', dtype=int, unit='mJy', format='%i', description='test column', meta={'c': 8, 'd': 12}) assert c1.attrs_equal(c2) assert c2.attrs_equal(c1) # Check that the meta descriptor is working as expected. The MetaBaseTest class # takes care of defining all the tests, and we simply have to define the class # and any minimal set of args to pass. class TestMetaColumn(MetaBaseTest): test_class = table.Column args = () class TestMetaMaskedColumn(MetaBaseTest): test_class = table.MaskedColumn args = () def test_getitem_metadata_regression(): """ Regression test for #1471: MaskedArray does not call __array_finalize__ so the meta-data was not getting copied over. By overloading _update_from we are able to work around this bug. """ # Make sure that meta-data gets propagated with __getitem__ c = table.Column(data=[1, 2], name='a', description='b', unit='m', format="%i", meta={'c': 8}) assert c[1:2].name == 'a' assert c[1:2].description == 'b' assert c[1:2].unit == 'm' assert c[1:2].format == '%i' assert c[1:2].meta['c'] == 8 c = table.MaskedColumn(data=[1, 2], name='a', description='b', unit='m', format="%i", meta={'c': 8}) assert c[1:2].name == 'a' assert c[1:2].description == 'b' assert c[1:2].unit == 'm' assert c[1:2].format == '%i' assert c[1:2].meta['c'] == 8 # As above, but with take() - check the method and the function c = table.Column(data=[1, 2, 3], name='a', description='b', unit='m', format="%i", meta={'c': 8}) for subset in [c.take([0, 1]), np.take(c, [0, 1])]: assert subset.name == 'a' assert subset.description == 'b' assert subset.unit == 'm' assert subset.format == '%i' assert subset.meta['c'] == 8 # Metadata isn't copied for scalar values for subset in [c.take(0), np.take(c, 0)]: assert subset == 1 assert subset.shape == () assert not isinstance(subset, table.Column) c = table.MaskedColumn(data=[1, 2, 3], name='a', description='b', unit='m', format="%i", meta={'c': 8}) for subset in [c.take([0, 1]), np.take(c, [0, 1])]: assert subset.name == 'a' assert subset.description == 'b' assert subset.unit == 'm' assert subset.format == '%i' assert subset.meta['c'] == 8 # Metadata isn't copied for scalar values for subset in [c.take(0), np.take(c, 0)]: assert subset == 1 assert subset.shape == () assert not isinstance(subset, table.MaskedColumn) def test_unicode_guidelines(): arr = np.array([1, 2, 3]) c = table.Column(arr, name='a') assert_follows_unicode_guidelines(c) def test_scalar_column(): """ Column is not designed to hold scalars, but for numpy 1.6 this can happen: >> type(np.std(table.Column([1, 2]))) astropy.table.column.Column """ c = table.Column(1.5) assert repr(c) == '1.5' assert str(c) == '1.5' def test_qtable_column_conversion(): """ Ensures that a QTable that gets assigned a unit switches to be Quantity-y """ qtab = table.QTable([[1, 2], [3, 4.2]], names=['i', 'f']) assert isinstance(qtab['i'], table.column.Column) assert isinstance(qtab['f'], table.column.Column) qtab['i'].unit = 'km/s' assert isinstance(qtab['i'], u.Quantity) assert isinstance(qtab['f'], table.column.Column) # should follow from the above, but good to make sure as a #4497 regression test assert isinstance(qtab['i'][0], u.Quantity) assert isinstance(qtab[0]['i'], u.Quantity) assert not isinstance(qtab['f'][0], u.Quantity) assert not isinstance(qtab[0]['f'], u.Quantity) # Regression test for #5342: if a function unit is assigned, the column # should become the appropriate FunctionQuantity subclass. qtab['f'].unit = u.dex(u.cm / u.s**2) assert isinstance(qtab['f'], u.Dex) @pytest.mark.parametrize('masked', [True, False]) def test_string_truncation_warning(masked): """ Test warnings associated with in-place assignment to a string column that results in truncation of the right hand side. """ from inspect import currentframe, getframeinfo t = table.Table([['aa', 'bb']], names=['a'], masked=masked) t['a'][1] = 'cc' t['a'][:] = 'dd' with pytest.warns(table.StringTruncateWarning, match=r'truncated right side ' r'string\(s\) longer than 2 character\(s\)') as w: frameinfo = getframeinfo(currentframe()) t['a'][0] = 'eee' # replace item with string that gets truncated assert t['a'][0] == 'ee' assert len(w) == 1 # Make sure the warning points back to the user code line assert w[0].lineno == frameinfo.lineno + 1 assert 'test_column' in w[0].filename with pytest.warns(table.StringTruncateWarning, match=r'truncated right side ' r'string\(s\) longer than 2 character\(s\)') as w: t['a'][:] = ['ff', 'ggg'] # replace item with string that gets truncated assert np.all(t['a'] == ['ff', 'gg']) assert len(w) == 1 # Test the obscure case of assigning from an array that was originally # wider than any of the current elements (i.e. dtype is U4 but actual # elements are U1 at the time of assignment). val = np.array(['ffff', 'gggg']) val[:] = ['f', 'g'] t['a'][:] = val assert np.all(t['a'] == ['f', 'g']) def test_string_truncation_warning_masked(): """ Test warnings associated with in-place assignment to a string to a masked column, specifically where the right hand side contains np.ma.masked. """ # Test for strings, but also cover assignment of np.ma.masked to # int and float masked column setting. This was previously only # covered in an unrelated io.ascii test (test_line_endings) which # showed an unexpected difference between handling of str and numeric # masked arrays. for values in (['a', 'b'], [1, 2], [1.0, 2.0]): mc = table.MaskedColumn(values) mc[1] = np.ma.masked assert np.all(mc.mask == [False, True]) mc[:] = np.ma.masked assert np.all(mc.mask == [True, True]) mc = table.MaskedColumn(['aa', 'bb']) with pytest.warns(table.StringTruncateWarning, match=r'truncated right side ' r'string\(s\) longer than 2 character\(s\)') as w: mc[:] = [np.ma.masked, 'ggg'] # replace item with string that gets truncated assert mc[1] == 'gg' assert np.all(mc.mask == [True, False]) assert len(w) == 1 @pytest.mark.parametrize('Column', (table.Column, table.MaskedColumn)) def test_col_unicode_sandwich_create_from_str(Column): """ Create a bytestring Column from strings (including unicode) in Py3. """ # a-umlaut is a 2-byte character in utf-8, test fails with ascii encoding. # Stress the system by injecting non-ASCII characters. uba = 'bä' c = Column([uba, 'def'], dtype='S') assert c.dtype.char == 'S' assert c[0] == uba assert isinstance(c[0], str) assert isinstance(c[:0], table.Column) assert np.all(c[:2] == np.array([uba, 'def'])) @pytest.mark.parametrize('Column', (table.Column, table.MaskedColumn)) def test_col_unicode_sandwich_bytes_obj(Column): """ Create a Column of dtype object with bytestring in it and make sure it keeps the bytestring and not convert to str with accessed. """ c = Column([None, b'def']) assert c.dtype.char == 'O' assert not c[0] assert c[1] == b'def' assert isinstance(c[1], bytes) assert not isinstance(c[1], str) assert isinstance(c[:0], table.Column) assert np.all(c[:2] == np.array([None, b'def'])) assert not np.all(c[:2] == np.array([None, 'def'])) @pytest.mark.parametrize('Column', (table.Column, table.MaskedColumn)) def test_col_unicode_sandwich_bytes(Column): """ Create a bytestring Column from bytes and ensure that it works in Python 3 in a convenient way like in Python 2. """ # a-umlaut is a 2-byte character in utf-8, test fails with ascii encoding. # Stress the system by injecting non-ASCII characters. uba = 'bä' uba8 = uba.encode('utf-8') c = Column([uba8, b'def']) assert c.dtype.char == 'S' assert c[0] == uba assert isinstance(c[0], str) assert isinstance(c[:0], table.Column) assert np.all(c[:2] == np.array([uba, 'def'])) assert isinstance(c[:], table.Column) assert c[:].dtype.char == 'S' # Array / list comparisons assert np.all(c == [uba, 'def']) ok = c == [uba8, b'def'] assert type(ok) is type(c.data) # noqa assert ok.dtype.char == '?' assert np.all(ok) assert np.all(c == np.array([uba, 'def'])) assert np.all(c == np.array([uba8, b'def'])) # Scalar compare cmps = (uba, uba8) for cmp in cmps: ok = c == cmp assert type(ok) is type(c.data) # noqa assert np.all(ok == [True, False]) def test_col_unicode_sandwich_unicode(): """ Sanity check that Unicode Column behaves normally. """ # On Py2 the unicode must be ASCII-compatible, else the final test fails. uba = 'bä' uba8 = uba.encode('utf-8') c = table.Column([uba, 'def'], dtype='U') assert c[0] == uba assert isinstance(c[:0], table.Column) assert isinstance(c[0], str) assert np.all(c[:2] == np.array([uba, 'def'])) assert isinstance(c[:], table.Column) assert c[:].dtype.char == 'U' ok = c == [uba, 'def'] assert type(ok) == np.ndarray assert ok.dtype.char == '?' assert np.all(ok) assert np.all(c != [uba8, b'def']) def test_masked_col_unicode_sandwich(): """ Create a bytestring MaskedColumn and ensure that it works in Python 3 in a convenient way like in Python 2. """ c = table.MaskedColumn([b'abc', b'def']) c[1] = np.ma.masked assert isinstance(c[:0], table.MaskedColumn) assert isinstance(c[0], str) assert c[0] == 'abc' assert c[1] is np.ma.masked assert isinstance(c[:], table.MaskedColumn) assert c[:].dtype.char == 'S' ok = c == ['abc', 'def'] assert ok[0] == True # noqa assert ok[1] is np.ma.masked assert np.all(c == [b'abc', b'def']) assert np.all(c == np.array(['abc', 'def'])) assert np.all(c == np.array([b'abc', b'def'])) for cmp in ('abc', b'abc'): ok = c == cmp assert type(ok) is np.ma.MaskedArray assert ok[0] == True # noqa assert ok[1] is np.ma.masked @pytest.mark.parametrize('Column', (table.Column, table.MaskedColumn)) def test_unicode_sandwich_set(Column): """ Test setting """ uba = 'bä' c = Column([b'abc', b'def']) c[0] = b'aa' assert np.all(c == ['aa', 'def']) c[0] = uba # a-umlaut is a 2-byte character in utf-8, test fails with ascii encoding assert np.all(c == [uba, 'def']) assert c.pformat() == ['None', '----', ' ' + uba, ' def'] c[:] = b'cc' assert np.all(c == ['cc', 'cc']) c[:] = uba assert np.all(c == [uba, uba]) c[:] = '' c[:] = [uba, b'def'] assert np.all(c == [uba, b'def']) @pytest.mark.parametrize('class1', [table.MaskedColumn, table.Column]) @pytest.mark.parametrize('class2', [table.MaskedColumn, table.Column, str, list]) def test_unicode_sandwich_compare(class1, class2): """Test that comparing a bytestring Column/MaskedColumn with various str (unicode) object types gives the expected result. Tests #6838. """ obj1 = class1([b'a', b'c']) if class2 is str: obj2 = 'a' elif class2 is list: obj2 = ['a', 'b'] else: obj2 = class2(['a', 'b']) assert np.all((obj1 == obj2) == [True, False]) assert np.all((obj2 == obj1) == [True, False]) assert np.all((obj1 != obj2) == [False, True]) assert np.all((obj2 != obj1) == [False, True]) assert np.all((obj1 > obj2) == [False, True]) assert np.all((obj2 > obj1) == [False, False]) assert np.all((obj1 <= obj2) == [True, False]) assert np.all((obj2 <= obj1) == [True, True]) assert np.all((obj1 < obj2) == [False, False]) assert np.all((obj2 < obj1) == [False, True]) assert np.all((obj1 >= obj2) == [True, True]) assert np.all((obj2 >= obj1) == [True, False]) def test_unicode_sandwich_masked_compare(): """Test the fix for #6839 from #6899.""" c1 = table.MaskedColumn(['a', 'b', 'c', 'd'], mask=[True, False, True, False]) c2 = table.MaskedColumn([b'a', b'b', b'c', b'd'], mask=[True, True, False, False]) for cmp in ((c1 == c2), (c2 == c1)): assert cmp[0] is np.ma.masked assert cmp[1] is np.ma.masked assert cmp[2] is np.ma.masked assert cmp[3] for cmp in ((c1 != c2), (c2 != c1)): assert cmp[0] is np.ma.masked assert cmp[1] is np.ma.masked assert cmp[2] is np.ma.masked assert not cmp[3] # Note: comparisons <, >, >=, <= fail to return a masked array entirely, # see https://github.com/numpy/numpy/issues/10092. def test_structured_masked_column_roundtrip(): mc = table.MaskedColumn([(1., 2.), (3., 4.)], mask=[(False, False), (False, False)], dtype='f8,f8') assert len(mc.dtype.fields) == 2 mc2 = table.MaskedColumn(mc) assert_array_equal(mc2, mc) @pytest.mark.parametrize('dtype', ['i4,f4', 'f4,(2,)f8']) def test_structured_empty_column_init(dtype): dtype = np.dtype(dtype) c = table.Column(length=5, shape=(2,), dtype=dtype) assert c.shape == (5, 2) assert c.dtype == dtype def test_column_value_access(): """Can a column's underlying data consistently be accessed via `.value`, whether it is a `Column`, `MaskedColumn`, `Quantity`, or `Time`?""" data = np.array([1, 2, 3]) tbl = table.QTable({'a': table.Column(data), 'b': table.MaskedColumn(data), 'c': u.Quantity(data), 'd': time.Time(data, format='mjd')}) assert type(tbl['a'].value) == np.ndarray assert type(tbl['b'].value) == np.ma.MaskedArray assert type(tbl['c'].value) == np.ndarray assert type(tbl['d'].value) == np.ndarray def test_masked_column_serialize_method_propagation(): mc = table.MaskedColumn([1., 2., 3.], mask=[True, False, True]) assert mc.info.serialize_method['ecsv'] == 'null_value' mc.info.serialize_method['ecsv'] = 'data_mask' assert mc.info.serialize_method['ecsv'] == 'data_mask' mc2 = mc.copy() assert mc2.info.serialize_method['ecsv'] == 'data_mask' mc3 = table.MaskedColumn(mc) assert mc3.info.serialize_method['ecsv'] == 'data_mask' mc4 = mc.view(table.MaskedColumn) assert mc4.info.serialize_method['ecsv'] == 'data_mask' mc5 = mc[1:] assert mc5.info.serialize_method['ecsv'] == 'data_mask' ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/tests/test_groups.py0000644000175100001710000005351300000000000021136 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import pytest import numpy as np from astropy.table import Table, Column, QTable, table_helpers, NdarrayMixin, unique from astropy.utils.compat import NUMPY_LT_1_22, NUMPY_LT_1_22_1 from astropy.utils.exceptions import AstropyUserWarning from astropy import time from astropy import units as u from astropy import coordinates def sort_eq(list1, list2): return sorted(list1) == sorted(list2) def test_column_group_by(T1): for masked in (False, True): t1 = Table(T1, masked=masked) t1a = t1['a'].copy() # Group by a Column (i.e. numpy array) t1ag = t1a.group_by(t1['a']) assert np.all(t1ag.groups.indices == np.array([0, 1, 4, 8])) # Group by a Table t1ag = t1a.group_by(t1['a', 'b']) assert np.all(t1ag.groups.indices == np.array([0, 1, 3, 4, 5, 7, 8])) # Group by a numpy structured array t1ag = t1a.group_by(t1['a', 'b'].as_array()) assert np.all(t1ag.groups.indices == np.array([0, 1, 3, 4, 5, 7, 8])) def test_table_group_by(T1): """ Test basic table group_by functionality for possible key types and for masked/unmasked tables. """ for masked in (False, True): t1 = Table(T1, masked=masked) # Group by a single column key specified by name tg = t1.group_by('a') assert np.all(tg.groups.indices == np.array([0, 1, 4, 8])) assert str(tg.groups) == "" assert str(tg['a'].groups) == "" # Sorted by 'a' and in original order for rest assert tg.pformat() == [' a b c d ', '--- --- --- ---', ' 0 a 0.0 4', ' 1 b 3.0 5', ' 1 a 2.0 6', ' 1 a 1.0 7', ' 2 c 7.0 0', ' 2 b 5.0 1', ' 2 b 6.0 2', ' 2 a 4.0 3'] assert tg.meta['ta'] == 1 assert tg['c'].meta['a'] == 1 assert tg['c'].description == 'column c' # Group by a table column tg2 = t1.group_by(t1['a']) assert tg.pformat() == tg2.pformat() # Group by two columns spec'd by name for keys in (['a', 'b'], ('a', 'b')): tg = t1.group_by(keys) assert np.all(tg.groups.indices == np.array([0, 1, 3, 4, 5, 7, 8])) # Sorted by 'a', 'b' and in original order for rest assert tg.pformat() == [' a b c d ', '--- --- --- ---', ' 0 a 0.0 4', ' 1 a 2.0 6', ' 1 a 1.0 7', ' 1 b 3.0 5', ' 2 a 4.0 3', ' 2 b 5.0 1', ' 2 b 6.0 2', ' 2 c 7.0 0'] # Group by a Table tg2 = t1.group_by(t1['a', 'b']) assert tg.pformat() == tg2.pformat() # Group by a structured array tg2 = t1.group_by(t1['a', 'b'].as_array()) assert tg.pformat() == tg2.pformat() # Group by a simple ndarray tg = t1.group_by(np.array([0, 1, 0, 1, 2, 1, 0, 0])) assert np.all(tg.groups.indices == np.array([0, 4, 7, 8])) assert tg.pformat() == [' a b c d ', '--- --- --- ---', ' 2 c 7.0 0', ' 2 b 6.0 2', ' 1 a 2.0 6', ' 1 a 1.0 7', ' 2 b 5.0 1', ' 2 a 4.0 3', ' 1 b 3.0 5', ' 0 a 0.0 4'] def test_groups_keys(T1): tg = T1.group_by('a') keys = tg.groups.keys assert keys.dtype.names == ('a',) assert np.all(keys['a'] == np.array([0, 1, 2])) tg = T1.group_by(['a', 'b']) keys = tg.groups.keys assert keys.dtype.names == ('a', 'b') assert np.all(keys['a'] == np.array([0, 1, 1, 2, 2, 2])) assert np.all(keys['b'] == np.array(['a', 'a', 'b', 'a', 'b', 'c'])) # Grouping by Column ignores column name tg = T1.group_by(T1['b']) keys = tg.groups.keys assert keys.dtype.names is None def test_groups_iterator(T1): tg = T1.group_by('a') for ii, group in enumerate(tg.groups): assert group.pformat() == tg.groups[ii].pformat() assert group['a'][0] == tg['a'][tg.groups.indices[ii]] def test_grouped_copy(T1): """ Test that copying a table or column copies the groups properly """ for masked in (False, True): t1 = Table(T1, masked=masked) tg = t1.group_by('a') tgc = tg.copy() assert np.all(tgc.groups.indices == tg.groups.indices) assert np.all(tgc.groups.keys == tg.groups.keys) tac = tg['a'].copy() assert np.all(tac.groups.indices == tg['a'].groups.indices) c1 = t1['a'].copy() gc1 = c1.group_by(t1['a']) gc1c = gc1.copy() assert np.all(gc1c.groups.indices == np.array([0, 1, 4, 8])) def test_grouped_slicing(T1): """ Test that slicing a table removes previous grouping """ for masked in (False, True): t1 = Table(T1, masked=masked) # Regular slice of a table tg = t1.group_by('a') tg2 = tg[3:5] assert np.all(tg2.groups.indices == np.array([0, len(tg2)])) assert tg2.groups.keys is None def test_group_column_from_table(T1): """ Group a column that is part of a table """ cg = T1['c'].group_by(np.array(T1['a'])) assert np.all(cg.groups.keys == np.array([0, 1, 2])) assert np.all(cg.groups.indices == np.array([0, 1, 4, 8])) def test_table_groups_mask_index(T1): """ Use boolean mask as item in __getitem__ for groups """ for masked in (False, True): t1 = Table(T1, masked=masked).group_by('a') t2 = t1.groups[np.array([True, False, True])] assert len(t2.groups) == 2 assert t2.groups[0].pformat() == t1.groups[0].pformat() assert t2.groups[1].pformat() == t1.groups[2].pformat() assert np.all(t2.groups.keys['a'] == np.array([0, 2])) def test_table_groups_array_index(T1): """ Use numpy array as item in __getitem__ for groups """ for masked in (False, True): t1 = Table(T1, masked=masked).group_by('a') t2 = t1.groups[np.array([0, 2])] assert len(t2.groups) == 2 assert t2.groups[0].pformat() == t1.groups[0].pformat() assert t2.groups[1].pformat() == t1.groups[2].pformat() assert np.all(t2.groups.keys['a'] == np.array([0, 2])) def test_table_groups_slicing(T1): """ Test that slicing table groups works """ for masked in (False, True): t1 = Table(T1, masked=masked).group_by('a') # slice(0, 2) t2 = t1.groups[0:2] assert len(t2.groups) == 2 assert t2.groups[0].pformat() == t1.groups[0].pformat() assert t2.groups[1].pformat() == t1.groups[1].pformat() assert np.all(t2.groups.keys['a'] == np.array([0, 1])) # slice(1, 2) t2 = t1.groups[1:2] assert len(t2.groups) == 1 assert t2.groups[0].pformat() == t1.groups[1].pformat() assert np.all(t2.groups.keys['a'] == np.array([1])) # slice(0, 3, 2) t2 = t1.groups[0:3:2] assert len(t2.groups) == 2 assert t2.groups[0].pformat() == t1.groups[0].pformat() assert t2.groups[1].pformat() == t1.groups[2].pformat() assert np.all(t2.groups.keys['a'] == np.array([0, 2])) def test_grouped_item_access(T1): """ Test that column slicing preserves grouping """ for masked in (False, True): t1 = Table(T1, masked=masked) # Regular slice of a table tg = t1.group_by('a') tgs = tg['a', 'c', 'd'] assert np.all(tgs.groups.keys == tg.groups.keys) assert np.all(tgs.groups.indices == tg.groups.indices) tgsa = tgs.groups.aggregate(np.sum) assert tgsa.pformat() == [' a c d ', '--- ---- ---', ' 0 0.0 4', ' 1 6.0 18', ' 2 22.0 6'] tgs = tg['c', 'd'] assert np.all(tgs.groups.keys == tg.groups.keys) assert np.all(tgs.groups.indices == tg.groups.indices) tgsa = tgs.groups.aggregate(np.sum) assert tgsa.pformat() == [' c d ', '---- ---', ' 0.0 4', ' 6.0 18', '22.0 6'] def test_mutable_operations(T1): """ Operations like adding or deleting a row should removing grouping, but adding or removing or renaming a column should retain grouping. """ for masked in (False, True): t1 = Table(T1, masked=masked) # add row tg = t1.group_by('a') tg.add_row((0, 'a', 3.0, 4)) assert np.all(tg.groups.indices == np.array([0, len(tg)])) assert tg.groups.keys is None # remove row tg = t1.group_by('a') tg.remove_row(4) assert np.all(tg.groups.indices == np.array([0, len(tg)])) assert tg.groups.keys is None # add column tg = t1.group_by('a') indices = tg.groups.indices.copy() tg.add_column(Column(name='e', data=np.arange(len(tg)))) assert np.all(tg.groups.indices == indices) assert np.all(tg['e'].groups.indices == indices) assert np.all(tg['e'].groups.keys == tg.groups.keys) # remove column (not key column) tg = t1.group_by('a') tg.remove_column('b') assert np.all(tg.groups.indices == indices) # Still has original key col names assert tg.groups.keys.dtype.names == ('a',) assert np.all(tg['a'].groups.indices == indices) # remove key column tg = t1.group_by('a') tg.remove_column('a') assert np.all(tg.groups.indices == indices) assert tg.groups.keys.dtype.names == ('a',) assert np.all(tg['b'].groups.indices == indices) # rename key column tg = t1.group_by('a') tg.rename_column('a', 'aa') assert np.all(tg.groups.indices == indices) assert tg.groups.keys.dtype.names == ('a',) assert np.all(tg['aa'].groups.indices == indices) def test_group_by_masked(T1): t1m = Table(T1, masked=True) t1m['c'].mask[4] = True t1m['d'].mask[5] = True assert t1m.group_by('a').pformat() == [' a b c d ', '--- --- --- ---', ' 0 a -- 4', ' 1 b 3.0 --', ' 1 a 2.0 6', ' 1 a 1.0 7', ' 2 c 7.0 0', ' 2 b 5.0 1', ' 2 b 6.0 2', ' 2 a 4.0 3'] def test_group_by_errors(T1): """ Appropriate errors get raised. """ # Bad column name as string with pytest.raises(ValueError): T1.group_by('f') # Bad column names in list with pytest.raises(ValueError): T1.group_by(['f', 'g']) # Wrong length array with pytest.raises(ValueError): T1.group_by(np.array([1, 2])) # Wrong type with pytest.raises(TypeError): T1.group_by(None) # Masked key column t1 = Table(T1, masked=True) t1['a'].mask[4] = True with pytest.raises(ValueError): t1.group_by('a') def test_groups_keys_meta(T1): """ Make sure the keys meta['grouped_by_table_cols'] is working. """ # Group by column in this table tg = T1.group_by('a') assert tg.groups.keys.meta['grouped_by_table_cols'] is True assert tg['c'].groups.keys.meta['grouped_by_table_cols'] is True assert tg.groups[1].groups.keys.meta['grouped_by_table_cols'] is True assert (tg['d'].groups[np.array([False, True, True])] .groups.keys.meta['grouped_by_table_cols'] is True) # Group by external Table tg = T1.group_by(T1['a', 'b']) assert tg.groups.keys.meta['grouped_by_table_cols'] is False assert tg['c'].groups.keys.meta['grouped_by_table_cols'] is False assert tg.groups[1].groups.keys.meta['grouped_by_table_cols'] is False # Group by external numpy array tg = T1.group_by(T1['a', 'b'].as_array()) assert not hasattr(tg.groups.keys, 'meta') assert not hasattr(tg['c'].groups.keys, 'meta') # Group by Column tg = T1.group_by(T1['a']) assert 'grouped_by_table_cols' not in tg.groups.keys.meta assert 'grouped_by_table_cols' not in tg['c'].groups.keys.meta def test_table_aggregate(T1): """ Aggregate a table """ # Table with only summable cols t1 = T1['a', 'c', 'd'] tg = t1.group_by('a') tga = tg.groups.aggregate(np.sum) assert tga.pformat() == [' a c d ', '--- ---- ---', ' 0 0.0 4', ' 1 6.0 18', ' 2 22.0 6'] # Reverts to default groups assert np.all(tga.groups.indices == np.array([0, 3])) assert tga.groups.keys is None # metadata survives assert tga.meta['ta'] == 1 assert tga['c'].meta['a'] == 1 assert tga['c'].description == 'column c' # Aggregate with np.sum with masked elements. This results # in one group with no elements, hence a nan result and conversion # to float for the 'd' column. t1m = Table(t1, masked=True) t1m['c'].mask[4:6] = True t1m['d'].mask[4:6] = True tg = t1m.group_by('a') with pytest.warns(UserWarning, match="converting a masked element to nan"): tga = tg.groups.aggregate(np.sum) assert tga.pformat() == [' a c d ', '--- ---- ----', ' 0 nan nan', ' 1 3.0 13.0', ' 2 22.0 6.0'] # Aggregrate with np.sum with masked elements, but where every # group has at least one remaining (unmasked) element. Then # the int column stays as an int. t1m = Table(t1, masked=True) t1m['c'].mask[5] = True t1m['d'].mask[5] = True tg = t1m.group_by('a') tga = tg.groups.aggregate(np.sum) assert tga.pformat() == [' a c d ', '--- ---- ---', ' 0 0.0 4', ' 1 3.0 13', ' 2 22.0 6'] # Aggregate with a column type that cannot by supplied to the aggregating # function. This raises a warning but still works. tg = T1.group_by('a') with pytest.warns(AstropyUserWarning, match="Cannot aggregate column"): tga = tg.groups.aggregate(np.sum) assert tga.pformat() == [' a c d ', '--- ---- ---', ' 0 0.0 4', ' 1 6.0 18', ' 2 22.0 6'] def test_table_aggregate_reduceat(T1): """ Aggregate table with functions which have a reduceat method """ # Comparison functions without reduceat def np_mean(x): return np.mean(x) def np_sum(x): return np.sum(x) def np_add(x): return np.add(x) # Table with only summable cols t1 = T1['a', 'c', 'd'] tg = t1.group_by('a') # Comparison tga_r = tg.groups.aggregate(np.sum) tga_a = tg.groups.aggregate(np.add) tga_n = tg.groups.aggregate(np_sum) assert np.all(tga_r == tga_n) assert np.all(tga_a == tga_n) assert tga_n.pformat() == [' a c d ', '--- ---- ---', ' 0 0.0 4', ' 1 6.0 18', ' 2 22.0 6'] tga_r = tg.groups.aggregate(np.mean) tga_n = tg.groups.aggregate(np_mean) assert np.all(tga_r == tga_n) assert tga_n.pformat() == [' a c d ', '--- --- ---', ' 0 0.0 4.0', ' 1 2.0 6.0', ' 2 5.5 1.5'] # Binary ufunc np_add should raise warning without reduceat t2 = T1['a', 'c'] tg = t2.group_by('a') with pytest.warns(AstropyUserWarning, match="Cannot aggregate column"): tga = tg.groups.aggregate(np_add) assert tga.pformat() == [' a ', '---', ' 0', ' 1', ' 2'] def test_column_aggregate(T1): """ Aggregate a single table column """ for masked in (False, True): tg = Table(T1, masked=masked).group_by('a') tga = tg['c'].groups.aggregate(np.sum) assert tga.pformat() == [' c ', '----', ' 0.0', ' 6.0', '22.0'] @pytest.mark.skipif(not NUMPY_LT_1_22 and NUMPY_LT_1_22_1, reason='https://github.com/numpy/numpy/issues/20699') def test_column_aggregate_f8(): """https://github.com/astropy/astropy/issues/12706""" # Just want to make sure it does not crash again. for masked in (False, True): tg = Table({'a': np.arange(2, dtype='>f8')}, masked=masked).group_by('a') tga = tg['a'].groups.aggregate(np.sum) assert tga.pformat() == [' a ', '---', '0.0', '1.0'] def test_table_filter(): """ Table groups filtering """ def all_positive(table, key_colnames): colnames = [name for name in table.colnames if name not in key_colnames] for colname in colnames: if np.any(table[colname] < 0): return False return True # Negative value in 'a' column should not filter because it is a key col t = Table.read([' a c d', ' -2 7.0 0', ' -2 5.0 1', ' 0 0.0 4', ' 1 3.0 5', ' 1 2.0 -6', ' 1 1.0 7', ' 3 3.0 5', ' 3 -2.0 6', ' 3 1.0 7', ], format='ascii') tg = t.group_by('a') t2 = tg.groups.filter(all_positive) assert t2.groups[0].pformat() == [' a c d ', '--- --- ---', ' -2 7.0 0', ' -2 5.0 1'] assert t2.groups[1].pformat() == [' a c d ', '--- --- ---', ' 0 0.0 4'] def test_column_filter(): """ Table groups filtering """ def all_positive(column): if np.any(column < 0): return False return True # Negative value in 'a' column should not filter because it is a key col t = Table.read([' a c d', ' -2 7.0 0', ' -2 5.0 1', ' 0 0.0 4', ' 1 3.0 5', ' 1 2.0 -6', ' 1 1.0 7', ' 3 3.0 5', ' 3 -2.0 6', ' 3 1.0 7', ], format='ascii') tg = t.group_by('a') c2 = tg['c'].groups.filter(all_positive) assert len(c2.groups) == 3 assert c2.groups[0].pformat() == [' c ', '---', '7.0', '5.0'] assert c2.groups[1].pformat() == [' c ', '---', '0.0'] assert c2.groups[2].pformat() == [' c ', '---', '3.0', '2.0', '1.0'] def test_group_mixins(): """ Test grouping a table with mixin columns """ # Setup mixins idx = np.arange(4) x = np.array([3., 1., 2., 1.]) q = x * u.m lon = coordinates.Longitude(x * u.deg) lat = coordinates.Latitude(x * u.deg) # For Time do J2000.0 + few * 0.1 ns (this requires > 64 bit precision) tm = time.Time(2000, format='jyear') + time.TimeDelta(x * 1e-10, format='sec') sc = coordinates.SkyCoord(ra=lon, dec=lat) aw = table_helpers.ArrayWrapper(x) nd = np.array([(3, 'c'), (1, 'a'), (2, 'b'), (1, 'a')], dtype='' exp = [table_header_line, 'name mean std min max', '---- ---- --- --- ---', ' a 1.5 0.5 1 2', ' b 1.5 0.5 1 2', ' c -- -- -- --', ' d -- -- 1.0 2.0'] assert out.getvalue().splitlines() == exp # option = ['attributes', 'stats'] tinfo = t.info(['attributes', 'stats'], out=None) assert tinfo.colnames == ['name', 'dtype', 'shape', 'unit', 'format', 'description', 'class', 'mean', 'std', 'min', 'max', 'n_bad', 'length'] assert np.all(tinfo['mean'] == ['1.5', '1.5', '--', '--']) assert np.all(tinfo['std'] == ['0.5', '0.5', '--', '--']) assert np.all(tinfo['min'] == ['1', '1', '--', '1.0']) assert np.all(tinfo['max'] == ['2', '2', '--', '2.0']) out = StringIO() t.info('stats', out=out) exp = [table_header_line, 'name mean std min max', '---- ---- --- --- ---', ' a 1.5 0.5 1 2', ' b 1.5 0.5 1 2', ' c -- -- -- --', ' d -- -- 1.0 2.0'] assert out.getvalue().splitlines() == exp # option = ['attributes', custom] custom = data_info_factory(names=['sum', 'first'], funcs=[np.sum, lambda col: col[0]]) out = StringIO() tinfo = t.info(['attributes', custom], out=None) assert tinfo.colnames == ['name', 'dtype', 'shape', 'unit', 'format', 'description', 'class', 'sum', 'first', 'n_bad', 'length'] assert np.all(tinfo['name'] == ['a', 'b', 'c', 'd']) assert np.all(tinfo['dtype'] == ['int32', 'float32', dtype_info_name('S1'), 'object']) assert np.all(tinfo['sum'] == ['6', '6', '--', '--']) assert np.all(tinfo['first'] == ['1', '1', 'a', '1.0']) def test_data_info(): """ Test getting info for just a column. """ cols = [table.Column([1.0, 2.0, np.nan], name='name', description='description', unit='m/s'), table.MaskedColumn([1.0, 2.0, 3.0], name='name', description='description', unit='m/s', mask=[False, False, True])] for c in cols: # Test getting the full ordered dict cinfo = c.info(out=None) assert cinfo == OrderedDict([('name', 'name'), ('dtype', 'float64'), ('shape', ''), ('unit', 'm / s'), ('format', ''), ('description', 'description'), ('class', type(c).__name__), ('n_bad', 1), ('length', 3)]) # Test the console (string) version which omits trivial values out = StringIO() c.info(out=out) exp = ['name = name', 'dtype = float64', 'unit = m / s', 'description = description', f'class = {type(c).__name__}', 'n_bad = 1', 'length = 3'] assert out.getvalue().splitlines() == exp # repr(c.info) gives the same as c.info() assert repr(c.info) == out.getvalue() # Test stats info cinfo = c.info('stats', out=None) assert cinfo == OrderedDict([('name', 'name'), ('mean', '1.5'), ('std', '0.5'), ('min', '1'), ('max', '2'), ('n_bad', 1), ('length', 3)]) def test_data_info_subclass(): class Column(table.Column): """ Confusingly named Column on purpose, but that is legal. """ pass for data in ([], [1, 2]): c = Column(data, dtype='int64') cinfo = c.info(out=None) assert cinfo == OrderedDict([('dtype', 'int64'), ('shape', ''), ('unit', ''), ('format', ''), ('description', ''), ('class', 'Column'), ('n_bad', 0), ('length', len(data))]) def test_scalar_info(): """ Make sure info works with scalar values """ c = time.Time('2000:001') cinfo = c.info(out=None) assert cinfo['n_bad'] == 0 assert 'length' not in cinfo def test_empty_table(): t = table.Table() out = StringIO() t.info(out=out) exp = ['
', ''] assert out.getvalue().splitlines() == exp def test_class_attribute(): """ Test that class info column is suppressed only for identical non-mixin columns. """ vals = [[1] * u.m, [2] * u.m] texp = ['
', 'name dtype unit', '---- ------- ----', 'col0 float64 m', 'col1 float64 m'] qexp = ['', 'name dtype unit class ', '---- ------- ---- --------', 'col0 float64 m Quantity', 'col1 float64 m Quantity'] for table_cls, exp in ((table.Table, texp), (table.QTable, qexp)): t = table_cls(vals) out = StringIO() t.info(out=out) assert out.getvalue().splitlines() == exp def test_ignore_warnings(): t = table.Table([[np.nan, np.nan]]) with warnings.catch_warnings(record=True) as warns: t.info('stats', out=None) assert len(warns) == 0 def test_no_deprecation_warning(): # regression test for #5459, where numpy deprecation warnings were # emitted unnecessarily. t = simple_table() with warnings.catch_warnings(record=True) as warns: t.info() assert len(warns) == 0 def test_lost_parent_error(): c = table.Column([1, 2, 3], name='a') with pytest.raises(AttributeError) as err: c[:].info.name assert 'failed access "info" attribute' in str(err.value) def test_info_serialize_method(): """ Unit test of context manager to set info.serialize_method. Normally just used to set this for writing a Table to file (FITS, ECSV, HDF5). """ t = table.Table({'tm': time.Time([1, 2], format='cxcsec'), 'sc': coordinates.SkyCoord([1, 2], [1, 2], unit='deg'), 'mc': table.MaskedColumn([1, 2], mask=[True, False]), 'mc2': table.MaskedColumn([1, 2], mask=[True, False])} ) origs = {} for name in ('tm', 'mc', 'mc2'): origs[name] = deepcopy(t[name].info.serialize_method) # Test setting by name and getting back to originals with serialize_method_as(t, {'tm': 'test_tm', 'mc': 'test_mc'}): for name in ('tm', 'mc'): assert all(t[name].info.serialize_method[key] == 'test_' + name for key in t[name].info.serialize_method) assert t['mc2'].info.serialize_method == origs['mc2'] assert not hasattr(t['sc'].info, 'serialize_method') for name in ('tm', 'mc', 'mc2'): assert t[name].info.serialize_method == origs[name] # dict compare assert not hasattr(t['sc'].info, 'serialize_method') # Test setting by name and class, where name takes precedence. Also # test that it works for subclasses. with serialize_method_as(t, {'tm': 'test_tm', 'mc': 'test_mc', table.Column: 'test_mc2'}): for name in ('tm', 'mc', 'mc2'): assert all(t[name].info.serialize_method[key] == 'test_' + name for key in t[name].info.serialize_method) assert not hasattr(t['sc'].info, 'serialize_method') for name in ('tm', 'mc', 'mc2'): assert t[name].info.serialize_method == origs[name] # dict compare assert not hasattr(t['sc'].info, 'serialize_method') # Test supplying a single string that all applies to all columns with # a serialize_method. with serialize_method_as(t, 'test'): for name in ('tm', 'mc', 'mc2'): assert all(t[name].info.serialize_method[key] == 'test' for key in t[name].info.serialize_method) assert not hasattr(t['sc'].info, 'serialize_method') for name in ('tm', 'mc', 'mc2'): assert t[name].info.serialize_method == origs[name] # dict compare assert not hasattr(t['sc'].info, 'serialize_method') def test_info_serialize_method_exception(): """ Unit test of context manager to set info.serialize_method. Normally just used to set this for writing a Table to file (FITS, ECSV, HDF5). """ t = simple_table(masked=True) origs = deepcopy(t['a'].info.serialize_method) try: with serialize_method_as(t, 'test'): assert all(t['a'].info.serialize_method[key] == 'test' for key in t['a'].info.serialize_method) raise ZeroDivisionError() except ZeroDivisionError: pass assert t['a'].info.serialize_method == origs # dict compare ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/tests/test_init_table.py0000644000175100001710000005406000000000000021727 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst from collections import OrderedDict, UserDict from collections.abc import Mapping import pytest import numpy as np from astropy.table import Column, TableColumns, Table, MaskedColumn import astropy.units as u class DictLike(Mapping): """A minimal mapping-like object that does not subclass dict. This is used to test code that expects dict-like but without actually inheriting from dict. """ def __init__(self, *args, **kwargs): self._data = dict(*args, **kwargs) def __getitem__(self, item): return self._data[item] def __setitem__(self, item, value): self._data[item] = value def __iter__(self): return iter(self._data) def __len__(self): return len(self._data) class TestTableColumnsInit(): def test_init(self): """Test initialisation with lists, tuples, dicts of arrays rather than Columns [regression test for #2647]""" x1 = np.arange(10.) x2 = np.arange(5.) x3 = np.arange(7.) col_list = [('x1', x1), ('x2', x2), ('x3', x3)] tc_list = TableColumns(col_list) for col in col_list: assert col[0] in tc_list assert tc_list[col[0]] is col[1] col_tuple = (('x1', x1), ('x2', x2), ('x3', x3)) tc_tuple = TableColumns(col_tuple) for col in col_tuple: assert col[0] in tc_tuple assert tc_tuple[col[0]] is col[1] col_dict = dict([('x1', x1), ('x2', x2), ('x3', x3)]) tc_dict = TableColumns(col_dict) for col in tc_dict.keys(): assert col in tc_dict assert tc_dict[col] is col_dict[col] columns = [Column(col[1], name=col[0]) for col in col_list] tc = TableColumns(columns) for col in columns: assert col.name in tc assert tc[col.name] is col # pytest.mark.usefixtures('table_type') class BaseInitFrom(): def _setup(self, table_type): pass def test_basic_init(self, table_type): self._setup(table_type) t = table_type(self.data, names=('a', 'b', 'c')) assert t.colnames == ['a', 'b', 'c'] assert np.all(t['a'] == np.array([1, 3])) assert np.all(t['b'] == np.array([2, 4])) assert np.all(t['c'] == np.array([3, 5])) assert all(t[name].name == name for name in t.colnames) def test_set_dtype(self, table_type): self._setup(table_type) t = table_type(self.data, names=('a', 'b', 'c'), dtype=('i4', 'f4', 'f8')) assert t.colnames == ['a', 'b', 'c'] assert np.all(t['a'] == np.array([1, 3], dtype='i4')) assert np.all(t['b'] == np.array([2, 4], dtype='f4')) assert np.all(t['c'] == np.array([3, 5], dtype='f8')) assert t['a'].dtype.type == np.int32 assert t['b'].dtype.type == np.float32 assert t['c'].dtype.type == np.float64 assert all(t[name].name == name for name in t.colnames) def test_names_dtype_mismatch(self, table_type): self._setup(table_type) with pytest.raises(ValueError): table_type(self.data, names=('a',), dtype=('i4', 'f4', 'i4')) def test_names_cols_mismatch(self, table_type): self._setup(table_type) with pytest.raises(ValueError): table_type(self.data, names=('a',), dtype=('i4')) @pytest.mark.usefixtures('table_type') class BaseInitFromListLike(BaseInitFrom): def test_names_cols_mismatch(self, table_type): self._setup(table_type) with pytest.raises(ValueError): table_type(self.data, names=['a'], dtype=[int]) def test_names_copy_false(self, table_type): self._setup(table_type) with pytest.raises(ValueError): table_type(self.data, names=['a'], dtype=[int], copy=False) @pytest.mark.usefixtures('table_type') class BaseInitFromDictLike(BaseInitFrom): pass @pytest.mark.usefixtures('table_type') class TestInitFromNdarrayHomo(BaseInitFromListLike): def setup_method(self, method): self.data = np.array([(1, 2, 3), (3, 4, 5)], dtype='i4') def test_default_names(self, table_type): self._setup(table_type) t = table_type(self.data) assert t.colnames == ['col0', 'col1', 'col2'] def test_ndarray_ref(self, table_type): """Init with ndarray and copy=False and show that this is a reference to input ndarray""" self._setup(table_type) t = table_type(self.data, copy=False) t['col1'][1] = 0 assert t.as_array()['col1'][1] == 0 assert t['col1'][1] == 0 assert self.data[1][1] == 0 def test_partial_names_dtype(self, table_type): self._setup(table_type) t = table_type(self.data, names=['a', None, 'c'], dtype=[None, None, 'f8']) assert t.colnames == ['a', 'col1', 'c'] assert t['a'].dtype.type == np.int32 assert t['col1'].dtype.type == np.int32 assert t['c'].dtype.type == np.float64 assert all(t[name].name == name for name in t.colnames) def test_partial_names_ref(self, table_type): self._setup(table_type) t = table_type(self.data, names=['a', None, 'c']) assert t.colnames == ['a', 'col1', 'c'] assert t['a'].dtype.type == np.int32 assert t['col1'].dtype.type == np.int32 assert t['c'].dtype.type == np.int32 assert all(t[name].name == name for name in t.colnames) @pytest.mark.usefixtures('table_type') class TestInitFromListOfLists(BaseInitFromListLike): def setup_method(self, table_type): self._setup(table_type) self.data = [(np.int32(1), np.int32(3)), Column(name='col1', data=[2, 4], dtype=np.int32), np.array([3, 5], dtype=np.int32)] def test_default_names(self, table_type): self._setup(table_type) t = table_type(self.data) assert t.colnames == ['col0', 'col1', 'col2'] assert all(t[name].name == name for name in t.colnames) def test_partial_names_dtype(self, table_type): self._setup(table_type) t = table_type(self.data, names=['b', None, 'c'], dtype=['f4', None, 'f8']) assert t.colnames == ['b', 'col1', 'c'] assert t['b'].dtype.type == np.float32 assert t['col1'].dtype.type == np.int32 assert t['c'].dtype.type == np.float64 assert all(t[name].name == name for name in t.colnames) def test_bad_data(self, table_type): self._setup(table_type) with pytest.raises(ValueError): table_type([[1, 2], [3, 4, 5]]) @pytest.mark.usefixtures('table_type') class TestInitFromListOfDicts(BaseInitFromListLike): def _setup(self, table_type): self.data = [{'a': 1, 'b': 2, 'c': 3}, {'a': 3, 'b': 4, 'c': 5}] self.data_ragged = [{'a': 1, 'b': 2}, {'a': 2, 'c': 4}] def test_names(self, table_type): self._setup(table_type) t = table_type(self.data) assert all(colname in set(['a', 'b', 'c']) for colname in t.colnames) def test_names_ordered(self, table_type): self._setup(table_type) t = table_type(self.data, names=('c', 'b', 'a')) assert t.colnames == ['c', 'b', 'a'] def test_missing_data_init_from_dict(self, table_type): self._setup(table_type) dat = self.data_ragged for rows in [False, True]: t = table_type(rows=dat) if rows else table_type(dat) assert np.all(t['a'] == [1, 2]) assert np.all(t['b'].mask == [False, True]) assert np.all(t['b'].data == [2, 2]) assert np.all(t['c'].mask == [True, False]) assert np.all(t['c'].data == [4, 4]) assert type(t['a']) is (MaskedColumn if t.masked else Column) assert type(t['b']) is MaskedColumn assert type(t['c']) is MaskedColumn class TestInitFromListOfMapping(TestInitFromListOfDicts): """Test that init from a Mapping that is not a dict subclass works""" def _setup(self, table_type): self.data = [DictLike(a=1, b=2, c=3), DictLike(a=3, b=4, c=5)] self.data_ragged = [DictLike(a=1, b=2), DictLike(a=2, c=4)] # Make sure data rows are not a dict subclass assert not isinstance(self.data[0], dict) @pytest.mark.usefixtures('table_type') class TestInitFromColsList(BaseInitFromListLike): def _setup(self, table_type): self.data = [Column([1, 3], name='x', dtype=np.int32), np.array([2, 4], dtype=np.int32), np.array([3, 5], dtype='i8')] def test_default_names(self, table_type): self._setup(table_type) t = table_type(self.data) assert t.colnames == ['x', 'col1', 'col2'] assert all(t[name].name == name for name in t.colnames) def test_partial_names_dtype(self, table_type): self._setup(table_type) t = table_type(self.data, names=['b', None, 'c'], dtype=['f4', None, 'f8']) assert t.colnames == ['b', 'col1', 'c'] assert t['b'].dtype.type == np.float32 assert t['col1'].dtype.type == np.int32 assert t['c'].dtype.type == np.float64 assert all(t[name].name == name for name in t.colnames) def test_ref(self, table_type): """Test that initializing from a list of columns can be done by reference""" self._setup(table_type) t = table_type(self.data, copy=False) t['x'][0] = 100 assert self.data[0][0] == 100 @pytest.mark.usefixtures('table_type') class TestInitFromNdarrayStruct(BaseInitFromDictLike): def _setup(self, table_type): self.data = np.array([(1, 2, 3), (3, 4, 5)], dtype=[('x', 'i8'), ('y', 'i4'), ('z', 'i8')]) def test_ndarray_ref(self, table_type): """Init with ndarray and copy=False and show that table uses reference to input ndarray""" self._setup(table_type) t = table_type(self.data, copy=False) t['x'][1] = 0 # Column-wise assignment t[0]['y'] = 0 # Row-wise assignment assert self.data['x'][1] == 0 assert self.data['y'][0] == 0 assert np.all(np.array(t) == self.data) assert all(t[name].name == name for name in t.colnames) def test_partial_names_dtype(self, table_type): self._setup(table_type) t = table_type(self.data, names=['e', None, 'd'], dtype=['f4', None, 'f8']) assert t.colnames == ['e', 'y', 'd'] assert t['e'].dtype.type == np.float32 assert t['y'].dtype.type == np.int32 assert t['d'].dtype.type == np.float64 assert all(t[name].name == name for name in t.colnames) def test_partial_names_ref(self, table_type): self._setup(table_type) t = table_type(self.data, names=['e', None, 'd'], copy=False) assert t.colnames == ['e', 'y', 'd'] assert t['e'].dtype.type == np.int64 assert t['y'].dtype.type == np.int32 assert t['d'].dtype.type == np.int64 assert all(t[name].name == name for name in t.colnames) @pytest.mark.usefixtures('table_type') class TestInitFromDict(BaseInitFromDictLike): def _setup(self, table_type): self.data = dict([('a', Column([1, 3], name='x')), ('b', [2, 4]), ('c', np.array([3, 5], dtype='i8'))]) @pytest.mark.usefixtures('table_type') class TestInitFromMapping(BaseInitFromDictLike): def _setup(self, table_type): self.data = UserDict([('a', Column([1, 3], name='x')), ('b', [2, 4]), ('c', np.array([3, 5], dtype='i8'))]) assert isinstance(self.data, Mapping) assert not isinstance(self.data, dict) @pytest.mark.usefixtures('table_type') class TestInitFromOrderedDict(BaseInitFromDictLike): def _setup(self, table_type): self.data = OrderedDict([('a', Column(name='x', data=[1, 3])), ('b', [2, 4]), ('c', np.array([3, 5], dtype='i8'))]) def test_col_order(self, table_type): self._setup(table_type) t = table_type(self.data) assert t.colnames == ['a', 'b', 'c'] @pytest.mark.usefixtures('table_type') class TestInitFromRow(BaseInitFromDictLike): def _setup(self, table_type): arr = np.array([(1, 2, 3), (3, 4, 5)], dtype=[('x', 'i8'), ('y', 'i8'), ('z', 'f8')]) self.data = table_type(arr, meta={'comments': ['comment1', 'comment2']}) def test_init_from_row(self, table_type): self._setup(table_type) t = table_type(self.data[0]) # Values and meta match original assert t.meta['comments'][0] == 'comment1' for name in t.colnames: assert np.all(t[name] == self.data[name][0:1]) assert all(t[name].name == name for name in t.colnames) # Change value in new instance and check that original is the same t['x'][0] = 8 t.meta['comments'][1] = 'new comment2' assert np.all(t['x'] == np.array([8])) assert np.all(self.data['x'] == np.array([1, 3])) assert self.data.meta['comments'][1] == 'comment2' @pytest.mark.usefixtures('table_type') class TestInitFromTable(BaseInitFromDictLike): def _setup(self, table_type): arr = np.array([(1, 2, 3), (3, 4, 5)], dtype=[('x', 'i8'), ('y', 'i8'), ('z', 'f8')]) self.data = table_type(arr, meta={'comments': ['comment1', 'comment2']}) def test_data_meta_copy(self, table_type): self._setup(table_type) t = table_type(self.data) assert t.meta['comments'][0] == 'comment1' t['x'][1] = 8 t.meta['comments'][1] = 'new comment2' assert self.data.meta['comments'][1] == 'comment2' assert np.all(t['x'] == np.array([1, 8])) assert np.all(self.data['x'] == np.array([1, 3])) assert t['z'].name == 'z' assert all(t[name].name == name for name in t.colnames) def test_table_ref(self, table_type): self._setup(table_type) t = table_type(self.data, copy=False) t['x'][1] = 0 assert t['x'][1] == 0 assert self.data['x'][1] == 0 assert np.all(t.as_array() == self.data.as_array()) assert all(t[name].name == name for name in t.colnames) def test_partial_names_dtype(self, table_type): self._setup(table_type) t = table_type(self.data, names=['e', None, 'd'], dtype=['f4', None, 'i8']) assert t.colnames == ['e', 'y', 'd'] assert t['e'].dtype.type == np.float32 assert t['y'].dtype.type == np.int64 assert t['d'].dtype.type == np.int64 assert all(t[name].name == name for name in t.colnames) def test_partial_names_ref(self, table_type): self._setup(table_type) t = table_type(self.data, names=['e', None, 'd'], copy=False) assert t.colnames == ['e', 'y', 'd'] assert t['e'].dtype.type == np.int64 assert t['y'].dtype.type == np.int64 assert t['d'].dtype.type == np.float64 assert all(t[name].name == name for name in t.colnames) def test_init_from_columns(self, table_type): self._setup(table_type) t = table_type(self.data) t2 = table_type(t.columns['z', 'x', 'y']) assert t2.colnames == ['z', 'x', 'y'] assert t2.dtype.names == ('z', 'x', 'y') def test_init_from_columns_slice(self, table_type): self._setup(table_type) t = table_type(self.data) t2 = table_type(t.columns[0:2]) assert t2.colnames == ['x', 'y'] assert t2.dtype.names == ('x', 'y') def test_init_from_columns_mix(self, table_type): self._setup(table_type) t = table_type(self.data) t2 = table_type([t.columns[0], t.columns['z']]) assert t2.colnames == ['x', 'z'] assert t2.dtype.names == ('x', 'z') @pytest.mark.usefixtures('table_type') class TestInitFromNone(): # Note table_table.TestEmptyData tests initializing a completely empty # table and adding data. def test_data_none_with_cols(self, table_type): """ Test different ways of initing an empty table """ np_t = np.empty(0, dtype=[('a', 'f4', (2,)), ('b', 'i4')]) for kwargs in ({'names': ('a', 'b')}, {'names': ('a', 'b'), 'dtype': (('f4', (2,)), 'i4')}, {'dtype': [('a', 'f4', (2,)), ('b', 'i4')]}, {'dtype': np_t.dtype}): t = table_type(**kwargs) assert t.colnames == ['a', 'b'] assert len(t['a']) == 0 assert len(t['b']) == 0 if 'dtype' in kwargs: assert t['a'].dtype.type == np.float32 assert t['b'].dtype.type == np.int32 assert t['a'].shape[1:] == (2,) @pytest.mark.usefixtures('table_types') class TestInitFromRows(): def test_init_with_rows(self, table_type): for rows in ([[1, 'a'], [2, 'b']], [(1, 'a'), (2, 'b')], ((1, 'a'), (2, 'b'))): t = table_type(rows=rows, names=('a', 'b')) assert np.all(t['a'] == [1, 2]) assert np.all(t['b'] == ['a', 'b']) assert t.colnames == ['a', 'b'] assert t['a'].dtype.kind == 'i' assert t['b'].dtype.kind in ('S', 'U') # Regression test for # https://github.com/astropy/astropy/issues/3052 assert t['b'].dtype.str.endswith('1') rows = np.arange(6).reshape(2, 3) t = table_type(rows=rows, names=('a', 'b', 'c'), dtype=['f8', 'f4', 'i8']) assert np.all(t['a'] == [0, 3]) assert np.all(t['b'] == [1, 4]) assert np.all(t['c'] == [2, 5]) assert t.colnames == ['a', 'b', 'c'] assert t['a'].dtype.str.endswith('f8') assert t['b'].dtype.str.endswith('f4') assert t['c'].dtype.str.endswith('i8') def test_init_with_rows_and_data(self, table_type): with pytest.raises(ValueError) as err: table_type(data=[[1]], rows=[[1]]) assert "Cannot supply both `data` and `rows` values" in str(err.value) @pytest.mark.parametrize('has_data', [True, False]) def test_init_table_with_names_and_structured_dtype(has_data): """Test fix for #10393""" arr = np.ones(2, dtype=np.dtype([('a', 'i4'), ('b', 'f4')])) data_args = [arr] if has_data else [] t = Table(*data_args, names=['x', 'y'], dtype=arr.dtype) assert t.colnames == ['x', 'y'] assert str(t['x'].dtype) == 'int32' assert str(t['y'].dtype) == 'float32' assert len(t) == (2 if has_data else 0) @pytest.mark.usefixtures('table_type') def test_init_and_ref_from_multidim_ndarray(table_type): """ Test that initializing from an ndarray structured array with a multi-dim column works for both copy=False and True and that the referencing is as expected. """ for copy in (False, True): nd = np.array([(1, [10, 20]), (3, [30, 40])], dtype=[('a', 'i8'), ('b', 'i8', (2,))]) t = table_type(nd, copy=copy) assert t.colnames == ['a', 'b'] assert t['a'].shape == (2,) assert t['b'].shape == (2, 2) t['a'][0] = -200 t['b'][1][1] = -100 if copy: assert nd['a'][0] == 1 assert nd['b'][1][1] == 40 else: assert nd['a'][0] == -200 assert nd['b'][1][1] == -100 @pytest.mark.usefixtures('table_type') @pytest.mark.parametrize('copy', [False, True]) def test_init_and_ref_from_dict(table_type, copy): """ Test that initializing from a dict works for both copy=False and True and that the referencing is as expected. """ x1 = np.arange(10.) x2 = np.zeros(10) col_dict = dict([('x1', x1), ('x2', x2)]) t = table_type(col_dict, copy=copy) assert set(t.colnames) == set(['x1', 'x2']) assert t['x1'].shape == (10,) assert t['x2'].shape == (10,) t['x1'][0] = -200 t['x2'][1] = -100 if copy: assert x1[0] == 0. assert x2[1] == 0. else: assert x1[0] == -200 assert x2[1] == -100 def test_add_none_object_column(): """Test fix for a problem introduced in #10636 (see https://github.com/astropy/astropy/pull/10636#issuecomment-676847515) """ t = Table(data={'a': [1, 2, 3]}) t['b'] = None assert all(val is None for val in t['b']) assert t['b'].dtype.kind == 'O' @pytest.mark.usefixtures('table_type') def test_init_from_row_OrderedDict(table_type): row1 = OrderedDict([('b', 1), ('a', 0)]) row2 = {'a': 10, 'b': 20} rows12 = [row1, row2] row3 = dict([('b', 1), ('a', 0)]) row4 = dict([('b', 11), ('a', 10)]) rows34 = [row3, row4] t1 = table_type(rows=rows12) t2 = table_type(rows=rows34) t3 = t2[sorted(t2.colnames)] assert t1.colnames == ['b', 'a'] assert t2.colnames == ['b', 'a'] assert t3.colnames == ['a', 'b'] def test_init_from_rows_as_generator(): rows = ((1 + ii, 2 + ii) for ii in range(2)) t = Table(rows=rows) assert np.all(t['col0'] == [1, 2]) assert np.all(t['col1'] == [2, 3]) @pytest.mark.parametrize('dtype', ['fail', 'i4']) def test_init_bad_dtype_in_empty_table(dtype): with pytest.raises(ValueError, match='type was specified but could not be parsed for column names'): Table(dtype=dtype) def test_init_data_type_not_allowed_to_init_table(): with pytest.raises(ValueError, match="Data type not allowed to init Table"): Table('hello') def test_init_Table_from_list_of_quantity(): """Test fix for #11327""" # Variation on original example in #11327 at the Table level data = [{'x': 5 * u.m, 'y': 1 * u.m}, {'x': 10 * u.m, 'y': 3}] t = Table(data) assert t['x'].unit is u.m assert t['y'].unit is None assert t['x'].dtype.kind == 'f' assert t['y'].dtype.kind == 'O' assert np.all(t['x'] == [5, 10]) assert t['y'][0] == 1 * u.m assert t['y'][1] == 3 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/tests/test_item_access.py0000644000175100001710000002206200000000000022071 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ Verify item access API in: https://github.com/astropy/astropy/wiki/Table-item-access-definition """ import pytest import numpy as np @pytest.mark.usefixtures('table_data') class BaseTestItems(): pass @pytest.mark.usefixtures('table_data') class TestTableColumnsItems(BaseTestItems): def test_by_name(self, table_data): """Access TableColumns by name and show that item access returns a Column that refers to underlying table data""" self.t = table_data.Table(table_data.COLS) self.tc = self.t.columns assert self.tc['a'].name == 'a' assert self.tc['a'][1] == 2 assert self.tc['a'].description == 'da' assert self.tc['a'].format == '%i' assert self.tc['a'].meta == {'ma': 1} assert self.tc['a'].unit == 'ua' assert self.tc['a'].attrs_equal(table_data.COLS[0]) assert isinstance(self.tc['a'], table_data.Column) self.tc['b'][1] = 0 assert self.t['b'][1] == 0 def test_by_position(self, table_data): """Access TableColumns by position and show that item access returns a Column that refers to underlying table data""" self.t = table_data.Table(table_data.COLS) self.tc = self.t.columns assert self.tc[1].name == 'b' assert np.all(self.tc[1].data == table_data.COLS[1].data) assert self.tc[1].description == 'db' assert self.tc[1].format == '%d' assert self.tc[1].meta == {'mb': 1} assert self.tc[1].unit == 'ub' assert self.tc[1].attrs_equal(table_data.COLS[1]) assert isinstance(self.tc[1], table_data.Column) assert self.tc[2].unit == 'ub' self.tc[1][1] = 0 assert self.t['b'][1] == 0 def test_mult_columns(self, table_data): """Access TableColumns with "fancy indexing" and showed that returned TableColumns object still references original data""" self.t = table_data.Table(table_data.COLS) self.tc = self.t.columns tc2 = self.tc['b', 'c'] assert tc2[1].name == 'c' assert tc2[1][1] == 8 assert tc2[0].name == 'b' assert tc2[0][1] == 5 tc2['c'][1] = 0 assert self.tc['c'][1] == 0 assert self.t['c'][1] == 0 def test_column_slice(self, table_data): """Access TableColumns with slice and showed that returned TableColumns object still references original data""" self.t = table_data.Table(table_data.COLS) self.tc = self.t.columns tc2 = self.tc[1:3] assert tc2[1].name == 'c' assert tc2[1][1] == 8 assert tc2[0].name == 'b' assert tc2[0][1] == 5 tc2['c'][1] = 0 assert self.tc['c'][1] == 0 assert self.t['c'][1] == 0 @pytest.mark.usefixtures('table_data') class TestTableItems(BaseTestItems): @pytest.mark.parametrize("idx", [1, np.int64(1), np.array(1)]) def test_column(self, table_data, idx): """Column access returns REFERENCE to data""" self.t = table_data.Table(table_data.COLS) self.tc = self.t.columns a = self.t['a'] assert a[idx] == 2 a[idx] = 0 assert self.t['a'][idx] == 0 @pytest.mark.parametrize("idx", [1, np.int64(1), np.array(1)]) def test_row(self, table_data, idx): """Row access returns REFERENCE to data""" self.t = table_data.Table(table_data.COLS) self.tc = self.t.columns row = self.t[idx] assert row['a'] == 2 assert row[idx] == 5 assert row.columns['a'].attrs_equal(table_data.COLS[0]) assert row.columns['b'].attrs_equal(table_data.COLS[1]) assert row.columns['c'].attrs_equal(table_data.COLS[2]) # Check that setting by col index sets the table and row value row[idx] = 0 assert row[idx] == 0 assert row['b'] == 0 assert self.t['b'][idx] == 0 assert self.t[idx]['b'] == 0 # Check that setting by col name sets the table and row value row['a'] = 0 assert row[0] == 0 assert row['a'] == 0 assert self.t['a'][1] == 0 assert self.t[1]['a'] == 0 def test_empty_iterable_item(self, table_data): """ Table item access with [], (), or np.array([]) returns the same table with no rows. """ self.t = table_data.Table(table_data.COLS) for item in [], (), np.array([]): t2 = self.t[item] assert not t2 assert len(t2) == 0 assert t2['a'].attrs_equal(table_data.COLS[0]) assert t2['b'].attrs_equal(table_data.COLS[1]) assert t2['c'].attrs_equal(table_data.COLS[2]) def test_table_slice(self, table_data): """Table slice returns REFERENCE to data""" self.t = table_data.Table(table_data.COLS) self.tc = self.t.columns t2 = self.t[1:3] assert np.all(t2['a'] == table_data.DATA['a'][1:3]) assert t2['a'].attrs_equal(table_data.COLS[0]) assert t2['b'].attrs_equal(table_data.COLS[1]) assert t2['c'].attrs_equal(table_data.COLS[2]) t2['a'][0] = 0 assert np.all(self.t['a'] == np.array([1, 0, 3])) assert t2.masked == self.t.masked assert t2._column_class == self.t._column_class assert isinstance(t2, table_data.Table) def test_fancy_index_slice(self, table_data): """Table fancy slice returns COPY of data""" self.t = table_data.Table(table_data.COLS) self.tc = self.t.columns slice = np.array([0, 2]) t2 = self.t[slice] assert np.all(t2['a'] == table_data.DATA['a'][slice]) assert t2['a'].attrs_equal(table_data.COLS[0]) assert t2['b'].attrs_equal(table_data.COLS[1]) assert t2['c'].attrs_equal(table_data.COLS[2]) t2['a'][0] = 0 assert np.all(self.t.as_array() == table_data.DATA) assert np.any(t2['a'] != table_data.DATA['a'][slice]) assert t2.masked == self.t.masked assert t2._column_class == self.t._column_class assert isinstance(t2, table_data.Table) def test_list_index_slice(self, table_data): """Table list index slice returns COPY of data""" self.t = table_data.Table(table_data.COLS) self.tc = self.t.columns slice = [0, 2] t2 = self.t[slice] assert np.all(t2['a'] == table_data.DATA['a'][slice]) assert t2['a'].attrs_equal(table_data.COLS[0]) assert t2['b'].attrs_equal(table_data.COLS[1]) assert t2['c'].attrs_equal(table_data.COLS[2]) t2['a'][0] = 0 assert np.all(self.t.as_array() == table_data.DATA) assert np.any(t2['a'] != table_data.DATA['a'][slice]) assert t2.masked == self.t.masked assert t2._column_class == self.t._column_class assert isinstance(t2, table_data.Table) def test_select_columns(self, table_data): """Select columns returns COPY of data and all column attributes""" self.t = table_data.Table(table_data.COLS) self.tc = self.t.columns # try both lists and tuples for columns in (('a', 'c'), ['a', 'c']): t2 = self.t[columns] assert np.all(t2['a'] == table_data.DATA['a']) assert np.all(t2['c'] == table_data.DATA['c']) assert t2['a'].attrs_equal(table_data.COLS[0]) assert t2['c'].attrs_equal(table_data.COLS[2]) t2['a'][0] = 0 assert np.all(self.t.as_array() == table_data.DATA) assert np.any(t2['a'] != table_data.DATA['a']) assert t2.masked == self.t.masked assert t2._column_class == self.t._column_class def test_select_columns_fail(self, table_data): """Selecting a column that doesn't exist fails""" self.t = table_data.Table(table_data.COLS) with pytest.raises(KeyError) as err: self.t[['xxxx']] assert "'xxxx'" in str(err.value) with pytest.raises(KeyError) as err: self.t[['xxxx', 'yyyy']] assert "'xxxx'" in str(err.value) def test_np_where(self, table_data): """Select rows using output of np.where""" t = table_data.Table(table_data.COLS) # Select last two rows rows = np.where(t['a'] > 1.5) t2 = t[rows] assert np.all(t2['a'] == [2, 3]) assert np.all(t2['b'] == [5, 6]) assert isinstance(t2, table_data.Table) # Select no rows rows = np.where(t['a'] > 100) t2 = t[rows] assert len(t2) == 0 assert isinstance(t2, table_data.Table) def test_np_integers(self, table_data): """ Select rows using numpy integers. This is a regression test for a py 3.3 failure mode """ t = table_data.Table(table_data.COLS) idxs = np.random.randint(len(t), size=2) t[idxs[1]] def test_select_bad_column(self, table_data): """Select column name that does not exist""" self.t = table_data.Table(table_data.COLS) self.tc = self.t.columns with pytest.raises(ValueError): self.t['a', 1] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/tests/test_jsviewer.py0000644000175100001710000001612200000000000021450 0ustar00vstsdockerfrom os.path import abspath, dirname, join import textwrap import pytest from astropy.coordinates import SkyCoord from astropy.time import Time from astropy.table.table import Table from astropy import extern from astropy.utils.compat.optional_deps import HAS_BLEACH, HAS_IPYTHON # noqa from astropy.utils.misc import _NOT_OVERWRITING_MSG_MATCH EXTERN_DIR = abspath(join(dirname(extern.__file__), 'jquery', 'data')) REFERENCE = """
%(lines)s
a b
""" TPL = (' \n' ' {0}\n' ' {1}\n' ' ') def format_lines(col1, col2): col1_format = getattr(col1.info, 'default_format', lambda x: x) col2_format = getattr(col2.info, 'default_format', lambda x: x) return '\n'.join(TPL.format(col1_format(v1), col2_format(v2)) for v1, v2 in zip(col1, col2)) def test_write_jsviewer_default(tmpdir): t = Table() t['a'] = [1, 2, 3, 4, 5] t['b'] = ['a', 'b', 'c', 'd', 'e'] t['a'].unit = 'm' tmpfile = tmpdir.join('test.html').strpath t.write(tmpfile, format='jsviewer') ref = REFERENCE % dict( lines=format_lines(t['a'], t['b']), table_class='display compact', table_id=f'table{id(t)}', length='50', display_length='10, 25, 50, 100, 500, 1000', datatables_css_url='https://cdn.datatables.net/1.10.12/css/jquery.dataTables.css', datatables_js_url='https://cdn.datatables.net/1.10.12/js/jquery.dataTables.min.js', jquery_url='https://code.jquery.com/jquery-3.1.1.min.js' ) with open(tmpfile) as f: assert f.read().strip() == ref.strip() def test_write_jsviewer_overwrite(tmpdir): t = Table() t['a'] = [1, 2, 3, 4, 5] t['b'] = ['a', 'b', 'c', 'd', 'e'] t['a'].unit = 'm' tmpfile = tmpdir.join('test.html').strpath # normal write t.write(tmpfile, format='jsviewer') # errors on overwrite with pytest.raises(OSError, match=_NOT_OVERWRITING_MSG_MATCH): t.write(tmpfile, format='jsviewer') # unless specified t.write(tmpfile, format='jsviewer', overwrite=True) @pytest.mark.parametrize('mixin', [ Time(['J2000', 'J2001']), Time([50000., 50001.0001], format='mjd'), SkyCoord(ra=[100., 110.], dec=[-10., 10.], unit='deg')]) def test_write_jsviewer_mixin(tmpdir, mixin): t = Table() t['a'] = [1, 2] t['b'] = mixin t['a'].unit = 'm' tmpfile = tmpdir.join('test.html').strpath t.write(tmpfile, format='jsviewer') ref = REFERENCE % dict( lines=format_lines(t['a'], t['b']), table_class='display compact', table_id=f'table{id(t)}', length='50', display_length='10, 25, 50, 100, 500, 1000', datatables_css_url='https://cdn.datatables.net/1.10.12/css/jquery.dataTables.css', datatables_js_url='https://cdn.datatables.net/1.10.12/js/jquery.dataTables.min.js', jquery_url='https://code.jquery.com/jquery-3.1.1.min.js' ) with open(tmpfile) as f: assert f.read().strip() == ref.strip() @pytest.mark.skipif('not HAS_BLEACH') def test_write_jsviewer_options(tmpdir): t = Table() t['a'] = [1, 2, 3, 4, 5] t['b'] = ['a', 'b', 'c', 'd', 'e'] t['a'].unit = 'm' tmpfile = tmpdir.join('test.html').strpath t.write(tmpfile, format='jsviewer', table_id='test', max_lines=3, jskwargs={'display_length': 5}, table_class='display hover', htmldict=dict(raw_html_cols='b')) ref = REFERENCE % dict( lines=format_lines(t['a'][:3], t['b'][:3]), table_class='display hover', table_id='test', length='5', display_length='5, 10, 25, 50, 100, 500, 1000', datatables_css_url='https://cdn.datatables.net/1.10.12/css/jquery.dataTables.css', datatables_js_url='https://cdn.datatables.net/1.10.12/js/jquery.dataTables.min.js', jquery_url='https://code.jquery.com/jquery-3.1.1.min.js' ) with open(tmpfile) as f: assert f.read().strip() == ref.strip() def test_write_jsviewer_local(tmpdir): t = Table() t['a'] = [1, 2, 3, 4, 5] t['b'] = ['a', 'b', 'c', 'd', 'e'] t['a'].unit = 'm' tmpfile = tmpdir.join('test.html').strpath t.write(tmpfile, format='jsviewer', table_id='test', jskwargs={'use_local_files': True}) ref = REFERENCE % dict( lines=format_lines(t['a'], t['b']), table_class='display compact', table_id='test', length='50', display_length='10, 25, 50, 100, 500, 1000', datatables_css_url='file://' + join(EXTERN_DIR, 'css', 'jquery.dataTables.css'), datatables_js_url='file://' + join(EXTERN_DIR, 'js', 'jquery.dataTables.min.js'), jquery_url='file://' + join(EXTERN_DIR, 'js', 'jquery-3.1.1.min.js') ) with open(tmpfile) as f: assert f.read().strip() == ref.strip() @pytest.mark.skipif('not HAS_IPYTHON') def test_show_in_notebook(): t = Table() t['a'] = [1, 2, 3, 4, 5] t['b'] = ['b', 'c', 'a', 'd', 'e'] htmlstr_windx = t.show_in_notebook().data # should default to 'idx' htmlstr_windx_named = t.show_in_notebook(show_row_index='realidx').data htmlstr_woindx = t.show_in_notebook(show_row_index=False).data assert (textwrap.dedent(""" idxab 01b 12c 23a 34d 45e """).strip() in htmlstr_windx) assert 'realidxab' in htmlstr_windx_named assert 'ab' in htmlstr_woindx ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/tests/test_masked.py0000644000175100001710000006143200000000000021062 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """Test behavior related to masked tables""" import pytest import numpy as np import numpy.ma as ma from astropy.table import Column, MaskedColumn, Table, QTable from astropy.table.column import BaseColumn from astropy.time import Time from astropy.utils.masked import Masked import astropy.units as u class SetupData: def setup_method(self, method): self.a = MaskedColumn(name='a', data=[1, 2, 3], fill_value=1) self.b = MaskedColumn(name='b', data=[4, 5, 6], mask=True) self.c = MaskedColumn(name='c', data=[7, 8, 9], mask=False) self.d_mask = np.array([False, True, False]) self.d = MaskedColumn(name='d', data=[7, 8, 7], mask=self.d_mask) self.t = Table([self.a, self.b], masked=True) self.ca = Column(name='ca', data=[1, 2, 3]) self.sc = MaskedColumn(name='sc', data=[(1, 1.), (2, 2.), (3, 3.)], dtype='i8,f8', fill_value=(0, -1.)) class TestPprint(SetupData): def test_pformat(self): assert self.t.pformat() == [' a b ', '--- ---', ' 1 --', ' 2 --', ' 3 --'] class TestFilled: """Test the filled method in MaskedColumn and Table""" def setup_method(self, method): mask = [True, False, False] self.meta = {'a': 1, 'b': [2, 3]} self.a = MaskedColumn(name='a', data=[1, 2, 3], fill_value=10, mask=mask, meta={'a': 1}) self.b = MaskedColumn(name='b', data=[4.0, 5.0, 6.0], fill_value=10.0, mask=mask) self.c = MaskedColumn(name='c', data=['7', '8', '9'], fill_value='1', mask=mask) def test_filled_column(self): f = self.a.filled() assert np.all(f == [10, 2, 3]) assert isinstance(f, Column) assert not isinstance(f, MaskedColumn) # Confirm copy, not ref assert f.meta['a'] == 1 f.meta['a'] = 2 f[1] = 100 assert self.a[1] == 2 assert self.a.meta['a'] == 1 # Fill with arg fill_value not column fill_value f = self.a.filled(20) assert np.all(f == [20, 2, 3]) f = self.b.filled() assert np.all(f == [10.0, 5.0, 6.0]) assert isinstance(f, Column) f = self.c.filled() assert np.all(f == ['1', '8', '9']) assert isinstance(f, Column) def test_filled_masked_table(self, tableclass): t = tableclass([self.a, self.b, self.c], meta=self.meta) f = t.filled() assert isinstance(f, Table) assert f.masked is False assert np.all(f['a'] == [10, 2, 3]) assert np.allclose(f['b'], [10.0, 5.0, 6.0]) assert np.all(f['c'] == ['1', '8', '9']) # Confirm copy, not ref assert f.meta['b'] == [2, 3] f.meta['b'][0] = 20 assert t.meta['b'] == [2, 3] f['a'][2] = 100 assert t['a'][2] == 3 def test_filled_unmasked_table(self, tableclass): t = tableclass([(1, 2), ('3', '4')], names=('a', 'b'), meta=self.meta) f = t.filled() assert isinstance(f, Table) assert f.masked is False assert np.all(f['a'] == t['a']) assert np.all(f['b'] == t['b']) # Confirm copy, not ref assert f.meta['b'] == [2, 3] f.meta['b'][0] = 20 assert t.meta['b'] == [2, 3] f['a'][1] = 100 assert t['a'][1] == 2 class TestFillValue(SetupData): """Test setting and getting fill value in MaskedColumn and Table""" def test_init_set_fill_value(self): """Check that setting fill_value in the MaskedColumn init works""" assert self.a.fill_value == 1 c = MaskedColumn(name='c', data=['xxxx', 'yyyy'], fill_value='none') assert c.fill_value == 'none' def test_set_get_fill_value_for_bare_column(self): """Check set and get of fill value works for bare Column""" self.d.fill_value = -999 assert self.d.fill_value == -999 assert np.all(self.d.filled() == [7, -999, 7]) def test_set_get_fill_value_for_str_column(self): c = MaskedColumn(name='c', data=['xxxx', 'yyyy'], mask=[True, False]) # assert np.all(c.filled() == ['N/A', 'yyyy']) c.fill_value = 'ABCDEF' assert c.fill_value == 'ABCD' # string truncated to dtype length assert np.all(c.filled() == ['ABCD', 'yyyy']) assert np.all(c.filled('XY') == ['XY', 'yyyy']) def test_set_get_fill_value_for_structured_column(self): assert self.sc.fill_value == np.array((0, -1.), self.sc.dtype) sc = self.sc.copy() assert sc.fill_value.item() == (0, -1.) sc.fill_value = (-1, np.inf) assert sc.fill_value == np.array((-1, np.inf), self.sc.dtype) sc2 = MaskedColumn(sc, fill_value=(-2, -np.inf)) assert sc2.fill_value == np.array((-2, -np.inf), sc2.dtype) def test_table_column_mask_not_ref(self): """Table column mask is not ref of original column mask""" self.b.fill_value = -999 assert self.t['b'].fill_value != -999 def test_set_get_fill_value_for_table_column(self): """Check set and get of fill value works for Column in a Table""" self.t['b'].fill_value = 1 assert self.t['b'].fill_value == 1 assert np.all(self.t['b'].filled() == [1, 1, 1]) def test_data_attribute_fill_and_mask(self): """Check that .data attribute preserves fill_value and mask""" self.t['b'].fill_value = 1 self.t['b'].mask = [True, False, True] assert self.t['b'].data.fill_value == 1 assert np.all(self.t['b'].data.mask == [True, False, True]) class TestMaskedColumnInit(SetupData): """Initialization of a masked column""" def test_set_mask_and_not_ref(self): """Check that mask gets set properly and that it is a copy, not ref""" assert np.all(~self.a.mask) assert np.all(self.b.mask) assert np.all(~self.c.mask) assert np.all(self.d.mask == self.d_mask) self.d.mask[0] = True assert not np.all(self.d.mask == self.d_mask) def test_set_mask_from_list(self): """Set mask from a list""" mask_list = [False, True, False] a = MaskedColumn(name='a', data=[1, 2, 3], mask=mask_list) assert np.all(a.mask == mask_list) def test_override_existing_mask(self): """Override existing mask values""" mask_list = [False, True, False] b = MaskedColumn(name='b', data=self.b, mask=mask_list) assert np.all(b.mask == mask_list) def test_incomplete_mask_spec(self): """Incomplete mask specification raises MaskError""" mask_list = [False, True] with pytest.raises(ma.MaskError): MaskedColumn(name='b', length=4, mask=mask_list) class TestTableInit(SetupData): """Initializing a table""" @pytest.mark.parametrize('type_str', ('?', 'b', 'i2', 'f4', 'c8', 'S', 'U', 'O')) @pytest.mark.parametrize('shape', ((8,), (4, 2), (2, 2, 2))) def test_init_from_sequence_data_numeric_typed(self, type_str, shape): """Test init from list or list of lists with dtype specified, optionally including an np.ma.masked element. """ # Make data of correct dtype and shape, then turn into a list, # then use that to init Table with spec'd type_str. data = list(range(8)) np_data = np.array(data, dtype=type_str).reshape(shape) np_data_list = np_data.tolist() t = Table([np_data_list], dtype=[type_str]) col = t['col0'] assert col.dtype == np_data.dtype assert np.all(col == np_data) assert type(col) is Column # Introduce np.ma.masked in the list input and confirm dtype still OK. if len(shape) == 1: np_data_list[-1] = np.ma.masked elif len(shape) == 2: np_data_list[-1][-1] = np.ma.masked else: np_data_list[-1][-1][-1] = np.ma.masked last_idx = tuple(-1 for _ in shape) t = Table([np_data_list], dtype=[type_str]) col = t['col0'] assert col.dtype == np_data.dtype assert np.all(col == np_data) assert col.mask[last_idx] assert type(col) is MaskedColumn @pytest.mark.parametrize('type_str', ('?', 'b', 'i2', 'f4', 'c8', 'S', 'U', 'O')) @pytest.mark.parametrize('shape', ((8,), (4, 2), (2, 2, 2))) def test_init_from_sequence_data_numeric_untyped(self, type_str, shape): """Test init from list or list of lists with dtype NOT specified, optionally including an np.ma.masked element. """ data = list(range(8)) np_data = np.array(data, dtype=type_str).reshape(shape) np_data_list = np_data.tolist() t = Table([np_data_list]) # Grab the dtype that numpy assigns for the Python list inputs dtype_expected = t['col0'].dtype # Introduce np.ma.masked in the list input and confirm dtype still OK. if len(shape) == 1: np_data_list[-1] = np.ma.masked elif len(shape) == 2: np_data_list[-1][-1] = np.ma.masked else: np_data_list[-1][-1][-1] = np.ma.masked last_idx = tuple(-1 for _ in shape) t = Table([np_data_list]) col = t['col0'] # Confirm dtype is same as for untype list input w/ no mask assert col.dtype == dtype_expected assert np.all(col == np_data) assert col.mask[last_idx] assert type(col) is MaskedColumn def test_initialization_with_all_columns(self): t1 = Table([self.a, self.b, self.c, self.d, self.ca, self.sc]) assert t1.colnames == ['a', 'b', 'c', 'd', 'ca', 'sc'] # Check we get the same result by passing in as list of dict. # (Regression test for error uncovered by scintillometry package.) lofd = [{k: row[k] for k in t1.colnames} for row in t1] t2 = Table(lofd) for k in t1.colnames: assert t1[k].dtype == t2[k].dtype assert np.all(t1[k] == t2[k]) in (True, np.ma.masked) assert np.all(getattr(t1[k], 'mask', False) == getattr(t2[k], 'mask', False)) def test_mask_false_if_input_mask_not_true(self): """Masking is always False if initial masked arg is not True""" t = Table([self.ca, self.a]) assert t.masked is False # True before astropy 4.0 t = Table([self.ca]) assert t.masked is False t = Table([self.ca, ma.array([1, 2, 3])]) assert t.masked is False # True before astropy 4.0 def test_mask_false_if_no_input_masked(self): """Masking not true if not (requested or input requires mask)""" t0 = Table([[3, 4]], masked=False) t1 = Table(t0, masked=True) t2 = Table(t1, masked=False) assert not t0.masked assert t1.masked assert not t2.masked def test_mask_property(self): t = self.t # Access table mask (boolean structured array) by column name assert np.all(t.mask['a'] == np.array([False, False, False])) assert np.all(t.mask['b'] == np.array([True, True, True])) # Check that setting mask from table mask has the desired effect on column t.mask['b'] = np.array([False, True, False]) assert np.all(t['b'].mask == np.array([False, True, False])) # Non-masked table returns None for mask attribute t2 = Table([self.ca], masked=False) assert t2.mask is None # Set mask property globally and verify local correctness for mask in (True, False): t.mask = mask for name in ('a', 'b'): assert np.all(t[name].mask == mask) class TestAddColumn: def test_add_masked_column_to_masked_table(self): t = Table(masked=True) assert t.masked t.add_column(MaskedColumn(name='a', data=[1, 2, 3], mask=[0, 1, 0])) assert t.masked t.add_column(MaskedColumn(name='b', data=[4, 5, 6], mask=[1, 0, 1])) assert t.masked assert isinstance(t['a'], MaskedColumn) assert isinstance(t['b'], MaskedColumn) assert np.all(t['a'] == np.array([1, 2, 3])) assert np.all(t['a'].mask == np.array([0, 1, 0], bool)) assert np.all(t['b'] == np.array([4, 5, 6])) assert np.all(t['b'].mask == np.array([1, 0, 1], bool)) def test_add_masked_column_to_non_masked_table(self): t = Table(masked=False) assert not t.masked t.add_column(Column(name='a', data=[1, 2, 3])) assert not t.masked t.add_column(MaskedColumn(name='b', data=[4, 5, 6], mask=[1, 0, 1])) assert not t.masked # Changed in 4.0, table no longer auto-upgrades assert isinstance(t['a'], Column) # Was MaskedColumn before 4.0 assert isinstance(t['b'], MaskedColumn) assert np.all(t['a'] == np.array([1, 2, 3])) assert not hasattr(t['a'], 'mask') assert np.all(t['b'] == np.array([4, 5, 6])) assert np.all(t['b'].mask == np.array([1, 0, 1], bool)) def test_add_non_masked_column_to_masked_table(self): t = Table(masked=True) assert t.masked t.add_column(Column(name='a', data=[1, 2, 3])) assert t.masked t.add_column(MaskedColumn(name='b', data=[4, 5, 6], mask=[1, 0, 1])) assert t.masked assert isinstance(t['a'], MaskedColumn) assert isinstance(t['b'], MaskedColumn) assert np.all(t['a'] == np.array([1, 2, 3])) assert np.all(t['a'].mask == np.array([0, 0, 0], bool)) assert np.all(t['b'] == np.array([4, 5, 6])) assert np.all(t['b'].mask == np.array([1, 0, 1], bool)) def test_convert_to_masked_table_only_if_necessary(self): # Do not convert to masked table, if new column has no masked value. # See #1185 for details. t = Table(masked=False) assert not t.masked t.add_column(Column(name='a', data=[1, 2, 3])) assert not t.masked t.add_column(MaskedColumn(name='b', data=[4, 5, 6], mask=[0, 0, 0])) assert not t.masked assert np.all(t['a'] == np.array([1, 2, 3])) assert np.all(t['b'] == np.array([4, 5, 6])) class TestRenameColumn: def test_rename_masked_column(self): t = Table(masked=True) t.add_column(MaskedColumn(name='a', data=[1, 2, 3], mask=[0, 1, 0])) t['a'].fill_value = 42 t.rename_column('a', 'b') assert t.masked assert np.all(t['b'] == np.array([1, 2, 3])) assert np.all(t['b'].mask == np.array([0, 1, 0], bool)) assert t['b'].fill_value == 42 assert t.colnames == ['b'] class TestRemoveColumn: def test_remove_masked_column(self): t = Table(masked=True) t.add_column(MaskedColumn(name='a', data=[1, 2, 3], mask=[0, 1, 0])) t['a'].fill_value = 42 t.add_column(MaskedColumn(name='b', data=[4, 5, 6], mask=[1, 0, 1])) t.remove_column('b') assert t.masked assert np.all(t['a'] == np.array([1, 2, 3])) assert np.all(t['a'].mask == np.array([0, 1, 0], bool)) assert t['a'].fill_value == 42 assert t.colnames == ['a'] class TestAddRow: def test_add_masked_row_to_masked_table_iterable(self): t = Table(masked=True) t.add_column(MaskedColumn(name='a', data=[1], mask=[0])) t.add_column(MaskedColumn(name='b', data=[4], mask=[1])) t.add_row([2, 5], mask=[1, 0]) t.add_row([3, 6], mask=[0, 1]) assert t.masked assert np.all(np.array(t['a']) == np.array([1, 2, 3])) assert np.all(t['a'].mask == np.array([0, 1, 0], bool)) assert np.all(np.array(t['b']) == np.array([4, 5, 6])) assert np.all(t['b'].mask == np.array([1, 0, 1], bool)) def test_add_masked_row_to_masked_table_mapping1(self): t = Table(masked=True) t.add_column(MaskedColumn(name='a', data=[1], mask=[0])) t.add_column(MaskedColumn(name='b', data=[4], mask=[1])) t.add_row({'b': 5, 'a': 2}, mask={'a': 1, 'b': 0}) t.add_row({'a': 3, 'b': 6}, mask={'b': 1, 'a': 0}) assert t.masked assert np.all(np.array(t['a']) == np.array([1, 2, 3])) assert np.all(t['a'].mask == np.array([0, 1, 0], bool)) assert np.all(np.array(t['b']) == np.array([4, 5, 6])) assert np.all(t['b'].mask == np.array([1, 0, 1], bool)) def test_add_masked_row_to_masked_table_mapping2(self): # When adding values to a masked table, if the mask is specified as a # dict, then values not specified will have mask values set to True t = Table(masked=True) t.add_column(MaskedColumn(name='a', data=[1], mask=[0])) t.add_column(MaskedColumn(name='b', data=[4], mask=[1])) t.add_row({'b': 5}, mask={'b': 0}) t.add_row({'a': 3}, mask={'a': 0}) assert t.masked assert t['a'][0] == 1 and t['a'][2] == 3 assert np.all(t['a'].mask == np.array([0, 1, 0], bool)) assert t['b'][1] == 5 assert np.all(t['b'].mask == np.array([1, 0, 1], bool)) def test_add_masked_row_to_masked_table_mapping3(self): # When adding values to a masked table, if mask is not passed to # add_row, then the mask should be set to False if values are present # and True if not. t = Table(masked=True) t.add_column(MaskedColumn(name='a', data=[1], mask=[0])) t.add_column(MaskedColumn(name='b', data=[4], mask=[1])) t.add_row({'b': 5}) t.add_row({'a': 3}) assert t.masked assert t['a'][0] == 1 and t['a'][2] == 3 assert np.all(t['a'].mask == np.array([0, 1, 0], bool)) assert t['b'][1] == 5 assert np.all(t['b'].mask == np.array([1, 0, 1], bool)) def test_add_masked_row_to_masked_table_mapping4(self): # When adding values to a masked table, if the mask is specified as a # dict, then keys in values should match keys in mask t = Table(masked=True) t.add_column(MaskedColumn(name='a', data=[1], mask=[0])) t.add_column(MaskedColumn(name='b', data=[4], mask=[1])) with pytest.raises(ValueError) as exc: t.add_row({'b': 5}, mask={'a': True}) assert exc.value.args[0] == 'keys in mask should match keys in vals' def test_add_masked_row_to_masked_table_mismatch(self): t = Table(masked=True) t.add_column(MaskedColumn(name='a', data=[1], mask=[0])) t.add_column(MaskedColumn(name='b', data=[4], mask=[1])) with pytest.raises(TypeError) as exc: t.add_row([2, 5], mask={'a': 1, 'b': 0}) assert exc.value.args[0] == "Mismatch between type of vals and mask" with pytest.raises(TypeError) as exc: t.add_row({'b': 5, 'a': 2}, mask=[1, 0]) assert exc.value.args[0] == "Mismatch between type of vals and mask" def test_add_masked_row_to_non_masked_table_iterable(self): t = Table(masked=False) t['a'] = [1] t['b'] = [4] t['c'] = Time([1], format='cxcsec') tm = Time(2, format='cxcsec') assert not t.masked t.add_row([2, 5, tm]) assert not t.masked t.add_row([3, 6, tm], mask=[0, 1, 1]) assert not t.masked assert type(t['a']) is Column assert type(t['b']) is MaskedColumn assert type(t['c']) is Time assert np.all(t['a'] == [1, 2, 3]) assert np.all(t['b'].data == [4, 5, 6]) assert np.all(t['b'].mask == [False, False, True]) assert np.all(t['c'][:2] == Time([1, 2], format='cxcsec')) assert np.all(t['c'].mask == [False, False, True]) def test_add_row_cannot_mask_column_raises_typeerror(self): t = QTable() t['a'] = [1, 2] * u.m t.add_row((3 * u.m,)) # No problem with pytest.raises(ValueError) as exc: t.add_row((3 * u.m,), mask=(True,)) assert (exc.value.args[0].splitlines() == ["Unable to insert row because of exception in column 'a':", "mask was supplied for column 'a' but it does not support masked values"]) def test_setting_from_masked_column(): """Test issue in #2997""" mask_b = np.array([True, True, False, False]) for select in (mask_b, slice(0, 2)): t = Table(masked=True) t['a'] = Column([1, 2, 3, 4]) t['b'] = MaskedColumn([11, 22, 33, 44], mask=mask_b) t['c'] = MaskedColumn([111, 222, 333, 444], mask=[True, False, True, False]) t['b'][select] = t['c'][select] assert t['b'][1] == t[1]['b'] assert t['b'][0] is np.ma.masked # Original state since t['c'][0] is masked assert t['b'][1] == 222 # New from t['c'] since t['c'][1] is unmasked assert t['b'][2] == 33 assert t['b'][3] == 44 assert np.all(t['b'].mask == t.mask['b']) # Avoid t.mask in general, this is for testing mask_before_add = t.mask.copy() t['d'] = np.arange(len(t)) assert np.all(t.mask['b'] == mask_before_add['b']) def test_coercing_fill_value_type(): """ Test that masked column fill_value is coerced into the correct column type. """ # This is the original example posted on the astropy@scipy mailing list t = Table({'a': ['1']}, masked=True) t['a'].set_fill_value('0') t2 = Table(t, names=['a'], dtype=[np.int32]) assert isinstance(t2['a'].fill_value, np.int32) # Unit test the same thing. c = MaskedColumn(['1']) c.set_fill_value('0') c2 = MaskedColumn(c, dtype=np.int32) assert isinstance(c2.fill_value, np.int32) def test_mask_copy(): """Test that the mask is copied when copying a table (issue #7362).""" c = MaskedColumn([1, 2], mask=[False, True]) c2 = MaskedColumn(c, copy=True) c2.mask[0] = True assert np.all(c.mask == [False, True]) assert np.all(c2.mask == [True, True]) def test_masked_as_array_with_mixin(): """Test that as_array() and Table.mask attr work with masked mixin columns""" t = Table() t['a'] = Time([1, 2], format='cxcsec') t['b'] = [3, 4] t['c'] = [5, 6] * u.m # With no mask, the output should be ndarray ta = t.as_array() assert isinstance(ta, np.ndarray) and not isinstance(ta, np.ma.MaskedArray) # With a mask, output is MaskedArray t['a'][1] = np.ma.masked ta = t.as_array() assert isinstance(ta, np.ma.MaskedArray) assert np.all(ta['a'].mask == [False, True]) assert np.isclose(ta['a'][0].cxcsec, 1.0) assert np.all(ta['b'].mask == False) # noqa assert np.all(ta['c'].mask == False) # noqa # Check table ``mask`` property tm = t.mask assert np.all(tm['a'] == [False, True]) assert np.all(tm['b'] == False) # noqa assert np.all(tm['c'] == False) # noqa def test_masked_column_with_unit_in_qtable(): """Test that adding a MaskedColumn with a unit to QTable creates a MaskedQuantity.""" MaskedQuantity = Masked(u.Quantity) t = QTable() t['a'] = MaskedColumn([1, 2]) assert isinstance(t['a'], MaskedColumn) t['b'] = MaskedColumn([1, 2], unit=u.m) assert isinstance(t['b'], MaskedQuantity) assert np.all(t['b'].mask == False) # noqa t['c'] = MaskedColumn([1, 2], unit=u.m, mask=[True, False]) assert isinstance(t['c'], MaskedQuantity) assert np.all(t['c'].mask == [True, False]) def test_masked_quantity_in_table(): MaskedQuantity = Masked(u.Quantity) t = Table() t['b'] = MaskedQuantity([1, 2], unit=u.m) assert isinstance(t['b'], MaskedColumn) assert np.all(t['b'].mask == False) # noqa t['c'] = MaskedQuantity([1, 2], unit=u.m, mask=[True, False]) assert isinstance(t['c'], MaskedColumn) assert np.all(t['c'].mask == [True, False]) def test_masked_column_data_attribute_is_plain_masked_array(): c = MaskedColumn([1, 2], mask=[False, True]) c_data = c.data assert type(c_data) is np.ma.MaskedArray assert type(c_data.data) is np.ndarray def test_mask_slicing_count_array_finalize(): """Check that we don't finalize MaskedColumn too often. Regression test for gh-6721. """ # Create a new BaseColumn class that counts how often # ``__array_finalize__`` is called. class MyBaseColumn(BaseColumn): counter = 0 def __array_finalize__(self, obj): super().__array_finalize__(obj) MyBaseColumn.counter += 1 # Base a new MaskedColumn class on it. The normal MaskedColumn # hardcodes the initialization to BaseColumn, so we exchange that. class MyMaskedColumn(MaskedColumn, Column, MyBaseColumn): def __new__(cls, *args, **kwargs): self = super().__new__(cls, *args, **kwargs) self._baseclass = MyBaseColumn return self # Creation really needs 2 finalizations (once for the BaseColumn # call inside ``__new__`` and once when the view as a MaskedColumn # is taken), but since the first is hardcoded, we do not capture it # and thus the count is only 1. c = MyMaskedColumn([1, 2], mask=[False, True]) assert MyBaseColumn.counter == 1 # slicing should need only one ``__array_finalize__`` (used to be 3). c0 = c[:] assert MyBaseColumn.counter == 2 # repr should need none (used to be 2!!) repr(c0) assert MyBaseColumn.counter == 2 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/tests/test_mixin.py0000644000175100001710000007361000000000000020743 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst import copy import pickle from io import StringIO import pytest import numpy as np from astropy.table.serialize import represent_mixins_as_columns from astropy.utils.data_info import ParentDtypeInfo from astropy.table.table_helpers import ArrayWrapper from astropy.coordinates import EarthLocation, SkyCoord from astropy.table import Table, QTable, join, hstack, vstack, Column, NdarrayMixin from astropy.table import serialize from astropy import time from astropy import coordinates from astropy import units as u from astropy.table.column import BaseColumn from astropy.table import table_helpers from astropy.utils.exceptions import AstropyUserWarning from astropy.utils.metadata import MergeConflictWarning from astropy.coordinates.tests.test_representation import representation_equal from astropy.io.misc.asdf.tags.helpers import skycoord_equal from .conftest import MIXIN_COLS def test_attributes(mixin_cols): """ Required attributes for a column can be set. """ m = mixin_cols['m'] m.info.name = 'a' assert m.info.name == 'a' m.info.description = 'a' assert m.info.description == 'a' # Cannot set unit for these classes if isinstance(m, (u.Quantity, coordinates.SkyCoord, time.Time, time.TimeDelta, coordinates.BaseRepresentationOrDifferential)): with pytest.raises(AttributeError): m.info.unit = u.m else: m.info.unit = u.m assert m.info.unit is u.m m.info.format = 'a' assert m.info.format == 'a' m.info.meta = {'a': 1} assert m.info.meta == {'a': 1} with pytest.raises(AttributeError): m.info.bad_attr = 1 with pytest.raises(AttributeError): m.info.bad_attr def check_mixin_type(table, table_col, in_col): # We check for QuantityInfo rather than just isinstance(col, u.Quantity) # since we want to treat EarthLocation as a mixin, even though it is # a Quantity subclass. if ((isinstance(in_col.info, u.QuantityInfo) and type(table) is not QTable) or isinstance(in_col, Column)): assert type(table_col) is table.ColumnClass else: assert type(table_col) is type(in_col) # Make sure in_col got copied and creating table did not touch it assert in_col.info.name is None def test_make_table(table_types, mixin_cols): """ Make a table with the columns in mixin_cols, which is an ordered dict of three cols: 'a' and 'b' are table_types.Column type, and 'm' is a mixin. """ t = table_types.Table(mixin_cols) check_mixin_type(t, t['m'], mixin_cols['m']) cols = list(mixin_cols.values()) t = table_types.Table(cols, names=('i', 'a', 'b', 'm')) check_mixin_type(t, t['m'], mixin_cols['m']) t = table_types.Table(cols) check_mixin_type(t, t['col3'], mixin_cols['m']) def test_io_ascii_write(): """ Test that table with mixin column can be written by io.ascii for every pure Python writer. No validation of the output is done, this just confirms no exceptions. """ from astropy.io.ascii.connect import _get_connectors_table t = QTable(MIXIN_COLS) for fmt in _get_connectors_table(): if fmt['Write'] and '.fast_' not in fmt['Format']: out = StringIO() t.write(out, format=fmt['Format']) def test_votable_quantity_write(tmpdir): """ Test that table with Quantity mixin column can be round-tripped by io.votable. Note that FITS and HDF5 mixin support are tested (much more thoroughly) in their respective subpackage tests (io/fits/tests/test_connect.py and io/misc/tests/test_hdf5.py). """ t = QTable() t['a'] = u.Quantity([1, 2, 4], unit='nm') filename = str(tmpdir.join('table-tmp')) t.write(filename, format='votable', overwrite=True) qt = QTable.read(filename, format='votable') assert isinstance(qt['a'], u.Quantity) assert qt['a'].unit == 'nm' @pytest.mark.remote_data @pytest.mark.parametrize('table_types', (Table, QTable)) def test_io_time_write_fits_standard(tmpdir, table_types): """ Test that table with Time mixin columns can be written by io.fits. Validation of the output is done. Test that io.fits writes a table containing Time mixin columns that can be partially round-tripped (metadata scale, location). Note that we postpone checking the "local" scale, since that cannot be done with format 'cxcsec', as it requires an epoch. """ t = table_types([[1, 2], ['string', 'column']]) for scale in time.STANDARD_TIME_SCALES: t['a' + scale] = time.Time([[1, 2], [3, 4]], format='cxcsec', scale=scale, location=EarthLocation( -2446354, 4237210, 4077985, unit='m')) t['b' + scale] = time.Time(['1999-01-01T00:00:00.123456789', '2010-01-01T00:00:00'], scale=scale) t['c'] = [3., 4.] filename = str(tmpdir.join('table-tmp')) # Show that FITS format succeeds with pytest.warns( AstropyUserWarning, match='Time Column "btai" has no specified location, ' 'but global Time Position is present'): t.write(filename, format='fits', overwrite=True) with pytest.warns( AstropyUserWarning, match='Time column reference position "TRPOSn" is not specified'): tm = table_types.read(filename, format='fits', astropy_native=True) for scale in time.STANDARD_TIME_SCALES: for ab in ('a', 'b'): name = ab + scale # Assert that the time columns are read as Time assert isinstance(tm[name], time.Time) # Assert that the scales round-trip assert tm[name].scale == t[name].scale # Assert that the format is jd assert tm[name].format == 'jd' # Assert that the location round-trips assert tm[name].location == t[name].location # Finally assert that the column data round-trips assert (tm[name] == t[name]).all() for name in ('col0', 'col1', 'c'): # Assert that the non-time columns are read as Column assert isinstance(tm[name], Column) # Assert that the non-time columns' data round-trips assert (tm[name] == t[name]).all() # Test for conversion of time data to its value, as defined by its format for scale in time.STANDARD_TIME_SCALES: for ab in ('a', 'b'): name = ab + scale t[name].info.serialize_method['fits'] = 'formatted_value' t.write(filename, format='fits', overwrite=True) tm = table_types.read(filename, format='fits') for scale in time.STANDARD_TIME_SCALES: for ab in ('a', 'b'): name = ab + scale assert not isinstance(tm[name], time.Time) assert (tm[name] == t[name].value).all() @pytest.mark.parametrize('table_types', (Table, QTable)) def test_io_time_write_fits_local(tmpdir, table_types): """ Test that table with a Time mixin with scale local can also be written by io.fits. Like ``test_io_time_write_fits_standard`` above, but avoiding ``cxcsec`` format, which requires an epoch and thus cannot be used for a local time scale. """ t = table_types([[1, 2], ['string', 'column']]) t['a_local'] = time.Time([[50001, 50002], [50003, 50004]], format='mjd', scale='local', location=EarthLocation(-2446354, 4237210, 4077985, unit='m')) t['b_local'] = time.Time(['1999-01-01T00:00:00.123456789', '2010-01-01T00:00:00'], scale='local') t['c'] = [3., 4.] filename = str(tmpdir.join('table-tmp')) # Show that FITS format succeeds with pytest.warns(AstropyUserWarning, match='Time Column "b_local" has no specified location'): t.write(filename, format='fits', overwrite=True) with pytest.warns(AstropyUserWarning, match='Time column reference position "TRPOSn" is not specified.'): tm = table_types.read(filename, format='fits', astropy_native=True) for ab in ('a', 'b'): name = ab + '_local' # Assert that the time columns are read as Time assert isinstance(tm[name], time.Time) # Assert that the scales round-trip assert tm[name].scale == t[name].scale # Assert that the format is jd assert tm[name].format == 'jd' # Assert that the location round-trips assert tm[name].location == t[name].location # Finally assert that the column data round-trips assert (tm[name] == t[name]).all() for name in ('col0', 'col1', 'c'): # Assert that the non-time columns are read as Column assert isinstance(tm[name], Column) # Assert that the non-time columns' data round-trips assert (tm[name] == t[name]).all() # Test for conversion of time data to its value, as defined by its format. for ab in ('a', 'b'): name = ab + '_local' t[name].info.serialize_method['fits'] = 'formatted_value' t.write(filename, format='fits', overwrite=True) tm = table_types.read(filename, format='fits') for ab in ('a', 'b'): name = ab + '_local' assert not isinstance(tm[name], time.Time) assert (tm[name] == t[name].value).all() def test_votable_mixin_write_fail(mixin_cols): """ Test that table with mixin columns (excluding Quantity) cannot be written by io.votable. """ t = QTable(mixin_cols) # Only do this test if there are unsupported column types (i.e. anything besides # BaseColumn and Quantity class instances). unsupported_cols = t.columns.not_isinstance((BaseColumn, u.Quantity)) if not unsupported_cols: pytest.skip("no unsupported column types") out = StringIO() with pytest.raises(ValueError) as err: t.write(out, format='votable') assert 'cannot write table with mixin column(s)' in str(err.value) def test_join(table_types): """ Join tables with mixin cols. Use column "i" as proxy for what the result should be for each mixin. """ t1 = table_types.Table() t1['a'] = table_types.Column(['a', 'b', 'b', 'c']) t1['i'] = table_types.Column([0, 1, 2, 3]) for name, col in MIXIN_COLS.items(): t1[name] = col t2 = table_types.Table(t1) t2['a'] = ['b', 'c', 'a', 'd'] for name, col in MIXIN_COLS.items(): t1[name].info.description = name t2[name].info.description = name + '2' for join_type in ('inner', 'left'): t12 = join(t1, t2, keys='a', join_type=join_type) idx1 = t12['i_1'] idx2 = t12['i_2'] for name, col in MIXIN_COLS.items(): name1 = name + '_1' name2 = name + '_2' assert_table_name_col_equal(t12, name1, col[idx1]) assert_table_name_col_equal(t12, name2, col[idx2]) assert t12[name1].info.description == name assert t12[name2].info.description == name + '2' for join_type in ('outer', 'right'): with pytest.raises(NotImplementedError) as exc: t12 = join(t1, t2, keys='a', join_type=join_type) assert 'join requires masking column' in str(exc.value) with pytest.raises(TypeError) as exc: t12 = join(t1, t2, keys=['a', 'skycoord']) assert 'one or more key columns are not sortable' in str(exc.value) # Join does work for a mixin which is a subclass of np.ndarray with pytest.warns(MergeConflictWarning, match="In merged column 'quantity' the 'description' " "attribute does not match"): t12 = join(t1, t2, keys=['quantity']) assert np.all(t12['a_1'] == t1['a']) def test_hstack(table_types): """ Hstack tables with mixin cols. Use column "i" as proxy for what the result should be for each mixin. """ t1 = table_types.Table() t1['i'] = table_types.Column([0, 1, 2, 3]) for name, col in MIXIN_COLS.items(): t1[name] = col t1[name].info.description = name t1[name].info.meta = {'a': 1} for join_type in ('inner', 'outer'): for chop in (True, False): t2 = table_types.Table(t1) if chop: t2 = t2[:-1] if join_type == 'outer': with pytest.raises(NotImplementedError) as exc: t12 = hstack([t1, t2], join_type=join_type) assert 'hstack requires masking column' in str(exc.value) continue t12 = hstack([t1, t2], join_type=join_type) idx1 = t12['i_1'] idx2 = t12['i_2'] for name, col in MIXIN_COLS.items(): name1 = name + '_1' name2 = name + '_2' assert_table_name_col_equal(t12, name1, col[idx1]) assert_table_name_col_equal(t12, name2, col[idx2]) for attr in ('description', 'meta'): assert getattr(t1[name].info, attr) == getattr(t12[name1].info, attr) assert getattr(t2[name].info, attr) == getattr(t12[name2].info, attr) def assert_table_name_col_equal(t, name, col): """ Assert all(t[name] == col), with special handling for known mixin cols. """ if isinstance(col, coordinates.SkyCoord): assert np.all(t[name].ra == col.ra) assert np.all(t[name].dec == col.dec) elif isinstance(col, coordinates.BaseRepresentationOrDifferential): assert np.all(representation_equal(t[name], col)) elif isinstance(col, u.Quantity): if type(t) is QTable: assert np.all(t[name] == col) elif isinstance(col, table_helpers.ArrayWrapper): assert np.all(t[name].data == col.data) else: assert np.all(t[name] == col) def test_get_items(mixin_cols): """ Test that slicing / indexing table gives right values and col attrs inherit """ attrs = ('name', 'unit', 'dtype', 'format', 'description', 'meta') m = mixin_cols['m'] m.info.name = 'm' m.info.format = '{0}' m.info.description = 'd' m.info.meta = {'a': 1} t = QTable([m]) for item in ([1, 3], np.array([0, 2]), slice(1, 3)): t2 = t[item] m2 = m[item] assert_table_name_col_equal(t2, 'm', m[item]) for attr in attrs: assert getattr(t2['m'].info, attr) == getattr(m.info, attr) assert getattr(m2.info, attr) == getattr(m.info, attr) def test_info_preserved_pickle_copy_init(mixin_cols): """ Test copy, pickle, and init from class roundtrip preserve info. This tests not only the mixin classes but a regular column as well. """ def pickle_roundtrip(c): return pickle.loads(pickle.dumps(c)) def init_from_class(c): return c.__class__(c) attrs = ('name', 'unit', 'dtype', 'format', 'description', 'meta') for colname in ('i', 'm'): m = mixin_cols[colname] m.info.name = colname m.info.format = '{0}' m.info.description = 'd' m.info.meta = {'a': 1} for func in (copy.copy, copy.deepcopy, pickle_roundtrip, init_from_class): m2 = func(m) for attr in attrs: # non-native byteorder not preserved by last 2 func, _except_ for structured dtype if (attr != 'dtype' or getattr(m.info.dtype, 'isnative', True) or m.info.dtype.name.startswith('void') or func in (copy.copy, copy.deepcopy)): original = getattr(m.info, attr) else: # func does not preserve byteorder, check against (native) type. original = m.info.dtype.newbyteorder('=') assert getattr(m2.info, attr) == original def test_add_column(mixin_cols): """ Test that adding a column preserves values and attributes """ attrs = ('name', 'unit', 'dtype', 'format', 'description', 'meta') m = mixin_cols['m'] assert m.info.name is None # Make sure adding column in various ways doesn't touch t = QTable([m], names=['a']) assert m.info.name is None t['new'] = m assert m.info.name is None m.info.name = 'm' m.info.format = '{0}' m.info.description = 'd' m.info.meta = {'a': 1} t = QTable([m]) # Add columns m2, m3, m4 by two different methods and test expected equality t['m2'] = m m.info.name = 'm3' t.add_columns([m], copy=True) m.info.name = 'm4' t.add_columns([m], copy=False) for name in ('m2', 'm3', 'm4'): assert_table_name_col_equal(t, name, m) for attr in attrs: if attr != 'name': assert getattr(t['m'].info, attr) == getattr(t[name].info, attr) # Also check that one can set using a scalar. s = m[0] if type(s) is type(m) and 'info' in s.__dict__: # We're not going to worry about testing classes for which scalars # are a different class than the real array, or where info is not copied. t['s'] = m[0] assert_table_name_col_equal(t, 's', m[0]) for attr in attrs: if attr != 'name': assert getattr(t['m'].info, attr) == getattr(t['s'].info, attr) # While we're add it, also check a length-1 table. t = QTable([m[1:2]], names=['m']) if type(s) is type(m) and 'info' in s.__dict__: t['s'] = m[0] assert_table_name_col_equal(t, 's', m[0]) for attr in attrs: if attr != 'name': assert getattr(t['m'].info, attr) == getattr(t['s'].info, attr) def test_vstack(): """ Vstack tables with mixin cols. """ t1 = QTable(MIXIN_COLS) t2 = QTable(MIXIN_COLS) with pytest.raises(NotImplementedError): vstack([t1, t2]) def test_insert_row(mixin_cols): """ Test inserting a row, which works for Column, Quantity, Time and SkyCoord. """ t = QTable(mixin_cols) t0 = t.copy() t['m'].info.description = 'd' idxs = [0, -1, 1, 2, 3] if isinstance(t['m'], (u.Quantity, Column, time.Time, time.TimeDelta, coordinates.SkyCoord)): t.insert_row(1, t[-1]) for name in t.colnames: col = t[name] if isinstance(col, coordinates.SkyCoord): assert skycoord_equal(col, t0[name][idxs]) else: assert np.all(col == t0[name][idxs]) assert t['m'].info.description == 'd' else: with pytest.raises(ValueError) as exc: t.insert_row(1, t[-1]) assert "Unable to insert row" in str(exc.value) def test_insert_row_bad_unit(): """ Insert a row into a QTable with the wrong unit """ t = QTable([[1] * u.m]) with pytest.raises(ValueError) as exc: t.insert_row(0, (2 * u.m / u.s,)) assert "'m / s' (speed/velocity) and 'm' (length) are not convertible" in str(exc.value) def test_convert_np_array(mixin_cols): """ Test that converting to numpy array creates an object dtype and that each instance in the array has the expected type. """ t = QTable(mixin_cols) ta = t.as_array() m = mixin_cols['m'] dtype_kind = m.dtype.kind if hasattr(m, 'dtype') else 'O' assert ta['m'].dtype.kind == dtype_kind def test_assignment_and_copy(): """ Test that assignment of an int, slice, and fancy index works. Along the way test that copying table works. """ for name in ('quantity', 'arraywrap'): m = MIXIN_COLS[name] t0 = QTable([m], names=['m']) for i0, i1 in ((1, 2), (slice(0, 2), slice(1, 3)), (np.array([1, 2]), np.array([2, 3]))): t = t0.copy() t['m'][i0] = m[i1] if name == 'arraywrap': assert np.all(t['m'].data[i0] == m.data[i1]) assert np.all(t0['m'].data[i0] == m.data[i0]) assert np.all(t0['m'].data[i0] != t['m'].data[i0]) else: assert np.all(t['m'][i0] == m[i1]) assert np.all(t0['m'][i0] == m[i0]) assert np.all(t0['m'][i0] != t['m'][i0]) def test_conversion_qtable_table(): """ Test that a table round trips from QTable => Table => QTable """ qt = QTable(MIXIN_COLS) names = qt.colnames for name in names: qt[name].info.description = name t = Table(qt) for name in names: assert t[name].info.description == name if name == 'quantity': assert np.all(t['quantity'] == qt['quantity'].value) assert np.all(t['quantity'].unit is qt['quantity'].unit) assert isinstance(t['quantity'], t.ColumnClass) else: assert_table_name_col_equal(t, name, qt[name]) qt2 = QTable(qt) for name in names: assert qt2[name].info.description == name assert_table_name_col_equal(qt2, name, qt[name]) def test_setitem_as_column_name(): """ Test for mixin-related regression described in #3321. """ t = Table() t['a'] = ['x', 'y'] t['b'] = 'b' # Previously was failing with KeyError assert np.all(t['a'] == ['x', 'y']) assert np.all(t['b'] == ['b', 'b']) def test_quantity_representation(): """ Test that table representation of quantities does not have unit """ t = QTable([[1, 2] * u.m]) assert t.pformat() == ['col0', ' m ', '----', ' 1.0', ' 2.0'] def test_representation_representation(): """ Test that Representations are represented correctly. """ # With no unit we get "None" in the unit row c = coordinates.CartesianRepresentation([0], [1], [0], unit=u.one) t = Table([c]) assert t.pformat() == [' col0 ', '------------', '(0., 1., 0.)'] c = coordinates.CartesianRepresentation([0], [1], [0], unit='m') t = Table([c]) assert t.pformat() == [' col0 ', ' m ', '------------', '(0., 1., 0.)'] c = coordinates.SphericalRepresentation([10]*u.deg, [20]*u.deg, [1]*u.pc) t = Table([c]) assert t.pformat() == [' col0 ', ' deg, deg, pc ', '--------------', '(10., 20., 1.)'] c = coordinates.UnitSphericalRepresentation([10]*u.deg, [20]*u.deg) t = Table([c]) assert t.pformat() == [' col0 ', ' deg ', '----------', '(10., 20.)'] c = coordinates.SphericalCosLatDifferential( [10]*u.mas/u.yr, [2]*u.mas/u.yr, [10]*u.km/u.s) t = Table([c]) assert t.pformat() == [' col0 ', 'mas / yr, mas / yr, km / s', '--------------------------', ' (10., 2., 10.)'] def test_skycoord_representation(): """ Test that skycoord representation works, both in the way that the values are output and in changing the frame representation. """ # With no unit we get "None" in the unit row c = coordinates.SkyCoord([0], [1], [0], representation_type='cartesian') t = Table([c]) assert t.pformat() == [' col0 ', 'None,None,None', '--------------', ' 0.0,1.0,0.0'] # Test that info works with a dynamically changed representation c = coordinates.SkyCoord([0], [1], [0], unit='m', representation_type='cartesian') t = Table([c]) assert t.pformat() == [' col0 ', ' m,m,m ', '-----------', '0.0,1.0,0.0'] t['col0'].representation_type = 'unitspherical' assert t.pformat() == [' col0 ', 'deg,deg ', '--------', '90.0,0.0'] t['col0'].representation_type = 'cylindrical' assert t.pformat() == [' col0 ', ' m,deg,m ', '------------', '1.0,90.0,0.0'] def test_ndarray_mixin(): """ Test directly adding a plain structured array into a table instead of the view as an NdarrayMixin. Once added as an NdarrayMixin then all the previous tests apply. """ a = np.array([(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')], dtype=' # tm q idx_1 idx_2 # m # object float64 int64 int64 # ------------------ ------- ----- ----- # 0.9999999999969589 1.0 2 -- # 2.00000000000351 1.0 3 -- # 2.00000000000351 2.0 1 10 # 3.000000000000469 3.0 -- 20 t12 = table.join(t1, t2, join_type='outer', keys=['tm', 'q']) # Key cols are lexically sorted assert np.all(t12['tm'] == Time([1, 2, 2, 3], format='cxcsec')) assert np.all(t12['q'] == [1, 1, 2, 3] * u.m) assert np.all(t12['idx_1'] == np.ma.array([2, 3, 1, 0], mask=[0, 0, 0, 1])) assert np.all(t12['idx_2'] == np.ma.array([0, 0, 10, 20], mask=[1, 1, 0, 0])) def test_join_mixins_not_sortable(): """ Test for table join using non-ndarray key columns that are not sortable. """ sc = SkyCoord([1, 2], [3, 4], unit='deg,deg') t1 = Table([sc, [1, 2]], names=['sc', 'idx1']) t2 = Table([sc, [10, 20]], names=['sc', 'idx2']) with pytest.raises(TypeError, match='one or more key columns are not sortable'): table.join(t1, t2, keys='sc') def test_join_non_1d_key_column(): c1 = [[1, 2], [3, 4]] c2 = [1, 2] t1 = Table([c1, c2], names=['a', 'b']) t2 = t1.copy() with pytest.raises(ValueError, match="key column 'a' must be 1-d"): table.join(t1, t2, keys='a') def test_argsort_time_column(): """Regression test for #10823.""" times = Time(['2016-01-01', '2018-01-01', '2017-01-01']) t = Table([times], names=['time']) i = t.argsort('time') assert np.all(i == times.argsort()) def test_sort_indexed_table(): """Test fix for #9473 and #6545 - and another regression test for #10823.""" t = Table([[1, 3, 2], [6, 4, 5]], names=('a', 'b')) t.add_index('a') t.sort('a') assert np.all(t['a'] == [1, 2, 3]) assert np.all(t['b'] == [6, 5, 4]) t.sort('b') assert np.all(t['b'] == [4, 5, 6]) assert np.all(t['a'] == [3, 2, 1]) times = ['2016-01-01', '2018-01-01', '2017-01-01'] tm = Time(times) t2 = Table([tm, [3, 2, 1]], names=['time', 'flux']) t2.sort('flux') assert np.all(t2['flux'] == [1, 2, 3]) t2.sort('time') assert np.all(t2['flux'] == [3, 1, 2]) assert np.all(t2['time'] == tm[[0, 2, 1]]) # Using the table as a TimeSeries implicitly sets the index, so # this test is a bit different from the above. from astropy.timeseries import TimeSeries ts = TimeSeries(time=times) ts['flux'] = [3, 2, 1] ts.sort('flux') assert np.all(ts['flux'] == [1, 2, 3]) ts.sort('time') assert np.all(ts['flux'] == [3, 1, 2]) assert np.all(ts['time'] == tm[[0, 2, 1]]) def test_get_out_class(): c = table.Column([1, 2]) mc = table.MaskedColumn([1, 2]) q = [1, 2] * u.m assert _get_out_class([c, mc]) is mc.__class__ assert _get_out_class([mc, c]) is mc.__class__ assert _get_out_class([c, c]) is c.__class__ assert _get_out_class([c]) is c.__class__ with pytest.raises(ValueError): _get_out_class([c, q]) with pytest.raises(ValueError): _get_out_class([q, c]) def test_masking_required_exception(): """ Test that outer join, hstack and vstack fail for a mixin column which does not support masking. """ col = table.NdarrayMixin([0, 1, 2, 3]) t1 = table.QTable([[1, 2, 3, 4], col], names=['a', 'b']) t2 = table.QTable([[1, 2], col[:2]], names=['a', 'c']) with pytest.raises(NotImplementedError) as err: table.vstack([t1, t2], join_type='outer') assert 'vstack unavailable' in str(err.value) with pytest.raises(NotImplementedError) as err: table.hstack([t1, t2], join_type='outer') assert 'hstack requires masking' in str(err.value) with pytest.raises(NotImplementedError) as err: table.join(t1, t2, join_type='outer') assert 'join requires masking' in str(err.value) def test_stack_columns(): c = table.Column([1, 2]) mc = table.MaskedColumn([1, 2]) q = [1, 2] * u.m time = Time(['2001-01-02T12:34:56', '2001-02-03T00:01:02']) sc = SkyCoord([1, 2], [3, 4], unit='deg') cq = table.Column([11, 22], unit=u.m) t = table.hstack([c, q]) assert t.__class__ is table.QTable assert t.masked is False t = table.hstack([q, c]) assert t.__class__ is table.QTable assert t.masked is False t = table.hstack([mc, q]) assert t.__class__ is table.QTable assert t.masked is False t = table.hstack([c, mc]) assert t.__class__ is table.Table assert t.masked is False t = table.vstack([q, q]) assert t.__class__ is table.QTable t = table.vstack([c, c]) assert t.__class__ is table.Table t = table.hstack([c, time]) assert t.__class__ is table.Table t = table.hstack([c, sc]) assert t.__class__ is table.Table t = table.hstack([q, time, sc]) assert t.__class__ is table.QTable with pytest.raises(ValueError): table.vstack([c, q]) with pytest.raises(ValueError): t = table.vstack([q, cq]) def test_mixin_join_regression(): # This used to trigger a ValueError: # ValueError: NumPy boolean array indexing assignment cannot assign # 6 input values to the 4 output values where the mask is true t1 = QTable() t1['index'] = [1, 2, 3, 4, 5] t1['flux1'] = [2, 3, 2, 1, 1] * u.Jy t1['flux2'] = [2, 3, 2, 1, 1] * u.Jy t2 = QTable() t2['index'] = [3, 4, 5, 6] t2['flux1'] = [2, 1, 1, 3] * u.Jy t2['flux2'] = [2, 1, 1, 3] * u.Jy t12 = table.join(t1, t2, keys=('index', 'flux1', 'flux2'), join_type='outer') assert len(t12) == 6 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/tests/test_pickle.py0000644000175100001710000000737300000000000021071 0ustar00vstsdocker import numpy as np import pickle from astropy.table import Table, Column, MaskedColumn, QTable from astropy.table.table_helpers import simple_table from astropy.units import Quantity, deg from astropy.time import Time from astropy.coordinates import SkyCoord def test_pickle_column(protocol): c = Column(data=[1, 2], name='a', format='%05d', description='col a', unit='cm', meta={'a': 1}) cs = pickle.dumps(c) cp = pickle.loads(cs) assert np.all(cp == c) assert cp.attrs_equal(c) assert cp._parent_table is None assert repr(c) == repr(cp) def test_pickle_masked_column(protocol): c = MaskedColumn(data=[1, 2], name='a', format='%05d', description='col a', unit='cm', meta={'a': 1}) c.mask[1] = True c.fill_value = -99 cs = pickle.dumps(c) cp = pickle.loads(cs) assert np.all(cp._data == c._data) assert np.all(cp.mask == c.mask) assert cp.attrs_equal(c) assert cp.fill_value == -99 assert cp._parent_table is None assert repr(c) == repr(cp) def test_pickle_multidimensional_column(protocol): """Regression test for https://github.com/astropy/astropy/issues/4098""" a = np.zeros((3, 2)) c = Column(a, name='a') cs = pickle.dumps(c) cp = pickle.loads(cs) assert np.all(c == cp) assert c.shape == cp.shape assert cp.attrs_equal(c) assert repr(c) == repr(cp) def test_pickle_table(protocol): a = Column(data=[1, 2], name='a', format='%05d', description='col a', unit='cm', meta={'a': 1}) b = Column(data=[3.0, 4.0], name='b', format='%05d', description='col b', unit='cm', meta={'b': 1}) for table_class in Table, QTable: t = table_class([a, b], meta={'a': 1, 'b': Quantity(10, unit='s')}) t['c'] = Quantity([1, 2], unit='m') t['d'] = Time(['2001-01-02T12:34:56', '2001-02-03T00:01:02']) t['e'] = SkyCoord([125.0, 180.0] * deg, [-45.0, 36.5] * deg) ts = pickle.dumps(t) tp = pickle.loads(ts) assert tp.__class__ is table_class assert np.all(tp['a'] == t['a']) assert np.all(tp['b'] == t['b']) # test mixin columns assert np.all(tp['c'] == t['c']) assert np.all(tp['d'] == t['d']) assert np.all(tp['e'].ra == t['e'].ra) assert np.all(tp['e'].dec == t['e'].dec) assert type(tp['c']) is type(t['c']) # nopep8 assert type(tp['d']) is type(t['d']) # nopep8 assert type(tp['e']) is type(t['e']) # nopep8 assert tp.meta == t.meta assert type(tp) is type(t) assert isinstance(tp['c'], Quantity if (table_class is QTable) else Column) def test_pickle_masked_table(protocol): a = Column(data=[1, 2], name='a', format='%05d', description='col a', unit='cm', meta={'a': 1}) b = Column(data=[3.0, 4.0], name='b', format='%05d', description='col b', unit='cm', meta={'b': 1}) t = Table([a, b], meta={'a': 1}, masked=True) t['a'].mask[1] = True t['a'].fill_value = -99 ts = pickle.dumps(t) tp = pickle.loads(ts) for colname in ('a', 'b'): for attr in ('_data', 'mask', 'fill_value'): assert np.all(getattr(tp[colname], attr) == getattr(tp[colname], attr)) assert tp['a'].attrs_equal(t['a']) assert tp['b'].attrs_equal(t['b']) assert tp.meta == t.meta def test_pickle_indexed_table(protocol): """ Ensure that any indices that have been added will survive pickling. """ t = simple_table() t.add_index('a') t.add_index(['a', 'b']) ts = pickle.dumps(t) tp = pickle.loads(ts) assert len(t.indices) == len(tp.indices) for index, indexp in zip(t.indices, tp.indices): assert np.all(index.data.data == indexp.data.data) assert index.data.data.colnames == indexp.data.data.colnames ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/tests/test_pprint.py0000644000175100001710000010370000000000000021125 0ustar00vstsdocker# This Python file uses the following encoding: utf-8 # Licensed under a 3-clause BSD style license - see LICENSE.rst import pytest import numpy as np from io import StringIO from astropy import table from astropy.io import ascii from astropy.table import Table, QTable from astropy.table.table_helpers import simple_table from astropy import units as u from astropy.utils import console BIG_WIDE_ARR = np.arange(2000, dtype=np.float64).reshape(100, 20) SMALL_ARR = np.arange(18, dtype=np.int64).reshape(6, 3) @pytest.mark.usefixtures('table_type') class TestMultiD(): def test_multidim(self, table_type): """Test printing with multidimensional column""" arr = [np.array([[1, 2], [10, 20]], dtype=np.int64), np.array([[3, 4], [30, 40]], dtype=np.int64), np.array([[5, 6], [50, 60]], dtype=np.int64)] t = table_type(arr) lines = t.pformat() assert lines == ['col0 [2] col1 [2] col2 [2]', '-------- -------- --------', ' 1 .. 2 3 .. 4 5 .. 6', '10 .. 20 30 .. 40 50 .. 60'] lines = t.pformat(html=True) assert lines == [ f'', '', '', '', '
col0 [2]col1 [2]col2 [2]
1 .. 23 .. 45 .. 6
10 .. 2030 .. 4050 .. 60
'] nbclass = table.conf.default_notebook_table_class masked = 'masked=True ' if t.masked else '' assert t._repr_html_().splitlines() == [ f'
{table_type.__name__} {masked}length=2', f'', '', '', '', '', '
col0 [2]col1 [2]col2 [2]
int64int64int64
1 .. 23 .. 45 .. 6
10 .. 2030 .. 4050 .. 60
'] t = table_type([arr]) lines = t.pformat() assert lines == ['col0 [2,2]', '----------', ' 1 .. 20', ' 3 .. 40', ' 5 .. 60'] def test_fake_multidim(self, table_type): """Test printing with 'fake' multidimensional column""" arr = [np.array([[(1,)], [(10,)]], dtype=np.int64), np.array([[(3,)], [(30,)]], dtype=np.int64), np.array([[(5,)], [(50,)]], dtype=np.int64)] t = table_type(arr) lines = t.pformat() assert lines == ['col0 [1,1] col1 [1,1] col2 [1,1]', '---------- ---------- ----------', ' 1 3 5', ' 10 30 50'] lines = t.pformat(html=True) assert lines == [ f'', '', '', '', '
col0 [1,1]col1 [1,1]col2 [1,1]
135
103050
'] nbclass = table.conf.default_notebook_table_class masked = 'masked=True ' if t.masked else '' assert t._repr_html_().splitlines() == [ f'
{table_type.__name__} {masked}length=2', f'', '', '', '', '', '
col0 [1,1]col1 [1,1]col2 [1,1]
int64int64int64
135
103050
'] t = table_type([arr]) lines = t.pformat() assert lines == ['col0 [2,1,1]', '------------', ' 1 .. 10', ' 3 .. 30', ' 5 .. 50'] def test_html_escaping(): t = table.Table([('', 2, 3)]) nbclass = table.conf.default_notebook_table_class assert t._repr_html_().splitlines() == [ '
Table length=3', f'', '', '', '', '', '', '
col0
str33
<script>alert("gotcha");</script>
2
3
'] @pytest.mark.usefixtures('table_type') class TestPprint(): def _setup(self, table_type): self.tb = table_type(BIG_WIDE_ARR) self.tb['col0'].format = 'e' self.tb['col1'].format = '.6f' self.tb['col0'].unit = 'km**2' self.tb['col19'].unit = 'kg s m**-2' self.ts = table_type(SMALL_ARR) def test_empty_table(self, table_type): t = table_type() lines = t.pformat() assert lines == [''] c = repr(t) masked = 'masked=True ' if t.masked else '' assert c.splitlines() == [f'<{table_type.__name__} {masked}length=0>', ''] def test_format0(self, table_type): """Try getting screen size but fail to defaults because testing doesn't have access to screen (fcntl.ioctl fails). """ self._setup(table_type) arr = np.arange(4000, dtype=np.float64).reshape(100, 40) lines = table_type(arr).pformat() nlines, width = console.terminal_size() assert len(lines) == nlines for line in lines[:-1]: # skip last "Length = .. rows" line assert width - 10 < len(line) <= width def test_format1(self, table_type): """Basic test of formatting, unit header row included""" self._setup(table_type) lines = self.tb.pformat(max_lines=8, max_width=40) assert lines == [' col0 col1 ... col19 ', ' km2 ... kg s / m2', '------------ ----------- ... ---------', '0.000000e+00 1.000000 ... 19.0', ' ... ... ... ...', '1.960000e+03 1961.000000 ... 1979.0', '1.980000e+03 1981.000000 ... 1999.0', 'Length = 100 rows'] def test_format2(self, table_type): """Basic test of formatting, unit header row excluded""" self._setup(table_type) lines = self.tb.pformat(max_lines=8, max_width=40, show_unit=False) assert lines == [' col0 col1 ... col19 ', '------------ ----------- ... ------', '0.000000e+00 1.000000 ... 19.0', '2.000000e+01 21.000000 ... 39.0', ' ... ... ... ...', '1.960000e+03 1961.000000 ... 1979.0', '1.980000e+03 1981.000000 ... 1999.0', 'Length = 100 rows'] def test_format3(self, table_type): """Include the unit header row""" self._setup(table_type) lines = self.tb.pformat(max_lines=8, max_width=40, show_unit=True) assert lines == [' col0 col1 ... col19 ', ' km2 ... kg s / m2', '------------ ----------- ... ---------', '0.000000e+00 1.000000 ... 19.0', ' ... ... ... ...', '1.960000e+03 1961.000000 ... 1979.0', '1.980000e+03 1981.000000 ... 1999.0', 'Length = 100 rows'] def test_format4(self, table_type): """Do not include the name header row""" self._setup(table_type) lines = self.tb.pformat(max_lines=8, max_width=40, show_name=False) assert lines == [' km2 ... kg s / m2', '------------ ----------- ... ---------', '0.000000e+00 1.000000 ... 19.0', '2.000000e+01 21.000000 ... 39.0', ' ... ... ... ...', '1.960000e+03 1961.000000 ... 1979.0', '1.980000e+03 1981.000000 ... 1999.0', 'Length = 100 rows'] def test_noclip(self, table_type): """Basic table print""" self._setup(table_type) lines = self.ts.pformat(max_lines=-1, max_width=-1) assert lines == ['col0 col1 col2', '---- ---- ----', ' 0 1 2', ' 3 4 5', ' 6 7 8', ' 9 10 11', ' 12 13 14', ' 15 16 17'] def test_clip1(self, table_type): """max lines below hard limit of 8 """ self._setup(table_type) lines = self.ts.pformat(max_lines=3, max_width=-1) assert lines == ['col0 col1 col2', '---- ---- ----', ' 0 1 2', ' 3 4 5', ' 6 7 8', ' 9 10 11', ' 12 13 14', ' 15 16 17'] def test_clip2(self, table_type): """max lines below hard limit of 8 and output longer than 8 """ self._setup(table_type) lines = self.ts.pformat(max_lines=3, max_width=-1, show_unit=True, show_dtype=True) assert lines == [' col0 col1 col2', ' ', 'int64 int64 int64', '----- ----- -----', ' 0 1 2', ' ... ... ...', ' 15 16 17', 'Length = 6 rows'] def test_clip3(self, table_type): """Max lines below hard limit of 8 and max width below hard limit of 10 """ self._setup(table_type) lines = self.ts.pformat(max_lines=3, max_width=1, show_unit=True) assert lines == ['col0 ...', ' ...', '---- ...', ' 0 ...', ' ... ...', ' 12 ...', ' 15 ...', 'Length = 6 rows'] def test_clip4(self, table_type): """Test a range of max_lines""" self._setup(table_type) for max_lines in (0, 1, 4, 5, 6, 7, 8, 100, 101, 102, 103, 104, 130): lines = self.tb.pformat(max_lines=max_lines, show_unit=False) assert len(lines) == max(8, min(102, max_lines)) def test_pformat_all(self, table_type): """Test that all rows are printed by default""" self._setup(table_type) lines = self.tb.pformat_all() # +3 accounts for the three header lines in this table assert len(lines) == BIG_WIDE_ARR.shape[0] + 3 @pytest.fixture def test_pprint_all(self, table_type, capsys): """Test that all rows are printed by default""" self._setup(table_type) self.tb.pprint_all() (out, err) = capsys.readouterr() # +3 accounts for the three header lines in this table assert len(out) == BIG_WIDE_ARR.shape[0] + 3 @pytest.mark.usefixtures('table_type') class TestFormat(): def test_column_format(self, table_type): t = table_type([[1, 2], [3, 4]], names=('a', 'b')) # default (format=None) assert str(t['a']) == ' a \n---\n 1\n 2' # just a plain format string t['a'].format = '5.2f' assert str(t['a']) == ' a \n-----\n 1.00\n 2.00' # Old-style that is almost new-style t['a'].format = '{ %4.2f }' assert str(t['a']) == ' a \n--------\n{ 1.00 }\n{ 2.00 }' # New-style that is almost old-style t['a'].format = '%{0:}' assert str(t['a']) == ' a \n---\n %1\n %2' # New-style with extra spaces t['a'].format = ' {0:05d} ' assert str(t['a']) == ' a \n-------\n 00001 \n 00002 ' # New-style has precedence t['a'].format = '%4.2f {0:}' assert str(t['a']) == ' a \n-------\n%4.2f 1\n%4.2f 2' # Invalid format spec with pytest.raises(ValueError): t['a'].format = 'fail' assert t['a'].format == '%4.2f {0:}' # format did not change def test_column_format_with_threshold(self, table_type): from astropy import conf with conf.set_temp('max_lines', 8): t = table_type([np.arange(20)], names=['a']) t['a'].format = '%{0:}' assert str(t['a']).splitlines() == [' a ', '---', ' %0', ' %1', '...', '%18', '%19', 'Length = 20 rows'] t['a'].format = '{ %4.2f }' assert str(t['a']).splitlines() == [' a ', '---------', ' { 0.00 }', ' { 1.00 }', ' ...', '{ 18.00 }', '{ 19.00 }', 'Length = 20 rows'] def test_column_format_func(self, table_type): # run most of functions twice # 1) astropy.table.pprint._format_funcs gets populated # 2) astropy.table.pprint._format_funcs gets used t = table_type([[1., 2.], [3, 4]], names=('a', 'b')) # mathematical function t['a'].format = lambda x: str(x * 3.) assert str(t['a']) == ' a \n---\n3.0\n6.0' assert str(t['a']) == ' a \n---\n3.0\n6.0' def test_column_format_callable(self, table_type): # run most of functions twice # 1) astropy.table.pprint._format_funcs gets populated # 2) astropy.table.pprint._format_funcs gets used t = table_type([[1., 2.], [3, 4]], names=('a', 'b')) # mathematical function class format: def __call__(self, x): return str(x * 3.) t['a'].format = format() assert str(t['a']) == ' a \n---\n3.0\n6.0' assert str(t['a']) == ' a \n---\n3.0\n6.0' def test_column_format_func_wrong_number_args(self, table_type): t = table_type([[1., 2.], [3, 4]], names=('a', 'b')) # function that expects wrong number of arguments def func(a, b): pass with pytest.raises(ValueError): t['a'].format = func def test_column_format_func_multiD(self, table_type): arr = [np.array([[1, 2], [10, 20]])] t = table_type(arr, names=['a']) # mathematical function t['a'].format = lambda x: str(x * 3.) outstr = ' a [2] \n------------\n 3.0 .. 6.0\n30.0 .. 60.0' assert str(t['a']) == outstr assert str(t['a']) == outstr def test_column_format_func_not_str(self, table_type): t = table_type([[1., 2.], [3, 4]], names=('a', 'b')) # mathematical function with pytest.raises(ValueError): t['a'].format = lambda x: x * 3 def test_column_alignment(self, table_type): t = table_type([[1], [2], [3], [4]], names=('long title a', 'long title b', 'long title c', 'long title d')) t['long title a'].format = '<' t['long title b'].format = '^' t['long title c'].format = '>' t['long title d'].format = '0=' assert str(t['long title a']) == 'long title a\n------------\n1 ' assert str(t['long title b']) == 'long title b\n------------\n 2 ' assert str(t['long title c']) == 'long title c\n------------\n 3' assert str(t['long title d']) == 'long title d\n------------\n000000000004' class TestFormatWithMaskedElements(): def test_column_format(self): t = Table([[1, 2, 3], [3, 4, 5]], names=('a', 'b'), masked=True) t['a'].mask = [True, False, True] # default (format=None) assert str(t['a']) == ' a \n---\n --\n 2\n --' # just a plain format string t['a'].format = '5.2f' assert str(t['a']) == ' a \n-----\n --\n 2.00\n --' # Old-style that is almost new-style t['a'].format = '{ %4.2f }' assert str(t['a']) == ' a \n--------\n --\n{ 2.00 }\n --' # New-style that is almost old-style t['a'].format = '%{0:}' assert str(t['a']) == ' a \n---\n --\n %2\n --' # New-style with extra spaces t['a'].format = ' {0:05d} ' assert str(t['a']) == ' a \n-------\n --\n 00002 \n --' # New-style has precedence t['a'].format = '%4.2f {0:}' assert str(t['a']) == ' a \n-------\n --\n%4.2f 2\n --' def test_column_format_with_threshold_masked_table(self): from astropy import conf with conf.set_temp('max_lines', 8): t = Table([np.arange(20)], names=['a'], masked=True) t['a'].format = '%{0:}' t['a'].mask[0] = True t['a'].mask[-1] = True assert str(t['a']).splitlines() == [' a ', '---', ' --', ' %1', '...', '%18', ' --', 'Length = 20 rows'] t['a'].format = '{ %4.2f }' assert str(t['a']).splitlines() == [' a ', '---------', ' --', ' { 1.00 }', ' ...', '{ 18.00 }', ' --', 'Length = 20 rows'] def test_column_format_func(self): # run most of functions twice # 1) astropy.table.pprint._format_funcs gets populated # 2) astropy.table.pprint._format_funcs gets used t = Table([[1., 2., 3.], [3, 4, 5]], names=('a', 'b'), masked=True) t['a'].mask = [True, False, True] # mathematical function t['a'].format = lambda x: str(x * 3.) assert str(t['a']) == ' a \n---\n --\n6.0\n --' assert str(t['a']) == ' a \n---\n --\n6.0\n --' def test_column_format_func_with_special_masked(self): # run most of functions twice # 1) astropy.table.pprint._format_funcs gets populated # 2) astropy.table.pprint._format_funcs gets used t = Table([[1., 2., 3.], [3, 4, 5]], names=('a', 'b'), masked=True) t['a'].mask = [True, False, True] # mathematical function def format_func(x): if x is np.ma.masked: return '!!' else: return str(x * 3.) t['a'].format = format_func assert str(t['a']) == ' a \n---\n !!\n6.0\n !!' assert str(t['a']) == ' a \n---\n !!\n6.0\n !!' def test_column_format_callable(self): # run most of functions twice # 1) astropy.table.pprint._format_funcs gets populated # 2) astropy.table.pprint._format_funcs gets used t = Table([[1., 2., 3.], [3, 4, 5]], names=('a', 'b'), masked=True) t['a'].mask = [True, False, True] # mathematical function class format: def __call__(self, x): return str(x * 3.) t['a'].format = format() assert str(t['a']) == ' a \n---\n --\n6.0\n --' assert str(t['a']) == ' a \n---\n --\n6.0\n --' def test_column_format_func_wrong_number_args(self): t = Table([[1., 2.], [3, 4]], names=('a', 'b'), masked=True) t['a'].mask = [True, False] # function that expects wrong number of arguments def func(a, b): pass with pytest.raises(ValueError): t['a'].format = func # but if all are masked, it never gets called t['a'].mask = [True, True] assert str(t['a']) == ' a \n---\n --\n --' def test_column_format_func_multiD(self): arr = [np.array([[1, 2], [10, 20]])] t = Table(arr, names=['a'], masked=True) t['a'].mask[0, 1] = True t['a'].mask[1, 1] = True # mathematical function t['a'].format = lambda x: str(x * 3.) outstr = ' a [2] \n----------\n 3.0 .. --\n30.0 .. --' assert str(t['a']) == outstr assert str(t['a']) == outstr def test_pprint_npfloat32(): """ Test for #148, that np.float32 cannot by itself be formatted as float, but has to be converted to a python float. """ dat = np.array([1., 2.], dtype=np.float32) t = Table([dat], names=['a']) t['a'].format = '5.2f' assert str(t['a']) == ' a \n-----\n 1.00\n 2.00' def test_pprint_py3_bytes(): """ Test for #1346 and #4944. Make sure a bytestring (dtype=S) in Python 3 is printed correctly (without the "b" prefix like b'string'). """ val = bytes('val', encoding='utf-8') blah = 'bläh'.encode('utf-8') dat = np.array([val, blah], dtype=[('col', 'S10')]) t = table.Table(dat) assert t['col'].pformat() == ['col ', '----', ' val', 'bläh'] def test_pprint_nameless_col(): """Regression test for #2213, making sure a nameless column can be printed using None as the name. """ col = table.Column([1., 2.]) assert str(col).startswith('None') def test_html(): """Test HTML printing""" dat = np.array([1., 2.], dtype=np.float32) t = Table([dat], names=['a']) lines = t.pformat(html=True) assert lines == [f'', '', '', '', '
a
1.0
2.0
'] lines = t.pformat(html=True, tableclass='table-striped') assert lines == [ f'', '', '', '', '
a
1.0
2.0
'] lines = t.pformat(html=True, tableclass=['table', 'table-striped']) assert lines == [ f'', '', '', '', '
a
1.0
2.0
'] def test_align(): t = simple_table(2, kinds='iS') assert t.pformat() == [' a b ', '--- ---', ' 1 b', ' 2 c'] # Use column format attribute t['a'].format = '<' assert t.pformat() == [' a b ', '--- ---', '1 b', '2 c'] # Now override column format attribute with various combinations of align tpf = [' a b ', '--- ---', ' 1 b ', ' 2 c '] for align in ('^', ['^', '^'], ('^', '^')): assert tpf == t.pformat(align=align) assert t.pformat(align='<') == [' a b ', '--- ---', '1 b ', '2 c '] assert t.pformat(align='0=') == [' a b ', '--- ---', '001 00b', '002 00c'] assert t.pformat(align=['<', '^']) == [' a b ', '--- ---', '1 b ', '2 c '] # Now use fill characters. Stress the system using a fill # character that is the same as an align character. t = simple_table(2, kinds='iS') assert t.pformat(align='^^') == [' a b ', '--- ---', '^1^ ^b^', '^2^ ^c^'] assert t.pformat(align='^>') == [' a b ', '--- ---', '^^1 ^^b', '^^2 ^^c'] assert t.pformat(align='^<') == [' a b ', '--- ---', '1^^ b^^', '2^^ c^^'] # Complicated interaction (same as narrative docs example) t1 = Table([[1.0, 2.0], [1, 2]], names=['column1', 'column2']) t1['column1'].format = '#^.2f' assert t1.pformat() == ['column1 column2', '------- -------', '##1.00# 1', '##2.00# 2'] assert t1.pformat(align='!<') == ['column1 column2', '------- -------', '1.00!!! 1!!!!!!', '2.00!!! 2!!!!!!'] assert t1.pformat(align=[None, '!<']) == ['column1 column2', '------- -------', '##1.00# 1!!!!!!', '##2.00# 2!!!!!!'] # Zero fill t['a'].format = '+d' assert t.pformat(align='0=') == [' a b ', '--- ---', '+01 00b', '+02 00c'] with pytest.raises(ValueError): t.pformat(align=['fail']) with pytest.raises(TypeError): t.pformat(align=0) with pytest.raises(TypeError): t.pprint(align=0) # Make sure pprint() does not raise an exception t.pprint() with pytest.raises(ValueError): t.pprint(align=['<', '<', '<']) with pytest.raises(ValueError): t.pprint(align='x=') def test_auto_format_func(): """Test for #5802 (fix for #5800 where format_func key is not unique)""" t = Table([[1, 2] * u.m]) t['col0'].format = '%f' t.pformat() # Force caching of format function qt = QTable(t) qt.pformat() # Generates exception prior to #5802 def test_decode_replace(): """ Test printing a bytestring column with a value that fails decoding to utf-8 and gets replaced by U+FFFD. See https://docs.python.org/3/library/codecs.html#codecs.replace_errors """ t = Table([[b'Z\xf0']]) assert t.pformat() == ['col0', '----', ' Z\ufffd'] class TestColumnsShowHide: """Tests of show and hide table columns""" def setup_method(self): self.t = simple_table(size=1, cols=4, kinds='i') @pytest.mark.parametrize('attr', ('pprint_exclude_names', 'pprint_include_names')) def test_basic(self, attr): t = self.t assert repr(getattr(Table, attr)) == f'' t_show_hide = getattr(t, attr) assert repr(t_show_hide) == f'' # Default value is None assert t_show_hide() is None def test_slice(self): t = self.t t.pprint_include_names = 'a' t.pprint_exclude_names = 'b' t2 = t[0:1] assert t2.pprint_include_names() == ('a',) assert t2.pprint_exclude_names() == ('b',) def test_copy(self): t = self.t t.pprint_include_names = 'a' t.pprint_exclude_names = 'b' t2 = t.copy() assert t2.pprint_include_names() == ('a',) assert t2.pprint_exclude_names() == ('b',) t2.pprint_include_names = 'c' t2.pprint_exclude_names = 'd' assert t.pprint_include_names() == ('a',) assert t.pprint_exclude_names() == ('b',) assert t2.pprint_include_names() == ('c',) assert t2.pprint_exclude_names() == ('d',) @pytest.mark.parametrize('attr', ('pprint_exclude_names', 'pprint_include_names')) @pytest.mark.parametrize('value', ('z', ['a', 'z'])) def test_setting(self, attr, value): t = self.t t_show_hide = getattr(t, attr) # Expected attribute value ('z',) or ('a', 'z') exp = (value,) if isinstance(value, str) else tuple(value) # Context manager, can include column names that do not exist with t_show_hide.set(value): assert t_show_hide() == exp assert t.meta['__attributes__'] == {attr: exp} assert t_show_hide() is None # Setting back to None clears out meta assert t.meta == {} # Do `t.pprint_include_names/hide = value` setattr(t, attr, value) assert t_show_hide() == exp # Clear attribute t_show_hide.set(None) assert t_show_hide() is None # Now use set() method t_show_hide.set(value) assert t_show_hide() == exp with t_show_hide.set(None): assert t_show_hide() is None assert t.meta == {} assert t_show_hide() == exp @pytest.mark.parametrize('attr', ('pprint_exclude_names', 'pprint_include_names')) @pytest.mark.parametrize('value', ('z', ['a', 'z'], ('a', 'z'))) def test_add_remove(self, attr, value): t = self.t t_show_hide = getattr(t, attr) # Expected attribute value ('z') or ('a', 'z') exp = (value,) if isinstance(value, str) else tuple(value) # add() method for str or list of str t_show_hide.add(value) assert t_show_hide() == exp # Adding twice has no effect t_show_hide.add(value) assert t_show_hide() == exp # Remove values (str or list of str). Reverts to None if all names are # removed. t_show_hide.remove(value) assert t_show_hide() is None # Remove just one name, possibly leaving a name. t_show_hide.add(value) t_show_hide.remove('z') assert t_show_hide() == (None if value == 'z' else ('a',)) # Cannot remove name not in the list t_show_hide.set(['a', 'z']) with pytest.raises(ValueError, match=f'x not in {attr}'): t_show_hide.remove(('x', 'z')) @pytest.mark.parametrize('attr', ('pprint_exclude_names', 'pprint_include_names')) def test_rename(self, attr): t = self.t t_hide_show = getattr(t, attr) t_hide_show.set(['a', 'b']) t.rename_column('a', 'aa') assert t_hide_show() == ('aa', 'b') @pytest.mark.parametrize('attr', ('pprint_exclude_names', 'pprint_include_names')) def test_remove(self, attr): t = self.t t_hide_show = getattr(t, attr) t_hide_show.set(['a', 'b']) del t['a'] assert t_hide_show() == ('b',) def test_serialization(self): # Serialization works for ECSV. Currently fails for FITS, works with # HDF5. t = self.t t.pprint_exclude_names = ['a', 'y'] t.pprint_include_names = ['b', 'z'] out = StringIO() ascii.write(t, out, format='ecsv') t2 = ascii.read(out.getvalue(), format='ecsv') assert t2.pprint_exclude_names() == ('a', 'y') assert t2.pprint_include_names() == ('b', 'z') def test_output(self): """Test that pprint_include/exclude_names actually changes the print output""" t = self.t exp = [' b d ', '--- ---', ' 2 4'] with t.pprint_exclude_names.set(['a', 'c']): out = t.pformat_all() assert out == exp with t.pprint_include_names.set(['b', 'd']): out = t.pformat_all() assert out == exp with t.pprint_exclude_names.set(['a', 'c']): out = t.pformat_all() assert out == exp with t.pprint_include_names.set(['b', 'd']): out = t.pformat_all() assert out == exp # Mixture (not common in practice but possible). Note, the trailing # backslash instead of parens is needed for Python < 3.9. See: # https://bugs.python.org/issue12782. with t.pprint_include_names.set(['b', 'c', 'd']), \ t.pprint_exclude_names.set(['c']): out = t.pformat_all() assert out == exp def test_output_globs(self): """Test that pprint_include/exclude_names works with globs (fnmatch)""" t = self.t t['a2'] = 1 t['a23'] = 2 # Show only the a* columns exp = [' a a2 a23', '--- --- ---', ' 1 1 2'] with t.pprint_include_names.set('a*'): out = t.pformat_all() assert out == exp # Show a* but exclude a?? exp = [' a a2', '--- ---', ' 1 1'] with t.pprint_include_names.set('a*'), t.pprint_exclude_names.set('a??'): out = t.pformat_all() assert out == exp # Exclude a?? exp = [' a b c d a2', '--- --- --- --- ---', ' 1 2 3 4 1'] with t.pprint_exclude_names.set('a??'): out = t.pformat_all() assert out == exp ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/tests/test_row.py0000644000175100001710000002772100000000000020430 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import sys import pytest import numpy as np from astropy import table from astropy.table import Row from astropy import units as u from .conftest import MaskedTable def test_masked_row_with_object_col(): """ Numpy < 1.8 has a bug in masked array that prevents access a row if there is a column with object type. """ t = table.Table([[1]], dtype=['O'], masked=True) t['col0'].mask = False assert t[0]['col0'] == 1 t['col0'].mask = True assert t[0]['col0'] is np.ma.masked @pytest.mark.usefixtures('table_types') class TestRow(): def _setup(self, table_types): self._table_type = table_types.Table self._column_type = table_types.Column @property def t(self): # pytest wants to run this method once before table_types is run # to set Table and Column. In this case just return None, which would # cause any downstream test to fail if this happened in any other context. if self._column_type is None: return None if not hasattr(self, '_t'): a = self._column_type(name='a', data=[1, 2, 3], dtype='i8') b = self._column_type(name='b', data=[4, 5, 6], dtype='i8') self._t = self._table_type([a, b]) return self._t def test_subclass(self, table_types): """Row is subclass of ndarray and Row""" self._setup(table_types) c = Row(self.t, 2) assert isinstance(c, Row) def test_values(self, table_types): """Row accurately reflects table values and attributes""" self._setup(table_types) table = self.t row = table[1] assert row['a'] == 2 assert row['b'] == 5 assert row[0] == 2 assert row[1] == 5 assert row.meta is table.meta assert row.colnames == table.colnames assert row.columns is table.columns with pytest.raises(IndexError): row[2] if sys.byteorder == 'little': assert str(row.dtype) == "[('a', 'i8'), ('b', '>i8')]" def test_ref(self, table_types): """Row is a reference into original table data""" self._setup(table_types) table = self.t row = table[1] row['a'] = 10 if table_types.Table is not MaskedTable: assert table['a'][1] == 10 def test_left_equal(self, table_types): """Compare a table row to the corresponding structured array row""" self._setup(table_types) np_t = self.t.as_array() if table_types.Table is MaskedTable: with pytest.raises(ValueError): self.t[0] == np_t[0] else: for row, np_row in zip(self.t, np_t): assert np.all(row == np_row) def test_left_not_equal(self, table_types): """Compare a table row to the corresponding structured array row""" self._setup(table_types) np_t = self.t.as_array() np_t['a'] = [0, 0, 0] if table_types.Table is MaskedTable: with pytest.raises(ValueError): self.t[0] == np_t[0] else: for row, np_row in zip(self.t, np_t): assert np.all(row != np_row) def test_right_equal(self, table_types): """Test right equal""" self._setup(table_types) np_t = self.t.as_array() if table_types.Table is MaskedTable: with pytest.raises(ValueError): self.t[0] == np_t[0] else: for row, np_row in zip(self.t, np_t): assert np.all(np_row == row) def test_convert_numpy_array(self, table_types): self._setup(table_types) d = self.t[1] np_data = np.array(d) if table_types.Table is not MaskedTable: assert np.all(np_data == d.as_void()) assert np_data is not d.as_void() assert d.colnames == list(np_data.dtype.names) np_data = np.array(d, copy=False) if table_types.Table is not MaskedTable: assert np.all(np_data == d.as_void()) assert np_data is not d.as_void() assert d.colnames == list(np_data.dtype.names) with pytest.raises(ValueError): np_data = np.array(d, dtype=[('c', 'i8'), ('d', 'i8')]) def test_format_row(self, table_types): """Test formatting row""" self._setup(table_types) table = self.t row = table[0] assert repr(row).splitlines() == ['<{} {}{}>' .format(row.__class__.__name__, 'index=0', ' masked=True' if table.masked else ''), ' a b ', 'int64 int64', '----- -----', ' 1 4'] assert str(row).splitlines() == [' a b ', '--- ---', ' 1 4'] assert row._repr_html_().splitlines() == [ '{} {}{}' .format(row.__class__.__name__, 'index=0', ' masked=True' if table.masked else ''), f'', '', '', '', '
ab
int64int64
14
'] def test_as_void(self, table_types): """Test the as_void() method""" self._setup(table_types) table = self.t row = table[0] # If masked then with no masks, issue numpy/numpy#483 should come # into play. Make sure as_void() code is working. row_void = row.as_void() if table.masked: assert isinstance(row_void, np.ma.mvoid) else: assert isinstance(row_void, np.void) assert row_void['a'] == 1 assert row_void['b'] == 4 # Confirm row is a view of table but row_void is not. table['a'][0] = -100 assert row['a'] == -100 assert row_void['a'] == 1 # Make sure it works for a table that has masked elements if table.masked: table['a'].mask = True # row_void is not a view, need to re-make assert row_void['a'] == 1 row_void = row.as_void() # but row is a view assert row['a'] is np.ma.masked def test_row_and_as_void_with_objects(self, table_types): """Test the deprecated data property and as_void() method""" t = table_types.Table([[{'a': 1}, {'b': 2}]], names=('a',)) assert t[0][0] == {'a': 1} assert t[0]['a'] == {'a': 1} assert t[0].as_void()[0] == {'a': 1} assert t[0].as_void()['a'] == {'a': 1} def test_bounds_checking(self, table_types): """Row gives index error upon creation for out-of-bounds index""" self._setup(table_types) for ibad in (-5, -4, 3, 4): with pytest.raises(IndexError): self.t[ibad] def test_create_rows_from_list(self, table_types): """https://github.com/astropy/astropy/issues/8976""" orig_tab = table_types.Table([[1, 2, 3], [4, 5, 6]], names=('a', 'b')) new_tab = type(orig_tab)(rows=[row for row in orig_tab], names=orig_tab.dtype.names) assert np.all(orig_tab == new_tab) def test_row_keys_values(self, table_types): self._setup(table_types) row = self.t[0] for row_key, col_key in zip(row.keys(), self.t.columns.keys()): assert row_key == col_key for row_value, col in zip(row.values(), self.t.columns.values()): assert row_value == col[0] def test_row_as_mapping(self, table_types): self._setup(table_types) row = self.t[0] row_dict = dict(row) for key, value in row_dict.items(): assert row[key] == value def f(**kwargs): return kwargs row_splatted = f(**row) for key, value in row_splatted.items(): assert row[key] == value def test_row_as_sequence(self, table_types): self._setup(table_types) row = self.t[0] row_tuple = tuple(row) keys = tuple(row.keys()) for key, value in zip(keys, row_tuple): assert row[key] == value def f(*args): return args row_splatted = f(*row) for key, value in zip(keys, row_splatted): assert row[key] == value def test_row_tuple_column_slice(): """ Test getting and setting a row using a tuple or list of column names """ t = table.QTable([[1, 2, 3] * u.m, [10., 20., 30.], [100., 200., 300.], ['x', 'y', 'z']], names=['a', 'b', 'c', 'd']) # Get a row for index=1 r1 = t[1] # Column slice with tuple of col names r1_abc = r1['a', 'b', 'c'] # Row object for these cols r1_abc_repr = ['', ' a b c ', ' m ', 'float64 float64 float64', '------- ------- -------', ' 2.0 20.0 200.0'] assert repr(r1_abc).splitlines() == r1_abc_repr # Column slice with list of col names r1_abc = r1[['a', 'b', 'c']] assert repr(r1_abc).splitlines() == r1_abc_repr # Make sure setting on a tuple or slice updates parent table and row r1['c'] = 1000 r1['a', 'b'] = 1000 * u.cm, 100. assert r1['a'] == 10 * u.m assert r1['b'] == 100 assert t['a'][1] == 10 * u.m assert t['b'][1] == 100. assert t['c'][1] == 1000 # Same but using a list of column names instead of tuple r1[['a', 'b']] = 2000 * u.cm, 200. assert r1['a'] == 20 * u.m assert r1['b'] == 200 assert t['a'][1] == 20 * u.m assert t['b'][1] == 200. # Set column slice of column slice r1_abc['a', 'c'] = -1 * u.m, -10 assert t['a'][1] == -1 * u.m assert t['b'][1] == 200. assert t['c'][1] == -10. # Bad column name with pytest.raises(KeyError) as err: t[1]['a', 'not_there'] assert "'not_there'" in str(err.value) # Too many values with pytest.raises(ValueError) as err: t[1]['a', 'b'] = 1 * u.m, 2, 3 assert 'right hand side must be a sequence' in str(err.value) # Something without a length with pytest.raises(ValueError) as err: t[1]['a', 'b'] = 1 assert 'right hand side must be a sequence' in str(err.value) def test_row_tuple_column_slice_transaction(): """ Test that setting a row that fails part way through does not change the table at all. """ t = table.QTable([[10., 20., 30.], [1, 2, 3] * u.m], names=['a', 'b']) tc = t.copy() # First one succeeds but second fails. with pytest.raises(ValueError) as err: t[1]['a', 'b'] = (-1, -1 * u.s) # Bad unit assert "'s' (time) and 'm' (length) are not convertible" in str(err.value) assert t[1] == tc[1] def test_uint_indexing(): """ Test that accessing a row with an unsigned integer works as with a signed integer. Similarly tests that printing such a row works. This is non-trivial: adding a signed and unsigned integer in numpy results in a float, which is an invalid slice index. Regression test for gh-7464. """ t = table.Table([[1., 2., 3.]], names='a') assert t['a'][1] == 2. assert t['a'][np.int_(1)] == 2. assert t['a'][np.uint(1)] == 2. assert t[np.uint(1)]['a'] == 2. trepr = ['', ' a ', 'float64', '-------', ' 2.0'] assert repr(t[1]).splitlines() == trepr assert repr(t[np.int_(1)]).splitlines() == trepr assert repr(t[np.uint(1)]).splitlines() == trepr ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/tests/test_showtable.py0000644000175100001710000001377700000000000021617 0ustar00vstsdockerimport os import re from astropy.table.scripts import showtable ROOT = os.path.abspath(os.path.dirname(__file__)) ASCII_ROOT = os.path.join(ROOT, '..', '..', 'io', 'ascii', 'tests') FITS_ROOT = os.path.join(ROOT, '..', '..', 'io', 'fits', 'tests') VOTABLE_ROOT = os.path.join(ROOT, '..', '..', 'io', 'votable', 'tests') def test_missing_file(capsys): showtable.main(['foobar.fits']) out, err = capsys.readouterr() assert err.startswith("ERROR: [Errno 2] No such file or directory: " "'foobar.fits'") def test_info(capsys): showtable.main([os.path.join(FITS_ROOT, 'data/table.fits'), '--info']) out, err = capsys.readouterr() assert out.splitlines() == ['', ' name dtype ', '------ -------', 'target bytes20', ' V_mag float32'] def test_stats(capsys): showtable.main([os.path.join(FITS_ROOT, 'data/table.fits'), '--stats']) out, err = capsys.readouterr() expected = ['
', ' name mean std min max ', '------ ------- ------- ---- ----', 'target -- -- -- --', ' V_mag 12.866[0-9]? 1.72111 11.1 15.2'] out = out.splitlines() assert out[:4] == expected[:4] # Here we use re.match as in some cases one of the values above is # platform-dependent. assert re.match(expected[4], out[4]) is not None def test_fits(capsys): showtable.main([os.path.join(FITS_ROOT, 'data/table.fits')]) out, err = capsys.readouterr() assert out.splitlines() == [' target V_mag', '------- -----', 'NGC1001 11.1', 'NGC1002 12.3', 'NGC1003 15.2'] def test_fits_hdu(capsys): showtable.main([os.path.join(FITS_ROOT, 'data/zerowidth.fits'), '--hdu', 'AIPS OF']) out, err = capsys.readouterr() assert out.startswith( ' TIME SOURCE ID ANTENNA NO. SUBARRAY FREQ ID ANT FLAG STATUS 1\n' ' DAYS \n' '---------- --------- ----------- -------- ------- -------- --------\n' '0.14438657 1 10 1 1 4 4\n') def test_csv(capsys): showtable.main([os.path.join(ASCII_ROOT, 'data/simple_csv.csv')]) out, err = capsys.readouterr() assert out.splitlines() == [' a b c ', '--- --- ---', ' 1 2 3', ' 4 5 6'] def test_ascii_format(capsys): showtable.main([os.path.join(ASCII_ROOT, 'data/commented_header.dat'), '--format', 'ascii.commented_header']) out, err = capsys.readouterr() assert out.splitlines() == [' a b c ', '--- --- ---', ' 1 2 3', ' 4 5 6'] def test_ascii_delimiter(capsys): showtable.main([os.path.join(ASCII_ROOT, 'data/simple2.txt'), '--format', 'ascii', '--delimiter', '|']) out, err = capsys.readouterr() assert out.splitlines() == [ "obsid redshift X Y object rad ", "----- -------- ---- ---- ----------- ----", " 3102 0.32 4167 4085 Q1250+568-A 9.0", " 3102 0.32 4706 3916 Q1250+568-B 14.0", " 877 0.22 4378 3892 'Source 82' 12.5", ] def test_votable(capsys): showtable.main([os.path.join(VOTABLE_ROOT, 'data/regression.xml'), '--table-id', 'main_table', '--max-width', '50']) out, err = capsys.readouterr() assert out.splitlines() == [ ' string_test string_test_2 ... bitarray2 [16]', '----------------- ------------- ... --------------', ' String & test Fixed stri ... True .. False', 'String & test 0123456789 ... -- .. --', ' XXXX XXXX ... -- .. --', ' ... -- .. --', ' ... -- .. --', ] def test_max_lines(capsys): showtable.main([os.path.join(ASCII_ROOT, 'data/cds2.dat'), '--format', 'ascii.cds', '--max-lines', '7', '--max-width', '30']) out, err = capsys.readouterr() assert out.splitlines() == [ ' SST ... Note', ' ... ', '--------------- ... ----', '041314.1+281910 ... --', ' ... ... ...', '044427.1+251216 ... --', '044642.6+245903 ... --', 'Length = 215 rows', ] def test_show_dtype(capsys): showtable.main([os.path.join(FITS_ROOT, 'data/table.fits'), '--show-dtype']) out, err = capsys.readouterr() assert out.splitlines() == [ ' target V_mag ', 'bytes20 float32', '------- -------', 'NGC1001 11.1', 'NGC1002 12.3', 'NGC1003 15.2', ] def test_hide_unit(capsys): showtable.main([os.path.join(ASCII_ROOT, 'data/cds.dat'), '--format', 'ascii.cds']) out, err = capsys.readouterr() assert out.splitlines() == [ 'Index RAh RAm RAs DE- DEd DEm DEs Match Class AK Fit ', ' h min s deg arcmin arcsec mag GMsun', '----- --- --- ----- --- --- ------ ------ ----- ----- --- -----', ' 1 3 28 39.09 + 31 6 1.9 -- I* -- 1.35', ] showtable.main([os.path.join(ASCII_ROOT, 'data/cds.dat'), '--format', 'ascii.cds', '--hide-unit']) out, err = capsys.readouterr() assert out.splitlines() == [ 'Index RAh RAm RAs DE- DEd DEm DEs Match Class AK Fit ', '----- --- --- ----- --- --- --- --- ----- ----- --- ----', ' 1 3 28 39.09 + 31 6 1.9 -- I* -- 1.35', ] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/tests/test_subclass.py0000644000175100001710000000462100000000000021432 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst from astropy import table from astropy.table import pprint class MyRow(table.Row): def __str__(self): return str(self.as_void()) class MyColumn(table.Column): pass class MyMaskedColumn(table.MaskedColumn): pass class MyTableColumns(table.TableColumns): pass class MyTableFormatter(pprint.TableFormatter): pass class MyTable(table.Table): Row = MyRow Column = MyColumn MaskedColumn = MyMaskedColumn TableColumns = MyTableColumns TableFormatter = MyTableFormatter def test_simple_subclass(): t = MyTable([[1, 2], [3, 4]]) row = t[0] assert isinstance(row, MyRow) assert isinstance(t['col0'], MyColumn) assert isinstance(t.columns, MyTableColumns) assert isinstance(t.formatter, MyTableFormatter) t2 = MyTable(t) row = t2[0] assert isinstance(row, MyRow) assert str(row) == '(1, 3)' t3 = table.Table(t) row = t3[0] assert not isinstance(row, MyRow) assert str(row) != '(1, 3)' t = MyTable([[1, 2], [3, 4]], masked=True) row = t[0] assert isinstance(row, MyRow) assert str(row) == '(1, 3)' assert isinstance(t['col0'], MyMaskedColumn) assert isinstance(t.formatter, MyTableFormatter) class ParamsRow(table.Row): """ Row class that allows access to an arbitrary dict of parameters stored as a dict object in the ``params`` column. """ def __getitem__(self, item): if item not in self.colnames: return super().__getitem__('params')[item] else: return super().__getitem__(item) def keys(self): out = [name for name in self.colnames if name != 'params'] params = [key.lower() for key in sorted(self['params'])] return out + params def values(self): return [self[key] for key in self.keys()] class ParamsTable(table.Table): Row = ParamsRow def test_params_table(): t = ParamsTable(names=['a', 'b', 'params'], dtype=['i', 'f', 'O']) t.add_row((1, 2.0, {'x': 1.5, 'y': 2.5})) t.add_row((2, 3.0, {'z': 'hello', 'id': 123123})) assert t['params'][0] == {'x': 1.5, 'y': 2.5} assert t[0]['params'] == {'x': 1.5, 'y': 2.5} assert t[0]['y'] == 2.5 assert t[1]['id'] == 123123 assert list(t[1].keys()) == ['a', 'b', 'id', 'z'] assert list(t[1].values()) == [2, 3.0, 123123, 'hello'] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/table/tests/test_table.py0000644000175100001710000032102300000000000020700 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst from astropy.utils.tests.test_metadata import MetaBaseTest import gc import sys import copy from io import StringIO from collections import OrderedDict import pickle import pytest import numpy as np from numpy.testing import assert_allclose, assert_array_equal from astropy.io import fits from astropy.table import (Table, QTable, Column, MaskedColumn, TableReplaceWarning, TableAttribute) from astropy.tests.helper import assert_follows_unicode_guidelines from astropy.coordinates import SkyCoord from astropy.utils.data import get_pkg_data_filename from astropy.utils.exceptions import AstropyUserWarning from astropy import table from astropy import units as u from astropy.time import Time, TimeDelta from .conftest import MaskedTable, MIXIN_COLS from astropy.utils.compat.optional_deps import HAS_PANDAS # noqa class SetupData: def _setup(self, table_types): self._table_type = table_types.Table self._column_type = table_types.Column @property def a(self): if self._column_type is not None: if not hasattr(self, '_a'): self._a = self._column_type( [1, 2, 3], name='a', format='%d', meta={'aa': [0, 1, 2, 3, 4]}) return self._a @property def b(self): if self._column_type is not None: if not hasattr(self, '_b'): self._b = self._column_type( [4, 5, 6], name='b', format='%d', meta={'aa': 1}) return self._b @property def c(self): if self._column_type is not None: if not hasattr(self, '_c'): self._c = self._column_type([7, 8, 9], 'c') return self._c @property def d(self): if self._column_type is not None: if not hasattr(self, '_d'): self._d = self._column_type([7, 8, 7], 'd') return self._d @property def obj(self): if self._column_type is not None: if not hasattr(self, '_obj'): self._obj = self._column_type([1, 'string', 3], 'obj', dtype='O') return self._obj @property def t(self): if self._table_type is not None: if not hasattr(self, '_t'): self._t = self._table_type([self.a, self.b]) return self._t @pytest.mark.usefixtures('table_types') class TestSetTableColumn(SetupData): def test_set_row(self, table_types): """Set a row from a tuple of values""" self._setup(table_types) t = table_types.Table([self.a, self.b]) t[1] = (20, 21) assert t['a'][0] == 1 assert t['a'][1] == 20 assert t['a'][2] == 3 assert t['b'][0] == 4 assert t['b'][1] == 21 assert t['b'][2] == 6 def test_set_row_existing(self, table_types): """Set a row from another existing row""" self._setup(table_types) t = table_types.Table([self.a, self.b]) t[0] = t[1] assert t[0][0] == 2 assert t[0][1] == 5 def test_set_row_fail_1(self, table_types): """Set a row from an incorrectly-sized or typed set of values""" self._setup(table_types) t = table_types.Table([self.a, self.b]) with pytest.raises(ValueError): t[1] = (20, 21, 22) with pytest.raises(ValueError): t[1] = 0 def test_set_row_fail_2(self, table_types): """Set a row from an incorrectly-typed tuple of values""" self._setup(table_types) t = table_types.Table([self.a, self.b]) with pytest.raises(ValueError): t[1] = ('abc', 'def') def test_set_new_col_new_table(self, table_types): """Create a new column in empty table using the item access syntax""" self._setup(table_types) t = table_types.Table() t['aa'] = self.a # Test that the new column name is 'aa' and that the values match assert np.all(t['aa'] == self.a) assert t.colnames == ['aa'] def test_set_new_col_new_table_quantity(self, table_types): """Create a new column (from a quantity) in empty table using the item access syntax""" self._setup(table_types) t = table_types.Table() t['aa'] = np.array([1, 2, 3]) * u.m assert np.all(t['aa'] == np.array([1, 2, 3])) assert t['aa'].unit == u.m t['bb'] = 3 * u.m assert np.all(t['bb'] == 3) assert t['bb'].unit == u.m def test_set_new_col_existing_table(self, table_types): """Create a new column in an existing table using the item access syntax""" self._setup(table_types) t = table_types.Table([self.a]) # Add a column t['bb'] = self.b assert np.all(t['bb'] == self.b) assert t.colnames == ['a', 'bb'] assert t['bb'].meta == self.b.meta assert t['bb'].format == self.b.format # Add another column t['c'] = t['a'] assert np.all(t['c'] == t['a']) assert t.colnames == ['a', 'bb', 'c'] assert t['c'].meta == t['a'].meta assert t['c'].format == t['a'].format # Add a multi-dimensional column t['d'] = table_types.Column(np.arange(12).reshape(3, 2, 2)) assert t['d'].shape == (3, 2, 2) assert t['d'][0, 0, 1] == 1 # Add column from a list t['e'] = ['hello', 'the', 'world'] assert np.all(t['e'] == np.array(['hello', 'the', 'world'])) # Make sure setting existing column still works t['e'] = ['world', 'hello', 'the'] assert np.all(t['e'] == np.array(['world', 'hello', 'the'])) # Add a column via broadcasting t['f'] = 10 assert np.all(t['f'] == 10) # Add a column from a Quantity t['g'] = np.array([1, 2, 3]) * u.m assert np.all(t['g'].data == np.array([1, 2, 3])) assert t['g'].unit == u.m # Add a column from a (scalar) Quantity t['g'] = 3 * u.m assert np.all(t['g'].data == 3) assert t['g'].unit == u.m def test_set_new_unmasked_col_existing_table(self, table_types): """Create a new column in an existing table using the item access syntax""" self._setup(table_types) t = table_types.Table([self.a]) # masked or unmasked b = table.Column(name='b', data=[1, 2, 3]) # unmasked t['b'] = b assert np.all(t['b'] == b) def test_set_new_masked_col_existing_table(self, table_types): """Create a new column in an existing table using the item access syntax""" self._setup(table_types) t = table_types.Table([self.a]) # masked or unmasked b = table.MaskedColumn(name='b', data=[1, 2, 3]) # masked t['b'] = b assert np.all(t['b'] == b) def test_set_new_col_existing_table_fail(self, table_types): """Generate failure when creating a new column using the item access syntax""" self._setup(table_types) t = table_types.Table([self.a]) # Wrong size with pytest.raises(ValueError): t['b'] = [1, 2] @pytest.mark.usefixtures('table_types') class TestEmptyData(): def test_1(self, table_types): t = table_types.Table() t.add_column(table_types.Column(name='a', dtype=int, length=100)) assert len(t['a']) == 100 def test_2(self, table_types): t = table_types.Table() t.add_column(table_types.Column(name='a', dtype=int, shape=(3, ), length=100)) assert len(t['a']) == 100 def test_3(self, table_types): t = table_types.Table() # length is not given t.add_column(table_types.Column(name='a', dtype=int)) assert len(t['a']) == 0 def test_4(self, table_types): t = table_types.Table() # length is not given t.add_column(table_types.Column(name='a', dtype=int, shape=(3, 4))) assert len(t['a']) == 0 def test_5(self, table_types): t = table_types.Table() t.add_column(table_types.Column(name='a')) # dtype is not specified assert len(t['a']) == 0 def test_scalar(self, table_types): """Test related to #3811 where setting empty tables to scalar values should raise an error instead of having an error raised when accessing the table.""" t = table_types.Table() with pytest.raises(TypeError, match='Empty table cannot have column set to scalar value'): t.add_column(0) def test_add_via_setitem_and_slice(self, table_types): """Test related to #3023 where a MaskedColumn is created with name=None and then gets changed to name='a'. After PR #2790 this test fails without the #3023 fix.""" t = table_types.Table() t['a'] = table_types.Column([1, 2, 3]) t2 = t[:] assert t2.colnames == t.colnames @pytest.mark.usefixtures('table_types') class TestNewFromColumns(): def test_simple(self, table_types): cols = [table_types.Column(name='a', data=[1, 2, 3]), table_types.Column(name='b', data=[4, 5, 6], dtype=np.float32)] t = table_types.Table(cols) assert np.all(t['a'].data == np.array([1, 2, 3])) assert np.all(t['b'].data == np.array([4, 5, 6], dtype=np.float32)) assert type(t['b'][1]) is np.float32 def test_from_np_array(self, table_types): cols = [table_types.Column(name='a', data=np.array([1, 2, 3], dtype=np.int64), dtype=np.float64), table_types.Column(name='b', data=np.array([4, 5, 6], dtype=np.float32))] t = table_types.Table(cols) assert np.all(t['a'] == np.array([1, 2, 3], dtype=np.float64)) assert np.all(t['b'] == np.array([4, 5, 6], dtype=np.float32)) assert type(t['a'][1]) is np.float64 assert type(t['b'][1]) is np.float32 def test_size_mismatch(self, table_types): cols = [table_types.Column(name='a', data=[1, 2, 3]), table_types.Column(name='b', data=[4, 5, 6, 7])] with pytest.raises(ValueError): table_types.Table(cols) def test_name_none(self, table_types): """Column with name=None can init a table whether or not names are supplied""" c = table_types.Column(data=[1, 2], name='c') d = table_types.Column(data=[3, 4]) t = table_types.Table([c, d], names=(None, 'd')) assert t.colnames == ['c', 'd'] t = table_types.Table([c, d]) assert t.colnames == ['c', 'col1'] @pytest.mark.usefixtures('table_types') class TestReverse(): def test_reverse(self, table_types): t = table_types.Table([[1, 2, 3], ['a', 'b', 'cc']]) t.reverse() assert np.all(t['col0'] == np.array([3, 2, 1])) assert np.all(t['col1'] == np.array(['cc', 'b', 'a'])) t2 = table_types.Table(t, copy=False) assert np.all(t2['col0'] == np.array([3, 2, 1])) assert np.all(t2['col1'] == np.array(['cc', 'b', 'a'])) t2 = table_types.Table(t, copy=True) assert np.all(t2['col0'] == np.array([3, 2, 1])) assert np.all(t2['col1'] == np.array(['cc', 'b', 'a'])) t2.sort('col0') assert np.all(t2['col0'] == np.array([1, 2, 3])) assert np.all(t2['col1'] == np.array(['a', 'b', 'cc'])) def test_reverse_big(self, table_types): x = np.arange(10000) y = x + 1 t = table_types.Table([x, y], names=('x', 'y')) t.reverse() assert np.all(t['x'] == x[::-1]) assert np.all(t['y'] == y[::-1]) def test_reverse_mixin(self): """Test reverse for a mixin with no item assignment, fix for #9836""" sc = SkyCoord([1, 2], [3, 4], unit='deg') t = Table([[2, 1], sc], names=['a', 'sc']) t.reverse() assert np.all(t['a'] == [1, 2]) assert np.allclose(t['sc'].ra.to_value('deg'), [2, 1]) @pytest.mark.usefixtures('table_types') class TestRound(): def test_round_int(self, table_types): t = table_types.Table([['a', 'b', 'c'], [1.11, 2.3, 3.0], [1.123456, 2.9876, 3.901]]) t.round() assert np.all(t['col0'] == ['a', 'b', 'c']) assert np.all(t['col1'] == [1., 2., 3.]) assert np.all(t['col2'] == [1., 3., 4.]) def test_round_dict(self, table_types): t = table_types.Table([['a', 'b', 'c'], [1.5, 2.5, 3.0111], [1.123456, 2.9876, 3.901]]) t.round({'col1': 0, 'col2': 3}) assert np.all(t['col0'] == ['a', 'b', 'c']) assert np.all(t['col1'] == [2.0, 2.0, 3.0]) assert np.all(t['col2'] == [1.123, 2.988, 3.901]) def test_round_invalid(self, table_types): t = table_types.Table([[1, 2, 3]]) with pytest.raises(ValueError, match="'decimals' argument must be an int or a dict"): t.round(0.5) def test_round_kind(self, table_types): for typecode in 'bBhHiIlLqQpPefdgFDG': # AllInteger, AllFloat arr = np.array([4, 16], dtype=typecode) t = Table([arr]) col0 = t['col0'] t.round(decimals=-1) # Round to nearest 10 assert np.all(t['col0'] == [0, 20]) assert t['col0'] is col0 @pytest.mark.usefixtures('table_types') class TestColumnAccess(): def test_1(self, table_types): t = table_types.Table() with pytest.raises(KeyError): t['a'] def test_2(self, table_types): t = table_types.Table() t.add_column(table_types.Column(name='a', data=[1, 2, 3])) assert np.all(t['a'] == np.array([1, 2, 3])) with pytest.raises(KeyError): t['b'] # column does not exist def test_itercols(self, table_types): names = ['a', 'b', 'c'] t = table_types.Table([[1], [2], [3]], names=names) for name, col in zip(names, t.itercols()): assert name == col.name assert isinstance(col, table_types.Column) @pytest.mark.usefixtures('table_types') class TestAddLength(SetupData): def test_right_length(self, table_types): self._setup(table_types) t = table_types.Table([self.a]) t.add_column(self.b) def test_too_long(self, table_types): self._setup(table_types) t = table_types.Table([self.a]) with pytest.raises(ValueError): t.add_column(table_types.Column(name='b', data=[4, 5, 6, 7])) # data too long def test_too_short(self, table_types): self._setup(table_types) t = table_types.Table([self.a]) with pytest.raises(ValueError): t.add_column(table_types.Column(name='b', data=[4, 5])) # data too short @pytest.mark.usefixtures('table_types') class TestAddPosition(SetupData): def test_1(self, table_types): self._setup(table_types) t = table_types.Table() t.add_column(self.a, 0) def test_2(self, table_types): self._setup(table_types) t = table_types.Table() t.add_column(self.a, 1) def test_3(self, table_types): self._setup(table_types) t = table_types.Table() t.add_column(self.a, -1) def test_5(self, table_types): self._setup(table_types) t = table_types.Table() with pytest.raises(ValueError): t.index_column('b') def test_6(self, table_types): self._setup(table_types) t = table_types.Table() t.add_column(self.a) t.add_column(self.b) assert t.colnames == ['a', 'b'] def test_7(self, table_types): self._setup(table_types) t = table_types.Table([self.a]) t.add_column(self.b, t.index_column('a')) assert t.colnames == ['b', 'a'] def test_8(self, table_types): self._setup(table_types) t = table_types.Table([self.a]) t.add_column(self.b, t.index_column('a') + 1) assert t.colnames == ['a', 'b'] def test_9(self, table_types): self._setup(table_types) t = table_types.Table() t.add_column(self.a) t.add_column(self.b, t.index_column('a') + 1) t.add_column(self.c, t.index_column('b')) assert t.colnames == ['a', 'c', 'b'] def test_10(self, table_types): self._setup(table_types) t = table_types.Table() t.add_column(self.a) ia = t.index_column('a') t.add_column(self.b, ia + 1) t.add_column(self.c, ia) assert t.colnames == ['c', 'a', 'b'] @pytest.mark.usefixtures('table_types') class TestAddName(SetupData): def test_override_name(self, table_types): self._setup(table_types) t = table_types.Table() # Check that we can override the name of the input column in the Table t.add_column(self.a, name='b') t.add_column(self.b, name='a') assert t.colnames == ['b', 'a'] # Check that we did not change the name of the input column assert self.a.info.name == 'a' assert self.b.info.name == 'b' # Now test with an input column from another table t2 = table_types.Table() t2.add_column(t['a'], name='c') assert t2.colnames == ['c'] # Check that we did not change the name of the input column assert t.colnames == ['b', 'a'] # Check that we can give a name if none was present col = table_types.Column([1, 2, 3]) t.add_column(col, name='c') assert t.colnames == ['b', 'a', 'c'] def test_default_name(self, table_types): t = table_types.Table() col = table_types.Column([1, 2, 3]) t.add_column(col) assert t.colnames == ['col0'] @pytest.mark.usefixtures('table_types') class TestInitFromTable(SetupData): def test_from_table_cols(self, table_types): """Ensure that using cols from an existing table gives a clean copy. """ self._setup(table_types) t = self.t cols = t.columns # Construct Table with cols via Table._new_from_cols t2a = table_types.Table([cols['a'], cols['b'], self.c]) # Construct with add_column t2b = table_types.Table() t2b.add_column(cols['a']) t2b.add_column(cols['b']) t2b.add_column(self.c) t['a'][1] = 20 t['b'][1] = 21 for t2 in [t2a, t2b]: t2['a'][2] = 10 t2['b'][2] = 11 t2['c'][2] = 12 t2.columns['a'].meta['aa'][3] = 10 assert np.all(t['a'] == np.array([1, 20, 3])) assert np.all(t['b'] == np.array([4, 21, 6])) assert np.all(t2['a'] == np.array([1, 2, 10])) assert np.all(t2['b'] == np.array([4, 5, 11])) assert np.all(t2['c'] == np.array([7, 8, 12])) assert t2['a'].name == 'a' assert t2.columns['a'].meta['aa'][3] == 10 assert t.columns['a'].meta['aa'][3] == 3 @pytest.mark.usefixtures('table_types') class TestAddColumns(SetupData): def test_add_columns1(self, table_types): self._setup(table_types) t = table_types.Table() t.add_columns([self.a, self.b, self.c]) assert t.colnames == ['a', 'b', 'c'] def test_add_columns2(self, table_types): self._setup(table_types) t = table_types.Table([self.a, self.b]) t.add_columns([self.c, self.d]) assert t.colnames == ['a', 'b', 'c', 'd'] assert np.all(t['c'] == np.array([7, 8, 9])) def test_add_columns3(self, table_types): self._setup(table_types) t = table_types.Table([self.a, self.b]) t.add_columns([self.c, self.d], indexes=[1, 0]) assert t.colnames == ['d', 'a', 'c', 'b'] def test_add_columns4(self, table_types): self._setup(table_types) t = table_types.Table([self.a, self.b]) t.add_columns([self.c, self.d], indexes=[0, 0]) assert t.colnames == ['c', 'd', 'a', 'b'] def test_add_columns5(self, table_types): self._setup(table_types) t = table_types.Table([self.a, self.b]) t.add_columns([self.c, self.d], indexes=[2, 2]) assert t.colnames == ['a', 'b', 'c', 'd'] def test_add_columns6(self, table_types): """Check that we can override column names.""" self._setup(table_types) t = table_types.Table() t.add_columns([self.a, self.b, self.c], names=['b', 'c', 'a']) assert t.colnames == ['b', 'c', 'a'] def test_add_columns7(self, table_types): """Check that default names are used when appropriate.""" t = table_types.Table() col0 = table_types.Column([1, 2, 3]) col1 = table_types.Column([4, 5, 3]) t.add_columns([col0, col1]) assert t.colnames == ['col0', 'col1'] def test_add_duplicate_column(self, table_types): self._setup(table_types) t = table_types.Table() t.add_column(self.a) with pytest.raises(ValueError): t.add_column(table_types.Column(name='a', data=[0, 1, 2])) t.add_column(table_types.Column(name='a', data=[0, 1, 2]), rename_duplicate=True) t.add_column(self.b) t.add_column(self.c) assert t.colnames == ['a', 'a_1', 'b', 'c'] t.add_column(table_types.Column(name='a', data=[0, 1, 2]), rename_duplicate=True) assert t.colnames == ['a', 'a_1', 'b', 'c', 'a_2'] # test adding column from a separate Table t1 = table_types.Table() t1.add_column(self.a) with pytest.raises(ValueError): t.add_column(t1['a']) t.add_column(t1['a'], rename_duplicate=True) t1['a'][0] = 100 # Change original column assert t.colnames == ['a', 'a_1', 'b', 'c', 'a_2', 'a_3'] assert t1.colnames == ['a'] # Check new column didn't change (since name conflict forced a copy) assert t['a_3'][0] == self.a[0] # Check that rename_duplicate=True is ok if there are no duplicates t.add_column(table_types.Column(name='q', data=[0, 1, 2]), rename_duplicate=True) assert t.colnames == ['a', 'a_1', 'b', 'c', 'a_2', 'a_3', 'q'] def test_add_duplicate_columns(self, table_types): self._setup(table_types) t = table_types.Table([self.a, self.b, self.c]) with pytest.raises(ValueError): t.add_columns([table_types.Column(name='a', data=[0, 1, 2]), table_types.Column(name='b', data=[0, 1, 2])]) t.add_columns([table_types.Column(name='a', data=[0, 1, 2]), table_types.Column(name='b', data=[0, 1, 2])], rename_duplicate=True) t.add_column(self.d) assert t.colnames == ['a', 'b', 'c', 'a_1', 'b_1', 'd'] @pytest.mark.usefixtures('table_types') class TestAddRow(SetupData): @property def b(self): if self._column_type is not None: if not hasattr(self, '_b'): self._b = self._column_type(name='b', data=[4.0, 5.1, 6.2]) return self._b @property def c(self): if self._column_type is not None: if not hasattr(self, '_c'): self._c = self._column_type(name='c', data=['7', '8', '9']) return self._c @property def d(self): if self._column_type is not None: if not hasattr(self, '_d'): self._d = self._column_type(name='d', data=[[1, 2], [3, 4], [5, 6]]) return self._d @property def t(self): if self._table_type is not None: if not hasattr(self, '_t'): self._t = self._table_type([self.a, self.b, self.c]) return self._t def test_add_none_to_empty_table(self, table_types): self._setup(table_types) t = table_types.Table(names=('a', 'b', 'c'), dtype=('(2,)i', 'S4', 'O')) t.add_row() assert np.all(t['a'][0] == [0, 0]) assert t['b'][0] == '' assert t['c'][0] == 0 t.add_row() assert np.all(t['a'][1] == [0, 0]) assert t['b'][1] == '' assert t['c'][1] == 0 def test_add_stuff_to_empty_table(self, table_types): self._setup(table_types) t = table_types.Table(names=('a', 'b', 'obj'), dtype=('(2,)i', 'S8', 'O')) t.add_row([[1, 2], 'hello', 'world']) assert np.all(t['a'][0] == [1, 2]) assert t['b'][0] == 'hello' assert t['obj'][0] == 'world' # Make sure it is not repeating last row but instead # adding zeros (as documented) t.add_row() assert np.all(t['a'][1] == [0, 0]) assert t['b'][1] == '' assert t['obj'][1] == 0 def test_add_table_row(self, table_types): self._setup(table_types) t = self.t t['d'] = self.d t2 = table_types.Table([self.a, self.b, self.c, self.d]) t.add_row(t2[0]) assert len(t) == 4 assert np.all(t['a'] == np.array([1, 2, 3, 1])) assert np.allclose(t['b'], np.array([4.0, 5.1, 6.2, 4.0])) assert np.all(t['c'] == np.array(['7', '8', '9', '7'])) assert np.all(t['d'] == np.array([[1, 2], [3, 4], [5, 6], [1, 2]])) def test_add_table_row_obj(self, table_types): self._setup(table_types) t = table_types.Table([self.a, self.b, self.obj]) t.add_row([1, 4.0, [10]]) assert len(t) == 4 assert np.all(t['a'] == np.array([1, 2, 3, 1])) assert np.allclose(t['b'], np.array([4.0, 5.1, 6.2, 4.0])) assert np.all(t['obj'] == np.array([1, 'string', 3, [10]], dtype='O')) def test_add_qtable_row_multidimensional(self): q = [[1, 2], [3, 4]] * u.m qt = table.QTable([q]) qt.add_row(([5, 6] * u.km,)) assert np.all(qt['col0'] == [[1, 2], [3, 4], [5000, 6000]] * u.m) def test_add_with_tuple(self, table_types): self._setup(table_types) t = self.t t.add_row((4, 7.2, '1')) assert len(t) == 4 assert np.all(t['a'] == np.array([1, 2, 3, 4])) assert np.allclose(t['b'], np.array([4.0, 5.1, 6.2, 7.2])) assert np.all(t['c'] == np.array(['7', '8', '9', '1'])) def test_add_with_list(self, table_types): self._setup(table_types) t = self.t t.add_row([4, 7.2, '10']) assert len(t) == 4 assert np.all(t['a'] == np.array([1, 2, 3, 4])) assert np.allclose(t['b'], np.array([4.0, 5.1, 6.2, 7.2])) assert np.all(t['c'] == np.array(['7', '8', '9', '10'])) def test_add_with_dict(self, table_types): self._setup(table_types) t = self.t t.add_row({'a': 4, 'b': 7.2}) assert len(t) == 4 assert np.all(t['a'] == np.array([1, 2, 3, 4])) assert np.allclose(t['b'], np.array([4.0, 5.1, 6.2, 7.2])) if t.masked: assert np.all(t['c'] == np.array(['7', '8', '9', '7'])) else: assert np.all(t['c'] == np.array(['7', '8', '9', ''])) def test_add_with_none(self, table_types): self._setup(table_types) t = self.t t.add_row() assert len(t) == 4 assert np.all(t['a'].data == np.array([1, 2, 3, 0])) assert np.allclose(t['b'], np.array([4.0, 5.1, 6.2, 0.0])) assert np.all(t['c'].data == np.array(['7', '8', '9', ''])) def test_add_missing_column(self, table_types): self._setup(table_types) t = self.t with pytest.raises(ValueError): t.add_row({'bad_column': 1}) def test_wrong_size_tuple(self, table_types): self._setup(table_types) t = self.t with pytest.raises(ValueError): t.add_row((1, 2)) def test_wrong_vals_type(self, table_types): self._setup(table_types) t = self.t with pytest.raises(TypeError): t.add_row(1) def test_add_row_failures(self, table_types): self._setup(table_types) t = self.t t_copy = table_types.Table(t, copy=True) # Wrong number of columns try: t.add_row([1, 2, 3, 4]) except ValueError: pass assert len(t) == 3 assert np.all(t.as_array() == t_copy.as_array()) # Wrong data type try: t.add_row(['one', 2, 3]) except ValueError: pass assert len(t) == 3 assert np.all(t.as_array() == t_copy.as_array()) def test_insert_table_row(self, table_types): """ Light testing of Table.insert_row() method. The deep testing is done via the add_row() tests which calls insert_row(index=len(self), ...), so here just test that the added index parameter is handled correctly. """ self._setup(table_types) row = (10, 40.0, 'x', [10, 20]) for index in range(-3, 4): indices = np.insert(np.arange(3), index, 3) t = table_types.Table([self.a, self.b, self.c, self.d]) t2 = t.copy() t.add_row(row) # By now we know this works t2.insert_row(index, row) for name in t.colnames: if t[name].dtype.kind == 'f': assert np.allclose(t[name][indices], t2[name]) else: assert np.all(t[name][indices] == t2[name]) for index in (-4, 4): t = table_types.Table([self.a, self.b, self.c, self.d]) with pytest.raises(IndexError): t.insert_row(index, row) @pytest.mark.usefixtures('table_types') class TestTableColumn(SetupData): def test_column_view(self, table_types): self._setup(table_types) t = self.t a = t.columns['a'] a[2] = 10 assert t['a'][2] == 10 @pytest.mark.usefixtures('table_types') class TestArrayColumns(SetupData): def test_1d(self, table_types): self._setup(table_types) b = table_types.Column(name='b', dtype=int, shape=(2, ), length=3) t = table_types.Table([self.a]) t.add_column(b) assert t['b'].shape == (3, 2) assert t['b'][0].shape == (2, ) def test_2d(self, table_types): self._setup(table_types) b = table_types.Column(name='b', dtype=int, shape=(2, 4), length=3) t = table_types.Table([self.a]) t.add_column(b) assert t['b'].shape == (3, 2, 4) assert t['b'][0].shape == (2, 4) def test_3d(self, table_types): self._setup(table_types) t = table_types.Table([self.a]) b = table_types.Column(name='b', dtype=int, shape=(2, 4, 6), length=3) t.add_column(b) assert t['b'].shape == (3, 2, 4, 6) assert t['b'][0].shape == (2, 4, 6) @pytest.mark.usefixtures('table_types') class TestRemove(SetupData): @property def t(self): if self._table_type is not None: if not hasattr(self, '_t'): self._t = self._table_type([self.a]) return self._t @property def t2(self): if self._table_type is not None: if not hasattr(self, '_t2'): self._t2 = self._table_type([self.a, self.b, self.c]) return self._t2 def test_1(self, table_types): self._setup(table_types) self.t.remove_columns('a') assert self.t.colnames == [] assert self.t.as_array().size == 0 # Regression test for gh-8640 assert not self.t assert isinstance(self.t == None, np.ndarray) # noqa assert (self.t == None).size == 0 # noqa def test_2(self, table_types): self._setup(table_types) self.t.add_column(self.b) self.t.remove_columns('a') assert self.t.colnames == ['b'] assert self.t.dtype.names == ('b',) assert np.all(self.t['b'] == np.array([4, 5, 6])) def test_3(self, table_types): """Check remove_columns works for a single column with a name of more than one character. Regression test against #2699""" self._setup(table_types) self.t['new_column'] = self.t['a'] assert 'new_column' in self.t.columns.keys() self.t.remove_columns('new_column') assert 'new_column' not in self.t.columns.keys() def test_remove_nonexistent_row(self, table_types): self._setup(table_types) with pytest.raises(IndexError): self.t.remove_row(4) def test_remove_row_0(self, table_types): self._setup(table_types) self.t.add_column(self.b) self.t.add_column(self.c) self.t.remove_row(0) assert self.t.colnames == ['a', 'b', 'c'] assert np.all(self.t['b'] == np.array([5, 6])) def test_remove_row_1(self, table_types): self._setup(table_types) self.t.add_column(self.b) self.t.add_column(self.c) self.t.remove_row(1) assert self.t.colnames == ['a', 'b', 'c'] assert np.all(self.t['a'] == np.array([1, 3])) def test_remove_row_2(self, table_types): self._setup(table_types) self.t.add_column(self.b) self.t.add_column(self.c) self.t.remove_row(2) assert self.t.colnames == ['a', 'b', 'c'] assert np.all(self.t['c'] == np.array([7, 8])) def test_remove_row_slice(self, table_types): self._setup(table_types) self.t.add_column(self.b) self.t.add_column(self.c) self.t.remove_rows(slice(0, 2, 1)) assert self.t.colnames == ['a', 'b', 'c'] assert np.all(self.t['c'] == np.array([9])) def test_remove_row_list(self, table_types): self._setup(table_types) self.t.add_column(self.b) self.t.add_column(self.c) self.t.remove_rows([0, 2]) assert self.t.colnames == ['a', 'b', 'c'] assert np.all(self.t['c'] == np.array([8])) def test_remove_row_preserves_meta(self, table_types): self._setup(table_types) self.t.add_column(self.b) self.t.remove_rows([0, 2]) assert self.t['a'].meta == {'aa': [0, 1, 2, 3, 4]} assert self.t.dtype == np.dtype([('a', 'int'), ('b', 'int')]) def test_delitem_row(self, table_types): self._setup(table_types) self.t.add_column(self.b) self.t.add_column(self.c) del self.t[1] assert self.t.colnames == ['a', 'b', 'c'] assert np.all(self.t['a'] == np.array([1, 3])) @pytest.mark.parametrize("idx", [[0, 2], np.array([0, 2])]) def test_delitem_row_list(self, table_types, idx): self._setup(table_types) self.t.add_column(self.b) self.t.add_column(self.c) del self.t[idx] assert self.t.colnames == ['a', 'b', 'c'] assert np.all(self.t['c'] == np.array([8])) def test_delitem_row_slice(self, table_types): self._setup(table_types) self.t.add_column(self.b) self.t.add_column(self.c) del self.t[0:2] assert self.t.colnames == ['a', 'b', 'c'] assert np.all(self.t['c'] == np.array([9])) def test_delitem_row_fail(self, table_types): self._setup(table_types) with pytest.raises(IndexError): del self.t[4] def test_delitem_row_float(self, table_types): self._setup(table_types) with pytest.raises(IndexError): del self.t[1.] def test_delitem1(self, table_types): self._setup(table_types) del self.t['a'] assert self.t.colnames == [] assert self.t.as_array().size == 0 # Regression test for gh-8640 assert not self.t assert isinstance(self.t == None, np.ndarray) # noqa assert (self.t == None).size == 0 # noqa def test_delitem2(self, table_types): self._setup(table_types) del self.t2['b'] assert self.t2.colnames == ['a', 'c'] def test_delitems(self, table_types): self._setup(table_types) del self.t2['a', 'b'] assert self.t2.colnames == ['c'] def test_delitem_fail(self, table_types): self._setup(table_types) with pytest.raises(KeyError): del self.t['d'] @pytest.mark.usefixtures('table_types') class TestKeep(SetupData): def test_1(self, table_types): self._setup(table_types) t = table_types.Table([self.a, self.b]) t.keep_columns([]) assert t.colnames == [] assert t.as_array().size == 0 # Regression test for gh-8640 assert not t assert isinstance(t == None, np.ndarray) # noqa assert (t == None).size == 0 # noqa def test_2(self, table_types): self._setup(table_types) t = table_types.Table([self.a, self.b]) t.keep_columns('b') assert t.colnames == ['b'] assert t.dtype.names == ('b',) assert np.all(t['b'] == np.array([4, 5, 6])) @pytest.mark.usefixtures('table_types') class TestRename(SetupData): def test_1(self, table_types): self._setup(table_types) t = table_types.Table([self.a]) t.rename_column('a', 'b') assert t.colnames == ['b'] assert t.dtype.names == ('b',) assert np.all(t['b'] == np.array([1, 2, 3])) def test_2(self, table_types): self._setup(table_types) t = table_types.Table([self.a, self.b]) t.rename_column('a', 'c') t.rename_column('b', 'a') assert t.colnames == ['c', 'a'] assert t.dtype.names == ('c', 'a') if t.masked: assert t.mask.dtype.names == ('c', 'a') assert np.all(t['c'] == np.array([1, 2, 3])) assert np.all(t['a'] == np.array([4, 5, 6])) def test_rename_by_attr(self, table_types): self._setup(table_types) t = table_types.Table([self.a, self.b]) t['a'].name = 'c' t['b'].name = 'a' assert t.colnames == ['c', 'a'] assert t.dtype.names == ('c', 'a') assert np.all(t['c'] == np.array([1, 2, 3])) assert np.all(t['a'] == np.array([4, 5, 6])) def test_rename_columns(self, table_types): self._setup(table_types) t = table_types.Table([self.a, self.b, self.c]) t.rename_columns(('a', 'b', 'c'), ('aa', 'bb', 'cc')) assert t.colnames == ['aa', 'bb', 'cc'] t.rename_columns(['bb', 'cc'], ['b', 'c']) assert t.colnames == ['aa', 'b', 'c'] with pytest.raises(TypeError): t.rename_columns(('aa'), ['a']) with pytest.raises(ValueError): t.rename_columns(['a'], ['b', 'c']) @pytest.mark.usefixtures('table_types') class TestSort(): def test_single(self, table_types): t = table_types.Table() t.add_column(table_types.Column(name='a', data=[2, 1, 3])) t.add_column(table_types.Column(name='b', data=[6, 5, 4])) t.add_column(table_types.Column(name='c', data=[(1, 2), (3, 4), (4, 5)])) assert np.all(t['a'] == np.array([2, 1, 3])) assert np.all(t['b'] == np.array([6, 5, 4])) t.sort('a') assert np.all(t['a'] == np.array([1, 2, 3])) assert np.all(t['b'] == np.array([5, 6, 4])) assert np.all(t['c'] == np.array([[3, 4], [1, 2], [4, 5]])) t.sort('b') assert np.all(t['a'] == np.array([3, 1, 2])) assert np.all(t['b'] == np.array([4, 5, 6])) assert np.all(t['c'] == np.array([[4, 5], [3, 4], [1, 2]])) @pytest.mark.parametrize('create_index', [False, True]) def test_single_reverse(self, table_types, create_index): t = table_types.Table() t.add_column(table_types.Column(name='a', data=[2, 1, 3])) t.add_column(table_types.Column(name='b', data=[6, 5, 4])) t.add_column(table_types.Column(name='c', data=[(1, 2), (3, 4), (4, 5)])) assert np.all(t['a'] == np.array([2, 1, 3])) assert np.all(t['b'] == np.array([6, 5, 4])) t.sort('a', reverse=True) assert np.all(t['a'] == np.array([3, 2, 1])) assert np.all(t['b'] == np.array([4, 6, 5])) assert np.all(t['c'] == np.array([[4, 5], [1, 2], [3, 4]])) t.sort('b', reverse=True) assert np.all(t['a'] == np.array([2, 1, 3])) assert np.all(t['b'] == np.array([6, 5, 4])) assert np.all(t['c'] == np.array([[1, 2], [3, 4], [4, 5]])) def test_single_big(self, table_types): """Sort a big-ish table with a non-trivial sort order""" x = np.arange(10000) y = np.sin(x) t = table_types.Table([x, y], names=('x', 'y')) t.sort('y') idx = np.argsort(y) assert np.all(t['x'] == x[idx]) assert np.all(t['y'] == y[idx]) @pytest.mark.parametrize('reverse', [True, False]) def test_empty_reverse(self, table_types, reverse): t = table_types.Table([[], []], dtype=['f4', 'U1']) t.sort('col1', reverse=reverse) def test_multiple(self, table_types): t = table_types.Table() t.add_column(table_types.Column(name='a', data=[2, 1, 3, 2, 3, 1])) t.add_column(table_types.Column(name='b', data=[6, 5, 4, 3, 5, 4])) assert np.all(t['a'] == np.array([2, 1, 3, 2, 3, 1])) assert np.all(t['b'] == np.array([6, 5, 4, 3, 5, 4])) t.sort(['a', 'b']) assert np.all(t['a'] == np.array([1, 1, 2, 2, 3, 3])) assert np.all(t['b'] == np.array([4, 5, 3, 6, 4, 5])) t.sort(['b', 'a']) assert np.all(t['a'] == np.array([2, 1, 3, 1, 3, 2])) assert np.all(t['b'] == np.array([3, 4, 4, 5, 5, 6])) t.sort(('a', 'b')) assert np.all(t['a'] == np.array([1, 1, 2, 2, 3, 3])) assert np.all(t['b'] == np.array([4, 5, 3, 6, 4, 5])) def test_multiple_reverse(self, table_types): t = table_types.Table() t.add_column(table_types.Column(name='a', data=[2, 1, 3, 2, 3, 1])) t.add_column(table_types.Column(name='b', data=[6, 5, 4, 3, 5, 4])) assert np.all(t['a'] == np.array([2, 1, 3, 2, 3, 1])) assert np.all(t['b'] == np.array([6, 5, 4, 3, 5, 4])) t.sort(['a', 'b'], reverse=True) assert np.all(t['a'] == np.array([3, 3, 2, 2, 1, 1])) assert np.all(t['b'] == np.array([5, 4, 6, 3, 5, 4])) t.sort(['b', 'a'], reverse=True) assert np.all(t['a'] == np.array([2, 3, 1, 3, 1, 2])) assert np.all(t['b'] == np.array([6, 5, 5, 4, 4, 3])) t.sort(('a', 'b'), reverse=True) assert np.all(t['a'] == np.array([3, 3, 2, 2, 1, 1])) assert np.all(t['b'] == np.array([5, 4, 6, 3, 5, 4])) def test_multiple_with_bytes(self, table_types): t = table_types.Table() t.add_column(table_types.Column(name='firstname', data=[b"Max", b"Jo", b"John"])) t.add_column(table_types.Column(name='name', data=[b"Miller", b"Miller", b"Jackson"])) t.add_column(table_types.Column(name='tel', data=[12, 15, 19])) t.sort(['name', 'firstname']) assert np.all([t['firstname'] == np.array([b"John", b"Jo", b"Max"])]) assert np.all([t['name'] == np.array([b"Jackson", b"Miller", b"Miller"])]) assert np.all([t['tel'] == np.array([19, 15, 12])]) def test_multiple_with_unicode(self, table_types): # Before Numpy 1.6.2, sorting with multiple column names # failed when a unicode column was present. t = table_types.Table() t.add_column(table_types.Column( name='firstname', data=[str(x) for x in ["Max", "Jo", "John"]])) t.add_column(table_types.Column( name='name', data=[str(x) for x in ["Miller", "Miller", "Jackson"]])) t.add_column(table_types.Column(name='tel', data=[12, 15, 19])) t.sort(['name', 'firstname']) assert np.all([t['firstname'] == np.array( [str(x) for x in ["John", "Jo", "Max"]])]) assert np.all([t['name'] == np.array( [str(x) for x in ["Jackson", "Miller", "Miller"]])]) assert np.all([t['tel'] == np.array([19, 15, 12])]) def test_argsort(self, table_types): t = table_types.Table() t.add_column(table_types.Column(name='a', data=[2, 1, 3, 2, 3, 1])) t.add_column(table_types.Column(name='b', data=[6, 5, 4, 3, 5, 4])) assert np.all(t.argsort() == t.as_array().argsort()) i0 = t.argsort('a') i1 = t.as_array().argsort(order=['a']) assert np.all(t['a'][i0] == t['a'][i1]) i0 = t.argsort(['a', 'b']) i1 = t.as_array().argsort(order=['a', 'b']) assert np.all(t['a'][i0] == t['a'][i1]) assert np.all(t['b'][i0] == t['b'][i1]) @pytest.mark.parametrize('add_index', [False, True]) def test_argsort_reverse(self, table_types, add_index): t = table_types.Table() t.add_column(table_types.Column(name='a', data=[2, 1, 3, 2, 3, 1])) t.add_column(table_types.Column(name='b', data=[6, 5, 4, 3, 5, 4])) if add_index: t.add_index('a') assert np.all(t.argsort(reverse=True) == np.array([4, 2, 0, 3, 1, 5])) i0 = t.argsort('a', reverse=True) i1 = np.array([4, 2, 3, 0, 5, 1]) assert np.all(t['a'][i0] == t['a'][i1]) i0 = t.argsort(['a', 'b'], reverse=True) i1 = np.array([4, 2, 0, 3, 1, 5]) assert np.all(t['a'][i0] == t['a'][i1]) assert np.all(t['b'][i0] == t['b'][i1]) def test_argsort_bytes(self, table_types): t = table_types.Table() t.add_column(table_types.Column(name='firstname', data=[b"Max", b"Jo", b"John"])) t.add_column(table_types.Column(name='name', data=[b"Miller", b"Miller", b"Jackson"])) t.add_column(table_types.Column(name='tel', data=[12, 15, 19])) assert np.all(t.argsort(['name', 'firstname']) == np.array([2, 1, 0])) def test_argsort_unicode(self, table_types): # Before Numpy 1.6.2, sorting with multiple column names # failed when a unicode column was present. t = table_types.Table() t.add_column(table_types.Column( name='firstname', data=[str(x) for x in ["Max", "Jo", "John"]])) t.add_column(table_types.Column( name='name', data=[str(x) for x in ["Miller", "Miller", "Jackson"]])) t.add_column(table_types.Column(name='tel', data=[12, 15, 19])) assert np.all(t.argsort(['name', 'firstname']) == np.array([2, 1, 0])) def test_rebuild_column_view_then_rename(self, table_types): """ Issue #2039 where renaming fails after any method that calls _rebuild_table_column_view (this includes sort and add_row). """ t = table_types.Table([[1]], names=('a',)) assert t.colnames == ['a'] assert t.dtype.names == ('a',) t.add_row((2,)) assert t.colnames == ['a'] assert t.dtype.names == ('a',) t.rename_column('a', 'b') assert t.colnames == ['b'] assert t.dtype.names == ('b',) t.sort('b') assert t.colnames == ['b'] assert t.dtype.names == ('b',) t.rename_column('b', 'c') assert t.colnames == ['c'] assert t.dtype.names == ('c',) @pytest.mark.usefixtures('table_types') class TestIterator(): def test_iterator(self, table_types): d = np.array([(2, 1), (3, 6), (4, 5)], dtype=[('a', 'i4'), ('b', 'i4')]) t = table_types.Table(d) if t.masked: with pytest.raises(ValueError): t[0] == d[0] else: for row, np_row in zip(t, d): assert np.all(row == np_row) @pytest.mark.usefixtures('table_types') class TestSetMeta(): def test_set_meta(self, table_types): d = table_types.Table(names=('a', 'b')) d.meta['a'] = 1 d.meta['b'] = 1 d.meta['c'] = 1 d.meta['d'] = 1 assert list(d.meta.keys()) == ['a', 'b', 'c', 'd'] @pytest.mark.usefixtures('table_types') class TestConvertNumpyArray(): def test_convert_numpy_array(self, table_types): d = table_types.Table([[1, 2], [3, 4]], names=('a', 'b')) np_data = np.array(d) if table_types.Table is not MaskedTable: assert np.all(np_data == d.as_array()) assert np_data is not d.as_array() assert d.colnames == list(np_data.dtype.names) np_data = np.array(d, copy=False) if table_types.Table is not MaskedTable: assert np.all(np_data == d.as_array()) assert d.colnames == list(np_data.dtype.names) with pytest.raises(ValueError): np_data = np.array(d, dtype=[('c', 'i8'), ('d', 'i8')]) def test_as_array_byteswap(self, table_types): """Test for https://github.com/astropy/astropy/pull/4080""" byte_orders = ('>', '<') native_order = byte_orders[sys.byteorder == 'little'] for order in byte_orders: col = table_types.Column([1.0, 2.0], name='a', dtype=order + 'f8') t = table_types.Table([col]) arr = t.as_array() assert arr['a'].dtype.byteorder in (native_order, '=') arr = t.as_array(keep_byteorder=True) if order == native_order: assert arr['a'].dtype.byteorder in (order, '=') else: assert arr['a'].dtype.byteorder == order def test_byteswap_fits_array(self, table_types): """ Test for https://github.com/astropy/astropy/pull/4080, demonstrating that FITS tables are converted to native byte order. """ non_native_order = ('>', '<')[sys.byteorder != 'little'] filename = get_pkg_data_filename('data/tb.fits', 'astropy.io.fits.tests') t = table_types.Table.read(filename) arr = t.as_array() for idx in range(len(arr.dtype)): assert arr.dtype[idx].byteorder != non_native_order with fits.open(filename, character_as_bytes=True) as hdul: data = hdul[1].data for colname in data.columns.names: assert np.all(data[colname] == arr[colname]) arr2 = t.as_array(keep_byteorder=True) for colname in data.columns.names: assert (data[colname].dtype.byteorder == arr2[colname].dtype.byteorder) def _assert_copies(t, t2, deep=True): assert t.colnames == t2.colnames np.testing.assert_array_equal(t.as_array(), t2.as_array()) assert t.meta == t2.meta for col, col2 in zip(t.columns.values(), t2.columns.values()): if deep: assert not np.may_share_memory(col, col2) else: assert np.may_share_memory(col, col2) def test_copy(): t = table.Table([[1, 2, 3], [2, 3, 4]], names=['x', 'y']) t2 = t.copy() _assert_copies(t, t2) def test_copy_masked(): t = table.Table([[1, 2, 3], [2, 3, 4]], names=['x', 'y'], masked=True, meta={'name': 'test'}) t['x'].mask == [True, False, True] t2 = t.copy() _assert_copies(t, t2) def test_copy_protocol(): t = table.Table([[1, 2, 3], [2, 3, 4]], names=['x', 'y']) t2 = copy.copy(t) t3 = copy.deepcopy(t) _assert_copies(t, t2, deep=False) _assert_copies(t, t3) def test_disallow_inequality_comparisons(): """ Regression test for #828 - disallow comparison operators on whole Table """ t = table.Table() with pytest.raises(TypeError): t > 2 with pytest.raises(TypeError): t < 1.1 with pytest.raises(TypeError): t >= 5.5 with pytest.raises(TypeError): t <= -1.1 def test_values_equal_part1(): col1 = [1, 2] col2 = [1.0, 2.0] col3 = ['a', 'b'] t1 = table.Table([col1, col2, col3], names=['a', 'b', 'c']) t2 = table.Table([col1, col2], names=['a', 'b']) t3 = table.table_helpers.simple_table() tm = t1.copy() tm['time'] = Time([1, 2], format='cxcsec') tm1 = tm.copy() tm1['time'][0] = np.ma.masked tq = table.table_helpers.simple_table() tq['quantity'] = [1., 2., 3.] * u.m tsk = table.table_helpers.simple_table() tsk['sk'] = SkyCoord(1, 2, unit='deg') eqsk = tsk.values_equal(tsk) for col in eqsk.itercols(): assert np.all(col) with pytest.raises(ValueError, match='cannot compare tables with different column names'): t2.values_equal(t1) with pytest.raises(ValueError, match='unable to compare column a'): # Shape mismatch t3.values_equal(t1) with pytest.raises(ValueError, match='unable to compare column c'): # Type mismatch in column c causes FutureWarning t1.values_equal(2) with pytest.raises(ValueError, match='unable to compare column c'): t1.values_equal([1, 2]) eq = t2.values_equal(t2) for col in eq.colnames: assert np.all(eq[col] == [True, True]) eq1 = tm1.values_equal(tm) for col in eq1.colnames: assert np.all(eq1[col] == [True, True]) eq2 = tq.values_equal(tq) for col in eq2.colnames: assert np.all(eq2[col] == [True, True, True]) eq3 = t2.values_equal(2) for col in eq3.colnames: assert np.all(eq3[col] == [False, True]) eq4 = t2.values_equal([1, 2]) for col in eq4.colnames: assert np.all(eq4[col] == [True, True]) # Compare table to its first row t = table.Table(rows=[(1, 'a'), (1, 'b')]) eq = t.values_equal(t[0]) assert np.all(eq['col0'] == [True, True]) assert np.all(eq['col1'] == [True, False]) def test_rows_equal(): t = table.Table.read([' a b c d', ' 2 c 7.0 0', ' 2 b 5.0 1', ' 2 b 6.0 2', ' 2 a 4.0 3', ' 0 a 0.0 4', ' 1 b 3.0 5', ' 1 a 2.0 6', ' 1 a 1.0 7'], format='ascii') # All rows are equal assert np.all(t == t) # Assert no rows are different assert not np.any(t != t) # Check equality result for a given row assert np.all((t == t[3]) == np.array([0, 0, 0, 1, 0, 0, 0, 0], dtype=bool)) # Check inequality result for a given row assert np.all((t != t[3]) == np.array([1, 1, 1, 0, 1, 1, 1, 1], dtype=bool)) t2 = table.Table.read([' a b c d', ' 2 c 7.0 0', ' 2 b 5.0 1', ' 3 b 6.0 2', ' 2 a 4.0 3', ' 0 a 1.0 4', ' 1 b 3.0 5', ' 1 c 2.0 6', ' 1 a 1.0 7', ], format='ascii') # In the above cases, Row.__eq__ gets called, but now need to make sure # Table.__eq__ also gets called. assert np.all((t == t2) == np.array([1, 1, 0, 1, 0, 1, 0, 1], dtype=bool)) assert np.all((t != t2) == np.array([0, 0, 1, 0, 1, 0, 1, 0], dtype=bool)) # Check that comparing to a structured array works assert np.all((t == t2.as_array()) == np.array([1, 1, 0, 1, 0, 1, 0, 1], dtype=bool)) assert np.all((t.as_array() == t2) == np.array([1, 1, 0, 1, 0, 1, 0, 1], dtype=bool)) def test_equality_masked(): t = table.Table.read([' a b c d', ' 2 c 7.0 0', ' 2 b 5.0 1', ' 2 b 6.0 2', ' 2 a 4.0 3', ' 0 a 0.0 4', ' 1 b 3.0 5', ' 1 a 2.0 6', ' 1 a 1.0 7', ], format='ascii') # Make into masked table t = table.Table(t, masked=True) # All rows are equal assert np.all(t == t) # Assert no rows are different assert not np.any(t != t) # Check equality result for a given row assert np.all((t == t[3]) == np.array([0, 0, 0, 1, 0, 0, 0, 0], dtype=bool)) # Check inequality result for a given row assert np.all((t != t[3]) == np.array([1, 1, 1, 0, 1, 1, 1, 1], dtype=bool)) t2 = table.Table.read([' a b c d', ' 2 c 7.0 0', ' 2 b 5.0 1', ' 3 b 6.0 2', ' 2 a 4.0 3', ' 0 a 1.0 4', ' 1 b 3.0 5', ' 1 c 2.0 6', ' 1 a 1.0 7', ], format='ascii') # In the above cases, Row.__eq__ gets called, but now need to make sure # Table.__eq__ also gets called. assert np.all((t == t2) == np.array([1, 1, 0, 1, 0, 1, 0, 1], dtype=bool)) assert np.all((t != t2) == np.array([0, 0, 1, 0, 1, 0, 1, 0], dtype=bool)) # Check that masking a value causes the row to differ t.mask['a'][0] = True assert np.all((t == t2) == np.array([0, 1, 0, 1, 0, 1, 0, 1], dtype=bool)) assert np.all((t != t2) == np.array([1, 0, 1, 0, 1, 0, 1, 0], dtype=bool)) # Check that comparing to a structured array works assert np.all((t == t2.as_array()) == np.array([0, 1, 0, 1, 0, 1, 0, 1], dtype=bool)) @pytest.mark.xfail def test_equality_masked_bug(): """ This highlights a Numpy bug. Once it works, it can be moved into the test_equality_masked test. Related Numpy bug report: https://github.com/numpy/numpy/issues/3840 """ t = table.Table.read([' a b c d', ' 2 c 7.0 0', ' 2 b 5.0 1', ' 2 b 6.0 2', ' 2 a 4.0 3', ' 0 a 0.0 4', ' 1 b 3.0 5', ' 1 a 2.0 6', ' 1 a 1.0 7', ], format='ascii') t = table.Table(t, masked=True) t2 = table.Table.read([' a b c d', ' 2 c 7.0 0', ' 2 b 5.0 1', ' 3 b 6.0 2', ' 2 a 4.0 3', ' 0 a 1.0 4', ' 1 b 3.0 5', ' 1 c 2.0 6', ' 1 a 1.0 7', ], format='ascii') assert np.all((t.as_array() == t2) == np.array([0, 1, 0, 1, 0, 1, 0, 1], dtype=bool)) # Check that the meta descriptor is working as expected. The MetaBaseTest class # takes care of defining all the tests, and we simply have to define the class # and any minimal set of args to pass. class TestMetaTable(MetaBaseTest): test_class = table.Table args = () def test_unicode_content(): # If we don't have unicode literals then return if isinstance('', bytes): return # Define unicode literals string_a = 'Đ°ŅŅ‚Ņ€ĐžĐŊĐžĐŧĐ¸Ņ‡ĐĩҁĐēĐ°Ņ ĐŋĐ¸Ņ‚ĐžĐŊа' string_b = 'ĐŧиĐģĐģĐ¸Đ°Ņ€Đ´Ņ‹ ŅĐ˛ĐĩŅ‚ĐžĐ˛Ņ‹Ņ… ĐģĐĩŅ‚' a = table.Table( [[string_a, 2], [string_b, 3]], names=('a', 'b')) assert string_a in str(a) # This only works because the coding of this file is utf-8, which # matches the default encoding of Table.__str__ assert string_a.encode('utf-8') in bytes(a) def test_unicode_policy(): t = table.Table.read([' a b c d', ' 2 c 7.0 0', ' 2 b 5.0 1', ' 2 b 6.0 2', ' 2 a 4.0 3', ' 0 a 0.0 4', ' 1 b 3.0 5', ' 1 a 2.0 6', ' 1 a 1.0 7', ], format='ascii') assert_follows_unicode_guidelines(t) @pytest.mark.parametrize('uni', ['ĐŋĐ¸Ņ‚ĐžĐŊа', 'ascii']) def test_unicode_bytestring_conversion(table_types, uni): """ Test converting columns to all unicode or all bytestring. This makes two columns, one which is unicode (str in Py3) and one which is bytes (UTF-8 encoded). There are two code paths in the conversions, a faster one where the data are actually ASCII and a slower one where UTF-8 conversion is required. This tests both via the ``uni`` param. """ byt = uni.encode('utf-8') t = table_types.Table([[byt], [uni], [1]], dtype=('S', 'U', 'i')) assert t['col0'].dtype.kind == 'S' assert t['col1'].dtype.kind == 'U' assert t['col2'].dtype.kind == 'i' t['col0'].description = 'col0' t['col1'].description = 'col1' t['col0'].meta['val'] = 'val0' t['col1'].meta['val'] = 'val1' # Unicode to bytestring t1 = t.copy() t1.convert_unicode_to_bytestring() assert t1['col0'].dtype.kind == 'S' assert t1['col1'].dtype.kind == 'S' assert t1['col2'].dtype.kind == 'i' # Meta made it through assert t1['col0'].description == 'col0' assert t1['col1'].description == 'col1' assert t1['col0'].meta['val'] == 'val0' assert t1['col1'].meta['val'] == 'val1' # Need to de-fang the automatic unicode sandwiching of Table assert np.array(t1['col0'])[0] == byt assert np.array(t1['col1'])[0] == byt assert np.array(t1['col2'])[0] == 1 # Bytestring to unicode t1 = t.copy() t1.convert_bytestring_to_unicode() assert t1['col0'].dtype.kind == 'U' assert t1['col1'].dtype.kind == 'U' assert t1['col2'].dtype.kind == 'i' # Meta made it through assert t1['col0'].description == 'col0' assert t1['col1'].description == 'col1' assert t1['col0'].meta['val'] == 'val0' assert t1['col1'].meta['val'] == 'val1' # No need to de-fang the automatic unicode sandwiching of Table here, but # do just for consistency to prove things are working. assert np.array(t1['col0'])[0] == uni assert np.array(t1['col1'])[0] == uni assert np.array(t1['col2'])[0] == 1 def test_table_deletion(): """ Regression test for the reference cycle discussed in https://github.com/astropy/astropy/issues/2877 """ deleted = set() # A special table subclass which leaves a record when it is finalized class TestTable(table.Table): def __del__(self): deleted.add(id(self)) t = TestTable({'a': [1, 2, 3]}) the_id = id(t) assert t['a'].parent_table is t del t # Cleanup gc.collect() assert the_id in deleted def test_nested_iteration(): """ Regression test for issue 3358 where nested iteration over a single table fails. """ t = table.Table([[0, 1]], names=['a']) out = [] for r1 in t: for r2 in t: out.append((r1['a'], r2['a'])) assert out == [(0, 0), (0, 1), (1, 0), (1, 1)] def test_table_init_from_degenerate_arrays(table_types): t = table_types.Table(np.array([])) assert len(t.columns) == 0 with pytest.raises(ValueError): t = table_types.Table(np.array(0)) t = table_types.Table(np.array([1, 2, 3])) assert len(t.columns) == 3 @pytest.mark.skipif('not HAS_PANDAS') class TestPandas: def test_simple(self): t = table.Table() for endian in ['<', '>', '=']: for kind in ['f', 'i']: for byte in ['2', '4', '8']: dtype = np.dtype(endian + kind + byte) x = np.array([1, 2, 3], dtype=dtype) t[endian + kind + byte] = x.newbyteorder(endian) t['u'] = ['a', 'b', 'c'] t['s'] = ['a', 'b', 'c'] d = t.to_pandas() for column in t.columns: if column == 'u': assert np.all(t['u'] == np.array(['a', 'b', 'c'])) assert d[column].dtype == np.dtype("O") # upstream feature of pandas elif column == 's': assert np.all(t['s'] == np.array(['a', 'b', 'c'])) assert d[column].dtype == np.dtype("O") # upstream feature of pandas else: # We should be able to compare exact values here assert np.all(t[column] == d[column]) if t[column].dtype.isnative: assert d[column].dtype == t[column].dtype else: assert d[column].dtype == t[column].byteswap().newbyteorder().dtype # Regression test for astropy/astropy#1156 - the following code gave a # ValueError: Big-endian buffer not supported on little-endian # compiler. We now automatically swap the endian-ness to native order # upon adding the arrays to the data frame. # Explicitly testing little/big/native endian separately - # regression for a case in astropy/astropy#11286 not caught by #3729. d[['i4']] d[['f4']] t2 = table.Table.from_pandas(d) for column in t.columns: if column in ('u', 's'): assert np.all(t[column] == t2[column]) else: assert_allclose(t[column], t2[column]) if t[column].dtype.isnative: assert t[column].dtype == t2[column].dtype else: assert t[column].byteswap().newbyteorder().dtype == t2[column].dtype @pytest.mark.parametrize('unsigned', ['u', '']) @pytest.mark.parametrize('bits', [8, 16, 32, 64]) def test_nullable_int(self, unsigned, bits): np_dtype = f'{unsigned}int{bits}' c = MaskedColumn([1, 2], mask=[False, True], dtype=np_dtype) t = Table([c]) df = t.to_pandas() pd_dtype = np_dtype.replace('i', 'I').replace('u', 'U') assert str(df['col0'].dtype) == pd_dtype t2 = Table.from_pandas(df) assert str(t2['col0'].dtype) == np_dtype assert np.all(t2['col0'].mask == [False, True]) assert np.all(t2['col0'] == c) def test_2d(self): t = table.Table() t['a'] = [1, 2, 3] t['b'] = np.ones((3, 2)) with pytest.raises(ValueError, match='Cannot convert a table with multidimensional columns'): t.to_pandas() def test_mixin_pandas(self): t = table.QTable() for name in sorted(MIXIN_COLS): if not name.startswith('ndarray'): t[name] = MIXIN_COLS[name] t['dt'] = TimeDelta([0, 2, 4, 6], format='sec') tp = t.to_pandas() t2 = table.Table.from_pandas(tp) assert np.allclose(t2['quantity'], [0, 1, 2, 3]) assert np.allclose(t2['longitude'], [0., 1., 5., 6.]) assert np.allclose(t2['latitude'], [5., 6., 10., 11.]) assert np.allclose(t2['skycoord.ra'], [0, 1, 2, 3]) assert np.allclose(t2['skycoord.dec'], [0, 1, 2, 3]) assert np.allclose(t2['arraywrap'], [0, 1, 2, 3]) assert np.allclose(t2['arrayswap'], [0, 1, 2, 3]) assert np.allclose(t2['earthlocation.y'], [0, 110708, 547501, 654527], rtol=0, atol=1) # For pandas, Time, TimeDelta are the mixins that round-trip the class assert isinstance(t2['time'], Time) assert np.allclose(t2['time'].jyear, [2000, 2001, 2002, 2003]) assert np.all(t2['time'].isot == ['2000-01-01T12:00:00.000', '2000-12-31T18:00:00.000', '2002-01-01T00:00:00.000', '2003-01-01T06:00:00.000']) assert t2['time'].format == 'isot' # TimeDelta assert isinstance(t2['dt'], TimeDelta) assert np.allclose(t2['dt'].value, [0, 2, 4, 6]) assert t2['dt'].format == 'sec' @pytest.mark.parametrize('use_IndexedTable', [False, True]) def test_to_pandas_index(self, use_IndexedTable): """Test to_pandas() with different indexing options. This also tests the fix for #12014. The exception seen there is reproduced here without the fix. """ import pandas as pd class IndexedTable(table.QTable): """Always index the first column""" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.add_index(self.colnames[0]) row_index = pd.RangeIndex(0, 2, 1) tm_index = pd.DatetimeIndex(['1998-01-01', '2002-01-01'], dtype='datetime64[ns]', name='tm', freq=None) tm = Time([1998, 2002], format='jyear') x = [1, 2] table_cls = IndexedTable if use_IndexedTable else table.QTable t = table_cls([tm, x], names=['tm', 'x']) tp = t.to_pandas() if not use_IndexedTable: assert np.all(tp.index == row_index) tp = t.to_pandas(index='tm') assert np.all(tp.index == tm_index) t.add_index('tm') tp = t.to_pandas() assert np.all(tp.index == tm_index) # Make sure writing to pandas didn't hack the original table assert t['tm'].info.indices tp = t.to_pandas(index=True) assert np.all(tp.index == tm_index) tp = t.to_pandas(index=False) assert np.all(tp.index == row_index) with pytest.raises(ValueError) as err: t.to_pandas(index='not a column') assert 'index must be None, False' in str(err.value) def test_mixin_pandas_masked(self): tm = Time([1, 2, 3], format='cxcsec') dt = TimeDelta([1, 2, 3], format='sec') tm[1] = np.ma.masked dt[1] = np.ma.masked t = table.QTable([tm, dt], names=['tm', 'dt']) tp = t.to_pandas() assert np.all(tp['tm'].isnull() == [False, True, False]) assert np.all(tp['dt'].isnull() == [False, True, False]) t2 = table.Table.from_pandas(tp) assert np.all(t2['tm'].mask == tm.mask) assert np.ma.allclose(t2['tm'].jd, tm.jd, rtol=1e-14, atol=1e-14) assert np.all(t2['dt'].mask == dt.mask) assert np.ma.allclose(t2['dt'].jd, dt.jd, rtol=1e-14, atol=1e-14) def test_from_pandas_index(self): tm = Time([1998, 2002], format='jyear') x = [1, 2] t = table.Table([tm, x], names=['tm', 'x']) tp = t.to_pandas(index='tm') t2 = table.Table.from_pandas(tp) assert t2.colnames == ['x'] t2 = table.Table.from_pandas(tp, index=True) assert t2.colnames == ['tm', 'x'] assert np.allclose(t2['tm'].jyear, tm.jyear) @pytest.mark.parametrize('use_nullable_int', [True, False]) def test_masking(self, use_nullable_int): t = table.Table(masked=True) t['a'] = [1, 2, 3] t['a'].mask = [True, False, True] t['b'] = [1., 2., 3.] t['b'].mask = [False, False, True] t['u'] = ['a', 'b', 'c'] t['u'].mask = [False, True, False] t['s'] = ['a', 'b', 'c'] t['s'].mask = [False, True, False] # https://github.com/astropy/astropy/issues/7741 t['Source'] = [2584290278794471936, 2584290038276303744, 2584288728310999296] t['Source'].mask = [False, False, False] if use_nullable_int: # Default # No warning with the default use_nullable_int=True d = t.to_pandas(use_nullable_int=use_nullable_int) else: with pytest.warns(TableReplaceWarning, match=r"converted column 'a' from int(32|64) to float64"): d = t.to_pandas(use_nullable_int=use_nullable_int) t2 = table.Table.from_pandas(d) for name, column in t.columns.items(): assert np.all(column.data == t2[name].data) if hasattr(t2[name], 'mask'): assert np.all(column.mask == t2[name].mask) if column.dtype.kind == 'i': if np.any(column.mask) and not use_nullable_int: assert t2[name].dtype.kind == 'f' else: assert t2[name].dtype.kind == 'i' assert_array_equal(column.data, t2[name].data.astype(column.dtype)) else: if column.dtype.byteorder in ('=', '|'): assert column.dtype == t2[name].dtype else: assert column.byteswap().newbyteorder().dtype == t2[name].dtype def test_units(self): import pandas as pd import astropy.units as u df = pd.DataFrame({'x': [1, 2, 3], 't': [1.3, 1.2, 1.8]}) t = table.Table.from_pandas(df, units={'x': u.m, 't': u.s}) assert t['x'].unit == u.m assert t['t'].unit == u.s # test error if not a mapping with pytest.raises(TypeError): table.Table.from_pandas(df, units=[u.m, u.s]) # test warning is raised if additional columns in units dict with pytest.warns(UserWarning) as record: table.Table.from_pandas(df, units={'x': u.m, 't': u.s, 'y': u.m}) assert len(record) == 1 assert "{'y'}" in record[0].message.args[0] def test_to_pandas_masked_int_data_with__index(self): data = {"data": [0, 1, 2], "index": [10, 11, 12]} t = table.Table(data=data, masked=True) t.add_index("index") t["data"].mask = [1, 1, 0] df = t.to_pandas() assert df["data"].iloc[-1] == 2 @pytest.mark.usefixtures('table_types') class TestReplaceColumn(SetupData): def test_fail_replace_column(self, table_types): """Raise exception when trying to replace column via table.columns object""" self._setup(table_types) t = table_types.Table([self.a, self.b]) with pytest.raises(ValueError, match=r"Cannot replace column 'a'. Use " "Table.replace_column.. instead."): t.columns['a'] = [1, 2, 3] with pytest.raises(ValueError, match=r"column name not there is not in the table"): t.replace_column('not there', [1, 2, 3]) with pytest.raises(ValueError, match=r"length of new column must match table length"): t.replace_column('a', [1, 2]) def test_replace_column(self, table_types): """Replace existing column with a new column""" self._setup(table_types) t = table_types.Table([self.a, self.b]) ta = t['a'] tb = t['b'] vals = [1.2, 3.4, 5.6] for col in (vals, table_types.Column(vals), table_types.Column(vals, name='a'), table_types.Column(vals, name='b')): t.replace_column('a', col) assert np.all(t['a'] == vals) assert t['a'] is not ta # New a column assert t['b'] is tb # Original b column unchanged assert t.colnames == ['a', 'b'] assert t['a'].meta == {} assert t['a'].format is None # Special case: replacing the only column can resize table del t['b'] assert len(t) == 3 t['a'] = [1, 2] assert len(t) == 2 def test_replace_index_column(self, table_types): """Replace index column and generate expected exception""" self._setup(table_types) t = table_types.Table([self.a, self.b]) t.add_index('a') with pytest.raises(ValueError) as err: t.replace_column('a', [1, 2, 3]) assert err.value.args[0] == 'cannot replace a table index column' def test_replace_column_no_copy(self): t = Table([[1, 2], [3, 4]], names=['a', 'b']) a = np.array([1.5, 2.5]) t.replace_column('a', a, copy=False) assert t['a'][0] == a[0] t['a'][0] = 10 assert t['a'][0] == a[0] class TestQTableColumnConversionCornerCases: def test_replace_with_masked_col_with_units_in_qtable(self): """This is a small regression from #8902""" t = QTable([[1, 2], [3, 4]], names=['a', 'b']) t['a'] = MaskedColumn([5, 6], unit='m') assert isinstance(t['a'], u.Quantity) def test_do_not_replace_string_column_with_units_in_qtable(self): t = QTable([[1*u.m]]) with pytest.warns(AstropyUserWarning, match='convert it to Quantity failed'): t['a'] = Column(['a'], unit=u.m) assert isinstance(t['a'], Column) class Test__Astropy_Table__(): """ Test initializing a Table subclass from a table-like object that implements the __astropy_table__ interface method. """ class SimpleTable: def __init__(self): self.columns = [[1, 2, 3], [4, 5, 6], [7, 8, 9] * u.m] self.names = ['a', 'b', 'c'] self.meta = OrderedDict([('a', 1), ('b', 2)]) def __astropy_table__(self, cls, copy, **kwargs): a, b, c = self.columns c.info.name = 'c' cols = [table.Column(a, name='a'), table.MaskedColumn(b, name='b'), c] names = [col.info.name for col in cols] return cls(cols, names=names, copy=copy, meta=kwargs or self.meta) def test_simple_1(self): """Make a SimpleTable and convert to Table, QTable with copy=False, True""" for table_cls in (table.Table, table.QTable): col_c_class = u.Quantity if table_cls is table.QTable else table.Column for cpy in (False, True): st = self.SimpleTable() # Test putting in a non-native kwarg `extra_meta` to Table initializer t = table_cls(st, copy=cpy, extra_meta='extra!') assert t.colnames == ['a', 'b', 'c'] assert t.meta == {'extra_meta': 'extra!'} assert np.all(t['a'] == st.columns[0]) assert np.all(t['b'] == st.columns[1]) vals = t['c'].value if table_cls is table.QTable else t['c'] assert np.all(st.columns[2].value == vals) assert isinstance(t['a'], table.Column) assert isinstance(t['b'], table.MaskedColumn) assert isinstance(t['c'], col_c_class) assert t['c'].unit is u.m assert type(t) is table_cls # Copy being respected? t['a'][0] = 10 assert st.columns[0][0] == 1 if cpy else 10 def test_simple_2(self): """Test converting a SimpleTable and changing column names and types""" st = self.SimpleTable() dtypes = [np.int32, np.float32, np.float16] names = ['a', 'b', 'c'] meta = OrderedDict([('c', 3)]) t = table.Table(st, dtype=dtypes, names=names, meta=meta) assert t.colnames == names assert all(col.dtype.type is dtype for col, dtype in zip(t.columns.values(), dtypes)) # The supplied meta is overrides the existing meta. Changed in astropy 3.2. assert t.meta != st.meta assert t.meta == meta def test_kwargs_exception(self): """If extra kwargs provided but without initializing with a table-like object, exception is raised""" with pytest.raises(TypeError) as err: table.Table([[1]], extra_meta='extra!') assert '__init__() got unexpected keyword argument' in str(err.value) class TestUpdate(): def _setup(self): self.a = Column((1, 2, 3), name='a') self.b = Column((4, 5, 6), name='b') self.c = Column((7, 8, 9), name='c') self.d = Column((10, 11, 12), name='d') def test_different_lengths(self): self._setup() t1 = Table([self.a]) t2 = Table([self.b[:-1]]) msg = 'Inconsistent data column lengths' with pytest.raises(ValueError, match=msg): t1.update(t2) # If update didn't succeed then t1 and t2 should not have changed. assert t1.colnames == ['a'] assert np.all(t1['a'] == self.a) assert t2.colnames == ['b'] assert np.all(t2['b'] == self.b[:-1]) def test_invalid_inputs(self): # If input is invalid then nothing should be modified. self._setup() t = Table([self.a]) d = {'b': self.b, 'c': [0]} msg = 'Inconsistent data column lengths: {1, 3}' with pytest.raises(ValueError, match=msg): t.update(d) assert t.colnames == ['a'] assert np.all(t['a'] == self.a) assert d == {'b': self.b, 'c': [0]} def test_metadata_conflict(self): self._setup() t1 = Table([self.a], meta={'a': 0, 'b': [0], 'c': True}) t2 = Table([self.b], meta={'a': 1, 'b': [1]}) t2meta = copy.deepcopy(t2.meta) t1.update(t2) assert t1.meta == {'a': 1, 'b': [0, 1], 'c': True} # t2 metadata should not have changed. assert t2.meta == t2meta def test_update(self): self._setup() t1 = Table([self.a, self.b]) t2 = Table([self.b, self.c]) t2['b'] += 1 t1.update(t2) assert t1.colnames == ['a', 'b', 'c'] assert np.all(t1['a'] == self.a) assert np.all(t1['b'] == self.b+1) assert np.all(t1['c'] == self.c) # t2 should not have changed. assert t2.colnames == ['b', 'c'] assert np.all(t2['b'] == self.b+1) assert np.all(t2['c'] == self.c) d = {'b': list(self.b), 'd': list(self.d)} dc = copy.deepcopy(d) t2.update(d) assert t2.colnames == ['b', 'c', 'd'] assert np.all(t2['b'] == self.b) assert np.all(t2['c'] == self.c) assert np.all(t2['d'] == self.d) # d should not have changed. assert d == dc # Columns were copied, so changing t2 shouldn't have affected t1. assert t1.colnames == ['a', 'b', 'c'] assert np.all(t1['a'] == self.a) assert np.all(t1['b'] == self.b+1) assert np.all(t1['c'] == self.c) def test_update_without_copy(self): self._setup() t1 = Table([self.a, self.b]) t2 = Table([self.b, self.c]) t1.update(t2, copy=False) t2['b'] -= 1 assert t1.colnames == ['a', 'b', 'c'] assert np.all(t1['a'] == self.a) assert np.all(t1['b'] == self.b-1) assert np.all(t1['c'] == self.c) d = {'b': np.array(self.b), 'd': np.array(self.d)} t2.update(d, copy=False) d['b'] *= 2 assert t2.colnames == ['b', 'c', 'd'] assert np.all(t2['b'] == 2*self.b) assert np.all(t2['c'] == self.c) assert np.all(t2['d'] == self.d) def test_table_meta_copy(): """ Test no copy vs light (key) copy vs deep copy of table meta for different situations. #8404. """ t = table.Table([[1]]) meta = {1: [1, 2]} # Assigning meta directly implies using direct object reference t.meta = meta assert t.meta is meta # Table slice implies key copy, so values are unchanged t2 = t[:] assert t2.meta is not t.meta # NOT the same OrderedDict object but equal assert t2.meta == t.meta assert t2.meta[1] is t.meta[1] # Value IS the list same object # Table init with copy=False implies key copy t2 = table.Table(t, copy=False) assert t2.meta is not t.meta # NOT the same OrderedDict object but equal assert t2.meta == t.meta assert t2.meta[1] is t.meta[1] # Value IS the same list object # Table init with copy=True implies deep copy t2 = table.Table(t, copy=True) assert t2.meta is not t.meta # NOT the same OrderedDict object but equal assert t2.meta == t.meta assert t2.meta[1] is not t.meta[1] # Value is NOT the same list object def test_table_meta_copy_with_meta_arg(): """ Test no copy vs light (key) copy vs deep copy of table meta when meta is supplied as a table init argument. #8404. """ meta = {1: [1, 2]} meta2 = {2: [3, 4]} t = table.Table([[1]], meta=meta, copy=False) assert t.meta is meta t = table.Table([[1]], meta=meta) # default copy=True assert t.meta is not meta assert t.meta == meta # Test initializing from existing table with meta with copy=False t2 = table.Table(t, meta=meta2, copy=False) assert t2.meta is meta2 assert t2.meta != t.meta # Change behavior in #8404 # Test initializing from existing table with meta with default copy=True t2 = table.Table(t, meta=meta2) assert t2.meta is not meta2 assert t2.meta != t.meta # Change behavior in #8404 # Table init with copy=True and empty dict meta gets that empty dict t2 = table.Table(t, copy=True, meta={}) assert t2.meta == {} # Table init with copy=True and kwarg meta=None gets the original table dict. # This is a somewhat ambiguous case because it could be interpreted as the # user wanting NO meta set on the output. This could be implemented by inspecting # call args. t2 = table.Table(t, copy=True, meta=None) assert t2.meta == t.meta # Test initializing empty table with meta with copy=False t = table.Table(meta=meta, copy=False) assert t.meta is meta assert t.meta[1] is meta[1] # Test initializing empty table with meta with default copy=True (deepcopy meta) t = table.Table(meta=meta) assert t.meta is not meta assert t.meta == meta assert t.meta[1] is not meta[1] def test_replace_column_qtable(): """Replace existing Quantity column with a new column in a QTable""" a = [1, 2, 3] * u.m b = [4, 5, 6] t = table.QTable([a, b], names=['a', 'b']) ta = t['a'] tb = t['b'] ta.info.meta = {'aa': [0, 1, 2, 3, 4]} ta.info.format = '%f' t.replace_column('a', a.to('cm')) assert np.all(t['a'] == ta) assert t['a'] is not ta # New a column assert t['b'] is tb # Original b column unchanged assert t.colnames == ['a', 'b'] assert t['a'].info.meta is None assert t['a'].info.format is None def test_replace_update_column_via_setitem(): """ Test table update like ``t['a'] = value``. This leverages off the already well-tested ``replace_column`` and in-place update ``t['a'][:] = value``, so this testing is fairly light. """ a = [1, 2] * u.m b = [3, 4] t = table.QTable([a, b], names=['a', 'b']) assert isinstance(t['a'], u.Quantity) # Inplace update ta = t['a'] t['a'] = 5 * u.m assert np.all(t['a'] == [5, 5] * u.m) assert t['a'] is ta # Replace t['a'] = [5, 6] assert np.all(t['a'] == [5, 6]) assert isinstance(t['a'], table.Column) assert t['a'] is not ta def test_replace_update_column_via_setitem_warnings_normal(): """ Test warnings related to table replace change in #5556: Normal warning-free replace """ t = table.Table([[1, 2, 3], [4, 5, 6]], names=['a', 'b']) with table.conf.set_temp('replace_warnings', ['refcount', 'attributes', 'slice']): t['a'] = 0 # in-place update t['a'] = [10, 20, 30] # replace column def test_replace_update_column_via_setitem_warnings_slice(): """ Test warnings related to table replace change in #5556: Replace a slice, one warning. """ t = table.Table([[1, 2, 3], [4, 5, 6]], names=['a', 'b']) with table.conf.set_temp('replace_warnings', ['refcount', 'attributes', 'slice']): t2 = t[:2] t2['a'] = 0 # in-place slice update assert np.all(t['a'] == [0, 0, 3]) with pytest.warns(TableReplaceWarning, match="replaced column 'a' " "which looks like an array slice") as w: t2['a'] = [10, 20] # replace slice assert len(w) == 1 def test_replace_update_column_via_setitem_warnings_attributes(): """ Test warnings related to table replace change in #5556: Lost attributes. """ t = table.Table([[1, 2, 3], [4, 5, 6]], names=['a', 'b']) t['a'].unit = 'm' with pytest.warns(TableReplaceWarning, match=r"replaced column 'a' " r"and column attributes \['unit'\]") as w: with table.conf.set_temp('replace_warnings', ['refcount', 'attributes', 'slice']): t['a'] = [10, 20, 30] assert len(w) == 1 def test_replace_update_column_via_setitem_warnings_refcount(): """ Test warnings related to table replace change in #5556: Reference count changes. """ t = table.Table([[1, 2, 3], [4, 5, 6]], names=['a', 'b']) ta = t['a'] # noqa : Generate an extra reference to original column with pytest.warns(TableReplaceWarning, match="replaced column 'a' and the " "number of references") as w: with table.conf.set_temp('replace_warnings', ['refcount', 'attributes', 'slice']): t['a'] = [10, 20, 30] assert len(w) == 1 def test_replace_update_column_via_setitem_warnings_always(): """ Test warnings related to table replace change in #5556: Test 'always' setting that raises warning for any replace. """ from inspect import currentframe, getframeinfo t = table.Table([[1, 2, 3], [4, 5, 6]], names=['a', 'b']) with table.conf.set_temp('replace_warnings', ['always']): t['a'] = 0 # in-place slice update with pytest.warns(TableReplaceWarning, match="replaced column 'a'") as w: frameinfo = getframeinfo(currentframe()) t['a'] = [10, 20, 30] # replace column assert len(w) == 1 # Make sure the warning points back to the user code line assert w[0].lineno == frameinfo.lineno + 1 assert 'test_table' in w[0].filename def test_replace_update_column_via_setitem_replace_inplace(): """ Test the replace_inplace config option related to #5556. In this case no replace is done. """ t = table.Table([[1, 2, 3], [4, 5, 6]], names=['a', 'b']) ta = t['a'] t['a'].unit = 'm' with table.conf.set_temp('replace_inplace', True): with table.conf.set_temp('replace_warnings', ['always', 'refcount', 'attributes', 'slice']): t['a'] = 0 # in-place update assert ta is t['a'] t['a'] = [10, 20, 30] # normally replaces column, but not now assert ta is t['a'] assert np.all(t['a'] == [10, 20, 30]) def test_primary_key_is_inherited(): """Test whether a new Table inherits the primary_key attribute from its parent Table. Issue #4672""" t = table.Table([(2, 3, 2, 1), (8, 7, 6, 5)], names=('a', 'b')) t.add_index('a') original_key = t.primary_key # can't test if tuples are equal, so just check content assert original_key[0] == 'a' t2 = t[:] t3 = t.copy() t4 = table.Table(t) # test whether the reference is the same in the following assert original_key == t2.primary_key assert original_key == t3.primary_key assert original_key == t4.primary_key # just test one element, assume rest are equal if assert passes assert t.loc[1] == t2.loc[1] assert t.loc[1] == t3.loc[1] assert t.loc[1] == t4.loc[1] def test_qtable_read_for_ipac_table_with_char_columns(): '''Test that a char column of a QTable is assigned no unit and not a dimensionless unit, otherwise conversion of reader output to QTable fails.''' t1 = table.QTable([["A"]], names="B") out = StringIO() t1.write(out, format="ascii.ipac") t2 = table.QTable.read(out.getvalue(), format="ascii.ipac", guess=False) assert t2["B"].unit is None def test_create_table_from_final_row(): """Regression test for issue #8422: passing the last row of a table into Table should return a new table containing that row.""" t1 = table.Table([(1, 2)], names=['col']) row = t1[-1] t2 = table.Table(row)['col'] assert t2[0] == 2 def test_key_values_in_as_array(): # Test for checking column slicing using key_values in Table.as_array() data_rows = [(1, 2.0, 'x'), (4, 5.0, 'y'), (5, 8.2, 'z')] # Creating a table with three columns t1 = table.Table(rows=data_rows, names=('a', 'b', 'c'), meta={'name': 'first table'}, dtype=('i4', 'f8', 'S1')) # Values of sliced column a,b is stored in a numpy array a = np.array([(1, 2.), (4, 5.), (5, 8.2)], dtype=[('a', '' t = MyTable([[1, 2]]) # __attributes__ created on the fly on the first access of an attribute # that has a non-None default. assert '__attributes__' not in t.meta assert t.foo is None assert '__attributes__' not in t.meta assert t.baz == 1 assert '__attributes__' in t.meta t.bar.append(2.0) assert t.bar == [2.0] assert t.baz == 1 t.baz = 'baz' assert t.baz == 'baz' # Table attributes round-trip through pickle tp = pickle.loads(pickle.dumps(t)) assert tp.foo is None assert tp.baz == 'baz' assert tp.bar == [2.0] # Allow initialization of attributes in table creation, with / without data for data in None, [[1, 2]]: t2 = MyTable(data, foo=3, bar='bar', baz='baz') assert t2.foo == 3 assert t2.bar == 'bar' assert t2.baz == 'baz' # Initializing from an existing MyTable works, with and without kwarg attrs t3 = MyTable(t2) assert t3.foo == 3 assert t3.bar == 'bar' assert t3.baz == 'baz' t3 = MyTable(t2, foo=5, bar='fubar') assert t3.foo == 5 assert t3.bar == 'fubar' assert t3.baz == 'baz' # Deleting attributes removes it from attributes del t.baz assert 'baz' not in t.meta['__attributes__'] del t.bar assert '__attributes__' not in t.meta def test_table_attribute_ecsv(): # Table attribute round-trip through ECSV t = MyTable([[1, 2]], bar=[2.0], baz='baz') out = StringIO() t.write(out, format='ascii.ecsv') t2 = MyTable.read(out.getvalue(), format='ascii.ecsv') assert t2.foo is None assert t2.bar == [2.0] assert t2.baz == 'baz' def test_table_attribute_fail(): # Code raises ValueError(f'{attr} not allowed as TableAttribute') but in this # context it gets re-raised as a RuntimeError during class definition. with pytest.raises(RuntimeError, match='Error calling __set_name__'): class MyTable2(Table): descriptions = TableAttribute() # Conflicts with init arg with pytest.raises(RuntimeError, match='Error calling __set_name__'): class MyTable3(Table): colnames = TableAttribute() # Conflicts with built-in property def test_set_units_fail(): dat = [[1.0, 2.0], ['aa', 'bb']] with pytest.raises(ValueError, match='sequence of unit values must match number of columns'): Table(dat, units=[u.m]) with pytest.raises(ValueError, match='invalid column name c for setting unit attribute'): Table(dat, units={'c': u.m}) def test_set_units(): dat = [[1.0, 2.0], ['aa', 'bb'], [3, 4]] exp_units = (u.m, None, None) for cls in Table, QTable: for units in ({'a': u.m, 'c': ''}, exp_units): qt = cls(dat, units=units, names=['a', 'b', 'c']) if cls is QTable: assert isinstance(qt['a'], u.Quantity) assert isinstance(qt['b'], table.Column) assert isinstance(qt['c'], table.Column) for col, unit in zip(qt.itercols(), exp_units): assert col.info.unit is unit def test_set_descriptions(): dat = [[1.0, 2.0], ['aa', 'bb']] exp_descriptions = ('my description', None) for cls in Table, QTable: for descriptions in ({'a': 'my description'}, exp_descriptions): qt = cls(dat, descriptions=descriptions, names=['a', 'b']) for col, description in zip(qt.itercols(), exp_descriptions): assert col.info.description == description def test_set_units_from_row(): text = ['a,b', ',s', '1,2', '3,4'] units = Table.read(text, format='ascii', data_start=1, data_end=2)[0] t = Table.read(text, format='ascii', data_start=2, units=units) assert isinstance(units, table.Row) assert t['a'].info.unit is None assert t['b'].info.unit is u.s def test_set_units_descriptions_read(): """Test setting units and descriptions via Table.read. The test here is less comprehensive because the implementation is exactly the same as for Table.__init__ (calling Table._set_column_attribute) """ for cls in Table, QTable: t = cls.read(['a b', '1 2'], format='ascii', units=[u.m, u.s], descriptions=['hi', 'there']) assert t['a'].info.unit is u.m assert t['b'].info.unit is u.s assert t['a'].info.description == 'hi' assert t['b'].info.description == 'there' def test_broadcasting_8933(): """Explicitly check re-work of code related to broadcasting in #8933""" t = table.Table([[1, 2]]) # Length=2 table t['a'] = [[3, 4]] # Can broadcast if ndim > 1 and shape[0] == 1 t['b'] = 5 t['c'] = [1] # Treat as broadcastable scalar, not length=1 array (which would fail) assert np.all(t['a'] == [[3, 4], [3, 4]]) assert np.all(t['b'] == [5, 5]) assert np.all(t['c'] == [1, 1]) # Test that broadcasted column is writeable t['c'][1] = 10 assert np.all(t['c'] == [1, 10]) def test_custom_masked_column_in_nonmasked_table(): """Test the refactor and change in column upgrades introduced in 95902650f. This fixes a regression introduced by #8789 (Change behavior of Table regarding masked columns).""" class MyMaskedColumn(table.MaskedColumn): pass class MySubMaskedColumn(MyMaskedColumn): pass class MyColumn(table.Column): pass class MySubColumn(MyColumn): pass class MyTable(table.Table): Column = MyColumn MaskedColumn = MyMaskedColumn a = table.Column([1]) b = table.MaskedColumn([2], mask=[True]) c = MyMaskedColumn([3], mask=[True]) d = MySubColumn([4]) e = MySubMaskedColumn([5], mask=[True]) # Two different pathways for making table t1 = MyTable([a, b, c, d, e], names=['a', 'b', 'c', 'd', 'e']) t2 = MyTable() t2['a'] = a t2['b'] = b t2['c'] = c t2['d'] = d t2['e'] = e for t in (t1, t2): assert type(t['a']) is MyColumn assert type(t['b']) is MyMaskedColumn # upgrade assert type(t['c']) is MyMaskedColumn assert type(t['d']) is MySubColumn assert type(t['e']) is MySubMaskedColumn # sub-class not downgraded def test_sort_with_mutable_skycoord(): """Test sorting a table that has a mutable column such as SkyCoord. In this case the sort is done in-place """ t = Table([[2, 1], SkyCoord([4, 3], [6, 5], unit='deg,deg')], names=['a', 'sc']) meta = {'a': [1, 2]} ta = t['a'] tsc = t['sc'] t['sc'].info.meta = meta t.sort('a') assert np.all(t['a'] == [1, 2]) assert np.allclose(t['sc'].ra.to_value(u.deg), [3, 4]) assert np.allclose(t['sc'].dec.to_value(u.deg), [5, 6]) assert t['a'] is ta assert t['sc'] is tsc # Prior to astropy 4.1 this was a deep copy of SkyCoord column; after 4.1 # it is a reference. t['sc'].info.meta['a'][0] = 100 assert meta['a'][0] == 100 def test_sort_with_non_mutable(): """Test sorting a table that has a non-mutable column. """ t = Table([[2, 1], [3, 4]], names=['a', 'b']) ta = t['a'] tb = t['b'] t['b'].setflags(write=False) meta = {'a': [1, 2]} t['b'].info.meta = meta t.sort('a') assert np.all(t['a'] == [1, 2]) assert np.all(t['b'] == [4, 3]) assert ta is t['a'] assert tb is not t['b'] # Prior to astropy 4.1 this was a deep copy of SkyCoord column; after 4.1 # it is a reference. t['b'].info.meta['a'][0] = 100 assert meta['a'][0] == 1 def test_init_with_list_of_masked_arrays(): """Test the fix for #8977""" m0 = np.ma.array([0, 1, 2], mask=[True, False, True]) m1 = np.ma.array([3, 4, 5], mask=[False, True, False]) mc = [m0, m1] # Test _init_from_list t = table.Table([mc], names=['a']) # Test add_column t['b'] = [m1, m0] assert t['a'].shape == (2, 3) assert np.all(t['a'][0] == m0) assert np.all(t['a'][1] == m1) assert np.all(t['a'][0].mask == m0.mask) assert np.all(t['a'][1].mask == m1.mask) assert t['b'].shape == (2, 3) assert np.all(t['b'][0] == m1) assert np.all(t['b'][1] == m0) assert np.all(t['b'][0].mask == m1.mask) assert np.all(t['b'][1].mask == m0.mask) def test_data_to_col_convert_strategy(): """Test the update to how data_to_col works (#8972), using the regression example from #8971. """ t = table.Table([[0, 1]]) t['a'] = 1 t['b'] = np.int64(2) # Failed previously assert np.all(t['a'] == [1, 1]) assert np.all(t['b'] == [2, 2]) def test_rows_with_mixins(): """Test for #9165 to allow adding a list of mixin objects. Also test for fix to #9357 where group_by() failed due to mixin object not having info.indices set to []. """ tm = Time([1, 2], format='cxcsec') q = [1, 2] * u.m mixed1 = [1 * u.m, 2] # Mixed input, fails to convert to Quantity mixed2 = [2, 1 * u.m] # Mixed input, not detected as potential mixin rows = [(1, q[0], tm[0]), (2, q[1], tm[1])] t = table.QTable(rows=rows) t['a'] = [q[0], q[1]] t['b'] = [tm[0], tm[1]] t['m1'] = mixed1 t['m2'] = mixed2 assert np.all(t['col1'] == q) assert np.all(t['col2'] == tm) assert np.all(t['a'] == q) assert np.all(t['b'] == tm) assert np.all(t['m1'][ii] == mixed1[ii] for ii in range(2)) assert np.all(t['m2'][ii] == mixed2[ii] for ii in range(2)) assert type(t['m1']) is table.Column assert t['m1'].dtype is np.dtype(object) assert type(t['m2']) is table.Column assert t['m2'].dtype is np.dtype(object) # Ensure group_by() runs without failing for sortable columns. # The columns 'm1', and 'm2' are object dtype and not sortable. for name in ['col0', 'col1', 'col2', 'a', 'b']: t.group_by(name) # For good measure include exactly the failure in #9357 in which the # list of Time() objects is in the Table initializer. mjds = [Time(58000, format="mjd")] t = Table([mjds, ["gbt"]], names=("mjd", "obs")) t.group_by("obs") def test_iterrows(): dat = [(1, 2, 3), (4, 5, 6), (7, 8, 6)] t = table.Table(rows=dat, names=('a', 'b', 'c')) c_s = [] a_s = [] for c, a in t.iterrows('c', 'a'): a_s.append(a) c_s.append(c) assert np.all(t['a'] == a_s) assert np.all(t['c'] == c_s) rows = [row for row in t.iterrows()] assert rows == dat with pytest.raises(ValueError, match='d is not a valid column name'): t.iterrows('d') def test_values_and_types(): dat = [(1, 2, 3), (4, 5, 6), (7, 8, 6)] t = table.Table(rows=dat, names=('a', 'b', 'c')) assert isinstance(t.values(), type(OrderedDict().values())) assert isinstance(t.columns.values(), type(OrderedDict().values())) assert isinstance(t.columns.keys(), type(OrderedDict().keys())) for i in t.values(): assert isinstance(i, table.column.Column) def test_items(): dat = [(1, 2, 3), (4, 5, 6), (7, 8, 9)] t = table.Table(rows=dat, names=('a', 'b', 'c')) assert isinstance(t.items(), type(OrderedDict({}).items())) for i in list(t.items()): assert isinstance(i, tuple) def test_read_write_not_replaceable(): t = table.Table() with pytest.raises(AttributeError): t.read = 'fake_read' with pytest.raises(AttributeError): t.write = 'fake_write' def test_keep_columns_with_generator(): # Regression test for #12529 t = table.table_helpers.simple_table(1) t.keep_columns(col for col in t.colnames if col == 'a') assert t.colnames == ['a'] def test_remove_columns_with_generator(): # Regression test for #12529 t = table.table_helpers.simple_table(1) t.remove_columns(col for col in t.colnames if col == 'a') assert t.colnames == ['b', 'c'] def test_keep_columns_invalid_names_messages(): t = table.table_helpers.simple_table(1) with pytest.raises(KeyError, match='column "d" does not exist'): t.keep_columns(['c', 'd']) with pytest.raises(KeyError, match='columns {\'[de]\', \'[de]\'} do not exist'): t.keep_columns(['c', 'd', 'e']) def test_remove_columns_invalid_names_messages(): t = table.table_helpers.simple_table(1) with pytest.raises(KeyError, match='column "d" does not exist'): t.remove_columns(['c', 'd']) with pytest.raises(KeyError, match='columns {\'[de]\', \'[de]\'} do not exist'): t.remove_columns(['c', 'd', 'e']) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1712518 astropy-5.0.2/astropy/tests/0000755000175100001710000000000000000000000015110 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/tests/__init__.py0000644000175100001710000000034500000000000017223 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This package contains utilities to run the astropy test suite, tools for writing tests, and general tests that are not associated with a particular package. """ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/tests/command.py0000644000175100001710000003303000000000000017077 0ustar00vstsdocker"""Implements the wrapper for the Astropy test runner. This is for backward-compatibility for other downstream packages and can be removed once astropy-helpers has reached end-of-life. """ import os import stat import shutil import subprocess import sys import tempfile from contextlib import contextmanager from setuptools import Command from astropy.logger import log @contextmanager def _suppress_stdout(): ''' A context manager to temporarily disable stdout. Used later when installing a temporary copy of astropy to avoid a very verbose output. ''' with open(os.devnull, "w") as devnull: old_stdout = sys.stdout sys.stdout = devnull try: yield finally: sys.stdout = old_stdout class FixRemoteDataOption(type): """ This metaclass is used to catch cases where the user is running the tests with --remote-data. We've now changed the --remote-data option so that it takes arguments, but we still want --remote-data to work as before and to enable all remote tests. With this metaclass, we can modify sys.argv before setuptools try to parse the command-line options. """ def __init__(cls, name, bases, dct): try: idx = sys.argv.index('--remote-data') except ValueError: pass else: sys.argv[idx] = '--remote-data=any' try: idx = sys.argv.index('-R') except ValueError: pass else: sys.argv[idx] = '-R=any' return super().__init__(name, bases, dct) class AstropyTest(Command, metaclass=FixRemoteDataOption): description = 'Run the tests for this package' user_options = [ ('package=', 'P', "The name of a specific package to test, e.g. 'io.fits' or 'utils'. " "Accepts comma separated string to specify multiple packages. " "If nothing is specified, all default tests are run."), ('test-path=', 't', 'Specify a test location by path. If a relative path to a .py file, ' 'it is relative to the built package, so e.g., a leading "astropy/" ' 'is necessary. If a relative path to a .rst file, it is relative to ' 'the directory *below* the --docs-path directory, so a leading ' '"docs/" is usually necessary. May also be an absolute path.'), ('verbose-results', 'V', 'Turn on verbose output from pytest.'), ('plugins=', 'p', 'Plugins to enable when running pytest.'), ('pastebin=', 'b', "Enable pytest pastebin output. Either 'all' or 'failed'."), ('args=', 'a', 'Additional arguments to be passed to pytest.'), ('remote-data=', 'R', 'Run tests that download remote data. Should be ' 'one of none/astropy/any (defaults to none).'), ('pep8', '8', 'Enable PEP8 checking and disable regular tests. ' 'Requires the pytest-pep8 plugin.'), ('pdb', 'd', 'Start the interactive Python debugger on errors.'), ('coverage', 'c', 'Create a coverage report. Requires the coverage package.'), ('open-files', 'o', 'Fail if any tests leave files open. Requires the ' 'psutil package.'), ('parallel=', 'j', 'Run the tests in parallel on the specified number of ' 'CPUs. If "auto", all the cores on the machine will be ' 'used. Requires the pytest-xdist plugin.'), ('docs-path=', None, 'The path to the documentation .rst files. If not provided, and ' 'the current directory contains a directory called "docs", that ' 'will be used.'), ('skip-docs', None, "Don't test the documentation .rst files."), ('repeat=', None, 'How many times to repeat each test (can be used to check for ' 'sporadic failures).'), ('temp-root=', None, 'The root directory in which to create the temporary testing files. ' 'If unspecified the system default is used (e.g. /tmp) as explained ' 'in the documentation for tempfile.mkstemp.'), ('verbose-install', None, 'Turn on terminal output from the installation of astropy in a ' 'temporary folder.'), ('readonly', None, 'Make the temporary installation being tested read-only.') ] package_name = '' def initialize_options(self): self.package = None self.test_path = None self.verbose_results = False self.plugins = None self.pastebin = None self.args = None self.remote_data = 'none' self.pep8 = False self.pdb = False self.coverage = False self.open_files = False self.parallel = 0 self.docs_path = None self.skip_docs = False self.repeat = None self.temp_root = None self.verbose_install = False self.readonly = False def finalize_options(self): # Normally we would validate the options here, but that's handled in # run_tests pass def generate_testing_command(self): """ Build a Python script to run the tests. """ cmd_pre = '' # Commands to run before the test function cmd_post = '' # Commands to run after the test function if self.coverage: pre, post = self._generate_coverage_commands() cmd_pre += pre cmd_post += post set_flag = "import builtins; builtins._ASTROPY_TEST_ = True" cmd = ('{cmd_pre}{0}; import {1.package_name}, sys; result = (' '{1.package_name}.test(' 'package={1.package!r}, ' 'test_path={1.test_path!r}, ' 'args={1.args!r}, ' 'plugins={1.plugins!r}, ' 'verbose={1.verbose_results!r}, ' 'pastebin={1.pastebin!r}, ' 'remote_data={1.remote_data!r}, ' 'pep8={1.pep8!r}, ' 'pdb={1.pdb!r}, ' 'open_files={1.open_files!r}, ' 'parallel={1.parallel!r}, ' 'docs_path={1.docs_path!r}, ' 'skip_docs={1.skip_docs!r}, ' 'add_local_eggs_to_path=True, ' # see _build_temp_install below 'repeat={1.repeat!r})); ' '{cmd_post}' 'sys.exit(result)') return cmd.format(set_flag, self, cmd_pre=cmd_pre, cmd_post=cmd_post) def run(self): """ Run the tests! """ # Install the runtime dependencies. if self.distribution.install_requires: self.distribution.fetch_build_eggs(self.distribution.install_requires) # Ensure there is a doc path if self.docs_path is None: cfg_docs_dir = self.distribution.get_option_dict('build_docs').get('source_dir', None) # Some affiliated packages use this. # See astropy/package-template#157 if cfg_docs_dir is not None and os.path.exists(cfg_docs_dir[1]): self.docs_path = os.path.abspath(cfg_docs_dir[1]) # fall back on a default path of "docs" elif os.path.exists('docs'): # pragma: no cover self.docs_path = os.path.abspath('docs') # Build a testing install of the package self._build_temp_install() # Install the test dependencies # NOTE: we do this here after _build_temp_install because there is # a weird but which occurs if psutil is installed in this way before # astropy is built, Cython can have segmentation fault. Strange, eh? if self.distribution.tests_require: self.distribution.fetch_build_eggs(self.distribution.tests_require) # Copy any additional dependencies that may have been installed via # tests_requires or install_requires. We then pass the # add_local_eggs_to_path=True option to package.test() to make sure the # eggs get included in the path. if os.path.exists('.eggs'): shutil.copytree('.eggs', os.path.join(self.testing_path, '.eggs')) # This option exists so that we can make sure that the tests don't # write to an installed location. if self.readonly: log.info('changing permissions of temporary installation to read-only') self._change_permissions_testing_path(writable=False) # Run everything in a try: finally: so that the tmp dir gets deleted. try: # Construct this modules testing command cmd = self.generate_testing_command() # Run the tests in a subprocess--this is necessary since # new extension modules may have appeared, and this is the # easiest way to set up a new environment testproc = subprocess.Popen( [sys.executable, '-c', cmd], cwd=self.testing_path, close_fds=False) retcode = testproc.wait() except KeyboardInterrupt: import signal # If a keyboard interrupt is handled, pass it to the test # subprocess to prompt pytest to initiate its teardown testproc.send_signal(signal.SIGINT) retcode = testproc.wait() finally: # Remove temporary directory if self.readonly: self._change_permissions_testing_path(writable=True) shutil.rmtree(self.tmp_dir) raise SystemExit(retcode) def _build_temp_install(self): """ Install the package and to a temporary directory for the purposes of testing. This allows us to test the install command, include the entry points, and also avoids creating pyc and __pycache__ directories inside the build directory """ # On OSX the default path for temp files is under /var, but in most # cases on OSX /var is actually a symlink to /private/var; ensure we # dereference that link, because pytest is very sensitive to relative # paths... tmp_dir = tempfile.mkdtemp(prefix=self.package_name + '-test-', dir=self.temp_root) self.tmp_dir = os.path.realpath(tmp_dir) log.info(f'installing to temporary directory: {self.tmp_dir}') # We now install the package to the temporary directory. We do this # rather than build and copy because this will ensure that e.g. entry # points work. self.reinitialize_command('install') install_cmd = self.distribution.get_command_obj('install') install_cmd.prefix = self.tmp_dir if self.verbose_install: self.run_command('install') else: with _suppress_stdout(): self.run_command('install') # We now get the path to the site-packages directory that was created # inside self.tmp_dir install_cmd = self.get_finalized_command('install') self.testing_path = install_cmd.install_lib # Ideally, docs_path is set properly in run(), but if it is still # not set here, do not pretend it is, otherwise bad things happen. # See astropy/package-template#157 if self.docs_path is not None: new_docs_path = os.path.join(self.testing_path, os.path.basename(self.docs_path)) shutil.copytree(self.docs_path, new_docs_path) self.docs_path = new_docs_path shutil.copy('setup.cfg', self.testing_path) def _change_permissions_testing_path(self, writable=False): if writable: basic_flags = stat.S_IRUSR | stat.S_IWUSR else: basic_flags = stat.S_IRUSR for root, dirs, files in os.walk(self.testing_path): for dirname in dirs: os.chmod(os.path.join(root, dirname), basic_flags | stat.S_IXUSR) for filename in files: os.chmod(os.path.join(root, filename), basic_flags) def _generate_coverage_commands(self): """ This method creates the post and pre commands if coverage is to be generated """ if self.parallel != 0: raise ValueError( "--coverage can not be used with --parallel") try: import coverage # pylint: disable=W0611 except ImportError: raise ImportError( "--coverage requires that the coverage package is " "installed.") # Don't use get_pkg_data_filename here, because it # requires importing astropy.config and thus screwing # up coverage results for those packages. coveragerc = os.path.join( self.testing_path, self.package_name.replace('.', '/'), 'tests', 'coveragerc') with open(coveragerc, 'r') as fd: coveragerc_content = fd.read() coveragerc_content = coveragerc_content.replace( "{packagename}", self.package_name.replace('.', '/')) tmp_coveragerc = os.path.join(self.tmp_dir, 'coveragerc') with open(tmp_coveragerc, 'wb') as tmp: tmp.write(coveragerc_content.encode('utf-8')) cmd_pre = ( 'import coverage; ' 'cov = coverage.coverage(data_file=r"{}", config_file=r"{}"); ' 'cov.start();'.format( os.path.abspath(".coverage"), os.path.abspath(tmp_coveragerc))) cmd_post = ( 'cov.stop(); ' 'from astropy.tests.helper import _save_coverage; ' '_save_coverage(cov, result, r"{}", r"{}");'.format( os.path.abspath('.'), os.path.abspath(self.testing_path))) return cmd_pre, cmd_post ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/tests/disable_internet.py0000644000175100001710000000275200000000000021003 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This is retained only for backwards compatibility. Affiliated packages should no longer import ``disable_internet`` from ``astropy.tests``. It is now available from ``pytest_remotedata``. However, this is not the recommended mechanism for controlling access to remote data in tests. Instead, packages should make use of decorators provided by the pytest_remotedata plugin: - ``@pytest.mark.remote_data`` for tests that require remote data access - ``@pytest.mark.internet_off`` for tests that should only run when remote data access is disabled. Remote data access for the test suite is controlled by the ``--remote-data`` command line flag. This is passed to ``pytest`` directly. TODO: This module should eventually be removed once backwards compatibility is no longer supported. """ from warnings import warn from astropy.utils.exceptions import AstropyDeprecationWarning warn("The ``disable_internet`` module is no longer provided by astropy. It " "is now available as ``pytest_remotedata.disable_internet``. However, " "developers are encouraged to avoid using this module directly. See " " " "for more information.", AstropyDeprecationWarning) try: # This should only be necessary during testing, in which case the test # package must be installed anyway. from pytest_remotedata.disable_internet import * except ImportError: pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/tests/helper.py0000644000175100001710000004011200000000000016737 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This module provides the tools used to internally run the astropy test suite from the installed astropy. It makes use of the `pytest`_ testing framework. """ import os import sys import pickle import warnings import functools import pytest from astropy.units import allclose as quantity_allclose # noqa from astropy.utils.exceptions import (AstropyDeprecationWarning, AstropyPendingDeprecationWarning) # For backward-compatibility with affiliated packages from .runner import TestRunner # pylint: disable=W0611 # noqa __all__ = ['raises', 'enable_deprecations_as_exceptions', 'remote_data', 'treat_deprecations_as_exceptions', 'catch_warnings', 'assert_follows_unicode_guidelines', 'assert_quantity_allclose', 'check_pickling_recovery', 'pickle_protocol', 'generic_recursive_equality_test'] # pytest marker to mark tests which get data from the web # This is being maintained for backwards compatibility remote_data = pytest.mark.remote_data def _save_coverage(cov, result, rootdir, testing_path): """ This method is called after the tests have been run in coverage mode to cleanup and then save the coverage data and report. """ from astropy.utils.console import color_print if result != 0: return # The coverage report includes the full path to the temporary # directory, so we replace all the paths with the true source # path. Note that this will not work properly for packages that still # rely on 2to3. try: # Coverage 4.0: _harvest_data has been renamed to get_data, the # lines dict is private cov.get_data() except AttributeError: # Coverage < 4.0 cov._harvest_data() lines = cov.data.lines else: lines = cov.data._lines for key in list(lines.keys()): new_path = os.path.relpath( os.path.realpath(key), os.path.realpath(testing_path)) new_path = os.path.abspath( os.path.join(rootdir, new_path)) lines[new_path] = lines.pop(key) color_print('Saving coverage data in .coverage...', 'green') cov.save() color_print('Saving HTML coverage report in htmlcov...', 'green') cov.html_report(directory=os.path.join(rootdir, 'htmlcov')) # TODO: Plan a roadmap of deprecation as pytest.raises has matured over the years. # See https://github.com/astropy/astropy/issues/6761 class raises: """ A decorator to mark that a test should raise a given exception. Use as follows:: @raises(ZeroDivisionError) def test_foo(): x = 1/0 This can also be used a context manager, in which case it is just an alias for the ``pytest.raises`` context manager (because the two have the same name this help avoid confusion by being flexible). .. note:: Usage of ``pytest.raises`` is preferred. """ # pep-8 naming exception -- this is a decorator class def __init__(self, exc): self._exc = exc self._ctx = None def __call__(self, func): @functools.wraps(func) def run_raises_test(*args, **kwargs): pytest.raises(self._exc, func, *args, **kwargs) return run_raises_test def __enter__(self): self._ctx = pytest.raises(self._exc) return self._ctx.__enter__() def __exit__(self, *exc_info): return self._ctx.__exit__(*exc_info) _deprecations_as_exceptions = False _include_astropy_deprecations = True _modules_to_ignore_on_import = set([ r'compiler', # A deprecated stdlib module used by pytest r'scipy', r'pygments', r'ipykernel', r'IPython', # deprecation warnings for async and await r'setuptools']) _warnings_to_ignore_entire_module = set([]) _warnings_to_ignore_by_pyver = { None: set([ # Python version agnostic # https://github.com/astropy/astropy/pull/7372 (r"Importing from numpy\.testing\.decorators is deprecated, " r"import from numpy\.testing instead\.", DeprecationWarning), # inspect raises this slightly different warning on Python 3.7. # Keeping it since e.g. lxml as of 3.8.0 is still calling getargspec() (r"inspect\.getargspec\(\) is deprecated, use " r"inspect\.signature\(\) or inspect\.getfullargspec\(\)", DeprecationWarning), # https://github.com/astropy/pytest-doctestplus/issues/29 (r"split\(\) requires a non-empty pattern match", FutureWarning), # Package resolution warning that we can do nothing about (r"can't resolve package from __spec__ or __package__, " r"falling back on __name__ and __path__", ImportWarning)]), (3, 7): set([ # Deprecation warning for collections.abc, fixed in Astropy but still # used in lxml, and maybe others (r"Using or importing the ABCs from 'collections'", DeprecationWarning)]) } def enable_deprecations_as_exceptions(include_astropy_deprecations=True, modules_to_ignore_on_import=[], warnings_to_ignore_entire_module=[], warnings_to_ignore_by_pyver={}): """ Turn on the feature that turns deprecations into exceptions. Parameters ---------- include_astropy_deprecations : bool If set to `True`, ``AstropyDeprecationWarning`` and ``AstropyPendingDeprecationWarning`` are also turned into exceptions. modules_to_ignore_on_import : list of str List of additional modules that generate deprecation warnings on import, which are to be ignored. By default, these are already included: ``compiler``, ``scipy``, ``pygments``, ``ipykernel``, and ``setuptools``. warnings_to_ignore_entire_module : list of str List of modules with deprecation warnings to ignore completely, not just during import. If ``include_astropy_deprecations=True`` is given, ``AstropyDeprecationWarning`` and ``AstropyPendingDeprecationWarning`` are also ignored for the modules. warnings_to_ignore_by_pyver : dict Dictionary mapping tuple of ``(major, minor)`` Python version to a list of ``(warning_message, warning_class)`` to ignore. Python version-agnostic warnings should be mapped to `None` key. This is in addition of those already ignored by default (see ``_warnings_to_ignore_by_pyver`` values). """ global _deprecations_as_exceptions _deprecations_as_exceptions = True global _include_astropy_deprecations _include_astropy_deprecations = include_astropy_deprecations global _modules_to_ignore_on_import _modules_to_ignore_on_import.update(modules_to_ignore_on_import) global _warnings_to_ignore_entire_module _warnings_to_ignore_entire_module.update(warnings_to_ignore_entire_module) global _warnings_to_ignore_by_pyver for key, val in warnings_to_ignore_by_pyver.items(): if key in _warnings_to_ignore_by_pyver: _warnings_to_ignore_by_pyver[key].update(val) else: _warnings_to_ignore_by_pyver[key] = set(val) def treat_deprecations_as_exceptions(): """ Turn all DeprecationWarnings (which indicate deprecated uses of Python itself or Numpy, but not within Astropy, where we use our own deprecation warning class) into exceptions so that we find out about them early. This completely resets the warning filters and any "already seen" warning state. """ # First, totally reset the warning state. The modules may change during # this iteration thus we copy the original state to a list to iterate # on. See https://github.com/astropy/astropy/pull/5513. for module in list(sys.modules.values()): try: del module.__warningregistry__ except Exception: pass if not _deprecations_as_exceptions: return warnings.resetwarnings() # Hide the next couple of DeprecationWarnings warnings.simplefilter('ignore', DeprecationWarning) # Here's the wrinkle: a couple of our third-party dependencies # (pytest and scipy) are still using deprecated features # themselves, and we'd like to ignore those. Fortunately, those # show up only at import time, so if we import those things *now*, # before we turn the warnings into exceptions, we're golden. for m in _modules_to_ignore_on_import: try: __import__(m) except ImportError: pass # Now, start over again with the warning filters warnings.resetwarnings() # Now, turn these warnings into exceptions _all_warns = [DeprecationWarning, FutureWarning, ImportWarning] # Only turn astropy deprecation warnings into exceptions if requested if _include_astropy_deprecations: _all_warns += [AstropyDeprecationWarning, AstropyPendingDeprecationWarning] for w in _all_warns: warnings.filterwarnings("error", ".*", w) # This ignores all specified warnings from given module(s), # not just on import, for use of Astropy affiliated packages. for m in _warnings_to_ignore_entire_module: for w in _all_warns: warnings.filterwarnings('ignore', category=w, module=m) # This ignores only specified warnings by Python version, if applicable. for v in _warnings_to_ignore_by_pyver: if v is None or sys.version_info[:2] == v: for s in _warnings_to_ignore_by_pyver[v]: warnings.filterwarnings("ignore", s[0], s[1]) # TODO: Plan a roadmap of deprecation as pytest.warns has matured over the years. # See https://github.com/astropy/astropy/issues/6761 class catch_warnings(warnings.catch_warnings): """ A high-powered version of warnings.catch_warnings to use for testing and to make sure that there is no dependence on the order in which the tests are run. This completely blitzes any memory of any warnings that have appeared before so that all warnings will be caught and displayed. ``*args`` is a set of warning classes to collect. If no arguments are provided, all warnings are collected. Use as follows:: with catch_warnings(MyCustomWarning) as w: do.something.bad() assert len(w) > 0 .. note:: Usage of :ref:`pytest.warns ` is preferred. """ def __init__(self, *classes): super().__init__(record=True) self.classes = classes def __enter__(self): warning_list = super().__enter__() treat_deprecations_as_exceptions() if len(self.classes) == 0: warnings.simplefilter('always') else: warnings.simplefilter('ignore') for cls in self.classes: warnings.simplefilter('always', cls) return warning_list def __exit__(self, type, value, traceback): treat_deprecations_as_exceptions() class ignore_warnings(catch_warnings): """ This can be used either as a context manager or function decorator to ignore all warnings that occur within a function or block of code. An optional category option can be supplied to only ignore warnings of a certain category or categories (if a list is provided). """ def __init__(self, category=None): super().__init__() if isinstance(category, type) and issubclass(category, Warning): self.category = [category] else: self.category = category def __call__(self, func): @functools.wraps(func) def wrapper(*args, **kwargs): # Originally this just reused self, but that doesn't work if the # function is called more than once so we need to make a new # context manager instance for each call with self.__class__(category=self.category): return func(*args, **kwargs) return wrapper def __enter__(self): retval = super().__enter__() if self.category is not None: for category in self.category: warnings.simplefilter('ignore', category) else: warnings.simplefilter('ignore') return retval def assert_follows_unicode_guidelines( x, roundtrip=None): """ Test that an object follows our Unicode policy. See "Unicode guidelines" in the coding guidelines. Parameters ---------- x : object The instance to test roundtrip : module, optional When provided, this namespace will be used to evaluate ``repr(x)`` and ensure that it roundtrips. It will also ensure that ``__bytes__(x)`` roundtrip. If not provided, no roundtrip testing will be performed. """ from astropy import conf with conf.set_temp('unicode_output', False): bytes_x = bytes(x) unicode_x = str(x) repr_x = repr(x) assert isinstance(bytes_x, bytes) bytes_x.decode('ascii') assert isinstance(unicode_x, str) unicode_x.encode('ascii') assert isinstance(repr_x, str) if isinstance(repr_x, bytes): repr_x.decode('ascii') else: repr_x.encode('ascii') if roundtrip is not None: assert x.__class__(bytes_x) == x assert x.__class__(unicode_x) == x assert eval(repr_x, roundtrip) == x with conf.set_temp('unicode_output', True): bytes_x = bytes(x) unicode_x = str(x) repr_x = repr(x) assert isinstance(bytes_x, bytes) bytes_x.decode('ascii') assert isinstance(unicode_x, str) assert isinstance(repr_x, str) if isinstance(repr_x, bytes): repr_x.decode('ascii') else: repr_x.encode('ascii') if roundtrip is not None: assert x.__class__(bytes_x) == x assert x.__class__(unicode_x) == x assert eval(repr_x, roundtrip) == x @pytest.fixture(params=[0, 1, -1]) def pickle_protocol(request): """ Fixture to run all the tests for protocols 0 and 1, and -1 (most advanced). (Originally from astropy.table.tests.test_pickle) """ return request.param def generic_recursive_equality_test(a, b, class_history): """ Check if the attributes of a and b are equal. Then, check if the attributes of the attributes are equal. """ dict_a = a.__getstate__() if hasattr(a, '__getstate__') else a.__dict__ dict_b = b.__dict__ for key in dict_a: assert key in dict_b,\ f"Did not pickle {key}" if hasattr(dict_a[key], '__eq__'): eq = (dict_a[key] == dict_b[key]) if '__iter__' in dir(eq): eq = (False not in eq) assert eq, f"Value of {key} changed by pickling" if hasattr(dict_a[key], '__dict__'): if dict_a[key].__class__ in class_history: # attempt to prevent infinite recursion pass else: new_class_history = [dict_a[key].__class__] new_class_history.extend(class_history) generic_recursive_equality_test(dict_a[key], dict_b[key], new_class_history) def check_pickling_recovery(original, protocol): """ Try to pickle an object. If successful, make sure the object's attributes survived pickling and unpickling. """ f = pickle.dumps(original, protocol=protocol) unpickled = pickle.loads(f) class_history = [original.__class__] generic_recursive_equality_test(original, unpickled, class_history) def assert_quantity_allclose(actual, desired, rtol=1.e-7, atol=None, **kwargs): """ Raise an assertion if two objects are not equal up to desired tolerance. This is a :class:`~astropy.units.Quantity`-aware version of :func:`numpy.testing.assert_allclose`. """ import numpy as np from astropy.units.quantity import _unquantify_allclose_arguments np.testing.assert_allclose(*_unquantify_allclose_arguments( actual, desired, rtol, atol), **kwargs) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/tests/image_tests.py0000644000175100001710000000134500000000000017771 0ustar00vstsdockertry: import matplotlib from matplotlib import pyplot as plt # noqa except ImportError: MPL_VERSION = '' ROOT = '' IMAGE_REFERENCE_DIR = '' else: MPL_VERSION = matplotlib.__version__ # The developer versions of the form 3.2.x+... contain changes that will only # be included in the 3.3.x release, so we update this here. if MPL_VERSION[:3] == '3.2' and '+' in MPL_VERSION: MPL_VERSION = '3.3' ROOT = "http://{server}/testing/astropy/2021-08-25T18:18:36.000000/{mpl_version}/" IMAGE_REFERENCE_DIR = ( ROOT.format(server='data.astropy.org', mpl_version=MPL_VERSION[:3] + '.x') + ',' + ROOT.format(server='www.astropy.org/astropy-data', mpl_version=MPL_VERSION[:3] + '.x')) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1712518 astropy-5.0.2/astropy/tests/plugins/0000755000175100001710000000000000000000000016571 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/tests/plugins/__init__.py0000644000175100001710000000010000000000000020671 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/tests/plugins/display.py0000644000175100001710000000136300000000000020613 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst # This plugin now lives in pytest-astropy, but we keep the code below during # a deprecation phase. import warnings from astropy.utils.exceptions import AstropyDeprecationWarning try: from pytest_astropy_header.display import (PYTEST_HEADER_MODULES, TESTED_VERSIONS) except ImportError: PYTEST_HEADER_MODULES = {} TESTED_VERSIONS = {} warnings.warn('The astropy.tests.plugins.display plugin has been deprecated. ' 'See the pytest-astropy-header documentation for information on ' 'migrating to using pytest-astropy-header to customize the ' 'pytest header.', AstropyDeprecationWarning) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/tests/runner.py0000644000175100001710000005371200000000000017003 0ustar00vstsdocker"""Implements the Astropy TestRunner which is a thin wrapper around pytest.""" import inspect import os import glob import copy import shlex import sys import tempfile import warnings from collections import OrderedDict from importlib.util import find_spec from functools import wraps from astropy.config.paths import set_temp_config, set_temp_cache from astropy.utils import find_current_module from astropy.utils.exceptions import AstropyWarning, AstropyDeprecationWarning __all__ = ['TestRunner', 'TestRunnerBase', 'keyword'] class keyword: """ A decorator to mark a method as keyword argument for the ``TestRunner``. Parameters ---------- default_value : `object` The default value for the keyword argument. (Default: `None`) priority : `int` keyword argument methods are executed in order of descending priority. """ def __init__(self, default_value=None, priority=0): self.default_value = default_value self.priority = priority def __call__(self, f): def keyword(*args, **kwargs): return f(*args, **kwargs) keyword._default_value = self.default_value keyword._priority = self.priority # Set __doc__ explicitly here rather than using wraps because we want # to keep the function name as keyword so we can inspect it later. keyword.__doc__ = f.__doc__ return keyword class TestRunnerBase: """ The base class for the TestRunner. A test runner can be constructed by creating a subclass of this class and defining 'keyword' methods. These are methods that have the :class:`~astropy.tests.runner.keyword` decorator, these methods are used to construct allowed keyword arguments to the ``run_tests`` method as a way to allow customization of individual keyword arguments (and associated logic) without having to re-implement the whole ``run_tests`` method. Examples -------- A simple keyword method:: class MyRunner(TestRunnerBase): @keyword('default_value'): def spam(self, spam, kwargs): \"\"\" spam : `str` The parameter description for the run_tests docstring. \"\"\" # Return value must be a list with a CLI parameter for pytest. return ['--spam={}'.format(spam)] """ def __init__(self, base_path): self.base_path = os.path.abspath(base_path) def __new__(cls, *args, **kwargs): # Before constructing the class parse all the methods that have been # decorated with ``keyword``. # The objective of this method is to construct a default set of keyword # arguments to the ``run_tests`` method. It does this by inspecting the # methods of the class for functions with the name ``keyword`` which is # the name of the decorator wrapping function. Once it has created this # dictionary, it also formats the docstring of ``run_tests`` to be # comprised of the docstrings for the ``keyword`` methods. # To add a keyword argument to the ``run_tests`` method, define a new # method decorated with ``@keyword`` and with the ``self, name, kwargs`` # signature. # Get all 'function' members as the wrapped methods are functions functions = inspect.getmembers(cls, predicate=inspect.isfunction) # Filter out anything that's not got the name 'keyword' keywords = filter(lambda func: func[1].__name__ == 'keyword', functions) # Sort all keywords based on the priority flag. sorted_keywords = sorted(keywords, key=lambda x: x[1]._priority, reverse=True) cls.keywords = OrderedDict() doc_keywords = "" for name, func in sorted_keywords: # Here we test if the function has been overloaded to return # NotImplemented which is the way to disable arguments on # subclasses. If it has been disabled we need to remove it from the # default keywords dict. We do it in the try except block because # we do not have access to an instance of the class, so this is # going to error unless the method is just doing `return # NotImplemented`. try: # Second argument is False, as it is normally a bool. # The other two are placeholders for objects. if func(None, False, None) is NotImplemented: continue except Exception: pass # Construct the default kwargs dict and docstring cls.keywords[name] = func._default_value if func.__doc__: doc_keywords += ' '*8 doc_keywords += func.__doc__.strip() doc_keywords += '\n\n' cls.run_tests.__doc__ = cls.RUN_TESTS_DOCSTRING.format(keywords=doc_keywords) return super().__new__(cls) def _generate_args(self, **kwargs): # Update default values with passed kwargs # but don't modify the defaults keywords = copy.deepcopy(self.keywords) keywords.update(kwargs) # Iterate through the keywords (in order of priority) args = [] for keyword in keywords.keys(): func = getattr(self, keyword) result = func(keywords[keyword], keywords) # Allow disabling of options in a subclass if result is NotImplemented: raise TypeError(f"run_tests() got an unexpected keyword argument {keyword}") # keyword methods must return a list if not isinstance(result, list): raise TypeError(f"{keyword} keyword method must return a list") args += result return args RUN_TESTS_DOCSTRING = \ """ Run the tests for the package. This method builds arguments for and then calls ``pytest.main``. Parameters ---------- {keywords} """ _required_dependencies = ['pytest', 'pytest_remotedata', 'pytest_doctestplus', 'pytest_astropy_header'] _missing_dependancy_error = ( "Test dependencies are missing: {module}. You should install the " "'pytest-astropy' package (you may need to update the package if you " "have a previous version installed, e.g., " "'pip install pytest-astropy --upgrade' or the equivalent with conda).") @classmethod def _has_test_dependencies(cls): # pragma: no cover # Using the test runner will not work without these dependencies, but # pytest-openfiles is optional, so it's not listed here. for module in cls._required_dependencies: spec = find_spec(module) # Checking loader accounts for packages that were uninstalled if spec is None or spec.loader is None: raise RuntimeError( cls._missing_dependancy_error.format(module=module)) def run_tests(self, **kwargs): # The following option will include eggs inside a .eggs folder in # sys.path when running the tests. This is possible so that when # running pytest, test dependencies installed via e.g. # tests_requires are available here. This is not an advertised option # since it is only for internal use if kwargs.pop('add_local_eggs_to_path', False): # Add each egg to sys.path individually for egg in glob.glob(os.path.join('.eggs', '*.egg')): sys.path.insert(0, egg) self._has_test_dependencies() # pragma: no cover # The docstring for this method is defined as a class variable. # This allows it to be built for each subclass in __new__. # Don't import pytest until it's actually needed to run the tests import pytest # Raise error for undefined kwargs allowed_kwargs = set(self.keywords.keys()) passed_kwargs = set(kwargs.keys()) if not passed_kwargs.issubset(allowed_kwargs): wrong_kwargs = list(passed_kwargs.difference(allowed_kwargs)) raise TypeError(f"run_tests() got an unexpected keyword argument {wrong_kwargs[0]}") args = self._generate_args(**kwargs) if kwargs.get('plugins', None) is not None: plugins = kwargs.pop('plugins') elif self.keywords.get('plugins', None) is not None: plugins = self.keywords['plugins'] else: plugins = [] # Override the config locations to not make a new directory nor use # existing cache or config. Note that we need to do this here in # addition to in conftest.py - for users running tests interactively # in e.g. IPython, conftest.py would get read in too late, so we need # to do it here - but at the same time the code here doesn't work when # running tests in parallel mode because this uses subprocesses which # don't know about the temporary config/cache. astropy_config = tempfile.mkdtemp('astropy_config') astropy_cache = tempfile.mkdtemp('astropy_cache') # Have to use nested with statements for cross-Python support # Note, using these context managers here is superfluous if the # config_dir or cache_dir options to pytest are in use, but it's # also harmless to nest the contexts with set_temp_config(astropy_config, delete=True): with set_temp_cache(astropy_cache, delete=True): return pytest.main(args=args, plugins=plugins) @classmethod def make_test_runner_in(cls, path): """ Constructs a `TestRunner` to run in the given path, and returns a ``test()`` function which takes the same arguments as ``TestRunner.run_tests``. The returned ``test()`` function will be defined in the module this was called from. This is used to implement the ``astropy.test()`` function (or the equivalent for affiliated packages). """ runner = cls(path) @wraps(runner.run_tests, ('__doc__',)) def test(**kwargs): return runner.run_tests(**kwargs) module = find_current_module(2) if module is not None: test.__module__ = module.__name__ # A somewhat unusual hack, but delete the attached __wrapped__ # attribute--although this is normally used to tell if the function # was wrapped with wraps, on some version of Python this is also # used to determine the signature to display in help() which is # not useful in this case. We don't really care in this case if the # function was wrapped either if hasattr(test, '__wrapped__'): del test.__wrapped__ test.__test__ = False return test class TestRunner(TestRunnerBase): """ A test runner for astropy tests """ def packages_path(self, packages, base_path, error=None, warning=None): """ Generates the path for multiple packages. Parameters ---------- packages : str Comma separated string of packages. base_path : str Base path to the source code or documentation. error : str Error message to be raised as ``ValueError``. Individual package name and path can be accessed by ``{name}`` and ``{path}`` respectively. No error is raised if `None`. (Default: `None`) warning : str Warning message to be issued. Individual package name and path can be accessed by ``{name}`` and ``{path}`` respectively. No warning is issues if `None`. (Default: `None`) Returns ------- paths : list of str List of strings of existing package paths. """ packages = packages.split(",") paths = [] for package in packages: path = os.path.join( base_path, package.replace('.', os.path.sep)) if not os.path.isdir(path): info = {'name': package, 'path': path} if error is not None: raise ValueError(error.format(**info)) if warning is not None: warnings.warn(warning.format(**info)) else: paths.append(path) return paths # Increase priority so this warning is displayed first. @keyword(priority=1000) def coverage(self, coverage, kwargs): if coverage: warnings.warn( "The coverage option is ignored on run_tests, since it " "can not be made to work in that context. Use " "'python setup.py test --coverage' instead.", AstropyWarning) return [] # test_path depends on self.package_path so make sure this runs before # test_path. @keyword(priority=1) def package(self, package, kwargs): """ package : str, optional The name of a specific package to test, e.g. 'io.fits' or 'utils'. Accepts comma separated string to specify multiple packages. If nothing is specified all default tests are run. """ if package is None: self.package_path = [self.base_path] else: error_message = ('package to test is not found: {name} ' '(at path {path}).') self.package_path = self.packages_path(package, self.base_path, error=error_message) if not kwargs['test_path']: return self.package_path return [] @keyword() def test_path(self, test_path, kwargs): """ test_path : str, optional Specify location to test by path. May be a single file or directory. Must be specified absolutely or relative to the calling directory. """ all_args = [] # Ensure that the package kwarg has been run. self.package(kwargs['package'], kwargs) if test_path: base, ext = os.path.splitext(test_path) if ext in ('.rst', ''): if kwargs['docs_path'] is None: # This shouldn't happen from "python setup.py test" raise ValueError( "Can not test .rst files without a docs_path " "specified.") abs_docs_path = os.path.abspath(kwargs['docs_path']) abs_test_path = os.path.abspath( os.path.join(abs_docs_path, os.pardir, test_path)) common = os.path.commonprefix((abs_docs_path, abs_test_path)) if os.path.exists(abs_test_path) and common == abs_docs_path: # Turn on the doctest_rst plugin all_args.append('--doctest-rst') test_path = abs_test_path # Check that the extensions are in the path and not at the end to # support specifying the name of the test, i.e. # test_quantity.py::test_unit if not (os.path.isdir(test_path) or ('.py' in test_path or '.rst' in test_path)): raise ValueError("Test path must be a directory or a path to " "a .py or .rst file") return all_args + [test_path] return [] @keyword() def args(self, args, kwargs): """ args : str, optional Additional arguments to be passed to ``pytest.main`` in the ``args`` keyword argument. """ if args: return shlex.split(args, posix=not sys.platform.startswith('win')) return [] @keyword(default_value=[]) def plugins(self, plugins, kwargs): """ plugins : list, optional Plugins to be passed to ``pytest.main`` in the ``plugins`` keyword argument. """ # Plugins are handled independently by `run_tests` so we define this # keyword just for the docstring return [] @keyword() def verbose(self, verbose, kwargs): """ verbose : bool, optional Convenience option to turn on verbose output from pytest. Passing True is the same as specifying ``-v`` in ``args``. """ if verbose: return ['-v'] return [] @keyword() def pastebin(self, pastebin, kwargs): """ pastebin : ('failed', 'all', None), optional Convenience option for turning on pytest pastebin output. Set to 'failed' to upload info for failed tests, or 'all' to upload info for all tests. """ if pastebin is not None: if pastebin in ['failed', 'all']: return [f'--pastebin={pastebin}'] else: raise ValueError("pastebin should be 'failed' or 'all'") return [] @keyword(default_value='none') def remote_data(self, remote_data, kwargs): """ remote_data : {'none', 'astropy', 'any'}, optional Controls whether to run tests marked with @pytest.mark.remote_data. This can be set to run no tests with remote data (``none``), only ones that use data from http://data.astropy.org (``astropy``), or all tests that use remote data (``any``). The default is ``none``. """ if remote_data is True: remote_data = 'any' elif remote_data is False: remote_data = 'none' elif remote_data not in ('none', 'astropy', 'any'): warnings.warn("The remote_data option should be one of " "none/astropy/any (found {}). For backward-compatibility, " "assuming 'any', but you should change the option to be " "one of the supported ones to avoid issues in " "future.".format(remote_data), AstropyDeprecationWarning) remote_data = 'any' return [f'--remote-data={remote_data}'] @keyword() def pep8(self, pep8, kwargs): """ pep8 : bool, optional Turn on PEP8 checking via the pytest-pep8 plugin and disable normal tests. Same as specifying ``--pep8 -k pep8`` in ``args``. """ if pep8: try: import pytest_pep8 # pylint: disable=W0611 except ImportError: raise ImportError('PEP8 checking requires pytest-pep8 plugin: ' 'https://pypi.org/project/pytest-pep8') else: return ['--pep8', '-k', 'pep8'] return [] @keyword() def pdb(self, pdb, kwargs): """ pdb : bool, optional Turn on PDB post-mortem analysis for failing tests. Same as specifying ``--pdb`` in ``args``. """ if pdb: return ['--pdb'] return [] @keyword() def open_files(self, open_files, kwargs): """ open_files : bool, optional Fail when any tests leave files open. Off by default, because this adds extra run time to the test suite. Requires the ``psutil`` package. """ if open_files: if kwargs['parallel'] != 0: raise SystemError( "open file detection may not be used in conjunction with " "parallel testing.") try: import psutil # pylint: disable=W0611 except ImportError: raise SystemError( "open file detection requested, but psutil package " "is not installed.") return ['--open-files'] print("Checking for unclosed files") return [] @keyword(0) def parallel(self, parallel, kwargs): """ parallel : int or 'auto', optional When provided, run the tests in parallel on the specified number of CPUs. If parallel is ``'auto'``, it will use the all the cores on the machine. Requires the ``pytest-xdist`` plugin. """ if parallel != 0: try: from xdist import plugin # noqa except ImportError: raise SystemError( "running tests in parallel requires the pytest-xdist package") return ['-n', str(parallel)] return [] @keyword() def docs_path(self, docs_path, kwargs): """ docs_path : str, optional The path to the documentation .rst files. """ paths = [] if docs_path is not None and not kwargs['skip_docs']: if kwargs['package'] is not None: warning_message = ("Can not test .rst docs for {name}, since " "docs path ({path}) does not exist.") paths = self.packages_path(kwargs['package'], docs_path, warning=warning_message) elif not kwargs['test_path']: paths = [docs_path, ] if len(paths) and not kwargs['test_path']: paths.append('--doctest-rst') return paths @keyword() def skip_docs(self, skip_docs, kwargs): """ skip_docs : `bool`, optional When `True`, skips running the doctests in the .rst files. """ # Skip docs is a bool used by docs_path only. return [] @keyword() def repeat(self, repeat, kwargs): """ repeat : `int`, optional If set, specifies how many times each test should be run. This is useful for diagnosing sporadic failures. """ if repeat: return [f'--repeat={repeat}'] return [] # Override run_tests for astropy-specific fixes def run_tests(self, **kwargs): # This prevents cyclical import problems that make it # impossible to test packages that define Table types on their # own. from astropy.table import Table # pylint: disable=W0611 return super().run_tests(**kwargs) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/tests/test_logger.py0000644000175100001710000003710600000000000020007 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import importlib import sys import warnings import logging import locale import pytest from astropy import log from astropy.logger import LoggingError, conf from astropy.utils.exceptions import AstropyWarning, AstropyUserWarning # Save original values of hooks. These are not the system values, but the # already overwritten values since the logger already gets imported before # this file gets executed. _excepthook = sys.__excepthook__ _showwarning = warnings.showwarning try: ip = get_ipython() except NameError: ip = None def setup_function(function): # Reset modules to default importlib.reload(warnings) importlib.reload(sys) # Reset internal original hooks log._showwarning_orig = None log._excepthook_orig = None # Set up the logger log._set_defaults() # Reset hooks if log.warnings_logging_enabled(): log.disable_warnings_logging() if log.exception_logging_enabled(): log.disable_exception_logging() teardown_module = setup_function def test_warnings_logging_disable_no_enable(): with pytest.raises(LoggingError) as e: log.disable_warnings_logging() assert e.value.args[0] == 'Warnings logging has not been enabled' def test_warnings_logging_enable_twice(): log.enable_warnings_logging() with pytest.raises(LoggingError) as e: log.enable_warnings_logging() assert e.value.args[0] == 'Warnings logging has already been enabled' def test_warnings_logging_overridden(): log.enable_warnings_logging() warnings.showwarning = lambda: None with pytest.raises(LoggingError, match=r'Cannot disable warnings logging: ' r'warnings\.showwarning was not set by this logger, or has been overridden'): log.disable_warnings_logging() def test_warnings_logging(): # Without warnings logging with pytest.warns(AstropyUserWarning, match="This is a warning") as warn_list: with log.log_to_list() as log_list: warnings.warn("This is a warning", AstropyUserWarning) assert len(log_list) == 0 assert len(warn_list) == 1 # With warnings logging with warnings.catch_warnings(record=True) as warn_list: log.enable_warnings_logging() with log.log_to_list() as log_list: warnings.warn("This is a warning", AstropyUserWarning) log.disable_warnings_logging() assert len(log_list) == 1 assert len(warn_list) == 0 assert log_list[0].levelname == 'WARNING' assert log_list[0].message.startswith('This is a warning') assert log_list[0].origin == 'astropy.tests.test_logger' # With warnings logging (differentiate between Astropy and non-Astropy) with pytest.warns(UserWarning, match="This is another warning, not " "from Astropy") as warn_list: log.enable_warnings_logging() with log.log_to_list() as log_list: warnings.warn("This is a warning", AstropyUserWarning) warnings.warn("This is another warning, not from Astropy") log.disable_warnings_logging() assert len(log_list) == 1 assert len(warn_list) == 1 assert log_list[0].levelname == 'WARNING' assert log_list[0].message.startswith('This is a warning') assert log_list[0].origin == 'astropy.tests.test_logger' # Without warnings logging with pytest.warns(AstropyUserWarning, match="This is a warning") as warn_list: with log.log_to_list() as log_list: warnings.warn("This is a warning", AstropyUserWarning) assert len(log_list) == 0 assert len(warn_list) == 1 def test_warnings_logging_with_custom_class(): class CustomAstropyWarningClass(AstropyWarning): pass # With warnings logging with warnings.catch_warnings(record=True) as warn_list: log.enable_warnings_logging() with log.log_to_list() as log_list: warnings.warn("This is a warning", CustomAstropyWarningClass) log.disable_warnings_logging() assert len(log_list) == 1 assert len(warn_list) == 0 assert log_list[0].levelname == 'WARNING' assert log_list[0].message.startswith('CustomAstropyWarningClass: This is a warning') assert log_list[0].origin == 'astropy.tests.test_logger' def test_warning_logging_with_io_votable_warning(): from astropy.io.votable.exceptions import W02, vo_warn with warnings.catch_warnings(record=True) as warn_list: log.enable_warnings_logging() with log.log_to_list() as log_list: vo_warn(W02, ('a', 'b')) log.disable_warnings_logging() assert len(log_list) == 1 assert len(warn_list) == 0 assert log_list[0].levelname == 'WARNING' x = log_list[0].message.startswith("W02: ?:?:?: W02: a attribute 'b' is " "invalid. Must be a standard XML id") assert x assert log_list[0].origin == 'astropy.tests.test_logger' def test_import_error_in_warning_logging(): """ Regression test for https://github.com/astropy/astropy/issues/2671 This test actually puts a goofy fake module into ``sys.modules`` to test this problem. """ class FakeModule: def __getattr__(self, attr): raise ImportError('_showwarning should ignore any exceptions ' 'here') log.enable_warnings_logging() sys.modules[''] = FakeModule() try: warnings.showwarning(AstropyWarning('Regression test for #2671'), AstropyWarning, '', 1) finally: del sys.modules[''] def test_exception_logging_disable_no_enable(): with pytest.raises(LoggingError) as e: log.disable_exception_logging() assert e.value.args[0] == 'Exception logging has not been enabled' def test_exception_logging_enable_twice(): log.enable_exception_logging() with pytest.raises(LoggingError) as e: log.enable_exception_logging() assert e.value.args[0] == 'Exception logging has already been enabled' # You can't really override the exception handler in IPython this way, so # this test doesn't really make sense in the IPython context. @pytest.mark.skipif("ip is not None") def test_exception_logging_overridden(): log.enable_exception_logging() sys.excepthook = lambda etype, evalue, tb: None with pytest.raises(LoggingError, match='Cannot disable exception logging: ' 'sys.excepthook was not set by this logger, or has been overridden'): log.disable_exception_logging() @pytest.mark.xfail("ip is not None") def test_exception_logging(): # Without exception logging try: with log.log_to_list() as log_list: raise Exception("This is an Exception") except Exception as exc: sys.excepthook(*sys.exc_info()) assert exc.args[0] == "This is an Exception" else: assert False # exception should have been raised assert len(log_list) == 0 # With exception logging try: log.enable_exception_logging() with log.log_to_list() as log_list: raise Exception("This is an Exception") except Exception as exc: sys.excepthook(*sys.exc_info()) assert exc.args[0] == "This is an Exception" else: assert False # exception should have been raised assert len(log_list) == 1 assert log_list[0].levelname == 'ERROR' assert log_list[0].message.startswith('Exception: This is an Exception') assert log_list[0].origin == 'astropy.tests.test_logger' # Without exception logging log.disable_exception_logging() try: with log.log_to_list() as log_list: raise Exception("This is an Exception") except Exception as exc: sys.excepthook(*sys.exc_info()) assert exc.args[0] == "This is an Exception" else: assert False # exception should have been raised assert len(log_list) == 0 @pytest.mark.xfail("ip is not None") def test_exception_logging_origin(): # The point here is to get an exception raised from another location # and make sure the error's origin is reported correctly from astropy.utils.collections import HomogeneousList l = HomogeneousList(int) # noqa try: log.enable_exception_logging() with log.log_to_list() as log_list: l.append('foo') except TypeError as exc: sys.excepthook(*sys.exc_info()) assert exc.args[0].startswith( "homogeneous list must contain only objects of type ") else: assert False assert len(log_list) == 1 assert log_list[0].levelname == 'ERROR' assert log_list[0].message.startswith( "TypeError: homogeneous list must contain only objects of type ") assert log_list[0].origin == 'astropy.utils.collections' @pytest.mark.skip(reason="Infinite recursion on Python 3.5+, probably a real issue") # @pytest.mark.xfail("ip is not None") def test_exception_logging_argless_exception(): """ Regression test for a crash that occurred on Python 3 when logging an exception that was instantiated with no arguments (no message, etc.) Regression test for https://github.com/astropy/astropy/pull/4056 """ try: log.enable_exception_logging() with log.log_to_list() as log_list: raise Exception() except Exception: sys.excepthook(*sys.exc_info()) else: assert False # exception should have been raised assert len(log_list) == 1 assert log_list[0].levelname == 'ERROR' assert log_list[0].message == 'Exception [astropy.tests.test_logger]' assert log_list[0].origin == 'astropy.tests.test_logger' @pytest.mark.parametrize(('level'), [None, 'DEBUG', 'INFO', 'WARN', 'ERROR']) def test_log_to_list(level): orig_level = log.level try: if level is not None: log.setLevel(level) with log.log_to_list() as log_list: log.error("Error message") log.warning("Warning message") log.info("Information message") log.debug("Debug message") finally: log.setLevel(orig_level) if level is None: # The log level *should* be set to whatever it was in the config level = conf.log_level # Check list length if level == 'DEBUG': assert len(log_list) == 4 elif level == 'INFO': assert len(log_list) == 3 elif level == 'WARN': assert len(log_list) == 2 elif level == 'ERROR': assert len(log_list) == 1 # Check list content assert log_list[0].levelname == 'ERROR' assert log_list[0].message.startswith('Error message') assert log_list[0].origin == 'astropy.tests.test_logger' if len(log_list) >= 2: assert log_list[1].levelname == 'WARNING' assert log_list[1].message.startswith('Warning message') assert log_list[1].origin == 'astropy.tests.test_logger' if len(log_list) >= 3: assert log_list[2].levelname == 'INFO' assert log_list[2].message.startswith('Information message') assert log_list[2].origin == 'astropy.tests.test_logger' if len(log_list) >= 4: assert log_list[3].levelname == 'DEBUG' assert log_list[3].message.startswith('Debug message') assert log_list[3].origin == 'astropy.tests.test_logger' def test_log_to_list_level(): with log.log_to_list(filter_level='ERROR') as log_list: log.error("Error message") log.warning("Warning message") assert len(log_list) == 1 and log_list[0].levelname == 'ERROR' def test_log_to_list_origin1(): with log.log_to_list(filter_origin='astropy.tests') as log_list: log.error("Error message") log.warning("Warning message") assert len(log_list) == 2 def test_log_to_list_origin2(): with log.log_to_list(filter_origin='astropy.wcs') as log_list: log.error("Error message") log.warning("Warning message") assert len(log_list) == 0 @pytest.mark.parametrize(('level'), [None, 'DEBUG', 'INFO', 'WARN', 'ERROR']) def test_log_to_file(tmpdir, level): local_path = tmpdir.join('test.log') log_file = local_path.open('wb') log_path = str(local_path.realpath()) orig_level = log.level try: if level is not None: log.setLevel(level) with log.log_to_file(log_path): log.error("Error message") log.warning("Warning message") log.info("Information message") log.debug("Debug message") log_file.close() finally: log.setLevel(orig_level) log_file = local_path.open('rb') log_entries = log_file.readlines() log_file.close() if level is None: # The log level *should* be set to whatever it was in the config level = conf.log_level # Check list length if level == 'DEBUG': assert len(log_entries) == 4 elif level == 'INFO': assert len(log_entries) == 3 elif level == 'WARN': assert len(log_entries) == 2 elif level == 'ERROR': assert len(log_entries) == 1 # Check list content assert eval(log_entries[0].strip())[-3:] == ( 'astropy.tests.test_logger', 'ERROR', 'Error message') if len(log_entries) >= 2: assert eval(log_entries[1].strip())[-3:] == ( 'astropy.tests.test_logger', 'WARNING', 'Warning message') if len(log_entries) >= 3: assert eval(log_entries[2].strip())[-3:] == ( 'astropy.tests.test_logger', 'INFO', 'Information message') if len(log_entries) >= 4: assert eval(log_entries[3].strip())[-3:] == ( 'astropy.tests.test_logger', 'DEBUG', 'Debug message') def test_log_to_file_level(tmpdir): local_path = tmpdir.join('test.log') log_file = local_path.open('wb') log_path = str(local_path.realpath()) with log.log_to_file(log_path, filter_level='ERROR'): log.error("Error message") log.warning("Warning message") log_file.close() log_file = local_path.open('rb') log_entries = log_file.readlines() log_file.close() assert len(log_entries) == 1 assert eval(log_entries[0].strip())[-2:] == ( 'ERROR', 'Error message') def test_log_to_file_origin1(tmpdir): local_path = tmpdir.join('test.log') log_file = local_path.open('wb') log_path = str(local_path.realpath()) with log.log_to_file(log_path, filter_origin='astropy.tests'): log.error("Error message") log.warning("Warning message") log_file.close() log_file = local_path.open('rb') log_entries = log_file.readlines() log_file.close() assert len(log_entries) == 2 def test_log_to_file_origin2(tmpdir): local_path = tmpdir.join('test.log') log_file = local_path.open('wb') log_path = str(local_path.realpath()) with log.log_to_file(log_path, filter_origin='astropy.wcs'): log.error("Error message") log.warning("Warning message") log_file.close() log_file = local_path.open('rb') log_entries = log_file.readlines() log_file.close() assert len(log_entries) == 0 @pytest.mark.parametrize(('encoding'), ['', 'utf-8', 'cp1252']) def test_log_to_file_encoding(tmpdir, encoding): local_path = tmpdir.join('test.log') log_path = str(local_path.realpath()) orig_encoding = conf.log_file_encoding conf.log_file_encoding = encoding with log.log_to_file(log_path): for handler in log.handlers: if isinstance(handler, logging.FileHandler): if encoding: assert handler.stream.encoding == encoding else: assert handler.stream.encoding == locale.getpreferredencoding() conf.log_file_encoding = orig_encoding ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1712518 astropy-5.0.2/astropy/tests/tests/0000755000175100001710000000000000000000000016252 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/tests/tests/__init__.py0000644000175100001710000000000000000000000020351 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/tests/tests/test_imports.py0000644000175100001710000000153000000000000021357 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import pkgutil def test_imports(): """ This just imports all modules in astropy, making sure they don't have any dependencies that sneak through """ def onerror(name): # We should raise any legitimate error that occurred, but not # any warnings which happen to be caught because of our pytest # settings (e.g., DeprecationWarning). try: raise except Warning: pass for imper, nm, ispkg in pkgutil.walk_packages(['astropy'], 'astropy.', onerror=onerror): imper.find_spec(nm) def test_toplevel_namespace(): import astropy d = dir(astropy) assert 'os' not in d assert 'log' in d assert 'test' in d assert 'sys' not in d ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/tests/tests/test_quantity_helpers.py0000644000175100001710000000313200000000000023262 0ustar00vstsdockerimport pytest from astropy import units as u from astropy.tests.helper import assert_quantity_allclose def test_assert_quantity_allclose(): assert_quantity_allclose([1, 2], [1, 2]) assert_quantity_allclose([1, 2] * u.m, [100, 200] * u.cm) assert_quantity_allclose([1, 2] * u.m, [101, 201] * u.cm, atol=2 * u.cm) with pytest.raises(AssertionError) as exc: assert_quantity_allclose([1, 2] * u.m, [90, 200] * u.cm) assert exc.value.args[0].startswith("\nNot equal to tolerance") with pytest.raises(AssertionError): assert_quantity_allclose([1, 2] * u.m, [101, 201] * u.cm, atol=0.5 * u.cm) with pytest.raises(u.UnitsError) as exc: assert_quantity_allclose([1, 2] * u.m, [100, 200]) assert exc.value.args[0] == "Units for 'desired' () and 'actual' (m) are not convertible" with pytest.raises(u.UnitsError) as exc: assert_quantity_allclose([1, 2], [100, 200] * u.cm) assert exc.value.args[0] == "Units for 'desired' (cm) and 'actual' () are not convertible" with pytest.raises(u.UnitsError) as exc: assert_quantity_allclose([1, 2] * u.m, [100, 200] * u.cm, atol=0.3) assert exc.value.args[0] == "Units for 'atol' () and 'actual' (m) are not convertible" with pytest.raises(u.UnitsError) as exc: assert_quantity_allclose([1, 2], [1, 2], atol=0.3 * u.m) assert exc.value.args[0] == "Units for 'atol' (m) and 'actual' () are not convertible" with pytest.raises(u.UnitsError) as exc: assert_quantity_allclose([1, 2], [1, 2], rtol=0.3 * u.m) assert exc.value.args[0] == "'rtol' should be dimensionless" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/tests/tests/test_run_tests.py0000644000175100001710000000117000000000000021710 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst import pytest # test helper.run_tests function from astropy import test as run_tests # run_tests should raise ValueError when asked to run on a module it can't find def test_module_not_found(): with pytest.raises(ValueError): run_tests(package='fake.module') # run_tests should raise ValueError when passed an invalid pastebin= option def test_pastebin_keyword(): with pytest.raises(ValueError): run_tests(pastebin='not_an_option') def test_unicode_literal_conversion(): assert isinstance('ÃĨngstrÃļm', str) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/tests/tests/test_runner.py0000644000175100001710000000375200000000000021203 0ustar00vstsdockerimport pytest # Renamed these imports so that them being in the namespace will not # cause pytest 3 to discover them as tests and then complain that # they have __init__ defined. from astropy.tests.runner import TestRunner as _TestRunner from astropy.tests.runner import TestRunnerBase as _TestRunnerBase from astropy.tests.runner import keyword def test_disable_kwarg(): class no_remote_data(_TestRunner): @keyword() def remote_data(self, remote_data, kwargs): return NotImplemented r = no_remote_data('.') with pytest.raises(TypeError): r.run_tests(remote_data='bob') def test_wrong_kwarg(): r = _TestRunner('.') with pytest.raises(TypeError): r.run_tests(spam='eggs') def test_invalid_kwarg(): class bad_return(_TestRunnerBase): @keyword() def remote_data(self, remote_data, kwargs): return 'bob' r = bad_return('.') with pytest.raises(TypeError): r.run_tests(remote_data='bob') def test_new_kwarg(): class Spam(_TestRunnerBase): @keyword() def spam(self, spam, kwargs): return [spam] r = Spam('.') args = r._generate_args(spam='spam') assert ['spam'] == args def test_priority(): class Spam(_TestRunnerBase): @keyword() def spam(self, spam, kwargs): return [spam] @keyword(priority=1) def eggs(self, eggs, kwargs): return [eggs] r = Spam('.') args = r._generate_args(spam='spam', eggs='eggs') assert ['eggs', 'spam'] == args def test_docs(): class Spam(_TestRunnerBase): @keyword() def spam(self, spam, kwargs): """ Spam Spam Spam """ return [spam] @keyword() def eggs(self, eggs, kwargs): """ eggs asldjasljd """ return [eggs] r = Spam('.') assert "eggs" in r.run_tests.__doc__ assert "Spam Spam Spam" in r.run_tests.__doc__ ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1712518 astropy-5.0.2/astropy/time/0000755000175100001710000000000000000000000014704 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/time/__init__.py0000644000175100001710000000134200000000000017015 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst from astropy import config as _config class Conf(_config.ConfigNamespace): # noqa """ Configuration parameters for `astropy.table`. """ use_fast_parser = _config.ConfigItem( ['True', 'False', 'force'], "Use fast C parser for supported time strings formats, including ISO, " "ISOT, and YearDayTime. Allowed values are the 'False' (use Python parser)," "'True' (use C parser and fall through to Python parser if fails), and " "'force' (use C parser and raise exception if it fails). Note that the" "options are all strings.") conf = Conf() # noqa from .formats import * # noqa from .core import * # noqa ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/time/core.py0000644000175100001710000033737500000000000016230 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """ The astropy.time package provides functionality for manipulating times and dates. Specific emphasis is placed on supporting time scales (e.g. UTC, TAI, UT1) and time representations (e.g. JD, MJD, ISO 8601) that are used in astronomy. """ import os import copy import enum import operator import threading from datetime import datetime, date, timedelta from time import strftime from warnings import warn import numpy as np import erfa from astropy import units as u, constants as const from astropy.units import UnitConversionError from astropy.utils import ShapedLikeNDArray from astropy.utils.compat.misc import override__dir__ from astropy.utils.data_info import MixinInfo, data_info_factory from astropy.utils.exceptions import AstropyWarning from .utils import day_frac from .formats import (TIME_FORMATS, TIME_DELTA_FORMATS, TimeJD, TimeUnique, TimeAstropyTime, TimeDatetime) # Import TimeFromEpoch to avoid breaking code that followed the old example of # making a custom timescale in the documentation. from .formats import TimeFromEpoch # noqa from astropy.extern import _strptime __all__ = ['TimeBase', 'Time', 'TimeDelta', 'TimeInfo', 'update_leap_seconds', 'TIME_SCALES', 'STANDARD_TIME_SCALES', 'TIME_DELTA_SCALES', 'ScaleValueError', 'OperandTypeError'] STANDARD_TIME_SCALES = ('tai', 'tcb', 'tcg', 'tdb', 'tt', 'ut1', 'utc') LOCAL_SCALES = ('local',) TIME_TYPES = dict((scale, scales) for scales in (STANDARD_TIME_SCALES, LOCAL_SCALES) for scale in scales) TIME_SCALES = STANDARD_TIME_SCALES + LOCAL_SCALES MULTI_HOPS = {('tai', 'tcb'): ('tt', 'tdb'), ('tai', 'tcg'): ('tt',), ('tai', 'ut1'): ('utc',), ('tai', 'tdb'): ('tt',), ('tcb', 'tcg'): ('tdb', 'tt'), ('tcb', 'tt'): ('tdb',), ('tcb', 'ut1'): ('tdb', 'tt', 'tai', 'utc'), ('tcb', 'utc'): ('tdb', 'tt', 'tai'), ('tcg', 'tdb'): ('tt',), ('tcg', 'ut1'): ('tt', 'tai', 'utc'), ('tcg', 'utc'): ('tt', 'tai'), ('tdb', 'ut1'): ('tt', 'tai', 'utc'), ('tdb', 'utc'): ('tt', 'tai'), ('tt', 'ut1'): ('tai', 'utc'), ('tt', 'utc'): ('tai',), } GEOCENTRIC_SCALES = ('tai', 'tt', 'tcg') BARYCENTRIC_SCALES = ('tcb', 'tdb') ROTATIONAL_SCALES = ('ut1',) TIME_DELTA_TYPES = dict((scale, scales) for scales in (GEOCENTRIC_SCALES, BARYCENTRIC_SCALES, ROTATIONAL_SCALES, LOCAL_SCALES) for scale in scales) TIME_DELTA_SCALES = GEOCENTRIC_SCALES + BARYCENTRIC_SCALES + ROTATIONAL_SCALES + LOCAL_SCALES # For time scale changes, we need L_G and L_B, which are stored in erfam.h as # /* L_G = 1 - d(TT)/d(TCG) */ # define ERFA_ELG (6.969290134e-10) # /* L_B = 1 - d(TDB)/d(TCB), and TDB (s) at TAI 1977/1/1.0 */ # define ERFA_ELB (1.550519768e-8) # These are exposed in erfa as erfa.ELG and erfa.ELB. # Implied: d(TT)/d(TCG) = 1-L_G # and d(TCG)/d(TT) = 1/(1-L_G) = 1 + (1-(1-L_G))/(1-L_G) = 1 + L_G/(1-L_G) # scale offsets as second = first + first * scale_offset[(first,second)] SCALE_OFFSETS = {('tt', 'tai'): None, ('tai', 'tt'): None, ('tcg', 'tt'): -erfa.ELG, ('tt', 'tcg'): erfa.ELG / (1. - erfa.ELG), ('tcg', 'tai'): -erfa.ELG, ('tai', 'tcg'): erfa.ELG / (1. - erfa.ELG), ('tcb', 'tdb'): -erfa.ELB, ('tdb', 'tcb'): erfa.ELB / (1. - erfa.ELB)} # triple-level dictionary, yay! SIDEREAL_TIME_MODELS = { 'mean': { 'IAU2006': {'function': erfa.gmst06, 'scales': ('ut1', 'tt')}, 'IAU2000': {'function': erfa.gmst00, 'scales': ('ut1', 'tt')}, 'IAU1982': {'function': erfa.gmst82, 'scales': ('ut1',), 'include_tio': False} }, 'apparent': { 'IAU2006A': {'function': erfa.gst06a, 'scales': ('ut1', 'tt')}, 'IAU2000A': {'function': erfa.gst00a, 'scales': ('ut1', 'tt')}, 'IAU2000B': {'function': erfa.gst00b, 'scales': ('ut1',)}, 'IAU1994': {'function': erfa.gst94, 'scales': ('ut1',), 'include_tio': False} }} class _LeapSecondsCheck(enum.Enum): NOT_STARTED = 0 # No thread has reached the check RUNNING = 1 # A thread is running update_leap_seconds (_LEAP_SECONDS_LOCK is held) DONE = 2 # update_leap_seconds has completed _LEAP_SECONDS_CHECK = _LeapSecondsCheck.NOT_STARTED _LEAP_SECONDS_LOCK = threading.RLock() class TimeInfo(MixinInfo): """ Container for meta information like name, description, format. This is required when the object is used as a mixin column within a table, but can be used as a general way to store meta information. """ attr_names = MixinInfo.attr_names | {'serialize_method'} _supports_indexing = True # The usual tuple of attributes needed for serialization is replaced # by a property, since Time can be serialized different ways. _represent_as_dict_extra_attrs = ('format', 'scale', 'precision', 'in_subfmt', 'out_subfmt', 'location', '_delta_ut1_utc', '_delta_tdb_tt') # When serializing, write out the `value` attribute using the column name. _represent_as_dict_primary_data = 'value' mask_val = np.ma.masked @property def _represent_as_dict_attrs(self): method = self.serialize_method[self._serialize_context] if method == 'formatted_value': out = ('value',) elif method == 'jd1_jd2': out = ('jd1', 'jd2') else: raise ValueError("serialize method must be 'formatted_value' or 'jd1_jd2'") return out + self._represent_as_dict_extra_attrs def __init__(self, bound=False): super().__init__(bound) # If bound to a data object instance then create the dict of attributes # which stores the info attribute values. if bound: # Specify how to serialize this object depending on context. # If ``True`` for a context, then use formatted ``value`` attribute # (e.g. the ISO time string). If ``False`` then use float jd1 and jd2. self.serialize_method = {'fits': 'jd1_jd2', 'ecsv': 'formatted_value', 'hdf5': 'jd1_jd2', 'yaml': 'jd1_jd2', 'parquet': 'jd1_jd2', None: 'jd1_jd2'} def get_sortable_arrays(self): """ Return a list of arrays which can be lexically sorted to represent the order of the parent column. Returns ------- arrays : list of ndarray """ parent = self._parent jd_approx = parent.jd jd_remainder = (parent - parent.__class__(jd_approx, format='jd')).jd return [jd_approx, jd_remainder] @property def unit(self): return None info_summary_stats = staticmethod( data_info_factory(names=MixinInfo._stats, funcs=[getattr(np, stat) for stat in MixinInfo._stats])) # When Time has mean, std, min, max methods: # funcs = [lambda x: getattr(x, stat)() for stat_name in MixinInfo._stats]) def _construct_from_dict_base(self, map): if 'jd1' in map and 'jd2' in map: # Initialize as JD but revert to desired format and out_subfmt (if needed) format = map.pop('format') out_subfmt = map.pop('out_subfmt', None) map['format'] = 'jd' map['val'] = map.pop('jd1') map['val2'] = map.pop('jd2') out = self._parent_cls(**map) out.format = format if out_subfmt is not None: out.out_subfmt = out_subfmt else: map['val'] = map.pop('value') out = self._parent_cls(**map) return out def _construct_from_dict(self, map): delta_ut1_utc = map.pop('_delta_ut1_utc', None) delta_tdb_tt = map.pop('_delta_tdb_tt', None) out = self._construct_from_dict_base(map) if delta_ut1_utc is not None: out._delta_ut1_utc = delta_ut1_utc if delta_tdb_tt is not None: out._delta_tdb_tt = delta_tdb_tt return out def new_like(self, cols, length, metadata_conflicts='warn', name=None): """ Return a new Time instance which is consistent with the input Time objects ``cols`` and has ``length`` rows. This is intended for creating an empty Time instance whose elements can be set in-place for table operations like join or vstack. It checks that the input locations and attributes are consistent. This is used when a Time object is used as a mixin column in an astropy Table. Parameters ---------- cols : list List of input columns (Time objects) length : int Length of the output column object metadata_conflicts : str ('warn'|'error'|'silent') How to handle metadata conflicts name : str Output column name Returns ------- col : Time (or subclass) Empty instance of this class consistent with ``cols`` """ # Get merged info attributes like shape, dtype, format, description, etc. attrs = self.merge_cols_attributes(cols, metadata_conflicts, name, ('meta', 'description')) attrs.pop('dtype') # Not relevant for Time col0 = cols[0] # Check that location is consistent for all Time objects for col in cols[1:]: # This is the method used by __setitem__ to ensure that the right side # has a consistent location (and coerce data if necessary, but that does # not happen in this case since `col` is already a Time object). If this # passes then any subsequent table operations via setitem will work. try: col0._make_value_equivalent(slice(None), col) except ValueError: raise ValueError('input columns have inconsistent locations') # Make a new Time object with the desired shape and attributes shape = (length,) + attrs.pop('shape') jd2000 = 2451544.5 # Arbitrary JD value J2000.0 that will work with ERFA jd1 = np.full(shape, jd2000, dtype='f8') jd2 = np.zeros(shape, dtype='f8') tm_attrs = {attr: getattr(col0, attr) for attr in ('scale', 'location', 'precision', 'in_subfmt', 'out_subfmt')} out = self._parent_cls(jd1, jd2, format='jd', **tm_attrs) out.format = col0.format # Set remaining info attributes for attr, value in attrs.items(): setattr(out.info, attr, value) return out class TimeDeltaInfo(TimeInfo): _represent_as_dict_extra_attrs = ('format', 'scale') def _construct_from_dict(self, map): return self._construct_from_dict_base(map) def new_like(self, cols, length, metadata_conflicts='warn', name=None): """ Return a new TimeDelta instance which is consistent with the input Time objects ``cols`` and has ``length`` rows. This is intended for creating an empty Time instance whose elements can be set in-place for table operations like join or vstack. It checks that the input locations and attributes are consistent. This is used when a Time object is used as a mixin column in an astropy Table. Parameters ---------- cols : list List of input columns (Time objects) length : int Length of the output column object metadata_conflicts : str ('warn'|'error'|'silent') How to handle metadata conflicts name : str Output column name Returns ------- col : Time (or subclass) Empty instance of this class consistent with ``cols`` """ # Get merged info attributes like shape, dtype, format, description, etc. attrs = self.merge_cols_attributes(cols, metadata_conflicts, name, ('meta', 'description')) attrs.pop('dtype') # Not relevant for Time col0 = cols[0] # Make a new Time object with the desired shape and attributes shape = (length,) + attrs.pop('shape') jd1 = np.zeros(shape, dtype='f8') jd2 = np.zeros(shape, dtype='f8') out = self._parent_cls(jd1, jd2, format='jd', scale=col0.scale) out.format = col0.format # Set remaining info attributes for attr, value in attrs.items(): setattr(out.info, attr, value) return out class TimeBase(ShapedLikeNDArray): """Base time class from which Time and TimeDelta inherit.""" # Make sure that reverse arithmetic (e.g., TimeDelta.__rmul__) # gets called over the __mul__ of Numpy arrays. __array_priority__ = 20000 # Declare that Time can be used as a Table column by defining the # attribute where column attributes will be stored. _astropy_column_attrs = None def __getnewargs__(self): return (self._time,) def _init_from_vals(self, val, val2, format, scale, copy, precision=None, in_subfmt=None, out_subfmt=None): """ Set the internal _format, scale, and _time attrs from user inputs. This handles coercion into the correct shapes and some basic input validation. """ if precision is None: precision = 3 if in_subfmt is None: in_subfmt = '*' if out_subfmt is None: out_subfmt = '*' # Coerce val into an array val = _make_array(val, copy) # If val2 is not None, ensure consistency if val2 is not None: val2 = _make_array(val2, copy) try: np.broadcast(val, val2) except ValueError: raise ValueError('Input val and val2 have inconsistent shape; ' 'they cannot be broadcast together.') if scale is not None: if not (isinstance(scale, str) and scale.lower() in self.SCALES): raise ScaleValueError("Scale {!r} is not in the allowed scales " "{}".format(scale, sorted(self.SCALES))) # If either of the input val, val2 are masked arrays then # find the masked elements and fill them. mask, val, val2 = _check_for_masked_and_fill(val, val2) # Parse / convert input values into internal jd1, jd2 based on format self._time = self._get_time_fmt(val, val2, format, scale, precision, in_subfmt, out_subfmt) self._format = self._time.name # Hack from #9969 to allow passing the location value that has been # collected by the TimeAstropyTime format class up to the Time level. # TODO: find a nicer way. if hasattr(self._time, '_location'): self.location = self._time._location del self._time._location # If any inputs were masked then masked jd2 accordingly. From above # routine ``mask`` must be either Python bool False or an bool ndarray # with shape broadcastable to jd2. if mask is not False: mask = np.broadcast_to(mask, self._time.jd2.shape) self._time.jd1[mask] = 2451544.5 # Set to JD for 2000-01-01 self._time.jd2[mask] = np.nan def _get_time_fmt(self, val, val2, format, scale, precision, in_subfmt, out_subfmt): """ Given the supplied val, val2, format and scale try to instantiate the corresponding TimeFormat class to convert the input values into the internal jd1 and jd2. If format is `None` and the input is a string-type or object array then guess available formats and stop when one matches. """ if (format is None and (val.dtype.kind in ('S', 'U', 'O', 'M') or val.dtype.names)): # Input is a string, object, datetime, or a table-like ndarray # (structured array, recarray). These input types can be # uniquely identified by the format classes. formats = [(name, cls) for name, cls in self.FORMATS.items() if issubclass(cls, TimeUnique)] # AstropyTime is a pseudo-format that isn't in the TIME_FORMATS registry, # but try to guess it at the end. formats.append(('astropy_time', TimeAstropyTime)) elif not (isinstance(format, str) and format.lower() in self.FORMATS): if format is None: raise ValueError("No time format was given, and the input is " "not unique") else: raise ValueError("Format {!r} is not one of the allowed " "formats {}".format(format, sorted(self.FORMATS))) else: formats = [(format, self.FORMATS[format])] assert formats problems = {} for name, cls in formats: try: return cls(val, val2, scale, precision, in_subfmt, out_subfmt) except UnitConversionError: raise except (ValueError, TypeError) as err: # If ``format`` specified then there is only one possibility, so raise # immediately and include the upstream exception message to make it # easier for user to see what is wrong. if len(formats) == 1: raise ValueError( f'Input values did not match the format class {format}:' + os.linesep + f'{err.__class__.__name__}: {err}' ) from err else: problems[name] = err else: raise ValueError(f'Input values did not match any of the formats ' f'where the format keyword is optional: ' f'{problems}') from problems[formats[0][0]] @property def writeable(self): return self._time.jd1.flags.writeable & self._time.jd2.flags.writeable @writeable.setter def writeable(self, value): self._time.jd1.flags.writeable = value self._time.jd2.flags.writeable = value @property def format(self): """ Get or set time format. The format defines the way times are represented when accessed via the ``.value`` attribute. By default it is the same as the format used for initializing the `Time` instance, but it can be set to any other value that could be used for initialization. These can be listed with:: >>> list(Time.FORMATS) ['jd', 'mjd', 'decimalyear', 'unix', 'unix_tai', 'cxcsec', 'gps', 'plot_date', 'stardate', 'datetime', 'ymdhms', 'iso', 'isot', 'yday', 'datetime64', 'fits', 'byear', 'jyear', 'byear_str', 'jyear_str'] """ return self._format @format.setter def format(self, format): """Set time format""" if format not in self.FORMATS: raise ValueError(f'format must be one of {list(self.FORMATS)}') format_cls = self.FORMATS[format] # Get the new TimeFormat object to contain time in new format. Possibly # coerce in/out_subfmt to '*' (default) if existing subfmt values are # not valid in the new format. self._time = format_cls( self._time.jd1, self._time.jd2, self._time._scale, self.precision, in_subfmt=format_cls._get_allowed_subfmt(self.in_subfmt), out_subfmt=format_cls._get_allowed_subfmt(self.out_subfmt), from_jd=True) self._format = format def __repr__(self): return ("<{} object: scale='{}' format='{}' value={}>" .format(self.__class__.__name__, self.scale, self.format, getattr(self, self.format))) def __str__(self): return str(getattr(self, self.format)) def __hash__(self): try: loc = getattr(self, 'location', None) if loc is not None: loc = loc.x.to_value(u.m), loc.y.to_value(u.m), loc.z.to_value(u.m) return hash((self.jd1, self.jd2, self.scale, loc)) except TypeError: if self.ndim != 0: reason = '(must be scalar)' elif self.masked: reason = '(value is masked)' else: raise raise TypeError(f"unhashable type: '{self.__class__.__name__}' {reason}") @property def scale(self): """Time scale""" return self._time.scale def _set_scale(self, scale): """ This is the key routine that actually does time scale conversions. This is not public and not connected to the read-only scale property. """ if scale == self.scale: return if scale not in self.SCALES: raise ValueError("Scale {!r} is not in the allowed scales {}" .format(scale, sorted(self.SCALES))) if scale == 'utc' or self.scale == 'utc': # If doing a transform involving UTC then check that the leap # seconds table is up to date. _check_leapsec() # Determine the chain of scale transformations to get from the current # scale to the new scale. MULTI_HOPS contains a dict of all # transformations (xforms) that require intermediate xforms. # The MULTI_HOPS dict is keyed by (sys1, sys2) in alphabetical order. xform = (self.scale, scale) xform_sort = tuple(sorted(xform)) multi = MULTI_HOPS.get(xform_sort, ()) xforms = xform_sort[:1] + multi + xform_sort[-1:] # If we made the reverse xform then reverse it now. if xform_sort != xform: xforms = tuple(reversed(xforms)) # Transform the jd1,2 pairs through the chain of scale xforms. jd1, jd2 = self._time.jd1, self._time.jd2_filled for sys1, sys2 in zip(xforms[:-1], xforms[1:]): # Some xforms require an additional delta_ argument that is # provided through Time methods. These values may be supplied by # the user or computed based on available approximations. The # get_delta_ methods are available for only one combination of # sys1, sys2 though the property applies for both xform directions. args = [jd1, jd2] for sys12 in ((sys1, sys2), (sys2, sys1)): dt_method = '_get_delta_{}_{}'.format(*sys12) try: get_dt = getattr(self, dt_method) except AttributeError: pass else: args.append(get_dt(jd1, jd2)) break conv_func = getattr(erfa, sys1 + sys2) jd1, jd2 = conv_func(*args) jd1, jd2 = day_frac(jd1, jd2) if self.masked: jd2[self.mask] = np.nan self._time = self.FORMATS[self.format](jd1, jd2, scale, self.precision, self.in_subfmt, self.out_subfmt, from_jd=True) @property def precision(self): """ Decimal precision when outputting seconds as floating point (int value between 0 and 9 inclusive). """ return self._time.precision @precision.setter def precision(self, val): del self.cache if not isinstance(val, int) or val < 0 or val > 9: raise ValueError('precision attribute must be an int between ' '0 and 9') self._time.precision = val @property def in_subfmt(self): """ Unix wildcard pattern to select subformats for parsing string input times. """ return self._time.in_subfmt @in_subfmt.setter def in_subfmt(self, val): self._time.in_subfmt = val del self.cache @property def out_subfmt(self): """ Unix wildcard pattern to select subformats for outputting times. """ return self._time.out_subfmt @out_subfmt.setter def out_subfmt(self, val): # Setting the out_subfmt property here does validation of ``val`` self._time.out_subfmt = val del self.cache @property def shape(self): """The shape of the time instances. Like `~numpy.ndarray.shape`, can be set to a new shape by assigning a tuple. Note that if different instances share some but not all underlying data, setting the shape of one instance can make the other instance unusable. Hence, it is strongly recommended to get new, reshaped instances with the ``reshape`` method. Raises ------ ValueError If the new shape has the wrong total number of elements. AttributeError If the shape of the ``jd1``, ``jd2``, ``location``, ``delta_ut1_utc``, or ``delta_tdb_tt`` attributes cannot be changed without the arrays being copied. For these cases, use the `Time.reshape` method (which copies any arrays that cannot be reshaped in-place). """ return self._time.jd1.shape @shape.setter def shape(self, shape): del self.cache # We have to keep track of arrays that were already reshaped, # since we may have to return those to their original shape if a later # shape-setting fails. reshaped = [] oldshape = self.shape # In-place reshape of data/attributes. Need to access _time.jd1/2 not # self.jd1/2 because the latter are not guaranteed to be the actual # data, and in fact should not be directly changeable from the public # API. for obj, attr in ((self._time, 'jd1'), (self._time, 'jd2'), (self, '_delta_ut1_utc'), (self, '_delta_tdb_tt'), (self, 'location')): val = getattr(obj, attr, None) if val is not None and val.size > 1: try: val.shape = shape except Exception: for val2 in reshaped: val2.shape = oldshape raise else: reshaped.append(val) def _shaped_like_input(self, value): if self._time.jd1.shape: if isinstance(value, np.ndarray): return value else: raise TypeError( f"JD is an array ({self._time.jd1!r}) but value " f"is not ({value!r})") else: # zero-dimensional array, is it safe to unbox? if (isinstance(value, np.ndarray) and not value.shape and not np.ma.is_masked(value)): if value.dtype.kind == 'M': # existing test doesn't want datetime64 converted return value[()] elif value.dtype.fields: # Unpack but keep field names; .item() doesn't # Still don't get python types in the fields return value[()] else: return value.item() else: return value @property def jd1(self): """ First of the two doubles that internally store time value(s) in JD. """ jd1 = self._time.mask_if_needed(self._time.jd1) return self._shaped_like_input(jd1) @property def jd2(self): """ Second of the two doubles that internally store time value(s) in JD. """ jd2 = self._time.mask_if_needed(self._time.jd2) return self._shaped_like_input(jd2) def to_value(self, format, subfmt='*'): """Get time values expressed in specified output format. This method allows representing the ``Time`` object in the desired output ``format`` and optional sub-format ``subfmt``. Available built-in formats include ``jd``, ``mjd``, ``iso``, and so forth. Each format can have its own sub-formats For built-in numerical formats like ``jd`` or ``unix``, ``subfmt`` can be one of 'float', 'long', 'decimal', 'str', or 'bytes'. Here, 'long' uses ``numpy.longdouble`` for somewhat enhanced precision (with the enhancement depending on platform), and 'decimal' :class:`decimal.Decimal` for full precision. For 'str' and 'bytes', the number of digits is also chosen such that time values are represented accurately. For built-in date-like string formats, one of 'date_hms', 'date_hm', or 'date' (or 'longdate_hms', etc., for 5-digit years in `~astropy.time.TimeFITS`). For sub-formats including seconds, the number of digits used for the fractional seconds is as set by `~astropy.time.Time.precision`. Parameters ---------- format : str The format in which one wants the time values. Default: the current format. subfmt : str or None, optional Value or wildcard pattern to select the sub-format in which the values should be given. The default of '*' picks the first available for a given format, i.e., 'float' or 'date_hms'. If `None`, use the instance's ``out_subfmt``. """ # TODO: add a precision argument (but ensure it is keyword argument # only, to make life easier for TimeDelta.to_value()). if format not in self.FORMATS: raise ValueError(f'format must be one of {list(self.FORMATS)}') cache = self.cache['format'] # Try to keep cache behaviour like it was in astropy < 4.0. key = format if subfmt is None else (format, subfmt) if key not in cache: if format == self.format: tm = self else: tm = self.replicate(format=format) # Some TimeFormat subclasses may not be able to handle being passes # on a out_subfmt. This includes some core classes like # TimeBesselianEpochString that do not have any allowed subfmts. But # those do deal with `self.out_subfmt` internally, so if subfmt is # the same, we do not pass it on. kwargs = {} if subfmt is not None and subfmt != tm.out_subfmt: kwargs['out_subfmt'] = subfmt try: value = tm._time.to_value(parent=tm, **kwargs) except TypeError as exc: # Try validating subfmt, e.g. for formats like 'jyear_str' that # do not implement out_subfmt in to_value() (because there are # no allowed subformats). If subfmt is not valid this gives the # same exception as would have occurred if the call to # `to_value()` had succeeded. tm._time._select_subfmts(subfmt) # Subfmt was valid, so fall back to the original exception to see # if it was lack of support for out_subfmt as a call arg. if "unexpected keyword argument 'out_subfmt'" in str(exc): raise ValueError( f"to_value() method for format {format!r} does not " f"support passing a 'subfmt' argument") from None else: # Some unforeseen exception so raise. raise value = tm._shaped_like_input(value) cache[key] = value return cache[key] @property def value(self): """Time value(s) in current format""" return self.to_value(self.format, None) @property def masked(self): return self._time.masked @property def mask(self): return self._time.mask def insert(self, obj, values, axis=0): """ Insert values before the given indices in the column and return a new `~astropy.time.Time` or `~astropy.time.TimeDelta` object. The values to be inserted must conform to the rules for in-place setting of ``Time`` objects (see ``Get and set values`` in the ``Time`` documentation). The API signature matches the ``np.insert`` API, but is more limited. The specification of insert index ``obj`` must be a single integer, and the ``axis`` must be ``0`` for simple row insertion before the index. Parameters ---------- obj : int Integer index before which ``values`` is inserted. values : array-like Value(s) to insert. If the type of ``values`` is different from that of quantity, ``values`` is converted to the matching type. axis : int, optional Axis along which to insert ``values``. Default is 0, which is the only allowed value and will insert a row. Returns ------- out : `~astropy.time.Time` subclass New time object with inserted value(s) """ # Validate inputs: obj arg is integer, axis=0, self is not a scalar, and # input index is in bounds. try: idx0 = operator.index(obj) except TypeError: raise TypeError('obj arg must be an integer') if axis != 0: raise ValueError('axis must be 0') if not self.shape: raise TypeError('cannot insert into scalar {} object' .format(self.__class__.__name__)) if abs(idx0) > len(self): raise IndexError('index {} is out of bounds for axis 0 with size {}' .format(idx0, len(self))) # Turn negative index into positive if idx0 < 0: idx0 = len(self) + idx0 # For non-Time object, use numpy to help figure out the length. (Note annoying # case of a string input that has a length which is not the length we want). if not isinstance(values, self.__class__): values = np.asarray(values) n_values = len(values) if values.shape else 1 # Finally make the new object with the correct length and set values for the # three sections, before insert, the insert, and after the insert. out = self.__class__.info.new_like([self], len(self) + n_values, name=self.info.name) out._time.jd1[:idx0] = self._time.jd1[:idx0] out._time.jd2[:idx0] = self._time.jd2[:idx0] # This uses the Time setting machinery to coerce and validate as necessary. out[idx0:idx0 + n_values] = values out._time.jd1[idx0 + n_values:] = self._time.jd1[idx0:] out._time.jd2[idx0 + n_values:] = self._time.jd2[idx0:] return out def __setitem__(self, item, value): if not self.writeable: if self.shape: raise ValueError('{} object is read-only. Make a ' 'copy() or set "writeable" attribute to True.' .format(self.__class__.__name__)) else: raise ValueError('scalar {} object is read-only.' .format(self.__class__.__name__)) # Any use of setitem results in immediate cache invalidation del self.cache # Setting invalidates transform deltas for attr in ('_delta_tdb_tt', '_delta_ut1_utc'): if hasattr(self, attr): delattr(self, attr) if value is np.ma.masked or value is np.nan: self._time.jd2[item] = np.nan return value = self._make_value_equivalent(item, value) # Finally directly set the jd1/2 values. Locations are known to match. if self.scale is not None: value = getattr(value, self.scale) self._time.jd1[item] = value._time.jd1 self._time.jd2[item] = value._time.jd2 def isclose(self, other, atol=None): """Returns a boolean or boolean array where two Time objects are element-wise equal within a time tolerance. This evaluates the expression below:: abs(self - other) <= atol Parameters ---------- other : `~astropy.time.Time` Time object for comparison. atol : `~astropy.units.Quantity` or `~astropy.time.TimeDelta` Absolute tolerance for equality with units of time (e.g. ``u.s`` or ``u.day``). Default is two bits in the 128-bit JD time representation, equivalent to about 40 picosecs. """ if atol is None: # Note: use 2 bits instead of 1 bit based on experience in precision # tests, since taking the difference with a UTC time means one has # to do a scale change. atol = 2 * np.finfo(float).eps * u.day if not isinstance(atol, (u.Quantity, TimeDelta)): raise TypeError("'atol' argument must be a Quantity or TimeDelta instance, got " f'{atol.__class__.__name__} instead') try: # Separate these out so user sees where the problem is dt = self - other dt = abs(dt) out = dt <= atol except Exception as err: raise TypeError("'other' argument must support subtraction with Time " f"and return a value that supports comparison with " f"{atol.__class__.__name__}: {err}") return out def copy(self, format=None): """ Return a fully independent copy the Time object, optionally changing the format. If ``format`` is supplied then the time format of the returned Time object will be set accordingly, otherwise it will be unchanged from the original. In this method a full copy of the internal time arrays will be made. The internal time arrays are normally not changeable by the user so in most cases the ``replicate()`` method should be used. Parameters ---------- format : str, optional Time format of the copy. Returns ------- tm : Time object Copy of this object """ return self._apply('copy', format=format) def replicate(self, format=None, copy=False, cls=None): """ Return a replica of the Time object, optionally changing the format. If ``format`` is supplied then the time format of the returned Time object will be set accordingly, otherwise it will be unchanged from the original. If ``copy`` is set to `True` then a full copy of the internal time arrays will be made. By default the replica will use a reference to the original arrays when possible to save memory. The internal time arrays are normally not changeable by the user so in most cases it should not be necessary to set ``copy`` to `True`. The convenience method copy() is available in which ``copy`` is `True` by default. Parameters ---------- format : str, optional Time format of the replica. copy : bool, optional Return a true copy instead of using references where possible. Returns ------- tm : Time object Replica of this object """ return self._apply('copy' if copy else 'replicate', format=format, cls=cls) def _apply(self, method, *args, format=None, cls=None, **kwargs): """Create a new time object, possibly applying a method to the arrays. Parameters ---------- method : str or callable If string, can be 'replicate' or the name of a relevant `~numpy.ndarray` method. In the former case, a new time instance with unchanged internal data is created, while in the latter the method is applied to the internal ``jd1`` and ``jd2`` arrays, as well as to possible ``location``, ``_delta_ut1_utc``, and ``_delta_tdb_tt`` arrays. If a callable, it is directly applied to the above arrays. Examples: 'copy', '__getitem__', 'reshape', `~numpy.broadcast_to`. args : tuple Any positional arguments for ``method``. kwargs : dict Any keyword arguments for ``method``. If the ``format`` keyword argument is present, this will be used as the Time format of the replica. Examples -------- Some ways this is used internally:: copy : ``_apply('copy')`` replicate : ``_apply('replicate')`` reshape : ``_apply('reshape', new_shape)`` index or slice : ``_apply('__getitem__', item)`` broadcast : ``_apply(np.broadcast, shape=new_shape)`` """ new_format = self.format if format is None else format if callable(method): apply_method = lambda array: method(array, *args, **kwargs) else: if method == 'replicate': apply_method = None else: apply_method = operator.methodcaller(method, *args, **kwargs) jd1, jd2 = self._time.jd1, self._time.jd2 if apply_method: jd1 = apply_method(jd1) jd2 = apply_method(jd2) # Get a new instance of our class and set its attributes directly. tm = super().__new__(cls or self.__class__) tm._time = TimeJD(jd1, jd2, self.scale, precision=0, in_subfmt='*', out_subfmt='*', from_jd=True) # Optional ndarray attributes. for attr in ('_delta_ut1_utc', '_delta_tdb_tt', 'location'): try: val = getattr(self, attr) except AttributeError: continue if apply_method: # Apply the method to any value arrays (though skip if there is # only an array scalar and the method would return a view, # since in that case nothing would change). if getattr(val, 'shape', ()): val = apply_method(val) elif method == 'copy' or method == 'flatten': # flatten should copy also for a single element array, but # we cannot use it directly for array scalars, since it # always returns a one-dimensional array. So, just copy. val = copy.copy(val) setattr(tm, attr, val) # Copy other 'info' attr only if it has actually been defined and the # time object is not a scalar (issue #10688). # See PR #3898 for further explanation and justification, along # with Quantity.__array_finalize__ if 'info' in self.__dict__: tm.info = self.info # Make the new internal _time object corresponding to the format # in the copy. If the format is unchanged this process is lightweight # and does not create any new arrays. if new_format not in tm.FORMATS: raise ValueError(f'format must be one of {list(tm.FORMATS)}') NewFormat = tm.FORMATS[new_format] tm._time = NewFormat( tm._time.jd1, tm._time.jd2, tm._time._scale, precision=self.precision, in_subfmt=NewFormat._get_allowed_subfmt(self.in_subfmt), out_subfmt=NewFormat._get_allowed_subfmt(self.out_subfmt), from_jd=True) tm._format = new_format tm.SCALES = self.SCALES return tm def __copy__(self): """ Overrides the default behavior of the `copy.copy` function in the python stdlib to behave like `Time.copy`. Does *not* make a copy of the JD arrays - only copies by reference. """ return self.replicate() def __deepcopy__(self, memo): """ Overrides the default behavior of the `copy.deepcopy` function in the python stdlib to behave like `Time.copy`. Does make a copy of the JD arrays. """ return self.copy() def _advanced_index(self, indices, axis=None, keepdims=False): """Turn argmin, argmax output into an advanced index. Argmin, argmax output contains indices along a given axis in an array shaped like the other dimensions. To use this to get values at the correct location, a list is constructed in which the other axes are indexed sequentially. For ``keepdims`` is ``True``, the net result is the same as constructing an index grid with ``np.ogrid`` and then replacing the ``axis`` item with ``indices`` with its shaped expanded at ``axis``. For ``keepdims`` is ``False``, the result is the same but with the ``axis`` dimension removed from all list entries. For ``axis`` is ``None``, this calls :func:`~numpy.unravel_index`. Parameters ---------- indices : array Output of argmin or argmax. axis : int or None axis along which argmin or argmax was used. keepdims : bool Whether to construct indices that keep or remove the axis along which argmin or argmax was used. Default: ``False``. Returns ------- advanced_index : list of arrays Suitable for use as an advanced index. """ if axis is None: return np.unravel_index(indices, self.shape) ndim = self.ndim if axis < 0: axis = axis + ndim if keepdims and indices.ndim < self.ndim: indices = np.expand_dims(indices, axis) index = [indices if i == axis else np.arange(s).reshape( (1,) * (i if keepdims or i < axis else i - 1) + (s,) + (1,) * (ndim - i - (1 if keepdims or i > axis else 2)) ) for i, s in enumerate(self.shape)] return tuple(index) def argmin(self, axis=None, out=None): """Return indices of the minimum values along the given axis. This is similar to :meth:`~numpy.ndarray.argmin`, but adapted to ensure that the full precision given by the two doubles ``jd1`` and ``jd2`` is used. See :func:`~numpy.argmin` for detailed documentation. """ # First get the minimum at normal precision. jd1, jd2 = self.jd1, self.jd2 approx = np.min(jd1 + jd2, axis, keepdims=True) # Approx is very close to the true minimum, and by subtracting it at # full precision, all numbers near 0 can be represented correctly, # so we can be sure we get the true minimum. # The below is effectively what would be done for # dt = (self - self.__class__(approx, format='jd')).jd # which translates to: # approx_jd1, approx_jd2 = day_frac(approx, 0.) # dt = (self.jd1 - approx_jd1) + (self.jd2 - approx_jd2) dt = (jd1 - approx) + jd2 return dt.argmin(axis, out) def argmax(self, axis=None, out=None): """Return indices of the maximum values along the given axis. This is similar to :meth:`~numpy.ndarray.argmax`, but adapted to ensure that the full precision given by the two doubles ``jd1`` and ``jd2`` is used. See :func:`~numpy.argmax` for detailed documentation. """ # For procedure, see comment on argmin. jd1, jd2 = self.jd1, self.jd2 approx = np.max(jd1 + jd2, axis, keepdims=True) dt = (jd1 - approx) + jd2 return dt.argmax(axis, out) def argsort(self, axis=-1): """Returns the indices that would sort the time array. This is similar to :meth:`~numpy.ndarray.argsort`, but adapted to ensure that the full precision given by the two doubles ``jd1`` and ``jd2`` is used, and that corresponding attributes are copied. Internally, it uses :func:`~numpy.lexsort`, and hence no sort method can be chosen. """ # For procedure, see comment on argmin. jd1, jd2 = self.jd1, self.jd2 approx = jd1 + jd2 remainder = (jd1 - approx) + jd2 if axis is None: return np.lexsort((remainder.ravel(), approx.ravel())) else: return np.lexsort(keys=(remainder, approx), axis=axis) def min(self, axis=None, out=None, keepdims=False): """Minimum along a given axis. This is similar to :meth:`~numpy.ndarray.min`, but adapted to ensure that the full precision given by the two doubles ``jd1`` and ``jd2`` is used, and that corresponding attributes are copied. Note that the ``out`` argument is present only for compatibility with ``np.min``; since `Time` instances are immutable, it is not possible to have an actual ``out`` to store the result in. """ if out is not None: raise ValueError("Since `Time` instances are immutable, ``out`` " "cannot be set to anything but ``None``.") return self[self._advanced_index(self.argmin(axis), axis, keepdims)] def max(self, axis=None, out=None, keepdims=False): """Maximum along a given axis. This is similar to :meth:`~numpy.ndarray.max`, but adapted to ensure that the full precision given by the two doubles ``jd1`` and ``jd2`` is used, and that corresponding attributes are copied. Note that the ``out`` argument is present only for compatibility with ``np.max``; since `Time` instances are immutable, it is not possible to have an actual ``out`` to store the result in. """ if out is not None: raise ValueError("Since `Time` instances are immutable, ``out`` " "cannot be set to anything but ``None``.") return self[self._advanced_index(self.argmax(axis), axis, keepdims)] def ptp(self, axis=None, out=None, keepdims=False): """Peak to peak (maximum - minimum) along a given axis. This is similar to :meth:`~numpy.ndarray.ptp`, but adapted to ensure that the full precision given by the two doubles ``jd1`` and ``jd2`` is used. Note that the ``out`` argument is present only for compatibility with `~numpy.ptp`; since `Time` instances are immutable, it is not possible to have an actual ``out`` to store the result in. """ if out is not None: raise ValueError("Since `Time` instances are immutable, ``out`` " "cannot be set to anything but ``None``.") return (self.max(axis, keepdims=keepdims) - self.min(axis, keepdims=keepdims)) def sort(self, axis=-1): """Return a copy sorted along the specified axis. This is similar to :meth:`~numpy.ndarray.sort`, but internally uses indexing with :func:`~numpy.lexsort` to ensure that the full precision given by the two doubles ``jd1`` and ``jd2`` is kept, and that corresponding attributes are properly sorted and copied as well. Parameters ---------- axis : int or None Axis to be sorted. If ``None``, the flattened array is sorted. By default, sort over the last axis. """ return self[self._advanced_index(self.argsort(axis), axis, keepdims=True)] @property def cache(self): """ Return the cache associated with this instance. """ return self._time.cache @cache.deleter def cache(self): del self._time.cache def __getattr__(self, attr): """ Get dynamic attributes to output format or do timescale conversion. """ if attr in self.SCALES and self.scale is not None: cache = self.cache['scale'] if attr not in cache: if attr == self.scale: tm = self else: tm = self.replicate() tm._set_scale(attr) if tm.shape: # Prevent future modification of cached array-like object tm.writeable = False cache[attr] = tm return cache[attr] elif attr in self.FORMATS: return self.to_value(attr, subfmt=None) elif attr in TIME_SCALES: # allowed ones done above (self.SCALES) if self.scale is None: raise ScaleValueError("Cannot convert TimeDelta with " "undefined scale to any defined scale.") else: raise ScaleValueError("Cannot convert {} with scale " "'{}' to scale '{}'" .format(self.__class__.__name__, self.scale, attr)) else: # Should raise AttributeError return self.__getattribute__(attr) @override__dir__ def __dir__(self): result = set(self.SCALES) result.update(self.FORMATS) return result def _match_shape(self, val): """ Ensure that `val` is matched to length of self. If val has length 1 then broadcast, otherwise cast to double and make sure shape matches. """ val = _make_array(val, copy=True) # be conservative and copy if val.size > 1 and val.shape != self.shape: try: # check the value can be broadcast to the shape of self. val = np.broadcast_to(val, self.shape, subok=True) except Exception: raise ValueError('Attribute shape must match or be ' 'broadcastable to that of Time object. ' 'Typically, give either a single value or ' 'one for each time.') return val def _time_comparison(self, other, op): """If other is of same class as self, compare difference in self.scale. Otherwise, return NotImplemented """ if other.__class__ is not self.__class__: try: other = self.__class__(other, scale=self.scale) except Exception: # Let other have a go. return NotImplemented if(self.scale is not None and self.scale not in other.SCALES or other.scale is not None and other.scale not in self.SCALES): # Other will also not be able to do it, so raise a TypeError # immediately, allowing us to explain why it doesn't work. raise TypeError("Cannot compare {} instances with scales " "'{}' and '{}'".format(self.__class__.__name__, self.scale, other.scale)) if self.scale is not None and other.scale is not None: other = getattr(other, self.scale) return op((self.jd1 - other.jd1) + (self.jd2 - other.jd2), 0.) def __lt__(self, other): return self._time_comparison(other, operator.lt) def __le__(self, other): return self._time_comparison(other, operator.le) def __eq__(self, other): """ If other is an incompatible object for comparison, return `False`. Otherwise, return `True` if the time difference between self and other is zero. """ return self._time_comparison(other, operator.eq) def __ne__(self, other): """ If other is an incompatible object for comparison, return `True`. Otherwise, return `False` if the time difference between self and other is zero. """ return self._time_comparison(other, operator.ne) def __gt__(self, other): return self._time_comparison(other, operator.gt) def __ge__(self, other): return self._time_comparison(other, operator.ge) class Time(TimeBase): """ Represent and manipulate times and dates for astronomy. A `Time` object is initialized with one or more times in the ``val`` argument. The input times in ``val`` must conform to the specified ``format`` and must correspond to the specified time ``scale``. The optional ``val2`` time input should be supplied only for numeric input formats (e.g. JD) where very high precision (better than 64-bit precision) is required. The allowed values for ``format`` can be listed with:: >>> list(Time.FORMATS) ['jd', 'mjd', 'decimalyear', 'unix', 'unix_tai', 'cxcsec', 'gps', 'plot_date', 'stardate', 'datetime', 'ymdhms', 'iso', 'isot', 'yday', 'datetime64', 'fits', 'byear', 'jyear', 'byear_str', 'jyear_str'] See also: http://docs.astropy.org/en/stable/time/ Parameters ---------- val : sequence, ndarray, number, str, bytes, or `~astropy.time.Time` object Value(s) to initialize the time or times. Bytes are decoded as ascii. val2 : sequence, ndarray, or number; optional Value(s) to initialize the time or times. Only used for numerical input, to help preserve precision. format : str, optional Format of input value(s) scale : str, optional Time scale of input value(s), must be one of the following: ('tai', 'tcb', 'tcg', 'tdb', 'tt', 'ut1', 'utc') precision : int, optional Digits of precision in string representation of time in_subfmt : str, optional Unix glob to select subformats for parsing input times out_subfmt : str, optional Unix glob to select subformat for outputting times location : `~astropy.coordinates.EarthLocation` or tuple, optional If given as an tuple, it should be able to initialize an an EarthLocation instance, i.e., either contain 3 items with units of length for geocentric coordinates, or contain a longitude, latitude, and an optional height for geodetic coordinates. Can be a single location, or one for each input time. If not given, assumed to be the center of the Earth for time scale transformations to and from the solar-system barycenter. copy : bool, optional Make a copy of the input values """ SCALES = TIME_SCALES """List of time scales""" FORMATS = TIME_FORMATS """Dict of time formats""" def __new__(cls, val, val2=None, format=None, scale=None, precision=None, in_subfmt=None, out_subfmt=None, location=None, copy=False): if isinstance(val, Time): self = val.replicate(format=format, copy=copy, cls=cls) else: self = super().__new__(cls) return self def __init__(self, val, val2=None, format=None, scale=None, precision=None, in_subfmt=None, out_subfmt=None, location=None, copy=False): if location is not None: from astropy.coordinates import EarthLocation if isinstance(location, EarthLocation): self.location = location else: self.location = EarthLocation(*location) if self.location.size == 1: self.location = self.location.squeeze() else: if not hasattr(self, 'location'): self.location = None if isinstance(val, Time): # Update _time formatting parameters if explicitly specified if precision is not None: self._time.precision = precision if in_subfmt is not None: self._time.in_subfmt = in_subfmt if out_subfmt is not None: self._time.out_subfmt = out_subfmt self.SCALES = TIME_TYPES[self.scale] if scale is not None: self._set_scale(scale) else: self._init_from_vals(val, val2, format, scale, copy, precision, in_subfmt, out_subfmt) self.SCALES = TIME_TYPES[self.scale] if self.location is not None and (self.location.size > 1 and self.location.shape != self.shape): try: # check the location can be broadcast to self's shape. self.location = np.broadcast_to(self.location, self.shape, subok=True) except Exception as err: raise ValueError('The location with shape {} cannot be ' 'broadcast against time with shape {}. ' 'Typically, either give a single location or ' 'one for each time.' .format(self.location.shape, self.shape)) from err def _make_value_equivalent(self, item, value): """Coerce setitem value into an equivalent Time object""" # If there is a vector location then broadcast to the Time shape # and then select with ``item`` if self.location is not None and self.location.shape: self_location = np.broadcast_to(self.location, self.shape, subok=True)[item] else: self_location = self.location if isinstance(value, Time): # Make sure locations are compatible. Location can be either None or # a Location object. if self_location is None and value.location is None: match = True elif ((self_location is None and value.location is not None) or (self_location is not None and value.location is None)): match = False else: match = np.all(self_location == value.location) if not match: raise ValueError('cannot set to Time with different location: ' 'expected location={} and ' 'got location={}' .format(self_location, value.location)) else: try: value = self.__class__(value, scale=self.scale, location=self_location) except Exception: try: value = self.__class__(value, scale=self.scale, format=self.format, location=self_location) except Exception as err: raise ValueError('cannot convert value to a compatible Time object: {}' .format(err)) return value @classmethod def now(cls): """ Creates a new object corresponding to the instant in time this method is called. .. note:: "Now" is determined using the `~datetime.datetime.utcnow` function, so its accuracy and precision is determined by that function. Generally that means it is set by the accuracy of your system clock. Returns ------- nowtime : :class:`~astropy.time.Time` A new `Time` object (or a subclass of `Time` if this is called from such a subclass) at the current time. """ # call `utcnow` immediately to be sure it's ASAP dtnow = datetime.utcnow() return cls(val=dtnow, format='datetime', scale='utc') info = TimeInfo() @classmethod def strptime(cls, time_string, format_string, **kwargs): """ Parse a string to a Time according to a format specification. See `time.strptime` documentation for format specification. >>> Time.strptime('2012-Jun-30 23:59:60', '%Y-%b-%d %H:%M:%S')
{}
' blank_row_container = "{}" heading_row_content = "{}" * self.ROW_LEN data_row_content = "{}" * self.ROW_LEN # The HTML will be rendered & the table is simple, so don't # bother to include newlines & indentation for the HTML code. heading_row = blank_row_container.format( heading_row_content.format(*self.HEADING_NAMES)) data_rows = self._process_equivalent_units(self) all_rows = heading_row for row in data_rows: html_row = blank_row_container.format( data_row_content.format(*row)) all_rows += html_row return blank_table.format(all_rows) @staticmethod def _process_equivalent_units(equiv_units_data): """ Extract attributes, and sort, the equivalent units pre-formatting. """ processed_equiv_units = [] for u in equiv_units_data: irred = u.decompose().to_string() if irred == u.name: irred = 'irreducible' processed_equiv_units.append( (u.name, irred, ', '.join(u.aliases))) processed_equiv_units.sort() return processed_equiv_units def find_equivalent_units(self, equivalencies=[], units=None, include_prefix_units=False): """ Return a list of all the units that are the same type as ``self``. Parameters ---------- equivalencies : list of tuple A list of equivalence pairs to also list. See :ref:`astropy:unit_equivalencies`. Any list given, including an empty one, supersedes global defaults that may be in effect (as set by `set_enabled_equivalencies`) units : set of `~astropy.units.Unit`, optional If not provided, all defined units will be searched for equivalencies. Otherwise, may be a dict, module or sequence containing the units to search for equivalencies. include_prefix_units : bool, optional When `True`, include prefixed units in the result. Default is `False`. Returns ------- units : list of `UnitBase` A list of unit objects that match ``u``. A subclass of `list` (``EquivalentUnitsList``) is returned that pretty-prints the list of units when output. """ results = self.compose( equivalencies=equivalencies, units=units, max_depth=1, include_prefix_units=include_prefix_units) results = set( x.bases[0] for x in results if len(x.bases) == 1) return self.EquivalentUnitsList(results) def is_unity(self): """ Returns `True` if the unit is unscaled and dimensionless. """ return False class NamedUnit(UnitBase): """ The base class of units that have a name. Parameters ---------- st : str, list of str, 2-tuple The name of the unit. If a list of strings, the first element is the canonical (short) name, and the rest of the elements are aliases. If a tuple of lists, the first element is a list of short names, and the second element is a list of long names; all but the first short name are considered "aliases". Each name *should* be a valid Python identifier to make it easy to access, but this is not required. namespace : dict, optional When provided, inject the unit, and all of its aliases, in the given namespace dictionary. If a unit by the same name is already in the namespace, a ValueError is raised. doc : str, optional A docstring describing the unit. format : dict, optional A mapping to format-specific representations of this unit. For example, for the ``Ohm`` unit, it might be nice to have it displayed as ``\\Omega`` by the ``latex`` formatter. In that case, `format` argument should be set to:: {'latex': r'\\Omega'} Raises ------ ValueError If any of the given unit names are already in the registry. ValueError If any of the given unit names are not valid Python tokens. """ def __init__(self, st, doc=None, format=None, namespace=None): UnitBase.__init__(self) if isinstance(st, (bytes, str)): self._names = [st] self._short_names = [st] self._long_names = [] elif isinstance(st, tuple): if not len(st) == 2: raise ValueError("st must be string, list or 2-tuple") self._names = st[0] + [n for n in st[1] if n not in st[0]] if not len(self._names): raise ValueError("must provide at least one name") self._short_names = st[0][:] self._long_names = st[1][:] else: if len(st) == 0: raise ValueError( "st list must have at least one entry") self._names = st[:] self._short_names = [st[0]] self._long_names = st[1:] if format is None: format = {} self._format = format if doc is None: doc = self._generate_doc() else: doc = textwrap.dedent(doc) doc = textwrap.fill(doc) self.__doc__ = doc self._inject(namespace) def _generate_doc(self): """ Generate a docstring for the unit if the user didn't supply one. This is only used from the constructor and may be overridden in subclasses. """ names = self.names if len(self.names) > 1: return "{1} ({0})".format(*names[:2]) else: return names[0] def get_format_name(self, format): """ Get a name for this unit that is specific to a particular format. Uses the dictionary passed into the `format` kwarg in the constructor. Parameters ---------- format : str The name of the format Returns ------- name : str The name of the unit for the given format. """ return self._format.get(format, self.name) @property def names(self): """ Returns all of the names associated with this unit. """ return self._names @property def name(self): """ Returns the canonical (short) name associated with this unit. """ return self._names[0] @property def aliases(self): """ Returns the alias (long) names for this unit. """ return self._names[1:] @property def short_names(self): """ Returns all of the short names associated with this unit. """ return self._short_names @property def long_names(self): """ Returns all of the long names associated with this unit. """ return self._long_names def _inject(self, namespace=None): """ Injects the unit, and all of its aliases, in the given namespace dictionary. """ if namespace is None: return # Loop through all of the names first, to ensure all of them # are new, then add them all as a single "transaction" below. for name in self._names: if name in namespace and self != namespace[name]: raise ValueError( "Object with name {!r} already exists in " "given namespace ({!r}).".format( name, namespace[name])) for name in self._names: namespace[name] = self def _recreate_irreducible_unit(cls, names, registered): """ This is used to reconstruct units when passed around by multiprocessing. """ registry = get_current_unit_registry().registry if names[0] in registry: # If in local registry return that object. return registry[names[0]] else: # otherwise, recreate the unit. unit = cls(names) if registered: # If not in local registry but registered in origin registry, # enable unit in local registry. get_current_unit_registry().add_enabled_units([unit]) return unit class IrreducibleUnit(NamedUnit): """ Irreducible units are the units that all other units are defined in terms of. Examples are meters, seconds, kilograms, amperes, etc. There is only once instance of such a unit per type. """ def __reduce__(self): # When IrreducibleUnit objects are passed to other processes # over multiprocessing, they need to be recreated to be the # ones already in the subprocesses' namespace, not new # objects, or they will be considered "unconvertible". # Therefore, we have a custom pickler/unpickler that # understands how to recreate the Unit on the other side. registry = get_current_unit_registry().registry return (_recreate_irreducible_unit, (self.__class__, list(self.names), self.name in registry), self.__getstate__()) @property def represents(self): """The unit that this named unit represents. For an irreducible unit, that is always itself. """ return self def decompose(self, bases=set()): if len(bases) and self not in bases: for base in bases: try: scale = self._to(base) except UnitsError: pass else: if is_effectively_unity(scale): return base else: return CompositeUnit(scale, [base], [1], _error_check=False) raise UnitConversionError( f"Unit {self} can not be decomposed into the requested bases") return self class UnrecognizedUnit(IrreducibleUnit): """ A unit that did not parse correctly. This allows for round-tripping it as a string, but no unit operations actually work on it. Parameters ---------- st : str The name of the unit. """ # For UnrecognizedUnits, we want to use "standard" Python # pickling, not the special case that is used for # IrreducibleUnits. __reduce__ = object.__reduce__ def __repr__(self): return f"UnrecognizedUnit({str(self)})" def __bytes__(self): return self.name.encode('ascii', 'replace') def __str__(self): return self.name def to_string(self, format=None): return self.name def _unrecognized_operator(self, *args, **kwargs): raise ValueError( "The unit {!r} is unrecognized, so all arithmetic operations " "with it are invalid.".format(self.name)) __pow__ = __div__ = __rdiv__ = __truediv__ = __rtruediv__ = __mul__ = \ __rmul__ = __lt__ = __gt__ = __le__ = __ge__ = __neg__ = \ _unrecognized_operator def __eq__(self, other): try: other = Unit(other, parse_strict='silent') except (ValueError, UnitsError, TypeError): return NotImplemented return isinstance(other, type(self)) and self.name == other.name def __ne__(self, other): return not (self == other) def is_equivalent(self, other, equivalencies=None): self._normalize_equivalencies(equivalencies) return self == other def _get_converter(self, other, equivalencies=None): self._normalize_equivalencies(equivalencies) raise ValueError( "The unit {!r} is unrecognized. It can not be converted " "to other units.".format(self.name)) def get_format_name(self, format): return self.name def is_unity(self): return False class _UnitMetaClass(type): """ This metaclass exists because the Unit constructor should sometimes return instances that already exist. This "overrides" the constructor before the new instance is actually created, so we can return an existing one. """ def __call__(self, s="", represents=None, format=None, namespace=None, doc=None, parse_strict='raise'): # Short-circuit if we're already a unit if hasattr(s, '_get_physical_type_id'): return s # turn possible Quantity input for s or represents into a Unit from .quantity import Quantity if isinstance(represents, Quantity): if is_effectively_unity(represents.value): represents = represents.unit else: represents = CompositeUnit(represents.value * represents.unit.scale, bases=represents.unit.bases, powers=represents.unit.powers, _error_check=False) if isinstance(s, Quantity): if is_effectively_unity(s.value): s = s.unit else: s = CompositeUnit(s.value * s.unit.scale, bases=s.unit.bases, powers=s.unit.powers, _error_check=False) # now decide what we really need to do; define derived Unit? if isinstance(represents, UnitBase): # This has the effect of calling the real __new__ and # __init__ on the Unit class. return super().__call__( s, represents, format=format, namespace=namespace, doc=doc) # or interpret a Quantity (now became unit), string or number? if isinstance(s, UnitBase): return s elif isinstance(s, (bytes, str)): if len(s.strip()) == 0: # Return the NULL unit return dimensionless_unscaled if format is None: format = unit_format.Generic f = unit_format.get_format(format) if isinstance(s, bytes): s = s.decode('ascii') try: return f.parse(s) except NotImplementedError: raise except Exception as e: if parse_strict == 'silent': pass else: # Deliberately not issubclass here. Subclasses # should use their name. if f is not unit_format.Generic: format_clause = f.name + ' ' else: format_clause = '' msg = ("'{}' did not parse as {}unit: {} " "If this is meant to be a custom unit, " "define it with 'u.def_unit'. To have it " "recognized inside a file reader or other code, " "enable it with 'u.add_enabled_units'. " "For details, see " "https://docs.astropy.org/en/latest/units/combining_and_defining.html" .format(s, format_clause, str(e))) if parse_strict == 'raise': raise ValueError(msg) elif parse_strict == 'warn': warnings.warn(msg, UnitsWarning) else: raise ValueError("'parse_strict' must be 'warn', " "'raise' or 'silent'") return UnrecognizedUnit(s) elif isinstance(s, (int, float, np.floating, np.integer)): return CompositeUnit(s, [], [], _error_check=False) elif isinstance(s, tuple): from .structured import StructuredUnit return StructuredUnit(s) elif s is None: raise TypeError("None is not a valid Unit") else: raise TypeError(f"{s} can not be converted to a Unit") class Unit(NamedUnit, metaclass=_UnitMetaClass): """ The main unit class. There are a number of different ways to construct a Unit, but always returns a `UnitBase` instance. If the arguments refer to an already-existing unit, that existing unit instance is returned, rather than a new one. - From a string:: Unit(s, format=None, parse_strict='silent') Construct from a string representing a (possibly compound) unit. The optional `format` keyword argument specifies the format the string is in, by default ``"generic"``. For a description of the available formats, see `astropy.units.format`. The optional ``parse_strict`` keyword controls what happens when an unrecognized unit string is passed in. It may be one of the following: - ``'raise'``: (default) raise a ValueError exception. - ``'warn'``: emit a Warning, and return an `UnrecognizedUnit` instance. - ``'silent'``: return an `UnrecognizedUnit` instance. - From a number:: Unit(number) Creates a dimensionless unit. - From a `UnitBase` instance:: Unit(unit) Returns the given unit unchanged. - From no arguments:: Unit() Returns the dimensionless unit. - The last form, which creates a new `Unit` is described in detail below. See also: https://docs.astropy.org/en/stable/units/ Parameters ---------- st : str or list of str The name of the unit. If a list, the first element is the canonical (short) name, and the rest of the elements are aliases. represents : UnitBase instance The unit that this named unit represents. doc : str, optional A docstring describing the unit. format : dict, optional A mapping to format-specific representations of this unit. For example, for the ``Ohm`` unit, it might be nice to have it displayed as ``\\Omega`` by the ``latex`` formatter. In that case, `format` argument should be set to:: {'latex': r'\\Omega'} namespace : dict, optional When provided, inject the unit (and all of its aliases) into the given namespace. Raises ------ ValueError If any of the given unit names are already in the registry. ValueError If any of the given unit names are not valid Python tokens. """ def __init__(self, st, represents=None, doc=None, format=None, namespace=None): represents = Unit(represents) self._represents = represents NamedUnit.__init__(self, st, namespace=namespace, doc=doc, format=format) @property def represents(self): """The unit that this named unit represents.""" return self._represents def decompose(self, bases=set()): return self._represents.decompose(bases=bases) def is_unity(self): return self._represents.is_unity() def __hash__(self): if self._hash is None: self._hash = hash((self.name, self._represents)) return self._hash @classmethod def _from_physical_type_id(cls, physical_type_id): # get string bases and powers from the ID tuple bases = [cls(base) for base, _ in physical_type_id] powers = [power for _, power in physical_type_id] if len(physical_type_id) == 1 and powers[0] == 1: unit = bases[0] else: unit = CompositeUnit(1, bases, powers, _error_check=False) return unit class PrefixUnit(Unit): """ A unit that is simply a SI-prefixed version of another unit. For example, ``mm`` is a `PrefixUnit` of ``.001 * m``. The constructor is the same as for `Unit`. """ class CompositeUnit(UnitBase): """ Create a composite unit using expressions of previously defined units. Direct use of this class is not recommended. Instead use the factory function `Unit` and arithmetic operators to compose units. Parameters ---------- scale : number A scaling factor for the unit. bases : sequence of `UnitBase` A sequence of units this unit is composed of. powers : sequence of numbers A sequence of powers (in parallel with ``bases``) for each of the base units. """ _decomposed_cache = None def __init__(self, scale, bases, powers, decompose=False, decompose_bases=set(), _error_check=True): # There are many cases internal to astropy.units where we # already know that all the bases are Unit objects, and the # powers have been validated. In those cases, we can skip the # error checking for performance reasons. When the private # kwarg `_error_check` is False, the error checking is turned # off. if _error_check: for base in bases: if not isinstance(base, UnitBase): raise TypeError( "bases must be sequence of UnitBase instances") powers = [validate_power(p) for p in powers] if not decompose and len(bases) == 1 and powers[0] >= 0: # Short-cut; with one unit there's nothing to expand and gather, # as that has happened already when creating the unit. But do only # positive powers, since for negative powers we need to re-sort. unit = bases[0] power = powers[0] if power == 1: scale *= unit.scale self._bases = unit.bases self._powers = unit.powers elif power == 0: self._bases = [] self._powers = [] else: scale *= unit.scale ** power self._bases = unit.bases self._powers = [operator.mul(*resolve_fractions(p, power)) for p in unit.powers] self._scale = sanitize_scale(scale) else: # Regular case: use inputs as preliminary scale, bases, and powers, # then "expand and gather" identical bases, sanitize the scale, &c. self._scale = scale self._bases = bases self._powers = powers self._expand_and_gather(decompose=decompose, bases=decompose_bases) def __repr__(self): if len(self._bases): return super().__repr__() else: if self._scale != 1.0: return f'Unit(dimensionless with a scale of {self._scale})' else: return 'Unit(dimensionless)' @property def scale(self): """ Return the scale of the composite unit. """ return self._scale @property def bases(self): """ Return the bases of the composite unit. """ return self._bases @property def powers(self): """ Return the powers of the composite unit. """ return self._powers def _expand_and_gather(self, decompose=False, bases=set()): def add_unit(unit, power, scale): if bases and unit not in bases: for base in bases: try: scale *= unit._to(base) ** power except UnitsError: pass else: unit = base break if unit in new_parts: a, b = resolve_fractions(new_parts[unit], power) new_parts[unit] = a + b else: new_parts[unit] = power return scale new_parts = {} scale = self._scale for b, p in zip(self._bases, self._powers): if decompose and b not in bases: b = b.decompose(bases=bases) if isinstance(b, CompositeUnit): scale *= b._scale ** p for b_sub, p_sub in zip(b._bases, b._powers): a, b = resolve_fractions(p_sub, p) scale = add_unit(b_sub, a * b, scale) else: scale = add_unit(b, p, scale) new_parts = [x for x in new_parts.items() if x[1] != 0] new_parts.sort(key=lambda x: (-x[1], getattr(x[0], 'name', ''))) self._bases = [x[0] for x in new_parts] self._powers = [x[1] for x in new_parts] self._scale = sanitize_scale(scale) def __copy__(self): """ For compatibility with python copy module. """ return CompositeUnit(self._scale, self._bases[:], self._powers[:]) def decompose(self, bases=set()): if len(bases) == 0 and self._decomposed_cache is not None: return self._decomposed_cache for base in self.bases: if (not isinstance(base, IrreducibleUnit) or (len(bases) and base not in bases)): break else: if len(bases) == 0: self._decomposed_cache = self return self x = CompositeUnit(self.scale, self.bases, self.powers, decompose=True, decompose_bases=bases) if len(bases) == 0: self._decomposed_cache = x return x def is_unity(self): unit = self.decompose() return len(unit.bases) == 0 and unit.scale == 1.0 si_prefixes = [ (['Y'], ['yotta'], 1e24), (['Z'], ['zetta'], 1e21), (['E'], ['exa'], 1e18), (['P'], ['peta'], 1e15), (['T'], ['tera'], 1e12), (['G'], ['giga'], 1e9), (['M'], ['mega'], 1e6), (['k'], ['kilo'], 1e3), (['h'], ['hecto'], 1e2), (['da'], ['deka', 'deca'], 1e1), (['d'], ['deci'], 1e-1), (['c'], ['centi'], 1e-2), (['m'], ['milli'], 1e-3), (['u'], ['micro'], 1e-6), (['n'], ['nano'], 1e-9), (['p'], ['pico'], 1e-12), (['f'], ['femto'], 1e-15), (['a'], ['atto'], 1e-18), (['z'], ['zepto'], 1e-21), (['y'], ['yocto'], 1e-24) ] binary_prefixes = [ (['Ki'], ['kibi'], 2. ** 10), (['Mi'], ['mebi'], 2. ** 20), (['Gi'], ['gibi'], 2. ** 30), (['Ti'], ['tebi'], 2. ** 40), (['Pi'], ['pebi'], 2. ** 50), (['Ei'], ['exbi'], 2. ** 60) ] def _add_prefixes(u, excludes=[], namespace=None, prefixes=False): """ Set up all of the standard metric prefixes for a unit. This function should not be used directly, but instead use the `prefixes` kwarg on `def_unit`. Parameters ---------- excludes : list of str, optional Any prefixes to exclude from creation to avoid namespace collisions. namespace : dict, optional When provided, inject the unit (and all of its aliases) into the given namespace dictionary. prefixes : list, optional When provided, it is a list of prefix definitions of the form: (short_names, long_tables, factor) """ if prefixes is True: prefixes = si_prefixes elif prefixes is False: prefixes = [] for short, full, factor in prefixes: names = [] format = {} for prefix in short: if prefix in excludes: continue for alias in u.short_names: names.append(prefix + alias) # This is a hack to use Greek mu as a prefix # for some formatters. if prefix == 'u': format['latex'] = r'\mu ' + u.get_format_name('latex') format['unicode'] = '\N{MICRO SIGN}' + u.get_format_name('unicode') for key, val in u._format.items(): format.setdefault(key, prefix + val) for prefix in full: if prefix in excludes: continue for alias in u.long_names: names.append(prefix + alias) if len(names): PrefixUnit(names, CompositeUnit(factor, [u], [1], _error_check=False), namespace=namespace, format=format) def def_unit(s, represents=None, doc=None, format=None, prefixes=False, exclude_prefixes=[], namespace=None): """ Factory function for defining new units. Parameters ---------- s : str or list of str The name of the unit. If a list, the first element is the canonical (short) name, and the rest of the elements are aliases. represents : UnitBase instance, optional The unit that this named unit represents. If not provided, a new `IrreducibleUnit` is created. doc : str, optional A docstring describing the unit. format : dict, optional A mapping to format-specific representations of this unit. For example, for the ``Ohm`` unit, it might be nice to have it displayed as ``\\Omega`` by the ``latex`` formatter. In that case, `format` argument should be set to:: {'latex': r'\\Omega'} prefixes : bool or list, optional When `True`, generate all of the SI prefixed versions of the unit as well. For example, for a given unit ``m``, will generate ``mm``, ``cm``, ``km``, etc. When a list, it is a list of prefix definitions of the form: (short_names, long_tables, factor) Default is `False`. This function always returns the base unit object, even if multiple scaled versions of the unit were created. exclude_prefixes : list of str, optional If any of the SI prefixes need to be excluded, they may be listed here. For example, ``Pa`` can be interpreted either as "petaannum" or "Pascal". Therefore, when defining the prefixes for ``a``, ``exclude_prefixes`` should be set to ``["P"]``. namespace : dict, optional When provided, inject the unit (and all of its aliases and prefixes), into the given namespace dictionary. Returns ------- unit : `~astropy.units.UnitBase` The newly-defined unit, or a matching unit that was already defined. """ if represents is not None: result = Unit(s, represents, namespace=namespace, doc=doc, format=format) else: result = IrreducibleUnit( s, namespace=namespace, doc=doc, format=format) if prefixes: _add_prefixes(result, excludes=exclude_prefixes, namespace=namespace, prefixes=prefixes) return result def _condition_arg(value): """ Validate value is acceptable for conversion purposes. Will convert into an array if not a scalar, and can be converted into an array Parameters ---------- value : int or float value, or sequence of such values Returns ------- Scalar value or numpy array Raises ------ ValueError If value is not as expected """ if isinstance(value, (np.ndarray, float, int, complex, np.void)): return value avalue = np.array(value) if avalue.dtype.kind not in ['i', 'f', 'c']: raise ValueError("Value not scalar compatible or convertible to " "an int, float, or complex array") return avalue def unit_scale_converter(val): """Function that just multiplies the value by unity. This is a separate function so it can be recognized and discarded in unit conversion. """ return 1. * _condition_arg(val) dimensionless_unscaled = CompositeUnit(1, [], [], _error_check=False) # Abbreviation of the above, see #1980 one = dimensionless_unscaled # Maintain error in old location for backward compatibility # TODO: Is this still needed? Should there be a deprecation warning? unit_format.fits.UnitScaleError = UnitScaleError ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/decorators.py0000644000175100001710000002743600000000000017643 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst __all__ = ['quantity_input'] import inspect from numbers import Number from collections.abc import Sequence from functools import wraps import numpy as np from . import _typing as T from .core import (Unit, UnitBase, UnitsError, add_enabled_equivalencies, dimensionless_unscaled) from .function.core import FunctionUnitBase from .physical import PhysicalType, get_physical_type from .quantity import Quantity from .structured import StructuredUnit NoneType = type(None) def _get_allowed_units(targets): """ From a list of target units (either as strings or unit objects) and physical types, return a list of Unit objects. """ allowed_units = [] for target in targets: try: unit = Unit(target) except (TypeError, ValueError): try: unit = get_physical_type(target)._unit except (TypeError, ValueError, KeyError): # KeyError for Enum raise ValueError(f"Invalid unit or physical type {target!r}.") from None allowed_units.append(unit) return allowed_units def _validate_arg_value(param_name, func_name, arg, targets, equivalencies, strict_dimensionless=False): """ Validates the object passed in to the wrapped function, ``arg``, with target unit or physical type, ``target``. """ if len(targets) == 0: return allowed_units = _get_allowed_units(targets) # If dimensionless is an allowed unit and the argument is unit-less, # allow numbers or numpy arrays with numeric dtypes if (dimensionless_unscaled in allowed_units and not strict_dimensionless and not hasattr(arg, "unit")): if isinstance(arg, Number): return elif (isinstance(arg, np.ndarray) and np.issubdtype(arg.dtype, np.number)): return for allowed_unit in allowed_units: try: is_equivalent = arg.unit.is_equivalent(allowed_unit, equivalencies=equivalencies) if is_equivalent: break except AttributeError: # Either there is no .unit or no .is_equivalent if hasattr(arg, "unit"): error_msg = ("a 'unit' attribute without an 'is_equivalent' method") else: error_msg = "no 'unit' attribute" raise TypeError(f"Argument '{param_name}' to function '{func_name}'" f" has {error_msg}. You should pass in an astropy " "Quantity instead.") else: error_msg = (f"Argument '{param_name}' to function '{func_name}' must " "be in units convertible to") if len(targets) > 1: targ_names = ", ".join([f"'{str(targ)}'" for targ in targets]) raise UnitsError(f"{error_msg} one of: {targ_names}.") else: raise UnitsError(f"{error_msg} '{str(targets[0])}'.") def _parse_annotation(target): if target in (None, NoneType, inspect._empty): return target # check if unit-like try: unit = Unit(target) except (TypeError, ValueError): try: ptype = get_physical_type(target) except (TypeError, ValueError, KeyError): # KeyError for Enum if isinstance(target, str): raise ValueError(f"invalid unit or physical type {target!r}.") from None else: return ptype else: return unit # could be a type hint origin = T.get_origin(target) if origin is T.Union: return [_parse_annotation(t) for t in T.get_args(target)] elif origin is not T.Annotated: # can't be Quantity[] return False # parse type hint cls, *annotations = T.get_args(target) if not issubclass(cls, Quantity) or not annotations: return False # get unit from type hint unit, *rest = annotations if not isinstance(unit, (UnitBase, PhysicalType)): return False return unit class QuantityInput: @classmethod def as_decorator(cls, func=None, **kwargs): r""" A decorator for validating the units of arguments to functions. Unit specifications can be provided as keyword arguments to the decorator, or by using function annotation syntax. Arguments to the decorator take precedence over any function annotations present. A `~astropy.units.UnitsError` will be raised if the unit attribute of the argument is not equivalent to the unit specified to the decorator or in the annotation. If the argument has no unit attribute, i.e. it is not a Quantity object, a `ValueError` will be raised unless the argument is an annotation. This is to allow non Quantity annotations to pass through. Where an equivalency is specified in the decorator, the function will be executed with that equivalency in force. Notes ----- The checking of arguments inside variable arguments to a function is not supported (i.e. \*arg or \**kwargs). The original function is accessible by the attributed ``__wrapped__``. See :func:`functools.wraps` for details. Examples -------- .. code-block:: python import astropy.units as u @u.quantity_input(myangle=u.arcsec) def myfunction(myangle): return myangle**2 .. code-block:: python import astropy.units as u @u.quantity_input def myfunction(myangle: u.arcsec): return myangle**2 Or using a unit-aware Quantity annotation. .. code-block:: python @u.quantity_input def myfunction(myangle: u.Quantity[u.arcsec]): return myangle**2 Also you can specify a return value annotation, which will cause the function to always return a `~astropy.units.Quantity` in that unit. .. code-block:: python import astropy.units as u @u.quantity_input def myfunction(myangle: u.arcsec) -> u.deg**2: return myangle**2 Using equivalencies:: import astropy.units as u @u.quantity_input(myenergy=u.eV, equivalencies=u.mass_energy()) def myfunction(myenergy): return myenergy**2 """ self = cls(**kwargs) if func is not None and not kwargs: return self(func) else: return self def __init__(self, func=None, strict_dimensionless=False, **kwargs): self.equivalencies = kwargs.pop('equivalencies', []) self.decorator_kwargs = kwargs self.strict_dimensionless = strict_dimensionless def __call__(self, wrapped_function): # Extract the function signature for the function we are wrapping. wrapped_signature = inspect.signature(wrapped_function) # Define a new function to return in place of the wrapped one @wraps(wrapped_function) def wrapper(*func_args, **func_kwargs): # Bind the arguments to our new function to the signature of the original. bound_args = wrapped_signature.bind(*func_args, **func_kwargs) # Iterate through the parameters of the original signature for param in wrapped_signature.parameters.values(): # We do not support variable arguments (*args, **kwargs) if param.kind in (inspect.Parameter.VAR_KEYWORD, inspect.Parameter.VAR_POSITIONAL): continue # Catch the (never triggered) case where bind relied on a default value. if (param.name not in bound_args.arguments and param.default is not param.empty): bound_args.arguments[param.name] = param.default # Get the value of this parameter (argument to new function) arg = bound_args.arguments[param.name] # Get target unit or physical type, either from decorator kwargs # or annotations if param.name in self.decorator_kwargs: targets = self.decorator_kwargs[param.name] is_annotation = False else: targets = param.annotation is_annotation = True # parses to unit if it's an annotation (or list thereof) targets = _parse_annotation(targets) # If the targets is empty, then no target units or physical # types were specified so we can continue to the next arg if targets is inspect.Parameter.empty: continue # If the argument value is None, and the default value is None, # pass through the None even if there is a target unit if arg is None and param.default is None: continue # Here, we check whether multiple target unit/physical type's # were specified in the decorator/annotation, or whether a # single string (unit or physical type) or a Unit object was # specified if (isinstance(targets, str) or not isinstance(targets, Sequence)): valid_targets = [targets] # Check for None in the supplied list of allowed units and, if # present and the passed value is also None, ignore. elif None in targets or NoneType in targets: if arg is None: continue else: valid_targets = [t for t in targets if t is not None] else: valid_targets = targets # If we're dealing with an annotation, skip all the targets that # are not strings or subclasses of Unit. This is to allow # non unit related annotations to pass through if is_annotation: valid_targets = [t for t in valid_targets if isinstance(t, (str, UnitBase, PhysicalType))] # Now we loop over the allowed units/physical types and validate # the value of the argument: _validate_arg_value(param.name, wrapped_function.__name__, arg, valid_targets, self.equivalencies, self.strict_dimensionless) # Call the original function with any equivalencies in force. with add_enabled_equivalencies(self.equivalencies): return_ = wrapped_function(*func_args, **func_kwargs) # Return ra = wrapped_signature.return_annotation valid_empty = (inspect.Signature.empty, None, NoneType, T.NoReturn) if ra not in valid_empty: target = (ra if T.get_origin(ra) not in (T.Annotated, T.Union) else _parse_annotation(ra)) if isinstance(target, str) or not isinstance(target, Sequence): target = [target] valid_targets = [t for t in target if isinstance(t, (str, UnitBase, PhysicalType))] _validate_arg_value("return", wrapped_function.__name__, return_, valid_targets, self.equivalencies, self.strict_dimensionless) if len(valid_targets) > 0: return_ <<= valid_targets[0] return return_ return wrapper quantity_input = QuantityInput.as_decorator ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/deprecated.py0000644000175100001710000000426700000000000017573 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """ This package defines deprecated units. These units are not available in the top-level `astropy.units` namespace. To use these units, you must import the `astropy.units.deprecated` module:: >>> from astropy.units import deprecated >>> q = 10. * deprecated.emu # doctest: +SKIP To include them in `~astropy.units.UnitBase.compose` and the results of `~astropy.units.UnitBase.find_equivalent_units`, do:: >>> from astropy.units import deprecated >>> deprecated.enable() # doctest: +SKIP """ _ns = globals() def _initialize_module(): # Local imports to avoid polluting top-level namespace from . import cgs from . import astrophys from .core import def_unit, _add_prefixes def_unit(['emu'], cgs.Bi, namespace=_ns, doc='Biot: CGS (EMU) unit of current') # Add only some *prefixes* as deprecated units. _add_prefixes(astrophys.jupiterMass, namespace=_ns, prefixes=True) _add_prefixes(astrophys.earthMass, namespace=_ns, prefixes=True) _add_prefixes(astrophys.jupiterRad, namespace=_ns, prefixes=True) _add_prefixes(astrophys.earthRad, namespace=_ns, prefixes=True) _initialize_module() ########################################################################### # DOCSTRING # This generates a docstring for this module that describes all of the # standard units defined here. from .utils import (generate_unit_summary as _generate_unit_summary, generate_prefixonly_unit_summary as _generate_prefixonly_unit_summary) if __doc__ is not None: __doc__ += _generate_unit_summary(globals()) __doc__ += _generate_prefixonly_unit_summary(globals()) def enable(): """ Enable deprecated units so they appear in results of `~astropy.units.UnitBase.find_equivalent_units` and `~astropy.units.UnitBase.compose`. This may be used with the ``with`` statement to enable deprecated units only temporarily. """ # Local import to avoid cyclical import from .core import add_enabled_units # Local import to avoid polluting namespace import inspect return add_enabled_units(inspect.getmodule(enable)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/equivalencies.py0000644000175100001710000007357600000000000020341 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """A set of standard astronomical equivalencies.""" from collections import UserList # THIRD-PARTY import numpy as np import warnings # LOCAL from astropy.constants import si as _si from astropy.utils.exceptions import AstropyDeprecationWarning from astropy.utils.misc import isiterable from . import si from . import cgs from . import astrophys from . import misc from .function import units as function_units from . import dimensionless_unscaled from .core import UnitsError, Unit __all__ = ['parallax', 'spectral', 'spectral_density', 'doppler_radio', 'doppler_optical', 'doppler_relativistic', 'mass_energy', 'brightness_temperature', 'thermodynamic_temperature', 'beam_angular_area', 'dimensionless_angles', 'logarithmic', 'temperature', 'temperature_energy', 'molar_mass_amu', 'pixel_scale', 'plate_scale', "Equivalency"] class Equivalency(UserList): """ A container for a units equivalency. Attributes ---------- name: `str` The name of the equivalency. kwargs: `dict` Any positional or keyword arguments used to make the equivalency. """ def __init__(self, equiv_list, name='', kwargs=None): self.data = equiv_list self.name = [name] self.kwargs = [kwargs] if kwargs is not None else [dict()] def __add__(self, other): if isinstance(other, Equivalency): new = super().__add__(other) new.name = self.name[:] + other.name new.kwargs = self.kwargs[:] + other.kwargs return new else: return self.data.__add__(other) def __eq__(self, other): return (isinstance(other, self.__class__) and self.name == other.name and self.kwargs == other.kwargs) def dimensionless_angles(): """Allow angles to be equivalent to dimensionless (with 1 rad = 1 m/m = 1). It is special compared to other equivalency pairs in that it allows this independent of the power to which the angle is raised, and independent of whether it is part of a more complicated unit. """ return Equivalency([(si.radian, None)], "dimensionless_angles") def logarithmic(): """Allow logarithmic units to be converted to dimensionless fractions""" return Equivalency([ (dimensionless_unscaled, function_units.dex, np.log10, lambda x: 10.**x) ], "logarithmic") def parallax(): """ Returns a list of equivalence pairs that handle the conversion between parallax angle and distance. """ def parallax_converter(x): x = np.asanyarray(x) d = 1 / x if isiterable(d): d[d < 0] = np.nan return d else: if d < 0: return np.array(np.nan) else: return d return Equivalency([ (si.arcsecond, astrophys.parsec, parallax_converter) ], "parallax") def spectral(): """ Returns a list of equivalence pairs that handle spectral wavelength, wave number, frequency, and energy equivalencies. Allows conversions between wavelength units, wave number units, frequency units, and energy units as they relate to light. There are two types of wave number: * spectroscopic - :math:`1 / \\lambda` (per meter) * angular - :math:`2 \\pi / \\lambda` (radian per meter) """ hc = _si.h.value * _si.c.value two_pi = 2.0 * np.pi inv_m_spec = si.m ** -1 inv_m_ang = si.radian / si.m return Equivalency([ (si.m, si.Hz, lambda x: _si.c.value / x), (si.m, si.J, lambda x: hc / x), (si.Hz, si.J, lambda x: _si.h.value * x, lambda x: x / _si.h.value), (si.m, inv_m_spec, lambda x: 1.0 / x), (si.Hz, inv_m_spec, lambda x: x / _si.c.value, lambda x: _si.c.value * x), (si.J, inv_m_spec, lambda x: x / hc, lambda x: hc * x), (inv_m_spec, inv_m_ang, lambda x: x * two_pi, lambda x: x / two_pi), (si.m, inv_m_ang, lambda x: two_pi / x), (si.Hz, inv_m_ang, lambda x: two_pi * x / _si.c.value, lambda x: _si.c.value * x / two_pi), (si.J, inv_m_ang, lambda x: x * two_pi / hc, lambda x: hc * x / two_pi) ], "spectral") def spectral_density(wav, factor=None): """ Returns a list of equivalence pairs that handle spectral density with regard to wavelength and frequency. Parameters ---------- wav : `~astropy.units.Quantity` `~astropy.units.Quantity` associated with values being converted (e.g., wavelength or frequency). Notes ----- The ``factor`` argument is left for backward-compatibility with the syntax ``spectral_density(unit, factor)`` but users are encouraged to use ``spectral_density(factor * unit)`` instead. """ from .core import UnitBase if isinstance(wav, UnitBase): if factor is None: raise ValueError( 'If `wav` is specified as a unit, `factor` should be set') wav = factor * wav # Convert to Quantity c_Aps = _si.c.to_value(si.AA / si.s) # Angstrom/s h_cgs = _si.h.cgs.value # erg * s hc = c_Aps * h_cgs # flux density f_la = cgs.erg / si.angstrom / si.cm ** 2 / si.s f_nu = cgs.erg / si.Hz / si.cm ** 2 / si.s nu_f_nu = cgs.erg / si.cm ** 2 / si.s la_f_la = nu_f_nu phot_f_la = astrophys.photon / (si.cm ** 2 * si.s * si.AA) phot_f_nu = astrophys.photon / (si.cm ** 2 * si.s * si.Hz) la_phot_f_la = astrophys.photon / (si.cm ** 2 * si.s) # luminosity density L_nu = cgs.erg / si.s / si.Hz L_la = cgs.erg / si.s / si.angstrom nu_L_nu = cgs.erg / si.s la_L_la = nu_L_nu phot_L_la = astrophys.photon / (si.s * si.AA) phot_L_nu = astrophys.photon / (si.s * si.Hz) # surface brightness (flux equiv) S_la = cgs.erg / si.angstrom / si.cm ** 2 / si.s / si.sr S_nu = cgs.erg / si.Hz / si.cm ** 2 / si.s / si.sr nu_S_nu = cgs.erg / si.cm ** 2 / si.s / si.sr la_S_la = nu_S_nu phot_S_la = astrophys.photon / (si.cm ** 2 * si.s * si.AA * si.sr) phot_S_nu = astrophys.photon / (si.cm ** 2 * si.s * si.Hz * si.sr) # surface brightness (luminosity equiv) SL_nu = cgs.erg / si.s / si.Hz / si.sr SL_la = cgs.erg / si.s / si.angstrom / si.sr nu_SL_nu = cgs.erg / si.s / si.sr la_SL_la = nu_SL_nu phot_SL_la = astrophys.photon / (si.s * si.AA * si.sr) phot_SL_nu = astrophys.photon / (si.s * si.Hz * si.sr) def converter(x): return x * (wav.to_value(si.AA, spectral()) ** 2 / c_Aps) def iconverter(x): return x / (wav.to_value(si.AA, spectral()) ** 2 / c_Aps) def converter_f_nu_to_nu_f_nu(x): return x * wav.to_value(si.Hz, spectral()) def iconverter_f_nu_to_nu_f_nu(x): return x / wav.to_value(si.Hz, spectral()) def converter_f_la_to_la_f_la(x): return x * wav.to_value(si.AA, spectral()) def iconverter_f_la_to_la_f_la(x): return x / wav.to_value(si.AA, spectral()) def converter_phot_f_la_to_f_la(x): return hc * x / wav.to_value(si.AA, spectral()) def iconverter_phot_f_la_to_f_la(x): return x * wav.to_value(si.AA, spectral()) / hc def converter_phot_f_la_to_f_nu(x): return h_cgs * x * wav.to_value(si.AA, spectral()) def iconverter_phot_f_la_to_f_nu(x): return x / (wav.to_value(si.AA, spectral()) * h_cgs) def converter_phot_f_la_phot_f_nu(x): return x * wav.to_value(si.AA, spectral()) ** 2 / c_Aps def iconverter_phot_f_la_phot_f_nu(x): return c_Aps * x / wav.to_value(si.AA, spectral()) ** 2 converter_phot_f_nu_to_f_nu = converter_phot_f_la_to_f_la iconverter_phot_f_nu_to_f_nu = iconverter_phot_f_la_to_f_la def converter_phot_f_nu_to_f_la(x): return x * hc * c_Aps / wav.to_value(si.AA, spectral()) ** 3 def iconverter_phot_f_nu_to_f_la(x): return x * wav.to_value(si.AA, spectral()) ** 3 / (hc * c_Aps) # for luminosity density converter_L_nu_to_nu_L_nu = converter_f_nu_to_nu_f_nu iconverter_L_nu_to_nu_L_nu = iconverter_f_nu_to_nu_f_nu converter_L_la_to_la_L_la = converter_f_la_to_la_f_la iconverter_L_la_to_la_L_la = iconverter_f_la_to_la_f_la converter_phot_L_la_to_L_la = converter_phot_f_la_to_f_la iconverter_phot_L_la_to_L_la = iconverter_phot_f_la_to_f_la converter_phot_L_la_to_L_nu = converter_phot_f_la_to_f_nu iconverter_phot_L_la_to_L_nu = iconverter_phot_f_la_to_f_nu converter_phot_L_la_phot_L_nu = converter_phot_f_la_phot_f_nu iconverter_phot_L_la_phot_L_nu = iconverter_phot_f_la_phot_f_nu converter_phot_L_nu_to_L_nu = converter_phot_f_nu_to_f_nu iconverter_phot_L_nu_to_L_nu = iconverter_phot_f_nu_to_f_nu converter_phot_L_nu_to_L_la = converter_phot_f_nu_to_f_la iconverter_phot_L_nu_to_L_la = iconverter_phot_f_nu_to_f_la return Equivalency([ # flux (f_la, f_nu, converter, iconverter), (f_nu, nu_f_nu, converter_f_nu_to_nu_f_nu, iconverter_f_nu_to_nu_f_nu), (f_la, la_f_la, converter_f_la_to_la_f_la, iconverter_f_la_to_la_f_la), (phot_f_la, f_la, converter_phot_f_la_to_f_la, iconverter_phot_f_la_to_f_la), (phot_f_la, f_nu, converter_phot_f_la_to_f_nu, iconverter_phot_f_la_to_f_nu), (phot_f_la, phot_f_nu, converter_phot_f_la_phot_f_nu, iconverter_phot_f_la_phot_f_nu), (phot_f_nu, f_nu, converter_phot_f_nu_to_f_nu, iconverter_phot_f_nu_to_f_nu), (phot_f_nu, f_la, converter_phot_f_nu_to_f_la, iconverter_phot_f_nu_to_f_la), # integrated flux (la_phot_f_la, la_f_la, converter_phot_f_la_to_f_la, iconverter_phot_f_la_to_f_la), # luminosity (L_la, L_nu, converter, iconverter), (L_nu, nu_L_nu, converter_L_nu_to_nu_L_nu, iconverter_L_nu_to_nu_L_nu), (L_la, la_L_la, converter_L_la_to_la_L_la, iconverter_L_la_to_la_L_la), (phot_L_la, L_la, converter_phot_L_la_to_L_la, iconverter_phot_L_la_to_L_la), (phot_L_la, L_nu, converter_phot_L_la_to_L_nu, iconverter_phot_L_la_to_L_nu), (phot_L_la, phot_L_nu, converter_phot_L_la_phot_L_nu, iconverter_phot_L_la_phot_L_nu), (phot_L_nu, L_nu, converter_phot_L_nu_to_L_nu, iconverter_phot_L_nu_to_L_nu), (phot_L_nu, L_la, converter_phot_L_nu_to_L_la, iconverter_phot_L_nu_to_L_la), # surface brightness (flux equiv) (S_la, S_nu, converter, iconverter), (S_nu, nu_S_nu, converter_f_nu_to_nu_f_nu, iconverter_f_nu_to_nu_f_nu), (S_la, la_S_la, converter_f_la_to_la_f_la, iconverter_f_la_to_la_f_la), (phot_S_la, S_la, converter_phot_f_la_to_f_la, iconverter_phot_f_la_to_f_la), (phot_S_la, S_nu, converter_phot_f_la_to_f_nu, iconverter_phot_f_la_to_f_nu), (phot_S_la, phot_S_nu, converter_phot_f_la_phot_f_nu, iconverter_phot_f_la_phot_f_nu), (phot_S_nu, S_nu, converter_phot_f_nu_to_f_nu, iconverter_phot_f_nu_to_f_nu), (phot_S_nu, S_la, converter_phot_f_nu_to_f_la, iconverter_phot_f_nu_to_f_la), # surface brightness (luminosity equiv) (SL_la, SL_nu, converter, iconverter), (SL_nu, nu_SL_nu, converter_L_nu_to_nu_L_nu, iconverter_L_nu_to_nu_L_nu), (SL_la, la_SL_la, converter_L_la_to_la_L_la, iconverter_L_la_to_la_L_la), (phot_SL_la, SL_la, converter_phot_L_la_to_L_la, iconverter_phot_L_la_to_L_la), (phot_SL_la, SL_nu, converter_phot_L_la_to_L_nu, iconverter_phot_L_la_to_L_nu), (phot_SL_la, phot_SL_nu, converter_phot_L_la_phot_L_nu, iconverter_phot_L_la_phot_L_nu), (phot_SL_nu, SL_nu, converter_phot_L_nu_to_L_nu, iconverter_phot_L_nu_to_L_nu), (phot_SL_nu, SL_la, converter_phot_L_nu_to_L_la, iconverter_phot_L_nu_to_L_la), ], "spectral_density", {'wav': wav, 'factor': factor}) def doppler_radio(rest): r""" Return the equivalency pairs for the radio convention for velocity. The radio convention for the relation between velocity and frequency is: :math:`V = c \frac{f_0 - f}{f_0} ; f(V) = f_0 ( 1 - V/c )` Parameters ---------- rest : `~astropy.units.Quantity` Any quantity supported by the standard spectral equivalencies (wavelength, energy, frequency, wave number). References ---------- `NRAO site defining the conventions `_ Examples -------- >>> import astropy.units as u >>> CO_restfreq = 115.27120*u.GHz # rest frequency of 12 CO 1-0 in GHz >>> radio_CO_equiv = u.doppler_radio(CO_restfreq) >>> measured_freq = 115.2832*u.GHz >>> radio_velocity = measured_freq.to(u.km/u.s, equivalencies=radio_CO_equiv) >>> radio_velocity # doctest: +FLOAT_CMP """ assert_is_spectral_unit(rest) ckms = _si.c.to_value('km/s') def to_vel_freq(x): restfreq = rest.to_value(si.Hz, equivalencies=spectral()) return (restfreq-x) / (restfreq) * ckms def from_vel_freq(x): restfreq = rest.to_value(si.Hz, equivalencies=spectral()) voverc = x/ckms return restfreq * (1-voverc) def to_vel_wav(x): restwav = rest.to_value(si.AA, spectral()) return (x-restwav) / (x) * ckms def from_vel_wav(x): restwav = rest.to_value(si.AA, spectral()) return restwav * ckms / (ckms-x) def to_vel_en(x): resten = rest.to_value(si.eV, equivalencies=spectral()) return (resten-x) / (resten) * ckms def from_vel_en(x): resten = rest.to_value(si.eV, equivalencies=spectral()) voverc = x/ckms return resten * (1-voverc) return Equivalency([(si.Hz, si.km/si.s, to_vel_freq, from_vel_freq), (si.AA, si.km/si.s, to_vel_wav, from_vel_wav), (si.eV, si.km/si.s, to_vel_en, from_vel_en), ], "doppler_radio", {'rest': rest}) def doppler_optical(rest): r""" Return the equivalency pairs for the optical convention for velocity. The optical convention for the relation between velocity and frequency is: :math:`V = c \frac{f_0 - f}{f } ; f(V) = f_0 ( 1 + V/c )^{-1}` Parameters ---------- rest : `~astropy.units.Quantity` Any quantity supported by the standard spectral equivalencies (wavelength, energy, frequency, wave number). References ---------- `NRAO site defining the conventions `_ Examples -------- >>> import astropy.units as u >>> CO_restfreq = 115.27120*u.GHz # rest frequency of 12 CO 1-0 in GHz >>> optical_CO_equiv = u.doppler_optical(CO_restfreq) >>> measured_freq = 115.2832*u.GHz >>> optical_velocity = measured_freq.to(u.km/u.s, equivalencies=optical_CO_equiv) >>> optical_velocity # doctest: +FLOAT_CMP """ assert_is_spectral_unit(rest) ckms = _si.c.to_value('km/s') def to_vel_freq(x): restfreq = rest.to_value(si.Hz, equivalencies=spectral()) return ckms * (restfreq-x) / x def from_vel_freq(x): restfreq = rest.to_value(si.Hz, equivalencies=spectral()) voverc = x/ckms return restfreq / (1+voverc) def to_vel_wav(x): restwav = rest.to_value(si.AA, spectral()) return ckms * (x/restwav-1) def from_vel_wav(x): restwav = rest.to_value(si.AA, spectral()) voverc = x/ckms return restwav * (1+voverc) def to_vel_en(x): resten = rest.to_value(si.eV, equivalencies=spectral()) return ckms * (resten-x) / x def from_vel_en(x): resten = rest.to_value(si.eV, equivalencies=spectral()) voverc = x/ckms return resten / (1+voverc) return Equivalency([(si.Hz, si.km/si.s, to_vel_freq, from_vel_freq), (si.AA, si.km/si.s, to_vel_wav, from_vel_wav), (si.eV, si.km/si.s, to_vel_en, from_vel_en), ], "doppler_optical", {'rest': rest}) def doppler_relativistic(rest): r""" Return the equivalency pairs for the relativistic convention for velocity. The full relativistic convention for the relation between velocity and frequency is: :math:`V = c \frac{f_0^2 - f^2}{f_0^2 + f^2} ; f(V) = f_0 \frac{\left(1 - (V/c)^2\right)^{1/2}}{(1+V/c)}` Parameters ---------- rest : `~astropy.units.Quantity` Any quantity supported by the standard spectral equivalencies (wavelength, energy, frequency, wave number). References ---------- `NRAO site defining the conventions `_ Examples -------- >>> import astropy.units as u >>> CO_restfreq = 115.27120*u.GHz # rest frequency of 12 CO 1-0 in GHz >>> relativistic_CO_equiv = u.doppler_relativistic(CO_restfreq) >>> measured_freq = 115.2832*u.GHz >>> relativistic_velocity = measured_freq.to(u.km/u.s, equivalencies=relativistic_CO_equiv) >>> relativistic_velocity # doctest: +FLOAT_CMP >>> measured_velocity = 1250 * u.km/u.s >>> relativistic_frequency = measured_velocity.to(u.GHz, equivalencies=relativistic_CO_equiv) >>> relativistic_frequency # doctest: +FLOAT_CMP >>> relativistic_wavelength = measured_velocity.to(u.mm, equivalencies=relativistic_CO_equiv) >>> relativistic_wavelength # doctest: +FLOAT_CMP """ assert_is_spectral_unit(rest) ckms = _si.c.to_value('km/s') def to_vel_freq(x): restfreq = rest.to_value(si.Hz, equivalencies=spectral()) return (restfreq**2-x**2) / (restfreq**2+x**2) * ckms def from_vel_freq(x): restfreq = rest.to_value(si.Hz, equivalencies=spectral()) voverc = x/ckms return restfreq * ((1-voverc) / (1+(voverc)))**0.5 def to_vel_wav(x): restwav = rest.to_value(si.AA, spectral()) return (x**2-restwav**2) / (restwav**2+x**2) * ckms def from_vel_wav(x): restwav = rest.to_value(si.AA, spectral()) voverc = x/ckms return restwav * ((1+voverc) / (1-voverc))**0.5 def to_vel_en(x): resten = rest.to_value(si.eV, spectral()) return (resten**2-x**2) / (resten**2+x**2) * ckms def from_vel_en(x): resten = rest.to_value(si.eV, spectral()) voverc = x/ckms return resten * ((1-voverc) / (1+(voverc)))**0.5 return Equivalency([(si.Hz, si.km/si.s, to_vel_freq, from_vel_freq), (si.AA, si.km/si.s, to_vel_wav, from_vel_wav), (si.eV, si.km/si.s, to_vel_en, from_vel_en), ], "doppler_relativistic", {'rest': rest}) def molar_mass_amu(): """ Returns the equivalence between amu and molar mass. """ return Equivalency([ (si.g/si.mol, misc.u) ], "molar_mass_amu") def mass_energy(): """ Returns a list of equivalence pairs that handle the conversion between mass and energy. """ return Equivalency([(si.kg, si.J, lambda x: x * _si.c.value ** 2, lambda x: x / _si.c.value ** 2), (si.kg / si.m ** 2, si.J / si.m ** 2, lambda x: x * _si.c.value ** 2, lambda x: x / _si.c.value ** 2), (si.kg / si.m ** 3, si.J / si.m ** 3, lambda x: x * _si.c.value ** 2, lambda x: x / _si.c.value ** 2), (si.kg / si.s, si.J / si.s, lambda x: x * _si.c.value ** 2, lambda x: x / _si.c.value ** 2), ], "mass_energy") def brightness_temperature(frequency, beam_area=None): r""" Defines the conversion between Jy/sr and "brightness temperature", :math:`T_B`, in Kelvins. The brightness temperature is a unit very commonly used in radio astronomy. See, e.g., "Tools of Radio Astronomy" (Wilson 2009) eqn 8.16 and eqn 8.19 (these pages are available on `google books `__). :math:`T_B \equiv S_\nu / \left(2 k \nu^2 / c^2 \right)` If the input is in Jy/beam or Jy (assuming it came from a single beam), the beam area is essential for this computation: the brightness temperature is inversely proportional to the beam area. Parameters ---------- frequency : `~astropy.units.Quantity` The observed ``spectral`` equivalent `~astropy.units.Unit` (e.g., frequency or wavelength). The variable is named 'frequency' because it is more commonly used in radio astronomy. BACKWARD COMPATIBILITY NOTE: previous versions of the brightness temperature equivalency used the keyword ``disp``, which is no longer supported. beam_area : `~astropy.units.Quantity` ['solid angle'] Beam area in angular units, i.e. steradian equivalent Examples -------- Arecibo C-band beam:: >>> import numpy as np >>> from astropy import units as u >>> beam_sigma = 50*u.arcsec >>> beam_area = 2*np.pi*(beam_sigma)**2 >>> freq = 5*u.GHz >>> equiv = u.brightness_temperature(freq) >>> (1*u.Jy/beam_area).to(u.K, equivalencies=equiv) # doctest: +FLOAT_CMP VLA synthetic beam:: >>> bmaj = 15*u.arcsec >>> bmin = 15*u.arcsec >>> fwhm_to_sigma = 1./(8*np.log(2))**0.5 >>> beam_area = 2.*np.pi*(bmaj*bmin*fwhm_to_sigma**2) >>> freq = 5*u.GHz >>> equiv = u.brightness_temperature(freq) >>> (u.Jy/beam_area).to(u.K, equivalencies=equiv) # doctest: +FLOAT_CMP Any generic surface brightness: >>> surf_brightness = 1e6*u.MJy/u.sr >>> surf_brightness.to(u.K, equivalencies=u.brightness_temperature(500*u.GHz)) # doctest: +FLOAT_CMP """ if frequency.unit.is_equivalent(si.sr): if not beam_area.unit.is_equivalent(si.Hz): raise ValueError("The inputs to `brightness_temperature` are " "frequency and angular area.") warnings.warn("The inputs to `brightness_temperature` have changed. " "Frequency is now the first input, and angular area " "is the second, optional input.", AstropyDeprecationWarning) frequency, beam_area = beam_area, frequency nu = frequency.to(si.GHz, spectral()) if beam_area is not None: beam = beam_area.to_value(si.sr) def convert_Jy_to_K(x_jybm): factor = (2 * _si.k_B * si.K * nu**2 / _si.c**2).to(astrophys.Jy).value return (x_jybm / beam / factor) def convert_K_to_Jy(x_K): factor = (astrophys.Jy / (2 * _si.k_B * nu**2 / _si.c**2)).to(si.K).value return (x_K * beam / factor) return Equivalency([(astrophys.Jy, si.K, convert_Jy_to_K, convert_K_to_Jy), (astrophys.Jy/astrophys.beam, si.K, convert_Jy_to_K, convert_K_to_Jy),], "brightness_temperature", {'frequency': frequency, 'beam_area': beam_area}) else: def convert_JySr_to_K(x_jysr): factor = (2 * _si.k_B * si.K * nu**2 / _si.c**2).to(astrophys.Jy).value return (x_jysr / factor) def convert_K_to_JySr(x_K): factor = (astrophys.Jy / (2 * _si.k_B * nu**2 / _si.c**2)).to(si.K).value return (x_K / factor) # multiplied by 1x for 1 steradian return Equivalency([(astrophys.Jy/si.sr, si.K, convert_JySr_to_K, convert_K_to_JySr)], "brightness_temperature", {'frequency': frequency, 'beam_area': beam_area}) def beam_angular_area(beam_area): """ Convert between the ``beam`` unit, which is commonly used to express the area of a radio telescope resolution element, and an area on the sky. This equivalency also supports direct conversion between ``Jy/beam`` and ``Jy/steradian`` units, since that is a common operation. Parameters ---------- beam_area : unit-like The area of the beam in angular area units (e.g., steradians) Must have angular area equivalent units. """ return Equivalency([(astrophys.beam, Unit(beam_area)), (astrophys.beam**-1, Unit(beam_area)**-1), (astrophys.Jy/astrophys.beam, astrophys.Jy/Unit(beam_area)),], "beam_angular_area", {'beam_area': beam_area}) def thermodynamic_temperature(frequency, T_cmb=None): r"""Defines the conversion between Jy/sr and "thermodynamic temperature", :math:`T_{CMB}`, in Kelvins. The thermodynamic temperature is a unit very commonly used in cosmology. See eqn 8 in [1] :math:`K_{CMB} \equiv I_\nu / \left(2 k \nu^2 / c^2 f(\nu) \right)` with :math:`f(\nu) = \frac{ x^2 e^x}{(e^x - 1 )^2}` where :math:`x = h \nu / k T` Parameters ---------- frequency : `~astropy.units.Quantity` The observed `spectral` equivalent `~astropy.units.Unit` (e.g., frequency or wavelength). Must have spectral units. T_cmb : `~astropy.units.Quantity` ['temperature'] or None The CMB temperature at z=0. If `None`, the default cosmology will be used to get this temperature. Must have units of temperature. Notes ----- For broad band receivers, this conversion do not hold as it highly depends on the frequency References ---------- .. [1] Planck 2013 results. IX. HFI spectral response https://arxiv.org/abs/1303.5070 Examples -------- Planck HFI 143 GHz:: >>> from astropy import units as u >>> from astropy.cosmology import Planck15 >>> freq = 143 * u.GHz >>> equiv = u.thermodynamic_temperature(freq, Planck15.Tcmb0) >>> (1. * u.mK).to(u.MJy / u.sr, equivalencies=equiv) # doctest: +FLOAT_CMP """ nu = frequency.to(si.GHz, spectral()) if T_cmb is None: from astropy.cosmology import default_cosmology T_cmb = default_cosmology.get().Tcmb0 def f(nu, T_cmb=T_cmb): x = _si.h * nu / _si.k_B / T_cmb return x**2 * np.exp(x) / np.expm1(x)**2 def convert_Jy_to_K(x_jybm): factor = (f(nu) * 2 * _si.k_B * si.K * nu**2 / _si.c**2).to_value(astrophys.Jy) return x_jybm / factor def convert_K_to_Jy(x_K): factor = (astrophys.Jy / (f(nu) * 2 * _si.k_B * nu**2 / _si.c**2)).to_value(si.K) return x_K / factor return Equivalency([(astrophys.Jy/si.sr, si.K, convert_Jy_to_K, convert_K_to_Jy)], "thermodynamic_temperature", {'frequency': frequency, "T_cmb": T_cmb}) def temperature(): """Convert between Kelvin, Celsius, Rankine and Fahrenheit here because Unit and CompositeUnit cannot do addition or subtraction properly. """ from .imperial import deg_F, deg_R return Equivalency([ (si.K, si.deg_C, lambda x: x - 273.15, lambda x: x + 273.15), (si.deg_C, deg_F, lambda x: x * 1.8 + 32.0, lambda x: (x - 32.0) / 1.8), (si.K, deg_F, lambda x: (x - 273.15) * 1.8 + 32.0, lambda x: ((x - 32.0) / 1.8) + 273.15), (deg_R, deg_F, lambda x: x - 459.67, lambda x: x + 459.67), (deg_R, si.deg_C, lambda x: (x - 491.67) * (5/9), lambda x: x * 1.8 + 491.67), (deg_R, si.K, lambda x: x * (5/9), lambda x: x * 1.8)], "temperature") def temperature_energy(): """Convert between Kelvin and keV(eV) to an equivalent amount.""" return Equivalency([ (si.K, si.eV, lambda x: x / (_si.e.value / _si.k_B.value), lambda x: x * (_si.e.value / _si.k_B.value))], "temperature_energy") def assert_is_spectral_unit(value): try: value.to(si.Hz, spectral()) except (AttributeError, UnitsError) as ex: raise UnitsError("The 'rest' value must be a spectral equivalent " "(frequency, wavelength, or energy).") def pixel_scale(pixscale): """ Convert between pixel distances (in units of ``pix``) and other units, given a particular ``pixscale``. Parameters ---------- pixscale : `~astropy.units.Quantity` The pixel scale either in units of /pixel or pixel/. """ decomposed = pixscale.unit.decompose() dimensions = dict(zip(decomposed.bases, decomposed.powers)) pix_power = dimensions.get(misc.pix, 0) if pix_power == -1: physical_unit = Unit(pixscale * misc.pix) elif pix_power == 1: physical_unit = Unit(misc.pix / pixscale) else: raise UnitsError( "The pixel scale unit must have" " pixel dimensionality of 1 or -1.") return Equivalency([(misc.pix, physical_unit)], "pixel_scale", {'pixscale': pixscale}) def plate_scale(platescale): """ Convert between lengths (to be interpreted as lengths in the focal plane) and angular units with a specified ``platescale``. Parameters ---------- platescale : `~astropy.units.Quantity` The pixel scale either in units of distance/pixel or distance/angle. """ if platescale.unit.is_equivalent(si.arcsec/si.m): platescale_val = platescale.to_value(si.radian/si.m) elif platescale.unit.is_equivalent(si.m/si.arcsec): platescale_val = (1/platescale).to_value(si.radian/si.m) else: raise UnitsError("The pixel scale must be in angle/distance or " "distance/angle") return Equivalency([(si.m, si.radian, lambda d: d*platescale_val, lambda rad: rad/platescale_val)], "plate_scale", {'platescale': platescale}) # ------------------------------------------------------------------------- def __getattr__(attr): if attr == "with_H0": import warnings from astropy.cosmology.units import with_H0 from astropy.utils.exceptions import AstropyDeprecationWarning warnings.warn( ("`with_H0` is deprecated from `astropy.units.equivalencies` " "since astropy 5.0 and may be removed in a future version. " "Use `astropy.cosmology.units.with_H0` instead."), AstropyDeprecationWarning) return with_H0 raise AttributeError(f"module {__name__!r} has no attribute {attr!r}.") ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1832528 astropy-5.0.2/astropy/units/format/0000755000175100001710000000000000000000000016400 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/format/__init__.py0000644000175100001710000000421300000000000020511 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ A collection of different unit formats. """ # This is pretty atrocious, but it will prevent a circular import for those # formatters that need access to the units.core module An entry for it should # exist in sys.modules since astropy.units.core imports this module import sys core = sys.modules['astropy.units.core'] from .base import Base # noqa from .generic import Generic, Unscaled # noqa from .cds import CDS # noqa from .console import Console # noqa from .fits import Fits # noqa from .latex import Latex, LatexInline # noqa from .ogip import OGIP # noqa from .unicode_format import Unicode # noqa from .vounit import VOUnit # noqa __all__ = [ 'Base', 'Generic', 'CDS', 'Console', 'Fits', 'Latex', 'LatexInline', 'OGIP', 'Unicode', 'Unscaled', 'VOUnit', 'get_format'] def _known_formats(): inout = [name for name, cls in Base.registry.items() if cls.parse.__func__ is not Base.parse.__func__] out_only = [name for name, cls in Base.registry.items() if cls.parse.__func__ is Base.parse.__func__] return (f"Valid formatter names are: {inout} for input and output, " f"and {out_only} for output only.") def get_format(format=None): """ Get a formatter by name. Parameters ---------- format : str or `astropy.units.format.Base` instance or subclass The name of the format, or the format instance or subclass itself. Returns ------- format : `astropy.units.format.Base` instance The requested formatter. """ if format is None: return Generic if isinstance(format, type) and issubclass(format, Base): return format elif not (isinstance(format, str) or format is None): raise TypeError( f"Formatter must a subclass or instance of a subclass of {Base!r} " f"or a string giving the name of the formatter. {_known_formats()}.") format_lower = format.lower() if format_lower in Base.registry: return Base.registry[format_lower] raise ValueError(f"Unknown format {format!r}. {_known_formats()}") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/format/base.py0000644000175100001710000000217300000000000017667 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst class Base: """ The abstract base class of all unit formats. """ registry = {} def __new__(cls, *args, **kwargs): # This __new__ is to make it clear that there is no reason to # instantiate a Formatter--if you try to you'll just get back the # class return cls def __init_subclass__(cls, **kwargs): # Keep a registry of all formats. Key by the class name unless a name # is explicitly set (i.e., one *not* inherited from a superclass). if 'name' not in cls.__dict__: cls.name = cls.__name__.lower() Base.registry[cls.name] = cls super().__init_subclass__(**kwargs) @classmethod def parse(cls, s): """ Convert a string to a unit object. """ raise NotImplementedError( f"Can not parse with {cls.__name__} format") @classmethod def to_string(cls, u): """ Convert a unit object to a string. """ raise NotImplementedError( f"Can not output in {cls.__name__} format") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/format/cds.py0000644000175100001710000002436400000000000017534 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICNSE.rst # This module includes files automatically generated from ply (these end in # _lextab.py and _parsetab.py). To generate these files, remove them from this # folder, then build astropy and run the tests in-place: # # python setup.py build_ext --inplace # pytest astropy/units # # You can then commit the changes to the re-generated _lextab.py and # _parsetab.py files. """ Handles the CDS string format for units """ import operator import os import re from .base import Base from . import core, utils from astropy.units.utils import is_effectively_unity from astropy.utils import classproperty, parsing from astropy.utils.misc import did_you_mean # TODO: Support logarithmic units using bracketed syntax class CDS(Base): """ Support the `Centre de DonnÊes astronomiques de Strasbourg `_ `Standards for Astronomical Catalogues 2.0 `_ format, and the `complete set of supported units `_. This format is used by VOTable up to version 1.2. """ _tokens = ( 'PRODUCT', 'DIVISION', 'OPEN_PAREN', 'CLOSE_PAREN', 'OPEN_BRACKET', 'CLOSE_BRACKET', 'X', 'SIGN', 'UINT', 'UFLOAT', 'UNIT', 'DIMENSIONLESS' ) @classproperty(lazy=True) def _units(cls): return cls._generate_unit_names() @classproperty(lazy=True) def _parser(cls): return cls._make_parser() @classproperty(lazy=True) def _lexer(cls): return cls._make_lexer() @staticmethod def _generate_unit_names(): from astropy.units import cds from astropy import units as u names = {} for key, val in cds.__dict__.items(): if isinstance(val, u.UnitBase): names[key] = val return names @classmethod def _make_lexer(cls): tokens = cls._tokens t_PRODUCT = r'\.' t_DIVISION = r'/' t_OPEN_PAREN = r'\(' t_CLOSE_PAREN = r'\)' t_OPEN_BRACKET = r'\[' t_CLOSE_BRACKET = r'\]' # NOTE THE ORDERING OF THESE RULES IS IMPORTANT!! # Regular expression rules for simple tokens def t_UFLOAT(t): r'((\d+\.?\d+)|(\.\d+))([eE][+-]?\d+)?' if not re.search(r'[eE\.]', t.value): t.type = 'UINT' t.value = int(t.value) else: t.value = float(t.value) return t def t_UINT(t): r'\d+' t.value = int(t.value) return t def t_SIGN(t): r'[+-](?=\d)' t.value = float(t.value + '1') return t def t_X(t): # multiplication for factor in front of unit r'[x×]' return t def t_UNIT(t): r'\%|°|\\h|((?!\d)\w)+' t.value = cls._get_unit(t) return t def t_DIMENSIONLESS(t): r'---|-' # These are separate from t_UNIT since they cannot have a prefactor. t.value = cls._get_unit(t) return t t_ignore = '' # Error handling rule def t_error(t): raise ValueError( f"Invalid character at col {t.lexpos}") return parsing.lex(lextab='cds_lextab', package='astropy/units', reflags=int(re.UNICODE)) @classmethod def _make_parser(cls): """ The grammar here is based on the description in the `Standards for Astronomical Catalogues 2.0 `_, which is not terribly precise. The exact grammar is here is based on the YACC grammar in the `unity library `_. """ tokens = cls._tokens def p_main(p): ''' main : factor combined_units | combined_units | DIMENSIONLESS | OPEN_BRACKET combined_units CLOSE_BRACKET | OPEN_BRACKET DIMENSIONLESS CLOSE_BRACKET | factor ''' from astropy.units.core import Unit from astropy.units import dex if len(p) == 3: p[0] = Unit(p[1] * p[2]) elif len(p) == 4: p[0] = dex(p[2]) else: p[0] = Unit(p[1]) def p_combined_units(p): ''' combined_units : product_of_units | division_of_units ''' p[0] = p[1] def p_product_of_units(p): ''' product_of_units : unit_expression PRODUCT combined_units | unit_expression ''' if len(p) == 4: p[0] = p[1] * p[3] else: p[0] = p[1] def p_division_of_units(p): ''' division_of_units : DIVISION unit_expression | unit_expression DIVISION combined_units ''' if len(p) == 3: p[0] = p[2] ** -1 else: p[0] = p[1] / p[3] def p_unit_expression(p): ''' unit_expression : unit_with_power | OPEN_PAREN combined_units CLOSE_PAREN ''' if len(p) == 2: p[0] = p[1] else: p[0] = p[2] def p_factor(p): ''' factor : signed_float X UINT signed_int | UINT X UINT signed_int | UINT signed_int | UINT | signed_float ''' if len(p) == 5: if p[3] != 10: raise ValueError( "Only base ten exponents are allowed in CDS") p[0] = p[1] * 10.0 ** p[4] elif len(p) == 3: if p[1] != 10: raise ValueError( "Only base ten exponents are allowed in CDS") p[0] = 10.0 ** p[2] elif len(p) == 2: p[0] = p[1] def p_unit_with_power(p): ''' unit_with_power : UNIT numeric_power | UNIT ''' if len(p) == 2: p[0] = p[1] else: p[0] = p[1] ** p[2] def p_numeric_power(p): ''' numeric_power : sign UINT ''' p[0] = p[1] * p[2] def p_sign(p): ''' sign : SIGN | ''' if len(p) == 2: p[0] = p[1] else: p[0] = 1.0 def p_signed_int(p): ''' signed_int : SIGN UINT ''' p[0] = p[1] * p[2] def p_signed_float(p): ''' signed_float : sign UINT | sign UFLOAT ''' p[0] = p[1] * p[2] def p_error(p): raise ValueError() return parsing.yacc(tabmodule='cds_parsetab', package='astropy/units') @classmethod def _get_unit(cls, t): try: return cls._parse_unit(t.value) except ValueError as e: registry = core.get_current_unit_registry() if t.value in registry.aliases: return registry.aliases[t.value] raise ValueError( f"At col {t.lexpos}, {str(e)}") @classmethod def _parse_unit(cls, unit, detailed_exception=True): if unit not in cls._units: if detailed_exception: raise ValueError( "Unit '{}' not supported by the CDS SAC " "standard. {}".format( unit, did_you_mean( unit, cls._units))) else: raise ValueError() return cls._units[unit] @classmethod def parse(cls, s, debug=False): if ' ' in s: raise ValueError('CDS unit must not contain whitespace') if not isinstance(s, str): s = s.decode('ascii') # This is a short circuit for the case where the string # is just a single unit name try: return cls._parse_unit(s, detailed_exception=False) except ValueError: try: return cls._parser.parse(s, lexer=cls._lexer, debug=debug) except ValueError as e: if str(e): raise ValueError(str(e)) else: raise ValueError("Syntax error") @staticmethod def _get_unit_name(unit): return unit.get_format_name('cds') @classmethod def _format_unit_list(cls, units): out = [] for base, power in units: if power == 1: out.append(cls._get_unit_name(base)) else: out.append(f'{cls._get_unit_name(base)}{int(power)}') return '.'.join(out) @classmethod def to_string(cls, unit): # Remove units that aren't known to the format unit = utils.decompose_to_known_units(unit, cls._get_unit_name) if isinstance(unit, core.CompositeUnit): if unit == core.dimensionless_unscaled: return '---' elif is_effectively_unity(unit.scale*100.): return '%' if unit.scale == 1: s = '' else: m, e = utils.split_mantissa_exponent(unit.scale) parts = [] if m not in ('', '1'): parts.append(m) if e: if not e.startswith('-'): e = "+" + e parts.append(f'10{e}') s = 'x'.join(parts) pairs = list(zip(unit.bases, unit.powers)) if len(pairs) > 0: pairs.sort(key=operator.itemgetter(1), reverse=True) s += cls._format_unit_list(pairs) elif isinstance(unit, core.NamedUnit): s = cls._get_unit_name(unit) return s ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/format/cds_lextab.py0000644000175100001710000000265700000000000021074 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst # This file was automatically generated from ply. To re-generate this file, # remove it from this folder, then build astropy and run the tests in-place: # # python setup.py build_ext --inplace # pytest astropy/units # # You can then commit the changes to this file. # cds_lextab.py. This file automatically created by PLY (version 3.11). Don't edit! _tabversion = '3.10' _lextokens = set(('CLOSE_BRACKET', 'CLOSE_PAREN', 'DIMENSIONLESS', 'DIVISION', 'OPEN_BRACKET', 'OPEN_PAREN', 'PRODUCT', 'SIGN', 'UFLOAT', 'UINT', 'UNIT', 'X')) _lexreflags = 32 _lexliterals = '' _lexstateinfo = {'INITIAL': 'inclusive'} _lexstatere = {'INITIAL': [('(?P((\\d+\\.?\\d+)|(\\.\\d+))([eE][+-]?\\d+)?)|(?P\\d+)|(?P[+-](?=\\d))|(?P[x×])|(?P\\%|°|\\\\h|((?!\\d)\\w)+)|(?P---|-)|(?P\\.)|(?P\\()|(?P\\))|(?P\\[)|(?P\\])|(?P/)', [None, ('t_UFLOAT', 'UFLOAT'), None, None, None, None, ('t_UINT', 'UINT'), ('t_SIGN', 'SIGN'), ('t_X', 'X'), ('t_UNIT', 'UNIT'), None, ('t_DIMENSIONLESS', 'DIMENSIONLESS'), (None, 'PRODUCT'), (None, 'OPEN_PAREN'), (None, 'CLOSE_PAREN'), (None, 'OPEN_BRACKET'), (None, 'CLOSE_BRACKET'), (None, 'DIVISION')])]} _lexstateignore = {'INITIAL': ''} _lexstateerrorf = {'INITIAL': 't_error'} _lexstateeoff = {} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/format/cds_parsetab.py0000644000175100001710000001407200000000000021410 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst # This file was automatically generated from ply. To re-generate this file, # remove it from this folder, then build astropy and run the tests in-place: # # python setup.py build_ext --inplace # pytest astropy/units # # You can then commit the changes to this file. # cds_parsetab.py # This file is automatically generated. Do not edit. # pylint: disable=W,C,R _tabversion = '3.10' _lr_method = 'LALR' _lr_signature = 'CLOSE_BRACKET CLOSE_PAREN DIMENSIONLESS DIVISION OPEN_BRACKET OPEN_PAREN PRODUCT SIGN UFLOAT UINT UNIT X\n main : factor combined_units\n | combined_units\n | DIMENSIONLESS\n | OPEN_BRACKET combined_units CLOSE_BRACKET\n | OPEN_BRACKET DIMENSIONLESS CLOSE_BRACKET\n | factor\n \n combined_units : product_of_units\n | division_of_units\n \n product_of_units : unit_expression PRODUCT combined_units\n | unit_expression\n \n division_of_units : DIVISION unit_expression\n | unit_expression DIVISION combined_units\n \n unit_expression : unit_with_power\n | OPEN_PAREN combined_units CLOSE_PAREN\n \n factor : signed_float X UINT signed_int\n | UINT X UINT signed_int\n | UINT signed_int\n | UINT\n | signed_float\n \n unit_with_power : UNIT numeric_power\n | UNIT\n \n numeric_power : sign UINT\n \n sign : SIGN\n |\n \n signed_int : SIGN UINT\n \n signed_float : sign UINT\n | sign UFLOAT\n ' _lr_action_items = {'DIMENSIONLESS':([0,5,],[4,19,]),'OPEN_BRACKET':([0,],[5,]),'UINT':([0,10,13,16,20,21,23,31,],[7,24,-23,-24,34,35,36,40,]),'DIVISION':([0,2,5,6,7,11,14,15,16,22,24,25,26,27,30,36,39,40,41,42,],[12,12,12,-19,-18,27,-13,12,-21,-17,-26,-27,12,12,-20,-25,-14,-22,-15,-16,]),'SIGN':([0,7,16,34,35,],[13,23,13,23,23,]),'UFLOAT':([0,10,13,],[-24,25,-23,]),'OPEN_PAREN':([0,2,5,6,7,12,15,22,24,25,26,27,36,41,42,],[15,15,15,-19,-18,15,15,-17,-26,-27,15,15,-25,-15,-16,]),'UNIT':([0,2,5,6,7,12,15,22,24,25,26,27,36,41,42,],[16,16,16,-19,-18,16,16,-17,-26,-27,16,16,-25,-15,-16,]),'$end':([1,2,3,4,6,7,8,9,11,14,16,17,22,24,25,28,30,32,33,36,37,38,39,40,41,42,],[0,-6,-2,-3,-19,-18,-7,-8,-10,-13,-21,-1,-17,-26,-27,-11,-20,-4,-5,-25,-9,-12,-14,-22,-15,-16,]),'X':([6,7,24,25,],[20,21,-26,-27,]),'CLOSE_BRACKET':([8,9,11,14,16,18,19,28,30,37,38,39,40,],[-7,-8,-10,-13,-21,32,33,-11,-20,-9,-12,-14,-22,]),'CLOSE_PAREN':([8,9,11,14,16,28,29,30,37,38,39,40,],[-7,-8,-10,-13,-21,-11,39,-20,-9,-12,-14,-22,]),'PRODUCT':([11,14,16,30,39,40,],[26,-13,-21,-20,-14,-22,]),} _lr_action = {} for _k, _v in _lr_action_items.items(): for _x,_y in zip(_v[0],_v[1]): if not _x in _lr_action: _lr_action[_x] = {} _lr_action[_x][_k] = _y del _lr_action_items _lr_goto_items = {'main':([0,],[1,]),'factor':([0,],[2,]),'combined_units':([0,2,5,15,26,27,],[3,17,18,29,37,38,]),'signed_float':([0,],[6,]),'product_of_units':([0,2,5,15,26,27,],[8,8,8,8,8,8,]),'division_of_units':([0,2,5,15,26,27,],[9,9,9,9,9,9,]),'sign':([0,16,],[10,31,]),'unit_expression':([0,2,5,12,15,26,27,],[11,11,11,28,11,11,11,]),'unit_with_power':([0,2,5,12,15,26,27,],[14,14,14,14,14,14,14,]),'signed_int':([7,34,35,],[22,41,42,]),'numeric_power':([16,],[30,]),} _lr_goto = {} for _k, _v in _lr_goto_items.items(): for _x, _y in zip(_v[0], _v[1]): if not _x in _lr_goto: _lr_goto[_x] = {} _lr_goto[_x][_k] = _y del _lr_goto_items _lr_productions = [ ("S' -> main","S'",1,None,None,None), ('main -> factor combined_units','main',2,'p_main','cds.py',156), ('main -> combined_units','main',1,'p_main','cds.py',157), ('main -> DIMENSIONLESS','main',1,'p_main','cds.py',158), ('main -> OPEN_BRACKET combined_units CLOSE_BRACKET','main',3,'p_main','cds.py',159), ('main -> OPEN_BRACKET DIMENSIONLESS CLOSE_BRACKET','main',3,'p_main','cds.py',160), ('main -> factor','main',1,'p_main','cds.py',161), ('combined_units -> product_of_units','combined_units',1,'p_combined_units','cds.py',174), ('combined_units -> division_of_units','combined_units',1,'p_combined_units','cds.py',175), ('product_of_units -> unit_expression PRODUCT combined_units','product_of_units',3,'p_product_of_units','cds.py',181), ('product_of_units -> unit_expression','product_of_units',1,'p_product_of_units','cds.py',182), ('division_of_units -> DIVISION unit_expression','division_of_units',2,'p_division_of_units','cds.py',191), ('division_of_units -> unit_expression DIVISION combined_units','division_of_units',3,'p_division_of_units','cds.py',192), ('unit_expression -> unit_with_power','unit_expression',1,'p_unit_expression','cds.py',201), ('unit_expression -> OPEN_PAREN combined_units CLOSE_PAREN','unit_expression',3,'p_unit_expression','cds.py',202), ('factor -> signed_float X UINT signed_int','factor',4,'p_factor','cds.py',211), ('factor -> UINT X UINT signed_int','factor',4,'p_factor','cds.py',212), ('factor -> UINT signed_int','factor',2,'p_factor','cds.py',213), ('factor -> UINT','factor',1,'p_factor','cds.py',214), ('factor -> signed_float','factor',1,'p_factor','cds.py',215), ('unit_with_power -> UNIT numeric_power','unit_with_power',2,'p_unit_with_power','cds.py',232), ('unit_with_power -> UNIT','unit_with_power',1,'p_unit_with_power','cds.py',233), ('numeric_power -> sign UINT','numeric_power',2,'p_numeric_power','cds.py',242), ('sign -> SIGN','sign',1,'p_sign','cds.py',248), ('sign -> ','sign',0,'p_sign','cds.py',249), ('signed_int -> SIGN UINT','signed_int',2,'p_signed_int','cds.py',258), ('signed_float -> sign UINT','signed_float',2,'p_signed_float','cds.py',264), ('signed_float -> sign UFLOAT','signed_float',2,'p_signed_float','cds.py',265), ] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/format/console.py0000644000175100001710000000523500000000000020421 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """ Handles the "Console" unit format. """ from . import base, core, utils class Console(base.Base): """ Output-only format for to display pretty formatting at the console. For example:: >>> import astropy.units as u >>> print(u.Ry.decompose().to_string('console')) # doctest: +FLOAT_CMP m^2 kg 2.1798721*10^-18 ------ s^2 """ _times = "*" _line = "-" @classmethod def _get_unit_name(cls, unit): return unit.get_format_name('console') @classmethod def _format_superscript(cls, number): return f'^{number}' @classmethod def _format_unit_list(cls, units): out = [] for base, power in units: if power == 1: out.append(cls._get_unit_name(base)) else: out.append('{}{}'.format( cls._get_unit_name(base), cls._format_superscript( utils.format_power(power)))) return ' '.join(out) @classmethod def format_exponential_notation(cls, val): m, ex = utils.split_mantissa_exponent(val) parts = [] if m: parts.append(m) if ex: parts.append(f"10{cls._format_superscript(ex)}") return cls._times.join(parts) @classmethod def to_string(cls, unit): if isinstance(unit, core.CompositeUnit): if unit.scale == 1: s = '' else: s = cls.format_exponential_notation(unit.scale) if len(unit.bases): positives, negatives = utils.get_grouped_by_powers( unit.bases, unit.powers) if len(negatives): if len(positives): positives = cls._format_unit_list(positives) else: positives = '1' negatives = cls._format_unit_list(negatives) l = len(s) r = max(len(positives), len(negatives)) f = f"{{0:^{l}s}} {{1:^{r}s}}" lines = [ f.format('', positives), f.format(s, cls._line * r), f.format('', negatives) ] s = '\n'.join(lines) else: positives = cls._format_unit_list(positives) s += positives elif isinstance(unit, core.NamedUnit): s = cls._get_unit_name(unit) return s ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/format/fits.py0000644000175100001710000001215300000000000017721 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ Handles the "FITS" unit format. """ import numpy as np import copy import keyword import operator from . import core, generic, utils class Fits(generic.Generic): """ The FITS standard unit format. This supports the format defined in the Units section of the `FITS Standard `_. """ name = 'fits' @staticmethod def _generate_unit_names(): from astropy import units as u names = {} deprecated_names = set() # Note about deprecated units: before v2.0, several units were treated # as deprecated (G, barn, erg, Angstrom, angstrom). However, in the # FITS 3.0 standard, these units are explicitly listed in the allowed # units, but deprecated in the IAU Style Manual (McNally 1988). So # after discussion (https://github.com/astropy/astropy/issues/2933), # these units have been removed from the lists of deprecated units and # bases. bases = [ 'm', 'g', 's', 'rad', 'sr', 'K', 'A', 'mol', 'cd', 'Hz', 'J', 'W', 'V', 'N', 'Pa', 'C', 'Ohm', 'S', 'F', 'Wb', 'T', 'H', 'lm', 'lx', 'a', 'yr', 'eV', 'pc', 'Jy', 'mag', 'R', 'bit', 'byte', 'G', 'barn' ] deprecated_bases = [] prefixes = [ 'y', 'z', 'a', 'f', 'p', 'n', 'u', 'm', 'c', 'd', '', 'da', 'h', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'] special_cases = {'dbyte': u.Unit('dbyte', 0.1*u.byte)} for base in bases + deprecated_bases: for prefix in prefixes: key = prefix + base if keyword.iskeyword(key): continue elif key in special_cases: names[key] = special_cases[key] else: names[key] = getattr(u, key) for base in deprecated_bases: for prefix in prefixes: deprecated_names.add(prefix + base) simple_units = [ 'deg', 'arcmin', 'arcsec', 'mas', 'min', 'h', 'd', 'Ry', 'solMass', 'u', 'solLum', 'solRad', 'AU', 'lyr', 'count', 'ct', 'photon', 'ph', 'pixel', 'pix', 'D', 'Sun', 'chan', 'bin', 'voxel', 'adu', 'beam', 'erg', 'Angstrom', 'angstrom' ] deprecated_units = [] for unit in simple_units + deprecated_units: names[unit] = getattr(u, unit) for unit in deprecated_units: deprecated_names.add(unit) return names, deprecated_names, [] @classmethod def _validate_unit(cls, unit, detailed_exception=True): if unit not in cls._units: if detailed_exception: raise ValueError( "Unit '{}' not supported by the FITS standard. {}".format( unit, utils.did_you_mean_units( unit, cls._units, cls._deprecated_units, cls._to_decomposed_alternative))) else: raise ValueError() if unit in cls._deprecated_units: utils.unit_deprecation_warning( unit, cls._units[unit], 'FITS', cls._to_decomposed_alternative) @classmethod def _parse_unit(cls, unit, detailed_exception=True): cls._validate_unit(unit) return cls._units[unit] @classmethod def _get_unit_name(cls, unit): name = unit.get_format_name('fits') cls._validate_unit(name) return name @classmethod def to_string(cls, unit): # Remove units that aren't known to the format unit = utils.decompose_to_known_units(unit, cls._get_unit_name) parts = [] if isinstance(unit, core.CompositeUnit): base = np.log10(unit.scale) if base % 1.0 != 0.0: raise core.UnitScaleError( "The FITS unit format is not able to represent scales " "that are not powers of 10. Multiply your data by " "{:e}.".format(unit.scale)) elif unit.scale != 1.0: parts.append(f'10**{int(base)}') pairs = list(zip(unit.bases, unit.powers)) if len(pairs): pairs.sort(key=operator.itemgetter(1), reverse=True) parts.append(cls._format_unit_list(pairs)) s = ' '.join(parts) elif isinstance(unit, core.NamedUnit): s = cls._get_unit_name(unit) return s @classmethod def _to_decomposed_alternative(cls, unit): try: s = cls.to_string(unit) except core.UnitScaleError: scale = unit.scale unit = copy.copy(unit) unit._scale = 1.0 return f'{cls.to_string(unit)} (with data multiplied by {scale})' return s @classmethod def parse(cls, s, debug=False): result = super().parse(s, debug) if hasattr(result, 'function_unit'): raise ValueError("Function units are not yet supported for " "FITS units.") return result ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/format/generic.py0000644000175100001710000004771500000000000020404 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst # This module includes files automatically generated from ply (these end in # _lextab.py and _parsetab.py). To generate these files, remove them from this # folder, then build astropy and run the tests in-place: # # python setup.py build_ext --inplace # pytest astropy/units # # You can then commit the changes to the re-generated _lextab.py and # _parsetab.py files. """ Handles a "generic" string format for units """ import re import warnings from fractions import Fraction import unicodedata from . import core, utils from .base import Base from astropy.utils import classproperty, parsing from astropy.utils.misc import did_you_mean def _to_string(cls, unit): if isinstance(unit, core.CompositeUnit): parts = [] if cls._show_scale and unit.scale != 1: parts.append(f'{unit.scale:g}') if len(unit.bases): positives, negatives = utils.get_grouped_by_powers( unit.bases, unit.powers) if len(positives): parts.append(cls._format_unit_list(positives)) elif len(parts) == 0: parts.append('1') if len(negatives): parts.append('/') unit_list = cls._format_unit_list(negatives) if len(negatives) == 1: parts.append(f'{unit_list}') else: parts.append(f'({unit_list})') return ' '.join(parts) elif isinstance(unit, core.NamedUnit): return cls._get_unit_name(unit) class Generic(Base): """ A "generic" format. The syntax of the format is based directly on the FITS standard, but instead of only supporting the units that FITS knows about, it supports any unit available in the `astropy.units` namespace. """ _show_scale = True _tokens = ( 'COMMA', 'DOUBLE_STAR', 'STAR', 'PERIOD', 'SOLIDUS', 'CARET', 'OPEN_PAREN', 'CLOSE_PAREN', 'FUNCNAME', 'UNIT', 'SIGN', 'UINT', 'UFLOAT' ) @classproperty(lazy=True) def _all_units(cls): return cls._generate_unit_names() @classproperty(lazy=True) def _units(cls): return cls._all_units[0] @classproperty(lazy=True) def _deprecated_units(cls): return cls._all_units[1] @classproperty(lazy=True) def _functions(cls): return cls._all_units[2] @classproperty(lazy=True) def _parser(cls): return cls._make_parser() @classproperty(lazy=True) def _lexer(cls): return cls._make_lexer() @classmethod def _make_lexer(cls): tokens = cls._tokens t_COMMA = r'\,' t_STAR = r'\*' t_PERIOD = r'\.' t_SOLIDUS = r'/' t_DOUBLE_STAR = r'\*\*' t_CARET = r'\^' t_OPEN_PAREN = r'\(' t_CLOSE_PAREN = r'\)' # NOTE THE ORDERING OF THESE RULES IS IMPORTANT!! # Regular expression rules for simple tokens def t_UFLOAT(t): r'((\d+\.?\d*)|(\.\d+))([eE][+-]?\d+)?' if not re.search(r'[eE\.]', t.value): t.type = 'UINT' t.value = int(t.value) elif t.value.endswith('.'): t.type = 'UINT' t.value = int(t.value[:-1]) else: t.value = float(t.value) return t def t_UINT(t): r'\d+' t.value = int(t.value) return t def t_SIGN(t): r'[+-](?=\d)' t.value = int(t.value + '1') return t # This needs to be a function so we can force it to happen # before t_UNIT def t_FUNCNAME(t): r'((sqrt)|(ln)|(exp)|(log)|(mag)|(dB)|(dex))(?=\ *\()' return t def t_UNIT(t): "%|([YZEPTGMkhdcmu\N{MICRO SIGN}npfazy]?'((?!\\d)\\w)+')|((?!\\d)\\w)+" t.value = cls._get_unit(t) return t t_ignore = ' ' # Error handling rule def t_error(t): raise ValueError( f"Invalid character at col {t.lexpos}") return parsing.lex(lextab='generic_lextab', package='astropy/units', reflags=int(re.UNICODE)) @classmethod def _make_parser(cls): """ The grammar here is based on the description in the `FITS standard `_, Section 4.3, which is not terribly precise. The exact grammar is here is based on the YACC grammar in the `unity library `_. This same grammar is used by the `"fits"` and `"vounit"` formats, the only difference being the set of available unit strings. """ tokens = cls._tokens def p_main(p): ''' main : unit | structured_unit | structured_subunit ''' if isinstance(p[1], tuple): # Unpack possible StructuredUnit inside a tuple, ie., # ignore any set of very outer parentheses. p[0] = p[1][0] else: p[0] = p[1] def p_structured_subunit(p): ''' structured_subunit : OPEN_PAREN structured_unit CLOSE_PAREN ''' # We hide a structured unit enclosed by parentheses inside # a tuple, so that we can easily distinguish units like # "(au, au/day), yr" from "au, au/day, yr". p[0] = (p[2],) def p_structured_unit(p): ''' structured_unit : subunit COMMA | subunit COMMA subunit ''' from ..structured import StructuredUnit inputs = (p[1],) if len(p) == 3 else (p[1], p[3]) units = () for subunit in inputs: if isinstance(subunit, tuple): # Structured unit that should be its own entry in the # new StructuredUnit (was enclosed in parentheses). units += subunit elif isinstance(subunit, StructuredUnit): # Structured unit whose entries should be # individiually added to the new StructuredUnit. units += subunit.values() else: # Regular unit to be added to the StructuredUnit. units += (subunit,) p[0] = StructuredUnit(units) def p_subunit(p): ''' subunit : unit | structured_unit | structured_subunit ''' p[0] = p[1] def p_unit(p): ''' unit : product_of_units | factor product_of_units | factor product product_of_units | division_product_of_units | factor division_product_of_units | factor product division_product_of_units | inverse_unit | factor inverse_unit | factor product inverse_unit | factor ''' from astropy.units.core import Unit if len(p) == 2: p[0] = Unit(p[1]) elif len(p) == 3: p[0] = Unit(p[1] * p[2]) elif len(p) == 4: p[0] = Unit(p[1] * p[3]) def p_division_product_of_units(p): ''' division_product_of_units : division_product_of_units division product_of_units | product_of_units ''' from astropy.units.core import Unit if len(p) == 4: p[0] = Unit(p[1] / p[3]) else: p[0] = p[1] def p_inverse_unit(p): ''' inverse_unit : division unit_expression ''' p[0] = p[2] ** -1 def p_factor(p): ''' factor : factor_fits | factor_float | factor_int ''' p[0] = p[1] def p_factor_float(p): ''' factor_float : signed_float | signed_float UINT signed_int | signed_float UINT power numeric_power ''' if cls.name == 'fits': raise ValueError("Numeric factor not supported by FITS") if len(p) == 4: p[0] = p[1] * p[2] ** float(p[3]) elif len(p) == 5: p[0] = p[1] * p[2] ** float(p[4]) elif len(p) == 2: p[0] = p[1] def p_factor_int(p): ''' factor_int : UINT | UINT signed_int | UINT power numeric_power | UINT UINT signed_int | UINT UINT power numeric_power ''' if cls.name == 'fits': raise ValueError("Numeric factor not supported by FITS") if len(p) == 2: p[0] = p[1] elif len(p) == 3: p[0] = p[1] ** float(p[2]) elif len(p) == 4: if isinstance(p[2], int): p[0] = p[1] * p[2] ** float(p[3]) else: p[0] = p[1] ** float(p[3]) elif len(p) == 5: p[0] = p[1] * p[2] ** p[4] def p_factor_fits(p): ''' factor_fits : UINT power OPEN_PAREN signed_int CLOSE_PAREN | UINT power OPEN_PAREN UINT CLOSE_PAREN | UINT power signed_int | UINT power UINT | UINT SIGN UINT | UINT OPEN_PAREN signed_int CLOSE_PAREN ''' if p[1] != 10: if cls.name == 'fits': raise ValueError("Base must be 10") else: return if len(p) == 4: if p[2] in ('**', '^'): p[0] = 10 ** p[3] else: p[0] = 10 ** (p[2] * p[3]) elif len(p) == 5: p[0] = 10 ** p[3] elif len(p) == 6: p[0] = 10 ** p[4] def p_product_of_units(p): ''' product_of_units : unit_expression product product_of_units | unit_expression product_of_units | unit_expression ''' if len(p) == 2: p[0] = p[1] elif len(p) == 3: p[0] = p[1] * p[2] else: p[0] = p[1] * p[3] def p_unit_expression(p): ''' unit_expression : function | unit_with_power | OPEN_PAREN product_of_units CLOSE_PAREN ''' if len(p) == 2: p[0] = p[1] else: p[0] = p[2] def p_unit_with_power(p): ''' unit_with_power : UNIT power numeric_power | UNIT numeric_power | UNIT ''' if len(p) == 2: p[0] = p[1] elif len(p) == 3: p[0] = p[1] ** p[2] else: p[0] = p[1] ** p[3] def p_numeric_power(p): ''' numeric_power : sign UINT | OPEN_PAREN paren_expr CLOSE_PAREN ''' if len(p) == 3: p[0] = p[1] * p[2] elif len(p) == 4: p[0] = p[2] def p_paren_expr(p): ''' paren_expr : sign UINT | signed_float | frac ''' if len(p) == 3: p[0] = p[1] * p[2] else: p[0] = p[1] def p_frac(p): ''' frac : sign UINT division sign UINT ''' p[0] = Fraction(p[1] * p[2], p[4] * p[5]) def p_sign(p): ''' sign : SIGN | ''' if len(p) == 2: p[0] = p[1] else: p[0] = 1 def p_product(p): ''' product : STAR | PERIOD ''' pass def p_division(p): ''' division : SOLIDUS ''' pass def p_power(p): ''' power : DOUBLE_STAR | CARET ''' p[0] = p[1] def p_signed_int(p): ''' signed_int : SIGN UINT ''' p[0] = p[1] * p[2] def p_signed_float(p): ''' signed_float : sign UINT | sign UFLOAT ''' p[0] = p[1] * p[2] def p_function_name(p): ''' function_name : FUNCNAME ''' p[0] = p[1] def p_function(p): ''' function : function_name OPEN_PAREN main CLOSE_PAREN ''' if p[1] == 'sqrt': p[0] = p[3] ** 0.5 return elif p[1] in ('mag', 'dB', 'dex'): function_unit = cls._parse_unit(p[1]) # In Generic, this is callable, but that does not have to # be the case in subclasses (e.g., in VOUnit it is not). if callable(function_unit): p[0] = function_unit(p[3]) return raise ValueError(f"'{p[1]}' is not a recognized function") def p_error(p): raise ValueError() return parsing.yacc(tabmodule='generic_parsetab', package='astropy/units') @classmethod def _get_unit(cls, t): try: return cls._parse_unit(t.value) except ValueError as e: registry = core.get_current_unit_registry() if t.value in registry.aliases: return registry.aliases[t.value] raise ValueError( f"At col {t.lexpos}, {str(e)}") @classmethod def _parse_unit(cls, s, detailed_exception=True): registry = core.get_current_unit_registry().registry if s in cls._unit_symbols: s = cls._unit_symbols[s] elif not s.isascii(): if s[0] == '\N{MICRO SIGN}': s = 'u' + s[1:] if s[-1] in cls._prefixable_unit_symbols: s = s[:-1] + cls._prefixable_unit_symbols[s[-1]] elif len(s) > 1 and s[-1] in cls._unit_suffix_symbols: s = s[:-1] + cls._unit_suffix_symbols[s[-1]] elif s.endswith('R\N{INFINITY}'): s = s[:-2] + 'Ry' if s in registry: return registry[s] if detailed_exception: raise ValueError( f'{s} is not a valid unit. {did_you_mean(s, registry)}') else: raise ValueError() _unit_symbols = { '%': 'percent', '\N{PRIME}': 'arcmin', '\N{DOUBLE PRIME}': 'arcsec', '\N{MODIFIER LETTER SMALL H}': 'hourangle', 'e\N{SUPERSCRIPT MINUS}': 'electron', } _prefixable_unit_symbols = { '\N{GREEK CAPITAL LETTER OMEGA}': 'Ohm', '\N{LATIN CAPITAL LETTER A WITH RING ABOVE}': 'Angstrom', '\N{SCRIPT SMALL L}': 'l', } _unit_suffix_symbols = { '\N{CIRCLED DOT OPERATOR}': 'sun', '\N{SUN}': 'sun', '\N{CIRCLED PLUS}': 'earth', '\N{EARTH}': 'earth', '\N{JUPITER}': 'jupiter', '\N{LATIN SUBSCRIPT SMALL LETTER E}': '_e', '\N{LATIN SUBSCRIPT SMALL LETTER P}': '_p', } _translations = str.maketrans({ '\N{GREEK SMALL LETTER MU}': '\N{MICRO SIGN}', '\N{MINUS SIGN}': '-', }) """Character translations that should be applied before parsing a string. Note that this does explicitly *not* generally translate MICRO SIGN to u, since then a string like 'Âĩ' would be interpreted as unit mass. """ _superscripts = ( '\N{SUPERSCRIPT MINUS}' '\N{SUPERSCRIPT PLUS SIGN}' '\N{SUPERSCRIPT ZERO}' '\N{SUPERSCRIPT ONE}' '\N{SUPERSCRIPT TWO}' '\N{SUPERSCRIPT THREE}' '\N{SUPERSCRIPT FOUR}' '\N{SUPERSCRIPT FIVE}' '\N{SUPERSCRIPT SIX}' '\N{SUPERSCRIPT SEVEN}' '\N{SUPERSCRIPT EIGHT}' '\N{SUPERSCRIPT NINE}' ) _superscript_translations = str.maketrans(_superscripts, '-+0123456789') _regex_superscript = re.compile(f'[{_superscripts}]?[{_superscripts[2:]}]+') _regex_deg = re.compile('°([CF])?') @classmethod def _convert_superscript(cls, m): return f'({m.group().translate(cls._superscript_translations)})' @classmethod def _convert_deg(cls, m): if len(m.string) == 1: return 'deg' return m.string.replace('°', 'deg_') @classmethod def parse(cls, s, debug=False): if not isinstance(s, str): s = s.decode('ascii') elif not s.isascii(): # common normalization of unicode strings to avoid # having to deal with multiple representations of # the same character. This normalizes to "composed" form # and will e.g. convert OHM SIGN to GREEK CAPITAL LETTER OMEGA s = unicodedata.normalize('NFC', s) # Translate some basic unicode items that we'd like to support on # input but are not standard. s = s.translate(cls._translations) # TODO: might the below be better done in the parser/lexer? # Translate superscripts to parenthesized numbers; this ensures # that mixes of superscripts and regular numbers fail. s = cls._regex_superscript.sub(cls._convert_superscript, s) # Translate possible degrees. s = cls._regex_deg.sub(cls._convert_deg, s) result = cls._do_parse(s, debug=debug) # Check for excess solidi, but exclude fractional exponents (accepted) n_slashes = s.count('/') if n_slashes > 1 and (n_slashes - len(re.findall(r'\(\d+/\d+\)', s))) > 1: warnings.warn( "'{}' contains multiple slashes, which is " "discouraged by the FITS standard".format(s), core.UnitsWarning) return result @classmethod def _do_parse(cls, s, debug=False): try: # This is a short circuit for the case where the string # is just a single unit name return cls._parse_unit(s, detailed_exception=False) except ValueError as e: try: return cls._parser.parse(s, lexer=cls._lexer, debug=debug) except ValueError as e: if str(e): raise else: raise ValueError(f"Syntax error parsing unit '{s}'") @classmethod def _get_unit_name(cls, unit): return unit.get_format_name('generic') @classmethod def _format_unit_list(cls, units): out = [] units.sort(key=lambda x: cls._get_unit_name(x[0]).lower()) for base, power in units: if power == 1: out.append(cls._get_unit_name(base)) else: power = utils.format_power(power) if '/' in power or '.' in power: out.append(f'{cls._get_unit_name(base)}({power})') else: out.append(f'{cls._get_unit_name(base)}{power}') return ' '.join(out) @classmethod def to_string(cls, unit): return _to_string(cls, unit) class Unscaled(Generic): """ A format that doesn't display the scale part of the unit, other than that, it is identical to the `Generic` format. This is used in some error messages where the scale is irrelevant. """ _show_scale = False ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/format/generic_lextab.py0000644000175100001710000000307600000000000021733 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst # This file was automatically generated from ply. To re-generate this file, # remove it from this folder, then build astropy and run the tests in-place: # # python setup.py build_ext --inplace # pytest astropy/units # # You can then commit the changes to this file. # generic_lextab.py. This file automatically created by PLY (version 3.11). Don't edit! _tabversion = '3.10' _lextokens = set(('CARET', 'CLOSE_PAREN', 'COMMA', 'DOUBLE_STAR', 'FUNCNAME', 'OPEN_PAREN', 'PERIOD', 'SIGN', 'SOLIDUS', 'STAR', 'UFLOAT', 'UINT', 'UNIT')) _lexreflags = 32 _lexliterals = '' _lexstateinfo = {'INITIAL': 'inclusive'} _lexstatere = {'INITIAL': [("(?P((\\d+\\.?\\d*)|(\\.\\d+))([eE][+-]?\\d+)?)|(?P\\d+)|(?P[+-](?=\\d))|(?P((sqrt)|(ln)|(exp)|(log)|(mag)|(dB)|(dex))(?=\\ *\\())|(?P%|([YZEPTGMkhdcmuÂĩnpfazy]?'((?!\\d)\\w)+')|((?!\\d)\\w)+)|(?P\\*\\*)|(?P\\,)|(?P\\*)|(?P\\.)|(?P\\^)|(?P\\()|(?P\\))|(?P/)", [None, ('t_UFLOAT', 'UFLOAT'), None, None, None, None, ('t_UINT', 'UINT'), ('t_SIGN', 'SIGN'), ('t_FUNCNAME', 'FUNCNAME'), None, None, None, None, None, None, None, None, ('t_UNIT', 'UNIT'), None, None, None, (None, 'DOUBLE_STAR'), (None, 'COMMA'), (None, 'STAR'), (None, 'PERIOD'), (None, 'CARET'), (None, 'OPEN_PAREN'), (None, 'CLOSE_PAREN'), (None, 'SOLIDUS')])]} _lexstateignore = {'INITIAL': ' '} _lexstateerrorf = {'INITIAL': 't_error'} _lexstateeoff = {} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/format/generic_parsetab.py0000644000175100001710000003561200000000000022256 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst # This file was automatically generated from ply. To re-generate this file, # remove it from this folder, then build astropy and run the tests in-place: # # python setup.py build_ext --inplace # pytest astropy/units # # You can then commit the changes to this file. # generic_parsetab.py # This file is automatically generated. Do not edit. # pylint: disable=W,C,R _tabversion = '3.10' _lr_method = 'LALR' _lr_signature = 'CARET CLOSE_PAREN COMMA DOUBLE_STAR FUNCNAME OPEN_PAREN PERIOD SIGN SOLIDUS STAR UFLOAT UINT UNIT\n main : unit\n | structured_unit\n | structured_subunit\n \n structured_subunit : OPEN_PAREN structured_unit CLOSE_PAREN\n \n structured_unit : subunit COMMA\n | subunit COMMA subunit\n \n subunit : unit\n | structured_unit\n | structured_subunit\n \n unit : product_of_units\n | factor product_of_units\n | factor product product_of_units\n | division_product_of_units\n | factor division_product_of_units\n | factor product division_product_of_units\n | inverse_unit\n | factor inverse_unit\n | factor product inverse_unit\n | factor\n \n division_product_of_units : division_product_of_units division product_of_units\n | product_of_units\n \n inverse_unit : division unit_expression\n \n factor : factor_fits\n | factor_float\n | factor_int\n \n factor_float : signed_float\n | signed_float UINT signed_int\n | signed_float UINT power numeric_power\n \n factor_int : UINT\n | UINT signed_int\n | UINT power numeric_power\n | UINT UINT signed_int\n | UINT UINT power numeric_power\n \n factor_fits : UINT power OPEN_PAREN signed_int CLOSE_PAREN\n | UINT power OPEN_PAREN UINT CLOSE_PAREN\n | UINT power signed_int\n | UINT power UINT\n | UINT SIGN UINT\n | UINT OPEN_PAREN signed_int CLOSE_PAREN\n \n product_of_units : unit_expression product product_of_units\n | unit_expression product_of_units\n | unit_expression\n \n unit_expression : function\n | unit_with_power\n | OPEN_PAREN product_of_units CLOSE_PAREN\n \n unit_with_power : UNIT power numeric_power\n | UNIT numeric_power\n | UNIT\n \n numeric_power : sign UINT\n | OPEN_PAREN paren_expr CLOSE_PAREN\n \n paren_expr : sign UINT\n | signed_float\n | frac\n \n frac : sign UINT division sign UINT\n \n sign : SIGN\n |\n \n product : STAR\n | PERIOD\n \n division : SOLIDUS\n \n power : DOUBLE_STAR\n | CARET\n \n signed_int : SIGN UINT\n \n signed_float : sign UINT\n | sign UFLOAT\n \n function_name : FUNCNAME\n \n function : function_name OPEN_PAREN main CLOSE_PAREN\n ' _lr_action_items = {'OPEN_PAREN':([0,6,10,11,12,13,14,15,16,17,18,20,21,22,23,25,27,30,31,32,33,34,35,40,44,46,48,49,51,52,53,56,57,66,68,69,71,73,74,77,78,79,81,82,87,88,91,92,93,94,96,97,],[10,32,35,32,-23,-24,-25,32,-43,-44,45,-26,-59,51,55,-65,32,-57,-58,32,32,10,35,32,72,-30,-60,-61,10,55,-47,-63,-64,-45,-32,55,-37,-36,-31,-38,-27,55,-46,-49,-33,-62,-39,-28,-66,-50,-35,-34,]),'UINT':([0,10,18,19,20,21,23,24,34,35,44,47,48,49,51,52,54,55,56,57,69,70,72,75,79,84,98,99,],[18,18,43,-55,50,-59,-56,56,18,18,71,77,-60,-61,18,-56,82,-56,-63,-64,-56,88,89,88,-56,95,-56,100,]),'SOLIDUS':([0,5,6,7,10,11,12,13,14,16,17,18,20,23,26,27,28,30,31,34,35,37,41,46,51,53,56,57,58,59,62,66,67,68,71,73,74,77,78,81,82,87,88,91,92,93,94,95,96,97,],[21,-21,21,21,21,-42,-23,-24,-25,-43,-44,-29,-26,-48,-21,21,21,-57,-58,21,21,-21,-41,-30,21,-47,-63,-64,-21,21,-20,-45,-40,-32,-37,-36,-31,-38,-27,-46,-49,-33,-62,-39,-28,-66,-50,21,-35,-34,]),'UNIT':([0,6,10,11,12,13,14,15,16,17,18,20,21,23,27,30,31,32,33,34,35,40,46,51,53,56,57,66,68,71,73,74,77,78,81,82,87,88,91,92,93,94,96,97,],[23,23,23,23,-23,-24,-25,23,-43,-44,-29,-26,-59,-48,23,-57,-58,23,23,23,23,23,-30,23,-47,-63,-64,-45,-32,-37,-36,-31,-38,-27,-46,-49,-33,-62,-39,-28,-66,-50,-35,-34,]),'FUNCNAME':([0,6,10,11,12,13,14,15,16,17,18,20,21,23,27,30,31,32,33,34,35,40,46,51,53,56,57,66,68,71,73,74,77,78,81,82,87,88,91,92,93,94,96,97,],[25,25,25,25,-23,-24,-25,25,-43,-44,-29,-26,-59,-48,25,-57,-58,25,25,25,25,25,-30,25,-47,-63,-64,-45,-32,-37,-36,-31,-38,-27,-46,-49,-33,-62,-39,-28,-66,-50,-35,-34,]),'SIGN':([0,10,18,21,23,34,35,43,44,45,48,49,50,51,52,55,69,72,79,98,],[19,19,47,-59,19,19,19,70,75,70,-60,-61,70,19,19,19,19,75,19,19,]),'UFLOAT':([0,10,19,24,34,35,51,55,72,75,84,],[-56,-56,-55,57,-56,-56,-56,-56,-56,-55,57,]),'$end':([1,2,3,4,5,6,7,8,11,12,13,14,16,17,18,20,23,26,28,29,34,38,39,41,42,46,53,56,57,58,59,60,62,63,64,65,66,67,68,71,73,74,77,78,81,82,87,88,91,92,93,94,96,97,],[0,-1,-2,-3,-10,-19,-13,-16,-42,-23,-24,-25,-43,-44,-29,-26,-48,-11,-14,-17,-5,-7,-9,-41,-22,-30,-47,-63,-64,-12,-15,-18,-20,-6,-8,-4,-45,-40,-32,-37,-36,-31,-38,-27,-46,-49,-33,-62,-39,-28,-66,-50,-35,-34,]),'CLOSE_PAREN':([2,3,4,5,6,7,8,11,12,13,14,16,17,18,20,23,26,28,29,34,36,37,38,39,41,42,46,53,56,57,58,59,60,61,62,63,64,65,66,67,68,71,73,74,76,77,78,80,81,82,83,85,86,87,88,89,90,91,92,93,94,95,96,97,100,],[-1,-2,-3,-10,-19,-13,-16,-42,-23,-24,-25,-43,-44,-29,-26,-48,-11,-14,-17,-5,65,66,-7,-9,-41,-22,-30,-47,-63,-64,-12,-15,-18,66,-20,-6,-8,-4,-45,-40,-32,-37,-36,-31,91,-38,-27,93,-46,-49,94,-52,-53,-33,-62,96,97,-39,-28,-66,-50,-51,-35,-34,-54,]),'COMMA':([2,3,4,5,6,7,8,9,11,12,13,14,16,17,18,20,23,26,28,29,34,36,37,38,39,41,42,46,53,56,57,58,59,60,62,63,64,65,66,67,68,71,73,74,77,78,81,82,87,88,91,92,93,94,96,97,],[-7,-8,-9,-10,-19,-13,-16,34,-42,-23,-24,-25,-43,-44,-29,-26,-48,-11,-14,-17,-5,-8,-10,-7,-9,-41,-22,-30,-47,-63,-64,-12,-15,-18,-20,34,-8,-4,-45,-40,-32,-37,-36,-31,-38,-27,-46,-49,-33,-62,-39,-28,-66,-50,-35,-34,]),'STAR':([6,11,12,13,14,16,17,18,20,23,46,53,56,57,66,68,71,73,74,77,78,81,82,87,88,91,92,93,94,96,97,],[30,30,-23,-24,-25,-43,-44,-29,-26,-48,-30,-47,-63,-64,-45,-32,-37,-36,-31,-38,-27,-46,-49,-33,-62,-39,-28,-66,-50,-35,-34,]),'PERIOD':([6,11,12,13,14,16,17,18,20,23,46,53,56,57,66,68,71,73,74,77,78,81,82,87,88,91,92,93,94,96,97,],[31,31,-23,-24,-25,-43,-44,-29,-26,-48,-30,-47,-63,-64,-45,-32,-37,-36,-31,-38,-27,-46,-49,-33,-62,-39,-28,-66,-50,-35,-34,]),'DOUBLE_STAR':([18,23,43,50,],[48,48,48,48,]),'CARET':([18,23,43,50,],[49,49,49,49,]),} _lr_action = {} for _k, _v in _lr_action_items.items(): for _x,_y in zip(_v[0],_v[1]): if not _x in _lr_action: _lr_action[_x] = {} _lr_action[_x][_k] = _y del _lr_action_items _lr_goto_items = {'main':([0,51,],[1,80,]),'unit':([0,10,34,35,51,],[2,38,38,38,2,]),'structured_unit':([0,10,34,35,51,],[3,36,64,36,3,]),'structured_subunit':([0,10,34,35,51,],[4,39,39,39,4,]),'product_of_units':([0,6,10,11,27,32,33,34,35,40,51,],[5,26,37,41,58,61,62,5,37,67,5,]),'factor':([0,10,34,35,51,],[6,6,6,6,6,]),'division_product_of_units':([0,6,10,27,34,35,51,],[7,28,7,59,7,7,7,]),'inverse_unit':([0,6,10,27,34,35,51,],[8,29,8,60,8,8,8,]),'subunit':([0,10,34,35,51,],[9,9,63,9,9,]),'unit_expression':([0,6,10,11,15,27,32,33,34,35,40,51,],[11,11,11,11,42,11,11,11,11,11,11,11,]),'factor_fits':([0,10,34,35,51,],[12,12,12,12,12,]),'factor_float':([0,10,34,35,51,],[13,13,13,13,13,]),'factor_int':([0,10,34,35,51,],[14,14,14,14,14,]),'division':([0,6,7,10,27,28,34,35,51,59,95,],[15,15,33,15,15,33,15,15,15,33,98,]),'function':([0,6,10,11,15,27,32,33,34,35,40,51,],[16,16,16,16,16,16,16,16,16,16,16,16,]),'unit_with_power':([0,6,10,11,15,27,32,33,34,35,40,51,],[17,17,17,17,17,17,17,17,17,17,17,17,]),'signed_float':([0,10,34,35,51,55,72,],[20,20,20,20,20,85,85,]),'function_name':([0,6,10,11,15,27,32,33,34,35,40,51,],[22,22,22,22,22,22,22,22,22,22,22,22,]),'sign':([0,10,23,34,35,44,51,52,55,69,72,79,98,],[24,24,54,24,24,54,24,54,84,54,84,54,99,]),'product':([6,11,],[27,40,]),'power':([18,23,43,50,],[44,52,69,79,]),'signed_int':([18,43,44,45,50,72,],[46,68,73,76,78,90,]),'numeric_power':([23,44,52,69,79,],[53,74,81,87,92,]),'paren_expr':([55,72,],[83,83,]),'frac':([55,72,],[86,86,]),} _lr_goto = {} for _k, _v in _lr_goto_items.items(): for _x, _y in zip(_v[0], _v[1]): if not _x in _lr_goto: _lr_goto[_x] = {} _lr_goto[_x][_k] = _y del _lr_goto_items _lr_productions = [ ("S' -> main","S'",1,None,None,None), ('main -> unit','main',1,'p_main','generic.py',196), ('main -> structured_unit','main',1,'p_main','generic.py',197), ('main -> structured_subunit','main',1,'p_main','generic.py',198), ('structured_subunit -> OPEN_PAREN structured_unit CLOSE_PAREN','structured_subunit',3,'p_structured_subunit','generic.py',209), ('structured_unit -> subunit COMMA','structured_unit',2,'p_structured_unit','generic.py',218), ('structured_unit -> subunit COMMA subunit','structured_unit',3,'p_structured_unit','generic.py',219), ('subunit -> unit','subunit',1,'p_subunit','generic.py',241), ('subunit -> structured_unit','subunit',1,'p_subunit','generic.py',242), ('subunit -> structured_subunit','subunit',1,'p_subunit','generic.py',243), ('unit -> product_of_units','unit',1,'p_unit','generic.py',249), ('unit -> factor product_of_units','unit',2,'p_unit','generic.py',250), ('unit -> factor product product_of_units','unit',3,'p_unit','generic.py',251), ('unit -> division_product_of_units','unit',1,'p_unit','generic.py',252), ('unit -> factor division_product_of_units','unit',2,'p_unit','generic.py',253), ('unit -> factor product division_product_of_units','unit',3,'p_unit','generic.py',254), ('unit -> inverse_unit','unit',1,'p_unit','generic.py',255), ('unit -> factor inverse_unit','unit',2,'p_unit','generic.py',256), ('unit -> factor product inverse_unit','unit',3,'p_unit','generic.py',257), ('unit -> factor','unit',1,'p_unit','generic.py',258), ('division_product_of_units -> division_product_of_units division product_of_units','division_product_of_units',3,'p_division_product_of_units','generic.py',270), ('division_product_of_units -> product_of_units','division_product_of_units',1,'p_division_product_of_units','generic.py',271), ('inverse_unit -> division unit_expression','inverse_unit',2,'p_inverse_unit','generic.py',281), ('factor -> factor_fits','factor',1,'p_factor','generic.py',287), ('factor -> factor_float','factor',1,'p_factor','generic.py',288), ('factor -> factor_int','factor',1,'p_factor','generic.py',289), ('factor_float -> signed_float','factor_float',1,'p_factor_float','generic.py',295), ('factor_float -> signed_float UINT signed_int','factor_float',3,'p_factor_float','generic.py',296), ('factor_float -> signed_float UINT power numeric_power','factor_float',4,'p_factor_float','generic.py',297), ('factor_int -> UINT','factor_int',1,'p_factor_int','generic.py',310), ('factor_int -> UINT signed_int','factor_int',2,'p_factor_int','generic.py',311), ('factor_int -> UINT power numeric_power','factor_int',3,'p_factor_int','generic.py',312), ('factor_int -> UINT UINT signed_int','factor_int',3,'p_factor_int','generic.py',313), ('factor_int -> UINT UINT power numeric_power','factor_int',4,'p_factor_int','generic.py',314), ('factor_fits -> UINT power OPEN_PAREN signed_int CLOSE_PAREN','factor_fits',5,'p_factor_fits','generic.py',332), ('factor_fits -> UINT power OPEN_PAREN UINT CLOSE_PAREN','factor_fits',5,'p_factor_fits','generic.py',333), ('factor_fits -> UINT power signed_int','factor_fits',3,'p_factor_fits','generic.py',334), ('factor_fits -> UINT power UINT','factor_fits',3,'p_factor_fits','generic.py',335), ('factor_fits -> UINT SIGN UINT','factor_fits',3,'p_factor_fits','generic.py',336), ('factor_fits -> UINT OPEN_PAREN signed_int CLOSE_PAREN','factor_fits',4,'p_factor_fits','generic.py',337), ('product_of_units -> unit_expression product product_of_units','product_of_units',3,'p_product_of_units','generic.py',356), ('product_of_units -> unit_expression product_of_units','product_of_units',2,'p_product_of_units','generic.py',357), ('product_of_units -> unit_expression','product_of_units',1,'p_product_of_units','generic.py',358), ('unit_expression -> function','unit_expression',1,'p_unit_expression','generic.py',369), ('unit_expression -> unit_with_power','unit_expression',1,'p_unit_expression','generic.py',370), ('unit_expression -> OPEN_PAREN product_of_units CLOSE_PAREN','unit_expression',3,'p_unit_expression','generic.py',371), ('unit_with_power -> UNIT power numeric_power','unit_with_power',3,'p_unit_with_power','generic.py',380), ('unit_with_power -> UNIT numeric_power','unit_with_power',2,'p_unit_with_power','generic.py',381), ('unit_with_power -> UNIT','unit_with_power',1,'p_unit_with_power','generic.py',382), ('numeric_power -> sign UINT','numeric_power',2,'p_numeric_power','generic.py',393), ('numeric_power -> OPEN_PAREN paren_expr CLOSE_PAREN','numeric_power',3,'p_numeric_power','generic.py',394), ('paren_expr -> sign UINT','paren_expr',2,'p_paren_expr','generic.py',403), ('paren_expr -> signed_float','paren_expr',1,'p_paren_expr','generic.py',404), ('paren_expr -> frac','paren_expr',1,'p_paren_expr','generic.py',405), ('frac -> sign UINT division sign UINT','frac',5,'p_frac','generic.py',414), ('sign -> SIGN','sign',1,'p_sign','generic.py',420), ('sign -> ','sign',0,'p_sign','generic.py',421), ('product -> STAR','product',1,'p_product','generic.py',430), ('product -> PERIOD','product',1,'p_product','generic.py',431), ('division -> SOLIDUS','division',1,'p_division','generic.py',437), ('power -> DOUBLE_STAR','power',1,'p_power','generic.py',443), ('power -> CARET','power',1,'p_power','generic.py',444), ('signed_int -> SIGN UINT','signed_int',2,'p_signed_int','generic.py',450), ('signed_float -> sign UINT','signed_float',2,'p_signed_float','generic.py',456), ('signed_float -> sign UFLOAT','signed_float',2,'p_signed_float','generic.py',457), ('function_name -> FUNCNAME','function_name',1,'p_function_name','generic.py',463), ('function -> function_name OPEN_PAREN main CLOSE_PAREN','function',4,'p_function','generic.py',469), ] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/format/latex.py0000644000175100001710000001037100000000000020071 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ Handles the "LaTeX" unit format. """ import re import numpy as np from . import base, core, utils class Latex(base.Base): """ Output LaTeX to display the unit based on IAU style guidelines. Attempts to follow the `IAU Style Manual `_. """ @classmethod def _latex_escape(cls, name): # This doesn't escape arbitrary LaTeX strings, but it should # be good enough for unit names which are required to be alpha # + "_" anyway. return name.replace('_', r'\_') @classmethod def _get_unit_name(cls, unit): name = unit.get_format_name('latex') if name == unit.name: return cls._latex_escape(name) return name @classmethod def _format_unit_list(cls, units): out = [] for base, power in units: base_latex = cls._get_unit_name(base) if power == 1: out.append(base_latex) else: # If the LaTeX representation of the base unit already ends with # a superscript, we need to spell out the unit to avoid double # superscripts. For example, the logic below ensures that # `u.deg**2` returns `deg^{2}` instead of `{}^{\circ}^{2}`. if re.match(r".*\^{[^}]*}$", base_latex): # ends w/ superscript? base_latex = base.short_names[0] out.append(f'{base_latex}^{{{utils.format_power(power)}}}') return r'\,'.join(out) @classmethod def _format_bases(cls, unit): positives, negatives = utils.get_grouped_by_powers( unit.bases, unit.powers) if len(negatives): if len(positives): positives = cls._format_unit_list(positives) else: positives = '1' negatives = cls._format_unit_list(negatives) s = fr'\frac{{{positives}}}{{{negatives}}}' else: positives = cls._format_unit_list(positives) s = positives return s @classmethod def to_string(cls, unit): latex_name = None if hasattr(unit, '_format'): latex_name = unit._format.get('latex') if latex_name is not None: s = latex_name elif isinstance(unit, core.CompositeUnit): if unit.scale == 1: s = '' else: s = cls.format_exponential_notation(unit.scale) + r'\,' if len(unit.bases): s += cls._format_bases(unit) elif isinstance(unit, core.NamedUnit): s = cls._latex_escape(unit.name) return fr'$\mathrm{{{s}}}$' @classmethod def format_exponential_notation(cls, val, format_spec=".8g"): """ Formats a value in exponential notation for LaTeX. Parameters ---------- val : number The value to be formatted format_spec : str, optional Format used to split up mantissa and exponent Returns ------- latex_string : str The value in exponential notation in a format suitable for LaTeX. """ if np.isfinite(val): m, ex = utils.split_mantissa_exponent(val, format_spec) parts = [] if m: parts.append(m) if ex: parts.append(f"10^{{{ex}}}") return r" \times ".join(parts) else: if np.isnan(val): return r'{\rm NaN}' elif val > 0: # positive infinity return r'\infty' else: # negative infinity return r'-\infty' class LatexInline(Latex): """ Output LaTeX to display the unit based on IAU style guidelines with negative powers. Attempts to follow the `IAU Style Manual `_ and the `ApJ and AJ style guide `_. """ name = 'latex_inline' @classmethod def _format_bases(cls, unit): return cls._format_unit_list(zip(unit.bases, unit.powers)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/format/ogip.py0000644000175100001710000003343500000000000017720 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICNSE.rst # This module includes files automatically generated from ply (these end in # _lextab.py and _parsetab.py). To generate these files, remove them from this # folder, then build astropy and run the tests in-place: # # python setup.py build_ext --inplace # pytest astropy/units # # You can then commit the changes to the re-generated _lextab.py and # _parsetab.py files. """ Handles units in `Office of Guest Investigator Programs (OGIP) FITS files `__. """ import keyword import math import os import copy import warnings from fractions import Fraction from . import core, generic, utils from astropy.utils import parsing class OGIP(generic.Generic): """ Support the units in `Office of Guest Investigator Programs (OGIP) FITS files `__. """ _tokens = ( 'DIVISION', 'OPEN_PAREN', 'CLOSE_PAREN', 'WHITESPACE', 'STARSTAR', 'STAR', 'SIGN', 'UFLOAT', 'LIT10', 'UINT', 'UNKNOWN', 'UNIT' ) @staticmethod def _generate_unit_names(): from astropy import units as u names = {} deprecated_names = set() bases = [ 'A', 'C', 'cd', 'eV', 'F', 'g', 'H', 'Hz', 'J', 'Jy', 'K', 'lm', 'lx', 'm', 'mol', 'N', 'ohm', 'Pa', 'pc', 'rad', 's', 'S', 'sr', 'T', 'V', 'W', 'Wb' ] deprecated_bases = [] prefixes = [ 'y', 'z', 'a', 'f', 'p', 'n', 'u', 'm', 'c', 'd', '', 'da', 'h', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' ] for base in bases + deprecated_bases: for prefix in prefixes: key = prefix + base if keyword.iskeyword(key): continue names[key] = getattr(u, key) for base in deprecated_bases: for prefix in prefixes: deprecated_names.add(prefix + base) simple_units = [ 'angstrom', 'arcmin', 'arcsec', 'AU', 'barn', 'bin', 'byte', 'chan', 'count', 'day', 'deg', 'erg', 'G', 'h', 'lyr', 'mag', 'min', 'photon', 'pixel', 'voxel', 'yr' ] for unit in simple_units: names[unit] = getattr(u, unit) # Create a separate, disconnected unit for the special case of # Crab and mCrab, since OGIP doesn't define their quantities. Crab = u.def_unit(['Crab'], prefixes=False, doc='Crab (X-ray flux)') mCrab = u.Unit(10 ** -3 * Crab) names['Crab'] = Crab names['mCrab'] = mCrab deprecated_units = ['Crab', 'mCrab'] for unit in deprecated_units: deprecated_names.add(unit) # Define the function names, so we can parse them, even though # we can't use any of them (other than sqrt) meaningfully for # now. functions = [ 'log', 'ln', 'exp', 'sqrt', 'sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'sinh', 'cosh', 'tanh' ] for name in functions: names[name] = name return names, deprecated_names, functions @classmethod def _make_lexer(cls): tokens = cls._tokens t_DIVISION = r'/' t_OPEN_PAREN = r'\(' t_CLOSE_PAREN = r'\)' t_WHITESPACE = '[ \t]+' t_STARSTAR = r'\*\*' t_STAR = r'\*' # NOTE THE ORDERING OF THESE RULES IS IMPORTANT!! # Regular expression rules for simple tokens def t_UFLOAT(t): r'(((\d+\.?\d*)|(\.\d+))([eE][+-]?\d+))|(((\d+\.\d*)|(\.\d+))([eE][+-]?\d+)?)' t.value = float(t.value) return t def t_UINT(t): r'\d+' t.value = int(t.value) return t def t_SIGN(t): r'[+-](?=\d)' t.value = float(t.value + '1') return t def t_X(t): # multiplication for factor in front of unit r'[x×]' return t def t_LIT10(t): r'10' return 10 def t_UNKNOWN(t): r'[Uu][Nn][Kk][Nn][Oo][Ww][Nn]' return None def t_UNIT(t): r'[a-zA-Z][a-zA-Z_]*' t.value = cls._get_unit(t) return t # Don't ignore whitespace t_ignore = '' # Error handling rule def t_error(t): raise ValueError( f"Invalid character at col {t.lexpos}") return parsing.lex(lextab='ogip_lextab', package='astropy/units') @classmethod def _make_parser(cls): """ The grammar here is based on the description in the `Specification of Physical Units within OGIP FITS files `__, which is not terribly precise. The exact grammar is here is based on the YACC grammar in the `unity library `_. """ tokens = cls._tokens def p_main(p): ''' main : UNKNOWN | complete_expression | scale_factor complete_expression | scale_factor WHITESPACE complete_expression ''' if len(p) == 4: p[0] = p[1] * p[3] elif len(p) == 3: p[0] = p[1] * p[2] else: p[0] = p[1] def p_complete_expression(p): ''' complete_expression : product_of_units ''' p[0] = p[1] def p_product_of_units(p): ''' product_of_units : unit_expression | division unit_expression | product_of_units product unit_expression | product_of_units division unit_expression ''' if len(p) == 4: if p[2] == 'DIVISION': p[0] = p[1] / p[3] else: p[0] = p[1] * p[3] elif len(p) == 3: p[0] = p[2] ** -1 else: p[0] = p[1] def p_unit_expression(p): ''' unit_expression : unit | UNIT OPEN_PAREN complete_expression CLOSE_PAREN | OPEN_PAREN complete_expression CLOSE_PAREN | UNIT OPEN_PAREN complete_expression CLOSE_PAREN power numeric_power | OPEN_PAREN complete_expression CLOSE_PAREN power numeric_power ''' # If we run p[1] in cls._functions, it will try and parse each # item in the list into a unit, which is slow. Since we know that # all the items in the list are strings, we can simply convert # p[1] to a string instead. p1_str = str(p[1]) if p1_str in cls._functions and p1_str != 'sqrt': raise ValueError( "The function '{}' is valid in OGIP, but not understood " "by astropy.units.".format( p[1])) if len(p) == 7: if p1_str == 'sqrt': p[0] = p[1] * p[3] ** (0.5 * p[6]) else: p[0] = p[1] * p[3] ** p[6] elif len(p) == 6: p[0] = p[2] ** p[5] elif len(p) == 5: if p1_str == 'sqrt': p[0] = p[3] ** 0.5 else: p[0] = p[1] * p[3] elif len(p) == 4: p[0] = p[2] else: p[0] = p[1] def p_scale_factor(p): ''' scale_factor : LIT10 power numeric_power | LIT10 | signed_float | signed_float power numeric_power | signed_int power numeric_power ''' if len(p) == 4: p[0] = 10 ** p[3] else: p[0] = p[1] # Can't use np.log10 here, because p[0] may be a Python long. if math.log10(p[0]) % 1.0 != 0.0: from astropy.units.core import UnitsWarning warnings.warn( "'{}' scale should be a power of 10 in " "OGIP format".format(p[0]), UnitsWarning) def p_division(p): ''' division : DIVISION | WHITESPACE DIVISION | WHITESPACE DIVISION WHITESPACE | DIVISION WHITESPACE ''' p[0] = 'DIVISION' def p_product(p): ''' product : WHITESPACE | STAR | WHITESPACE STAR | WHITESPACE STAR WHITESPACE | STAR WHITESPACE ''' p[0] = 'PRODUCT' def p_power(p): ''' power : STARSTAR ''' p[0] = 'POWER' def p_unit(p): ''' unit : UNIT | UNIT power numeric_power ''' if len(p) == 4: p[0] = p[1] ** p[3] else: p[0] = p[1] def p_numeric_power(p): ''' numeric_power : UINT | signed_float | OPEN_PAREN signed_int CLOSE_PAREN | OPEN_PAREN signed_float CLOSE_PAREN | OPEN_PAREN signed_float division UINT CLOSE_PAREN ''' if len(p) == 6: p[0] = Fraction(int(p[2]), int(p[4])) elif len(p) == 4: p[0] = p[2] else: p[0] = p[1] def p_sign(p): ''' sign : SIGN | ''' if len(p) == 2: p[0] = p[1] else: p[0] = 1.0 def p_signed_int(p): ''' signed_int : SIGN UINT ''' p[0] = p[1] * p[2] def p_signed_float(p): ''' signed_float : sign UINT | sign UFLOAT ''' p[0] = p[1] * p[2] def p_error(p): raise ValueError() return parsing.yacc(tabmodule='ogip_parsetab', package='astropy/units') @classmethod def _validate_unit(cls, unit, detailed_exception=True): if unit not in cls._units: if detailed_exception: raise ValueError( "Unit '{}' not supported by the OGIP " "standard. {}".format( unit, utils.did_you_mean_units( unit, cls._units, cls._deprecated_units, cls._to_decomposed_alternative))) else: raise ValueError() if unit in cls._deprecated_units: utils.unit_deprecation_warning( unit, cls._units[unit], 'OGIP', cls._to_decomposed_alternative) @classmethod def _parse_unit(cls, unit, detailed_exception=True): cls._validate_unit(unit, detailed_exception=detailed_exception) return cls._units[unit] @classmethod def parse(cls, s, debug=False): s = s.strip() try: # This is a short circuit for the case where the string is # just a single unit name return cls._parse_unit(s, detailed_exception=False) except ValueError: try: return core.Unit( cls._parser.parse(s, lexer=cls._lexer, debug=debug)) except ValueError as e: if str(e): raise else: raise ValueError( f"Syntax error parsing unit '{s}'") @classmethod def _get_unit_name(cls, unit): name = unit.get_format_name('ogip') cls._validate_unit(name) return name @classmethod def _format_unit_list(cls, units): out = [] units.sort(key=lambda x: cls._get_unit_name(x[0]).lower()) for base, power in units: if power == 1: out.append(cls._get_unit_name(base)) else: power = utils.format_power(power) if '/' in power: out.append(f'{cls._get_unit_name(base)}**({power})') else: out.append(f'{cls._get_unit_name(base)}**{power}') return ' '.join(out) @classmethod def to_string(cls, unit): # Remove units that aren't known to the format unit = utils.decompose_to_known_units(unit, cls._get_unit_name) if isinstance(unit, core.CompositeUnit): # Can't use np.log10 here, because p[0] may be a Python long. if math.log10(unit.scale) % 1.0 != 0.0: warnings.warn( f"'{unit.scale}' scale should be a power of 10 in OGIP format", core.UnitsWarning) return generic._to_string(cls, unit) @classmethod def _to_decomposed_alternative(cls, unit): # Remove units that aren't known to the format unit = utils.decompose_to_known_units(unit, cls._get_unit_name) if isinstance(unit, core.CompositeUnit): # Can't use np.log10 here, because p[0] may be a Python long. if math.log10(unit.scale) % 1.0 != 0.0: scale = unit.scale unit = copy.copy(unit) unit._scale = 1.0 return '{} (with data multiplied by {})'.format( generic._to_string(cls, unit), scale) return generic._to_string(unit) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/format/ogip_lextab.py0000644000175100001710000000300400000000000021244 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst # This file was automatically generated from ply. To re-generate this file, # remove it from this folder, then build astropy and run the tests in-place: # # python setup.py build_ext --inplace # pytest astropy/units # # You can then commit the changes to this file. # ogip_lextab.py. This file automatically created by PLY (version 3.11). Don't edit! _tabversion = '3.10' _lextokens = set(('CLOSE_PAREN', 'DIVISION', 'LIT10', 'OPEN_PAREN', 'SIGN', 'STAR', 'STARSTAR', 'UFLOAT', 'UINT', 'UNIT', 'UNKNOWN', 'WHITESPACE')) _lexreflags = 64 _lexliterals = '' _lexstateinfo = {'INITIAL': 'inclusive'} _lexstatere = {'INITIAL': [('(?P(((\\d+\\.?\\d*)|(\\.\\d+))([eE][+-]?\\d+))|(((\\d+\\.\\d*)|(\\.\\d+))([eE][+-]?\\d+)?))|(?P\\d+)|(?P[+-](?=\\d))|(?P[x×])|(?P10)|(?P[Uu][Nn][Kk][Nn][Oo][Ww][Nn])|(?P[a-zA-Z][a-zA-Z_]*)|(?P[ \t]+)|(?P\\*\\*)|(?P\\()|(?P\\))|(?P\\*)|(?P/)', [None, ('t_UFLOAT', 'UFLOAT'), None, None, None, None, None, None, None, None, None, None, ('t_UINT', 'UINT'), ('t_SIGN', 'SIGN'), ('t_X', 'X'), ('t_LIT10', 'LIT10'), ('t_UNKNOWN', 'UNKNOWN'), ('t_UNIT', 'UNIT'), (None, 'WHITESPACE'), (None, 'STARSTAR'), (None, 'OPEN_PAREN'), (None, 'CLOSE_PAREN'), (None, 'STAR'), (None, 'DIVISION')])]} _lexstateignore = {'INITIAL': ''} _lexstateerrorf = {'INITIAL': 't_error'} _lexstateeoff = {} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/format/ogip_parsetab.py0000644000175100001710000002240100000000000021570 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst # This file was automatically generated from ply. To re-generate this file, # remove it from this folder, then build astropy and run the tests in-place: # # python setup.py build_ext --inplace # pytest astropy/units # # You can then commit the changes to this file. # ogip_parsetab.py # This file is automatically generated. Do not edit. # pylint: disable=W,C,R _tabversion = '3.10' _lr_method = 'LALR' _lr_signature = 'CLOSE_PAREN DIVISION LIT10 OPEN_PAREN SIGN STAR STARSTAR UFLOAT UINT UNIT UNKNOWN WHITESPACE\n main : UNKNOWN\n | complete_expression\n | scale_factor complete_expression\n | scale_factor WHITESPACE complete_expression\n \n complete_expression : product_of_units\n \n product_of_units : unit_expression\n | division unit_expression\n | product_of_units product unit_expression\n | product_of_units division unit_expression\n \n unit_expression : unit\n | UNIT OPEN_PAREN complete_expression CLOSE_PAREN\n | OPEN_PAREN complete_expression CLOSE_PAREN\n | UNIT OPEN_PAREN complete_expression CLOSE_PAREN power numeric_power\n | OPEN_PAREN complete_expression CLOSE_PAREN power numeric_power\n \n scale_factor : LIT10 power numeric_power\n | LIT10\n | signed_float\n | signed_float power numeric_power\n | signed_int power numeric_power\n \n division : DIVISION\n | WHITESPACE DIVISION\n | WHITESPACE DIVISION WHITESPACE\n | DIVISION WHITESPACE\n \n product : WHITESPACE\n | STAR\n | WHITESPACE STAR\n | WHITESPACE STAR WHITESPACE\n | STAR WHITESPACE\n \n power : STARSTAR\n \n unit : UNIT\n | UNIT power numeric_power\n \n numeric_power : UINT\n | signed_float\n | OPEN_PAREN signed_int CLOSE_PAREN\n | OPEN_PAREN signed_float CLOSE_PAREN\n | OPEN_PAREN signed_float division UINT CLOSE_PAREN\n \n sign : SIGN\n |\n \n signed_int : SIGN UINT\n \n signed_float : sign UINT\n | sign UFLOAT\n ' _lr_action_items = {'UNKNOWN':([0,],[2,]),'LIT10':([0,],[7,]),'SIGN':([0,25,26,27,28,34,47,59,63,],[13,48,-29,48,48,48,13,48,48,]),'UNIT':([0,4,7,8,11,16,17,19,20,21,22,23,24,30,31,33,36,38,39,42,43,44,45,46,49,50,54,55,60,61,67,],[15,15,-16,-17,15,15,-20,15,-21,15,15,-24,-25,-40,-41,15,-23,-20,-22,-26,-28,-15,-32,-33,-18,-19,-22,-27,-34,-35,-36,]),'OPEN_PAREN':([0,4,7,8,11,15,16,17,19,20,21,22,23,24,25,26,27,28,30,31,33,34,36,38,39,42,43,44,45,46,49,50,54,55,59,60,61,63,67,],[16,16,-16,-17,16,33,16,-20,16,-21,16,16,-24,-25,47,-29,47,47,-40,-41,16,47,-23,-20,-22,-26,-28,-15,-32,-33,-18,-19,-22,-27,47,-34,-35,47,-36,]),'DIVISION':([0,4,5,6,7,8,10,14,15,16,19,23,29,30,31,33,40,41,44,45,46,49,50,52,53,57,58,60,61,64,66,67,],[17,17,20,17,-16,-17,-6,-10,-30,17,38,20,-7,-40,-41,17,-8,-9,-15,-32,-33,-18,-19,-31,-12,17,-11,-34,-35,-14,-13,-36,]),'WHITESPACE':([0,4,6,7,8,10,14,15,16,17,19,20,24,29,30,31,33,38,40,41,42,44,45,46,49,50,52,53,57,58,60,61,64,66,67,],[5,19,23,-16,-17,-6,-10,-30,5,36,5,39,43,-7,-40,-41,5,54,-8,-9,55,-15,-32,-33,-18,-19,-31,-12,5,-11,-34,-35,-14,-13,-36,]),'UINT':([0,12,13,17,20,25,26,27,28,34,36,39,47,48,59,62,63,],[-38,30,32,-20,-21,45,-29,45,45,45,-23,-22,-38,-37,45,65,45,]),'UFLOAT':([0,12,13,25,26,27,28,34,47,48,59,63,],[-38,31,-37,-38,-29,-38,-38,-38,-38,-37,-38,-38,]),'$end':([1,2,3,6,10,14,15,18,29,30,31,37,40,41,45,46,52,53,58,60,61,64,66,67,],[0,-1,-2,-5,-6,-10,-30,-3,-7,-40,-41,-4,-8,-9,-32,-33,-31,-12,-11,-34,-35,-14,-13,-36,]),'CLOSE_PAREN':([6,10,14,15,29,30,31,32,35,40,41,45,46,51,52,53,56,57,58,60,61,64,65,66,67,],[-5,-6,-10,-30,-7,-40,-41,-39,53,-8,-9,-32,-33,58,-31,-12,60,61,-11,-34,-35,-14,67,-13,-36,]),'STAR':([6,10,14,15,23,29,30,31,40,41,45,46,52,53,58,60,61,64,66,67,],[24,-6,-10,-30,42,-7,-40,-41,-8,-9,-32,-33,-31,-12,-11,-34,-35,-14,-13,-36,]),'STARSTAR':([7,8,9,15,30,31,32,53,58,],[26,26,26,26,-40,-41,-39,26,26,]),} _lr_action = {} for _k, _v in _lr_action_items.items(): for _x,_y in zip(_v[0],_v[1]): if not _x in _lr_action: _lr_action[_x] = {} _lr_action[_x][_k] = _y del _lr_action_items _lr_goto_items = {'main':([0,],[1,]),'complete_expression':([0,4,16,19,33,],[3,18,35,37,51,]),'scale_factor':([0,],[4,]),'product_of_units':([0,4,16,19,33,],[6,6,6,6,6,]),'signed_float':([0,25,27,28,34,47,59,63,],[8,46,46,46,46,57,46,46,]),'signed_int':([0,47,],[9,56,]),'unit_expression':([0,4,11,16,19,21,22,33,],[10,10,29,10,10,40,41,10,]),'division':([0,4,6,16,19,33,57,],[11,11,22,11,11,11,62,]),'sign':([0,25,27,28,34,47,59,63,],[12,12,12,12,12,12,12,12,]),'unit':([0,4,11,16,19,21,22,33,],[14,14,14,14,14,14,14,14,]),'product':([6,],[21,]),'power':([7,8,9,15,53,58,],[25,27,28,34,59,63,]),'numeric_power':([25,27,28,34,59,63,],[44,49,50,52,64,66,]),} _lr_goto = {} for _k, _v in _lr_goto_items.items(): for _x, _y in zip(_v[0], _v[1]): if not _x in _lr_goto: _lr_goto[_x] = {} _lr_goto[_x][_k] = _y del _lr_goto_items _lr_productions = [ ("S' -> main","S'",1,None,None,None), ('main -> UNKNOWN','main',1,'p_main','ogip.py',184), ('main -> complete_expression','main',1,'p_main','ogip.py',185), ('main -> scale_factor complete_expression','main',2,'p_main','ogip.py',186), ('main -> scale_factor WHITESPACE complete_expression','main',3,'p_main','ogip.py',187), ('complete_expression -> product_of_units','complete_expression',1,'p_complete_expression','ogip.py',198), ('product_of_units -> unit_expression','product_of_units',1,'p_product_of_units','ogip.py',204), ('product_of_units -> division unit_expression','product_of_units',2,'p_product_of_units','ogip.py',205), ('product_of_units -> product_of_units product unit_expression','product_of_units',3,'p_product_of_units','ogip.py',206), ('product_of_units -> product_of_units division unit_expression','product_of_units',3,'p_product_of_units','ogip.py',207), ('unit_expression -> unit','unit_expression',1,'p_unit_expression','ogip.py',221), ('unit_expression -> UNIT OPEN_PAREN complete_expression CLOSE_PAREN','unit_expression',4,'p_unit_expression','ogip.py',222), ('unit_expression -> OPEN_PAREN complete_expression CLOSE_PAREN','unit_expression',3,'p_unit_expression','ogip.py',223), ('unit_expression -> UNIT OPEN_PAREN complete_expression CLOSE_PAREN power numeric_power','unit_expression',6,'p_unit_expression','ogip.py',224), ('unit_expression -> OPEN_PAREN complete_expression CLOSE_PAREN power numeric_power','unit_expression',5,'p_unit_expression','ogip.py',225), ('scale_factor -> LIT10 power numeric_power','scale_factor',3,'p_scale_factor','ogip.py',259), ('scale_factor -> LIT10','scale_factor',1,'p_scale_factor','ogip.py',260), ('scale_factor -> signed_float','scale_factor',1,'p_scale_factor','ogip.py',261), ('scale_factor -> signed_float power numeric_power','scale_factor',3,'p_scale_factor','ogip.py',262), ('scale_factor -> signed_int power numeric_power','scale_factor',3,'p_scale_factor','ogip.py',263), ('division -> DIVISION','division',1,'p_division','ogip.py',278), ('division -> WHITESPACE DIVISION','division',2,'p_division','ogip.py',279), ('division -> WHITESPACE DIVISION WHITESPACE','division',3,'p_division','ogip.py',280), ('division -> DIVISION WHITESPACE','division',2,'p_division','ogip.py',281), ('product -> WHITESPACE','product',1,'p_product','ogip.py',287), ('product -> STAR','product',1,'p_product','ogip.py',288), ('product -> WHITESPACE STAR','product',2,'p_product','ogip.py',289), ('product -> WHITESPACE STAR WHITESPACE','product',3,'p_product','ogip.py',290), ('product -> STAR WHITESPACE','product',2,'p_product','ogip.py',291), ('power -> STARSTAR','power',1,'p_power','ogip.py',297), ('unit -> UNIT','unit',1,'p_unit','ogip.py',303), ('unit -> UNIT power numeric_power','unit',3,'p_unit','ogip.py',304), ('numeric_power -> UINT','numeric_power',1,'p_numeric_power','ogip.py',313), ('numeric_power -> signed_float','numeric_power',1,'p_numeric_power','ogip.py',314), ('numeric_power -> OPEN_PAREN signed_int CLOSE_PAREN','numeric_power',3,'p_numeric_power','ogip.py',315), ('numeric_power -> OPEN_PAREN signed_float CLOSE_PAREN','numeric_power',3,'p_numeric_power','ogip.py',316), ('numeric_power -> OPEN_PAREN signed_float division UINT CLOSE_PAREN','numeric_power',5,'p_numeric_power','ogip.py',317), ('sign -> SIGN','sign',1,'p_sign','ogip.py',328), ('sign -> ','sign',0,'p_sign','ogip.py',329), ('signed_int -> SIGN UINT','signed_int',2,'p_signed_int','ogip.py',338), ('signed_float -> sign UINT','signed_float',2,'p_signed_float','ogip.py',344), ('signed_float -> sign UFLOAT','signed_float',2,'p_signed_float','ogip.py',345), ] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/format/unicode_format.py0000644000175100001710000000307200000000000021752 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """ Handles the "Unicode" unit format. """ from . import console, utils class Unicode(console.Console): """ Output-only format to display pretty formatting at the console using Unicode characters. For example:: >>> import astropy.units as u >>> print(u.bar.decompose().to_string('unicode')) kg 100000 ──── m s² """ _times = "×" _line = "─" @classmethod def _get_unit_name(cls, unit): return unit.get_format_name('unicode') @classmethod def format_exponential_notation(cls, val): m, ex = utils.split_mantissa_exponent(val) parts = [] if m: parts.append(m.replace('-', '−')) if ex: parts.append(f"10{cls._format_superscript(ex)}") return cls._times.join(parts) @classmethod def _format_superscript(cls, number): mapping = { '0': '⁰', '1': 'š', '2': '²', '3': 'Âŗ', '4': '⁴', '5': 'âĩ', '6': 'âļ', '7': '⁡', '8': '⁸', '9': '⁚', '-': 'âģ', '−': 'âģ', # This is actually a "raised omission bracket", but it's # the closest thing I could find to a superscript solidus. '/': '⸍', } output = [] for c in number: output.append(mapping[c]) return ''.join(output) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/format/utils.py0000644000175100001710000001367700000000000020130 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ Utilities shared by the different formats. """ import warnings from fractions import Fraction from astropy.utils.misc import did_you_mean from ..utils import maybe_simple_fraction def get_grouped_by_powers(bases, powers): """ Groups the powers and bases in the given `~astropy.units.CompositeUnit` into positive powers and negative powers for easy display on either side of a solidus. Parameters ---------- bases : list of `astropy.units.UnitBase` instances powers : list of int Returns ------- positives, negatives : tuple of lists Each element in each list is tuple of the form (*base*, *power*). The negatives have the sign of their power reversed (i.e. the powers are all positive). """ positive = [] negative = [] for base, power in zip(bases, powers): if power < 0: negative.append((base, -power)) elif power > 0: positive.append((base, power)) else: raise ValueError("Unit with 0 power") return positive, negative def split_mantissa_exponent(v, format_spec=".8g"): """ Given a number, split it into its mantissa and base 10 exponent parts, each as strings. If the exponent is too small, it may be returned as the empty string. Parameters ---------- v : float format_spec : str, optional Number representation formatting string Returns ------- mantissa, exponent : tuple of strings """ x = format(v, format_spec).split('e') if x[0] != '1.' + '0' * (len(x[0]) - 2): m = x[0] else: m = '' if len(x) == 2: ex = x[1].lstrip("0+") if len(ex) > 0 and ex[0] == '-': ex = '-' + ex[1:].lstrip('0') else: ex = '' return m, ex def decompose_to_known_units(unit, func): """ Partially decomposes a unit so it is only composed of units that are "known" to a given format. Parameters ---------- unit : `~astropy.units.UnitBase` instance func : callable This function will be called to determine if a given unit is "known". If the unit is not known, this function should raise a `ValueError`. Returns ------- unit : `~astropy.units.UnitBase` instance A flattened unit. """ from astropy.units import core if isinstance(unit, core.CompositeUnit): new_unit = core.Unit(unit.scale) for base, power in zip(unit.bases, unit.powers): new_unit = new_unit * decompose_to_known_units(base, func) ** power return new_unit elif isinstance(unit, core.NamedUnit): try: func(unit) except ValueError: if isinstance(unit, core.Unit): return decompose_to_known_units(unit._represents, func) raise return unit else: raise TypeError("unit argument must be a 'NamedUnit' or 'CompositeUnit', " f"not {type(unit)}") def format_power(power): """ Converts a value for a power (which may be floating point or a `fractions.Fraction` object), into a string looking like either an integer or a fraction, if the power is close to that. """ if not hasattr(power, 'denominator'): power = maybe_simple_fraction(power) if getattr(power, 'denonimator', None) == 1: power = power.nominator return str(power) def _try_decomposed(unit, format_decomposed): represents = getattr(unit, '_represents', None) if represents is not None: try: represents_string = format_decomposed(represents) except ValueError: pass else: return represents_string decomposed = unit.decompose() if decomposed is not unit: try: decompose_string = format_decomposed(decomposed) except ValueError: pass else: return decompose_string return None def did_you_mean_units(s, all_units, deprecated_units, format_decomposed): """ A wrapper around `astropy.utils.misc.did_you_mean` that deals with the display of deprecated units. Parameters ---------- s : str The invalid unit string all_units : dict A mapping from valid unit names to unit objects. deprecated_units : sequence The deprecated unit names format_decomposed : callable A function to turn a decomposed version of the unit into a string. Should return `None` if not possible Returns ------- msg : str A string message with a list of alternatives, or the empty string. """ def fix_deprecated(x): if x in deprecated_units: results = [x + ' (deprecated)'] decomposed = _try_decomposed( all_units[x], format_decomposed) if decomposed is not None: results.append(decomposed) return results return (x,) return did_you_mean(s, all_units, fix=fix_deprecated) def unit_deprecation_warning(s, unit, standard_name, format_decomposed): """ Raises a UnitsWarning about a deprecated unit in a given format. Suggests a decomposed alternative if one is available. Parameters ---------- s : str The deprecated unit name. unit : astropy.units.core.UnitBase The unit object. standard_name : str The name of the format for which the unit is deprecated. format_decomposed : callable A function to turn a decomposed version of the unit into a string. Should return `None` if not possible """ from astropy.units.core import UnitsWarning message = f"The unit '{s}' has been deprecated in the {standard_name} standard." decomposed = _try_decomposed(unit, format_decomposed) if decomposed is not None: message += f" Suggested: {decomposed}." warnings.warn(message, UnitsWarning) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/format/vounit.py0000644000175100001710000002064400000000000020304 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ Handles the "VOUnit" unit format. """ import copy import keyword import operator import re import warnings from . import core, generic, utils class VOUnit(generic.Generic): """ The IVOA standard for units used by the VO. This is an implementation of `Units in the VO 1.0 `_. """ _explicit_custom_unit_regex = re.compile( r"^[YZEPTGMkhdcmunpfazy]?'((?!\d)\w)+'$") _custom_unit_regex = re.compile(r"^((?!\d)\w)+$") _custom_units = {} @staticmethod def _generate_unit_names(): from astropy import units as u from astropy.units import required_by_vounit as uvo names = {} deprecated_names = set() bases = [ 'A', 'C', 'D', 'F', 'G', 'H', 'Hz', 'J', 'Jy', 'K', 'N', 'Ohm', 'Pa', 'R', 'Ry', 'S', 'T', 'V', 'W', 'Wb', 'a', 'adu', 'arcmin', 'arcsec', 'barn', 'beam', 'bin', 'cd', 'chan', 'count', 'ct', 'd', 'deg', 'eV', 'erg', 'g', 'h', 'lm', 'lx', 'lyr', 'm', 'mag', 'min', 'mol', 'pc', 'ph', 'photon', 'pix', 'pixel', 'rad', 'rad', 's', 'solLum', 'solMass', 'solRad', 'sr', 'u', 'voxel', 'yr' ] binary_bases = [ 'bit', 'byte', 'B' ] simple_units = [ 'Angstrom', 'angstrom', 'AU', 'au', 'Ba', 'dB', 'mas' ] si_prefixes = [ 'y', 'z', 'a', 'f', 'p', 'n', 'u', 'm', 'c', 'd', '', 'da', 'h', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' ] binary_prefixes = [ 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei' ] deprecated_units = set([ 'a', 'angstrom', 'Angstrom', 'au', 'Ba', 'barn', 'ct', 'erg', 'G', 'ph', 'pix' ]) def do_defines(bases, prefixes, skips=[]): for base in bases: for prefix in prefixes: key = prefix + base if key in skips: continue if keyword.iskeyword(key): continue names[key] = getattr(u if hasattr(u, key) else uvo, key) if base in deprecated_units: deprecated_names.add(key) do_defines(bases, si_prefixes, ['pct', 'pcount', 'yd']) do_defines(binary_bases, si_prefixes + binary_prefixes, ['dB', 'dbyte']) do_defines(simple_units, ['']) return names, deprecated_names, [] @classmethod def parse(cls, s, debug=False): if s in ('unknown', 'UNKNOWN'): return None if s == '': return core.dimensionless_unscaled # Check for excess solidi, but exclude fractional exponents (allowed) if (s.count('/') > 1 and s.count('/') - len(re.findall(r'\(\d+/\d+\)', s)) > 1): raise core.UnitsError( "'{}' contains multiple slashes, which is " "disallowed by the VOUnit standard".format(s)) result = cls._do_parse(s, debug=debug) if hasattr(result, 'function_unit'): raise ValueError("Function units are not yet supported in " "VOUnit.") return result @classmethod def _get_unit(cls, t): try: return super()._get_unit(t) except ValueError: if cls._explicit_custom_unit_regex.match(t.value): return cls._def_custom_unit(t.value) if cls._custom_unit_regex.match(t.value): warnings.warn( "Unit {!r} not supported by the VOUnit " "standard. {}".format( t.value, utils.did_you_mean_units( t.value, cls._units, cls._deprecated_units, cls._to_decomposed_alternative)), core.UnitsWarning) return cls._def_custom_unit(t.value) raise @classmethod def _parse_unit(cls, unit, detailed_exception=True): if unit not in cls._units: raise ValueError() if unit in cls._deprecated_units: utils.unit_deprecation_warning( unit, cls._units[unit], 'VOUnit', cls._to_decomposed_alternative) return cls._units[unit] @classmethod def _get_unit_name(cls, unit): # The da- and d- prefixes are discouraged. This has the # effect of adding a scale to value in the result. if isinstance(unit, core.PrefixUnit): if unit._represents.scale == 10.0: raise ValueError( "In '{}': VOUnit can not represent units with the 'da' " "(deka) prefix".format(unit)) elif unit._represents.scale == 0.1: raise ValueError( "In '{}': VOUnit can not represent units with the 'd' " "(deci) prefix".format(unit)) name = unit.get_format_name('vounit') if unit in cls._custom_units.values(): return name if name not in cls._units: raise ValueError( f"Unit {name!r} is not part of the VOUnit standard") if name in cls._deprecated_units: utils.unit_deprecation_warning( name, unit, 'VOUnit', cls._to_decomposed_alternative) return name @classmethod def _def_custom_unit(cls, unit): def def_base(name): if name in cls._custom_units: return cls._custom_units[name] if name.startswith("'"): return core.def_unit( [name[1:-1], name], format={'vounit': name}, namespace=cls._custom_units) else: return core.def_unit( name, namespace=cls._custom_units) if unit in cls._custom_units: return cls._custom_units[unit] for short, full, factor in core.si_prefixes: for prefix in short: if unit.startswith(prefix): base_name = unit[len(prefix):] base_unit = def_base(base_name) return core.PrefixUnit( [prefix + x for x in base_unit.names], core.CompositeUnit(factor, [base_unit], [1], _error_check=False), format={'vounit': prefix + base_unit.names[-1]}, namespace=cls._custom_units) return def_base(unit) @classmethod def _format_unit_list(cls, units): out = [] units.sort(key=lambda x: cls._get_unit_name(x[0]).lower()) for base, power in units: if power == 1: out.append(cls._get_unit_name(base)) else: power = utils.format_power(power) if '/' in power or '.' in power: out.append(f'{cls._get_unit_name(base)}({power})') else: out.append(f'{cls._get_unit_name(base)}**{power}') return '.'.join(out) @classmethod def to_string(cls, unit): from astropy.units import core # Remove units that aren't known to the format unit = utils.decompose_to_known_units(unit, cls._get_unit_name) if isinstance(unit, core.CompositeUnit): if unit.physical_type == 'dimensionless' and unit.scale != 1: raise core.UnitScaleError( "The VOUnit format is not able to " "represent scale for dimensionless units. " "Multiply your data by {:e}." .format(unit.scale)) s = '' if unit.scale != 1: s += f'{unit.scale:.8g}' pairs = list(zip(unit.bases, unit.powers)) pairs.sort(key=operator.itemgetter(1), reverse=True) s += cls._format_unit_list(pairs) elif isinstance(unit, core.NamedUnit): s = cls._get_unit_name(unit) return s @classmethod def _to_decomposed_alternative(cls, unit): from astropy.units import core try: s = cls.to_string(unit) except core.UnitScaleError: scale = unit.scale unit = copy.copy(unit) unit._scale = 1.0 return f'{cls.to_string(unit)} (with data multiplied by {scale})' return s ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1832528 astropy-5.0.2/astropy/units/function/0000755000175100001710000000000000000000000016735 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/function/__init__.py0000644000175100001710000000052300000000000021046 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This subpackage contains classes and functions for defining and converting between different function units and quantities, i.e., using units which are some function of a physical unit, such as magnitudes and decibels. """ from .core import * from .logarithmic import * ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/function/core.py0000644000175100001710000006567600000000000020263 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """Function Units and Quantities.""" from abc import ABCMeta, abstractmethod import numpy as np from astropy.units import (Unit, UnitBase, UnitsError, UnitTypeError, UnitConversionError, dimensionless_unscaled, Quantity) __all__ = ['FunctionUnitBase', 'FunctionQuantity'] SUPPORTED_UFUNCS = set(getattr(np.core.umath, ufunc) for ufunc in ( 'isfinite', 'isinf', 'isnan', 'sign', 'signbit', 'rint', 'floor', 'ceil', 'trunc', '_ones_like', 'ones_like', 'positive') if hasattr(np.core.umath, ufunc)) # TODO: the following could work if helper changed relative to Quantity: # - spacing should return dimensionless, not same unit # - negative should negate unit too, # - add, subtract, comparisons can work if units added/subtracted SUPPORTED_FUNCTIONS = set(getattr(np, function) for function in ('clip', 'trace', 'mean', 'min', 'max', 'round')) # subclassing UnitBase or CompositeUnit was found to be problematic, requiring # a large number of overrides. Hence, define new class. class FunctionUnitBase(metaclass=ABCMeta): """Abstract base class for function units. Function units are functions containing a physical unit, such as dB(mW). Most of the arithmetic operations on function units are defined in this base class. While instantiation is defined, this class should not be used directly. Rather, subclasses should be used that override the abstract properties `_default_function_unit` and `_quantity_class`, and the abstract methods `from_physical`, and `to_physical`. Parameters ---------- physical_unit : `~astropy.units.Unit` or `string` Unit that is encapsulated within the function unit. If not given, dimensionless. function_unit : `~astropy.units.Unit` or `string` By default, the same as the function unit set by the subclass. """ # ↓↓↓ the following four need to be set by subclasses # Make this a property so we can ensure subclasses define it. @property @abstractmethod def _default_function_unit(self): """Default function unit corresponding to the function. This property should be overridden by subclasses, with, e.g., `~astropy.unit.MagUnit` returning `~astropy.unit.mag`. """ # This has to be a property because the function quantity will not be # known at unit definition time, as it gets defined after. @property @abstractmethod def _quantity_class(self): """Function quantity class corresponding to this function unit. This property should be overridden by subclasses, with, e.g., `~astropy.unit.MagUnit` returning `~astropy.unit.Magnitude`. """ @abstractmethod def from_physical(self, x): """Transformation from value in physical to value in function units. This method should be overridden by subclasses. It is used to provide automatic transformations using an equivalency. """ @abstractmethod def to_physical(self, x): """Transformation from value in function to value in physical units. This method should be overridden by subclasses. It is used to provide automatic transformations using an equivalency. """ # ↑↑↑ the above four need to be set by subclasses # have priority over arrays, regular units, and regular quantities __array_priority__ = 30000 def __init__(self, physical_unit=None, function_unit=None): if physical_unit is None: self._physical_unit = dimensionless_unscaled else: self._physical_unit = Unit(physical_unit) if (not isinstance(self._physical_unit, UnitBase) or self._physical_unit.is_equivalent( self._default_function_unit)): raise UnitConversionError("Unit {} is not a physical unit." .format(self._physical_unit)) if function_unit is None: self._function_unit = self._default_function_unit else: # any function unit should be equivalent to subclass default function_unit = Unit(getattr(function_unit, 'function_unit', function_unit)) if function_unit.is_equivalent(self._default_function_unit): self._function_unit = function_unit else: raise UnitConversionError( "Cannot initialize '{}' instance with function unit '{}'" ", as it is not equivalent to default function unit '{}'." .format(self.__class__.__name__, function_unit, self._default_function_unit)) def _copy(self, physical_unit=None): """Copy oneself, possibly with a different physical unit.""" if physical_unit is None: physical_unit = self.physical_unit return self.__class__(physical_unit, self.function_unit) @property def physical_unit(self): return self._physical_unit @property def function_unit(self): return self._function_unit @property def equivalencies(self): """List of equivalencies between function and physical units. Uses the `from_physical` and `to_physical` methods. """ return [(self, self.physical_unit, self.to_physical, self.from_physical)] # ↓↓↓ properties/methods required to behave like a unit def decompose(self, bases=set()): """Copy the current unit with the physical unit decomposed. For details, see `~astropy.units.UnitBase.decompose`. """ return self._copy(self.physical_unit.decompose(bases)) @property def si(self): """Copy the current function unit with the physical unit in SI.""" return self._copy(self.physical_unit.si) @property def cgs(self): """Copy the current function unit with the physical unit in CGS.""" return self._copy(self.physical_unit.cgs) def _get_physical_type_id(self): """Get physical type corresponding to physical unit.""" return self.physical_unit._get_physical_type_id() @property def physical_type(self): """Return the physical type of the physical unit (e.g., 'length').""" return self.physical_unit.physical_type def is_equivalent(self, other, equivalencies=[]): """ Returns `True` if this unit is equivalent to ``other``. Parameters ---------- other : `~astropy.units.Unit`, string, or tuple The unit to convert to. If a tuple of units is specified, this method returns true if the unit matches any of those in the tuple. equivalencies : list of tuple A list of equivalence pairs to try if the units are not directly convertible. See :ref:`astropy:unit_equivalencies`. This list is in addition to the built-in equivalencies between the function unit and the physical one, as well as possible global defaults set by, e.g., `~astropy.units.set_enabled_equivalencies`. Use `None` to turn off any global equivalencies. Returns ------- bool """ if isinstance(other, tuple): return any(self.is_equivalent(u, equivalencies=equivalencies) for u in other) other_physical_unit = getattr(other, 'physical_unit', ( dimensionless_unscaled if self.function_unit.is_equivalent(other) else other)) return self.physical_unit.is_equivalent(other_physical_unit, equivalencies) def to(self, other, value=1., equivalencies=[]): """ Return the converted values in the specified unit. Parameters ---------- other : `~astropy.units.Unit`, `~astropy.units.function.FunctionUnitBase`, or str The unit to convert to. value : int, float, or scalar array-like, optional Value(s) in the current unit to be converted to the specified unit. If not provided, defaults to 1.0. equivalencies : list of tuple A list of equivalence pairs to try if the units are not directly convertible. See :ref:`astropy:unit_equivalencies`. This list is in meant to treat only equivalencies between different physical units; the built-in equivalency between the function unit and the physical one is automatically taken into account. Returns ------- values : scalar or array Converted value(s). Input value sequences are returned as numpy arrays. Raises ------ `~astropy.units.UnitsError` If units are inconsistent. """ # conversion to one's own physical unit should be fastest if other is self.physical_unit: return self.to_physical(value) other_function_unit = getattr(other, 'function_unit', other) if self.function_unit.is_equivalent(other_function_unit): # when other is an equivalent function unit: # first convert physical units to other's physical units other_physical_unit = getattr(other, 'physical_unit', dimensionless_unscaled) if self.physical_unit != other_physical_unit: value_other_physical = self.physical_unit.to( other_physical_unit, self.to_physical(value), equivalencies) # make function unit again, in own system value = self.from_physical(value_other_physical) # convert possible difference in function unit (e.g., dex->dB) return self.function_unit.to(other_function_unit, value) else: try: # when other is not a function unit return self.physical_unit.to(other, self.to_physical(value), equivalencies) except UnitConversionError as e: if self.function_unit == Unit('mag'): # One can get to raw magnitudes via math that strips the dimensions off. # Include extra information in the exception to remind users of this. msg = "Did you perhaps subtract magnitudes so the unit got lost?" e.args += (msg,) raise e else: raise def is_unity(self): return False def __eq__(self, other): return (self.physical_unit == getattr(other, 'physical_unit', dimensionless_unscaled) and self.function_unit == getattr(other, 'function_unit', other)) def __ne__(self, other): return not self.__eq__(other) def __rlshift__(self, other): """Unit conversion operator ``<<``""" try: return self._quantity_class(other, self, copy=False, subok=True) except Exception: return NotImplemented def __mul__(self, other): if isinstance(other, (str, UnitBase, FunctionUnitBase)): if self.physical_unit == dimensionless_unscaled: # If dimensionless, drop back to normal unit and retry. return self.function_unit * other else: raise UnitsError("Cannot multiply a function unit " "with a physical dimension with any unit.") else: # Anything not like a unit, try initialising as a function quantity. try: return self._quantity_class(other, unit=self) except Exception: return NotImplemented def __rmul__(self, other): return self.__mul__(other) def __div__(self, other): if isinstance(other, (str, UnitBase, FunctionUnitBase)): if self.physical_unit == dimensionless_unscaled: # If dimensionless, drop back to normal unit and retry. return self.function_unit / other else: raise UnitsError("Cannot divide a function unit " "with a physical dimension by any unit.") else: # Anything not like a unit, try initialising as a function quantity. try: return self._quantity_class(1./other, unit=self) except Exception: return NotImplemented def __rdiv__(self, other): if isinstance(other, (str, UnitBase, FunctionUnitBase)): if self.physical_unit == dimensionless_unscaled: # If dimensionless, drop back to normal unit and retry. return other / self.function_unit else: raise UnitsError("Cannot divide a function unit " "with a physical dimension into any unit") else: # Don't know what to do with anything not like a unit. return NotImplemented __truediv__ = __div__ __rtruediv__ = __rdiv__ def __pow__(self, power): if power == 0: return dimensionless_unscaled elif power == 1: return self._copy() if self.physical_unit == dimensionless_unscaled: return self.function_unit ** power raise UnitsError("Cannot raise a function unit " "with a physical dimension to any power but 0 or 1.") def __pos__(self): return self._copy() def to_string(self, format='generic'): """ Output the unit in the given format as a string. The physical unit is appended, within parentheses, to the function unit, as in "dB(mW)", with both units set using the given format Parameters ---------- format : `astropy.units.format.Base` instance or str The name of a format or a formatter object. If not provided, defaults to the generic format. """ if format not in ('generic', 'unscaled', 'latex'): raise ValueError("Function units cannot be written in {} format. " "Only 'generic', 'unscaled' and 'latex' are " "supported.".format(format)) self_str = self.function_unit.to_string(format) pu_str = self.physical_unit.to_string(format) if pu_str == '': pu_str = '1' if format == 'latex': self_str += r'$\mathrm{{\left( {0} \right)}}$'.format( pu_str[1:-1]) # need to strip leading and trailing "$" else: self_str += f'({pu_str})' return self_str def __str__(self): """Return string representation for unit.""" self_str = str(self.function_unit) pu_str = str(self.physical_unit) if pu_str: self_str += f'({pu_str})' return self_str def __repr__(self): # By default, try to give a representation using `Unit()`, # with string such that parsing it would give the correct FunctionUnit. if callable(self.function_unit): return f'Unit("{self.to_string()}")' else: return '{}("{}"{})'.format( self.__class__.__name__, self.physical_unit, "" if self.function_unit is self._default_function_unit else f', unit="{self.function_unit}"') def _repr_latex_(self): """ Generate latex representation of unit name. This is used by the IPython notebook to print a unit with a nice layout. Returns ------- Latex string """ return self.to_string('latex') def __hash__(self): return hash((self.function_unit, self.physical_unit)) class FunctionQuantity(Quantity): """A representation of a (scaled) function of a number with a unit. Function quantities are quantities whose units are functions containing a physical unit, such as dB(mW). Most of the arithmetic operations on function quantities are defined in this base class. While instantiation is also defined here, this class should not be instantiated directly. Rather, subclasses should be made which have ``_unit_class`` pointing back to the corresponding function unit class. Parameters ---------- value : number, quantity-like, or sequence thereof The numerical value of the function quantity. If a number or a `~astropy.units.Quantity` with a function unit, it will be converted to ``unit`` and the physical unit will be inferred from ``unit``. If a `~astropy.units.Quantity` with just a physical unit, it will converted to the function unit, after, if necessary, converting it to the physical unit inferred from ``unit``. unit : str, `~astropy.units.UnitBase`, or `~astropy.units.function.FunctionUnitBase`, optional For an `~astropy.units.function.FunctionUnitBase` instance, the physical unit will be taken from it; for other input, it will be inferred from ``value``. By default, ``unit`` is set by the subclass. dtype : `~numpy.dtype`, optional The dtype of the resulting Numpy array or scalar that will hold the value. If not provided, it is determined from the input, except that any input that cannot represent float (integer and bool) is converted to float. copy : bool, optional If `True` (default), then the value is copied. Otherwise, a copy will only be made if ``__array__`` returns a copy, if value is a nested sequence, or if a copy is needed to satisfy an explicitly given ``dtype``. (The `False` option is intended mostly for internal use, to speed up initialization where a copy is known to have been made. Use with care.) order : {'C', 'F', 'A'}, optional Specify the order of the array. As in `~numpy.array`. Ignored if the input does not need to be converted and ``copy=False``. subok : bool, optional If `False` (default), the returned array will be forced to be of the class used. Otherwise, subclasses will be passed through. ndmin : int, optional Specifies the minimum number of dimensions that the resulting array should have. Ones will be pre-pended to the shape as needed to meet this requirement. This parameter is ignored if the input is a `~astropy.units.Quantity` and ``copy=False``. Raises ------ TypeError If the value provided is not a Python numeric type. TypeError If the unit provided is not a `~astropy.units.function.FunctionUnitBase` or `~astropy.units.Unit` object, or a parseable string unit. """ _unit_class = None """Default `~astropy.units.function.FunctionUnitBase` subclass. This should be overridden by subclasses. """ # Ensure priority over ndarray, regular Unit & Quantity, and FunctionUnit. __array_priority__ = 40000 # Define functions that work on FunctionQuantity. _supported_ufuncs = SUPPORTED_UFUNCS _supported_functions = SUPPORTED_FUNCTIONS def __new__(cls, value, unit=None, dtype=None, copy=True, order=None, subok=False, ndmin=0): if unit is not None: # Convert possible string input to a (function) unit. unit = Unit(unit) if not isinstance(unit, FunctionUnitBase): # By default, use value's physical unit. value_unit = getattr(value, 'unit', None) if value_unit is None: # if iterable, see if first item has a unit # (mixed lists fail in super call below). try: value_unit = getattr(value[0], 'unit') except Exception: pass physical_unit = getattr(value_unit, 'physical_unit', value_unit) unit = cls._unit_class(physical_unit, function_unit=unit) # initialise! return super().__new__(cls, value, unit, dtype=dtype, copy=copy, order=order, subok=subok, ndmin=ndmin) # ↓↓↓ properties not found in Quantity @property def physical(self): """The physical quantity corresponding the function one.""" return self.to(self.unit.physical_unit) @property def _function_view(self): """View as Quantity with function unit, dropping the physical unit. Use `~astropy.units.quantity.Quantity.value` for just the value. """ return self._new_view(unit=self.unit.function_unit) # ↓↓↓ methods overridden to change the behavior @property def si(self): """Return a copy with the physical unit in SI units.""" return self.__class__(self.physical.si) @property def cgs(self): """Return a copy with the physical unit in CGS units.""" return self.__class__(self.physical.cgs) def decompose(self, bases=[]): """Generate a new `FunctionQuantity` with the physical unit decomposed. For details, see `~astropy.units.Quantity.decompose`. """ return self.__class__(self.physical.decompose(bases)) # ↓↓↓ methods overridden to add additional behavior def __quantity_subclass__(self, unit): if isinstance(unit, FunctionUnitBase): return self.__class__, True else: return super().__quantity_subclass__(unit)[0], False def _set_unit(self, unit): if not isinstance(unit, self._unit_class): # Have to take care of, e.g., (10*u.mag).view(u.Magnitude) try: # "or 'nonsense'" ensures `None` breaks, just in case. unit = self._unit_class(function_unit=unit or 'nonsense') except Exception: raise UnitTypeError( "{} instances require {} function units" .format(type(self).__name__, self._unit_class.__name__) + f", so cannot set it to '{unit}'.") self._unit = unit def __array_ufunc__(self, function, method, *inputs, **kwargs): # TODO: it would be more logical to have this in Quantity already, # instead of in UFUNC_HELPERS, where it cannot be overridden. # And really it should just return NotImplemented, since possibly # another argument might know what to do. if function not in self._supported_ufuncs: raise UnitTypeError( f"Cannot use ufunc '{function.__name__}' with function quantities") return super().__array_ufunc__(function, method, *inputs, **kwargs) # ↓↓↓ methods overridden to change behavior def __mul__(self, other): if self.unit.physical_unit == dimensionless_unscaled: return self._function_view * other raise UnitTypeError("Cannot multiply function quantities which " "are not dimensionless with anything.") def __truediv__(self, other): if self.unit.physical_unit == dimensionless_unscaled: return self._function_view / other raise UnitTypeError("Cannot divide function quantities which " "are not dimensionless by anything.") def __rtruediv__(self, other): if self.unit.physical_unit == dimensionless_unscaled: return self._function_view.__rdiv__(other) raise UnitTypeError("Cannot divide function quantities which " "are not dimensionless into anything.") def _comparison(self, other, comparison_func): """Do a comparison between self and other, raising UnitsError when other cannot be converted to self because it has different physical unit, and returning NotImplemented when there are other errors.""" try: # will raise a UnitsError if physical units not equivalent other_in_own_unit = self._to_own_unit(other, check_precision=False) except UnitsError as exc: if self.unit.physical_unit != dimensionless_unscaled: raise exc try: other_in_own_unit = self._function_view._to_own_unit( other, check_precision=False) except Exception: raise exc except Exception: return NotImplemented return comparison_func(other_in_own_unit) def __eq__(self, other): try: return self._comparison(other, self.value.__eq__) except UnitsError: return False def __ne__(self, other): try: return self._comparison(other, self.value.__ne__) except UnitsError: return True def __gt__(self, other): return self._comparison(other, self.value.__gt__) def __ge__(self, other): return self._comparison(other, self.value.__ge__) def __lt__(self, other): return self._comparison(other, self.value.__lt__) def __le__(self, other): return self._comparison(other, self.value.__le__) def __lshift__(self, other): """Unit conversion operator `<<`""" try: other = Unit(other, parse_strict='silent') except UnitTypeError: return NotImplemented return self.__class__(self, other, copy=False, subok=True) # Ensure Quantity methods are used only if they make sense. def _wrap_function(self, function, *args, **kwargs): if function in self._supported_functions: return super()._wrap_function(function, *args, **kwargs) # For dimensionless, we can convert to regular quantities. if all(arg.unit.physical_unit == dimensionless_unscaled for arg in (self,) + args if (hasattr(arg, 'unit') and hasattr(arg.unit, 'physical_unit'))): args = tuple(getattr(arg, '_function_view', arg) for arg in args) return self._function_view._wrap_function(function, *args, **kwargs) raise TypeError("Cannot use method that uses function '{}' with " "function quantities that are not dimensionless." .format(function.__name__)) # Override functions that are supported but do not use _wrap_function # in Quantity. def max(self, axis=None, out=None, keepdims=False): return self._wrap_function(np.max, axis, out=out, keepdims=keepdims) def min(self, axis=None, out=None, keepdims=False): return self._wrap_function(np.min, axis, out=out, keepdims=keepdims) def sum(self, axis=None, dtype=None, out=None, keepdims=False): return self._wrap_function(np.sum, axis, dtype, out=out, keepdims=keepdims) def cumsum(self, axis=None, dtype=None, out=None): return self._wrap_function(np.cumsum, axis, dtype, out=out) def clip(self, a_min, a_max, out=None): return self._wrap_function(np.clip, self._to_own_unit(a_min), self._to_own_unit(a_max), out=out) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/function/logarithmic.py0000644000175100001710000003273600000000000021624 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst import numpy as np from astropy.units import (dimensionless_unscaled, photometric, Unit, CompositeUnit, UnitsError, UnitTypeError, UnitConversionError) from .core import FunctionUnitBase, FunctionQuantity from .units import dex, dB, mag __all__ = ['LogUnit', 'MagUnit', 'DexUnit', 'DecibelUnit', 'LogQuantity', 'Magnitude', 'Decibel', 'Dex', 'STmag', 'ABmag', 'M_bol', 'm_bol'] class LogUnit(FunctionUnitBase): """Logarithmic unit containing a physical one Usually, logarithmic units are instantiated via specific subclasses such `MagUnit`, `DecibelUnit`, and `DexUnit`. Parameters ---------- physical_unit : `~astropy.units.Unit` or `string` Unit that is encapsulated within the logarithmic function unit. If not given, dimensionless. function_unit : `~astropy.units.Unit` or `string` By default, the same as the logarithmic unit set by the subclass. """ # the four essential overrides of FunctionUnitBase @property def _default_function_unit(self): return dex @property def _quantity_class(self): return LogQuantity def from_physical(self, x): """Transformation from value in physical to value in logarithmic units. Used in equivalency.""" return dex.to(self._function_unit, np.log10(x)) def to_physical(self, x): """Transformation from value in logarithmic to value in physical units. Used in equivalency.""" return 10 ** self._function_unit.to(dex, x) # ^^^^ the four essential overrides of FunctionUnitBase # add addition and subtraction, which imply multiplication/division of # the underlying physical units def _add_and_adjust_physical_unit(self, other, sign_self, sign_other): """Add/subtract LogUnit to/from another unit, and adjust physical unit. self and other are multiplied by sign_self and sign_other, resp. We wish to do: Âąlu_1 + Âąlu_2 -> lu_f (lu=logarithmic unit) and pu_1^(Âą1) * pu_2^(Âą1) -> pu_f (pu=physical unit) Raises ------ UnitsError If function units are not equivalent. """ # First, insist on compatible logarithmic type. Here, plain u.mag, # u.dex, and u.dB are OK, i.e., other does not have to be LogUnit # (this will indirectly test whether other is a unit at all). try: getattr(other, 'function_unit', other)._to(self._function_unit) except AttributeError: # if other is not a unit (i.e., does not have _to). return NotImplemented except UnitsError: raise UnitsError("Can only add/subtract logarithmic units of" "of compatible type.") other_physical_unit = getattr(other, 'physical_unit', dimensionless_unscaled) physical_unit = CompositeUnit( 1, [self._physical_unit, other_physical_unit], [sign_self, sign_other]) return self._copy(physical_unit) def __neg__(self): return self._copy(self.physical_unit**(-1)) def __add__(self, other): # Only know how to add to a logarithmic unit with compatible type, # be it a plain one (u.mag, etc.,) or another LogUnit return self._add_and_adjust_physical_unit(other, +1, +1) def __radd__(self, other): return self._add_and_adjust_physical_unit(other, +1, +1) def __sub__(self, other): return self._add_and_adjust_physical_unit(other, +1, -1) def __rsub__(self, other): # here, in normal usage other cannot be LogUnit; only equivalent one # would be u.mag,u.dB,u.dex. But might as well use common routine. return self._add_and_adjust_physical_unit(other, -1, +1) class MagUnit(LogUnit): """Logarithmic physical units expressed in magnitudes Parameters ---------- physical_unit : `~astropy.units.Unit` or `string` Unit that is encapsulated within the magnitude function unit. If not given, dimensionless. function_unit : `~astropy.units.Unit` or `string` By default, this is ``mag``, but this allows one to use an equivalent unit such as ``2 mag``. """ @property def _default_function_unit(self): return mag @property def _quantity_class(self): return Magnitude class DexUnit(LogUnit): """Logarithmic physical units expressed in magnitudes Parameters ---------- physical_unit : `~astropy.units.Unit` or `string` Unit that is encapsulated within the magnitude function unit. If not given, dimensionless. function_unit : `~astropy.units.Unit` or `string` By default, this is ``dex`, but this allows one to use an equivalent unit such as ``0.5 dex``. """ @property def _default_function_unit(self): return dex @property def _quantity_class(self): return Dex def to_string(self, format='generic'): if format == 'cds': if self.physical_unit == dimensionless_unscaled: return "[-]" # by default, would get "[---]". else: return f"[{self.physical_unit.to_string(format=format)}]" else: return super(DexUnit, self).to_string() class DecibelUnit(LogUnit): """Logarithmic physical units expressed in dB Parameters ---------- physical_unit : `~astropy.units.Unit` or `string` Unit that is encapsulated within the decibel function unit. If not given, dimensionless. function_unit : `~astropy.units.Unit` or `string` By default, this is ``dB``, but this allows one to use an equivalent unit such as ``2 dB``. """ @property def _default_function_unit(self): return dB @property def _quantity_class(self): return Decibel class LogQuantity(FunctionQuantity): """A representation of a (scaled) logarithm of a number with a unit Parameters ---------- value : number, `~astropy.units.Quantity`, `~astropy.units.function.logarithmic.LogQuantity`, or sequence of quantity-like. The numerical value of the logarithmic quantity. If a number or a `~astropy.units.Quantity` with a logarithmic unit, it will be converted to ``unit`` and the physical unit will be inferred from ``unit``. If a `~astropy.units.Quantity` with just a physical unit, it will converted to the logarithmic unit, after, if necessary, converting it to the physical unit inferred from ``unit``. unit : str, `~astropy.units.UnitBase`, or `~astropy.units.function.FunctionUnitBase`, optional For an `~astropy.units.function.FunctionUnitBase` instance, the physical unit will be taken from it; for other input, it will be inferred from ``value``. By default, ``unit`` is set by the subclass. dtype : `~numpy.dtype`, optional The ``dtype`` of the resulting Numpy array or scalar that will hold the value. If not provided, is is determined automatically from the input value. copy : bool, optional If `True` (default), then the value is copied. Otherwise, a copy will only be made if ``__array__`` returns a copy, if value is a nested sequence, or if a copy is needed to satisfy an explicitly given ``dtype``. (The `False` option is intended mostly for internal use, to speed up initialization where a copy is known to have been made. Use with care.) Examples -------- Typically, use is made of an `~astropy.units.function.FunctionQuantity` subclass, as in:: >>> import astropy.units as u >>> u.Magnitude(-2.5) >>> u.Magnitude(10.*u.count/u.second) >>> u.Decibel(1.*u.W, u.DecibelUnit(u.mW)) # doctest: +FLOAT_CMP """ # only override of FunctionQuantity _unit_class = LogUnit # additions that work just for logarithmic units def __add__(self, other): # Add function units, thus multiplying physical units. If no unit is # given, assume dimensionless_unscaled; this will give the appropriate # exception in LogUnit.__add__. new_unit = self.unit + getattr(other, 'unit', dimensionless_unscaled) # Add actual logarithmic values, rescaling, e.g., dB -> dex. result = self._function_view + getattr(other, '_function_view', other) return self._new_view(result, new_unit) def __radd__(self, other): return self.__add__(other) def __iadd__(self, other): new_unit = self.unit + getattr(other, 'unit', dimensionless_unscaled) # Do calculation in-place using _function_view of array. function_view = self._function_view function_view += getattr(other, '_function_view', other) self._set_unit(new_unit) return self def __sub__(self, other): # Subtract function units, thus dividing physical units. new_unit = self.unit - getattr(other, 'unit', dimensionless_unscaled) # Subtract actual logarithmic values, rescaling, e.g., dB -> dex. result = self._function_view - getattr(other, '_function_view', other) return self._new_view(result, new_unit) def __rsub__(self, other): new_unit = self.unit.__rsub__( getattr(other, 'unit', dimensionless_unscaled)) result = self._function_view.__rsub__( getattr(other, '_function_view', other)) # Ensure the result is in right function unit scale # (with rsub, this does not have to be one's own). result = result.to(new_unit.function_unit) return self._new_view(result, new_unit) def __isub__(self, other): new_unit = self.unit - getattr(other, 'unit', dimensionless_unscaled) # Do calculation in-place using _function_view of array. function_view = self._function_view function_view -= getattr(other, '_function_view', other) self._set_unit(new_unit) return self def __pow__(self, other): # We check if this power is OK by applying it first to the unit. try: other = float(other) except TypeError: return NotImplemented new_unit = self.unit ** other new_value = self.view(np.ndarray) ** other return self._new_view(new_value, new_unit) def __ilshift__(self, other): try: other = Unit(other) except UnitTypeError: return NotImplemented if not isinstance(other, self._unit_class): return NotImplemented try: factor = self.unit.physical_unit._to(other.physical_unit) except UnitConversionError: # Maybe via equivalencies? Now we do make a temporary copy. try: value = self._to_value(other) except UnitConversionError: return NotImplemented self.view(np.ndarray)[...] = value else: self.view(np.ndarray)[...] += self.unit.from_physical(factor) self._set_unit(other) return self # Could add __mul__ and __div__ and try interpreting other as a power, # but this seems just too error-prone. # Methods that do not work for function units generally but are OK for # logarithmic units as they imply differences and independence of # physical unit. def var(self, axis=None, dtype=None, out=None, ddof=0): return self._wrap_function(np.var, axis, dtype, out=out, ddof=ddof, unit=self.unit.function_unit**2) def std(self, axis=None, dtype=None, out=None, ddof=0): return self._wrap_function(np.std, axis, dtype, out=out, ddof=ddof, unit=self.unit._copy(dimensionless_unscaled)) def ptp(self, axis=None, out=None): return self._wrap_function(np.ptp, axis, out=out, unit=self.unit._copy(dimensionless_unscaled)) def diff(self, n=1, axis=-1): return self._wrap_function(np.diff, n, axis, unit=self.unit._copy(dimensionless_unscaled)) def ediff1d(self, to_end=None, to_begin=None): return self._wrap_function(np.ediff1d, to_end, to_begin, unit=self.unit._copy(dimensionless_unscaled)) _supported_functions = (FunctionQuantity._supported_functions | set(getattr(np, function) for function in ('var', 'std', 'ptp', 'diff', 'ediff1d'))) class Dex(LogQuantity): _unit_class = DexUnit class Decibel(LogQuantity): _unit_class = DecibelUnit class Magnitude(LogQuantity): _unit_class = MagUnit dex._function_unit_class = DexUnit dB._function_unit_class = DecibelUnit mag._function_unit_class = MagUnit STmag = MagUnit(photometric.STflux) STmag.__doc__ = "ST magnitude: STmag=-21.1 corresponds to 1 erg/s/cm2/A" ABmag = MagUnit(photometric.ABflux) ABmag.__doc__ = "AB magnitude: ABmag=-48.6 corresponds to 1 erg/s/cm2/Hz" M_bol = MagUnit(photometric.Bol) M_bol.__doc__ = ("Absolute bolometric magnitude: M_bol=0 corresponds to " "L_bol0={}".format(photometric.Bol.si)) m_bol = MagUnit(photometric.bol) m_bol.__doc__ = ("Apparent bolometric magnitude: m_bol=0 corresponds to " "f_bol0={}".format(photometric.bol.si)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/function/mixin.py0000644000175100001710000000135500000000000020437 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst from astropy.units.core import IrreducibleUnit, Unit class FunctionMixin: """Mixin class that makes UnitBase subclasses callable. Provides a __call__ method that passes on arguments to a FunctionUnit. Instances of this class should define ``_function_unit_class`` pointing to the relevant class. See units.py and logarithmic.py for usage. """ def __call__(self, unit=None): return self._function_unit_class(physical_unit=unit, function_unit=self) class IrreducibleFunctionUnit(FunctionMixin, IrreducibleUnit): pass class RegularFunctionUnit(FunctionMixin, Unit): pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/function/units.py0000644000175100001710000000336100000000000020454 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """ This package defines units that can also be used as functions of other units. If called, their arguments are used to initialize the corresponding function unit (e.g., ``u.mag(u.ct/u.s)``). Note that the prefixed versions cannot be called, as it would be unclear what, e.g., ``u.mmag(u.ct/u.s)`` would mean. """ from astropy.units.core import _add_prefixes from .mixin import RegularFunctionUnit, IrreducibleFunctionUnit _ns = globals() ########################################################################### # Logarithmic units # These calls are what core.def_unit would do, but we need to use the callable # unit versions. The actual function unit classes get added in logarithmic. dex = IrreducibleFunctionUnit(['dex'], namespace=_ns, doc="Dex: Base 10 logarithmic unit") dB = RegularFunctionUnit(['dB', 'decibel'], 0.1 * dex, namespace=_ns, doc="Decibel: ten per base 10 logarithmic unit") mag = RegularFunctionUnit(['mag'], -0.4 * dex, namespace=_ns, doc=("Astronomical magnitude: " "-2.5 per base 10 logarithmic unit")) _add_prefixes(mag, namespace=_ns, prefixes=True) ########################################################################### # CLEANUP del RegularFunctionUnit del IrreducibleFunctionUnit ########################################################################### # DOCSTRING # This generates a docstring for this module that describes all of the # standard units defined here. from astropy.units.utils import generate_unit_summary as _generate_unit_summary if __doc__ is not None: __doc__ += _generate_unit_summary(globals()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/imperial.py0000644000175100001710000001250700000000000017271 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """ This package defines colloquially used Imperial units. They are available in the `astropy.units.imperial` namespace, but not in the top-level `astropy.units` namespace, e.g.:: >>> import astropy.units as u >>> mph = u.imperial.mile / u.hour >>> mph Unit("mi / h") To include them in `~astropy.units.UnitBase.compose` and the results of `~astropy.units.UnitBase.find_equivalent_units`, do:: >>> import astropy.units as u >>> u.imperial.enable() # doctest: +SKIP """ from .core import UnitBase, def_unit from . import si _ns = globals() ########################################################################### # LENGTH def_unit(['inch'], 2.54 * si.cm, namespace=_ns, doc="International inch") def_unit(['ft', 'foot'], 12 * inch, namespace=_ns, doc="International foot") def_unit(['yd', 'yard'], 3 * ft, namespace=_ns, doc="International yard") def_unit(['mi', 'mile'], 5280 * ft, namespace=_ns, doc="International mile") def_unit(['mil', 'thou'], 0.001 * inch, namespace=_ns, doc="Thousandth of an inch") def_unit(['nmi', 'nauticalmile', 'NM'], 1852 * si.m, namespace=_ns, doc="Nautical mile") def_unit(['fur', 'furlong'], 660 * ft, namespace=_ns, doc="Furlong") ########################################################################### # AREAS def_unit(['ac', 'acre'], 43560 * ft ** 2, namespace=_ns, doc="International acre") ########################################################################### # VOLUMES def_unit(['gallon'], si.liter / 0.264172052, namespace=_ns, doc="U.S. liquid gallon") def_unit(['quart'], gallon / 4, namespace=_ns, doc="U.S. liquid quart") def_unit(['pint'], quart / 2, namespace=_ns, doc="U.S. liquid pint") def_unit(['cup'], pint / 2, namespace=_ns, doc="U.S. customary cup") def_unit(['foz', 'fluid_oz', 'fluid_ounce'], cup / 8, namespace=_ns, doc="U.S. fluid ounce") def_unit(['tbsp', 'tablespoon'], foz / 2, namespace=_ns, doc="U.S. customary tablespoon") def_unit(['tsp', 'teaspoon'], tbsp / 3, namespace=_ns, doc="U.S. customary teaspoon") ########################################################################### # MASS def_unit(['oz', 'ounce'], 28.349523125 * si.g, namespace=_ns, doc="International avoirdupois ounce: mass") def_unit(['lb', 'lbm', 'pound'], 16 * oz, namespace=_ns, doc="International avoirdupois pound: mass") def_unit(['st', 'stone'], 14 * lb, namespace=_ns, doc="International avoirdupois stone: mass") def_unit(['ton'], 2000 * lb, namespace=_ns, doc="International avoirdupois ton: mass") def_unit(['slug'], 32.174049 * lb, namespace=_ns, doc="slug: mass") ########################################################################### # SPEED def_unit(['kn', 'kt', 'knot', 'NMPH'], nmi / si.h, namespace=_ns, doc="nautical unit of speed: 1 nmi per hour") ########################################################################### # FORCE def_unit('lbf', slug * ft * si.s**-2, namespace=_ns, doc="Pound: force") def_unit(['kip', 'kilopound'], 1000 * lbf, namespace=_ns, doc="Kilopound: force") ########################################################################## # ENERGY def_unit(['BTU', 'btu'], 1.05505585 * si.kJ, namespace=_ns, doc="British thermal unit") def_unit(['cal', 'calorie'], 4.184 * si.J, namespace=_ns, doc="Thermochemical calorie: pre-SI metric unit of energy") def_unit(['kcal', 'Cal', 'Calorie', 'kilocal', 'kilocalorie'], 1000 * cal, namespace=_ns, doc="Calorie: colloquial definition of Calorie") ########################################################################## # PRESSURE def_unit('psi', lbf * inch ** -2, namespace=_ns, doc="Pound per square inch: pressure") ########################################################################### # POWER # Imperial units def_unit(['hp', 'horsepower'], si.W / 0.00134102209, namespace=_ns, doc="Electrical horsepower") ########################################################################### # TEMPERATURE def_unit(['deg_F', 'Fahrenheit'], namespace=_ns, doc='Degrees Fahrenheit', format={'latex': r'{}^{\circ}F', 'unicode': '°F'}) def_unit(['deg_R', 'Rankine'], namespace=_ns, doc='Rankine scale: absolute scale of thermodynamic temperature') ########################################################################### # CLEANUP del UnitBase del def_unit ########################################################################### # DOCSTRING # This generates a docstring for this module that describes all of the # standard units defined here. from .utils import generate_unit_summary as _generate_unit_summary if __doc__ is not None: __doc__ += _generate_unit_summary(globals()) def enable(): """ Enable Imperial units so they appear in results of `~astropy.units.UnitBase.find_equivalent_units` and `~astropy.units.UnitBase.compose`. This may be used with the ``with`` statement to enable Imperial units only temporarily. """ # Local import to avoid cyclical import from .core import add_enabled_units # Local import to avoid polluting namespace import inspect return add_enabled_units(inspect.getmodule(enable)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/misc.py0000644000175100001710000000650100000000000016417 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """ This package defines miscellaneous units. They are also available in the `astropy.units` namespace. """ from . import si from astropy.constants import si as _si from .core import (UnitBase, def_unit, si_prefixes, binary_prefixes, set_enabled_units) # To ensure si units of the constants can be interpreted. set_enabled_units([si]) import numpy as _numpy _ns = globals() ########################################################################### # AREAS def_unit(['barn', 'barn'], 10 ** -28 * si.m ** 2, namespace=_ns, prefixes=True, doc="barn: unit of area used in HEP") ########################################################################### # ANGULAR MEASUREMENTS def_unit(['cycle', 'cy'], 2.0 * _numpy.pi * si.rad, namespace=_ns, prefixes=False, doc="cycle: angular measurement, a full turn or rotation") def_unit(['spat', 'sp'], 4.0 * _numpy.pi * si.sr, namespace=_ns, prefixes=False, doc="spat: the solid angle of the sphere, 4pi sr") ########################################################################## # PRESSURE def_unit(['bar'], 1e5 * si.Pa, namespace=_ns, prefixes=[(['m'], ['milli'], 1.e-3)], doc="bar: pressure") # The torr is almost the same as mmHg but not quite. # See https://en.wikipedia.org/wiki/Torr # Define the unit here despite it not being an astrophysical unit. # It may be moved if more similar units are created later. def_unit(['Torr', 'torr'], _si.atm.value/760. * si.Pa, namespace=_ns, prefixes=[(['m'], ['milli'], 1.e-3)], doc="Unit of pressure based on an absolute scale, now defined as " "exactly 1/760 of a standard atmosphere") ########################################################################### # MASS def_unit(['M_p'], _si.m_p, namespace=_ns, doc="Proton mass", format={'latex': r'M_{p}', 'unicode': 'Mₚ'}) def_unit(['M_e'], _si.m_e, namespace=_ns, doc="Electron mass", format={'latex': r'M_{e}', 'unicode': 'Mₑ'}) # Unified atomic mass unit def_unit(['u', 'Da', 'Dalton'], _si.u, namespace=_ns, prefixes=True, exclude_prefixes=['a', 'da'], doc="Unified atomic mass unit") ########################################################################### # COMPUTER def_unit((['bit', 'b'], ['bit']), namespace=_ns, prefixes=si_prefixes + binary_prefixes) def_unit((['byte', 'B'], ['byte']), 8 * bit, namespace=_ns, format={'vounit': 'byte'}, prefixes=si_prefixes + binary_prefixes, exclude_prefixes=['d']) def_unit((['pix', 'pixel'], ['pixel']), format={'ogip': 'pixel', 'vounit': 'pixel'}, namespace=_ns, prefixes=True) def_unit((['vox', 'voxel'], ['voxel']), format={'fits': 'voxel', 'ogip': 'voxel', 'vounit': 'voxel'}, namespace=_ns, prefixes=True) ########################################################################### # CLEANUP del UnitBase del def_unit del si ########################################################################### # DOCSTRING # This generates a docstring for this module that describes all of the # standard units defined here. from .utils import generate_unit_summary as _generate_unit_summary if __doc__ is not None: __doc__ += _generate_unit_summary(globals()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/photometric.py0000644000175100001710000000456500000000000020031 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """ This module defines magnitude zero points and related photometric quantities. The corresponding magnitudes are given in the description of each unit (the actual definitions are in `~astropy.units.function.logarithmic`). """ import numpy as _numpy from .core import UnitBase, def_unit, Unit from astropy.constants import si as _si from . import cgs, si, astrophys _ns = globals() def_unit(['Bol', 'L_bol'], _si.L_bol0, namespace=_ns, prefixes=False, doc="Luminosity corresponding to absolute bolometric magnitude zero " "(magnitude ``M_bol``).") def_unit(['bol', 'f_bol'], _si.L_bol0 / (4 * _numpy.pi * (10.*astrophys.pc)**2), namespace=_ns, prefixes=False, doc="Irradiance corresponding to " "appparent bolometric magnitude zero (magnitude ``m_bol``).") def_unit(['AB', 'ABflux'], 10.**(48.6/-2.5) * cgs.erg * cgs.cm**-2 / si.s / si.Hz, namespace=_ns, prefixes=False, doc="AB magnitude zero flux density (magnitude ``ABmag``).") def_unit(['ST', 'STflux'], 10.**(21.1/-2.5) * cgs.erg * cgs.cm**-2 / si.s / si.AA, namespace=_ns, prefixes=False, doc="ST magnitude zero flux density (magnitude ``STmag``).") def_unit(['mgy', 'maggy'], namespace=_ns, prefixes=[(['n'], ['nano'], 1e-9)], doc="Maggies - a linear flux unit that is the flux for a mag=0 object." "To tie this onto a specific calibrated unit system, the " "zero_point_flux equivalency should be used.") def zero_point_flux(flux0): """ An equivalency for converting linear flux units ("maggys") defined relative to a standard source into a standardized system. Parameters ---------- flux0 : `~astropy.units.Quantity` The flux of a magnitude-0 object in the "maggy" system. """ flux_unit0 = Unit(flux0) return [(maggy, flux_unit0)] ########################################################################### # CLEANUP del UnitBase del def_unit del cgs, si, astrophys ########################################################################### # DOCSTRING # This generates a docstring for this module that describes all of the # standard units defined here. from .utils import generate_unit_summary as _generate_unit_summary if __doc__ is not None: __doc__ += _generate_unit_summary(globals()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/physical.py0000644000175100001710000005372000000000000017305 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """Defines the physical types that correspond to different units.""" import numbers import warnings from . import core from . import si from . import astrophys from . import cgs from . import imperial # Need this for backward namespace compat, see issues 11975 and 11977 # noqa from . import misc from . import quantity from astropy.utils.exceptions import AstropyDeprecationWarning __all__ = ["def_physical_type", "get_physical_type", "PhysicalType"] _units_and_physical_types = [ (core.dimensionless_unscaled, "dimensionless"), (si.m, "length"), (si.m ** 2, "area"), (si.m ** 3, "volume"), (si.s, "time"), (si.rad, "angle"), (si.sr, "solid angle"), (si.m / si.s, {"speed", "velocity"}), (si.m / si.s ** 2, "acceleration"), (si.Hz, "frequency"), (si.g, "mass"), (si.mol, "amount of substance"), (si.K, "temperature"), (si.W * si.m ** -1 * si.K ** -1, "thermal conductivity"), (si.J * si.K ** -1, {"heat capacity", "entropy"}), (si.J * si.K ** -1 * si.kg ** -1, {"specific heat capacity", "specific entropy"}), (si.N, "force"), (si.J, {"energy", "work", "torque"}), (si.J * si.m ** -2 * si.s ** -1, {"energy flux", "irradiance"}), (si.Pa, {"pressure", "energy density", "stress"}), (si.W, {"power", "radiant flux"}), (si.kg * si.m ** -3, "mass density"), (si.m ** 3 / si.kg, "specific volume"), (si.mol / si.m ** 3, "molar concentration"), (si.m ** 3 / si.mol, "molar volume"), (si.kg * si.m / si.s, {"momentum", "impulse"}), (si.kg * si.m ** 2 / si.s, {"angular momentum", "action"}), (si.rad / si.s, {"angular speed", "angular velocity", "angular frequency"}), (si.rad / si.s ** 2, "angular acceleration"), (si.rad / si.m, "plate scale"), (si.g / (si.m * si.s), "dynamic viscosity"), (si.m ** 2 / si.s, {"diffusivity", "kinematic viscosity"}), (si.m ** -1, "wavenumber"), (si.m ** -2, "column density"), (si.A, "electrical current"), (si.C, "electrical charge"), (si.V, "electrical potential"), (si.Ohm, {"electrical resistance", "electrical impedance", "electrical reactance"}), (si.Ohm * si.m, "electrical resistivity"), (si.S, "electrical conductance"), (si.S / si.m, "electrical conductivity"), (si.F, "electrical capacitance"), (si.C * si.m, "electrical dipole moment"), (si.A / si.m ** 2, "electrical current density"), (si.V / si.m, "electrical field strength"), (si.C / si.m ** 2, {"electrical flux density", "surface charge density", "polarization density"}, ), (si.C / si.m ** 3, "electrical charge density"), (si.F / si.m, "permittivity"), (si.Wb, "magnetic flux"), (si.T, "magnetic flux density"), (si.A / si.m, "magnetic field strength"), (si.m ** 2 * si.A, "magnetic moment"), (si.H / si.m, {"electromagnetic field strength", "permeability"}), (si.H, "inductance"), (si.cd, "luminous intensity"), (si.lm, "luminous flux"), (si.lx, {"luminous emittance", "illuminance"}), (si.W / si.sr, "radiant intensity"), (si.cd / si.m ** 2, "luminance"), (si.m ** -3 * si.s ** -1, "volumetric rate"), (astrophys.Jy, "spectral flux density"), (si.W * si.m ** 2 * si.Hz ** -1, "surface tension"), (si.J * si.m ** -3 * si.s ** -1, {"spectral flux density wav", "power density"}), (astrophys.photon / si.Hz / si.cm ** 2 / si.s, "photon flux density"), (astrophys.photon / si.AA / si.cm ** 2 / si.s, "photon flux density wav"), (astrophys.R, "photon flux"), (misc.bit, "data quantity"), (misc.bit / si.s, "bandwidth"), (cgs.Franklin, "electrical charge (ESU)"), (cgs.statampere, "electrical current (ESU)"), (cgs.Biot, "electrical current (EMU)"), (cgs.abcoulomb, "electrical charge (EMU)"), (si.m * si.s ** -3, {"jerk", "jolt"}), (si.m * si.s ** -4, {"snap", "jounce"}), (si.m * si.s ** -5, "crackle"), (si.m * si.s ** -6, {"pop", "pounce"}), (si.K / si.m, "temperature gradient"), (si.J / si.kg, "specific energy"), (si.mol * si.m ** -3 * si.s ** -1, "reaction rate"), (si.kg * si.m ** 2, "moment of inertia"), (si.mol / si.s, "catalytic activity"), (si.J * si.K ** -1 * si.mol ** -1, "molar heat capacity"), (si.mol / si.kg, "molality"), (si.m * si.s, "absement"), (si.m * si.s ** 2, "absity"), (si.m ** 3 / si.s, "volumetric flow rate"), (si.s ** -2, "frequency drift"), (si.Pa ** -1, "compressibility"), (astrophys.electron * si.m ** -3, "electron density"), (astrophys.electron * si.m ** -2 * si.s ** -1, "electron flux"), (si.kg / si.m ** 2, "surface mass density"), (si.W / si.m ** 2 / si.sr, "radiance"), (si.J / si.mol, "chemical potential"), (si.kg / si.m, "linear density"), (si.H ** -1, "magnetic reluctance"), (si.W / si.K, "thermal conductance"), (si.K / si.W, "thermal resistance"), (si.K * si.m / si.W, "thermal resistivity"), (si.N / si.s, "yank"), (si.S * si.m ** 2 / si.mol, "molar conductivity"), (si.m ** 2 / si.V / si.s, "electrical mobility"), (si.lumen / si.W, "luminous efficacy"), (si.m ** 2 / si.kg, {"opacity", "mass attenuation coefficient"}), (si.kg * si.m ** -2 * si.s ** -1, {"mass flux", "momentum density"}), (si.m ** -3, "number density"), (si.m ** -2 * si.s ** -1, "particle flux"), ] _physical_unit_mapping = {} _unit_physical_mapping = {} _name_physical_mapping = {} # mapping from attribute-accessible name (no spaces, etc.) to the actual name. _attrname_physical_mapping = {} def _physical_type_from_str(name): """ Return the `PhysicalType` instance associated with the name of a physical type. """ if name == "unknown": raise ValueError("cannot uniquely identify an 'unknown' physical type.") elif name in _attrname_physical_mapping: return _attrname_physical_mapping[name] # convert attribute-accessible elif name in _name_physical_mapping: return _name_physical_mapping[name] else: raise ValueError(f"{name!r} is not a known physical type.") def _replace_temperatures_with_kelvin(unit): """ If a unit contains a temperature unit besides kelvin, then replace that unit with kelvin. Temperatures cannot be converted directly between K, °F, °C, and °Ra, in particular since there would be different conversions for T and ΔT. However, each of these temperatures each represents the physical type. Replacing the different temperature units with kelvin allows the physical type to be treated consistently. """ physical_type_id = unit._get_physical_type_id() physical_type_id_components = [] substitution_was_made = False for base, power in physical_type_id: if base in ["deg_F", "deg_C", "deg_R"]: base = "K" substitution_was_made = True physical_type_id_components.append((base, power)) if substitution_was_made: return core.Unit._from_physical_type_id(tuple(physical_type_id_components)) else: return unit def _standardize_physical_type_names(physical_type_input): """ Convert a string or `set` of strings into a `set` containing string representations of physical types. The strings provided in ``physical_type_input`` can each contain multiple physical types that are separated by a regular slash. Underscores are treated as spaces so that variable names could be identical to physical type names. """ if isinstance(physical_type_input, str): physical_type_input = {physical_type_input} standardized_physical_types = set() for ptype_input in physical_type_input: if not isinstance(ptype_input, str): raise ValueError(f"expecting a string, but got {ptype_input}") input_set = set(ptype_input.split("/")) processed_set = {s.strip().replace("_", " ") for s in input_set} standardized_physical_types |= processed_set return standardized_physical_types class PhysicalType: """ Represents the physical type(s) that are dimensionally compatible with a set of units. Instances of this class should be accessed through either `get_physical_type` or by using the `~astropy.units.core.UnitBase.physical_type` attribute of units. This class is not intended to be instantiated directly in user code. Parameters ---------- unit : `~astropy.units.Unit` The unit to be represented by the physical type. physical_types : `str` or `set` of `str` A `str` representing the name of the physical type of the unit, or a `set` containing strings that represent one or more names of physical types. Notes ----- A physical type will be considered equal to an equivalent `PhysicalType` instance (recommended) or a string that contains a name of the physical type. The latter method is not recommended in packages, as the names of some physical types may change in the future. To maintain backwards compatibility, two physical type names may be included in one string if they are separated with a slash (e.g., ``"momentum/impulse"``). String representations of physical types may include underscores instead of spaces. Examples -------- `PhysicalType` instances may be accessed via the `~astropy.units.core.UnitBase.physical_type` attribute of units. >>> import astropy.units as u >>> u.meter.physical_type PhysicalType('length') `PhysicalType` instances may also be accessed by calling `get_physical_type`. This function will accept a unit, a string containing the name of a physical type, or the number one. >>> u.get_physical_type(u.m ** -3) PhysicalType('number density') >>> u.get_physical_type("volume") PhysicalType('volume') >>> u.get_physical_type(1) PhysicalType('dimensionless') Some units are dimensionally compatible with multiple physical types. A pascal is intended to represent pressure and stress, but the unit decomposition is equivalent to that of energy density. >>> pressure = u.get_physical_type("pressure") >>> pressure PhysicalType({'energy density', 'pressure', 'stress'}) >>> 'energy density' in pressure True Physical types can be tested for equality against other physical type objects or against strings that may contain the name of a physical type. >>> area = (u.m ** 2).physical_type >>> area == u.barn.physical_type True >>> area == "area" True Multiplication, division, and exponentiation are enabled so that physical types may be used for dimensional analysis. >>> length = u.pc.physical_type >>> area = (u.cm ** 2).physical_type >>> length * area PhysicalType('volume') >>> area / length PhysicalType('length') >>> length ** 3 PhysicalType('volume') may also be performed using a string that contains the name of a physical type. >>> "length" * area PhysicalType('volume') >>> "area" / length PhysicalType('length') Unknown physical types are labelled as ``"unknown"``. >>> (u.s ** 13).physical_type PhysicalType('unknown') Dimensional analysis may be performed for unknown physical types too. >>> length_to_19th_power = (u.m ** 19).physical_type >>> length_to_20th_power = (u.m ** 20).physical_type >>> length_to_20th_power / length_to_19th_power PhysicalType('length') """ def __init__(self, unit, physical_types): self._unit = _replace_temperatures_with_kelvin(unit) self._physical_type_id = self._unit._get_physical_type_id() self._physical_type = _standardize_physical_type_names(physical_types) self._physical_type_list = sorted(self._physical_type) def __iter__(self): yield from self._physical_type_list def __getattr__(self, attr): # TODO: remove this whole method when accessing str attributes from # physical types is no longer supported # short circuit attribute accessed in __str__ to prevent recursion if attr == '_physical_type_list': super().__getattribute__(attr) self_str_attr = getattr(str(self), attr, None) if hasattr(str(self), attr): warning_message = ( f"support for accessing str attributes such as {attr!r} " "from PhysicalType instances is deprecated since 4.3 " "and will be removed in a subsequent release.") warnings.warn(warning_message, AstropyDeprecationWarning) return self_str_attr else: super().__getattribute__(attr) # to get standard error message def __eq__(self, other): """ Return `True` if ``other`` represents a physical type that is consistent with the physical type of the `PhysicalType` instance. """ if isinstance(other, PhysicalType): return self._physical_type_id == other._physical_type_id elif isinstance(other, str): other = _standardize_physical_type_names(other) return other.issubset(self._physical_type) else: return NotImplemented def __ne__(self, other): equality = self.__eq__(other) return not equality if isinstance(equality, bool) else NotImplemented def _name_string_as_ordered_set(self): return "{" + str(self._physical_type_list)[1:-1] + "}" def __repr__(self): if len(self._physical_type) == 1: names = "'" + self._physical_type_list[0] + "'" else: names = self._name_string_as_ordered_set() return f"PhysicalType({names})" def __str__(self): return "/".join(self._physical_type_list) @staticmethod def _dimensionally_compatible_unit(obj): """ Return a unit that corresponds to the provided argument. If a unit is passed in, return that unit. If a physical type (or a `str` with the name of a physical type) is passed in, return a unit that corresponds to that physical type. If the number equal to ``1`` is passed in, return a dimensionless unit. Otherwise, return `NotImplemented`. """ if isinstance(obj, core.UnitBase): return _replace_temperatures_with_kelvin(obj) elif isinstance(obj, PhysicalType): return obj._unit elif isinstance(obj, numbers.Real) and obj == 1: return core.dimensionless_unscaled elif isinstance(obj, str): return _physical_type_from_str(obj)._unit else: return NotImplemented def _dimensional_analysis(self, other, operation): other_unit = self._dimensionally_compatible_unit(other) if other_unit is NotImplemented: return NotImplemented other_unit = _replace_temperatures_with_kelvin(other_unit) new_unit = getattr(self._unit, operation)(other_unit) return new_unit.physical_type def __mul__(self, other): return self._dimensional_analysis(other, "__mul__") def __rmul__(self, other): return self.__mul__(other) def __truediv__(self, other): return self._dimensional_analysis(other, "__truediv__") def __rtruediv__(self, other): other = self._dimensionally_compatible_unit(other) if other is NotImplemented: return NotImplemented return other.physical_type._dimensional_analysis(self, "__truediv__") def __pow__(self, power): return (self._unit ** power).physical_type def __hash__(self): return hash(self._physical_type_id) def __len__(self): return len(self._physical_type) # We need to prevent operations like where a Unit instance left # multiplies a PhysicalType instance from returning a `Quantity` # instance with a PhysicalType as the value. We can do this by # preventing np.array from casting a PhysicalType instance as # an object array. __array__ = None def def_physical_type(unit, name): """ Add a mapping between a unit and the corresponding physical type(s). If a physical type already exists for a unit, add new physical type names so long as those names are not already in use for other physical types. Parameters ---------- unit : `~astropy.units.Unit` The unit to be represented by the physical type. name : `str` or `set` of `str` A `str` representing the name of the physical type of the unit, or a `set` containing strings that represent one or more names of physical types. Raises ------ ValueError If a physical type name is already in use for another unit, or if attempting to name a unit as ``"unknown"``. """ physical_type_id = unit._get_physical_type_id() physical_type_names = _standardize_physical_type_names(name) if "unknown" in physical_type_names: raise ValueError("cannot uniquely define an unknown physical type") names_for_other_units = set(_unit_physical_mapping.keys()).difference( _physical_unit_mapping.get(physical_type_id, {})) names_already_in_use = physical_type_names & names_for_other_units if names_already_in_use: raise ValueError( f"the following physical type names are already in use: " f"{names_already_in_use}.") unit_already_in_use = physical_type_id in _physical_unit_mapping if unit_already_in_use: physical_type = _physical_unit_mapping[physical_type_id] physical_type_names |= set(physical_type) physical_type.__init__(unit, physical_type_names) else: physical_type = PhysicalType(unit, physical_type_names) _physical_unit_mapping[physical_type_id] = physical_type for ptype in physical_type: _unit_physical_mapping[ptype] = physical_type_id for ptype_name in physical_type_names: _name_physical_mapping[ptype_name] = physical_type # attribute-accessible name attr_name = ptype_name.replace(' ', '_').replace('(', '').replace(')', '') _attrname_physical_mapping[attr_name] = physical_type def get_physical_type(obj): """ Return the physical type that corresponds to a unit (or another physical type representation). Parameters ---------- obj : quantity-like or `~astropy.units.PhysicalType`-like An object that (implicitly or explicitly) has a corresponding physical type. This object may be a unit, a `~astropy.units.Quantity`, an object that can be converted to a `~astropy.units.Quantity` (such as a number or array), a string that contains a name of a physical type, or a `~astropy.units.PhysicalType` instance. Returns ------- `~astropy.units.PhysicalType` A representation of the physical type(s) of the unit. Examples -------- The physical type may be retrieved from a unit or a `~astropy.units.Quantity`. >>> import astropy.units as u >>> u.get_physical_type(u.meter ** -2) PhysicalType('column density') >>> u.get_physical_type(0.62 * u.barn * u.Mpc) PhysicalType('volume') The physical type may also be retrieved by providing a `str` that contains the name of a physical type. >>> u.get_physical_type("energy") PhysicalType({'energy', 'torque', 'work'}) Numbers and arrays of numbers correspond to a dimensionless physical type. >>> u.get_physical_type(1) PhysicalType('dimensionless') """ if isinstance(obj, PhysicalType): return obj if isinstance(obj, str): return _physical_type_from_str(obj) try: unit = obj if isinstance(obj, core.UnitBase) else quantity.Quantity(obj, copy=False).unit except TypeError as exc: raise TypeError(f"{obj} does not correspond to a physical type.") from exc unit = _replace_temperatures_with_kelvin(unit) physical_type_id = unit._get_physical_type_id() unit_has_known_physical_type = physical_type_id in _physical_unit_mapping if unit_has_known_physical_type: return _physical_unit_mapping[physical_type_id] else: return PhysicalType(unit, "unknown") # ------------------------------------------------------------------------------ # Script section creating the physical types and the documentation # define the physical types for unit, physical_type in _units_and_physical_types: def_physical_type(unit, physical_type) # For getting the physical types. def __getattr__(name): """Checks for physical types using lazy import. This also allows user-defined physical types to be accessible from the :mod:`astropy.units.physical` module. See `PEP 562 `_ Parameters ---------- name : str The name of the attribute in this module. If it is already defined, then this function is not called. Returns ------- ptype : `~astropy.units.physical.PhysicalType` Raises ------ AttributeError If the ``name`` does not correspond to a physical type """ if name in _attrname_physical_mapping: return _attrname_physical_mapping[name] raise AttributeError(f"module {__name__!r} has no attribute {name!r}") def __dir__(): """Return contents directory (__all__ + all physical type names).""" return list(set(__all__) | set(_attrname_physical_mapping.keys())) # This generates a docstring addition for this module that describes all of the # standard physical types defined here. if __doc__ is not None: doclines = [ ".. list-table:: Defined Physical Types", " :header-rows: 1", " :widths: 30 10 50", "", " * - Physical type", " - Unit", " - Other physical type(s) with same unit"] for name in sorted(_name_physical_mapping.keys()): physical_type = _name_physical_mapping[name] doclines.extend([ f" * - _`{name}`", f" - :math:`{physical_type._unit.to_string('latex')[1:-1]}`", f" - {', '.join([n for n in physical_type if n != name])}"]) __doc__ += '\n\n' + '\n'.join(doclines) del unit, physical_type ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/quantity.py0000644000175100001710000023660500000000000017354 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """ This module defines the `Quantity` object, which represents a number with some associated units. `Quantity` objects support operations like ordinary numbers, but will deal with unit conversions internally. """ # Standard library import re import numbers from fractions import Fraction import operator import warnings import numpy as np # AstroPy from .core import (Unit, dimensionless_unscaled, get_current_unit_registry, UnitBase, UnitsError, UnitConversionError, UnitTypeError) from .structured import StructuredUnit from .utils import is_effectively_unity from .format.latex import Latex from astropy.utils.compat import NUMPY_LT_1_22 from astropy.utils.compat.misc import override__dir__ from astropy.utils.exceptions import AstropyDeprecationWarning, AstropyWarning from astropy.utils.introspection import minversion from astropy.utils.misc import isiterable from astropy.utils.data_info import ParentDtypeInfo from astropy import config as _config from .quantity_helper import (converters_and_unit, can_have_arbitrary_unit, check_output) from .quantity_helper.function_helpers import ( SUBCLASS_SAFE_FUNCTIONS, FUNCTION_HELPERS, DISPATCHED_FUNCTIONS, UNSUPPORTED_FUNCTIONS) __all__ = ["Quantity", "SpecificTypeQuantity", "QuantityInfoBase", "QuantityInfo", "allclose", "isclose"] # We don't want to run doctests in the docstrings we inherit from Numpy __doctest_skip__ = ['Quantity.*'] _UNIT_NOT_INITIALISED = "(Unit not initialised)" _UFUNCS_FILTER_WARNINGS = {np.arcsin, np.arccos, np.arccosh, np.arctanh} class Conf(_config.ConfigNamespace): """ Configuration parameters for Quantity """ latex_array_threshold = _config.ConfigItem(100, 'The maximum size an array Quantity can be before its LaTeX ' 'representation for IPython gets "summarized" (meaning only the first ' 'and last few elements are shown with "..." between). Setting this to a ' 'negative number means that the value will instead be whatever numpy ' 'gets from get_printoptions.') conf = Conf() class QuantityIterator: """ Flat iterator object to iterate over Quantities A `QuantityIterator` iterator is returned by ``q.flat`` for any Quantity ``q``. It allows iterating over the array as if it were a 1-D array, either in a for-loop or by calling its `next` method. Iteration is done in C-contiguous style, with the last index varying the fastest. The iterator can also be indexed using basic slicing or advanced indexing. See Also -------- Quantity.flatten : Returns a flattened copy of an array. Notes ----- `QuantityIterator` is inspired by `~numpy.ma.core.MaskedIterator`. It is not exported by the `~astropy.units` module. Instead of instantiating a `QuantityIterator` directly, use `Quantity.flat`. """ def __init__(self, q): self._quantity = q self._dataiter = q.view(np.ndarray).flat def __iter__(self): return self def __getitem__(self, indx): out = self._dataiter.__getitem__(indx) # For single elements, ndarray.flat.__getitem__ returns scalars; these # need a new view as a Quantity. if isinstance(out, type(self._quantity)): return out else: return self._quantity._new_view(out) def __setitem__(self, index, value): self._dataiter[index] = self._quantity._to_own_unit(value) def __next__(self): """ Return the next value, or raise StopIteration. """ out = next(self._dataiter) # ndarray.flat._dataiter returns scalars, so need a view as a Quantity. return self._quantity._new_view(out) next = __next__ def __len__(self): return len(self._dataiter) #### properties and methods to match `numpy.ndarray.flatiter` #### @property def base(self): """A reference to the array that is iterated over.""" return self._quantity @property def coords(self): """An N-dimensional tuple of current coordinates.""" return self._dataiter.coords @property def index(self): """Current flat index into the array.""" return self._dataiter.index def copy(self): """Get a copy of the iterator as a 1-D array.""" return self._quantity.flatten() class QuantityInfoBase(ParentDtypeInfo): # This is on a base class rather than QuantityInfo directly, so that # it can be used for EarthLocationInfo yet make clear that that class # should not be considered a typical Quantity subclass by Table. attrs_from_parent = {'dtype', 'unit'} # dtype and unit taken from parent _supports_indexing = True @staticmethod def default_format(val): return f'{val.value}' @staticmethod def possible_string_format_functions(format_): """Iterate through possible string-derived format functions. A string can either be a format specifier for the format built-in, a new-style format string, or an old-style format string. This method is overridden in order to suppress printing the unit in each row since it is already at the top in the column header. """ yield lambda format_, val: format(val.value, format_) yield lambda format_, val: format_.format(val.value) yield lambda format_, val: format_ % val.value class QuantityInfo(QuantityInfoBase): """ Container for meta information like name, description, format. This is required when the object is used as a mixin column within a table, but can be used as a general way to store meta information. """ _represent_as_dict_attrs = ('value', 'unit') _construct_from_dict_args = ['value'] _represent_as_dict_primary_data = 'value' def new_like(self, cols, length, metadata_conflicts='warn', name=None): """ Return a new Quantity instance which is consistent with the input ``cols`` and has ``length`` rows. This is intended for creating an empty column object whose elements can be set in-place for table operations like join or vstack. Parameters ---------- cols : list List of input columns length : int Length of the output column object metadata_conflicts : str ('warn'|'error'|'silent') How to handle metadata conflicts name : str Output column name Returns ------- col : `~astropy.units.Quantity` (or subclass) Empty instance of this class consistent with ``cols`` """ # Get merged info attributes like shape, dtype, format, description, etc. attrs = self.merge_cols_attributes(cols, metadata_conflicts, name, ('meta', 'format', 'description')) # Make an empty quantity using the unit of the last one. shape = (length,) + attrs.pop('shape') dtype = attrs.pop('dtype') # Use zeros so we do not get problems for Quantity subclasses such # as Longitude and Latitude, which cannot take arbitrary values. data = np.zeros(shape=shape, dtype=dtype) # Get arguments needed to reconstruct class map = {key: (data if key == 'value' else getattr(cols[-1], key)) for key in self._represent_as_dict_attrs} map['copy'] = False out = self._construct_from_dict(map) # Set remaining info attributes for attr, value in attrs.items(): setattr(out.info, attr, value) return out def get_sortable_arrays(self): """ Return a list of arrays which can be lexically sorted to represent the order of the parent column. For Quantity this is just the quantity itself. Returns ------- arrays : list of ndarray """ return [self._parent] class Quantity(np.ndarray): """A `~astropy.units.Quantity` represents a number with some associated unit. See also: https://docs.astropy.org/en/stable/units/quantity.html Parameters ---------- value : number, `~numpy.ndarray`, `~astropy.units.Quantity` (sequence), or str The numerical value of this quantity in the units given by unit. If a `Quantity` or sequence of them (or any other valid object with a ``unit`` attribute), creates a new `Quantity` object, converting to `unit` units as needed. If a string, it is converted to a number or `Quantity`, depending on whether a unit is present. unit : unit-like An object that represents the unit associated with the input value. Must be an `~astropy.units.UnitBase` object or a string parseable by the :mod:`~astropy.units` package. dtype : ~numpy.dtype, optional The dtype of the resulting Numpy array or scalar that will hold the value. If not provided, it is determined from the input, except that any integer and (non-Quantity) object inputs are converted to float by default. copy : bool, optional If `True` (default), then the value is copied. Otherwise, a copy will only be made if ``__array__`` returns a copy, if value is a nested sequence, or if a copy is needed to satisfy an explicitly given ``dtype``. (The `False` option is intended mostly for internal use, to speed up initialization where a copy is known to have been made. Use with care.) order : {'C', 'F', 'A'}, optional Specify the order of the array. As in `~numpy.array`. This parameter is ignored if the input is a `Quantity` and ``copy=False``. subok : bool, optional If `False` (default), the returned array will be forced to be a `Quantity`. Otherwise, `Quantity` subclasses will be passed through, or a subclass appropriate for the unit will be used (such as `~astropy.units.Dex` for ``u.dex(u.AA)``). ndmin : int, optional Specifies the minimum number of dimensions that the resulting array should have. Ones will be pre-pended to the shape as needed to meet this requirement. This parameter is ignored if the input is a `Quantity` and ``copy=False``. Raises ------ TypeError If the value provided is not a Python numeric type. TypeError If the unit provided is not either a :class:`~astropy.units.Unit` object or a parseable string unit. Notes ----- Quantities can also be created by multiplying a number or array with a :class:`~astropy.units.Unit`. See https://docs.astropy.org/en/latest/units/ Unless the ``dtype`` argument is explicitly specified, integer or (non-Quantity) object inputs are converted to `float` by default. """ # Need to set a class-level default for _equivalencies, or # Constants can not initialize properly _equivalencies = [] # Default unit for initialization; can be overridden by subclasses, # possibly to `None` to indicate there is no default unit. _default_unit = dimensionless_unscaled # Ensures views have an undefined unit. _unit = None __array_priority__ = 10000 def __class_getitem__(cls, unit_shape_dtype): """Quantity Type Hints. Unit-aware type hints are ``Annotated`` objects that encode the class, the unit, and possibly shape and dtype information, depending on the python and :mod:`numpy` versions. Schematically, ``Annotated[cls[shape, dtype], unit]`` As a classmethod, the type is the class, ie ``Quantity`` produces an ``Annotated[Quantity, ...]`` while a subclass like :class:`~astropy.coordinates.Angle` returns ``Annotated[Angle, ...]``. Parameters ---------- unit_shape_dtype : :class:`~astropy.units.UnitBase`, str, `~astropy.units.PhysicalType`, or tuple Unit specification, can be the physical type (ie str or class). If tuple, then the first element is the unit specification and all other elements are for `numpy.ndarray` type annotations. Whether they are included depends on the python and :mod:`numpy` versions. Returns ------- `typing.Annotated`, `typing_extensions.Annotated`, `astropy.units.Unit`, or `astropy.units.PhysicalType` Return type in this preference order: * if python v3.9+ : `typing.Annotated` * if :mod:`typing_extensions` is installed : `typing_extensions.Annotated` * `astropy.units.Unit` or `astropy.units.PhysicalType` Raises ------ TypeError If the unit/physical_type annotation is not Unit-like or PhysicalType-like. Examples -------- Create a unit-aware Quantity type annotation >>> Quantity[Unit("s")] Annotated[Quantity, Unit("s")] See Also -------- `~astropy.units.quantity_input` Use annotations for unit checks on function arguments and results. Notes ----- With Python 3.9+ or :mod:`typing_extensions`, |Quantity| types are also static-type compatible. """ # LOCAL from ._typing import HAS_ANNOTATED, Annotated # process whether [unit] or [unit, shape, ptype] if isinstance(unit_shape_dtype, tuple): # unit, shape, dtype target = unit_shape_dtype[0] shape_dtype = unit_shape_dtype[1:] else: # just unit target = unit_shape_dtype shape_dtype = () # Allowed unit/physical types. Errors if neither. try: unit = Unit(target) except (TypeError, ValueError): from astropy.units.physical import get_physical_type try: unit = get_physical_type(target) except (TypeError, ValueError, KeyError): # KeyError for Enum raise TypeError("unit annotation is not a Unit or PhysicalType") from None # Allow to sort of work for python 3.8- / no typing_extensions # instead of bailing out, return the unit for `quantity_input` if not HAS_ANNOTATED: warnings.warn("Quantity annotations are valid static type annotations only" " if Python is v3.9+ or `typing_extensions` is installed.") return unit # Quantity does not (yet) properly extend the NumPy generics types, # introduced in numpy v1.22+, instead just including the unit info as # metadata using Annotated. # TODO: ensure we do interact with NDArray.__class_getitem__. return Annotated.__class_getitem__((cls, unit)) def __new__(cls, value, unit=None, dtype=None, copy=True, order=None, subok=False, ndmin=0): if unit is not None: # convert unit first, to avoid multiple string->unit conversions unit = Unit(unit) # optimize speed for Quantity with no dtype given, copy=False if isinstance(value, Quantity): if unit is not None and unit is not value.unit: value = value.to(unit) # the above already makes a copy (with float dtype) copy = False if type(value) is not cls and not (subok and isinstance(value, cls)): value = value.view(cls) if dtype is None and value.dtype.kind in 'iu': dtype = float return np.array(value, dtype=dtype, copy=copy, order=order, subok=True, ndmin=ndmin) # Maybe str, or list/tuple of Quantity? If so, this may set value_unit. # To ensure array remains fast, we short-circuit it. value_unit = None if not isinstance(value, np.ndarray): if isinstance(value, str): # The first part of the regex string matches any integer/float; # the second parts adds possible trailing .+-, which will break # the float function below and ensure things like 1.2.3deg # will not work. pattern = (r'\s*[+-]?' r'((\d+\.?\d*)|(\.\d+)|([nN][aA][nN])|' r'([iI][nN][fF]([iI][nN][iI][tT][yY]){0,1}))' r'([eE][+-]?\d+)?' r'[.+-]?') v = re.match(pattern, value) unit_string = None try: value = float(v.group()) except Exception: raise TypeError('Cannot parse "{}" as a {}. It does not ' 'start with a number.' .format(value, cls.__name__)) unit_string = v.string[v.end():].strip() if unit_string: value_unit = Unit(unit_string) if unit is None: unit = value_unit # signal no conversion needed below. elif isiterable(value) and len(value) > 0: # Iterables like lists and tuples. if all(isinstance(v, Quantity) for v in value): # If a list/tuple containing only quantities, convert all # to the same unit. if unit is None: unit = value[0].unit value = [q.to_value(unit) for q in value] value_unit = unit # signal below that conversion has been done elif (dtype is None and not hasattr(value, 'dtype') and isinstance(unit, StructuredUnit)): # Special case for list/tuple of values and a structured unit: # ``np.array(value, dtype=None)`` would treat tuples as lower # levels of the array, rather than as elements of a structured # array, so we use the structure of the unit to help infer the # structured dtype of the value. dtype = unit._recursively_get_dtype(value) if value_unit is None: # If the value has a `unit` attribute and if not None # (for Columns with uninitialized unit), treat it like a quantity. value_unit = getattr(value, 'unit', None) if value_unit is None: # Default to dimensionless for no (initialized) unit attribute. if unit is None: unit = cls._default_unit value_unit = unit # signal below that no conversion is needed else: try: value_unit = Unit(value_unit) except Exception as exc: raise TypeError("The unit attribute {!r} of the input could " "not be parsed as an astropy Unit, raising " "the following exception:\n{}" .format(value.unit, exc)) if unit is None: unit = value_unit elif unit is not value_unit: copy = False # copy will be made in conversion at end value = np.array(value, dtype=dtype, copy=copy, order=order, subok=True, ndmin=ndmin) # check that array contains numbers or long int objects if (value.dtype.kind in 'OSU' and not (value.dtype.kind == 'O' and isinstance(value.item(0), numbers.Number))): raise TypeError("The value must be a valid Python or " "Numpy numeric type.") # by default, cast any integer, boolean, etc., to float if dtype is None and value.dtype.kind in 'iuO': value = value.astype(float) # if we allow subclasses, allow a class from the unit. if subok: qcls = getattr(unit, '_quantity_class', cls) if issubclass(qcls, cls): cls = qcls value = value.view(cls) value._set_unit(value_unit) if unit is value_unit: return value else: # here we had non-Quantity input that had a "unit" attribute # with a unit different from the desired one. So, convert. return value.to(unit) def __array_finalize__(self, obj): # Check whether super().__array_finalize should be called # (sadly, ndarray.__array_finalize__ is None; we cannot be sure # what is above us). super_array_finalize = super().__array_finalize__ if super_array_finalize is not None: super_array_finalize(obj) # If we're a new object or viewing an ndarray, nothing has to be done. if obj is None or obj.__class__ is np.ndarray: return # If our unit is not set and obj has a valid one, use it. if self._unit is None: unit = getattr(obj, '_unit', None) if unit is not None: self._set_unit(unit) # Copy info if the original had `info` defined. Because of the way the # DataInfo works, `'info' in obj.__dict__` is False until the # `info` attribute is accessed or set. if 'info' in obj.__dict__: self.info = obj.info def __array_wrap__(self, obj, context=None): if context is None: # Methods like .squeeze() created a new `ndarray` and then call # __array_wrap__ to turn the array into self's subclass. return self._new_view(obj) raise NotImplementedError('__array_wrap__ should not be used ' 'with a context any more since all use ' 'should go through array_function. ' 'Please raise an issue on ' 'https://github.com/astropy/astropy') def __array_ufunc__(self, function, method, *inputs, **kwargs): """Wrap numpy ufuncs, taking care of units. Parameters ---------- function : callable ufunc to wrap. method : str Ufunc method: ``__call__``, ``at``, ``reduce``, etc. inputs : tuple Input arrays. kwargs : keyword arguments As passed on, with ``out`` containing possible quantity output. Returns ------- result : `~astropy.units.Quantity` Results of the ufunc, with the unit set properly. """ # Determine required conversion functions -- to bring the unit of the # input to that expected (e.g., radian for np.sin), or to get # consistent units between two inputs (e.g., in np.add) -- # and the unit of the result (or tuple of units for nout > 1). converters, unit = converters_and_unit(function, method, *inputs) out = kwargs.get('out', None) # Avoid loop back by turning any Quantity output into array views. if out is not None: # If pre-allocated output is used, check it is suitable. # This also returns array view, to ensure we don't loop back. if function.nout == 1: out = out[0] out_array = check_output(out, unit, inputs, function=function) # Ensure output argument remains a tuple. kwargs['out'] = (out_array,) if function.nout == 1 else out_array # Same for inputs, but here also convert if necessary. arrays = [] for input_, converter in zip(inputs, converters): input_ = getattr(input_, 'value', input_) arrays.append(converter(input_) if converter else input_) # Call our superclass's __array_ufunc__ result = super().__array_ufunc__(function, method, *arrays, **kwargs) # If unit is None, a plain array is expected (e.g., comparisons), which # means we're done. # We're also done if the result was None (for method 'at') or # NotImplemented, which can happen if other inputs/outputs override # __array_ufunc__; hopefully, they can then deal with us. if unit is None or result is None or result is NotImplemented: return result return self._result_as_quantity(result, unit, out) def _result_as_quantity(self, result, unit, out): """Turn result into a quantity with the given unit. If no output is given, it will take a view of the array as a quantity, and set the unit. If output is given, those should be quantity views of the result arrays, and the function will just set the unit. Parameters ---------- result : ndarray or tuple thereof Array(s) which need to be turned into quantity. unit : `~astropy.units.Unit` Unit for the quantities to be returned (or `None` if the result should not be a quantity). Should be tuple if result is a tuple. out : `~astropy.units.Quantity` or None Possible output quantity. Should be `None` or a tuple if result is a tuple. Returns ------- out : `~astropy.units.Quantity` With units set. """ if isinstance(result, (tuple, list)): if out is None: out = (None,) * len(result) return result.__class__( self._result_as_quantity(result_, unit_, out_) for (result_, unit_, out_) in zip(result, unit, out)) if out is None: # View the result array as a Quantity with the proper unit. return result if unit is None else self._new_view(result, unit) # For given output, just set the unit. We know the unit is not None and # the output is of the correct Quantity subclass, as it was passed # through check_output. out._set_unit(unit) return out def __quantity_subclass__(self, unit): """ Overridden by subclasses to change what kind of view is created based on the output unit of an operation. Parameters ---------- unit : UnitBase The unit for which the appropriate class should be returned Returns ------- tuple : - `~astropy.units.Quantity` subclass - bool: True if subclasses of the given class are ok """ return Quantity, True def _new_view(self, obj=None, unit=None): """ Create a Quantity view of some array-like input, and set the unit By default, return a view of ``obj`` of the same class as ``self`` and with the same unit. Subclasses can override the type of class for a given unit using ``__quantity_subclass__``, and can ensure properties other than the unit are copied using ``__array_finalize__``. If the given unit defines a ``_quantity_class`` of which ``self`` is not an instance, a view using this class is taken. Parameters ---------- obj : ndarray or scalar, optional The array to create a view of. If obj is a numpy or python scalar, it will be converted to an array scalar. By default, ``self`` is converted. unit : unit-like, optional The unit of the resulting object. It is used to select a subclass, and explicitly assigned to the view if given. If not given, the subclass and unit will be that of ``self``. Returns ------- view : `~astropy.units.Quantity` subclass """ # Determine the unit and quantity subclass that we need for the view. if unit is None: unit = self.unit quantity_subclass = self.__class__ elif unit is self.unit and self.__class__ is Quantity: # The second part is because we should not presume what other # classes want to do for the same unit. E.g., Constant will # always want to fall back to Quantity, and relies on going # through `__quantity_subclass__`. quantity_subclass = Quantity else: unit = Unit(unit) quantity_subclass = getattr(unit, '_quantity_class', Quantity) if isinstance(self, quantity_subclass): quantity_subclass, subok = self.__quantity_subclass__(unit) if subok: quantity_subclass = self.__class__ # We only want to propagate information from ``self`` to our new view, # so obj should be a regular array. By using ``np.array``, we also # convert python and numpy scalars, which cannot be viewed as arrays # and thus not as Quantity either, to zero-dimensional arrays. # (These are turned back into scalar in `.value`) # Note that for an ndarray input, the np.array call takes only double # ``obj.__class is np.ndarray``. So, not worth special-casing. if obj is None: obj = self.view(np.ndarray) else: obj = np.array(obj, copy=False, subok=True) # Take the view, set the unit, and update possible other properties # such as ``info``, ``wrap_angle`` in `Longitude`, etc. view = obj.view(quantity_subclass) view._set_unit(unit) view.__array_finalize__(self) return view def _set_unit(self, unit): """Set the unit. This is used anywhere the unit is set or modified, i.e., in the initilizer, in ``__imul__`` and ``__itruediv__`` for in-place multiplication and division by another unit, as well as in ``__array_finalize__`` for wrapping up views. For Quantity, it just sets the unit, but subclasses can override it to check that, e.g., a unit is consistent. """ if not isinstance(unit, UnitBase): if (isinstance(self._unit, StructuredUnit) or isinstance(unit, StructuredUnit)): unit = StructuredUnit(unit, self.dtype) else: # Trying to go through a string ensures that, e.g., Magnitudes with # dimensionless physical unit become Quantity with units of mag. unit = Unit(str(unit), parse_strict='silent') if not isinstance(unit, (UnitBase, StructuredUnit)): raise UnitTypeError( "{} instances require normal units, not {} instances." .format(type(self).__name__, type(unit))) self._unit = unit def __deepcopy__(self, memo): # If we don't define this, ``copy.deepcopy(quantity)`` will # return a bare Numpy array. return self.copy() def __reduce__(self): # patch to pickle Quantity objects (ndarray subclasses), see # http://www.mail-archive.com/numpy-discussion@scipy.org/msg02446.html object_state = list(super().__reduce__()) object_state[2] = (object_state[2], self.__dict__) return tuple(object_state) def __setstate__(self, state): # patch to unpickle Quantity objects (ndarray subclasses), see # http://www.mail-archive.com/numpy-discussion@scipy.org/msg02446.html nd_state, own_state = state super().__setstate__(nd_state) self.__dict__.update(own_state) info = QuantityInfo() def _to_value(self, unit, equivalencies=[]): """Helper method for to and to_value.""" if equivalencies == []: equivalencies = self._equivalencies if not self.dtype.names or isinstance(self.unit, StructuredUnit): # Standard path, let unit to do work. return self.unit.to(unit, self.view(np.ndarray), equivalencies=equivalencies) else: # The .to() method of a simple unit cannot convert a structured # dtype, so we work around it, by recursing. # TODO: deprecate this? # Convert simple to Structured on initialization? result = np.empty_like(self.view(np.ndarray)) for name in self.dtype.names: result[name] = self[name]._to_value(unit, equivalencies) return result def to(self, unit, equivalencies=[], copy=True): """ Return a new `~astropy.units.Quantity` object with the specified unit. Parameters ---------- unit : unit-like An object that represents the unit to convert to. Must be an `~astropy.units.UnitBase` object or a string parseable by the `~astropy.units` package. equivalencies : list of tuple A list of equivalence pairs to try if the units are not directly convertible. See :ref:`astropy:unit_equivalencies`. If not provided or ``[]``, class default equivalencies will be used (none for `~astropy.units.Quantity`, but may be set for subclasses) If `None`, no equivalencies will be applied at all, not even any set globally or within a context. copy : bool, optional If `True` (default), then the value is copied. Otherwise, a copy will only be made if necessary. See also -------- to_value : get the numerical value in a given unit. """ # We don't use `to_value` below since we always want to make a copy # and don't want to slow down this method (esp. the scalar case). unit = Unit(unit) if copy: # Avoid using to_value to ensure that we make a copy. We also # don't want to slow down this method (esp. the scalar case). value = self._to_value(unit, equivalencies) else: # to_value only copies if necessary value = self.to_value(unit, equivalencies) return self._new_view(value, unit) def to_value(self, unit=None, equivalencies=[]): """ The numerical value, possibly in a different unit. Parameters ---------- unit : unit-like, optional The unit in which the value should be given. If not given or `None`, use the current unit. equivalencies : list of tuple, optional A list of equivalence pairs to try if the units are not directly convertible (see :ref:`astropy:unit_equivalencies`). If not provided or ``[]``, class default equivalencies will be used (none for `~astropy.units.Quantity`, but may be set for subclasses). If `None`, no equivalencies will be applied at all, not even any set globally or within a context. Returns ------- value : ndarray or scalar The value in the units specified. For arrays, this will be a view of the data if no unit conversion was necessary. See also -------- to : Get a new instance in a different unit. """ if unit is None or unit is self.unit: value = self.view(np.ndarray) elif not self.dtype.names: # For non-structured, we attempt a short-cut, where we just get # the scale. If that is 1, we do not have to do anything. unit = Unit(unit) # We want a view if the unit does not change. One could check # with "==", but that calculates the scale that we need anyway. # TODO: would be better for `unit.to` to have an in-place flag. try: scale = self.unit._to(unit) except Exception: # Short-cut failed; try default (maybe equivalencies help). value = self._to_value(unit, equivalencies) else: value = self.view(np.ndarray) if not is_effectively_unity(scale): # not in-place! value = value * scale else: # For structured arrays, we go the default route. value = self._to_value(unit, equivalencies) # Index with empty tuple to decay array scalars in to numpy scalars. return value if value.shape else value[()] value = property(to_value, doc="""The numerical value of this instance. See also -------- to_value : Get the numerical value in a given unit. """) @property def unit(self): """ A `~astropy.units.UnitBase` object representing the unit of this quantity. """ return self._unit @property def equivalencies(self): """ A list of equivalencies that will be applied by default during unit conversions. """ return self._equivalencies def _recursively_apply(self, func): """Apply function recursively to every field. Returns a copy with the result. """ result = np.empty_like(self) result_value = result.view(np.ndarray) result_unit = () for name in self.dtype.names: part = func(self[name]) result_value[name] = part.value result_unit += (part.unit,) result._set_unit(result_unit) return result @property def si(self): """ Returns a copy of the current `Quantity` instance with SI units. The value of the resulting object will be scaled. """ if self.dtype.names: return self._recursively_apply(operator.attrgetter('si')) si_unit = self.unit.si return self._new_view(self.value * si_unit.scale, si_unit / si_unit.scale) @property def cgs(self): """ Returns a copy of the current `Quantity` instance with CGS units. The value of the resulting object will be scaled. """ if self.dtype.names: return self._recursively_apply(operator.attrgetter('cgs')) cgs_unit = self.unit.cgs return self._new_view(self.value * cgs_unit.scale, cgs_unit / cgs_unit.scale) @property def isscalar(self): """ True if the `value` of this quantity is a scalar, or False if it is an array-like object. .. note:: This is subtly different from `numpy.isscalar` in that `numpy.isscalar` returns False for a zero-dimensional array (e.g. ``np.array(1)``), while this is True for quantities, since quantities cannot represent true numpy scalars. """ return not self.shape # This flag controls whether convenience conversion members, such # as `q.m` equivalent to `q.to_value(u.m)` are available. This is # not turned on on Quantity itself, but is on some subclasses of # Quantity, such as `astropy.coordinates.Angle`. _include_easy_conversion_members = False @override__dir__ def __dir__(self): """ Quantities are able to directly convert to other units that have the same physical type. This function is implemented in order to make autocompletion still work correctly in IPython. """ if not self._include_easy_conversion_members: return [] extra_members = set() equivalencies = Unit._normalize_equivalencies(self.equivalencies) for equivalent in self.unit._get_units_with_same_physical_type( equivalencies): extra_members.update(equivalent.names) return extra_members def __getattr__(self, attr): """ Quantities are able to directly convert to other units that have the same physical type. """ if not self._include_easy_conversion_members: raise AttributeError( f"'{self.__class__.__name__}' object has no '{attr}' member") def get_virtual_unit_attribute(): registry = get_current_unit_registry().registry to_unit = registry.get(attr, None) if to_unit is None: return None try: return self.unit.to( to_unit, self.value, equivalencies=self.equivalencies) except UnitsError: return None value = get_virtual_unit_attribute() if value is None: raise AttributeError( f"{self.__class__.__name__} instance has no attribute '{attr}'") else: return value # Equality needs to be handled explicitly as ndarray.__eq__ gives # DeprecationWarnings on any error, which is distracting, and does not # deal well with structured arrays (nor does the ufunc). def __eq__(self, other): try: other_value = self._to_own_unit(other) except UnitsError: return False except Exception: return NotImplemented return self.value.__eq__(other_value) def __ne__(self, other): try: other_value = self._to_own_unit(other) except UnitsError: return True except Exception: return NotImplemented return self.value.__ne__(other_value) # Unit conversion operator (<<). def __lshift__(self, other): try: other = Unit(other, parse_strict='silent') except UnitTypeError: return NotImplemented return self.__class__(self, other, copy=False, subok=True) def __ilshift__(self, other): try: other = Unit(other, parse_strict='silent') except UnitTypeError: return NotImplemented try: factor = self.unit._to(other) except Exception: # Maybe via equivalencies? Now we do make a temporary copy. try: value = self._to_value(other) except UnitConversionError: return NotImplemented self.view(np.ndarray)[...] = value else: self.view(np.ndarray)[...] *= factor self._set_unit(other) return self def __rlshift__(self, other): if not self.isscalar: return NotImplemented return Unit(self).__rlshift__(other) # Give warning for other >> self, since probably other << self was meant. def __rrshift__(self, other): warnings.warn(">> is not implemented. Did you mean to convert " "something to this quantity as a unit using '<<'?", AstropyWarning) return NotImplemented # Also define __rshift__ and __irshift__ so we override default ndarray # behaviour, but instead of emitting a warning here, let it be done by # other (which likely is a unit if this was a mistake). def __rshift__(self, other): return NotImplemented def __irshift__(self, other): return NotImplemented # Arithmetic operations def __mul__(self, other): """ Multiplication between `Quantity` objects and other objects.""" if isinstance(other, (UnitBase, str)): try: return self._new_view(self.copy(), other * self.unit) except UnitsError: # let other try to deal with it return NotImplemented return super().__mul__(other) def __imul__(self, other): """In-place multiplication between `Quantity` objects and others.""" if isinstance(other, (UnitBase, str)): self._set_unit(other * self.unit) return self return super().__imul__(other) def __rmul__(self, other): """ Right Multiplication between `Quantity` objects and other objects. """ return self.__mul__(other) def __truediv__(self, other): """ Division between `Quantity` objects and other objects.""" if isinstance(other, (UnitBase, str)): try: return self._new_view(self.copy(), self.unit / other) except UnitsError: # let other try to deal with it return NotImplemented return super().__truediv__(other) def __itruediv__(self, other): """Inplace division between `Quantity` objects and other objects.""" if isinstance(other, (UnitBase, str)): self._set_unit(self.unit / other) return self return super().__itruediv__(other) def __rtruediv__(self, other): """ Right Division between `Quantity` objects and other objects.""" if isinstance(other, (UnitBase, str)): return self._new_view(1. / self.value, other / self.unit) return super().__rtruediv__(other) def __div__(self, other): """ Division between `Quantity` objects. """ return self.__truediv__(other) def __idiv__(self, other): """ Division between `Quantity` objects. """ return self.__itruediv__(other) def __rdiv__(self, other): """ Division between `Quantity` objects. """ return self.__rtruediv__(other) def __pow__(self, other): if isinstance(other, Fraction): # Avoid getting object arrays by raising the value to a Fraction. return self._new_view(self.value ** float(other), self.unit ** other) return super().__pow__(other) # other overrides of special functions def __hash__(self): return hash(self.value) ^ hash(self.unit) def __iter__(self): if self.isscalar: raise TypeError( "'{cls}' object with a scalar value is not iterable" .format(cls=self.__class__.__name__)) # Otherwise return a generator def quantity_iter(): for val in self.value: yield self._new_view(val) return quantity_iter() def __getitem__(self, key): if isinstance(key, str) and isinstance(self.unit, StructuredUnit): return self._new_view(self.view(np.ndarray)[key], self.unit[key]) try: out = super().__getitem__(key) except IndexError: # We want zero-dimensional Quantity objects to behave like scalars, # so they should raise a TypeError rather than an IndexError. if self.isscalar: raise TypeError( "'{cls}' object with a scalar value does not support " "indexing".format(cls=self.__class__.__name__)) else: raise # For single elements, ndarray.__getitem__ returns scalars; these # need a new view as a Quantity. if not isinstance(out, np.ndarray): out = self._new_view(out) return out def __setitem__(self, i, value): if isinstance(i, str): # Indexing will cause a different unit, so by doing this in # two steps we effectively try with the right unit. self[i][...] = value return # update indices in info if the info property has been accessed # (in which case 'info' in self.__dict__ is True; this is guaranteed # to be the case if we're part of a table). if not self.isscalar and 'info' in self.__dict__: self.info.adjust_indices(i, value, len(self)) self.view(np.ndarray).__setitem__(i, self._to_own_unit(value)) # __contains__ is OK def __bool__(self): """Quantities should always be treated as non-False; there is too much potential for ambiguity otherwise. """ warnings.warn('The truth value of a Quantity is ambiguous. ' 'In the future this will raise a ValueError.', AstropyDeprecationWarning) return True def __len__(self): if self.isscalar: raise TypeError("'{cls}' object with a scalar value has no " "len()".format(cls=self.__class__.__name__)) else: return len(self.value) # Numerical types def __float__(self): try: return float(self.to_value(dimensionless_unscaled)) except (UnitsError, TypeError): raise TypeError('only dimensionless scalar quantities can be ' 'converted to Python scalars') def __int__(self): try: return int(self.to_value(dimensionless_unscaled)) except (UnitsError, TypeError): raise TypeError('only dimensionless scalar quantities can be ' 'converted to Python scalars') def __index__(self): # for indices, we do not want to mess around with scaling at all, # so unlike for float, int, we insist here on unscaled dimensionless try: assert self.unit.is_unity() return self.value.__index__() except Exception: raise TypeError('only integer dimensionless scalar quantities ' 'can be converted to a Python index') # TODO: we may want to add a hook for dimensionless quantities? @property def _unitstr(self): if self.unit is None: unitstr = _UNIT_NOT_INITIALISED else: unitstr = str(self.unit) if unitstr: unitstr = ' ' + unitstr return unitstr def to_string(self, unit=None, precision=None, format=None, subfmt=None): """ Generate a string representation of the quantity and its unit. The behavior of this function can be altered via the `numpy.set_printoptions` function and its various keywords. The exception to this is the ``threshold`` keyword, which is controlled via the ``[units.quantity]`` configuration item ``latex_array_threshold``. This is treated separately because the numpy default of 1000 is too big for most browsers to handle. Parameters ---------- unit : unit-like, optional Specifies the unit. If not provided, the unit used to initialize the quantity will be used. precision : number, optional The level of decimal precision. If `None`, or not provided, it will be determined from NumPy print options. format : str, optional The format of the result. If not provided, an unadorned string is returned. Supported values are: - 'latex': Return a LaTeX-formatted string subfmt : str, optional Subformat of the result. For the moment, only used for format="latex". Supported values are: - 'inline': Use ``$ ... $`` as delimiters. - 'display': Use ``$\\displaystyle ... $`` as delimiters. Returns ------- str A string with the contents of this Quantity """ if unit is not None and unit != self.unit: return self.to(unit).to_string( unit=None, precision=precision, format=format, subfmt=subfmt) formats = { None: None, "latex": { None: ("$", "$"), "inline": ("$", "$"), "display": (r"$\displaystyle ", r"$"), }, } if format not in formats: raise ValueError(f"Unknown format '{format}'") elif format is None: if precision is None: # Use default formatting settings return f'{self.value}{self._unitstr:s}' else: # np.array2string properly formats arrays as well as scalars return np.array2string(self.value, precision=precision, floatmode="fixed") + self._unitstr # else, for the moment we assume format="latex" # need to do try/finally because "threshold" cannot be overridden # with array2string # Set the precision if set, otherwise use numpy default pops = np.get_printoptions() format_spec = f".{precision if precision is not None else pops['precision']}g" def float_formatter(value): return Latex.format_exponential_notation(value, format_spec=format_spec) def complex_formatter(value): return '({}{}i)'.format( Latex.format_exponential_notation(value.real, format_spec=format_spec), Latex.format_exponential_notation(value.imag, format_spec='+' + format_spec)) try: formatter = {'float_kind': float_formatter, 'complex_kind': complex_formatter} if conf.latex_array_threshold > -1: np.set_printoptions(threshold=conf.latex_array_threshold) # the view is needed for the scalar case - value might be float latex_value = np.array2string( self.view(np.ndarray), formatter=formatter, max_line_width=np.inf, separator=',~') latex_value = latex_value.replace('...', r'\dots') finally: np.set_printoptions(**pops) # Format unit # [1:-1] strips the '$' on either side needed for math mode latex_unit = (self.unit._repr_latex_()[1:-1] # note this is unicode if self.unit is not None else _UNIT_NOT_INITIALISED) delimiter_left, delimiter_right = formats[format][subfmt] return r'{left}{0} \; {1}{right}'.format(latex_value, latex_unit, left=delimiter_left, right=delimiter_right) def __str__(self): return self.to_string() def __repr__(self): prefixstr = '<' + self.__class__.__name__ + ' ' arrstr = np.array2string(self.view(np.ndarray), separator=', ', prefix=prefixstr) return f'{prefixstr}{arrstr}{self._unitstr:s}>' def _repr_latex_(self): """ Generate a latex representation of the quantity and its unit. Returns ------- lstr A LaTeX string with the contents of this Quantity """ # NOTE: This should change to display format in a future release return self.to_string(format='latex', subfmt='inline') def __format__(self, format_spec): """ Format quantities using the new-style python formatting codes as specifiers for the number. If the format specifier correctly applies itself to the value, then it is used to format only the value. If it cannot be applied to the value, then it is applied to the whole string. """ try: value = format(self.value, format_spec) full_format_spec = "s" except ValueError: value = self.value full_format_spec = format_spec return format(f"{value}{self._unitstr:s}", full_format_spec) def decompose(self, bases=[]): """ Generates a new `Quantity` with the units decomposed. Decomposed units have only irreducible units in them (see `astropy.units.UnitBase.decompose`). Parameters ---------- bases : sequence of `~astropy.units.UnitBase`, optional The bases to decompose into. When not provided, decomposes down to any irreducible units. When provided, the decomposed result will only contain the given units. This will raises a `~astropy.units.UnitsError` if it's not possible to do so. Returns ------- newq : `~astropy.units.Quantity` A new object equal to this quantity with units decomposed. """ return self._decompose(False, bases=bases) def _decompose(self, allowscaledunits=False, bases=[]): """ Generates a new `Quantity` with the units decomposed. Decomposed units have only irreducible units in them (see `astropy.units.UnitBase.decompose`). Parameters ---------- allowscaledunits : bool If True, the resulting `Quantity` may have a scale factor associated with it. If False, any scaling in the unit will be subsumed into the value of the resulting `Quantity` bases : sequence of UnitBase, optional The bases to decompose into. When not provided, decomposes down to any irreducible units. When provided, the decomposed result will only contain the given units. This will raises a `~astropy.units.UnitsError` if it's not possible to do so. Returns ------- newq : `~astropy.units.Quantity` A new object equal to this quantity with units decomposed. """ new_unit = self.unit.decompose(bases=bases) # Be careful here because self.value usually is a view of self; # be sure that the original value is not being modified. if not allowscaledunits and hasattr(new_unit, 'scale'): new_value = self.value * new_unit.scale new_unit = new_unit / new_unit.scale return self._new_view(new_value, new_unit) else: return self._new_view(self.copy(), new_unit) # These functions need to be overridden to take into account the units # Array conversion # https://numpy.org/doc/stable/reference/arrays.ndarray.html#array-conversion def item(self, *args): """Copy an element of an array to a scalar Quantity and return it. Like :meth:`~numpy.ndarray.item` except that it always returns a `Quantity`, not a Python scalar. """ return self._new_view(super().item(*args)) def tolist(self): raise NotImplementedError("cannot make a list of Quantities. Get " "list of values with q.value.tolist()") def _to_own_unit(self, value, check_precision=True): try: _value = value.to_value(self.unit) except AttributeError: # We're not a Quantity. # First remove two special cases (with a fast test): # 1) Maybe masked printing? MaskedArray with quantities does not # work very well, but no reason to break even repr and str. # 2) np.ma.masked? useful if we're a MaskedQuantity. if (value is np.ma.masked or (value is np.ma.masked_print_option and self.dtype.kind == 'O')): return value # Now, let's try a more general conversion. # Plain arrays will be converted to dimensionless in the process, # but anything with a unit attribute will use that. try: as_quantity = Quantity(value) _value = as_quantity.to_value(self.unit) except UnitsError: # last chance: if this was not something with a unit # and is all 0, inf, or nan, we treat it as arbitrary unit. if (not hasattr(value, 'unit') and can_have_arbitrary_unit(as_quantity.value)): _value = as_quantity.value else: raise if self.dtype.kind == 'i' and check_precision: # If, e.g., we are casting float to int, we want to fail if # precision is lost, but let things pass if it works. _value = np.array(_value, copy=False, subok=True) if not np.can_cast(_value.dtype, self.dtype): self_dtype_array = np.array(_value, self.dtype, subok=True) if not np.all(np.logical_or(self_dtype_array == _value, np.isnan(_value))): raise TypeError("cannot convert value type to array type " "without precision loss") # Setting names to ensure things like equality work (note that # above will have failed already if units did not match). if self.dtype.names: _value.dtype.names = self.dtype.names return _value def itemset(self, *args): if len(args) == 0: raise ValueError("itemset must have at least one argument") self.view(np.ndarray).itemset(*(args[:-1] + (self._to_own_unit(args[-1]),))) def tostring(self, order='C'): raise NotImplementedError("cannot write Quantities to string. Write " "array with q.value.tostring(...).") def tobytes(self, order='C'): raise NotImplementedError("cannot write Quantities to string. Write " "array with q.value.tobytes(...).") def tofile(self, fid, sep="", format="%s"): raise NotImplementedError("cannot write Quantities to file. Write " "array with q.value.tofile(...)") def dump(self, file): raise NotImplementedError("cannot dump Quantities to file. Write " "array with q.value.dump()") def dumps(self): raise NotImplementedError("cannot dump Quantities to string. Write " "array with q.value.dumps()") # astype, byteswap, copy, view, getfield, setflags OK as is def fill(self, value): self.view(np.ndarray).fill(self._to_own_unit(value)) # Shape manipulation: resize cannot be done (does not own data), but # shape, transpose, swapaxes, flatten, ravel, squeeze all OK. Only # the flat iterator needs to be overwritten, otherwise single items are # returned as numbers. @property def flat(self): """A 1-D iterator over the Quantity array. This returns a ``QuantityIterator`` instance, which behaves the same as the `~numpy.flatiter` instance returned by `~numpy.ndarray.flat`, and is similar to, but not a subclass of, Python's built-in iterator object. """ return QuantityIterator(self) @flat.setter def flat(self, value): y = self.ravel() y[:] = value # Item selection and manipulation # repeat, sort, compress, diagonal OK def take(self, indices, axis=None, out=None, mode='raise'): out = super().take(indices, axis=axis, out=out, mode=mode) # For single elements, ndarray.take returns scalars; these # need a new view as a Quantity. if type(out) is not type(self): out = self._new_view(out) return out def put(self, indices, values, mode='raise'): self.view(np.ndarray).put(indices, self._to_own_unit(values), mode) def choose(self, choices, out=None, mode='raise'): raise NotImplementedError("cannot choose based on quantity. Choose " "using array with q.value.choose(...)") # ensure we do not return indices as quantities def argsort(self, axis=-1, kind='quicksort', order=None): return self.view(np.ndarray).argsort(axis=axis, kind=kind, order=order) def searchsorted(self, v, *args, **kwargs): return np.searchsorted(np.array(self), self._to_own_unit(v, check_precision=False), *args, **kwargs) # avoid numpy 1.6 problem def argmax(self, axis=None, out=None): return self.view(np.ndarray).argmax(axis, out=out) def argmin(self, axis=None, out=None): return self.view(np.ndarray).argmin(axis, out=out) def __array_function__(self, function, types, args, kwargs): """Wrap numpy functions, taking care of units. Parameters ---------- function : callable Numpy function to wrap types : iterable of classes Classes that provide an ``__array_function__`` override. Can in principle be used to interact with other classes. Below, mostly passed on to `~numpy.ndarray`, which can only interact with subclasses. args : tuple Positional arguments provided in the function call. kwargs : dict Keyword arguments provided in the function call. Returns ------- result: `~astropy.units.Quantity`, `~numpy.ndarray` As appropriate for the function. If the function is not supported, `NotImplemented` is returned, which will lead to a `TypeError` unless another argument overrode the function. Raises ------ ~astropy.units.UnitsError If operands have incompatible units. """ # A function should be in one of the following sets or dicts: # 1. SUBCLASS_SAFE_FUNCTIONS (set), if the numpy implementation # supports Quantity; we pass on to ndarray.__array_function__. # 2. FUNCTION_HELPERS (dict), if the numpy implementation is usable # after converting quantities to arrays with suitable units, # and possibly setting units on the result. # 3. DISPATCHED_FUNCTIONS (dict), if the function makes sense but # requires a Quantity-specific implementation. # 4. UNSUPPORTED_FUNCTIONS (set), if the function does not make sense. # For now, since we may not yet have complete coverage, if a # function is in none of the above, we simply call the numpy # implementation. if function in SUBCLASS_SAFE_FUNCTIONS: return super().__array_function__(function, types, args, kwargs) elif function in FUNCTION_HELPERS: function_helper = FUNCTION_HELPERS[function] try: args, kwargs, unit, out = function_helper(*args, **kwargs) except NotImplementedError: return self._not_implemented_or_raise(function, types) result = super().__array_function__(function, types, args, kwargs) # Fall through to return section elif function in DISPATCHED_FUNCTIONS: dispatched_function = DISPATCHED_FUNCTIONS[function] try: result, unit, out = dispatched_function(*args, **kwargs) except NotImplementedError: return self._not_implemented_or_raise(function, types) # Fall through to return section elif function in UNSUPPORTED_FUNCTIONS: return NotImplemented else: warnings.warn("function '{}' is not known to astropy's Quantity. " "Will run it anyway, hoping it will treat ndarray " "subclasses correctly. Please raise an issue at " "https://github.com/astropy/astropy/issues. " .format(function.__name__), AstropyWarning) return super().__array_function__(function, types, args, kwargs) # If unit is None, a plain array is expected (e.g., boolean), which # means we're done. # We're also done if the result was NotImplemented, which can happen # if other inputs/outputs override __array_function__; # hopefully, they can then deal with us. if unit is None or result is NotImplemented: return result return self._result_as_quantity(result, unit, out=out) def _not_implemented_or_raise(self, function, types): # Our function helper or dispatcher found that the function does not # work with Quantity. In principle, there may be another class that # knows what to do with us, for which we should return NotImplemented. # But if there is ndarray (or a non-Quantity subclass of it) around, # it quite likely coerces, so we should just break. if any(issubclass(t, np.ndarray) and not issubclass(t, Quantity) for t in types): raise TypeError("the Quantity implementation cannot handle {} " "with the given arguments." .format(function)) from None else: return NotImplemented # Calculation -- override ndarray methods to take into account units. # We use the corresponding numpy functions to evaluate the results, since # the methods do not always allow calling with keyword arguments. # For instance, np.array([0.,2.]).clip(a_min=0., a_max=1.) gives # TypeError: 'a_max' is an invalid keyword argument for this function. def _wrap_function(self, function, *args, unit=None, out=None, **kwargs): """Wrap a numpy function that processes self, returning a Quantity. Parameters ---------- function : callable Numpy function to wrap. args : positional arguments Any positional arguments to the function beyond the first argument (which will be set to ``self``). kwargs : keyword arguments Keyword arguments to the function. If present, the following arguments are treated specially: unit : `~astropy.units.Unit` Unit of the output result. If not given, the unit of ``self``. out : `~astropy.units.Quantity` A Quantity instance in which to store the output. Notes ----- Output should always be assigned via a keyword argument, otherwise no proper account of the unit is taken. Returns ------- out : `~astropy.units.Quantity` Result of the function call, with the unit set properly. """ if unit is None: unit = self.unit # Ensure we don't loop back by turning any Quantity into array views. args = (self.value,) + tuple((arg.value if isinstance(arg, Quantity) else arg) for arg in args) if out is not None: # If pre-allocated output is used, check it is suitable. # This also returns array view, to ensure we don't loop back. arrays = tuple(arg for arg in args if isinstance(arg, np.ndarray)) kwargs['out'] = check_output(out, unit, arrays, function=function) # Apply the function and turn it back into a Quantity. result = function(*args, **kwargs) return self._result_as_quantity(result, unit, out) def trace(self, offset=0, axis1=0, axis2=1, dtype=None, out=None): return self._wrap_function(np.trace, offset, axis1, axis2, dtype, out=out) def var(self, axis=None, dtype=None, out=None, ddof=0, keepdims=False): return self._wrap_function(np.var, axis, dtype, out=out, ddof=ddof, keepdims=keepdims, unit=self.unit**2) def std(self, axis=None, dtype=None, out=None, ddof=0, keepdims=False): return self._wrap_function(np.std, axis, dtype, out=out, ddof=ddof, keepdims=keepdims) def mean(self, axis=None, dtype=None, out=None, keepdims=False): return self._wrap_function(np.mean, axis, dtype, out=out, keepdims=keepdims) def round(self, decimals=0, out=None): return self._wrap_function(np.round, decimals, out=out) def dot(self, b, out=None): result_unit = self.unit * getattr(b, 'unit', dimensionless_unscaled) return self._wrap_function(np.dot, b, out=out, unit=result_unit) # Calculation: override methods that do not make sense. def all(self, axis=None, out=None): raise TypeError("cannot evaluate truth value of quantities. " "Evaluate array with q.value.all(...)") def any(self, axis=None, out=None): raise TypeError("cannot evaluate truth value of quantities. " "Evaluate array with q.value.any(...)") # Calculation: numpy functions that can be overridden with methods. def diff(self, n=1, axis=-1): return self._wrap_function(np.diff, n, axis) def ediff1d(self, to_end=None, to_begin=None): return self._wrap_function(np.ediff1d, to_end, to_begin) def nansum(self, axis=None, out=None, keepdims=False): return self._wrap_function(np.nansum, axis, out=out, keepdims=keepdims) def insert(self, obj, values, axis=None): """ Insert values along the given axis before the given indices and return a new `~astropy.units.Quantity` object. This is a thin wrapper around the `numpy.insert` function. Parameters ---------- obj : int, slice or sequence of int Object that defines the index or indices before which ``values`` is inserted. values : array-like Values to insert. If the type of ``values`` is different from that of quantity, ``values`` is converted to the matching type. ``values`` should be shaped so that it can be broadcast appropriately The unit of ``values`` must be consistent with this quantity. axis : int, optional Axis along which to insert ``values``. If ``axis`` is None then the quantity array is flattened before insertion. Returns ------- out : `~astropy.units.Quantity` A copy of quantity with ``values`` inserted. Note that the insertion does not occur in-place: a new quantity array is returned. Examples -------- >>> import astropy.units as u >>> q = [1, 2] * u.m >>> q.insert(0, 50 * u.cm) >>> q = [[1, 2], [3, 4]] * u.m >>> q.insert(1, [10, 20] * u.m, axis=0) >>> q.insert(1, 10 * u.m, axis=1) """ out_array = np.insert(self.value, obj, self._to_own_unit(values), axis) return self._new_view(out_array) class SpecificTypeQuantity(Quantity): """Superclass for Quantities of specific physical type. Subclasses of these work just like :class:`~astropy.units.Quantity`, except that they are for specific physical types (and may have methods that are only appropriate for that type). Astropy examples are :class:`~astropy.coordinates.Angle` and :class:`~astropy.coordinates.Distance` At a minimum, subclasses should set ``_equivalent_unit`` to the unit associated with the physical type. """ # The unit for the specific physical type. Instances can only be created # with units that are equivalent to this. _equivalent_unit = None # The default unit used for views. Even with `None`, views of arrays # without units are possible, but will have an uninitialized unit. _unit = None # Default unit for initialization through the constructor. _default_unit = None # ensure that we get precedence over our superclass. __array_priority__ = Quantity.__array_priority__ + 10 def __quantity_subclass__(self, unit): if unit.is_equivalent(self._equivalent_unit): return type(self), True else: return super().__quantity_subclass__(unit)[0], False def _set_unit(self, unit): if unit is None or not unit.is_equivalent(self._equivalent_unit): raise UnitTypeError( "{} instances require units equivalent to '{}'" .format(type(self).__name__, self._equivalent_unit) + (", but no unit was given." if unit is None else f", so cannot set it to '{unit}'.")) super()._set_unit(unit) def isclose(a, b, rtol=1.e-5, atol=None, equal_nan=False, **kwargs): """ Return a boolean array where two arrays are element-wise equal within a tolerance. Parameters ---------- a, b : array-like or `~astropy.units.Quantity` Input values or arrays to compare rtol : array-like or `~astropy.units.Quantity` The relative tolerance for the comparison, which defaults to ``1e-5``. If ``rtol`` is a :class:`~astropy.units.Quantity`, then it must be dimensionless. atol : number or `~astropy.units.Quantity` The absolute tolerance for the comparison. The units (or lack thereof) of ``a``, ``b``, and ``atol`` must be consistent with each other. If `None`, ``atol`` defaults to zero in the appropriate units. equal_nan : `bool` Whether to compare NaN’s as equal. If `True`, NaNs in ``a`` will be considered equal to NaN’s in ``b``. Notes ----- This is a :class:`~astropy.units.Quantity`-aware version of :func:`numpy.isclose`. However, this differs from the `numpy` function in that the default for the absolute tolerance here is zero instead of ``atol=1e-8`` in `numpy`, as there is no natural way to set a default *absolute* tolerance given two inputs that may have differently scaled units. Raises ------ `~astropy.units.UnitsError` If the dimensions of ``a``, ``b``, or ``atol`` are incompatible, or if ``rtol`` is not dimensionless. See also -------- allclose """ unquantified_args = _unquantify_allclose_arguments(a, b, rtol, atol) return np.isclose(*unquantified_args, equal_nan=equal_nan, **kwargs) def allclose(a, b, rtol=1.e-5, atol=None, equal_nan=False, **kwargs) -> bool: """ Whether two arrays are element-wise equal within a tolerance. Parameters ---------- a, b : array-like or `~astropy.units.Quantity` Input values or arrays to compare rtol : array-like or `~astropy.units.Quantity` The relative tolerance for the comparison, which defaults to ``1e-5``. If ``rtol`` is a :class:`~astropy.units.Quantity`, then it must be dimensionless. atol : number or `~astropy.units.Quantity` The absolute tolerance for the comparison. The units (or lack thereof) of ``a``, ``b``, and ``atol`` must be consistent with each other. If `None`, ``atol`` defaults to zero in the appropriate units. equal_nan : `bool` Whether to compare NaN’s as equal. If `True`, NaNs in ``a`` will be considered equal to NaN’s in ``b``. Notes ----- This is a :class:`~astropy.units.Quantity`-aware version of :func:`numpy.allclose`. However, this differs from the `numpy` function in that the default for the absolute tolerance here is zero instead of ``atol=1e-8`` in `numpy`, as there is no natural way to set a default *absolute* tolerance given two inputs that may have differently scaled units. Raises ------ `~astropy.units.UnitsError` If the dimensions of ``a``, ``b``, or ``atol`` are incompatible, or if ``rtol`` is not dimensionless. See also -------- isclose """ unquantified_args = _unquantify_allclose_arguments(a, b, rtol, atol) return np.allclose(*unquantified_args, equal_nan=equal_nan, **kwargs) def _unquantify_allclose_arguments(actual, desired, rtol, atol): actual = Quantity(actual, subok=True, copy=False) desired = Quantity(desired, subok=True, copy=False) try: desired = desired.to(actual.unit) except UnitsError: raise UnitsError( f"Units for 'desired' ({desired.unit}) and 'actual' " f"({actual.unit}) are not convertible" ) if atol is None: # By default, we assume an absolute tolerance of zero in the # appropriate units. The default value of None for atol is # needed because the units of atol must be consistent with the # units for a and b. atol = Quantity(0) else: atol = Quantity(atol, subok=True, copy=False) try: atol = atol.to(actual.unit) except UnitsError: raise UnitsError( f"Units for 'atol' ({atol.unit}) and 'actual' " f"({actual.unit}) are not convertible" ) rtol = Quantity(rtol, subok=True, copy=False) try: rtol = rtol.to(dimensionless_unscaled) except Exception: raise UnitsError("'rtol' should be dimensionless") return actual.value, desired.value, rtol.value, atol.value ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1832528 astropy-5.0.2/astropy/units/quantity_helper/0000755000175100001710000000000000000000000020325 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/quantity_helper/__init__.py0000644000175100001710000000111000000000000022427 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """Helper functions for Quantity. In particular, this implements the logic that determines scaling and result units for a given ufunc, given input units. """ from .converters import * # By importing helpers, all the unit conversion functions needed for # numpy ufuncs and functions are defined. from . import helpers, function_helpers # For scipy.special and erfa, importing the helper modules ensures # the definitions are added as modules to UFUNC_HELPERS, to be loaded # on demand. from . import scipy_special, erfa ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/quantity_helper/converters.py0000644000175100001710000003654000000000000023101 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """Converters for Quantity.""" import threading import numpy as np from astropy.units.core import (UnitsError, UnitConversionError, UnitTypeError, dimensionless_unscaled) __all__ = ['can_have_arbitrary_unit', 'converters_and_unit', 'check_output', 'UFUNC_HELPERS', 'UNSUPPORTED_UFUNCS'] class UfuncHelpers(dict): """Registry of unit conversion functions to help ufunc evaluation. Based on dict for quick access, but with a missing method to load helpers for additional modules such as scipy.special and erfa. Such modules should be registered using ``register_module``. """ def __init__(self, *args, **kwargs): self.modules = {} self.UNSUPPORTED = set() # Upper-case for backwards compatibility self._lock = threading.RLock() super().__init__(*args, **kwargs) def register_module(self, module, names, importer): """Register (but do not import) a set of ufunc helpers. Parameters ---------- module : str Name of the module with the ufuncs (e.g., 'scipy.special'). names : iterable of str Names of the module ufuncs for which helpers are available. importer : callable Function that imports the ufuncs and returns a dict of helpers keyed by those ufuncs. If the value is `None`, the ufunc is explicitly *not* supported. """ with self._lock: self.modules[module] = {'names': names, 'importer': importer} def import_module(self, module): """Import the helpers from the given module using its helper function. Parameters ---------- module : str Name of the module. Has to have been registered beforehand. """ with self._lock: module_info = self.modules.pop(module) self.update(module_info['importer']()) def __missing__(self, ufunc): """Called if a ufunc is not found. Check if the ufunc is in any of the available modules, and, if so, import the helpers for that module. """ with self._lock: # Check if it was loaded while we waited for the lock if ufunc in self: return self[ufunc] if ufunc in self.UNSUPPORTED: raise TypeError(f"Cannot use ufunc '{ufunc.__name__}' with quantities") for module, module_info in list(self.modules.items()): if ufunc.__name__ in module_info['names']: # A ufunc with the same name is supported by this module. # Of course, this doesn't necessarily mean it is the # right module. So, we try let the importer do its work. # If it fails (e.g., for `scipy.special`), then that's # fine, just raise the TypeError. If it succeeds, but # the ufunc is not found, that is also fine: we will # enter __missing__ again and either find another # module or get the TypeError there. try: self.import_module(module) except ImportError: # pragma: no cover pass else: return self[ufunc] raise TypeError("unknown ufunc {}. If you believe this ufunc " "should be supported, please raise an issue on " "https://github.com/astropy/astropy" .format(ufunc.__name__)) def __setitem__(self, key, value): # Implementation note: in principle, we could just let `None` # mean that something is not implemented, but this means an # extra if clause for the output, slowing down the common # path where a ufunc is supported. with self._lock: if value is None: self.UNSUPPORTED |= {key} self.pop(key, None) else: super().__setitem__(key, value) self.UNSUPPORTED -= {key} UFUNC_HELPERS = UfuncHelpers() UNSUPPORTED_UFUNCS = UFUNC_HELPERS.UNSUPPORTED def can_have_arbitrary_unit(value): """Test whether the items in value can have arbitrary units Numbers whose value does not change upon a unit change, i.e., zero, infinity, or not-a-number Parameters ---------- value : number or array Returns ------- bool `True` if each member is either zero or not finite, `False` otherwise """ return np.all(np.logical_or(np.equal(value, 0.), ~np.isfinite(value))) def converters_and_unit(function, method, *args): """Determine the required converters and the unit of the ufunc result. Converters are functions required to convert to a ufunc's expected unit, e.g., radian for np.sin; or to ensure units of two inputs are consistent, e.g., for np.add. In these examples, the unit of the result would be dimensionless_unscaled for np.sin, and the same consistent unit for np.add. Parameters ---------- function : `~numpy.ufunc` Numpy universal function method : str Method with which the function is evaluated, e.g., '__call__', 'reduce', etc. *args : `~astropy.units.Quantity` or ndarray subclass Input arguments to the function Raises ------ TypeError : when the specified function cannot be used with Quantities (e.g., np.logical_or), or when the routine does not know how to handle the specified function (in which case an issue should be raised on https://github.com/astropy/astropy). UnitTypeError : when the conversion to the required (or consistent) units is not possible. """ # Check whether we support this ufunc, by getting the helper function # (defined in helpers) which returns a list of function(s) that convert the # input(s) to the unit required for the ufunc, as well as the unit the # result will have (a tuple of units if there are multiple outputs). ufunc_helper = UFUNC_HELPERS[function] if method == '__call__' or (method == 'outer' and function.nin == 2): # Find out the units of the arguments passed to the ufunc; usually, # at least one is a quantity, but for two-argument ufuncs, the second # could also be a Numpy array, etc. These are given unit=None. units = [getattr(arg, 'unit', None) for arg in args] # Determine possible conversion functions, and the result unit. converters, result_unit = ufunc_helper(function, *units) if any(converter is False for converter in converters): # for multi-argument ufuncs with a quantity and a non-quantity, # the quantity normally needs to be dimensionless, *except* # if the non-quantity can have arbitrary unit, i.e., when it # is all zero, infinity or NaN. In that case, the non-quantity # can just have the unit of the quantity # (this allows, e.g., `q > 0.` independent of unit) try: # Don't fold this loop in the test above: this rare case # should not make the common case slower. for i, converter in enumerate(converters): if converter is not False: continue if can_have_arbitrary_unit(args[i]): converters[i] = None else: raise UnitConversionError( "Can only apply '{}' function to " "dimensionless quantities when other " "argument is not a quantity (unless the " "latter is all zero/infinity/nan)" .format(function.__name__)) except TypeError: # _can_have_arbitrary_unit failed: arg could not be compared # with zero or checked to be finite. Then, ufunc will fail too. raise TypeError("Unsupported operand type(s) for ufunc {}: " "'{}'".format(function.__name__, ','.join([arg.__class__.__name__ for arg in args]))) # In the case of np.power and np.float_power, the unit itself needs to # be modified by an amount that depends on one of the input values, # so we need to treat this as a special case. # TODO: find a better way to deal with this. if result_unit is False: if units[0] is None or units[0] == dimensionless_unscaled: result_unit = dimensionless_unscaled else: if units[1] is None: p = args[1] else: p = args[1].to(dimensionless_unscaled).value try: result_unit = units[0] ** p except ValueError as exc: # Changing the unit does not work for, e.g., array-shaped # power, but this is OK if we're (scaled) dimensionless. try: converters[0] = units[0]._get_converter( dimensionless_unscaled) except UnitConversionError: raise exc else: result_unit = dimensionless_unscaled else: # methods for which the unit should stay the same nin = function.nin unit = getattr(args[0], 'unit', None) if method == 'at' and nin <= 2: if nin == 1: units = [unit] else: units = [unit, getattr(args[2], 'unit', None)] converters, result_unit = ufunc_helper(function, *units) # ensure there is no 'converter' for indices (2nd argument) converters.insert(1, None) elif method in {'reduce', 'accumulate', 'reduceat'} and nin == 2: converters, result_unit = ufunc_helper(function, unit, unit) converters = converters[:1] if method == 'reduceat': # add 'scale' for indices (2nd argument) converters += [None] else: if method in {'reduce', 'accumulate', 'reduceat', 'outer'} and nin != 2: raise ValueError(f"{method} only supported for binary functions") raise TypeError("Unexpected ufunc method {}. If this should " "work, please raise an issue on" "https://github.com/astropy/astropy" .format(method)) # for all but __call__ method, scaling is not allowed if unit is not None and result_unit is None: raise TypeError("Cannot use '{1}' method on ufunc {0} with a " "Quantity instance as the result is not a " "Quantity.".format(function.__name__, method)) if (converters[0] is not None or (unit is not None and unit is not result_unit and (not result_unit.is_equivalent(unit) or result_unit.to(unit) != 1.))): # NOTE: this cannot be the more logical UnitTypeError, since # then things like np.cumprod will not longer fail (they check # for TypeError). raise UnitsError("Cannot use '{1}' method on ufunc {0} with a " "Quantity instance as it would change the unit." .format(function.__name__, method)) return converters, result_unit def check_output(output, unit, inputs, function=None): """Check that function output can be stored in the output array given. Parameters ---------- output : array or `~astropy.units.Quantity` or tuple Array that should hold the function output (or tuple of such arrays). unit : `~astropy.units.Unit` or None, or tuple Unit that the output will have, or `None` for pure numbers (should be tuple of same if output is a tuple of outputs). inputs : tuple Any input arguments. These should be castable to the output. function : callable The function that will be producing the output. If given, used to give a more informative error message. Returns ------- arrays : ndarray view or tuple thereof The view(s) is of ``output``. Raises ------ UnitTypeError : If ``unit`` is inconsistent with the class of ``output`` TypeError : If the ``inputs`` cannot be cast safely to ``output``. """ if isinstance(output, tuple): return tuple(check_output(output_, unit_, inputs, function) for output_, unit_ in zip(output, unit)) # ``None`` indicates no actual array is needed. This can happen, e.g., # with np.modf(a, out=(None, b)). if output is None: return None if hasattr(output, '__quantity_subclass__'): # Check that we're not trying to store a plain Numpy array or a # Quantity with an inconsistent unit (e.g., not angular for Angle). if unit is None: raise TypeError("Cannot store non-quantity output{} in {} " "instance".format( (f" from {function.__name__} function" if function is not None else ""), type(output))) q_cls, subok = output.__quantity_subclass__(unit) if not (subok or q_cls is type(output)): raise UnitTypeError( "Cannot store output with unit '{}'{} " "in {} instance. Use {} instance instead." .format(unit, (f" from {function.__name__} function" if function is not None else ""), type(output), q_cls)) # check we can handle the dtype (e.g., that we are not int # when float is required). Note that we only do this for Quantity # output; for array output, we defer to numpy's default handling. # Also, any structured dtype are ignored (likely erfa ufuncs). # TODO: make more logical; is this necessary at all? if inputs and not output.dtype.names: result_type = np.result_type(*inputs) if not (result_type.names or np.can_cast(result_type, output.dtype, casting='same_kind')): raise TypeError("Arguments cannot be cast safely to inplace " "output with dtype={}".format(output.dtype)) # Turn into ndarray, so we do not loop into array_wrap/array_ufunc # if the output is used to store results of a function. return output.view(np.ndarray) else: # output is not a Quantity, so cannot obtain a unit. if not (unit is None or unit is dimensionless_unscaled): raise UnitTypeError("Cannot store quantity with dimension " "{}in a non-Quantity instance." .format("" if function is None else "resulting from {} function " .format(function.__name__))) return output ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/quantity_helper/erfa.py0000644000175100001710000003211300000000000021614 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """Quantity helpers for the ERFA ufuncs.""" # Tests for these are in coordinates, not in units. from erfa import ufunc as erfa_ufunc, dt_pv, dt_eraLDBODY, dt_eraASTROM from astropy.units.core import UnitsError, UnitTypeError, dimensionless_unscaled from astropy.units.structured import StructuredUnit from . import UFUNC_HELPERS from .helpers import (get_converter, helper_invariant, helper_multiplication, helper_twoarg_invariant, _d) erfa_ufuncs = ('s2c', 's2p', 'c2s', 'p2s', 'pm', 'pdp', 'pxp', 'rxp', 'cpv', 'p2pv', 'pv2p', 'pv2s', 'pvdpv', 'pvm', 'pvmpv', 'pvppv', 'pvstar', 'pvtob', 'pvu', 'pvup', 'pvxpv', 'rxpv', 's2pv', 's2xpv', 'starpv', 'sxpv', 'trxpv', 'gd2gc', 'gc2gd', 'ldn', 'aper', 'apio', 'atciq', 'atciqn', 'atciqz', 'aticq', 'atioq', 'atoiq') def has_matching_structure(unit, dtype): dtype_fields = dtype.fields if dtype_fields: return (isinstance(unit, StructuredUnit) and len(unit) == len(dtype_fields) and all(has_matching_structure(u, df_v[0]) for (u, df_v) in zip(unit.values(), dtype_fields.values()))) else: return not isinstance(unit, StructuredUnit) def check_structured_unit(unit, dtype): if not has_matching_structure(unit, dtype): msg = {dt_pv: 'pv', dt_eraLDBODY: 'ldbody', dt_eraASTROM: 'astrom'}.get(dtype, 'function') raise UnitTypeError(f'{msg} input needs unit matching dtype={dtype}.') def helper_s2c(f, unit1, unit2): from astropy.units.si import radian try: return [get_converter(unit1, radian), get_converter(unit2, radian)], dimensionless_unscaled except UnitsError: raise UnitTypeError("Can only apply '{}' function to " "quantities with angle units" .format(f.__name__)) def helper_s2p(f, unit1, unit2, unit3): from astropy.units.si import radian try: return [get_converter(unit1, radian), get_converter(unit2, radian), None], unit3 except UnitsError: raise UnitTypeError("Can only apply '{}' function to " "quantities with angle units" .format(f.__name__)) def helper_c2s(f, unit1): from astropy.units.si import radian return [None], (radian, radian) def helper_p2s(f, unit1): from astropy.units.si import radian return [None], (radian, radian, unit1) def helper_gc2gd(f, nounit, unit1): from astropy.units.si import m, radian if nounit is not None: raise UnitTypeError("ellipsoid cannot be a quantity.") try: return [None, get_converter(unit1, m)], (radian, radian, m, None) except UnitsError: raise UnitTypeError("Can only apply '{}' function to " "quantities with length units" .format(f.__name__)) def helper_gd2gc(f, nounit, unit1, unit2, unit3): from astropy.units.si import m, radian if nounit is not None: raise UnitTypeError("ellipsoid cannot be a quantity.") try: return [None, get_converter(unit1, radian), get_converter(unit2, radian), get_converter(unit3, m)], (m, None) except UnitsError: raise UnitTypeError("Can only apply '{}' function to lon, lat " "with angle and height with length units" .format(f.__name__)) def helper_p2pv(f, unit1): from astropy.units.si import s if isinstance(unit1, StructuredUnit): raise UnitTypeError("p vector unit cannot be a structured unit.") return [None], StructuredUnit((unit1, unit1 / s)) def helper_pv2p(f, unit1): check_structured_unit(unit1, dt_pv) return [None], unit1[0] def helper_pv2s(f, unit_pv): from astropy.units.si import radian check_structured_unit(unit_pv, dt_pv) ang_unit = radian * unit_pv[1] / unit_pv[0] return [None], (radian, radian, unit_pv[0], ang_unit, ang_unit, unit_pv[1]) def helper_s2pv(f, unit_theta, unit_phi, unit_r, unit_td, unit_pd, unit_rd): from astropy.units.si import radian time_unit = unit_r / unit_rd return [get_converter(unit_theta, radian), get_converter(unit_phi, radian), None, get_converter(unit_td, radian / time_unit), get_converter(unit_pd, radian / time_unit), None], StructuredUnit((unit_r, unit_rd)) def helper_pv_multiplication(f, unit1, unit2): check_structured_unit(unit1, dt_pv) check_structured_unit(unit2, dt_pv) result_unit = StructuredUnit((unit1[0] * unit2[0], unit1[1] * unit2[0])) converter = get_converter(unit2, StructuredUnit( (unit2[0], unit1[1] * unit2[0] / unit1[0]))) return [None, converter], result_unit def helper_pvm(f, unit1): check_structured_unit(unit1, dt_pv) return [None], (unit1[0], unit1[1]) def helper_pvstar(f, unit1): from astropy.units.astrophys import AU from astropy.units.si import km, s, radian, day, year, arcsec return [get_converter(unit1, StructuredUnit((AU, AU/day)))], ( radian, radian, radian / year, radian / year, arcsec, km / s, None) def helper_starpv(f, unit_ra, unit_dec, unit_pmr, unit_pmd, unit_px, unit_rv): from astropy.units.si import km, s, day, year, radian, arcsec from astropy.units.astrophys import AU return [get_converter(unit_ra, radian), get_converter(unit_dec, radian), get_converter(unit_pmr, radian/year), get_converter(unit_pmd, radian/year), get_converter(unit_px, arcsec), get_converter(unit_rv, km/s)], (StructuredUnit((AU, AU/day)), None) def helper_pvtob(f, unit_elong, unit_phi, unit_hm, unit_xp, unit_yp, unit_sp, unit_theta): from astropy.units.si import m, s, radian return [get_converter(unit_elong, radian), get_converter(unit_phi, radian), get_converter(unit_hm, m), get_converter(unit_xp, radian), get_converter(unit_yp, radian), get_converter(unit_sp, radian), get_converter(unit_theta, radian)], StructuredUnit((m, m/s)) def helper_pvu(f, unit_t, unit_pv): check_structured_unit(unit_pv, dt_pv) return [get_converter(unit_t, unit_pv[0]/unit_pv[1]), None], unit_pv def helper_pvup(f, unit_t, unit_pv): check_structured_unit(unit_pv, dt_pv) return [get_converter(unit_t, unit_pv[0]/unit_pv[1]), None], unit_pv[0] def helper_s2xpv(f, unit1, unit2, unit_pv): check_structured_unit(unit_pv, dt_pv) return [None, None, None], StructuredUnit((_d(unit1) * unit_pv[0], _d(unit2) * unit_pv[1])) def ldbody_unit(): from astropy.units.si import day, radian from astropy.units.astrophys import Msun, AU return StructuredUnit((Msun, radian, (AU, AU/day)), erfa_ufunc.dt_eraLDBODY) def astrom_unit(): from astropy.units.si import rad, year from astropy.units.astrophys import AU one = rel2c = dimensionless_unscaled return StructuredUnit((year, AU, one, AU, rel2c, one, one, rad, rad, rad, rad, one, one, rel2c, rad, rad, rad), erfa_ufunc.dt_eraASTROM) def helper_ldn(f, unit_b, unit_ob, unit_sc): from astropy.units.astrophys import AU return [get_converter(unit_b, ldbody_unit()), get_converter(unit_ob, AU), get_converter(_d(unit_sc), dimensionless_unscaled)], dimensionless_unscaled def helper_aper(f, unit_theta, unit_astrom): check_structured_unit(unit_astrom, dt_eraASTROM) unit_along = unit_astrom[7] # along if unit_astrom[14] is unit_along: # eral result_unit = unit_astrom else: result_units = tuple((unit_along if i == 14 else v) for i, v in enumerate(unit_astrom.values())) result_unit = unit_astrom.__class__(result_units, names=unit_astrom) return [get_converter(unit_theta, unit_along), None], result_unit def helper_apio(f, unit_sp, unit_theta, unit_elong, unit_phi, unit_hm, unit_xp, unit_yp, unit_refa, unit_refb): from astropy.units.si import radian, m return [get_converter(unit_sp, radian), get_converter(unit_theta, radian), get_converter(unit_elong, radian), get_converter(unit_phi, radian), get_converter(unit_hm, m), get_converter(unit_xp, radian), get_converter(unit_xp, radian), get_converter(unit_xp, radian), get_converter(unit_xp, radian)], astrom_unit() def helper_atciq(f, unit_rc, unit_dc, unit_pr, unit_pd, unit_px, unit_rv, unit_astrom): from astropy.units.si import radian, arcsec, year, km, s return [get_converter(unit_rc, radian), get_converter(unit_dc, radian), get_converter(unit_pr, radian / year), get_converter(unit_pd, radian / year), get_converter(unit_px, arcsec), get_converter(unit_rv, km / s), get_converter(unit_astrom, astrom_unit())], (radian, radian) def helper_atciqn(f, unit_rc, unit_dc, unit_pr, unit_pd, unit_px, unit_rv, unit_astrom, unit_b): from astropy.units.si import radian, arcsec, year, km, s return [get_converter(unit_rc, radian), get_converter(unit_dc, radian), get_converter(unit_pr, radian / year), get_converter(unit_pd, radian / year), get_converter(unit_px, arcsec), get_converter(unit_rv, km / s), get_converter(unit_astrom, astrom_unit()), get_converter(unit_b, ldbody_unit())], (radian, radian) def helper_atciqz_aticq(f, unit_rc, unit_dc, unit_astrom): from astropy.units.si import radian return [get_converter(unit_rc, radian), get_converter(unit_dc, radian), get_converter(unit_astrom, astrom_unit())], (radian, radian) def helper_aticqn(f, unit_rc, unit_dc, unit_astrom, unit_b): from astropy.units.si import radian return [get_converter(unit_rc, radian), get_converter(unit_dc, radian), get_converter(unit_astrom, astrom_unit()), get_converter(unit_b, ldbody_unit())], (radian, radian) def helper_atioq(f, unit_rc, unit_dc, unit_astrom): from astropy.units.si import radian return [get_converter(unit_rc, radian), get_converter(unit_dc, radian), get_converter(unit_astrom, astrom_unit())], (radian,)*5 def helper_atoiq(f, unit_type, unit_ri, unit_di, unit_astrom): from astropy.units.si import radian if unit_type is not None: raise UnitTypeError("argument 'type' should not have a unit") return [None, get_converter(unit_ri, radian), get_converter(unit_di, radian), get_converter(unit_astrom, astrom_unit())], (radian, radian) def get_erfa_helpers(): ERFA_HELPERS = {} ERFA_HELPERS[erfa_ufunc.s2c] = helper_s2c ERFA_HELPERS[erfa_ufunc.s2p] = helper_s2p ERFA_HELPERS[erfa_ufunc.c2s] = helper_c2s ERFA_HELPERS[erfa_ufunc.p2s] = helper_p2s ERFA_HELPERS[erfa_ufunc.pm] = helper_invariant ERFA_HELPERS[erfa_ufunc.cpv] = helper_invariant ERFA_HELPERS[erfa_ufunc.p2pv] = helper_p2pv ERFA_HELPERS[erfa_ufunc.pv2p] = helper_pv2p ERFA_HELPERS[erfa_ufunc.pv2s] = helper_pv2s ERFA_HELPERS[erfa_ufunc.pvdpv] = helper_pv_multiplication ERFA_HELPERS[erfa_ufunc.pvxpv] = helper_pv_multiplication ERFA_HELPERS[erfa_ufunc.pvm] = helper_pvm ERFA_HELPERS[erfa_ufunc.pvmpv] = helper_twoarg_invariant ERFA_HELPERS[erfa_ufunc.pvppv] = helper_twoarg_invariant ERFA_HELPERS[erfa_ufunc.pvstar] = helper_pvstar ERFA_HELPERS[erfa_ufunc.pvtob] = helper_pvtob ERFA_HELPERS[erfa_ufunc.pvu] = helper_pvu ERFA_HELPERS[erfa_ufunc.pvup] = helper_pvup ERFA_HELPERS[erfa_ufunc.pdp] = helper_multiplication ERFA_HELPERS[erfa_ufunc.pxp] = helper_multiplication ERFA_HELPERS[erfa_ufunc.rxp] = helper_multiplication ERFA_HELPERS[erfa_ufunc.rxpv] = helper_multiplication ERFA_HELPERS[erfa_ufunc.s2pv] = helper_s2pv ERFA_HELPERS[erfa_ufunc.s2xpv] = helper_s2xpv ERFA_HELPERS[erfa_ufunc.starpv] = helper_starpv ERFA_HELPERS[erfa_ufunc.sxpv] = helper_multiplication ERFA_HELPERS[erfa_ufunc.trxpv] = helper_multiplication ERFA_HELPERS[erfa_ufunc.gc2gd] = helper_gc2gd ERFA_HELPERS[erfa_ufunc.gd2gc] = helper_gd2gc ERFA_HELPERS[erfa_ufunc.ldn] = helper_ldn ERFA_HELPERS[erfa_ufunc.aper] = helper_aper ERFA_HELPERS[erfa_ufunc.apio] = helper_apio ERFA_HELPERS[erfa_ufunc.atciq] = helper_atciq ERFA_HELPERS[erfa_ufunc.atciqn] = helper_atciqn ERFA_HELPERS[erfa_ufunc.atciqz] = helper_atciqz_aticq ERFA_HELPERS[erfa_ufunc.aticq] = helper_atciqz_aticq ERFA_HELPERS[erfa_ufunc.aticqn] = helper_aticqn ERFA_HELPERS[erfa_ufunc.atioq] = helper_atioq ERFA_HELPERS[erfa_ufunc.atoiq] = helper_atoiq return ERFA_HELPERS UFUNC_HELPERS.register_module('erfa.ufunc', erfa_ufuncs, get_erfa_helpers) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/quantity_helper/function_helpers.py0000644000175100001710000010463700000000000024261 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license. See LICENSE.rst except # for parts explicitly labelled as being (largely) copies of numpy # implementations; for those, see licenses/NUMPY_LICENSE.rst. """Helpers for overriding numpy functions. We override numpy functions in `~astropy.units.Quantity.__array_function__`. In this module, the numpy functions are split in four groups, each of which has an associated `set` or `dict`: 1. SUBCLASS_SAFE_FUNCTIONS (set), if the numpy implementation supports Quantity; we pass on to ndarray.__array_function__. 2. FUNCTION_HELPERS (dict), if the numpy implementation is usable after converting quantities to arrays with suitable units, and possibly setting units on the result. 3. DISPATCHED_FUNCTIONS (dict), if the function makes sense but requires a Quantity-specific implementation 4. UNSUPPORTED_FUNCTIONS (set), if the function does not make sense. For the FUNCTION_HELPERS `dict`, the value is a function that does the unit conversion. It should take the same arguments as the numpy function would (though one can use ``*args`` and ``**kwargs``) and return a tuple of ``args, kwargs, unit, out``, where ``args`` and ``kwargs`` will be will be passed on to the numpy implementation, ``unit`` is a possible unit of the result (`None` if it should not be converted to Quantity), and ``out`` is a possible output Quantity passed in, which will be filled in-place. For the DISPATCHED_FUNCTIONS `dict`, the value is a function that implements the numpy functionality for Quantity input. It should return a tuple of ``result, unit, out``, where ``result`` is generally a plain array with the result, and ``unit`` and ``out`` are as above. If unit is `None`, result gets returned directly, so one can also return a Quantity directly using ``quantity_result, None, None``. """ import functools import operator import numpy as np from astropy.units.core import ( UnitsError, UnitTypeError, dimensionless_unscaled) from astropy.utils.compat import NUMPY_LT_1_20, NUMPY_LT_1_23 from astropy.utils import isiterable # In 1.17, overrides are enabled by default, but it is still possible to # turn them off using an environment variable. We use getattr since it # is planned to remove that possibility in later numpy versions. ARRAY_FUNCTION_ENABLED = getattr(np.core.overrides, 'ENABLE_ARRAY_FUNCTION', True) SUBCLASS_SAFE_FUNCTIONS = set() """Functions with implementations supporting subclasses like Quantity.""" FUNCTION_HELPERS = {} """Functions with implementations usable with proper unit conversion.""" DISPATCHED_FUNCTIONS = {} """Functions for which we provide our own implementation.""" UNSUPPORTED_FUNCTIONS = set() """Functions that cannot sensibly be used with quantities.""" SUBCLASS_SAFE_FUNCTIONS |= { np.shape, np.size, np.ndim, np.reshape, np.ravel, np.moveaxis, np.rollaxis, np.swapaxes, np.transpose, np.atleast_1d, np.atleast_2d, np.atleast_3d, np.expand_dims, np.squeeze, np.broadcast_to, np.broadcast_arrays, np.flip, np.fliplr, np.flipud, np.rot90, np.argmin, np.argmax, np.argsort, np.lexsort, np.searchsorted, np.nonzero, np.argwhere, np.flatnonzero, np.diag_indices_from, np.triu_indices_from, np.tril_indices_from, np.real, np.imag, np.diagonal, np.diagflat, np.empty_like, np.compress, np.extract, np.delete, np.trim_zeros, np.roll, np.take, np.put, np.fill_diagonal, np.tile, np.repeat, np.split, np.array_split, np.hsplit, np.vsplit, np.dsplit, np.stack, np.column_stack, np.hstack, np.vstack, np.dstack, np.amax, np.amin, np.ptp, np.sum, np.cumsum, np.prod, np.product, np.cumprod, np.cumproduct, np.round, np.around, np.fix, np.angle, np.i0, np.clip, np.isposinf, np.isneginf, np.isreal, np.iscomplex, np.average, np.mean, np.std, np.var, np.median, np.trace, np.nanmax, np.nanmin, np.nanargmin, np.nanargmax, np.nanmean, np.nanmedian, np.nansum, np.nancumsum, np.nanstd, np.nanvar, np.nanprod, np.nancumprod, np.einsum_path, np.trapz, np.linspace, np.sort, np.msort, np.partition, np.meshgrid, np.common_type, np.result_type, np.can_cast, np.min_scalar_type, np.iscomplexobj, np.isrealobj, np.shares_memory, np.may_share_memory, np.apply_along_axis, np.take_along_axis, np.put_along_axis, np.linalg.cond, np.linalg.multi_dot} # Implemented as methods on Quantity: # np.ediff1d is from setops, but we support it anyway; the others # currently return NotImplementedError. # TODO: move latter to UNSUPPORTED? Would raise TypeError instead. SUBCLASS_SAFE_FUNCTIONS |= {np.ediff1d} # Nonsensical for quantities. UNSUPPORTED_FUNCTIONS |= { np.packbits, np.unpackbits, np.unravel_index, np.ravel_multi_index, np.ix_, np.cov, np.corrcoef, np.busday_count, np.busday_offset, np.datetime_as_string, np.is_busday, np.all, np.any, np.sometrue, np.alltrue} # Could be supported if we had a natural logarithm unit. UNSUPPORTED_FUNCTIONS |= {np.linalg.slogdet} # The following are not just unsupported, but so unlikely to be thought # to be supported that we ignore them in testing. (Kept in a separate # variable so that we can check consistency in the test routine - # test_quantity_non_ufuncs.py) IGNORED_FUNCTIONS = { # I/O - useless for Quantity, since no way to store the unit. np.save, np.savez, np.savetxt, np.savez_compressed, # Polynomials np.poly, np.polyadd, np.polyder, np.polydiv, np.polyfit, np.polyint, np.polymul, np.polysub, np.polyval, np.roots, np.vander} if NUMPY_LT_1_20: # financial IGNORED_FUNCTIONS |= {np.fv, np.ipmt, np.irr, np.mirr, np.nper, np.npv, np.pmt, np.ppmt, np.pv, np.rate} if NUMPY_LT_1_23: IGNORED_FUNCTIONS |= { # Deprecated, removed in numpy 1.23 np.asscalar, np.alen, } UNSUPPORTED_FUNCTIONS |= IGNORED_FUNCTIONS class FunctionAssigner: def __init__(self, assignments): self.assignments = assignments def __call__(self, f=None, helps=None, module=np): """Add a helper to a numpy function. Normally used as a decorator. If ``helps`` is given, it should be the numpy function helped (or an iterable of numpy functions helped). If ``helps`` is not given, it is assumed the function helped is the numpy function with the same name as the decorated function. """ if f is not None: if helps is None: helps = getattr(module, f.__name__) if not isiterable(helps): helps = (helps,) for h in helps: self.assignments[h] = f return f elif helps is not None or module is not np: return functools.partial(self.__call__, helps=helps, module=module) else: # pragma: no cover raise ValueError("function_helper requires at least one argument.") function_helper = FunctionAssigner(FUNCTION_HELPERS) dispatched_function = FunctionAssigner(DISPATCHED_FUNCTIONS) @function_helper(helps={ np.copy, np.asfarray, np.real_if_close, np.sort_complex, np.resize, np.fft.fft, np.fft.ifft, np.fft.rfft, np.fft.irfft, np.fft.fft2, np.fft.ifft2, np.fft.rfft2, np.fft.irfft2, np.fft.fftn, np.fft.ifftn, np.fft.rfftn, np.fft.irfftn, np.fft.hfft, np.fft.ihfft, np.linalg.eigvals, np.linalg.eigvalsh}) def invariant_a_helper(a, *args, **kwargs): return (a.view(np.ndarray),) + args, kwargs, a.unit, None @function_helper(helps={np.tril, np.triu}) def invariant_m_helper(m, *args, **kwargs): return (m.view(np.ndarray),) + args, kwargs, m.unit, None @function_helper(helps={np.fft.fftshift, np.fft.ifftshift}) def invariant_x_helper(x, *args, **kwargs): return (x.view(np.ndarray),) + args, kwargs, x.unit, None # Note that ones_like does *not* work by default since if one creates an empty # array with a unit, one cannot just fill it with unity. Indeed, in this # respect, it is a bit of an odd function for Quantity. On the other hand, it # matches the idea that a unit is the same as the quantity with that unit and # value of 1. Also, it used to work without __array_function__. # zeros_like does work by default for regular quantities, because numpy first # creates an empty array with the unit and then fills it with 0 (which can have # any unit), but for structured dtype this fails (0 cannot have an arbitrary # structured unit), so we include it here too. @function_helper(helps={np.ones_like, np.zeros_like}) def like_helper(a, *args, **kwargs): subok = args[2] if len(args) > 2 else kwargs.pop('subok', True) unit = a.unit if subok else None return (a.view(np.ndarray),) + args, kwargs, unit, None @function_helper def sinc(x): from astropy.units.si import radian try: x = x.to_value(radian) except UnitsError: raise UnitTypeError("Can only apply 'sinc' function to " "quantities with angle units") return (x,), {}, dimensionless_unscaled, None @dispatched_function def unwrap(p, discont=None, axis=-1): from astropy.units.si import radian if discont is None: discont = np.pi << radian p, discont = _as_quantities(p, discont) result = np.unwrap.__wrapped__(p.to_value(radian), discont.to_value(radian), axis=axis) result = radian.to(p.unit, result) return result, p.unit, None @function_helper def argpartition(a, *args, **kwargs): return (a.view(np.ndarray),) + args, kwargs, None, None @function_helper def full_like(a, fill_value, *args, **kwargs): unit = a.unit if kwargs.get('subok', True) else None return (a.view(np.ndarray), a._to_own_unit(fill_value)) + args, kwargs, unit, None @function_helper def putmask(a, mask, values): from astropy.units import Quantity if isinstance(a, Quantity): return (a.view(np.ndarray), mask, a._to_own_unit(values)), {}, a.unit, None elif isinstance(values, Quantity): return (a, mask, values.to_value(dimensionless_unscaled)), {}, None, None else: raise NotImplementedError @function_helper def place(arr, mask, vals): from astropy.units import Quantity if isinstance(arr, Quantity): return (arr.view(np.ndarray), mask, arr._to_own_unit(vals)), {}, arr.unit, None elif isinstance(vals, Quantity): return (arr, mask, vals.to_value(dimensionless_unscaled)), {}, None, None else: raise NotImplementedError @function_helper def copyto(dst, src, *args, **kwargs): from astropy.units import Quantity if isinstance(dst, Quantity): return ((dst.view(np.ndarray), dst._to_own_unit(src)) + args, kwargs, None, None) elif isinstance(src, Quantity): return ((dst, src.to_value(dimensionless_unscaled)) + args, kwargs, None, None) else: raise NotImplementedError @function_helper def nan_to_num(x, copy=True, nan=0.0, posinf=None, neginf=None): nan = x._to_own_unit(nan) if posinf is not None: posinf = x._to_own_unit(posinf) if neginf is not None: neginf = x._to_own_unit(neginf) return ((x.view(np.ndarray),), dict(copy=True, nan=nan, posinf=posinf, neginf=neginf), x.unit, None) def _as_quantity(a): """Convert argument to a Quantity (or raise NotImplementedError).""" from astropy.units import Quantity try: return Quantity(a, copy=False, subok=True) except Exception: # If we cannot convert to Quantity, we should just bail. raise NotImplementedError def _as_quantities(*args): """Convert arguments to Quantity (or raise NotImplentedError).""" from astropy.units import Quantity try: return tuple(Quantity(a, copy=False, subok=True) for a in args) except Exception: # If we cannot convert to Quantity, we should just bail. raise NotImplementedError def _quantities2arrays(*args, unit_from_first=False): """Convert to arrays in units of the first argument that has a unit. If unit_from_first, take the unit of the first argument regardless whether it actually defined a unit (e.g., dimensionless for arrays). """ # Turn first argument into a quantity. q = _as_quantity(args[0]) if len(args) == 1: return (q.value,), q.unit # If we care about the unit being explicit, then check whether this # argument actually had a unit, or was likely inferred. if not unit_from_first and (q.unit is q._default_unit and not hasattr(args[0], 'unit')): # Here, the argument could still be things like [10*u.one, 11.*u.one]), # i.e., properly dimensionless. So, we only override with anything # that has a unit not equivalent to dimensionless (fine to ignore other # dimensionless units pass, even if explicitly given). for arg in args[1:]: trial = _as_quantity(arg) if not trial.unit.is_equivalent(q.unit): # Use any explicit unit not equivalent to dimensionless. q = trial break # We use the private _to_own_unit method here instead of just # converting everything to quantity and then do .to_value(qs0.unit) # as we want to allow arbitrary unit for 0, inf, and nan. try: arrays = tuple((q._to_own_unit(arg)) for arg in args) except TypeError: raise NotImplementedError return arrays, q.unit def _iterable_helper(*args, out=None, **kwargs): """Convert arguments to Quantity, and treat possible 'out'.""" from astropy.units import Quantity if out is not None: if isinstance(out, Quantity): kwargs['out'] = out.view(np.ndarray) else: # TODO: for an ndarray output, we could in principle # try converting all Quantity to dimensionless. raise NotImplementedError arrays, unit = _quantities2arrays(*args) return arrays, kwargs, unit, out @function_helper def concatenate(arrays, axis=0, out=None): # TODO: make this smarter by creating an appropriately shaped # empty output array and just filling it. arrays, kwargs, unit, out = _iterable_helper(*arrays, out=out, axis=axis) return (arrays,), kwargs, unit, out @dispatched_function def block(arrays): # We need to override block since the numpy implementation can take two # different paths, one for concatenation, one for creating a large empty # result array in which parts are set. Each assumes array input and # cannot be used directly. Since it would be very costly to inspect all # arrays and then turn them back into a nested list, we just copy here the # second implementation, np.core.shape_base._block_slicing, since it is # shortest and easiest. (arrays, list_ndim, result_ndim, final_size) = np.core.shape_base._block_setup(arrays) shape, slices, arrays = np.core.shape_base._block_info_recursion( arrays, list_ndim, result_ndim) # Here, one line of difference! arrays, unit = _quantities2arrays(*arrays) # Back to _block_slicing dtype = np.result_type(*[arr.dtype for arr in arrays]) F_order = all(arr.flags['F_CONTIGUOUS'] for arr in arrays) C_order = all(arr.flags['C_CONTIGUOUS'] for arr in arrays) order = 'F' if F_order and not C_order else 'C' result = np.empty(shape=shape, dtype=dtype, order=order) for the_slice, arr in zip(slices, arrays): result[(Ellipsis,) + the_slice] = arr return result, unit, None @function_helper def choose(a, choices, out=None, **kwargs): choices, kwargs, unit, out = _iterable_helper(*choices, out=out, **kwargs) return (a, choices,), kwargs, unit, out @function_helper def select(condlist, choicelist, default=0): choicelist, kwargs, unit, out = _iterable_helper(*choicelist) if default != 0: default = (1 * unit)._to_own_unit(default) return (condlist, choicelist, default), kwargs, unit, out @dispatched_function def piecewise(x, condlist, funclist, *args, **kw): from astropy.units import Quantity # Copied implementation from numpy.lib.function_base.piecewise, # taking care of units of function outputs. n2 = len(funclist) # undocumented: single condition is promoted to a list of one condition if np.isscalar(condlist) or ( not isinstance(condlist[0], (list, np.ndarray)) and x.ndim != 0): condlist = [condlist] if any(isinstance(c, Quantity) for c in condlist): raise NotImplementedError condlist = np.array(condlist, dtype=bool) n = len(condlist) if n == n2 - 1: # compute the "otherwise" condition. condelse = ~np.any(condlist, axis=0, keepdims=True) condlist = np.concatenate([condlist, condelse], axis=0) n += 1 elif n != n2: raise ValueError( f"with {n} condition(s), either {n} or {n + 1} functions are expected" ) y = np.zeros(x.shape, x.dtype) where = [] what = [] for k in range(n): item = funclist[k] if not callable(item): where.append(condlist[k]) what.append(item) else: vals = x[condlist[k]] if vals.size > 0: where.append(condlist[k]) what.append(item(vals, *args, **kw)) what, unit = _quantities2arrays(*what) for item, value in zip(where, what): y[item] = value return y, unit, None @function_helper def append(arr, values, *args, **kwargs): arrays, unit = _quantities2arrays(arr, values, unit_from_first=True) return arrays + args, kwargs, unit, None @function_helper def insert(arr, obj, values, *args, **kwargs): from astropy.units import Quantity if isinstance(obj, Quantity): raise NotImplementedError (arr, values), unit = _quantities2arrays(arr, values, unit_from_first=True) return (arr, obj, values) + args, kwargs, unit, None @function_helper def pad(array, pad_width, mode='constant', **kwargs): # pad dispatches only on array, so that must be a Quantity. for key in 'constant_values', 'end_values': value = kwargs.pop(key, None) if value is None: continue if not isinstance(value, tuple): value = (value,) new_value = [] for v in value: new_value.append( tuple(array._to_own_unit(_v) for _v in v) if isinstance(v, tuple) else array._to_own_unit(v)) kwargs[key] = new_value return (array.view(np.ndarray), pad_width, mode), kwargs, array.unit, None @function_helper def where(condition, *args): from astropy.units import Quantity if isinstance(condition, Quantity) or len(args) != 2: raise NotImplementedError args, unit = _quantities2arrays(*args) return (condition,) + args, {}, unit, None @function_helper(helps=({np.quantile, np.nanquantile})) def quantile(a, q, *args, _q_unit=dimensionless_unscaled, **kwargs): if len(args) >= 2: out = args[1] args = args[:1] + args[2:] else: out = kwargs.pop('out', None) from astropy.units import Quantity if isinstance(q, Quantity): q = q.to_value(_q_unit) (a,), kwargs, unit, out = _iterable_helper(a, out=out, **kwargs) return (a, q) + args, kwargs, unit, out @function_helper(helps={np.percentile, np.nanpercentile}) def percentile(a, q, *args, **kwargs): from astropy.units import percent return quantile(a, q, *args, _q_unit=percent, **kwargs) @function_helper def count_nonzero(a, *args, **kwargs): return (a.value,) + args, kwargs, None, None @function_helper(helps={np.isclose, np.allclose}) def close(a, b, rtol=1e-05, atol=1e-08, *args, **kwargs): from astropy.units import Quantity (a, b), unit = _quantities2arrays(a, b, unit_from_first=True) # Allow number without a unit as having the unit. atol = Quantity(atol, unit).value return (a, b, rtol, atol) + args, kwargs, None, None @function_helper def array_equal(a1, a2): args, unit = _quantities2arrays(a1, a2) return args, {}, None, None @function_helper def array_equiv(a1, a2): args, unit = _quantities2arrays(a1, a2) return args, {}, None, None @function_helper(helps={np.dot, np.outer}) def dot_like(a, b, out=None): from astropy.units import Quantity a, b = _as_quantities(a, b) unit = a.unit * b.unit if out is not None: if not isinstance(out, Quantity): raise NotImplementedError return tuple(x.view(np.ndarray) for x in (a, b, out)), {}, unit, out else: return (a.view(np.ndarray), b.view(np.ndarray)), {}, unit, None @function_helper(helps={np.cross, np.inner, np.vdot, np.tensordot, np.kron, np.correlate, np.convolve}) def cross_like(a, b, *args, **kwargs): a, b = _as_quantities(a, b) unit = a.unit * b.unit return (a.view(np.ndarray), b.view(np.ndarray)) + args, kwargs, unit, None @function_helper def einsum(subscripts, *operands, out=None, **kwargs): from astropy.units import Quantity if not isinstance(subscripts, str): raise ValueError('only "subscripts" string mode supported for einsum.') if out is not None: if not isinstance(out, Quantity): raise NotImplementedError else: kwargs['out'] = out.view(np.ndarray) qs = _as_quantities(*operands) unit = functools.reduce(operator.mul, (q.unit for q in qs), dimensionless_unscaled) arrays = tuple(q.view(np.ndarray) for q in qs) return (subscripts,) + arrays, kwargs, unit, out @function_helper def bincount(x, weights=None, minlength=0): from astropy.units import Quantity if isinstance(x, Quantity): raise NotImplementedError return (x, weights.value, minlength), {}, weights.unit, None @function_helper def digitize(x, bins, *args, **kwargs): arrays, unit = _quantities2arrays(x, bins, unit_from_first=True) return arrays + args, kwargs, None, None def _check_bins(bins, unit): from astropy.units import Quantity check = _as_quantity(bins) if check.ndim > 0: return check.to_value(unit) elif isinstance(bins, Quantity): # bins should be an integer (or at least definitely not a Quantity). raise NotImplementedError else: return bins @function_helper def histogram(a, bins=10, range=None, weights=None, density=None): if weights is not None: weights = _as_quantity(weights) unit = weights.unit weights = weights.value else: unit = None a = _as_quantity(a) if not isinstance(bins, str): bins = _check_bins(bins, a.unit) if density: unit = (unit or 1) / a.unit return ((a.value, bins, range), {'weights': weights, 'density': density}, (unit, a.unit), None) @function_helper(helps=np.histogram_bin_edges) def histogram_bin_edges(a, bins=10, range=None, weights=None): # weights is currently unused a = _as_quantity(a) if not isinstance(bins, str): bins = _check_bins(bins, a.unit) return (a.value, bins, range, weights), {}, a.unit, None @function_helper def histogram2d(x, y, bins=10, range=None, weights=None, density=None): from astropy.units import Quantity if weights is not None: weights = _as_quantity(weights) unit = weights.unit weights = weights.value else: unit = None x, y = _as_quantities(x, y) try: n = len(bins) except TypeError: # bins should be an integer (or at least definitely not a Quantity). if isinstance(bins, Quantity): raise NotImplementedError else: if n == 1: raise NotImplementedError elif n == 2 and not isinstance(bins, Quantity): bins = [_check_bins(b, unit) for (b, unit) in zip(bins, (x.unit, y.unit))] else: bins = _check_bins(bins, x.unit) y = y.to(x.unit) if density: unit = (unit or 1) / x.unit / y.unit return ((x.value, y.value, bins, range), {'weights': weights, 'density': density}, (unit, x.unit, y.unit), None) @function_helper def histogramdd(sample, bins=10, range=None, weights=None, density=None): if weights is not None: weights = _as_quantity(weights) unit = weights.unit weights = weights.value else: unit = None try: # Sample is an ND-array. _, D = sample.shape except (AttributeError, ValueError): # Sample is a sequence of 1D arrays. sample = _as_quantities(*sample) sample_units = [s.unit for s in sample] sample = [s.value for s in sample] D = len(sample) else: sample = _as_quantity(sample) sample_units = [sample.unit] * D try: M = len(bins) except TypeError: # bins should be an integer from astropy.units import Quantity if isinstance(bins, Quantity): raise NotImplementedError else: if M != D: raise ValueError( 'The dimension of bins must be equal to the dimension of the ' ' sample x.') bins = [_check_bins(b, unit) for (b, unit) in zip(bins, sample_units)] if density: unit = functools.reduce(operator.truediv, sample_units, (unit or 1)) return ((sample, bins, range), {'weights': weights, 'density': density}, (unit, sample_units), None) @function_helper def diff(a, n=1, axis=-1, prepend=np._NoValue, append=np._NoValue): a = _as_quantity(a) if prepend is not np._NoValue: prepend = _as_quantity(prepend).to_value(a.unit) if append is not np._NoValue: append = _as_quantity(append).to_value(a.unit) return (a.value, n, axis, prepend, append), {}, a.unit, None @function_helper def gradient(f, *varargs, **kwargs): f = _as_quantity(f) axis = kwargs.get('axis', None) if axis is None: n_axis = f.ndim elif isinstance(axis, tuple): n_axis = len(axis) else: n_axis = 1 if varargs: varargs = _as_quantities(*varargs) if len(varargs) == 1 and n_axis > 1: varargs = varargs * n_axis if varargs: units = [f.unit / q.unit for q in varargs] varargs = tuple(q.value for q in varargs) else: units = [f.unit] * n_axis if len(units) == 1: units = units[0] return (f.value,) + varargs, kwargs, units, None @function_helper def logspace(start, stop, *args, **kwargs): from astropy.units import LogQuantity, dex if (not isinstance(start, LogQuantity) or not isinstance(stop, LogQuantity)): raise NotImplementedError # Get unit from end point as for linspace. stop = stop.to(dex(stop.unit.physical_unit)) start = start.to(stop.unit) unit = stop.unit.physical_unit return (start.value, stop.value) + args, kwargs, unit, None @function_helper def geomspace(start, stop, *args, **kwargs): # Get unit from end point as for linspace. (stop, start), unit = _quantities2arrays(stop, start) return (start, stop) + args, kwargs, unit, None @function_helper def interp(x, xp, fp, *args, **kwargs): from astropy.units import Quantity (x, xp), _ = _quantities2arrays(x, xp) if isinstance(fp, Quantity): unit = fp.unit fp = fp.value else: unit = None return (x, xp, fp) + args, kwargs, unit, None @function_helper def unique(ar, return_index=False, return_inverse=False, return_counts=False, axis=None): unit = ar.unit n_index = sum(bool(i) for i in (return_index, return_inverse, return_counts)) if n_index: unit = [unit] + n_index * [None] return (ar.value, return_index, return_inverse, return_counts, axis), {}, unit, None @function_helper def intersect1d(ar1, ar2, assume_unique=False, return_indices=False): (ar1, ar2), unit = _quantities2arrays(ar1, ar2) if return_indices: unit = [unit, None, None] return (ar1, ar2, assume_unique, return_indices), {}, unit, None @function_helper(helps=(np.setxor1d, np.union1d, np.setdiff1d)) def twosetop(ar1, ar2, *args, **kwargs): (ar1, ar2), unit = _quantities2arrays(ar1, ar2) return (ar1, ar2) + args, kwargs, unit, None @function_helper(helps=(np.isin, np.in1d)) def setcheckop(ar1, ar2, *args, **kwargs): # This tests whether ar1 is in ar2, so we should change the unit of # a1 to that of a2. (ar2, ar1), unit = _quantities2arrays(ar2, ar1) return (ar1, ar2) + args, kwargs, None, None @dispatched_function def apply_over_axes(func, a, axes): # Copied straight from numpy/lib/shape_base, just to omit its # val = asarray(a); if only it had been asanyarray, or just not there # since a is assumed to an an array in the next line... # Which is what we do here - we can only get here if it is a Quantity. val = a N = a.ndim if np.array(axes).ndim == 0: axes = (axes,) for axis in axes: if axis < 0: axis = N + axis args = (val, axis) res = func(*args) if res.ndim == val.ndim: val = res else: res = np.expand_dims(res, axis) if res.ndim == val.ndim: val = res else: raise ValueError("function is not returning " "an array of the correct shape") # Returning unit is None to signal nothing should happen to # the output. return val, None, None @dispatched_function def array_repr(arr, *args, **kwargs): # TODO: The addition of "unit='...'" doesn't worry about line # length. Could copy & adapt _array_repr_implementation from # numpy.core.arrayprint.py cls_name = arr.__class__.__name__ fake_name = '_' * len(cls_name) fake_cls = type(fake_name, (np.ndarray,), {}) no_unit = np.array_repr(arr.view(fake_cls), *args, **kwargs).replace(fake_name, cls_name) unit_part = f"unit='{arr.unit}'" pre, dtype, post = no_unit.rpartition('dtype') if dtype: return f"{pre}{unit_part}, {dtype}{post}", None, None else: return f"{no_unit[:-1]}, {unit_part})", None, None @dispatched_function def array_str(arr, *args, **kwargs): # TODO: The addition of the unit doesn't worry about line length. # Could copy & adapt _array_repr_implementation from # numpy.core.arrayprint.py no_unit = np.array_str(arr.value, *args, **kwargs) return no_unit + arr._unitstr, None, None @function_helper def array2string(a, *args, **kwargs): # array2string breaks on quantities as it tries to turn individual # items into float, which works only for dimensionless. Since the # defaults would not keep any unit anyway, this is rather pointless - # we're better off just passing on the array view. However, one can # also work around this by passing on a formatter (as is done in Angle). # So, we do nothing if the formatter argument is present and has the # relevant formatter for our dtype. formatter = args[6] if len(args) >= 7 else kwargs.get('formatter', None) if formatter is None: a = a.value else: # See whether it covers our dtype. from numpy.core.arrayprint import _get_format_function with np.printoptions(formatter=formatter) as options: try: ff = _get_format_function(a.value, **options) except Exception: # Shouldn't happen, but possibly we're just not being smart # enough, so let's pass things on as is. pass else: # If the selected format function is that of numpy, we know # things will fail if 'numpy' in ff.__module__: a = a.value return (a,) + args, kwargs, None, None @function_helper def diag(v, *args, **kwargs): # Function works for *getting* the diagonal, but not *setting*. # So, override always. return (v.value,) + args, kwargs, v.unit, None @function_helper(module=np.linalg) def svd(a, full_matrices=True, compute_uv=True, hermitian=False): unit = a.unit if compute_uv: unit = (None, unit, None) return ((a.view(np.ndarray), full_matrices, compute_uv, hermitian), {}, unit, None) def _interpret_tol(tol, unit): from astropy.units import Quantity return Quantity(tol, unit).value @function_helper(module=np.linalg) def matrix_rank(M, tol=None, *args, **kwargs): if tol is not None: tol = _interpret_tol(tol, M.unit) return (M.view(np.ndarray), tol) + args, kwargs, None, None @function_helper(helps={np.linalg.inv, np.linalg.tensorinv}) def inv(a, *args, **kwargs): return (a.view(np.ndarray),)+args, kwargs, 1/a.unit, None @function_helper(module=np.linalg) def pinv(a, rcond=1e-15, *args, **kwargs): rcond = _interpret_tol(rcond, a.unit) return (a.view(np.ndarray), rcond) + args, kwargs, 1/a.unit, None @function_helper(module=np.linalg) def det(a): return (a.view(np.ndarray),), {}, a.unit ** a.shape[-1], None @function_helper(helps={np.linalg.solve, np.linalg.tensorsolve}) def solve(a, b, *args, **kwargs): a, b = _as_quantities(a, b) return ((a.view(np.ndarray), b.view(np.ndarray)) + args, kwargs, b.unit / a.unit, None) @function_helper(module=np.linalg) def lstsq(a, b, rcond="warn"): a, b = _as_quantities(a, b) if rcond not in (None, "warn", -1): rcond = _interpret_tol(rcond, a.unit) return ((a.view(np.ndarray), b.view(np.ndarray), rcond), {}, (b.unit / a.unit, b.unit ** 2, None, a.unit), None) @function_helper(module=np.linalg) def norm(x, ord=None, *args, **kwargs): if ord == 0: from astropy.units import dimensionless_unscaled unit = dimensionless_unscaled else: unit = x.unit return (x.view(np.ndarray), ord)+args, kwargs, unit, None @function_helper(module=np.linalg) def matrix_power(a, n): return (a.value, n), {}, a.unit ** n, None @function_helper(module=np.linalg) def cholesky(a): return (a.value,), {}, a.unit ** 0.5, None @function_helper(module=np.linalg) def qr(a, mode='reduced'): if mode.startswith('e'): units = None elif mode == 'r': units = a.unit else: from astropy.units import dimensionless_unscaled units = (dimensionless_unscaled, a.unit) return (a.value, mode), {}, units, None @function_helper(helps={np.linalg.eig, np.linalg.eigh}) def eig(a, *args, **kwargs): from astropy.units import dimensionless_unscaled return (a.value,)+args, kwargs, (a.unit, dimensionless_unscaled), None ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/quantity_helper/helpers.py0000644000175100001710000003647400000000000022357 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst # The idea for this module (but no code) was borrowed from the # quantities (http://pythonhosted.org/quantities/) package. """Helper functions for Quantity. In particular, this implements the logic that determines scaling and result units for a given ufunc, given input units. """ from fractions import Fraction import numpy as np from . import UFUNC_HELPERS, UNSUPPORTED_UFUNCS from astropy.units.core import ( UnitsError, UnitConversionError, UnitTypeError, dimensionless_unscaled, get_current_unit_registry, unit_scale_converter) def _d(unit): if unit is None: return dimensionless_unscaled else: return unit def get_converter(from_unit, to_unit): """Like Unit._get_converter, except returns None if no scaling is needed, i.e., if the inferred scale is unity.""" converter = from_unit._get_converter(to_unit) return None if converter is unit_scale_converter else converter def get_converters_and_unit(f, unit1, unit2): converters = [None, None] # By default, we try adjusting unit2 to unit1, so that the result will # be unit1 as well. But if there is no second unit, we have to try # adjusting unit1 (to dimensionless, see below). if unit2 is None: if unit1 is None: # No units for any input -- e.g., np.add(a1, a2, out=q) return converters, dimensionless_unscaled changeable = 0 # swap units. unit2 = unit1 unit1 = None elif unit2 is unit1: # ensure identical units is fast ("==" is slow, so avoid that). return converters, unit1 else: changeable = 1 # Try to get a converter from unit2 to unit1. if unit1 is None: try: converters[changeable] = get_converter(unit2, dimensionless_unscaled) except UnitsError: # special case: would be OK if unitless number is zero, inf, nan converters[1-changeable] = False return converters, unit2 else: return converters, dimensionless_unscaled else: try: converters[changeable] = get_converter(unit2, unit1) except UnitsError: raise UnitConversionError( "Can only apply '{}' function to quantities " "with compatible dimensions" .format(f.__name__)) return converters, unit1 # SINGLE ARGUMENT UFUNC HELPERS # # The functions below take a single argument, which is the quantity upon which # the ufunc is being used. The output of the helper function should be two # values: a list with a single converter to be used to scale the input before # it is being passed to the ufunc (or None if no conversion is needed), and # the unit the output will be in. def helper_onearg_test(f, unit): return ([None], None) def helper_invariant(f, unit): return ([None], _d(unit)) def helper_square(f, unit): return ([None], unit ** 2 if unit is not None else dimensionless_unscaled) def helper_reciprocal(f, unit): return ([None], unit ** -1 if unit is not None else dimensionless_unscaled) one_half = 0.5 # faster than Fraction(1, 2) one_third = Fraction(1, 3) def helper_sqrt(f, unit): return ([None], unit ** one_half if unit is not None else dimensionless_unscaled) def helper_cbrt(f, unit): return ([None], (unit ** one_third if unit is not None else dimensionless_unscaled)) def helper_modf(f, unit): if unit is None: return [None], (dimensionless_unscaled, dimensionless_unscaled) try: return ([get_converter(unit, dimensionless_unscaled)], (dimensionless_unscaled, dimensionless_unscaled)) except UnitsError: raise UnitTypeError("Can only apply '{}' function to " "dimensionless quantities" .format(f.__name__)) def helper__ones_like(f, unit): return [None], dimensionless_unscaled def helper_dimensionless_to_dimensionless(f, unit): if unit is None: return [None], dimensionless_unscaled try: return ([get_converter(unit, dimensionless_unscaled)], dimensionless_unscaled) except UnitsError: raise UnitTypeError("Can only apply '{}' function to " "dimensionless quantities" .format(f.__name__)) def helper_dimensionless_to_radian(f, unit): from astropy.units.si import radian if unit is None: return [None], radian try: return [get_converter(unit, dimensionless_unscaled)], radian except UnitsError: raise UnitTypeError("Can only apply '{}' function to " "dimensionless quantities" .format(f.__name__)) def helper_degree_to_radian(f, unit): from astropy.units.si import degree, radian try: return [get_converter(unit, degree)], radian except UnitsError: raise UnitTypeError("Can only apply '{}' function to " "quantities with angle units" .format(f.__name__)) def helper_radian_to_degree(f, unit): from astropy.units.si import degree, radian try: return [get_converter(unit, radian)], degree except UnitsError: raise UnitTypeError("Can only apply '{}' function to " "quantities with angle units" .format(f.__name__)) def helper_radian_to_dimensionless(f, unit): from astropy.units.si import radian try: return [get_converter(unit, radian)], dimensionless_unscaled except UnitsError: raise UnitTypeError("Can only apply '{}' function to " "quantities with angle units" .format(f.__name__)) def helper_frexp(f, unit): if not unit.is_unity(): raise UnitTypeError("Can only apply '{}' function to " "unscaled dimensionless quantities" .format(f.__name__)) return [None], (None, None) # TWO ARGUMENT UFUNC HELPERS # # The functions below take a two arguments. The output of the helper function # should be two values: a tuple of two converters to be used to scale the # inputs before being passed to the ufunc (None if no conversion is needed), # and the unit the output will be in. def helper_multiplication(f, unit1, unit2): return [None, None], _d(unit1) * _d(unit2) def helper_division(f, unit1, unit2): return [None, None], _d(unit1) / _d(unit2) def helper_power(f, unit1, unit2): # TODO: find a better way to do this, currently need to signal that one # still needs to raise power of unit1 in main code if unit2 is None: return [None, None], False try: return [None, get_converter(unit2, dimensionless_unscaled)], False except UnitsError: raise UnitTypeError("Can only raise something to a " "dimensionless quantity") def helper_ldexp(f, unit1, unit2): if unit2 is not None: raise TypeError("Cannot use ldexp with a quantity " "as second argument.") else: return [None, None], _d(unit1) def helper_copysign(f, unit1, unit2): # if first arg is not a quantity, just return plain array if unit1 is None: return [None, None], None else: return [None, None], unit1 def helper_heaviside(f, unit1, unit2): try: converter2 = (get_converter(unit2, dimensionless_unscaled) if unit2 is not None else None) except UnitsError: raise UnitTypeError("Can only apply 'heaviside' function with a " "dimensionless second argument.") return ([None, converter2], dimensionless_unscaled) def helper_two_arg_dimensionless(f, unit1, unit2): try: converter1 = (get_converter(unit1, dimensionless_unscaled) if unit1 is not None else None) converter2 = (get_converter(unit2, dimensionless_unscaled) if unit2 is not None else None) except UnitsError: raise UnitTypeError("Can only apply '{}' function to " "dimensionless quantities" .format(f.__name__)) return ([converter1, converter2], dimensionless_unscaled) # This used to be a separate function that just called get_converters_and_unit. # Using it directly saves a few us; keeping the clearer name. helper_twoarg_invariant = get_converters_and_unit def helper_twoarg_comparison(f, unit1, unit2): converters, _ = get_converters_and_unit(f, unit1, unit2) return converters, None def helper_twoarg_invtrig(f, unit1, unit2): from astropy.units.si import radian converters, _ = get_converters_and_unit(f, unit1, unit2) return converters, radian def helper_twoarg_floor_divide(f, unit1, unit2): converters, _ = get_converters_and_unit(f, unit1, unit2) return converters, dimensionless_unscaled def helper_divmod(f, unit1, unit2): converters, result_unit = get_converters_and_unit(f, unit1, unit2) return converters, (dimensionless_unscaled, result_unit) def helper_clip(f, unit1, unit2, unit3): # Treat the array being clipped as primary. converters = [None] if unit1 is None: result_unit = dimensionless_unscaled try: converters += [(None if unit is None else get_converter(unit, dimensionless_unscaled)) for unit in (unit2, unit3)] except UnitsError: raise UnitConversionError( "Can only apply '{}' function to quantities with " "compatible dimensions".format(f.__name__)) else: result_unit = unit1 for unit in unit2, unit3: try: converter = get_converter(_d(unit), result_unit) except UnitsError: if unit is None: # special case: OK if unitless number is zero, inf, nan converters.append(False) else: raise UnitConversionError( "Can only apply '{}' function to quantities with " "compatible dimensions".format(f.__name__)) else: converters.append(converter) return converters, result_unit # list of ufuncs: # https://numpy.org/doc/stable/reference/ufuncs.html#available-ufuncs UNSUPPORTED_UFUNCS |= { np.bitwise_and, np.bitwise_or, np.bitwise_xor, np.invert, np.left_shift, np.right_shift, np.logical_and, np.logical_or, np.logical_xor, np.logical_not, np.isnat, np.gcd, np.lcm} # SINGLE ARGUMENT UFUNCS # ufuncs that do not care about the unit and do not return a Quantity # (but rather a boolean, or -1, 0, or +1 for np.sign). onearg_test_ufuncs = (np.isfinite, np.isinf, np.isnan, np.sign, np.signbit) for ufunc in onearg_test_ufuncs: UFUNC_HELPERS[ufunc] = helper_onearg_test # ufuncs that return a value with the same unit as the input invariant_ufuncs = (np.absolute, np.fabs, np.conj, np.conjugate, np.negative, np.spacing, np.rint, np.floor, np.ceil, np.trunc, np.positive) for ufunc in invariant_ufuncs: UFUNC_HELPERS[ufunc] = helper_invariant # ufuncs that require dimensionless input and and give dimensionless output dimensionless_to_dimensionless_ufuncs = (np.exp, np.expm1, np.exp2, np.log, np.log10, np.log2, np.log1p) # Default numpy does not ship an "erf" ufunc, but some versions hacked by # intel do. This is bad, since it means code written for that numpy will # not run on non-hacked numpy. But still, we might as well support it. if isinstance(getattr(np.core.umath, 'erf', None), np.ufunc): dimensionless_to_dimensionless_ufuncs += (np.core.umath.erf,) for ufunc in dimensionless_to_dimensionless_ufuncs: UFUNC_HELPERS[ufunc] = helper_dimensionless_to_dimensionless # ufuncs that require dimensionless input and give output in radians dimensionless_to_radian_ufuncs = (np.arccos, np.arcsin, np.arctan, np.arccosh, np.arcsinh, np.arctanh) for ufunc in dimensionless_to_radian_ufuncs: UFUNC_HELPERS[ufunc] = helper_dimensionless_to_radian # ufuncs that require input in degrees and give output in radians degree_to_radian_ufuncs = (np.radians, np.deg2rad) for ufunc in degree_to_radian_ufuncs: UFUNC_HELPERS[ufunc] = helper_degree_to_radian # ufuncs that require input in radians and give output in degrees radian_to_degree_ufuncs = (np.degrees, np.rad2deg) for ufunc in radian_to_degree_ufuncs: UFUNC_HELPERS[ufunc] = helper_radian_to_degree # ufuncs that require input in radians and give dimensionless output radian_to_dimensionless_ufuncs = (np.cos, np.sin, np.tan, np.cosh, np.sinh, np.tanh) for ufunc in radian_to_dimensionless_ufuncs: UFUNC_HELPERS[ufunc] = helper_radian_to_dimensionless # ufuncs handled as special cases UFUNC_HELPERS[np.sqrt] = helper_sqrt UFUNC_HELPERS[np.square] = helper_square UFUNC_HELPERS[np.reciprocal] = helper_reciprocal UFUNC_HELPERS[np.cbrt] = helper_cbrt UFUNC_HELPERS[np.core.umath._ones_like] = helper__ones_like UFUNC_HELPERS[np.modf] = helper_modf UFUNC_HELPERS[np.frexp] = helper_frexp # TWO ARGUMENT UFUNCS # two argument ufuncs that require dimensionless input and and give # dimensionless output two_arg_dimensionless_ufuncs = (np.logaddexp, np.logaddexp2) for ufunc in two_arg_dimensionless_ufuncs: UFUNC_HELPERS[ufunc] = helper_two_arg_dimensionless # two argument ufuncs that return a value with the same unit as the input twoarg_invariant_ufuncs = (np.add, np.subtract, np.hypot, np.maximum, np.minimum, np.fmin, np.fmax, np.nextafter, np.remainder, np.mod, np.fmod) for ufunc in twoarg_invariant_ufuncs: UFUNC_HELPERS[ufunc] = helper_twoarg_invariant # two argument ufuncs that need compatible inputs and return a boolean twoarg_comparison_ufuncs = (np.greater, np.greater_equal, np.less, np.less_equal, np.not_equal, np.equal) for ufunc in twoarg_comparison_ufuncs: UFUNC_HELPERS[ufunc] = helper_twoarg_comparison # two argument ufuncs that do inverse trigonometry twoarg_invtrig_ufuncs = (np.arctan2,) # another private function in numpy; use getattr in case it disappears if isinstance(getattr(np.core.umath, '_arg', None), np.ufunc): twoarg_invtrig_ufuncs += (np.core.umath._arg,) for ufunc in twoarg_invtrig_ufuncs: UFUNC_HELPERS[ufunc] = helper_twoarg_invtrig # ufuncs handled as special cases UFUNC_HELPERS[np.multiply] = helper_multiplication if isinstance(getattr(np, 'matmul', None), np.ufunc): UFUNC_HELPERS[np.matmul] = helper_multiplication UFUNC_HELPERS[np.divide] = helper_division UFUNC_HELPERS[np.true_divide] = helper_division UFUNC_HELPERS[np.power] = helper_power UFUNC_HELPERS[np.ldexp] = helper_ldexp UFUNC_HELPERS[np.copysign] = helper_copysign UFUNC_HELPERS[np.floor_divide] = helper_twoarg_floor_divide UFUNC_HELPERS[np.heaviside] = helper_heaviside UFUNC_HELPERS[np.float_power] = helper_power UFUNC_HELPERS[np.divmod] = helper_divmod # Check for clip ufunc; note that np.clip is a wrapper function, not the ufunc. if isinstance(getattr(np.core.umath, 'clip', None), np.ufunc): UFUNC_HELPERS[np.core.umath.clip] = helper_clip del ufunc ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/quantity_helper/scipy_special.py0000644000175100001710000000703600000000000023534 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """Quantity helpers for the scipy.special ufuncs. Available ufuncs in this module are at https://docs.scipy.org/doc/scipy/reference/special.html """ import numpy as np from astropy.units.core import UnitsError, UnitTypeError, dimensionless_unscaled from . import UFUNC_HELPERS from .helpers import (get_converter, helper_dimensionless_to_dimensionless, helper_cbrt, helper_two_arg_dimensionless) # ufuncs that require dimensionless input and give dimensionless output. dimensionless_to_dimensionless_sps_ufuncs = ( 'erf', 'erfc', 'erfcx', 'erfi', 'erfinv', 'erfcinv', 'gamma', 'gammaln', 'loggamma', 'gammasgn', 'psi', 'rgamma', 'digamma', 'wofz', 'dawsn', 'entr', 'exprel', 'expm1', 'log1p', 'exp2', 'exp10', 'j0', 'j1', 'y0', 'y1', 'i0', 'i0e', 'i1', 'i1e', 'k0', 'k0e', 'k1', 'k1e', 'itj0y0', 'it2j0y0', 'iti0k0', 'it2i0k0', 'ndtr', 'ndtri') scipy_special_ufuncs = dimensionless_to_dimensionless_sps_ufuncs # ufuncs that require input in degrees and give dimensionless output. degree_to_dimensionless_sps_ufuncs = ('cosdg', 'sindg', 'tandg', 'cotdg') scipy_special_ufuncs += degree_to_dimensionless_sps_ufuncs # ufuncs that require 2 dimensionless inputs and give dimensionless output. # note: 'jv' and 'jn' are aliases in some scipy versions, which will # cause the same key to be written twice, but since both are handled by the # same helper there is no harm done. two_arg_dimensionless_sps_ufuncs = ( 'jv', 'jn', 'jve', 'yn', 'yv', 'yve', 'kn', 'kv', 'kve', 'iv', 'ive', 'hankel1', 'hankel1e', 'hankel2', 'hankel2e') scipy_special_ufuncs += two_arg_dimensionless_sps_ufuncs # ufuncs handled as special cases scipy_special_ufuncs += ('cbrt', 'radian') def helper_degree_to_dimensionless(f, unit): from astropy.units.si import degree try: return [get_converter(unit, degree)], dimensionless_unscaled except UnitsError: raise UnitTypeError("Can only apply '{}' function to " "quantities with angle units" .format(f.__name__)) def helper_degree_minute_second_to_radian(f, unit1, unit2, unit3): from astropy.units.si import degree, arcmin, arcsec, radian try: return [get_converter(unit1, degree), get_converter(unit2, arcmin), get_converter(unit3, arcsec)], radian except UnitsError: raise UnitTypeError("Can only apply '{}' function to " "quantities with angle units" .format(f.__name__)) def get_scipy_special_helpers(): import scipy.special as sps SCIPY_HELPERS = {} for name in dimensionless_to_dimensionless_sps_ufuncs: # In SCIPY_LT_1_5, erfinv and erfcinv are not ufuncs. ufunc = getattr(sps, name, None) if isinstance(ufunc, np.ufunc): SCIPY_HELPERS[ufunc] = helper_dimensionless_to_dimensionless for ufunc in degree_to_dimensionless_sps_ufuncs: SCIPY_HELPERS[getattr(sps, ufunc)] = helper_degree_to_dimensionless for ufunc in two_arg_dimensionless_sps_ufuncs: SCIPY_HELPERS[getattr(sps, ufunc)] = helper_two_arg_dimensionless # ufuncs handled as special cases SCIPY_HELPERS[sps.cbrt] = helper_cbrt SCIPY_HELPERS[sps.radian] = helper_degree_minute_second_to_radian return SCIPY_HELPERS UFUNC_HELPERS.register_module('scipy.special', scipy_special_ufuncs, get_scipy_special_helpers) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/required_by_vounit.py0000644000175100001710000000417300000000000021405 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """ This package defines SI prefixed units that are required by the VOUnit standard but that are rarely used in practice and liable to lead to confusion (such as ``msolMass`` for milli-solar mass). They are in a separate module from `astropy.units.deprecated` because they need to be enabled by default for `astropy.units` to parse compliant VOUnit strings. As a result, e.g., ``Unit('msolMass')`` will just work, but to access the unit directly, use ``astropy.units.required_by_vounit.msolMass`` instead of the more typical idiom possible for the non-prefixed unit, ``astropy.units.solMass``. """ _ns = globals() def _initialize_module(): # Local imports to avoid polluting top-level namespace from . import cgs from . import astrophys from .core import def_unit, _add_prefixes _add_prefixes(astrophys.solMass, namespace=_ns, prefixes=True) _add_prefixes(astrophys.solRad, namespace=_ns, prefixes=True) _add_prefixes(astrophys.solLum, namespace=_ns, prefixes=True) _initialize_module() ########################################################################### # DOCSTRING # This generates a docstring for this module that describes all of the # standard units defined here. from .utils import (generate_unit_summary as _generate_unit_summary, generate_prefixonly_unit_summary as _generate_prefixonly_unit_summary) if __doc__ is not None: __doc__ += _generate_unit_summary(globals()) __doc__ += _generate_prefixonly_unit_summary(globals()) def _enable(): """ Enable the VOUnit-required extra units so they appear in results of `~astropy.units.UnitBase.find_equivalent_units` and `~astropy.units.UnitBase.compose`, and are recognized in the ``Unit('...')`` idiom. """ # Local import to avoid cyclical import from .core import add_enabled_units # Local import to avoid polluting namespace import inspect return add_enabled_units(inspect.getmodule(_enable)) # Because these are VOUnit mandated units, they start enabled (which is why the # function is hidden). _enable() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/si.py0000644000175100001710000002073000000000000016077 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """ This package defines the SI units. They are also available in the `astropy.units` namespace. """ from astropy.constants import si as _si from .core import UnitBase, Unit, def_unit import numpy as _numpy _ns = globals() ########################################################################### # DIMENSIONLESS def_unit(['percent', 'pct'], Unit(0.01), namespace=_ns, prefixes=False, doc="percent: one hundredth of unity, factor 0.01", format={'generic': '%', 'console': '%', 'cds': '%', 'latex': r'\%', 'unicode': '%'}) ########################################################################### # LENGTH def_unit(['m', 'meter'], namespace=_ns, prefixes=True, doc="meter: base unit of length in SI") def_unit(['micron'], um, namespace=_ns, doc="micron: alias for micrometer (um)", format={'latex': r'\mu m', 'unicode': '\N{MICRO SIGN}m'}) def_unit(['Angstrom', 'AA', 'angstrom'], 0.1 * nm, namespace=_ns, doc="ÃĨngstrÃļm: 10 ** -10 m", prefixes=[(['m', 'milli'], ['milli', 'm'], 1.e-3)], format={'latex': r'\mathring{A}', 'unicode': 'Å', 'vounit': 'Angstrom'}) ########################################################################### # VOLUMES def_unit((['l', 'L'], ['liter']), 1000 * cm ** 3.0, namespace=_ns, prefixes=True, format={'latex': r'\mathcal{l}', 'unicode': 'ℓ'}, doc="liter: metric unit of volume") ########################################################################### # ANGULAR MEASUREMENTS def_unit(['rad', 'radian'], namespace=_ns, prefixes=True, doc="radian: angular measurement of the ratio between the length " "on an arc and its radius") def_unit(['deg', 'degree'], _numpy.pi / 180.0 * rad, namespace=_ns, prefixes=True, doc="degree: angular measurement 1/360 of full rotation", format={'latex': r'{}^{\circ}', 'unicode': '°'}) def_unit(['hourangle'], 15.0 * deg, namespace=_ns, prefixes=False, doc="hour angle: angular measurement with 24 in a full circle", format={'latex': r'{}^{h}', 'unicode': 'ʰ'}) def_unit(['arcmin', 'arcminute'], 1.0 / 60.0 * deg, namespace=_ns, prefixes=True, doc="arc minute: angular measurement", format={'latex': r'{}^{\prime}', 'unicode': '′'}) def_unit(['arcsec', 'arcsecond'], 1.0 / 3600.0 * deg, namespace=_ns, prefixes=True, doc="arc second: angular measurement") # These special formats should only be used for the non-prefix versions arcsec._format = {'latex': r'{}^{\prime\prime}', 'unicode': 'â€ŗ'} def_unit(['mas'], 0.001 * arcsec, namespace=_ns, doc="milli arc second: angular measurement") def_unit(['uas'], 0.000001 * arcsec, namespace=_ns, doc="micro arc second: angular measurement", format={'latex': r'\mu as', 'unicode': 'Îŧas'}) def_unit(['sr', 'steradian'], rad ** 2, namespace=_ns, prefixes=True, doc="steradian: unit of solid angle in SI") ########################################################################### # TIME def_unit(['s', 'second'], namespace=_ns, prefixes=True, exclude_prefixes=['a'], doc="second: base unit of time in SI.") def_unit(['min', 'minute'], 60 * s, prefixes=True, namespace=_ns) def_unit(['h', 'hour', 'hr'], 3600 * s, namespace=_ns, prefixes=True, exclude_prefixes=['p']) def_unit(['d', 'day'], 24 * h, namespace=_ns, prefixes=True, exclude_prefixes=['c', 'y']) def_unit(['sday'], 86164.09053 * s, namespace=_ns, doc="Sidereal day (sday) is the time of one rotation of the Earth.") def_unit(['wk', 'week'], 7 * day, namespace=_ns) def_unit(['fortnight'], 2 * wk, namespace=_ns) def_unit(['a', 'annum'], 365.25 * d, namespace=_ns, prefixes=True, exclude_prefixes=['P']) def_unit(['yr', 'year'], 365.25 * d, namespace=_ns, prefixes=True) ########################################################################### # FREQUENCY def_unit(['Hz', 'Hertz', 'hertz'], 1 / s, namespace=_ns, prefixes=True, doc="Frequency") ########################################################################### # MASS def_unit(['kg', 'kilogram'], namespace=_ns, doc="kilogram: base unit of mass in SI.") def_unit(['g', 'gram'], 1.0e-3 * kg, namespace=_ns, prefixes=True, exclude_prefixes=['k', 'kilo']) def_unit(['t', 'tonne'], 1000 * kg, namespace=_ns, doc="Metric tonne") ########################################################################### # AMOUNT OF SUBSTANCE def_unit(['mol', 'mole'], namespace=_ns, prefixes=True, doc="mole: amount of a chemical substance in SI.") ########################################################################### # TEMPERATURE def_unit( ['K', 'Kelvin'], namespace=_ns, prefixes=True, doc="Kelvin: temperature with a null point at absolute zero.") def_unit( ['deg_C', 'Celsius'], namespace=_ns, doc='Degrees Celsius', format={'latex': r'{}^{\circ}C', 'unicode': '°C'}) ########################################################################### # FORCE def_unit(['N', 'Newton', 'newton'], kg * m * s ** -2, namespace=_ns, prefixes=True, doc="Newton: force") ########################################################################## # ENERGY def_unit(['J', 'Joule', 'joule'], N * m, namespace=_ns, prefixes=True, doc="Joule: energy") def_unit(['eV', 'electronvolt'], _si.e.value * J, namespace=_ns, prefixes=True, doc="Electron Volt") ########################################################################## # PRESSURE def_unit(['Pa', 'Pascal', 'pascal'], J * m ** -3, namespace=_ns, prefixes=True, doc="Pascal: pressure") ########################################################################### # POWER def_unit(['W', 'Watt', 'watt'], J / s, namespace=_ns, prefixes=True, doc="Watt: power") ########################################################################### # ELECTRICAL def_unit(['A', 'ampere', 'amp'], namespace=_ns, prefixes=True, doc="ampere: base unit of electric current in SI") def_unit(['C', 'coulomb'], A * s, namespace=_ns, prefixes=True, doc="coulomb: electric charge") def_unit(['V', 'Volt', 'volt'], J * C ** -1, namespace=_ns, prefixes=True, doc="Volt: electric potential or electromotive force") def_unit((['Ohm', 'ohm'], ['Ohm']), V * A ** -1, namespace=_ns, prefixes=True, doc="Ohm: electrical resistance", format={'latex': r'\Omega', 'unicode': 'Ί'}) def_unit(['S', 'Siemens', 'siemens'], A * V ** -1, namespace=_ns, prefixes=True, doc="Siemens: electrical conductance") def_unit(['F', 'Farad', 'farad'], C * V ** -1, namespace=_ns, prefixes=True, doc="Farad: electrical capacitance") ########################################################################### # MAGNETIC def_unit(['Wb', 'Weber', 'weber'], V * s, namespace=_ns, prefixes=True, doc="Weber: magnetic flux") def_unit(['T', 'Tesla', 'tesla'], Wb * m ** -2, namespace=_ns, prefixes=True, doc="Tesla: magnetic flux density") def_unit(['H', 'Henry', 'henry'], Wb * A ** -1, namespace=_ns, prefixes=True, doc="Henry: inductance") ########################################################################### # ILLUMINATION def_unit(['cd', 'candela'], namespace=_ns, prefixes=True, doc="candela: base unit of luminous intensity in SI") def_unit(['lm', 'lumen'], cd * sr, namespace=_ns, prefixes=True, doc="lumen: luminous flux") def_unit(['lx', 'lux'], lm * m ** -2, namespace=_ns, prefixes=True, doc="lux: luminous emittance") ########################################################################### # RADIOACTIVITY def_unit(['Bq', 'becquerel'], 1 / s, namespace=_ns, prefixes=False, doc="becquerel: unit of radioactivity") def_unit(['Ci', 'curie'], Bq * 3.7e10, namespace=_ns, prefixes=False, doc="curie: unit of radioactivity") ########################################################################### # BASES bases = set([m, s, kg, A, cd, rad, K, mol]) ########################################################################### # CLEANUP del UnitBase del Unit del def_unit ########################################################################### # DOCSTRING # This generates a docstring for this module that describes all of the # standard units defined here. from .utils import generate_unit_summary as _generate_unit_summary if __doc__ is not None: __doc__ += _generate_unit_summary(globals()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/structured.py0000644000175100001710000004534100000000000017675 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """ This module defines structured units and quantities. """ # Standard library import operator import numpy as np from .core import Unit, UnitBase, UNITY __all__ = ['StructuredUnit'] DTYPE_OBJECT = np.dtype('O') def _names_from_dtype(dtype): """Recursively extract field names from a dtype.""" names = [] for name in dtype.names: subdtype = dtype.fields[name][0] if subdtype.names: names.append([name, _names_from_dtype(subdtype)]) else: names.append(name) return tuple(names) def _normalize_names(names): """Recursively normalize, inferring upper level names for unadorned tuples. Generally, we want the field names to be organized like dtypes, as in ``(['pv', ('p', 'v')], 't')``. But we automatically infer upper field names if the list is absent from items like ``(('p', 'v'), 't')``, by concatenating the names inside the tuple. """ result = [] for name in names: if isinstance(name, str) and len(name) > 0: result.append(name) elif (isinstance(name, list) and len(name) == 2 and isinstance(name[0], str) and len(name[0]) > 0 and isinstance(name[1], tuple) and len(name[1]) > 0): result.append([name[0], _normalize_names(name[1])]) elif isinstance(name, tuple) and len(name) > 0: new_tuple = _normalize_names(name) result.append([''.join([(i[0] if isinstance(i, list) else i) for i in new_tuple]), new_tuple]) else: raise ValueError(f'invalid entry {name!r}. Should be a name, ' 'tuple of names, or 2-element list of the ' 'form [name, tuple of names].') return tuple(result) class StructuredUnit: """Container for units for a structured Quantity. Parameters ---------- units : unit-like, tuple of unit-like, or `~astropy.units.StructuredUnit` Tuples can be nested. If a `~astropy.units.StructuredUnit` is passed in, it will be returned unchanged unless different names are requested. names : tuple of str, tuple or list; `~numpy.dtype`; or `~astropy.units.StructuredUnit`, optional Field names for the units, possibly nested. Can be inferred from a structured `~numpy.dtype` or another `~astropy.units.StructuredUnit`. For nested tuples, by default the name of the upper entry will be the concatenation of the names of the lower levels. One can pass in a list with the upper-level name and a tuple of lower-level names to avoid this. For tuples, not all levels have to be given; for any level not passed in, default field names of 'f0', 'f1', etc., will be used. Notes ----- It is recommended to initialze the class indirectly, using `~astropy.units.Unit`. E.g., ``u.Unit('AU,AU/day')``. When combined with a structured array to produce a structured `~astropy.units.Quantity`, array field names will take precedence. Generally, passing in ``names`` is needed only if the unit is used unattached to a `~astropy.units.Quantity` and one needs to access its fields. Examples -------- Various ways to initialize a `~astropy.units.StructuredUnit`:: >>> import astropy.units as u >>> su = u.Unit('(AU,AU/day),yr') >>> su Unit("((AU, AU / d), yr)") >>> su.field_names (['f0', ('f0', 'f1')], 'f1') >>> su['f1'] Unit("yr") >>> su2 = u.StructuredUnit(((u.AU, u.AU/u.day), u.yr), names=(('p', 'v'), 't')) >>> su2 == su True >>> su2.field_names (['pv', ('p', 'v')], 't') >>> su3 = u.StructuredUnit((su2['pv'], u.day), names=(['p_v', ('p', 'v')], 't')) >>> su3.field_names (['p_v', ('p', 'v')], 't') >>> su3.keys() ('p_v', 't') >>> su3.values() (Unit("(AU, AU / d)"), Unit("d")) Structured units share most methods with regular units:: >>> su.physical_type ((PhysicalType('length'), PhysicalType({'speed', 'velocity'})), PhysicalType('time')) >>> su.si Unit("((1.49598e+11 m, 1.73146e+06 m / s), 3.15576e+07 s)") """ def __new__(cls, units, names=None): dtype = None if names is not None: if isinstance(names, StructuredUnit): dtype = names._units.dtype names = names.field_names elif isinstance(names, np.dtype): if not names.fields: raise ValueError('dtype should be structured, with fields.') dtype = np.dtype([(name, DTYPE_OBJECT) for name in names.names]) names = _names_from_dtype(names) else: if not isinstance(names, tuple): names = (names,) names = _normalize_names(names) if not isinstance(units, tuple): units = Unit(units) if isinstance(units, StructuredUnit): # Avoid constructing a new StructuredUnit if no field names # are given, or if all field names are the same already anyway. if names is None or units.field_names == names: return units # Otherwise, turn (the upper level) into a tuple, for renaming. units = units.values() else: # Single regular unit: make a tuple for iteration below. units = (units,) if names is None: names = tuple(f'f{i}' for i in range(len(units))) elif len(units) != len(names): raise ValueError("lengths of units and field names must match.") converted = [] for unit, name in zip(units, names): if isinstance(name, list): # For list, the first item is the name of our level, # and the second another tuple of names, i.e., we recurse. unit = cls(unit, name[1]) name = name[0] else: # We are at the lowest level. Check unit. unit = Unit(unit) if dtype is not None and isinstance(unit, StructuredUnit): raise ValueError("units do not match in depth with field " "names from dtype or structured unit.") converted.append(unit) self = super().__new__(cls) if dtype is None: dtype = np.dtype([((name[0] if isinstance(name, list) else name), DTYPE_OBJECT) for name in names]) # Decay array to void so we can access by field name and number. self._units = np.array(tuple(converted), dtype)[()] return self def __getnewargs__(self): """When de-serializing, e.g. pickle, start with a blank structure.""" return (), None @property def field_names(self): """Possibly nested tuple of the field names of the parts.""" return tuple(([name, unit.field_names] if isinstance(unit, StructuredUnit) else name) for name, unit in self.items()) # Allow StructuredUnit to be treated as an (ordered) mapping. def __len__(self): return len(self._units.dtype.names) def __getitem__(self, item): # Since we are based on np.void, indexing by field number works too. return self._units[item] def values(self): return self._units.item() def keys(self): return self._units.dtype.names def items(self): return tuple(zip(self._units.dtype.names, self._units.item())) def __iter__(self): yield from self._units.dtype.names # Helpers for methods below. def _recursively_apply(self, func, cls=None): """Apply func recursively. Parameters ---------- func : callable Function to apply to all parts of the structured unit, recursing as needed. cls : type, optional If given, should be a subclass of `~numpy.void`. By default, will return a new `~astropy.units.StructuredUnit` instance. """ results = np.array(tuple([func(part) for part in self.values()]), self._units.dtype)[()] if cls is not None: return results.view((cls, results.dtype)) # Short-cut; no need to interpret field names, etc. result = super().__new__(self.__class__) result._units = results return result def _recursively_get_dtype(self, value, enter_lists=True): """Get structured dtype according to value, using our field names. This is useful since ``np.array(value)`` would treat tuples as lower levels of the array, rather than as elements of a structured array. The routine does presume that the type of the first tuple is representative of the rest. Used in ``_get_converter``. For the special value of ``UNITY``, all fields are assumed to be 1.0, and hence this will return an all-float dtype. """ if enter_lists: while isinstance(value, list): value = value[0] if value is UNITY: value = (UNITY,) * len(self) elif not isinstance(value, tuple) or len(self) != len(value): raise ValueError(f"cannot interpret value {value} for unit {self}.") descr = [] for (name, unit), part in zip(self.items(), value): if isinstance(unit, StructuredUnit): descr.append( (name, unit._recursively_get_dtype(part, enter_lists=False))) else: # Got a part associated with a regular unit. Gets its dtype. # Like for Quantity, we cast integers to float. part = np.array(part) part_dtype = part.dtype if part_dtype.kind in 'iu': part_dtype = np.dtype(float) descr.append((name, part_dtype, part.shape)) return np.dtype(descr) @property def si(self): """The `StructuredUnit` instance in SI units.""" return self._recursively_apply(operator.attrgetter('si')) @property def cgs(self): """The `StructuredUnit` instance in cgs units.""" return self._recursively_apply(operator.attrgetter('cgs')) # Needed to pass through Unit initializer, so might as well use it. def _get_physical_type_id(self): return self._recursively_apply( operator.methodcaller('_get_physical_type_id'), cls=Structure) @property def physical_type(self): """Physical types of all the fields.""" return self._recursively_apply( operator.attrgetter('physical_type'), cls=Structure) def decompose(self, bases=set()): """The `StructuredUnit` composed of only irreducible units. Parameters ---------- bases : sequence of `~astropy.units.UnitBase`, optional The bases to decompose into. When not provided, decomposes down to any irreducible units. When provided, the decomposed result will only contain the given units. This will raises a `UnitsError` if it's not possible to do so. Returns ------- `~astropy.units.StructuredUnit` With the unit for each field containing only irreducible units. """ return self._recursively_apply( operator.methodcaller('decompose', bases=bases)) def is_equivalent(self, other, equivalencies=[]): """`True` if all fields are equivalent to the other's fields. Parameters ---------- other : `~astropy.units.StructuredUnit` The structured unit to compare with, or what can initialize one. equivalencies : list of tuple, optional A list of equivalence pairs to try if the units are not directly convertible. See :ref:`unit_equivalencies`. The list will be applied to all fields. Returns ------- bool """ try: other = StructuredUnit(other) except Exception: return False if len(self) != len(other): return False for self_part, other_part in zip(self.values(), other.values()): if not self_part.is_equivalent(other_part, equivalencies=equivalencies): return False return True def _get_converter(self, other, equivalencies=[]): if not isinstance(other, type(self)): other = self.__class__(other, names=self) converters = [self_part._get_converter(other_part, equivalencies=equivalencies) for (self_part, other_part) in zip(self.values(), other.values())] def converter(value): if not hasattr(value, 'dtype'): value = np.array(value, self._recursively_get_dtype(value)) result = np.empty_like(value) for name, converter_ in zip(result.dtype.names, converters): result[name] = converter_(value[name]) # Index with empty tuple to decay array scalars to numpy void. return result if result.shape else result[()] return converter def to(self, other, value=np._NoValue, equivalencies=[]): """Return values converted to the specified unit. Parameters ---------- other : `~astropy.units.StructuredUnit` The unit to convert to. If necessary, will be converted to a `~astropy.units.StructuredUnit` using the dtype of ``value``. value : array-like, optional Value(s) in the current unit to be converted to the specified unit. If a sequence, the first element must have entries of the correct type to represent all elements (i.e., not have, e.g., a ``float`` where other elements have ``complex``). If not given, assumed to have 1. in all fields. equivalencies : list of tuple, optional A list of equivalence pairs to try if the units are not directly convertible. See :ref:`unit_equivalencies`. This list is in addition to possible global defaults set by, e.g., `set_enabled_equivalencies`. Use `None` to turn off all equivalencies. Returns ------- values : scalar or array Converted value(s). Raises ------ UnitsError If units are inconsistent """ if value is np._NoValue: # We do not have UNITY as a default, since then the docstring # would list 1.0 as default, yet one could not pass that in. value = UNITY return self._get_converter(other, equivalencies=equivalencies)(value) def to_string(self, format='generic'): """Output the unit in the given format as a string. Units are separated by commas. Parameters ---------- format : `astropy.units.format.Base` instance or str The name of a format or a formatter object. If not provided, defaults to the generic format. Notes ----- Structured units can be written to all formats, but can be re-read only with 'generic'. """ parts = [part.to_string(format) for part in self.values()] out_fmt = '({})' if len(self) > 1 else '({},)' if format == 'latex': # Strip $ from parts and add them on the outside. parts = [part[1:-1] for part in parts] out_fmt = '$' + out_fmt + '$' return out_fmt.format(', '.join(parts)) def _repr_latex_(self): return self.to_string('latex') __array_ufunc__ = None def __mul__(self, other): if isinstance(other, str): try: other = Unit(other, parse_strict='silent') except Exception: return NotImplemented if isinstance(other, UnitBase): new_units = tuple(part * other for part in self.values()) return self.__class__(new_units, names=self) if isinstance(other, StructuredUnit): return NotImplemented # Anything not like a unit, try initialising as a structured quantity. try: from .quantity import Quantity return Quantity(other, unit=self) except Exception: return NotImplemented def __rmul__(self, other): return self.__mul__(other) def __truediv__(self, other): if isinstance(other, str): try: other = Unit(other, parse_strict='silent') except Exception: return NotImplemented if isinstance(other, UnitBase): new_units = tuple(part / other for part in self.values()) return self.__class__(new_units, names=self) return NotImplemented def __rlshift__(self, m): try: from .quantity import Quantity return Quantity(m, self, copy=False, subok=True) except Exception: return NotImplemented def __str__(self): return self.to_string() def __repr__(self): return f'Unit("{self.to_string()}")' def __eq__(self, other): try: other = StructuredUnit(other) except Exception: return NotImplemented return self.values() == other.values() def __ne__(self, other): if not isinstance(other, type(self)): try: other = StructuredUnit(other) except Exception: return NotImplemented return self.values() != other.values() class Structure(np.void): """Single element structure for physical type IDs, etc. Behaves like a `~numpy.void` and thus mostly like a tuple which can also be indexed with field names, but overrides ``__eq__`` and ``__ne__`` to compare only the contents, not the field names. Furthermore, this way no `FutureWarning` about comparisons is given. """ # Note that it is important for physical type IDs to not be stored in a # tuple, since then the physical types would be treated as alternatives in # :meth:`~astropy.units.UnitBase.is_equivalent`. (Of course, in that # case, they could also not be indexed by name.) def __eq__(self, other): if isinstance(other, np.void): other = other.item() return self.item() == other def __ne__(self, other): if isinstance(other, np.void): other = other.item() return self.item() != other ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1872532 astropy-5.0.2/astropy/units/tests/0000755000175100001710000000000000000000000016252 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/tests/__init__.py0000644000175100001710000000000000000000000020351 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/tests/test_aliases.py0000644000175100001710000000577400000000000021321 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """Test setting and adding unit aliases.""" import pytest import astropy.units as u trials = [ ({"Angstroms": u.AA}, "Angstroms", u.AA), ({"counts": u.count}, "counts/s", u.count / u.s), ({"ergs": u.erg, "Angstroms": u.AA}, "ergs/(s cm**2 Angstroms)", u.erg / (u.s * u.cm**2 * u.AA))] class TestAliases: def teardown_method(self): u.set_enabled_aliases({}) def teardown_class(self): assert u.get_current_unit_registry().aliases == {} @pytest.mark.parametrize('format_', [None, 'fits', 'ogip', 'vounit', 'cds']) @pytest.mark.parametrize('aliases,bad,unit', trials) def test_set_enabled_aliases_context_manager(self, aliases, bad, unit, format_): if format_ == 'cds': bad = bad.replace(' ', '.').replace('**', '') with u.set_enabled_aliases(aliases): assert u.get_current_unit_registry().aliases == aliases assert u.Unit(bad) == unit assert u.get_current_unit_registry().aliases == {} with pytest.raises(ValueError): u.Unit(bad) @pytest.mark.parametrize('aliases,bad,unit', trials) def test_add_enabled_aliases_context_manager(self, aliases, bad, unit): with u.add_enabled_aliases(aliases): assert u.get_current_unit_registry().aliases == aliases assert u.Unit(bad) == unit assert u.get_current_unit_registry().aliases == {} with pytest.raises(ValueError): u.Unit(bad) def test_set_enabled_aliases(self): for i, (aliases, bad, unit) in enumerate(trials): u.set_enabled_aliases(aliases) assert u.get_current_unit_registry().aliases == aliases assert u.Unit(bad) == unit for _, bad2, unit2 in trials: if bad2 == bad or bad2 in aliases: assert u.Unit(bad2) == unit2 else: with pytest.raises(ValueError): u.Unit(bad2) def test_add_enabled_aliases(self): expected_aliases = {} for i, (aliases, bad, unit) in enumerate(trials): u.add_enabled_aliases(aliases) expected_aliases.update(aliases) assert u.get_current_unit_registry().aliases == expected_aliases assert u.Unit(bad) == unit for j, (_, bad2, unit2) in enumerate(trials): if j <= i: assert u.Unit(bad2) == unit2 else: with pytest.raises(ValueError): u.Unit(bad2) def test_cannot_alias_existing_unit(self): with pytest.raises(ValueError, match='already means'): u.set_enabled_aliases({'pct': u.Unit(1e-12*u.count)}) def test_cannot_alias_existing_alias_to_another_unit(self): u.set_enabled_aliases({'counts': u.count}) with pytest.raises(ValueError, match='already is an alias'): u.add_enabled_aliases({'counts': u.adu}) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/tests/test_deprecated.py0000644000175100001710000000416200000000000021766 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """Regression tests for deprecated units or those that are "soft" deprecated because they are required for VOUnit support but are not in common use.""" import pytest from astropy.units import deprecated, required_by_vounit from astropy import units as u def test_emu(): with pytest.raises(AttributeError): u.emu assert u.Bi.to(deprecated.emu, 1) == 1 with deprecated.enable(): assert u.Bi.compose()[0] == deprecated.emu assert u.Bi.compose()[0] == u.Bi # test that the earth/jupiter mass/rad are also in the deprecated bunch for body in ('earth', 'jupiter'): for phystype in ('Mass', 'Rad'): # only test a couple prefixes to same time for prefix in ('n', 'y'): namewoprefix = body + phystype unitname = prefix + namewoprefix with pytest.raises(AttributeError): getattr(u, unitname) assert (getattr(deprecated, unitname).represents.bases[0] == getattr(u, namewoprefix)) def test_required_by_vounit(): # The tests below could be replicated with all the various prefixes, but it # seems unnecessary because they all come as a set. So we only use nano for # the purposes of this test. with pytest.raises(AttributeError): # nano-solar mass/rad/lum shouldn't be in the base unit namespace u.nsolMass u.nsolRad u.nsolLum # but they should be enabled by default via required_by_vounit, to allow # the Unit constructor to accept them assert u.Unit('nsolMass') == required_by_vounit.nsolMass assert u.Unit('nsolRad') == required_by_vounit.nsolRad assert u.Unit('nsolLum') == required_by_vounit.nsolLum # but because they are prefixes, they shouldn't be in find_equivalent_units assert required_by_vounit.nsolMass not in u.solMass.find_equivalent_units() assert required_by_vounit.nsolRad not in u.solRad.find_equivalent_units() assert required_by_vounit.nsolLum not in u.solLum.find_equivalent_units() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/tests/test_equivalencies.py0000644000175100001710000010050200000000000022516 0ustar00vstsdocker# coding: utf-8 # Licensed under a 3-clause BSD style license - see LICENSE.rst """Separate tests specifically for equivalencies.""" # THIRD-PARTY import pytest import numpy as np from numpy.testing import assert_allclose # LOCAL from astropy import units as u from astropy.units.equivalencies import Equivalency from astropy import constants from astropy.tests.helper import assert_quantity_allclose from astropy.utils.exceptions import AstropyDeprecationWarning def test_dimensionless_angles(): # test that the angles_dimensionless option allows one to change # by any order in radian in the unit (#1161) rad1 = u.dimensionless_angles() assert u.radian.to(1, equivalencies=rad1) == 1. assert u.deg.to(1, equivalencies=rad1) == u.deg.to(u.rad) assert u.steradian.to(1, equivalencies=rad1) == 1. assert u.dimensionless_unscaled.to(u.steradian, equivalencies=rad1) == 1. # now quantities assert (1.*u.radian).to_value(1, equivalencies=rad1) == 1. assert (1.*u.deg).to_value(1, equivalencies=rad1) == u.deg.to(u.rad) assert (1.*u.steradian).to_value(1, equivalencies=rad1) == 1. # more complicated example I = 1.e45 * u.g * u.cm**2 # noqa Omega = u.cycle / (1.*u.s) Erot = 0.5 * I * Omega**2 # check that equivalency makes this work Erot_in_erg1 = Erot.to(u.erg, equivalencies=rad1) # and check that value is correct assert_allclose(Erot_in_erg1.value, (Erot/u.radian**2).to_value(u.erg)) # test built-in equivalency in subclass class MyRad1(u.Quantity): _equivalencies = rad1 phase = MyRad1(1., u.cycle) assert phase.to_value(1) == u.cycle.to(u.radian) @pytest.mark.parametrize('log_unit', (u.mag, u.dex, u.dB)) def test_logarithmic(log_unit): # check conversion of mag, dB, and dex to dimensionless and vice versa with pytest.raises(u.UnitsError): log_unit.to(1, 0.) with pytest.raises(u.UnitsError): u.dimensionless_unscaled.to(log_unit) assert log_unit.to(1, 0., equivalencies=u.logarithmic()) == 1. assert u.dimensionless_unscaled.to(log_unit, equivalencies=u.logarithmic()) == 0. # also try with quantities q_dex = np.array([0., -1., 1., 2.]) * u.dex q_expected = 10.**q_dex.value * u.dimensionless_unscaled q_log_unit = q_dex.to(log_unit) assert np.all(q_log_unit.to(1, equivalencies=u.logarithmic()) == q_expected) assert np.all(q_expected.to(log_unit, equivalencies=u.logarithmic()) == q_log_unit) with u.set_enabled_equivalencies(u.logarithmic()): assert np.all(np.abs(q_log_unit - q_expected.to(log_unit)) < 1.e-10*log_unit) doppler_functions = [u.doppler_optical, u.doppler_radio, u.doppler_relativistic] @pytest.mark.parametrize(('function'), doppler_functions) def test_doppler_frequency_0(function): rest = 105.01 * u.GHz velo0 = rest.to(u.km/u.s, equivalencies=function(rest)) assert velo0.value == 0 @pytest.mark.parametrize(('function'), doppler_functions) def test_doppler_wavelength_0(function): rest = 105.01 * u.GHz q1 = 0.00285489437196 * u.m velo0 = q1.to(u.km/u.s, equivalencies=function(rest)) np.testing.assert_almost_equal(velo0.value, 0, decimal=6) @pytest.mark.parametrize(('function'), doppler_functions) def test_doppler_energy_0(function): rest = 105.01 * u.GHz q1 = 0.0004342864648539744 * u.eV velo0 = q1.to(u.km/u.s, equivalencies=function(rest)) np.testing.assert_almost_equal(velo0.value, 0, decimal=6) @pytest.mark.parametrize(('function'), doppler_functions) def test_doppler_frequency_circle(function): rest = 105.01 * u.GHz shifted = 105.03 * u.GHz velo = shifted.to(u.km/u.s, equivalencies=function(rest)) freq = velo.to(u.GHz, equivalencies=function(rest)) np.testing.assert_almost_equal(freq.value, shifted.value, decimal=7) @pytest.mark.parametrize(('function'), doppler_functions) def test_doppler_wavelength_circle(function): rest = 105.01 * u.nm shifted = 105.03 * u.nm velo = shifted.to(u.km / u.s, equivalencies=function(rest)) wav = velo.to(u.nm, equivalencies=function(rest)) np.testing.assert_almost_equal(wav.value, shifted.value, decimal=7) @pytest.mark.parametrize(('function'), doppler_functions) def test_doppler_energy_circle(function): rest = 1.0501 * u.eV shifted = 1.0503 * u.eV velo = shifted.to(u.km / u.s, equivalencies=function(rest)) en = velo.to(u.eV, equivalencies=function(rest)) np.testing.assert_almost_equal(en.value, shifted.value, decimal=7) values_ghz = (999.899940784289, 999.8999307714406, 999.8999357778647) @pytest.mark.parametrize(('function', 'value'), list(zip(doppler_functions, values_ghz))) def test_30kms(function, value): rest = 1000 * u.GHz velo = 30 * u.km/u.s shifted = velo.to(u.GHz, equivalencies=function(rest)) np.testing.assert_almost_equal(shifted.value, value, decimal=7) bad_values = (5, 5*u.Jy, None) @pytest.mark.parametrize(('function', 'value'), list(zip(doppler_functions, bad_values))) def test_bad_restfreqs(function, value): with pytest.raises(u.UnitsError): function(value) def test_massenergy(): # The relative tolerance of these tests is set by the uncertainties # in the charge of the electron, which is known to about # 3e-9 (relative tolerance). Therefore, we limit the # precision of the tests to 1e-7 to be safe. The masses are # (loosely) known to ~ 5e-8 rel tolerance, so we couldn't test to # 1e-7 if we used the values from astropy.constants; that is, # they might change by more than 1e-7 in some future update, so instead # they are hardwired here. # Electron, proton, neutron, muon, 1g mass_eV = u.Quantity([510.998928e3, 938.272046e6, 939.565378e6, 105.6583715e6, 5.60958884539e32], u.eV) mass_g = u.Quantity([9.10938291e-28, 1.672621777e-24, 1.674927351e-24, 1.88353147e-25, 1], u.g) # Test both ways assert np.allclose(mass_eV.to_value(u.g, equivalencies=u.mass_energy()), mass_g.value, rtol=1e-7) assert np.allclose(mass_g.to_value(u.eV, equivalencies=u.mass_energy()), mass_eV.value, rtol=1e-7) # Basic tests of 'derived' equivalencies # Surface density sdens_eV = u.Quantity(5.60958884539e32, u.eV / u.m**2) sdens_g = u.Quantity(1e-4, u.g / u.cm**2) assert np.allclose(sdens_eV.to_value(u.g / u.cm**2, equivalencies=u.mass_energy()), sdens_g.value, rtol=1e-7) assert np.allclose(sdens_g.to_value(u.eV / u.m**2, equivalencies=u.mass_energy()), sdens_eV.value, rtol=1e-7) # Density dens_eV = u.Quantity(5.60958884539e32, u.eV / u.m**3) dens_g = u.Quantity(1e-6, u.g / u.cm**3) assert np.allclose(dens_eV.to_value(u.g / u.cm**3, equivalencies=u.mass_energy()), dens_g.value, rtol=1e-7) assert np.allclose(dens_g.to_value(u.eV / u.m**3, equivalencies=u.mass_energy()), dens_eV.value, rtol=1e-7) # Power pow_eV = u.Quantity(5.60958884539e32, u.eV / u.s) pow_g = u.Quantity(1, u.g / u.s) assert np.allclose(pow_eV.to_value(u.g / u.s, equivalencies=u.mass_energy()), pow_g.value, rtol=1e-7) assert np.allclose(pow_g.to_value(u.eV / u.s, equivalencies=u.mass_energy()), pow_eV.value, rtol=1e-7) def test_is_equivalent(): assert u.m.is_equivalent(u.pc) assert u.cycle.is_equivalent(u.mas) assert not u.cycle.is_equivalent(u.dimensionless_unscaled) assert u.cycle.is_equivalent(u.dimensionless_unscaled, u.dimensionless_angles()) assert not (u.Hz.is_equivalent(u.J)) assert u.Hz.is_equivalent(u.J, u.spectral()) assert u.J.is_equivalent(u.Hz, u.spectral()) assert u.pc.is_equivalent(u.arcsecond, u.parallax()) assert u.arcminute.is_equivalent(u.au, u.parallax()) # Pass a tuple for multiple possibilities assert u.cm.is_equivalent((u.m, u.s, u.kg)) assert u.ms.is_equivalent((u.m, u.s, u.kg)) assert u.g.is_equivalent((u.m, u.s, u.kg)) assert not u.L.is_equivalent((u.m, u.s, u.kg)) assert not (u.km / u.s).is_equivalent((u.m, u.s, u.kg)) def test_parallax(): a = u.arcsecond.to(u.pc, 10, u.parallax()) assert_allclose(a, 0.10, rtol=1.e-12) b = u.pc.to(u.arcsecond, a, u.parallax()) assert_allclose(b, 10, rtol=1.e-12) a = u.arcminute.to(u.au, 1, u.parallax()) assert_allclose(a, 3437.746770785, rtol=1.e-12) b = u.au.to(u.arcminute, a, u.parallax()) assert_allclose(b, 1, rtol=1.e-12) val = (-1 * u.mas).to(u.pc, u.parallax()) assert np.isnan(val.value) val = (-1 * u.mas).to_value(u.pc, u.parallax()) assert np.isnan(val) def test_parallax2(): a = u.arcsecond.to(u.pc, [0.1, 2.5], u.parallax()) assert_allclose(a, [10, 0.4], rtol=1.e-12) def test_spectral(): a = u.AA.to(u.Hz, 1, u.spectral()) assert_allclose(a, 2.9979245799999995e+18) b = u.Hz.to(u.AA, a, u.spectral()) assert_allclose(b, 1) a = u.AA.to(u.MHz, 1, u.spectral()) assert_allclose(a, 2.9979245799999995e+12) b = u.MHz.to(u.AA, a, u.spectral()) assert_allclose(b, 1) a = u.m.to(u.Hz, 1, u.spectral()) assert_allclose(a, 2.9979245799999995e+8) b = u.Hz.to(u.m, a, u.spectral()) assert_allclose(b, 1) def test_spectral2(): a = u.nm.to(u.J, 500, u.spectral()) assert_allclose(a, 3.972891366538605e-19) b = u.J.to(u.nm, a, u.spectral()) assert_allclose(b, 500) a = u.AA.to(u.Hz, 1, u.spectral()) b = u.Hz.to(u.J, a, u.spectral()) c = u.AA.to(u.J, 1, u.spectral()) assert_allclose(b, c) c = u.J.to(u.Hz, b, u.spectral()) assert_allclose(a, c) def test_spectral3(): a = u.nm.to(u.Hz, [1000, 2000], u.spectral()) assert_allclose(a, [2.99792458e+14, 1.49896229e+14]) @pytest.mark.parametrize( ('in_val', 'in_unit'), [([0.1, 5000.0, 10000.0], u.AA), ([1e+5, 2.0, 1.0], u.micron ** -1), ([2.99792458e+19, 5.99584916e+14, 2.99792458e+14], u.Hz), ([1.98644568e-14, 3.97289137e-19, 1.98644568e-19], u.J)]) def test_spectral4(in_val, in_unit): """Wave number conversion w.r.t. wavelength, freq, and energy.""" # Spectroscopic and angular out_units = [u.micron ** -1, u.radian / u.micron] answers = [[1e+5, 2.0, 1.0], [6.28318531e+05, 12.5663706, 6.28318531]] for out_unit, ans in zip(out_units, answers): # Forward a = in_unit.to(out_unit, in_val, u.spectral()) assert_allclose(a, ans) # Backward b = out_unit.to(in_unit, ans, u.spectral()) assert_allclose(b, in_val) @pytest.mark.parametrize('wav', (3500 * u.AA, 8.5654988e+14 * u.Hz, 1 / (3500 * u.AA), 5.67555959e-19 * u.J)) def test_spectraldensity2(wav): # flux density flambda = u.erg / u.angstrom / u.cm ** 2 / u.s fnu = u.erg / u.Hz / u.cm ** 2 / u.s a = flambda.to(fnu, 1, u.spectral_density(wav)) assert_allclose(a, 4.086160166177361e-12) # integrated flux f_int = u.erg / u.cm ** 2 / u.s phot_int = u.ph / u.cm ** 2 / u.s a = f_int.to(phot_int, 1, u.spectral_density(wav)) assert_allclose(a, 1.7619408e+11) a = phot_int.to(f_int, 1, u.spectral_density(wav)) assert_allclose(a, 5.67555959e-12) # luminosity density llambda = u.erg / u.angstrom / u.s lnu = u.erg / u.Hz / u.s a = llambda.to(lnu, 1, u.spectral_density(wav)) assert_allclose(a, 4.086160166177361e-12) a = lnu.to(llambda, 1, u.spectral_density(wav)) assert_allclose(a, 2.44728537142857e11) def test_spectraldensity3(): # Define F_nu in Jy f_nu = u.Jy # Define F_lambda in ergs / cm^2 / s / micron f_lambda = u.erg / u.cm ** 2 / u.s / u.micron # 1 GHz one_ghz = u.Quantity(1, u.GHz) # Convert to ergs / cm^2 / s / Hz assert_allclose(f_nu.to(u.erg / u.cm ** 2 / u.s / u.Hz, 1.), 1.e-23, 10) # Convert to ergs / cm^2 / s at 10 Ghz assert_allclose(f_nu.to(u.erg / u.cm ** 2 / u.s, 1., equivalencies=u.spectral_density(one_ghz * 10)), 1.e-13, 10) # Convert to F_lambda at 1 Ghz assert_allclose(f_nu.to(f_lambda, 1., equivalencies=u.spectral_density(one_ghz)), 3.335640951981521e-20, 10) # Convert to Jy at 1 Ghz assert_allclose(f_lambda.to(u.Jy, 1., equivalencies=u.spectral_density(one_ghz)), 1. / 3.335640951981521e-20, 10) # Convert to ergs / cm^2 / s at 10 microns assert_allclose(f_lambda.to(u.erg / u.cm ** 2 / u.s, 1., equivalencies=u.spectral_density(u.Quantity(10, u.micron))), 10., 10) def test_spectraldensity4(): """PHOTLAM and PHOTNU conversions.""" flam = u.erg / (u.cm ** 2 * u.s * u.AA) fnu = u.erg / (u.cm ** 2 * u.s * u.Hz) photlam = u.photon / (u.cm ** 2 * u.s * u.AA) photnu = u.photon / (u.cm ** 2 * u.s * u.Hz) wave = u.Quantity([4956.8, 4959.55, 4962.3], u.AA) flux_photlam = [9.7654e-3, 1.003896e-2, 9.78473e-3] flux_photnu = [8.00335589e-14, 8.23668949e-14, 8.03700310e-14] flux_flam = [3.9135e-14, 4.0209e-14, 3.9169e-14] flux_fnu = [3.20735792e-25, 3.29903646e-25, 3.21727226e-25] flux_jy = [3.20735792e-2, 3.29903646e-2, 3.21727226e-2] flux_stmag = [12.41858665, 12.38919182, 12.41764379] flux_abmag = [12.63463143, 12.60403221, 12.63128047] # PHOTLAM <--> FLAM assert_allclose(photlam.to( flam, flux_photlam, u.spectral_density(wave)), flux_flam, rtol=1e-6) assert_allclose(flam.to( photlam, flux_flam, u.spectral_density(wave)), flux_photlam, rtol=1e-6) # PHOTLAM <--> FNU assert_allclose(photlam.to( fnu, flux_photlam, u.spectral_density(wave)), flux_fnu, rtol=1e-6) assert_allclose(fnu.to( photlam, flux_fnu, u.spectral_density(wave)), flux_photlam, rtol=1e-6) # PHOTLAM <--> Jy assert_allclose(photlam.to( u.Jy, flux_photlam, u.spectral_density(wave)), flux_jy, rtol=1e-6) assert_allclose(u.Jy.to( photlam, flux_jy, u.spectral_density(wave)), flux_photlam, rtol=1e-6) # PHOTLAM <--> PHOTNU assert_allclose(photlam.to( photnu, flux_photlam, u.spectral_density(wave)), flux_photnu, rtol=1e-6) assert_allclose(photnu.to( photlam, flux_photnu, u.spectral_density(wave)), flux_photlam, rtol=1e-6) # PHOTNU <--> FNU assert_allclose(photnu.to( fnu, flux_photnu, u.spectral_density(wave)), flux_fnu, rtol=1e-6) assert_allclose(fnu.to( photnu, flux_fnu, u.spectral_density(wave)), flux_photnu, rtol=1e-6) # PHOTNU <--> FLAM assert_allclose(photnu.to( flam, flux_photnu, u.spectral_density(wave)), flux_flam, rtol=1e-6) assert_allclose(flam.to( photnu, flux_flam, u.spectral_density(wave)), flux_photnu, rtol=1e-6) # PHOTLAM <--> STMAG assert_allclose(photlam.to( u.STmag, flux_photlam, u.spectral_density(wave)), flux_stmag, rtol=1e-6) assert_allclose(u.STmag.to( photlam, flux_stmag, u.spectral_density(wave)), flux_photlam, rtol=1e-6) # PHOTLAM <--> ABMAG assert_allclose(photlam.to( u.ABmag, flux_photlam, u.spectral_density(wave)), flux_abmag, rtol=1e-6) assert_allclose(u.ABmag.to( photlam, flux_abmag, u.spectral_density(wave)), flux_photlam, rtol=1e-6) def test_spectraldensity5(): """ Test photon luminosity density conversions. """ L_la = u.erg / (u.s * u.AA) L_nu = u.erg / (u.s * u.Hz) phot_L_la = u.photon / (u.s * u.AA) phot_L_nu = u.photon / (u.s * u.Hz) wave = u.Quantity([4956.8, 4959.55, 4962.3], u.AA) flux_phot_L_la = [9.7654e-3, 1.003896e-2, 9.78473e-3] flux_phot_L_nu = [8.00335589e-14, 8.23668949e-14, 8.03700310e-14] flux_L_la = [3.9135e-14, 4.0209e-14, 3.9169e-14] flux_L_nu = [3.20735792e-25, 3.29903646e-25, 3.21727226e-25] # PHOTLAM <--> FLAM assert_allclose(phot_L_la.to( L_la, flux_phot_L_la, u.spectral_density(wave)), flux_L_la, rtol=1e-6) assert_allclose(L_la.to( phot_L_la, flux_L_la, u.spectral_density(wave)), flux_phot_L_la, rtol=1e-6) # PHOTLAM <--> FNU assert_allclose(phot_L_la.to( L_nu, flux_phot_L_la, u.spectral_density(wave)), flux_L_nu, rtol=1e-6) assert_allclose(L_nu.to( phot_L_la, flux_L_nu, u.spectral_density(wave)), flux_phot_L_la, rtol=1e-6) # PHOTLAM <--> PHOTNU assert_allclose(phot_L_la.to( phot_L_nu, flux_phot_L_la, u.spectral_density(wave)), flux_phot_L_nu, rtol=1e-6) assert_allclose(phot_L_nu.to( phot_L_la, flux_phot_L_nu, u.spectral_density(wave)), flux_phot_L_la, rtol=1e-6) # PHOTNU <--> FNU assert_allclose(phot_L_nu.to( L_nu, flux_phot_L_nu, u.spectral_density(wave)), flux_L_nu, rtol=1e-6) assert_allclose(L_nu.to( phot_L_nu, flux_L_nu, u.spectral_density(wave)), flux_phot_L_nu, rtol=1e-6) # PHOTNU <--> FLAM assert_allclose(phot_L_nu.to( L_la, flux_phot_L_nu, u.spectral_density(wave)), flux_L_la, rtol=1e-6) assert_allclose(L_la.to( phot_L_nu, flux_L_la, u.spectral_density(wave)), flux_phot_L_nu, rtol=1e-6) def test_spectraldensity6(): """ Test surface brightness conversions. """ slam = u.erg / (u.cm ** 2 * u.s * u.AA * u.sr) snu = u.erg / (u.cm ** 2 * u.s * u.Hz * u.sr) wave = u.Quantity([4956.8, 4959.55, 4962.3], u.AA) sb_flam = [3.9135e-14, 4.0209e-14, 3.9169e-14] sb_fnu = [3.20735792e-25, 3.29903646e-25, 3.21727226e-25] # S(nu) <--> S(lambda) assert_allclose(snu.to( slam, sb_fnu, u.spectral_density(wave)), sb_flam, rtol=1e-6) assert_allclose(slam.to( snu, sb_flam, u.spectral_density(wave)), sb_fnu, rtol=1e-6) @pytest.mark.parametrize( ('from_unit', 'to_unit'), [(u.ph / u.cm ** 2 / u.s, (u.cm * u.cm * u.s) ** -1), (u.ph / u.cm ** 2 / u.s, u.erg / (u.cm * u.cm * u.s * u.keV)), (u.erg / u.cm ** 2 / u.s, (u.cm * u.cm * u.s) ** -1), (u.erg / u.cm ** 2 / u.s, u.erg / (u.cm * u.cm * u.s * u.keV))]) def test_spectraldensity_not_allowed(from_unit, to_unit): """Not allowed to succeed as per https://github.com/astropy/astropy/pull/10015 """ with pytest.raises(u.UnitConversionError, match='not convertible'): from_unit.to(to_unit, 1, u.spectral_density(1 * u.AA)) # The other way with pytest.raises(u.UnitConversionError, match='not convertible'): to_unit.to(from_unit, 1, u.spectral_density(1 * u.AA)) def test_equivalent_units(): from astropy.units import imperial with u.add_enabled_units(imperial): units = u.g.find_equivalent_units() units_set = set(units) match = set( [u.M_e, u.M_p, u.g, u.kg, u.solMass, u.t, u.u, u.M_earth, u.M_jup, imperial.oz, imperial.lb, imperial.st, imperial.ton, imperial.slug]) assert units_set == match r = repr(units) assert r.count('\n') == len(units) + 2 def test_equivalent_units2(): units = set(u.Hz.find_equivalent_units(u.spectral())) match = set( [u.AU, u.Angstrom, u.Hz, u.J, u.Ry, u.cm, u.eV, u.erg, u.lyr, u.lsec, u.m, u.micron, u.pc, u.solRad, u.Bq, u.Ci, u.k, u.earthRad, u.jupiterRad]) assert units == match from astropy.units import imperial with u.add_enabled_units(imperial): units = set(u.Hz.find_equivalent_units(u.spectral())) match = set( [u.AU, u.Angstrom, imperial.BTU, u.Hz, u.J, u.Ry, imperial.cal, u.cm, u.eV, u.erg, imperial.ft, imperial.fur, imperial.inch, imperial.kcal, u.lyr, u.m, imperial.mi, u.lsec, imperial.mil, u.micron, u.pc, u.solRad, imperial.yd, u.Bq, u.Ci, imperial.nmi, u.k, u.earthRad, u.jupiterRad]) assert units == match units = set(u.Hz.find_equivalent_units(u.spectral())) match = set( [u.AU, u.Angstrom, u.Hz, u.J, u.Ry, u.cm, u.eV, u.erg, u.lyr, u.lsec, u.m, u.micron, u.pc, u.solRad, u.Bq, u.Ci, u.k, u.earthRad, u.jupiterRad]) assert units == match def test_trivial_equivalency(): assert u.m.to(u.kg, equivalencies=[(u.m, u.kg)]) == 1.0 def test_invalid_equivalency(): with pytest.raises(ValueError): u.m.to(u.kg, equivalencies=[(u.m,)]) with pytest.raises(ValueError): u.m.to(u.kg, equivalencies=[(u.m, 5.0)]) def test_irrelevant_equivalency(): with pytest.raises(u.UnitsError): u.m.to(u.kg, equivalencies=[(u.m, u.l)]) def test_brightness_temperature(): omega_B = np.pi * (50 * u.arcsec) ** 2 nu = u.GHz * 5 tb = 7.052587837212582 * u.K np.testing.assert_almost_equal( tb.value, (1 * u.Jy).to_value( u.K, equivalencies=u.brightness_temperature(nu, beam_area=omega_B))) np.testing.assert_almost_equal( 1.0, tb.to_value( u.Jy, equivalencies=u.brightness_temperature(nu, beam_area=omega_B))) def test_swapped_args_brightness_temperature(): """ #5173 changes the order of arguments but accepts the old (deprecated) args """ omega_B = np.pi * (50 * u.arcsec) ** 2 nu = u.GHz * 5 tb = 7.052587837212582 * u.K with pytest.warns(AstropyDeprecationWarning) as w: result = (1*u.Jy).to( u.K, equivalencies=u.brightness_temperature(omega_B, nu)) roundtrip = result.to( u.Jy, equivalencies=u.brightness_temperature(omega_B, nu)) assert len(w) == 2 np.testing.assert_almost_equal(tb.value, result.value) np.testing.assert_almost_equal(roundtrip.value, 1) def test_surfacebrightness(): sb = 50*u.MJy/u.sr k = sb.to(u.K, u.brightness_temperature(50*u.GHz)) np.testing.assert_almost_equal(k.value, 0.650965, 5) assert k.unit.is_equivalent(u.K) def test_beam(): # pick a beam area: 2 pi r^2 = area of a Gaussina with sigma=50 arcsec omega_B = 2 * np.pi * (50 * u.arcsec) ** 2 new_beam = (5*u.beam).to(u.sr, u.equivalencies.beam_angular_area(omega_B)) np.testing.assert_almost_equal(omega_B.to(u.sr).value * 5, new_beam.value) assert new_beam.unit.is_equivalent(u.sr) # make sure that it's still consistent with 5 beams nbeams = new_beam.to(u.beam, u.equivalencies.beam_angular_area(omega_B)) np.testing.assert_almost_equal(nbeams.value, 5) # test inverse beam equivalency # (this is just a sanity check that the equivalency is defined; # it's not for testing numerical consistency) (5/u.beam).to(1/u.sr, u.equivalencies.beam_angular_area(omega_B)) # test practical case # (this is by far the most important one) flux_density = (5*u.Jy/u.beam).to(u.MJy/u.sr, u.equivalencies.beam_angular_area(omega_B)) np.testing.assert_almost_equal(flux_density.value, 13.5425483146382) def test_thermodynamic_temperature(): nu = 143 * u.GHz tb = 0.0026320501262630277 * u.K eq = u.thermodynamic_temperature(nu, T_cmb=2.7255 * u.K) np.testing.assert_almost_equal( tb.value, (1 * (u.MJy / u.sr)).to_value(u.K, equivalencies=eq)) np.testing.assert_almost_equal( 1.0, tb.to_value(u.MJy / u.sr, equivalencies=eq)) def test_equivalency_context(): with u.set_enabled_equivalencies(u.dimensionless_angles()): phase = u.Quantity(1., u.cycle) assert_allclose(np.exp(1j*phase), 1.) Omega = u.cycle / (1.*u.minute) assert_allclose(np.exp(1j*Omega*60.*u.second), 1.) # ensure we can turn off equivalencies even within the scope with pytest.raises(u.UnitsError): phase.to(1, equivalencies=None) # test the manager also works in the Quantity constructor. q1 = u.Quantity(phase, u.dimensionless_unscaled) assert_allclose(q1.value, u.cycle.to(u.radian)) # and also if we use a class that happens to have a unit attribute. class MyQuantityLookalike(np.ndarray): pass mylookalike = np.array(1.).view(MyQuantityLookalike) mylookalike.unit = 'cycle' # test the manager also works in the Quantity constructor. q2 = u.Quantity(mylookalike, u.dimensionless_unscaled) assert_allclose(q2.value, u.cycle.to(u.radian)) with u.set_enabled_equivalencies(u.spectral()): u.GHz.to(u.cm) eq_on = u.GHz.find_equivalent_units() with pytest.raises(u.UnitsError): u.GHz.to(u.cm, equivalencies=None) # without equivalencies, we should find a smaller (sub)set eq_off = u.GHz.find_equivalent_units() assert all(eq in set(eq_on) for eq in eq_off) assert set(eq_off) < set(eq_on) # Check the equivalency manager also works in ufunc evaluations, # not just using (wrong) scaling. [#2496] l2v = u.doppler_optical(6000 * u.angstrom) l1 = 6010 * u.angstrom assert l1.to(u.km/u.s, equivalencies=l2v) > 100. * u.km / u.s with u.set_enabled_equivalencies(l2v): assert l1 > 100. * u.km / u.s assert abs((l1 - 500. * u.km / u.s).to(u.angstrom)) < 1. * u.km/u.s def test_equivalency_context_manager(): base_registry = u.get_current_unit_registry() def just_to_from_units(equivalencies): return [(equiv[0], equiv[1]) for equiv in equivalencies] tf_dimensionless_angles = just_to_from_units(u.dimensionless_angles()) tf_spectral = just_to_from_units(u.spectral()) # <=1 b/c might have the dimensionless_redshift equivalency enabled. assert len(base_registry.equivalencies) <= 1 with u.set_enabled_equivalencies(u.dimensionless_angles()): new_registry = u.get_current_unit_registry() assert (set(just_to_from_units(new_registry.equivalencies)) == set(tf_dimensionless_angles)) assert set(new_registry.all_units) == set(base_registry.all_units) with u.set_enabled_equivalencies(u.spectral()): newer_registry = u.get_current_unit_registry() assert (set(just_to_from_units(newer_registry.equivalencies)) == set(tf_spectral)) assert (set(newer_registry.all_units) == set(base_registry.all_units)) assert (set(just_to_from_units(new_registry.equivalencies)) == set(tf_dimensionless_angles)) assert set(new_registry.all_units) == set(base_registry.all_units) with u.add_enabled_equivalencies(u.spectral()): newer_registry = u.get_current_unit_registry() assert (set(just_to_from_units(newer_registry.equivalencies)) == set(tf_dimensionless_angles) | set(tf_spectral)) assert (set(newer_registry.all_units) == set(base_registry.all_units)) assert base_registry is u.get_current_unit_registry() def test_temperature(): from astropy.units.imperial import deg_F, deg_R t_k = 0 * u.K assert_allclose(t_k.to_value(u.deg_C, u.temperature()), -273.15) assert_allclose(t_k.to_value(deg_F, u.temperature()), -459.67) t_k = 20 * u.K assert_allclose(t_k.to_value(deg_R, u.temperature()), 36.0) t_k = 20 * deg_R assert_allclose(t_k.to_value(u.K, u.temperature()), 11.11, atol=0.01) t_k = 20 * deg_F assert_allclose(t_k.to_value(deg_R, u.temperature()), 479.67) t_k = 20 * deg_R assert_allclose(t_k.to_value(deg_F, u.temperature()), -439.67) t_k = 20 * u.deg_C assert_allclose(t_k.to_value(deg_R, u.temperature()), 527.67) t_k = 20 * deg_R assert_allclose(t_k.to_value(u.deg_C, u.temperature()), -262.039, atol=0.01) def test_temperature_energy(): x = 1000 * u.K y = (x * constants.k_B).to(u.keV) assert_allclose(x.to_value(u.keV, u.temperature_energy()), y.value) assert_allclose(y.to_value(u.K, u.temperature_energy()), x.value) def test_molar_mass_amu(): x = 1 * (u.g/u.mol) y = 1 * u.u assert_allclose(x.to_value(u.u, u.molar_mass_amu()), y.value) assert_allclose(y.to_value(u.g/u.mol, u.molar_mass_amu()), x.value) with pytest.raises(u.UnitsError): x.to(u.u) def test_compose_equivalencies(): x = u.Unit("arcsec").compose(units=(u.pc,), equivalencies=u.parallax()) assert x[0] == u.pc x = u.Unit("2 arcsec").compose(units=(u.pc,), equivalencies=u.parallax()) assert x[0] == u.Unit(0.5 * u.pc) x = u.degree.compose(equivalencies=u.dimensionless_angles()) assert u.Unit(u.degree.to(u.radian)) in x x = (u.nm).compose(units=(u.m, u.s), equivalencies=u.doppler_optical(0.55*u.micron)) for y in x: if y.bases == [u.m, u.s]: assert y.powers == [1, -1] assert_allclose( y.scale, u.nm.to(u.m / u.s, equivalencies=u.doppler_optical(0.55 * u.micron))) break else: assert False, "Didn't find speed in compose results" def test_pixel_scale(): pix = 75*u.pix asec = 30*u.arcsec pixscale = 0.4*u.arcsec/u.pix pixscale2 = 2.5*u.pix/u.arcsec assert_quantity_allclose(pix.to(u.arcsec, u.pixel_scale(pixscale)), asec) assert_quantity_allclose(pix.to(u.arcmin, u.pixel_scale(pixscale)), asec) assert_quantity_allclose(pix.to(u.arcsec, u.pixel_scale(pixscale2)), asec) assert_quantity_allclose(pix.to(u.arcmin, u.pixel_scale(pixscale2)), asec) assert_quantity_allclose(asec.to(u.pix, u.pixel_scale(pixscale)), pix) assert_quantity_allclose(asec.to(u.pix, u.pixel_scale(pixscale2)), pix) def test_pixel_scale_invalid_scale_unit(): pixscale = 0.4 * u.arcsec pixscale2 = 0.4 * u.arcsec / u.pix ** 2 with pytest.raises(u.UnitsError, match="pixel dimension"): u.pixel_scale(pixscale) with pytest.raises(u.UnitsError, match="pixel dimension"): u.pixel_scale(pixscale2) def test_pixel_scale_acceptable_scale_unit(): pix = 75 * u.pix v = 3000 * (u.cm / u.s) pixscale = 0.4 * (u.m / u.s / u.pix) pixscale2 = 2.5 * (u.pix / (u.m / u.s)) assert_quantity_allclose(pix.to(u.m / u.s, u.pixel_scale(pixscale)), v) assert_quantity_allclose(pix.to(u.km / u.s, u.pixel_scale(pixscale)), v) assert_quantity_allclose(pix.to(u.m / u.s, u.pixel_scale(pixscale2)), v) assert_quantity_allclose(pix.to(u.km / u.s, u.pixel_scale(pixscale2)), v) assert_quantity_allclose(v.to(u.pix, u.pixel_scale(pixscale)), pix) assert_quantity_allclose(v.to(u.pix, u.pixel_scale(pixscale2)), pix) def test_plate_scale(): mm = 1.5*u.mm asec = 30*u.arcsec platescale = 20*u.arcsec/u.mm platescale2 = 0.05*u.mm/u.arcsec assert_quantity_allclose(mm.to(u.arcsec, u.plate_scale(platescale)), asec) assert_quantity_allclose(mm.to(u.arcmin, u.plate_scale(platescale)), asec) assert_quantity_allclose(mm.to(u.arcsec, u.plate_scale(platescale2)), asec) assert_quantity_allclose(mm.to(u.arcmin, u.plate_scale(platescale2)), asec) assert_quantity_allclose(asec.to(u.mm, u.plate_scale(platescale)), mm) assert_quantity_allclose(asec.to(u.mm, u.plate_scale(platescale2)), mm) def test_equivelency(): ps = u.pixel_scale(10*u.arcsec/u.pix) assert isinstance(ps, Equivalency) assert isinstance(ps.name, list) assert len(ps.name) == 1 assert ps.name[0] == "pixel_scale" assert isinstance(ps.kwargs, list) assert len(ps.kwargs) == 1 assert ps.kwargs[0] == dict({'pixscale': 10*u.arcsec/u.pix}) def test_add_equivelencies(): e1 = u.pixel_scale(10*u.arcsec/u.pixel) + u.temperature_energy() assert isinstance(e1, Equivalency) assert e1.name == ["pixel_scale", "temperature_energy"] assert isinstance(e1.kwargs, list) assert e1.kwargs == [dict({'pixscale': 10*u.arcsec/u.pix}), dict()] e2 = u.pixel_scale(10*u.arcsec/u.pixel) + [1, 2, 3] assert isinstance(e2, list) def test_pprint(): pprint_class = u.UnitBase.EquivalentUnitsList equiv_units_to_Hz = u.Hz.find_equivalent_units() assert pprint_class.__repr__(equiv_units_to_Hz).splitlines() == [ ' Primary name | Unit definition | Aliases ', '[', ' Bq | 1 / s | becquerel ,', ' Ci | 3.7e+10 / s | curie ,', ' Hz | 1 / s | Hertz, hertz ,', ']' ] assert pprint_class._repr_html_(equiv_units_to_Hz) == ( '' '' '' '' '' '
Primary nameUnit definitionAliases
Bq1 / sbecquerel
Ci3.7e+10 / scurie
Hz1 / sHertz, hertz
' ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/tests/test_format.py0000644000175100001710000005674100000000000021170 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """ Regression tests for the units.format package """ import warnings from contextlib import nullcontext from fractions import Fraction import pytest import numpy as np from numpy.testing import assert_allclose from astropy import units as u from astropy.constants import si from astropy.units import core, dex, UnitsWarning from astropy.units import format as u_format from astropy.units.utils import is_effectively_unity @pytest.mark.parametrize('strings, unit', [ (["m s", "m*s", "m.s"], u.m * u.s), (["m/s", "m*s**-1", "m /s", "m / s", "m/ s"], u.m / u.s), (["m**2", "m2", "m**(2)", "m**+2", "m+2", "m^(+2)"], u.m ** 2), (["m**-3", "m-3", "m^(-3)", "/m3"], u.m ** -3), (["m**(1.5)", "m(3/2)", "m**(3/2)", "m^(3/2)"], u.m ** 1.5), (["2.54 cm"], u.Unit(u.cm * 2.54)), (["10+8m"], u.Unit(u.m * 1e8)), # This is the VOUnits documentation, but doesn't seem to follow the # unity grammar (["3.45 10**(-4)Jy"], 3.45 * 1e-4 * u.Jy) (["sqrt(m)"], u.m ** 0.5), (["dB(mW)", "dB (mW)"], u.DecibelUnit(u.mW)), (["mag"], u.mag), (["mag(ct/s)"], u.MagUnit(u.ct / u.s)), (["dex"], u.dex), (["dex(cm s**-2)", "dex(cm/s2)"], u.DexUnit(u.cm / u.s**2)), ]) def test_unit_grammar(strings, unit): for s in strings: print(s) unit2 = u_format.Generic.parse(s) assert unit2 == unit @pytest.mark.parametrize('string', ['sin( /pixel /s)', 'mag(mag)', 'dB(dB(mW))', 'dex()']) def test_unit_grammar_fail(string): with pytest.raises(ValueError): print(string) u_format.Generic.parse(string) @pytest.mark.parametrize('strings, unit', [ (["0.1nm"], u.AA), (["mW/m2"], u.Unit(u.erg / u.cm ** 2 / u.s)), (["mW/(m2)"], u.Unit(u.erg / u.cm ** 2 / u.s)), (["km/s", "km.s-1"], u.km / u.s), (["10pix/nm"], u.Unit(10 * u.pix / u.nm)), (["1.5x10+11m"], u.Unit(1.5e11 * u.m)), (["1.5×10+11m"], u.Unit(1.5e11 * u.m)), (["m2"], u.m ** 2), (["10+21m"], u.Unit(u.m * 1e21)), (["2.54cm"], u.Unit(u.cm * 2.54)), (["20%"], 0.20 * u.dimensionless_unscaled), (["10+9"], 1.e9 * u.dimensionless_unscaled), (["2x10-9"], 2.e-9 * u.dimensionless_unscaled), (["---"], u.dimensionless_unscaled), (["ma"], u.ma), (["mAU"], u.mAU), (["uarcmin"], u.uarcmin), (["uarcsec"], u.uarcsec), (["kbarn"], u.kbarn), (["Gbit"], u.Gbit), (["Gibit"], 2 ** 30 * u.bit), (["kbyte"], u.kbyte), (["mRy"], 0.001 * u.Ry), (["mmag"], u.mmag), (["Mpc"], u.Mpc), (["Gyr"], u.Gyr), (["°"], u.degree), (["°/s"], u.degree / u.s), (["Å"], u.AA), (["Å/s"], u.AA / u.s), (["\\h"], si.h), (["[cm/s2]"], dex(u.cm / u.s ** 2)), (["[K]"], dex(u.K)), (["[-]"], dex(u.dimensionless_unscaled))]) def test_cds_grammar(strings, unit): for s in strings: print(s) unit2 = u_format.CDS.parse(s) assert unit2 == unit @pytest.mark.parametrize('string', [ '0.1 nm', 'solMass(3/2)', 'km / s', 'km s-1', 'pix0.1nm', 'pix/(0.1nm)', 'km*s', 'km**2', '5x8+3m', '0.1---', '---m', 'm---', '--', '0.1-', '-m', 'm-', 'mag(s-1)', 'dB(mW)', 'dex(cm s-2)', '[--]']) def test_cds_grammar_fail(string): with pytest.raises(ValueError): print(string) u_format.CDS.parse(string) def test_cds_dimensionless(): assert u.Unit('---', format='cds') == u.dimensionless_unscaled assert u.dimensionless_unscaled.to_string(format='cds') == "---" def test_cds_log10_dimensionless(): assert u.Unit('[-]', format='cds') == u.dex(u.dimensionless_unscaled) assert u.dex(u.dimensionless_unscaled).to_string(format='cds') == "[-]" # These examples are taken from the EXAMPLES section of # https://heasarc.gsfc.nasa.gov/docs/heasarc/ofwg/docs/general/ogip_93_001/ @pytest.mark.parametrize('strings, unit', [ (["count /s", "count/s", "count s**(-1)", "count / s", "count /s "], u.count / u.s), (["/pixel /s", "/(pixel * s)"], (u.pixel * u.s) ** -1), (["count /m**2 /s /eV", "count m**(-2) * s**(-1) * eV**(-1)", "count /(m**2 * s * eV)"], u.count * u.m ** -2 * u.s ** -1 * u.eV ** -1), (["erg /pixel /s /GHz", "erg /s /GHz /pixel", "erg /pixel /(s * GHz)"], u.erg / (u.s * u.GHz * u.pixel)), (["keV**2 /yr /angstrom", "10**(10) keV**2 /yr /m"], # Though this is given as an example, it seems to violate the rules # of not raising scales to powers, so I'm just excluding it # "(10**2 MeV)**2 /yr /m" u.keV**2 / (u.yr * u.angstrom)), (["10**(46) erg /s", "10**46 erg /s", "10**(39) J /s", "10**(39) W", "10**(15) YW", "YJ /fs"], 10**46 * u.erg / u.s), (["10**(-7) J /cm**2 /MeV", "10**(-9) J m**(-2) eV**(-1)", "nJ m**(-2) eV**(-1)", "nJ /m**2 /eV"], 10 ** -7 * u.J * u.cm ** -2 * u.MeV ** -1), (["sqrt(erg /pixel /s /GHz)", "(erg /pixel /s /GHz)**(0.5)", "(erg /pixel /s /GHz)**(1/2)", "erg**(0.5) pixel**(-0.5) s**(-0.5) GHz**(-0.5)"], (u.erg * u.pixel ** -1 * u.s ** -1 * u.GHz ** -1) ** 0.5), (["(count /s) (/pixel /s)", "(count /s) * (/pixel /s)", "count /pixel /s**2"], (u.count / u.s) * (1.0 / (u.pixel * u.s)))]) def test_ogip_grammar(strings, unit): for s in strings: print(s) unit2 = u_format.OGIP.parse(s) assert unit2 == unit @pytest.mark.parametrize('string', [ 'log(photon /m**2 /s /Hz)', 'sin( /pixel /s)', 'log(photon /cm**2 /s /Hz) /(sin( /pixel /s))', 'log(photon /cm**2 /s /Hz) (sin( /pixel /s))**(-1)', 'dB(mW)', 'dex(cm/s**2)']) def test_ogip_grammar_fail(string): with pytest.raises(ValueError): print(string) u_format.OGIP.parse(string) class RoundtripBase: deprecated_units = set() def check_roundtrip(self, unit, output_format=None): if output_format is None: output_format = self.format_ with warnings.catch_warnings(): warnings.simplefilter('ignore') # Same warning shows up multiple times s = unit.to_string(output_format) if s in self.deprecated_units: with pytest.warns(UnitsWarning, match='deprecated') as w: a = core.Unit(s, format=self.format_) assert len(w) == 1 else: a = core.Unit(s, format=self.format_) # No warning assert_allclose(a.decompose().scale, unit.decompose().scale, rtol=1e-9) def check_roundtrip_decompose(self, unit): ud = unit.decompose() s = ud.to_string(self.format_) assert ' ' not in s a = core.Unit(s, format=self.format_) assert_allclose(a.decompose().scale, ud.scale, rtol=1e-5) class TestRoundtripGeneric(RoundtripBase): format_ = 'generic' @pytest.mark.parametrize('unit', [ unit for unit in u.__dict__.values() if (isinstance(unit, core.UnitBase) and not isinstance(unit, core.PrefixUnit))]) def test_roundtrip(self, unit): self.check_roundtrip(unit) self.check_roundtrip(unit, output_format='unicode') self.check_roundtrip_decompose(unit) class TestRoundtripVOUnit(RoundtripBase): format_ = 'vounit' deprecated_units = u_format.VOUnit._deprecated_units @pytest.mark.parametrize('unit', [ unit for unit in u_format.VOUnit._units.values() if (isinstance(unit, core.UnitBase) and not isinstance(unit, core.PrefixUnit))]) def test_roundtrip(self, unit): self.check_roundtrip(unit) if unit not in (u.mag, u.dB): self.check_roundtrip_decompose(unit) class TestRoundtripFITS(RoundtripBase): format_ = 'fits' deprecated_units = u_format.Fits._deprecated_units @pytest.mark.parametrize('unit', [ unit for unit in u_format.Fits._units.values() if (isinstance(unit, core.UnitBase) and not isinstance(unit, core.PrefixUnit))]) def test_roundtrip(self, unit): self.check_roundtrip(unit) class TestRoundtripCDS(RoundtripBase): format_ = 'cds' @pytest.mark.parametrize('unit', [ unit for unit in u_format.CDS._units.values() if (isinstance(unit, core.UnitBase) and not isinstance(unit, core.PrefixUnit))]) def test_roundtrip(self, unit): self.check_roundtrip(unit) if unit == u.mag: # Skip mag: decomposes into dex, which is unknown to CDS. return self.check_roundtrip_decompose(unit) @pytest.mark.parametrize('unit', [u.dex(unit) for unit in (u.cm/u.s**2, u.K, u.Lsun)]) def test_roundtrip_dex(self, unit): string = unit.to_string(format='cds') recovered = u.Unit(string, format='cds') assert recovered == unit class TestRoundtripOGIP(RoundtripBase): format_ = 'ogip' deprecated_units = u_format.OGIP._deprecated_units | {'d'} @pytest.mark.parametrize('unit', [ unit for unit in u_format.OGIP._units.values() if (isinstance(unit, core.UnitBase) and not isinstance(unit, core.PrefixUnit))]) def test_roundtrip(self, unit): if str(unit) in ('d', '0.001 Crab'): # Special-case day, which gets auto-converted to hours, and mCrab, # which the default check does not recognize as a deprecated unit. with pytest.warns(UnitsWarning): s = unit.to_string(self.format_) a = core.Unit(s, format=self.format_) assert_allclose(a.decompose().scale, unit.decompose().scale, rtol=1e-9) else: self.check_roundtrip(unit) if str(unit) in ('mag', 'byte', 'Crab'): # Skip mag and byte, which decompose into dex and bit, resp., # both of which are unknown to OGIP, as well as Crab, which does # not decompose, and thus gives a deprecated unit warning. return power_of_ten = np.log10(unit.decompose().scale) if abs(power_of_ten - round(power_of_ten)) > 1e-3: ctx = pytest.warns(UnitsWarning, match='power of 10') elif str(unit) == '0.001 Crab': ctx = pytest.warns(UnitsWarning, match='deprecated') else: ctx = nullcontext() with ctx: self.check_roundtrip_decompose(unit) def test_fits_units_available(): u_format.Fits._units def test_vo_units_available(): u_format.VOUnit._units def test_cds_units_available(): u_format.CDS._units def test_cds_non_ascii_unit(): """Regression test for #5350. This failed with a decoding error as Îŧas could not be represented in ascii.""" from astropy.units import cds with cds.enable(): u.radian.find_equivalent_units(include_prefix_units=True) def test_latex(): fluxunit = u.erg / (u.cm ** 2 * u.s) assert fluxunit.to_string('latex') == r'$\mathrm{\frac{erg}{s\,cm^{2}}}$' def test_new_style_latex(): fluxunit = u.erg / (u.cm ** 2 * u.s) assert f"{fluxunit:latex}" == r'$\mathrm{\frac{erg}{s\,cm^{2}}}$' def test_latex_scale(): fluxunit = u.Unit(1.e-24 * u.erg / (u.cm ** 2 * u.s * u.Hz)) latex = r'$\mathrm{1 \times 10^{-24}\,\frac{erg}{Hz\,s\,cm^{2}}}$' assert fluxunit.to_string('latex') == latex def test_latex_inline_scale(): fluxunit = u.Unit(1.e-24 * u.erg / (u.cm ** 2 * u.s * u.Hz)) latex_inline = (r'$\mathrm{1 \times 10^{-24}\,erg' r'\,Hz^{-1}\,s^{-1}\,cm^{-2}}$') assert fluxunit.to_string('latex_inline') == latex_inline @pytest.mark.parametrize('format_spec, string', [ ('generic', 'erg / (cm2 s)'), ('s', 'erg / (cm2 s)'), ('console', ' erg \n ------\n s cm^2'), ('latex', '$\\mathrm{\\frac{erg}{s\\,cm^{2}}}$'), ('latex_inline', '$\\mathrm{erg\\,s^{-1}\\,cm^{-2}}$'), ('>20s', ' erg / (cm2 s)')]) def test_format_styles(format_spec, string): fluxunit = u.erg / (u.cm ** 2 * u.s) assert format(fluxunit, format_spec) == string def test_flatten_to_known(): myunit = u.def_unit("FOOBAR_One", u.erg / u.Hz) assert myunit.to_string('fits') == 'erg Hz-1' myunit2 = myunit * u.bit ** 3 assert myunit2.to_string('fits') == 'bit3 erg Hz-1' def test_flatten_impossible(): myunit = u.def_unit("FOOBAR_Two") with u.add_enabled_units(myunit), pytest.raises(ValueError): myunit.to_string('fits') def test_console_out(): """ Issue #436. """ u.Jy.decompose().to_string('console') def test_flexible_float(): assert u.min._represents.to_string('latex') == r'$\mathrm{60\,s}$' def test_fits_to_string_function_error(): """Test function raises TypeError on bad input. This instead of returning None, see gh-11825. """ with pytest.raises(TypeError, match='unit argument must be'): u_format.Fits.to_string(None) def test_fraction_repr(): area = u.cm ** 2.0 assert '.' not in area.to_string('latex') fractional = u.cm ** 2.5 assert '5/2' in fractional.to_string('latex') assert fractional.to_string('unicode') == 'cmâĩ⸍²' def test_scale_effectively_unity(): """Scale just off unity at machine precision level is OK. Ensures #748 does not recur """ a = (3. * u.N).cgs assert is_effectively_unity(a.unit.scale) assert len(a.__repr__().split()) == 3 def test_percent(): """Test that the % unit is properly recognized. Since % is a special symbol, this goes slightly beyond the round-tripping tested above.""" assert u.Unit('%') == u.percent == u.Unit(0.01) assert u.Unit('%', format='cds') == u.Unit(0.01) assert u.Unit(0.01).to_string('cds') == '%' with pytest.raises(ValueError): u.Unit('%', format='fits') with pytest.raises(ValueError): u.Unit('%', format='vounit') def test_scaled_dimensionless(): """Test that scaled dimensionless units are properly recognized in generic and CDS, but not in fits and vounit.""" assert u.Unit('0.1') == u.Unit(0.1) == 0.1 * u.dimensionless_unscaled assert u.Unit('1.e-4') == u.Unit(1.e-4) assert u.Unit('10-4', format='cds') == u.Unit(1.e-4) assert u.Unit('10+8').to_string('cds') == '10+8' with pytest.raises(ValueError): u.Unit(0.15).to_string('fits') assert u.Unit(0.1).to_string('fits') == '10**-1' with pytest.raises(ValueError): u.Unit(0.1).to_string('vounit') def test_deprecated_did_you_mean_units(): with pytest.raises(ValueError) as exc_info: u.Unit('ANGSTROM', format='fits') assert 'Did you mean Angstrom or angstrom?' in str(exc_info.value) with pytest.raises(ValueError) as exc_info: u.Unit('crab', format='ogip') assert 'Crab (deprecated)' in str(exc_info.value) assert 'mCrab (deprecated)' in str(exc_info.value) with pytest.warns(UnitsWarning, match=r'.* Did you mean 0\.1nm, Angstrom ' r'\(deprecated\) or angstrom \(deprecated\)\?') as w: u.Unit('ANGSTROM', format='vounit') assert len(w) == 1 assert str(w[0].message).count('0.1nm') == 1 with pytest.warns(UnitsWarning, match=r'.* 0\.1nm\.') as w: u.Unit('angstrom', format='vounit') assert len(w) == 1 @pytest.mark.parametrize('string', ['mag(ct/s)', 'dB(mW)', 'dex(cm s**-2)']) def test_fits_function(string): # Function units cannot be written, so ensure they're not parsed either. with pytest.raises(ValueError): print(string) u_format.Fits().parse(string) @pytest.mark.parametrize('string', ['mag(ct/s)', 'dB(mW)', 'dex(cm s**-2)']) def test_vounit_function(string): # Function units cannot be written, so ensure they're not parsed either. with pytest.raises(ValueError), warnings.catch_warnings(): warnings.simplefilter('ignore') # ct, dex also raise warnings - irrelevant here. u_format.VOUnit().parse(string) def test_vounit_binary_prefix(): u.Unit('KiB', format='vounit') == u.Unit('1024 B') u.Unit('Kibyte', format='vounit') == u.Unit('1024 B') u.Unit('Kibit', format='vounit') == u.Unit('1024 B') with pytest.warns(UnitsWarning) as w: u.Unit('kibibyte', format='vounit') assert len(w) == 1 def test_vounit_unknown(): assert u.Unit('unknown', format='vounit') is None assert u.Unit('UNKNOWN', format='vounit') is None assert u.Unit('', format='vounit') is u.dimensionless_unscaled def test_vounit_details(): with pytest.warns(UnitsWarning, match='deprecated') as w: assert u.Unit('Pa', format='vounit') is u.Pascal assert len(w) == 1 # The da- prefix is not allowed, and the d- prefix is discouraged assert u.dam.to_string('vounit') == '10m' assert u.Unit('dam dag').to_string('vounit') == '100g.m' # Parse round-trip with pytest.warns(UnitsWarning, match='deprecated'): flam = u.erg / u.cm / u.cm / u.s / u.AA x = u.format.VOUnit.to_string(flam) assert x == 'Angstrom**-1.cm**-2.erg.s**-1' new_flam = u.format.VOUnit.parse(x) assert new_flam == flam @pytest.mark.parametrize('unit, vounit, number, scale, voscale', [('nm', 'nm', 0.1, '10^-1', '0.1'), ('fm', 'fm', 100.0, '10+2', '100'), ('m^2', 'm**2', 100.0, '100.0', '100'), ('cm', 'cm', 2.54, '2.54', '2.54'), ('kg', 'kg', 1.898124597e27, '1.898124597E27', '1.8981246e+27'), ('m/s', 'm.s**-1', 299792458.0, '299792458', '2.9979246e+08'), ('cm2', 'cm**2', 1.e-20, '10^(-20)', '1e-20')]) def test_vounit_scale_factor(unit, vounit, number, scale, voscale): x = u.Unit(f'{scale} {unit}') assert x == number * u.Unit(unit) assert x.to_string(format='vounit') == voscale + vounit def test_vounit_custom(): x = u.Unit("'foo' m", format='vounit') x_vounit = x.to_string('vounit') assert x_vounit == "'foo'.m" x_string = x.to_string() assert x_string == "foo m" x = u.Unit("m'foo' m", format='vounit') assert x.bases[1]._represents.scale == 0.001 x_vounit = x.to_string('vounit') assert x_vounit == "m.m'foo'" x_string = x.to_string() assert x_string == 'm mfoo' def test_vounit_implicit_custom(): # Yikes, this becomes "femto-urlong"... But at least there's a warning. with pytest.warns(UnitsWarning) as w: x = u.Unit("furlong/week", format="vounit") assert x.bases[0]._represents.scale == 1e-15 assert x.bases[0]._represents.bases[0].name == 'urlong' assert len(w) == 2 assert 'furlong' in str(w[0].message) assert 'week' in str(w[1].message) @pytest.mark.parametrize('scale, number, string', [('10+2', 100, '10**2'), ('10(+2)', 100, '10**2'), ('10**+2', 100, '10**2'), ('10**(+2)', 100, '10**2'), ('10^+2', 100, '10**2'), ('10^(+2)', 100, '10**2'), ('10**2', 100, '10**2'), ('10**(2)', 100, '10**2'), ('10^2', 100, '10**2'), ('10^(2)', 100, '10**2'), ('10-20', 10**(-20), '10**-20'), ('10(-20)', 10**(-20), '10**-20'), ('10**-20', 10**(-20), '10**-20'), ('10**(-20)', 10**(-20), '10**-20'), ('10^-20', 10**(-20), '10**-20'), ('10^(-20)', 10**(-20), '10**-20'), ]) def test_fits_scale_factor(scale, number, string): x = u.Unit(scale + ' erg/(s cm**2 Angstrom)', format='fits') assert x == number * (u.erg / u.s / u.cm ** 2 / u.Angstrom) assert x.to_string(format='fits') == string + ' Angstrom-1 cm-2 erg s-1' x = u.Unit(scale + '*erg/(s cm**2 Angstrom)', format='fits') assert x == number * (u.erg / u.s / u.cm ** 2 / u.Angstrom) assert x.to_string(format='fits') == string + ' Angstrom-1 cm-2 erg s-1' def test_fits_scale_factor_errors(): with pytest.raises(ValueError): x = u.Unit('1000 erg/(s cm**2 Angstrom)', format='fits') with pytest.raises(ValueError): x = u.Unit('12 erg/(s cm**2 Angstrom)', format='fits') x = u.Unit(1.2 * u.erg) with pytest.raises(ValueError): x.to_string(format='fits') x = u.Unit(100.0 * u.erg) assert x.to_string(format='fits') == '10**2 erg' def test_double_superscript(): """Regression test for #5870, #8699, #9218; avoid double superscripts.""" assert (u.deg).to_string("latex") == r'$\mathrm{{}^{\circ}}$' assert (u.deg**2).to_string("latex") == r'$\mathrm{deg^{2}}$' assert (u.arcmin).to_string("latex") == r'$\mathrm{{}^{\prime}}$' assert (u.arcmin**2).to_string("latex") == r'$\mathrm{arcmin^{2}}$' assert (u.arcsec).to_string("latex") == r'$\mathrm{{}^{\prime\prime}}$' assert (u.arcsec**2).to_string("latex") == r'$\mathrm{arcsec^{2}}$' assert (u.hourangle).to_string("latex") == r'$\mathrm{{}^{h}}$' assert (u.hourangle**2).to_string("latex") == r'$\mathrm{hourangle^{2}}$' assert (u.electron).to_string("latex") == r'$\mathrm{e^{-}}$' assert (u.electron**2).to_string("latex") == r'$\mathrm{electron^{2}}$' @pytest.mark.parametrize('power,expected', ( (1., 'm'), (2., 'm2'), (-10, '1 / m10'), (1.5, 'm(3/2)'), (2/3, 'm(2/3)'), (7/11, 'm(7/11)'), (-1/64, '1 / m(1/64)'), (1/100, 'm(1/100)'), (2/101, 'm(0.019801980198019802)'), (Fraction(2, 101), 'm(2/101)'))) def test_powers(power, expected): """Regression test for #9279 - powers should not be oversimplified.""" unit = u.m ** power s = unit.to_string() assert s == expected assert unit == s @pytest.mark.parametrize('string,unit', [ ('\N{MICRO SIGN}g', u.microgram), ('\N{GREEK SMALL LETTER MU}g', u.microgram), ('g\N{MINUS SIGN}1', u.g**(-1)), ('m\N{SUPERSCRIPT MINUS}\N{SUPERSCRIPT ONE}', 1 / u.m), ('m s\N{SUPERSCRIPT MINUS}\N{SUPERSCRIPT ONE}', u.m / u.s), ('m\N{SUPERSCRIPT TWO}', u.m**2), ('m\N{SUPERSCRIPT PLUS SIGN}\N{SUPERSCRIPT TWO}', u.m**2), ('m\N{SUPERSCRIPT THREE}', u.m**3), ('m\N{SUPERSCRIPT ONE}\N{SUPERSCRIPT ZERO}', u.m**10), ('\N{GREEK CAPITAL LETTER OMEGA}', u.ohm), ('\N{OHM SIGN}', u.ohm), # deprecated but for compatibility ('\N{MICRO SIGN}\N{GREEK CAPITAL LETTER OMEGA}', u.microOhm), ('\N{ANGSTROM SIGN}', u.Angstrom), ('\N{ANGSTROM SIGN} \N{OHM SIGN}', u.Angstrom * u.Ohm), ('\N{LATIN CAPITAL LETTER A WITH RING ABOVE}', u.Angstrom), ('\N{LATIN CAPITAL LETTER A}\N{COMBINING RING ABOVE}', u.Angstrom), ('m\N{ANGSTROM SIGN}', u.milliAngstrom), ('°C', u.deg_C), ('°', u.deg), ('M⊙', u.Msun), # \N{CIRCLED DOT OPERATOR} ('L☉', u.Lsun), # \N{SUN} ('M⊕', u.Mearth), # normal earth symbol = \N{CIRCLED PLUS} ('M♁', u.Mearth), # be generous with \N{EARTH} ('R♃', u.Rjup), # \N{JUPITER} ('′', u.arcmin), # \N{PRIME} ('R∞', u.Ry), ('Mₚ', u.M_p), ]) def test_unicode(string, unit): assert u_format.Generic.parse(string) == unit assert u.Unit(string) == unit @pytest.mark.parametrize('string', [ 'g\N{MICRO SIGN}', 'g\N{MINUS SIGN}', 'm\N{SUPERSCRIPT MINUS}1', 'm+\N{SUPERSCRIPT ONE}', 'm\N{MINUS SIGN}\N{SUPERSCRIPT ONE}', 'k\N{ANGSTROM SIGN}', ]) def test_unicode_failures(string): with pytest.raises(ValueError): u.Unit(string) @pytest.mark.parametrize('format_', ('unicode', 'latex', 'latex_inline')) def test_parse_error_message_for_output_only_format(format_): with pytest.raises(NotImplementedError, match='not parse'): u.Unit('m', format=format_) def test_unknown_parser(): with pytest.raises(ValueError, match=r"Unknown.*unicode'\] for output only"): u.Unit('m', format='foo') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/tests/test_logarithmic.py0000644000175100001710000010064700000000000022175 0ustar00vstsdocker# coding: utf-8 # Licensed under a 3-clause BSD style license - see LICENSE.rst """ Test the Logarithmic Units and Quantities """ import pickle import itertools import pytest import numpy as np from numpy.testing import assert_allclose from astropy.tests.helper import assert_quantity_allclose from astropy import units as u, constants as c lu_units = [u.dex, u.mag, u.decibel] lu_subclasses = [u.DexUnit, u.MagUnit, u.DecibelUnit] lq_subclasses = [u.Dex, u.Magnitude, u.Decibel] pu_sample = (u.dimensionless_unscaled, u.m, u.g/u.s**2, u.Jy) class TestLogUnitCreation: def test_logarithmic_units(self): """Check logarithmic units are set up correctly.""" assert u.dB.to(u.dex) == 0.1 assert u.dex.to(u.mag) == -2.5 assert u.mag.to(u.dB) == -4 @pytest.mark.parametrize('lu_unit, lu_cls', zip(lu_units, lu_subclasses)) def test_callable_units(self, lu_unit, lu_cls): assert isinstance(lu_unit, u.UnitBase) assert callable(lu_unit) assert lu_unit._function_unit_class is lu_cls @pytest.mark.parametrize('lu_unit', lu_units) def test_equality_to_normal_unit_for_dimensionless(self, lu_unit): lu = lu_unit() assert lu == lu._default_function_unit # eg, MagUnit() == u.mag assert lu._default_function_unit == lu # and u.mag == MagUnit() @pytest.mark.parametrize('lu_unit, physical_unit', itertools.product(lu_units, pu_sample)) def test_call_units(self, lu_unit, physical_unit): """Create a LogUnit subclass using the callable unit and physical unit, and do basic check that output is right.""" lu1 = lu_unit(physical_unit) assert lu1.physical_unit == physical_unit assert lu1.function_unit == lu1._default_function_unit def test_call_invalid_unit(self): with pytest.raises(TypeError): u.mag([]) with pytest.raises(ValueError): u.mag(u.mag()) @pytest.mark.parametrize('lu_cls, physical_unit', itertools.product( lu_subclasses + [u.LogUnit], pu_sample)) def test_subclass_creation(self, lu_cls, physical_unit): """Create a LogUnit subclass object for given physical unit, and do basic check that output is right.""" lu1 = lu_cls(physical_unit) assert lu1.physical_unit == physical_unit assert lu1.function_unit == lu1._default_function_unit lu2 = lu_cls(physical_unit, function_unit=2*lu1._default_function_unit) assert lu2.physical_unit == physical_unit assert lu2.function_unit == u.Unit(2*lu2._default_function_unit) with pytest.raises(ValueError): lu_cls(physical_unit, u.m) def test_lshift_magnitude(self): mag = 1. << u.ABmag assert isinstance(mag, u.Magnitude) assert mag.unit == u.ABmag assert mag.value == 1. # same test for an array, which should produce a view a2 = np.arange(10.) q2 = a2 << u.ABmag assert isinstance(q2, u.Magnitude) assert q2.unit == u.ABmag assert np.all(q2.value == a2) a2[9] = 0. assert np.all(q2.value == a2) # a different magnitude unit mag = 10. << u.STmag assert isinstance(mag, u.Magnitude) assert mag.unit == u.STmag assert mag.value == 10. def test_ilshift_magnitude(self): # test in-place operation and conversion mag_fnu_cgs = u.mag(u.erg/u.s/u.cm**2/u.Hz) m = np.arange(10.0) * u.mag(u.Jy) jy = m.physical m2 = m << mag_fnu_cgs assert np.all(m2 == m.to(mag_fnu_cgs)) m2 = m m <<= mag_fnu_cgs assert m is m2 # Check it was done in-place! assert np.all(m.value == m2.value) assert m.unit == mag_fnu_cgs # Check it works if equivalencies are in-place. with u.add_enabled_equivalencies(u.spectral_density(5500*u.AA)): st = jy.to(u.ST) m <<= u.STmag assert m is m2 assert_quantity_allclose(m.physical, st) assert m.unit == u.STmag def test_lshift_errors(self): m = np.arange(10.0) * u.mag(u.Jy) with pytest.raises(u.UnitsError): m << u.STmag with pytest.raises(u.UnitsError): m << u.Jy with pytest.raises(u.UnitsError): m <<= u.STmag with pytest.raises(u.UnitsError): m <<= u.Jy def test_predefined_magnitudes(): assert_quantity_allclose((-21.1*u.STmag).physical, 1.*u.erg/u.cm**2/u.s/u.AA) assert_quantity_allclose((-48.6*u.ABmag).physical, 1.*u.erg/u.cm**2/u.s/u.Hz) assert_quantity_allclose((0*u.M_bol).physical, c.L_bol0) assert_quantity_allclose((0*u.m_bol).physical, c.L_bol0/(4.*np.pi*(10.*c.pc)**2)) def test_predefined_reinitialisation(): assert u.mag('STflux') == u.STmag assert u.mag('ABflux') == u.ABmag assert u.mag('Bol') == u.M_bol assert u.mag('bol') == u.m_bol # required for backwards-compatibility, at least unless deprecated assert u.mag('ST') == u.STmag assert u.mag('AB') == u.ABmag def test_predefined_string_roundtrip(): """Ensure round-tripping; see #5015""" assert u.Unit(u.STmag.to_string()) == u.STmag assert u.Unit(u.ABmag.to_string()) == u.ABmag assert u.Unit(u.M_bol.to_string()) == u.M_bol assert u.Unit(u.m_bol.to_string()) == u.m_bol def test_inequality(): """Check __ne__ works (regression for #5342).""" lu1 = u.mag(u.Jy) lu2 = u.dex(u.Jy) lu3 = u.mag(u.Jy**2) lu4 = lu3 - lu1 assert lu1 != lu2 assert lu1 != lu3 assert lu1 == lu4 class TestLogUnitStrings: def test_str(self): """Do some spot checks that str, repr, etc. work as expected.""" lu1 = u.mag(u.Jy) assert str(lu1) == 'mag(Jy)' assert repr(lu1) == 'Unit("mag(Jy)")' assert lu1.to_string('generic') == 'mag(Jy)' with pytest.raises(ValueError): lu1.to_string('fits') with pytest.raises(ValueError): lu1.to_string(format='cds') lu2 = u.dex() assert str(lu2) == 'dex' assert repr(lu2) == 'Unit("dex(1)")' assert lu2.to_string() == 'dex(1)' lu3 = u.MagUnit(u.Jy, function_unit=2*u.mag) assert str(lu3) == '2 mag(Jy)' assert repr(lu3) == 'MagUnit("Jy", unit="2 mag")' assert lu3.to_string() == '2 mag(Jy)' lu4 = u.mag(u.ct) assert lu4.to_string('generic') == 'mag(ct)' assert lu4.to_string('latex') == ('$\\mathrm{mag}$$\\mathrm{\\left( ' '\\mathrm{ct} \\right)}$') assert lu4._repr_latex_() == lu4.to_string('latex') class TestLogUnitConversion: @pytest.mark.parametrize('lu_unit, physical_unit', itertools.product(lu_units, pu_sample)) def test_physical_unit_conversion(self, lu_unit, physical_unit): """Check various LogUnit subclasses are equivalent and convertible to their non-log counterparts.""" lu1 = lu_unit(physical_unit) assert lu1.is_equivalent(physical_unit) assert lu1.to(physical_unit, 0.) == 1. assert physical_unit.is_equivalent(lu1) assert physical_unit.to(lu1, 1.) == 0. pu = u.Unit(8.*physical_unit) assert lu1.is_equivalent(physical_unit) assert lu1.to(pu, 0.) == 0.125 assert pu.is_equivalent(lu1) assert_allclose(pu.to(lu1, 0.125), 0., atol=1.e-15) # Check we round-trip. value = np.linspace(0., 10., 6) assert_allclose(pu.to(lu1, lu1.to(pu, value)), value, atol=1.e-15) # And that we're not just returning True all the time. pu2 = u.g assert not lu1.is_equivalent(pu2) with pytest.raises(u.UnitsError): lu1.to(pu2) assert not pu2.is_equivalent(lu1) with pytest.raises(u.UnitsError): pu2.to(lu1) @pytest.mark.parametrize('lu_unit', lu_units) def test_container_unit_conversion(self, lu_unit): """Check that conversion to logarithmic units (u.mag, u.dB, u.dex) is only possible when the physical unit is dimensionless.""" values = np.linspace(0., 10., 6) lu1 = lu_unit(u.dimensionless_unscaled) assert lu1.is_equivalent(lu1.function_unit) assert_allclose(lu1.to(lu1.function_unit, values), values) lu2 = lu_unit(u.Jy) assert not lu2.is_equivalent(lu2.function_unit) with pytest.raises(u.UnitsError): lu2.to(lu2.function_unit, values) @pytest.mark.parametrize( 'flu_unit, tlu_unit, physical_unit', itertools.product(lu_units, lu_units, pu_sample)) def test_subclass_conversion(self, flu_unit, tlu_unit, physical_unit): """Check various LogUnit subclasses are equivalent and convertible to each other if they correspond to equivalent physical units.""" values = np.linspace(0., 10., 6) flu = flu_unit(physical_unit) tlu = tlu_unit(physical_unit) assert flu.is_equivalent(tlu) assert_allclose(flu.to(tlu), flu.function_unit.to(tlu.function_unit)) assert_allclose(flu.to(tlu, values), values * flu.function_unit.to(tlu.function_unit)) tlu2 = tlu_unit(u.Unit(100.*physical_unit)) assert flu.is_equivalent(tlu2) # Check that we round-trip. assert_allclose(flu.to(tlu2, tlu2.to(flu, values)), values, atol=1.e-15) tlu3 = tlu_unit(physical_unit.to_system(u.si)[0]) assert flu.is_equivalent(tlu3) assert_allclose(flu.to(tlu3, tlu3.to(flu, values)), values, atol=1.e-15) tlu4 = tlu_unit(u.g) assert not flu.is_equivalent(tlu4) with pytest.raises(u.UnitsError): flu.to(tlu4, values) def test_unit_decomposition(self): lu = u.mag(u.Jy) assert lu.decompose() == u.mag(u.Jy.decompose()) assert lu.decompose().physical_unit.bases == [u.kg, u.s] assert lu.si == u.mag(u.Jy.si) assert lu.si.physical_unit.bases == [u.kg, u.s] assert lu.cgs == u.mag(u.Jy.cgs) assert lu.cgs.physical_unit.bases == [u.g, u.s] def test_unit_multiple_possible_equivalencies(self): lu = u.mag(u.Jy) assert lu.is_equivalent(pu_sample) def test_magnitude_conversion_fails_message(self): """Check that "dimensionless" magnitude units include a message in their exception text suggesting a possible cause of the problem. """ with pytest.raises(u.UnitConversionError) as excinfo: (10*u.ABmag - 2*u.ABmag).to(u.nJy) assert "Did you perhaps subtract magnitudes so the unit got lost?" in str(excinfo.value) class TestLogUnitArithmetic: def test_multiplication_division(self): """Check that multiplication/division with other units is only possible when the physical unit is dimensionless, and that this turns the unit into a normal one.""" lu1 = u.mag(u.Jy) with pytest.raises(u.UnitsError): lu1 * u.m with pytest.raises(u.UnitsError): u.m * lu1 with pytest.raises(u.UnitsError): lu1 / lu1 for unit in (u.dimensionless_unscaled, u.m, u.mag, u.dex): with pytest.raises(u.UnitsError): lu1 / unit lu2 = u.mag(u.dimensionless_unscaled) with pytest.raises(u.UnitsError): lu2 * lu1 with pytest.raises(u.UnitsError): lu2 / lu1 # But dimensionless_unscaled can be cancelled. assert lu2 / lu2 == u.dimensionless_unscaled # With dimensionless, normal units are OK, but we return a plain unit. tf = lu2 * u.m tr = u.m * lu2 for t in (tf, tr): assert not isinstance(t, type(lu2)) assert t == lu2.function_unit * u.m with u.set_enabled_equivalencies(u.logarithmic()): with pytest.raises(u.UnitsError): t.to(lu2.physical_unit) # Now we essentially have a LogUnit with a prefactor of 100, # so should be equivalent again. t = tf / u.cm with u.set_enabled_equivalencies(u.logarithmic()): assert t.is_equivalent(lu2.function_unit) assert_allclose(t.to(u.dimensionless_unscaled, np.arange(3.)/100.), lu2.to(lu2.physical_unit, np.arange(3.))) # If we effectively remove lu1, a normal unit should be returned. t2 = tf / lu2 assert not isinstance(t2, type(lu2)) assert t2 == u.m t3 = tf / lu2.function_unit assert not isinstance(t3, type(lu2)) assert t3 == u.m # For completeness, also ensure non-sensical operations fail with pytest.raises(TypeError): lu1 * object() with pytest.raises(TypeError): slice(None) * lu1 with pytest.raises(TypeError): lu1 / [] with pytest.raises(TypeError): 1 / lu1 @pytest.mark.parametrize('power', (2, 0.5, 1, 0)) def test_raise_to_power(self, power): """Check that raising LogUnits to some power is only possible when the physical unit is dimensionless, and that conversion is turned off when the resulting logarithmic unit (such as mag**2) is incompatible.""" lu1 = u.mag(u.Jy) if power == 0: assert lu1 ** power == u.dimensionless_unscaled elif power == 1: assert lu1 ** power == lu1 else: with pytest.raises(u.UnitsError): lu1 ** power # With dimensionless, though, it works, but returns a normal unit. lu2 = u.mag(u.dimensionless_unscaled) t = lu2**power if power == 0: assert t == u.dimensionless_unscaled elif power == 1: assert t == lu2 else: assert not isinstance(t, type(lu2)) assert t == lu2.function_unit**power # also check we roundtrip t2 = t**(1./power) assert t2 == lu2.function_unit with u.set_enabled_equivalencies(u.logarithmic()): assert_allclose(t2.to(u.dimensionless_unscaled, np.arange(3.)), lu2.to(lu2.physical_unit, np.arange(3.))) @pytest.mark.parametrize('other', pu_sample) def test_addition_subtraction_to_normal_units_fails(self, other): lu1 = u.mag(u.Jy) with pytest.raises(u.UnitsError): lu1 + other with pytest.raises(u.UnitsError): lu1 - other with pytest.raises(u.UnitsError): other - lu1 def test_addition_subtraction_to_non_units_fails(self): lu1 = u.mag(u.Jy) with pytest.raises(TypeError): lu1 + 1. with pytest.raises(TypeError): lu1 - [1., 2., 3.] @pytest.mark.parametrize( 'other', (u.mag, u.mag(), u.mag(u.Jy), u.mag(u.m), u.Unit(2*u.mag), u.MagUnit('', 2.*u.mag))) def test_addition_subtraction(self, other): """Check physical units are changed appropriately""" lu1 = u.mag(u.Jy) other_pu = getattr(other, 'physical_unit', u.dimensionless_unscaled) lu_sf = lu1 + other assert lu_sf.is_equivalent(lu1.physical_unit * other_pu) lu_sr = other + lu1 assert lu_sr.is_equivalent(lu1.physical_unit * other_pu) lu_df = lu1 - other assert lu_df.is_equivalent(lu1.physical_unit / other_pu) lu_dr = other - lu1 assert lu_dr.is_equivalent(other_pu / lu1.physical_unit) def test_complicated_addition_subtraction(self): """for fun, a more complicated example of addition and subtraction""" dm0 = u.Unit('DM', 1./(4.*np.pi*(10.*u.pc)**2)) lu_dm = u.mag(dm0) lu_absST = u.STmag - lu_dm assert lu_absST.is_equivalent(u.erg/u.s/u.AA) def test_neg_pos(self): lu1 = u.mag(u.Jy) neg_lu = -lu1 assert neg_lu != lu1 assert neg_lu.physical_unit == u.Jy**-1 assert -neg_lu == lu1 pos_lu = +lu1 assert pos_lu is not lu1 assert pos_lu == lu1 def test_pickle(): lu1 = u.dex(u.cm/u.s**2) s = pickle.dumps(lu1) lu2 = pickle.loads(s) assert lu1 == lu2 def test_hashable(): lu1 = u.dB(u.mW) lu2 = u.dB(u.m) lu3 = u.dB(u.mW) assert hash(lu1) != hash(lu2) assert hash(lu1) == hash(lu3) luset = {lu1, lu2, lu3} assert len(luset) == 2 class TestLogQuantityCreation: @pytest.mark.parametrize('lq, lu', zip(lq_subclasses + [u.LogQuantity], lu_subclasses + [u.LogUnit])) def test_logarithmic_quantities(self, lq, lu): """Check logarithmic quantities are all set up correctly""" assert lq._unit_class == lu assert type(lu()._quantity_class(1.)) is lq @pytest.mark.parametrize('lq_cls, physical_unit', itertools.product(lq_subclasses, pu_sample)) def test_subclass_creation(self, lq_cls, physical_unit): """Create LogQuantity subclass objects for some physical units, and basic check on transformations""" value = np.arange(1., 10.) log_q = lq_cls(value * physical_unit) assert log_q.unit.physical_unit == physical_unit assert log_q.unit.function_unit == log_q.unit._default_function_unit assert_allclose(log_q.physical.value, value) with pytest.raises(ValueError): lq_cls(value, physical_unit) @pytest.mark.parametrize( 'unit', (u.mag, u.mag(), u.mag(u.Jy), u.mag(u.m), u.Unit(2*u.mag), u.MagUnit('', 2.*u.mag), u.MagUnit(u.Jy, -1*u.mag), u.MagUnit(u.m, -2.*u.mag))) def test_different_units(self, unit): q = u.Magnitude(1.23, unit) assert q.unit.function_unit == getattr(unit, 'function_unit', unit) assert q.unit.physical_unit is getattr(unit, 'physical_unit', u.dimensionless_unscaled) @pytest.mark.parametrize('value, unit', ( (1.*u.mag(u.Jy), None), (1.*u.dex(u.Jy), None), (1.*u.mag(u.W/u.m**2/u.Hz), u.mag(u.Jy)), (1.*u.dex(u.W/u.m**2/u.Hz), u.mag(u.Jy)))) def test_function_values(self, value, unit): lq = u.Magnitude(value, unit) assert lq == value assert lq.unit.function_unit == u.mag assert lq.unit.physical_unit == getattr(unit, 'physical_unit', value.unit.physical_unit) @pytest.mark.parametrize( 'unit', (u.mag(), u.mag(u.Jy), u.mag(u.m), u.MagUnit('', 2.*u.mag), u.MagUnit(u.Jy, -1*u.mag), u.MagUnit(u.m, -2.*u.mag))) def test_indirect_creation(self, unit): q1 = 2.5 * unit assert isinstance(q1, u.Magnitude) assert q1.value == 2.5 assert q1.unit == unit pv = 100. * unit.physical_unit q2 = unit * pv assert q2.unit == unit assert q2.unit.physical_unit == pv.unit assert q2.to_value(unit.physical_unit) == 100. assert (q2._function_view / u.mag).to_value(1) == -5. q3 = unit / 0.4 assert q3 == q1 def test_from_view(self): # Cannot view a physical quantity as a function quantity, since the # values would change. q = [100., 1000.] * u.cm/u.s**2 with pytest.raises(TypeError): q.view(u.Dex) # But fine if we have the right magnitude. q = [2., 3.] * u.dex lq = q.view(u.Dex) assert isinstance(lq, u.Dex) assert lq.unit.physical_unit == u.dimensionless_unscaled assert np.all(q == lq) def test_using_quantity_class(self): """Check that we can use Quantity if we have subok=True""" # following issue #5851 lu = u.dex(u.AA) with pytest.raises(u.UnitTypeError): u.Quantity(1., lu) q = u.Quantity(1., lu, subok=True) assert type(q) is lu._quantity_class def test_conversion_to_and_from_physical_quantities(): """Ensures we can convert from regular quantities.""" mst = [10., 12., 14.] * u.STmag flux_lambda = mst.physical mst_roundtrip = flux_lambda.to(u.STmag) # check we return a logquantity; see #5178. assert isinstance(mst_roundtrip, u.Magnitude) assert mst_roundtrip.unit == mst.unit assert_allclose(mst_roundtrip.value, mst.value) wave = [4956.8, 4959.55, 4962.3] * u.AA flux_nu = mst.to(u.Jy, equivalencies=u.spectral_density(wave)) mst_roundtrip2 = flux_nu.to(u.STmag, u.spectral_density(wave)) assert isinstance(mst_roundtrip2, u.Magnitude) assert mst_roundtrip2.unit == mst.unit assert_allclose(mst_roundtrip2.value, mst.value) def test_quantity_decomposition(): lq = 10.*u.mag(u.Jy) assert lq.decompose() == lq assert lq.decompose().unit.physical_unit.bases == [u.kg, u.s] assert lq.si == lq assert lq.si.unit.physical_unit.bases == [u.kg, u.s] assert lq.cgs == lq assert lq.cgs.unit.physical_unit.bases == [u.g, u.s] class TestLogQuantityViews: def setup(self): self.lq = u.Magnitude(np.arange(1., 10.) * u.Jy) self.lq2 = u.Magnitude(np.arange(1., 5.)) def test_value_view(self): lq_value = self.lq.value assert type(lq_value) is np.ndarray lq_value[2] = -1. assert np.all(self.lq.value == lq_value) def test_function_view(self): lq_fv = self.lq._function_view assert type(lq_fv) is u.Quantity assert lq_fv.unit is self.lq.unit.function_unit lq_fv[3] = -2. * lq_fv.unit assert np.all(self.lq.value == lq_fv.value) def test_quantity_view(self): # Cannot view as Quantity, since the unit cannot be represented. with pytest.raises(TypeError): self.lq.view(u.Quantity) # But a dimensionless one is fine. q2 = self.lq2.view(u.Quantity) assert q2.unit is u.mag assert np.all(q2.value == self.lq2.value) lq3 = q2.view(u.Magnitude) assert type(lq3.unit) is u.MagUnit assert lq3.unit.physical_unit == u.dimensionless_unscaled assert np.all(lq3 == self.lq2) class TestLogQuantitySlicing: def test_item_get_and_set(self): lq1 = u.Magnitude(np.arange(1., 11.)*u.Jy) assert lq1[9] == u.Magnitude(10.*u.Jy) lq1[2] = 100.*u.Jy assert lq1[2] == u.Magnitude(100.*u.Jy) with pytest.raises(u.UnitsError): lq1[2] = 100.*u.m with pytest.raises(u.UnitsError): lq1[2] = 100.*u.mag with pytest.raises(u.UnitsError): lq1[2] = u.Magnitude(100.*u.m) assert lq1[2] == u.Magnitude(100.*u.Jy) def test_slice_get_and_set(self): lq1 = u.Magnitude(np.arange(1., 10.)*u.Jy) lq1[2:4] = 100.*u.Jy assert np.all(lq1[2:4] == u.Magnitude(100.*u.Jy)) with pytest.raises(u.UnitsError): lq1[2:4] = 100.*u.m with pytest.raises(u.UnitsError): lq1[2:4] = 100.*u.mag with pytest.raises(u.UnitsError): lq1[2:4] = u.Magnitude(100.*u.m) assert np.all(lq1[2] == u.Magnitude(100.*u.Jy)) class TestLogQuantityArithmetic: def test_multiplication_division(self): """Check that multiplication/division with other quantities is only possible when the physical unit is dimensionless, and that this turns the result into a normal quantity.""" lq = u.Magnitude(np.arange(1., 11.)*u.Jy) with pytest.raises(u.UnitsError): lq * (1.*u.m) with pytest.raises(u.UnitsError): (1.*u.m) * lq with pytest.raises(u.UnitsError): lq / lq for unit in (u.m, u.mag, u.dex): with pytest.raises(u.UnitsError): lq / unit lq2 = u.Magnitude(np.arange(1, 11.)) with pytest.raises(u.UnitsError): lq2 * lq with pytest.raises(u.UnitsError): lq2 / lq with pytest.raises(u.UnitsError): lq / lq2 # but dimensionless_unscaled can be cancelled r = lq2 / u.Magnitude(2.) assert r.unit == u.dimensionless_unscaled assert np.all(r.value == lq2.value/2.) # with dimensionless, normal units OK, but return normal quantities tf = lq2 * u.m tr = u.m * lq2 for t in (tf, tr): assert not isinstance(t, type(lq2)) assert t.unit == lq2.unit.function_unit * u.m with u.set_enabled_equivalencies(u.logarithmic()): with pytest.raises(u.UnitsError): t.to(lq2.unit.physical_unit) t = tf / (50.*u.cm) # now we essentially have the same quantity but with a prefactor of 2 assert t.unit.is_equivalent(lq2.unit.function_unit) assert_allclose(t.to(lq2.unit.function_unit), lq2._function_view*2) @pytest.mark.parametrize('power', (2, 0.5, 1, 0)) def test_raise_to_power(self, power): """Check that raising LogQuantities to some power is only possible when the physical unit is dimensionless, and that conversion is turned off when the resulting logarithmic unit (say, mag**2) is incompatible.""" lq = u.Magnitude(np.arange(1., 4.)*u.Jy) if power == 0: assert np.all(lq ** power == 1.) elif power == 1: assert np.all(lq ** power == lq) else: with pytest.raises(u.UnitsError): lq ** power # with dimensionless, it works, but falls back to normal quantity # (except for power=1) lq2 = u.Magnitude(np.arange(10.)) t = lq2**power if power == 0: assert t.unit is u.dimensionless_unscaled assert np.all(t.value == 1.) elif power == 1: assert np.all(t == lq2) else: assert not isinstance(t, type(lq2)) assert t.unit == lq2.unit.function_unit ** power with u.set_enabled_equivalencies(u.logarithmic()): with pytest.raises(u.UnitsError): t.to(u.dimensionless_unscaled) def test_error_on_lq_as_power(self): lq = u.Magnitude(np.arange(1., 4.)*u.Jy) with pytest.raises(TypeError): lq ** lq @pytest.mark.parametrize('other', pu_sample) def test_addition_subtraction_to_normal_units_fails(self, other): lq = u.Magnitude(np.arange(1., 10.)*u.Jy) q = 1.23 * other with pytest.raises(u.UnitsError): lq + q with pytest.raises(u.UnitsError): lq - q with pytest.raises(u.UnitsError): q - lq @pytest.mark.parametrize( 'other', (1.23 * u.mag, 2.34 * u.mag(), u.Magnitude(3.45 * u.Jy), u.Magnitude(4.56 * u.m), 5.67 * u.Unit(2*u.mag), u.Magnitude(6.78, 2.*u.mag))) def test_addition_subtraction(self, other): """Check that addition/subtraction with quantities with magnitude or MagUnit units works, and that it changes the physical units appropriately.""" lq = u.Magnitude(np.arange(1., 10.)*u.Jy) other_physical = other.to(getattr(other.unit, 'physical_unit', u.dimensionless_unscaled), equivalencies=u.logarithmic()) lq_sf = lq + other assert_allclose(lq_sf.physical, lq.physical * other_physical) lq_sr = other + lq assert_allclose(lq_sr.physical, lq.physical * other_physical) lq_df = lq - other assert_allclose(lq_df.physical, lq.physical / other_physical) lq_dr = other - lq assert_allclose(lq_dr.physical, other_physical / lq.physical) @pytest.mark.parametrize('other', pu_sample) def test_inplace_addition_subtraction_unit_checks(self, other): lu1 = u.mag(u.Jy) lq1 = u.Magnitude(np.arange(1., 10.), lu1) with pytest.raises(u.UnitsError): lq1 += other assert np.all(lq1.value == np.arange(1., 10.)) assert lq1.unit == lu1 with pytest.raises(u.UnitsError): lq1 -= other assert np.all(lq1.value == np.arange(1., 10.)) assert lq1.unit == lu1 @pytest.mark.parametrize( 'other', (1.23 * u.mag, 2.34 * u.mag(), u.Magnitude(3.45 * u.Jy), u.Magnitude(4.56 * u.m), 5.67 * u.Unit(2*u.mag), u.Magnitude(6.78, 2.*u.mag))) def test_inplace_addition_subtraction(self, other): """Check that inplace addition/subtraction with quantities with magnitude or MagUnit units works, and that it changes the physical units appropriately.""" lq = u.Magnitude(np.arange(1., 10.)*u.Jy) other_physical = other.to(getattr(other.unit, 'physical_unit', u.dimensionless_unscaled), equivalencies=u.logarithmic()) lq_sf = lq.copy() lq_sf += other assert_allclose(lq_sf.physical, lq.physical * other_physical) lq_df = lq.copy() lq_df -= other assert_allclose(lq_df.physical, lq.physical / other_physical) def test_complicated_addition_subtraction(self): """For fun, a more complicated example of addition and subtraction.""" dm0 = u.Unit('DM', 1./(4.*np.pi*(10.*u.pc)**2)) DMmag = u.mag(dm0) m_st = 10. * u.STmag dm = 5. * DMmag M_st = m_st - dm assert M_st.unit.is_equivalent(u.erg/u.s/u.AA) assert np.abs(M_st.physical / (m_st.physical*4.*np.pi*(100.*u.pc)**2) - 1.) < 1.e-15 class TestLogQuantityComparisons: def test_comparison_to_non_quantities_fails(self): lq = u.Magnitude(np.arange(1., 10.)*u.Jy) with pytest.raises(TypeError): lq > 'a' assert not (lq == 'a') assert lq != 'a' def test_comparison(self): lq1 = u.Magnitude(np.arange(1., 4.)*u.Jy) lq2 = u.Magnitude(2.*u.Jy) assert np.all((lq1 > lq2) == np.array([True, False, False])) assert np.all((lq1 == lq2) == np.array([False, True, False])) lq3 = u.Dex(2.*u.Jy) assert np.all((lq1 > lq3) == np.array([True, False, False])) assert np.all((lq1 == lq3) == np.array([False, True, False])) lq4 = u.Magnitude(2.*u.m) assert not (lq1 == lq4) assert lq1 != lq4 with pytest.raises(u.UnitsError): lq1 < lq4 q5 = 1.5 * u.Jy assert np.all((lq1 > q5) == np.array([True, False, False])) assert np.all((q5 < lq1) == np.array([True, False, False])) with pytest.raises(u.UnitsError): lq1 >= 2.*u.m with pytest.raises(u.UnitsError): lq1 <= lq1.value * u.mag # For physically dimensionless, we can compare with the function unit. lq6 = u.Magnitude(np.arange(1., 4.)) fv6 = lq6.value * u.mag assert np.all(lq6 == fv6) # but not some arbitrary unit, of course. with pytest.raises(u.UnitsError): lq6 < 2.*u.m class TestLogQuantityMethods: def setup(self): self.mJy = np.arange(1., 5.).reshape(2, 2) * u.mag(u.Jy) self.m1 = np.arange(1., 5.5, 0.5).reshape(3, 3) * u.mag() self.mags = (self.mJy, self.m1) @pytest.mark.parametrize('method', ('mean', 'min', 'max', 'round', 'trace', 'std', 'var', 'ptp', 'diff', 'ediff1d')) def test_always_ok(self, method): for mag in self.mags: res = getattr(mag, method)() assert np.all(res.value == getattr(mag._function_view, method)().value) if method in ('std', 'ptp', 'diff', 'ediff1d'): assert res.unit == u.mag() elif method == 'var': assert res.unit == u.mag**2 else: assert res.unit == mag.unit def test_clip(self): for mag in self.mags: assert np.all(mag.clip(2. * mag.unit, 4. * mag.unit).value == mag.value.clip(2., 4.)) @pytest.mark.parametrize('method', ('sum', 'cumsum', 'nansum')) def test_only_ok_if_dimensionless(self, method): res = getattr(self.m1, method)() assert np.all(res.value == getattr(self.m1._function_view, method)().value) assert res.unit == self.m1.unit with pytest.raises(TypeError): getattr(self.mJy, method)() def test_dot(self): assert np.all(self.m1.dot(self.m1).value == self.m1.value.dot(self.m1.value)) @pytest.mark.parametrize('method', ('prod', 'cumprod')) def test_never_ok(self, method): with pytest.raises(TypeError): getattr(self.mJy, method)() with pytest.raises(TypeError): getattr(self.m1, method)() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/tests/test_photometric.py0000644000175100001710000000213300000000000022217 0ustar00vstsdocker# coding: utf-8 # Licensed under a 3-clause BSD style license - see LICENSE.rst """ Tests for the photometric module. Note that this is shorter than might be expected because a lot of the relevant tests that deal with magnidues are in `test_logarithmic.py` """ from astropy.tests.helper import assert_quantity_allclose from astropy.units import Magnitude, mgy, nmgy, ABflux, STflux, zero_point_flux, Jy from astropy.units import erg, cm, s, AA def test_maggies(): assert_quantity_allclose(1e-9*mgy, 1*nmgy) assert_quantity_allclose(Magnitude((1*nmgy).to(mgy)).value, 22.5) def test_maggies_zpts(): assert_quantity_allclose((1*nmgy).to(ABflux, zero_point_flux(1*ABflux)), 3631e-9*Jy, rtol=1e-3) ST_base_unit = erg * cm**-2 / s / AA stmgy = (10*mgy).to(STflux, zero_point_flux(1*ST_base_unit)) assert_quantity_allclose(stmgy, 10*ST_base_unit) mgyst = (2*ST_base_unit).to(mgy, zero_point_flux(0.5*ST_base_unit)) assert_quantity_allclose(mgyst, 4*mgy) nmgyst = (5.e-10*ST_base_unit).to(mgy, zero_point_flux(0.5*ST_base_unit)) assert_quantity_allclose(nmgyst, 1*nmgy) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/tests/test_physical.py0000644000175100001710000004670500000000000021513 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ Unit tests for the handling of physical types in `astropy.units`. """ import pickle import pytest from astropy import units as u from astropy.units import physical from astropy.constants import hbar from astropy.utils.exceptions import AstropyDeprecationWarning unit_physical_type_pairs = [ (u.m, "length"), (u.cm ** 3, "volume"), (u.km / u.h, "speed"), (u.barn * u.Mpc, "volume"), (u.m * u.s ** 8, "unknown"), (u.m / u.m, "dimensionless"), (hbar.unit, "angular momentum"), (u.erg / (u.cm ** 2 * u.s * u.AA), "spectral flux density wav"), (u.photon / (u.cm ** 2 * u.s * u.AA), "photon flux density wav"), (u.photon / (u.cm ** 2 * u.s * u.Hz), "photon flux density"), (u.byte, "data quantity"), (u.bit, "data quantity"), (u.imperial.mi / u.week, "speed"), (u.erg / u.s, "power"), (u.C / u.s, "electrical current"), (u.C / u.s / u.cm ** 2, "electrical current density"), (u.T * u.m ** 2, "magnetic flux"), (u.N * u.m, "energy"), (u.rad / u.ms, "angular speed"), (u.Unit(1), "dimensionless"), (u.m ** 2, "area"), (u.s, "time"), (u.rad, "angle"), (u.sr, "solid angle"), (u.m / u.s ** 2, "acceleration"), (u.Hz, "frequency"), (u.g, "mass"), (u.mol, "amount of substance"), (u.K, "temperature"), (u.deg_C, "temperature"), (u.imperial.deg_F, "temperature"), (u.imperial.deg_R, "temperature"), (u.imperial.deg_R / u.m, "temperature_gradient"), (u.N, "force"), (u.J, "energy"), (u.Pa, "pressure"), (u.W, "power"), (u.kg / u.m ** 3, "mass density"), (u.m ** 3 / u.kg, "specific volume"), (u.mol / u.m ** 3, "molar concentration"), (u.kg * u.m / u.s, "momentum/impulse"), (u.kg * u.m ** 2 / u.s, "angular momentum"), (u.rad / u.s, "angular speed"), (u.rad / u.s ** 2, "angular acceleration"), (u.g / (u.m * u.s), "dynamic viscosity"), (u.m ** 2 / u.s, "kinematic viscosity"), (u.m ** -1, "wavenumber"), (u.A, "electrical current"), (u.C, "electrical charge"), (u.V, "electrical potential"), (u.Ohm, "electrical resistance"), (u.S, "electrical conductance"), (u.F, "electrical capacitance"), (u.C * u.m, "electrical dipole moment"), (u.A / u.m ** 2, "electrical current density"), (u.V / u.m, "electrical field strength"), (u.C / u.m ** 2, "electrical flux density"), (u.C / u.m ** 3, "electrical charge density"), (u.F / u.m, "permittivity"), (u.Wb, "magnetic flux"), (u.T, "magnetic flux density"), (u.A / u.m, "magnetic field strength"), (u.H / u.m, "electromagnetic field strength"), (u.H, "inductance"), (u.cd, "luminous intensity"), (u.lm, "luminous flux"), (u.lx, "luminous emittance/illuminance"), (u.W / u.sr, "radiant intensity"), (u.cd / u.m ** 2, "luminance"), (u.astrophys.Jy, "spectral flux density"), (u.astrophys.R, "photon flux"), (u.misc.bit, "data quantity"), (u.misc.bit / u.s, "bandwidth"), (u.cgs.Franklin, "electrical charge (ESU)"), (u.cgs.statampere, "electrical current (ESU)"), (u.cgs.Biot, "electrical current (EMU)"), (u.cgs.abcoulomb, "electrical charge (EMU)"), (u.imperial.btu / (u.s * u.m * u.imperial.deg_F), "thermal conductivity"), (u.imperial.cal / u.deg_C, "heat capacity"), (u.imperial.cal / u.deg_C / u.g, "specific heat capacity"), (u.J * u.m ** -2 * u.s ** -1, "energy flux"), (u.W / u.m ** 2, "energy flux"), (u.m ** 3 / u.mol, "molar volume"), (u.m / u.S, "electrical resistivity"), (u.S / u.m, "electrical conductivity"), (u.A * u.m ** 2, "magnetic moment"), (u.J / u.T, "magnetic moment"), (u.yr ** -1 * u.Mpc ** -3, "volumetric rate"), (u.m / u.s ** 3, "jerk"), (u.m / u.s ** 4, "snap"), (u.m / u.s ** 5, "crackle"), (u.m / u.s ** 6, "pop"), (u.deg_C / u.m, "temperature gradient"), (u.imperial.deg_F / u.m, "temperature gradient"), (u.imperial.deg_R / u.imperial.ft, "temperature gradient"), (u.imperial.Calorie / u.g, "specific energy"), (u.mol / u.L / u.s, "reaction rate"), (u.imperial.lbf * u.imperial.ft * u.s ** 2, "moment of inertia"), (u.mol / u.s, "catalytic activity"), (u.imperial.kcal / u.deg_C / u.mol, "molar heat capacity"), (u.mol / u.kg, "molality"), (u.imperial.inch * u.hr, "absement"), (u.imperial.ft ** 3 / u.s, "volumetric flow rate"), (u.Hz / u.s, "frequency drift"), (u.Pa ** -1, "compressibility"), (u.dimensionless_unscaled, "dimensionless"), ] @pytest.mark.parametrize("unit, physical_type", unit_physical_type_pairs) def test_physical_type_names(unit, physical_type): """ Test that the `physical_type` attribute of `u.Unit` objects provides the expected physical type for various units. Many of these tests are used to test backwards compatibility. """ assert unit.physical_type == physical_type, ( f"{unit!r}.physical_type was expected to return " f"{physical_type!r}, but instead returned {unit.physical_type!r}." ) length = u.m.physical_type time = u.s.physical_type speed = (u.m / u.s).physical_type area = (u.m ** 2).physical_type wavenumber = (u.m ** -1).physical_type dimensionless = u.dimensionless_unscaled.physical_type pressure = u.Pa.physical_type momentum = (u.kg * u.m / u.s).physical_type @pytest.mark.parametrize( "physical_type_representation, physical_type_name", [ (1.0, "dimensionless"), (u.m, "length"), ("work", "work"), (5 * u.m, "length"), (length, length), (u.Pa, "energy_density"), # attribute-accessible name ("energy_density", "energy_density") # attribute-accessible name ], ) def test_getting_physical_type(physical_type_representation, physical_type_name): """Test different ways of getting a physical type.""" physical_type = physical.get_physical_type(physical_type_representation) assert isinstance(physical_type, physical.PhysicalType) assert physical_type == physical_type_name @pytest.mark.parametrize( "argument, exception", [ ("unknown", ValueError), ("not a name of a physical type", ValueError), ({"this set cannot be made into a Quantity"}, TypeError), ] ) def test_getting_physical_type_exceptions(argument, exception): """ Test that `get_physical_type` raises appropriate exceptions when provided with invalid arguments. """ with pytest.raises(exception): physical.get_physical_type(argument) def test_physical_type_cannot_become_quantity(): """ Test that `PhysicalType` instances cannot be cast into `Quantity` objects. A failure in this test could be related to failures in subsequent tests. """ with pytest.raises(TypeError): u.Quantity(u.m.physical_type, u.m) # left term, right term, operator, expected value operation_parameters = [ (length, length, "__eq__", True), (length, area, "__eq__", False), (length, "length", "__eq__", True), ("length", length, "__eq__", NotImplemented), (dimensionless, dimensionless, "__eq__", True), (momentum, "momentum/impulse", "__eq__", True), # test delimiters in names (pressure, "energy_density", "__eq__", True), # test underscores in names ((u.m ** 8).physical_type, "unknown", "__eq__", True), ((u.m ** 8).physical_type, (u.m ** 9).physical_type, "__eq__", False), (length, length, "__ne__", False), (speed, time, "__ne__", True), (pressure, dimensionless, "__ne__", True), (length, u.m, "__eq__", NotImplemented), (length, length, "__mul__", area), (speed, time, "__mul__", length), (speed, time, "__rmul__", length), (length, time, "__truediv__", speed), (area, length, "__truediv__", length), (length, area, "__rtruediv__", length), (dimensionless, dimensionless, "__mul__", dimensionless), (dimensionless, dimensionless, "__truediv__", dimensionless), (length, 2, "__pow__", area), (area, 0.5, "__pow__", length), (dimensionless, 4, "__pow__", dimensionless), (u.m, length, "__mul__", NotImplemented), (3.2, length, "__mul__", NotImplemented), (u.m, time, "__truediv__", NotImplemented), (3.2, length, "__truediv__", NotImplemented), (length, u.m, "__mul__", area), (length, u.m, "__rmul__", area), (speed, u.s, "__mul__", length), (length, 1, "__mul__", length), (length, 1, "__rmul__", length), (length, u.s, "__truediv__", speed), (area, 1, "__truediv__", area), (time, u.m, "__rtruediv__", speed), (length, 1.0, "__rtruediv__", wavenumber), (length, 2, "__pow__", area), (length, 32, "__mul__", NotImplemented), (length, 0, "__rmul__", NotImplemented), (length, 3.2, "__truediv__", NotImplemented), (length, -1, "__rtruediv__", NotImplemented), (length, "length", "__mul__", area), (length, "length", "__rmul__", area), (area, "length", "__truediv__", length), (length, "area", "__rtruediv__", length), ] @pytest.mark.parametrize("left, right, operator, expected", operation_parameters) def test_physical_type_operations(left, right, operator, expected): """ Test that `PhysicalType` dunder methods that require another argument behave as intended. """ assert getattr(left, operator)(right) == expected unit_with_physical_type_set = [ (u.m, {"length"}), (u.kg * u.m / u.s, {"impulse", "momentum"}), (u.Pa, {"energy density", "pressure", "stress"}), ] @pytest.mark.parametrize("unit, expected_set", unit_with_physical_type_set) def test_physical_type_as_set(unit, expected_set): """Test making a `physical.PhysicalType` instance into a `set`.""" resulting_set = set(unit.physical_type) assert resulting_set == expected_set def test_physical_type_iteration(): """Test iterating through different physical type names.""" physical_type_names = [physical_type_name for physical_type_name in pressure] assert physical_type_names == ["energy density", "pressure", "stress"] def test_physical_type_in(): """ Test that `in` works as expected for `PhysicalType` objects with one or multiple names. """ assert "length" in length assert "pressure" in pressure equivalent_unit_pairs = [ (u.m, u.m), (u.m, u.cm), (u.N, u.kg * u.m * u.s ** -2), (u.barn * u.Mpc, u.cm ** 3), (u.K, u.deg_C), (u.K, u.imperial.deg_R), (u.K, u.imperial.deg_F), (u.deg_C, u.imperial.deg_F), (u.m ** 18, u.pc ** 18), ] @pytest.mark.parametrize("unit1, unit2", equivalent_unit_pairs) def test_physical_type_instance_equality(unit1, unit2): """ Test that `physical.PhysicalType` instances for units of the same dimensionality are equal. """ assert (unit1.physical_type == unit2.physical_type) is True assert (unit1.physical_type != unit2.physical_type) is False @pytest.mark.parametrize("unit1, unit2", equivalent_unit_pairs) def test_get_physical_type_equivalent_pairs(unit1, unit2): """ Test that `get_physical_type` retrieves the same `PhysicalType` instances for equivalent physical types, except for unknown types which are not cataloged. """ physical_type1 = physical.get_physical_type(unit1) physical_type2 = physical.get_physical_type(unit2) assert physical_type1 == physical_type2 if physical_type1 != "unknown": assert physical_type1 is physical_type2 nonequivalent_unit_pairs = [ (u.m, u.s), (u.m ** 18, u.m ** 19), (u.N, u.J), (u.barn, u.imperial.deg_F), ] @pytest.mark.parametrize("unit1, unit2", nonequivalent_unit_pairs) def test_physical_type_instance_inequality(unit1, unit2): """ Test that `physical.PhysicalType` instances for units with different dimensionality are considered unequal. """ physical_type1 = physical.PhysicalType(unit1, "ptype1") physical_type2 = physical.PhysicalType(unit2, "ptype2") assert (physical_type1 != physical_type2) is True assert (physical_type1 == physical_type2) is False physical_type_with_expected_str = [ (length, "length"), (speed, "speed/velocity"), (pressure, "energy density/pressure/stress"), (u.deg_C.physical_type, "temperature"), ((u.J / u.K / u.kg).physical_type, "specific entropy/specific heat capacity"), ] physical_type_with_expected_repr = [ (length, "PhysicalType('length')"), (speed, "PhysicalType({'speed', 'velocity'})"), (pressure, "PhysicalType({'energy density', 'pressure', 'stress'})"), (u.deg_C.physical_type, "PhysicalType('temperature')"), ((u.J / u.K / u.kg).physical_type, "PhysicalType({'specific entropy', 'specific heat capacity'})"), ] @pytest.mark.parametrize("physical_type, expected_str", physical_type_with_expected_str) def test_physical_type_str(physical_type, expected_str): """Test using `str` on a `PhysicalType` instance.""" assert str(physical_type) == expected_str @pytest.mark.parametrize( "physical_type, expected_repr", physical_type_with_expected_repr ) def physical_type_repr(physical_type, expected_repr): """Test using `repr` on a `PhysicalType` instance.""" assert repr(physical_type) == expected_repr def test_physical_type_hash(): """Test that a `PhysicalType` instance can be used as a dict key.""" dictionary = {length: 42} assert dictionary[length] == 42 @pytest.mark.parametrize("multiplicand", [list(), 42, 0, -1]) def test_physical_type_multiplication(multiplicand): """ Test that multiplication of a physical type returns `NotImplemented` when attempted for an invalid type. """ with pytest.raises(TypeError): length * multiplicand def test_unrecognized_unit_physical_type(): """ Test basic functionality for the physical type of an unrecognized unit. """ unrecognized_unit = u.Unit("parrot", parse_strict="silent") physical_type = unrecognized_unit.physical_type assert isinstance(physical_type, physical.PhysicalType) assert physical_type == "unknown" invalid_inputs = [(42,), ("valid input", 42)] @pytest.mark.parametrize("invalid_input", invalid_inputs) def test_invalid_physical_types(invalid_input): """ Test that `PhysicalType` cannot be instantiated when one of the supplied names is not a string, while making sure that the physical type for the unit remains unknown. """ obscure_unit = u.s ** 87 with pytest.raises(ValueError): physical.PhysicalType(obscure_unit, invalid_input) assert obscure_unit.physical_type == "unknown" class TestDefPhysType: weird_unit = u.m ** 99 strange_unit = u.s ** 42 def test_attempt_to_define_unknown_physical_type(self): """Test that a unit cannot be defined as unknown.""" with pytest.raises(ValueError): physical.def_physical_type(self.weird_unit, "unknown") assert "unknown" not in physical._unit_physical_mapping def test_multiple_same_physical_type_names(self): """ Test that `def_physical_type` raises an exception when it tries to set the physical type of a new unit as the name of an existing physical type. """ with pytest.raises(ValueError): physical.def_physical_type(self.weird_unit, {"time", "something"}) assert self.weird_unit.physical_type == "unknown" def test_expanding_names_for_physical_type(self): """ Test that calling `def_physical_type` on an existing physical type adds a new physical type name. """ weird_name = "weird name" strange_name = "strange name" try: physical.def_physical_type(self.weird_unit, weird_name) assert ( self.weird_unit.physical_type == weird_name ), f"unable to set physical type for {self.weird_unit}" except Exception: raise finally: # cleanup added name physical._attrname_physical_mapping.pop(weird_name.replace(' ', '_'), None) physical._name_physical_mapping.pop(weird_name, None) # add both strange_name and weird_name try: physical.def_physical_type(self.weird_unit, strange_name) assert set((self.weird_unit).physical_type) == { weird_name, strange_name, }, f"did not correctly append a new physical type name." except Exception: raise finally: # cleanup added names physical._attrname_physical_mapping.pop(strange_name.replace(' ', '_'), None) physical._name_physical_mapping.pop(strange_name, None) physical._attrname_physical_mapping.pop(weird_name.replace(' ', '_'), None) physical._name_physical_mapping.pop(weird_name, None) def test_redundant_physical_type(self): """ Test that a physical type name already in use cannot be assigned for another unit (excluding `"unknown"`). """ with pytest.raises(ValueError): physical.def_physical_type(self.weird_unit, "length") @staticmethod def _undef_physical_type(unit): """Reset the physical type of unit to "unknown".""" for name in list(unit.physical_type): del physical._unit_physical_mapping[name] del physical._physical_unit_mapping[unit._get_physical_type_id()] assert unit.physical_type == "unknown" def teardown_method(self): """ Remove the definitions of the physical types that were added using `def_physical_unit` for testing purposes. """ for unit in [self.weird_unit, self.strange_unit]: physical_type = physical.get_physical_type(unit) if physical_type != "unknown": self._undef_physical_type(unit) assert unit.physical_type == "unknown", ( f"the physical type for {unit}, which was added for" f"testing, was not deleted." ) @pytest.mark.parametrize("method, expected", [ ("title", 'Length'), ("isalpha", True), ("isnumeric", False), ("upper", 'LENGTH') ]) def test_that_str_methods_work_with_physical_types(method, expected): """ Test that str methods work for `PhysicalType` instances while issuing a deprecation warning. """ with pytest.warns(AstropyDeprecationWarning, match="PhysicalType instances"): result_of_method_call = getattr(length, method)() assert result_of_method_call == expected def test_missing_physical_type_attribute(): """ Test that a missing attribute raises an `AttributeError`. This test should be removed when the deprecated option of calling string methods on PhysicalType instances is removed from `PhysicalType.__getattr__`. """ with pytest.raises(AttributeError): length.not_the_name_of_a_str_or_physical_type_attribute @pytest.mark.parametrize('ptype_name', ['length', 'speed', 'entropy']) def test_pickling(ptype_name): # Regression test for #11685 ptype = u.get_physical_type(ptype_name) pkl = pickle.dumps(ptype) other = pickle.loads(pkl) assert other == ptype def test_physical_types_module_access(): # all physical type names in dir assert set(dir(physical)).issuperset(physical._attrname_physical_mapping.keys()) assert set(dir(physical)).issuperset(physical.__all__) # all physical type can be accessed by name for pname in physical._attrname_physical_mapping.keys(): ptype = physical._attrname_physical_mapping[pname] assert hasattr(physical, pname) # make sure works in lazy load assert getattr(physical, pname) is ptype # a failed access with pytest.raises(AttributeError, match="has no attribute"): physical.not_a_valid_physical_type_name ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/tests/test_quantity.py0000644000175100001710000015351700000000000021555 0ustar00vstsdocker# coding: utf-8 # Licensed under a 3-clause BSD style license - see LICENSE.rst """Test the Quantity class and related.""" import copy import pickle import decimal import numbers from fractions import Fraction import pytest import numpy as np from numpy.testing import (assert_allclose, assert_array_equal, assert_array_almost_equal) from astropy.utils import isiterable, minversion from astropy.utils.exceptions import AstropyDeprecationWarning, AstropyWarning from astropy import units as u from astropy.units.quantity import _UNIT_NOT_INITIALISED """ The Quantity class will represent a number + unit + uncertainty """ class TestQuantityCreation: def test_1(self): # create objects through operations with Unit objects: quantity = 11.42 * u.meter # returns a Quantity object assert isinstance(quantity, u.Quantity) quantity = u.meter * 11.42 # returns a Quantity object assert isinstance(quantity, u.Quantity) quantity = 11.42 / u.meter assert isinstance(quantity, u.Quantity) quantity = u.meter / 11.42 assert isinstance(quantity, u.Quantity) quantity = 11.42 * u.meter / u.second assert isinstance(quantity, u.Quantity) with pytest.raises(TypeError): quantity = 182.234 + u.meter with pytest.raises(TypeError): quantity = 182.234 - u.meter with pytest.raises(TypeError): quantity = 182.234 % u.meter def test_2(self): # create objects using the Quantity constructor: _ = u.Quantity(11.412, unit=u.meter) _ = u.Quantity(21.52, "cm") q3 = u.Quantity(11.412) # By default quantities that don't specify a unit are unscaled # dimensionless assert q3.unit == u.Unit(1) with pytest.raises(TypeError): u.Quantity(object(), unit=u.m) def test_3(self): # with pytest.raises(u.UnitsError): with pytest.raises(ValueError): # Until @mdboom fixes the errors in units u.Quantity(11.412, unit="testingggg") def test_nan_inf(self): # Not-a-number q = u.Quantity('nan', unit='cm') assert np.isnan(q.value) q = u.Quantity('NaN', unit='cm') assert np.isnan(q.value) q = u.Quantity('-nan', unit='cm') # float() allows this assert np.isnan(q.value) q = u.Quantity('nan cm') assert np.isnan(q.value) assert q.unit == u.cm # Infinity q = u.Quantity('inf', unit='cm') assert np.isinf(q.value) q = u.Quantity('-inf', unit='cm') assert np.isinf(q.value) q = u.Quantity('inf cm') assert np.isinf(q.value) assert q.unit == u.cm q = u.Quantity('Infinity', unit='cm') # float() allows this assert np.isinf(q.value) # make sure these strings don't parse... with pytest.raises(TypeError): q = u.Quantity('', unit='cm') with pytest.raises(TypeError): q = u.Quantity('spam', unit='cm') def test_unit_property(self): # test getting and setting 'unit' attribute q1 = u.Quantity(11.4, unit=u.meter) with pytest.raises(AttributeError): q1.unit = u.cm def test_preserve_dtype(self): """Test that if an explicit dtype is given, it is used, while if not, numbers are converted to float (including decimal.Decimal, which numpy converts to an object; closes #1419) """ # If dtype is specified, use it, but if not, convert int, bool to float q1 = u.Quantity(12, unit=u.m / u.s, dtype=int) assert q1.dtype == int q2 = u.Quantity(q1) assert q2.dtype == float assert q2.value == float(q1.value) assert q2.unit == q1.unit # but we should preserve any float32 or even float16 a3_32 = np.array([1., 2.], dtype=np.float32) q3_32 = u.Quantity(a3_32, u.yr) assert q3_32.dtype == a3_32.dtype a3_16 = np.array([1., 2.], dtype=np.float16) q3_16 = u.Quantity(a3_16, u.yr) assert q3_16.dtype == a3_16.dtype # items stored as objects by numpy should be converted to float # by default q4 = u.Quantity(decimal.Decimal('10.25'), u.m) assert q4.dtype == float q5 = u.Quantity(decimal.Decimal('10.25'), u.m, dtype=object) assert q5.dtype == object def test_copy(self): # By default, a new quantity is constructed, but not if copy=False a = np.arange(10.) q0 = u.Quantity(a, unit=u.m / u.s) assert q0.base is not a q1 = u.Quantity(a, unit=u.m / u.s, copy=False) assert q1.base is a q2 = u.Quantity(q0) assert q2 is not q0 assert q2.base is not q0.base q2 = u.Quantity(q0, copy=False) assert q2 is q0 assert q2.base is q0.base q3 = u.Quantity(q0, q0.unit, copy=False) assert q3 is q0 assert q3.base is q0.base q4 = u.Quantity(q0, u.cm / u.s, copy=False) assert q4 is not q0 assert q4.base is not q0.base def test_subok(self): """Test subok can be used to keep class, or to insist on Quantity""" class MyQuantitySubclass(u.Quantity): pass myq = MyQuantitySubclass(np.arange(10.), u.m) # try both with and without changing the unit assert type(u.Quantity(myq)) is u.Quantity assert type(u.Quantity(myq, subok=True)) is MyQuantitySubclass assert type(u.Quantity(myq, u.km)) is u.Quantity assert type(u.Quantity(myq, u.km, subok=True)) is MyQuantitySubclass def test_order(self): """Test that order is correctly propagated to np.array""" ac = np.array(np.arange(10.), order='C') qcc = u.Quantity(ac, u.m, order='C') assert qcc.flags['C_CONTIGUOUS'] qcf = u.Quantity(ac, u.m, order='F') assert qcf.flags['F_CONTIGUOUS'] qca = u.Quantity(ac, u.m, order='A') assert qca.flags['C_CONTIGUOUS'] # check it works also when passing in a quantity assert u.Quantity(qcc, order='C').flags['C_CONTIGUOUS'] assert u.Quantity(qcc, order='A').flags['C_CONTIGUOUS'] assert u.Quantity(qcc, order='F').flags['F_CONTIGUOUS'] af = np.array(np.arange(10.), order='F') qfc = u.Quantity(af, u.m, order='C') assert qfc.flags['C_CONTIGUOUS'] qff = u.Quantity(ac, u.m, order='F') assert qff.flags['F_CONTIGUOUS'] qfa = u.Quantity(af, u.m, order='A') assert qfa.flags['F_CONTIGUOUS'] assert u.Quantity(qff, order='C').flags['C_CONTIGUOUS'] assert u.Quantity(qff, order='A').flags['F_CONTIGUOUS'] assert u.Quantity(qff, order='F').flags['F_CONTIGUOUS'] def test_ndmin(self): """Test that ndmin is correctly propagated to np.array""" a = np.arange(10.) q1 = u.Quantity(a, u.m, ndmin=1) assert q1.ndim == 1 and q1.shape == (10,) q2 = u.Quantity(a, u.m, ndmin=2) assert q2.ndim == 2 and q2.shape == (1, 10) # check it works also when passing in a quantity q3 = u.Quantity(q1, u.m, ndmin=3) assert q3.ndim == 3 and q3.shape == (1, 1, 10) # see github issue #10063 assert u.Quantity(u.Quantity(1, 'm'), 'm', ndmin=1).ndim == 1 assert u.Quantity(u.Quantity(1, 'cm'), 'm', ndmin=1).ndim == 1 def test_non_quantity_with_unit(self): """Test that unit attributes in objects get recognized.""" class MyQuantityLookalike(np.ndarray): pass a = np.arange(3.) mylookalike = a.copy().view(MyQuantityLookalike) mylookalike.unit = 'm' q1 = u.Quantity(mylookalike) assert isinstance(q1, u.Quantity) assert q1.unit is u.m assert np.all(q1.value == a) q2 = u.Quantity(mylookalike, u.mm) assert q2.unit is u.mm assert np.all(q2.value == 1000.*a) q3 = u.Quantity(mylookalike, copy=False) assert np.all(q3.value == mylookalike) q3[2] = 0 assert q3[2] == 0. assert mylookalike[2] == 0. mylookalike = a.copy().view(MyQuantityLookalike) mylookalike.unit = u.m q4 = u.Quantity(mylookalike, u.mm, copy=False) q4[2] = 0 assert q4[2] == 0. assert mylookalike[2] == 2. mylookalike.unit = 'nonsense' with pytest.raises(TypeError): u.Quantity(mylookalike) def test_creation_via_view(self): # This works but is no better than 1. * u.m q1 = 1. << u.m assert isinstance(q1, u.Quantity) assert q1.unit == u.m assert q1.value == 1. # With an array, we get an actual view. a2 = np.arange(10.) q2 = a2 << u.m / u.s assert isinstance(q2, u.Quantity) assert q2.unit == u.m / u.s assert np.all(q2.value == a2) a2[9] = 0. assert np.all(q2.value == a2) # But with a unit change we get a copy. q3 = q2 << u.mm / u.s assert isinstance(q3, u.Quantity) assert q3.unit == u.mm / u.s assert np.all(q3.value == a2 * 1000.) a2[8] = 0. assert q3[8].value == 8000. # Without a unit change, we do get a view. q4 = q2 << q2.unit a2[7] = 0. assert np.all(q4.value == a2) with pytest.raises(u.UnitsError): q2 << u.s # But one can do an in-place unit change. a2_copy = a2.copy() q2 <<= u.mm / u.s assert q2.unit == u.mm / u.s # Of course, this changes a2 as well. assert np.all(q2.value == a2) # Sanity check on the values. assert np.all(q2.value == a2_copy * 1000.) a2[8] = -1. # Using quantities, one can also work with strings. q5 = q2 << 'km/hr' assert q5.unit == u.km / u.hr assert np.all(q5 == q2) # Finally, we can use scalar quantities as units. not_quite_a_foot = 30. * u.cm a6 = np.arange(5.) q6 = a6 << not_quite_a_foot assert q6.unit == u.Unit(not_quite_a_foot) assert np.all(q6.to_value(u.cm) == 30. * a6) def test_rshift_warns(self): with pytest.raises(TypeError), \ pytest.warns(AstropyWarning, match='is not implemented') as warning_lines: 1 >> u.m assert len(warning_lines) == 1 q = 1. * u.km with pytest.raises(TypeError), \ pytest.warns(AstropyWarning, match='is not implemented') as warning_lines: q >> u.m assert len(warning_lines) == 1 with pytest.raises(TypeError), \ pytest.warns(AstropyWarning, match='is not implemented') as warning_lines: q >>= u.m assert len(warning_lines) == 1 with pytest.raises(TypeError), \ pytest.warns(AstropyWarning, match='is not implemented') as warning_lines: 1. >> q assert len(warning_lines) == 1 class TestQuantityOperations: q1 = u.Quantity(11.42, u.meter) q2 = u.Quantity(8.0, u.centimeter) def test_addition(self): # Take units from left object, q1 new_quantity = self.q1 + self.q2 assert new_quantity.value == 11.5 assert new_quantity.unit == u.meter # Take units from left object, q2 new_quantity = self.q2 + self.q1 assert new_quantity.value == 1150.0 assert new_quantity.unit == u.centimeter new_q = u.Quantity(1500.1, u.m) + u.Quantity(13.5, u.km) assert new_q.unit == u.m assert new_q.value == 15000.1 def test_subtraction(self): # Take units from left object, q1 new_quantity = self.q1 - self.q2 assert new_quantity.value == 11.34 assert new_quantity.unit == u.meter # Take units from left object, q2 new_quantity = self.q2 - self.q1 assert new_quantity.value == -1134.0 assert new_quantity.unit == u.centimeter def test_multiplication(self): # Take units from left object, q1 new_quantity = self.q1 * self.q2 assert new_quantity.value == 91.36 assert new_quantity.unit == (u.meter * u.centimeter) # Take units from left object, q2 new_quantity = self.q2 * self.q1 assert new_quantity.value == 91.36 assert new_quantity.unit == (u.centimeter * u.meter) # Multiply with a number new_quantity = 15. * self.q1 assert new_quantity.value == 171.3 assert new_quantity.unit == u.meter # Multiply with a number new_quantity = self.q1 * 15. assert new_quantity.value == 171.3 assert new_quantity.unit == u.meter def test_division(self): # Take units from left object, q1 new_quantity = self.q1 / self.q2 assert_array_almost_equal(new_quantity.value, 1.4275, decimal=5) assert new_quantity.unit == (u.meter / u.centimeter) # Take units from left object, q2 new_quantity = self.q2 / self.q1 assert_array_almost_equal(new_quantity.value, 0.70052539404553416, decimal=16) assert new_quantity.unit == (u.centimeter / u.meter) q1 = u.Quantity(11.4, unit=u.meter) q2 = u.Quantity(10.0, unit=u.second) new_quantity = q1 / q2 assert_array_almost_equal(new_quantity.value, 1.14, decimal=10) assert new_quantity.unit == (u.meter / u.second) # divide with a number new_quantity = self.q1 / 10. assert new_quantity.value == 1.142 assert new_quantity.unit == u.meter # divide with a number new_quantity = 11.42 / self.q1 assert new_quantity.value == 1. assert new_quantity.unit == u.Unit("1/m") def test_commutativity(self): """Regression test for issue #587.""" new_q = u.Quantity(11.42, 'm*s') assert self.q1 * u.s == u.s * self.q1 == new_q assert self.q1 / u.s == u.Quantity(11.42, 'm/s') assert u.s / self.q1 == u.Quantity(1 / 11.42, 's/m') def test_power(self): # raise quantity to a power new_quantity = self.q1 ** 2 assert_array_almost_equal(new_quantity.value, 130.4164, decimal=5) assert new_quantity.unit == u.Unit("m^2") new_quantity = self.q1 ** 3 assert_array_almost_equal(new_quantity.value, 1489.355288, decimal=7) assert new_quantity.unit == u.Unit("m^3") def test_matrix_multiplication(self): a = np.eye(3) q = a * u.m result1 = q @ a assert np.all(result1 == q) result2 = a @ q assert np.all(result2 == q) result3 = q @ q assert np.all(result3 == a * u.m ** 2) # less trivial case. q2 = np.array([[[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]], [[0., 1., 0.], [0., 0., 1.], [1., 0., 0.]], [[0., 0., 1.], [1., 0., 0.], [0., 1., 0.]]]) / u.s result4 = q @ q2 assert np.all(result4 == np.matmul(a, q2.value) * q.unit * q2.unit) def test_unary(self): # Test the minus unary operator new_quantity = -self.q1 assert new_quantity.value == -self.q1.value assert new_quantity.unit == self.q1.unit new_quantity = -(-self.q1) assert new_quantity.value == self.q1.value assert new_quantity.unit == self.q1.unit # Test the plus unary operator new_quantity = +self.q1 assert new_quantity.value == self.q1.value assert new_quantity.unit == self.q1.unit def test_abs(self): q = 1. * u.m / u.s new_quantity = abs(q) assert new_quantity.value == q.value assert new_quantity.unit == q.unit q = -1. * u.m / u.s new_quantity = abs(q) assert new_quantity.value == -q.value assert new_quantity.unit == q.unit def test_incompatible_units(self): """ When trying to add or subtract units that aren't compatible, throw an error """ q1 = u.Quantity(11.412, unit=u.meter) q2 = u.Quantity(21.52, unit=u.second) with pytest.raises(u.UnitsError): q1 + q2 def test_non_number_type(self): q1 = u.Quantity(11.412, unit=u.meter) with pytest.raises(TypeError) as exc: q1 + {'a': 1} assert exc.value.args[0].startswith( "Unsupported operand type(s) for ufunc add:") with pytest.raises(TypeError): q1 + u.meter def test_dimensionless_operations(self): # test conversion to dimensionless dq = 3. * u.m / u.km dq1 = dq + 1. * u.mm / u.km assert dq1.value == 3.001 assert dq1.unit == dq.unit dq2 = dq + 1. assert dq2.value == 1.003 assert dq2.unit == u.dimensionless_unscaled # this test will check that operations with dimensionless Quantities # don't work with pytest.raises(u.UnitsError): self.q1 + u.Quantity(0.1, unit=u.Unit("")) with pytest.raises(u.UnitsError): self.q1 - u.Quantity(0.1, unit=u.Unit("")) # and test that scaling of integers works q = u.Quantity(np.array([1, 2, 3]), u.m / u.km, dtype=int) q2 = q + np.array([4, 5, 6]) assert q2.unit == u.dimensionless_unscaled assert_allclose(q2.value, np.array([4.001, 5.002, 6.003])) # but not if doing it inplace with pytest.raises(TypeError): q += np.array([1, 2, 3]) # except if it is actually possible q = np.array([1, 2, 3]) * u.km / u.m q += np.array([4, 5, 6]) assert q.unit == u.dimensionless_unscaled assert np.all(q.value == np.array([1004, 2005, 3006])) def test_complicated_operation(self): """ Perform a more complicated test """ from astropy.units import imperial # Multiple units distance = u.Quantity(15., u.meter) time = u.Quantity(11., u.second) velocity = (distance / time).to(imperial.mile / u.hour) assert_array_almost_equal( velocity.value, 3.05037, decimal=5) G = u.Quantity(6.673E-11, u.m ** 3 / u.kg / u.s ** 2) _ = ((1. / (4. * np.pi * G)).to(u.pc ** -3 / u.s ** -2 * u.kg)) # Area side1 = u.Quantity(11., u.centimeter) side2 = u.Quantity(7., u.centimeter) area = side1 * side2 assert_array_almost_equal(area.value, 77., decimal=15) assert area.unit == u.cm * u.cm def test_comparison(self): # equality/ non-equality is straightforward for quantity objects assert (1 / (u.cm * u.cm)) == 1 * u.cm ** -2 assert 1 * u.m == 100 * u.cm assert 1 * u.m != 1 * u.cm # when one is a unit, Quantity does not know what to do, # but unit is fine with it, so it still works unit = u.cm**3 q = 1. * unit assert q.__eq__(unit) is NotImplemented assert unit.__eq__(q) is True assert q == unit q = 1000. * u.mm**3 assert q == unit # mismatched types should never work assert not 1. * u.cm == 1. assert 1. * u.cm != 1. # comparison with zero should raise a deprecation warning for quantity in (1. * u.cm, 1. * u.dimensionless_unscaled): with pytest.warns(AstropyDeprecationWarning, match='The truth value of ' 'a Quantity is ambiguous. In the future this will ' 'raise a ValueError.'): bool(quantity) def test_numeric_converters(self): # float, int, long, and __index__ should only work for single # quantities, of appropriate type, and only if they are dimensionless. # for index, this should be unscaled as well # (Check on __index__ is also a regression test for #1557) # quantities with units should never convert, or be usable as an index q1 = u.Quantity(1, u.m) converter_err_msg = ("only dimensionless scalar quantities " "can be converted to Python scalars") index_err_msg = ("only integer dimensionless scalar quantities " "can be converted to a Python index") with pytest.raises(TypeError) as exc: float(q1) assert exc.value.args[0] == converter_err_msg with pytest.raises(TypeError) as exc: int(q1) assert exc.value.args[0] == converter_err_msg # We used to test `q1 * ['a', 'b', 'c'] here, but that that worked # at all was a really odd confluence of bugs. Since it doesn't work # in numpy >=1.10 any more, just go directly for `__index__` (which # makes the test more similar to the `int`, `long`, etc., tests). with pytest.raises(TypeError) as exc: q1.__index__() assert exc.value.args[0] == index_err_msg # dimensionless but scaled is OK, however q2 = u.Quantity(1.23, u.m / u.km) assert float(q2) == float(q2.to_value(u.dimensionless_unscaled)) assert int(q2) == int(q2.to_value(u.dimensionless_unscaled)) with pytest.raises(TypeError) as exc: q2.__index__() assert exc.value.args[0] == index_err_msg # dimensionless unscaled is OK, though for index needs to be int q3 = u.Quantity(1.23, u.dimensionless_unscaled) assert float(q3) == 1.23 assert int(q3) == 1 with pytest.raises(TypeError) as exc: q3.__index__() assert exc.value.args[0] == index_err_msg # integer dimensionless unscaled is good for all q4 = u.Quantity(2, u.dimensionless_unscaled, dtype=int) assert float(q4) == 2. assert int(q4) == 2 assert q4.__index__() == 2 # but arrays are not OK q5 = u.Quantity([1, 2], u.m) with pytest.raises(TypeError) as exc: float(q5) assert exc.value.args[0] == converter_err_msg with pytest.raises(TypeError) as exc: int(q5) assert exc.value.args[0] == converter_err_msg with pytest.raises(TypeError) as exc: q5.__index__() assert exc.value.args[0] == index_err_msg # See https://github.com/numpy/numpy/issues/5074 # It seems unlikely this will be resolved, so xfail'ing it. @pytest.mark.xfail(reason="list multiplication only works for numpy <=1.10") def test_numeric_converter_to_index_in_practice(self): """Test that use of __index__ actually works.""" q4 = u.Quantity(2, u.dimensionless_unscaled, dtype=int) assert q4 * ['a', 'b', 'c'] == ['a', 'b', 'c', 'a', 'b', 'c'] def test_array_converters(self): # Scalar quantity q = u.Quantity(1.23, u.m) assert np.all(np.array(q) == np.array([1.23])) # Array quantity q = u.Quantity([1., 2., 3.], u.m) assert np.all(np.array(q) == np.array([1., 2., 3.])) def test_quantity_conversion(): q1 = u.Quantity(0.1, unit=u.meter) value = q1.value assert value == 0.1 value_in_km = q1.to_value(u.kilometer) assert value_in_km == 0.0001 new_quantity = q1.to(u.kilometer) assert new_quantity.value == 0.0001 with pytest.raises(u.UnitsError): q1.to(u.zettastokes) with pytest.raises(u.UnitsError): q1.to_value(u.zettastokes) def test_quantity_value_views(): q1 = u.Quantity([1., 2.], unit=u.meter) # views if the unit is the same. v1 = q1.value v1[0] = 0. assert np.all(q1 == [0., 2.] * u.meter) v2 = q1.to_value() v2[1] = 3. assert np.all(q1 == [0., 3.] * u.meter) v3 = q1.to_value('m') v3[0] = 1. assert np.all(q1 == [1., 3.] * u.meter) q2 = q1.to('m', copy=False) q2[0] = 2 * u.meter assert np.all(q1 == [2., 3.] * u.meter) v4 = q1.to_value('cm') v4[0] = 0. # copy if different unit. assert np.all(q1 == [2., 3.] * u.meter) def test_quantity_conversion_with_equiv(): q1 = u.Quantity(0.1, unit=u.meter) v2 = q1.to_value(u.Hz, equivalencies=u.spectral()) assert_allclose(v2, 2997924580.0) q2 = q1.to(u.Hz, equivalencies=u.spectral()) assert_allclose(q2.value, v2) q1 = u.Quantity(0.4, unit=u.arcsecond) v2 = q1.to_value(u.au, equivalencies=u.parallax()) q2 = q1.to(u.au, equivalencies=u.parallax()) v3 = q2.to_value(u.arcminute, equivalencies=u.parallax()) q3 = q2.to(u.arcminute, equivalencies=u.parallax()) assert_allclose(v2, 515662.015) assert_allclose(q2.value, v2) assert q2.unit == u.au assert_allclose(v3, 0.0066666667) assert_allclose(q3.value, v3) assert q3.unit == u.arcminute def test_quantity_conversion_equivalency_passed_on(): class MySpectral(u.Quantity): _equivalencies = u.spectral() def __quantity_view__(self, obj, unit): return obj.view(MySpectral) def __quantity_instance__(self, *args, **kwargs): return MySpectral(*args, **kwargs) q1 = MySpectral([1000, 2000], unit=u.Hz) q2 = q1.to(u.nm) assert q2.unit == u.nm q3 = q2.to(u.Hz) assert q3.unit == u.Hz assert_allclose(q3.value, q1.value) q4 = MySpectral([1000, 2000], unit=u.nm) q5 = q4.to(u.Hz).to(u.nm) assert q5.unit == u.nm assert_allclose(q4.value, q5.value) # Regression test for issue #2315, divide-by-zero error when examining 0*unit def test_self_equivalency(): assert u.deg.is_equivalent(0*u.radian) assert u.deg.is_equivalent(1*u.radian) def test_si(): q1 = 10. * u.m * u.s ** 2 / (200. * u.ms) ** 2 # 250 meters assert q1.si.value == 250 assert q1.si.unit == u.m q = 10. * u.m # 10 meters assert q.si.value == 10 assert q.si.unit == u.m q = 10. / u.m # 10 1 / meters assert q.si.value == 10 assert q.si.unit == (1 / u.m) def test_cgs(): q1 = 10. * u.cm * u.s ** 2 / (200. * u.ms) ** 2 # 250 centimeters assert q1.cgs.value == 250 assert q1.cgs.unit == u.cm q = 10. * u.m # 10 centimeters assert q.cgs.value == 1000 assert q.cgs.unit == u.cm q = 10. / u.cm # 10 1 / centimeters assert q.cgs.value == 10 assert q.cgs.unit == (1 / u.cm) q = 10. * u.Pa # 10 pascals assert q.cgs.value == 100 assert q.cgs.unit == u.barye class TestQuantityComparison: def test_quantity_equality(self): assert u.Quantity(1000, unit='m') == u.Quantity(1, unit='km') assert not (u.Quantity(1, unit='m') == u.Quantity(1, unit='km')) # for ==, !=, return False, True if units do not match assert (u.Quantity(1100, unit=u.m) != u.Quantity(1, unit=u.s)) is True assert (u.Quantity(1100, unit=u.m) == u.Quantity(1, unit=u.s)) is False assert (u.Quantity(0, unit=u.m) == u.Quantity(0, unit=u.s)) is False # But allow comparison with 0, +/-inf if latter unitless assert u.Quantity(0, u.m) == 0. assert u.Quantity(1, u.m) != 0. assert u.Quantity(1, u.m) != np.inf assert u.Quantity(np.inf, u.m) == np.inf def test_quantity_equality_array(self): a = u.Quantity([0., 1., 1000.], u.m) b = u.Quantity(1., u.km) eq = a == b ne = a != b assert np.all(eq == [False, False, True]) assert np.all(eq != ne) # For mismatched units, we should just get True, False c = u.Quantity(1., u.s) eq = a == c ne = a != c assert eq is False assert ne is True # Constants are treated as dimensionless, so False too. eq = a == 1. ne = a != 1. assert eq is False assert ne is True # But 0 can have any units, so we can compare. eq = a == 0 ne = a != 0 assert np.all(eq == [True, False, False]) assert np.all(eq != ne) # But we do not extend that to arrays; they should have the same unit. d = np.array([0, 1., 1000.]) eq = a == d ne = a != d assert eq is False assert ne is True def test_quantity_comparison(self): assert u.Quantity(1100, unit=u.meter) > u.Quantity(1, unit=u.kilometer) assert u.Quantity(900, unit=u.meter) < u.Quantity(1, unit=u.kilometer) with pytest.raises(u.UnitsError): assert u.Quantity(1100, unit=u.meter) > u.Quantity(1, unit=u.second) with pytest.raises(u.UnitsError): assert u.Quantity(1100, unit=u.meter) < u.Quantity(1, unit=u.second) assert u.Quantity(1100, unit=u.meter) >= u.Quantity(1, unit=u.kilometer) assert u.Quantity(1000, unit=u.meter) >= u.Quantity(1, unit=u.kilometer) assert u.Quantity(900, unit=u.meter) <= u.Quantity(1, unit=u.kilometer) assert u.Quantity(1000, unit=u.meter) <= u.Quantity(1, unit=u.kilometer) with pytest.raises(u.UnitsError): assert u.Quantity( 1100, unit=u.meter) >= u.Quantity(1, unit=u.second) with pytest.raises(u.UnitsError): assert u.Quantity(1100, unit=u.meter) <= u.Quantity(1, unit=u.second) assert u.Quantity(1200, unit=u.meter) != u.Quantity(1, unit=u.kilometer) class TestQuantityDisplay: scalarintq = u.Quantity(1, unit='m', dtype=int) scalarfloatq = u.Quantity(1.3, unit='m') arrq = u.Quantity([1, 2.3, 8.9], unit='m') scalar_complex_q = u.Quantity(complex(1.0, 2.0)) scalar_big_complex_q = u.Quantity(complex(1.0, 2.0e27) * 1e25) scalar_big_neg_complex_q = u.Quantity(complex(-1.0, -2.0e27) * 1e36) arr_complex_q = u.Quantity(np.arange(3) * (complex(-1.0, -2.0e27) * 1e36)) big_arr_complex_q = u.Quantity(np.arange(125) * (complex(-1.0, -2.0e27) * 1e36)) def test_dimensionless_quantity_repr(self): q2 = u.Quantity(1., unit='m-1') q3 = u.Quantity(1, unit='m-1', dtype=int) assert repr(self.scalarintq * q2) == "" assert repr(self.arrq * q2) == "" assert repr(self.scalarintq * q3) == "" def test_dimensionless_quantity_str(self): q2 = u.Quantity(1., unit='m-1') q3 = u.Quantity(1, unit='m-1', dtype=int) assert str(self.scalarintq * q2) == "1.0" assert str(self.scalarintq * q3) == "1" assert str(self.arrq * q2) == "[1. 2.3 8.9]" def test_dimensionless_quantity_format(self): q1 = u.Quantity(3.14) assert format(q1, '.2f') == '3.14' def test_scalar_quantity_str(self): assert str(self.scalarintq) == "1 m" assert str(self.scalarfloatq) == "1.3 m" def test_scalar_quantity_repr(self): assert repr(self.scalarintq) == "" assert repr(self.scalarfloatq) == "" def test_array_quantity_str(self): assert str(self.arrq) == "[1. 2.3 8.9] m" def test_array_quantity_repr(self): assert repr(self.arrq) == "" def test_scalar_quantity_format(self): assert format(self.scalarintq, '02d') == "01 m" assert format(self.scalarfloatq, '.1f') == "1.3 m" assert format(self.scalarfloatq, '.0f') == "1 m" def test_uninitialized_unit_format(self): bad_quantity = np.arange(10.).view(u.Quantity) assert str(bad_quantity).endswith(_UNIT_NOT_INITIALISED) assert repr(bad_quantity).endswith(_UNIT_NOT_INITIALISED + '>') def test_to_string(self): qscalar = u.Quantity(1.5e14, 'm/s') # __str__ is the default `format` assert str(qscalar) == qscalar.to_string() res = 'Quantity as KMS: 150000000000.0 km / s' assert f"Quantity as KMS: {qscalar.to_string(unit=u.km / u.s)}" == res # With precision set res = 'Quantity as KMS: 1.500e+11 km / s' assert f"Quantity as KMS: {qscalar.to_string(precision=3, unit=u.km / u.s)}" == res res = r'$1.5 \times 10^{14} \; \mathrm{\frac{m}{s}}$' assert qscalar.to_string(format="latex") == res res = r'$1.5 \times 10^{14} \; \mathrm{\frac{m}{s}}$' assert qscalar.to_string(format="latex", subfmt="inline") == res res = r'$\displaystyle 1.5 \times 10^{14} \; \mathrm{\frac{m}{s}}$' assert qscalar.to_string(format="latex", subfmt="display") == res def test_repr_latex(self): from astropy.units.quantity import conf q2scalar = u.Quantity(1.5e14, 'm/s') assert self.scalarintq._repr_latex_() == r'$1 \; \mathrm{m}$' assert self.scalarfloatq._repr_latex_() == r'$1.3 \; \mathrm{m}$' assert (q2scalar._repr_latex_() == r'$1.5 \times 10^{14} \; \mathrm{\frac{m}{s}}$') assert self.arrq._repr_latex_() == r'$[1,~2.3,~8.9] \; \mathrm{m}$' # Complex quantities assert self.scalar_complex_q._repr_latex_() == r'$(1+2i) \; \mathrm{}$' assert (self.scalar_big_complex_q._repr_latex_() == r'$(1 \times 10^{25}+2 \times 10^{52}i) \; \mathrm{}$') assert (self.scalar_big_neg_complex_q._repr_latex_() == r'$(-1 \times 10^{36}-2 \times 10^{63}i) \; \mathrm{}$') assert (self.arr_complex_q._repr_latex_() == (r'$[(0-0i),~(-1 \times 10^{36}-2 \times 10^{63}i),' r'~(-2 \times 10^{36}-4 \times 10^{63}i)] \; \mathrm{}$')) assert r'\dots' in self.big_arr_complex_q._repr_latex_() qmed = np.arange(100)*u.m qbig = np.arange(1000)*u.m qvbig = np.arange(10000)*1e9*u.m pops = np.get_printoptions() oldlat = conf.latex_array_threshold try: # check precision behavior q = u.Quantity(987654321.123456789, 'm/s') qa = np.array([7.89123, 123456789.987654321, 0]) * u.cm np.set_printoptions(precision=8) assert q._repr_latex_() == r'$9.8765432 \times 10^{8} \; \mathrm{\frac{m}{s}}$' assert qa._repr_latex_() == r'$[7.89123,~1.2345679 \times 10^{8},~0] \; \mathrm{cm}$' np.set_printoptions(precision=2) assert q._repr_latex_() == r'$9.9 \times 10^{8} \; \mathrm{\frac{m}{s}}$' assert qa._repr_latex_() == r'$[7.9,~1.2 \times 10^{8},~0] \; \mathrm{cm}$' # check thresholding behavior conf.latex_array_threshold = 100 # should be default lsmed = qmed._repr_latex_() assert r'\dots' not in lsmed lsbig = qbig._repr_latex_() assert r'\dots' in lsbig lsvbig = qvbig._repr_latex_() assert r'\dots' in lsvbig conf.latex_array_threshold = 1001 lsmed = qmed._repr_latex_() assert r'\dots' not in lsmed lsbig = qbig._repr_latex_() assert r'\dots' not in lsbig lsvbig = qvbig._repr_latex_() assert r'\dots' in lsvbig conf.latex_array_threshold = -1 # means use the numpy threshold np.set_printoptions(threshold=99) lsmed = qmed._repr_latex_() assert r'\dots' in lsmed lsbig = qbig._repr_latex_() assert r'\dots' in lsbig lsvbig = qvbig._repr_latex_() assert r'\dots' in lsvbig assert lsvbig.endswith(',~1 \\times 10^{13}] \\; \\mathrm{m}$') finally: # prevent side-effects from influencing other tests np.set_printoptions(**pops) conf.latex_array_threshold = oldlat qinfnan = [np.inf, -np.inf, np.nan] * u.m assert qinfnan._repr_latex_() == r'$[\infty,~-\infty,~{\rm NaN}] \; \mathrm{m}$' def test_decompose(): q1 = 5 * u.N assert q1.decompose() == (5 * u.kg * u.m * u.s ** -2) def test_decompose_regression(): """ Regression test for bug #1163 If decompose was called multiple times on a Quantity with an array and a scale != 1, the result changed every time. This is because the value was being referenced not copied, then modified, which changed the original value. """ q = np.array([1, 2, 3]) * u.m / (2. * u.km) assert np.all(q.decompose().value == np.array([0.0005, 0.001, 0.0015])) assert np.all(q == np.array([1, 2, 3]) * u.m / (2. * u.km)) assert np.all(q.decompose().value == np.array([0.0005, 0.001, 0.0015])) def test_arrays(): """ Test using quantites with array values """ qsec = u.Quantity(np.arange(10), u.second) assert isinstance(qsec.value, np.ndarray) assert not qsec.isscalar # len and indexing should work for arrays assert len(qsec) == len(qsec.value) qsecsub25 = qsec[2:5] assert qsecsub25.unit == qsec.unit assert isinstance(qsecsub25, u.Quantity) assert len(qsecsub25) == 3 # make sure isscalar, len, and indexing behave correctly for non-arrays. qsecnotarray = u.Quantity(10., u.second) assert qsecnotarray.isscalar with pytest.raises(TypeError): len(qsecnotarray) with pytest.raises(TypeError): qsecnotarray[0] qseclen0array = u.Quantity(np.array(10), u.second, dtype=int) # 0d numpy array should act basically like a scalar assert qseclen0array.isscalar with pytest.raises(TypeError): len(qseclen0array) with pytest.raises(TypeError): qseclen0array[0] assert isinstance(qseclen0array.value, numbers.Integral) a = np.array([(1., 2., 3.), (4., 5., 6.), (7., 8., 9.)], dtype=[('x', float), ('y', float), ('z', float)]) qkpc = u.Quantity(a, u.kpc) assert not qkpc.isscalar qkpc0 = qkpc[0] assert qkpc0.value == a[0] assert qkpc0.unit == qkpc.unit assert isinstance(qkpc0, u.Quantity) assert qkpc0.isscalar qkpcx = qkpc['x'] assert np.all(qkpcx.value == a['x']) assert qkpcx.unit == qkpc.unit assert isinstance(qkpcx, u.Quantity) assert not qkpcx.isscalar qkpcx1 = qkpc['x'][1] assert qkpcx1.unit == qkpc.unit assert isinstance(qkpcx1, u.Quantity) assert qkpcx1.isscalar qkpc1x = qkpc[1]['x'] assert qkpc1x.isscalar assert qkpc1x == qkpcx1 # can also create from lists, will auto-convert to arrays qsec = u.Quantity(list(range(10)), u.second) assert isinstance(qsec.value, np.ndarray) # quantity math should work with arrays assert_array_equal((qsec * 2).value, (np.arange(10) * 2)) assert_array_equal((qsec / 2).value, (np.arange(10) / 2)) # quantity addition/subtraction should *not* work with arrays b/c unit # ambiguous with pytest.raises(u.UnitsError): assert_array_equal((qsec + 2).value, (np.arange(10) + 2)) with pytest.raises(u.UnitsError): assert_array_equal((qsec - 2).value, (np.arange(10) + 2)) # should create by unit multiplication, too qsec2 = np.arange(10) * u.second qsec3 = u.second * np.arange(10) assert np.all(qsec == qsec2) assert np.all(qsec2 == qsec3) # make sure numerical-converters fail when arrays are present with pytest.raises(TypeError): float(qsec) with pytest.raises(TypeError): int(qsec) def test_array_indexing_slicing(): q = np.array([1., 2., 3.]) * u.m assert q[0] == 1. * u.m assert np.all(q[0:2] == u.Quantity([1., 2.], u.m)) def test_array_setslice(): q = np.array([1., 2., 3.]) * u.m q[1:2] = np.array([400.]) * u.cm assert np.all(q == np.array([1., 4., 3.]) * u.m) def test_inverse_quantity(): """ Regression test from issue #679 """ q = u.Quantity(4., u.meter / u.second) qot = q / 2 toq = 2 / q npqot = q / np.array(2) assert npqot.value == 2.0 assert npqot.unit == (u.meter / u.second) assert qot.value == 2.0 assert qot.unit == (u.meter / u.second) assert toq.value == 0.5 assert toq.unit == (u.second / u.meter) def test_quantity_mutability(): q = u.Quantity(9.8, u.meter / u.second / u.second) with pytest.raises(AttributeError): q.value = 3 with pytest.raises(AttributeError): q.unit = u.kg def test_quantity_initialized_with_quantity(): q1 = u.Quantity(60, u.second) q2 = u.Quantity(q1, u.minute) assert q2.value == 1 q3 = u.Quantity([q1, q2], u.second) assert q3[0].value == 60 assert q3[1].value == 60 q4 = u.Quantity([q2, q1]) assert q4.unit == q2.unit assert q4[0].value == 1 assert q4[1].value == 1 def test_quantity_string_unit(): q1 = 1. * u.m / 's' assert q1.value == 1 assert q1.unit == (u.m / u.s) q2 = q1 * "m" assert q2.unit == ((u.m * u.m) / u.s) def test_quantity_invalid_unit_string(): with pytest.raises(ValueError): "foo" * u.m def test_implicit_conversion(): q = u.Quantity(1.0, u.meter) # Manually turn this on to simulate what might happen in a subclass q._include_easy_conversion_members = True assert_allclose(q.centimeter, 100) assert_allclose(q.cm, 100) assert_allclose(q.parsec, 3.240779289469756e-17) def test_implicit_conversion_autocomplete(): q = u.Quantity(1.0, u.meter) # Manually turn this on to simulate what might happen in a subclass q._include_easy_conversion_members = True q.foo = 42 attrs = dir(q) assert 'centimeter' in attrs assert 'cm' in attrs assert 'parsec' in attrs assert 'foo' in attrs assert 'to' in attrs assert 'value' in attrs # Something from the base class, object assert '__setattr__' in attrs with pytest.raises(AttributeError): q.l def test_quantity_iterability(): """Regressiont est for issue #878. Scalar quantities should not be iterable and should raise a type error on iteration. """ q1 = [15.0, 17.0] * u.m assert isiterable(q1) q2 = next(iter(q1)) assert q2 == 15.0 * u.m assert not isiterable(q2) pytest.raises(TypeError, iter, q2) def test_copy(): q1 = u.Quantity(np.array([[1., 2., 3.], [4., 5., 6.]]), unit=u.m) q2 = q1.copy() assert np.all(q1.value == q2.value) assert q1.unit == q2.unit assert q1.dtype == q2.dtype assert q1.value is not q2.value q3 = q1.copy(order='F') assert q3.flags['F_CONTIGUOUS'] assert np.all(q1.value == q3.value) assert q1.unit == q3.unit assert q1.dtype == q3.dtype assert q1.value is not q3.value q4 = q1.copy(order='C') assert q4.flags['C_CONTIGUOUS'] assert np.all(q1.value == q4.value) assert q1.unit == q4.unit assert q1.dtype == q4.dtype assert q1.value is not q4.value def test_deepcopy(): q1 = u.Quantity(np.array([1., 2., 3.]), unit=u.m) q2 = copy.deepcopy(q1) assert isinstance(q2, u.Quantity) assert np.all(q1.value == q2.value) assert q1.unit == q2.unit assert q1.dtype == q2.dtype assert q1.value is not q2.value def test_equality_numpy_scalar(): """ A regression test to ensure that numpy scalars are correctly compared (which originally failed due to the lack of ``__array_priority__``). """ assert 10 != 10. * u.m assert np.int64(10) != 10 * u.m assert 10 * u.m != np.int64(10) def test_quantity_pickelability(): """ Testing pickleability of quantity """ q1 = np.arange(10) * u.m q2 = pickle.loads(pickle.dumps(q1)) assert np.all(q1.value == q2.value) assert q1.unit.is_equivalent(q2.unit) assert q1.unit == q2.unit def test_quantity_initialisation_from_string(): q = u.Quantity('1') assert q.unit == u.dimensionless_unscaled assert q.value == 1. q = u.Quantity('1.5 m/s') assert q.unit == u.m/u.s assert q.value == 1.5 assert u.Unit(q) == u.Unit('1.5 m/s') q = u.Quantity('.5 m') assert q == u.Quantity(0.5, u.m) q = u.Quantity('-1e1km') assert q == u.Quantity(-10, u.km) q = u.Quantity('-1e+1km') assert q == u.Quantity(-10, u.km) q = u.Quantity('+.5km') assert q == u.Quantity(.5, u.km) q = u.Quantity('+5e-1km') assert q == u.Quantity(.5, u.km) q = u.Quantity('5', u.m) assert q == u.Quantity(5., u.m) q = u.Quantity('5 km', u.m) assert q.value == 5000. assert q.unit == u.m q = u.Quantity('5Em') assert q == u.Quantity(5., u.Em) with pytest.raises(TypeError): u.Quantity('') with pytest.raises(TypeError): u.Quantity('m') with pytest.raises(TypeError): u.Quantity('1.2.3 deg') with pytest.raises(TypeError): u.Quantity('1+deg') with pytest.raises(TypeError): u.Quantity('1-2deg') with pytest.raises(TypeError): u.Quantity('1.2e-13.3m') with pytest.raises(TypeError): u.Quantity(['5']) with pytest.raises(TypeError): u.Quantity(np.array(['5'])) with pytest.raises(ValueError): u.Quantity('5E') with pytest.raises(ValueError): u.Quantity('5 foo') def test_unsupported(): q1 = np.arange(10) * u.m with pytest.raises(TypeError): np.bitwise_and(q1, q1) def test_unit_identity(): q = 1.0 * u.hour assert q.unit is u.hour def test_quantity_to_view(): q1 = np.array([1000, 2000]) * u.m q2 = q1.to(u.km) assert q1.value[0] == 1000 assert q2.value[0] == 1 def test_quantity_tuple_power(): with pytest.raises(ValueError): (5.0 * u.m) ** (1, 2) def test_quantity_fraction_power(): q = (25.0 * u.m**2) ** Fraction(1, 2) assert q.value == 5. assert q.unit == u.m # Regression check to ensure we didn't create an object type by raising # the value of the quantity to a Fraction. [#3922] assert q.dtype.kind == 'f' def test_quantity_from_table(): """ Checks that units from tables are respected when converted to a Quantity. This also generically checks the use of *anything* with a `unit` attribute passed into Quantity """ from astropy.table import Table t = Table(data=[np.arange(5), np.arange(5)], names=['a', 'b']) t['a'].unit = u.kpc qa = u.Quantity(t['a']) assert qa.unit == u.kpc assert_array_equal(qa.value, t['a']) qb = u.Quantity(t['b']) assert qb.unit == u.dimensionless_unscaled assert_array_equal(qb.value, t['b']) # This does *not* auto-convert, because it's not necessarily obvious that's # desired. Instead we revert to standard `Quantity` behavior qap = u.Quantity(t['a'], u.pc) assert qap.unit == u.pc assert_array_equal(qap.value, t['a'] * 1000) qbp = u.Quantity(t['b'], u.pc) assert qbp.unit == u.pc assert_array_equal(qbp.value, t['b']) # Also check with a function unit (regression test for gh-8430) t['a'].unit = u.dex(u.cm/u.s**2) fq = u.Dex(t['a']) assert fq.unit == u.dex(u.cm/u.s**2) assert_array_equal(fq.value, t['a']) fq2 = u.Quantity(t['a'], subok=True) assert isinstance(fq2, u.Dex) assert fq2.unit == u.dex(u.cm/u.s**2) assert_array_equal(fq2.value, t['a']) with pytest.raises(u.UnitTypeError): u.Quantity(t['a']) def test_assign_slice_with_quantity_like(): # Regression tests for gh-5961 from astropy.table import Table, Column # first check directly that we can use a Column to assign to a slice. c = Column(np.arange(10.), unit=u.mm) q = u.Quantity(c) q[:2] = c[:2] # next check that we do not fail the original problem. t = Table() t['x'] = np.arange(10) * u.mm t['y'] = np.ones(10) * u.mm assert type(t['x']) is Column xy = np.vstack([t['x'], t['y']]).T * u.mm ii = [0, 2, 4] assert xy[ii, 0].unit == t['x'][ii].unit # should not raise anything xy[ii, 0] = t['x'][ii] def test_insert(): """ Test Quantity.insert method. This does not test the full capabilities of the underlying np.insert, but hits the key functionality for Quantity. """ q = [1, 2] * u.m # Insert a compatible float with different units q2 = q.insert(0, 1 * u.km) assert np.all(q2.value == [1000, 1, 2]) assert q2.unit is u.m assert q2.dtype.kind == 'f' if minversion(np, '1.8.0'): q2 = q.insert(1, [1, 2] * u.km) assert np.all(q2.value == [1, 1000, 2000, 2]) assert q2.unit is u.m # Cannot convert 1.5 * u.s to m with pytest.raises(u.UnitsError): q.insert(1, 1.5 * u.s) # Tests with multi-dim quantity q = [[1, 2], [3, 4]] * u.m q2 = q.insert(1, [10, 20] * u.m, axis=0) assert np.all(q2.value == [[1, 2], [10, 20], [3, 4]]) q2 = q.insert(1, [10, 20] * u.m, axis=1) assert np.all(q2.value == [[1, 10, 2], [3, 20, 4]]) q2 = q.insert(1, 10 * u.m, axis=1) assert np.all(q2.value == [[1, 10, 2], [3, 10, 4]]) def test_repr_array_of_quantity(): """ Test print/repr of object arrays of Quantity objects with different units. Regression test for the issue first reported in https://github.com/astropy/astropy/issues/3777 """ a = np.array([1 * u.m, 2 * u.s], dtype=object) assert repr(a) == 'array([, ], dtype=object)' assert str(a) == '[ ]' class TestSpecificTypeQuantity: def setup(self): class Length(u.SpecificTypeQuantity): _equivalent_unit = u.m class Length2(Length): _default_unit = u.m class Length3(Length): _unit = u.m self.Length = Length self.Length2 = Length2 self.Length3 = Length3 def test_creation(self): l = self.Length(np.arange(10.)*u.km) assert type(l) is self.Length with pytest.raises(u.UnitTypeError): self.Length(np.arange(10.) * u.hour) with pytest.raises(u.UnitTypeError): self.Length(np.arange(10.)) l2 = self.Length2(np.arange(5.)) assert type(l2) is self.Length2 assert l2._default_unit is self.Length2._default_unit with pytest.raises(u.UnitTypeError): self.Length3(np.arange(10.)) def test_view(self): l = (np.arange(5.) * u.km).view(self.Length) assert type(l) is self.Length with pytest.raises(u.UnitTypeError): (np.arange(5.) * u.s).view(self.Length) v = np.arange(5.).view(self.Length) assert type(v) is self.Length assert v._unit is None l3 = np.ones((2, 2)).view(self.Length3) assert type(l3) is self.Length3 assert l3.unit is self.Length3._unit def test_operation_precedence_and_fallback(self): l = self.Length(np.arange(5.)*u.cm) sum1 = l + 1.*u.m assert type(sum1) is self.Length sum2 = 1.*u.km + l assert type(sum2) is self.Length sum3 = l + l assert type(sum3) is self.Length res1 = l * (1.*u.m) assert type(res1) is u.Quantity res2 = l * l assert type(res2) is u.Quantity def test_unit_class_override(): class MyQuantity(u.Quantity): pass my_unit = u.Unit("my_deg", u.deg) my_unit._quantity_class = MyQuantity q1 = u.Quantity(1., my_unit) assert type(q1) is u.Quantity q2 = u.Quantity(1., my_unit, subok=True) assert type(q2) is MyQuantity class QuantityMimic: def __init__(self, value, unit): self.value = value self.unit = unit def __array__(self): return np.array(self.value) class QuantityMimic2(QuantityMimic): def to(self, unit): return u.Quantity(self.value, self.unit).to(unit) def to_value(self, unit): return u.Quantity(self.value, self.unit).to_value(unit) class TestQuantityMimics: """Test Quantity Mimics that are not ndarray subclasses.""" @pytest.mark.parametrize('Mimic', (QuantityMimic, QuantityMimic2)) def test_mimic_input(self, Mimic): value = np.arange(10.) mimic = Mimic(value, u.m) q = u.Quantity(mimic) assert q.unit == u.m assert np.all(q.value == value) q2 = u.Quantity(mimic, u.cm) assert q2.unit == u.cm assert np.all(q2.value == 100 * value) @pytest.mark.parametrize('Mimic', (QuantityMimic, QuantityMimic2)) def test_mimic_setting(self, Mimic): mimic = Mimic([1., 2.], u.m) q = u.Quantity(np.arange(10.), u.cm) q[8:] = mimic assert np.all(q[:8].value == np.arange(8.)) assert np.all(q[8:].value == [100., 200.]) def test_mimic_function_unit(self): mimic = QuantityMimic([1., 2.], u.dex(u.cm/u.s**2)) d = u.Dex(mimic) assert isinstance(d, u.Dex) assert d.unit == u.dex(u.cm/u.s**2) assert np.all(d.value == [1., 2.]) q = u.Quantity(mimic, subok=True) assert isinstance(q, u.Dex) assert q.unit == u.dex(u.cm/u.s**2) assert np.all(q.value == [1., 2.]) with pytest.raises(u.UnitTypeError): u.Quantity(mimic) def test_masked_quantity_str_repr(): """Ensure we don't break masked Quantity representation.""" # Really, masked quantities do not work well, but at least let the # basics work. masked_quantity = np.ma.array([1, 2, 3, 4] * u.kg, mask=[True, False, True, False]) str(masked_quantity) repr(masked_quantity) class TestQuantitySubclassAboveAndBelow: @classmethod def setup_class(self): class MyArray(np.ndarray): def __array_finalize__(self, obj): super_array_finalize = super().__array_finalize__ if super_array_finalize is not None: super_array_finalize(obj) if hasattr(obj, 'my_attr'): self.my_attr = obj.my_attr self.MyArray = MyArray self.MyQuantity1 = type('MyQuantity1', (u.Quantity, MyArray), dict(my_attr='1')) self.MyQuantity2 = type('MyQuantity2', (MyArray, u.Quantity), dict(my_attr='2')) def test_setup(self): mq1 = self.MyQuantity1(10, u.m) assert isinstance(mq1, self.MyQuantity1) assert mq1.my_attr == '1' assert mq1.unit is u.m mq2 = self.MyQuantity2(10, u.m) assert isinstance(mq2, self.MyQuantity2) assert mq2.my_attr == '2' assert mq2.unit is u.m def test_attr_propagation(self): mq1 = self.MyQuantity1(10, u.m) mq12 = self.MyQuantity2(mq1) assert isinstance(mq12, self.MyQuantity2) assert not isinstance(mq12, self.MyQuantity1) assert mq12.my_attr == '1' assert mq12.unit is u.m mq2 = self.MyQuantity2(10, u.m) mq21 = self.MyQuantity1(mq2) assert isinstance(mq21, self.MyQuantity1) assert not isinstance(mq21, self.MyQuantity2) assert mq21.my_attr == '2' assert mq21.unit is u.m ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/tests/test_quantity_annotations.py0000644000175100001710000002517100000000000024164 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst # STDLIB import sys import typing as T # THIRD PARTY import pytest # LOCAL from astropy import units as u from astropy.units import Quantity from astropy.units._typing import HAS_ANNOTATED, Annotated def test_ignore_generic_type_annotations(): """Test annotations that are not unit related are ignored. This test passes if the function works. """ # one unit, one not (should be ignored) @u.quantity_input def func(x: u.m, y: str): return x, y i_q, i_str = 2 * u.m, "cool string" o_q, o_str = func(i_q, i_str) # if this doesn't fail, it worked. assert i_q == o_q assert i_str == o_str @pytest.mark.skipif(not HAS_ANNOTATED, reason="need `Annotated`") class TestQuantityUnitAnnotations: """Test Quantity[Unit] type annotation.""" def test_simple_annotation(self): @u.quantity_input def func(x: Quantity[u.m], y: str): return x, y i_q, i_str = 2 * u.m, "cool string" o_q, o_str = func(i_q, i_str) assert i_q == o_q assert i_str == o_str # checks the input on the 1st arg with pytest.raises(u.UnitsError): func(1 * u.s, i_str) # but not the second o_q, o_str = func(i_q, {"not": "a string"}) assert i_q == o_q assert i_str != o_str def test_multiple_annotation(self): @u.quantity_input def multi_func(a: Quantity[u.km]) -> Quantity[u.m]: return a i_q = 2 * u.km o_q = multi_func(i_q) assert o_q == i_q assert o_q.unit == u.m @pytest.mark.skipif(not HAS_ANNOTATED, reason="need `Annotated`") def test_optional_and_annotated(self): @u.quantity_input def opt_func(x: T.Optional[Quantity[u.m]] = None) -> Quantity[u.km]: if x is None: return 1 * u.km return x i_q = 250 * u.m o_q = opt_func(i_q) assert o_q.unit == u.km assert o_q == i_q i_q = None o_q = opt_func(i_q) assert o_q == 1 * u.km @pytest.mark.skipif(not HAS_ANNOTATED, reason="need `Annotated`") def test_union_and_annotated(self): # Union and Annotated @u.quantity_input def union_func(x: T.Union[Quantity[u.m], Quantity[u.s], None]): if x is None: return None else: return 2 * x i_q = 1 * u.m o_q = union_func(i_q) assert o_q == 2 * i_q i_q = 1 * u.s o_q = union_func(i_q) assert o_q == 2 * i_q i_q = None o_q = union_func(i_q) assert o_q is None def test_not_unit_or_ptype(self): with pytest.raises(TypeError, match="unit annotation is not"): Quantity["definitely not a unit"] @pytest.mark.skipif(HAS_ANNOTATED, reason="requires py3.8 behavior") def test_not_unit_or_ptype(): """ Same as above test, but different behavior for python 3.8 b/c it passes Quantity right through. """ with pytest.warns(Warning): annot = Quantity[u.km] assert annot == u.km @pytest.mark.parametrize("solarx_unit,solary_unit", [ (u.arcsec, u.arcsec), ('angle', 'angle')]) def test_args3(solarx_unit, solary_unit): @u.quantity_input def myfunc_args(solarx: solarx_unit, solary: solary_unit): return solarx, solary solarx, solary = myfunc_args(1*u.arcsec, 1*u.arcsec) assert isinstance(solarx, Quantity) assert isinstance(solary, Quantity) assert solarx.unit == u.arcsec assert solary.unit == u.arcsec @pytest.mark.parametrize("solarx_unit,solary_unit", [ (u.arcsec, u.arcsec), ('angle', 'angle')]) def test_args_noconvert3(solarx_unit, solary_unit): @u.quantity_input() def myfunc_args(solarx: solarx_unit, solary: solary_unit): return solarx, solary solarx, solary = myfunc_args(1*u.deg, 1*u.arcmin) assert isinstance(solarx, Quantity) assert isinstance(solary, Quantity) assert solarx.unit == u.deg assert solary.unit == u.arcmin @pytest.mark.parametrize("solarx_unit", [ u.arcsec, 'angle']) def test_args_nonquantity3(solarx_unit): @u.quantity_input def myfunc_args(solarx: solarx_unit, solary): return solarx, solary solarx, solary = myfunc_args(1*u.arcsec, 100) assert isinstance(solarx, Quantity) assert isinstance(solary, int) assert solarx.unit == u.arcsec @pytest.mark.parametrize("solarx_unit,solary_unit", [ (u.arcsec, u.eV), ('angle', 'energy')]) def test_arg_equivalencies3(solarx_unit, solary_unit): @u.quantity_input(equivalencies=u.mass_energy()) def myfunc_args(solarx: solarx_unit, solary: solary_unit): return solarx, solary+(10*u.J) # Add an energy to check equiv is working solarx, solary = myfunc_args(1*u.arcsec, 100*u.gram) assert isinstance(solarx, Quantity) assert isinstance(solary, Quantity) assert solarx.unit == u.arcsec assert solary.unit == u.gram @pytest.mark.parametrize("solarx_unit,solary_unit", [ (u.arcsec, u.deg), ('angle', 'angle')]) def test_wrong_unit3(solarx_unit, solary_unit): @u.quantity_input def myfunc_args(solarx: solarx_unit, solary: solary_unit): return solarx, solary with pytest.raises(u.UnitsError) as e: solarx, solary = myfunc_args(1*u.arcsec, 100*u.km) str_to = str(solary_unit) assert str(e.value) == f"Argument 'solary' to function 'myfunc_args' must be in units convertible to '{str_to}'." @pytest.mark.parametrize("solarx_unit,solary_unit", [ (u.arcsec, u.deg), ('angle', 'angle')]) def test_not_quantity3(solarx_unit, solary_unit): @u.quantity_input def myfunc_args(solarx: solarx_unit, solary: solary_unit): return solarx, solary with pytest.raises(TypeError) as e: solarx, solary = myfunc_args(1*u.arcsec, 100) assert str(e.value) == "Argument 'solary' to function 'myfunc_args' has no 'unit' attribute. You should pass in an astropy Quantity instead." def test_decorator_override(): @u.quantity_input(solarx=u.arcsec) def myfunc_args(solarx: u.km, solary: u.arcsec): return solarx, solary solarx, solary = myfunc_args(1*u.arcsec, 1*u.arcsec) assert isinstance(solarx, Quantity) assert isinstance(solary, Quantity) assert solarx.unit == u.arcsec assert solary.unit == u.arcsec @pytest.mark.parametrize("solarx_unit,solary_unit", [ (u.arcsec, u.deg), ('angle', 'angle')]) def test_kwargs3(solarx_unit, solary_unit): @u.quantity_input def myfunc_args(solarx: solarx_unit, solary, myk: solary_unit=1*u.arcsec): return solarx, solary, myk solarx, solary, myk = myfunc_args(1*u.arcsec, 100, myk=100*u.deg) assert isinstance(solarx, Quantity) assert isinstance(solary, int) assert isinstance(myk, Quantity) assert myk.unit == u.deg @pytest.mark.parametrize("solarx_unit,solary_unit", [ (u.arcsec, u.deg), ('angle', 'angle')]) def test_unused_kwargs3(solarx_unit, solary_unit): @u.quantity_input def myfunc_args(solarx: solarx_unit, solary, myk: solary_unit=1*u.arcsec, myk2=1000): return solarx, solary, myk, myk2 solarx, solary, myk, myk2 = myfunc_args(1*u.arcsec, 100, myk=100*u.deg, myk2=10) assert isinstance(solarx, Quantity) assert isinstance(solary, int) assert isinstance(myk, Quantity) assert isinstance(myk2, int) assert myk.unit == u.deg assert myk2 == 10 @pytest.mark.parametrize("solarx_unit,energy", [ (u.arcsec, u.eV), ('angle', 'energy')]) def test_kwarg_equivalencies3(solarx_unit, energy): @u.quantity_input(equivalencies=u.mass_energy()) def myfunc_args(solarx: solarx_unit, energy: energy=10*u.eV): return solarx, energy+(10*u.J) # Add an energy to check equiv is working solarx, energy = myfunc_args(1*u.arcsec, 100*u.gram) assert isinstance(solarx, Quantity) assert isinstance(energy, Quantity) assert solarx.unit == u.arcsec assert energy.unit == u.gram @pytest.mark.parametrize("solarx_unit,solary_unit", [ (u.arcsec, u.deg), ('angle', 'angle')]) def test_kwarg_wrong_unit3(solarx_unit, solary_unit): @u.quantity_input def myfunc_args(solarx: solarx_unit, solary: solary_unit=10*u.deg): return solarx, solary with pytest.raises(u.UnitsError) as e: solarx, solary = myfunc_args(1*u.arcsec, solary=100*u.km) str_to = str(solary_unit) assert str(e.value) == f"Argument 'solary' to function 'myfunc_args' must be in units convertible to '{str_to}'." @pytest.mark.parametrize("solarx_unit,solary_unit", [ (u.arcsec, u.deg), ('angle', 'angle')]) def test_kwarg_not_quantity3(solarx_unit, solary_unit): @u.quantity_input def myfunc_args(solarx: solarx_unit, solary: solary_unit=10*u.deg): return solarx, solary with pytest.raises(TypeError) as e: solarx, solary = myfunc_args(1*u.arcsec, solary=100) assert str(e.value) == "Argument 'solary' to function 'myfunc_args' has no 'unit' attribute. You should pass in an astropy Quantity instead." @pytest.mark.parametrize("solarx_unit,solary_unit", [ (u.arcsec, u.deg), ('angle', 'angle')]) def test_kwarg_default3(solarx_unit, solary_unit): @u.quantity_input def myfunc_args(solarx: solarx_unit, solary: solary_unit=10*u.deg): return solarx, solary solarx, solary = myfunc_args(1*u.arcsec) def test_return_annotation(): @u.quantity_input def myfunc_args(solarx: u.arcsec) -> u.deg: return solarx solarx = myfunc_args(1*u.arcsec) assert solarx.unit is u.deg def test_return_annotation_none(): @u.quantity_input def myfunc_args(solarx: u.arcsec) -> None: pass solarx = myfunc_args(1*u.arcsec) assert solarx is None def test_return_annotation_notUnit(): @u.quantity_input def myfunc_args(solarx: u.arcsec) -> int: return 0 solarx = myfunc_args(1*u.arcsec) assert solarx == 0 def test_enum_annotation(): # Regression test for gh-9932 from enum import Enum, auto class BasicEnum(Enum): AnOption = auto() @u.quantity_input def myfunc_args(a: BasicEnum, b: u.arcsec) -> None: pass myfunc_args(BasicEnum.AnOption, 1*u.arcsec) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/tests/test_quantity_array_methods.py0000644000175100001710000004543300000000000024473 0ustar00vstsdocker# The purpose of these tests are to ensure that calling quantities using # array methods returns quantities with the right units, or raises exceptions. import sys import pytest import numpy as np from numpy.testing import assert_array_equal from astropy import units as u from astropy.utils.compat import NUMPY_LT_1_21_1 class TestQuantityArrayCopy: """ Test whether arrays are properly copied/used in place """ def test_copy_on_creation(self): v = np.arange(1000.) q_nocopy = u.Quantity(v, "km/s", copy=False) q_copy = u.Quantity(v, "km/s", copy=True) v[0] = -1. assert q_nocopy[0].value == v[0] assert q_copy[0].value != v[0] def test_to_copies(self): q = u.Quantity(np.arange(1., 100.), "km/s") q2 = q.to(u.m/u.s) assert np.all(q.value != q2.value) q3 = q.to(u.km/u.s) assert np.all(q.value == q3.value) q[0] = -1.*u.km/u.s assert q[0].value != q3[0].value def test_si_copies(self): q = u.Quantity(np.arange(100.), "m/s") q2 = q.si assert np.all(q.value == q2.value) q[0] = -1.*u.m/u.s assert q[0].value != q2[0].value def test_getitem_is_view(self): """Check that [keys] work, and that, like ndarray, it returns a view, so that changing one changes the other. Also test that one can add axes (closes #1422) """ q = u.Quantity(np.arange(100.), "m/s") q_sel = q[10:20] q_sel[0] = -1.*u.m/u.s assert q_sel[0] == q[10] # also check that getitem can do new axes q2 = q[:, np.newaxis] q2[10, 0] = -9*u.m/u.s assert np.all(q2.flatten() == q) def test_flat(self): q = u.Quantity(np.arange(9.).reshape(3, 3), "m/s") q_flat = q.flat # check that a single item is a quantity (with the right value) assert q_flat[8] == 8. * u.m / u.s # and that getting a range works as well assert np.all(q_flat[0:2] == np.arange(2.) * u.m / u.s) # as well as getting items via iteration q_flat_list = [_q for _q in q.flat] assert np.all(u.Quantity(q_flat_list) == u.Quantity([_a for _a in q.value.flat], q.unit)) # check that flat works like a view of the real array q_flat[8] = -1. * u.km / u.s assert q_flat[8] == -1. * u.km / u.s assert q[2, 2] == -1. * u.km / u.s # while if one goes by an iterated item, a copy is made q_flat_list[8] = -2 * u.km / u.s assert q_flat_list[8] == -2. * u.km / u.s assert q_flat[8] == -1. * u.km / u.s assert q[2, 2] == -1. * u.km / u.s class TestQuantityReshapeFuncs: """Test different ndarray methods that alter the array shape tests: reshape, squeeze, ravel, flatten, transpose, swapaxes """ def test_reshape(self): q = np.arange(6.) * u.m q_reshape = q.reshape(3, 2) assert isinstance(q_reshape, u.Quantity) assert q_reshape.unit == q.unit assert np.all(q_reshape.value == q.value.reshape(3, 2)) def test_squeeze(self): q = np.arange(6.).reshape(6, 1) * u.m q_squeeze = q.squeeze() assert isinstance(q_squeeze, u.Quantity) assert q_squeeze.unit == q.unit assert np.all(q_squeeze.value == q.value.squeeze()) def test_ravel(self): q = np.arange(6.).reshape(3, 2) * u.m q_ravel = q.ravel() assert isinstance(q_ravel, u.Quantity) assert q_ravel.unit == q.unit assert np.all(q_ravel.value == q.value.ravel()) def test_flatten(self): q = np.arange(6.).reshape(3, 2) * u.m q_flatten = q.flatten() assert isinstance(q_flatten, u.Quantity) assert q_flatten.unit == q.unit assert np.all(q_flatten.value == q.value.flatten()) def test_transpose(self): q = np.arange(6.).reshape(3, 2) * u.m q_transpose = q.transpose() assert isinstance(q_transpose, u.Quantity) assert q_transpose.unit == q.unit assert np.all(q_transpose.value == q.value.transpose()) def test_swapaxes(self): q = np.arange(6.).reshape(3, 1, 2) * u.m q_swapaxes = q.swapaxes(0, 2) assert isinstance(q_swapaxes, u.Quantity) assert q_swapaxes.unit == q.unit assert np.all(q_swapaxes.value == q.value.swapaxes(0, 2)) @pytest.mark.xfail(sys.byteorder == 'big' and NUMPY_LT_1_21_1, reason="Numpy GitHub Issue 19153") def test_flat_attributes(self): """While ``flat`` doesn't make a copy, it changes the shape.""" q = np.arange(6.).reshape(3, 1, 2) * u.m qf = q.flat # flat shape is same as before reshaping assert len(qf) == 6 # see TestQuantityArrayCopy.test_flat for tests of iteration # and slicing and setting. Here we test the properties and methods to # match `numpy.ndarray.flatiter` assert qf.base is q # testing the indices -- flat and full -- into the array assert qf.coords == (0, 0, 0) # to start assert qf.index == 0 # now consume the iterator endindices = [(qf.index, qf.coords) for x in qf][-2] # next() oversteps assert endindices[0] == 5 assert endindices[1] == (2, 0, 1) # shape of q - 1 # also check q_flat copies properly q_flat_copy = qf.copy() assert all(q_flat_copy == q.flatten()) assert isinstance(q_flat_copy, u.Quantity) assert not np.may_share_memory(q_flat_copy, q) class TestQuantityStatsFuncs: """ Test statistical functions """ def test_mean(self): q1 = np.array([1., 2., 4., 5., 6.]) * u.m assert_array_equal(np.mean(q1), 3.6 * u.m) assert_array_equal(np.mean(q1, keepdims=True), [3.6] * u.m) def test_mean_inplace(self): q1 = np.array([1., 2., 4., 5., 6.]) * u.m qi = 1.5 * u.s qi2 = np.mean(q1, out=qi) assert qi2 is qi assert qi == 3.6 * u.m def test_std(self): q1 = np.array([1., 2.]) * u.m assert_array_equal(np.std(q1), 0.5 * u.m) assert_array_equal(q1.std(axis=-1, keepdims=True), [0.5] * u.m) def test_std_inplace(self): q1 = np.array([1., 2.]) * u.m qi = 1.5 * u.s np.std(q1, out=qi) assert qi == 0.5 * u.m def test_var(self): q1 = np.array([1., 2.]) * u.m assert_array_equal(np.var(q1), 0.25 * u.m ** 2) assert_array_equal(q1.var(axis=0, keepdims=True), [0.25] * u.m ** 2) def test_var_inplace(self): q1 = np.array([1., 2.]) * u.m qi = 1.5 * u.s np.var(q1, out=qi) assert qi == 0.25 * u.m ** 2 def test_median(self): q1 = np.array([1., 2., 4., 5., 6.]) * u.m assert np.median(q1) == 4. * u.m def test_median_inplace(self): q1 = np.array([1., 2., 4., 5., 6.]) * u.m qi = 1.5 * u.s np.median(q1, out=qi) assert qi == 4 * u.m def test_min(self): q1 = np.array([1., 2., 4., 5., 6.]) * u.m assert np.min(q1) == 1. * u.m def test_min_inplace(self): q1 = np.array([1., 2., 4., 5., 6.]) * u.m qi = 1.5 * u.s np.min(q1, out=qi) assert qi == 1. * u.m def test_argmin(self): q1 = np.array([6., 2., 4., 5., 6.]) * u.m assert np.argmin(q1) == 1 def test_max(self): q1 = np.array([1., 2., 4., 5., 6.]) * u.m assert np.max(q1) == 6. * u.m def test_max_inplace(self): q1 = np.array([1., 2., 4., 5., 6.]) * u.m qi = 1.5 * u.s np.max(q1, out=qi) assert qi == 6. * u.m def test_argmax(self): q1 = np.array([5., 2., 4., 5., 6.]) * u.m assert np.argmax(q1) == 4 def test_clip(self): q1 = np.array([1., 2., 4., 5., 6.]) * u.km / u.m c1 = q1.clip(1500, 5.5 * u.Mm / u.km) assert np.all(c1 == np.array([1.5, 2., 4., 5., 5.5]) * u.km / u.m) def test_clip_inplace(self): q1 = np.array([1., 2., 4., 5., 6.]) * u.km / u.m c1 = q1.clip(1500, 5.5 * u.Mm / u.km, out=q1) assert np.all(q1 == np.array([1.5, 2., 4., 5., 5.5]) * u.km / u.m) c1[0] = 10 * u.Mm/u.mm assert np.all(c1.value == q1.value) def test_conj(self): q1 = np.array([1., 2., 4., 5., 6.]) * u.km / u.m assert np.all(q1.conj() == q1) def test_ptp(self): q1 = np.array([1., 2., 4., 5., 6.]) * u.m assert np.ptp(q1) == 5. * u.m def test_ptp_inplace(self): q1 = np.array([1., 2., 4., 5., 6.]) * u.m qi = 1.5 * u.s np.ptp(q1, out=qi) assert qi == 5. * u.m def test_round(self): q1 = np.array([1.253, 2.253, 3.253]) * u.kg assert np.all(np.round(q1) == np.array([1, 2, 3]) * u.kg) assert np.all(np.round(q1, decimals=2) == np.round(q1.value, decimals=2) * u.kg) assert np.all(q1.round(decimals=2) == q1.value.round(decimals=2) * u.kg) def test_round_inplace(self): q1 = np.array([1.253, 2.253, 3.253]) * u.kg qi = np.zeros(3) * u.s a = q1.round(decimals=2, out=qi) assert a is qi assert np.all(q1.round(decimals=2) == qi) def test_sum(self): q1 = np.array([1., 2., 6.]) * u.m assert np.all(q1.sum() == 9. * u.m) assert np.all(np.sum(q1) == 9. * u.m) q2 = np.array([[4., 5., 9.], [1., 1., 1.]]) * u.s assert np.all(q2.sum(0) == np.array([5., 6., 10.]) * u.s) assert np.all(np.sum(q2, 0) == np.array([5., 6., 10.]) * u.s) def test_sum_inplace(self): q1 = np.array([1., 2., 6.]) * u.m qi = 1.5 * u.s np.sum(q1, out=qi) assert qi == 9. * u.m def test_cumsum(self): q1 = np.array([1, 2, 6]) * u.m assert np.all(q1.cumsum() == np.array([1, 3, 9]) * u.m) assert np.all(np.cumsum(q1) == np.array([1, 3, 9]) * u.m) q2 = np.array([4, 5, 9]) * u.s assert np.all(q2.cumsum() == np.array([4, 9, 18]) * u.s) assert np.all(np.cumsum(q2) == np.array([4, 9, 18]) * u.s) def test_cumsum_inplace(self): q1 = np.array([1, 2, 6]) * u.m qi = np.ones(3) * u.s np.cumsum(q1, out=qi) assert np.all(qi == np.array([1, 3, 9]) * u.m) q2 = q1 q1.cumsum(out=q1) assert np.all(q2 == qi) def test_nansum(self): q1 = np.array([1., 2., np.nan]) * u.m assert np.all(q1.nansum() == 3. * u.m) assert np.all(np.nansum(q1) == 3. * u.m) q2 = np.array([[np.nan, 5., 9.], [1., np.nan, 1.]]) * u.s assert np.all(q2.nansum(0) == np.array([1., 5., 10.]) * u.s) assert np.all(np.nansum(q2, 0) == np.array([1., 5., 10.]) * u.s) def test_nansum_inplace(self): q1 = np.array([1., 2., np.nan]) * u.m qi = 1.5 * u.s qout = q1.nansum(out=qi) assert qout is qi assert qi == np.nansum(q1.value) * q1.unit qi2 = 1.5 * u.s qout2 = np.nansum(q1, out=qi2) assert qout2 is qi2 assert qi2 == np.nansum(q1.value) * q1.unit def test_prod(self): q1 = np.array([1, 2, 6]) * u.m with pytest.raises(u.UnitsError) as exc: q1.prod() with pytest.raises(u.UnitsError) as exc: np.prod(q1) q2 = np.array([3., 4., 5.]) * u.Unit(1) assert q2.prod() == 60. * u.Unit(1) assert np.prod(q2) == 60. * u.Unit(1) def test_cumprod(self): q1 = np.array([1, 2, 6]) * u.m with pytest.raises(u.UnitsError) as exc: q1.cumprod() with pytest.raises(u.UnitsError) as exc: np.cumprod(q1) q2 = np.array([3, 4, 5]) * u.Unit(1) assert np.all(q2.cumprod() == np.array([3, 12, 60]) * u.Unit(1)) assert np.all(np.cumprod(q2) == np.array([3, 12, 60]) * u.Unit(1)) def test_diff(self): q1 = np.array([1., 2., 4., 10.]) * u.m assert np.all(q1.diff() == np.array([1., 2., 6.]) * u.m) assert np.all(np.diff(q1) == np.array([1., 2., 6.]) * u.m) def test_ediff1d(self): q1 = np.array([1., 2., 4., 10.]) * u.m assert np.all(q1.ediff1d() == np.array([1., 2., 6.]) * u.m) assert np.all(np.ediff1d(q1) == np.array([1., 2., 6.]) * u.m) def test_dot_meth(self): q1 = np.array([1., 2., 4., 10.]) * u.m q2 = np.array([3., 4., 5., 6.]) * u.s q3 = q1.dot(q2) assert q3.value == np.dot(q1.value, q2.value) assert q3.unit == u.m * u.s def test_trace_func(self): q = np.array([[1., 2.], [3., 4.]]) * u.m assert np.trace(q) == 5. * u.m def test_trace_meth(self): q1 = np.array([[1., 2.], [3., 4.]]) * u.m assert q1.trace() == 5. * u.m cont = u.Quantity(4., u.s) q2 = np.array([[3., 4.], [5., 6.]]) * u.m q2.trace(out=cont) assert cont == 9. * u.m def test_clip_func(self): q = np.arange(10) * u.m assert np.all(np.clip(q, 3 * u.m, 6 * u.m) == np.array([3., 3., 3., 3., 4., 5., 6., 6., 6., 6.]) * u.m) def test_clip_meth(self): expected = np.array([3., 3., 3., 3., 4., 5., 6., 6., 6., 6.]) * u.m q1 = np.arange(10) * u.m q3 = q1.clip(3 * u.m, 6 * u.m) assert np.all(q1.clip(3 * u.m, 6 * u.m) == expected) cont = np.zeros(10) * u.s q1.clip(3 * u.m, 6 * u.m, out=cont) assert np.all(cont == expected) class TestArrayConversion: """ Test array conversion methods """ def test_item(self): q1 = u.Quantity(np.array([1, 2, 3]), u.m / u.km, dtype=int) assert q1.item(1) == 2 * q1.unit q1.itemset(1, 1) assert q1.item(1) == 1000 * u.m / u.km q1.itemset(1, 100 * u.cm / u.km) assert q1.item(1) == 1 * u.m / u.km with pytest.raises(TypeError): q1.itemset(1, 1.5 * u.m / u.km) with pytest.raises(ValueError): q1.itemset() q1[1] = 1 assert q1[1] == 1000 * u.m / u.km q1[1] = 100 * u.cm / u.km assert q1[1] == 1 * u.m / u.km with pytest.raises(TypeError): q1[1] = 1.5 * u.m / u.km def test_take_put(self): q1 = np.array([1, 2, 3]) * u.m / u.km assert q1.take(1) == 2 * u.m / u.km assert all(q1.take((0, 2)) == np.array([1, 3]) * u.m / u.km) q1.put((1, 2), (3, 4)) assert np.all(q1.take((1, 2)) == np.array([3000, 4000]) * q1.unit) q1.put(0, 500 * u.cm / u.km) assert q1.item(0) == 5 * u.m / u.km def test_slice(self): """Test that setitem changes the unit if needed (or ignores it for values where that is allowed; viz., #2695)""" q2 = np.array([[1., 2., 3.], [4., 5., 6.]]) * u.km / u.m q1 = q2.copy() q2[0, 0] = 10000. assert q2.unit == q1.unit assert q2[0, 0].value == 10. q2[0] = 9. * u.Mm / u.km assert all(q2.flatten()[:3].value == np.array([9., 9., 9.])) q2[0, :-1] = 8000. assert all(q2.flatten()[:3].value == np.array([8., 8., 9.])) with pytest.raises(u.UnitsError): q2[1, 1] = 10 * u.s # just to be sure, repeat with a dimensionfull unit q3 = u.Quantity(np.arange(10.), "m/s") q3[5] = 100. * u.cm / u.s assert q3[5].value == 1. # and check unit is ignored for 0, inf, nan, where that is reasonable q3[5] = 0. assert q3[5] == 0. q3[5] = np.inf assert np.isinf(q3[5]) q3[5] = np.nan assert np.isnan(q3[5]) def test_fill(self): q1 = np.array([1, 2, 3]) * u.m / u.km q1.fill(2) assert np.all(q1 == 2000 * u.m / u.km) def test_repeat_compress_diagonal(self): q1 = np.array([1, 2, 3]) * u.m / u.km q2 = q1.repeat(2) assert q2.unit == q1.unit assert all(q2.value == q1.value.repeat(2)) q2.sort() assert q2.unit == q1.unit q2 = q1.compress(np.array([True, True, False, False])) assert q2.unit == q1.unit assert all(q2.value == q1.value.compress(np.array([True, True, False, False]))) q1 = np.array([[1, 2], [3, 4]]) * u.m / u.km q2 = q1.diagonal() assert q2.unit == q1.unit assert all(q2.value == q1.value.diagonal()) def test_view(self): q1 = np.array([1, 2, 3], dtype=np.int64) * u.m / u.km q2 = q1.view(np.ndarray) assert not hasattr(q2, 'unit') q3 = q2.view(u.Quantity) assert q3._unit is None # MaskedArray copies and properties assigned in __dict__ q4 = np.ma.MaskedArray(q1) assert q4._unit is q1._unit q5 = q4.view(u.Quantity) assert q5.unit is q1.unit def test_slice_to_quantity(self): """ Regression test for https://github.com/astropy/astropy/issues/2003 """ a = np.random.uniform(size=(10, 8)) x, y, z = a[:, 1:4].T * u.km/u.s total = np.sum(a[:, 1] * u.km / u.s - x) assert isinstance(total, u.Quantity) assert total == (0.0 * u.km / u.s) def test_byte_type_view_field_changes(self): q1 = np.array([1, 2, 3], dtype=np.int64) * u.m / u.km q2 = q1.byteswap() assert q2.unit == q1.unit assert all(q2.value == q1.value.byteswap()) q2 = q1.astype(np.float64) assert all(q2 == q1) assert q2.dtype == np.float64 q2a = q1.getfield(np.int32, offset=0) q2b = q1.byteswap().getfield(np.int32, offset=4) assert q2a.unit == q1.unit assert all(q2b.byteswap() == q2a) def test_sort(self): q1 = np.array([1., 5., 2., 4.]) * u.km / u.m i = q1.argsort() assert not hasattr(i, 'unit') q1.sort() i = q1.searchsorted([1500, 2500]) assert not hasattr(i, 'unit') assert all(i == q1.to( u.dimensionless_unscaled).value.searchsorted([1500, 2500])) def test_not_implemented(self): q1 = np.array([1, 2, 3]) * u.m / u.km with pytest.raises(NotImplementedError): q1.choose([0, 0, 1]) with pytest.raises(NotImplementedError): q1.tolist() with pytest.raises(NotImplementedError): q1.tostring() with pytest.raises(NotImplementedError): q1.tobytes() with pytest.raises(NotImplementedError): q1.tofile(0) with pytest.raises(NotImplementedError): q1.dump('a.a') with pytest.raises(NotImplementedError): q1.dumps() class TestRecArray: """Record arrays are not specifically supported, but we should not prevent their use unnecessarily""" def setup(self): self.ra = (np.array(np.arange(12.).reshape(4, 3)) .view(dtype=('f8,f8,f8')).squeeze()) def test_creation(self): qra = u.Quantity(self.ra, u.m) assert np.all(qra[:2].value == self.ra[:2]) def test_equality(self): qra = u.Quantity(self.ra, u.m) qra[1] = qra[2] assert qra[1] == qra[2] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/tests/test_quantity_decorator.py0000644000175100001710000003052200000000000023605 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst # STDLIB import sys import typing # THIRD PARTY import pytest import numpy as np # LOCAL from astropy import units as u from astropy.units._typing import HAS_ANNOTATED # list of pairs (target unit/physical type, input unit) x_inputs = [(u.arcsec, u.deg), ('angle', u.deg), (u.kpc/u.Myr, u.km/u.s), ('speed', u.km/u.s), ([u.arcsec, u.km], u.deg), ([u.arcsec, u.km], u.km), # multiple allowed (['angle', 'length'], u.deg), (['angle', 'length'], u.km)] y_inputs = [(u.m, u.km), (u.km, u.m), (u.arcsec, u.deg), ('angle', u.deg), (u.kpc/u.Myr, u.km/u.s), ('speed', u.km/u.s)] @pytest.fixture(scope="module", params=list(range(len(x_inputs)))) def x_input(request): return x_inputs[request.param] @pytest.fixture(scope="module", params=list(range(len(y_inputs)))) def y_input(request): return y_inputs[request.param] # ---- Tests that use the fixtures defined above ---- def test_args(x_input, y_input): x_target, x_unit = x_input y_target, y_unit = y_input @u.quantity_input(x=x_target, y=y_target) def myfunc_args(x, y): return x, y x, y = myfunc_args(1*x_unit, 1*y_unit) assert isinstance(x, u.Quantity) assert isinstance(y, u.Quantity) assert x.unit == x_unit assert y.unit == y_unit def test_args_nonquantity(x_input): x_target, x_unit = x_input @u.quantity_input(x=x_target) def myfunc_args(x, y): return x, y x, y = myfunc_args(1*x_unit, 100) assert isinstance(x, u.Quantity) assert isinstance(y, int) assert x.unit == x_unit def test_wrong_unit(x_input, y_input): x_target, x_unit = x_input y_target, y_unit = y_input @u.quantity_input(x=x_target, y=y_target) def myfunc_args(x, y): return x, y with pytest.raises(u.UnitsError) as e: x, y = myfunc_args(1*x_unit, 100*u.Joule) # has to be an unspecified unit str_to = str(y_target) assert str(e.value) == f"Argument 'y' to function 'myfunc_args' must be in units convertible to '{str_to}'." def test_wrong_unit_annotated(x_input, y_input): x_target, x_unit = x_input y_target, y_unit = y_input @u.quantity_input def myfunc_args(x: x_target, y: y_target): return x, y with pytest.raises(u.UnitsError, match="Argument 'y' to function 'myfunc_args'"): x, y = myfunc_args(1*x_unit, 100*u.Joule) # has to be an unspecified unit def test_not_quantity(x_input, y_input): x_target, x_unit = x_input y_target, y_unit = y_input @u.quantity_input(x=x_target, y=y_target) def myfunc_args(x, y): return x, y with pytest.raises(TypeError) as e: x, y = myfunc_args(1*x_unit, 100) assert str(e.value) == "Argument 'y' to function 'myfunc_args' has no 'unit' attribute. You should pass in an astropy Quantity instead." def test_not_quantity_annotated(x_input, y_input): x_target, x_unit = x_input y_target, y_unit = y_input @u.quantity_input def myfunc_args(x: x_target, y: y_target): return x, y with pytest.raises(TypeError) as e: x, y = myfunc_args(1*x_unit, 100) assert str(e.value) == "Argument 'y' to function 'myfunc_args' has no 'unit' attribute. You should pass in an astropy Quantity instead." def test_kwargs(x_input, y_input): x_target, x_unit = x_input y_target, y_unit = y_input @u.quantity_input(x=x_target, y=y_target) def myfunc_args(x, my_arg, y=1*y_unit): return x, my_arg, y x, my_arg, y = myfunc_args(1*x_unit, 100, y=100*y_unit) assert isinstance(x, u.Quantity) assert isinstance(my_arg, int) assert isinstance(y, u.Quantity) assert y.unit == y_unit def test_unused_kwargs(x_input, y_input): x_target, x_unit = x_input y_target, y_unit = y_input @u.quantity_input(x=x_target, y=y_target) def myfunc_args(x, my_arg1, y=y_unit, my_arg2=1000): return x, my_arg1, y, my_arg2 x, my_arg1, y, my_arg2 = myfunc_args(1*x_unit, 100, y=100*y_unit, my_arg2=10) assert isinstance(x, u.Quantity) assert isinstance(my_arg1, int) assert isinstance(y, u.Quantity) assert isinstance(my_arg2, int) assert y.unit == y_unit assert my_arg2 == 10 def test_kwarg_wrong_unit(x_input, y_input): x_target, x_unit = x_input y_target, y_unit = y_input @u.quantity_input(x=x_target, y=y_target) def myfunc_args(x, y=10*y_unit): return x, y with pytest.raises(u.UnitsError) as e: x, y = myfunc_args(1*x_unit, y=100*u.Joule) str_to = str(y_target) assert str(e.value) == f"Argument 'y' to function 'myfunc_args' must be in units convertible to '{str_to}'." def test_kwarg_not_quantity(x_input, y_input): x_target, x_unit = x_input y_target, y_unit = y_input @u.quantity_input(x=x_target, y=y_target) def myfunc_args(x, y=10*y_unit): return x, y with pytest.raises(TypeError) as e: x, y = myfunc_args(1*x_unit, y=100) assert str(e.value) == "Argument 'y' to function 'myfunc_args' has no 'unit' attribute. You should pass in an astropy Quantity instead." def test_kwarg_default(x_input, y_input): x_target, x_unit = x_input y_target, y_unit = y_input @u.quantity_input(x=x_target, y=y_target) def myfunc_args(x, y=10*y_unit): return x, y x, y = myfunc_args(1*x_unit) assert isinstance(x, u.Quantity) assert isinstance(y, u.Quantity) assert x.unit == x_unit assert y.unit == y_unit def test_kwargs_input(x_input, y_input): x_target, x_unit = x_input y_target, y_unit = y_input @u.quantity_input(x=x_target, y=y_target) def myfunc_args(x=1*x_unit, y=1*y_unit): return x, y kwargs = {'x': 10*x_unit, 'y': 10*y_unit} x, y = myfunc_args(**kwargs) assert isinstance(x, u.Quantity) assert isinstance(y, u.Quantity) assert x.unit == x_unit assert y.unit == y_unit def test_kwargs_extra(x_input): x_target, x_unit = x_input @u.quantity_input(x=x_target) def myfunc_args(x, **kwargs): return x x = myfunc_args(1*x_unit) assert isinstance(x, u.Quantity) assert x.unit == x_unit # ---- Tests that don't used the fixtures ---- @pytest.mark.parametrize("x_unit,y_unit", [ (u.arcsec, u.eV), ('angle', 'energy')]) def test_arg_equivalencies(x_unit, y_unit): @u.quantity_input(x=x_unit, y=y_unit, equivalencies=u.mass_energy()) def myfunc_args(x, y): return x, y+(10*u.J) # Add an energy to check equiv is working x, y = myfunc_args(1*u.arcsec, 100*u.gram) assert isinstance(x, u.Quantity) assert isinstance(y, u.Quantity) assert x.unit == u.arcsec assert y.unit == u.gram @pytest.mark.parametrize("x_unit,energy_unit", [ (u.arcsec, u.eV), ('angle', 'energy')]) def test_kwarg_equivalencies(x_unit, energy_unit): @u.quantity_input(x=x_unit, energy=energy_unit, equivalencies=u.mass_energy()) def myfunc_args(x, energy=10*u.eV): return x, energy+(10*u.J) # Add an energy to check equiv is working x, energy = myfunc_args(1*u.arcsec, 100*u.gram) assert isinstance(x, u.Quantity) assert isinstance(energy, u.Quantity) assert x.unit == u.arcsec assert energy.unit == u.gram def test_no_equivalent(): class test_unit: pass class test_quantity: unit = test_unit() @u.quantity_input(x=u.arcsec) def myfunc_args(x): return x with pytest.raises(TypeError) as e: x, y = myfunc_args(test_quantity()) assert str(e.value) == "Argument 'x' to function 'myfunc_args' has a 'unit' attribute without an 'is_equivalent' method. You should pass in an astropy Quantity instead." def test_kwarg_invalid_physical_type(): @u.quantity_input(x='angle', y='africanswallow') def myfunc_args(x, y=10*u.deg): return x, y with pytest.raises(ValueError) as e: x, y = myfunc_args(1*u.arcsec, y=100*u.deg) assert str(e.value) == "Invalid unit or physical type 'africanswallow'." def test_default_value_check(): x_target = u.deg x_unit = u.arcsec with pytest.raises(TypeError): @u.quantity_input(x=x_target) def myfunc_args(x=1.): return x x = myfunc_args() x = myfunc_args(1*x_unit) assert isinstance(x, u.Quantity) assert x.unit == x_unit def test_str_unit_typo(): @u.quantity_input def myfunc_args(x: "kilograam"): return x with pytest.raises(ValueError): result = myfunc_args(u.kg) @pytest.mark.skipif(not HAS_ANNOTATED, reason="need `Annotated`") class TestTypeAnnotations: @pytest.mark.parametrize("annot", [u.m, u.Quantity[u.m], u.Quantity[u.m, "more"]] if HAS_ANNOTATED else [None]) # Note: parametrization is done even if test class is skipped def test_single_annotation_unit(self, annot): """Try a variety of valid annotations.""" @u.quantity_input def myfunc_args(x: annot, y: str): return x, y i_q, i_str = 2 * u.m, "cool string" o_q, o_str = myfunc_args(i_q, i_str) assert o_q == i_q assert o_str == i_str def test_args_None(): x_target = u.deg x_unit = u.arcsec y_target = u.km y_unit = u.kpc @u.quantity_input(x=[x_target, None], y=[None, y_target]) def myfunc_args(x, y): return x, y x, y = myfunc_args(1*x_unit, None) assert isinstance(x, u.Quantity) assert x.unit == x_unit assert y is None x, y = myfunc_args(None, 1*y_unit) assert isinstance(y, u.Quantity) assert y.unit == y_unit assert x is None def test_args_None_kwarg(): x_target = u.deg x_unit = u.arcsec y_target = u.km @u.quantity_input(x=x_target, y=y_target) def myfunc_args(x, y=None): return x, y x, y = myfunc_args(1*x_unit) assert isinstance(x, u.Quantity) assert x.unit == x_unit assert y is None x, y = myfunc_args(1*x_unit, None) assert isinstance(x, u.Quantity) assert x.unit == x_unit assert y is None with pytest.raises(TypeError): x, y = myfunc_args(None, None) @pytest.mark.parametrize('val', [1., 1, np.arange(10), np.arange(10.)]) def test_allow_dimensionless_numeric(val): """ When dimensionless_unscaled is an allowed unit, numbers and numeric numpy arrays are allowed through """ @u.quantity_input(velocity=[u.km/u.s, u.dimensionless_unscaled]) def myfunc(velocity): return velocity assert np.all(myfunc(val) == val) @pytest.mark.parametrize('val', [1., 1, np.arange(10), np.arange(10.)]) def test_allow_dimensionless_numeric_strict(val): """ When dimensionless_unscaled is an allowed unit, but we are being strict, don't allow numbers and numeric numpy arrays through """ @u.quantity_input(velocity=[u.km/u.s, u.dimensionless_unscaled], strict_dimensionless=True) def myfunc(velocity): return velocity with pytest.raises(TypeError): assert myfunc(val) @pytest.mark.parametrize('val', [1*u.deg, [1, 2, 3]*u.m]) def test_dimensionless_with_nondimensionless_input(val): """ When dimensionless_unscaled is the only allowed unit, don't let input with non-dimensionless units through """ @u.quantity_input(x=u.dimensionless_unscaled) def myfunc(x): return x with pytest.raises(u.UnitsError): myfunc(val) @pytest.mark.skipif(sys.version_info < (3, 9), reason="requires py3.9+") def test_annotated_not_quantity(): """Test when annotation looks like a Quantity[X], but isn't.""" @u.quantity_input() def myfunc(x: typing.Annotated[object, u.m]): return x # nothing happens when wrong unit is passed assert myfunc(1) == 1 assert myfunc(1 * u.m) == 1 * u.m assert myfunc(1 * u.s) == 1 * u.s @pytest.mark.skipif(sys.version_info < (3, 9), reason="requires py3.9+") def test_annotated_not_unit(): """Test when annotation looks like a Quantity[X], but the unit's wrong.""" @u.quantity_input() def myfunc(x: typing.Annotated[u.Quantity, object()]): return x # nothing happens when wrong unit is passed assert myfunc(1) == 1 assert myfunc(1 * u.m) == 1 * u.m assert myfunc(1 * u.s) == 1 * u.s ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/tests/test_quantity_helpers.py0000644000175100001710000000127400000000000023267 0ustar00vstsdocker""" Test ``allclose`` and ``isclose``. ``allclose`` was ``quantity_allclose`` in ``astropy.tests.helper``. """ import numpy as np import pytest from astropy import units as u @pytest.mark.parametrize( ('a', 'b'), [([1, 2], [1, 2]), ([1, 2] * u.m, [100, 200] * u.cm), (1 * u.s, 1000 * u.ms)]) def test_allclose_isclose_default(a, b): assert u.allclose(a, b) assert np.all(u.isclose(a, b)) def test_allclose_isclose(): a = [1, 2] * u.m b = [101, 201] * u.cm delta = 2 * u.cm assert u.allclose(a, b, atol=delta) assert np.all(u.isclose(a, b, atol=delta)) c = [90, 200] * u.cm assert not u.allclose(a, c) assert not np.all(u.isclose(a, c)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/tests/test_quantity_non_ufuncs.py0000644000175100001710000021152300000000000024002 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import itertools import inspect import numpy as np from numpy.testing import assert_array_equal import pytest from astropy import units as u from astropy.units.quantity_helper.function_helpers import ( ARRAY_FUNCTION_ENABLED, SUBCLASS_SAFE_FUNCTIONS, UNSUPPORTED_FUNCTIONS, FUNCTION_HELPERS, DISPATCHED_FUNCTIONS, IGNORED_FUNCTIONS) from astropy.utils.compat import NUMPY_LT_1_20, NUMPY_LT_1_23 needs_array_function = pytest.mark.xfail( not ARRAY_FUNCTION_ENABLED, reason="Needs __array_function__ support") # To get the functions that could be covered, we look for those that # are wrapped. Of course, this does not give a full list pre-1.17. def get_wrapped_functions(*modules): wrapped_functions = {} for mod in modules: for name, f in mod.__dict__.items(): if f is np.printoptions: continue if callable(f) and hasattr(f, '__wrapped__'): wrapped_functions[name] = f return wrapped_functions all_wrapped_functions = get_wrapped_functions(np, np.fft, np.linalg) all_wrapped = set(all_wrapped_functions.values()) class CoverageMeta(type): """Meta class that tracks which functions are covered by tests. Assumes that a test is called 'test_'. """ covered = set() def __new__(mcls, name, bases, members): for k, v in members.items(): if inspect.isfunction(v) and k.startswith('test'): f = k.replace('test_', '') if f in all_wrapped_functions: mcls.covered.add(all_wrapped_functions[f]) return super().__new__(mcls, name, bases, members) class BasicTestSetup(metaclass=CoverageMeta): """Test setup for functions that should not change the unit. Also provides a default Quantity with shape (3, 3) and units of m. """ def setup(self): self.q = np.arange(9.).reshape(3, 3) / 4. * u.m class InvariantUnitTestSetup(BasicTestSetup): def check(self, func, *args, **kwargs): o = func(self.q, *args, **kwargs) expected = func(self.q.value, *args, **kwargs) * self.q.unit assert o.shape == expected.shape assert np.all(o == expected) class NoUnitTestSetup(BasicTestSetup): def check(self, func, *args, **kwargs): out = func(self.q, *args, **kwargs) expected = func(self.q.value, *args, *kwargs) assert type(out) is type(expected) if isinstance(expected, tuple): assert all(np.all(o == x) for o, x in zip(out, expected)) else: assert np.all(out == expected) class TestShapeInformation(BasicTestSetup): def test_shape(self): assert np.shape(self.q) == (3, 3) def test_size(self): assert np.size(self.q) == 9 def test_ndim(self): assert np.ndim(self.q) == 2 class TestShapeManipulation(InvariantUnitTestSetup): # Note: do not parametrize the below, since test names are used # to check coverage. def test_reshape(self): self.check(np.reshape, (9, 1)) def test_ravel(self): self.check(np.ravel) def test_moveaxis(self): self.check(np.moveaxis, 0, 1) def test_rollaxis(self): self.check(np.rollaxis, 0, 2) def test_swapaxes(self): self.check(np.swapaxes, 0, 1) def test_transpose(self): self.check(np.transpose) def test_atleast_1d(self): q = 1. * u.m o, so = np.atleast_1d(q, self.q) assert o.shape == (1,) assert o == q expected = np.atleast_1d(self.q.value) * u.m assert np.all(so == expected) def test_atleast_2d(self): q = 1. * u.m o, so = np.atleast_2d(q, self.q) assert o.shape == (1, 1) assert o == q expected = np.atleast_2d(self.q.value) * u.m assert np.all(so == expected) def test_atleast_3d(self): q = 1. * u.m o, so = np.atleast_3d(q, self.q) assert o.shape == (1, 1, 1) assert o == q expected = np.atleast_3d(self.q.value) * u.m assert np.all(so == expected) def test_expand_dims(self): self.check(np.expand_dims, 1) def test_squeeze(self): o = np.squeeze(self.q[:, np.newaxis, :]) assert o.shape == (3, 3) assert np.all(o == self.q) def test_flip(self): self.check(np.flip) def test_fliplr(self): self.check(np.fliplr) def test_flipud(self): self.check(np.flipud) def test_rot90(self): self.check(np.rot90) def test_broadcast_to(self): # Decided *not* to change default for subok for Quantity, since # that would be contrary to the docstring and might break code. self.check(np.broadcast_to, (3, 3, 3), subok=True) out = np.broadcast_to(self.q, (3, 3, 3)) assert type(out) is np.ndarray # NOT Quantity def test_broadcast_arrays(self): # Decided *not* to change default for subok for Quantity, since # that would be contrary to the docstring and might break code. q2 = np.ones((3, 3, 3)) / u.s o1, o2 = np.broadcast_arrays(self.q, q2, subok=True) assert isinstance(o1, u.Quantity) assert isinstance(o2, u.Quantity) assert o1.shape == o2.shape == (3, 3, 3) assert np.all(o1 == self.q) assert np.all(o2 == q2) a1, a2 = np.broadcast_arrays(self.q, q2) assert type(a1) is np.ndarray assert type(a2) is np.ndarray class TestArgFunctions(NoUnitTestSetup): def test_argmin(self): self.check(np.argmin) def test_argmax(self): self.check(np.argmax) def test_argsort(self): self.check(np.argsort) def test_lexsort(self): self.check(np.lexsort) def test_searchsorted(self): q = self.q.ravel() q2 = np.array([150., 350.]) * u.cm out = np.searchsorted(q, q2) expected = np.searchsorted(q.value, q2.to_value(q.unit)) assert np.all(out == expected) def test_nonzero(self): self.check(np.nonzero) def test_argwhere(self): self.check(np.argwhere) @needs_array_function def test_argpartition(self): self.check(np.argpartition, 2) def test_flatnonzero(self): self.check(np.flatnonzero) class TestAlongAxis(BasicTestSetup): def test_take_along_axis(self): indices = np.expand_dims(np.argmax(self.q, axis=0), axis=0) out = np.take_along_axis(self.q, indices, axis=0) expected = np.take_along_axis(self.q.value, indices, axis=0) * self.q.unit assert np.all(out == expected) def test_put_along_axis(self): q = self.q.copy() indices = np.expand_dims(np.argmax(self.q, axis=0), axis=0) np.put_along_axis(q, indices, axis=0, values=-100 * u.cm) expected = q.value.copy() np.put_along_axis(expected, indices, axis=0, values=-1) expected = expected * q.unit assert np.all(q == expected) @pytest.mark.parametrize('axis', (0, 1)) def test_apply_along_axis(self, axis): out = np.apply_along_axis(np.square, axis, self.q) expected = np.apply_along_axis(np.square, axis, self.q.value) * self.q.unit ** 2 assert_array_equal(out, expected) @needs_array_function @pytest.mark.parametrize('axes', ((1,), (0,), (0, 1))) def test_apply_over_axes(self, axes): def function(x, axis): return np.sum(np.square(x), axis) out = np.apply_over_axes(function, self.q, axes) expected = np.apply_over_axes(function, self.q.value, axes) expected = expected * self.q.unit ** (2 * len(axes)) assert_array_equal(out, expected) class TestIndicesFrom(NoUnitTestSetup): def test_diag_indices_from(self): self.check(np.diag_indices_from) def test_triu_indices_from(self): self.check(np.triu_indices_from) def test_tril_indices_from(self): self.check(np.tril_indices_from) class TestRealImag(InvariantUnitTestSetup): def setup(self): self.q = (np.arange(9.).reshape(3, 3) + 1j) * u.m def test_real(self): self.check(np.real) def test_imag(self): self.check(np.imag) class TestCopyAndCreation(InvariantUnitTestSetup): @needs_array_function def test_copy(self): self.check(np.copy) # Also as kwarg copy = np.copy(a=self.q) assert_array_equal(copy, self.q) @needs_array_function def test_asfarray(self): self.check(np.asfarray) farray = np.asfarray(a=self.q) assert_array_equal(farray, self.q) def test_empty_like(self): o = np.empty_like(self.q) assert o.shape == (3, 3) assert isinstance(o, u.Quantity) assert o.unit == self.q.unit o2 = np.empty_like(prototype=self.q) assert o2.shape == (3, 3) assert isinstance(o2, u.Quantity) assert o2.unit == self.q.unit o3 = np.empty_like(self.q, subok=False) assert type(o3) is np.ndarray def test_zeros_like(self): self.check(np.zeros_like) o2 = np.zeros_like(a=self.q) assert_array_equal(o2, self.q * 0.) def test_ones_like(self): self.check(np.ones_like) @needs_array_function def test_full_like(self): o = np.full_like(self.q, 0.5 * u.km) expected = np.empty_like(self.q.value) * u.m expected[...] = 0.5 * u.km assert np.all(o == expected) with pytest.raises(u.UnitsError): np.full_like(self.q, 0.5 * u.s) class TestAccessingParts(InvariantUnitTestSetup): def test_diag(self): self.check(np.diag) @needs_array_function def test_diag_1d_input(self): # Also check 1-D case; drops unit w/o __array_function__. q = self.q.ravel() o = np.diag(q) expected = np.diag(q.value) << q.unit assert o.unit == self.q.unit assert o.shape == expected.shape assert_array_equal(o, expected) def test_diagonal(self): self.check(np.diagonal) def test_diagflat(self): self.check(np.diagflat) def test_compress(self): o = np.compress([True, False, True], self.q, axis=0) expected = np.compress([True, False, True], self.q.value, axis=0) * self.q.unit assert np.all(o == expected) def test_extract(self): o = np.extract([True, False, True], self.q) expected = np.extract([True, False, True], self.q.value) * self.q.unit assert np.all(o == expected) def test_delete(self): self.check(np.delete, slice(1, 2), 0) self.check(np.delete, [0, 2], 1) def test_trim_zeros(self): q = self.q.ravel() out = np.trim_zeros(q) expected = np.trim_zeros(q.value) * u.m assert np.all(out == expected) def test_roll(self): self.check(np.roll, 1) self.check(np.roll, 1, axis=0) def test_take(self): self.check(np.take, [0, 1], axis=1) self.check(np.take, 1) class TestSettingParts(metaclass=CoverageMeta): def test_put(self): q = np.arange(3.) * u.m np.put(q, [0, 2], [50, 150] * u.cm) assert q.unit == u.m expected = [50, 100, 150] * u.cm assert np.all(q == expected) @needs_array_function def test_putmask(self): q = np.arange(3.) * u.m mask = [True, False, True] values = [50, 0, 150] * u.cm np.putmask(q, mask, values) assert q.unit == u.m expected = [50, 100, 150] * u.cm assert np.all(q == expected) with pytest.raises(u.UnitsError): np.putmask(q, mask, values.value) with pytest.raises(u.UnitsError): np.putmask(q.value, mask, values) a = np.arange(3.) values = [50, 0, 150] * u.percent np.putmask(a, mask, values) expected = np.array([0.5, 1., 1.5]) assert np.all(a == expected) @needs_array_function def test_place(self): q = np.arange(3.) * u.m np.place(q, [True, False, True], [50, 150] * u.cm) assert q.unit == u.m expected = [50, 100, 150] * u.cm assert np.all(q == expected) a = np.arange(3.) np.place(a, [True, False, True], [50, 150] * u.percent) assert type(a) is np.ndarray expected = np.array([0.5, 1., 1.5]) assert np.all(a == expected) @needs_array_function def test_copyto(self): q = np.arange(3.) * u.m np.copyto(q, [50, 0, 150] * u.cm, where=[True, False, True]) assert q.unit == u.m expected = [50, 100, 150] * u.cm assert np.all(q == expected) a = np.arange(3.) np.copyto(a, [50, 0, 150] * u.percent, where=[True, False, True]) assert type(a) is np.ndarray expected = np.array([0.5, 1., 1.5]) assert np.all(a == expected) def test_fill_diagonal(self): q = np.arange(9.).reshape(3, 3) * u.m expected = q.value.copy() np.fill_diagonal(expected, 0.25) expected = expected * u.m np.fill_diagonal(q, 25. * u.cm) assert q.unit == u.m assert np.all(q == expected) class TestRepeat(InvariantUnitTestSetup): def test_tile(self): self.check(np.tile, 2) def test_repeat(self): self.check(np.repeat, 2) @needs_array_function def test_resize(self): self.check(np.resize, (4, 4)) class TestConcatenate(metaclass=CoverageMeta): def setup(self): self.q1 = np.arange(6.).reshape(2, 3) * u.m self.q2 = self.q1.to(u.cm) def check(self, func, *args, **kwargs): q_list = kwargs.pop('q_list', [self.q1, self.q2]) q_ref = kwargs.pop('q_ref', q_list[0]) o = func(q_list, *args, **kwargs) v_list = [q_ref._to_own_unit(q) for q in q_list] expected = func(v_list, *args, **kwargs) * q_ref.unit assert o.shape == expected.shape assert np.all(o == expected) @needs_array_function def test_concatenate(self): self.check(np.concatenate) self.check(np.concatenate, axis=1) self.check(np.concatenate, q_list=[np.zeros(self.q1.shape), self.q1, self.q2], q_ref=self.q1) out = np.empty((4, 3)) * u.dimensionless_unscaled result = np.concatenate([self.q1, self.q2], out=out) assert out is result assert out.unit == self.q1.unit expected = np.concatenate( [self.q1.value, self.q2.to_value(self.q1.unit)]) * self.q1.unit assert np.all(result == expected) with pytest.raises(TypeError): np.concatenate([self.q1, object()]) @needs_array_function def test_stack(self): self.check(np.stack) @needs_array_function def test_column_stack(self): self.check(np.column_stack) @needs_array_function def test_hstack(self): self.check(np.hstack) @needs_array_function def test_vstack(self): self.check(np.vstack) @needs_array_function def test_dstack(self): self.check(np.dstack) @needs_array_function def test_block(self): self.check(np.block) result = np.block([[0., 1.*u.m], [1.*u.cm, 2.*u.km]]) assert np.all(result == np.block([[0, 1.], [.01, 2000.]]) << u.m) @needs_array_function def test_append(self): out = np.append(self.q1, self.q2, axis=0) assert out.unit == self.q1.unit expected = np.append(self.q1.value, self.q2.to_value(self.q1.unit), axis=0) * self.q1.unit assert np.all(out == expected) a = np.arange(3.) result = np.append(a, 50. * u.percent) assert isinstance(result, u.Quantity) assert result.unit == u.dimensionless_unscaled expected = np.append(a, 0.5) * u.dimensionless_unscaled assert np.all(result == expected) @needs_array_function def test_insert(self): # Unit of inserted values is not ignored. q = np.arange(12.).reshape(6, 2) * u.m out = np.insert(q, (3, 5), [50., 25.] * u.cm) assert isinstance(out, u.Quantity) assert out.unit == q.unit expected = np.insert(q.value, (3, 5), [0.5, 0.25]) << q.unit assert np.all(out == expected) # 0 can have any unit. out2 = np.insert(q, (3, 5), 0) expected2 = np.insert(q.value, (3, 5), 0) << q.unit assert np.all(out2 == expected2) a = np.arange(3.) result = np.insert(a, (2,), 50. * u.percent) assert isinstance(result, u.Quantity) assert result.unit == u.dimensionless_unscaled expected = np.insert(a, (2,), 0.5) * u.dimensionless_unscaled assert np.all(result == expected) with pytest.raises(TypeError): np.insert(q, 3 * u.cm, 50. * u.cm) with pytest.raises(u.UnitsError): np.insert(q, (3, 5), 0. * u.s) @needs_array_function def test_pad(self): q = np.arange(1., 6.) * u.m out = np.pad(q, (2, 3), 'constant', constant_values=(0., 150.*u.cm)) assert out.unit == q.unit expected = np.pad(q.value, (2, 3), 'constant', constant_values=(0., 1.5)) * q.unit assert np.all(out == expected) out2 = np.pad(q, (2, 3), 'constant', constant_values=150.*u.cm) assert out2.unit == q.unit expected2 = np.pad(q.value, (2, 3), 'constant', constant_values=1.5) * q.unit assert np.all(out2 == expected2) out3 = np.pad(q, (2, 3), 'linear_ramp', end_values=(25.*u.cm, 0.)) assert out3.unit == q.unit expected3 = np.pad(q.value, (2, 3), 'linear_ramp', end_values=(0.25, 0.)) * q.unit assert np.all(out3 == expected3) class TestSplit(metaclass=CoverageMeta): def setup(self): self.q = np.arange(54.).reshape(3, 3, 6) * u.m def check(self, func, *args, **kwargs): out = func(self.q, *args, **kwargs) expected = func(self.q.value, *args, **kwargs) expected = [x * self.q.unit for x in expected] assert len(out) == len(expected) assert all(o.shape == x.shape for o, x in zip(out, expected)) assert all(np.all(o == x) for o, x in zip(out, expected)) def test_split(self): self.check(np.split, [1]) def test_array_split(self): self.check(np.array_split, 2) def test_hsplit(self): self.check(np.hsplit, [1, 4]) def test_vsplit(self): self.check(np.vsplit, [1]) def test_dsplit(self): self.check(np.dsplit, [1]) class TestUfuncReductions(InvariantUnitTestSetup): def test_amax(self): self.check(np.amax) def test_amin(self): self.check(np.amin) def test_sum(self): self.check(np.sum) def test_cumsum(self): self.check(np.cumsum) def test_any(self): with pytest.raises(TypeError): np.any(self.q) def test_all(self): with pytest.raises(TypeError): np.all(self.q) def test_sometrue(self): with pytest.raises(TypeError): np.sometrue(self.q) def test_alltrue(self): with pytest.raises(TypeError): np.alltrue(self.q) def test_prod(self): with pytest.raises(u.UnitsError): np.prod(self.q) def test_product(self): with pytest.raises(u.UnitsError): np.product(self.q) def test_cumprod(self): with pytest.raises(u.UnitsError): np.cumprod(self.q) def test_cumproduct(self): with pytest.raises(u.UnitsError): np.cumproduct(self.q) class TestUfuncLike(InvariantUnitTestSetup): def test_ptp(self): self.check(np.ptp) self.check(np.ptp, axis=0) def test_round_(self): self.check(np.round_) def test_around(self): self.check(np.around) def test_fix(self): self.check(np.fix) def test_angle(self): q = np.array([1+0j, 0+1j, 1+1j, 0+0j]) * u.m out = np.angle(q) expected = np.angle(q.value) * u.radian assert np.all(out == expected) def test_i0(self): q = np.array([0., 10., 20.]) * u.percent out = np.i0(q) expected = np.i0(q.to_value(u.one)) * u.one assert isinstance(out, u.Quantity) assert np.all(out == expected) with pytest.raises(u.UnitsError): np.i0(self.q) def test_clip(self): qmin = 200 * u.cm qmax = [270, 280, 290] * u.cm out = np.clip(self.q, qmin, qmax) expected = np.clip(self.q.value, qmin.to_value(self.q.unit), qmax.to_value(self.q.unit)) * self.q.unit assert np.all(out == expected) @needs_array_function def test_sinc(self): q = [0., 3690., -270., 690.] * u.deg out = np.sinc(q) expected = np.sinc(q.to_value(u.radian)) * u.one assert isinstance(out, u.Quantity) assert np.all(out == expected) with pytest.raises(u.UnitsError): np.sinc(1.*u.one) @needs_array_function def test_where(self): out = np.where([True, False, True], self.q, 1. * u.km) expected = np.where([True, False, True], self.q.value, 1000.) * self.q.unit assert np.all(out == expected) @needs_array_function def test_choose(self): # from np.choose docstring a = np.array([0, 1]).reshape((2, 1, 1)) q1 = np.array([1, 2, 3]).reshape((1, 3, 1)) * u.cm q2 = np.array([-1, -2, -3, -4, -5]).reshape((1, 1, 5)) * u.m out = np.choose(a, (q1, q2)) # result is 2x3x5, res[0,:,:]=c1, res[1,:,:]=c2 expected = np.choose(a, (q1.value, q2.to_value(q1.unit))) * u.cm assert np.all(out == expected) @needs_array_function def test_select(self): q = self.q out = np.select([q < 0.55 * u.m, q > 1. * u.m], [q, q.to(u.cm)], default=-1. * u.km) expected = np.select([q.value < 0.55, q.value > 1], [q.value, q.value], default=-1000) * u.m assert np.all(out == expected) @needs_array_function def test_real_if_close(self): q = np.array([1+0j, 0+1j, 1+1j, 0+0j]) * u.m out = np.real_if_close(q) expected = np.real_if_close(q.value) * u.m assert np.all(out == expected) @needs_array_function def test_tril(self): self.check(np.tril) @needs_array_function def test_triu(self): self.check(np.triu) @needs_array_function def test_unwrap(self): q = [0., 3690., -270., 690.] * u.deg out = np.unwrap(q) expected = (np.unwrap(q.to_value(u.rad)) * u.rad).to(q.unit) assert out.unit == expected.unit assert np.allclose(out, expected, atol=1*u.urad, rtol=0) with pytest.raises(u.UnitsError): np.unwrap([1., 2.]*u.m) with pytest.raises(u.UnitsError): np.unwrap(q, discont=1.*u.m) def test_nan_to_num(self): q = np.array([-np.inf, +np.inf, np.nan, 3., 4.]) * u.m out = np.nan_to_num(q) expected = np.nan_to_num(q.value) * q.unit assert np.all(out == expected) @needs_array_function def test_nan_to_num_complex(self): q = np.array([-np.inf, +np.inf, np.nan, 3., 4.]) * u.m out = np.nan_to_num(q, nan=1.*u.km, posinf=2.*u.km, neginf=-2*u.km) expected = [-2000., 2000., 1000., 3., 4.] * u.m assert np.all(out == expected) class TestUfuncLikeTests(metaclass=CoverageMeta): def setup(self): self.q = np.array([-np.inf, +np.inf, np.nan, 3., 4.]) * u.m def check(self, func): out = func(self.q) expected = func(self.q.value) assert type(out) is np.ndarray assert out.dtype.kind == 'b' assert np.all(out == expected) def test_isposinf(self): self.check(np.isposinf) def test_isneginf(self): self.check(np.isneginf) def test_isreal(self): self.check(np.isreal) assert not np.isreal([1. + 1j]*u.m) def test_iscomplex(self): self.check(np.iscomplex) assert np.iscomplex([1. + 1j]*u.m) def test_isclose(self): q1 = np.arange(3.) * u.m q2 = np.array([0., 102., 199.]) * u.cm atol = 1.5 * u.cm rtol = 1. * u.percent out = np.isclose(q1, q2, atol=atol) expected = np.isclose(q1.value, q2.to_value(q1.unit), atol=atol.to_value(q1.unit)) assert type(out) is np.ndarray assert out.dtype.kind == 'b' assert np.all(out == expected) out = np.isclose(q1, q2, atol=0, rtol=rtol) expected = np.isclose(q1.value, q2.to_value(q1.unit), atol=0, rtol=0.01) assert type(out) is np.ndarray assert out.dtype.kind == 'b' assert np.all(out == expected) @needs_array_function def test_allclose_atol_default_unit(self): q_cm = self.q.to(u.cm) out = np.isclose(self.q, q_cm) expected = np.isclose(self.q.value, q_cm.to_value(u.m)) assert np.all(out == expected) q1 = np.arange(3.) * u.m q2 = np.array([0., 101., 198.]) * u.cm out = np.isclose(q1, q2, atol=0.011, rtol=0) expected = np.isclose(q1.value, q2.to_value(q1.unit), atol=0.011, rtol=0) assert np.all(out == expected) out2 = np.isclose(q2, q1, atol=0.011, rtol=0) expected2 = np.isclose(q2.value, q1.to_value(q2.unit), atol=0.011, rtol=0) assert np.all(out2 == expected2) class TestReductionLikeFunctions(InvariantUnitTestSetup): def test_average(self): q1 = np.arange(9.).reshape(3, 3) * u.m q2 = np.eye(3) / u.s o = np.average(q1, weights=q2) expected = np.average(q1.value, weights=q2.value) * u.m assert np.all(o == expected) def test_mean(self): self.check(np.mean) def test_std(self): self.check(np.std) def test_var(self): o = np.var(self.q) expected = np.var(self.q.value) * self.q.unit ** 2 assert np.all(o == expected) def test_median(self): self.check(np.median) @needs_array_function def test_quantile(self): self.check(np.quantile, 0.5) o = np.quantile(self.q, 50 * u.percent) expected = np.quantile(self.q.value, 0.5) * u.m assert np.all(o == expected) # For ndarray input, we return a Quantity. o2 = np.quantile(self.q.value, 50 * u.percent) assert o2.unit == u.dimensionless_unscaled assert np.all(o2 == expected.value) o3 = 0 * o2 result = np.quantile(self.q, 50 * u.percent, out=o3) assert result is o3 assert np.all(o3 == expected) o4 = 0 * o2 result = np.quantile(self.q, 50 * u.percent, None, o4) assert result is o4 assert np.all(o4 == expected) @needs_array_function def test_percentile(self): self.check(np.percentile, 0.5) o = np.percentile(self.q, 0.5 * u.one) expected = np.percentile(self.q.value, 50) * u.m assert np.all(o == expected) def test_trace(self): self.check(np.trace) @needs_array_function def test_count_nonzero(self): q1 = np.arange(9.).reshape(3, 3) * u.m o = np.count_nonzero(q1) assert type(o) is not u.Quantity assert o == 8 o = np.count_nonzero(q1, axis=1) # Returns integer Quantity with units of m assert type(o) is np.ndarray assert np.all(o == np.array([2, 3, 3])) def test_allclose(self): q1 = np.arange(3.) * u.m q2 = np.array([0., 101., 199.]) * u.cm atol = 2 * u.cm rtol = 1. * u.percent assert np.allclose(q1, q2, atol=atol) assert np.allclose(q1, q2, atol=0., rtol=rtol) @needs_array_function def test_allclose_atol_default_unit(self): q1 = np.arange(3.) * u.m q2 = np.array([0., 101., 199.]) * u.cm assert np.allclose(q1, q2, atol=0.011, rtol=0) assert not np.allclose(q2, q1, atol=0.011, rtol=0) def test_allclose_failures(self): q1 = np.arange(3.) * u.m q2 = np.array([0., 101., 199.]) * u.cm with pytest.raises(u.UnitsError): np.allclose(q1, q2, atol=2*u.s, rtol=0) with pytest.raises(u.UnitsError): np.allclose(q1, q2, atol=0, rtol=1.*u.s) @needs_array_function def test_array_equal(self): q1 = np.arange(3.) * u.m q2 = q1.to(u.cm) assert np.array_equal(q1, q2) q3 = q1.value * u.cm assert not np.array_equal(q1, q3) @needs_array_function def test_array_equiv(self): q1 = np.array([[0., 1., 2.]]*3) * u.m q2 = q1[0].to(u.cm) assert np.array_equiv(q1, q2) q3 = q1[0].value * u.cm assert not np.array_equiv(q1, q3) class TestNanFunctions(InvariantUnitTestSetup): def setup(self): super().setup() self.q[1, 1] = np.nan def test_nanmax(self): self.check(np.nanmax) def test_nanmin(self): self.check(np.nanmin) def test_nanargmin(self): out = np.nanargmin(self.q) expected = np.nanargmin(self.q.value) assert out == expected def test_nanargmax(self): out = np.nanargmax(self.q) expected = np.nanargmax(self.q.value) assert out == expected def test_nanmean(self): self.check(np.nanmean) def test_nanmedian(self): self.check(np.nanmedian) def test_nansum(self): self.check(np.nansum) def test_nancumsum(self): self.check(np.nancumsum) def test_nanstd(self): self.check(np.nanstd) def test_nanvar(self): out = np.nanvar(self.q) expected = np.nanvar(self.q.value) * self.q.unit ** 2 assert np.all(out == expected) def test_nanprod(self): with pytest.raises(u.UnitsError): np.nanprod(self.q) def test_nancumprod(self): with pytest.raises(u.UnitsError): np.nancumprod(self.q) @needs_array_function def test_nanquantile(self): self.check(np.nanquantile, 0.5) o = np.nanquantile(self.q, 50 * u.percent) expected = np.nanquantile(self.q.value, 0.5) * u.m assert np.all(o == expected) @needs_array_function def test_nanpercentile(self): self.check(np.nanpercentile, 0.5) o = np.nanpercentile(self.q, 0.5 * u.one) expected = np.nanpercentile(self.q.value, 50) * u.m assert np.all(o == expected) class TestVariousProductFunctions(metaclass=CoverageMeta): """ Test functions that are similar to gufuncs """ @needs_array_function def test_cross(self): q1 = np.arange(6.).reshape(2, 3) * u.m q2 = np.array([4., 5., 6.]) / u.s o = np.cross(q1, q2) expected = np.cross(q1.value, q2.value) * u.m / u.s assert np.all(o == expected) @needs_array_function def test_outer(self): q1 = np.array([1, 2, 3]) * u.m q2 = np.array([1, 2]) / u.s o = np.outer(q1, q2) assert np.all(o == np.array([[1, 2], [2, 4], [3, 6]]) * u.m / u.s) o2 = 0 * o result = np.outer(q1, q2, out=o2) assert result is o2 assert np.all(o2 == o) with pytest.raises(TypeError): np.outer(q1, q2, out=object()) @needs_array_function def test_inner(self): q1 = np.array([1, 2, 3]) * u.m q2 = np.array([4, 5, 6]) / u.s o = np.inner(q1, q2) assert o == 32 * u.m / u.s @needs_array_function def test_dot(self): q1 = np.array([1., 2., 3.]) * u.m q2 = np.array([4., 5., 6.]) / u.s o = np.dot(q1, q2) assert o == 32. * u.m / u.s @needs_array_function def test_vdot(self): q1 = np.array([1j, 2j, 3j]) * u.m q2 = np.array([4j, 5j, 6j]) / u.s o = np.vdot(q1, q2) assert o == (32. + 0j) * u.m / u.s @needs_array_function def test_tensordot(self): # From the docstring example a = np.arange(60.).reshape(3, 4, 5) * u.m b = np.arange(24.).reshape(4, 3, 2) / u.s c = np.tensordot(a, b, axes=([1, 0], [0, 1])) expected = np.tensordot(a.value, b.value, axes=([1, 0], [0, 1])) * u.m / u.s assert np.all(c == expected) @needs_array_function def test_kron(self): q1 = np.eye(2) * u.m q2 = np.ones(2) / u.s o = np.kron(q1, q2) expected = np.kron(q1.value, q2.value) * u.m / u.s assert np.all(o == expected) @needs_array_function def test_einsum(self): q1 = np.arange(9.).reshape(3, 3) * u.m o = np.einsum('...i', q1) assert np.all(o == q1) o = np.einsum('ii', q1) expected = np.einsum('ii', q1.value) * u.m assert np.all(o == expected) q2 = np.eye(3) / u.s o2 = np.einsum('ij,jk', q1, q2) assert np.all(o2 == q1 / u.s) o3 = 0 * o2 result = np.einsum('ij,jk', q1, q2, out=o3) assert result is o3 assert np.all(o3 == o2) def test_einsum_path(self): q1 = np.arange(9.).reshape(3, 3) * u.m o = np.einsum_path('...i', q1) assert o[0] == ['einsum_path', (0,)] o = np.einsum_path('ii', q1) assert o[0] == ['einsum_path', (0,)] q2 = np.eye(3) / u.s o = np.einsum_path('ij,jk', q1, q2) assert o[0] == ['einsum_path', (0, 1)] class TestIntDiffFunctions(metaclass=CoverageMeta): def test_trapz(self): y = np.arange(9.) * u.m / u.s out = np.trapz(y) expected = np.trapz(y.value) * y.unit assert np.all(out == expected) dx = 10. * u.s out = np.trapz(y, dx=dx) expected = np.trapz(y.value, dx=dx.value) * y.unit * dx.unit assert np.all(out == expected) x = np.arange(9.) * u.s out = np.trapz(y, x) expected = np.trapz(y.value, x.value) * y.unit * x.unit assert np.all(out == expected) def test_diff(self): # Simple diff works out of the box. x = np.arange(10.) * u.m out = np.diff(x) expected = np.diff(x.value) * u.m assert np.all(out == expected) @needs_array_function def test_diff_prepend_append(self): x = np.arange(10.) * u.m out = np.diff(x, prepend=-12.5*u.cm, append=1*u.km) expected = np.diff(x.value, prepend=-0.125, append=1000.) * x.unit assert np.all(out == expected) x = np.arange(10.) * u.m out = np.diff(x, prepend=-12.5*u.cm, append=1*u.km, n=2) expected = np.diff(x.value, prepend=-0.125, append=1000., n=2) * x.unit assert np.all(out == expected) with pytest.raises(TypeError): np.diff(x, prepend=object()) def test_gradient(self): # Simple gradient works out of the box. x = np.arange(10.) * u.m out = np.gradient(x) expected = np.gradient(x.value) * u.m assert np.all(out == expected) @needs_array_function def test_gradient_spacing(self): # Simple gradient works out of the box. x = np.arange(10.) * u.m spacing = 10. * u.s out = np.gradient(x, spacing) expected = np.gradient(x.value, spacing.value) * (x.unit / spacing.unit) assert np.all(out == expected) f = np.array([[1, 2, 6], [3, 4, 5]]) * u.m dx = 2. * u.s y = [1., 1.5, 3.5] * u.GHz dfdx, dfdy = np.gradient(f, dx, y) exp_dfdx, exp_dfdy = np.gradient(f.value, dx.value, y.value) exp_dfdx = exp_dfdx * f.unit / dx.unit exp_dfdy = exp_dfdy * f.unit / y.unit assert np.all(dfdx == exp_dfdx) assert np.all(dfdy == exp_dfdy) dfdx2 = np.gradient(f, dx, axis=0) assert np.all(dfdx2 == exp_dfdx) dfdy2 = np.gradient(f, y, axis=(1,)) assert np.all(dfdy2 == exp_dfdy) class TestSpaceFunctions(metaclass=CoverageMeta): def test_linspace(self): # Note: linspace gets unit of end point, not superlogical. out = np.linspace(1000.*u.m, 10.*u.km, 5) expected = np.linspace(1, 10, 5) * u.km assert np.all(out == expected) q1 = np.arange(6.).reshape(2, 3) * u.m q2 = 10000. * u.cm out = np.linspace(q1, q2, 5) expected = np.linspace(q1.to_value(q2.unit), q2.value, 5) * q2.unit assert np.all(out == expected) @needs_array_function def test_logspace(self): unit = u.m / u.s**2 out = np.logspace(10.*u.dex(unit), 20*u.dex(unit), 10) expected = np.logspace(10., 20., 10) * unit assert np.all(out == expected) out = np.logspace(10.*u.STmag, 20*u.STmag, 10) expected = np.logspace(10., 20., 10, base=10.**(-0.4)) * u.ST assert u.allclose(out, expected) @needs_array_function def test_geomspace(self): out = np.geomspace(1000.*u.m, 10.*u.km, 5) expected = np.geomspace(1, 10, 5) * u.km assert np.all(out == expected) q1 = np.arange(1., 7.).reshape(2, 3) * u.m q2 = 10000. * u.cm out = np.geomspace(q1, q2, 5) expected = np.geomspace(q1.to_value(q2.unit), q2.value, 5) * q2.unit assert np.all(out == expected) class TestInterpolationFunctions(metaclass=CoverageMeta): @needs_array_function def test_interp(self): x = np.array([1250., 2750.]) * u.m xp = np.arange(5.) * u.km yp = np.arange(5.) * u.day out = np.interp(x, xp, yp) expected = np.interp(x.to_value(xp.unit), xp.value, yp.value) * yp.unit assert np.all(out == expected) out = np.interp(x, xp, yp.value) assert type(out) is np.ndarray assert np.all(out == expected.value) @needs_array_function def test_piecewise(self): x = np.linspace(-2.5, 2.5, 6) * u.m out = np.piecewise(x, [x < 0, x >= 0], [-1*u.s, 1*u.day]) expected = np.piecewise(x.value, [x.value < 0, x.value >= 0], [-1, 24*3600]) * u.s assert out.unit == expected.unit assert np.all(out == expected) out2 = np.piecewise(x, [x < 1 * u.m, x >= 0], [-1*u.s, 1*u.day, lambda x: 1*u.hour]) expected2 = np.piecewise(x.value, [x.value < 1, x.value >= 0], [-1, 24*3600, 3600]) * u.s assert out2.unit == expected2.unit assert np.all(out2 == expected2) out3 = np.piecewise(x, [x < 1 * u.m, x >= 0], [0, 1*u.percent, lambda x: 1*u.one]) expected3 = np.piecewise(x.value, [x.value < 1, x.value >= 0], [0, 0.01, 1]) * u.one assert out3.unit == expected3.unit assert np.all(out3 == expected3) with pytest.raises(TypeError): # no Quantity in condlist. np.piecewise(x, [x], [0.]) with pytest.raises(TypeError): # no Quantity in condlist. np.piecewise(x.value, [x], [0.]) class TestBincountDigitize(metaclass=CoverageMeta): @needs_array_function def test_bincount(self): i = np.array([1, 1, 2, 3, 2, 4]) weights = np.arange(len(i)) * u.Jy out = np.bincount(i, weights) expected = np.bincount(i, weights.value) * weights.unit assert_array_equal(out, expected) with pytest.raises(TypeError): np.bincount(weights) @needs_array_function def test_digitize(self): x = np.array([1500., 2500., 4500.]) * u.m bins = np.arange(10.) * u.km out = np.digitize(x, bins) expected = np.digitize(x.to_value(bins.unit), bins.value) assert_array_equal(out, expected) class TestHistogramFunctions(metaclass=CoverageMeta): def setup(self): self.x = np.array([1.1, 1.2, 1.3, 2.1, 5.1]) * u.m self.y = np.array([1.2, 2.2, 2.4, 3.0, 4.0]) * u.cm self.weights = np.arange(len(self.x)) / u.s def check(self, function, *args, value_args=None, value_kwargs=None, expected_units=None, **kwargs): """Check quanties are treated correctly in the histogram function. Test is done by applying ``function(*args, **kwargs)``, where the argument can be quantities, and comparing the result to ``function(*value_args, **value_kwargs)``, with the outputs converted to quantities using the ``expected_units`` (where `None` indicates the output is expected to be a regular array). For ``**value_kwargs``, any regular ``kwargs`` are treated as defaults, i.e., non-quantity arguments do not have to be repeated. """ if value_kwargs is None: value_kwargs = kwargs else: for k, v in kwargs.items(): value_kwargs.setdefault(k, v) # Get the result, using the Quantity override. out = function(*args, **kwargs) # Get the comparison, with non-Quantity arguments. expected = function(*value_args, **value_kwargs) # All histogram functions return a tuple of the actual histogram # and the bin edges. First, check the actual histogram. out_h = out[0] expected_h = expected[0] if expected_units[0] is not None: expected_h = expected_h * expected_units[0] assert_array_equal(out_h, expected_h) # Check bin edges. Here, histogramdd returns an interable of the # bin edges as the second return argument, while histogram and # histogram2d return the bin edges directly. if function is np.histogramdd: bin_slice = 1 else: bin_slice = slice(1, None) for o_bin, e_bin, e_unit in zip(out[bin_slice], expected[bin_slice], expected_units[bin_slice]): if e_unit is not None: e_bin = e_bin * e_unit assert_array_equal(o_bin, e_bin) @needs_array_function def test_histogram(self): x = self.x weights = self.weights # Plain histogram. self.check(np.histogram, x, value_args=(x.value,), expected_units=(None, x.unit)) # With bins. self.check(np.histogram, x, [125, 200] * u.cm, value_args=(x.value, [1.25, 2.]), expected_units=(None, x.unit)) # With density. self.check(np.histogram, x, [125, 200] * u.cm, density=True, value_args=(x.value, [1.25, 2.]), expected_units=(1/x.unit, x.unit)) # With weights. self.check(np.histogram, x, [125, 200] * u.cm, weights=weights, value_args=(x.value, [1.25, 2.]), value_kwargs=dict(weights=weights.value), expected_units=(weights.unit, x.unit)) # With weights and density. self.check(np.histogram, x, [125, 200] * u.cm, weights=weights, density=True, value_args=(x.value, [1.25, 2.]), value_kwargs=dict(weights=weights.value), expected_units=(weights.unit/x.unit, x.unit)) with pytest.raises(u.UnitsError): np.histogram(x, [125, 200] * u.s) with pytest.raises(u.UnitsError): np.histogram(x, [125, 200]) with pytest.raises(u.UnitsError): np.histogram(x.value, [125, 200] * u.s) @needs_array_function def test_histogram_bin_edges(self): x = np.array([1.1, 1.2, 1.3, 2.1, 5.1]) * u.m out_b = np.histogram_bin_edges(x) expected_b = np.histogram_bin_edges(x.value) * x.unit assert np.all(out_b == expected_b) # With bins out2_b = np.histogram_bin_edges(x, [125, 200] * u.cm) expected2_b = np.histogram_bin_edges(x.value, [1.25, 2.]) * x.unit assert np.all(out2_b == expected2_b) with pytest.raises(u.UnitsError): np.histogram_bin_edges(x, [125, 200] * u.s) with pytest.raises(u.UnitsError): np.histogram_bin_edges(x, [125, 200]) with pytest.raises(u.UnitsError): np.histogram_bin_edges(x.value, [125, 200] * u.s) @needs_array_function def test_histogram2d(self): x, y = self.x, self.y weights = self.weights # Basic tests with X, Y. self.check(np.histogram2d, x, y, value_args=(x.value, y.value), expected_units=(None, x.unit, y.unit)) # Check units with density. self.check(np.histogram2d, x, y, density=True, value_args=(x.value, y.value), expected_units=(1/(x.unit*y.unit), x.unit, y.unit)) # Check units with weights. self.check(np.histogram2d, x, y, weights=weights, value_args=(x.value, y.value), value_kwargs=dict(weights=weights.value), expected_units=(weights.unit, x.unit, y.unit)) # Check quantity bin sizes. inb_y = [0, 0.025, 1.] * u.m self.check(np.histogram2d, x, y, [5, inb_y], value_args=(x.value, y.value, [5, np.array([0, 2.5, 100.])]), expected_units=(None, x.unit, y.unit)) # Check we dispatch on bin sizes (and check kwarg as well). inb2_y = [0, 250, 10000.] * u.percent self.check(np.histogram2d, x.value, y.value, bins=[5, inb2_y], value_args=(x.value, y.value), value_kwargs=dict(bins=[5, np.array([0, 2.5, 100.])]), expected_units=(None, u.one, u.one)) # Single-item bins should be integer, not Quantity. with pytest.raises(TypeError): np.histogram2d(x, y, 125 * u.s) with pytest.raises(TypeError): np.histogram2d(x.value, y.value, 125 * u.s) # Bin units need to match units of x, y. with pytest.raises(u.UnitsError): np.histogram2d(x, y, [125, 200] * u.s) with pytest.raises(u.UnitsError): np.histogram2d(x, y, ([125, 200], [125, 200])) with pytest.raises(u.UnitsError): np.histogram2d(x.value, y.value, [125, 200] * u.s) @needs_array_function def test_histogramdd(self): # First replicates of the histogram2d tests, but using the # histogramdd override. Normally takes the sample as a tuple # with a given number of dimensions, and returns the histogram # as well as a tuple of bin edges. sample = self.x, self.y sample_units = self.x.unit, self.y.unit sample_values = (self.x.value, self.y.value) weights = self.weights # Basic tests with X, Y self.check(np.histogramdd, sample, value_args=(sample_values,), expected_units=(None, sample_units)) # Check units with density. self.check(np.histogramdd, sample, density=True, value_args=(sample_values,), expected_units=(1/(self.x.unit*self.y.unit), sample_units)) # Check units with weights. self.check(np.histogramdd, sample, weights=weights, value_args=(sample_values,), value_kwargs=dict(weights=weights.value), expected_units=(weights.unit, sample_units)) # Check quantity bin sizes. inb_y = [0, 0.025, 1.] * u.m self.check(np.histogramdd, sample, [5, inb_y], value_args=(sample_values, [5, np.array([0, 2.5, 100.])]), expected_units=(None, sample_units)) # Check we dispatch on bin sizes (and check kwarg as well). inb2_y = [0, 250, 10000.] * u.percent self.check(np.histogramdd, sample_values, bins=[5, inb2_y], value_args=(sample_values,), value_kwargs=dict(bins=[5, np.array([0, 2.5, 100.])]), expected_units=(None, (u.one, u.one))) # For quantities, it is probably not that likely one would pass # in the sample as an array, but check that it works anyway. # This also gives a 3-D check. xyz = np.random.normal(size=(10, 3)) * u.m self.check(np.histogramdd, xyz, value_args=(xyz.value,), expected_units=(None, (xyz.unit,)*3)) # Passing it in as a tuple should work just as well; note the # *last* axis contains the sample dimension. self.check(np.histogramdd, (xyz[:, 0], xyz[:, 1], xyz[:, 2]), value_args=(xyz.value,), expected_units=(None, (xyz.unit,)*3)) # Single-item bins should be integer, not Quantity. with pytest.raises(TypeError): np.histogramdd(sample, 125 * u.s) # Sequence of single items should be integer. with pytest.raises(TypeError): np.histogramdd(sample, [125, 200] * u.s) with pytest.raises(TypeError): np.histogramdd(sample_values, [125, 200] * u.s) # Units of bins should match. with pytest.raises(u.UnitsError): np.histogramdd(sample, ([125, 200], [125, 200])) with pytest.raises(u.UnitsError): np.histogramdd(sample_values, ([125, 200] * u.s, [125, 200])) @needs_array_function def test_correlate(self): x1 = [1, 2, 3] * u.m x2 = [0, 1, 0.5] * u.m out = np.correlate(x1, x2) expected = np.correlate(x1.value, x2.value) * u.m ** 2 assert np.all(out == expected) @needs_array_function def test_convolve(self): x1 = [1, 2, 3] * u.m x2 = [0, 1, 0.5] * u.m out = np.convolve(x1, x2) expected = np.convolve(x1.value, x2.value) * u.m ** 2 assert np.all(out == expected) @needs_array_function def test_cov(self): # Do not see how we can use cov with Quantity x = np.array([[0, 2], [1, 1], [2, 0]]).T * u.m with pytest.raises(TypeError): np.cov(x) @needs_array_function def test_corrcoef(self): # Do not see how we can use cov with Quantity x = np.array([[0, 2], [1, 1], [2, 0]]).T * u.m with pytest.raises(TypeError): np.corrcoef(x) class TestSortFunctions(InvariantUnitTestSetup): def test_sort(self): self.check(np.sort) @needs_array_function def test_sort_complex(self): self.check(np.sort_complex) def test_msort(self): self.check(np.msort) def test_partition(self): self.check(np.partition, 2) class TestStringFunctions(metaclass=CoverageMeta): # For these, making behaviour work means deviating only slightly from # the docstring, and by default they fail miserably. So, might as well. def setup(self): self.q = np.arange(3.) * u.Jy @needs_array_function def test_array2string(self): # The default formatters cannot handle units, so if we do not pass # a relevant formatter, we are better off just treating it as an # array (which happens for all subtypes). out0 = np.array2string(self.q) expected0 = str(self.q.value) assert out0 == expected0 # Arguments are interpreted as usual. out1 = np.array2string(self.q, separator=', ') expected1 = '[0., 1., 2.]' assert out1 == expected1 # If we do pass in a formatter, though, it should be used. out2 = np.array2string(self.q, separator=', ', formatter={'all': str}) expected2 = '[0.0 Jy, 1.0 Jy, 2.0 Jy]' assert out2 == expected2 # Also as positional argument (no, nobody will do this!) out3 = np.array2string(self.q, None, None, None, ', ', '', np._NoValue, {'float': str}) assert out3 == expected2 # But not if the formatter is not relevant for us. out4 = np.array2string(self.q, separator=', ', formatter={'int': str}) assert out4 == expected1 @needs_array_function def test_array_repr(self): out = np.array_repr(self.q) assert out == "Quantity([0., 1., 2.], unit='Jy')" q2 = self.q.astype('f4') out2 = np.array_repr(q2) assert out2 == "Quantity([0., 1., 2.], unit='Jy', dtype=float32)" @needs_array_function def test_array_str(self): out = np.array_str(self.q) expected = str(self.q) assert out == expected class TestBitAndIndexFunctions(metaclass=CoverageMeta): # Index/bit functions generally fail for floats, so the usual # float quantity are safe, but the integer ones are not. def setup(self): self.q = np.arange(3) * u.m self.uint_q = u.Quantity(np.arange(3), 'm', dtype='u1') @needs_array_function def test_packbits(self): with pytest.raises(TypeError): np.packbits(self.q) with pytest.raises(TypeError): np.packbits(self.uint_q) @needs_array_function def test_unpackbits(self): with pytest.raises(TypeError): np.unpackbits(self.q) with pytest.raises(TypeError): np.unpackbits(self.uint_q) @needs_array_function def test_unravel_index(self): with pytest.raises(TypeError): np.unravel_index(self.q, 3) with pytest.raises(TypeError): np.unravel_index(self.uint_q, 3) @needs_array_function def test_ravel_multi_index(self): with pytest.raises(TypeError): np.ravel_multi_index((self.q,), 3) with pytest.raises(TypeError): np.ravel_multi_index((self.uint_q,), 3) @needs_array_function def test_ix_(self): with pytest.raises(TypeError): np.ix_(self.q) with pytest.raises(TypeError): np.ix_(self.uint_q) class TestDtypeFunctions(NoUnitTestSetup): def test_common_type(self): self.check(np.common_type) def test_result_type(self): self.check(np.result_type) def test_can_cast(self): self.check(np.can_cast, self.q.dtype) self.check(np.can_cast, 'f4') def test_min_scalar_type(self): out = np.min_scalar_type(self.q[0]) expected = np.min_scalar_type(self.q.value[0]) assert out == expected def test_iscomplexobj(self): self.check(np.iscomplexobj) def test_isrealobj(self): self.check(np.isrealobj) class TestMeshGrid(metaclass=CoverageMeta): def test_meshgrid(self): q1 = np.arange(3.) * u.m q2 = np.arange(5.) * u.s o1, o2 = np.meshgrid(q1, q2) e1, e2 = np.meshgrid(q1.value, q2.value) assert np.all(o1 == e1 * q1.unit) assert np.all(o2 == e2 * q2.unit) class TestMemoryFunctions(NoUnitTestSetup): def test_shares_memory(self): self.check(np.shares_memory, self.q.value) def test_may_share_memory(self): self.check(np.may_share_memory, self.q.value) class TestSetOpsFcuntions(metaclass=CoverageMeta): def setup(self): self.q = np.array([[0., 1., -1.], [3., 5., 3.], [0., 1., -1]]) * u.m self.q2 = np.array([0., 100., 150., 200.]) * u.cm def check(self, function, qs, *args, **kwargs): unit = kwargs.pop('unit', self.q.unit) out = function(*qs, *args, **kwargs) qv = tuple(q.to_value(self.q.unit) for q in qs) expected = function(*qv, *args, **kwargs) if isinstance(expected, tuple): if unit: expected = (expected[0] * unit,) + expected[1:] for o, e in zip(out, expected): assert_array_equal(o, e) else: if unit: expected = expected * unit assert_array_equal(out, expected) def check1(self, function, *args, **kwargs): self.check(function, (self.q,), *args, **kwargs) def check2(self, function, *args, **kwargs): self.check(function, (self.q, self.q2), *args, **kwargs) @pytest.mark.parametrize('kwargs', ( dict(return_index=True, return_inverse=True), dict(return_counts=True), dict(return_index=True, return_inverse=True, return_counts=True))) def test_unique(self, kwargs): self.check1(np.unique, **kwargs) @needs_array_function @pytest.mark.parametrize('kwargs', ( dict(axis=0), dict(axis=1), dict(return_counts=True, return_inverse=False, axis=1))) def test_unique_more_complex(self, kwargs): self.check1(np.unique, **kwargs) @needs_array_function @pytest.mark.parametrize('kwargs', ( dict(), dict(return_indices=True))) def test_intersect1d(self, kwargs): self.check2(np.intersect1d, **kwargs) @needs_array_function def test_setxor1d(self): self.check2(np.setxor1d) @needs_array_function def test_union1d(self): self.check2(np.union1d) result = np.union1d(np.array([0., np.nan]), np.arange(3) << u.m) assert result.unit is u.m assert_array_equal(result.value, np.array([0., 1., 2., np.nan])) @needs_array_function def test_setdiff1d(self): self.check2(np.setdiff1d) @needs_array_function def test_in1d(self): self.check2(np.in1d, unit=None) # Check zero is treated as having any unit. assert np.in1d(np.zeros(1), self.q2) with pytest.raises(u.UnitsError): np.in1d(np.ones(1), self.q2) @needs_array_function def test_isin(self): self.check2(np.isin, unit=None) def test_ediff1d(self): # ediff1d works always as it calls the Quantity method. self.check1(np.ediff1d) x = np.arange(10.) * u.m out = np.ediff1d(x, to_begin=-12.5*u.cm, to_end=1*u.km) expected = np.ediff1d(x.value, to_begin=-0.125, to_end=1000.) * x.unit assert_array_equal(out, expected) class TestDatetimeFunctions(BasicTestSetup): def test_busday_count(self): with pytest.raises(TypeError): np.busday_count(self.q, self.q) def test_busday_offset(self): with pytest.raises(TypeError): np.busday_offset(self.q, self.q) def test_datetime_as_string(self): with pytest.raises(TypeError): np.datetime_as_string(self.q) def test_is_busday(self): with pytest.raises(TypeError): np.is_busday(self.q) # These functions always worked; ensure they do not regress. # Note that they are *not* wrapped so no need to check coverage. @pytest.mark.parametrize('function', [np.fft.fftfreq, np.fft.rfftfreq]) def test_fft_frequencies(function): out = function(128, d=0.1*u.s) expected = function(128, d=0.1) / u.s assert_array_equal(out, expected) @needs_array_function class TestFFT(InvariantUnitTestSetup): # These are all trivial, just preserve the unit. def setup(self): # Use real input; gets turned into complex as needed. self.q = np.arange(128.).reshape(8, -1) * u.s def test_fft(self): self.check(np.fft.fft) def test_ifft(self): self.check(np.fft.ifft) def test_rfft(self): self.check(np.fft.rfft) def test_irfft(self): self.check(np.fft.irfft) def test_fft2(self): self.check(np.fft.fft2) def test_ifft2(self): self.check(np.fft.ifft2) def test_rfft2(self): self.check(np.fft.rfft2) def test_irfft2(self): self.check(np.fft.irfft2) def test_fftn(self): self.check(np.fft.fftn) def test_ifftn(self): self.check(np.fft.ifftn) def test_rfftn(self): self.check(np.fft.rfftn) def test_irfftn(self): self.check(np.fft.irfftn) def test_hfft(self): self.check(np.fft.hfft) def test_ihfft(self): self.check(np.fft.ihfft) def test_fftshift(self): self.check(np.fft.fftshift) def test_ifftshift(self): self.check(np.fft.ifftshift) class TestLinAlg(metaclass=CoverageMeta): def setup(self): # Use a matrix safe for inversion, etc. self.q = np.array([[1., -1., 2.], [0., 3., -1.], [-1., -1., 1.]]) << u.m def test_cond(self): c = np.linalg.cond(self.q) expected = np.linalg.cond(self.q.value) assert c == expected def test_matrix_rank(self): r = np.linalg.matrix_rank(self.q) x = np.linalg.matrix_rank(self.q.value) assert r == x @needs_array_function def test_matrix_rank_with_tol(self): # Use a matrix that is not so good, so tol=1 and tol=0.01 differ. q = np.arange(9.).reshape(3, 3) / 4 * u.m tol = 1. * u.cm r2 = np.linalg.matrix_rank(q, tol) x2 = np.linalg.matrix_rank(q.value, tol.to_value(q.unit)) assert r2 == x2 def test_matrix_power(self): q1 = np.linalg.matrix_power(self.q, 1) assert_array_equal(q1, self.q) q2 = np.linalg.matrix_power(self.q, 2) assert_array_equal(q2, self.q @ self.q) q2 = np.linalg.matrix_power(self.q, 4) assert_array_equal(q2, self.q @ self.q @ self.q @ self.q) @needs_array_function def test_matrix_inv_power(self): qinv = np.linalg.inv(self.q.value) / self.q.unit qm1 = np.linalg.matrix_power(self.q, -1) assert_array_equal(qm1, qinv) qm3 = np.linalg.matrix_power(self.q, -3) assert_array_equal(qm3, qinv @ qinv @ qinv) @needs_array_function def test_multi_dot(self): q2 = np.linalg.multi_dot([self.q, self.q]) q2x = self.q @ self.q assert_array_equal(q2, q2x) q3 = np.linalg.multi_dot([self.q, self.q, self.q]) q3x = self.q @ self.q @ self.q assert_array_equal(q3, q3x) @needs_array_function def test_svd(self): m = np.arange(10.) * np.arange(5.)[:, np.newaxis] * u.m svd_u, svd_s, svd_vt = np.linalg.svd(m, full_matrices=False) svd_ux, svd_sx, svd_vtx = np.linalg.svd(m.value, full_matrices=False) svd_sx <<= m.unit assert_array_equal(svd_u, svd_ux) assert_array_equal(svd_vt, svd_vtx) assert_array_equal(svd_s, svd_sx) assert u.allclose(svd_u @ np.diag(svd_s) @ svd_vt, m) s2 = np.linalg.svd(m, compute_uv=False) svd_s2x = np.linalg.svd(m.value, compute_uv=False) << m.unit assert_array_equal(s2, svd_s2x) @needs_array_function def test_inv(self): inv = np.linalg.inv(self.q) expected = np.linalg.inv(self.q.value) / self.q.unit assert_array_equal(inv, expected) @needs_array_function def test_pinv(self): pinv = np.linalg.pinv(self.q) expected = np.linalg.pinv(self.q.value) / self.q.unit assert_array_equal(pinv, expected) rcond = 0.01 * u.cm pinv2 = np.linalg.pinv(self.q, rcond) expected2 = np.linalg.pinv(self.q.value, rcond.to_value(self.q.unit)) / self.q.unit assert_array_equal(pinv2, expected2) @needs_array_function def test_tensorinv(self): inv = np.linalg.tensorinv(self.q, ind=1) expected = np.linalg.tensorinv(self.q.value, ind=1) / self.q.unit assert_array_equal(inv, expected) @needs_array_function def test_det(self): det = np.linalg.det(self.q) expected = np.linalg.det(self.q.value) expected <<= self.q.unit ** self.q.shape[-1] assert_array_equal(det, expected) with pytest.raises(np.linalg.LinAlgError): np.linalg.det(self.q[0]) # Not 2-D with pytest.raises(np.linalg.LinAlgError): np.linalg.det(self.q[:-1]) # Not square. @needs_array_function def test_slogdet(self): # TODO: Could be supported if we had a natural logarithm unit. with pytest.raises(TypeError): logdet = np.linalg.slogdet(self.q) assert hasattr(logdet, 'unit') @needs_array_function def test_solve(self): b = np.array([1., 2., 4.]) * u.m / u.s x = np.linalg.solve(self.q, b) xx = np.linalg.solve(self.q.value, b.value) xx <<= b.unit / self.q.unit assert_array_equal(x, xx) assert u.allclose(self.q @ x, b) @needs_array_function def test_tensorsolve(self): b = np.array([1., 2., 4.]) * u.m / u.s x = np.linalg.tensorsolve(self.q, b) xx = np.linalg.tensorsolve(self.q.value, b.value) xx <<= b.unit / self.q.unit assert_array_equal(x, xx) assert u.allclose(self.q @ x, b) @needs_array_function def test_lstsq(self): b = np.array([1., 2., 4.]) * u.m / u.s x, residuals, rank, s = np.linalg.lstsq(self.q, b, rcond=None) xx, residualsx, rankx, sx = np.linalg.lstsq(self.q.value, b.value, rcond=None) xx <<= b.unit / self.q.unit residualsx <<= b.unit ** 2 sx <<= self.q.unit assert_array_equal(x, xx) assert_array_equal(residuals, residualsx) assert_array_equal(s, sx) assert rank == rankx assert u.allclose(self.q @ x, b) # Also do one where we can check the answer... m = np.eye(3) b = np.arange(3) * u.m x, residuals, rank, s = np.linalg.lstsq(m, b, rcond=1.*u.percent) assert_array_equal(x, b) assert np.all(residuals == 0 * u.m**2) assert rank == 3 assert_array_equal(s, np.array([1., 1., 1.]) << u.one) with pytest.raises(u.UnitsError): np.linalg.lstsq(m, b, rcond=1.*u.s) @needs_array_function def test_norm(self): n = np.linalg.norm(self.q) expected = np.linalg.norm(self.q.value) << self.q.unit assert_array_equal(n, expected) # Special case: 1-D, ord=0. n1 = np.linalg.norm(self.q[0], ord=0) expected1 = np.linalg.norm(self.q[0].value, ord=0) << u.one assert_array_equal(n1, expected1) @needs_array_function def test_cholesky(self): # Numbers from np.linalg.cholesky docstring. q = np.array([[1, -2j], [2j, 5]]) * u.m cd = np.linalg.cholesky(q) cdx = np.linalg.cholesky(q.value) << q.unit ** 0.5 assert_array_equal(cd, cdx) assert u.allclose(cd @ cd.T.conj(), q) @needs_array_function def test_qr(self): # This is not exhaustive... a = np.array([[1, -2j], [2j, 5]]) * u.m q, r = np.linalg.qr(a) qx, rx = np.linalg.qr(a.value) qx <<= u.one rx <<= a.unit assert_array_equal(q, qx) assert_array_equal(r, rx) assert u.allclose(q @ r, a) @needs_array_function def test_eig(self): w, v = np.linalg.eig(self.q) wx, vx = np.linalg.eig(self.q.value) wx <<= self.q.unit vx <<= u.one assert_array_equal(w, wx) assert_array_equal(v, vx) # Comprehensible example q = np.diag((1, 2, 3) * u.m) w, v = np.linalg.eig(q) assert_array_equal(w, np.arange(1, 4) * u.m) assert_array_equal(v, np.eye(3)) @needs_array_function def test_eigvals(self): w = np.linalg.eigvals(self.q) wx = np.linalg.eigvals(self.q.value) << self.q.unit assert_array_equal(w, wx) # Comprehensible example q = np.diag((1, 2, 3) * u.m) w = np.linalg.eigvals(q) assert_array_equal(w, np.arange(1, 4) * u.m) @needs_array_function def test_eigh(self): w, v = np.linalg.eigh(self.q) wx, vx = np.linalg.eigh(self.q.value) wx <<= self.q.unit vx <<= u.one assert_array_equal(w, wx) assert_array_equal(v, vx) @needs_array_function def test_eigvalsh(self): w = np.linalg.eigvalsh(self.q) wx = np.linalg.eigvalsh(self.q.value) << self.q.unit assert_array_equal(w, wx) untested_functions = set() if NUMPY_LT_1_20: financial_functions = {f for f in all_wrapped_functions.values() if f in np.lib.financial.__dict__.values()} untested_functions |= financial_functions if NUMPY_LT_1_23: deprecated_functions = { # Deprecated, removed in numpy 1.23 np.asscalar, np.alen, } else: deprecated_functions = set() untested_functions |= deprecated_functions io_functions = {np.save, np.savez, np.savetxt, np.savez_compressed} untested_functions |= io_functions poly_functions = { np.poly, np.polyadd, np.polyder, np.polydiv, np.polyfit, np.polyint, np.polymul, np.polysub, np.polyval, np.roots, np.vander } untested_functions |= poly_functions @needs_array_function def test_testing_completeness(): assert not CoverageMeta.covered.intersection(untested_functions) assert all_wrapped == (CoverageMeta.covered | untested_functions) class TestFunctionHelpersCompleteness: @pytest.mark.parametrize('one, two', itertools.combinations( (SUBCLASS_SAFE_FUNCTIONS, UNSUPPORTED_FUNCTIONS, set(FUNCTION_HELPERS.keys()), set(DISPATCHED_FUNCTIONS.keys())), 2)) def test_no_duplicates(self, one, two): assert not one.intersection(two) @needs_array_function def test_all_included(self): included_in_helpers = (SUBCLASS_SAFE_FUNCTIONS | UNSUPPORTED_FUNCTIONS | set(FUNCTION_HELPERS.keys()) | set(DISPATCHED_FUNCTIONS.keys())) assert all_wrapped == included_in_helpers # untested_function is created using all_wrapped_functions @needs_array_function def test_ignored_are_untested(self): assert IGNORED_FUNCTIONS == untested_functions ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/tests/test_quantity_typing.py0000644000175100001710000000526400000000000023142 0ustar00vstsdocker# coding: utf-8 # Licensed under a 3-clause BSD style license - see LICENSE.rst """Test the Quantity class and related.""" import sys import typing as T import numpy as np import pytest from astropy import units as u from astropy.units._typing import Annotated, HAS_ANNOTATED @pytest.mark.skipif(sys.version_info < (3, 9), reason="requires py3.9+") class TestQuantityTyping: """Test Quantity Typing Annotations.""" def test_quantity_typing(self): """Test type hint creation from Quantity.""" annot = u.Quantity[u.m] assert T.get_origin(annot) is Annotated assert T.get_args(annot) == (u.Quantity, u.m) # test usage def func(x: annot, y: str) -> u.Quantity[u.s]: return x, y annots = T.get_type_hints(func, include_extras=True) assert annots["x"] is annot assert annots["return"].__metadata__[0] == u.s def test_metadata_in_annotation(self): """Test Quantity annotation with added metadata.""" multi_annot = u.Quantity[u.m, T.Any, np.dtype] def multi_func(x: multi_annot, y: str): return x, y annots = T.get_type_hints(multi_func, include_extras=True) assert annots["x"] == multi_annot def test_optional_and_annotated(self): """Test Quantity annotation in an Optional.""" opt_annot = T.Optional[u.Quantity[u.m]] def opt_func(x: opt_annot, y: str): return x, y annots = T.get_type_hints(opt_func, include_extras=True) assert annots["x"] == opt_annot def test_union_and_annotated(self): """Test Quantity annotation in a Union.""" # double Quantity[] union_annot1 = T.Union[u.Quantity[u.m], u.Quantity[u.s]] # one Quantity, one physical-type union_annot2 = T.Union[u.Quantity[u.m], u.Quantity["time"]] # one Quantity, one general type union_annot3 = T.Union[u.Quantity[u.m / u.s], float] def union_func(x: union_annot1, y: union_annot2) -> union_annot3: if isinstance(y, str): # value = time return x.value # returns else: return x / y # returns Quantity[m / s] annots = T.get_type_hints(union_func, include_extras=True) assert annots["x"] == union_annot1 assert annots["y"] == union_annot2 assert annots["return"] == union_annot3 def test_quantity_subclass_typing(self): """Test type hint creation from a Quantity subclasses.""" class Length(u.SpecificTypeQuantity): _equivalent_unit = u.m annot = Length[u.km] assert T.get_origin(annot) is Annotated assert T.get_args(annot) == (Length, u.km) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/tests/test_quantity_ufuncs.py0000644000175100001710000014454200000000000023136 0ustar00vstsdocker# The purpose of these tests are to ensure that calling ufuncs with quantities # returns quantities with the right units, or raises exceptions. import concurrent.futures import warnings from collections import namedtuple import pytest import numpy as np from numpy.testing import assert_allclose from erfa import ufunc as erfa_ufunc from astropy import units as u from astropy.units import quantity_helper as qh from astropy.units.quantity_helper.converters import UfuncHelpers from astropy.units.quantity_helper.helpers import helper_sqrt from astropy.utils.compat.optional_deps import HAS_SCIPY # noqa testcase = namedtuple('testcase', ['f', 'q_in', 'q_out']) testexc = namedtuple('testexc', ['f', 'q_in', 'exc', 'msg']) testwarn = namedtuple('testwarn', ['f', 'q_in', 'wfilter']) @pytest.mark.skip def test_testcase(tc): results = tc.f(*tc.q_in) # careful of the following line, would break on a function returning # a single tuple (as opposed to tuple of return values) results = (results, ) if type(results) != tuple else results for result, expected in zip(results, tc.q_out): assert result.unit == expected.unit assert_allclose(result.value, expected.value, atol=1.E-15) @pytest.mark.skip def test_testexc(te): with pytest.raises(te.exc) as exc: te.f(*te.q_in) if te.msg is not None: assert te.msg in exc.value.args[0] @pytest.mark.skip def test_testwarn(tw): with warnings.catch_warnings(): warnings.filterwarnings(tw.wfilter) tw.f(*tw.q_in) class TestUfuncHelpers: # Note that this test should work even if scipy is present, since # the scipy.special ufuncs are only loaded on demand. # The test passes independently of whether erfa is already loaded # (which will be the case for a full test, since coordinates uses it). def test_coverage(self): """Test that we cover all ufunc's""" all_np_ufuncs = set([ufunc for ufunc in np.core.umath.__dict__.values() if isinstance(ufunc, np.ufunc)]) all_q_ufuncs = (qh.UNSUPPORTED_UFUNCS | set(qh.UFUNC_HELPERS.keys())) # Check that every numpy ufunc is covered. assert all_np_ufuncs - all_q_ufuncs == set() # Check that all ufuncs we cover come from numpy or erfa. # (Since coverage for erfa is incomplete, we do not check # this the other way). all_erfa_ufuncs = set([ufunc for ufunc in erfa_ufunc.__dict__.values() if isinstance(ufunc, np.ufunc)]) assert (all_q_ufuncs - all_np_ufuncs - all_erfa_ufuncs == set()) def test_scipy_registered(self): # Should be registered as existing even if scipy is not available. assert 'scipy.special' in qh.UFUNC_HELPERS.modules def test_removal_addition(self): assert np.add in qh.UFUNC_HELPERS assert np.add not in qh.UNSUPPORTED_UFUNCS qh.UFUNC_HELPERS[np.add] = None assert np.add not in qh.UFUNC_HELPERS assert np.add in qh.UNSUPPORTED_UFUNCS qh.UFUNC_HELPERS[np.add] = qh.UFUNC_HELPERS[np.subtract] assert np.add in qh.UFUNC_HELPERS assert np.add not in qh.UNSUPPORTED_UFUNCS def test_thread_safety(self, fast_thread_switching): def dummy_ufunc(*args, **kwargs): return np.sqrt(*args, **kwargs) def register(): return {dummy_ufunc: helper_sqrt} workers = 8 with concurrent.futures.ThreadPoolExecutor(max_workers=workers) as executor: for p in range(10000): helpers = UfuncHelpers() helpers.register_module( 'astropy.units.tests.test_quantity_ufuncs', ['dummy_ufunc'], register ) futures = [executor.submit(lambda: helpers[dummy_ufunc]) for i in range(workers)] values = [future.result() for future in futures] assert values == [helper_sqrt] * workers class TestQuantityTrigonometricFuncs: """ Test trigonometric functions """ @pytest.mark.parametrize('tc', ( testcase( f=np.sin, q_in=(30. * u.degree, ), q_out=(0.5*u.dimensionless_unscaled, ) ), testcase( f=np.sin, q_in=(np.array([0., np.pi / 4., np.pi / 2.]) * u.radian, ), q_out=(np.array([0., 1. / np.sqrt(2.), 1.]) * u.one, ) ), testcase( f=np.arcsin, q_in=(np.sin(30. * u.degree), ), q_out=(np.radians(30.) * u.radian, ) ), testcase( f=np.arcsin, q_in=(np.sin(np.array([0., np.pi / 4., np.pi / 2.]) * u.radian), ), q_out=(np.array([0., np.pi / 4., np.pi / 2.]) * u.radian, ) ), testcase( f=np.cos, q_in=(np.pi / 3. * u.radian, ), q_out=(0.5 * u.dimensionless_unscaled, ) ), testcase( f=np.cos, q_in=(np.array([0., np.pi / 4., np.pi / 2.]) * u.radian, ), q_out=(np.array([1., 1. / np.sqrt(2.), 0.]) * u.one, ) ), testcase( f=np.arccos, q_in=(np.cos(np.pi / 3. * u.radian), ), q_out=(np.pi / 3. * u.radian, ) ), testcase( f=np.arccos, q_in=(np.cos(np.array([0., np.pi / 4., np.pi / 2.]) * u.radian), ), q_out=(np.array([0., np.pi / 4., np.pi / 2.]) * u.radian, ), ), testcase( f=np.tan, q_in=(np.pi / 3. * u.radian, ), q_out=(np.sqrt(3.) * u.dimensionless_unscaled, ) ), testcase( f=np.tan, q_in=(np.array([0., 45., 135., 180.]) * u.degree, ), q_out=(np.array([0., 1., -1., 0.]) * u.dimensionless_unscaled, ) ), testcase( f=np.arctan, q_in=(np.tan(np.pi / 3. * u.radian), ), q_out=(np.pi / 3. * u.radian, ) ), testcase( f=np.arctan, q_in=(np.tan(np.array([10., 30., 70., 80.]) * u.degree), ), q_out=(np.radians(np.array([10., 30., 70., 80.]) * u.degree), ) ), testcase( f=np.arctan2, q_in=(np.array([10., 30., 70., 80.]) * u.m, 2.0 * u.km), q_out=(np.arctan2(np.array([10., 30., 70., 80.]), 2000.) * u.radian, ) ), testcase( f=np.arctan2, q_in=((np.array([10., 80.]) * u.m / (2.0 * u.km)).to(u.one), 1.), q_out=(np.arctan2(np.array([10., 80.]) / 2000., 1.) * u.radian, ) ), testcase( f=np.deg2rad, q_in=(180. * u.degree, ), q_out=(np.pi * u.radian, ) ), testcase( f=np.radians, q_in=(180. * u.degree, ), q_out=(np.pi * u.radian, ) ), testcase( f=np.deg2rad, q_in=(3. * u.radian, ), q_out=(3. * u.radian, ) ), testcase( f=np.radians, q_in=(3. * u.radian, ), q_out=(3. * u.radian, ) ), testcase( f=np.rad2deg, q_in=(60. * u.degree, ), q_out=(60. * u.degree, ) ), testcase( f=np.degrees, q_in=(60. * u.degree, ), q_out=(60. * u.degree, ) ), testcase( f=np.rad2deg, q_in=(np.pi * u.radian, ), q_out=(180. * u.degree, ) ), testcase( f=np.degrees, q_in=(np.pi * u.radian, ), q_out=(180. * u.degree, ) ) )) def test_testcases(self, tc): return test_testcase(tc) @pytest.mark.parametrize('te', ( testexc( f=np.deg2rad, q_in=(3. * u.m, ), exc=TypeError, msg=None ), testexc( f=np.radians, q_in=(3. * u.m, ), exc=TypeError, msg=None ), testexc( f=np.rad2deg, q_in=(3. * u.m), exc=TypeError, msg=None ), testexc( f=np.degrees, q_in=(3. * u.m), exc=TypeError, msg=None ), testexc( f=np.sin, q_in=(3. * u.m, ), exc=TypeError, msg="Can only apply 'sin' function to quantities with angle units" ), testexc( f=np.arcsin, q_in=(3. * u.m, ), exc=TypeError, msg="Can only apply 'arcsin' function to dimensionless quantities" ), testexc( f=np.cos, q_in=(3. * u.s, ), exc=TypeError, msg="Can only apply 'cos' function to quantities with angle units" ), testexc( f=np.arccos, q_in=(3. * u.s, ), exc=TypeError, msg="Can only apply 'arccos' function to dimensionless quantities" ), testexc( f=np.tan, q_in=(np.array([1, 2, 3]) * u.N, ), exc=TypeError, msg="Can only apply 'tan' function to quantities with angle units" ), testexc( f=np.arctan, q_in=(np.array([1, 2, 3]) * u.N, ), exc=TypeError, msg="Can only apply 'arctan' function to dimensionless quantities" ), testexc( f=np.arctan2, q_in=(np.array([1, 2, 3]) * u.N, 1. * u.s), exc=u.UnitsError, msg="compatible dimensions" ), testexc( f=np.arctan2, q_in=(np.array([1, 2, 3]) * u.N, 1.), exc=u.UnitsError, msg="dimensionless quantities when other arg" ) )) def test_testexcs(self, te): return test_testexc(te) @pytest.mark.parametrize('tw', ( testwarn( f=np.arcsin, q_in=(27. * u.pc / (15 * u.kpc), ), wfilter='error' ), )) def test_testwarns(self, tw): return test_testwarn(tw) class TestQuantityMathFuncs: """ Test other mathematical functions """ def test_multiply_scalar(self): assert np.multiply(4. * u.m, 2. / u.s) == 8. * u.m / u.s assert np.multiply(4. * u.m, 2.) == 8. * u.m assert np.multiply(4., 2. / u.s) == 8. / u.s def test_multiply_array(self): assert np.all(np.multiply(np.arange(3.) * u.m, 2. / u.s) == np.arange(0, 6., 2.) * u.m / u.s) @pytest.mark.skipif(not isinstance(getattr(np, 'matmul', None), np.ufunc), reason="np.matmul is not yet a gufunc") def test_matmul(self): q = np.arange(3.) * u.m r = np.matmul(q, q) assert r == 5. * u.m ** 2 # less trivial case. q1 = np.eye(3) * u.m q2 = np.array([[[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]], [[0., 1., 0.], [0., 0., 1.], [1., 0., 0.]], [[0., 0., 1.], [1., 0., 0.], [0., 1., 0.]]]) / u.s r2 = np.matmul(q1, q2) assert np.all(r2 == np.matmul(q1.value, q2.value) * q1.unit * q2.unit) @pytest.mark.parametrize('function', (np.divide, np.true_divide)) def test_divide_scalar(self, function): assert function(4. * u.m, 2. * u.s) == function(4., 2.) * u.m / u.s assert function(4. * u.m, 2.) == function(4., 2.) * u.m assert function(4., 2. * u.s) == function(4., 2.) / u.s @pytest.mark.parametrize('function', (np.divide, np.true_divide)) def test_divide_array(self, function): assert np.all(function(np.arange(3.) * u.m, 2. * u.s) == function(np.arange(3.), 2.) * u.m / u.s) def test_floor_divide_remainder_and_divmod(self): inch = u.Unit(0.0254 * u.m) dividend = np.array([1., 2., 3.]) * u.m divisor = np.array([3., 4., 5.]) * inch quotient = dividend // divisor remainder = dividend % divisor assert_allclose(quotient.value, [13., 19., 23.]) assert quotient.unit == u.dimensionless_unscaled assert_allclose(remainder.value, [0.0094, 0.0696, 0.079]) assert remainder.unit == dividend.unit quotient2 = np.floor_divide(dividend, divisor) remainder2 = np.remainder(dividend, divisor) assert np.all(quotient2 == quotient) assert np.all(remainder2 == remainder) quotient3, remainder3 = divmod(dividend, divisor) assert np.all(quotient3 == quotient) assert np.all(remainder3 == remainder) with pytest.raises(TypeError): divmod(dividend, u.km) with pytest.raises(TypeError): dividend // u.km with pytest.raises(TypeError): dividend % u.km quotient4, remainder4 = np.divmod(dividend, divisor) assert np.all(quotient4 == quotient) assert np.all(remainder4 == remainder) with pytest.raises(TypeError): np.divmod(dividend, u.km) def test_sqrt_scalar(self): assert np.sqrt(4. * u.m) == 2. * u.m ** 0.5 def test_sqrt_array(self): assert np.all(np.sqrt(np.array([1., 4., 9.]) * u.m) == np.array([1., 2., 3.]) * u.m ** 0.5) def test_square_scalar(self): assert np.square(4. * u.m) == 16. * u.m ** 2 def test_square_array(self): assert np.all(np.square(np.array([1., 2., 3.]) * u.m) == np.array([1., 4., 9.]) * u.m ** 2) def test_reciprocal_scalar(self): assert np.reciprocal(4. * u.m) == 0.25 / u.m def test_reciprocal_array(self): assert np.all(np.reciprocal(np.array([1., 2., 4.]) * u.m) == np.array([1., 0.5, 0.25]) / u.m) def test_heaviside_scalar(self): assert np.heaviside(0. * u.m, 0.5) == 0.5 * u.dimensionless_unscaled assert np.heaviside(0. * u.s, 25 * u.percent) == 0.25 * u.dimensionless_unscaled assert np.heaviside(2. * u.J, 0.25) == 1. * u.dimensionless_unscaled def test_heaviside_array(self): values = np.array([-1., 0., 0., +1.]) halfway = np.array([0.75, 0.25, 0.75, 0.25]) * u.dimensionless_unscaled assert np.all(np.heaviside(values * u.m, halfway * u.dimensionless_unscaled) == [0, 0.25, 0.75, +1.] * u.dimensionless_unscaled) @pytest.mark.parametrize('function', (np.cbrt, )) def test_cbrt_scalar(self, function): assert function(8. * u.m**3) == 2. * u.m @pytest.mark.parametrize('function', (np.cbrt, )) def test_cbrt_array(self, function): # Calculate cbrt on both sides since on Windows the cube root of 64 # does not exactly equal 4. See 4388. values = np.array([1., 8., 64.]) assert np.all(function(values * u.m**3) == function(values) * u.m) def test_power_scalar(self): assert np.power(4. * u.m, 2.) == 16. * u.m ** 2 assert np.power(4., 200. * u.cm / u.m) == \ u.Quantity(16., u.dimensionless_unscaled) # regression check on #1696 assert np.power(4. * u.m, 0.) == 1. * u.dimensionless_unscaled def test_power_array(self): assert np.all(np.power(np.array([1., 2., 3.]) * u.m, 3.) == np.array([1., 8., 27.]) * u.m ** 3) # regression check on #1696 assert np.all(np.power(np.arange(4.) * u.m, 0.) == 1. * u.dimensionless_unscaled) def test_float_power_array(self): assert np.all(np.float_power(np.array([1., 2., 3.]) * u.m, 3.) == np.array([1., 8., 27.]) * u.m ** 3) # regression check on #1696 assert np.all(np.float_power(np.arange(4.) * u.m, 0.) == 1. * u.dimensionless_unscaled) def test_power_array_array(self): with pytest.raises(ValueError): np.power(4. * u.m, [2., 4.]) def test_power_array_array2(self): with pytest.raises(ValueError): np.power([2., 4.] * u.m, [2., 4.]) def test_power_array_array3(self): # Identical unit fractions are converted automatically to dimensionless # and should be allowed as base for np.power: #4764 q = [2., 4.] * u.m / u.m powers = [2., 4.] res = np.power(q, powers) assert np.all(res.value == q.value ** powers) assert res.unit == u.dimensionless_unscaled # The same holds for unit fractions that are scaled dimensionless. q2 = [2., 4.] * u.m / u.cm # Test also against different types of exponent for cls in (list, tuple, np.array, np.ma.array, u.Quantity): res2 = np.power(q2, cls(powers)) assert np.all(res2.value == q2.to_value(1) ** powers) assert res2.unit == u.dimensionless_unscaled # Though for single powers, we keep the composite unit. res3 = q2 ** 2 assert np.all(res3.value == q2.value ** 2) assert res3.unit == q2.unit ** 2 assert np.all(res3 == q2 ** [2, 2]) def test_power_invalid(self): with pytest.raises(TypeError) as exc: np.power(3., 4. * u.m) assert "raise something to a dimensionless" in exc.value.args[0] def test_copysign_scalar(self): assert np.copysign(3 * u.m, 1.) == 3. * u.m assert np.copysign(3 * u.m, 1. * u.s) == 3. * u.m assert np.copysign(3 * u.m, -1.) == -3. * u.m assert np.copysign(3 * u.m, -1. * u.s) == -3. * u.m def test_copysign_array(self): assert np.all(np.copysign(np.array([1., 2., 3.]) * u.s, -1.) == -np.array([1., 2., 3.]) * u.s) assert np.all(np.copysign(np.array([1., 2., 3.]) * u.s, -1. * u.m) == -np.array([1., 2., 3.]) * u.s) assert np.all(np.copysign(np.array([1., 2., 3.]) * u.s, np.array([-2., 2., -4.]) * u.m) == np.array([-1., 2., -3.]) * u.s) q = np.copysign(np.array([1., 2., 3.]), -3 * u.m) assert np.all(q == np.array([-1., -2., -3.])) assert not isinstance(q, u.Quantity) def test_ldexp_scalar(self): assert np.ldexp(4. * u.m, 2) == 16. * u.m def test_ldexp_array(self): assert np.all(np.ldexp(np.array([1., 2., 3.]) * u.m, [3, 2, 1]) == np.array([8., 8., 6.]) * u.m) def test_ldexp_invalid(self): with pytest.raises(TypeError): np.ldexp(3. * u.m, 4.) with pytest.raises(TypeError): np.ldexp(3., u.Quantity(4, u.m, dtype=int)) @pytest.mark.parametrize('function', (np.exp, np.expm1, np.exp2, np.log, np.log2, np.log10, np.log1p)) def test_exp_scalar(self, function): q = function(3. * u.m / (6. * u.m)) assert q.unit == u.dimensionless_unscaled assert q.value == function(0.5) @pytest.mark.parametrize('function', (np.exp, np.expm1, np.exp2, np.log, np.log2, np.log10, np.log1p)) def test_exp_array(self, function): q = function(np.array([2., 3., 6.]) * u.m / (6. * u.m)) assert q.unit == u.dimensionless_unscaled assert np.all(q.value == function(np.array([1. / 3., 1. / 2., 1.]))) # should also work on quantities that can be made dimensionless q2 = function(np.array([2., 3., 6.]) * u.m / (6. * u.cm)) assert q2.unit == u.dimensionless_unscaled assert_allclose(q2.value, function(np.array([100. / 3., 100. / 2., 100.]))) @pytest.mark.parametrize('function', (np.exp, np.expm1, np.exp2, np.log, np.log2, np.log10, np.log1p)) def test_exp_invalid_units(self, function): # Can't use exp() with non-dimensionless quantities with pytest.raises(TypeError) as exc: function(3. * u.m / u.s) assert exc.value.args[0] == ("Can only apply '{}' function to " "dimensionless quantities" .format(function.__name__)) def test_modf_scalar(self): q = np.modf(9. * u.m / (600. * u.cm)) assert q == (0.5 * u.dimensionless_unscaled, 1. * u.dimensionless_unscaled) def test_modf_array(self): v = np.arange(10.) * u.m / (500. * u.cm) q = np.modf(v) n = np.modf(v.to_value(u.dimensionless_unscaled)) assert q[0].unit == u.dimensionless_unscaled assert q[1].unit == u.dimensionless_unscaled assert all(q[0].value == n[0]) assert all(q[1].value == n[1]) def test_frexp_scalar(self): q = np.frexp(3. * u.m / (6. * u.m)) assert q == (np.array(0.5), np.array(0.0)) def test_frexp_array(self): q = np.frexp(np.array([2., 3., 6.]) * u.m / (6. * u.m)) assert all((_q0, _q1) == np.frexp(_d) for _q0, _q1, _d in zip(q[0], q[1], [1. / 3., 1. / 2., 1.])) def test_frexp_invalid_units(self): # Can't use prod() with non-dimensionless quantities with pytest.raises(TypeError) as exc: np.frexp(3. * u.m / u.s) assert exc.value.args[0] == ("Can only apply 'frexp' function to " "unscaled dimensionless quantities") # also does not work on quantities that can be made dimensionless with pytest.raises(TypeError) as exc: np.frexp(np.array([2., 3., 6.]) * u.m / (6. * u.cm)) assert exc.value.args[0] == ("Can only apply 'frexp' function to " "unscaled dimensionless quantities") @pytest.mark.parametrize('function', (np.logaddexp, np.logaddexp2)) def test_dimensionless_twoarg_array(self, function): q = function(np.array([2., 3., 6.]) * u.m / (6. * u.cm), 1.) assert q.unit == u.dimensionless_unscaled assert_allclose(q.value, function(np.array([100. / 3., 100. / 2., 100.]), 1.)) @pytest.mark.parametrize('function', (np.logaddexp, np.logaddexp2)) def test_dimensionless_twoarg_invalid_units(self, function): with pytest.raises(TypeError) as exc: function(1. * u.km / u.s, 3. * u.m / u.s) assert exc.value.args[0] == ("Can only apply '{}' function to " "dimensionless quantities" .format(function.__name__)) class TestInvariantUfuncs: @pytest.mark.parametrize(('ufunc'), [np.absolute, np.fabs, np.conj, np.conjugate, np.negative, np.spacing, np.rint, np.floor, np.ceil, np.positive]) def test_invariant_scalar(self, ufunc): q_i = 4.7 * u.m q_o = ufunc(q_i) assert isinstance(q_o, u.Quantity) assert q_o.unit == q_i.unit assert q_o.value == ufunc(q_i.value) @pytest.mark.parametrize(('ufunc'), [np.absolute, np.conjugate, np.negative, np.rint, np.floor, np.ceil]) def test_invariant_array(self, ufunc): q_i = np.array([-3.3, 2.1, 10.2]) * u.kg / u.s q_o = ufunc(q_i) assert isinstance(q_o, u.Quantity) assert q_o.unit == q_i.unit assert np.all(q_o.value == ufunc(q_i.value)) @pytest.mark.parametrize(('ufunc'), [np.add, np.subtract, np.hypot, np.maximum, np.minimum, np.nextafter, np.remainder, np.mod, np.fmod]) def test_invariant_twoarg_scalar(self, ufunc): q_i1 = 4.7 * u.m q_i2 = 9.4 * u.km q_o = ufunc(q_i1, q_i2) assert isinstance(q_o, u.Quantity) assert q_o.unit == q_i1.unit assert_allclose(q_o.value, ufunc(q_i1.value, q_i2.to_value(q_i1.unit))) @pytest.mark.parametrize(('ufunc'), [np.add, np.subtract, np.hypot, np.maximum, np.minimum, np.nextafter, np.remainder, np.mod, np.fmod]) def test_invariant_twoarg_array(self, ufunc): q_i1 = np.array([-3.3, 2.1, 10.2]) * u.kg / u.s q_i2 = np.array([10., -5., 1.e6]) * u.g / u.us q_o = ufunc(q_i1, q_i2) assert isinstance(q_o, u.Quantity) assert q_o.unit == q_i1.unit assert_allclose(q_o.value, ufunc(q_i1.value, q_i2.to_value(q_i1.unit))) @pytest.mark.parametrize(('ufunc', 'arbitrary'), [ (np.add, 0.), (np.subtract, 0.), (np.hypot, 0.), (np.maximum, 0.), (np.minimum, 0.), (np.nextafter, 0.), (np.remainder, np.inf), (np.mod, np.inf), (np.fmod, np.inf)]) def test_invariant_twoarg_one_arbitrary(self, ufunc, arbitrary): q_i1 = np.array([-3.3, 2.1, 10.2]) * u.kg / u.s q_o = ufunc(q_i1, arbitrary) assert isinstance(q_o, u.Quantity) assert q_o.unit == q_i1.unit assert_allclose(q_o.value, ufunc(q_i1.value, arbitrary)) @pytest.mark.parametrize(('ufunc'), [np.add, np.subtract, np.hypot, np.maximum, np.minimum, np.nextafter, np.remainder, np.mod, np.fmod]) def test_invariant_twoarg_invalid_units(self, ufunc): q_i1 = 4.7 * u.m q_i2 = 9.4 * u.s with pytest.raises(u.UnitsError) as exc: ufunc(q_i1, q_i2) assert "compatible dimensions" in exc.value.args[0] class TestComparisonUfuncs: @pytest.mark.parametrize(('ufunc'), [np.greater, np.greater_equal, np.less, np.less_equal, np.not_equal, np.equal]) def test_comparison_valid_units(self, ufunc): q_i1 = np.array([-3.3, 2.1, 10.2]) * u.kg / u.s q_i2 = np.array([10., -5., 1.e6]) * u.g / u.Ms q_o = ufunc(q_i1, q_i2) assert not isinstance(q_o, u.Quantity) assert q_o.dtype == bool assert np.all(q_o == ufunc(q_i1.value, q_i2.to_value(q_i1.unit))) q_o2 = ufunc(q_i1 / q_i2, 2.) assert not isinstance(q_o2, u.Quantity) assert q_o2.dtype == bool assert np.all(q_o2 == ufunc((q_i1 / q_i2) .to_value(u.dimensionless_unscaled), 2.)) # comparison with 0., inf, nan is OK even for dimensional quantities # (though ignore numpy runtime warnings for comparisons with nan). with warnings.catch_warnings(): warnings.filterwarnings('ignore', category=RuntimeWarning) for arbitrary_unit_value in (0., np.inf, np.nan): ufunc(q_i1, arbitrary_unit_value) ufunc(q_i1, arbitrary_unit_value*np.ones(len(q_i1))) # and just for completeness ufunc(q_i1, np.array([0., np.inf, np.nan])) @pytest.mark.parametrize(('ufunc'), [np.greater, np.greater_equal, np.less, np.less_equal, np.not_equal, np.equal]) def test_comparison_invalid_units(self, ufunc): q_i1 = 4.7 * u.m q_i2 = 9.4 * u.s with pytest.raises(u.UnitsError) as exc: ufunc(q_i1, q_i2) assert "compatible dimensions" in exc.value.args[0] @pytest.mark.parametrize('ufunc', (np.isfinite, np.isinf, np.isnan, np.signbit)) def test_onearg_test_ufuncs(self, ufunc): q = [1., np.inf, -np.inf, np.nan, -1., 0.] * u.m out = ufunc(q) assert not isinstance(out, u.Quantity) assert out.dtype == bool assert np.all(out == ufunc(q.value)) # Ignore RuntimeWarning raised on Windows and s390. @pytest.mark.filterwarnings('ignore:.*invalid value encountered in sign') def test_sign(self): q = [1., np.inf, -np.inf, np.nan, -1., 0.] * u.m out = np.sign(q) assert not isinstance(out, u.Quantity) assert out.dtype == q.dtype assert np.all((out == np.sign(q.value)) | (np.isnan(out) & np.isnan(q.value))) class TestInplaceUfuncs: @pytest.mark.parametrize(('value'), [1., np.arange(10.)]) def test_one_argument_ufunc_inplace(self, value): # without scaling s = value * u.rad check = s np.sin(s, out=s) assert check is s assert check.unit == u.dimensionless_unscaled # with scaling s2 = (value * u.rad).to(u.deg) check2 = s2 np.sin(s2, out=s2) assert check2 is s2 assert check2.unit == u.dimensionless_unscaled assert_allclose(s.value, s2.value) @pytest.mark.parametrize(('value'), [1., np.arange(10.)]) def test_one_argument_ufunc_inplace_2(self, value): """Check inplace works with non-quantity input and quantity output""" s = value * u.m check = s np.absolute(value, out=s) assert check is s assert np.all(check.value == np.absolute(value)) assert check.unit is u.dimensionless_unscaled np.sqrt(value, out=s) assert check is s assert np.all(check.value == np.sqrt(value)) assert check.unit is u.dimensionless_unscaled np.exp(value, out=s) assert check is s assert np.all(check.value == np.exp(value)) assert check.unit is u.dimensionless_unscaled np.arcsin(value/10., out=s) assert check is s assert np.all(check.value == np.arcsin(value/10.)) assert check.unit is u.radian @pytest.mark.parametrize(('value'), [1., np.arange(10.)]) def test_one_argument_two_output_ufunc_inplace(self, value): v = 100. * value * u.cm / u.m v_copy = v.copy() tmp = v.copy() check = v np.modf(v, tmp, v) assert check is v assert check.unit == u.dimensionless_unscaled v2 = v_copy.to(u.dimensionless_unscaled) check2 = v2 np.modf(v2, tmp, v2) assert check2 is v2 assert check2.unit == u.dimensionless_unscaled # can also replace in last position if no scaling is needed v3 = v_copy.to(u.dimensionless_unscaled) check3 = v3 np.modf(v3, v3, tmp) assert check3 is v3 assert check3.unit == u.dimensionless_unscaled # can also replace input with first output when scaling v4 = v_copy.copy() check4 = v4 np.modf(v4, v4, tmp) assert check4 is v4 assert check4.unit == u.dimensionless_unscaled @pytest.mark.parametrize(('value'), [1., np.arange(10.)]) def test_two_argument_ufunc_inplace_1(self, value): s = value * u.cycle check = s s /= 2. assert check is s assert np.all(check.value == value / 2.) s /= u.s assert check is s assert check.unit == u.cycle / u.s s *= 2. * u.s assert check is s assert np.all(check == value * u.cycle) @pytest.mark.parametrize(('value'), [1., np.arange(10.)]) def test_two_argument_ufunc_inplace_2(self, value): s = value * u.cycle check = s np.arctan2(s, s, out=s) assert check is s assert check.unit == u.radian with pytest.raises(u.UnitsError): s += 1. * u.m assert check is s assert check.unit == u.radian np.arctan2(1. * u.deg, s, out=s) assert check is s assert check.unit == u.radian np.add(1. * u.deg, s, out=s) assert check is s assert check.unit == u.deg np.multiply(2. / u.s, s, out=s) assert check is s assert check.unit == u.deg / u.s def test_two_argument_ufunc_inplace_3(self): s = np.array([1., 2., 3.]) * u.dimensionless_unscaled np.add(np.array([1., 2., 3.]), np.array([1., 2., 3.]) * 2., out=s) assert np.all(s.value == np.array([3., 6., 9.])) assert s.unit is u.dimensionless_unscaled np.arctan2(np.array([1., 2., 3.]), np.array([1., 2., 3.]) * 2., out=s) assert_allclose(s.value, np.arctan2(1., 2.)) assert s.unit is u.radian @pytest.mark.parametrize(('value'), [1., np.arange(10.)]) def test_two_argument_two_output_ufunc_inplace(self, value): v = value * u.m divisor = 70.*u.cm v1 = v.copy() tmp = v.copy() check = np.divmod(v1, divisor, out=(tmp, v1)) assert check[0] is tmp and check[1] is v1 assert tmp.unit == u.dimensionless_unscaled assert v1.unit == v.unit v2 = v.copy() check2 = np.divmod(v2, divisor, out=(v2, tmp)) assert check2[0] is v2 and check2[1] is tmp assert v2.unit == u.dimensionless_unscaled assert tmp.unit == v.unit v3a = v.copy() v3b = v.copy() check3 = np.divmod(v3a, divisor, out=(v3a, v3b)) assert check3[0] is v3a and check3[1] is v3b assert v3a.unit == u.dimensionless_unscaled assert v3b.unit == v.unit def test_ufunc_inplace_non_contiguous_data(self): # ensure inplace works also for non-contiguous data (closes #1834) s = np.arange(10.) * u.m s_copy = s.copy() s2 = s[::2] s2 += 1. * u.cm assert np.all(s[::2] > s_copy[::2]) assert np.all(s[1::2] == s_copy[1::2]) def test_ufunc_inplace_non_standard_dtype(self): """Check that inplace operations check properly for casting. First two tests that check that float32 is kept close #3976. """ a1 = u.Quantity([1, 2, 3, 4], u.m, dtype=np.float32) a1 *= np.float32(10) assert a1.unit is u.m assert a1.dtype == np.float32 a2 = u.Quantity([1, 2, 3, 4], u.m, dtype=np.float32) a2 += (20.*u.km) assert a2.unit is u.m assert a2.dtype == np.float32 # For integer, in-place only works if no conversion is done. a3 = u.Quantity([1, 2, 3, 4], u.m, dtype=np.int32) a3 += u.Quantity(10, u.m, dtype=np.int64) assert a3.unit is u.m assert a3.dtype == np.int32 a4 = u.Quantity([1, 2, 3, 4], u.m, dtype=np.int32) with pytest.raises(TypeError): a4 += u.Quantity(10, u.mm, dtype=np.int64) @pytest.mark.parametrize('ufunc', (np.equal, np.greater)) def test_comparison_ufuncs_inplace(self, ufunc): q_i1 = np.array([-3.3, 2.1, 10.2]) * u.kg / u.s q_i2 = np.array([10., -5., 1.e6]) * u.g / u.Ms check = np.empty(q_i1.shape, bool) ufunc(q_i1.value, q_i2.to_value(q_i1.unit), out=check) result = np.empty(q_i1.shape, bool) q_o = ufunc(q_i1, q_i2, out=result) assert q_o is result assert type(q_o) is np.ndarray assert q_o.dtype == bool assert np.all(q_o == check) @pytest.mark.parametrize('ufunc', (np.isfinite, np.signbit)) def test_onearg_test_ufuncs_inplace(self, ufunc): q = [1., np.inf, -np.inf, np.nan, -1., 0.] * u.m check = np.empty(q.shape, bool) ufunc(q.value, out=check) result = np.empty(q.shape, bool) out = ufunc(q, out=result) assert out is result assert type(out) is np.ndarray assert out.dtype == bool assert np.all(out == ufunc(q.value)) # Ignore RuntimeWarning raised on Windows and s390. @pytest.mark.filterwarnings('ignore:.*invalid value encountered in sign') def test_sign_inplace(self): q = [1., np.inf, -np.inf, np.nan, -1., 0.] * u.m check = np.empty(q.shape, q.dtype) np.sign(q.value, out=check) result = np.empty(q.shape, q.dtype) out = np.sign(q, out=result) assert out is result assert type(out) is np.ndarray assert out.dtype == q.dtype assert np.all((out == np.sign(q.value)) | (np.isnan(out) & np.isnan(q.value))) @pytest.mark.skipif(not hasattr(np.core.umath, 'clip'), reason='no clip ufunc available') class TestClip: """Test the clip ufunc. In numpy, this is hidden behind a function that does not backwards compatibility checks. We explicitly test the ufunc here. """ def setup(self): self.clip = np.core.umath.clip def test_clip_simple(self): q = np.arange(-1., 10.) * u.m q_min = 125 * u.cm q_max = 0.0055 * u.km result = self.clip(q, q_min, q_max) assert result.unit == q.unit expected = self.clip(q.value, q_min.to_value(q.unit), q_max.to_value(q.unit)) * q.unit assert np.all(result == expected) def test_clip_unitless_parts(self): q = np.arange(-1., 10.) * u.m qlim = 0.0055 * u.km # one-sided result1 = self.clip(q, -np.inf, qlim) expected1 = self.clip(q.value, -np.inf, qlim.to_value(q.unit)) * q.unit assert np.all(result1 == expected1) result2 = self.clip(q, qlim, np.inf) expected2 = self.clip(q.value, qlim.to_value(q.unit), np.inf) * q.unit assert np.all(result2 == expected2) # Zero result3 = self.clip(q, np.zeros(q.shape), qlim) expected3 = self.clip(q.value, 0, qlim.to_value(q.unit)) * q.unit assert np.all(result3 == expected3) # Two unitless parts, array-shaped. result4 = self.clip(q, np.zeros(q.shape), np.full(q.shape, np.inf)) expected4 = self.clip(q.value, 0, np.inf) * q.unit assert np.all(result4 == expected4) def test_clip_dimensionless(self): q = np.arange(-1., 10.) * u.dimensionless_unscaled result = self.clip(q, 200 * u.percent, 5.) expected = self.clip(q, 2., 5.) assert result.unit == u.dimensionless_unscaled assert np.all(result == expected) def test_clip_ndarray(self): a = np.arange(-1., 10.) result = self.clip(a, 200 * u.percent, 5. * u.dimensionless_unscaled) assert isinstance(result, u.Quantity) expected = self.clip(a, 2., 5.) * u.dimensionless_unscaled assert np.all(result == expected) def test_clip_quantity_inplace(self): q = np.arange(-1., 10.) * u.m q_min = 125 * u.cm q_max = 0.0055 * u.km expected = self.clip(q.value, q_min.to_value(q.unit), q_max.to_value(q.unit)) * q.unit result = self.clip(q, q_min, q_max, out=q) assert result is q assert np.all(result == expected) def test_clip_ndarray_dimensionless_output(self): a = np.arange(-1., 10.) q = np.zeros_like(a) * u.m expected = self.clip(a, 2., 5.) * u.dimensionless_unscaled result = self.clip(a, 200 * u.percent, 5. * u.dimensionless_unscaled, out=q) assert result is q assert result.unit == u.dimensionless_unscaled assert np.all(result == expected) def test_clip_errors(self): q = np.arange(-1., 10.) * u.m with pytest.raises(u.UnitsError): self.clip(q, 0, 1*u.s) with pytest.raises(u.UnitsError): self.clip(q.value, 0, 1*u.s) with pytest.raises(u.UnitsError): self.clip(q, -1, 0.) with pytest.raises(u.UnitsError): self.clip(q, 0., 1.) class TestUfuncAt: """Test that 'at' method for ufuncs (calculates in-place at given indices) For Quantities, since calculations are in-place, it makes sense only if the result is still a quantity, and if the unit does not have to change """ def test_one_argument_ufunc_at(self): q = np.arange(10.) * u.m i = np.array([1, 2]) qv = q.value.copy() np.negative.at(q, i) np.negative.at(qv, i) assert np.all(q.value == qv) assert q.unit is u.m # cannot change from quantity to bool array with pytest.raises(TypeError): np.isfinite.at(q, i) # for selective in-place, cannot change the unit with pytest.raises(u.UnitsError): np.square.at(q, i) # except if the unit does not change (i.e., dimensionless) d = np.arange(10.) * u.dimensionless_unscaled dv = d.value.copy() np.square.at(d, i) np.square.at(dv, i) assert np.all(d.value == dv) assert d.unit is u.dimensionless_unscaled d = np.arange(10.) * u.dimensionless_unscaled dv = d.value.copy() np.log.at(d, i) np.log.at(dv, i) assert np.all(d.value == dv) assert d.unit is u.dimensionless_unscaled # also for sine it doesn't work, even if given an angle a = np.arange(10.) * u.radian with pytest.raises(u.UnitsError): np.sin.at(a, i) # except, for consistency, if we have made radian equivalent to # dimensionless (though hopefully it will never be needed) av = a.value.copy() with u.add_enabled_equivalencies(u.dimensionless_angles()): np.sin.at(a, i) np.sin.at(av, i) assert_allclose(a.value, av) # but we won't do double conversion ad = np.arange(10.) * u.degree with pytest.raises(u.UnitsError): np.sin.at(ad, i) def test_two_argument_ufunc_at(self): s = np.arange(10.) * u.m i = np.array([1, 2]) check = s.value.copy() np.add.at(s, i, 1.*u.km) np.add.at(check, i, 1000.) assert np.all(s.value == check) assert s.unit is u.m with pytest.raises(u.UnitsError): np.add.at(s, i, 1.*u.s) # also raise UnitsError if unit would have to be changed with pytest.raises(u.UnitsError): np.multiply.at(s, i, 1*u.s) # but be fine if it does not s = np.arange(10.) * u.m check = s.value.copy() np.multiply.at(s, i, 2.*u.dimensionless_unscaled) np.multiply.at(check, i, 2) assert np.all(s.value == check) s = np.arange(10.) * u.m np.multiply.at(s, i, 2.) assert np.all(s.value == check) # of course cannot change class of data either with pytest.raises(TypeError): np.greater.at(s, i, 1.*u.km) class TestUfuncReduceReduceatAccumulate: """Test 'reduce', 'reduceat' and 'accumulate' methods for ufuncs For Quantities, it makes sense only if the unit does not have to change """ def test_one_argument_ufunc_reduce_accumulate(self): # one argument cannot be used s = np.arange(10.) * u.radian i = np.array([0, 5, 1, 6]) with pytest.raises(ValueError): np.sin.reduce(s) with pytest.raises(ValueError): np.sin.accumulate(s) with pytest.raises(ValueError): np.sin.reduceat(s, i) def test_two_argument_ufunc_reduce_accumulate(self): s = np.arange(10.) * u.m i = np.array([0, 5, 1, 6]) check = s.value.copy() s_add_reduce = np.add.reduce(s) check_add_reduce = np.add.reduce(check) assert s_add_reduce.value == check_add_reduce assert s_add_reduce.unit is u.m s_add_accumulate = np.add.accumulate(s) check_add_accumulate = np.add.accumulate(check) assert np.all(s_add_accumulate.value == check_add_accumulate) assert s_add_accumulate.unit is u.m s_add_reduceat = np.add.reduceat(s, i) check_add_reduceat = np.add.reduceat(check, i) assert np.all(s_add_reduceat.value == check_add_reduceat) assert s_add_reduceat.unit is u.m # reduce(at) or accumulate on comparisons makes no sense, # as intermediate result is not even a Quantity with pytest.raises(TypeError): np.greater.reduce(s) with pytest.raises(TypeError): np.greater.accumulate(s) with pytest.raises(TypeError): np.greater.reduceat(s, i) # raise UnitsError if unit would have to be changed with pytest.raises(u.UnitsError): np.multiply.reduce(s) with pytest.raises(u.UnitsError): np.multiply.accumulate(s) with pytest.raises(u.UnitsError): np.multiply.reduceat(s, i) # but be fine if it does not s = np.arange(10.) * u.dimensionless_unscaled check = s.value.copy() s_multiply_reduce = np.multiply.reduce(s) check_multiply_reduce = np.multiply.reduce(check) assert s_multiply_reduce.value == check_multiply_reduce assert s_multiply_reduce.unit is u.dimensionless_unscaled s_multiply_accumulate = np.multiply.accumulate(s) check_multiply_accumulate = np.multiply.accumulate(check) assert np.all(s_multiply_accumulate.value == check_multiply_accumulate) assert s_multiply_accumulate.unit is u.dimensionless_unscaled s_multiply_reduceat = np.multiply.reduceat(s, i) check_multiply_reduceat = np.multiply.reduceat(check, i) assert np.all(s_multiply_reduceat.value == check_multiply_reduceat) assert s_multiply_reduceat.unit is u.dimensionless_unscaled class TestUfuncOuter: """Test 'outer' methods for ufuncs Just a few spot checks, since it uses the same code as the regular ufunc call """ def test_one_argument_ufunc_outer(self): # one argument cannot be used s = np.arange(10.) * u.radian with pytest.raises(ValueError): np.sin.outer(s) def test_two_argument_ufunc_outer(self): s1 = np.arange(10.) * u.m s2 = np.arange(2.) * u.s check1 = s1.value check2 = s2.value s12_multiply_outer = np.multiply.outer(s1, s2) check12_multiply_outer = np.multiply.outer(check1, check2) assert np.all(s12_multiply_outer.value == check12_multiply_outer) assert s12_multiply_outer.unit == s1.unit * s2.unit # raise UnitsError if appropriate with pytest.raises(u.UnitsError): np.add.outer(s1, s2) # but be fine if it does not s3 = np.arange(2.) * s1.unit check3 = s3.value s13_add_outer = np.add.outer(s1, s3) check13_add_outer = np.add.outer(check1, check3) assert np.all(s13_add_outer.value == check13_add_outer) assert s13_add_outer.unit is s1.unit s13_greater_outer = np.greater.outer(s1, s3) check13_greater_outer = np.greater.outer(check1, check3) assert type(s13_greater_outer) is np.ndarray assert np.all(s13_greater_outer == check13_greater_outer) if HAS_SCIPY: from scipy import special as sps erf_like_ufuncs = ( sps.erf, sps.erfc, sps.erfcx, sps.erfi, sps.gamma, sps.gammaln, sps.loggamma, sps.gammasgn, sps.psi, sps.rgamma, sps.digamma, sps.wofz, sps.dawsn, sps.entr, sps.exprel, sps.expm1, sps.log1p, sps.exp2, sps.exp10) if isinstance(sps.erfinv, np.ufunc): erf_like_ufuncs += (sps.erfinv, sps.erfcinv) def test_scipy_registration(): """Check that scipy gets loaded upon first use.""" assert sps.erf not in qh.UFUNC_HELPERS sps.erf(1. * u.percent) assert sps.erf in qh.UFUNC_HELPERS if isinstance(sps.erfinv, np.ufunc): assert sps.erfinv in qh.UFUNC_HELPERS else: assert sps.erfinv not in qh.UFUNC_HELPERS class TestScipySpecialUfuncs: @pytest.mark.parametrize('function', erf_like_ufuncs) def test_erf_scalar(self, function): TestQuantityMathFuncs.test_exp_scalar(None, function) @pytest.mark.parametrize('function', erf_like_ufuncs) def test_erf_array(self, function): TestQuantityMathFuncs.test_exp_array(None, function) @pytest.mark.parametrize('function', erf_like_ufuncs) def test_erf_invalid_units(self, function): TestQuantityMathFuncs.test_exp_invalid_units(None, function) @pytest.mark.parametrize('function', (sps.cbrt, )) def test_cbrt_scalar(self, function): TestQuantityMathFuncs.test_cbrt_scalar(None, function) @pytest.mark.parametrize('function', (sps.cbrt, )) def test_cbrt_array(self, function): TestQuantityMathFuncs.test_cbrt_array(None, function) @pytest.mark.parametrize('function', (sps.radian, )) def test_radian(self, function): q1 = function(180. * u.degree, 0. * u.arcmin, 0. * u.arcsec) assert_allclose(q1.value, np.pi) assert q1.unit == u.radian q2 = function(0. * u.degree, 30. * u.arcmin, 0. * u.arcsec) assert_allclose(q2.value, (30. * u.arcmin).to(u.radian).value) assert q2.unit == u.radian q3 = function(0. * u.degree, 0. * u.arcmin, 30. * u.arcsec) assert_allclose(q3.value, (30. * u.arcsec).to(u.radian).value) # the following doesn't make much sense in terms of the name of the # routine, but we check it gives the correct result. q4 = function(3. * u.radian, 0. * u.arcmin, 0. * u.arcsec) assert_allclose(q4.value, 3.) assert q4.unit == u.radian with pytest.raises(TypeError): function(3. * u.m, 2. * u.s, 1. * u.kg) jv_like_ufuncs = ( sps.jv, sps.jn, sps.jve, sps.yn, sps.yv, sps.yve, sps.kn, sps.kv, sps.kve, sps.iv, sps.ive, sps.hankel1, sps.hankel1e, sps.hankel2, sps.hankel2e) @pytest.mark.parametrize('function', jv_like_ufuncs) def test_jv_scalar(self, function): q = function(2. * u.m / (2. * u.m), 3. * u.m / (6. * u.m)) assert q.unit == u.dimensionless_unscaled assert q.value == function(1.0, 0.5) @pytest.mark.parametrize('function', jv_like_ufuncs) def test_jv_array(self, function): q = function(np.ones(3) * u.m / (1. * u.m), np.array([2., 3., 6.]) * u.m / (6. * u.m)) assert q.unit == u.dimensionless_unscaled assert np.all(q.value == function( np.ones(3), np.array([1. / 3., 1. / 2., 1.])) ) # should also work on quantities that can be made dimensionless q2 = function(np.ones(3) * u.m / (1. * u.m), np.array([2., 3., 6.]) * u.m / (6. * u.cm)) assert q2.unit == u.dimensionless_unscaled assert_allclose(q2.value, function(np.ones(3), np.array([100. / 3., 100. / 2., 100.]))) @pytest.mark.parametrize('function', jv_like_ufuncs) def test_jv_invalid_units(self, function): # Can't use jv() with non-dimensionless quantities with pytest.raises(TypeError) as exc: function(1. * u.kg, 3. * u.m / u.s) assert exc.value.args[0] == ("Can only apply '{}' function to " "dimensionless quantities" .format(function.__name__)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/tests/test_structured.py0000644000175100001710000006747500000000000022112 0ustar00vstsdocker# coding: utf-8 # Licensed under a 3-clause BSD style license - see LICENSE.rst """ Test Structured units and quantities. """ import copy import pytest import numpy as np from numpy.testing import assert_array_equal from astropy import units as u from astropy.units import StructuredUnit, Unit, UnitBase, Quantity from astropy.tests.helper import pickle_protocol, check_pickling_recovery from astropy.utils.compat import NUMPY_LT_1_21_1 from astropy.utils.masked import Masked class StructuredTestBase: @classmethod def setup_class(self): self.pv_dtype = np.dtype([('p', 'f8'), ('v', 'f8')]) self.pv_t_dtype = np.dtype([('pv', self.pv_dtype), ('t', 'f8')]) self.p_unit = u.km self.v_unit = u.km / u.s self.t_unit = u.s self.pv_dtype = np.dtype([('p', 'f8'), ('v', 'f8')]) self.pv_t_dtype = np.dtype([('pv', self.pv_dtype), ('t', 'f8')]) self.pv = np.array([(1., 0.25), (2., 0.5), (3., 0.75)], self.pv_dtype) self.pv_t = np.array([((4., 2.5), 0.), ((5., 5.0), 1.), ((6., 7.5), 2.)], self.pv_t_dtype) class StructuredTestBaseWithUnits(StructuredTestBase): @classmethod def setup_class(self): super().setup_class() self.pv_unit = StructuredUnit((self.p_unit, self.v_unit), ('p', 'v')) self.pv_t_unit = StructuredUnit((self.pv_unit, self.t_unit), ('pv', 't')) class TestStructuredUnitBasics(StructuredTestBase): def test_initialization_and_keying(self): su = StructuredUnit((self.p_unit, self.v_unit), ('p', 'v')) assert su['p'] is self.p_unit assert su['v'] is self.v_unit su2 = StructuredUnit((su, self.t_unit), ('pv', 't')) assert isinstance(su2['pv'], StructuredUnit) assert su2['pv']['p'] is self.p_unit assert su2['pv']['v'] is self.v_unit assert su2['t'] is self.t_unit assert su2['pv'] == su su3 = StructuredUnit(('AU', 'AU/day'), ('p', 'v')) assert isinstance(su3['p'], UnitBase) assert isinstance(su3['v'], UnitBase) su4 = StructuredUnit('AU, AU/day', ('p', 'v')) assert su4['p'] == u.AU assert su4['v'] == u.AU / u.day su5 = StructuredUnit(('AU', 'AU/day')) assert su5.field_names == ('f0', 'f1') assert su5['f0'] == u.AU assert su5['f1'] == u.AU / u.day def test_recursive_initialization(self): su = StructuredUnit(((self.p_unit, self.v_unit), self.t_unit), (('p', 'v'), 't')) assert isinstance(su['pv'], StructuredUnit) assert su['pv']['p'] is self.p_unit assert su['pv']['v'] is self.v_unit assert su['t'] is self.t_unit su2 = StructuredUnit(((self.p_unit, self.v_unit), self.t_unit), (['p_v', ('p', 'v')], 't')) assert isinstance(su2['p_v'], StructuredUnit) assert su2['p_v']['p'] is self.p_unit assert su2['p_v']['v'] is self.v_unit assert su2['t'] is self.t_unit su3 = StructuredUnit((('AU', 'AU/day'), 'yr'), (['p_v', ('p', 'v')], 't')) assert isinstance(su3['p_v'], StructuredUnit) assert su3['p_v']['p'] == u.AU assert su3['p_v']['v'] == u.AU / u.day assert su3['t'] == u.yr su4 = StructuredUnit('(AU, AU/day), yr', (('p', 'v'), 't')) assert isinstance(su4['pv'], StructuredUnit) assert su4['pv']['p'] == u.AU assert su4['pv']['v'] == u.AU / u.day assert su4['t'] == u.yr def test_extreme_recursive_initialization(self): su = StructuredUnit('(yr,(AU,AU/day,(km,(day,day))),m)', ('t', ('p', 'v', ('h', ('d1', 'd2'))), 'l')) assert su.field_names == ('t', ['pvhd1d2', ('p', 'v', ['hd1d2', ('h', ['d1d2', ('d1', 'd2')])])], 'l') @pytest.mark.parametrize('names, invalid', [ [('t', ['p', 'v']), "['p', 'v']"], [('t', ['pv', 'p', 'v']), "['pv', 'p', 'v']"], [('t', ['pv', ['p', 'v']]), "['pv', ['p', 'v']"], [('t', ()), "()"], [('t', ('p', None)), "None"], [('t', ['pv', ('p', '')]), "''"]]) def test_initialization_names_invalid_list_errors(self, names, invalid): with pytest.raises(ValueError) as exc: StructuredUnit('(yr,(AU,AU/day)', names) assert f'invalid entry {invalid}' in str(exc) def test_looks_like_unit(self): su = StructuredUnit((self.p_unit, self.v_unit), ('p', 'v')) assert Unit(su) is su def test_initialize_with_float_dtype(self): su = StructuredUnit(('AU', 'AU/d'), self.pv_dtype) assert isinstance(su['p'], UnitBase) assert isinstance(su['v'], UnitBase) assert su['p'] == u.AU assert su['v'] == u.AU / u.day su = StructuredUnit((('km', 'km/s'), 'yr'), self.pv_t_dtype) assert isinstance(su['pv'], StructuredUnit) assert isinstance(su['pv']['p'], UnitBase) assert isinstance(su['t'], UnitBase) assert su['pv']['v'] == u.km / u.s su = StructuredUnit('(km, km/s), yr', self.pv_t_dtype) assert isinstance(su['pv'], StructuredUnit) assert isinstance(su['pv']['p'], UnitBase) assert isinstance(su['t'], UnitBase) assert su['pv']['v'] == u.km / u.s def test_initialize_with_structured_unit_for_names(self): su = StructuredUnit(('AU', 'AU/d'), names=('p', 'v')) su2 = StructuredUnit(('km', 'km/s'), names=su) assert su2.field_names == ('p', 'v') assert su2['p'] == u.km assert su2['v'] == u.km / u.s def test_initialize_single_field(self): su = StructuredUnit('AU', 'p') assert isinstance(su, StructuredUnit) assert isinstance(su['p'], UnitBase) assert su['p'] == u.AU su = StructuredUnit('AU') assert isinstance(su, StructuredUnit) assert isinstance(su['f0'], UnitBase) assert su['f0'] == u.AU def test_equality(self): su = StructuredUnit(('AU', 'AU/d'), self.pv_dtype) assert su == StructuredUnit(('AU', 'AU/d'), self.pv_dtype) assert su != StructuredUnit(('m', 'AU/d'), self.pv_dtype) # Names should be ignored. assert su == StructuredUnit(('AU', 'AU/d')) assert su == StructuredUnit(('AU', 'AU/d'), names=('q', 'w')) assert su != StructuredUnit(('m', 'm/s')) def test_parsing(self): su = Unit('AU, AU/d') assert isinstance(su, StructuredUnit) assert isinstance(su['f0'], UnitBase) assert isinstance(su['f1'], UnitBase) assert su['f0'] == u.AU assert su['f1'] == u.AU/u.day su2 = Unit('AU, AU/d, yr') assert isinstance(su2, StructuredUnit) assert su2 == StructuredUnit(('AU', 'AU/d', 'yr')) su2a = Unit('(AU, AU/d, yr)') assert isinstance(su2a, StructuredUnit) assert su2a == su2 su3 = Unit('(km, km/s), yr') assert isinstance(su3, StructuredUnit) assert su3 == StructuredUnit((('km', 'km/s'), 'yr')) su4 = Unit('km,') assert isinstance(su4, StructuredUnit) assert su4 == StructuredUnit((u.km,)) su5 = Unit('(m,s),') assert isinstance(su5, StructuredUnit) assert su5 == StructuredUnit(((u.m, u.s),)) ldbody_unit = Unit('Msun, 0.5rad^2, (au, au/day)') assert ldbody_unit == StructuredUnit( (u.Msun, Unit(u.rad**2 / 2), (u.AU, u.AU / u.day))) def test_str(self): su = StructuredUnit(((u.km, u.km/u.s), u.yr)) assert str(su) == '((km, km / s), yr)' assert Unit(str(su)) == su def test_repr(self): su = StructuredUnit(((u.km, u.km/u.s), u.yr)) assert repr(su) == 'Unit("((km, km / s), yr)")' assert eval(repr(su)) == su class TestStructuredUnitsCopyPickle(StructuredTestBaseWithUnits): def test_copy(self): su_copy = copy.copy(self.pv_t_unit) assert su_copy is not self.pv_t_unit assert su_copy == self.pv_t_unit assert su_copy._units is self.pv_t_unit._units def test_deepcopy(self): su_copy = copy.deepcopy(self.pv_t_unit) assert su_copy is not self.pv_t_unit assert su_copy == self.pv_t_unit assert su_copy._units is not self.pv_t_unit._units @pytest.mark.skipif(NUMPY_LT_1_21_1, reason="https://stackoverflow.com/q/69571643") def test_pickle(self, pickle_protocol): check_pickling_recovery(self.pv_t_unit, pickle_protocol) class TestStructuredUnitAsMapping(StructuredTestBaseWithUnits): def test_len(self): assert len(self.pv_unit) == 2 assert len(self.pv_t_unit) == 2 def test_keys(self): slv = list(self.pv_t_unit.keys()) assert slv == ['pv', 't'] def test_values(self): values = self.pv_t_unit.values() assert values == (self.pv_unit, self.t_unit) def test_field_names(self): field_names = self.pv_t_unit.field_names assert isinstance(field_names, tuple) assert field_names == (['pv', ('p', 'v')], 't') @pytest.mark.parametrize('iterable', [list, set]) def test_as_iterable(self, iterable): sl = iterable(self.pv_unit) assert isinstance(sl, iterable) assert sl == iterable(['p', 'v']) def test_as_dict(self): sd = dict(self.pv_t_unit) assert sd == {'pv': self.pv_unit, 't': self.t_unit} def test_contains(self): assert 'p' in self.pv_unit assert 'v' in self.pv_unit assert 't' not in self.pv_unit def test_setitem_fails(self): with pytest.raises(TypeError, match='item assignment'): self.pv_t_unit['t'] = u.Gyr class TestStructuredUnitMethods(StructuredTestBaseWithUnits): def test_physical_type_id(self): pv_ptid = self.pv_unit._get_physical_type_id() assert len(pv_ptid) == 2 assert pv_ptid.dtype.names == ('p', 'v') p_ptid = self.pv_unit['p']._get_physical_type_id() v_ptid = self.pv_unit['v']._get_physical_type_id() # Expected should be (subclass of) void, with structured object dtype. expected = np.array((p_ptid, v_ptid), [('p', 'O'), ('v', 'O')])[()] assert pv_ptid == expected # Names should be ignored in comparison. assert pv_ptid == np.array((p_ptid, v_ptid), 'O,O')[()] # Should be possible to address by field and by number. assert pv_ptid['p'] == p_ptid assert pv_ptid['v'] == v_ptid assert pv_ptid[0] == p_ptid assert pv_ptid[1] == v_ptid # More complicated version. pv_t_ptid = self.pv_t_unit._get_physical_type_id() t_ptid = self.t_unit._get_physical_type_id() assert pv_t_ptid == np.array((pv_ptid, t_ptid), 'O,O')[()] assert pv_t_ptid['pv'] == pv_ptid assert pv_t_ptid['t'] == t_ptid assert pv_t_ptid['pv'][1] == v_ptid def test_physical_type(self): pv_pt = self.pv_unit.physical_type assert pv_pt == np.array(('length', 'speed'), 'O,O')[()] pv_t_pt = self.pv_t_unit.physical_type assert pv_t_pt == np.array((pv_pt, 'time'), 'O,O')[()] def test_si(self): pv_t_si = self.pv_t_unit.si assert pv_t_si == self.pv_t_unit assert pv_t_si['pv']['v'].scale == 1000 def test_cgs(self): pv_t_cgs = self.pv_t_unit.cgs assert pv_t_cgs == self.pv_t_unit assert pv_t_cgs['pv']['v'].scale == 100000 def test_decompose(self): pv_t_decompose = self.pv_t_unit.decompose() assert pv_t_decompose['pv']['v'].scale == 1000 def test_is_equivalent(self): assert self.pv_unit.is_equivalent(('AU', 'AU/day')) assert not self.pv_unit.is_equivalent('m') assert not self.pv_unit.is_equivalent(('AU', 'AU')) # Names should be ignored. pv_alt = StructuredUnit('m,m/s', names=('q', 'w')) assert pv_alt.field_names != self.pv_unit.field_names assert self.pv_unit.is_equivalent(pv_alt) # Regular units should work too. assert not u.m.is_equivalent(self.pv_unit) def test_conversion(self): pv1 = self.pv_unit.to(('AU', 'AU/day'), self.pv) assert isinstance(pv1, np.ndarray) assert pv1.dtype == self.pv.dtype assert np.all(pv1['p'] * u.AU == self.pv['p'] * self.p_unit) assert np.all(pv1['v'] * u.AU / u.day == self.pv['v'] * self.v_unit) # Names should be from value. su2 = StructuredUnit((self.p_unit, self.v_unit), ('position', 'velocity')) pv2 = su2.to(('Mm', 'mm/s'), self.pv) assert pv2.dtype.names == ('p', 'v') assert pv2.dtype == self.pv.dtype # Check recursion. pv_t1 = self.pv_t_unit.to((('AU', 'AU/day'), 'Myr'), self.pv_t) assert isinstance(pv_t1, np.ndarray) assert pv_t1.dtype == self.pv_t.dtype assert np.all(pv_t1['pv']['p'] * u.AU == self.pv_t['pv']['p'] * self.p_unit) assert np.all(pv_t1['pv']['v'] * u.AU / u.day == self.pv_t['pv']['v'] * self.v_unit) assert np.all(pv_t1['t'] * u.Myr == self.pv_t['t'] * self.t_unit) # Passing in tuples should work. pv_t2 = self.pv_t_unit.to((('AU', 'AU/day'), 'Myr'), ((1., 0.1), 10.)) assert pv_t2['pv']['p'] == self.p_unit.to('AU', 1.) assert pv_t2['pv']['v'] == self.v_unit.to('AU/day', 0.1) assert pv_t2['t'] == self.t_unit.to('Myr', 10.) pv_t3 = self.pv_t_unit.to((('AU', 'AU/day'), 'Myr'), [((1., 0.1), 10.), ((2., 0.2), 20.)]) assert np.all(pv_t3['pv']['p'] == self.p_unit.to('AU', [1., 2.])) assert np.all(pv_t3['pv']['v'] == self.v_unit.to('AU/day', [0.1, 0.2])) assert np.all(pv_t3['t'] == self.t_unit.to('Myr', [10., 20.])) class TestStructuredUnitArithmatic(StructuredTestBaseWithUnits): def test_multiplication(self): pv_times_au = self.pv_unit * u.au assert isinstance(pv_times_au, StructuredUnit) assert pv_times_au.field_names == ('p', 'v') assert pv_times_au['p'] == self.p_unit * u.AU assert pv_times_au['v'] == self.v_unit * u.AU au_times_pv = u.au * self.pv_unit assert au_times_pv == pv_times_au pv_times_au2 = self.pv_unit * 'au' assert pv_times_au2 == pv_times_au au_times_pv2 = 'AU' * self.pv_unit assert au_times_pv2 == pv_times_au with pytest.raises(TypeError): self.pv_unit * self.pv_unit with pytest.raises(TypeError): 's,s' * self.pv_unit def test_division(self): pv_by_s = self.pv_unit / u.s assert isinstance(pv_by_s, StructuredUnit) assert pv_by_s.field_names == ('p', 'v') assert pv_by_s['p'] == self.p_unit / u.s assert pv_by_s['v'] == self.v_unit / u.s pv_by_s2 = self.pv_unit / 's' assert pv_by_s2 == pv_by_s with pytest.raises(TypeError): 1. / self.pv_unit with pytest.raises(TypeError): u.s / self.pv_unit class TestStructuredQuantity(StructuredTestBaseWithUnits): def test_initialization_and_keying(self): q_pv = Quantity(self.pv, self.pv_unit) q_p = q_pv['p'] assert isinstance(q_p, Quantity) assert isinstance(q_p.unit, UnitBase) assert np.all(q_p == self.pv['p'] * self.pv_unit['p']) q_v = q_pv['v'] assert isinstance(q_v, Quantity) assert isinstance(q_v.unit, UnitBase) assert np.all(q_v == self.pv['v'] * self.pv_unit['v']) q_pv_t = Quantity(self.pv_t, self.pv_t_unit) q_t = q_pv_t['t'] assert np.all(q_t == self.pv_t['t'] * self.pv_t_unit['t']) q_pv2 = q_pv_t['pv'] assert isinstance(q_pv2, Quantity) assert q_pv2.unit == self.pv_unit with pytest.raises(ValueError): Quantity(self.pv, self.pv_t_unit) with pytest.raises(ValueError): Quantity(self.pv_t, self.pv_unit) def test_initialization_with_unit_tuples(self): q_pv_t = Quantity(self.pv_t, (('km', 'km/s'), 's')) assert isinstance(q_pv_t.unit, StructuredUnit) assert q_pv_t.unit == self.pv_t_unit def test_initialization_with_string(self): q_pv_t = Quantity(self.pv_t, '(km, km/s), s') assert isinstance(q_pv_t.unit, StructuredUnit) assert q_pv_t.unit == self.pv_t_unit def test_initialization_by_multiplication_with_unit(self): q_pv_t = self.pv_t * self.pv_t_unit assert q_pv_t.unit is self.pv_t_unit assert np.all(q_pv_t.value == self.pv_t) assert not np.may_share_memory(q_pv_t, self.pv_t) q_pv_t2 = self.pv_t_unit * self.pv_t assert q_pv_t.unit is self.pv_t_unit # Not testing equality of structured Quantity here. assert np.all(q_pv_t2.value == q_pv_t.value) def test_initialization_by_shifting_to_unit(self): q_pv_t = self.pv_t << self.pv_t_unit assert q_pv_t.unit is self.pv_t_unit assert np.all(q_pv_t.value == self.pv_t) assert np.may_share_memory(q_pv_t, self.pv_t) def test_getitem(self): q_pv_t = Quantity(self.pv_t, self.pv_t_unit) q_pv_t01 = q_pv_t[:2] assert isinstance(q_pv_t01, Quantity) assert q_pv_t01.unit == q_pv_t.unit assert np.all(q_pv_t01['t'] == q_pv_t['t'][:2]) q_pv_t1 = q_pv_t[1] assert isinstance(q_pv_t1, Quantity) assert q_pv_t1.unit == q_pv_t.unit assert q_pv_t1.shape == () assert q_pv_t1['t'] == q_pv_t['t'][1] def test_value(self): q_pv_t = Quantity(self.pv_t, self.pv_t_unit) value = q_pv_t.value assert type(value) is np.ndarray assert np.all(value == self.pv_t) value1 = q_pv_t[1].value assert type(value1) is np.void assert np.all(value1 == self.pv_t[1]) def test_conversion(self): q_pv = Quantity(self.pv, self.pv_unit) q1 = q_pv.to(('AU', 'AU/day')) assert isinstance(q1, Quantity) assert q1['p'].unit == u.AU assert q1['v'].unit == u.AU / u.day assert np.all(q1['p'] == q_pv['p'].to(u.AU)) assert np.all(q1['v'] == q_pv['v'].to(u.AU/u.day)) q2 = q_pv.to(self.pv_unit) assert q2['p'].unit == self.p_unit assert q2['v'].unit == self.v_unit assert np.all(q2['p'].value == self.pv['p']) assert np.all(q2['v'].value == self.pv['v']) assert not np.may_share_memory(q2, q_pv) pv1 = q_pv.to_value(('AU', 'AU/day')) assert type(pv1) is np.ndarray assert np.all(pv1['p'] == q_pv['p'].to_value(u.AU)) assert np.all(pv1['v'] == q_pv['v'].to_value(u.AU/u.day)) pv11 = q_pv[1].to_value(('AU', 'AU/day')) assert type(pv11) is np.void assert pv11 == pv1[1] q_pv_t = Quantity(self.pv_t, self.pv_t_unit) q2 = q_pv_t.to((('kpc', 'kpc/Myr'), 'Myr')) assert q2['pv']['p'].unit == u.kpc assert q2['pv']['v'].unit == u.kpc / u.Myr assert q2['t'].unit == u.Myr assert np.all(q2['pv']['p'] == q_pv_t['pv']['p'].to(u.kpc)) assert np.all(q2['pv']['v'] == q_pv_t['pv']['v'].to(u.kpc/u.Myr)) assert np.all(q2['t'] == q_pv_t['t'].to(u.Myr)) def test_conversion_via_lshift(self): q_pv = Quantity(self.pv, self.pv_unit) q1 = q_pv << StructuredUnit(('AU', 'AU/day')) assert isinstance(q1, Quantity) assert q1['p'].unit == u.AU assert q1['v'].unit == u.AU / u.day assert np.all(q1['p'] == q_pv['p'].to(u.AU)) assert np.all(q1['v'] == q_pv['v'].to(u.AU/u.day)) q2 = q_pv << self.pv_unit assert q2['p'].unit == self.p_unit assert q2['v'].unit == self.v_unit assert np.all(q2['p'].value == self.pv['p']) assert np.all(q2['v'].value == self.pv['v']) assert np.may_share_memory(q2, q_pv) q_pv_t = Quantity(self.pv_t, self.pv_t_unit) q2 = q_pv_t << '(kpc,kpc/Myr),Myr' assert q2['pv']['p'].unit == u.kpc assert q2['pv']['v'].unit == u.kpc / u.Myr assert q2['t'].unit == u.Myr assert np.all(q2['pv']['p'] == q_pv_t['pv']['p'].to(u.kpc)) assert np.all(q2['pv']['v'] == q_pv_t['pv']['v'].to(u.kpc/u.Myr)) assert np.all(q2['t'] == q_pv_t['t'].to(u.Myr)) def test_inplace_conversion(self): q_pv = Quantity(self.pv, self.pv_unit) q1 = q_pv.copy() q_link = q1 q1 <<= StructuredUnit(('AU', 'AU/day')) assert q1 is q_link assert q1['p'].unit == u.AU assert q1['v'].unit == u.AU / u.day assert np.all(q1['p'] == q_pv['p'].to(u.AU)) assert np.all(q1['v'] == q_pv['v'].to(u.AU/u.day)) q_pv_t = Quantity(self.pv_t, self.pv_t_unit) q2 = q_pv_t.copy() q_link = q2 q2 <<= '(kpc,kpc/Myr),Myr' assert q2 is q_link assert q2['pv']['p'].unit == u.kpc assert q2['pv']['v'].unit == u.kpc / u.Myr assert q2['t'].unit == u.Myr assert np.all(q2['pv']['p'] == q_pv_t['pv']['p'].to(u.kpc)) assert np.all(q2['pv']['v'] == q_pv_t['pv']['v'].to(u.kpc/u.Myr)) assert np.all(q2['t'] == q_pv_t['t'].to(u.Myr)) def test_si(self): q_pv_t = Quantity(self.pv_t, self.pv_t_unit) q_pv_t_si = q_pv_t.si assert_array_equal(q_pv_t_si, q_pv_t.to('(m,m/s),s')) def test_cgs(self): q_pv_t = Quantity(self.pv_t, self.pv_t_unit) q_pv_t_cgs = q_pv_t.cgs assert_array_equal(q_pv_t_cgs, q_pv_t.to('(cm,cm/s),s')) def test_equality(self): q_pv = Quantity(self.pv, self.pv_unit) equal = q_pv == q_pv not_equal = q_pv != q_pv assert np.all(equal) assert not np.any(not_equal) equal2 = q_pv == q_pv[1] not_equal2 = q_pv != q_pv[1] assert np.all(equal2 == [False, True, False]) assert np.all(not_equal2 != equal2) q1 = q_pv.to(('AU', 'AU/day')) # Ensure same conversion is done, by placing q1 first. assert np.all(q1 == q_pv) assert not np.any(q1 != q_pv) # Check different names in dtype. assert np.all(q1.value * u.Unit('AU, AU/day') == q_pv) assert not np.any(q1.value * u.Unit('AU, AU/day') != q_pv) assert (q_pv == 'b') is False assert ('b' != q_pv) is True q_pv_t = Quantity(self.pv_t, self.pv_t_unit) assert np.all((q_pv_t[2] == q_pv_t) == [False, False, True]) assert np.all((q_pv_t[2] != q_pv_t) != [False, False, True]) assert (q_pv == q_pv_t) is False assert (q_pv_t != q_pv) is True def test_setitem(self): q_pv = Quantity(self.pv, self.pv_unit) q_pv[1] = (2., 2.) * self.pv_unit assert q_pv[1].value == np.array((2., 2.), self.pv_dtype) q_pv[1:2] = (1., 0.5) * u.Unit('AU, AU/day') assert q_pv['p'][1] == 1. * u.AU assert q_pv['v'][1] == 0.5 * u.AU / u.day q_pv['v'] = 1. * u.km / u.s assert np.all(q_pv['v'] == 1. * u.km / u.s) with pytest.raises(u.UnitsError): q_pv[1] = (1., 1.) * u.Unit('AU, AU') with pytest.raises(u.UnitsError): q_pv['v'] = 1. * u.km q_pv_t = Quantity(self.pv_t, self.pv_t_unit) q_pv_t[1] = ((2., 2.), 3.) * self.pv_t_unit assert q_pv_t[1].value == np.array(((2., 2.), 3.), self.pv_t_dtype) q_pv_t[1:2] = ((1., 0.5), 5.) * u.Unit('(AU, AU/day), yr') assert q_pv_t['pv'][1] == (1., 0.5) * u.Unit('AU, AU/day') assert q_pv_t['t'][1] == 5. * u.yr q_pv_t['pv'] = (1., 0.5) * self.pv_unit assert np.all(q_pv_t['pv'] == (1., 0.5) * self.pv_unit) class TestStructuredQuantityFunctions(StructuredTestBaseWithUnits): @classmethod def setup_class(self): super().setup_class() self.q_pv = self.pv << self.pv_unit self.q_pv_t = self.pv_t << self.pv_t_unit def test_empty_like(self): z = np.empty_like(self.q_pv) assert z.dtype == self.pv_dtype assert z.unit == self.pv_unit assert z.shape == self.pv.shape @pytest.mark.parametrize('func', [np.zeros_like, np.ones_like]) def test_zeros_ones_like(self, func): z = func(self.q_pv) assert z.dtype == self.pv_dtype assert z.unit == self.pv_unit assert z.shape == self.pv.shape assert_array_equal(z, func(self.pv) << self.pv_unit) class TestStructuredSpecificTypeQuantity(StructuredTestBaseWithUnits): def setup_class(self): super().setup_class() class PositionVelocity(u.SpecificTypeQuantity): _equivalent_unit = self.pv_unit self.PositionVelocity = PositionVelocity def test_init(self): pv = self.PositionVelocity(self.pv, self.pv_unit) assert isinstance(pv, self.PositionVelocity) assert type(pv['p']) is u.Quantity assert_array_equal(pv['p'], self.pv['p'] << self.pv_unit['p']) pv2 = self.PositionVelocity(self.pv, 'AU,AU/day') assert_array_equal(pv2['p'], self.pv['p'] << u.AU) def test_error_on_non_equivalent_unit(self): with pytest.raises(u.UnitsError): self.PositionVelocity(self.pv, 'AU') with pytest.raises(u.UnitsError): self.PositionVelocity(self.pv, 'AU,yr') class TestStructuredLogUnit: def setup_class(self): self.mag_time_dtype = np.dtype([('mag', 'f8'), ('t', 'f8')]) self.mag_time = np.array([(20., 10.), (25., 100.)], self.mag_time_dtype) def test_unit_initialization(self): mag_time_unit = StructuredUnit((u.STmag, u.s), self.mag_time_dtype) assert mag_time_unit['mag'] == u.STmag assert mag_time_unit['t'] == u.s mag_time_unit2 = u.Unit('mag(ST),s') assert mag_time_unit2 == mag_time_unit def test_quantity_initialization(self): su = u.Unit('mag(ST),s') mag_time = self.mag_time << su assert isinstance(mag_time['mag'], u.Magnitude) assert isinstance(mag_time['t'], u.Quantity) assert mag_time.unit == su assert_array_equal(mag_time['mag'], self.mag_time['mag'] << u.STmag) assert_array_equal(mag_time['t'], self.mag_time['t'] << u.s) def test_quantity_si(self): mag_time = self.mag_time << u.Unit('mag(ST),yr') mag_time_si = mag_time.si assert_array_equal(mag_time_si['mag'], mag_time['mag'].si) assert_array_equal(mag_time_si['t'], mag_time['t'].si) class TestStructuredMaskedQuantity(StructuredTestBaseWithUnits): """Somewhat minimal tests. Conversion is most stringent.""" def setup_class(self): super().setup_class() self.qpv = self.pv << self.pv_unit self.pv_mask = np.array([(True, False), (False, False), (False, True)], [('p', bool), ('v', bool)]) self.mpv = Masked(self.qpv, mask=self.pv_mask) def test_init(self): assert isinstance(self.mpv, Masked) assert isinstance(self.mpv, Quantity) assert_array_equal(self.mpv.unmasked, self.qpv) assert_array_equal(self.mpv.mask, self.pv_mask) def test_slicing(self): mp = self.mpv['p'] assert isinstance(mp, Masked) assert isinstance(mp, Quantity) assert_array_equal(mp.unmasked, self.qpv['p']) assert_array_equal(mp.mask, self.pv_mask['p']) def test_conversion(self): mpv = self.mpv.to('AU,AU/day') assert isinstance(mpv, Masked) assert isinstance(mpv, Quantity) assert_array_equal(mpv.unmasked, self.qpv.to('AU,AU/day')) assert_array_equal(mpv.mask, self.pv_mask) assert np.all(mpv == self.mpv) def test_si(self): mpv = self.mpv.si assert isinstance(mpv, Masked) assert isinstance(mpv, Quantity) assert_array_equal(mpv.unmasked, self.qpv.si) assert_array_equal(mpv.mask, self.pv_mask) assert np.all(mpv == self.mpv) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/tests/test_structured_erfa_ufuncs.py0000644000175100001710000004676700000000000024473 0ustar00vstsdocker# coding: utf-8 # Licensed under a 3-clause BSD style license - see LICENSE.rst """ Test Structured units and quantities specifically with the ERFA ufuncs. """ import pytest import numpy as np from numpy.testing import assert_array_equal import erfa from erfa import ufunc as erfa_ufunc from astropy import units as u from astropy.tests.helper import assert_quantity_allclose from astropy.utils.introspection import minversion ERFA_LE_2_0_0 = not minversion(erfa, '2.0.0.1') class TestPVUfuncs: def setup_class(self): self.pv_unit = u.Unit('AU,AU/day') self.pv_value = np.array([([1., 0., 0.], [0., 0.0125, 0.]), ([0., 1., 0.], [-.0125, 0., 0.])], dtype=erfa_ufunc.dt_pv) self.pv = self.pv_value << self.pv_unit def test_cpv(self): pv_copy = erfa_ufunc.cpv(self.pv) assert_array_equal(pv_copy, self.pv) assert not np.may_share_memory(pv_copy, self.pv) def test_p2pv(self): p2pv = erfa_ufunc.p2pv(self.pv['p']) assert_array_equal(p2pv['p'], self.pv['p']) assert_array_equal(p2pv['v'], np.zeros(self.pv.shape+(3,), float) << u.m/u.s) @pytest.mark.xfail(erfa.__version__ <= '2.0.0', reason='erfa bug; https://github.com/liberfa/pyerfa/issues/70)') def test_p2pv_inplace(self): # TODO: fix np.zeros_like. out = np.zeros_like(self.pv_value) << self.pv_unit p2pv = erfa_ufunc.p2pv(self.pv['p'], out=out) assert out is p2pv assert_array_equal(p2pv['p'], self.pv['p']) assert_array_equal(p2pv['v'], np.zeros(self.pv.shape+(3,), float) << u.m/u.s) def test_pv2p(self): p = erfa_ufunc.pv2p(self.pv) assert_array_equal(p, self.pv['p']) out = np.zeros_like(p) p2 = erfa_ufunc.pv2p(self.pv, out=out) assert out is p2 assert_array_equal(p2, self.pv['p']) def test_pv2s(self): theta, phi, r, td, pd, rd = erfa_ufunc.pv2s(self.pv) assert theta.unit == u.radian assert_quantity_allclose(theta, [0, 90] * u.deg) # longitude assert phi.unit == u.radian assert_array_equal(phi.value, np.zeros(self.pv.shape)) # latitude assert r.unit == u.AU assert_array_equal(r.value, np.ones(self.pv.shape)) assert td.unit == u.radian/u.day assert_array_equal(td.value, np.array([0.0125]*2)) assert pd.unit == u.radian/u.day assert_array_equal(pd.value, np.zeros(self.pv.shape)) assert rd.unit == u.AU/u.day assert_array_equal(rd.value, np.zeros(self.pv.shape)) def test_pv2s_non_standard_units(self): pv = self.pv_value << u.Unit('Pa,Pa/m') theta, phi, r, td, pd, rd = erfa_ufunc.pv2s(pv) assert theta.unit == u.radian assert_quantity_allclose(theta, [0, 90] * u.deg) # longitude assert phi.unit == u.radian assert_array_equal(phi.value, np.zeros(pv.shape)) # latitude assert r.unit == u.Pa assert_array_equal(r.value, np.ones(pv.shape)) assert td.unit == u.radian/u.m assert_array_equal(td.value, np.array([0.0125]*2)) assert pd.unit == u.radian/u.m assert_array_equal(pd.value, np.zeros(pv.shape)) assert rd.unit == u.Pa/u.m assert_array_equal(rd.value, np.zeros(pv.shape)) @pytest.mark.xfail(reason=( 'erfa ufuncs cannot take different names; it is not yet clear whether ' 'this is changeable; see https://github.com/liberfa/pyerfa/issues/77')) def test_pv2s_non_standard_names_and_units(self): pv_value = np.array(self.pv_value, dtype=[('pos', 'f8'), ('vel', 'f8')]) pv = pv_value << u.Unit('Pa,Pa/m') theta, phi, r, td, pd, rd = erfa_ufunc.pv2s(pv) assert theta.unit == u.radian assert_quantity_allclose(theta, [0, 90] * u.deg) # longitude assert phi.unit == u.radian assert_array_equal(phi.value, np.zeros(pv.shape)) # latitude assert r.unit == u.Pa assert_array_equal(r.value, np.ones(pv.shape)) assert td.unit == u.radian/u.m assert_array_equal(td.value, np.array([0.0125]*2)) assert pd.unit == u.radian/u.m assert_array_equal(pd.value, np.zeros(pv.shape)) assert rd.unit == u.Pa/u.m assert_array_equal(rd.value, np.zeros(pv.shape)) def test_s2pv(self): theta, phi, r, td, pd, rd = erfa_ufunc.pv2s(self.pv) # On purpose change some of the units away from expected by s2pv. pv = erfa_ufunc.s2pv(theta.to(u.deg), phi, r.to(u.m), td.to(u.deg/u.day), pd, rd.to(u.m/u.s)) assert pv.unit == u.StructuredUnit('m, m/s', names=('p', 'v')) assert_quantity_allclose(pv['p'], self.pv['p'], atol=1*u.m, rtol=0) assert_quantity_allclose(pv['v'], self.pv['v'], atol=1*u.mm/u.s, rtol=0) def test_pvstar(self): ra, dec, pmr, pmd, px, rv, stat = erfa_ufunc.pvstar(self.pv) assert_array_equal(stat, np.zeros(self.pv.shape, dtype='i4')) assert ra.unit == u.radian assert_quantity_allclose(ra, [0, 90] * u.deg) assert dec.unit == u.radian assert_array_equal(dec.value, np.zeros(self.pv.shape)) # latitude assert pmr.unit == u.radian/u.year assert_quantity_allclose(pmr, [0.0125, 0.0125]*u.radian/u.day) assert pmd.unit == u.radian/u.year assert_array_equal(pmd.value, np.zeros(self.pv.shape)) assert px.unit == u.arcsec assert_quantity_allclose(px, 1*u.radian) assert rv.unit == u.km / u.s assert_array_equal(rv.value, np.zeros(self.pv.shape)) def test_starpv(self): ra, dec, pmr, pmd, px, rv, stat = erfa_ufunc.pvstar(self.pv) pv, stat = erfa_ufunc.starpv(ra.to(u.deg), dec.to(u.deg), pmr, pmd, px, rv.to(u.m/u.s)) assert_array_equal(stat, np.zeros(self.pv.shape, dtype='i4')) assert pv.unit == self.pv.unit # Roundtrip is not as good as hoped on 32bit, not clear why. # But proper motions are ridiculously high... assert_quantity_allclose(pv['p'], self.pv['p'], atol=1*u.m, rtol=0) assert_quantity_allclose(pv['v'], self.pv['v'], atol=1*u.m/u.s, rtol=0) def test_pvtob(self): pv = erfa_ufunc.pvtob([90, 0]*u.deg, 0.*u.deg, 100*u.km, 0*u.deg, 0*u.deg, 0*u.deg, 90*u.deg) assert pv.unit == u.StructuredUnit('m, m/s', names=('p', 'v')) assert pv.unit['v'] == u.m / u.s assert_quantity_allclose(pv['p'], [[-6478, 0, 0], [0, 6478, 0]]*u.km, atol=2*u.km) assert_quantity_allclose(pv['v'], [[0, -0.5, 0], [-0.5, 0, 0]]*u.km/u.s, atol=0.1*u.km/u.s) def test_pvdpv(self): pvdpv = erfa_ufunc.pvdpv(self.pv, self.pv) assert pvdpv['pdp'].unit == self.pv.unit['p'] ** 2 assert pvdpv['pdv'].unit == self.pv.unit['p'] * self.pv.unit['v'] assert_array_equal(pvdpv['pdp'], np.einsum('...i,...i->...', self.pv['p'], self.pv['p'])) assert_array_equal(pvdpv['pdv'], 2*np.einsum('...i,...i->...', self.pv['p'], self.pv['v'])) z_axis = u.Quantity( np.array(([0, 0, 1], [0, 0, 0]), erfa_ufunc.dt_pv), '1,1/s') pvdpv2 = erfa_ufunc.pvdpv(self.pv, z_axis) assert pvdpv2['pdp'].unit == self.pv.unit['p'] assert pvdpv2['pdv'].unit == self.pv.unit['v'] assert_array_equal(pvdpv2['pdp'].value, np.zeros(self.pv.shape)) assert_array_equal(pvdpv2['pdv'].value, np.zeros(self.pv.shape)) def test_pvxpv(self): pvxpv = erfa_ufunc.pvxpv(self.pv, self.pv) assert pvxpv['p'].unit == self.pv.unit['p'] ** 2 assert pvxpv['v'].unit == self.pv.unit['p'] * self.pv.unit['v'] assert_array_equal(pvxpv['p'].value, np.zeros(self.pv['p'].shape)) assert_array_equal(pvxpv['v'].value, np.zeros(self.pv['v'].shape)) z_axis = u.Quantity( np.array(([0, 0, 1], [0, 0, 0]), erfa_ufunc.dt_pv), '1,1/s') pvxpv2 = erfa_ufunc.pvxpv(self.pv, z_axis) assert pvxpv2['p'].unit == self.pv.unit['p'] assert pvxpv2['v'].unit == self.pv.unit['v'] assert_array_equal(pvxpv2['p'], [[0., -1, 0.], [1., 0., 0.]] * u.AU) assert_array_equal(pvxpv2['v'], [[0.0125, 0., 0.], [0., 0.0125, 0.]] * u.AU / u.day) def test_pvm(self): pm, vm = erfa_ufunc.pvm(self.pv) assert pm.unit == self.pv.unit['p'] assert vm.unit == self.pv.unit['v'] assert_array_equal(pm, np.linalg.norm(self.pv['p'], axis=-1)) assert_array_equal(vm, np.linalg.norm(self.pv['v'], axis=-1)) def test_pvmpv(self): pvmpv = erfa_ufunc.pvmpv(self.pv, self.pv) assert pvmpv.unit == self.pv.unit assert_array_equal(pvmpv['p'], 0*self.pv['p']) assert_array_equal(pvmpv['v'], 0*self.pv['v']) def test_pvppv(self): pvppv = erfa_ufunc.pvppv(self.pv, self.pv) assert pvppv.unit == self.pv.unit assert_array_equal(pvppv['p'], 2*self.pv['p']) assert_array_equal(pvppv['v'], 2*self.pv['v']) def test_pvu(self): pvu = erfa_ufunc.pvu(86400*u.s, self.pv) assert pvu.unit == self.pv.unit assert_array_equal(pvu['p'], self.pv['p'] + 1*u.day*self.pv['v']) assert_array_equal(pvu['v'], self.pv['v']) def test_pvup(self): pvup = erfa_ufunc.pvup(86400*u.s, self.pv) assert pvup.unit == self.pv.unit['p'] assert_array_equal(pvup, self.pv['p'] + 1*u.day*self.pv['v']) def test_sxpv(self): # Not a realistic example!! sxpv = erfa_ufunc.sxpv(10., self.pv) assert sxpv.unit == self.pv.unit assert_array_equal(sxpv['p'], self.pv['p']*10) assert_array_equal(sxpv['v'], self.pv['v']*10) sxpv2 = erfa_ufunc.sxpv(30.*u.s, self.pv) assert sxpv2.unit == u.StructuredUnit('AU s,AU s/d', names=('p', 'v')) assert_array_equal(sxpv2['p'], self.pv['p']*30*u.s) assert_array_equal(sxpv2['v'], self.pv['v']*30*u.s) def test_s2xpv(self): # Not a realistic example!! s2xpv = erfa_ufunc.s2xpv(10., 1*u.s, self.pv) assert s2xpv.unit == u.StructuredUnit('AU,AU s/d', names=('p', 'v')) assert_array_equal(s2xpv['p'], self.pv['p']*10) assert_array_equal(s2xpv['v'], self.pv['v']*u.s) @pytest.mark.parametrize('r', [ np.eye(3), np.array([[0., -1., 0.], [1., 0., 0.], [0., 0., 1.]]), np.eye(3) / u.s]) def test_rxpv(self, r): result = erfa_ufunc.rxpv(r, self.pv) assert_array_equal(result['p'], np.einsum('...ij,...j->...i', r, self.pv['p'])) assert_array_equal(result['v'], np.einsum('...ij,...j->...i', r, self.pv['v'])) @pytest.mark.parametrize('r', [ np.eye(3), np.array([[0., -1., 0.], [1., 0., 0.], [0., 0., 1.]]), np.eye(3) / u.s]) def test_trxpv(self, r): result = erfa_ufunc.trxpv(r, self.pv) assert_array_equal(result['p'], np.einsum('...ij,...j->...i', r.T, self.pv['p'])) assert_array_equal(result['v'], np.einsum('...ij,...j->...i', r.T, self.pv['v'])) @pytest.mark.xfail(erfa.__version__ < '1.7.3.1', reason='dt_eraLDBODY incorrectly defined', scope='class') class TestEraStructUfuncs: def setup_class(self): # From t_ldn in t_erfa_c.c ldbody = np.array( [(0.00028574, 3e-10, ([-7.81014427, -5.60956681, -1.98079819], [0.0030723249, -0.00406995477, -0.00181335842])), (0.00095435, 3e-9, ([0.738098796, 4.63658692, 1.9693136], [-0.00755816922, 0.00126913722, 0.000727999001])), (1.0, 6e-6, ([-0.000712174377, -0.00230478303, -0.00105865966], [6.29235213e-6, -3.30888387e-7, -2.96486623e-7]))], dtype=erfa_ufunc.dt_eraLDBODY) ldbody_unit = u.StructuredUnit('Msun,radian,(AU,AU/day)', ldbody.dtype) self.ldbody = ldbody << ldbody_unit self.ob = [-0.974170437, -0.2115201, -0.0917583114] << u.AU self.sc = np.array([-0.763276255, -0.608633767, -0.216735543]) # From t_atciq in t_erfa_c.c astrom, eo = erfa_ufunc.apci13(2456165.5, 0.401182685) self.astrom_unit = u.StructuredUnit( 'yr,AU,1,AU,1,1,1,rad,rad,rad,rad,1,1,1,rad,rad,rad', astrom.dtype) self.astrom = astrom << self.astrom_unit self.rc = 2.71 * u.rad self.dc = 0.174 * u.rad self.pr = 1e-5 * u.rad/u.year self.pd = 5e-6 * u.rad/u.year self.px = 0.1 * u.arcsec self.rv = 55.0 * u.km/u.s def test_ldn_basic(self): sn = erfa_ufunc.ldn(self.ldbody, self.ob, self.sc) assert_quantity_allclose(sn, [-0.7632762579693333866, -0.6086337636093002660, -0.2167355420646328159] * u.one, atol=1e-12, rtol=0) def test_ldn_in_other_unit(self): ldbody = self.ldbody.to('kg,rad,(m,m/s)') ob = self.ob.to('m') sn = erfa_ufunc.ldn(ldbody, ob, self.sc) assert_quantity_allclose(sn, [-0.7632762579693333866, -0.6086337636093002660, -0.2167355420646328159] * u.one, atol=1e-12, rtol=0) def test_ldn_in_SI(self): sn = erfa_ufunc.ldn(self.ldbody.si, self.ob.si, self.sc) assert_quantity_allclose(sn, [-0.7632762579693333866, -0.6086337636093002660, -0.2167355420646328159] * u.one, atol=1e-12, rtol=0) def test_aper(self): along = self.astrom['along'] astrom2 = erfa_ufunc.aper(10*u.deg, self.astrom) assert astrom2['eral'].unit == u.radian assert_quantity_allclose(astrom2['eral'], along+10*u.deg) astrom3 = self.astrom.to('s,km,1,km,1,1,1,deg,deg,deg,deg,1,1,1,rad,rad,rad') astrom4 = erfa_ufunc.aper(10*u.deg, astrom3) assert astrom3['eral'].unit == u.rad assert astrom4['eral'].unit == u.deg assert astrom4.unit == 's,km,1,km,1,1,1,deg,deg,deg,deg,1,1,1,deg,rad,rad' assert_quantity_allclose(astrom4['eral'], along+10*u.deg) def test_atciq_basic(self): ri, di = erfa_ufunc.atciq(self.rc, self.dc, self.pr, self.pd, self.px, self.rv, self.astrom) assert_quantity_allclose(ri, 2.710121572968696744*u.rad) assert_quantity_allclose(di, 0.1729371367219539137*u.rad) def test_atciq_in_other_unit(self): astrom = self.astrom.to('s,km,1,km,1,1,1,deg,deg,deg,deg,1,1,1,deg,deg,deg') ri, di = erfa_ufunc.atciq(self.rc.to(u.deg), self.dc.to(u.deg), self.pr.to(u.mas/u.yr), self.pd.to(u.mas/u.yr), self.px, self.rv.to(u.m/u.s), astrom) assert_quantity_allclose(ri, 2.710121572968696744*u.rad, atol=1e-12*u.rad) assert_quantity_allclose(di, 0.1729371367219539137*u.rad, atol=1e-12*u.rad) def test_atciqn(self): ri, di = erfa_ufunc.atciqn(self.rc.to(u.deg), self.dc.to(u.deg), self.pr.to(u.mas/u.yr), self.pd.to(u.mas/u.yr), self.px, self.rv.to(u.m/u.s), self.astrom.si, self.ldbody.si) assert_quantity_allclose(ri, 2.710122008104983335*u.rad, atol=1e-12*u.rad) assert_quantity_allclose(di, 0.1729371916492767821*u.rad, atol=1e-12*u.rad) def test_atciqz(self): ri, di = erfa_ufunc.atciqz(self.rc.to(u.deg), self.dc.to(u.deg), self.astrom.si) assert_quantity_allclose(ri, 2.709994899247256984*u.rad, atol=1e-12*u.rad) assert_quantity_allclose(di, 0.1728740720984931891*u.rad, atol=1e-12*u.rad) def test_aticq(self): ri = 2.710121572969038991 * u.rad di = 0.1729371367218230438 * u.rad rc, dc = erfa_ufunc.aticq(ri.to(u.deg), di.to(u.deg), self.astrom.si) assert_quantity_allclose(rc, 2.710126504531716819*u.rad, atol=1e-12*u.rad) assert_quantity_allclose(dc, 0.1740632537627034482*u.rad, atol=1e-12*u.rad) def test_aticqn(self): ri = 2.709994899247599271 * u.rad di = 0.1728740720983623469 * u.rad rc, dc = erfa_ufunc.aticqn(ri.to(u.deg), di.to(u.deg), self.astrom.si, self.ldbody.si) assert_quantity_allclose(rc, 2.709999575033027333*u.rad, atol=1e-12*u.rad) assert_quantity_allclose(dc, 0.1739999656316469990*u.rad, atol=1e-12*u.rad) def test_atioq_atoiq(self): astrom, _ = erfa_ufunc.apio13(2456384.5, 0.969254051, 0.1550675, -0.527800806, -1.2345856, 2738.0, 2.47230737e-7, 1.82640464e-6, 731.0, 12.8, 0.59, 0.55) astrom = astrom << self.astrom_unit ri = 2.710121572969038991 * u.rad di = 0.1729371367218230438 * u.rad aob, zob, hob, dob, rob = erfa_ufunc.atioq(ri.to(u.deg), di.to(u.deg), astrom.si) assert_quantity_allclose(aob, 0.9233952224895122499e-1*u.rad, atol=1e-12*u.rad) assert_quantity_allclose(zob, 1.407758704513549991*u.rad, atol=1e-12*u.rad) assert_quantity_allclose(hob, -0.9247619879881698140e-1*u.rad, atol=1e-12*u.rad) assert_quantity_allclose(dob, 0.1717653435756234676*u.rad, atol=1e-12*u.rad) assert_quantity_allclose(rob, 2.710085107988480746*u.rad, atol=1e-12*u.rad) # Sadly does not just use the values from above. ob1 = 2.710085107986886201 * u.rad ob2 = 0.1717653435758265198 * u.rad ri2, di2 = erfa_ufunc.atoiq("R", ob1.to(u.deg), ob2.to(u.deg), astrom.si) assert_quantity_allclose(ri2, 2.710121574447540810*u.rad, atol=1e-12*u.rad) assert_quantity_allclose(di2, 0.17293718391166087785*u.rad, atol=1e-12*u.rad) @pytest.mark.xfail(erfa.__version__ < '2.0.0', reason='comparisons changed') def test_apio(self): sp = -3.01974337e-11 * u.rad theta = 3.14540971 * u.rad elong = -0.527800806 * u.rad phi = -1.2345856 * u.rad hm = 2738.0 * u.m xp = 2.47230737e-7 * u.rad yp = 1.82640464e-6 * u.rad refa = 0.000201418779 * u.rad refb = -2.36140831e-7 * u.rad astrom = erfa_ufunc.apio(sp.to(u.deg), theta, elong, phi, hm.to(u.km), xp, yp, refa, refb) assert astrom.unit == self.astrom_unit for name, value in [ ('along', -0.5278008060295995734), ('xpl', 0.1133427418130752958e-5), ('ypl', 0.1453347595780646207e-5), ('sphi', -0.9440115679003211329), ('cphi', 0.3299123514971474711), ('diurab', 0.5135843661699913529e-6), ('eral', 2.617608903970400427), ('refa', 0.2014187790000000000e-3), ('refb', -0.2361408310000000000e-6)]: assert_quantity_allclose(astrom[name], value * self.astrom_unit[name], rtol=1e-12, atol=0*self.astrom_unit[name]) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/tests/test_units.py0000644000175100001710000005700100000000000021030 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """Regression tests for the units package.""" import pickle from fractions import Fraction import pytest import numpy as np from numpy.testing import assert_allclose from astropy import units as u from astropy import constants as c from astropy.units import utils def test_initialisation(): assert u.Unit(u.m) is u.m ten_meter = u.Unit(10.*u.m) assert ten_meter == u.CompositeUnit(10., [u.m], [1]) assert u.Unit(ten_meter) is ten_meter assert u.Unit(10.*ten_meter) == u.CompositeUnit(100., [u.m], [1]) foo = u.Unit('foo', (10. * ten_meter)**2, namespace=locals()) assert foo == u.CompositeUnit(10000., [u.m], [2]) assert u.Unit('m') == u.m assert u.Unit('') == u.dimensionless_unscaled assert u.one == u.dimensionless_unscaled assert u.Unit('10 m') == ten_meter assert u.Unit(10.) == u.CompositeUnit(10., [], []) assert u.Unit() == u.dimensionless_unscaled def test_invalid_power(): x = u.m ** Fraction(1, 3) assert isinstance(x.powers[0], Fraction) x = u.m ** Fraction(1, 2) assert isinstance(x.powers[0], float) # Test the automatic conversion to a fraction x = u.m ** (1. / 3.) assert isinstance(x.powers[0], Fraction) def test_invalid_compare(): assert not (u.m == u.s) def test_convert(): assert u.h._get_converter(u.s)(1) == 3600 def test_convert_fail(): with pytest.raises(u.UnitsError): u.cm.to(u.s, 1) with pytest.raises(u.UnitsError): (u.cm / u.s).to(u.m, 1) def test_composite(): assert (u.cm / u.s * u.h)._get_converter(u.m)(1) == 36 assert u.cm * u.cm == u.cm ** 2 assert u.cm * u.cm * u.cm == u.cm ** 3 assert u.Hz.to(1000 * u.Hz, 1) == 0.001 def test_str(): assert str(u.cm) == "cm" def test_repr(): assert repr(u.cm) == 'Unit("cm")' def test_represents(): assert u.m.represents is u.m assert u.km.represents.scale == 1000. assert u.km.represents.bases == [u.m] assert u.Ry.scale == 1.0 and u.Ry.bases == [u.Ry] assert_allclose(u.Ry.represents.scale, 13.605692518464949) assert u.Ry.represents.bases == [u.eV] bla = u.def_unit('bla', namespace=locals()) assert bla.represents is bla blabla = u.def_unit('blabla', 10 * u.hr, namespace=locals()) assert blabla.represents.scale == 10. assert blabla.represents.bases == [u.hr] assert blabla.decompose().scale == 10 * 3600 assert blabla.decompose().bases == [u.s] def test_units_conversion(): assert_allclose(u.kpc.to(u.Mpc), 0.001) assert_allclose(u.Mpc.to(u.kpc), 1000) assert_allclose(u.yr.to(u.Myr), 1.e-6) assert_allclose(u.AU.to(u.pc), 4.84813681e-6) assert_allclose(u.cycle.to(u.rad), 6.283185307179586) assert_allclose(u.spat.to(u.sr), 12.56637061435917) def test_units_manipulation(): # Just do some manipulation and check it's happy (u.kpc * u.yr) ** Fraction(1, 3) / u.Myr (u.AA * u.erg) ** 9 def test_decompose(): assert u.Ry == u.Ry.decompose() def test_dimensionless_to_si(): """ Issue #1150: Test for conversion of dimensionless quantities to the SI system """ testunit = ((1.0 * u.kpc) / (1.0 * u.Mpc)) assert testunit.unit.physical_type == 'dimensionless' assert_allclose(testunit.si, 0.001) def test_dimensionless_to_cgs(): """ Issue #1150: Test for conversion of dimensionless quantities to the CGS system """ testunit = ((1.0 * u.m) / (1.0 * u.km)) assert testunit.unit.physical_type == 'dimensionless' assert_allclose(testunit.cgs, 0.001) def test_unknown_unit(): with pytest.warns(u.UnitsWarning, match='FOO'): u.Unit("FOO", parse_strict='warn') def test_multiple_solidus(): with pytest.warns(u.UnitsWarning, match="'m/s/kg' contains multiple " "slashes, which is discouraged"): assert u.Unit("m/s/kg").to_string() == 'm / (kg s)' with pytest.raises(ValueError): u.Unit("m/s/kg", format="vounit") # Regression test for #9000: solidi in exponents do not count towards this. x = u.Unit("kg(3/10) * m(5/2) / s", format="vounit") assert x.to_string() == 'kg(3/10) m(5/2) / s' def test_unknown_unit3(): unit = u.Unit("FOO", parse_strict='silent') assert isinstance(unit, u.UnrecognizedUnit) assert unit.name == "FOO" unit2 = u.Unit("FOO", parse_strict='silent') assert unit == unit2 assert unit.is_equivalent(unit2) unit3 = u.Unit("BAR", parse_strict='silent') assert unit != unit3 assert not unit.is_equivalent(unit3) # Also test basic (in)equalities. assert unit == "FOO" assert unit != u.m # next two from gh-7603. assert unit != None # noqa assert unit not in (None, u.m) with pytest.raises(ValueError): unit._get_converter(unit3) _ = unit.to_string('latex') _ = unit2.to_string('cgs') with pytest.raises(ValueError): u.Unit("BAR", parse_strict='strict') with pytest.raises(TypeError): u.Unit(None) def test_invalid_scale(): with pytest.raises(TypeError): ['a', 'b', 'c'] * u.m def test_cds_power(): unit = u.Unit("10+22/cm2", format="cds", parse_strict='silent') assert unit.scale == 1e22 def test_register(): foo = u.def_unit("foo", u.m ** 3, namespace=locals()) assert 'foo' in locals() with u.add_enabled_units(foo): assert 'foo' in u.get_current_unit_registry().registry assert 'foo' not in u.get_current_unit_registry().registry def test_in_units(): speed_unit = u.cm / u.s _ = speed_unit.in_units(u.pc / u.hour, 1) def test_null_unit(): assert (u.m / u.m) == u.Unit(1) def test_unrecognized_equivalency(): assert u.m.is_equivalent('foo') is False assert u.m.is_equivalent('pc') is True def test_convertible_exception(): with pytest.raises(u.UnitsError, match=r'length.+ are not convertible'): u.AA.to(u.h * u.s ** 2) def test_convertible_exception2(): with pytest.raises(u.UnitsError, match=r'length. and .+time.+ are not convertible'): u.m.to(u.s) def test_invalid_type(): class A: pass with pytest.raises(TypeError): u.Unit(A()) def test_steradian(): """ Issue #599 """ assert u.sr.is_equivalent(u.rad * u.rad) results = u.sr.compose(units=u.cgs.bases) assert results[0].bases[0] is u.rad results = u.sr.compose(units=u.cgs.__dict__) assert results[0].bases[0] is u.sr def test_decompose_bases(): """ From issue #576 """ from astropy.units import cgs from astropy.constants import e d = e.esu.unit.decompose(bases=cgs.bases) assert d._bases == [u.cm, u.g, u.s] assert d._powers == [Fraction(3, 2), 0.5, -1] assert d._scale == 1.0 def test_complex_compose(): complex = u.cd * u.sr * u.Wb composed = complex.compose() assert set(composed[0]._bases) == set([u.lm, u.Wb]) def test_equiv_compose(): composed = u.m.compose(equivalencies=u.spectral()) assert any([u.Hz] == x.bases for x in composed) def test_empty_compose(): with pytest.raises(u.UnitsError): u.m.compose(units=[]) def _unit_as_str(unit): # This function serves two purposes - it is used to sort the units to # test alphabetically, and it is also use to allow pytest to show the unit # in the [] when running the parametrized tests. return str(unit) # We use a set to make sure we don't have any duplicates. COMPOSE_ROUNDTRIP = set() for val in u.__dict__.values(): if (isinstance(val, u.UnitBase) and not isinstance(val, u.PrefixUnit)): COMPOSE_ROUNDTRIP.add(val) @pytest.mark.parametrize('unit', sorted(COMPOSE_ROUNDTRIP, key=_unit_as_str), ids=_unit_as_str) def test_compose_roundtrip(unit): composed_list = unit.decompose().compose() found = False for composed in composed_list: if len(composed.bases): if composed.bases[0] is unit: found = True break elif len(unit.bases) == 0: found = True break assert found # We use a set to make sure we don't have any duplicates. COMPOSE_CGS_TO_SI = set() for val in u.cgs.__dict__.values(): # Can't decompose Celsius if (isinstance(val, u.UnitBase) and not isinstance(val, u.PrefixUnit) and val != u.cgs.deg_C): COMPOSE_CGS_TO_SI.add(val) @pytest.mark.parametrize('unit', sorted(COMPOSE_CGS_TO_SI, key=_unit_as_str), ids=_unit_as_str) def test_compose_cgs_to_si(unit): si = unit.to_system(u.si) assert [x.is_equivalent(unit) for x in si] assert si[0] == unit.si # We use a set to make sure we don't have any duplicates. COMPOSE_SI_TO_CGS = set() for val in u.si.__dict__.values(): # Can't decompose Celsius if (isinstance(val, u.UnitBase) and not isinstance(val, u.PrefixUnit) and val != u.si.deg_C): COMPOSE_SI_TO_CGS.add(val) @pytest.mark.parametrize('unit', sorted(COMPOSE_SI_TO_CGS, key=_unit_as_str), ids=_unit_as_str) def test_compose_si_to_cgs(unit): # Can't convert things with Ampere to CGS without more context try: cgs = unit.to_system(u.cgs) except u.UnitsError: if u.A in unit.decompose().bases: pass else: raise else: assert [x.is_equivalent(unit) for x in cgs] assert cgs[0] == unit.cgs def test_to_si(): """Check units that are not official derived units. Should not appear on its own or as part of a composite unit. """ # TODO: extend to all units not listed in Tables 1--6 of # https://physics.nist.gov/cuu/Units/units.html # See gh-10585. # This was always the case assert u.bar.si is not u.bar # But this used to fail. assert u.bar not in (u.kg/(u.s**2*u.sr*u.nm)).si._bases def test_to_cgs(): assert u.Pa.to_system(u.cgs)[1]._bases[0] is u.Ba assert u.Pa.to_system(u.cgs)[1]._scale == 10.0 def test_decompose_to_cgs(): from astropy.units import cgs assert u.m.decompose(bases=cgs.bases)._bases[0] is cgs.cm def test_compose_issue_579(): unit = u.kg * u.s ** 2 / u.m result = unit.compose(units=[u.N, u.s, u.m]) assert len(result) == 1 assert result[0]._bases == [u.s, u.N, u.m] assert result[0]._powers == [4, 1, -2] def test_compose_prefix_unit(): x = u.m.compose(units=(u.m,)) assert x[0].bases[0] is u.m assert x[0].scale == 1.0 x = u.m.compose(units=[u.km], include_prefix_units=True) assert x[0].bases[0] is u.km assert x[0].scale == 0.001 x = u.m.compose(units=[u.km]) assert x[0].bases[0] is u.km assert x[0].scale == 0.001 x = (u.km/u.s).compose(units=(u.pc, u.Myr)) assert x[0].bases == [u.pc, u.Myr] assert_allclose(x[0].scale, 1.0227121650537077) with pytest.raises(u.UnitsError): (u.km/u.s).compose(units=(u.pc, u.Myr), include_prefix_units=False) def test_self_compose(): unit = u.kg * u.s assert len(unit.compose(units=[u.g, u.s])) == 1 def test_compose_failed(): unit = u.kg with pytest.raises(u.UnitsError): unit.compose(units=[u.N]) def test_compose_fractional_powers(): # Warning: with a complicated unit, this test becomes very slow; # e.g., x = (u.kg / u.s ** 3 * u.au ** 2.5 / u.yr ** 0.5 / u.sr ** 2) # takes 3 s x = u.m ** 0.5 / u.yr ** 1.5 factored = x.compose() for unit in factored: assert x.decompose() == unit.decompose() factored = x.compose(units=u.cgs) for unit in factored: assert x.decompose() == unit.decompose() factored = x.compose(units=u.si) for unit in factored: assert x.decompose() == unit.decompose() def test_compose_best_unit_first(): results = u.l.compose() assert len(results[0].bases) == 1 assert results[0].bases[0] is u.l results = (u.s ** -1).compose() assert results[0].bases[0] in (u.Hz, u.Bq) results = (u.Ry.decompose()).compose() assert results[0].bases[0] is u.Ry def test_compose_no_duplicates(): new = u.kg / u.s ** 3 * u.au ** 2.5 / u.yr ** 0.5 / u.sr ** 2 composed = new.compose(units=u.cgs.bases) assert len(composed) == 1 def test_long_int(): """ Issue #672 """ sigma = 10 ** 21 * u.M_p / u.cm ** 2 sigma.to(u.M_sun / u.pc ** 2) def test_endian_independence(): """ Regression test for #744 A logic issue in the units code meant that big endian arrays could not be converted because the dtype is '>f4', not 'float32', and the code was looking for the strings 'float' or 'int'. """ for endian in ['<', '>']: for ntype in ['i', 'f']: for byte in ['4', '8']: x = np.array([1, 2, 3], dtype=(endian + ntype + byte)) u.m.to(u.cm, x) def test_radian_base(): """ Issue #863 """ assert (1 * u.degree).si.unit == u.rad def test_no_as(): # We don't define 'as', since it is a keyword, but we # do want to define the long form (`attosecond`). assert not hasattr(u, 'as') assert hasattr(u, 'attosecond') def test_no_duplicates_in_names(): # Regression test for #5036 assert u.ct.names == ['ct', 'count'] assert u.ct.short_names == ['ct', 'count'] assert u.ct.long_names == ['count'] assert set(u.ph.names) == set(u.ph.short_names) | set(u.ph.long_names) def test_pickling(): p = pickle.dumps(u.m) other = pickle.loads(p) assert other is u.m new_unit = u.IrreducibleUnit(['foo'], format={'baz': 'bar'}) # This is local, so the unit should not be registered. assert 'foo' not in u.get_current_unit_registry().registry # Test pickling of this unregistered unit. p = pickle.dumps(new_unit) new_unit_copy = pickle.loads(p) assert new_unit_copy is not new_unit assert new_unit_copy.names == ['foo'] assert new_unit_copy.get_format_name('baz') == 'bar' # It should still not be registered. assert 'foo' not in u.get_current_unit_registry().registry # Now try the same with a registered unit. with u.add_enabled_units([new_unit]): p = pickle.dumps(new_unit) assert 'foo' in u.get_current_unit_registry().registry new_unit_copy = pickle.loads(p) assert new_unit_copy is new_unit # Check that a registered unit can be loaded and that it gets re-enabled. with u.add_enabled_units([]): assert 'foo' not in u.get_current_unit_registry().registry new_unit_copy = pickle.loads(p) assert new_unit_copy is not new_unit assert new_unit_copy.names == ['foo'] assert new_unit_copy.get_format_name('baz') == 'bar' assert 'foo' in u.get_current_unit_registry().registry # And just to be sure, that it gets removed outside of the context. assert 'foo' not in u.get_current_unit_registry().registry def test_pickle_between_sessions(): """We cannot really test between sessions easily, so fake it. This test can be changed if the pickle protocol or the code changes enough that it no longer works. """ hash_m = hash(u.m) unit = pickle.loads( b'\x80\x04\x95\xd6\x00\x00\x00\x00\x00\x00\x00\x8c\x12' b'astropy.units.core\x94\x8c\x1a_recreate_irreducible_unit' b'\x94\x93\x94h\x00\x8c\x0fIrreducibleUnit\x94\x93\x94]\x94' b'(\x8c\x01m\x94\x8c\x05meter\x94e\x88\x87\x94R\x94}\x94(\x8c\x06' b'_names\x94]\x94(h\x06h\x07e\x8c\x0c_short_names' b'\x94]\x94h\x06a\x8c\x0b_long_names\x94]\x94h\x07a\x8c\x07' b'_format\x94}\x94\x8c\x07__doc__\x94\x8c ' b'meter: base unit of length in SI\x94ub.') assert unit is u.m assert hash(u.m) == hash_m @pytest.mark.parametrize('unit', [ u.IrreducibleUnit(['foo'], format={'baz': 'bar'}), u.Unit('m_per_s', u.m/u.s)]) def test_pickle_does_not_keep_memoized_hash(unit): """ Tests private attribute since the problem with _hash being pickled and restored only appeared if the unpickling was done in another session, for which the hash no longer was valid, and it is difficult to mimic separate sessions in a simple test. See gh-11872. """ unit_hash = hash(unit) assert unit._hash is not None unit_copy = pickle.loads(pickle.dumps(unit)) # unit is not registered so we get a copy. assert unit_copy is not unit assert unit_copy._hash is None assert hash(unit_copy) == unit_hash with u.add_enabled_units([unit]): # unit is registered, so we get a reference. unit_ref = pickle.loads(pickle.dumps(unit)) if isinstance(unit, u.IrreducibleUnit): assert unit_ref is unit else: assert unit_ref is not unit # pickle.load used to override the hash, although in this case # it would be the same anyway, so not clear this tests much. assert hash(unit) == unit_hash def test_pickle_unrecognized_unit(): """ Issue #2047 """ a = u.Unit('asdf', parse_strict='silent') pickle.loads(pickle.dumps(a)) def test_duplicate_define(): with pytest.raises(ValueError): u.def_unit('m', namespace=u.__dict__) def test_all_units(): from astropy.units.core import get_current_unit_registry registry = get_current_unit_registry() assert len(registry.all_units) > len(registry.non_prefix_units) def test_repr_latex(): assert u.m._repr_latex_() == u.m.to_string('latex') def test_operations_with_strings(): assert u.m / '5s' == (u.m / (5.0 * u.s)) assert u.m * '5s' == (5.0 * u.m * u.s) def test_comparison(): assert u.m > u.cm assert u.m >= u.cm assert u.cm < u.m assert u.cm <= u.m with pytest.raises(u.UnitsError): u.m > u.kg def test_compose_into_arbitrary_units(): # Issue #1438 from astropy.constants import G G.decompose([u.kg, u.km, u.Unit("15 s")]) def test_unit_multiplication_with_string(): """Check that multiplication with strings produces the correct unit.""" u1 = u.cm us = 'kg' assert us * u1 == u.Unit(us) * u1 assert u1 * us == u1 * u.Unit(us) def test_unit_division_by_string(): """Check that multiplication with strings produces the correct unit.""" u1 = u.cm us = 'kg' assert us / u1 == u.Unit(us) / u1 assert u1 / us == u1 / u.Unit(us) def test_sorted_bases(): """See #1616.""" assert (u.m * u.Jy).bases == (u.Jy * u.m).bases def test_megabit(): """See #1543""" assert u.Mbit is u.Mb assert u.megabit is u.Mb assert u.Mbyte is u.MB assert u.megabyte is u.MB def test_composite_unit_get_format_name(): """See #1576""" unit1 = u.Unit('nrad/s') unit2 = u.Unit('Hz(1/2)') assert (str(u.CompositeUnit(1, [unit1, unit2], [1, -1])) == 'nrad / (Hz(1/2) s)') def test_unicode_policy(): from astropy.tests.helper import assert_follows_unicode_guidelines assert_follows_unicode_guidelines( u.degree, roundtrip=u.__dict__) def test_suggestions(): for search, matches in [ ('microns', 'micron'), ('s/microns', 'micron'), ('M', 'm'), ('metre', 'meter'), ('angstroms', 'Angstrom or angstrom'), ('milimeter', 'millimeter'), ('ÃĨngstrÃļm', 'Angstrom, angstrom, mAngstrom or mangstrom'), ('kev', 'EV, eV, kV or keV')]: with pytest.raises(ValueError, match=f'Did you mean {matches}'): u.Unit(search) def test_fits_hst_unit(): """See #1911.""" with pytest.warns(u.UnitsWarning, match='multiple slashes') as w: x = u.Unit("erg /s /cm**2 /angstrom") assert x == u.erg * u.s ** -1 * u.cm ** -2 * u.angstrom ** -1 assert len(w) == 1 def test_barn_prefixes(): """Regression test for https://github.com/astropy/astropy/issues/3753""" assert u.fbarn is u.femtobarn assert u.pbarn is u.picobarn def test_fractional_powers(): """See #2069""" m = 1e9 * u.Msun tH = 1. / (70. * u.km / u.s / u.Mpc) vc = 200 * u.km/u.s x = (c.G ** 2 * m ** 2 * tH.cgs) ** Fraction(1, 3) / vc v1 = x.to('pc') x = (c.G ** 2 * m ** 2 * tH) ** Fraction(1, 3) / vc v2 = x.to('pc') x = (c.G ** 2 * m ** 2 * tH.cgs) ** (1.0 / 3.0) / vc v3 = x.to('pc') x = (c.G ** 2 * m ** 2 * tH) ** (1.0 / 3.0) / vc v4 = x.to('pc') assert_allclose(v1, v2) assert_allclose(v2, v3) assert_allclose(v3, v4) x = u.m ** (1.0 / 101.0) assert isinstance(x.powers[0], float) x = u.m ** (3.0 / 7.0) assert isinstance(x.powers[0], Fraction) assert x.powers[0].numerator == 3 assert x.powers[0].denominator == 7 x = u.cm ** Fraction(1, 2) * u.cm ** Fraction(2, 3) assert isinstance(x.powers[0], Fraction) assert x.powers[0] == Fraction(7, 6) # Regression test for #9258. x = (u.TeV ** (-2.2)) ** (1/-2.2) assert isinstance(x.powers[0], Fraction) assert x.powers[0] == Fraction(1, 1) def test_sqrt_mag(): sqrt_mag = u.mag ** 0.5 assert hasattr(sqrt_mag.decompose().scale, 'imag') assert (sqrt_mag.decompose())**2 == u.mag def test_composite_compose(): # Issue #2382 composite_unit = u.s.compose(units=[u.Unit("s")])[0] u.s.compose(units=[composite_unit]) def test_data_quantities(): assert u.byte.is_equivalent(u.bit) def test_compare_with_none(): # Ensure that equality comparisons with `None` work, and don't # raise exceptions. We are deliberately not using `is None` here # because that doesn't trigger the bug. See #3108. assert not (u.m == None) # noqa assert u.m != None # noqa def test_validate_power_detect_fraction(): frac = utils.validate_power(1.1666666666666665) assert isinstance(frac, Fraction) assert frac.numerator == 7 assert frac.denominator == 6 def test_complex_fractional_rounding_errors(): # See #3788 kappa = 0.34 * u.cm**2 / u.g r_0 = 886221439924.7849 * u.cm q = 1.75 rho_0 = 5e-10 * u.solMass / u.solRad**3 y = 0.5 beta = 0.19047619047619049 a = 0.47619047619047628 m_h = 1e6*u.solMass t1 = 2 * c.c / (kappa * np.sqrt(np.pi)) t2 = (r_0**-q) / (rho_0 * y * beta * (a * c.G * m_h)**0.5) result = ((t1 * t2)**-0.8) assert result.unit.physical_type == 'length' result.to(u.solRad) def test_fractional_rounding_errors_simple(): x = (u.m ** 1.5) ** Fraction(4, 5) assert isinstance(x.powers[0], Fraction) assert x.powers[0].numerator == 6 assert x.powers[0].denominator == 5 def test_enable_unit_groupings(): from astropy.units import cds with cds.enable(): assert cds.geoMass in u.kg.find_equivalent_units() from astropy.units import imperial with imperial.enable(): assert imperial.inch in u.m.find_equivalent_units() def test_unit_summary_prefixes(): """ Test for a few units that the unit summary table correctly reports whether or not that unit supports prefixes. Regression test for https://github.com/astropy/astropy/issues/3835 """ from astropy.units import astrophys for summary in utils._iter_unit_summary(astrophys.__dict__): unit, _, _, _, prefixes = summary if unit.name == 'lyr': assert prefixes elif unit.name == 'pc': assert prefixes elif unit.name == 'barn': assert prefixes elif unit.name == 'cycle': assert prefixes == 'No' elif unit.name == 'spat': assert prefixes == 'No' elif unit.name == 'vox': assert prefixes == 'Yes' def test_raise_to_negative_power(): """Test that order of bases is changed when raising to negative power. Regression test for https://github.com/astropy/astropy/issues/8260 """ m2s2 = u.m ** 2 / u.s ** 2 spm = m2s2 ** (-1 / 2) assert spm.bases == [u.s, u.m] assert spm.powers == [1, -1] assert spm == u.s / u.m ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/tests/test_utils.py0000644000175100001710000000150600000000000021025 0ustar00vstsdocker# coding: utf-8 # Licensed under a 3-clause BSD style license - see LICENSE.rst """ Test utilities for `astropy.units`. """ import numpy as np from numpy import finfo from astropy.units.utils import sanitize_scale from astropy.units.utils import quantity_asanyarray from astropy.units.quantity import Quantity _float_finfo = finfo(float) def test_quantity_asanyarray(): array_of_quantities = [Quantity(1), Quantity(2), Quantity(3)] quantity_array = quantity_asanyarray(array_of_quantities) assert isinstance(quantity_array, Quantity) array_of_integers = [1, 2, 3] np_array = quantity_asanyarray(array_of_integers) assert isinstance(np_array, np.ndarray) def test_sanitize_scale(): assert sanitize_scale(complex(2, _float_finfo.eps)) == 2 assert sanitize_scale(complex(_float_finfo.eps, 2)) == 2j ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/units/utils.py0000644000175100001710000002074000000000000016625 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ Miscellaneous utilities for `astropy.units`. None of the functions in the module are meant for use outside of the package. """ import io import re from fractions import Fraction import numpy as np from numpy import finfo _float_finfo = finfo(float) # take float here to ensure comparison with another float is fast # give a little margin since often multiple calculations happened _JUST_BELOW_UNITY = float(1.-4.*_float_finfo.epsneg) _JUST_ABOVE_UNITY = float(1.+4.*_float_finfo.eps) def _get_first_sentence(s): """ Get the first sentence from a string and remove any carriage returns. """ x = re.match(r".*?\S\.\s", s) if x is not None: s = x.group(0) return s.replace('\n', ' ') def _iter_unit_summary(namespace): """ Generates the ``(unit, doc, represents, aliases, prefixes)`` tuple used to format the unit summary docs in `generate_unit_summary`. """ from . import core # Get all of the units, and keep track of which ones have SI # prefixes units = [] has_prefixes = set() for key, val in namespace.items(): # Skip non-unit items if not isinstance(val, core.UnitBase): continue # Skip aliases if key != val.name: continue if isinstance(val, core.PrefixUnit): # This will return the root unit that is scaled by the prefix # attached to it has_prefixes.add(val._represents.bases[0].name) else: units.append(val) # Sort alphabetically, case insensitive units.sort(key=lambda x: x.name.lower()) for unit in units: doc = _get_first_sentence(unit.__doc__).strip() represents = '' if isinstance(unit, core.Unit): represents = f":math:`{unit._represents.to_string('latex')[1:-1]}`" aliases = ', '.join(f'``{x}``' for x in unit.aliases) yield (unit, doc, represents, aliases, 'Yes' if unit.name in has_prefixes else 'No') def generate_unit_summary(namespace): """ Generates a summary of units from a given namespace. This is used to generate the docstring for the modules that define the actual units. Parameters ---------- namespace : dict A namespace containing units. Returns ------- docstring : str A docstring containing a summary table of the units. """ docstring = io.StringIO() docstring.write(""" .. list-table:: Available Units :header-rows: 1 :widths: 10 20 20 20 1 * - Unit - Description - Represents - Aliases - SI Prefixes """) for unit_summary in _iter_unit_summary(namespace): docstring.write(""" * - ``{}`` - {} - {} - {} - {} """.format(*unit_summary)) return docstring.getvalue() def generate_prefixonly_unit_summary(namespace): """ Generates table entries for units in a namespace that are just prefixes without the base unit. Note that this is intended to be used *after* `generate_unit_summary` and therefore does not include the table header. Parameters ---------- namespace : dict A namespace containing units that are prefixes but do *not* have the base unit in their namespace. Returns ------- docstring : str A docstring containing a summary table of the units. """ from . import PrefixUnit faux_namespace = {} for nm, unit in namespace.items(): if isinstance(unit, PrefixUnit): base_unit = unit.represents.bases[0] faux_namespace[base_unit.name] = base_unit docstring = io.StringIO() for unit_summary in _iter_unit_summary(faux_namespace): docstring.write(""" * - Prefixes for ``{}`` - {} prefixes - {} - {} - Only """.format(*unit_summary)) return docstring.getvalue() def is_effectively_unity(value): # value is *almost* always real, except, e.g., for u.mag**0.5, when # it will be complex. Use try/except to ensure normal case is fast try: return _JUST_BELOW_UNITY <= value <= _JUST_ABOVE_UNITY except TypeError: # value is complex return (_JUST_BELOW_UNITY <= value.real <= _JUST_ABOVE_UNITY and _JUST_BELOW_UNITY <= value.imag + 1 <= _JUST_ABOVE_UNITY) def sanitize_scale(scale): if is_effectively_unity(scale): return 1.0 # Maximum speed for regular case where scale is a float. if scale.__class__ is float: return scale # We cannot have numpy scalars, since they don't autoconvert to # complex if necessary. They are also slower. if hasattr(scale, 'dtype'): scale = scale.item() # All classes that scale can be (int, float, complex, Fraction) # have an "imag" attribute. if scale.imag: if abs(scale.real) > abs(scale.imag): if is_effectively_unity(scale.imag/scale.real + 1): return scale.real elif is_effectively_unity(scale.real/scale.imag + 1): return complex(0., scale.imag) return scale else: return scale.real def maybe_simple_fraction(p, max_denominator=100): """Fraction very close to x with denominator at most max_denominator. The fraction has to be such that fraction/x is unity to within 4 ulp. If such a fraction does not exist, returns the float number. The algorithm is that of `fractions.Fraction.limit_denominator`, but sped up by not creating a fraction to start with. """ if p == 0 or p.__class__ is int: return p n, d = p.as_integer_ratio() a = n // d # Normally, start with 0,1 and 1,0; here we have applied first iteration. n0, d0 = 1, 0 n1, d1 = a, 1 while d1 <= max_denominator: if _JUST_BELOW_UNITY <= n1/(d1*p) <= _JUST_ABOVE_UNITY: return Fraction(n1, d1) n, d = d, n-a*d a = n // d n0, n1 = n1, n0+a*n1 d0, d1 = d1, d0+a*d1 return p def validate_power(p): """Convert a power to a floating point value, an integer, or a Fraction. If a fractional power can be represented exactly as a floating point number, convert it to a float, to make the math much faster; otherwise, retain it as a `fractions.Fraction` object to avoid losing precision. Conversely, if the value is indistinguishable from a rational number with a low-numbered denominator, convert to a Fraction object. Parameters ---------- p : float, int, Rational, Fraction Power to be converted """ denom = getattr(p, 'denominator', None) if denom is None: try: p = float(p) except Exception: if not np.isscalar(p): raise ValueError("Quantities and Units may only be raised " "to a scalar power") else: raise # This returns either a (simple) Fraction or the same float. p = maybe_simple_fraction(p) # If still a float, nothing more to be done. if isinstance(p, float): return p # Otherwise, check for simplifications. denom = p.denominator if denom == 1: p = p.numerator elif (denom & (denom - 1)) == 0: # Above is a bit-twiddling hack to see if denom is a power of two. # If so, float does not lose precision and will speed things up. p = float(p) return p def resolve_fractions(a, b): """ If either input is a Fraction, convert the other to a Fraction (at least if it does not have a ridiculous denominator). This ensures that any operation involving a Fraction will use rational arithmetic and preserve precision. """ # We short-circuit on the most common cases of int and float, since # isinstance(a, Fraction) is very slow for any non-Fraction instances. a_is_fraction = (a.__class__ is not int and a.__class__ is not float and isinstance(a, Fraction)) b_is_fraction = (b.__class__ is not int and b.__class__ is not float and isinstance(b, Fraction)) if a_is_fraction and not b_is_fraction: b = maybe_simple_fraction(b) elif not a_is_fraction and b_is_fraction: a = maybe_simple_fraction(a) return a, b def quantity_asanyarray(a, dtype=None): from .quantity import Quantity if not isinstance(a, np.ndarray) and not np.isscalar(a) and any(isinstance(x, Quantity) for x in a): return Quantity(a, dtype=dtype) else: return np.asanyarray(a, dtype=dtype) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1872532 astropy-5.0.2/astropy/utils/0000755000175100001710000000000000000000000015106 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/__init__.py0000644000175100001710000000152500000000000017222 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This subpackage contains developer-oriented utilities used by Astropy. Public functions and classes in this subpackage are safe to be used by other packages, but this subpackage is for utilities that are primarily of use for developers or to implement python hacks. This subpackage also includes the ``astropy.utils.compat`` package, which houses utilities that provide compatibility and bugfixes across all versions of Python that Astropy supports. However, the content of this module is solely for internal use of ``astropy`` and subject to changes without deprecations. Do not use it in external packages or code. """ from .codegen import * # noqa from .decorators import * # noqa from .introspection import * # noqa from .misc import * # noqa from .shapes import * # noqa ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/argparse.py0000644000175100001710000000273700000000000017275 0ustar00vstsdocker"""Utilities and extensions for use with `argparse`.""" import os import argparse def directory(arg): """ An argument type (for use with the ``type=`` argument to `argparse.ArgumentParser.add_argument` which determines if the argument is an existing directory (and returns the absolute path). """ if not isinstance(arg, str) and os.path.isdir(arg): raise argparse.ArgumentTypeError( "{} is not a directory or does not exist (the directory must " "be created first)".format(arg)) return os.path.abspath(arg) def readable_directory(arg): """ An argument type (for use with the ``type=`` argument to `argparse.ArgumentParser.add_argument` which determines if the argument is a directory that exists and is readable (and returns the absolute path). """ arg = directory(arg) if not os.access(arg, os.R_OK): raise argparse.ArgumentTypeError( f"{arg} exists but is not readable with its current permissions") return arg def writeable_directory(arg): """ An argument type (for use with the ``type=`` argument to `argparse.ArgumentParser.add_argument` which determines if the argument is a directory that exists and is writeable (and returns the absolute path). """ arg = directory(arg) if not os.access(arg, os.W_OK): raise argparse.ArgumentTypeError( f"{arg} exists but is not writeable with its current permissions") return arg ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/codegen.py0000644000175100001710000001036500000000000017071 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """Utilities for generating new Python code at runtime.""" import inspect import itertools import keyword import os import re import textwrap from .introspection import find_current_module __all__ = ['make_function_with_signature'] _ARGNAME_RE = re.compile(r'^[A-Za-z][A-Za-z_]*') """ Regular expression used my make_func which limits the allowed argument names for the created function. Only valid Python variable names in the ASCII range and not beginning with '_' are allowed, currently. """ def make_function_with_signature(func, args=(), kwargs={}, varargs=None, varkwargs=None, name=None): """ Make a new function from an existing function but with the desired signature. The desired signature must of course be compatible with the arguments actually accepted by the input function. The ``args`` are strings that should be the names of the positional arguments. ``kwargs`` can map names of keyword arguments to their default values. It may be either a ``dict`` or a list of ``(keyword, default)`` tuples. If ``varargs`` is a string it is added to the positional arguments as ``*``. Likewise ``varkwargs`` can be the name for a variable keyword argument placeholder like ``**``. If not specified the name of the new function is taken from the original function. Otherwise, the ``name`` argument can be used to specify a new name. Note, the names may only be valid Python variable names. """ pos_args = [] key_args = [] if isinstance(kwargs, dict): iter_kwargs = kwargs.items() else: iter_kwargs = iter(kwargs) # Check that all the argument names are valid for item in itertools.chain(args, iter_kwargs): if isinstance(item, tuple): argname = item[0] key_args.append(item) else: argname = item pos_args.append(item) if keyword.iskeyword(argname) or not _ARGNAME_RE.match(argname): raise SyntaxError(f'invalid argument name: {argname}') for item in (varargs, varkwargs): if item is not None: if keyword.iskeyword(item) or not _ARGNAME_RE.match(item): raise SyntaxError(f'invalid argument name: {item}') def_signature = [', '.join(pos_args)] if varargs: def_signature.append(f', *{varargs}') call_signature = def_signature[:] if name is None: name = func.__name__ global_vars = {f'__{name}__func': func} local_vars = {} # Make local variables to handle setting the default args for idx, item in enumerate(key_args): key, value = item default_var = f'_kwargs{idx}' local_vars[default_var] = value def_signature.append(f', {key}={default_var}') call_signature.append(', {0}={0}'.format(key)) if varkwargs: def_signature.append(f', **{varkwargs}') call_signature.append(f', **{varkwargs}') def_signature = ''.join(def_signature).lstrip(', ') call_signature = ''.join(call_signature).lstrip(', ') mod = find_current_module(2) frm = inspect.currentframe().f_back if mod: filename = mod.__file__ modname = mod.__name__ if filename.endswith('.pyc'): filename = os.path.splitext(filename)[0] + '.py' else: filename = '' modname = '__main__' # Subtract 2 from the line number since the length of the template itself # is two lines. Therefore we have to subtract those off in order for the # pointer in tracebacks from __{name}__func to point to the right spot. lineno = frm.f_lineno - 2 # The lstrip is in case there were *no* positional arguments (a rare case) # in any context this will actually be used... template = textwrap.dedent("""{0}\ def {name}({sig1}): return __{name}__func({sig2}) """.format('\n' * lineno, name=name, sig1=def_signature, sig2=call_signature)) code = compile(template, filename, 'single') eval(code, global_vars, local_vars) new_func = local_vars[name] new_func.__module__ = modname new_func.__doc__ = func.__doc__ return new_func ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/collections.py0000644000175100001710000000272600000000000020005 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ A module containing specialized collection classes. """ class HomogeneousList(list): """ A subclass of list that contains only elements of a given type or types. If an item that is not of the specified type is added to the list, a `TypeError` is raised. """ def __init__(self, types, values=[]): """ Parameters ---------- types : sequence of types The types to accept. values : sequence, optional An initial set of values. """ self._types = types super().__init__() self.extend(values) def _assert(self, x): if not isinstance(x, self._types): raise TypeError( f"homogeneous list must contain only objects of type '{self._types}'") def __iadd__(self, other): self.extend(other) return self def __setitem__(self, idx, value): if isinstance(idx, slice): value = list(value) for item in value: self._assert(item) else: self._assert(value) return super().__setitem__(idx, value) def append(self, x): self._assert(x) return super().append(x) def insert(self, i, x): self._assert(x) return super().insert(i, x) def extend(self, x): for item in x: self._assert(item) super().append(item) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1912537 astropy-5.0.2/astropy/utils/compat/0000755000175100001710000000000000000000000016371 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/compat/__init__.py0000644000175100001710000000122100000000000020476 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This subpackage contains utility modules for compatibility with older/newer versions of python, as well as including some bugfixes for the stdlib that are important for Astropy. Note that all public functions in the `astropy.utils.compat.misc` module are imported here for easier access. The content of this module is solely for internal use of ``astropy`` and subject to changes without deprecations. Do not use it in external packages or code. """ from .misc import * # noqa # Importing this module will also install monkey-patches defined in it from .numpycompat import * # noqa ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/compat/misc.py0000644000175100001710000000404500000000000017701 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ Simple utility functions and bug fixes for compatibility with all supported versions of Python. This module should generally not be used directly, as everything in `__all__` will be imported into `astropy.utils.compat` and can be accessed from there. """ import sys import functools from contextlib import suppress __all__ = ['override__dir__', 'suppress', 'possible_filename', 'namedtuple_asdict'] def possible_filename(filename): """ Determine if the ``filename`` argument is an allowable type for a filename. In Python 3.3 use of non-unicode filenames on system calls such as `os.stat` and others that accept a filename argument was deprecated (and may be removed outright in the future). Therefore this returns `True` in all cases except for `bytes` strings in Windows. """ if isinstance(filename, str): return True elif isinstance(filename, bytes): return not (sys.platform == 'win32') return False def override__dir__(f): """ When overriding a __dir__ method on an object, you often want to include the "standard" members on the object as well. This decorator takes care of that automatically, and all the wrapped function needs to do is return a list of the "special" members that wouldn't be found by the normal Python means. Example ------- Your class could define __dir__ as follows:: @override__dir__ def __dir__(self): return ['special_method1', 'special_method2'] """ # http://bugs.python.org/issue12166 @functools.wraps(f) def override__dir__wrapper(self): members = set(object.__dir__(self)) members.update(f(self)) return sorted(members) return override__dir__wrapper def namedtuple_asdict(namedtuple): """ The same as ``namedtuple._adict()``. Parameters ---------- namedtuple : collections.namedtuple The named tuple to get the dict of """ return namedtuple._asdict() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/compat/numpycompat.py0000644000175100001710000000154000000000000021317 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This is a collection of monkey patches and workarounds for bugs in earlier versions of Numpy. """ import numpy as np from astropy.utils import minversion __all__ = ['NUMPY_LT_1_19', 'NUMPY_LT_1_19_1', 'NUMPY_LT_1_20', 'NUMPY_LT_1_21_1', 'NUMPY_LT_1_22', 'NUMPY_LT_1_22_1', 'NUMPY_LT_1_23'] # TODO: It might also be nice to have aliases to these named for specific # features/bugs we're checking for (ex: # astropy.table.table._BROKEN_UNICODE_TABLE_SORT) NUMPY_LT_1_19 = not minversion(np, '1.19') NUMPY_LT_1_19_1 = not minversion(np, '1.19.1') NUMPY_LT_1_20 = not minversion(np, '1.20') NUMPY_LT_1_21_1 = not minversion(np, '1.21.1') NUMPY_LT_1_22 = not minversion(np, '1.22') NUMPY_LT_1_22_1 = not minversion(np, '1.22.1') NUMPY_LT_1_23 = not minversion(np, '1.23dev0') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/compat/optional_deps.py0000644000175100001710000000303700000000000021606 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """Checks for optional dependencies using lazy import from `PEP 562 `_. """ import importlib import warnings # First, the top-level packages: # TODO: This list is a duplicate of the dependencies in setup.cfg "all", but # some of the package names are different from the pip-install name (e.g., # beautifulsoup4 -> bs4). _optional_deps = ['asdf', 'bleach', 'bottleneck', 'bs4', 'bz2', 'h5py', 'html5lib', 'IPython', 'jplephem', 'lxml', 'matplotlib', 'mpmath', 'pandas', 'PIL', 'pytz', 'scipy', 'skyfield', 'sortedcontainers', 'lzma', 'pyarrow'] _formerly_optional_deps = ['yaml'] # for backward compatibility _deps = {k.upper(): k for k in _optional_deps + _formerly_optional_deps} # Any subpackages that have different import behavior: _deps['PLT'] = 'matplotlib.pyplot' __all__ = [f"HAS_{pkg}" for pkg in _deps] def __getattr__(name): if name in __all__: module_name = name[4:] if module_name == "YAML": warnings.warn( "PyYaml is now a strict dependency. HAS_YAML is deprecated as " "of v5.0 and will be removed in a subsequent version.", category=AstropyDeprecationWarning) try: importlib.import_module(_deps[module_name]) except (ImportError, ModuleNotFoundError): return False return True raise AttributeError(f"Module {__name__!r} has no attribute {name!r}.") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/console.py0000644000175100001710000010665600000000000017140 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """ Utilities for console input and output. """ import codecs import locale import re import math import multiprocessing import os import struct import sys import threading import time # concurrent.futures imports moved inside functions using them to avoid # import failure when running in pyodide/Emscripten try: import fcntl import termios import signal _CAN_RESIZE_TERMINAL = True except ImportError: _CAN_RESIZE_TERMINAL = False from astropy import conf from .misc import isiterable from .decorators import classproperty __all__ = [ 'isatty', 'color_print', 'human_time', 'human_file_size', 'ProgressBar', 'Spinner', 'print_code_line', 'ProgressBarOrSpinner', 'terminal_size'] _DEFAULT_ENCODING = 'utf-8' class _IPython: """Singleton class given access to IPython streams, etc.""" @classproperty def get_ipython(cls): try: from IPython import get_ipython except ImportError: pass return get_ipython @classproperty def OutStream(cls): if not hasattr(cls, '_OutStream'): cls._OutStream = None try: cls.get_ipython() except NameError: return None try: from ipykernel.iostream import OutStream except ImportError: try: from IPython.zmq.iostream import OutStream except ImportError: from IPython import version_info if version_info[0] >= 4: return None try: from IPython.kernel.zmq.iostream import OutStream except ImportError: return None cls._OutStream = OutStream return cls._OutStream @classproperty def ipyio(cls): if not hasattr(cls, '_ipyio'): try: from IPython.utils import io except ImportError: cls._ipyio = None else: cls._ipyio = io return cls._ipyio @classmethod def get_stream(cls, stream): return getattr(cls.ipyio, stream) def _get_stdout(stderr=False): """ This utility function contains the logic to determine what streams to use by default for standard out/err. Typically this will just return `sys.stdout`, but it contains additional logic for use in IPython on Windows to determine the correct stream to use (usually ``IPython.util.io.stdout`` but only if sys.stdout is a TTY). """ if stderr: stream = 'stderr' else: stream = 'stdout' sys_stream = getattr(sys, stream) return sys_stream def isatty(file): """ Returns `True` if ``file`` is a tty. Most built-in Python file-like objects have an `isatty` member, but some user-defined types may not, so this assumes those are not ttys. """ if (multiprocessing.current_process().name != 'MainProcess' or threading.current_thread().name != 'MainThread'): return False if hasattr(file, 'isatty'): return file.isatty() if _IPython.OutStream is None or (not isinstance(file, _IPython.OutStream)): return False # File is an IPython OutStream. Check whether: # - File name is 'stdout'; or # - File wraps a Console if getattr(file, 'name', None) == 'stdout': return True if hasattr(file, 'stream'): # FIXME: pyreadline has no had new release since 2015, drop it when # IPython minversion is 5.x. # On Windows, in IPython 2 the standard I/O streams will wrap # pyreadline.Console objects if pyreadline is available; this should # be considered a TTY. try: from pyreadline.console import Console as PyreadlineConsole except ImportError: return False return isinstance(file.stream, PyreadlineConsole) return False def terminal_size(file=None): """ Returns a tuple (height, width) containing the height and width of the terminal. This function will look for the width in height in multiple areas before falling back on the width and height in astropy's configuration. """ if file is None: file = _get_stdout() try: s = struct.pack("HHHH", 0, 0, 0, 0) x = fcntl.ioctl(file, termios.TIOCGWINSZ, s) (lines, width, xpixels, ypixels) = struct.unpack("HHHH", x) if lines > 12: lines -= 6 if width > 10: width -= 1 if lines <= 0 or width <= 0: raise Exception('unable to get terminal size') return (lines, width) except Exception: try: # see if POSIX standard variables will work return (int(os.environ.get('LINES')), int(os.environ.get('COLUMNS'))) except TypeError: # fall back on configuration variables, or if not # set, (25, 80) lines = conf.max_lines width = conf.max_width if lines is None: lines = 25 if width is None: width = 80 return lines, width def _color_text(text, color): """ Returns a string wrapped in ANSI color codes for coloring the text in a terminal:: colored_text = color_text('Here is a message', 'blue') This won't actually effect the text until it is printed to the terminal. Parameters ---------- text : str The string to return, bounded by the color codes. color : str An ANSI terminal color name. Must be one of: black, red, green, brown, blue, magenta, cyan, lightgrey, default, darkgrey, lightred, lightgreen, yellow, lightblue, lightmagenta, lightcyan, white, or '' (the empty string). """ color_mapping = { 'black': '0;30', 'red': '0;31', 'green': '0;32', 'brown': '0;33', 'blue': '0;34', 'magenta': '0;35', 'cyan': '0;36', 'lightgrey': '0;37', 'default': '0;39', 'darkgrey': '1;30', 'lightred': '1;31', 'lightgreen': '1;32', 'yellow': '1;33', 'lightblue': '1;34', 'lightmagenta': '1;35', 'lightcyan': '1;36', 'white': '1;37'} if sys.platform == 'win32' and _IPython.OutStream is None: # On Windows do not colorize text unless in IPython return text color_code = color_mapping.get(color, '0;39') return f'\033[{color_code}m{text}\033[0m' def _decode_preferred_encoding(s): """Decode the supplied byte string using the preferred encoding for the locale (`locale.getpreferredencoding`) or, if the default encoding is invalid, fall back first on utf-8, then on latin-1 if the message cannot be decoded with utf-8. """ enc = locale.getpreferredencoding() try: try: return s.decode(enc) except LookupError: enc = _DEFAULT_ENCODING return s.decode(enc) except UnicodeDecodeError: return s.decode('latin-1') def _write_with_fallback(s, write, fileobj): """Write the supplied string with the given write function like ``write(s)``, but use a writer for the locale's preferred encoding in case of a UnicodeEncodeError. Failing that attempt to write with 'utf-8' or 'latin-1'. """ try: write(s) return write except UnicodeEncodeError: # Let's try the next approach... pass enc = locale.getpreferredencoding() try: Writer = codecs.getwriter(enc) except LookupError: Writer = codecs.getwriter(_DEFAULT_ENCODING) f = Writer(fileobj) write = f.write try: write(s) return write except UnicodeEncodeError: Writer = codecs.getwriter('latin-1') f = Writer(fileobj) write = f.write # If this doesn't work let the exception bubble up; I'm out of ideas write(s) return write def color_print(*args, end='\n', **kwargs): """ Prints colors and styles to the terminal uses ANSI escape sequences. :: color_print('This is the color ', 'default', 'GREEN', 'green') Parameters ---------- positional args : str The positional arguments come in pairs (*msg*, *color*), where *msg* is the string to display and *color* is the color to display it in. *color* is an ANSI terminal color name. Must be one of: black, red, green, brown, blue, magenta, cyan, lightgrey, default, darkgrey, lightred, lightgreen, yellow, lightblue, lightmagenta, lightcyan, white, or '' (the empty string). file : writable file-like, optional Where to write to. Defaults to `sys.stdout`. If file is not a tty (as determined by calling its `isatty` member, if one exists), no coloring will be included. end : str, optional The ending of the message. Defaults to ``\\n``. The end will be printed after resetting any color or font state. """ file = kwargs.get('file', _get_stdout()) write = file.write if isatty(file) and conf.use_color: for i in range(0, len(args), 2): msg = args[i] if i + 1 == len(args): color = '' else: color = args[i + 1] if color: msg = _color_text(msg, color) # Some file objects support writing unicode sensibly on some Python # versions; if this fails try creating a writer using the locale's # preferred encoding. If that fails too give up. write = _write_with_fallback(msg, write, file) write(end) else: for i in range(0, len(args), 2): msg = args[i] write(msg) write(end) def strip_ansi_codes(s): """ Remove ANSI color codes from the string. """ return re.sub('\033\\[([0-9]+)(;[0-9]+)*m', '', s) def human_time(seconds): """ Returns a human-friendly time string that is always exactly 6 characters long. Depending on the number of seconds given, can be one of:: 1w 3d 2d 4h 1h 5m 1m 4s 15s Will be in color if console coloring is turned on. Parameters ---------- seconds : int The number of seconds to represent Returns ------- time : str A human-friendly representation of the given number of seconds that is always exactly 6 characters. """ units = [ ('y', 60 * 60 * 24 * 7 * 52), ('w', 60 * 60 * 24 * 7), ('d', 60 * 60 * 24), ('h', 60 * 60), ('m', 60), ('s', 1), ] seconds = int(seconds) if seconds < 60: return f' {seconds:2d}s' for i in range(len(units) - 1): unit1, limit1 = units[i] unit2, limit2 = units[i + 1] if seconds >= limit1: return '{:2d}{}{:2d}{}'.format( seconds // limit1, unit1, (seconds % limit1) // limit2, unit2) return ' ~inf' def human_file_size(size): """ Returns a human-friendly string representing a file size that is 2-4 characters long. For example, depending on the number of bytes given, can be one of:: 256b 64k 1.1G Parameters ---------- size : int The size of the file (in bytes) Returns ------- size : str A human-friendly representation of the size of the file """ if hasattr(size, 'unit'): # Import units only if necessary because the import takes a # significant time [#4649] from astropy import units as u size = u.Quantity(size, u.byte).value suffixes = ' kMGTPEZY' if size == 0: num_scale = 0 else: num_scale = int(math.floor(math.log(size) / math.log(1000))) if num_scale > 7: suffix = '?' else: suffix = suffixes[num_scale] num_scale = int(math.pow(1000, num_scale)) value = size / num_scale str_value = str(value) if suffix == ' ': str_value = str_value[:str_value.index('.')] elif str_value[2] == '.': str_value = str_value[:2] else: str_value = str_value[:3] return f"{str_value:>3s}{suffix}" class _mapfunc(object): """ A function wrapper to support ProgressBar.map(). """ def __init__(self, func): self._func = func def __call__(self, i_arg): i, arg = i_arg return i, self._func(arg) class ProgressBar: """ A class to display a progress bar in the terminal. It is designed to be used either with the ``with`` statement:: with ProgressBar(len(items)) as bar: for item in enumerate(items): bar.update() or as a generator:: for item in ProgressBar(items): item.process() """ def __init__(self, total_or_items, ipython_widget=False, file=None): """ Parameters ---------- total_or_items : int or sequence If an int, the number of increments in the process being tracked. If a sequence, the items to iterate over. ipython_widget : bool, optional If `True`, the progress bar will display as an IPython notebook widget. file : writable file-like, optional The file to write the progress bar to. Defaults to `sys.stdout`. If ``file`` is not a tty (as determined by calling its `isatty` member, if any, or special case hacks to detect the IPython console), the progress bar will be completely silent. """ if file is None: file = _get_stdout() if not ipython_widget and not isatty(file): self.update = self._silent_update self._silent = True else: self._silent = False if isiterable(total_or_items): self._items = iter(total_or_items) self._total = len(total_or_items) else: try: self._total = int(total_or_items) except TypeError: raise TypeError("First argument must be int or sequence") else: self._items = iter(range(self._total)) self._file = file self._start_time = time.time() self._human_total = human_file_size(self._total) self._ipython_widget = ipython_widget self._signal_set = False if not ipython_widget: self._should_handle_resize = ( _CAN_RESIZE_TERMINAL and self._file.isatty()) self._handle_resize() if self._should_handle_resize: signal.signal(signal.SIGWINCH, self._handle_resize) self._signal_set = True self.update(0) def _handle_resize(self, signum=None, frame=None): terminal_width = terminal_size(self._file)[1] self._bar_length = terminal_width - 37 def __enter__(self): return self def __exit__(self, exc_type, exc_value, traceback): if not self._silent: if exc_type is None: self.update(self._total) self._file.write('\n') self._file.flush() if self._signal_set: signal.signal(signal.SIGWINCH, signal.SIG_DFL) def __iter__(self): return self def __next__(self): try: rv = next(self._items) except StopIteration: self.__exit__(None, None, None) raise else: self.update() return rv def update(self, value=None): """ Update progress bar via the console or notebook accordingly. """ # Update self.value if value is None: value = self._current_value + 1 self._current_value = value # Choose the appropriate environment if self._ipython_widget: self._update_ipython_widget(value) else: self._update_console(value) def _update_console(self, value=None): """ Update the progress bar to the given value (out of the total given to the constructor). """ if self._total == 0: frac = 1.0 else: frac = float(value) / float(self._total) file = self._file write = file.write if frac > 1: bar_fill = int(self._bar_length) else: bar_fill = int(float(self._bar_length) * frac) write('\r|') color_print('=' * bar_fill, 'blue', file=file, end='') if bar_fill < self._bar_length: color_print('>', 'green', file=file, end='') write('-' * (self._bar_length - bar_fill - 1)) write('|') if value >= self._total: t = time.time() - self._start_time prefix = ' ' elif value <= 0: t = None prefix = '' else: t = ((time.time() - self._start_time) * (1.0 - frac)) / frac prefix = ' ETA ' write(f' {human_file_size(value):>4s}/{self._human_total:>4s}') write(f' ({frac:>6.2%})') write(prefix) if t is not None: write(human_time(t)) self._file.flush() def _update_ipython_widget(self, value=None): """ Update the progress bar to the given value (out of a total given to the constructor). This method is for use in the IPython notebook 2+. """ # Create and display an empty progress bar widget, # if none exists. if not hasattr(self, '_widget'): # Import only if an IPython widget, i.e., widget in iPython NB from IPython import version_info if version_info[0] < 4: from IPython.html import widgets self._widget = widgets.FloatProgressWidget() else: _IPython.get_ipython() from ipywidgets import widgets self._widget = widgets.FloatProgress() from IPython.display import display display(self._widget) self._widget.value = 0 # Calculate percent completion, and update progress bar frac = (value/self._total) self._widget.value = frac * 100 self._widget.description = f' ({frac:>6.2%})' def _silent_update(self, value=None): pass @classmethod def map(cls, function, items, multiprocess=False, file=None, step=100, ipython_widget=False, multiprocessing_start_method=None): """Map function over items while displaying a progress bar with percentage complete. The map operation may run in arbitrary order on the items, but the results are returned in sequential order. :: def work(i): print(i) ProgressBar.map(work, range(50)) Parameters ---------- function : function Function to call for each step items : sequence Sequence where each element is a tuple of arguments to pass to *function*. multiprocess : bool, int, optional If `True`, use the `multiprocessing` module to distribute each task to a different processor core. If a number greater than 1, then use that number of cores. ipython_widget : bool, optional If `True`, the progress bar will display as an IPython notebook widget. file : writable file-like, optional The file to write the progress bar to. Defaults to `sys.stdout`. If ``file`` is not a tty (as determined by calling its `isatty` member, if any), the scrollbar will be completely silent. step : int, optional Update the progress bar at least every *step* steps (default: 100). If ``multiprocess`` is `True`, this will affect the size of the chunks of ``items`` that are submitted as separate tasks to the process pool. A large step size may make the job complete faster if ``items`` is very long. multiprocessing_start_method : str, optional Useful primarily for testing; if in doubt leave it as the default. When using multiprocessing, certain anomalies occur when starting processes with the "spawn" method (the only option on Windows); other anomalies occur with the "fork" method (the default on Linux). """ if multiprocess: function = _mapfunc(function) items = list(enumerate(items)) results = cls.map_unordered( function, items, multiprocess=multiprocess, file=file, step=step, ipython_widget=ipython_widget, multiprocessing_start_method=multiprocessing_start_method) if multiprocess: _, results = zip(*sorted(results)) results = list(results) return results @classmethod def map_unordered(cls, function, items, multiprocess=False, file=None, step=100, ipython_widget=False, multiprocessing_start_method=None): """Map function over items, reporting the progress. Does a `map` operation while displaying a progress bar with percentage complete. The map operation may run on arbitrary order on the items, and the results may be returned in arbitrary order. :: def work(i): print(i) ProgressBar.map(work, range(50)) Parameters ---------- function : function Function to call for each step items : sequence Sequence where each element is a tuple of arguments to pass to *function*. multiprocess : bool, int, optional If `True`, use the `multiprocessing` module to distribute each task to a different processor core. If a number greater than 1, then use that number of cores. ipython_widget : bool, optional If `True`, the progress bar will display as an IPython notebook widget. file : writable file-like, optional The file to write the progress bar to. Defaults to `sys.stdout`. If ``file`` is not a tty (as determined by calling its `isatty` member, if any), the scrollbar will be completely silent. step : int, optional Update the progress bar at least every *step* steps (default: 100). If ``multiprocess`` is `True`, this will affect the size of the chunks of ``items`` that are submitted as separate tasks to the process pool. A large step size may make the job complete faster if ``items`` is very long. multiprocessing_start_method : str, optional Useful primarily for testing; if in doubt leave it as the default. When using multiprocessing, certain anomalies occur when starting processes with the "spawn" method (the only option on Windows); other anomalies occur with the "fork" method (the default on Linux). """ # concurrent.futures import here to avoid import failure when running # in pyodide/Emscripten from concurrent.futures import ProcessPoolExecutor, as_completed results = [] if file is None: file = _get_stdout() with cls(len(items), ipython_widget=ipython_widget, file=file) as bar: if bar._ipython_widget: chunksize = step else: default_step = max(int(float(len(items)) / bar._bar_length), 1) chunksize = min(default_step, step) if not multiprocess or multiprocess < 1: for i, item in enumerate(items): results.append(function(item)) if (i % chunksize) == 0: bar.update(i) else: ctx = multiprocessing.get_context(multiprocessing_start_method) kwargs = dict(mp_context=ctx) with ProcessPoolExecutor( max_workers=(int(multiprocess) if multiprocess is not True else None), **kwargs) as p: for i, f in enumerate( as_completed( p.submit(function, item) for item in items)): bar.update(i) results.append(f.result()) return results class Spinner: """ A class to display a spinner in the terminal. It is designed to be used with the ``with`` statement:: with Spinner("Reticulating splines", "green") as s: for item in enumerate(items): s.update() """ _default_unicode_chars = "◓◑◒◐" _default_ascii_chars = "-/|\\" def __init__(self, msg, color='default', file=None, step=1, chars=None): """ Parameters ---------- msg : str The message to print color : str, optional An ANSI terminal color name. Must be one of: black, red, green, brown, blue, magenta, cyan, lightgrey, default, darkgrey, lightred, lightgreen, yellow, lightblue, lightmagenta, lightcyan, white. file : writable file-like, optional The file to write the spinner to. Defaults to `sys.stdout`. If ``file`` is not a tty (as determined by calling its `isatty` member, if any, or special case hacks to detect the IPython console), the spinner will be completely silent. step : int, optional Only update the spinner every *step* steps chars : str, optional The character sequence to use for the spinner """ if file is None: file = _get_stdout() self._msg = msg self._color = color self._file = file self._step = step if chars is None: if conf.unicode_output: chars = self._default_unicode_chars else: chars = self._default_ascii_chars self._chars = chars self._silent = not isatty(file) if self._silent: self._iter = self._silent_iterator() else: self._iter = self._iterator() def _iterator(self): chars = self._chars index = 0 file = self._file write = file.write flush = file.flush try_fallback = True while True: write('\r') color_print(self._msg, self._color, file=file, end='') write(' ') try: if try_fallback: write = _write_with_fallback(chars[index], write, file) else: write(chars[index]) except UnicodeError: # If even _write_with_fallback failed for any reason just give # up on trying to use the unicode characters chars = self._default_ascii_chars write(chars[index]) try_fallback = False # No good will come of using this again flush() yield for i in range(self._step): yield index = (index + 1) % len(chars) def __enter__(self): return self def __exit__(self, exc_type, exc_value, traceback): file = self._file write = file.write flush = file.flush if not self._silent: write('\r') color_print(self._msg, self._color, file=file, end='') if exc_type is None: color_print(' [Done]', 'green', file=file) else: color_print(' [Failed]', 'red', file=file) flush() def __iter__(self): return self def __next__(self): next(self._iter) def update(self, value=None): """Update the spin wheel in the terminal. Parameters ---------- value : int, optional Ignored (present just for compatibility with `ProgressBar.update`). """ next(self) def _silent_iterator(self): color_print(self._msg, self._color, file=self._file, end='') self._file.flush() while True: yield class ProgressBarOrSpinner: """ A class that displays either a `ProgressBar` or `Spinner` depending on whether the total size of the operation is known or not. It is designed to be used with the ``with`` statement:: if file.has_length(): length = file.get_length() else: length = None bytes_read = 0 with ProgressBarOrSpinner(length) as bar: while file.read(blocksize): bytes_read += blocksize bar.update(bytes_read) """ def __init__(self, total, msg, color='default', file=None): """ Parameters ---------- total : int or None If an int, the number of increments in the process being tracked and a `ProgressBar` is displayed. If `None`, a `Spinner` is displayed. msg : str The message to display above the `ProgressBar` or alongside the `Spinner`. color : str, optional The color of ``msg``, if any. Must be an ANSI terminal color name. Must be one of: black, red, green, brown, blue, magenta, cyan, lightgrey, default, darkgrey, lightred, lightgreen, yellow, lightblue, lightmagenta, lightcyan, white. file : writable file-like, optional The file to write the to. Defaults to `sys.stdout`. If ``file`` is not a tty (as determined by calling its `isatty` member, if any), only ``msg`` will be displayed: the `ProgressBar` or `Spinner` will be silent. """ if file is None: file = _get_stdout() if total is None or not isatty(file): self._is_spinner = True self._obj = Spinner(msg, color=color, file=file) else: self._is_spinner = False color_print(msg, color, file=file) self._obj = ProgressBar(total, file=file) def __enter__(self): return self def __exit__(self, exc_type, exc_value, traceback): return self._obj.__exit__(exc_type, exc_value, traceback) def update(self, value): """ Update the progress bar to the given value (out of the total given to the constructor. """ self._obj.update(value) def print_code_line(line, col=None, file=None, tabwidth=8, width=70): """ Prints a line of source code, highlighting a particular character position in the line. Useful for displaying the context of error messages. If the line is more than ``width`` characters, the line is truncated accordingly and 'â€Ļ' characters are inserted at the front and/or end. It looks like this:: there_is_a_syntax_error_here : ^ Parameters ---------- line : unicode The line of code to display col : int, optional The character in the line to highlight. ``col`` must be less than ``len(line)``. file : writable file-like, optional Where to write to. Defaults to `sys.stdout`. tabwidth : int, optional The number of spaces per tab (``'\\t'``) character. Default is 8. All tabs will be converted to spaces to ensure that the caret lines up with the correct column. width : int, optional The width of the display, beyond which the line will be truncated. Defaults to 70 (this matches the default in the standard library's `textwrap` module). """ if file is None: file = _get_stdout() if conf.unicode_output: ellipsis = 'â€Ļ' else: ellipsis = '...' write = file.write if col is not None: if col >= len(line): raise ValueError('col must be less the the line length.') ntabs = line[:col].count('\t') col += ntabs * (tabwidth - 1) line = line.rstrip('\n') line = line.replace('\t', ' ' * tabwidth) if col is not None and col > width: new_col = min(width // 2, len(line) - col) offset = col - new_col line = line[offset + len(ellipsis):] width -= len(ellipsis) new_col = col col -= offset color_print(ellipsis, 'darkgrey', file=file, end='') if len(line) > width: write(line[:width - len(ellipsis)]) color_print(ellipsis, 'darkgrey', file=file) else: write(line) write('\n') if col is not None: write(' ' * col) color_print('^', 'red', file=file) # The following four Getch* classes implement unbuffered character reading from # stdin on Windows, linux, MacOSX. This is taken directly from ActiveState # Code Recipes: # http://code.activestate.com/recipes/134892-getch-like-unbuffered-character-reading-from-stdin/ # class Getch: """Get a single character from standard input without screen echo. Returns ------- char : str (one character) """ def __init__(self): try: self.impl = _GetchWindows() except ImportError: try: self.impl = _GetchMacCarbon() except (ImportError, AttributeError): self.impl = _GetchUnix() def __call__(self): return self.impl() class _GetchUnix: def __init__(self): import tty # pylint: disable=W0611 import sys # pylint: disable=W0611 # import termios now or else you'll get the Unix # version on the Mac import termios # pylint: disable=W0611 def __call__(self): import sys import tty import termios fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) try: tty.setraw(sys.stdin.fileno()) ch = sys.stdin.read(1) finally: termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) return ch class _GetchWindows: def __init__(self): import msvcrt # pylint: disable=W0611 def __call__(self): import msvcrt return msvcrt.getch() class _GetchMacCarbon: """ A function which returns the current ASCII key that is down; if no ASCII key is down, the null string is returned. The page http://www.mactech.com/macintosh-c/chap02-1.html was very helpful in figuring out how to do this. """ def __init__(self): import Carbon Carbon.Evt # see if it has this (in Unix, it doesn't) def __call__(self): import Carbon if Carbon.Evt.EventAvail(0x0008)[0] == 0: # 0x0008 is the keyDownMask return '' else: # # The event contains the following info: # (what,msg,when,where,mod)=Carbon.Evt.GetNextEvent(0x0008)[1] # # The message (msg) contains the ASCII char which is # extracted with the 0x000000FF charCodeMask; this # number is converted to an ASCII character with chr() and # returned # (what, msg, when, where, mod) = Carbon.Evt.GetNextEvent(0x0008)[1] return chr(msg & 0x000000FF) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/data.py0000644000175100001710000023747600000000000016414 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """Functions for accessing, downloading, and caching data files.""" import atexit import contextlib import errno import fnmatch import functools import hashlib import os import io import re import shutil import socket # import ssl moved inside functions using ssl to avoid import failure # when running in pyodide/Emscripten import sys import urllib.request import urllib.error import urllib.parse import zipfile import ftplib from tempfile import NamedTemporaryFile, gettempdir, TemporaryDirectory, mkdtemp from warnings import warn try: import certifi except ImportError: # certifi support is optional; when available it will be used for TLS/SSL # downloads certifi = None import astropy.config.paths from astropy import config as _config from astropy.utils.exceptions import AstropyWarning from astropy.utils.introspection import find_current_module, resolve_name # Order here determines order in the autosummary __all__ = [ 'Conf', 'conf', 'download_file', 'download_files_in_parallel', 'get_readable_fileobj', 'get_pkg_data_fileobj', 'get_pkg_data_filename', 'get_pkg_data_contents', 'get_pkg_data_fileobjs', 'get_pkg_data_filenames', 'get_pkg_data_path', 'is_url', 'is_url_in_cache', 'get_cached_urls', 'cache_total_size', 'cache_contents', 'export_download_cache', 'import_download_cache', 'import_file_to_cache', 'check_download_cache', 'clear_download_cache', 'compute_hash', 'get_free_space_in_dir', 'check_free_space_in_dir', 'get_file_contents', 'CacheMissingWarning', "CacheDamaged" ] _dataurls_to_alias = {} class _NonClosingBufferedReader(io.BufferedReader): def __del__(self): try: # NOTE: self.raw will not be closed, but left in the state # it was in at detactment self.detach() except Exception: pass class _NonClosingTextIOWrapper(io.TextIOWrapper): def __del__(self): try: # NOTE: self.stream will not be closed, but left in the state # it was in at detactment self.detach() except Exception: pass class Conf(_config.ConfigNamespace): """ Configuration parameters for `astropy.utils.data`. """ dataurl = _config.ConfigItem( 'http://data.astropy.org/', 'Primary URL for astropy remote data site.') dataurl_mirror = _config.ConfigItem( 'http://www.astropy.org/astropy-data/', 'Mirror URL for astropy remote data site.') default_http_user_agent = _config.ConfigItem( 'astropy', 'Default User-Agent for HTTP request headers. This can be overwritten ' 'for a particular call via http_headers option, where available. ' 'This only provides the default value when not set by https_headers.') remote_timeout = _config.ConfigItem( 10., 'Time to wait for remote data queries (in seconds).', aliases=['astropy.coordinates.name_resolve.name_resolve_timeout']) allow_internet = _config.ConfigItem( True, 'If False, prevents any attempt to download from Internet.') compute_hash_block_size = _config.ConfigItem( 2 ** 16, # 64K 'Block size for computing file hashes.') download_block_size = _config.ConfigItem( 2 ** 16, # 64K 'Number of bytes of remote data to download per step.') delete_temporary_downloads_at_exit = _config.ConfigItem( True, 'If True, temporary download files created when the cache is ' 'inaccessible will be deleted at the end of the python session.') conf = Conf() class CacheMissingWarning(AstropyWarning): """ This warning indicates the standard cache directory is not accessible, with the first argument providing the warning message. If args[1] is present, it is a filename indicating the path to a temporary file that was created to store a remote data download in the absence of the cache. """ def is_url(string): """ Test whether a string is a valid URL for :func:`download_file`. Parameters ---------- string : str The string to test. Returns ------- status : bool String is URL or not. """ url = urllib.parse.urlparse(string) # we can't just check that url.scheme is not an empty string, because # file paths in windows would return a non-empty scheme (e.g. e:\\ # returns 'e'). return url.scheme.lower() in ['http', 'https', 'ftp', 'sftp', 'ssh', 'file'] # Backward compatibility because some downstream packages allegedly uses it. _is_url = is_url def _is_inside(path, parent_path): # We have to try realpath too to avoid issues with symlinks, but we leave # abspath because some systems like debian have the absolute path (with no # symlinks followed) match, but the real directories in different # locations, so need to try both cases. return os.path.abspath(path).startswith(os.path.abspath(parent_path)) \ or os.path.realpath(path).startswith(os.path.realpath(parent_path)) @contextlib.contextmanager def get_readable_fileobj(name_or_obj, encoding=None, cache=False, show_progress=True, remote_timeout=None, sources=None, http_headers=None): """Yield a readable, seekable file-like object from a file or URL. This supports passing filenames, URLs, and readable file-like objects, any of which can be compressed in gzip, bzip2 or lzma (xz) if the appropriate compression libraries are provided by the Python installation. Notes ----- This function is a context manager, and should be used for example as:: with get_readable_fileobj('file.dat') as f: contents = f.read() If a URL is provided and the cache is in use, the provided URL will be the name used in the cache. The contents may already be stored in the cache under this URL provided, they may be downloaded from this URL, or they may be downloaded from one of the locations listed in ``sources``. See `~download_file` for details. Parameters ---------- name_or_obj : str or file-like The filename of the file to access (if given as a string), or the file-like object to access. If a file-like object, it must be opened in binary mode. encoding : str, optional When `None` (default), returns a file-like object with a ``read`` method that returns `str` (``unicode``) objects, using `locale.getpreferredencoding` as an encoding. This matches the default behavior of the built-in `open` when no ``mode`` argument is provided. When ``'binary'``, returns a file-like object where its ``read`` method returns `bytes` objects. When another string, it is the name of an encoding, and the file-like object's ``read`` method will return `str` (``unicode``) objects, decoded from binary using the given encoding. cache : bool or "update", optional Whether to cache the contents of remote URLs. If "update", check the remote URL for a new version but store the result in the cache. show_progress : bool, optional Whether to display a progress bar if the file is downloaded from a remote server. Default is `True`. remote_timeout : float Timeout for remote requests in seconds (default is the configurable `astropy.utils.data.Conf.remote_timeout`). sources : list of str, optional If provided, a list of URLs to try to obtain the file from. The result will be stored under the original URL. The original URL will *not* be tried unless it is in this list; this is to prevent long waits for a primary server that is known to be inaccessible at the moment. http_headers : dict or None HTTP request headers to pass into ``urlopen`` if needed. (These headers are ignored if the protocol for the ``name_or_obj``/``sources`` entry is not a remote HTTP URL.) In the default case (None), the headers are ``User-Agent: some_value`` and ``Accept: */*``, where ``some_value`` is set by ``astropy.utils.data.conf.default_http_user_agent``. Returns ------- file : readable file-like """ # close_fds is a list of file handles created by this function # that need to be closed. We don't want to always just close the # returned file handle, because it may simply be the file handle # passed in. In that case it is not the responsibility of this # function to close it: doing so could result in a "double close" # and an "invalid file descriptor" exception. close_fds = [] delete_fds = [] if remote_timeout is None: # use configfile default remote_timeout = conf.remote_timeout # name_or_obj could be an os.PathLike object if isinstance(name_or_obj, os.PathLike): name_or_obj = os.fspath(name_or_obj) # Get a file object to the content if isinstance(name_or_obj, str): is_url = _is_url(name_or_obj) if is_url: name_or_obj = download_file( name_or_obj, cache=cache, show_progress=show_progress, timeout=remote_timeout, sources=sources, http_headers=http_headers) fileobj = io.FileIO(name_or_obj, 'r') if is_url and not cache: delete_fds.append(fileobj) close_fds.append(fileobj) else: fileobj = name_or_obj # Check if the file object supports random access, and if not, # then wrap it in a BytesIO buffer. It would be nicer to use a # BufferedReader to avoid reading loading the whole file first, # but that is not compatible with streams or urllib2.urlopen # objects on Python 2.x. if not hasattr(fileobj, 'seek'): try: # py.path.LocalPath objects have .read() method but it uses # text mode, which won't work. .read_binary() does, and # surely other ducks would return binary contents when # called like this. # py.path.LocalPath is what comes from the tmpdir fixture # in pytest. fileobj = io.BytesIO(fileobj.read_binary()) except AttributeError: fileobj = io.BytesIO(fileobj.read()) # Now read enough bytes to look at signature signature = fileobj.read(4) fileobj.seek(0) if signature[:3] == b'\x1f\x8b\x08': # gzip import struct try: import gzip fileobj_new = gzip.GzipFile(fileobj=fileobj, mode='rb') fileobj_new.read(1) # need to check that the file is really gzip except (OSError, EOFError, struct.error): # invalid gzip file fileobj.seek(0) fileobj_new.close() else: fileobj_new.seek(0) fileobj = fileobj_new elif signature[:3] == b'BZh': # bzip2 try: import bz2 except ImportError: for fd in close_fds: fd.close() raise ModuleNotFoundError( "This Python installation does not provide the bz2 module.") try: # bz2.BZ2File does not support file objects, only filenames, so we # need to write the data to a temporary file with NamedTemporaryFile("wb", delete=False) as tmp: tmp.write(fileobj.read()) tmp.close() fileobj_new = bz2.BZ2File(tmp.name, mode='rb') fileobj_new.read(1) # need to check that the file is really bzip2 except OSError: # invalid bzip2 file fileobj.seek(0) fileobj_new.close() # raise else: fileobj_new.seek(0) close_fds.append(fileobj_new) fileobj = fileobj_new elif signature[:3] == b'\xfd7z': # xz try: import lzma fileobj_new = lzma.LZMAFile(fileobj, mode='rb') fileobj_new.read(1) # need to check that the file is really xz except ImportError: for fd in close_fds: fd.close() raise ModuleNotFoundError( "This Python installation does not provide the lzma module.") except (OSError, EOFError): # invalid xz file fileobj.seek(0) fileobj_new.close() # should we propagate this to the caller to signal bad content? # raise ValueError(e) else: fileobj_new.seek(0) fileobj = fileobj_new # By this point, we have a file, io.FileIO, gzip.GzipFile, bz2.BZ2File # or lzma.LZMAFile instance opened in binary mode (that is, read # returns bytes). Now we need to, if requested, wrap it in a # io.TextIOWrapper so read will return unicode based on the # encoding parameter. needs_textio_wrapper = encoding != 'binary' if needs_textio_wrapper: # A bz2.BZ2File can not be wrapped by a TextIOWrapper, # so we decompress it to a temporary file and then # return a handle to that. try: import bz2 except ImportError: pass else: if isinstance(fileobj, bz2.BZ2File): tmp = NamedTemporaryFile("wb", delete=False) data = fileobj.read() tmp.write(data) tmp.close() delete_fds.append(tmp) fileobj = io.FileIO(tmp.name, 'r') close_fds.append(fileobj) fileobj = _NonClosingBufferedReader(fileobj) fileobj = _NonClosingTextIOWrapper(fileobj, encoding=encoding) # Ensure that file is at the start - io.FileIO will for # example not always be at the start: # >>> import io # >>> f = open('test.fits', 'rb') # >>> f.read(4) # 'SIMP' # >>> f.seek(0) # >>> fileobj = io.FileIO(f.fileno()) # >>> fileobj.tell() # 4096L fileobj.seek(0) try: yield fileobj finally: for fd in close_fds: fd.close() for fd in delete_fds: os.remove(fd.name) def get_file_contents(*args, **kwargs): """ Retrieves the contents of a filename or file-like object. See the `get_readable_fileobj` docstring for details on parameters. Returns ------- object The content of the file (as requested by ``encoding``). """ with get_readable_fileobj(*args, **kwargs) as f: return f.read() @contextlib.contextmanager def get_pkg_data_fileobj(data_name, package=None, encoding=None, cache=True): """ Retrieves a data file from the standard locations for the package and provides the file as a file-like object that reads bytes. Parameters ---------- data_name : str Name/location of the desired data file. One of the following: * The name of a data file included in the source distribution. The path is relative to the module calling this function. For example, if calling from ``astropy.pkname``, use ``'data/file.dat'`` to get the file in ``astropy/pkgname/data/file.dat``. Double-dots can be used to go up a level. In the same example, use ``'../data/file.dat'`` to get ``astropy/data/file.dat``. * If a matching local file does not exist, the Astropy data server will be queried for the file. * A hash like that produced by `compute_hash` can be requested, prefixed by 'hash/' e.g. 'hash/34c33b3eb0d56eb9462003af249eff28'. The hash will first be searched for locally, and if not found, the Astropy data server will be queried. package : str, optional If specified, look for a file relative to the given package, rather than the default of looking relative to the calling module's package. encoding : str, optional When `None` (default), returns a file-like object with a ``read`` method returns `str` (``unicode``) objects, using `locale.getpreferredencoding` as an encoding. This matches the default behavior of the built-in `open` when no ``mode`` argument is provided. When ``'binary'``, returns a file-like object where its ``read`` method returns `bytes` objects. When another string, it is the name of an encoding, and the file-like object's ``read`` method will return `str` (``unicode``) objects, decoded from binary using the given encoding. cache : bool If True, the file will be downloaded and saved locally or the already-cached local copy will be accessed. If False, the file-like object will directly access the resource (e.g. if a remote URL is accessed, an object like that from `urllib.request.urlopen` is returned). Returns ------- fileobj : file-like An object with the contents of the data file available via ``read`` function. Can be used as part of a ``with`` statement, automatically closing itself after the ``with`` block. Raises ------ urllib.error.URLError If a remote file cannot be found. OSError If problems occur writing or reading a local file. Examples -------- This will retrieve a data file and its contents for the `astropy.wcs` tests:: >>> from astropy.utils.data import get_pkg_data_fileobj >>> with get_pkg_data_fileobj('data/3d_cd.hdr', ... package='astropy.wcs.tests') as fobj: ... fcontents = fobj.read() ... This next example would download a data file from the astropy data server because the ``allsky/allsky_rosat.fits`` file is not present in the source distribution. It will also save the file locally so the next time it is accessed it won't need to be downloaded.:: >>> from astropy.utils.data import get_pkg_data_fileobj >>> with get_pkg_data_fileobj('allsky/allsky_rosat.fits', ... encoding='binary') as fobj: # doctest: +REMOTE_DATA +IGNORE_OUTPUT ... fcontents = fobj.read() ... Downloading http://data.astropy.org/allsky/allsky_rosat.fits [Done] This does the same thing but does *not* cache it locally:: >>> with get_pkg_data_fileobj('allsky/allsky_rosat.fits', ... encoding='binary', cache=False) as fobj: # doctest: +REMOTE_DATA +IGNORE_OUTPUT ... fcontents = fobj.read() ... Downloading http://data.astropy.org/allsky/allsky_rosat.fits [Done] See Also -------- get_pkg_data_contents : returns the contents of a file or url as a bytes object get_pkg_data_filename : returns a local name for a file containing the data """ # noqa datafn = get_pkg_data_path(data_name, package=package) if os.path.isdir(datafn): raise OSError("Tried to access a data file that's actually " "a package data directory") elif os.path.isfile(datafn): # local file with get_readable_fileobj(datafn, encoding=encoding) as fileobj: yield fileobj else: # remote file with get_readable_fileobj( conf.dataurl + data_name, encoding=encoding, cache=cache, sources=[conf.dataurl + data_name, conf.dataurl_mirror + data_name], ) as fileobj: # We read a byte to trigger any URLErrors fileobj.read(1) fileobj.seek(0) yield fileobj def get_pkg_data_filename(data_name, package=None, show_progress=True, remote_timeout=None): """ Retrieves a data file from the standard locations for the package and provides a local filename for the data. This function is similar to `get_pkg_data_fileobj` but returns the file *name* instead of a readable file-like object. This means that this function must always cache remote files locally, unlike `get_pkg_data_fileobj`. Parameters ---------- data_name : str Name/location of the desired data file. One of the following: * The name of a data file included in the source distribution. The path is relative to the module calling this function. For example, if calling from ``astropy.pkname``, use ``'data/file.dat'`` to get the file in ``astropy/pkgname/data/file.dat``. Double-dots can be used to go up a level. In the same example, use ``'../data/file.dat'`` to get ``astropy/data/file.dat``. * If a matching local file does not exist, the Astropy data server will be queried for the file. * A hash like that produced by `compute_hash` can be requested, prefixed by 'hash/' e.g. 'hash/34c33b3eb0d56eb9462003af249eff28'. The hash will first be searched for locally, and if not found, the Astropy data server will be queried. package : str, optional If specified, look for a file relative to the given package, rather than the default of looking relative to the calling module's package. show_progress : bool, optional Whether to display a progress bar if the file is downloaded from a remote server. Default is `True`. remote_timeout : float Timeout for the requests in seconds (default is the configurable `astropy.utils.data.Conf.remote_timeout`). Raises ------ urllib.error.URLError If a remote file cannot be found. OSError If problems occur writing or reading a local file. Returns ------- filename : str A file path on the local file system corresponding to the data requested in ``data_name``. Examples -------- This will retrieve the contents of the data file for the `astropy.wcs` tests:: >>> from astropy.utils.data import get_pkg_data_filename >>> fn = get_pkg_data_filename('data/3d_cd.hdr', ... package='astropy.wcs.tests') >>> with open(fn) as f: ... fcontents = f.read() ... This retrieves a data file by hash either locally or from the astropy data server:: >>> from astropy.utils.data import get_pkg_data_filename >>> fn = get_pkg_data_filename('hash/34c33b3eb0d56eb9462003af249eff28') # doctest: +SKIP >>> with open(fn) as f: ... fcontents = f.read() ... See Also -------- get_pkg_data_contents : returns the contents of a file or url as a bytes object get_pkg_data_fileobj : returns a file-like object with the data """ if remote_timeout is None: # use configfile default remote_timeout = conf.remote_timeout if data_name.startswith('hash/'): # first try looking for a local version if a hash is specified hashfn = _find_hash_fn(data_name[5:]) if hashfn is None: return download_file(conf.dataurl + data_name, cache=True, show_progress=show_progress, timeout=remote_timeout, sources=[conf.dataurl + data_name, conf.dataurl_mirror + data_name]) else: return hashfn else: fs_path = os.path.normpath(data_name) datafn = get_pkg_data_path(fs_path, package=package) if os.path.isdir(datafn): raise OSError("Tried to access a data file that's actually " "a package data directory") elif os.path.isfile(datafn): # local file return datafn else: # remote file return download_file(conf.dataurl + data_name, cache=True, show_progress=show_progress, timeout=remote_timeout, sources=[conf.dataurl + data_name, conf.dataurl_mirror + data_name]) def get_pkg_data_contents(data_name, package=None, encoding=None, cache=True): """ Retrieves a data file from the standard locations and returns its contents as a bytes object. Parameters ---------- data_name : str Name/location of the desired data file. One of the following: * The name of a data file included in the source distribution. The path is relative to the module calling this function. For example, if calling from ``astropy.pkname``, use ``'data/file.dat'`` to get the file in ``astropy/pkgname/data/file.dat``. Double-dots can be used to go up a level. In the same example, use ``'../data/file.dat'`` to get ``astropy/data/file.dat``. * If a matching local file does not exist, the Astropy data server will be queried for the file. * A hash like that produced by `compute_hash` can be requested, prefixed by 'hash/' e.g. 'hash/34c33b3eb0d56eb9462003af249eff28'. The hash will first be searched for locally, and if not found, the Astropy data server will be queried. * A URL to some other file. package : str, optional If specified, look for a file relative to the given package, rather than the default of looking relative to the calling module's package. encoding : str, optional When `None` (default), returns a file-like object with a ``read`` method that returns `str` (``unicode``) objects, using `locale.getpreferredencoding` as an encoding. This matches the default behavior of the built-in `open` when no ``mode`` argument is provided. When ``'binary'``, returns a file-like object where its ``read`` method returns `bytes` objects. When another string, it is the name of an encoding, and the file-like object's ``read`` method will return `str` (``unicode``) objects, decoded from binary using the given encoding. cache : bool If True, the file will be downloaded and saved locally or the already-cached local copy will be accessed. If False, the file-like object will directly access the resource (e.g. if a remote URL is accessed, an object like that from `urllib.request.urlopen` is returned). Returns ------- contents : bytes The complete contents of the file as a bytes object. Raises ------ urllib.error.URLError If a remote file cannot be found. OSError If problems occur writing or reading a local file. See Also -------- get_pkg_data_fileobj : returns a file-like object with the data get_pkg_data_filename : returns a local name for a file containing the data """ with get_pkg_data_fileobj(data_name, package=package, encoding=encoding, cache=cache) as fd: contents = fd.read() return contents def get_pkg_data_filenames(datadir, package=None, pattern='*'): """ Returns the path of all of the data files in a given directory that match a given glob pattern. Parameters ---------- datadir : str Name/location of the desired data files. One of the following: * The name of a directory included in the source distribution. The path is relative to the module calling this function. For example, if calling from ``astropy.pkname``, use ``'data'`` to get the files in ``astropy/pkgname/data``. * Remote URLs are not currently supported. package : str, optional If specified, look for a file relative to the given package, rather than the default of looking relative to the calling module's package. pattern : str, optional A UNIX-style filename glob pattern to match files. See the `glob` module in the standard library for more information. By default, matches all files. Returns ------- filenames : iterator of str Paths on the local filesystem in *datadir* matching *pattern*. Examples -------- This will retrieve the contents of the data file for the `astropy.wcs` tests:: >>> from astropy.utils.data import get_pkg_data_filenames >>> for fn in get_pkg_data_filenames('data/maps', 'astropy.wcs.tests', ... '*.hdr'): ... with open(fn) as f: ... fcontents = f.read() ... """ path = get_pkg_data_path(datadir, package=package) if os.path.isfile(path): raise OSError( "Tried to access a data directory that's actually " "a package data file") elif os.path.isdir(path): for filename in os.listdir(path): if fnmatch.fnmatch(filename, pattern): yield os.path.join(path, filename) else: raise OSError("Path not found") def get_pkg_data_fileobjs(datadir, package=None, pattern='*', encoding=None): """ Returns readable file objects for all of the data files in a given directory that match a given glob pattern. Parameters ---------- datadir : str Name/location of the desired data files. One of the following: * The name of a directory included in the source distribution. The path is relative to the module calling this function. For example, if calling from ``astropy.pkname``, use ``'data'`` to get the files in ``astropy/pkgname/data`` * Remote URLs are not currently supported package : str, optional If specified, look for a file relative to the given package, rather than the default of looking relative to the calling module's package. pattern : str, optional A UNIX-style filename glob pattern to match files. See the `glob` module in the standard library for more information. By default, matches all files. encoding : str, optional When `None` (default), returns a file-like object with a ``read`` method that returns `str` (``unicode``) objects, using `locale.getpreferredencoding` as an encoding. This matches the default behavior of the built-in `open` when no ``mode`` argument is provided. When ``'binary'``, returns a file-like object where its ``read`` method returns `bytes` objects. When another string, it is the name of an encoding, and the file-like object's ``read`` method will return `str` (``unicode``) objects, decoded from binary using the given encoding. Returns ------- fileobjs : iterator of file object File objects for each of the files on the local filesystem in *datadir* matching *pattern*. Examples -------- This will retrieve the contents of the data file for the `astropy.wcs` tests:: >>> from astropy.utils.data import get_pkg_data_filenames >>> for fd in get_pkg_data_fileobjs('data/maps', 'astropy.wcs.tests', ... '*.hdr'): ... fcontents = fd.read() ... """ for fn in get_pkg_data_filenames(datadir, package=package, pattern=pattern): with get_readable_fileobj(fn, encoding=encoding) as fd: yield fd def compute_hash(localfn): """ Computes the MD5 hash for a file. The hash for a data file is used for looking up data files in a unique fashion. This is of particular use for tests; a test may require a particular version of a particular file, in which case it can be accessed via hash to get the appropriate version. Typically, if you wish to write a test that requires a particular data file, you will want to submit that file to the astropy data servers, and use e.g. ``get_pkg_data_filename('hash/34c33b3eb0d56eb9462003af249eff28')``, but with the hash for your file in place of the hash in the example. Parameters ---------- localfn : str The path to the file for which the hash should be generated. Returns ------- hash : str The hex digest of the cryptographic hash for the contents of the ``localfn`` file. """ with open(localfn, 'rb') as f: h = hashlib.md5() block = f.read(conf.compute_hash_block_size) while block: h.update(block) block = f.read(conf.compute_hash_block_size) return h.hexdigest() def get_pkg_data_path(*path, package=None): """Get path from source-included data directories. Parameters ---------- *path : str Name/location of the desired data file/directory. May be a tuple of strings for ``os.path`` joining. package : str or None, optional, keyword-only If specified, look for a file relative to the given package, rather than the calling module's package. Returns ------- path : str Name/location of the desired data file/directory. Raises ------ ImportError Given package or module is not importable. RuntimeError If the local data file is outside of the package's tree. """ if package is None: module = find_current_module(1, finddiff=['astropy.utils.data', 'contextlib']) if module is None: # not called from inside an astropy package. So just pass name # through return os.path.join(*path) if not hasattr(module, '__package__') or not module.__package__: # The __package__ attribute may be missing or set to None; see # PEP-366, also astropy issue #1256 if '.' in module.__name__: package = module.__name__.rpartition('.')[0] else: package = module.__name__ else: package = module.__package__ else: # package errors if it isn't a str # so there is no need for checks in the containing if/else module = resolve_name(package) # module path within package module_path = os.path.dirname(module.__file__) full_path = os.path.join(module_path, *path) # Check that file is inside tree. rootpkgname = package.partition('.')[0] rootpkg = resolve_name(rootpkgname) root_dir = os.path.dirname(rootpkg.__file__) if not _is_inside(full_path, root_dir): raise RuntimeError(f"attempted to get a local data file outside " f"of the {rootpkgname} tree.") return full_path def _find_hash_fn(hexdigest, pkgname='astropy'): """ Looks for a local file by hash - returns file name if found and a valid file, otherwise returns None. """ for v in cache_contents(pkgname=pkgname).values(): if compute_hash(v) == hexdigest: return v return None def get_free_space_in_dir(path, unit=False): """ Given a path to a directory, returns the amount of free space on that filesystem. Parameters ---------- path : str The path to a directory. unit : bool or `~astropy.units.Unit` Return the amount of free space as Quantity in the given unit, if provided. Default is `False` for backward-compatibility. Returns ------- free_space : int or `~astropy.units.Quantity` The amount of free space on the partition that the directory is on. If ``unit=False``, it is returned as plain integer (in bytes). """ if not os.path.isdir(path): raise OSError( "Can only determine free space associated with directories, " "not files.") # Actually you can on Linux but I want to avoid code that fails # on Windows only. free_space = shutil.disk_usage(path).free if unit: from astropy import units as u # TODO: Automatically determine best prefix to use. if unit is True: unit = u.byte free_space = u.Quantity(free_space, u.byte).to(unit) return free_space def check_free_space_in_dir(path, size): """ Determines if a given directory has enough space to hold a file of a given size. Parameters ---------- path : str The path to a directory. size : int or `~astropy.units.Quantity` A proposed filesize. If not a Quantity, assume it is in bytes. Raises ------ OSError There is not enough room on the filesystem. """ space = get_free_space_in_dir(path, unit=getattr(size, 'unit', False)) if space < size: from astropy.utils.console import human_file_size raise OSError(f"Not enough free space in {path} " f"to download a {human_file_size(size)} file, " f"only {human_file_size(space)} left") class _ftptlswrapper(urllib.request.ftpwrapper): def init(self): self.busy = 0 self.ftp = ftplib.FTP_TLS() self.ftp.connect(self.host, self.port, self.timeout) self.ftp.login(self.user, self.passwd) self.ftp.prot_p() _target = '/'.join(self.dirs) self.ftp.cwd(_target) class _FTPTLSHandler(urllib.request.FTPHandler): def connect_ftp(self, user, passwd, host, port, dirs, timeout): return _ftptlswrapper(user, passwd, host, port, dirs, timeout, persistent=False) @functools.lru_cache() def _build_urlopener(ftp_tls=False, ssl_context=None, allow_insecure=False): """ Helper for building a `urllib.request.build_opener` which handles TLS/SSL. """ # Import ssl here to avoid import failure when running in pyodide/Emscripten import ssl ssl_context = dict(it for it in ssl_context) if ssl_context else {} cert_chain = {} if 'certfile' in ssl_context: cert_chain.update({ 'certfile': ssl_context.pop('certfile'), 'keyfile': ssl_context.pop('keyfile', None), 'password': ssl_context.pop('password', None) }) elif 'password' in ssl_context or 'keyfile' in ssl_context: raise ValueError( "passing 'keyfile' or 'password' in the ssl_context argument " "requires passing 'certfile' as well") if 'cafile' not in ssl_context and certifi is not None: ssl_context['cafile'] = certifi.where() ssl_context = ssl.create_default_context(**ssl_context) if allow_insecure: ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE if cert_chain: ssl_context.load_cert_chain(**cert_chain) https_handler = urllib.request.HTTPSHandler(context=ssl_context) if ftp_tls: urlopener = urllib.request.build_opener(_FTPTLSHandler(), https_handler) else: urlopener = urllib.request.build_opener(https_handler) return urlopener def _try_url_open(source_url, timeout=None, http_headers=None, ftp_tls=False, ssl_context=None, allow_insecure=False): """Helper for opening a URL while handling TLS/SSL verification issues.""" # Import ssl here to avoid import failure when running in pyodide/Emscripten import ssl # Always try first with a secure connection # _build_urlopener uses lru_cache, so the ssl_context argument must be # converted to a hashshable type (a set of 2-tuples) ssl_context = frozenset(ssl_context.items() if ssl_context else []) urlopener = _build_urlopener(ftp_tls=ftp_tls, ssl_context=ssl_context, allow_insecure=False) req = urllib.request.Request(source_url, headers=http_headers) try: return urlopener.open(req, timeout=timeout) except urllib.error.URLError as exc: reason = exc.reason if (isinstance(reason, ssl.SSLError) and reason.reason == 'CERTIFICATE_VERIFY_FAILED'): msg = (f'Verification of TLS/SSL certificate at {source_url} ' f'failed: this can mean either the server is ' f'misconfigured or your local root CA certificates are ' f'out-of-date; in the latter case this can usually be ' f'addressed by installing the Python package "certifi" ' f'(see the documentation for astropy.utils.data.download_url)') if not allow_insecure: msg += (f' or in both cases you can work around this by ' f'passing allow_insecure=True, but only if you ' f'understand the implications; the original error ' f'was: {reason}') raise urllib.error.URLError(msg) else: msg += '. Re-trying with allow_insecure=True.' warn(msg, AstropyWarning) # Try again with a new urlopener allowing insecure connections urlopener = _build_urlopener(ftp_tls=ftp_tls, ssl_context=ssl_context, allow_insecure=True) return urlopener.open(req, timeout=timeout) raise def _download_file_from_source(source_url, show_progress=True, timeout=None, remote_url=None, cache=False, pkgname='astropy', http_headers=None, ftp_tls=None, ssl_context=None, allow_insecure=False): from astropy.utils.console import ProgressBarOrSpinner if not conf.allow_internet: raise urllib.error.URLError( f"URL {remote_url} was supposed to be downloaded but " f"allow_internet is {conf.allow_internet}; " f"if this is unexpected check the astropy.cfg file for the option " f"allow_internet") if remote_url is None: remote_url = source_url if http_headers is None: http_headers = {} if ftp_tls is None and urllib.parse.urlparse(remote_url).scheme == "ftp": try: return _download_file_from_source(source_url, show_progress=show_progress, timeout=timeout, remote_url=remote_url, cache=cache, pkgname=pkgname, http_headers=http_headers, ftp_tls=False) except urllib.error.URLError as e: # e.reason might not be a string, e.g. socket.gaierror if str(e.reason).startswith("ftp error: error_perm"): ftp_tls = True else: raise with _try_url_open(source_url, timeout=timeout, http_headers=http_headers, ftp_tls=ftp_tls, ssl_context=ssl_context, allow_insecure=allow_insecure) as remote: info = remote.info() try: size = int(info['Content-Length']) except (KeyError, ValueError, TypeError): size = None if size is not None: check_free_space_in_dir(gettempdir(), size) if cache: dldir = _get_download_cache_loc(pkgname) check_free_space_in_dir(dldir, size) if show_progress and sys.stdout.isatty(): progress_stream = sys.stdout else: progress_stream = io.StringIO() if source_url == remote_url: dlmsg = f"Downloading {remote_url}" else: dlmsg = f"Downloading {remote_url} from {source_url}" with ProgressBarOrSpinner(size, dlmsg, file=progress_stream) as p: with NamedTemporaryFile(prefix=f"astropy-download-{os.getpid()}-", delete=False) as f: try: bytes_read = 0 block = remote.read(conf.download_block_size) while block: f.write(block) bytes_read += len(block) p.update(bytes_read) block = remote.read(conf.download_block_size) if size is not None and bytes_read > size: raise urllib.error.URLError( f"File was supposed to be {size} bytes but " f"server provides more, at least {bytes_read} " f"bytes. Download failed.") if size is not None and bytes_read < size: raise urllib.error.ContentTooShortError( f"File was supposed to be {size} bytes but we " f"only got {bytes_read} bytes. Download failed.", content=None) except BaseException: if os.path.exists(f.name): try: os.remove(f.name) except OSError: pass raise return f.name def download_file(remote_url, cache=False, show_progress=True, timeout=None, sources=None, pkgname='astropy', http_headers=None, ssl_context=None, allow_insecure=False): """Downloads a URL and optionally caches the result. It returns the filename of a file containing the URL's contents. If ``cache=True`` and the file is present in the cache, just returns the filename; if the file had to be downloaded, add it to the cache. If ``cache="update"`` always download and add it to the cache. The cache is effectively a dictionary mapping URLs to files; by default the file contains the contents of the URL that is its key, but in practice these can be obtained from a mirror (using ``sources``) or imported from the local filesystem (using `~import_file_to_cache` or `~import_download_cache`). Regardless, each file is regarded as representing the contents of a particular URL, and this URL should be used to look them up or otherwise manipulate them. The files in the cache directory are named according to a cryptographic hash of their URLs (currently MD5, so hackers can cause collisions). The modification times on these files normally indicate when they were last downloaded from the Internet. Parameters ---------- remote_url : str The URL of the file to download cache : bool or "update", optional Whether to cache the contents of remote URLs. If "update", always download the remote URL in case there is a new version and store the result in the cache. show_progress : bool, optional Whether to display a progress bar during the download (default is `True`). Regardless of this setting, the progress bar is only displayed when outputting to a terminal. timeout : float, optional Timeout for remote requests in seconds (default is the configurable `astropy.utils.data.Conf.remote_timeout`). sources : list of str, optional If provided, a list of URLs to try to obtain the file from. The result will be stored under the original URL. The original URL will *not* be tried unless it is in this list; this is to prevent long waits for a primary server that is known to be inaccessible at the moment. If an empty list is passed, then ``download_file`` will not attempt to connect to the Internet, that is, if the file is not in the cache a KeyError will be raised. pkgname : `str`, optional The package name to use to locate the download cache. i.e. for ``pkgname='astropy'`` the default cache location is ``~/.astropy/cache``. http_headers : dict or None HTTP request headers to pass into ``urlopen`` if needed. (These headers are ignored if the protocol for the ``name_or_obj``/``sources`` entry is not a remote HTTP URL.) In the default case (None), the headers are ``User-Agent: some_value`` and ``Accept: */*``, where ``some_value`` is set by ``astropy.utils.data.conf.default_http_user_agent``. ssl_context : dict, optional Keyword arguments to pass to `ssl.create_default_context` when downloading from HTTPS or TLS+FTP sources. This can be used provide alternative paths to root CA certificates. Additionally, if the key ``'certfile'`` and optionally ``'keyfile'`` and ``'password'`` are included, they are passed to `ssl.SSLContext.load_cert_chain`. This can be used for performing SSL/TLS client certificate authentication for servers that require it. allow_insecure : bool, optional Allow downloading files over a TLS/SSL connection even when the server certificate verification failed. When set to `True` the potentially insecure download is allowed to proceed, but an `~astropy.utils.exceptions.AstropyWarning` is issued. If you are frequently getting certificate verification warnings, consider installing or upgrading `certifi`_ package, which provides frequently updated certificates for common root CAs (i.e., a set similar to those used by web browsers). If installed, Astropy will use it automatically. .. _certifi: https://pypi.org/project/certifi/ Returns ------- local_path : str Returns the local path that the file was download to. Raises ------ urllib.error.URLError Whenever there's a problem getting the remote file. KeyError When a file was requested from the cache but is missing and no sources were provided to obtain it from the Internet. Notes ----- Because this function returns a filename, another process could run `clear_download_cache` before you actually open the file, leaving you with a filename that no longer points to a usable file. """ if timeout is None: timeout = conf.remote_timeout if sources is None: sources = [remote_url] if http_headers is None: http_headers = {'User-Agent': conf.default_http_user_agent, 'Accept': '*/*'} missing_cache = "" url_key = remote_url if cache: try: dldir = _get_download_cache_loc(pkgname) except OSError as e: cache = False missing_cache = ( f"Cache directory cannot be read or created ({e}), " f"providing data in temporary file instead." ) else: if cache == "update": pass elif isinstance(cache, str): raise ValueError(f"Cache value '{cache}' was requested but " f"'update' is the only recognized string; " f"otherwise use a boolean") else: filename = os.path.join(dldir, _url_to_dirname(url_key), "contents") if os.path.exists(filename): return os.path.abspath(filename) errors = {} for source_url in sources: try: f_name = _download_file_from_source( source_url, timeout=timeout, show_progress=show_progress, cache=cache, remote_url=remote_url, pkgname=pkgname, http_headers=http_headers, ssl_context=ssl_context, allow_insecure=allow_insecure) # Success! break except urllib.error.URLError as e: # errno 8 is from SSL "EOF occurred in violation of protocol" if (hasattr(e, 'reason') and hasattr(e.reason, 'errno') and e.reason.errno == 8): e.reason.strerror = (e.reason.strerror + '. requested URL: ' + remote_url) e.reason.args = (e.reason.errno, e.reason.strerror) errors[source_url] = e except socket.timeout as e: # this isn't supposed to happen, but occasionally a socket.timeout # gets through. It's supposed to be caught in urllib and raised # in this way, but for some reason in mysterious circumstances it # doesn't (or didn't in python2?). So we'll just re-raise it here # instead. errors[source_url] = e else: # No success if not sources: raise KeyError( f"No sources listed and file {remote_url} not in cache! " f"Please include primary URL in sources if you want it to be " f"included as a valid source.") elif len(sources) == 1: raise errors[sources[0]] else: raise urllib.error.URLError( f"Unable to open any source! Exceptions were {errors}") \ from errors[sources[0]] if cache: try: return import_file_to_cache(url_key, f_name, remove_original=True, replace=(cache == 'update'), pkgname=pkgname) except PermissionError as e: # Cache is readonly, we can't update it missing_cache = ( f"Cache directory appears to be read-only ({e}), unable to import " f"downloaded file, providing data in temporary file {f_name} " f"instead.") # FIXME: other kinds of cache problem can occur? if missing_cache: warn(CacheMissingWarning(missing_cache, f_name)) if conf.delete_temporary_downloads_at_exit: global _tempfilestodel _tempfilestodel.append(f_name) return os.path.abspath(f_name) def is_url_in_cache(url_key, pkgname='astropy'): """Check if a download for ``url_key`` is in the cache. The provided ``url_key`` will be the name used in the cache. The contents may have been downloaded from this URL or from a mirror or they may have been provided by the user. See `~download_file` for details. Parameters ---------- url_key : str The URL retrieved pkgname : `str`, optional The package name to use to locate the download cache. i.e. for ``pkgname='astropy'`` the default cache location is ``~/.astropy/cache``. Returns ------- in_cache : bool `True` if a download for ``url_key`` is in the cache, `False` if not or if the cache does not exist at all. See Also -------- cache_contents : obtain a dictionary listing everything in the cache """ try: dldir = _get_download_cache_loc(pkgname) except OSError: return False filename = os.path.join(dldir, _url_to_dirname(url_key), "contents") return os.path.exists(filename) def cache_total_size(pkgname='astropy'): """Return the total size in bytes of all files in the cache.""" size = 0 dldir = _get_download_cache_loc(pkgname=pkgname) for root, dirs, files in os.walk(dldir): size += sum(os.path.getsize(os.path.join(root, name)) for name in files) return size def _do_download_files_in_parallel(kwargs): with astropy.config.paths.set_temp_config(kwargs.pop("temp_config")): with astropy.config.paths.set_temp_cache(kwargs.pop("temp_cache")): return download_file(**kwargs) def download_files_in_parallel(urls, cache="update", show_progress=True, timeout=None, sources=None, multiprocessing_start_method=None, pkgname='astropy'): """Download multiple files in parallel from the given URLs. Blocks until all files have downloaded. The result is a list of local file paths corresponding to the given urls. The results will be stored in the cache under the values in ``urls`` even if they are obtained from some other location via ``sources``. See `~download_file` for details. Parameters ---------- urls : list of str The URLs to retrieve. cache : bool or "update", optional Whether to use the cache (default is `True`). If "update", always download the remote URLs to see if new data is available and store the result in cache. .. versionchanged:: 4.0 The default was changed to ``"update"`` and setting it to ``False`` will print a Warning and set it to ``"update"`` again, because the function will not work properly without cache. Using ``True`` will work as expected. .. versionchanged:: 3.0 The default was changed to ``True`` and setting it to ``False`` will print a Warning and set it to ``True`` again, because the function will not work properly without cache. show_progress : bool, optional Whether to display a progress bar during the download (default is `True`) timeout : float, optional Timeout for each individual requests in seconds (default is the configurable `astropy.utils.data.Conf.remote_timeout`). sources : dict, optional If provided, for each URL a list of URLs to try to obtain the file from. The result will be stored under the original URL. For any URL in this dictionary, the original URL will *not* be tried unless it is in this list; this is to prevent long waits for a primary server that is known to be inaccessible at the moment. multiprocessing_start_method : str, optional Useful primarily for testing; if in doubt leave it as the default. When using multiprocessing, certain anomalies occur when starting processes with the "spawn" method (the only option on Windows); other anomalies occur with the "fork" method (the default on Linux). pkgname : `str`, optional The package name to use to locate the download cache. i.e. for ``pkgname='astropy'`` the default cache location is ``~/.astropy/cache``. Returns ------- paths : list of str The local file paths corresponding to the downloaded URLs. Notes ----- If a URL is unreachable, the downloading will grind to a halt and the exception will propagate upward, but an unpredictable number of files will have been successfully downloaded and will remain in the cache. """ from .console import ProgressBar if timeout is None: timeout = conf.remote_timeout if sources is None: sources = {} if not cache: # See issue #6662, on windows won't work because the files are removed # again before they can be used. On *NIX systems it will behave as if # cache was set to True because multiprocessing cannot insert the items # in the list of to-be-removed files. This could be fixed, but really, # just use the cache, with update_cache if appropriate. warn('Disabling the cache does not work because of multiprocessing, ' 'it will be set to ``"update"``. You may need to manually remove ' 'the cached files with clear_download_cache() afterwards.', AstropyWarning) cache = "update" if show_progress: progress = sys.stdout else: progress = io.BytesIO() # Combine duplicate URLs combined_urls = list(set(urls)) combined_paths = ProgressBar.map( _do_download_files_in_parallel, [dict(remote_url=u, cache=cache, show_progress=False, timeout=timeout, sources=sources.get(u, None), pkgname=pkgname, temp_cache=astropy.config.paths.set_temp_cache._temp_path, temp_config=astropy.config.paths.set_temp_config._temp_path) for u in combined_urls], file=progress, multiprocess=True, multiprocessing_start_method=multiprocessing_start_method, ) paths = [] for url in urls: paths.append(combined_paths[combined_urls.index(url)]) return paths # This is used by download_file and _deltemps to determine the files to delete # when the interpreter exits _tempfilestodel = [] @atexit.register def _deltemps(): global _tempfilestodel if _tempfilestodel is not None: while len(_tempfilestodel) > 0: fn = _tempfilestodel.pop() if os.path.isfile(fn): try: os.remove(fn) except OSError: # oh well we tried # could be held open by some process, on Windows pass elif os.path.isdir(fn): try: shutil.rmtree(fn) except OSError: # couldn't get rid of it, sorry # could be held open by some process, on Windows pass def clear_download_cache(hashorurl=None, pkgname='astropy'): """Clears the data file cache by deleting the local file(s). If a URL is provided, it will be the name used in the cache. The contents may have been downloaded from this URL or from a mirror or they may have been provided by the user. See `~download_file` for details. For the purposes of this function, a file can also be identified by a hash of its contents or by the filename under which the data is stored (as returned by `~download_file`, for example). Parameters ---------- hashorurl : str or None If None, the whole cache is cleared. Otherwise, specify a hash for the cached file that is supposed to be deleted, the full path to a file in the cache that should be deleted, or a URL that should be removed from the cache if present. pkgname : `str`, optional The package name to use to locate the download cache. i.e. for ``pkgname='astropy'`` the default cache location is ``~/.astropy/cache``. """ try: dldir = _get_download_cache_loc(pkgname) except OSError as e: # Problem arose when trying to open the cache # Just a warning, though msg = 'Not clearing data cache - cache inaccessible due to ' estr = '' if len(e.args) < 1 else (': ' + str(e)) warn(CacheMissingWarning(msg + e.__class__.__name__ + estr)) return try: if hashorurl is None: # Optional: delete old incompatible caches too _rmtree(dldir) elif _is_url(hashorurl): filepath = os.path.join(dldir, _url_to_dirname(hashorurl)) _rmtree(filepath) else: # Not a URL, it should be either a filename or a hash filepath = os.path.join(dldir, hashorurl) rp = os.path.relpath(filepath, dldir) if rp.startswith(".."): raise RuntimeError( f"attempted to use clear_download_cache on the path " f"{filepath} outside the data cache directory {dldir}") d, f = os.path.split(rp) if d and f in ["contents", "url"]: # It's a filename not the hash of a URL # so we want to zap the directory containing the # files "url" and "contents" filepath = os.path.join(dldir, d) if os.path.exists(filepath): _rmtree(filepath) elif (len(hashorurl) == 2*hashlib.md5().digest_size and re.match(r"[0-9a-f]+", hashorurl)): # It's the hash of some file contents, we have to find the right file filename = _find_hash_fn(hashorurl) if filename is not None: clear_download_cache(filename) except OSError as e: msg = 'Not clearing data from cache - problem arose ' estr = '' if len(e.args) < 1 else (': ' + str(e)) warn(CacheMissingWarning(msg + e.__class__.__name__ + estr)) def _get_download_cache_loc(pkgname='astropy'): """Finds the path to the cache directory and makes them if they don't exist. Parameters ---------- pkgname : `str`, optional The package name to use to locate the download cache. i.e. for ``pkgname='astropy'`` the default cache location is ``~/.astropy/cache``. Returns ------- datadir : str The path to the data cache directory. """ try: datadir = os.path.join(astropy.config.paths.get_cache_dir(pkgname), 'download', 'url') if not os.path.exists(datadir): try: os.makedirs(datadir) except OSError: if not os.path.exists(datadir): raise elif not os.path.isdir(datadir): raise OSError(f'Data cache directory {datadir} is not a directory') return datadir except OSError as e: msg = 'Remote data cache could not be accessed due to ' estr = '' if len(e.args) < 1 else (': ' + str(e)) warn(CacheMissingWarning(msg + e.__class__.__name__ + estr)) raise def _url_to_dirname(url): if not _is_url(url): raise ValueError(f"Malformed URL: '{url}'") # Make domain names case-insensitive # Also makes the http:// case-insensitive urlobj = list(urllib.parse.urlsplit(url)) urlobj[1] = urlobj[1].lower() if urlobj[0].lower() in ['http', 'https'] and urlobj[1] and urlobj[2] == '': urlobj[2] = '/' url_c = urllib.parse.urlunsplit(urlobj) return hashlib.md5(url_c.encode("utf-8")).hexdigest() class ReadOnlyDict(dict): def __setitem__(self, key, value): raise TypeError("This object is read-only.") _NOTHING = ReadOnlyDict({}) class CacheDamaged(ValueError): """Record the URL or file that was a problem. Using clear_download_cache on the .bad_file or .bad_url attribute, whichever is not None, should resolve this particular problem. """ def __init__(self, *args, bad_urls=None, bad_files=None, **kwargs): super().__init__(*args, **kwargs) self.bad_urls = bad_urls if bad_urls is not None else [] self.bad_files = bad_files if bad_files is not None else [] def check_download_cache(pkgname='astropy'): """Do a consistency check on the cache. .. note:: Since v5.0, this function no longer returns anything. Because the cache is shared by all versions of ``astropy`` in all virtualenvs run by your user, possibly concurrently, it could accumulate problems. This could lead to hard-to-debug problems or wasted space. This function detects a number of incorrect conditions, including nonexistent files that are indexed, files that are indexed but in the wrong place, and, if you request it, files whose content does not match the hash that is indexed. This function also returns a list of non-indexed files. A few will be associated with the shelve object; their exact names depend on the backend used but will probably be based on ``urlmap``. The presence of other files probably indicates that something has gone wrong and inaccessible files have accumulated in the cache. These can be removed with :func:`clear_download_cache`, either passing the filename returned here, or with no arguments to empty the entire cache and return it to a reasonable, if empty, state. Parameters ---------- pkgname : str, optional The package name to use to locate the download cache, i.e., for ``pkgname='astropy'`` the default cache location is ``~/.astropy/cache``. Raises ------ `~astropy.utils.data.CacheDamaged` To indicate a problem with the cache contents; the exception contains a ``.bad_files`` attribute containing a set of filenames to allow the user to use :func:`clear_download_cache` to remove the offending items. OSError, RuntimeError To indicate some problem with the cache structure. This may need a full :func:`clear_download_cache` to resolve, or may indicate some kind of misconfiguration. """ bad_files = set() messages = set() dldir = _get_download_cache_loc(pkgname=pkgname) with os.scandir(dldir) as it: for entry in it: f = os.path.abspath(os.path.join(dldir, entry.name)) if entry.name.startswith("rmtree-"): if f not in _tempfilestodel: bad_files.add(f) messages.add(f"Cache entry {entry.name} not scheduled for deletion") elif entry.is_dir(): for sf in os.listdir(f): if sf in ['url', 'contents']: continue sf = os.path.join(f, sf) bad_files.add(sf) messages.add(f"Unexpected file f{sf}") urlf = os.path.join(f, "url") url = None if not os.path.isfile(urlf): bad_files.add(urlf) messages.add(f"Problem with URL file f{urlf}") else: url = get_file_contents(urlf, encoding="utf-8") if not _is_url(url): bad_files.add(f) messages.add(f"Malformed URL: {url}") else: hashname = _url_to_dirname(url) if entry.name != hashname: bad_files.add(f) messages.add(f"URL hashes to {hashname} but is stored in {entry.name}") if not os.path.isfile(os.path.join(f, "contents")): bad_files.add(f) if url is None: messages.add(f"Hash {entry.name} is missing contents") else: messages.add(f"URL {url} with hash {entry.name} is missing contents") else: bad_files.add(f) messages.add(f"Left-over non-directory {f} in cache") if bad_files: raise CacheDamaged("\n".join(messages), bad_files=bad_files) @contextlib.contextmanager def _SafeTemporaryDirectory(suffix=None, prefix=None, dir=None): """Temporary directory context manager This will not raise an exception if the temporary directory goes away before it's supposed to be deleted. Specifically, what is deleted will be the directory *name* produced; if no such directory exists, no exception will be raised. It would be safer to delete it only if it's really the same directory - checked by file descriptor - and if it's still called the same thing. But that opens a platform-specific can of worms. It would also be more robust to use ExitStack and TemporaryDirectory, which is more aggressive about removing readonly things. """ d = mkdtemp(suffix=suffix, prefix=prefix, dir=dir) try: yield d finally: try: shutil.rmtree(d) except OSError: pass def _rmtree(path, replace=None): """More-atomic rmtree. Ignores missing directory.""" with TemporaryDirectory(prefix="rmtree-", dir=os.path.dirname(os.path.abspath(path))) as d: try: os.rename(path, os.path.join(d, "to-zap")) except FileNotFoundError: pass except PermissionError: warn(CacheMissingWarning( f"Unable to remove directory {path} because a file in it " f"is in use and you are on Windows", path)) raise if replace is not None: try: os.rename(replace, path) except FileExistsError: # already there, fine pass except OSError as e: if e.errno == errno.ENOTEMPTY: # already there, fine pass else: raise def import_file_to_cache(url_key, filename, remove_original=False, pkgname='astropy', *, replace=True): """Import the on-disk file specified by filename to the cache. The provided ``url_key`` will be the name used in the cache. The file should contain the contents of this URL, at least notionally (the URL may be temporarily or permanently unavailable). It is using ``url_key`` that users will request these contents from the cache. See :func:`download_file` for details. If ``url_key`` already exists in the cache, it will be updated to point to these imported contents, and its old contents will be deleted from the cache. Parameters ---------- url_key : str The key to index the file under. This should probably be the URL where the file was located, though if you obtained it from a mirror you should use the URL of the primary location. filename : str The file whose contents you want to import. remove_original : bool Whether to remove the original file (``filename``) once import is complete. pkgname : `str`, optional The package name to use to locate the download cache. i.e. for ``pkgname='astropy'`` the default cache location is ``~/.astropy/cache``. replace : boolean, optional Whether or not to replace an existing object in the cache, if one exists. If replacement is not requested but the object exists, silently pass. """ cache_dir = _get_download_cache_loc(pkgname=pkgname) cache_dirname = _url_to_dirname(url_key) local_dirname = os.path.join(cache_dir, cache_dirname) local_filename = os.path.join(local_dirname, "contents") with _SafeTemporaryDirectory(prefix="temp_dir", dir=cache_dir) as temp_dir: temp_filename = os.path.join(temp_dir, "contents") # Make sure we're on the same filesystem # This will raise an exception if the url_key doesn't turn into a valid filename shutil.copy(filename, temp_filename) with open(os.path.join(temp_dir, "url"), "wt", encoding="utf-8") as f: f.write(url_key) if replace: _rmtree(local_dirname, replace=temp_dir) else: try: os.rename(temp_dir, local_dirname) except FileExistsError: # already there, fine pass except OSError as e: if e.errno == errno.ENOTEMPTY: # already there, fine pass else: raise if remove_original: os.remove(filename) return os.path.abspath(local_filename) def get_cached_urls(pkgname='astropy'): """ Get the list of URLs in the cache. Especially useful for looking up what files are stored in your cache when you don't have internet access. The listed URLs are the keys programs should use to access the file contents, but those contents may have actually been obtained from a mirror. See `~download_file` for details. Parameters ---------- pkgname : `str`, optional The package name to use to locate the download cache. i.e. for ``pkgname='astropy'`` the default cache location is ``~/.astropy/cache``. Returns ------- cached_urls : list List of cached URLs. See Also -------- cache_contents : obtain a dictionary listing everything in the cache """ return sorted(cache_contents(pkgname=pkgname).keys()) def cache_contents(pkgname='astropy'): """Obtain a dict mapping cached URLs to filenames. This dictionary is a read-only snapshot of the state of the cache when this function was called. If other processes are actively working with the cache, it is possible for them to delete files that are listed in this dictionary. Use with some caution if you are working on a system that is busy with many running astropy processes, although the same issues apply to most functions in this module. """ r = {} try: dldir = _get_download_cache_loc(pkgname=pkgname) except OSError: return _NOTHING with os.scandir(dldir) as it: for entry in it: if entry.is_dir: url = get_file_contents(os.path.join(dldir, entry.name, "url"), encoding="utf-8") r[url] = os.path.abspath(os.path.join(dldir, entry.name, "contents")) return ReadOnlyDict(r) def export_download_cache(filename_or_obj, urls=None, overwrite=False, pkgname='astropy'): """Exports the cache contents as a ZIP file. Parameters ---------- filename_or_obj : str or file-like Where to put the created ZIP file. Must be something the zipfile module can write to. urls : iterable of str or None The URLs to include in the exported cache. The default is all URLs currently in the cache. If a URL is included in this list but is not currently in the cache, a KeyError will be raised. To ensure that all are in the cache use `~download_file` or `~download_files_in_parallel`. overwrite : bool, optional If filename_or_obj is a filename that exists, it will only be overwritten if this is True. pkgname : `str`, optional The package name to use to locate the download cache. i.e. for ``pkgname='astropy'`` the default cache location is ``~/.astropy/cache``. See Also -------- import_download_cache : import the contents of such a ZIP file import_file_to_cache : import a single file directly """ if urls is None: urls = get_cached_urls(pkgname) with zipfile.ZipFile(filename_or_obj, 'w' if overwrite else 'x') as z: for u in urls: fn = download_file(u, cache=True, sources=[], pkgname=pkgname) # Do not use os.path.join because ZIP files want # "/" on all platforms z_fn = urllib.parse.quote(u, safe="") z.write(fn, z_fn) def import_download_cache(filename_or_obj, urls=None, update_cache=False, pkgname='astropy'): """Imports the contents of a ZIP file into the cache. Each member of the ZIP file should be named by a quoted version of the URL whose contents it stores. These names are decoded with :func:`~urllib.parse.unquote`. Parameters ---------- filename_or_obj : str or file-like Where the stored ZIP file is. Must be something the :mod:`~zipfile` module can read from. urls : set of str or list of str or None The URLs to import from the ZIP file. The default is all URLs in the file. update_cache : bool, optional If True, any entry in the ZIP file will overwrite the value in the cache; if False, leave untouched any entry already in the cache. pkgname : `str`, optional The package name to use to locate the download cache. i.e. for ``pkgname='astropy'`` the default cache location is ``~/.astropy/cache``. See Also -------- export_download_cache : export the contents the cache to of such a ZIP file import_file_to_cache : import a single file directly """ with zipfile.ZipFile(filename_or_obj, 'r') as z, TemporaryDirectory() as d: for i, zf in enumerate(z.infolist()): url = urllib.parse.unquote(zf.filename) # FIXME(aarchiba): do we want some kind of validation on this URL? # urllib.parse might do something sensible...but what URLs might # they have? # is_url in this file is probably a good check, not just here # but throughout this file. if urls is not None and url not in urls: continue if not update_cache and is_url_in_cache(url, pkgname=pkgname): continue f_temp_name = os.path.join(d, str(i)) with z.open(zf) as f_zip, open(f_temp_name, "wb") as f_temp: block = f_zip.read(conf.download_block_size) while block: f_temp.write(block) block = f_zip.read(conf.download_block_size) import_file_to_cache(url, f_temp_name, remove_original=True, pkgname=pkgname) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/data_info.py0000644000175100001710000006475400000000000017424 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """This module contains functions and methods that relate to the DataInfo class which provides a container for informational attributes as well as summary info methods. A DataInfo object is attached to the Quantity, SkyCoord, and Time classes in astropy. Here it allows those classes to be used in Tables and uniformly carry table column attributes such as name, format, dtype, meta, and description. """ # Note: these functions and classes are tested extensively in astropy table # tests via their use in providing mixin column info, and in # astropy/tests/test_info for providing table and column info summary data. import os import re import sys import weakref import warnings from io import StringIO from copy import deepcopy from functools import partial from collections import OrderedDict from contextlib import contextmanager import numpy as np from . import metadata __all__ = ['data_info_factory', 'dtype_info_name', 'BaseColumnInfo', 'DataInfo', 'MixinInfo', 'ParentDtypeInfo'] # Tuple of filterwarnings kwargs to ignore when calling info IGNORE_WARNINGS = (dict(category=RuntimeWarning, message='All-NaN|' 'Mean of empty slice|Degrees of freedom <= 0|' 'invalid value encountered in sqrt'),) STRING_TYPE_NAMES = {(False, 'S'): 'str', # not PY3 (False, 'U'): 'unicode', (True, 'S'): 'bytes', # PY3 (True, 'U'): 'str'} @contextmanager def serialize_context_as(context): """Set context for serialization. This will allow downstream code to understand the context in which a column is being serialized. Objects like Time or SkyCoord will have different default serialization representations depending on context. Parameters ---------- context : str Context name, e.g. 'fits', 'hdf5', 'parquet', 'ecsv', 'yaml' """ old_context = BaseColumnInfo._serialize_context BaseColumnInfo._serialize_context = context try: yield finally: BaseColumnInfo._serialize_context = old_context def dtype_info_name(dtype): """Return a human-oriented string name of the ``dtype`` arg. This can be use by astropy methods that present type information about a data object. The output is mostly equivalent to ``dtype.name`` which takes the form [B] where is like ``int`` or ``bool`` and [B] is an optional number of bits which gets included only for numeric types. For bytes, string and unicode types, the output is shown below, where is the number of characters. This representation corresponds to the Python type that matches the dtype:: Numpy S U Python bytes str Parameters ---------- dtype : str, `~numpy.dtype`, type Input dtype as an object that can be converted via np.dtype() Returns ------- dtype_info_name : str String name of ``dtype`` """ dtype = np.dtype(dtype) if dtype.kind in ('S', 'U'): length = re.search(r'(\d+)', dtype.str).group(1) type_name = STRING_TYPE_NAMES[(True, dtype.kind)] out = type_name + length else: out = dtype.name return out def data_info_factory(names, funcs): """ Factory to create a function that can be used as an ``option`` for outputting data object summary information. Examples -------- >>> from astropy.utils.data_info import data_info_factory >>> from astropy.table import Column >>> c = Column([4., 3., 2., 1.]) >>> mystats = data_info_factory(names=['min', 'median', 'max'], ... funcs=[np.min, np.median, np.max]) >>> c.info(option=mystats) min = 1 median = 2.5 max = 4 n_bad = 0 length = 4 Parameters ---------- names : list List of information attribute names funcs : list List of functions that compute the corresponding information attribute Returns ------- func : function Function that can be used as a data info option """ def func(dat): outs = [] for name, func in zip(names, funcs): try: if isinstance(func, str): out = getattr(dat, func)() else: out = func(dat) except Exception: outs.append('--') else: try: outs.append(f'{out:g}') except (TypeError, ValueError): outs.append(str(out)) return OrderedDict(zip(names, outs)) return func def _get_obj_attrs_map(obj, attrs): """ Get the values for object ``attrs`` and return as a dict. This ignores any attributes that are None and in Py2 converts any unicode attribute names or values to str. In the context of serializing the supported core astropy classes this conversion will succeed and results in more succinct and less python-specific YAML. """ out = {} for attr in attrs: val = getattr(obj, attr, None) if val is not None: out[attr] = val return out def _get_data_attribute(dat, attr=None): """ Get a data object attribute for the ``attributes`` info summary method """ if attr == 'class': val = type(dat).__name__ elif attr == 'dtype': val = dtype_info_name(dat.info.dtype) elif attr == 'shape': datshape = dat.shape[1:] val = datshape if datshape else '' else: val = getattr(dat.info, attr) if val is None: val = '' return str(val) class InfoAttribute: def __init__(self, attr, default=None): self.attr = attr self.default = default def __get__(self, instance, owner_cls): if instance is None: return self return instance._attrs.get(self.attr, self.default) def __set__(self, instance, value): if instance is None: # This is an unbound descriptor on the class raise ValueError('cannot set unbound descriptor') instance._attrs[self.attr] = value class ParentAttribute: def __init__(self, attr): self.attr = attr def __get__(self, instance, owner_cls): if instance is None: return self return getattr(instance._parent, self.attr) def __set__(self, instance, value): if instance is None: # This is an unbound descriptor on the class raise ValueError('cannot set unbound descriptor') setattr(instance._parent, self.attr, value) class DataInfoMeta(type): def __new__(mcls, name, bases, dct): # Ensure that we do not gain a __dict__, which would mean # arbitrary attributes could be set. dct.setdefault('__slots__', []) return super().__new__(mcls, name, bases, dct) def __init__(cls, name, bases, dct): super().__init__(name, bases, dct) # Define default getters/setters for attributes, if needed. for attr in cls.attr_names: if attr not in dct: # If not defined explicitly for this class, did any of # its superclasses define it, and, if so, was this an # automatically defined look-up-on-parent attribute? cls_attr = getattr(cls, attr, None) if attr in cls.attrs_from_parent: # If the attribute is supposed to be stored on the parent, # and that is stated by this class yet it was not the case # on the superclass, override it. if 'attrs_from_parent' in dct and not isinstance(cls_attr, ParentAttribute): setattr(cls, attr, ParentAttribute(attr)) elif not cls_attr or isinstance(cls_attr, ParentAttribute): # If the attribute is not meant to be stored on the parent, # and if it was not defined already or was previously defined # as an attribute on the parent, define a regular # look-up-on-info attribute setattr(cls, attr, InfoAttribute(attr, cls._attr_defaults.get(attr))) class DataInfo(metaclass=DataInfoMeta): """ Descriptor that data classes use to add an ``info`` attribute for storing data attributes in a uniform and portable way. Note that it *must* be called ``info`` so that the DataInfo() object can be stored in the ``instance`` using the ``info`` key. Because owner_cls.x is a descriptor, Python doesn't use __dict__['x'] normally, and the descriptor can safely store stuff there. Thanks to https://nbviewer.jupyter.org/urls/gist.github.com/ChrisBeaumont/5758381/raw/descriptor_writeup.ipynb for this trick that works for non-hashable classes. Parameters ---------- bound : bool If True this is a descriptor attribute in a class definition, else it is a DataInfo() object that is bound to a data object instance. Default is False. """ _stats = ['mean', 'std', 'min', 'max'] attrs_from_parent = set() attr_names = set(['name', 'unit', 'dtype', 'format', 'description', 'meta']) _attr_defaults = {'dtype': np.dtype('O')} _attrs_no_copy = set() _info_summary_attrs = ('dtype', 'shape', 'unit', 'format', 'description', 'class') __slots__ = ['_parent_cls', '_parent_ref', '_attrs'] # This specifies the list of object attributes which must be stored in # order to re-create the object after serialization. This is independent # of normal `info` attributes like name or description. Subclasses will # generally either define this statically (QuantityInfo) or dynamically # (SkyCoordInfo). These attributes may be scalars or arrays. If arrays # that match the object length they will be serialized as an independent # column. _represent_as_dict_attrs = () # This specifies attributes which are to be provided to the class # initializer as ordered args instead of keyword args. This is needed # for Quantity subclasses where the keyword for data varies (e.g. # between Quantity and Angle). _construct_from_dict_args = () # This specifies the name of an attribute which is the "primary" data. # Then when representing as columns # (table.serialize._represent_mixin_as_column) the output for this # attribute will be written with the just name of the mixin instead of the # usual ".". _represent_as_dict_primary_data = None def __init__(self, bound=False): # If bound to a data object instance then create the dict of attributes # which stores the info attribute values. Default of None for "unset" # except for dtype where the default is object. if bound: self._attrs = {} @property def _parent(self): try: parent = self._parent_ref() except AttributeError: return None if parent is None: raise AttributeError("""\ failed access "info" attribute on a temporary object. It looks like you have done something like ``col[3:5].info``, i.e. you accessed ``info`` from a temporary slice object ``col[3:5]`` that only exists momentarily. This has failed because the reference to that temporary object is now lost. Instead force a permanent reference with ``c = col[3:5]`` followed by ``c.info``.""") return parent def __get__(self, instance, owner_cls): if instance is None: # This is an unbound descriptor on the class self._parent_cls = owner_cls return self info = instance.__dict__.get('info') if info is None: info = instance.__dict__['info'] = self.__class__(bound=True) # We set _parent_ref on every call, since if one makes copies of # instances, 'info' will be copied as well, which will lose the # reference. info._parent_ref = weakref.ref(instance) return info def __set__(self, instance, value): if instance is None: # This is an unbound descriptor on the class raise ValueError('cannot set unbound descriptor') if isinstance(value, DataInfo): info = instance.__dict__['info'] = self.__class__(bound=True) attr_names = info.attr_names if value.__class__ is self.__class__: # For same class, attributes are guaranteed to be stored in # _attrs, so speed matters up by not accessing defaults. # Doing this before difference in for loop helps speed. attr_names = attr_names & set(value._attrs) # NOT in-place! else: # For different classes, copy over the attributes in common. attr_names = attr_names & (value.attr_names - value._attrs_no_copy) for attr in attr_names - info.attrs_from_parent - info._attrs_no_copy: info._attrs[attr] = deepcopy(getattr(value, attr)) else: raise TypeError('info must be set with a DataInfo instance') def __getstate__(self): return self._attrs def __setstate__(self, state): self._attrs = state def _represent_as_dict(self, attrs=None): """Get the values for the parent ``attrs`` and return as a dict. By default, uses '_represent_as_dict_attrs'. """ if attrs is None: attrs = self._represent_as_dict_attrs return _get_obj_attrs_map(self._parent, attrs) def _construct_from_dict(self, map): args = [map.pop(attr) for attr in self._construct_from_dict_args] return self._parent_cls(*args, **map) info_summary_attributes = staticmethod( data_info_factory(names=_info_summary_attrs, funcs=[partial(_get_data_attribute, attr=attr) for attr in _info_summary_attrs])) # No nan* methods in numpy < 1.8 info_summary_stats = staticmethod( data_info_factory(names=_stats, funcs=[getattr(np, 'nan' + stat) for stat in _stats])) def __call__(self, option='attributes', out=''): """ Write summary information about data object to the ``out`` filehandle. By default this prints to standard output via sys.stdout. The ``option`` argument specifies what type of information to include. This can be a string, a function, or a list of strings or functions. Built-in options are: - ``attributes``: data object attributes like ``dtype`` and ``format`` - ``stats``: basic statistics: min, mean, and max If a function is specified then that function will be called with the data object as its single argument. The function must return an OrderedDict containing the information attributes. If a list is provided then the information attributes will be appended for each of the options, in order. Examples -------- >>> from astropy.table import Column >>> c = Column([1, 2], unit='m', dtype='int32') >>> c.info() dtype = int32 unit = m class = Column n_bad = 0 length = 2 >>> c.info(['attributes', 'stats']) dtype = int32 unit = m class = Column mean = 1.5 std = 0.5 min = 1 max = 2 n_bad = 0 length = 2 Parameters ---------- option : str, callable, list of (str or callable) Info option, defaults to 'attributes'. out : file-like, None Output destination, defaults to sys.stdout. If None then the OrderedDict with information attributes is returned Returns ------- info : `~collections.OrderedDict` or None `~collections.OrderedDict` if out==None else None """ if out == '': out = sys.stdout dat = self._parent info = OrderedDict() name = dat.info.name if name is not None: info['name'] = name options = option if isinstance(option, (list, tuple)) else [option] for option in options: if isinstance(option, str): if hasattr(self, 'info_summary_' + option): option = getattr(self, 'info_summary_' + option) else: raise ValueError('option={} is not an allowed information type' .format(option)) with warnings.catch_warnings(): for ignore_kwargs in IGNORE_WARNINGS: warnings.filterwarnings('ignore', **ignore_kwargs) info.update(option(dat)) if hasattr(dat, 'mask'): n_bad = np.count_nonzero(dat.mask) else: try: n_bad = np.count_nonzero(np.isinf(dat) | np.isnan(dat)) except Exception: n_bad = 0 info['n_bad'] = n_bad try: info['length'] = len(dat) except (TypeError, IndexError): pass if out is None: return info for key, val in info.items(): if val != '': out.write(f'{key} = {val}' + os.linesep) def __repr__(self): if self._parent is None: return super().__repr__() out = StringIO() self.__call__(out=out) return out.getvalue() class BaseColumnInfo(DataInfo): """ Base info class for anything that can be a column in an astropy Table. There are at least two classes that inherit from this: ColumnInfo: for native astropy Column / MaskedColumn objects MixinInfo: for mixin column objects Note that this class is defined here so that mixins can use it without importing the table package. """ attr_names = DataInfo.attr_names.union(['parent_table', 'indices']) _attrs_no_copy = set(['parent_table', 'indices']) # Context for serialization. This can be set temporarily via # ``serialize_context_as(context)`` context manager to allow downstream # code to understand the context in which a column is being serialized. # Typical values are 'fits', 'hdf5', 'parquet', 'ecsv', 'yaml'. Objects # like Time or SkyCoord will have different default serialization # representations depending on context. _serialize_context = None __slots__ = ['_format_funcs', '_copy_indices'] @property def parent_table(self): value = self._attrs.get('parent_table') if callable(value): value = value() return value @parent_table.setter def parent_table(self, parent_table): if parent_table is None: self._attrs.pop('parent_table', None) else: parent_table = weakref.ref(parent_table) self._attrs['parent_table'] = parent_table def __init__(self, bound=False): super().__init__(bound=bound) # If bound to a data object instance then add a _format_funcs dict # for caching functions for print formatting. if bound: self._format_funcs = {} def __set__(self, instance, value): # For Table columns do not set `info` when the instance is a scalar. try: if not instance.shape: return except AttributeError: pass super().__set__(instance, value) def iter_str_vals(self): """ This is a mixin-safe version of Column.iter_str_vals. """ col = self._parent if self.parent_table is None: from astropy.table.column import FORMATTER as formatter else: formatter = self.parent_table.formatter _pformat_col_iter = formatter._pformat_col_iter for str_val in _pformat_col_iter(col, -1, False, False, {}): yield str_val @property def indices(self): # Implementation note: the auto-generation as an InfoAttribute cannot # be used here, since on access, one should not just return the # default (empty list is this case), but set _attrs['indices'] so that # if the list is appended to, it is registered here. return self._attrs.setdefault('indices', []) @indices.setter def indices(self, indices): self._attrs['indices'] = indices def adjust_indices(self, index, value, col_len): ''' Adjust info indices after column modification. Parameters ---------- index : slice, int, list, or ndarray Element(s) of column to modify. This parameter can be a single row number, a list of row numbers, an ndarray of row numbers, a boolean ndarray (a mask), or a column slice. value : int, list, or ndarray New value(s) to insert col_len : int Length of the column ''' if not self.indices: return if isinstance(index, slice): # run through each key in slice t = index.indices(col_len) keys = list(range(*t)) elif isinstance(index, np.ndarray) and index.dtype.kind == 'b': # boolean mask keys = np.where(index)[0] else: # single int keys = [index] value = np.atleast_1d(value) # turn array(x) into array([x]) if value.size == 1: # repeat single value value = list(value) * len(keys) for key, val in zip(keys, value): for col_index in self.indices: col_index.replace(key, self.name, val) def slice_indices(self, col_slice, item, col_len): ''' Given a sliced object, modify its indices to correctly represent the slice. Parameters ---------- col_slice : `~astropy.table.Column` or mixin Sliced object. If not a column, it must be a valid mixin, see https://docs.astropy.org/en/stable/table/mixin_columns.html item : slice, list, or ndarray Slice used to create col_slice col_len : int Length of original object ''' from astropy.table.sorted_array import SortedArray if not getattr(self, '_copy_indices', True): # Necessary because MaskedArray will perform a shallow copy col_slice.info.indices = [] return col_slice elif isinstance(item, slice): col_slice.info.indices = [x[item] for x in self.indices] elif self.indices: if isinstance(item, np.ndarray) and item.dtype.kind == 'b': # boolean mask item = np.where(item)[0] # Empirical testing suggests that recreating a BST/RBT index is # more effective than relabelling when less than ~60% of # the total number of rows are involved, and is in general # more effective for SortedArray. small = len(item) <= 0.6 * col_len col_slice.info.indices = [] for index in self.indices: if small or isinstance(index, SortedArray): new_index = index.get_slice(col_slice, item) else: new_index = deepcopy(index) new_index.replace_rows(item) col_slice.info.indices.append(new_index) return col_slice @staticmethod def merge_cols_attributes(cols, metadata_conflicts, name, attrs): """ Utility method to merge and validate the attributes ``attrs`` for the input table columns ``cols``. Note that ``dtype`` and ``shape`` attributes are handled specially. These should not be passed in ``attrs`` but will always be in the returned dict of merged attributes. Parameters ---------- cols : list List of input Table column objects metadata_conflicts : str ('warn'|'error'|'silent') How to handle metadata conflicts name : str Output column name attrs : list List of attribute names to be merged Returns ------- attrs : dict Of merged attributes. """ from astropy.table.np_utils import TableMergeError def warn_str_func(key, left, right): out = ("In merged column '{}' the '{}' attribute does not match " "({} != {}). Using {} for merged output" .format(name, key, left, right, right)) return out def getattrs(col): return {attr: getattr(col.info, attr) for attr in attrs if getattr(col.info, attr, None) is not None} out = getattrs(cols[0]) for col in cols[1:]: out = metadata.merge(out, getattrs(col), metadata_conflicts=metadata_conflicts, warn_str_func=warn_str_func) # Output dtype is the superset of all dtypes in in_cols out['dtype'] = metadata.common_dtype(cols) # Make sure all input shapes are the same uniq_shapes = set(col.shape[1:] for col in cols) if len(uniq_shapes) != 1: raise TableMergeError('columns have different shapes') out['shape'] = uniq_shapes.pop() # "Merged" output name is the supplied name if name is not None: out['name'] = name return out def get_sortable_arrays(self): """ Return a list of arrays which can be lexically sorted to represent the order of the parent column. The base method raises NotImplementedError and must be overridden. Returns ------- arrays : list of ndarray """ raise NotImplementedError(f'column {self.name} is not sortable') class MixinInfo(BaseColumnInfo): @property def name(self): return self._attrs.get('name') @name.setter def name(self, name): # For mixin columns that live within a table, rename the column in the # table when setting the name attribute. This mirrors the same # functionality in the BaseColumn class. if self.parent_table is not None: from astropy.table.np_utils import fix_column_name new_name = fix_column_name(name) # Ensure col name is numpy compatible self.parent_table.columns._rename_column(self.name, new_name) self._attrs['name'] = name class ParentDtypeInfo(MixinInfo): """Mixin that gets info.dtype from parent""" attrs_from_parent = set(['dtype']) # dtype and unit taken from parent ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/decorators.py0000644000175100001710000011536200000000000017635 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """Sundry function and class decorators.""" import functools import inspect import textwrap import threading import types import warnings from inspect import signature from .exceptions import (AstropyDeprecationWarning, AstropyUserWarning, AstropyPendingDeprecationWarning) __all__ = ['classproperty', 'deprecated', 'deprecated_attribute', 'deprecated_renamed_argument', 'format_doc', 'lazyproperty', 'sharedmethod'] _NotFound = object() def deprecated(since, message='', name='', alternative='', pending=False, obj_type=None, warning_type=AstropyDeprecationWarning): """ Used to mark a function or class as deprecated. To mark an attribute as deprecated, use `deprecated_attribute`. Parameters ---------- since : str The release at which this API became deprecated. This is required. message : str, optional Override the default deprecation message. The format specifier ``func`` may be used for the name of the function, and ``alternative`` may be used in the deprecation message to insert the name of an alternative to the deprecated function. ``obj_type`` may be used to insert a friendly name for the type of object being deprecated. name : str, optional The name of the deprecated function or class; if not provided the name is automatically determined from the passed in function or class, though this is useful in the case of renamed functions, where the new function is just assigned to the name of the deprecated function. For example:: def new_function(): ... oldFunction = new_function alternative : str, optional An alternative function or class name that the user may use in place of the deprecated object. The deprecation warning will tell the user about this alternative if provided. pending : bool, optional If True, uses a AstropyPendingDeprecationWarning instead of a ``warning_type``. obj_type : str, optional The type of this object, if the automatically determined one needs to be overridden. warning_type : Warning Warning to be issued. Default is `~astropy.utils.exceptions.AstropyDeprecationWarning`. """ method_types = (classmethod, staticmethod, types.MethodType) def deprecate_doc(old_doc, message): """ Returns a given docstring with a deprecation message prepended to it. """ if not old_doc: old_doc = '' old_doc = textwrap.dedent(old_doc).strip('\n') new_doc = (('\n.. deprecated:: {since}' '\n {message}\n\n'.format( **{'since': since, 'message': message.strip()})) + old_doc) if not old_doc: # This is to prevent a spurious 'unexpected unindent' warning from # docutils when the original docstring was blank. new_doc += r'\ ' return new_doc def get_function(func): """ Given a function or classmethod (or other function wrapper type), get the function object. """ if isinstance(func, method_types): func = func.__func__ return func def deprecate_function(func, message, warning_type=warning_type): """ Returns a wrapped function that displays ``warning_type`` when it is called. """ if isinstance(func, method_types): func_wrapper = type(func) else: func_wrapper = lambda f: f func = get_function(func) def deprecated_func(*args, **kwargs): if pending: category = AstropyPendingDeprecationWarning else: category = warning_type warnings.warn(message, category, stacklevel=2) return func(*args, **kwargs) # If this is an extension function, we can't call # functools.wraps on it, but we normally don't care. # This crazy way to get the type of a wrapper descriptor is # straight out of the Python 3.3 inspect module docs. if type(func) is not type(str.__dict__['__add__']): # nopep8 deprecated_func = functools.wraps(func)(deprecated_func) deprecated_func.__doc__ = deprecate_doc( deprecated_func.__doc__, message) return func_wrapper(deprecated_func) def deprecate_class(cls, message, warning_type=warning_type): """ Update the docstring and wrap the ``__init__`` in-place (or ``__new__`` if the class or any of the bases overrides ``__new__``) so it will give a deprecation warning when an instance is created. This won't work for extension classes because these can't be modified in-place and the alternatives don't work in the general case: - Using a new class that looks and behaves like the original doesn't work because the __new__ method of extension types usually makes sure that it's the same class or a subclass. - Subclassing the class and return the subclass can lead to problems with pickle and will look weird in the Sphinx docs. """ cls.__doc__ = deprecate_doc(cls.__doc__, message) if cls.__new__ is object.__new__: cls.__init__ = deprecate_function(get_function(cls.__init__), message, warning_type) else: cls.__new__ = deprecate_function(get_function(cls.__new__), message, warning_type) return cls def deprecate(obj, message=message, name=name, alternative=alternative, pending=pending, warning_type=warning_type): if obj_type is None: if isinstance(obj, type): obj_type_name = 'class' elif inspect.isfunction(obj): obj_type_name = 'function' elif inspect.ismethod(obj) or isinstance(obj, method_types): obj_type_name = 'method' else: obj_type_name = 'object' else: obj_type_name = obj_type if not name: name = get_function(obj).__name__ altmessage = '' if not message or type(message) is type(deprecate): if pending: message = ('The {func} {obj_type} will be deprecated in a ' 'future version.') else: message = ('The {func} {obj_type} is deprecated and may ' 'be removed in a future version.') if alternative: altmessage = f'\n Use {alternative} instead.' message = ((message.format(**{ 'func': name, 'name': name, 'alternative': alternative, 'obj_type': obj_type_name})) + altmessage) if isinstance(obj, type): return deprecate_class(obj, message, warning_type) else: return deprecate_function(obj, message, warning_type) if type(message) is type(deprecate): return deprecate(message) return deprecate def deprecated_attribute(name, since, message=None, alternative=None, pending=False, warning_type=AstropyDeprecationWarning): """ Used to mark a public attribute as deprecated. This creates a property that will warn when the given attribute name is accessed. To prevent the warning (i.e. for internal code), use the private name for the attribute by prepending an underscore (i.e. ``self._name``). Parameters ---------- name : str The name of the deprecated attribute. since : str The release at which this API became deprecated. This is required. message : str, optional Override the default deprecation message. The format specifier ``name`` may be used for the name of the attribute, and ``alternative`` may be used in the deprecation message to insert the name of an alternative to the deprecated function. alternative : str, optional An alternative attribute that the user may use in place of the deprecated attribute. The deprecation warning will tell the user about this alternative if provided. pending : bool, optional If True, uses a AstropyPendingDeprecationWarning instead of ``warning_type``. warning_type : Warning Warning to be issued. Default is `~astropy.utils.exceptions.AstropyDeprecationWarning`. Examples -------- :: class MyClass: # Mark the old_name as deprecated old_name = misc.deprecated_attribute('old_name', '0.1') def method(self): self._old_name = 42 """ private_name = '_' + name specific_deprecated = deprecated(since, name=name, obj_type='attribute', message=message, alternative=alternative, pending=pending, warning_type=warning_type) @specific_deprecated def get(self): return getattr(self, private_name) @specific_deprecated def set(self, val): setattr(self, private_name, val) @specific_deprecated def delete(self): delattr(self, private_name) return property(get, set, delete) def deprecated_renamed_argument(old_name, new_name, since, arg_in_kwargs=False, relax=False, pending=False, warning_type=AstropyDeprecationWarning, alternative='', message=''): """Deprecate a _renamed_ or _removed_ function argument. The decorator assumes that the argument with the ``old_name`` was removed from the function signature and the ``new_name`` replaced it at the **same position** in the signature. If the ``old_name`` argument is given when calling the decorated function the decorator will catch it and issue a deprecation warning and pass it on as ``new_name`` argument. Parameters ---------- old_name : str or sequence of str The old name of the argument. new_name : str or sequence of str or None The new name of the argument. Set this to `None` to remove the argument ``old_name`` instead of renaming it. since : str or number or sequence of str or number The release at which the old argument became deprecated. arg_in_kwargs : bool or sequence of bool, optional If the argument is not a named argument (for example it was meant to be consumed by ``**kwargs``) set this to ``True``. Otherwise the decorator will throw an Exception if the ``new_name`` cannot be found in the signature of the decorated function. Default is ``False``. relax : bool or sequence of bool, optional If ``False`` a ``TypeError`` is raised if both ``new_name`` and ``old_name`` are given. If ``True`` the value for ``new_name`` is used and a Warning is issued. Default is ``False``. pending : bool or sequence of bool, optional If ``True`` this will hide the deprecation warning and ignore the corresponding ``relax`` parameter value. Default is ``False``. warning_type : Warning Warning to be issued. Default is `~astropy.utils.exceptions.AstropyDeprecationWarning`. alternative : str, optional An alternative function or class name that the user may use in place of the deprecated object if ``new_name`` is None. The deprecation warning will tell the user about this alternative if provided. message : str, optional A custom warning message. If provided then ``since`` and ``alternative`` options will have no effect. Raises ------ TypeError If the new argument name cannot be found in the function signature and arg_in_kwargs was False or if it is used to deprecate the name of the ``*args``-, ``**kwargs``-like arguments. At runtime such an Error is raised if both the new_name and old_name were specified when calling the function and "relax=False". Notes ----- The decorator should be applied to a function where the **name** of an argument was changed but it applies the same logic. .. warning:: If ``old_name`` is a list or tuple the ``new_name`` and ``since`` must also be a list or tuple with the same number of entries. ``relax`` and ``arg_in_kwarg`` can be a single bool (applied to all) or also a list/tuple with the same number of entries like ``new_name``, etc. Examples -------- The deprecation warnings are not shown in the following examples. To deprecate a positional or keyword argument:: >>> from astropy.utils.decorators import deprecated_renamed_argument >>> @deprecated_renamed_argument('sig', 'sigma', '1.0') ... def test(sigma): ... return sigma >>> test(2) 2 >>> test(sigma=2) 2 >>> test(sig=2) # doctest: +SKIP 2 To deprecate an argument caught inside the ``**kwargs`` the ``arg_in_kwargs`` has to be set:: >>> @deprecated_renamed_argument('sig', 'sigma', '1.0', ... arg_in_kwargs=True) ... def test(**kwargs): ... return kwargs['sigma'] >>> test(sigma=2) 2 >>> test(sig=2) # doctest: +SKIP 2 By default providing the new and old keyword will lead to an Exception. If a Warning is desired set the ``relax`` argument:: >>> @deprecated_renamed_argument('sig', 'sigma', '1.0', relax=True) ... def test(sigma): ... return sigma >>> test(sig=2) # doctest: +SKIP 2 It is also possible to replace multiple arguments. The ``old_name``, ``new_name`` and ``since`` have to be `tuple` or `list` and contain the same number of entries:: >>> @deprecated_renamed_argument(['a', 'b'], ['alpha', 'beta'], ... ['1.0', 1.2]) ... def test(alpha, beta): ... return alpha, beta >>> test(a=2, b=3) # doctest: +SKIP (2, 3) In this case ``arg_in_kwargs`` and ``relax`` can be a single value (which is applied to all renamed arguments) or must also be a `tuple` or `list` with values for each of the arguments. """ cls_iter = (list, tuple) if isinstance(old_name, cls_iter): n = len(old_name) # Assume that new_name and since are correct (tuple/list with the # appropriate length) in the spirit of the "consenting adults". But the # optional parameters may not be set, so if these are not iterables # wrap them. if not isinstance(arg_in_kwargs, cls_iter): arg_in_kwargs = [arg_in_kwargs] * n if not isinstance(relax, cls_iter): relax = [relax] * n if not isinstance(pending, cls_iter): pending = [pending] * n if not isinstance(message, cls_iter): message = [message] * n else: # To allow a uniform approach later on, wrap all arguments in lists. n = 1 old_name = [old_name] new_name = [new_name] since = [since] arg_in_kwargs = [arg_in_kwargs] relax = [relax] pending = [pending] message = [message] def decorator(function): # The named arguments of the function. arguments = signature(function).parameters keys = list(arguments.keys()) position = [None] * n for i in range(n): # Determine the position of the argument. if arg_in_kwargs[i]: pass else: if new_name[i] is None: param = arguments[old_name[i]] elif new_name[i] in arguments: param = arguments[new_name[i]] # In case the argument is not found in the list of arguments # the only remaining possibility is that it should be caught # by some kind of **kwargs argument. # This case has to be explicitly specified, otherwise throw # an exception! else: raise TypeError( f'"{new_name[i]}" was not specified in the function ' 'signature. If it was meant to be part of ' '"**kwargs" then set "arg_in_kwargs" to "True"') # There are several possibilities now: # 1.) Positional or keyword argument: if param.kind == param.POSITIONAL_OR_KEYWORD: if new_name[i] is None: position[i] = keys.index(old_name[i]) else: position[i] = keys.index(new_name[i]) # 2.) Keyword only argument: elif param.kind == param.KEYWORD_ONLY: # These cannot be specified by position. position[i] = None # 3.) positional-only argument, varargs, varkwargs or some # unknown type: else: raise TypeError(f'cannot replace argument "{new_name[i]}" ' f'of kind {repr(param.kind)}.') @functools.wraps(function) def wrapper(*args, **kwargs): for i in range(n): msg = message[i] or (f'"{old_name[i]}" was deprecated in ' f'version {since[i]} and will be removed ' 'in a future version. ') # The only way to have oldkeyword inside the function is # that it is passed as kwarg because the oldkeyword # parameter was renamed to newkeyword. if old_name[i] in kwargs: value = kwargs.pop(old_name[i]) # Display the deprecation warning only when it's not # pending. if not pending[i]: if not message[i]: if new_name[i] is not None: msg += f'Use argument "{new_name[i]}" instead.' elif alternative: msg += f'\n Use {alternative} instead.' warnings.warn(msg, warning_type, stacklevel=2) # Check if the newkeyword was given as well. newarg_in_args = (position[i] is not None and len(args) > position[i]) newarg_in_kwargs = new_name[i] in kwargs if newarg_in_args or newarg_in_kwargs: if not pending[i]: # If both are given print a Warning if relax is # True or raise an Exception is relax is False. if relax[i]: warnings.warn( f'"{old_name[i]}" and "{new_name[i]}" ' 'keywords were set. ' f'Using the value of "{new_name[i]}".', AstropyUserWarning) else: raise TypeError( f'cannot specify both "{old_name[i]}" and ' f'"{new_name[i]}".') else: # Pass the value of the old argument with the # name of the new argument to the function if new_name[i] is not None: kwargs[new_name[i]] = value # If old argument has no replacement, cast it back. # https://github.com/astropy/astropy/issues/9914 else: kwargs[old_name[i]] = value # Deprecated keyword without replacement is given as # positional argument. elif (not pending[i] and not new_name[i] and position[i] and len(args) > position[i]): if alternative and not message[i]: msg += f'\n Use {alternative} instead.' warnings.warn(msg, warning_type, stacklevel=2) return function(*args, **kwargs) return wrapper return decorator # TODO: This can still be made to work for setters by implementing an # accompanying metaclass that supports it; we just don't need that right this # second class classproperty(property): """ Similar to `property`, but allows class-level properties. That is, a property whose getter is like a `classmethod`. The wrapped method may explicitly use the `classmethod` decorator (which must become before this decorator), or the `classmethod` may be omitted (it is implicit through use of this decorator). .. note:: classproperty only works for *read-only* properties. It does not currently allow writeable/deletable properties, due to subtleties of how Python descriptors work. In order to implement such properties on a class a metaclass for that class must be implemented. Parameters ---------- fget : callable The function that computes the value of this property (in particular, the function when this is used as a decorator) a la `property`. doc : str, optional The docstring for the property--by default inherited from the getter function. lazy : bool, optional If True, caches the value returned by the first call to the getter function, so that it is only called once (used for lazy evaluation of an attribute). This is analogous to `lazyproperty`. The ``lazy`` argument can also be used when `classproperty` is used as a decorator (see the third example below). When used in the decorator syntax this *must* be passed in as a keyword argument. Examples -------- :: >>> class Foo: ... _bar_internal = 1 ... @classproperty ... def bar(cls): ... return cls._bar_internal + 1 ... >>> Foo.bar 2 >>> foo_instance = Foo() >>> foo_instance.bar 2 >>> foo_instance._bar_internal = 2 >>> foo_instance.bar # Ignores instance attributes 2 As previously noted, a `classproperty` is limited to implementing read-only attributes:: >>> class Foo: ... _bar_internal = 1 ... @classproperty ... def bar(cls): ... return cls._bar_internal ... @bar.setter ... def bar(cls, value): ... cls._bar_internal = value ... Traceback (most recent call last): ... NotImplementedError: classproperty can only be read-only; use a metaclass to implement modifiable class-level properties When the ``lazy`` option is used, the getter is only called once:: >>> class Foo: ... @classproperty(lazy=True) ... def bar(cls): ... print("Performing complicated calculation") ... return 1 ... >>> Foo.bar Performing complicated calculation 1 >>> Foo.bar 1 If a subclass inherits a lazy `classproperty` the property is still re-evaluated for the subclass:: >>> class FooSub(Foo): ... pass ... >>> FooSub.bar Performing complicated calculation 1 >>> FooSub.bar 1 """ def __new__(cls, fget=None, doc=None, lazy=False): if fget is None: # Being used as a decorator--return a wrapper that implements # decorator syntax def wrapper(func): return cls(func, lazy=lazy) return wrapper return super().__new__(cls) def __init__(self, fget, doc=None, lazy=False): self._lazy = lazy if lazy: self._lock = threading.RLock() # Protects _cache self._cache = {} fget = self._wrap_fget(fget) super().__init__(fget=fget, doc=doc) # There is a buglet in Python where self.__doc__ doesn't # get set properly on instances of property subclasses if # the doc argument was used rather than taking the docstring # from fget # Related Python issue: https://bugs.python.org/issue24766 if doc is not None: self.__doc__ = doc def __get__(self, obj, objtype): if self._lazy: val = self._cache.get(objtype, _NotFound) if val is _NotFound: with self._lock: # Check if another thread initialised before we locked. val = self._cache.get(objtype, _NotFound) if val is _NotFound: val = self.fget.__wrapped__(objtype) self._cache[objtype] = val else: # The base property.__get__ will just return self here; # instead we pass objtype through to the original wrapped # function (which takes the class as its sole argument) val = self.fget.__wrapped__(objtype) return val def getter(self, fget): return super().getter(self._wrap_fget(fget)) def setter(self, fset): raise NotImplementedError( "classproperty can only be read-only; use a metaclass to " "implement modifiable class-level properties") def deleter(self, fdel): raise NotImplementedError( "classproperty can only be read-only; use a metaclass to " "implement modifiable class-level properties") @staticmethod def _wrap_fget(orig_fget): if isinstance(orig_fget, classmethod): orig_fget = orig_fget.__func__ # Using stock functools.wraps instead of the fancier version # found later in this module, which is overkill for this purpose @functools.wraps(orig_fget) def fget(obj): return orig_fget(obj.__class__) return fget # Adapted from the recipe at # http://code.activestate.com/recipes/363602-lazy-property-evaluation class lazyproperty(property): """ Works similarly to property(), but computes the value only once. This essentially memorizes the value of the property by storing the result of its computation in the ``__dict__`` of the object instance. This is useful for computing the value of some property that should otherwise be invariant. For example:: >>> class LazyTest: ... @lazyproperty ... def complicated_property(self): ... print('Computing the value for complicated_property...') ... return 42 ... >>> lt = LazyTest() >>> lt.complicated_property Computing the value for complicated_property... 42 >>> lt.complicated_property 42 As the example shows, the second time ``complicated_property`` is accessed, the ``print`` statement is not executed. Only the return value from the first access off ``complicated_property`` is returned. By default, a setter and deleter are used which simply overwrite and delete, respectively, the value stored in ``__dict__``. Any user-specified setter or deleter is executed before executing these default actions. The one exception is that the default setter is not run if the user setter already sets the new value in ``__dict__`` and returns that value and the returned value is not ``None``. """ def __init__(self, fget, fset=None, fdel=None, doc=None): super().__init__(fget, fset, fdel, doc) self._key = self.fget.__name__ self._lock = threading.RLock() def __get__(self, obj, owner=None): try: obj_dict = obj.__dict__ val = obj_dict.get(self._key, _NotFound) if val is _NotFound: with self._lock: # Check if another thread beat us to it. val = obj_dict.get(self._key, _NotFound) if val is _NotFound: val = self.fget(obj) obj_dict[self._key] = val return val except AttributeError: if obj is None: return self raise def __set__(self, obj, val): obj_dict = obj.__dict__ if self.fset: ret = self.fset(obj, val) if ret is not None and obj_dict.get(self._key) is ret: # By returning the value set the setter signals that it # took over setting the value in obj.__dict__; this # mechanism allows it to override the input value return obj_dict[self._key] = val def __delete__(self, obj): if self.fdel: self.fdel(obj) obj.__dict__.pop(self._key, None) # Delete if present class sharedmethod(classmethod): """ This is a method decorator that allows both an instancemethod and a `classmethod` to share the same name. When using `sharedmethod` on a method defined in a class's body, it may be called on an instance, or on a class. In the former case it behaves like a normal instance method (a reference to the instance is automatically passed as the first ``self`` argument of the method):: >>> class Example: ... @sharedmethod ... def identify(self, *args): ... print('self was', self) ... print('additional args were', args) ... >>> ex = Example() >>> ex.identify(1, 2) self was additional args were (1, 2) In the latter case, when the `sharedmethod` is called directly from a class, it behaves like a `classmethod`:: >>> Example.identify(3, 4) self was additional args were (3, 4) This also supports a more advanced usage, where the `classmethod` implementation can be written separately. If the class's *metaclass* has a method of the same name as the `sharedmethod`, the version on the metaclass is delegated to:: >>> class ExampleMeta(type): ... def identify(self): ... print('this implements the {0}.identify ' ... 'classmethod'.format(self.__name__)) ... >>> class Example(metaclass=ExampleMeta): ... @sharedmethod ... def identify(self): ... print('this implements the instancemethod') ... >>> Example().identify() this implements the instancemethod >>> Example.identify() this implements the Example.identify classmethod """ def __get__(self, obj, objtype=None): if obj is None: mcls = type(objtype) clsmeth = getattr(mcls, self.__func__.__name__, None) if callable(clsmeth): func = clsmeth else: func = self.__func__ return self._make_method(func, objtype) else: return self._make_method(self.__func__, obj) @staticmethod def _make_method(func, instance): return types.MethodType(func, instance) def format_doc(docstring, *args, **kwargs): """ Replaces the docstring of the decorated object and then formats it. The formatting works like :meth:`str.format` and if the decorated object already has a docstring this docstring can be included in the new documentation if you use the ``{__doc__}`` placeholder. Its primary use is for reusing a *long* docstring in multiple functions when it is the same or only slightly different between them. Parameters ---------- docstring : str or object or None The docstring that will replace the docstring of the decorated object. If it is an object like a function or class it will take the docstring of this object. If it is a string it will use the string itself. One special case is if the string is ``None`` then it will use the decorated functions docstring and formats it. args : passed to :meth:`str.format`. kwargs : passed to :meth:`str.format`. If the function has a (not empty) docstring the original docstring is added to the kwargs with the keyword ``'__doc__'``. Raises ------ ValueError If the ``docstring`` (or interpreted docstring if it was ``None`` or not a string) is empty. IndexError, KeyError If a placeholder in the (interpreted) ``docstring`` was not filled. see :meth:`str.format` for more information. Notes ----- Using this decorator allows, for example Sphinx, to parse the correct docstring. Examples -------- Replacing the current docstring is very easy:: >>> from astropy.utils.decorators import format_doc >>> @format_doc('''Perform num1 + num2''') ... def add(num1, num2): ... return num1+num2 ... >>> help(add) # doctest: +SKIP Help on function add in module __main__: add(num1, num2) Perform num1 + num2 sometimes instead of replacing you only want to add to it:: >>> doc = ''' ... {__doc__} ... Parameters ... ---------- ... num1, num2 : Numbers ... Returns ... ------- ... result: Number ... ''' >>> @format_doc(doc) ... def add(num1, num2): ... '''Perform addition.''' ... return num1+num2 ... >>> help(add) # doctest: +SKIP Help on function add in module __main__: add(num1, num2) Perform addition. Parameters ---------- num1, num2 : Numbers Returns ------- result : Number in case one might want to format it further:: >>> doc = ''' ... Perform {0}. ... Parameters ... ---------- ... num1, num2 : Numbers ... Returns ... ------- ... result: Number ... result of num1 {op} num2 ... {__doc__} ... ''' >>> @format_doc(doc, 'addition', op='+') ... def add(num1, num2): ... return num1+num2 ... >>> @format_doc(doc, 'subtraction', op='-') ... def subtract(num1, num2): ... '''Notes: This one has additional notes.''' ... return num1-num2 ... >>> help(add) # doctest: +SKIP Help on function add in module __main__: add(num1, num2) Perform addition. Parameters ---------- num1, num2 : Numbers Returns ------- result : Number result of num1 + num2 >>> help(subtract) # doctest: +SKIP Help on function subtract in module __main__: subtract(num1, num2) Perform subtraction. Parameters ---------- num1, num2 : Numbers Returns ------- result : Number result of num1 - num2 Notes : This one has additional notes. These methods can be combined an even taking the docstring from another object is possible as docstring attribute. You just have to specify the object:: >>> @format_doc(add) ... def another_add(num1, num2): ... return num1 + num2 ... >>> help(another_add) # doctest: +SKIP Help on function another_add in module __main__: another_add(num1, num2) Perform addition. Parameters ---------- num1, num2 : Numbers Returns ------- result : Number result of num1 + num2 But be aware that this decorator *only* formats the given docstring not the strings passed as ``args`` or ``kwargs`` (not even the original docstring):: >>> @format_doc(doc, 'addition', op='+') ... def yet_another_add(num1, num2): ... '''This one is good for {0}.''' ... return num1 + num2 ... >>> help(yet_another_add) # doctest: +SKIP Help on function yet_another_add in module __main__: yet_another_add(num1, num2) Perform addition. Parameters ---------- num1, num2 : Numbers Returns ------- result : Number result of num1 + num2 This one is good for {0}. To work around it you could specify the docstring to be ``None``:: >>> @format_doc(None, 'addition') ... def last_add_i_swear(num1, num2): ... '''This one is good for {0}.''' ... return num1 + num2 ... >>> help(last_add_i_swear) # doctest: +SKIP Help on function last_add_i_swear in module __main__: last_add_i_swear(num1, num2) This one is good for addition. Using it with ``None`` as docstring allows to use the decorator twice on an object to first parse the new docstring and then to parse the original docstring or the ``args`` and ``kwargs``. """ def set_docstring(obj): if docstring is None: # None means: use the objects __doc__ doc = obj.__doc__ # Delete documentation in this case so we don't end up with # awkwardly self-inserted docs. obj.__doc__ = None elif isinstance(docstring, str): # String: use the string that was given doc = docstring else: # Something else: Use the __doc__ of this doc = docstring.__doc__ if not doc: # In case the docstring is empty it's probably not what was wanted. raise ValueError('docstring must be a string or containing a ' 'docstring that is not empty.') # If the original has a not-empty docstring append it to the format # kwargs. kwargs['__doc__'] = obj.__doc__ or '' obj.__doc__ = doc.format(*args, **kwargs) return obj return set_docstring ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/diff.py0000644000175100001710000001155600000000000016400 0ustar00vstsdockerimport difflib import functools import sys import numbers import numpy as np from .misc import indent __all__ = ['fixed_width_indent', 'diff_values', 'report_diff_values', 'where_not_allclose'] # Smaller default shift-width for indent fixed_width_indent = functools.partial(indent, width=2) def diff_values(a, b, rtol=0.0, atol=0.0): """ Diff two scalar values. If both values are floats, they are compared to within the given absolute and relative tolerance. Parameters ---------- a, b : int, float, str Scalar values to compare. rtol, atol : float Relative and absolute tolerances as accepted by :func:`numpy.allclose`. Returns ------- is_different : bool `True` if they are different, else `False`. """ if isinstance(a, float) and isinstance(b, float): if np.isnan(a) and np.isnan(b): return False return not np.allclose(a, b, rtol=rtol, atol=atol) else: return a != b def report_diff_values(a, b, fileobj=sys.stdout, indent_width=0): """ Write a diff report between two values to the specified file-like object. Parameters ---------- a, b Values to compare. Anything that can be turned into strings and compared using :py:mod:`difflib` should work. fileobj : object File-like object to write to. The default is ``sys.stdout``, which writes to terminal. indent_width : int Character column(s) to indent. Returns ------- identical : bool `True` if no diff, else `False`. """ if isinstance(a, np.ndarray) and isinstance(b, np.ndarray): if a.shape != b.shape: fileobj.write( fixed_width_indent(' Different array shapes:\n', indent_width)) report_diff_values(str(a.shape), str(b.shape), fileobj=fileobj, indent_width=indent_width + 1) return False diff_indices = np.transpose(np.where(a != b)) num_diffs = diff_indices.shape[0] for idx in diff_indices[:3]: lidx = idx.tolist() fileobj.write( fixed_width_indent(f' at {lidx!r}:\n', indent_width)) report_diff_values(a[tuple(idx)], b[tuple(idx)], fileobj=fileobj, indent_width=indent_width + 1) if num_diffs > 3: fileobj.write(fixed_width_indent( f' ...and at {num_diffs - 3:d} more indices.\n', indent_width)) return False return num_diffs == 0 typea = type(a) typeb = type(b) if typea == typeb: lnpad = ' ' sign_a = 'a>' sign_b = 'b>' if isinstance(a, numbers.Number): a = repr(a) b = repr(b) else: a = str(a) b = str(b) else: padding = max(len(typea.__name__), len(typeb.__name__)) + 3 lnpad = (padding + 1) * ' ' sign_a = ('(' + typea.__name__ + ') ').rjust(padding) + 'a>' sign_b = ('(' + typeb.__name__ + ') ').rjust(padding) + 'b>' is_a_str = isinstance(a, str) is_b_str = isinstance(b, str) a = (repr(a) if ((is_a_str and not is_b_str) or (not is_a_str and isinstance(a, numbers.Number))) else str(a)) b = (repr(b) if ((is_b_str and not is_a_str) or (not is_b_str and isinstance(b, numbers.Number))) else str(b)) identical = True for line in difflib.ndiff(a.splitlines(), b.splitlines()): if line[0] == '-': identical = False line = sign_a + line[1:] elif line[0] == '+': identical = False line = sign_b + line[1:] else: line = lnpad + line fileobj.write(fixed_width_indent( ' {}\n'.format(line.rstrip('\n')), indent_width)) return identical def where_not_allclose(a, b, rtol=1e-5, atol=1e-8): """ A version of :func:`numpy.allclose` that returns the indices where the two arrays differ, instead of just a boolean value. Parameters ---------- a, b : array-like Input arrays to compare. rtol, atol : float Relative and absolute tolerances as accepted by :func:`numpy.allclose`. Returns ------- idx : tuple of array Indices where the two arrays differ. """ # Create fixed mask arrays to handle INF and NaN; currently INF and NaN # are handled as equivalent if not np.all(np.isfinite(a)): a = np.ma.fix_invalid(a).data if not np.all(np.isfinite(b)): b = np.ma.fix_invalid(b).data if atol == 0.0 and rtol == 0.0: # Use a faster comparison for the most simple (and common) case return np.where(a != b) return np.where(np.abs(a - b) > (atol + rtol * np.abs(b))) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/exceptions.py0000644000175100001710000000417600000000000017651 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This module contains errors/exceptions and warnings of general use for astropy. Exceptions that are specific to a given subpackage should *not* be here, but rather in the particular subpackage. """ # TODO: deprecate these. This cannot be trivially done with # astropy.utils.decorators.deprecate, since that module needs the exceptions # here, leading to circular import problems. from erfa import ErfaError, ErfaWarning # noqa __all__ = [ 'AstropyWarning', 'AstropyUserWarning', 'AstropyDeprecationWarning', 'AstropyPendingDeprecationWarning', 'AstropyBackwardsIncompatibleChangeWarning', 'DuplicateRepresentationWarning', 'NoValue'] class AstropyWarning(Warning): """ The base warning class from which all Astropy warnings should inherit. Any warning inheriting from this class is handled by the Astropy logger. """ class AstropyUserWarning(UserWarning, AstropyWarning): """ The primary warning class for Astropy. Use this if you do not need a specific sub-class. """ class AstropyDeprecationWarning(AstropyWarning): """ A warning class to indicate a deprecated feature. """ class AstropyPendingDeprecationWarning(PendingDeprecationWarning, AstropyWarning): """ A warning class to indicate a soon-to-be deprecated feature. """ class AstropyBackwardsIncompatibleChangeWarning(AstropyWarning): """ A warning class indicating a change in astropy that is incompatible with previous versions. The suggested procedure is to issue this warning for the version in which the change occurs, and remove it for all following versions. """ class DuplicateRepresentationWarning(AstropyWarning): """ A warning class indicating a representation name was already registered """ class _NoValue: """Special keyword value. This class may be used as the default value assigned to a deprecated keyword in order to check if it has been given a user defined value. """ def __repr__(self): return 'astropy.utils.exceptions.NoValue' NoValue = _NoValue() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1912537 astropy-5.0.2/astropy/utils/iers/0000755000175100001710000000000000000000000016050 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/iers/__init__.py0000644000175100001710000000002500000000000020156 0ustar00vstsdocker from .iers import * ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1952538 astropy-5.0.2/astropy/utils/iers/data/0000755000175100001710000000000000000000000016761 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/iers/data/Leap_Second.dat0000644000175100001710000000251700000000000021634 0ustar00vstsdocker# Value of TAI-UTC in second valid beetween the initial value until # the epoch given on the next line. The last line reads that NO # leap second was introduced since the corresponding date # Updated through IERS Bulletin 63 issued in January 2022 # # # File expires on 28 December 2022 # # # MJD Date TAI-UTC (s) # day month year # --- -------------- ------ # 41317.0 1 1 1972 10 41499.0 1 7 1972 11 41683.0 1 1 1973 12 42048.0 1 1 1974 13 42413.0 1 1 1975 14 42778.0 1 1 1976 15 43144.0 1 1 1977 16 43509.0 1 1 1978 17 43874.0 1 1 1979 18 44239.0 1 1 1980 19 44786.0 1 7 1981 20 45151.0 1 7 1982 21 45516.0 1 7 1983 22 46247.0 1 7 1985 23 47161.0 1 1 1988 24 47892.0 1 1 1990 25 48257.0 1 1 1991 26 48804.0 1 7 1992 27 49169.0 1 7 1993 28 49534.0 1 7 1994 29 50083.0 1 1 1996 30 50630.0 1 7 1997 31 51179.0 1 1 1999 32 53736.0 1 1 2006 33 54832.0 1 1 2009 34 56109.0 1 7 2012 35 57204.0 1 7 2015 36 57754.0 1 1 2017 37 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/iers/data/ReadMe.eopc04_IAU20000000644000175100001710000000417200000000000022136 0ustar00vstsdockerTable: eopc04_iau2000 ================================================================================ from http://hpiers.obspm.fr/iers/eop/eopc04/eopc04_IAU2000.62-now INTERNATIONAL EARTH ROTATION AND REFERENCE SYSTEMS SERVICE EARTH ORIENTATION PARAMETERS EOP (IERS) 08 C04 ================================================================================ File Summary: -------------------------------------------------------------------------------- FileName Lrecl Records Explanations -------------------------------------------------------------------------------- ReadMe 80 . This file, made using header eopc04_IAU2000.62-now 155 18279 all EOP values since 01 January 1962 -------------------------------------------------------------------------------- ================================================================================ Byte-by-byte Description of file: * -------------------------------------------------------------------------------- Bytes Format Units Label Explanations -------------------------------------------------------------------------------- 1- 4 I4 --- year Calendar year 5- 8 I4 --- month Month 9- 12 I4 --- day day of month (0 hr UTC) 13- 19 I7 d MJD Modified Julian Date (MJD, 0 hr UTC) 20- 30 F11.6 arcsec PM_x polar motion x 31- 41 F11.6 arcsec PM_y polar motion y 42- 53 F12.7 s UT1_UTC Difference UT1-UTC 54- 65 F12.7 s LOD length of day 66- 76 F11.6 arcsec dX_2000A dX wrt IAU2000A Nutation 77- 87 F11.6 arcsec dY_2000A dY wrt IAU2000A Nutation 88- 98 F11.6 arcsec e_PM_x error in PM_x 99-109 F11.6 arcsec e_PM_y error in PM_y 110-120 F11.7 s e_UT1_UTC error in UT1_UTC 121-131 F11.7 s e_LOD error in length of day 132-143 F12.6 arcsec e_dX_2000A error in dX_2000A 144-155 F12.6 arcsec e_dY_2000A error in dY_2000A -------------------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/iers/data/ReadMe.finals2000A0000644000175100001710000000654500000000000021731 0ustar00vstsdockerTable: finals2000A ================================================================================ from http://maia.usno.navy.mil/ finals2000A.all -- all EOP values since 02 January 1973 with dX & dY using IAU2000A Nutation/Precession Theory (with 1 year of predic tions) ================================================================================ File Summary: -------------------------------------------------------------------------------- FileName Lrecl Records Explanations -------------------------------------------------------------------------------- ReadMe 80 . This file, adapted from readme.finals2000A finals2000A.all 187 15182 all EOP values since 02 January 1973 -------------------------------------------------------------------------------- ================================================================================ Byte-by-byte Description of file: * -------------------------------------------------------------------------------- Bytes Format Units Label Explanations -------------------------------------------------------------------------------- 1- 2 I2 --- year To get true calendar year, add 1900 for MJD<=51543 or add 2000 for MJD>=51544) 3- 4 I2 --- month 5- 6 I2 --- day of month 8- 15 F8.2 d MJD fractional Modified Julian Date (MJD UTC) 17 A1 --- PolPMFlag_A IERS (I) or Prediction (P) flag for Bull. A polar motion values 19- 27 F9.6 arcsec PM_x_A Bull. A PM-x 28- 36 F9.6 arcsec e_PM_x_A error in PM-x (sec. of arc) 38- 46 F9.6 arcsec PM_y_A Bull. A PM-y (sec. of arc) 47- 55 F9.6 arcsec e_PM_y_A error in PM-y (sec. of arc) 58 A1 --- UT1Flag_A IERS (I) or Prediction (P) flag for Bull. A UT1-UTC values 59- 68 F10.7 s UT1_UTC_A Bull. A UT1-UTC (sec. of time) 69- 78 F10.7 s e_UT1_UTC_A error in UT1-UTC (sec. of time) 80- 86 F7.4 ms LOD_A Bull. A LOD (msec. of time) -- NOT ALWAYS FILLED 87- 93 F7.4 ms e_LOD_A error in LOD (msec. of time) -- NOT ALWAYS FILLED 96 A1 --- NutFlag_A IERS (I) or Prediction (P) flag for Bull. A nutation values 98- 106 F9.3 marcsec dX_2000A_A Bull. A dX wrt IAU2000A Nutation Free Core Nutation NOT Removed 107- 115 F9.3 marcsec e_dX_2000A_A error in dX (msec. of arc) 117- 125 F9.3 marcsec dY_2000A_A Bull. A dY wrt IAU2000A Nutation Free Core Nutation NOT Removed 126- 134 F9.3 marcsec e_dY_2000A_A error in dY (msec. of arc) 135- 144 F10.6 arcsec PM_X_B Bull. B PM-x (sec. of arc) 145- 154 F10.6 arcsec PM_Y_B Bull. B PM-y (sec. of arc) 155- 165 F11.7 s UT1_UTC_B Bull. B UT1-UTC (sec. of time) 166- 175 F10.3 marcsec dX_2000A_B Bull. B dX wrt IAU2000A Nutation 176- 185 F10.3 marcsec dY_2000A_B Bull. B dY wrt IAU2000A Nutation -------------------------------------------------------------------------------- Notes: The same format is used for finals2000A.data, finals2000A.daily, and finals2000A.all ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/iers/data/eopc04_IAU2000.62-now0000644000175100001710001504220400000000000022035 0ustar00vstsdocker EARTH ORIENTATION PARAMETER (EOP) PRODUCT CENTER CENTER (PARIS OBSERVATORY) INTERNATIONAL EARTH ROTATION AND REFERENCE SYSTEMS SERVICE EOP (IERS) 14 C04 TIME SERIES Description: https://hpiers.obspm.fr/eoppc/eop/eopc04/C04.guide.pdf contact: christian.bizouard@obspm.fr FORMAT(3(I4),I7,2(F11.6),2(F12.7),2(F11.6),2(F11.6),2(F11.7),2(F12.6)) ################################################################################## Date MJD x y UT1-UTC LOD dX dY x Err y Err UT1-UTC Err LOD Err dX Err dY Err " " s s " " " " s s " " (0h UTC) 1962 1 1 37665 -0.012700 0.213000 0.0326338 0.0017230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 2 37666 -0.015900 0.214100 0.0320547 0.0016690 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 3 37667 -0.019000 0.215200 0.0315526 0.0015820 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 4 37668 -0.021999 0.216301 0.0311435 0.0014960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 5 37669 -0.024799 0.217301 0.0308154 0.0014160 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 6 37670 -0.027599 0.218301 0.0305353 0.0013820 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 7 37671 -0.030199 0.219301 0.0302682 0.0014130 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 8 37672 -0.032798 0.220202 0.0299280 0.0015050 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 9 37673 -0.035198 0.221102 0.0294869 0.0016280 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 10 37674 -0.037498 0.222002 0.0289268 0.0017380 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 11 37675 -0.039697 0.222803 0.0282797 0.0017940 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 12 37676 -0.041797 0.223703 0.0276136 0.0017740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 13 37677 -0.043797 0.224503 0.0270075 0.0016670 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 14 37678 -0.045697 0.225203 0.0265403 0.0015100 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 15 37679 -0.047496 0.226004 0.0262572 0.0013120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 16 37680 -0.049196 0.226704 0.0261751 0.0011120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 17 37681 -0.050796 0.227404 0.0262740 0.0009360 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 18 37682 -0.052295 0.228005 0.0265299 0.0008110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 19 37683 -0.053595 0.228705 0.0268868 0.0007330 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 20 37684 -0.054895 0.229305 0.0273077 0.0006810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 21 37685 -0.055995 0.229905 0.0277506 0.0006780 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 22 37686 -0.057094 0.230506 0.0281834 0.0007210 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 23 37687 -0.057994 0.231006 0.0285533 0.0007900 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 24 37688 -0.058794 0.231606 0.0288522 0.0008620 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 25 37689 -0.059594 0.232106 0.0290721 0.0009440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 26 37690 -0.060193 0.232607 0.0292210 0.0010040 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 27 37691 -0.060693 0.233207 0.0293239 0.0010370 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 28 37692 -0.061093 0.233707 0.0294068 0.0010520 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 29 37693 -0.061392 0.234208 0.0294776 0.0010520 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 30 37694 -0.061692 0.234708 0.0295585 0.0010440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 1 31 37695 -0.061792 0.235208 0.0296424 0.0010370 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 1 37696 -0.061792 0.235708 0.0297323 0.0010170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 2 37697 -0.061691 0.236209 0.0298362 0.0010410 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 3 37698 -0.061491 0.236709 0.0298791 0.0011250 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 4 37699 -0.061191 0.237309 0.0298030 0.0012890 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 5 37700 -0.060791 0.237809 0.0295339 0.0015060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 6 37701 -0.060390 0.238410 0.0290467 0.0017140 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 7 37702 -0.059790 0.239010 0.0283596 0.0018790 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 8 37703 -0.059190 0.239610 0.0275575 0.0019590 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 9 37704 -0.058389 0.240211 0.0267354 0.0019300 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 10 37705 -0.057589 0.240811 0.0259753 0.0018180 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 11 37706 -0.056689 0.241511 0.0253542 0.0016500 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 12 37707 -0.055689 0.242211 0.0249181 0.0014740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 13 37708 -0.054588 0.242912 0.0246570 0.0013030 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 14 37709 -0.053488 0.243612 0.0245359 0.0011660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 15 37710 -0.052288 0.244312 0.0245467 0.0010810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 16 37711 -0.050988 0.245112 0.0246076 0.0010560 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 17 37712 -0.049587 0.245813 0.0246695 0.0010640 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 18 37713 -0.048187 0.246613 0.0247074 0.0011130 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 19 37714 -0.046687 0.247413 0.0246873 0.0011600 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 20 37715 -0.045186 0.248214 0.0246352 0.0012130 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 21 37716 -0.043486 0.249014 0.0245041 0.0012870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 22 37717 -0.041786 0.249814 0.0243170 0.0013330 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 23 37718 -0.040086 0.250614 0.0240879 0.0013590 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 24 37719 -0.038285 0.251415 0.0238487 0.0013740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 25 37720 -0.036385 0.252115 0.0236096 0.0013510 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 26 37721 -0.034485 0.252915 0.0234035 0.0013080 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 27 37722 -0.032585 0.253715 0.0232364 0.0012560 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 2 28 37723 -0.030584 0.254416 0.0231283 0.0012210 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 1 37724 -0.028484 0.255116 0.0230452 0.0012020 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 2 37725 -0.026384 0.255816 0.0229381 0.0012430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 3 37726 -0.024283 0.256517 0.0227770 0.0013520 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 4 37727 -0.022083 0.257117 0.0224709 0.0015200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 5 37728 -0.019983 0.257717 0.0219628 0.0017300 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 6 37729 -0.017683 0.258317 0.0212546 0.0019290 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 7 37730 -0.015482 0.258818 0.0203775 0.0020600 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 8 37731 -0.013282 0.259218 0.0194214 0.0020840 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 9 37732 -0.010982 0.259618 0.0184953 0.0019990 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 10 37733 -0.008682 0.260018 0.0176992 0.0018350 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 11 37734 -0.006381 0.260319 0.0170871 0.0016380 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 12 37735 -0.004081 0.260519 0.0166690 0.0014540 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 13 37736 -0.001781 0.260719 0.0164149 0.0013130 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 14 37737 0.000420 0.260820 0.0162728 0.0012200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 15 37738 0.002720 0.260920 0.0161857 0.0011940 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 16 37739 0.005020 0.260920 0.0161086 0.0012170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 17 37740 0.007320 0.260820 0.0159894 0.0012770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 18 37741 0.009621 0.260621 0.0157963 0.0013510 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 19 37742 0.011921 0.260421 0.0155242 0.0014440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 20 37743 0.014121 0.260121 0.0151601 0.0015220 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 21 37744 0.016421 0.259721 0.0147350 0.0015840 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 22 37745 0.018622 0.259322 0.0142509 0.0016100 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 23 37746 0.020822 0.258822 0.0137668 0.0016110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 24 37747 0.023122 0.258222 0.0132897 0.0015690 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 25 37748 0.025323 0.257623 0.0128686 0.0015090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 26 37749 0.027423 0.256923 0.0125245 0.0014170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 27 37750 0.029623 0.256123 0.0122734 0.0013380 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 28 37751 0.031823 0.255323 0.0120923 0.0012910 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 29 37752 0.033924 0.254424 0.0119371 0.0012770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 30 37753 0.036024 0.253524 0.0117570 0.0013340 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 3 31 37754 0.038124 0.252524 0.0114859 0.0014700 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 1 37755 0.040224 0.251524 0.0110478 0.0016640 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 2 37756 0.042225 0.250525 0.0103997 0.0018730 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 3 37757 0.044225 0.249425 0.0095526 0.0020600 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 4 37758 0.046225 0.248325 0.0085585 0.0021620 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 5 37759 0.048226 0.247126 0.0075064 0.0021510 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 6 37760 0.050126 0.246026 0.0065313 0.0020430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 7 37761 0.052026 0.244826 0.0057022 0.0018580 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 8 37762 0.053926 0.243626 0.0050701 0.0016570 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 9 37763 0.055727 0.242427 0.0046280 0.0014860 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 10 37764 0.057627 0.241227 0.0043199 0.0013800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 11 37765 0.059327 0.240027 0.0040768 0.0013360 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 12 37766 0.061128 0.238828 0.0038687 0.0013390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 13 37767 0.062828 0.237628 0.0036235 0.0013860 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 14 37768 0.064428 0.236428 0.0033174 0.0014620 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 15 37769 0.066028 0.235228 0.0029343 0.0015530 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 16 37770 0.067629 0.234029 0.0024602 0.0016440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 17 37771 0.069129 0.232929 0.0019101 0.0017130 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 18 37772 0.070629 0.231729 0.0012930 0.0017470 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 19 37773 0.072129 0.230629 0.0006559 0.0017600 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 20 37774 0.073530 0.229530 0.0000338 0.0017280 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 21 37775 0.074830 0.228430 -0.0005283 0.0016520 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 22 37776 0.076230 0.227330 -0.0010234 0.0015640 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 23 37777 0.077431 0.226231 -0.0014155 0.0014820 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 24 37778 0.078631 0.225231 -0.0017436 0.0014070 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 25 37779 0.079831 0.224131 -0.0020127 0.0013810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 26 37780 0.080931 0.223131 -0.0022728 0.0014090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 27 37781 0.082032 0.222132 -0.0026029 0.0015010 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 28 37782 0.083132 0.221132 -0.0030440 0.0016510 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 29 37783 0.084032 0.220132 -0.0036681 0.0018400 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 4 30 37784 0.085032 0.219132 -0.0044842 0.0020370 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 1 37785 0.085933 0.218133 -0.0054853 0.0021840 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 2 37786 0.086733 0.217133 -0.0065815 0.0022400 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 3 37787 0.087533 0.216033 -0.0076706 0.0021800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 4 37788 0.088334 0.215034 -0.0086607 0.0020190 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 5 37789 0.089034 0.214034 -0.0094528 0.0018120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 6 37790 0.089734 0.212934 -0.0100369 0.0016090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 7 37791 0.090334 0.211834 -0.0104360 0.0014490 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 8 37792 0.090935 0.210735 -0.0107141 0.0013580 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 9 37793 0.091535 0.209635 -0.0109342 0.0013290 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 10 37794 0.092035 0.208435 -0.0111503 0.0013500 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 11 37795 0.092535 0.207235 -0.0114064 0.0014070 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 12 37796 0.092936 0.205936 -0.0117305 0.0014940 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 13 37797 0.093336 0.204636 -0.0121366 0.0015760 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 14 37798 0.093736 0.203336 -0.0126307 0.0016490 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 15 37799 0.094137 0.201937 -0.0131878 0.0017110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 16 37800 0.094437 0.200437 -0.0138029 0.0017440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 17 37801 0.094737 0.198937 -0.0144260 0.0017350 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 18 37802 0.095037 0.197437 -0.0150221 0.0016930 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 19 37803 0.095338 0.195738 -0.0155522 0.0016120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 20 37804 0.095538 0.194138 -0.0159923 0.0015270 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 21 37805 0.095738 0.192338 -0.0163584 0.0014400 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 22 37806 0.095938 0.190638 -0.0166415 0.0013740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 23 37807 0.096139 0.188739 -0.0168846 0.0013520 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 24 37808 0.096339 0.186839 -0.0171257 0.0013910 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 25 37809 0.096439 0.184939 -0.0174358 0.0014660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 26 37810 0.096640 0.182940 -0.0178309 0.0015780 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 27 37811 0.096740 0.180940 -0.0183450 0.0016970 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 28 37812 0.096840 0.178840 -0.0189741 0.0017850 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 29 37813 0.096940 0.176740 -0.0196522 0.0017960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 30 37814 0.097041 0.174641 -0.0202983 0.0017100 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 5 31 37815 0.097241 0.172441 -0.0207934 0.0015370 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 1 37816 0.097341 0.170241 -0.0210925 0.0013130 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 2 37817 0.097441 0.168041 -0.0211636 0.0010800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 3 37818 0.097542 0.165842 -0.0210097 0.0008690 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 4 37819 0.097642 0.163642 -0.0206698 0.0007010 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 5 37820 0.097742 0.161442 -0.0201919 0.0006030 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 6 37821 0.097843 0.159243 -0.0196530 0.0005790 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 7 37822 0.097943 0.157043 -0.0191031 0.0005950 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 8 37823 0.098043 0.154843 -0.0185932 0.0006380 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 9 37824 0.098143 0.152643 -0.0181413 0.0007090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 10 37825 0.098244 0.150544 -0.0177694 0.0007860 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 11 37826 0.098244 0.148444 -0.0174565 0.0008240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 12 37827 0.098344 0.146344 -0.0171687 0.0008450 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 13 37828 0.098444 0.144344 -0.0168878 0.0008260 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 14 37829 0.098545 0.142345 -0.0165709 0.0007870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 15 37830 0.098645 0.140345 -0.0162110 0.0007200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 16 37831 0.098645 0.138445 -0.0157641 0.0006340 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 17 37832 0.098746 0.136546 -0.0152182 0.0005350 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 18 37833 0.098746 0.134746 -0.0145923 0.0004580 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 19 37834 0.098846 0.132946 -0.0139104 0.0004270 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 20 37835 0.098846 0.131246 -0.0132284 0.0004600 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 21 37836 0.098947 0.129547 -0.0126115 0.0005550 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 22 37837 0.098947 0.127947 -0.0121126 0.0007010 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 23 37838 0.098947 0.126347 -0.0117647 0.0008510 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 24 37839 0.098947 0.124847 -0.0115558 0.0009710 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 25 37840 0.098948 0.123348 -0.0114269 0.0010290 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 26 37841 0.098948 0.121948 -0.0113290 0.0010110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 27 37842 0.098848 0.120548 -0.0111831 0.0009250 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 28 37843 0.098849 0.119249 -0.0109102 0.0007720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 29 37844 0.098749 0.117949 -0.0104783 0.0006120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 6 30 37845 0.098649 0.116749 -0.0098784 0.0004530 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 1 37846 0.098549 0.115549 -0.0091475 0.0003450 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 2 37847 0.098450 0.114450 -0.0083366 0.0002820 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 3 37848 0.098350 0.113350 -0.0074917 0.0002860 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 4 37849 0.098150 0.112350 -0.0066738 0.0003340 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 5 37850 0.097951 0.111351 -0.0059299 0.0004210 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 6 37851 0.097651 0.110351 -0.0052700 0.0005110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 7 37852 0.097351 0.109351 -0.0046921 0.0006000 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 8 37853 0.097051 0.108451 -0.0042052 0.0006730 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 9 37854 0.096752 0.107552 -0.0037803 0.0007220 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 10 37855 0.096352 0.106652 -0.0033884 0.0007390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 11 37856 0.095952 0.105852 -0.0029995 0.0007280 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 12 37857 0.095552 0.104952 -0.0025956 0.0006910 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 13 37858 0.095053 0.104153 -0.0021357 0.0006370 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 14 37859 0.094553 0.103253 -0.0016268 0.0005850 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 15 37860 0.094053 0.102353 -0.0010599 0.0005340 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 16 37861 0.093454 0.101554 -0.0004580 0.0005200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 17 37862 0.092854 0.100654 0.0001199 0.0005750 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 18 37863 0.092254 0.099754 0.0006178 0.0006900 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 19 37864 0.091654 0.098854 0.0009717 0.0008700 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 20 37865 0.090955 0.097855 0.0011216 0.0010680 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 21 37866 0.090255 0.096855 0.0010945 0.0012270 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 22 37867 0.089455 0.095855 0.0009414 0.0013160 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 23 37868 0.088755 0.094855 0.0007423 0.0013170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 24 37869 0.087956 0.093756 0.0005942 0.0012260 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 25 37870 0.087156 0.092656 0.0005491 0.0010870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 26 37871 0.086356 0.091556 0.0006690 0.0009120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 27 37872 0.085457 0.090357 0.0009619 0.0007560 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 28 37873 0.084657 0.089157 0.0013938 0.0006280 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 29 37874 0.083757 0.087957 0.0019367 0.0005540 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 30 37875 0.082857 0.086657 0.0025156 0.0005370 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 7 31 37876 0.081858 0.085358 0.0030976 0.0005670 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 1 37877 0.080958 0.084058 0.0036315 0.0006200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 2 37878 0.079958 0.082658 0.0040924 0.0006880 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 3 37879 0.079058 0.081358 0.0044943 0.0007580 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 4 37880 0.078059 0.079959 0.0048302 0.0008160 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 5 37881 0.076959 0.078559 0.0051201 0.0008500 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 6 37882 0.075959 0.077159 0.0053910 0.0008440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 7 37883 0.074860 0.075760 0.0056829 0.0008160 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 8 37884 0.073860 0.074360 0.0060068 0.0007530 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 9 37885 0.072660 0.072960 0.0064237 0.0006720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 10 37886 0.071560 0.071460 0.0069146 0.0005950 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 11 37887 0.070361 0.070061 0.0074805 0.0005250 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 12 37888 0.069261 0.068661 0.0081054 0.0004810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 13 37889 0.067961 0.067261 0.0087413 0.0004970 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 14 37890 0.066761 0.065861 0.0093282 0.0005820 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 15 37891 0.065462 0.064462 0.0098031 0.0007370 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 16 37892 0.064162 0.063162 0.0100980 0.0009260 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 17 37893 0.062762 0.061762 0.0101939 0.0011160 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 18 37894 0.061463 0.060463 0.0101269 0.0012330 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 19 37895 0.060063 0.059163 0.0099918 0.0012600 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 20 37896 0.058563 0.057863 0.0098937 0.0011800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 21 37897 0.057063 0.056663 0.0099086 0.0010290 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 22 37898 0.055564 0.055464 0.0100875 0.0008410 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 23 37899 0.054064 0.054264 0.0104634 0.0006700 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 24 37900 0.052464 0.053164 0.0109733 0.0005490 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 25 37901 0.050864 0.052164 0.0115962 0.0004750 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 26 37902 0.049265 0.051065 0.0122621 0.0004630 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 27 37903 0.047565 0.050165 0.0128930 0.0005130 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 28 37904 0.045965 0.049265 0.0134739 0.0006000 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 29 37905 0.044166 0.048366 0.0139448 0.0007080 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 30 37906 0.042466 0.047566 0.0143057 0.0008200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 8 31 37907 0.040666 0.046866 0.0145486 0.0009310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 1 37908 0.038866 0.046166 0.0147006 0.0010110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 2 37909 0.037067 0.045567 0.0147765 0.0010810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 3 37910 0.035267 0.044967 0.0147984 0.0011180 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 4 37911 0.033467 0.044467 0.0148003 0.0011150 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 5 37912 0.031567 0.044067 0.0148262 0.0010910 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 6 37913 0.029668 0.043668 0.0148711 0.0010590 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 7 37914 0.027768 0.043368 0.0149550 0.0010340 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 8 37915 0.025868 0.043168 0.0150359 0.0010310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 9 37916 0.023869 0.042969 0.0151198 0.0010580 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 10 37917 0.021969 0.042869 0.0151477 0.0011370 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 11 37918 0.019969 0.042769 0.0150616 0.0012880 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 12 37919 0.017969 0.042769 0.0147995 0.0014940 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 13 37920 0.015970 0.042770 0.0143155 0.0017150 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 14 37921 0.013970 0.042870 0.0136304 0.0019040 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 15 37922 0.011970 0.043070 0.0127863 0.0020030 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 16 37923 0.009870 0.043170 0.0119142 0.0019710 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 17 37924 0.007871 0.043471 0.0111231 0.0018150 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 18 37925 0.005771 0.043671 0.0105470 0.0015880 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 19 37926 0.003671 0.043971 0.0101909 0.0013560 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 20 37927 0.001572 0.044272 0.0100638 0.0011570 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 21 37928 -0.000628 0.044672 0.0101057 0.0010200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 22 37929 -0.002728 0.045072 0.0102506 0.0009410 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 23 37930 -0.004928 0.045472 0.0104526 0.0009240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 24 37931 -0.007127 0.045873 0.0106375 0.0009620 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 25 37932 -0.009427 0.046373 0.0107694 0.0010260 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 26 37933 -0.011627 0.046873 0.0108313 0.0010990 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 27 37934 -0.013926 0.047374 0.0108222 0.0011660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 28 37935 -0.016226 0.047974 0.0107561 0.0012220 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 29 37936 -0.018526 0.048474 0.0106380 0.0012500 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 9 30 37937 -0.020926 0.049074 0.0105179 0.0012440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 1 37938 -0.023225 0.049675 0.0104208 0.0012050 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 2 37939 -0.025625 0.050375 0.0103578 0.0011480 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 3 37940 -0.028025 0.050975 0.0103797 0.0010770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 4 37941 -0.030425 0.051675 0.0104526 0.0010080 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 5 37942 -0.032824 0.052376 0.0105955 0.0009700 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 6 37943 -0.035224 0.053176 0.0107504 0.0009690 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 7 37944 -0.037724 0.053976 0.0108803 0.0010300 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 8 37945 -0.040123 0.054777 0.0109162 0.0011590 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 9 37946 -0.042523 0.055577 0.0107901 0.0013550 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 10 37947 -0.044923 0.056477 0.0104390 0.0016020 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 11 37948 -0.047323 0.057377 0.0098240 0.0018640 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 12 37949 -0.049722 0.058278 0.0089789 0.0020720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 13 37950 -0.052122 0.059278 0.0079758 0.0021750 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 14 37951 -0.054422 0.060278 0.0069227 0.0021500 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 15 37952 -0.056822 0.061378 0.0059606 0.0020100 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 16 37953 -0.059121 0.062479 0.0051615 0.0018250 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 17 37954 -0.061321 0.063579 0.0045484 0.0016460 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 18 37955 -0.063521 0.064779 0.0040923 0.0015290 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 19 37956 -0.065720 0.066080 0.0037263 0.0014640 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 20 37957 -0.067920 0.067280 0.0033892 0.0014710 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 21 37958 -0.070020 0.068680 0.0030171 0.0015220 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 22 37959 -0.072020 0.069980 0.0025740 0.0016180 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 23 37960 -0.074019 0.071381 0.0020369 0.0017190 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 24 37961 -0.076019 0.072881 0.0013878 0.0018080 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 25 37962 -0.077919 0.074381 0.0006657 0.0018810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 26 37963 -0.079819 0.075881 -0.0001163 0.0019180 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 27 37964 -0.081618 0.077482 -0.0009184 0.0019110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 28 37965 -0.083318 0.079082 -0.0016875 0.0018710 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 29 37966 -0.085018 0.080682 -0.0024096 0.0017990 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 30 37967 -0.086717 0.082383 -0.0030377 0.0017050 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 10 31 37968 -0.088317 0.084083 -0.0035678 0.0015950 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 1 37969 -0.089817 0.085783 -0.0039819 0.0014790 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 2 37970 -0.091317 0.087583 -0.0042959 0.0014060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 3 37971 -0.092816 0.089284 -0.0045610 0.0013930 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 4 37972 -0.094216 0.091084 -0.0048531 0.0014410 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 5 37973 -0.095616 0.092884 -0.0052152 0.0015520 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 6 37974 -0.096916 0.094684 -0.0057163 0.0017170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 7 37975 -0.098215 0.096585 -0.0064094 0.0019090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 8 37976 -0.099515 0.098385 -0.0072885 0.0020920 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 9 37977 -0.100715 0.100285 -0.0083195 0.0022050 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 10 37978 -0.101914 0.102186 -0.0094216 0.0022200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 11 37979 -0.103114 0.104086 -0.0104707 0.0021200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 12 37980 -0.104314 0.105986 -0.0113928 0.0019440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 13 37981 -0.105514 0.107886 -0.0120979 0.0017270 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 14 37982 -0.106813 0.109787 -0.0126060 0.0015360 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 15 37983 -0.108013 0.111787 -0.0129420 0.0014090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 16 37984 -0.109213 0.113687 -0.0131991 0.0013560 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 17 37985 -0.110413 0.115687 -0.0134262 0.0013570 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 18 37986 -0.111712 0.117688 -0.0136873 0.0014110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 19 37987 -0.113012 0.119788 -0.0140154 0.0014870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 20 37988 -0.114312 0.121788 -0.0144125 0.0015660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 21 37989 -0.115711 0.123889 -0.0148935 0.0016230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 22 37990 -0.117111 0.125889 -0.0154206 0.0016670 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 23 37991 -0.118511 0.127989 -0.0159767 0.0016800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 24 37992 -0.120011 0.130089 -0.0165288 0.0016690 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 25 37993 -0.121510 0.132290 -0.0170549 0.0016270 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 26 37994 -0.123110 0.134390 -0.0175250 0.0015700 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 27 37995 -0.124710 0.136590 -0.0179400 0.0015000 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 28 37996 -0.126410 0.138690 -0.0182851 0.0014230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 29 37997 -0.128209 0.140891 -0.0185552 0.0013830 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 11 30 37998 -0.130009 0.143091 -0.0188063 0.0013780 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 1 37999 -0.131809 0.145391 -0.0190924 0.0014330 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 2 38000 -0.133708 0.147592 -0.0194534 0.0015600 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 3 38001 -0.135608 0.149892 -0.0199685 0.0017270 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 4 38002 -0.137608 0.152092 -0.0206666 0.0019210 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 5 38003 -0.139608 0.154392 -0.0215587 0.0021090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 6 38004 -0.141707 0.156693 -0.0226198 0.0022530 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 7 38005 -0.143807 0.158993 -0.0237879 0.0023170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 8 38006 -0.146007 0.161293 -0.0249709 0.0022720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 9 38007 -0.148107 0.163693 -0.0260530 0.0021390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 10 38008 -0.150306 0.165994 -0.0269811 0.0019430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 11 38009 -0.152506 0.168394 -0.0277082 0.0017550 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 12 38010 -0.154806 0.170694 -0.0282553 0.0016010 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 13 38011 -0.157005 0.173095 -0.0286823 0.0015150 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 14 38012 -0.159305 0.175495 -0.0290594 0.0014880 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 15 38013 -0.161505 0.177895 -0.0294355 0.0015110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 16 38014 -0.163805 0.180295 -0.0298416 0.0015430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 17 38015 -0.166004 0.182696 -0.0302847 0.0015930 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 18 38016 -0.168204 0.185096 -0.0307747 0.0016340 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 19 38017 -0.170404 0.187496 -0.0312948 0.0016530 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 20 38018 -0.172603 0.189897 -0.0318209 0.0016430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 21 38019 -0.174803 0.192297 -0.0323200 0.0016000 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 22 38020 -0.176903 0.194697 -0.0327601 0.0015160 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 23 38021 -0.179003 0.196997 -0.0331041 0.0014170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 24 38022 -0.181102 0.199398 -0.0333402 0.0013040 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 25 38023 -0.183102 0.201798 -0.0334703 0.0011880 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 26 38024 -0.185002 0.204198 -0.0334714 0.0010790 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 27 38025 -0.186902 0.206598 -0.0334015 0.0010190 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 28 38026 -0.188801 0.208999 -0.0332875 0.0010160 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 29 38027 -0.190501 0.211299 -0.0332046 0.0010780 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 30 38028 -0.192201 0.213699 -0.0332137 0.0011960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1962 12 31 38029 -0.193800 0.216000 -0.0333558 0.0013410 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 1 38030 -0.195400 0.218400 -0.0336428 0.0014780 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 2 38031 -0.196800 0.220700 -0.0340579 0.0015820 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 3 38032 -0.198100 0.223100 -0.0345420 0.0016140 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 4 38033 -0.199399 0.225401 -0.0350281 0.0015720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 5 38034 -0.200499 0.227701 -0.0354112 0.0014530 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 6 38035 -0.201599 0.230001 -0.0356652 0.0012800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 7 38036 -0.202499 0.232401 -0.0357273 0.0010940 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 8 38037 -0.203298 0.234702 -0.0356134 0.0009360 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 9 38038 -0.203998 0.236902 -0.0353695 0.0008370 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 10 38039 -0.204498 0.239202 -0.0350606 0.0008050 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 11 38040 -0.204997 0.241503 -0.0347596 0.0008410 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 12 38041 -0.205297 0.243803 -0.0345147 0.0009020 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 13 38042 -0.205497 0.246003 -0.0343188 0.0009660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 14 38043 -0.205597 0.248303 -0.0342049 0.0010340 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 15 38044 -0.205496 0.250504 -0.0341289 0.0010710 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 16 38045 -0.205396 0.252704 -0.0340870 0.0010780 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 17 38046 -0.205096 0.254904 -0.0340241 0.0010520 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 18 38047 -0.204796 0.257104 -0.0339292 0.0009920 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 19 38048 -0.204295 0.259305 -0.0337602 0.0009070 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 20 38049 -0.203695 0.261405 -0.0334983 0.0008070 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 21 38050 -0.202995 0.263505 -0.0331344 0.0007050 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 22 38051 -0.202194 0.265606 -0.0326715 0.0006230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 23 38052 -0.201294 0.267606 -0.0321315 0.0005720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 24 38053 -0.200394 0.269606 -0.0315836 0.0005730 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 25 38054 -0.199294 0.271606 -0.0310607 0.0006520 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 26 38055 -0.198093 0.273607 -0.0306498 0.0007960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 27 38056 -0.196893 0.275507 -0.0304168 0.0009830 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 28 38057 -0.195593 0.277307 -0.0303759 0.0011800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 29 38058 -0.194193 0.279207 -0.0305120 0.0013300 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 30 38059 -0.192792 0.281008 -0.0307591 0.0014090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 1 31 38060 -0.191292 0.282808 -0.0310581 0.0014030 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 1 38061 -0.189692 0.284508 -0.0312982 0.0013060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 2 38062 -0.187991 0.286209 -0.0314123 0.0011660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 3 38063 -0.186391 0.287909 -0.0313674 0.0010040 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 4 38064 -0.184591 0.289609 -0.0311884 0.0008860 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 5 38065 -0.182891 0.291209 -0.0309185 0.0008230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 6 38066 -0.180990 0.292810 -0.0305966 0.0008060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 7 38067 -0.179190 0.294410 -0.0303107 0.0008610 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 8 38068 -0.177290 0.296010 -0.0300937 0.0009500 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 9 38069 -0.175390 0.297610 -0.0299778 0.0010690 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 10 38070 -0.173489 0.299111 -0.0299719 0.0011760 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 11 38071 -0.171489 0.300611 -0.0300740 0.0012640 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 12 38072 -0.169589 0.302111 -0.0302400 0.0013130 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 13 38073 -0.167588 0.303612 -0.0304481 0.0013260 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 14 38074 -0.165588 0.305112 -0.0306402 0.0013030 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 15 38075 -0.163588 0.306612 -0.0307833 0.0012390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 16 38076 -0.161588 0.308012 -0.0308623 0.0011670 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 17 38077 -0.159487 0.309513 -0.0308654 0.0010810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 18 38078 -0.157487 0.311013 -0.0307865 0.0010040 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 19 38079 -0.155387 0.312413 -0.0306435 0.0009540 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 20 38080 -0.153387 0.313913 -0.0304596 0.0009370 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 21 38081 -0.151286 0.315314 -0.0302987 0.0010030 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 22 38082 -0.149186 0.316714 -0.0302308 0.0011430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 23 38083 -0.147086 0.318214 -0.0303458 0.0013460 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 24 38084 -0.144985 0.319615 -0.0306809 0.0015840 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 25 38085 -0.142885 0.321015 -0.0312550 0.0017940 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 26 38086 -0.140685 0.322415 -0.0319921 0.0019120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 27 38087 -0.138485 0.323715 -0.0328001 0.0019360 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 2 28 38088 -0.136284 0.325116 -0.0335682 0.0018430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 1 38089 -0.134084 0.326516 -0.0342123 0.0016870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 2 38090 -0.131784 0.327816 -0.0346843 0.0014970 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 3 38091 -0.129484 0.329116 -0.0349754 0.0013410 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 4 38092 -0.127183 0.330417 -0.0351255 0.0012310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 5 38093 -0.124783 0.331817 -0.0352105 0.0011910 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 6 38094 -0.122383 0.333017 -0.0352806 0.0012080 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 7 38095 -0.119982 0.334318 -0.0354047 0.0012870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 8 38096 -0.117482 0.335618 -0.0356148 0.0013850 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 9 38097 -0.114982 0.336818 -0.0359358 0.0014980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 10 38098 -0.112482 0.338118 -0.0363549 0.0015870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 11 38099 -0.109881 0.339319 -0.0368600 0.0016480 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 12 38100 -0.107281 0.340519 -0.0373990 0.0016730 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 13 38101 -0.104581 0.341719 -0.0379541 0.0016600 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 14 38102 -0.101880 0.342820 -0.0384682 0.0016120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 15 38103 -0.099180 0.344020 -0.0389203 0.0015380 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 16 38104 -0.096480 0.345120 -0.0392923 0.0014450 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 17 38105 -0.093680 0.346220 -0.0395624 0.0013580 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 18 38106 -0.090779 0.347321 -0.0397755 0.0013040 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 19 38107 -0.087979 0.348321 -0.0399425 0.0012880 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 20 38108 -0.085079 0.349321 -0.0401306 0.0013280 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 21 38109 -0.082079 0.350221 -0.0403817 0.0014370 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 22 38110 -0.079078 0.351222 -0.0407887 0.0016290 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 23 38111 -0.076078 0.352022 -0.0414078 0.0018650 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 24 38112 -0.073078 0.352922 -0.0422809 0.0021190 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 25 38113 -0.069977 0.353723 -0.0433859 0.0023170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 26 38114 -0.066877 0.354423 -0.0446290 0.0024170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 27 38115 -0.063777 0.355123 -0.0459171 0.0023770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 28 38116 -0.060577 0.355723 -0.0471071 0.0022280 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 29 38117 -0.057476 0.356324 -0.0481232 0.0020210 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 30 38118 -0.054176 0.356924 -0.0489213 0.0018190 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 3 31 38119 -0.050976 0.357324 -0.0495393 0.0016790 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 1 38120 -0.047676 0.357724 -0.0500454 0.0016060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 2 38121 -0.044375 0.358125 -0.0505165 0.0015980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 3 38122 -0.041075 0.358325 -0.0510216 0.0016500 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 4 38123 -0.037675 0.358625 -0.0515886 0.0017380 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 5 38124 -0.034274 0.358726 -0.0522417 0.0018290 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 6 38125 -0.030874 0.358826 -0.0529938 0.0019130 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 7 38126 -0.027474 0.358826 -0.0538098 0.0019630 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 8 38127 -0.023974 0.358726 -0.0546689 0.0019900 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 9 38128 -0.020573 0.358627 -0.0555260 0.0019680 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 10 38129 -0.016973 0.358427 -0.0563430 0.0018890 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 11 38130 -0.013473 0.358127 -0.0570551 0.0017900 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 12 38131 -0.009873 0.357827 -0.0576562 0.0016720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 13 38132 -0.006372 0.357428 -0.0581482 0.0015640 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 14 38133 -0.002772 0.356928 -0.0585503 0.0014740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 15 38134 0.000928 0.356428 -0.0588693 0.0014200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 16 38135 0.004529 0.355829 -0.0591674 0.0014250 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 17 38136 0.008229 0.355229 -0.0594895 0.0014810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 18 38137 0.011929 0.354429 -0.0599115 0.0016160 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 19 38138 0.015629 0.353729 -0.0605026 0.0018150 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 20 38139 0.019330 0.352930 -0.0613057 0.0020620 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 21 38140 0.023030 0.352030 -0.0623617 0.0022840 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 22 38141 0.026730 0.351130 -0.0636078 0.0024310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 23 38142 0.030530 0.350130 -0.0649439 0.0024680 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 24 38143 0.034231 0.349131 -0.0662489 0.0023630 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 25 38144 0.038031 0.348131 -0.0673870 0.0021610 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 26 38145 0.041831 0.347031 -0.0683111 0.0019260 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 27 38146 0.045532 0.345932 -0.0690091 0.0017310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 28 38147 0.049332 0.344832 -0.0695462 0.0015980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 29 38148 0.053132 0.343632 -0.0699933 0.0015590 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 4 30 38149 0.056832 0.342432 -0.0704373 0.0015900 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 1 38150 0.060633 0.341233 -0.0709484 0.0016770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 2 38151 0.064333 0.339933 -0.0715484 0.0017630 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 3 38152 0.068033 0.338733 -0.0722345 0.0018470 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 4 38153 0.071733 0.337433 -0.0729956 0.0019110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 5 38154 0.075434 0.336134 -0.0738056 0.0019440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 6 38155 0.079134 0.334834 -0.0746317 0.0019420 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 7 38156 0.082734 0.333434 -0.0754268 0.0018920 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 8 38157 0.086335 0.332135 -0.0761538 0.0018090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 9 38158 0.089835 0.330735 -0.0767869 0.0016930 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 10 38159 0.093435 0.329335 -0.0772980 0.0015700 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 11 38160 0.096935 0.327935 -0.0776900 0.0014580 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 12 38161 0.100336 0.326536 -0.0779841 0.0013760 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 13 38162 0.103736 0.325136 -0.0782181 0.0013410 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 14 38163 0.107136 0.323736 -0.0784452 0.0013620 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 15 38164 0.110436 0.322236 -0.0787043 0.0014260 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 16 38165 0.113737 0.320737 -0.0790763 0.0015590 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 17 38166 0.116937 0.319337 -0.0795964 0.0017450 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 18 38167 0.120137 0.317837 -0.0803114 0.0019340 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 19 38168 0.123238 0.316338 -0.0812005 0.0020850 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 20 38169 0.126338 0.314738 -0.0822016 0.0021380 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 21 38170 0.129438 0.313238 -0.0831966 0.0020820 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 22 38171 0.132438 0.311738 -0.0840877 0.0019220 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 23 38172 0.135339 0.310139 -0.0847678 0.0016920 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 24 38173 0.138239 0.308539 -0.0852088 0.0014550 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 25 38174 0.141139 0.306939 -0.0854459 0.0012710 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 26 38175 0.143939 0.305339 -0.0855379 0.0011790 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 27 38176 0.146740 0.303640 -0.0855910 0.0011780 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 28 38177 0.149440 0.301940 -0.0856641 0.0012250 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 29 38178 0.152140 0.300240 -0.0858111 0.0013100 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 30 38179 0.154841 0.298541 -0.0860342 0.0014050 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 5 31 38180 0.157441 0.296841 -0.0863542 0.0014720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 1 38181 0.160041 0.295041 -0.0867393 0.0015210 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 2 38182 0.162541 0.293241 -0.0871344 0.0015240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 3 38183 0.165042 0.291442 -0.0875334 0.0015000 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 4 38184 0.167542 0.289642 -0.0878825 0.0014430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 5 38185 0.169942 0.287742 -0.0881715 0.0013720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 6 38186 0.172343 0.285943 -0.0883626 0.0012690 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 7 38187 0.174743 0.284043 -0.0884607 0.0011700 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 8 38188 0.177043 0.282043 -0.0884607 0.0010860 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 9 38189 0.179343 0.280143 -0.0884068 0.0010440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 10 38190 0.181644 0.278144 -0.0883278 0.0010570 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 11 38191 0.183844 0.276144 -0.0882929 0.0011320 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 12 38192 0.186044 0.274044 -0.0883609 0.0012530 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 13 38193 0.188244 0.272044 -0.0885710 0.0014230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 14 38194 0.190345 0.269945 -0.0889511 0.0015960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 15 38195 0.192345 0.267845 -0.0895061 0.0017490 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 16 38196 0.194445 0.265745 -0.0901782 0.0018410 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 17 38197 0.196446 0.263546 -0.0909072 0.0018310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 18 38198 0.198346 0.261346 -0.0915643 0.0017170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 19 38199 0.200246 0.259146 -0.0920744 0.0015220 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 20 38200 0.202046 0.256946 -0.0923464 0.0012810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 21 38201 0.203847 0.254647 -0.0923955 0.0010750 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 22 38202 0.205647 0.252347 -0.0922795 0.0009470 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 23 38203 0.207247 0.250047 -0.0920676 0.0008930 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 24 38204 0.208947 0.247747 -0.0918386 0.0009190 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 25 38205 0.210448 0.245348 -0.0916687 0.0009840 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 26 38206 0.211948 0.242948 -0.0915697 0.0010570 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 27 38207 0.213348 0.240548 -0.0915368 0.0011240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 28 38208 0.214749 0.238149 -0.0915469 0.0011500 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 29 38209 0.215949 0.235649 -0.0915749 0.0011600 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 6 30 38210 0.217149 0.233249 -0.0916040 0.0011210 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 1 38211 0.218349 0.230749 -0.0915660 0.0010490 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 2 38212 0.219350 0.228250 -0.0914421 0.0009400 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 3 38213 0.220350 0.225750 -0.0912021 0.0008290 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 4 38214 0.221250 0.223250 -0.0908502 0.0007090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 5 38215 0.222050 0.220750 -0.0903763 0.0006070 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 6 38216 0.222751 0.218251 -0.0898163 0.0005310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 7 38217 0.223451 0.215751 -0.0892174 0.0005190 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 8 38218 0.224051 0.213251 -0.0886354 0.0005590 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 9 38219 0.224552 0.210752 -0.0881165 0.0006610 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 10 38220 0.224952 0.208152 -0.0877115 0.0007950 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 11 38221 0.225252 0.205652 -0.0874696 0.0009600 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 12 38222 0.225452 0.203152 -0.0873836 0.0011020 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 13 38223 0.225653 0.200653 -0.0874147 0.0011970 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 14 38224 0.225753 0.198053 -0.0875007 0.0012110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 15 38225 0.225753 0.195553 -0.0875668 0.0011480 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 16 38226 0.225653 0.193053 -0.0875209 0.0009990 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 17 38227 0.225454 0.190454 -0.0873119 0.0008200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 18 38228 0.225254 0.187954 -0.0869320 0.0006560 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 19 38229 0.224954 0.185354 -0.0863910 0.0005440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 20 38230 0.224455 0.182755 -0.0857951 0.0005080 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 21 38231 0.223955 0.180155 -0.0851931 0.0005490 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 22 38232 0.223355 0.177555 -0.0846712 0.0006430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 23 38233 0.222755 0.174955 -0.0842552 0.0007660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 24 38234 0.221956 0.172356 -0.0839493 0.0008670 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 25 38235 0.221156 0.169656 -0.0837293 0.0009380 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 26 38236 0.220156 0.167056 -0.0835714 0.0009790 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 27 38237 0.219156 0.164356 -0.0834244 0.0009690 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 28 38238 0.218057 0.161657 -0.0832575 0.0009310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 29 38239 0.216857 0.158857 -0.0830275 0.0008550 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 30 38240 0.215657 0.156157 -0.0827216 0.0007730 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 7 31 38241 0.214258 0.153358 -0.0823326 0.0006900 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 1 38242 0.212858 0.150658 -0.0818677 0.0006340 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 2 38243 0.211258 0.147858 -0.0813597 0.0005980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 3 38244 0.209658 0.145058 -0.0808388 0.0006300 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 4 38245 0.207959 0.142259 -0.0803899 0.0007230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 5 38246 0.206259 0.139359 -0.0800579 0.0008740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 6 38247 0.204359 0.136559 -0.0799060 0.0010700 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 7 38248 0.202459 0.133759 -0.0799650 0.0012990 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 8 38249 0.200460 0.130860 -0.0802481 0.0015090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 9 38250 0.198360 0.128060 -0.0807121 0.0016460 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 10 38251 0.196260 0.125160 -0.0812692 0.0016920 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 11 38252 0.194061 0.122261 -0.0818152 0.0016350 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 12 38253 0.191761 0.119461 -0.0822733 0.0015020 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 13 38254 0.189361 0.116561 -0.0825653 0.0013200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 14 38255 0.186961 0.113661 -0.0826734 0.0011410 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 15 38256 0.184562 0.110862 -0.0826124 0.0010070 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 16 38257 0.182062 0.107962 -0.0824515 0.0009430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 17 38258 0.179462 0.105062 -0.0822755 0.0009570 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 18 38259 0.176862 0.102162 -0.0821456 0.0010320 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 19 38260 0.174263 0.099363 -0.0821096 0.0011390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 20 38261 0.171563 0.096463 -0.0821727 0.0012450 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 21 38262 0.168763 0.093563 -0.0823407 0.0013250 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 22 38263 0.166064 0.090764 -0.0825678 0.0013630 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 23 38264 0.163264 0.087864 -0.0828018 0.0013470 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 24 38265 0.160464 0.084964 -0.0829969 0.0012880 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 25 38266 0.157664 0.082164 -0.0831259 0.0012040 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 26 38267 0.154765 0.079265 -0.0831589 0.0011100 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 27 38268 0.151965 0.076465 -0.0830940 0.0010120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 28 38269 0.149065 0.073665 -0.0829470 0.0009270 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 29 38270 0.146166 0.070766 -0.0827281 0.0008820 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 30 38271 0.143266 0.067966 -0.0824741 0.0008790 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 8 31 38272 0.140366 0.065266 -0.0822542 0.0009320 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 1 38273 0.137466 0.062466 -0.0821102 0.0010520 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 2 38274 0.134567 0.059667 -0.0821313 0.0012390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 3 38275 0.131667 0.056967 -0.0823643 0.0014810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 4 38276 0.128767 0.054267 -0.0828454 0.0017260 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 5 38277 0.125867 0.051567 -0.0835494 0.0019200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 6 38278 0.122968 0.048868 -0.0844025 0.0020160 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 7 38279 0.120068 0.046268 -0.0852925 0.0020060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 8 38280 0.117168 0.043668 -0.0861316 0.0018980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 9 38281 0.114269 0.041069 -0.0868106 0.0017150 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 10 38282 0.111369 0.038469 -0.0873207 0.0015400 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 11 38283 0.108469 0.035969 -0.0876547 0.0013990 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 12 38284 0.105569 0.033469 -0.0878928 0.0013210 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 13 38285 0.102670 0.031070 -0.0880828 0.0013230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 14 38286 0.099770 0.028570 -0.0883208 0.0014020 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 15 38287 0.096870 0.026270 -0.0886519 0.0015140 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 16 38288 0.093970 0.023870 -0.0891029 0.0016370 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 17 38289 0.091071 0.021571 -0.0896800 0.0017420 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 18 38290 0.088071 0.019271 -0.0903240 0.0017990 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 19 38291 0.085171 0.017071 -0.0910221 0.0018200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 20 38292 0.082172 0.014872 -0.0917191 0.0017950 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 21 38293 0.079172 0.012772 -0.0923592 0.0017300 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 22 38294 0.076172 0.010672 -0.0929292 0.0016460 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 23 38295 0.073172 0.008572 -0.0933983 0.0015420 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 24 38296 0.070073 0.006573 -0.0937753 0.0014450 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 25 38297 0.066973 0.004673 -0.0940573 0.0013750 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 26 38298 0.063873 0.002773 -0.0942894 0.0013360 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 27 38299 0.060673 0.000973 -0.0945064 0.0013480 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 28 38300 0.057474 -0.000826 -0.0947555 0.0014120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 29 38301 0.054174 -0.002526 -0.0951135 0.0015640 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 9 30 38302 0.050874 -0.004226 -0.0956536 0.0017660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 1 38303 0.047575 -0.005825 -0.0964166 0.0020100 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 2 38304 0.044175 -0.007425 -0.0974286 0.0022360 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 3 38305 0.040775 -0.008825 -0.0986217 0.0023930 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 4 38306 0.037275 -0.010225 -0.0999137 0.0024180 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 5 38307 0.033776 -0.011624 -0.1011758 0.0023270 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 6 38308 0.030176 -0.012924 -0.1022868 0.0021430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 7 38309 0.026576 -0.014124 -0.1032029 0.0019290 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 8 38310 0.022876 -0.015224 -0.1039259 0.0017570 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 9 38311 0.019177 -0.016223 -0.1045029 0.0016500 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 10 38312 0.015377 -0.017223 -0.1050160 0.0016410 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 11 38313 0.011577 -0.018123 -0.1055510 0.0017000 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 12 38314 0.007678 -0.019022 -0.1061821 0.0017990 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 13 38315 0.003778 -0.019722 -0.1069151 0.0019270 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 14 38316 -0.000122 -0.020422 -0.1077842 0.0020470 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 15 38317 -0.004122 -0.021022 -0.1087692 0.0021470 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 16 38318 -0.008121 -0.021521 -0.1098242 0.0022040 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 17 38319 -0.012121 -0.022021 -0.1109023 0.0022150 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 18 38320 -0.016221 -0.022321 -0.1119783 0.0021820 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 19 38321 -0.020221 -0.022621 -0.1130034 0.0021150 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 20 38322 -0.024320 -0.022820 -0.1139514 0.0020290 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 21 38323 -0.028420 -0.022920 -0.1148114 0.0019420 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 22 38324 -0.032620 -0.022920 -0.1156025 0.0018860 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 23 38325 -0.036719 -0.022919 -0.1163555 0.0018660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 24 38326 -0.040819 -0.022719 -0.1171026 0.0018870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 25 38327 -0.044919 -0.022519 -0.1178976 0.0019640 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 26 38328 -0.049019 -0.022219 -0.1188016 0.0020950 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 27 38329 -0.053118 -0.021818 -0.1198677 0.0022970 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 28 38330 -0.057118 -0.021318 -0.1211727 0.0025470 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 29 38331 -0.061218 -0.020718 -0.1227178 0.0027920 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 30 38332 -0.065118 -0.020118 -0.1244928 0.0029960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 10 31 38333 -0.069117 -0.019317 -0.1264278 0.0030950 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 1 38334 -0.073017 -0.018517 -0.0283989 0.0030640 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 2 38335 -0.076817 -0.017717 -0.0302639 0.0029000 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 3 38336 -0.080616 -0.016816 -0.0319240 0.0026520 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 4 38337 -0.084316 -0.015816 -0.0333380 0.0024010 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 5 38338 -0.088016 -0.014716 -0.0345060 0.0022000 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 6 38339 -0.091616 -0.013616 -0.0355291 0.0020810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 7 38340 -0.095115 -0.012515 -0.0364491 0.0020420 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 8 38341 -0.098515 -0.011315 -0.0373852 0.0020760 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 9 38342 -0.101915 -0.010015 -0.0383712 0.0021380 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 10 38343 -0.105115 -0.008715 -0.0394102 0.0021960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 11 38344 -0.108414 -0.007414 -0.0405053 0.0022190 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 12 38345 -0.111514 -0.006014 -0.0415853 0.0022040 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 13 38346 -0.114514 -0.004614 -0.0426483 0.0021540 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 14 38347 -0.117513 -0.003213 -0.0436504 0.0020820 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 15 38348 -0.120413 -0.001813 -0.0445514 0.0019650 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 16 38349 -0.123213 -0.000313 -0.0453315 0.0018430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 17 38350 -0.125913 0.001187 -0.0459845 0.0017130 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 18 38351 -0.128612 0.002688 -0.0465225 0.0015950 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 19 38352 -0.131212 0.004188 -0.0469556 0.0015180 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 20 38353 -0.133712 0.005688 -0.0473236 0.0014770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 21 38354 -0.136112 0.007288 -0.0476876 0.0015110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 22 38355 -0.138511 0.008789 -0.0481257 0.0016050 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 23 38356 -0.140811 0.010389 -0.0486767 0.0017460 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 24 38357 -0.143111 0.011889 -0.0493837 0.0019340 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 25 38358 -0.145310 0.013490 -0.0503038 0.0021490 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 26 38359 -0.147410 0.015090 -0.0514288 0.0023550 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 27 38360 -0.149510 0.016590 -0.0527349 0.0024930 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 28 38361 -0.151510 0.018190 -0.0541399 0.0025390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 29 38362 -0.153509 0.019691 -0.0555209 0.0024530 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 11 30 38363 -0.155409 0.021291 -0.0567710 0.0022650 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 1 38364 -0.157309 0.022891 -0.0577960 0.0020430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 2 38365 -0.159208 0.024492 -0.0586060 0.0018370 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 3 38366 -0.161008 0.025992 -0.0592481 0.0017110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 4 38367 -0.162908 0.027592 -0.0598211 0.0016810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 5 38368 -0.164708 0.029192 -0.0603961 0.0017400 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 6 38369 -0.166507 0.030793 -0.0610552 0.0018200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 7 38370 -0.168307 0.032393 -0.0618072 0.0019120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 8 38371 -0.170207 0.033993 -0.0626312 0.0019890 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 9 38372 -0.172007 0.035693 -0.0635223 0.0020170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 10 38373 -0.173806 0.037294 -0.0644093 0.0020110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 11 38374 -0.175706 0.038994 -0.0652793 0.0019630 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 12 38375 -0.177606 0.040694 -0.0660734 0.0018800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 13 38376 -0.179505 0.042395 -0.0667804 0.0017720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 14 38377 -0.181505 0.044095 -0.0673634 0.0016530 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 15 38378 -0.183505 0.045895 -0.0678385 0.0015400 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 16 38379 -0.185505 0.047695 -0.0682105 0.0014510 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 17 38380 -0.187604 0.049496 -0.0685125 0.0014130 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 18 38381 -0.189804 0.051396 -0.0688036 0.0014190 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 19 38382 -0.192004 0.053296 -0.0691306 0.0014940 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 20 38383 -0.194204 0.055196 -0.0695606 0.0016250 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 21 38384 -0.196503 0.057097 -0.0701457 0.0018000 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 22 38385 -0.198903 0.059097 -0.0709187 0.0019980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 23 38386 -0.201303 0.061197 -0.0718907 0.0021940 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 24 38387 -0.203802 0.063198 -0.0730338 0.0023430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 25 38388 -0.206302 0.065398 -0.0743018 0.0024280 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 26 38389 -0.208902 0.067598 -0.0756078 0.0024060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 27 38390 -0.211602 0.069798 -0.0768409 0.0022860 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 28 38391 -0.214301 0.072099 -0.0779169 0.0021100 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 29 38392 -0.217001 0.074399 -0.0788089 0.0019280 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 30 38393 -0.219801 0.076799 -0.0795510 0.0018090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1963 12 31 38394 -0.222601 0.079299 -0.0802090 0.0017810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 1 38395 -0.225500 0.081800 -0.0808950 0.0018440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 2 38396 -0.228400 0.084400 -0.0814970 0.0019660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 3 38397 -0.231300 0.087000 -0.0822311 0.0021030 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 4 38398 -0.234299 0.089701 -0.0831141 0.0022270 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 5 38399 -0.237299 0.092501 -0.0840911 0.0023170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 6 38400 -0.240199 0.095401 -0.0851432 0.0023580 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 7 38401 -0.243199 0.098301 -0.0862012 0.0023420 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 8 38402 -0.246198 0.101302 -0.0872232 0.0022880 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 9 38403 -0.249198 0.104302 -0.0881673 0.0021970 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 10 38404 -0.252198 0.107502 -0.0890143 0.0020950 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 11 38405 -0.255198 0.110702 -0.0897703 0.0019980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 12 38406 -0.258097 0.113903 -0.0904373 0.0019210 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 13 38407 -0.260997 0.117203 -0.0910244 0.0018610 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 14 38408 -0.263897 0.120603 -0.0915864 0.0018620 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 15 38409 -0.266696 0.124004 -0.0921794 0.0019030 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 16 38410 -0.269496 0.127504 -0.0928335 0.0020140 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 17 38411 -0.272196 0.131004 -0.0936235 0.0021630 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 18 38412 -0.274896 0.134604 -0.0945765 0.0023350 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 19 38413 -0.277495 0.138205 -0.0956915 0.0024910 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 20 38414 -0.279995 0.141805 -0.0969546 0.0025980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 21 38415 -0.282395 0.145505 -0.0982746 0.0026380 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 22 38416 -0.284795 0.149305 -0.0996026 0.0026040 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 23 38417 -0.286994 0.153006 -0.1008537 0.0024960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 24 38418 -0.289094 0.156806 -0.1019747 0.0023270 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 25 38419 -0.291194 0.160606 -0.1029107 0.0021470 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 26 38420 -0.293093 0.164507 -0.1036897 0.0020000 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 27 38421 -0.294893 0.168407 -0.1043468 0.0019190 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 28 38422 -0.296593 0.172307 -0.1049688 0.0019400 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 29 38423 -0.298193 0.176207 -0.1056518 0.0020270 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 30 38424 -0.299592 0.180108 -0.1064438 0.0021390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 1 31 38425 -0.300892 0.184108 -0.1073469 0.0022510 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 1 38426 -0.301992 0.188008 -0.1083319 0.0023210 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 2 38427 -0.303092 0.191908 -0.1093689 0.0023330 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 3 38428 -0.303891 0.195909 -0.1103889 0.0022780 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 4 38429 -0.304691 0.199809 -0.1113300 0.0021870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 5 38430 -0.305291 0.203809 -0.1121430 0.0020540 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 6 38431 -0.305690 0.207710 -0.1128330 0.0019140 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 7 38432 -0.305990 0.211610 -0.1133821 0.0017770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 8 38433 -0.306190 0.215510 -0.1138031 0.0016590 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 9 38434 -0.306190 0.219410 -0.1141221 0.0015870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 10 38435 -0.306089 0.223311 -0.1144031 0.0015630 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 11 38436 -0.305789 0.227111 -0.1146882 0.0015980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 12 38437 -0.305389 0.230911 -0.1150302 0.0016970 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 13 38438 -0.304889 0.234711 -0.1155012 0.0018430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 14 38439 -0.304188 0.238412 -0.1161382 0.0020360 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 15 38440 -0.303388 0.242112 -0.1169723 0.0022190 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 16 38441 -0.302488 0.245812 -0.1179833 0.0023720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 17 38442 -0.301387 0.249513 -0.1191013 0.0024490 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 18 38443 -0.300187 0.253113 -0.1202503 0.0024230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 19 38444 -0.298887 0.256713 -0.1213283 0.0023100 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 20 38445 -0.297487 0.260213 -0.1222494 0.0021350 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 21 38446 -0.295986 0.263714 -0.1229914 0.0019500 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 22 38447 -0.294286 0.267214 -0.1235574 0.0017900 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 23 38448 -0.292586 0.270614 -0.1240044 0.0016970 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 24 38449 -0.290785 0.274015 -0.1244015 0.0017020 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 25 38450 -0.288785 0.277315 -0.1248365 0.0017800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 26 38451 -0.286785 0.280615 -0.1253895 0.0019320 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 27 38452 -0.284685 0.283915 -0.1261035 0.0020940 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 28 38453 -0.282484 0.287216 -0.1269686 0.0022270 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 2 29 38454 -0.280284 0.290416 -0.1279386 0.0023130 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 1 38455 -0.277984 0.293616 -0.1289826 0.0023350 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 2 38456 -0.275584 0.296716 -0.1300096 0.0023000 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 3 38457 -0.273083 0.299817 -0.1309776 0.0022220 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 4 38458 -0.270583 0.302917 -0.1318447 0.0021080 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 5 38459 -0.268083 0.306017 -0.1326027 0.0020000 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 6 38460 -0.265382 0.309118 -0.1332687 0.0019070 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 7 38461 -0.262782 0.312118 -0.1338477 0.0018470 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 8 38462 -0.260082 0.315118 -0.1343797 0.0018250 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 9 38463 -0.257282 0.318118 -0.1349278 0.0018600 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 10 38464 -0.254481 0.321119 -0.1355318 0.0019590 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 11 38465 -0.251581 0.324119 -0.1362758 0.0021210 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 12 38466 -0.248681 0.327119 -0.1372108 0.0023350 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 13 38467 -0.245781 0.330019 -0.1383539 0.0025620 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 14 38468 -0.242780 0.333020 -0.1397269 0.0027570 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 15 38469 -0.239780 0.335920 -0.1412529 0.0028790 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 16 38470 -0.236680 0.338820 -0.1428499 0.0028850 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 17 38471 -0.233579 0.341721 -0.1444069 0.0027910 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 18 38472 -0.230379 0.344621 -0.1458150 0.0026050 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 19 38473 -0.227279 0.347521 -0.1470260 0.0023960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 20 38474 -0.223979 0.350421 -0.1480150 0.0021890 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 21 38475 -0.220678 0.353222 -0.1488250 0.0020460 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 22 38476 -0.217378 0.356122 -0.1495470 0.0020010 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 23 38477 -0.214078 0.358922 -0.1502670 0.0020430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 24 38478 -0.210678 0.361722 -0.1510631 0.0021470 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 25 38479 -0.207177 0.364523 -0.1519811 0.0022890 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 26 38480 -0.203777 0.367223 -0.1530271 0.0024080 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 27 38481 -0.200277 0.370023 -0.1541911 0.0024920 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 28 38482 -0.196676 0.372724 -0.1553901 0.0025050 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 29 38483 -0.193176 0.375424 -0.1565912 0.0024660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 30 38484 -0.189576 0.378024 -0.1577242 0.0023840 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 3 31 38485 -0.185876 0.380724 -0.1587572 0.0022660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 1 38486 -0.182275 0.383325 -0.0596522 0.0021140 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 2 38487 -0.178575 0.385925 -0.0603972 0.0019680 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 3 38488 -0.174875 0.388425 -0.0610082 0.0018500 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 4 38489 -0.171175 0.390925 -0.0615333 0.0017770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 5 38490 -0.167474 0.393426 -0.0620013 0.0017590 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 6 38491 -0.163774 0.395926 -0.0624723 0.0017920 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 7 38492 -0.160074 0.398326 -0.0630073 0.0018780 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 8 38493 -0.156273 0.400727 -0.0636583 0.0020340 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 9 38494 -0.152573 0.403027 -0.0644883 0.0022110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 10 38495 -0.148873 0.405427 -0.0654834 0.0023860 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 11 38496 -0.145073 0.407627 -0.0666554 0.0025460 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 12 38497 -0.141372 0.409928 -0.0679434 0.0026110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 13 38498 -0.137572 0.412128 -0.0692344 0.0025510 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 14 38499 -0.133872 0.414328 -0.0704174 0.0023680 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 15 38500 -0.130172 0.416428 -0.0713684 0.0021390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 16 38501 -0.126471 0.418529 -0.0720945 0.0019190 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 17 38502 -0.122771 0.420629 -0.0726255 0.0017670 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 18 38503 -0.119071 0.422629 -0.0730595 0.0017170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 19 38504 -0.115470 0.424630 -0.0734915 0.0017800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 20 38505 -0.111870 0.426530 -0.0740445 0.0019150 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 21 38506 -0.108270 0.428430 -0.0747425 0.0020840 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 22 38507 -0.104670 0.430330 -0.0756115 0.0022410 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 23 38508 -0.101069 0.432131 -0.0766236 0.0023750 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 24 38509 -0.097569 0.433931 -0.0777546 0.0024660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 25 38510 -0.094069 0.435631 -0.0789466 0.0024980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 26 38511 -0.090569 0.437331 -0.0801326 0.0024550 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 27 38512 -0.087168 0.438932 -0.0812536 0.0023710 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 28 38513 -0.083768 0.440532 -0.0822866 0.0022630 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 29 38514 -0.080368 0.442032 -0.0831886 0.0021520 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 4 30 38515 -0.076967 0.443533 -0.0840067 0.0020600 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 1 38516 -0.073667 0.444933 -0.0847217 0.0019880 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 2 38517 -0.070367 0.446333 -0.0853997 0.0019580 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 3 38518 -0.067067 0.447633 -0.0860677 0.0019870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 4 38519 -0.063766 0.448934 -0.0867937 0.0020560 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 5 38520 -0.060466 0.450134 -0.0875987 0.0021720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 6 38521 -0.057266 0.451234 -0.0885637 0.0023560 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 7 38522 -0.054066 0.452234 -0.0897187 0.0025460 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 8 38523 -0.050865 0.453235 -0.0910728 0.0027350 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 9 38524 -0.047665 0.454135 -0.0925788 0.0028420 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 10 38525 -0.044565 0.455035 -0.0941398 0.0028510 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 11 38526 -0.041364 0.455836 -0.0956468 0.0027330 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 12 38527 -0.038264 0.456536 -0.0969818 0.0025240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 13 38528 -0.035164 0.457136 -0.0980908 0.0022840 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 14 38529 -0.031964 0.457736 -0.0989608 0.0020670 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 15 38530 -0.028863 0.458237 -0.0996638 0.0019460 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 16 38531 -0.025763 0.458737 -0.1002888 0.0019290 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 17 38532 -0.022663 0.459037 -0.1009519 0.0019980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 18 38533 -0.019562 0.459338 -0.1017189 0.0021210 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 19 38534 -0.016462 0.459638 -0.1026129 0.0022560 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 20 38535 -0.013362 0.459738 -0.1036289 0.0023600 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 21 38536 -0.010262 0.459838 -0.1047259 0.0024150 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 22 38537 -0.007161 0.459939 -0.1058409 0.0024050 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 23 38538 -0.004061 0.459939 -0.1069279 0.0023520 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 24 38539 -0.000961 0.459839 -0.1079409 0.0022680 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 25 38540 0.002139 0.459739 -0.1088649 0.0021460 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 26 38541 0.005340 0.459540 -0.1096510 0.0020160 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 27 38542 0.008440 0.459240 -0.1103000 0.0018770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 28 38543 0.011640 0.458940 -0.1108360 0.0017800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 29 38544 0.014741 0.458541 -0.1112870 0.0017320 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 30 38545 0.017941 0.458141 -0.1117180 0.0017310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 5 31 38546 0.021141 0.457641 -0.1121780 0.0017790 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 1 38547 0.024341 0.457141 -0.1127050 0.0018720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 2 38548 0.027542 0.456542 -0.1133360 0.0019980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 3 38549 0.030742 0.455842 -0.1141200 0.0021430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 4 38550 0.033942 0.455142 -0.1150250 0.0022840 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 5 38551 0.037142 0.454342 -0.1160770 0.0023920 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 6 38552 0.040343 0.453543 -0.1172030 0.0024340 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 7 38553 0.043643 0.452643 -0.1183091 0.0023580 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 8 38554 0.046843 0.451743 -0.1192921 0.0021710 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 9 38555 0.050144 0.450744 -0.1200361 0.0019090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 10 38556 0.053344 0.449644 -0.1204971 0.0016300 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 11 38557 0.056644 0.448544 -0.1207261 0.0014230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 12 38558 0.059944 0.447444 -0.1207891 0.0013100 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 13 38559 0.063145 0.446245 -0.1207911 0.0012890 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 14 38560 0.066445 0.444945 -0.1207891 0.0013330 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 15 38561 0.069745 0.443645 -0.1208711 0.0014100 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 16 38562 0.072945 0.442245 -0.1210091 0.0014570 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 17 38563 0.076246 0.440846 -0.1211761 0.0014480 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 18 38564 0.079546 0.439346 -0.1213051 0.0013800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 19 38565 0.082746 0.437846 -0.1213181 0.0012580 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 20 38566 0.086047 0.436347 -0.1212171 0.0011240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 21 38567 0.089247 0.434747 -0.1209671 0.0009630 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 22 38568 0.092547 0.433147 -0.1205602 0.0008120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 23 38569 0.095747 0.431447 -0.1200042 0.0006800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 24 38570 0.098948 0.429748 -0.1193482 0.0005930 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 25 38571 0.102148 0.428048 -0.1186052 0.0005400 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 26 38572 0.105348 0.426248 -0.1178472 0.0005430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 27 38573 0.108548 0.424448 -0.1171212 0.0006150 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 28 38574 0.111749 0.422649 -0.1164962 0.0007530 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 29 38575 0.114949 0.420749 -0.1160522 0.0009440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 6 30 38576 0.118049 0.418849 -0.1157932 0.0011410 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 1 38577 0.121250 0.416950 -0.1157452 0.0013510 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 2 38578 0.124350 0.415050 -0.1158882 0.0015280 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 3 38579 0.127450 0.413050 -0.1161932 0.0016610 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 4 38580 0.130650 0.411050 -0.1165932 0.0017120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 5 38581 0.133751 0.409051 -0.1169862 0.0016470 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 6 38582 0.136851 0.407051 -0.1172792 0.0014990 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 7 38583 0.139851 0.404951 -0.1173822 0.0013060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 8 38584 0.142951 0.402851 -0.1173112 0.0011320 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 9 38585 0.145952 0.400752 -0.1170962 0.0010450 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 10 38586 0.149052 0.398552 -0.1168372 0.0010650 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 11 38587 0.152052 0.396452 -0.1166572 0.0011640 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 12 38588 0.155053 0.394153 -0.1165982 0.0013090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 13 38589 0.158053 0.391953 -0.1166692 0.0014060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 14 38590 0.160953 0.389653 -0.1168002 0.0014540 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 15 38591 0.163953 0.387353 -0.1169632 0.0014500 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 16 38592 0.166854 0.385054 -0.1170782 0.0013810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 17 38593 0.169754 0.382654 -0.1171082 0.0012630 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 18 38594 0.172554 0.380254 -0.1170152 0.0011360 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 19 38595 0.175454 0.377854 -0.1167872 0.0009980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 20 38596 0.178255 0.375355 -0.1164132 0.0008580 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 21 38597 0.181055 0.372755 -0.1159212 0.0007530 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 22 38598 0.183755 0.370255 -0.1153422 0.0006880 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 23 38599 0.186456 0.367556 -0.1147142 0.0006760 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 24 38600 0.189156 0.364956 -0.1141142 0.0007240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 25 38601 0.191756 0.362156 -0.1135922 0.0008310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 26 38602 0.194356 0.359356 -0.1132022 0.0009960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 27 38603 0.196957 0.356557 -0.1129932 0.0011800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 28 38604 0.199457 0.353657 -0.1129722 0.0013850 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 29 38605 0.201957 0.350657 -0.1131552 0.0015540 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 30 38606 0.204357 0.347657 -0.1134722 0.0016690 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 7 31 38607 0.206658 0.344658 -0.1138792 0.0017110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 1 38608 0.209058 0.341458 -0.1142872 0.0016720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 2 38609 0.211258 0.338258 -0.1146182 0.0015690 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 3 38610 0.213459 0.335059 -0.1148222 0.0014260 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 4 38611 0.215559 0.331759 -0.1148822 0.0012710 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 5 38612 0.217659 0.328359 -0.1148062 0.0011800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 6 38613 0.219659 0.324959 -0.1146862 0.0011880 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 7 38614 0.221560 0.321460 -0.1146262 0.0012860 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 8 38615 0.223460 0.317860 -0.1147012 0.0014480 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 9 38616 0.225160 0.314260 -0.1149352 0.0016060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 10 38617 0.226861 0.310561 -0.1153082 0.0017180 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 11 38618 0.228461 0.306861 -0.1157442 0.0017410 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 12 38619 0.229961 0.303061 -0.1161632 0.0016640 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 13 38620 0.231461 0.299161 -0.1164592 0.0015210 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 14 38621 0.232762 0.295262 -0.1165912 0.0013480 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 15 38622 0.234062 0.291262 -0.1165502 0.0011590 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 16 38623 0.235262 0.287262 -0.1163112 0.0009750 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 17 38624 0.236362 0.283162 -0.1159092 0.0008060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 18 38625 0.237263 0.279063 -0.1153362 0.0006770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 19 38626 0.238263 0.274863 -0.1146912 0.0006210 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 20 38627 0.239063 0.270663 -0.1140082 0.0006240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 21 38628 0.239764 0.266364 -0.1133592 0.0006970 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 22 38629 0.240364 0.262064 -0.1128212 0.0008250 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 23 38630 0.240964 0.257764 -0.1124232 0.0009920 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 24 38631 0.241364 0.253364 -0.1122192 0.0011800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 25 38632 0.241765 0.248965 -0.1121952 0.0013540 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 26 38633 0.241965 0.244465 -0.1123182 0.0014800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 27 38634 0.242165 0.239965 -0.1125272 0.0015240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 28 38635 0.242265 0.235565 -0.1127562 0.0015000 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 29 38636 0.242266 0.230966 -0.1129032 0.0013940 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 30 38637 0.242166 0.226466 -0.1129302 0.0012480 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 8 31 38638 0.242066 0.221966 -0.1128102 0.0011170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 1 38639 0.241767 0.217367 -0.0125822 0.0010390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 2 38640 0.241467 0.212767 -0.0123272 0.0010580 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 3 38641 0.241067 0.208267 -0.0121311 0.0011660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 4 38642 0.240567 0.203667 -0.0120961 0.0013640 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 5 38643 0.239968 0.199168 -0.0122791 0.0015940 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 6 38644 0.239368 0.194568 -0.0126771 0.0018020 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 7 38645 0.238568 0.190068 -0.0132621 0.0019440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 8 38646 0.237768 0.185568 -0.0139451 0.0019980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 9 38647 0.236969 0.181069 -0.0146311 0.0019620 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 10 38648 0.235969 0.176569 -0.0152591 0.0018770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 11 38649 0.234969 0.172169 -0.0157851 0.0017720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 12 38650 0.233970 0.167770 -0.0162021 0.0016540 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 13 38651 0.232770 0.163370 -0.0165091 0.0015460 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 14 38652 0.231670 0.159070 -0.0167171 0.0014770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 15 38653 0.230370 0.154770 -0.0168921 0.0014620 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 16 38654 0.229071 0.150571 -0.0170611 0.0014970 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 17 38655 0.227771 0.146371 -0.0173061 0.0015930 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 18 38656 0.226371 0.142271 -0.0176670 0.0017370 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 19 38657 0.224871 0.138171 -0.0182070 0.0019290 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 20 38658 0.223372 0.134072 -0.0189540 0.0021470 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 21 38659 0.221872 0.130072 -0.0199200 0.0023590 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 22 38660 0.220272 0.126172 -0.0210570 0.0025030 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 23 38661 0.218673 0.122273 -0.0223070 0.0025810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 24 38662 0.216973 0.118473 -0.0235930 0.0025550 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 25 38663 0.215273 0.114673 -0.0247860 0.0024260 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 26 38664 0.213573 0.110973 -0.0258380 0.0022430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 27 38665 0.211774 0.107374 -0.0266910 0.0020670 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 28 38666 0.209974 0.103774 -0.0273890 0.0019310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 29 38667 0.208074 0.100274 -0.0279910 0.0018900 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 9 30 38668 0.206174 0.096874 -0.0286129 0.0019480 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 1 38669 0.204175 0.093475 -0.0293259 0.0020900 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 2 38670 0.202175 0.090175 -0.0302179 0.0022800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 3 38671 0.200175 0.086975 -0.0313049 0.0024700 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 4 38672 0.198076 0.083776 -0.0325519 0.0026140 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 5 38673 0.195976 0.080676 -0.0339059 0.0026710 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 6 38674 0.193776 0.077676 -0.0352759 0.0026540 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 7 38675 0.191576 0.074676 -0.0365909 0.0025550 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 8 38676 0.189377 0.071877 -0.0377809 0.0024100 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 9 38677 0.187077 0.069077 -0.0388148 0.0022470 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 10 38678 0.184777 0.066277 -0.0396878 0.0020940 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 11 38679 0.182377 0.063677 -0.0404238 0.0019740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 12 38680 0.179978 0.061078 -0.0410628 0.0019040 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 13 38681 0.177478 0.058578 -0.0416518 0.0018850 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 14 38682 0.174978 0.056078 -0.0422638 0.0019400 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 15 38683 0.172479 0.053679 -0.0429518 0.0020440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 16 38684 0.169879 0.051379 -0.0437698 0.0021990 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 17 38685 0.167279 0.049079 -0.0447638 0.0023820 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 18 38686 0.164679 0.046879 -0.0459487 0.0025880 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 19 38687 0.161980 0.044780 -0.0473327 0.0027610 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 20 38688 0.159280 0.042680 -0.0488587 0.0028660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 21 38689 0.156480 0.040680 -0.0504287 0.0028560 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 22 38690 0.153680 0.038680 -0.0519327 0.0027330 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 23 38691 0.150881 0.036681 -0.0532767 0.0025230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 24 38692 0.147981 0.034881 -0.0543897 0.0022940 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 25 38693 0.145081 0.032981 -0.0552857 0.0020990 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 26 38694 0.142182 0.031182 -0.0560166 0.0019900 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 27 38695 0.139182 0.029382 -0.0566896 0.0019740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 28 38696 0.136182 0.027582 -0.0574056 0.0020610 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 29 38697 0.133182 0.025882 -0.0582396 0.0022030 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 30 38698 0.130083 0.024183 -0.0592246 0.0023550 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 10 31 38699 0.126983 0.022583 -0.0603496 0.0024760 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 1 38700 0.123783 0.020883 -0.0615556 0.0025250 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 2 38701 0.120584 0.019284 -0.0627935 0.0025170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 3 38702 0.117384 0.017684 -0.0639755 0.0024370 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 4 38703 0.114184 0.016084 -0.0650495 0.0022930 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 5 38704 0.110884 0.014584 -0.0659715 0.0021390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 6 38705 0.107585 0.012985 -0.0667365 0.0019820 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 7 38706 0.104285 0.011485 -0.0673435 0.0018370 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 8 38707 0.100885 0.009985 -0.0678354 0.0017460 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 9 38708 0.097585 0.008485 -0.0682644 0.0017110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 10 38709 0.094186 0.006986 -0.0686794 0.0017410 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 11 38710 0.090786 0.005486 -0.0691664 0.0018320 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 12 38711 0.087386 0.003986 -0.0697714 0.0019650 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 13 38712 0.083987 0.002587 -0.0705304 0.0021480 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 14 38713 0.080487 0.001187 -0.0714754 0.0023450 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 15 38714 0.077087 -0.000213 -0.0726303 0.0025510 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 16 38715 0.073687 -0.001613 -0.0739643 0.0027070 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 17 38716 0.070188 -0.002912 -0.0754183 0.0027840 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 18 38717 0.066788 -0.004312 -0.0768933 0.0027490 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 19 38718 0.063288 -0.005612 -0.0782793 0.0025960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 20 38719 0.059888 -0.006812 -0.0794823 0.0023850 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 21 38720 0.056489 -0.008011 -0.0804592 0.0021750 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 22 38721 0.052989 -0.009211 -0.0812552 0.0020230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 23 38722 0.049589 -0.010411 -0.0819512 0.0019800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 24 38723 0.046190 -0.011510 -0.0826602 0.0020520 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 25 38724 0.042790 -0.012610 -0.0834792 0.0021740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 26 38725 0.039390 -0.013610 -0.0844241 0.0023240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 27 38726 0.035990 -0.014610 -0.0855171 0.0024440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 28 38727 0.032691 -0.015509 -0.0867131 0.0025250 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 29 38728 0.029291 -0.016309 -0.0879431 0.0025240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 11 30 38729 0.025891 -0.017109 -0.0891491 0.0024770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 1 38730 0.022591 -0.017909 -0.0902890 0.0023760 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 2 38731 0.019292 -0.018508 -0.0913000 0.0022330 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 3 38732 0.015992 -0.019108 -0.0921620 0.0020910 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 4 38733 0.012592 -0.019708 -0.0928860 0.0019610 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 5 38734 0.009393 -0.020107 -0.0934960 0.0018660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 6 38735 0.006093 -0.020507 -0.0940450 0.0018320 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 7 38736 0.002793 -0.020907 -0.0945909 0.0018390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 8 38737 -0.000507 -0.021107 -0.0951639 0.0019180 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 9 38738 -0.003706 -0.021306 -0.0958449 0.0020300 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 10 38739 -0.006906 -0.021406 -0.0966589 0.0021930 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 11 38740 -0.010206 -0.021406 -0.0976489 0.0023800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 12 38741 -0.013406 -0.021306 -0.0988298 0.0025620 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 13 38742 -0.016605 -0.021205 -0.1001768 0.0027150 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 14 38743 -0.019805 -0.021005 -0.1016528 0.0028150 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 15 38744 -0.023005 -0.020805 -0.1031778 0.0028200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 16 38745 -0.026104 -0.020404 -0.1046567 0.0027110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 17 38746 -0.029304 -0.020004 -0.1059807 0.0025250 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 18 38747 -0.032504 -0.019504 -0.1071047 0.0023020 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 19 38748 -0.035604 -0.019004 -0.1080067 0.0021040 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 20 38749 -0.038803 -0.018403 -0.1087547 0.0020010 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 21 38750 -0.042003 -0.017703 -0.1094586 0.0020150 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 22 38751 -0.045103 -0.017003 -0.1102166 0.0021230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 23 38752 -0.048303 -0.016203 -0.1111156 0.0022660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 24 38753 -0.051502 -0.015302 -0.1121516 0.0023860 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 25 38754 -0.054602 -0.014402 -0.1132755 0.0024300 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 26 38755 -0.057802 -0.013402 -0.1144035 0.0024020 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 27 38756 -0.061001 -0.012301 -0.1154655 0.0023010 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 28 38757 -0.064201 -0.011201 -0.1163875 0.0021460 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 29 38758 -0.067401 -0.010001 -0.1171475 0.0019600 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 30 38759 -0.070601 -0.008801 -0.1177154 0.0017660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1964 12 31 38760 -0.073900 -0.007500 -0.1180924 0.0015830 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 1 38761 -0.077100 -0.006200 -0.0182914 0.0014300 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 2 38762 -0.080300 -0.004800 -0.0183784 0.0013330 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 3 38763 -0.083600 -0.003300 -0.0183863 0.0012940 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 4 38764 -0.086799 -0.001799 -0.0183853 0.0013150 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 5 38765 -0.090099 -0.000199 -0.0184453 0.0013930 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 6 38766 -0.093299 0.001401 -0.0185953 0.0015230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 7 38767 -0.096598 0.003002 -0.0188992 0.0016770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 8 38768 -0.099898 0.004802 -0.0193612 0.0018340 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 9 38769 -0.103098 0.006502 -0.0199712 0.0019730 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 10 38770 -0.106398 0.008302 -0.0207022 0.0020810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 11 38771 -0.109697 0.010203 -0.0215121 0.0021250 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 12 38772 -0.112997 0.012103 -0.0223351 0.0020970 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 13 38773 -0.116297 0.014103 -0.0230871 0.0019960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 14 38774 -0.119497 0.016103 -0.0237181 0.0018510 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 15 38775 -0.122796 0.018104 -0.0241900 0.0017100 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 16 38776 -0.126096 0.020204 -0.0245600 0.0016360 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 17 38777 -0.129296 0.022304 -0.0249000 0.0016750 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 18 38778 -0.132595 0.024405 -0.0253480 0.0018260 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 19 38779 -0.135795 0.026605 -0.0259959 0.0020670 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 20 38780 -0.138995 0.028805 -0.0268909 0.0023070 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 21 38781 -0.142195 0.031105 -0.0279879 0.0024650 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 22 38782 -0.145294 0.033406 -0.0291979 0.0025370 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 23 38783 -0.148394 0.035706 -0.0304308 0.0025060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 24 38784 -0.151494 0.038006 -0.0315958 0.0024040 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 25 38785 -0.154493 0.040307 -0.0326358 0.0022630 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 26 38786 -0.157493 0.042707 -0.0335277 0.0021120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 27 38787 -0.160493 0.045007 -0.0342747 0.0019650 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 28 38788 -0.163393 0.047407 -0.0348777 0.0018390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 29 38789 -0.166192 0.049808 -0.0353777 0.0017590 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 30 38790 -0.168992 0.052108 -0.0358156 0.0017260 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 1 31 38791 -0.171792 0.054508 -0.0362596 0.0017630 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 1 38792 -0.174492 0.056908 -0.0367716 0.0018500 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 2 38793 -0.177091 0.059309 -0.0373945 0.0019940 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 3 38794 -0.179691 0.061709 -0.0381685 0.0021570 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 4 38795 -0.182191 0.064109 -0.0391095 0.0023240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 5 38796 -0.184690 0.066510 -0.0402085 0.0024600 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 6 38797 -0.187090 0.068810 -0.0414244 0.0025610 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 7 38798 -0.189490 0.071210 -0.0427104 0.0025900 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 8 38799 -0.191790 0.073610 -0.0439894 0.0025350 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 9 38800 -0.194089 0.076011 -0.0451773 0.0024200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 10 38801 -0.196289 0.078411 -0.0462123 0.0022540 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 11 38802 -0.198389 0.080811 -0.0470813 0.0020770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 12 38803 -0.200489 0.083211 -0.0477803 0.0019440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 13 38804 -0.202488 0.085612 -0.0484012 0.0019050 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 14 38805 -0.204488 0.088112 -0.0490312 0.0019730 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 15 38806 -0.206488 0.090512 -0.0498002 0.0021570 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 16 38807 -0.208387 0.093013 -0.0507671 0.0023780 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 17 38808 -0.210187 0.095513 -0.0519431 0.0025640 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 18 38809 -0.211987 0.098013 -0.0532731 0.0026590 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 19 38810 -0.213787 0.100613 -0.0546330 0.0026430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 20 38811 -0.215486 0.103214 -0.0559360 0.0025390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 21 38812 -0.217086 0.105814 -0.0571010 0.0023730 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 22 38813 -0.218686 0.108414 -0.0580849 0.0021940 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 23 38814 -0.220286 0.111114 -0.0588909 0.0020230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 24 38815 -0.221785 0.113815 -0.0595509 0.0018940 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 25 38816 -0.223285 0.116515 -0.0601048 0.0018030 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 26 38817 -0.224685 0.119315 -0.0605868 0.0017810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 27 38818 -0.226084 0.122116 -0.0610888 0.0018120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 2 28 38819 -0.227484 0.124916 -0.0616527 0.0019250 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 1 38820 -0.228784 0.127816 0.0376433 0.0020820 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 2 38821 -0.229984 0.130716 0.0367723 0.0022750 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 3 38822 -0.231183 0.133717 0.0356874 0.0024830 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 4 38823 -0.232383 0.136717 0.0344104 0.0026760 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 5 38824 -0.233483 0.139717 0.0329514 0.0028230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 6 38825 -0.234583 0.142817 0.0313795 0.0028990 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 7 38826 -0.235582 0.145918 0.0297815 0.0028940 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 8 38827 -0.236582 0.149018 0.0282175 0.0028030 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 9 38828 -0.237482 0.152218 0.0267726 0.0026710 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 10 38829 -0.238281 0.155419 0.0254696 0.0025270 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 11 38830 -0.239081 0.158619 0.0242976 0.0024060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 12 38831 -0.239881 0.161819 0.0232207 0.0023650 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 13 38832 -0.240481 0.165119 0.0221317 0.0024220 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 14 38833 -0.241080 0.168320 0.0209217 0.0025820 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 15 38834 -0.241680 0.171620 0.0195248 0.0028090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 16 38835 -0.242080 0.174920 0.0179038 0.0030280 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 17 38836 -0.242480 0.178220 0.0160898 0.0031840 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 18 38837 -0.242779 0.181621 0.0141699 0.0032350 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 19 38838 -0.243079 0.184921 0.0122479 0.0031730 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 20 38839 -0.243179 0.188221 0.0104349 0.0030210 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 21 38840 -0.243278 0.191622 0.0088120 0.0028200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 22 38841 -0.243278 0.194922 0.0073970 0.0026120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 23 38842 -0.243178 0.198322 0.0061800 0.0024280 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 24 38843 -0.243078 0.201622 0.0051161 0.0022900 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 25 38844 -0.242777 0.204923 0.0041591 0.0022230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 26 38845 -0.242477 0.208223 0.0032472 0.0022120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 27 38846 -0.242077 0.211623 0.0023042 0.0022760 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 28 38847 -0.241577 0.214923 0.0012762 0.0023880 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 29 38848 -0.241076 0.218224 0.0001023 0.0025450 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 30 38849 -0.240376 0.221424 -0.0012417 0.0027370 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 3 31 38850 -0.239676 0.224724 -0.0027807 0.0029280 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 1 38851 -0.238875 0.228025 -0.0044866 0.0030760 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 2 38852 -0.238075 0.231225 -0.0063096 0.0031570 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 3 38853 -0.237175 0.234425 -0.0081805 0.0031480 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 4 38854 -0.236175 0.237625 -0.0099845 0.0030470 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 5 38855 -0.235174 0.240826 -0.0116505 0.0028770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 6 38856 -0.234074 0.244026 -0.0131304 0.0026730 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 7 38857 -0.232974 0.247226 -0.0144264 0.0025070 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 8 38858 -0.231874 0.250326 -0.0155804 0.0024060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 9 38859 -0.230573 0.253427 -0.0166823 0.0024160 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 10 38860 -0.229373 0.256527 -0.0178463 0.0025180 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 11 38861 -0.228073 0.259627 -0.0191642 0.0026960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 12 38862 -0.226772 0.262728 -0.0206682 0.0029010 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 13 38863 -0.225372 0.265728 -0.0223642 0.0030720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 14 38864 -0.223972 0.268728 -0.0241851 0.0031530 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 15 38865 -0.222572 0.271828 -0.0260441 0.0031270 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 16 38866 -0.221171 0.274729 -0.0278150 0.0030000 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 17 38867 -0.219671 0.277729 -0.0294210 0.0027930 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 18 38868 -0.218171 0.280729 -0.0308010 0.0025570 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 19 38869 -0.216670 0.283630 -0.0319469 0.0023180 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 20 38870 -0.215070 0.286530 -0.0328599 0.0021170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 21 38871 -0.213570 0.289430 -0.0335988 0.0019730 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 22 38872 -0.211970 0.292230 -0.0342368 0.0019050 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 23 38873 -0.210369 0.295131 -0.0348428 0.0019060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 24 38874 -0.208869 0.297931 -0.0354807 0.0019590 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 25 38875 -0.207269 0.300631 -0.0361967 0.0020700 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 26 38876 -0.205569 0.303431 -0.0370416 0.0022140 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 27 38877 -0.203968 0.306132 -0.0380386 0.0023790 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 28 38878 -0.202368 0.308832 -0.0392056 0.0025290 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 29 38879 -0.200768 0.311532 -0.0404905 0.0026310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 4 30 38880 -0.199067 0.314233 -0.0418505 0.0026620 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 1 38881 -0.197467 0.316833 -0.0431914 0.0025930 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 2 38882 -0.195867 0.319433 -0.0444254 0.0024420 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 3 38883 -0.194167 0.322033 -0.0454583 0.0022310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 4 38884 -0.192566 0.324534 -0.0462993 0.0020470 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 5 38885 -0.190866 0.327134 -0.0469863 0.0019310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 6 38886 -0.189266 0.329634 -0.0476062 0.0019080 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 7 38887 -0.187666 0.332034 -0.0482492 0.0019930 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 8 38888 -0.185965 0.334535 -0.0490281 0.0021660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 9 38889 -0.184365 0.336935 -0.0500031 0.0023730 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 10 38890 -0.182765 0.339335 -0.0511680 0.0025510 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 11 38891 -0.181064 0.341636 -0.0524930 0.0026650 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 12 38892 -0.179464 0.343936 -0.0538880 0.0026990 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 13 38893 -0.177764 0.346236 -0.0552599 0.0026290 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 14 38894 -0.176064 0.348536 -0.0565209 0.0024730 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 15 38895 -0.174463 0.350737 -0.0576008 0.0022830 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 16 38896 -0.172763 0.352937 -0.0584948 0.0020850 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 17 38897 -0.170963 0.355137 -0.0591897 0.0019120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 18 38898 -0.169263 0.357237 -0.0597347 0.0017770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 19 38899 -0.167462 0.359338 -0.0601756 0.0017050 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 20 38900 -0.165762 0.361438 -0.0605786 0.0017120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 21 38901 -0.163962 0.363438 -0.0610216 0.0017740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 22 38902 -0.162061 0.365439 -0.0615535 0.0018980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 23 38903 -0.160161 0.367439 -0.0622285 0.0020470 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 24 38904 -0.158261 0.369439 -0.0630724 0.0022230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 25 38905 -0.156361 0.371339 -0.0640824 0.0023940 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 26 38906 -0.154360 0.373240 -0.0652523 0.0025270 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 27 38907 -0.152360 0.375140 -0.0665273 0.0026110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 28 38908 -0.150260 0.377040 -0.0678442 0.0025970 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 29 38909 -0.148060 0.378840 -0.0691092 0.0024960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 30 38910 -0.145859 0.380741 -0.0702101 0.0023070 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 5 31 38911 -0.143659 0.382541 -0.0711241 0.0021030 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 1 38912 -0.141359 0.384341 -0.0718310 0.0019340 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 2 38913 -0.138958 0.386142 -0.0724250 0.0018630 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 3 38914 -0.136558 0.387942 -0.0730170 0.0019210 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 4 38915 -0.134058 0.389742 -0.0736989 0.0020650 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 5 38916 -0.131458 0.391542 -0.0745709 0.0022510 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 6 38917 -0.128757 0.393343 -0.0756158 0.0024310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 7 38918 -0.126057 0.395143 -0.0768118 0.0025370 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 8 38919 -0.123257 0.396843 -0.0780707 0.0025650 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 9 38920 -0.120357 0.398643 -0.0793327 0.0025050 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 10 38921 -0.117356 0.400344 -0.0804766 0.0023630 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 11 38922 -0.114256 0.402044 -0.0814536 0.0021750 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 12 38923 -0.111156 0.403744 -0.0822325 0.0019740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 13 38924 -0.107955 0.405445 -0.0828165 0.0017880 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 14 38925 -0.104655 0.407145 -0.0832224 0.0016320 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 15 38926 -0.101255 0.408745 -0.0834994 0.0015220 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 16 38927 -0.097855 0.410345 -0.0837083 0.0014880 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 17 38928 -0.094354 0.411946 -0.0838973 0.0015000 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 18 38929 -0.090754 0.413546 -0.0841372 0.0015670 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 19 38930 -0.087054 0.415046 -0.0844552 0.0016630 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 20 38931 -0.083354 0.416446 -0.0848801 0.0017880 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 21 38932 -0.079553 0.417947 -0.0854301 0.0019000 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 22 38933 -0.075753 0.419247 -0.0860940 0.0020020 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 23 38934 -0.071853 0.420647 -0.0868200 0.0020320 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 24 38935 -0.067952 0.421848 -0.0875449 0.0020050 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 25 38936 -0.063952 0.423148 -0.0882219 0.0019140 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 26 38937 -0.059952 0.424248 -0.0887638 0.0017390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 27 38938 -0.055852 0.425348 -0.0891028 0.0015230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 28 38939 -0.051751 0.426449 -0.0892237 0.0013170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 29 38940 -0.047651 0.427449 -0.0891617 0.0011870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 6 30 38941 -0.043551 0.428349 -0.0890396 0.0011980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 1 38942 -0.039451 0.429149 0.0110014 0.0013280 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 2 38943 -0.035250 0.429950 0.0108725 0.0015370 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 3 38944 -0.031150 0.430650 0.0105275 0.0017560 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 4 38945 -0.027050 0.431350 0.0099826 0.0019180 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 5 38946 -0.022849 0.431951 0.0093256 0.0019700 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 6 38947 -0.018749 0.432451 0.0086577 0.0019300 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 7 38948 -0.014649 0.432851 0.0080827 0.0018110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 8 38949 -0.010649 0.433251 0.0076518 0.0016460 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 9 38950 -0.006648 0.433552 0.0073838 0.0014800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 10 38951 -0.002648 0.433852 0.0072769 0.0013190 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 11 38952 0.001352 0.433952 0.0073239 0.0011950 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 12 38953 0.005152 0.434052 0.0074600 0.0011340 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 13 38954 0.009053 0.434153 0.0076361 0.0011250 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 14 38955 0.012753 0.434153 0.0077691 0.0011900 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 15 38956 0.016453 0.434053 0.0078272 0.0013030 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 16 38957 0.020154 0.433854 0.0077492 0.0014490 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 17 38958 0.023654 0.433654 0.0075123 0.0016170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 18 38959 0.027154 0.433354 0.0071063 0.0017740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 19 38960 0.030554 0.433054 0.0065524 0.0019190 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 20 38961 0.033855 0.432655 0.0058814 0.0020150 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 21 38962 0.037055 0.432155 0.0051495 0.0020470 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 22 38963 0.040155 0.431655 0.0044005 0.0020200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 23 38964 0.043156 0.431056 0.0037236 0.0019020 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 24 38965 0.046056 0.430356 0.0032056 0.0017260 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 25 38966 0.048956 0.429656 0.0028677 0.0015540 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 26 38967 0.051656 0.428856 0.0026828 0.0014180 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 27 38968 0.054357 0.427957 0.0025858 0.0013960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 28 38969 0.056857 0.427057 0.0024479 0.0015010 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 29 38970 0.059357 0.426057 0.0021489 0.0017100 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 30 38971 0.061757 0.424957 0.0016160 0.0019440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 7 31 38972 0.064058 0.423858 0.0008660 0.0021430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 1 38973 0.066258 0.422658 -0.0000339 0.0022260 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 2 38974 0.068358 0.421358 -0.0009629 0.0021920 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 3 38975 0.070359 0.419959 -0.0017938 0.0020440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 4 38976 0.072359 0.418559 -0.0024497 0.0018430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 5 38977 0.074259 0.417059 -0.0028827 0.0016240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 6 38978 0.076059 0.415459 -0.0031036 0.0014130 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 7 38979 0.077860 0.413860 -0.0031326 0.0012430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 8 38980 0.079560 0.412160 -0.0030175 0.0011380 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 9 38981 0.081260 0.410360 -0.0028295 0.0010960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 10 38982 0.082860 0.408460 -0.0026424 0.0011180 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 11 38983 0.084461 0.406461 -0.0024963 0.0012000 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 12 38984 0.085961 0.404461 -0.0024673 0.0013380 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 13 38985 0.087561 0.402361 -0.0025922 0.0015040 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 14 38986 0.089062 0.400162 -0.0028872 0.0016740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 15 38987 0.090462 0.397962 -0.0033421 0.0018320 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 16 38988 0.091962 0.395562 -0.0039361 0.0019480 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 17 38989 0.093362 0.393162 -0.0046290 0.0020070 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 18 38990 0.094863 0.390663 -0.0053379 0.0020110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 19 38991 0.096263 0.388163 -0.0060289 0.0019420 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 20 38992 0.097663 0.385563 -0.0066238 0.0018310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 21 38993 0.099063 0.382863 -0.0070838 0.0016890 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 22 38994 0.100564 0.380064 -0.0074197 0.0015820 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 23 38995 0.101964 0.377264 -0.0076836 0.0015530 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 24 38996 0.103464 0.374364 -0.0079766 0.0016430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 25 38997 0.104965 0.371365 -0.0084205 0.0018420 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 26 38998 0.106465 0.368365 -0.0091065 0.0021270 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 27 38999 0.107965 0.365265 -0.0100834 0.0024080 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 28 39000 0.109465 0.362165 -0.0112953 0.0025960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 29 39001 0.111066 0.358966 -0.0126313 0.0026520 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 30 39002 0.112666 0.355666 -0.0139632 0.0025730 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 8 31 39003 0.114266 0.352366 -0.0151632 0.0023960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 1 39004 0.115866 0.349066 0.0838499 0.0021760 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 2 39005 0.117467 0.345667 0.0830830 0.0019530 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 3 39006 0.119167 0.342267 0.0825200 0.0017730 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 4 39007 0.120867 0.338867 0.0821081 0.0016630 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 5 39008 0.122668 0.335368 0.0817711 0.0016120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 6 39009 0.124368 0.331868 0.0814612 0.0016190 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 7 39010 0.126168 0.328368 0.0811033 0.0016990 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 8 39011 0.127968 0.324768 0.0806473 0.0018190 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 9 39012 0.129869 0.321169 0.0800424 0.0019840 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 10 39013 0.131669 0.317669 0.0792655 0.0021590 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 11 39014 0.133569 0.314069 0.0783185 0.0023100 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 12 39015 0.135469 0.310369 0.0772386 0.0024310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 13 39016 0.137370 0.306770 0.0760776 0.0024910 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 14 39017 0.139270 0.303170 0.0748817 0.0024780 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 15 39018 0.141170 0.299570 0.0737348 0.0024050 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 16 39019 0.143071 0.295871 0.0726898 0.0022790 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 17 39020 0.144971 0.292271 0.0717839 0.0021320 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 18 39021 0.146871 0.288671 0.0710200 0.0020030 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 19 39022 0.148771 0.284971 0.0703560 0.0019390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 20 39023 0.150672 0.281372 0.0696981 0.0019770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 21 39024 0.152572 0.277772 0.0689441 0.0021410 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 22 39025 0.154472 0.274172 0.0679642 0.0024000 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 23 39026 0.156272 0.270672 0.0667113 0.0026960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 24 39027 0.158073 0.267073 0.0651853 0.0029520 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 25 39028 0.159973 0.263473 0.0634444 0.0030880 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 26 39029 0.161673 0.259973 0.0616365 0.0030940 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 27 39030 0.163474 0.256474 0.0598895 0.0029820 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 28 39031 0.165174 0.252974 0.0583086 0.0027710 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 29 39032 0.166874 0.249474 0.0569547 0.0025280 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 9 30 39033 0.168574 0.246074 0.0558227 0.0023240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 1 39034 0.170175 0.242575 0.0548868 0.0021690 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 2 39035 0.171775 0.239175 0.0540599 0.0020780 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 3 39036 0.173375 0.235775 0.0532969 0.0020610 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 4 39037 0.174875 0.232475 0.0525050 0.0021130 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 5 39038 0.176376 0.229076 0.0516410 0.0022130 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 6 39039 0.177776 0.225776 0.0506461 0.0023420 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 7 39040 0.179176 0.222476 0.0495402 0.0024910 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 8 39041 0.180577 0.219277 0.0482652 0.0026440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 9 39042 0.181877 0.215977 0.0468613 0.0027580 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 10 39043 0.183077 0.212777 0.0453584 0.0028250 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 11 39044 0.184277 0.209577 0.0438254 0.0028170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 12 39045 0.185478 0.206478 0.0423415 0.0027280 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 13 39046 0.186578 0.203378 0.0409926 0.0025700 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 14 39047 0.187578 0.200278 0.0398136 0.0023770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 15 39048 0.188479 0.197179 0.0388347 0.0021960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 16 39049 0.189379 0.194179 0.0380008 0.0020650 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 17 39050 0.190279 0.191179 0.0372538 0.0020380 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 18 39051 0.190979 0.188279 0.0364769 0.0021320 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 19 39052 0.191680 0.185280 0.0355570 0.0023220 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 20 39053 0.192280 0.182480 0.0344151 0.0025670 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 21 39054 0.192780 0.179580 0.0330251 0.0028150 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 22 39055 0.193180 0.176780 0.0314102 0.0029890 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 23 39056 0.193481 0.174081 0.0296873 0.0030340 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 24 39057 0.193781 0.171281 0.0279653 0.0029600 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 25 39058 0.193881 0.168681 0.0263824 0.0027920 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 26 39059 0.193982 0.165982 0.0249995 0.0025600 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 27 39060 0.193982 0.163382 0.0238515 0.0023410 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 28 39061 0.193882 0.160782 0.0228936 0.0021550 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 29 39062 0.193682 0.158182 0.0220967 0.0020500 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 30 39063 0.193383 0.155683 0.0213677 0.0020120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 10 31 39064 0.192983 0.153183 0.0206488 0.0020490 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 1 39065 0.192583 0.150683 0.0198489 0.0021500 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 2 39066 0.191983 0.148183 0.0189229 0.0022980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 3 39067 0.191384 0.145784 0.0178330 0.0024720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 4 39068 0.190684 0.143284 0.0165661 0.0026600 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 5 39069 0.189884 0.140884 0.0151192 0.0028290 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 6 39070 0.189085 0.138485 0.0135212 0.0029460 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 7 39071 0.188085 0.136085 0.0118283 0.0030070 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 8 39072 0.187085 0.133585 0.0101254 0.0029760 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 9 39073 0.185985 0.131185 0.0084944 0.0028720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 10 39074 0.184786 0.128786 0.0070095 0.0027010 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 11 39075 0.183586 0.126386 0.0056856 0.0025300 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 12 39076 0.182186 0.123886 0.0045137 0.0023960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 13 39077 0.180786 0.121486 0.0034517 0.0023450 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 14 39078 0.179287 0.119087 0.0023748 0.0024170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 15 39079 0.177787 0.116587 0.0011839 0.0025690 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 16 39080 0.176187 0.114087 -0.0002031 0.0027890 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 17 39081 0.174488 0.111688 -0.0017960 0.0030030 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 18 39082 0.172688 0.109188 -0.0035909 0.0031630 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 19 39083 0.170888 0.106688 -0.0055008 0.0032180 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 20 39084 0.168988 0.104188 -0.0074078 0.0031580 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 21 39085 0.167089 0.101689 -0.0091917 0.0029950 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 22 39086 0.165089 0.099189 -0.0107756 0.0027550 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 23 39087 0.162989 0.096689 -0.0121046 0.0025040 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 24 39088 0.160889 0.094189 -0.0132025 0.0022780 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 25 39089 0.158690 0.091690 -0.0141004 0.0021090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 26 39090 0.156490 0.089290 -0.0148543 0.0020130 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 27 39091 0.154190 0.086790 -0.0155513 0.0019930 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 28 39092 0.151791 0.084291 -0.0162632 0.0020310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 29 39093 0.149391 0.081891 -0.0170511 0.0021330 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 11 30 39094 0.146991 0.079391 -0.0179590 0.0022770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 1 39095 0.144491 0.076991 -0.0190180 0.0024200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 2 39096 0.141892 0.074592 -0.0202059 0.0025520 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 3 39097 0.139392 0.072192 -0.0215118 0.0026430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 4 39098 0.136692 0.069792 -0.0228947 0.0026930 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 5 39099 0.134092 0.067392 -0.0242847 0.0026540 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 6 39100 0.131393 0.065093 -0.0255866 0.0025450 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 7 39101 0.128693 0.062793 -0.0267505 0.0023540 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 8 39102 0.125893 0.060493 -0.0277014 0.0021360 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 9 39103 0.123094 0.058294 -0.0284294 0.0019380 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 10 39104 0.120294 0.056094 -0.0290053 0.0018000 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 11 39105 0.117394 0.053894 -0.0294892 0.0017900 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 12 39106 0.114494 0.051694 -0.0300331 0.0019040 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 13 39107 0.111595 0.049595 -0.0307331 0.0021010 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 14 39108 0.108695 0.047495 -0.0316470 0.0023160 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 15 39109 0.105695 0.045495 -0.0327549 0.0024770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 16 39110 0.102695 0.043495 -0.0339698 0.0025440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 17 39111 0.099796 0.041496 -0.0352168 0.0025120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 18 39112 0.096796 0.039596 -0.0363817 0.0023940 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 19 39113 0.093796 0.037696 -0.0373936 0.0022110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 20 39114 0.090797 0.035897 -0.0382055 0.0020220 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 21 39115 0.087697 0.034097 -0.0388525 0.0018470 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 22 39116 0.084697 0.032397 -0.0393354 0.0017180 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 23 39117 0.081697 0.030697 -0.0397103 0.0016440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 24 39118 0.078698 0.029098 -0.0400582 0.0016530 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 25 39119 0.075698 0.027598 -0.0404491 0.0017410 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 26 39120 0.072698 0.026098 -0.0409691 0.0018860 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 27 39121 0.069798 0.024698 -0.0416350 0.0020490 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 28 39122 0.066799 0.023399 -0.0424829 0.0022260 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 29 39123 0.063899 0.022099 -0.0434948 0.0023950 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 30 39124 0.060999 0.020899 -0.0446628 0.0025260 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1965 12 31 39125 0.058100 0.019800 -0.0459337 0.0026050 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 1 39126 0.055200 0.018800 -0.0472656 0.0026390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 2 39127 0.052400 0.017900 -0.0472975 0.0025960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 3 39128 0.049600 0.017000 -0.0472524 0.0024830 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 4 39129 0.046801 0.016201 -0.0470674 0.0023100 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 5 39130 0.044101 0.015501 -0.0466903 0.0021390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 6 39131 0.041301 0.014901 -0.0461732 0.0020210 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 7 39132 0.038602 0.014302 -0.0455791 0.0020120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 8 39133 0.036002 0.013902 -0.0450500 0.0021320 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 9 39134 0.033302 0.013502 -0.0446960 0.0023620 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 10 39135 0.030702 0.013102 -0.0445859 0.0026160 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 11 39136 0.028103 0.012903 -0.0447328 0.0028340 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 12 39137 0.025503 0.012703 -0.0450377 0.0029360 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 13 39138 0.023003 0.012603 -0.0453816 0.0029220 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 14 39139 0.020403 0.012503 -0.0456636 0.0027970 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 15 39140 0.017904 0.012504 -0.0457715 0.0025910 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 16 39141 0.015404 0.012604 -0.0456584 0.0023710 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 17 39142 0.012904 0.012704 -0.0453303 0.0021670 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 18 39143 0.010505 0.012805 -0.0448272 0.0020080 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 19 39144 0.008005 0.013005 -0.0441862 0.0019110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 20 39145 0.005605 0.013305 -0.0434841 0.0018860 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 21 39146 0.003105 0.013605 -0.0427900 0.0019280 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 22 39147 0.000706 0.013906 -0.0421799 0.0020300 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 23 39148 -0.001694 0.014206 -0.0416848 0.0021750 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 24 39149 -0.004094 0.014606 -0.0413557 0.0023390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 25 39150 -0.006494 0.015006 -0.0411807 0.0024980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 26 39151 -0.008993 0.015407 -0.0411616 0.0026400 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 27 39152 -0.011393 0.015907 -0.0412555 0.0027290 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 28 39153 -0.013793 0.016407 -0.0414214 0.0027750 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 29 39154 -0.016292 0.016908 -0.0416053 0.0027730 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 30 39155 -0.018692 0.017408 -0.0417583 0.0027030 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 1 31 39156 -0.021192 0.017908 -0.0418152 0.0025830 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 1 39157 -0.023592 0.018508 -0.0417281 0.0024320 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 2 39158 -0.026091 0.019009 -0.0414980 0.0023070 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 3 39159 -0.028591 0.019609 -0.0411809 0.0022580 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 4 39160 -0.031091 0.020209 -0.0408748 0.0023350 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 5 39161 -0.033591 0.020909 -0.0407128 0.0025490 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 6 39162 -0.036090 0.021510 -0.0407977 0.0028280 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 7 39163 -0.038690 0.022210 -0.0411746 0.0030970 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 8 39164 -0.041190 0.022910 -0.0417695 0.0032600 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 9 39165 -0.043789 0.023611 -0.0424654 0.0032890 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 10 39166 -0.046289 0.024411 -0.0431173 0.0031730 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 11 39167 -0.048889 0.025111 -0.0435872 0.0029450 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 12 39168 -0.051489 0.025911 -0.0438132 0.0026760 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 13 39169 -0.053988 0.026712 -0.0437631 0.0024190 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 14 39170 -0.056588 0.027512 -0.0434790 0.0022130 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 15 39171 -0.059188 0.028312 -0.0430219 0.0020660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 16 39172 -0.061688 0.029212 -0.0424558 0.0019930 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 17 39173 -0.064187 0.030113 -0.0418527 0.0019920 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 18 39174 -0.066687 0.031013 -0.0412697 0.0020320 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 19 39175 -0.069187 0.031913 -0.0407526 0.0021290 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 20 39176 -0.071686 0.032814 -0.0403465 0.0022620 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 21 39177 -0.074086 0.033714 -0.0400874 0.0023870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 22 39178 -0.076486 0.034714 -0.0399423 0.0025070 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 23 39179 -0.078786 0.035714 -0.0398872 0.0025640 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 24 39180 -0.081185 0.036715 -0.0398701 0.0025830 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 25 39181 -0.083485 0.037715 -0.0398430 0.0025410 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 26 39182 -0.085685 0.038715 -0.0397540 0.0024530 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 27 39183 -0.087885 0.039815 -0.0395519 0.0023290 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 2 28 39184 -0.090084 0.040816 -0.0392028 0.0021920 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 1 39185 -0.092184 0.041916 -0.0387397 0.0020680 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 2 39186 -0.094284 0.043016 -0.0381796 0.0020060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 3 39187 -0.096383 0.044217 -0.0375985 0.0020530 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 4 39188 -0.098383 0.045317 -0.0371384 0.0022300 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 5 39189 -0.100283 0.046517 -0.0369144 0.0025260 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 6 39190 -0.102183 0.047717 -0.0370243 0.0028620 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 7 39191 -0.104082 0.049018 -0.0374522 0.0031470 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 8 39192 -0.105882 0.050218 -0.0380931 0.0033000 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 9 39193 -0.107682 0.051518 -0.0388050 0.0032870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 10 39194 -0.109382 0.052918 -0.0394289 0.0031310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 11 39195 -0.111081 0.054219 -0.0398578 0.0028910 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 12 39196 -0.112781 0.055619 -0.0400267 0.0026390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 13 39197 -0.114381 0.057019 -0.0399596 0.0024100 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 14 39198 -0.115980 0.058420 -0.0397016 0.0022660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 15 39199 -0.117480 0.059920 -0.0393305 0.0021860 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 16 39200 -0.118980 0.061420 -0.0389094 0.0021840 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 17 39201 -0.120480 0.063020 -0.0385313 0.0022610 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 18 39202 -0.121879 0.064521 -0.0382572 0.0023790 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 19 39203 -0.123279 0.066121 -0.0381291 0.0025390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 20 39204 -0.124679 0.067821 -0.0381580 0.0026980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 21 39205 -0.126079 0.069521 -0.0383499 0.0028510 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 22 39206 -0.127478 0.071222 -0.0386658 0.0029640 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 23 39207 -0.128778 0.072922 -0.0390578 0.0030090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 24 39208 -0.130078 0.074722 -0.0394807 0.0029970 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 25 39209 -0.131377 0.076523 -0.0398586 0.0029290 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 26 39210 -0.132677 0.078423 -0.0401325 0.0028010 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 27 39211 -0.133977 0.080323 -0.0402724 0.0026470 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 28 39212 -0.135277 0.082223 -0.0402493 0.0025020 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 29 39213 -0.136576 0.084224 -0.0401132 0.0024070 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 30 39214 -0.137876 0.086224 -0.0399131 0.0024010 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 3 31 39215 -0.139176 0.088224 -0.0397550 0.0025040 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 1 39216 -0.140375 0.090225 -0.0397789 0.0027320 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 2 39217 -0.141675 0.092325 -0.0400538 0.0030250 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 3 39218 -0.142975 0.094425 -0.0406388 0.0033170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 4 39219 -0.144175 0.096525 -0.0414887 0.0035220 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 5 39220 -0.145474 0.098626 -0.0424526 0.0035780 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 6 39221 -0.146674 0.100826 -0.0433985 0.0034700 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 7 39222 -0.147874 0.102926 -0.0441794 0.0032460 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 8 39223 -0.149074 0.105126 -0.0446923 0.0029670 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 9 39224 -0.150273 0.107327 -0.0449192 0.0027040 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 10 39225 -0.151473 0.109427 -0.0449321 0.0025070 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 11 39226 -0.152573 0.111627 -0.0447820 0.0023980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 12 39227 -0.153672 0.113828 -0.0445679 0.0023780 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 13 39228 -0.154772 0.116028 -0.0443738 0.0024350 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 14 39229 -0.155772 0.118128 -0.0442667 0.0025500 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 15 39230 -0.156772 0.120328 -0.0443066 0.0027140 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 16 39231 -0.157771 0.122429 -0.0445095 0.0028730 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 17 39232 -0.158771 0.124529 -0.0448795 0.0030340 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 18 39233 -0.159571 0.126729 -0.0453774 0.0031540 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 19 39234 -0.160471 0.128829 -0.0459803 0.0032120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 20 39235 -0.161270 0.130830 -0.0465982 0.0032040 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 21 39236 -0.161970 0.132930 -0.0471831 0.0031240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 22 39237 -0.162670 0.134930 -0.0476450 0.0029910 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 23 39238 -0.163269 0.137031 -0.0479519 0.0028100 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 24 39239 -0.163769 0.138931 -0.0480748 0.0026200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 25 39240 -0.164269 0.140931 -0.0480247 0.0024720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 26 39241 -0.164669 0.142931 -0.0478666 0.0024170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 27 39242 -0.165068 0.144832 -0.0477145 0.0024690 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 28 39243 -0.165368 0.146732 -0.0476714 0.0026400 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 29 39244 -0.165668 0.148632 -0.0478323 0.0028830 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 4 30 39245 -0.165768 0.150432 -0.0482652 0.0031610 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 1 39246 -0.165867 0.152233 -0.0489601 0.0033950 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 2 39247 -0.165967 0.154033 -0.0498270 0.0035060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 3 39248 -0.165967 0.155833 -0.0507429 0.0034800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 4 39249 -0.165866 0.157634 -0.0515498 0.0033140 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 5 39250 -0.165766 0.159334 -0.0521497 0.0030570 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 6 39251 -0.165566 0.161034 -0.0524656 0.0027680 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 7 39252 -0.165366 0.162734 -0.0525196 0.0025210 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 8 39253 -0.165065 0.164435 -0.0523545 0.0023530 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 9 39254 -0.164665 0.166035 -0.0520774 0.0022790 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 10 39255 -0.164265 0.167735 -0.0517613 0.0022910 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 11 39256 -0.163765 0.169335 -0.0514922 0.0023600 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 12 39257 -0.163264 0.171036 -0.0513161 0.0024750 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 13 39258 -0.162664 0.172636 -0.0512580 0.0026110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 14 39259 -0.162064 0.174236 -0.0513469 0.0027350 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 15 39260 -0.161463 0.175937 -0.0515298 0.0028250 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 16 39261 -0.160663 0.177537 -0.0518027 0.0028920 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 17 39262 -0.159963 0.179237 -0.0521036 0.0028890 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 18 39263 -0.159163 0.180837 -0.0523685 0.0028190 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 19 39264 -0.158362 0.182538 -0.0525374 0.0026790 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 20 39265 -0.157462 0.184238 -0.0525193 0.0024770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 21 39266 -0.156562 0.186038 -0.0523062 0.0022780 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 22 39267 -0.155662 0.187738 -0.0518941 0.0020980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 23 39268 -0.154661 0.189539 -0.0513370 0.0019950 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 24 39269 -0.153661 0.191339 -0.0507399 0.0020090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 25 39270 -0.152661 0.193139 -0.0502118 0.0021330 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 26 39271 -0.151660 0.195040 -0.0498537 0.0023390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 27 39272 -0.150560 0.196940 -0.0497096 0.0025640 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 28 39273 -0.149460 0.198940 -0.0497915 0.0027690 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 29 39274 -0.148360 0.200940 -0.0500394 0.0028870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 30 39275 -0.147259 0.202941 -0.0503433 0.0028810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 5 31 39276 -0.146159 0.204941 -0.0505772 0.0027470 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 1 39277 -0.145059 0.207041 -0.0506241 0.0025140 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 2 39278 -0.143859 0.209241 -0.0504090 0.0022350 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 3 39279 -0.142758 0.211442 -0.0499289 0.0019710 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 4 39280 -0.141658 0.213642 -0.0491928 0.0017690 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 5 39281 -0.140458 0.215942 -0.0483057 0.0016640 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 6 39282 -0.139357 0.218243 -0.0473596 0.0016380 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 7 39283 -0.138157 0.220543 -0.0464365 0.0017080 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 8 39284 -0.137057 0.222943 -0.0456024 0.0018210 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 9 39285 -0.135857 0.225343 -0.0449083 0.0019730 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 10 39286 -0.134756 0.227744 -0.0443692 0.0021280 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 11 39287 -0.133556 0.230244 -0.0439771 0.0022630 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 12 39288 -0.132456 0.232744 -0.0436930 0.0023610 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 13 39289 -0.131256 0.235244 -0.0434809 0.0024060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 14 39290 -0.130155 0.237745 -0.0433048 0.0024010 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 15 39291 -0.129055 0.240345 -0.0430717 0.0023120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 16 39292 -0.127855 0.242845 -0.0427286 0.0021740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 17 39293 -0.126754 0.245446 -0.0422175 0.0019920 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 18 39294 -0.125554 0.248046 -0.0415244 0.0018180 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 19 39295 -0.124454 0.250546 -0.0406833 0.0016950 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 20 39296 -0.123254 0.253146 -0.0397702 0.0016780 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 21 39297 -0.122153 0.255647 -0.0389001 0.0017820 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 22 39298 -0.120953 0.258247 -0.0381850 0.0019810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 23 39299 -0.119753 0.260747 -0.0376959 0.0022110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 24 39300 -0.118652 0.263148 -0.0374168 0.0024100 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 25 39301 -0.117452 0.265648 -0.0373057 0.0025310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 26 39302 -0.116252 0.268048 -0.0372476 0.0025310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 27 39303 -0.115052 0.270448 -0.0371385 0.0024110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 28 39304 -0.113851 0.272749 -0.0368474 0.0021960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 29 39305 -0.112551 0.275049 -0.0363342 0.0019430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 6 30 39306 -0.111351 0.277349 -0.0355551 0.0016830 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 1 39307 -0.110151 0.279549 -0.0345360 0.0014810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 2 39308 -0.108850 0.281650 -0.0333529 0.0013460 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 3 39309 -0.107550 0.283750 -0.0320668 0.0012870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 4 39310 -0.106250 0.285850 -0.0307727 0.0013170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 5 39311 -0.104949 0.287851 -0.0295406 0.0014070 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 6 39312 -0.103649 0.289751 -0.0284195 0.0015330 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 7 39313 -0.102249 0.291651 -0.0274204 0.0016590 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 8 39314 -0.100949 0.293451 -0.0265513 0.0017690 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 9 39315 -0.099548 0.295152 -0.0257662 0.0018430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 10 39316 -0.098148 0.296852 -0.0250311 0.0018780 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 11 39317 -0.096748 0.298452 -0.0243130 0.0018570 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 12 39318 -0.095348 0.300052 -0.0235459 0.0017890 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 13 39319 -0.093847 0.301553 -0.0226818 0.0016670 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 14 39320 -0.092447 0.303053 -0.0216747 0.0015040 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 15 39321 -0.090947 0.304453 -0.0204966 0.0013310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 16 39322 -0.089546 0.305754 -0.0191785 0.0012040 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 17 39323 -0.088046 0.307154 -0.0177544 0.0011680 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 18 39324 -0.086546 0.308354 -0.0163753 0.0012670 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 19 39325 -0.085046 0.309554 -0.0151391 0.0014770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 20 39326 -0.083445 0.310755 -0.0141720 0.0017660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 21 39327 -0.081945 0.311955 -0.0134869 0.0020450 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 22 39328 -0.080345 0.313055 -0.0130508 0.0022340 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 23 39329 -0.078845 0.314055 -0.0127287 0.0022860 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 24 39330 -0.077244 0.315156 -0.0123956 0.0022080 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 25 39331 -0.075744 0.316156 -0.0119185 0.0020140 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 26 39332 -0.074144 0.317056 -0.0112254 0.0017780 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 27 39333 -0.072543 0.318057 -0.0102953 0.0015460 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 28 39334 -0.070943 0.318957 -0.0091642 0.0013830 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 29 39335 -0.069343 0.319857 -0.0078951 0.0012830 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 30 39336 -0.067643 0.320757 -0.0065580 0.0012580 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 7 31 39337 -0.066042 0.321658 -0.0052469 0.0013120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 1 39338 -0.064442 0.322458 -0.0040228 0.0014290 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 2 39339 -0.062742 0.323258 -0.0029396 0.0015890 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 3 39340 -0.061142 0.324058 -0.0020155 0.0017540 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 4 39341 -0.059441 0.324859 -0.0012634 0.0019190 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 5 39342 -0.057741 0.325659 -0.0006523 0.0020510 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 6 39343 -0.056141 0.326359 -0.0001492 0.0021240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 7 39344 -0.054440 0.327160 0.0002999 0.0021500 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 8 39345 -0.052740 0.327860 0.0007500 0.0021200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 9 39346 -0.051040 0.328560 0.0012671 0.0020300 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 10 39347 -0.049340 0.329160 0.0018832 0.0019130 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 11 39348 -0.047639 0.329861 0.0026273 0.0017780 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 12 39349 -0.045939 0.330461 0.0035114 0.0016610 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 13 39350 -0.044239 0.331061 0.0044726 0.0016000 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 14 39351 -0.042539 0.331561 0.0054427 0.0016610 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 15 39352 -0.040838 0.332162 0.0062848 0.0018550 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 16 39353 -0.039138 0.332662 0.0068869 0.0021550 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 17 39354 -0.037438 0.333162 0.0071550 0.0024780 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 18 39355 -0.035737 0.333563 0.0071321 0.0027400 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 19 39356 -0.034037 0.334063 0.0069012 0.0028730 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 20 39357 -0.032337 0.334463 0.0066223 0.0028370 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 21 39358 -0.030637 0.334763 0.0064454 0.0026680 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 22 39359 -0.028936 0.335064 0.0065045 0.0024170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 23 39360 -0.027136 0.335364 0.0068037 0.0021590 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 24 39361 -0.025436 0.335564 0.0073488 0.0019410 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 25 39362 -0.023736 0.335764 0.0080629 0.0018060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 26 39363 -0.022035 0.335965 0.0088770 0.0017610 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 27 39364 -0.020335 0.336065 0.0097021 0.0017910 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 28 39365 -0.018635 0.336165 0.0104632 0.0018880 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 29 39366 -0.016934 0.336166 0.0111023 0.0020310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 30 39367 -0.015234 0.336166 0.0115844 0.0021850 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 8 31 39368 -0.013434 0.336066 0.0119025 0.0023460 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 1 39369 -0.011734 0.335966 0.0120817 0.0024690 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 2 39370 -0.010033 0.335867 0.0121718 0.0025430 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 3 39371 -0.008233 0.335667 0.0122069 0.0025580 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 4 39372 -0.006533 0.335467 0.0122560 0.0025220 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 5 39373 -0.004733 0.335167 0.0123691 0.0024240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 6 39374 -0.003032 0.334868 0.0125902 0.0022990 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 7 39375 -0.001232 0.334468 0.0129573 0.0021570 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 8 39376 0.000568 0.334068 0.0134634 0.0020250 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 9 39377 0.002369 0.333569 0.0140816 0.0019410 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 10 39378 0.004169 0.333069 0.0147407 0.0019480 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 11 39379 0.005969 0.332569 0.0153248 0.0020770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 12 39380 0.007869 0.331969 0.0157249 0.0023400 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 13 39381 0.009670 0.331370 0.0158170 0.0026720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 14 39382 0.011570 0.330670 0.0155641 0.0029950 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 15 39383 0.013470 0.329970 0.0150322 0.0032250 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 16 39384 0.015271 0.329271 0.0143624 0.0032740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 17 39385 0.017171 0.328471 0.0137245 0.0031540 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 18 39386 0.019171 0.327671 0.0132896 0.0028920 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 19 39387 0.021071 0.326771 0.0131367 0.0025930 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 20 39388 0.022972 0.325972 0.0132728 0.0023250 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 21 39389 0.024972 0.324972 0.0136489 0.0021310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 22 39390 0.026972 0.324072 0.0141560 0.0020520 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 23 39391 0.028872 0.323072 0.0146932 0.0020680 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 24 39392 0.030873 0.322073 0.0151833 0.0021620 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 25 39393 0.032873 0.320973 0.0155424 0.0023080 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 26 39394 0.034873 0.319873 0.0157395 0.0024810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 27 39395 0.036874 0.318774 0.0157596 0.0026660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 28 39396 0.038874 0.317674 0.0156147 0.0028090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 29 39397 0.040874 0.316474 0.0153358 0.0029190 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 9 30 39398 0.042874 0.315274 0.0149770 0.0029700 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 1 39399 0.044875 0.314075 0.0146071 0.0029570 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 2 39400 0.046875 0.312775 0.0142732 0.0028730 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 3 39401 0.048875 0.311575 0.0140553 0.0027450 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 4 39402 0.050775 0.310175 0.0139804 0.0025850 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 5 39403 0.052776 0.308876 0.0140735 0.0024330 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 6 39404 0.054676 0.307576 0.0143007 0.0023020 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 7 39405 0.056676 0.306176 0.0146348 0.0022460 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 8 39406 0.058577 0.304777 0.0149629 0.0023060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 9 39407 0.060477 0.303277 0.0151630 0.0024840 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 10 39408 0.062377 0.301877 0.0151421 0.0027600 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 11 39409 0.064177 0.300377 0.0148102 0.0030740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 12 39410 0.066078 0.298878 0.0141914 0.0033380 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 13 39411 0.067878 0.297278 0.0133595 0.0034790 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 14 39412 0.069578 0.295778 0.0124636 0.0034510 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 15 39413 0.071378 0.294178 0.0117037 0.0032470 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 16 39414 0.073079 0.292579 0.0111848 0.0029610 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 17 39415 0.074779 0.290979 0.0109669 0.0026610 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 18 39416 0.076379 0.289279 0.0110311 0.0024150 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 19 39417 0.077980 0.287580 0.0112912 0.0022740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 20 39418 0.079580 0.285880 0.0116353 0.0022440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 21 39419 0.081080 0.284180 0.0119634 0.0023050 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 22 39420 0.082580 0.282380 0.0121855 0.0024390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 23 39421 0.084081 0.280581 0.0122647 0.0025970 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 24 39422 0.085481 0.278781 0.0121778 0.0027650 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 25 39423 0.086881 0.276981 0.0119309 0.0029060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 26 39424 0.088181 0.275081 0.0115490 0.0030200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 27 39425 0.089582 0.273282 0.0110981 0.0030710 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 28 39426 0.090782 0.271282 0.0106082 0.0030680 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 29 39427 0.092082 0.269382 0.0101634 0.0029910 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 30 39428 0.093383 0.267383 0.0098245 0.0028700 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 10 31 39429 0.094583 0.265383 0.0096156 0.0027160 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 1 39430 0.095783 0.263383 0.0095847 0.0025500 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 2 39431 0.096983 0.261383 0.0096948 0.0024290 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 3 39432 0.098084 0.259284 0.0098940 0.0023670 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 4 39433 0.099284 0.257184 0.0100971 0.0024130 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 5 39434 0.100384 0.255084 0.0102112 0.0025660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 6 39435 0.101584 0.252884 0.0101233 0.0028140 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 7 39436 0.102685 0.250785 0.0097554 0.0031060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 8 39437 0.103785 0.248585 0.0090946 0.0033870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 9 39438 0.104885 0.246385 0.0081907 0.0035810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 10 39439 0.105986 0.244186 0.0071708 0.0036200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 11 39440 0.107086 0.241986 0.0061959 0.0034950 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 12 39441 0.108186 0.239786 0.0054160 0.0032390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 13 39442 0.109286 0.237586 0.0049182 0.0029230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 14 39443 0.110287 0.235287 0.0047423 0.0026300 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 15 39444 0.111387 0.233087 0.0048194 0.0024130 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 16 39445 0.112487 0.230787 0.0050695 0.0023070 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 17 39446 0.113487 0.228587 0.0053697 0.0023060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 18 39447 0.114488 0.226388 0.0056108 0.0023930 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 19 39448 0.115488 0.224188 0.0057589 0.0025150 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 20 39449 0.116488 0.221988 0.0057660 0.0026610 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 21 39450 0.117489 0.219789 0.0056201 0.0027980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 22 39451 0.118389 0.217589 0.0053613 0.0028920 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 23 39452 0.119289 0.215389 0.0050224 0.0029480 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 24 39453 0.120189 0.213289 0.0046755 0.0029360 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 25 39454 0.120990 0.211190 0.0043626 0.0028510 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 26 39455 0.121790 0.209090 0.0041728 0.0027190 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 27 39456 0.122590 0.206990 0.0041389 0.0025450 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 28 39457 0.123290 0.204990 0.0042790 0.0023540 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 29 39458 0.123991 0.202991 0.0046021 0.0021860 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 11 30 39459 0.124591 0.201091 0.0050662 0.0020800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 1 39460 0.125091 0.199191 0.0056014 0.0020680 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 2 39461 0.125592 0.197292 0.0060735 0.0021750 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 3 39462 0.125992 0.195492 0.0063906 0.0023740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 4 39463 0.126292 0.193792 0.0064877 0.0026380 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 5 39464 0.126592 0.192092 0.0063069 0.0028980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 6 39465 0.126693 0.190493 0.0058930 0.0030940 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 7 39466 0.126793 0.188893 0.0053481 0.0031740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 8 39467 0.126793 0.187293 0.0047822 0.0031240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 9 39468 0.126694 0.185894 0.0043324 0.0029470 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 10 39469 0.126494 0.184494 0.0041055 0.0027010 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 11 39470 0.126194 0.183094 0.0041146 0.0024550 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 12 39471 0.125894 0.181794 0.0043667 0.0022350 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 13 39472 0.125395 0.180595 0.0047919 0.0021140 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 14 39473 0.124795 0.179395 0.0052840 0.0021000 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 15 39474 0.124095 0.178295 0.0057531 0.0021650 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 16 39475 0.123395 0.177295 0.0061162 0.0022880 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 17 39476 0.122496 0.176296 0.0063514 0.0024240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 18 39477 0.121596 0.175296 0.0064495 0.0025550 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 19 39478 0.120496 0.174396 0.0064306 0.0026580 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 20 39479 0.119397 0.173497 0.0063297 0.0027040 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 21 39480 0.118097 0.172697 0.0062199 0.0026960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 22 39481 0.116797 0.171897 0.0061480 0.0026290 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 23 39482 0.115397 0.171097 0.0061711 0.0024970 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 24 39483 0.113998 0.170398 0.0063502 0.0023300 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 25 39484 0.112398 0.169698 0.0067094 0.0021190 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 26 39485 0.110798 0.169098 0.0072815 0.0019230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 27 39486 0.109098 0.168498 0.0080286 0.0017740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 28 39487 0.107399 0.167899 0.0088837 0.0017240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 29 39488 0.105599 0.167299 0.0097229 0.0017870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 30 39489 0.103699 0.166699 0.0104540 0.0019560 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1966 12 31 39490 0.101800 0.166200 0.0109891 0.0021800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 1 39491 0.099900 0.165700 0.0112652 0.0024240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 2 39492 0.097900 0.165200 0.0113344 0.0026120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 3 39493 0.095900 0.164700 0.0112605 0.0026950 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 4 39494 0.093901 0.164301 0.0111796 0.0026440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 5 39495 0.091901 0.163801 0.0112018 0.0024840 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 6 39496 0.089801 0.163401 0.0114269 0.0022380 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 7 39497 0.087801 0.163001 0.0119130 0.0019930 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 8 39498 0.085702 0.162502 0.0126181 0.0017770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 9 39499 0.083602 0.162102 0.0135003 0.0016650 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 10 39500 0.081602 0.161702 0.0144434 0.0016540 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 11 39501 0.079503 0.161303 0.0153395 0.0017280 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 12 39502 0.077403 0.160903 0.0161347 0.0018800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 13 39503 0.075403 0.160503 0.0167578 0.0020570 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 14 39504 0.073403 0.160103 0.0172009 0.0022450 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 15 39505 0.071404 0.159704 0.0174460 0.0024080 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 16 39506 0.069404 0.159304 0.0175692 0.0025270 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 17 39507 0.067504 0.158904 0.0176013 0.0025790 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 18 39508 0.065604 0.158504 0.0176204 0.0025730 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 19 39509 0.063705 0.158105 0.0176636 0.0025120 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 20 39510 0.061905 0.157705 0.0177997 0.0023990 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 21 39511 0.060105 0.157305 0.0180558 0.0022680 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 22 39512 0.058406 0.157006 0.0184559 0.0021230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 23 39513 0.056706 0.156606 0.0189891 0.0020090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 24 39514 0.055006 0.156206 0.0196032 0.0019680 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 25 39515 0.053406 0.155906 0.0202063 0.0020260 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 26 39516 0.051807 0.155507 0.0206895 0.0022160 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 27 39517 0.050307 0.155207 0.0209326 0.0024790 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 28 39518 0.048807 0.154807 0.0208927 0.0027790 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 29 39519 0.047407 0.154507 0.0205849 0.0030010 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 30 39520 0.046008 0.154208 0.0201230 0.0030990 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 1 31 39521 0.044708 0.153908 0.0196301 0.0030520 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 1 39522 0.043408 0.153608 0.0192562 0.0028670 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 2 39523 0.042209 0.153309 0.0191154 0.0026060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 3 39524 0.041009 0.153009 0.0192405 0.0023140 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 4 39525 0.039909 0.152709 0.0196636 0.0020610 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 5 39526 0.038809 0.152409 0.0202818 0.0018990 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 6 39527 0.037710 0.152110 0.0210029 0.0018460 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 7 39528 0.036710 0.151910 0.0217270 0.0019000 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 8 39529 0.035810 0.151610 0.0223682 0.0020280 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 9 39530 0.034810 0.151310 0.0228463 0.0022110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 10 39531 0.033911 0.151111 0.0231324 0.0023950 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 11 39532 0.033111 0.150811 0.0232316 0.0025720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 12 39533 0.032211 0.150611 0.0231837 0.0027060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 13 39534 0.031412 0.150312 0.0230288 0.0027930 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 14 39535 0.030712 0.150112 0.0227979 0.0028180 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 15 39536 0.029912 0.149812 0.0225831 0.0027750 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 16 39537 0.029212 0.149612 0.0224442 0.0026860 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 17 39538 0.028513 0.149313 0.0224013 0.0025680 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 18 39539 0.027913 0.149013 0.0224905 0.0024440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 19 39540 0.027213 0.148813 0.0226776 0.0023390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 20 39541 0.026613 0.148513 0.0229637 0.0022800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 21 39542 0.026014 0.148214 0.0232769 0.0023040 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 22 39543 0.025414 0.147914 0.0234940 0.0024520 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 23 39544 0.024914 0.147614 0.0235131 0.0026980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 24 39545 0.024315 0.147315 0.0232553 0.0030230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 25 39546 0.023715 0.146915 0.0226624 0.0033230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 26 39547 0.023215 0.146615 0.0218165 0.0035230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 27 39548 0.022715 0.146215 0.0208627 0.0035440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 2 28 39549 0.022216 0.145916 0.0199778 0.0033800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 1 39550 0.021616 0.145516 0.0193259 0.0031000 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 2 39551 0.021116 0.145116 0.0189841 0.0027720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 3 39552 0.020617 0.144717 0.0189602 0.0024770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 4 39553 0.020117 0.144317 0.0191813 0.0022670 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 5 39554 0.019617 0.143917 0.0195705 0.0021640 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 6 39555 0.019217 0.143417 0.0199986 0.0021650 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 7 39556 0.018718 0.143018 0.0203937 0.0022570 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 8 39557 0.018218 0.142618 0.0206579 0.0023910 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 9 39558 0.017718 0.142218 0.0207760 0.0025550 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 10 39559 0.017318 0.141718 0.0207311 0.0027200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 11 39560 0.016819 0.141319 0.0205373 0.0028400 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 12 39561 0.016319 0.140919 0.0202394 0.0029160 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 13 39562 0.015819 0.140519 0.0199176 0.0029170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 14 39563 0.015420 0.140120 0.0196167 0.0028550 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 15 39564 0.014920 0.139720 0.0194168 0.0027400 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 16 39565 0.014420 0.139420 0.0193490 0.0025810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 17 39566 0.013920 0.139020 0.0194281 0.0024320 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 18 39567 0.013421 0.138721 0.0196702 0.0022870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 19 39568 0.012921 0.138421 0.0200284 0.0021970 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 20 39569 0.012421 0.138221 0.0204425 0.0021720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 21 39570 0.011921 0.137921 0.0208286 0.0022660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 22 39571 0.011422 0.137722 0.0210608 0.0024810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 23 39572 0.010922 0.137622 0.0210219 0.0027980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 24 39573 0.010422 0.137522 0.0206420 0.0031510 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 25 39574 0.009923 0.137423 0.0199192 0.0034470 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 26 39575 0.009323 0.137423 0.0189683 0.0036060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 27 39576 0.008823 0.137423 0.0179635 0.0035630 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 28 39577 0.008223 0.137423 0.0170916 0.0033460 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 29 39578 0.007724 0.137524 0.0164847 0.0030300 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 30 39579 0.007124 0.137724 0.0162039 0.0027200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 3 31 39580 0.006524 0.137924 0.0162100 0.0024840 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 1 39581 0.005924 0.138124 0.0163951 0.0023550 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 2 39582 0.005425 0.138425 0.0166503 0.0023440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 3 39583 0.004825 0.138725 0.0168674 0.0024260 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 4 39584 0.004225 0.139125 0.0169686 0.0025590 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 5 39585 0.003626 0.139426 0.0169107 0.0027290 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 6 39586 0.003026 0.139826 0.0166918 0.0028860 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 7 39587 0.002526 0.140226 0.0163290 0.0030350 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 8 39588 0.002026 0.140626 0.0158391 0.0031260 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 9 39589 0.001527 0.141127 0.0152872 0.0031660 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 10 39590 0.001027 0.141627 0.0147294 0.0031300 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 11 39591 0.000527 0.142127 0.0142475 0.0030250 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 12 39592 -0.000073 0.142627 0.0138737 0.0028890 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 13 39593 -0.000672 0.143128 0.0136568 0.0027340 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 14 39594 -0.001272 0.143628 0.0135919 0.0025790 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 15 39595 -0.001872 0.144128 0.0136671 0.0024520 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 16 39596 -0.002471 0.144629 0.0138372 0.0023910 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 17 39597 -0.003071 0.145129 0.0140253 0.0024310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 18 39598 -0.003671 0.145629 0.0141185 0.0025710 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 19 39599 -0.004271 0.146129 0.0140186 0.0028250 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 20 39600 -0.004870 0.146630 0.0136268 0.0031470 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 21 39601 -0.005470 0.147130 0.0129169 0.0034540 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 22 39602 -0.005970 0.147630 0.0119290 0.0036680 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 23 39603 -0.006470 0.148130 0.0108062 0.0037160 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 24 39604 -0.006969 0.148631 0.0097313 0.0035750 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 25 39605 -0.007369 0.149031 0.0088865 0.0032870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 26 39606 -0.007669 0.149431 0.0083586 0.0029480 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 27 39607 -0.007968 0.149832 0.0081687 0.0026350 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 28 39608 -0.008268 0.150232 0.0082329 0.0024390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 29 39609 -0.008568 0.150632 0.0084380 0.0023620 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 4 30 39610 -0.008768 0.151032 0.0086512 0.0024090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 1 39611 -0.008967 0.151433 0.0087763 0.0025300 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 2 39612 -0.009167 0.151833 0.0087594 0.0026870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 3 39613 -0.009367 0.152133 0.0085926 0.0028450 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 4 39614 -0.009467 0.152433 0.0082677 0.0029790 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 5 39615 -0.009566 0.152734 0.0078299 0.0030690 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 6 39616 -0.009666 0.153034 0.0073290 0.0031030 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 7 39617 -0.009766 0.153334 0.0068251 0.0030640 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 8 39618 -0.009765 0.153635 0.0064013 0.0029640 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 9 39619 -0.009765 0.153935 0.0061024 0.0028070 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 10 39620 -0.009665 0.154235 0.0059776 0.0026320 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 11 39621 -0.009665 0.154535 0.0060287 0.0024480 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 12 39622 -0.009564 0.154836 0.0062508 0.0022970 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 13 39623 -0.009364 0.155036 0.0066050 0.0022060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 14 39624 -0.009264 0.155336 0.0070091 0.0021910 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 15 39625 -0.009064 0.155436 0.0073803 0.0022740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 16 39626 -0.008863 0.155637 0.0076204 0.0024520 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 17 39627 -0.008663 0.155737 0.0076336 0.0027090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 18 39628 -0.008463 0.155937 0.0073847 0.0029770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 19 39629 -0.008162 0.156038 0.0068778 0.0032040 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 20 39630 -0.007962 0.156138 0.0061990 0.0033100 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 21 39631 -0.007662 0.156138 0.0055031 0.0032420 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 22 39632 -0.007362 0.156238 0.0049483 0.0030240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 23 39633 -0.007061 0.156339 0.0046704 0.0026930 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 24 39634 -0.006761 0.156339 0.0047366 0.0023600 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 25 39635 -0.006461 0.156439 0.0051067 0.0020990 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 26 39636 -0.006061 0.156539 0.0056878 0.0019510 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 27 39637 -0.005760 0.156640 0.0063420 0.0019400 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 28 39638 -0.005460 0.156740 0.0069661 0.0020160 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 29 39639 -0.005160 0.156840 0.0074843 0.0021420 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 30 39640 -0.004859 0.156941 0.0078694 0.0022760 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 5 31 39641 -0.004559 0.157141 0.0081396 0.0023790 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 1 39642 -0.004359 0.157341 0.0083067 0.0024480 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 2 39643 -0.004059 0.157541 0.0084418 0.0024630 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 3 39644 -0.003758 0.157742 0.0085920 0.0024070 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 4 39645 -0.003558 0.158042 0.0088381 0.0022910 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 5 39646 -0.003358 0.158242 0.0092173 0.0021350 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 6 39647 -0.003157 0.158643 0.0097704 0.0019360 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 7 39648 -0.002957 0.158943 0.0105176 0.0017400 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 8 39649 -0.002757 0.159343 0.0114637 0.0015560 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 9 39650 -0.002657 0.159743 0.0125788 0.0014270 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 10 39651 -0.002556 0.160144 0.0137630 0.0014010 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 11 39652 -0.002456 0.160644 0.0149241 0.0014740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 12 39653 -0.002356 0.161144 0.0159743 0.0016400 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 13 39654 -0.002256 0.161644 0.0168124 0.0018820 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 14 39655 -0.002255 0.162245 0.0173946 0.0021440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 15 39656 -0.002255 0.162745 0.0177177 0.0023690 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 16 39657 -0.002255 0.163345 0.0178589 0.0025090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 17 39658 -0.002254 0.163946 0.0179350 0.0025040 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 18 39659 -0.002354 0.164646 0.0180801 0.0023750 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 19 39660 -0.002454 0.165246 0.0184023 0.0021360 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 20 39661 -0.002554 0.165946 0.0190024 0.0018440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 21 39662 -0.002653 0.166647 0.0198826 0.0015870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 22 39663 -0.002753 0.167347 0.0209847 0.0014190 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 23 39664 -0.002953 0.168047 0.0221829 0.0013870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 24 39665 -0.003053 0.168847 0.0233530 0.0014580 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 25 39666 -0.003252 0.169548 0.0244242 0.0015990 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 26 39667 -0.003452 0.170348 0.0253283 0.0017630 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 27 39668 -0.003652 0.171048 0.0260845 0.0019100 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 28 39669 -0.003851 0.171849 0.0267126 0.0020050 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 29 39670 -0.004051 0.172649 0.0272747 0.0020520 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 6 30 39671 -0.004251 0.173349 0.0278189 0.0020280 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 1 39672 -0.004451 0.174149 0.0284190 0.0019530 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 2 39673 -0.004650 0.174950 0.0291102 0.0018280 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 3 39674 -0.004950 0.175650 0.0299563 0.0016670 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 4 39675 -0.005150 0.176450 0.0309615 0.0014920 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 5 39676 -0.005350 0.177150 0.0321476 0.0013300 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 6 39677 -0.005649 0.177851 0.0334668 0.0012230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 7 39678 -0.005849 0.178551 0.0348669 0.0011820 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 8 39679 -0.006049 0.179251 0.0362591 0.0012420 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 9 39680 -0.006348 0.179952 0.0375292 0.0014150 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 10 39681 -0.006548 0.180652 0.0385834 0.0016560 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 11 39682 -0.006748 0.181252 0.0393875 0.0019240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 12 39683 -0.006948 0.181952 0.0399287 0.0021630 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 13 39684 -0.007247 0.182553 0.0402848 0.0022860 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 14 39685 -0.007447 0.183153 0.0405710 0.0022880 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 15 39686 -0.007647 0.183653 0.0409341 0.0021550 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 16 39687 -0.007847 0.184153 0.0414762 0.0019280 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 17 39688 -0.008046 0.184754 0.0422844 0.0016420 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 18 39689 -0.008246 0.185154 0.0433655 0.0013750 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 19 39690 -0.008446 0.185654 0.0446877 0.0011870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 20 39691 -0.008645 0.186055 0.0461338 0.0011220 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 21 39692 -0.008845 0.186455 0.0475860 0.0011720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 22 39693 -0.008945 0.186855 0.0489411 0.0013090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 23 39694 -0.009145 0.187155 0.0501343 0.0014870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 24 39695 -0.009344 0.187456 0.0511484 0.0016710 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 25 39696 -0.009544 0.187756 0.0520056 0.0018070 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 26 39697 -0.009644 0.188056 0.0527447 0.0018940 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 27 39698 -0.009844 0.188256 0.0534299 0.0019150 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 28 39699 -0.009943 0.188557 0.0541260 0.0018720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 29 39700 -0.010143 0.188757 0.0548942 0.0017740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 30 39701 -0.010243 0.188857 0.0557813 0.0016390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 7 31 39702 -0.010342 0.189058 0.0568035 0.0014860 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 1 39703 -0.010542 0.189158 0.0579866 0.0013510 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 2 39704 -0.010642 0.189358 0.0592808 0.0012490 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 3 39705 -0.010742 0.189458 0.0606479 0.0012110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 4 39706 -0.010841 0.189559 0.0620181 0.0012570 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 5 39707 -0.010941 0.189559 0.0632762 0.0014240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 6 39708 -0.011141 0.189659 0.0643164 0.0016900 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 7 39709 -0.011241 0.189759 0.0650685 0.0019990 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 8 39710 -0.011340 0.189760 0.0655047 0.0022980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 9 39711 -0.011440 0.189760 0.0656938 0.0024920 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 10 39712 -0.011640 0.189760 0.0657510 0.0025490 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 11 39713 -0.011739 0.189761 0.0658381 0.0024420 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 12 39714 -0.011839 0.189761 0.0660863 0.0022270 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 13 39715 -0.012039 0.189761 0.0665814 0.0019580 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 14 39716 -0.012139 0.189761 0.0673546 0.0016950 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 15 39717 -0.012338 0.189762 0.0683577 0.0015060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 16 39718 -0.012438 0.189662 0.0694859 0.0014260 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 17 39719 -0.012638 0.189662 0.0706470 0.0014600 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 18 39720 -0.012838 0.189662 0.0717242 0.0015880 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 19 39721 -0.013137 0.189563 0.0726433 0.0017600 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 20 39722 -0.013337 0.189563 0.0733815 0.0019540 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 21 39723 -0.013637 0.189463 0.0739366 0.0021090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 22 39724 -0.013836 0.189364 0.0743608 0.0022100 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 23 39725 -0.014136 0.189364 0.0747189 0.0022530 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 24 39726 -0.014536 0.189264 0.0750691 0.0022160 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 25 39727 -0.014836 0.189164 0.0754882 0.0021170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 26 39728 -0.015235 0.189065 0.0760304 0.0019850 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 27 39729 -0.015635 0.189065 0.0767155 0.0018220 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 28 39730 -0.016035 0.188965 0.0775657 0.0016610 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 29 39731 -0.016434 0.188866 0.0785638 0.0015280 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 30 39732 -0.016934 0.188866 0.0796720 0.0014480 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 8 31 39733 -0.017334 0.188766 0.0808221 0.0014490 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 1 39734 -0.017834 0.188666 0.0819303 0.0015440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 2 39735 -0.018333 0.188567 0.0828874 0.0017490 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 3 39736 -0.018833 0.188567 0.0835826 0.0020500 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 4 39737 -0.019433 0.188467 0.0839707 0.0023720 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 5 39738 -0.019933 0.188367 0.0840619 0.0026180 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 6 39739 -0.020532 0.188368 0.0839531 0.0027300 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 7 39740 -0.021032 0.188268 0.0838422 0.0026530 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 8 39741 -0.021632 0.188268 0.0838804 0.0024390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 9 39742 -0.022131 0.188169 0.0841855 0.0021350 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 10 39743 -0.022731 0.188169 0.0847917 0.0018400 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 11 39744 -0.023231 0.188069 0.0856698 0.0016200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 12 39745 -0.023731 0.188069 0.0867040 0.0015150 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 13 39746 -0.024330 0.187970 0.0877701 0.0015420 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 14 39747 -0.024830 0.187970 0.0887763 0.0016590 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 15 39748 -0.025330 0.187870 0.0896104 0.0018500 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 16 39749 -0.025830 0.187870 0.0902486 0.0020730 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 17 39750 -0.026329 0.187871 0.0906497 0.0022800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 18 39751 -0.026829 0.187871 0.0908849 0.0024310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 19 39752 -0.027229 0.187871 0.0910000 0.0025170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 20 39753 -0.027728 0.187872 0.0910662 0.0025210 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 21 39754 -0.028128 0.187872 0.0911623 0.0024680 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 22 39755 -0.028528 0.187872 0.0913385 0.0023530 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 23 39756 -0.028928 0.187872 0.0916567 0.0021980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 24 39757 -0.029327 0.187973 0.0921248 0.0020490 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 25 39758 -0.029627 0.187973 0.0927310 0.0019140 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 26 39759 -0.030027 0.188073 0.0934601 0.0018160 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 27 39760 -0.030327 0.188173 0.0942563 0.0017970 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 28 39761 -0.030626 0.188274 0.0950264 0.0018590 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 29 39762 -0.030826 0.188374 0.0956836 0.0020260 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 9 30 39763 -0.031126 0.188574 0.0961217 0.0023030 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 1 39764 -0.031325 0.188675 0.0962479 0.0026200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 2 39765 -0.031625 0.188875 0.0960670 0.0029220 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 3 39766 -0.031825 0.189075 0.0956192 0.0031400 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 4 39767 -0.031925 0.189275 0.0950464 0.0031740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 5 39768 -0.032124 0.189576 0.0945255 0.0030180 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 6 39769 -0.032224 0.189776 0.0942277 0.0027310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 7 39770 -0.032324 0.190076 0.0942608 0.0023940 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 8 39771 -0.032424 0.190376 0.0946140 0.0021060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 9 39772 -0.032523 0.190677 0.0952001 0.0019340 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 10 39773 -0.032623 0.191077 0.0958803 0.0019090 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 11 39774 -0.032623 0.191377 0.0965224 0.0020030 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 12 39775 -0.032722 0.191778 0.0970296 0.0021810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 13 39776 -0.032722 0.192178 0.0973408 0.0023790 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 14 39777 -0.032722 0.192578 0.0974549 0.0025680 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 15 39778 -0.032722 0.192978 0.0973971 0.0027290 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 16 39779 -0.032721 0.193379 0.0972062 0.0028320 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 17 39780 -0.032621 0.193779 0.0969464 0.0028670 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 18 39781 -0.032621 0.194279 0.0966865 0.0028230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 19 39782 -0.032621 0.194679 0.0965007 0.0027210 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 20 39783 -0.032520 0.195180 0.0964388 0.0025800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 21 39784 -0.032520 0.195580 0.0965260 0.0024360 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 22 39785 -0.032420 0.196080 0.0967612 0.0022990 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 23 39786 -0.032319 0.196581 0.0971153 0.0021930 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 24 39787 -0.032219 0.196981 0.0975345 0.0021510 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 25 39788 -0.032119 0.197481 0.0979766 0.0021800 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 26 39789 -0.032119 0.197981 0.0983228 0.0023030 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 27 39790 -0.032018 0.198382 0.0985189 0.0025200 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 28 39791 -0.031918 0.198882 0.0984491 0.0028110 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 29 39792 -0.031718 0.199382 0.0980793 0.0031170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 30 39793 -0.031618 0.199782 0.0974114 0.0033820 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 10 31 39794 -0.031517 0.200283 0.0965386 0.0035060 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 1 39795 -0.031417 0.200683 0.0956507 0.0034390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 2 39796 -0.031317 0.201183 0.0948999 0.0032170 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 3 39797 -0.031116 0.201584 0.0944430 0.0028890 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 4 39798 -0.031016 0.202084 0.0943142 0.0025570 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 5 39799 -0.030816 0.202484 0.0944794 0.0023230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 6 39800 -0.030716 0.202884 0.0947995 0.0022310 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 7 39801 -0.030615 0.203385 0.0951517 0.0022770 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 8 39802 -0.030415 0.203785 0.0954048 0.0024100 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 9 39803 -0.030315 0.204185 0.0954870 0.0025970 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 10 39804 -0.030115 0.204585 0.0953931 0.0027790 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 11 39805 -0.030014 0.204986 0.0951223 0.0029240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 12 39806 -0.029814 0.205486 0.0947435 0.0030050 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 13 39807 -0.029714 0.205886 0.0943146 0.0030220 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 14 39808 -0.029513 0.206287 0.0939008 0.0029740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 15 39809 -0.029413 0.206787 0.0935659 0.0028570 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 16 39810 -0.029313 0.207187 0.0933821 0.0026960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 17 39811 -0.029113 0.207687 0.0933622 0.0025130 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 18 39812 -0.029012 0.208088 0.0935234 0.0023370 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 19 39813 -0.028912 0.208588 0.0938556 0.0021970 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 20 39814 -0.028812 0.209088 0.0943107 0.0020960 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 21 39815 -0.028711 0.209689 0.0948189 0.0020820 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 22 39816 -0.028611 0.210189 0.0952970 0.0021560 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 23 39817 -0.028511 0.210689 0.0956492 0.0023240 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 24 39818 -0.028411 0.211289 0.0958164 0.0025520 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 25 39819 -0.028410 0.211890 0.0957125 0.0028160 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 26 39820 -0.028310 0.212490 0.0953597 0.0030710 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 27 39821 -0.028310 0.213090 0.0947898 0.0032400 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 28 39822 -0.028310 0.213790 0.0941180 0.0032670 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 29 39823 -0.028209 0.214391 0.0934922 0.0031380 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 11 30 39824 -0.028209 0.215091 0.0930673 0.0028750 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 1 39825 -0.028209 0.215791 0.0929415 0.0025560 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 2 39826 -0.028308 0.216492 0.0931206 0.0022890 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 3 39827 -0.028308 0.217292 0.0935128 0.0021410 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 4 39828 -0.028308 0.217992 0.0939810 0.0021380 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 5 39829 -0.028408 0.218792 0.0943771 0.0022680 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 6 39830 -0.028407 0.219493 0.0946043 0.0024750 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 7 39831 -0.028507 0.220293 0.0946154 0.0026690 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 8 39832 -0.028607 0.221093 0.0944476 0.0028380 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 9 39833 -0.028607 0.221893 0.0941488 0.0029490 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 10 39834 -0.028706 0.222694 0.0937729 0.0029930 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 11 39835 -0.028806 0.223494 0.0933641 0.0029730 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 12 39836 -0.028806 0.224294 0.0930262 0.0028850 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 13 39837 -0.028905 0.225095 0.0927994 0.0027520 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 14 39838 -0.029005 0.225895 0.0927206 0.0025840 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 15 39839 -0.029005 0.226695 0.0928127 0.0024150 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 16 39840 -0.029105 0.227495 0.0930519 0.0022730 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 17 39841 -0.029104 0.228296 0.0934290 0.0021750 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 18 39842 -0.029104 0.228996 0.0938572 0.0021530 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 19 39843 -0.029104 0.229796 0.0942744 0.0022070 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 20 39844 -0.029104 0.230496 0.0945935 0.0023480 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 21 39845 -0.029103 0.231197 0.0947477 0.0025450 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 22 39846 -0.029003 0.231797 0.0946838 0.0027740 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 23 39847 -0.028903 0.232497 0.0943850 0.0029980 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 24 39848 -0.028802 0.233098 0.0939012 0.0031440 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 25 39849 -0.028702 0.233698 0.0933153 0.0031870 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 26 39850 -0.028602 0.234298 0.0927645 0.0030810 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 27 39851 -0.028402 0.234798 0.0923866 0.0028480 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 28 39852 -0.028201 0.235399 0.0922758 0.0025480 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 29 39853 -0.028001 0.235899 0.0924700 0.0022520 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 30 39854 -0.027701 0.236299 0.0929241 0.0020390 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1967 12 31 39855 -0.027401 0.236799 0.0935273 0.0019590 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000 1968 1 1 39856 -0.027100 0.237200 0.0941515 0.0020150 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 2 39857 -0.026700 0.237500 0.0946476 0.0021840 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 3 39858 -0.026400 0.237900 0.0949628 0.0023760 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 4 39859 -0.025999 0.238201 0.0950949 0.0025520 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 5 39860 -0.025599 0.238501 0.0950691 0.0026680 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 6 39861 -0.025099 0.238801 0.0949553 0.0027190 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 7 39862 -0.024699 0.239101 0.0948464 0.0026870 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 8 39863 -0.024198 0.239302 0.0947816 0.0026040 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 9 39864 -0.023698 0.239502 0.0948348 0.0024730 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 10 39865 -0.023198 0.239702 0.0950239 0.0023250 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 11 39866 -0.022698 0.239902 0.0953661 0.0021630 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 12 39867 -0.022197 0.240103 0.0958722 0.0020220 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 13 39868 -0.021697 0.240203 0.0964974 0.0019270 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 14 39869 -0.021197 0.240403 0.0971836 0.0018940 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 15 39870 -0.020696 0.240504 0.0978607 0.0019590 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 16 39871 -0.020196 0.240604 0.0984259 0.0021060 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 17 39872 -0.019696 0.240704 0.0987931 0.0023400 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 18 39873 -0.019196 0.240804 0.0989212 0.0026040 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 19 39874 -0.018695 0.240905 0.0987694 0.0028540 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 20 39875 -0.018195 0.241005 0.0984085 0.0030330 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 21 39876 -0.017695 0.241105 0.0979227 0.0031070 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 22 39877 -0.017095 0.241205 0.0974289 0.0030500 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 23 39878 -0.016594 0.241206 0.0970530 0.0028740 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 24 39879 -0.016094 0.241306 0.0968972 0.0026230 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 25 39880 -0.015594 0.241406 0.0970014 0.0023630 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 26 39881 -0.015093 0.241407 0.0973405 0.0021630 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 27 39882 -0.014593 0.241507 0.0978167 0.0020880 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 28 39883 -0.014093 0.241507 0.0983108 0.0021350 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 29 39884 -0.013493 0.241607 0.0986910 0.0023030 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 30 39885 -0.012992 0.241608 0.0988772 0.0025290 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 1 31 39886 -0.012392 0.241608 0.0988233 0.0027440 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 1 39887 -0.011792 0.241708 -0.0014225 0.0029160 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 2 39888 -0.011192 0.241708 -0.0018033 0.0030110 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 3 39889 -0.010591 0.241709 -0.0022262 0.0030220 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 4 39890 -0.009991 0.241709 -0.0026420 0.0029700 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 5 39891 -0.009291 0.241709 -0.0029578 0.0028430 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 6 39892 -0.008590 0.241710 -0.0031467 0.0026920 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 7 39893 -0.007890 0.241710 -0.0031575 0.0025320 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 8 39894 -0.007190 0.241610 -0.0030163 0.0023790 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 9 39895 -0.006390 0.241610 -0.0027592 0.0022770 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 10 39896 -0.005689 0.241611 -0.0024110 0.0022300 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 11 39897 -0.004889 0.241511 -0.0020569 0.0022560 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 12 39898 -0.004089 0.241411 -0.0017757 0.0023790 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 13 39899 -0.003288 0.241412 -0.0016645 0.0025930 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 14 39900 -0.002388 0.241312 -0.0017924 0.0028600 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 15 39901 -0.001588 0.241212 -0.0021962 0.0031330 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 16 39902 -0.000688 0.241112 -0.0028470 0.0033340 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 17 39903 0.000213 0.241013 -0.0036529 0.0034230 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 18 39904 0.001113 0.240913 -0.0044537 0.0033420 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 19 39905 0.002013 0.240713 -0.0050915 0.0031250 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 20 39906 0.002913 0.240613 -0.0054834 0.0028210 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 21 39907 0.003814 0.240414 -0.0055592 0.0025130 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 22 39908 0.004814 0.240314 -0.0053390 0.0022600 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 23 39909 0.005714 0.240114 -0.0049259 0.0021040 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 24 39910 0.006615 0.240015 -0.0044087 0.0020850 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 25 39911 0.007615 0.239815 -0.0039445 0.0021820 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 26 39912 0.008515 0.239615 -0.0036184 0.0023640 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 27 39913 0.009515 0.239415 -0.0034892 0.0025580 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 28 39914 0.010416 0.239216 -0.0035430 0.0027310 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 2 29 39915 0.011416 0.239016 -0.0037469 0.0028440 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 1 39916 0.012316 0.238816 -0.0040207 0.0028610 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 2 39917 0.013216 0.238616 -0.0042696 0.0028040 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 3 39918 0.014117 0.238417 -0.0044264 0.0026800 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 4 39919 0.015017 0.238217 -0.0044352 0.0025220 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 5 39920 0.015817 0.238017 -0.0042841 0.0023450 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 6 39921 0.016718 0.237818 -0.0039489 0.0021790 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 7 39922 0.017518 0.237618 -0.0034637 0.0020390 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 8 39923 0.018318 0.237418 -0.0028656 0.0019660 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 9 39924 0.019018 0.237218 -0.0022314 0.0019710 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 10 39925 0.019819 0.237019 -0.0016472 0.0020660 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 11 39926 0.020519 0.236919 -0.0012061 0.0022480 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 12 39927 0.021119 0.236719 -0.0009909 0.0025140 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 13 39928 0.021819 0.236619 -0.0010667 0.0028200 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 14 39929 0.022420 0.236420 -0.0014516 0.0031000 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 15 39930 0.023020 0.236320 -0.0020604 0.0032750 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 16 39931 0.023520 0.236120 -0.0027572 0.0032900 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 17 39932 0.024121 0.236021 -0.0033931 0.0031370 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 18 39933 0.024621 0.235921 -0.0037979 0.0028590 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 19 39934 0.025021 0.235821 -0.0039067 0.0025290 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 20 39935 0.025521 0.235721 -0.0036916 0.0022430 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 21 39936 0.026022 0.235622 -0.0032494 0.0020740 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 22 39937 0.026422 0.235522 -0.0027042 0.0020490 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 23 39938 0.026822 0.235422 -0.0021971 0.0021350 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 24 39939 0.027322 0.235422 -0.0018229 0.0023060 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 25 39940 0.027723 0.235323 -0.0016397 0.0025200 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 26 39941 0.028123 0.235223 -0.0016676 0.0027200 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 27 39942 0.028523 0.235223 -0.0018824 0.0028770 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 28 39943 0.029024 0.235124 -0.0022052 0.0029550 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 29 39944 0.029424 0.235024 -0.0025841 0.0029600 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 30 39945 0.029924 0.235024 -0.0029299 0.0029000 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 3 31 39946 0.030424 0.234924 -0.0031747 0.0027730 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 1 39947 0.030925 0.234825 -0.0032865 0.0026280 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 2 39948 0.031425 0.234825 -0.0032504 0.0024830 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 3 39949 0.032025 0.234725 -0.0030822 0.0023870 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 4 39950 0.032525 0.234625 -0.0028610 0.0023430 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 5 39951 0.033226 0.234526 -0.0026099 0.0023590 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 6 39952 0.033826 0.234426 -0.0024157 0.0024470 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 7 39953 0.034426 0.234326 -0.0023445 0.0026260 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 8 39954 0.035127 0.234227 -0.0025064 0.0028930 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 9 39955 0.035827 0.234127 -0.0029812 0.0032340 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 10 39956 0.036627 0.234027 -0.0037900 0.0035600 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 11 39957 0.037327 0.233827 -0.0048909 0.0038260 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 12 39958 0.038128 0.233728 -0.0062057 0.0039370 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 13 39959 0.038928 0.233528 -0.0075355 0.0038710 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 14 39960 0.039828 0.233328 -0.0087034 0.0036310 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 15 39961 0.040628 0.233128 -0.0095752 0.0032960 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 16 39962 0.041429 0.232829 -0.0101060 0.0029570 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 17 39963 0.042329 0.232629 -0.0103409 0.0027120 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 18 39964 0.043129 0.232329 -0.0103977 0.0026080 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 19 39965 0.044030 0.232030 -0.0104135 0.0026230 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 20 39966 0.044830 0.231730 -0.0105074 0.0027560 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 21 39967 0.045730 0.231330 -0.0107502 0.0029220 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 22 39968 0.046530 0.231030 -0.0111580 0.0030800 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 23 39969 0.047331 0.230631 -0.0117028 0.0031910 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 24 39970 0.048131 0.230231 -0.0123257 0.0032230 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 25 39971 0.048931 0.229831 -0.0129435 0.0031890 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 26 39972 0.049731 0.229331 -0.0134983 0.0030900 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 27 39973 0.050432 0.228832 -0.0139132 0.0029210 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 28 39974 0.051132 0.228432 -0.0141370 0.0027140 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 29 39975 0.051832 0.227832 -0.0141558 0.0024970 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 4 30 39976 0.052433 0.227333 -0.0139667 0.0023100 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 1 39977 0.053033 0.226833 -0.0136115 0.0021690 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 2 39978 0.053633 0.226233 -0.0131363 0.0020940 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 3 39979 0.054133 0.225633 -0.0126342 0.0021060 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 4 39980 0.054634 0.225034 -0.0121850 0.0021900 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 5 39981 0.055034 0.224434 -0.0118608 0.0023640 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 6 39982 0.055534 0.223734 -0.0117456 0.0026050 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 7 39983 0.055835 0.223135 -0.0118935 0.0028730 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 8 39984 0.056235 0.222435 -0.0123163 0.0031320 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 9 39985 0.056535 0.221735 -0.0129491 0.0033130 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 10 39986 0.056735 0.221035 -0.0136920 0.0033350 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 11 39987 0.057036 0.220336 -0.0143798 0.0031840 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 12 39988 0.057236 0.219636 -0.0148336 0.0028970 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 13 39989 0.057336 0.218836 -0.0149765 0.0025690 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 14 39990 0.057536 0.218036 -0.0147993 0.0022850 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 15 39991 0.057637 0.217337 -0.0144191 0.0021410 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 16 39992 0.057737 0.216537 -0.0139539 0.0021530 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 17 39993 0.057837 0.215737 -0.0135778 0.0022890 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 18 39994 0.057938 0.214938 -0.0133726 0.0024970 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 19 39995 0.057938 0.214138 -0.0133794 0.0026930 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 20 39996 0.058038 0.213338 -0.0135613 0.0028410 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 21 39997 0.058038 0.212438 -0.0138671 0.0029280 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 22 39998 0.058039 0.211639 -0.0142019 0.0029300 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 23 39999 0.058039 0.210839 -0.0145128 0.0028610 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 24 40000 0.058039 0.209939 -0.0147136 0.0027330 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 25 40001 0.058039 0.209139 -0.0147744 0.0025650 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 26 40002 0.058140 0.208240 -0.0146472 0.0023700 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 27 40003 0.058140 0.207440 -0.0143371 0.0021960 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 28 40004 0.058140 0.206540 -0.0138719 0.0020620 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 29 40005 0.058141 0.205641 -0.0133027 0.0019900 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 30 40006 0.058141 0.204741 -0.0126886 0.0019840 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 5 31 40007 0.058141 0.203941 -0.0121074 0.0020580 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 1 40008 0.058241 0.203041 -0.0116382 0.0021960 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 2 40009 0.058242 0.202142 -0.0113490 0.0024040 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 3 40010 0.058342 0.201242 -0.0112679 0.0026380 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 4 40011 0.058442 0.200342 -0.0114247 0.0028600 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 5 40012 0.058542 0.199442 -0.0117895 0.0030370 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 6 40013 0.058643 0.198543 -0.0122824 0.0031050 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 7 40014 0.058843 0.197643 -0.0127712 0.0030160 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 8 40015 0.058943 0.196643 -0.0130850 0.0027830 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 9 40016 0.059144 0.195744 -0.0131259 0.0024600 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 10 40017 0.059344 0.194844 -0.0128247 0.0021390 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 11 40018 0.059544 0.193844 -0.0122455 0.0019140 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 12 40019 0.059744 0.192944 -0.0115133 0.0018390 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 13 40020 0.059945 0.191945 -0.0107832 0.0019030 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 14 40021 0.060245 0.191045 -0.0101800 0.0020610 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 15 40022 0.060545 0.190045 -0.0097428 0.0022400 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 16 40023 0.060745 0.189045 -0.0094657 0.0023760 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 17 40024 0.061046 0.188046 -0.0092765 0.0024120 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 18 40025 0.061346 0.187046 -0.0090803 0.0023720 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 19 40026 0.061646 0.186146 -0.0087931 0.0022550 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 20 40027 0.061947 0.185147 -0.0083790 0.0020780 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 21 40028 0.062347 0.184147 -0.0077568 0.0018720 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 22 40029 0.062647 0.183147 -0.0069256 0.0016360 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 23 40030 0.062947 0.182147 -0.0058404 0.0014080 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 24 40031 0.063248 0.181148 -0.0045613 0.0012220 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 25 40032 0.063548 0.180148 -0.0031241 0.0011040 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 26 40033 0.063848 0.179148 -0.0016039 0.0010600 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 27 40034 0.064148 0.178148 -0.0000808 0.0010980 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 28 40035 0.064449 0.177149 0.0013544 0.0012230 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 29 40036 0.064749 0.176149 0.0026326 0.0014190 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 6 30 40037 0.065049 0.175249 0.0036958 0.0016480 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 1 40038 0.065350 0.174250 0.0045179 0.0018820 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 2 40039 0.065550 0.173250 0.0051271 0.0020890 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 3 40040 0.065750 0.172350 0.0055513 0.0022060 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 4 40041 0.065950 0.171350 0.0059264 0.0022020 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 5 40042 0.066151 0.170451 0.0063796 0.0020720 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 6 40043 0.066351 0.169551 0.0070058 0.0018450 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 7 40044 0.066451 0.168651 0.0078710 0.0016080 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 8 40045 0.066551 0.167751 0.0089611 0.0014170 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 9 40046 0.066552 0.166852 0.0101843 0.0013410 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 10 40047 0.066652 0.166052 0.0114085 0.0014270 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 11 40048 0.066652 0.165152 0.0124797 0.0016270 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 12 40049 0.066553 0.164353 0.0133158 0.0018930 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 13 40050 0.066453 0.163553 0.0138810 0.0021390 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 14 40051 0.066353 0.162653 0.0142552 0.0022870 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 15 40052 0.066153 0.161853 0.0145203 0.0023470 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 16 40053 0.065954 0.161154 0.0147735 0.0023020 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 17 40054 0.065754 0.160354 0.0151087 0.0021870 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 18 40055 0.065454 0.159554 0.0155949 0.0020260 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 19 40056 0.065154 0.158854 0.0162550 0.0018340 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 20 40057 0.064755 0.158155 0.0171062 0.0016570 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 21 40058 0.064355 0.157455 0.0181214 0.0014990 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 22 40059 0.063855 0.156755 0.0192716 0.0013830 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 23 40060 0.063356 0.156056 0.0205017 0.0013490 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 24 40061 0.062856 0.155356 0.0217359 0.0013970 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 25 40062 0.062256 0.154656 0.0228701 0.0015290 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 26 40063 0.061656 0.154056 0.0238362 0.0017400 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 27 40064 0.060957 0.153457 0.0245664 0.0019830 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 28 40065 0.060257 0.152757 0.0250416 0.0022340 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 29 40066 0.059557 0.152157 0.0252848 0.0024470 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 30 40067 0.058758 0.151658 0.0253689 0.0025670 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 7 31 40068 0.057958 0.151058 0.0253821 0.0025690 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 1 40069 0.057158 0.150458 0.0254523 0.0024710 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 2 40070 0.056258 0.149958 0.0256595 0.0022730 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 3 40071 0.055359 0.149459 0.0260886 0.0020500 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 4 40072 0.054359 0.148959 0.0267398 0.0018500 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 5 40073 0.053459 0.148459 0.0275450 0.0017500 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 6 40074 0.052459 0.148059 0.0283722 0.0018100 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 7 40075 0.051360 0.147560 0.0290713 0.0019930 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 8 40076 0.050360 0.147160 0.0295375 0.0022520 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 9 40077 0.049260 0.146760 0.0297417 0.0025260 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 10 40078 0.048161 0.146361 0.0296949 0.0027340 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 11 40079 0.047061 0.145961 0.0294870 0.0028440 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 12 40080 0.045961 0.145561 0.0292232 0.0028460 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 13 40081 0.044761 0.145161 0.0290154 0.0027370 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 14 40082 0.043662 0.144762 0.0289505 0.0025660 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 15 40083 0.042462 0.144362 0.0290727 0.0023670 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 16 40084 0.041262 0.144062 0.0294079 0.0021460 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 17 40085 0.040062 0.143662 0.0299611 0.0019520 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 18 40086 0.038863 0.143263 0.0306762 0.0018080 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 19 40087 0.037563 0.142963 0.0315034 0.0017300 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 20 40088 0.036363 0.142563 0.0323686 0.0017340 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 21 40089 0.035164 0.142164 0.0331888 0.0018120 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 22 40090 0.033864 0.141764 0.0339089 0.0019690 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 23 40091 0.032664 0.141464 0.0344211 0.0021940 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 24 40092 0.031364 0.141064 0.0346953 0.0024370 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 25 40093 0.030165 0.140665 0.0347405 0.0026530 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 26 40094 0.028865 0.140265 0.0346006 0.0027870 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 27 40095 0.027665 0.139865 0.0343998 0.0027820 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 28 40096 0.026465 0.139465 0.0342630 0.0026510 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 29 40097 0.025166 0.138966 0.0343132 0.0024170 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 30 40098 0.023966 0.138566 0.0346233 0.0021510 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 8 31 40099 0.022766 0.138066 0.0351925 0.0019130 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 1 40100 0.021567 0.137667 0.0359377 0.0017750 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 2 40101 0.020367 0.137167 0.0367779 0.0017670 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 3 40102 0.019167 0.136667 0.0375590 0.0018810 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 4 40103 0.017967 0.136167 0.0381532 0.0021050 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 5 40104 0.016768 0.135568 0.0385064 0.0023790 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 6 40105 0.015568 0.135068 0.0385926 0.0026280 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 7 40106 0.014468 0.134468 0.0384677 0.0027870 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 8 40107 0.013268 0.133868 0.0382349 0.0028490 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 9 40108 0.012169 0.133269 0.0379941 0.0027970 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 10 40109 0.010969 0.132669 0.0378483 0.0026750 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 11 40110 0.009869 0.132069 0.0378504 0.0025060 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 12 40111 0.008770 0.131370 0.0380306 0.0023150 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 13 40112 0.007670 0.130670 0.0383948 0.0021440 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 14 40113 0.006570 0.130070 0.0389090 0.0020170 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 15 40114 0.005470 0.129370 0.0395181 0.0019560 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 16 40115 0.004371 0.128571 0.0401613 0.0019710 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 17 40116 0.003271 0.127871 0.0407385 0.0020600 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 18 40117 0.002271 0.127171 0.0411947 0.0022300 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 19 40118 0.001171 0.126371 0.0414458 0.0024690 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 20 40119 0.000072 0.125672 0.0414340 0.0027380 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 21 40120 -0.000928 0.124872 0.0411522 0.0030100 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 22 40121 -0.002028 0.124072 0.0406274 0.0032030 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 23 40122 -0.003127 0.123373 0.0399685 0.0032710 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 24 40123 -0.004227 0.122573 0.0393177 0.0031840 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 25 40124 -0.005327 0.121773 0.0388259 0.0029620 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 26 40125 -0.006427 0.121073 0.0386081 0.0026570 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 27 40126 -0.007526 0.120274 0.0386992 0.0023710 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 28 40127 -0.008626 0.119474 0.0390384 0.0021610 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 29 40128 -0.009826 0.118774 0.0395126 0.0020940 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 9 30 40129 -0.011026 0.118074 0.0399848 0.0021540 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 1 40130 -0.012225 0.117375 0.0403399 0.0023290 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 2 40131 -0.013425 0.116675 0.0404981 0.0025480 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 3 40132 -0.014725 0.115975 0.0404273 0.0027700 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 4 40133 -0.016024 0.115376 0.0401595 0.0029330 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 5 40134 -0.017324 0.114776 0.0397826 0.0029940 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 6 40135 -0.018724 0.114176 0.0393958 0.0029540 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 7 40136 -0.020124 0.113676 0.0390960 0.0028340 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 8 40137 -0.021623 0.113177 0.0389392 0.0026520 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 9 40138 -0.023123 0.112677 0.0389814 0.0024530 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 10 40139 -0.024723 0.112277 0.0392125 0.0022600 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 11 40140 -0.026323 0.111977 0.0396297 0.0021140 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 12 40141 -0.027922 0.111678 0.0401649 0.0020180 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 13 40142 -0.029622 0.111478 0.0407501 0.0020060 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 14 40143 -0.031422 0.111278 0.0413162 0.0020650 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 15 40144 -0.033221 0.111079 0.0417744 0.0022220 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 16 40145 -0.035021 0.111079 0.0420386 0.0024400 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 17 40146 -0.037021 0.111079 0.0420568 0.0027110 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 18 40147 -0.038921 0.111179 0.0417899 0.0030010 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 19 40148 -0.040920 0.111280 0.0412451 0.0032490 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 20 40149 -0.043020 0.111480 0.0404953 0.0034110 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 21 40150 -0.045120 0.111680 0.0396525 0.0034280 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 22 40151 -0.047319 0.112081 0.0388836 0.0032770 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 23 40152 -0.049519 0.112381 0.0383288 0.0030080 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 24 40153 -0.051719 0.112881 0.0380690 0.0027050 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 25 40154 -0.054019 0.113381 0.0380882 0.0024540 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 26 40155 -0.056418 0.113982 0.0382883 0.0023420 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 27 40156 -0.058818 0.114582 0.0385425 0.0023720 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 28 40157 -0.061218 0.115282 0.0386927 0.0025240 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 29 40158 -0.063618 0.116082 0.0386629 0.0027310 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 30 40159 -0.066117 0.116883 0.0384110 0.0029390 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 10 31 40160 -0.068617 0.117783 0.0379732 0.0030950 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 1 40161 -0.071217 0.118683 0.0374284 0.0031800 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 2 40162 -0.073716 0.119684 0.0368446 0.0031630 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 3 40163 -0.076316 0.120684 0.0363128 0.0030700 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 4 40164 -0.078816 0.121784 0.0359079 0.0029110 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 5 40165 -0.081416 0.122884 0.0356931 0.0027140 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 6 40166 -0.083915 0.124085 0.0356823 0.0025110 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 7 40167 -0.086515 0.125285 0.0358535 0.0023340 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 8 40168 -0.089015 0.126585 0.0361676 0.0022180 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 9 40169 -0.091515 0.127885 0.0365838 0.0021730 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 10 40170 -0.094014 0.129186 0.0369760 0.0022160 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 11 40171 -0.096514 0.130586 0.0373162 0.0023150 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 12 40172 -0.098914 0.131986 0.0375123 0.0024920 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 13 40173 -0.101313 0.133387 0.0375045 0.0027120 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 14 40174 -0.103713 0.134887 0.0372597 0.0029610 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 15 40175 -0.105913 0.136287 0.0367649 0.0032030 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 16 40176 -0.108213 0.137887 0.0360521 0.0033890 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 17 40177 -0.110312 0.139388 0.0352052 0.0034630 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 18 40178 -0.112412 0.140888 0.0343574 0.0033890 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 19 40179 -0.114412 0.142488 0.0336656 0.0031650 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 20 40180 -0.116412 0.144088 0.0332448 0.0028590 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 21 40181 -0.118211 0.145689 0.0331229 0.0025650 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 22 40182 -0.120011 0.147289 0.0332601 0.0023760 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 23 40183 -0.121711 0.148989 0.0334993 0.0023420 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 24 40184 -0.123310 0.150590 0.0336955 0.0024570 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 25 40185 -0.124810 0.152290 0.0337256 0.0026620 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 26 40186 -0.126210 0.153990 0.0335478 0.0028800 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 27 40187 -0.127510 0.155690 0.0331730 0.0030470 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 28 40188 -0.128709 0.157291 0.0326722 0.0031180 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 29 40189 -0.129909 0.158991 0.0321494 0.0031040 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 11 30 40190 -0.130909 0.160791 0.0316815 0.0029980 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 1 40191 -0.131809 0.162491 0.0313547 0.0028290 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 2 40192 -0.132708 0.164192 0.0312179 0.0026310 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 3 40193 -0.133408 0.165892 0.0312861 0.0024230 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 4 40194 -0.134108 0.167592 0.0315562 0.0022210 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 5 40195 -0.134707 0.169293 0.0319994 0.0020730 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 6 40196 -0.135207 0.171093 0.0325686 0.0019900 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 7 40197 -0.135607 0.172793 0.0331848 0.0019830 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 8 40198 -0.136007 0.174493 0.0337679 0.0020620 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 9 40199 -0.136306 0.176194 0.0342271 0.0021990 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 10 40200 -0.136506 0.177894 0.0345243 0.0023950 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 11 40201 -0.136606 0.179594 0.0346085 0.0026180 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 12 40202 -0.136706 0.181294 0.0344687 0.0028410 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 13 40203 -0.136805 0.182995 0.0341198 0.0030260 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 14 40204 -0.136705 0.184695 0.0336230 0.0031430 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 15 40205 -0.136705 0.186395 0.0330542 0.0031420 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 16 40206 -0.136504 0.187996 0.0325624 0.0030010 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 17 40207 -0.136404 0.189696 0.0322675 0.0027570 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 18 40208 -0.136204 0.191396 0.0322407 0.0024800 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 19 40209 -0.135904 0.193096 0.0324689 0.0022620 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 20 40210 -0.135603 0.194697 0.0328601 0.0021820 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 21 40211 -0.135303 0.196397 0.0332503 0.0022520 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 22 40212 -0.134903 0.197997 0.0334924 0.0024490 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 23 40213 -0.134503 0.199697 0.0335086 0.0026910 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 24 40214 -0.134102 0.201298 0.0333038 0.0028970 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 25 40215 -0.133702 0.202998 0.0329360 0.0029990 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 26 40216 -0.133202 0.204598 0.0325241 0.0029990 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 27 40217 -0.132701 0.206199 0.0321613 0.0029010 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 28 40218 -0.132201 0.207899 0.0319345 0.0027250 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 29 40219 -0.131601 0.209499 0.0318957 0.0025210 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 30 40220 -0.131101 0.211199 0.0320869 0.0022970 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1968 12 31 40221 -0.130500 0.212800 0.0324860 0.0020990 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 1 40222 -0.129900 0.214400 0.0330652 0.0019400 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 2 40223 -0.129300 0.216100 0.0337654 0.0018510 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 3 40224 -0.128700 0.217700 0.0345286 0.0018370 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 4 40225 -0.127999 0.219401 0.0352557 0.0019010 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 5 40226 -0.127399 0.221001 0.0358829 0.0020360 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 6 40227 -0.126699 0.222701 0.0363471 0.0022230 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 7 40228 -0.125998 0.224302 0.0366083 0.0024370 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 8 40229 -0.125298 0.226002 0.0366545 0.0026480 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 9 40230 -0.124598 0.227602 0.0365046 0.0028320 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 10 40231 -0.123898 0.229302 0.0362138 0.0029370 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 11 40232 -0.123197 0.231003 0.0358550 0.0029440 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 12 40233 -0.122497 0.232603 0.0355522 0.0028410 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 13 40234 -0.121797 0.234303 0.0353953 0.0026400 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 14 40235 -0.121097 0.236003 0.0354795 0.0023790 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 15 40236 -0.120396 0.237704 0.0358107 0.0021510 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 16 40237 -0.119696 0.239404 0.0363129 0.0020350 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 17 40238 -0.118996 0.241204 0.0368781 0.0020620 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 18 40239 -0.118295 0.242905 0.0373302 0.0022360 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 19 40240 -0.117595 0.244605 0.0375574 0.0025090 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 20 40241 -0.116895 0.246405 0.0375016 0.0027730 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 21 40242 -0.116195 0.248205 0.0372178 0.0029670 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 22 40243 -0.115594 0.250006 0.0368009 0.0030270 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 23 40244 -0.114894 0.251806 0.0363871 0.0029730 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 24 40245 -0.114194 0.253606 0.0360863 0.0028170 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 25 40246 -0.113593 0.255407 0.0359505 0.0026190 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 26 40247 -0.112893 0.257307 0.0360327 0.0024180 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 27 40248 -0.112293 0.259107 0.0362998 0.0022330 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 28 40249 -0.111693 0.261007 0.0367350 0.0020960 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 29 40250 -0.111092 0.262908 0.0372782 0.0020080 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 30 40251 -0.110492 0.264808 0.0378744 0.0020030 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 1 31 40252 -0.109892 0.266708 0.0384355 0.0020680 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 1 40253 -0.109292 0.268708 0.0388817 0.0022200 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 2 40254 -0.108691 0.270609 0.0391549 0.0024330 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 3 40255 -0.108191 0.272609 0.0391941 0.0026820 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 4 40256 -0.107591 0.274609 0.0389713 0.0029330 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 5 40257 -0.107090 0.276610 0.0385214 0.0031470 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 6 40258 -0.106590 0.278610 0.0379026 0.0032770 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 7 40259 -0.105990 0.280610 0.0371818 0.0033270 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 8 40260 -0.105490 0.282610 0.0364750 0.0032600 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 9 40261 -0.104989 0.284611 0.0358831 0.0030910 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 10 40262 -0.104489 0.286711 0.0355013 0.0028600 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 11 40263 -0.103889 0.288711 0.0353405 0.0026480 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 12 40264 -0.103389 0.290711 0.0353697 0.0025030 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 13 40265 -0.102888 0.292712 0.0354809 0.0024790 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 14 40266 -0.102388 0.294712 0.0355420 0.0026030 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 15 40267 -0.101888 0.296712 0.0354172 0.0028430 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 16 40268 -0.101287 0.298713 0.0350214 0.0031280 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 17 40269 -0.100787 0.300713 0.0343646 0.0033510 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 18 40270 -0.100187 0.302613 0.0335457 0.0034650 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 19 40271 -0.099587 0.304513 0.0326709 0.0034520 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 20 40272 -0.099086 0.306414 0.0318621 0.0033290 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 21 40273 -0.098386 0.308314 0.0312303 0.0031250 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 22 40274 -0.097786 0.310114 0.0308025 0.0028990 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 23 40275 -0.097086 0.311814 0.0306086 0.0026810 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 24 40276 -0.096385 0.313615 0.0306078 0.0025000 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 25 40277 -0.095685 0.315315 0.0307700 0.0023770 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 26 40278 -0.094885 0.316915 0.0310112 0.0023360 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 27 40279 -0.094084 0.318516 0.0312624 0.0023750 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 2 28 40280 -0.093284 0.320116 0.0314235 0.0024950 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 1 40281 -0.092384 0.321616 0.0314387 0.0026740 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 2 40282 -0.091384 0.323016 0.0312389 0.0029130 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 3 40283 -0.090383 0.324417 0.0307881 0.0031690 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 4 40284 -0.089383 0.325817 0.0300982 0.0034020 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 5 40285 -0.088283 0.327117 0.0291974 0.0035560 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 6 40286 -0.087183 0.328417 0.0281916 0.0036150 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 7 40287 -0.085982 0.329618 0.0271978 0.0035430 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 8 40288 -0.084682 0.330718 0.0263220 0.0033740 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 9 40289 -0.083382 0.331918 0.0256601 0.0031340 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 10 40290 -0.082081 0.332919 0.0252343 0.0028940 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 11 40291 -0.080681 0.334019 0.0250295 0.0027220 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 12 40292 -0.079181 0.335019 0.0249317 0.0026770 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 13 40293 -0.077681 0.335919 0.0248188 0.0027620 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 14 40294 -0.076180 0.336820 0.0245570 0.0029690 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 15 40295 -0.074480 0.337720 0.0240482 0.0032470 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 16 40296 -0.072880 0.338520 0.0232564 0.0035210 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 17 40297 -0.071180 0.339320 0.0222216 0.0037200 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 18 40298 -0.069379 0.340121 0.0210377 0.0037960 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 19 40299 -0.067579 0.340821 0.0198639 0.0037420 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 20 40300 -0.065779 0.341521 0.0187901 0.0035730 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 21 40301 -0.063878 0.342222 0.0179083 0.0033540 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 22 40302 -0.061878 0.342822 0.0172655 0.0031130 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 23 40303 -0.059878 0.343422 0.0168526 0.0029090 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 24 40304 -0.057878 0.344022 0.0166198 0.0027490 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 25 40305 -0.055877 0.344623 0.0165130 0.0026590 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 26 40306 -0.053777 0.345223 0.0164552 0.0026500 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 27 40307 -0.051677 0.345723 0.0163663 0.0027210 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 28 40308 -0.049577 0.346323 0.0161695 0.0028650 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 29 40309 -0.047376 0.346824 0.0157977 0.0030780 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 30 40310 -0.045176 0.347324 0.0151939 0.0033130 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 3 31 40311 -0.042976 0.347824 0.0143611 0.0035380 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 1 40312 -0.040775 0.348225 0.0133142 0.0037260 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 2 40313 -0.038475 0.348725 0.0121214 0.0038200 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 3 40314 -0.036275 0.349225 0.0109066 0.0037780 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 4 40315 -0.033975 0.349625 0.0097898 0.0036070 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 5 40316 -0.031674 0.350126 0.0088929 0.0033560 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 6 40317 -0.029374 0.350526 0.0082751 0.0030720 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 7 40318 -0.027074 0.350926 0.0079103 0.0028530 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 8 40319 -0.024774 0.351326 0.0077205 0.0027390 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 9 40320 -0.022473 0.351727 0.0075757 0.0027640 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 10 40321 -0.020073 0.352127 0.0073298 0.0029240 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 11 40322 -0.017773 0.352527 0.0068910 0.0031520 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 12 40323 -0.015372 0.352928 0.0062012 0.0034050 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 13 40324 -0.012972 0.353228 0.0052784 0.0036080 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 14 40325 -0.010672 0.353628 0.0042096 0.0037030 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 15 40326 -0.008272 0.353928 0.0030927 0.0036900 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 16 40327 -0.005871 0.354229 0.0020569 0.0035570 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 17 40328 -0.003471 0.354529 0.0011851 0.0033560 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 18 40329 -0.001071 0.354729 0.0005353 0.0031220 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 19 40330 0.001330 0.355030 0.0001184 0.0028970 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 20 40331 0.003730 0.355230 -0.0000834 0.0027060 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 21 40332 0.006130 0.355330 -0.0001252 0.0025810 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 22 40333 0.008530 0.355530 -0.0000800 0.0025240 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 23 40334 0.010931 0.355531 -0.0000198 0.0025480 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 24 40335 0.013431 0.355631 -0.0000197 0.0026450 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 25 40336 0.015831 0.355631 -0.0001495 0.0028020 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 26 40337 0.018231 0.355531 -0.0004573 0.0030000 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 27 40338 0.020732 0.355432 -0.0009631 0.0032020 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 28 40339 0.023132 0.355332 -0.0016630 0.0033720 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 29 40340 0.025632 0.355032 -0.0025048 0.0034760 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 4 30 40341 0.028133 0.354833 -0.0033986 0.0034910 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 1 40342 0.030533 0.354433 -0.0042414 0.0033640 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 2 40343 0.033033 0.354033 -0.0049052 0.0031170 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 3 40344 0.035433 0.353633 -0.0052861 0.0028200 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 4 40345 0.037934 0.353034 -0.0053629 0.0025360 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 5 40346 0.040334 0.352434 -0.0052117 0.0023650 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 6 40347 0.042834 0.351834 -0.0049615 0.0023500 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 7 40348 0.045234 0.351034 -0.0047684 0.0024640 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 8 40349 0.047635 0.350235 -0.0047392 0.0026780 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 9 40350 0.050035 0.349435 -0.0049400 0.0029130 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 10 40351 0.052435 0.348535 -0.0053588 0.0031030 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 11 40352 0.054836 0.347536 -0.0059266 0.0032060 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 12 40353 0.057236 0.346436 -0.0065535 0.0032010 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 13 40354 0.059636 0.345436 -0.0071243 0.0031050 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 14 40355 0.061936 0.344236 -0.0075461 0.0029300 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 15 40356 0.064237 0.343037 -0.0077799 0.0027130 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 16 40357 0.066537 0.341737 -0.0077897 0.0024900 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 17 40358 0.068837 0.340537 -0.0075996 0.0023080 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 18 40359 0.071037 0.339137 -0.0072444 0.0021840 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 19 40360 0.073238 0.337738 -0.0068122 0.0021450 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 20 40361 0.075438 0.336338 -0.0063710 0.0021760 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 21 40362 0.077638 0.334838 -0.0059979 0.0022810 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 22 40363 0.079739 0.333439 -0.0057627 0.0024460 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 23 40364 0.081839 0.331839 -0.0057145 0.0026530 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 24 40365 0.083939 0.330339 -0.0058833 0.0028770 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 25 40366 0.086039 0.328739 -0.0062751 0.0030830 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 26 40367 0.088040 0.327140 -0.0068650 0.0032560 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 27 40368 0.089940 0.325540 -0.0075708 0.0033390 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 28 40369 0.091940 0.323840 -0.0083146 0.0033080 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 29 40370 0.093840 0.322240 -0.0089654 0.0031550 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 30 40371 0.095741 0.320541 -0.0094123 0.0028990 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 5 31 40372 0.097541 0.318841 -0.0095871 0.0026240 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 1 40373 0.099341 0.317141 -0.0095029 0.0024180 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 2 40374 0.101142 0.315442 -0.0092787 0.0023410 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 3 40375 0.102842 0.313742 -0.0090475 0.0024210 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 4 40376 0.104542 0.312042 -0.0089704 0.0026110 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 5 40377 0.106142 0.310342 -0.0091022 0.0028420 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 6 40378 0.107843 0.308643 -0.0094500 0.0030230 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 7 40379 0.109343 0.306843 -0.0099348 0.0031080 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 8 40380 0.110943 0.305143 -0.0104367 0.0030670 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 9 40381 0.112443 0.303343 -0.0108535 0.0029320 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 10 40382 0.113844 0.301644 -0.0110953 0.0027110 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 11 40383 0.115344 0.299944 -0.0110921 0.0024590 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 12 40384 0.116744 0.298144 -0.0108199 0.0021890 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 13 40385 0.118045 0.296445 -0.0102878 0.0019330 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 14 40386 0.119345 0.294645 -0.0095226 0.0017470 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 15 40387 0.120645 0.292945 -0.0086144 0.0016200 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 16 40388 0.121845 0.291145 -0.0076172 0.0015810 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 17 40389 0.123046 0.289446 -0.0066121 0.0016090 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 18 40390 0.124146 0.287646 -0.0056759 0.0017100 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 19 40391 0.125246 0.285846 -0.0048657 0.0018540 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 20 40392 0.126346 0.284146 -0.0042095 0.0020250 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 21 40393 0.127347 0.282347 -0.0037223 0.0021880 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 22 40394 0.128347 0.280647 -0.0033922 0.0023160 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 23 40395 0.129347 0.278847 -0.0031430 0.0023830 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 24 40396 0.130248 0.277148 -0.0029388 0.0023700 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 25 40397 0.131048 0.275348 -0.0026776 0.0022610 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 26 40398 0.131948 0.273648 -0.0022465 0.0020650 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 27 40399 0.132748 0.271848 -0.0015993 0.0018180 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 28 40400 0.133449 0.270049 -0.0007121 0.0016090 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 29 40401 0.134249 0.268249 0.0003361 0.0014980 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 6 30 40402 0.134949 0.266549 0.0014083 0.0015560 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 1 40403 0.135549 0.264749 0.0023554 0.0017630 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 2 40404 0.136150 0.262950 0.0030456 0.0020530 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 3 40405 0.136750 0.261150 0.0034328 0.0023310 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 4 40406 0.137350 0.259250 0.0035950 0.0025160 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 5 40407 0.137851 0.257451 0.0036281 0.0025750 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 6 40408 0.138351 0.255551 0.0036773 0.0024960 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 7 40409 0.138751 0.253751 0.0038465 0.0023450 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 8 40410 0.139251 0.251851 0.0041927 0.0021380 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 9 40411 0.139552 0.249952 0.0047519 0.0019160 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 10 40412 0.139952 0.248052 0.0055220 0.0017300 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 11 40413 0.140252 0.246152 0.0064662 0.0015820 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 12 40414 0.140553 0.244153 0.0075264 0.0014890 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 13 40415 0.140753 0.242253 0.0086426 0.0014830 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 14 40416 0.140953 0.240253 0.0097257 0.0015540 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 15 40417 0.141153 0.238253 0.0107009 0.0016840 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 16 40418 0.141254 0.236254 0.0115221 0.0018610 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 17 40419 0.141354 0.234154 0.0121533 0.0020590 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 18 40420 0.141354 0.232154 0.0125964 0.0022500 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 19 40421 0.141454 0.230054 0.0128546 0.0023950 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 20 40422 0.141455 0.228055 0.0129968 0.0024900 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 21 40423 0.141355 0.225955 0.0130920 0.0024960 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 22 40424 0.141355 0.223855 0.0132162 0.0024100 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 23 40425 0.141256 0.221656 0.0134713 0.0022380 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 24 40426 0.141056 0.219556 0.0139305 0.0020090 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 25 40427 0.140956 0.217456 0.0146347 0.0017790 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 26 40428 0.140756 0.215256 0.0155289 0.0016220 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 27 40429 0.140557 0.213057 0.0165250 0.0015910 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 28 40430 0.140257 0.210957 0.0174722 0.0017290 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 29 40431 0.139957 0.208757 0.0182154 0.0019790 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 30 40432 0.139657 0.206557 0.0186826 0.0022760 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 7 31 40433 0.139358 0.204358 0.0188738 0.0025020 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 1 40434 0.139058 0.202158 0.0189029 0.0025940 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 2 40435 0.138658 0.199958 0.0189291 0.0025310 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 3 40436 0.138259 0.197759 0.0190753 0.0023500 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 4 40437 0.137859 0.195559 0.0194425 0.0020980 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 5 40438 0.137359 0.193359 0.0200646 0.0018300 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 6 40439 0.136859 0.191159 0.0209538 0.0015880 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 7 40440 0.136360 0.188960 0.0220510 0.0014080 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 8 40441 0.135860 0.186760 0.0232952 0.0012970 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 9 40442 0.135360 0.184560 0.0246133 0.0012710 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 10 40443 0.134760 0.182360 0.0259165 0.0013240 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 11 40444 0.134161 0.180161 0.0271307 0.0014490 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 12 40445 0.133461 0.177961 0.0281809 0.0016390 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 13 40446 0.132861 0.175861 0.0290221 0.0018600 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 14 40447 0.132162 0.173662 0.0296422 0.0020790 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 15 40448 0.131462 0.171562 0.0300554 0.0022760 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 16 40449 0.130762 0.169462 0.0303016 0.0024100 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 17 40450 0.129962 0.167362 0.0304538 0.0024610 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 18 40451 0.129163 0.165263 0.0305899 0.0024200 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 19 40452 0.128363 0.163163 0.0308211 0.0022970 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 20 40453 0.127463 0.161163 0.0312063 0.0021170 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 21 40454 0.126563 0.159063 0.0317695 0.0019390 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 22 40455 0.125664 0.157064 0.0324906 0.0018030 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 23 40456 0.124764 0.155064 0.0333058 0.0017880 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 24 40457 0.123764 0.153064 0.0340660 0.0019080 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 25 40458 0.122765 0.151165 0.0346352 0.0021650 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 26 40459 0.121765 0.149265 0.0348893 0.0025020 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 27 40460 0.120665 0.147365 0.0348255 0.0028170 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 28 40461 0.119565 0.145465 0.0344697 0.0030520 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 29 40462 0.118466 0.143566 0.0339649 0.0031220 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 30 40463 0.117266 0.141766 0.0334691 0.0030370 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 8 31 40464 0.116066 0.139966 0.0331092 0.0028500 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 1 40465 0.114866 0.138166 0.0329654 0.0026150 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 2 40466 0.113567 0.136467 0.0330646 0.0023820 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 3 40467 0.112267 0.134667 0.0333748 0.0021990 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 4 40468 0.110967 0.132967 0.0338229 0.0020880 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 5 40469 0.109568 0.131268 0.0343521 0.0020580 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 6 40470 0.108168 0.129668 0.0348713 0.0021080 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 7 40471 0.106768 0.127968 0.0352905 0.0022340 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 8 40472 0.105268 0.126368 0.0355736 0.0024110 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 9 40473 0.103669 0.124769 0.0356458 0.0026280 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 10 40474 0.102169 0.123169 0.0354930 0.0028570 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 11 40475 0.100569 0.121669 0.0351302 0.0030530 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 12 40476 0.098869 0.120169 0.0345853 0.0032040 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 13 40477 0.097170 0.118570 0.0339295 0.0032610 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 14 40478 0.095470 0.117070 0.0332677 0.0032170 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 15 40479 0.093770 0.115670 0.0327089 0.0030780 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 16 40480 0.091871 0.114171 0.0323140 0.0028740 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 17 40481 0.090071 0.112671 0.0321472 0.0026540 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 18 40482 0.088171 0.111271 0.0321834 0.0024670 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 19 40483 0.086271 0.109871 0.0323606 0.0023780 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 20 40484 0.084272 0.108372 0.0325637 0.0024210 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 21 40485 0.082372 0.106972 0.0326549 0.0025970 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 22 40486 0.080272 0.105572 0.0325171 0.0028700 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 23 40487 0.078272 0.104172 0.0320963 0.0031690 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 24 40488 0.076173 0.102873 0.0313985 0.0034020 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 25 40489 0.074073 0.101473 0.0305146 0.0035100 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 26 40490 0.071873 0.100073 0.0296098 0.0034650 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 27 40491 0.069774 0.098674 0.0288220 0.0032830 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 28 40492 0.067574 0.097374 0.0282432 0.0030260 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 29 40493 0.065374 0.095974 0.0279473 0.0027490 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 9 30 40494 0.063074 0.094674 0.0279155 0.0025050 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 1 40495 0.060875 0.093375 0.0280947 0.0023290 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 2 40496 0.058675 0.091975 0.0284099 0.0022460 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 3 40497 0.056375 0.090675 0.0287640 0.0022490 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 4 40498 0.054076 0.089376 0.0290762 0.0023300 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 5 40499 0.051876 0.088076 0.0292714 0.0024780 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 6 40500 0.049576 0.086876 0.0292936 0.0026830 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 7 40501 0.047376 0.085576 0.0290877 0.0029000 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 8 40502 0.045177 0.084377 0.0286749 0.0031200 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 9 40503 0.042877 0.083177 0.0280601 0.0032900 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 10 40504 0.040677 0.081977 0.0272993 0.0033970 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 11 40505 0.038477 0.080777 0.0264804 0.0034050 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 12 40506 0.036278 0.079678 0.0257166 0.0032960 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 13 40507 0.034178 0.078578 0.0251078 0.0031090 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 14 40508 0.031978 0.077478 0.0247100 0.0028750 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 15 40509 0.029879 0.076379 0.0245291 0.0026790 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 16 40510 0.027679 0.075379 0.0245123 0.0025630 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 17 40511 0.025679 0.074479 0.0245385 0.0025780 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 18 40512 0.023579 0.073479 0.0244927 0.0027250 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 19 40513 0.021480 0.072580 0.0242448 0.0029620 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 20 40514 0.019480 0.071780 0.0237250 0.0032490 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 21 40515 0.017380 0.070880 0.0229482 0.0034950 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 22 40516 0.015380 0.070180 0.0219574 0.0036380 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 23 40517 0.013381 0.069381 0.0208965 0.0036500 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 24 40518 0.011381 0.068681 0.0198817 0.0035300 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 25 40519 0.009381 0.068081 0.0190409 0.0033080 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 26 40520 0.007382 0.067482 0.0184721 0.0030270 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 27 40521 0.005382 0.066882 0.0181852 0.0027530 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 28 40522 0.003482 0.066382 0.0181394 0.0025310 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 29 40523 0.001482 0.065882 0.0182876 0.0023770 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 30 40524 -0.000517 0.065483 0.0185378 0.0023190 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 10 31 40525 -0.002517 0.065083 0.0188129 0.0023340 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 1 40526 -0.004517 0.064683 0.0190361 0.0024190 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 2 40527 -0.006617 0.064383 0.0191373 0.0025660 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 3 40528 -0.008616 0.064084 0.0190745 0.0027420 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 4 40529 -0.010716 0.063884 0.0188326 0.0029100 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 5 40530 -0.012716 0.063684 0.0184528 0.0030540 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 6 40531 -0.014815 0.063485 0.0179330 0.0031640 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 7 40532 -0.017015 0.063385 0.0173331 0.0031900 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 8 40533 -0.019115 0.063285 0.0167673 0.0031240 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 9 40534 -0.021315 0.063285 0.0163105 0.0029660 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 10 40535 -0.023514 0.063186 0.0160487 0.0027410 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 11 40536 -0.025814 0.063186 0.0160098 0.0025140 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 12 40537 -0.028014 0.063286 0.0161770 0.0023680 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 13 40538 -0.030414 0.063286 0.0164312 0.0023500 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 14 40539 -0.032713 0.063387 0.0166194 0.0024850 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 15 40540 -0.035113 0.063487 0.0166025 0.0027330 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 16 40541 -0.037513 0.063687 0.0163177 0.0030180 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 17 40542 -0.039912 0.063788 0.0157549 0.0032890 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 18 40543 -0.042412 0.063988 0.0149601 0.0034640 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 19 40544 -0.045012 0.064288 0.0140462 0.0035330 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 20 40545 -0.047512 0.064488 0.0131244 0.0034710 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 21 40546 -0.050111 0.064789 0.0123166 0.0033130 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 22 40547 -0.052711 0.065089 0.0117088 0.0030870 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 23 40548 -0.055411 0.065389 0.0113249 0.0028530 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 24 40549 -0.058111 0.065789 0.0111621 0.0026520 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 25 40550 -0.060810 0.066190 0.0111893 0.0025080 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 26 40551 -0.063610 0.066590 0.0112995 0.0024450 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 27 40552 -0.066410 0.066990 0.0114416 0.0024650 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 28 40553 -0.069209 0.067491 0.0115248 0.0025590 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 29 40554 -0.072109 0.067991 0.0114840 0.0027090 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 11 30 40555 -0.075009 0.068591 0.0112761 0.0028910 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 1 40556 -0.077909 0.069191 0.0108913 0.0030700 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 2 40557 -0.080808 0.069892 0.0103335 0.0032310 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 3 40558 -0.083708 0.070592 0.0096227 0.0033520 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 4 40559 -0.086708 0.071392 0.0088408 0.0033980 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 5 40560 -0.089708 0.072192 0.0080450 0.0033590 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 6 40561 -0.092707 0.072993 0.0073362 0.0032230 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 7 40562 -0.095707 0.073993 0.0068064 0.0030060 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 8 40563 -0.098707 0.074993 0.0065155 0.0027540 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 9 40564 -0.101806 0.075994 0.0064657 0.0025390 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 10 40565 -0.104806 0.077094 0.0065909 0.0024240 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 11 40566 -0.107906 0.078294 0.0067471 0.0024690 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 12 40567 -0.110906 0.079594 0.0067962 0.0026520 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 13 40568 -0.114005 0.080895 0.0066094 0.0029080 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 14 40569 -0.117005 0.082295 0.0061756 0.0031510 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 15 40570 -0.120005 0.083795 0.0055277 0.0033060 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 16 40571 -0.123105 0.085295 0.0047869 0.0033320 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 17 40572 -0.126104 0.086896 0.0040861 0.0032410 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 18 40573 -0.129104 0.088596 0.0035193 0.0030520 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 19 40574 -0.132104 0.090396 0.0031714 0.0028190 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 20 40575 -0.135003 0.092297 0.0030736 0.0025670 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 21 40576 -0.138003 0.094197 0.0032068 0.0023540 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 22 40577 -0.140903 0.096197 0.0035260 0.0021990 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 23 40578 -0.143803 0.098297 0.0039641 0.0021290 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 24 40579 -0.146602 0.100498 0.0044313 0.0021300 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 25 40580 -0.149402 0.102698 0.0048585 0.0022170 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 26 40581 -0.152202 0.104998 0.0051586 0.0023630 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 27 40582 -0.155001 0.107399 0.0053008 0.0025460 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 28 40583 -0.157701 0.109799 0.0052430 0.0027490 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 29 40584 -0.160301 0.112299 0.0049992 0.0029360 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 30 40585 -0.162901 0.114799 0.0045843 0.0030750 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1969 12 31 40586 -0.165500 0.117400 0.0040385 0.0031680 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 1 40587 -0.168000 0.120100 0.0034537 0.0031890 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 2 40588 -0.170400 0.122700 0.0028768 0.0031300 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 3 40589 -0.172800 0.125500 0.0024100 0.0029930 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 4 40590 -0.175099 0.128201 0.0020982 0.0027960 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 5 40591 -0.177399 0.131001 0.0019874 0.0026130 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 6 40592 -0.179499 0.133901 0.0020255 0.0025080 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 7 40593 -0.181598 0.136702 0.0020947 0.0025510 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 8 40594 -0.183698 0.139602 0.0020619 0.0027490 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 9 40595 -0.185598 0.142502 0.0017580 0.0030510 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 10 40596 -0.187498 0.145402 0.0011312 0.0033790 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 11 40597 -0.189297 0.148303 0.0002054 0.0036250 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 12 40598 -0.190997 0.151303 -0.0009004 0.0037300 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 13 40599 -0.192597 0.154203 -0.0020213 0.0036780 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 14 40600 -0.194097 0.157203 -0.0030251 0.0034920 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 15 40601 -0.195496 0.160204 -0.0038119 0.0032380 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 16 40602 -0.196896 0.163204 -0.0043268 0.0029730 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 17 40603 -0.198096 0.166104 -0.0045796 0.0027310 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 18 40604 -0.199195 0.169105 -0.0046194 0.0025400 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 19 40605 -0.200295 0.172105 -0.0045052 0.0024240 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 20 40606 -0.201195 0.175105 -0.0043141 0.0023870 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 21 40607 -0.201995 0.178105 -0.0041249 0.0024380 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 22 40608 -0.202794 0.181006 -0.0040207 0.0025530 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 23 40609 -0.203394 0.184006 -0.0040546 0.0027000 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 24 40610 -0.203894 0.187006 -0.0042464 0.0028640 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 25 40611 -0.204294 0.190006 -0.0045982 0.0030250 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 26 40612 -0.204593 0.192907 -0.0051040 0.0031480 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 27 40613 -0.204793 0.195907 -0.0056949 0.0032140 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 28 40614 -0.204893 0.198907 -0.0063277 0.0032090 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 29 40615 -0.204892 0.201808 -0.0069185 0.0031410 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 30 40616 -0.204792 0.204808 -0.0073964 0.0030040 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 1 31 40617 -0.204592 0.207808 -0.0077092 0.0028070 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 1 40618 -0.204292 0.210808 -0.0078360 0.0026180 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 2 40619 -0.203891 0.213709 -0.0077718 0.0024680 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 3 40620 -0.203391 0.216709 -0.0076177 0.0024380 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 4 40621 -0.202891 0.219709 -0.0075085 0.0025600 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 5 40622 -0.202191 0.222709 -0.0075953 0.0028230 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 6 40623 -0.201490 0.225710 -0.0079912 0.0031640 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 7 40624 -0.200690 0.228710 -0.0087440 0.0035000 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 8 40625 -0.199790 0.231710 -0.0097708 0.0037070 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 9 40626 -0.198789 0.234711 -0.0109197 0.0037510 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 10 40627 -0.197789 0.237811 -0.0120165 0.0036190 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 11 40628 -0.196689 0.240811 -0.0129313 0.0033780 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 12 40629 -0.195589 0.243811 -0.0135811 0.0031110 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 13 40630 -0.194388 0.246912 -0.0139820 0.0028710 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 14 40631 -0.193088 0.249912 -0.0141648 0.0026870 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 15 40632 -0.191888 0.252912 -0.0141926 0.0025840 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 16 40633 -0.190588 0.256012 -0.0141595 0.0025550 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 17 40634 -0.189287 0.259013 -0.0141503 0.0026060 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 18 40635 -0.187887 0.262013 -0.0142251 0.0027260 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 19 40636 -0.186587 0.265013 -0.0144380 0.0028960 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 20 40637 -0.185186 0.268014 -0.0148348 0.0030810 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 21 40638 -0.183786 0.271014 -0.0154076 0.0032520 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 22 40639 -0.182486 0.274014 -0.0161464 0.0033890 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 23 40640 -0.181086 0.277014 -0.0169763 0.0034590 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 24 40641 -0.179685 0.279915 -0.0178601 0.0034660 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 25 40642 -0.178385 0.282815 -0.0187009 0.0033940 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 26 40643 -0.177085 0.285715 -0.0194448 0.0032510 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 27 40644 -0.175785 0.288615 -0.0200056 0.0030470 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 2 28 40645 -0.174484 0.291516 -0.0203424 0.0028280 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 1 40646 -0.173184 0.294316 -0.0204913 0.0026510 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 2 40647 -0.171984 0.297116 -0.0205041 0.0025720 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 3 40648 -0.170783 0.299817 -0.0204879 0.0026130 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 4 40649 -0.169583 0.302617 -0.0205968 0.0028080 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 5 40650 -0.168383 0.305317 -0.0209506 0.0031030 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 6 40651 -0.167283 0.307917 -0.0216334 0.0034390 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 7 40652 -0.166182 0.310618 -0.0226263 0.0037070 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 8 40653 -0.165082 0.313218 -0.0238261 0.0038340 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 9 40654 -0.163982 0.315718 -0.0250429 0.0037810 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 10 40655 -0.162882 0.318318 -0.0261357 0.0035640 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 11 40656 -0.161881 0.320819 -0.0269736 0.0032740 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 12 40657 -0.160781 0.323219 -0.0275134 0.0029900 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 13 40658 -0.159781 0.325619 -0.0277832 0.0027520 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 14 40659 -0.158680 0.328020 -0.0278671 0.0026100 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 15 40660 -0.157680 0.330320 -0.0278449 0.0025610 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 16 40661 -0.156680 0.332620 -0.0278167 0.0025870 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 17 40662 -0.155580 0.334920 -0.0278636 0.0026970 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 18 40663 -0.154479 0.337121 -0.0280484 0.0028620 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 19 40664 -0.153479 0.339221 -0.0284192 0.0030620 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 20 40665 -0.152279 0.341421 -0.0289941 0.0032680 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 21 40666 -0.151178 0.343522 -0.0297669 0.0034510 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 22 40667 -0.149978 0.345522 -0.0306997 0.0035850 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 23 40668 -0.148778 0.347522 -0.0317326 0.0036470 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 24 40669 -0.147578 0.349522 -0.0327954 0.0036260 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 25 40670 -0.146277 0.351423 -0.0337862 0.0035240 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 26 40671 -0.144977 0.353323 -0.0346421 0.0033610 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 27 40672 -0.143577 0.355123 -0.0353199 0.0031740 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 28 40673 -0.142177 0.356923 -0.0358067 0.0030000 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 29 40674 -0.140676 0.358624 -0.0361546 0.0029120 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 30 40675 -0.139176 0.360424 -0.0364784 0.0029280 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 3 31 40676 -0.137576 0.362024 -0.0368742 0.0030760 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 1 40677 -0.135875 0.363625 -0.0374681 0.0033280 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 2 40678 -0.134175 0.365225 -0.0383619 0.0036420 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 3 40679 -0.132375 0.366725 -0.0395647 0.0039250 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 4 40680 -0.130575 0.368225 -0.0409965 0.0041050 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 5 40681 -0.128674 0.369726 -0.0425404 0.0041250 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 6 40682 -0.126674 0.371126 -0.0440112 0.0039910 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 7 40683 -0.124674 0.372426 -0.0452810 0.0037240 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 8 40684 -0.122674 0.373726 -0.0462539 0.0034100 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 9 40685 -0.120473 0.375027 -0.0469197 0.0031110 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 10 40686 -0.118373 0.376227 -0.0473315 0.0028980 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 11 40687 -0.116073 0.377427 -0.0475574 0.0027710 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 12 40688 -0.113772 0.378628 -0.0477252 0.0027480 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 13 40689 -0.111472 0.379728 -0.0479010 0.0027960 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 14 40690 -0.109072 0.380828 -0.0481459 0.0029040 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 15 40691 -0.106672 0.381828 -0.0485307 0.0030520 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 16 40692 -0.104171 0.382829 -0.0490735 0.0032140 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 17 40693 -0.101671 0.383829 -0.0497754 0.0033650 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 18 40694 -0.099071 0.384729 -0.0506112 0.0034880 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 19 40695 -0.096471 0.385629 -0.0515410 0.0035390 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 20 40696 -0.093870 0.386530 -0.0524819 0.0035210 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 21 40697 -0.091170 0.387430 -0.0533627 0.0034070 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 22 40698 -0.088470 0.388230 -0.0540915 0.0032300 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 23 40699 -0.085769 0.389031 -0.0546174 0.0030110 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 24 40700 -0.083069 0.389731 -0.0549252 0.0028010 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 25 40701 -0.080269 0.390531 -0.0550521 0.0026460 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 26 40702 -0.077469 0.391231 -0.0550739 0.0026100 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 27 40703 -0.074668 0.391932 -0.0551337 0.0027100 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 28 40704 -0.071868 0.392632 -0.0553426 0.0029130 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 29 40705 -0.068968 0.393232 -0.0558004 0.0031910 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 4 30 40706 -0.066168 0.393932 -0.0565332 0.0034580 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 1 40707 -0.063267 0.394533 -0.0575021 0.0036540 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 2 40708 -0.060367 0.395133 -0.0586069 0.0037240 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 3 40709 -0.057467 0.395733 -0.0597197 0.0036460 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 4 40710 -0.054566 0.396334 -0.0606756 0.0034400 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 5 40711 -0.051666 0.396834 -0.0613934 0.0031580 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 6 40712 -0.048666 0.397434 -0.0618092 0.0028570 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 7 40713 -0.045766 0.397934 -0.0619461 0.0026180 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 8 40714 -0.042765 0.398435 -0.0618749 0.0024460 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 9 40715 -0.039765 0.398935 -0.0616907 0.0023820 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 10 40716 -0.036865 0.399435 -0.0614876 0.0024050 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 11 40717 -0.033865 0.399935 -0.0613444 0.0024970 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 12 40718 -0.030864 0.400336 -0.0613062 0.0026330 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 13 40719 -0.027864 0.400736 -0.0614171 0.0027790 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 14 40720 -0.024864 0.401136 -0.0616819 0.0029300 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 15 40721 -0.021763 0.401537 -0.0620757 0.0030510 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 16 40722 -0.018763 0.401937 -0.0625666 0.0031210 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 17 40723 -0.015663 0.402237 -0.0631044 0.0031230 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 18 40724 -0.012663 0.402637 -0.0635953 0.0030450 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 19 40725 -0.009562 0.402838 -0.0639891 0.0029000 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 20 40726 -0.006462 0.403138 -0.0641849 0.0026870 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 21 40727 -0.003362 0.403338 -0.0641678 0.0024700 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 22 40728 -0.000162 0.403538 -0.0639506 0.0022890 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 23 40729 0.002939 0.403739 -0.0635994 0.0022190 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 24 40730 0.006039 0.403939 -0.0632423 0.0022710 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 25 40731 0.009239 0.404039 -0.0630021 0.0024550 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 26 40732 0.012440 0.404040 -0.0629859 0.0027010 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 27 40733 0.015640 0.404140 -0.0632248 0.0029610 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 28 40734 0.018840 0.404040 -0.0636956 0.0031440 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 29 40735 0.022040 0.404040 -0.0642934 0.0032220 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 30 40736 0.025241 0.403941 -0.0649153 0.0031680 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 5 31 40737 0.028541 0.403841 -0.0654091 0.0029940 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 1 40738 0.031741 0.403641 -0.0656870 0.0027420 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 2 40739 0.035041 0.403441 -0.0656948 0.0024760 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 3 40740 0.038342 0.403142 -0.0654586 0.0022400 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 4 40741 0.041542 0.402842 -0.0650195 0.0020660 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 5 40742 0.044842 0.402442 -0.0644423 0.0019840 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 6 40743 0.048143 0.402043 -0.0638391 0.0019940 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 7 40744 0.051443 0.401643 -0.0632740 0.0020780 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 8 40745 0.054743 0.401143 -0.0628328 0.0022150 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 9 40746 0.058043 0.400543 -0.0625327 0.0023760 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 10 40747 0.061344 0.399944 -0.0623935 0.0025260 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 11 40748 0.064644 0.399244 -0.0623843 0.0026400 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 12 40749 0.067944 0.398544 -0.0624682 0.0027090 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 13 40750 0.071245 0.397745 -0.0625910 0.0027080 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 14 40751 0.074445 0.396945 -0.0626788 0.0026480 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 15 40752 0.077745 0.396045 -0.0626817 0.0025250 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 16 40753 0.081045 0.395145 -0.0625185 0.0023300 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 17 40754 0.084246 0.394146 -0.0621414 0.0021030 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 18 40755 0.087446 0.393046 -0.0615502 0.0018950 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 19 40756 0.090646 0.391946 -0.0607780 0.0017780 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 20 40757 0.093846 0.390746 -0.0599599 0.0017900 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 21 40758 0.096947 0.389547 -0.0592147 0.0019430 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 22 40759 0.100047 0.388247 -0.0586875 0.0021950 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 23 40760 0.103147 0.386847 -0.0584224 0.0024690 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 24 40761 0.106248 0.385448 -0.0584152 0.0026800 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 25 40762 0.109248 0.383948 -0.0585601 0.0027760 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 26 40763 0.112248 0.382448 -0.0587379 0.0027270 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 27 40764 0.115148 0.380848 -0.0587907 0.0025620 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 28 40765 0.118149 0.379149 -0.0586466 0.0023200 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 29 40766 0.120949 0.377449 -0.0582324 0.0020440 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 6 30 40767 0.123849 0.375649 -0.0575622 0.0018040 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 1 40768 0.126649 0.373749 -0.0566821 0.0016280 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 2 40769 0.129350 0.371850 -0.0556659 0.0015360 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 3 40770 0.132050 0.369850 -0.0546038 0.0015440 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 4 40771 0.134750 0.367850 -0.0535906 0.0016210 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 5 40772 0.137351 0.365751 -0.0526744 0.0017560 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 6 40773 0.139951 0.363551 -0.0519243 0.0019240 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 7 40774 0.142451 0.361351 -0.0513341 0.0020950 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 8 40775 0.144951 0.359051 -0.0509070 0.0022440 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 9 40776 0.147352 0.356752 -0.0506178 0.0023390 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 10 40777 0.149752 0.354352 -0.0503956 0.0023870 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 11 40778 0.152152 0.351952 -0.0501795 0.0023610 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 12 40779 0.154452 0.349552 -0.0499143 0.0022790 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 13 40780 0.156653 0.347053 -0.0495272 0.0021290 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 14 40781 0.158853 0.344453 -0.0489700 0.0019400 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 15 40782 0.161053 0.341853 -0.0482178 0.0017400 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 16 40783 0.163154 0.339254 -0.0472867 0.0016030 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 17 40784 0.165254 0.336554 -0.0462805 0.0015770 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 18 40785 0.167254 0.333854 -0.0452984 0.0016850 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 19 40786 0.169154 0.331154 -0.0445142 0.0019340 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 20 40787 0.171055 0.328355 -0.0439980 0.0022380 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 21 40788 0.172955 0.325555 -0.0437999 0.0025200 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 22 40789 0.174755 0.322755 -0.0438077 0.0026700 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 23 40790 0.176555 0.319855 -0.0439026 0.0026620 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 24 40791 0.178256 0.317056 -0.0438974 0.0024850 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 25 40792 0.179856 0.314156 -0.0436582 0.0022050 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 26 40793 0.181456 0.311256 -0.0431171 0.0019020 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 27 40794 0.183057 0.308257 -0.0422829 0.0016080 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 28 40795 0.184557 0.305357 -0.0411848 0.0013910 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 29 40796 0.185957 0.302357 -0.0399136 0.0012710 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 30 40797 0.187357 0.299457 -0.0385574 0.0012310 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 7 31 40798 0.188758 0.296458 -0.0372223 0.0012800 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 1 40799 0.190058 0.293458 -0.0359591 0.0013930 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 2 40800 0.191258 0.290458 -0.0348310 0.0015350 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 3 40801 0.192458 0.287458 -0.0338628 0.0017090 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 4 40802 0.193559 0.284559 -0.0330526 0.0018650 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 5 40803 0.194659 0.281559 -0.0323895 0.0019900 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 6 40804 0.195759 0.278559 -0.0318233 0.0020570 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 7 40805 0.196660 0.275560 -0.0312912 0.0020590 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 8 40806 0.197660 0.272560 -0.0307280 0.0019960 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 9 40807 0.198560 0.269560 -0.0300848 0.0018880 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 10 40808 0.199360 0.266560 -0.0293117 0.0017420 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 11 40809 0.200161 0.263661 -0.0283955 0.0015970 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 12 40810 0.200861 0.260661 -0.0273354 0.0014840 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 13 40811 0.201561 0.257661 -0.0262112 0.0014550 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 14 40812 0.202261 0.254661 -0.0251001 0.0015460 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 15 40813 0.202862 0.251662 -0.0241709 0.0017890 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 16 40814 0.203362 0.248662 -0.0235327 0.0021380 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 17 40815 0.203862 0.245662 -0.0232736 0.0025090 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 18 40816 0.204363 0.242663 -0.0233434 0.0027870 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 19 40817 0.204763 0.239663 -0.0236133 0.0029120 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 20 40818 0.205163 0.236663 -0.0239121 0.0028370 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 21 40819 0.205463 0.233663 -0.0240560 0.0026010 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 22 40820 0.205764 0.230564 -0.0239108 0.0022920 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 23 40821 0.206064 0.227564 -0.0234636 0.0019930 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 24 40822 0.206264 0.224464 -0.0227495 0.0017640 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 25 40823 0.206464 0.221364 -0.0218543 0.0016320 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 26 40824 0.206565 0.218265 -0.0208672 0.0015990 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 27 40825 0.206665 0.215165 -0.0198900 0.0016510 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 28 40826 0.206765 0.211965 -0.0190009 0.0017690 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 29 40827 0.206766 0.208866 -0.0182537 0.0019330 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 30 40828 0.206766 0.205666 -0.0176815 0.0021150 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 8 31 40829 0.206666 0.202466 -0.0172894 0.0022890 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 1 40830 0.206566 0.199266 -0.0170662 0.0024270 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 2 40831 0.206467 0.195967 -0.0169441 0.0025190 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 3 40832 0.206267 0.192767 -0.0168809 0.0025330 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 4 40833 0.206067 0.189467 -0.0168078 0.0024790 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 5 40834 0.205768 0.186168 -0.0166396 0.0023660 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 6 40835 0.205468 0.182868 -0.0163464 0.0022120 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 7 40836 0.205168 0.179568 -0.0158903 0.0020560 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 8 40837 0.204768 0.176268 -0.0152761 0.0019140 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 9 40838 0.204269 0.172869 -0.0145590 0.0018470 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 10 40839 0.203869 0.169569 -0.0138248 0.0018870 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 11 40840 0.203269 0.166169 -0.0131977 0.0020600 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 12 40841 0.202769 0.162869 -0.0127955 0.0023450 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 13 40842 0.202070 0.159470 -0.0127284 0.0027060 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 14 40843 0.201470 0.156070 -0.0130192 0.0030420 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 15 40844 0.200670 0.152670 -0.0135910 0.0032670 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 16 40845 0.199971 0.149271 -0.0142999 0.0032990 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 17 40846 0.199071 0.145871 -0.0149467 0.0031460 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 18 40847 0.198171 0.142571 -0.0153696 0.0028670 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 19 40848 0.197271 0.139171 -0.0154874 0.0025600 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 20 40849 0.196272 0.135772 -0.0153163 0.0022900 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 21 40850 0.195172 0.132472 -0.0149301 0.0021280 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 22 40851 0.194072 0.129172 -0.0144290 0.0020670 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 23 40852 0.192872 0.125772 -0.0139068 0.0021040 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 24 40853 0.191673 0.122473 -0.0134706 0.0022160 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 25 40854 0.190373 0.119173 -0.0131645 0.0023680 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 26 40855 0.188973 0.115973 -0.0130343 0.0025550 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 27 40856 0.187474 0.112674 -0.0130922 0.0027310 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 28 40857 0.185974 0.109474 -0.0133070 0.0028810 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 29 40858 0.184474 0.106274 -0.0136469 0.0029710 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 9 30 40859 0.182774 0.103174 -0.0140467 0.0029960 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 1 40860 0.181075 0.099975 -0.0144246 0.0029390 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 2 40861 0.179275 0.096875 -0.0147224 0.0028260 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 3 40862 0.177375 0.093875 -0.0148813 0.0026650 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 4 40863 0.175475 0.090875 -0.0148651 0.0024930 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 5 40864 0.173476 0.087876 -0.0146829 0.0023180 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 6 40865 0.171376 0.084976 -0.0143398 0.0022100 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 7 40866 0.169276 0.082076 -0.0139526 0.0022050 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 8 40867 0.167077 0.079277 -0.0136195 0.0023280 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 9 40868 0.164777 0.076477 -0.0134583 0.0025680 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 10 40869 0.162377 0.073777 -0.0135922 0.0028790 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 11 40870 0.159977 0.071077 -0.0140520 0.0032260 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 12 40871 0.157478 0.068478 -0.0148319 0.0034950 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 13 40872 0.154878 0.065978 -0.0158127 0.0036300 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 14 40873 0.152278 0.063578 -0.0168526 0.0035880 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 15 40874 0.149578 0.061178 -0.0177574 0.0033900 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 16 40875 0.146779 0.058779 -0.0184123 0.0031040 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 17 40876 0.143879 0.056579 -0.0187761 0.0028200 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 18 40877 0.140979 0.054379 -0.0188870 0.0025990 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 19 40878 0.138080 0.052280 -0.0188408 0.0024990 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 20 40879 0.135080 0.050280 -0.0187417 0.0025110 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 21 40880 0.131980 0.048280 -0.0186915 0.0026000 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 22 40881 0.128880 0.046380 -0.0187723 0.0027490 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 23 40882 0.125681 0.044581 -0.0190202 0.0029190 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 24 40883 0.122481 0.042781 -0.0194410 0.0031030 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 25 40884 0.119181 0.041181 -0.0200199 0.0032490 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 26 40885 0.115981 0.039481 -0.0207347 0.0033530 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 27 40886 0.112582 0.037982 -0.0215266 0.0034090 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 28 40887 0.109282 0.036482 -0.0223314 0.0033870 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 29 40888 0.105882 0.035082 -0.0230973 0.0033060 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 30 40889 0.102483 0.033683 -0.0237431 0.0031580 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 10 31 40890 0.098983 0.032383 -0.0242210 0.0029870 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 1 40891 0.095583 0.031083 -0.0245278 0.0028200 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 2 40892 0.092083 0.029883 -0.0246967 0.0027000 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 3 40893 0.088684 0.028684 -0.0247775 0.0026690 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 4 40894 0.085184 0.027484 -0.0248814 0.0027490 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 5 40895 0.081684 0.026384 -0.0251212 0.0029390 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 6 40896 0.078184 0.025284 -0.0255971 0.0032010 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 7 40897 0.074685 0.024285 -0.0263529 0.0034900 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 8 40898 0.071185 0.023185 -0.0273738 0.0037380 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 9 40899 0.067785 0.022185 -0.0286026 0.0038700 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 10 40900 0.064286 0.021186 -0.0298945 0.0038660 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 11 40901 0.060786 0.020186 -0.0310953 0.0036930 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 12 40902 0.057386 0.019286 -0.0320642 0.0034220 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 13 40903 0.053986 0.018286 -0.0327370 0.0031030 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 14 40904 0.050487 0.017287 -0.0331039 0.0028220 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 15 40905 0.047087 0.016387 -0.0332317 0.0026330 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 16 40906 0.043687 0.015387 -0.0332256 0.0025550 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 17 40907 0.040287 0.014487 -0.0331844 0.0025770 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 18 40908 0.036988 0.013588 -0.0332153 0.0026710 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 19 40909 0.033588 0.012588 -0.0333491 0.0028040 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 20 40910 0.030288 0.011688 -0.0336360 0.0029470 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 21 40911 0.026989 0.010789 -0.0340578 0.0030840 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 22 40912 0.023689 0.009889 -0.0346117 0.0031870 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 23 40913 0.020389 0.009089 -0.0352345 0.0032380 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 24 40914 0.017089 0.008189 -0.0358764 0.0032260 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 25 40915 0.013890 0.007390 -0.0364742 0.0031490 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 26 40916 0.010690 0.006590 -0.0369651 0.0030040 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 27 40917 0.007490 0.005790 -0.0372989 0.0028270 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 28 40918 0.004390 0.005090 -0.0374348 0.0026380 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 29 40919 0.001191 0.004291 -0.0374046 0.0024810 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 11 30 40920 -0.001909 0.003691 -0.0372435 0.0024020 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 1 40921 -0.005009 0.002991 -0.0370663 0.0024340 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 2 40922 -0.008108 0.002392 -0.0369702 0.0025830 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 3 40923 -0.011208 0.001892 -0.0370710 0.0028100 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 4 40924 -0.014208 0.001392 -0.0374199 0.0030780 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 5 40925 -0.017208 0.000992 -0.0380237 0.0032970 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 6 40926 -0.020207 0.000593 -0.0388016 0.0034200 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 7 40927 -0.023207 0.000293 -0.0396394 0.0034120 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 8 40928 -0.026207 -0.000007 -0.0404023 0.0032710 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 9 40929 -0.029106 -0.000206 -0.0409671 0.0030280 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 10 40930 -0.032106 -0.000306 -0.0412510 0.0027360 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 11 40931 -0.035006 -0.000306 -0.0412448 0.0024490 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 12 40932 -0.037806 -0.000306 -0.0409917 0.0022410 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 13 40933 -0.040705 -0.000205 -0.0405805 0.0021230 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 14 40934 -0.043605 -0.000005 -0.0401024 0.0021170 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 15 40935 -0.046405 0.000295 -0.0396423 0.0021840 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 16 40936 -0.049305 0.000595 -0.0392971 0.0023120 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 17 40937 -0.052104 0.001096 -0.0390900 0.0024560 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 18 40938 -0.054904 0.001596 -0.0390248 0.0025990 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 19 40939 -0.057704 0.002196 -0.0390867 0.0027180 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 20 40940 -0.060503 0.002797 -0.0392635 0.0027980 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 21 40941 -0.063303 0.003597 -0.0394834 0.0028200 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 22 40942 -0.066103 0.004397 -0.0397032 0.0027910 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 23 40943 -0.068903 0.005397 -0.0398551 0.0026950 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 24 40944 -0.071602 0.006398 -0.0398989 0.0025760 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 25 40945 -0.074402 0.007398 -0.0398198 0.0024360 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 26 40946 -0.077202 0.008598 -0.0395856 0.0023000 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 27 40947 -0.079902 0.009898 -0.0392505 0.0022250 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 28 40948 -0.082701 0.011199 -0.0388893 0.0022530 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 29 40949 -0.085501 0.012599 -0.0386082 0.0024060 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 30 40950 -0.088201 0.014099 -0.0385581 0.0026790 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1970 12 31 40951 -0.091000 0.015600 -0.0387929 0.0029840 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 1 40952 -0.093700 0.017300 -0.0393358 0.0032610 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 2 40953 -0.096500 0.019000 -0.0401116 0.0034370 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 3 40954 -0.099200 0.020800 -0.0409825 0.0034690 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 4 40955 -0.101999 0.022601 -0.0418123 0.0033490 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 5 40956 -0.104799 0.024501 -0.0424642 0.0031230 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 6 40957 -0.107499 0.026501 -0.0428610 0.0028490 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 7 40958 -0.110199 0.028601 -0.0429859 0.0025880 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 8 40959 -0.112998 0.030702 -0.0428777 0.0023790 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 9 40960 -0.115698 0.032902 -0.0425946 0.0022600 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 10 40961 -0.118498 0.035102 -0.0422525 0.0022510 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 11 40962 -0.121197 0.037403 -0.0419353 0.0023190 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 12 40963 -0.123997 0.039703 -0.0417292 0.0024470 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 13 40964 -0.126697 0.042103 -0.0416590 0.0026130 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 14 40965 -0.129397 0.044503 -0.0417639 0.0027650 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 15 40966 -0.132196 0.047004 -0.0419977 0.0028860 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 16 40967 -0.134896 0.049504 -0.0423386 0.0029580 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 17 40968 -0.137596 0.052104 -0.0427144 0.0029710 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 18 40969 -0.140296 0.054704 -0.0430813 0.0029330 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 19 40970 -0.142995 0.057305 -0.0433712 0.0028290 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 20 40971 -0.145795 0.060005 -0.0435340 0.0026820 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 21 40972 -0.148495 0.062705 -0.0435359 0.0025100 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 22 40973 -0.151194 0.065406 -0.0433647 0.0023420 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 23 40974 -0.153894 0.068106 -0.0430436 0.0022060 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 24 40975 -0.156594 0.070906 -0.0426344 0.0021650 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 25 40976 -0.159294 0.073706 -0.0422343 0.0022460 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 26 40977 -0.161993 0.076507 -0.0419791 0.0024450 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 27 40978 -0.164593 0.079407 -0.0419730 0.0027430 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 28 40979 -0.167293 0.082207 -0.0422789 0.0030410 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 29 40980 -0.169893 0.085107 -0.0428477 0.0032560 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 30 40981 -0.172492 0.088008 -0.0435596 0.0033170 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 1 31 40982 -0.175092 0.090908 -0.0442434 0.0032140 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 1 40983 -0.177692 0.093808 -0.0447403 0.0029620 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 2 40984 -0.180291 0.096809 -0.0449541 0.0026410 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 3 40985 -0.182791 0.099709 -0.0448450 0.0023380 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 4 40986 -0.185291 0.102709 -0.0444619 0.0020990 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 5 40987 -0.187791 0.105609 -0.0438847 0.0019550 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 6 40988 -0.190190 0.108610 -0.0432156 0.0019130 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 7 40989 -0.192690 0.111610 -0.0425604 0.0019700 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 8 40990 -0.194990 0.114610 -0.0419873 0.0020930 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 9 40991 -0.197390 0.117610 -0.0415702 0.0022440 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 10 40992 -0.199689 0.120711 -0.0413080 0.0024120 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 11 40993 -0.201989 0.123711 -0.0412049 0.0025560 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 12 40994 -0.204189 0.126811 -0.0412247 0.0026650 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 13 40995 -0.206388 0.129812 -0.0413136 0.0027040 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 14 40996 -0.208488 0.132912 -0.0414204 0.0026780 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 15 40997 -0.210588 0.135912 -0.0414793 0.0025930 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 16 40998 -0.212588 0.139012 -0.0414202 0.0024720 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 17 40999 -0.214587 0.142113 -0.0412240 0.0023040 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 18 41000 -0.216487 0.145213 -0.0408469 0.0021440 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 19 41001 -0.218287 0.148413 -0.0403297 0.0020220 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 20 41002 -0.220087 0.151513 -0.0397226 0.0019560 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 21 41003 -0.221886 0.154614 -0.0390985 0.0020060 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 22 41004 -0.223486 0.157814 -0.0385973 0.0021830 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 23 41005 -0.225086 0.161014 -0.0383242 0.0024770 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 24 41006 -0.226585 0.164115 -0.0383810 0.0028400 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 25 41007 -0.228085 0.167415 -0.0387929 0.0031690 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 26 41008 -0.229485 0.170615 -0.0394858 0.0033810 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 27 41009 -0.230785 0.173815 -0.0403006 0.0034060 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 2 28 41010 -0.231984 0.177116 -0.0410565 0.0032600 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 1 41011 -0.233084 0.180316 -0.0416003 0.0029950 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 2 41012 -0.234184 0.183616 -0.0418482 0.0027020 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 3 41013 -0.235083 0.186917 -0.0418231 0.0024630 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 4 41014 -0.235983 0.190317 -0.0416169 0.0023350 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 5 41015 -0.236783 0.193617 -0.0413508 0.0023200 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 6 41016 -0.237483 0.197017 -0.0410996 0.0023940 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 7 41017 -0.238082 0.200418 -0.0409725 0.0025500 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 8 41018 -0.238682 0.203918 -0.0410244 0.0027390 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 9 41019 -0.239082 0.207318 -0.0412642 0.0029420 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 10 41020 -0.239382 0.210818 -0.0417231 0.0031330 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 11 41021 -0.239681 0.214319 -0.0423469 0.0032860 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 12 41022 -0.239881 0.217819 -0.0430968 0.0033830 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 13 41023 -0.239881 0.221419 -0.0439007 0.0034050 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 14 41024 -0.239880 0.224920 -0.0446955 0.0033540 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 15 41025 -0.239780 0.228520 -0.0454114 0.0032500 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 16 41026 -0.239680 0.232120 -0.0460053 0.0031040 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 17 41027 -0.239380 0.235720 -0.0464471 0.0029610 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 18 41028 -0.238979 0.239321 -0.0467430 0.0028280 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 19 41029 -0.238579 0.243021 -0.0469308 0.0027390 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 20 41030 -0.238079 0.246621 -0.0470687 0.0027350 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 21 41031 -0.237579 0.250221 -0.0472596 0.0028540 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 22 41032 -0.236978 0.253822 -0.0476264 0.0030810 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 23 41033 -0.236278 0.257522 -0.0482703 0.0034070 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 24 41034 -0.235478 0.261122 -0.0492471 0.0037430 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 25 41035 -0.234677 0.264723 -0.0505520 0.0040160 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 26 41036 -0.233877 0.268323 -0.0520369 0.0041230 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 27 41037 -0.232977 0.271823 -0.0535437 0.0040390 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 28 41038 -0.231977 0.275423 -0.0548786 0.0037890 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 29 41039 -0.231076 0.278924 -0.0559035 0.0034450 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 30 41040 -0.230076 0.282424 -0.0565833 0.0031130 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 3 31 41041 -0.228976 0.285924 -0.0569792 0.0028800 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 1 41042 -0.227976 0.289424 -0.0571931 0.0027580 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 2 41043 -0.226875 0.292825 -0.0573539 0.0027510 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 3 41044 -0.225775 0.296125 -0.0575438 0.0028290 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 4 41045 -0.224675 0.299525 -0.0578476 0.0029560 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 5 41046 -0.223474 0.302826 -0.0582805 0.0031010 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 6 41047 -0.222374 0.306026 -0.0588664 0.0032400 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 7 41048 -0.221174 0.309226 -0.0595802 0.0033500 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 8 41049 -0.220074 0.312326 -0.0603691 0.0034110 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 9 41050 -0.218873 0.315427 -0.0612010 0.0034210 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 10 41051 -0.217673 0.318527 -0.0619998 0.0033570 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 11 41052 -0.216473 0.321527 -0.0627157 0.0032360 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 12 41053 -0.215373 0.324427 -0.0632786 0.0030760 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 13 41054 -0.214172 0.327328 -0.0636824 0.0029010 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 14 41055 -0.212972 0.330228 -0.0639153 0.0027500 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 15 41056 -0.211772 0.333028 -0.0640082 0.0026350 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 16 41057 -0.210571 0.335729 -0.0640210 0.0025960 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 17 41058 -0.209371 0.338429 -0.0640409 0.0026530 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 18 41059 -0.208171 0.341129 -0.0641727 0.0028060 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 19 41060 -0.206971 0.343729 -0.0645046 0.0030600 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 20 41061 -0.205770 0.346230 -0.0651265 0.0033590 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 21 41062 -0.204470 0.348830 -0.0660423 0.0036420 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 22 41063 -0.203270 0.351230 -0.0671852 0.0038210 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 23 41064 -0.201970 0.353730 -0.0684391 0.0038370 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 24 41065 -0.200669 0.356131 -0.0696299 0.0036900 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 25 41066 -0.199369 0.358531 -0.0705958 0.0034170 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 26 41067 -0.198069 0.360931 -0.0712607 0.0031030 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 27 41068 -0.196668 0.363332 -0.0716295 0.0028390 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 28 41069 -0.195268 0.365632 -0.0717954 0.0026950 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 29 41070 -0.193868 0.367932 -0.0718823 0.0026770 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 4 30 41071 -0.192368 0.370232 -0.0719931 0.0027520 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 1 41072 -0.190867 0.372533 -0.0722260 0.0029010 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 2 41073 -0.189267 0.374833 -0.0726219 0.0030740 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 3 41074 -0.187667 0.377133 -0.0731917 0.0032420 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 4 41075 -0.186067 0.379433 -0.0739076 0.0033740 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 5 41076 -0.184266 0.381634 -0.0747455 0.0034730 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 6 41077 -0.182566 0.383934 -0.0756443 0.0035060 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 7 41078 -0.180666 0.386234 -0.0765462 0.0034780 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 8 41079 -0.178765 0.388435 -0.0773911 0.0033820 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 9 41080 -0.176765 0.390735 -0.0781159 0.0032520 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 10 41081 -0.174765 0.393035 -0.0786888 0.0030900 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 11 41082 -0.172565 0.395235 -0.0791087 0.0029340 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 12 41083 -0.170364 0.397536 -0.0793895 0.0028170 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 13 41084 -0.168064 0.399736 -0.0795744 0.0027590 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 14 41085 -0.165664 0.402036 -0.0797563 0.0028030 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 15 41086 -0.163264 0.404236 -0.0800341 0.0029370 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 16 41087 -0.160663 0.406437 -0.0804880 0.0031540 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 17 41088 -0.158063 0.408637 -0.0811769 0.0034170 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 18 41089 -0.155363 0.410937 -0.0821278 0.0036600 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 19 41090 -0.152562 0.413138 -0.0832916 0.0038310 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 20 41091 -0.149662 0.415338 -0.0845675 0.0038660 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 21 41092 -0.146662 0.417438 -0.0858024 0.0037610 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 22 41093 -0.143662 0.419638 -0.0868532 0.0035150 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 23 41094 -0.140461 0.421739 -0.0876271 0.0031950 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 24 41095 -0.137261 0.423839 -0.0880670 0.0028940 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 25 41096 -0.133961 0.425939 -0.0882408 0.0026620 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 26 41097 -0.130560 0.428040 -0.0882417 0.0025500 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 27 41098 -0.127060 0.430040 -0.0881906 0.0025440 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 28 41099 -0.123460 0.432040 -0.0881864 0.0026310 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 29 41100 -0.119860 0.433940 -0.0882743 0.0027470 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 30 41101 -0.116159 0.435941 -0.0884912 0.0028730 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 5 31 41102 -0.112359 0.437741 -0.0888221 0.0029730 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 1 41103 -0.108559 0.439641 -0.0892429 0.0030400 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 2 41104 -0.104559 0.441341 -0.0896938 0.0030440 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 3 41105 -0.100658 0.443142 -0.0901297 0.0029980 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 4 41106 -0.096558 0.444742 -0.0904915 0.0028960 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 5 41107 -0.092458 0.446442 -0.0907164 0.0027470 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 6 41108 -0.088357 0.447943 -0.0907863 0.0025710 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 7 41109 -0.084157 0.449543 -0.0906762 0.0024020 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 8 41110 -0.079857 0.450943 -0.0904100 0.0022520 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 9 41111 -0.075557 0.452343 -0.0900219 0.0021750 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 10 41112 -0.071256 0.453644 -0.0895908 0.0021790 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 11 41113 -0.066856 0.454944 -0.0892246 0.0022860 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 12 41114 -0.062556 0.456144 -0.0890115 0.0024810 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 13 41115 -0.058056 0.457244 -0.0890234 0.0027260 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 14 41116 -0.053655 0.458245 -0.0892692 0.0029610 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 15 41117 -0.049155 0.459245 -0.0897311 0.0031270 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 16 41118 -0.044655 0.460145 -0.0903050 0.0031790 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 17 41119 -0.040154 0.460946 -0.0908639 0.0030970 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 18 41120 -0.035654 0.461746 -0.0912777 0.0028950 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 19 41121 -0.031154 0.462346 -0.0914476 0.0026180 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 20 41122 -0.026654 0.462946 -0.0913305 0.0023290 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 21 41123 -0.022153 0.463447 -0.0909444 0.0021030 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 22 41124 -0.017553 0.463947 -0.0903792 0.0019670 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 23 41125 -0.013053 0.464247 -0.0897271 0.0019460 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 24 41126 -0.008553 0.464547 -0.0891240 0.0020330 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 25 41127 -0.004052 0.464748 -0.0886308 0.0021760 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 26 41128 0.000448 0.464848 -0.0882917 0.0023240 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 27 41129 0.004848 0.464848 -0.0881016 0.0024600 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 28 41130 0.009349 0.464849 -0.0880165 0.0025530 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 29 41131 0.013749 0.464649 -0.0879973 0.0025890 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 6 30 41132 0.018249 0.464449 -0.0879842 0.0025650 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 1 41133 0.022549 0.464149 -0.0879291 0.0024950 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 2 41134 0.026950 0.463750 -0.0877780 0.0023770 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 3 41135 0.031250 0.463250 -0.0874908 0.0022270 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 4 41136 0.035550 0.462650 -0.0870487 0.0020790 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 5 41137 0.039850 0.462050 -0.0864636 0.0019390 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 6 41138 0.044051 0.461351 -0.0857635 0.0018610 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 7 41139 0.048251 0.460551 -0.0850223 0.0018660 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 8 41140 0.052451 0.459651 -0.0843502 0.0019770 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 9 41141 0.056552 0.458652 -0.0838411 0.0022020 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 10 41142 0.060652 0.457652 -0.0835870 0.0024860 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 11 41143 0.064652 0.456552 -0.0836358 0.0027860 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 12 41144 0.068652 0.455352 -0.0839467 0.0030190 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 13 41145 0.072553 0.454053 -0.0844526 0.0031290 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 14 41146 0.076453 0.452753 -0.0849755 0.0030940 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 15 41147 0.080353 0.451353 -0.0854073 0.0029220 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 16 41148 0.084153 0.449853 -0.0856142 0.0026740 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 17 41149 0.087954 0.448354 -0.0855611 0.0024120 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 18 41150 0.091754 0.446854 -0.0852650 0.0021870 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 19 41151 0.095454 0.445154 -0.0847838 0.0020500 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 20 41152 0.099055 0.443555 -0.0842197 0.0020210 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 21 41153 0.102755 0.441755 -0.0836676 0.0020810 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 22 41154 0.106355 0.440055 -0.0832145 0.0022020 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 23 41155 0.109955 0.438255 -0.0828923 0.0023530 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 24 41156 0.113456 0.436356 -0.0827282 0.0025050 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 25 41157 0.116956 0.434456 -0.0826981 0.0026070 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 26 41158 0.120456 0.432556 -0.0827430 0.0026630 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 27 41159 0.123856 0.430556 -0.0828128 0.0026450 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 28 41160 0.127357 0.428557 -0.0828227 0.0025670 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 29 41161 0.130757 0.426557 -0.0827486 0.0024480 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 30 41162 0.134057 0.424557 -0.0825165 0.0022940 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 7 31 41163 0.137358 0.422458 -0.0821333 0.0021180 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 1 41164 0.140658 0.420358 -0.0815852 0.0019620 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 2 41165 0.143958 0.418258 -0.0808891 0.0018450 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 3 41166 0.147258 0.416158 -0.0801190 0.0018090 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 4 41167 0.150459 0.413959 -0.0793499 0.0018620 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 5 41168 0.153559 0.411759 -0.0787007 0.0020360 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 6 41169 0.156759 0.409559 -0.0782736 0.0023140 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 7 41170 0.159859 0.407359 -0.0781525 0.0026240 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 8 41171 0.162960 0.405160 -0.0783294 0.0029050 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 9 41172 0.165960 0.402860 -0.0787432 0.0030680 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 10 41173 0.168960 0.400560 -0.0792291 0.0030670 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 11 41174 0.171861 0.398261 -0.0796340 0.0029080 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 12 41175 0.174761 0.395961 -0.0798199 0.0026440 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 13 41176 0.177661 0.393661 -0.0797318 0.0023620 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 14 41177 0.180461 0.391261 -0.0793796 0.0021250 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 15 41178 0.183162 0.388862 -0.0788445 0.0019910 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 16 41179 0.185862 0.386462 -0.0782184 0.0019670 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 17 41180 0.188462 0.384062 -0.0776213 0.0020430 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 18 41181 0.191063 0.381563 -0.0771412 0.0021960 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 19 41182 0.193563 0.379063 -0.0768360 0.0023890 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 20 41183 0.196063 0.376563 -0.0767289 0.0025860 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 21 41184 0.198463 0.373963 -0.0768088 0.0027540 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 22 41185 0.200764 0.371364 -0.0770407 0.0028710 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 23 41186 0.202964 0.368764 -0.0773476 0.0029230 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 24 41187 0.205164 0.366064 -0.0776854 0.0029110 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 25 41188 0.207264 0.363364 -0.0779603 0.0028320 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 26 41189 0.209265 0.360565 -0.0781562 0.0027240 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 27 41190 0.211165 0.357765 -0.0782121 0.0025880 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 28 41191 0.213065 0.354965 -0.0781540 0.0024580 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 29 41192 0.214766 0.352066 -0.0779698 0.0023590 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 30 41193 0.216466 0.349066 -0.0777117 0.0023170 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 8 31 41194 0.218066 0.346066 -0.0774516 0.0023600 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 1 41195 0.219566 0.343066 -0.0772865 0.0024970 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 2 41196 0.221067 0.339967 -0.0773004 0.0027400 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 3 41197 0.222367 0.336767 -0.0776002 0.0030470 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 4 41198 0.223667 0.333567 -0.0782181 0.0033630 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 5 41199 0.224867 0.330267 -0.0791190 0.0035990 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 6 41200 0.225968 0.326968 -0.0801739 0.0036800 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 7 41201 0.226968 0.323568 -0.0812178 0.0035690 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 8 41202 0.227868 0.320168 -0.0820797 0.0033160 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 9 41203 0.228669 0.316669 -0.0826455 0.0029900 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 10 41204 0.229469 0.313169 -0.0828774 0.0026750 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 11 41205 0.230169 0.309569 -0.0828463 0.0024510 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 12 41206 0.230769 0.305969 -0.0826492 0.0023580 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 13 41207 0.231270 0.302270 -0.0824201 0.0023790 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 14 41208 0.231770 0.298570 -0.0822549 0.0024830 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 15 41209 0.232070 0.294870 -0.0822218 0.0026340 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 16 41210 0.232370 0.291070 -0.0823467 0.0027960 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 17 41211 0.232571 0.287271 -0.0826266 0.0029490 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 18 41212 0.232771 0.283371 -0.0830395 0.0030590 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 19 41213 0.232871 0.279471 -0.0835444 0.0031200 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 20 41214 0.232872 0.275572 -0.0840782 0.0031170 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 21 41215 0.232772 0.271672 -0.0845681 0.0030530 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 22 41216 0.232672 0.267672 -0.0849790 0.0029530 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 23 41217 0.232472 0.263772 -0.0852749 0.0028280 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 24 41218 0.232173 0.259773 -0.0854448 0.0027040 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 25 41219 0.231873 0.255773 -0.0854997 0.0026150 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 26 41220 0.231473 0.251773 -0.0854996 0.0025750 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 27 41221 0.231073 0.247873 -0.0854934 0.0026060 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 28 41222 0.230574 0.243874 -0.0855623 0.0027280 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 29 41223 0.230074 0.239874 -0.0857932 0.0029400 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 9 30 41224 0.229474 0.235974 -0.0862921 0.0032500 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 1 41225 0.228875 0.231975 -0.0871270 0.0036040 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 2 41226 0.228175 0.228075 -0.0882999 0.0039190 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 3 41227 0.227475 0.224175 -0.0897287 0.0041150 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 4 41228 0.226675 0.220275 -0.0912916 0.0041500 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 5 41229 0.225876 0.216376 -0.0927785 0.0039970 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 6 41230 0.224976 0.212476 -0.0940634 0.0037190 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 7 41231 0.224076 0.208676 -0.0950353 0.0034080 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 8 41232 0.223176 0.204876 -0.0957112 0.0031590 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 9 41233 0.222177 0.201077 -0.0961941 0.0030200 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 10 41234 0.221177 0.197277 -0.0966039 0.0030010 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 11 41235 0.220077 0.193577 -0.0970498 0.0030850 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 12 41236 0.219078 0.189878 -0.0976117 0.0032250 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 13 41237 0.217878 0.186178 -0.0983246 0.0033910 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 14 41238 0.216778 0.182578 -0.0991985 0.0035320 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 15 41239 0.215578 0.178978 -0.1001964 0.0036350 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 16 41240 0.214379 0.175379 -0.1012623 0.0036780 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 17 41241 0.213079 0.171879 -0.1023511 0.0036800 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 18 41242 0.211879 0.168379 -0.1034120 0.0036120 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 19 41243 0.210579 0.164979 -0.1043779 0.0035030 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 20 41244 0.209180 0.161480 -0.1052178 0.0033630 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 21 41245 0.207880 0.158180 -0.1059107 0.0032170 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 22 41246 0.206480 0.154780 -0.1064766 0.0030890 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 23 41247 0.205081 0.151481 -0.1069245 0.0030050 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 24 41248 0.203681 0.148281 -0.1073184 0.0029860 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 25 41249 0.202181 0.145081 -0.1077312 0.0030470 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 26 41250 0.200781 0.141981 -0.1082611 0.0032070 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 27 41251 0.199282 0.138882 -0.1089830 0.0034380 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 28 41252 0.197782 0.135782 -0.1099669 0.0037250 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 29 41253 0.196282 0.132782 -0.1112448 0.0040170 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 30 41254 0.194682 0.129882 -0.1127987 0.0042460 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 10 31 41255 0.193183 0.126983 -0.1145136 0.0043480 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 1 41256 0.191583 0.124183 -0.1162485 0.0042850 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 2 41257 0.189983 0.121383 -0.1178534 0.0040730 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 3 41258 0.188284 0.118684 -0.1191862 0.0037790 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 4 41259 0.186684 0.115984 -0.1202131 0.0034850 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 5 41260 0.184984 0.113384 -0.1209970 0.0032930 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 6 41261 0.183284 0.110784 -0.1216549 0.0032230 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 7 41262 0.181585 0.108285 -0.1223158 0.0032860 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 8 41263 0.179785 0.105785 -0.1230727 0.0034170 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 9 41264 0.177985 0.103385 -0.1239776 0.0035850 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 10 41265 0.176186 0.100986 -0.1250365 0.0037290 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 11 41266 0.174286 0.098686 -0.1262324 0.0038250 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 12 41267 0.172486 0.096386 -0.1274883 0.0038710 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 13 41268 0.170486 0.094186 -0.1287741 0.0038610 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 14 41269 0.168587 0.091987 -0.1300110 0.0037940 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 15 41270 0.166587 0.089887 -0.1311669 0.0036780 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 16 41271 0.164587 0.087787 -0.1321648 0.0035150 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 17 41272 0.162487 0.085787 -0.1330007 0.0033390 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 18 41273 0.160388 0.083688 -0.1336556 0.0031650 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 19 41274 0.158288 0.081788 -0.1341535 0.0030190 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 20 41275 0.156088 0.079788 -0.1345434 0.0029440 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 21 41276 0.153889 0.077889 -0.1348853 0.0029460 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 22 41277 0.151589 0.075989 -0.1352622 0.0030210 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 23 41278 0.149289 0.074189 -0.1357731 0.0031820 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 24 41279 0.146989 0.072389 -0.1364629 0.0033940 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 25 41280 0.144590 0.070590 -0.1373748 0.0036080 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 26 41281 0.142190 0.068790 -0.1384947 0.0038010 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 27 41282 0.139690 0.066990 -0.1397546 0.0038910 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 28 41283 0.137190 0.065290 -0.1410415 0.0038490 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 29 41284 0.134591 0.063591 -0.1422264 0.0036810 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 11 30 41285 0.131991 0.061791 -0.1431903 0.0034130 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 1 41286 0.129391 0.060091 -0.1438632 0.0031150 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 2 41287 0.126692 0.058492 -0.1442481 0.0028690 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 3 41288 0.123992 0.056792 -0.1444490 0.0027340 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 4 41289 0.121192 0.055092 -0.1445799 0.0027280 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 5 41290 0.118392 0.053492 -0.1447678 0.0028320 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 6 41291 0.115493 0.051893 -0.1450797 0.0029850 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 7 41292 0.112593 0.050293 -0.1455376 0.0031250 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 8 41293 0.109693 0.048693 -0.1461374 0.0032360 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 9 41294 0.106693 0.047093 -0.1468013 0.0032820 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 10 41295 0.103694 0.045494 -0.1475012 0.0032780 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 11 41296 0.100694 0.043994 -0.1481581 0.0032180 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 12 41297 0.097594 0.042394 -0.1487310 0.0030990 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 13 41298 0.094495 0.040895 -0.1491629 0.0029520 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 14 41299 0.091295 0.039495 -0.1494378 0.0027770 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 15 41300 0.088095 0.037995 -0.1495377 0.0026170 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 16 41301 0.084895 0.036595 -0.1494826 0.0024800 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 17 41302 0.081696 0.035196 -0.1493365 0.0024080 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 18 41303 0.078396 0.033796 -0.1491444 0.0024030 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 19 41304 0.075096 0.032496 -0.1489903 0.0024920 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 20 41305 0.071796 0.031196 -0.1489652 0.0026620 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 21 41306 0.068397 0.029897 -0.1491511 0.0028850 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 22 41307 0.065097 0.028697 -0.1495580 0.0031190 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 23 41308 0.061697 0.027497 -0.1501849 0.0033130 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 24 41309 0.058198 0.026298 -0.1509658 0.0034200 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 25 41310 0.054798 0.025198 -0.1517957 0.0034100 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 26 41311 0.051298 0.024198 -0.1525556 0.0032800 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 27 41312 0.047898 0.023098 -0.1531444 0.0030670 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 28 41313 0.044399 0.022099 -0.1534953 0.0028140 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 29 41314 0.040899 0.021199 -0.1535992 0.0025860 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 30 41315 0.037399 0.020299 -0.1535161 0.0024550 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1971 12 31 41316 0.033899 0.019499 -0.1533590 0.0024410 0.000000 0.000000 0.020000 0.020000 0.0015000 0.0010000 0.003580 0.002000 1972 1 1 41317 0.030400 0.018700 -0.0454859 0.0025390 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 2 41318 0.026900 0.017900 -0.0481008 0.0027080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 3 41319 0.023300 0.017200 -0.0509077 0.0028970 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 4 41320 0.019801 0.016501 -0.0538936 0.0030650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 5 41321 0.016301 0.015901 -0.0570195 0.0031770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 6 41322 0.012801 0.015301 -0.0602134 0.0032200 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 7 41323 0.009301 0.014801 -0.0634283 0.0032010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 8 41324 0.005902 0.014302 -0.0665972 0.0031370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 9 41325 0.002402 0.013902 -0.0696791 0.0030330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 10 41326 -0.001098 0.013502 -0.0726460 0.0028980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 11 41327 -0.004498 0.013202 -0.0754839 0.0027720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 12 41328 -0.007897 0.012903 -0.0782088 0.0026720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 13 41329 -0.011297 0.012703 -0.0808457 0.0026210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 14 41330 -0.014597 0.012503 -0.0834756 0.0026420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 15 41331 -0.017996 0.012304 -0.0861595 0.0027400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 16 41332 -0.021296 0.012204 -0.0889954 0.0029370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 17 41333 -0.024596 0.012104 -0.0920563 0.0031830 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 18 41334 -0.027796 0.012104 -0.0953802 0.0034650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 19 41335 -0.030995 0.012105 -0.0989651 0.0037040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 20 41336 -0.034195 0.012105 -0.1027570 0.0038620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 21 41337 -0.037295 0.012205 -0.1066459 0.0038820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 22 41338 -0.040395 0.012305 -0.1104778 0.0037730 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 23 41339 -0.043494 0.012406 -0.1141587 0.0035680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 24 41340 -0.046494 0.012606 -0.1176086 0.0033210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 25 41341 -0.049494 0.012806 -0.1208075 0.0030950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 26 41342 -0.052393 0.013007 -0.1238134 0.0029340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 27 41343 -0.055293 0.013307 -0.1267113 0.0028890 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 28 41344 -0.058193 0.013607 -0.1296192 0.0029450 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 29 41345 -0.060993 0.013907 -0.1326401 0.0030960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 30 41346 -0.063692 0.014208 -0.1358340 0.0032870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 1 31 41347 -0.066392 0.014608 -0.1392209 0.0034690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 1 41348 -0.069092 0.015008 -0.1427668 0.0036140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 2 41349 -0.071791 0.015509 -0.1464147 0.0036790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 3 41350 -0.074491 0.016009 -0.1501106 0.0036820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 4 41351 -0.077091 0.016609 -0.1537675 0.0036120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 5 41352 -0.079591 0.017109 -0.1573194 0.0034950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 6 41353 -0.082090 0.017810 -0.1607483 0.0033500 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 7 41354 -0.084590 0.018510 -0.1640172 0.0031890 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 8 41355 -0.087090 0.019210 -0.1671311 0.0030460 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 9 41356 -0.089490 0.020010 -0.1701220 0.0029350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 10 41357 -0.091889 0.020811 -0.1730219 0.0028780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 11 41358 -0.094189 0.021811 -0.1759038 0.0029130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 12 41359 -0.096489 0.022811 -0.1788787 0.0030400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 13 41360 -0.098688 0.023812 -0.1820136 0.0032430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 14 41361 -0.100888 0.024912 -0.1853935 0.0035100 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 15 41362 -0.103088 0.026112 -0.1890314 0.0037720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 16 41363 -0.105288 0.027412 -0.1929123 0.0039600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 17 41364 -0.107487 0.028813 -0.1969072 0.0040150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 18 41365 -0.109687 0.030213 -0.2008901 0.0039160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 19 41366 -0.111887 0.031713 -0.2047060 0.0037000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 20 41367 -0.114087 0.033413 -0.2082679 0.0034110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 21 41368 -0.116286 0.035014 -0.2115408 0.0031420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 22 41369 -0.118386 0.036814 -0.2145778 0.0029480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 23 41370 -0.120486 0.038714 -0.2174737 0.0028720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 24 41371 -0.122585 0.040615 -0.2203586 0.0029070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 25 41372 -0.124685 0.042715 -0.2233065 0.0030310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 26 41373 -0.126785 0.044915 -0.2264074 0.0032070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 27 41374 -0.128885 0.047215 -0.2296923 0.0033910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 28 41375 -0.130984 0.049616 -0.2331582 0.0035450 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 2 29 41376 -0.133084 0.052016 -0.2367521 0.0036500 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 1 41377 -0.135284 0.054516 -0.2403950 0.0036530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 2 41378 -0.137584 0.057016 -0.2440249 0.0036070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 3 41379 -0.139883 0.059517 -0.2475898 0.0035050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 4 41380 -0.142083 0.062117 -0.2510217 0.0033660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 5 41381 -0.144383 0.064817 -0.2543156 0.0032130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 6 41382 -0.146582 0.067518 -0.2574615 0.0030720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 7 41383 -0.148682 0.070418 -0.2604714 0.0029640 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 8 41384 -0.150882 0.073318 -0.2633983 0.0029010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 9 41385 -0.152882 0.076218 -0.2662972 0.0029110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 10 41386 -0.154981 0.079219 -0.2692491 0.0030080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 11 41387 -0.156981 0.082319 -0.2723520 0.0032030 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 12 41388 -0.158881 0.085419 -0.2756800 0.0034630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 13 41389 -0.160781 0.088619 -0.2792889 0.0037550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 14 41390 -0.162580 0.091820 -0.2831778 0.0040120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 15 41391 -0.164380 0.095020 -0.2872767 0.0041620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 16 41392 -0.166080 0.098320 -0.2914486 0.0041550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 17 41393 -0.167679 0.101621 -0.2955415 0.0039880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 18 41394 -0.169279 0.105021 -0.2993964 0.0037120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 19 41395 -0.170879 0.108321 -0.3029563 0.0034110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 20 41396 -0.172379 0.111721 -0.3062392 0.0031690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 21 41397 -0.173778 0.115122 -0.3093421 0.0030380 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 22 41398 -0.175078 0.118622 -0.3123650 0.0030290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 23 41399 -0.176478 0.122022 -0.3154329 0.0031190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 24 41400 -0.177678 0.125522 -0.3186218 0.0032660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 25 41401 -0.178877 0.128923 -0.3219687 0.0034290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 26 41402 -0.180077 0.132423 -0.3254717 0.0035710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 27 41403 -0.181077 0.135923 -0.3290956 0.0036670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 28 41404 -0.182176 0.139424 -0.3327855 0.0037120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 29 41405 -0.183176 0.142824 -0.3364864 0.0036790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 30 41406 -0.184076 0.146324 -0.3401333 0.0035960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 3 31 41407 -0.184976 0.149824 -0.3436732 0.0034690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 1 41408 -0.185775 0.153225 -0.3470731 0.0033310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 2 41409 -0.186575 0.156725 -0.3503250 0.0031860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 3 41410 -0.187275 0.160125 -0.3534539 0.0030780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 4 41411 -0.187975 0.163525 -0.3564968 0.0030180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 5 41412 -0.188574 0.167026 -0.3595117 0.0030230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 6 41413 -0.189074 0.170326 -0.3625677 0.0031020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 7 41414 -0.189574 0.173726 -0.3657436 0.0032630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 8 41415 -0.190073 0.177127 -0.3691205 0.0034910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 9 41416 -0.190473 0.180427 -0.3727434 0.0037710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 10 41417 -0.190773 0.183727 -0.3766533 0.0040550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 11 41418 -0.191073 0.187027 -0.3808232 0.0042680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 12 41419 -0.191372 0.190328 -0.3851471 0.0043550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 13 41420 -0.191572 0.193528 -0.3894780 0.0042790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 14 41421 -0.191672 0.196728 -0.3936569 0.0040500 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 15 41422 -0.191772 0.199928 -0.3975619 0.0037450 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 16 41423 -0.191771 0.203029 -0.4011628 0.0034570 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 17 41424 -0.191771 0.206129 -0.4045077 0.0032530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 18 41425 -0.191671 0.209229 -0.4077136 0.0031800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 19 41426 -0.191570 0.212330 -0.4109075 0.0032250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 20 41427 -0.191370 0.215330 -0.4141874 0.0033420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 21 41428 -0.191170 0.218330 -0.4175983 0.0034800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 22 41429 -0.190870 0.221230 -0.4211392 0.0035980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 23 41430 -0.190569 0.224231 -0.4247781 0.0036720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 24 41431 -0.190169 0.227131 -0.4284641 0.0036900 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 25 41432 -0.189769 0.229931 -0.4321390 0.0036480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 26 41433 -0.189268 0.232732 -0.4357519 0.0035590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 27 41434 -0.188668 0.235532 -0.4392418 0.0034240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 28 41435 -0.188168 0.238332 -0.4425917 0.0032620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 29 41436 -0.187468 0.241032 -0.4457746 0.0031070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 4 30 41437 -0.186867 0.243733 -0.4488115 0.0029730 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 1 41438 -0.186067 0.246433 -0.4517355 0.0028830 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 2 41439 -0.185267 0.249033 -0.4545874 0.0028520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 3 41440 -0.184467 0.251633 -0.4574613 0.0029000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 4 41441 -0.183566 0.254134 -0.4604112 0.0030200 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 5 41442 -0.182666 0.256734 -0.4635241 0.0032180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 6 41443 -0.181666 0.259234 -0.4668640 0.0034590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 7 41444 -0.180665 0.261635 -0.4704579 0.0037300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 8 41445 -0.179565 0.264035 -0.4743259 0.0039740 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 9 41446 -0.178365 0.266435 -0.4783888 0.0041340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 10 41447 -0.177165 0.268835 -0.4825487 0.0041620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 11 41448 -0.175964 0.271136 -0.4866536 0.0040360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 12 41449 -0.174664 0.273436 -0.4905835 0.0038110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 13 41450 -0.173264 0.275736 -0.4942744 0.0035530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 14 41451 -0.171864 0.278036 -0.4977083 0.0033320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 15 41452 -0.170363 0.280237 -0.5009773 0.0032280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 16 41453 -0.168863 0.282437 -0.5042002 0.0032470 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 17 41454 -0.167263 0.284637 -0.5074951 0.0033440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 18 41455 -0.165562 0.286838 -0.5109020 0.0034810 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 19 41456 -0.163862 0.288938 -0.5144409 0.0036020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 20 41457 -0.162162 0.291038 -0.5180888 0.0036830 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 21 41458 -0.160362 0.293138 -0.5217768 0.0036930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 22 41459 -0.158461 0.295239 -0.5254537 0.0036420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 23 41460 -0.156561 0.297339 -0.5290426 0.0035270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 24 41461 -0.154561 0.299439 -0.5325015 0.0033770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 25 41462 -0.152561 0.301539 -0.5357864 0.0031980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 26 41463 -0.150460 0.303540 -0.5388853 0.0030020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 27 41464 -0.148360 0.305640 -0.5418043 0.0028310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 28 41465 -0.146160 0.307640 -0.5445712 0.0027000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 29 41466 -0.143959 0.309641 -0.5472231 0.0026260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 30 41467 -0.141759 0.311741 -0.5498350 0.0026210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 5 31 41468 -0.139359 0.313741 -0.5524879 0.0026860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 1 41469 -0.137059 0.315741 -0.5552298 0.0028150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 2 41470 -0.134658 0.317742 -0.5581348 0.0030010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 3 41471 -0.132258 0.319842 -0.5612377 0.0031960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 4 41472 -0.129758 0.321842 -0.5645296 0.0033820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 5 41473 -0.127358 0.323842 -0.5679805 0.0034970 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 6 41474 -0.124757 0.325843 -0.5714994 0.0035210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 7 41475 -0.122257 0.327843 -0.5749814 0.0034240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 8 41476 -0.119657 0.329843 -0.5783093 0.0032170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 9 41477 -0.117056 0.331844 -0.5813852 0.0029510 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 10 41478 -0.114356 0.333744 -0.5842071 0.0026910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 11 41479 -0.111756 0.335744 -0.5868070 0.0025280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 12 41480 -0.109056 0.337744 -0.5893159 0.0024920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 13 41481 -0.106355 0.339745 -0.5918409 0.0025750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 14 41482 -0.103555 0.341645 -0.5944888 0.0027270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 15 41483 -0.100755 0.343645 -0.5972967 0.0028840 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 16 41484 -0.098055 0.345545 -0.6002416 0.0029850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 17 41485 -0.095254 0.347446 -0.6032425 0.0030250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 18 41486 -0.092354 0.349346 -0.6062565 0.0029820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 19 41487 -0.089554 0.351346 -0.6091954 0.0028880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 20 41488 -0.086653 0.353147 -0.6120173 0.0027480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 21 41489 -0.083753 0.355047 -0.6146922 0.0025790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 22 41490 -0.080853 0.356947 -0.6171812 0.0023980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 23 41491 -0.077953 0.358747 -0.6194931 0.0022390 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 24 41492 -0.075052 0.360648 -0.6216600 0.0021140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 25 41493 -0.072052 0.362448 -0.6237279 0.0020440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 26 41494 -0.069152 0.364248 -0.6257598 0.0020420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 27 41495 -0.066152 0.366048 -0.6278378 0.0021250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 28 41496 -0.063151 0.367749 -0.6300337 0.0022760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 29 41497 -0.060151 0.369549 -0.6324066 0.0024770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 6 30 41498 -0.057151 0.371249 -0.6349935 0.0027070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 1 41499 -0.054050 0.372950 0.3621956 0.0029080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 2 41500 -0.051050 0.374550 0.3592006 0.0030580 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 3 41501 -0.047950 0.376250 0.3561097 0.0031050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 4 41502 -0.044950 0.377850 0.3530268 0.0030450 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 5 41503 -0.041849 0.379451 0.3500439 0.0028870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 6 41504 -0.038749 0.380951 0.3472639 0.0026670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 7 41505 -0.035649 0.382451 0.3447110 0.0024350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 8 41506 -0.032549 0.383951 0.3423751 0.0022620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 9 41507 -0.029448 0.385352 0.3401592 0.0021880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 10 41508 -0.026348 0.386752 0.3379592 0.0022230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 11 41509 -0.023248 0.388152 0.3356723 0.0023310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 12 41510 -0.020147 0.389453 0.3332844 0.0024750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 13 41511 -0.016947 0.390653 0.3307405 0.0026140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 14 41512 -0.013847 0.391953 0.3280816 0.0027040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 15 41513 -0.010747 0.393053 0.3253726 0.0027000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 16 41514 -0.007646 0.394254 0.3226967 0.0026500 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 17 41515 -0.004546 0.395354 0.3201008 0.0025340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 18 41516 -0.001446 0.396354 0.3176409 0.0023930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 19 41517 0.001654 0.397354 0.3153199 0.0022370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 20 41518 0.004655 0.398355 0.3131630 0.0020880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 21 41519 0.007755 0.399255 0.3111441 0.0019780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 22 41520 0.010755 0.400055 0.3092012 0.0019180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 23 41521 0.013756 0.400856 0.3072862 0.0019240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 24 41522 0.016756 0.401656 0.3053273 0.0020160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 25 41523 0.019756 0.402356 0.3032384 0.0021730 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 26 41524 0.022656 0.402956 0.3009495 0.0024020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 27 41525 0.025557 0.403557 0.2984135 0.0026630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 28 41526 0.028457 0.404157 0.2956176 0.0029230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 29 41527 0.031257 0.404657 0.2925977 0.0031140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 30 41528 0.034058 0.405058 0.2894227 0.0032060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 7 31 41529 0.036758 0.405458 0.2862148 0.0031910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 1 41530 0.039458 0.405858 0.2830859 0.0030540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 2 41531 0.042158 0.406158 0.2801290 0.0028530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 3 41532 0.044759 0.406459 0.2773810 0.0026460 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 4 41533 0.047359 0.406659 0.2748301 0.0024790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 5 41534 0.049859 0.406759 0.2723912 0.0023960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 6 41535 0.052359 0.406859 0.2700003 0.0024060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 7 41536 0.054760 0.406960 0.2675373 0.0025240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 8 41537 0.057160 0.406960 0.2649414 0.0026910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 9 41538 0.059460 0.406860 0.2621645 0.0028500 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 10 41539 0.061761 0.406761 0.2592475 0.0029600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 11 41540 0.063961 0.406561 0.2562806 0.0029800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 12 41541 0.066161 0.406361 0.2533167 0.0029230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 13 41542 0.068261 0.406061 0.2504588 0.0027950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 14 41543 0.070262 0.405762 0.2477338 0.0026290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 15 41544 0.072362 0.405362 0.2452079 0.0024300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 16 41545 0.074262 0.404862 0.2428730 0.0022330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 17 41546 0.076162 0.404362 0.2407260 0.0020790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 18 41547 0.078063 0.403763 0.2387111 0.0019590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 19 41548 0.079863 0.403163 0.2367862 0.0019110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 20 41549 0.081663 0.402363 0.2348643 0.0019460 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 21 41550 0.083364 0.401664 0.2328693 0.0020570 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 22 41551 0.085064 0.400764 0.2307274 0.0022490 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 23 41552 0.086664 0.399864 0.2283655 0.0024910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 24 41553 0.088264 0.398864 0.2257515 0.0027450 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 25 41554 0.089865 0.397765 0.2228886 0.0029690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 26 41555 0.091365 0.396665 0.2198547 0.0031000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 27 41556 0.092865 0.395465 0.2167317 0.0031120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 28 41557 0.094265 0.394265 0.2136628 0.0029980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 29 41558 0.095666 0.392966 0.2107649 0.0027980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 30 41559 0.097066 0.391566 0.2080740 0.0025770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 8 31 41560 0.098466 0.390166 0.2055960 0.0024000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 1 41561 0.099767 0.388667 0.2032421 0.0023170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 2 41562 0.101067 0.387067 0.2009152 0.0023450 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 3 41563 0.102267 0.385467 0.1985182 0.0024730 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 4 41564 0.103567 0.383767 0.1959473 0.0026680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 5 41565 0.104768 0.382068 0.1931764 0.0028820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 6 41566 0.105968 0.380368 0.1901914 0.0030690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 7 41567 0.107168 0.378568 0.1870595 0.0031830 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 8 41568 0.108268 0.376668 0.1838536 0.0032240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 9 41569 0.109469 0.374769 0.1806376 0.0031870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 10 41570 0.110569 0.372869 0.1775007 0.0030780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 11 41571 0.111669 0.370969 0.1744928 0.0029350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 12 41572 0.112770 0.368970 0.1716338 0.0027940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 13 41573 0.113870 0.366870 0.1688999 0.0026690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 14 41574 0.114970 0.364870 0.1662820 0.0025740 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 15 41575 0.116070 0.362770 0.1637230 0.0025440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 16 41576 0.117171 0.360671 0.1611721 0.0025800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 17 41577 0.118271 0.358471 0.1585382 0.0026900 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 18 41578 0.119371 0.356371 0.1557772 0.0028620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 19 41579 0.120471 0.354171 0.1527943 0.0031040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 20 41580 0.121572 0.351972 0.1495584 0.0033700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 21 41581 0.122672 0.349672 0.1460474 0.0036370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 22 41582 0.123772 0.347472 0.1423065 0.0038290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 23 41583 0.124873 0.345173 0.1384286 0.0039040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 24 41584 0.125973 0.342873 0.1345356 0.0038470 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 25 41585 0.127173 0.340573 0.1307847 0.0036610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 26 41586 0.128273 0.338273 0.1272448 0.0034150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 27 41587 0.129474 0.335974 0.1239578 0.0031790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 28 41588 0.130574 0.333574 0.1208569 0.0030410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 29 41589 0.131774 0.331274 0.1178350 0.0030120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 9 30 41590 0.132974 0.328874 0.1147850 0.0030930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 1 41591 0.134075 0.326475 0.1116131 0.0032480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 2 41592 0.135275 0.324075 0.1082811 0.0034280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 3 41593 0.136475 0.321675 0.1047742 0.0035800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 4 41594 0.137676 0.319276 0.1011273 0.0036830 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 5 41595 0.138876 0.316776 0.0974223 0.0037160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 6 41596 0.140076 0.314376 0.0937204 0.0036660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 7 41597 0.141276 0.311876 0.0901025 0.0035610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 8 41598 0.142477 0.309377 0.0866235 0.0034020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 9 41599 0.143577 0.306877 0.0833036 0.0032250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 10 41600 0.144777 0.304377 0.0801607 0.0030550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 11 41601 0.145977 0.301877 0.0771827 0.0029180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 12 41602 0.147078 0.299378 0.0743188 0.0028300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 13 41603 0.148178 0.296878 0.0715018 0.0028050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 14 41604 0.149278 0.294378 0.0686849 0.0028480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 15 41605 0.150279 0.291879 0.0657940 0.0029470 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 16 41606 0.151379 0.289379 0.0627610 0.0031160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 17 41607 0.152379 0.286779 0.0595471 0.0033290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 18 41608 0.153279 0.284279 0.0560992 0.0035560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 19 41609 0.154280 0.281780 0.0524442 0.0037530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 20 41610 0.155080 0.279280 0.0486223 0.0038650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 21 41611 0.155980 0.276780 0.0447563 0.0038520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 22 41612 0.156781 0.274281 0.0409634 0.0037040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 23 41613 0.157481 0.271781 0.0373825 0.0034470 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 24 41614 0.158181 0.269281 0.0340675 0.0031760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 25 41615 0.158781 0.266781 0.0310106 0.0029640 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 26 41616 0.159382 0.264382 0.0281106 0.0028570 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 27 41617 0.159882 0.261882 0.0252537 0.0028850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 28 41618 0.160382 0.259482 0.0223188 0.0029950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 29 41619 0.160782 0.257082 0.0192408 0.0031510 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 30 41620 0.161183 0.254683 0.0160329 0.0032810 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 10 31 41621 0.161483 0.252383 0.0126969 0.0033700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 1 41622 0.161683 0.250083 0.0093150 0.0033940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 2 41623 0.161884 0.247784 0.0059321 0.0033610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 3 41624 0.162084 0.245484 0.0026121 0.0032610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 4 41625 0.162184 0.243284 -0.0005848 0.0031260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 5 41626 0.162184 0.241084 -0.0036308 0.0029660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 6 41627 0.162185 0.238885 -0.0065167 0.0028160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 7 41628 0.162085 0.236685 -0.0092726 0.0026910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 8 41629 0.161985 0.234585 -0.0119246 0.0026210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 9 41630 0.161885 0.232485 -0.0145245 0.0026100 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 10 41631 0.161686 0.230486 -0.0171555 0.0026530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 11 41632 0.161486 0.228486 -0.0198624 0.0027690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 12 41633 0.161186 0.226486 -0.0227224 0.0029390 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 13 41634 0.160887 0.224487 -0.0257643 0.0031520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 14 41635 0.160487 0.222587 -0.0290322 0.0033940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 15 41636 0.160187 0.220587 -0.0325392 0.0036170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 16 41637 0.159787 0.218687 -0.0362481 0.0037880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 17 41638 0.159388 0.216888 -0.0400841 0.0038650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 18 41639 0.158888 0.214988 -0.0439390 0.0038230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 19 41640 0.158388 0.213088 -0.0476940 0.0036700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 20 41641 0.157888 0.211288 -0.0512579 0.0034560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 21 41642 0.157389 0.209389 -0.0546098 0.0032560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 22 41643 0.156889 0.207589 -0.0578008 0.0031460 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 23 41644 0.156389 0.205689 -0.0609437 0.0031630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 24 41645 0.155790 0.203890 -0.0641647 0.0032930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 25 41646 0.155190 0.201990 -0.0675406 0.0034750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 26 41647 0.154590 0.200190 -0.0711126 0.0036520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 27 41648 0.153990 0.198290 -0.0748375 0.0037750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 28 41649 0.153391 0.196391 -0.0786364 0.0038120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 29 41650 0.152791 0.194491 -0.0824264 0.0037670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 11 30 41651 0.152191 0.192591 -0.0861503 0.0036630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 1 41652 0.151491 0.190691 -0.0897383 0.0035080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 2 41653 0.150892 0.188792 -0.0931682 0.0033410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 3 41654 0.150192 0.186792 -0.0964192 0.0031500 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 4 41655 0.149492 0.184892 -0.0994761 0.0029790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 5 41656 0.148893 0.182893 -0.1023891 0.0028570 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 6 41657 0.148193 0.180893 -0.1052090 0.0027920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 7 41658 0.147493 0.178793 -0.1079840 0.0027810 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 8 41659 0.146793 0.176793 -0.1107919 0.0028320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 9 41660 0.146094 0.174694 -0.1136778 0.0029380 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 10 41661 0.145294 0.172594 -0.1166898 0.0031020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 11 41662 0.144594 0.170494 -0.1198767 0.0032730 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 12 41663 0.143894 0.168394 -0.1232337 0.0034460 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 13 41664 0.143095 0.166295 -0.1267456 0.0035800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 14 41665 0.142295 0.164095 -0.1303706 0.0036440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 15 41666 0.141595 0.161995 -0.1340125 0.0036240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 16 41667 0.140796 0.159796 -0.1375735 0.0034950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 17 41668 0.139896 0.157596 -0.1409774 0.0033030 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 18 41669 0.139096 0.155396 -0.1441854 0.0031060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 19 41670 0.138196 0.153196 -0.1472073 0.0029630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 20 41671 0.137397 0.150997 -0.1501363 0.0029180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 21 41672 0.136397 0.148797 -0.1530952 0.0030080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 22 41673 0.135497 0.146597 -0.1561932 0.0031870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 23 41674 0.134597 0.144297 -0.1594781 0.0033920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 24 41675 0.133598 0.142098 -0.1629631 0.0035560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 25 41676 0.132598 0.139898 -0.1665510 0.0036260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 26 41677 0.131598 0.137798 -0.1701840 0.0036150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 27 41678 0.130499 0.135599 -0.1737559 0.0035190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 28 41679 0.129399 0.133399 -0.1771979 0.0033760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 29 41680 0.128299 0.131299 -0.1804908 0.0032100 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 30 41681 0.127199 0.129199 -0.1836158 0.0030410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1972 12 31 41682 0.126000 0.127100 -0.1865687 0.0028890 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 1 41683 0.124800 0.125000 0.8105944 0.0027730 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 2 41684 0.123500 0.123000 0.8078584 0.0027100 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 3 41685 0.122300 0.121000 0.8051525 0.0027220 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 4 41686 0.120901 0.119001 0.8024015 0.0027910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 5 41687 0.119601 0.117101 0.7995416 0.0029280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 6 41688 0.118201 0.115201 0.7965306 0.0031080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 7 41689 0.116802 0.113402 0.7933287 0.0033170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 8 41690 0.115302 0.111602 0.7899097 0.0035070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 9 41691 0.113802 0.109802 0.7863177 0.0036550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 10 41692 0.112202 0.108102 0.7826208 0.0037260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 11 41693 0.110603 0.106503 0.7788958 0.0037110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 12 41694 0.109003 0.105003 0.7752289 0.0035990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 13 41695 0.107303 0.103403 0.7717109 0.0034200 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 14 41696 0.105604 0.102004 0.7683970 0.0031970 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 15 41697 0.103804 0.100604 0.7653050 0.0030060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 16 41698 0.102004 0.099304 0.7623651 0.0029000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 17 41699 0.100104 0.098004 0.7594751 0.0029000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 18 41700 0.098205 0.096805 0.7565292 0.0030070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 19 41701 0.096305 0.095705 0.7534322 0.0031820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 20 41702 0.094305 0.094605 0.7501683 0.0033480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 21 41703 0.092305 0.093605 0.7467603 0.0034550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 22 41704 0.090306 0.092606 0.7432924 0.0034720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 23 41705 0.088306 0.091806 0.7398474 0.0034030 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 24 41706 0.086206 0.090906 0.7365095 0.0032640 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 25 41707 0.084107 0.090107 0.7333215 0.0030990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 26 41708 0.082007 0.089407 0.7303046 0.0029270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 27 41709 0.079907 0.088807 0.7274526 0.0027890 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 28 41710 0.077707 0.088207 0.7247257 0.0026740 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 29 41711 0.075608 0.087608 0.7220887 0.0026200 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 30 41712 0.073408 0.087108 0.7194757 0.0026190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 1 31 41713 0.071308 0.086608 0.7168188 0.0026970 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 1 41714 0.069108 0.086208 0.7140608 0.0028500 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 2 41715 0.067009 0.085809 0.7111109 0.0030460 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 3 41716 0.064909 0.085509 0.7079499 0.0032710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 4 41717 0.062809 0.085209 0.7045700 0.0034960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 5 41718 0.060610 0.085010 0.7009800 0.0036740 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 6 41719 0.058510 0.084810 0.6972361 0.0037910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 7 41720 0.056410 0.084710 0.6934291 0.0038140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 8 41721 0.054410 0.084510 0.6896492 0.0037340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 9 41722 0.052311 0.084511 0.6859972 0.0035720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 10 41723 0.050211 0.084411 0.6825032 0.0033930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 11 41724 0.048211 0.084411 0.6792013 0.0032290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 12 41725 0.046111 0.084411 0.6760223 0.0031370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 13 41726 0.044112 0.084412 0.6728844 0.0031480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 14 41727 0.042112 0.084512 0.6696794 0.0032660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 15 41728 0.040112 0.084612 0.6663255 0.0034620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 16 41729 0.038013 0.084713 0.6627585 0.0036710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 17 41730 0.036013 0.084813 0.6590055 0.0038320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 18 41731 0.034013 0.085013 0.6551316 0.0038990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 19 41732 0.032013 0.085213 0.6512426 0.0038730 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 20 41733 0.030014 0.085414 0.6474257 0.0037470 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 21 41734 0.028014 0.085614 0.6437687 0.0035520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 22 41735 0.025914 0.085814 0.6403188 0.0033440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 23 41736 0.023914 0.086014 0.6370878 0.0031320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 24 41737 0.021915 0.086315 0.6340458 0.0029490 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 25 41738 0.019815 0.086515 0.6311749 0.0028120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 26 41739 0.017815 0.086815 0.6284009 0.0027350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 27 41740 0.015716 0.087116 0.6256820 0.0027350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 2 28 41741 0.013616 0.087416 0.6229080 0.0028140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 1 41742 0.011616 0.087716 0.6200251 0.0029520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 2 41743 0.009516 0.088016 0.6169801 0.0031440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 3 41744 0.007417 0.088417 0.6137421 0.0033420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 4 41745 0.005317 0.088717 0.6103022 0.0035310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 5 41746 0.003117 0.089017 0.6067022 0.0036690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 6 41747 0.001017 0.089417 0.6030073 0.0037120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 7 41748 -0.001082 0.089818 0.5993143 0.0036560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 8 41749 -0.003182 0.090118 0.5957253 0.0035190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 9 41750 -0.005382 0.090518 0.5922824 0.0033460 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 10 41751 -0.007481 0.091019 0.5890194 0.0031860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 11 41752 -0.009581 0.091419 0.5858875 0.0030930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 12 41753 -0.011681 0.091819 0.5828015 0.0030990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 13 41754 -0.013881 0.092319 0.5796535 0.0032110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 14 41755 -0.015980 0.092820 0.5763516 0.0034130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 15 41756 -0.018080 0.093320 0.5728156 0.0036640 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 16 41757 -0.020180 0.093920 0.5690297 0.0038920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 17 41758 -0.022280 0.094520 0.5650497 0.0040620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 18 41759 -0.024279 0.095121 0.5609337 0.0041340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 19 41760 -0.026379 0.095721 0.5568028 0.0041040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 20 41761 -0.028479 0.096421 0.5527518 0.0039800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 21 41762 -0.030478 0.097222 0.5488569 0.0038140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 22 41763 -0.032578 0.098022 0.5451369 0.0036290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 23 41764 -0.034578 0.098822 0.5415929 0.0034440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 24 41765 -0.036578 0.099722 0.5382250 0.0033000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 25 41766 -0.038577 0.100623 0.5349760 0.0032100 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 26 41767 -0.040577 0.101623 0.5317740 0.0031940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 27 41768 -0.042577 0.102723 0.5285651 0.0032340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 28 41769 -0.044577 0.103823 0.5252851 0.0033350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 29 41770 -0.046576 0.104924 0.5218782 0.0034860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 30 41771 -0.048576 0.106124 0.5182932 0.0036780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 3 31 41772 -0.050476 0.107424 0.5145222 0.0038610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 1 41773 -0.052475 0.108725 0.5105833 0.0040180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 2 41774 -0.054475 0.110125 0.5065233 0.0040970 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 3 41775 -0.056375 0.111525 0.5024243 0.0040690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 4 41776 -0.058375 0.113025 0.4984214 0.0039310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 5 41777 -0.060274 0.114626 0.4945984 0.0037070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 6 41778 -0.062174 0.116226 0.4910034 0.0034770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 7 41779 -0.064174 0.117826 0.4876275 0.0032880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 8 41780 -0.066073 0.119527 0.4844035 0.0031990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 9 41781 -0.067973 0.121227 0.4812026 0.0032200 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 10 41782 -0.069873 0.123027 0.4779246 0.0033370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 11 41783 -0.071673 0.124827 0.4745136 0.0034980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 12 41784 -0.073572 0.126728 0.4709417 0.0036420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 13 41785 -0.075372 0.128628 0.4672347 0.0037520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 14 41786 -0.077172 0.130528 0.4634527 0.0037900 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 15 41787 -0.078972 0.132428 0.4596818 0.0037480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 16 41788 -0.080671 0.134429 0.4559808 0.0036340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 17 41789 -0.082471 0.136329 0.4524208 0.0034790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 18 41790 -0.084171 0.138329 0.4490389 0.0032930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 19 41791 -0.085770 0.140330 0.4458319 0.0031150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 20 41792 -0.087470 0.142330 0.4427969 0.0029700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 21 41793 -0.089070 0.144330 0.4398850 0.0028750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 22 41794 -0.090570 0.146330 0.4370380 0.0028410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 23 41795 -0.092069 0.148231 0.4341930 0.0028680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 24 41796 -0.093569 0.150231 0.4312921 0.0029540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 25 41797 -0.095069 0.152131 0.4282781 0.0030890 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 26 41798 -0.096469 0.154131 0.4251011 0.0032590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 27 41799 -0.097768 0.156032 0.4217562 0.0034520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 28 41800 -0.099168 0.157932 0.4182122 0.0036300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 29 41801 -0.100468 0.159832 0.4145122 0.0037680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 4 30 41802 -0.101667 0.161733 0.4107153 0.0038200 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 1 41803 -0.102867 0.163633 0.4069183 0.0037650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 2 41804 -0.104067 0.165433 0.4032163 0.0036340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 3 41805 -0.105267 0.167333 0.3996674 0.0034530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 4 41806 -0.106366 0.169134 0.3962954 0.0032810 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 5 41807 -0.107466 0.170934 0.3930764 0.0031830 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 6 41808 -0.108466 0.172634 0.3898895 0.0032010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 7 41809 -0.109466 0.174434 0.3866395 0.0033130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 8 41810 -0.110465 0.176135 0.3832445 0.0034710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 9 41811 -0.111365 0.177835 0.3796995 0.0036260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 10 41812 -0.112265 0.179535 0.3760196 0.0037130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 11 41813 -0.113164 0.181236 0.3722876 0.0037370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 12 41814 -0.113964 0.182936 0.3685706 0.0036660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 13 41815 -0.114764 0.184536 0.3649667 0.0035310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 14 41816 -0.115564 0.186236 0.3615247 0.0033480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 15 41817 -0.116263 0.187837 0.3582797 0.0031400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 16 41818 -0.117063 0.189437 0.3552538 0.0029240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 17 41819 -0.117663 0.191037 0.3524238 0.0027320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 18 41820 -0.118363 0.192537 0.3497638 0.0025960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 19 41821 -0.119062 0.194138 0.3472129 0.0025170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 20 41822 -0.119662 0.195638 0.3447089 0.0025000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 21 41823 -0.120162 0.197238 0.3421939 0.0025500 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 22 41824 -0.120761 0.198739 0.3395929 0.0026570 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 23 41825 -0.121261 0.200239 0.3368690 0.0027960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 24 41826 -0.121761 0.201739 0.3339860 0.0029600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 25 41827 -0.122161 0.203239 0.3309410 0.0031270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 26 41828 -0.122560 0.204840 0.3277531 0.0032520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 27 41829 -0.122960 0.206340 0.3244481 0.0033360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 28 41830 -0.123260 0.207840 0.3211101 0.0033330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 29 41831 -0.123560 0.209340 0.3178141 0.0032370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 30 41832 -0.123759 0.210841 0.3146612 0.0030610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 5 31 41833 -0.123959 0.212441 0.3116972 0.0028800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 1 41834 -0.124059 0.213941 0.3088922 0.0027530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 2 41835 -0.124058 0.215442 0.3061542 0.0027330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 3 41836 -0.124058 0.217042 0.3033863 0.0028210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 4 41837 -0.124058 0.218642 0.3004843 0.0029920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 5 41838 -0.123958 0.220142 0.2973873 0.0031800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 6 41839 -0.123757 0.221743 0.2941294 0.0033230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 7 41840 -0.123557 0.223343 0.2907594 0.0033820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 8 41841 -0.123257 0.224943 0.2873864 0.0033410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 9 41842 -0.122957 0.226543 0.2841024 0.0032270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 10 41843 -0.122556 0.228144 0.2809475 0.0030670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 11 41844 -0.122056 0.229844 0.2779655 0.0028760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 12 41845 -0.121556 0.231444 0.2751855 0.0026860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 13 41846 -0.121055 0.233145 0.2725865 0.0025080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 14 41847 -0.120455 0.234745 0.2701476 0.0023690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 15 41848 -0.119755 0.236445 0.2678286 0.0022870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 16 41849 -0.119055 0.238145 0.2655536 0.0022650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 17 41850 -0.118254 0.239846 0.2632776 0.0022940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 18 41851 -0.117454 0.241646 0.2609497 0.0023710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 19 41852 -0.116554 0.243346 0.2585257 0.0024710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 20 41853 -0.115654 0.245146 0.2559937 0.0025940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 21 41854 -0.114753 0.246947 0.2533407 0.0027090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 22 41855 -0.113753 0.248747 0.2505848 0.0027860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 23 41856 -0.112653 0.250547 0.2477848 0.0028220 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 24 41857 -0.111552 0.252348 0.2449728 0.0027900 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 25 41858 -0.110452 0.254248 0.2422308 0.0026800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 26 41859 -0.109352 0.256148 0.2396369 0.0025010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 27 41860 -0.108152 0.258048 0.2372319 0.0023100 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 28 41861 -0.106851 0.259949 0.2349999 0.0021520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 29 41862 -0.105651 0.261849 0.2328999 0.0020760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 6 30 41863 -0.104351 0.263849 0.2308099 0.0021160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 1 41864 -0.103050 0.265850 0.2286230 0.0022720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 2 41865 -0.101650 0.267750 0.2262580 0.0024710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 3 41866 -0.100250 0.269750 0.2236880 0.0026600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 4 41867 -0.098850 0.271750 0.2209650 0.0027690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 5 41868 -0.097449 0.273751 0.2181871 0.0027690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 6 41869 -0.095949 0.275751 0.2154591 0.0026820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 7 41870 -0.094449 0.277751 0.2128531 0.0025320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 8 41871 -0.092949 0.279751 0.2104131 0.0023460 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 9 41872 -0.091448 0.281752 0.2081511 0.0021710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 10 41873 -0.089948 0.283652 0.2060532 0.0020190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 11 41874 -0.088448 0.285652 0.2040902 0.0019170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 12 41875 -0.086947 0.287553 0.2022032 0.0018770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 13 41876 -0.085347 0.289353 0.2003262 0.0018880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 14 41877 -0.083847 0.291253 0.1984063 0.0019720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 15 41878 -0.082347 0.293053 0.1963743 0.0021000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 16 41879 -0.080746 0.294754 0.1941833 0.0022760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 17 41880 -0.079246 0.296454 0.1918163 0.0024690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 18 41881 -0.077746 0.298154 0.1892473 0.0026560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 19 41882 -0.076246 0.299754 0.1865164 0.0028020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 20 41883 -0.074745 0.301355 0.1836504 0.0029080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 21 41884 -0.073245 0.302855 0.1807224 0.0029570 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 22 41885 -0.071745 0.304255 0.1777604 0.0029360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 23 41886 -0.070244 0.305656 0.1748724 0.0028230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 24 41887 -0.068744 0.306956 0.1721265 0.0026650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 25 41888 -0.067244 0.308156 0.1695385 0.0025060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 26 41889 -0.065844 0.309356 0.1670945 0.0023860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 27 41890 -0.064343 0.310457 0.1647325 0.0023660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 28 41891 -0.062843 0.311557 0.1623235 0.0024570 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 29 41892 -0.061343 0.312457 0.1597815 0.0026390 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 30 41893 -0.059943 0.313457 0.1570406 0.0028300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 7 31 41894 -0.058442 0.314258 0.1541386 0.0029490 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 1 41895 -0.056942 0.315058 0.1511876 0.0029640 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 2 41896 -0.055542 0.315758 0.1482516 0.0028820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 3 41897 -0.054041 0.316459 0.1454456 0.0027170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 4 41898 -0.052541 0.317059 0.1428337 0.0025110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 5 41899 -0.051041 0.317659 0.1404357 0.0022870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 6 41900 -0.049541 0.318159 0.1382427 0.0021050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 7 41901 -0.048040 0.318660 0.1362127 0.0019620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 8 41902 -0.046540 0.319060 0.1343097 0.0018720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 9 41903 -0.044940 0.319460 0.1324477 0.0018520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 10 41904 -0.043440 0.319760 0.1305748 0.0019060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 11 41905 -0.041939 0.320061 0.1286168 0.0020290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 12 41906 -0.040339 0.320361 0.1265108 0.0021880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 13 41907 -0.038839 0.320661 0.1242328 0.0023830 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 14 41908 -0.037238 0.320862 0.1217448 0.0025790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 15 41909 -0.035738 0.321062 0.1190738 0.0027600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 16 41910 -0.034138 0.321362 0.1162539 0.0028800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 17 41911 -0.032538 0.321562 0.1133479 0.0029290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 18 41912 -0.030937 0.321763 0.1104209 0.0029030 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 19 41913 -0.029337 0.321963 0.1075549 0.0028090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 20 41914 -0.027737 0.322163 0.1048049 0.0026790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 21 41915 -0.026137 0.322363 0.1021959 0.0025520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 22 41916 -0.024536 0.322564 0.0996949 0.0024630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 23 41917 -0.022936 0.322764 0.0972420 0.0024600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 24 41918 -0.021336 0.322964 0.0947310 0.0025590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 25 41919 -0.019735 0.323265 0.0920820 0.0027490 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 26 41920 -0.018035 0.323465 0.0892270 0.0029670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 27 41921 -0.016435 0.323765 0.0861540 0.0031790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 28 41922 -0.014735 0.324065 0.0828940 0.0033160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 29 41923 -0.013034 0.324366 0.0795610 0.0033310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 30 41924 -0.011434 0.324566 0.0762701 0.0032350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 8 31 41925 -0.009734 0.324866 0.0731071 0.0030700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 1 41926 -0.008034 0.325266 0.0701501 0.0028510 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 2 41927 -0.006233 0.325567 0.0673921 0.0026490 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 3 41928 -0.004533 0.325867 0.0648301 0.0024740 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 4 41929 -0.002833 0.326167 0.0624181 0.0023510 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 5 41930 -0.001032 0.326568 0.0600981 0.0022880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 6 41931 0.000668 0.326868 0.0578212 0.0022880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 7 41932 0.002468 0.327168 0.0555122 0.0023500 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 8 41933 0.004268 0.327468 0.0531152 0.0024530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 9 41934 0.005969 0.327869 0.0505842 0.0026120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 10 41935 0.007769 0.328169 0.0478872 0.0027830 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 11 41936 0.009569 0.328469 0.0450222 0.0029420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 12 41937 0.011369 0.328769 0.0420062 0.0030690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 13 41938 0.013170 0.328970 0.0389052 0.0031290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 14 41939 0.014970 0.329270 0.0357853 0.0031070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 15 41940 0.016770 0.329470 0.0327283 0.0030050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 16 41941 0.018571 0.329771 0.0297933 0.0028590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 17 41942 0.020371 0.329871 0.0270033 0.0027050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 18 41943 0.022171 0.330071 0.0243603 0.0026010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 19 41944 0.023971 0.330171 0.0217843 0.0025680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 20 41945 0.025772 0.330272 0.0191813 0.0026430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 21 41946 0.027572 0.330272 0.0164683 0.0027970 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 22 41947 0.029272 0.330272 0.0135693 0.0030170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 23 41948 0.030973 0.330273 0.0104413 0.0032350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 24 41949 0.032773 0.330173 0.0071054 0.0034170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 25 41950 0.034473 0.330073 0.0036264 0.0035120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 26 41951 0.036173 0.329873 0.0001144 0.0034940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 27 41952 0.037774 0.329674 -0.0033406 0.0033930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 28 41953 0.039474 0.329374 -0.0066416 0.0032150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 29 41954 0.041074 0.328974 -0.0097736 0.0030310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 9 30 41955 0.042674 0.328574 -0.0127216 0.0028690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 1 41956 0.044275 0.328175 -0.0155186 0.0027450 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 2 41957 0.045775 0.327675 -0.0182206 0.0026690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 3 41958 0.047375 0.327075 -0.0208776 0.0026560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 4 41959 0.048876 0.326476 -0.0235626 0.0027050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 5 41960 0.050276 0.325776 -0.0262955 0.0027970 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 6 41961 0.051776 0.325076 -0.0291615 0.0029310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 7 41962 0.053176 0.324376 -0.0321735 0.0030860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 8 41963 0.054577 0.323577 -0.0353425 0.0032510 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 9 41964 0.055877 0.322677 -0.0386575 0.0033810 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 10 41965 0.057277 0.321777 -0.0420775 0.0034580 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 11 41966 0.058577 0.320877 -0.0455475 0.0034590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 12 41967 0.059778 0.319978 -0.0489655 0.0033840 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 13 41968 0.061078 0.318978 -0.0522815 0.0032270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 14 41969 0.062278 0.317978 -0.0554185 0.0030460 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 15 41970 0.063479 0.316879 -0.0583805 0.0028870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 16 41971 0.064579 0.315879 -0.0612165 0.0028110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 17 41972 0.065779 0.314779 -0.0640255 0.0028240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 18 41973 0.066879 0.313679 -0.0669075 0.0029420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 19 41974 0.067880 0.312580 -0.0699394 0.0031190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 20 41975 0.068980 0.311380 -0.0731494 0.0033090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 21 41976 0.069980 0.310280 -0.0765554 0.0034750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 22 41977 0.070980 0.309180 -0.0800764 0.0035720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 23 41978 0.071981 0.307981 -0.0836604 0.0035720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 24 41979 0.072881 0.306881 -0.0872024 0.0034980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 25 41980 0.073781 0.305681 -0.0906454 0.0033610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 26 41981 0.074682 0.304582 -0.0939234 0.0031930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 27 41982 0.075482 0.303382 -0.0970334 0.0030300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 28 41983 0.076282 0.302282 -0.0999864 0.0028930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 29 41984 0.077082 0.301182 -0.1028374 0.0028090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 30 41985 0.077883 0.300083 -0.1056244 0.0027870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 10 31 41986 0.078583 0.298983 -0.1084214 0.0028250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 1 41987 0.079283 0.297883 -0.1112934 0.0029180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 2 41988 0.079983 0.296783 -0.1142804 0.0030620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 3 41989 0.080684 0.295784 -0.1174254 0.0032220 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 4 41990 0.081284 0.294684 -0.1207274 0.0034000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 5 41991 0.081984 0.293684 -0.1242104 0.0035640 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 6 41992 0.082585 0.292685 -0.1278434 0.0036930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 7 41993 0.083185 0.291685 -0.1315774 0.0037640 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 8 41994 0.083785 0.290685 -0.1353444 0.0037580 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 9 41995 0.084385 0.289785 -0.1390764 0.0036840 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 10 41996 0.084986 0.288786 -0.1426943 0.0035440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 11 41997 0.085486 0.287886 -0.1461533 0.0033880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 12 41998 0.086086 0.286986 -0.1494883 0.0032940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 13 41999 0.086686 0.286086 -0.1527733 0.0032850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 14 42000 0.087287 0.285187 -0.1560923 0.0033600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 15 42001 0.087787 0.284387 -0.1595283 0.0035090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 16 42002 0.088387 0.283487 -0.1631173 0.0036790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 17 42003 0.088988 0.282688 -0.1668623 0.0038030 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 18 42004 0.089588 0.281888 -0.1706893 0.0038360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 19 42005 0.090188 0.281088 -0.1745073 0.0037850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 20 42006 0.090788 0.280288 -0.1782333 0.0036560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 21 42007 0.091489 0.279489 -0.1818003 0.0034710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 22 42008 0.092089 0.278689 -0.1851653 0.0032570 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 23 42009 0.092689 0.277889 -0.1883233 0.0030400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 24 42010 0.093389 0.277089 -0.1912653 0.0028490 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 25 42011 0.094090 0.276290 -0.1940353 0.0027030 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 26 42012 0.094790 0.275490 -0.1966903 0.0026250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 27 42013 0.095490 0.274690 -0.1993063 0.0026080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 28 42014 0.096191 0.273891 -0.2019243 0.0026350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 29 42015 0.096891 0.273091 -0.2046013 0.0027250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 11 30 42016 0.097591 0.272291 -0.2073823 0.0028410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 1 42017 0.098291 0.271491 -0.2102863 0.0029760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 2 42018 0.099092 0.270592 -0.2133323 0.0031020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 3 42019 0.099792 0.269692 -0.2164933 0.0032130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 4 42020 0.100592 0.268792 -0.2197423 0.0032790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 5 42021 0.101292 0.267892 -0.2230213 0.0032860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 6 42022 0.102093 0.266893 -0.2262823 0.0032250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 7 42023 0.102793 0.265893 -0.2294513 0.0031140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 8 42024 0.103593 0.264893 -0.2324903 0.0029640 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 9 42025 0.104294 0.263794 -0.2353963 0.0028480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 10 42026 0.104994 0.262694 -0.2382213 0.0028080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 11 42027 0.105694 0.261494 -0.2410503 0.0028760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 12 42028 0.106394 0.260394 -0.2439953 0.0030290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 13 42029 0.107095 0.259095 -0.2471313 0.0032360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 14 42030 0.107795 0.257895 -0.2504603 0.0034100 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 15 42031 0.108395 0.256595 -0.2539163 0.0034970 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 16 42032 0.109096 0.255196 -0.2574283 0.0034920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 17 42033 0.109596 0.253796 -0.2608694 0.0033850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 18 42034 0.110196 0.252396 -0.2641794 0.0032180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 19 42035 0.110696 0.250996 -0.2672954 0.0030030 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 20 42036 0.111197 0.249497 -0.2701864 0.0027910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 21 42037 0.111697 0.247997 -0.2728754 0.0025930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 22 42038 0.112097 0.246397 -0.2753864 0.0024370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 23 42039 0.112497 0.244897 -0.2777674 0.0023250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 24 42040 0.112798 0.243298 -0.2800674 0.0022730 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 25 42041 0.113098 0.241598 -0.2823434 0.0022980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 26 42042 0.113298 0.239998 -0.2846674 0.0023680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 27 42043 0.113499 0.238399 -0.2870884 0.0024660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 28 42044 0.113599 0.236699 -0.2896134 0.0025850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 29 42045 0.113699 0.235099 -0.2922654 0.0027050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 30 42046 0.113699 0.233399 -0.2950164 0.0027900 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1973 12 31 42047 0.113600 0.231800 -0.2978324 0.0028560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 1 42048 0.113500 0.230100 0.6992996 0.0028610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 2 42049 0.113400 0.228500 0.6964546 0.0028300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 3 42050 0.113200 0.226800 0.6936686 0.0027350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 4 42051 0.112901 0.225201 0.6909966 0.0026060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 5 42052 0.112601 0.223601 0.6884556 0.0024820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 6 42053 0.112201 0.222001 0.6860146 0.0024010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 7 42054 0.111802 0.220402 0.6836126 0.0024140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 8 42055 0.111302 0.218802 0.6811506 0.0025250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 9 42056 0.110702 0.217302 0.6785365 0.0027120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 10 42057 0.110202 0.215702 0.6757235 0.0029090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 11 42058 0.109503 0.214203 0.6727395 0.0030340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 12 42059 0.108803 0.212703 0.6696825 0.0030590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 13 42060 0.108103 0.211203 0.6666705 0.0029560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 14 42061 0.107403 0.209703 0.6638005 0.0027640 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 15 42062 0.106604 0.208304 0.6611475 0.0025380 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 16 42063 0.105804 0.206904 0.6587335 0.0023110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 17 42064 0.104904 0.205404 0.6565245 0.0021130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 18 42065 0.104005 0.204005 0.6544935 0.0019790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 19 42066 0.103105 0.202705 0.6525595 0.0018990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 20 42067 0.102205 0.201305 0.6506765 0.0018780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 21 42068 0.101305 0.200005 0.6487825 0.0019270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 22 42069 0.100306 0.198606 0.6468045 0.0020360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 23 42070 0.099406 0.197306 0.6446894 0.0021900 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 24 42071 0.098406 0.196006 0.6424204 0.0023590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 25 42072 0.097506 0.194806 0.6399744 0.0025320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 26 42073 0.096507 0.193507 0.6373754 0.0026800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 27 42074 0.095607 0.192307 0.6346374 0.0028070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 28 42075 0.094707 0.191107 0.6317774 0.0028840 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 29 42076 0.093808 0.190008 0.6288794 0.0028950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 30 42077 0.092908 0.188808 0.6260054 0.0028360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 1 31 42078 0.092008 0.187708 0.6232074 0.0027550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 1 42079 0.091108 0.186608 0.6205064 0.0026600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 2 42080 0.090309 0.185609 0.6178754 0.0025820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 3 42081 0.089509 0.184509 0.6153063 0.0025720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 4 42082 0.088709 0.183509 0.6126973 0.0026630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 5 42083 0.087909 0.182609 0.6099583 0.0028390 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 6 42084 0.087110 0.181610 0.6070043 0.0030730 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 7 42085 0.086410 0.180710 0.6038293 0.0032760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 8 42086 0.085710 0.179810 0.6004823 0.0033990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 9 42087 0.085011 0.179011 0.5970833 0.0033860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 10 42088 0.084311 0.178111 0.5937513 0.0032620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 11 42089 0.083611 0.177311 0.5905853 0.0030600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 12 42090 0.082911 0.176611 0.5876392 0.0028320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 13 42091 0.082312 0.175812 0.5849132 0.0026240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 14 42092 0.081612 0.175112 0.5823852 0.0024630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 15 42093 0.080912 0.174312 0.5799802 0.0023580 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 16 42094 0.080212 0.173712 0.5776482 0.0023140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 17 42095 0.079513 0.173013 0.5753322 0.0023400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 18 42096 0.078813 0.172313 0.5729602 0.0024110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 19 42097 0.078113 0.171713 0.5704952 0.0025240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 20 42098 0.077414 0.171114 0.5678932 0.0026720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 21 42099 0.076614 0.170514 0.5651601 0.0028120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 22 42100 0.075914 0.169914 0.5622751 0.0029320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 23 42101 0.075114 0.169314 0.5592991 0.0030240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 24 42102 0.074215 0.168815 0.5562451 0.0030630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 25 42103 0.073415 0.168315 0.5531931 0.0030420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 26 42104 0.072515 0.167815 0.5501911 0.0029650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 27 42105 0.071615 0.167315 0.5472851 0.0028500 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 2 28 42106 0.070616 0.166916 0.5444930 0.0027260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 1 42107 0.069616 0.166516 0.5418140 0.0026410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 2 42108 0.068616 0.166116 0.5391900 0.0026190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 3 42109 0.067617 0.165717 0.5365450 0.0026880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 4 42110 0.066517 0.165417 0.5337820 0.0028610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 5 42111 0.065417 0.165117 0.5308100 0.0030930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 6 42112 0.064217 0.164917 0.5275810 0.0033510 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 7 42113 0.063118 0.164718 0.5241239 0.0035600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 8 42114 0.061918 0.164618 0.5204959 0.0036660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 9 42115 0.060718 0.164518 0.5168239 0.0036460 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 10 42116 0.059519 0.164419 0.5132389 0.0035200 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 11 42117 0.058219 0.164419 0.5098049 0.0033320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 12 42118 0.057019 0.164519 0.5065759 0.0031280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 13 42119 0.055719 0.164719 0.5035369 0.0029590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 14 42120 0.054520 0.164820 0.5006488 0.0028370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 15 42121 0.053220 0.165120 0.4978518 0.0027680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 16 42122 0.052020 0.165420 0.4950828 0.0027600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 17 42123 0.050820 0.165820 0.4923028 0.0028090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 18 42124 0.049621 0.166221 0.4894498 0.0028940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 19 42125 0.048421 0.166621 0.4865028 0.0030020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 20 42126 0.047321 0.167221 0.4834317 0.0031320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 21 42127 0.046122 0.167722 0.4802427 0.0032420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 22 42128 0.045022 0.168322 0.4769567 0.0033330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 23 42129 0.044022 0.169022 0.4736037 0.0033650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 24 42130 0.042922 0.169722 0.4702557 0.0033280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 25 42131 0.041923 0.170423 0.4669587 0.0032370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 26 42132 0.041023 0.171223 0.4637886 0.0030970 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 27 42133 0.040023 0.172023 0.4607716 0.0029360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 28 42134 0.039223 0.172823 0.4579106 0.0027920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 29 42135 0.038324 0.173624 0.4551686 0.0027040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 30 42136 0.037524 0.174424 0.4524856 0.0026890 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 3 31 42137 0.036724 0.175224 0.4497516 0.0027720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 1 42138 0.036025 0.176025 0.4469075 0.0029260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 2 42139 0.035225 0.176825 0.4438905 0.0031010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 3 42140 0.034625 0.177625 0.4407115 0.0032670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 4 42141 0.033925 0.178425 0.4373895 0.0033630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 5 42142 0.033326 0.179126 0.4340105 0.0033760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 6 42143 0.032726 0.179826 0.4306734 0.0032900 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 7 42144 0.032126 0.180526 0.4274674 0.0031240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 8 42145 0.031626 0.181226 0.4244394 0.0029310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 9 42146 0.031127 0.181827 0.4216014 0.0027600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 10 42147 0.030627 0.182327 0.4189124 0.0026360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 11 42148 0.030127 0.182927 0.4162993 0.0025930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 12 42149 0.029628 0.183328 0.4137043 0.0026350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 13 42150 0.029128 0.183828 0.4110093 0.0027340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 14 42151 0.028628 0.184228 0.4082213 0.0028710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 15 42152 0.028228 0.184528 0.4052663 0.0030340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 16 42153 0.027729 0.184829 0.4021472 0.0032150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 17 42154 0.027229 0.185029 0.3988352 0.0034070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 18 42155 0.026729 0.185229 0.3953302 0.0035780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 19 42156 0.026229 0.185429 0.3916922 0.0036920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 20 42157 0.025730 0.185530 0.3879752 0.0037430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 21 42158 0.025130 0.185530 0.3842271 0.0037320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 22 42159 0.024630 0.185630 0.3805301 0.0036550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 23 42160 0.024031 0.185631 0.3769211 0.0035400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 24 42161 0.023431 0.185531 0.3734491 0.0034160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 25 42162 0.022831 0.185431 0.3700831 0.0033170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 26 42163 0.022231 0.185331 0.3667790 0.0033060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 27 42164 0.021532 0.185232 0.3634510 0.0033540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 28 42165 0.020832 0.185032 0.3600470 0.0034730 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 29 42166 0.020132 0.184932 0.3564940 0.0036360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 4 30 42167 0.019432 0.184732 0.3527799 0.0037760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 1 42168 0.018633 0.184533 0.3489619 0.0038600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 2 42169 0.017833 0.184333 0.3450979 0.0038520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 3 42170 0.017033 0.184033 0.3412889 0.0037520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 4 42171 0.016234 0.183834 0.3376118 0.0035830 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 5 42172 0.015334 0.183634 0.3341398 0.0033560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 6 42173 0.014434 0.183434 0.3309008 0.0031320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 7 42174 0.013534 0.183134 0.3278758 0.0029280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 8 42175 0.012635 0.182935 0.3250278 0.0027870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 9 42176 0.011735 0.182735 0.3222797 0.0027110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 10 42177 0.010735 0.182535 0.3195767 0.0026940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 11 42178 0.009835 0.182335 0.3168647 0.0027380 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 12 42179 0.008836 0.182136 0.3140887 0.0028180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 13 42180 0.007936 0.181936 0.3112306 0.0029200 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 14 42181 0.006936 0.181836 0.3082576 0.0030250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 15 42182 0.006037 0.181637 0.3051746 0.0031180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 16 42183 0.005037 0.181537 0.3020226 0.0031910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 17 42184 0.004137 0.181337 0.2988155 0.0032220 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 18 42185 0.003237 0.181237 0.2955945 0.0032000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 19 42186 0.002238 0.181138 0.2924235 0.0031230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 20 42187 0.001338 0.181138 0.2893645 0.0030010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 21 42188 0.000538 0.181038 0.2864374 0.0028620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 22 42189 -0.000362 0.181038 0.2836404 0.0027490 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 23 42190 -0.001161 0.180939 0.2809174 0.0027040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 24 42191 -0.001961 0.181039 0.2782024 0.0027510 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 25 42192 -0.002761 0.181039 0.2753953 0.0028720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 26 42193 -0.003560 0.181040 0.2724443 0.0030360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 27 42194 -0.004260 0.181140 0.2693293 0.0031880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 28 42195 -0.004960 0.181240 0.2660873 0.0032820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 29 42196 -0.005560 0.181340 0.2628032 0.0032800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 30 42197 -0.006159 0.181541 0.2595572 0.0031900 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 5 31 42198 -0.006759 0.181741 0.2564382 0.0030290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 1 42199 -0.007259 0.181941 0.2535041 0.0028240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 2 42200 -0.007659 0.182141 0.2507921 0.0025980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 3 42201 -0.008058 0.182442 0.2482901 0.0024020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 4 42202 -0.008358 0.182742 0.2459831 0.0022300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 5 42203 -0.008658 0.183042 0.2438000 0.0021280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 6 42204 -0.008857 0.183343 0.2416970 0.0020870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 7 42205 -0.008957 0.183743 0.2396180 0.0020890 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 8 42206 -0.009057 0.184043 0.2375059 0.0021410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 9 42207 -0.009057 0.184543 0.2353279 0.0022160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 10 42208 -0.008956 0.184944 0.2330809 0.0022870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 11 42209 -0.008756 0.185344 0.2307459 0.0023680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 12 42210 -0.008456 0.185844 0.2283538 0.0024130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 13 42211 -0.008155 0.186345 0.2259228 0.0024420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 14 42212 -0.007755 0.186845 0.2234948 0.0024160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 15 42213 -0.007255 0.187345 0.2211077 0.0023520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 16 42214 -0.006755 0.187945 0.2188057 0.0022540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 17 42215 -0.006054 0.188446 0.2166087 0.0021300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 18 42216 -0.005454 0.189046 0.2145437 0.0020130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 19 42217 -0.004654 0.189646 0.2125746 0.0019480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 20 42218 -0.003854 0.190246 0.2106296 0.0019690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 21 42219 -0.002953 0.190847 0.2086146 0.0020850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 22 42220 -0.002353 0.191447 0.2064465 0.0022590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 23 42221 -0.001753 0.192147 0.2040845 0.0024610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 24 42222 -0.001052 0.192848 0.2015525 0.0025980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 25 42223 -0.000352 0.193448 0.1989214 0.0026370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 26 42224 0.000248 0.194148 0.1963144 0.0025690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 27 42225 0.000948 0.194848 0.1938204 0.0024170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 28 42226 0.001549 0.195549 0.1914954 0.0022190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 29 42227 0.002149 0.196349 0.1893763 0.0020230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 6 30 42228 0.002749 0.197049 0.1874433 0.0018380 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 1 42229 0.003349 0.197749 0.1856753 0.0017060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 2 42230 0.003850 0.198450 0.1840222 0.0016290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 3 42231 0.004250 0.199250 0.1824082 0.0016110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 4 42232 0.004650 0.199950 0.1807812 0.0016500 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 5 42233 0.005051 0.200751 0.1790921 0.0017340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 6 42234 0.005351 0.201451 0.1772941 0.0018550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 7 42235 0.005751 0.202151 0.1753791 0.0019750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 8 42236 0.006151 0.202951 0.1733370 0.0020860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 9 42237 0.006552 0.203652 0.1712050 0.0021720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 10 42238 0.006952 0.204352 0.1689940 0.0022230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 11 42239 0.007352 0.204952 0.1667629 0.0022330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 12 42240 0.007652 0.205552 0.1645529 0.0021790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 13 42241 0.007953 0.206153 0.1624069 0.0020960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 14 42242 0.008153 0.206653 0.1603698 0.0019750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 15 42243 0.008253 0.207053 0.1584568 0.0018520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 16 42244 0.008354 0.207354 0.1566548 0.0017610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 17 42245 0.008454 0.207654 0.1549207 0.0017320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 18 42246 0.008554 0.207854 0.1531587 0.0018090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 19 42247 0.008554 0.207954 0.1512627 0.0019740 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 20 42248 0.008555 0.207955 0.1491866 0.0021820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 21 42249 0.008555 0.207955 0.1469086 0.0023630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 22 42250 0.008555 0.207955 0.1445006 0.0024440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 23 42251 0.008555 0.207955 0.1420525 0.0024290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 24 42252 0.008556 0.207956 0.1396895 0.0023000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 25 42253 0.008556 0.207956 0.1374875 0.0020980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 26 42254 0.008556 0.207956 0.1354914 0.0018950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 27 42255 0.008557 0.207957 0.1336894 0.0017140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 28 42256 0.008557 0.207957 0.1320374 0.0015910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 29 42257 0.008557 0.207957 0.1304983 0.0015160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 30 42258 0.008557 0.207957 0.1289843 0.0015110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 7 31 42259 0.008558 0.207958 0.1274463 0.0015740 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 1 42260 0.008558 0.207958 0.1258212 0.0016840 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 2 42261 0.008558 0.207958 0.1240662 0.0018190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 3 42262 0.008558 0.207958 0.1221691 0.0019780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 4 42263 0.008559 0.207959 0.1201121 0.0021320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 5 42264 0.008559 0.207959 0.1179211 0.0022640 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 6 42265 0.008559 0.207959 0.1156060 0.0023500 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 7 42266 0.008560 0.207960 0.1132360 0.0023940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 8 42267 0.008560 0.207960 0.1108320 0.0024040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 9 42268 0.008560 0.207960 0.1084499 0.0023550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 10 42269 0.008560 0.207960 0.1061209 0.0022790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 11 42270 0.008561 0.207961 0.1038849 0.0021850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 12 42271 0.008561 0.207961 0.1017428 0.0021140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 13 42272 0.008561 0.207961 0.0996378 0.0020980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 14 42273 0.008561 0.207961 0.0975187 0.0021570 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 15 42274 0.008562 0.207962 0.0952837 0.0023190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 16 42275 0.008562 0.207962 0.0928577 0.0025410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 17 42276 0.008562 0.207962 0.0901956 0.0027780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 18 42277 0.008563 0.207963 0.0873206 0.0029580 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 19 42278 0.008563 0.207963 0.0843186 0.0030240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 20 42279 0.008563 0.207963 0.0813185 0.0029550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 21 42280 0.008563 0.207963 0.0784555 0.0027660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 22 42281 0.008564 0.207964 0.0757954 0.0025310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 23 42282 0.008564 0.207964 0.0733834 0.0022990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 24 42283 0.008564 0.207964 0.0711914 0.0021020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 25 42284 0.008564 0.207964 0.0691553 0.0019800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 26 42285 0.008565 0.207965 0.0672103 0.0019220 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 27 42286 0.008565 0.207965 0.0653002 0.0019150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 28 42287 0.008565 0.207965 0.0633632 0.0019590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 29 42288 0.008566 0.207966 0.0613692 0.0020420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 30 42289 0.008566 0.207966 0.0592811 0.0021470 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 8 31 42290 0.008566 0.207966 0.0570851 0.0022540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 1 42291 0.008566 0.207966 0.0547800 0.0023530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 2 42292 0.008567 0.207967 0.0523900 0.0024200 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 3 42293 0.008567 0.207967 0.0499540 0.0024440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 4 42294 0.008567 0.207967 0.0475079 0.0024320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 5 42295 0.008568 0.207968 0.0451049 0.0023770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 6 42296 0.008568 0.207968 0.0427638 0.0023000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 7 42297 0.008568 0.207968 0.0404998 0.0022210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 8 42298 0.008568 0.207968 0.0383178 0.0021470 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 9 42299 0.008569 0.207969 0.0361907 0.0021290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 10 42300 0.008569 0.208069 0.0340367 0.0021830 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 11 42301 0.008569 0.208169 0.0317856 0.0023330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 12 42302 0.008569 0.208269 0.0293446 0.0025510 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 13 42303 0.008370 0.208370 0.0266595 0.0028210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 14 42304 0.008170 0.208470 0.0237165 0.0030660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 15 42305 0.008070 0.208670 0.0205535 0.0032430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 16 42306 0.007871 0.208771 0.0172814 0.0032780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 17 42307 0.007671 0.208971 0.0140394 0.0031860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 18 42308 0.007471 0.209271 0.0109303 0.0030020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 19 42309 0.007271 0.209671 0.0080373 0.0027730 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 20 42310 0.006972 0.210272 0.0053663 0.0025670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 21 42311 0.006672 0.210872 0.0028842 0.0024190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 22 42312 0.006272 0.211472 0.0005042 0.0023430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 23 42313 0.005872 0.212172 -0.0018249 0.0023230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 24 42314 0.005473 0.212973 -0.0041619 0.0023590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 25 42315 0.004973 0.213673 -0.0065560 0.0024360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 26 42316 0.004373 0.214473 -0.0090430 0.0025410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 27 42317 0.003874 0.215374 -0.0116520 0.0026660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 28 42318 0.003274 0.216174 -0.0143611 0.0027710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 29 42319 0.002574 0.217074 -0.0171851 0.0028600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 9 30 42320 0.001974 0.217874 -0.0200792 0.0029200 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 1 42321 0.001275 0.218775 -0.0230102 0.0029230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 2 42322 0.000575 0.219675 -0.0259203 0.0028910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 3 42323 -0.000225 0.220575 -0.0287783 0.0028200 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 4 42324 -0.000925 0.221475 -0.0315524 0.0027380 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 5 42325 -0.001724 0.222276 -0.0342454 0.0026520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 6 42326 -0.002524 0.223176 -0.0368794 0.0026130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 7 42327 -0.003324 0.224076 -0.0395055 0.0026400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 8 42328 -0.004123 0.224877 -0.0421955 0.0027450 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 9 42329 -0.004923 0.225777 -0.0450186 0.0029240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 10 42330 -0.005723 0.226577 -0.0480596 0.0031530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 11 42331 -0.006523 0.227377 -0.0513377 0.0033890 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 12 42332 -0.007322 0.228178 -0.0548127 0.0035700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 13 42333 -0.008122 0.228978 -0.0584388 0.0036620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 14 42334 -0.008922 0.229778 -0.0620988 0.0036310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 15 42335 -0.009622 0.230478 -0.0656749 0.0035060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 16 42336 -0.010421 0.231179 -0.0690799 0.0032970 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 17 42337 -0.011121 0.231979 -0.0722760 0.0030780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 18 42338 -0.011921 0.232679 -0.0752600 0.0028970 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 19 42339 -0.012620 0.233380 -0.0780840 0.0027620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 20 42340 -0.013320 0.233980 -0.0808081 0.0026980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 21 42341 -0.014020 0.234680 -0.0835001 0.0026950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 22 42342 -0.014720 0.235280 -0.0862032 0.0027370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 23 42343 -0.015419 0.235981 -0.0889742 0.0028000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 24 42344 -0.016019 0.236581 -0.0918073 0.0028780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 25 42345 -0.016719 0.237181 -0.0947193 0.0029530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 26 42346 -0.017319 0.237781 -0.0977084 0.0030200 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 27 42347 -0.017918 0.238382 -0.1007384 0.0030540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 28 42348 -0.018618 0.238982 -0.1038015 0.0030560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 29 42349 -0.019218 0.239482 -0.1068355 0.0030130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 30 42350 -0.019817 0.240083 -0.1098146 0.0029390 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 10 31 42351 -0.020417 0.240583 -0.1127036 0.0028360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 1 42352 -0.021017 0.241183 -0.1154847 0.0027370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 2 42353 -0.021617 0.241683 -0.1181767 0.0026640 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 3 42354 -0.022116 0.242184 -0.1208208 0.0026480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 4 42355 -0.022716 0.242684 -0.1235068 0.0027280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 5 42356 -0.023316 0.243184 -0.1263019 0.0028720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 6 42357 -0.023916 0.243684 -0.1292669 0.0030660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 7 42358 -0.024415 0.244085 -0.1324360 0.0032700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 8 42359 -0.025015 0.244585 -0.1357960 0.0034410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 9 42360 -0.025615 0.244985 -0.1392951 0.0035420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 10 42361 -0.026114 0.245486 -0.1428491 0.0035530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 11 42362 -0.026714 0.245886 -0.1463692 0.0034620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 12 42363 -0.027214 0.246286 -0.1497512 0.0033030 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 13 42364 -0.027814 0.246686 -0.1529563 0.0031160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 14 42365 -0.028313 0.247087 -0.1559773 0.0029330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 15 42366 -0.028913 0.247487 -0.1588394 0.0028000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 16 42367 -0.029413 0.247787 -0.1616104 0.0027450 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 17 42368 -0.029913 0.248187 -0.1643505 0.0027440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 18 42369 -0.030512 0.248488 -0.1671155 0.0027940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 19 42370 -0.031012 0.248888 -0.1699486 0.0028780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 20 42371 -0.031512 0.249188 -0.1728766 0.0029780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 21 42372 -0.032111 0.249489 -0.1758967 0.0030810 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 22 42373 -0.032611 0.249889 -0.1790237 0.0031590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 23 42374 -0.033111 0.250189 -0.1822158 0.0032210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 24 42375 -0.033611 0.250489 -0.1854418 0.0032360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 25 42376 -0.034210 0.250790 -0.1886739 0.0032110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 26 42377 -0.034710 0.251190 -0.1918609 0.0031470 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 27 42378 -0.035210 0.251490 -0.1949570 0.0030510 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 28 42379 -0.035709 0.251791 -0.1979490 0.0029310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 29 42380 -0.036209 0.252191 -0.2008341 0.0028330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 11 30 42381 -0.036709 0.252491 -0.2036301 0.0027710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 1 42382 -0.037109 0.252891 -0.2063892 0.0027810 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 2 42383 -0.037608 0.253192 -0.2092102 0.0028610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 3 42384 -0.038108 0.253592 -0.2121423 0.0030100 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 4 42385 -0.038508 0.253992 -0.2152243 0.0031740 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 5 42386 -0.038908 0.254392 -0.2184684 0.0032940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 6 42387 -0.039407 0.254693 -0.2217974 0.0033510 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 7 42388 -0.039807 0.255193 -0.2251495 0.0033280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 8 42389 -0.040207 0.255593 -0.2284266 0.0032230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 9 42390 -0.040606 0.255994 -0.2315746 0.0030570 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 10 42391 -0.041006 0.256394 -0.2345297 0.0028620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 11 42392 -0.041406 0.256894 -0.2373027 0.0026750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 12 42393 -0.041806 0.257294 -0.2399048 0.0025270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 13 42394 -0.042205 0.257795 -0.2423758 0.0024360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 14 42395 -0.042505 0.258195 -0.2447979 0.0024090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 15 42396 -0.042905 0.258695 -0.2472219 0.0024380 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 16 42397 -0.043305 0.259195 -0.2496960 0.0025060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 17 42398 -0.043604 0.259696 -0.2522410 0.0025940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 18 42399 -0.044004 0.260196 -0.2548761 0.0026750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 19 42400 -0.044404 0.260796 -0.2575871 0.0027540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 20 42401 -0.044703 0.261297 -0.2603752 0.0027980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 21 42402 -0.045103 0.261897 -0.2631833 0.0028200 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 22 42403 -0.045403 0.262497 -0.2660033 0.0028050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 23 42404 -0.045803 0.262997 -0.2687794 0.0027440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 24 42405 -0.046102 0.263598 -0.2714904 0.0026630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 25 42406 -0.046502 0.264298 -0.2740985 0.0025640 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 26 42407 -0.046802 0.264898 -0.2766195 0.0024690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 27 42408 -0.047202 0.265498 -0.2790476 0.0024060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 28 42409 -0.047501 0.266199 -0.2814426 0.0023970 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 29 42410 -0.047801 0.266799 -0.2838697 0.0024800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 30 42411 -0.048101 0.267499 -0.2864298 0.0026390 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1974 12 31 42412 -0.048400 0.268200 -0.2891688 0.0028430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 1 42413 -0.048700 0.268900 0.7078931 0.0030250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 2 42414 -0.049000 0.269600 0.7048071 0.0031300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 3 42415 -0.049200 0.270400 0.7016570 0.0031400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 4 42416 -0.049499 0.271101 0.6985700 0.0030400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 5 42417 -0.049699 0.271901 0.6956009 0.0028790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 6 42418 -0.049899 0.272601 0.6928118 0.0026900 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 7 42419 -0.049999 0.273401 0.6902078 0.0025210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 8 42420 -0.050098 0.274202 0.6877557 0.0023910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 9 42421 -0.050198 0.275002 0.6854077 0.0023160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 10 42422 -0.050298 0.275802 0.6831036 0.0023020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 11 42423 -0.050297 0.276703 0.6807936 0.0023360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 12 42424 -0.050297 0.277503 0.6784155 0.0024260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 13 42425 -0.050197 0.278403 0.6759234 0.0025520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 14 42426 -0.050097 0.279203 0.6733104 0.0026650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 15 42427 -0.049996 0.280104 0.6705873 0.0027770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 16 42428 -0.049796 0.281004 0.6677733 0.0028560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 17 42429 -0.049596 0.281904 0.6648852 0.0029030 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 18 42430 -0.049296 0.282704 0.6619791 0.0029130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 19 42431 -0.048995 0.283605 0.6590711 0.0028880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 20 42432 -0.048595 0.284505 0.6562140 0.0028330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 21 42433 -0.048195 0.285405 0.6534220 0.0027590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 22 42434 -0.047794 0.286306 0.6507059 0.0026750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 23 42435 -0.047294 0.287306 0.6480649 0.0026020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 24 42436 -0.046694 0.288206 0.6454728 0.0025910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 25 42437 -0.046094 0.289106 0.6428557 0.0026580 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 26 42438 -0.045493 0.290107 0.6401287 0.0027990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 27 42439 -0.044893 0.291007 0.6372266 0.0030040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 28 42440 -0.044193 0.292007 0.6341176 0.0032190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 29 42441 -0.043393 0.293007 0.6308075 0.0033880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 30 42442 -0.042692 0.293908 0.6273794 0.0034570 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 1 31 42443 -0.041892 0.294908 0.6239354 0.0034010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 1 42444 -0.040992 0.296008 0.6206013 0.0032620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 2 42445 -0.040191 0.297009 0.6174183 0.0030710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 3 42446 -0.039291 0.298009 0.6144482 0.0028720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 4 42447 -0.038391 0.299109 0.6116611 0.0027220 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 5 42448 -0.037491 0.300209 0.6089931 0.0026230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 6 42449 -0.036590 0.301310 0.6063930 0.0025980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 7 42450 -0.035590 0.302410 0.6037769 0.0026320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 8 42451 -0.034590 0.303610 0.6011129 0.0027050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 9 42452 -0.033590 0.304710 0.5983668 0.0028010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 10 42453 -0.032589 0.305911 0.5955048 0.0029130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 11 42454 -0.031589 0.307111 0.5925307 0.0030210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 12 42455 -0.030589 0.308311 0.5894696 0.0031080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 13 42456 -0.029488 0.309612 0.5863366 0.0031530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 14 42457 -0.028488 0.310812 0.5831875 0.0031500 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 15 42458 -0.027388 0.312112 0.5800485 0.0031100 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 16 42459 -0.026288 0.313312 0.5769774 0.0030280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 17 42460 -0.025187 0.314613 0.5739993 0.0029250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 18 42461 -0.024087 0.315813 0.5711293 0.0028160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 19 42462 -0.022987 0.317113 0.5683632 0.0027120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 20 42463 -0.021786 0.318314 0.5656821 0.0026480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 21 42464 -0.020586 0.319514 0.5630341 0.0026500 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 22 42465 -0.019386 0.320714 0.5603550 0.0027250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 23 42466 -0.018186 0.321914 0.5575489 0.0028880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 24 42467 -0.016985 0.323115 0.5545629 0.0030960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 25 42468 -0.015685 0.324215 0.5513728 0.0032890 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 26 42469 -0.014485 0.325315 0.5480238 0.0034010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 27 42470 -0.013185 0.326415 0.5446127 0.0033960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 2 28 42471 -0.011884 0.327516 0.5412646 0.0032710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 1 42472 -0.010484 0.328516 0.5381126 0.0030430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 2 42473 -0.009184 0.329516 0.5351785 0.0028030 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 3 42474 -0.007783 0.330517 0.5324964 0.0025880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 4 42475 -0.006383 0.331417 0.5299814 0.0024440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 5 42476 -0.004983 0.332217 0.5275853 0.0023700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 6 42477 -0.003483 0.333117 0.5252212 0.0023700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 7 42478 -0.002082 0.333918 0.5228372 0.0024120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 8 42479 -0.000582 0.334618 0.5203731 0.0025120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 9 42480 0.000918 0.335318 0.5178050 0.0026340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 10 42481 0.002418 0.336018 0.5151120 0.0027610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 11 42482 0.004019 0.336619 0.5122879 0.0028730 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 12 42483 0.005519 0.337119 0.5093759 0.0029580 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 13 42484 0.007119 0.337719 0.5063748 0.0030260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 14 42485 0.008720 0.338120 0.5033357 0.0030460 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 15 42486 0.010320 0.338520 0.5003037 0.0030210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 16 42487 0.011920 0.338920 0.4973026 0.0029700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 17 42488 0.013520 0.339220 0.4943575 0.0029070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 18 42489 0.015221 0.339521 0.4914845 0.0028520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 19 42490 0.016921 0.339721 0.4886424 0.0028190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 20 42491 0.018621 0.339921 0.4858193 0.0028400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 21 42492 0.020321 0.340021 0.4829383 0.0029240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 22 42493 0.022022 0.340122 0.4799352 0.0030840 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 23 42494 0.023722 0.340122 0.4767401 0.0032950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 24 42495 0.025422 0.340022 0.4733281 0.0035260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 25 42496 0.027223 0.340023 0.4697100 0.0037080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 26 42497 0.028923 0.339823 0.4659439 0.0037950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 27 42498 0.030723 0.339623 0.4621619 0.0037460 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 28 42499 0.032523 0.339423 0.4584918 0.0035780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 29 42500 0.034224 0.339124 0.4550297 0.0033290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 30 42501 0.036024 0.338724 0.4518277 0.0030790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 3 31 42502 0.037824 0.338324 0.4488576 0.0028620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 1 42503 0.039524 0.337924 0.4460695 0.0027260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 2 42504 0.041225 0.337325 0.4433814 0.0026610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 3 42505 0.043025 0.336825 0.4407284 0.0026540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 4 42506 0.044725 0.336125 0.4380493 0.0026980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 5 42507 0.046426 0.335426 0.4353232 0.0027670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 6 42508 0.048126 0.334726 0.4325122 0.0028450 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 7 42509 0.049726 0.333926 0.4296341 0.0029080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 8 42510 0.051326 0.333026 0.4267030 0.0029590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 9 42511 0.052927 0.332127 0.4237270 0.0029870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 10 42512 0.054527 0.331227 0.4207509 0.0029780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 11 42513 0.056127 0.330227 0.4177818 0.0029440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 12 42514 0.057627 0.329127 0.4148638 0.0029000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 13 42515 0.059028 0.328128 0.4119867 0.0028400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 14 42516 0.060528 0.326928 0.4091936 0.0027600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 15 42517 0.061928 0.325728 0.4064586 0.0027140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 16 42518 0.063329 0.324529 0.4037495 0.0027140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 17 42519 0.064629 0.323329 0.4010094 0.0027780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 18 42520 0.065929 0.322029 0.3981803 0.0029010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 19 42521 0.067229 0.320729 0.3951873 0.0030930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 20 42522 0.068430 0.319430 0.3919832 0.0033060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 21 42523 0.069630 0.318030 0.3885781 0.0035080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 22 42524 0.070830 0.316730 0.3849781 0.0036600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 23 42525 0.072030 0.315330 0.3812920 0.0036940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 24 42526 0.073131 0.313931 0.3776269 0.0036270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 25 42527 0.074231 0.312531 0.3740778 0.0034600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 26 42528 0.075231 0.311131 0.3707218 0.0032490 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 27 42529 0.076332 0.309732 0.3675657 0.0030510 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 28 42530 0.077332 0.308432 0.3645926 0.0029080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 29 42531 0.078332 0.307032 0.3617346 0.0028280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 4 30 42532 0.079332 0.305632 0.3589235 0.0028050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 1 42533 0.080333 0.304233 0.3561094 0.0028280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 2 42534 0.081233 0.302833 0.3532573 0.0028790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 3 42535 0.082233 0.301533 0.3503573 0.0029320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 4 42536 0.083133 0.300133 0.3473952 0.0029810 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 5 42537 0.084034 0.298834 0.3444001 0.0030040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 6 42538 0.084934 0.297534 0.3413951 0.0030100 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 7 42539 0.085834 0.296234 0.3383920 0.0029810 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 8 42540 0.086635 0.294935 0.3354359 0.0029260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 9 42541 0.087535 0.293635 0.3325488 0.0028420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 10 42542 0.088435 0.292335 0.3297578 0.0027380 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 11 42543 0.089235 0.291135 0.3270837 0.0026300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 12 42544 0.090136 0.289836 0.3245006 0.0025380 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 13 42545 0.090936 0.288636 0.3219935 0.0024850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 14 42546 0.091836 0.287436 0.3195105 0.0025010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 15 42547 0.092637 0.286237 0.3169784 0.0025740 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 16 42548 0.093437 0.285037 0.3143443 0.0027130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 17 42549 0.094337 0.283837 0.3115423 0.0028830 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 18 42550 0.095237 0.282637 0.3085812 0.0030450 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 19 42551 0.096038 0.281438 0.3054681 0.0031710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 20 42552 0.096938 0.280338 0.3022640 0.0032110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 21 42553 0.097838 0.279138 0.2990760 0.0031610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 22 42554 0.098738 0.278038 0.2959809 0.0030270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 23 42555 0.099739 0.276839 0.2930398 0.0028390 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 24 42556 0.100639 0.275739 0.2902967 0.0026410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 25 42557 0.101639 0.274539 0.2877467 0.0024770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 26 42558 0.102640 0.273440 0.2853216 0.0023760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 27 42559 0.103640 0.272340 0.2829715 0.0023340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 28 42560 0.104740 0.271140 0.2806234 0.0023590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 29 42561 0.105840 0.270040 0.2782514 0.0023990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 30 42562 0.106941 0.268941 0.2758113 0.0024620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 5 31 42563 0.108141 0.267841 0.2733182 0.0025220 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 1 42564 0.109241 0.266641 0.2707721 0.0025680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 2 42565 0.110441 0.265541 0.2682001 0.0025890 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 3 42566 0.111642 0.264442 0.2656130 0.0025680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 4 42567 0.112942 0.263342 0.2630649 0.0025230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 5 42568 0.114242 0.262242 0.2605778 0.0024570 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 6 42569 0.115443 0.261043 0.2581698 0.0023600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 7 42570 0.116843 0.259943 0.2558617 0.0022650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 8 42571 0.118143 0.258843 0.2536456 0.0021700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 9 42572 0.119443 0.257743 0.2515005 0.0021180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 10 42573 0.120744 0.256544 0.2493825 0.0021300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 11 42574 0.122044 0.255444 0.2472284 0.0022000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 12 42575 0.123344 0.254344 0.2449613 0.0023430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 13 42576 0.124644 0.253144 0.2425302 0.0025220 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 14 42577 0.125945 0.252045 0.2399191 0.0026950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 15 42578 0.127245 0.250845 0.2371561 0.0028200 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 16 42579 0.128445 0.249745 0.2343150 0.0028670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 17 42580 0.129746 0.248546 0.2314619 0.0028270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 18 42581 0.130846 0.247346 0.2286868 0.0027010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 19 42582 0.132046 0.246246 0.2260758 0.0025270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 20 42583 0.133046 0.245046 0.2236377 0.0023390 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 21 42584 0.134147 0.243747 0.2213806 0.0021730 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 22 42585 0.135047 0.242547 0.2192645 0.0020580 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 23 42586 0.136047 0.241347 0.2172524 0.0019880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 24 42587 0.136847 0.240047 0.2152684 0.0019800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 25 42588 0.137648 0.238748 0.2132683 0.0020150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 26 42589 0.138448 0.237448 0.2112302 0.0020720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 27 42590 0.139048 0.236148 0.2091351 0.0021190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 28 42591 0.139649 0.234849 0.2069981 0.0021510 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 29 42592 0.140249 0.233449 0.2048410 0.0021590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 6 30 42593 0.140749 0.232149 0.2026909 0.0021350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 1 42594 0.141149 0.230749 0.2005818 0.0020780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 2 42595 0.141450 0.229250 0.1985457 0.0019990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 3 42596 0.141750 0.227850 0.1965907 0.0018980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 4 42597 0.141950 0.226450 0.1947436 0.0017860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 5 42598 0.142150 0.224950 0.1930075 0.0016890 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 6 42599 0.142251 0.223451 0.1913674 0.0016180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 7 42600 0.142251 0.222051 0.1897663 0.0015940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 8 42601 0.142251 0.220551 0.1881473 0.0016360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 9 42602 0.142252 0.218952 0.1864592 0.0017600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 10 42603 0.142152 0.217452 0.1846181 0.0019270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 11 42604 0.141952 0.215952 0.1825900 0.0021160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 12 42605 0.141752 0.214452 0.1804119 0.0022510 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 13 42606 0.141553 0.212853 0.1781169 0.0023110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 14 42607 0.141253 0.211353 0.1758128 0.0022780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 15 42608 0.140953 0.209753 0.1736007 0.0021450 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 16 42609 0.140653 0.208253 0.1715406 0.0019680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 17 42610 0.140254 0.206654 0.1696785 0.0017770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 18 42611 0.139854 0.205054 0.1679885 0.0016110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 19 42612 0.139454 0.203454 0.1664314 0.0015020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 20 42613 0.139055 0.201955 0.1649633 0.0014450 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 21 42614 0.138555 0.200355 0.1635202 0.0014590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 22 42615 0.138155 0.198755 0.1620271 0.0015330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 23 42616 0.137655 0.197155 0.1604541 0.0016270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 24 42617 0.137156 0.195556 0.1587700 0.0017290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 25 42618 0.136756 0.193956 0.1569889 0.0018300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 26 42619 0.136256 0.192456 0.1551188 0.0019070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 27 42620 0.135756 0.190856 0.1531867 0.0019510 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 28 42621 0.135257 0.189257 0.1512366 0.0019620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 29 42622 0.134757 0.187657 0.1492846 0.0019400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 30 42623 0.134257 0.186057 0.1473745 0.0018940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 7 31 42624 0.133858 0.184558 0.1455114 0.0018230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 1 42625 0.133358 0.182958 0.1437173 0.0017640 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 2 42626 0.132858 0.181458 0.1419662 0.0017240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 3 42627 0.132358 0.179858 0.1402571 0.0017220 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 4 42628 0.131859 0.178359 0.1385121 0.0017710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 5 42629 0.131459 0.176759 0.1366810 0.0018920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 6 42630 0.130959 0.175259 0.1347139 0.0020720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 7 42631 0.130460 0.173760 0.1325248 0.0023100 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 8 42632 0.129960 0.172260 0.1300997 0.0025320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 9 42633 0.129460 0.170760 0.1274856 0.0026810 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 10 42634 0.128960 0.169260 0.1247766 0.0027260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 11 42635 0.128561 0.167861 0.1220715 0.0026560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 12 42636 0.128061 0.166361 0.1194934 0.0024910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 13 42637 0.127561 0.164861 0.1170993 0.0022960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 14 42638 0.126961 0.163461 0.1148952 0.0021190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 15 42639 0.126462 0.162062 0.1128431 0.0020050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 16 42640 0.125962 0.160662 0.1108741 0.0019460 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 17 42641 0.125362 0.159262 0.1089310 0.0019400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 18 42642 0.124763 0.157863 0.1069669 0.0019960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 19 42643 0.124263 0.156463 0.1049258 0.0020790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 20 42644 0.123563 0.155063 0.1028127 0.0021680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 21 42645 0.122963 0.153663 0.1006016 0.0022530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 22 42646 0.122264 0.152364 0.0983136 0.0023190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 23 42647 0.121564 0.150964 0.0959745 0.0023530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 24 42648 0.120764 0.149664 0.0936194 0.0023510 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 25 42649 0.120064 0.148364 0.0912833 0.0023170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 26 42650 0.119265 0.147065 0.0890042 0.0022450 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 27 42651 0.118365 0.145665 0.0867981 0.0021560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 28 42652 0.117465 0.144365 0.0846940 0.0020640 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 29 42653 0.116566 0.143066 0.0826660 0.0019850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 30 42654 0.115566 0.141766 0.0807039 0.0019370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 8 31 42655 0.114566 0.140566 0.0787648 0.0019490 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 1 42656 0.113466 0.139266 0.0767817 0.0020290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 2 42657 0.112367 0.137967 0.0746836 0.0021800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 3 42658 0.111267 0.136667 0.0723925 0.0023990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 4 42659 0.110067 0.135467 0.0698794 0.0026370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 5 42660 0.108767 0.134167 0.0671334 0.0028360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 6 42661 0.107468 0.132968 0.0642403 0.0029400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 7 42662 0.106168 0.131768 0.0612952 0.0029280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 8 42663 0.104768 0.130468 0.0584231 0.0028000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 9 42664 0.103369 0.129269 0.0557280 0.0026030 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 10 42665 0.101869 0.128069 0.0532199 0.0024080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 11 42666 0.100369 0.126869 0.0509078 0.0022460 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 12 42667 0.098869 0.125669 0.0487137 0.0021540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 13 42668 0.097270 0.124570 0.0465757 0.0021330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 14 42669 0.095670 0.123370 0.0444286 0.0021700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 15 42670 0.093970 0.122170 0.0422135 0.0022560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 16 42671 0.092270 0.121070 0.0399194 0.0023540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 17 42672 0.090571 0.119971 0.0375143 0.0024560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 18 42673 0.088771 0.118871 0.0350022 0.0025550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 19 42674 0.086971 0.117771 0.0324131 0.0026170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 20 42675 0.085172 0.116672 0.0297780 0.0026560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 21 42676 0.083372 0.115572 0.0271240 0.0026590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 22 42677 0.081472 0.114572 0.0244809 0.0026330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 23 42678 0.079472 0.113472 0.0218748 0.0025760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 24 42679 0.077573 0.112473 0.0193207 0.0025220 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 25 42680 0.075573 0.111473 0.0168176 0.0024760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 26 42681 0.073573 0.110473 0.0143605 0.0024530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 27 42682 0.071573 0.109473 0.0118964 0.0024740 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 28 42683 0.069474 0.108474 0.0093943 0.0025410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 29 42684 0.067374 0.107574 0.0067912 0.0026850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 9 30 42685 0.065274 0.106574 0.0040132 0.0028810 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 1 42686 0.063175 0.105675 0.0010151 0.0031170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 2 42687 0.060975 0.104775 -0.0022200 0.0033490 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 3 42688 0.058775 0.103975 -0.0056741 0.0035240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 4 42689 0.056575 0.103075 -0.0092432 0.0036050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 5 42690 0.054276 0.102276 -0.0128333 0.0035540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 6 42691 0.051976 0.101476 -0.0163184 0.0034020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 7 42692 0.049676 0.100776 -0.0196205 0.0032020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 8 42693 0.047276 0.100076 -0.0227256 0.0030050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 9 42694 0.044877 0.099377 -0.0256597 0.0028770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 10 42695 0.042477 0.098677 -0.0284947 0.0028150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 11 42696 0.040077 0.098077 -0.0313018 0.0028200 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 12 42697 0.037578 0.097478 -0.0341399 0.0028610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 13 42698 0.035078 0.096978 -0.0370430 0.0029370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 14 42699 0.032478 0.096478 -0.0400161 0.0030090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 15 42700 0.029978 0.096078 -0.0430692 0.0030850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 16 42701 0.027379 0.095679 -0.0461693 0.0031320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 17 42702 0.024679 0.095279 -0.0493124 0.0031480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 18 42703 0.022079 0.094979 -0.0524555 0.0031300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 19 42704 0.019379 0.094779 -0.0555536 0.0030710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 20 42705 0.016680 0.094580 -0.0585897 0.0029990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 21 42706 0.013880 0.094480 -0.0615377 0.0029060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 22 42707 0.011080 0.094380 -0.0644038 0.0028260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 23 42708 0.008381 0.094281 -0.0671859 0.0027540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 24 42709 0.005581 0.094381 -0.0699240 0.0027280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 25 42710 0.002681 0.094381 -0.0726581 0.0027410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 26 42711 -0.000119 0.094581 -0.0754362 0.0028240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 27 42712 -0.002918 0.094682 -0.0783273 0.0029650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 28 42713 -0.005818 0.094982 -0.0813904 0.0031580 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 29 42714 -0.008718 0.095282 -0.0846465 0.0033540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 30 42715 -0.011517 0.095583 -0.0880886 0.0035320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 10 31 42716 -0.014417 0.095983 -0.0916877 0.0036410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 1 42717 -0.017217 0.096483 -0.0953478 0.0036500 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 2 42718 -0.020017 0.096983 -0.0989519 0.0035560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 3 42719 -0.022816 0.097484 -0.1024339 0.0033880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 4 42720 -0.025616 0.098184 -0.1057220 0.0031990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 5 42721 -0.028416 0.098784 -0.1088331 0.0030420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 6 42722 -0.031116 0.099584 -0.1118182 0.0029420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 7 42723 -0.033915 0.100285 -0.1147503 0.0029140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 8 42724 -0.036515 0.101185 -0.1176754 0.0029530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 9 42725 -0.039215 0.101985 -0.1206575 0.0030130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 10 42726 -0.041814 0.102986 -0.1237036 0.0030810 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 11 42727 -0.044314 0.103886 -0.1268167 0.0031430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 12 42728 -0.046914 0.104986 -0.1299738 0.0031780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 13 42729 -0.049414 0.105986 -0.1331649 0.0031990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 14 42730 -0.051813 0.107187 -0.1363610 0.0031780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 15 42731 -0.054213 0.108287 -0.1395121 0.0031270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 16 42732 -0.056613 0.109487 -0.1426072 0.0030610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 17 42733 -0.058913 0.110787 -0.1456283 0.0029710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 18 42734 -0.061212 0.111988 -0.1485484 0.0028700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 19 42735 -0.063512 0.113388 -0.1513734 0.0027940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 20 42736 -0.065812 0.114688 -0.1541465 0.0027470 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 21 42737 -0.068011 0.116089 -0.1568826 0.0027360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 22 42738 -0.070211 0.117489 -0.1596367 0.0027900 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 23 42739 -0.072511 0.118989 -0.1624708 0.0028880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 24 42740 -0.074611 0.120489 -0.1654259 0.0030360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 25 42741 -0.076810 0.121990 -0.1685390 0.0031890 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 26 42742 -0.079010 0.123490 -0.1718071 0.0033320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 27 42743 -0.081210 0.125090 -0.1751752 0.0034120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 28 42744 -0.083410 0.126690 -0.1786063 0.0034260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 29 42745 -0.085509 0.128391 -0.1819994 0.0033550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 11 30 42746 -0.087709 0.129991 -0.1852935 0.0032020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 1 42747 -0.089909 0.131691 -0.1884006 0.0030220 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 2 42748 -0.092008 0.133492 -0.1913287 0.0028390 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 3 42749 -0.094208 0.135192 -0.1940948 0.0027040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 4 42750 -0.096308 0.136992 -0.1967589 0.0026370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 5 42751 -0.098508 0.138792 -0.1994000 0.0026340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 6 42752 -0.100607 0.140593 -0.2020501 0.0026720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 7 42753 -0.102707 0.142393 -0.2047592 0.0027350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 8 42754 -0.104807 0.144293 -0.2075083 0.0027820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 9 42755 -0.106907 0.146193 -0.2103064 0.0028100 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 10 42756 -0.108906 0.148094 -0.2131205 0.0028230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 11 42757 -0.110906 0.149994 -0.2159436 0.0028180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 12 42758 -0.112906 0.151994 -0.2187556 0.0027930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 13 42759 -0.114805 0.153895 -0.2215097 0.0027310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 14 42760 -0.116705 0.155895 -0.2242138 0.0026740 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 15 42761 -0.118605 0.157895 -0.2268559 0.0026030 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 16 42762 -0.120405 0.159895 -0.2294230 0.0025430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 17 42763 -0.122204 0.161996 -0.2319521 0.0025210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 18 42764 -0.123904 0.163996 -0.2344782 0.0025290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 19 42765 -0.125504 0.166096 -0.2370283 0.0025810 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 20 42766 -0.127104 0.168096 -0.2396594 0.0026900 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 21 42767 -0.128703 0.170197 -0.2424235 0.0028330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 22 42768 -0.130203 0.172297 -0.2453416 0.0030030 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 23 42769 -0.131603 0.174397 -0.2484117 0.0031330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 24 42770 -0.133002 0.176598 -0.2515988 0.0032180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 25 42771 -0.134302 0.178698 -0.2548229 0.0032270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 26 42772 -0.135602 0.180898 -0.2580170 0.0031490 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 27 42773 -0.136802 0.183098 -0.2611001 0.0030080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 28 42774 -0.138001 0.185299 -0.2640112 0.0028210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 29 42775 -0.139101 0.187499 -0.2667423 0.0026450 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 30 42776 -0.140201 0.189699 -0.2693124 0.0025040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1975 12 31 42777 -0.141201 0.191999 -0.2717695 0.0024220 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 1 42778 -0.142200 0.194300 0.7258224 0.0024030 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 2 42779 -0.143200 0.196600 0.7233963 0.0024470 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 3 42780 -0.144100 0.199000 0.7209292 0.0025060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 4 42781 -0.144899 0.201301 0.7183831 0.0025760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 5 42782 -0.145799 0.203701 0.7157740 0.0026370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 6 42783 -0.146599 0.206201 0.7131179 0.0026700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 7 42784 -0.147299 0.208601 0.7104348 0.0026810 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 8 42785 -0.147998 0.211102 0.7077667 0.0026620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 9 42786 -0.148698 0.213602 0.7051216 0.0026150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 10 42787 -0.149398 0.216102 0.7025425 0.0025490 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 11 42788 -0.149998 0.218602 0.7000254 0.0024860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 12 42789 -0.150597 0.221203 0.6975683 0.0024210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 13 42790 -0.151097 0.223803 0.6951652 0.0023890 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 14 42791 -0.151697 0.226403 0.6927751 0.0024060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 15 42792 -0.152096 0.229004 0.6903350 0.0024750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 16 42793 -0.152596 0.231604 0.6877959 0.0026030 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 17 42794 -0.152996 0.234204 0.6850998 0.0027970 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 18 42795 -0.153396 0.236804 0.6822017 0.0030110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 19 42796 -0.153795 0.239405 0.6790806 0.0032160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 20 42797 -0.154195 0.242005 0.6757775 0.0033770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 21 42798 -0.154495 0.244605 0.6723654 0.0034420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 22 42799 -0.154795 0.247305 0.6689343 0.0034140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 23 42800 -0.154994 0.249906 0.6655612 0.0033120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 24 42801 -0.155194 0.252506 0.6623221 0.0031620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 25 42802 -0.155394 0.255106 0.6592360 0.0030130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 26 42803 -0.155593 0.257607 0.6562849 0.0028970 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 27 42804 -0.155693 0.260207 0.6534228 0.0028270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 28 42805 -0.155793 0.262707 0.6506107 0.0028090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 29 42806 -0.155893 0.265307 0.6477876 0.0028360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 30 42807 -0.155892 0.267808 0.6449255 0.0029010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 1 31 42808 -0.155892 0.270308 0.6419804 0.0029780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 1 42809 -0.155792 0.272808 0.6389723 0.0030340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 2 42810 -0.155691 0.275309 0.6359212 0.0030730 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 3 42811 -0.155591 0.277709 0.6328471 0.0030680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 4 42812 -0.155391 0.280209 0.6297960 0.0030380 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 5 42813 -0.155191 0.282609 0.6267819 0.0029780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 6 42814 -0.154990 0.285010 0.6238478 0.0028960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 7 42815 -0.154690 0.287410 0.6210037 0.0028020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 8 42816 -0.154290 0.289810 0.6182526 0.0027000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 9 42817 -0.153990 0.292110 0.6155855 0.0026270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 10 42818 -0.153489 0.294411 0.6129773 0.0025870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 11 42819 -0.153089 0.296811 0.6103852 0.0025950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 12 42820 -0.152589 0.299111 0.6077681 0.0026620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 13 42821 -0.151988 0.301312 0.6050400 0.0027920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 14 42822 -0.151388 0.303612 0.6021659 0.0029620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 15 42823 -0.150788 0.305912 0.5991008 0.0031570 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 16 42824 -0.150088 0.308112 0.5958627 0.0033090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 17 42825 -0.149387 0.310313 0.5925106 0.0033900 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 18 42826 -0.148687 0.312513 0.5891295 0.0033530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 19 42827 -0.147887 0.314713 0.5858384 0.0032240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 20 42828 -0.147087 0.316913 0.5827123 0.0030220 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 21 42829 -0.146286 0.319014 0.5797892 0.0028260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 22 42830 -0.145386 0.321214 0.5770501 0.0026700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 23 42831 -0.144486 0.323314 0.5744390 0.0025720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 24 42832 -0.143585 0.325415 0.5718939 0.0025380 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 25 42833 -0.142585 0.327415 0.5693428 0.0025620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 26 42834 -0.141585 0.329515 0.5667447 0.0026390 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 27 42835 -0.140585 0.331515 0.5640576 0.0027380 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 28 42836 -0.139584 0.333516 0.5612685 0.0028370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 2 29 42837 -0.138584 0.335516 0.5583884 0.0029280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 1 42838 -0.137484 0.337416 0.5554223 0.0029870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 2 42839 -0.136484 0.339316 0.5524262 0.0030110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 3 42840 -0.135383 0.341217 0.5494011 0.0030110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 4 42841 -0.134183 0.343117 0.5464020 0.0029760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 5 42842 -0.133083 0.344917 0.5434559 0.0029240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 6 42843 -0.131982 0.346718 0.5405537 0.0028700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 7 42844 -0.130782 0.348518 0.5377126 0.0028260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 8 42845 -0.129582 0.350318 0.5349025 0.0027990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 9 42846 -0.128382 0.352018 0.5320894 0.0028140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 10 42847 -0.127181 0.353719 0.5292463 0.0028820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 11 42848 -0.125981 0.355419 0.5263042 0.0030120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 12 42849 -0.124681 0.357119 0.5232021 0.0031910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 13 42850 -0.123381 0.358719 0.5199000 0.0034090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 14 42851 -0.122080 0.360420 0.5163739 0.0036370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 15 42852 -0.120780 0.362020 0.5126528 0.0037930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 16 42853 -0.119480 0.363720 0.5088207 0.0038610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 17 42854 -0.118079 0.365321 0.5049686 0.0038140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 18 42855 -0.116679 0.366921 0.5012245 0.0036700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 19 42856 -0.115279 0.368521 0.4976554 0.0034670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 20 42857 -0.113779 0.370221 0.4942783 0.0032830 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 21 42858 -0.112278 0.371822 0.4910722 0.0031500 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 22 42859 -0.110778 0.373422 0.4879550 0.0030870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 23 42860 -0.109178 0.375122 0.4848779 0.0030860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 24 42861 -0.107578 0.376722 0.4817668 0.0031420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 25 42862 -0.105977 0.378423 0.4785847 0.0032130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 26 42863 -0.104277 0.380123 0.4753376 0.0032920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 27 42864 -0.102477 0.381823 0.4719945 0.0033710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 28 42865 -0.100776 0.383524 0.4685924 0.0034270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 29 42866 -0.098876 0.385224 0.4651513 0.0034410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 30 42867 -0.097076 0.387024 0.4617122 0.0034310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 3 31 42868 -0.095076 0.388724 0.4583081 0.0033830 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 1 42869 -0.093175 0.390525 0.4549620 0.0033160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 2 42870 -0.091075 0.392225 0.4516779 0.0032530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 3 42871 -0.089075 0.394025 0.4484658 0.0031750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 4 42872 -0.086975 0.395725 0.4453107 0.0031170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 5 42873 -0.084774 0.397526 0.4422085 0.0030930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 6 42874 -0.082574 0.399326 0.4390984 0.0031150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 7 42875 -0.080374 0.401026 0.4359603 0.0031820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 8 42876 -0.078073 0.402827 0.4327152 0.0033150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 9 42877 -0.075773 0.404527 0.4293221 0.0034870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 10 42878 -0.073373 0.406227 0.4257340 0.0036710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 11 42879 -0.070973 0.407927 0.4219749 0.0038480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 12 42880 -0.068572 0.409628 0.4180688 0.0039500 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 13 42881 -0.066172 0.411228 0.4140997 0.0039510 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 14 42882 -0.063672 0.412828 0.4101926 0.0038440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 15 42883 -0.061172 0.414428 0.4064285 0.0036550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 16 42884 -0.058671 0.415929 0.4028803 0.0034400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 17 42885 -0.056071 0.417429 0.3995382 0.0032530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 18 42886 -0.053571 0.418929 0.3963531 0.0031300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 19 42887 -0.050970 0.420330 0.3932540 0.0030770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 20 42888 -0.048370 0.421730 0.3901699 0.0030780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 21 42889 -0.045770 0.423030 0.3870788 0.0031180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 22 42890 -0.043170 0.424230 0.3839317 0.0031660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 23 42891 -0.040569 0.425431 0.3807486 0.0032160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 24 42892 -0.037969 0.426531 0.3775145 0.0032490 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 25 42893 -0.035369 0.427631 0.3742604 0.0032550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 26 42894 -0.032668 0.428632 0.3710243 0.0032310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 27 42895 -0.030068 0.429632 0.3678071 0.0031880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 28 42896 -0.027468 0.430432 0.3646550 0.0031150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 29 42897 -0.024768 0.431232 0.3615709 0.0030420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 4 30 42898 -0.022167 0.432033 0.3585688 0.0029730 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 1 42899 -0.019567 0.432633 0.3556297 0.0029200 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 2 42900 -0.016867 0.433233 0.3527196 0.0028960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 3 42901 -0.014267 0.433733 0.3498155 0.0029110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 4 42902 -0.011566 0.434234 0.3468824 0.0029740 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 5 42903 -0.008966 0.434534 0.3438503 0.0030880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 6 42904 -0.006266 0.434834 0.3406901 0.0032370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 7 42905 -0.003665 0.435135 0.3373660 0.0034240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 8 42906 -0.000965 0.435235 0.3338529 0.0036010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 9 42907 0.001635 0.435335 0.3301858 0.0037320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 10 42908 0.004335 0.435335 0.3264027 0.0038020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 11 42909 0.007036 0.435336 0.3226036 0.0037790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 12 42910 0.009736 0.435136 0.3188745 0.0036670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 13 42911 0.012436 0.434936 0.3152964 0.0034920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 14 42912 0.015136 0.434736 0.3118903 0.0033150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 15 42913 0.017837 0.434337 0.3086521 0.0031720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 16 42914 0.020537 0.433937 0.3055240 0.0031070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 17 42915 0.023237 0.433537 0.3024259 0.0030960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 18 42916 0.026038 0.432938 0.2993168 0.0031150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 19 42917 0.028838 0.432438 0.2961827 0.0031550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 20 42918 0.031638 0.431738 0.2930106 0.0031850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 21 42919 0.034438 0.431038 0.2898275 0.0031860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 22 42920 0.037239 0.430339 0.2866564 0.0031610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 23 42921 0.040039 0.429539 0.2835142 0.0031090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 24 42922 0.042939 0.428639 0.2804581 0.0030190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 25 42923 0.045839 0.427739 0.2774830 0.0029170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 26 42924 0.048740 0.426740 0.2746189 0.0028020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 27 42925 0.051640 0.425740 0.2718788 0.0026790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 28 42926 0.054540 0.424740 0.2692547 0.0025810 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 29 42927 0.057541 0.423641 0.2667066 0.0025100 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 30 42928 0.060541 0.422541 0.2642225 0.0024750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 5 31 42929 0.063541 0.421341 0.2617413 0.0024960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 1 42930 0.066541 0.420141 0.2592152 0.0025540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 2 42931 0.069542 0.418842 0.2566191 0.0026540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 3 42932 0.072642 0.417542 0.2538980 0.0027800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 4 42933 0.075642 0.416242 0.2510469 0.0029180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 5 42934 0.078742 0.414942 0.2480808 0.0030180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 6 42935 0.081743 0.413543 0.2450287 0.0030650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 7 42936 0.084843 0.412143 0.2419756 0.0030380 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 8 42937 0.087943 0.410643 0.2389874 0.0029370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 9 42938 0.091044 0.409144 0.2361213 0.0027780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 10 42939 0.094144 0.407744 0.2334382 0.0025970 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 11 42940 0.097144 0.406144 0.2309181 0.0024390 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 12 42941 0.100244 0.404644 0.2285410 0.0023270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 13 42942 0.103345 0.403045 0.2262319 0.0022920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 14 42943 0.106345 0.401545 0.2239398 0.0023090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 15 42944 0.109445 0.399945 0.2216076 0.0023490 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 16 42945 0.112445 0.398345 0.2192445 0.0023840 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 17 42946 0.115446 0.396646 0.2168584 0.0023950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 18 42947 0.118446 0.395046 0.2144753 0.0023750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 19 42948 0.121446 0.393346 0.2121162 0.0023260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 20 42949 0.124347 0.391647 0.2098221 0.0022590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 21 42950 0.127347 0.389947 0.2076060 0.0021780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 22 42951 0.130247 0.388247 0.2054808 0.0020720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 23 42952 0.133147 0.386547 0.2034517 0.0019840 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 24 42953 0.135948 0.384748 0.2015176 0.0018980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 25 42954 0.138848 0.382948 0.1996475 0.0018370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 26 42955 0.141648 0.381248 0.1978204 0.0018230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 27 42956 0.144448 0.379348 0.1959863 0.0018540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 28 42957 0.147249 0.377549 0.1940961 0.0019430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 29 42958 0.149949 0.375749 0.1920850 0.0020770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 6 30 42959 0.152649 0.373849 0.1899319 0.0022500 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 1 42960 0.155350 0.371950 0.1875928 0.0024160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 2 42961 0.158050 0.370050 0.1850987 0.0025630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 3 42962 0.160750 0.368150 0.1824836 0.0026550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 4 42963 0.163350 0.366150 0.1798115 0.0026770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 5 42964 0.165951 0.364251 0.1771613 0.0026320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 6 42965 0.168551 0.362251 0.1745752 0.0025350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 7 42966 0.171151 0.360251 0.1720991 0.0024160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 8 42967 0.173751 0.358251 0.1697390 0.0023080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 9 42968 0.176252 0.356252 0.1674679 0.0022440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 10 42969 0.178752 0.354252 0.1652418 0.0022310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 11 42970 0.181252 0.352252 0.1629966 0.0022670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 12 42971 0.183653 0.350153 0.1606935 0.0023410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 13 42972 0.186153 0.348153 0.1583024 0.0024220 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 14 42973 0.188553 0.346153 0.1558463 0.0024850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 15 42974 0.190853 0.344053 0.1533442 0.0025130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 16 42975 0.193154 0.342054 0.1508421 0.0024950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 17 42976 0.195454 0.340054 0.1483649 0.0024540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 18 42977 0.197754 0.337954 0.1459528 0.0023770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 19 42978 0.199955 0.335955 0.1436077 0.0022920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 20 42979 0.202155 0.333855 0.1413616 0.0022000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 21 42980 0.204255 0.331855 0.1392145 0.0021160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 22 42981 0.206255 0.329755 0.1371314 0.0020440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 23 42982 0.208356 0.327656 0.1351032 0.0020270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 24 42983 0.210256 0.325556 0.1330721 0.0020440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 25 42984 0.212156 0.323456 0.1309980 0.0021120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 26 42985 0.214056 0.321356 0.1288319 0.0022390 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 27 42986 0.215857 0.319257 0.1265168 0.0023950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 28 42987 0.217557 0.317057 0.1240266 0.0025750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 29 42988 0.219257 0.314857 0.1213825 0.0027240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 30 42989 0.220958 0.312658 0.1185974 0.0028250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 7 31 42990 0.222458 0.310458 0.1157603 0.0028360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 1 42991 0.223958 0.308158 0.1129422 0.0027780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 2 42992 0.225458 0.305858 0.1102241 0.0026520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 3 42993 0.226759 0.303559 0.1076469 0.0025010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 4 42994 0.228159 0.301159 0.1052168 0.0023630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 5 42995 0.229359 0.298759 0.1029087 0.0022540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 6 42996 0.230559 0.296359 0.1006906 0.0022020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 7 42997 0.231660 0.293860 0.0984935 0.0021890 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 8 42998 0.232660 0.291360 0.0962863 0.0022330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 9 42999 0.233660 0.288860 0.0940212 0.0022980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 10 43000 0.234561 0.286261 0.0916921 0.0023470 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 11 43001 0.235361 0.283661 0.0893270 0.0023780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 12 43002 0.236161 0.281061 0.0869499 0.0023690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 13 43003 0.236861 0.278361 0.0846018 0.0023210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 14 43004 0.237462 0.275662 0.0823086 0.0022510 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 15 43005 0.238062 0.272962 0.0800955 0.0021600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 16 43006 0.238462 0.270262 0.0779814 0.0020690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 17 43007 0.238862 0.267462 0.0759583 0.0019800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 18 43008 0.239263 0.264663 0.0740162 0.0019170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 19 43009 0.239463 0.261863 0.0721220 0.0018850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 20 43010 0.239663 0.258963 0.0702319 0.0018950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 21 43011 0.239764 0.256164 0.0683058 0.0019640 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 22 43012 0.239864 0.253264 0.0662857 0.0020960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 23 43013 0.239764 0.250364 0.0640986 0.0022750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 24 43014 0.239664 0.247464 0.0617254 0.0024850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 25 43015 0.239565 0.244565 0.0591283 0.0027030 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 26 43016 0.239265 0.241665 0.0563432 0.0028670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 27 43017 0.238965 0.238765 0.0534111 0.0029620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 28 43018 0.238565 0.235865 0.0504420 0.0029600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 29 43019 0.238166 0.232866 0.0475178 0.0028780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 30 43020 0.237566 0.229966 0.0447017 0.0027510 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 8 31 43021 0.237066 0.227066 0.0420046 0.0026270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 1 43022 0.236367 0.224067 0.0394245 0.0025420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 2 43023 0.235667 0.221167 0.0369004 0.0025150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 3 43024 0.234867 0.218267 0.0343632 0.0025490 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 4 43025 0.234067 0.215367 0.0317761 0.0026330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 5 43026 0.233168 0.212468 0.0290880 0.0027460 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 6 43027 0.232268 0.209568 0.0262909 0.0028650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 7 43028 0.231268 0.206668 0.0233717 0.0029680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 8 43029 0.230268 0.203768 0.0203646 0.0030380 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 9 43030 0.229169 0.200969 0.0173095 0.0030670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 10 43031 0.228069 0.198169 0.0142434 0.0030600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 11 43032 0.226869 0.195269 0.0112083 0.0030260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 12 43033 0.225670 0.192570 0.0082061 0.0029670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 13 43034 0.224470 0.189770 0.0052650 0.0029160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 14 43035 0.223170 0.187070 0.0023809 0.0028560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 15 43036 0.221970 0.184370 -0.0004562 0.0028210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 16 43037 0.220671 0.181671 -0.0032853 0.0028230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 17 43038 0.219271 0.179071 -0.0061265 0.0028700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 18 43039 0.217971 0.176371 -0.0090316 0.0029580 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 19 43040 0.216571 0.173871 -0.0120597 0.0031060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 20 43041 0.215172 0.171272 -0.0152578 0.0032860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 21 43042 0.213772 0.168872 -0.0186400 0.0034860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 22 43043 0.212372 0.166372 -0.0222151 0.0036700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 23 43044 0.210873 0.163973 -0.0259592 0.0037930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 24 43045 0.209373 0.161573 -0.0297713 0.0038140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 25 43046 0.207973 0.159273 -0.0335634 0.0037450 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 26 43047 0.206473 0.156973 -0.0372376 0.0036020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 27 43048 0.204974 0.154774 -0.0407487 0.0034220 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 28 43049 0.203374 0.152574 -0.0440998 0.0032760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 29 43050 0.201874 0.150374 -0.0473209 0.0031780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 9 30 43051 0.200274 0.148274 -0.0504771 0.0031460 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 1 43052 0.198775 0.146175 -0.0536302 0.0031680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 2 43053 0.197175 0.144175 -0.0568343 0.0032230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 3 43054 0.195575 0.142175 -0.0600904 0.0032890 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 4 43055 0.193976 0.140276 -0.0634105 0.0033480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 5 43056 0.192376 0.138376 -0.0667777 0.0033820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 6 43057 0.190676 0.136476 -0.0701538 0.0033740 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 7 43058 0.188976 0.134676 -0.0735139 0.0033400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 8 43059 0.187377 0.132877 -0.0768240 0.0032750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 9 43060 0.185677 0.131077 -0.0800482 0.0031810 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 10 43061 0.183877 0.129377 -0.0831943 0.0030900 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 11 43062 0.182178 0.127678 -0.0862404 0.0030070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 12 43063 0.180378 0.125978 -0.0892135 0.0029430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 13 43064 0.178578 0.124378 -0.0921367 0.0029190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 14 43065 0.176778 0.122678 -0.0950658 0.0029360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 15 43066 0.174879 0.121079 -0.0980239 0.0029880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 16 43067 0.172979 0.119579 -0.1010690 0.0030990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 17 43068 0.171079 0.117979 -0.1042362 0.0032540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 18 43069 0.169079 0.116479 -0.1075863 0.0034390 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 19 43070 0.167080 0.114980 -0.1111074 0.0036210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 20 43071 0.165080 0.113480 -0.1148185 0.0037820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 21 43072 0.162980 0.111980 -0.1186497 0.0038660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 22 43073 0.160881 0.110481 -0.1225198 0.0038670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 23 43074 0.158781 0.109081 -0.1263529 0.0037770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 24 43075 0.156581 0.107681 -0.1300540 0.0036180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 25 43076 0.154381 0.106281 -0.1335871 0.0034520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 26 43077 0.152082 0.104982 -0.1369813 0.0033270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 27 43078 0.149782 0.103682 -0.1402724 0.0032670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 28 43079 0.147382 0.102382 -0.1435265 0.0032590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 29 43080 0.144982 0.101082 -0.1468146 0.0033020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 30 43081 0.142583 0.099883 -0.1501348 0.0033480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 10 31 43082 0.140083 0.098683 -0.1534989 0.0033760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 1 43083 0.137583 0.097483 -0.1568820 0.0033850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 2 43084 0.135084 0.096384 -0.1602691 0.0033660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 3 43085 0.132484 0.095284 -0.1636143 0.0033170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 4 43086 0.129884 0.094184 -0.1668944 0.0032400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 5 43087 0.127184 0.093184 -0.1700765 0.0031300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 6 43088 0.124585 0.092185 -0.1731516 0.0030100 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 7 43089 0.121785 0.091285 -0.1761078 0.0029040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 8 43090 0.119085 0.090285 -0.1789559 0.0028050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 9 43091 0.116285 0.089385 -0.1817260 0.0027310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 10 43092 0.113486 0.088586 -0.1844302 0.0026930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 11 43093 0.110586 0.087786 -0.1871273 0.0027060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 12 43094 0.107686 0.086886 -0.1898584 0.0027530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 13 43095 0.104787 0.086187 -0.1926465 0.0028400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 14 43096 0.101787 0.085387 -0.1955487 0.0029690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 15 43097 0.098787 0.084687 -0.1985998 0.0031220 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 16 43098 0.095787 0.083987 -0.2017899 0.0032640 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 17 43099 0.092688 0.083288 -0.2051050 0.0033660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 18 43100 0.089588 0.082588 -0.2084982 0.0034090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 19 43101 0.086488 0.081988 -0.2118953 0.0033690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 20 43102 0.083288 0.081388 -0.2152134 0.0032590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 21 43103 0.080189 0.080789 -0.2184005 0.0031140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 22 43104 0.076889 0.080189 -0.2214477 0.0029930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 23 43105 0.073689 0.079589 -0.2243948 0.0029240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 24 43106 0.070390 0.079090 -0.2273079 0.0029110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 25 43107 0.067090 0.078490 -0.2302440 0.0029580 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 26 43108 0.063690 0.077990 -0.2332312 0.0030270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 27 43109 0.060390 0.077490 -0.2362843 0.0030880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 28 43110 0.056991 0.077091 -0.2393994 0.0031250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 29 43111 0.053491 0.076591 -0.2425256 0.0031320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 11 30 43112 0.049991 0.076191 -0.2456437 0.0031000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 1 43113 0.046491 0.075791 -0.2487168 0.0030420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 2 43114 0.042992 0.075392 -0.2517309 0.0029740 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 3 43115 0.039392 0.074992 -0.2546611 0.0028830 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 4 43116 0.035792 0.074692 -0.2574982 0.0027930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 5 43117 0.032193 0.074293 -0.2602513 0.0027070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 6 43118 0.028493 0.074093 -0.2629314 0.0026560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 7 43119 0.024793 0.073793 -0.2655656 0.0026290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 8 43120 0.021093 0.073593 -0.2681927 0.0026300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 9 43121 0.017294 0.073394 -0.2708398 0.0026820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 10 43122 0.013494 0.073294 -0.2735600 0.0027620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 11 43123 0.009694 0.073094 -0.2763751 0.0028720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 12 43124 0.005894 0.073094 -0.2793082 0.0029850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 13 43125 0.001995 0.073095 -0.2823333 0.0030910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 14 43126 -0.001905 0.073095 -0.2854705 0.0031660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 15 43127 -0.005805 0.073195 -0.2886586 0.0032000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 16 43128 -0.009704 0.073296 -0.2918387 0.0031600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 17 43129 -0.013604 0.073496 -0.2949678 0.0030680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 18 43130 -0.017604 0.073696 -0.2979610 0.0029250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 19 43131 -0.021504 0.073996 -0.3008261 0.0027960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 20 43132 -0.025503 0.074297 -0.3035542 0.0026900 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 21 43133 -0.029503 0.074697 -0.3062154 0.0026430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 22 43134 -0.033403 0.075197 -0.3088705 0.0026650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 23 43135 -0.037403 0.075697 -0.3115666 0.0027230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 24 43136 -0.041402 0.076298 -0.3143167 0.0027830 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 25 43137 -0.045302 0.076898 -0.3171259 0.0028290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 26 43138 -0.049202 0.077598 -0.3199610 0.0028360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 27 43139 -0.053201 0.078399 -0.3227861 0.0028070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 28 43140 -0.057101 0.079199 -0.3255753 0.0027570 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 29 43141 -0.060901 0.080099 -0.3282924 0.0026850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 30 43142 -0.064801 0.081099 -0.3309315 0.0026010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1976 12 31 43143 -0.068600 0.082100 -0.3334846 0.0025150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 1 43144 -0.072400 0.083200 0.6640352 0.0024390 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 2 43145 -0.076200 0.084400 0.6616291 0.0023880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 3 43146 -0.079899 0.085701 0.6592480 0.0023700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 4 43147 -0.083599 0.087001 0.6568658 0.0024020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 5 43148 -0.087299 0.088401 0.6544407 0.0024650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 6 43149 -0.090899 0.089901 0.6519226 0.0025680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 7 43150 -0.094498 0.091502 0.6492834 0.0027130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 8 43151 -0.098098 0.093102 0.6465003 0.0028630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 9 43152 -0.101598 0.094802 0.6435602 0.0030050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 10 43153 -0.105098 0.096602 0.6405021 0.0031140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 11 43154 -0.108497 0.098403 0.6373489 0.0031720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 12 43155 -0.111897 0.100303 0.6341788 0.0031700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 13 43156 -0.115297 0.102303 0.6310277 0.0031130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 14 43157 -0.118596 0.104404 0.6279635 0.0030100 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 15 43158 -0.121896 0.106504 0.6250104 0.0029070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 16 43159 -0.125196 0.108704 0.6221523 0.0028170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 17 43160 -0.128396 0.111004 0.6193602 0.0027760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 18 43161 -0.131595 0.113305 0.6165790 0.0027850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 19 43162 -0.134795 0.115705 0.6137639 0.0028520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 20 43163 -0.137895 0.118105 0.6108678 0.0029300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 21 43164 -0.140995 0.120605 0.6078976 0.0030050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 22 43165 -0.144094 0.123106 0.6048795 0.0030330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 23 43166 -0.147094 0.125806 0.6018584 0.0030140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 24 43167 -0.150094 0.128406 0.5988762 0.0029530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 25 43168 -0.152993 0.131107 0.5959701 0.0028540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 26 43169 -0.155893 0.133907 0.5931640 0.0027470 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 27 43170 -0.158793 0.136707 0.5904778 0.0026340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 28 43171 -0.161693 0.139607 0.5878927 0.0025280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 29 43172 -0.164492 0.142508 0.5854146 0.0024430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 30 43173 -0.167292 0.145408 0.5829965 0.0023890 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 1 31 43174 -0.169992 0.148408 0.5806223 0.0023770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 1 43175 -0.172692 0.151408 0.5782372 0.0024090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 2 43176 -0.175391 0.154509 0.5757991 0.0024740 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 3 43177 -0.177991 0.157709 0.5732659 0.0025880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 4 43178 -0.180591 0.160809 0.5706048 0.0027250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 5 43179 -0.183190 0.164010 0.5678047 0.0028630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 6 43180 -0.185690 0.167310 0.5648885 0.0029710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 7 43181 -0.188190 0.170610 0.5618814 0.0030230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 8 43182 -0.190590 0.173910 0.5588563 0.0030140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 9 43183 -0.192989 0.177311 0.5558831 0.0029320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 10 43184 -0.195289 0.180711 0.5530070 0.0028070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 11 43185 -0.197589 0.184111 0.5502639 0.0026810 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 12 43186 -0.199889 0.187611 0.5476487 0.0025650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 13 43187 -0.202088 0.191112 0.5451186 0.0025040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 14 43188 -0.204188 0.194712 0.5426215 0.0025000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 15 43189 -0.206288 0.198212 0.5400904 0.0025600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 16 43190 -0.208287 0.201813 0.5374792 0.0026550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 17 43191 -0.210287 0.205413 0.5347681 0.0027660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 18 43192 -0.212187 0.209113 0.5319660 0.0028420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 19 43193 -0.214087 0.212713 0.5290978 0.0028850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 20 43194 -0.215886 0.216414 0.5262117 0.0028800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 21 43195 -0.217586 0.220114 0.5233516 0.0028340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 22 43196 -0.219286 0.223814 0.5205614 0.0027630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 23 43197 -0.220886 0.227514 0.5178393 0.0026790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 24 43198 -0.222385 0.231215 0.5152112 0.0025870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 25 43199 -0.223785 0.235015 0.5126590 0.0025200 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 26 43200 -0.225185 0.238715 0.5101619 0.0024790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 27 43201 -0.226484 0.242416 0.5076868 0.0024670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 2 28 43202 -0.227684 0.246116 0.5052026 0.0025100 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 1 43203 -0.228884 0.249816 0.5026605 0.0025900 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 2 43204 -0.229884 0.253516 0.5000074 0.0027130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 3 43205 -0.230883 0.257217 0.4972222 0.0028710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 4 43206 -0.231783 0.260817 0.4942701 0.0030340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 5 43207 -0.232583 0.264517 0.4911490 0.0031940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 6 43208 -0.233283 0.268217 0.4878888 0.0033060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 7 43209 -0.233982 0.271818 0.4845607 0.0033450 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 8 43210 -0.234482 0.275518 0.4812376 0.0033020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 9 43211 -0.234882 0.279118 0.4779884 0.0031960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 10 43212 -0.235281 0.282719 0.4748543 0.0030620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 11 43213 -0.235581 0.286419 0.4718602 0.0029510 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 12 43214 -0.235781 0.290019 0.4689480 0.0028830 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 13 43215 -0.235781 0.293619 0.4660659 0.0028910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 14 43216 -0.235780 0.297220 0.4631568 0.0029450 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 15 43217 -0.235680 0.300820 0.4601616 0.0030480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 16 43218 -0.235480 0.304320 0.4570435 0.0031800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 17 43219 -0.235280 0.307920 0.4538154 0.0033030 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 18 43220 -0.234879 0.311521 0.4504472 0.0033970 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 19 43221 -0.234379 0.315021 0.4470271 0.0034370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 20 43222 -0.233879 0.318521 0.4435880 0.0034330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 21 43223 -0.233178 0.322022 0.4401718 0.0033850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 22 43224 -0.232478 0.325522 0.4368237 0.0033180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 23 43225 -0.231678 0.329022 0.4335376 0.0032360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 24 43226 -0.230778 0.332522 0.4303494 0.0031430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 25 43227 -0.229777 0.335923 0.4272443 0.0030710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 26 43228 -0.228677 0.339323 0.4242062 0.0030210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 27 43229 -0.227477 0.342623 0.4211980 0.0030030 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 28 43230 -0.226276 0.345924 0.4181859 0.0030300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 29 43231 -0.224876 0.349224 0.4151228 0.0031020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 30 43232 -0.223476 0.352424 0.4119776 0.0032040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 3 31 43233 -0.221976 0.355624 0.4087055 0.0033340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 1 43234 -0.220375 0.358825 0.4052984 0.0034700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 2 43235 -0.218775 0.361925 0.4017732 0.0035820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 3 43236 -0.217075 0.364925 0.3981631 0.0036250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 4 43237 -0.215275 0.367925 0.3945510 0.0035950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 5 43238 -0.213374 0.370926 0.3910098 0.0034840 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 6 43239 -0.211474 0.373826 0.3876107 0.0033080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 7 43240 -0.209474 0.376726 0.3843966 0.0031420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 8 43241 -0.207473 0.379627 0.3813254 0.0030170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 9 43242 -0.205373 0.382427 0.3783423 0.0029590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 10 43243 -0.203173 0.385127 0.3753792 0.0029580 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 11 43244 -0.200973 0.387827 0.3724020 0.0030210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 12 43245 -0.198772 0.390528 0.3693299 0.0031130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 13 43246 -0.196472 0.393228 0.3661757 0.0032040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 14 43247 -0.194172 0.395828 0.3629276 0.0032760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 15 43248 -0.191772 0.398328 0.3596345 0.0033140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 16 43249 -0.189471 0.400829 0.3563023 0.0033350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 17 43250 -0.187071 0.403329 0.3529772 0.0033200 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 18 43251 -0.184571 0.405829 0.3496791 0.0032610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 19 43252 -0.182170 0.408230 0.3464569 0.0031830 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 20 43253 -0.179670 0.410630 0.3433028 0.0031180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 21 43254 -0.177270 0.412930 0.3402147 0.0030610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 22 43255 -0.174770 0.415230 0.3371705 0.0030310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 23 43256 -0.172269 0.417531 0.3341514 0.0030260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 24 43257 -0.169769 0.419831 0.3311153 0.0030520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 25 43258 -0.167269 0.422031 0.3280321 0.0031210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 26 43259 -0.164669 0.424231 0.3248700 0.0032100 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 27 43260 -0.162168 0.426432 0.3215919 0.0033300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 28 43261 -0.159668 0.428532 0.3181937 0.0034680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 29 43262 -0.157068 0.430632 0.3146576 0.0036010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 4 30 43263 -0.154567 0.432733 0.3109924 0.0037010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 1 43264 -0.152067 0.434833 0.3072673 0.0037370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 2 43265 -0.149467 0.436833 0.3035552 0.0036930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 3 43266 -0.146867 0.438933 0.2999150 0.0035680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 4 43267 -0.144266 0.440934 0.2964229 0.0034140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 5 43268 -0.141666 0.442834 0.2930838 0.0032680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 6 43269 -0.139066 0.444834 0.2898796 0.0031590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 7 43270 -0.136366 0.446734 0.2867445 0.0031200 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 8 43271 -0.133665 0.448635 0.2836324 0.0031320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 9 43272 -0.130965 0.450535 0.2804842 0.0031570 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 10 43273 -0.128165 0.452335 0.2773091 0.0031900 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 11 43274 -0.125364 0.454136 0.2740999 0.0032020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 12 43275 -0.122464 0.455936 0.2709038 0.0031850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 13 43276 -0.119564 0.457636 0.2677417 0.0031350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 14 43277 -0.116564 0.459336 0.2646545 0.0030540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 15 43278 -0.113563 0.460937 0.2616514 0.0029390 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 16 43279 -0.110463 0.462537 0.2587703 0.0028210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 17 43280 -0.107263 0.464137 0.2560071 0.0027050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 18 43281 -0.104063 0.465637 0.2533560 0.0025920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 19 43282 -0.100762 0.467138 0.2508149 0.0025050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 20 43283 -0.097462 0.468538 0.2483347 0.0024600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 21 43284 -0.094062 0.469938 0.2458916 0.0024320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 22 43285 -0.090561 0.471239 0.2434464 0.0024540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 23 43286 -0.086961 0.472539 0.2409613 0.0025130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 24 43287 -0.083361 0.473739 0.2384002 0.0026020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 25 43288 -0.079661 0.474939 0.2357500 0.0027100 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 26 43289 -0.075860 0.476040 0.2329889 0.0028210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 27 43290 -0.072060 0.477140 0.2301248 0.0029150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 28 43291 -0.068160 0.478140 0.2271736 0.0029670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 29 43292 -0.064160 0.479040 0.2242005 0.0029680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 30 43293 -0.060159 0.480041 0.2212593 0.0029010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 5 31 43294 -0.056159 0.480841 0.2184252 0.0027820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 1 43295 -0.051959 0.481741 0.2157001 0.0026470 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 2 43296 -0.047758 0.482442 0.2131109 0.0025490 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 3 43297 -0.043558 0.483242 0.2105848 0.0025050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 4 43298 -0.039258 0.483842 0.2080907 0.0025100 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 5 43299 -0.034958 0.484542 0.2055515 0.0025610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 6 43300 -0.030557 0.485143 0.2029674 0.0026050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 7 43301 -0.026157 0.485643 0.2003492 0.0026250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 8 43302 -0.021757 0.486143 0.1977301 0.0026080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 9 43303 -0.017257 0.486543 0.1951570 0.0025530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 10 43304 -0.012656 0.486944 0.1926448 0.0024570 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 11 43305 -0.008156 0.487244 0.1902397 0.0023490 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 12 43306 -0.003556 0.487544 0.1879506 0.0022180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 13 43307 0.001045 0.487845 0.1857934 0.0020960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 14 43308 0.005645 0.487945 0.1837543 0.0019750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 15 43309 0.010345 0.488045 0.1818351 0.0018780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 16 43310 0.014945 0.488145 0.1799870 0.0018240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 17 43311 0.019646 0.488146 0.1781749 0.0017960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 18 43312 0.024346 0.488046 0.1763817 0.0018070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 19 43313 0.028946 0.487946 0.1745486 0.0018530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 20 43314 0.033647 0.487647 0.1726545 0.0019390 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 21 43315 0.038347 0.487447 0.1706743 0.0020340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 22 43316 0.042947 0.487047 0.1685962 0.0021310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 23 43317 0.047547 0.486647 0.1664170 0.0022130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 24 43318 0.052148 0.486148 0.1641699 0.0022740 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 25 43319 0.056748 0.485648 0.1618958 0.0022770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 26 43320 0.061348 0.485048 0.1596236 0.0022360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 27 43321 0.065848 0.484348 0.1574295 0.0021470 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 28 43322 0.070349 0.483549 0.1553383 0.0020320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 29 43323 0.074849 0.482749 0.1533612 0.0019360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 6 30 43324 0.079249 0.481849 0.1514621 0.0018710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 1 43325 0.083650 0.480850 0.1495879 0.0018750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 2 43326 0.087950 0.479850 0.1476938 0.0019300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 3 43327 0.092250 0.478750 0.1457227 0.0020030 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 4 43328 0.096450 0.477550 0.1436925 0.0020610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 5 43329 0.100651 0.476351 0.1416254 0.0020760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 6 43330 0.104851 0.475051 0.1395562 0.0020520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 7 43331 0.108851 0.473651 0.1375351 0.0019770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 8 43332 0.112951 0.472251 0.1356020 0.0018840 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 9 43333 0.116952 0.470752 0.1337718 0.0017760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 10 43334 0.120852 0.469252 0.1320497 0.0016760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 11 43335 0.124752 0.467652 0.1304165 0.0015850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 12 43336 0.128553 0.466053 0.1288634 0.0015250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 13 43337 0.132253 0.464353 0.1273543 0.0014880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 14 43338 0.136053 0.462653 0.1258641 0.0014990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 15 43339 0.139653 0.460853 0.1243430 0.0015600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 16 43340 0.143354 0.459054 0.1227308 0.0016480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 17 43341 0.146854 0.457154 0.1210257 0.0017680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 18 43342 0.150354 0.455254 0.1191886 0.0019080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 19 43343 0.153854 0.453354 0.1172074 0.0020530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 20 43344 0.157255 0.451355 0.1150873 0.0021730 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 21 43345 0.160655 0.449355 0.1128631 0.0022690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 22 43346 0.163955 0.447255 0.1105750 0.0022980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 23 43347 0.167256 0.445156 0.1082829 0.0022770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 24 43348 0.170456 0.443056 0.1060357 0.0022140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 25 43349 0.173656 0.440956 0.1038636 0.0021170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 26 43350 0.176756 0.438756 0.1017914 0.0020220 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 27 43351 0.179857 0.436457 0.0997993 0.0019580 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 28 43352 0.182957 0.434257 0.0978572 0.0019370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 29 43353 0.185957 0.431957 0.0959070 0.0019710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 30 43354 0.188857 0.429657 0.0938919 0.0020430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 7 31 43355 0.191858 0.427258 0.0918097 0.0021180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 1 43356 0.194658 0.424858 0.0896656 0.0021600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 2 43357 0.197558 0.422458 0.0874965 0.0021600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 3 43358 0.200359 0.420059 0.0853653 0.0020940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 4 43359 0.203059 0.417559 0.0833322 0.0019860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 5 43360 0.205759 0.415059 0.0814000 0.0018650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 6 43361 0.208459 0.412559 0.0796029 0.0017370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 7 43362 0.211160 0.409960 0.0779328 0.0016160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 8 43363 0.213760 0.407360 0.0763646 0.0015230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 9 43364 0.216260 0.404760 0.0748755 0.0014710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 10 43365 0.218860 0.402060 0.0734103 0.0014560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 11 43366 0.221361 0.399361 0.0719482 0.0014940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 12 43367 0.223761 0.396661 0.0704171 0.0015630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 13 43368 0.226261 0.393861 0.0687999 0.0016870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 14 43369 0.228662 0.391162 0.0670448 0.0018270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 15 43370 0.230962 0.388362 0.0651316 0.0019880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 16 43371 0.233362 0.385462 0.0630715 0.0021400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 17 43372 0.235662 0.382662 0.0608624 0.0022580 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 18 43373 0.237863 0.379763 0.0585622 0.0023350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 19 43374 0.240163 0.376863 0.0562231 0.0023430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 20 43375 0.242363 0.373963 0.0538919 0.0023120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 21 43376 0.244463 0.370963 0.0515968 0.0022550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 22 43377 0.246664 0.367964 0.0493717 0.0022080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 23 43378 0.248664 0.364964 0.0471815 0.0021790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 24 43379 0.250764 0.361964 0.0449964 0.0022090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 25 43380 0.252765 0.358965 0.0427552 0.0022930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 26 43381 0.254665 0.355865 0.0404051 0.0024230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 27 43382 0.256565 0.352865 0.0379020 0.0025740 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 28 43383 0.258465 0.349765 0.0352608 0.0027040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 29 43384 0.260266 0.346566 0.0325087 0.0028110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 30 43385 0.261966 0.343466 0.0296675 0.0028410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 8 31 43386 0.263666 0.340266 0.0268344 0.0028270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 1 43387 0.265366 0.337166 0.0240352 0.0027550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 2 43388 0.266867 0.333867 0.0213191 0.0026760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 3 43389 0.268367 0.330667 0.0186920 0.0025880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 4 43390 0.269867 0.327467 0.0161378 0.0025140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 5 43391 0.271168 0.324168 0.0136557 0.0024660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 6 43392 0.272468 0.320868 0.0111935 0.0024550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 7 43393 0.273668 0.317468 0.0087314 0.0024760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 8 43394 0.274868 0.314168 0.0062273 0.0025500 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 9 43395 0.275869 0.310769 0.0036291 0.0026430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 10 43396 0.276869 0.307369 0.0009200 0.0027690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 11 43397 0.277769 0.303869 -0.0019162 0.0029130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 12 43398 0.278670 0.300370 -0.0048973 0.0030500 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 13 43399 0.279370 0.296870 -0.0080084 0.0031740 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 14 43400 0.279970 0.293270 -0.0112206 0.0032410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 15 43401 0.280570 0.289670 -0.0144687 0.0032430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 16 43402 0.280971 0.286071 -0.0176849 0.0031800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 17 43403 0.281371 0.282371 -0.0208150 0.0030740 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 18 43404 0.281671 0.278571 -0.0238402 0.0029580 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 19 43405 0.281871 0.274871 -0.0267373 0.0028650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 20 43406 0.281972 0.271072 -0.0295754 0.0028190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 21 43407 0.281972 0.267172 -0.0323946 0.0028180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 22 43408 0.281972 0.263272 -0.0352377 0.0028750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 23 43409 0.281773 0.259373 -0.0381439 0.0029620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 24 43410 0.281573 0.255473 -0.0411530 0.0030420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 25 43411 0.281273 0.251473 -0.0442321 0.0031080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 26 43412 0.280873 0.247473 -0.0473533 0.0031280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 27 43413 0.280374 0.243374 -0.0504684 0.0030950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 28 43414 0.279774 0.239374 -0.0535286 0.0030060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 29 43415 0.279174 0.235274 -0.0564817 0.0028970 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 9 30 43416 0.278474 0.231174 -0.0593189 0.0027880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 1 43417 0.277675 0.226975 -0.0620520 0.0026790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 2 43418 0.276775 0.222875 -0.0646931 0.0026000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 3 43419 0.275775 0.218675 -0.0672623 0.0025530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 4 43420 0.274776 0.214576 -0.0698134 0.0025560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 5 43421 0.273676 0.210376 -0.0723796 0.0025910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 6 43422 0.272476 0.206176 -0.0750197 0.0026770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 7 43423 0.271176 0.202076 -0.0777549 0.0028000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 8 43424 0.269877 0.197877 -0.0806270 0.0029680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 9 43425 0.268477 0.193777 -0.0836851 0.0031380 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 10 43426 0.266977 0.189677 -0.0869123 0.0033020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 11 43427 0.265477 0.185577 -0.0902884 0.0034350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 12 43428 0.263878 0.181478 -0.0937736 0.0035210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 13 43429 0.262178 0.177378 -0.0972997 0.0035280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 14 43430 0.260478 0.173378 -0.1008089 0.0034720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 15 43431 0.258579 0.169379 -0.1042320 0.0033820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 16 43432 0.256779 0.165479 -0.1075741 0.0032990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 17 43433 0.254779 0.161579 -0.1108333 0.0032460 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 18 43434 0.252779 0.157779 -0.1140864 0.0032480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 19 43435 0.250680 0.153980 -0.1173586 0.0033030 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 20 43436 0.248580 0.150180 -0.1207027 0.0033800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 21 43437 0.246380 0.146580 -0.1241309 0.0034650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 22 43438 0.244180 0.142880 -0.1276270 0.0035250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 23 43439 0.241781 0.139381 -0.1311691 0.0035420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 24 43440 0.239481 0.135881 -0.1347063 0.0035160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 25 43441 0.236981 0.132481 -0.1381964 0.0034470 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 26 43442 0.234582 0.129082 -0.1415896 0.0033330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 27 43443 0.231982 0.125882 -0.1448677 0.0032130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 28 43444 0.229382 0.122682 -0.1480149 0.0030830 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 29 43445 0.226782 0.119482 -0.1510290 0.0029690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 30 43446 0.224083 0.116483 -0.1539521 0.0028720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 10 31 43447 0.221383 0.113483 -0.1567963 0.0028190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 1 43448 0.218583 0.110583 -0.1596034 0.0028060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 2 43449 0.215783 0.107683 -0.1624306 0.0028430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 3 43450 0.212984 0.104984 -0.1653027 0.0029160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 4 43451 0.210084 0.102284 -0.1682729 0.0030180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 5 43452 0.207184 0.099584 -0.1713450 0.0031390 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 6 43453 0.204185 0.097085 -0.1745521 0.0032640 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 7 43454 0.201185 0.094585 -0.1778783 0.0033840 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 8 43455 0.198185 0.092185 -0.1813194 0.0034680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 9 43456 0.195185 0.089785 -0.1848046 0.0034940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 10 43457 0.192086 0.087586 -0.1882837 0.0034540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 11 43458 0.188986 0.085286 -0.1916959 0.0033630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 12 43459 0.185786 0.083086 -0.1950050 0.0032530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 13 43460 0.182586 0.080986 -0.1982091 0.0031640 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 14 43461 0.179387 0.078887 -0.2013493 0.0031260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 15 43462 0.176187 0.076887 -0.2044794 0.0031440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 16 43463 0.172887 0.074987 -0.2076516 0.0031910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 17 43464 0.169588 0.072988 -0.2108767 0.0032580 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 18 43465 0.166288 0.071088 -0.2141629 0.0032990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 19 43466 0.162888 0.069288 -0.2174640 0.0033080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 20 43467 0.159488 0.067488 -0.2207572 0.0032690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 21 43468 0.156089 0.065689 -0.2239883 0.0031920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 22 43469 0.152589 0.063989 -0.2271404 0.0030950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 23 43470 0.149089 0.062189 -0.2301746 0.0029710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 24 43471 0.145589 0.060489 -0.2330817 0.0028420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 25 43472 0.141990 0.058890 -0.2358629 0.0027250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 26 43473 0.138390 0.057190 -0.2385380 0.0026310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 27 43474 0.134790 0.055590 -0.2411352 0.0025790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 28 43475 0.131091 0.053991 -0.2437093 0.0025620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 29 43476 0.127391 0.052491 -0.2462824 0.0025930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 11 30 43477 0.123691 0.050891 -0.2488956 0.0026480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 1 43478 0.119991 0.049391 -0.2515897 0.0027430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 2 43479 0.116192 0.047892 -0.2543879 0.0028470 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 3 43480 0.112392 0.046392 -0.2572970 0.0029690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 4 43481 0.108592 0.044992 -0.2603252 0.0030950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 5 43482 0.104692 0.043592 -0.2634793 0.0031980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 6 43483 0.100893 0.042193 -0.2667095 0.0032730 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 7 43484 0.096993 0.040893 -0.2699986 0.0033050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 8 43485 0.093093 0.039493 -0.2732927 0.0032850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 9 43486 0.089194 0.038294 -0.2765679 0.0032410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 10 43487 0.085294 0.036994 -0.2797760 0.0031980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 11 43488 0.081394 0.035894 -0.2829652 0.0031900 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 12 43489 0.077494 0.034694 -0.2861733 0.0032470 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 13 43490 0.073595 0.033595 -0.2894775 0.0033540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 14 43491 0.069695 0.032595 -0.2928796 0.0034620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 15 43492 0.065695 0.031595 -0.2964058 0.0035660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 16 43493 0.061796 0.030696 -0.2999979 0.0036200 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 17 43494 0.057896 0.029796 -0.3036210 0.0036170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 18 43495 0.053996 0.028996 -0.3072182 0.0035630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 19 43496 0.050096 0.028196 -0.3107373 0.0034690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 20 43497 0.046197 0.027597 -0.3141505 0.0033480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 21 43498 0.042297 0.026897 -0.3174416 0.0032240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 22 43499 0.038397 0.026397 -0.3206028 0.0031000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 23 43500 0.034597 0.025897 -0.3236489 0.0029970 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 24 43501 0.030698 0.025598 -0.3265971 0.0029150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 25 43502 0.026898 0.025198 -0.3295002 0.0028790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 26 43503 0.022998 0.024998 -0.3323783 0.0028790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 27 43504 0.019199 0.024899 -0.3352605 0.0029030 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 28 43505 0.015399 0.024799 -0.3381936 0.0029650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 29 43506 0.011599 0.024799 -0.3411978 0.0030480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 30 43507 0.007899 0.024899 -0.3442809 0.0031280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1977 12 31 43508 0.004100 0.025000 -0.3474531 0.0032130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 1 43509 0.000400 0.025300 0.6492998 0.0032780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 2 43510 -0.003400 0.025600 0.6459906 0.0033130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 3 43511 -0.007100 0.025900 0.6426775 0.0033170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 4 43512 -0.010799 0.026401 0.6393814 0.0032710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 5 43513 -0.014499 0.026901 0.6361472 0.0032010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 6 43514 -0.018199 0.027501 0.6329911 0.0031210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 7 43515 -0.021898 0.028202 0.6298989 0.0030620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 8 43516 -0.025598 0.028902 0.6268418 0.0030600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 9 43517 -0.029298 0.029702 0.6237586 0.0031250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 10 43518 -0.032898 0.030602 0.6205895 0.0032170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 11 43519 -0.036597 0.031503 0.6173233 0.0033110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 12 43520 -0.040297 0.032503 0.6139692 0.0033800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 13 43521 -0.043997 0.033603 0.6105830 0.0033820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 14 43522 -0.047697 0.034703 0.6072239 0.0033350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 15 43523 -0.051396 0.035804 0.6039358 0.0032460 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 16 43524 -0.055196 0.037004 0.6007496 0.0031340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 17 43525 -0.058896 0.038304 0.5976695 0.0030170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 18 43526 -0.062595 0.039605 0.5947233 0.0028990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 19 43527 -0.066395 0.041005 0.5918642 0.0028010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 20 43528 -0.070095 0.042405 0.5891000 0.0027440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 21 43529 -0.073895 0.043805 0.5863729 0.0027150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 22 43530 -0.077594 0.045306 0.5836677 0.0027140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 23 43531 -0.081394 0.046906 0.5809336 0.0027600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 24 43532 -0.085094 0.048406 0.5781365 0.0028260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 25 43533 -0.088894 0.050006 0.5752633 0.0029240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 26 43534 -0.092593 0.051707 0.5722862 0.0030320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 27 43535 -0.096393 0.053307 0.5692010 0.0031350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 28 43536 -0.100093 0.055007 0.5660219 0.0032280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 29 43537 -0.103792 0.056708 0.5627657 0.0032880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 30 43538 -0.107492 0.058408 0.5594696 0.0033070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 1 31 43539 -0.111092 0.060208 0.5561644 0.0032870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 1 43540 -0.114692 0.061908 0.5528953 0.0032490 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 2 43541 -0.118291 0.063709 0.5496701 0.0032000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 3 43542 -0.121891 0.065509 0.5464890 0.0031660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 4 43543 -0.125391 0.067409 0.5433149 0.0031810 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 5 43544 -0.128791 0.069209 0.5401087 0.0032510 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 6 43545 -0.132190 0.071110 0.5367946 0.0033920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 7 43546 -0.135590 0.073010 0.5333264 0.0035480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 8 43547 -0.138890 0.074910 0.5296943 0.0036880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 9 43548 -0.142189 0.076811 0.5259551 0.0037890 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 10 43549 -0.145289 0.078811 0.5221490 0.0038210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 11 43550 -0.148489 0.080711 0.5183328 0.0037920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 12 43551 -0.151489 0.082711 0.5145787 0.0037120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 13 43552 -0.154488 0.084812 0.5109255 0.0036150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 14 43553 -0.157388 0.086812 0.5073584 0.0035120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 15 43554 -0.160288 0.088912 0.5038952 0.0034370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 16 43555 -0.163088 0.091012 0.5004831 0.0033810 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 17 43556 -0.165787 0.093213 0.4971110 0.0033620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 18 43557 -0.168487 0.095413 0.4937468 0.0033750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 19 43558 -0.171087 0.097613 0.4903477 0.0034280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 20 43559 -0.173586 0.099914 0.4868775 0.0035070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 21 43560 -0.176086 0.102214 0.4833234 0.0035830 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 22 43561 -0.178486 0.104514 0.4797062 0.0036540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 23 43562 -0.180886 0.106914 0.4760161 0.0037260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 24 43563 -0.183185 0.109415 0.4722489 0.0037810 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 25 43564 -0.185485 0.111915 0.4684548 0.0038020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 26 43565 -0.187685 0.114415 0.4646716 0.0037750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 27 43566 -0.189885 0.117015 0.4609295 0.0037020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 2 28 43567 -0.191984 0.119716 0.4572814 0.0036030 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 1 43568 -0.193984 0.122416 0.4537292 0.0034900 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 2 43569 -0.195984 0.125216 0.4502961 0.0033890 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 3 43570 -0.197983 0.128017 0.4469499 0.0033230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 4 43571 -0.199883 0.130917 0.4436448 0.0033080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 5 43572 -0.201683 0.133817 0.4403166 0.0033560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 6 43573 -0.203483 0.136817 0.4369185 0.0034350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 7 43574 -0.205282 0.139818 0.4334333 0.0035430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 8 43575 -0.206982 0.142918 0.4298412 0.0036330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 9 43576 -0.208582 0.146018 0.4261880 0.0036650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 10 43577 -0.210181 0.149219 0.4225339 0.0036290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 11 43578 -0.211681 0.152419 0.4189387 0.0035450 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 12 43579 -0.213081 0.155719 0.4154566 0.0034150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 13 43580 -0.214481 0.159019 0.4121095 0.0032870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 14 43581 -0.215780 0.162420 0.4088783 0.0031700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 15 43582 -0.217080 0.165820 0.4057622 0.0030680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 16 43583 -0.218180 0.169220 0.4027210 0.0030100 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 17 43584 -0.219280 0.172720 0.3997279 0.0029920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 18 43585 -0.220379 0.176221 0.3967217 0.0030270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 19 43586 -0.221279 0.179821 0.3936706 0.0030830 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 20 43587 -0.222179 0.183421 0.3905354 0.0031800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 21 43588 -0.222978 0.187022 0.3872923 0.0033000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 22 43589 -0.223678 0.190722 0.3839231 0.0034290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 23 43590 -0.224378 0.194522 0.3804380 0.0035500 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 24 43591 -0.224978 0.198222 0.3768408 0.0036350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 25 43592 -0.225477 0.202023 0.3731727 0.0036850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 26 43593 -0.225877 0.205923 0.3694896 0.0036700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 27 43594 -0.226277 0.209723 0.3658494 0.0036050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 28 43595 -0.226577 0.213623 0.3622893 0.0035110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 29 43596 -0.226776 0.217624 0.3588361 0.0034090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 30 43597 -0.226876 0.221624 0.3554600 0.0033480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 3 31 43598 -0.226976 0.225624 0.3521228 0.0033260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 1 43599 -0.226975 0.229625 0.3487807 0.0033660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 2 43600 -0.226975 0.233725 0.3453855 0.0034390 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 3 43601 -0.226875 0.237825 0.3418944 0.0035440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 4 43602 -0.226675 0.242025 0.3383022 0.0036400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 5 43603 -0.226474 0.246126 0.3346281 0.0036990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 6 43604 -0.226274 0.250326 0.3309219 0.0037010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 7 43605 -0.225974 0.254526 0.3272448 0.0036530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 8 43606 -0.225574 0.258826 0.3236417 0.0035470 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 9 43607 -0.225173 0.263127 0.3201575 0.0034180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 10 43608 -0.224773 0.267327 0.3168054 0.0032890 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 11 43609 -0.224273 0.271627 0.3135832 0.0031780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 12 43610 -0.223772 0.276028 0.3104491 0.0030860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 13 43611 -0.223172 0.280328 0.3073879 0.0030420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 14 43612 -0.222572 0.284628 0.3043518 0.0030380 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 15 43613 -0.221972 0.288928 0.3013086 0.0030660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 16 43614 -0.221271 0.293229 0.2982085 0.0031390 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 17 43615 -0.220571 0.297529 0.2950213 0.0032300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 18 43616 -0.219771 0.301829 0.2917442 0.0033360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 19 43617 -0.219071 0.306129 0.2883590 0.0034330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 20 43618 -0.218270 0.310330 0.2848809 0.0035170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 21 43619 -0.217370 0.314530 0.2813337 0.0035680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 22 43620 -0.216570 0.318630 0.2777516 0.0035690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 23 43621 -0.215669 0.322731 0.2742145 0.0035040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 24 43622 -0.214669 0.326831 0.2707583 0.0034030 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 25 43623 -0.213769 0.330831 0.2674132 0.0032760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 26 43624 -0.212769 0.334731 0.2641900 0.0031760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 27 43625 -0.211768 0.338632 0.2610569 0.0031100 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 28 43626 -0.210668 0.342432 0.2579517 0.0031080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 29 43627 -0.209668 0.346132 0.2548256 0.0031400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 4 30 43628 -0.208568 0.349732 0.2516524 0.0032050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 1 43629 -0.207467 0.353333 0.2484253 0.0032680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 2 43630 -0.206267 0.356733 0.2451361 0.0033140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 3 43631 -0.205067 0.360133 0.2418130 0.0033260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 4 43632 -0.203866 0.363434 0.2384998 0.0032980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 5 43633 -0.202666 0.366534 0.2352397 0.0032140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 6 43634 -0.201466 0.369634 0.2320805 0.0031090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 7 43635 -0.200166 0.372634 0.2290244 0.0029950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 8 43636 -0.198865 0.375535 0.2260883 0.0028910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 9 43637 -0.197465 0.378335 0.2232431 0.0028120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 10 43638 -0.196065 0.381135 0.2204610 0.0027570 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 11 43639 -0.194665 0.383735 0.2177058 0.0027490 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 12 43640 -0.193264 0.386336 0.2149387 0.0027810 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 13 43641 -0.191764 0.388836 0.2121325 0.0028380 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 14 43642 -0.190164 0.391236 0.2092534 0.0029250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 15 43643 -0.188563 0.393637 0.2062742 0.0030310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 16 43644 -0.186963 0.395937 0.2031771 0.0031440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 17 43645 -0.185263 0.398137 0.1999789 0.0032510 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 18 43646 -0.183563 0.400337 0.1966798 0.0033290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 19 43647 -0.181662 0.402438 0.1933326 0.0033710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 20 43648 -0.179862 0.404538 0.1899555 0.0033640 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 21 43649 -0.177862 0.406538 0.1866223 0.0033070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 22 43650 -0.175862 0.408538 0.1833622 0.0032060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 23 43651 -0.173761 0.410439 0.1802001 0.0031140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 24 43652 -0.171661 0.412439 0.1771229 0.0030440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 25 43653 -0.169461 0.414239 0.1740938 0.0030270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 26 43654 -0.167160 0.416140 0.1710426 0.0030710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 27 43655 -0.164760 0.417940 0.1679425 0.0031320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 28 43656 -0.162260 0.419740 0.1647893 0.0031800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 29 43657 -0.159660 0.421540 0.1616022 0.0031900 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 30 43658 -0.157059 0.423241 0.1584150 0.0031660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 5 31 43659 -0.154359 0.424941 0.1552859 0.0030860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 1 43660 -0.151559 0.426641 0.1522577 0.0029650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 2 43661 -0.148658 0.428342 0.1493756 0.0028050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 3 43662 -0.145758 0.430042 0.1466504 0.0026440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 4 43663 -0.142658 0.431642 0.1440873 0.0024770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 5 43664 -0.139558 0.433242 0.1416781 0.0023420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 6 43665 -0.136457 0.434843 0.1393900 0.0022390 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 7 43666 -0.133157 0.436443 0.1371988 0.0021710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 8 43667 -0.129857 0.438043 0.1350457 0.0021310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 9 43668 -0.126557 0.439643 0.1329166 0.0021350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 10 43669 -0.123156 0.441244 0.1307554 0.0021690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 11 43670 -0.119756 0.442744 0.1285593 0.0022240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 12 43671 -0.116256 0.444344 0.1263051 0.0022880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 13 43672 -0.112755 0.445845 0.1239760 0.0023590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 14 43673 -0.109255 0.447445 0.1215908 0.0024060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 15 43674 -0.105755 0.448945 0.1191717 0.0024380 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 16 43675 -0.102155 0.450445 0.1167275 0.0024340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 17 43676 -0.098654 0.451946 0.1143154 0.0023990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 18 43677 -0.095054 0.453446 0.1119502 0.0023170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 19 43678 -0.091554 0.454946 0.1096791 0.0022280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 20 43679 -0.087954 0.456446 0.1074899 0.0021550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 21 43680 -0.084453 0.457947 0.1053518 0.0021370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 22 43681 -0.080853 0.459447 0.1032056 0.0021650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 23 43682 -0.077353 0.460847 0.1009985 0.0022440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 24 43683 -0.073852 0.462248 0.0987053 0.0023300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 25 43684 -0.070352 0.463748 0.0963492 0.0023960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 26 43685 -0.066852 0.465148 0.0939421 0.0024100 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 27 43686 -0.063452 0.466448 0.0915379 0.0023670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 28 43687 -0.059951 0.467849 0.0892108 0.0022880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 29 43688 -0.056551 0.469149 0.0869796 0.0021700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 6 30 43689 -0.053151 0.470449 0.0848755 0.0020400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 1 43690 -0.049651 0.471749 0.0828973 0.0019160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 2 43691 -0.046250 0.472950 0.0810352 0.0018120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 3 43692 -0.042750 0.474150 0.0792540 0.0017370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 4 43693 -0.039350 0.475350 0.0775379 0.0016990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 5 43694 -0.035849 0.476451 0.0758527 0.0016790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 6 43695 -0.032349 0.477551 0.0741696 0.0016930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 7 43696 -0.028849 0.478551 0.0724564 0.0017370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 8 43697 -0.025349 0.479551 0.0706783 0.0018030 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 9 43698 -0.021748 0.480552 0.0688361 0.0018790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 10 43699 -0.018148 0.481452 0.0669190 0.0019550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 11 43700 -0.014448 0.482252 0.0649418 0.0020070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 12 43701 -0.010748 0.483152 0.0629137 0.0020460 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 13 43702 -0.007047 0.483853 0.0608616 0.0020450 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 14 43703 -0.003247 0.484553 0.0588254 0.0020210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 15 43704 0.000553 0.485253 0.0568393 0.0019560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 16 43705 0.004454 0.485754 0.0549291 0.0018730 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 17 43706 0.008354 0.486354 0.0530820 0.0018040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 18 43707 0.012354 0.486754 0.0513008 0.0017670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 19 43708 0.016354 0.487154 0.0495287 0.0017950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 20 43709 0.020355 0.487455 0.0477015 0.0018750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 21 43710 0.024455 0.487755 0.0457694 0.0019830 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 22 43711 0.028555 0.487855 0.0437332 0.0020860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 23 43712 0.032655 0.487955 0.0416131 0.0021380 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 24 43713 0.036756 0.487956 0.0394699 0.0021300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 25 43714 0.040956 0.487856 0.0373758 0.0020560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 26 43715 0.045156 0.487756 0.0353826 0.0019290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 27 43716 0.049357 0.487457 0.0335155 0.0018040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 28 43717 0.053557 0.487157 0.0317713 0.0016840 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 29 43718 0.057757 0.486757 0.0301502 0.0015830 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 30 43719 0.061857 0.486257 0.0286041 0.0015130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 7 31 43720 0.066058 0.485658 0.0271009 0.0014910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 1 43721 0.070158 0.485058 0.0256088 0.0015080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 2 43722 0.074258 0.484258 0.0240816 0.0015630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 3 43723 0.078258 0.483458 0.0224835 0.0016490 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 4 43724 0.082259 0.482559 0.0207753 0.0017590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 5 43725 0.086259 0.481559 0.0189502 0.0018920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 6 43726 0.090059 0.480459 0.0170000 0.0020160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 7 43727 0.093960 0.479260 0.0149229 0.0021280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 8 43728 0.097660 0.478060 0.0127447 0.0022250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 9 43729 0.101360 0.476760 0.0104936 0.0022800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 10 43730 0.104960 0.475360 0.0081834 0.0023120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 11 43731 0.108561 0.473861 0.0058783 0.0023060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 12 43732 0.111961 0.472361 0.0035871 0.0022740 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 13 43733 0.115361 0.470761 0.0013290 0.0022430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 14 43734 0.118661 0.469061 -0.0009172 0.0022480 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 15 43735 0.121962 0.467362 -0.0031723 0.0022790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 16 43736 0.125162 0.465562 -0.0055064 0.0023760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 17 43737 0.128262 0.463762 -0.0079396 0.0025080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 18 43738 0.131263 0.461863 -0.0105157 0.0026510 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 19 43739 0.134263 0.459963 -0.0132319 0.0027630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 20 43740 0.137163 0.457963 -0.0160190 0.0028060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 21 43741 0.139963 0.455963 -0.0188192 0.0027710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 22 43742 0.142764 0.453864 -0.0215373 0.0026680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 23 43743 0.145464 0.451864 -0.0241325 0.0025290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 24 43744 0.148164 0.449664 -0.0266026 0.0023920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 25 43745 0.150765 0.447565 -0.0289228 0.0022710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 26 43746 0.153365 0.445365 -0.0311449 0.0021710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 27 43747 0.155965 0.443065 -0.0332871 0.0021190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 28 43748 0.158465 0.440865 -0.0353982 0.0021090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 29 43749 0.160866 0.438566 -0.0375204 0.0021410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 30 43750 0.163366 0.436266 -0.0396925 0.0021990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 8 31 43751 0.165766 0.433966 -0.0419286 0.0022840 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 1 43752 0.168066 0.431666 -0.0442568 0.0023860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 2 43753 0.170467 0.429267 -0.0466919 0.0024820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 3 43754 0.172767 0.426967 -0.0492171 0.0025690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 4 43755 0.174967 0.424567 -0.0518222 0.0026250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 5 43756 0.177268 0.422168 -0.0544564 0.0026460 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 6 43757 0.179468 0.419768 -0.0571035 0.0026280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 7 43758 0.181668 0.417268 -0.0597107 0.0025740 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 8 43759 0.183868 0.414868 -0.0622538 0.0024900 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 9 43760 0.185969 0.412369 -0.0647010 0.0024060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 10 43761 0.188069 0.409969 -0.0670751 0.0023440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 11 43762 0.190169 0.407469 -0.0694053 0.0023340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 12 43763 0.192269 0.404969 -0.0717524 0.0023680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 13 43764 0.194270 0.402370 -0.0741676 0.0024620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 14 43765 0.196170 0.399870 -0.0766857 0.0025870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 15 43766 0.198170 0.397270 -0.0793409 0.0027370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 16 43767 0.200071 0.394671 -0.0821360 0.0028310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 17 43768 0.201871 0.392071 -0.0849891 0.0028620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 18 43769 0.203771 0.389471 -0.0878433 0.0028430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 19 43770 0.205471 0.386771 -0.0906464 0.0027650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 20 43771 0.207272 0.384072 -0.0933536 0.0026580 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 21 43772 0.208972 0.381372 -0.0959517 0.0025540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 22 43773 0.210572 0.378572 -0.0984589 0.0024740 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 23 43774 0.212172 0.375772 -0.1009140 0.0024420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 24 43775 0.213773 0.372973 -0.1033552 0.0024510 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 25 43776 0.215273 0.370073 -0.1058203 0.0024950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 26 43777 0.216773 0.367073 -0.1083495 0.0025690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 27 43778 0.218174 0.364074 -0.1109706 0.0026860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 28 43779 0.219474 0.361074 -0.1137198 0.0028150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 29 43780 0.220874 0.357974 -0.1166129 0.0029640 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 9 30 43781 0.222074 0.354874 -0.1196471 0.0030890 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 1 43782 0.223275 0.351675 -0.1227972 0.0031980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 2 43783 0.224475 0.348475 -0.1260323 0.0032780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 3 43784 0.225575 0.345175 -0.1293295 0.0032960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 4 43785 0.226575 0.341875 -0.1326106 0.0032600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 5 43786 0.227576 0.338476 -0.1358468 0.0032010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 6 43787 0.228476 0.334976 -0.1390089 0.0031200 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 7 43788 0.229376 0.331476 -0.1420931 0.0030460 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 8 43789 0.230177 0.327977 -0.1451242 0.0030100 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 9 43790 0.230877 0.324377 -0.1481434 0.0030270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 10 43791 0.231577 0.320777 -0.1511945 0.0030940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 11 43792 0.232177 0.317077 -0.1543447 0.0031990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 12 43793 0.232678 0.313378 -0.1575968 0.0033040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 13 43794 0.233178 0.309578 -0.1609440 0.0033970 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 14 43795 0.233578 0.305778 -0.1643631 0.0034270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 15 43796 0.233878 0.301978 -0.1677763 0.0033960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 16 43797 0.234179 0.298079 -0.1711224 0.0032980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 17 43798 0.234379 0.294279 -0.1743475 0.0031440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 18 43799 0.234579 0.290379 -0.1774157 0.0029830 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 19 43800 0.234680 0.286480 -0.1803268 0.0028440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 20 43801 0.234680 0.282680 -0.1831050 0.0027260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 21 43802 0.234680 0.278780 -0.1858041 0.0026580 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 22 43803 0.234580 0.274980 -0.1884463 0.0026320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 23 43804 0.234481 0.271081 -0.1910824 0.0026490 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 24 43805 0.234181 0.267281 -0.1937556 0.0027020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 25 43806 0.233981 0.263481 -0.1964947 0.0027830 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 26 43807 0.233681 0.259781 -0.1993259 0.0028790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 27 43808 0.233282 0.255982 -0.2022550 0.0029780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 28 43809 0.232882 0.252382 -0.2052682 0.0030670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 29 43810 0.232382 0.248682 -0.2083723 0.0031350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 30 43811 0.231883 0.245083 -0.2115385 0.0031690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 10 31 43812 0.231383 0.241583 -0.2147056 0.0031700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 1 43813 0.230783 0.238083 -0.2178537 0.0031190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 2 43814 0.230183 0.234683 -0.2209349 0.0030500 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 3 43815 0.229584 0.231284 -0.2239440 0.0029710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 4 43816 0.228884 0.227984 -0.2268882 0.0029330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 5 43817 0.228184 0.224684 -0.2298163 0.0029340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 6 43818 0.227384 0.221484 -0.2327755 0.0029890 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 7 43819 0.226685 0.218385 -0.2358166 0.0030910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 8 43820 0.225885 0.215285 -0.2389628 0.0032080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 9 43821 0.225085 0.212185 -0.2422199 0.0033020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 10 43822 0.224186 0.209186 -0.2455541 0.0033670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 11 43823 0.223386 0.206186 -0.2489352 0.0033770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 12 43824 0.222486 0.203286 -0.2522994 0.0033290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 13 43825 0.221586 0.200386 -0.2555765 0.0032310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 14 43826 0.220587 0.197487 -0.2587516 0.0031170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 15 43827 0.219687 0.194587 -0.2617988 0.0029920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 16 43828 0.218687 0.191787 -0.2647419 0.0028880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 17 43829 0.217588 0.188988 -0.2675971 0.0028280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 18 43830 0.216588 0.186188 -0.2704032 0.0027990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 19 43831 0.215488 0.183388 -0.2732074 0.0028090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 20 43832 0.214288 0.180588 -0.2760415 0.0028660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 21 43833 0.213089 0.177789 -0.2789407 0.0029430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 22 43834 0.211889 0.174989 -0.2819258 0.0030310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 23 43835 0.210589 0.172289 -0.2850030 0.0031260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 24 43836 0.209289 0.169489 -0.2881761 0.0032070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 25 43837 0.207990 0.166690 -0.2914233 0.0032740 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 26 43838 0.206590 0.163990 -0.2947264 0.0033270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 27 43839 0.205090 0.161190 -0.2980565 0.0033260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 28 43840 0.203591 0.158491 -0.3013647 0.0032950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 29 43841 0.202091 0.155791 -0.3046348 0.0032300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 11 30 43842 0.200491 0.153091 -0.3078100 0.0031390 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 1 43843 0.198891 0.150391 -0.3109181 0.0030710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 2 43844 0.197292 0.147792 -0.3139673 0.0030360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 3 43845 0.195592 0.145192 -0.3170074 0.0030650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 4 43846 0.193892 0.142592 -0.3201016 0.0031290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 5 43847 0.192192 0.139992 -0.3232717 0.0032110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 6 43848 0.190393 0.137493 -0.3265209 0.0032890 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 7 43849 0.188593 0.134993 -0.3298280 0.0033170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 8 43850 0.186793 0.132493 -0.3331352 0.0032920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 9 43851 0.184894 0.130094 -0.3364043 0.0032250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 10 43852 0.182994 0.127694 -0.3395724 0.0031150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 11 43853 0.181194 0.125394 -0.3426146 0.0029690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 12 43854 0.179294 0.123094 -0.3455077 0.0028280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 13 43855 0.177295 0.120895 -0.3482659 0.0026920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 14 43856 0.175395 0.118695 -0.3509030 0.0025960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 15 43857 0.173395 0.116495 -0.3534612 0.0025280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 16 43858 0.171495 0.114395 -0.3559803 0.0025070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 17 43859 0.169496 0.112296 -0.3584985 0.0025220 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 18 43860 0.167496 0.110296 -0.3610356 0.0025670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 19 43861 0.165496 0.108296 -0.3636308 0.0026340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 20 43862 0.163597 0.106297 -0.3663079 0.0027120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 21 43863 0.161597 0.104397 -0.3690641 0.0027980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 22 43864 0.159497 0.102497 -0.3718902 0.0028740 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 23 43865 0.157497 0.100597 -0.3748043 0.0029400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 24 43866 0.155498 0.098798 -0.3777635 0.0029710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 25 43867 0.153498 0.096998 -0.3807476 0.0029930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 26 43868 0.151398 0.095198 -0.3837288 0.0029730 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 27 43869 0.149398 0.093398 -0.3866879 0.0029420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 28 43870 0.147299 0.091699 -0.3896031 0.0029110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 29 43871 0.145199 0.089999 -0.3925102 0.0029090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 30 43872 0.143099 0.088299 -0.3954394 0.0029590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1978 12 31 43873 0.140900 0.086600 -0.3984455 0.0030620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 1 43874 0.138800 0.085000 0.5984263 0.0031970 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 2 43875 0.136500 0.083400 0.5951622 0.0033250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 3 43876 0.134300 0.081800 0.5918001 0.0034000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 4 43877 0.132001 0.080201 0.5883829 0.0034110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 5 43878 0.129601 0.078701 0.5849888 0.0033570 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 6 43879 0.127201 0.077101 0.5816736 0.0032560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 7 43880 0.124701 0.075601 0.5784855 0.0031180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 8 43881 0.122102 0.074202 0.5754283 0.0029770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 9 43882 0.119502 0.072702 0.5725162 0.0028510 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 10 43883 0.116902 0.071302 0.5697150 0.0027440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 11 43884 0.114103 0.070003 0.5670139 0.0026650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 12 43885 0.111303 0.068603 0.5643717 0.0026360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 13 43886 0.108503 0.067303 0.5617396 0.0026330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 14 43887 0.105603 0.066103 0.5590965 0.0026590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 15 43888 0.102604 0.064904 0.5564233 0.0027080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 16 43889 0.099504 0.063704 0.5536742 0.0027800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 17 43890 0.096504 0.062604 0.5508620 0.0028430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 18 43891 0.093304 0.061604 0.5479819 0.0029160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 19 43892 0.090105 0.060605 0.5450467 0.0029590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 20 43893 0.086905 0.059605 0.5420616 0.0029990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 21 43894 0.083705 0.058705 0.5390594 0.0030120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 22 43895 0.080406 0.057906 0.5360443 0.0030110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 23 43896 0.077106 0.057106 0.5330532 0.0029820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 24 43897 0.073806 0.056406 0.5300820 0.0029490 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 25 43898 0.070506 0.055806 0.5271489 0.0029340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 26 43899 0.067207 0.055207 0.5242107 0.0029730 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 27 43900 0.063807 0.054707 0.5211946 0.0030590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 28 43901 0.060607 0.054307 0.5180644 0.0031940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 29 43902 0.057307 0.053907 0.5148003 0.0033450 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 30 43903 0.054008 0.053608 0.5113961 0.0034560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 1 31 43904 0.050808 0.053408 0.5079010 0.0035090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 1 43905 0.047608 0.053308 0.5044128 0.0034600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 2 43906 0.044509 0.053209 0.5010037 0.0033410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 3 43907 0.041409 0.053209 0.4977356 0.0031790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 4 43908 0.038309 0.053309 0.4946474 0.0030060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 5 43909 0.035309 0.053409 0.4917293 0.0028370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 6 43910 0.032410 0.053710 0.4889641 0.0027000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 7 43911 0.029510 0.054010 0.4863160 0.0026010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 8 43912 0.026610 0.054310 0.4837458 0.0025460 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 9 43913 0.023811 0.054811 0.4812007 0.0025310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 10 43914 0.021111 0.055311 0.4786625 0.0025600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 11 43915 0.018411 0.055811 0.4760814 0.0026050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 12 43916 0.015711 0.056511 0.4734463 0.0026630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 13 43917 0.013112 0.057212 0.4707521 0.0027260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 14 43918 0.010512 0.058012 0.4679880 0.0027910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 15 43919 0.007912 0.058812 0.4651758 0.0028370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 16 43920 0.005312 0.059712 0.4623327 0.0028550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 17 43921 0.002813 0.060713 0.4594745 0.0028440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 18 43922 0.000313 0.061813 0.4566424 0.0028070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 19 43923 -0.002187 0.062913 0.4538572 0.0027620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 20 43924 -0.004686 0.064114 0.4511191 0.0027140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 21 43925 -0.007186 0.065314 0.4484250 0.0026800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 22 43926 -0.009586 0.066614 0.4457468 0.0026920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 23 43927 -0.012086 0.067914 0.4430207 0.0027580 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 24 43928 -0.014585 0.069415 0.4402005 0.0028930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 25 43929 -0.017085 0.070815 0.4372324 0.0030570 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 26 43930 -0.019585 0.072315 0.4340862 0.0032210 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 27 43931 -0.022085 0.073915 0.4307961 0.0033460 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 2 28 43932 -0.024584 0.075516 0.4274319 0.0033780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 1 43933 -0.027084 0.077116 0.4240708 0.0033190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 2 43934 -0.029684 0.078716 0.4208067 0.0031900 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 3 43935 -0.032183 0.080417 0.4176905 0.0030380 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 4 43936 -0.034683 0.082117 0.4147414 0.0028770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 5 43937 -0.037283 0.083817 0.4119392 0.0027420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 6 43938 -0.039783 0.085517 0.4092521 0.0026490 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 7 43939 -0.042382 0.087218 0.4066359 0.0026000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 8 43940 -0.044882 0.088918 0.4040348 0.0025970 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 9 43941 -0.047482 0.090718 0.4014276 0.0026330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 10 43942 -0.049982 0.092418 0.3987685 0.0027000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 11 43943 -0.052581 0.094119 0.3960324 0.0027860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 12 43944 -0.055181 0.095819 0.3932032 0.0028800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 13 43945 -0.057681 0.097419 0.3902821 0.0029700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 14 43946 -0.060280 0.099120 0.3872689 0.0030440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 15 43947 -0.062780 0.100820 0.3841948 0.0031020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 16 43948 -0.065280 0.102420 0.3810876 0.0031160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 17 43949 -0.067780 0.104120 0.3779725 0.0030960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 18 43950 -0.070279 0.105721 0.3748934 0.0030520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 19 43951 -0.072779 0.107321 0.3718622 0.0029990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 20 43952 -0.075179 0.109021 0.3688811 0.0029570 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 21 43953 -0.077679 0.110621 0.3659369 0.0029470 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 22 43954 -0.080078 0.112222 0.3629808 0.0029760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 23 43955 -0.082478 0.113822 0.3599646 0.0030620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 24 43956 -0.084778 0.115522 0.3568385 0.0031980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 25 43957 -0.087077 0.117123 0.3535613 0.0033590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 26 43958 -0.089377 0.118823 0.3501152 0.0035030 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 27 43959 -0.091677 0.120523 0.3465651 0.0035870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 28 43960 -0.093877 0.122223 0.3429729 0.0035830 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 29 43961 -0.096176 0.123924 0.3394278 0.0034920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 30 43962 -0.098276 0.125724 0.3359986 0.0033400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 3 31 43963 -0.100476 0.127524 0.3327445 0.0031750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 1 43964 -0.102576 0.129324 0.3296543 0.0030130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 2 43965 -0.104775 0.131225 0.3267072 0.0028960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 3 43966 -0.106775 0.133125 0.3238571 0.0028140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 4 43967 -0.108875 0.135125 0.3210639 0.0027790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 5 43968 -0.110874 0.137126 0.3182738 0.0027970 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 6 43969 -0.112974 0.139226 0.3154566 0.0028420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 7 43970 -0.114874 0.141326 0.3125715 0.0029220 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 8 43971 -0.116874 0.143426 0.3096073 0.0030150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 9 43972 -0.118773 0.145627 0.3065412 0.0031080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 10 43973 -0.120673 0.147927 0.3033951 0.0031910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 11 43974 -0.122473 0.150127 0.3001669 0.0032610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 12 43975 -0.124273 0.152527 0.2968818 0.0032910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 13 43976 -0.125972 0.154828 0.2935866 0.0032940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 14 43977 -0.127672 0.157228 0.2903145 0.0032540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 15 43978 -0.129372 0.159728 0.2870843 0.0031930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 16 43979 -0.130971 0.162229 0.2839172 0.0031350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 17 43980 -0.132471 0.164729 0.2807971 0.0030920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 18 43981 -0.133971 0.167229 0.2777079 0.0030940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 19 43982 -0.135371 0.169829 0.2745898 0.0031410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 20 43983 -0.136670 0.172330 0.2713986 0.0032470 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 21 43984 -0.137970 0.174930 0.2680945 0.0033660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 22 43985 -0.139170 0.177530 0.2646663 0.0034880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 23 43986 -0.140370 0.180130 0.2611182 0.0035870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 24 43987 -0.141469 0.182631 0.2575231 0.0036110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 25 43988 -0.142469 0.185231 0.2539339 0.0035530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 26 43989 -0.143469 0.187731 0.2504418 0.0034130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 27 43990 -0.144368 0.190232 0.2471146 0.0032380 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 28 43991 -0.145168 0.192732 0.2439785 0.0030560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 29 43992 -0.145968 0.195132 0.2410043 0.0028860 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 4 30 43993 -0.146768 0.197632 0.2381802 0.0027670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 1 43994 -0.147367 0.200033 0.2354451 0.0027040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 2 43995 -0.148067 0.202333 0.2327589 0.0026850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 3 43996 -0.148667 0.204733 0.2300708 0.0026950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 4 43997 -0.149166 0.207034 0.2273566 0.0027450 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 5 43998 -0.149666 0.209334 0.2245825 0.0028140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 6 43999 -0.150066 0.211534 0.2217363 0.0028780 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 7 44000 -0.150466 0.213834 0.2188202 0.0029450 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 8 44001 -0.150865 0.216035 0.2158541 0.0030050 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 9 44002 -0.151165 0.218235 0.2128279 0.0030290 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 10 44003 -0.151465 0.220435 0.2097948 0.0030320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 11 44004 -0.151665 0.222635 0.2067846 0.0030000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 12 44005 -0.151964 0.224836 0.2038135 0.0029390 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 13 44006 -0.152064 0.227036 0.2009103 0.0028570 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 14 44007 -0.152264 0.229136 0.1980842 0.0028000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 15 44008 -0.152363 0.231337 0.1952971 0.0027720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 16 44009 -0.152563 0.233537 0.1925219 0.0027970 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 17 44010 -0.152563 0.235737 0.1896938 0.0028630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 18 44011 -0.152663 0.237937 0.1867946 0.0029510 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 19 44012 -0.152662 0.240038 0.1837805 0.0030560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 20 44013 -0.152762 0.242338 0.1806884 0.0031280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 21 44014 -0.152762 0.244538 0.1775412 0.0031500 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 22 44015 -0.152662 0.246738 0.1744101 0.0031080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 23 44016 -0.152661 0.248939 0.1713559 0.0029900 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 24 44017 -0.152561 0.251239 0.1684358 0.0028320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 25 44018 -0.152561 0.253439 0.1656986 0.0026420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 26 44019 -0.152460 0.255740 0.1631375 0.0024720 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 27 44020 -0.152360 0.258040 0.1607544 0.0023230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 28 44021 -0.152160 0.260240 0.1584872 0.0022180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 29 44022 -0.152060 0.262540 0.1562941 0.0021560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 30 44023 -0.151859 0.264841 0.1541529 0.0021430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 5 31 44024 -0.151659 0.267241 0.1520078 0.0021530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 1 44025 -0.151459 0.269541 0.1498397 0.0021940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 2 44026 -0.151259 0.271841 0.1476235 0.0022360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 3 44027 -0.151058 0.274142 0.1453594 0.0022840 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 4 44028 -0.150758 0.276542 0.1430512 0.0023280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 5 44029 -0.150458 0.278842 0.1407201 0.0023410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 6 44030 -0.150157 0.281243 0.1383860 0.0023390 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 7 44031 -0.149857 0.283543 0.1360518 0.0023170 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 8 44032 -0.149457 0.285943 0.1337537 0.0022760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 9 44033 -0.149157 0.288243 0.1315165 0.0022160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 10 44034 -0.148656 0.290644 0.1293314 0.0021570 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 11 44035 -0.148256 0.292944 0.1271922 0.0021260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 12 44036 -0.147756 0.295244 0.1250511 0.0021570 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 13 44037 -0.147256 0.297644 0.1228610 0.0022430 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 14 44038 -0.146655 0.299945 0.1205618 0.0023680 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 15 44039 -0.146055 0.302245 0.1181307 0.0025010 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 16 44040 -0.145355 0.304545 0.1155685 0.0026090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 17 44041 -0.144654 0.306846 0.1129294 0.0026670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 18 44042 -0.143854 0.309146 0.1102653 0.0026520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 19 44043 -0.143054 0.311446 0.1076441 0.0025890 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 20 44044 -0.142254 0.313746 0.1051020 0.0024790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 21 44045 -0.141353 0.316047 0.1026928 0.0023370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 22 44046 -0.140353 0.318347 0.1004267 0.0022080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 23 44047 -0.139353 0.320547 0.0982776 0.0020930 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 24 44048 -0.138253 0.322847 0.0962264 0.0020190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 25 44049 -0.137152 0.325048 0.0942163 0.0019970 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 26 44050 -0.136052 0.327348 0.0922181 0.0020060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 27 44051 -0.134752 0.329548 0.0901940 0.0020360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 28 44052 -0.133451 0.331749 0.0881379 0.0020900 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 29 44053 -0.132151 0.333949 0.0860197 0.0021460 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 6 30 44054 -0.130751 0.336149 0.0838356 0.0022040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 1 44055 -0.129251 0.338349 0.0816164 0.0022400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 2 44056 -0.127750 0.340450 0.0793623 0.0022660 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 3 44057 -0.126150 0.342650 0.0771012 0.0022590 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 4 44058 -0.124550 0.344750 0.0748520 0.0022370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 5 44059 -0.122850 0.346850 0.0726349 0.0021820 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 6 44060 -0.121149 0.349051 0.0704827 0.0021180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 7 44061 -0.119349 0.351051 0.0684006 0.0020380 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 8 44062 -0.117449 0.353151 0.0664025 0.0019740 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 9 44063 -0.115548 0.355252 0.0644293 0.0019620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 10 44064 -0.113648 0.357252 0.0624592 0.0019980 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 11 44065 -0.111648 0.359252 0.0604150 0.0020960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 12 44066 -0.109648 0.361252 0.0582589 0.0022070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 13 44067 -0.107547 0.363253 0.0560078 0.0023090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 14 44068 -0.105447 0.365153 0.0536706 0.0023440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 15 44069 -0.103247 0.367153 0.0513345 0.0023140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 16 44070 -0.101047 0.369053 0.0490643 0.0022150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 17 44071 -0.098746 0.370854 0.0469312 0.0020650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 18 44072 -0.096446 0.372754 0.0449531 0.0018920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 19 44073 -0.094146 0.374554 0.0431459 0.0017220 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 20 44074 -0.091745 0.376255 0.0415008 0.0015870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 21 44075 -0.089245 0.378055 0.0399696 0.0014800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 22 44076 -0.086745 0.379655 0.0385145 0.0014380 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 23 44077 -0.084245 0.381355 0.0370804 0.0014280 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 24 44078 -0.081644 0.382956 0.0356382 0.0014610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 25 44079 -0.079044 0.384556 0.0341491 0.0015190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 26 44080 -0.076344 0.386056 0.0325949 0.0016000 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 27 44081 -0.073644 0.387556 0.0309578 0.0016750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 28 44082 -0.070943 0.388957 0.0292367 0.0017520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 29 44083 -0.068143 0.390257 0.0274485 0.0018100 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 30 44084 -0.065343 0.391657 0.0256134 0.0018550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 7 31 44085 -0.062442 0.392858 0.0237382 0.0018840 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 1 44086 -0.059542 0.394058 0.0218541 0.0018920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 2 44087 -0.056642 0.395258 0.0199700 0.0018840 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 3 44088 -0.053742 0.396358 0.0180868 0.0018710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 4 44089 -0.050741 0.397459 0.0162237 0.0018670 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 5 44090 -0.047741 0.398459 0.0143425 0.0018940 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 6 44091 -0.044741 0.399359 0.0124074 0.0019850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 7 44092 -0.041740 0.400260 0.0103613 0.0021260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 8 44093 -0.038740 0.401060 0.0081381 0.0023110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 9 44094 -0.035740 0.401860 0.0057360 0.0024900 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 10 44095 -0.032740 0.402660 0.0031729 0.0026340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 11 44096 -0.029739 0.403361 0.0005067 0.0026850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 12 44097 -0.026739 0.403961 -0.0021664 0.0026460 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 13 44098 -0.023739 0.404561 -0.0047596 0.0025330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 14 44099 -0.020839 0.405161 -0.0072187 0.0023710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 15 44100 -0.017838 0.405662 -0.0095028 0.0021880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 16 44101 -0.014838 0.406062 -0.0116140 0.0020390 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 17 44102 -0.011938 0.406562 -0.0135841 0.0019220 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 18 44103 -0.009037 0.406963 -0.0154743 0.0018530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 19 44104 -0.006137 0.407263 -0.0173164 0.0018300 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 20 44105 -0.003337 0.407663 -0.0191465 0.0018350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 21 44106 -0.000437 0.407963 -0.0209957 0.0018770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 22 44107 0.002364 0.408164 -0.0228968 0.0019260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 23 44108 0.005164 0.408464 -0.0248489 0.0019790 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 24 44109 0.007864 0.408664 -0.0268531 0.0020260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 25 44110 0.010664 0.408964 -0.0288972 0.0020470 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 26 44111 0.013365 0.409165 -0.0309514 0.0020640 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 27 44112 0.015965 0.409365 -0.0330065 0.0020440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 28 44113 0.018665 0.409465 -0.0350286 0.0020080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 29 44114 0.021266 0.409666 -0.0370168 0.0019550 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 30 44115 0.023866 0.409866 -0.0389479 0.0019060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 8 31 44116 0.026366 0.409966 -0.0408430 0.0018770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 1 44117 0.028866 0.410066 -0.0427092 0.0018730 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 2 44118 0.031367 0.410267 -0.0446043 0.0019140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 3 44119 0.033867 0.410367 -0.0465685 0.0020340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 4 44120 0.036267 0.410467 -0.0486826 0.0022020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 5 44121 0.038667 0.410467 -0.0509827 0.0024110 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 6 44122 0.040968 0.410568 -0.0534889 0.0026040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 7 44123 0.043268 0.410568 -0.0561580 0.0027220 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 8 44124 0.045568 0.410568 -0.0589101 0.0027520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 9 44125 0.047769 0.410569 -0.0616393 0.0026840 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 10 44126 0.049969 0.410469 -0.0642544 0.0025470 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 11 44127 0.052069 0.410469 -0.0667156 0.0023750 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 12 44128 0.054169 0.410369 -0.0689987 0.0022070 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 13 44129 0.056270 0.410170 -0.0711428 0.0020900 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 14 44130 0.058270 0.409970 -0.0731970 0.0020150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 15 44131 0.060170 0.409770 -0.0751901 0.0019910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 16 44132 0.062070 0.409570 -0.0771932 0.0020120 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 17 44133 0.063971 0.409271 -0.0792264 0.0020560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 18 44134 0.065771 0.408971 -0.0813125 0.0021320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 19 44135 0.067371 0.408571 -0.0834837 0.0022060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 20 44136 0.069072 0.408172 -0.0857348 0.0022950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 21 44137 0.070772 0.407772 -0.0880699 0.0023710 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 22 44138 0.072372 0.407272 -0.0904591 0.0024240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 23 44139 0.073972 0.406772 -0.0928972 0.0024490 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 24 44140 0.075573 0.406173 -0.0953563 0.0024540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 25 44141 0.077173 0.405673 -0.0977975 0.0024350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 26 44142 0.078773 0.405073 -0.1002226 0.0024140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 27 44143 0.080273 0.404373 -0.1026177 0.0023890 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 28 44144 0.081774 0.403774 -0.1049979 0.0023870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 29 44145 0.083274 0.403074 -0.1074050 0.0024260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 9 30 44146 0.084674 0.402374 -0.1098792 0.0025190 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 1 44147 0.085975 0.401675 -0.1124633 0.0026700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 2 44148 0.087275 0.400975 -0.1152234 0.0028570 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 3 44149 0.088475 0.400175 -0.1181816 0.0030580 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 4 44150 0.089675 0.399375 -0.1213397 0.0032260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 5 44151 0.090776 0.398576 -0.1246198 0.0033180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 6 44152 0.091776 0.397776 -0.1279320 0.0033080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 7 44153 0.092876 0.396976 -0.1311931 0.0031950 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 8 44154 0.093676 0.396176 -0.1343112 0.0030350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 9 44155 0.094477 0.395277 -0.1372514 0.0028530 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 10 44156 0.095277 0.394377 -0.1400185 0.0026990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 11 44157 0.095977 0.393477 -0.1426566 0.0025850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 12 44158 0.096678 0.392478 -0.1452078 0.0025350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 13 44159 0.097478 0.391478 -0.1477339 0.0025250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 14 44160 0.098278 0.390478 -0.1502721 0.0025560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 15 44161 0.099178 0.389478 -0.1528442 0.0026040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 16 44162 0.100079 0.388479 -0.1554943 0.0026770 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 17 44163 0.101079 0.387479 -0.1581995 0.0027400 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 18 44164 0.102179 0.386479 -0.1609706 0.0027920 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 19 44165 0.103379 0.385479 -0.1637867 0.0028230 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 20 44166 0.104680 0.384480 -0.1666199 0.0028080 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 21 44167 0.105980 0.383580 -0.1694130 0.0027730 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 22 44168 0.107380 0.382680 -0.1721551 0.0027090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 23 44169 0.108881 0.381681 -0.1748223 0.0026240 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 24 44170 0.110481 0.380681 -0.1774014 0.0025340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 25 44171 0.112281 0.379681 -0.1798975 0.0024620 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 26 44172 0.113981 0.378581 -0.1823267 0.0024260 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 27 44173 0.115782 0.377382 -0.1847558 0.0024420 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 28 44174 0.117682 0.376182 -0.1872299 0.0025130 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 29 44175 0.119482 0.374882 -0.1897981 0.0026410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 30 44176 0.121283 0.373583 -0.1925102 0.0027960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 10 31 44177 0.123083 0.372183 -0.1953784 0.0029330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 1 44178 0.124783 0.370683 -0.1983705 0.0030330 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 2 44179 0.126383 0.369083 -0.2014256 0.0030630 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 3 44180 0.127884 0.367484 -0.2044558 0.0029910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 4 44181 0.129284 0.365884 -0.2073829 0.0028440 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 5 44182 0.130484 0.364084 -0.2101320 0.0026580 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 6 44183 0.131684 0.362284 -0.2127112 0.0024870 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 7 44184 0.132585 0.360485 -0.2151193 0.0023520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 8 44185 0.133385 0.358585 -0.2174344 0.0022800 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 9 44186 0.134085 0.356685 -0.2196866 0.0022500 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 10 44187 0.134586 0.354686 -0.2219497 0.0022730 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 11 44188 0.134986 0.352586 -0.2242328 0.0023200 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 12 44189 0.135286 0.350486 -0.2265940 0.0023960 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 13 44190 0.135386 0.348386 -0.2290291 0.0024690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 14 44191 0.135387 0.346287 -0.2315232 0.0025360 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 15 44192 0.135287 0.344087 -0.2340844 0.0025850 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 16 44193 0.135187 0.341987 -0.2366845 0.0026100 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 17 44194 0.134987 0.339787 -0.2392866 0.0025990 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 18 44195 0.134788 0.337588 -0.2418818 0.0025690 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 19 44196 0.134488 0.335388 -0.2444159 0.0025140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 20 44197 0.134188 0.333188 -0.2468960 0.0024340 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 21 44198 0.133889 0.330989 -0.2492952 0.0023700 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 22 44199 0.133589 0.328689 -0.2516363 0.0023250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 23 44200 0.133389 0.326489 -0.2539624 0.0023380 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 24 44201 0.133189 0.324289 -0.2563306 0.0024060 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 25 44202 0.132990 0.322090 -0.2587997 0.0025310 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 26 44203 0.132890 0.319890 -0.2614018 0.0026730 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 27 44204 0.132790 0.317690 -0.2641470 0.0028140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 28 44205 0.132790 0.315590 -0.2670301 0.0029320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 29 44206 0.132791 0.313491 -0.2699922 0.0029910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 11 30 44207 0.132791 0.311391 -0.2729864 0.0029760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 1 44208 0.132891 0.309291 -0.2759295 0.0028890 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 2 44209 0.132992 0.307192 -0.2787596 0.0027640 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 3 44210 0.133092 0.305192 -0.2814428 0.0026140 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 4 44211 0.133192 0.303192 -0.2839849 0.0024760 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 5 44212 0.133292 0.301192 -0.2864190 0.0023910 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 6 44213 0.133493 0.299293 -0.2887822 0.0023560 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 7 44214 0.133693 0.297393 -0.2911353 0.0023570 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 8 44215 0.133893 0.295493 -0.2935174 0.0024020 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 9 44216 0.134093 0.293593 -0.2959496 0.0024610 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 10 44217 0.134294 0.291794 -0.2984327 0.0025200 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 11 44218 0.134594 0.289994 -0.3009998 0.0025880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 12 44219 0.134894 0.288194 -0.3036140 0.0026320 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 13 44220 0.135295 0.286395 -0.3062551 0.0026540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 14 44221 0.135695 0.284695 -0.3089152 0.0026520 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 15 44222 0.136095 0.282995 -0.3115504 0.0026150 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 16 44223 0.136495 0.281295 -0.3141475 0.0025650 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 17 44224 0.136996 0.279696 -0.3166746 0.0024880 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 18 44225 0.137496 0.278096 -0.3191318 0.0024180 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 19 44226 0.138096 0.276496 -0.3215149 0.0023540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 20 44227 0.138596 0.274896 -0.3238650 0.0023410 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 21 44228 0.139197 0.273297 -0.3262171 0.0023840 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 22 44229 0.139697 0.271697 -0.3286413 0.0024810 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 23 44230 0.140197 0.270197 -0.3311794 0.0026090 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 24 44231 0.140698 0.268598 -0.3338485 0.0027350 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 25 44232 0.141098 0.266998 -0.3366387 0.0028270 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 26 44233 0.141398 0.265498 -0.3394808 0.0028600 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 27 44234 0.141698 0.263898 -0.3423349 0.0028250 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 28 44235 0.141899 0.262399 -0.3451201 0.0027370 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 29 44236 0.141999 0.260799 -0.3477952 0.0026040 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 30 44237 0.141999 0.259299 -0.3503143 0.0024540 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1979 12 31 44238 0.141899 0.257699 -0.3526975 0.0023160 0.000000 0.000000 0.015000 0.015000 0.0019000 0.0007000 0.001989 0.002000 1980 1 1 44239 0.141700 0.256100 0.6450414 0.0022150 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 2 44240 0.141300 0.254500 0.6428473 0.0021710 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 3 44241 0.140800 0.252800 0.6406841 0.0021740 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 4 44242 0.140201 0.251201 0.6384880 0.0022130 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 5 44243 0.139501 0.249501 0.6362489 0.0022770 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 6 44244 0.138701 0.247801 0.6339388 0.0023540 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 7 44245 0.137701 0.246101 0.6315316 0.0024410 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 8 44246 0.136702 0.244402 0.6290515 0.0025170 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 9 44247 0.135602 0.242602 0.6265034 0.0025740 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 10 44248 0.134502 0.240802 0.6239112 0.0026060 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 11 44249 0.133302 0.239002 0.6213091 0.0026040 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 12 44250 0.132003 0.237103 0.6187000 0.0025910 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 13 44251 0.130703 0.235103 0.6161208 0.0025650 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 14 44252 0.129303 0.233103 0.6135817 0.0025230 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 15 44253 0.127904 0.231104 0.6110716 0.0025010 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 16 44254 0.126404 0.229104 0.6085694 0.0024990 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 17 44255 0.124904 0.227104 0.6060563 0.0025390 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 18 44256 0.123404 0.225004 0.6034802 0.0026200 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 19 44257 0.121805 0.222905 0.6007981 0.0027570 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 20 44258 0.120205 0.220905 0.5979729 0.0028950 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 21 44259 0.118605 0.218905 0.5950198 0.0030010 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 22 44260 0.116906 0.217006 0.5919927 0.0030390 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 23 44261 0.115206 0.215106 0.5889685 0.0030050 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 24 44262 0.113506 0.213306 0.5860064 0.0028880 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 25 44263 0.111806 0.211606 0.5831983 0.0027220 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 26 44264 0.110007 0.210007 0.5805671 0.0025290 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 27 44265 0.108307 0.208607 0.5781250 0.0023590 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 28 44266 0.106507 0.207307 0.5758479 0.0022140 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 29 44267 0.104707 0.206107 0.5736818 0.0021170 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 30 44268 0.102908 0.205008 0.5715946 0.0020700 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 1 31 44269 0.101208 0.203908 0.5695265 0.0020640 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 1 44270 0.099408 0.202808 0.5674584 0.0020850 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 2 44271 0.097709 0.201809 0.5653602 0.0021110 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 3 44272 0.096009 0.200909 0.5631961 0.0021700 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 4 44273 0.094309 0.200109 0.5609840 0.0022390 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 5 44274 0.092609 0.199309 0.5587229 0.0022910 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 6 44275 0.090910 0.198510 0.5564517 0.0022870 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 7 44276 0.089210 0.197710 0.5541976 0.0022270 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 8 44277 0.087610 0.196910 0.5519955 0.0021640 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 9 44278 0.086010 0.196010 0.5498833 0.0020860 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 10 44279 0.084411 0.195211 0.5478242 0.0020350 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 11 44280 0.082911 0.194311 0.5458231 0.0020010 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 12 44281 0.081511 0.193411 0.5438250 0.0020110 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 13 44282 0.080012 0.192512 0.5417948 0.0020860 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 14 44283 0.078612 0.191612 0.5396317 0.0022410 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 15 44284 0.077312 0.190612 0.5372916 0.0024470 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 16 44285 0.075812 0.189712 0.5347254 0.0026990 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 17 44286 0.074513 0.188813 0.5319073 0.0029320 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 18 44287 0.073113 0.188013 0.5288722 0.0031040 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 19 44288 0.071813 0.187113 0.5257211 0.0031810 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 20 44289 0.070513 0.186313 0.5225509 0.0031510 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 21 44290 0.069214 0.185614 0.5194428 0.0030570 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 22 44291 0.067914 0.184814 0.5164487 0.0029110 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 23 44292 0.066714 0.184014 0.5136095 0.0027410 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 24 44293 0.065515 0.183315 0.5109424 0.0025890 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 25 44294 0.064315 0.182615 0.5084233 0.0024580 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 26 44295 0.063215 0.182015 0.5060082 0.0023710 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 27 44296 0.062015 0.181415 0.5036660 0.0023220 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 28 44297 0.060916 0.180916 0.5013529 0.0023070 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 2 29 44298 0.059816 0.180416 0.4990458 0.0023120 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 1 44299 0.058816 0.180016 0.4967296 0.0023220 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 2 44300 0.057716 0.179716 0.4943945 0.0023350 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 3 44301 0.056717 0.179417 0.4920534 0.0023420 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 4 44302 0.055617 0.179217 0.4897273 0.0023250 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 5 44303 0.054517 0.179017 0.4874211 0.0022800 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 6 44304 0.053518 0.178918 0.4851660 0.0022370 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 7 44305 0.052418 0.178818 0.4829639 0.0021850 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 8 44306 0.051218 0.178818 0.4807998 0.0021340 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 9 44307 0.050018 0.178818 0.4786916 0.0020900 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 10 44308 0.048719 0.178819 0.4766125 0.0020770 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 11 44309 0.047419 0.178919 0.4745264 0.0021010 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 12 44310 0.046019 0.179019 0.4723893 0.0021810 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 13 44311 0.044519 0.179119 0.4701431 0.0023340 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 14 44312 0.043020 0.179220 0.4677030 0.0025440 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 15 44313 0.041320 0.179320 0.4650469 0.0027760 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 16 44314 0.039620 0.179520 0.4621707 0.0029790 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 17 44315 0.037821 0.179821 0.4591076 0.0031200 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 18 44316 0.036021 0.180121 0.4559655 0.0031430 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 19 44317 0.034221 0.180421 0.4528554 0.0030620 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 20 44318 0.032321 0.180721 0.4498732 0.0029050 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 21 44319 0.030422 0.181122 0.4470511 0.0027420 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 22 44320 0.028522 0.181622 0.4443910 0.0025960 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 23 44321 0.026722 0.182022 0.4418309 0.0025120 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 24 44322 0.024822 0.182522 0.4393467 0.0024780 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 25 44323 0.023023 0.183023 0.4368586 0.0024970 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 26 44324 0.021323 0.183523 0.4343385 0.0025580 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 27 44325 0.019523 0.184123 0.4317434 0.0026360 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 28 44326 0.017924 0.184624 0.4290712 0.0027150 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 29 44327 0.016224 0.185224 0.4263231 0.0027810 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 30 44328 0.014624 0.185824 0.4235130 0.0028340 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 3 31 44329 0.013024 0.186524 0.4206639 0.0028540 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 1 44330 0.011425 0.187125 0.4178067 0.0028460 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 2 44331 0.009825 0.187825 0.4149706 0.0028100 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 3 44332 0.008225 0.188425 0.4121945 0.0027370 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 4 44333 0.006625 0.189125 0.4095004 0.0026400 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 5 44334 0.005026 0.189926 0.4069052 0.0025320 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 6 44335 0.003426 0.190626 0.4044211 0.0024410 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 7 44336 0.001726 0.191326 0.4020120 0.0023840 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 8 44337 0.000027 0.192127 0.3996249 0.0023860 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 9 44338 -0.001673 0.192827 0.3972197 0.0024460 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 10 44339 -0.003373 0.193627 0.3947126 0.0025660 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 11 44340 -0.005173 0.194427 0.3920625 0.0027390 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 12 44341 -0.006972 0.195228 0.3892234 0.0029260 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 13 44342 -0.008872 0.196128 0.3862142 0.0030770 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 14 44343 -0.010672 0.196928 0.3831091 0.0031370 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 15 44344 -0.012471 0.197729 0.3799870 0.0030970 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 16 44345 -0.014371 0.198629 0.3769469 0.0029810 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 17 44346 -0.016271 0.199529 0.3740427 0.0028050 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 18 44347 -0.018071 0.200329 0.3713256 0.0026300 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 19 44348 -0.019970 0.201230 0.3687575 0.0024960 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 20 44349 -0.021770 0.202130 0.3663044 0.0024220 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 21 44350 -0.023570 0.203130 0.3638942 0.0024070 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 22 44351 -0.025270 0.204030 0.3614641 0.0024510 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 23 44352 -0.027069 0.205031 0.3589800 0.0025180 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 24 44353 -0.028669 0.206031 0.3564309 0.0025820 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 25 44354 -0.030269 0.207031 0.3538157 0.0026490 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 26 44355 -0.031868 0.208032 0.3511376 0.0026950 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 27 44356 -0.033268 0.209132 0.3484235 0.0027210 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 28 44357 -0.034668 0.210232 0.3457044 0.0027010 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 29 44358 -0.035968 0.211332 0.3430293 0.0026320 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 4 30 44359 -0.037167 0.212433 0.3404381 0.0025570 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 1 44360 -0.038367 0.213633 0.3379320 0.0024610 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 2 44361 -0.039367 0.214833 0.3355279 0.0023570 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 3 44362 -0.040467 0.215933 0.3332068 0.0022810 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 4 44363 -0.041366 0.217134 0.3309556 0.0022350 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 5 44364 -0.042266 0.218234 0.3287305 0.0022230 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 6 44365 -0.043066 0.219334 0.3264904 0.0022760 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 7 44366 -0.043865 0.220535 0.3241703 0.0023740 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 8 44367 -0.044565 0.221635 0.3217271 0.0025160 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 9 44368 -0.045265 0.222735 0.3191210 0.0026980 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 10 44369 -0.046065 0.223835 0.3163369 0.0028530 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 11 44370 -0.046764 0.225036 0.3134248 0.0029580 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 12 44371 -0.047464 0.226036 0.3104507 0.0029720 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 13 44372 -0.048164 0.227136 0.3075135 0.0028870 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 14 44373 -0.048764 0.228236 0.3047014 0.0027290 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 15 44374 -0.049363 0.229337 0.3020653 0.0025520 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 16 44375 -0.049863 0.230437 0.2995992 0.0023940 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 17 44376 -0.050363 0.231437 0.2972680 0.0022770 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 18 44377 -0.050862 0.232538 0.2950249 0.0022110 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 19 44378 -0.051262 0.233538 0.2928178 0.0022100 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 20 44379 -0.051562 0.234638 0.2905937 0.0022360 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 21 44380 -0.051962 0.235638 0.2883276 0.0022950 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 22 44381 -0.052261 0.236639 0.2860004 0.0023600 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 23 44382 -0.052561 0.237639 0.2836203 0.0023990 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 24 44383 -0.052861 0.238639 0.2812102 0.0024000 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 25 44384 -0.053061 0.239639 0.2788181 0.0023760 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 26 44385 -0.053260 0.240640 0.2764659 0.0023150 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 27 44386 -0.053460 0.241640 0.2741968 0.0022280 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 28 44387 -0.053660 0.242640 0.2720267 0.0021190 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 29 44388 -0.053859 0.243741 0.2699636 0.0020080 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 30 44389 -0.054059 0.244741 0.2680115 0.0018970 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 5 31 44390 -0.054259 0.245741 0.2661613 0.0018080 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 1 44391 -0.054459 0.246741 0.2643932 0.0017580 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 2 44392 -0.054558 0.247742 0.2626371 0.0017620 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 3 44393 -0.054758 0.248842 0.2608490 0.0018210 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 4 44394 -0.054858 0.249842 0.2589699 0.0019320 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 5 44395 -0.054958 0.250842 0.2569677 0.0020720 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 6 44396 -0.055157 0.251843 0.2548296 0.0022020 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 7 44397 -0.055257 0.252743 0.2525695 0.0022990 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 8 44398 -0.055357 0.253743 0.2502544 0.0023370 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 9 44399 -0.055456 0.254744 0.2479223 0.0023230 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 10 44400 -0.055556 0.255644 0.2456431 0.0022250 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 11 44401 -0.055656 0.256644 0.2434860 0.0020730 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 12 44402 -0.055856 0.257644 0.2414869 0.0019300 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 13 44403 -0.055955 0.258545 0.2396238 0.0018110 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 14 44404 -0.055955 0.259545 0.2378437 0.0017490 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 15 44405 -0.056055 0.260545 0.2360965 0.0017540 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 16 44406 -0.056155 0.261645 0.2343224 0.0017930 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 17 44407 -0.056254 0.262646 0.2325023 0.0018480 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 18 44408 -0.056254 0.263746 0.2306232 0.0019130 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 19 44409 -0.056354 0.264846 0.2286781 0.0019650 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 20 44410 -0.056353 0.266047 0.2266979 0.0020010 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 21 44411 -0.056253 0.267147 0.2246928 0.0020040 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 22 44412 -0.056253 0.268347 0.2226997 0.0019790 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 23 44413 -0.056153 0.269547 0.2207436 0.0019280 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 24 44414 -0.055952 0.270848 0.2188595 0.0018570 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 25 44415 -0.055752 0.272048 0.2170443 0.0017620 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 26 44416 -0.055552 0.273348 0.2153262 0.0016640 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 27 44417 -0.055252 0.274648 0.2137101 0.0015800 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 28 44418 -0.054951 0.275949 0.2121650 0.0015180 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 29 44419 -0.054551 0.277349 0.2106569 0.0015070 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 6 30 44420 -0.054051 0.278649 0.2091317 0.0015540 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 1 44421 -0.053550 0.280050 0.2075326 0.0016500 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 2 44422 -0.053050 0.281350 0.2058245 0.0017780 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 3 44423 -0.052450 0.282750 0.2039804 0.0018950 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 4 44424 -0.051750 0.284050 0.2020393 0.0019760 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 5 44425 -0.051049 0.285351 0.2000492 0.0020010 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 6 44426 -0.050349 0.286551 0.1980640 0.0019510 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 7 44427 -0.049549 0.287851 0.1961599 0.0018460 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 8 44428 -0.048748 0.289052 0.1943838 0.0017090 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 9 44429 -0.047948 0.290252 0.1927437 0.0015730 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 10 44430 -0.047048 0.291452 0.1912296 0.0014500 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 11 44431 -0.046248 0.292552 0.1898264 0.0013770 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 12 44432 -0.045447 0.293653 0.1884583 0.0013600 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 13 44433 -0.044647 0.294653 0.1870792 0.0013920 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 14 44434 -0.043847 0.295753 0.1856631 0.0014550 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 15 44435 -0.043147 0.296853 0.1841650 0.0015320 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 16 44436 -0.042546 0.297854 0.1825999 0.0016070 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 17 44437 -0.041946 0.298954 0.1809647 0.0016690 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 18 44438 -0.041546 0.299954 0.1792796 0.0017090 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 19 44439 -0.041045 0.300955 0.1775665 0.0017110 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 20 44440 -0.040645 0.302055 0.1758584 0.0016950 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 21 44441 -0.040245 0.302955 0.1741753 0.0016570 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 22 44442 -0.039945 0.303955 0.1725482 0.0015960 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 23 44443 -0.039644 0.304856 0.1709830 0.0015420 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 24 44444 -0.039444 0.305756 0.1694679 0.0014880 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 25 44445 -0.039144 0.306656 0.1679888 0.0014680 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 26 44446 -0.038944 0.307456 0.1665267 0.0014830 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 27 44447 -0.038643 0.308257 0.1650136 0.0015460 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 28 44448 -0.038443 0.308957 0.1634065 0.0016690 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 29 44449 -0.038243 0.309657 0.1616533 0.0018190 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 30 44450 -0.038042 0.310258 0.1597562 0.0019680 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 7 31 44451 -0.037842 0.310958 0.1577421 0.0020620 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 1 44452 -0.037642 0.311558 0.1556700 0.0020680 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 2 44453 -0.037442 0.312058 0.1536259 0.0019970 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 3 44454 -0.037241 0.312659 0.1516898 0.0018630 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 4 44455 -0.037041 0.313159 0.1499126 0.0016860 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 5 44456 -0.036841 0.313759 0.1483125 0.0015190 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 6 44457 -0.036641 0.314259 0.1468674 0.0013760 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 7 44458 -0.036440 0.314860 0.1455553 0.0012890 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 8 44459 -0.036240 0.315460 0.1442792 0.0012690 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 9 44460 -0.036040 0.316060 0.1430091 0.0012910 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 10 44461 -0.035739 0.316661 0.1416760 0.0013610 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 11 44462 -0.035539 0.317361 0.1402698 0.0014500 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 12 44463 -0.035239 0.318061 0.1387757 0.0015490 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 13 44464 -0.034939 0.318761 0.1371856 0.0016370 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 14 44465 -0.034638 0.319462 0.1355185 0.0017030 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 15 44466 -0.034238 0.320262 0.1337874 0.0017520 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 16 44467 -0.033838 0.321162 0.1320323 0.0017620 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 17 44468 -0.033438 0.321962 0.1302701 0.0017470 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 18 44469 -0.033137 0.322863 0.1285440 0.0017150 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 19 44470 -0.032737 0.323663 0.1268409 0.0016890 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 20 44471 -0.032437 0.324563 0.1251718 0.0016620 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 21 44472 -0.032236 0.325364 0.1235007 0.0016660 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 22 44473 -0.032136 0.326164 0.1218276 0.0016970 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 23 44474 -0.031936 0.326964 0.1200975 0.0017710 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 24 44475 -0.031836 0.327764 0.1182533 0.0019090 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 25 44476 -0.031835 0.328465 0.1162522 0.0021020 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 26 44477 -0.031735 0.329165 0.1140391 0.0023090 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 27 44478 -0.031835 0.329765 0.1116410 0.0024800 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 28 44479 -0.031935 0.330265 0.1091049 0.0025760 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 29 44480 -0.032034 0.330866 0.1065238 0.0025690 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 30 44481 -0.032134 0.331366 0.1040107 0.0024530 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 8 31 44482 -0.032334 0.331766 0.1016295 0.0022910 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 1 44483 -0.032433 0.332267 0.0994354 0.0021080 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 2 44484 -0.032533 0.332667 0.0974073 0.0019460 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 3 44485 -0.032533 0.333067 0.0955172 0.0018440 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 4 44486 -0.032633 0.333467 0.0937001 0.0018020 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 5 44487 -0.032632 0.333868 0.0918830 0.0018290 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 6 44488 -0.032632 0.334368 0.0900159 0.0019100 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 7 44489 -0.032532 0.334768 0.0880538 0.0020170 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 8 44490 -0.032332 0.335168 0.0859906 0.0021200 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 9 44491 -0.032131 0.335569 0.0838155 0.0022140 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 10 44492 -0.031931 0.336069 0.0815584 0.0022970 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 11 44493 -0.031731 0.336469 0.0792403 0.0023440 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 12 44494 -0.031430 0.336870 0.0768822 0.0023700 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 13 44495 -0.031130 0.337270 0.0745191 0.0023590 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 14 44496 -0.030830 0.337770 0.0721720 0.0023150 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 15 44497 -0.030530 0.338170 0.0698829 0.0022630 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 16 44498 -0.030229 0.338571 0.0676547 0.0022050 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 17 44499 -0.029829 0.339071 0.0654636 0.0021680 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 18 44500 -0.029529 0.339471 0.0633165 0.0021440 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 19 44501 -0.029129 0.339871 0.0611604 0.0021680 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 20 44502 -0.028728 0.340372 0.0589613 0.0022400 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 21 44503 -0.028428 0.340772 0.0566482 0.0023750 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 22 44504 -0.028028 0.341172 0.0541871 0.0025560 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 23 44505 -0.027627 0.341573 0.0515240 0.0027540 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 24 44506 -0.027227 0.342073 0.0486928 0.0029050 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 25 44507 -0.026827 0.342473 0.0457547 0.0029710 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 26 44508 -0.026327 0.342973 0.0428006 0.0029190 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 27 44509 -0.025926 0.343474 0.0399405 0.0027780 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 28 44510 -0.025426 0.343974 0.0372624 0.0025820 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 29 44511 -0.024926 0.344474 0.0347853 0.0023880 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 9 30 44512 -0.024525 0.345075 0.0324722 0.0022380 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 1 44513 -0.024025 0.345675 0.0302861 0.0021440 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 2 44514 -0.023625 0.346275 0.0281620 0.0021250 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 3 44515 -0.023225 0.346875 0.0260268 0.0021500 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 4 44516 -0.022724 0.347576 0.0238407 0.0022080 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 5 44517 -0.022324 0.348176 0.0215976 0.0022890 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 6 44518 -0.021824 0.348876 0.0192635 0.0023670 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 7 44519 -0.021324 0.349676 0.0168594 0.0024380 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 8 44520 -0.020823 0.350377 0.0143953 0.0024820 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 9 44521 -0.020223 0.351177 0.0119042 0.0024960 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 10 44522 -0.019623 0.351977 0.0094141 0.0024810 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 11 44523 -0.019022 0.352678 0.0069510 0.0024400 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 12 44524 -0.018422 0.353478 0.0045499 0.0023830 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 13 44525 -0.017722 0.354278 0.0021967 0.0023240 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 14 44526 -0.017122 0.355078 -0.0001054 0.0022810 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 15 44527 -0.016421 0.355879 -0.0023645 0.0022480 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 16 44528 -0.015721 0.356579 -0.0046236 0.0022680 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 17 44529 -0.015021 0.357379 -0.0069107 0.0023330 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 18 44530 -0.014421 0.358079 -0.0093008 0.0024560 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 19 44531 -0.013720 0.358680 -0.0118519 0.0026440 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 20 44532 -0.013020 0.359280 -0.0145990 0.0028640 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 21 44533 -0.012420 0.359880 -0.0175661 0.0030720 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 22 44534 -0.011719 0.360481 -0.0207212 0.0032170 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 23 44535 -0.011019 0.360981 -0.0239754 0.0032570 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 24 44536 -0.010319 0.361481 -0.0271985 0.0031810 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 25 44537 -0.009619 0.361981 -0.0302976 0.0030070 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 26 44538 -0.008918 0.362382 -0.0331997 0.0027960 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 27 44539 -0.008218 0.362782 -0.0358988 0.0026070 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 28 44540 -0.007518 0.363182 -0.0384339 0.0024660 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 29 44541 -0.006818 0.363582 -0.0408540 0.0023960 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 30 44542 -0.006017 0.363983 -0.0432471 0.0023880 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 10 31 44543 -0.005317 0.364383 -0.0456562 0.0024230 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 1 44544 -0.004617 0.364683 -0.0481093 0.0024770 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 2 44545 -0.003916 0.365084 -0.0506104 0.0025240 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 3 44546 -0.003216 0.365384 -0.0531525 0.0025680 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 4 44547 -0.002416 0.365684 -0.0557397 0.0025790 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 5 44548 -0.001716 0.366084 -0.0583118 0.0025610 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 6 44549 -0.000915 0.366385 -0.0608529 0.0025130 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 7 44550 -0.000115 0.366785 -0.0633290 0.0024380 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 8 44551 0.000685 0.367185 -0.0657111 0.0023430 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 9 44552 0.001585 0.367585 -0.0680042 0.0022400 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 10 44553 0.002486 0.367986 -0.0701933 0.0021540 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 11 44554 0.003486 0.368386 -0.0723084 0.0020820 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 12 44555 0.004386 0.368786 -0.0743815 0.0020600 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 13 44556 0.005487 0.369187 -0.0764576 0.0020900 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 14 44557 0.006587 0.369587 -0.0785807 0.0021840 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 15 44558 0.007787 0.369987 -0.0808328 0.0023300 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 16 44559 0.008987 0.370387 -0.0832609 0.0025230 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 17 44560 0.010288 0.370688 -0.0858910 0.0027350 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 18 44561 0.011588 0.371088 -0.0887222 0.0029260 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 19 44562 0.012888 0.371488 -0.0917103 0.0030450 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 20 44563 0.014288 0.371788 -0.0947874 0.0030620 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 21 44564 0.015789 0.372089 -0.0978095 0.0029790 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 22 44565 0.017289 0.372389 -0.1007126 0.0028210 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 23 44566 0.018789 0.372589 -0.1034467 0.0026500 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 24 44567 0.020290 0.372890 -0.1060158 0.0024870 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 25 44568 0.021990 0.373090 -0.1084429 0.0023800 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 26 44569 0.023590 0.373290 -0.1107880 0.0023410 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 27 44570 0.025290 0.373390 -0.1131301 0.0023420 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 28 44571 0.026891 0.373591 -0.1154812 0.0023700 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 29 44572 0.028491 0.373691 -0.1178743 0.0024050 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 11 30 44573 0.030191 0.373791 -0.1202874 0.0024200 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 1 44574 0.031691 0.373891 -0.1227065 0.0024250 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 2 44575 0.033292 0.373992 -0.1251286 0.0024020 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 3 44576 0.034792 0.374092 -0.1275107 0.0023700 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 4 44577 0.036292 0.374192 -0.1298498 0.0023110 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 5 44578 0.037693 0.374193 -0.1321379 0.0022520 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 6 44579 0.038993 0.374293 -0.1343501 0.0021800 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 7 44580 0.040293 0.374193 -0.1364992 0.0021200 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 8 44581 0.041493 0.374193 -0.1385873 0.0020770 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 9 44582 0.042794 0.374094 -0.1406564 0.0020690 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 10 44583 0.043994 0.373994 -0.1427405 0.0021080 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 11 44584 0.045194 0.373794 -0.1448916 0.0022030 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 12 44585 0.046394 0.373494 -0.1471637 0.0023480 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 13 44586 0.047595 0.373095 -0.1495988 0.0025170 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 14 44587 0.048895 0.372795 -0.1522099 0.0027060 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 15 44588 0.050095 0.372295 -0.1549940 0.0028560 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 16 44589 0.051396 0.371796 -0.1579061 0.0029440 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 17 44590 0.052696 0.371196 -0.1608672 0.0029550 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 18 44591 0.054096 0.370596 -0.1637773 0.0028610 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 19 44592 0.055496 0.369896 -0.1665554 0.0026950 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 20 44593 0.056997 0.369197 -0.1691585 0.0024870 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 21 44594 0.058397 0.368397 -0.1715446 0.0023030 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 22 44595 0.059897 0.367497 -0.1737807 0.0021800 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 23 44596 0.061398 0.366698 -0.1759178 0.0021250 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 24 44597 0.062798 0.365798 -0.1780399 0.0021270 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 25 44598 0.064298 0.364798 -0.1801930 0.0021740 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 26 44599 0.065698 0.363798 -0.1823911 0.0022430 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 27 44600 0.067099 0.362899 -0.1846662 0.0023030 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 28 44601 0.068399 0.361899 -0.1869903 0.0023430 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 29 44602 0.069599 0.360999 -0.1893524 0.0023750 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 30 44603 0.070699 0.360099 -0.1917225 0.0023780 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1980 12 31 44604 0.071700 0.359200 -0.1941006 0.0023630 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 1 44605 0.072600 0.358400 -0.1964497 0.0023250 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 2 44606 0.073400 0.357600 -0.1987358 0.0022560 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 3 44607 0.074101 0.356901 -0.2009620 0.0021870 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 4 44608 0.074701 0.356301 -0.2031241 0.0021300 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 5 44609 0.075201 0.355701 -0.2052312 0.0020910 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 6 44610 0.075601 0.355101 -0.2073213 0.0020970 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 7 44611 0.076002 0.354602 -0.2094434 0.0021580 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 8 44612 0.076402 0.354102 -0.2116565 0.0022740 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 9 44613 0.076702 0.353602 -0.2140046 0.0024290 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 10 44614 0.076902 0.353102 -0.2165177 0.0025950 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 11 44615 0.077103 0.352603 -0.2191768 0.0027370 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 12 44616 0.077303 0.352103 -0.2219649 0.0028270 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 13 44617 0.077503 0.351603 -0.2248060 0.0028450 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 14 44618 0.077604 0.350904 -0.2276201 0.0027880 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 15 44619 0.077704 0.350304 -0.2303522 0.0026690 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 16 44620 0.077804 0.349504 -0.2329463 0.0025250 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 17 44621 0.077904 0.348804 -0.2353934 0.0023750 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 18 44622 0.078005 0.348005 -0.2377095 0.0022650 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 19 44623 0.078105 0.347105 -0.2399446 0.0022160 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 20 44624 0.078205 0.346205 -0.2421727 0.0022390 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 21 44625 0.078305 0.345305 -0.2444388 0.0022970 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 22 44626 0.078406 0.344306 -0.2467739 0.0023740 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 23 44627 0.078506 0.343406 -0.2491940 0.0024360 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 24 44628 0.078806 0.342306 -0.2516401 0.0024580 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 25 44629 0.079107 0.341307 -0.2540912 0.0024400 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 26 44630 0.079607 0.340207 -0.2565103 0.0023900 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 27 44631 0.080207 0.339207 -0.2588614 0.0023090 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 28 44632 0.080907 0.338107 -0.2611195 0.0021920 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 29 44633 0.081808 0.337008 -0.2632416 0.0020510 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 30 44634 0.082808 0.336008 -0.2652217 0.0019090 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 1 31 44635 0.083808 0.334908 -0.2670718 0.0018080 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 1 44636 0.084908 0.333908 -0.2688349 0.0017220 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 2 44637 0.086009 0.333009 -0.2705390 0.0016850 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 3 44638 0.087009 0.332109 -0.2722341 0.0017120 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 4 44639 0.088109 0.331309 -0.2739722 0.0018190 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 5 44640 0.089110 0.330510 -0.2758783 0.0020180 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 6 44641 0.090010 0.329710 -0.2780274 0.0022710 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 7 44642 0.090810 0.329010 -0.2804145 0.0024980 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 8 44643 0.091610 0.328410 -0.2830126 0.0026760 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 9 44644 0.092211 0.327711 -0.2857387 0.0027700 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 10 44645 0.092711 0.327111 -0.2885138 0.0027780 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 11 44646 0.093011 0.326511 -0.2912729 0.0027080 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 12 44647 0.093111 0.325911 -0.2939090 0.0025720 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 13 44648 0.093012 0.325212 -0.2964181 0.0024400 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 14 44649 0.092712 0.324512 -0.2988092 0.0023340 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 15 44650 0.092312 0.323812 -0.3011143 0.0022670 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 16 44651 0.091813 0.323113 -0.3033554 0.0022350 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 17 44652 0.091213 0.322313 -0.3056024 0.0022460 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 18 44653 0.090613 0.321513 -0.3078685 0.0022770 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 19 44654 0.089913 0.320613 -0.3101576 0.0022910 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 20 44655 0.089214 0.319714 -0.3124537 0.0022980 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 21 44656 0.088514 0.318814 -0.3147348 0.0022860 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 22 44657 0.087714 0.317914 -0.3170149 0.0022690 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 23 44658 0.086914 0.317114 -0.3192710 0.0022470 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 24 44659 0.086215 0.316215 -0.3214981 0.0022150 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 25 44660 0.085615 0.315415 -0.3236942 0.0022010 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 26 44661 0.085015 0.314715 -0.3258893 0.0021920 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 27 44662 0.084616 0.313916 -0.3280904 0.0022110 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 2 28 44663 0.084216 0.313316 -0.3303205 0.0022440 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 1 44664 0.084016 0.312616 -0.3325926 0.0023030 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 2 44665 0.083916 0.312016 -0.3349447 0.0023910 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 3 44666 0.083917 0.311417 -0.3374038 0.0025390 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 4 44667 0.084017 0.310917 -0.3400339 0.0027280 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 5 44668 0.084317 0.310317 -0.3428670 0.0029440 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 6 44669 0.084717 0.309817 -0.3459241 0.0031570 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 7 44670 0.085218 0.309218 -0.3491752 0.0033380 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 8 44671 0.085718 0.308618 -0.3525693 0.0034310 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 9 44672 0.086318 0.308018 -0.3560014 0.0034060 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 10 44673 0.086919 0.307319 -0.3593595 0.0032970 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 11 44674 0.087619 0.306719 -0.3625676 0.0031220 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 12 44675 0.088319 0.305919 -0.3656017 0.0029510 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 13 44676 0.089119 0.305219 -0.3684808 0.0027940 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 14 44677 0.089820 0.304420 -0.3712119 0.0026600 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 15 44678 0.090520 0.303620 -0.3738220 0.0025830 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 16 44679 0.091320 0.302720 -0.3763880 0.0025560 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 17 44680 0.092121 0.301921 -0.3789601 0.0025790 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 18 44681 0.092921 0.301021 -0.3815412 0.0026060 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 19 44682 0.093621 0.300221 -0.3841673 0.0026330 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 20 44683 0.094421 0.299321 -0.3867994 0.0026360 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 21 44684 0.095222 0.298522 -0.3894175 0.0026030 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 22 44685 0.096022 0.297722 -0.3919946 0.0025440 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 23 44686 0.096722 0.296922 -0.3945047 0.0024610 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 24 44687 0.097522 0.296122 -0.3969178 0.0023610 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 25 44688 0.098223 0.295323 -0.3992119 0.0022480 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 26 44689 0.098823 0.294523 -0.4014040 0.0021370 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 27 44690 0.099523 0.293723 -0.4035031 0.0020640 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 28 44691 0.100124 0.292924 -0.4055332 0.0020260 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 29 44692 0.100624 0.292124 -0.4075603 0.0020420 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 30 44693 0.101124 0.291324 -0.4096464 0.0021230 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 3 31 44694 0.101524 0.290424 -0.4118355 0.0022660 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 1 44695 0.101925 0.289525 -0.4142086 0.0024670 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 2 44696 0.102225 0.288625 -0.4167926 0.0027130 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 3 44697 0.102425 0.287625 -0.4196227 0.0029400 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 4 44698 0.102625 0.286525 -0.4226618 0.0031230 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 5 44699 0.102726 0.285526 -0.4258339 0.0032000 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 6 44700 0.102826 0.284326 -0.4290220 0.0031580 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 7 44701 0.102826 0.283126 -0.4321191 0.0030160 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 8 44702 0.102727 0.281927 -0.4350502 0.0028460 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 9 44703 0.102627 0.280727 -0.4378183 0.0026840 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 10 44704 0.102427 0.279427 -0.4404494 0.0025930 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 11 44705 0.102127 0.278227 -0.4430285 0.0025660 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 12 44706 0.101828 0.277028 -0.4455936 0.0025860 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 13 44707 0.101328 0.275828 -0.4482257 0.0026630 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 14 44708 0.100828 0.274628 -0.4509278 0.0027520 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 15 44709 0.100328 0.273528 -0.4537188 0.0028390 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 16 44710 0.099729 0.272429 -0.4565899 0.0028980 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 17 44711 0.099029 0.271429 -0.4595040 0.0029250 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 18 44712 0.098429 0.270429 -0.4624281 0.0029170 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 19 44713 0.097830 0.269630 -0.4653262 0.0028740 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 20 44714 0.097230 0.268730 -0.4681683 0.0027920 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 21 44715 0.096630 0.268030 -0.4709154 0.0027000 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 22 44716 0.096030 0.267330 -0.4735555 0.0025930 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 23 44717 0.095531 0.266631 -0.4760956 0.0024880 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 24 44718 0.095031 0.266031 -0.4785517 0.0024220 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 25 44719 0.094531 0.265431 -0.4809528 0.0023870 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 26 44720 0.094231 0.264931 -0.4833429 0.0024030 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 27 44721 0.093932 0.264332 -0.4857869 0.0024750 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 28 44722 0.093732 0.263732 -0.4883240 0.0026040 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 29 44723 0.093632 0.263032 -0.4910021 0.0027700 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 4 30 44724 0.093533 0.262433 -0.4938592 0.0029440 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 1 44725 0.093533 0.261833 -0.4968823 0.0030920 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 2 44726 0.093633 0.261133 -0.5000184 0.0031720 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 3 44727 0.093733 0.260433 -0.5031785 0.0031280 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 4 44728 0.093834 0.259734 -0.5062456 0.0029820 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 5 44729 0.093934 0.259034 -0.5091167 0.0027410 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 6 44730 0.094034 0.258334 -0.5117328 0.0025040 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 7 44731 0.094134 0.257634 -0.5141308 0.0023200 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 8 44732 0.094135 0.256935 -0.5163879 0.0022090 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 9 44733 0.094235 0.256135 -0.5185840 0.0021950 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 10 44734 0.094335 0.255435 -0.5207871 0.0022370 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 11 44735 0.094336 0.254736 -0.5230682 0.0023180 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 12 44736 0.094436 0.254036 -0.5254243 0.0023930 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 13 44737 0.094436 0.253236 -0.5278494 0.0024620 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 14 44738 0.094436 0.252536 -0.5303385 0.0025030 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 15 44739 0.094437 0.251737 -0.5328526 0.0025200 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 16 44740 0.094337 0.250937 -0.5353686 0.0024940 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 17 44741 0.094337 0.250137 -0.5378307 0.0024470 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 18 44742 0.094237 0.249337 -0.5402468 0.0023590 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 19 44743 0.094138 0.248438 -0.5425569 0.0022710 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 20 44744 0.093938 0.247538 -0.5447800 0.0021790 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 21 44745 0.093838 0.246738 -0.5469211 0.0020990 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 22 44746 0.093539 0.245839 -0.5490002 0.0020660 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 23 44747 0.093339 0.244839 -0.5510603 0.0020530 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 24 44748 0.092939 0.243939 -0.5531333 0.0020920 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 25 44749 0.092539 0.243039 -0.5552524 0.0021630 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 26 44750 0.091940 0.242040 -0.5574755 0.0022880 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 27 44751 0.091340 0.241140 -0.5598366 0.0024290 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 28 44752 0.090640 0.240140 -0.5623417 0.0025860 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 29 44753 0.089840 0.239240 -0.5649858 0.0026990 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 30 44754 0.089041 0.238241 -0.5677009 0.0027370 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 5 31 44755 0.088141 0.237341 -0.5704230 0.0026790 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 1 44756 0.087341 0.236441 -0.5730380 0.0025390 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 2 44757 0.086442 0.235542 -0.5754961 0.0023500 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 3 44758 0.085642 0.234642 -0.5777522 0.0021720 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 4 44759 0.084742 0.233742 -0.5798593 0.0020640 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 5 44760 0.083942 0.232942 -0.5819074 0.0020350 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 6 44761 0.083143 0.232243 -0.5839635 0.0020740 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 7 44762 0.082343 0.231443 -0.5860686 0.0021430 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 8 44763 0.081543 0.230743 -0.5882526 0.0022210 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 9 44764 0.080743 0.230043 -0.5905167 0.0022840 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 10 44765 0.080044 0.229444 -0.5928198 0.0023180 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 11 44766 0.079344 0.228744 -0.5951519 0.0023090 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 12 44767 0.078644 0.227944 -0.5974380 0.0022560 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 13 44768 0.077945 0.227245 -0.5996431 0.0021610 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 14 44769 0.077345 0.226445 -0.6017532 0.0020350 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 15 44770 0.076745 0.225645 -0.6037202 0.0018970 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 16 44771 0.076245 0.224745 -0.6055373 0.0017510 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 17 44772 0.075746 0.223946 -0.6072274 0.0016230 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 18 44773 0.075146 0.223046 -0.6087845 0.0014970 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 19 44774 0.074646 0.222146 -0.6102476 0.0014270 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 20 44775 0.074147 0.221247 -0.6116477 0.0013910 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 21 44776 0.073647 0.220247 -0.6130477 0.0014170 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 22 44777 0.073147 0.219347 -0.6144948 0.0014840 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 23 44778 0.072647 0.218447 -0.6160229 0.0015840 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 24 44779 0.072148 0.217548 -0.6176620 0.0016910 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 25 44780 0.071548 0.216548 -0.6193951 0.0017770 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 26 44781 0.070948 0.215648 -0.6211862 0.0018120 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 27 44782 0.070348 0.214748 -0.6229823 0.0017840 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 28 44783 0.069749 0.213749 -0.6247153 0.0016800 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 29 44784 0.069149 0.212849 -0.6263314 0.0015360 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 6 30 44785 0.068549 0.211849 -0.6277815 0.0013770 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 1 44786 0.068050 0.210950 0.3709024 0.0012550 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 2 44787 0.067450 0.209950 0.3696753 0.0012130 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 3 44788 0.066950 0.208950 0.3684492 0.0012480 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 4 44789 0.066350 0.207950 0.3671722 0.0013160 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 5 44790 0.065951 0.206851 0.3658111 0.0014040 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 6 44791 0.065451 0.205851 0.3643760 0.0014710 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 7 44792 0.065051 0.204851 0.3628899 0.0014970 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 8 44793 0.064651 0.203851 0.3613858 0.0014850 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 9 44794 0.064252 0.202752 0.3599317 0.0014160 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 10 44795 0.063952 0.201752 0.3585557 0.0013230 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 11 44796 0.063652 0.200852 0.3573046 0.0011860 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 12 44797 0.063353 0.199853 0.3561855 0.0010360 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 13 44798 0.063053 0.198953 0.3552214 0.0008970 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 14 44799 0.062653 0.198053 0.3543883 0.0007730 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 15 44800 0.062353 0.197153 0.3536653 0.0006980 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 16 44801 0.061854 0.196354 0.3529872 0.0006850 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 17 44802 0.061354 0.195654 0.3522871 0.0007350 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 18 44803 0.060754 0.194954 0.3514990 0.0008500 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 19 44804 0.060154 0.194354 0.3505609 0.0010320 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 20 44805 0.059355 0.193755 0.3494169 0.0012500 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 21 44806 0.058555 0.193155 0.3480738 0.0014530 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 22 44807 0.057555 0.192655 0.3465307 0.0016220 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 23 44808 0.056556 0.192156 0.3448506 0.0017300 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 24 44809 0.055456 0.191656 0.3430865 0.0017730 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 25 44810 0.054256 0.191156 0.3413274 0.0017340 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 26 44811 0.053056 0.190756 0.3396374 0.0016480 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 27 44812 0.051757 0.190257 0.3380493 0.0015310 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 28 44813 0.050357 0.189757 0.3365682 0.0014360 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 29 44814 0.048857 0.189257 0.3351461 0.0013980 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 30 44815 0.047357 0.188757 0.3337350 0.0014350 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 7 31 44816 0.045858 0.188258 0.3322650 0.0015160 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 1 44817 0.044258 0.187858 0.3306819 0.0016420 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 2 44818 0.042558 0.187358 0.3289818 0.0017480 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 3 44819 0.040959 0.186959 0.3271957 0.0018150 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 4 44820 0.039259 0.186559 0.3253746 0.0018310 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 5 44821 0.037559 0.186159 0.3235486 0.0018020 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 6 44822 0.035859 0.185759 0.3217815 0.0017350 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 7 44823 0.034160 0.185460 0.3200894 0.0016490 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 8 44824 0.032460 0.185160 0.3184913 0.0015350 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 9 44825 0.030760 0.184860 0.3170073 0.0014300 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 10 44826 0.029060 0.184660 0.3156152 0.0013390 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 11 44827 0.027361 0.184461 0.3143121 0.0012750 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 12 44828 0.025661 0.184261 0.3130530 0.0012500 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 13 44829 0.023961 0.184061 0.3118049 0.0012650 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 14 44830 0.022162 0.183962 0.3105049 0.0013570 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 15 44831 0.020462 0.183862 0.3090828 0.0014930 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 16 44832 0.018762 0.183762 0.3074947 0.0016580 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 17 44833 0.017162 0.183662 0.3057546 0.0018190 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 18 44834 0.015463 0.183663 0.3038655 0.0019380 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 19 44835 0.013763 0.183663 0.3018905 0.0019880 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 20 44836 0.012163 0.183763 0.2999194 0.0019430 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 21 44837 0.010563 0.183763 0.2980443 0.0018050 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 22 44838 0.008964 0.183964 0.2963272 0.0016210 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 23 44839 0.007464 0.184064 0.2948192 0.0014160 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 24 44840 0.005964 0.184364 0.2934981 0.0012400 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 25 44841 0.004465 0.184565 0.2923210 0.0011260 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 26 44842 0.003065 0.184965 0.2912219 0.0010930 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 27 44843 0.001665 0.185265 0.2901009 0.0011590 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 28 44844 0.000265 0.185765 0.2888868 0.0012830 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 29 44845 -0.001134 0.186166 0.2875397 0.0014010 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 30 44846 -0.002534 0.186666 0.2860806 0.0015100 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 8 31 44847 -0.003934 0.187266 0.2845315 0.0015800 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 1 44848 -0.005334 0.187766 0.2829375 0.0016010 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 2 44849 -0.006833 0.188267 0.2813454 0.0015770 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 3 44850 -0.008233 0.188767 0.2797853 0.0015260 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 4 44851 -0.009633 0.189267 0.2782902 0.0014620 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 5 44852 -0.011032 0.189768 0.2768742 0.0013800 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 6 44853 -0.012532 0.190168 0.2755251 0.0013080 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 7 44854 -0.013932 0.190668 0.2742400 0.0012710 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 8 44855 -0.015432 0.191168 0.2729709 0.0012630 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 9 44856 -0.016931 0.191669 0.2716869 0.0013120 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 10 44857 -0.018531 0.192169 0.2703278 0.0014160 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 11 44858 -0.020131 0.192669 0.2688447 0.0015770 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 12 44859 -0.021830 0.193170 0.2671566 0.0017890 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 13 44860 -0.023430 0.193770 0.2652476 0.0020380 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 14 44861 -0.025230 0.194270 0.2630935 0.0022750 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 15 44862 -0.026930 0.194970 0.2607284 0.0024410 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 16 44863 -0.028829 0.195571 0.2582333 0.0025220 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 17 44864 -0.030629 0.196271 0.2557193 0.0025000 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 18 44865 -0.032529 0.196971 0.2532692 0.0023870 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 19 44866 -0.034429 0.197671 0.2509461 0.0022480 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 20 44867 -0.036428 0.198472 0.2487681 0.0021130 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 21 44868 -0.038428 0.199272 0.2467020 0.0020310 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 22 44869 -0.040528 0.200072 0.2446799 0.0020220 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 23 44870 -0.042627 0.200973 0.2426318 0.0020770 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 24 44871 -0.044827 0.201873 0.2404988 0.0021960 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 25 44872 -0.047027 0.202773 0.2382307 0.0023220 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 26 44873 -0.049227 0.203773 0.2358466 0.0024430 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 27 44874 -0.051526 0.204774 0.2333645 0.0025130 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 28 44875 -0.053726 0.205774 0.2308345 0.0025460 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 29 44876 -0.056026 0.206774 0.2282874 0.0025210 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 9 30 44877 -0.058226 0.207774 0.2257983 0.0024540 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 1 44878 -0.060325 0.208775 0.2233912 0.0023450 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 2 44879 -0.062525 0.209775 0.2211122 0.0022200 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 3 44880 -0.064525 0.210775 0.2189581 0.0020980 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 4 44881 -0.066424 0.211876 0.2169090 0.0019960 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 5 44882 -0.068224 0.212876 0.2149570 0.0019290 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 6 44883 -0.069924 0.214076 0.2130449 0.0018990 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 7 44884 -0.071524 0.215176 0.2111408 0.0019220 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 8 44885 -0.072923 0.216377 0.2091727 0.0020100 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 9 44886 -0.074223 0.217677 0.2071107 0.0021430 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 10 44887 -0.075523 0.219077 0.2048716 0.0023390 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 11 44888 -0.076723 0.220477 0.2024175 0.0025590 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 12 44889 -0.077922 0.222078 0.1997645 0.0027480 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 13 44890 -0.078922 0.223678 0.1969584 0.0028560 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 14 44891 -0.080022 0.225378 0.1940903 0.0028530 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 15 44892 -0.081021 0.227179 0.1912802 0.0027510 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 16 44893 -0.082021 0.228979 0.1886202 0.0025680 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 17 44894 -0.083021 0.230779 0.1861451 0.0023840 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 18 44895 -0.084021 0.232579 0.1838380 0.0022330 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 19 44896 -0.085120 0.234480 0.1816550 0.0021580 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 20 44897 -0.086120 0.236380 0.1794949 0.0021640 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 21 44898 -0.087220 0.238180 0.1773048 0.0022240 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 22 44899 -0.088320 0.240080 0.1750348 0.0023190 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 23 44900 -0.089419 0.241881 0.1726657 0.0024170 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 24 44901 -0.090619 0.243581 0.1702096 0.0024930 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 25 44902 -0.091719 0.245381 0.1676935 0.0025300 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 26 44903 -0.092818 0.246982 0.1651635 0.0025220 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 27 44904 -0.094018 0.248682 0.1626644 0.0024690 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 28 44905 -0.095118 0.250282 0.1602363 0.0023810 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 29 44906 -0.096218 0.251782 0.1579193 0.0022610 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 30 44907 -0.097217 0.253283 0.1557162 0.0021440 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 10 31 44908 -0.098317 0.254783 0.1536271 0.0020300 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 1 44909 -0.099317 0.256283 0.1516481 0.0019440 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 2 44910 -0.100317 0.257683 0.1497240 0.0019030 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 3 44911 -0.101316 0.259184 0.1478149 0.0019130 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 4 44912 -0.102216 0.260584 0.1458689 0.0019860 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 5 44913 -0.103116 0.262084 0.1438348 0.0021020 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 6 44914 -0.104015 0.263485 0.1416597 0.0022640 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 7 44915 -0.104915 0.264985 0.1392857 0.0024760 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 8 44916 -0.105715 0.266485 0.1367176 0.0026760 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 9 44917 -0.106515 0.267885 0.1339585 0.0028310 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 10 44918 -0.107314 0.269386 0.1310884 0.0029040 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 11 44919 -0.108014 0.270986 0.1281994 0.0028620 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 12 44920 -0.108614 0.272486 0.1253863 0.0027310 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 13 44921 -0.109214 0.274186 0.1227442 0.0025390 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 14 44922 -0.109613 0.275787 0.1203042 0.0023400 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 15 44923 -0.110013 0.277587 0.1180411 0.0021970 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 16 44924 -0.110313 0.279387 0.1158810 0.0021410 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 17 44925 -0.110412 0.281288 0.1137360 0.0021510 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 18 44926 -0.110512 0.283188 0.1115749 0.0021850 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 19 44927 -0.110512 0.285188 0.1093618 0.0022380 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 20 44928 -0.110512 0.287188 0.1071038 0.0022630 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 21 44929 -0.110511 0.289189 0.1048367 0.0022630 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 22 44930 -0.110411 0.291289 0.1026026 0.0022200 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 23 44931 -0.110411 0.293489 0.1004216 0.0021350 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 24 44932 -0.110411 0.295689 0.0983335 0.0020260 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 25 44933 -0.110410 0.297790 0.0963784 0.0019110 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 26 44934 -0.110410 0.299990 0.0945144 0.0018160 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 27 44935 -0.110510 0.302190 0.0927343 0.0017360 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 28 44936 -0.110709 0.304391 0.0910253 0.0016780 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 29 44937 -0.110909 0.306491 0.0893652 0.0016580 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 11 30 44938 -0.111209 0.308691 0.0876931 0.0016860 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 1 44939 -0.111509 0.310791 0.0859661 0.0017780 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 2 44940 -0.111908 0.312892 0.0841310 0.0019100 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 3 44941 -0.112308 0.314992 0.0821399 0.0020760 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 4 44942 -0.112708 0.317092 0.0799779 0.0022620 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 5 44943 -0.113007 0.319193 0.0776138 0.0024580 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 6 44944 -0.113307 0.321393 0.0750677 0.0026350 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 7 44945 -0.113507 0.323593 0.0723737 0.0027530 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 8 44946 -0.113607 0.325793 0.0696036 0.0027690 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 9 44947 -0.113706 0.327994 0.0668695 0.0026930 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 10 44948 -0.113806 0.330194 0.0642535 0.0025310 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 11 44949 -0.113706 0.332394 0.0618164 0.0023460 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 12 44950 -0.113606 0.334694 0.0595474 0.0021990 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 13 44951 -0.113405 0.336895 0.0573893 0.0021330 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 14 44952 -0.113205 0.339195 0.0552522 0.0021530 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 15 44953 -0.112805 0.341395 0.0530722 0.0022340 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 16 44954 -0.112304 0.343596 0.0507881 0.0023240 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 17 44955 -0.111804 0.345796 0.0484200 0.0024070 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 18 44956 -0.111204 0.347996 0.0459990 0.0024300 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 19 44957 -0.110404 0.350196 0.0435649 0.0024180 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 20 44958 -0.109603 0.352297 0.0411758 0.0023630 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 21 44959 -0.108603 0.354497 0.0388608 0.0022730 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 22 44960 -0.107603 0.356597 0.0366377 0.0021590 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 23 44961 -0.106503 0.358697 0.0345467 0.0020330 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 24 44962 -0.105302 0.360798 0.0325716 0.0019190 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 25 44963 -0.104002 0.362798 0.0307005 0.0018140 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 26 44964 -0.102602 0.364898 0.0289205 0.0017520 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 27 44965 -0.101101 0.366899 0.0271834 0.0017250 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 28 44966 -0.099601 0.368999 0.0254454 0.0017600 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 29 44967 -0.098101 0.370999 0.0236553 0.0018460 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 30 44968 -0.096501 0.372999 0.0217482 0.0019660 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1981 12 31 44969 -0.094800 0.375000 0.0197032 0.0021240 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 1 44970 -0.093100 0.377000 0.0174851 0.0023000 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 2 44971 -0.091300 0.378900 0.0151090 0.0024500 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 3 44972 -0.089500 0.380800 0.0125990 0.0025690 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 4 44973 -0.087599 0.382701 0.0100039 0.0026090 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 5 44974 -0.085699 0.384501 0.0074079 0.0025670 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 6 44975 -0.083699 0.386301 0.0048848 0.0024590 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 7 44976 -0.081798 0.388102 0.0025047 0.0022990 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 8 44977 -0.079798 0.389802 0.0002927 0.0021310 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 9 44978 -0.077798 0.391402 -0.0017894 0.0020340 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 10 44979 -0.075798 0.393002 -0.0038054 0.0020230 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 11 44980 -0.073797 0.394503 -0.0058605 0.0020890 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 12 44981 -0.071897 0.396003 -0.0079956 0.0021930 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 13 44982 -0.069897 0.397403 -0.0102366 0.0022810 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 14 44983 -0.067897 0.398803 -0.0125537 0.0023380 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 15 44984 -0.065996 0.400204 -0.0148927 0.0023400 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 16 44985 -0.063996 0.401504 -0.0172048 0.0022790 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 17 44986 -0.062096 0.402804 -0.0194349 0.0021760 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 18 44987 -0.060295 0.404105 -0.0215359 0.0020350 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 19 44988 -0.058395 0.405405 -0.0235000 0.0018910 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 20 44989 -0.056595 0.406805 -0.0253210 0.0017490 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 21 44990 -0.054795 0.408205 -0.0269951 0.0016150 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 22 44991 -0.053094 0.409606 -0.0285601 0.0015130 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 23 44992 -0.051494 0.411006 -0.0300452 0.0014730 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 24 44993 -0.049794 0.412406 -0.0315143 0.0014850 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 25 44994 -0.048294 0.413906 -0.0330223 0.0015500 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 26 44995 -0.046693 0.415407 -0.0346314 0.0016740 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 27 44996 -0.045193 0.416907 -0.0363704 0.0018310 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 28 44997 -0.043793 0.418307 -0.0382935 0.0020050 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 29 44998 -0.042292 0.419808 -0.0403855 0.0021700 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 30 44999 -0.040892 0.421208 -0.0426286 0.0022890 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 1 31 45000 -0.039392 0.422608 -0.0449497 0.0023430 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 1 45001 -0.037892 0.423808 -0.0472897 0.0023240 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 2 45002 -0.036291 0.425009 -0.0495878 0.0022510 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 3 45003 -0.034691 0.426109 -0.0517778 0.0021260 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 4 45004 -0.032991 0.427209 -0.0538389 0.0019910 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 5 45005 -0.031191 0.428109 -0.0557749 0.0019000 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 6 45006 -0.029290 0.428910 -0.0576650 0.0018860 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 7 45007 -0.027390 0.429710 -0.0595651 0.0019460 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 8 45008 -0.025290 0.430410 -0.0615771 0.0020650 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 9 45009 -0.023189 0.431011 -0.0637102 0.0021990 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 10 45010 -0.020989 0.431511 -0.0659652 0.0023130 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 11 45011 -0.018789 0.432011 -0.0683183 0.0023700 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 12 45012 -0.016389 0.432511 -0.0706923 0.0023720 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 13 45013 -0.013988 0.433012 -0.0730324 0.0023190 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 14 45014 -0.011588 0.433512 -0.0753174 0.0022260 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 15 45015 -0.009088 0.434112 -0.0774895 0.0021240 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 16 45016 -0.006488 0.434612 -0.0795536 0.0020090 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 17 45017 -0.003887 0.435213 -0.0815226 0.0019110 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 18 45018 -0.001287 0.435713 -0.0833967 0.0018530 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 19 45019 0.001413 0.436413 -0.0852437 0.0018390 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 20 45020 0.004114 0.437014 -0.0871028 0.0018860 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 21 45021 0.006814 0.437714 -0.0890338 0.0019880 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 22 45022 0.009614 0.438314 -0.0910849 0.0021440 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 23 45023 0.012414 0.439014 -0.0933359 0.0023520 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 24 45024 0.015115 0.439715 -0.0957970 0.0025710 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 25 45025 0.017915 0.440415 -0.0984740 0.0027960 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 26 45026 0.020615 0.441115 -0.1013631 0.0029520 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 27 45027 0.023416 0.441716 -0.1043622 0.0030440 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 2 28 45028 0.026116 0.442316 -0.1074132 0.0030320 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 1 45029 0.028816 0.442816 -0.1103923 0.0028980 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 2 45030 0.031416 0.443316 -0.1132053 0.0026930 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 3 45031 0.034017 0.443617 -0.1157884 0.0024860 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 4 45032 0.036617 0.443817 -0.1181794 0.0023070 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 5 45033 0.039117 0.443817 -0.1204265 0.0021880 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 6 45034 0.041517 0.443817 -0.1225955 0.0021620 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 7 45035 0.043918 0.443618 -0.1247646 0.0022060 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 8 45036 0.046318 0.443318 -0.1270196 0.0022960 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 9 45037 0.048818 0.442918 -0.1293647 0.0023890 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 10 45038 0.051319 0.442419 -0.1317697 0.0024250 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 11 45039 0.053819 0.441819 -0.1341908 0.0024150 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 12 45040 0.056319 0.441119 -0.1365778 0.0023790 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 13 45041 0.058919 0.440419 -0.1389319 0.0023100 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 14 45042 0.061520 0.439620 -0.1411869 0.0022090 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 15 45043 0.064220 0.438820 -0.1433460 0.0020960 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 16 45044 0.066820 0.438120 -0.1453930 0.0019920 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 17 45045 0.069520 0.437320 -0.1473511 0.0019160 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 18 45046 0.072221 0.436521 -0.1492391 0.0018620 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 19 45047 0.074921 0.435821 -0.1510922 0.0018600 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 20 45048 0.077621 0.435121 -0.1529882 0.0019330 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 21 45049 0.080222 0.434422 -0.1549763 0.0020520 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 22 45050 0.082822 0.433922 -0.1571004 0.0022220 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 23 45051 0.085322 0.433322 -0.1594224 0.0024260 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 24 45052 0.087822 0.432922 -0.1619545 0.0026370 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 25 45053 0.090223 0.432423 -0.1646855 0.0028250 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 26 45054 0.092723 0.432023 -0.1675696 0.0029290 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 27 45055 0.095123 0.431723 -0.1705206 0.0029450 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 28 45056 0.097523 0.431323 -0.1734397 0.0028690 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 29 45057 0.099824 0.431024 -0.1762457 0.0027400 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 30 45058 0.102124 0.430624 -0.1789047 0.0025870 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 3 31 45059 0.104424 0.430224 -0.1814228 0.0024590 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 1 45060 0.106725 0.429825 -0.1838558 0.0024100 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 2 45061 0.108925 0.429325 -0.1862709 0.0024340 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 3 45062 0.111025 0.428825 -0.1887589 0.0025330 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 4 45063 0.113225 0.428225 -0.1913630 0.0026780 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 5 45064 0.115326 0.427626 -0.1941180 0.0028240 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 6 45065 0.117326 0.426926 -0.1970091 0.0029400 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 7 45066 0.119326 0.426126 -0.1999821 0.0030020 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 8 45067 0.121326 0.425226 -0.2029822 0.0029680 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 9 45068 0.123227 0.424327 -0.2059062 0.0028640 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 10 45069 0.125127 0.423327 -0.2086953 0.0027170 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 11 45070 0.126927 0.422227 -0.2113233 0.0025370 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 12 45071 0.128728 0.421028 -0.2137784 0.0023650 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 13 45072 0.130528 0.419828 -0.2160694 0.0022130 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 14 45073 0.132328 0.418628 -0.2182265 0.0021080 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 15 45074 0.134028 0.417328 -0.2203035 0.0020640 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 16 45075 0.135829 0.416029 -0.2223746 0.0020760 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 17 45076 0.137629 0.414729 -0.2244726 0.0021430 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 18 45077 0.139429 0.413329 -0.2266767 0.0022710 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 19 45078 0.141229 0.412029 -0.2290307 0.0024430 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 20 45079 0.143030 0.410630 -0.2315598 0.0026480 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 21 45080 0.144830 0.409230 -0.2343148 0.0028470 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 22 45081 0.146630 0.407730 -0.2372478 0.0030050 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 23 45082 0.148431 0.406231 -0.2402959 0.0030930 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 24 45083 0.150231 0.404731 -0.2433869 0.0030730 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 25 45084 0.152031 0.403231 -0.2464010 0.0029520 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 26 45085 0.153831 0.401631 -0.2492860 0.0027960 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 27 45086 0.155532 0.400032 -0.2520091 0.0026670 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 28 45087 0.157232 0.398332 -0.2546311 0.0025820 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 29 45088 0.158932 0.396632 -0.2572022 0.0025660 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 4 30 45089 0.160632 0.394932 -0.2597902 0.0026100 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 1 45090 0.162233 0.393133 -0.2624513 0.0026980 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 2 45091 0.163933 0.391433 -0.2652033 0.0028030 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 3 45092 0.165533 0.389533 -0.2680524 0.0028800 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 4 45093 0.167234 0.387634 -0.2709484 0.0029020 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 5 45094 0.168834 0.385734 -0.2738374 0.0028570 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 6 45095 0.170534 0.383734 -0.2766425 0.0027430 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 7 45096 0.172134 0.381734 -0.2793075 0.0025820 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 8 45097 0.173835 0.379735 -0.2817966 0.0023820 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 9 45098 0.175435 0.377535 -0.2840786 0.0021810 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 10 45099 0.177035 0.375435 -0.2861527 0.0019820 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 11 45100 0.178735 0.373235 -0.2880517 0.0018220 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 12 45101 0.180336 0.371036 -0.2898107 0.0017070 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 13 45102 0.181936 0.368736 -0.2914918 0.0016660 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 14 45103 0.183636 0.366436 -0.2931518 0.0016820 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 15 45104 0.185237 0.364137 -0.2948639 0.0017580 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 16 45105 0.186837 0.361737 -0.2966729 0.0018870 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 17 45106 0.188337 0.359337 -0.2986480 0.0020760 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 18 45107 0.189937 0.356937 -0.3008280 0.0022940 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 19 45108 0.191438 0.354438 -0.3032390 0.0025110 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 20 45109 0.192938 0.352038 -0.3058191 0.0026450 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 21 45110 0.194438 0.349538 -0.3084971 0.0026830 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 22 45111 0.195839 0.347039 -0.3111612 0.0026260 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 23 45112 0.197239 0.344539 -0.3137232 0.0024920 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 24 45113 0.198739 0.342039 -0.3161293 0.0023210 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 25 45114 0.200039 0.339439 -0.3183813 0.0021840 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 26 45115 0.201440 0.336940 -0.3205243 0.0021230 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 27 45116 0.202840 0.334440 -0.3226574 0.0021460 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 28 45117 0.204240 0.331840 -0.3248504 0.0022460 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 29 45118 0.205540 0.329340 -0.3271475 0.0023490 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 30 45119 0.206941 0.326741 -0.3295425 0.0024260 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 5 31 45120 0.208241 0.324141 -0.3319845 0.0024480 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 1 45121 0.209641 0.321541 -0.3344306 0.0024250 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 2 45122 0.211042 0.318842 -0.3368176 0.0023370 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 3 45123 0.212342 0.316142 -0.3390907 0.0022140 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 4 45124 0.213742 0.313342 -0.3412347 0.0020700 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 5 45125 0.215142 0.310642 -0.3432258 0.0019130 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 6 45126 0.216643 0.307743 -0.3450618 0.0017700 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 7 45127 0.218043 0.304943 -0.3467738 0.0016510 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 8 45128 0.219343 0.302043 -0.3483779 0.0015710 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 9 45129 0.220743 0.299143 -0.3499249 0.0015420 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 10 45130 0.222044 0.296244 -0.3514710 0.0015590 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 11 45131 0.223244 0.293344 -0.3530600 0.0016270 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 12 45132 0.224344 0.290444 -0.3547390 0.0017370 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 13 45133 0.225345 0.287545 -0.3565431 0.0018760 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 14 45134 0.226145 0.284645 -0.3584941 0.0020260 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 15 45135 0.226945 0.281745 -0.3605931 0.0021690 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 16 45136 0.227545 0.278945 -0.3628302 0.0022730 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 17 45137 0.228046 0.276046 -0.3651272 0.0023080 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 18 45138 0.228346 0.273246 -0.3674143 0.0022500 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 19 45139 0.228646 0.270546 -0.3696083 0.0021060 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 20 45140 0.228846 0.267746 -0.3716193 0.0019120 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 21 45141 0.228847 0.265047 -0.3734254 0.0017200 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 22 45142 0.228847 0.262447 -0.3750824 0.0016080 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 23 45143 0.228747 0.259747 -0.3766745 0.0015840 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 24 45144 0.228448 0.257148 -0.3782875 0.0016450 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 25 45145 0.228248 0.254548 -0.3799785 0.0017490 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 26 45146 0.227948 0.251948 -0.3817836 0.0018450 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 27 45147 0.227548 0.249348 -0.3836516 0.0018920 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 28 45148 0.227249 0.246649 -0.3855456 0.0018740 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 29 45149 0.226849 0.243949 -0.3873897 0.0017950 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 6 30 45150 0.226449 0.241249 -0.3891197 0.0016670 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 1 45151 0.225949 0.238549 0.6092862 0.0015200 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 2 45152 0.225550 0.235850 0.6078552 0.0013590 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 3 45153 0.225050 0.233050 0.6065772 0.0012130 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 4 45154 0.224450 0.230250 0.6054231 0.0010870 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 5 45155 0.223951 0.227451 0.6043801 0.0010070 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 6 45156 0.223351 0.224651 0.6033951 0.0009730 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 7 45157 0.222851 0.221751 0.6024070 0.0010040 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 8 45158 0.222151 0.218951 0.6013590 0.0010980 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 9 45159 0.221552 0.216052 0.6002040 0.0012270 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 10 45160 0.220852 0.213152 0.5988939 0.0013950 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 11 45161 0.220152 0.210252 0.5974219 0.0015620 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 12 45162 0.219452 0.207352 0.5957739 0.0017300 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 13 45163 0.218653 0.204553 0.5939718 0.0018560 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 14 45164 0.217753 0.201753 0.5920888 0.0019200 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 15 45165 0.216853 0.198953 0.5901657 0.0019020 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 16 45166 0.215854 0.196154 0.5882997 0.0018090 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 17 45167 0.214854 0.193354 0.5865787 0.0016370 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 18 45168 0.213754 0.190654 0.5850306 0.0014520 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 19 45169 0.212554 0.187954 0.5836596 0.0012990 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 20 45170 0.211355 0.185355 0.5824016 0.0012350 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 21 45171 0.210155 0.182655 0.5811485 0.0012780 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 22 45172 0.208855 0.180055 0.5798135 0.0013990 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 23 45173 0.207455 0.177555 0.5783565 0.0015230 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 24 45174 0.206056 0.174956 0.5767804 0.0016280 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 25 45175 0.204656 0.172456 0.5751354 0.0016490 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 26 45176 0.203256 0.169956 0.5735084 0.0016030 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 27 45177 0.201957 0.167457 0.5719503 0.0014940 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 28 45178 0.200557 0.164957 0.5705233 0.0013570 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 29 45179 0.199157 0.162557 0.5692423 0.0012140 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 30 45180 0.197857 0.160057 0.5681022 0.0010760 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 7 31 45181 0.196558 0.157658 0.5670832 0.0009590 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 1 45182 0.195258 0.155258 0.5661832 0.0008680 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 2 45183 0.193958 0.152958 0.5653301 0.0008330 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 3 45184 0.192658 0.150558 0.5644991 0.0008510 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 4 45185 0.191459 0.148259 0.5636211 0.0009130 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 5 45186 0.190259 0.145859 0.5626571 0.0010330 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 6 45187 0.188959 0.143559 0.5615440 0.0011880 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 7 45188 0.187560 0.141260 0.5602760 0.0013560 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 8 45189 0.186160 0.138860 0.5588250 0.0015230 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 9 45190 0.184760 0.136560 0.5572429 0.0016540 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 10 45191 0.183160 0.134260 0.5555469 0.0017310 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 11 45192 0.181561 0.131961 0.5538029 0.0017420 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 12 45193 0.179861 0.129661 0.5520848 0.0016870 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 13 45194 0.178061 0.127461 0.5504358 0.0015920 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 14 45195 0.176062 0.125162 0.5488978 0.0014760 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 15 45196 0.174062 0.122962 0.5474747 0.0013960 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 16 45197 0.171862 0.120762 0.5460817 0.0013850 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 17 45198 0.169662 0.118562 0.5446717 0.0014690 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 18 45199 0.167363 0.116463 0.5431137 0.0016490 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 19 45200 0.164963 0.114363 0.5413606 0.0018610 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 20 45201 0.162563 0.112363 0.5394086 0.0020470 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 21 45202 0.160063 0.110363 0.5372786 0.0021790 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 22 45203 0.157464 0.108464 0.5350695 0.0022230 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 23 45204 0.154864 0.106564 0.5328695 0.0021740 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 24 45205 0.152264 0.104764 0.5307505 0.0020570 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 25 45206 0.149565 0.103065 0.5287544 0.0019130 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 26 45207 0.146865 0.101365 0.5269144 0.0017780 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 27 45208 0.144065 0.099765 0.5251924 0.0016530 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 28 45209 0.141365 0.098165 0.5235974 0.0015640 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 29 45210 0.138466 0.096666 0.5220473 0.0015340 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 30 45211 0.135666 0.095166 0.5205013 0.0015680 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 8 31 45212 0.132766 0.093766 0.5188923 0.0016570 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 1 45213 0.129766 0.092366 0.5171682 0.0018080 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 2 45214 0.126867 0.090967 0.5152742 0.0020090 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 3 45215 0.123767 0.089667 0.5131522 0.0022340 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 4 45216 0.120767 0.088367 0.5107952 0.0024550 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 5 45217 0.117668 0.087068 0.5082631 0.0026230 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 6 45218 0.114568 0.085868 0.5055811 0.0027200 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 7 45219 0.111368 0.084568 0.5028391 0.0027420 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 8 45220 0.108168 0.083368 0.5001321 0.0026810 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 9 45221 0.104969 0.082169 0.4975060 0.0025260 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 10 45222 0.101769 0.081069 0.4950760 0.0023220 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 11 45223 0.098469 0.079869 0.4928540 0.0021300 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 12 45224 0.095169 0.078769 0.4908070 0.0019870 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 13 45225 0.091870 0.077670 0.4888509 0.0019400 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 14 45226 0.088570 0.076570 0.4868859 0.0020030 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 15 45227 0.085170 0.075570 0.4848339 0.0021370 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 16 45228 0.081771 0.074571 0.4826068 0.0023240 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 17 45229 0.078471 0.073571 0.4801988 0.0024810 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 18 45230 0.074971 0.072671 0.4776718 0.0025480 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 19 45231 0.071571 0.071871 0.4751238 0.0025330 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 20 45232 0.068172 0.071172 0.4726217 0.0024410 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 21 45233 0.064672 0.070472 0.4702487 0.0023010 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 22 45234 0.061172 0.069872 0.4680247 0.0021350 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 23 45235 0.057672 0.069372 0.4659637 0.0019900 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 24 45236 0.054173 0.068973 0.4640326 0.0018790 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 25 45237 0.050573 0.068573 0.4621996 0.0018060 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 26 45238 0.047073 0.068373 0.4604006 0.0018010 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 27 45239 0.043474 0.068274 0.4585796 0.0018430 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 28 45240 0.039874 0.068274 0.4566955 0.0019410 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 29 45241 0.036374 0.068274 0.4546815 0.0020930 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 9 30 45242 0.032774 0.068374 0.4524985 0.0022670 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 1 45243 0.029175 0.068575 0.4501445 0.0024520 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 2 45244 0.025575 0.068775 0.4476105 0.0026180 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 3 45245 0.021875 0.069075 0.4449244 0.0027310 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 4 45246 0.018275 0.069475 0.4421654 0.0027640 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 5 45247 0.014676 0.069876 0.4394264 0.0027070 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 6 45248 0.011076 0.070376 0.4367864 0.0025670 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 7 45249 0.007476 0.070876 0.4343163 0.0023820 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 8 45250 0.003877 0.071377 0.4320153 0.0022130 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 9 45251 0.000277 0.071977 0.4298693 0.0020910 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 10 45252 -0.003223 0.072577 0.4278053 0.0020540 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 11 45253 -0.006823 0.073177 0.4257223 0.0021060 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 12 45254 -0.010322 0.073778 0.4235612 0.0022260 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 13 45255 -0.013722 0.074478 0.4212602 0.0023770 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 14 45256 -0.017222 0.075078 0.4188222 0.0025000 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 15 45257 -0.020622 0.075778 0.4162802 0.0025740 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 16 45258 -0.023921 0.076479 0.4137041 0.0025750 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 17 45259 -0.027221 0.077079 0.4111691 0.0024920 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 18 45260 -0.030521 0.077779 0.4087511 0.0023460 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 19 45261 -0.033720 0.078480 0.4064881 0.0021660 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 20 45262 -0.036920 0.079180 0.4044101 0.0019930 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 21 45263 -0.040020 0.079880 0.4024940 0.0018630 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 22 45264 -0.043120 0.080680 0.4006790 0.0017760 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 23 45265 -0.046219 0.081381 0.3989230 0.0017450 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 24 45266 -0.049319 0.082181 0.3971590 0.0017850 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 25 45267 -0.052319 0.082981 0.3953340 0.0018830 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 26 45268 -0.055319 0.083781 0.3933879 0.0020200 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 27 45269 -0.058318 0.084682 0.3912819 0.0021830 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 28 45270 -0.061218 0.085582 0.3890029 0.0023580 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 29 45271 -0.064218 0.086482 0.3865669 0.0025110 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 30 45272 -0.067217 0.087583 0.3839829 0.0026420 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 10 31 45273 -0.070217 0.088683 0.3812958 0.0027160 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 1 45274 -0.073317 0.089983 0.3785808 0.0026880 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 2 45275 -0.076317 0.091283 0.3759418 0.0025760 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 3 45276 -0.079416 0.092684 0.3734498 0.0024220 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 4 45277 -0.082516 0.094084 0.3711118 0.0022570 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 5 45278 -0.085716 0.095684 0.3689187 0.0021490 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 6 45279 -0.088815 0.097385 0.3667837 0.0021280 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 7 45280 -0.092015 0.099085 0.3646217 0.0022010 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 8 45281 -0.095115 0.100885 0.3623557 0.0023390 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 9 45282 -0.098215 0.102785 0.3599317 0.0025130 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 10 45283 -0.101314 0.104686 0.3573327 0.0026800 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 11 45284 -0.104314 0.106686 0.3545966 0.0027920 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 12 45285 -0.107214 0.108786 0.3517816 0.0028240 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 13 45286 -0.110014 0.110886 0.3489726 0.0027910 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 14 45287 -0.112813 0.113087 0.3462226 0.0026820 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 15 45288 -0.115613 0.115387 0.3436156 0.0025300 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 16 45289 -0.118313 0.117587 0.3411785 0.0023620 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 17 45290 -0.121012 0.119888 0.3388955 0.0022060 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 18 45291 -0.123712 0.122188 0.3367545 0.0020830 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 19 45292 -0.126312 0.124488 0.3347235 0.0020090 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 20 45293 -0.129012 0.126888 0.3327175 0.0020040 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 21 45294 -0.131711 0.129189 0.3306955 0.0020480 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 22 45295 -0.134411 0.131489 0.3286035 0.0021450 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 23 45296 -0.137111 0.133789 0.3263914 0.0022820 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 24 45297 -0.139811 0.136089 0.3240304 0.0024440 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 25 45298 -0.142510 0.138390 0.3215004 0.0026130 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 26 45299 -0.145210 0.140690 0.3188184 0.0027580 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 27 45300 -0.147910 0.143090 0.3159994 0.0028710 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 28 45301 -0.150609 0.145391 0.3130994 0.0029100 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 29 45302 -0.153209 0.147791 0.3102203 0.0028460 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 11 30 45303 -0.155909 0.150191 0.3074373 0.0027080 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 1 45304 -0.158509 0.152691 0.3048183 0.0025270 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 2 45305 -0.161008 0.155192 0.3023773 0.0023640 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 3 45306 -0.163508 0.157792 0.3000533 0.0022760 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 4 45307 -0.166008 0.160592 0.2977793 0.0023000 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 5 45308 -0.168308 0.163492 0.2954343 0.0024030 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 6 45309 -0.170607 0.166593 0.2929492 0.0025640 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 7 45310 -0.172807 0.169793 0.2903172 0.0027120 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 8 45311 -0.174907 0.173193 0.2875402 0.0028240 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 9 45312 -0.177006 0.176694 0.2846932 0.0028570 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 10 45313 -0.179006 0.180194 0.2818502 0.0028270 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 11 45314 -0.180906 0.183894 0.2790682 0.0027270 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 12 45315 -0.182806 0.187694 0.2764102 0.0025940 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 13 45316 -0.184505 0.191595 0.2738961 0.0024340 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 14 45317 -0.186205 0.195595 0.2715421 0.0022880 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 15 45318 -0.187805 0.199595 0.2693201 0.0021590 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 16 45319 -0.189305 0.203595 0.2672101 0.0020710 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 17 45320 -0.190804 0.207596 0.2651621 0.0020370 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 18 45321 -0.192104 0.211696 0.2631171 0.0020600 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 19 45322 -0.193304 0.215696 0.2610111 0.0021380 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 20 45323 -0.194503 0.219697 0.2588171 0.0022590 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 21 45324 -0.195603 0.223597 0.2564851 0.0024050 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 22 45325 -0.196503 0.227397 0.2539940 0.0025610 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 23 45326 -0.197403 0.230997 0.2513570 0.0027080 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 24 45327 -0.198202 0.234598 0.2485770 0.0028380 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 25 45328 -0.198902 0.237998 0.2457090 0.0029060 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 26 45329 -0.199502 0.241398 0.2428000 0.0029010 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 27 45330 -0.200102 0.244498 0.2399350 0.0028140 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 28 45331 -0.200701 0.247599 0.2371910 0.0026660 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 29 45332 -0.201301 0.250599 0.2346080 0.0025030 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 30 45333 -0.201801 0.253399 0.2321700 0.0023890 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1982 12 31 45334 -0.202300 0.256100 0.2298089 0.0023600 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 1 45335 -0.202900 0.258900 0.2274139 0.0024463 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 2 45336 -0.203600 0.261700 0.2248920 0.0026048 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 3 45337 -0.204300 0.264600 0.2221998 0.0027665 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 4 45338 -0.204999 0.267501 0.2193742 0.0028935 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 5 45339 -0.205799 0.270501 0.2164497 0.0029306 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 6 45340 -0.206699 0.273501 0.2135318 0.0028918 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 7 45341 -0.207499 0.276701 0.2106995 0.0027831 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 8 45342 -0.208298 0.279902 0.2079900 0.0026310 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 9 45343 -0.208998 0.283102 0.2054331 0.0024722 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 10 45344 -0.209598 0.286502 0.2030334 0.0023300 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 11 45345 -0.210097 0.289903 0.2007747 0.0022029 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 12 45346 -0.210597 0.293403 0.1986043 0.0021456 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 13 45347 -0.210897 0.296903 0.1964667 0.0021487 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 14 45348 -0.210997 0.300603 0.1942883 0.0022175 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 15 45349 -0.210996 0.304304 0.1920135 0.0023408 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 16 45350 -0.210896 0.308004 0.1895914 0.0025097 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 17 45351 -0.210696 0.311804 0.1869842 0.0027080 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 18 45352 -0.210296 0.315604 0.1841722 0.0029159 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 19 45353 -0.209695 0.319405 0.1811458 0.0031036 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 20 45354 -0.209095 0.323305 0.1779643 0.0032536 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 21 45355 -0.208295 0.327205 0.1746630 0.0033404 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 22 45356 -0.207494 0.331106 0.1712927 0.0033797 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 23 45357 -0.206594 0.334906 0.1679259 0.0033529 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 24 45358 -0.205594 0.338706 0.1646172 0.0032463 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 25 45359 -0.204594 0.342506 0.1614335 0.0031099 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 26 45360 -0.203493 0.346207 0.1583904 0.0029847 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 27 45361 -0.202393 0.349907 0.1554486 0.0029252 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 28 45362 -0.201193 0.353607 0.1525037 0.0029729 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 29 45363 -0.199893 0.357307 0.1494700 0.0031174 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 30 45364 -0.198692 0.360908 0.1462532 0.0033080 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 1 31 45365 -0.197392 0.364508 0.1428617 0.0034757 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 1 45366 -0.195992 0.368108 0.1393290 0.0035632 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 2 45367 -0.194691 0.371609 0.1357705 0.0035361 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 3 45368 -0.193491 0.375109 0.1322885 0.0034244 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 4 45369 -0.192011 0.378489 0.1289596 0.0032312 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 5 45370 -0.190281 0.381799 0.1258336 0.0030265 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 6 45371 -0.188530 0.385050 0.1229055 0.0028417 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 7 45372 -0.187210 0.388300 0.1201407 0.0027138 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 8 45373 -0.186400 0.391610 0.1175005 0.0025797 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 9 45374 -0.185839 0.394781 0.1149700 0.0024856 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 10 45375 -0.185199 0.397891 0.1125113 0.0024393 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 11 45376 -0.184289 0.401061 0.1100726 0.0024479 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 12 45377 -0.183029 0.404401 0.1075981 0.0025093 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 13 45378 -0.181618 0.407942 0.1050423 0.0026086 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 14 45379 -0.180218 0.411662 0.1023750 0.0027277 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 15 45380 -0.178908 0.415442 0.0995907 0.0028415 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 16 45381 -0.177608 0.419162 0.0967034 0.0029353 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 17 45382 -0.176317 0.422683 0.0937352 0.0030028 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 18 45383 -0.175067 0.426003 0.0907174 0.0030316 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 19 45384 -0.173927 0.429183 0.0876923 0.0030148 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 20 45385 -0.172916 0.432374 0.0847063 0.0029469 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 21 45386 -0.171886 0.435494 0.0818097 0.0028472 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 22 45387 -0.170716 0.438474 0.0790093 0.0027589 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 23 45388 -0.169096 0.441194 0.0762733 0.0027231 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 24 45389 -0.166965 0.443665 0.0735310 0.0027793 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 25 45390 -0.164705 0.446165 0.0706779 0.0029386 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 26 45391 -0.162465 0.449105 0.0676288 0.0031680 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 27 45392 -0.160365 0.452315 0.0643376 0.0034109 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 2 28 45393 -0.158474 0.455496 0.0608254 0.0035992 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 1 45394 -0.156974 0.458516 0.0571754 0.0036714 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 2 45395 -0.155894 0.461536 0.0535217 0.0036007 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 3 45396 -0.155253 0.464737 0.0500042 0.0034090 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 4 45397 -0.154953 0.468177 0.0467206 0.0031565 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 5 45398 -0.154413 0.471767 0.0436929 0.0029006 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 6 45399 -0.153143 0.475227 0.0409113 0.0026697 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 7 45400 -0.150992 0.478398 0.0383385 0.0024904 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 8 45401 -0.148142 0.481308 0.0359107 0.0023821 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 9 45402 -0.144642 0.483888 0.0335549 0.0023546 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 10 45403 -0.141102 0.486308 0.0311825 0.0024068 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 11 45404 -0.137931 0.488659 0.0287226 0.0025209 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 12 45405 -0.135201 0.491139 0.0261271 0.0026786 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 13 45406 -0.132881 0.493769 0.0233586 0.0028554 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 14 45407 -0.130630 0.496500 0.0204153 0.0030244 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 15 45408 -0.128350 0.499230 0.0173195 0.0031627 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 16 45409 -0.125910 0.501930 0.0141076 0.0032470 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 17 45410 -0.123120 0.504490 0.0108470 0.0032622 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 18 45411 -0.120009 0.506961 0.0076067 0.0031972 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 19 45412 -0.116689 0.509381 0.0044712 0.0030711 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 20 45413 -0.113149 0.511721 0.0014743 0.0029183 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 21 45414 -0.109469 0.514031 -0.0013681 0.0027737 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 22 45415 -0.105658 0.516402 -0.0040875 0.0026802 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 23 45416 -0.101798 0.518912 -0.0067561 0.0026729 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 24 45417 -0.097968 0.521572 -0.0094672 0.0027641 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 25 45418 -0.094207 0.524353 -0.0123155 0.0029438 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 26 45419 -0.090457 0.527233 -0.0153706 0.0031681 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 27 45420 -0.086567 0.530053 -0.0186451 0.0033697 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 28 45421 -0.082337 0.532673 -0.0220837 0.0034975 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 29 45422 -0.077866 0.534994 -0.0256019 0.0035220 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 30 45423 -0.073246 0.536874 -0.0290900 0.0034385 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 3 31 45424 -0.068696 0.538134 -0.0324519 0.0032737 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 1 45425 -0.064226 0.539034 -0.0356268 0.0030732 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 2 45426 -0.059975 0.540355 -0.0385999 0.0028764 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 3 45427 -0.055945 0.542105 -0.0413914 0.0027088 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 4 45428 -0.052045 0.544015 -0.0440363 0.0025902 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 5 45429 -0.048214 0.546036 -0.0465923 0.0025317 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 6 45430 -0.044434 0.548066 -0.0491202 0.0025306 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 7 45431 -0.040674 0.549966 -0.0516738 0.0025784 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 8 45432 -0.036764 0.551656 -0.0542924 0.0026533 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 9 45433 -0.032673 0.552987 -0.0569893 0.0027479 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 10 45434 -0.028333 0.554047 -0.0597917 0.0028638 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 11 45435 -0.023623 0.554877 -0.0627125 0.0029743 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 12 45436 -0.018503 0.555547 -0.0657270 0.0030608 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 13 45437 -0.013272 0.556238 -0.0688113 0.0031033 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 14 45438 -0.008162 0.557018 -0.0719069 0.0030764 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 15 45439 -0.003242 0.557868 -0.0749399 0.0029779 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 16 45440 0.001369 0.558809 -0.0778466 0.0028367 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 17 45441 0.005649 0.559769 -0.0806106 0.0026962 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 18 45442 0.009589 0.560539 -0.0832528 0.0025837 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 19 45443 0.013229 0.561069 -0.0858050 0.0025208 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 20 45444 0.016670 0.561290 -0.0883266 0.0025315 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 21 45445 0.020150 0.561220 -0.0908989 0.0026280 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 22 45446 0.023750 0.560910 -0.0936029 0.0027829 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 23 45447 0.027640 0.560570 -0.0964682 0.0029463 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 24 45448 0.031801 0.560291 -0.0994786 0.0030672 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 25 45449 0.036011 0.559991 -0.1025721 0.0031065 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 26 45450 0.040231 0.559661 -0.1056543 0.0030512 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 27 45451 0.044362 0.559392 -0.1086421 0.0029082 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 28 45452 0.048262 0.559182 -0.1114512 0.0026951 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 29 45453 0.052082 0.558962 -0.1140275 0.0024445 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 4 30 45454 0.055932 0.558792 -0.1163480 0.0022149 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 1 45455 0.059723 0.558613 -0.1184737 0.0020511 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 2 45456 0.063483 0.558413 -0.1204711 0.0019628 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 3 45457 0.067173 0.558073 -0.1224207 0.0019583 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 4 45458 0.070714 0.557554 -0.1244086 0.0020103 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 5 45459 0.074124 0.556904 -0.1264583 0.0020884 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 6 45460 0.077494 0.556104 -0.1285981 0.0022016 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 7 45461 0.080834 0.555144 -0.1308660 0.0023403 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 8 45462 0.084365 0.554225 -0.1332768 0.0024890 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 9 45463 0.088285 0.553445 -0.1358366 0.0026293 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 10 45464 0.092535 0.552685 -0.1385196 0.0027322 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 11 45465 0.097075 0.551955 -0.1412763 0.0027786 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 12 45466 0.101556 0.551046 -0.1440478 0.0027480 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 13 45467 0.105996 0.549976 -0.1467500 0.0026396 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 14 45468 0.110396 0.548896 -0.1493171 0.0024932 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 15 45469 0.114747 0.547907 -0.1517448 0.0023597 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 16 45470 0.119037 0.546907 -0.1540603 0.0022797 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 17 45471 0.123267 0.545927 -0.1563364 0.0022734 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 18 45472 0.127387 0.545037 -0.1586395 0.0023433 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 19 45473 0.131498 0.544218 -0.1610444 0.0024749 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 20 45474 0.135688 0.543378 -0.1635937 0.0026168 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 21 45475 0.140008 0.542298 -0.1662661 0.0027254 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 22 45476 0.144378 0.540928 -0.1690196 0.0027742 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 23 45477 0.148809 0.539329 -0.1717842 0.0027462 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 24 45478 0.153249 0.537449 -0.1744822 0.0026483 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 25 45479 0.157549 0.535199 -0.1770601 0.0024834 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 26 45480 0.161710 0.532770 -0.1794382 0.0022663 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 27 45481 0.165730 0.530200 -0.1815952 0.0020547 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 28 45482 0.169640 0.527600 -0.1835600 0.0018881 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 29 45483 0.173250 0.525260 -0.1853901 0.0017825 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 30 45484 0.176631 0.523041 -0.1871457 0.0017367 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 5 31 45485 0.179901 0.520811 -0.1888850 0.0017562 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 1 45486 0.183151 0.518481 -0.1906756 0.0018391 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 2 45487 0.186571 0.515911 -0.1925776 0.0019650 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 3 45488 0.189962 0.513212 -0.1946124 0.0021005 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 4 45489 0.193262 0.510282 -0.1967801 0.0022276 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 5 45490 0.196442 0.507142 -0.1990622 0.0023382 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 6 45491 0.199323 0.503963 -0.2014437 0.0024212 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 7 45492 0.201803 0.500843 -0.2038866 0.0024535 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 8 45493 0.203753 0.497873 -0.2063268 0.0024205 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 9 45494 0.205573 0.494933 -0.2087029 0.0023220 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 10 45495 0.207534 0.491944 -0.2109519 0.0021748 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 11 45496 0.209904 0.488734 -0.2130523 0.0020225 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 12 45497 0.212724 0.485454 -0.2150155 0.0019149 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 13 45498 0.215994 0.482224 -0.2169154 0.0019022 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 14 45499 0.219655 0.479175 -0.2188550 0.0019873 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 15 45500 0.223475 0.476435 -0.2209165 0.0021373 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 16 45501 0.227245 0.473995 -0.2231365 0.0023014 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 17 45502 0.230716 0.471776 -0.2255070 0.0024257 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 18 45503 0.233946 0.469556 -0.2279622 0.0024718 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 19 45504 0.236956 0.467116 -0.2304195 0.0024277 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 20 45505 0.239676 0.464156 -0.2327899 0.0023014 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 21 45506 0.242327 0.460927 -0.2350016 0.0021152 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 22 45507 0.245017 0.457487 -0.2370091 0.0018954 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 23 45508 0.247827 0.454067 -0.2387940 0.0016741 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 24 45509 0.250617 0.450737 -0.2403662 0.0014800 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 25 45510 0.253158 0.447708 -0.2417704 0.0013387 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 26 45511 0.255388 0.444878 -0.2430647 0.0012585 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 27 45512 0.257458 0.442008 -0.2443083 0.0012370 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 28 45513 0.259469 0.438959 -0.2455579 0.0012679 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 29 45514 0.261489 0.435499 -0.2468588 0.0013250 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 6 30 45515 0.263519 0.431689 -0.2482162 0.0013972 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 1 45516 0.265649 0.427599 0.7503454 0.0015088 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 2 45517 0.268170 0.423320 0.7487712 0.0016268 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 3 45518 0.270870 0.418880 0.7471018 0.0017049 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 4 45519 0.273660 0.414320 0.7453772 0.0017328 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 5 45520 0.276420 0.409700 0.7436557 0.0016983 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 6 45521 0.279041 0.405131 0.7420043 0.0016014 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 7 45522 0.281201 0.400701 0.7404733 0.0014495 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 8 45523 0.283151 0.396391 0.7391148 0.0012672 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 9 45524 0.284942 0.392272 0.7379310 0.0011089 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 10 45525 0.286612 0.388322 0.7368699 0.0010230 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 11 45526 0.288122 0.384632 0.7358474 0.0010512 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 12 45527 0.289592 0.381072 0.7347332 0.0011916 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 13 45528 0.291043 0.377643 0.7334473 0.0013944 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 14 45529 0.292673 0.374213 0.7319515 0.0015948 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 15 45530 0.294493 0.370693 0.7302855 0.0017361 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 16 45531 0.296613 0.366993 0.7285160 0.0017935 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 17 45532 0.299034 0.363084 0.7267334 0.0017511 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 18 45533 0.301554 0.359084 0.7250372 0.0016297 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 19 45534 0.304054 0.355034 0.7234833 0.0014820 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 20 45535 0.306465 0.350995 0.7220719 0.0013290 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 21 45536 0.308595 0.347145 0.7208153 0.0011842 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 22 45537 0.310385 0.343535 0.7196876 0.0010643 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 23 45538 0.311875 0.340065 0.7186684 0.0009912 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 24 45539 0.313186 0.336686 0.7176849 0.0009849 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 25 45540 0.314306 0.333246 0.7166795 0.0010368 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 26 45541 0.315306 0.329636 0.7155956 0.0011406 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 27 45542 0.316267 0.325927 0.7143883 0.0012752 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 28 45543 0.317297 0.322167 0.7130414 0.0014162 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 29 45544 0.318567 0.318377 0.7115604 0.0015520 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 30 45545 0.319827 0.314447 0.7099479 0.0016728 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 7 31 45546 0.320758 0.310288 0.7082291 0.0017607 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 1 45547 0.321328 0.305978 0.7064435 0.0018026 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 2 45548 0.321758 0.301518 0.7046435 0.0017910 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 3 45549 0.322178 0.296928 0.7028792 0.0017217 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 4 45550 0.322719 0.292279 0.7012119 0.0015979 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 5 45551 0.323309 0.287649 0.6996820 0.0014628 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 6 45552 0.323839 0.282949 0.6982671 0.0013792 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 7 45553 0.324180 0.278100 0.6968878 0.0013961 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 8 45554 0.324340 0.273330 0.6954366 0.0015274 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 9 45555 0.324420 0.268750 0.6938059 0.0017397 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 10 45556 0.324360 0.264660 0.6919539 0.0019675 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 11 45557 0.324221 0.260841 0.6898931 0.0021457 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 12 45558 0.324051 0.257041 0.6877026 0.0022254 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 13 45559 0.324211 0.252681 0.6854847 0.0021816 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 14 45560 0.324291 0.248211 0.6833738 0.0020255 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 15 45561 0.324102 0.243822 0.6814504 0.0018153 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 16 45562 0.323472 0.239732 0.6797436 0.0016125 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 17 45563 0.322362 0.235962 0.6782142 0.0014451 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 18 45564 0.321243 0.232153 0.6768354 0.0013074 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 19 45565 0.320303 0.228003 0.6755786 0.0012288 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 20 45566 0.319383 0.223513 0.6743567 0.0012274 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 21 45567 0.318263 0.218703 0.6731052 0.0012867 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 22 45568 0.316754 0.213604 0.6717679 0.0013970 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 23 45569 0.315344 0.208574 0.6703001 0.0015329 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 24 45570 0.314344 0.203934 0.6686976 0.0016685 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 25 45571 0.314014 0.199944 0.6669660 0.0017942 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 26 45572 0.313665 0.196155 0.6651203 0.0018895 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 27 45573 0.312835 0.192315 0.6632026 0.0019403 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 28 45574 0.311275 0.188305 0.6612571 0.0019472 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 29 45575 0.309266 0.184216 0.6593256 0.0019091 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 30 45576 0.306896 0.179966 0.6574539 0.0018455 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 8 31 45577 0.304236 0.175396 0.6556452 0.0017478 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 1 45578 0.301656 0.170626 0.6539592 0.0016170 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 2 45579 0.299247 0.165977 0.6523992 0.0015094 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 3 45580 0.297057 0.161627 0.6509125 0.0014752 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 4 45581 0.294907 0.157597 0.6494102 0.0015448 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 5 45582 0.292677 0.153887 0.6477877 0.0017207 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 6 45583 0.290348 0.150418 0.6459505 0.0019507 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 7 45584 0.287828 0.147148 0.6438944 0.0021736 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 8 45585 0.285118 0.143928 0.6416356 0.0023418 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 9 45586 0.282299 0.140659 0.6392589 0.0023835 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 10 45587 0.279549 0.137259 0.6369144 0.0022976 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 11 45588 0.277119 0.133469 0.6346932 0.0021211 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 12 45589 0.274909 0.129409 0.6326824 0.0018916 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 13 45590 0.272850 0.125210 0.6309019 0.0016638 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 14 45591 0.270800 0.120950 0.6293371 0.0014879 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 15 45592 0.268600 0.116950 0.6279028 0.0013896 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 16 45593 0.266200 0.113300 0.6265332 0.0013531 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 17 45594 0.263621 0.109961 0.6251761 0.0013762 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 18 45595 0.260841 0.106811 0.6237629 0.0014580 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 19 45596 0.257811 0.103711 0.6222464 0.0015790 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 20 45597 0.254472 0.100492 0.6205975 0.0017283 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 21 45598 0.250882 0.097092 0.6187916 0.0018813 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 22 45599 0.247072 0.093592 0.6168443 0.0020073 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 23 45600 0.243192 0.090132 0.6147933 0.0020889 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 24 45601 0.239413 0.086843 0.6126866 0.0021129 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 25 45602 0.235813 0.083833 0.6105879 0.0020753 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 26 45603 0.232363 0.081123 0.6085536 0.0019836 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 27 45604 0.229063 0.078653 0.6066332 0.0018587 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 28 45605 0.225924 0.076304 0.6048375 0.0017451 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 29 45606 0.222774 0.073714 0.6031320 0.0016796 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 9 30 45607 0.219474 0.070734 0.6014558 0.0016896 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 1 45608 0.216015 0.067415 0.5997207 0.0017986 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 2 45609 0.212515 0.063975 0.5978235 0.0020072 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 3 45610 0.209025 0.060675 0.5956803 0.0022819 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 4 45611 0.205595 0.057725 0.5932548 0.0025628 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 5 45612 0.202266 0.055266 0.5905749 0.0027775 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 6 45613 0.199076 0.053246 0.5877388 0.0028687 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 7 45614 0.195866 0.051366 0.5848843 0.0028062 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 8 45615 0.192526 0.049426 0.5821668 0.0026117 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 9 45616 0.189007 0.047287 0.5796833 0.0023516 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 10 45617 0.185277 0.045027 0.5774653 0.0020872 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 11 45618 0.181387 0.042777 0.5754933 0.0018609 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 12 45619 0.177468 0.040688 0.5737200 0.0017165 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 13 45620 0.173558 0.038748 0.5720344 0.0016886 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 14 45621 0.169678 0.036878 0.5703185 0.0017136 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 15 45622 0.165848 0.035058 0.5685858 0.0017449 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 16 45623 0.161989 0.033379 0.5668136 0.0018095 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 17 45624 0.158099 0.032029 0.5649593 0.0019038 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 18 45625 0.154149 0.031009 0.5630045 0.0020188 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 19 45626 0.150040 0.029990 0.5609264 0.0021420 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 20 45627 0.145670 0.028680 0.5587332 0.0022466 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 21 45628 0.141030 0.026870 0.5564531 0.0023050 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 22 45629 0.136300 0.024800 0.5541459 0.0023007 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 23 45630 0.131601 0.022821 0.5518743 0.0022394 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 24 45631 0.127031 0.021251 0.5496828 0.0021410 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 25 45632 0.122551 0.020201 0.5475987 0.0020301 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 26 45633 0.118041 0.019551 0.5456149 0.0019497 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 27 45634 0.113372 0.019112 0.5436772 0.0019395 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 28 45635 0.108482 0.018722 0.5417047 0.0020184 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 29 45636 0.103502 0.018362 0.5396060 0.0021916 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 30 45637 0.098613 0.018013 0.5372935 0.0024468 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 10 31 45638 0.093963 0.017693 0.5347012 0.0027362 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 1 45639 0.089723 0.017373 0.5318293 0.0029935 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 2 45640 0.085863 0.017023 0.5287424 0.0031573 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 3 45641 0.082104 0.016654 0.5255558 0.0031930 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 4 45642 0.078154 0.016274 0.5223974 0.0031077 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 5 45643 0.073754 0.015864 0.5193714 0.0029162 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 6 45644 0.068824 0.015544 0.5165776 0.0026599 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 7 45645 0.063625 0.015285 0.5140458 0.0023977 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 8 45646 0.058365 0.015185 0.5117632 0.0021733 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 9 45647 0.053645 0.015165 0.5096739 0.0020376 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 10 45648 0.049536 0.015166 0.5076621 0.0020065 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 11 45649 0.045866 0.015086 0.5056380 0.0020469 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 12 45650 0.042286 0.015016 0.5035506 0.0021313 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 13 45651 0.038346 0.015226 0.5013634 0.0022538 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 14 45652 0.033857 0.015767 0.4990392 0.0023929 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 15 45653 0.028987 0.016517 0.4965799 0.0025225 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 16 45654 0.024247 0.017357 0.4940048 0.0026215 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 17 45655 0.019997 0.018167 0.4913533 0.0026715 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 18 45656 0.016098 0.019018 0.4886823 0.0026586 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 19 45657 0.012268 0.019938 0.4860595 0.0025765 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 20 45658 0.008158 0.020968 0.4835504 0.0024329 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 21 45659 0.003849 0.022029 0.4812060 0.0022543 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 22 45660 -0.000631 0.023039 0.4790402 0.0020739 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 23 45661 -0.005091 0.023889 0.4770381 0.0019465 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 24 45662 -0.009541 0.024619 0.4751150 0.0019220 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 25 45663 -0.014010 0.025370 0.4731607 0.0020010 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 26 45664 -0.018450 0.026200 0.4710852 0.0021596 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 27 45665 -0.022810 0.027120 0.4688292 0.0023567 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 28 45666 -0.027030 0.028110 0.4663778 0.0025372 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 29 45667 -0.031079 0.029171 0.4637758 0.0026504 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 11 30 45668 -0.034969 0.030301 0.4611109 0.0026651 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 1 45669 -0.038759 0.031571 0.4584829 0.0025722 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 2 45670 -0.042548 0.033012 0.4559977 0.0023975 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 3 45671 -0.046388 0.034482 0.4537068 0.0021826 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 4 45672 -0.050438 0.035882 0.4516330 0.0019652 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 5 45673 -0.054668 0.037192 0.4497635 0.0017790 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 6 45674 -0.058937 0.038363 0.4480520 0.0016473 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 7 45675 -0.063127 0.039433 0.4464437 0.0015699 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 8 45676 -0.067017 0.040433 0.4448884 0.0015609 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 9 45677 -0.070467 0.041513 0.4433036 0.0016192 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 10 45678 -0.073536 0.042764 0.4416367 0.0017194 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 11 45679 -0.076396 0.044364 0.4398579 0.0018485 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 12 45680 -0.079136 0.046294 0.4379403 0.0019915 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 13 45681 -0.081795 0.048555 0.4358837 0.0021225 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 14 45682 -0.084545 0.050945 0.4337070 0.0022216 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 15 45683 -0.087455 0.053325 0.4314572 0.0022668 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 16 45684 -0.090455 0.055565 0.4291936 0.0022490 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 17 45685 -0.093504 0.057586 0.4269803 0.0021587 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 18 45686 -0.096654 0.059496 0.4248931 0.0020087 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 19 45687 -0.099874 0.061486 0.4229682 0.0018416 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 20 45688 -0.103074 0.063736 0.4211981 0.0017121 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 21 45689 -0.106133 0.066327 0.4195154 0.0016695 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 22 45690 -0.108923 0.068977 0.4178220 0.0017341 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 23 45691 -0.111463 0.071507 0.4160144 0.0018945 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 24 45692 -0.113872 0.073798 0.4140157 0.0021083 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 25 45693 -0.116352 0.075708 0.4118017 0.0023196 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 26 45694 -0.118912 0.077348 0.4094005 0.0024728 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 27 45695 -0.121492 0.078928 0.4068896 0.0025280 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 28 45696 -0.124101 0.080659 0.4043797 0.0024750 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 29 45697 -0.126631 0.082759 0.4019680 0.0023364 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 30 45698 -0.128971 0.085349 0.3997242 0.0021441 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1983 12 31 45699 -0.131161 0.088359 0.3976841 0.0019372 0.000000 0.000000 0.002000 0.002000 0.0004000 0.0001500 0.001193 0.002000 1984 1 1 45700 -0.133145 0.088674 0.3957414 0.0017690 0.001887 -0.003052 0.000819 0.000745 0.0000913 0.0001290 0.000922 0.000587 1984 1 2 45701 -0.135325 0.092188 0.3940313 0.0016181 0.001617 -0.002860 0.000812 0.000730 0.0000912 0.0001290 0.000908 0.000572 1984 1 3 45702 -0.138195 0.095992 0.3924517 0.0015198 0.000989 -0.002224 0.000804 0.000714 0.0000912 0.0001289 0.000892 0.000555 1984 1 4 45703 -0.141989 0.098328 0.3909482 0.0014797 0.000362 -0.001589 0.000796 0.000700 0.0000911 0.0001288 0.000878 0.000539 1984 1 5 45704 -0.146511 0.099212 0.3894625 0.0014968 -0.000265 -0.000953 0.000790 0.000687 0.0000910 0.0001284 0.000864 0.000525 1984 1 6 45705 -0.150843 0.100971 0.3879423 0.0015636 -0.000446 -0.000819 0.000783 0.000672 0.0000906 0.0001281 0.000859 0.000517 1984 1 7 45706 -0.153947 0.105293 0.3863464 0.0016662 -0.000485 -0.000844 0.000774 0.000654 0.0000901 0.0001275 0.000858 0.000511 1984 1 8 45707 -0.155758 0.110920 0.3846474 0.0017843 -0.000524 -0.000870 0.000765 0.000641 0.0000897 0.0001269 0.000857 0.000506 1984 1 9 45708 -0.157253 0.115200 0.3828345 0.0018931 -0.000563 -0.000895 0.000757 0.000633 0.0000894 0.0001264 0.000856 0.000500 1984 1 10 45709 -0.159246 0.117250 0.3809173 0.0019674 -0.000602 -0.000920 0.000749 0.000625 0.0000890 0.0001271 0.000855 0.000495 1984 1 11 45710 -0.161489 0.118554 0.3789307 0.0019842 -0.000593 -0.000957 0.000749 0.000623 0.0000903 0.0001283 0.000858 0.000498 1984 1 12 45711 -0.163275 0.120811 0.3769387 0.0019255 -0.000568 -0.000997 0.000754 0.000627 0.0000923 0.0001306 0.000862 0.000504 1984 1 13 45712 -0.164560 0.124278 0.3750304 0.0017828 -0.000542 -0.001037 0.000760 0.000630 0.0000944 0.0001335 0.000867 0.000510 1984 1 14 45713 -0.166050 0.128218 0.3733049 0.0015651 -0.000517 -0.001078 0.000774 0.000643 0.0000964 0.0001365 0.000872 0.000517 1984 1 15 45714 -0.168317 0.131983 0.3718412 0.0013084 -0.000492 -0.001118 0.000798 0.000668 0.0000986 0.0001381 0.000877 0.000523 1984 1 16 45715 -0.171241 0.135248 0.3706615 0.0010764 -0.000504 -0.000962 0.000819 0.000690 0.0000989 0.0001394 0.000881 0.000529 1984 1 17 45716 -0.174303 0.137940 0.3697026 0.0009460 -0.000529 -0.000743 0.000838 0.000710 0.0000986 0.0001394 0.000886 0.000534 1984 1 18 45717 -0.177071 0.140431 0.3688168 0.0009773 -0.000554 -0.000524 0.000861 0.000732 0.0000982 0.0001389 0.000890 0.000539 1984 1 19 45718 -0.179380 0.143412 0.3678099 0.0011836 -0.000579 -0.000305 0.000888 0.000757 0.0000979 0.0001385 0.000895 0.000544 1984 1 20 45719 -0.181379 0.147086 0.3665050 0.0015173 -0.000603 -0.000086 0.000913 0.000783 0.0000976 0.0001380 0.000900 0.000549 1984 1 21 45720 -0.183479 0.150834 0.3648064 0.0018838 -0.000628 0.000133 0.000937 0.000809 0.0000973 0.0001376 0.000905 0.000554 1984 1 22 45721 -0.186002 0.154038 0.3627352 0.0021768 -0.000653 0.000352 0.000965 0.000838 0.0000970 0.0001372 0.000909 0.000559 1984 1 23 45722 -0.188797 0.156881 0.3604203 0.0023165 -0.000678 0.000571 0.000995 0.000871 0.0000968 0.0001369 0.000914 0.000563 1984 1 24 45723 -0.191394 0.159829 0.3580530 0.0022742 -0.000564 0.000513 0.001027 0.000908 0.0000966 0.0001366 0.000917 0.000566 1984 1 25 45724 -0.193592 0.162723 0.3558261 0.0020729 -0.000273 0.000102 0.001062 0.000949 0.0000964 0.0001369 0.000917 0.000566 1984 1 26 45725 -0.195626 0.165140 0.3538824 0.0017719 0.000451 0.000361 0.001097 0.000992 0.0000970 0.0001370 0.000916 0.000563 1984 1 27 45726 -0.197704 0.167489 0.3522890 0.0014429 0.000302 0.000214 0.001128 0.001033 0.0000974 0.0001374 0.000913 0.000556 1984 1 28 45727 -0.199728 0.170780 0.3510316 0.0011514 -0.000280 -0.000200 0.001156 0.001073 0.0000973 0.0001376 0.000910 0.000548 1984 1 29 45728 -0.201655 0.175040 0.3500329 0.0009439 -0.000862 -0.000613 0.001186 0.001118 0.0000973 0.0001376 0.000907 0.000540 1984 1 30 45729 -0.203789 0.178829 0.3491820 0.0008437 -0.001443 -0.001026 0.001216 0.001167 0.0000973 0.0001379 0.000904 0.000532 1984 1 31 45730 -0.206419 0.180943 0.3483617 0.0008514 -0.001200 -0.001004 0.001244 0.001215 0.0000976 0.0001382 0.000906 0.000534 1984 2 1 45731 -0.209370 0.182075 0.3474704 0.0009500 -0.000709 -0.000851 0.001267 0.001261 0.0000981 0.0001388 0.000910 0.000538 1984 2 2 45732 -0.212164 0.184077 0.3464347 0.0011103 -0.000218 -0.000697 0.001293 0.001310 0.0000987 0.0001395 0.000913 0.000543 1984 2 3 45733 -0.214466 0.187890 0.3452144 0.0012977 0.000274 -0.000544 0.001318 0.001365 0.0000992 0.0001402 0.000917 0.000548 1984 2 4 45734 -0.216104 0.192905 0.3438038 0.0014777 0.000765 -0.000391 0.001337 0.001416 0.0000997 0.0001415 0.000921 0.000554 1984 2 5 45735 -0.216926 0.198082 0.3422284 0.0016220 0.000598 -0.000385 0.001355 0.001465 0.0001010 0.0001433 0.000925 0.000555 1984 2 6 45736 -0.217072 0.202779 0.3405375 0.0017135 0.000206 -0.000429 0.001379 0.001522 0.0001030 0.0001457 0.000929 0.000554 1984 2 7 45737 -0.217239 0.206536 0.3387918 0.0017491 -0.000185 -0.000474 0.001399 0.001576 0.0001050 0.0001486 0.000932 0.000554 1984 2 8 45738 -0.218152 0.209130 0.3370503 0.0017368 -0.000576 -0.000518 0.001417 0.001627 0.0001071 0.0001516 0.000936 0.000554 1984 2 9 45739 -0.219754 0.211328 0.3353585 0.0016893 -0.000967 -0.000562 0.001435 0.001685 0.0001093 0.0001546 0.000940 0.000554 1984 2 10 45740 -0.221422 0.214619 0.3337434 0.0016185 -0.000763 -0.000407 0.001450 0.001737 0.0001114 0.0001576 0.000946 0.000557 1984 2 11 45741 -0.222991 0.219370 0.3322101 0.0015347 -0.000372 -0.000189 0.001464 0.001783 0.0001136 0.0001607 0.000951 0.000562 1984 2 12 45742 -0.224969 0.223946 0.3307437 0.0014532 0.000018 0.000029 0.001478 0.001835 0.0001159 0.0001639 0.000958 0.000566 1984 2 13 45743 -0.227473 0.226723 0.3293107 0.0013992 0.000409 0.000247 0.001490 0.001877 0.0001181 0.0001671 0.000964 0.000571 1984 2 14 45744 -0.229629 0.228501 0.3278603 0.0014046 0.000799 0.000465 0.001500 0.001910 0.0001204 0.0001692 0.000970 0.000575 1984 2 15 45745 -0.230603 0.231522 0.3263326 0.0014938 0.000784 0.000424 0.001503 0.001932 0.0001211 0.0001710 0.000975 0.000578 1984 2 16 45746 -0.230813 0.236075 0.3246807 0.0016659 0.000576 0.000258 0.001505 0.001935 0.0001215 0.0001718 0.000978 0.000578 1984 2 17 45747 -0.231403 0.239742 0.3228827 0.0018874 0.000368 0.000093 0.001513 0.001925 0.0001218 0.0001722 0.000982 0.000579 1984 2 18 45748 -0.232687 0.240922 0.3209435 0.0021016 0.000160 -0.000072 0.001524 0.001922 0.0001221 0.0001727 0.000985 0.000580 1984 2 19 45749 -0.233895 0.241719 0.3188899 0.0022497 -0.000048 -0.000237 0.001537 0.001904 0.0001224 0.0001727 0.000988 0.000581 1984 2 20 45750 -0.234566 0.245649 0.3167575 0.0022916 -0.000148 0.000034 0.001552 0.001864 0.0001221 0.0001725 0.000987 0.000580 1984 2 21 45751 -0.235376 0.252935 0.3145522 0.0022159 -0.000211 0.000458 0.001569 0.001825 0.0001216 0.0001710 0.000986 0.000577 1984 2 22 45752 -0.237106 0.259864 0.3123049 0.0020386 -0.000274 0.000253 0.001578 0.001779 0.0001197 0.0001692 0.000986 0.000567 1984 2 23 45753 -0.239275 0.263182 0.3101820 0.0017973 -0.000342 -0.000091 0.001575 0.001724 0.0001176 0.0001666 0.000979 0.000556 1984 2 24 45754 -0.240519 0.263666 0.3083846 0.0015448 -0.000411 -0.000436 0.001580 0.001682 0.0001158 0.0001650 0.000971 0.000545 1984 2 25 45755 -0.240314 0.264532 0.3070007 0.0013386 0.000518 -0.001798 0.001592 0.001659 0.0001157 0.0001644 0.000970 0.000544 1984 2 26 45756 -0.239799 0.267511 0.3056955 0.0012262 0.000787 -0.002648 0.001606 0.001656 0.0001167 0.0001652 0.000973 0.000545 1984 2 27 45757 -0.240615 0.271847 0.3045456 0.0012335 0.000629 -0.002243 0.001615 0.001659 0.0001179 0.0001658 0.000975 0.000545 1984 2 28 45758 -0.243094 0.276480 0.3037610 0.0013528 0.000157 -0.001838 0.001621 0.001652 0.0001178 0.0001664 0.000971 0.000545 1984 2 29 45759 -0.245854 0.281497 0.3026583 0.0015311 -0.000384 -0.001433 0.001625 0.001644 0.0001175 0.0001662 0.000966 0.000546 1984 3 1 45760 -0.247257 0.287116 0.3005269 0.0016822 -0.000520 -0.001132 0.001632 0.001647 0.0001173 0.0001647 0.000962 0.000548 1984 3 2 45761 -0.247156 0.292595 0.2981546 0.0017410 -0.000521 -0.000866 0.001626 0.001635 0.0001154 0.0001631 0.000959 0.000550 1984 3 3 45762 -0.246944 0.297046 0.2961903 0.0017101 -0.000522 -0.000599 0.001621 0.001627 0.0001133 0.0001603 0.000956 0.000552 1984 3 4 45763 -0.247803 0.300674 0.2947181 0.0016525 -0.000524 -0.000333 0.001622 0.001631 0.0001113 0.0001574 0.000953 0.000555 1984 3 5 45764 -0.249238 0.304399 0.2935325 0.0016434 -0.000525 -0.000067 0.001608 0.001614 0.0001092 0.0001544 0.000950 0.000557 1984 3 6 45765 -0.249772 0.308577 0.2922528 0.0017197 -0.000383 -0.000066 0.001587 0.001590 0.0001071 0.0001516 0.000943 0.000554 1984 3 7 45766 -0.248910 0.312792 0.2906072 0.0018581 -0.000194 -0.000151 0.001573 0.001577 0.0001050 0.0001486 0.000935 0.000549 1984 3 8 45767 -0.247726 0.316756 0.2885431 0.0019907 -0.000006 -0.000236 0.001551 0.001556 0.0001029 0.0001456 0.000927 0.000544 1984 3 9 45768 -0.247305 0.320733 0.2862133 0.0020459 0.000183 -0.000321 0.001520 0.001518 0.0001008 0.0001427 0.000920 0.000539 1984 3 10 45769 -0.247326 0.325001 0.2838933 0.0019904 0.000371 -0.000406 0.001495 0.001493 0.0000989 0.0001403 0.000913 0.000535 1984 3 11 45770 -0.246759 0.329431 0.2818368 0.0018532 0.000262 -0.000456 0.001478 0.001473 0.0000975 0.0001381 0.000906 0.000529 1984 3 12 45771 -0.245417 0.333763 0.2801215 0.0017153 0.000048 -0.000494 0.001468 0.001461 0.0000964 0.0001363 0.000899 0.000523 1984 3 13 45772 -0.243999 0.337902 0.2786248 0.0016717 -0.000166 -0.000533 0.001459 0.001449 0.0000953 0.0001348 0.000893 0.000517 1984 3 14 45773 -0.242835 0.341852 0.2770981 0.0017814 -0.000380 -0.000571 0.001446 0.001431 0.0000942 0.0001332 0.000886 0.000511 1984 3 15 45774 -0.241480 0.345679 0.2752822 0.0020337 -0.000594 -0.000609 0.001425 0.001397 0.0000931 0.0001324 0.000880 0.000506 1984 3 16 45775 -0.239625 0.349658 0.2730322 0.0023495 0.000119 -0.001328 0.001409 0.001378 0.0000931 0.0001311 0.000886 0.000517 1984 3 17 45776 -0.237590 0.354074 0.2704347 0.0026185 0.000343 -0.001481 0.001390 0.001357 0.0000923 0.0001302 0.000892 0.000529 1984 3 18 45777 -0.235671 0.358715 0.2676698 0.0027503 0.000211 -0.001283 0.001369 0.001331 0.0000911 0.0001288 0.000896 0.000540 1984 3 19 45778 -0.233777 0.362961 0.2649163 0.0027110 0.000079 -0.001085 0.001348 0.001306 0.0000898 0.0001270 0.000900 0.000553 1984 3 20 45779 -0.232061 0.366589 0.2623192 0.0025295 -0.000053 -0.000887 0.001328 0.001283 0.0000886 0.0001251 0.000904 0.000567 1984 3 21 45780 -0.231126 0.370137 0.2599522 0.0022737 -0.000251 -0.000889 0.001307 0.001257 0.0000871 0.0001231 0.000907 0.000576 1984 3 22 45781 -0.230975 0.374165 0.2578263 0.0020168 -0.000471 -0.000958 0.001288 0.001233 0.0000854 0.0001208 0.000909 0.000585 1984 3 23 45782 -0.230481 0.378519 0.2559084 0.0018111 -0.000691 -0.001027 0.001267 0.001210 0.0000838 0.0001185 0.000910 0.000595 1984 3 24 45783 -0.228726 0.382721 0.2541438 0.0016804 -0.000911 -0.001096 0.001245 0.001188 0.0000822 0.0001163 0.000912 0.000605 1984 3 25 45784 -0.226361 0.386739 0.2524740 0.0016268 -0.001130 -0.001165 0.001223 0.001165 0.0000806 0.0001152 0.000914 0.000615 1984 3 26 45785 -0.224687 0.390811 0.2508409 0.0016412 -0.000555 -0.000949 0.001210 0.001151 0.0000807 0.0001145 0.000921 0.000626 1984 3 27 45786 -0.223761 0.394742 0.2491856 0.0017099 0.000285 -0.000639 0.001199 0.001139 0.0000813 0.0001150 0.000930 0.000640 1984 3 28 45787 -0.222542 0.398060 0.2474520 0.0018152 0.001126 -0.000329 0.001188 0.001128 0.0000819 0.0001159 0.000939 0.000654 1984 3 29 45788 -0.220740 0.400870 0.2455970 0.0019342 0.001966 -0.000019 0.001177 0.001116 0.0000826 0.0001168 0.000948 0.000670 1984 3 30 45789 -0.219177 0.403884 0.2436054 0.0020400 0.002807 0.000292 0.001162 0.001103 0.0000833 0.0001178 0.000957 0.000686 1984 3 31 45790 -0.218085 0.407472 0.2414999 0.0021067 0.002648 0.000282 0.001150 0.001090 0.0000840 0.0001188 0.000961 0.000696 1984 4 1 45791 -0.216446 0.411291 0.2393400 0.0021157 0.002129 0.000157 0.001133 0.001074 0.0000847 0.0001197 0.000962 0.000705 1984 4 2 45792 -0.213696 0.415102 0.2372084 0.0020624 0.001611 0.000032 0.001112 0.001055 0.0000854 0.0001207 0.000964 0.000714 1984 4 3 45793 -0.210843 0.419223 0.2351858 0.0019582 0.001092 -0.000093 0.001092 0.001037 0.0000860 0.0001216 0.000966 0.000723 1984 4 4 45794 -0.208860 0.423733 0.2333239 0.0018276 0.000573 -0.000218 0.001071 0.001017 0.0000866 0.0001238 0.000967 0.000732 1984 4 5 45795 -0.207010 0.427881 0.2316283 0.0017000 0.000401 -0.000286 0.001049 0.000995 0.0000890 0.0001265 0.000976 0.000742 1984 4 6 45796 -0.204095 0.431029 0.2300536 0.0016012 0.000353 -0.000334 0.001028 0.000976 0.0000922 0.0001306 0.000988 0.000755 1984 4 7 45797 -0.200588 0.433751 0.2285227 0.0015488 0.000304 -0.000383 0.001011 0.000960 0.0000956 0.0001353 0.001000 0.000767 1984 4 8 45798 -0.197927 0.437166 0.2269546 0.0015539 0.000256 -0.000431 0.000996 0.000948 0.0000991 0.0001402 0.001013 0.000779 1984 4 9 45799 -0.196058 0.441390 0.2252854 0.0016256 0.000207 -0.000479 0.000982 0.000936 0.0001026 0.0001448 0.001025 0.000791 1984 4 10 45800 -0.193496 0.445489 0.2234776 0.0017714 0.000466 -0.000604 0.000972 0.000927 0.0001056 0.0001493 0.001033 0.000795 1984 4 11 45801 -0.189897 0.448907 0.2215267 0.0019893 0.000841 -0.000758 0.000967 0.000920 0.0001084 0.0001533 0.001039 0.000796 1984 4 12 45802 -0.186683 0.452030 0.2194335 0.0022552 0.001217 -0.000911 0.000962 0.000913 0.0001112 0.0001573 0.001044 0.000797 1984 4 13 45803 -0.184559 0.455328 0.2171850 0.0025168 0.001592 -0.001065 0.000966 0.000911 0.0001140 0.0001603 0.001050 0.000798 1984 4 14 45804 -0.182315 0.458930 0.2147546 0.0027024 0.000416 -0.001016 0.000976 0.000908 0.0001155 0.0001626 0.001051 0.000795 1984 4 15 45805 -0.179144 0.463191 0.2120333 0.0027465 -0.000118 -0.001336 0.000979 0.000898 0.0001159 0.0001636 0.001047 0.000787 1984 4 16 45806 -0.176271 0.468364 0.2091658 0.0026218 -0.000305 -0.001803 0.000975 0.000883 0.0001159 0.0001638 0.001042 0.000775 1984 4 17 45807 -0.174601 0.473207 0.2064804 0.0023597 -0.000492 -0.002271 0.000968 0.000866 0.0001159 0.0001638 0.001037 0.000764 1984 4 18 45808 -0.172488 0.475503 0.2042569 0.0020400 -0.000678 -0.002738 0.000962 0.000850 0.0001158 0.0001630 0.001032 0.000754 1984 4 19 45809 -0.168445 0.475384 0.2025360 0.0017553 0.000210 -0.001160 0.000959 0.000836 0.0001146 0.0001621 0.001025 0.000742 1984 4 20 45810 -0.164928 0.476804 0.2007777 0.0015728 0.000336 -0.000334 0.000956 0.000820 0.0001134 0.0001612 0.001016 0.000728 1984 4 21 45811 -0.165826 0.483315 0.1992697 0.0015203 0.000268 0.000110 0.000951 0.000806 0.0001133 0.0001612 0.001011 0.000721 1984 4 22 45812 -0.169739 0.492609 0.1981034 0.0015878 0.000344 0.000534 0.000946 0.000795 0.0001146 0.0001621 0.001010 0.000726 1984 4 23 45813 -0.169525 0.497966 0.1965591 0.0017296 0.000420 0.000959 0.000940 0.000783 0.0001159 0.0001631 0.001009 0.000732 1984 4 24 45814 -0.160871 0.496152 0.1942256 0.0018817 0.000823 0.000372 0.000931 0.000769 0.0001161 0.0001634 0.001003 0.000732 1984 4 25 45815 -0.148717 0.491671 0.1920742 0.0020001 0.001060 0.000847 0.000919 0.000753 0.0001151 0.0001628 0.000993 0.000725 1984 4 26 45816 -0.141893 0.491382 0.1902319 0.0020764 0.001200 0.001718 0.000904 0.000736 0.0001141 0.0001605 0.000982 0.000717 1984 4 27 45817 -0.142562 0.496517 0.1881831 0.0021186 0.000014 0.000818 0.000886 0.000716 0.0001118 0.0001585 0.000965 0.000701 1984 4 28 45818 -0.144529 0.502487 0.1860806 0.0021341 -0.000180 0.000079 0.000879 0.000706 0.0001100 0.0001557 0.000950 0.000689 1984 4 29 45819 -0.141933 0.505715 0.1840134 0.0021244 0.000014 -0.000598 0.000881 0.000704 0.0001084 0.0001539 0.000936 0.000679 1984 4 30 45820 -0.135897 0.507504 0.1819488 0.0020840 0.000344 -0.000732 0.000880 0.000700 0.0001077 0.0001525 0.000922 0.000666 1984 5 1 45821 -0.131040 0.510534 0.1799025 0.0020042 0.000723 -0.000673 0.000874 0.000692 0.0001073 0.0001517 0.000914 0.000653 1984 5 2 45822 -0.128563 0.514462 0.1779246 0.0018819 0.001102 -0.000614 0.000865 0.000681 0.0001069 0.0001512 0.000906 0.000638 1984 5 3 45823 -0.125827 0.517081 0.1760706 0.0017278 0.001481 -0.000555 0.000856 0.000670 0.0001065 0.0001506 0.000898 0.000624 1984 5 4 45824 -0.121289 0.518172 0.1743807 0.0015686 0.001859 -0.000497 0.000855 0.000669 0.0001061 0.0001494 0.000889 0.000610 1984 5 5 45825 -0.116466 0.519716 0.1728582 0.0014426 0.001645 -0.000361 0.000864 0.000679 0.0001047 0.0001477 0.000878 0.000596 1984 5 6 45826 -0.112791 0.522703 0.1714551 0.0013895 0.001214 -0.000198 0.000872 0.000690 0.0001028 0.0001454 0.000867 0.000579 1984 5 7 45827 -0.109280 0.525961 0.1700770 0.0014374 0.000784 -0.000034 0.000879 0.000698 0.0001010 0.0001428 0.000856 0.000562 1984 5 8 45828 -0.104524 0.528419 0.1686050 0.0015915 0.000353 0.000129 0.000882 0.000703 0.0000991 0.0001402 0.000844 0.000547 1984 5 9 45829 -0.099201 0.530649 0.1669284 0.0018259 -0.000077 0.000292 0.000885 0.000708 0.0000973 0.0001379 0.000833 0.000532 1984 5 10 45830 -0.095067 0.533409 0.1649827 0.0020844 -0.000128 0.000315 0.000890 0.000715 0.0000959 0.0001358 0.000824 0.000524 1984 5 11 45831 -0.092400 0.536125 0.1627786 0.0022932 0.000058 0.000252 0.000897 0.000724 0.0000948 0.0001340 0.000816 0.000520 1984 5 12 45832 -0.089915 0.537931 0.1604075 0.0023849 0.000244 0.000188 0.000903 0.000733 0.0000936 0.0001324 0.000808 0.000516 1984 5 13 45833 -0.086809 0.539227 0.1580170 0.0023250 0.000430 0.000125 0.000907 0.000739 0.0000925 0.0001308 0.000797 0.000512 1984 5 14 45834 -0.083518 0.540987 0.1557657 0.0021263 0.000616 0.000061 0.000906 0.000742 0.0000914 0.0001292 0.000787 0.000508 1984 5 15 45835 -0.080465 0.543093 0.1537731 0.0018444 0.000684 -0.000033 0.000902 0.000741 0.0000903 0.0001276 0.000782 0.000508 1984 5 16 45836 -0.077221 0.544590 0.1520854 0.0015536 0.000713 -0.000138 0.000900 0.000742 0.0000890 0.0001259 0.000780 0.000509 1984 5 17 45837 -0.073281 0.545349 0.1506721 0.0013190 0.000743 -0.000244 0.000902 0.000748 0.0000878 0.0001242 0.000777 0.000511 1984 5 18 45838 -0.068881 0.546290 0.1494487 0.0011768 0.000772 -0.000349 0.000904 0.000753 0.0000866 0.0001225 0.000774 0.000512 1984 5 19 45839 -0.064575 0.547906 0.1483113 0.0011315 0.000801 -0.000454 0.000913 0.000762 0.0000854 0.0001212 0.000771 0.000514 1984 5 20 45840 -0.060512 0.549628 0.1471667 0.0011654 0.002902 -0.000814 0.000925 0.000771 0.0000849 0.0001203 0.000770 0.000518 1984 5 21 45841 -0.056512 0.550928 0.1459504 0.0012510 0.002969 -0.000750 0.000935 0.000778 0.0000847 0.0001197 0.000765 0.000522 1984 5 22 45842 -0.052476 0.552117 0.1446300 0.0013603 0.001911 -0.000476 0.000942 0.000784 0.0000845 0.0001194 0.000755 0.000526 1984 5 23 45843 -0.048350 0.553585 0.1432010 0.0014691 0.000853 -0.000202 0.000944 0.000786 0.0000842 0.0001191 0.000749 0.000529 1984 5 24 45844 -0.043997 0.555036 0.1416794 0.0015581 -0.000204 0.000072 0.000946 0.000788 0.0000840 0.0001188 0.000743 0.000533 1984 5 25 45845 -0.039496 0.556063 0.1400943 0.0016137 -0.000470 0.000089 0.000944 0.000788 0.0000837 0.0001184 0.000739 0.000541 1984 5 26 45846 -0.035312 0.556883 0.1384814 0.0016276 -0.000475 0.000021 0.000940 0.000785 0.0000834 0.0001180 0.000735 0.000550 1984 5 27 45847 -0.031723 0.557844 0.1368801 0.0015950 -0.000479 -0.000047 0.000935 0.000783 0.0000832 0.0001176 0.000728 0.000562 1984 5 28 45848 -0.028221 0.558698 0.1353329 0.0015142 -0.000483 -0.000115 0.000926 0.000778 0.0000829 0.0001172 0.000724 0.000574 1984 5 29 45849 -0.023949 0.559099 0.1338824 0.0013896 -0.000488 -0.000183 0.000914 0.000771 0.0000826 0.0001168 0.000719 0.000586 1984 5 30 45850 -0.018744 0.559458 0.1325651 0.0012359 -0.000366 -0.000278 0.000900 0.000761 0.0000823 0.0001165 0.000714 0.000596 1984 5 31 45851 -0.013358 0.560436 0.1313989 0.0010816 -0.000197 -0.000383 0.000881 0.000746 0.0000822 0.0001163 0.000710 0.000605 1984 6 1 45852 -0.008608 0.561732 0.1303703 0.0009646 -0.000028 -0.000488 0.000858 0.000728 0.0000821 0.0001160 0.000706 0.000616 1984 6 2 45853 -0.004635 0.562317 0.1294279 0.0009212 0.000140 -0.000592 0.000837 0.000711 0.0000818 0.0001156 0.000702 0.000625 1984 6 3 45854 -0.001061 0.561934 0.1284889 0.0009717 0.000309 -0.000697 0.000814 0.000693 0.0000814 0.0001151 0.000697 0.000632 1984 6 4 45855 0.002526 0.561490 0.1274585 0.0011119 0.000227 -0.000725 0.000786 0.000669 0.0000809 0.0001144 0.000692 0.000637 1984 6 5 45856 0.006428 0.561651 0.1262566 0.0013113 0.000061 -0.000728 0.000760 0.000647 0.0000804 0.0001137 0.000686 0.000641 1984 6 6 45857 0.010832 0.561893 0.1248429 0.0015209 -0.000104 -0.000731 0.000737 0.000627 0.0000798 0.0001129 0.000680 0.000644 1984 6 7 45858 0.015620 0.561493 0.1232329 0.0016848 -0.000269 -0.000734 0.000716 0.000609 0.0000793 0.0001121 0.000674 0.000648 1984 6 8 45859 0.020380 0.560759 0.1214984 0.0017548 -0.000435 -0.000736 0.000698 0.000593 0.0000787 0.0001108 0.000668 0.000652 1984 6 9 45860 0.024870 0.560464 0.1197522 0.0017047 -0.000391 -0.000787 0.000683 0.000581 0.0000774 0.0001093 0.000659 0.000647 1984 6 10 45861 0.029311 0.560514 0.1181190 0.0015394 -0.000283 -0.000853 0.000672 0.000572 0.0000759 0.0001071 0.000649 0.000641 1984 6 11 45862 0.033926 0.560097 0.1166999 0.0012960 -0.000174 -0.000920 0.000662 0.000564 0.0000740 0.0001051 0.000639 0.000625 1984 6 12 45863 0.038384 0.559044 0.1155445 0.0010325 -0.000065 -0.000986 0.000656 0.000562 0.0000727 0.0001028 0.000630 0.000618 1984 6 13 45864 0.042170 0.558131 0.1146397 0.0008080 0.000043 -0.001052 0.000654 0.000564 0.0000713 0.0001015 0.000621 0.000612 1984 6 14 45865 0.045435 0.557837 0.1139195 0.0006644 0.000006 -0.000962 0.000650 0.000564 0.0000709 0.0001004 0.000615 0.000606 1984 6 15 45866 0.048951 0.557602 0.1132904 0.0006162 -0.000084 -0.000817 0.000651 0.000567 0.0000706 0.0000999 0.000609 0.000601 1984 6 16 45867 0.053100 0.556778 0.1126591 0.0006533 -0.000175 -0.000672 0.000658 0.000574 0.0000703 0.0000995 0.000604 0.000593 1984 6 17 45868 0.057420 0.555738 0.1119530 0.0007510 -0.000265 -0.000527 0.000665 0.000583 0.0000701 0.0000992 0.000598 0.000589 1984 6 18 45869 0.061423 0.555438 0.1111286 0.0008806 -0.000355 -0.000382 0.000676 0.000592 0.0000699 0.0000991 0.000593 0.000582 1984 6 19 45870 0.065344 0.556114 0.1101707 0.0010158 -0.000381 -0.000387 0.000687 0.000602 0.0000700 0.0000991 0.000586 0.000577 1984 6 20 45871 0.069561 0.556939 0.1090874 0.0011349 -0.000384 -0.000442 0.000699 0.000611 0.0000703 0.0000994 0.000580 0.000571 1984 6 21 45872 0.073728 0.556948 0.1079037 0.0012226 -0.000388 -0.000498 0.000709 0.000618 0.0000706 0.0000998 0.000572 0.000565 1984 6 22 45873 0.077235 0.555946 0.1066561 0.0012705 -0.000392 -0.000554 0.000715 0.000622 0.0000708 0.0001002 0.000560 0.000560 1984 6 23 45874 0.080344 0.554528 0.1053870 0.0012755 -0.000395 -0.000610 0.000723 0.000627 0.0000711 0.0001003 0.000553 0.000555 1984 6 24 45875 0.084003 0.553441 0.1041406 0.0012374 -0.000196 -0.000643 0.000729 0.000630 0.0000710 0.0001004 0.000544 0.000543 1984 6 25 45876 0.088401 0.552926 0.1029592 0.0011567 0.000072 -0.000668 0.000733 0.000632 0.0000709 0.0001003 0.000530 0.000530 1984 6 26 45877 0.092649 0.552499 0.1018792 0.0010368 0.000340 -0.000694 0.000738 0.000633 0.0000708 0.0001001 0.000521 0.000517 1984 6 27 45878 0.096289 0.551426 0.1009259 0.0008901 0.000608 -0.000719 0.000741 0.000634 0.0000706 0.0000999 0.000512 0.000506 1984 6 28 45879 0.100239 0.549575 0.1001035 0.0007419 0.000877 -0.000745 0.000743 0.000635 0.0000705 0.0000996 0.000504 0.000496 1984 6 29 45880 0.105410 0.547607 0.0993891 0.0006271 0.000947 -0.000787 0.000744 0.000633 0.0000701 0.0000992 0.000494 0.000482 1984 6 30 45881 0.111086 0.546140 0.0987376 0.0005780 0.000951 -0.000836 0.000741 0.000631 0.0000697 0.0000986 0.000484 0.000468 1984 7 1 45882 0.115827 0.544980 0.0980924 0.0006105 0.000955 -0.000884 0.000738 0.000630 0.0000693 0.0000980 0.000474 0.000454 1984 7 2 45883 0.119656 0.543594 0.0974005 0.0007165 0.000959 -0.000932 0.000734 0.000629 0.0000689 0.0000974 0.000466 0.000443 1984 7 3 45884 0.124005 0.542063 0.0966260 0.0008674 0.000964 -0.000981 0.000730 0.000627 0.0000685 0.0000965 0.000458 0.000432 1984 7 4 45885 0.129403 0.540896 0.0957530 0.0010236 0.000817 -0.000887 0.000722 0.000621 0.0000676 0.0000956 0.000448 0.000418 1984 7 5 45886 0.134602 0.539928 0.0947762 0.0011450 0.000621 -0.000746 0.000714 0.000614 0.0000667 0.0000943 0.000438 0.000404 1984 7 6 45887 0.138566 0.538231 0.0937034 0.0011972 0.000424 -0.000606 0.000704 0.000605 0.0000658 0.0000930 0.000429 0.000392 1984 7 7 45888 0.142000 0.535491 0.0925650 0.0011550 0.000227 -0.000465 0.000693 0.000594 0.0000649 0.0000919 0.000420 0.000380 1984 7 8 45889 0.145919 0.532718 0.0914251 0.0010082 0.000031 -0.000324 0.000683 0.000585 0.0000641 0.0000909 0.000413 0.000371 1984 7 9 45890 0.149838 0.530925 0.0903847 0.0007682 -0.000071 -0.000354 0.000677 0.000580 0.0000636 0.0000901 0.000410 0.000368 1984 7 10 45891 0.152834 0.529609 0.0895761 0.0004734 -0.000109 -0.000501 0.000673 0.000579 0.0000632 0.0000894 0.000409 0.000369 1984 7 11 45892 0.155642 0.527419 0.0891158 0.0001859 -0.000146 -0.000648 0.000669 0.000578 0.0000628 0.0000849 0.000409 0.000368 1984 7 12 45893 0.159833 0.524133 0.0890388 -0.0000227 -0.000183 -0.000794 0.000662 0.000574 0.0000567 0.0000842 0.000409 0.000367 1984 7 13 45894 0.165139 0.521026 0.0892598 -0.0000938 -0.000220 -0.000941 0.000661 0.000575 0.0000561 0.0000794 0.000408 0.000368 1984 7 14 45895 0.169607 0.519110 0.0895760 -0.0000038 -0.000748 -0.000944 0.000658 0.000574 0.0000556 0.0000767 0.000407 0.000366 1984 7 15 45896 0.172707 0.517858 0.0896877 0.0002226 -0.001480 -0.000886 0.000649 0.000566 0.0000523 0.0000759 0.000405 0.000362 1984 7 16 45897 0.176170 0.516098 0.0893350 0.0005172 -0.001861 -0.000800 0.000641 0.000561 0.0000516 0.0000726 0.000403 0.000358 1984 7 17 45898 0.180846 0.513520 0.0884765 0.0007927 -0.001211 -0.000627 0.000634 0.000555 0.0000504 0.0000713 0.000398 0.000351 1984 7 18 45899 0.184995 0.510718 0.0873404 0.0009773 -0.000561 -0.000455 0.000625 0.000548 0.0000493 0.0000696 0.000394 0.000345 1984 7 19 45900 0.187555 0.508197 0.0862171 0.0010383 -0.000315 -0.000289 0.000612 0.000538 0.0000480 0.0000680 0.000388 0.000336 1984 7 20 45901 0.191101 0.505967 0.0852360 0.0009860 -0.000203 -0.000125 0.000599 0.000527 0.0000468 0.0000663 0.000382 0.000328 1984 7 21 45902 0.198472 0.503847 0.0843858 0.0008583 -0.000091 0.000038 0.000590 0.000518 0.0000457 0.0000647 0.000377 0.000321 1984 7 22 45903 0.207312 0.501543 0.0836068 0.0007008 0.000010 0.000104 0.000582 0.000510 0.0000447 0.0000633 0.000373 0.000314 1984 7 23 45904 0.211714 0.498596 0.0829679 0.0005550 0.000124 -0.000252 0.000575 0.000502 0.0000438 0.0000621 0.000371 0.000309 1984 7 24 45905 0.210147 0.494922 0.0826735 0.0004537 0.001396 -0.001705 0.000571 0.000497 0.0000431 0.0000608 0.000373 0.000308 1984 7 25 45906 0.208317 0.491320 0.0824141 0.0004172 0.001877 -0.002285 0.000565 0.000493 0.0000421 0.0000594 0.000373 0.000306 1984 7 26 45907 0.212008 0.488699 0.0819329 0.0004534 0.001383 -0.001792 0.000557 0.000487 0.0000410 0.0000580 0.000372 0.000302 1984 7 27 45908 0.219693 0.486748 0.0812340 0.0005645 0.000889 -0.001299 0.000549 0.000481 0.0000399 0.0000565 0.000371 0.000298 1984 7 28 45909 0.225297 0.484184 0.0803961 0.0007494 0.000396 -0.000806 0.000541 0.000476 0.0000389 0.0000551 0.000370 0.000294 1984 7 29 45910 0.226687 0.480591 0.0794980 0.0009950 -0.000059 -0.000328 0.000532 0.000470 0.0000380 0.0000535 0.000369 0.000290 1984 7 30 45911 0.227637 0.477112 0.0785105 0.0012650 -0.000110 -0.000003 0.000524 0.000464 0.0000368 0.0000523 0.000367 0.000285 1984 7 31 45912 0.231489 0.474717 0.0772345 0.0014997 -0.000024 -0.000163 0.000521 0.000461 0.0000360 0.0000510 0.000369 0.000289 1984 8 1 45913 0.236742 0.472614 0.0756737 0.0016344 0.000067 -0.000340 0.000518 0.000457 0.0000353 0.0000499 0.000371 0.000294 1984 8 2 45914 0.240382 0.469456 0.0739801 0.0016280 0.000158 -0.000516 0.000516 0.000455 0.0000346 0.0000487 0.000373 0.000299 1984 8 3 45915 0.242576 0.465578 0.0723622 0.0014810 0.000159 -0.000552 0.000513 0.000453 0.0000336 0.0000476 0.000374 0.000301 1984 8 4 45916 0.245548 0.462596 0.0709781 0.0012342 0.000129 -0.000540 0.000508 0.000449 0.0000327 0.0000463 0.000374 0.000303 1984 8 5 45917 0.249636 0.460684 0.0698963 0.0009504 0.000045 -0.000474 0.000504 0.000445 0.0000318 0.0000450 0.000374 0.000305 1984 8 6 45918 0.253246 0.457787 0.0691016 0.0006925 -0.000256 -0.000191 0.000502 0.000442 0.0000310 0.0000437 0.000377 0.000308 1984 8 7 45919 0.255943 0.452421 0.0685227 0.0005076 0.000735 -0.000006 0.000499 0.000437 0.0000299 0.0000422 0.000379 0.000313 1984 8 8 45920 0.258926 0.446193 0.0680767 0.0004209 0.001739 -0.001132 0.000496 0.000434 0.0000287 0.0000406 0.000379 0.000315 1984 8 9 45921 0.262449 0.442109 0.0676603 0.0004360 0.002207 -0.001970 0.000494 0.000430 0.0000274 0.0000387 0.000378 0.000315 1984 8 10 45922 0.265167 0.440773 0.0671743 0.0005396 0.001674 -0.001401 0.000489 0.000425 0.0000260 0.0000369 0.000376 0.000313 1984 8 11 45923 0.266619 0.439689 0.0665473 0.0007079 0.001141 -0.000832 0.000486 0.000422 0.0000247 0.0000351 0.000373 0.000312 1984 8 12 45924 0.268317 0.436548 0.0657354 0.0009124 0.000607 -0.000263 0.000486 0.000421 0.0000236 0.0000333 0.000370 0.000310 1984 8 13 45925 0.271426 0.431904 0.0647215 0.0011237 0.000486 -0.000092 0.000484 0.000419 0.0000223 0.0000317 0.000366 0.000305 1984 8 14 45926 0.275028 0.427873 0.0635118 0.0013135 0.000541 -0.000092 0.000479 0.000415 0.0000211 0.0000300 0.000361 0.000300 1984 8 15 45927 0.277850 0.425177 0.0621344 0.0014568 0.000596 -0.000092 0.000473 0.000411 0.0000201 0.0000285 0.000356 0.000294 1984 8 16 45928 0.280271 0.422693 0.0606383 0.0015348 0.000651 -0.000092 0.000467 0.000406 0.0000191 0.0000272 0.000352 0.000289 1984 8 17 45929 0.283171 0.419543 0.0590881 0.0015381 0.000706 -0.000092 0.000462 0.000402 0.0000183 0.0000259 0.000347 0.000284 1984 8 18 45930 0.285933 0.416245 0.0575580 0.0014677 0.000493 -0.000100 0.000456 0.000396 0.0000174 0.0000247 0.000341 0.000276 1984 8 19 45931 0.287375 0.413441 0.0561237 0.0013347 0.000193 -0.000111 0.000449 0.000390 0.0000166 0.0000236 0.000335 0.000269 1984 8 20 45932 0.288005 0.410510 0.0548504 0.0011596 -0.000108 -0.000122 0.000441 0.000381 0.0000159 0.0000225 0.000329 0.000262 1984 8 21 45933 0.289443 0.406338 0.0537763 0.0009746 -0.000408 -0.000132 0.000431 0.000372 0.0000152 0.0000216 0.000324 0.000256 1984 8 22 45934 0.291747 0.401043 0.0528950 0.0008249 -0.000709 -0.000143 0.000422 0.000364 0.0000147 0.0000208 0.000319 0.000250 1984 8 23 45935 0.293201 0.396052 0.0521410 0.0007633 -0.000488 -0.000198 0.000412 0.000355 0.0000141 0.0000200 0.000313 0.000243 1984 8 24 45936 0.293065 0.392375 0.0513875 0.0008341 -0.000090 -0.000267 0.000402 0.000346 0.0000135 0.0000192 0.000306 0.000236 1984 8 25 45937 0.292781 0.389442 0.0504753 0.0010496 0.000307 -0.000336 0.000393 0.000338 0.0000130 0.0000185 0.000301 0.000229 1984 8 26 45938 0.293701 0.385926 0.0492641 0.0013735 0.000288 -0.000445 0.000384 0.000330 0.0000126 0.0000178 0.000295 0.000224 1984 8 27 45939 0.295167 0.381328 0.0476901 0.0017255 -0.000490 -0.000627 0.000375 0.000323 0.0000121 0.0000171 0.000289 0.000219 1984 8 28 45940 0.295958 0.376375 0.0457960 0.0020086 -0.000453 -0.000651 0.000365 0.000315 0.0000115 0.0000164 0.000282 0.000212 1984 8 29 45941 0.296379 0.372076 0.0437008 0.0021476 -0.000145 -0.000623 0.000354 0.000306 0.0000110 0.0000156 0.000276 0.000206 1984 8 30 45942 0.297478 0.368760 0.0415623 0.0021170 -0.000158 -0.000583 0.000342 0.000295 0.0000105 0.0000149 0.000269 0.000201 1984 8 31 45943 0.298985 0.366019 0.0395419 0.0019455 -0.000377 -0.000542 0.000334 0.000288 0.0000101 0.0000146 0.000264 0.000197 1984 9 1 45944 0.299638 0.363237 0.0377412 0.0016957 -0.000754 -0.000538 0.000337 0.000290 0.0000101 0.0000143 0.000265 0.000197 1984 9 2 45945 0.299296 0.360019 0.0361593 0.0014352 -0.000472 -0.000663 0.000337 0.000290 0.0000101 0.0000142 0.000265 0.000195 1984 9 3 45946 0.299206 0.356295 0.0347983 0.0012151 -0.000032 -0.000794 0.000339 0.000292 0.0000100 0.0000144 0.000265 0.000194 1984 9 4 45947 0.300103 0.352218 0.0336459 0.0010631 -0.000031 -0.000667 0.000350 0.000301 0.0000103 0.0000146 0.000270 0.000199 1984 9 5 45948 0.301385 0.347991 0.0326329 0.0009874 -0.000029 -0.000539 0.000361 0.000311 0.0000106 0.0000151 0.000276 0.000205 1984 9 6 45949 0.302473 0.343731 0.0316711 0.0009828 -0.000028 -0.000412 0.000374 0.000321 0.0000110 0.0000155 0.000282 0.000212 1984 9 7 45950 0.303705 0.339505 0.0306772 0.0010360 0.000008 -0.000355 0.000387 0.000332 0.0000113 0.0000160 0.000287 0.000217 1984 9 8 45951 0.305329 0.335444 0.0295943 0.0011296 0.000054 -0.000323 0.000401 0.000343 0.0000117 0.0000165 0.000292 0.000223 1984 9 9 45952 0.306683 0.331674 0.0283967 0.0012445 0.000101 -0.000291 0.000417 0.000356 0.0000120 0.0000171 0.000298 0.000230 1984 9 10 45953 0.307164 0.328071 0.0270844 0.0013624 0.000147 -0.000258 0.000432 0.000368 0.0000125 0.0000177 0.000304 0.000237 1984 9 11 45954 0.307209 0.324264 0.0256744 0.0014670 0.000194 -0.000226 0.000449 0.000381 0.0000130 0.0000184 0.000310 0.000246 1984 9 12 45955 0.307523 0.320035 0.0241909 0.0015453 0.000120 -0.000064 0.000465 0.000394 0.0000134 0.0000190 0.000316 0.000253 1984 9 13 45956 0.308002 0.315657 0.0226562 0.0015879 0.000006 0.000140 0.000481 0.000406 0.0000139 0.0000197 0.000322 0.000259 1984 9 14 45957 0.308303 0.311630 0.0210923 0.0015887 -0.000108 0.000345 0.000497 0.000419 0.0000144 0.0000205 0.000329 0.000267 1984 9 15 45958 0.308822 0.308091 0.0195265 0.0015453 -0.000222 0.000550 0.000515 0.000434 0.0000150 0.0000213 0.000336 0.000276 1984 9 16 45959 0.310027 0.304630 0.0179960 0.0014593 -0.000336 0.000755 0.000533 0.000449 0.0000157 0.0000221 0.000343 0.000286 1984 9 17 45960 0.311257 0.300719 0.0165462 0.0013397 -0.000416 0.000629 0.000547 0.000461 0.0000163 0.0000230 0.000350 0.000293 1984 9 18 45961 0.311416 0.296168 0.0152198 0.0012093 -0.000485 0.000396 0.000562 0.000473 0.0000168 0.0000239 0.000355 0.000299 1984 9 19 45962 0.310764 0.291179 0.0140312 0.0011080 -0.000553 0.000162 0.000577 0.000486 0.0000175 0.0000248 0.000361 0.000306 1984 9 20 45963 0.310747 0.286181 0.0129406 0.0010878 -0.000622 -0.000071 0.000590 0.000498 0.0000182 0.0000259 0.000368 0.000314 1984 9 21 45964 0.311865 0.281711 0.0118441 0.0011940 -0.000691 -0.000305 0.000605 0.000511 0.0000191 0.0000269 0.000374 0.000321 1984 9 22 45965 0.312946 0.278191 0.0105933 0.0014386 -0.000336 -0.000274 0.000618 0.000523 0.0000198 0.0000280 0.000379 0.000327 1984 9 23 45966 0.313002 0.275509 0.0090438 0.0017813 0.000161 -0.000154 0.000629 0.000533 0.0000204 0.0000289 0.000383 0.000332 1984 9 24 45967 0.312641 0.272943 0.0071168 0.0021337 0.000265 -0.000078 0.000641 0.000543 0.0000211 0.0000300 0.000387 0.000339 1984 9 25 45968 0.312864 0.269779 0.0048429 0.0023906 -0.000114 -0.000054 0.000653 0.000555 0.0000220 0.0000312 0.000391 0.000347 1984 9 26 45969 0.313450 0.265978 0.0023618 0.0024738 -0.000494 -0.000031 0.000663 0.000568 0.0000229 0.0000324 0.000395 0.000355 1984 9 27 45970 0.313590 0.262004 -0.0001245 0.0023651 -0.000661 -0.000110 0.000677 0.000581 0.0000237 0.0000336 0.000400 0.000363 1984 9 28 45971 0.313404 0.258077 -0.0024210 0.0021113 -0.000757 -0.000224 0.000691 0.000596 0.0000246 0.0000349 0.000406 0.000373 1984 9 29 45972 0.313563 0.254000 -0.0044045 0.0017999 -0.000852 -0.000337 0.000708 0.000614 0.0000256 0.0000363 0.000413 0.000383 1984 9 30 45973 0.313782 0.249777 -0.0060540 0.0015219 -0.000948 -0.000451 0.000726 0.000634 0.0000267 0.0000379 0.000420 0.000395 1984 10 1 45974 0.313018 0.245880 -0.0074411 0.0013411 -0.001043 -0.000565 0.000741 0.000653 0.0000279 0.0000393 0.000427 0.000408 1984 10 2 45975 0.311192 0.242587 -0.0086928 0.0012811 -0.000933 -0.000510 0.000751 0.000667 0.0000289 0.0000408 0.000432 0.000417 1984 10 3 45976 0.309444 0.239429 -0.0099471 0.0013306 -0.000744 -0.000389 0.000759 0.000680 0.0000297 0.0000421 0.000436 0.000425 1984 10 4 45977 0.308410 0.235767 -0.0113164 0.0014563 -0.000555 -0.000269 0.000765 0.000691 0.0000307 0.0000435 0.000440 0.000433 1984 10 5 45978 0.307418 0.231732 -0.0128640 0.0016159 -0.000366 -0.000148 0.000770 0.000701 0.0000317 0.0000450 0.000444 0.000441 1984 10 6 45979 0.305913 0.228042 -0.0145994 0.0017683 -0.000176 -0.000027 0.000776 0.000712 0.0000329 0.0000464 0.000449 0.000450 1984 10 7 45980 0.304501 0.224886 -0.0164842 0.0018816 -0.000177 -0.000112 0.000784 0.000722 0.0000339 0.0000480 0.000455 0.000461 1984 10 8 45981 0.303730 0.221583 -0.0184476 0.0019373 -0.000246 -0.000269 0.000794 0.000734 0.0000350 0.0000497 0.000461 0.000472 1984 10 9 45982 0.302791 0.217523 -0.0204088 0.0019327 -0.000315 -0.000426 0.000804 0.000745 0.0000363 0.0000514 0.000468 0.000485 1984 10 10 45983 0.300609 0.212967 -0.0222999 0.0018788 -0.000383 -0.000583 0.000812 0.000755 0.0000376 0.0000533 0.000475 0.000498 1984 10 11 45984 0.297621 0.208610 -0.0240827 0.0017947 -0.000452 -0.000740 0.000817 0.000762 0.0000391 0.0000550 0.000483 0.000512 1984 10 12 45985 0.295145 0.204745 -0.0257538 0.0016999 -0.000316 -0.000640 0.000822 0.000766 0.0000402 0.0000568 0.000488 0.000522 1984 10 13 45986 0.293295 0.201213 -0.0273408 0.0016081 -0.000100 -0.000440 0.000823 0.000766 0.0000412 0.0000583 0.000492 0.000531 1984 10 14 45987 0.291031 0.197812 -0.0288821 0.0015246 0.000116 -0.000240 0.000821 0.000763 0.0000423 0.0000599 0.000497 0.000541 1984 10 15 45988 0.288368 0.194300 -0.0304048 0.0014501 0.000332 -0.000041 0.000821 0.000762 0.0000435 0.0000616 0.000502 0.000552 1984 10 16 45989 0.286849 0.190344 -0.0319138 0.0013900 0.000548 0.000159 0.000819 0.000758 0.0000447 0.0000632 0.000506 0.000562 1984 10 17 45990 0.287059 0.186087 -0.0333985 0.0013635 0.000446 0.000140 0.000814 0.000750 0.0000458 0.0000648 0.000512 0.000570 1984 10 18 45991 0.287107 0.182517 -0.0348510 0.0014040 0.000236 0.000046 0.000811 0.000743 0.0000469 0.0000664 0.000517 0.000578 1984 10 19 45992 0.285068 0.180393 -0.0363035 0.0015442 0.000026 -0.000048 0.000808 0.000738 0.0000480 0.0000709 0.000523 0.000590 1984 10 20 45993 0.282067 0.178771 -0.0378492 0.0017906 -0.000183 -0.000142 0.000814 0.000745 0.0000532 0.0000724 0.000529 0.000605 1984 10 21 45994 0.281103 0.175622 -0.0396182 0.0021009 -0.000393 -0.000236 0.000810 0.000741 0.0000541 0.0000771 0.000535 0.000611 1984 10 22 45995 0.282777 0.170438 -0.0417183 0.0023856 -0.000710 -0.000845 0.000810 0.000739 0.0000558 0.0000825 0.000542 0.000620 1984 10 23 45996 0.283969 0.165333 -0.0442118 0.0025396 -0.001061 -0.001622 0.000819 0.000745 0.0000622 0.0000843 0.000550 0.000640 1984 10 24 45997 0.281608 0.162633 -0.0470010 0.0024941 -0.001413 -0.001624 0.000816 0.000740 0.0000633 0.0000894 0.000558 0.000640 1984 10 25 45998 0.276527 0.161885 -0.0497135 0.0022597 -0.001087 -0.000973 0.000809 0.000733 0.0000641 0.0000907 0.000563 0.000632 1984 10 26 45999 0.272298 0.160413 -0.0519418 0.0019311 -0.000425 -0.000079 0.000803 0.000727 0.0000651 0.0000920 0.000566 0.000621 1984 10 27 46000 0.270796 0.156695 -0.0535037 0.0016430 -0.000135 0.001280 0.000795 0.000720 0.0000659 0.0000932 0.000567 0.000608 1984 10 28 46001 0.270335 0.151976 -0.0546445 0.0015008 -0.000069 0.001677 0.000786 0.000711 0.0000668 0.0000945 0.000566 0.000595 1984 10 29 46002 0.268338 0.148177 -0.0558452 0.0015270 -0.000098 0.000984 0.000776 0.000702 0.0000677 0.0000950 0.000563 0.000583 1984 10 30 46003 0.264583 0.145437 -0.0574907 0.0016592 -0.000127 0.000292 0.000767 0.000694 0.0000675 0.0000954 0.000560 0.000570 1984 10 31 46004 0.261026 0.142589 -0.0595577 0.0017969 -0.000156 -0.000401 0.000757 0.000687 0.0000672 0.0000953 0.000557 0.000558 1984 11 1 46005 0.259064 0.139270 -0.0617476 0.0018618 -0.000316 -0.000581 0.000746 0.000679 0.0000673 0.0000952 0.000555 0.000544 1984 11 2 46006 0.258021 0.136247 -0.0637919 0.0018347 -0.000517 -0.000598 0.000735 0.000670 0.0000674 0.0000954 0.000553 0.000530 1984 11 3 46007 0.256406 0.133869 -0.0655561 0.0017525 -0.000718 -0.000615 0.000731 0.000666 0.0000676 0.0000955 0.000551 0.000516 1984 11 4 46008 0.253879 0.131387 -0.0670608 0.0016764 -0.000919 -0.000632 0.000735 0.000667 0.0000677 0.0000957 0.000550 0.000502 1984 11 5 46009 0.251417 0.128167 -0.0684553 0.0016543 -0.001121 -0.000649 0.000739 0.000668 0.0000678 0.0000957 0.000548 0.000490 1984 11 6 46010 0.249781 0.124640 -0.0699303 0.0016956 -0.001018 -0.000589 0.000744 0.000670 0.0000677 0.0000956 0.000546 0.000484 1984 11 7 46011 0.248382 0.121498 -0.0716047 0.0017684 -0.000814 -0.000503 0.000751 0.000673 0.0000674 0.0000954 0.000545 0.000480 1984 11 8 46012 0.245959 0.118612 -0.0734810 0.0018175 -0.000610 -0.000417 0.000758 0.000677 0.0000672 0.0000950 0.000544 0.000475 1984 11 9 46013 0.242205 0.115443 -0.0754557 0.0017918 -0.000406 -0.000331 0.000764 0.000680 0.0000670 0.0000947 0.000547 0.000471 1984 11 10 46014 0.238313 0.112106 -0.0773650 0.0016704 -0.000202 -0.000245 0.000767 0.000683 0.0000667 0.0000940 0.000545 0.000468 1984 11 11 46015 0.235644 0.109240 -0.0790527 0.0014735 -0.000444 -0.000306 0.000769 0.000684 0.0000660 0.0000932 0.000542 0.000459 1984 11 12 46016 0.234046 0.106939 -0.0804398 0.0012576 -0.000841 -0.000417 0.000767 0.000682 0.0000650 0.0000919 0.000541 0.000449 1984 11 13 46017 0.231979 0.104588 -0.0815521 0.0010962 -0.001238 -0.000529 0.000763 0.000679 0.0000640 0.0000906 0.000537 0.000440 1984 11 14 46018 0.228507 0.101871 -0.0825121 0.0010556 -0.001634 -0.000640 0.000759 0.000676 0.0000631 0.0000893 0.000533 0.000432 1984 11 15 46019 0.224693 0.099302 -0.0835056 0.0011720 -0.002031 -0.000751 0.000753 0.000674 0.0000622 0.0000879 0.000530 0.000424 1984 11 16 46020 0.222373 0.097395 -0.0847276 0.0014379 -0.001346 0.000068 0.000743 0.000671 0.0000613 0.0000865 0.000526 0.000421 1984 11 17 46021 0.221667 0.095823 -0.0863213 0.0017984 -0.000353 0.000075 0.000731 0.000665 0.0000602 0.0000851 0.000520 0.000417 1984 11 18 46022 0.220565 0.093904 -0.0883341 0.0021629 0.000015 -0.000204 0.000717 0.000657 0.0000591 0.0000836 0.000514 0.000419 1984 11 19 46023 0.217406 0.091674 -0.0907003 0.0024304 0.000027 -0.000386 0.000701 0.000647 0.0000580 0.0000821 0.000510 0.000425 1984 11 20 46024 0.213072 0.089893 -0.0932565 0.0025243 0.000039 -0.000569 0.000686 0.000637 0.0000571 0.0000812 0.000506 0.000433 1984 11 21 46025 0.209765 0.088926 -0.0957901 0.0024216 0.000091 -0.000572 0.000673 0.000626 0.0000567 0.0000804 0.000504 0.000439 1984 11 22 46026 0.207934 0.088074 -0.0981086 0.0021622 0.000158 -0.000513 0.000661 0.000615 0.0000567 0.0000801 0.000504 0.000445 1984 11 23 46027 0.205664 0.086303 -0.1000967 0.0018323 0.000224 -0.000453 0.000649 0.000605 0.0000566 0.0000800 0.000504 0.000452 1984 11 24 46028 0.201491 0.083445 -0.1017426 0.0015288 0.000291 -0.000393 0.000636 0.000593 0.0000565 0.0000800 0.000503 0.000459 1984 11 25 46029 0.196619 0.080371 -0.1031255 0.0013233 0.000358 -0.000333 0.000621 0.000579 0.0000565 0.0000795 0.000503 0.000468 1984 11 26 46030 0.193225 0.077930 -0.1043742 0.0012434 0.000379 -0.000307 0.000606 0.000564 0.0000559 0.0000788 0.000500 0.000470 1984 11 27 46031 0.191263 0.075975 -0.1056176 0.0012756 0.000385 -0.000293 0.000588 0.000545 0.0000549 0.0000777 0.000496 0.000470 1984 11 28 46032 0.188467 0.073687 -0.1069499 0.0013828 0.000391 -0.000279 0.000569 0.000526 0.0000541 0.0000765 0.000493 0.000471 1984 11 29 46033 0.183622 0.070787 -0.1084192 0.0015235 0.000396 -0.000264 0.000551 0.000509 0.0000532 0.0000753 0.000489 0.000472 1984 11 30 46034 0.178297 0.068023 -0.1100317 0.0016626 0.000402 -0.000250 0.000538 0.000495 0.0000524 0.0000748 0.000485 0.000472 1984 12 1 46035 0.174553 0.066152 -0.1117647 0.0017754 0.000333 -0.000271 0.000527 0.000483 0.0000525 0.0000745 0.000486 0.000475 1984 12 2 46036 0.172082 0.064695 -0.1135799 0.0018460 0.000240 -0.000304 0.000516 0.000470 0.0000530 0.0000750 0.000488 0.000479 1984 12 3 46037 0.168929 0.062301 -0.1154319 0.0018661 0.000146 -0.000337 0.000509 0.000462 0.0000535 0.0000757 0.000491 0.000483 1984 12 4 46038 0.164473 0.058517 -0.1172735 0.0018339 0.000053 -0.000369 0.000505 0.000458 0.0000541 0.0000765 0.000494 0.000488 1984 12 5 46039 0.160149 0.054614 -0.1190594 0.0017530 -0.000041 -0.000402 0.000500 0.000454 0.0000546 0.0000774 0.000496 0.000492 1984 12 6 46040 0.157089 0.052167 -0.1207487 0.0016319 -0.000067 -0.000371 0.000497 0.000451 0.0000554 0.0000785 0.000501 0.000495 1984 12 7 46041 0.154441 0.051141 -0.1223094 0.0014852 -0.000072 -0.000320 0.000493 0.000449 0.0000564 0.0000799 0.000507 0.000499 1984 12 8 46042 0.150740 0.050033 -0.1237253 0.0013351 -0.000076 -0.000269 0.000489 0.000447 0.0000575 0.0000814 0.000513 0.000503 1984 12 9 46043 0.145948 0.047873 -0.1250049 0.0012113 -0.000081 -0.000218 0.000489 0.000448 0.0000586 0.0000829 0.000518 0.000508 1984 12 10 46044 0.141183 0.045343 -0.1261871 0.0011454 -0.000085 -0.000166 0.000491 0.000451 0.0000597 0.0000842 0.000525 0.000513 1984 12 11 46045 0.136952 0.043651 -0.1273400 0.0011612 -0.000124 -0.000279 0.000491 0.000452 0.0000605 0.0000854 0.000529 0.000513 1984 12 12 46046 0.132719 0.042918 -0.1285485 0.0012655 -0.000173 -0.000447 0.000492 0.000452 0.0000610 0.0000863 0.000533 0.000512 1984 12 13 46047 0.128035 0.042237 -0.1298955 0.0014428 -0.000223 -0.000614 0.000494 0.000455 0.0000616 0.0000871 0.000537 0.000510 1984 12 14 46048 0.123137 0.040957 -0.1314385 0.0016567 -0.000273 -0.000781 0.000496 0.000457 0.0000622 0.0000879 0.000542 0.000508 1984 12 15 46049 0.118296 0.039251 -0.1331916 0.0018570 -0.000323 -0.000948 0.000499 0.000460 0.0000627 0.0000882 0.000546 0.000506 1984 12 16 46050 0.113355 0.037473 -0.1351160 0.0019903 -0.000244 -0.000981 0.000499 0.000460 0.0000626 0.0000884 0.000548 0.000498 1984 12 17 46051 0.108225 0.035606 -0.1371234 0.0020143 -0.000121 -0.000969 0.000497 0.000458 0.0000622 0.0000880 0.000549 0.000487 1984 12 18 46052 0.103196 0.033564 -0.1390943 0.0019113 0.000001 -0.000958 0.000498 0.000460 0.0000619 0.0000875 0.000550 0.000477 1984 12 19 46053 0.098354 0.031590 -0.1409083 0.0016983 0.000123 -0.000946 0.000502 0.000466 0.0000615 0.0000871 0.000551 0.000467 1984 12 20 46054 0.093209 0.030051 -0.1424781 0.0014255 0.000245 -0.000934 0.000506 0.000473 0.0000612 0.0000864 0.000552 0.000459 1984 12 21 46055 0.087365 0.029021 -0.1437756 0.0011612 0.000283 -0.000859 0.000511 0.000481 0.0000607 0.0000858 0.000552 0.000448 1984 12 22 46056 0.081231 0.028279 -0.1448388 0.0009689 0.000291 -0.000761 0.000516 0.000490 0.0000601 0.0000850 0.000551 0.000436 1984 12 23 46057 0.075617 0.027537 -0.1457574 0.0008864 0.000299 -0.000663 0.000521 0.000499 0.0000595 0.0000847 0.000550 0.000426 1984 12 24 46058 0.070872 0.026544 -0.1466447 0.0009178 0.000232 -0.000651 0.000527 0.000509 0.0000597 0.0000851 0.000552 0.000419 1984 12 25 46059 0.066795 0.025200 -0.1476070 0.0010399 0.000094 -0.000720 0.000535 0.000520 0.0000608 0.0000861 0.000556 0.000416 1984 12 26 46060 0.063135 0.023782 -0.1487220 0.0012157 -0.000044 -0.000790 0.000542 0.000532 0.0000620 0.0000878 0.000560 0.000412 1984 12 27 46061 0.059682 0.022852 -0.1500295 0.0014080 -0.000182 -0.000859 0.000553 0.000545 0.0000633 0.0000896 0.000564 0.000409 1984 12 28 46062 0.056073 0.022675 -0.1515312 0.0015856 -0.000320 -0.000929 0.000567 0.000559 0.0000647 0.0000915 0.000569 0.000405 1984 12 29 46063 0.052110 0.022879 -0.1531968 0.0017250 -0.000458 -0.000999 0.000583 0.000575 0.0000660 0.0000934 0.000573 0.000402 1984 12 30 46064 0.048204 0.022919 -0.1549751 0.0018112 -0.000596 -0.001068 0.000601 0.000592 0.0000674 0.0000953 0.000577 0.000399 1984 12 31 46065 0.044936 0.022708 -0.1568080 0.0018380 -0.000475 -0.000966 0.000616 0.000607 0.0000686 0.0000971 0.000581 0.000399 1985 1 1 46066 0.041725 0.022466 -0.1585983 0.0018421 0.000347 -0.000328 0.000280 0.000246 0.0000377 0.0000534 0.000278 0.000299 1985 1 2 46067 0.038971 0.022434 -0.1604066 0.0017731 0.000367 -0.000314 0.000285 0.000251 0.0000381 0.0000538 0.000279 0.000298 1985 1 3 46068 0.035505 0.022514 -0.1621330 0.0016616 0.000386 -0.000301 0.000288 0.000254 0.0000384 0.0000543 0.000279 0.000298 1985 1 4 46069 0.030948 0.022283 -0.1637405 0.0015253 0.000406 -0.000288 0.000290 0.000256 0.0000387 0.0000545 0.000280 0.000297 1985 1 5 46070 0.027658 0.023071 -0.1652107 0.0013928 0.000453 -0.000315 0.000295 0.000260 0.0000387 0.0000547 0.000279 0.000294 1985 1 6 46071 0.024427 0.024053 -0.1665625 0.0013025 0.000511 -0.000355 0.000302 0.000267 0.0000386 0.0000546 0.000278 0.000291 1985 1 7 46072 0.019750 0.024064 -0.1678569 0.0012931 0.000568 -0.000395 0.000308 0.000273 0.0000385 0.0000544 0.000277 0.000287 1985 1 8 46073 0.014925 0.024189 -0.1691877 0.0013878 0.000625 -0.000435 0.000314 0.000280 0.0000384 0.0000543 0.000276 0.000284 1985 1 9 46074 0.010130 0.024301 -0.1706572 0.0015807 0.000683 -0.000475 0.000320 0.000287 0.0000383 0.0000542 0.000275 0.000281 1985 1 10 46075 0.006064 0.025122 -0.1723469 0.0018330 0.000352 -0.000360 0.000326 0.000293 0.0000382 0.0000541 0.000274 0.000277 1985 1 11 46076 0.003357 0.027377 -0.1742897 0.0020833 -0.000106 -0.000194 0.000333 0.000300 0.0000383 0.0000542 0.000273 0.000273 1985 1 12 46077 -0.000380 0.028703 -0.1764572 0.0022661 -0.000565 -0.000029 0.000339 0.000306 0.0000384 0.0000543 0.000273 0.000270 1985 1 13 46078 -0.005307 0.029047 -0.1787633 0.0023314 -0.001023 0.000137 0.000345 0.000312 0.0000385 0.0000545 0.000272 0.000267 1985 1 14 46079 -0.008807 0.029875 -0.1810820 0.0022580 -0.000997 0.000303 0.000352 0.000319 0.0000386 0.0000543 0.000269 0.000264 1985 1 15 46080 -0.011500 0.030616 -0.1832752 0.0020588 -0.000710 0.001053 0.000360 0.000325 0.0000383 0.0000539 0.000266 0.000261 1985 1 16 46081 -0.014754 0.031472 -0.1852262 0.0017778 -0.000378 0.002000 0.000366 0.000330 0.0000376 0.0000534 0.000263 0.000258 1985 1 17 46082 -0.017499 0.032353 -0.1868702 0.0014789 -0.000047 0.001365 0.000372 0.000335 0.0000373 0.0000527 0.000261 0.000252 1985 1 18 46083 -0.019967 0.033627 -0.1882141 0.0012288 0.000284 0.000401 0.000379 0.000340 0.0000369 0.0000522 0.000258 0.000245 1985 1 19 46084 -0.022987 0.036573 -0.1893343 0.0010779 0.000615 -0.000563 0.000383 0.000343 0.0000366 0.0000516 0.000256 0.000240 1985 1 20 46085 -0.025776 0.038857 -0.1903535 0.0010457 0.000678 -0.000676 0.000387 0.000346 0.0000360 0.0000509 0.000252 0.000233 1985 1 21 46086 -0.029213 0.039047 -0.1914033 0.0011179 0.000654 -0.000512 0.000390 0.000349 0.0000354 0.0000501 0.000248 0.000227 1985 1 22 46087 -0.033438 0.039930 -0.1925839 0.0012559 0.000629 -0.000348 0.000393 0.000352 0.0000349 0.0000493 0.000245 0.000221 1985 1 23 46088 -0.035724 0.042534 -0.1939399 0.0014125 0.000604 -0.000184 0.000396 0.000354 0.0000343 0.0000486 0.000242 0.000216 1985 1 24 46089 -0.038097 0.045418 -0.1954577 0.0015470 0.000580 -0.000019 0.000401 0.000355 0.0000339 0.0000480 0.000239 0.000212 1985 1 25 46090 -0.043733 0.046911 -0.1970825 0.0016337 -0.000346 0.000074 0.000405 0.000355 0.0000335 0.0000477 0.000236 0.000207 1985 1 26 46091 -0.048643 0.047120 -0.1987339 0.0016626 -0.000230 0.000191 0.000406 0.000354 0.0000336 0.0000476 0.000234 0.000203 1985 1 27 46092 -0.051244 0.048060 -0.2003538 0.0016355 -0.000050 0.000110 0.000407 0.000354 0.0000337 0.0000477 0.000234 0.000204 1985 1 28 46093 -0.055341 0.049714 -0.2019152 0.0015602 -0.000219 -0.000121 0.000408 0.000353 0.0000339 0.0000480 0.000237 0.000208 1985 1 29 46094 -0.060387 0.051573 -0.2034016 0.0014456 -0.000387 -0.000351 0.000406 0.000350 0.0000341 0.0000479 0.000240 0.000212 1985 1 30 46095 -0.063690 0.053461 -0.2047910 0.0013001 -0.000357 -0.000415 0.000403 0.000345 0.0000338 0.0000477 0.000241 0.000215 1985 1 31 46096 -0.065506 0.054038 -0.2060463 0.0011348 -0.000262 -0.000423 0.000399 0.000340 0.0000333 0.0000471 0.000242 0.000216 1985 2 1 46097 -0.067723 0.054787 -0.2071314 0.0009699 -0.000166 -0.000432 0.000394 0.000333 0.0000329 0.0000465 0.000243 0.000217 1985 2 2 46098 -0.070525 0.056827 -0.2080417 0.0008391 -0.000071 -0.000441 0.000387 0.000326 0.0000324 0.0000459 0.000244 0.000219 1985 2 3 46099 -0.071976 0.058438 -0.2088285 0.0007856 0.000024 -0.000449 0.000380 0.000318 0.0000320 0.0000450 0.000245 0.000221 1985 2 4 46100 -0.074242 0.060516 -0.2096021 0.0008454 0.000116 -0.000473 0.000373 0.000311 0.0000311 0.0000440 0.000244 0.000220 1985 2 5 46101 -0.078054 0.062690 -0.2105053 0.0010267 0.000207 -0.000502 0.000368 0.000305 0.0000301 0.0000427 0.000243 0.000218 1985 2 6 46102 -0.078789 0.063419 -0.2116624 0.0012967 0.000298 -0.000531 0.000362 0.000299 0.0000292 0.0000414 0.000242 0.000216 1985 2 7 46103 -0.080101 0.064947 -0.2131292 0.0015874 0.000389 -0.000559 0.000356 0.000293 0.0000284 0.0000402 0.000241 0.000214 1985 2 8 46104 -0.084458 0.066943 -0.2148688 0.0018204 0.000480 -0.000588 0.000350 0.000288 0.0000276 0.0000396 0.000240 0.000211 1985 2 9 46105 -0.084915 0.068317 -0.2167681 0.0019386 0.000453 -0.000529 0.000346 0.000285 0.0000276 0.0000393 0.000241 0.000213 1985 2 10 46106 -0.085568 0.071174 -0.2186868 0.0019253 0.000382 -0.000437 0.000343 0.000282 0.0000280 0.0000395 0.000242 0.000216 1985 2 11 46107 -0.090653 0.074281 -0.2205084 0.0018040 0.000311 -0.000346 0.000337 0.000274 0.0000283 0.0000400 0.000244 0.000219 1985 2 12 46108 -0.092910 0.076533 -0.2221718 0.0016210 0.000240 -0.000255 0.000332 0.000269 0.0000287 0.0000405 0.000246 0.000223 1985 2 13 46109 -0.094889 0.079323 -0.2236732 0.0014236 0.000169 -0.000163 0.000326 0.000264 0.0000290 0.0000408 0.000248 0.000227 1985 2 14 46110 -0.099145 0.081664 -0.2250419 0.0012478 0.000171 -0.000137 0.000319 0.000256 0.0000291 0.0000410 0.000248 0.000228 1985 2 15 46111 -0.100593 0.083725 -0.2263070 0.0011166 0.000197 -0.000133 0.000314 0.000251 0.0000290 0.0000410 0.000248 0.000228 1985 2 16 46112 -0.103330 0.086346 -0.2274864 0.0010472 0.000223 -0.000129 0.000308 0.000246 0.0000289 0.0000408 0.000248 0.000228 1985 2 17 46113 -0.107651 0.088605 -0.2285987 0.0010568 0.000249 -0.000125 0.000302 0.000240 0.0000288 0.0000407 0.000249 0.000228 1985 2 18 46114 -0.109646 0.090637 -0.2296844 0.0011615 0.000275 -0.000121 0.000294 0.000233 0.0000287 0.0000405 0.000249 0.000228 1985 2 19 46115 -0.114006 0.092131 -0.2308259 0.0013667 0.000318 -0.000125 0.000291 0.000229 0.0000284 0.0000401 0.000248 0.000227 1985 2 20 46116 -0.118479 0.093751 -0.2321556 0.0016530 0.000366 -0.000131 0.000290 0.000223 0.0000281 0.0000397 0.000247 0.000225 1985 2 21 46117 -0.120188 0.096540 -0.2338113 0.0019667 0.000414 -0.000137 0.000288 0.000219 0.0000277 0.0000392 0.000246 0.000223 1985 2 22 46118 -0.124725 0.098297 -0.2358669 0.0022242 0.000462 -0.000144 0.000288 0.000216 0.0000274 0.0000388 0.000245 0.000221 1985 2 23 46119 -0.129845 0.099785 -0.2382733 0.0023359 0.000510 -0.000150 0.000289 0.000213 0.0000271 0.0000382 0.000245 0.000220 1985 2 24 46120 -0.133066 0.102695 -0.2408350 0.0022424 0.000474 -0.000168 0.000291 0.000212 0.0000267 0.0000377 0.000243 0.000217 1985 2 25 46121 -0.137160 0.104501 -0.2432288 0.0019476 0.000410 -0.000190 0.000295 0.000211 0.0000262 0.0000371 0.000241 0.000214 1985 2 26 46122 -0.140439 0.106504 -0.2451307 0.0015293 0.000346 -0.000211 0.000301 0.000211 0.0000258 0.0000365 0.000240 0.000211 1985 2 27 46123 -0.142566 0.110382 -0.2463670 0.0011150 0.000282 -0.000233 0.000305 0.000209 0.0000254 0.0000359 0.000239 0.000209 1985 2 28 46124 -0.144789 0.112779 -0.2470021 0.0008325 0.000217 -0.000255 0.000309 0.000207 0.0000250 0.0000354 0.000237 0.000206 1985 3 1 46125 -0.149562 0.114414 -0.2473375 0.0007581 -0.001299 0.000453 0.000313 0.000205 0.0000247 0.0000350 0.000236 0.000204 1985 3 2 46126 -0.158007 0.117788 -0.2479081 0.0008896 -0.003340 0.001424 0.000315 0.000202 0.0000245 0.0000344 0.000235 0.000203 1985 3 3 46127 -0.161548 0.121180 -0.2491476 0.0011617 -0.002524 0.001274 0.000317 0.000198 0.0000239 0.0000338 0.000233 0.000199 1985 3 4 46128 -0.159833 0.123838 -0.2509518 0.0014932 -0.001335 0.000978 0.000317 0.000193 0.0000233 0.0000330 0.000231 0.000195 1985 3 5 46129 -0.161279 0.126517 -0.2529485 0.0018290 -0.000147 0.000681 0.000317 0.000189 0.0000227 0.0000321 0.000229 0.000191 1985 3 6 46130 -0.162834 0.129348 -0.2548401 0.0021451 0.000298 -0.000015 0.000315 0.000184 0.0000221 0.0000316 0.000227 0.000188 1985 3 7 46131 -0.165125 0.132265 -0.2568150 0.0024199 0.000424 -0.000653 0.000313 0.000180 0.0000219 0.0000314 0.000227 0.000188 1985 3 8 46132 -0.171910 0.134835 -0.2591416 0.0026115 0.000403 -0.000986 0.000312 0.000177 0.0000223 0.0000316 0.000229 0.000190 1985 3 9 46133 -0.175568 0.137452 -0.2617844 0.0026698 0.000865 -0.001319 0.000311 0.000174 0.0000228 0.0000323 0.000229 0.000193 1985 3 10 46134 -0.175683 0.141145 -0.2645506 0.0025722 0.001386 -0.001651 0.000309 0.000170 0.0000233 0.0000330 0.000230 0.000196 1985 3 11 46135 -0.177041 0.146020 -0.2671734 0.0023474 0.001566 -0.000750 0.000306 0.000167 0.0000239 0.0000336 0.000230 0.000199 1985 3 12 46136 -0.178909 0.150008 -0.2694403 0.0020688 0.000920 -0.000229 0.000301 0.000162 0.0000242 0.0000341 0.000230 0.000200 1985 3 13 46137 -0.183721 0.151337 -0.2713211 0.0018224 0.000005 0.000029 0.000295 0.000157 0.0000243 0.0000344 0.000229 0.000201 1985 3 14 46138 -0.188044 0.153218 -0.2729473 0.0016702 -0.000909 0.000287 0.000287 0.000152 0.0000245 0.0000347 0.000229 0.000201 1985 3 15 46139 -0.186988 0.157820 -0.2745129 0.0016300 -0.000598 0.000411 0.000280 0.000147 0.0000247 0.0000349 0.000227 0.000199 1985 3 16 46140 -0.186915 0.162109 -0.2761776 0.0016788 -0.000298 0.000303 0.000271 0.000142 0.0000249 0.0000351 0.000225 0.000197 1985 3 17 46141 -0.189325 0.165908 -0.2779932 0.0017739 -0.000073 0.000127 0.000263 0.000137 0.0000250 0.0000354 0.000224 0.000195 1985 3 18 46142 -0.190885 0.170640 -0.2799214 0.0018771 0.000152 -0.000049 0.000255 0.000133 0.0000251 0.0000356 0.000223 0.000192 1985 3 19 46143 -0.192860 0.174961 -0.2818953 0.0019691 0.000376 -0.000225 0.000248 0.000129 0.0000253 0.0000358 0.000221 0.000190 1985 3 20 46144 -0.194801 0.178994 -0.2838732 0.0020484 0.000601 -0.000401 0.000240 0.000124 0.0000255 0.0000361 0.000220 0.000188 1985 3 21 46145 -0.197049 0.183123 -0.2858628 0.0021200 -0.000952 -0.000172 0.000233 0.000120 0.0000257 0.0000363 0.000219 0.000186 1985 3 22 46146 -0.198933 0.186934 -0.2879111 0.0021815 -0.001255 -0.000154 0.000226 0.000116 0.0000259 0.0000367 0.000219 0.000187 1985 3 23 46147 -0.197981 0.190983 -0.2900572 0.0022165 -0.000697 -0.000298 0.000219 0.000113 0.0000262 0.0000371 0.000220 0.000191 1985 3 24 46148 -0.197858 0.194685 -0.2922886 0.0021999 -0.000139 -0.000441 0.000212 0.000109 0.0000265 0.0000376 0.000221 0.000195 1985 3 25 46149 -0.199372 0.198159 -0.2945298 0.0021115 0.000419 -0.000585 0.000206 0.000105 0.0000269 0.0000379 0.000222 0.000200 1985 3 26 46150 -0.199070 0.202377 -0.2966650 0.0019492 0.000610 -0.000597 0.000199 0.000102 0.0000270 0.0000382 0.000222 0.000203 1985 3 27 46151 -0.198521 0.206484 -0.2985818 0.0017355 0.000675 -0.000564 0.000192 0.000098 0.0000271 0.0000383 0.000222 0.000207 1985 3 28 46152 -0.198281 0.210480 -0.3002192 0.0015151 0.000740 -0.000531 0.000186 0.000094 0.0000271 0.0000384 0.000222 0.000210 1985 3 29 46153 -0.198158 0.214692 -0.3015988 0.0013454 0.000805 -0.000498 0.000179 0.000090 0.0000272 0.0000384 0.000222 0.000214 1985 3 30 46154 -0.199646 0.218665 -0.3028262 0.0012830 0.000871 -0.000465 0.000173 0.000087 0.0000272 0.0000385 0.000222 0.000218 1985 3 31 46155 -0.200656 0.222762 -0.3040675 0.0013668 0.000862 -0.000449 0.000167 0.000083 0.0000273 0.0000386 0.000221 0.000222 1985 4 1 46156 -0.200559 0.226637 -0.3055037 0.0016004 0.000830 -0.000439 0.000160 0.000080 0.0000274 0.0000387 0.000221 0.000226 1985 4 2 46157 -0.201173 0.230704 -0.3072772 0.0019397 0.000798 -0.000429 0.000156 0.000078 0.0000275 0.0000389 0.000221 0.000230 1985 4 3 46158 -0.201940 0.235418 -0.3094422 0.0022962 0.000766 -0.000419 0.000153 0.000077 0.0000276 0.0000390 0.000221 0.000235 1985 4 4 46159 -0.202745 0.238977 -0.3119386 0.0025616 0.000733 -0.000408 0.000150 0.000076 0.0000276 0.0000389 0.000221 0.000240 1985 4 5 46160 -0.203293 0.242316 -0.3146036 0.0026481 0.000730 -0.000430 0.000149 0.000075 0.0000275 0.0000389 0.000220 0.000243 1985 4 6 46161 -0.202459 0.246632 -0.3172230 0.0025262 0.000736 -0.000461 0.000149 0.000075 0.0000274 0.0000387 0.000218 0.000245 1985 4 7 46162 -0.201307 0.250064 -0.3196018 0.0022385 0.000741 -0.000493 0.000148 0.000075 0.0000272 0.0000385 0.000217 0.000248 1985 4 8 46163 -0.201375 0.253822 -0.3216283 0.0018810 0.000747 -0.000525 0.000148 0.000075 0.0000271 0.0000383 0.000216 0.000250 1985 4 9 46164 -0.202130 0.258319 -0.3233029 0.0015624 0.000753 -0.000557 0.000149 0.000076 0.0000269 0.0000380 0.000215 0.000253 1985 4 10 46165 -0.201959 0.261436 -0.3247233 0.0013621 0.000692 -0.000499 0.000148 0.000076 0.0000267 0.0000377 0.000213 0.000254 1985 4 11 46166 -0.201334 0.265241 -0.3260358 0.0013088 0.000607 -0.000409 0.000150 0.000077 0.0000264 0.0000374 0.000212 0.000254 1985 4 12 46167 -0.201118 0.269889 -0.3273830 0.0013838 0.000522 -0.000319 0.000153 0.000079 0.0000261 0.0000370 0.000210 0.000254 1985 4 13 46168 -0.199944 0.273143 -0.3288653 0.0015416 0.000437 -0.000229 0.000156 0.000080 0.0000259 0.0000367 0.000208 0.000254 1985 4 14 46169 -0.198794 0.277237 -0.3305294 0.0017325 0.000352 -0.000139 0.000161 0.000083 0.0000257 0.0000363 0.000207 0.000254 1985 4 15 46170 -0.198988 0.281736 -0.3323757 0.0019169 0.000400 -0.000171 0.000168 0.000087 0.0000255 0.0000360 0.000205 0.000253 1985 4 16 46171 -0.198516 0.284393 -0.3343764 0.0020683 0.000492 -0.000243 0.000174 0.000091 0.0000253 0.0000358 0.000204 0.000252 1985 4 17 46172 -0.197603 0.287745 -0.3364902 0.0021710 0.000584 -0.000315 0.000181 0.000095 0.0000251 0.0000355 0.000203 0.000251 1985 4 18 46173 -0.197391 0.291590 -0.3386698 0.0022157 0.000676 -0.000388 0.000188 0.000099 0.0000249 0.0000352 0.000201 0.000250 1985 4 19 46174 -0.197123 0.294127 -0.3408647 0.0021979 0.000768 -0.000460 0.000194 0.000103 0.0000247 0.0000352 0.000200 0.000250 1985 4 20 46175 -0.196793 0.297871 -0.3430210 0.0021181 0.000822 -0.000454 0.000201 0.000108 0.0000249 0.0000353 0.000200 0.000250 1985 4 21 46176 -0.196257 0.302414 -0.3450841 0.0019844 0.000863 -0.000418 0.000209 0.000113 0.0000251 0.0000355 0.000200 0.000251 1985 4 22 46177 -0.196005 0.305241 -0.3470047 0.0018135 0.000904 -0.000383 0.000216 0.000118 0.0000253 0.0000358 0.000201 0.000252 1985 4 23 46178 -0.195959 0.308188 -0.3487487 0.0016311 0.000944 -0.000348 0.000223 0.000123 0.0000256 0.0000362 0.000201 0.000253 1985 4 24 46179 -0.195140 0.312372 -0.3503086 0.0014684 0.000985 -0.000312 0.000231 0.000129 0.0000258 0.0000365 0.000201 0.000253 1985 4 25 46180 -0.195180 0.316456 -0.3517108 0.0013574 0.000626 -0.000507 0.000239 0.000134 0.0000261 0.0000369 0.000201 0.000254 1985 4 26 46181 -0.195149 0.320600 -0.3530139 0.0013263 0.000493 -0.000601 0.000247 0.000140 0.0000264 0.0000372 0.000201 0.000254 1985 4 27 46182 -0.194076 0.324574 -0.3543241 0.0013947 0.000504 -0.000624 0.000255 0.000146 0.0000265 0.0000375 0.000201 0.000253 1985 4 28 46183 -0.195370 0.327494 -0.3557748 0.0015664 0.000515 -0.000647 0.000263 0.000152 0.0000267 0.0000377 0.000201 0.000252 1985 4 29 46184 -0.196487 0.330605 -0.3574836 0.0018226 0.000525 -0.000671 0.000271 0.000159 0.0000268 0.0000379 0.000201 0.000251 1985 4 30 46185 -0.195169 0.334521 -0.3595124 0.0021171 0.000316 -0.000275 0.000278 0.000165 0.0000269 0.0000380 0.000200 0.000249 1985 5 1 46186 -0.195019 0.337520 -0.3618269 0.0023823 0.000035 0.000257 0.000285 0.000171 0.0000269 0.0000376 0.000199 0.000247 1985 5 2 46187 -0.193182 0.340284 -0.3643125 0.0025469 -0.000245 0.000788 0.000289 0.000176 0.0000263 0.0000376 0.000199 0.000243 1985 5 3 46188 -0.189066 0.345185 -0.3668173 0.0025616 -0.000526 0.001320 0.000293 0.000182 0.0000262 0.0000369 0.000198 0.000241 1985 5 4 46189 -0.187589 0.350160 -0.3692100 0.0024196 0.000405 0.000798 0.000296 0.000186 0.0000260 0.0000367 0.000197 0.000238 1985 5 5 46190 -0.186474 0.352895 -0.3714901 0.0021599 0.000413 0.000654 0.000298 0.000190 0.0000257 0.0000363 0.000195 0.000234 1985 5 6 46191 -0.184690 0.355983 -0.3735758 0.0018543 0.000066 0.000690 0.000299 0.000194 0.0000253 0.0000359 0.000194 0.000230 1985 5 7 46192 -0.183464 0.359658 -0.3753531 0.0015818 -0.000281 0.000727 0.000300 0.000198 0.0000251 0.0000353 0.000193 0.000227 1985 5 8 46193 -0.181192 0.362098 -0.3768093 0.0014004 0.000224 0.000257 0.000299 0.000202 0.0000246 0.0000347 0.000191 0.000223 1985 5 9 46194 -0.180611 0.366220 -0.3781552 0.0013290 0.000524 -0.000613 0.000298 0.000204 0.0000241 0.0000341 0.000189 0.000219 1985 5 10 46195 -0.180665 0.371500 -0.3795397 0.0013517 0.000420 -0.000585 0.000295 0.000206 0.0000236 0.0000335 0.000188 0.000214 1985 5 11 46196 -0.177909 0.373716 -0.3809355 0.0014376 0.000135 -0.000055 0.000294 0.000209 0.0000234 0.0000333 0.000188 0.000212 1985 5 12 46197 -0.176429 0.376537 -0.3823757 0.0015578 -0.000257 0.000727 0.000294 0.000213 0.0000235 0.0000333 0.000189 0.000213 1985 5 13 46198 -0.175242 0.382136 -0.3840330 0.0016880 -0.000649 0.001509 0.000294 0.000217 0.0000237 0.0000333 0.000190 0.000215 1985 5 14 46199 -0.171903 0.385383 -0.3858876 0.0018058 0.000526 -0.000131 0.000292 0.000220 0.0000236 0.0000332 0.000190 0.000214 1985 5 15 46200 -0.170364 0.387419 -0.3870855 0.0018844 0.001240 -0.000903 0.000289 0.000222 0.0000234 0.0000329 0.000190 0.000212 1985 5 16 46201 -0.168287 0.390990 -0.3891764 0.0018787 0.000705 -0.000275 0.000283 0.000222 0.0000229 0.0000325 0.000189 0.000208 1985 5 17 46202 -0.164401 0.393263 -0.3916477 0.0017491 0.000307 -0.000072 0.000281 0.000223 0.0000226 0.0000320 0.000188 0.000207 1985 5 18 46203 -0.163433 0.395203 -0.3934148 0.0015164 0.000187 -0.000290 0.000282 0.000224 0.0000224 0.0000316 0.000188 0.000209 1985 5 19 46204 -0.162907 0.398350 -0.3945485 0.0012600 0.000068 -0.000508 0.000283 0.000225 0.0000221 0.0000313 0.000189 0.000210 1985 5 20 46205 -0.159945 0.400706 -0.3953772 0.0010654 0.000069 -0.000579 0.000283 0.000226 0.0000218 0.0000309 0.000189 0.000211 1985 5 21 46206 -0.156342 0.403125 -0.3961961 0.0009770 0.000114 -0.000596 0.000284 0.000227 0.0000215 0.0000305 0.000190 0.000212 1985 5 22 46207 -0.152072 0.406156 -0.3971749 0.0009870 0.000159 -0.000614 0.000284 0.000229 0.0000212 0.0000300 0.000191 0.000213 1985 5 23 46208 -0.148414 0.409043 -0.3983566 0.0010571 0.000204 -0.000631 0.000283 0.000228 0.0000209 0.0000296 0.000192 0.000214 1985 5 24 46209 -0.146102 0.412421 -0.3996685 0.0011513 0.000249 -0.000649 0.000280 0.000227 0.0000206 0.0000291 0.000192 0.000215 1985 5 25 46210 -0.142922 0.415069 -0.4010042 0.0012598 0.000248 -0.000625 0.000277 0.000227 0.0000202 0.0000285 0.000193 0.000215 1985 5 26 46211 -0.139239 0.417033 -0.4023326 0.0013981 0.000231 -0.000587 0.000273 0.000224 0.0000197 0.0000279 0.000194 0.000214 1985 5 27 46212 -0.136633 0.419921 -0.4037180 0.0015844 0.000214 -0.000550 0.000269 0.000221 0.0000193 0.0000273 0.000194 0.000214 1985 5 28 46213 -0.134602 0.422653 -0.4052749 0.0018119 0.000197 -0.000512 0.000263 0.000217 0.0000188 0.0000266 0.000195 0.000213 1985 5 29 46214 -0.132157 0.425182 -0.4070982 0.0020345 0.000181 -0.000474 0.000257 0.000213 0.0000184 0.0000259 0.000195 0.000212 1985 5 30 46215 -0.129749 0.427523 -0.4091944 0.0021787 0.000400 -0.000541 0.000251 0.000208 0.0000178 0.0000252 0.000195 0.000209 1985 5 31 46216 -0.127893 0.429078 -0.4114455 0.0021799 0.000698 -0.000642 0.000244 0.000203 0.0000172 0.0000243 0.000195 0.000206 1985 6 1 46217 -0.125251 0.432048 -0.4136513 0.0020191 0.000794 -0.000524 0.000239 0.000198 0.0000166 0.0000235 0.000195 0.000206 1985 6 2 46218 -0.122122 0.435442 -0.4156155 0.0017405 0.000817 -0.000326 0.000235 0.000193 0.0000161 0.0000228 0.000195 0.000206 1985 6 3 46219 -0.119840 0.436869 -0.4172262 0.0014344 0.000840 -0.000127 0.000231 0.000189 0.0000156 0.0000219 0.000196 0.000206 1985 6 4 46220 -0.117246 0.439118 -0.4184984 0.0011970 0.000784 -0.000119 0.000226 0.000184 0.0000150 0.0000212 0.000195 0.000205 1985 6 5 46221 -0.114547 0.442564 -0.4195618 0.0010888 0.000699 -0.000182 0.000221 0.000179 0.0000143 0.0000203 0.000194 0.000203 1985 6 6 46222 -0.112684 0.444567 -0.4205946 0.0011144 0.000614 -0.000245 0.000216 0.000173 0.0000138 0.0000195 0.000193 0.000201 1985 6 7 46223 -0.110439 0.445862 -0.4217443 0.0012308 0.000529 -0.000308 0.000212 0.000170 0.0000133 0.0000188 0.000193 0.000199 1985 6 8 46224 -0.107837 0.447594 -0.4230776 0.0013750 0.000443 -0.000371 0.000210 0.000169 0.0000128 0.0000181 0.000192 0.000197 1985 6 9 46225 -0.105564 0.450032 -0.4245733 0.0014917 0.000450 -0.000389 0.000207 0.000166 0.0000124 0.0000175 0.000192 0.000194 1985 6 10 46226 -0.103557 0.453003 -0.4261517 0.0015495 0.000488 -0.000391 0.000204 0.000164 0.0000119 0.0000169 0.000192 0.000192 1985 6 11 46227 -0.101828 0.455319 -0.4277202 0.0015421 0.000527 -0.000393 0.000200 0.000160 0.0000115 0.0000163 0.000191 0.000190 1985 6 12 46228 -0.099913 0.456669 -0.4292115 0.0014795 0.000565 -0.000394 0.000196 0.000157 0.0000111 0.0000158 0.000191 0.000187 1985 6 13 46229 -0.097972 0.457522 -0.4305959 0.0013786 0.000603 -0.000396 0.000192 0.000155 0.0000108 0.0000152 0.000191 0.000185 1985 6 14 46230 -0.095956 0.459127 -0.4318710 0.0012549 0.000640 -0.000445 0.000188 0.000153 0.0000104 0.0000147 0.000190 0.000182 1985 6 15 46231 -0.093786 0.461508 -0.4330398 0.0011202 0.000675 -0.000510 0.000183 0.000151 0.0000100 0.0000142 0.000189 0.000178 1985 6 16 46232 -0.092121 0.462747 -0.4340979 0.0009833 0.000711 -0.000576 0.000179 0.000148 0.0000097 0.0000137 0.000188 0.000174 1985 6 17 46233 -0.089561 0.464166 -0.4350361 0.0008541 0.000747 -0.000641 0.000174 0.000145 0.0000094 0.0000133 0.000187 0.000171 1985 6 18 46234 -0.086480 0.466645 -0.4358533 0.0007479 0.000782 -0.000707 0.000169 0.000142 0.0000091 0.0000129 0.000186 0.000168 1985 6 19 46235 -0.084805 0.467645 -0.4365762 0.0006852 -0.000031 -0.000060 0.000164 0.000139 0.0000088 0.0000124 0.000184 0.000164 1985 6 20 46236 -0.081726 0.468359 -0.4372967 0.0006877 0.000280 -0.000083 0.000159 0.000135 0.0000084 0.0000122 0.000183 0.000159 1985 6 21 46237 -0.077302 0.470225 -0.4380454 0.0007724 0.000703 -0.000387 0.000158 0.000134 0.0000084 0.0000121 0.000182 0.000158 1985 6 22 46238 -0.075093 0.471590 -0.4388673 0.0009431 0.000738 -0.000619 0.000161 0.000136 0.0000087 0.0000123 0.000182 0.000161 1985 6 23 46239 -0.072773 0.473077 -0.4398698 0.0011829 0.000773 -0.000851 0.000165 0.000139 0.0000090 0.0000127 0.000181 0.000164 1985 6 24 46240 -0.069137 0.474566 -0.4411425 0.0014498 0.000845 -0.000874 0.000168 0.000140 0.0000093 0.0000132 0.000181 0.000166 1985 6 25 46241 -0.066541 0.475021 -0.4427038 0.0016825 0.000930 -0.000826 0.000171 0.000141 0.0000096 0.0000136 0.000182 0.000168 1985 6 26 46242 -0.063703 0.475818 -0.4444856 0.0018151 0.001015 -0.000779 0.000174 0.000143 0.0000100 0.0000141 0.000182 0.000170 1985 6 27 46243 -0.059888 0.477054 -0.4463466 0.0017990 0.001100 -0.000731 0.000176 0.000143 0.0000104 0.0000147 0.000182 0.000173 1985 6 28 46244 -0.056373 0.478460 -0.4481080 0.0016229 0.001186 -0.000684 0.000178 0.000143 0.0000108 0.0000152 0.000182 0.000176 1985 6 29 46245 -0.052927 0.480026 -0.4496067 0.0013228 0.001154 -0.000585 0.000179 0.000143 0.0000112 0.0000158 0.000181 0.000177 1985 6 30 46246 -0.049658 0.480755 -0.4507502 0.0009736 0.001084 -0.000470 0.000179 0.000142 0.0000115 0.0000163 0.000180 0.000177 1985 7 1 46247 -0.046908 0.481763 0.5484588 0.0006624 0.001013 -0.000354 0.000179 0.000141 0.0000119 0.0000169 0.000179 0.000177 1985 7 2 46248 -0.044134 0.483272 0.5479327 0.0004565 0.000943 -0.000239 0.000179 0.000139 0.0000123 0.0000175 0.000178 0.000178 1985 7 3 46249 -0.040997 0.483989 0.5475381 0.0003799 0.000872 -0.000123 0.000179 0.000138 0.0000128 0.0000181 0.000177 0.000178 1985 7 4 46250 -0.038437 0.484801 0.5471462 0.0004120 0.000795 -0.000135 0.000179 0.000137 0.0000132 0.0000187 0.000176 0.000177 1985 7 5 46251 -0.036754 0.485408 0.5466743 0.0005053 0.000716 -0.000189 0.000179 0.000136 0.0000136 0.0000192 0.000175 0.000177 1985 7 6 46252 -0.033749 0.485878 0.5460971 0.0006101 0.000637 -0.000243 0.000179 0.000135 0.0000140 0.0000198 0.000174 0.000176 1985 7 7 46253 -0.029767 0.487346 0.5454336 0.0006919 0.000558 -0.000297 0.000179 0.000134 0.0000144 0.0000204 0.000173 0.000175 1985 7 8 46254 -0.026778 0.487718 0.5447233 0.0007356 0.000509 -0.000382 0.000179 0.000134 0.0000148 0.0000209 0.000172 0.000176 1985 7 9 46255 -0.023126 0.487388 0.5440038 0.0007391 0.000457 -0.000431 0.000179 0.000133 0.0000151 0.0000213 0.000172 0.000176 1985 7 10 46256 -0.019104 0.488493 0.5433051 0.0007055 0.000403 -0.000467 0.000179 0.000132 0.0000153 0.0000217 0.000172 0.000176 1985 7 11 46257 -0.016024 0.489105 0.5426510 0.0006384 0.000349 -0.000504 0.000179 0.000133 0.0000156 0.0000221 0.000172 0.000176 1985 7 12 46258 -0.011890 0.489652 0.5420631 0.0005419 0.000296 -0.000541 0.000179 0.000133 0.0000159 0.0000225 0.000172 0.000176 1985 7 13 46259 -0.007709 0.491353 0.5415641 0.0004228 0.000242 -0.000578 0.000180 0.000133 0.0000162 0.0000230 0.000172 0.000176 1985 7 14 46260 -0.004579 0.491835 0.5411758 0.0002935 0.000318 -0.000635 0.000181 0.000134 0.0000167 0.0000236 0.000173 0.000176 1985 7 15 46261 -0.000666 0.491609 0.5409127 0.0001758 0.000433 -0.000699 0.000181 0.000133 0.0000171 0.0000243 0.000174 0.000177 1985 7 16 46262 0.002811 0.492162 0.5407650 0.0001005 0.000548 -0.000762 0.000182 0.000133 0.0000176 0.0000250 0.000174 0.000177 1985 7 17 46263 0.005947 0.492556 0.5406822 0.0001019 0.000664 -0.000826 0.000182 0.000134 0.0000182 0.0000257 0.000175 0.000177 1985 7 18 46264 0.010402 0.492932 0.5405721 0.0002047 0.000779 -0.000889 0.000183 0.000133 0.0000187 0.0000264 0.000176 0.000178 1985 7 19 46265 0.014121 0.493368 0.5403155 0.0004089 0.000226 -0.000274 0.000183 0.000132 0.0000192 0.0000270 0.000177 0.000177 1985 7 20 46266 0.017024 0.493994 0.5397796 0.0006821 -0.000050 0.000000 0.000183 0.000132 0.0000195 0.0000275 0.000176 0.000175 1985 7 21 46267 0.020272 0.495141 0.5389193 0.0009652 0.000204 -0.000333 0.000182 0.000130 0.0000197 0.0000279 0.000175 0.000172 1985 7 22 46268 0.022784 0.495692 0.5378119 0.0011912 0.000392 -0.000461 0.000182 0.000129 0.0000199 0.0000283 0.000175 0.000171 1985 7 23 46269 0.025619 0.496010 0.5365597 0.0013059 0.000470 -0.000239 0.000184 0.000129 0.0000203 0.0000286 0.000176 0.000173 1985 7 24 46270 0.029511 0.496192 0.5352517 0.0012825 0.000323 0.000024 0.000185 0.000128 0.0000206 0.0000291 0.000176 0.000175 1985 7 25 46271 0.033080 0.495022 0.5340229 0.0011278 0.000117 0.000298 0.000185 0.000126 0.0000209 0.0000295 0.000176 0.000176 1985 7 26 46272 0.036375 0.494698 0.5330073 0.0008812 -0.000089 0.000573 0.000185 0.000125 0.0000211 0.0000298 0.000176 0.000177 1985 7 27 46273 0.039563 0.496150 0.5322839 0.0006049 -0.000109 0.000528 0.000184 0.000123 0.0000213 0.0000300 0.000176 0.000178 1985 7 28 46274 0.042593 0.496265 0.5318389 0.0003670 0.000227 -0.000126 0.000183 0.000120 0.0000213 0.0000301 0.000175 0.000177 1985 7 29 46275 0.045901 0.495292 0.5315674 0.0002210 0.000388 -0.000446 0.000181 0.000118 0.0000213 0.0000300 0.000175 0.000176 1985 7 30 46276 0.049393 0.495423 0.5313484 0.0001909 0.000359 -0.000431 0.000179 0.000116 0.0000211 0.0000298 0.000175 0.000175 1985 7 31 46277 0.052873 0.495797 0.5310838 0.0002678 0.000329 -0.000416 0.000177 0.000114 0.0000209 0.0000296 0.000175 0.000173 1985 8 1 46278 0.055932 0.495629 0.5307105 0.0004189 0.000299 -0.000401 0.000175 0.000114 0.0000208 0.0000294 0.000174 0.000172 1985 8 2 46279 0.058581 0.495413 0.5302028 0.0006032 0.000269 -0.000386 0.000174 0.000114 0.0000206 0.0000291 0.000174 0.000171 1985 8 3 46280 0.061325 0.494963 0.5295572 0.0007833 0.000217 -0.000504 0.000174 0.000115 0.0000204 0.0000289 0.000173 0.000169 1985 8 4 46281 0.064209 0.494494 0.5287675 0.0009295 0.000156 -0.000672 0.000177 0.000117 0.0000202 0.0000285 0.000172 0.000166 1985 8 5 46282 0.067820 0.494876 0.5278328 0.0010173 0.000095 -0.000839 0.000179 0.000119 0.0000200 0.0000282 0.000172 0.000164 1985 8 6 46283 0.071912 0.495279 0.5267830 0.0010270 0.000035 -0.001007 0.000181 0.000121 0.0000197 0.0000279 0.000171 0.000161 1985 8 7 46284 0.075136 0.494304 0.5256951 0.0009504 -0.000026 -0.001175 0.000183 0.000123 0.0000195 0.0000275 0.000170 0.000159 1985 8 8 46285 0.078047 0.493045 0.5246893 0.0007999 0.000102 -0.001041 0.000184 0.000125 0.0000192 0.0000271 0.000168 0.000156 1985 8 9 46286 0.081759 0.492736 0.5239199 0.0006122 0.000296 -0.000801 0.000186 0.000127 0.0000188 0.0000268 0.000166 0.000152 1985 8 10 46287 0.085982 0.492471 0.5234820 0.0004372 0.000490 -0.000562 0.000190 0.000130 0.0000187 0.0000263 0.000164 0.000149 1985 8 11 46288 0.089776 0.491824 0.5233443 0.0003148 0.000685 -0.000322 0.000192 0.000133 0.0000184 0.0000264 0.000163 0.000146 1985 8 12 46289 0.092832 0.491076 0.5233113 0.0002552 0.000325 -0.000186 0.000196 0.000137 0.0000186 0.0000265 0.000163 0.000146 1985 8 13 46290 0.096009 0.489818 0.5228742 0.0002407 0.000741 -0.000193 0.000200 0.000142 0.0000190 0.0000269 0.000164 0.000148 1985 8 14 46291 0.099291 0.488231 0.5222112 0.0002570 0.001436 -0.000242 0.000203 0.000146 0.0000195 0.0000274 0.000165 0.000150 1985 8 15 46292 0.102437 0.486986 0.5217612 0.0003231 0.001322 -0.000339 0.000207 0.000151 0.0000197 0.0000279 0.000167 0.000152 1985 8 16 46293 0.105373 0.485868 0.5214952 0.0004782 0.001017 -0.000455 0.000210 0.000155 0.0000200 0.0000282 0.000169 0.000154 1985 8 17 46294 0.107039 0.484689 0.5211736 0.0007382 0.000712 -0.000570 0.000212 0.000160 0.0000202 0.0000286 0.000171 0.000157 1985 8 18 46295 0.109683 0.484011 0.5204987 0.0010630 0.000582 -0.000542 0.000215 0.000164 0.0000205 0.0000289 0.000172 0.000159 1985 8 19 46296 0.114804 0.483507 0.5193375 0.0013628 0.000509 -0.000467 0.000217 0.000168 0.0000207 0.0000293 0.000174 0.000160 1985 8 20 46297 0.118229 0.482519 0.5177734 0.0015390 0.000435 -0.000392 0.000218 0.000171 0.0000209 0.0000296 0.000175 0.000162 1985 8 21 46298 0.120841 0.482094 0.5160468 0.0015310 0.000361 -0.000318 0.000219 0.000175 0.0000212 0.0000299 0.000177 0.000163 1985 8 22 46299 0.125576 0.482312 0.5144533 0.0013440 0.000288 -0.000243 0.000220 0.000178 0.0000214 0.0000302 0.000178 0.000165 1985 8 23 46300 0.128564 0.481279 0.5132203 0.0010439 0.000125 -0.000280 0.000220 0.000180 0.0000216 0.0000305 0.000179 0.000165 1985 8 24 46301 0.130469 0.478997 0.5123979 0.0007277 -0.000064 -0.000352 0.000219 0.000182 0.0000217 0.0000307 0.000180 0.000165 1985 8 25 46302 0.134303 0.476883 0.5118821 0.0004861 -0.000254 -0.000423 0.000218 0.000183 0.0000218 0.0000310 0.000180 0.000165 1985 8 26 46303 0.136386 0.475845 0.5114975 0.0003762 -0.000066 -0.000432 0.000217 0.000184 0.0000222 0.0000315 0.000183 0.000168 1985 8 27 46304 0.137344 0.475933 0.5111058 0.0004127 0.000273 -0.000417 0.000217 0.000185 0.0000228 0.0000323 0.000186 0.000173 1985 8 28 46305 0.140926 0.474910 0.5106193 0.0005729 0.000387 -0.000455 0.000216 0.000186 0.0000234 0.0000332 0.000189 0.000177 1985 8 29 46306 0.144994 0.472071 0.5099533 0.0008095 0.000425 -0.000512 0.000214 0.000185 0.0000241 0.0000341 0.000192 0.000182 1985 8 30 46307 0.148126 0.470085 0.5090452 0.0010644 0.000464 -0.000568 0.000212 0.000185 0.0000249 0.0000352 0.000195 0.000187 1985 8 31 46308 0.150830 0.468938 0.5078797 0.0012813 0.000502 -0.000624 0.000211 0.000186 0.0000257 0.0000364 0.000198 0.000193 1985 9 1 46309 0.153156 0.467126 0.5064965 0.0014172 0.000540 -0.000680 0.000210 0.000186 0.0000266 0.0000375 0.000201 0.000199 1985 9 2 46310 0.156493 0.465619 0.5049905 0.0014493 -0.001475 -0.000592 0.000208 0.000186 0.0000273 0.0000384 0.000204 0.000203 1985 9 3 46311 0.159690 0.464133 0.5035167 0.0013790 -0.002152 -0.000495 0.000207 0.000185 0.0000277 0.0000390 0.000205 0.000205 1985 9 4 46312 0.160954 0.461300 0.5022017 0.0012303 -0.001378 -0.000425 0.000204 0.000183 0.0000279 0.0000395 0.000206 0.000206 1985 9 5 46313 0.162728 0.458385 0.5010981 0.0010417 -0.000605 -0.000355 0.000201 0.000181 0.0000281 0.0000398 0.000206 0.000207 1985 9 6 46314 0.166100 0.457135 0.5001999 0.0008538 0.000168 -0.000285 0.000199 0.000179 0.0000283 0.0000399 0.000207 0.000208 1985 9 7 46315 0.169264 0.456605 0.4994592 0.0006995 0.000389 -0.000372 0.000196 0.000177 0.0000283 0.0000400 0.000207 0.000208 1985 9 8 46316 0.172167 0.454994 0.4988178 0.0006003 0.000438 -0.000507 0.000193 0.000174 0.0000283 0.0000400 0.000207 0.000206 1985 9 9 46317 0.174854 0.453003 0.4982179 0.0005702 0.000487 -0.000643 0.000190 0.000172 0.0000282 0.0000399 0.000206 0.000205 1985 9 10 46318 0.176489 0.451829 0.4975991 0.0006223 0.000536 -0.000778 0.000187 0.000169 0.0000282 0.0000398 0.000206 0.000204 1985 9 11 46319 0.177917 0.450369 0.4968906 0.0007690 0.000585 -0.000913 0.000184 0.000167 0.0000281 0.0000397 0.000206 0.000202 1985 9 12 46320 0.180008 0.447832 0.4960072 0.0010120 -0.000058 -0.001170 0.000181 0.000164 0.0000280 0.0000396 0.000205 0.000200 1985 9 13 46321 0.182270 0.445057 0.4948577 0.0013271 -0.000423 -0.000503 0.000177 0.000161 0.0000278 0.0000393 0.000203 0.000196 1985 9 14 46322 0.184434 0.442986 0.4933860 0.0016565 -0.000399 -0.000137 0.000174 0.000158 0.0000276 0.0000390 0.000202 0.000195 1985 9 15 46323 0.186058 0.441366 0.4916072 0.0019205 -0.000253 -0.000242 0.000173 0.000157 0.0000274 0.0000387 0.000202 0.000198 1985 9 16 46324 0.187047 0.438938 0.4896176 0.0020458 -0.000106 -0.000346 0.000171 0.000155 0.0000271 0.0000384 0.000201 0.000200 1985 9 17 46325 0.188235 0.436277 0.4875744 0.0019978 -0.000074 -0.000461 0.000170 0.000154 0.0000269 0.0000381 0.000201 0.000201 1985 9 18 46326 0.189665 0.434014 0.4856488 0.0017971 -0.000080 -0.000579 0.000170 0.000153 0.0000267 0.0000377 0.000200 0.000202 1985 9 19 46327 0.191341 0.431020 0.4839709 0.0015117 -0.000086 -0.000696 0.000170 0.000152 0.0000264 0.0000374 0.000199 0.000203 1985 9 20 46328 0.192902 0.428615 0.4825906 0.0012296 -0.000092 -0.000814 0.000171 0.000153 0.0000262 0.0000371 0.000198 0.000204 1985 9 21 46329 0.193716 0.427336 0.4814704 0.0010274 -0.000098 -0.000932 0.000174 0.000156 0.0000260 0.0000368 0.000197 0.000205 1985 9 22 46330 0.195735 0.424840 0.4805062 0.0009488 -0.000065 -0.000901 0.000177 0.000159 0.0000258 0.0000365 0.000196 0.000204 1985 9 23 46331 0.199061 0.422105 0.4795628 0.0009992 -0.000019 -0.000823 0.000178 0.000160 0.0000257 0.0000363 0.000195 0.000204 1985 9 24 46332 0.201149 0.420039 0.4785123 0.0011525 0.000028 -0.000745 0.000179 0.000161 0.0000255 0.0000361 0.000194 0.000203 1985 9 25 46333 0.203062 0.417824 0.4772650 0.0013633 0.000074 -0.000666 0.000180 0.000162 0.0000254 0.0000359 0.000193 0.000202 1985 9 26 46334 0.205104 0.416773 0.4757839 0.0015811 0.000120 -0.000588 0.000181 0.000164 0.0000253 0.0000356 0.000192 0.000201 1985 9 27 46335 0.206120 0.414871 0.4740875 0.0017613 0.000037 -0.000520 0.000185 0.000167 0.0000249 0.0000352 0.000190 0.000198 1985 9 28 46336 0.207950 0.410535 0.4722402 0.0018736 -0.000085 -0.000456 0.000187 0.000170 0.0000245 0.0000347 0.000188 0.000195 1985 9 29 46337 0.209795 0.407834 0.4703312 0.0019057 -0.000206 -0.000392 0.000189 0.000172 0.0000241 0.0000342 0.000186 0.000191 1985 9 30 46338 0.210583 0.406025 0.4684484 0.0018620 -0.000328 -0.000327 0.000191 0.000175 0.0000238 0.0000339 0.000184 0.000188 1985 10 1 46339 0.211837 0.402331 0.4666597 0.0017590 -0.000295 -0.000183 0.000194 0.000178 0.0000238 0.0000337 0.000183 0.000187 1985 10 2 46340 0.211964 0.399336 0.4649918 0.0016196 -0.000051 0.000061 0.000199 0.000182 0.0000239 0.0000337 0.000183 0.000187 1985 10 3 46341 0.212154 0.396684 0.4634516 0.0014687 0.000193 0.000304 0.000205 0.000187 0.0000239 0.0000332 0.000182 0.000187 1985 10 4 46342 0.214721 0.392763 0.4620393 0.0013300 0.000253 0.000010 0.000209 0.000190 0.0000230 0.0000331 0.000183 0.000189 1985 10 5 46343 0.215633 0.389784 0.4607414 0.0012259 0.000216 -0.000569 0.000215 0.000195 0.0000229 0.0000324 0.000184 0.000194 1985 10 6 46344 0.215052 0.387559 0.4595286 0.0011767 0.000179 -0.001147 0.000220 0.000200 0.0000228 0.0000323 0.000185 0.000200 1985 10 7 46345 0.216549 0.384379 0.4583489 0.0012020 0.000115 -0.001250 0.000225 0.000204 0.0000228 0.0000322 0.000187 0.000204 1985 10 8 46346 0.218539 0.380781 0.4571187 0.0013191 0.000041 -0.001200 0.000229 0.000208 0.0000228 0.0000322 0.000188 0.000209 1985 10 9 46347 0.220295 0.377648 0.4557291 0.0015347 -0.000032 -0.001149 0.000234 0.000212 0.0000227 0.0000321 0.000189 0.000214 1985 10 10 46348 0.221873 0.375332 0.4540693 0.0018328 -0.000106 -0.001099 0.000237 0.000215 0.0000227 0.0000321 0.000191 0.000219 1985 10 11 46349 0.222780 0.373103 0.4520641 0.0021642 -0.000180 -0.001048 0.000242 0.000219 0.0000227 0.0000320 0.000192 0.000224 1985 10 12 46350 0.223881 0.370045 0.4497148 0.0024504 -0.000219 -0.000992 0.000246 0.000223 0.0000226 0.0000320 0.000193 0.000228 1985 10 13 46351 0.224244 0.366185 0.4471262 0.0026081 -0.000246 -0.000934 0.000251 0.000228 0.0000226 0.0000319 0.000195 0.000232 1985 10 14 46352 0.224219 0.362535 0.4444845 0.0025843 -0.000274 -0.000876 0.000256 0.000232 0.0000225 0.0000319 0.000196 0.000235 1985 10 15 46353 0.224765 0.360266 0.4419955 0.0023852 -0.000302 -0.000818 0.000260 0.000236 0.0000225 0.0000318 0.000197 0.000240 1985 10 16 46354 0.224965 0.357683 0.4398093 0.0020777 -0.000329 -0.000760 0.000265 0.000240 0.0000224 0.0000318 0.000198 0.000243 1985 10 17 46355 0.225785 0.354186 0.4379652 0.0017608 -0.001092 -0.000514 0.000269 0.000243 0.0000225 0.0000318 0.000200 0.000247 1985 10 18 46356 0.226149 0.352073 0.4363755 0.0015235 -0.002079 -0.000210 0.000272 0.000245 0.0000226 0.0000319 0.000202 0.000250 1985 10 19 46357 0.226174 0.348709 0.4348888 0.0014127 -0.003066 0.000094 0.000275 0.000247 0.0000226 0.0000320 0.000204 0.000254 1985 10 20 46358 0.228863 0.343325 0.4333704 0.0014285 -0.004053 0.000398 0.000278 0.000250 0.0000227 0.0000319 0.000206 0.000258 1985 10 21 46359 0.229821 0.341631 0.4317612 0.0015431 -0.000450 -0.000417 0.000281 0.000252 0.0000225 0.0000317 0.000208 0.000259 1985 10 22 46360 0.228028 0.341209 0.4301701 0.0017235 0.000029 -0.000870 0.000283 0.000253 0.0000221 0.0000313 0.000208 0.000259 1985 10 23 46361 0.228762 0.337298 0.4285226 0.0019383 -0.000802 -0.001132 0.000286 0.000255 0.0000218 0.0000308 0.000209 0.000258 1985 10 24 46362 0.229085 0.334084 0.4266121 0.0021497 -0.001633 -0.001395 0.000289 0.000258 0.0000214 0.0000302 0.000210 0.000257 1985 10 25 46363 0.228328 0.331847 0.4243160 0.0023115 -0.001010 -0.000977 0.000292 0.000261 0.0000209 0.0000295 0.000209 0.000254 1985 10 26 46364 0.229211 0.328082 0.4217871 0.0023834 -0.000100 -0.000425 0.000294 0.000262 0.0000203 0.0000288 0.000209 0.000251 1985 10 27 46365 0.229200 0.326104 0.4193088 0.0023498 -0.000447 0.000489 0.000294 0.000263 0.0000198 0.0000280 0.000209 0.000248 1985 10 28 46366 0.230004 0.324862 0.4170400 0.0022259 -0.001186 0.001516 0.000293 0.000262 0.0000193 0.0000273 0.000209 0.000244 1985 10 29 46367 0.231115 0.321173 0.4150035 0.0020454 -0.000599 0.000284 0.000291 0.000260 0.0000188 0.0000266 0.000208 0.000239 1985 10 30 46368 0.229808 0.318194 0.4131452 0.0018435 0.000003 -0.000812 0.000287 0.000258 0.0000183 0.0000259 0.000207 0.000234 1985 10 31 46369 0.230143 0.316569 0.4114114 0.0016459 -0.000131 -0.000164 0.000284 0.000255 0.0000178 0.0000251 0.000207 0.000229 1985 11 1 46370 0.229787 0.313589 0.4098129 0.0014688 -0.000136 0.000344 0.000280 0.000252 0.0000171 0.0000242 0.000208 0.000226 1985 11 2 46371 0.228062 0.310378 0.4083554 0.0013253 -0.000100 0.000808 0.000276 0.000249 0.0000165 0.0000234 0.000208 0.000223 1985 11 3 46372 0.229771 0.307939 0.4070293 0.0012318 -0.000063 0.001272 0.000271 0.000244 0.0000159 0.0000225 0.000209 0.000220 1985 11 4 46373 0.228741 0.305231 0.4057993 0.0012108 -0.000027 0.001009 0.000266 0.000240 0.0000154 0.0000218 0.000210 0.000215 1985 11 5 46374 0.228168 0.302471 0.4045876 0.0012860 0.000009 0.000602 0.000260 0.000235 0.0000148 0.0000209 0.000210 0.000210 1985 11 6 46375 0.235310 0.299668 0.4032751 0.0014706 0.000994 -0.000571 0.000254 0.000229 0.0000142 0.0000202 0.000211 0.000204 1985 11 7 46376 0.235669 0.296433 0.4017290 0.0017499 0.000760 -0.000787 0.000248 0.000224 0.0000136 0.0000193 0.000210 0.000198 1985 11 8 46377 0.227955 0.293763 0.3998505 0.0020701 -0.000246 -0.000394 0.000240 0.000218 0.0000131 0.0000186 0.000209 0.000191 1985 11 9 46378 0.227295 0.291931 0.3976260 0.0023448 -0.000327 -0.000473 0.000233 0.000213 0.0000126 0.0000179 0.000209 0.000190 1985 11 10 46379 0.229006 0.290130 0.3951544 0.0024833 -0.000099 -0.000709 0.000226 0.000207 0.0000122 0.0000172 0.000208 0.000190 1985 11 11 46380 0.227829 0.288295 0.3926272 0.0024302 -0.000062 -0.000711 0.000219 0.000201 0.0000117 0.0000165 0.000208 0.000189 1985 11 12 46381 0.228677 0.285846 0.3902637 0.0021971 -0.000085 -0.000638 0.000211 0.000195 0.0000112 0.0000158 0.000207 0.000188 1985 11 13 46382 0.229271 0.282670 0.3882259 0.0018633 -0.000108 -0.000565 0.000205 0.000189 0.0000107 0.0000152 0.000207 0.000186 1985 11 14 46383 0.228042 0.280192 0.3865568 0.0015440 -0.000131 -0.000492 0.000200 0.000184 0.0000103 0.0000147 0.000206 0.000185 1985 11 15 46384 0.226936 0.277603 0.3851709 0.0013407 -0.000154 -0.000419 0.000195 0.000179 0.0000100 0.0000141 0.000206 0.000183 1985 11 16 46385 0.226394 0.273808 0.3838990 0.0013019 -0.000198 -0.000371 0.000190 0.000174 0.0000096 0.0000136 0.000205 0.000180 1985 11 17 46386 0.226722 0.270533 0.3825636 0.0014123 -0.000248 -0.000332 0.000185 0.000169 0.0000092 0.0000131 0.000203 0.000177 1985 11 18 46387 0.226355 0.267652 0.3810411 0.0016122 -0.000299 -0.000292 0.000179 0.000164 0.0000089 0.0000126 0.000202 0.000173 1985 11 19 46388 0.225659 0.264482 0.3792893 0.0018298 -0.000350 -0.000252 0.000174 0.000159 0.0000086 0.0000122 0.000200 0.000170 1985 11 20 46389 0.225575 0.262588 0.3773372 0.0020086 -0.000400 -0.000212 0.000169 0.000154 0.0000083 0.0000118 0.000199 0.000167 1985 11 21 46390 0.225502 0.260743 0.3752537 0.0021176 -0.000415 -0.000023 0.000164 0.000149 0.0000081 0.0000114 0.000198 0.000164 1985 11 22 46391 0.227254 0.257477 0.3731114 0.0021483 -0.000153 -0.000093 0.000158 0.000144 0.0000077 0.0000111 0.000196 0.000160 1985 11 23 46392 0.228790 0.254885 0.3709892 0.0021055 -0.000243 -0.000085 0.000156 0.000143 0.0000077 0.0000111 0.000197 0.000160 1985 11 24 46393 0.227751 0.253311 0.3689527 0.0020007 -0.000701 0.000134 0.000159 0.000146 0.0000080 0.0000113 0.000199 0.000164 1985 11 25 46394 0.227759 0.251721 0.3670427 0.0018484 -0.001160 0.000353 0.000162 0.000148 0.0000083 0.0000117 0.000201 0.000169 1985 11 26 46395 0.228169 0.249989 0.3652860 0.0016663 -0.001064 0.000230 0.000164 0.000149 0.0000086 0.0000122 0.000203 0.000173 1985 11 27 46396 0.227249 0.247340 0.3637002 0.0014760 -0.000802 0.000005 0.000165 0.000150 0.0000089 0.0000127 0.000205 0.000178 1985 11 28 46397 0.226897 0.244778 0.3622890 0.0013035 -0.000540 -0.000221 0.000166 0.000150 0.0000093 0.0000132 0.000208 0.000183 1985 11 29 46398 0.226046 0.243355 0.3610340 0.0011770 -0.000277 -0.000446 0.000167 0.000151 0.0000097 0.0000138 0.000211 0.000189 1985 11 30 46399 0.225028 0.241359 0.3598894 0.0011226 -0.000015 -0.000672 0.000167 0.000151 0.0000102 0.0000144 0.000213 0.000196 1985 12 1 46400 0.224678 0.238696 0.3587797 0.0011585 0.000031 -0.000753 0.000167 0.000150 0.0000106 0.0000150 0.000215 0.000201 1985 12 2 46401 0.223387 0.236213 0.3576014 0.0012897 0.000010 -0.000789 0.000168 0.000150 0.0000111 0.0000157 0.000217 0.000206 1985 12 3 46402 0.222224 0.233389 0.3562426 0.0015044 -0.000011 -0.000826 0.000169 0.000149 0.0000116 0.0000164 0.000218 0.000211 1985 12 4 46403 0.220592 0.230757 0.3546111 0.0017728 -0.000032 -0.000862 0.000170 0.000149 0.0000121 0.0000173 0.000220 0.000217 1985 12 5 46404 0.218068 0.228327 0.3526642 0.0020485 -0.000053 -0.000898 0.000173 0.000151 0.0000128 0.0000181 0.000222 0.000223 1985 12 6 46405 0.217422 0.225729 0.3504332 0.0022745 -0.000116 -0.000812 0.000175 0.000151 0.0000134 0.0000190 0.000222 0.000226 1985 12 7 46406 0.216747 0.223896 0.3480358 0.0023951 -0.000193 -0.000687 0.000178 0.000153 0.0000140 0.0000198 0.000223 0.000229 1985 12 8 46407 0.215322 0.222147 0.3456406 0.0023742 -0.000269 -0.000562 0.000182 0.000155 0.0000146 0.0000208 0.000224 0.000233 1985 12 9 46408 0.215131 0.219885 0.3434081 0.0022113 -0.000345 -0.000437 0.000185 0.000156 0.0000154 0.0000219 0.000224 0.000236 1985 12 10 46409 0.213176 0.217682 0.3414398 0.0019462 -0.000421 -0.000312 0.000188 0.000158 0.0000162 0.0000229 0.000225 0.000239 1985 12 11 46410 0.210447 0.214557 0.3397403 0.0016458 0.000582 -0.001059 0.000192 0.000161 0.0000170 0.0000240 0.000225 0.000240 1985 12 12 46411 0.210606 0.211776 0.3381137 0.0013805 0.000982 -0.001210 0.000195 0.000163 0.0000176 0.0000250 0.000225 0.000240 1985 12 13 46412 0.210314 0.211017 0.3365962 0.0012047 0.001014 -0.001024 0.000198 0.000165 0.0000183 0.0000257 0.000226 0.000240 1985 12 14 46413 0.207992 0.208846 0.3353582 0.0011484 0.000314 -0.000996 0.000201 0.000167 0.0000188 0.0000266 0.000224 0.000238 1985 12 15 46414 0.206216 0.204898 0.3342903 0.0012127 -0.000445 -0.000197 0.000202 0.000168 0.0000192 0.0000271 0.000225 0.000239 1985 12 16 46415 0.205392 0.203107 0.3331499 0.0013694 -0.000557 0.000030 0.000204 0.000170 0.0000196 0.0000277 0.000225 0.000240 1985 12 17 46416 0.205293 0.201735 0.3317755 0.0015698 -0.000430 -0.000038 0.000206 0.000171 0.0000199 0.0000282 0.000225 0.000241 1985 12 18 46417 0.205323 0.198891 0.3301198 0.0017598 -0.000302 -0.000105 0.000207 0.000172 0.0000203 0.0000287 0.000225 0.000241 1985 12 19 46418 0.204378 0.197884 0.3282306 0.0018929 -0.000175 -0.000173 0.000209 0.000174 0.0000207 0.0000293 0.000226 0.000242 1985 12 20 46419 0.202644 0.197508 0.3262266 0.0019388 -0.000047 -0.000241 0.000214 0.000178 0.0000212 0.0000298 0.000226 0.000242 1985 12 21 46420 0.201350 0.193879 0.3242507 0.0018873 0.000203 0.000361 0.000218 0.000181 0.0000214 0.0000302 0.000225 0.000241 1985 12 22 46421 0.200954 0.189903 0.3224192 0.0017472 0.000496 0.001199 0.000222 0.000184 0.0000216 0.0000306 0.000224 0.000239 1985 12 23 46422 0.200122 0.188329 0.3208005 0.0015422 0.000790 0.002037 0.000228 0.000190 0.0000218 0.0000309 0.000223 0.000236 1985 12 24 46423 0.198861 0.186100 0.3194167 0.0013025 0.000971 0.002596 0.000233 0.000194 0.0000220 0.0000312 0.000222 0.000234 1985 12 25 46424 0.198067 0.182863 0.3182574 0.0010584 0.000765 0.002187 0.000238 0.000199 0.0000223 0.0000315 0.000221 0.000231 1985 12 26 46425 0.196813 0.181124 0.3172982 0.0008369 0.000560 0.001778 0.000244 0.000204 0.0000225 0.0000319 0.000219 0.000228 1985 12 27 46426 0.195325 0.179624 0.3165125 0.0006622 0.000354 0.001369 0.000249 0.000208 0.0000228 0.0000322 0.000218 0.000225 1985 12 28 46427 0.193806 0.177541 0.3158715 0.0005563 0.000148 0.000960 0.000254 0.000213 0.0000230 0.0000326 0.000216 0.000222 1985 12 29 46428 0.191631 0.176243 0.3153312 0.0005366 -0.000058 0.000552 0.000258 0.000217 0.0000233 0.0000329 0.000215 0.000220 1985 12 30 46429 0.189770 0.174497 0.3148142 0.0006102 -0.000264 0.000143 0.000262 0.000220 0.0000235 0.0000333 0.000214 0.000217 1985 12 31 46430 0.187242 0.171668 0.3141948 0.0007660 -0.000308 0.000056 0.000265 0.000222 0.0000238 0.0000337 0.000212 0.000215 1986 1 1 46431 0.184126 0.168879 0.3134103 0.0011877 -0.000299 0.000061 0.000254 0.000209 0.0000192 0.0000271 0.000267 0.000276 1986 1 2 46432 0.183485 0.166826 0.3121379 0.0016022 -0.000296 0.000064 0.000254 0.000209 0.0000192 0.0000272 0.000264 0.000272 1986 1 3 46433 0.182086 0.165434 0.3103399 0.0019313 -0.000293 0.000067 0.000253 0.000208 0.0000193 0.0000273 0.000261 0.000269 1986 1 4 46434 0.179125 0.164747 0.3081293 0.0020590 -0.000291 0.000070 0.000251 0.000207 0.0000193 0.0000275 0.000258 0.000265 1986 1 5 46435 0.177318 0.162571 0.3058183 0.0019308 -0.001365 -0.000448 0.000247 0.000204 0.0000196 0.0000278 0.000256 0.000262 1986 1 6 46436 0.175393 0.158728 0.3038829 0.0015923 -0.002713 -0.001098 0.000242 0.000201 0.0000200 0.0000281 0.000254 0.000260 1986 1 7 46437 0.173185 0.157270 0.3026616 0.0011786 -0.002087 -0.001099 0.000237 0.000197 0.0000201 0.0000283 0.000251 0.000254 1986 1 8 46438 0.171331 0.156728 0.3019980 0.0008496 -0.001067 -0.000970 0.000231 0.000192 0.0000201 0.0000284 0.000247 0.000249 1986 1 9 46439 0.168456 0.155136 0.3014450 0.0007117 -0.000047 -0.000840 0.000225 0.000187 0.0000201 0.0000283 0.000244 0.000244 1986 1 10 46440 0.165769 0.153739 0.3005855 0.0007789 0.000145 -0.000261 0.000218 0.000181 0.0000200 0.0000283 0.000241 0.000239 1986 1 11 46441 0.164402 0.151295 0.2994822 0.0009928 0.000064 0.000070 0.000212 0.000176 0.0000198 0.0000281 0.000238 0.000234 1986 1 12 46442 0.162349 0.149263 0.2982796 0.0012705 0.000078 0.000054 0.000207 0.000173 0.0000197 0.0000279 0.000237 0.000230 1986 1 13 46443 0.159357 0.147637 0.2969371 0.0015383 0.000093 0.000039 0.000204 0.000170 0.0000196 0.0000278 0.000236 0.000226 1986 1 14 46444 0.158014 0.144557 0.2953974 0.0017427 0.000107 0.000023 0.000200 0.000167 0.0000195 0.0000276 0.000234 0.000223 1986 1 15 46445 0.158049 0.143790 0.2936231 0.0018502 0.000316 0.000010 0.000197 0.000164 0.0000194 0.0000273 0.000233 0.000219 1986 1 16 46446 0.156462 0.142851 0.2916736 0.0018476 0.000111 -0.000057 0.000194 0.000161 0.0000191 0.0000272 0.000231 0.000214 1986 1 17 46447 0.153612 0.138534 0.2897841 0.0017452 -0.000013 -0.000031 0.000191 0.000158 0.0000191 0.0000270 0.000229 0.000211 1986 1 18 46448 0.150602 0.137029 0.2881165 0.0015764 -0.000056 0.000033 0.000189 0.000156 0.0000191 0.0000270 0.000228 0.000209 1986 1 19 46449 0.147244 0.136786 0.2866980 0.0013851 -0.000099 0.000098 0.000187 0.000154 0.0000191 0.0000269 0.000227 0.000207 1986 1 20 46450 0.144948 0.134444 0.2854791 0.0012108 -0.000059 -0.000117 0.000185 0.000151 0.0000190 0.0000270 0.000225 0.000204 1986 1 21 46451 0.142332 0.133899 0.2843750 0.0010773 -0.000759 -0.000022 0.000184 0.000149 0.0000190 0.0000270 0.000224 0.000203 1986 1 22 46452 0.138387 0.133014 0.2833246 0.0009934 -0.000847 0.000105 0.000183 0.000149 0.0000191 0.0000270 0.000224 0.000203 1986 1 23 46453 0.136062 0.130990 0.2822988 0.0009609 -0.000509 0.000186 0.000182 0.000147 0.0000192 0.0000272 0.000224 0.000202 1986 1 24 46454 0.133613 0.131126 0.2812809 0.0009846 -0.000172 0.000267 0.000182 0.000146 0.0000193 0.0000271 0.000225 0.000202 1986 1 25 46455 0.130262 0.130662 0.2802408 0.0010745 -0.000013 0.000228 0.000181 0.000145 0.0000192 0.0000271 0.000224 0.000200 1986 1 26 46456 0.129412 0.129012 0.2791095 0.0012379 0.000090 0.000153 0.000179 0.000142 0.0000190 0.0000269 0.000223 0.000198 1986 1 27 46457 0.127586 0.128213 0.2777957 0.0014668 0.000194 0.000077 0.000178 0.000140 0.0000189 0.0000267 0.000222 0.000195 1986 1 28 46458 0.123330 0.127144 0.2762242 0.0017301 0.000297 0.000002 0.000177 0.000139 0.0000187 0.0000265 0.000221 0.000193 1986 1 29 46459 0.121224 0.125902 0.2743694 0.0019775 0.000400 -0.000074 0.000176 0.000137 0.0000186 0.0000262 0.000221 0.000190 1986 1 30 46460 0.119243 0.124756 0.2722758 0.0021540 0.000090 0.000155 0.000175 0.000135 0.0000183 0.0000261 0.000219 0.000188 1986 1 31 46461 0.115680 0.123742 0.2700715 0.0022183 -0.000066 0.000277 0.000175 0.000134 0.0000184 0.0000261 0.000219 0.000187 1986 2 1 46462 0.112840 0.123217 0.2678862 0.0021550 -0.000134 0.000338 0.000176 0.000133 0.0000186 0.0000262 0.000220 0.000187 1986 2 2 46463 0.108995 0.122306 0.2658232 0.0019787 -0.000202 0.000399 0.000176 0.000132 0.0000187 0.0000265 0.000221 0.000187 1986 2 3 46464 0.104800 0.121589 0.2639573 0.0017316 -0.000271 0.000460 0.000176 0.000132 0.0000189 0.0000267 0.000222 0.000187 1986 2 4 46465 0.102832 0.121327 0.2623238 0.0014757 -0.000504 0.000143 0.000175 0.000131 0.0000190 0.0000270 0.000223 0.000187 1986 2 5 46466 0.100602 0.120580 0.2609360 0.0012796 -0.000497 0.000065 0.000176 0.000132 0.0000192 0.0000273 0.000225 0.000189 1986 2 6 46467 0.097577 0.120062 0.2597199 0.0011969 -0.000390 0.000110 0.000178 0.000134 0.0000196 0.0000278 0.000228 0.000194 1986 2 7 46468 0.095389 0.119691 0.2585326 0.0012462 -0.000284 0.000154 0.000179 0.000135 0.0000201 0.0000284 0.000231 0.000199 1986 2 8 46469 0.092544 0.118978 0.2572294 0.0014021 -0.000177 0.000198 0.000180 0.000137 0.0000205 0.0000289 0.000234 0.000204 1986 2 9 46470 0.089508 0.118290 0.2557157 0.0016069 -0.000069 0.000126 0.000182 0.000140 0.0000208 0.0000295 0.000237 0.000208 1986 2 10 46471 0.087908 0.117317 0.2539865 0.0017954 0.000039 0.000011 0.000184 0.000142 0.0000211 0.0000299 0.000239 0.000213 1986 2 11 46472 0.086187 0.116438 0.2521082 0.0019196 0.000147 -0.000105 0.000186 0.000144 0.0000214 0.0000303 0.000242 0.000217 1986 2 12 46473 0.084025 0.115643 0.2501757 0.0019600 0.000254 -0.000221 0.000187 0.000146 0.0000218 0.0000308 0.000244 0.000222 1986 2 13 46474 0.082059 0.114687 0.2482725 0.0019187 0.000189 0.000366 0.000189 0.000147 0.0000222 0.0000313 0.000246 0.000226 1986 2 14 46475 0.079173 0.114768 0.2464281 0.0018069 0.000118 0.000526 0.000191 0.000149 0.0000225 0.0000318 0.000247 0.000228 1986 2 15 46476 0.076529 0.114647 0.2446835 0.0016372 0.000064 0.000456 0.000193 0.000152 0.0000228 0.0000323 0.000248 0.000230 1986 2 16 46477 0.075146 0.113274 0.2431035 0.0014259 0.000010 0.000387 0.000195 0.000154 0.0000232 0.0000328 0.000249 0.000232 1986 2 17 46478 0.072524 0.113823 0.2417472 0.0011984 -0.000044 0.000318 0.000197 0.000156 0.0000236 0.0000334 0.000249 0.000234 1986 2 18 46479 0.069009 0.115518 0.2406425 0.0009901 -0.000098 0.000249 0.000199 0.000158 0.0000240 0.0000339 0.000250 0.000236 1986 2 19 46480 0.066854 0.114458 0.2397622 0.0008403 -0.000943 -0.000700 0.000199 0.000160 0.0000244 0.0000344 0.000250 0.000238 1986 2 20 46481 0.064442 0.113281 0.2390125 0.0007809 -0.001147 -0.000882 0.000200 0.000161 0.0000246 0.0000349 0.000251 0.000239 1986 2 21 46482 0.061051 0.114081 0.2382597 0.0008277 -0.000834 -0.000455 0.000202 0.000163 0.0000249 0.0000353 0.000253 0.000240 1986 2 22 46483 0.058206 0.113847 0.2373724 0.0009753 -0.000520 -0.000028 0.000203 0.000165 0.0000252 0.0000357 0.000254 0.000242 1986 2 23 46484 0.054932 0.113736 0.2362544 0.0011975 -0.000206 0.000398 0.000204 0.000166 0.0000255 0.0000362 0.000256 0.000243 1986 2 24 46485 0.051000 0.114702 0.2348684 0.0014506 -0.000082 -0.000552 0.000205 0.000168 0.0000260 0.0000365 0.000258 0.000246 1986 2 25 46486 0.048109 0.114092 0.2332605 0.0016825 -0.000106 -0.000742 0.000206 0.000170 0.0000261 0.0000368 0.000258 0.000247 1986 2 26 46487 0.045220 0.114307 0.2315015 0.0018445 -0.000175 -0.000347 0.000208 0.000171 0.0000261 0.0000369 0.000258 0.000247 1986 2 27 46488 0.041545 0.115839 0.2296650 0.0019033 -0.000244 0.000049 0.000210 0.000173 0.0000261 0.0000369 0.000258 0.000247 1986 2 28 46489 0.038452 0.114930 0.2278320 0.0018500 -0.000313 0.000445 0.000211 0.000174 0.0000261 0.0000370 0.000258 0.000247 1986 3 1 46490 0.035362 0.114220 0.2260795 0.0017018 -0.000359 0.000541 0.000215 0.000177 0.0000261 0.0000370 0.000258 0.000248 1986 3 2 46491 0.032081 0.114956 0.2244736 0.0014974 -0.000398 0.000547 0.000220 0.000181 0.0000262 0.0000370 0.000257 0.000249 1986 3 3 46492 0.029402 0.114686 0.2230530 0.0012863 -0.000437 0.000554 0.000224 0.000185 0.0000262 0.0000371 0.000257 0.000250 1986 3 4 46493 0.026210 0.115401 0.2218153 0.0011185 -0.000476 0.000560 0.000229 0.000189 0.0000262 0.0000371 0.000256 0.000251 1986 3 5 46494 0.023072 0.116227 0.2207159 0.0010330 -0.000515 0.000566 0.000235 0.000193 0.0000262 0.0000371 0.000255 0.000252 1986 3 6 46495 0.020524 0.115876 0.2196745 0.0010493 -0.000502 0.000514 0.000240 0.000196 0.0000262 0.0000370 0.000254 0.000252 1986 3 7 46496 0.017215 0.117013 0.2185906 0.0011608 -0.000473 0.000443 0.000244 0.000200 0.0000261 0.0000369 0.000253 0.000253 1986 3 8 46497 0.014448 0.116888 0.2173726 0.0013344 -0.000443 0.000373 0.000248 0.000203 0.0000260 0.0000367 0.000252 0.000253 1986 3 9 46498 0.011544 0.115416 0.2159681 0.0015190 -0.000414 0.000302 0.000252 0.000205 0.0000259 0.0000366 0.000251 0.000253 1986 3 10 46499 0.007143 0.117715 0.2143805 0.0016610 -0.000385 0.000232 0.000255 0.000207 0.0000258 0.0000364 0.000250 0.000254 1986 3 11 46500 0.005020 0.119928 0.2126691 0.0017200 -0.000272 0.000230 0.000257 0.000208 0.0000256 0.0000362 0.000248 0.000253 1986 3 12 46501 0.004039 0.118808 0.2109368 0.0016792 -0.000133 0.000250 0.000258 0.000209 0.0000254 0.0000358 0.000246 0.000253 1986 3 13 46502 0.000265 0.119204 0.2092989 0.0015467 -0.000348 0.000493 0.000259 0.000209 0.0000251 0.0000359 0.000246 0.000254 1986 3 14 46503 -0.003643 0.120915 0.2078495 0.0013485 -0.000233 0.000437 0.000259 0.000209 0.0000255 0.0000361 0.000249 0.000259 1986 3 15 46504 -0.006776 0.120957 0.2066307 0.0011200 0.000059 0.000234 0.000260 0.000208 0.0000260 0.0000366 0.000254 0.000265 1986 3 16 46505 -0.009689 0.120641 0.2056358 0.0008972 0.000187 0.000195 0.000260 0.000208 0.0000263 0.0000372 0.000258 0.000270 1986 3 17 46506 -0.010932 0.120632 0.2048365 0.0007122 0.000265 0.000206 0.000259 0.000207 0.0000266 0.0000376 0.000261 0.000274 1986 3 18 46507 -0.012693 0.120854 0.2041880 0.0005897 0.000343 0.000216 0.000257 0.000205 0.0000269 0.0000381 0.000265 0.000279 1986 3 19 46508 -0.015780 0.122335 0.2036293 0.0005470 0.000422 0.000227 0.000255 0.000203 0.0000272 0.0000385 0.000269 0.000284 1986 3 20 46509 -0.017776 0.123882 0.2030835 0.0005937 0.000500 0.000237 0.000253 0.000201 0.0000275 0.0000388 0.000273 0.000289 1986 3 21 46510 -0.018868 0.123698 0.2024528 0.0007326 0.000096 0.000390 0.000251 0.000199 0.0000277 0.0000392 0.000276 0.000294 1986 3 22 46511 -0.020597 0.123644 0.2015910 0.0009569 -0.000012 0.000493 0.000248 0.000196 0.0000280 0.0000395 0.000279 0.000298 1986 3 23 46512 -0.023074 0.124901 0.2004258 0.0012483 0.000071 0.000555 0.000244 0.000194 0.0000282 0.0000398 0.000281 0.000301 1986 3 24 46513 -0.024455 0.125886 0.1989708 0.0015740 0.000153 0.000617 0.000240 0.000190 0.0000284 0.0000401 0.000284 0.000304 1986 3 25 46514 -0.025742 0.127702 0.1972726 0.0018866 0.000236 0.000680 0.000237 0.000188 0.0000286 0.0000404 0.000287 0.000308 1986 3 26 46515 -0.028824 0.129936 0.1953842 0.0021275 -0.000723 0.000759 0.000235 0.000186 0.0000288 0.0000407 0.000289 0.000311 1986 3 27 46516 -0.030810 0.130082 0.1933007 0.0022392 -0.001998 0.000842 0.000231 0.000184 0.0000290 0.0000408 0.000291 0.000316 1986 3 28 46517 -0.033504 0.131450 0.1910470 0.0021859 -0.001300 0.000415 0.000229 0.000183 0.0000289 0.0000409 0.000292 0.000317 1986 3 29 46518 -0.038280 0.133587 0.1888071 0.0019769 -0.000175 -0.000124 0.000227 0.000182 0.0000289 0.0000408 0.000293 0.000318 1986 3 30 46519 -0.039286 0.132453 0.1868184 0.0016750 0.000299 -0.000210 0.000225 0.000181 0.0000288 0.0000407 0.000294 0.000320 1986 3 31 46520 -0.040431 0.133685 0.1852710 0.0013784 0.000110 0.000162 0.000225 0.000180 0.0000288 0.0000406 0.000295 0.000321 1986 4 1 46521 -0.044936 0.137262 0.1842020 0.0011798 -0.000064 0.000164 0.000225 0.000179 0.0000286 0.0000403 0.000295 0.000322 1986 4 2 46522 -0.045847 0.136724 0.1831787 0.0011257 -0.000232 -0.000003 0.000224 0.000177 0.0000283 0.0000405 0.000295 0.000322 1986 4 3 46523 -0.047145 0.138174 0.1817545 0.0012061 0.000296 -0.000145 0.000224 0.000175 0.0000287 0.0000406 0.000295 0.000323 1986 4 4 46524 -0.051512 0.142541 0.1806027 0.0013840 0.000271 0.000157 0.000225 0.000173 0.0000291 0.0000412 0.000295 0.000322 1986 4 5 46525 -0.052279 0.142567 0.1791843 0.0016128 -0.000210 0.000447 0.000224 0.000170 0.0000295 0.0000418 0.000295 0.000322 1986 4 6 46526 -0.053601 0.143170 0.1772687 0.0018397 -0.000196 0.000842 0.000225 0.000168 0.0000300 0.0000425 0.000296 0.000325 1986 4 7 46527 -0.057373 0.146000 0.1753049 0.0020233 0.000505 0.001421 0.000226 0.000167 0.0000306 0.0000432 0.000298 0.000329 1986 4 8 46528 -0.058250 0.146560 0.1735924 0.0021368 0.000560 0.001197 0.000226 0.000165 0.0000310 0.0000437 0.000298 0.000332 1986 4 9 46529 -0.059484 0.148808 0.1715004 0.0021461 0.000147 0.000654 0.000226 0.000163 0.0000311 0.0000441 0.000297 0.000331 1986 4 10 46530 -0.061665 0.152286 0.1691190 0.0020152 -0.001683 0.000023 0.000227 0.000162 0.0000313 0.0000443 0.000297 0.000332 1986 4 11 46531 -0.061803 0.154132 0.1669342 0.0017472 -0.003940 -0.000625 0.000227 0.000162 0.0000316 0.0000444 0.000297 0.000333 1986 4 12 46532 -0.063029 0.157534 0.1652925 0.0014085 -0.002899 -0.000494 0.000228 0.000163 0.0000315 0.0000446 0.000296 0.000332 1986 4 13 46533 -0.065117 0.160397 0.1642203 0.0011047 -0.001251 -0.000220 0.000229 0.000163 0.0000315 0.0000445 0.000294 0.000329 1986 4 14 46534 -0.066022 0.161367 0.1634773 0.0009274 0.000397 0.000055 0.000229 0.000164 0.0000314 0.0000443 0.000292 0.000327 1986 4 15 46535 -0.067708 0.163869 0.1627280 0.0009109 0.000588 0.000232 0.000230 0.000165 0.0000312 0.0000441 0.000290 0.000324 1986 4 16 46536 -0.069373 0.166144 0.1617502 0.0010263 0.000334 0.000380 0.000232 0.000166 0.0000310 0.0000438 0.000288 0.000320 1986 4 17 46537 -0.069554 0.167048 0.1604856 0.0012131 0.000080 0.000528 0.000232 0.000167 0.0000307 0.0000435 0.000285 0.000316 1986 4 18 46538 -0.070819 0.168984 0.1589925 0.0014201 -0.000174 0.000676 0.000236 0.000170 0.0000305 0.0000431 0.000282 0.000312 1986 4 19 46539 -0.073557 0.171520 0.1573664 0.0016285 0.000119 0.000384 0.000241 0.000175 0.0000302 0.0000427 0.000282 0.000311 1986 4 20 46540 -0.074932 0.173074 0.1556575 0.0018425 0.000349 0.000309 0.000246 0.000180 0.0000298 0.0000421 0.000281 0.000310 1986 4 21 46541 -0.075969 0.174784 0.1538263 0.0020593 0.000519 0.000335 0.000250 0.000184 0.0000294 0.0000415 0.000281 0.000308 1986 4 22 46542 -0.078250 0.177696 0.1517988 0.0022440 0.000689 0.000361 0.000253 0.000188 0.0000289 0.0000409 0.000280 0.000306 1986 4 23 46543 -0.079483 0.178670 0.1495591 0.0023336 0.000859 0.000387 0.000256 0.000192 0.0000285 0.0000403 0.000279 0.000304 1986 4 24 46544 -0.080191 0.178548 0.1472041 0.0022713 0.001029 0.000413 0.000259 0.000195 0.0000280 0.0000394 0.000278 0.000301 1986 4 25 46545 -0.081851 0.181749 0.1449288 0.0020472 0.000983 0.000428 0.000261 0.000198 0.0000273 0.0000386 0.000276 0.000297 1986 4 26 46546 -0.082837 0.184568 0.1429454 0.0017187 0.000869 0.000441 0.000262 0.000199 0.0000266 0.0000376 0.000273 0.000292 1986 4 27 46547 -0.083612 0.186061 0.1413707 0.0013916 0.000755 0.000454 0.000263 0.000201 0.0000259 0.0000366 0.000271 0.000287 1986 4 28 46548 -0.084538 0.189318 0.1401569 0.0011738 0.000641 0.000466 0.000263 0.000202 0.0000252 0.0000357 0.000268 0.000282 1986 4 29 46549 -0.084819 0.190546 0.1391124 0.0011286 0.000527 0.000479 0.000263 0.000203 0.0000246 0.0000348 0.000265 0.000277 1986 4 30 46550 -0.085463 0.192050 0.1379952 0.0012521 0.000480 0.000361 0.000263 0.000204 0.0000240 0.0000337 0.000263 0.000272 1986 5 1 46551 -0.086043 0.195742 0.1366275 0.0014852 0.000455 0.000199 0.000262 0.000204 0.0000230 0.0000328 0.000260 0.000265 1986 5 2 46552 -0.085960 0.196133 0.1349566 0.0017465 0.000429 0.000038 0.000262 0.000204 0.0000224 0.0000317 0.000257 0.000260 1986 5 3 46553 -0.085132 0.199277 0.1330423 0.0019657 0.000404 -0.000124 0.000263 0.000205 0.0000219 0.0000316 0.000255 0.000255 1986 5 4 46554 -0.084028 0.205916 0.1309936 0.0021013 0.000377 -0.000143 0.000265 0.000207 0.0000223 0.0000316 0.000255 0.000256 1986 5 5 46555 -0.085840 0.205873 0.1288847 0.0021392 0.000349 -0.000099 0.000265 0.000209 0.0000228 0.0000323 0.000256 0.000262 1986 5 6 46556 -0.089159 0.205171 0.1267828 0.0020842 0.000321 -0.000054 0.000264 0.000210 0.0000233 0.0000331 0.000258 0.000268 1986 5 7 46557 -0.090153 0.208453 0.1247588 0.0019517 0.000292 -0.000010 0.000264 0.000211 0.0000239 0.0000339 0.000260 0.000274 1986 5 8 46558 -0.090866 0.209480 0.1228808 0.0017651 0.000264 0.000035 0.000263 0.000211 0.0000245 0.0000347 0.000262 0.000280 1986 5 9 46559 -0.092213 0.211215 0.1212085 0.0015536 0.000236 0.000080 0.000263 0.000212 0.0000252 0.0000355 0.000263 0.000286 1986 5 10 46560 -0.093501 0.214306 0.1197714 0.0013497 0.000248 0.000116 0.000263 0.000212 0.0000257 0.0000363 0.000264 0.000290 1986 5 11 46561 -0.095155 0.215096 0.1185433 0.0011815 0.000273 0.000151 0.000263 0.000213 0.0000261 0.0000369 0.000265 0.000293 1986 5 12 46562 -0.095579 0.216903 0.1174532 0.0010655 0.000298 0.000185 0.000263 0.000213 0.0000265 0.0000375 0.000266 0.000296 1986 5 13 46563 -0.095856 0.219587 0.1164184 0.0010041 0.000323 0.000219 0.000263 0.000214 0.0000270 0.0000381 0.000266 0.000298 1986 5 14 46564 -0.096986 0.220816 0.1153743 0.0009913 0.000348 0.000253 0.000262 0.000214 0.0000274 0.0000386 0.000267 0.000301 1986 5 15 46565 -0.096746 0.222474 0.1142927 0.0010235 0.000156 0.000452 0.000261 0.000214 0.0000276 0.0000390 0.000267 0.000301 1986 5 16 46566 -0.096946 0.225070 0.1132297 0.0011059 -0.000026 0.000587 0.000260 0.000216 0.0000278 0.0000393 0.000267 0.000303 1986 5 17 46567 -0.098738 0.227894 0.1121359 0.0012455 -0.000113 0.000579 0.000259 0.000217 0.0000280 0.0000396 0.000268 0.000307 1986 5 18 46568 -0.099439 0.230550 0.1108146 0.0014323 -0.000943 0.000224 0.000259 0.000220 0.0000281 0.0000398 0.000270 0.000311 1986 5 19 46569 -0.099613 0.233095 0.1092362 0.0016297 -0.002533 -0.000485 0.000260 0.000223 0.0000283 0.0000398 0.000271 0.000317 1986 5 20 46570 -0.100916 0.235574 0.1075490 0.0017821 -0.001073 -0.000201 0.000260 0.000226 0.0000282 0.0000398 0.000271 0.000320 1986 5 21 46571 -0.102259 0.237476 0.1058158 0.0018342 0.000978 0.000275 0.000258 0.000228 0.0000279 0.0000395 0.000271 0.000323 1986 5 22 46572 -0.102151 0.239578 0.1040705 0.0017524 0.003030 0.000752 0.000257 0.000230 0.0000277 0.0000390 0.000272 0.000326 1986 5 23 46573 -0.101809 0.241424 0.1023776 0.0015439 0.002527 0.000495 0.000254 0.000231 0.0000273 0.0000385 0.000271 0.000326 1986 5 24 46574 -0.103266 0.242343 0.1008735 0.0012627 0.001336 0.000041 0.000250 0.000232 0.0000267 0.0000376 0.000269 0.000325 1986 5 25 46575 -0.104650 0.244030 0.0996738 0.0009928 0.000946 -0.000140 0.000244 0.000231 0.0000259 0.0000366 0.000266 0.000321 1986 5 26 46576 -0.104327 0.246261 0.0987623 0.0008130 0.000819 -0.000230 0.000239 0.000231 0.0000250 0.0000355 0.000263 0.000317 1986 5 27 46577 -0.103810 0.248420 0.0980162 0.0007634 0.000692 -0.000321 0.000236 0.000230 0.0000242 0.0000343 0.000260 0.000313 1986 5 28 46578 -0.103478 0.250795 0.0972786 0.0008333 0.000565 -0.000411 0.000233 0.000229 0.0000235 0.0000333 0.000257 0.000309 1986 5 29 46579 -0.103394 0.252685 0.0964215 0.0009736 0.000438 -0.000502 0.000230 0.000228 0.0000228 0.0000322 0.000254 0.000305 1986 5 30 46580 -0.103757 0.255091 0.0953865 0.0011229 0.001088 0.000101 0.000228 0.000227 0.0000220 0.0000311 0.000251 0.000301 1986 5 31 46581 -0.103662 0.257546 0.0941947 0.0012301 0.001222 0.000179 0.000225 0.000224 0.0000212 0.0000301 0.000249 0.000296 1986 6 1 46582 -0.103203 0.258502 0.0929205 0.0012649 0.001071 -0.000022 0.000223 0.000221 0.0000205 0.0000291 0.000247 0.000292 1986 6 2 46583 -0.103457 0.260241 0.0916570 0.0012171 0.000921 -0.000224 0.000220 0.000218 0.0000199 0.0000282 0.000245 0.000288 1986 6 3 46584 -0.103999 0.262623 0.0904910 0.0010913 0.000770 -0.000425 0.000218 0.000215 0.0000193 0.0000272 0.000243 0.000284 1986 6 4 46585 -0.103226 0.264114 0.0894898 0.0009023 0.000663 -0.000419 0.000216 0.000212 0.0000186 0.0000264 0.000241 0.000279 1986 6 5 46586 -0.102557 0.266954 0.0886971 0.0006734 0.000571 -0.000346 0.000214 0.000209 0.0000180 0.0000255 0.000239 0.000274 1986 6 6 46587 -0.103311 0.270155 0.0881348 0.0004347 0.000480 -0.000273 0.000213 0.000206 0.0000174 0.0000246 0.000237 0.000269 1986 6 7 46588 -0.103077 0.271933 0.0878019 0.0002210 0.000388 -0.000200 0.000212 0.000202 0.0000168 0.0000239 0.000235 0.000265 1986 6 8 46589 -0.103195 0.274822 0.0876686 0.0000659 0.000296 -0.000127 0.000210 0.000198 0.0000164 0.0000231 0.000233 0.000259 1986 6 9 46590 -0.104002 0.277890 0.0876704 -0.0000055 0.000514 0.000047 0.000210 0.000195 0.0000158 0.0000223 0.000230 0.000253 1986 6 10 46591 -0.101856 0.278906 0.0877057 0.0000168 0.000835 0.000254 0.000208 0.000191 0.0000152 0.0000216 0.000227 0.000247 1986 6 11 46592 -0.100729 0.280367 0.0876598 0.0001247 0.001156 0.000462 0.000206 0.000186 0.0000147 0.0000209 0.000225 0.000241 1986 6 12 46593 -0.101345 0.282822 0.0874371 0.0002970 0.001477 0.000669 0.000203 0.000182 0.0000143 0.0000203 0.000222 0.000236 1986 6 13 46594 -0.098962 0.284537 0.0869838 0.0005080 0.000593 0.000380 0.000200 0.000177 0.0000140 0.0000197 0.000221 0.000230 1986 6 14 46595 -0.098227 0.286070 0.0862991 0.0007345 0.000149 0.000116 0.000197 0.000173 0.0000135 0.0000191 0.000219 0.000224 1986 6 15 46596 -0.098022 0.287708 0.0854683 0.0009548 0.000256 -0.000027 0.000192 0.000168 0.0000130 0.0000184 0.000217 0.000217 1986 6 16 46597 -0.093640 0.290196 0.0845017 0.0011396 0.000362 -0.000170 0.000187 0.000162 0.0000124 0.0000177 0.000215 0.000211 1986 6 17 46598 -0.092492 0.293759 0.0833743 0.0012469 0.000469 -0.000313 0.000182 0.000156 0.0000120 0.0000170 0.000213 0.000205 1986 6 18 46599 -0.093738 0.295499 0.0821184 0.0012353 0.000417 0.000157 0.000176 0.000151 0.0000115 0.0000163 0.000210 0.000199 1986 6 19 46600 -0.091354 0.296186 0.0808940 0.0010922 0.000418 0.000085 0.000170 0.000145 0.0000110 0.0000158 0.000207 0.000191 1986 6 20 46601 -0.089614 0.298782 0.0798663 0.0008560 0.000446 -0.000052 0.000169 0.000144 0.0000109 0.0000157 0.000205 0.000188 1986 6 21 46602 -0.088152 0.301491 0.0791136 0.0006101 0.000474 -0.000061 0.000175 0.000148 0.0000112 0.0000159 0.000204 0.000189 1986 6 22 46603 -0.085876 0.303479 0.0786014 0.0004476 0.000501 -0.000069 0.000180 0.000152 0.0000115 0.0000164 0.000204 0.000191 1986 6 23 46604 -0.086012 0.305836 0.0782005 0.0004273 0.000528 -0.000078 0.000186 0.000155 0.0000119 0.0000168 0.000203 0.000192 1986 6 24 46605 -0.085418 0.307914 0.0777450 0.0005477 0.000545 -0.000100 0.000191 0.000159 0.0000123 0.0000174 0.000202 0.000192 1986 6 25 46606 -0.083284 0.309853 0.0771065 0.0007529 0.000560 -0.000125 0.000196 0.000162 0.0000126 0.0000179 0.000201 0.000192 1986 6 26 46607 -0.082060 0.311520 0.0762385 0.0009644 0.000574 -0.000151 0.000201 0.000165 0.0000130 0.0000185 0.000199 0.000192 1986 6 27 46608 -0.080420 0.313360 0.0751783 0.0011166 0.000588 -0.000176 0.000205 0.000167 0.0000135 0.0000191 0.000198 0.000192 1986 6 28 46609 -0.078588 0.316492 0.0740155 0.0011773 0.000602 -0.000201 0.000209 0.000169 0.0000140 0.0000197 0.000197 0.000191 1986 6 29 46610 -0.076621 0.318933 0.0728502 0.0011465 0.000615 -0.000173 0.000212 0.000170 0.0000144 0.0000203 0.000195 0.000190 1986 6 30 46611 -0.074451 0.320607 0.0717611 0.0010426 0.000627 -0.000126 0.000216 0.000172 0.0000148 0.0000209 0.000192 0.000188 1986 7 1 46612 -0.073334 0.323354 0.0707994 0.0008884 0.000639 -0.000080 0.000218 0.000173 0.0000152 0.0000216 0.000190 0.000186 1986 7 2 46613 -0.071983 0.325637 0.0699975 0.0007054 0.000651 -0.000033 0.000220 0.000174 0.0000157 0.0000222 0.000188 0.000184 1986 7 3 46614 -0.070911 0.327424 0.0693745 0.0005151 0.000663 0.000014 0.000222 0.000174 0.0000162 0.0000228 0.000186 0.000182 1986 7 4 46615 -0.070777 0.330037 0.0689339 0.0003422 0.000608 0.000024 0.000222 0.000174 0.0000166 0.0000234 0.000184 0.000179 1986 7 5 46616 -0.069168 0.332239 0.0686554 0.0002137 0.000530 0.000022 0.000221 0.000172 0.0000169 0.0000239 0.000181 0.000175 1986 7 6 46617 -0.066981 0.333902 0.0684876 0.0001537 0.000452 0.000020 0.000220 0.000171 0.0000172 0.0000243 0.000178 0.000172 1986 7 7 46618 -0.065515 0.336439 0.0683504 0.0001769 0.000552 -0.000004 0.000221 0.000170 0.0000175 0.0000247 0.000178 0.000171 1986 7 8 46619 -0.063897 0.339177 0.0681472 0.0002825 0.000682 -0.000033 0.000222 0.000168 0.0000177 0.0000249 0.000178 0.000171 1986 7 9 46620 -0.062693 0.340084 0.0677893 0.0004530 0.000715 -0.000040 0.000223 0.000166 0.0000178 0.0000252 0.000177 0.000168 1986 7 10 46621 -0.061131 0.341316 0.0672218 0.0006572 0.000717 -0.000041 0.000222 0.000163 0.0000178 0.0000252 0.000176 0.000166 1986 7 11 46622 -0.058663 0.345906 0.0664338 0.0008587 0.000719 -0.000041 0.000220 0.000160 0.0000179 0.0000253 0.000175 0.000163 1986 7 12 46623 -0.057398 0.348918 0.0654582 0.0010229 0.000721 -0.000042 0.000218 0.000157 0.0000179 0.0000253 0.000174 0.000161 1986 7 13 46624 -0.057398 0.347593 0.0643623 0.0011224 0.000723 -0.000043 0.000215 0.000153 0.0000179 0.0000253 0.000174 0.000158 1986 7 14 46625 -0.056716 0.347886 0.0632329 0.0011392 0.000592 0.000028 0.000214 0.000151 0.0000179 0.0000254 0.000174 0.000159 1986 7 15 46626 -0.054858 0.350287 0.0621577 0.0010658 0.000440 0.000110 0.000214 0.000153 0.0000180 0.0000254 0.000175 0.000161 1986 7 16 46627 -0.052971 0.350954 0.0612118 0.0009098 0.000289 0.000192 0.000213 0.000153 0.0000180 0.0000254 0.000175 0.000163 1986 7 17 46628 -0.051800 0.351487 0.0604450 0.0006983 0.000138 0.000274 0.000213 0.000155 0.0000180 0.0000255 0.000176 0.000164 1986 7 18 46629 -0.050238 0.352987 0.0598668 0.0004790 0.000894 0.000065 0.000215 0.000158 0.0000180 0.0000254 0.000176 0.000164 1986 7 19 46630 -0.047624 0.353871 0.0594264 0.0003096 0.000967 0.000065 0.000217 0.000161 0.0000179 0.0000253 0.000176 0.000163 1986 7 20 46631 -0.045398 0.355299 0.0590703 0.0002408 0.000773 0.000147 0.000217 0.000163 0.0000178 0.0000251 0.000176 0.000162 1986 7 21 46632 -0.044072 0.358332 0.0587435 0.0002973 0.000580 0.000228 0.000218 0.000165 0.0000176 0.0000250 0.000176 0.000161 1986 7 22 46633 -0.041663 0.359707 0.0583769 0.0004672 0.000386 0.000310 0.000218 0.000167 0.0000175 0.0000248 0.000176 0.000160 1986 7 23 46634 -0.038253 0.358752 0.0578960 0.0007041 0.000192 0.000392 0.000216 0.000168 0.0000174 0.0000245 0.000176 0.000158 1986 7 24 46635 -0.036907 0.359680 0.0572301 0.0009392 0.000718 0.000529 0.000215 0.000168 0.0000172 0.0000243 0.000175 0.000156 1986 7 25 46636 -0.036851 0.361962 0.0562699 0.0011002 0.001478 0.000684 0.000212 0.000168 0.0000169 0.0000238 0.000173 0.000153 1986 7 26 46637 -0.034922 0.363321 0.0549824 0.0011342 0.001449 0.000502 0.000208 0.000167 0.0000165 0.0000233 0.000172 0.000149 1986 7 27 46638 -0.032387 0.365160 0.0536694 0.0010308 0.000838 0.000071 0.000205 0.000167 0.0000161 0.0000230 0.000170 0.000146 1986 7 28 46639 -0.031115 0.366332 0.0527531 0.0008279 0.000429 -0.000112 0.000203 0.000166 0.0000160 0.0000226 0.000171 0.000145 1986 7 29 46640 -0.030088 0.366809 0.0521683 0.0005871 0.000443 -0.000062 0.000203 0.000167 0.0000159 0.0000224 0.000171 0.000145 1986 7 30 46641 -0.028795 0.368553 0.0517897 0.0003614 0.000577 0.000049 0.000203 0.000167 0.0000157 0.0000222 0.000171 0.000144 1986 7 31 46642 -0.027541 0.369340 0.0515494 0.0001797 0.000712 0.000159 0.000202 0.000166 0.0000156 0.0000220 0.000171 0.000143 1986 8 1 46643 -0.026336 0.369239 0.0513961 0.0000530 0.000846 0.000269 0.000201 0.000167 0.0000154 0.0000218 0.000171 0.000142 1986 8 2 46644 -0.025172 0.370372 0.0513098 -0.0000133 0.000980 0.000379 0.000201 0.000167 0.0000152 0.0000216 0.000171 0.000141 1986 8 3 46645 -0.024028 0.371763 0.0512789 -0.0000090 0.000717 0.000040 0.000200 0.000167 0.0000152 0.0000216 0.000171 0.000141 1986 8 4 46646 -0.022959 0.372909 0.0512617 0.0000803 0.000564 -0.000120 0.000201 0.000168 0.0000153 0.0000218 0.000174 0.000143 1986 8 5 46647 -0.021698 0.373200 0.0511589 0.0002622 0.000508 -0.000147 0.000203 0.000171 0.0000156 0.0000221 0.000177 0.000148 1986 8 6 46648 -0.019854 0.373781 0.0508401 0.0005228 0.000453 -0.000175 0.000204 0.000172 0.0000159 0.0000225 0.000180 0.000154 1986 8 7 46649 -0.018045 0.376601 0.0501973 0.0008205 0.000397 -0.000203 0.000204 0.000173 0.0000162 0.0000229 0.000184 0.000160 1986 8 8 46650 -0.017174 0.378303 0.0491956 0.0010937 0.000557 -0.000059 0.000203 0.000174 0.0000165 0.0000233 0.000187 0.000165 1986 8 9 46651 -0.016301 0.377861 0.0479153 0.0012806 0.000791 0.000143 0.000202 0.000173 0.0000167 0.0000236 0.000190 0.000170 1986 8 10 46652 -0.014365 0.378527 0.0465222 0.0013422 0.001024 0.000345 0.000201 0.000173 0.0000169 0.0000239 0.000193 0.000176 1986 8 11 46653 -0.012542 0.379552 0.0452009 0.0012739 0.001257 0.000547 0.000202 0.000173 0.0000171 0.0000242 0.000196 0.000182 1986 8 12 46654 -0.011282 0.379850 0.0440913 0.0011011 0.001491 0.000749 0.000201 0.000173 0.0000173 0.0000245 0.000199 0.000189 1986 8 13 46655 -0.010101 0.380888 0.0432437 0.0008650 0.001042 0.000574 0.000202 0.000174 0.0000175 0.0000248 0.000202 0.000195 1986 8 14 46656 -0.009421 0.382493 0.0425553 0.0006093 0.000328 0.000267 0.000205 0.000177 0.0000178 0.0000250 0.000205 0.000201 1986 8 15 46657 -0.008452 0.383036 0.0419206 0.0003784 0.000360 0.000072 0.000206 0.000179 0.0000179 0.0000253 0.000208 0.000206 1986 8 16 46658 -0.006906 0.383120 0.0414156 0.0002256 0.000571 -0.000082 0.000207 0.000180 0.0000179 0.0000254 0.000210 0.000212 1986 8 17 46659 -0.005732 0.384435 0.0411257 0.0002094 0.000783 -0.000237 0.000209 0.000182 0.0000180 0.0000256 0.000213 0.000218 1986 8 18 46660 -0.004504 0.385396 0.0410133 0.0003666 0.000754 -0.000054 0.000210 0.000182 0.0000182 0.0000259 0.000216 0.000224 1986 8 19 46661 -0.003418 0.385736 0.0407832 0.0006758 0.000650 0.000236 0.000211 0.000183 0.0000186 0.0000262 0.000219 0.000230 1986 8 20 46662 -0.002004 0.387332 0.0400772 0.0010440 0.000574 0.000592 0.000212 0.000183 0.0000188 0.0000265 0.000222 0.000236 1986 8 21 46663 0.000726 0.388154 0.0387692 0.0013403 0.000519 0.000997 0.000210 0.000181 0.0000189 0.0000265 0.000225 0.000242 1986 8 22 46664 0.002695 0.388269 0.0370644 0.0014594 0.000580 0.000140 0.000209 0.000180 0.0000187 0.0000266 0.000227 0.000245 1986 8 23 46665 0.003947 0.389711 0.0354617 0.0013738 0.000488 -0.000190 0.000207 0.000178 0.0000187 0.0000265 0.000230 0.000248 1986 8 24 46666 0.006272 0.390462 0.0342366 0.0011365 0.000348 -0.000359 0.000205 0.000175 0.0000188 0.0000266 0.000232 0.000252 1986 8 25 46667 0.008420 0.390900 0.0333960 0.0008391 0.000209 -0.000528 0.000204 0.000174 0.0000189 0.0000267 0.000235 0.000255 1986 8 26 46668 0.010385 0.391997 0.0328082 0.0005634 0.000070 -0.000698 0.000204 0.000173 0.0000190 0.0000269 0.000238 0.000260 1986 8 27 46669 0.012630 0.392166 0.0323268 0.0003581 0.000878 -0.000920 0.000202 0.000171 0.0000192 0.0000272 0.000241 0.000263 1986 8 28 46670 0.014482 0.392730 0.0320398 0.0002421 0.000994 -0.000860 0.000203 0.000171 0.0000195 0.0000276 0.000242 0.000267 1986 8 29 46671 0.016290 0.393614 0.0318626 0.0002145 0.000836 -0.000683 0.000205 0.000173 0.0000199 0.0000280 0.000244 0.000269 1986 8 30 46672 0.017679 0.393400 0.0316174 0.0002599 0.000680 -0.000393 0.000206 0.000174 0.0000201 0.0000284 0.000245 0.000270 1986 8 31 46673 0.019384 0.393956 0.0312533 0.0003566 0.000524 -0.000103 0.000209 0.000176 0.0000204 0.0000288 0.000245 0.000272 1986 9 1 46674 0.021619 0.395185 0.0307654 0.0004885 0.000368 0.000186 0.000216 0.000179 0.0000207 0.0000291 0.000246 0.000273 1986 9 2 46675 0.022513 0.395713 0.0301612 0.0006500 0.000364 0.000308 0.000221 0.000182 0.0000208 0.0000295 0.000247 0.000276 1986 9 3 46676 0.023642 0.396275 0.0294253 0.0008404 0.000409 0.000377 0.000225 0.000184 0.0000210 0.0000297 0.000247 0.000277 1986 9 4 46677 0.025511 0.396688 0.0285233 0.0010504 0.000454 0.000446 0.000229 0.000186 0.0000212 0.0000300 0.000248 0.000278 1986 9 5 46678 0.026874 0.396807 0.0274272 0.0012537 0.000499 0.000514 0.000233 0.000187 0.0000214 0.0000302 0.000248 0.000280 1986 9 6 46679 0.029528 0.397908 0.0261396 0.0014090 0.000544 0.000583 0.000236 0.000187 0.0000216 0.0000304 0.000248 0.000281 1986 9 7 46680 0.031427 0.399055 0.0247094 0.0014747 0.000470 0.000535 0.000238 0.000189 0.0000216 0.0000305 0.000248 0.000282 1986 9 8 46681 0.031214 0.398296 0.0232339 0.0014279 0.000359 0.000450 0.000241 0.000192 0.0000216 0.0000305 0.000247 0.000282 1986 9 9 46682 0.032832 0.397898 0.0218326 0.0012777 0.000247 0.000366 0.000244 0.000196 0.0000216 0.0000305 0.000246 0.000282 1986 9 10 46683 0.035009 0.398758 0.0206091 0.0010667 0.000135 0.000281 0.000248 0.000200 0.0000216 0.0000305 0.000245 0.000282 1986 9 11 46684 0.035765 0.397553 0.0196154 0.0008603 0.000024 0.000196 0.000252 0.000203 0.0000215 0.0000304 0.000244 0.000282 1986 9 12 46685 0.037253 0.396182 0.0188275 0.0007276 0.000022 0.000160 0.000256 0.000208 0.0000214 0.0000302 0.000242 0.000281 1986 9 13 46686 0.039326 0.396725 0.0181404 0.0007191 0.000054 0.000138 0.000261 0.000212 0.0000212 0.0000300 0.000241 0.000279 1986 9 14 46687 0.041559 0.396564 0.0174011 0.0008493 0.000086 0.000116 0.000265 0.000216 0.0000211 0.0000298 0.000240 0.000279 1986 9 15 46688 0.043070 0.397293 0.0164617 0.0010897 0.000118 0.000094 0.000269 0.000221 0.0000209 0.0000296 0.000239 0.000278 1986 9 16 46689 0.043184 0.398925 0.0152285 0.0013783 0.000150 0.000072 0.000274 0.000226 0.0000208 0.0000293 0.000238 0.000279 1986 9 17 46690 0.044582 0.398477 0.0136946 0.0016409 0.000402 -0.000637 0.000278 0.000231 0.0000206 0.0000292 0.000236 0.000276 1986 9 18 46691 0.046631 0.397983 0.0119683 0.0018169 0.000604 -0.000429 0.000280 0.000235 0.0000205 0.0000292 0.000234 0.000273 1986 9 19 46692 0.047001 0.397867 0.0101257 0.0018754 0.000522 -0.000278 0.000282 0.000239 0.0000207 0.0000293 0.000233 0.000274 1986 9 20 46693 0.047379 0.397298 0.0082561 0.0018167 0.000310 -0.000423 0.000285 0.000243 0.0000210 0.0000298 0.000233 0.000276 1986 9 21 46694 0.048785 0.397103 0.0064828 0.0016659 0.000099 -0.000569 0.000288 0.000247 0.0000214 0.0000302 0.000233 0.000279 1986 9 22 46695 0.050643 0.397093 0.0048997 0.0014626 0.000119 -0.000474 0.000291 0.000250 0.0000216 0.0000306 0.000233 0.000281 1986 9 23 46696 0.052185 0.398522 0.0035448 0.0012505 0.000209 -0.000306 0.000292 0.000252 0.0000219 0.0000309 0.000232 0.000284 1986 9 24 46697 0.052818 0.398579 0.0024012 0.0010697 0.000299 -0.000138 0.000293 0.000254 0.0000220 0.0000312 0.000231 0.000284 1986 9 25 46698 0.053429 0.396034 0.0014121 0.0009515 0.000390 0.000030 0.000294 0.000255 0.0000223 0.0000315 0.000230 0.000285 1986 9 26 46699 0.054157 0.396459 0.0004959 0.0009153 0.000480 0.000197 0.000294 0.000255 0.0000225 0.0000317 0.000229 0.000285 1986 9 27 46700 0.055032 0.396299 -0.0004371 0.0009672 0.000436 0.000287 0.000294 0.000255 0.0000226 0.0000320 0.000228 0.000285 1986 9 28 46701 0.056542 0.393824 -0.0014709 0.0011024 0.000349 0.000351 0.000294 0.000255 0.0000228 0.0000323 0.000228 0.000285 1986 9 29 46702 0.057860 0.395249 -0.0026769 0.0013075 0.000262 0.000415 0.000293 0.000254 0.0000230 0.0000325 0.000227 0.000285 1986 9 30 46703 0.059345 0.395220 -0.0041105 0.0015611 0.000176 0.000479 0.000291 0.000252 0.0000232 0.0000328 0.000226 0.000284 1986 10 1 46704 0.061260 0.392709 -0.0058047 0.0018301 0.000089 0.000543 0.000290 0.000251 0.0000234 0.0000330 0.000225 0.000284 1986 10 2 46705 0.062202 0.394591 -0.0077578 0.0020677 0.000105 0.000482 0.000289 0.000249 0.0000234 0.0000331 0.000224 0.000282 1986 10 3 46706 0.062924 0.395398 -0.0099167 0.0022196 0.000152 0.000386 0.000287 0.000246 0.0000234 0.0000331 0.000223 0.000280 1986 10 4 46707 0.064238 0.394076 -0.0121718 0.0022411 0.000199 0.000289 0.000285 0.000243 0.0000234 0.0000331 0.000221 0.000277 1986 10 5 46708 0.064978 0.395995 -0.0143757 0.0021194 0.000245 0.000192 0.000282 0.000239 0.0000234 0.0000331 0.000220 0.000275 1986 10 6 46709 0.065633 0.396768 -0.0163844 0.0018864 0.000292 0.000096 0.000279 0.000235 0.0000234 0.0000330 0.000219 0.000274 1986 10 7 46710 0.067036 0.394754 -0.0181098 0.0016117 0.000307 -0.000106 0.000276 0.000231 0.0000233 0.0000329 0.000217 0.000270 1986 10 8 46711 0.068348 0.393649 -0.0195596 0.0013769 0.000313 -0.000341 0.000272 0.000226 0.0000231 0.0000327 0.000215 0.000267 1986 10 9 46712 0.069705 0.393577 -0.0208299 0.0012436 0.000318 -0.000576 0.000269 0.000222 0.0000230 0.0000325 0.000214 0.000264 1986 10 10 46713 0.071281 0.393436 -0.0220613 0.0012334 0.000324 -0.000811 0.000266 0.000218 0.0000228 0.0000323 0.000212 0.000261 1986 10 11 46714 0.071982 0.392577 -0.0233843 0.0013279 0.000255 -0.000436 0.000262 0.000215 0.0000227 0.0000321 0.000212 0.000260 1986 10 12 46715 0.072746 0.391843 -0.0248714 0.0014855 0.000259 -0.000370 0.000259 0.000211 0.0000225 0.0000318 0.000212 0.000258 1986 10 13 46716 0.074393 0.391321 -0.0265085 0.0016630 0.000270 -0.000335 0.000257 0.000209 0.0000223 0.0000316 0.000211 0.000256 1986 10 14 46717 0.075512 0.390506 -0.0282410 0.0018283 0.000281 -0.000300 0.000254 0.000205 0.0000222 0.0000314 0.000211 0.000254 1986 10 15 46718 0.077136 0.390707 -0.0300254 0.0019591 0.000292 -0.000264 0.000251 0.000203 0.0000220 0.0000311 0.000210 0.000252 1986 10 16 46719 0.079493 0.390908 -0.0318455 0.0020328 0.000303 -0.000229 0.000248 0.000200 0.0000219 0.0000309 0.000209 0.000251 1986 10 17 46720 0.080636 0.390325 -0.0337273 0.0020200 0.000084 -0.000212 0.000246 0.000198 0.0000217 0.0000307 0.000208 0.000248 1986 10 18 46721 0.082553 0.390183 -0.0360391 0.0018956 -0.000496 0.000195 0.000243 0.000197 0.0000216 0.0000307 0.000209 0.000249 1986 10 19 46722 0.085006 0.390037 -0.0383223 0.0016754 -0.001506 0.001198 0.000242 0.000197 0.0000217 0.0000305 0.000211 0.000254 1986 10 20 46723 0.085562 0.389983 -0.0394032 0.0014331 -0.000984 0.001315 0.000239 0.000196 0.0000216 0.0000304 0.000212 0.000258 1986 10 21 46724 0.087112 0.389908 -0.0405938 0.0012478 -0.000202 -0.000082 0.000237 0.000195 0.0000214 0.0000302 0.000214 0.000260 1986 10 22 46725 0.089179 0.389789 -0.0417534 0.0011529 0.000108 -0.000708 0.000234 0.000194 0.0000210 0.0000298 0.000214 0.000260 1986 10 23 46726 0.089351 0.389954 -0.0428118 0.0011381 0.000272 -0.000994 0.000230 0.000192 0.0000207 0.0000292 0.000215 0.000259 1986 10 24 46727 0.090447 0.388944 -0.0441520 0.0011689 0.000436 -0.000403 0.000225 0.000190 0.0000202 0.0000286 0.000216 0.000257 1986 10 25 46728 0.091607 0.388467 -0.0454402 0.0012149 0.000309 -0.000145 0.000222 0.000188 0.0000197 0.0000279 0.000216 0.000255 1986 10 26 46729 0.091959 0.388622 -0.0467210 0.0012730 0.000090 -0.000038 0.000221 0.000186 0.0000192 0.0000272 0.000217 0.000254 1986 10 27 46730 0.094457 0.386544 -0.0482757 0.0013669 -0.001443 0.000568 0.000219 0.000184 0.0000187 0.0000264 0.000217 0.000251 1986 10 28 46731 0.096321 0.386123 -0.0495627 0.0015331 -0.001773 0.000334 0.000216 0.000182 0.0000181 0.0000256 0.000216 0.000247 1986 10 29 46732 0.095687 0.387366 -0.0506991 0.0017811 -0.001318 -0.000384 0.000212 0.000178 0.0000174 0.0000247 0.000215 0.000242 1986 10 30 46733 0.095890 0.386045 -0.0524676 0.0020466 -0.000795 -0.001170 0.000208 0.000175 0.0000169 0.0000239 0.000214 0.000236 1986 10 31 46734 0.096945 0.385995 -0.0551862 0.0022110 -0.000678 -0.001154 0.000204 0.000171 0.0000163 0.0000230 0.000211 0.000229 1986 11 1 46735 0.098329 0.386545 -0.0575528 0.0021892 -0.000162 -0.000704 0.000199 0.000167 0.0000157 0.0000224 0.000208 0.000222 1986 11 2 46736 0.100985 0.384142 -0.0594428 0.0019835 0.000154 -0.000236 0.000194 0.000163 0.0000153 0.0000217 0.000206 0.000220 1986 11 3 46737 0.103408 0.382847 -0.0611888 0.0016622 0.000191 -0.000115 0.000189 0.000158 0.0000150 0.0000212 0.000204 0.000219 1986 11 4 46738 0.104277 0.382432 -0.0627098 0.0013225 0.000161 -0.000149 0.000184 0.000154 0.0000147 0.0000208 0.000202 0.000218 1986 11 5 46739 0.104880 0.380688 -0.0638929 0.0010598 0.000063 -0.000240 0.000178 0.000148 0.0000143 0.0000203 0.000199 0.000216 1986 11 6 46740 0.106280 0.379350 -0.0648446 0.0009370 0.000036 -0.000420 0.000172 0.000143 0.0000139 0.0000199 0.000196 0.000212 1986 11 7 46741 0.107664 0.377949 -0.0658090 0.0009645 0.000269 -0.000620 0.000170 0.000141 0.0000138 0.0000197 0.000194 0.000211 1986 11 8 46742 0.109394 0.377261 -0.0669128 0.0011077 0.000736 -0.000817 0.000172 0.000144 0.0000140 0.0000198 0.000194 0.000212 1986 11 9 46743 0.111930 0.377553 -0.0681279 0.0013124 0.000600 -0.000479 0.000175 0.000146 0.0000142 0.0000201 0.000195 0.000215 1986 11 10 46744 0.113627 0.376773 -0.0694882 0.0015273 0.000331 -0.000024 0.000178 0.000149 0.0000145 0.0000204 0.000196 0.000219 1986 11 11 46745 0.115270 0.376206 -0.0710464 0.0017101 0.000088 -0.000100 0.000181 0.000152 0.0000147 0.0000207 0.000197 0.000222 1986 11 12 46746 0.117459 0.375669 -0.0727924 0.0018271 -0.000146 -0.000344 0.000184 0.000155 0.0000148 0.0000210 0.000198 0.000225 1986 11 13 46747 0.118439 0.373961 -0.0746568 0.0018543 -0.000380 -0.000588 0.000187 0.000158 0.0000150 0.0000213 0.000198 0.000228 1986 11 14 46748 0.119728 0.373016 -0.0765311 0.0017826 -0.000335 -0.000525 0.000190 0.000160 0.0000152 0.0000216 0.000199 0.000231 1986 11 15 46749 0.121164 0.372349 -0.0782905 0.0016230 -0.000140 -0.000298 0.000194 0.000163 0.0000155 0.0000219 0.000201 0.000235 1986 11 16 46750 0.120506 0.370524 -0.0798324 0.0014066 -0.000142 -0.000276 0.000197 0.000166 0.0000157 0.0000221 0.000202 0.000237 1986 11 17 46751 0.120014 0.368431 -0.0811128 0.0011782 -0.000202 -0.000316 0.000200 0.000168 0.0000158 0.0000224 0.000203 0.000240 1986 11 18 46752 0.120206 0.366946 -0.0821556 0.0009834 -0.000263 -0.000357 0.000203 0.000169 0.0000160 0.0000226 0.000204 0.000243 1986 11 19 46753 0.120168 0.366205 -0.0830360 0.0008568 -0.000324 -0.000397 0.000205 0.000170 0.0000162 0.0000229 0.000206 0.000246 1986 11 20 46754 0.121344 0.364930 -0.0838517 0.0008145 -0.000385 -0.000437 0.000207 0.000171 0.0000164 0.0000231 0.000207 0.000249 1986 11 21 46755 0.121959 0.363337 -0.0846937 0.0008550 -0.000239 -0.000584 0.000209 0.000172 0.0000165 0.0000233 0.000209 0.000252 1986 11 22 46756 0.121191 0.362952 -0.0856263 0.0009648 -0.000028 -0.000765 0.000209 0.000171 0.0000166 0.0000235 0.000210 0.000254 1986 11 23 46757 0.121355 0.362111 -0.0866900 0.0011272 0.000184 -0.000945 0.000209 0.000171 0.0000167 0.0000236 0.000212 0.000256 1986 11 24 46758 0.121567 0.360207 -0.0879142 0.0013262 0.000395 -0.001125 0.000209 0.000170 0.0000168 0.0000237 0.000214 0.000259 1986 11 25 46759 0.121189 0.358830 -0.0893270 0.0015430 0.000607 -0.001306 0.000208 0.000169 0.0000169 0.0000240 0.000216 0.000262 1986 11 26 46760 0.121575 0.357595 -0.0909486 0.0017477 0.000526 -0.001208 0.000208 0.000168 0.0000171 0.0000243 0.000218 0.000264 1986 11 27 46761 0.122181 0.356430 -0.0927649 0.0018948 0.000355 -0.001024 0.000207 0.000167 0.0000175 0.0000248 0.000219 0.000267 1986 11 28 46762 0.122274 0.355401 -0.0947013 0.0019330 0.000185 -0.000840 0.000206 0.000166 0.0000179 0.0000253 0.000221 0.000270 1986 11 29 46763 0.122592 0.354119 -0.0966212 0.0018292 0.000014 -0.000656 0.000204 0.000164 0.0000183 0.0000259 0.000223 0.000273 1986 11 30 46764 0.123648 0.353225 -0.0983624 0.0015947 -0.000157 -0.000472 0.000203 0.000163 0.0000188 0.0000265 0.000225 0.000276 1986 12 1 46765 0.124857 0.351786 -0.0998045 0.0012935 -0.000182 -0.000455 0.000201 0.000161 0.0000192 0.0000272 0.000227 0.000279 1986 12 2 46766 0.126180 0.349536 -0.1009317 0.0010223 -0.000161 -0.000491 0.000199 0.000159 0.0000196 0.0000277 0.000230 0.000281 1986 12 3 46767 0.127951 0.348035 -0.1018440 0.0008703 -0.000140 -0.000527 0.000198 0.000158 0.0000200 0.0000283 0.000232 0.000283 1986 12 4 46768 0.129655 0.346710 -0.1027100 0.0008805 -0.000118 -0.000563 0.000195 0.000155 0.0000204 0.0000289 0.000235 0.000285 1986 12 5 46769 0.131540 0.345843 -0.1036945 0.0010357 -0.000097 -0.000599 0.000193 0.000153 0.0000209 0.0000295 0.000237 0.000288 1986 12 6 46770 0.133065 0.345652 -0.1048953 0.0012751 0.000000 -0.000589 0.000190 0.000152 0.0000213 0.0000301 0.000240 0.000290 1986 12 7 46771 0.133544 0.343685 -0.1063038 0.0015265 0.000120 -0.000565 0.000187 0.000150 0.0000217 0.0000308 0.000243 0.000294 1986 12 8 46772 0.134959 0.341369 -0.1078583 0.0017310 0.000240 -0.000541 0.000184 0.000148 0.0000222 0.0000314 0.000245 0.000297 1986 12 9 46773 0.136826 0.340597 -0.1094963 0.0018467 0.000360 -0.000517 0.000182 0.000147 0.0000226 0.0000320 0.000248 0.000300 1986 12 10 46774 0.137514 0.338785 -0.1112160 0.0018404 0.000396 -0.000588 0.000179 0.000146 0.0000231 0.0000328 0.000250 0.000302 1986 12 11 46775 0.138420 0.336523 -0.1133781 0.0016901 0.001249 -0.001238 0.000178 0.000145 0.0000237 0.0000334 0.000253 0.000305 1986 12 12 46776 0.138975 0.335493 -0.1152252 0.0014140 0.001157 -0.001517 0.000180 0.000146 0.0000241 0.0000340 0.000255 0.000304 1986 12 13 46777 0.139227 0.333875 -0.1163097 0.0010842 0.000536 -0.001555 0.000180 0.000146 0.0000244 0.0000345 0.000256 0.000303 1986 12 14 46778 0.140751 0.332078 -0.1169557 0.0007896 -0.000085 -0.001594 0.000182 0.000147 0.0000247 0.0000348 0.000258 0.000303 1986 12 15 46779 0.141012 0.331092 -0.1175734 0.0005879 -0.000290 -0.000948 0.000184 0.000149 0.0000248 0.0000349 0.000258 0.000299 1986 12 16 46780 0.139814 0.329653 -0.1181673 0.0004962 -0.000233 -0.000639 0.000185 0.000149 0.0000246 0.0000348 0.000257 0.000293 1986 12 17 46781 0.140230 0.327829 -0.1187229 0.0005076 -0.000114 -0.000502 0.000187 0.000151 0.0000244 0.0000345 0.000256 0.000287 1986 12 18 46782 0.141111 0.326180 -0.1193083 0.0006063 -0.000217 -0.000366 0.000190 0.000155 0.0000242 0.0000342 0.000253 0.000280 1986 12 19 46783 0.141026 0.325189 -0.1199916 0.0007742 -0.000127 -0.000273 0.000193 0.000158 0.0000239 0.0000339 0.000252 0.000277 1986 12 20 46784 0.141247 0.325270 -0.1208479 0.0009902 0.000088 -0.000203 0.000196 0.000161 0.0000237 0.0000336 0.000252 0.000275 1986 12 21 46785 0.142484 0.324683 -0.1219430 0.0012295 0.000133 -0.000091 0.000199 0.000164 0.0000235 0.0000333 0.000252 0.000273 1986 12 22 46786 0.143741 0.323043 -0.1233000 0.0014650 0.000121 0.000034 0.000201 0.000166 0.0000234 0.0000331 0.000252 0.000273 1986 12 23 46787 0.143748 0.322578 -0.1248930 0.0016688 0.000109 0.000160 0.000203 0.000168 0.0000232 0.0000328 0.000252 0.000272 1986 12 24 46788 0.143749 0.322554 -0.1266578 0.0018137 0.000070 0.000168 0.000206 0.000171 0.0000229 0.0000323 0.000251 0.000270 1986 12 25 46789 0.144553 0.320749 -0.1285078 0.0018736 0.000007 0.000059 0.000208 0.000174 0.0000225 0.0000318 0.000250 0.000266 1986 12 26 46790 0.144617 0.318612 -0.1303479 0.0018291 -0.000057 -0.000050 0.000211 0.000177 0.0000220 0.0000313 0.000249 0.000263 1986 12 27 46791 0.144484 0.317628 -0.1320855 0.0016799 -0.000120 -0.000159 0.000214 0.000180 0.0000217 0.0000306 0.000249 0.000260 1986 12 28 46792 0.145045 0.316712 -0.1336463 0.0014572 -0.000184 -0.000268 0.000217 0.000183 0.0000213 0.0000301 0.000247 0.000256 1986 12 29 46793 0.145196 0.315828 -0.1349949 0.0012254 -0.000247 -0.000376 0.000219 0.000185 0.0000209 0.0000295 0.000246 0.000253 1986 12 30 46794 0.144981 0.314829 -0.1361542 0.0010645 -0.000311 -0.000485 0.000222 0.000188 0.0000205 0.0000288 0.000245 0.000249 1986 12 31 46795 0.145180 0.313064 -0.1372083 0.0010368 -0.000335 -0.000491 0.000225 0.000190 0.0000199 0.0000281 0.000242 0.000243 1987 1 1 46796 0.145593 0.311747 -0.1382708 0.0011157 -0.000348 -0.000465 0.000210 0.000180 0.0000200 0.0000284 0.000212 0.000285 1987 1 2 46797 0.146018 0.311303 -0.1394883 0.0013256 -0.000361 -0.000440 0.000213 0.000181 0.0000194 0.0000275 0.000208 0.000277 1987 1 3 46798 0.146201 0.309698 -0.1409205 0.0015672 -0.000374 -0.000415 0.000215 0.000183 0.0000188 0.0000267 0.000204 0.000270 1987 1 4 46799 0.146845 0.309942 -0.1425665 0.0017620 -0.000387 -0.000390 0.000215 0.000182 0.0000183 0.0000259 0.000201 0.000264 1987 1 5 46800 0.147018 0.309026 -0.1443657 0.0018557 -0.000347 -0.000392 0.000215 0.000181 0.0000178 0.0000252 0.000197 0.000259 1987 1 6 46801 0.146442 0.305543 -0.1462178 0.0018304 -0.000290 -0.000401 0.000214 0.000180 0.0000173 0.0000245 0.000193 0.000252 1987 1 7 46802 0.146427 0.305074 -0.1480102 0.0016989 -0.000233 -0.000410 0.000213 0.000178 0.0000168 0.0000239 0.000190 0.000247 1987 1 8 46803 0.146441 0.304153 -0.1496399 0.0014924 -0.000177 -0.000420 0.000213 0.000176 0.0000165 0.0000233 0.000187 0.000243 1987 1 9 46804 0.145533 0.302510 -0.1510303 0.0012496 -0.000120 -0.000429 0.000211 0.000174 0.0000161 0.0000227 0.000184 0.000239 1987 1 10 46805 0.144231 0.301412 -0.1521481 0.0010093 -0.000083 -0.000436 0.000210 0.000172 0.0000157 0.0000222 0.000180 0.000234 1987 1 11 46806 0.142810 0.299626 -0.1530193 0.0008058 -0.000052 -0.000443 0.000209 0.000170 0.0000153 0.0000216 0.000177 0.000228 1987 1 12 46807 0.141794 0.297885 -0.1537186 0.0006639 -0.000021 -0.000449 0.000208 0.000167 0.0000149 0.0000211 0.000174 0.000224 1987 1 13 46808 0.141079 0.295847 -0.1543407 0.0005957 0.000011 -0.000455 0.000206 0.000165 0.0000146 0.0000206 0.000171 0.000220 1987 1 14 46809 0.140395 0.294278 -0.1549727 0.0006030 0.000042 -0.000462 0.000204 0.000162 0.0000143 0.0000202 0.000168 0.000216 1987 1 15 46810 0.140539 0.292624 -0.1556718 0.0006834 -0.000389 -0.000614 0.000201 0.000159 0.0000140 0.0000201 0.000165 0.000211 1987 1 16 46811 0.140478 0.291969 -0.1564149 0.0008334 -0.000600 -0.000568 0.000200 0.000157 0.0000141 0.0000200 0.000164 0.000210 1987 1 17 46812 0.140270 0.291189 -0.1572616 0.0010422 -0.000596 -0.000378 0.000200 0.000156 0.0000143 0.0000202 0.000163 0.000211 1987 1 18 46813 0.140433 0.289245 -0.1583520 0.0012804 -0.000592 -0.000189 0.000199 0.000154 0.0000145 0.0000206 0.000163 0.000212 1987 1 19 46814 0.139977 0.288263 -0.1597797 0.0014999 -0.000588 0.000001 0.000199 0.000152 0.0000148 0.0000209 0.000163 0.000213 1987 1 20 46815 0.139703 0.285631 -0.1615118 0.0016519 -0.000427 -0.000144 0.000197 0.000150 0.0000150 0.0000211 0.000162 0.000212 1987 1 21 46816 0.139225 0.283676 -0.1631730 0.0017077 -0.000225 -0.000390 0.000195 0.000147 0.0000151 0.0000215 0.000161 0.000211 1987 1 22 46817 0.137916 0.282732 -0.1647918 0.0016603 -0.000201 -0.000315 0.000193 0.000146 0.0000154 0.0000218 0.000161 0.000211 1987 1 23 46818 0.136732 0.280581 -0.1664043 0.0015152 -0.000176 -0.000241 0.000191 0.000144 0.0000157 0.0000223 0.000162 0.000211 1987 1 24 46819 0.136110 0.280894 -0.1678465 0.0012967 -0.000152 -0.000166 0.000189 0.000143 0.0000161 0.0000227 0.000162 0.000212 1987 1 25 46820 0.135834 0.280011 -0.1689966 0.0010574 -0.000165 -0.000147 0.000186 0.000140 0.0000163 0.0000231 0.000161 0.000210 1987 1 26 46821 0.135464 0.277163 -0.1698909 0.0008680 -0.000188 -0.000144 0.000184 0.000138 0.0000166 0.0000234 0.000161 0.000208 1987 1 27 46822 0.135933 0.276566 -0.1706828 0.0007905 -0.000211 -0.000141 0.000181 0.000136 0.0000168 0.0000237 0.000160 0.000206 1987 1 28 46823 0.136541 0.276446 -0.1715507 0.0008517 -0.000234 -0.000138 0.000177 0.000133 0.0000170 0.0000241 0.000159 0.000204 1987 1 29 46824 0.136019 0.276101 -0.1726317 0.0010369 -0.000257 -0.000135 0.000174 0.000130 0.0000172 0.0000243 0.000159 0.000203 1987 1 30 46825 0.135686 0.275545 -0.1739508 0.0013041 -0.000201 -0.000577 0.000170 0.000127 0.0000173 0.0000245 0.000158 0.000200 1987 1 31 46826 0.135209 0.274731 -0.1751497 0.0016029 -0.000192 -0.000630 0.000169 0.000126 0.0000174 0.0000247 0.000157 0.000199 1987 2 1 46827 0.133615 0.273576 -0.1765007 0.0018684 -0.000216 -0.000445 0.000169 0.000127 0.0000176 0.0000247 0.000157 0.000200 1987 2 2 46828 0.131841 0.272400 -0.1785824 0.0020167 -0.000240 -0.000260 0.000169 0.000127 0.0000176 0.0000248 0.000157 0.000200 1987 2 3 46829 0.129526 0.271713 -0.1809793 0.0019891 -0.000263 -0.000074 0.000168 0.000126 0.0000175 0.0000247 0.000157 0.000201 1987 2 4 46830 0.127287 0.269225 -0.1829475 0.0018052 -0.000507 -0.000322 0.000166 0.000125 0.0000174 0.0000247 0.000156 0.000200 1987 2 5 46831 0.128381 0.266321 -0.1846522 0.0015509 -0.000285 -0.000491 0.000164 0.000124 0.0000174 0.0000246 0.000155 0.000198 1987 2 6 46832 0.129060 0.265766 -0.1858744 0.0013236 -0.000153 -0.000481 0.000164 0.000124 0.0000174 0.0000246 0.000154 0.000198 1987 2 7 46833 0.126070 0.265407 -0.1868336 0.0011794 -0.000169 -0.000432 0.000166 0.000125 0.0000175 0.0000246 0.000154 0.000199 1987 2 8 46834 0.126023 0.263251 -0.1881430 0.0011095 -0.000305 -0.000148 0.000167 0.000125 0.0000174 0.0000246 0.000153 0.000197 1987 2 9 46835 0.128397 0.261217 -0.1892017 0.0010737 -0.000569 -0.000239 0.000168 0.000125 0.0000173 0.0000246 0.000152 0.000195 1987 2 10 46836 0.128189 0.261104 -0.1905436 0.0010436 -0.000549 -0.000343 0.000170 0.000126 0.0000174 0.0000246 0.000152 0.000195 1987 2 11 46837 0.127222 0.260199 -0.1917561 0.0010296 -0.000381 -0.000379 0.000173 0.000128 0.0000174 0.0000246 0.000152 0.000195 1987 2 12 46838 0.127198 0.258703 -0.1925814 0.0010802 -0.000213 -0.000416 0.000176 0.000130 0.0000173 0.0000245 0.000151 0.000195 1987 2 13 46839 0.127010 0.258671 -0.1934678 0.0012318 -0.000044 -0.000452 0.000179 0.000132 0.0000173 0.0000245 0.000151 0.000195 1987 2 14 46840 0.125161 0.257552 -0.1948405 0.0014644 -0.000502 -0.000247 0.000182 0.000135 0.0000173 0.0000244 0.000151 0.000195 1987 2 15 46841 0.124460 0.256652 -0.1965549 0.0017157 -0.000553 -0.000140 0.000183 0.000136 0.0000173 0.0000245 0.000150 0.000193 1987 2 16 46842 0.125694 0.256466 -0.1984224 0.0019209 -0.000354 -0.000105 0.000185 0.000138 0.0000173 0.0000245 0.000149 0.000192 1987 2 17 46843 0.125715 0.254816 -0.2003923 0.0020360 -0.000155 -0.000071 0.000186 0.000139 0.0000173 0.0000244 0.000149 0.000190 1987 2 18 46844 0.125298 0.254475 -0.2024144 0.0020405 0.000044 -0.000037 0.000186 0.000140 0.0000173 0.0000244 0.000148 0.000188 1987 2 19 46845 0.124569 0.254496 -0.2044296 0.0019363 -0.000155 -0.000109 0.000186 0.000140 0.0000172 0.0000242 0.000147 0.000186 1987 2 20 46846 0.123931 0.252878 -0.2062961 0.0017505 -0.000189 -0.000089 0.000186 0.000141 0.0000169 0.0000239 0.000147 0.000184 1987 2 21 46847 0.123519 0.251584 -0.2079270 0.0015348 -0.000103 -0.000017 0.000186 0.000142 0.0000167 0.0000236 0.000146 0.000183 1987 2 22 46848 0.122705 0.250811 -0.2093405 0.0013572 -0.000018 0.000054 0.000185 0.000142 0.0000164 0.0000233 0.000146 0.000181 1987 2 23 46849 0.122928 0.249573 -0.2106298 0.0012835 0.000068 0.000125 0.000185 0.000142 0.0000162 0.0000228 0.000146 0.000180 1987 2 24 46850 0.122476 0.248257 -0.2119408 0.0013554 -0.000100 0.000111 0.000184 0.000142 0.0000158 0.0000225 0.000145 0.000177 1987 2 25 46851 0.121131 0.248517 -0.2134185 0.0015737 -0.000358 -0.000135 0.000185 0.000143 0.0000156 0.0000223 0.000146 0.000177 1987 2 26 46852 0.120536 0.247216 -0.2151657 0.0018929 -0.000218 -0.000186 0.000189 0.000146 0.0000156 0.0000223 0.000147 0.000180 1987 2 27 46853 0.120588 0.244351 -0.2172322 0.0022336 0.000159 -0.000080 0.000194 0.000150 0.0000159 0.0000225 0.000149 0.000183 1987 2 28 46854 0.120914 0.244222 -0.2195998 0.0025085 0.000536 0.000026 0.000198 0.000153 0.0000162 0.0000229 0.000150 0.000188 1987 3 1 46855 0.120259 0.242943 -0.2221785 0.0026519 0.000550 0.000035 0.000201 0.000155 0.0000164 0.0000232 0.000152 0.000191 1987 3 2 46856 0.119519 0.241095 -0.2248303 0.0026392 0.000451 0.000013 0.000203 0.000157 0.0000166 0.0000235 0.000153 0.000194 1987 3 3 46857 0.118373 0.240963 -0.2274079 0.0024868 0.000352 -0.000008 0.000205 0.000159 0.0000168 0.0000238 0.000154 0.000198 1987 3 4 46858 0.117100 0.238931 -0.2297896 0.0022376 0.000254 -0.000030 0.000207 0.000160 0.0000170 0.0000241 0.000155 0.000201 1987 3 5 46859 0.117345 0.237125 -0.2318980 0.0019421 0.000155 -0.000051 0.000207 0.000160 0.0000173 0.0000243 0.000156 0.000206 1987 3 6 46860 0.115873 0.236004 -0.2337048 0.0016467 0.000108 -0.000035 0.000207 0.000160 0.0000174 0.0000245 0.000156 0.000208 1987 3 7 46861 0.113061 0.233951 -0.2352256 0.0013895 0.000078 -0.000007 0.000205 0.000159 0.0000174 0.0000246 0.000157 0.000211 1987 3 8 46862 0.111741 0.232317 -0.2365128 0.0012021 0.000049 0.000021 0.000203 0.000158 0.0000174 0.0000247 0.000157 0.000213 1987 3 9 46863 0.111021 0.230452 -0.2376475 0.0011078 0.000019 0.000049 0.000202 0.000156 0.0000175 0.0000247 0.000157 0.000215 1987 3 10 46864 0.110460 0.228666 -0.2387307 0.0011181 -0.000011 0.000077 0.000200 0.000155 0.0000175 0.0000247 0.000157 0.000217 1987 3 11 46865 0.109202 0.227518 -0.2398725 0.0012278 -0.000300 0.000183 0.000199 0.000154 0.0000174 0.0000247 0.000157 0.000219 1987 3 12 46866 0.108556 0.226293 -0.2411839 0.0014145 -0.000315 0.000179 0.000198 0.000153 0.0000175 0.0000248 0.000158 0.000221 1987 3 13 46867 0.109735 0.225138 -0.2427292 0.0016426 -0.000212 0.000132 0.000197 0.000152 0.0000176 0.0000249 0.000159 0.000223 1987 3 14 46868 0.109849 0.224096 -0.2445150 0.0018712 -0.000109 0.000084 0.000197 0.000152 0.0000177 0.0000251 0.000160 0.000226 1987 3 15 46869 0.109348 0.223130 -0.2465024 0.0020606 -0.000005 0.000037 0.000198 0.000151 0.0000178 0.0000252 0.000162 0.000228 1987 3 16 46870 0.109836 0.222885 -0.2486215 0.0021783 -0.000027 0.000029 0.000198 0.000151 0.0000179 0.0000254 0.000163 0.000231 1987 3 17 46871 0.109702 0.222697 -0.2507943 0.0022037 -0.000088 0.000034 0.000199 0.000150 0.0000180 0.0000255 0.000163 0.000234 1987 3 18 46872 0.109505 0.221807 -0.2529420 0.0021323 -0.000148 0.000039 0.000200 0.000150 0.0000181 0.0000256 0.000164 0.000237 1987 3 19 46873 0.109743 0.221676 -0.2549902 0.0019786 -0.000208 0.000044 0.000200 0.000150 0.0000182 0.0000258 0.000165 0.000241 1987 3 20 46874 0.108877 0.221598 -0.2568802 0.0017764 -0.000269 0.000049 0.000201 0.000151 0.0000183 0.0000258 0.000166 0.000244 1987 3 21 46875 0.107988 0.220499 -0.2585823 0.0015736 -0.000385 0.000165 0.000203 0.000152 0.0000183 0.0000259 0.000166 0.000247 1987 3 22 46876 0.107300 0.219958 -0.2600896 0.0014232 -0.000387 -0.000087 0.000204 0.000154 0.0000183 0.0000259 0.000167 0.000250 1987 3 23 46877 0.104843 0.219902 -0.2614712 0.0013694 -0.000339 -0.000493 0.000204 0.000154 0.0000183 0.0000257 0.000169 0.000253 1987 3 24 46878 0.102857 0.219194 -0.2628560 0.0014325 -0.000332 -0.000393 0.000204 0.000155 0.0000181 0.0000255 0.000169 0.000254 1987 3 25 46879 0.102163 0.217910 -0.2643803 0.0016004 -0.000332 -0.000201 0.000202 0.000154 0.0000178 0.0000252 0.000169 0.000254 1987 3 26 46880 0.098616 0.216764 -0.2661433 0.0018327 -0.000657 -0.000316 0.000202 0.000155 0.0000175 0.0000248 0.000169 0.000253 1987 3 27 46881 0.095761 0.216280 -0.2682067 0.0020764 -0.000545 -0.000096 0.000203 0.000157 0.0000172 0.0000246 0.000169 0.000250 1987 3 28 46882 0.097767 0.215874 -0.2702114 0.0022827 -0.000448 0.000073 0.000205 0.000160 0.0000172 0.0000246 0.000169 0.000251 1987 3 29 46883 0.097661 0.214974 -0.2722374 0.0024030 -0.000569 0.000037 0.000206 0.000161 0.0000176 0.0000248 0.000171 0.000254 1987 3 30 46884 0.095328 0.214216 -0.2747873 0.0023793 -0.000691 0.000000 0.000207 0.000163 0.0000179 0.0000252 0.000173 0.000258 1987 3 31 46885 0.095807 0.213300 -0.2773694 0.0021782 -0.000623 0.000047 0.000208 0.000164 0.0000180 0.0000254 0.000174 0.000260 1987 4 1 46886 0.094910 0.212335 -0.2795286 0.0018351 -0.000496 0.000119 0.000208 0.000166 0.0000181 0.0000256 0.000175 0.000262 1987 4 2 46887 0.093663 0.212104 -0.2811453 0.0014469 -0.000369 0.000190 0.000209 0.000167 0.0000182 0.0000257 0.000177 0.000263 1987 4 3 46888 0.095013 0.211829 -0.2822819 0.0011265 -0.000242 0.000262 0.000208 0.000168 0.0000183 0.0000258 0.000178 0.000265 1987 4 4 46889 0.094165 0.212373 -0.2831503 0.0009530 -0.000116 0.000334 0.000208 0.000168 0.0000184 0.0000259 0.000179 0.000267 1987 4 5 46890 0.092248 0.212490 -0.2840099 0.0009457 -0.000120 0.000337 0.000206 0.000168 0.0000183 0.0000258 0.000179 0.000267 1987 4 6 46891 0.091840 0.210924 -0.2850356 0.0010696 -0.000167 0.000317 0.000204 0.000167 0.0000182 0.0000257 0.000180 0.000266 1987 4 7 46892 0.090819 0.210653 -0.2862909 0.0012640 -0.000214 0.000298 0.000201 0.000166 0.0000180 0.0000255 0.000180 0.000265 1987 4 8 46893 0.089723 0.210942 -0.2877573 0.0014742 -0.000261 0.000278 0.000198 0.000163 0.0000179 0.0000253 0.000180 0.000264 1987 4 9 46894 0.088624 0.210645 -0.2893781 0.0016700 -0.000308 0.000258 0.000194 0.000161 0.0000178 0.0000251 0.000180 0.000263 1987 4 10 46895 0.087316 0.210142 -0.2911080 0.0018432 -0.000468 -0.000110 0.000191 0.000160 0.0000176 0.0000248 0.000180 0.000261 1987 4 11 46896 0.086011 0.209675 -0.2929702 0.0019897 -0.000542 -0.000287 0.000190 0.000160 0.0000173 0.0000244 0.000179 0.000259 1987 4 12 46897 0.084032 0.209451 -0.2949819 0.0020930 -0.000455 -0.000068 0.000189 0.000160 0.0000169 0.0000240 0.000178 0.000256 1987 4 13 46898 0.082242 0.208759 -0.2970915 0.0021235 -0.000369 0.000151 0.000189 0.000160 0.0000166 0.0000235 0.000177 0.000253 1987 4 14 46899 0.080345 0.208617 -0.2992010 0.0020553 -0.000283 0.000370 0.000189 0.000162 0.0000163 0.0000230 0.000176 0.000251 1987 4 15 46900 0.078924 0.207174 -0.3011894 0.0018867 -0.000439 0.000363 0.000189 0.000163 0.0000159 0.0000228 0.000175 0.000247 1987 4 16 46901 0.078066 0.205691 -0.3029595 0.0016510 -0.000373 0.000200 0.000192 0.000166 0.0000159 0.0000227 0.000175 0.000248 1987 4 17 46902 0.076206 0.206071 -0.3044773 0.0014086 -0.000130 -0.000012 0.000196 0.000170 0.0000162 0.0000230 0.000175 0.000251 1987 4 18 46903 0.075290 0.204802 -0.3057826 0.0012254 0.000114 -0.000224 0.000200 0.000174 0.0000165 0.0000233 0.000176 0.000255 1987 4 19 46904 0.074258 0.204310 -0.3069727 0.0011489 0.000212 -0.000260 0.000205 0.000178 0.0000167 0.0000236 0.000177 0.000257 1987 4 20 46905 0.072389 0.204336 -0.3081627 0.0011960 0.000159 -0.000116 0.000210 0.000183 0.0000168 0.0000238 0.000176 0.000258 1987 4 21 46906 0.072009 0.203364 -0.3094516 0.0013526 0.000107 0.000028 0.000215 0.000188 0.0000170 0.0000240 0.000176 0.000259 1987 4 22 46907 0.070846 0.203882 -0.3109104 0.0015812 0.000054 0.000173 0.000219 0.000192 0.0000171 0.0000243 0.000176 0.000259 1987 4 23 46908 0.069718 0.203874 -0.3125762 0.0018298 -0.000184 -0.000009 0.000224 0.000197 0.0000174 0.0000246 0.000178 0.000263 1987 4 24 46909 0.070109 0.203443 -0.3144675 0.0020402 -0.000487 -0.000301 0.000227 0.000200 0.0000177 0.0000251 0.000181 0.000268 1987 4 25 46910 0.069510 0.203319 -0.3165614 0.0021588 -0.000360 -0.000197 0.000230 0.000204 0.0000181 0.0000256 0.000184 0.000273 1987 4 26 46911 0.068536 0.203437 -0.3187563 0.0021518 -0.000100 0.000031 0.000234 0.000207 0.0000184 0.0000261 0.000187 0.000278 1987 4 27 46912 0.067734 0.203337 -0.3209021 0.0020187 0.000161 0.000258 0.000238 0.000210 0.0000188 0.0000266 0.000190 0.000283 1987 4 28 46913 0.066671 0.203217 -0.3228523 0.0017938 0.000421 0.000486 0.000241 0.000213 0.0000191 0.0000270 0.000193 0.000288 1987 4 29 46914 0.065756 0.204901 -0.3245115 0.0015340 0.000681 0.000714 0.000246 0.000217 0.0000195 0.0000274 0.000197 0.000293 1987 4 30 46915 0.064759 0.203720 -0.3258677 0.0012963 0.000336 0.000347 0.000249 0.000219 0.0000197 0.0000277 0.000199 0.000296 1987 5 1 46916 0.062194 0.202006 -0.3270123 0.0011182 0.000273 0.000109 0.000251 0.000220 0.0000196 0.0000278 0.000201 0.000296 1987 5 2 46917 0.058600 0.204615 -0.3280789 0.0010115 0.000378 -0.000018 0.000253 0.000221 0.0000196 0.0000278 0.000202 0.000296 1987 5 3 46918 0.057730 0.203726 -0.3291551 0.0009713 0.000376 -0.000042 0.000254 0.000221 0.0000197 0.0000279 0.000203 0.000296 1987 5 4 46919 0.057132 0.200701 -0.3301595 0.0009929 0.000105 0.000135 0.000256 0.000222 0.0000199 0.0000280 0.000204 0.000297 1987 5 5 46920 0.054671 0.202227 -0.3311423 0.0010763 -0.000070 -0.000302 0.000258 0.000222 0.0000200 0.0000283 0.000205 0.000297 1987 5 6 46921 0.054597 0.201895 -0.3322878 0.0012187 -0.000094 -0.000547 0.000260 0.000223 0.0000201 0.0000283 0.000205 0.000298 1987 5 7 46922 0.055258 0.198370 -0.3336314 0.0014089 0.000050 -0.000278 0.000261 0.000224 0.0000201 0.0000286 0.000207 0.000301 1987 5 8 46923 0.054533 0.198477 -0.3350336 0.0016244 -0.000027 -0.000042 0.000262 0.000225 0.0000203 0.0000288 0.000209 0.000307 1987 5 9 46924 0.053727 0.199770 -0.3366512 0.0018215 -0.000175 0.000185 0.000264 0.000226 0.0000207 0.0000292 0.000212 0.000314 1987 5 10 46925 0.052247 0.199654 -0.3386778 0.0019356 -0.001387 0.000858 0.000265 0.000226 0.0000209 0.0000295 0.000214 0.000320 1987 5 11 46926 0.051126 0.200135 -0.3408308 0.0019158 -0.002893 0.001655 0.000266 0.000228 0.0000211 0.0000297 0.000216 0.000326 1987 5 12 46927 0.049893 0.199491 -0.3426618 0.0017638 -0.002322 0.001305 0.000266 0.000228 0.0000211 0.0000298 0.000218 0.000329 1987 5 13 46928 0.048234 0.199204 -0.3441022 0.0015327 -0.001334 0.000725 0.000266 0.000228 0.0000210 0.0000298 0.000219 0.000332 1987 5 14 46929 0.046882 0.199838 -0.3453378 0.0012906 -0.000345 0.000145 0.000267 0.000229 0.0000210 0.0000296 0.000220 0.000335 1987 5 15 46930 0.044399 0.198947 -0.3465893 0.0010897 0.000036 -0.000361 0.000266 0.000229 0.0000208 0.0000294 0.000221 0.000336 1987 5 16 46931 0.042744 0.198857 -0.3478520 0.0009660 0.000186 -0.000840 0.000266 0.000229 0.0000206 0.0000292 0.000221 0.000336 1987 5 17 46932 0.041794 0.198719 -0.3489799 0.0009521 0.000335 -0.001319 0.000266 0.000230 0.0000204 0.0000289 0.000221 0.000336 1987 5 18 46933 0.039368 0.197133 -0.3498798 0.0010725 0.000485 -0.001798 0.000265 0.000229 0.0000202 0.0000285 0.000221 0.000336 1987 5 19 46934 0.037692 0.196837 -0.3506607 0.0013128 0.000390 -0.000283 0.000263 0.000228 0.0000198 0.0000279 0.000220 0.000333 1987 5 20 46935 0.037192 0.196953 -0.3520377 0.0015945 0.000560 -0.000550 0.000261 0.000227 0.0000193 0.0000273 0.000219 0.000328 1987 5 21 46936 0.036974 0.197046 -0.3540794 0.0018066 0.000847 -0.001638 0.000257 0.000225 0.0000187 0.0000265 0.000217 0.000321 1987 5 22 46937 0.036433 0.197510 -0.3562214 0.0018826 0.001134 -0.002726 0.000254 0.000222 0.0000182 0.0000257 0.000215 0.000316 1987 5 23 46938 0.035631 0.197906 -0.3579370 0.0018370 0.000811 -0.002170 0.000250 0.000220 0.0000176 0.0000249 0.000213 0.000308 1987 5 24 46939 0.034542 0.199828 -0.3593940 0.0017240 0.000330 -0.001185 0.000245 0.000217 0.0000170 0.0000240 0.000210 0.000300 1987 5 25 46940 0.032201 0.199948 -0.3610444 0.0015757 -0.000056 -0.000218 0.000242 0.000214 0.0000164 0.0000235 0.000206 0.000290 1987 5 26 46941 0.030582 0.198565 -0.3626894 0.0013963 -0.000134 0.000144 0.000241 0.000214 0.0000162 0.0000231 0.000205 0.000288 1987 5 27 46942 0.029526 0.200010 -0.3640717 0.0011949 -0.000054 0.000161 0.000242 0.000214 0.0000164 0.0000232 0.000205 0.000291 1987 5 28 46943 0.028406 0.199364 -0.3651754 0.0010002 0.000027 0.000179 0.000244 0.000215 0.0000165 0.0000234 0.000205 0.000293 1987 5 29 46944 0.027961 0.197259 -0.3660493 0.0008495 0.000107 0.000196 0.000245 0.000217 0.0000167 0.0000236 0.000206 0.000296 1987 5 30 46945 0.027010 0.196826 -0.3667997 0.0007698 -0.000243 0.000243 0.000246 0.000218 0.0000168 0.0000236 0.000205 0.000296 1987 5 31 46946 0.026359 0.196381 -0.3675434 0.0007669 -0.000394 0.000251 0.000247 0.000218 0.0000166 0.0000235 0.000204 0.000294 1987 6 1 46947 0.025998 0.197586 -0.3683591 0.0008269 -0.000409 0.000240 0.000249 0.000219 0.0000164 0.0000233 0.000202 0.000292 1987 6 2 46948 0.025466 0.197453 -0.3692770 0.0009280 -0.000423 0.000230 0.000250 0.000219 0.0000163 0.0000230 0.000200 0.000289 1987 6 3 46949 0.024692 0.196540 -0.3702959 0.0010526 -0.000438 0.000219 0.000250 0.000218 0.0000161 0.0000226 0.000199 0.000287 1987 6 4 46950 0.024296 0.197433 -0.3714080 0.0011909 -0.000404 0.000197 0.000249 0.000216 0.0000157 0.0000223 0.000196 0.000282 1987 6 5 46951 0.024558 0.197609 -0.3726296 0.0013345 -0.000355 0.000171 0.000248 0.000214 0.0000154 0.0000218 0.000193 0.000276 1987 6 6 46952 0.023537 0.198441 -0.3739848 0.0014630 -0.000305 0.000145 0.000246 0.000211 0.0000151 0.0000213 0.000191 0.000270 1987 6 7 46953 0.022906 0.198599 -0.3754706 0.0015393 -0.000250 0.000184 0.000243 0.000208 0.0000147 0.0000207 0.000188 0.000264 1987 6 8 46954 0.022193 0.198120 -0.3770231 0.0015204 -0.000188 0.000292 0.000241 0.000206 0.0000142 0.0000201 0.000185 0.000257 1987 6 9 46955 0.022059 0.198424 -0.3785206 0.0013841 -0.000125 0.000400 0.000238 0.000202 0.0000138 0.0000195 0.000182 0.000250 1987 6 10 46956 0.022998 0.198168 -0.3798299 0.0011520 -0.000063 0.000507 0.000234 0.000199 0.0000134 0.0000190 0.000179 0.000244 1987 6 11 46957 0.020833 0.199168 -0.3808659 0.0008945 0.000115 0.000381 0.000230 0.000195 0.0000130 0.0000184 0.000177 0.000240 1987 6 12 46958 0.018406 0.199682 -0.3816458 0.0007051 0.000331 0.000177 0.000225 0.000191 0.0000127 0.0000179 0.000175 0.000237 1987 6 13 46959 0.015845 0.198971 -0.3822901 0.0006581 0.000547 -0.000027 0.000220 0.000186 0.0000123 0.0000174 0.000173 0.000235 1987 6 14 46960 0.014403 0.198936 -0.3829742 0.0007718 0.000492 -0.000003 0.000215 0.000181 0.0000119 0.0000169 0.000171 0.000230 1987 6 15 46961 0.014622 0.198797 -0.3838510 0.0010010 0.000353 0.000091 0.000209 0.000177 0.0000116 0.0000164 0.000169 0.000225 1987 6 16 46962 0.011907 0.199018 -0.3849936 0.0012602 0.000215 0.000184 0.000204 0.000173 0.0000112 0.0000159 0.000167 0.000220 1987 6 17 46963 0.011885 0.199618 -0.3863764 0.0014628 0.000076 0.000278 0.000198 0.000170 0.0000109 0.0000155 0.000165 0.000216 1987 6 18 46964 0.011435 0.200561 -0.3878980 0.0015537 -0.000062 0.000372 0.000193 0.000166 0.0000106 0.0000150 0.000163 0.000213 1987 6 19 46965 0.008667 0.201227 -0.3894304 0.0015199 -0.000012 0.000392 0.000187 0.000163 0.0000103 0.0000147 0.000160 0.000207 1987 6 20 46966 0.009057 0.201101 -0.3908775 0.0013800 0.000044 0.000347 0.000182 0.000159 0.0000101 0.0000143 0.000159 0.000205 1987 6 21 46967 0.007695 0.201595 -0.3921615 0.0011680 0.000071 0.000274 0.000177 0.000156 0.0000100 0.0000141 0.000158 0.000205 1987 6 22 46968 0.006302 0.202081 -0.3932201 0.0009207 0.000097 0.000202 0.000172 0.000152 0.0000098 0.0000139 0.000158 0.000205 1987 6 23 46969 0.005327 0.202519 -0.3940224 0.0006734 0.000123 0.000130 0.000167 0.000149 0.0000097 0.0000137 0.000158 0.000205 1987 6 24 46970 0.003955 0.203866 -0.3945760 0.0004573 -0.000088 0.000287 0.000162 0.000145 0.0000095 0.0000134 0.000157 0.000204 1987 6 25 46971 0.003618 0.203967 -0.3949495 0.0002977 0.000175 0.000166 0.000157 0.000141 0.0000093 0.0000133 0.000156 0.000202 1987 6 26 46972 0.001792 0.203302 -0.3952095 0.0002116 0.000441 0.000072 0.000156 0.000141 0.0000093 0.0000134 0.000156 0.000203 1987 6 27 46973 0.000379 0.204684 -0.3954141 0.0002067 0.000403 0.000204 0.000161 0.000145 0.0000097 0.0000138 0.000158 0.000209 1987 6 28 46974 -0.002073 0.205995 -0.3956317 0.0002798 0.000364 0.000337 0.000165 0.000150 0.0000102 0.0000144 0.000160 0.000214 1987 6 29 46975 -0.003377 0.205987 -0.3959437 0.0004149 0.000236 0.000552 0.000169 0.000153 0.0000106 0.0000149 0.000162 0.000219 1987 6 30 46976 -0.004332 0.205747 -0.3965144 0.0005859 0.000348 0.000646 0.000172 0.000157 0.0000109 0.0000154 0.000162 0.000222 1987 7 1 46977 -0.007824 0.205867 -0.3971599 0.0007656 0.000794 0.000454 0.000176 0.000161 0.0000112 0.0000158 0.000163 0.000224 1987 7 2 46978 -0.007385 0.206909 -0.3979562 0.0009292 0.000732 0.000006 0.000179 0.000164 0.0000115 0.0000163 0.000164 0.000225 1987 7 3 46979 -0.006580 0.207326 -0.3989859 0.0010498 0.000334 -0.000525 0.000182 0.000167 0.0000118 0.0000166 0.000164 0.000225 1987 7 4 46980 -0.007464 0.208107 -0.4000993 0.0011005 0.000289 -0.000462 0.000184 0.000170 0.0000120 0.0000170 0.000164 0.000224 1987 7 5 46981 -0.008421 0.209699 -0.4011865 0.0010625 0.000357 -0.000211 0.000186 0.000173 0.0000123 0.0000174 0.000164 0.000222 1987 7 6 46982 -0.010120 0.209889 -0.4021694 0.0009303 0.000425 0.000041 0.000188 0.000175 0.0000125 0.0000178 0.000164 0.000220 1987 7 7 46983 -0.010746 0.209144 -0.4029824 0.0007209 0.000493 0.000293 0.000190 0.000178 0.0000128 0.0000182 0.000164 0.000219 1987 7 8 46984 -0.012091 0.209388 -0.4035886 0.0004810 0.000561 0.000545 0.000191 0.000179 0.0000131 0.0000185 0.000163 0.000217 1987 7 9 46985 -0.013060 0.211252 -0.4039955 0.0002827 -0.000136 0.000214 0.000192 0.000181 0.0000134 0.0000190 0.000163 0.000215 1987 7 10 46986 -0.015238 0.211882 -0.4042327 0.0002019 -0.000208 0.000239 0.000194 0.000182 0.0000137 0.0000195 0.000163 0.000214 1987 7 11 46987 -0.015990 0.212150 -0.4044327 0.0002825 0.000239 0.000586 0.000195 0.000184 0.0000142 0.0000201 0.000164 0.000215 1987 7 12 46988 -0.015408 0.213076 -0.4047957 0.0005076 0.000686 0.000934 0.000197 0.000184 0.0000147 0.0000207 0.000164 0.000216 1987 7 13 46989 -0.019644 0.212707 -0.4054649 0.0008006 0.000530 0.000768 0.000198 0.000185 0.0000151 0.0000213 0.000165 0.000215 1987 7 14 46990 -0.020682 0.213386 -0.4064329 0.0010605 0.000282 0.000674 0.000198 0.000184 0.0000154 0.0000218 0.000165 0.000213 1987 7 15 46991 -0.021194 0.214738 -0.4075921 0.0012079 0.000043 0.000635 0.000197 0.000183 0.0000158 0.0000223 0.000164 0.000211 1987 7 16 46992 -0.023963 0.215993 -0.4087953 0.0012128 -0.000195 0.000596 0.000197 0.000182 0.0000161 0.0000228 0.000164 0.000209 1987 7 17 46993 -0.023774 0.216283 -0.4099080 0.0010928 -0.000155 0.000473 0.000196 0.000180 0.0000164 0.0000232 0.000163 0.000206 1987 7 18 46994 -0.025240 0.216365 -0.4108775 0.0008887 0.000083 0.000290 0.000195 0.000178 0.0000167 0.0000236 0.000163 0.000204 1987 7 19 46995 -0.025000 0.218480 -0.4116988 0.0006415 0.000111 0.000072 0.000193 0.000175 0.0000170 0.0000240 0.000162 0.000200 1987 7 20 46996 -0.025613 0.217643 -0.4122500 0.0003863 0.000112 0.000018 0.000194 0.000173 0.0000172 0.0000243 0.000162 0.000196 1987 7 21 46997 -0.027897 0.216881 -0.4124871 0.0001541 0.000079 0.000203 0.000196 0.000173 0.0000174 0.0000246 0.000162 0.000194 1987 7 22 46998 -0.025915 0.219302 -0.4125365 -0.0000281 0.000046 0.000387 0.000198 0.000173 0.0000176 0.0000248 0.000162 0.000191 1987 7 23 46999 -0.027147 0.220029 -0.4125258 -0.0001369 0.000198 0.000397 0.000199 0.000172 0.0000177 0.0000251 0.000162 0.000188 1987 7 24 47000 -0.027351 0.221443 -0.4124071 -0.0001492 0.000400 0.000361 0.000200 0.000171 0.0000179 0.0000254 0.000162 0.000185 1987 7 25 47001 -0.025024 0.222974 -0.4121475 -0.0000502 0.000374 0.000594 0.000203 0.000171 0.0000182 0.0000259 0.000163 0.000189 1987 7 26 47002 -0.029077 0.221978 -0.4120556 0.0001456 0.000327 0.000851 0.000205 0.000171 0.0000187 0.0000264 0.000166 0.000195 1987 7 27 47003 -0.029426 0.222782 -0.4124771 0.0003885 0.000353 0.000949 0.000207 0.000170 0.0000191 0.0000270 0.000168 0.000201 1987 7 28 47004 -0.025471 0.225522 -0.4132257 0.0006230 0.000527 0.000730 0.000209 0.000169 0.0000195 0.0000276 0.000170 0.000206 1987 7 29 47005 -0.027718 0.225041 -0.4136145 0.0008143 0.002225 0.000294 0.000210 0.000168 0.0000199 0.0000281 0.000172 0.000210 1987 7 30 47006 -0.028274 0.224917 -0.4143500 0.0009287 0.002295 0.000123 0.000210 0.000166 0.0000203 0.0000287 0.000173 0.000213 1987 7 31 47007 -0.026762 0.227314 -0.4156136 0.0009232 0.001633 0.000066 0.000210 0.000165 0.0000206 0.0000292 0.000174 0.000215 1987 8 1 47008 -0.029471 0.226819 -0.4168002 0.0007915 0.000970 0.000010 0.000209 0.000163 0.0000210 0.0000297 0.000175 0.000218 1987 8 2 47009 -0.029140 0.227443 -0.4173237 0.0005921 0.000308 -0.000046 0.000208 0.000160 0.0000214 0.0000302 0.000176 0.000220 1987 8 3 47010 -0.027775 0.230016 -0.4172465 0.0004057 -0.000419 -0.000180 0.000208 0.000161 0.0000217 0.0000306 0.000179 0.000227 1987 8 4 47011 -0.029409 0.231031 -0.4182144 0.0002763 -0.001131 -0.000350 0.000208 0.000164 0.0000220 0.0000309 0.000182 0.000233 1987 8 5 47012 -0.029860 0.232073 -0.4176682 0.0002308 -0.001789 -0.000580 0.000209 0.000166 0.0000220 0.0000311 0.000184 0.000239 1987 8 6 47013 -0.030961 0.232827 -0.4182615 0.0002738 -0.001299 -0.000473 0.000209 0.000168 0.0000219 0.0000309 0.000186 0.000243 1987 8 7 47014 -0.032035 0.233262 -0.4189350 0.0003844 0.000272 -0.000352 0.000207 0.000169 0.0000217 0.0000308 0.000187 0.000246 1987 8 8 47015 -0.031417 0.233813 -0.4193993 0.0005596 0.000196 -0.000065 0.000208 0.000171 0.0000217 0.0000307 0.000188 0.000247 1987 8 9 47016 -0.031139 0.237433 -0.4200116 0.0007939 -0.000404 0.000277 0.000212 0.000175 0.0000217 0.0000306 0.000188 0.000249 1987 8 10 47017 -0.031366 0.238744 -0.4207945 0.0010484 0.000129 0.000031 0.000215 0.000179 0.0000216 0.0000306 0.000188 0.000248 1987 8 11 47018 -0.032372 0.236471 -0.4218911 0.0012538 0.000624 -0.000128 0.000218 0.000183 0.0000215 0.0000304 0.000188 0.000249 1987 8 12 47019 -0.033753 0.238510 -0.4232448 0.0013428 0.001064 -0.000059 0.000224 0.000188 0.0000214 0.0000302 0.000190 0.000253 1987 8 13 47020 -0.032918 0.238605 -0.4245710 0.0012874 0.000691 0.000452 0.000229 0.000193 0.0000213 0.0000301 0.000192 0.000256 1987 8 14 47021 -0.032293 0.239279 -0.4257953 0.0011094 -0.000016 0.001159 0.000234 0.000198 0.0000212 0.0000300 0.000193 0.000259 1987 8 15 47022 -0.035651 0.241414 -0.4269026 0.0008630 0.000672 0.000597 0.000240 0.000203 0.0000212 0.0000297 0.000194 0.000261 1987 8 16 47023 -0.036975 0.240550 -0.4274716 0.0006120 0.001067 0.000239 0.000243 0.000207 0.0000209 0.0000295 0.000195 0.000261 1987 8 17 47024 -0.037694 0.243616 -0.4279375 0.0004023 0.001363 -0.000039 0.000245 0.000210 0.0000204 0.0000290 0.000195 0.000261 1987 8 18 47025 -0.039432 0.244302 -0.4284564 0.0002558 0.001008 0.000118 0.000247 0.000212 0.0000201 0.0000285 0.000196 0.000259 1987 8 19 47026 -0.036331 0.243306 -0.4288040 0.0001962 0.000566 0.000329 0.000247 0.000214 0.0000199 0.0000281 0.000196 0.000257 1987 8 20 47027 -0.036515 0.245098 -0.4288241 0.0002552 0.000124 0.000540 0.000248 0.000215 0.0000196 0.0000277 0.000196 0.000255 1987 8 21 47028 -0.038441 0.245964 -0.4286455 0.0004370 -0.000319 0.000728 0.000247 0.000215 0.0000193 0.0000272 0.000197 0.000253 1987 8 22 47029 -0.037516 0.248137 -0.4296966 0.0006847 0.000434 0.000332 0.000245 0.000214 0.0000188 0.0000266 0.000196 0.000249 1987 8 23 47030 -0.039527 0.248942 -0.4307409 0.0009309 0.000522 -0.000023 0.000243 0.000214 0.0000184 0.0000263 0.000196 0.000245 1987 8 24 47031 -0.038849 0.251298 -0.4315552 0.0011523 0.000293 -0.000147 0.000244 0.000215 0.0000184 0.0000261 0.000197 0.000246 1987 8 25 47032 -0.036639 0.253069 -0.4326893 0.0013401 0.000000 -0.000157 0.000245 0.000217 0.0000186 0.0000262 0.000200 0.000251 1987 8 26 47033 -0.036483 0.253119 -0.4342127 0.0014717 0.000019 -0.000126 0.000246 0.000218 0.0000187 0.0000265 0.000202 0.000256 1987 8 27 47034 -0.036665 0.257238 -0.4357918 0.0015269 0.000611 0.000145 0.000246 0.000219 0.0000189 0.0000267 0.000205 0.000260 1987 8 28 47035 -0.037966 0.256887 -0.4372572 0.0015035 0.000564 -0.000077 0.000246 0.000219 0.0000191 0.0000269 0.000206 0.000264 1987 8 29 47036 -0.038154 0.256692 -0.4386518 0.0014112 0.000447 -0.000088 0.000246 0.000219 0.0000191 0.0000270 0.000208 0.000266 1987 8 30 47037 -0.038573 0.259685 -0.4399736 0.0012612 0.000381 0.000050 0.000247 0.000219 0.0000191 0.0000271 0.000209 0.000268 1987 8 31 47038 -0.038287 0.258799 -0.4411666 0.0010696 0.000315 0.000188 0.000246 0.000218 0.0000191 0.0000271 0.000210 0.000270 1987 9 1 47039 -0.038192 0.260260 -0.4421788 0.0008682 0.000249 0.000327 0.000246 0.000217 0.0000191 0.0000270 0.000211 0.000272 1987 9 2 47040 -0.039515 0.262404 -0.4429934 0.0007085 0.000335 0.000330 0.000246 0.000215 0.0000190 0.0000269 0.000211 0.000273 1987 9 3 47041 -0.039347 0.263259 -0.4436699 0.0006521 0.000465 0.000292 0.000245 0.000212 0.0000188 0.0000266 0.000211 0.000273 1987 9 4 47042 -0.040359 0.264542 -0.4443400 0.0007441 0.000596 0.000254 0.000244 0.000210 0.0000186 0.0000264 0.000212 0.000272 1987 9 5 47043 -0.041021 0.264749 -0.4451679 0.0009860 0.000727 0.000216 0.000244 0.000209 0.0000184 0.0000261 0.000212 0.000272 1987 9 6 47044 -0.040827 0.265868 -0.4462931 0.0013238 0.000858 0.000178 0.000243 0.000207 0.0000183 0.0000257 0.000212 0.000273 1987 9 7 47045 -0.041061 0.266157 -0.4477751 0.0016616 0.000786 0.000264 0.000242 0.000206 0.0000180 0.0000254 0.000212 0.000271 1987 9 8 47046 -0.040743 0.266168 -0.4495651 0.0018988 0.000650 0.000388 0.000243 0.000206 0.0000176 0.0000249 0.000211 0.000269 1987 9 9 47047 -0.041250 0.266642 -0.4515239 0.0019697 0.000514 0.000512 0.000243 0.000205 0.0000173 0.0000244 0.000210 0.000267 1987 9 10 47048 -0.041591 0.267363 -0.4534715 0.0018658 0.000378 0.000636 0.000243 0.000204 0.0000170 0.0000240 0.000209 0.000265 1987 9 11 47049 -0.042683 0.269664 -0.4552449 0.0016313 0.000243 0.000760 0.000242 0.000203 0.0000166 0.0000235 0.000209 0.000263 1987 9 12 47050 -0.043458 0.269667 -0.4567415 0.0013376 0.000308 -0.000075 0.000242 0.000202 0.0000162 0.0000232 0.000207 0.000258 1987 9 13 47051 -0.043918 0.269677 -0.4579349 0.0010549 0.000393 -0.000389 0.000242 0.000201 0.0000161 0.0000230 0.000207 0.000260 1987 9 14 47052 -0.044491 0.272165 -0.4588661 0.0008343 0.000455 -0.000235 0.000245 0.000202 0.0000162 0.0000230 0.000208 0.000265 1987 9 15 47053 -0.043732 0.273489 -0.4596190 0.0007040 0.000516 -0.000081 0.000247 0.000203 0.0000163 0.0000231 0.000209 0.000270 1987 9 16 47054 -0.045958 0.276552 -0.4602952 0.0006749 0.000577 0.000073 0.000248 0.000203 0.0000164 0.0000232 0.000210 0.000275 1987 9 17 47055 -0.046901 0.279796 -0.4609968 0.0007458 0.001880 -0.000140 0.000250 0.000202 0.0000165 0.0000232 0.000210 0.000279 1987 9 18 47056 -0.044940 0.278835 -0.4618102 0.0009051 0.002078 -0.000145 0.000249 0.000200 0.0000164 0.0000232 0.000210 0.000280 1987 9 19 47057 -0.046200 0.278061 -0.4628135 0.0011310 0.001609 -0.000005 0.000249 0.000199 0.0000163 0.0000231 0.000210 0.000281 1987 9 20 47058 -0.047470 0.278954 -0.4640666 0.0013910 0.001141 0.000136 0.000248 0.000196 0.0000163 0.0000231 0.000209 0.000282 1987 9 21 47059 -0.047505 0.280204 -0.4655919 0.0016457 0.000672 0.000276 0.000246 0.000194 0.0000163 0.0000231 0.000208 0.000284 1987 9 22 47060 -0.048309 0.281320 -0.4673652 0.0018548 0.000567 0.000230 0.000245 0.000192 0.0000164 0.0000232 0.000207 0.000285 1987 9 23 47061 -0.049542 0.281792 -0.4693102 0.0019842 0.000572 0.000129 0.000244 0.000190 0.0000165 0.0000233 0.000206 0.000285 1987 9 24 47062 -0.049559 0.283936 -0.4713190 0.0020127 0.000577 0.000027 0.000242 0.000188 0.0000166 0.0000235 0.000205 0.000285 1987 9 25 47063 -0.050315 0.285839 -0.4732806 0.0019361 0.000405 0.000033 0.000241 0.000187 0.0000168 0.0000238 0.000207 0.000289 1987 9 26 47064 -0.052862 0.286480 -0.4751210 0.0017687 0.000145 0.000092 0.000241 0.000188 0.0000171 0.0000241 0.000209 0.000295 1987 9 27 47065 -0.052027 0.289525 -0.4767964 0.0015433 -0.000117 -0.000195 0.000241 0.000187 0.0000173 0.0000243 0.000211 0.000299 1987 9 28 47066 -0.051579 0.292244 -0.4782443 0.0013097 -0.000077 -0.000408 0.000240 0.000187 0.0000172 0.0000243 0.000211 0.000300 1987 9 29 47067 -0.053371 0.293136 -0.4794625 0.0011274 0.000091 -0.000546 0.000239 0.000188 0.0000171 0.0000242 0.000211 0.000301 1987 9 30 47068 -0.053340 0.295333 -0.4805330 0.0010528 0.000258 -0.000684 0.000237 0.000188 0.0000170 0.0000240 0.000211 0.000302 1987 10 1 47069 -0.054747 0.296377 -0.4815924 0.0011203 0.000426 -0.000822 0.000235 0.000187 0.0000168 0.0000239 0.000211 0.000303 1987 10 2 47070 -0.056152 0.296137 -0.4827971 0.0013283 0.000465 -0.000685 0.000232 0.000186 0.0000169 0.0000239 0.000211 0.000303 1987 10 3 47071 -0.054674 0.298165 -0.4842733 0.0016332 0.000465 -0.000466 0.000228 0.000184 0.0000170 0.0000240 0.000211 0.000304 1987 10 4 47072 -0.054437 0.299830 -0.4860782 0.0019585 0.000465 -0.000246 0.000224 0.000181 0.0000171 0.0000241 0.000211 0.000305 1987 10 5 47073 -0.055990 0.300494 -0.4881817 0.0022175 0.000466 -0.000026 0.000219 0.000178 0.0000172 0.0000243 0.000211 0.000305 1987 10 6 47074 -0.055760 0.302239 -0.4904750 0.0023428 0.000466 0.000194 0.000214 0.000175 0.0000172 0.0000244 0.000211 0.000306 1987 10 7 47075 -0.056210 0.303444 -0.4928051 0.0023093 0.000382 0.000118 0.000211 0.000172 0.0000173 0.0000245 0.000210 0.000304 1987 10 8 47076 -0.058279 0.304313 -0.4950259 0.0021387 0.000272 -0.000047 0.000209 0.000171 0.0000174 0.0000246 0.000208 0.000301 1987 10 9 47077 -0.057555 0.305820 -0.4970346 0.0018853 0.000162 -0.000213 0.000208 0.000170 0.0000175 0.0000247 0.000207 0.000298 1987 10 10 47078 -0.057574 0.306855 -0.4987870 0.0016109 0.000052 -0.000378 0.000207 0.000170 0.0000176 0.0000248 0.000206 0.000296 1987 10 11 47079 -0.059031 0.306705 -0.5002920 0.0013663 -0.000058 -0.000543 0.000208 0.000171 0.0000176 0.0000248 0.000204 0.000294 1987 10 12 47080 -0.058140 0.308704 -0.5015936 0.0011841 -0.000035 -0.000505 0.000207 0.000171 0.0000175 0.0000248 0.000203 0.000289 1987 10 13 47081 -0.058898 0.312042 -0.5027451 0.0010845 0.000035 -0.000395 0.000205 0.000170 0.0000175 0.0000247 0.000200 0.000284 1987 10 14 47082 -0.060793 0.312272 -0.5038119 0.0010795 0.000105 -0.000286 0.000203 0.000169 0.0000173 0.0000245 0.000198 0.000280 1987 10 15 47083 -0.060590 0.313984 -0.5048807 0.0011705 0.000175 -0.000177 0.000201 0.000167 0.0000172 0.0000244 0.000197 0.000275 1987 10 16 47084 -0.061780 0.314913 -0.5060493 0.0013400 0.000245 -0.000067 0.000198 0.000166 0.0000171 0.0000242 0.000195 0.000272 1987 10 17 47085 -0.064105 0.313698 -0.5074207 0.0015470 0.000294 -0.000293 0.000196 0.000164 0.0000170 0.0000240 0.000193 0.000268 1987 10 18 47086 -0.062734 0.317028 -0.5092454 0.0017382 0.000240 -0.000195 0.000194 0.000163 0.0000168 0.0000238 0.000192 0.000265 1987 10 19 47087 -0.060636 0.318343 -0.5112976 0.0018772 0.000055 0.000492 0.000192 0.000162 0.0000166 0.0000235 0.000192 0.000263 1987 10 20 47088 -0.062097 0.318246 -0.5129495 0.0019620 0.000247 0.000175 0.000189 0.000161 0.0000163 0.0000231 0.000190 0.000260 1987 10 21 47089 -0.063256 0.320699 -0.5148663 0.0019967 0.000362 -0.000169 0.000186 0.000159 0.0000160 0.0000225 0.000188 0.000255 1987 10 22 47090 -0.063218 0.320349 -0.5169135 0.0019699 0.000250 -0.000296 0.000185 0.000157 0.0000155 0.0000218 0.000186 0.000250 1987 10 23 47091 -0.063365 0.320949 -0.5188969 0.0018744 0.000168 -0.000200 0.000184 0.000157 0.0000149 0.0000213 0.000184 0.000244 1987 10 24 47092 -0.062314 0.323522 -0.5206232 0.0017249 0.000142 -0.000311 0.000183 0.000156 0.0000147 0.0000209 0.000182 0.000243 1987 10 25 47093 -0.062390 0.324942 -0.5221396 0.0015530 0.000141 -0.000594 0.000183 0.000157 0.0000146 0.0000206 0.000182 0.000245 1987 10 26 47094 -0.063281 0.325156 -0.5237418 0.0013923 0.000139 -0.000436 0.000184 0.000158 0.0000145 0.0000204 0.000182 0.000246 1987 10 27 47095 -0.062272 0.325131 -0.5252202 0.0012798 0.000235 0.000019 0.000184 0.000158 0.0000142 0.0000200 0.000182 0.000244 1987 10 28 47096 -0.062605 0.326523 -0.5264921 0.0012589 0.000361 0.000540 0.000183 0.000158 0.0000139 0.0000196 0.000181 0.000242 1987 10 29 47097 -0.062904 0.328283 -0.5277100 0.0013595 0.000381 0.000925 0.000183 0.000158 0.0000136 0.0000191 0.000179 0.000238 1987 10 30 47098 -0.060910 0.330773 -0.5290782 0.0015735 0.000363 0.000626 0.000181 0.000157 0.0000132 0.0000187 0.000177 0.000233 1987 10 31 47099 -0.061895 0.331339 -0.5307588 0.0018477 0.000338 0.000099 0.000179 0.000156 0.0000128 0.0000181 0.000174 0.000227 1987 11 1 47100 -0.062845 0.331387 -0.5327955 0.0021025 0.000627 -0.000124 0.000176 0.000154 0.0000124 0.0000177 0.000172 0.000220 1987 11 2 47101 -0.061435 0.334437 -0.5350250 0.0022643 0.000562 -0.000163 0.000173 0.000152 0.0000121 0.0000172 0.000171 0.000218 1987 11 3 47102 -0.062050 0.336529 -0.5372915 0.0022921 0.000316 -0.000166 0.000170 0.000150 0.0000119 0.0000169 0.000171 0.000219 1987 11 4 47103 -0.061657 0.339419 -0.5395076 0.0021845 0.000105 -0.000169 0.000167 0.000147 0.0000118 0.0000166 0.000170 0.000219 1987 11 5 47104 -0.061265 0.340503 -0.5416031 0.0019738 0.000158 -0.000208 0.000164 0.000144 0.0000115 0.0000163 0.000169 0.000218 1987 11 6 47105 -0.062154 0.338119 -0.5434871 0.0017136 0.000346 -0.000480 0.000160 0.000141 0.0000112 0.0000161 0.000169 0.000217 1987 11 7 47106 -0.060896 0.339584 -0.5450946 0.0014653 0.000394 -0.000596 0.000159 0.000141 0.0000112 0.0000160 0.000168 0.000217 1987 11 8 47107 -0.059557 0.341668 -0.5464474 0.0012818 0.000300 -0.000520 0.000162 0.000142 0.0000114 0.0000161 0.000168 0.000218 1987 11 9 47108 -0.058677 0.343058 -0.5476453 0.0011944 0.000207 -0.000444 0.000164 0.000143 0.0000115 0.0000163 0.000169 0.000220 1987 11 10 47109 -0.058313 0.345890 -0.5488153 0.0012081 0.000114 -0.000368 0.000166 0.000144 0.0000117 0.0000165 0.000169 0.000221 1987 11 11 47110 -0.057890 0.347399 -0.5500717 0.0013060 0.000421 -0.000301 0.000168 0.000144 0.0000119 0.0000168 0.000169 0.000221 1987 11 12 47111 -0.056809 0.349088 -0.5514699 0.0014588 0.000535 -0.000284 0.000170 0.000145 0.0000120 0.0000171 0.000169 0.000224 1987 11 13 47112 -0.057041 0.351328 -0.5530332 0.0016348 0.000451 -0.000294 0.000173 0.000147 0.0000123 0.0000174 0.000171 0.000228 1987 11 14 47113 -0.056956 0.353602 -0.5547679 0.0018062 0.000367 -0.000305 0.000176 0.000148 0.0000126 0.0000178 0.000173 0.000233 1987 11 15 47114 -0.056874 0.355536 -0.5566573 0.0019522 0.000283 -0.000315 0.000178 0.000150 0.0000129 0.0000181 0.000175 0.000239 1987 11 16 47115 -0.056782 0.356434 -0.5586665 0.0020582 0.000304 -0.000421 0.000180 0.000151 0.0000131 0.0000185 0.000177 0.000244 1987 11 17 47116 -0.055540 0.357927 -0.5607465 0.0021119 0.000362 -0.000560 0.000182 0.000151 0.0000133 0.0000189 0.000179 0.000248 1987 11 18 47117 -0.055078 0.359088 -0.5628392 0.0021006 0.000420 -0.000698 0.000184 0.000152 0.0000136 0.0000193 0.000181 0.000254 1987 11 19 47118 -0.054551 0.360292 -0.5648803 0.0020136 0.000478 -0.000837 0.000186 0.000153 0.0000139 0.0000196 0.000183 0.000259 1987 11 20 47119 -0.053974 0.362095 -0.5668045 0.0018516 0.000536 -0.000975 0.000187 0.000154 0.0000142 0.0000200 0.000186 0.000265 1987 11 21 47120 -0.053936 0.363323 -0.5685574 0.0016380 0.000542 -0.000916 0.000189 0.000155 0.0000143 0.0000202 0.000187 0.000268 1987 11 22 47121 -0.053877 0.365201 -0.5701124 0.0014218 0.000531 -0.000790 0.000190 0.000156 0.0000145 0.0000205 0.000189 0.000271 1987 11 23 47122 -0.054039 0.366832 -0.5714880 0.0012661 0.000520 -0.000664 0.000191 0.000156 0.0000146 0.0000206 0.000190 0.000273 1987 11 24 47123 -0.053459 0.368624 -0.5727547 0.0012265 0.000509 -0.000538 0.000192 0.000157 0.0000147 0.0000208 0.000192 0.000276 1987 11 25 47124 -0.053733 0.371057 -0.5740232 0.0013275 -0.000045 -0.000249 0.000193 0.000157 0.0000149 0.0000212 0.000193 0.000281 1987 11 26 47125 -0.055827 0.372178 -0.5753939 0.0015494 -0.000650 0.000024 0.000194 0.000158 0.0000152 0.0000216 0.000195 0.000287 1987 11 27 47126 -0.057451 0.373981 -0.5769962 0.0018303 -0.000541 0.000048 0.000195 0.000158 0.0000157 0.0000222 0.000196 0.000291 1987 11 28 47127 -0.058717 0.375962 -0.5789243 0.0020823 -0.000432 0.000071 0.000197 0.000159 0.0000161 0.0000228 0.000198 0.000295 1987 11 29 47128 -0.059773 0.376945 -0.5811559 0.0022244 -0.000322 0.000095 0.000197 0.000159 0.0000166 0.0000235 0.000199 0.000299 1987 11 30 47129 -0.060483 0.378047 -0.5835490 0.0022174 -0.000213 0.000118 0.000198 0.000158 0.0000171 0.0000242 0.000200 0.000304 1987 12 1 47130 -0.061735 0.378359 -0.5858765 0.0020859 -0.000249 -0.000066 0.000198 0.000158 0.0000176 0.0000248 0.000201 0.000307 1987 12 2 47131 -0.061693 0.379759 -0.5877217 0.0019064 -0.000163 -0.000109 0.000198 0.000156 0.0000179 0.0000252 0.000202 0.000309 1987 12 3 47132 -0.060242 0.381742 -0.5891519 0.0017522 -0.000008 -0.000066 0.000199 0.000155 0.0000181 0.0000256 0.000202 0.000310 1987 12 4 47133 -0.060097 0.382369 -0.5906136 0.0016333 0.000148 -0.000023 0.000199 0.000155 0.0000184 0.0000260 0.000203 0.000311 1987 12 5 47134 -0.060120 0.383411 -0.5924479 0.0014966 0.000304 0.000019 0.000198 0.000154 0.0000186 0.0000263 0.000203 0.000311 1987 12 6 47135 -0.058589 0.384298 -0.5946043 0.0013019 0.000064 0.000428 0.000198 0.000153 0.0000188 0.0000264 0.000203 0.000310 1987 12 7 47136 -0.057194 0.385641 -0.5958767 0.0011014 0.000162 0.000458 0.000198 0.000152 0.0000188 0.0000265 0.000202 0.000306 1987 12 8 47137 -0.056495 0.387589 -0.5963089 0.0010122 0.000460 0.000272 0.000196 0.000150 0.0000187 0.0000264 0.000200 0.000301 1987 12 9 47138 -0.055044 0.387542 -0.5970948 0.0010976 0.000642 0.000062 0.000196 0.000149 0.0000186 0.0000265 0.000199 0.000296 1987 12 10 47139 -0.054532 0.387932 -0.5981774 0.0013111 0.000520 -0.000261 0.000197 0.000150 0.0000188 0.0000266 0.000198 0.000291 1987 12 11 47140 -0.054522 0.390508 -0.5998499 0.0015382 0.000425 -0.000316 0.000198 0.000150 0.0000190 0.0000268 0.000197 0.000287 1987 12 12 47141 -0.052535 0.391963 -0.6019374 0.0016811 0.000340 -0.000280 0.000199 0.000150 0.0000192 0.0000271 0.000197 0.000283 1987 12 13 47142 -0.051666 0.393032 -0.6036978 0.0017253 0.000254 -0.000244 0.000202 0.000152 0.0000193 0.0000272 0.000196 0.000281 1987 12 14 47143 -0.050240 0.395257 -0.6051156 0.0017239 0.000169 -0.000208 0.000203 0.000153 0.0000193 0.0000273 0.000195 0.000277 1987 12 15 47144 -0.047868 0.396311 -0.6065639 0.0017201 0.000083 -0.000172 0.000205 0.000154 0.0000194 0.0000274 0.000194 0.000274 1987 12 16 47145 -0.047698 0.397854 -0.6083489 0.0017027 0.000154 -0.000441 0.000206 0.000155 0.0000194 0.0000275 0.000193 0.000272 1987 12 17 47146 -0.045627 0.400277 -0.6101703 0.0016333 0.000141 -0.000614 0.000207 0.000156 0.0000196 0.0000278 0.000193 0.000271 1987 12 18 47147 -0.044393 0.400546 -0.6117670 0.0014994 0.000048 -0.000667 0.000208 0.000157 0.0000199 0.0000282 0.000194 0.000273 1987 12 19 47148 -0.044466 0.400815 -0.6131658 0.0013357 -0.000045 -0.000720 0.000209 0.000158 0.0000203 0.0000287 0.000195 0.000274 1987 12 20 47149 -0.042803 0.402355 -0.6144351 0.0012093 0.000861 0.000213 0.000209 0.000159 0.0000207 0.0000292 0.000196 0.000276 1987 12 21 47150 -0.043167 0.403476 -0.6156128 0.0011896 0.000543 0.000239 0.000209 0.000160 0.0000210 0.0000297 0.000197 0.000276 1987 12 22 47151 -0.041253 0.403932 -0.6168462 0.0013125 0.000156 -0.000034 0.000209 0.000161 0.0000212 0.0000300 0.000197 0.000276 1987 12 23 47152 -0.038182 0.404092 -0.6182833 0.0015595 -0.000084 -0.000286 0.000208 0.000161 0.0000214 0.0000301 0.000197 0.000274 1987 12 24 47153 -0.038386 0.404727 -0.6199960 0.0018631 -0.000164 -0.000346 0.000208 0.000162 0.0000214 0.0000302 0.000196 0.000271 1987 12 25 47154 -0.037027 0.405533 -0.6219910 0.0021345 -0.000094 -0.000228 0.000209 0.000164 0.0000213 0.0000302 0.000195 0.000266 1987 12 26 47155 -0.034820 0.405680 -0.6242080 0.0022981 -0.000025 -0.000111 0.000210 0.000165 0.0000213 0.0000302 0.000194 0.000261 1987 12 27 47156 -0.033540 0.406762 -0.6265288 0.0023152 0.000044 0.000007 0.000210 0.000166 0.0000213 0.0000301 0.000193 0.000257 1987 12 28 47157 -0.032218 0.410125 -0.6288066 0.0021903 0.000113 0.000125 0.000211 0.000166 0.0000212 0.0000300 0.000192 0.000253 1987 12 29 47158 -0.030732 0.411316 -0.6309028 0.0019611 0.000182 0.000243 0.000210 0.000165 0.0000212 0.0000299 0.000191 0.000248 1987 12 30 47159 -0.029431 0.409327 -0.6327241 0.0016814 0.000252 0.000361 0.000210 0.000165 0.0000211 0.0000298 0.000190 0.000245 1987 12 31 47160 -0.027425 0.410316 -0.6342471 0.0014047 0.000192 0.000311 0.000209 0.000164 0.0000210 0.0000297 0.000189 0.000241 1988 1 1 47161 -0.024227 0.413366 0.3644819 0.0012246 0.000091 0.000210 0.000178 0.000127 0.0000240 0.0000340 0.000199 0.000165 1988 1 2 47162 -0.022208 0.414698 0.3633396 0.0011255 -0.000009 0.000109 0.000176 0.000126 0.0000240 0.0000340 0.000198 0.000163 1988 1 3 47163 -0.020308 0.415273 0.3622262 0.0011073 -0.000110 0.000007 0.000173 0.000124 0.0000240 0.0000339 0.000197 0.000161 1988 1 4 47164 -0.018432 0.416075 0.3610628 0.0011487 -0.000210 -0.000094 0.000170 0.000123 0.0000240 0.0000339 0.000196 0.000159 1988 1 5 47165 -0.016446 0.417979 0.3598151 0.0012283 -0.000015 -0.000313 0.000167 0.000121 0.0000239 0.0000339 0.000195 0.000157 1988 1 6 47166 -0.013868 0.419092 0.3585064 0.0013360 0.000132 -0.000524 0.000166 0.000119 0.0000239 0.0000339 0.000193 0.000155 1988 1 7 47167 -0.013481 0.418956 0.3571385 0.0014710 0.000204 -0.000712 0.000163 0.000117 0.0000240 0.0000339 0.000191 0.000152 1988 1 8 47168 -0.011189 0.419525 0.3556691 0.0016273 0.000276 -0.000900 0.000163 0.000116 0.0000240 0.0000340 0.000190 0.000150 1988 1 9 47169 -0.009869 0.420282 0.3540390 0.0017803 -0.000138 -0.000271 0.000163 0.000117 0.0000241 0.0000340 0.000190 0.000151 1988 1 10 47170 -0.008837 0.420406 0.3521590 0.0018876 -0.000361 -0.000345 0.000164 0.000118 0.0000241 0.0000341 0.000191 0.000151 1988 1 11 47171 -0.005718 0.420441 0.3501393 0.0019106 -0.000495 -0.000689 0.000164 0.000119 0.0000241 0.0000341 0.000191 0.000151 1988 1 12 47172 -0.004846 0.420729 0.3482001 0.0018383 -0.000445 -0.000213 0.000164 0.000119 0.0000240 0.0000340 0.000191 0.000152 1988 1 13 47173 -0.002747 0.421110 0.3464687 0.0016917 -0.000393 0.000267 0.000162 0.000119 0.0000240 0.0000338 0.000191 0.000152 1988 1 14 47174 -0.001971 0.422618 0.3449744 0.0015071 -0.000437 0.000365 0.000163 0.000120 0.0000238 0.0000336 0.000192 0.000154 1988 1 15 47175 -0.000965 0.423887 0.3436142 0.0013193 -0.000265 -0.000269 0.000166 0.000122 0.0000236 0.0000334 0.000193 0.000156 1988 1 16 47176 0.001585 0.423796 0.3423330 0.0011618 -0.000014 -0.001123 0.000168 0.000123 0.0000234 0.0000330 0.000194 0.000158 1988 1 17 47177 0.001265 0.424709 0.3411378 0.0010747 -0.000052 -0.000822 0.000170 0.000124 0.0000231 0.0000326 0.000194 0.000160 1988 1 18 47178 0.003072 0.425019 0.3400469 0.0010984 -0.000053 -0.000369 0.000171 0.000125 0.0000228 0.0000322 0.000195 0.000162 1988 1 19 47179 0.004210 0.423918 0.3389229 0.0012462 -0.000046 0.000115 0.000173 0.000126 0.0000224 0.0000317 0.000196 0.000164 1988 1 20 47180 0.004512 0.424364 0.3375781 0.0014785 -0.000255 -0.000027 0.000175 0.000128 0.0000220 0.0000312 0.000196 0.000165 1988 1 21 47181 0.006995 0.425238 0.3359480 0.0017114 -0.000233 -0.000262 0.000178 0.000130 0.0000216 0.0000306 0.000196 0.000165 1988 1 22 47182 0.008094 0.425224 0.3341202 0.0018581 -0.000111 -0.000463 0.000179 0.000132 0.0000212 0.0000300 0.000195 0.000165 1988 1 23 47183 0.009967 0.425990 0.3322644 0.0018702 0.000011 -0.000665 0.000181 0.000133 0.0000208 0.0000295 0.000195 0.000165 1988 1 24 47184 0.011867 0.426905 0.3305338 0.0017503 -0.000302 -0.000143 0.000183 0.000134 0.0000205 0.0000289 0.000195 0.000167 1988 1 25 47185 0.013648 0.426819 0.3289212 0.0015335 -0.000386 -0.000047 0.000186 0.000136 0.0000201 0.0000284 0.000194 0.000168 1988 1 26 47186 0.017197 0.427692 0.3274668 0.0012642 -0.000364 -0.000140 0.000188 0.000137 0.0000196 0.0000278 0.000194 0.000169 1988 1 27 47187 0.019628 0.428951 0.3262620 0.0009899 -0.000342 -0.000234 0.000190 0.000138 0.0000192 0.0000272 0.000193 0.000169 1988 1 28 47188 0.021201 0.428580 0.3253624 0.0007612 -0.000320 -0.000328 0.000191 0.000139 0.0000189 0.0000271 0.000192 0.000170 1988 1 29 47189 0.023655 0.428844 0.3247402 0.0006253 -0.000268 0.000504 0.000193 0.000140 0.0000191 0.0000271 0.000194 0.000174 1988 1 30 47190 0.026347 0.429686 0.3242025 0.0006094 -0.000196 0.000604 0.000195 0.000141 0.0000194 0.0000275 0.000197 0.000178 1988 1 31 47191 0.028438 0.429441 0.3235744 0.0007080 -0.000121 0.000433 0.000196 0.000141 0.0000197 0.0000279 0.000199 0.000182 1988 2 1 47192 0.031052 0.429839 0.3227549 0.0008883 -0.000045 0.000262 0.000197 0.000141 0.0000200 0.0000283 0.000202 0.000186 1988 2 2 47193 0.034655 0.430448 0.3217057 0.0011076 0.000030 0.000091 0.000197 0.000140 0.0000203 0.0000287 0.000204 0.000190 1988 2 3 47194 0.036904 0.430285 0.3204436 0.0013303 0.000106 -0.000080 0.000197 0.000140 0.0000205 0.0000290 0.000207 0.000194 1988 2 4 47195 0.039213 0.430734 0.3190074 0.0015356 0.000008 -0.000327 0.000197 0.000139 0.0000208 0.0000294 0.000209 0.000197 1988 2 5 47196 0.043035 0.431428 0.3174153 0.0017142 -0.000522 -0.000283 0.000197 0.000139 0.0000210 0.0000297 0.000210 0.000201 1988 2 6 47197 0.045439 0.431363 0.3156647 0.0018578 -0.001225 -0.000093 0.000197 0.000138 0.0000212 0.0000299 0.000211 0.000205 1988 2 7 47198 0.047528 0.431731 0.3137645 0.0019529 -0.000781 0.000052 0.000197 0.000138 0.0000213 0.0000301 0.000212 0.000209 1988 2 8 47199 0.049334 0.432673 0.3117822 0.0019829 -0.000103 -0.000245 0.000197 0.000138 0.0000213 0.0000300 0.000213 0.000211 1988 2 9 47200 0.050257 0.433198 0.3098164 0.0019338 0.000140 -0.001145 0.000197 0.000138 0.0000212 0.0000300 0.000212 0.000213 1988 2 10 47201 0.051820 0.434026 0.3079370 0.0018026 0.000123 -0.001911 0.000196 0.000137 0.0000211 0.0000298 0.000211 0.000212 1988 2 11 47202 0.051453 0.434589 0.3061956 0.0016070 0.000066 -0.002327 0.000195 0.000137 0.0000210 0.0000297 0.000210 0.000211 1988 2 12 47203 0.053358 0.434293 0.3046236 0.0013969 0.000361 -0.000873 0.000194 0.000136 0.0000209 0.0000299 0.000208 0.000209 1988 2 13 47204 0.055225 0.434045 0.3032463 0.0012560 0.000108 0.000107 0.000193 0.000136 0.0000213 0.0000303 0.000209 0.000210 1988 2 14 47205 0.051140 0.433785 0.3022701 0.0012740 -0.000162 0.000101 0.000192 0.000138 0.0000219 0.0000309 0.000210 0.000211 1988 2 15 47206 0.052354 0.433273 0.3008791 0.0014859 -0.000347 -0.000056 0.000191 0.000140 0.0000224 0.0000316 0.000211 0.000212 1988 2 16 47207 0.056258 0.432213 0.2991167 0.0018456 -0.000439 0.000002 0.000189 0.000141 0.0000227 0.0000320 0.000212 0.000212 1988 2 17 47208 0.056019 0.431285 0.2970478 0.0022549 -0.000189 0.000147 0.000188 0.000142 0.0000229 0.0000323 0.000213 0.000212 1988 2 18 47209 0.058689 0.431410 0.2945924 0.0025996 0.000235 0.000336 0.000186 0.000142 0.0000230 0.0000325 0.000214 0.000213 1988 2 19 47210 0.061741 0.432048 0.2918943 0.0027870 0.000216 0.000255 0.000185 0.000143 0.0000230 0.0000325 0.000214 0.000213 1988 2 20 47211 0.063017 0.431239 0.2891243 0.0027775 0.000046 0.000082 0.000184 0.000144 0.0000230 0.0000326 0.000214 0.000212 1988 2 21 47212 0.064248 0.429369 0.2864417 0.0025916 -0.000085 -0.000064 0.000184 0.000145 0.0000230 0.0000326 0.000214 0.000213 1988 2 22 47213 0.065202 0.429790 0.2839806 0.0022935 -0.000141 -0.000158 0.000185 0.000146 0.0000231 0.0000327 0.000215 0.000214 1988 2 23 47214 0.066137 0.430554 0.2818314 0.0019633 -0.000198 -0.000251 0.000185 0.000147 0.0000232 0.0000328 0.000216 0.000215 1988 2 24 47215 0.066710 0.429489 0.2800113 0.0016713 0.000045 -0.000313 0.000186 0.000148 0.0000232 0.0000327 0.000216 0.000216 1988 2 25 47216 0.067413 0.429381 0.2784555 0.0014639 0.000322 0.000244 0.000188 0.000150 0.0000230 0.0000325 0.000216 0.000216 1988 2 26 47217 0.067317 0.430104 0.2770608 0.0013617 0.000546 0.000960 0.000190 0.000152 0.0000227 0.0000321 0.000215 0.000215 1988 2 27 47218 0.068386 0.429599 0.2757173 0.0013657 0.000505 0.000575 0.000192 0.000154 0.0000225 0.0000318 0.000215 0.000213 1988 2 28 47219 0.070170 0.429180 0.2743198 0.0014629 0.000464 0.000190 0.000194 0.000156 0.0000222 0.0000313 0.000214 0.000212 1988 2 29 47220 0.071560 0.430079 0.2727812 0.0016286 0.000325 0.000100 0.000195 0.000157 0.0000219 0.0000309 0.000213 0.000210 1988 3 1 47221 0.074673 0.430465 0.2710454 0.0018290 0.000156 0.000101 0.000196 0.000158 0.0000215 0.0000305 0.000212 0.000208 1988 3 2 47222 0.076858 0.430898 0.2690980 0.0020271 -0.000013 0.000103 0.000197 0.000158 0.0000212 0.0000300 0.000211 0.000207 1988 3 3 47223 0.078668 0.431813 0.2669669 0.0021901 -0.000182 0.000104 0.000198 0.000159 0.0000209 0.0000295 0.000210 0.000205 1988 3 4 47224 0.081091 0.431966 0.2647114 0.0022957 -0.000351 0.000106 0.000198 0.000160 0.0000205 0.0000290 0.000209 0.000204 1988 3 5 47225 0.082822 0.432736 0.2624023 0.0023333 -0.000279 0.000252 0.000199 0.000160 0.0000201 0.0000285 0.000207 0.000202 1988 3 6 47226 0.084543 0.433416 0.2601028 0.0023004 -0.000132 0.000443 0.000199 0.000161 0.0000197 0.0000279 0.000205 0.000199 1988 3 7 47227 0.086812 0.432893 0.2578683 0.0021977 0.000016 0.000635 0.000199 0.000161 0.0000193 0.0000273 0.000204 0.000197 1988 3 8 47228 0.089046 0.432607 0.2557545 0.0020274 0.000134 0.000762 0.000200 0.000161 0.0000189 0.0000268 0.000202 0.000195 1988 3 9 47229 0.090241 0.432402 0.2538219 0.0017985 -0.000034 0.000273 0.000201 0.000163 0.0000186 0.0000263 0.000199 0.000191 1988 3 10 47230 0.093444 0.431192 0.2521249 0.0015348 0.000212 -0.000188 0.000202 0.000164 0.0000182 0.0000260 0.000196 0.000188 1988 3 11 47231 0.096482 0.430110 0.2506889 0.0012824 0.000284 -0.000214 0.000204 0.000166 0.0000182 0.0000258 0.000196 0.000186 1988 3 12 47232 0.098944 0.429443 0.2494869 0.0011057 0.000201 -0.000031 0.000208 0.000170 0.0000182 0.0000258 0.000196 0.000186 1988 3 13 47233 0.103783 0.428981 0.2484228 0.0010686 0.000117 0.000153 0.000211 0.000173 0.0000183 0.0000259 0.000197 0.000186 1988 3 14 47234 0.106195 0.428707 0.2473410 0.0012032 0.000034 0.000337 0.000214 0.000176 0.0000184 0.0000259 0.000198 0.000186 1988 3 15 47235 0.107948 0.426778 0.2460655 0.0014830 0.000025 -0.000487 0.000217 0.000179 0.0000183 0.0000257 0.000197 0.000184 1988 3 16 47236 0.110518 0.426683 0.2444231 0.0018192 0.000089 -0.001385 0.000219 0.000181 0.0000179 0.0000253 0.000196 0.000181 1988 3 17 47237 0.112979 0.427350 0.2424128 0.0020939 0.000124 -0.001979 0.000221 0.000183 0.0000176 0.0000249 0.000195 0.000178 1988 3 18 47238 0.115239 0.424856 0.2402060 0.0022140 -0.000381 -0.000409 0.000223 0.000184 0.0000172 0.0000249 0.000193 0.000177 1988 3 19 47239 0.115799 0.424560 0.2380241 0.0021524 -0.000436 0.000190 0.000225 0.000186 0.0000176 0.0000248 0.000193 0.000179 1988 3 20 47240 0.117990 0.424350 0.2359966 0.0019498 -0.000296 0.000271 0.000227 0.000189 0.0000179 0.0000253 0.000192 0.000180 1988 3 21 47241 0.120079 0.422083 0.2341958 0.0016838 -0.000119 0.000242 0.000230 0.000191 0.0000182 0.0000258 0.000192 0.000181 1988 3 22 47242 0.122656 0.421138 0.2326406 0.0014311 0.000058 0.000212 0.000231 0.000192 0.0000185 0.0000262 0.000191 0.000182 1988 3 23 47243 0.124040 0.419150 0.2312942 0.0012419 0.000235 0.000182 0.000232 0.000193 0.0000189 0.0000267 0.000191 0.000183 1988 3 24 47244 0.122165 0.416655 0.2300927 0.0011360 0.000412 0.000152 0.000232 0.000194 0.0000193 0.0000271 0.000190 0.000184 1988 3 25 47245 0.124932 0.415220 0.2289629 0.0011130 0.000373 0.000183 0.000232 0.000195 0.0000195 0.0000275 0.000189 0.000183 1988 3 26 47246 0.127912 0.413110 0.2278277 0.0011661 0.000264 0.000233 0.000232 0.000196 0.0000197 0.0000278 0.000187 0.000183 1988 3 27 47247 0.128662 0.411395 0.2266122 0.0012872 0.000155 0.000284 0.000231 0.000197 0.0000199 0.0000281 0.000185 0.000182 1988 3 28 47248 0.130861 0.411333 0.2252504 0.0014650 0.000046 0.000334 0.000230 0.000197 0.0000200 0.0000283 0.000184 0.000182 1988 3 29 47249 0.131437 0.409874 0.2236915 0.0016797 -0.000063 0.000385 0.000229 0.000197 0.0000202 0.0000286 0.000182 0.000181 1988 3 30 47250 0.131920 0.408223 0.2219077 0.0019023 0.000046 0.000180 0.000227 0.000197 0.0000204 0.0000289 0.000181 0.000180 1988 3 31 47251 0.132637 0.407427 0.2199043 0.0020976 0.000232 -0.000115 0.000225 0.000198 0.0000207 0.0000292 0.000179 0.000178 1988 4 1 47252 0.132917 0.405850 0.2177246 0.0022324 0.000366 -0.000359 0.000224 0.000197 0.0000209 0.0000296 0.000177 0.000177 1988 4 2 47253 0.133227 0.405618 0.2154465 0.0022830 0.000029 -0.000137 0.000222 0.000196 0.0000212 0.0000299 0.000176 0.000175 1988 4 3 47254 0.132772 0.403422 0.2131686 0.0022419 -0.000201 0.000025 0.000220 0.000195 0.0000213 0.0000301 0.000174 0.000173 1988 4 4 47255 0.132289 0.401387 0.2109846 0.0021199 -0.000318 0.000121 0.000219 0.000195 0.0000213 0.0000302 0.000172 0.000169 1988 4 5 47256 0.132403 0.401363 0.2089600 0.0019453 -0.000435 0.000218 0.000218 0.000193 0.0000213 0.0000301 0.000170 0.000166 1988 4 6 47257 0.132657 0.398542 0.2071197 0.0017575 -0.000552 0.000315 0.000216 0.000191 0.0000213 0.0000301 0.000168 0.000163 1988 4 7 47258 0.132874 0.397173 0.2054459 0.0016008 -0.000349 0.000297 0.000214 0.000189 0.0000213 0.0000301 0.000169 0.000165 1988 4 8 47259 0.134252 0.396008 0.2038826 0.0015174 -0.000039 0.000242 0.000212 0.000187 0.0000213 0.0000302 0.000172 0.000168 1988 4 9 47260 0.135725 0.393697 0.2023433 0.0015406 -0.000049 -0.000170 0.000209 0.000184 0.0000215 0.0000304 0.000174 0.000171 1988 4 10 47261 0.136576 0.393982 0.2007280 0.0016864 -0.000157 -0.000693 0.000207 0.000181 0.0000217 0.0000305 0.000177 0.000175 1988 4 11 47262 0.137853 0.393316 0.1989324 0.0019419 -0.000176 -0.000622 0.000206 0.000178 0.0000217 0.0000307 0.000179 0.000178 1988 4 12 47263 0.139184 0.390204 0.1968619 0.0022572 -0.000166 -0.000351 0.000204 0.000175 0.0000217 0.0000307 0.000180 0.000180 1988 4 13 47264 0.139567 0.388007 0.1944760 0.0025498 -0.000155 -0.000080 0.000203 0.000171 0.0000217 0.0000306 0.000182 0.000182 1988 4 14 47265 0.139714 0.386566 0.1918251 0.0027284 -0.000263 -0.000068 0.000202 0.000168 0.0000216 0.0000308 0.000183 0.000184 1988 4 15 47266 0.141322 0.383673 0.1890419 0.0027285 0.000200 -0.000383 0.000203 0.000167 0.0000219 0.0000311 0.000186 0.000186 1988 4 16 47267 0.143774 0.381462 0.1863597 0.0025432 0.000955 -0.000815 0.000206 0.000168 0.0000223 0.0000315 0.000189 0.000189 1988 4 17 47268 0.146172 0.379972 0.1840029 0.0022259 0.000787 -0.000551 0.000208 0.000170 0.0000226 0.0000319 0.000191 0.000191 1988 4 18 47269 0.147142 0.379582 0.1819931 0.0018608 0.000429 -0.000144 0.000209 0.000170 0.0000228 0.0000323 0.000194 0.000194 1988 4 19 47270 0.148812 0.378970 0.1802504 0.0015248 -0.000173 -0.000003 0.000211 0.000170 0.0000231 0.0000325 0.000197 0.000195 1988 4 20 47271 0.151433 0.377435 0.1788591 0.0012693 -0.000531 -0.000059 0.000212 0.000171 0.0000231 0.0000327 0.000198 0.000196 1988 4 21 47272 0.152196 0.377615 0.1777250 0.0011164 -0.000767 -0.000160 0.000213 0.000171 0.0000231 0.0000329 0.000200 0.000197 1988 4 22 47273 0.154120 0.374625 0.1766186 0.0010626 -0.000397 -0.000136 0.000215 0.000171 0.0000234 0.0000333 0.000202 0.000199 1988 4 23 47274 0.155389 0.373526 0.1754721 0.0010947 0.000007 -0.000014 0.000216 0.000172 0.0000240 0.0000339 0.000204 0.000204 1988 4 24 47275 0.156565 0.373844 0.1743458 0.0012059 0.000143 0.000463 0.000217 0.000172 0.0000246 0.0000348 0.000206 0.000208 1988 4 25 47276 0.158731 0.372147 0.1731526 0.0013886 0.000195 0.001055 0.000218 0.000173 0.0000252 0.0000356 0.000207 0.000212 1988 4 26 47277 0.158433 0.373984 0.1717164 0.0016146 0.000246 0.001647 0.000219 0.000173 0.0000258 0.0000364 0.000208 0.000217 1988 4 27 47278 0.159931 0.369065 0.1699345 0.0018315 0.000297 0.001056 0.000219 0.000172 0.0000263 0.0000372 0.000210 0.000220 1988 4 28 47279 0.161770 0.364614 0.1679315 0.0019855 0.000348 0.000237 0.000218 0.000170 0.0000267 0.0000377 0.000212 0.000223 1988 4 29 47280 0.162978 0.366957 0.1659215 0.0020434 0.001055 -0.000283 0.000215 0.000168 0.0000271 0.0000382 0.000212 0.000224 1988 4 30 47281 0.165046 0.365178 0.1639590 0.0019945 0.001975 -0.000706 0.000212 0.000165 0.0000273 0.0000385 0.000213 0.000225 1988 5 1 47282 0.163750 0.363950 0.1620219 0.0018426 -0.000589 0.001233 0.000208 0.000162 0.0000273 0.0000385 0.000213 0.000225 1988 5 2 47283 0.164005 0.361786 0.1601936 0.0016124 -0.000887 0.001042 0.000204 0.000158 0.0000271 0.0000384 0.000211 0.000224 1988 5 3 47284 0.168547 0.359783 0.1586545 0.0013630 -0.000612 0.000346 0.000199 0.000154 0.0000269 0.0000382 0.000210 0.000221 1988 5 4 47285 0.169900 0.361003 0.1575026 0.0011802 -0.001145 -0.000240 0.000195 0.000150 0.0000268 0.0000380 0.000208 0.000219 1988 5 5 47286 0.167883 0.360643 0.1564772 0.0011361 -0.001939 -0.000790 0.000192 0.000147 0.0000268 0.0000377 0.000206 0.000216 1988 5 6 47287 0.168766 0.358358 0.1552112 0.0012530 -0.002513 -0.001094 0.000188 0.000143 0.0000265 0.0000374 0.000205 0.000214 1988 5 7 47288 0.170295 0.355188 0.1539037 0.0015012 -0.001417 -0.000386 0.000185 0.000141 0.0000261 0.0000369 0.000203 0.000210 1988 5 8 47289 0.169680 0.354265 0.1523633 0.0018082 -0.000322 0.000322 0.000186 0.000141 0.0000256 0.0000361 0.000202 0.000207 1988 5 9 47290 0.170366 0.352380 0.1502010 0.0020729 -0.000065 0.000347 0.000186 0.000141 0.0000250 0.0000353 0.000200 0.000202 1988 5 10 47291 0.171405 0.349982 0.1478292 0.0022157 -0.000079 0.000152 0.000186 0.000141 0.0000243 0.0000344 0.000198 0.000198 1988 5 11 47292 0.171937 0.348724 0.1456061 0.0022244 -0.000092 -0.000042 0.000185 0.000140 0.0000236 0.0000333 0.000196 0.000193 1988 5 12 47293 0.172619 0.346227 0.1435762 0.0021408 -0.000123 -0.000208 0.000184 0.000139 0.0000228 0.0000323 0.000195 0.000189 1988 5 13 47294 0.173560 0.345566 0.1416766 0.0020149 -0.000333 -0.000068 0.000182 0.000138 0.0000222 0.0000313 0.000193 0.000184 1988 5 14 47295 0.175174 0.344412 0.1398067 0.0018721 -0.000277 -0.000027 0.000181 0.000136 0.0000215 0.0000304 0.000191 0.000179 1988 5 15 47296 0.176095 0.343009 0.1379624 0.0017132 -0.000124 -0.000023 0.000180 0.000134 0.0000208 0.0000295 0.000189 0.000173 1988 5 16 47297 0.176944 0.341758 0.1362246 0.0015348 0.000030 -0.000018 0.000178 0.000132 0.0000203 0.0000287 0.000187 0.000168 1988 5 17 47298 0.177676 0.338922 0.1346894 0.0013493 0.000184 -0.000013 0.000176 0.000130 0.0000197 0.0000283 0.000185 0.000163 1988 5 18 47299 0.177002 0.337526 0.1334088 0.0011863 0.000275 0.000063 0.000174 0.000127 0.0000197 0.0000279 0.000185 0.000161 1988 5 19 47300 0.176637 0.336213 0.1323061 0.0010807 0.000293 0.000143 0.000171 0.000125 0.0000198 0.0000279 0.000184 0.000160 1988 5 20 47301 0.176621 0.334111 0.1312873 0.0010559 0.000092 0.000164 0.000169 0.000123 0.0000198 0.0000280 0.000183 0.000158 1988 5 21 47302 0.175695 0.331689 0.1302489 0.0011161 -0.000110 0.000185 0.000167 0.000121 0.0000198 0.0000279 0.000183 0.000157 1988 5 22 47303 0.176610 0.329651 0.1290898 0.0012440 -0.000272 -0.000097 0.000166 0.000120 0.0000197 0.0000277 0.000182 0.000155 1988 5 23 47304 0.177680 0.328028 0.1277560 0.0014064 -0.000390 -0.000710 0.000165 0.000119 0.0000195 0.0000275 0.000180 0.000153 1988 5 24 47305 0.176203 0.325694 0.1262485 0.0015653 -0.000082 -0.000297 0.000164 0.000117 0.0000192 0.0000273 0.000180 0.000152 1988 5 25 47306 0.176271 0.323967 0.1246049 0.0016879 0.000050 -0.000126 0.000163 0.000117 0.0000192 0.0000272 0.000180 0.000153 1988 5 26 47307 0.176840 0.322279 0.1228775 0.0017530 0.000100 -0.000064 0.000162 0.000117 0.0000192 0.0000271 0.000181 0.000155 1988 5 27 47308 0.176040 0.320517 0.1211260 0.0017496 0.000151 -0.000002 0.000161 0.000117 0.0000192 0.0000271 0.000181 0.000157 1988 5 28 47309 0.174926 0.318744 0.1194164 0.0016750 0.000202 0.000059 0.000160 0.000117 0.0000192 0.0000271 0.000182 0.000159 1988 5 29 47310 0.173306 0.316738 0.1178138 0.0015353 0.000217 -0.000054 0.000160 0.000118 0.0000191 0.0000270 0.000182 0.000160 1988 5 30 47311 0.172076 0.315140 0.1163725 0.0013495 0.000220 -0.000226 0.000159 0.000119 0.0000190 0.0000269 0.000182 0.000161 1988 5 31 47312 0.170688 0.313142 0.1151190 0.0011529 0.000223 -0.000399 0.000159 0.000119 0.0000190 0.0000268 0.000182 0.000161 1988 6 1 47313 0.169673 0.311311 0.1140396 0.0009932 0.000226 -0.000572 0.000158 0.000120 0.0000189 0.0000267 0.000182 0.000162 1988 6 2 47314 0.168908 0.309464 0.1130765 0.0009163 0.000229 -0.000744 0.000157 0.000121 0.0000188 0.0000266 0.000182 0.000163 1988 6 3 47315 0.168270 0.307059 0.1121384 0.0009488 0.000068 -0.000560 0.000157 0.000121 0.0000187 0.0000264 0.000182 0.000163 1988 6 4 47316 0.167909 0.305335 0.1111240 0.0010852 -0.000147 -0.000259 0.000157 0.000121 0.0000185 0.0000262 0.000181 0.000162 1988 6 5 47317 0.167155 0.303773 0.1099506 0.0012878 -0.000361 0.000041 0.000156 0.000121 0.0000184 0.0000260 0.000181 0.000161 1988 6 6 47318 0.167137 0.302203 0.1085788 0.0014978 -0.000309 -0.000093 0.000156 0.000121 0.0000183 0.0000259 0.000181 0.000162 1988 6 7 47319 0.166100 0.300604 0.1070208 0.0016525 -0.000019 -0.000539 0.000156 0.000121 0.0000183 0.0000257 0.000182 0.000164 1988 6 8 47320 0.164858 0.298050 0.1053434 0.0017023 -0.000256 -0.001095 0.000156 0.000121 0.0000181 0.0000255 0.000182 0.000165 1988 6 9 47321 0.165368 0.296001 0.1036618 0.0016230 -0.000659 -0.001686 0.000156 0.000120 0.0000179 0.0000253 0.000182 0.000165 1988 6 10 47322 0.165479 0.294572 0.1021089 0.0014232 -0.000986 -0.002152 0.000157 0.000120 0.0000177 0.0000250 0.000182 0.000166 1988 6 11 47323 0.164589 0.292862 0.1007993 0.0011441 -0.000484 -0.001268 0.000156 0.000119 0.0000175 0.0000247 0.000182 0.000165 1988 6 12 47324 0.164103 0.291166 0.0997967 0.0008482 0.000019 -0.000385 0.000156 0.000118 0.0000173 0.0000244 0.000182 0.000165 1988 6 13 47325 0.164813 0.288982 0.0990932 0.0006005 0.000228 -0.000126 0.000156 0.000117 0.0000171 0.0000241 0.000182 0.000163 1988 6 14 47326 0.165177 0.286996 0.0986064 0.0004464 0.000342 -0.000071 0.000156 0.000116 0.0000168 0.0000237 0.000182 0.000162 1988 6 15 47327 0.165555 0.285088 0.0982130 0.0003980 0.000456 -0.000015 0.000155 0.000114 0.0000165 0.0000234 0.000182 0.000160 1988 6 16 47328 0.165549 0.282956 0.0977971 0.0004357 0.000571 0.000040 0.000154 0.000113 0.0000163 0.0000230 0.000182 0.000158 1988 6 17 47329 0.165246 0.281102 0.0972850 0.0005233 0.000685 0.000095 0.000153 0.000112 0.0000161 0.0000226 0.000181 0.000157 1988 6 18 47330 0.165675 0.279633 0.0966594 0.0006274 0.000876 0.000017 0.000152 0.000110 0.0000157 0.0000224 0.000181 0.000154 1988 6 19 47331 0.164016 0.277703 0.0959848 0.0007290 0.000468 0.000072 0.000151 0.000109 0.0000156 0.0000222 0.000180 0.000153 1988 6 20 47332 0.163337 0.274308 0.0952542 0.0008194 0.000046 0.000077 0.000152 0.000109 0.0000157 0.0000223 0.000180 0.000152 1988 6 21 47333 0.164578 0.272472 0.0944271 0.0008883 -0.000022 -0.000078 0.000154 0.000110 0.0000159 0.0000225 0.000180 0.000152 1988 6 22 47334 0.164285 0.270755 0.0935192 0.0009192 -0.000089 -0.000234 0.000156 0.000111 0.0000161 0.0000227 0.000180 0.000151 1988 6 23 47335 0.164798 0.266970 0.0925808 0.0008945 -0.000190 -0.000004 0.000158 0.000111 0.0000162 0.0000229 0.000179 0.000150 1988 6 24 47336 0.166210 0.264780 0.0917084 0.0008041 -0.000130 0.000069 0.000160 0.000111 0.0000162 0.0000229 0.000179 0.000148 1988 6 25 47337 0.166752 0.263349 0.0909823 0.0006501 0.000027 -0.000026 0.000161 0.000112 0.0000162 0.0000229 0.000178 0.000147 1988 6 26 47338 0.166706 0.262131 0.0904477 0.0004481 0.000183 -0.000122 0.000162 0.000112 0.0000162 0.0000229 0.000178 0.000146 1988 6 27 47339 0.167788 0.261105 0.0901205 0.0002287 0.000339 -0.000218 0.000163 0.000112 0.0000161 0.0000229 0.000177 0.000144 1988 6 28 47340 0.169335 0.258609 0.0899813 0.0000382 0.000121 -0.000277 0.000164 0.000112 0.0000163 0.0000230 0.000177 0.000144 1988 6 29 47341 0.169733 0.256134 0.0899803 -0.0000682 -0.000170 -0.000329 0.000165 0.000111 0.0000164 0.0000232 0.000177 0.000143 1988 6 30 47342 0.170052 0.254551 0.0900284 -0.0000441 -0.000462 -0.000381 0.000165 0.000110 0.0000166 0.0000235 0.000177 0.000142 1988 7 1 47343 0.169423 0.253071 0.0900037 0.0001248 -0.000643 -0.000405 0.000165 0.000110 0.0000168 0.0000237 0.000177 0.000141 1988 7 2 47344 0.169343 0.250963 0.0897846 0.0004043 0.000395 -0.000123 0.000165 0.000108 0.0000169 0.0000239 0.000177 0.000141 1988 7 3 47345 0.169327 0.249077 0.0892867 0.0007147 0.000485 -0.000228 0.000165 0.000108 0.0000171 0.0000242 0.000176 0.000140 1988 7 4 47346 0.167568 0.246891 0.0884382 0.0009573 0.000085 -0.000514 0.000167 0.000109 0.0000172 0.0000243 0.000176 0.000138 1988 7 5 47347 0.168216 0.244994 0.0872964 0.0010552 -0.000096 -0.000585 0.000168 0.000110 0.0000173 0.0000245 0.000175 0.000137 1988 7 6 47348 0.169032 0.244786 0.0863040 0.0009898 0.000094 -0.000255 0.000169 0.000111 0.0000173 0.0000245 0.000175 0.000137 1988 7 7 47349 0.168000 0.242523 0.0854528 0.0007964 0.000085 0.000486 0.000170 0.000111 0.0000173 0.0000245 0.000175 0.000136 1988 7 8 47350 0.168575 0.239048 0.0847289 0.0005352 0.000075 0.000272 0.000170 0.000111 0.0000173 0.0000246 0.000174 0.000135 1988 7 9 47351 0.168143 0.237207 0.0843226 0.0002724 -0.000052 -0.000069 0.000171 0.000112 0.0000175 0.0000248 0.000174 0.000135 1988 7 10 47352 0.166655 0.235103 0.0842373 0.0000666 -0.000310 -0.000211 0.000172 0.000112 0.0000178 0.0000251 0.000174 0.000136 1988 7 11 47353 0.166752 0.233427 0.0842304 -0.0000496 -0.000352 -0.000299 0.000172 0.000112 0.0000180 0.0000255 0.000174 0.000137 1988 7 12 47354 0.167213 0.232161 0.0842116 -0.0000706 0.000048 -0.000278 0.000172 0.000111 0.0000183 0.0000258 0.000173 0.000137 1988 7 13 47355 0.166915 0.229727 0.0843060 -0.0000044 0.000255 -0.000287 0.000173 0.000111 0.0000185 0.0000261 0.000173 0.000137 1988 7 14 47356 0.165276 0.227268 0.0842765 0.0001295 0.000256 -0.000341 0.000172 0.000110 0.0000186 0.0000263 0.000173 0.000137 1988 7 15 47357 0.165283 0.225441 0.0840408 0.0002978 0.000032 0.000524 0.000172 0.000109 0.0000187 0.0000264 0.000172 0.000137 1988 7 16 47358 0.165957 0.223788 0.0836236 0.0004656 -0.000220 0.001511 0.000171 0.000108 0.0000188 0.0000266 0.000172 0.000137 1988 7 17 47359 0.163664 0.221956 0.0830614 0.0006087 -0.000190 0.001291 0.000169 0.000106 0.0000189 0.0000267 0.000172 0.000137 1988 7 18 47360 0.162920 0.220073 0.0824040 0.0007174 -0.000055 0.000957 0.000168 0.000105 0.0000190 0.0000268 0.000172 0.000139 1988 7 19 47361 0.162659 0.218205 0.0816830 0.0007902 -0.000172 0.002049 0.000168 0.000107 0.0000191 0.0000270 0.000172 0.000140 1988 7 20 47362 0.161365 0.215768 0.0809083 0.0008250 -0.000268 0.001607 0.000168 0.000108 0.0000192 0.0000271 0.000173 0.000142 1988 7 21 47363 0.162265 0.213558 0.0800951 0.0008134 -0.000364 0.001166 0.000167 0.000108 0.0000193 0.0000273 0.000173 0.000143 1988 7 22 47364 0.161033 0.211747 0.0792825 0.0007442 -0.000460 0.000724 0.000165 0.000108 0.0000194 0.0000274 0.000173 0.000144 1988 7 23 47365 0.159175 0.209672 0.0785421 0.0006155 -0.000290 0.000286 0.000162 0.000108 0.0000194 0.0000274 0.000173 0.000145 1988 7 24 47366 0.158654 0.207893 0.0780258 0.0004471 -0.000062 0.000086 0.000160 0.000108 0.0000194 0.0000274 0.000173 0.000145 1988 7 25 47367 0.156654 0.205712 0.0776998 0.0002816 0.000129 0.000182 0.000158 0.000108 0.0000194 0.0000275 0.000172 0.000145 1988 7 26 47368 0.155599 0.202978 0.0774149 0.0001746 0.000228 0.000566 0.000156 0.000107 0.0000194 0.0000275 0.000173 0.000146 1988 7 27 47369 0.153898 0.201543 0.0773486 0.0001813 0.000274 0.000656 0.000153 0.000106 0.0000195 0.0000276 0.000173 0.000148 1988 7 28 47370 0.152911 0.200918 0.0769827 0.0003286 0.000159 0.000099 0.000151 0.000105 0.0000196 0.0000277 0.000173 0.000149 1988 7 29 47371 0.152447 0.198540 0.0766598 0.0005955 0.000099 -0.000401 0.000148 0.000104 0.0000196 0.0000277 0.000174 0.000151 1988 7 30 47372 0.149549 0.196145 0.0758260 0.0009094 0.000173 -0.000802 0.000145 0.000102 0.0000196 0.0000277 0.000174 0.000152 1988 7 31 47373 0.149092 0.194766 0.0747498 0.0011696 0.000234 -0.000218 0.000143 0.000100 0.0000196 0.0000277 0.000174 0.000153 1988 8 1 47374 0.148788 0.191943 0.0735479 0.0012958 0.000202 0.000353 0.000140 0.000099 0.0000195 0.0000275 0.000174 0.000154 1988 8 2 47375 0.148075 0.189910 0.0722696 0.0012551 0.000094 0.000307 0.000138 0.000098 0.0000194 0.0000274 0.000174 0.000155 1988 8 3 47376 0.147561 0.188345 0.0710962 0.0010679 -0.000037 -0.000047 0.000137 0.000099 0.0000192 0.0000272 0.000174 0.000156 1988 8 4 47377 0.145283 0.186137 0.0701545 0.0007951 -0.000168 -0.000401 0.000135 0.000100 0.0000191 0.0000269 0.000174 0.000157 1988 8 5 47378 0.144926 0.185037 0.0695072 0.0005102 -0.000031 -0.000491 0.000134 0.000100 0.0000189 0.0000266 0.000174 0.000157 1988 8 6 47379 0.142502 0.182606 0.0691577 0.0002719 0.000272 -0.000058 0.000133 0.000101 0.0000186 0.0000265 0.000174 0.000158 1988 8 7 47380 0.139755 0.180166 0.0689557 0.0001095 0.000284 0.000094 0.000131 0.000101 0.0000186 0.0000264 0.000174 0.000159 1988 8 8 47381 0.139209 0.178773 0.0688470 0.0000286 0.000255 0.000069 0.000131 0.000102 0.0000188 0.0000267 0.000175 0.000161 1988 8 9 47382 0.136855 0.176867 0.0688132 0.0000274 0.000378 0.000069 0.000132 0.000104 0.0000191 0.0000270 0.000177 0.000164 1988 8 10 47383 0.135474 0.175454 0.0687702 0.0001025 0.000501 0.000069 0.000133 0.000106 0.0000194 0.0000274 0.000179 0.000167 1988 8 11 47384 0.133067 0.173114 0.0686263 0.0002447 0.000624 0.000069 0.000133 0.000108 0.0000197 0.0000277 0.000181 0.000170 1988 8 12 47385 0.131521 0.170884 0.0683044 0.0004324 0.001458 -0.000564 0.000134 0.000109 0.0000199 0.0000281 0.000182 0.000173 1988 8 13 47386 0.131987 0.170061 0.0677701 0.0006338 0.002396 -0.001314 0.000133 0.000110 0.0000201 0.0000284 0.000183 0.000175 1988 8 14 47387 0.130500 0.168856 0.0670357 0.0008130 0.001685 -0.000900 0.000133 0.000111 0.0000203 0.0000287 0.000184 0.000177 1988 8 15 47388 0.129520 0.167613 0.0661493 0.0009389 0.000975 -0.000486 0.000133 0.000112 0.0000205 0.0000291 0.000185 0.000178 1988 8 16 47389 0.127598 0.166787 0.0651792 0.0009913 0.000264 -0.000073 0.000132 0.000113 0.0000208 0.0000294 0.000186 0.000179 1988 8 17 47390 0.125036 0.165903 0.0641990 0.0009622 0.000144 -0.000028 0.000132 0.000113 0.0000211 0.0000299 0.000187 0.000181 1988 8 18 47391 0.123173 0.164610 0.0632796 0.0008549 0.000205 -0.000097 0.000132 0.000114 0.0000214 0.0000303 0.000187 0.000183 1988 8 19 47392 0.120972 0.163465 0.0624890 0.0006840 0.000262 -0.000155 0.000132 0.000115 0.0000218 0.0000308 0.000188 0.000185 1988 8 20 47393 0.119453 0.162047 0.0618875 0.0004771 0.000254 -0.000044 0.000133 0.000116 0.0000222 0.0000314 0.000188 0.000185 1988 8 21 47394 0.117858 0.159848 0.0615075 0.0002772 0.000245 0.000066 0.000134 0.000118 0.0000226 0.0000318 0.000188 0.000185 1988 8 22 47395 0.115529 0.158691 0.0613255 0.0001402 0.000567 0.000110 0.000134 0.000119 0.0000229 0.0000323 0.000188 0.000184 1988 8 23 47396 0.112807 0.157767 0.0612410 0.0001224 0.000939 0.000134 0.000136 0.000121 0.0000232 0.0000328 0.000188 0.000184 1988 8 24 47397 0.110876 0.156175 0.0610920 0.0002578 0.000648 0.000194 0.000137 0.000122 0.0000235 0.0000333 0.000189 0.000184 1988 8 25 47398 0.108719 0.155043 0.0607056 0.0005350 0.000356 0.000253 0.000138 0.000124 0.0000239 0.0000337 0.000191 0.000185 1988 8 26 47399 0.105966 0.153435 0.0599654 0.0008895 0.000065 0.000312 0.000139 0.000125 0.0000242 0.0000342 0.000192 0.000186 1988 8 27 47400 0.103394 0.152323 0.0588604 0.0012194 0.000014 0.000334 0.000141 0.000127 0.0000245 0.0000346 0.000193 0.000186 1988 8 28 47401 0.100886 0.151969 0.0574961 0.0014246 0.000042 0.000343 0.000141 0.000128 0.0000247 0.0000349 0.000194 0.000185 1988 8 29 47402 0.099233 0.150890 0.0560508 0.0014478 0.000071 0.000352 0.000142 0.000129 0.0000249 0.0000352 0.000195 0.000185 1988 8 30 47403 0.097243 0.150013 0.0547074 0.0012970 0.000099 0.000361 0.000143 0.000130 0.0000251 0.0000352 0.000196 0.000184 1988 8 31 47404 0.094727 0.148581 0.0535897 0.0010353 0.000266 0.000390 0.000144 0.000131 0.0000248 0.0000351 0.000196 0.000182 1988 9 1 47405 0.092002 0.147044 0.0526989 0.0007484 0.000284 0.000260 0.000145 0.000132 0.0000246 0.0000348 0.000195 0.000179 1988 9 2 47406 0.089544 0.145999 0.0520519 0.0005106 -0.000298 0.000624 0.000147 0.000134 0.0000244 0.0000344 0.000194 0.000175 1988 9 3 47407 0.087351 0.144550 0.0516148 0.0003652 -0.001152 0.001264 0.000149 0.000135 0.0000241 0.0000340 0.000192 0.000171 1988 9 4 47408 0.085051 0.143846 0.0512858 0.0003202 -0.000750 0.000810 0.000150 0.000136 0.0000237 0.0000336 0.000192 0.000170 1988 9 5 47409 0.082603 0.143609 0.0509591 0.0003565 -0.000144 0.000178 0.000151 0.000138 0.0000234 0.0000331 0.000191 0.000169 1988 9 6 47410 0.080371 0.142861 0.0505522 0.0004429 0.000195 -0.000040 0.000153 0.000140 0.0000231 0.0000327 0.000190 0.000167 1988 9 7 47411 0.079203 0.141314 0.0500281 0.0005501 0.000446 -0.000120 0.000155 0.000142 0.0000228 0.0000322 0.000189 0.000165 1988 9 8 47412 0.076223 0.140693 0.0493891 0.0006599 0.000697 -0.000201 0.000158 0.000145 0.0000225 0.0000318 0.000187 0.000163 1988 9 9 47413 0.074499 0.140024 0.0486561 0.0007673 0.000948 -0.000281 0.000160 0.000148 0.0000222 0.0000314 0.000186 0.000161 1988 9 10 47414 0.072430 0.138565 0.0478506 0.0008753 0.000757 0.000078 0.000163 0.000150 0.0000219 0.0000310 0.000185 0.000161 1988 9 11 47415 0.067527 0.139234 0.0469963 0.0009845 0.000411 0.000630 0.000165 0.000153 0.0000217 0.0000306 0.000184 0.000160 1988 9 12 47416 0.067514 0.138100 0.0460176 0.0010814 0.000327 0.000577 0.000168 0.000155 0.0000213 0.0000301 0.000182 0.000160 1988 9 13 47417 0.066887 0.136257 0.0448959 0.0011383 0.000337 0.000311 0.000170 0.000157 0.0000209 0.0000296 0.000181 0.000161 1988 9 14 47418 0.063761 0.136512 0.0437080 0.0011272 0.000347 0.000046 0.000172 0.000159 0.0000205 0.0000290 0.000180 0.000162 1988 9 15 47419 0.061407 0.135078 0.0425678 0.0010390 0.000358 -0.000220 0.000174 0.000160 0.0000201 0.0000285 0.000179 0.000163 1988 9 16 47420 0.057987 0.134295 0.0415823 0.0008926 0.000291 -0.000239 0.000176 0.000162 0.0000198 0.0000280 0.000178 0.000163 1988 9 17 47421 0.055453 0.134404 0.0407904 0.0007298 0.000198 -0.000175 0.000178 0.000163 0.0000194 0.0000275 0.000176 0.000163 1988 9 18 47422 0.051739 0.134082 0.0401576 0.0006023 0.000106 -0.000111 0.000180 0.000164 0.0000191 0.0000272 0.000175 0.000163 1988 9 19 47423 0.049040 0.133796 0.0395968 0.0005596 0.000157 -0.000242 0.000181 0.000166 0.0000190 0.0000269 0.000175 0.000164 1988 9 20 47424 0.046907 0.132616 0.0390057 0.0006387 0.000259 -0.000441 0.000182 0.000167 0.0000190 0.0000268 0.000176 0.000165 1988 9 21 47425 0.043555 0.131765 0.0382702 0.0008537 -0.000017 -0.000249 0.000183 0.000169 0.0000189 0.0000268 0.000176 0.000165 1988 9 22 47426 0.040330 0.131418 0.0372561 0.0011820 -0.000075 -0.000099 0.000184 0.000170 0.0000190 0.0000265 0.000177 0.000166 1988 9 23 47427 0.036281 0.131211 0.0358762 0.0015586 0.000040 -0.000038 0.000184 0.000170 0.0000185 0.0000265 0.000177 0.000167 1988 9 24 47428 0.033559 0.130747 0.0341364 0.0018888 0.000155 0.000024 0.000185 0.000171 0.0000185 0.0000261 0.000178 0.000168 1988 9 25 47429 0.029128 0.129901 0.0321388 0.0020794 0.000270 0.000086 0.000186 0.000172 0.0000185 0.0000260 0.000179 0.000169 1988 9 26 47430 0.025287 0.129216 0.0300546 0.0020764 0.000487 0.000133 0.000187 0.000174 0.0000183 0.0000259 0.000180 0.000170 1988 9 27 47431 0.024293 0.129150 0.0280705 0.0018875 0.000735 0.000176 0.000189 0.000176 0.0000182 0.0000257 0.000180 0.000170 1988 9 28 47432 0.021096 0.128832 0.0263330 0.0015779 0.000983 0.000219 0.000189 0.000177 0.0000180 0.0000255 0.000180 0.000170 1988 9 29 47433 0.017225 0.128448 0.0249138 0.0012415 0.001145 0.000251 0.000189 0.000177 0.0000178 0.0000253 0.000180 0.000170 1988 9 30 47434 0.013660 0.129348 0.0238026 0.0009651 0.000287 0.000149 0.000189 0.000177 0.0000177 0.0000251 0.000180 0.000170 1988 10 1 47435 0.009358 0.129552 0.0229221 0.0008032 0.000136 0.000108 0.000189 0.000178 0.0000176 0.0000250 0.000181 0.000170 1988 10 2 47436 0.004829 0.129355 0.0221545 0.0007714 0.000213 0.000085 0.000191 0.000180 0.0000176 0.0000249 0.000182 0.000172 1988 10 3 47437 0.002158 0.128603 0.0213700 0.0008551 0.000290 0.000063 0.000191 0.000181 0.0000176 0.0000249 0.000183 0.000173 1988 10 4 47438 -0.000875 0.128160 0.0204543 0.0010223 0.000367 0.000041 0.000192 0.000182 0.0000176 0.0000249 0.000184 0.000174 1988 10 5 47439 -0.004678 0.128946 0.0193301 0.0012338 0.000444 0.000019 0.000193 0.000184 0.0000176 0.0000249 0.000185 0.000175 1988 10 6 47440 -0.006060 0.128231 0.0179685 0.0014502 0.000245 0.000180 0.000194 0.000185 0.0000176 0.0000249 0.000185 0.000175 1988 10 7 47441 -0.008018 0.128735 0.0163826 0.0016386 0.000014 0.000323 0.000195 0.000187 0.0000175 0.0000248 0.000186 0.000176 1988 10 8 47442 -0.010609 0.129377 0.0146343 0.0017786 0.000222 -0.000033 0.000195 0.000187 0.0000174 0.0000246 0.000187 0.000176 1988 10 9 47443 -0.013473 0.130044 0.0128380 0.0018631 0.000385 -0.000296 0.000195 0.000187 0.0000173 0.0000244 0.000188 0.000177 1988 10 10 47444 -0.017380 0.133214 0.0110462 0.0018896 0.000329 -0.000109 0.000195 0.000186 0.0000171 0.0000243 0.000188 0.000177 1988 10 11 47445 -0.021235 0.134179 0.0091961 0.0018482 0.000354 0.000026 0.000194 0.000185 0.0000171 0.0000242 0.000189 0.000179 1988 10 12 47446 -0.024244 0.133961 0.0073381 0.0017267 0.000408 0.000142 0.000194 0.000185 0.0000171 0.0000242 0.000190 0.000182 1988 10 13 47447 -0.028234 0.135234 0.0056110 0.0015322 0.000462 0.000259 0.000193 0.000184 0.0000172 0.0000243 0.000191 0.000185 1988 10 14 47448 -0.032522 0.136209 0.0041425 0.0013060 0.000516 0.000376 0.000194 0.000183 0.0000172 0.0000242 0.000191 0.000188 1988 10 15 47449 -0.035137 0.135914 0.0029990 0.0011148 0.000922 0.000109 0.000193 0.000182 0.0000171 0.0000241 0.000192 0.000190 1988 10 16 47450 -0.041999 0.137066 0.0021771 0.0010189 0.000659 -0.000148 0.000193 0.000180 0.0000169 0.0000238 0.000192 0.000190 1988 10 17 47451 -0.046318 0.139006 0.0010279 0.0010408 0.000239 -0.000341 0.000193 0.000178 0.0000166 0.0000234 0.000192 0.000190 1988 10 18 47452 -0.046480 0.137373 -0.0002423 0.0011762 0.000237 -0.000269 0.000191 0.000175 0.0000162 0.0000229 0.000192 0.000189 1988 10 19 47453 -0.051310 0.137628 -0.0014573 0.0014192 0.000236 -0.000198 0.000189 0.000172 0.0000158 0.0000226 0.000191 0.000188 1988 10 20 47454 -0.052927 0.140161 -0.0029212 0.0017430 0.001645 0.000521 0.000188 0.000169 0.0000158 0.0000223 0.000191 0.000189 1988 10 21 47455 -0.053403 0.139934 -0.0047631 0.0020735 0.001610 0.000449 0.000185 0.000166 0.0000157 0.0000222 0.000191 0.000190 1988 10 22 47456 -0.057278 0.141274 -0.0071531 0.0023070 0.000948 -0.000024 0.000183 0.000162 0.0000156 0.0000220 0.000191 0.000191 1988 10 23 47457 -0.059159 0.143673 -0.0096344 0.0023686 0.000463 -0.000309 0.000180 0.000158 0.0000154 0.0000217 0.000189 0.000189 1988 10 24 47458 -0.060577 0.143186 -0.0118218 0.0022556 0.000404 -0.000286 0.000176 0.000154 0.0000151 0.0000213 0.000188 0.000187 1988 10 25 47459 -0.064077 0.144099 -0.0137608 0.0020175 0.000346 -0.000262 0.000173 0.000149 0.0000148 0.0000209 0.000186 0.000185 1988 10 26 47460 -0.068100 0.147058 -0.0155878 0.0017117 -0.000454 0.000166 0.000170 0.000145 0.0000145 0.0000204 0.000184 0.000183 1988 10 27 47461 -0.071063 0.148007 -0.0174279 0.0013897 -0.000967 0.000582 0.000166 0.000141 0.0000141 0.0000199 0.000182 0.000179 1988 10 28 47462 -0.074772 0.149261 -0.0188267 0.0011161 -0.000081 0.000262 0.000163 0.000137 0.0000136 0.0000193 0.000180 0.000176 1988 10 29 47463 -0.077993 0.150891 -0.0196819 0.0009656 0.000805 -0.000057 0.000160 0.000133 0.0000131 0.0000186 0.000177 0.000173 1988 10 30 47464 -0.080919 0.151524 -0.0204466 0.0009764 0.000702 -0.000092 0.000157 0.000129 0.0000127 0.0000180 0.000175 0.000169 1988 10 31 47465 -0.083037 0.152480 -0.0215450 0.0011217 0.000820 0.000458 0.000156 0.000128 0.0000123 0.0000174 0.000174 0.000167 1988 11 1 47466 -0.084250 0.153800 -0.0228140 0.0013393 0.001203 0.000644 0.000156 0.000128 0.0000119 0.0000168 0.000173 0.000165 1988 11 2 47467 -0.087383 0.156650 -0.0243072 0.0015711 0.000730 0.000148 0.000154 0.000128 0.0000114 0.0000161 0.000170 0.000162 1988 11 3 47468 -0.090410 0.158921 -0.0260263 0.0017769 0.000484 -0.000108 0.000153 0.000127 0.0000109 0.0000154 0.000169 0.000159 1988 11 4 47469 -0.095173 0.160512 -0.0278521 0.0019344 0.000713 -0.000044 0.000152 0.000126 0.0000104 0.0000147 0.000169 0.000158 1988 11 5 47470 -0.097890 0.162388 -0.0297830 0.0020292 0.000800 0.000482 0.000150 0.000125 0.0000099 0.0000140 0.000168 0.000156 1988 11 6 47471 -0.098310 0.163163 -0.0318600 0.0020478 0.000599 0.000373 0.000149 0.000124 0.0000094 0.0000133 0.000168 0.000153 1988 11 7 47472 -0.101815 0.164787 -0.0339600 0.0019854 0.000272 -0.000137 0.000147 0.000122 0.0000089 0.0000127 0.000167 0.000151 1988 11 8 47473 -0.104556 0.167264 -0.0358659 0.0018571 0.000299 -0.000216 0.000146 0.000121 0.0000085 0.0000121 0.000167 0.000150 1988 11 9 47474 -0.107774 0.170342 -0.0375605 0.0016916 0.000446 -0.000152 0.000144 0.000119 0.0000081 0.0000115 0.000167 0.000150 1988 11 10 47475 -0.110535 0.172574 -0.0391428 0.0015162 0.000496 -0.000026 0.000143 0.000117 0.0000077 0.0000109 0.000167 0.000148 1988 11 11 47476 -0.113061 0.173591 -0.0406260 0.0013545 0.000578 -0.000169 0.000140 0.000115 0.0000073 0.0000105 0.000166 0.000146 1988 11 12 47477 -0.115959 0.175611 -0.0419650 0.0012371 0.000632 -0.000299 0.000140 0.000115 0.0000071 0.0000103 0.000166 0.000145 1988 11 13 47478 -0.116974 0.177713 -0.0431788 0.0012028 0.000614 -0.000240 0.000144 0.000118 0.0000073 0.0000103 0.000166 0.000146 1988 11 14 47479 -0.119410 0.180075 -0.0443842 0.0012842 0.000596 -0.000182 0.000147 0.000121 0.0000075 0.0000106 0.000165 0.000147 1988 11 15 47480 -0.120972 0.182018 -0.0457322 0.0014863 0.000628 -0.000142 0.000149 0.000123 0.0000076 0.0000108 0.000165 0.000147 1988 11 16 47481 -0.121929 0.184007 -0.0473462 0.0017771 0.000676 -0.000108 0.000152 0.000126 0.0000078 0.0000110 0.000164 0.000148 1988 11 17 47482 -0.123309 0.186908 -0.0492856 0.0020922 0.000724 -0.000074 0.000154 0.000128 0.0000079 0.0000112 0.000163 0.000148 1988 11 18 47483 -0.124544 0.189311 -0.0515282 0.0023521 0.000773 -0.000040 0.000156 0.000131 0.0000081 0.0000115 0.000163 0.000148 1988 11 19 47484 -0.126435 0.192146 -0.0539717 0.0024857 0.000821 -0.000006 0.000159 0.000133 0.0000083 0.0000118 0.000162 0.000148 1988 11 20 47485 -0.127484 0.195363 -0.0564603 0.0024528 0.000767 -0.000054 0.000161 0.000134 0.0000085 0.0000121 0.000161 0.000148 1988 11 21 47486 -0.129093 0.198539 -0.0588281 0.0022598 0.000679 -0.000130 0.000162 0.000136 0.0000087 0.0000124 0.000161 0.000148 1988 11 22 47487 -0.130548 0.201336 -0.0609422 0.0019592 0.000592 -0.000205 0.000164 0.000137 0.0000090 0.0000127 0.000161 0.000149 1988 11 23 47488 -0.133540 0.203298 -0.0627364 0.0016335 0.000504 -0.000280 0.000164 0.000138 0.0000092 0.0000131 0.000161 0.000149 1988 11 24 47489 -0.137144 0.205401 -0.0642267 0.0013657 0.000417 -0.000355 0.000165 0.000138 0.0000095 0.0000134 0.000161 0.000149 1988 11 25 47490 -0.138824 0.208157 -0.0655018 0.0012118 0.000344 -0.000344 0.000165 0.000138 0.0000097 0.0000137 0.000160 0.000148 1988 11 26 47491 -0.141209 0.211361 -0.0666883 0.0011871 0.000277 -0.000303 0.000165 0.000138 0.0000099 0.0000140 0.000159 0.000147 1988 11 27 47492 -0.143032 0.214577 -0.0679097 0.0012703 0.000210 -0.000261 0.000164 0.000137 0.0000101 0.0000143 0.000158 0.000145 1988 11 28 47493 -0.145007 0.217549 -0.0692540 0.0014207 0.000142 -0.000220 0.000163 0.000136 0.0000103 0.0000146 0.000157 0.000144 1988 11 29 47494 -0.146682 0.220483 -0.0707626 0.0015953 0.000075 -0.000179 0.000162 0.000135 0.0000105 0.0000149 0.000156 0.000143 1988 11 30 47495 -0.148502 0.223505 -0.0724378 0.0017581 0.000215 0.000019 0.000160 0.000134 0.0000107 0.0000152 0.000156 0.000141 1988 12 1 47496 -0.151074 0.226053 -0.0742623 0.0018808 0.000374 0.000078 0.000160 0.000133 0.0000110 0.0000155 0.000157 0.000141 1988 12 2 47497 -0.151853 0.229312 -0.0761903 0.0019427 0.000511 0.000041 0.000160 0.000133 0.0000113 0.0000160 0.000158 0.000142 1988 12 3 47498 -0.154781 0.231792 -0.0781494 0.0019331 0.000647 0.000004 0.000160 0.000133 0.0000116 0.0000164 0.000160 0.000143 1988 12 4 47499 -0.157296 0.232906 -0.0800574 0.0018542 0.000783 -0.000033 0.000159 0.000131 0.0000120 0.0000169 0.000161 0.000144 1988 12 5 47500 -0.156348 0.236807 -0.0818408 0.0017200 0.000926 0.000601 0.000158 0.000130 0.0000122 0.0000173 0.000163 0.000144 1988 12 6 47501 -0.157120 0.240125 -0.0834566 0.0015519 0.001071 0.001463 0.000156 0.000128 0.0000125 0.0000177 0.000164 0.000143 1988 12 7 47502 -0.158158 0.242051 -0.0848955 0.0013729 0.001216 0.002326 0.000154 0.000126 0.0000128 0.0000181 0.000165 0.000143 1988 12 8 47503 -0.158709 0.245968 -0.0861736 0.0012061 0.001311 0.002907 0.000151 0.000123 0.0000131 0.0000185 0.000167 0.000143 1988 12 9 47504 -0.161186 0.249012 -0.0873242 0.0010769 0.000825 0.000220 0.000149 0.000121 0.0000134 0.0000189 0.000168 0.000143 1988 12 10 47505 -0.162819 0.251671 -0.0883949 0.0010126 0.000494 -0.000360 0.000146 0.000117 0.0000136 0.0000193 0.000170 0.000142 1988 12 11 47506 -0.163120 0.254989 -0.0894449 0.0010372 0.000218 -0.000183 0.000143 0.000114 0.0000139 0.0000198 0.000173 0.000142 1988 12 12 47507 -0.163919 0.257736 -0.0905486 0.0011597 0.000274 -0.000213 0.000141 0.000113 0.0000143 0.0000203 0.000175 0.000145 1988 12 13 47508 -0.164406 0.260321 -0.0917788 0.0013631 0.000417 -0.000298 0.000141 0.000114 0.0000148 0.0000209 0.000178 0.000148 1988 12 14 47509 -0.165537 0.263559 -0.0931877 0.0015995 0.000560 -0.000382 0.000140 0.000114 0.0000152 0.0000215 0.000181 0.000152 1988 12 15 47510 -0.167308 0.266656 -0.0948140 0.0017974 0.000562 -0.000292 0.000140 0.000115 0.0000156 0.0000221 0.000184 0.000155 1988 12 16 47511 -0.167721 0.268748 -0.0968877 0.0018852 0.000512 -0.000146 0.000140 0.000116 0.0000161 0.0000227 0.000186 0.000159 1988 12 17 47512 -0.166968 0.271924 -0.0987664 0.0018325 0.000190 -0.000196 0.000141 0.000118 0.0000164 0.0000232 0.000189 0.000164 1988 12 18 47513 -0.166633 0.275139 -0.1002990 0.0016609 -0.000088 -0.000378 0.000141 0.000119 0.0000167 0.0000236 0.000191 0.000168 1988 12 19 47514 -0.166827 0.277328 -0.1019324 0.0014098 0.000276 -0.000398 0.000141 0.000120 0.0000169 0.0000239 0.000193 0.000171 1988 12 20 47515 -0.166157 0.280600 -0.1032242 0.0011268 0.000466 0.000008 0.000141 0.000121 0.0000171 0.0000240 0.000195 0.000173 1988 12 21 47516 -0.166222 0.284659 -0.1042029 0.0008700 0.000284 -0.000002 0.000142 0.000122 0.0000171 0.0000241 0.000196 0.000175 1988 12 22 47517 -0.166784 0.287913 -0.1049932 0.0006903 0.000034 -0.000191 0.000143 0.000123 0.0000170 0.0000243 0.000197 0.000176 1988 12 23 47518 -0.166389 0.289896 -0.1056480 0.0006163 0.000302 -0.000145 0.000143 0.000123 0.0000173 0.0000245 0.000198 0.000178 1988 12 24 47519 -0.166556 0.292534 -0.1062720 0.0006511 0.000450 -0.000167 0.000143 0.000124 0.0000176 0.0000249 0.000200 0.000180 1988 12 25 47520 -0.165791 0.295537 -0.1069694 0.0007752 0.000463 -0.000263 0.000145 0.000125 0.0000178 0.0000252 0.000202 0.000183 1988 12 26 47521 -0.163975 0.297595 -0.1078189 0.0009562 0.000477 -0.000359 0.000146 0.000125 0.0000181 0.0000257 0.000203 0.000185 1988 12 27 47522 -0.163134 0.301046 -0.1088641 0.0011570 0.000490 -0.000455 0.000146 0.000126 0.0000185 0.0000261 0.000205 0.000187 1988 12 28 47523 -0.163134 0.305539 -0.1101119 0.0013425 0.000504 -0.000552 0.000146 0.000125 0.0000188 0.0000266 0.000208 0.000191 1988 12 29 47524 -0.162827 0.308857 -0.1115349 0.0014821 0.000517 -0.000648 0.000145 0.000125 0.0000192 0.0000271 0.000210 0.000194 1988 12 30 47525 -0.161619 0.311606 -0.1130744 0.0015537 0.000510 -0.000594 0.000145 0.000124 0.0000196 0.0000277 0.000212 0.000196 1988 12 31 47526 -0.161120 0.313432 -0.1146438 0.0015464 0.000497 -0.000492 0.000145 0.000123 0.0000199 0.0000286 0.000214 0.000198 1989 1 1 47527 -0.160407 0.314051 -0.1161499 0.0014182 0.000483 -0.000393 0.000115 0.000098 0.0000164 0.0000232 0.000194 0.000196 1989 1 2 47528 -0.159586 0.316470 -0.1174924 0.0012537 0.000469 -0.000292 0.000115 0.000097 0.0000166 0.0000235 0.000196 0.000198 1989 1 3 47529 -0.160169 0.320638 -0.1186357 0.0010734 0.000455 -0.000191 0.000114 0.000096 0.0000169 0.0000237 0.000197 0.000199 1989 1 4 47530 -0.158624 0.323526 -0.1195877 0.0009155 0.001232 0.000985 0.000113 0.000094 0.0000169 0.0000239 0.000198 0.000200 1989 1 5 47531 -0.155747 0.326008 -0.1204134 0.0008096 0.002280 0.002529 0.000112 0.000093 0.0000170 0.0000240 0.000199 0.000201 1989 1 6 47532 -0.155216 0.328130 -0.1212064 0.0007743 0.003170 0.003832 0.000111 0.000091 0.0000171 0.0000240 0.000200 0.000202 1989 1 7 47533 -0.154289 0.329037 -0.1220489 0.0008201 0.002082 0.002115 0.000109 0.000089 0.0000169 0.0000239 0.000199 0.000200 1989 1 8 47534 -0.153123 0.331610 -0.1229810 0.0009504 0.000994 0.000397 0.000107 0.000087 0.0000168 0.0000237 0.000199 0.000198 1989 1 9 47535 -0.150999 0.335657 -0.1240381 0.0011560 0.000659 -0.000051 0.000105 0.000085 0.0000166 0.0000234 0.000198 0.000196 1989 1 10 47536 -0.149317 0.338605 -0.1252816 0.0014057 0.000564 -0.000096 0.000103 0.000083 0.0000163 0.0000231 0.000197 0.000193 1989 1 11 47537 -0.148980 0.341358 -0.1267599 0.0016438 0.000469 -0.000141 0.000101 0.000080 0.0000161 0.0000227 0.000196 0.000190 1989 1 12 47538 -0.147945 0.343996 -0.1284617 0.0018039 0.000374 -0.000186 0.000100 0.000078 0.0000159 0.0000224 0.000195 0.000188 1989 1 13 47539 -0.147850 0.346174 -0.1303032 0.0018344 0.000279 -0.000230 0.000098 0.000076 0.0000157 0.0000221 0.000195 0.000186 1989 1 14 47540 -0.147179 0.348485 -0.1321415 0.0017226 0.000215 -0.000276 0.000098 0.000077 0.0000154 0.0000218 0.000194 0.000184 1989 1 15 47541 -0.146700 0.350963 -0.1337755 0.0015025 0.000304 -0.000328 0.000099 0.000078 0.0000152 0.0000215 0.000194 0.000184 1989 1 16 47542 -0.145997 0.352976 -0.1351228 0.0012393 0.000393 -0.000379 0.000099 0.000080 0.0000150 0.0000213 0.000194 0.000184 1989 1 17 47543 -0.144958 0.355154 -0.1362067 0.0009995 0.000482 -0.000430 0.000100 0.000082 0.0000149 0.0000210 0.000193 0.000184 1989 1 18 47544 -0.144991 0.357867 -0.1371101 0.0008284 0.000571 -0.000482 0.000101 0.000083 0.0000147 0.0000208 0.000193 0.000184 1989 1 19 47545 -0.142637 0.359825 -0.1379318 0.0007468 -0.000293 -0.000124 0.000102 0.000085 0.0000145 0.0000206 0.000193 0.000184 1989 1 20 47546 -0.140442 0.362369 -0.1387269 0.0007614 -0.001490 0.000376 0.000104 0.000087 0.0000143 0.0000202 0.000192 0.000184 1989 1 21 47547 -0.139891 0.365043 -0.1395377 0.0008747 -0.000662 -0.000075 0.000105 0.000089 0.0000141 0.0000198 0.000191 0.000183 1989 1 22 47548 -0.138209 0.367380 -0.1404691 0.0010814 -0.000206 -0.000170 0.000106 0.000090 0.0000137 0.0000194 0.000190 0.000180 1989 1 23 47549 -0.136885 0.369546 -0.1416349 0.0013557 0.000099 -0.000158 0.000107 0.000092 0.0000134 0.0000191 0.000188 0.000178 1989 1 24 47550 -0.136772 0.371187 -0.1430787 0.0016437 0.000146 -0.000276 0.000109 0.000094 0.0000133 0.0000189 0.000187 0.000177 1989 1 25 47551 -0.134668 0.372985 -0.1446083 0.0018665 0.000451 -0.000095 0.000110 0.000096 0.0000134 0.0000189 0.000187 0.000178 1989 1 26 47552 -0.131402 0.374787 -0.1470074 0.0019416 0.000893 0.000219 0.000111 0.000097 0.0000133 0.0000188 0.000188 0.000179 1989 1 27 47553 -0.130630 0.378405 -0.1494386 0.0018666 0.000800 -0.000028 0.000111 0.000098 0.0000132 0.0000186 0.000188 0.000179 1989 1 28 47554 -0.130536 0.380218 -0.1504358 0.0017561 0.000598 -0.000390 0.000110 0.000098 0.0000130 0.0000184 0.000187 0.000178 1989 1 29 47555 -0.130461 0.380481 -0.1515077 0.0016749 -0.000268 -0.000203 0.000111 0.000099 0.0000129 0.0000182 0.000187 0.000179 1989 1 30 47556 -0.130134 0.383313 -0.1540102 0.0015290 -0.000571 0.000544 0.000111 0.000099 0.0000128 0.0000180 0.000187 0.000178 1989 1 31 47557 -0.128523 0.385291 -0.1558630 0.0012556 -0.000493 0.000546 0.000111 0.000099 0.0000125 0.0000177 0.000186 0.000176 1989 2 1 47558 -0.127667 0.386957 -0.1566115 0.0009655 -0.000365 0.000384 0.000112 0.000098 0.0000123 0.0000173 0.000184 0.000174 1989 2 2 47559 -0.126912 0.389313 -0.1570099 0.0008151 -0.000237 0.000222 0.000112 0.000098 0.0000120 0.0000170 0.000183 0.000172 1989 2 3 47560 -0.123935 0.391933 -0.1578861 0.0008550 0.000107 -0.000181 0.000113 0.000097 0.0000118 0.0000167 0.000182 0.000170 1989 2 4 47561 -0.121356 0.394432 -0.1590632 0.0010392 0.000489 -0.000286 0.000114 0.000097 0.0000116 0.0000164 0.000181 0.000169 1989 2 5 47562 -0.119898 0.397125 -0.1603227 0.0013091 0.000855 -0.000223 0.000114 0.000097 0.0000114 0.0000161 0.000180 0.000167 1989 2 6 47563 -0.117331 0.400437 -0.1617541 0.0016210 0.000883 -0.000113 0.000115 0.000096 0.0000112 0.0000158 0.000178 0.000164 1989 2 7 47564 -0.115769 0.403262 -0.1634515 0.0019257 0.000807 0.000012 0.000115 0.000096 0.0000109 0.0000156 0.000176 0.000160 1989 2 8 47565 -0.114599 0.406156 -0.1654731 0.0021602 0.000411 -0.000294 0.000116 0.000095 0.0000109 0.0000154 0.000175 0.000158 1989 2 9 47566 -0.112155 0.408323 -0.1677917 0.0022724 0.000371 -0.000137 0.000117 0.000095 0.0000108 0.0000152 0.000174 0.000157 1989 2 10 47567 -0.109683 0.410293 -0.1701241 0.0022574 0.000540 0.000293 0.000118 0.000095 0.0000107 0.0000151 0.000174 0.000156 1989 2 11 47568 -0.107673 0.411520 -0.1721119 0.0021516 0.000708 0.000723 0.000120 0.000095 0.0000106 0.0000149 0.000173 0.000155 1989 2 12 47569 -0.105884 0.412621 -0.1737467 0.0019681 0.000515 -0.000045 0.000120 0.000094 0.0000104 0.0000149 0.000173 0.000154 1989 2 13 47570 -0.103730 0.414120 -0.1760617 0.0016523 -0.000254 -0.001034 0.000121 0.000093 0.0000104 0.0000147 0.000172 0.000153 1989 2 14 47571 -0.100917 0.415305 -0.1780407 0.0011852 -0.000224 -0.001304 0.000121 0.000093 0.0000103 0.0000146 0.000172 0.000152 1989 2 15 47572 -0.097905 0.417603 -0.1789667 0.0007000 -0.000007 -0.001429 0.000121 0.000092 0.0000102 0.0000145 0.000171 0.000150 1989 2 16 47573 -0.095026 0.419771 -0.1790789 0.0004093 0.000225 -0.001475 0.000122 0.000090 0.0000101 0.0000143 0.000170 0.000149 1989 2 17 47574 -0.091983 0.422261 -0.1790255 0.0004318 0.000611 -0.000636 0.000122 0.000089 0.0000100 0.0000142 0.000169 0.000146 1989 2 18 47575 -0.090771 0.424808 -0.1796633 0.0007046 0.000623 -0.000184 0.000121 0.000088 0.0000099 0.0000140 0.000168 0.000145 1989 2 19 47576 -0.089090 0.427384 -0.1808495 0.0010587 0.000350 -0.000347 0.000121 0.000086 0.0000098 0.0000138 0.000166 0.000143 1989 2 20 47577 -0.086293 0.428866 -0.1821695 0.0013578 0.000242 -0.000459 0.000121 0.000086 0.0000096 0.0000136 0.000165 0.000141 1989 2 21 47578 -0.085294 0.429451 -0.1835695 0.0015506 0.000287 -0.000398 0.000122 0.000088 0.0000095 0.0000135 0.000164 0.000140 1989 2 22 47579 -0.083281 0.432659 -0.1851468 0.0016402 0.000222 -0.000170 0.000123 0.000089 0.0000094 0.0000133 0.000164 0.000140 1989 2 23 47580 -0.080460 0.435055 -0.1867854 0.0016480 0.000181 -0.000056 0.000124 0.000090 0.0000094 0.0000133 0.000163 0.000140 1989 2 24 47581 -0.076955 0.436350 -0.1883874 0.0015983 0.000155 0.000007 0.000124 0.000091 0.0000094 0.0000133 0.000163 0.000140 1989 2 25 47582 -0.073271 0.438390 -0.1899243 0.0015105 0.000129 0.000070 0.000124 0.000091 0.0000094 0.0000133 0.000163 0.000140 1989 2 26 47583 -0.070055 0.440386 -0.1913769 0.0013957 0.000104 0.000132 0.000123 0.000091 0.0000094 0.0000133 0.000163 0.000140 1989 2 27 47584 -0.066640 0.443055 -0.1927273 0.0012613 0.000078 0.000195 0.000122 0.000091 0.0000095 0.0000133 0.000163 0.000140 1989 2 28 47585 -0.063853 0.446032 -0.1939536 0.0011215 0.000339 -0.000380 0.000121 0.000090 0.0000094 0.0000133 0.000162 0.000139 1989 3 1 47586 -0.060969 0.448586 -0.1950159 0.0010055 0.000422 -0.000573 0.000120 0.000090 0.0000094 0.0000133 0.000162 0.000139 1989 3 2 47587 -0.058987 0.450229 -0.1959646 0.0009557 0.000428 -0.000598 0.000119 0.000089 0.0000094 0.0000133 0.000162 0.000138 1989 3 3 47588 -0.056820 0.451685 -0.1969326 0.0010137 0.000434 -0.000623 0.000118 0.000088 0.0000094 0.0000132 0.000162 0.000138 1989 3 4 47589 -0.055015 0.453241 -0.1980573 0.0012034 0.000440 -0.000647 0.000117 0.000087 0.0000092 0.0000131 0.000162 0.000137 1989 3 5 47590 -0.053305 0.454673 -0.1994109 0.0015164 -0.000154 -0.000428 0.000115 0.000086 0.0000092 0.0000130 0.000162 0.000138 1989 3 6 47591 -0.050911 0.455837 -0.2010968 0.0019025 -0.000967 -0.000317 0.000114 0.000085 0.0000092 0.0000130 0.000162 0.000138 1989 3 7 47592 -0.048850 0.457027 -0.2031661 0.0022723 -0.001794 -0.000290 0.000114 0.000086 0.0000091 0.0000129 0.000162 0.000138 1989 3 8 47593 -0.045912 0.458288 -0.2055596 0.0025237 -0.002355 -0.000263 0.000114 0.000086 0.0000091 0.0000128 0.000163 0.000138 1989 3 9 47594 -0.044118 0.459513 -0.2081265 0.0025822 -0.000454 -0.000235 0.000114 0.000086 0.0000090 0.0000128 0.000162 0.000138 1989 3 10 47595 -0.041550 0.460771 -0.2106651 0.0024316 0.000112 -0.000245 0.000115 0.000086 0.0000090 0.0000127 0.000162 0.000138 1989 3 11 47596 -0.037930 0.461659 -0.2129810 0.0021200 0.000237 -0.000266 0.000116 0.000087 0.0000090 0.0000127 0.000162 0.000139 1989 3 12 47597 -0.034849 0.462800 -0.2149447 0.0017390 0.000361 -0.000287 0.000116 0.000087 0.0000090 0.0000127 0.000162 0.000140 1989 3 13 47598 -0.031250 0.463983 -0.2165228 0.0013890 0.000485 -0.000308 0.000117 0.000087 0.0000090 0.0000127 0.000161 0.000141 1989 3 14 47599 -0.028334 0.465195 -0.2177772 0.0011486 0.000610 -0.000329 0.000117 0.000087 0.0000090 0.0000128 0.000161 0.000142 1989 3 15 47600 -0.025789 0.466512 -0.2188390 0.0010587 0.001012 -0.000514 0.000118 0.000087 0.0000091 0.0000129 0.000162 0.000143 1989 3 16 47601 -0.023012 0.468097 -0.2198757 0.0011192 0.001509 -0.000755 0.000119 0.000088 0.0000092 0.0000131 0.000162 0.000145 1989 3 17 47602 -0.018734 0.469906 -0.2210448 0.0012954 0.001906 -0.000951 0.000120 0.000088 0.0000094 0.0000133 0.000163 0.000147 1989 3 18 47603 -0.015858 0.471447 -0.2224516 0.0015289 0.001212 -0.000657 0.000121 0.000087 0.0000095 0.0000135 0.000162 0.000146 1989 3 19 47604 -0.014483 0.473114 -0.2241276 0.0017545 0.000519 -0.000363 0.000121 0.000087 0.0000097 0.0000137 0.000162 0.000146 1989 3 20 47605 -0.011166 0.473948 -0.2260257 0.0019192 0.000324 -0.000277 0.000120 0.000087 0.0000098 0.0000139 0.000162 0.000147 1989 3 21 47606 -0.007759 0.474717 -0.2280172 0.0019975 0.000327 -0.000269 0.000120 0.000088 0.0000099 0.0000140 0.000162 0.000147 1989 3 22 47607 -0.004744 0.475839 -0.2300050 0.0019930 0.000330 -0.000261 0.000120 0.000089 0.0000100 0.0000142 0.000162 0.000148 1989 3 23 47608 -0.001843 0.476214 -0.2319334 0.0019260 0.000333 -0.000253 0.000120 0.000089 0.0000101 0.0000143 0.000162 0.000149 1989 3 24 47609 0.001296 0.477184 -0.2337752 0.0018172 0.000336 -0.000245 0.000120 0.000090 0.0000102 0.0000145 0.000162 0.000149 1989 3 25 47610 0.004256 0.478447 -0.2355169 0.0016792 0.000356 -0.000416 0.000120 0.000090 0.0000104 0.0000148 0.000163 0.000151 1989 3 26 47611 0.008062 0.478656 -0.2371362 0.0015189 0.000382 -0.000645 0.000120 0.000090 0.0000107 0.0000152 0.000164 0.000152 1989 3 27 47612 0.011832 0.479286 -0.2386043 0.0013469 0.000323 -0.000734 0.000120 0.000091 0.0000110 0.0000155 0.000165 0.000153 1989 3 28 47613 0.013967 0.480474 -0.2398862 0.0011862 0.000155 -0.000642 0.000120 0.000091 0.0000112 0.0000160 0.000165 0.000154 1989 3 29 47614 0.017245 0.480312 -0.2409781 0.0010722 0.000140 -0.000272 0.000120 0.000092 0.0000116 0.0000164 0.000166 0.000155 1989 3 30 47615 0.019776 0.480061 -0.2420260 0.0010411 0.000278 -0.000099 0.000121 0.000092 0.0000120 0.0000169 0.000166 0.000157 1989 3 31 47616 0.022378 0.480779 -0.2431083 0.0011193 0.000211 -0.000107 0.000121 0.000092 0.0000123 0.0000175 0.000167 0.000157 1989 4 1 47617 0.026756 0.480377 -0.2443121 0.0013131 0.000039 -0.000157 0.000121 0.000092 0.0000127 0.0000179 0.000167 0.000157 1989 4 2 47618 0.030050 0.480366 -0.2457567 0.0015958 0.000007 -0.000100 0.000121 0.000092 0.0000130 0.0000183 0.000167 0.000157 1989 4 3 47619 0.032838 0.481820 -0.2475023 0.0019023 0.000028 -0.000002 0.000120 0.000092 0.0000132 0.0000187 0.000168 0.000158 1989 4 4 47620 0.036221 0.481512 -0.2495241 0.0021434 0.000524 0.000438 0.000120 0.000091 0.0000135 0.0000190 0.000168 0.000158 1989 4 5 47621 0.039937 0.481227 -0.2517215 0.0022382 0.000721 0.000471 0.000119 0.000090 0.0000137 0.0000193 0.000167 0.000158 1989 4 6 47622 0.043720 0.481850 -0.2539301 0.0021503 0.000682 0.000237 0.000117 0.000090 0.0000137 0.0000195 0.000167 0.000159 1989 4 7 47623 0.048010 0.481545 -0.2559735 0.0019070 0.000644 0.000004 0.000116 0.000088 0.0000139 0.0000196 0.000167 0.000159 1989 4 8 47624 0.050958 0.482033 -0.2577296 0.0015891 0.000606 -0.000230 0.000114 0.000087 0.0000140 0.0000197 0.000166 0.000160 1989 4 9 47625 0.053224 0.482446 -0.2591697 0.0012955 0.000328 -0.000433 0.000113 0.000086 0.0000140 0.0000198 0.000166 0.000159 1989 4 10 47626 0.056808 0.482049 -0.2603589 0.0011030 -0.000021 -0.000623 0.000111 0.000085 0.0000140 0.0000198 0.000165 0.000159 1989 4 11 47627 0.059328 0.482134 -0.2614193 0.0010431 0.000058 -0.000530 0.000110 0.000085 0.0000140 0.0000198 0.000164 0.000158 1989 4 12 47628 0.061999 0.482307 -0.2624817 0.0011035 0.000137 -0.000438 0.000110 0.000084 0.0000140 0.0000198 0.000164 0.000157 1989 4 13 47629 0.064669 0.482153 -0.2636500 0.0012475 0.000216 -0.000345 0.000108 0.000083 0.0000140 0.0000198 0.000163 0.000156 1989 4 14 47630 0.067439 0.482127 -0.2649873 0.0014339 0.000241 -0.000287 0.000108 0.000083 0.0000140 0.0000198 0.000164 0.000156 1989 4 15 47631 0.071217 0.481862 -0.2665191 0.0016285 0.000250 -0.000240 0.000108 0.000083 0.0000140 0.0000198 0.000165 0.000156 1989 4 16 47632 0.073855 0.481530 -0.2682411 0.0018055 0.000258 -0.000192 0.000107 0.000083 0.0000140 0.0000197 0.000166 0.000156 1989 4 17 47633 0.077170 0.481427 -0.2701255 0.0019456 0.000266 -0.000145 0.000107 0.000083 0.0000139 0.0000197 0.000167 0.000156 1989 4 18 47634 0.080310 0.481651 -0.2721272 0.0020359 0.000275 -0.000098 0.000107 0.000083 0.0000139 0.0000196 0.000168 0.000156 1989 4 19 47635 0.082974 0.481886 -0.2741854 0.0020720 0.000248 -0.000094 0.000107 0.000083 0.0000138 0.0000194 0.000168 0.000155 1989 4 20 47636 0.086597 0.481393 -0.2762005 0.0020564 0.000121 -0.000341 0.000108 0.000083 0.0000136 0.0000193 0.000168 0.000154 1989 4 21 47637 0.089266 0.481853 -0.2782726 0.0019936 -0.000040 -0.000678 0.000109 0.000084 0.0000135 0.0000193 0.000168 0.000153 1989 4 22 47638 0.090831 0.481568 -0.2801973 0.0018924 0.000032 -0.000676 0.000110 0.000085 0.0000137 0.0000195 0.000168 0.000153 1989 4 23 47639 0.091920 0.481437 -0.2820341 0.0017691 0.000338 -0.000517 0.000111 0.000085 0.0000141 0.0000199 0.000169 0.000153 1989 4 24 47640 0.094454 0.481013 -0.2837736 0.0016453 0.000219 -0.000480 0.000112 0.000087 0.0000145 0.0000205 0.000170 0.000154 1989 4 25 47641 0.096847 0.480141 -0.2853817 0.0015510 -0.000046 -0.000489 0.000113 0.000089 0.0000149 0.0000211 0.000170 0.000154 1989 4 26 47642 0.096482 0.481588 -0.2869051 0.0015213 -0.000585 -0.000209 0.000114 0.000090 0.0000153 0.0000216 0.000171 0.000154 1989 4 27 47643 0.097627 0.478923 -0.2883996 0.0015837 -0.000396 0.000168 0.000115 0.000092 0.0000156 0.0000220 0.000171 0.000154 1989 4 28 47644 0.101364 0.477568 -0.2900879 0.0017434 0.000226 0.000015 0.000115 0.000092 0.0000159 0.0000225 0.000171 0.000155 1989 4 29 47645 0.103680 0.478793 -0.2919521 0.0019781 0.000157 0.000035 0.000116 0.000094 0.0000162 0.0000229 0.000172 0.000156 1989 4 30 47646 0.105848 0.477104 -0.2940210 0.0022392 -0.000157 0.000148 0.000117 0.000095 0.0000165 0.0000234 0.000172 0.000157 1989 5 1 47647 0.107966 0.476612 -0.2963752 0.0024533 -0.000472 0.000262 0.000118 0.000096 0.0000168 0.0000238 0.000173 0.000158 1989 5 2 47648 0.108477 0.474989 -0.2989737 0.0025439 -0.000901 0.000038 0.000119 0.000098 0.0000171 0.0000242 0.000173 0.000159 1989 5 3 47649 0.111362 0.474476 -0.3015101 0.0024733 -0.000140 -0.000416 0.000119 0.000099 0.0000173 0.0000245 0.000173 0.000161 1989 5 4 47650 0.114446 0.474231 -0.3037890 0.0022628 0.000396 -0.000590 0.000120 0.000100 0.0000176 0.0000248 0.000173 0.000163 1989 5 5 47651 0.116854 0.472728 -0.3058181 0.0019731 0.000779 -0.000671 0.000120 0.000101 0.0000177 0.0000251 0.000173 0.000166 1989 5 6 47652 0.121289 0.471434 -0.3076888 0.0016733 0.001162 -0.000752 0.000119 0.000101 0.0000179 0.0000253 0.000173 0.000168 1989 5 7 47653 0.123630 0.469824 -0.3094335 0.0014293 -0.000078 -0.000211 0.000118 0.000101 0.0000180 0.0000254 0.000173 0.000169 1989 5 8 47654 0.126362 0.470041 -0.3107036 0.0013017 0.000006 -0.000064 0.000117 0.000101 0.0000180 0.0000254 0.000171 0.000170 1989 5 9 47655 0.130688 0.469795 -0.3118662 0.0013137 -0.000030 0.000042 0.000116 0.000100 0.0000180 0.0000254 0.000171 0.000170 1989 5 10 47656 0.132315 0.469320 -0.3131358 0.0014190 -0.000453 0.000196 0.000114 0.000099 0.0000180 0.0000254 0.000171 0.000171 1989 5 11 47657 0.134282 0.468032 -0.3147542 0.0015306 -0.000990 0.000361 0.000112 0.000099 0.0000180 0.0000254 0.000171 0.000172 1989 5 12 47658 0.137301 0.466847 -0.3167897 0.0015940 -0.001043 0.000479 0.000111 0.000098 0.0000180 0.0000253 0.000171 0.000173 1989 5 13 47659 0.139678 0.465899 -0.3178979 0.0016429 -0.000285 -0.000039 0.000109 0.000097 0.0000178 0.0000252 0.000170 0.000172 1989 5 14 47660 0.142158 0.464792 -0.3195238 0.0017200 0.000233 -0.000344 0.000108 0.000096 0.0000176 0.0000249 0.000169 0.000171 1989 5 15 47661 0.145095 0.464172 -0.3213792 0.0018030 0.000054 -0.000522 0.000107 0.000096 0.0000174 0.0000246 0.000169 0.000170 1989 5 16 47662 0.148102 0.461322 -0.3231026 0.0018453 -0.000416 -0.000696 0.000105 0.000095 0.0000171 0.0000242 0.000168 0.000168 1989 5 17 47663 0.149594 0.460711 -0.3252170 0.0018087 -0.000867 -0.000852 0.000104 0.000095 0.0000168 0.0000237 0.000167 0.000166 1989 5 18 47664 0.152189 0.459855 -0.3269214 0.0016973 -0.000199 -0.000720 0.000104 0.000095 0.0000163 0.0000230 0.000165 0.000163 1989 5 19 47665 0.154695 0.456220 -0.3283945 0.0015552 0.000053 -0.000543 0.000103 0.000095 0.0000158 0.0000224 0.000163 0.000160 1989 5 20 47666 0.156543 0.454263 -0.3298882 0.0014174 0.000091 -0.000371 0.000103 0.000095 0.0000153 0.0000217 0.000162 0.000157 1989 5 21 47667 0.160848 0.452458 -0.3313126 0.0013015 0.000129 -0.000200 0.000102 0.000094 0.0000149 0.0000210 0.000160 0.000154 1989 5 22 47668 0.162139 0.451234 -0.3325844 0.0012284 0.000092 -0.000178 0.000102 0.000094 0.0000144 0.0000204 0.000159 0.000153 1989 5 23 47669 0.163516 0.450524 -0.3337716 0.0012247 0.000030 -0.000205 0.000102 0.000095 0.0000140 0.0000198 0.000157 0.000152 1989 5 24 47670 0.166470 0.448394 -0.3350301 0.0013085 -0.000064 -0.000229 0.000103 0.000095 0.0000136 0.0000192 0.000156 0.000151 1989 5 25 47671 0.166466 0.446661 -0.3364448 0.0014797 -0.000041 -0.000197 0.000103 0.000095 0.0000131 0.0000188 0.000155 0.000150 1989 5 26 47672 0.168101 0.445798 -0.3380342 0.0017200 -0.000038 -0.000168 0.000103 0.000095 0.0000130 0.0000186 0.000154 0.000150 1989 5 27 47673 0.170318 0.443932 -0.3398520 0.0019911 -0.000084 -0.000156 0.000104 0.000096 0.0000132 0.0000187 0.000154 0.000151 1989 5 28 47674 0.171630 0.441739 -0.3419608 0.0022336 -0.000129 -0.000144 0.000105 0.000096 0.0000134 0.0000190 0.000154 0.000152 1989 5 29 47675 0.173900 0.439670 -0.3443367 0.0023800 -0.000061 -0.000191 0.000106 0.000097 0.0000136 0.0000192 0.000154 0.000152 1989 5 30 47676 0.176419 0.438259 -0.3467848 0.0023843 0.000043 -0.000257 0.000107 0.000098 0.0000137 0.0000194 0.000154 0.000152 1989 5 31 47677 0.178147 0.436762 -0.3490462 0.0022429 0.000146 -0.000323 0.000108 0.000099 0.0000138 0.0000195 0.000153 0.000152 1989 6 1 47678 0.180530 0.436377 -0.3509947 0.0019857 0.000226 -0.000495 0.000109 0.000100 0.0000139 0.0000195 0.000153 0.000151 1989 6 2 47679 0.182756 0.436072 -0.3529723 0.0016549 0.000293 -0.000720 0.000110 0.000101 0.0000138 0.0000195 0.000153 0.000151 1989 6 3 47680 0.184342 0.432482 -0.3545680 0.0013129 0.000135 -0.000401 0.000110 0.000102 0.0000137 0.0000194 0.000152 0.000150 1989 6 4 47681 0.186498 0.431147 -0.3556913 0.0010464 -0.000095 0.000094 0.000111 0.000102 0.0000136 0.0000194 0.000152 0.000149 1989 6 5 47682 0.186120 0.429287 -0.3566275 0.0009228 -0.000267 -0.000299 0.000112 0.000103 0.0000137 0.0000194 0.000152 0.000148 1989 6 6 47683 0.188355 0.426771 -0.3574832 0.0009518 -0.000185 -0.000499 0.000112 0.000104 0.0000139 0.0000197 0.000151 0.000148 1989 6 7 47684 0.191028 0.426689 -0.3584541 0.0010850 0.000036 -0.000585 0.000113 0.000104 0.0000142 0.0000200 0.000151 0.000149 1989 6 8 47685 0.190412 0.423874 -0.3597234 0.0012463 -0.000003 -0.000286 0.000113 0.000105 0.0000144 0.0000204 0.000152 0.000149 1989 6 9 47686 0.192874 0.422275 -0.3611222 0.0013799 0.000001 -0.000061 0.000113 0.000105 0.0000147 0.0000207 0.000152 0.000149 1989 6 10 47687 0.195890 0.421103 -0.3624932 0.0014730 0.000164 -0.000084 0.000113 0.000105 0.0000148 0.0000210 0.000153 0.000151 1989 6 11 47688 0.198301 0.418581 -0.3639090 0.0015308 0.000326 -0.000106 0.000113 0.000105 0.0000150 0.0000212 0.000154 0.000152 1989 6 12 47689 0.200549 0.416825 -0.3654450 0.0015444 0.000089 -0.000067 0.000113 0.000106 0.0000151 0.0000213 0.000154 0.000153 1989 6 13 47690 0.203248 0.414190 -0.3670068 0.0014911 0.000029 -0.000136 0.000114 0.000107 0.0000152 0.0000215 0.000155 0.000154 1989 6 14 47691 0.205675 0.411779 -0.3684754 0.0013570 0.000054 -0.000244 0.000116 0.000108 0.0000152 0.0000215 0.000156 0.000156 1989 6 15 47692 0.206935 0.409912 -0.3697609 0.0011532 0.000078 -0.000351 0.000117 0.000108 0.0000153 0.0000216 0.000156 0.000157 1989 6 16 47693 0.208388 0.407626 -0.3708019 0.0009174 0.000102 -0.000459 0.000119 0.000109 0.0000153 0.0000216 0.000157 0.000159 1989 6 17 47694 0.209356 0.404375 -0.3715893 0.0007025 0.000127 -0.000567 0.000120 0.000110 0.0000153 0.0000216 0.000158 0.000161 1989 6 18 47695 0.211471 0.402221 -0.3721762 0.0005602 0.000081 -0.000531 0.000121 0.000110 0.0000153 0.0000216 0.000158 0.000161 1989 6 19 47696 0.213394 0.399851 -0.3726743 0.0005249 0.000011 -0.000445 0.000123 0.000110 0.0000152 0.0000215 0.000159 0.000162 1989 6 20 47697 0.215268 0.396893 -0.3732207 0.0006040 -0.000060 -0.000360 0.000124 0.000111 0.0000151 0.0000214 0.000159 0.000162 1989 6 21 47698 0.216924 0.394675 -0.3739358 0.0007781 -0.000130 -0.000275 0.000126 0.000110 0.0000151 0.0000213 0.000160 0.000162 1989 6 22 47699 0.218462 0.391585 -0.3748967 0.0010104 -0.000200 -0.000190 0.000127 0.000110 0.0000150 0.0000212 0.000160 0.000163 1989 6 23 47700 0.221726 0.390150 -0.3760973 0.0012607 0.000006 -0.000244 0.000129 0.000110 0.0000149 0.0000210 0.000160 0.000163 1989 6 24 47701 0.224377 0.387329 -0.3772610 0.0014878 0.000050 -0.001098 0.000129 0.000109 0.0000147 0.0000208 0.000160 0.000163 1989 6 25 47702 0.225888 0.383694 -0.3787759 0.0016317 -0.000038 -0.001939 0.000130 0.000108 0.0000145 0.0000204 0.000160 0.000162 1989 6 26 47703 0.227849 0.381569 -0.3807346 0.0016267 -0.000264 -0.001683 0.000131 0.000107 0.0000142 0.0000200 0.000160 0.000161 1989 6 27 47704 0.229911 0.377829 -0.3822008 0.0014640 -0.000419 -0.000540 0.000131 0.000106 0.0000138 0.0000195 0.000158 0.000158 1989 6 28 47705 0.230257 0.377256 -0.3834229 0.0011954 -0.000299 -0.000003 0.000131 0.000105 0.0000134 0.0000190 0.000157 0.000156 1989 6 29 47706 0.232454 0.375427 -0.3844584 0.0008842 -0.000178 0.000097 0.000131 0.000104 0.0000131 0.0000185 0.000157 0.000154 1989 6 30 47707 0.236422 0.370076 -0.3852260 0.0005893 -0.000097 0.000090 0.000130 0.000102 0.0000128 0.0000181 0.000156 0.000153 1989 7 1 47708 0.238496 0.367728 -0.3857365 0.0003660 -0.000017 0.000082 0.000129 0.000101 0.0000125 0.0000177 0.000155 0.000151 1989 7 2 47709 0.239219 0.364834 -0.3860465 0.0002588 0.000064 0.000074 0.000127 0.000099 0.0000123 0.0000173 0.000155 0.000150 1989 7 3 47710 0.239886 0.361378 -0.3862652 0.0002855 -0.000064 -0.000094 0.000126 0.000098 0.0000120 0.0000170 0.000154 0.000148 1989 7 4 47711 0.241562 0.358400 -0.3865923 0.0004253 -0.000064 -0.000245 0.000124 0.000097 0.0000118 0.0000166 0.000153 0.000147 1989 7 5 47712 0.242985 0.355480 -0.3871370 0.0006269 0.000035 -0.000360 0.000123 0.000095 0.0000115 0.0000163 0.000153 0.000146 1989 7 6 47713 0.244896 0.352896 -0.3878822 0.0008344 0.000134 -0.000476 0.000121 0.000094 0.0000113 0.0000160 0.000153 0.000145 1989 7 7 47714 0.246122 0.349625 -0.3887777 0.0010066 -0.000055 -0.000092 0.000119 0.000093 0.0000112 0.0000157 0.000152 0.000145 1989 7 8 47715 0.247538 0.347077 -0.3898471 0.0011188 -0.000139 0.000003 0.000118 0.000092 0.0000109 0.0000155 0.000152 0.000144 1989 7 9 47716 0.249376 0.344592 -0.3910239 0.0011594 -0.000170 -0.000027 0.000116 0.000091 0.0000107 0.0000152 0.000151 0.000143 1989 7 10 47717 0.249918 0.341636 -0.3921801 0.0011320 -0.000370 0.000226 0.000114 0.000090 0.0000105 0.0000149 0.000151 0.000142 1989 7 11 47718 0.251248 0.338410 -0.3932568 0.0010530 -0.000386 0.000217 0.000113 0.000090 0.0000103 0.0000146 0.000150 0.000142 1989 7 12 47719 0.252174 0.335649 -0.3942439 0.0009437 -0.000309 0.000070 0.000113 0.000091 0.0000101 0.0000143 0.000151 0.000142 1989 7 13 47720 0.253308 0.332329 -0.3951441 0.0008255 -0.000284 -0.000052 0.000113 0.000091 0.0000099 0.0000141 0.000150 0.000142 1989 7 14 47721 0.253745 0.329211 -0.3959104 0.0007197 -0.000276 -0.000165 0.000113 0.000092 0.0000097 0.0000138 0.000150 0.000141 1989 7 15 47722 0.254688 0.326736 -0.3965350 0.0006470 -0.000242 -0.000257 0.000113 0.000092 0.0000096 0.0000135 0.000149 0.000140 1989 7 16 47723 0.256796 0.323134 -0.3972331 0.0006236 -0.000148 -0.000312 0.000112 0.000092 0.0000094 0.0000133 0.000149 0.000140 1989 7 17 47724 0.257285 0.321538 -0.3978816 0.0006673 0.000181 -0.000134 0.000111 0.000092 0.0000093 0.0000131 0.000149 0.000140 1989 7 18 47725 0.258190 0.319093 -0.3986001 0.0007965 0.000106 -0.000314 0.000110 0.000092 0.0000091 0.0000129 0.000149 0.000139 1989 7 19 47726 0.258819 0.315908 -0.3995089 0.0010127 -0.000103 -0.000615 0.000109 0.000091 0.0000090 0.0000129 0.000148 0.000139 1989 7 20 47727 0.258958 0.314150 -0.4006393 0.0012870 -0.000028 -0.000556 0.000108 0.000091 0.0000090 0.0000128 0.000148 0.000138 1989 7 21 47728 0.259098 0.310491 -0.4020350 0.0015600 0.000139 -0.000380 0.000107 0.000091 0.0000092 0.0000130 0.000148 0.000138 1989 7 22 47729 0.259136 0.307401 -0.4036975 0.0017563 0.000305 -0.000204 0.000106 0.000090 0.0000093 0.0000131 0.000148 0.000138 1989 7 23 47730 0.259273 0.304406 -0.4055389 0.0018134 0.000137 -0.000123 0.000105 0.000089 0.0000094 0.0000133 0.000147 0.000137 1989 7 24 47731 0.259420 0.300843 -0.4073404 0.0017125 -0.000140 -0.000073 0.000104 0.000088 0.0000095 0.0000134 0.000146 0.000136 1989 7 25 47732 0.258914 0.298545 -0.4088880 0.0014846 -0.000130 -0.000177 0.000103 0.000088 0.0000095 0.0000135 0.000145 0.000135 1989 7 26 47733 0.258951 0.295603 -0.4102273 0.0011885 -0.000091 -0.000213 0.000102 0.000087 0.0000096 0.0000136 0.000145 0.000135 1989 7 27 47734 0.260170 0.291481 -0.4113054 0.0008888 -0.000045 -0.000161 0.000101 0.000086 0.0000097 0.0000136 0.000144 0.000135 1989 7 28 47735 0.259391 0.287363 -0.4120213 0.0006460 -0.000270 0.000124 0.000099 0.000085 0.0000097 0.0000136 0.000144 0.000135 1989 7 29 47736 0.259408 0.283747 -0.4126417 0.0005034 -0.000191 0.000189 0.000099 0.000085 0.0000096 0.0000136 0.000143 0.000135 1989 7 30 47737 0.260145 0.281146 -0.4131722 0.0004815 0.000032 0.000146 0.000098 0.000084 0.0000096 0.0000137 0.000142 0.000135 1989 7 31 47738 0.259699 0.278109 -0.4135148 0.0005772 0.000125 0.000163 0.000098 0.000084 0.0000098 0.0000138 0.000143 0.000135 1989 8 1 47739 0.259398 0.274059 -0.4142579 0.0007489 0.000189 0.000196 0.000099 0.000085 0.0000100 0.0000140 0.000143 0.000136 1989 8 2 47740 0.258982 0.271320 -0.4151258 0.0009329 0.000107 0.000104 0.000099 0.000086 0.0000101 0.0000142 0.000143 0.000136 1989 8 3 47741 0.258164 0.268886 -0.4161661 0.0010816 -0.000025 -0.000028 0.000101 0.000087 0.0000102 0.0000144 0.000144 0.000137 1989 8 4 47742 0.257617 0.265859 -0.4172714 0.0011737 -0.000301 -0.000046 0.000103 0.000089 0.0000103 0.0000146 0.000144 0.000137 1989 8 5 47743 0.259179 0.262217 -0.4184492 0.0012072 0.000061 -0.000010 0.000105 0.000090 0.0000104 0.0000147 0.000144 0.000138 1989 8 6 47744 0.259634 0.258947 -0.4196368 0.0011875 0.000058 -0.000112 0.000107 0.000092 0.0000105 0.0000149 0.000145 0.000138 1989 8 7 47745 0.259634 0.256547 -0.4207893 0.0011215 0.000130 0.000162 0.000110 0.000094 0.0000106 0.0000150 0.000145 0.000138 1989 8 8 47746 0.259945 0.253551 -0.4218978 0.0010199 0.000270 0.000579 0.000112 0.000095 0.0000107 0.0000151 0.000145 0.000139 1989 8 9 47747 0.259150 0.251076 -0.4228993 0.0009019 0.000426 0.000219 0.000114 0.000097 0.0000108 0.0000153 0.000146 0.000139 1989 8 10 47748 0.258985 0.248245 -0.4236250 0.0007932 0.000178 0.000007 0.000117 0.000098 0.0000109 0.0000154 0.000147 0.000141 1989 8 11 47749 0.258913 0.244460 -0.4243764 0.0007087 -0.000001 0.000185 0.000118 0.000099 0.0000110 0.0000156 0.000147 0.000142 1989 8 12 47750 0.260330 0.240683 -0.4251240 0.0006511 0.000046 0.000108 0.000120 0.000101 0.0000111 0.0000157 0.000148 0.000143 1989 8 13 47751 0.260672 0.237524 -0.4258040 0.0006360 0.000167 -0.000073 0.000122 0.000103 0.0000112 0.0000159 0.000149 0.000144 1989 8 14 47752 0.259634 0.234805 -0.4264695 0.0006983 0.000287 -0.000255 0.000124 0.000104 0.0000113 0.0000160 0.000149 0.000144 1989 8 15 47753 0.259353 0.231962 -0.4272215 0.0008722 0.000407 -0.000437 0.000126 0.000106 0.0000114 0.0000162 0.000150 0.000145 1989 8 16 47754 0.258783 0.229147 -0.4281916 0.0011605 0.000527 -0.000619 0.000127 0.000108 0.0000116 0.0000163 0.000151 0.000146 1989 8 17 47755 0.258368 0.226043 -0.4294935 0.0015140 0.000401 -0.000306 0.000129 0.000109 0.0000116 0.0000164 0.000151 0.000146 1989 8 18 47756 0.256995 0.223195 -0.4311647 0.0018390 0.000196 0.000164 0.000130 0.000110 0.0000116 0.0000165 0.000151 0.000146 1989 8 19 47757 0.255558 0.220054 -0.4331329 0.0020327 0.000158 0.000526 0.000130 0.000110 0.0000117 0.0000165 0.000152 0.000147 1989 8 20 47758 0.254533 0.216544 -0.4352180 0.0020295 0.000176 0.000744 0.000131 0.000110 0.0000117 0.0000166 0.000152 0.000148 1989 8 21 47759 0.253432 0.213014 -0.4371945 0.0018317 0.000177 0.000531 0.000131 0.000110 0.0000118 0.0000166 0.000152 0.000148 1989 8 22 47760 0.252068 0.209881 -0.4388764 0.0015076 0.000223 0.000382 0.000131 0.000110 0.0000117 0.0000166 0.000152 0.000147 1989 8 23 47761 0.251426 0.206077 -0.4401841 0.0011584 0.000285 0.000252 0.000131 0.000109 0.0000117 0.0000165 0.000151 0.000146 1989 8 24 47762 0.250749 0.202748 -0.4411556 0.0008740 -0.000205 0.000205 0.000131 0.000109 0.0000117 0.0000165 0.000150 0.000145 1989 8 25 47763 0.249224 0.201076 -0.4419239 0.0007035 -0.000799 0.000173 0.000131 0.000109 0.0000116 0.0000164 0.000150 0.000145 1989 8 26 47764 0.249712 0.196995 -0.4426341 0.0006531 -0.000096 0.000260 0.000131 0.000108 0.0000116 0.0000163 0.000150 0.000144 1989 8 27 47765 0.249974 0.193732 -0.4433309 0.0007047 0.000153 0.000126 0.000131 0.000108 0.0000115 0.0000162 0.000150 0.000144 1989 8 28 47766 0.249990 0.191895 -0.4440812 0.0008333 0.000172 -0.000088 0.000131 0.000108 0.0000114 0.0000161 0.000150 0.000145 1989 8 29 47767 0.248965 0.188745 -0.4449747 0.0010099 0.000191 -0.000302 0.000131 0.000108 0.0000112 0.0000159 0.000150 0.000146 1989 8 30 47768 0.246011 0.186903 -0.4460738 0.0011994 0.000211 -0.000516 0.000131 0.000108 0.0000111 0.0000159 0.000150 0.000146 1989 8 31 47769 0.245394 0.184468 -0.4473790 0.0013650 0.000182 -0.000128 0.000131 0.000108 0.0000113 0.0000160 0.000151 0.000148 1989 9 1 47770 0.244094 0.180425 -0.4487336 0.0014742 0.000201 0.000415 0.000132 0.000108 0.0000115 0.0000163 0.000152 0.000150 1989 9 2 47771 0.241332 0.176569 -0.4502346 0.0014989 0.000075 0.000882 0.000132 0.000109 0.0000117 0.0000165 0.000152 0.000152 1989 9 3 47772 0.239697 0.172874 -0.4518001 0.0014220 -0.000148 0.001099 0.000132 0.000109 0.0000118 0.0000166 0.000153 0.000153 1989 9 4 47773 0.237726 0.169598 -0.4531774 0.0012582 -0.000220 0.000566 0.000132 0.000109 0.0000118 0.0000168 0.000153 0.000154 1989 9 5 47774 0.235707 0.167106 -0.4543057 0.0010540 -0.000292 0.000033 0.000132 0.000109 0.0000119 0.0000168 0.000153 0.000155 1989 9 6 47775 0.233853 0.163880 -0.4552148 0.0008644 -0.000117 -0.000056 0.000132 0.000109 0.0000119 0.0000168 0.000153 0.000155 1989 9 7 47776 0.231608 0.161104 -0.4559723 0.0007290 0.000141 0.000004 0.000131 0.000108 0.0000119 0.0000168 0.000152 0.000155 1989 9 8 47777 0.229012 0.158964 -0.4566596 0.0006642 0.000400 0.000064 0.000130 0.000108 0.0000118 0.0000167 0.000152 0.000155 1989 9 9 47778 0.226366 0.155962 -0.4573500 0.0006715 0.000386 0.000028 0.000129 0.000107 0.0000118 0.0000166 0.000152 0.000155 1989 9 10 47779 0.223990 0.153894 -0.4580609 0.0007511 0.000350 -0.000024 0.000128 0.000105 0.0000117 0.0000166 0.000152 0.000156 1989 9 11 47780 0.221294 0.151214 -0.4588323 0.0009052 0.000545 0.000227 0.000126 0.000104 0.0000116 0.0000165 0.000152 0.000156 1989 9 12 47781 0.218543 0.148193 -0.4600152 0.0011299 0.000325 0.000202 0.000126 0.000104 0.0000116 0.0000165 0.000152 0.000156 1989 9 13 47782 0.216685 0.146015 -0.4613237 0.0014166 -0.000118 0.000006 0.000125 0.000104 0.0000116 0.0000164 0.000152 0.000156 1989 9 14 47783 0.214561 0.143996 -0.4626062 0.0017404 -0.000379 -0.000069 0.000125 0.000105 0.0000116 0.0000163 0.000152 0.000157 1989 9 15 47784 0.211428 0.142586 -0.4645284 0.0020224 -0.000299 0.000045 0.000124 0.000105 0.0000114 0.0000161 0.000151 0.000156 1989 9 16 47785 0.209179 0.140236 -0.4667339 0.0021578 -0.000073 0.000074 0.000123 0.000104 0.0000112 0.0000159 0.000149 0.000154 1989 9 17 47786 0.207736 0.137466 -0.4689060 0.0020940 0.000203 0.000074 0.000121 0.000103 0.0000110 0.0000156 0.000148 0.000152 1989 9 18 47787 0.205221 0.135747 -0.4708795 0.0018610 0.000193 0.000200 0.000120 0.000103 0.0000108 0.0000153 0.000147 0.000150 1989 9 19 47788 0.202160 0.133393 -0.4725716 0.0015477 0.000175 0.000143 0.000120 0.000102 0.0000107 0.0000151 0.000146 0.000149 1989 9 20 47789 0.199362 0.130103 -0.4739707 0.0012551 0.000173 0.000013 0.000119 0.000102 0.0000105 0.0000149 0.000146 0.000148 1989 9 21 47790 0.197086 0.128230 -0.4751313 0.0010584 0.000119 0.000176 0.000118 0.000101 0.0000104 0.0000146 0.000145 0.000147 1989 9 22 47791 0.194419 0.126326 -0.4761458 0.0009898 0.000104 0.000204 0.000117 0.000100 0.0000101 0.0000143 0.000144 0.000146 1989 9 23 47792 0.191450 0.123231 -0.4771399 0.0010412 0.000110 0.000145 0.000116 0.000099 0.0000099 0.0000140 0.000143 0.000144 1989 9 24 47793 0.188937 0.120862 -0.4782347 0.0011786 0.000117 0.000086 0.000114 0.000098 0.0000097 0.0000137 0.000142 0.000142 1989 9 25 47794 0.185194 0.119197 -0.4795090 0.0013590 0.000123 0.000026 0.000113 0.000096 0.0000094 0.0000133 0.000142 0.000141 1989 9 26 47795 0.181803 0.117038 -0.4809888 0.0015439 0.000178 0.000063 0.000111 0.000094 0.0000092 0.0000130 0.000141 0.000139 1989 9 27 47796 0.178569 0.114353 -0.4826161 0.0017063 0.000250 0.000132 0.000109 0.000093 0.0000089 0.0000126 0.000140 0.000137 1989 9 28 47797 0.175144 0.112234 -0.4843183 0.0018260 -0.000132 0.000001 0.000108 0.000092 0.0000087 0.0000123 0.000139 0.000135 1989 9 29 47798 0.172247 0.109818 -0.4861665 0.0018804 -0.000131 0.000109 0.000107 0.000091 0.0000084 0.0000119 0.000138 0.000133 1989 9 30 47799 0.168691 0.107123 -0.4880990 0.0018485 0.000044 0.000319 0.000105 0.000090 0.0000081 0.0000114 0.000137 0.000130 1989 10 1 47800 0.166155 0.105337 -0.4899388 0.0017307 0.000385 0.000356 0.000104 0.000089 0.0000078 0.0000110 0.000136 0.000128 1989 10 2 47801 0.162417 0.104510 -0.4915837 0.0015573 0.000779 0.000338 0.000102 0.000087 0.0000075 0.0000107 0.000135 0.000125 1989 10 3 47802 0.159454 0.102704 -0.4930160 0.0013757 0.001173 0.000320 0.000100 0.000086 0.0000073 0.0000103 0.000134 0.000123 1989 10 4 47803 0.156692 0.101429 -0.4942769 0.0012286 0.001256 0.000257 0.000097 0.000084 0.0000071 0.0000100 0.000134 0.000121 1989 10 5 47804 0.151924 0.101329 -0.4954426 0.0011412 0.000537 0.000080 0.000095 0.000082 0.0000069 0.0000097 0.000133 0.000119 1989 10 6 47805 0.150738 0.097775 -0.4965911 0.0011214 -0.000202 -0.000372 0.000093 0.000081 0.0000067 0.0000094 0.000132 0.000117 1989 10 7 47806 0.147409 0.096029 -0.4977583 0.0011728 -0.000330 -0.000344 0.000090 0.000079 0.0000065 0.0000092 0.000130 0.000115 1989 10 8 47807 0.141920 0.096300 -0.4989965 0.0013028 -0.000123 -0.000008 0.000088 0.000077 0.0000063 0.0000089 0.000129 0.000114 1989 10 9 47808 0.138761 0.094159 -0.5003943 0.0015182 0.000084 0.000329 0.000085 0.000075 0.0000061 0.0000087 0.000128 0.000112 1989 10 10 47809 0.134900 0.093194 -0.5020435 0.0018095 0.000149 0.000275 0.000083 0.000073 0.0000060 0.0000085 0.000127 0.000111 1989 10 11 47810 0.132214 0.092098 -0.5039965 0.0021366 0.000201 0.000245 0.000081 0.000071 0.0000059 0.0000083 0.000127 0.000110 1989 10 12 47811 0.129124 0.091285 -0.5062859 0.0024276 0.000114 0.000174 0.000079 0.000070 0.0000057 0.0000081 0.000125 0.000108 1989 10 13 47812 0.124093 0.090463 -0.5088296 0.0026013 -0.000060 0.000039 0.000077 0.000069 0.0000056 0.0000079 0.000124 0.000106 1989 10 14 47813 0.119839 0.089095 -0.5114654 0.0026048 -0.000200 -0.000038 0.000075 0.000067 0.0000054 0.0000076 0.000122 0.000104 1989 10 15 47814 0.116256 0.088644 -0.5139981 0.0024445 -0.000309 -0.000067 0.000073 0.000066 0.0000052 0.0000074 0.000121 0.000102 1989 10 16 47815 0.111191 0.086984 -0.5162708 0.0021866 -0.000202 -0.000059 0.000072 0.000064 0.0000051 0.0000072 0.000120 0.000100 1989 10 17 47816 0.106459 0.085848 -0.5183215 0.0019251 -0.000005 -0.000045 0.000070 0.000063 0.0000050 0.0000070 0.000118 0.000097 1989 10 18 47817 0.103101 0.084717 -0.5201662 0.0017416 0.000247 -0.000053 0.000069 0.000063 0.0000049 0.0000069 0.000117 0.000096 1989 10 19 47818 0.099748 0.083343 -0.5218861 0.0016794 0.000212 -0.000062 0.000068 0.000062 0.0000048 0.0000068 0.000116 0.000095 1989 10 20 47819 0.096657 0.083708 -0.5236020 0.0017366 0.000204 -0.000266 0.000068 0.000062 0.0000048 0.0000068 0.000115 0.000095 1989 10 21 47820 0.092445 0.081910 -0.5253912 0.0018789 0.000225 -0.000451 0.000067 0.000062 0.0000048 0.0000067 0.000114 0.000095 1989 10 22 47821 0.087962 0.079535 -0.5273423 0.0020579 0.000219 -0.000268 0.000066 0.000061 0.0000047 0.0000067 0.000113 0.000095 1989 10 23 47822 0.083734 0.079528 -0.5294733 0.0022264 0.000124 0.000094 0.000065 0.000061 0.0000047 0.0000066 0.000112 0.000094 1989 10 24 47823 0.080484 0.078525 -0.5317927 0.0023490 -0.000102 0.000160 0.000065 0.000060 0.0000047 0.0000066 0.000112 0.000094 1989 10 25 47824 0.077926 0.077590 -0.5342130 0.0024072 -0.000118 0.000203 0.000064 0.000060 0.0000047 0.0000066 0.000111 0.000093 1989 10 26 47825 0.074211 0.077685 -0.5366362 0.0024024 0.000010 0.000218 0.000063 0.000059 0.0000046 0.0000065 0.000111 0.000092 1989 10 27 47826 0.070397 0.077065 -0.5389457 0.0023482 0.000127 0.000223 0.000063 0.000059 0.0000046 0.0000065 0.000110 0.000091 1989 10 28 47827 0.067229 0.076738 -0.5412439 0.0022564 0.000091 0.000201 0.000063 0.000059 0.0000046 0.0000065 0.000110 0.000091 1989 10 29 47828 0.063971 0.077105 -0.5434642 0.0021335 0.000053 0.000188 0.000063 0.000059 0.0000047 0.0000066 0.000110 0.000092 1989 10 30 47829 0.059447 0.076733 -0.5455240 0.0019897 0.000011 0.000198 0.000063 0.000059 0.0000047 0.0000067 0.000110 0.000093 1989 10 31 47830 0.056031 0.076034 -0.5474337 0.0018410 -0.000035 0.000098 0.000064 0.000060 0.0000048 0.0000069 0.000110 0.000094 1989 11 1 47831 0.052691 0.075573 -0.5492188 0.0017055 -0.000007 -0.000065 0.000065 0.000061 0.0000049 0.0000070 0.000110 0.000095 1989 11 2 47832 0.049463 0.074641 -0.5508772 0.0016039 -0.000031 -0.000191 0.000066 0.000062 0.0000051 0.0000072 0.000111 0.000097 1989 11 3 47833 0.047123 0.074634 -0.5525022 0.0015601 0.000019 -0.000259 0.000068 0.000063 0.0000053 0.0000075 0.000112 0.000100 1989 11 4 47834 0.042790 0.074457 -0.5540368 0.0016005 0.000275 0.000132 0.000070 0.000065 0.0000055 0.0000077 0.000113 0.000102 1989 11 5 47835 0.038763 0.074128 -0.5556440 0.0017417 0.000237 0.000190 0.000072 0.000066 0.0000057 0.0000080 0.000115 0.000104 1989 11 6 47836 0.034959 0.074664 -0.5575143 0.0019734 0.000102 0.000138 0.000073 0.000067 0.0000058 0.0000083 0.000116 0.000106 1989 11 7 47837 0.031075 0.074878 -0.5596796 0.0022586 0.000064 0.000128 0.000075 0.000069 0.0000060 0.0000085 0.000117 0.000108 1989 11 8 47838 0.026153 0.075003 -0.5620162 0.0025417 -0.000124 0.000213 0.000077 0.000070 0.0000062 0.0000088 0.000118 0.000109 1989 11 9 47839 0.021338 0.074130 -0.5646581 0.0027514 0.000045 0.000190 0.000078 0.000071 0.0000064 0.0000090 0.000119 0.000111 1989 11 10 47840 0.018232 0.074533 -0.5675282 0.0028172 0.000362 0.000049 0.000080 0.000072 0.0000065 0.0000092 0.000119 0.000112 1989 11 11 47841 0.014294 0.075033 -0.5703348 0.0027108 0.000467 0.000067 0.000082 0.000074 0.0000067 0.0000095 0.000120 0.000113 1989 11 12 47842 0.010525 0.074735 -0.5728842 0.0024687 0.000457 0.000178 0.000083 0.000074 0.0000068 0.0000097 0.000120 0.000114 1989 11 13 47843 0.005355 0.076249 -0.5751405 0.0021735 0.000501 -0.000007 0.000084 0.000075 0.0000070 0.0000099 0.000121 0.000115 1989 11 14 47844 0.001042 0.076387 -0.5771935 0.0019135 0.000180 0.000462 0.000086 0.000076 0.0000071 0.0000101 0.000121 0.000116 1989 11 15 47845 -0.001199 0.075731 -0.5790772 0.0017528 0.000408 0.000577 0.000087 0.000076 0.0000073 0.0000103 0.000121 0.000117 1989 11 16 47846 -0.004561 0.076737 -0.5808417 0.0017205 0.000851 0.000521 0.000088 0.000077 0.0000074 0.0000105 0.000122 0.000118 1989 11 17 47847 -0.008891 0.078811 -0.5825760 0.0018100 0.001293 0.000465 0.000090 0.000078 0.0000075 0.0000107 0.000122 0.000119 1989 11 18 47848 -0.012637 0.078968 -0.5843926 0.0019836 0.000997 -0.000106 0.000092 0.000078 0.0000077 0.0000109 0.000122 0.000120 1989 11 19 47849 -0.015404 0.078480 -0.5864964 0.0021849 0.000366 0.000090 0.000093 0.000078 0.0000078 0.0000110 0.000123 0.000121 1989 11 20 47850 -0.019734 0.080094 -0.5888111 0.0023628 0.000238 0.000264 0.000095 0.000079 0.0000079 0.0000112 0.000123 0.000121 1989 11 21 47851 -0.023457 0.081155 -0.5912383 0.0024901 0.000292 0.000371 0.000096 0.000079 0.0000080 0.0000113 0.000123 0.000122 1989 11 22 47852 -0.026536 0.082540 -0.5937461 0.0025584 0.000346 0.000478 0.000097 0.000078 0.0000081 0.0000114 0.000123 0.000122 1989 11 23 47853 -0.029911 0.084213 -0.5963031 0.0025639 0.000303 0.000298 0.000098 0.000078 0.0000082 0.0000116 0.000123 0.000122 1989 11 24 47854 -0.033583 0.085694 -0.5988552 0.0025033 0.000230 0.000028 0.000099 0.000077 0.0000083 0.0000117 0.000123 0.000123 1989 11 25 47855 -0.037549 0.087606 -0.6013300 0.0023813 0.000210 0.000072 0.000100 0.000076 0.0000083 0.0000118 0.000124 0.000124 1989 11 26 47856 -0.040756 0.089533 -0.6036438 0.0022183 0.000208 0.000219 0.000101 0.000075 0.0000084 0.0000119 0.000124 0.000124 1989 11 27 47857 -0.045412 0.091197 -0.6057472 0.0020471 0.000681 0.000230 0.000102 0.000075 0.0000085 0.0000120 0.000124 0.000125 1989 11 28 47858 -0.049471 0.092800 -0.6077025 0.0019005 0.000659 0.000193 0.000103 0.000076 0.0000085 0.0000120 0.000125 0.000126 1989 11 29 47859 -0.053581 0.094318 -0.6095595 0.0018015 0.000458 0.000151 0.000104 0.000077 0.0000085 0.0000120 0.000125 0.000127 1989 11 30 47860 -0.057504 0.094455 -0.6113474 0.0017640 0.000400 0.000155 0.000105 0.000078 0.0000085 0.0000120 0.000125 0.000127 1989 12 1 47861 -0.060146 0.095130 -0.6131239 0.0017948 0.000392 0.000175 0.000105 0.000078 0.0000084 0.0000119 0.000125 0.000127 1989 12 2 47862 -0.063141 0.095976 -0.6149612 0.0018921 0.000383 0.000195 0.000105 0.000078 0.0000084 0.0000118 0.000125 0.000127 1989 12 3 47863 -0.065874 0.096868 -0.6169255 0.0020429 0.000374 0.000216 0.000105 0.000078 0.0000083 0.0000117 0.000125 0.000127 1989 12 4 47864 -0.068677 0.098044 -0.6190618 0.0022219 0.000365 0.000236 0.000105 0.000078 0.0000082 0.0000116 0.000124 0.000128 1989 12 5 47865 -0.069959 0.099197 -0.6213801 0.0023936 0.000234 0.000634 0.000104 0.000077 0.0000081 0.0000115 0.000125 0.000127 1989 12 6 47866 -0.072540 0.101736 -0.6238418 0.0025174 0.000189 0.000740 0.000103 0.000076 0.0000080 0.0000113 0.000125 0.000127 1989 12 7 47867 -0.074854 0.103726 -0.6263757 0.0025558 0.000205 0.000642 0.000102 0.000075 0.0000078 0.0000111 0.000125 0.000126 1989 12 8 47868 -0.075587 0.105857 -0.6288894 0.0024848 0.000222 0.000543 0.000100 0.000073 0.0000077 0.0000109 0.000125 0.000126 1989 12 9 47869 -0.079121 0.108324 -0.6312801 0.0023056 0.000238 0.000444 0.000098 0.000071 0.0000076 0.0000107 0.000125 0.000125 1989 12 10 47870 -0.081639 0.110699 -0.6334604 0.0020525 0.000254 0.000345 0.000096 0.000070 0.0000074 0.0000105 0.000125 0.000125 1989 12 11 47871 -0.083125 0.113071 -0.6353862 0.0017873 0.000270 0.000247 0.000094 0.000068 0.0000073 0.0000103 0.000125 0.000124 1989 12 12 47872 -0.086519 0.115268 -0.6370769 0.0015801 0.000287 0.000148 0.000092 0.000066 0.0000072 0.0000101 0.000125 0.000124 1989 12 13 47873 -0.090162 0.117402 -0.6386125 0.0014821 0.000303 0.000049 0.000090 0.000064 0.0000070 0.0000102 0.000125 0.000123 1989 12 14 47874 -0.092881 0.118755 -0.6401064 0.0015068 0.000246 0.000055 0.000088 0.000062 0.0000072 0.0000102 0.000125 0.000123 1989 12 15 47875 -0.095420 0.121717 -0.6416645 0.0016291 -0.000034 0.000225 0.000087 0.000061 0.0000074 0.0000104 0.000125 0.000123 1989 12 16 47876 -0.096997 0.125178 -0.6433636 0.0018013 0.000087 0.000233 0.000086 0.000059 0.0000075 0.0000107 0.000125 0.000123 1989 12 17 47877 -0.098657 0.127923 -0.6452363 0.0019738 0.000456 0.000130 0.000084 0.000058 0.0000077 0.0000109 0.000125 0.000122 1989 12 18 47878 -0.101685 0.130317 -0.6472709 0.0021093 0.000825 0.000027 0.000082 0.000056 0.0000079 0.0000111 0.000125 0.000121 1989 12 19 47879 -0.103307 0.132700 -0.6494246 0.0021861 0.000486 0.000036 0.000081 0.000054 0.0000080 0.0000113 0.000125 0.000120 1989 12 20 47880 -0.105224 0.135145 -0.6516376 0.0021944 0.000300 -0.000034 0.000079 0.000053 0.0000082 0.0000116 0.000125 0.000119 1989 12 21 47881 -0.107575 0.136866 -0.6538135 0.0021335 0.000131 -0.000108 0.000079 0.000053 0.0000083 0.0000117 0.000125 0.000119 1989 12 22 47882 -0.109639 0.139836 -0.6558856 0.0020109 -0.000056 -0.000174 0.000080 0.000054 0.0000084 0.0000119 0.000125 0.000118 1989 12 23 47883 -0.112101 0.142041 -0.6578225 0.0018424 0.000102 -0.000265 0.000081 0.000056 0.0000086 0.0000121 0.000125 0.000118 1989 12 24 47884 -0.113614 0.143763 -0.6595814 0.0016521 0.000348 -0.000215 0.000082 0.000057 0.0000086 0.0000122 0.000125 0.000118 1989 12 25 47885 -0.116010 0.146221 -0.6611392 0.0014713 0.000386 0.000003 0.000083 0.000059 0.0000087 0.0000123 0.000125 0.000118 1989 12 26 47886 -0.119248 0.148336 -0.6625273 0.0013323 0.000424 0.000221 0.000084 0.000061 0.0000087 0.0000124 0.000125 0.000118 1989 12 27 47887 -0.121886 0.150814 -0.6638099 0.0012609 0.000463 0.000440 0.000085 0.000063 0.0000088 0.0000124 0.000125 0.000118 1989 12 28 47888 -0.125190 0.152957 -0.6650707 0.0012719 0.000501 0.000658 0.000086 0.000064 0.0000089 0.0000125 0.000125 0.000117 1989 12 29 47889 -0.128652 0.155677 -0.6663945 0.0013667 0.000420 0.000273 0.000087 0.000066 0.0000089 0.0000126 0.000125 0.000117 1989 12 30 47890 -0.130348 0.158139 -0.6678444 0.0015322 0.000375 0.000106 0.000088 0.000067 0.0000089 0.0000126 0.000126 0.000117 1989 12 31 47891 -0.131956 0.161173 -0.6694706 0.0017401 0.000349 0.000051 0.000089 0.000068 0.0000090 0.0000127 0.000126 0.000116 1990 1 1 47892 -0.133762 0.166056 0.3286996 0.0019477 0.000324 -0.000003 0.000148 0.000112 0.0000152 0.0000215 0.000087 0.000097 1990 1 2 47893 -0.134701 0.168777 0.3266677 0.0021320 0.000298 -0.000057 0.000148 0.000113 0.0000154 0.0000217 0.000087 0.000098 1990 1 3 47894 -0.136685 0.170321 0.3244848 0.0022419 0.000273 -0.000112 0.000148 0.000114 0.0000155 0.0000220 0.000087 0.000099 1990 1 4 47895 -0.137751 0.173842 0.3222376 0.0022459 0.000295 -0.000131 0.000149 0.000115 0.0000157 0.0000222 0.000087 0.000099 1990 1 5 47896 -0.138818 0.176589 0.3200374 0.0021331 0.000333 -0.000139 0.000149 0.000116 0.0000158 0.0000224 0.000088 0.000100 1990 1 6 47897 -0.140623 0.178883 0.3179953 0.0019209 0.000370 -0.000147 0.000149 0.000116 0.0000160 0.0000226 0.000088 0.000101 1990 1 7 47898 -0.142141 0.181514 0.3161921 0.0016556 0.000408 -0.000155 0.000149 0.000117 0.0000161 0.0000228 0.000088 0.000102 1990 1 8 47899 -0.145142 0.183788 0.3146525 0.0014029 0.000446 -0.000163 0.000148 0.000117 0.0000163 0.0000230 0.000088 0.000102 1990 1 9 47900 -0.147660 0.186034 0.3133341 0.0012292 0.000361 -0.000172 0.000147 0.000116 0.0000164 0.0000232 0.000089 0.000103 1990 1 10 47901 -0.150020 0.188096 0.3121405 0.0011787 0.000233 -0.000180 0.000147 0.000116 0.0000166 0.0000236 0.000089 0.000104 1990 1 11 47902 -0.152057 0.190641 0.3109465 0.0012576 0.000034 -0.000167 0.000146 0.000116 0.0000169 0.0000240 0.000090 0.000105 1990 1 12 47903 -0.153699 0.194000 0.3096049 0.0014339 0.000135 -0.000147 0.000146 0.000116 0.0000174 0.0000247 0.000091 0.000108 1990 1 13 47904 -0.156133 0.196845 0.3080640 0.0016532 0.000484 -0.000127 0.000146 0.000116 0.0000179 0.0000254 0.000092 0.000110 1990 1 14 47905 -0.157838 0.199654 0.3063705 0.0018578 0.000346 -0.000298 0.000146 0.000116 0.0000185 0.0000261 0.000093 0.000112 1990 1 15 47906 -0.158927 0.202455 0.3044919 0.0019919 0.000034 -0.000536 0.000146 0.000116 0.0000190 0.0000269 0.000094 0.000115 1990 1 16 47907 -0.160399 0.205718 0.3023926 0.0020084 -0.000277 -0.000775 0.000145 0.000116 0.0000196 0.0000277 0.000096 0.000118 1990 1 17 47908 -0.161833 0.208975 0.3002101 0.0019000 0.000181 -0.000168 0.000145 0.000115 0.0000201 0.0000283 0.000096 0.000120 1990 1 18 47909 -0.164082 0.211734 0.2985856 0.0017240 0.000371 0.000069 0.000144 0.000115 0.0000204 0.0000289 0.000097 0.000121 1990 1 19 47910 -0.166177 0.214905 0.2969965 0.0015527 0.000326 0.000056 0.000143 0.000114 0.0000208 0.0000294 0.000097 0.000122 1990 1 20 47911 -0.168344 0.217571 0.2955043 0.0014209 -0.000005 -0.000171 0.000143 0.000114 0.0000212 0.0000300 0.000098 0.000123 1990 1 21 47912 -0.173940 0.220854 0.2941912 0.0013350 -0.000457 -0.000485 0.000143 0.000115 0.0000216 0.0000305 0.000099 0.000125 1990 1 22 47913 -0.177008 0.224833 0.2927953 0.0012856 -0.000267 -0.000706 0.000144 0.000115 0.0000219 0.0000308 0.000099 0.000126 1990 1 23 47914 -0.178321 0.226816 0.2914550 0.0012723 0.000213 -0.000566 0.000143 0.000114 0.0000220 0.0000311 0.000099 0.000126 1990 1 24 47915 -0.182081 0.228503 0.2901813 0.0013195 0.000336 -0.000330 0.000144 0.000114 0.0000222 0.0000314 0.000099 0.000126 1990 1 25 47916 -0.184209 0.232776 0.2890040 0.0014536 0.000182 -0.000126 0.000145 0.000115 0.0000224 0.0000316 0.000100 0.000126 1990 1 26 47917 -0.185733 0.235912 0.2871859 0.0016651 0.000054 -0.000023 0.000146 0.000115 0.0000225 0.0000318 0.000100 0.000126 1990 1 27 47918 -0.187275 0.239021 0.2854804 0.0019313 0.000146 -0.000047 0.000148 0.000116 0.0000225 0.0000318 0.000100 0.000126 1990 1 28 47919 -0.189770 0.244021 0.2834710 0.0022280 0.000410 -0.000072 0.000150 0.000117 0.0000225 0.0000319 0.000100 0.000126 1990 1 29 47920 -0.191180 0.247122 0.2810343 0.0025019 0.000308 -0.000140 0.000151 0.000118 0.0000225 0.0000319 0.000100 0.000126 1990 1 30 47921 -0.192994 0.250643 0.2784508 0.0026952 0.000070 -0.000222 0.000153 0.000119 0.0000226 0.0000320 0.000100 0.000127 1990 1 31 47922 -0.195924 0.253950 0.2758031 0.0027686 -0.000039 -0.000170 0.000155 0.000120 0.0000228 0.0000322 0.000100 0.000128 1990 2 1 47923 -0.195834 0.257065 0.2729886 0.0027022 -0.000105 -0.000077 0.000156 0.000121 0.0000229 0.0000324 0.000100 0.000129 1990 2 2 47924 -0.197440 0.261935 0.2702555 0.0025145 -0.000018 0.000120 0.000157 0.000121 0.0000230 0.0000324 0.000100 0.000130 1990 2 3 47925 -0.198625 0.265473 0.2678869 0.0022792 0.000008 -0.000053 0.000157 0.000122 0.0000229 0.0000324 0.000100 0.000130 1990 2 4 47926 -0.199514 0.268590 0.2658290 0.0020886 0.000008 -0.000348 0.000157 0.000121 0.0000228 0.0000323 0.000100 0.000130 1990 2 5 47927 -0.202398 0.272993 0.2638326 0.0019953 0.000008 -0.000642 0.000157 0.000121 0.0000228 0.0000321 0.000099 0.000130 1990 2 6 47928 -0.202824 0.276541 0.2617061 0.0019982 0.000275 -0.000370 0.000156 0.000119 0.0000226 0.0000319 0.000099 0.000129 1990 2 7 47929 -0.203379 0.279134 0.2596553 0.0020790 0.000172 -0.000228 0.000154 0.000118 0.0000223 0.0000316 0.000098 0.000128 1990 2 8 47930 -0.205583 0.283166 0.2575663 0.0022222 -0.000139 -0.000218 0.000153 0.000116 0.0000220 0.0000312 0.000098 0.000127 1990 2 9 47931 -0.205780 0.287276 0.2550607 0.0024045 -0.000177 -0.000145 0.000152 0.000116 0.0000218 0.0000308 0.000097 0.000126 1990 2 10 47932 -0.204935 0.291231 0.2529381 0.0026049 0.000065 0.000001 0.000151 0.000115 0.0000215 0.0000304 0.000096 0.000125 1990 2 11 47933 -0.207058 0.294718 0.2501444 0.0027733 0.000264 0.000112 0.000149 0.000113 0.0000211 0.0000298 0.000095 0.000123 1990 2 12 47934 -0.206447 0.298677 0.2471617 0.0028399 0.000249 -0.000093 0.000148 0.000112 0.0000207 0.0000292 0.000094 0.000120 1990 2 13 47935 -0.203545 0.303773 0.2443518 0.0027898 0.000180 -0.000080 0.000145 0.000110 0.0000202 0.0000286 0.000092 0.000118 1990 2 14 47936 -0.203001 0.306426 0.2416575 0.0026589 0.000176 -0.000010 0.000145 0.000110 0.0000198 0.0000280 0.000091 0.000116 1990 2 15 47937 -0.201552 0.311219 0.2391219 0.0024912 0.000200 0.000043 0.000145 0.000111 0.0000194 0.0000275 0.000091 0.000115 1990 2 16 47938 -0.201713 0.316602 0.2367366 0.0023138 0.000224 0.000096 0.000144 0.000112 0.0000191 0.0000271 0.000090 0.000114 1990 2 17 47939 -0.201390 0.319076 0.2344759 0.0021361 0.000273 -0.000131 0.000144 0.000113 0.0000189 0.0000267 0.000090 0.000113 1990 2 18 47940 -0.201057 0.323490 0.2324322 0.0019642 0.000268 -0.000320 0.000143 0.000114 0.0000187 0.0000265 0.000090 0.000112 1990 2 19 47941 -0.201683 0.326900 0.2305273 0.0018105 0.000077 -0.000404 0.000143 0.000115 0.0000186 0.0000263 0.000090 0.000112 1990 2 20 47942 -0.200707 0.329786 0.2287216 0.0016979 -0.000040 -0.000488 0.000143 0.000116 0.0000185 0.0000262 0.000090 0.000111 1990 2 21 47943 -0.202048 0.333826 0.2270756 0.0016632 0.000035 -0.000574 0.000143 0.000117 0.0000184 0.0000261 0.000089 0.000110 1990 2 22 47944 -0.203355 0.336282 0.2254174 0.0017413 0.000160 -0.000298 0.000143 0.000118 0.0000184 0.0000260 0.000089 0.000109 1990 2 23 47945 -0.203373 0.339349 0.2236038 0.0019371 -0.000239 -0.000126 0.000144 0.000119 0.0000183 0.0000259 0.000089 0.000108 1990 2 24 47946 -0.202531 0.342917 0.2215414 0.0022140 -0.000768 -0.000026 0.000145 0.000120 0.0000183 0.0000258 0.000088 0.000107 1990 2 25 47947 -0.201007 0.346298 0.2191817 0.0024992 -0.000424 -0.000113 0.000146 0.000121 0.0000182 0.0000258 0.000088 0.000107 1990 2 26 47948 -0.199111 0.349955 0.2165622 0.0027060 -0.000080 -0.000201 0.000147 0.000122 0.0000182 0.0000257 0.000088 0.000107 1990 2 27 47949 -0.196508 0.353575 0.2138027 0.0027671 0.000263 -0.000288 0.000149 0.000123 0.0000181 0.0000256 0.000088 0.000106 1990 2 28 47950 -0.195071 0.358131 0.2110690 0.0026617 0.000324 -0.000283 0.000150 0.000123 0.0000180 0.0000254 0.000087 0.000106 1990 3 1 47951 -0.193399 0.362792 0.2085171 0.0024245 0.000292 -0.000248 0.000151 0.000124 0.0000178 0.0000252 0.000087 0.000105 1990 3 2 47952 -0.192756 0.367258 0.2062430 0.0021301 0.000254 -0.000259 0.000153 0.000124 0.0000177 0.0000250 0.000086 0.000104 1990 3 3 47953 -0.193285 0.371168 0.2042568 0.0018625 0.000214 -0.000274 0.000153 0.000124 0.0000176 0.0000249 0.000086 0.000104 1990 3 4 47954 -0.193682 0.374401 0.2024924 0.0016867 0.000175 -0.000288 0.000153 0.000123 0.0000175 0.0000247 0.000085 0.000103 1990 3 5 47955 -0.193371 0.377560 0.2008374 0.0016334 0.000153 -0.000239 0.000153 0.000122 0.0000173 0.0000244 0.000085 0.000102 1990 3 6 47956 -0.192166 0.380682 0.1991723 0.0017003 0.000135 -0.000169 0.000153 0.000120 0.0000171 0.0000242 0.000084 0.000102 1990 3 7 47957 -0.191595 0.384852 0.1973950 0.0018617 0.000118 -0.000099 0.000152 0.000118 0.0000169 0.0000239 0.000083 0.000101 1990 3 8 47958 -0.191520 0.388813 0.1954355 0.0020778 0.000100 -0.000029 0.000151 0.000116 0.0000167 0.0000237 0.000083 0.000100 1990 3 9 47959 -0.190999 0.392158 0.1932612 0.0023018 0.000081 -0.000188 0.000149 0.000114 0.0000166 0.0000234 0.000082 0.000099 1990 3 10 47960 -0.189432 0.396259 0.1908720 0.0024856 0.000072 -0.000228 0.000148 0.000111 0.0000164 0.0000232 0.000081 0.000098 1990 3 11 47961 -0.188271 0.400362 0.1883217 0.0025887 0.000066 -0.000219 0.000147 0.000109 0.0000163 0.0000230 0.000081 0.000098 1990 3 12 47962 -0.186958 0.403685 0.1857067 0.0025892 0.000061 -0.000210 0.000146 0.000106 0.0000161 0.0000228 0.000080 0.000097 1990 3 13 47963 -0.185946 0.407207 0.1831378 0.0024922 0.000055 -0.000200 0.000145 0.000104 0.0000159 0.0000226 0.000080 0.000096 1990 3 14 47964 -0.185230 0.411052 0.1807091 0.0023292 0.000050 -0.000191 0.000144 0.000102 0.0000158 0.0000223 0.000079 0.000096 1990 3 15 47965 -0.185152 0.414125 0.1784749 0.0021487 -0.000024 -0.000170 0.000143 0.000099 0.0000156 0.0000220 0.000078 0.000095 1990 3 16 47966 -0.185543 0.416493 0.1764557 0.0020000 -0.000087 -0.000228 0.000142 0.000097 0.0000154 0.0000217 0.000077 0.000094 1990 3 17 47967 -0.184750 0.418865 0.1745399 0.0019129 -0.000052 -0.000287 0.000142 0.000095 0.0000151 0.0000213 0.000077 0.000093 1990 3 18 47968 -0.184848 0.422082 0.1726235 0.0018911 0.000043 -0.000319 0.000141 0.000093 0.0000148 0.0000209 0.000076 0.000093 1990 3 19 47969 -0.183647 0.424761 0.1706833 0.0019263 0.000137 -0.000351 0.000140 0.000091 0.0000145 0.0000205 0.000075 0.000092 1990 3 20 47970 -0.181462 0.427512 0.1687050 0.0020160 0.000206 -0.000399 0.000139 0.000088 0.0000142 0.0000200 0.000074 0.000092 1990 3 21 47971 -0.179598 0.431428 0.1666286 0.0021663 0.000265 -0.000452 0.000137 0.000086 0.0000139 0.0000196 0.000072 0.000091 1990 3 22 47972 -0.177369 0.435052 0.1643626 0.0023808 0.000324 -0.000505 0.000135 0.000083 0.0000136 0.0000192 0.000071 0.000091 1990 3 23 47973 -0.174916 0.438977 0.1618333 0.0026469 0.000182 -0.000331 0.000133 0.000080 0.0000133 0.0000189 0.000070 0.000090 1990 3 24 47974 -0.172757 0.442906 0.1590624 0.0029289 0.000072 -0.000182 0.000132 0.000080 0.0000132 0.0000186 0.000070 0.000089 1990 3 25 47975 -0.170995 0.447040 0.1560307 0.0031655 0.000039 -0.000204 0.000133 0.000081 0.0000131 0.0000185 0.000069 0.000089 1990 3 26 47976 -0.168849 0.451278 0.1527868 0.0032826 0.000006 -0.000227 0.000133 0.000082 0.0000130 0.0000183 0.000069 0.000089 1990 3 27 47977 -0.167461 0.454839 0.1494978 0.0032274 -0.000027 -0.000249 0.000134 0.000083 0.0000128 0.0000182 0.000069 0.000089 1990 3 28 47978 -0.164523 0.457960 0.1463617 0.0030008 -0.000060 -0.000272 0.000134 0.000084 0.0000127 0.0000182 0.000068 0.000088 1990 3 29 47979 -0.162319 0.460382 0.1435342 0.0026646 0.000004 -0.000253 0.000134 0.000085 0.0000129 0.0000182 0.000069 0.000089 1990 3 30 47980 -0.160484 0.463098 0.1410369 0.0023151 0.000065 -0.000208 0.000135 0.000087 0.0000130 0.0000185 0.000069 0.000089 1990 3 31 47981 -0.158172 0.465723 0.1388582 0.0020459 0.000091 -0.000180 0.000136 0.000089 0.0000132 0.0000188 0.000070 0.000090 1990 4 1 47982 -0.156311 0.468152 0.1369041 0.0019169 0.000105 -0.000163 0.000138 0.000091 0.0000135 0.0000192 0.000071 0.000092 1990 4 2 47983 -0.153733 0.471820 0.1350093 0.0019369 0.000118 -0.000146 0.000139 0.000093 0.0000138 0.0000196 0.000072 0.000093 1990 4 3 47984 -0.152225 0.475232 0.1330219 0.0020684 0.000132 -0.000129 0.000140 0.000095 0.0000142 0.0000200 0.000073 0.000095 1990 4 4 47985 -0.148072 0.477614 0.1308485 0.0022503 -0.000025 -0.000087 0.000141 0.000097 0.0000145 0.0000204 0.000074 0.000096 1990 4 5 47986 -0.145623 0.480729 0.1284913 0.0024249 -0.000039 -0.000059 0.000140 0.000098 0.0000147 0.0000207 0.000074 0.000097 1990 4 6 47987 -0.143395 0.483789 0.1259928 0.0025542 0.000026 -0.000040 0.000140 0.000099 0.0000149 0.0000210 0.000075 0.000098 1990 4 7 47988 -0.138594 0.486550 0.1234059 0.0026210 0.000092 -0.000021 0.000140 0.000100 0.0000150 0.0000213 0.000075 0.000098 1990 4 8 47989 -0.136267 0.490158 0.1207890 0.0026225 0.000157 -0.000002 0.000139 0.000100 0.0000152 0.0000215 0.000075 0.000099 1990 4 9 47990 -0.132182 0.493208 0.1181981 0.0025637 0.000013 0.000043 0.000138 0.000101 0.0000153 0.0000217 0.000076 0.000099 1990 4 10 47991 -0.128196 0.496167 0.1156866 0.0024552 -0.000200 0.000097 0.000138 0.000102 0.0000154 0.0000218 0.000076 0.000099 1990 4 11 47992 -0.125316 0.499745 0.1132990 0.0023117 -0.000402 0.000144 0.000136 0.000102 0.0000155 0.0000219 0.000076 0.000099 1990 4 12 47993 -0.122717 0.502678 0.1110634 0.0021521 -0.000268 -0.000059 0.000136 0.000102 0.0000155 0.0000220 0.000077 0.000099 1990 4 13 47994 -0.120528 0.505982 0.1089879 0.0019973 -0.000007 -0.000261 0.000135 0.000102 0.0000157 0.0000221 0.000077 0.000100 1990 4 14 47995 -0.117958 0.509210 0.1070578 0.0018681 0.000184 -0.000357 0.000134 0.000102 0.0000157 0.0000222 0.000078 0.000100 1990 4 15 47996 -0.115671 0.511563 0.1052244 0.0017842 0.000171 -0.000297 0.000133 0.000102 0.0000157 0.0000222 0.000078 0.000100 1990 4 16 47997 -0.112854 0.514316 0.1034418 0.0017648 0.000066 -0.000176 0.000133 0.000102 0.0000156 0.0000221 0.000079 0.000100 1990 4 17 47998 -0.110514 0.516686 0.1016622 0.0018280 -0.000039 -0.000054 0.000132 0.000103 0.0000156 0.0000221 0.000079 0.000100 1990 4 18 47999 -0.107588 0.518540 0.0998038 0.0019837 0.000020 -0.000411 0.000131 0.000103 0.0000156 0.0000220 0.000079 0.000100 1990 4 19 48000 -0.105128 0.520467 0.0977081 0.0022197 0.000110 -0.000392 0.000131 0.000103 0.0000155 0.0000220 0.000079 0.000100 1990 4 20 48001 -0.102345 0.522956 0.0953303 0.0024975 0.000195 -0.000219 0.000130 0.000103 0.0000155 0.0000220 0.000079 0.000099 1990 4 21 48002 -0.099004 0.526438 0.0926889 0.0027591 0.000191 -0.000146 0.000129 0.000102 0.0000155 0.0000220 0.000080 0.000100 1990 4 22 48003 -0.097286 0.529456 0.0898328 0.0029378 0.000186 -0.000073 0.000128 0.000102 0.0000156 0.0000221 0.000080 0.000100 1990 4 23 48004 -0.095219 0.531191 0.0868724 0.0029743 0.000182 0.000000 0.000127 0.000101 0.0000156 0.0000221 0.000081 0.000100 1990 4 24 48005 -0.094102 0.533185 0.0839586 0.0028403 0.000134 -0.000237 0.000126 0.000101 0.0000156 0.0000220 0.000081 0.000100 1990 4 25 48006 -0.092513 0.535400 0.0812323 0.0025567 0.000021 -0.000320 0.000125 0.000101 0.0000155 0.0000219 0.000081 0.000099 1990 4 26 48007 -0.089214 0.536440 0.0788389 0.0021959 -0.000117 -0.000274 0.000124 0.000101 0.0000154 0.0000218 0.000081 0.000098 1990 4 27 48008 -0.087057 0.538527 0.0768436 0.0018563 -0.000228 -0.000301 0.000124 0.000101 0.0000153 0.0000217 0.000081 0.000097 1990 4 28 48009 -0.084747 0.540679 0.0750913 0.0016197 -0.000138 -0.000364 0.000123 0.000101 0.0000154 0.0000218 0.000081 0.000097 1990 4 29 48010 -0.082110 0.541454 0.0735124 0.0015242 -0.000076 -0.000369 0.000123 0.000102 0.0000155 0.0000219 0.000082 0.000098 1990 4 30 48011 -0.080092 0.543339 0.0719989 0.0015631 -0.000036 -0.000353 0.000123 0.000102 0.0000156 0.0000221 0.000083 0.000098 1990 5 1 48012 -0.078194 0.545419 0.0704065 0.0016962 0.000004 -0.000338 0.000122 0.000102 0.0000157 0.0000223 0.000083 0.000098 1990 5 2 48013 -0.075441 0.546639 0.0686377 0.0018668 0.000044 -0.000323 0.000121 0.000101 0.0000158 0.0000224 0.000084 0.000098 1990 5 3 48014 -0.072734 0.548224 0.0666691 0.0020223 -0.000032 -0.000307 0.000120 0.000100 0.0000160 0.0000226 0.000084 0.000099 1990 5 4 48015 -0.070069 0.549888 0.0645996 0.0021281 -0.000165 -0.000275 0.000120 0.000100 0.0000161 0.0000227 0.000085 0.000099 1990 5 5 48016 -0.065085 0.550701 0.0624522 0.0021670 -0.000109 -0.000292 0.000119 0.000099 0.0000162 0.0000228 0.000085 0.000099 1990 5 6 48017 -0.060398 0.552396 0.0602735 0.0021331 0.000047 -0.000335 0.000118 0.000098 0.0000162 0.0000229 0.000085 0.000099 1990 5 7 48018 -0.056218 0.554628 0.0581668 0.0020337 0.000203 -0.000378 0.000117 0.000097 0.0000162 0.0000229 0.000085 0.000099 1990 5 8 48019 -0.051442 0.556425 0.0562168 0.0018911 0.000241 -0.000193 0.000116 0.000096 0.0000162 0.0000229 0.000086 0.000099 1990 5 9 48020 -0.046858 0.557847 0.0544502 0.0017340 0.000154 -0.000119 0.000115 0.000096 0.0000162 0.0000229 0.000086 0.000099 1990 5 10 48021 -0.042561 0.559211 0.0527749 0.0015846 -0.000065 -0.000242 0.000115 0.000096 0.0000161 0.0000228 0.000086 0.000099 1990 5 11 48022 -0.038441 0.561091 0.0511967 0.0014622 -0.000320 -0.000420 0.000115 0.000095 0.0000161 0.0000227 0.000086 0.000099 1990 5 12 48023 -0.034431 0.562310 0.0497767 0.0013936 -0.000115 -0.000376 0.000115 0.000095 0.0000159 0.0000225 0.000085 0.000099 1990 5 13 48024 -0.031041 0.563674 0.0484349 0.0014066 0.000185 -0.000286 0.000115 0.000094 0.0000157 0.0000222 0.000085 0.000098 1990 5 14 48025 -0.026417 0.564366 0.0470210 0.0015088 0.000098 -0.000156 0.000114 0.000093 0.0000155 0.0000219 0.000084 0.000097 1990 5 15 48026 -0.022871 0.565660 0.0454190 0.0016808 -0.000118 -0.000013 0.000114 0.000092 0.0000152 0.0000217 0.000084 0.000095 1990 5 16 48027 -0.018023 0.567110 0.0435785 0.0018912 -0.000357 -0.000296 0.000113 0.000091 0.0000152 0.0000215 0.000084 0.000095 1990 5 17 48028 -0.012533 0.567336 0.0415540 0.0021160 -0.000250 -0.000232 0.000112 0.000089 0.0000152 0.0000216 0.000084 0.000095 1990 5 18 48029 -0.009499 0.568413 0.0393512 0.0023390 -0.000019 -0.000012 0.000111 0.000088 0.0000153 0.0000216 0.000084 0.000095 1990 5 19 48030 -0.004573 0.569122 0.0369392 0.0025331 0.000028 0.000004 0.000110 0.000086 0.0000153 0.0000217 0.000083 0.000095 1990 5 20 48031 -0.000558 0.570242 0.0343506 0.0026525 0.000014 -0.000048 0.000109 0.000084 0.0000153 0.0000217 0.000083 0.000094 1990 5 21 48032 0.003639 0.570909 0.0316866 0.0026491 0.000001 -0.000100 0.000108 0.000083 0.0000153 0.0000216 0.000083 0.000094 1990 5 22 48033 0.007867 0.571471 0.0290902 0.0025015 -0.000013 -0.000152 0.000107 0.000081 0.0000153 0.0000216 0.000083 0.000094 1990 5 23 48034 0.011442 0.571942 0.0267031 0.0022373 -0.000129 -0.000193 0.000105 0.000079 0.0000153 0.0000216 0.000083 0.000093 1990 5 24 48035 0.015115 0.572055 0.0246019 0.0019306 -0.000111 -0.000208 0.000104 0.000079 0.0000152 0.0000215 0.000083 0.000093 1990 5 25 48036 0.018510 0.572659 0.0227866 0.0016746 -0.000062 -0.000121 0.000104 0.000079 0.0000152 0.0000216 0.000083 0.000093 1990 5 26 48037 0.022822 0.572108 0.0211924 0.0015435 -0.000055 0.000022 0.000106 0.000081 0.0000153 0.0000217 0.000083 0.000094 1990 5 27 48038 0.026095 0.572398 0.0196774 0.0015611 -0.000063 0.000168 0.000109 0.000083 0.0000155 0.0000220 0.000084 0.000096 1990 5 28 48039 0.030405 0.572965 0.0180793 0.0016929 -0.000070 0.000315 0.000113 0.000086 0.0000157 0.0000223 0.000084 0.000097 1990 5 29 48040 0.032870 0.573728 0.0162956 0.0018679 -0.000191 0.000198 0.000116 0.000089 0.0000160 0.0000226 0.000085 0.000098 1990 5 30 48041 0.036393 0.574288 0.0143313 0.0020168 -0.000350 -0.000004 0.000119 0.000092 0.0000162 0.0000229 0.000086 0.000100 1990 5 31 48042 0.041835 0.574020 0.0122635 0.0020994 -0.000269 -0.000112 0.000122 0.000095 0.0000164 0.0000232 0.000087 0.000101 1990 6 1 48043 0.044228 0.574393 0.0101656 0.0021072 -0.000100 -0.000184 0.000125 0.000097 0.0000166 0.0000235 0.000087 0.000103 1990 6 2 48044 0.048383 0.574071 0.0080932 0.0020472 0.000069 -0.000257 0.000128 0.000100 0.0000168 0.0000237 0.000088 0.000104 1990 6 3 48045 0.052815 0.573904 0.0060946 0.0019284 0.000031 -0.000415 0.000131 0.000102 0.0000170 0.0000240 0.000089 0.000105 1990 6 4 48046 0.055759 0.575691 0.0042289 0.0017623 -0.000075 -0.000601 0.000133 0.000104 0.0000171 0.0000242 0.000089 0.000106 1990 6 5 48047 0.059563 0.576298 0.0025520 0.0015692 -0.000182 -0.000788 0.000135 0.000106 0.0000173 0.0000245 0.000090 0.000106 1990 6 6 48048 0.064325 0.574696 0.0010895 0.0013802 -0.000057 -0.000754 0.000137 0.000108 0.0000175 0.0000247 0.000090 0.000107 1990 6 7 48049 0.067965 0.574369 -0.0001943 0.0012284 0.000144 -0.000649 0.000139 0.000109 0.0000177 0.0000250 0.000091 0.000108 1990 6 8 48050 0.071453 0.573079 -0.0013746 0.0011390 0.000163 -0.000493 0.000141 0.000110 0.0000178 0.0000252 0.000091 0.000108 1990 6 9 48051 0.075885 0.572115 -0.0025106 0.0011256 0.000121 -0.000320 0.000142 0.000112 0.0000179 0.0000254 0.000091 0.000108 1990 6 10 48052 0.079106 0.571330 -0.0036542 0.0011912 -0.000053 -0.000344 0.000144 0.000112 0.0000181 0.0000255 0.000091 0.000108 1990 6 11 48053 0.082405 0.569280 -0.0048809 0.0013270 -0.000122 -0.000376 0.000144 0.000112 0.0000181 0.0000256 0.000091 0.000108 1990 6 12 48054 0.087250 0.568888 -0.0063154 0.0015095 0.000012 -0.000348 0.000145 0.000112 0.0000182 0.0000257 0.000091 0.000108 1990 6 13 48055 0.092162 0.568859 -0.0079465 0.0017079 0.000046 -0.000130 0.000145 0.000112 0.0000181 0.0000257 0.000091 0.000108 1990 6 14 48056 0.096455 0.568643 -0.0097544 0.0018937 0.000069 -0.000060 0.000145 0.000111 0.0000181 0.0000256 0.000090 0.000107 1990 6 15 48057 0.101009 0.567358 -0.0117223 0.0020419 0.000103 -0.000091 0.000146 0.000111 0.0000181 0.0000256 0.000090 0.000107 1990 6 16 48058 0.104261 0.568157 -0.0138026 0.0021271 0.000137 -0.000122 0.000146 0.000110 0.0000181 0.0000255 0.000090 0.000106 1990 6 17 48059 0.107627 0.567561 -0.0159243 0.0021257 0.000171 -0.000153 0.000146 0.000109 0.0000180 0.0000255 0.000090 0.000106 1990 6 18 48060 0.111619 0.565018 -0.0179979 0.0020245 0.000003 -0.000335 0.000146 0.000109 0.0000180 0.0000254 0.000089 0.000105 1990 6 19 48061 0.116469 0.565263 -0.0199337 0.0018338 -0.000233 -0.000567 0.000146 0.000107 0.0000179 0.0000253 0.000089 0.000104 1990 6 20 48062 0.120615 0.563692 -0.0216607 0.0015955 -0.000253 -0.000393 0.000145 0.000106 0.0000178 0.0000252 0.000089 0.000103 1990 6 21 48063 0.122707 0.562350 -0.0231386 0.0013753 -0.000141 -0.000380 0.000145 0.000104 0.0000177 0.0000251 0.000088 0.000102 1990 6 22 48064 0.127266 0.560980 -0.0244799 0.0012387 0.000013 -0.000335 0.000144 0.000102 0.0000177 0.0000250 0.000088 0.000102 1990 6 23 48065 0.130708 0.558738 -0.0256988 0.0012255 -0.000084 -0.000424 0.000143 0.000100 0.0000176 0.0000249 0.000087 0.000100 1990 6 24 48066 0.132860 0.556799 -0.0269388 0.0013316 -0.000098 -0.000383 0.000142 0.000100 0.0000176 0.0000249 0.000087 0.000100 1990 6 25 48067 0.137447 0.555175 -0.0283450 0.0015065 -0.000027 -0.000250 0.000142 0.000100 0.0000176 0.0000249 0.000087 0.000099 1990 6 26 48068 0.141359 0.553524 -0.0299444 0.0016778 0.000044 -0.000116 0.000141 0.000100 0.0000176 0.0000249 0.000087 0.000099 1990 6 27 48069 0.144068 0.551031 -0.0316917 0.0017877 0.000142 -0.000026 0.000141 0.000100 0.0000177 0.0000250 0.000087 0.000099 1990 6 28 48070 0.148700 0.549188 -0.0335058 0.0018132 0.000091 -0.000075 0.000141 0.000101 0.0000178 0.0000251 0.000088 0.000099 1990 6 29 48071 0.152651 0.547022 -0.0352975 0.0017637 -0.000013 -0.000168 0.000141 0.000102 0.0000179 0.0000253 0.000088 0.000099 1990 6 30 48072 0.155534 0.545456 -0.0369968 0.0016628 -0.000078 -0.000272 0.000141 0.000103 0.0000180 0.0000253 0.000089 0.000100 1990 7 1 48073 0.160668 0.543059 -0.0385690 0.0015305 -0.000132 -0.000379 0.000141 0.000105 0.0000179 0.0000254 0.000089 0.000101 1990 7 2 48074 0.165402 0.541912 -0.0400682 0.0013773 -0.000173 -0.000199 0.000142 0.000107 0.0000180 0.0000253 0.000090 0.000103 1990 7 3 48075 0.170428 0.541258 -0.0413876 0.0012172 -0.000070 -0.000533 0.000143 0.000109 0.0000178 0.0000253 0.000090 0.000104 1990 7 4 48076 0.174558 0.538939 -0.0425018 0.0010751 -0.000104 -0.000552 0.000144 0.000111 0.0000178 0.0000252 0.000091 0.000104 1990 7 5 48077 0.178205 0.537427 -0.0434908 0.0009732 -0.000228 -0.000324 0.000145 0.000112 0.0000179 0.0000253 0.000092 0.000106 1990 7 6 48078 0.181821 0.534848 -0.0444373 0.0009185 -0.000351 -0.000095 0.000146 0.000113 0.0000179 0.0000253 0.000092 0.000107 1990 7 7 48079 0.185069 0.533272 -0.0454021 0.0009082 -0.000112 -0.000077 0.000146 0.000115 0.0000179 0.0000253 0.000093 0.000107 1990 7 8 48080 0.188862 0.531000 -0.0463574 0.0009458 -0.000065 -0.000175 0.000147 0.000116 0.0000179 0.0000253 0.000093 0.000108 1990 7 9 48081 0.191314 0.527880 -0.0473257 0.0010440 -0.000105 -0.000296 0.000148 0.000118 0.0000179 0.0000253 0.000094 0.000109 1990 7 10 48082 0.195845 0.524583 -0.0483907 0.0012059 -0.000144 -0.000417 0.000149 0.000119 0.0000179 0.0000254 0.000094 0.000110 1990 7 11 48083 0.199115 0.521626 -0.0496482 0.0014037 0.000034 -0.000479 0.000149 0.000120 0.0000179 0.0000254 0.000095 0.000110 1990 7 12 48084 0.201770 0.521053 -0.0512011 0.0015800 0.000162 -0.000148 0.000149 0.000121 0.0000180 0.0000255 0.000096 0.000111 1990 7 13 48085 0.206335 0.518384 -0.0528783 0.0016784 0.000218 0.000067 0.000149 0.000121 0.0000181 0.0000256 0.000096 0.000112 1990 7 14 48086 0.209482 0.515600 -0.0545402 0.0016703 0.000256 0.000219 0.000150 0.000122 0.0000182 0.0000257 0.000097 0.000112 1990 7 15 48087 0.212833 0.513332 -0.0561337 0.0015542 0.000295 0.000155 0.000150 0.000122 0.0000182 0.0000258 0.000098 0.000113 1990 7 16 48088 0.215371 0.510669 -0.0575871 0.0013480 0.000332 -0.000060 0.000149 0.000122 0.0000182 0.0000258 0.000098 0.000113 1990 7 17 48089 0.218632 0.508542 -0.0588251 0.0010895 0.000370 -0.000275 0.000149 0.000122 0.0000182 0.0000257 0.000099 0.000113 1990 7 18 48090 0.222818 0.505723 -0.0598107 0.0008384 -0.000070 -0.000364 0.000148 0.000121 0.0000182 0.0000257 0.000099 0.000113 1990 7 19 48091 0.225844 0.503716 -0.0605495 0.0006661 -0.000257 -0.000366 0.000147 0.000121 0.0000181 0.0000256 0.000100 0.000113 1990 7 20 48092 0.228571 0.501542 -0.0611637 0.0006289 -0.000212 -0.000343 0.000147 0.000120 0.0000181 0.0000256 0.000100 0.000112 1990 7 21 48093 0.231609 0.498246 -0.0618372 0.0007391 -0.000166 -0.000180 0.000146 0.000120 0.0000180 0.0000255 0.000100 0.000112 1990 7 22 48094 0.234912 0.495451 -0.0626542 0.0009573 0.000025 -0.000227 0.000144 0.000119 0.0000180 0.0000253 0.000101 0.000113 1990 7 23 48095 0.237524 0.492713 -0.0637258 0.0012074 0.000101 -0.000336 0.000143 0.000118 0.0000178 0.0000251 0.000101 0.000113 1990 7 24 48096 0.240263 0.488887 -0.0650712 0.0014084 0.000131 -0.000451 0.000142 0.000118 0.0000176 0.0000249 0.000101 0.000112 1990 7 25 48097 0.243654 0.486019 -0.0665861 0.0015122 -0.000074 -0.000219 0.000141 0.000117 0.0000175 0.0000247 0.000102 0.000113 1990 7 26 48098 0.246736 0.483167 -0.0680843 0.0015220 -0.000097 -0.000007 0.000140 0.000117 0.0000173 0.0000244 0.000102 0.000114 1990 7 27 48099 0.250052 0.479364 -0.0695449 0.0014722 -0.000308 -0.000098 0.000140 0.000117 0.0000171 0.0000242 0.000103 0.000114 1990 7 28 48100 0.252860 0.476485 -0.0709604 0.0013937 -0.000309 -0.000117 0.000140 0.000117 0.0000170 0.0000240 0.000103 0.000115 1990 7 29 48101 0.255016 0.473156 -0.0723100 0.0012981 -0.000257 -0.000101 0.000140 0.000117 0.0000168 0.0000238 0.000104 0.000116 1990 7 30 48102 0.257947 0.469497 -0.0735734 0.0011849 -0.000224 -0.000089 0.000140 0.000117 0.0000167 0.0000236 0.000104 0.000117 1990 7 31 48103 0.259915 0.465951 -0.0747227 0.0010573 -0.000191 -0.000078 0.000140 0.000116 0.0000166 0.0000234 0.000105 0.000118 1990 8 1 48104 0.261627 0.462390 -0.0757374 0.0009336 -0.000238 -0.000050 0.000140 0.000116 0.0000164 0.0000232 0.000105 0.000118 1990 8 2 48105 0.263376 0.458509 -0.0766210 0.0008458 -0.000075 -0.000048 0.000140 0.000116 0.0000162 0.0000229 0.000106 0.000118 1990 8 3 48106 0.265394 0.454802 -0.0774215 0.0008272 0.000128 -0.000086 0.000140 0.000116 0.0000160 0.0000226 0.000106 0.000119 1990 8 4 48107 0.267429 0.451939 -0.0782754 0.0008971 0.000189 -0.000247 0.000140 0.000116 0.0000157 0.0000222 0.000106 0.000119 1990 8 5 48108 0.269162 0.448642 -0.0792516 0.0010561 -0.000006 0.000107 0.000139 0.000116 0.0000155 0.0000219 0.000107 0.000119 1990 8 6 48109 0.272552 0.445188 -0.0804039 0.0012870 -0.000330 0.000722 0.000139 0.000116 0.0000152 0.0000215 0.000107 0.000119 1990 8 7 48110 0.274720 0.441739 -0.0818088 0.0015537 -0.000342 0.000557 0.000138 0.000115 0.0000150 0.0000212 0.000107 0.000119 1990 8 8 48111 0.276654 0.438948 -0.0834972 0.0018028 -0.000245 0.000119 0.000138 0.000115 0.0000147 0.0000208 0.000107 0.000118 1990 8 9 48112 0.278788 0.435285 -0.0854297 0.0019790 -0.000277 0.000045 0.000137 0.000114 0.0000144 0.0000204 0.000107 0.000118 1990 8 10 48113 0.279999 0.431326 -0.0874410 0.0020458 -0.000274 0.000098 0.000136 0.000114 0.0000141 0.0000199 0.000106 0.000117 1990 8 11 48114 0.281650 0.429286 -0.0894310 0.0019954 -0.000233 0.000154 0.000136 0.000113 0.0000137 0.0000194 0.000106 0.000116 1990 8 12 48115 0.283841 0.425857 -0.0913731 0.0018436 -0.000371 -0.000306 0.000134 0.000112 0.0000133 0.0000188 0.000105 0.000114 1990 8 13 48116 0.285516 0.422564 -0.0931402 0.0016285 -0.000473 -0.000468 0.000133 0.000111 0.0000129 0.0000182 0.000105 0.000112 1990 8 14 48117 0.286329 0.420827 -0.0946586 0.0014093 -0.000528 -0.000397 0.000132 0.000109 0.0000125 0.0000176 0.000104 0.000110 1990 8 15 48118 0.288830 0.417520 -0.0959700 0.0012505 -0.000284 -0.000212 0.000130 0.000108 0.0000120 0.0000170 0.000103 0.000108 1990 8 16 48119 0.289157 0.413599 -0.0971874 0.0011999 0.000068 -0.000096 0.000129 0.000107 0.0000115 0.0000163 0.000102 0.000105 1990 8 17 48120 0.289337 0.410712 -0.0984144 0.0012752 -0.000175 0.000087 0.000127 0.000106 0.0000110 0.0000156 0.000101 0.000103 1990 8 18 48121 0.292535 0.407503 -0.0997679 0.0014582 -0.000335 0.000120 0.000125 0.000104 0.0000105 0.0000149 0.000100 0.000101 1990 8 19 48122 0.294010 0.403718 -0.1013412 0.0016997 -0.000349 0.000056 0.000123 0.000103 0.0000100 0.0000142 0.000099 0.000100 1990 8 20 48123 0.295899 0.400230 -0.1031605 0.0019351 -0.000362 -0.000009 0.000122 0.000101 0.0000096 0.0000136 0.000098 0.000099 1990 8 21 48124 0.298171 0.396588 -0.1051885 0.0021063 -0.000375 -0.000073 0.000120 0.000100 0.0000092 0.0000134 0.000097 0.000098 1990 8 22 48125 0.299934 0.393228 -0.1073410 0.0021801 -0.000165 -0.000104 0.000120 0.000100 0.0000093 0.0000134 0.000097 0.000099 1990 8 23 48126 0.302161 0.389908 -0.1095162 0.0021535 0.000121 -0.000125 0.000121 0.000101 0.0000097 0.0000137 0.000098 0.000100 1990 8 24 48127 0.303378 0.386451 -0.1116219 0.0020459 0.000051 -0.000256 0.000121 0.000102 0.0000100 0.0000141 0.000099 0.000101 1990 8 25 48128 0.304677 0.382728 -0.1135914 0.0018860 -0.000136 -0.000424 0.000122 0.000103 0.0000103 0.0000146 0.000100 0.000102 1990 8 26 48129 0.305149 0.379433 -0.1153871 0.0017010 -0.000323 -0.000592 0.000124 0.000104 0.0000106 0.0000150 0.000100 0.000103 1990 8 27 48130 0.305277 0.376309 -0.1169968 0.0015137 -0.000290 -0.000642 0.000125 0.000104 0.0000109 0.0000155 0.000101 0.000104 1990 8 28 48131 0.306085 0.372322 -0.1184293 0.0013442 -0.000182 -0.000653 0.000125 0.000105 0.0000113 0.0000160 0.000102 0.000105 1990 8 29 48132 0.305958 0.368494 -0.1197126 0.0012130 -0.000075 -0.000664 0.000127 0.000105 0.0000117 0.0000165 0.000102 0.000106 1990 8 30 48133 0.306388 0.364658 -0.1208930 0.0011420 0.000104 -0.000347 0.000127 0.000106 0.0000120 0.0000170 0.000103 0.000106 1990 8 31 48134 0.305841 0.361569 -0.1220343 0.0011526 0.000310 0.000091 0.000128 0.000107 0.0000124 0.0000175 0.000103 0.000106 1990 9 1 48135 0.305877 0.357552 -0.1232206 0.0012602 0.000383 0.000259 0.000129 0.000108 0.0000127 0.0000179 0.000103 0.000106 1990 9 2 48136 0.307425 0.353528 -0.1245559 0.0014653 0.000413 0.000338 0.000129 0.000108 0.0000130 0.0000184 0.000103 0.000106 1990 9 3 48137 0.308250 0.349866 -0.1261383 0.0017435 0.000442 0.000418 0.000129 0.000109 0.0000133 0.0000188 0.000104 0.000107 1990 9 4 48138 0.309586 0.345874 -0.1280254 0.0020417 0.000472 0.000498 0.000130 0.000109 0.0000137 0.0000193 0.000104 0.000107 1990 9 5 48139 0.310366 0.342776 -0.1302053 0.0022876 0.000502 0.000578 0.000129 0.000109 0.0000140 0.0000198 0.000104 0.000107 1990 9 6 48140 0.312374 0.337590 -0.1325876 0.0024122 0.000210 0.000532 0.000129 0.000109 0.0000144 0.0000204 0.000104 0.000107 1990 9 7 48141 0.312719 0.334042 -0.1350123 0.0023782 -0.000192 0.000444 0.000129 0.000109 0.0000148 0.0000210 0.000104 0.000108 1990 9 8 48142 0.312150 0.331190 -0.1373045 0.0021974 -0.000397 0.000241 0.000128 0.000108 0.0000153 0.0000216 0.000105 0.000110 1990 9 9 48143 0.313132 0.326961 -0.1393636 0.0019264 -0.000462 -0.000043 0.000128 0.000107 0.0000157 0.0000223 0.000105 0.000111 1990 9 10 48144 0.312900 0.322688 -0.1411699 0.0016461 -0.000099 0.000235 0.000127 0.000107 0.0000163 0.0000230 0.000107 0.000114 1990 9 11 48145 0.313234 0.317733 -0.1426875 0.0014372 0.000119 0.000296 0.000127 0.000107 0.0000168 0.0000237 0.000108 0.000116 1990 9 12 48146 0.312583 0.314459 -0.1440529 0.0013548 0.000074 -0.000020 0.000127 0.000107 0.0000172 0.0000242 0.000109 0.000117 1990 9 13 48147 0.312237 0.310207 -0.1454261 0.0014126 -0.000300 -0.000368 0.000128 0.000108 0.0000175 0.0000247 0.000110 0.000119 1990 9 14 48148 0.312193 0.306217 -0.1469199 0.0015851 -0.000704 -0.000545 0.000128 0.000108 0.0000177 0.0000251 0.000111 0.000119 1990 9 15 48149 0.311804 0.301969 -0.1486231 0.0018225 -0.000094 -0.000005 0.000129 0.000108 0.0000180 0.0000254 0.000111 0.000120 1990 9 16 48150 0.311050 0.297472 -0.1505696 0.0020655 0.000063 0.000161 0.000130 0.000108 0.0000182 0.0000257 0.000111 0.000120 1990 9 17 48151 0.309971 0.294299 -0.1527374 0.0022597 0.000069 0.000203 0.000131 0.000108 0.0000183 0.0000259 0.000112 0.000120 1990 9 18 48152 0.309406 0.290385 -0.1550588 0.0023670 0.000076 0.000246 0.000132 0.000108 0.0000185 0.0000262 0.000112 0.000119 1990 9 19 48153 0.308197 0.287272 -0.1574390 0.0023733 0.000083 0.000288 0.000133 0.000107 0.0000187 0.0000264 0.000112 0.000119 1990 9 20 48154 0.308502 0.283496 -0.1597801 0.0022889 0.000090 0.000331 0.000133 0.000107 0.0000189 0.0000266 0.000112 0.000119 1990 9 21 48155 0.307909 0.280081 -0.1620029 0.0021424 -0.000049 0.000283 0.000133 0.000106 0.0000189 0.0000268 0.000112 0.000118 1990 9 22 48156 0.306754 0.277092 -0.1640571 0.0019704 -0.000058 0.000249 0.000134 0.000105 0.0000190 0.0000269 0.000112 0.000117 1990 9 23 48157 0.305638 0.273765 -0.1659360 0.0018068 0.000028 0.000238 0.000134 0.000105 0.0000191 0.0000270 0.000111 0.000117 1990 9 24 48158 0.303875 0.270443 -0.1676697 0.0016767 0.000113 0.000227 0.000134 0.000104 0.0000192 0.0000271 0.000111 0.000116 1990 9 25 48159 0.301865 0.266830 -0.1693069 0.0015959 0.000199 0.000216 0.000134 0.000103 0.0000193 0.0000272 0.000111 0.000115 1990 9 26 48160 0.299989 0.262754 -0.1709028 0.0015744 0.000128 0.000048 0.000134 0.000102 0.0000193 0.0000273 0.000111 0.000115 1990 9 27 48161 0.299063 0.258100 -0.1724970 0.0016204 0.000135 0.000027 0.000135 0.000102 0.0000193 0.0000273 0.000110 0.000114 1990 9 28 48162 0.297216 0.254754 -0.1741582 0.0017386 0.000210 0.000109 0.000136 0.000102 0.0000192 0.0000272 0.000110 0.000114 1990 9 29 48163 0.297410 0.250372 -0.1759780 0.0019247 0.000247 0.000137 0.000136 0.000101 0.0000191 0.0000270 0.000109 0.000113 1990 9 30 48164 0.297005 0.246142 -0.1780199 0.0021611 0.000275 0.000155 0.000136 0.000100 0.0000190 0.0000268 0.000109 0.000112 1990 10 1 48165 0.295643 0.243333 -0.1803124 0.0024147 0.000210 0.000178 0.000136 0.000099 0.0000188 0.0000265 0.000108 0.000111 1990 10 2 48166 0.295562 0.240200 -0.1828456 0.0026382 0.000114 0.000204 0.000136 0.000098 0.0000185 0.0000262 0.000107 0.000110 1990 10 3 48167 0.295117 0.236336 -0.1855594 0.0027769 0.000018 0.000230 0.000135 0.000096 0.0000183 0.0000259 0.000106 0.000108 1990 10 4 48168 0.294530 0.232966 -0.1883453 0.0027847 -0.000020 0.000269 0.000134 0.000095 0.0000181 0.0000256 0.000105 0.000107 1990 10 5 48169 0.292521 0.230981 -0.1910876 0.0026467 -0.000040 0.000313 0.000132 0.000093 0.0000180 0.0000254 0.000104 0.000106 1990 10 6 48170 0.290680 0.227677 -0.1936676 0.0023975 0.000050 0.000054 0.000131 0.000091 0.0000179 0.0000254 0.000103 0.000105 1990 10 7 48171 0.288467 0.224272 -0.1958700 0.0021189 0.000206 0.000031 0.000130 0.000090 0.0000180 0.0000255 0.000103 0.000106 1990 10 8 48172 0.286577 0.220862 -0.1977836 0.0018985 0.000378 0.000183 0.000130 0.000091 0.0000183 0.0000258 0.000104 0.000108 1990 10 9 48173 0.284142 0.216860 -0.1996939 0.0017821 0.000386 -0.000017 0.000130 0.000092 0.0000184 0.0000260 0.000104 0.000109 1990 10 10 48174 0.281234 0.212650 -0.2015205 0.0017732 0.000111 -0.000019 0.000130 0.000093 0.0000184 0.0000261 0.000104 0.000109 1990 10 11 48175 0.280390 0.208662 -0.2033175 0.0018571 0.000009 0.000060 0.000129 0.000093 0.0000185 0.0000260 0.000104 0.000110 1990 10 12 48176 0.278639 0.205007 -0.2052154 0.0020056 0.000078 -0.000143 0.000129 0.000093 0.0000184 0.0000260 0.000103 0.000109 1990 10 13 48177 0.276076 0.200899 -0.2072814 0.0021770 0.000099 -0.000170 0.000129 0.000094 0.0000183 0.0000259 0.000103 0.000109 1990 10 14 48178 0.273468 0.197741 -0.2095301 0.0023238 0.000051 0.000035 0.000130 0.000095 0.0000183 0.0000259 0.000103 0.000109 1990 10 15 48179 0.270697 0.194312 -0.2119239 0.0024054 0.000004 0.000241 0.000130 0.000096 0.0000183 0.0000258 0.000103 0.000109 1990 10 16 48180 0.268167 0.190567 -0.2143747 0.0024025 -0.000248 0.000110 0.000131 0.000096 0.0000182 0.0000257 0.000103 0.000109 1990 10 17 48181 0.266042 0.187150 -0.2167069 0.0023237 -0.000568 -0.000133 0.000131 0.000096 0.0000181 0.0000256 0.000103 0.000109 1990 10 18 48182 0.263587 0.184284 -0.2189351 0.0021930 -0.000450 -0.000204 0.000131 0.000097 0.0000180 0.0000255 0.000103 0.000109 1990 10 19 48183 0.260807 0.181706 -0.2210743 0.0020350 -0.000147 -0.000188 0.000131 0.000097 0.0000179 0.0000254 0.000102 0.000109 1990 10 20 48184 0.257941 0.178318 -0.2230600 0.0018758 0.000144 0.000018 0.000131 0.000097 0.0000179 0.0000253 0.000102 0.000109 1990 10 21 48185 0.254720 0.175132 -0.2248469 0.0017473 -0.000034 -0.000091 0.000132 0.000098 0.0000179 0.0000252 0.000102 0.000109 1990 10 22 48186 0.251877 0.172603 -0.2265153 0.0016760 -0.000368 -0.000318 0.000133 0.000099 0.0000178 0.0000251 0.000101 0.000108 1990 10 23 48187 0.249078 0.169368 -0.2281972 0.0016705 -0.000253 -0.000333 0.000133 0.000099 0.0000176 0.0000249 0.000100 0.000107 1990 10 24 48188 0.247099 0.165154 -0.2299102 0.0017258 -0.000024 -0.000190 0.000134 0.000100 0.0000174 0.0000247 0.000100 0.000107 1990 10 25 48189 0.244978 0.162256 -0.2316958 0.0018361 0.000214 -0.000008 0.000135 0.000101 0.0000173 0.0000244 0.000099 0.000106 1990 10 26 48190 0.243245 0.159702 -0.2336250 0.0019982 -0.000045 -0.000050 0.000135 0.000101 0.0000171 0.0000243 0.000098 0.000105 1990 10 27 48191 0.242072 0.157020 -0.2357005 0.0022094 -0.000160 -0.000064 0.000137 0.000102 0.0000171 0.0000242 0.000098 0.000104 1990 10 28 48192 0.239292 0.154320 -0.2380001 0.0024565 -0.000122 -0.000027 0.000139 0.000104 0.0000172 0.0000243 0.000098 0.000105 1990 10 29 48193 0.237520 0.151551 -0.2406203 0.0027045 0.000244 0.000150 0.000140 0.000105 0.0000173 0.0000246 0.000098 0.000105 1990 10 30 48194 0.236249 0.149530 -0.2434339 0.0029043 0.000207 0.000247 0.000142 0.000107 0.0000176 0.0000248 0.000098 0.000107 1990 10 31 48195 0.233858 0.147223 -0.2463775 0.0030050 0.000191 0.000278 0.000143 0.000108 0.0000178 0.0000251 0.000099 0.000108 1990 11 1 48196 0.232046 0.145161 -0.2493811 0.0029668 0.000213 0.000296 0.000144 0.000109 0.0000180 0.0000254 0.000099 0.000109 1990 11 2 48197 0.229954 0.142376 -0.2522761 0.0027814 0.000224 0.000228 0.000145 0.000110 0.0000182 0.0000257 0.000099 0.000111 1990 11 3 48198 0.227688 0.139625 -0.2549188 0.0024888 0.000181 0.000103 0.000145 0.000111 0.0000184 0.0000260 0.000099 0.000112 1990 11 4 48199 0.225323 0.137734 -0.2572606 0.0021706 0.000139 -0.000022 0.000146 0.000111 0.0000187 0.0000263 0.000100 0.000114 1990 11 5 48200 0.222377 0.135607 -0.2593330 0.0019220 0.000097 -0.000112 0.000146 0.000111 0.0000188 0.0000266 0.000100 0.000115 1990 11 6 48201 0.218827 0.133175 -0.2611962 0.0018190 0.000056 -0.000190 0.000147 0.000112 0.0000190 0.0000269 0.000100 0.000117 1990 11 7 48202 0.214526 0.130621 -0.2629596 0.0018883 0.000015 -0.000268 0.000146 0.000111 0.0000191 0.0000271 0.000100 0.000118 1990 11 8 48203 0.210842 0.128498 -0.2649047 0.0020901 -0.000075 -0.000062 0.000146 0.000111 0.0000192 0.0000272 0.000100 0.000119 1990 11 9 48204 0.207337 0.126427 -0.2671511 0.0023367 0.000063 0.000185 0.000147 0.000111 0.0000194 0.0000274 0.000100 0.000120 1990 11 10 48205 0.204503 0.124930 -0.2696146 0.0025402 -0.000028 0.000535 0.000147 0.000112 0.0000195 0.0000275 0.000100 0.000121 1990 11 11 48206 0.201582 0.121776 -0.2722294 0.0026480 -0.000193 0.000918 0.000149 0.000113 0.0000196 0.0000276 0.000099 0.000121 1990 11 12 48207 0.198816 0.119040 -0.2749241 0.0026483 -0.000091 0.000811 0.000150 0.000114 0.0000195 0.0000275 0.000099 0.000122 1990 11 13 48208 0.196484 0.118234 -0.2775100 0.0025609 -0.000024 0.000471 0.000150 0.000114 0.0000194 0.0000274 0.000098 0.000122 1990 11 14 48209 0.193204 0.115153 -0.2799510 0.0024159 0.000028 0.000098 0.000150 0.000114 0.0000192 0.0000271 0.000097 0.000121 1990 11 15 48210 0.191088 0.112959 -0.2822975 0.0022355 0.000029 -0.000088 0.000151 0.000115 0.0000190 0.0000268 0.000097 0.000121 1990 11 16 48211 0.187148 0.111419 -0.2844695 0.0020383 0.000013 -0.000093 0.000151 0.000115 0.0000188 0.0000265 0.000096 0.000120 1990 11 17 48212 0.183285 0.108706 -0.2864159 0.0018523 -0.000003 -0.000042 0.000152 0.000114 0.0000186 0.0000263 0.000095 0.000119 1990 11 18 48213 0.181278 0.106579 -0.2881760 0.0017118 -0.000019 0.000009 0.000151 0.000114 0.0000184 0.0000260 0.000094 0.000119 1990 11 19 48214 0.177752 0.104830 -0.2898282 0.0016431 0.000035 0.000041 0.000151 0.000114 0.0000181 0.0000257 0.000094 0.000118 1990 11 20 48215 0.174803 0.103438 -0.2914701 0.0016555 0.000028 0.000026 0.000150 0.000114 0.0000179 0.0000254 0.000093 0.000118 1990 11 21 48216 0.171748 0.101287 -0.2931741 0.0017423 -0.000004 -0.000004 0.000150 0.000115 0.0000178 0.0000252 0.000093 0.000118 1990 11 22 48217 0.168759 0.100429 -0.2949885 0.0018887 -0.000024 0.000034 0.000150 0.000115 0.0000176 0.0000249 0.000092 0.000118 1990 11 23 48218 0.165916 0.099367 -0.2969640 0.0020769 -0.000040 0.000094 0.000150 0.000116 0.0000175 0.0000248 0.000092 0.000118 1990 11 24 48219 0.162611 0.096783 -0.2991434 0.0022862 -0.000057 0.000155 0.000150 0.000116 0.0000174 0.0000245 0.000091 0.000117 1990 11 25 48220 0.158939 0.096152 -0.3015447 0.0024927 -0.000078 0.000106 0.000150 0.000116 0.0000172 0.0000243 0.000091 0.000117 1990 11 26 48221 0.155555 0.094955 -0.3041398 0.0026692 -0.000101 0.000021 0.000150 0.000116 0.0000171 0.0000241 0.000090 0.000117 1990 11 27 48222 0.152682 0.092980 -0.3068641 0.0027862 -0.000124 -0.000064 0.000149 0.000116 0.0000169 0.0000239 0.000090 0.000116 1990 11 28 48223 0.148121 0.092080 -0.3096429 0.0028143 -0.000040 0.000369 0.000149 0.000116 0.0000167 0.0000235 0.000089 0.000116 1990 11 29 48224 0.143744 0.091323 -0.3124394 0.0027336 -0.000018 0.000434 0.000149 0.000117 0.0000164 0.0000231 0.000088 0.000114 1990 11 30 48225 0.139696 0.089769 -0.3151086 0.0025542 -0.000146 0.000239 0.000149 0.000117 0.0000160 0.0000229 0.000087 0.000113 1990 12 1 48226 0.135567 0.088348 -0.3175497 0.0023290 -0.000135 0.000188 0.000149 0.000118 0.0000160 0.0000227 0.000087 0.000113 1990 12 2 48227 0.132300 0.087681 -0.3197669 0.0021371 -0.000024 0.000245 0.000151 0.000119 0.0000161 0.0000228 0.000088 0.000113 1990 12 3 48228 0.128979 0.086125 -0.3218418 0.0020462 0.000087 0.000303 0.000153 0.000121 0.0000163 0.0000231 0.000088 0.000114 1990 12 4 48229 0.125843 0.085633 -0.3239019 0.0020787 0.000198 0.000360 0.000154 0.000122 0.0000165 0.0000232 0.000088 0.000115 1990 12 5 48230 0.122526 0.084981 -0.3260627 0.0022045 0.000414 0.000474 0.000156 0.000123 0.0000166 0.0000234 0.000088 0.000115 1990 12 6 48231 0.119350 0.082963 -0.3283665 0.0023622 0.000667 0.000607 0.000157 0.000123 0.0000166 0.0000234 0.000088 0.000114 1990 12 7 48232 0.115655 0.081606 -0.3307874 0.0024920 0.000643 0.000536 0.000158 0.000124 0.0000166 0.0000234 0.000088 0.000114 1990 12 8 48233 0.111071 0.080776 -0.3332855 0.0025563 0.000527 0.000397 0.000159 0.000123 0.0000165 0.0000234 0.000088 0.000113 1990 12 9 48234 0.108028 0.080492 -0.3358151 0.0025400 0.000412 0.000258 0.000158 0.000123 0.0000165 0.0000233 0.000088 0.000112 1990 12 10 48235 0.104608 0.079686 -0.3383181 0.0024418 0.000261 0.000230 0.000158 0.000122 0.0000164 0.0000231 0.000087 0.000110 1990 12 11 48236 0.101084 0.078701 -0.3407164 0.0022702 0.000097 0.000239 0.000158 0.000121 0.0000162 0.0000229 0.000087 0.000109 1990 12 12 48237 0.098706 0.077476 -0.3429243 0.0020487 -0.000048 0.000051 0.000158 0.000121 0.0000161 0.0000227 0.000086 0.000108 1990 12 13 48238 0.094857 0.076824 -0.3448367 0.0018177 -0.000063 0.000093 0.000158 0.000120 0.0000159 0.0000225 0.000086 0.000107 1990 12 14 48239 0.090465 0.076287 -0.3464870 0.0016207 -0.000006 0.000301 0.000158 0.000120 0.0000158 0.0000223 0.000086 0.000106 1990 12 15 48240 0.086226 0.074395 -0.3480159 0.0014827 0.000147 0.000478 0.000158 0.000119 0.0000156 0.0000223 0.000086 0.000104 1990 12 16 48241 0.083955 0.073560 -0.3494917 0.0014073 0.000244 0.000500 0.000158 0.000119 0.0000158 0.0000224 0.000086 0.000105 1990 12 17 48242 0.080927 0.072751 -0.3509290 0.0013931 0.000295 0.000449 0.000159 0.000119 0.0000160 0.0000227 0.000087 0.000105 1990 12 18 48243 0.076524 0.071277 -0.3523421 0.0014459 0.000346 0.000398 0.000160 0.000118 0.0000163 0.0000230 0.000088 0.000106 1990 12 19 48244 0.073842 0.070278 -0.3537836 0.0015704 0.000234 -0.000023 0.000161 0.000118 0.0000164 0.0000233 0.000089 0.000107 1990 12 20 48245 0.070715 0.069743 -0.3554270 0.0017526 -0.000070 -0.000126 0.000162 0.000119 0.0000167 0.0000237 0.000090 0.000108 1990 12 21 48246 0.069006 0.069268 -0.3573236 0.0019596 -0.000427 -0.000096 0.000165 0.000122 0.0000171 0.0000242 0.000091 0.000109 1990 12 22 48247 0.064947 0.068661 -0.3594089 0.0021585 -0.000347 -0.000159 0.000168 0.000125 0.0000174 0.0000246 0.000092 0.000110 1990 12 23 48248 0.059034 0.069559 -0.3616467 0.0023279 -0.000109 -0.000255 0.000169 0.000127 0.0000177 0.0000250 0.000093 0.000112 1990 12 24 48249 0.055343 0.069856 -0.3640200 0.0024512 0.000072 -0.000260 0.000171 0.000128 0.0000180 0.0000254 0.000094 0.000113 1990 12 25 48250 0.051878 0.067655 -0.3664907 0.0025081 0.000194 -0.000167 0.000172 0.000129 0.0000182 0.0000257 0.000095 0.000114 1990 12 26 48251 0.048559 0.067476 -0.3689883 0.0024770 0.000316 -0.000075 0.000172 0.000130 0.0000183 0.0000259 0.000096 0.000114 1990 12 27 48252 0.044177 0.069524 -0.3714206 0.0023506 0.000437 0.000018 0.000172 0.000129 0.0000185 0.0000261 0.000096 0.000115 1990 12 28 48253 0.040174 0.070062 -0.3736960 0.0021531 0.000330 0.000043 0.000172 0.000130 0.0000186 0.0000263 0.000097 0.000115 1990 12 29 48254 0.035204 0.070569 -0.3757554 0.0019446 0.000113 0.000037 0.000172 0.000131 0.0000187 0.0000263 0.000097 0.000116 1990 12 30 48255 0.030121 0.070694 -0.3776128 0.0018032 0.000143 0.000343 0.000172 0.000132 0.0000186 0.0000263 0.000098 0.000115 1990 12 31 48256 0.025551 0.069937 -0.3793804 0.0017887 0.000242 0.000684 0.000172 0.000133 0.0000186 0.0000263 0.000098 0.000115 1991 1 1 48257 0.021146 0.070127 0.6187785 0.0019473 0.000258 0.000579 0.000246 0.000204 0.0000146 0.0000207 0.000079 0.000072 1991 1 2 48258 0.018600 0.070580 0.6167176 0.0021949 0.000273 0.000468 0.000244 0.000203 0.0000145 0.0000205 0.000078 0.000072 1991 1 3 48259 0.015059 0.071429 0.6143742 0.0024480 0.000287 0.000358 0.000241 0.000202 0.0000143 0.0000203 0.000078 0.000072 1991 1 4 48260 0.011577 0.073111 0.6117903 0.0026240 0.000156 0.000283 0.000240 0.000201 0.0000142 0.0000200 0.000077 0.000072 1991 1 5 48261 0.009437 0.074164 0.6091360 0.0026889 0.000072 0.000283 0.000239 0.000201 0.0000140 0.0000198 0.000076 0.000072 1991 1 6 48262 0.005653 0.074388 0.6065096 0.0026555 0.000040 0.000316 0.000237 0.000200 0.0000138 0.0000195 0.000076 0.000072 1991 1 7 48263 0.003080 0.075738 0.6039076 0.0025511 0.000066 0.000290 0.000236 0.000199 0.0000136 0.0000192 0.000075 0.000071 1991 1 8 48264 0.000935 0.077721 0.6013777 0.0023987 0.000249 0.000100 0.000234 0.000198 0.0000133 0.0000189 0.000074 0.000071 1991 1 9 48265 -0.002358 0.079084 0.5990656 0.0022237 0.000324 -0.000082 0.000234 0.000197 0.0000131 0.0000186 0.000074 0.000072 1991 1 10 48266 -0.005430 0.079815 0.5969487 0.0020560 0.000242 -0.000051 0.000236 0.000197 0.0000130 0.0000183 0.000073 0.000072 1991 1 11 48267 -0.008442 0.080410 0.5949671 0.0019188 0.000044 0.000186 0.000238 0.000199 0.0000128 0.0000181 0.000073 0.000072 1991 1 12 48268 -0.012234 0.082278 0.5930925 0.0018265 0.000136 0.000203 0.000238 0.000199 0.0000126 0.0000178 0.000072 0.000073 1991 1 13 48269 -0.016988 0.083324 0.5912828 0.0017876 0.000288 0.000175 0.000238 0.000200 0.0000124 0.0000176 0.000072 0.000073 1991 1 14 48270 -0.020077 0.083207 0.5894877 0.0018052 0.000258 0.000136 0.000238 0.000200 0.0000123 0.0000175 0.000073 0.000074 1991 1 15 48271 -0.023389 0.084289 0.5876512 0.0018758 0.000166 0.000093 0.000238 0.000200 0.0000123 0.0000174 0.000073 0.000075 1991 1 16 48272 -0.027593 0.084445 0.5857218 0.0019877 0.000075 0.000050 0.000236 0.000200 0.0000122 0.0000173 0.000073 0.000076 1991 1 17 48273 -0.030737 0.084240 0.5836638 0.0021230 -0.000016 0.000007 0.000234 0.000199 0.0000122 0.0000172 0.000074 0.000077 1991 1 18 48274 -0.035109 0.085418 0.5814643 0.0022607 0.000148 -0.000080 0.000232 0.000197 0.0000121 0.0000170 0.000074 0.000077 1991 1 19 48275 -0.039510 0.085902 0.5791440 0.0023800 0.000228 -0.000076 0.000230 0.000196 0.0000118 0.0000167 0.000074 0.000077 1991 1 20 48276 -0.043421 0.085995 0.5767320 0.0024612 0.000263 -0.000038 0.000228 0.000195 0.0000116 0.0000164 0.000073 0.000077 1991 1 21 48277 -0.047954 0.086571 0.5742669 0.0024850 0.000298 -0.000001 0.000225 0.000193 0.0000114 0.0000161 0.000073 0.000077 1991 1 22 48278 -0.051396 0.087173 0.5718052 0.0024354 0.000333 0.000036 0.000222 0.000190 0.0000112 0.0000158 0.000073 0.000077 1991 1 23 48279 -0.053961 0.088162 0.5694177 0.0023087 0.000368 0.000074 0.000218 0.000187 0.0000110 0.0000155 0.000073 0.000077 1991 1 24 48280 -0.056336 0.089511 0.5671753 0.0021254 0.000123 -0.000046 0.000216 0.000185 0.0000108 0.0000152 0.000072 0.000077 1991 1 25 48281 -0.057791 0.091072 0.5651473 0.0019349 0.000019 -0.000100 0.000214 0.000183 0.0000105 0.0000149 0.000072 0.000077 1991 1 26 48282 -0.059425 0.092677 0.5633119 0.0018021 0.000036 -0.000090 0.000213 0.000182 0.0000103 0.0000145 0.000072 0.000077 1991 1 27 48283 -0.063001 0.094439 0.5615524 0.0017766 0.000054 -0.000081 0.000212 0.000180 0.0000100 0.0000142 0.000072 0.000077 1991 1 28 48284 -0.066652 0.096517 0.5597236 0.0018682 0.000071 -0.000072 0.000210 0.000178 0.0000099 0.0000139 0.000072 0.000076 1991 1 29 48285 -0.070081 0.097913 0.5577120 0.0020474 0.000141 -0.000389 0.000208 0.000175 0.0000096 0.0000136 0.000072 0.000076 1991 1 30 48286 -0.075081 0.099326 0.5555505 0.0022665 0.000256 -0.000440 0.000205 0.000172 0.0000093 0.0000132 0.000071 0.000076 1991 1 31 48287 -0.080043 0.101375 0.5532309 0.0024759 0.000386 -0.000302 0.000203 0.000169 0.0000091 0.0000131 0.000071 0.000075 1991 2 1 48288 -0.084234 0.102930 0.5507036 0.0026254 0.000327 -0.000102 0.000200 0.000165 0.0000091 0.0000130 0.000071 0.000075 1991 2 2 48289 -0.088422 0.104476 0.5480350 0.0026740 0.000205 0.000118 0.000198 0.000162 0.0000093 0.0000132 0.000071 0.000075 1991 2 3 48290 -0.092575 0.105721 0.5453614 0.0026096 0.000198 0.000173 0.000195 0.000159 0.0000095 0.0000134 0.000072 0.000075 1991 2 4 48291 -0.096596 0.106563 0.5428045 0.0024551 0.000229 0.000174 0.000194 0.000157 0.0000097 0.0000137 0.000072 0.000076 1991 2 5 48292 -0.100272 0.107722 0.5404438 0.0022553 0.000260 0.000174 0.000192 0.000154 0.0000099 0.0000140 0.000073 0.000076 1991 2 6 48293 -0.103452 0.109014 0.5383043 0.0020577 0.000241 0.000071 0.000189 0.000151 0.0000101 0.0000142 0.000073 0.000076 1991 2 7 48294 -0.106420 0.110756 0.5363476 0.0018969 0.000206 -0.000068 0.000186 0.000148 0.0000102 0.0000144 0.000074 0.000076 1991 2 8 48295 -0.109301 0.112006 0.5345039 0.0017908 0.000197 -0.000007 0.000183 0.000144 0.0000102 0.0000144 0.000074 0.000075 1991 2 9 48296 -0.111866 0.113322 0.5327299 0.0017470 0.000245 0.000026 0.000180 0.000141 0.0000102 0.0000145 0.000074 0.000074 1991 2 10 48297 -0.114543 0.115462 0.5309742 0.0017689 0.000316 0.000011 0.000177 0.000137 0.0000102 0.0000144 0.000073 0.000074 1991 2 11 48298 -0.117109 0.117327 0.5291675 0.0018557 0.000388 -0.000005 0.000174 0.000134 0.0000102 0.0000144 0.000073 0.000073 1991 2 12 48299 -0.120229 0.119783 0.5272433 0.0019988 0.000459 -0.000021 0.000171 0.000131 0.0000101 0.0000143 0.000073 0.000072 1991 2 13 48300 -0.124334 0.122451 0.5251505 0.0021810 0.000347 0.000002 0.000168 0.000127 0.0000101 0.0000144 0.000073 0.000071 1991 2 14 48301 -0.127399 0.124655 0.5228754 0.0023777 0.000148 -0.000121 0.000166 0.000125 0.0000102 0.0000144 0.000073 0.000071 1991 2 15 48302 -0.129974 0.127110 0.5204135 0.0025561 0.000068 -0.000169 0.000167 0.000126 0.0000103 0.0000146 0.000073 0.000071 1991 2 16 48303 -0.133408 0.129965 0.5177908 0.0026769 0.000083 -0.000107 0.000169 0.000128 0.0000105 0.0000148 0.000073 0.000071 1991 2 17 48304 -0.136841 0.133220 0.5150836 0.0027047 0.000098 -0.000046 0.000170 0.000129 0.0000106 0.0000150 0.000073 0.000071 1991 2 18 48305 -0.139901 0.136499 0.5123976 0.0026240 0.000022 -0.000051 0.000171 0.000131 0.0000107 0.0000152 0.000073 0.000071 1991 2 19 48306 -0.142881 0.139816 0.5098452 0.0024519 -0.000086 -0.000080 0.000172 0.000133 0.0000109 0.0000154 0.000073 0.000072 1991 2 20 48307 -0.145460 0.142988 0.5075069 0.0022372 -0.000193 -0.000109 0.000173 0.000135 0.0000110 0.0000156 0.000073 0.000072 1991 2 21 48308 -0.148239 0.146233 0.5053983 0.0020443 -0.000032 -0.000117 0.000173 0.000136 0.0000112 0.0000159 0.000073 0.000072 1991 2 22 48309 -0.151813 0.149635 0.5034452 0.0019289 0.000231 -0.000118 0.000174 0.000138 0.0000114 0.0000161 0.000074 0.000073 1991 2 23 48310 -0.154455 0.152489 0.5015217 0.0019204 0.000266 -0.000111 0.000175 0.000140 0.0000115 0.0000163 0.000074 0.000073 1991 2 24 48311 -0.157257 0.154747 0.4995290 0.0020207 0.000228 -0.000101 0.000176 0.000141 0.0000116 0.0000164 0.000074 0.000073 1991 2 25 48312 -0.160651 0.156946 0.4973997 0.0022117 0.000190 -0.000091 0.000178 0.000142 0.0000117 0.0000166 0.000074 0.000074 1991 2 26 48313 -0.162930 0.159375 0.4950845 0.0024578 0.000247 -0.000032 0.000179 0.000144 0.0000118 0.0000167 0.000074 0.000074 1991 2 27 48314 -0.165638 0.161721 0.4925156 0.0027048 0.000334 0.000044 0.000180 0.000146 0.0000118 0.0000167 0.000074 0.000074 1991 2 28 48315 -0.167632 0.165329 0.4896751 0.0028904 0.000348 0.000034 0.000182 0.000147 0.0000118 0.0000166 0.000074 0.000074 1991 3 1 48316 -0.169063 0.168790 0.4867554 0.0029719 0.000240 -0.000127 0.000183 0.000148 0.0000116 0.0000165 0.000073 0.000074 1991 3 2 48317 -0.171727 0.170600 0.4838305 0.0029362 0.000168 -0.000163 0.000183 0.000148 0.0000115 0.0000162 0.000073 0.000074 1991 3 3 48318 -0.173610 0.173567 0.4809446 0.0027896 0.000155 -0.000066 0.000183 0.000148 0.0000113 0.0000160 0.000073 0.000074 1991 3 4 48319 -0.175326 0.176722 0.4782298 0.0025538 0.000143 0.000031 0.000182 0.000148 0.0000111 0.0000157 0.000072 0.000074 1991 3 5 48320 -0.177378 0.179755 0.4757933 0.0022691 0.000156 0.000062 0.000182 0.000147 0.0000109 0.0000154 0.000072 0.000074 1991 3 6 48321 -0.179378 0.183159 0.4736686 0.0019889 0.000177 0.000071 0.000181 0.000146 0.0000106 0.0000151 0.000071 0.000074 1991 3 7 48322 -0.181900 0.186371 0.4718165 0.0017656 0.000199 0.000080 0.000179 0.000145 0.0000104 0.0000147 0.000070 0.000073 1991 3 8 48323 -0.184236 0.190266 0.4701469 0.0016369 0.000288 0.000015 0.000177 0.000144 0.0000102 0.0000144 0.000070 0.000073 1991 3 9 48324 -0.186415 0.193299 0.4685447 0.0016166 0.000398 -0.000072 0.000175 0.000143 0.0000100 0.0000141 0.000069 0.000073 1991 3 10 48325 -0.187996 0.196862 0.4668966 0.0016950 0.000439 -0.000087 0.000173 0.000142 0.0000097 0.0000138 0.000069 0.000073 1991 3 11 48326 -0.188946 0.200835 0.4651179 0.0018474 0.000456 -0.000078 0.000170 0.000140 0.0000095 0.0000134 0.000068 0.000073 1991 3 12 48327 -0.189768 0.204031 0.4631576 0.0020461 0.000473 -0.000069 0.000168 0.000138 0.0000093 0.0000131 0.000067 0.000073 1991 3 13 48328 -0.190620 0.208533 0.4609905 0.0022689 0.000384 -0.000048 0.000164 0.000136 0.0000090 0.0000128 0.000066 0.000072 1991 3 14 48329 -0.192315 0.212474 0.4586119 0.0024979 0.000256 -0.000023 0.000161 0.000134 0.0000088 0.0000124 0.000066 0.000072 1991 3 15 48330 -0.194362 0.216292 0.4560398 0.0027088 0.000189 -0.000082 0.000158 0.000131 0.0000085 0.0000123 0.000065 0.000072 1991 3 16 48331 -0.196081 0.220413 0.4532578 0.0028618 -0.000073 -0.000064 0.000158 0.000132 0.0000086 0.0000122 0.000065 0.000072 1991 3 17 48332 -0.197488 0.223653 0.4503430 0.0029115 -0.000145 -0.000072 0.000161 0.000135 0.0000088 0.0000125 0.000066 0.000072 1991 3 18 48333 -0.198930 0.227230 0.4474422 0.0028341 -0.000006 -0.000137 0.000164 0.000137 0.0000091 0.0000128 0.000066 0.000073 1991 3 19 48334 -0.200421 0.230570 0.4446862 0.0026475 0.000133 -0.000202 0.000167 0.000140 0.0000094 0.0000132 0.000066 0.000074 1991 3 20 48335 -0.201539 0.234081 0.4421638 0.0024062 0.000242 -0.000175 0.000169 0.000142 0.0000096 0.0000136 0.000067 0.000074 1991 3 21 48336 -0.202556 0.237590 0.4398826 0.0021794 0.000342 -0.000118 0.000171 0.000144 0.0000099 0.0000140 0.000067 0.000074 1991 3 22 48337 -0.203281 0.241261 0.4377789 0.0020257 0.000347 -0.000094 0.000173 0.000145 0.0000101 0.0000143 0.000067 0.000074 1991 3 23 48338 -0.204298 0.245194 0.4357664 0.0019809 0.000285 -0.000092 0.000174 0.000146 0.0000104 0.0000147 0.000067 0.000075 1991 3 24 48339 -0.205632 0.248680 0.4337539 0.0020566 0.000222 -0.000091 0.000174 0.000146 0.0000107 0.0000151 0.000067 0.000075 1991 3 25 48340 -0.206942 0.253426 0.4316432 0.0022383 0.000216 -0.000104 0.000176 0.000148 0.0000110 0.0000154 0.000067 0.000075 1991 3 26 48341 -0.209691 0.257656 0.4293200 0.0024810 0.000381 -0.000159 0.000177 0.000150 0.0000111 0.0000157 0.000067 0.000075 1991 3 27 48342 -0.212044 0.261050 0.4267200 0.0027136 0.000294 -0.000133 0.000178 0.000152 0.0000112 0.0000158 0.000067 0.000075 1991 3 28 48343 -0.213246 0.265531 0.4238967 0.0028631 0.000156 -0.000092 0.000178 0.000153 0.0000113 0.0000160 0.000067 0.000075 1991 3 29 48344 -0.215658 0.269613 0.4209841 0.0028872 0.000019 -0.000050 0.000179 0.000154 0.0000114 0.0000161 0.000066 0.000075 1991 3 30 48345 -0.217421 0.273274 0.4181330 0.0027910 0.000124 -0.000007 0.000180 0.000156 0.0000114 0.0000162 0.000066 0.000074 1991 3 31 48346 -0.218103 0.277077 0.4154425 0.0026169 0.000232 -0.000098 0.000182 0.000157 0.0000115 0.0000163 0.000065 0.000073 1991 4 1 48347 -0.218807 0.280960 0.4129458 0.0024177 0.000274 -0.000302 0.000184 0.000159 0.0000116 0.0000163 0.000065 0.000072 1991 4 2 48348 -0.218842 0.284777 0.4106281 0.0022326 0.000316 -0.000506 0.000187 0.000161 0.0000116 0.0000164 0.000065 0.000072 1991 4 3 48349 -0.219079 0.289200 0.4084543 0.0020819 0.000320 -0.000277 0.000189 0.000163 0.0000116 0.0000164 0.000065 0.000071 1991 4 4 48350 -0.218767 0.294352 0.4064097 0.0019769 0.000424 -0.000153 0.000190 0.000164 0.0000116 0.0000164 0.000065 0.000070 1991 4 5 48351 -0.218601 0.298400 0.4044698 0.0019277 0.000362 -0.000449 0.000192 0.000166 0.0000116 0.0000164 0.000065 0.000069 1991 4 6 48352 -0.219439 0.302162 0.4025658 0.0019394 0.000183 -0.000949 0.000194 0.000167 0.0000116 0.0000164 0.000065 0.000068 1991 4 7 48353 -0.219761 0.306257 0.4006101 0.0020022 0.000003 -0.001450 0.000195 0.000168 0.0000116 0.0000164 0.000065 0.000068 1991 4 8 48354 -0.220721 0.310183 0.3985360 0.0020944 0.000176 -0.000634 0.000195 0.000168 0.0000116 0.0000164 0.000066 0.000068 1991 4 9 48355 -0.220687 0.314584 0.3963181 0.0022021 0.000188 -0.000249 0.000196 0.000168 0.0000115 0.0000163 0.000066 0.000069 1991 4 10 48356 -0.220319 0.318514 0.3940393 0.0023342 0.000130 -0.000069 0.000195 0.000167 0.0000114 0.0000162 0.000066 0.000069 1991 4 11 48357 -0.221654 0.322428 0.3917652 0.0025049 0.000265 -0.000193 0.000195 0.000166 0.0000113 0.0000160 0.000067 0.000069 1991 4 12 48358 -0.220264 0.327213 0.3892182 0.0026826 0.000320 -0.000191 0.000193 0.000164 0.0000112 0.0000158 0.000067 0.000070 1991 4 13 48359 -0.218171 0.330759 0.3863767 0.0027867 0.000327 -0.000116 0.000191 0.000162 0.0000110 0.0000155 0.000067 0.000070 1991 4 14 48360 -0.217345 0.333918 0.3835430 0.0027534 0.000226 -0.000064 0.000188 0.000159 0.0000107 0.0000152 0.000067 0.000070 1991 4 15 48361 -0.215372 0.338242 0.3808887 0.0025844 0.000089 -0.000019 0.000185 0.000156 0.0000105 0.0000148 0.000067 0.000070 1991 4 16 48362 -0.214542 0.341673 0.3784550 0.0023365 -0.000031 0.000012 0.000183 0.000153 0.0000103 0.0000145 0.000067 0.000070 1991 4 17 48363 -0.213697 0.345242 0.3762324 0.0020888 0.000074 -0.000132 0.000182 0.000150 0.0000100 0.0000142 0.000067 0.000070 1991 4 18 48364 -0.212529 0.349862 0.3742175 0.0019178 0.000178 -0.000276 0.000180 0.000147 0.0000097 0.0000138 0.000067 0.000070 1991 4 19 48365 -0.212732 0.353823 0.3723488 0.0018784 0.000151 -0.000241 0.000179 0.000144 0.0000095 0.0000136 0.000067 0.000070 1991 4 20 48366 -0.212223 0.357916 0.3704525 0.0019826 0.000177 -0.000182 0.000181 0.000144 0.0000095 0.0000136 0.000067 0.000070 1991 4 21 48367 -0.211200 0.362077 0.3683745 0.0021935 0.000252 -0.000139 0.000185 0.000146 0.0000098 0.0000138 0.000067 0.000070 1991 4 22 48368 -0.210961 0.365749 0.3660486 0.0024438 0.000326 -0.000097 0.000189 0.000149 0.0000100 0.0000142 0.000067 0.000071 1991 4 23 48369 -0.211225 0.369472 0.3634820 0.0026652 0.000381 -0.000099 0.000192 0.000151 0.0000103 0.0000145 0.000068 0.000071 1991 4 24 48370 -0.211091 0.373455 0.3607366 0.0028081 0.000336 -0.000323 0.000195 0.000152 0.0000105 0.0000148 0.000068 0.000071 1991 4 25 48371 -0.211768 0.377812 0.3578971 0.0028482 0.000323 -0.000303 0.000198 0.000154 0.0000107 0.0000151 0.000068 0.000071 1991 4 26 48372 -0.212179 0.381817 0.3550680 0.0027861 0.000326 -0.000159 0.000202 0.000157 0.0000109 0.0000154 0.000068 0.000071 1991 4 27 48373 -0.209763 0.385325 0.3523482 0.0026432 0.000290 -0.000105 0.000205 0.000160 0.0000111 0.0000156 0.000068 0.000071 1991 4 28 48374 -0.208847 0.388532 0.3498017 0.0024544 0.000232 -0.000103 0.000208 0.000161 0.0000112 0.0000159 0.000068 0.000071 1991 4 29 48375 -0.209689 0.391742 0.3474510 0.0022572 0.000174 -0.000100 0.000209 0.000163 0.0000114 0.0000162 0.000069 0.000071 1991 4 30 48376 -0.209301 0.395242 0.3452844 0.0020823 0.000120 -0.000083 0.000212 0.000164 0.0000116 0.0000164 0.000069 0.000071 1991 5 1 48377 -0.208591 0.399236 0.3432667 0.0019500 0.000089 0.000012 0.000214 0.000165 0.0000117 0.0000166 0.000069 0.000071 1991 5 2 48378 -0.207159 0.403367 0.3413516 0.0018727 0.000057 0.000106 0.000215 0.000166 0.0000119 0.0000167 0.000069 0.000070 1991 5 3 48379 -0.205976 0.406257 0.3394846 0.0018589 0.000109 -0.000161 0.000216 0.000166 0.0000119 0.0000168 0.000068 0.000070 1991 5 4 48380 -0.204502 0.409817 0.3376105 0.0019140 0.000151 -0.000237 0.000217 0.000166 0.0000119 0.0000169 0.000068 0.000070 1991 5 5 48381 -0.202435 0.414480 0.3356578 0.0020357 0.000174 -0.000149 0.000218 0.000166 0.0000120 0.0000170 0.000068 0.000070 1991 5 6 48382 -0.201279 0.417559 0.3335513 0.0022082 0.000196 -0.000061 0.000217 0.000165 0.0000120 0.0000170 0.000068 0.000070 1991 5 7 48383 -0.199616 0.420868 0.3312391 0.0024033 0.000210 -0.000032 0.000216 0.000164 0.0000120 0.0000170 0.000068 0.000070 1991 5 8 48384 -0.197596 0.425474 0.3287183 0.0025888 0.000182 -0.000292 0.000215 0.000162 0.0000120 0.0000170 0.000068 0.000070 1991 5 9 48385 -0.195613 0.429113 0.3260468 0.0027375 0.000202 -0.000159 0.000216 0.000162 0.0000119 0.0000169 0.000068 0.000069 1991 5 10 48386 -0.193889 0.431979 0.3232727 0.0028268 0.000234 0.000076 0.000217 0.000162 0.0000119 0.0000168 0.000068 0.000068 1991 5 11 48387 -0.192250 0.435600 0.3204445 0.0028354 0.000258 0.000231 0.000217 0.000162 0.0000118 0.0000167 0.000067 0.000068 1991 5 12 48388 -0.189969 0.439686 0.3176454 0.0027498 0.000278 0.000331 0.000218 0.000162 0.0000117 0.0000166 0.000067 0.000067 1991 5 13 48389 -0.188331 0.443778 0.3149710 0.0025798 0.000284 0.000067 0.000218 0.000161 0.0000117 0.0000166 0.000067 0.000066 1991 5 14 48390 -0.186156 0.447859 0.3124933 0.0023665 0.000253 -0.000166 0.000217 0.000160 0.0000117 0.0000164 0.000066 0.000066 1991 5 15 48391 -0.183183 0.450940 0.3102239 0.0021710 0.000065 -0.000262 0.000217 0.000159 0.0000115 0.0000163 0.000066 0.000065 1991 5 16 48392 -0.180721 0.453686 0.3081042 0.0020497 0.000136 -0.000509 0.000217 0.000160 0.0000114 0.0000161 0.000065 0.000064 1991 5 17 48393 -0.177857 0.457095 0.3060577 0.0020309 0.000426 -0.000004 0.000215 0.000160 0.0000112 0.0000158 0.000064 0.000062 1991 5 18 48394 -0.174789 0.460409 0.3040003 0.0021049 0.000285 -0.000140 0.000214 0.000159 0.0000110 0.0000156 0.000064 0.000062 1991 5 19 48395 -0.171854 0.463831 0.3018537 0.0022300 -0.000009 -0.000521 0.000212 0.000158 0.0000108 0.0000153 0.000063 0.000061 1991 5 20 48396 -0.168652 0.467285 0.2995795 0.0023478 -0.000172 -0.000709 0.000209 0.000157 0.0000106 0.0000150 0.000063 0.000061 1991 5 21 48397 -0.165388 0.470010 0.2971973 0.0024048 -0.000025 -0.000430 0.000206 0.000156 0.0000104 0.0000147 0.000063 0.000061 1991 5 22 48398 -0.162671 0.472659 0.2947853 0.0023699 0.000036 -0.000257 0.000203 0.000154 0.0000102 0.0000146 0.000063 0.000062 1991 5 23 48399 -0.159891 0.475601 0.2924640 0.0022429 -0.000029 -0.000132 0.000204 0.000154 0.0000102 0.0000146 0.000063 0.000062 1991 5 24 48400 -0.156673 0.478082 0.2903177 0.0020491 -0.000136 -0.000022 0.000207 0.000157 0.0000105 0.0000148 0.000064 0.000063 1991 5 25 48401 -0.153710 0.480873 0.2883836 0.0018265 -0.000139 -0.000073 0.000210 0.000159 0.0000107 0.0000151 0.000064 0.000064 1991 5 26 48402 -0.150729 0.484199 0.2866690 0.0016149 -0.000105 -0.000180 0.000214 0.000161 0.0000109 0.0000155 0.000064 0.000065 1991 5 27 48403 -0.148133 0.486982 0.2851490 0.0014490 -0.000071 -0.000287 0.000216 0.000163 0.0000112 0.0000158 0.000065 0.000066 1991 5 28 48404 -0.145292 0.489923 0.2837678 0.0013525 -0.000006 -0.000428 0.000219 0.000165 0.0000115 0.0000161 0.000065 0.000067 1991 5 29 48405 -0.141913 0.492934 0.2824473 0.0013308 0.000212 -0.000738 0.000222 0.000166 0.0000116 0.0000165 0.000065 0.000067 1991 5 30 48406 -0.138989 0.495859 0.2810974 0.0013708 0.000430 -0.001047 0.000224 0.000167 0.0000118 0.0000166 0.000066 0.000068 1991 5 31 48407 -0.136022 0.498896 0.2796552 0.0014501 0.000592 -0.000672 0.000225 0.000167 0.0000119 0.0000168 0.000065 0.000068 1991 6 1 48408 -0.133148 0.501590 0.2781315 0.0015540 0.000516 -0.000409 0.000226 0.000167 0.0000119 0.0000168 0.000065 0.000068 1991 6 2 48409 -0.130203 0.504710 0.2765245 0.0016829 0.000319 -0.000343 0.000226 0.000166 0.0000119 0.0000168 0.000065 0.000068 1991 6 3 48410 -0.127879 0.507187 0.2747907 0.0018407 0.000122 -0.000278 0.000225 0.000165 0.0000118 0.0000167 0.000065 0.000068 1991 6 4 48411 -0.125533 0.509262 0.2728817 0.0020205 -0.000075 -0.000212 0.000224 0.000163 0.0000118 0.0000166 0.000065 0.000068 1991 6 5 48412 -0.121220 0.512128 0.2707698 0.0021978 0.000024 -0.000132 0.000225 0.000163 0.0000117 0.0000165 0.000064 0.000068 1991 6 6 48413 -0.117241 0.514192 0.2684813 0.0023382 0.000175 -0.000048 0.000225 0.000165 0.0000116 0.0000164 0.000064 0.000068 1991 6 7 48414 -0.113932 0.516601 0.2660871 0.0024101 0.000326 0.000035 0.000224 0.000166 0.0000115 0.0000163 0.000064 0.000068 1991 6 8 48415 -0.110642 0.519410 0.2636803 0.0023970 0.000284 -0.000040 0.000222 0.000166 0.0000115 0.0000163 0.000063 0.000069 1991 6 9 48416 -0.107852 0.521997 0.2613406 0.0023026 0.000168 -0.000175 0.000220 0.000166 0.0000115 0.0000162 0.000063 0.000069 1991 6 10 48417 -0.104143 0.525455 0.2591213 0.0021522 0.000053 -0.000309 0.000217 0.000165 0.0000114 0.0000161 0.000063 0.000069 1991 6 11 48418 -0.099877 0.527754 0.2570413 0.0019898 -0.000038 -0.000393 0.000214 0.000164 0.0000113 0.0000160 0.000063 0.000070 1991 6 12 48419 -0.095357 0.530087 0.2550883 0.0018679 -0.000004 -0.000224 0.000211 0.000162 0.0000112 0.0000158 0.000063 0.000069 1991 6 13 48420 -0.091749 0.533277 0.2532312 0.0018305 0.000004 -0.000239 0.000208 0.000162 0.0000110 0.0000156 0.000062 0.000069 1991 6 14 48421 -0.089258 0.535096 0.2513811 0.0018908 0.000007 -0.000300 0.000205 0.000161 0.0000109 0.0000154 0.000062 0.000069 1991 6 15 48422 -0.084889 0.537351 0.2494392 0.0020192 0.000023 -0.000257 0.000202 0.000160 0.0000108 0.0000152 0.000062 0.000069 1991 6 16 48423 -0.080473 0.539473 0.2473596 0.0021545 0.000043 -0.000178 0.000201 0.000160 0.0000106 0.0000151 0.000061 0.000069 1991 6 17 48424 -0.077744 0.540667 0.2451651 0.0022332 0.000063 -0.000099 0.000199 0.000159 0.0000105 0.0000149 0.000061 0.000069 1991 6 18 48425 -0.074524 0.542159 0.2429330 0.0022165 0.000060 -0.000035 0.000197 0.000158 0.0000104 0.0000147 0.000061 0.000069 1991 6 19 48426 -0.070934 0.543244 0.2407643 0.0021005 -0.000059 -0.000043 0.000195 0.000158 0.0000102 0.0000145 0.000061 0.000068 1991 6 20 48427 -0.067458 0.545164 0.2387512 0.0019083 -0.000177 -0.000050 0.000193 0.000157 0.0000101 0.0000142 0.000060 0.000068 1991 6 21 48428 -0.064240 0.546966 0.2369560 0.0016745 -0.000295 -0.000058 0.000191 0.000155 0.0000099 0.0000140 0.000060 0.000068 1991 6 22 48429 -0.061701 0.547875 0.2354051 0.0014318 -0.000176 -0.000113 0.000188 0.000154 0.0000097 0.0000138 0.000060 0.000068 1991 6 23 48430 -0.059364 0.549537 0.2340913 0.0012063 0.000065 -0.000191 0.000186 0.000152 0.0000096 0.0000136 0.000060 0.000068 1991 6 24 48431 -0.056835 0.550659 0.2329833 0.0010175 0.000306 -0.000269 0.000183 0.000151 0.0000095 0.0000134 0.000060 0.000068 1991 6 25 48432 -0.053840 0.552374 0.2320337 0.0008802 0.000455 -0.000356 0.000180 0.000148 0.0000094 0.0000132 0.000060 0.000068 1991 6 26 48433 -0.050130 0.554757 0.2311901 0.0008054 0.000149 -0.000492 0.000176 0.000146 0.0000092 0.0000130 0.000060 0.000068 1991 6 27 48434 -0.046062 0.555736 0.2304019 0.0007986 0.000184 -0.000471 0.000173 0.000143 0.0000090 0.0000128 0.000060 0.000068 1991 6 28 48435 -0.042873 0.557502 0.2295804 0.0008562 0.000219 -0.000429 0.000169 0.000140 0.0000088 0.0000125 0.000060 0.000067 1991 6 29 48436 -0.040214 0.559838 0.2286829 0.0009645 0.000090 -0.000325 0.000165 0.000136 0.0000086 0.0000123 0.000059 0.000067 1991 6 30 48437 -0.036916 0.560888 0.2276433 0.0011037 0.000057 -0.000191 0.000163 0.000136 0.0000086 0.0000123 0.000059 0.000066 1991 7 1 48438 -0.033026 0.561782 0.2264507 0.0012534 0.000076 -0.000103 0.000164 0.000137 0.0000088 0.0000124 0.000060 0.000067 1991 7 2 48439 -0.029086 0.562790 0.2251443 0.0013970 0.000018 -0.000090 0.000164 0.000138 0.0000089 0.0000126 0.000060 0.000067 1991 7 3 48440 -0.026458 0.563919 0.2237190 0.0015146 0.000115 -0.000130 0.000164 0.000139 0.0000090 0.0000127 0.000060 0.000068 1991 7 4 48441 -0.022818 0.565542 0.2221542 0.0015749 0.000750 -0.000478 0.000164 0.000140 0.0000090 0.0000128 0.000060 0.000068 1991 7 5 48442 -0.017456 0.566535 0.2205518 0.0015475 0.001174 -0.000682 0.000164 0.000140 0.0000091 0.0000128 0.000060 0.000068 1991 7 6 48443 -0.013760 0.566927 0.2190502 0.0014251 0.000992 -0.000501 0.000162 0.000139 0.0000090 0.0000128 0.000060 0.000067 1991 7 7 48444 -0.009720 0.567860 0.2177262 0.0012335 0.000811 -0.000321 0.000161 0.000139 0.0000090 0.0000127 0.000060 0.000067 1991 7 8 48445 -0.005473 0.568702 0.2166088 0.0010259 0.000629 -0.000140 0.000158 0.000137 0.0000090 0.0000127 0.000060 0.000067 1991 7 9 48446 -0.002085 0.569325 0.2156645 0.0008695 0.000427 0.000014 0.000156 0.000136 0.0000090 0.0000126 0.000060 0.000066 1991 7 10 48447 0.001876 0.569740 0.2148193 0.0008259 0.000122 0.000040 0.000154 0.000134 0.0000089 0.0000125 0.000060 0.000066 1991 7 11 48448 0.005215 0.569681 0.2139802 0.0009268 0.000012 -0.000200 0.000151 0.000133 0.0000088 0.0000126 0.000059 0.000065 1991 7 12 48449 0.009598 0.569805 0.2129273 0.0011530 0.000038 -0.000265 0.000151 0.000133 0.0000090 0.0000127 0.000060 0.000065 1991 7 13 48450 0.013865 0.569730 0.2116301 0.0014395 -0.000033 -0.000280 0.000152 0.000135 0.0000092 0.0000131 0.000060 0.000065 1991 7 14 48451 0.017033 0.570138 0.2101131 0.0017027 -0.000107 -0.000259 0.000152 0.000136 0.0000095 0.0000134 0.000061 0.000066 1991 7 15 48452 0.021615 0.571550 0.2083032 0.0018641 -0.000053 -0.000111 0.000152 0.000137 0.0000097 0.0000138 0.000061 0.000066 1991 7 16 48453 0.026605 0.572531 0.2063600 0.0018805 -0.000011 0.000003 0.000151 0.000137 0.0000100 0.0000141 0.000062 0.000066 1991 7 17 48454 0.031851 0.572796 0.2045477 0.0017672 -0.000027 -0.000045 0.000150 0.000137 0.0000102 0.0000144 0.000062 0.000066 1991 7 18 48455 0.035965 0.572780 0.2029027 0.0015752 -0.000092 -0.000072 0.000149 0.000138 0.0000104 0.0000147 0.000062 0.000066 1991 7 19 48456 0.040210 0.572732 0.2014270 0.0013519 -0.000170 -0.000095 0.000148 0.000139 0.0000106 0.0000150 0.000062 0.000066 1991 7 20 48457 0.046034 0.572230 0.2001316 0.0011317 -0.000168 -0.000041 0.000148 0.000141 0.0000108 0.0000153 0.000063 0.000066 1991 7 21 48458 0.050218 0.572077 0.1991118 0.0009486 -0.000096 0.000009 0.000151 0.000143 0.0000110 0.0000156 0.000063 0.000066 1991 7 22 48459 0.054180 0.572805 0.1982929 0.0008332 0.000016 0.000044 0.000153 0.000146 0.0000112 0.0000159 0.000063 0.000066 1991 7 23 48460 0.059054 0.572770 0.1974561 0.0007936 0.000029 -0.000219 0.000156 0.000149 0.0000114 0.0000161 0.000064 0.000066 1991 7 24 48461 0.064192 0.572833 0.1966296 0.0008211 -0.000223 -0.000094 0.000159 0.000151 0.0000116 0.0000164 0.000064 0.000066 1991 7 25 48462 0.068912 0.572775 0.1957810 0.0009060 -0.000253 0.000032 0.000162 0.000154 0.0000118 0.0000167 0.000064 0.000066 1991 7 26 48463 0.073299 0.571386 0.1948161 0.0010351 -0.000111 0.000037 0.000164 0.000156 0.0000120 0.0000169 0.000064 0.000066 1991 7 27 48464 0.077887 0.570840 0.1936997 0.0011874 0.000007 -0.000073 0.000167 0.000159 0.0000121 0.0000172 0.000064 0.000066 1991 7 28 48465 0.081046 0.570896 0.1924451 0.0013373 0.000118 -0.000223 0.000170 0.000161 0.0000123 0.0000174 0.000064 0.000066 1991 7 29 48466 0.085252 0.570341 0.1910751 0.0014563 -0.000164 0.000113 0.000173 0.000163 0.0000124 0.0000176 0.000064 0.000066 1991 7 30 48467 0.089570 0.570325 0.1895095 0.0015159 -0.000096 0.000017 0.000175 0.000165 0.0000126 0.0000178 0.000065 0.000067 1991 7 31 48468 0.092130 0.570230 0.1879838 0.0015067 0.000041 -0.000271 0.000177 0.000166 0.0000127 0.0000180 0.000065 0.000067 1991 8 1 48469 0.095687 0.569315 0.1865646 0.0014428 0.000101 -0.000372 0.000179 0.000167 0.0000128 0.0000181 0.000065 0.000067 1991 8 2 48470 0.098575 0.568808 0.1852011 0.0013376 0.000126 -0.000364 0.000180 0.000167 0.0000129 0.0000182 0.000065 0.000068 1991 8 3 48471 0.101202 0.567776 0.1838992 0.0011958 0.000156 -0.000159 0.000181 0.000166 0.0000129 0.0000183 0.000065 0.000068 1991 8 4 48472 0.104701 0.565399 0.1827618 0.0010339 0.000229 0.000007 0.000181 0.000165 0.0000130 0.0000183 0.000065 0.000068 1991 8 5 48473 0.107802 0.564159 0.1818100 0.0008939 0.000217 0.000021 0.000181 0.000164 0.0000130 0.0000183 0.000065 0.000068 1991 8 6 48474 0.111449 0.563433 0.1809643 0.0008299 0.000096 -0.000007 0.000181 0.000162 0.0000130 0.0000183 0.000065 0.000069 1991 8 7 48475 0.115645 0.561564 0.1801192 0.0008820 -0.000182 0.000093 0.000181 0.000160 0.0000129 0.0000182 0.000065 0.000068 1991 8 8 48476 0.118876 0.560195 0.1791598 0.0010559 -0.000191 -0.000048 0.000180 0.000158 0.0000128 0.0000181 0.000064 0.000068 1991 8 9 48477 0.121401 0.559141 0.1779809 0.0013140 -0.000139 -0.000240 0.000180 0.000157 0.0000128 0.0000180 0.000064 0.000068 1991 8 10 48478 0.125612 0.557543 0.1765286 0.0015870 -0.000123 -0.000157 0.000180 0.000155 0.0000127 0.0000179 0.000063 0.000067 1991 8 11 48479 0.129677 0.556063 0.1748281 0.0018007 -0.000121 0.000023 0.000179 0.000153 0.0000126 0.0000178 0.000063 0.000067 1991 8 12 48480 0.132595 0.554859 0.1729696 0.0019071 -0.000119 0.000203 0.000177 0.000150 0.0000125 0.0000176 0.000062 0.000067 1991 8 13 48481 0.136756 0.553473 0.1710692 0.0018992 -0.000163 0.000407 0.000176 0.000148 0.0000124 0.0000174 0.000062 0.000066 1991 8 14 48482 0.140585 0.552081 0.1692264 0.0018026 -0.000439 0.000725 0.000175 0.000146 0.0000122 0.0000173 0.000061 0.000066 1991 8 15 48483 0.143653 0.550798 0.1674982 0.0016526 -0.000480 0.000625 0.000173 0.000144 0.0000120 0.0000170 0.000061 0.000065 1991 8 16 48484 0.146643 0.548754 0.1659105 0.0014777 -0.000440 0.000382 0.000171 0.000141 0.0000119 0.0000168 0.000060 0.000064 1991 8 17 48485 0.149691 0.547207 0.1644778 0.0012996 0.000083 0.000361 0.000169 0.000138 0.0000118 0.0000166 0.000059 0.000063 1991 8 18 48486 0.152561 0.545951 0.1632556 0.0011455 0.000180 0.000420 0.000168 0.000136 0.0000116 0.0000164 0.000058 0.000062 1991 8 19 48487 0.154241 0.543326 0.1622060 0.0010460 -0.000030 0.000475 0.000166 0.000134 0.0000115 0.0000162 0.000058 0.000061 1991 8 20 48488 0.156590 0.541137 0.1611982 0.0010185 -0.000253 0.000479 0.000164 0.000131 0.0000113 0.0000159 0.000057 0.000060 1991 8 21 48489 0.159611 0.539009 0.1601310 0.0010612 -0.000541 0.000224 0.000163 0.000129 0.0000110 0.0000156 0.000056 0.000059 1991 8 22 48490 0.161641 0.536696 0.1590000 0.0011657 -0.000172 -0.000044 0.000161 0.000126 0.0000108 0.0000155 0.000055 0.000058 1991 8 23 48491 0.163644 0.534861 0.1577897 0.0013261 0.000170 -0.000152 0.000160 0.000124 0.0000108 0.0000154 0.000054 0.000057 1991 8 24 48492 0.166304 0.532328 0.1563862 0.0015286 -0.000120 -0.000168 0.000159 0.000123 0.0000109 0.0000155 0.000054 0.000056 1991 8 25 48493 0.169441 0.530239 0.1547403 0.0017425 -0.000360 -0.000139 0.000159 0.000122 0.0000111 0.0000156 0.000053 0.000055 1991 8 26 48494 0.172334 0.527955 0.1529043 0.0019282 -0.000219 -0.000082 0.000158 0.000121 0.0000112 0.0000158 0.000053 0.000054 1991 8 27 48495 0.174057 0.526040 0.1509456 0.0020463 -0.000038 -0.000033 0.000159 0.000122 0.0000112 0.0000158 0.000052 0.000053 1991 8 28 48496 0.176572 0.524793 0.1488246 0.0020645 0.000175 0.000010 0.000159 0.000124 0.0000112 0.0000158 0.000052 0.000052 1991 8 29 48497 0.180855 0.521540 0.1467338 0.0019804 0.000387 0.000052 0.000160 0.000125 0.0000112 0.0000158 0.000052 0.000051 1991 8 30 48498 0.183389 0.519578 0.1448748 0.0018374 0.000086 -0.000353 0.000160 0.000127 0.0000111 0.0000157 0.000051 0.000050 1991 8 31 48499 0.184587 0.518375 0.1431720 0.0016966 0.000007 -0.000311 0.000160 0.000128 0.0000110 0.0000155 0.000051 0.000049 1991 9 1 48500 0.187106 0.515608 0.1415242 0.0016000 0.000095 0.000013 0.000160 0.000129 0.0000108 0.0000154 0.000051 0.000049 1991 9 2 48501 0.189945 0.513956 0.1399087 0.0015692 -0.000069 0.000082 0.000159 0.000129 0.0000107 0.0000152 0.000051 0.000050 1991 9 3 48502 0.192403 0.511427 0.1382947 0.0016209 -0.000225 0.000135 0.000159 0.000130 0.0000106 0.0000149 0.000052 0.000051 1991 9 4 48503 0.194984 0.508766 0.1366182 0.0017665 -0.000342 0.000105 0.000157 0.000129 0.0000104 0.0000147 0.000052 0.000051 1991 9 5 48504 0.198250 0.507247 0.1347638 0.0019954 -0.000460 0.000076 0.000156 0.000129 0.0000102 0.0000145 0.000053 0.000052 1991 9 6 48505 0.201408 0.504687 0.1326382 0.0022617 -0.000254 0.000067 0.000155 0.000128 0.0000101 0.0000142 0.000053 0.000053 1991 9 7 48506 0.204354 0.502890 0.1302386 0.0024963 -0.000131 0.000002 0.000154 0.000128 0.0000099 0.0000142 0.000054 0.000054 1991 9 8 48507 0.207352 0.501200 0.1276630 0.0026377 -0.000323 -0.000109 0.000155 0.000130 0.0000100 0.0000142 0.000054 0.000054 1991 9 9 48508 0.209913 0.498469 0.1250193 0.0026568 -0.000675 -0.000231 0.000157 0.000132 0.0000102 0.0000144 0.000054 0.000055 1991 9 10 48509 0.212498 0.496409 0.1223951 0.0025620 -0.000370 0.000163 0.000160 0.000135 0.0000104 0.0000147 0.000055 0.000056 1991 9 11 48510 0.214693 0.494442 0.1199198 0.0023906 -0.000338 0.000321 0.000162 0.000138 0.0000105 0.0000149 0.000055 0.000057 1991 9 12 48511 0.216454 0.491927 0.1176465 0.0021878 -0.000447 0.000361 0.000164 0.000140 0.0000106 0.0000150 0.000056 0.000058 1991 9 13 48512 0.217208 0.489389 0.1155561 0.0019849 -0.000556 0.000400 0.000166 0.000143 0.0000108 0.0000152 0.000056 0.000058 1991 9 14 48513 0.218213 0.486692 0.1136208 0.0017967 -0.000517 0.000216 0.000168 0.000145 0.0000109 0.0000154 0.000056 0.000059 1991 9 15 48514 0.220168 0.483670 0.1118826 0.0016391 -0.000346 0.000085 0.000169 0.000147 0.0000110 0.0000155 0.000057 0.000060 1991 9 16 48515 0.220722 0.480970 0.1103216 0.0015387 -0.000136 0.000023 0.000170 0.000148 0.0000111 0.0000156 0.000057 0.000061 1991 9 17 48516 0.222632 0.478105 0.1088301 0.0015188 0.000039 -0.000025 0.000171 0.000149 0.0000111 0.0000157 0.000057 0.000061 1991 9 18 48517 0.225883 0.474803 0.1072948 0.0015825 0.000036 0.000003 0.000171 0.000149 0.0000111 0.0000157 0.000057 0.000062 1991 9 19 48518 0.227903 0.471966 0.1056439 0.0017116 0.000032 0.000030 0.000171 0.000150 0.0000111 0.0000157 0.000057 0.000062 1991 9 20 48519 0.229869 0.469045 0.1038381 0.0018788 0.000028 0.000058 0.000171 0.000150 0.0000111 0.0000157 0.000057 0.000062 1991 9 21 48520 0.231753 0.465880 0.1018655 0.0020598 -0.000049 0.000091 0.000172 0.000151 0.0000111 0.0000156 0.000057 0.000062 1991 9 22 48521 0.233590 0.462912 0.0997252 0.0022353 -0.000154 0.000126 0.000172 0.000151 0.0000110 0.0000156 0.000058 0.000063 1991 9 23 48522 0.234811 0.459988 0.0974275 0.0023860 -0.000259 0.000161 0.000172 0.000151 0.0000110 0.0000156 0.000058 0.000063 1991 9 24 48523 0.237037 0.457240 0.0950022 0.0024870 -0.000340 0.000179 0.000173 0.000151 0.0000110 0.0000155 0.000058 0.000063 1991 9 25 48524 0.240163 0.455011 0.0925032 0.0025111 -0.000303 0.000108 0.000172 0.000151 0.0000109 0.0000154 0.000058 0.000062 1991 9 26 48525 0.241888 0.452972 0.0900063 0.0024418 -0.000266 0.000037 0.000172 0.000150 0.0000108 0.0000152 0.000057 0.000062 1991 9 27 48526 0.244175 0.450098 0.0876018 0.0022888 -0.000436 -0.000019 0.000171 0.000149 0.0000106 0.0000150 0.000057 0.000061 1991 9 28 48527 0.246166 0.446365 0.0853879 0.0020956 -0.000396 -0.000081 0.000170 0.000148 0.0000105 0.0000148 0.000057 0.000061 1991 9 29 48528 0.247588 0.442954 0.0833839 0.0019274 -0.000263 -0.000148 0.000169 0.000148 0.0000103 0.0000145 0.000056 0.000060 1991 9 30 48529 0.249556 0.440558 0.0815214 0.0018441 -0.000130 -0.000214 0.000167 0.000147 0.0000101 0.0000143 0.000056 0.000059 1991 10 1 48530 0.250616 0.437591 0.0796824 0.0018748 -0.000025 -0.000239 0.000166 0.000145 0.0000100 0.0000140 0.000056 0.000058 1991 10 2 48531 0.251258 0.434089 0.0777468 0.0020093 -0.000068 -0.000055 0.000164 0.000144 0.0000097 0.0000138 0.000055 0.000057 1991 10 3 48532 0.252072 0.431289 0.0756422 0.0022052 -0.000110 0.000129 0.000163 0.000143 0.0000095 0.0000135 0.000055 0.000056 1991 10 4 48533 0.252655 0.427209 0.0733469 0.0024028 -0.000066 -0.000194 0.000161 0.000142 0.0000093 0.0000132 0.000054 0.000055 1991 10 5 48534 0.253380 0.423254 0.0708638 0.0025408 -0.000006 -0.000244 0.000160 0.000140 0.0000091 0.0000128 0.000054 0.000054 1991 10 6 48535 0.254953 0.420845 0.0682746 0.0025775 0.000048 -0.000074 0.000159 0.000139 0.0000088 0.0000125 0.000053 0.000053 1991 10 7 48536 0.255813 0.417111 0.0657154 0.0025085 0.000040 0.000097 0.000157 0.000137 0.0000086 0.0000122 0.000053 0.000053 1991 10 8 48537 0.256119 0.412957 0.0633031 0.0023659 -0.000125 0.000270 0.000156 0.000136 0.0000084 0.0000119 0.000053 0.000054 1991 10 9 48538 0.257402 0.409701 0.0610760 0.0021923 -0.000183 0.000403 0.000154 0.000134 0.0000082 0.0000116 0.000054 0.000054 1991 10 10 48539 0.258421 0.406241 0.0589621 0.0020117 -0.000113 0.000247 0.000152 0.000132 0.0000079 0.0000112 0.000054 0.000054 1991 10 11 48540 0.259522 0.402674 0.0569811 0.0018287 0.000002 -0.000009 0.000150 0.000129 0.0000077 0.0000109 0.000054 0.000055 1991 10 12 48541 0.259997 0.399519 0.0552072 0.0016525 0.000045 -0.000085 0.000147 0.000127 0.0000075 0.0000106 0.000054 0.000055 1991 10 13 48542 0.259941 0.396408 0.0536375 0.0015090 0.000062 -0.000099 0.000144 0.000124 0.0000072 0.0000102 0.000054 0.000055 1991 10 14 48543 0.260424 0.392940 0.0522004 0.0014288 0.000080 -0.000113 0.000141 0.000121 0.0000070 0.0000100 0.000054 0.000055 1991 10 15 48544 0.260479 0.389583 0.0507933 0.0014297 0.000082 -0.000116 0.000138 0.000118 0.0000069 0.0000097 0.000054 0.000055 1991 10 16 48545 0.260789 0.386092 0.0493320 0.0015087 0.000004 -0.000055 0.000135 0.000115 0.0000067 0.0000095 0.000053 0.000054 1991 10 17 48546 0.261137 0.382618 0.0477717 0.0016462 -0.000191 0.000127 0.000132 0.000112 0.0000065 0.0000093 0.000053 0.000054 1991 10 18 48547 0.261906 0.379507 0.0460037 0.0018144 -0.000194 0.000172 0.000130 0.000110 0.0000065 0.0000092 0.000053 0.000054 1991 10 19 48548 0.262298 0.376252 0.0441264 0.0019886 -0.000107 0.000046 0.000128 0.000108 0.0000065 0.0000092 0.000053 0.000055 1991 10 20 48549 0.261549 0.373015 0.0420865 0.0021457 -0.000080 -0.000066 0.000127 0.000107 0.0000065 0.0000092 0.000053 0.000055 1991 10 21 48550 0.261730 0.370065 0.0398661 0.0022537 -0.000142 -0.000064 0.000128 0.000108 0.0000065 0.0000093 0.000054 0.000056 1991 10 22 48551 0.261603 0.366854 0.0375960 0.0022826 -0.000210 0.000015 0.000130 0.000110 0.0000066 0.0000094 0.000054 0.000056 1991 10 23 48552 0.260869 0.362826 0.0353068 0.0022235 -0.000143 0.000028 0.000133 0.000112 0.0000067 0.0000096 0.000055 0.000057 1991 10 24 48553 0.260543 0.359713 0.0330727 0.0021030 0.000091 -0.000037 0.000135 0.000114 0.0000069 0.0000098 0.000055 0.000057 1991 10 25 48554 0.260387 0.356693 0.0312228 0.0019823 0.000386 0.000293 0.000138 0.000116 0.0000070 0.0000100 0.000055 0.000058 1991 10 26 48555 0.259935 0.352345 0.0292336 0.0019064 0.000083 0.000372 0.000140 0.000117 0.0000072 0.0000101 0.000056 0.000059 1991 10 27 48556 0.259414 0.350203 0.0271977 0.0018890 -0.000121 0.000264 0.000142 0.000118 0.0000073 0.0000103 0.000056 0.000059 1991 10 28 48557 0.259538 0.348237 0.0253330 0.0019507 -0.000033 0.000145 0.000143 0.000119 0.0000074 0.0000104 0.000056 0.000059 1991 10 29 48558 0.258981 0.344046 0.0233729 0.0021031 0.000053 0.000059 0.000143 0.000119 0.0000074 0.0000105 0.000056 0.000059 1991 10 30 48559 0.258924 0.340849 0.0211349 0.0023160 0.000129 0.000137 0.000143 0.000118 0.0000075 0.0000105 0.000056 0.000059 1991 10 31 48560 0.259250 0.337626 0.0187054 0.0025352 0.000205 0.000068 0.000142 0.000117 0.0000075 0.0000106 0.000056 0.000059 1991 11 1 48561 0.259313 0.334167 0.0161061 0.0027086 0.000282 -0.000036 0.000142 0.000116 0.0000075 0.0000105 0.000056 0.000058 1991 11 2 48562 0.260729 0.331583 0.0133425 0.0027934 0.000022 -0.000035 0.000141 0.000115 0.0000074 0.0000106 0.000056 0.000058 1991 11 3 48563 0.261748 0.328812 0.0105319 0.0027647 -0.000124 -0.000014 0.000142 0.000116 0.0000075 0.0000107 0.000056 0.000058 1991 11 4 48564 0.262658 0.326169 0.0078152 0.0026290 -0.000105 -0.000005 0.000144 0.000118 0.0000077 0.0000108 0.000056 0.000058 1991 11 5 48565 0.263100 0.323612 0.0052869 0.0024234 -0.000082 0.000011 0.000146 0.000120 0.0000078 0.0000110 0.000056 0.000058 1991 11 6 48566 0.262921 0.321271 0.0029882 0.0022008 -0.000037 0.000065 0.000148 0.000121 0.0000079 0.0000112 0.000056 0.000058 1991 11 7 48567 0.263233 0.318682 0.0008998 0.0020093 0.000007 0.000118 0.000150 0.000122 0.0000080 0.0000114 0.000056 0.000058 1991 11 8 48568 0.262085 0.315397 -0.0010368 0.0018770 0.000052 0.000171 0.000151 0.000123 0.0000082 0.0000116 0.000056 0.000058 1991 11 9 48569 0.261695 0.312704 -0.0028914 0.0018117 0.000281 0.000180 0.000152 0.000123 0.0000083 0.0000117 0.000056 0.000058 1991 11 10 48570 0.261757 0.309874 -0.0047046 0.0018101 0.000315 0.000199 0.000154 0.000124 0.0000084 0.0000119 0.000056 0.000057 1991 11 11 48571 0.260557 0.306413 -0.0065315 0.0018653 0.000219 0.000231 0.000154 0.000124 0.0000085 0.0000120 0.000056 0.000057 1991 11 12 48572 0.259811 0.303530 -0.0084424 0.0019673 0.000155 0.000184 0.000155 0.000124 0.0000086 0.0000121 0.000056 0.000057 1991 11 13 48573 0.258385 0.300890 -0.0104836 0.0021022 0.000100 0.000070 0.000155 0.000123 0.0000087 0.0000122 0.000056 0.000056 1991 11 14 48574 0.257331 0.298093 -0.0126588 0.0022543 0.000016 0.000062 0.000156 0.000123 0.0000087 0.0000123 0.000056 0.000055 1991 11 15 48575 0.256395 0.295236 -0.0149780 0.0024064 -0.000076 0.000086 0.000157 0.000125 0.0000087 0.0000123 0.000056 0.000055 1991 11 16 48576 0.254882 0.292323 -0.0174462 0.0025371 0.000073 0.000194 0.000158 0.000126 0.0000087 0.0000123 0.000056 0.000054 1991 11 17 48577 0.254083 0.289380 -0.0200385 0.0026205 0.000308 0.000252 0.000159 0.000126 0.0000087 0.0000123 0.000055 0.000053 1991 11 18 48578 0.252361 0.285445 -0.0226837 0.0026335 0.000354 0.000239 0.000160 0.000127 0.0000086 0.0000122 0.000056 0.000053 1991 11 19 48579 0.251356 0.281859 -0.0252816 0.0025648 0.000212 0.000196 0.000160 0.000127 0.0000086 0.0000121 0.000056 0.000054 1991 11 20 48580 0.251931 0.279915 -0.0277636 0.0024222 -0.000136 0.000133 0.000159 0.000126 0.0000085 0.0000119 0.000057 0.000055 1991 11 21 48581 0.252187 0.276682 -0.0301347 0.0022373 -0.000361 -0.000087 0.000159 0.000126 0.0000083 0.0000118 0.000057 0.000056 1991 11 22 48582 0.251621 0.273130 -0.0322844 0.0020703 -0.000250 -0.000210 0.000158 0.000126 0.0000083 0.0000117 0.000057 0.000057 1991 11 23 48583 0.249416 0.271257 -0.0342752 0.0019932 -0.000099 -0.000171 0.000158 0.000126 0.0000083 0.0000117 0.000057 0.000057 1991 11 24 48584 0.247854 0.268597 -0.0362725 0.0020488 0.000001 -0.000069 0.000158 0.000127 0.0000082 0.0000116 0.000057 0.000058 1991 11 25 48585 0.247179 0.265654 -0.0384006 0.0022251 0.000101 0.000032 0.000158 0.000127 0.0000082 0.0000115 0.000057 0.000058 1991 11 26 48586 0.245352 0.262509 -0.0407413 0.0024625 0.000161 0.000118 0.000157 0.000127 0.0000081 0.0000114 0.000057 0.000059 1991 11 27 48587 0.244332 0.258239 -0.0433439 0.0026833 0.000016 0.000127 0.000156 0.000126 0.0000080 0.0000113 0.000057 0.000059 1991 11 28 48588 0.243739 0.254799 -0.0462211 0.0028324 -0.000092 0.000103 0.000155 0.000126 0.0000079 0.0000112 0.000057 0.000059 1991 11 29 48589 0.242039 0.251352 -0.0489564 0.0029052 -0.000173 0.000055 0.000153 0.000124 0.0000078 0.0000110 0.000056 0.000059 1991 11 30 48590 0.241523 0.247250 -0.0517698 0.0029116 -0.000254 0.000007 0.000150 0.000123 0.0000076 0.0000107 0.000056 0.000059 1991 12 1 48591 0.241878 0.244092 -0.0547764 0.0028347 -0.000336 -0.000040 0.000148 0.000121 0.0000074 0.0000105 0.000056 0.000059 1991 12 2 48592 0.240716 0.241232 -0.0575644 0.0026675 -0.000328 -0.000008 0.000145 0.000119 0.0000072 0.0000102 0.000056 0.000059 1991 12 3 48593 0.240620 0.238198 -0.0600909 0.0024423 -0.000079 0.000223 0.000142 0.000116 0.0000070 0.0000099 0.000055 0.000059 1991 12 4 48594 0.240804 0.235688 -0.0624967 0.0022098 -0.000022 0.000160 0.000139 0.000114 0.0000068 0.0000096 0.000055 0.000059 1991 12 5 48595 0.238148 0.233659 -0.0644904 0.0020260 0.000035 0.000097 0.000135 0.000111 0.0000066 0.0000095 0.000054 0.000059 1991 12 6 48596 0.236863 0.231843 -0.0664602 0.0019223 -0.000115 0.000127 0.000135 0.000111 0.0000066 0.0000094 0.000054 0.000059 1991 12 7 48597 0.235217 0.229471 -0.0684166 0.0018914 -0.000121 0.000158 0.000137 0.000112 0.0000067 0.0000095 0.000055 0.000060 1991 12 8 48598 0.230305 0.226208 -0.0703232 0.0019196 -0.000020 0.000174 0.000138 0.000113 0.0000068 0.0000097 0.000055 0.000060 1991 12 9 48599 0.227350 0.223368 -0.0722594 0.0019993 0.000081 0.000189 0.000139 0.000114 0.0000070 0.0000098 0.000055 0.000061 1991 12 10 48600 0.225498 0.220557 -0.0743034 0.0021186 0.000166 0.000199 0.000140 0.000114 0.0000071 0.0000100 0.000056 0.000062 1991 12 11 48601 0.222926 0.217117 -0.0764989 0.0022571 0.000175 0.000178 0.000140 0.000114 0.0000072 0.0000102 0.000056 0.000062 1991 12 12 48602 0.220811 0.214297 -0.0788264 0.0023921 0.000085 0.000027 0.000140 0.000114 0.0000073 0.0000103 0.000056 0.000062 1991 12 13 48603 0.218778 0.211450 -0.0812796 0.0025048 -0.000002 0.000259 0.000140 0.000114 0.0000073 0.0000103 0.000055 0.000062 1991 12 14 48604 0.217571 0.208656 -0.0838274 0.0025811 0.000088 0.000321 0.000140 0.000115 0.0000074 0.0000104 0.000055 0.000061 1991 12 15 48605 0.215961 0.206843 -0.0864218 0.0026103 0.000247 0.000258 0.000140 0.000115 0.0000074 0.0000104 0.000055 0.000061 1991 12 16 48606 0.213264 0.204704 -0.0890121 0.0025818 0.000189 0.000211 0.000139 0.000115 0.0000074 0.0000104 0.000055 0.000060 1991 12 17 48607 0.211392 0.201922 -0.0915490 0.0024869 0.000070 0.000169 0.000137 0.000114 0.0000074 0.0000104 0.000055 0.000059 1991 12 18 48608 0.210246 0.199079 -0.0939729 0.0023292 0.000015 0.000126 0.000136 0.000113 0.0000073 0.0000104 0.000054 0.000059 1991 12 19 48609 0.208338 0.196529 -0.0962179 0.0021379 -0.000071 0.000075 0.000135 0.000113 0.0000073 0.0000104 0.000054 0.000058 1991 12 20 48610 0.207088 0.194478 -0.0983036 0.0019699 -0.000061 -0.000054 0.000137 0.000115 0.0000074 0.0000104 0.000054 0.000058 1991 12 21 48611 0.206219 0.192857 -0.1002047 0.0018926 0.000100 -0.000015 0.000140 0.000118 0.0000074 0.0000105 0.000054 0.000058 1991 12 22 48612 0.203401 0.190961 -0.1020774 0.0019477 0.000256 0.000008 0.000142 0.000120 0.0000075 0.0000106 0.000054 0.000058 1991 12 23 48613 0.200727 0.188325 -0.1041103 0.0021174 0.000368 -0.000051 0.000145 0.000123 0.0000075 0.0000106 0.000054 0.000058 1991 12 24 48614 0.197944 0.185813 -0.1063494 0.0023341 0.000347 -0.000014 0.000148 0.000126 0.0000075 0.0000106 0.000054 0.000058 1991 12 25 48615 0.195355 0.183541 -0.1087814 0.0025182 0.000194 0.000120 0.000151 0.000128 0.0000075 0.0000106 0.000053 0.000058 1991 12 26 48616 0.193944 0.181975 -0.1113471 0.0026132 0.000040 0.000254 0.000153 0.000131 0.0000075 0.0000105 0.000053 0.000057 1991 12 27 48617 0.191094 0.179862 -0.1139531 0.0026014 -0.000113 0.000388 0.000156 0.000133 0.0000074 0.0000105 0.000053 0.000057 1991 12 28 48618 0.189355 0.176993 -0.1165053 0.0024991 -0.000129 0.000294 0.000158 0.000135 0.0000074 0.0000104 0.000052 0.000056 1991 12 29 48619 0.189092 0.175638 -0.1189300 0.0023404 -0.000098 0.000123 0.000160 0.000137 0.0000073 0.0000103 0.000052 0.000056 1991 12 30 48620 0.187858 0.172526 -0.1211857 0.0021611 -0.000068 -0.000048 0.000161 0.000139 0.0000072 0.0000103 0.000052 0.000055 1991 12 31 48621 0.186116 0.169230 -0.1232641 0.0019902 -0.000035 -0.000179 0.000162 0.000140 0.0000072 0.0000102 0.000051 0.000054 1992 1 1 48622 0.183560 0.168944 -0.1251849 0.0018528 -0.000002 -0.000107 0.000127 0.000114 0.0000075 0.0000106 0.000064 0.000074 1992 1 2 48623 0.180749 0.167255 -0.1269899 0.0017635 0.000031 -0.000042 0.000127 0.000114 0.0000075 0.0000106 0.000064 0.000073 1992 1 3 48624 0.177697 0.164882 -0.1287361 0.0017384 0.000063 0.000023 0.000126 0.000113 0.0000075 0.0000105 0.000063 0.000072 1992 1 4 48625 0.175200 0.163102 -0.1304905 0.0017831 -0.000096 0.000016 0.000125 0.000113 0.0000074 0.0000105 0.000062 0.000071 1992 1 5 48626 0.173488 0.160655 -0.1323209 0.0018915 -0.000159 0.000081 0.000124 0.000112 0.0000074 0.0000105 0.000062 0.000070 1992 1 6 48627 0.170223 0.159076 -0.1342847 0.0020452 0.000011 0.000284 0.000123 0.000110 0.0000074 0.0000104 0.000062 0.000070 1992 1 7 48628 0.168342 0.156781 -0.1364172 0.0022179 0.000147 0.000406 0.000122 0.000109 0.0000074 0.0000104 0.000062 0.000070 1992 1 8 48629 0.166574 0.154560 -0.1387238 0.0023833 0.000112 0.000114 0.000120 0.000107 0.0000073 0.0000103 0.000061 0.000070 1992 1 9 48630 0.164604 0.152983 -0.1411775 0.0025232 0.000085 0.000138 0.000120 0.000106 0.0000073 0.0000103 0.000062 0.000070 1992 1 10 48631 0.160736 0.151368 -0.1437493 0.0026253 0.000061 0.000321 0.000120 0.000106 0.0000073 0.0000103 0.000062 0.000071 1992 1 11 48632 0.158074 0.150106 -0.1464053 0.0026756 0.000060 0.000310 0.000120 0.000106 0.0000073 0.0000103 0.000062 0.000071 1992 1 12 48633 0.156301 0.148122 -0.1490856 0.0026608 0.000065 0.000235 0.000120 0.000106 0.0000073 0.0000104 0.000063 0.000071 1992 1 13 48634 0.151869 0.147602 -0.1517169 0.0025803 0.000071 0.000160 0.000120 0.000106 0.0000073 0.0000104 0.000063 0.000072 1992 1 14 48635 0.150255 0.145353 -0.1542330 0.0024525 0.000059 0.000089 0.000120 0.000105 0.0000073 0.0000104 0.000063 0.000072 1992 1 15 48636 0.147286 0.142611 -0.1566036 0.0023108 -0.000040 0.000042 0.000119 0.000104 0.0000074 0.0000105 0.000063 0.000072 1992 1 16 48637 0.143129 0.143468 -0.1588605 0.0021936 -0.000126 0.000010 0.000118 0.000103 0.0000074 0.0000105 0.000063 0.000072 1992 1 17 48638 0.140682 0.142551 -0.1610367 0.0021466 -0.000209 -0.000016 0.000118 0.000102 0.0000075 0.0000106 0.000064 0.000073 1992 1 18 48639 0.137403 0.140836 -0.1631971 0.0022197 -0.000081 0.000060 0.000117 0.000101 0.0000076 0.0000107 0.000064 0.000072 1992 1 19 48640 0.134164 0.140029 -0.1654980 0.0024285 0.000033 0.000068 0.000116 0.000100 0.0000076 0.0000108 0.000064 0.000072 1992 1 20 48641 0.130073 0.139022 -0.1680708 0.0027229 0.000104 0.000024 0.000115 0.000100 0.0000076 0.0000108 0.000064 0.000072 1992 1 21 48642 0.125973 0.138226 -0.1709474 0.0030044 0.000163 0.000008 0.000114 0.000099 0.0000076 0.0000108 0.000064 0.000071 1992 1 22 48643 0.122985 0.136275 -0.1740597 0.0031779 0.000161 0.000134 0.000112 0.000098 0.0000076 0.0000108 0.000064 0.000071 1992 1 23 48644 0.120520 0.134207 -0.1772604 0.0031961 0.000025 0.000170 0.000112 0.000098 0.0000076 0.0000108 0.000064 0.000071 1992 1 24 48645 0.117962 0.133251 -0.1803982 0.0030705 -0.000177 0.000160 0.000112 0.000098 0.0000077 0.0000109 0.000064 0.000071 1992 1 25 48646 0.115570 0.131487 -0.1833625 0.0028508 -0.000175 0.000108 0.000111 0.000097 0.0000078 0.0000110 0.000064 0.000070 1992 1 26 48647 0.112874 0.129943 -0.1860888 0.0025974 -0.000106 0.000041 0.000111 0.000097 0.0000078 0.0000111 0.000064 0.000070 1992 1 27 48648 0.110175 0.129783 -0.1885673 0.0023636 -0.000037 -0.000026 0.000111 0.000096 0.0000079 0.0000112 0.000064 0.000070 1992 1 28 48649 0.107366 0.128044 -0.1908349 0.0021875 0.000022 -0.000059 0.000110 0.000095 0.0000080 0.0000112 0.000064 0.000069 1992 1 29 48650 0.103744 0.126323 -0.1929602 0.0020895 0.000011 0.000112 0.000110 0.000094 0.0000080 0.0000113 0.000064 0.000070 1992 1 30 48651 0.101523 0.125579 -0.1950312 0.0020710 0.000251 0.000056 0.000110 0.000094 0.0000080 0.0000113 0.000064 0.000070 1992 1 31 48652 0.099029 0.124393 -0.1971238 0.0021167 0.000577 -0.000077 0.000110 0.000094 0.0000080 0.0000113 0.000064 0.000070 1992 2 1 48653 0.096048 0.123596 -0.1992895 0.0022022 0.000358 -0.000044 0.000110 0.000094 0.0000079 0.0000112 0.000063 0.000070 1992 2 2 48654 0.094157 0.122984 -0.2015522 0.0023047 -0.000043 0.000045 0.000110 0.000095 0.0000079 0.0000112 0.000063 0.000069 1992 2 3 48655 0.091780 0.122299 -0.2039163 0.0024119 -0.000088 0.000038 0.000110 0.000094 0.0000079 0.0000112 0.000063 0.000069 1992 2 4 48656 0.090237 0.121929 -0.2063800 0.0025228 0.000151 -0.000031 0.000110 0.000094 0.0000079 0.0000111 0.000064 0.000069 1992 2 5 48657 0.088174 0.122030 -0.2089463 0.0026373 0.000125 0.000050 0.000110 0.000094 0.0000078 0.0000111 0.000064 0.000070 1992 2 6 48658 0.084622 0.121815 -0.2116253 0.0027397 0.000098 0.000005 0.000111 0.000095 0.0000079 0.0000112 0.000064 0.000070 1992 2 7 48659 0.082215 0.121385 -0.2143998 0.0027946 0.000070 -0.000081 0.000113 0.000096 0.0000080 0.0000113 0.000065 0.000072 1992 2 8 48660 0.079374 0.119871 -0.2172112 0.0027669 0.000096 -0.000027 0.000115 0.000098 0.0000081 0.0000115 0.000065 0.000073 1992 2 9 48661 0.076775 0.118640 -0.2199356 0.0026541 0.000135 -0.000026 0.000117 0.000099 0.0000082 0.0000116 0.000066 0.000074 1992 2 10 48662 0.074358 0.118662 -0.2224963 0.0024904 0.000173 -0.000076 0.000119 0.000100 0.0000084 0.0000119 0.000067 0.000074 1992 2 11 48663 0.070744 0.117889 -0.2248895 0.0023167 0.000152 -0.000063 0.000120 0.000101 0.0000085 0.0000121 0.000067 0.000075 1992 2 12 48664 0.067690 0.117518 -0.2271335 0.0021624 -0.000162 0.000260 0.000121 0.000102 0.0000087 0.0000122 0.000068 0.000077 1992 2 13 48665 0.064081 0.116864 -0.2292470 0.0020575 -0.000101 0.000358 0.000122 0.000102 0.0000087 0.0000124 0.000068 0.000078 1992 2 14 48666 0.060630 0.116084 -0.2312888 0.0020407 0.000086 0.000382 0.000122 0.000101 0.0000088 0.0000125 0.000069 0.000079 1992 2 15 48667 0.057502 0.116485 -0.2333607 0.0021409 0.000184 0.000040 0.000122 0.000101 0.0000089 0.0000125 0.000069 0.000080 1992 2 16 48668 0.054274 0.116288 -0.2355962 0.0023490 0.000199 -0.000078 0.000122 0.000101 0.0000089 0.0000126 0.000070 0.000080 1992 2 17 48669 0.051190 0.115656 -0.2380787 0.0026100 0.000177 -0.000067 0.000123 0.000102 0.0000089 0.0000126 0.000070 0.000081 1992 2 18 48670 0.048312 0.116223 -0.2408079 0.0028474 0.000155 -0.000056 0.000123 0.000102 0.0000089 0.0000125 0.000070 0.000081 1992 2 19 48671 0.046421 0.116480 -0.2437213 0.0029913 0.000134 -0.000047 0.000122 0.000102 0.0000088 0.0000124 0.000070 0.000081 1992 2 20 48672 0.043574 0.116400 -0.2467301 0.0029961 0.000063 -0.000089 0.000121 0.000102 0.0000087 0.0000123 0.000070 0.000080 1992 2 21 48673 0.040300 0.117437 -0.2496839 0.0028616 -0.000024 -0.000148 0.000119 0.000100 0.0000086 0.0000121 0.000070 0.000080 1992 2 22 48674 0.036182 0.117538 -0.2524416 0.0026428 0.000106 0.000166 0.000118 0.000099 0.0000085 0.0000120 0.000070 0.000079 1992 2 23 48675 0.032176 0.117310 -0.2549574 0.0024205 0.000212 0.000220 0.000116 0.000098 0.0000084 0.0000119 0.000070 0.000078 1992 2 24 48676 0.029173 0.117251 -0.2572735 0.0022486 0.000269 0.000077 0.000115 0.000097 0.0000083 0.0000117 0.000070 0.000077 1992 2 25 48677 0.025734 0.116740 -0.2594667 0.0021304 0.000290 -0.000061 0.000114 0.000096 0.0000082 0.0000116 0.000070 0.000076 1992 2 26 48678 0.023210 0.116149 -0.2615815 0.0020427 0.000133 -0.000181 0.000113 0.000095 0.0000081 0.0000114 0.000070 0.000076 1992 2 27 48679 0.019978 0.115770 -0.2635987 0.0019827 0.000129 -0.000066 0.000112 0.000094 0.0000079 0.0000111 0.000070 0.000075 1992 2 28 48680 0.016615 0.115706 -0.2655609 0.0019761 0.000157 0.000097 0.000111 0.000093 0.0000077 0.0000109 0.000069 0.000074 1992 2 29 48681 0.013438 0.115063 -0.2675552 0.0020436 0.000190 0.000093 0.000110 0.000092 0.0000076 0.0000107 0.000069 0.000073 1992 3 1 48682 0.009403 0.115424 -0.2696582 0.0021801 0.000224 0.000034 0.000109 0.000091 0.0000074 0.0000105 0.000069 0.000072 1992 3 2 48683 0.005823 0.116207 -0.2719234 0.0023591 0.000259 -0.000026 0.000108 0.000090 0.0000073 0.0000103 0.000069 0.000072 1992 3 3 48684 0.002408 0.116542 -0.2743742 0.0025457 0.000269 -0.000062 0.000107 0.000088 0.0000072 0.0000101 0.000069 0.000071 1992 3 4 48685 -0.001327 0.117558 -0.2770015 0.0027053 0.000158 0.000015 0.000105 0.000086 0.0000070 0.0000101 0.000069 0.000070 1992 3 5 48686 -0.005026 0.118414 -0.2797704 0.0028094 0.000086 0.000069 0.000105 0.000085 0.0000071 0.0000101 0.000069 0.000070 1992 3 6 48687 -0.008422 0.118794 -0.2826075 0.0028438 0.000034 0.000112 0.000107 0.000086 0.0000073 0.0000103 0.000069 0.000071 1992 3 7 48688 -0.012712 0.119646 -0.2854273 0.0028111 0.000018 -0.000006 0.000108 0.000087 0.0000075 0.0000105 0.000070 0.000072 1992 3 8 48689 -0.016433 0.120525 -0.2881997 0.0027210 0.000081 -0.000026 0.000109 0.000087 0.0000076 0.0000108 0.000071 0.000073 1992 3 9 48690 -0.019262 0.120728 -0.2908762 0.0025908 0.000177 0.000030 0.000111 0.000088 0.0000078 0.0000110 0.000071 0.000074 1992 3 10 48691 -0.022813 0.121579 -0.2934008 0.0024645 0.000273 0.000062 0.000112 0.000089 0.0000080 0.0000113 0.000072 0.000075 1992 3 11 48692 -0.025778 0.122319 -0.2957988 0.0024006 0.000371 -0.000023 0.000113 0.000090 0.0000081 0.0000114 0.000072 0.000076 1992 3 12 48693 -0.027903 0.123020 -0.2982106 0.0024318 0.000425 -0.000015 0.000115 0.000092 0.0000082 0.0000116 0.000072 0.000076 1992 3 13 48694 -0.031364 0.124685 -0.3007150 0.0025588 0.000387 0.000025 0.000118 0.000093 0.0000082 0.0000116 0.000073 0.000076 1992 3 14 48695 -0.035088 0.126286 -0.3033758 0.0027714 0.000272 0.000070 0.000120 0.000095 0.0000082 0.0000116 0.000072 0.000075 1992 3 15 48696 -0.037459 0.127844 -0.3062725 0.0030457 0.000239 0.000118 0.000122 0.000096 0.0000082 0.0000116 0.000072 0.000075 1992 3 16 48697 -0.041816 0.129672 -0.3094515 0.0033269 0.000247 0.000168 0.000124 0.000098 0.0000082 0.0000116 0.000072 0.000074 1992 3 17 48698 -0.044839 0.131510 -0.3128956 0.0035343 0.000196 0.000148 0.000126 0.000099 0.0000082 0.0000116 0.000072 0.000073 1992 3 18 48699 -0.046462 0.133642 -0.3164954 0.0035992 -0.000148 -0.000218 0.000128 0.000100 0.0000082 0.0000116 0.000071 0.000073 1992 3 19 48700 -0.050698 0.136301 -0.3200581 0.0035100 -0.000265 -0.000331 0.000130 0.000102 0.0000083 0.0000117 0.000071 0.000072 1992 3 20 48701 -0.054297 0.137660 -0.3234549 0.0033107 -0.000157 -0.000192 0.000131 0.000104 0.0000083 0.0000118 0.000071 0.000071 1992 3 21 48702 -0.057990 0.138907 -0.3266545 0.0030604 -0.000030 0.000043 0.000133 0.000105 0.0000084 0.0000118 0.000070 0.000070 1992 3 22 48703 -0.061090 0.141277 -0.3295995 0.0028154 0.000043 0.000169 0.000134 0.000107 0.0000084 0.0000118 0.000069 0.000069 1992 3 23 48704 -0.063836 0.142581 -0.3323040 0.0026259 0.000125 0.000177 0.000136 0.000109 0.0000083 0.0000118 0.000069 0.000068 1992 3 24 48705 -0.066704 0.144109 -0.3348603 0.0025151 0.000264 0.000110 0.000137 0.000110 0.0000083 0.0000119 0.000069 0.000069 1992 3 25 48706 -0.068258 0.146584 -0.3373552 0.0024713 0.000308 0.000078 0.000138 0.000111 0.0000084 0.0000119 0.000069 0.000069 1992 3 26 48707 -0.070397 0.148760 -0.3398349 0.0024707 0.000353 0.000045 0.000138 0.000112 0.0000085 0.0000121 0.000069 0.000070 1992 3 27 48708 -0.072134 0.151482 -0.3423267 0.0025024 0.000397 0.000013 0.000140 0.000113 0.0000086 0.0000122 0.000069 0.000070 1992 3 28 48709 -0.074523 0.153677 -0.3448567 0.0025720 0.000399 0.000014 0.000141 0.000115 0.0000088 0.0000124 0.000069 0.000071 1992 3 29 48710 -0.077182 0.155739 -0.3474697 0.0026841 0.000258 0.000087 0.000142 0.000116 0.0000089 0.0000126 0.000070 0.000072 1992 3 30 48711 -0.078674 0.159241 -0.3502124 0.0028244 0.000117 0.000159 0.000143 0.000117 0.0000091 0.0000129 0.000070 0.000073 1992 3 31 48712 -0.080755 0.160773 -0.3531064 0.0029561 -0.000044 0.000176 0.000144 0.000117 0.0000093 0.0000132 0.000071 0.000074 1992 4 1 48713 -0.083117 0.162396 -0.3561235 0.0030386 -0.000304 -0.000091 0.000144 0.000118 0.0000095 0.0000134 0.000071 0.000074 1992 4 2 48714 -0.084911 0.165374 -0.3591756 0.0030506 -0.000257 -0.000123 0.000145 0.000119 0.0000097 0.0000137 0.000071 0.000075 1992 4 3 48715 -0.086772 0.166423 -0.3621943 0.0029930 -0.000104 -0.000076 0.000145 0.000119 0.0000098 0.0000139 0.000071 0.000074 1992 4 4 48716 -0.089096 0.168154 -0.3651312 0.0028745 0.000033 -0.000029 0.000145 0.000119 0.0000100 0.0000142 0.000071 0.000074 1992 4 5 48717 -0.090608 0.169884 -0.3679319 0.0027109 0.000070 0.000014 0.000145 0.000119 0.0000102 0.0000144 0.000072 0.000075 1992 4 6 48718 -0.092396 0.171106 -0.3705595 0.0025364 0.000107 0.000056 0.000145 0.000119 0.0000104 0.0000147 0.000072 0.000075 1992 4 7 48719 -0.094029 0.173090 -0.3730208 0.0024022 0.000113 0.000125 0.000144 0.000118 0.0000105 0.0000148 0.000072 0.000075 1992 4 8 48720 -0.094578 0.174645 -0.3753799 0.0023576 -0.000041 0.000326 0.000144 0.000118 0.0000106 0.0000150 0.000072 0.000075 1992 4 9 48721 -0.096519 0.177159 -0.3777567 0.0024237 -0.000058 0.000292 0.000144 0.000118 0.0000106 0.0000150 0.000072 0.000074 1992 4 10 48722 -0.099095 0.180064 -0.3802604 0.0025861 0.000094 0.000024 0.000143 0.000118 0.0000106 0.0000151 0.000071 0.000073 1992 4 11 48723 -0.100567 0.181913 -0.3829590 0.0028100 0.000196 -0.000185 0.000142 0.000117 0.0000107 0.0000151 0.000071 0.000072 1992 4 12 48724 -0.101857 0.183960 -0.3858917 0.0030565 0.000183 -0.000268 0.000140 0.000116 0.0000108 0.0000152 0.000070 0.000072 1992 4 13 48725 -0.103635 0.186064 -0.3890604 0.0032868 0.000170 -0.000351 0.000139 0.000115 0.0000108 0.0000153 0.000070 0.000071 1992 4 14 48726 -0.105616 0.188428 -0.3924227 0.0034610 0.000152 -0.000382 0.000137 0.000114 0.0000109 0.0000154 0.000070 0.000071 1992 4 15 48727 -0.107510 0.191634 -0.3959113 0.0035326 0.000107 -0.000149 0.000135 0.000112 0.0000109 0.0000153 0.000069 0.000070 1992 4 16 48728 -0.108567 0.194383 -0.3994508 0.0034559 0.000128 0.000021 0.000133 0.000111 0.0000108 0.0000152 0.000068 0.000069 1992 4 17 48729 -0.110308 0.197297 -0.4028329 0.0032286 0.000122 0.000031 0.000132 0.000111 0.0000106 0.0000149 0.000068 0.000067 1992 4 18 48730 -0.112888 0.199656 -0.4059124 0.0029159 0.000103 -0.000009 0.000131 0.000111 0.0000104 0.0000147 0.000067 0.000066 1992 4 19 48731 -0.114707 0.201737 -0.4086642 0.0026121 0.000104 -0.000045 0.000130 0.000110 0.0000102 0.0000144 0.000066 0.000065 1992 4 20 48732 -0.116406 0.204676 -0.4111444 0.0023876 0.000214 -0.000063 0.000129 0.000109 0.0000100 0.0000141 0.000067 0.000065 1992 4 21 48733 -0.117780 0.206306 -0.4134565 0.0022648 0.000264 -0.000072 0.000128 0.000108 0.0000098 0.0000138 0.000067 0.000065 1992 4 22 48734 -0.119660 0.207789 -0.4157018 0.0022290 0.000013 -0.000034 0.000126 0.000107 0.0000095 0.0000136 0.000068 0.000065 1992 4 23 48735 -0.121345 0.210261 -0.4179432 0.0022563 -0.000102 -0.000050 0.000126 0.000107 0.0000094 0.0000134 0.000068 0.000065 1992 4 24 48736 -0.122680 0.213181 -0.4202317 0.0023312 -0.000148 -0.000093 0.000127 0.000108 0.0000094 0.0000133 0.000069 0.000066 1992 4 25 48737 -0.124250 0.215897 -0.4226115 0.0024435 -0.000096 -0.000121 0.000128 0.000109 0.0000094 0.0000133 0.000070 0.000068 1992 4 26 48738 -0.125458 0.218167 -0.4251151 0.0025771 -0.000011 -0.000145 0.000129 0.000109 0.0000094 0.0000133 0.000070 0.000069 1992 4 27 48739 -0.127669 0.220788 -0.4277547 0.0027041 0.000073 -0.000169 0.000129 0.000109 0.0000094 0.0000133 0.000071 0.000070 1992 4 28 48740 -0.129181 0.222954 -0.4305113 0.0027897 0.000112 -0.000192 0.000129 0.000110 0.0000094 0.0000133 0.000072 0.000071 1992 4 29 48741 -0.130015 0.224788 -0.4333275 0.0028057 -0.000085 -0.000205 0.000130 0.000110 0.0000093 0.0000132 0.000072 0.000072 1992 4 30 48742 -0.131654 0.227312 -0.4361111 0.0027438 0.000027 -0.000158 0.000130 0.000110 0.0000092 0.0000130 0.000073 0.000072 1992 5 1 48743 -0.132785 0.230133 -0.4387900 0.0026155 0.000228 -0.000092 0.000131 0.000110 0.0000091 0.0000129 0.000073 0.000072 1992 5 2 48744 -0.134480 0.232575 -0.4413182 0.0024421 0.000216 -0.000073 0.000131 0.000110 0.0000090 0.0000128 0.000073 0.000072 1992 5 3 48745 -0.137315 0.234856 -0.4436653 0.0022519 0.000131 -0.000071 0.000131 0.000111 0.0000090 0.0000127 0.000073 0.000073 1992 5 4 48746 -0.139432 0.237211 -0.4458311 0.0020838 0.000046 -0.000069 0.000132 0.000111 0.0000090 0.0000127 0.000074 0.000073 1992 5 5 48747 -0.141382 0.239343 -0.4478585 0.0019818 -0.000024 -0.000058 0.000132 0.000111 0.0000089 0.0000126 0.000074 0.000074 1992 5 6 48748 -0.143571 0.240801 -0.4498303 0.0019818 -0.000014 -0.000004 0.000131 0.000110 0.0000088 0.0000125 0.000074 0.000074 1992 5 7 48749 -0.144914 0.242485 -0.4518512 0.0020947 0.000084 -0.000082 0.000131 0.000110 0.0000087 0.0000123 0.000074 0.000073 1992 5 8 48750 -0.145846 0.244890 -0.4540308 0.0022941 0.000200 -0.000187 0.000132 0.000111 0.0000085 0.0000121 0.000074 0.000073 1992 5 9 48751 -0.146118 0.248252 -0.4564388 0.0025199 0.000244 -0.000175 0.000131 0.000111 0.0000084 0.0000119 0.000074 0.000073 1992 5 10 48752 -0.146508 0.251606 -0.4590645 0.0027034 0.000264 -0.000123 0.000131 0.000111 0.0000083 0.0000118 0.000074 0.000073 1992 5 11 48753 -0.147065 0.253914 -0.4618309 0.0027979 0.000276 -0.000069 0.000131 0.000110 0.0000083 0.0000117 0.000075 0.000075 1992 5 12 48754 -0.148410 0.257464 -0.4646303 0.0027931 0.000282 -0.000022 0.000130 0.000110 0.0000082 0.0000116 0.000076 0.000077 1992 5 13 48755 -0.150449 0.260567 -0.4673677 0.0027046 0.000249 -0.000073 0.000130 0.000109 0.0000081 0.0000115 0.000077 0.000078 1992 5 14 48756 -0.151182 0.262415 -0.4699975 0.0025511 0.000276 0.000023 0.000130 0.000109 0.0000081 0.0000115 0.000079 0.000080 1992 5 15 48757 -0.152443 0.264566 -0.4724653 0.0023504 0.000334 0.000192 0.000131 0.000110 0.0000082 0.0000116 0.000080 0.000083 1992 5 16 48758 -0.153566 0.266554 -0.4747224 0.0021367 0.000266 0.000221 0.000132 0.000111 0.0000082 0.0000116 0.000082 0.000085 1992 5 17 48759 -0.153798 0.268584 -0.4767601 0.0019622 0.000113 -0.000028 0.000133 0.000112 0.0000082 0.0000116 0.000084 0.000088 1992 5 18 48760 -0.154051 0.270720 -0.4786578 0.0018691 0.000133 -0.000324 0.000133 0.000113 0.0000082 0.0000116 0.000085 0.000090 1992 5 19 48761 -0.154003 0.273269 -0.4805155 0.0018645 0.000260 -0.000491 0.000134 0.000113 0.0000081 0.0000115 0.000086 0.000092 1992 5 20 48762 -0.153791 0.275593 -0.4824039 0.0019242 0.000172 -0.000287 0.000134 0.000114 0.0000080 0.0000114 0.000087 0.000094 1992 5 21 48763 -0.154004 0.278334 -0.4843798 0.0020111 0.000083 -0.000084 0.000134 0.000114 0.0000079 0.0000112 0.000089 0.000096 1992 5 22 48764 -0.154616 0.281140 -0.4864592 0.0020984 0.000028 0.000019 0.000135 0.000114 0.0000078 0.0000110 0.000090 0.000097 1992 5 23 48765 -0.154800 0.283515 -0.4885847 0.0021865 -0.000007 0.000077 0.000135 0.000114 0.0000076 0.0000107 0.000091 0.000099 1992 5 24 48766 -0.155274 0.286355 -0.4908002 0.0022805 -0.000220 0.000158 0.000135 0.000114 0.0000074 0.0000104 0.000092 0.000100 1992 5 25 48767 -0.155476 0.289667 -0.4931248 0.0023587 -0.000160 0.000170 0.000135 0.000114 0.0000071 0.0000101 0.000093 0.000102 1992 5 26 48768 -0.156428 0.292291 -0.4955132 0.0023845 0.000061 0.000114 0.000135 0.000115 0.0000069 0.0000098 0.000093 0.000102 1992 5 27 48769 -0.157808 0.293775 -0.4978920 0.0023352 -0.000053 -0.000036 0.000135 0.000115 0.0000067 0.0000095 0.000093 0.000102 1992 5 28 48770 -0.158728 0.295880 -0.5001754 0.0022162 -0.000167 -0.000185 0.000135 0.000115 0.0000065 0.0000093 0.000094 0.000102 1992 5 29 48771 -0.159443 0.297579 -0.5022959 0.0020526 -0.000051 -0.000183 0.000134 0.000115 0.0000064 0.0000091 0.000094 0.000102 1992 5 30 48772 -0.158796 0.299419 -0.5042560 0.0018692 0.000113 -0.000175 0.000134 0.000114 0.0000064 0.0000091 0.000094 0.000103 1992 5 31 48773 -0.157658 0.301684 -0.5060402 0.0016902 0.000207 -0.000075 0.000134 0.000115 0.0000065 0.0000092 0.000094 0.000104 1992 6 1 48774 -0.156367 0.304303 -0.5076604 0.0015544 0.000063 0.000003 0.000136 0.000116 0.0000065 0.0000092 0.000094 0.000105 1992 6 2 48775 -0.156787 0.307337 -0.5091934 0.0015106 -0.000141 0.000014 0.000138 0.000116 0.0000066 0.0000094 0.000095 0.000106 1992 6 3 48776 -0.156753 0.309707 -0.5107222 0.0015963 0.000142 0.000057 0.000140 0.000117 0.0000068 0.0000095 0.000095 0.000107 1992 6 4 48777 -0.155875 0.312271 -0.5123603 0.0017980 0.000116 0.000011 0.000141 0.000118 0.0000069 0.0000097 0.000096 0.000108 1992 6 5 48778 -0.156198 0.314400 -0.5143154 0.0020202 0.000245 -0.000233 0.000144 0.000120 0.0000070 0.0000099 0.000096 0.000110 1992 6 6 48779 -0.155853 0.316745 -0.5164479 0.0021538 0.000358 -0.000210 0.000146 0.000122 0.0000071 0.0000100 0.000097 0.000111 1992 6 7 48780 -0.155865 0.318876 -0.5186108 0.0021668 0.000466 -0.000099 0.000149 0.000125 0.0000072 0.0000101 0.000097 0.000113 1992 6 8 48781 -0.155044 0.321038 -0.5207240 0.0020928 0.000573 0.000013 0.000150 0.000126 0.0000072 0.0000102 0.000098 0.000115 1992 6 9 48782 -0.154677 0.323186 -0.5227421 0.0019783 0.000659 0.000116 0.000152 0.000128 0.0000073 0.0000103 0.000098 0.000116 1992 6 10 48783 -0.154880 0.325347 -0.5246496 0.0018513 0.000634 0.000175 0.000153 0.000129 0.0000073 0.0000104 0.000098 0.000117 1992 6 11 48784 -0.154454 0.327758 -0.5264358 0.0017214 0.000608 0.000234 0.000154 0.000130 0.0000074 0.0000104 0.000098 0.000118 1992 6 12 48785 -0.154054 0.330069 -0.5280975 0.0015912 0.000583 0.000293 0.000155 0.000131 0.0000074 0.0000104 0.000099 0.000119 1992 6 13 48786 -0.152994 0.332890 -0.5296384 0.0014681 0.000371 0.000327 0.000155 0.000132 0.0000074 0.0000104 0.000099 0.000119 1992 6 14 48787 -0.153272 0.335156 -0.5310714 0.0013708 0.000188 0.000220 0.000155 0.000132 0.0000074 0.0000105 0.000098 0.000118 1992 6 15 48788 -0.153216 0.339581 -0.5324067 0.0013285 0.000165 -0.000086 0.000155 0.000132 0.0000075 0.0000107 0.000098 0.000118 1992 6 16 48789 -0.152599 0.342761 -0.5337266 0.0013561 0.000077 -0.000342 0.000155 0.000132 0.0000077 0.0000109 0.000098 0.000117 1992 6 17 48790 -0.153138 0.345255 -0.5351220 0.0014318 -0.000357 -0.000346 0.000155 0.000131 0.0000079 0.0000112 0.000097 0.000116 1992 6 18 48791 -0.153121 0.348976 -0.5366249 0.0015179 -0.000268 -0.000428 0.000154 0.000130 0.0000081 0.0000114 0.000097 0.000115 1992 6 19 48792 -0.152846 0.351136 -0.5381964 0.0016034 -0.000073 -0.000525 0.000154 0.000129 0.0000082 0.0000116 0.000096 0.000114 1992 6 20 48793 -0.154201 0.354238 -0.5397977 0.0017052 -0.000167 -0.000623 0.000152 0.000128 0.0000084 0.0000118 0.000095 0.000112 1992 6 21 48794 -0.153518 0.355252 -0.5415560 0.0018127 -0.000224 -0.000308 0.000150 0.000126 0.0000085 0.0000120 0.000094 0.000110 1992 6 22 48795 -0.150869 0.357562 -0.5434286 0.0018774 -0.000006 0.000027 0.000148 0.000123 0.0000086 0.0000121 0.000093 0.000108 1992 6 23 48796 -0.151026 0.360612 -0.5453192 0.0018688 0.000268 0.000165 0.000145 0.000120 0.0000086 0.0000122 0.000092 0.000106 1992 6 24 48797 -0.150179 0.361977 -0.5471834 0.0017994 0.000053 0.000001 0.000141 0.000117 0.0000086 0.0000122 0.000091 0.000103 1992 6 25 48798 -0.149047 0.364526 -0.5488953 0.0017138 -0.000063 -0.000218 0.000138 0.000115 0.0000086 0.0000121 0.000089 0.000100 1992 6 26 48799 -0.148733 0.366952 -0.5505096 0.0016294 -0.000155 -0.000448 0.000135 0.000112 0.0000085 0.0000121 0.000088 0.000098 1992 6 27 48800 -0.147229 0.369772 -0.5521300 0.0014930 -0.000129 -0.000394 0.000132 0.000110 0.0000085 0.0000119 0.000087 0.000095 1992 6 28 48801 -0.146465 0.371133 -0.5536406 0.0012750 0.000042 -0.000194 0.000129 0.000107 0.0000084 0.0000118 0.000085 0.000092 1992 6 29 48802 -0.145412 0.374137 -0.5547725 0.0010887 0.000230 -0.000046 0.000125 0.000105 0.0000082 0.0000116 0.000084 0.000090 1992 6 30 48803 -0.143768 0.377272 -0.5556797 0.0010872 0.000407 -0.000073 0.000122 0.000102 0.0000080 0.0000114 0.000082 0.000086 1992 7 1 48804 -0.142512 0.379060 0.4430613 0.0012508 0.000279 -0.000139 0.000119 0.000099 0.0000078 0.0000112 0.000080 0.000083 1992 7 2 48805 -0.141661 0.381518 0.4416665 0.0014592 -0.000071 -0.000187 0.000117 0.000098 0.0000078 0.0000111 0.000079 0.000082 1992 7 3 48806 -0.140222 0.383823 0.4401580 0.0016509 -0.000231 -0.000205 0.000117 0.000097 0.0000079 0.0000112 0.000079 0.000082 1992 7 4 48807 -0.138866 0.386695 0.4384428 0.0017823 -0.000039 -0.000205 0.000117 0.000097 0.0000080 0.0000113 0.000078 0.000082 1992 7 5 48808 -0.137556 0.388382 0.4366279 0.0018045 0.000153 -0.000205 0.000116 0.000096 0.0000080 0.0000114 0.000078 0.000082 1992 7 6 48809 -0.136357 0.391416 0.4348537 0.0017076 0.000346 -0.000206 0.000115 0.000095 0.0000081 0.0000115 0.000077 0.000082 1992 7 7 48810 -0.135285 0.393335 0.4332424 0.0015319 0.000475 -0.000203 0.000114 0.000094 0.0000082 0.0000116 0.000076 0.000082 1992 7 8 48811 -0.133086 0.394687 0.4318306 0.0013313 0.000284 -0.000186 0.000112 0.000092 0.0000082 0.0000116 0.000076 0.000081 1992 7 9 48812 -0.131090 0.397345 0.4305640 0.0011375 0.000078 -0.000195 0.000110 0.000091 0.0000082 0.0000116 0.000075 0.000080 1992 7 10 48813 -0.129074 0.398916 0.4295192 0.0009771 -0.000033 -0.000117 0.000108 0.000089 0.0000081 0.0000115 0.000074 0.000079 1992 7 11 48814 -0.128757 0.401940 0.4286134 0.0008775 -0.000034 -0.000054 0.000107 0.000088 0.0000080 0.0000114 0.000073 0.000078 1992 7 12 48815 -0.128212 0.405035 0.4277497 0.0008405 0.000014 -0.000005 0.000105 0.000087 0.0000079 0.0000112 0.000072 0.000077 1992 7 13 48816 -0.126544 0.407770 0.4268915 0.0008536 0.000062 0.000044 0.000102 0.000085 0.0000079 0.0000111 0.000072 0.000075 1992 7 14 48817 -0.127014 0.409473 0.4260105 0.0009120 0.000087 0.000071 0.000100 0.000083 0.0000078 0.0000110 0.000071 0.000074 1992 7 15 48818 -0.126292 0.410646 0.4250669 0.0010163 -0.000002 -0.000016 0.000097 0.000081 0.0000077 0.0000108 0.000070 0.000073 1992 7 16 48819 -0.124648 0.411885 0.4239923 0.0011511 -0.000091 -0.000104 0.000095 0.000079 0.0000076 0.0000107 0.000069 0.000072 1992 7 17 48820 -0.123155 0.413695 0.4227502 0.0012847 -0.000289 -0.000378 0.000092 0.000077 0.0000074 0.0000105 0.000068 0.000071 1992 7 18 48821 -0.120994 0.415906 0.4214165 0.0013987 -0.000280 -0.000414 0.000090 0.000075 0.0000073 0.0000103 0.000068 0.000070 1992 7 19 48822 -0.118516 0.417723 0.4199848 0.0014891 -0.000177 -0.000336 0.000087 0.000074 0.0000071 0.0000101 0.000067 0.000069 1992 7 20 48823 -0.115322 0.421288 0.4184589 0.0015443 -0.000067 -0.000246 0.000085 0.000072 0.0000070 0.0000099 0.000066 0.000068 1992 7 21 48824 -0.112639 0.423309 0.4169019 0.0015516 0.000028 -0.000179 0.000083 0.000070 0.0000068 0.0000096 0.000065 0.000066 1992 7 22 48825 -0.110313 0.425501 0.4153677 0.0015117 0.000043 -0.000229 0.000080 0.000069 0.0000066 0.0000094 0.000064 0.000065 1992 7 23 48826 -0.108113 0.428259 0.4138773 0.0014390 0.000012 -0.000221 0.000078 0.000067 0.0000065 0.0000092 0.000063 0.000064 1992 7 24 48827 -0.106515 0.430089 0.4125048 0.0013593 0.000043 -0.000199 0.000078 0.000067 0.0000063 0.0000089 0.000062 0.000063 1992 7 25 48828 -0.104250 0.432486 0.4111808 0.0012921 0.000044 -0.000295 0.000078 0.000067 0.0000061 0.0000087 0.000062 0.000062 1992 7 26 48829 -0.101426 0.433962 0.4098840 0.0012459 0.000006 -0.000372 0.000078 0.000067 0.0000060 0.0000084 0.000061 0.000061 1992 7 27 48830 -0.099689 0.436423 0.4086425 0.0012480 0.000024 -0.000285 0.000077 0.000067 0.0000058 0.0000082 0.000060 0.000060 1992 7 28 48831 -0.098064 0.438150 0.4073584 0.0013349 0.000127 -0.000327 0.000077 0.000066 0.0000056 0.0000080 0.000059 0.000058 1992 7 29 48832 -0.096557 0.439363 0.4059471 0.0015153 0.000216 -0.000426 0.000076 0.000066 0.0000054 0.0000077 0.000058 0.000057 1992 7 30 48833 -0.094837 0.441244 0.4043209 0.0017538 0.000105 -0.000364 0.000076 0.000065 0.0000053 0.0000075 0.000057 0.000056 1992 7 31 48834 -0.092167 0.443003 0.4024589 0.0019816 -0.000053 -0.000176 0.000075 0.000065 0.0000052 0.0000074 0.000057 0.000055 1992 8 1 48835 -0.090220 0.445682 0.4004051 0.0021257 -0.000159 0.000008 0.000075 0.000065 0.0000051 0.0000073 0.000056 0.000054 1992 8 2 48836 -0.088067 0.448202 0.3982526 0.0021401 -0.000186 -0.000013 0.000075 0.000065 0.0000051 0.0000072 0.000056 0.000054 1992 8 3 48837 -0.085925 0.451085 0.3961540 0.0020306 -0.000140 -0.000130 0.000076 0.000065 0.0000051 0.0000072 0.000056 0.000054 1992 8 4 48838 -0.084220 0.453000 0.3942233 0.0018477 -0.000042 -0.000153 0.000076 0.000066 0.0000051 0.0000072 0.000056 0.000054 1992 8 5 48839 -0.082111 0.454462 0.3924684 0.0016463 0.000021 -0.000162 0.000076 0.000066 0.0000051 0.0000072 0.000056 0.000053 1992 8 6 48840 -0.080080 0.456440 0.3909023 0.0014631 -0.000018 -0.000221 0.000076 0.000066 0.0000051 0.0000072 0.000056 0.000053 1992 8 7 48841 -0.078458 0.458149 0.3895277 0.0013219 -0.000051 -0.000240 0.000077 0.000067 0.0000051 0.0000072 0.000056 0.000053 1992 8 8 48842 -0.076788 0.460718 0.3882490 0.0012286 -0.000090 -0.000321 0.000078 0.000068 0.0000051 0.0000073 0.000056 0.000053 1992 8 9 48843 -0.074463 0.463124 0.3870210 0.0011813 -0.000156 -0.000264 0.000079 0.000069 0.0000052 0.0000073 0.000056 0.000053 1992 8 10 48844 -0.072526 0.465779 0.3858453 0.0012015 -0.000186 -0.000154 0.000080 0.000070 0.0000053 0.0000075 0.000057 0.000054 1992 8 11 48845 -0.070560 0.468661 0.3846395 0.0013153 -0.000107 -0.000164 0.000081 0.000072 0.0000054 0.0000077 0.000058 0.000055 1992 8 12 48846 -0.068674 0.471225 0.3832319 0.0014995 -0.000133 -0.000286 0.000083 0.000074 0.0000056 0.0000079 0.000058 0.000056 1992 8 13 48847 -0.066580 0.473647 0.3816205 0.0016896 -0.000065 -0.000276 0.000085 0.000077 0.0000058 0.0000081 0.000059 0.000057 1992 8 14 48848 -0.064570 0.475030 0.3798456 0.0018314 -0.000082 -0.000250 0.000088 0.000079 0.0000059 0.0000084 0.000060 0.000059 1992 8 15 48849 -0.062794 0.476717 0.3779655 0.0019022 -0.000136 -0.000229 0.000090 0.000082 0.0000061 0.0000086 0.000061 0.000060 1992 8 16 48850 -0.059571 0.478950 0.3760519 0.0019087 -0.000191 -0.000208 0.000093 0.000084 0.0000063 0.0000089 0.000062 0.000062 1992 8 17 48851 -0.057692 0.480796 0.3741623 0.0018760 -0.000245 -0.000187 0.000095 0.000087 0.0000065 0.0000092 0.000063 0.000063 1992 8 18 48852 -0.055240 0.482200 0.3723299 0.0018298 -0.000277 -0.000190 0.000098 0.000089 0.0000067 0.0000094 0.000064 0.000065 1992 8 19 48853 -0.051638 0.483359 0.3705472 0.0017734 -0.000196 -0.000315 0.000100 0.000092 0.0000069 0.0000097 0.000064 0.000066 1992 8 20 48854 -0.048865 0.484993 0.3687686 0.0016895 -0.000040 -0.000297 0.000102 0.000094 0.0000071 0.0000100 0.000065 0.000068 1992 8 21 48855 -0.045377 0.486718 0.3670971 0.0015922 0.000130 -0.000250 0.000105 0.000097 0.0000073 0.0000103 0.000066 0.000070 1992 8 22 48856 -0.043334 0.488206 0.3656210 0.0015495 0.000205 -0.000207 0.000108 0.000099 0.0000074 0.0000105 0.000067 0.000073 1992 8 23 48857 -0.040569 0.489647 0.3640347 0.0015943 0.000232 -0.000094 0.000110 0.000101 0.0000076 0.0000107 0.000068 0.000075 1992 8 24 48858 -0.036680 0.490536 0.3623384 0.0017087 0.000226 -0.000062 0.000112 0.000103 0.0000077 0.0000109 0.000069 0.000076 1992 8 25 48859 -0.033129 0.490917 0.3605650 0.0018952 0.000189 -0.000160 0.000114 0.000104 0.0000079 0.0000111 0.000070 0.000078 1992 8 26 48860 -0.029826 0.492049 0.3585496 0.0021535 0.000149 -0.000252 0.000115 0.000105 0.0000079 0.0000112 0.000071 0.000079 1992 8 27 48861 -0.027311 0.493735 0.3562666 0.0024374 0.000131 -0.000041 0.000115 0.000105 0.0000079 0.0000112 0.000071 0.000080 1992 8 28 48862 -0.024173 0.495560 0.3537190 0.0026642 -0.000118 0.000020 0.000115 0.000105 0.0000080 0.0000113 0.000071 0.000081 1992 8 29 48863 -0.021492 0.497256 0.3509800 0.0027468 -0.000201 0.000097 0.000116 0.000105 0.0000080 0.0000112 0.000072 0.000081 1992 8 30 48864 -0.017694 0.498565 0.3482533 0.0026475 -0.000166 0.000012 0.000117 0.000105 0.0000079 0.0000112 0.000072 0.000081 1992 8 31 48865 -0.014885 0.501092 0.3457208 0.0024037 -0.000166 -0.000096 0.000118 0.000105 0.0000079 0.0000111 0.000072 0.000081 1992 9 1 48866 -0.013437 0.502381 0.3434716 0.0020956 -0.000204 -0.000142 0.000118 0.000105 0.0000078 0.0000110 0.000071 0.000080 1992 9 2 48867 -0.011137 0.502104 0.3415253 0.0017997 -0.000187 -0.000110 0.000119 0.000104 0.0000077 0.0000109 0.000071 0.000079 1992 9 3 48868 -0.010278 0.502431 0.3398472 0.0015661 -0.000165 -0.000206 0.000120 0.000105 0.0000076 0.0000108 0.000071 0.000079 1992 9 4 48869 -0.007249 0.501453 0.3383641 0.0014175 -0.000138 -0.000396 0.000122 0.000107 0.0000076 0.0000107 0.000072 0.000080 1992 9 5 48870 -0.003861 0.501438 0.3369871 0.0013597 -0.000041 -0.000474 0.000124 0.000108 0.0000075 0.0000106 0.000072 0.000082 1992 9 6 48871 -0.002236 0.502682 0.3356250 0.0013889 0.000080 -0.000516 0.000125 0.000109 0.0000075 0.0000106 0.000073 0.000083 1992 9 7 48872 0.000628 0.503510 0.3341941 0.0014950 0.000201 -0.000557 0.000127 0.000110 0.0000074 0.0000105 0.000073 0.000084 1992 9 8 48873 0.003109 0.504501 0.3326274 0.0016574 0.000255 -0.000573 0.000128 0.000111 0.0000074 0.0000104 0.000074 0.000086 1992 9 9 48874 0.005072 0.505262 0.3308825 0.0018415 -0.000029 -0.000462 0.000130 0.000112 0.0000073 0.0000103 0.000074 0.000087 1992 9 10 48875 0.007520 0.506074 0.3289481 0.0020026 -0.000135 -0.000340 0.000131 0.000113 0.0000072 0.0000101 0.000075 0.000088 1992 9 11 48876 0.010280 0.505809 0.3268734 0.0021039 -0.000112 -0.000209 0.000132 0.000114 0.0000070 0.0000099 0.000075 0.000088 1992 9 12 48877 0.012645 0.506723 0.3247449 0.0021362 -0.000108 -0.000179 0.000133 0.000115 0.0000069 0.0000097 0.000075 0.000089 1992 9 13 48878 0.014766 0.507557 0.3226248 0.0021133 -0.000111 -0.000182 0.000134 0.000115 0.0000067 0.0000095 0.000075 0.000089 1992 9 14 48879 0.016802 0.505988 0.3205491 0.0020507 -0.000114 -0.000184 0.000133 0.000115 0.0000066 0.0000093 0.000075 0.000089 1992 9 15 48880 0.019053 0.507299 0.3185415 0.0019543 -0.000062 -0.000173 0.000133 0.000115 0.0000064 0.0000092 0.000075 0.000090 1992 9 16 48881 0.022146 0.508298 0.3166321 0.0018321 0.000261 -0.000089 0.000133 0.000114 0.0000064 0.0000091 0.000075 0.000090 1992 9 17 48882 0.024828 0.507315 0.3148683 0.0017127 0.000085 -0.000143 0.000133 0.000114 0.0000064 0.0000090 0.000075 0.000091 1992 9 18 48883 0.026513 0.508636 0.3132152 0.0016332 -0.000243 -0.000237 0.000132 0.000113 0.0000063 0.0000089 0.000075 0.000091 1992 9 19 48884 0.028942 0.508510 0.3115929 0.0016134 -0.000253 -0.000224 0.000132 0.000113 0.0000062 0.0000088 0.000075 0.000091 1992 9 20 48885 0.031979 0.507330 0.3099497 0.0016565 -0.000263 -0.000210 0.000132 0.000113 0.0000061 0.0000086 0.000075 0.000091 1992 9 21 48886 0.034122 0.506878 0.3082335 0.0017676 -0.000273 -0.000196 0.000132 0.000113 0.0000060 0.0000085 0.000075 0.000091 1992 9 22 48887 0.036206 0.506450 0.3063855 0.0019531 -0.000268 -0.000179 0.000132 0.000112 0.0000059 0.0000085 0.000075 0.000091 1992 9 23 48888 0.037942 0.507428 0.3043360 0.0021986 -0.000184 -0.000142 0.000131 0.000111 0.0000060 0.0000084 0.000075 0.000091 1992 9 24 48889 0.040167 0.506823 0.3020147 0.0024467 -0.000228 -0.000109 0.000131 0.000112 0.0000060 0.0000084 0.000075 0.000091 1992 9 25 48890 0.042554 0.506337 0.2994654 0.0026176 -0.000297 -0.000078 0.000133 0.000113 0.0000060 0.0000084 0.000075 0.000091 1992 9 26 48891 0.044360 0.507008 0.2968158 0.0026585 -0.000316 -0.000068 0.000134 0.000115 0.0000059 0.0000083 0.000074 0.000091 1992 9 27 48892 0.047134 0.505752 0.2941963 0.0025685 -0.000335 -0.000058 0.000135 0.000116 0.0000058 0.0000082 0.000074 0.000090 1992 9 28 48893 0.048722 0.505695 0.2917139 0.0023895 -0.000353 -0.000048 0.000135 0.000116 0.0000058 0.0000081 0.000073 0.000089 1992 9 29 48894 0.050325 0.505595 0.2894260 0.0021803 -0.000361 -0.000035 0.000135 0.000117 0.0000057 0.0000080 0.000073 0.000088 1992 9 30 48895 0.053722 0.504107 0.2873361 0.0019920 -0.000311 -0.000001 0.000135 0.000117 0.0000056 0.0000079 0.000072 0.000086 1992 10 1 48896 0.056050 0.503357 0.2854106 0.0018560 -0.000261 0.000032 0.000134 0.000117 0.0000055 0.0000077 0.000072 0.000085 1992 10 2 48897 0.058117 0.502708 0.2835930 0.0017849 -0.000214 0.000057 0.000134 0.000116 0.0000054 0.0000076 0.000071 0.000084 1992 10 3 48898 0.061224 0.502278 0.2818180 0.0017807 -0.000202 -0.000017 0.000132 0.000115 0.0000053 0.0000075 0.000070 0.000082 1992 10 4 48899 0.063415 0.502333 0.2800174 0.0018394 -0.000190 -0.000091 0.000131 0.000114 0.0000052 0.0000073 0.000070 0.000080 1992 10 5 48900 0.065742 0.502938 0.2781301 0.0019513 -0.000179 -0.000165 0.000129 0.000113 0.0000051 0.0000072 0.000069 0.000079 1992 10 6 48901 0.068717 0.503066 0.2761097 0.0020985 -0.000197 -0.000240 0.000126 0.000111 0.0000051 0.0000072 0.000069 0.000077 1992 10 7 48902 0.071627 0.502619 0.2739330 0.0022545 -0.000367 -0.000319 0.000124 0.000110 0.0000050 0.0000071 0.000068 0.000076 1992 10 8 48903 0.075737 0.501788 0.2716068 0.0023892 -0.000537 -0.000398 0.000121 0.000108 0.0000050 0.0000071 0.000068 0.000075 1992 10 9 48904 0.078302 0.501295 0.2691664 0.0024768 -0.000682 -0.000462 0.000118 0.000105 0.0000050 0.0000071 0.000068 0.000074 1992 10 10 48905 0.080170 0.501350 0.2666680 0.0025023 -0.000572 -0.000366 0.000114 0.000102 0.0000050 0.0000070 0.000067 0.000072 1992 10 11 48906 0.082969 0.500260 0.2641771 0.0024645 -0.000461 -0.000269 0.000111 0.000099 0.0000049 0.0000070 0.000066 0.000070 1992 10 12 48907 0.084396 0.499119 0.2617530 0.0023761 -0.000350 -0.000173 0.000107 0.000096 0.0000049 0.0000069 0.000066 0.000069 1992 10 13 48908 0.086740 0.497731 0.2594368 0.0022605 -0.000233 -0.000100 0.000103 0.000093 0.0000048 0.0000068 0.000065 0.000068 1992 10 14 48909 0.089844 0.496252 0.2572402 0.0021471 -0.000086 -0.000144 0.000100 0.000091 0.0000048 0.0000068 0.000064 0.000066 1992 10 15 48910 0.092324 0.495719 0.2551396 0.0020636 -0.000071 -0.000142 0.000100 0.000090 0.0000048 0.0000068 0.000065 0.000067 1992 10 16 48911 0.095625 0.495658 0.2530932 0.0020329 -0.000103 -0.000126 0.000102 0.000091 0.0000049 0.0000069 0.000065 0.000068 1992 10 17 48912 0.098587 0.495459 0.2510425 0.0020731 -0.000156 -0.000131 0.000104 0.000092 0.0000050 0.0000070 0.000065 0.000069 1992 10 18 48913 0.100194 0.495020 0.2489125 0.0021965 -0.000209 -0.000137 0.000106 0.000092 0.0000050 0.0000071 0.000065 0.000070 1992 10 19 48914 0.101858 0.495041 0.2466213 0.0024043 -0.000262 -0.000142 0.000107 0.000092 0.0000051 0.0000072 0.000066 0.000071 1992 10 20 48915 0.103781 0.493979 0.2440995 0.0026754 -0.000281 -0.000155 0.000108 0.000092 0.0000051 0.0000073 0.000066 0.000071 1992 10 21 48916 0.105624 0.492509 0.2413028 0.0029532 -0.000099 -0.000219 0.000109 0.000092 0.0000053 0.0000075 0.000066 0.000072 1992 10 22 48917 0.107960 0.491178 0.2382126 0.0031495 -0.000050 -0.000182 0.000110 0.000092 0.0000054 0.0000077 0.000066 0.000073 1992 10 23 48918 0.110459 0.489854 0.2349931 0.0031981 -0.000069 -0.000113 0.000112 0.000093 0.0000056 0.0000079 0.000067 0.000073 1992 10 24 48919 0.112658 0.489289 0.2318579 0.0031042 -0.000336 -0.000084 0.000113 0.000094 0.0000057 0.0000080 0.000067 0.000074 1992 10 25 48920 0.114879 0.488519 0.2288600 0.0029147 -0.000314 -0.000014 0.000115 0.000095 0.0000058 0.0000082 0.000067 0.000074 1992 10 26 48921 0.117146 0.488133 0.2260509 0.0026730 -0.000085 0.000085 0.000117 0.000096 0.0000059 0.0000083 0.000067 0.000073 1992 10 27 48922 0.118825 0.487111 0.2234890 0.0024245 0.000097 0.000147 0.000118 0.000097 0.0000059 0.0000083 0.000067 0.000073 1992 10 28 48923 0.120551 0.485361 0.2211702 0.0022223 0.000045 0.000024 0.000119 0.000097 0.0000059 0.0000084 0.000067 0.000072 1992 10 29 48924 0.121962 0.484304 0.2190195 0.0021089 -0.000008 -0.000100 0.000120 0.000097 0.0000060 0.0000084 0.000067 0.000072 1992 10 30 48925 0.122845 0.483238 0.2169378 0.0020934 -0.000051 -0.000220 0.000121 0.000097 0.0000060 0.0000085 0.000066 0.000071 1992 10 31 48926 0.124954 0.481091 0.2148319 0.0021464 0.000002 -0.000305 0.000120 0.000096 0.0000060 0.0000085 0.000066 0.000070 1992 11 1 48927 0.127362 0.479054 0.2126298 0.0022162 -0.000082 -0.000298 0.000120 0.000095 0.0000060 0.0000084 0.000066 0.000069 1992 11 2 48928 0.129480 0.478173 0.2103529 0.0022688 -0.000168 -0.000234 0.000119 0.000094 0.0000059 0.0000084 0.000066 0.000068 1992 11 3 48929 0.131876 0.476806 0.2080716 0.0023187 -0.000023 -0.000213 0.000118 0.000093 0.0000059 0.0000084 0.000066 0.000069 1992 11 4 48930 0.133916 0.475761 0.2057703 0.0023948 -0.000144 -0.000576 0.000118 0.000092 0.0000059 0.0000083 0.000066 0.000070 1992 11 5 48931 0.135701 0.474807 0.2033152 0.0024789 -0.000172 -0.000680 0.000117 0.000091 0.0000058 0.0000083 0.000066 0.000071 1992 11 6 48932 0.136986 0.473524 0.2007949 0.0025244 -0.000144 -0.000410 0.000116 0.000090 0.0000058 0.0000081 0.000066 0.000071 1992 11 7 48933 0.138115 0.472253 0.1982739 0.0025100 -0.000120 -0.000255 0.000116 0.000089 0.0000057 0.0000080 0.000066 0.000072 1992 11 8 48934 0.139638 0.470688 0.1957939 0.0024412 -0.000107 -0.000222 0.000117 0.000090 0.0000056 0.0000079 0.000067 0.000072 1992 11 9 48935 0.140969 0.469166 0.1934031 0.0023381 -0.000094 -0.000189 0.000117 0.000090 0.0000055 0.0000078 0.000067 0.000072 1992 11 10 48936 0.143001 0.466966 0.1911277 0.0022286 -0.000083 -0.000123 0.000117 0.000090 0.0000054 0.0000077 0.000067 0.000073 1992 11 11 48937 0.145061 0.465340 0.1889572 0.0021394 -0.000079 0.000106 0.000117 0.000090 0.0000054 0.0000077 0.000067 0.000073 1992 11 12 48938 0.147086 0.463504 0.1868374 0.0020876 -0.000063 0.000023 0.000116 0.000091 0.0000054 0.0000077 0.000067 0.000074 1992 11 13 48939 0.149856 0.461327 0.1847368 0.0020883 -0.000042 -0.000166 0.000116 0.000091 0.0000054 0.0000076 0.000068 0.000074 1992 11 14 48940 0.151785 0.460263 0.1826211 0.0021648 0.000072 -0.000171 0.000116 0.000091 0.0000054 0.0000076 0.000068 0.000073 1992 11 15 48941 0.153616 0.459328 0.1803926 0.0023302 0.000064 -0.000081 0.000115 0.000092 0.0000054 0.0000076 0.000067 0.000073 1992 11 16 48942 0.155704 0.458494 0.1779566 0.0025633 -0.000039 0.000026 0.000115 0.000092 0.0000054 0.0000076 0.000067 0.000072 1992 11 17 48943 0.158237 0.457191 0.1752742 0.0028089 -0.000117 0.000089 0.000115 0.000092 0.0000054 0.0000076 0.000067 0.000072 1992 11 18 48944 0.160173 0.456081 0.1723651 0.0029974 -0.000069 -0.000068 0.000114 0.000091 0.0000053 0.0000075 0.000067 0.000071 1992 11 19 48945 0.161828 0.455229 0.1693040 0.0030681 -0.000133 -0.000234 0.000113 0.000091 0.0000053 0.0000075 0.000067 0.000070 1992 11 20 48946 0.164749 0.453766 0.1662385 0.0030007 -0.000278 -0.000408 0.000112 0.000090 0.0000053 0.0000074 0.000066 0.000069 1992 11 21 48947 0.166587 0.452176 0.1633279 0.0028334 -0.000288 -0.000335 0.000111 0.000089 0.0000052 0.0000073 0.000066 0.000068 1992 11 22 48948 0.168134 0.450503 0.1606133 0.0026352 -0.000028 -0.000180 0.000112 0.000089 0.0000051 0.0000073 0.000066 0.000068 1992 11 23 48949 0.169171 0.448948 0.1580756 0.0024617 0.000062 -0.000101 0.000113 0.000091 0.0000052 0.0000073 0.000066 0.000069 1992 11 24 48950 0.170112 0.446942 0.1556783 0.0023376 -0.000197 -0.000171 0.000115 0.000093 0.0000052 0.0000074 0.000066 0.000070 1992 11 25 48951 0.171363 0.444565 0.1533727 0.0022608 0.000062 -0.000405 0.000118 0.000095 0.0000053 0.0000075 0.000066 0.000070 1992 11 26 48952 0.171517 0.442100 0.1511240 0.0022132 0.000124 -0.000395 0.000120 0.000097 0.0000054 0.0000076 0.000066 0.000071 1992 11 27 48953 0.171899 0.439316 0.1489168 0.0021764 0.000117 -0.000298 0.000121 0.000098 0.0000055 0.0000078 0.000066 0.000071 1992 11 28 48954 0.172371 0.436916 0.1467470 0.0021481 0.000109 -0.000202 0.000123 0.000100 0.0000056 0.0000080 0.000067 0.000071 1992 11 29 48955 0.173400 0.434954 0.1446014 0.0021500 0.000102 -0.000106 0.000125 0.000101 0.0000057 0.0000081 0.000067 0.000072 1992 11 30 48956 0.174182 0.432858 0.1424398 0.0022188 0.000095 -0.000010 0.000126 0.000102 0.0000059 0.0000083 0.000067 0.000072 1992 12 1 48957 0.175115 0.430424 0.1401982 0.0023732 0.000019 -0.000012 0.000127 0.000103 0.0000060 0.0000085 0.000067 0.000072 1992 12 2 48958 0.175851 0.428067 0.1377636 0.0025711 -0.000395 -0.000503 0.000127 0.000104 0.0000061 0.0000086 0.000067 0.000073 1992 12 3 48959 0.176011 0.426068 0.1350332 0.0027129 -0.000201 -0.000331 0.000127 0.000104 0.0000062 0.0000087 0.000067 0.000073 1992 12 4 48960 0.177832 0.424243 0.1322807 0.0027430 -0.000130 -0.000031 0.000128 0.000105 0.0000062 0.0000088 0.000067 0.000073 1992 12 5 48961 0.179504 0.422839 0.1295814 0.0026923 -0.000175 0.000044 0.000128 0.000105 0.0000062 0.0000088 0.000067 0.000073 1992 12 6 48962 0.180401 0.421301 0.1269413 0.0026088 -0.000255 0.000041 0.000128 0.000106 0.0000062 0.0000088 0.000068 0.000073 1992 12 7 48963 0.180980 0.419093 0.1243708 0.0025179 -0.000304 -0.000007 0.000129 0.000107 0.0000063 0.0000089 0.000068 0.000073 1992 12 8 48964 0.181951 0.417154 0.1218940 0.0024358 -0.000308 -0.000044 0.000131 0.000109 0.0000063 0.0000090 0.000068 0.000073 1992 12 9 48965 0.183382 0.415301 0.1195074 0.0023813 -0.000166 0.000087 0.000132 0.000110 0.0000064 0.0000090 0.000068 0.000073 1992 12 10 48966 0.184160 0.412799 0.1171205 0.0023618 -0.000280 0.000011 0.000134 0.000111 0.0000065 0.0000092 0.000068 0.000074 1992 12 11 48967 0.184528 0.410684 0.1147163 0.0023817 -0.000480 -0.000133 0.000134 0.000112 0.0000065 0.0000092 0.000068 0.000074 1992 12 12 48968 0.185789 0.408749 0.1123032 0.0024653 -0.000461 -0.000123 0.000135 0.000112 0.0000065 0.0000092 0.000068 0.000074 1992 12 13 48969 0.188014 0.406143 0.1097977 0.0026300 -0.000369 -0.000060 0.000135 0.000113 0.0000065 0.0000092 0.000068 0.000074 1992 12 14 48970 0.189180 0.404450 0.1070933 0.0028342 -0.000277 0.000003 0.000136 0.000112 0.0000065 0.0000092 0.000068 0.000074 1992 12 15 48971 0.189740 0.402857 0.1041447 0.0029833 -0.000212 0.000060 0.000135 0.000112 0.0000065 0.0000092 0.000068 0.000073 1992 12 16 48972 0.190061 0.400537 0.1010661 0.0030133 -0.000284 0.000091 0.000135 0.000112 0.0000065 0.0000091 0.000068 0.000073 1992 12 17 48973 0.191162 0.398845 0.0981664 0.0029575 -0.000356 0.000007 0.000135 0.000112 0.0000064 0.0000090 0.000067 0.000072 1992 12 18 48974 0.192524 0.396544 0.0952962 0.0028557 -0.000427 -0.000147 0.000134 0.000111 0.0000063 0.0000089 0.000067 0.000072 1992 12 19 48975 0.193210 0.393613 0.0924568 0.0026751 -0.000300 -0.000211 0.000133 0.000111 0.0000062 0.0000087 0.000066 0.000071 1992 12 20 48976 0.193949 0.391114 0.0898537 0.0024068 -0.000108 -0.000245 0.000131 0.000110 0.0000061 0.0000085 0.000065 0.000070 1992 12 21 48977 0.193799 0.388467 0.0876219 0.0021377 0.000048 -0.000245 0.000130 0.000109 0.0000059 0.0000083 0.000065 0.000069 1992 12 22 48978 0.194414 0.385439 0.0856299 0.0019721 -0.000031 -0.000102 0.000128 0.000108 0.0000057 0.0000081 0.000064 0.000068 1992 12 23 48979 0.195668 0.382887 0.0836756 0.0019347 -0.000011 -0.000118 0.000126 0.000107 0.0000056 0.0000079 0.000064 0.000067 1992 12 24 48980 0.196674 0.380390 0.0817044 0.0019876 -0.000037 -0.000123 0.000124 0.000105 0.0000055 0.0000078 0.000063 0.000066 1992 12 25 48981 0.197816 0.377551 0.0796652 0.0020910 -0.000080 -0.000123 0.000123 0.000105 0.0000054 0.0000076 0.000062 0.000065 1992 12 26 48982 0.199216 0.374805 0.0775127 0.0022203 -0.000122 -0.000123 0.000121 0.000103 0.0000052 0.0000074 0.000062 0.000064 1992 12 27 48983 0.201037 0.371951 0.0752261 0.0023593 -0.000164 -0.000123 0.000119 0.000102 0.0000051 0.0000072 0.000061 0.000063 1992 12 28 48984 0.202873 0.369834 0.0728015 0.0024948 -0.000140 -0.000111 0.000117 0.000100 0.0000050 0.0000071 0.000061 0.000062 1992 12 29 48985 0.205227 0.366902 0.0702486 0.0026120 -0.000046 -0.000102 0.000115 0.000099 0.0000049 0.0000070 0.000060 0.000061 1992 12 30 48986 0.206771 0.364691 0.0675922 0.0026943 -0.000101 -0.000211 0.000113 0.000097 0.0000049 0.0000070 0.000060 0.000060 1992 12 31 48987 0.207664 0.363725 0.0648738 0.0027277 0.000258 -0.000196 0.000112 0.000097 0.0000049 0.0000070 0.000060 0.000060 1993 1 1 48988 0.208497 0.359631 0.0621460 0.0027066 0.000353 -0.000186 0.000113 0.000098 0.0000050 0.0000070 0.000060 0.000061 1993 1 2 48989 0.208121 0.355705 0.0594291 0.0026771 0.000239 -0.000191 0.000162 0.000154 0.0000065 0.0000092 0.000063 0.000061 1993 1 3 48990 0.208559 0.352928 0.0567996 0.0025727 0.000131 -0.000207 0.000162 0.000154 0.0000065 0.0000092 0.000063 0.000061 1993 1 4 48991 0.208158 0.350234 0.0542850 0.0024790 0.000023 -0.000223 0.000162 0.000153 0.0000066 0.0000093 0.000063 0.000061 1993 1 5 48992 0.208496 0.347343 0.0518348 0.0024352 -0.000080 -0.000226 0.000162 0.000152 0.0000066 0.0000093 0.000063 0.000061 1993 1 6 48993 0.208620 0.344250 0.0493976 0.0024203 -0.000158 -0.000168 0.000162 0.000151 0.0000066 0.0000093 0.000063 0.000060 1993 1 7 48994 0.210839 0.341366 0.0469672 0.0024299 -0.000115 -0.000079 0.000161 0.000151 0.0000066 0.0000093 0.000064 0.000061 1993 1 8 48995 0.209669 0.339557 0.0445058 0.0024988 -0.000065 0.000008 0.000161 0.000151 0.0000066 0.0000093 0.000064 0.000061 1993 1 9 48996 0.211995 0.336923 0.0419434 0.0026343 -0.000081 0.000041 0.000160 0.000151 0.0000065 0.0000092 0.000064 0.000061 1993 1 10 48997 0.213191 0.334591 0.0392283 0.0027680 -0.000097 0.000075 0.000158 0.000149 0.0000065 0.0000092 0.000064 0.000062 1993 1 11 48998 0.213076 0.331893 0.0364222 0.0028695 -0.000112 0.000108 0.000155 0.000148 0.0000064 0.0000091 0.000064 0.000062 1993 1 12 48999 0.214504 0.328361 0.0335242 0.0029444 -0.000127 0.000124 0.000153 0.000146 0.0000063 0.0000089 0.000064 0.000062 1993 1 13 49000 0.215103 0.327083 0.0305768 0.0029598 -0.000138 0.000049 0.000150 0.000143 0.0000062 0.0000088 0.000064 0.000061 1993 1 14 49001 0.215343 0.324551 0.0276422 0.0028938 -0.000150 -0.000025 0.000147 0.000141 0.0000061 0.0000087 0.000064 0.000061 1993 1 15 49002 0.215491 0.322564 0.0248116 0.0027242 -0.000161 -0.000100 0.000144 0.000138 0.0000060 0.0000085 0.000064 0.000061 1993 1 16 49003 0.213719 0.318715 0.0221987 0.0024888 -0.000124 -0.000094 0.000141 0.000134 0.0000059 0.0000083 0.000063 0.000060 1993 1 17 49004 0.212723 0.315368 0.0198247 0.0022736 -0.000071 -0.000062 0.000138 0.000131 0.0000057 0.0000081 0.000063 0.000059 1993 1 18 49005 0.212820 0.312966 0.0176326 0.0021211 -0.000019 -0.000031 0.000135 0.000128 0.0000056 0.0000079 0.000063 0.000058 1993 1 19 49006 0.212731 0.310563 0.0155584 0.0020411 0.000003 -0.000005 0.000132 0.000124 0.0000054 0.0000077 0.000063 0.000058 1993 1 20 49007 0.212486 0.307591 0.0135252 0.0020459 -0.000126 -0.000010 0.000129 0.000121 0.0000053 0.0000076 0.000063 0.000058 1993 1 21 49008 0.210939 0.304759 0.0114443 0.0021250 -0.000150 0.000028 0.000129 0.000121 0.0000053 0.0000076 0.000063 0.000059 1993 1 22 49009 0.212031 0.302168 0.0092594 0.0022334 -0.000097 0.000098 0.000133 0.000123 0.0000055 0.0000078 0.000064 0.000060 1993 1 23 49010 0.211130 0.299280 0.0069706 0.0023176 -0.000078 0.000116 0.000136 0.000125 0.0000057 0.0000080 0.000065 0.000062 1993 1 24 49011 0.211615 0.296449 0.0046261 0.0024007 -0.000071 0.000116 0.000139 0.000128 0.0000058 0.0000082 0.000066 0.000063 1993 1 25 49012 0.212014 0.295444 0.0021780 0.0025207 -0.000064 0.000117 0.000141 0.000129 0.0000059 0.0000084 0.000067 0.000065 1993 1 26 49013 0.211753 0.293321 -0.0004020 0.0026487 -0.000081 0.000111 0.000144 0.000131 0.0000061 0.0000086 0.000068 0.000066 1993 1 27 49014 0.211275 0.291078 -0.0031038 0.0027364 -0.000223 0.000070 0.000146 0.000132 0.0000062 0.0000088 0.000068 0.000068 1993 1 28 49015 0.211348 0.289137 -0.0058593 0.0027499 -0.000365 0.000030 0.000149 0.000134 0.0000063 0.0000090 0.000069 0.000070 1993 1 29 49016 0.210330 0.287063 -0.0085904 0.0027117 -0.000455 0.000244 0.000151 0.000136 0.0000065 0.0000091 0.000070 0.000071 1993 1 30 49017 0.209669 0.284326 -0.0112741 0.0026293 -0.000371 0.000173 0.000152 0.000138 0.0000065 0.0000093 0.000070 0.000071 1993 1 31 49018 0.208470 0.281234 -0.0138467 0.0025092 -0.000234 -0.000010 0.000153 0.000139 0.0000066 0.0000094 0.000070 0.000071 1993 2 1 49019 0.205686 0.279363 -0.0162977 0.0023887 -0.000097 -0.000192 0.000154 0.000141 0.0000067 0.0000095 0.000071 0.000072 1993 2 2 49020 0.205713 0.276122 -0.0186379 0.0023398 -0.000003 -0.000287 0.000154 0.000141 0.0000068 0.0000096 0.000071 0.000072 1993 2 3 49021 0.204437 0.273139 -0.0210000 0.0023927 -0.000149 0.000095 0.000154 0.000142 0.0000068 0.0000096 0.000071 0.000072 1993 2 4 49022 0.203929 0.270082 -0.0234532 0.0024570 0.000212 0.000402 0.000154 0.000142 0.0000068 0.0000096 0.000071 0.000071 1993 2 5 49023 0.205331 0.267270 -0.0259444 0.0026323 0.000622 0.000701 0.000154 0.000141 0.0000067 0.0000095 0.000070 0.000070 1993 2 6 49024 0.205065 0.265333 -0.0287377 0.0029318 0.000514 0.000557 0.000153 0.000141 0.0000067 0.0000094 0.000070 0.000069 1993 2 7 49025 0.206342 0.263476 -0.0318067 0.0031585 0.000352 0.000368 0.000152 0.000140 0.0000066 0.0000093 0.000069 0.000068 1993 2 8 49026 0.205972 0.261159 -0.0350283 0.0033041 0.000190 0.000178 0.000151 0.000138 0.0000065 0.0000092 0.000069 0.000067 1993 2 9 49027 0.204020 0.259050 -0.0383703 0.0033772 0.000017 0.000030 0.000149 0.000137 0.0000064 0.0000090 0.000068 0.000066 1993 2 10 49028 0.203910 0.255961 -0.0417351 0.0032982 -0.000216 0.000093 0.000146 0.000135 0.0000063 0.0000088 0.000067 0.000065 1993 2 11 49029 0.202421 0.253366 -0.0449319 0.0030930 -0.000201 0.000105 0.000144 0.000133 0.0000061 0.0000087 0.000067 0.000063 1993 2 12 49030 0.201740 0.250950 -0.0479076 0.0028031 -0.000086 0.000075 0.000142 0.000131 0.0000060 0.0000084 0.000066 0.000062 1993 2 13 49031 0.200170 0.248643 -0.0505451 0.0025262 -0.000108 -0.000071 0.000139 0.000129 0.0000058 0.0000083 0.000065 0.000060 1993 2 14 49032 0.198426 0.245970 -0.0529801 0.0023428 -0.000092 -0.000121 0.000140 0.000129 0.0000058 0.0000083 0.000064 0.000059 1993 2 15 49033 0.197631 0.243399 -0.0552556 0.0022000 -0.000031 -0.000104 0.000142 0.000131 0.0000059 0.0000083 0.000064 0.000059 1993 2 16 49034 0.197289 0.240425 -0.0574047 0.0021855 0.000023 -0.000088 0.000144 0.000133 0.0000059 0.0000084 0.000064 0.000059 1993 2 17 49035 0.196976 0.238058 -0.0596483 0.0022676 0.000049 -0.000075 0.000147 0.000136 0.0000061 0.0000086 0.000064 0.000060 1993 2 18 49036 0.196371 0.235650 -0.0619570 0.0023488 0.000075 -0.000061 0.000149 0.000138 0.0000062 0.0000087 0.000064 0.000061 1993 2 19 49037 0.195707 0.233226 -0.0643566 0.0024900 0.000100 -0.000047 0.000151 0.000140 0.0000063 0.0000089 0.000065 0.000062 1993 2 20 49038 0.195169 0.231509 -0.0669399 0.0026512 0.000025 -0.000025 0.000153 0.000141 0.0000064 0.0000090 0.000065 0.000063 1993 2 21 49039 0.193546 0.230323 -0.0696538 0.0027683 -0.000083 0.000001 0.000154 0.000142 0.0000065 0.0000092 0.000065 0.000064 1993 2 22 49040 0.191277 0.229367 -0.0724651 0.0028389 -0.000192 0.000026 0.000155 0.000143 0.0000066 0.0000093 0.000066 0.000065 1993 2 23 49041 0.189237 0.227693 -0.0753168 0.0028554 -0.000269 0.000055 0.000155 0.000143 0.0000067 0.0000094 0.000066 0.000066 1993 2 24 49042 0.186188 0.226054 -0.0781600 0.0028151 -0.000189 0.000102 0.000156 0.000143 0.0000068 0.0000096 0.000066 0.000066 1993 2 25 49043 0.183947 0.223108 -0.0809324 0.0027071 -0.000110 0.000149 0.000156 0.000143 0.0000069 0.0000097 0.000066 0.000067 1993 2 26 49044 0.182686 0.221122 -0.0835633 0.0025648 -0.000030 0.000197 0.000155 0.000143 0.0000069 0.0000098 0.000066 0.000067 1993 2 27 49045 0.180162 0.219225 -0.0860568 0.0024429 0.000039 0.000208 0.000154 0.000142 0.0000070 0.0000099 0.000066 0.000068 1993 2 28 49046 0.178366 0.217541 -0.0884514 0.0023260 0.000104 0.000208 0.000153 0.000141 0.0000071 0.0000100 0.000066 0.000068 1993 3 1 49047 0.176112 0.215231 -0.0907194 0.0022355 0.000169 0.000208 0.000152 0.000139 0.0000072 0.0000102 0.000066 0.000068 1993 3 2 49048 0.174206 0.212760 -0.0929413 0.0021954 0.000199 0.000209 0.000150 0.000137 0.0000073 0.0000103 0.000066 0.000068 1993 3 3 49049 0.172265 0.211485 -0.0951357 0.0022306 0.000046 0.000212 0.000147 0.000134 0.0000073 0.0000104 0.000066 0.000068 1993 3 4 49050 0.171207 0.209624 -0.0974311 0.0023909 -0.000107 0.000215 0.000145 0.000132 0.0000074 0.0000105 0.000066 0.000067 1993 3 5 49051 0.169613 0.208571 -0.0999421 0.0026095 -0.000180 0.000263 0.000142 0.000130 0.0000075 0.0000105 0.000066 0.000068 1993 3 6 49052 0.168055 0.207160 -0.1026610 0.0028217 -0.000187 0.000179 0.000139 0.000128 0.0000075 0.0000106 0.000066 0.000068 1993 3 7 49053 0.167109 0.204864 -0.1055745 0.0030246 -0.000172 0.000049 0.000137 0.000126 0.0000075 0.0000106 0.000066 0.000068 1993 3 8 49054 0.165619 0.203390 -0.1086760 0.0031940 -0.000156 -0.000081 0.000134 0.000124 0.0000075 0.0000106 0.000066 0.000068 1993 3 9 49055 0.163914 0.201977 -0.1119144 0.0032737 -0.000133 -0.000168 0.000131 0.000122 0.0000075 0.0000106 0.000067 0.000068 1993 3 10 49056 0.163086 0.199942 -0.1151773 0.0032095 -0.000074 -0.000045 0.000129 0.000121 0.0000076 0.0000107 0.000067 0.000069 1993 3 11 49057 0.162433 0.198633 -0.1183047 0.0030389 -0.000076 -0.000014 0.000128 0.000119 0.0000076 0.0000107 0.000067 0.000068 1993 3 12 49058 0.162410 0.197146 -0.1212507 0.0028520 -0.000083 0.000008 0.000127 0.000119 0.0000076 0.0000107 0.000068 0.000069 1993 3 13 49059 0.161543 0.195972 -0.1240246 0.0026803 -0.000039 -0.000009 0.000128 0.000120 0.0000076 0.0000107 0.000068 0.000069 1993 3 14 49060 0.159833 0.194807 -0.1266373 0.0025441 0.000022 -0.000038 0.000129 0.000121 0.0000076 0.0000107 0.000068 0.000068 1993 3 15 49061 0.158088 0.193293 -0.1291389 0.0024766 0.000083 -0.000067 0.000131 0.000122 0.0000075 0.0000106 0.000068 0.000068 1993 3 16 49062 0.155120 0.191748 -0.1316117 0.0024892 0.000127 -0.000065 0.000132 0.000123 0.0000074 0.0000105 0.000068 0.000068 1993 3 17 49063 0.153285 0.189887 -0.1341330 0.0025635 0.000085 0.000097 0.000134 0.000124 0.0000073 0.0000104 0.000068 0.000068 1993 3 18 49064 0.150047 0.188758 -0.1367494 0.0026356 0.000160 0.000135 0.000135 0.000125 0.0000072 0.0000102 0.000069 0.000068 1993 3 19 49065 0.148112 0.187457 -0.1394096 0.0026962 0.000231 0.000071 0.000136 0.000126 0.0000071 0.0000101 0.000068 0.000067 1993 3 20 49066 0.145704 0.186296 -0.1421408 0.0027975 0.000177 0.000064 0.000137 0.000127 0.0000070 0.0000099 0.000068 0.000066 1993 3 21 49067 0.144237 0.184596 -0.1449969 0.0028823 0.000081 0.000083 0.000138 0.000128 0.0000068 0.0000097 0.000068 0.000065 1993 3 22 49068 0.142607 0.182898 -0.1478929 0.0028853 -0.000015 0.000102 0.000138 0.000129 0.0000067 0.0000095 0.000068 0.000065 1993 3 23 49069 0.140517 0.181764 -0.1507527 0.0028566 -0.000077 0.000134 0.000139 0.000129 0.0000065 0.0000092 0.000067 0.000064 1993 3 24 49070 0.138217 0.180017 -0.1535914 0.0028284 0.000041 0.000227 0.000139 0.000129 0.0000064 0.0000090 0.000067 0.000063 1993 3 25 49071 0.135855 0.178967 -0.1563971 0.0027574 -0.000034 0.000069 0.000139 0.000129 0.0000062 0.0000089 0.000067 0.000062 1993 3 26 49072 0.132915 0.178150 -0.1590983 0.0025941 -0.000465 0.000141 0.000141 0.000131 0.0000063 0.0000089 0.000068 0.000063 1993 3 27 49073 0.130344 0.176980 -0.1615840 0.0024415 -0.000431 0.000155 0.000144 0.000134 0.0000064 0.0000090 0.000068 0.000064 1993 3 28 49074 0.126669 0.175259 -0.1639882 0.0023847 -0.000219 0.000133 0.000147 0.000138 0.0000065 0.0000092 0.000069 0.000065 1993 3 29 49075 0.123147 0.173956 -0.1663685 0.0023253 -0.000007 0.000111 0.000151 0.000141 0.0000066 0.0000093 0.000069 0.000067 1993 3 30 49076 0.120314 0.172735 -0.1686608 0.0023046 0.000165 0.000093 0.000154 0.000144 0.0000067 0.0000095 0.000070 0.000068 1993 3 31 49077 0.117415 0.171113 -0.1710028 0.0023829 0.000132 0.000089 0.000157 0.000147 0.0000068 0.0000096 0.000071 0.000069 1993 4 1 49078 0.114867 0.170147 -0.1734500 0.0025253 0.000100 0.000086 0.000159 0.000149 0.0000069 0.0000097 0.000071 0.000071 1993 4 2 49079 0.112184 0.169333 -0.1760686 0.0027428 0.000068 0.000083 0.000162 0.000152 0.0000070 0.0000099 0.000072 0.000073 1993 4 3 49080 0.110399 0.169187 -0.1789357 0.0029936 0.000059 0.000107 0.000164 0.000154 0.0000071 0.0000100 0.000072 0.000074 1993 4 4 49081 0.106876 0.168459 -0.1820362 0.0031939 0.000059 0.000142 0.000165 0.000156 0.0000072 0.0000102 0.000073 0.000075 1993 4 5 49082 0.103355 0.167784 -0.1852860 0.0033183 0.000059 0.000176 0.000166 0.000158 0.0000073 0.0000103 0.000073 0.000077 1993 4 6 49083 0.100116 0.167280 -0.1886272 0.0033494 0.000054 0.000203 0.000167 0.000159 0.0000074 0.0000104 0.000074 0.000078 1993 4 7 49084 0.096541 0.166869 -0.1919461 0.0032328 0.000027 0.000193 0.000167 0.000160 0.0000074 0.0000105 0.000074 0.000079 1993 4 8 49085 0.093084 0.166473 -0.1950735 0.0030341 0.000000 0.000184 0.000167 0.000160 0.0000075 0.0000106 0.000074 0.000079 1993 4 9 49086 0.090184 0.166262 -0.1980186 0.0028633 0.000006 0.000159 0.000167 0.000161 0.0000075 0.0000106 0.000074 0.000080 1993 4 10 49087 0.087203 0.165612 -0.2008220 0.0027280 0.000024 0.000129 0.000167 0.000161 0.0000075 0.0000107 0.000074 0.000080 1993 4 11 49088 0.083817 0.163696 -0.2035025 0.0026372 0.000042 0.000099 0.000166 0.000160 0.0000076 0.0000107 0.000074 0.000081 1993 4 12 49089 0.081166 0.163916 -0.2061206 0.0026140 0.000060 0.000069 0.000164 0.000159 0.0000076 0.0000107 0.000074 0.000081 1993 4 13 49090 0.079238 0.164253 -0.2087466 0.0026544 0.000103 0.000088 0.000162 0.000158 0.0000076 0.0000107 0.000074 0.000081 1993 4 14 49091 0.077130 0.164254 -0.2114383 0.0027408 0.000272 0.000356 0.000160 0.000156 0.0000076 0.0000107 0.000074 0.000081 1993 4 15 49092 0.076031 0.164301 -0.2142323 0.0028497 0.000459 0.000320 0.000158 0.000154 0.0000076 0.0000107 0.000074 0.000081 1993 4 16 49093 0.073997 0.164838 -0.2171377 0.0029405 0.000234 -0.000135 0.000156 0.000153 0.0000076 0.0000107 0.000073 0.000080 1993 4 17 49094 0.072080 0.163396 -0.2201086 0.0029801 0.000226 -0.000225 0.000154 0.000152 0.0000075 0.0000106 0.000073 0.000079 1993 4 18 49095 0.069993 0.163333 -0.2230883 0.0029663 0.000268 -0.000235 0.000153 0.000151 0.0000074 0.0000105 0.000073 0.000077 1993 4 19 49096 0.067650 0.164056 -0.2260283 0.0029114 0.000310 -0.000245 0.000151 0.000149 0.0000074 0.0000104 0.000072 0.000076 1993 4 20 49097 0.064020 0.163516 -0.2288976 0.0028406 0.000240 -0.000251 0.000149 0.000147 0.0000073 0.0000103 0.000072 0.000075 1993 4 21 49098 0.062009 0.164585 -0.2316975 0.0027906 -0.000394 -0.000236 0.000147 0.000145 0.0000072 0.0000101 0.000071 0.000074 1993 4 22 49099 0.059313 0.164236 -0.2344701 0.0027867 -0.000132 -0.000011 0.000145 0.000143 0.0000070 0.0000100 0.000070 0.000072 1993 4 23 49100 0.056588 0.164616 -0.2372672 0.0027366 0.000079 0.000000 0.000143 0.000141 0.0000069 0.0000098 0.000069 0.000070 1993 4 24 49101 0.053584 0.164323 -0.2399468 0.0025990 0.000136 -0.000100 0.000141 0.000139 0.0000067 0.0000095 0.000068 0.000068 1993 4 25 49102 0.051415 0.164246 -0.2424772 0.0025263 0.000150 -0.000223 0.000138 0.000137 0.0000066 0.0000093 0.000068 0.000067 1993 4 26 49103 0.048478 0.164057 -0.2450189 0.0025383 0.000165 -0.000345 0.000136 0.000134 0.0000064 0.0000090 0.000067 0.000065 1993 4 27 49104 0.045676 0.164059 -0.2475775 0.0025744 0.000140 -0.000395 0.000133 0.000131 0.0000062 0.0000088 0.000066 0.000064 1993 4 28 49105 0.044544 0.164417 -0.2501897 0.0027079 -0.000084 -0.000079 0.000130 0.000128 0.0000060 0.0000086 0.000065 0.000062 1993 4 29 49106 0.041431 0.164672 -0.2530080 0.0029629 -0.000066 0.000024 0.000128 0.000125 0.0000059 0.0000084 0.000064 0.000061 1993 4 30 49107 0.039674 0.165091 -0.2561184 0.0031662 0.000194 0.000083 0.000128 0.000125 0.0000059 0.0000083 0.000064 0.000061 1993 5 1 49108 0.038423 0.165652 -0.2593287 0.0033609 0.000236 0.000174 0.000129 0.000126 0.0000059 0.0000083 0.000064 0.000061 1993 5 2 49109 0.036409 0.165806 -0.2628141 0.0035072 0.000191 0.000278 0.000130 0.000126 0.0000059 0.0000083 0.000064 0.000061 1993 5 3 49110 0.034557 0.165763 -0.2663068 0.0034685 0.000169 0.000312 0.000130 0.000125 0.0000059 0.0000083 0.000064 0.000061 1993 5 4 49111 0.033392 0.166343 -0.2697137 0.0033005 0.000210 0.000166 0.000129 0.000124 0.0000058 0.0000082 0.000063 0.000061 1993 5 5 49112 0.030832 0.166634 -0.2728810 0.0030474 0.000309 0.000168 0.000129 0.000123 0.0000058 0.0000082 0.000063 0.000061 1993 5 6 49113 0.029499 0.166885 -0.2758006 0.0027808 0.000188 0.000007 0.000128 0.000122 0.0000057 0.0000081 0.000062 0.000060 1993 5 7 49114 0.027245 0.166947 -0.2784549 0.0025581 -0.000069 -0.000159 0.000128 0.000121 0.0000057 0.0000080 0.000062 0.000059 1993 5 8 49115 0.024689 0.166763 -0.2809423 0.0024381 -0.000074 0.000006 0.000127 0.000120 0.0000056 0.0000079 0.000061 0.000058 1993 5 9 49116 0.022977 0.166141 -0.2833588 0.0023857 0.000062 0.000331 0.000126 0.000118 0.0000055 0.0000077 0.000060 0.000057 1993 5 10 49117 0.021214 0.165707 -0.2857344 0.0023806 0.000096 0.000297 0.000124 0.000115 0.0000054 0.0000076 0.000060 0.000056 1993 5 11 49118 0.019090 0.166086 -0.2881309 0.0023913 0.000105 0.000175 0.000122 0.000113 0.0000052 0.0000074 0.000059 0.000056 1993 5 12 49119 0.017651 0.166690 -0.2905200 0.0024161 0.000114 0.000052 0.000120 0.000110 0.0000051 0.0000072 0.000059 0.000055 1993 5 13 49120 0.016177 0.167119 -0.2929614 0.0024697 0.000205 0.000150 0.000117 0.000108 0.0000050 0.0000071 0.000058 0.000055 1993 5 14 49121 0.015484 0.167640 -0.2954544 0.0025167 0.000366 0.000280 0.000118 0.000108 0.0000050 0.0000072 0.000058 0.000055 1993 5 15 49122 0.013710 0.168136 -0.2979866 0.0025701 0.000402 0.000283 0.000121 0.000110 0.0000052 0.0000073 0.000059 0.000056 1993 5 16 49123 0.012568 0.169089 -0.3005837 0.0026199 0.000331 0.000207 0.000123 0.000112 0.0000053 0.0000075 0.000059 0.000057 1993 5 17 49124 0.010842 0.169981 -0.3032141 0.0025905 0.000261 0.000132 0.000126 0.000113 0.0000055 0.0000077 0.000059 0.000057 1993 5 18 49125 0.009822 0.170657 -0.3057534 0.0025186 0.000191 0.000056 0.000128 0.000114 0.0000056 0.0000079 0.000059 0.000058 1993 5 19 49126 0.008445 0.171603 -0.3082430 0.0024491 -0.000060 -0.000060 0.000129 0.000115 0.0000057 0.0000080 0.000059 0.000059 1993 5 20 49127 0.007335 0.172858 -0.3106477 0.0023367 -0.000035 -0.000143 0.000132 0.000116 0.0000058 0.0000082 0.000059 0.000059 1993 5 21 49128 0.005609 0.173615 -0.3129182 0.0022136 0.000095 -0.000211 0.000135 0.000117 0.0000059 0.0000084 0.000059 0.000060 1993 5 22 49129 0.004569 0.174812 -0.3150843 0.0021642 0.000224 -0.000280 0.000137 0.000118 0.0000061 0.0000086 0.000059 0.000061 1993 5 23 49130 0.002728 0.175201 -0.3172642 0.0021496 0.000169 -0.000204 0.000139 0.000120 0.0000062 0.0000088 0.000060 0.000062 1993 5 24 49131 0.000974 0.176184 -0.3194069 0.0021196 0.000077 -0.000099 0.000141 0.000122 0.0000063 0.0000089 0.000060 0.000063 1993 5 25 49132 -0.001511 0.176751 -0.3215270 0.0022195 -0.000015 0.000006 0.000143 0.000123 0.0000064 0.0000090 0.000061 0.000064 1993 5 26 49133 -0.005166 0.177601 -0.3238623 0.0024238 0.000086 -0.000078 0.000144 0.000125 0.0000065 0.0000091 0.000061 0.000064 1993 5 27 49134 -0.007067 0.177583 -0.3263781 0.0025964 0.000228 -0.000017 0.000145 0.000126 0.0000065 0.0000092 0.000061 0.000064 1993 5 28 49135 -0.009550 0.177894 -0.3290442 0.0027439 0.000274 -0.000006 0.000146 0.000127 0.0000066 0.0000093 0.000061 0.000064 1993 5 29 49136 -0.010853 0.178337 -0.3318430 0.0028605 0.000271 -0.000051 0.000146 0.000128 0.0000066 0.0000093 0.000061 0.000063 1993 5 30 49137 -0.011798 0.179298 -0.3347350 0.0028908 0.000268 -0.000096 0.000146 0.000129 0.0000066 0.0000093 0.000061 0.000063 1993 5 31 49138 -0.013369 0.180351 -0.3375935 0.0027722 0.000266 -0.000141 0.000146 0.000129 0.0000065 0.0000092 0.000060 0.000062 1993 6 1 49139 -0.014879 0.180168 -0.3402543 0.0025878 0.000263 -0.000186 0.000144 0.000128 0.0000065 0.0000091 0.000060 0.000062 1993 6 2 49140 -0.017469 0.180994 -0.3427566 0.0022759 0.000261 -0.000231 0.000142 0.000127 0.0000064 0.0000090 0.000060 0.000061 1993 6 3 49141 -0.019405 0.180682 -0.3448101 0.0020610 0.000069 -0.000423 0.000140 0.000126 0.0000063 0.0000089 0.000060 0.000061 1993 6 4 49142 -0.021055 0.181045 -0.3468974 0.0020612 0.000009 -0.000458 0.000139 0.000124 0.0000062 0.0000088 0.000060 0.000060 1993 6 5 49143 -0.023056 0.182027 -0.3489594 0.0019182 0.000051 -0.000386 0.000137 0.000123 0.0000061 0.0000087 0.000059 0.000060 1993 6 6 49144 -0.025010 0.183202 -0.3507592 0.0018350 0.000092 -0.000314 0.000134 0.000121 0.0000060 0.0000085 0.000059 0.000059 1993 6 7 49145 -0.026726 0.183854 -0.3526461 0.0019101 0.000134 -0.000242 0.000132 0.000118 0.0000059 0.0000083 0.000059 0.000058 1993 6 8 49146 -0.028376 0.184584 -0.3545855 0.0020167 0.000175 -0.000170 0.000129 0.000116 0.0000057 0.0000081 0.000058 0.000057 1993 6 9 49147 -0.030184 0.185912 -0.3566774 0.0021178 0.000401 -0.000155 0.000126 0.000113 0.0000056 0.0000080 0.000058 0.000056 1993 6 10 49148 -0.031825 0.186683 -0.3588143 0.0021830 0.000446 -0.000144 0.000125 0.000112 0.0000056 0.0000079 0.000057 0.000055 1993 6 11 49149 -0.033877 0.187483 -0.3610342 0.0022483 0.000411 -0.000131 0.000124 0.000111 0.0000056 0.0000079 0.000057 0.000054 1993 6 12 49150 -0.034759 0.188491 -0.3633000 0.0022726 0.000376 -0.000117 0.000122 0.000111 0.0000056 0.0000078 0.000057 0.000053 1993 6 13 49151 -0.035562 0.189705 -0.3655675 0.0022427 0.000341 -0.000104 0.000121 0.000109 0.0000055 0.0000078 0.000057 0.000053 1993 6 14 49152 -0.037033 0.191045 -0.3677742 0.0021327 0.000306 -0.000090 0.000119 0.000108 0.0000055 0.0000077 0.000056 0.000052 1993 6 15 49153 -0.037923 0.192629 -0.3698246 0.0020153 0.000271 -0.000077 0.000116 0.000106 0.0000054 0.0000077 0.000056 0.000052 1993 6 16 49154 -0.039247 0.194336 -0.3718009 0.0019282 0.000259 -0.000398 0.000116 0.000106 0.0000054 0.0000077 0.000056 0.000052 1993 6 17 49155 -0.041143 0.195710 -0.3736821 0.0018217 0.000214 -0.000426 0.000117 0.000107 0.0000054 0.0000077 0.000056 0.000052 1993 6 18 49156 -0.042668 0.196859 -0.3754518 0.0017287 0.000157 -0.000334 0.000119 0.000108 0.0000054 0.0000077 0.000057 0.000053 1993 6 19 49157 -0.045189 0.197530 -0.3771544 0.0016890 0.000100 -0.000241 0.000120 0.000108 0.0000054 0.0000076 0.000057 0.000053 1993 6 20 49158 -0.046782 0.198511 -0.3788517 0.0017022 0.000043 -0.000149 0.000120 0.000109 0.0000054 0.0000076 0.000057 0.000054 1993 6 21 49159 -0.049083 0.199374 -0.3805842 0.0017733 -0.000014 -0.000088 0.000120 0.000108 0.0000053 0.0000075 0.000057 0.000054 1993 6 22 49160 -0.051998 0.199957 -0.3824192 0.0019100 -0.000071 -0.000126 0.000119 0.000108 0.0000052 0.0000073 0.000057 0.000054 1993 6 23 49161 -0.053556 0.200787 -0.3844123 0.0020866 -0.000012 -0.000277 0.000118 0.000107 0.0000051 0.0000073 0.000057 0.000053 1993 6 24 49162 -0.054819 0.202046 -0.3865832 0.0022376 0.000200 -0.000108 0.000118 0.000107 0.0000051 0.0000073 0.000057 0.000053 1993 6 25 49163 -0.055756 0.203137 -0.3888628 0.0023121 0.000455 0.000163 0.000118 0.000107 0.0000052 0.0000073 0.000057 0.000054 1993 6 26 49164 -0.056385 0.204319 -0.3911750 0.0023607 0.000303 0.000061 0.000118 0.000107 0.0000052 0.0000075 0.000057 0.000054 1993 6 27 49165 -0.057611 0.205393 -0.3935529 0.0022988 0.000176 0.000004 0.000119 0.000108 0.0000054 0.0000076 0.000057 0.000055 1993 6 28 49166 -0.058865 0.206417 -0.3957496 0.0020468 0.000052 -0.000050 0.000121 0.000110 0.0000056 0.0000079 0.000058 0.000056 1993 6 29 49167 -0.059948 0.207745 -0.3976355 0.0018170 -0.000073 -0.000104 0.000122 0.000111 0.0000058 0.0000081 0.000058 0.000057 1993 6 30 49168 -0.061456 0.208413 -0.3993854 0.0016690 -0.000038 -0.000165 0.000122 0.000112 0.0000059 0.0000084 0.000058 0.000057 1993 7 1 49169 -0.062641 0.209884 0.5990128 0.0015402 0.000014 -0.000181 0.000123 0.000113 0.0000061 0.0000087 0.000058 0.000058 1993 7 2 49170 -0.063547 0.211079 0.5975117 0.0014728 0.000059 -0.000181 0.000124 0.000113 0.0000063 0.0000090 0.000058 0.000058 1993 7 3 49171 -0.065732 0.212322 0.5960419 0.0014112 0.000105 -0.000180 0.000124 0.000113 0.0000065 0.0000092 0.000058 0.000058 1993 7 4 49172 -0.066965 0.213284 0.5946682 0.0013607 0.000151 -0.000180 0.000125 0.000113 0.0000067 0.0000095 0.000058 0.000058 1993 7 5 49173 -0.066859 0.214728 0.5933086 0.0014447 0.000196 -0.000180 0.000124 0.000113 0.0000069 0.0000097 0.000058 0.000059 1993 7 6 49174 -0.067896 0.216259 0.5917771 0.0015271 0.000242 -0.000180 0.000124 0.000112 0.0000071 0.0000100 0.000059 0.000059 1993 7 7 49175 -0.068077 0.216910 0.5902605 0.0015850 0.000288 -0.000180 0.000123 0.000110 0.0000072 0.0000102 0.000059 0.000059 1993 7 8 49176 -0.068460 0.217253 0.5886177 0.0016164 0.000446 -0.000019 0.000122 0.000109 0.0000073 0.0000103 0.000059 0.000060 1993 7 9 49177 -0.068244 0.218037 0.5870399 0.0016454 0.000444 0.000071 0.000122 0.000109 0.0000074 0.0000105 0.000059 0.000060 1993 7 10 49178 -0.068509 0.219308 0.5853393 0.0016161 0.000386 0.000017 0.000121 0.000108 0.0000075 0.0000106 0.000059 0.000059 1993 7 11 49179 -0.068693 0.219970 0.5838194 0.0015244 0.000341 -0.000083 0.000120 0.000107 0.0000075 0.0000106 0.000058 0.000059 1993 7 12 49180 -0.068520 0.221441 0.5822998 0.0014812 0.000295 -0.000183 0.000119 0.000106 0.0000075 0.0000106 0.000058 0.000058 1993 7 13 49181 -0.068832 0.222905 0.5808621 0.0014202 0.000249 -0.000283 0.000117 0.000105 0.0000075 0.0000105 0.000058 0.000057 1993 7 14 49182 -0.069451 0.224084 0.5794590 0.0013676 0.000206 -0.000223 0.000115 0.000103 0.0000074 0.0000105 0.000057 0.000057 1993 7 15 49183 -0.070654 0.225710 0.5781207 0.0013107 0.000143 -0.000172 0.000115 0.000103 0.0000074 0.0000105 0.000058 0.000057 1993 7 16 49184 -0.071197 0.227097 0.5768251 0.0012751 0.000166 -0.000145 0.000114 0.000103 0.0000074 0.0000104 0.000058 0.000056 1993 7 17 49185 -0.072112 0.228623 0.5755514 0.0012648 0.000262 -0.000120 0.000114 0.000103 0.0000073 0.0000103 0.000058 0.000056 1993 7 18 49186 -0.072207 0.230335 0.5742711 0.0013168 0.000287 -0.000156 0.000113 0.000103 0.0000072 0.0000102 0.000058 0.000055 1993 7 19 49187 -0.072563 0.232339 0.5728933 0.0014638 0.000242 -0.000245 0.000114 0.000103 0.0000071 0.0000101 0.000058 0.000054 1993 7 20 49188 -0.072586 0.233633 0.5713279 0.0016724 0.000197 -0.000334 0.000114 0.000103 0.0000070 0.0000099 0.000057 0.000053 1993 7 21 49189 -0.073216 0.235850 0.5695500 0.0019175 0.000144 -0.000226 0.000114 0.000103 0.0000069 0.0000098 0.000057 0.000053 1993 7 22 49190 -0.074189 0.237402 0.5675144 0.0021514 0.000050 -0.000042 0.000114 0.000103 0.0000068 0.0000096 0.000058 0.000053 1993 7 23 49191 -0.074331 0.239159 0.5652829 0.0022775 0.000018 0.000016 0.000114 0.000103 0.0000067 0.0000094 0.000058 0.000053 1993 7 24 49192 -0.074870 0.241258 0.5629979 0.0022451 0.000024 0.000006 0.000114 0.000103 0.0000066 0.0000093 0.000057 0.000053 1993 7 25 49193 -0.075631 0.242402 0.5608218 0.0020908 0.000030 -0.000005 0.000113 0.000103 0.0000064 0.0000091 0.000057 0.000053 1993 7 26 49194 -0.076553 0.243795 0.5588296 0.0018964 0.000036 -0.000015 0.000112 0.000102 0.0000063 0.0000088 0.000057 0.000053 1993 7 27 49195 -0.078030 0.245202 0.5570265 0.0016534 0.000042 -0.000026 0.000111 0.000101 0.0000061 0.0000086 0.000057 0.000053 1993 7 28 49196 -0.079558 0.246888 0.5555088 0.0014639 0.000048 -0.000036 0.000109 0.000100 0.0000059 0.0000084 0.000057 0.000052 1993 7 29 49197 -0.080193 0.248820 0.5540782 0.0014261 0.000110 -0.000179 0.000108 0.000099 0.0000058 0.0000081 0.000057 0.000053 1993 7 30 49198 -0.081475 0.250678 0.5526338 0.0014719 0.000070 -0.000171 0.000107 0.000098 0.0000056 0.0000080 0.000058 0.000053 1993 7 31 49199 -0.082199 0.252214 0.5511135 0.0015259 0.000064 -0.000154 0.000107 0.000098 0.0000056 0.0000080 0.000058 0.000053 1993 8 1 49200 -0.083494 0.254346 0.5495668 0.0015526 0.000113 -0.000191 0.000109 0.000100 0.0000058 0.0000081 0.000058 0.000054 1993 8 2 49201 -0.084468 0.255653 0.5480014 0.0016514 0.000163 -0.000228 0.000110 0.000101 0.0000059 0.0000083 0.000059 0.000055 1993 8 3 49202 -0.085682 0.257311 0.5462661 0.0018041 0.000213 -0.000265 0.000111 0.000102 0.0000060 0.0000085 0.000059 0.000056 1993 8 4 49203 -0.086451 0.259644 0.5444021 0.0019116 0.000231 -0.000175 0.000111 0.000103 0.0000061 0.0000086 0.000060 0.000058 1993 8 5 49204 -0.087633 0.261535 0.5424555 0.0019987 0.000252 -0.000089 0.000113 0.000104 0.0000062 0.0000088 0.000060 0.000059 1993 8 6 49205 -0.089408 0.263562 0.5404183 0.0020423 0.000237 -0.000034 0.000114 0.000105 0.0000063 0.0000089 0.000061 0.000060 1993 8 7 49206 -0.090986 0.265547 0.5383834 0.0019823 0.000214 -0.000001 0.000115 0.000105 0.0000064 0.0000090 0.000061 0.000060 1993 8 8 49207 -0.092798 0.267452 0.5364640 0.0018538 0.000199 0.000026 0.000115 0.000106 0.0000064 0.0000091 0.000062 0.000061 1993 8 9 49208 -0.093862 0.269132 0.5346825 0.0017257 0.000185 0.000052 0.000116 0.000106 0.0000065 0.0000091 0.000062 0.000061 1993 8 10 49209 -0.094902 0.271406 0.5330140 0.0016286 0.000170 0.000079 0.000116 0.000106 0.0000065 0.0000091 0.000063 0.000061 1993 8 11 49210 -0.094992 0.273933 0.5314206 0.0015112 0.000037 -0.000081 0.000116 0.000105 0.0000065 0.0000091 0.000063 0.000062 1993 8 12 49211 -0.095967 0.275845 0.5299809 0.0014127 0.000049 -0.000025 0.000116 0.000105 0.0000064 0.0000090 0.000063 0.000062 1993 8 13 49212 -0.096131 0.278102 0.5285786 0.0014485 0.000077 0.000003 0.000116 0.000105 0.0000063 0.0000089 0.000063 0.000061 1993 8 14 49213 -0.097140 0.280220 0.5270621 0.0015803 0.000087 -0.000024 0.000116 0.000105 0.0000062 0.0000088 0.000063 0.000060 1993 8 15 49214 -0.097374 0.282899 0.5253938 0.0017356 0.000097 -0.000051 0.000116 0.000105 0.0000061 0.0000086 0.000063 0.000060 1993 8 16 49215 -0.098408 0.284552 0.5235702 0.0019309 0.000106 -0.000078 0.000116 0.000104 0.0000060 0.0000085 0.000063 0.000059 1993 8 17 49216 -0.099345 0.286662 0.5215234 0.0021710 0.000116 -0.000105 0.000115 0.000103 0.0000059 0.0000083 0.000062 0.000059 1993 8 18 49217 -0.099933 0.288120 0.5192392 0.0023279 -0.000077 -0.000475 0.000114 0.000102 0.0000057 0.0000081 0.000063 0.000058 1993 8 19 49218 -0.100694 0.289872 0.5168987 0.0024964 -0.000149 -0.000657 0.000114 0.000102 0.0000056 0.0000079 0.000063 0.000058 1993 8 20 49219 -0.101173 0.291055 0.5142890 0.0026377 -0.000177 -0.000506 0.000113 0.000101 0.0000055 0.0000078 0.000063 0.000056 1993 8 21 49220 -0.102176 0.292841 0.5116629 0.0025210 -0.000138 -0.000319 0.000114 0.000101 0.0000055 0.0000078 0.000063 0.000056 1993 8 22 49221 -0.102280 0.294345 0.5092709 0.0023017 -0.000049 -0.000194 0.000116 0.000104 0.0000056 0.0000080 0.000063 0.000057 1993 8 23 49222 -0.102006 0.296387 0.5070627 0.0020814 0.000040 -0.000068 0.000119 0.000105 0.0000058 0.0000082 0.000064 0.000058 1993 8 24 49223 -0.101976 0.298507 0.5050940 0.0018612 0.000129 0.000057 0.000120 0.000107 0.0000059 0.0000084 0.000064 0.000059 1993 8 25 49224 -0.101712 0.299948 0.5033177 0.0017003 0.000091 -0.000267 0.000122 0.000108 0.0000061 0.0000086 0.000064 0.000060 1993 8 26 49225 -0.101603 0.302392 0.5016701 0.0016095 0.000304 -0.000599 0.000123 0.000110 0.0000062 0.0000088 0.000065 0.000060 1993 8 27 49226 -0.101262 0.304787 0.5000788 0.0015885 0.000372 -0.000661 0.000125 0.000111 0.0000063 0.0000089 0.000065 0.000060 1993 8 28 49227 -0.100491 0.307399 0.4984782 0.0016258 0.000322 -0.000602 0.000126 0.000113 0.0000064 0.0000091 0.000065 0.000060 1993 8 29 49228 -0.100576 0.309149 0.4968182 0.0017060 0.000272 -0.000544 0.000126 0.000114 0.0000065 0.0000092 0.000065 0.000060 1993 8 30 49229 -0.100882 0.311523 0.4950640 0.0018129 0.000221 -0.000486 0.000127 0.000114 0.0000066 0.0000094 0.000064 0.000060 1993 8 31 49230 -0.099690 0.314013 0.4931974 0.0019275 0.000171 -0.000427 0.000126 0.000114 0.0000067 0.0000096 0.000064 0.000060 1993 9 1 49231 -0.099832 0.315863 0.4912197 0.0020305 0.000257 -0.000303 0.000127 0.000115 0.0000069 0.0000098 0.000065 0.000061 1993 9 2 49232 -0.100032 0.317459 0.4891498 0.0021187 0.000146 -0.000092 0.000128 0.000116 0.0000070 0.0000100 0.000065 0.000062 1993 9 3 49233 -0.099563 0.319417 0.4869958 0.0021468 0.000230 0.000072 0.000130 0.000118 0.0000072 0.0000101 0.000065 0.000062 1993 9 4 49234 -0.099330 0.321163 0.4848676 0.0020667 0.000301 0.000096 0.000131 0.000119 0.0000073 0.0000102 0.000065 0.000063 1993 9 5 49235 -0.099758 0.323130 0.4828705 0.0019460 0.000265 0.000046 0.000133 0.000120 0.0000073 0.0000103 0.000065 0.000063 1993 9 6 49236 -0.100179 0.325109 0.4809792 0.0018484 0.000229 -0.000004 0.000134 0.000121 0.0000073 0.0000104 0.000065 0.000063 1993 9 7 49237 -0.100778 0.326912 0.4791714 0.0017964 0.000192 -0.000054 0.000134 0.000121 0.0000073 0.0000104 0.000065 0.000063 1993 9 8 49238 -0.101243 0.328050 0.4773777 0.0017586 0.000153 -0.000196 0.000134 0.000121 0.0000073 0.0000103 0.000065 0.000063 1993 9 9 49239 -0.101435 0.329683 0.4756395 0.0017176 0.000149 -0.000214 0.000135 0.000121 0.0000073 0.0000102 0.000064 0.000064 1993 9 10 49240 -0.102226 0.331386 0.4739229 0.0017460 0.000157 -0.000187 0.000135 0.000122 0.0000072 0.0000101 0.000064 0.000064 1993 9 11 49241 -0.101791 0.332844 0.4721249 0.0018786 0.000166 -0.000160 0.000135 0.000122 0.0000071 0.0000100 0.000064 0.000064 1993 9 12 49242 -0.101612 0.334555 0.4701439 0.0020793 0.000174 -0.000133 0.000134 0.000121 0.0000070 0.0000099 0.000063 0.000064 1993 9 13 49243 -0.100779 0.336819 0.4679512 0.0023145 0.000182 -0.000106 0.000133 0.000120 0.0000069 0.0000097 0.000063 0.000065 1993 9 14 49244 -0.099607 0.339311 0.4655142 0.0025724 0.000190 -0.000079 0.000132 0.000119 0.0000067 0.0000095 0.000063 0.000065 1993 9 15 49245 -0.098242 0.341549 0.4628254 0.0027385 0.000198 -0.000053 0.000130 0.000118 0.0000066 0.0000093 0.000063 0.000065 1993 9 16 49246 -0.097684 0.344043 0.4600741 0.0028315 0.000042 -0.000143 0.000129 0.000116 0.0000065 0.0000091 0.000063 0.000065 1993 9 17 49247 -0.097478 0.346352 0.4572066 0.0028177 -0.000104 -0.000185 0.000128 0.000115 0.0000063 0.0000090 0.000062 0.000066 1993 9 18 49248 -0.097149 0.348338 0.4544751 0.0026310 -0.000130 -0.000180 0.000126 0.000114 0.0000062 0.0000087 0.000062 0.000065 1993 9 19 49249 -0.097470 0.350022 0.4519614 0.0024161 -0.000092 -0.000169 0.000125 0.000113 0.0000060 0.0000085 0.000061 0.000065 1993 9 20 49250 -0.096849 0.351512 0.4496369 0.0021894 -0.000055 -0.000159 0.000123 0.000111 0.0000059 0.0000083 0.000061 0.000064 1993 9 21 49251 -0.097686 0.352581 0.4475604 0.0020353 -0.000018 -0.000149 0.000120 0.000109 0.0000057 0.0000080 0.000060 0.000064 1993 9 22 49252 -0.097702 0.353528 0.4455395 0.0020071 0.000019 -0.000139 0.000118 0.000107 0.0000055 0.0000078 0.000060 0.000063 1993 9 23 49253 -0.097604 0.355067 0.4435234 0.0020353 0.000206 -0.000111 0.000116 0.000105 0.0000053 0.0000075 0.000059 0.000064 1993 9 24 49254 -0.097866 0.357001 0.4414538 0.0021126 0.000444 -0.000077 0.000114 0.000104 0.0000052 0.0000073 0.000059 0.000064 1993 9 25 49255 -0.097071 0.359355 0.4392901 0.0021980 0.000342 -0.000079 0.000112 0.000102 0.0000050 0.0000071 0.000059 0.000064 1993 9 26 49256 -0.097200 0.361305 0.4370549 0.0022723 0.000238 -0.000081 0.000110 0.000100 0.0000048 0.0000069 0.000059 0.000064 1993 9 27 49257 -0.096464 0.362261 0.4347474 0.0023517 0.000133 -0.000083 0.000108 0.000097 0.0000047 0.0000066 0.000058 0.000064 1993 9 28 49258 -0.095917 0.364690 0.4323585 0.0024109 0.000029 -0.000085 0.000106 0.000095 0.0000045 0.0000064 0.000058 0.000064 1993 9 29 49259 -0.095750 0.366552 0.4299368 0.0024207 0.000057 -0.000238 0.000103 0.000092 0.0000044 0.0000062 0.000057 0.000063 1993 9 30 49260 -0.095586 0.368595 0.4275304 0.0023841 0.000055 -0.000331 0.000100 0.000090 0.0000042 0.0000059 0.000057 0.000062 1993 10 1 49261 -0.096520 0.370063 0.4251811 0.0023341 0.000034 -0.000267 0.000098 0.000087 0.0000040 0.0000058 0.000056 0.000061 1993 10 2 49262 -0.095499 0.372116 0.4228719 0.0022692 0.000032 -0.000179 0.000098 0.000087 0.0000040 0.0000058 0.000056 0.000060 1993 10 3 49263 -0.095006 0.373761 0.4206483 0.0021626 0.000046 -0.000222 0.000101 0.000090 0.0000042 0.0000059 0.000056 0.000062 1993 10 4 49264 -0.094693 0.375468 0.4185472 0.0021018 0.000060 -0.000264 0.000103 0.000092 0.0000043 0.0000061 0.000057 0.000063 1993 10 5 49265 -0.094392 0.377647 0.4164389 0.0020952 0.000075 -0.000306 0.000105 0.000094 0.0000044 0.0000063 0.000058 0.000064 1993 10 6 49266 -0.093147 0.379785 0.4143443 0.0021177 0.000089 -0.000348 0.000107 0.000096 0.0000046 0.0000064 0.000058 0.000065 1993 10 7 49267 -0.092842 0.381876 0.4121853 0.0022048 0.000001 -0.000299 0.000109 0.000097 0.0000047 0.0000066 0.000059 0.000066 1993 10 8 49268 -0.092780 0.383257 0.4099134 0.0022913 0.000054 -0.000184 0.000110 0.000099 0.0000048 0.0000067 0.000060 0.000067 1993 10 9 49269 -0.091796 0.384925 0.4075816 0.0024076 0.000097 -0.000130 0.000112 0.000100 0.0000048 0.0000068 0.000060 0.000067 1993 10 10 49270 -0.090656 0.386788 0.4050815 0.0025641 0.000072 -0.000131 0.000113 0.000101 0.0000049 0.0000069 0.000060 0.000067 1993 10 11 49271 -0.088630 0.388773 0.4024462 0.0027936 0.000046 -0.000131 0.000114 0.000102 0.0000049 0.0000070 0.000060 0.000066 1993 10 12 49272 -0.087343 0.390589 0.3995019 0.0030564 0.000021 -0.000132 0.000114 0.000102 0.0000050 0.0000070 0.000060 0.000066 1993 10 13 49273 -0.085963 0.392966 0.3963581 0.0032278 -0.000007 0.000046 0.000115 0.000102 0.0000050 0.0000070 0.000060 0.000066 1993 10 14 49274 -0.084808 0.395438 0.3930842 0.0033068 -0.000045 -0.000057 0.000115 0.000103 0.0000050 0.0000070 0.000060 0.000066 1993 10 15 49275 -0.083441 0.397520 0.3897850 0.0032357 0.000051 -0.000314 0.000116 0.000103 0.0000050 0.0000070 0.000060 0.000066 1993 10 16 49276 -0.082578 0.399996 0.3866421 0.0030353 0.000109 -0.000394 0.000116 0.000103 0.0000049 0.0000070 0.000060 0.000065 1993 10 17 49277 -0.082265 0.401338 0.3837225 0.0027474 0.000089 -0.000328 0.000115 0.000103 0.0000049 0.0000069 0.000060 0.000064 1993 10 18 49278 -0.081697 0.401539 0.3811336 0.0024980 0.000070 -0.000262 0.000115 0.000102 0.0000048 0.0000068 0.000059 0.000063 1993 10 19 49279 -0.081912 0.403245 0.3786997 0.0023792 0.000050 -0.000197 0.000114 0.000101 0.0000048 0.0000069 0.000059 0.000063 1993 10 20 49280 -0.080623 0.404238 0.3763478 0.0023480 -0.000097 -0.000349 0.000115 0.000102 0.0000049 0.0000069 0.000059 0.000063 1993 10 21 49281 -0.080075 0.405553 0.3739843 0.0023902 -0.000037 -0.000237 0.000117 0.000104 0.0000050 0.0000070 0.000059 0.000064 1993 10 22 49282 -0.079265 0.407287 0.3715581 0.0024719 -0.000009 -0.000175 0.000120 0.000106 0.0000051 0.0000072 0.000060 0.000065 1993 10 23 49283 -0.078930 0.409073 0.3690386 0.0025753 -0.000036 -0.000191 0.000123 0.000108 0.0000052 0.0000074 0.000060 0.000065 1993 10 24 49284 -0.078676 0.410796 0.3664099 0.0026629 -0.000064 -0.000207 0.000125 0.000110 0.0000053 0.0000075 0.000060 0.000066 1993 10 25 49285 -0.078394 0.412260 0.3637182 0.0027042 -0.000091 -0.000223 0.000127 0.000111 0.0000054 0.0000077 0.000061 0.000067 1993 10 26 49286 -0.077282 0.413508 0.3610101 0.0027448 -0.000119 -0.000239 0.000128 0.000111 0.0000056 0.0000079 0.000061 0.000068 1993 10 27 49287 -0.076258 0.415657 0.3582400 0.0027625 0.000084 -0.000243 0.000129 0.000112 0.0000057 0.0000080 0.000061 0.000069 1993 10 28 49288 -0.075592 0.417462 0.3554974 0.0027296 0.000233 0.000269 0.000130 0.000112 0.0000058 0.0000081 0.000062 0.000070 1993 10 29 49289 -0.075566 0.419098 0.3527914 0.0026524 0.000215 0.000382 0.000130 0.000113 0.0000058 0.0000082 0.000062 0.000070 1993 10 30 49290 -0.075339 0.419882 0.3501995 0.0025718 0.000127 0.000209 0.000131 0.000113 0.0000059 0.0000083 0.000061 0.000071 1993 10 31 49291 -0.074864 0.421250 0.3476502 0.0024627 0.000039 0.000036 0.000132 0.000113 0.0000060 0.0000084 0.000061 0.000071 1993 11 1 49292 -0.073611 0.422867 0.3452711 0.0022848 -0.000049 -0.000138 0.000132 0.000112 0.0000060 0.0000085 0.000061 0.000071 1993 11 2 49293 -0.072813 0.422708 0.3430711 0.0021956 -0.000138 -0.000311 0.000132 0.000112 0.0000061 0.0000086 0.000061 0.000071 1993 11 3 49294 -0.071276 0.423355 0.3408641 0.0021716 -0.000081 -0.000274 0.000133 0.000112 0.0000062 0.0000087 0.000061 0.000071 1993 11 4 49295 -0.068499 0.424551 0.3387075 0.0022129 -0.000165 -0.000173 0.000134 0.000112 0.0000062 0.0000088 0.000061 0.000071 1993 11 5 49296 -0.066496 0.425780 0.3364171 0.0022755 -0.000361 -0.000137 0.000136 0.000114 0.0000063 0.0000089 0.000060 0.000071 1993 11 6 49297 -0.063978 0.427133 0.3341395 0.0023706 -0.000379 -0.000102 0.000138 0.000116 0.0000063 0.0000089 0.000060 0.000071 1993 11 7 49298 -0.062549 0.428803 0.3316671 0.0025690 -0.000249 -0.000041 0.000140 0.000119 0.0000063 0.0000089 0.000059 0.000070 1993 11 8 49299 -0.060290 0.430405 0.3290043 0.0028003 -0.000119 0.000020 0.000143 0.000121 0.0000063 0.0000090 0.000058 0.000069 1993 11 9 49300 -0.058541 0.432529 0.3260826 0.0030046 0.000010 0.000081 0.000144 0.000123 0.0000063 0.0000089 0.000058 0.000068 1993 11 10 49301 -0.056723 0.433681 0.3230231 0.0031049 -0.000197 -0.000057 0.000145 0.000125 0.0000063 0.0000089 0.000057 0.000066 1993 11 11 49302 -0.054485 0.434785 0.3199072 0.0030941 -0.000225 -0.000089 0.000147 0.000127 0.0000062 0.0000088 0.000056 0.000064 1993 11 12 49303 -0.054010 0.436219 0.3168665 0.0029637 -0.000193 -0.000084 0.000148 0.000129 0.0000062 0.0000088 0.000055 0.000063 1993 11 13 49304 -0.052143 0.436984 0.3139982 0.0027772 -0.000160 -0.000080 0.000150 0.000131 0.0000062 0.0000087 0.000054 0.000062 1993 11 14 49305 -0.051294 0.437117 0.3113109 0.0025526 -0.000127 -0.000075 0.000150 0.000132 0.0000061 0.0000086 0.000054 0.000061 1993 11 15 49306 -0.050177 0.438760 0.3088736 0.0023347 -0.000095 -0.000070 0.000149 0.000132 0.0000060 0.0000085 0.000053 0.000060 1993 11 16 49307 -0.049576 0.439864 0.3066133 0.0022194 -0.000062 -0.000066 0.000147 0.000131 0.0000060 0.0000084 0.000052 0.000059 1993 11 17 49308 -0.047714 0.439952 0.3044095 0.0022187 -0.000030 -0.000061 0.000145 0.000130 0.0000059 0.0000084 0.000052 0.000058 1993 11 18 49309 -0.046764 0.441538 0.3021611 0.0022733 0.000127 -0.000143 0.000144 0.000129 0.0000058 0.0000083 0.000051 0.000057 1993 11 19 49310 -0.046365 0.442521 0.2998596 0.0023360 0.000166 -0.000186 0.000142 0.000129 0.0000058 0.0000082 0.000051 0.000057 1993 11 20 49311 -0.046014 0.444015 0.2974932 0.0024009 0.000125 -0.000193 0.000140 0.000128 0.0000057 0.0000081 0.000051 0.000056 1993 11 21 49312 -0.046813 0.444673 0.2950651 0.0024365 0.000084 -0.000201 0.000139 0.000128 0.0000057 0.0000080 0.000051 0.000055 1993 11 22 49313 -0.045424 0.445101 0.2926289 0.0024577 0.000043 -0.000209 0.000137 0.000126 0.0000056 0.0000080 0.000050 0.000054 1993 11 23 49314 -0.044146 0.446137 0.2901596 0.0024824 0.000003 -0.000217 0.000134 0.000124 0.0000055 0.0000079 0.000050 0.000054 1993 11 24 49315 -0.042281 0.447266 0.2876753 0.0024564 -0.000038 -0.000225 0.000130 0.000122 0.0000055 0.0000077 0.000050 0.000053 1993 11 25 49316 -0.041762 0.448386 0.2852575 0.0023667 -0.000040 -0.000219 0.000127 0.000119 0.0000054 0.0000077 0.000050 0.000053 1993 11 26 49317 -0.040634 0.449278 0.2829497 0.0022574 -0.000028 -0.000209 0.000124 0.000117 0.0000053 0.0000075 0.000050 0.000052 1993 11 27 49318 -0.040646 0.449339 0.2807461 0.0021708 -0.000017 -0.000199 0.000120 0.000114 0.0000053 0.0000074 0.000050 0.000052 1993 11 28 49319 -0.039203 0.450999 0.2786062 0.0020839 -0.000005 -0.000189 0.000116 0.000111 0.0000052 0.0000073 0.000050 0.000052 1993 11 29 49320 -0.038399 0.452319 0.2765708 0.0019329 0.000006 -0.000178 0.000112 0.000107 0.0000051 0.0000072 0.000050 0.000051 1993 11 30 49321 -0.039175 0.451458 0.2747270 0.0018055 0.000017 -0.000168 0.000108 0.000104 0.0000050 0.0000072 0.000050 0.000051 1993 12 1 49322 -0.036321 0.452805 0.2729409 0.0017926 0.000089 -0.000106 0.000106 0.000101 0.0000051 0.0000072 0.000050 0.000052 1993 12 2 49323 -0.035544 0.453113 0.2711204 0.0018514 -0.000006 -0.000361 0.000104 0.000099 0.0000051 0.0000072 0.000051 0.000053 1993 12 3 49324 -0.034036 0.454036 0.2692196 0.0019547 -0.000061 -0.000438 0.000102 0.000097 0.0000052 0.0000073 0.000051 0.000053 1993 12 4 49325 -0.032272 0.454746 0.2672009 0.0021064 -0.000067 -0.000370 0.000100 0.000095 0.0000052 0.0000074 0.000051 0.000054 1993 12 5 49326 -0.030297 0.456270 0.2650090 0.0023024 -0.000073 -0.000301 0.000097 0.000093 0.0000053 0.0000075 0.000052 0.000055 1993 12 6 49327 -0.029503 0.457362 0.2626107 0.0024868 -0.000078 -0.000233 0.000095 0.000091 0.0000053 0.0000075 0.000052 0.000055 1993 12 7 49328 -0.027843 0.458011 0.2600595 0.0026388 -0.000084 -0.000165 0.000092 0.000088 0.0000053 0.0000076 0.000053 0.000056 1993 12 8 49329 -0.026572 0.459253 0.2573617 0.0027477 -0.000187 -0.000092 0.000089 0.000085 0.0000054 0.0000076 0.000053 0.000056 1993 12 9 49330 -0.025072 0.460448 0.2545914 0.0027015 -0.000187 -0.000181 0.000087 0.000083 0.0000054 0.0000076 0.000053 0.000057 1993 12 10 49331 -0.024820 0.461360 0.2519781 0.0025572 -0.000148 -0.000324 0.000084 0.000081 0.0000054 0.0000076 0.000054 0.000058 1993 12 11 49332 -0.021916 0.462511 0.2494825 0.0024748 -0.000085 -0.000202 0.000082 0.000078 0.0000054 0.0000076 0.000054 0.000059 1993 12 12 49333 -0.020858 0.462809 0.2470178 0.0023343 -0.000005 0.000112 0.000080 0.000076 0.0000054 0.0000076 0.000055 0.000059 1993 12 13 49334 -0.020539 0.463931 0.2447906 0.0021578 0.000013 0.000055 0.000077 0.000074 0.0000053 0.0000075 0.000055 0.000059 1993 12 14 49335 -0.019035 0.465651 0.2426749 0.0021574 0.000010 -0.000123 0.000075 0.000071 0.0000053 0.0000074 0.000055 0.000059 1993 12 15 49336 -0.018307 0.467094 0.2404544 0.0022756 0.000045 -0.000320 0.000072 0.000069 0.0000052 0.0000073 0.000055 0.000059 1993 12 16 49337 -0.017224 0.468446 0.2381140 0.0024211 -0.000008 -0.000259 0.000070 0.000066 0.0000051 0.0000072 0.000055 0.000059 1993 12 17 49338 -0.015708 0.469719 0.2356142 0.0025597 -0.000090 -0.000111 0.000067 0.000064 0.0000050 0.0000071 0.000055 0.000059 1993 12 18 49339 -0.014750 0.470292 0.2330038 0.0026161 -0.000106 0.000009 0.000065 0.000062 0.0000050 0.0000070 0.000054 0.000059 1993 12 19 49340 -0.013627 0.471015 0.2303937 0.0026197 -0.000074 0.000109 0.000062 0.000060 0.0000049 0.0000069 0.000054 0.000058 1993 12 20 49341 -0.011664 0.471396 0.2277761 0.0026075 -0.000039 0.000133 0.000060 0.000058 0.0000048 0.0000067 0.000054 0.000058 1993 12 21 49342 -0.010767 0.471756 0.2251900 0.0026107 0.000007 -0.000072 0.000058 0.000055 0.0000047 0.0000066 0.000054 0.000057 1993 12 22 49343 -0.007474 0.473046 0.2225652 0.0025896 -0.000052 -0.000113 0.000055 0.000053 0.0000046 0.0000064 0.000053 0.000057 1993 12 23 49344 -0.005034 0.474249 0.2200191 0.0024892 -0.000056 -0.000123 0.000053 0.000051 0.0000044 0.0000063 0.000053 0.000056 1993 12 24 49345 -0.002019 0.474648 0.2175907 0.0023835 -0.000035 -0.000131 0.000051 0.000049 0.0000043 0.0000061 0.000052 0.000055 1993 12 25 49346 -0.000853 0.476575 0.2152506 0.0022888 -0.000015 -0.000140 0.000049 0.000047 0.0000042 0.0000060 0.000052 0.000054 1993 12 26 49347 0.001051 0.478426 0.2130061 0.0021928 0.000006 -0.000149 0.000047 0.000045 0.0000041 0.0000058 0.000051 0.000053 1993 12 27 49348 0.002546 0.477040 0.2108527 0.0021164 0.000026 -0.000158 0.000044 0.000043 0.0000040 0.0000057 0.000051 0.000052 1993 12 28 49349 0.003403 0.477233 0.2087559 0.0020930 0.000047 -0.000167 0.000042 0.000041 0.0000039 0.0000055 0.000050 0.000052 1993 12 29 49350 0.005325 0.476206 0.2066455 0.0021481 0.000068 -0.000176 0.000040 0.000039 0.0000038 0.0000054 0.000050 0.000051 1993 12 30 49351 0.006533 0.475899 0.2044389 0.0022806 0.000042 -0.000159 0.000039 0.000038 0.0000037 0.0000053 0.000049 0.000050 1993 12 31 49352 0.008025 0.475793 0.2020702 0.0024612 0.000029 -0.000153 0.000037 0.000036 0.0000036 0.0000052 0.000049 0.000050 1994 1 1 49353 0.009717 0.476323 0.1995166 0.0026396 0.000031 -0.000157 0.000101 0.000087 0.0000033 0.0000046 0.000048 0.000043 1994 1 2 49354 0.012600 0.476666 0.1968054 0.0027682 0.000033 -0.000160 0.000099 0.000085 0.0000033 0.0000046 0.000048 0.000044 1994 1 3 49355 0.015113 0.477029 0.1940062 0.0028125 0.000035 -0.000164 0.000096 0.000083 0.0000032 0.0000046 0.000048 0.000044 1994 1 4 49356 0.017914 0.477717 0.1912107 0.0027630 0.000037 -0.000167 0.000094 0.000081 0.0000032 0.0000046 0.000048 0.000044 1994 1 5 49357 0.020841 0.478424 0.1885068 0.0026365 0.000039 -0.000170 0.000091 0.000079 0.0000032 0.0000045 0.000048 0.000044 1994 1 6 49358 0.023513 0.479198 0.1859552 0.0024752 0.000000 -0.000086 0.000089 0.000077 0.0000032 0.0000045 0.000048 0.000045 1994 1 7 49359 0.026357 0.479572 0.1835617 0.0023085 -0.000173 -0.000066 0.000086 0.000076 0.0000031 0.0000044 0.000048 0.000045 1994 1 8 49360 0.029317 0.480070 0.1813307 0.0021495 -0.000271 -0.000082 0.000084 0.000074 0.0000031 0.0000044 0.000048 0.000044 1994 1 9 49361 0.031865 0.480199 0.1792442 0.0020296 -0.000270 -0.000089 0.000081 0.000072 0.0000030 0.0000043 0.000048 0.000044 1994 1 10 49362 0.034016 0.480045 0.1772465 0.0019726 -0.000269 -0.000097 0.000079 0.000070 0.0000030 0.0000042 0.000047 0.000043 1994 1 11 49363 0.035964 0.479708 0.1752747 0.0019950 -0.000268 -0.000104 0.000077 0.000068 0.0000029 0.0000041 0.000047 0.000043 1994 1 12 49364 0.038050 0.479561 0.1732400 0.0021061 -0.000238 -0.000080 0.000075 0.000066 0.0000028 0.0000040 0.000046 0.000042 1994 1 13 49365 0.040610 0.479566 0.1710578 0.0022524 -0.000212 -0.000095 0.000072 0.000065 0.0000027 0.0000039 0.000046 0.000042 1994 1 14 49366 0.043359 0.478957 0.1687415 0.0023523 -0.000162 -0.000055 0.000070 0.000063 0.0000027 0.0000038 0.000045 0.000041 1994 1 15 49367 0.046284 0.478657 0.1663660 0.0023683 -0.000099 -0.000047 0.000069 0.000061 0.0000026 0.0000037 0.000045 0.000040 1994 1 16 49368 0.048489 0.478873 0.1640196 0.0023243 -0.000061 -0.000058 0.000067 0.000060 0.0000026 0.0000036 0.000044 0.000039 1994 1 17 49369 0.050484 0.479136 0.1617309 0.0022765 -0.000086 -0.000057 0.000066 0.000059 0.0000025 0.0000036 0.000044 0.000039 1994 1 18 49370 0.052529 0.479037 0.1594783 0.0022253 -0.000115 -0.000032 0.000066 0.000059 0.0000025 0.0000036 0.000043 0.000039 1994 1 19 49371 0.054144 0.478583 0.1572894 0.0021304 -0.000157 0.000036 0.000066 0.000059 0.0000025 0.0000036 0.000043 0.000038 1994 1 20 49372 0.055628 0.478013 0.1552226 0.0020266 -0.000160 0.000003 0.000066 0.000059 0.0000025 0.0000036 0.000043 0.000038 1994 1 21 49373 0.057572 0.477587 0.1532358 0.0019675 -0.000159 -0.000086 0.000066 0.000059 0.0000026 0.0000036 0.000043 0.000038 1994 1 22 49374 0.059515 0.476675 0.1512812 0.0019335 -0.000156 -0.000199 0.000066 0.000059 0.0000026 0.0000037 0.000043 0.000038 1994 1 23 49375 0.062047 0.475910 0.1493568 0.0019204 -0.000097 -0.000108 0.000067 0.000059 0.0000026 0.0000037 0.000043 0.000038 1994 1 24 49376 0.064886 0.475755 0.1474236 0.0019428 -0.000058 -0.000129 0.000068 0.000060 0.0000026 0.0000038 0.000044 0.000039 1994 1 25 49377 0.067711 0.476289 0.1454506 0.0020157 -0.000052 -0.000154 0.000069 0.000061 0.0000027 0.0000039 0.000044 0.000039 1994 1 26 49378 0.070463 0.476137 0.1433703 0.0021658 -0.000083 -0.000136 0.000072 0.000063 0.0000028 0.0000040 0.000045 0.000040 1994 1 27 49379 0.073252 0.475421 0.1411005 0.0023849 -0.000086 -0.000138 0.000074 0.000065 0.0000029 0.0000042 0.000046 0.000041 1994 1 28 49380 0.076190 0.474415 0.1385927 0.0026151 -0.000096 -0.000132 0.000077 0.000068 0.0000030 0.0000043 0.000047 0.000042 1994 1 29 49381 0.078753 0.473776 0.1358790 0.0027632 -0.000131 -0.000110 0.000079 0.000070 0.0000032 0.0000045 0.000047 0.000043 1994 1 30 49382 0.081085 0.472738 0.1330915 0.0027935 -0.000167 -0.000088 0.000082 0.000073 0.0000033 0.0000047 0.000048 0.000044 1994 1 31 49383 0.083745 0.471613 0.1303269 0.0027657 -0.000202 -0.000066 0.000085 0.000075 0.0000034 0.0000049 0.000049 0.000045 1994 2 1 49384 0.086456 0.470911 0.1275935 0.0026884 -0.000237 -0.000044 0.000089 0.000078 0.0000036 0.0000051 0.000050 0.000047 1994 2 2 49385 0.089355 0.470033 0.1249722 0.0025315 -0.000273 -0.000022 0.000092 0.000081 0.0000037 0.0000053 0.000051 0.000048 1994 2 3 49386 0.092533 0.469124 0.1225370 0.0023238 -0.000302 -0.000023 0.000095 0.000084 0.0000039 0.0000055 0.000052 0.000050 1994 2 4 49387 0.094999 0.468946 0.1203166 0.0021254 -0.000360 -0.000135 0.000099 0.000086 0.0000040 0.0000057 0.000053 0.000051 1994 2 5 49388 0.097487 0.468127 0.1182683 0.0019806 -0.000434 -0.000297 0.000102 0.000089 0.0000042 0.0000060 0.000054 0.000053 1994 2 6 49389 0.099373 0.467067 0.1163326 0.0018961 -0.000508 -0.000460 0.000105 0.000092 0.0000044 0.0000062 0.000056 0.000054 1994 2 7 49390 0.101401 0.466135 0.1144532 0.0019052 -0.000443 -0.000369 0.000109 0.000095 0.0000046 0.0000065 0.000057 0.000055 1994 2 8 49391 0.103277 0.465362 0.1125034 0.0020075 -0.000264 -0.000068 0.000112 0.000098 0.0000047 0.0000067 0.000058 0.000057 1994 2 9 49392 0.105504 0.464593 0.1104275 0.0021707 -0.000111 -0.000099 0.000116 0.000101 0.0000049 0.0000070 0.000059 0.000058 1994 2 10 49393 0.107568 0.463456 0.1081618 0.0022643 0.000026 0.000015 0.000119 0.000104 0.0000051 0.0000072 0.000061 0.000060 1994 2 11 49394 0.109847 0.462178 0.1059078 0.0022925 0.000165 -0.000081 0.000123 0.000107 0.0000053 0.0000075 0.000062 0.000062 1994 2 12 49395 0.111225 0.461066 0.1035910 0.0023348 0.000203 -0.000146 0.000127 0.000110 0.0000055 0.0000078 0.000063 0.000063 1994 2 13 49396 0.112801 0.459952 0.1012536 0.0023085 0.000165 -0.000090 0.000130 0.000113 0.0000057 0.0000080 0.000064 0.000064 1994 2 14 49397 0.114481 0.459036 0.0989876 0.0023273 0.000127 -0.000033 0.000134 0.000117 0.0000058 0.0000083 0.000065 0.000066 1994 2 15 49398 0.116594 0.458024 0.0966095 0.0023096 0.000089 0.000024 0.000138 0.000120 0.0000060 0.0000085 0.000066 0.000067 1994 2 16 49399 0.118525 0.456689 0.0943751 0.0021816 -0.000136 -0.000162 0.000141 0.000123 0.0000061 0.0000087 0.000067 0.000068 1994 2 17 49400 0.120909 0.455478 0.0922481 0.0021237 -0.000329 -0.000219 0.000145 0.000126 0.0000063 0.0000089 0.000068 0.000070 1994 2 18 49401 0.122956 0.454268 0.0901235 0.0020895 -0.000499 -0.000199 0.000148 0.000129 0.0000065 0.0000091 0.000069 0.000071 1994 2 19 49402 0.124009 0.452338 0.0880588 0.0020134 -0.000670 -0.000179 0.000152 0.000132 0.0000066 0.0000093 0.000070 0.000073 1994 2 20 49403 0.126070 0.450705 0.0860814 0.0019932 -0.000840 -0.000159 0.000155 0.000135 0.0000067 0.0000095 0.000071 0.000074 1994 2 21 49404 0.128158 0.449664 0.0840533 0.0020965 -0.000487 0.000039 0.000158 0.000137 0.0000068 0.0000097 0.000072 0.000075 1994 2 22 49405 0.130756 0.449531 0.0818671 0.0022457 0.000385 0.000415 0.000161 0.000140 0.0000069 0.0000098 0.000073 0.000076 1994 2 23 49406 0.133988 0.448640 0.0795416 0.0024403 0.000276 -0.000147 0.000163 0.000142 0.0000070 0.0000098 0.000073 0.000076 1994 2 24 49407 0.136820 0.448412 0.0769725 0.0027200 0.000180 -0.000273 0.000165 0.000143 0.0000070 0.0000099 0.000073 0.000076 1994 2 25 49408 0.138389 0.448290 0.0741008 0.0030169 0.000122 -0.000213 0.000167 0.000145 0.0000070 0.0000099 0.000073 0.000075 1994 2 26 49409 0.139955 0.447489 0.0709557 0.0032552 0.000064 -0.000152 0.000168 0.000146 0.0000070 0.0000099 0.000073 0.000074 1994 2 27 49410 0.141017 0.446732 0.0676233 0.0033814 0.000006 -0.000091 0.000168 0.000146 0.0000070 0.0000099 0.000073 0.000074 1994 2 28 49411 0.141792 0.445927 0.0642322 0.0033674 -0.000052 -0.000030 0.000169 0.000146 0.0000070 0.0000099 0.000073 0.000073 1994 3 1 49412 0.143038 0.444828 0.0609209 0.0032361 -0.000111 0.000030 0.000169 0.000145 0.0000070 0.0000099 0.000073 0.000072 1994 3 2 49413 0.143991 0.443216 0.0577756 0.0030591 -0.000169 0.000091 0.000168 0.000145 0.0000069 0.0000098 0.000073 0.000072 1994 3 3 49414 0.145194 0.441185 0.0547989 0.0028876 -0.000164 0.000354 0.000168 0.000144 0.0000069 0.0000097 0.000072 0.000071 1994 3 4 49415 0.146462 0.439442 0.0519826 0.0027291 -0.000139 0.000684 0.000167 0.000143 0.0000068 0.0000096 0.000072 0.000070 1994 3 5 49416 0.147210 0.437538 0.0493174 0.0025901 -0.000051 0.000654 0.000167 0.000142 0.0000067 0.0000095 0.000071 0.000069 1994 3 6 49417 0.147574 0.435777 0.0467804 0.0024907 0.000043 0.000590 0.000166 0.000141 0.0000066 0.0000093 0.000071 0.000067 1994 3 7 49418 0.148790 0.434164 0.0443191 0.0024499 0.000137 0.000525 0.000165 0.000140 0.0000065 0.0000092 0.000070 0.000066 1994 3 8 49419 0.149864 0.432611 0.0418697 0.0024757 0.000231 0.000461 0.000164 0.000139 0.0000064 0.0000090 0.000069 0.000065 1994 3 9 49420 0.150673 0.431033 0.0393638 0.0025913 0.000098 0.000133 0.000163 0.000137 0.0000063 0.0000089 0.000069 0.000064 1994 3 10 49421 0.151988 0.429284 0.0366907 0.0026926 -0.000046 0.000010 0.000162 0.000135 0.0000062 0.0000087 0.000068 0.000062 1994 3 11 49422 0.152971 0.427733 0.0339885 0.0026659 -0.000179 -0.000027 0.000160 0.000133 0.0000060 0.0000085 0.000067 0.000061 1994 3 12 49423 0.153789 0.425644 0.0313727 0.0026049 -0.000221 -0.000033 0.000158 0.000132 0.0000059 0.0000084 0.000067 0.000060 1994 3 13 49424 0.155729 0.423574 0.0287928 0.0025491 -0.000198 -0.000016 0.000156 0.000130 0.0000058 0.0000082 0.000066 0.000059 1994 3 14 49425 0.157123 0.421916 0.0262863 0.0024585 -0.000174 0.000000 0.000154 0.000128 0.0000057 0.0000081 0.000065 0.000058 1994 3 15 49426 0.158936 0.421214 0.0238837 0.0023502 -0.000151 0.000017 0.000152 0.000126 0.0000056 0.0000080 0.000064 0.000057 1994 3 16 49427 0.160140 0.420062 0.0215896 0.0022820 -0.000056 0.000097 0.000152 0.000126 0.0000057 0.0000080 0.000064 0.000056 1994 3 17 49428 0.161563 0.418213 0.0193184 0.0022102 -0.000023 0.000104 0.000152 0.000126 0.0000057 0.0000081 0.000064 0.000056 1994 3 18 49429 0.162877 0.416418 0.0171622 0.0021150 -0.000112 0.000112 0.000152 0.000127 0.0000057 0.0000081 0.000064 0.000055 1994 3 19 49430 0.163548 0.415093 0.0150760 0.0020944 -0.000236 0.000113 0.000152 0.000127 0.0000057 0.0000081 0.000065 0.000056 1994 3 20 49431 0.163721 0.413676 0.0129566 0.0021348 -0.000348 0.000098 0.000152 0.000127 0.0000057 0.0000080 0.000065 0.000056 1994 3 21 49432 0.164094 0.412118 0.0107872 0.0022164 -0.000323 0.000022 0.000151 0.000127 0.0000056 0.0000080 0.000065 0.000056 1994 3 22 49433 0.164428 0.410185 0.0085045 0.0023686 -0.000243 -0.000078 0.000150 0.000126 0.0000056 0.0000079 0.000066 0.000055 1994 3 23 49434 0.164291 0.408139 0.0060339 0.0025748 -0.000111 -0.000044 0.000149 0.000126 0.0000055 0.0000077 0.000066 0.000054 1994 3 24 49435 0.165121 0.405578 0.0033471 0.0028105 -0.000092 0.000010 0.000147 0.000124 0.0000053 0.0000077 0.000066 0.000053 1994 3 25 49436 0.166251 0.404283 0.0004188 0.0030587 -0.000204 0.000013 0.000148 0.000125 0.0000054 0.0000077 0.000066 0.000054 1994 3 26 49437 0.167510 0.403077 -0.0027476 0.0032508 -0.000260 0.000001 0.000149 0.000127 0.0000055 0.0000078 0.000066 0.000054 1994 3 27 49438 0.168610 0.400659 -0.0060470 0.0032946 -0.000241 -0.000002 0.000150 0.000128 0.0000056 0.0000080 0.000066 0.000054 1994 3 28 49439 0.169389 0.398758 -0.0092984 0.0031600 -0.000222 -0.000005 0.000152 0.000129 0.0000058 0.0000082 0.000066 0.000055 1994 3 29 49440 0.170141 0.397086 -0.0123394 0.0029203 -0.000204 -0.000008 0.000153 0.000130 0.0000059 0.0000083 0.000067 0.000055 1994 3 30 49441 0.170727 0.395090 -0.0151314 0.0027112 -0.000185 -0.000011 0.000153 0.000131 0.0000060 0.0000085 0.000067 0.000056 1994 3 31 49442 0.171652 0.392774 -0.0177738 0.0025545 -0.000112 -0.000034 0.000154 0.000132 0.0000062 0.0000087 0.000067 0.000057 1994 4 1 49443 0.173136 0.391008 -0.0202640 0.0024119 -0.000021 -0.000065 0.000156 0.000134 0.0000063 0.0000089 0.000068 0.000057 1994 4 2 49444 0.174682 0.389358 -0.0226217 0.0023522 0.000070 -0.000096 0.000157 0.000135 0.0000064 0.0000091 0.000068 0.000058 1994 4 3 49445 0.176421 0.388129 -0.0249857 0.0024047 0.000161 -0.000127 0.000158 0.000136 0.0000065 0.0000092 0.000069 0.000059 1994 4 4 49446 0.177883 0.386520 -0.0274397 0.0024682 0.000125 -0.000114 0.000159 0.000137 0.0000066 0.0000093 0.000069 0.000059 1994 4 5 49447 0.178825 0.384452 -0.0299241 0.0024822 0.000081 -0.000099 0.000159 0.000138 0.0000067 0.0000094 0.000069 0.000059 1994 4 6 49448 0.179568 0.382561 -0.0324015 0.0025287 0.000037 -0.000084 0.000159 0.000138 0.0000067 0.0000095 0.000069 0.000060 1994 4 7 49449 0.180843 0.381375 -0.0349752 0.0026168 0.000060 -0.000052 0.000159 0.000138 0.0000068 0.0000096 0.000069 0.000060 1994 4 8 49450 0.181599 0.379421 -0.0376254 0.0026496 0.000106 -0.000015 0.000159 0.000138 0.0000068 0.0000096 0.000069 0.000060 1994 4 9 49451 0.181709 0.377437 -0.0402626 0.0026280 0.000153 0.000022 0.000159 0.000138 0.0000068 0.0000096 0.000069 0.000060 1994 4 10 49452 0.182667 0.375332 -0.0428702 0.0025980 0.000199 0.000060 0.000158 0.000137 0.0000068 0.0000096 0.000069 0.000061 1994 4 11 49453 0.183333 0.373918 -0.0454504 0.0025042 0.000245 0.000097 0.000156 0.000136 0.0000067 0.0000095 0.000069 0.000061 1994 4 12 49454 0.183604 0.372681 -0.0478744 0.0023646 0.000292 0.000134 0.000154 0.000135 0.0000067 0.0000095 0.000069 0.000061 1994 4 13 49455 0.183306 0.371034 -0.0501796 0.0024387 -0.000139 0.000033 0.000153 0.000133 0.0000066 0.0000094 0.000068 0.000061 1994 4 14 49456 0.182853 0.369040 -0.0527564 0.0022399 -0.000687 0.000108 0.000150 0.000131 0.0000065 0.0000092 0.000068 0.000061 1994 4 15 49457 0.182893 0.366568 -0.0546687 0.0020172 -0.000829 0.000235 0.000148 0.000129 0.0000064 0.0000091 0.000067 0.000060 1994 4 16 49458 0.183048 0.364189 -0.0568048 0.0020967 -0.000761 0.000355 0.000146 0.000127 0.0000063 0.0000088 0.000066 0.000059 1994 4 17 49459 0.183540 0.362051 -0.0588792 0.0021149 -0.000692 0.000476 0.000143 0.000125 0.0000061 0.0000086 0.000065 0.000058 1994 4 18 49460 0.183855 0.360221 -0.0610522 0.0022387 -0.000623 0.000596 0.000141 0.000122 0.0000059 0.0000083 0.000064 0.000057 1994 4 19 49461 0.184060 0.358130 -0.0633722 0.0023872 -0.000554 0.000717 0.000138 0.000120 0.0000057 0.0000081 0.000063 0.000056 1994 4 20 49462 0.183810 0.356777 -0.0658366 0.0025611 -0.000045 0.000154 0.000135 0.000117 0.0000055 0.0000078 0.000062 0.000054 1994 4 21 49463 0.184026 0.355484 -0.0684950 0.0027619 0.000059 0.000026 0.000133 0.000115 0.0000054 0.0000076 0.000060 0.000053 1994 4 22 49464 0.184018 0.354115 -0.0713483 0.0029497 0.000017 0.000061 0.000130 0.000113 0.0000053 0.0000074 0.000060 0.000052 1994 4 23 49465 0.183633 0.352755 -0.0743689 0.0031028 -0.000025 0.000096 0.000127 0.000110 0.0000051 0.0000072 0.000059 0.000051 1994 4 24 49466 0.183375 0.350657 -0.0775197 0.0031552 -0.000068 0.000131 0.000125 0.000108 0.0000049 0.0000070 0.000058 0.000049 1994 4 25 49467 0.182759 0.348845 -0.0806467 0.0030637 -0.000110 0.000166 0.000122 0.000106 0.0000048 0.0000068 0.000057 0.000049 1994 4 26 49468 0.182652 0.346415 -0.0836278 0.0028762 -0.000152 0.000201 0.000120 0.000103 0.0000046 0.0000066 0.000056 0.000048 1994 4 27 49469 0.182661 0.343848 -0.0863998 0.0026629 -0.000087 0.000007 0.000117 0.000101 0.0000045 0.0000063 0.000055 0.000047 1994 4 28 49470 0.182991 0.341134 -0.0889721 0.0025143 -0.000030 -0.000017 0.000114 0.000098 0.0000043 0.0000061 0.000054 0.000046 1994 4 29 49471 0.182769 0.338398 -0.0914544 0.0024551 -0.000010 0.000069 0.000111 0.000095 0.0000042 0.0000060 0.000053 0.000044 1994 4 30 49472 0.183205 0.335883 -0.0939043 0.0024590 -0.000016 0.000104 0.000110 0.000094 0.0000041 0.0000059 0.000052 0.000043 1994 5 1 49473 0.183715 0.333728 -0.0963834 0.0025225 -0.000030 0.000090 0.000110 0.000094 0.0000041 0.0000058 0.000052 0.000043 1994 5 2 49474 0.184145 0.331957 -0.0989498 0.0025818 -0.000044 0.000076 0.000109 0.000093 0.0000041 0.0000058 0.000052 0.000042 1994 5 3 49475 0.184798 0.329927 -0.1015414 0.0025922 -0.000058 0.000062 0.000108 0.000092 0.0000041 0.0000058 0.000051 0.000042 1994 5 4 49476 0.185270 0.327835 -0.1041265 0.0026220 -0.000072 0.000048 0.000107 0.000091 0.0000041 0.0000057 0.000051 0.000042 1994 5 5 49477 0.185360 0.325927 -0.1067773 0.0026625 -0.000079 0.000054 0.000106 0.000090 0.0000040 0.0000057 0.000050 0.000041 1994 5 6 49478 0.185391 0.323747 -0.1094428 0.0026229 -0.000083 0.000068 0.000105 0.000089 0.0000040 0.0000056 0.000050 0.000041 1994 5 7 49479 0.185649 0.321260 -0.1120142 0.0025174 -0.000088 0.000082 0.000104 0.000088 0.0000039 0.0000055 0.000049 0.000040 1994 5 8 49480 0.186105 0.318383 -0.1144700 0.0024261 -0.000092 0.000096 0.000103 0.000087 0.0000038 0.0000054 0.000049 0.000040 1994 5 9 49481 0.186513 0.316148 -0.1168622 0.0023554 -0.000096 0.000109 0.000101 0.000085 0.0000037 0.0000052 0.000048 0.000039 1994 5 10 49482 0.186896 0.314052 -0.1191808 0.0022750 -0.000100 0.000123 0.000099 0.000083 0.0000036 0.0000051 0.000048 0.000039 1994 5 11 49483 0.187981 0.312090 -0.1214164 0.0022072 -0.000072 0.000066 0.000097 0.000082 0.0000035 0.0000049 0.000048 0.000038 1994 5 12 49484 0.188477 0.310174 -0.1236031 0.0021701 -0.000013 0.000032 0.000095 0.000080 0.0000034 0.0000049 0.000047 0.000038 1994 5 13 49485 0.189150 0.308483 -0.1257685 0.0021608 0.000099 -0.000011 0.000096 0.000081 0.0000034 0.0000049 0.000048 0.000038 1994 5 14 49486 0.189443 0.306064 -0.1279402 0.0021743 0.000187 0.000039 0.000099 0.000083 0.0000035 0.0000050 0.000049 0.000039 1994 5 15 49487 0.188973 0.303727 -0.1301342 0.0022092 0.000242 0.000164 0.000101 0.000085 0.0000036 0.0000051 0.000049 0.000041 1994 5 16 49488 0.188289 0.301579 -0.1323741 0.0022907 0.000296 0.000289 0.000103 0.000087 0.0000037 0.0000053 0.000050 0.000042 1994 5 17 49489 0.187790 0.299910 -0.1347260 0.0024347 0.000351 0.000414 0.000105 0.000089 0.0000038 0.0000054 0.000051 0.000043 1994 5 18 49490 0.187158 0.297771 -0.1372459 0.0026080 0.000112 0.000169 0.000107 0.000091 0.0000039 0.0000055 0.000052 0.000044 1994 5 19 49491 0.187295 0.295825 -0.1399348 0.0027508 -0.000294 -0.000096 0.000109 0.000093 0.0000040 0.0000057 0.000053 0.000045 1994 5 20 49492 0.187005 0.293359 -0.1427303 0.0028149 -0.000377 -0.000119 0.000111 0.000094 0.0000041 0.0000059 0.000053 0.000046 1994 5 21 49493 0.186763 0.291613 -0.1455391 0.0027810 -0.000278 -0.000025 0.000113 0.000096 0.0000043 0.0000060 0.000054 0.000047 1994 5 22 49494 0.186253 0.289841 -0.1482637 0.0026532 -0.000179 0.000069 0.000115 0.000098 0.0000044 0.0000062 0.000055 0.000048 1994 5 23 49495 0.185568 0.288482 -0.1508224 0.0024595 -0.000080 0.000163 0.000117 0.000100 0.0000046 0.0000065 0.000056 0.000049 1994 5 24 49496 0.184087 0.287072 -0.1531738 0.0022508 0.000019 0.000256 0.000119 0.000102 0.0000047 0.0000067 0.000056 0.000050 1994 5 25 49497 0.182611 0.285485 -0.1553329 0.0020884 0.000007 0.000017 0.000121 0.000103 0.0000049 0.0000069 0.000057 0.000050 1994 5 26 49498 0.181427 0.283361 -0.1573732 0.0019846 -0.000067 -0.000228 0.000122 0.000105 0.0000050 0.0000071 0.000058 0.000051 1994 5 27 49499 0.180107 0.281004 -0.1593279 0.0019171 -0.000074 -0.000259 0.000123 0.000106 0.0000052 0.0000073 0.000058 0.000051 1994 5 28 49500 0.178791 0.278650 -0.1612255 0.0018909 -0.000039 -0.000179 0.000125 0.000107 0.0000053 0.0000074 0.000059 0.000052 1994 5 29 49501 0.177654 0.276541 -0.1631145 0.0019106 -0.000004 -0.000100 0.000125 0.000108 0.0000053 0.0000075 0.000059 0.000052 1994 5 30 49502 0.176714 0.274334 -0.1650404 0.0019559 0.000032 -0.000020 0.000126 0.000109 0.0000054 0.0000076 0.000060 0.000052 1994 5 31 49503 0.175412 0.271891 -0.1670148 0.0019988 0.000067 0.000059 0.000126 0.000109 0.0000054 0.0000077 0.000060 0.000053 1994 6 1 49504 0.174209 0.269365 -0.1690266 0.0020202 0.000103 0.000139 0.000126 0.000109 0.0000055 0.0000078 0.000061 0.000053 1994 6 2 49505 0.173516 0.266990 -0.1710456 0.0020011 0.000102 0.000087 0.000127 0.000110 0.0000055 0.0000078 0.000061 0.000054 1994 6 3 49506 0.172760 0.265100 -0.1730208 0.0019320 0.000090 -0.000009 0.000127 0.000110 0.0000056 0.0000079 0.000062 0.000055 1994 6 4 49507 0.171426 0.263317 -0.1749030 0.0018317 0.000070 -0.000003 0.000127 0.000111 0.0000056 0.0000079 0.000063 0.000055 1994 6 5 49508 0.170365 0.261430 -0.1766799 0.0017203 0.000050 0.000002 0.000128 0.000111 0.0000056 0.0000080 0.000063 0.000056 1994 6 6 49509 0.169246 0.259778 -0.1783430 0.0015936 0.000029 0.000007 0.000128 0.000112 0.0000056 0.0000080 0.000064 0.000056 1994 6 7 49510 0.167609 0.257996 -0.1798710 0.0014720 0.000009 0.000012 0.000128 0.000112 0.0000056 0.0000079 0.000065 0.000057 1994 6 8 49511 0.165965 0.256415 -0.1812949 0.0014128 -0.000011 0.000017 0.000129 0.000113 0.0000056 0.0000079 0.000065 0.000057 1994 6 9 49512 0.165864 0.254099 -0.1827080 0.0014005 0.000032 0.000067 0.000129 0.000114 0.0000055 0.0000078 0.000066 0.000057 1994 6 10 49513 0.164775 0.252171 -0.1841104 0.0014099 0.000053 0.000064 0.000129 0.000114 0.0000054 0.0000077 0.000067 0.000058 1994 6 11 49514 0.163709 0.250233 -0.1855447 0.0014861 0.000053 0.000027 0.000129 0.000114 0.0000054 0.0000076 0.000067 0.000059 1994 6 12 49515 0.162564 0.248057 -0.1870991 0.0016229 0.000052 -0.000010 0.000129 0.000114 0.0000053 0.0000075 0.000068 0.000060 1994 6 13 49516 0.161537 0.245684 -0.1888025 0.0017760 0.000052 -0.000047 0.000129 0.000115 0.0000052 0.0000073 0.000068 0.000061 1994 6 14 49517 0.160575 0.243311 -0.1906550 0.0019208 0.000065 -0.000110 0.000128 0.000115 0.0000051 0.0000072 0.000069 0.000062 1994 6 15 49518 0.160068 0.241148 -0.1926377 0.0020393 0.000126 -0.000267 0.000128 0.000115 0.0000050 0.0000070 0.000069 0.000062 1994 6 16 49519 0.159307 0.239501 -0.1947181 0.0021116 0.000366 0.000004 0.000128 0.000115 0.0000049 0.0000070 0.000069 0.000062 1994 6 17 49520 0.158661 0.237855 -0.1968393 0.0021340 0.000424 0.000132 0.000127 0.000114 0.0000049 0.0000070 0.000069 0.000062 1994 6 18 49521 0.157865 0.236181 -0.1989625 0.0020914 0.000359 0.000113 0.000127 0.000114 0.0000050 0.0000071 0.000068 0.000061 1994 6 19 49522 0.156451 0.234491 -0.2010017 0.0019376 0.000293 0.000094 0.000127 0.000114 0.0000051 0.0000072 0.000068 0.000060 1994 6 20 49523 0.154726 0.232541 -0.2028262 0.0017068 0.000228 0.000075 0.000126 0.000114 0.0000052 0.0000074 0.000067 0.000060 1994 6 21 49524 0.152776 0.230203 -0.2044170 0.0014892 0.000163 0.000056 0.000125 0.000113 0.0000053 0.0000075 0.000067 0.000059 1994 6 22 49525 0.151104 0.227807 -0.2058200 0.0013439 0.000063 0.000068 0.000125 0.000113 0.0000054 0.0000076 0.000067 0.000059 1994 6 23 49526 0.149830 0.225533 -0.2071289 0.0012698 -0.000013 0.000167 0.000124 0.000112 0.0000054 0.0000077 0.000067 0.000059 1994 6 24 49527 0.148432 0.223576 -0.2083828 0.0012197 -0.000078 0.000292 0.000124 0.000112 0.0000055 0.0000077 0.000067 0.000059 1994 6 25 49528 0.146589 0.221811 -0.2095814 0.0012047 -0.000143 0.000418 0.000124 0.000112 0.0000055 0.0000078 0.000067 0.000060 1994 6 26 49529 0.145089 0.219965 -0.2107917 0.0012693 -0.000163 0.000466 0.000123 0.000112 0.0000055 0.0000077 0.000067 0.000060 1994 6 27 49530 0.143368 0.218025 -0.2121087 0.0013468 -0.000049 0.000279 0.000123 0.000111 0.0000054 0.0000077 0.000067 0.000059 1994 6 28 49531 0.141509 0.216231 -0.2134698 0.0013477 0.000043 0.000114 0.000122 0.000111 0.0000054 0.0000076 0.000066 0.000059 1994 6 29 49532 0.139829 0.214759 -0.2147903 0.0012917 -0.000114 0.000203 0.000121 0.000110 0.0000053 0.0000075 0.000066 0.000058 1994 6 30 49533 0.138274 0.213609 -0.2160429 0.0011981 -0.000149 0.000313 0.000120 0.000109 0.0000052 0.0000074 0.000065 0.000057 1994 7 1 49534 0.136269 0.211786 0.7828207 0.0010991 -0.000065 0.000110 0.000118 0.000107 0.0000052 0.0000074 0.000064 0.000056 1994 7 2 49535 0.135030 0.210906 0.7817638 0.0010438 -0.000003 -0.000028 0.000118 0.000106 0.0000052 0.0000074 0.000063 0.000055 1994 7 3 49536 0.133327 0.209548 0.7807347 0.0010118 0.000013 0.000007 0.000117 0.000106 0.0000053 0.0000075 0.000063 0.000054 1994 7 4 49537 0.131282 0.208332 0.7797376 0.0009687 0.000028 0.000042 0.000116 0.000105 0.0000053 0.0000076 0.000062 0.000054 1994 7 5 49538 0.129243 0.206687 0.7787899 0.0009118 0.000043 0.000077 0.000115 0.000104 0.0000054 0.0000077 0.000061 0.000053 1994 7 6 49539 0.127482 0.205337 0.7779029 0.0008603 0.000058 0.000112 0.000114 0.000104 0.0000055 0.0000078 0.000061 0.000052 1994 7 7 49540 0.125690 0.203721 0.7770552 0.0008688 0.000121 0.000079 0.000113 0.000103 0.0000055 0.0000078 0.000060 0.000052 1994 7 8 49541 0.123921 0.202051 0.7761489 0.0009849 0.000200 0.000023 0.000112 0.000102 0.0000056 0.0000079 0.000060 0.000051 1994 7 9 49542 0.122261 0.200631 0.7750682 0.0011680 0.000225 -0.000014 0.000111 0.000101 0.0000056 0.0000079 0.000059 0.000051 1994 7 10 49543 0.120517 0.199362 0.7737982 0.0013514 0.000162 -0.000020 0.000111 0.000101 0.0000056 0.0000079 0.000059 0.000051 1994 7 11 49544 0.118511 0.198053 0.7723581 0.0015299 0.000099 -0.000025 0.000111 0.000100 0.0000056 0.0000079 0.000059 0.000050 1994 7 12 49545 0.116854 0.197175 0.7707424 0.0017045 0.000036 -0.000031 0.000110 0.000099 0.0000056 0.0000078 0.000059 0.000050 1994 7 13 49546 0.115465 0.196224 0.7689649 0.0018433 0.000029 0.000043 0.000109 0.000098 0.0000055 0.0000078 0.000059 0.000050 1994 7 14 49547 0.113682 0.195039 0.7670791 0.0019209 0.000035 -0.000082 0.000109 0.000097 0.0000054 0.0000078 0.000059 0.000051 1994 7 15 49548 0.111823 0.193633 0.7651476 0.0019072 -0.000143 -0.000248 0.000109 0.000097 0.0000055 0.0000078 0.000059 0.000051 1994 7 16 49549 0.109756 0.192456 0.7632841 0.0018234 -0.000228 -0.000243 0.000109 0.000098 0.0000056 0.0000080 0.000060 0.000052 1994 7 17 49550 0.108062 0.191283 0.7615113 0.0017447 -0.000181 -0.000126 0.000109 0.000098 0.0000058 0.0000082 0.000060 0.000053 1994 7 18 49551 0.106234 0.189511 0.7597942 0.0016513 -0.000134 -0.000009 0.000109 0.000099 0.0000059 0.0000083 0.000060 0.000053 1994 7 19 49552 0.103892 0.187455 0.7581976 0.0015006 -0.000087 0.000108 0.000109 0.000099 0.0000060 0.0000085 0.000060 0.000054 1994 7 20 49553 0.101993 0.185589 0.7567735 0.0013390 -0.000078 -0.000128 0.000110 0.000099 0.0000061 0.0000087 0.000061 0.000055 1994 7 21 49554 0.100329 0.183651 0.7554970 0.0013101 -0.000029 -0.000245 0.000110 0.000100 0.0000063 0.0000089 0.000061 0.000056 1994 7 22 49555 0.098306 0.182625 0.7541349 0.0013681 0.000078 -0.000171 0.000109 0.000100 0.0000064 0.0000090 0.000062 0.000057 1994 7 23 49556 0.096319 0.181141 0.7527531 0.0013847 0.000201 -0.000189 0.000109 0.000100 0.0000065 0.0000092 0.000062 0.000058 1994 7 24 49557 0.094418 0.179634 0.7513704 0.0014588 0.000320 -0.000317 0.000109 0.000100 0.0000066 0.0000093 0.000062 0.000058 1994 7 25 49558 0.093099 0.178394 0.7498496 0.0015478 0.000440 -0.000445 0.000109 0.000100 0.0000067 0.0000095 0.000062 0.000059 1994 7 26 49559 0.091005 0.177557 0.7482920 0.0015270 0.000559 -0.000574 0.000109 0.000100 0.0000068 0.0000096 0.000063 0.000059 1994 7 27 49560 0.088595 0.176649 0.7468104 0.0014670 0.000114 -0.000078 0.000109 0.000101 0.0000069 0.0000097 0.000063 0.000059 1994 7 28 49561 0.086342 0.176238 0.7453682 0.0014380 0.000036 0.000030 0.000109 0.000101 0.0000070 0.0000099 0.000062 0.000059 1994 7 29 49562 0.084413 0.175521 0.7439405 0.0014112 0.000124 -0.000039 0.000109 0.000101 0.0000071 0.0000100 0.000062 0.000059 1994 7 30 49563 0.082369 0.175648 0.7425486 0.0013614 0.000104 0.000051 0.000110 0.000101 0.0000072 0.0000102 0.000062 0.000060 1994 7 31 49564 0.080396 0.174682 0.7412165 0.0012865 0.000074 0.000155 0.000110 0.000101 0.0000073 0.0000103 0.000062 0.000061 1994 8 1 49565 0.078548 0.174014 0.7399698 0.0011923 0.000044 0.000259 0.000109 0.000101 0.0000073 0.0000104 0.000063 0.000061 1994 8 2 49566 0.076665 0.173471 0.7388215 0.0011083 0.000014 0.000363 0.000109 0.000101 0.0000074 0.0000105 0.000063 0.000062 1994 8 3 49567 0.074726 0.173122 0.7377393 0.0010977 -0.000009 0.000115 0.000109 0.000101 0.0000074 0.0000105 0.000063 0.000062 1994 8 4 49568 0.073168 0.172984 0.7366102 0.0011740 -0.000023 -0.000292 0.000109 0.000101 0.0000075 0.0000105 0.000062 0.000062 1994 8 5 49569 0.071711 0.172850 0.7353744 0.0012971 -0.000004 -0.000490 0.000109 0.000101 0.0000074 0.0000105 0.000062 0.000062 1994 8 6 49570 0.069853 0.172561 0.7340001 0.0014370 -0.000005 -0.000477 0.000109 0.000101 0.0000074 0.0000105 0.000061 0.000061 1994 8 7 49571 0.068099 0.172405 0.7324892 0.0015605 -0.000029 -0.000395 0.000109 0.000100 0.0000073 0.0000104 0.000060 0.000061 1994 8 8 49572 0.066518 0.171816 0.7308779 0.0016529 -0.000054 -0.000314 0.000108 0.000100 0.0000072 0.0000103 0.000060 0.000060 1994 8 9 49573 0.065226 0.171707 0.7291955 0.0017178 -0.000079 -0.000233 0.000108 0.000100 0.0000072 0.0000101 0.000059 0.000059 1994 8 10 49574 0.064240 0.171622 0.7274664 0.0017677 -0.000033 -0.000059 0.000108 0.000099 0.0000070 0.0000100 0.000058 0.000058 1994 8 11 49575 0.063192 0.171859 0.7256891 0.0017642 0.000116 -0.000172 0.000108 0.000099 0.0000069 0.0000098 0.000058 0.000057 1994 8 12 49576 0.061595 0.171447 0.7239629 0.0016690 0.000346 -0.000045 0.000107 0.000098 0.0000069 0.0000097 0.000057 0.000056 1994 8 13 49577 0.059752 0.171527 0.7223646 0.0015142 0.000406 0.000092 0.000107 0.000097 0.0000068 0.0000096 0.000056 0.000055 1994 8 14 49578 0.057303 0.171214 0.7209343 0.0013409 0.000273 0.000072 0.000106 0.000096 0.0000067 0.0000095 0.000056 0.000054 1994 8 15 49579 0.054502 0.170613 0.7196716 0.0012186 0.000140 0.000053 0.000105 0.000096 0.0000066 0.0000093 0.000055 0.000052 1994 8 16 49580 0.051549 0.169646 0.7184790 0.0011993 0.000008 0.000034 0.000105 0.000095 0.0000065 0.0000091 0.000054 0.000051 1994 8 17 49581 0.049441 0.168957 0.7172528 0.0012524 0.000036 -0.000095 0.000104 0.000094 0.0000063 0.0000089 0.000054 0.000050 1994 8 18 49582 0.047663 0.168414 0.7159562 0.0013306 0.000055 -0.000121 0.000103 0.000093 0.0000062 0.0000087 0.000053 0.000049 1994 8 19 49583 0.045788 0.168423 0.7145801 0.0014156 0.000069 -0.000111 0.000102 0.000092 0.0000060 0.0000085 0.000053 0.000048 1994 8 20 49584 0.043169 0.168704 0.7131232 0.0015142 0.000083 -0.000101 0.000102 0.000091 0.0000058 0.0000083 0.000052 0.000047 1994 8 21 49585 0.040024 0.168883 0.7115599 0.0016354 0.000098 -0.000092 0.000101 0.000090 0.0000057 0.0000080 0.000052 0.000046 1994 8 22 49586 0.036704 0.168960 0.7098679 0.0017342 0.000112 -0.000082 0.000100 0.000089 0.0000055 0.0000077 0.000052 0.000045 1994 8 23 49587 0.033342 0.168801 0.7081087 0.0017699 0.000126 -0.000072 0.000098 0.000088 0.0000053 0.0000075 0.000051 0.000044 1994 8 24 49588 0.030438 0.168678 0.7063424 0.0017600 0.000141 -0.000062 0.000097 0.000087 0.0000051 0.0000072 0.000051 0.000044 1994 8 25 49589 0.028224 0.167834 0.7045979 0.0016997 0.000031 0.000062 0.000096 0.000086 0.0000049 0.0000070 0.000050 0.000043 1994 8 26 49590 0.026511 0.167915 0.7029473 0.0016303 -0.000081 0.000146 0.000095 0.000085 0.0000049 0.0000069 0.000051 0.000043 1994 8 27 49591 0.024742 0.168224 0.7013374 0.0015890 -0.000068 0.000138 0.000095 0.000085 0.0000049 0.0000069 0.000051 0.000043 1994 8 28 49592 0.022746 0.168368 0.6997650 0.0015183 0.000021 0.000095 0.000095 0.000085 0.0000049 0.0000069 0.000051 0.000044 1994 8 29 49593 0.020750 0.168730 0.6982920 0.0014366 0.000110 0.000052 0.000095 0.000085 0.0000049 0.0000070 0.000051 0.000044 1994 8 30 49594 0.018505 0.169156 0.6968789 0.0014087 0.000199 0.000009 0.000095 0.000085 0.0000049 0.0000069 0.000051 0.000044 1994 8 31 49595 0.016074 0.169903 0.6954590 0.0014375 0.000143 -0.000060 0.000094 0.000085 0.0000049 0.0000069 0.000051 0.000045 1994 9 1 49596 0.013289 0.170401 0.6939872 0.0015364 0.000212 -0.000024 0.000094 0.000084 0.0000049 0.0000069 0.000051 0.000045 1994 9 2 49597 0.010720 0.170635 0.6923702 0.0017046 0.000215 0.000053 0.000094 0.000084 0.0000049 0.0000069 0.000052 0.000045 1994 9 3 49598 0.008316 0.170670 0.6905648 0.0019173 0.000115 0.000159 0.000093 0.000084 0.0000049 0.0000069 0.000052 0.000045 1994 9 4 49599 0.006103 0.170810 0.6885292 0.0021519 -0.000017 0.000286 0.000093 0.000083 0.0000048 0.0000068 0.000052 0.000045 1994 9 5 49600 0.004212 0.171277 0.6862661 0.0023347 -0.000113 0.000363 0.000092 0.000082 0.0000048 0.0000067 0.000052 0.000045 1994 9 6 49601 0.002021 0.172160 0.6838788 0.0024429 -0.000035 0.000206 0.000092 0.000082 0.0000047 0.0000066 0.000052 0.000044 1994 9 7 49602 -0.000648 0.173390 0.6814102 0.0025094 0.000042 0.000049 0.000091 0.000081 0.0000046 0.0000065 0.000051 0.000044 1994 9 8 49603 -0.003545 0.174304 0.6788916 0.0025380 -0.000099 0.000165 0.000091 0.000081 0.0000045 0.0000065 0.000051 0.000043 1994 9 9 49604 -0.006356 0.174908 0.6763566 0.0025239 -0.000077 0.000186 0.000091 0.000081 0.0000046 0.0000065 0.000051 0.000044 1994 9 10 49605 -0.008846 0.175565 0.6738499 0.0024396 0.000007 0.000116 0.000093 0.000083 0.0000047 0.0000067 0.000052 0.000044 1994 9 11 49606 -0.010789 0.176721 0.6714676 0.0022917 0.000050 0.000047 0.000094 0.000084 0.0000048 0.0000068 0.000052 0.000044 1994 9 12 49607 -0.012932 0.177958 0.6692470 0.0021826 0.000092 -0.000021 0.000095 0.000085 0.0000050 0.0000070 0.000052 0.000045 1994 9 13 49608 -0.015442 0.179251 0.6670809 0.0021853 0.000135 -0.000089 0.000096 0.000086 0.0000051 0.0000072 0.000053 0.000045 1994 9 14 49609 -0.018527 0.179826 0.6648590 0.0022410 0.000123 -0.000149 0.000097 0.000086 0.0000052 0.0000073 0.000053 0.000046 1994 9 15 49610 -0.021714 0.180771 0.6625879 0.0023202 0.000086 -0.000164 0.000097 0.000087 0.0000053 0.0000075 0.000053 0.000047 1994 9 16 49611 -0.025076 0.181573 0.6602148 0.0024602 0.000043 -0.000164 0.000098 0.000088 0.0000054 0.0000076 0.000053 0.000047 1994 9 17 49612 -0.028151 0.182315 0.6576711 0.0025956 0.000070 -0.000152 0.000098 0.000088 0.0000055 0.0000077 0.000054 0.000048 1994 9 18 49613 -0.030812 0.182989 0.6550341 0.0026313 0.000149 -0.000132 0.000099 0.000089 0.0000055 0.0000078 0.000054 0.000048 1994 9 19 49614 -0.033175 0.183535 0.6524233 0.0025928 0.000228 -0.000111 0.000099 0.000089 0.0000056 0.0000079 0.000054 0.000048 1994 9 20 49615 -0.035507 0.184736 0.6498639 0.0025381 0.000307 -0.000090 0.000100 0.000090 0.0000056 0.0000079 0.000054 0.000049 1994 9 21 49616 -0.038193 0.186089 0.6473593 0.0024724 0.000061 -0.000150 0.000100 0.000090 0.0000056 0.0000080 0.000054 0.000049 1994 9 22 49617 -0.041378 0.187087 0.6449262 0.0023793 -0.000032 -0.000148 0.000100 0.000090 0.0000056 0.0000080 0.000054 0.000049 1994 9 23 49618 -0.044076 0.188221 0.6426024 0.0022539 -0.000066 -0.000122 0.000100 0.000090 0.0000056 0.0000080 0.000054 0.000049 1994 9 24 49619 -0.047374 0.189185 0.6404156 0.0021381 -0.000076 -0.000058 0.000099 0.000090 0.0000056 0.0000079 0.000053 0.000048 1994 9 25 49620 -0.049701 0.190482 0.6383192 0.0020592 -0.000084 0.000010 0.000099 0.000090 0.0000056 0.0000078 0.000053 0.000048 1994 9 26 49621 -0.052228 0.191744 0.6362862 0.0019816 -0.000091 0.000078 0.000098 0.000089 0.0000055 0.0000078 0.000053 0.000047 1994 9 27 49622 -0.055084 0.193064 0.6343415 0.0019064 -0.000099 0.000145 0.000097 0.000089 0.0000054 0.0000076 0.000053 0.000047 1994 9 28 49623 -0.057673 0.194254 0.6324569 0.0019300 -0.000001 -0.000055 0.000096 0.000088 0.0000053 0.0000075 0.000052 0.000046 1994 9 29 49624 -0.060503 0.195865 0.6304653 0.0020388 0.000130 0.000030 0.000095 0.000087 0.0000052 0.0000074 0.000052 0.000046 1994 9 30 49625 -0.063354 0.197480 0.6283653 0.0021641 0.000140 0.000061 0.000094 0.000087 0.0000052 0.0000073 0.000051 0.000045 1994 10 1 49626 -0.065674 0.198963 0.6261279 0.0023309 0.000084 0.000014 0.000093 0.000086 0.0000051 0.0000071 0.000051 0.000044 1994 10 2 49627 -0.067551 0.200671 0.6237025 0.0024857 0.000027 -0.000032 0.000092 0.000085 0.0000049 0.0000070 0.000050 0.000043 1994 10 3 49628 -0.069406 0.202433 0.6211670 0.0026266 -0.000029 -0.000078 0.000091 0.000085 0.0000048 0.0000068 0.000050 0.000043 1994 10 4 49629 -0.071064 0.204415 0.6184726 0.0027931 -0.000085 -0.000125 0.000090 0.000084 0.0000046 0.0000065 0.000049 0.000042 1994 10 5 49630 -0.073583 0.206586 0.6156125 0.0028796 0.000034 0.000029 0.000088 0.000082 0.0000045 0.0000064 0.000048 0.000041 1994 10 6 49631 -0.076516 0.208030 0.6127435 0.0028150 0.000153 -0.000013 0.000087 0.000082 0.0000044 0.0000062 0.000048 0.000040 1994 10 7 49632 -0.080004 0.209223 0.6099999 0.0026588 0.000097 -0.000182 0.000086 0.000081 0.0000043 0.0000061 0.000047 0.000039 1994 10 8 49633 -0.083633 0.210429 0.6074247 0.0024886 0.000047 -0.000257 0.000085 0.000081 0.0000042 0.0000060 0.000046 0.000037 1994 10 9 49634 -0.086529 0.211851 0.6050055 0.0023543 0.000062 -0.000244 0.000083 0.000080 0.0000041 0.0000058 0.000045 0.000036 1994 10 10 49635 -0.089581 0.213386 0.6026921 0.0022867 0.000078 -0.000232 0.000082 0.000079 0.0000040 0.0000057 0.000044 0.000035 1994 10 11 49636 -0.091955 0.214646 0.6004111 0.0022917 0.000093 -0.000219 0.000081 0.000078 0.0000039 0.0000056 0.000043 0.000034 1994 10 12 49637 -0.093438 0.215884 0.5980966 0.0023494 0.000109 -0.000207 0.000079 0.000077 0.0000038 0.0000055 0.000042 0.000033 1994 10 13 49638 -0.094634 0.217529 0.5957094 0.0024309 0.000118 -0.000178 0.000078 0.000076 0.0000038 0.0000054 0.000042 0.000032 1994 10 14 49639 -0.095872 0.219392 0.5932386 0.0025074 0.000126 -0.000145 0.000077 0.000075 0.0000037 0.0000054 0.000041 0.000031 1994 10 15 49640 -0.096897 0.221852 0.5907027 0.0025488 0.000110 -0.000124 0.000077 0.000076 0.0000038 0.0000054 0.000041 0.000031 1994 10 16 49641 -0.098237 0.224205 0.5881522 0.0025321 0.000089 -0.000107 0.000079 0.000077 0.0000038 0.0000054 0.000041 0.000032 1994 10 17 49642 -0.099462 0.226487 0.5856513 0.0024544 0.000068 -0.000089 0.000080 0.000078 0.0000039 0.0000055 0.000042 0.000033 1994 10 18 49643 -0.101487 0.228906 0.5832557 0.0023324 0.000047 -0.000071 0.000081 0.000079 0.0000040 0.0000056 0.000042 0.000033 1994 10 19 49644 -0.104097 0.231209 0.5809956 0.0021964 0.000206 -0.000135 0.000082 0.000079 0.0000040 0.0000056 0.000042 0.000034 1994 10 20 49645 -0.106985 0.233393 0.5788670 0.0020806 0.000130 -0.000205 0.000083 0.000080 0.0000040 0.0000057 0.000042 0.000035 1994 10 21 49646 -0.110184 0.235488 0.5768335 0.0020048 -0.000025 -0.000277 0.000084 0.000081 0.0000041 0.0000057 0.000043 0.000035 1994 10 22 49647 -0.113092 0.237606 0.5748520 0.0019568 0.000022 -0.000244 0.000085 0.000081 0.0000041 0.0000057 0.000043 0.000036 1994 10 23 49648 -0.115232 0.239482 0.5729107 0.0019257 0.000078 -0.000207 0.000085 0.000082 0.0000041 0.0000057 0.000043 0.000036 1994 10 24 49649 -0.117416 0.241801 0.5709880 0.0019350 0.000133 -0.000170 0.000086 0.000082 0.0000040 0.0000057 0.000043 0.000037 1994 10 25 49650 -0.119220 0.244149 0.5690255 0.0020048 0.000189 -0.000132 0.000086 0.000082 0.0000040 0.0000057 0.000044 0.000038 1994 10 26 49651 -0.121392 0.246155 0.5669623 0.0021282 0.000229 -0.000129 0.000087 0.000082 0.0000040 0.0000056 0.000044 0.000038 1994 10 27 49652 -0.123532 0.248282 0.5647546 0.0022458 0.000212 -0.000216 0.000087 0.000083 0.0000039 0.0000056 0.000044 0.000039 1994 10 28 49653 -0.125966 0.250225 0.5624602 0.0023865 0.000147 -0.000190 0.000088 0.000083 0.0000039 0.0000056 0.000044 0.000039 1994 10 29 49654 -0.128616 0.252160 0.5599775 0.0025924 0.000125 -0.000120 0.000089 0.000084 0.0000040 0.0000057 0.000045 0.000040 1994 10 30 49655 -0.130668 0.254192 0.5572797 0.0027603 0.000150 -0.000059 0.000091 0.000086 0.0000041 0.0000059 0.000045 0.000041 1994 10 31 49656 -0.131800 0.256250 0.5544718 0.0028695 0.000175 0.000001 0.000093 0.000087 0.0000043 0.0000061 0.000046 0.000042 1994 11 1 49657 -0.133053 0.258729 0.5515654 0.0029493 0.000200 0.000062 0.000094 0.000089 0.0000045 0.0000063 0.000047 0.000043 1994 11 2 49658 -0.134474 0.260975 0.5486025 0.0029444 0.000080 -0.000016 0.000096 0.000090 0.0000046 0.0000066 0.000047 0.000044 1994 11 3 49659 -0.136158 0.263124 0.5457013 0.0028675 0.000033 -0.000311 0.000097 0.000091 0.0000048 0.0000068 0.000048 0.000045 1994 11 4 49660 -0.137271 0.265001 0.5428777 0.0026906 -0.000023 -0.000308 0.000099 0.000092 0.0000050 0.0000071 0.000048 0.000045 1994 11 5 49661 -0.138612 0.266968 0.5403120 0.0024506 -0.000097 -0.000113 0.000100 0.000094 0.0000052 0.0000073 0.000048 0.000046 1994 11 6 49662 -0.140027 0.269517 0.5379544 0.0023547 -0.000172 0.000082 0.000101 0.000094 0.0000053 0.0000075 0.000048 0.000047 1994 11 7 49663 -0.141446 0.271894 0.5355774 0.0023178 -0.000079 0.000039 0.000102 0.000095 0.0000054 0.0000077 0.000048 0.000047 1994 11 8 49664 -0.142787 0.274318 0.5333013 0.0022863 0.000096 -0.000119 0.000102 0.000096 0.0000056 0.0000078 0.000048 0.000048 1994 11 9 49665 -0.144472 0.276415 0.5309998 0.0023392 0.000049 -0.000019 0.000101 0.000096 0.0000057 0.0000080 0.000048 0.000047 1994 11 10 49666 -0.145255 0.278855 0.5286282 0.0024229 -0.000017 -0.000048 0.000101 0.000096 0.0000057 0.0000081 0.000048 0.000047 1994 11 11 49667 -0.145494 0.281711 0.5261646 0.0025147 -0.000083 -0.000130 0.000101 0.000095 0.0000058 0.0000082 0.000048 0.000047 1994 11 12 49668 -0.145564 0.284737 0.5236103 0.0025549 -0.000090 -0.000162 0.000100 0.000095 0.0000059 0.0000083 0.000047 0.000046 1994 11 13 49669 -0.146051 0.287695 0.5210656 0.0025007 -0.000054 -0.000159 0.000100 0.000095 0.0000059 0.0000083 0.000047 0.000046 1994 11 14 49670 -0.146743 0.290407 0.5186191 0.0024257 -0.000018 -0.000155 0.000100 0.000095 0.0000059 0.0000083 0.000046 0.000045 1994 11 15 49671 -0.147415 0.292986 0.5162229 0.0023873 0.000018 -0.000152 0.000100 0.000095 0.0000059 0.0000083 0.000045 0.000044 1994 11 16 49672 -0.148039 0.295415 0.5138499 0.0023388 0.000054 -0.000149 0.000100 0.000094 0.0000059 0.0000083 0.000045 0.000044 1994 11 17 49673 -0.148629 0.297850 0.5115461 0.0022701 0.000066 -0.000153 0.000099 0.000094 0.0000058 0.0000082 0.000044 0.000043 1994 11 18 49674 -0.149347 0.300621 0.5093057 0.0021689 0.000070 -0.000160 0.000099 0.000093 0.0000058 0.0000082 0.000044 0.000042 1994 11 19 49675 -0.150336 0.303591 0.5072004 0.0020171 0.000073 -0.000167 0.000098 0.000093 0.0000057 0.0000081 0.000044 0.000041 1994 11 20 49676 -0.151530 0.306110 0.5052605 0.0019563 0.000077 -0.000174 0.000097 0.000092 0.0000056 0.0000079 0.000043 0.000041 1994 11 21 49677 -0.152619 0.308571 0.5032743 0.0020163 0.000081 -0.000181 0.000096 0.000091 0.0000054 0.0000077 0.000043 0.000040 1994 11 22 49678 -0.153424 0.311653 0.5012127 0.0020967 0.000085 -0.000188 0.000095 0.000090 0.0000053 0.0000075 0.000043 0.000040 1994 11 23 49679 -0.153953 0.314710 0.4990661 0.0022184 0.000035 -0.000180 0.000094 0.000090 0.0000052 0.0000073 0.000042 0.000039 1994 11 24 49680 -0.153823 0.317371 0.4967646 0.0023884 0.000008 -0.000180 0.000093 0.000089 0.0000050 0.0000071 0.000042 0.000038 1994 11 25 49681 -0.152937 0.320113 0.4942839 0.0025539 -0.000010 -0.000183 0.000092 0.000088 0.0000048 0.0000068 0.000042 0.000037 1994 11 26 49682 -0.152144 0.323178 0.4916588 0.0026737 -0.000028 -0.000186 0.000091 0.000087 0.0000047 0.0000066 0.000041 0.000036 1994 11 27 49683 -0.151696 0.325743 0.4889468 0.0027365 -0.000046 -0.000189 0.000089 0.000085 0.0000045 0.0000064 0.000041 0.000036 1994 11 28 49684 -0.151519 0.328539 0.4862037 0.0027481 -0.000063 -0.000192 0.000087 0.000084 0.0000043 0.0000061 0.000040 0.000035 1994 11 29 49685 -0.151736 0.331056 0.4834738 0.0027217 -0.000081 -0.000195 0.000086 0.000082 0.0000042 0.0000060 0.000040 0.000034 1994 11 30 49686 -0.151290 0.334120 0.4807839 0.0026830 -0.000035 -0.000183 0.000084 0.000081 0.0000042 0.0000059 0.000040 0.000034 1994 12 1 49687 -0.151586 0.336735 0.4781238 0.0026017 -0.000050 -0.000187 0.000083 0.000081 0.0000042 0.0000060 0.000039 0.000034 1994 12 2 49688 -0.152179 0.339377 0.4755820 0.0024485 -0.000091 -0.000197 0.000082 0.000081 0.0000043 0.0000060 0.000039 0.000033 1994 12 3 49689 -0.152900 0.341584 0.4732124 0.0023185 -0.000131 -0.000206 0.000081 0.000080 0.0000043 0.0000061 0.000039 0.000033 1994 12 4 49690 -0.153422 0.343636 0.4709206 0.0022861 -0.000142 -0.000234 0.000080 0.000080 0.0000043 0.0000061 0.000038 0.000032 1994 12 5 49691 -0.153092 0.345976 0.4686168 0.0023223 -0.000125 -0.000278 0.000079 0.000079 0.0000043 0.0000061 0.000038 0.000032 1994 12 6 49692 -0.152267 0.348171 0.4662636 0.0023849 -0.000107 -0.000321 0.000078 0.000079 0.0000043 0.0000061 0.000038 0.000032 1994 12 7 49693 -0.152006 0.350340 0.4638490 0.0024681 0.000024 -0.000214 0.000076 0.000078 0.0000043 0.0000061 0.000037 0.000031 1994 12 8 49694 -0.151786 0.352308 0.4613401 0.0025274 0.000036 -0.000088 0.000075 0.000077 0.0000043 0.0000061 0.000037 0.000031 1994 12 9 49695 -0.151682 0.355032 0.4588103 0.0025088 0.000030 -0.000039 0.000073 0.000075 0.0000042 0.0000060 0.000036 0.000030 1994 12 10 49696 -0.151574 0.357875 0.4563365 0.0024610 0.000037 -0.000028 0.000071 0.000074 0.0000042 0.0000059 0.000035 0.000029 1994 12 11 49697 -0.152081 0.361037 0.4538987 0.0024464 0.000044 -0.000017 0.000069 0.000073 0.0000041 0.0000058 0.000035 0.000028 1994 12 12 49698 -0.153080 0.364083 0.4514514 0.0024403 0.000051 -0.000007 0.000068 0.000071 0.0000040 0.0000057 0.000034 0.000027 1994 12 13 49699 -0.154055 0.366589 0.4490232 0.0023973 0.000058 0.000004 0.000066 0.000070 0.0000039 0.0000056 0.000033 0.000026 1994 12 14 49700 -0.154086 0.369009 0.4466585 0.0023156 0.000166 -0.000135 0.000064 0.000068 0.0000039 0.0000056 0.000033 0.000025 1994 12 15 49701 -0.154240 0.371711 0.4443893 0.0022343 0.000123 -0.000188 0.000062 0.000067 0.0000040 0.0000057 0.000032 0.000024 1994 12 16 49702 -0.154383 0.374486 0.4421827 0.0022050 0.000025 -0.000203 0.000060 0.000065 0.0000041 0.0000058 0.000031 0.000023 1994 12 17 49703 -0.154664 0.377044 0.4399686 0.0022288 0.000016 -0.000225 0.000058 0.000064 0.0000042 0.0000059 0.000030 0.000022 1994 12 18 49704 -0.155285 0.379907 0.4377120 0.0022899 0.000016 -0.000248 0.000057 0.000063 0.0000043 0.0000060 0.000030 0.000021 1994 12 19 49705 -0.155999 0.382460 0.4353743 0.0023983 0.000015 -0.000271 0.000055 0.000061 0.0000043 0.0000061 0.000029 0.000020 1994 12 20 49706 -0.157072 0.385355 0.4329009 0.0025511 0.000015 -0.000294 0.000053 0.000059 0.0000044 0.0000062 0.000028 0.000019 1994 12 21 49707 -0.158047 0.387527 0.4302598 0.0027127 0.000122 -0.000289 0.000051 0.000058 0.0000045 0.0000063 0.000028 0.000018 1994 12 22 49708 -0.158348 0.389808 0.4274686 0.0028363 0.000143 -0.000277 0.000049 0.000056 0.0000046 0.0000064 0.000027 0.000017 1994 12 23 49709 -0.158676 0.391897 0.4245884 0.0029195 0.000129 -0.000265 0.000047 0.000054 0.0000047 0.0000066 0.000026 0.000016 1994 12 24 49710 -0.159184 0.394072 0.4216393 0.0029985 0.000115 -0.000253 0.000045 0.000053 0.0000047 0.0000066 0.000025 0.000015 1994 12 25 49711 -0.159406 0.396563 0.4186079 0.0030624 0.000101 -0.000241 0.000044 0.000051 0.0000047 0.0000067 0.000025 0.000015 1994 12 26 49712 -0.158979 0.399409 0.4155345 0.0030737 0.000087 -0.000229 0.000042 0.000049 0.0000048 0.0000067 0.000024 0.000014 1994 12 27 49713 -0.158749 0.402480 0.4124802 0.0030194 0.000073 -0.000217 0.000040 0.000048 0.0000048 0.0000068 0.000023 0.000013 1994 12 28 49714 -0.158354 0.405971 0.4095106 0.0029065 0.000059 -0.000205 0.000039 0.000046 0.0000048 0.0000069 0.000023 0.000013 1994 12 29 49715 -0.158129 0.409212 0.4066726 0.0027688 0.000046 -0.000196 0.000037 0.000044 0.0000049 0.0000069 0.000022 0.000012 1994 12 30 49716 -0.157216 0.412221 0.4039655 0.0026670 0.000037 -0.000312 0.000038 0.000045 0.0000050 0.0000070 0.000023 0.000013 1994 12 31 49717 -0.155665 0.415183 0.4013193 0.0026338 0.000023 -0.000341 0.000040 0.000046 0.0000050 0.0000070 0.000023 0.000013 1995 1 1 49718 -0.153365 0.418539 0.3986932 0.0026603 0.000003 -0.000306 0.000076 0.000064 0.0000050 0.0000071 0.000028 0.000026 1995 1 2 49719 -0.151121 0.421237 0.3959872 0.0027667 -0.000016 -0.000271 0.000079 0.000067 0.0000050 0.0000071 0.000028 0.000026 1995 1 3 49720 -0.148595 0.424026 0.3931530 0.0029034 -0.000035 -0.000236 0.000083 0.000070 0.0000050 0.0000071 0.000029 0.000027 1995 1 4 49721 -0.146409 0.426733 0.3901884 0.0030113 -0.000055 -0.000201 0.000086 0.000073 0.0000050 0.0000071 0.000029 0.000028 1995 1 5 49722 -0.144593 0.429318 0.3871481 0.0030421 -0.000051 -0.000182 0.000090 0.000075 0.0000050 0.0000071 0.000030 0.000029 1995 1 6 49723 -0.143353 0.431256 0.3841237 0.0029811 -0.000040 -0.000167 0.000094 0.000078 0.0000050 0.0000071 0.000030 0.000030 1995 1 7 49724 -0.141698 0.433336 0.3812015 0.0028513 -0.000029 -0.000152 0.000097 0.000081 0.0000050 0.0000071 0.000031 0.000031 1995 1 8 49725 -0.140123 0.435306 0.3784310 0.0026889 -0.000018 -0.000137 0.000101 0.000083 0.0000050 0.0000071 0.000032 0.000032 1995 1 9 49726 -0.138992 0.437173 0.3758292 0.0025214 -0.000007 -0.000123 0.000104 0.000086 0.0000050 0.0000070 0.000032 0.000033 1995 1 10 49727 -0.137498 0.438929 0.3733901 0.0023686 0.000004 -0.000108 0.000108 0.000088 0.0000050 0.0000070 0.000033 0.000034 1995 1 11 49728 -0.135550 0.441758 0.3710900 0.0022483 -0.000039 -0.000156 0.000111 0.000090 0.0000049 0.0000070 0.000033 0.000035 1995 1 12 49729 -0.133825 0.444521 0.3688870 0.0021524 -0.000035 -0.000165 0.000115 0.000093 0.0000049 0.0000070 0.000034 0.000036 1995 1 13 49730 -0.132344 0.446944 0.3667743 0.0020754 -0.000015 -0.000158 0.000118 0.000095 0.0000049 0.0000070 0.000034 0.000037 1995 1 14 49731 -0.130718 0.449171 0.3647225 0.0020661 0.000005 -0.000152 0.000122 0.000097 0.0000049 0.0000070 0.000035 0.000038 1995 1 15 49732 -0.129586 0.451710 0.3626271 0.0021257 0.000025 -0.000145 0.000125 0.000099 0.0000049 0.0000069 0.000035 0.000038 1995 1 16 49733 -0.129029 0.454317 0.3604560 0.0021944 0.000046 -0.000139 0.000128 0.000101 0.0000048 0.0000068 0.000036 0.000039 1995 1 17 49734 -0.128590 0.456803 0.3582247 0.0022633 0.000066 -0.000133 0.000131 0.000103 0.0000048 0.0000067 0.000036 0.000040 1995 1 18 49735 -0.128171 0.458761 0.3559201 0.0023820 0.000086 -0.000126 0.000134 0.000104 0.0000047 0.0000066 0.000037 0.000041 1995 1 19 49736 -0.127753 0.461043 0.3534592 0.0025550 -0.000267 -0.000337 0.000136 0.000104 0.0000046 0.0000065 0.000037 0.000042 1995 1 20 49737 -0.126540 0.462650 0.3508187 0.0027070 -0.000394 -0.000416 0.000138 0.000105 0.0000045 0.0000064 0.000037 0.000042 1995 1 21 49738 -0.125198 0.464137 0.3480628 0.0027878 -0.000319 -0.000377 0.000140 0.000105 0.0000044 0.0000062 0.000038 0.000042 1995 1 22 49739 -0.124056 0.465810 0.3452652 0.0028236 -0.000243 -0.000337 0.000141 0.000105 0.0000043 0.0000060 0.000038 0.000042 1995 1 23 49740 -0.122556 0.467597 0.3424363 0.0028331 -0.000167 -0.000298 0.000142 0.000104 0.0000041 0.0000059 0.000038 0.000042 1995 1 24 49741 -0.120883 0.470038 0.3396132 0.0028036 -0.000091 -0.000259 0.000142 0.000103 0.0000040 0.0000058 0.000038 0.000042 1995 1 25 49742 -0.119277 0.472493 0.3368340 0.0027440 -0.000057 -0.000178 0.000144 0.000103 0.0000040 0.0000058 0.000038 0.000042 1995 1 26 49743 -0.117543 0.475421 0.3341198 0.0026851 -0.000066 -0.000171 0.000146 0.000105 0.0000041 0.0000059 0.000038 0.000043 1995 1 27 49744 -0.116884 0.477506 0.3314487 0.0026621 -0.000086 -0.000191 0.000148 0.000105 0.0000043 0.0000060 0.000039 0.000043 1995 1 28 49745 -0.116121 0.479739 0.3287740 0.0026795 -0.000127 -0.000252 0.000149 0.000106 0.0000043 0.0000062 0.000039 0.000043 1995 1 29 49746 -0.115409 0.481543 0.3260677 0.0027213 -0.000169 -0.000316 0.000151 0.000106 0.0000044 0.0000063 0.000039 0.000043 1995 1 30 49747 -0.115161 0.483337 0.3233169 0.0027702 -0.000211 -0.000380 0.000151 0.000106 0.0000045 0.0000064 0.000039 0.000043 1995 1 31 49748 -0.115387 0.484694 0.3205258 0.0028272 -0.000253 -0.000444 0.000152 0.000105 0.0000047 0.0000066 0.000039 0.000043 1995 2 1 49749 -0.115616 0.486531 0.3176746 0.0029688 -0.000131 -0.000171 0.000151 0.000104 0.0000047 0.0000067 0.000039 0.000042 1995 2 2 49750 -0.116002 0.487779 0.3146086 0.0029380 -0.000072 -0.000030 0.000151 0.000103 0.0000048 0.0000068 0.000039 0.000042 1995 2 3 49751 -0.115899 0.489448 0.3118196 0.0027480 -0.000105 -0.000070 0.000150 0.000102 0.0000049 0.0000069 0.000039 0.000041 1995 2 4 49752 -0.115356 0.490701 0.3091283 0.0027427 -0.000127 -0.000124 0.000151 0.000102 0.0000049 0.0000069 0.000039 0.000040 1995 2 5 49753 -0.114336 0.491933 0.3063432 0.0027105 -0.000118 -0.000145 0.000155 0.000105 0.0000049 0.0000069 0.000039 0.000041 1995 2 6 49754 -0.112679 0.493145 0.3037107 0.0025738 -0.000109 -0.000165 0.000158 0.000107 0.0000049 0.0000069 0.000039 0.000041 1995 2 7 49755 -0.109997 0.494780 0.3011947 0.0024678 -0.000099 -0.000186 0.000161 0.000110 0.0000048 0.0000068 0.000039 0.000041 1995 2 8 49756 -0.106706 0.497196 0.2987700 0.0023420 -0.000090 -0.000206 0.000164 0.000111 0.0000048 0.0000068 0.000040 0.000042 1995 2 9 49757 -0.103141 0.499684 0.2965012 0.0022279 -0.000130 -0.000208 0.000167 0.000114 0.0000048 0.0000068 0.000040 0.000043 1995 2 10 49758 -0.100029 0.502246 0.2943006 0.0022000 -0.000187 -0.000205 0.000171 0.000117 0.0000049 0.0000069 0.000041 0.000043 1995 2 11 49759 -0.097790 0.504374 0.2920853 0.0021913 -0.000244 -0.000201 0.000175 0.000121 0.0000049 0.0000069 0.000041 0.000045 1995 2 12 49760 -0.096292 0.506474 0.2899020 0.0021860 -0.000300 -0.000197 0.000178 0.000123 0.0000049 0.0000070 0.000042 0.000046 1995 2 13 49761 -0.095166 0.508154 0.2876987 0.0022466 -0.000357 -0.000193 0.000182 0.000126 0.0000049 0.0000070 0.000042 0.000047 1995 2 14 49762 -0.094354 0.509537 0.2853973 0.0023824 -0.000414 -0.000189 0.000185 0.000128 0.0000050 0.0000070 0.000043 0.000048 1995 2 15 49763 -0.093197 0.510549 0.2829285 0.0025637 -0.000166 -0.000088 0.000187 0.000130 0.0000050 0.0000070 0.000043 0.000049 1995 2 16 49764 -0.091417 0.511828 0.2802740 0.0027380 -0.000016 -0.000169 0.000190 0.000132 0.0000049 0.0000070 0.000043 0.000049 1995 2 17 49765 -0.089287 0.513498 0.2774680 0.0028570 -0.000005 -0.000201 0.000197 0.000136 0.0000049 0.0000069 0.000044 0.000050 1995 2 18 49766 -0.087102 0.515078 0.2745840 0.0028899 -0.000043 -0.000178 0.000199 0.000138 0.0000049 0.0000069 0.000044 0.000051 1995 2 19 49767 -0.085388 0.516649 0.2717140 0.0028323 -0.000081 -0.000154 0.000201 0.000141 0.0000048 0.0000068 0.000044 0.000051 1995 2 20 49768 -0.083829 0.517983 0.2689388 0.0027103 -0.000118 -0.000130 0.000202 0.000142 0.0000048 0.0000067 0.000044 0.000052 1995 2 21 49769 -0.082327 0.519025 0.2663011 0.0025707 -0.000156 -0.000106 0.000203 0.000144 0.0000047 0.0000066 0.000045 0.000052 1995 2 22 49770 -0.080894 0.520281 0.2637927 0.0024637 -0.000193 -0.000082 0.000202 0.000144 0.0000046 0.0000066 0.000045 0.000053 1995 2 23 49771 -0.079261 0.521351 0.2613595 0.0024301 -0.000436 -0.000167 0.000203 0.000144 0.0000046 0.0000065 0.000045 0.000053 1995 2 24 49772 -0.077206 0.522759 0.2589132 0.0024818 -0.000747 -0.000287 0.000203 0.000145 0.0000045 0.0000064 0.000045 0.000053 1995 2 25 49773 -0.074376 0.524532 0.2563757 0.0025840 -0.000663 -0.000218 0.000202 0.000145 0.0000045 0.0000063 0.000045 0.000053 1995 2 26 49774 -0.070920 0.526700 0.2537291 0.0026872 -0.000541 -0.000131 0.000202 0.000145 0.0000044 0.0000063 0.000045 0.000053 1995 2 27 49775 -0.067224 0.528992 0.2509937 0.0027674 -0.000419 -0.000044 0.000201 0.000144 0.0000044 0.0000062 0.000045 0.000052 1995 2 28 49776 -0.063843 0.530440 0.2481981 0.0028346 -0.000297 0.000043 0.000199 0.000143 0.0000043 0.0000061 0.000044 0.000052 1995 3 1 49777 -0.060093 0.531976 0.2453390 0.0029235 -0.000175 0.000130 0.000198 0.000142 0.0000042 0.0000060 0.000044 0.000052 1995 3 2 49778 -0.056652 0.533497 0.2423715 0.0030227 -0.000177 0.000070 0.000196 0.000140 0.0000041 0.0000058 0.000044 0.000051 1995 3 3 49779 -0.053650 0.534863 0.2393132 0.0030765 -0.000220 -0.000039 0.000193 0.000137 0.0000040 0.0000057 0.000043 0.000050 1995 3 4 49780 -0.050349 0.536159 0.2362324 0.0030584 -0.000160 -0.000048 0.000191 0.000135 0.0000039 0.0000055 0.000043 0.000049 1995 3 5 49781 -0.047142 0.537241 0.2332031 0.0029739 -0.000096 -0.000053 0.000188 0.000133 0.0000038 0.0000054 0.000042 0.000047 1995 3 6 49782 -0.043498 0.538312 0.2302854 0.0028468 -0.000031 -0.000058 0.000185 0.000130 0.0000037 0.0000053 0.000042 0.000046 1995 3 7 49783 -0.040116 0.539948 0.2275059 0.0027169 0.000033 -0.000063 0.000181 0.000127 0.0000036 0.0000052 0.000041 0.000045 1995 3 8 49784 -0.037121 0.541268 0.2248443 0.0026331 -0.000056 -0.000001 0.000180 0.000126 0.0000036 0.0000052 0.000041 0.000045 1995 3 9 49785 -0.034397 0.542502 0.2222282 0.0026277 -0.000065 0.000022 0.000181 0.000127 0.0000037 0.0000052 0.000041 0.000045 1995 3 10 49786 -0.032078 0.543454 0.2195743 0.0026791 -0.000044 0.000031 0.000182 0.000129 0.0000038 0.0000053 0.000041 0.000046 1995 3 11 49787 -0.029776 0.544591 0.2168542 0.0027431 -0.000022 0.000040 0.000183 0.000131 0.0000039 0.0000055 0.000041 0.000046 1995 3 12 49788 -0.027640 0.545261 0.2140731 0.0028193 -0.000001 0.000048 0.000184 0.000132 0.0000039 0.0000056 0.000042 0.000047 1995 3 13 49789 -0.026251 0.545450 0.2112032 0.0029014 0.000021 0.000057 0.000185 0.000133 0.0000040 0.0000057 0.000042 0.000047 1995 3 14 49790 -0.024321 0.545399 0.2082621 0.0029770 0.000042 0.000066 0.000185 0.000133 0.0000041 0.0000058 0.000042 0.000048 1995 3 15 49791 -0.022699 0.545777 0.2052481 0.0030970 -0.000003 0.000004 0.000184 0.000133 0.0000041 0.0000058 0.000042 0.000048 1995 3 16 49792 -0.019812 0.546182 0.2020772 0.0032330 -0.000018 -0.000005 0.000184 0.000132 0.0000042 0.0000059 0.000042 0.000048 1995 3 17 49793 -0.016982 0.547033 0.1988021 0.0032977 -0.000018 0.000010 0.000182 0.000132 0.0000042 0.0000059 0.000041 0.000047 1995 3 18 49794 -0.013928 0.547805 0.1955090 0.0032949 -0.000019 0.000024 0.000181 0.000130 0.0000042 0.0000059 0.000041 0.000047 1995 3 19 49795 -0.010972 0.548640 0.1922383 0.0032112 -0.000019 0.000038 0.000179 0.000129 0.0000042 0.0000059 0.000041 0.000046 1995 3 20 49796 -0.008569 0.549793 0.1891023 0.0030340 -0.000019 0.000052 0.000177 0.000127 0.0000041 0.0000059 0.000040 0.000046 1995 3 21 49797 -0.007079 0.550721 0.1861711 0.0028156 -0.000020 0.000066 0.000174 0.000125 0.0000041 0.0000058 0.000040 0.000045 1995 3 22 49798 -0.005019 0.551664 0.1834586 0.0026170 -0.000020 0.000080 0.000171 0.000122 0.0000041 0.0000058 0.000040 0.000045 1995 3 23 49799 -0.003467 0.552092 0.1809176 0.0024959 -0.000069 0.000057 0.000170 0.000121 0.0000041 0.0000058 0.000040 0.000045 1995 3 24 49800 -0.001333 0.552500 0.1784475 0.0024820 -0.000133 0.000020 0.000169 0.000122 0.0000041 0.0000058 0.000040 0.000046 1995 3 25 49801 0.001945 0.552804 0.1759393 0.0025556 -0.000141 -0.000020 0.000168 0.000122 0.0000042 0.0000059 0.000040 0.000047 1995 3 26 49802 0.006588 0.553004 0.1733291 0.0026663 -0.000107 -0.000063 0.000167 0.000122 0.0000042 0.0000060 0.000040 0.000049 1995 3 27 49803 0.011907 0.553863 0.1706072 0.0027698 -0.000073 -0.000106 0.000165 0.000121 0.0000042 0.0000060 0.000041 0.000050 1995 3 28 49804 0.017397 0.555380 0.1677979 0.0028437 -0.000039 -0.000149 0.000163 0.000120 0.0000043 0.0000060 0.000041 0.000051 1995 3 29 49805 0.021841 0.557050 0.1649347 0.0028995 -0.000135 0.000039 0.000161 0.000119 0.0000043 0.0000060 0.000041 0.000051 1995 3 30 49806 0.025743 0.558023 0.1620166 0.0029125 -0.000151 0.000071 0.000158 0.000118 0.0000043 0.0000060 0.000041 0.000051 1995 3 31 49807 0.029047 0.558522 0.1591254 0.0028525 -0.000136 0.000043 0.000155 0.000116 0.0000042 0.0000060 0.000040 0.000051 1995 4 1 49808 0.031757 0.558487 0.1563215 0.0027695 -0.000121 0.000016 0.000152 0.000114 0.0000042 0.0000060 0.000040 0.000051 1995 4 2 49809 0.034831 0.558237 0.1535896 0.0026873 -0.000106 -0.000011 0.000148 0.000112 0.0000042 0.0000059 0.000040 0.000051 1995 4 3 49810 0.038020 0.558201 0.1509445 0.0025923 -0.000091 -0.000038 0.000145 0.000109 0.0000042 0.0000059 0.000039 0.000051 1995 4 4 49811 0.041611 0.558190 0.1483986 0.0024975 -0.000076 -0.000065 0.000141 0.000106 0.0000041 0.0000058 0.000039 0.000051 1995 4 5 49812 0.044612 0.557948 0.1459402 0.0024369 -0.000037 -0.000036 0.000137 0.000104 0.0000041 0.0000058 0.000039 0.000050 1995 4 6 49813 0.047736 0.557348 0.1435126 0.0024242 -0.000076 -0.000064 0.000133 0.000101 0.0000041 0.0000057 0.000038 0.000050 1995 4 7 49814 0.051167 0.557324 0.1410775 0.0024756 -0.000142 -0.000111 0.000130 0.000098 0.0000040 0.0000057 0.000038 0.000050 1995 4 8 49815 0.054446 0.557724 0.1385470 0.0025754 -0.000208 -0.000158 0.000126 0.000096 0.0000040 0.0000056 0.000037 0.000049 1995 4 9 49816 0.057162 0.557834 0.1359143 0.0026339 -0.000274 -0.000205 0.000122 0.000093 0.0000039 0.0000056 0.000037 0.000049 1995 4 10 49817 0.059901 0.557868 0.1332703 0.0026957 -0.000341 -0.000252 0.000118 0.000090 0.0000039 0.0000055 0.000036 0.000049 1995 4 11 49818 0.062945 0.557946 0.1305189 0.0028514 -0.000407 -0.000299 0.000114 0.000087 0.0000038 0.0000054 0.000036 0.000048 1995 4 12 49819 0.065926 0.557800 0.1275704 0.0030379 -0.000159 -0.000065 0.000110 0.000084 0.0000038 0.0000053 0.000036 0.000048 1995 4 13 49820 0.068991 0.557544 0.1244554 0.0031418 0.000084 0.000147 0.000107 0.000082 0.0000037 0.0000053 0.000035 0.000047 1995 4 14 49821 0.071724 0.556905 0.1213085 0.0031587 0.000031 0.000018 0.000109 0.000083 0.0000037 0.0000053 0.000036 0.000048 1995 4 15 49822 0.075316 0.556297 0.1181646 0.0031291 -0.000018 -0.000044 0.000110 0.000084 0.0000037 0.0000053 0.000036 0.000048 1995 4 16 49823 0.078701 0.555992 0.1150728 0.0030425 -0.000064 -0.000059 0.000111 0.000085 0.0000037 0.0000052 0.000036 0.000049 1995 4 17 49824 0.082351 0.556014 0.1120894 0.0029231 -0.000110 -0.000073 0.000112 0.000085 0.0000037 0.0000052 0.000037 0.000049 1995 4 18 49825 0.085762 0.555978 0.1092203 0.0028078 -0.000156 -0.000088 0.000112 0.000086 0.0000037 0.0000052 0.000037 0.000049 1995 4 19 49826 0.088897 0.555612 0.1064555 0.0027035 -0.000202 -0.000102 0.000112 0.000085 0.0000036 0.0000051 0.000037 0.000050 1995 4 20 49827 0.091548 0.555722 0.1037920 0.0026546 -0.000098 -0.000090 0.000112 0.000085 0.0000036 0.0000051 0.000037 0.000050 1995 4 21 49828 0.094539 0.555510 0.1011305 0.0026779 -0.000011 -0.000066 0.000111 0.000084 0.0000036 0.0000051 0.000037 0.000050 1995 4 22 49829 0.098016 0.554918 0.0984301 0.0027286 -0.000053 -0.000035 0.000111 0.000084 0.0000036 0.0000052 0.000038 0.000050 1995 4 23 49830 0.101621 0.554104 0.0956759 0.0027990 -0.000114 0.000007 0.000111 0.000085 0.0000037 0.0000053 0.000038 0.000050 1995 4 24 49831 0.105269 0.553075 0.0928404 0.0028723 -0.000174 0.000048 0.000111 0.000086 0.0000038 0.0000055 0.000038 0.000051 1995 4 25 49832 0.109377 0.552326 0.0899432 0.0029164 -0.000235 0.000090 0.000111 0.000087 0.0000040 0.0000056 0.000039 0.000051 1995 4 26 49833 0.113576 0.551337 0.0870210 0.0029296 -0.000054 0.000086 0.000112 0.000087 0.0000041 0.0000058 0.000039 0.000052 1995 4 27 49834 0.117870 0.550165 0.0840969 0.0028803 -0.000038 0.000098 0.000113 0.000088 0.0000042 0.0000059 0.000039 0.000053 1995 4 28 49835 0.121933 0.548906 0.0812704 0.0027524 -0.000076 0.000115 0.000114 0.000089 0.0000043 0.0000061 0.000040 0.000053 1995 4 29 49836 0.126007 0.547510 0.0785967 0.0026205 -0.000115 0.000132 0.000115 0.000090 0.0000044 0.0000062 0.000040 0.000054 1995 4 30 49837 0.129713 0.546121 0.0760280 0.0024760 -0.000154 0.000149 0.000116 0.000091 0.0000045 0.0000064 0.000041 0.000055 1995 5 1 49838 0.133209 0.544489 0.0736386 0.0023411 -0.000192 0.000166 0.000117 0.000092 0.0000046 0.0000066 0.000041 0.000055 1995 5 2 49839 0.137038 0.542802 0.0713368 0.0023090 -0.000231 0.000183 0.000118 0.000093 0.0000048 0.0000067 0.000042 0.000056 1995 5 3 49840 0.140445 0.541598 0.0690094 0.0023452 -0.000142 -0.000084 0.000120 0.000095 0.0000049 0.0000069 0.000042 0.000057 1995 5 4 49841 0.143879 0.540110 0.0666339 0.0023764 -0.000108 -0.000144 0.000121 0.000096 0.0000050 0.0000071 0.000042 0.000058 1995 5 5 49842 0.147443 0.538772 0.0642434 0.0024322 -0.000094 -0.000130 0.000122 0.000098 0.0000051 0.0000073 0.000043 0.000059 1995 5 6 49843 0.150975 0.536880 0.0617573 0.0025871 -0.000080 -0.000117 0.000124 0.000099 0.0000053 0.0000074 0.000043 0.000060 1995 5 7 49844 0.154874 0.535278 0.0590597 0.0026489 -0.000067 -0.000104 0.000126 0.000101 0.0000054 0.0000076 0.000043 0.000061 1995 5 8 49845 0.159082 0.533761 0.0564544 0.0026298 -0.000053 -0.000090 0.000129 0.000104 0.0000054 0.0000077 0.000044 0.000062 1995 5 9 49846 0.163498 0.532440 0.0538004 0.0027628 -0.000039 -0.000077 0.000132 0.000106 0.0000055 0.0000078 0.000044 0.000063 1995 5 10 49847 0.167832 0.530964 0.0509355 0.0029396 -0.000025 -0.000064 0.000136 0.000109 0.0000055 0.0000078 0.000045 0.000064 1995 5 11 49848 0.172105 0.530169 0.0479354 0.0030355 -0.000032 -0.000093 0.000140 0.000113 0.0000055 0.0000079 0.000045 0.000065 1995 5 12 49849 0.174753 0.527705 0.0448849 0.0030402 -0.000051 -0.000086 0.000144 0.000116 0.0000056 0.0000079 0.000045 0.000065 1995 5 13 49850 0.177656 0.526062 0.0418773 0.0029571 -0.000073 -0.000053 0.000148 0.000119 0.0000056 0.0000079 0.000045 0.000064 1995 5 14 49851 0.180859 0.524288 0.0389869 0.0028436 -0.000095 -0.000020 0.000152 0.000122 0.0000056 0.0000079 0.000044 0.000064 1995 5 15 49852 0.184211 0.522903 0.0361929 0.0027455 -0.000118 0.000012 0.000155 0.000124 0.0000056 0.0000079 0.000044 0.000063 1995 5 16 49853 0.186790 0.521179 0.0334836 0.0026660 -0.000140 0.000045 0.000158 0.000126 0.0000055 0.0000078 0.000044 0.000062 1995 5 17 49854 0.189470 0.519742 0.0308392 0.0026121 -0.000162 0.000078 0.000161 0.000128 0.0000055 0.0000078 0.000044 0.000062 1995 5 18 49855 0.191872 0.518154 0.0282390 0.0025703 -0.000133 0.000103 0.000163 0.000130 0.0000055 0.0000078 0.000044 0.000061 1995 5 19 49856 0.193867 0.516296 0.0256883 0.0025429 -0.000087 0.000125 0.000166 0.000131 0.0000055 0.0000078 0.000043 0.000061 1995 5 20 49857 0.195561 0.514152 0.0231557 0.0025598 -0.000041 0.000147 0.000168 0.000133 0.0000055 0.0000079 0.000043 0.000060 1995 5 21 49858 0.197005 0.511339 0.0205802 0.0025683 0.000005 0.000169 0.000170 0.000134 0.0000056 0.0000078 0.000043 0.000060 1995 5 22 49859 0.198859 0.508632 0.0180337 0.0025269 0.000051 0.000191 0.000171 0.000135 0.0000056 0.0000079 0.000043 0.000060 1995 5 23 49860 0.201364 0.506386 0.0155400 0.0024533 0.000097 0.000213 0.000172 0.000135 0.0000055 0.0000078 0.000042 0.000059 1995 5 24 49861 0.203538 0.504092 0.0131379 0.0023258 0.000143 0.000235 0.000172 0.000135 0.0000055 0.0000078 0.000042 0.000059 1995 5 25 49862 0.205574 0.501770 0.0108963 0.0022333 -0.000159 0.000128 0.000172 0.000135 0.0000055 0.0000078 0.000042 0.000058 1995 5 26 49863 0.207478 0.499542 0.0086757 0.0021823 -0.000271 0.000076 0.000171 0.000134 0.0000055 0.0000077 0.000041 0.000057 1995 5 27 49864 0.209413 0.496985 0.0065314 0.0020503 -0.000228 0.000074 0.000170 0.000133 0.0000054 0.0000076 0.000041 0.000056 1995 5 28 49865 0.211508 0.494419 0.0045699 0.0019339 -0.000186 0.000072 0.000169 0.000132 0.0000053 0.0000075 0.000040 0.000055 1995 5 29 49866 0.213380 0.491889 0.0026544 0.0019019 -0.000143 0.000070 0.000167 0.000131 0.0000052 0.0000074 0.000039 0.000053 1995 5 30 49867 0.215485 0.489047 0.0007547 0.0018893 -0.000100 0.000068 0.000165 0.000129 0.0000052 0.0000073 0.000039 0.000052 1995 5 31 49868 0.217387 0.486172 -0.0011365 0.0018866 -0.000058 0.000066 0.000163 0.000127 0.0000051 0.0000072 0.000038 0.000052 1995 6 1 49869 0.219630 0.483139 -0.0030311 0.0019081 0.000014 0.000086 0.000160 0.000125 0.0000051 0.0000072 0.000038 0.000051 1995 6 2 49870 0.221990 0.480191 -0.0049648 0.0020040 0.000010 0.000080 0.000159 0.000125 0.0000051 0.0000072 0.000038 0.000051 1995 6 3 49871 0.224739 0.477209 -0.0070494 0.0021662 -0.000036 0.000057 0.000158 0.000124 0.0000051 0.0000073 0.000038 0.000051 1995 6 4 49872 0.227974 0.473984 -0.0093035 0.0022701 -0.000082 0.000033 0.000156 0.000123 0.0000052 0.0000073 0.000038 0.000051 1995 6 5 49873 0.231374 0.470538 -0.0115904 0.0023067 -0.000128 0.000010 0.000154 0.000122 0.0000052 0.0000073 0.000038 0.000051 1995 6 6 49874 0.234904 0.467343 -0.0139120 0.0023566 -0.000174 -0.000014 0.000151 0.000121 0.0000052 0.0000073 0.000038 0.000051 1995 6 7 49875 0.237643 0.464525 -0.0162934 0.0024208 -0.000221 -0.000037 0.000148 0.000119 0.0000052 0.0000073 0.000038 0.000051 1995 6 8 49876 0.240569 0.461772 -0.0187386 0.0024561 -0.000111 -0.000022 0.000145 0.000117 0.0000052 0.0000073 0.000038 0.000051 1995 6 9 49877 0.243235 0.458964 -0.0211880 0.0024211 -0.000094 0.000145 0.000144 0.000116 0.0000052 0.0000074 0.000038 0.000052 1995 6 10 49878 0.245943 0.456143 -0.0235649 0.0023279 -0.000095 0.000208 0.000144 0.000117 0.0000053 0.0000074 0.000039 0.000054 1995 6 11 49879 0.248600 0.453241 -0.0258354 0.0022148 -0.000057 0.000148 0.000144 0.000117 0.0000053 0.0000075 0.000040 0.000055 1995 6 12 49880 0.250455 0.450487 -0.0279989 0.0021005 -0.000018 0.000089 0.000143 0.000116 0.0000053 0.0000075 0.000041 0.000056 1995 6 13 49881 0.252241 0.447299 -0.0300533 0.0020225 0.000021 0.000029 0.000142 0.000116 0.0000053 0.0000076 0.000041 0.000058 1995 6 14 49882 0.254029 0.444117 -0.0320663 0.0020460 0.000059 -0.000030 0.000140 0.000115 0.0000054 0.0000076 0.000042 0.000059 1995 6 15 49883 0.256238 0.440648 -0.0341627 0.0021208 -0.000139 -0.000191 0.000138 0.000113 0.0000054 0.0000076 0.000043 0.000061 1995 6 16 49884 0.258423 0.437204 -0.0363121 0.0021657 -0.000191 -0.000212 0.000136 0.000112 0.0000054 0.0000076 0.000043 0.000061 1995 6 17 49885 0.260761 0.434133 -0.0384842 0.0022022 -0.000128 -0.000146 0.000133 0.000110 0.0000054 0.0000076 0.000044 0.000062 1995 6 18 49886 0.263180 0.431091 -0.0406982 0.0022379 -0.000065 -0.000080 0.000131 0.000108 0.0000053 0.0000075 0.000044 0.000063 1995 6 19 49887 0.265486 0.427877 -0.0429412 0.0022331 -0.000002 -0.000014 0.000128 0.000105 0.0000053 0.0000074 0.000045 0.000063 1995 6 20 49888 0.267551 0.424650 -0.0451504 0.0021656 0.000060 0.000052 0.000125 0.000103 0.0000052 0.0000073 0.000045 0.000064 1995 6 21 49889 0.269257 0.420758 -0.0472641 0.0020553 0.000095 -0.000033 0.000122 0.000101 0.0000051 0.0000072 0.000045 0.000064 1995 6 22 49890 0.271012 0.417189 -0.0492573 0.0019135 0.000115 0.000006 0.000120 0.000099 0.0000050 0.0000071 0.000046 0.000064 1995 6 23 49891 0.272197 0.413605 -0.0510910 0.0017236 0.000130 0.000086 0.000118 0.000098 0.0000049 0.0000070 0.000046 0.000063 1995 6 24 49892 0.273175 0.410150 -0.0527083 0.0015065 0.000146 0.000166 0.000116 0.000096 0.0000049 0.0000069 0.000046 0.000063 1995 6 25 49893 0.273684 0.406546 -0.0541121 0.0013323 0.000162 0.000246 0.000115 0.000095 0.0000049 0.0000069 0.000046 0.000063 1995 6 26 49894 0.274291 0.403265 -0.0553841 0.0012129 0.000177 0.000326 0.000113 0.000094 0.0000049 0.0000070 0.000046 0.000062 1995 6 27 49895 0.275066 0.399783 -0.0565509 0.0011283 0.000193 0.000406 0.000112 0.000093 0.0000050 0.0000070 0.000046 0.000062 1995 6 28 49896 0.275966 0.395959 -0.0576538 0.0011153 -0.000004 0.000320 0.000111 0.000092 0.0000050 0.0000070 0.000045 0.000061 1995 6 29 49897 0.277210 0.392058 -0.0587940 0.0011966 0.000105 0.000146 0.000111 0.000091 0.0000050 0.0000071 0.000045 0.000060 1995 6 30 49898 0.278625 0.388413 -0.0600581 0.0012965 0.000159 0.000091 0.000110 0.000091 0.0000051 0.0000072 0.000045 0.000060 1995 7 1 49899 0.280104 0.384568 -0.0613950 0.0013821 0.000131 0.000108 0.000109 0.000091 0.0000052 0.0000074 0.000046 0.000061 1995 7 2 49900 0.281349 0.380523 -0.0628251 0.0015403 0.000102 0.000124 0.000109 0.000091 0.0000053 0.0000075 0.000047 0.000062 1995 7 3 49901 0.282068 0.376601 -0.0644717 0.0017198 0.000074 0.000141 0.000109 0.000091 0.0000055 0.0000077 0.000048 0.000063 1995 7 4 49902 0.282634 0.372159 -0.0662549 0.0017959 0.000045 0.000158 0.000109 0.000091 0.0000056 0.0000079 0.000049 0.000065 1995 7 5 49903 0.283653 0.367895 -0.0680499 0.0017640 0.000017 0.000174 0.000109 0.000091 0.0000057 0.0000081 0.000050 0.000066 1995 7 6 49904 0.284994 0.363851 -0.0697681 0.0017118 -0.000012 0.000191 0.000109 0.000091 0.0000058 0.0000082 0.000051 0.000067 1995 7 7 49905 0.285866 0.360061 -0.0714603 0.0016720 -0.000118 0.000115 0.000110 0.000092 0.0000059 0.0000084 0.000052 0.000069 1995 7 8 49906 0.286059 0.356002 -0.0731036 0.0015833 -0.000251 0.000007 0.000112 0.000093 0.0000061 0.0000086 0.000053 0.000070 1995 7 9 49907 0.286545 0.351943 -0.0746268 0.0014706 -0.000383 -0.000101 0.000113 0.000095 0.0000062 0.0000087 0.000054 0.000071 1995 7 10 49908 0.286659 0.348040 -0.0760555 0.0014001 -0.000515 -0.000208 0.000116 0.000097 0.0000063 0.0000089 0.000055 0.000073 1995 7 11 49909 0.287089 0.344076 -0.0774463 0.0013984 -0.000648 -0.000316 0.000119 0.000099 0.0000064 0.0000090 0.000056 0.000074 1995 7 12 49910 0.287630 0.340622 -0.0788730 0.0014671 -0.000196 0.000003 0.000122 0.000102 0.0000065 0.0000092 0.000056 0.000074 1995 7 13 49911 0.287584 0.337056 -0.0803933 0.0015652 -0.000043 -0.000002 0.000125 0.000105 0.0000066 0.0000093 0.000057 0.000074 1995 7 14 49912 0.287676 0.333431 -0.0820020 0.0016675 -0.000035 -0.000043 0.000128 0.000107 0.0000066 0.0000094 0.000057 0.000074 1995 7 15 49913 0.287381 0.330113 -0.0837130 0.0017582 -0.000039 -0.000042 0.000130 0.000109 0.0000067 0.0000095 0.000057 0.000073 1995 7 16 49914 0.287900 0.326207 -0.0854960 0.0017706 -0.000043 -0.000041 0.000133 0.000112 0.0000068 0.0000096 0.000057 0.000073 1995 7 17 49915 0.288107 0.322433 -0.0872333 0.0016950 0.000029 0.000060 0.000136 0.000114 0.0000068 0.0000097 0.000058 0.000073 1995 7 18 49916 0.288068 0.318622 -0.0888722 0.0015881 0.000117 0.000181 0.000138 0.000116 0.0000069 0.0000098 0.000058 0.000074 1995 7 19 49917 0.287833 0.314809 -0.0904032 0.0014710 0.000049 0.000029 0.000141 0.000118 0.0000070 0.0000099 0.000059 0.000074 1995 7 20 49918 0.287535 0.311083 -0.0918136 0.0013209 0.000025 0.000010 0.000143 0.000120 0.0000070 0.0000099 0.000059 0.000074 1995 7 21 49919 0.287545 0.307100 -0.0930480 0.0011349 0.000017 0.000035 0.000145 0.000122 0.0000071 0.0000100 0.000059 0.000073 1995 7 22 49920 0.287513 0.303260 -0.0940897 0.0009874 0.000008 0.000061 0.000148 0.000123 0.0000071 0.0000100 0.000059 0.000073 1995 7 23 49921 0.287037 0.299333 -0.0950328 0.0008936 -0.000001 0.000086 0.000149 0.000125 0.0000070 0.0000099 0.000059 0.000073 1995 7 24 49922 0.286339 0.295191 -0.0958895 0.0008225 -0.000010 0.000112 0.000151 0.000126 0.0000070 0.0000099 0.000060 0.000072 1995 7 25 49923 0.286019 0.291214 -0.0966916 0.0007995 -0.000018 0.000137 0.000153 0.000127 0.0000069 0.0000098 0.000060 0.000072 1995 7 26 49924 0.285408 0.287562 -0.0975017 0.0008625 -0.000038 -0.000042 0.000154 0.000128 0.0000069 0.0000098 0.000061 0.000073 1995 7 27 49925 0.284716 0.283685 -0.0984283 0.0009319 -0.000007 -0.000033 0.000156 0.000129 0.0000070 0.0000099 0.000061 0.000074 1995 7 28 49926 0.283779 0.279702 -0.0993747 0.0009357 0.000041 0.000040 0.000157 0.000131 0.0000070 0.0000099 0.000062 0.000075 1995 7 29 49927 0.282905 0.275992 -0.1003048 0.0010448 0.000089 0.000113 0.000158 0.000132 0.0000070 0.0000099 0.000063 0.000077 1995 7 30 49928 0.281429 0.272466 -0.1014629 0.0012153 0.000137 0.000186 0.000159 0.000132 0.0000070 0.0000099 0.000063 0.000078 1995 7 31 49929 0.280296 0.268454 -0.1027263 0.0013147 0.000185 0.000259 0.000160 0.000133 0.0000069 0.0000098 0.000064 0.000079 1995 8 1 49930 0.279546 0.264618 -0.1040775 0.0014092 0.000232 0.000332 0.000161 0.000134 0.0000069 0.0000097 0.000065 0.000080 1995 8 2 49931 0.278902 0.260652 -0.1055280 0.0014751 -0.000024 0.000118 0.000161 0.000134 0.0000068 0.0000097 0.000065 0.000080 1995 8 3 49932 0.278250 0.257070 -0.1070137 0.0014407 -0.000123 0.000080 0.000162 0.000134 0.0000067 0.0000095 0.000065 0.000080 1995 8 4 49933 0.277707 0.252731 -0.1084017 0.0013277 -0.000149 0.000121 0.000162 0.000134 0.0000067 0.0000094 0.000065 0.000080 1995 8 5 49934 0.276659 0.248808 -0.1096690 0.0012878 -0.000175 0.000162 0.000162 0.000134 0.0000065 0.0000092 0.000065 0.000080 1995 8 6 49935 0.275963 0.244769 -0.1109854 0.0013184 -0.000200 0.000204 0.000162 0.000134 0.0000064 0.0000090 0.000065 0.000080 1995 8 7 49936 0.275187 0.241119 -0.1123212 0.0013385 -0.000226 0.000245 0.000162 0.000133 0.0000062 0.0000088 0.000065 0.000080 1995 8 8 49937 0.273984 0.237483 -0.1136815 0.0013817 -0.000251 0.000286 0.000162 0.000133 0.0000061 0.0000086 0.000066 0.000080 1995 8 9 49938 0.272511 0.233973 -0.1151014 0.0014694 0.000071 0.000161 0.000162 0.000132 0.0000059 0.0000084 0.000065 0.000079 1995 8 10 49939 0.270481 0.230622 -0.1166276 0.0016507 0.000044 0.000170 0.000162 0.000132 0.0000058 0.0000081 0.000065 0.000078 1995 8 11 49940 0.268949 0.226850 -0.1183964 0.0018141 -0.000002 0.000176 0.000162 0.000131 0.0000056 0.0000079 0.000064 0.000077 1995 8 12 49941 0.267751 0.223170 -0.1202370 0.0018280 0.000003 0.000156 0.000162 0.000130 0.0000054 0.0000076 0.000064 0.000075 1995 8 13 49942 0.266264 0.219534 -0.1220283 0.0017550 0.000007 0.000136 0.000161 0.000130 0.0000052 0.0000074 0.000063 0.000074 1995 8 14 49943 0.264722 0.216141 -0.1237261 0.0016553 0.000011 0.000117 0.000161 0.000129 0.0000051 0.0000072 0.000063 0.000073 1995 8 15 49944 0.263001 0.212967 -0.1253262 0.0015644 0.000016 0.000097 0.000162 0.000128 0.0000049 0.0000069 0.000062 0.000071 1995 8 16 49945 0.260230 0.209519 -0.1268507 0.0014955 0.000020 0.000078 0.000161 0.000127 0.0000048 0.0000067 0.000061 0.000070 1995 8 17 49946 0.257521 0.206416 -0.1283192 0.0014111 -0.000013 0.000107 0.000161 0.000126 0.0000046 0.0000066 0.000061 0.000069 1995 8 18 49947 0.255255 0.203240 -0.1296786 0.0013304 -0.000017 0.000109 0.000161 0.000126 0.0000045 0.0000064 0.000060 0.000068 1995 8 19 49948 0.253249 0.200288 -0.1309886 0.0013199 -0.000002 0.000090 0.000160 0.000125 0.0000044 0.0000062 0.000060 0.000067 1995 8 20 49949 0.251080 0.197583 -0.1323298 0.0013175 0.000014 0.000071 0.000160 0.000124 0.0000042 0.0000060 0.000059 0.000067 1995 8 21 49950 0.249246 0.194786 -0.1336373 0.0013215 0.000030 0.000052 0.000160 0.000123 0.0000041 0.0000058 0.000059 0.000066 1995 8 22 49951 0.247415 0.192055 -0.1349869 0.0014001 0.000046 0.000033 0.000160 0.000122 0.0000040 0.0000056 0.000058 0.000065 1995 8 23 49952 0.245183 0.189013 -0.1364499 0.0014981 0.000062 0.000014 0.000159 0.000121 0.0000038 0.0000054 0.000058 0.000065 1995 8 24 49953 0.242693 0.186399 -0.1379931 0.0015877 -0.000075 0.000177 0.000159 0.000120 0.0000037 0.0000053 0.000057 0.000064 1995 8 25 49954 0.240276 0.183515 -0.1396319 0.0017180 -0.000021 0.000296 0.000158 0.000119 0.0000036 0.0000052 0.000057 0.000064 1995 8 26 49955 0.237989 0.180366 -0.1414303 0.0018785 0.000114 0.000313 0.000158 0.000118 0.0000036 0.0000051 0.000057 0.000064 1995 8 27 49956 0.236029 0.177242 -0.1433827 0.0020137 0.000197 0.000263 0.000157 0.000118 0.0000035 0.0000050 0.000056 0.000063 1995 8 28 49957 0.233946 0.174639 -0.1454435 0.0021097 0.000119 0.000225 0.000157 0.000118 0.0000036 0.0000051 0.000056 0.000064 1995 8 29 49958 0.232121 0.172071 -0.1475828 0.0021351 -0.000020 0.000163 0.000157 0.000118 0.0000036 0.0000052 0.000056 0.000064 1995 8 30 49959 0.230032 0.169609 -0.1496951 0.0020834 -0.000136 0.000064 0.000157 0.000119 0.0000037 0.0000053 0.000056 0.000064 1995 8 31 49960 0.227442 0.166823 -0.1517381 0.0020204 -0.000208 -0.000143 0.000156 0.000119 0.0000038 0.0000054 0.000057 0.000065 1995 9 1 49961 0.224627 0.164197 -0.1537347 0.0019825 -0.000337 -0.000125 0.000156 0.000120 0.0000039 0.0000056 0.000057 0.000065 1995 9 2 49962 0.221761 0.161586 -0.1557114 0.0019708 -0.000377 -0.000053 0.000156 0.000120 0.0000040 0.0000057 0.000056 0.000065 1995 9 3 49963 0.219220 0.159003 -0.1576912 0.0019814 -0.000329 -0.000037 0.000155 0.000121 0.0000041 0.0000059 0.000056 0.000065 1995 9 4 49964 0.217098 0.156761 -0.1596920 0.0020120 -0.000282 -0.000022 0.000155 0.000121 0.0000043 0.0000060 0.000056 0.000065 1995 9 5 49965 0.215116 0.154847 -0.1617315 0.0020635 -0.000234 -0.000006 0.000155 0.000121 0.0000044 0.0000062 0.000055 0.000064 1995 9 6 49966 0.212664 0.152889 -0.1638296 0.0021367 -0.000187 0.000010 0.000155 0.000122 0.0000045 0.0000064 0.000055 0.000064 1995 9 7 49967 0.210051 0.151146 -0.1660058 0.0022359 -0.000128 0.000115 0.000156 0.000122 0.0000047 0.0000066 0.000055 0.000064 1995 9 8 49968 0.206888 0.148897 -0.1682906 0.0023412 -0.000093 0.000144 0.000156 0.000123 0.0000048 0.0000068 0.000055 0.000063 1995 9 9 49969 0.203731 0.146110 -0.1706680 0.0023882 -0.000071 0.000120 0.000156 0.000123 0.0000049 0.0000069 0.000054 0.000063 1995 9 10 49970 0.200578 0.143534 -0.1730435 0.0023258 -0.000050 0.000095 0.000156 0.000124 0.0000050 0.0000071 0.000054 0.000062 1995 9 11 49971 0.197231 0.140848 -0.1753005 0.0021954 -0.000028 0.000071 0.000155 0.000124 0.0000051 0.0000072 0.000053 0.000062 1995 9 12 49972 0.193664 0.137968 -0.1774237 0.0020663 -0.000007 0.000047 0.000155 0.000124 0.0000052 0.0000073 0.000053 0.000061 1995 9 13 49973 0.190790 0.134985 -0.1794315 0.0019562 0.000015 0.000022 0.000155 0.000124 0.0000052 0.0000074 0.000053 0.000061 1995 9 14 49974 0.188101 0.132365 -0.1813405 0.0018813 0.000010 0.000006 0.000155 0.000124 0.0000053 0.0000074 0.000052 0.000060 1995 9 15 49975 0.185618 0.130662 -0.1832022 0.0018493 -0.000003 -0.000008 0.000154 0.000123 0.0000053 0.0000075 0.000052 0.000059 1995 9 16 49976 0.183151 0.128984 -0.1850495 0.0018329 -0.000017 -0.000022 0.000153 0.000122 0.0000053 0.0000074 0.000051 0.000058 1995 9 17 49977 0.180174 0.127376 -0.1868809 0.0018322 -0.000030 -0.000036 0.000152 0.000121 0.0000052 0.0000074 0.000050 0.000057 1995 9 18 49978 0.176945 0.125557 -0.1887280 0.0018604 -0.000044 -0.000050 0.000151 0.000120 0.0000052 0.0000073 0.000050 0.000056 1995 9 19 49979 0.173909 0.123602 -0.1906152 0.0019212 -0.000058 -0.000064 0.000150 0.000118 0.0000051 0.0000073 0.000049 0.000055 1995 9 20 49980 0.171397 0.121584 -0.1925815 0.0020368 0.000085 0.000135 0.000149 0.000118 0.0000051 0.0000073 0.000049 0.000056 1995 9 21 49981 0.168512 0.119661 -0.1946962 0.0021996 0.000049 0.000077 0.000149 0.000117 0.0000052 0.0000074 0.000050 0.000056 1995 9 22 49982 0.165178 0.118023 -0.1969837 0.0023666 -0.000052 -0.000073 0.000148 0.000117 0.0000053 0.0000075 0.000050 0.000057 1995 9 23 49983 0.161687 0.116673 -0.1994264 0.0025141 -0.000031 -0.000039 0.000147 0.000116 0.0000053 0.0000075 0.000050 0.000057 1995 9 24 49984 0.158407 0.114768 -0.2020013 0.0026296 0.000000 0.000012 0.000145 0.000115 0.0000054 0.0000076 0.000049 0.000057 1995 9 25 49985 0.155490 0.113181 -0.2046675 0.0026924 0.000031 0.000063 0.000144 0.000114 0.0000054 0.0000077 0.000049 0.000057 1995 9 26 49986 0.152692 0.112107 -0.2073644 0.0026850 0.000062 0.000114 0.000143 0.000113 0.0000055 0.0000078 0.000049 0.000057 1995 9 27 49987 0.149784 0.110723 -0.2100195 0.0025984 -0.000077 0.000071 0.000141 0.000111 0.0000055 0.0000078 0.000049 0.000056 1995 9 28 49988 0.147011 0.109724 -0.2125537 0.0024763 -0.000087 0.000067 0.000140 0.000110 0.0000056 0.0000079 0.000048 0.000055 1995 9 29 49989 0.144451 0.109007 -0.2149775 0.0023707 -0.000047 0.000080 0.000138 0.000108 0.0000056 0.0000078 0.000048 0.000054 1995 9 30 49990 0.141435 0.107837 -0.2173107 0.0022936 -0.000008 0.000092 0.000136 0.000106 0.0000055 0.0000078 0.000047 0.000053 1995 10 1 49991 0.138203 0.106845 -0.2195840 0.0022992 0.000032 0.000105 0.000134 0.000104 0.0000055 0.0000077 0.000047 0.000052 1995 10 2 49992 0.134575 0.105693 -0.2219260 0.0023836 0.000072 0.000117 0.000131 0.000102 0.0000054 0.0000076 0.000046 0.000051 1995 10 3 49993 0.130881 0.104906 -0.2243618 0.0024744 0.000111 0.000130 0.000129 0.000100 0.0000053 0.0000075 0.000046 0.000051 1995 10 4 49994 0.126401 0.103893 -0.2268775 0.0025482 -0.000002 0.000257 0.000127 0.000098 0.0000053 0.0000075 0.000045 0.000050 1995 10 5 49995 0.122442 0.102953 -0.2294524 0.0026088 -0.000059 0.000105 0.000124 0.000096 0.0000052 0.0000074 0.000045 0.000049 1995 10 6 49996 0.118734 0.101952 -0.2320809 0.0026607 -0.000087 -0.000148 0.000122 0.000093 0.0000052 0.0000073 0.000045 0.000049 1995 10 7 49997 0.114714 0.100540 -0.2347541 0.0026853 -0.000079 -0.000124 0.000119 0.000091 0.0000052 0.0000073 0.000044 0.000048 1995 10 8 49998 0.110863 0.099267 -0.2374313 0.0026533 -0.000067 -0.000075 0.000116 0.000089 0.0000051 0.0000072 0.000044 0.000047 1995 10 9 49999 0.106600 0.097668 -0.2400454 0.0025487 -0.000056 -0.000026 0.000113 0.000087 0.0000051 0.0000072 0.000043 0.000046 1995 10 10 50000 0.102366 0.095954 -0.2425217 0.0023858 -0.000044 0.000023 0.000110 0.000084 0.0000050 0.0000070 0.000043 0.000045 1995 10 11 50001 0.098239 0.094340 -0.2448183 0.0022169 -0.000043 0.000079 0.000107 0.000082 0.0000049 0.0000069 0.000042 0.000044 1995 10 12 50002 0.094156 0.092704 -0.2469626 0.0020851 -0.000049 0.000075 0.000104 0.000080 0.0000048 0.0000068 0.000042 0.000042 1995 10 13 50003 0.090637 0.091046 -0.2489987 0.0019971 -0.000058 0.000051 0.000102 0.000078 0.0000047 0.0000067 0.000041 0.000041 1995 10 14 50004 0.087911 0.090176 -0.2509690 0.0019437 -0.000056 0.000041 0.000100 0.000076 0.0000047 0.0000066 0.000041 0.000040 1995 10 15 50005 0.085121 0.090063 -0.2528996 0.0019199 -0.000047 0.000039 0.000098 0.000075 0.0000047 0.0000066 0.000040 0.000040 1995 10 16 50006 0.081303 0.089533 -0.2548225 0.0019425 -0.000038 0.000037 0.000097 0.000075 0.0000046 0.0000065 0.000040 0.000040 1995 10 17 50007 0.077268 0.088584 -0.2567966 0.0020173 -0.000029 0.000035 0.000096 0.000074 0.0000046 0.0000065 0.000040 0.000040 1995 10 18 50008 0.073253 0.087721 -0.2588658 0.0021168 -0.000020 0.000033 0.000094 0.000073 0.0000046 0.0000065 0.000040 0.000040 1995 10 19 50009 0.069223 0.086625 -0.2610344 0.0022049 -0.000020 0.000036 0.000093 0.000072 0.0000046 0.0000065 0.000040 0.000040 1995 10 20 50010 0.066407 0.085744 -0.2632751 0.0022868 -0.000024 0.000040 0.000092 0.000071 0.0000046 0.0000065 0.000040 0.000041 1995 10 21 50011 0.064744 0.085460 -0.2656015 0.0024082 -0.000028 0.000044 0.000092 0.000071 0.0000046 0.0000066 0.000040 0.000041 1995 10 22 50012 0.062475 0.085573 -0.2680782 0.0024774 -0.000032 0.000048 0.000091 0.000071 0.0000047 0.0000066 0.000041 0.000042 1995 10 23 50013 0.059348 0.085505 -0.2705369 0.0024517 -0.000036 0.000052 0.000091 0.000071 0.0000047 0.0000066 0.000041 0.000043 1995 10 24 50014 0.055415 0.085252 -0.2729608 0.0024282 -0.000040 0.000056 0.000092 0.000071 0.0000047 0.0000066 0.000041 0.000044 1995 10 25 50015 0.051509 0.084783 -0.2753783 0.0024110 -0.000003 0.000026 0.000092 0.000071 0.0000047 0.0000066 0.000041 0.000044 1995 10 26 50016 0.046974 0.084168 -0.2777805 0.0023463 0.000013 0.000023 0.000092 0.000072 0.0000047 0.0000066 0.000041 0.000044 1995 10 27 50017 0.042489 0.083204 -0.2800824 0.0022453 0.000021 0.000029 0.000093 0.000072 0.0000046 0.0000066 0.000041 0.000044 1995 10 28 50018 0.038510 0.082282 -0.2822914 0.0022512 0.000030 0.000035 0.000093 0.000073 0.0000046 0.0000065 0.000040 0.000044 1995 10 29 50019 0.034910 0.081966 -0.2846051 0.0023345 0.000039 0.000041 0.000094 0.000073 0.0000046 0.0000065 0.000040 0.000044 1995 10 30 50020 0.031526 0.082132 -0.2869733 0.0024124 0.000047 0.000047 0.000095 0.000074 0.0000045 0.0000064 0.000040 0.000044 1995 10 31 50021 0.028334 0.082494 -0.2894326 0.0025328 0.000056 0.000053 0.000097 0.000076 0.0000045 0.0000064 0.000040 0.000044 1995 11 1 50022 0.024934 0.082646 -0.2920329 0.0026840 0.000064 0.000059 0.000099 0.000077 0.0000044 0.0000063 0.000039 0.000044 1995 11 2 50023 0.021863 0.082955 -0.2947886 0.0027753 0.000075 0.000058 0.000101 0.000079 0.0000045 0.0000064 0.000040 0.000044 1995 11 3 50024 0.018909 0.083396 -0.2975678 0.0027452 0.000087 0.000055 0.000103 0.000081 0.0000045 0.0000064 0.000040 0.000045 1995 11 4 50025 0.015144 0.083909 -0.3002622 0.0026817 0.000099 0.000051 0.000105 0.000083 0.0000046 0.0000065 0.000040 0.000045 1995 11 5 50026 0.011272 0.084150 -0.3029163 0.0025813 0.000110 0.000048 0.000107 0.000084 0.0000046 0.0000065 0.000040 0.000046 1995 11 6 50027 0.007376 0.084215 -0.3054149 0.0024300 0.000122 0.000045 0.000109 0.000086 0.0000046 0.0000066 0.000040 0.000047 1995 11 7 50028 0.003477 0.084367 -0.3077738 0.0023075 0.000134 0.000041 0.000110 0.000088 0.0000046 0.0000066 0.000041 0.000047 1995 11 8 50029 -0.000088 0.085116 -0.3100347 0.0022078 0.000145 0.000038 0.000112 0.000089 0.0000046 0.0000066 0.000041 0.000048 1995 11 9 50030 -0.003737 0.085612 -0.3121990 0.0021084 0.000151 0.000176 0.000113 0.000090 0.0000046 0.0000066 0.000041 0.000049 1995 11 10 50031 -0.007373 0.085493 -0.3142635 0.0020148 0.000155 0.000362 0.000115 0.000091 0.0000046 0.0000066 0.000041 0.000050 1995 11 11 50032 -0.011048 0.085773 -0.3162414 0.0019581 0.000151 0.000365 0.000116 0.000093 0.0000046 0.0000066 0.000042 0.000050 1995 11 12 50033 -0.014986 0.086314 -0.3181927 0.0019848 0.000141 0.000237 0.000118 0.000094 0.0000046 0.0000065 0.000042 0.000051 1995 11 13 50034 -0.018809 0.086571 -0.3202232 0.0020840 0.000130 0.000109 0.000119 0.000094 0.0000046 0.0000065 0.000042 0.000051 1995 11 14 50035 -0.022231 0.087328 -0.3223704 0.0022131 0.000120 -0.000019 0.000120 0.000095 0.0000046 0.0000064 0.000042 0.000051 1995 11 15 50036 -0.025176 0.087978 -0.3246548 0.0023819 0.000132 0.000016 0.000121 0.000096 0.0000045 0.0000064 0.000042 0.000051 1995 11 16 50037 -0.028705 0.089355 -0.3271349 0.0025720 0.000112 0.000045 0.000121 0.000096 0.0000045 0.0000063 0.000041 0.000050 1995 11 17 50038 -0.033109 0.090654 -0.3297945 0.0027211 0.000082 0.000073 0.000122 0.000097 0.0000044 0.0000062 0.000041 0.000050 1995 11 18 50039 -0.037642 0.091977 -0.3325679 0.0028132 0.000064 0.000070 0.000122 0.000097 0.0000044 0.0000062 0.000041 0.000050 1995 11 19 50040 -0.041900 0.093317 -0.3354069 0.0028605 0.000047 0.000064 0.000123 0.000098 0.0000043 0.0000061 0.000041 0.000051 1995 11 20 50041 -0.045731 0.094697 -0.3382711 0.0028662 0.000031 0.000058 0.000123 0.000099 0.0000043 0.0000061 0.000041 0.000051 1995 11 21 50042 -0.049618 0.096135 -0.3411224 0.0028337 0.000014 0.000052 0.000124 0.000099 0.0000043 0.0000060 0.000041 0.000051 1995 11 22 50043 -0.054091 0.097069 -0.3439292 0.0027727 0.000002 0.000074 0.000124 0.000100 0.0000042 0.0000059 0.000041 0.000051 1995 11 23 50044 -0.058371 0.097540 -0.3466714 0.0027019 -0.000035 0.000030 0.000124 0.000100 0.0000041 0.0000058 0.000041 0.000051 1995 11 24 50045 -0.061921 0.098418 -0.3493493 0.0026468 -0.000079 -0.000036 0.000124 0.000101 0.0000041 0.0000057 0.000041 0.000051 1995 11 25 50046 -0.065174 0.100039 -0.3519872 0.0026298 -0.000124 -0.000103 0.000125 0.000101 0.0000040 0.0000056 0.000041 0.000051 1995 11 26 50047 -0.068640 0.102002 -0.3546271 0.0026595 -0.000169 -0.000169 0.000125 0.000101 0.0000039 0.0000055 0.000041 0.000050 1995 11 27 50048 -0.072005 0.103594 -0.3573129 0.0027221 -0.000214 -0.000235 0.000125 0.000102 0.0000039 0.0000055 0.000041 0.000050 1995 11 28 50049 -0.075618 0.105189 -0.3600652 0.0027880 -0.000259 -0.000301 0.000125 0.000102 0.0000038 0.0000054 0.000040 0.000050 1995 11 29 50050 -0.079723 0.107032 -0.3628742 0.0028285 -0.000023 -0.000144 0.000125 0.000102 0.0000038 0.0000054 0.000040 0.000049 1995 11 30 50051 -0.084849 0.108841 -0.3657048 0.0028150 0.000031 -0.000071 0.000125 0.000101 0.0000038 0.0000054 0.000040 0.000048 1995 12 1 50052 -0.090049 0.110601 -0.3684881 0.0027285 0.000024 -0.000026 0.000125 0.000101 0.0000038 0.0000054 0.000039 0.000047 1995 12 2 50053 -0.095319 0.112185 -0.3711490 0.0025956 0.000017 0.000019 0.000125 0.000101 0.0000038 0.0000054 0.000039 0.000046 1995 12 3 50054 -0.099819 0.113642 -0.3736705 0.0024826 0.000010 0.000064 0.000125 0.000101 0.0000038 0.0000054 0.000038 0.000046 1995 12 4 50055 -0.104101 0.115390 -0.3761103 0.0023902 0.000004 0.000109 0.000125 0.000101 0.0000038 0.0000054 0.000038 0.000045 1995 12 5 50056 -0.108717 0.117518 -0.3784533 0.0022796 -0.000003 0.000154 0.000125 0.000101 0.0000038 0.0000054 0.000038 0.000044 1995 12 6 50057 -0.112676 0.119446 -0.3806776 0.0021609 -0.000010 0.000199 0.000125 0.000101 0.0000038 0.0000054 0.000037 0.000043 1995 12 7 50058 -0.116467 0.121652 -0.3827868 0.0020856 0.000198 0.000010 0.000125 0.000100 0.0000038 0.0000054 0.000037 0.000043 1995 12 8 50059 -0.119414 0.123344 -0.3848618 0.0020966 0.000147 -0.000138 0.000125 0.000100 0.0000038 0.0000054 0.000037 0.000042 1995 12 9 50060 -0.122408 0.124944 -0.3869928 0.0021590 0.000059 -0.000159 0.000126 0.000100 0.0000038 0.0000053 0.000036 0.000041 1995 12 10 50061 -0.125238 0.127066 -0.3891915 0.0022161 0.000066 -0.000131 0.000126 0.000100 0.0000038 0.0000053 0.000036 0.000041 1995 12 11 50062 -0.128148 0.129206 -0.3914347 0.0022697 0.000072 -0.000102 0.000127 0.000100 0.0000038 0.0000053 0.000036 0.000041 1995 12 12 50063 -0.132086 0.131470 -0.3937373 0.0023512 0.000078 -0.000074 0.000127 0.000099 0.0000037 0.0000053 0.000036 0.000041 1995 12 13 50064 -0.136044 0.133761 -0.3961387 0.0024780 0.000084 -0.000045 0.000127 0.000099 0.0000037 0.0000053 0.000036 0.000041 1995 12 14 50065 -0.138719 0.136496 -0.3986898 0.0025969 0.000112 -0.000116 0.000128 0.000100 0.0000037 0.0000053 0.000036 0.000041 1995 12 15 50066 -0.140860 0.139232 -0.4013246 0.0026463 0.000107 -0.000137 0.000129 0.000101 0.0000038 0.0000054 0.000036 0.000042 1995 12 16 50067 -0.143247 0.142293 -0.4039711 0.0026493 0.000082 -0.000117 0.000130 0.000102 0.0000039 0.0000055 0.000036 0.000043 1995 12 17 50068 -0.145558 0.145378 -0.4066098 0.0026426 0.000057 -0.000096 0.000131 0.000103 0.0000040 0.0000056 0.000037 0.000043 1995 12 18 50069 -0.147546 0.148881 -0.4092425 0.0026327 0.000032 -0.000076 0.000131 0.000103 0.0000040 0.0000057 0.000037 0.000044 1995 12 19 50070 -0.150057 0.151848 -0.4118647 0.0026097 0.000007 -0.000055 0.000132 0.000104 0.0000041 0.0000058 0.000037 0.000045 1995 12 20 50071 -0.152495 0.154739 -0.4144596 0.0025585 0.000000 -0.000016 0.000132 0.000104 0.0000041 0.0000058 0.000038 0.000045 1995 12 21 50072 -0.154933 0.157531 -0.4169912 0.0024836 0.000005 -0.000011 0.000132 0.000104 0.0000042 0.0000059 0.000038 0.000046 1995 12 22 50073 -0.157172 0.160201 -0.4194464 0.0024340 0.000013 -0.000019 0.000132 0.000105 0.0000042 0.0000059 0.000038 0.000046 1995 12 23 50074 -0.158604 0.163573 -0.4218809 0.0024689 0.000021 -0.000026 0.000131 0.000105 0.0000042 0.0000060 0.000038 0.000046 1995 12 24 50075 -0.159971 0.167162 -0.4243982 0.0025802 0.000029 -0.000034 0.000131 0.000105 0.0000042 0.0000060 0.000038 0.000046 1995 12 25 50076 -0.162007 0.170986 -0.4270408 0.0027049 0.000038 -0.000041 0.000130 0.000104 0.0000043 0.0000060 0.000039 0.000046 1995 12 26 50077 -0.164204 0.174511 -0.4297935 0.0027860 0.000046 -0.000049 0.000130 0.000104 0.0000043 0.0000060 0.000039 0.000046 1995 12 27 50078 -0.166501 0.177830 -0.4325910 0.0027856 0.000054 -0.000056 0.000129 0.000104 0.0000043 0.0000061 0.000039 0.000046 1995 12 28 50079 -0.168581 0.180637 -0.4353435 0.0026987 0.000054 -0.000032 0.000129 0.000104 0.0000044 0.0000062 0.000040 0.000046 1995 12 29 50080 -0.170619 0.183497 -0.4379728 0.0025412 0.000052 0.000003 0.000129 0.000104 0.0000044 0.0000062 0.000040 0.000047 1995 12 30 50081 -0.172599 0.186087 -0.4404169 0.0023350 0.000049 0.000038 0.000129 0.000105 0.0000045 0.0000063 0.000041 0.000048 1995 12 31 50082 -0.174429 0.188863 -0.4426395 0.0021185 0.000047 0.000073 0.000129 0.000106 0.0000045 0.0000064 0.000042 0.000048 1996 1 1 50083 -0.176028 0.191724 0.5553352 0.0019165 0.000045 0.000108 0.000163 0.000140 0.0000035 0.0000083 0.000045 0.000043 1996 1 2 50084 -0.177290 0.194420 0.5534943 0.0017598 0.000042 0.000143 0.000164 0.000141 0.0000039 0.0000084 0.000045 0.000044 1996 1 3 50085 -0.178324 0.197578 0.5517970 0.0016532 0.000040 0.000178 0.000165 0.000142 0.0000042 0.0000085 0.000046 0.000045 1996 1 4 50086 -0.179241 0.200509 0.5501975 0.0015803 0.000049 0.000156 0.000165 0.000143 0.0000041 0.0000086 0.000046 0.000045 1996 1 5 50087 -0.180278 0.203817 0.5486467 0.0015376 0.000063 0.000115 0.000166 0.000144 0.0000037 0.0000086 0.000047 0.000045 1996 1 6 50088 -0.181729 0.207098 0.5470860 0.0015706 0.000077 0.000073 0.000166 0.000144 0.0000034 0.0000086 0.000047 0.000045 1996 1 7 50089 -0.183397 0.210612 0.5454560 0.0016838 0.000091 0.000031 0.000167 0.000145 0.0000030 0.0000087 0.000047 0.000045 1996 1 8 50090 -0.185420 0.213672 0.5437199 0.0018030 0.000104 -0.000010 0.000167 0.000145 0.0000026 0.0000087 0.000047 0.000045 1996 1 9 50091 -0.186772 0.216283 0.5418755 0.0018872 0.000118 -0.000052 0.000167 0.000145 0.0000023 0.0000086 0.000048 0.000045 1996 1 10 50092 -0.188587 0.218550 0.5399454 0.0019637 0.000132 -0.000093 0.000167 0.000145 0.0000019 0.0000087 0.000048 0.000045 1996 1 11 50093 -0.190639 0.221066 0.5379327 0.0020022 0.000129 -0.000124 0.000168 0.000146 0.0000201 0.0000087 0.000048 0.000045 1996 1 12 50094 -0.192631 0.223928 0.5358944 0.0019944 0.000121 -0.000151 0.000169 0.000146 0.0000445 0.0000088 0.000049 0.000046 1996 1 13 50095 -0.194770 0.227343 0.5338666 0.0019904 0.000113 -0.000177 0.000170 0.000147 0.0000689 0.0000089 0.000049 0.000046 1996 1 14 50096 -0.196739 0.230607 0.5318632 0.0019307 0.000105 -0.000204 0.000170 0.000147 0.0000934 0.0000091 0.000050 0.000047 1996 1 15 50097 -0.198421 0.233194 0.5298885 0.0018823 0.000097 -0.000231 0.000170 0.000147 0.0001178 0.0000092 0.000050 0.000047 1996 1 16 50098 -0.199516 0.235520 0.5279548 0.0019300 0.000089 -0.000258 0.000169 0.000147 0.0001299 0.0000092 0.000051 0.000048 1996 1 17 50099 -0.200686 0.238298 0.5262050 0.0018854 0.000081 -0.000285 0.000169 0.000146 0.0000291 0.0000093 0.000051 0.000049 1996 1 18 50100 -0.202208 0.241453 0.5243680 0.0017492 0.000094 -0.000306 0.000168 0.000145 0.0000102 0.0000094 0.000052 0.000049 1996 1 19 50101 -0.203669 0.245118 0.5225259 0.0017420 0.000113 -0.000326 0.000168 0.000144 0.0000178 0.0000094 0.000052 0.000049 1996 1 20 50102 -0.205113 0.249312 0.5207455 0.0018758 0.000132 -0.000346 0.000167 0.000144 0.0000155 0.0000094 0.000053 0.000050 1996 1 21 50103 -0.206696 0.253023 0.5188413 0.0020375 0.000152 -0.000366 0.000166 0.000143 0.0000131 0.0000094 0.000053 0.000050 1996 1 22 50104 -0.207966 0.256598 0.5168062 0.0021470 0.000171 -0.000385 0.000165 0.000142 0.0000108 0.0000094 0.000054 0.000051 1996 1 23 50105 -0.209851 0.259725 0.5146982 0.0021597 0.000190 -0.000405 0.000165 0.000141 0.0000084 0.0000093 0.000054 0.000051 1996 1 24 50106 -0.211257 0.263063 0.5125755 0.0020937 0.000026 -0.000152 0.000164 0.000140 0.0000052 0.0000093 0.000054 0.000051 1996 1 25 50107 -0.212154 0.266735 0.5105299 0.0019911 -0.000020 -0.000003 0.000163 0.000139 0.0000048 0.0000092 0.000054 0.000051 1996 1 26 50108 -0.212931 0.270336 0.5086049 0.0018720 -0.000023 0.000107 0.000162 0.000138 0.0000054 0.0000091 0.000054 0.000051 1996 1 27 50109 -0.213504 0.274348 0.5066818 0.0017377 -0.000004 0.000039 0.000160 0.000137 0.0000140 0.0000089 0.000054 0.000050 1996 1 28 50110 -0.215198 0.278182 0.5049222 0.0015921 0.000016 -0.000046 0.000159 0.000136 0.0000207 0.0000088 0.000054 0.000049 1996 1 29 50111 -0.217074 0.281979 0.5035005 0.0014668 0.000036 -0.000130 0.000157 0.000135 0.0000117 0.0000086 0.000053 0.000049 1996 1 30 50112 -0.218702 0.285301 0.5021783 0.0013918 0.000056 -0.000214 0.000156 0.000134 0.0000026 0.0000085 0.000053 0.000048 1996 1 31 50113 -0.220011 0.288663 0.5008120 0.0013660 0.000139 -0.000260 0.000156 0.000134 0.0000035 0.0000085 0.000053 0.000049 1996 2 1 50114 -0.221070 0.291919 0.4993342 0.0013933 0.000146 -0.000257 0.000156 0.000134 0.0000124 0.0000084 0.000054 0.000049 1996 2 2 50115 -0.221817 0.295673 0.4977808 0.0014868 0.000126 -0.000240 0.000156 0.000135 0.0000205 0.0000084 0.000054 0.000050 1996 2 3 50116 -0.222228 0.299462 0.4962361 0.0016175 0.000106 -0.000222 0.000156 0.000135 0.0000118 0.0000083 0.000054 0.000050 1996 2 4 50117 -0.222158 0.303351 0.4945666 0.0017193 0.000087 -0.000205 0.000155 0.000134 0.0000146 0.0000082 0.000055 0.000051 1996 2 5 50118 -0.222326 0.307067 0.4929039 0.0018137 0.000067 -0.000188 0.000155 0.000134 0.0000100 0.0000080 0.000055 0.000051 1996 2 6 50119 -0.223040 0.310962 0.4911284 0.0019472 0.000047 -0.000170 0.000154 0.000133 0.0000054 0.0000079 0.000055 0.000052 1996 2 7 50120 -0.223697 0.314562 0.4891395 0.0020094 0.000076 -0.000050 0.000153 0.000132 0.0000020 0.0000078 0.000055 0.000052 1996 2 8 50121 -0.224405 0.318133 0.4869161 0.0021609 0.000003 0.000077 0.000153 0.000132 0.0000115 0.0000078 0.000056 0.000053 1996 2 9 50122 -0.225301 0.321373 0.4846236 0.0021890 -0.000120 0.000290 0.000154 0.000133 0.0000215 0.0000078 0.000057 0.000054 1996 2 10 50123 -0.225544 0.323863 0.4825248 0.0020878 -0.000171 0.000397 0.000155 0.000134 0.0000141 0.0000079 0.000057 0.000055 1996 2 11 50124 -0.224826 0.326622 0.4804574 0.0020770 -0.000064 0.000213 0.000155 0.000134 0.0000138 0.0000079 0.000058 0.000055 1996 2 12 50125 -0.223492 0.329506 0.4785269 0.0019901 0.000043 0.000030 0.000155 0.000134 0.0000117 0.0000078 0.000058 0.000056 1996 2 13 50126 -0.222048 0.332546 0.4766625 0.0019395 0.000150 -0.000154 0.000154 0.000134 0.0000096 0.0000077 0.000059 0.000056 1996 2 14 50127 -0.220795 0.335990 0.4747273 0.0019302 -0.000060 -0.000176 0.000154 0.000134 0.0000093 0.0000076 0.000059 0.000056 1996 2 15 50128 -0.219661 0.339601 0.4727939 0.0019556 0.000145 -0.000092 0.000153 0.000133 0.0000083 0.0000074 0.000059 0.000055 1996 2 16 50129 -0.218728 0.343900 0.4707973 0.0020504 0.000496 0.000025 0.000152 0.000132 0.0000070 0.0000072 0.000059 0.000055 1996 2 17 50130 -0.218443 0.348732 0.4686674 0.0022098 0.000459 0.000032 0.000150 0.000131 0.0000066 0.0000070 0.000058 0.000053 1996 2 18 50131 -0.218550 0.353509 0.4663668 0.0023885 0.000386 0.000029 0.000148 0.000129 0.0000062 0.0000068 0.000058 0.000052 1996 2 19 50132 -0.219375 0.357782 0.4639030 0.0025321 0.000313 0.000026 0.000146 0.000128 0.0000058 0.0000066 0.000057 0.000050 1996 2 20 50133 -0.220501 0.361693 0.4613335 0.0025954 0.000240 0.000023 0.000144 0.000125 0.0000055 0.0000064 0.000057 0.000049 1996 2 21 50134 -0.221113 0.364711 0.4587458 0.0025618 0.000167 0.000021 0.000141 0.000123 0.0000051 0.0000062 0.000056 0.000048 1996 2 22 50135 -0.221441 0.367758 0.4562328 0.0024500 0.000102 0.000000 0.000138 0.000121 0.0000152 0.0000060 0.000055 0.000046 1996 2 23 50136 -0.221444 0.370710 0.4538569 0.0022961 0.000039 -0.000027 0.000135 0.000118 0.0000288 0.0000060 0.000055 0.000045 1996 2 24 50137 -0.221417 0.374810 0.4516481 0.0021243 0.000015 -0.000058 0.000136 0.000119 0.0000259 0.0000060 0.000054 0.000045 1996 2 25 50138 -0.220855 0.379059 0.4496212 0.0019506 -0.000004 -0.000090 0.000138 0.000120 0.0000214 0.0000062 0.000054 0.000045 1996 2 26 50139 -0.220351 0.383359 0.4477621 0.0017987 -0.000024 -0.000122 0.000139 0.000121 0.0000169 0.0000065 0.000054 0.000046 1996 2 27 50140 -0.219974 0.387121 0.4460254 0.0016979 -0.000043 -0.000155 0.000141 0.000122 0.0000124 0.0000067 0.000054 0.000046 1996 2 28 50141 -0.219641 0.391104 0.4443344 0.0016769 -0.000063 -0.000187 0.000142 0.000123 0.0000079 0.0000070 0.000054 0.000046 1996 2 29 50142 -0.219057 0.394701 0.4425078 0.0017834 -0.000062 -0.000181 0.000142 0.000124 0.0000171 0.0000072 0.000054 0.000046 1996 3 1 50143 -0.217728 0.398436 0.4405361 0.0019758 -0.000054 -0.000162 0.000142 0.000124 0.0000273 0.0000074 0.000054 0.000046 1996 3 2 50144 -0.216085 0.402576 0.4384639 0.0020939 -0.000046 -0.000144 0.000143 0.000124 0.0000241 0.0000076 0.000054 0.000046 1996 3 3 50145 -0.214359 0.406790 0.4363468 0.0021870 -0.000038 -0.000125 0.000142 0.000124 0.0000184 0.0000077 0.000053 0.000046 1996 3 4 50146 -0.212321 0.410859 0.4341736 0.0023348 -0.000030 -0.000107 0.000142 0.000123 0.0000122 0.0000078 0.000053 0.000046 1996 3 5 50147 -0.210623 0.415069 0.4318784 0.0024669 -0.000023 -0.000088 0.000141 0.000123 0.0000060 0.0000078 0.000053 0.000046 1996 3 6 50148 -0.208624 0.419403 0.4293654 0.0025571 -0.000034 0.000008 0.000140 0.000122 0.0000026 0.0000079 0.000053 0.000046 1996 3 7 50149 -0.206797 0.423448 0.4267880 0.0025950 0.000006 -0.000104 0.000140 0.000122 0.0000023 0.0000080 0.000052 0.000046 1996 3 8 50150 -0.205445 0.427119 0.4240893 0.0026051 0.000032 -0.000159 0.000139 0.000123 0.0000142 0.0000082 0.000053 0.000046 1996 3 9 50151 -0.204072 0.430877 0.4213715 0.0026039 0.000042 -0.000150 0.000139 0.000123 0.0000248 0.0000083 0.000053 0.000046 1996 3 10 50152 -0.202900 0.434510 0.4188027 0.0025553 0.000052 -0.000142 0.000139 0.000123 0.0000156 0.0000085 0.000053 0.000046 1996 3 11 50153 -0.201453 0.437504 0.4163837 0.0024658 0.000063 -0.000133 0.000138 0.000123 0.0000105 0.0000086 0.000053 0.000045 1996 3 12 50154 -0.199542 0.440879 0.4140502 0.0023696 0.000059 -0.000125 0.000137 0.000123 0.0000057 0.0000087 0.000053 0.000045 1996 3 13 50155 -0.198229 0.444488 0.4117275 0.0022521 -0.000044 -0.000125 0.000135 0.000123 0.0000032 0.0000088 0.000053 0.000045 1996 3 14 50156 -0.196867 0.447727 0.4095034 0.0021848 -0.000090 -0.000132 0.000134 0.000123 0.0000072 0.0000088 0.000053 0.000045 1996 3 15 50157 -0.194775 0.451652 0.4071952 0.0022096 -0.000086 -0.000147 0.000133 0.000122 0.0000154 0.0000089 0.000053 0.000045 1996 3 16 50158 -0.192726 0.455003 0.4048865 0.0022671 -0.000082 -0.000163 0.000132 0.000122 0.0000218 0.0000090 0.000053 0.000044 1996 3 17 50159 -0.190768 0.458433 0.4025948 0.0023405 -0.000078 -0.000178 0.000130 0.000121 0.0000221 0.0000090 0.000053 0.000044 1996 3 18 50160 -0.188435 0.461797 0.4002270 0.0024110 -0.000074 -0.000194 0.000129 0.000120 0.0000205 0.0000089 0.000053 0.000044 1996 3 19 50161 -0.185313 0.465635 0.3978358 0.0024480 -0.000070 -0.000209 0.000127 0.000118 0.0000168 0.0000088 0.000053 0.000044 1996 3 20 50162 -0.181650 0.470480 0.3955289 0.0024353 -0.000066 -0.000225 0.000125 0.000117 0.0000076 0.0000088 0.000054 0.000044 1996 3 21 50163 -0.178710 0.474968 0.3931533 0.0023718 -0.000076 -0.000117 0.000122 0.000115 0.0000025 0.0000088 0.000054 0.000043 1996 3 22 50164 -0.176563 0.478427 0.3907295 0.0022477 -0.000143 -0.000060 0.000123 0.000116 0.0000128 0.0000088 0.000054 0.000044 1996 3 23 50165 -0.175361 0.482156 0.3884396 0.0020846 -0.000235 -0.000051 0.000125 0.000117 0.0000212 0.0000090 0.000055 0.000045 1996 3 24 50166 -0.173761 0.484563 0.3864441 0.0019652 -0.000328 -0.000041 0.000128 0.000119 0.0000104 0.0000092 0.000056 0.000047 1996 3 25 50167 -0.171452 0.487283 0.3846010 0.0019051 -0.000420 -0.000031 0.000130 0.000120 0.0000085 0.0000094 0.000057 0.000048 1996 3 26 50168 -0.168754 0.489658 0.3828141 0.0018683 -0.000513 -0.000021 0.000132 0.000122 0.0000066 0.0000096 0.000058 0.000050 1996 3 27 50169 -0.165788 0.492822 0.3809701 0.0018664 -0.000164 -0.000069 0.000134 0.000123 0.0000033 0.0000098 0.000058 0.000051 1996 3 28 50170 -0.162621 0.495560 0.3790846 0.0019097 -0.000170 -0.000022 0.000135 0.000123 0.0000052 0.0000101 0.000059 0.000052 1996 3 29 50171 -0.159721 0.498695 0.3770323 0.0019908 -0.000223 0.000019 0.000137 0.000125 0.0000167 0.0000104 0.000060 0.000053 1996 3 30 50172 -0.157027 0.501594 0.3748876 0.0020824 -0.000224 0.000038 0.000138 0.000126 0.0000259 0.0000106 0.000061 0.000055 1996 3 31 50173 -0.154359 0.504362 0.3727619 0.0021577 -0.000224 0.000057 0.000140 0.000127 0.0000227 0.0000109 0.000061 0.000056 1996 4 1 50174 -0.151916 0.507512 0.3705600 0.0022737 -0.000224 0.000077 0.000141 0.000127 0.0000233 0.0000111 0.000062 0.000057 1996 4 2 50175 -0.149472 0.510585 0.3682589 0.0024330 -0.000224 0.000096 0.000142 0.000128 0.0000197 0.0000113 0.000064 0.000059 1996 4 3 50176 -0.147336 0.513486 0.3659014 0.0024969 -0.000225 0.000115 0.000143 0.000128 0.0000067 0.0000115 0.000065 0.000060 1996 4 4 50177 -0.145679 0.515726 0.3633318 0.0025067 -0.000229 -0.000136 0.000143 0.000129 0.0000163 0.0000117 0.000066 0.000062 1996 4 5 50178 -0.144005 0.517501 0.3607191 0.0025238 -0.000218 -0.000252 0.000144 0.000130 0.0000255 0.0000119 0.000067 0.000063 1996 4 6 50179 -0.141834 0.519089 0.3582097 0.0024584 -0.000198 -0.000255 0.000145 0.000130 0.0000197 0.0000120 0.000067 0.000065 1996 4 7 50180 -0.140092 0.520966 0.3558055 0.0023785 -0.000178 -0.000258 0.000146 0.000131 0.0000204 0.0000121 0.000068 0.000066 1996 4 8 50181 -0.138190 0.522599 0.3534526 0.0023217 -0.000158 -0.000261 0.000147 0.000132 0.0000227 0.0000122 0.000069 0.000067 1996 4 9 50182 -0.135212 0.524958 0.3512127 0.0022534 -0.000139 -0.000264 0.000148 0.000133 0.0000198 0.0000122 0.000070 0.000069 1996 4 10 50183 -0.132050 0.527795 0.3490945 0.0022602 -0.000190 -0.000152 0.000149 0.000133 0.0000058 0.0000124 0.000071 0.000069 1996 4 11 50184 -0.129242 0.530905 0.3467181 0.0023376 -0.000182 -0.000102 0.000150 0.000134 0.0000145 0.0000125 0.000071 0.000070 1996 4 12 50185 -0.126583 0.533844 0.3442355 0.0024356 -0.000152 -0.000074 0.000152 0.000135 0.0000255 0.0000127 0.000072 0.000072 1996 4 13 50186 -0.123670 0.536625 0.3417325 0.0025603 -0.000122 -0.000047 0.000153 0.000136 0.0000252 0.0000130 0.000073 0.000073 1996 4 14 50187 -0.120087 0.539204 0.3391586 0.0026049 -0.000092 -0.000020 0.000154 0.000137 0.0000217 0.0000132 0.000074 0.000075 1996 4 15 50188 -0.116414 0.541719 0.3366807 0.0025560 -0.000062 0.000008 0.000155 0.000138 0.0000149 0.0000134 0.000075 0.000076 1996 4 16 50189 -0.112546 0.544377 0.3342376 0.0025065 -0.000032 0.000035 0.000155 0.000138 0.0000080 0.0000134 0.000075 0.000078 1996 4 17 50190 -0.109354 0.546770 0.3317619 0.0024407 -0.000044 0.000013 0.000156 0.000138 0.0000083 0.0000135 0.000076 0.000079 1996 4 18 50191 -0.106502 0.549332 0.3292781 0.0023177 -0.000056 0.000003 0.000156 0.000138 0.0000099 0.0000135 0.000077 0.000079 1996 4 19 50192 -0.103774 0.551590 0.3269175 0.0021422 -0.000068 -0.000002 0.000156 0.000138 0.0000128 0.0000135 0.000077 0.000079 1996 4 20 50193 -0.100809 0.554060 0.3248683 0.0019960 -0.000080 -0.000007 0.000156 0.000138 0.0000211 0.0000135 0.000077 0.000080 1996 4 21 50194 -0.097783 0.556055 0.3229115 0.0019392 -0.000091 -0.000012 0.000156 0.000138 0.0000074 0.0000134 0.000077 0.000080 1996 4 22 50195 -0.094709 0.557919 0.3209749 0.0019144 -0.000103 -0.000017 0.000156 0.000138 0.0000091 0.0000133 0.000078 0.000080 1996 4 23 50196 -0.091116 0.559860 0.3190911 0.0018743 -0.000115 -0.000022 0.000156 0.000138 0.0000099 0.0000132 0.000078 0.000080 1996 4 24 50197 -0.087633 0.561894 0.3173905 0.0018949 -0.000127 -0.000027 0.000155 0.000137 0.0000035 0.0000132 0.000079 0.000080 1996 4 25 50198 -0.084170 0.563204 0.3154893 0.0019823 -0.000005 0.000021 0.000155 0.000137 0.0000031 0.0000132 0.000079 0.000082 1996 4 26 50199 -0.080800 0.564689 0.3133592 0.0020790 -0.000078 0.000068 0.000156 0.000138 0.0000083 0.0000134 0.000080 0.000083 1996 4 27 50200 -0.076904 0.565952 0.3110948 0.0021957 -0.000141 0.000084 0.000155 0.000137 0.0000151 0.0000136 0.000080 0.000084 1996 4 28 50201 -0.072521 0.567374 0.3088587 0.0023185 -0.000110 0.000083 0.000155 0.000137 0.0000192 0.0000138 0.000080 0.000084 1996 4 29 50202 -0.068063 0.569629 0.3064887 0.0024237 -0.000079 0.000082 0.000155 0.000137 0.0000162 0.0000140 0.000080 0.000085 1996 4 30 50203 -0.063733 0.572309 0.3040366 0.0025114 -0.000049 0.000081 0.000154 0.000136 0.0000128 0.0000142 0.000080 0.000086 1996 5 1 50204 -0.059661 0.574930 0.3016450 0.0025853 -0.000018 0.000080 0.000154 0.000136 0.0000070 0.0000143 0.000080 0.000087 1996 5 2 50205 -0.056465 0.576627 0.2990675 0.0026405 -0.000332 -0.000014 0.000154 0.000136 0.0000045 0.0000145 0.000080 0.000087 1996 5 3 50206 -0.053369 0.578142 0.2963781 0.0026293 -0.000366 -0.000018 0.000154 0.000136 0.0000059 0.0000147 0.000080 0.000087 1996 5 4 50207 -0.050039 0.579695 0.2937171 0.0025202 -0.000202 0.000040 0.000154 0.000136 0.0000088 0.0000150 0.000079 0.000088 1996 5 5 50208 -0.046014 0.580941 0.2911635 0.0023944 -0.000038 0.000097 0.000154 0.000136 0.0000116 0.0000152 0.000079 0.000088 1996 5 6 50209 -0.041959 0.582118 0.2887975 0.0023262 0.000127 0.000154 0.000155 0.000136 0.0000152 0.0000154 0.000078 0.000089 1996 5 7 50210 -0.037890 0.583340 0.2865064 0.0023181 0.000291 0.000212 0.000155 0.000137 0.0000169 0.0000156 0.000078 0.000090 1996 5 8 50211 -0.033695 0.584587 0.2843276 0.0023650 -0.000132 -0.000194 0.000156 0.000138 0.0000087 0.0000158 0.000077 0.000089 1996 5 9 50212 -0.029214 0.585976 0.2818644 0.0024510 -0.000226 -0.000259 0.000157 0.000138 0.0000190 0.0000158 0.000076 0.000088 1996 5 10 50213 -0.024844 0.587184 0.2792465 0.0025567 -0.000209 -0.000208 0.000157 0.000139 0.0000307 0.0000159 0.000075 0.000087 1996 5 11 50214 -0.020584 0.588233 0.2766438 0.0026583 -0.000191 -0.000158 0.000158 0.000140 0.0000169 0.0000159 0.000074 0.000086 1996 5 12 50215 -0.016050 0.589104 0.2739575 0.0027033 -0.000173 -0.000107 0.000159 0.000141 0.0000107 0.0000159 0.000073 0.000085 1996 5 13 50216 -0.011376 0.590232 0.2712727 0.0026560 -0.000156 -0.000057 0.000159 0.000141 0.0000115 0.0000159 0.000072 0.000084 1996 5 14 50217 -0.007220 0.591192 0.2686845 0.0025429 -0.000138 -0.000006 0.000160 0.000141 0.0000113 0.0000158 0.000071 0.000083 1996 5 15 50218 -0.003371 0.591960 0.2663571 0.0024222 -0.000121 0.000044 0.000160 0.000142 0.0000052 0.0000157 0.000070 0.000082 1996 5 16 50219 0.000269 0.592766 0.2640292 0.0022887 -0.000057 -0.000031 0.000160 0.000142 0.0000059 0.0000158 0.000070 0.000082 1996 5 17 50220 0.003274 0.593314 0.2617287 0.0021130 -0.000051 -0.000035 0.000160 0.000142 0.0000127 0.0000158 0.000069 0.000081 1996 5 18 50221 0.006067 0.593936 0.2595800 0.0019407 -0.000080 0.000017 0.000160 0.000141 0.0000183 0.0000159 0.000069 0.000080 1996 5 19 50222 0.009917 0.594323 0.2577205 0.0018194 -0.000110 0.000070 0.000159 0.000141 0.0000115 0.0000159 0.000068 0.000080 1996 5 20 50223 0.013538 0.594853 0.2560446 0.0017355 -0.000139 0.000122 0.000159 0.000140 0.0000096 0.0000159 0.000067 0.000079 1996 5 21 50224 0.017040 0.594971 0.2544384 0.0016713 -0.000169 0.000175 0.000158 0.000139 0.0000076 0.0000158 0.000067 0.000078 1996 5 22 50225 0.020813 0.595338 0.2527849 0.0016793 0.000066 0.000139 0.000157 0.000139 0.0000074 0.0000158 0.000066 0.000078 1996 5 23 50226 0.025074 0.595204 0.2510444 0.0017182 0.000123 0.000108 0.000156 0.000138 0.0000092 0.0000156 0.000066 0.000076 1996 5 24 50227 0.029594 0.595211 0.2492465 0.0017207 0.000115 0.000078 0.000155 0.000137 0.0000118 0.0000155 0.000065 0.000075 1996 5 25 50228 0.034546 0.595537 0.2474090 0.0017927 0.000107 0.000049 0.000154 0.000136 0.0000149 0.0000153 0.000064 0.000073 1996 5 26 50229 0.039728 0.595810 0.2455576 0.0018964 0.000099 0.000020 0.000152 0.000135 0.0000190 0.0000150 0.000064 0.000072 1996 5 27 50230 0.044906 0.596108 0.2437118 0.0019395 0.000092 -0.000010 0.000152 0.000134 0.0000161 0.0000147 0.000063 0.000071 1996 5 28 50231 0.049957 0.596165 0.2418199 0.0019612 0.000084 -0.000039 0.000151 0.000133 0.0000132 0.0000144 0.000062 0.000070 1996 5 29 50232 0.054238 0.596638 0.2399153 0.0019621 0.000076 -0.000068 0.000150 0.000133 0.0000103 0.0000141 0.000062 0.000069 1996 5 30 50233 0.057727 0.596877 0.2379829 0.0019174 -0.000058 0.000008 0.000150 0.000132 0.0000084 0.0000138 0.000061 0.000067 1996 5 31 50234 0.061405 0.596829 0.2361091 0.0018245 -0.000248 -0.000001 0.000149 0.000131 0.0000069 0.0000134 0.000060 0.000066 1996 6 1 50235 0.065514 0.596424 0.2343358 0.0017238 -0.000292 -0.000022 0.000148 0.000130 0.0000057 0.0000130 0.000059 0.000065 1996 6 2 50236 0.070107 0.595691 0.2326485 0.0016569 -0.000226 -0.000009 0.000147 0.000130 0.0000048 0.0000127 0.000058 0.000064 1996 6 3 50237 0.074426 0.594806 0.2310012 0.0016492 -0.000160 0.000004 0.000146 0.000129 0.0000039 0.0000123 0.000058 0.000062 1996 6 4 50238 0.078516 0.594033 0.2293333 0.0017048 -0.000094 0.000017 0.000146 0.000129 0.0000030 0.0000121 0.000057 0.000061 1996 6 5 50239 0.082495 0.592569 0.2275819 0.0018014 0.000064 0.000107 0.000145 0.000129 0.0000067 0.0000118 0.000056 0.000060 1996 6 6 50240 0.086583 0.591218 0.2256308 0.0018963 -0.000002 0.000117 0.000144 0.000128 0.0000102 0.0000117 0.000055 0.000059 1996 6 7 50241 0.090902 0.590223 0.2236344 0.0019632 -0.000145 0.000097 0.000143 0.000128 0.0000112 0.0000115 0.000054 0.000058 1996 6 8 50242 0.094661 0.589364 0.2217782 0.0020182 -0.000288 0.000076 0.000141 0.000127 0.0000061 0.0000113 0.000054 0.000056 1996 6 9 50243 0.097965 0.588138 0.2197783 0.0020565 -0.000226 0.000066 0.000140 0.000126 0.0000057 0.0000111 0.000053 0.000056 1996 6 10 50244 0.101241 0.586672 0.2177248 0.0020379 -0.000062 0.000060 0.000139 0.000126 0.0000076 0.0000109 0.000053 0.000055 1996 6 11 50245 0.104908 0.585203 0.2157195 0.0019516 0.000103 0.000053 0.000138 0.000125 0.0000095 0.0000107 0.000053 0.000055 1996 6 12 50246 0.109072 0.583674 0.2138236 0.0018377 -0.000175 -0.000077 0.000137 0.000124 0.0000061 0.0000105 0.000053 0.000054 1996 6 13 50247 0.113462 0.582050 0.2120678 0.0016829 -0.000351 -0.000088 0.000136 0.000123 0.0000042 0.0000103 0.000053 0.000053 1996 6 14 50248 0.118041 0.580442 0.2104752 0.0014913 -0.000313 0.000036 0.000135 0.000122 0.0000029 0.0000101 0.000052 0.000052 1996 6 15 50249 0.122278 0.579007 0.2089496 0.0013590 -0.000208 0.000122 0.000134 0.000122 0.0000086 0.0000099 0.000052 0.000050 1996 6 16 50250 0.126492 0.577304 0.2074913 0.0012932 -0.000177 0.000089 0.000133 0.000121 0.0000183 0.0000097 0.000051 0.000049 1996 6 17 50251 0.130585 0.575409 0.2062321 0.0012310 -0.000146 0.000055 0.000133 0.000121 0.0000191 0.0000095 0.000051 0.000049 1996 6 18 50252 0.134550 0.573531 0.2050714 0.0011740 -0.000114 0.000021 0.000132 0.000120 0.0000169 0.0000093 0.000051 0.000048 1996 6 19 50253 0.137907 0.571463 0.2040540 0.0011920 -0.000083 -0.000013 0.000131 0.000119 0.0000063 0.0000091 0.000051 0.000047 1996 6 20 50254 0.141439 0.569591 0.2028543 0.0012868 -0.000023 -0.000001 0.000130 0.000118 0.0000043 0.0000089 0.000050 0.000046 1996 6 21 50255 0.145247 0.567577 0.2015149 0.0013909 0.000046 0.000025 0.000129 0.000117 0.0000052 0.0000087 0.000050 0.000045 1996 6 22 50256 0.149127 0.566014 0.2000775 0.0014961 0.000057 0.000032 0.000127 0.000116 0.0000037 0.0000085 0.000049 0.000044 1996 6 23 50257 0.153042 0.565097 0.1984433 0.0015833 -0.000066 -0.000009 0.000126 0.000115 0.0000107 0.0000083 0.000049 0.000045 1996 6 24 50258 0.156671 0.563922 0.1967574 0.0016037 -0.000189 -0.000051 0.000125 0.000114 0.0000181 0.0000081 0.000049 0.000045 1996 6 25 50259 0.160451 0.562539 0.1951491 0.0015610 -0.000312 -0.000092 0.000124 0.000113 0.0000194 0.0000078 0.000049 0.000045 1996 6 26 50260 0.163137 0.560569 0.1937697 0.0015067 -0.000212 -0.000004 0.000123 0.000111 0.0000057 0.0000076 0.000049 0.000044 1996 6 27 50261 0.166437 0.558019 0.1923134 0.0014657 -0.000140 0.000015 0.000121 0.000110 0.0000018 0.0000074 0.000048 0.000044 1996 6 28 50262 0.169478 0.555388 0.1908773 0.0014122 -0.000083 0.000007 0.000120 0.000109 0.0000013 0.0000074 0.000048 0.000043 1996 6 29 50263 0.172497 0.552499 0.1893752 0.0013237 -0.000108 0.000043 0.000120 0.000109 0.0000205 0.0000074 0.000048 0.000043 1996 6 30 50264 0.175821 0.549993 0.1880071 0.0012162 -0.000142 0.000083 0.000120 0.000110 0.0000352 0.0000075 0.000048 0.000043 1996 7 1 50265 0.179155 0.547431 0.1868351 0.0011500 -0.000175 0.000123 0.000121 0.000110 0.0000350 0.0000076 0.000048 0.000044 1996 7 2 50266 0.182335 0.544781 0.1857271 0.0011677 -0.000209 0.000163 0.000121 0.000110 0.0000298 0.0000077 0.000048 0.000044 1996 7 3 50267 0.185326 0.542024 0.1846664 0.0012572 -0.000242 0.000203 0.000121 0.000110 0.0000131 0.0000077 0.000049 0.000044 1996 7 4 50268 0.188352 0.539018 0.1833597 0.0013719 -0.000238 0.000197 0.000121 0.000110 0.0000098 0.0000077 0.000049 0.000044 1996 7 5 50269 0.191742 0.536120 0.1819033 0.0014573 -0.000221 0.000176 0.000120 0.000110 0.0000110 0.0000077 0.000048 0.000044 1996 7 6 50270 0.195599 0.533201 0.1803935 0.0014757 -0.000204 0.000155 0.000119 0.000110 0.0000122 0.0000076 0.000048 0.000044 1996 7 7 50271 0.199733 0.530974 0.1789038 0.0014171 -0.000188 0.000134 0.000119 0.000109 0.0000134 0.0000076 0.000048 0.000043 1996 7 8 50272 0.203960 0.528873 0.1775023 0.0012979 -0.000171 0.000113 0.000118 0.000109 0.0000146 0.0000076 0.000048 0.000043 1996 7 9 50273 0.207801 0.526877 0.1762889 0.0011550 -0.000154 0.000092 0.000117 0.000108 0.0000129 0.0000075 0.000048 0.000043 1996 7 10 50274 0.211308 0.524406 0.1753379 0.0010327 -0.000137 0.000071 0.000115 0.000108 0.0000051 0.0000074 0.000048 0.000043 1996 7 11 50275 0.215176 0.521779 0.1743816 0.0009459 -0.000167 0.000015 0.000113 0.000106 0.0000024 0.0000073 0.000048 0.000042 1996 7 12 50276 0.219119 0.518630 0.1734698 0.0008813 -0.000213 -0.000051 0.000112 0.000105 0.0000014 0.0000074 0.000048 0.000041 1996 7 13 50277 0.221504 0.515568 0.1724909 0.0008309 -0.000218 -0.000022 0.000113 0.000106 0.0000156 0.0000074 0.000048 0.000042 1996 7 14 50278 0.224938 0.512996 0.1716041 0.0008056 -0.000215 0.000027 0.000114 0.000106 0.0000242 0.0000075 0.000049 0.000043 1996 7 15 50279 0.227686 0.509796 0.1708832 0.0008299 -0.000212 0.000076 0.000115 0.000107 0.0000157 0.0000077 0.000049 0.000044 1996 7 16 50280 0.230643 0.506645 0.1701199 0.0009032 -0.000209 0.000125 0.000116 0.000107 0.0000073 0.0000078 0.000050 0.000045 1996 7 17 50281 0.233139 0.503472 0.1691754 0.0009771 -0.000022 0.000209 0.000117 0.000107 0.0000043 0.0000079 0.000050 0.000046 1996 7 18 50282 0.235355 0.500811 0.1681655 0.0010560 -0.000081 0.000150 0.000117 0.000107 0.0000095 0.0000080 0.000051 0.000046 1996 7 19 50283 0.237343 0.498136 0.1669495 0.0011566 -0.000112 0.000109 0.000117 0.000107 0.0000255 0.0000080 0.000051 0.000046 1996 7 20 50284 0.239147 0.495271 0.1656519 0.0012303 -0.000086 0.000102 0.000117 0.000107 0.0000394 0.0000080 0.000051 0.000046 1996 7 21 50285 0.240112 0.492367 0.1644370 0.0012699 -0.000060 0.000095 0.000117 0.000106 0.0000357 0.0000079 0.000051 0.000046 1996 7 22 50286 0.241114 0.489317 0.1632390 0.0012986 -0.000035 0.000087 0.000117 0.000106 0.0000199 0.0000078 0.000051 0.000046 1996 7 23 50287 0.242456 0.486305 0.1620116 0.0013221 -0.000009 0.000080 0.000116 0.000105 0.0000040 0.0000077 0.000051 0.000046 1996 7 24 50288 0.244027 0.483754 0.1606875 0.0013355 -0.000168 -0.000082 0.000116 0.000104 0.0000080 0.0000076 0.000051 0.000045 1996 7 25 50289 0.245361 0.481172 0.1593493 0.0013256 -0.000174 -0.000060 0.000115 0.000104 0.0000060 0.0000075 0.000051 0.000045 1996 7 26 50290 0.246954 0.478230 0.1580366 0.0012874 -0.000122 0.000029 0.000114 0.000103 0.0000015 0.0000075 0.000051 0.000044 1996 7 27 50291 0.248740 0.475003 0.1566386 0.0012450 -0.000139 0.000049 0.000116 0.000104 0.0000121 0.0000076 0.000051 0.000045 1996 7 28 50292 0.250693 0.471833 0.1553363 0.0012398 -0.000163 0.000063 0.000117 0.000105 0.0000181 0.0000078 0.000052 0.000046 1996 7 29 50293 0.252759 0.469041 0.1541416 0.0013016 -0.000186 0.000076 0.000119 0.000107 0.0000139 0.0000081 0.000053 0.000047 1996 7 30 50294 0.254546 0.466581 0.1528402 0.0014366 -0.000210 0.000090 0.000120 0.000108 0.0000097 0.0000083 0.000053 0.000048 1996 7 31 50295 0.256143 0.463863 0.1513768 0.0016175 -0.000233 0.000104 0.000122 0.000109 0.0000056 0.0000085 0.000054 0.000049 1996 8 1 50296 0.257703 0.460832 0.1497002 0.0017644 -0.000233 0.000121 0.000123 0.000110 0.0000050 0.0000087 0.000054 0.000050 1996 8 2 50297 0.259350 0.457621 0.1479235 0.0017898 -0.000224 0.000138 0.000124 0.000111 0.0000056 0.0000089 0.000055 0.000051 1996 8 3 50298 0.260720 0.454073 0.1461841 0.0016781 -0.000216 0.000156 0.000125 0.000112 0.0000063 0.0000091 0.000055 0.000051 1996 8 4 50299 0.262199 0.450035 0.1445885 0.0014853 -0.000207 0.000173 0.000126 0.000113 0.0000069 0.0000093 0.000056 0.000052 1996 8 5 50300 0.263375 0.445941 0.1431920 0.0012830 -0.000199 0.000191 0.000127 0.000114 0.0000076 0.0000094 0.000056 0.000053 1996 8 6 50301 0.265143 0.441838 0.1419970 0.0011016 -0.000190 0.000208 0.000128 0.000115 0.0000082 0.0000095 0.000057 0.000054 1996 8 7 50302 0.267322 0.437835 0.1409772 0.0009326 -0.000182 0.000226 0.000129 0.000116 0.0000089 0.0000095 0.000057 0.000055 1996 8 8 50303 0.269809 0.433558 0.1401061 0.0008387 -0.000448 0.000077 0.000130 0.000116 0.0000094 0.0000095 0.000057 0.000056 1996 8 9 50304 0.272679 0.430227 0.1393568 0.0007464 -0.000557 0.000034 0.000130 0.000117 0.0000092 0.0000095 0.000057 0.000056 1996 8 10 50305 0.274535 0.426712 0.1387027 0.0005874 -0.000541 0.000074 0.000129 0.000116 0.0000087 0.0000094 0.000057 0.000055 1996 8 11 50306 0.276131 0.422881 0.1380790 0.0005991 -0.000493 0.000107 0.000129 0.000116 0.0000083 0.0000092 0.000056 0.000055 1996 8 12 50307 0.277817 0.419508 0.1373771 0.0007473 -0.000286 0.000109 0.000128 0.000116 0.0000080 0.0000091 0.000056 0.000054 1996 8 13 50308 0.279763 0.416006 0.1365916 0.0008141 -0.000079 0.000111 0.000127 0.000115 0.0000078 0.0000089 0.000055 0.000053 1996 8 14 50309 0.282010 0.412442 0.1357654 0.0008817 -0.000128 -0.000009 0.000126 0.000114 0.0000068 0.0000087 0.000054 0.000052 1996 8 15 50310 0.284223 0.408986 0.1348019 0.0009560 -0.000130 -0.000041 0.000124 0.000113 0.0000155 0.0000085 0.000053 0.000051 1996 8 16 50311 0.286291 0.405569 0.1337336 0.0010166 -0.000114 -0.000042 0.000123 0.000112 0.0000275 0.0000082 0.000052 0.000049 1996 8 17 50312 0.287472 0.401866 0.1326158 0.0011575 -0.000097 -0.000042 0.000121 0.000111 0.0000313 0.0000080 0.000051 0.000048 1996 8 18 50313 0.288488 0.398159 0.1314810 0.0012402 -0.000080 -0.000043 0.000119 0.000110 0.0000245 0.0000077 0.000050 0.000047 1996 8 19 50314 0.289954 0.394531 0.1303296 0.0011836 -0.000064 -0.000043 0.000117 0.000108 0.0000177 0.0000074 0.000049 0.000045 1996 8 20 50315 0.291239 0.391241 0.1292075 0.0011083 -0.000047 -0.000044 0.000115 0.000107 0.0000109 0.0000072 0.000049 0.000044 1996 8 21 50316 0.292594 0.387595 0.1281174 0.0010892 -0.000030 -0.000044 0.000113 0.000106 0.0000040 0.0000069 0.000048 0.000043 1996 8 22 50317 0.293892 0.384086 0.1270007 0.0011367 -0.000020 -0.000056 0.000111 0.000104 0.0000023 0.0000067 0.000047 0.000042 1996 8 23 50318 0.295049 0.380632 0.1258661 0.0011644 -0.000013 -0.000072 0.000109 0.000103 0.0000022 0.0000065 0.000046 0.000041 1996 8 24 50319 0.295966 0.377364 0.1247319 0.0011317 -0.000006 -0.000088 0.000106 0.000101 0.0000022 0.0000062 0.000046 0.000041 1996 8 25 50320 0.296949 0.373773 0.1235906 0.0011401 0.000002 -0.000103 0.000104 0.000099 0.0000021 0.0000060 0.000045 0.000040 1996 8 26 50321 0.297164 0.369961 0.1223941 0.0012378 0.000009 -0.000119 0.000101 0.000097 0.0000020 0.0000057 0.000044 0.000039 1996 8 27 50322 0.297612 0.365267 0.1210726 0.0013935 0.000016 -0.000135 0.000099 0.000095 0.0000020 0.0000055 0.000044 0.000039 1996 8 28 50323 0.297418 0.361491 0.1195905 0.0015873 -0.000010 -0.000001 0.000097 0.000094 0.0000041 0.0000053 0.000044 0.000039 1996 8 29 50324 0.298121 0.356755 0.1179151 0.0017602 -0.000145 0.000137 0.000095 0.000092 0.0000164 0.0000052 0.000043 0.000038 1996 8 30 50325 0.298193 0.352243 0.1160462 0.0018354 -0.000210 0.000168 0.000096 0.000092 0.0000214 0.0000051 0.000043 0.000039 1996 8 31 50326 0.297764 0.348022 0.1141306 0.0017834 -0.000222 0.000147 0.000098 0.000094 0.0000211 0.0000050 0.000044 0.000039 1996 9 1 50327 0.297388 0.343489 0.1123602 0.0016288 -0.000235 0.000126 0.000100 0.000095 0.0000191 0.0000050 0.000044 0.000040 1996 9 2 50328 0.296898 0.339120 0.1109188 0.0014314 -0.000248 0.000105 0.000101 0.000096 0.0000110 0.0000049 0.000044 0.000041 1996 9 3 50329 0.296547 0.334684 0.1096726 0.0012485 -0.000260 0.000084 0.000103 0.000096 0.0000029 0.0000049 0.000044 0.000042 1996 9 4 50330 0.295907 0.330542 0.1085167 0.0011018 -0.000048 0.000157 0.000104 0.000097 0.0000024 0.0000048 0.000044 0.000043 1996 9 5 50331 0.295405 0.326333 0.1074755 0.0009907 0.000091 0.000196 0.000105 0.000098 0.0000018 0.0000048 0.000044 0.000043 1996 9 6 50332 0.294712 0.322367 0.1065211 0.0009377 0.000077 0.000121 0.000107 0.000098 0.0000018 0.0000048 0.000044 0.000044 1996 9 7 50333 0.294118 0.318238 0.1055842 0.0009379 0.000027 0.000157 0.000108 0.000099 0.0000015 0.0000048 0.000044 0.000044 1996 9 8 50334 0.293492 0.314351 0.1046003 0.0009649 -0.000046 0.000143 0.000109 0.000100 0.0000077 0.0000048 0.000044 0.000044 1996 9 9 50335 0.292791 0.310825 0.1035391 0.0010428 -0.000135 0.000067 0.000110 0.000100 0.0000172 0.0000048 0.000044 0.000044 1996 9 10 50336 0.292375 0.306884 0.1024020 0.0011922 -0.000225 -0.000010 0.000111 0.000101 0.0000211 0.0000048 0.000044 0.000045 1996 9 11 50337 0.292117 0.303105 0.1012257 0.0013995 -0.000135 0.000072 0.000112 0.000101 0.0000090 0.0000048 0.000044 0.000044 1996 9 12 50338 0.291534 0.299647 0.0997393 0.0016152 -0.000002 0.000121 0.000112 0.000100 0.0000059 0.0000047 0.000043 0.000044 1996 9 13 50339 0.290423 0.296056 0.0979470 0.0017539 0.000065 0.000122 0.000112 0.000100 0.0000176 0.0000047 0.000043 0.000043 1996 9 14 50340 0.289111 0.292459 0.0960553 0.0017903 0.000094 0.000108 0.000112 0.000100 0.0000273 0.0000046 0.000042 0.000043 1996 9 15 50341 0.287701 0.288498 0.0942849 0.0017969 0.000123 0.000094 0.000112 0.000099 0.0000171 0.0000045 0.000042 0.000042 1996 9 16 50342 0.286078 0.283949 0.0925624 0.0017813 0.000152 0.000080 0.000111 0.000098 0.0000097 0.0000044 0.000041 0.000041 1996 9 17 50343 0.284714 0.279428 0.0908955 0.0017084 0.000181 0.000066 0.000110 0.000097 0.0000023 0.0000043 0.000041 0.000041 1996 9 18 50344 0.283695 0.275287 0.0892481 0.0016233 -0.000012 0.000005 0.000110 0.000096 0.0000015 0.0000042 0.000041 0.000040 1996 9 19 50345 0.283061 0.271335 0.0876538 0.0015732 -0.000018 -0.000034 0.000109 0.000096 0.0000017 0.0000042 0.000040 0.000040 1996 9 20 50346 0.282477 0.267217 0.0860870 0.0015727 0.000077 -0.000091 0.000108 0.000095 0.0000013 0.0000041 0.000040 0.000040 1996 9 21 50347 0.282027 0.263751 0.0844936 0.0016270 0.000042 -0.000039 0.000107 0.000095 0.0000204 0.0000041 0.000040 0.000039 1996 9 22 50348 0.281440 0.260737 0.0828212 0.0017395 0.000011 0.000036 0.000107 0.000095 0.0000250 0.0000042 0.000040 0.000040 1996 9 23 50349 0.280469 0.257606 0.0810038 0.0019095 0.000015 0.000093 0.000107 0.000095 0.0000174 0.0000042 0.000040 0.000040 1996 9 24 50350 0.278810 0.254141 0.0789943 0.0021088 0.000016 0.000133 0.000106 0.000095 0.0000100 0.0000042 0.000040 0.000040 1996 9 25 50351 0.277052 0.250267 0.0767917 0.0022812 -0.000011 0.000056 0.000105 0.000095 0.0000042 0.0000043 0.000040 0.000040 1996 9 26 50352 0.275567 0.246327 0.0743384 0.0023847 -0.000038 0.000063 0.000103 0.000094 0.0000097 0.0000043 0.000039 0.000040 1996 9 27 50353 0.273746 0.242742 0.0718550 0.0023719 -0.000064 0.000098 0.000101 0.000093 0.0000183 0.0000043 0.000039 0.000040 1996 9 28 50354 0.272097 0.238704 0.0695970 0.0022134 -0.000091 0.000133 0.000099 0.000091 0.0000189 0.0000043 0.000039 0.000040 1996 9 29 50355 0.270495 0.234787 0.0676055 0.0020331 -0.000118 0.000168 0.000097 0.000090 0.0000061 0.0000042 0.000038 0.000039 1996 9 30 50356 0.268754 0.231585 0.0656566 0.0019250 -0.000132 0.000126 0.000096 0.000089 0.0000016 0.0000042 0.000038 0.000039 1996 10 1 50357 0.267262 0.228236 0.0637812 0.0018353 -0.000140 0.000045 0.000096 0.000089 0.0000012 0.0000041 0.000038 0.000040 1996 10 2 50358 0.265697 0.224403 0.0619960 0.0017218 -0.000012 0.000141 0.000095 0.000088 0.0000022 0.0000041 0.000038 0.000040 1996 10 3 50359 0.263766 0.220638 0.0603333 0.0016095 0.000045 0.000205 0.000094 0.000087 0.0000017 0.0000041 0.000038 0.000040 1996 10 4 50360 0.261665 0.216672 0.0587594 0.0015566 0.000060 0.000239 0.000093 0.000086 0.0000014 0.0000041 0.000038 0.000040 1996 10 5 50361 0.259713 0.213120 0.0572011 0.0015706 0.000028 0.000203 0.000092 0.000086 0.0000206 0.0000041 0.000038 0.000040 1996 10 6 50362 0.257976 0.209653 0.0556094 0.0016220 0.000003 0.000154 0.000091 0.000085 0.0000260 0.0000041 0.000038 0.000041 1996 10 7 50363 0.255969 0.206251 0.0539557 0.0016932 -0.000018 0.000099 0.000090 0.000085 0.0000200 0.0000042 0.000038 0.000041 1996 10 8 50364 0.254122 0.203187 0.0522173 0.0017776 -0.000040 0.000043 0.000089 0.000084 0.0000139 0.0000042 0.000038 0.000042 1996 10 9 50365 0.251939 0.200621 0.0503936 0.0018818 -0.000132 0.000103 0.000088 0.000083 0.0000080 0.0000042 0.000038 0.000042 1996 10 10 50366 0.249688 0.197940 0.0484548 0.0019914 -0.000199 0.000159 0.000087 0.000082 0.0000062 0.0000043 0.000037 0.000042 1996 10 11 50367 0.247224 0.195128 0.0464150 0.0020692 -0.000252 0.000209 0.000085 0.000081 0.0000061 0.0000043 0.000037 0.000041 1996 10 12 50368 0.244733 0.191897 0.0442034 0.0021109 -0.000232 0.000211 0.000084 0.000080 0.0000133 0.0000043 0.000037 0.000041 1996 10 13 50369 0.242356 0.188784 0.0420290 0.0021234 -0.000211 0.000213 0.000082 0.000079 0.0000157 0.0000042 0.000036 0.000040 1996 10 14 50370 0.239973 0.185829 0.0399945 0.0020982 -0.000190 0.000215 0.000080 0.000078 0.0000090 0.0000042 0.000036 0.000040 1996 10 15 50371 0.237312 0.182950 0.0380065 0.0020376 -0.000170 0.000217 0.000078 0.000077 0.0000023 0.0000041 0.000035 0.000040 1996 10 16 50372 0.234931 0.180016 0.0360153 0.0019665 0.000008 0.000272 0.000077 0.000075 0.0000028 0.0000041 0.000035 0.000039 1996 10 17 50373 0.232973 0.177439 0.0340776 0.0019044 0.000060 0.000239 0.000074 0.000074 0.0000019 0.0000041 0.000034 0.000039 1996 10 18 50374 0.230339 0.174807 0.0321905 0.0018886 0.000067 0.000178 0.000072 0.000072 0.0000012 0.0000041 0.000034 0.000038 1996 10 19 50375 0.227635 0.172102 0.0302758 0.0019652 0.000129 0.000138 0.000070 0.000071 0.0000013 0.0000041 0.000033 0.000037 1996 10 20 50376 0.224980 0.169436 0.0281919 0.0021000 0.000115 0.000166 0.000068 0.000070 0.0000062 0.0000041 0.000033 0.000037 1996 10 21 50377 0.222691 0.166859 0.0259505 0.0022151 0.000064 0.000227 0.000066 0.000068 0.0000135 0.0000041 0.000032 0.000036 1996 10 22 50378 0.220224 0.164530 0.0236834 0.0022935 0.000013 0.000289 0.000064 0.000067 0.0000148 0.0000041 0.000032 0.000036 1996 10 23 50379 0.217429 0.161738 0.0214674 0.0023961 0.000035 0.000183 0.000062 0.000065 0.0000060 0.0000041 0.000031 0.000035 1996 10 24 50380 0.214360 0.159135 0.0189300 0.0024726 0.000046 0.000142 0.000060 0.000063 0.0000110 0.0000041 0.000031 0.000034 1996 10 25 50381 0.211077 0.156221 0.0163773 0.0024244 0.000052 0.000124 0.000058 0.000062 0.0000185 0.0000041 0.000030 0.000033 1996 10 26 50382 0.208349 0.152849 0.0140161 0.0023034 0.000059 0.000106 0.000056 0.000060 0.0000275 0.0000040 0.000029 0.000032 1996 10 27 50383 0.206482 0.149776 0.0117851 0.0021515 0.000066 0.000089 0.000054 0.000058 0.0000347 0.0000039 0.000029 0.000031 1996 10 28 50384 0.204802 0.146922 0.0097234 0.0019671 0.000073 0.000071 0.000052 0.000056 0.0000263 0.0000038 0.000028 0.000030 1996 10 29 50385 0.202702 0.144227 0.0078744 0.0017904 0.000079 0.000053 0.000050 0.000054 0.0000172 0.0000038 0.000027 0.000029 1996 10 30 50386 0.199953 0.141287 0.0062882 0.0016786 0.000086 0.000036 0.000048 0.000052 0.0000056 0.0000037 0.000027 0.000028 1996 10 31 50387 0.197288 0.138200 0.0046692 0.0016345 0.000102 0.000183 0.000046 0.000051 0.0000216 0.0000036 0.000026 0.000028 1996 11 1 50388 0.194396 0.135295 0.0029561 0.0016229 0.000124 0.000209 0.000044 0.000049 0.0000204 0.0000035 0.000026 0.000027 1996 11 2 50389 0.191462 0.132336 0.0012215 0.0016498 0.000146 0.000148 0.000043 0.000048 0.0000105 0.0000035 0.000026 0.000027 1996 11 3 50390 0.188567 0.129496 -0.0004408 0.0017369 0.000169 0.000086 0.000042 0.000047 0.0000128 0.0000034 0.000026 0.000027 1996 11 4 50391 0.185288 0.126949 -0.0021615 0.0018630 0.000192 0.000025 0.000041 0.000046 0.0000077 0.0000034 0.000025 0.000027 1996 11 5 50392 0.181830 0.124651 -0.0040101 0.0019971 0.000126 0.000136 0.000040 0.000045 0.0000026 0.0000033 0.000025 0.000027 1996 11 6 50393 0.178251 0.122931 -0.0060574 0.0021034 0.000030 0.000154 0.000038 0.000043 0.0000027 0.0000032 0.000025 0.000026 1996 11 7 50394 0.174149 0.121086 -0.0081954 0.0021629 -0.000035 0.000127 0.000037 0.000042 0.0000018 0.0000031 0.000024 0.000026 1996 11 8 50395 0.169869 0.119313 -0.0103798 0.0021858 -0.000031 0.000100 0.000035 0.000040 0.0000013 0.0000030 0.000024 0.000025 1996 11 9 50396 0.166089 0.117324 -0.0125557 0.0021627 -0.000017 0.000095 0.000034 0.000039 0.0000146 0.0000030 0.000023 0.000024 1996 11 10 50397 0.162457 0.115225 -0.0146887 0.0021091 -0.000016 0.000092 0.000034 0.000038 0.0000212 0.0000029 0.000023 0.000024 1996 11 11 50398 0.158750 0.113624 -0.0167756 0.0020619 -0.000017 0.000087 0.000033 0.000038 0.0000212 0.0000029 0.000023 0.000023 1996 11 12 50399 0.154662 0.112446 -0.0188167 0.0020319 -0.000019 0.000081 0.000032 0.000037 0.0000212 0.0000029 0.000023 0.000023 1996 11 13 50400 0.150474 0.111046 -0.0208398 0.0019941 -0.000020 -0.000051 0.000032 0.000037 0.0000062 0.0000028 0.000023 0.000023 1996 11 14 50401 0.146087 0.110029 -0.0228085 0.0019223 -0.000007 -0.000045 0.000032 0.000037 0.0000153 0.0000028 0.000023 0.000023 1996 11 15 50402 0.141265 0.108483 -0.0246921 0.0018524 0.000051 0.000040 0.000033 0.000038 0.0000212 0.0000028 0.000023 0.000023 1996 11 16 50403 0.137148 0.106407 -0.0265373 0.0018733 0.000121 0.000085 0.000034 0.000039 0.0000212 0.0000029 0.000023 0.000024 1996 11 17 50404 0.134028 0.104467 -0.0285159 0.0019855 0.000100 0.000104 0.000035 0.000040 0.0000204 0.0000029 0.000023 0.000024 1996 11 18 50405 0.131132 0.102858 -0.0306272 0.0020849 0.000051 0.000128 0.000037 0.000042 0.0000192 0.0000030 0.000024 0.000025 1996 11 19 50406 0.128042 0.101560 -0.0327559 0.0021260 0.000002 0.000152 0.000038 0.000043 0.0000160 0.0000031 0.000024 0.000025 1996 11 20 50407 0.124794 0.100518 -0.0347691 0.0021510 -0.000047 0.000176 0.000040 0.000045 0.0000074 0.0000032 0.000024 0.000026 1996 11 21 50408 0.121882 0.099367 -0.0368905 0.0021383 0.000069 0.000109 0.000041 0.000046 0.0000139 0.0000033 0.000025 0.000027 1996 11 22 50409 0.119239 0.098811 -0.0389898 0.0020475 0.000103 0.000107 0.000043 0.000048 0.0000252 0.0000033 0.000025 0.000027 1996 11 23 50410 0.116009 0.098247 -0.0410687 0.0019195 0.000091 0.000113 0.000044 0.000049 0.0000235 0.0000034 0.000025 0.000027 1996 11 24 50411 0.112580 0.097046 -0.0430086 0.0017917 0.000099 0.000089 0.000046 0.000051 0.0000140 0.0000035 0.000025 0.000028 1996 11 25 50412 0.108823 0.095823 -0.0446610 0.0016839 0.000107 0.000066 0.000047 0.000053 0.0000085 0.0000036 0.000025 0.000028 1996 11 26 50413 0.105199 0.094856 -0.0462227 0.0016121 0.000115 0.000042 0.000049 0.000054 0.0000030 0.0000036 0.000026 0.000029 1996 11 27 50414 0.101363 0.094571 -0.0478027 0.0015785 0.000212 0.000073 0.000050 0.000056 0.0000025 0.0000037 0.000026 0.000029 1996 11 28 50415 0.097292 0.094342 -0.0494254 0.0015759 0.000222 0.000070 0.000052 0.000057 0.0000038 0.0000038 0.000026 0.000030 1996 11 29 50416 0.093637 0.093814 -0.0510723 0.0015940 0.000197 0.000052 0.000053 0.000058 0.0000053 0.0000038 0.000026 0.000030 1996 11 30 50417 0.089314 0.093114 -0.0527426 0.0016239 0.000171 0.000034 0.000054 0.000059 0.0000068 0.0000039 0.000026 0.000030 1996 12 1 50418 0.085664 0.092492 -0.0543977 0.0016587 0.000146 0.000016 0.000054 0.000060 0.0000071 0.0000039 0.000026 0.000031 1996 12 2 50419 0.082255 0.091569 -0.0559893 0.0016929 0.000121 -0.000002 0.000055 0.000060 0.0000050 0.0000039 0.000026 0.000031 1996 12 3 50420 0.078706 0.090827 -0.0576172 0.0017247 0.000096 -0.000020 0.000055 0.000060 0.0000029 0.0000040 0.000026 0.000031 1996 12 4 50421 0.074878 0.090699 -0.0593399 0.0017579 0.000147 -0.000024 0.000055 0.000060 0.0000059 0.0000040 0.000026 0.000032 1996 12 5 50422 0.071005 0.089940 -0.0611177 0.0018106 0.000060 0.000044 0.000055 0.000060 0.0000229 0.0000040 0.000026 0.000031 1996 12 6 50423 0.066445 0.089363 -0.0630466 0.0018376 -0.000150 0.000077 0.000056 0.000061 0.0000211 0.0000041 0.000026 0.000032 1996 12 7 50424 0.062144 0.088450 -0.0649652 0.0017844 -0.000190 0.000085 0.000059 0.000064 0.0000107 0.0000042 0.000027 0.000033 1996 12 8 50425 0.058482 0.087480 -0.0666895 0.0017081 -0.000081 0.000097 0.000061 0.000066 0.0000075 0.0000044 0.000027 0.000034 1996 12 9 50426 0.054631 0.086654 -0.0682805 0.0016517 0.000027 0.000109 0.000063 0.000068 0.0000082 0.0000046 0.000028 0.000035 1996 12 10 50427 0.050644 0.085777 -0.0698234 0.0016203 0.000136 0.000121 0.000065 0.000070 0.0000090 0.0000048 0.000028 0.000036 1996 12 11 50428 0.046662 0.085325 -0.0714464 0.0016475 0.000102 -0.000015 0.000068 0.000072 0.0000035 0.0000049 0.000029 0.000036 1996 12 12 50429 0.042837 0.085008 -0.0732271 0.0016975 0.000079 -0.000041 0.000070 0.000074 0.0000069 0.0000051 0.000029 0.000037 1996 12 13 50430 0.039541 0.084945 -0.0750462 0.0017648 0.000063 -0.000027 0.000072 0.000075 0.0000116 0.0000053 0.000030 0.000038 1996 12 14 50431 0.036687 0.085023 -0.0768655 0.0019112 0.000047 -0.000013 0.000074 0.000077 0.0000135 0.0000055 0.000030 0.000038 1996 12 15 50432 0.033906 0.085701 -0.0788290 0.0020393 0.000030 0.000001 0.000077 0.000079 0.0000147 0.0000057 0.000031 0.000039 1996 12 16 50433 0.030793 0.086489 -0.0808387 0.0020988 0.000014 0.000015 0.000079 0.000081 0.0000120 0.0000059 0.000031 0.000040 1996 12 17 50434 0.027658 0.087199 -0.0829226 0.0021512 -0.000002 0.000030 0.000081 0.000083 0.0000094 0.0000061 0.000032 0.000041 1996 12 18 50435 0.024614 0.087899 -0.0850407 0.0021882 -0.000018 0.000044 0.000083 0.000084 0.0000067 0.0000063 0.000032 0.000043 1996 12 19 50436 0.021460 0.088663 -0.0873161 0.0021552 -0.000048 0.000041 0.000085 0.000085 0.0000090 0.0000065 0.000033 0.000043 1996 12 20 50437 0.018243 0.089341 -0.0895014 0.0020270 -0.000081 0.000034 0.000087 0.000087 0.0000124 0.0000067 0.000033 0.000044 1996 12 21 50438 0.015068 0.089855 -0.0914507 0.0018829 -0.000115 0.000026 0.000089 0.000088 0.0000149 0.0000069 0.000034 0.000045 1996 12 22 50439 0.012121 0.090507 -0.0932604 0.0017929 -0.000149 0.000018 0.000090 0.000089 0.0000166 0.0000072 0.000035 0.000047 1996 12 23 50440 0.009810 0.091068 -0.0949526 0.0017535 -0.000183 0.000010 0.000092 0.000090 0.0000171 0.0000074 0.000035 0.000048 1996 12 24 50441 0.007471 0.091455 -0.0966158 0.0017443 -0.000216 0.000002 0.000094 0.000091 0.0000177 0.0000076 0.000036 0.000049 1996 12 25 50442 0.004941 0.092056 -0.0983537 0.0017495 -0.000177 0.000003 0.000095 0.000092 0.0000163 0.0000078 0.000036 0.000049 1996 12 26 50443 0.001573 0.092526 -0.1001064 0.0017560 -0.000131 0.000005 0.000096 0.000093 0.0000147 0.0000080 0.000037 0.000050 1996 12 27 50444 -0.002136 0.092633 -0.1018634 0.0017585 -0.000084 0.000007 0.000097 0.000093 0.0000131 0.0000082 0.000037 0.000050 1996 12 28 50445 -0.006040 0.092916 -0.1036224 0.0017633 -0.000038 0.000009 0.000098 0.000094 0.0000115 0.0000085 0.000038 0.000051 1996 12 29 50446 -0.010231 0.093194 -0.1053924 0.0017833 0.000008 0.000011 0.000099 0.000094 0.0000099 0.0000087 0.000038 0.000051 1996 12 30 50447 -0.014563 0.094092 -0.1071954 0.0018272 0.000054 0.000013 0.000101 0.000095 0.0000083 0.0000090 0.000039 0.000052 1996 12 31 50448 -0.019404 0.094900 -0.1090580 0.0018923 0.000101 0.000015 0.000102 0.000095 0.0000067 0.0000093 0.000040 0.000052 1997 1 1 50449 -0.023298 0.095306 -0.1110612 0.0019692 0.000118 0.000010 0.000107 0.000099 0.0000155 0.0000161 0.000070 0.000033 1997 1 2 50450 -0.026982 0.095777 -0.1131505 0.0019986 0.000126 0.000003 0.000106 0.000098 0.0000234 0.0000308 0.000069 0.000033 1997 1 3 50451 -0.030417 0.096625 -0.1152534 0.0019527 0.000134 -0.000004 0.000105 0.000097 0.0000269 0.0000309 0.000069 0.000032 1997 1 4 50452 -0.033699 0.097893 -0.1172662 0.0019396 0.000142 -0.000012 0.000104 0.000096 0.0000173 0.0000310 0.000068 0.000031 1997 1 5 50453 -0.036668 0.099330 -0.1191296 0.0019022 0.000150 -0.000019 0.000103 0.000095 0.0000116 0.0000312 0.000068 0.000031 1997 1 6 50454 -0.040237 0.101065 -0.1210321 0.0018426 0.000158 -0.000026 0.000102 0.000095 0.0000141 0.0000313 0.000067 0.000030 1997 1 7 50455 -0.044130 0.102350 -0.1228600 0.0018449 0.000166 -0.000033 0.000101 0.000094 0.0000145 0.0000315 0.000067 0.000030 1997 1 8 50456 -0.047504 0.103467 -0.1245484 0.0018670 0.000174 -0.000040 0.000099 0.000092 0.0000087 0.0000317 0.000066 0.000030 1997 1 9 50457 -0.050420 0.104542 -0.1263897 0.0019179 0.000233 0.000006 0.000097 0.000091 0.0000049 0.0000318 0.000066 0.000029 1997 1 10 50458 -0.053131 0.105761 -0.1283615 0.0020086 0.000201 -0.000040 0.000095 0.000089 0.0000056 0.0000321 0.000065 0.000028 1997 1 11 50459 -0.055899 0.106979 -0.1304355 0.0021171 0.000116 -0.000107 0.000094 0.000088 0.0000073 0.0000323 0.000064 0.000027 1997 1 12 50460 -0.058965 0.108135 -0.1326042 0.0021719 -0.000012 -0.000082 0.000092 0.000086 0.0000077 0.0000325 0.000063 0.000027 1997 1 13 50461 -0.061883 0.109401 -0.1349160 0.0022543 -0.000019 -0.000057 0.000090 0.000085 0.0000133 0.0000327 0.000062 0.000026 1997 1 14 50462 -0.064111 0.110753 -0.1371893 0.0022441 -0.000027 -0.000031 0.000088 0.000083 0.0000151 0.0000330 0.000062 0.000025 1997 1 15 50463 -0.066084 0.112452 -0.1392693 0.0021497 -0.000035 -0.000006 0.000086 0.000081 0.0000063 0.0000332 0.000061 0.000025 1997 1 16 50464 -0.067949 0.114404 -0.1414570 0.0020332 -0.000002 -0.000001 0.000083 0.000079 0.0000046 0.0000336 0.000060 0.000024 1997 1 17 50465 -0.069841 0.116555 -0.1435495 0.0019125 0.000045 -0.000003 0.000081 0.000078 0.0000064 0.0000339 0.000059 0.000023 1997 1 18 50466 -0.071836 0.118548 -0.1453861 0.0017201 0.000092 -0.000005 0.000079 0.000076 0.0000084 0.0000343 0.000059 0.000022 1997 1 19 50467 -0.073898 0.120557 -0.1470309 0.0015808 0.000140 -0.000007 0.000077 0.000074 0.0000054 0.0000347 0.000058 0.000022 1997 1 20 50468 -0.076470 0.122868 -0.1485806 0.0014730 0.000187 -0.000010 0.000074 0.000072 0.0000063 0.0000350 0.000057 0.000021 1997 1 21 50469 -0.079658 0.124902 -0.1499931 0.0014397 0.000234 -0.000012 0.000072 0.000070 0.0000062 0.0000354 0.000056 0.000021 1997 1 22 50470 -0.082395 0.126707 -0.1512455 0.0014212 0.000281 -0.000014 0.000070 0.000068 0.0000039 0.0000358 0.000055 0.000020 1997 1 23 50471 -0.084905 0.128723 -0.1526448 0.0014624 0.000081 0.000042 0.000068 0.000066 0.0000027 0.0000361 0.000055 0.000019 1997 1 24 50472 -0.087540 0.130459 -0.1542306 0.0015042 0.000020 0.000045 0.000065 0.000064 0.0000052 0.0000364 0.000054 0.000019 1997 1 25 50473 -0.090376 0.132264 -0.1558373 0.0015134 0.000040 0.000023 0.000063 0.000062 0.0000069 0.0000367 0.000053 0.000018 1997 1 26 50474 -0.093631 0.134062 -0.1573544 0.0015775 0.000061 0.000000 0.000061 0.000060 0.0000047 0.0000369 0.000052 0.000017 1997 1 27 50475 -0.096851 0.135685 -0.1589135 0.0016384 0.000082 -0.000023 0.000059 0.000058 0.0000057 0.0000372 0.000051 0.000017 1997 1 28 50476 -0.099686 0.137493 -0.1604959 0.0016478 0.000102 -0.000045 0.000056 0.000056 0.0000057 0.0000374 0.000050 0.000016 1997 1 29 50477 -0.102759 0.139607 -0.1620429 0.0016677 0.000123 -0.000068 0.000054 0.000054 0.0000031 0.0000375 0.000049 0.000016 1997 1 30 50478 -0.105750 0.141294 -0.1636409 0.0015577 0.000151 -0.000150 0.000052 0.000052 0.0000085 0.0000376 0.000048 0.000016 1997 1 31 50479 -0.108153 0.143265 -0.1651896 0.0015114 0.000125 -0.000212 0.000050 0.000050 0.0000166 0.0000377 0.000047 0.000015 1997 2 1 50480 -0.111153 0.145638 -0.1667478 0.0014040 0.000094 -0.000206 0.000050 0.000050 0.0000130 0.0000378 0.000047 0.000015 1997 2 2 50481 -0.114474 0.147783 -0.1682279 0.0013016 0.000081 -0.000165 0.000052 0.000052 0.0000036 0.0000378 0.000049 0.000016 1997 2 3 50482 -0.117198 0.149755 -0.1694264 0.0012439 0.000067 -0.000124 0.000054 0.000054 0.0000031 0.0000378 0.000050 0.000017 1997 2 4 50483 -0.119931 0.152169 -0.1705964 0.0012786 0.000054 -0.000083 0.000056 0.000056 0.0000026 0.0000378 0.000052 0.000017 1997 2 5 50484 -0.122625 0.154538 -0.1718848 0.0013665 0.000032 -0.000104 0.000059 0.000058 0.0000045 0.0000378 0.000053 0.000018 1997 2 6 50485 -0.124938 0.157010 -0.1733222 0.0015617 0.000062 0.000010 0.000061 0.000060 0.0000082 0.0000379 0.000054 0.000019 1997 2 7 50486 -0.126835 0.159146 -0.1749623 0.0017018 0.000102 0.000156 0.000063 0.000062 0.0000116 0.0000379 0.000056 0.000020 1997 2 8 50487 -0.128506 0.161386 -0.1769284 0.0019097 0.000060 0.000143 0.000065 0.000063 0.0000071 0.0000379 0.000057 0.000020 1997 2 9 50488 -0.130353 0.164259 -0.1789589 0.0020314 0.000018 0.000131 0.000067 0.000065 0.0000039 0.0000380 0.000058 0.000021 1997 2 10 50489 -0.132352 0.167154 -0.1808942 0.0020798 -0.000024 0.000118 0.000069 0.000067 0.0000036 0.0000380 0.000059 0.000022 1997 2 11 50490 -0.134195 0.169960 -0.1828513 0.0020783 -0.000065 0.000105 0.000072 0.000069 0.0000033 0.0000381 0.000060 0.000023 1997 2 12 50491 -0.136284 0.172903 -0.1849137 0.0020256 0.000038 -0.000002 0.000074 0.000071 0.0000025 0.0000382 0.000061 0.000024 1997 2 13 50492 -0.138493 0.175460 -0.1868569 0.0018624 0.000117 -0.000034 0.000076 0.000073 0.0000050 0.0000383 0.000063 0.000024 1997 2 14 50493 -0.140499 0.177995 -0.1886844 0.0016946 0.000164 -0.000038 0.000078 0.000074 0.0000076 0.0000384 0.000064 0.000025 1997 2 15 50494 -0.142396 0.181101 -0.1904969 0.0016160 0.000122 -0.000037 0.000080 0.000076 0.0000060 0.0000385 0.000065 0.000025 1997 2 16 50495 -0.144739 0.183894 -0.1921676 0.0015538 0.000080 -0.000037 0.000082 0.000078 0.0000052 0.0000387 0.000066 0.000026 1997 2 17 50496 -0.147293 0.186456 -0.1936827 0.0015215 0.000037 -0.000036 0.000084 0.000079 0.0000064 0.0000389 0.000067 0.000027 1997 2 18 50497 -0.150153 0.188868 -0.1951473 0.0015280 -0.000005 -0.000036 0.000087 0.000081 0.0000065 0.0000391 0.000068 0.000028 1997 2 19 50498 -0.152601 0.191145 -0.1965757 0.0015738 -0.000048 -0.000036 0.000089 0.000083 0.0000045 0.0000394 0.000069 0.000028 1997 2 20 50499 -0.154935 0.193378 -0.1981511 0.0016346 0.000023 0.000000 0.000091 0.000085 0.0000043 0.0000398 0.000070 0.000029 1997 2 21 50500 -0.157102 0.195659 -0.1998397 0.0017471 0.000132 0.000047 0.000094 0.000087 0.0000046 0.0000401 0.000071 0.000030 1997 2 22 50501 -0.158854 0.198076 -0.2016821 0.0018393 0.000098 0.000002 0.000096 0.000089 0.0000103 0.0000405 0.000072 0.000030 1997 2 23 50502 -0.160487 0.200754 -0.2036230 0.0019365 0.000052 -0.000052 0.000098 0.000091 0.0000165 0.0000409 0.000073 0.000031 1997 2 24 50503 -0.161726 0.203683 -0.2056374 0.0020374 0.000005 -0.000106 0.000101 0.000093 0.0000228 0.0000412 0.000074 0.000032 1997 2 25 50504 -0.163061 0.206963 -0.2076264 0.0020332 -0.000041 -0.000160 0.000103 0.000095 0.0000221 0.0000415 0.000075 0.000032 1997 2 26 50505 -0.165080 0.210295 -0.2095267 0.0019968 -0.000088 -0.000214 0.000105 0.000097 0.0000111 0.0000418 0.000077 0.000033 1997 2 27 50506 -0.167661 0.213803 -0.2115666 0.0020007 -0.000076 -0.000240 0.000107 0.000098 0.0000085 0.0000421 0.000077 0.000034 1997 2 28 50507 -0.170167 0.217048 -0.2136511 0.0020364 -0.000043 -0.000257 0.000109 0.000100 0.0000089 0.0000424 0.000078 0.000034 1997 3 1 50508 -0.172121 0.219962 -0.2157154 0.0020317 -0.000011 -0.000274 0.000111 0.000102 0.0000082 0.0000427 0.000079 0.000034 1997 3 2 50509 -0.173799 0.223170 -0.2177482 0.0020294 0.000021 -0.000291 0.000112 0.000103 0.0000069 0.0000430 0.000080 0.000035 1997 3 3 50510 -0.175058 0.226505 -0.2197852 0.0020267 0.000054 -0.000308 0.000114 0.000104 0.0000082 0.0000433 0.000081 0.000035 1997 3 4 50511 -0.175717 0.229783 -0.2218090 0.0020497 0.000086 -0.000325 0.000115 0.000105 0.0000084 0.0000435 0.000081 0.000035 1997 3 5 50512 -0.176419 0.233111 -0.2237805 0.0021466 0.000118 -0.000342 0.000116 0.000106 0.0000054 0.0000438 0.000082 0.000036 1997 3 6 50513 -0.177090 0.236339 -0.2260477 0.0023086 0.000112 -0.000315 0.000116 0.000107 0.0000061 0.0000441 0.000083 0.000036 1997 3 7 50514 -0.178353 0.239734 -0.2285582 0.0025074 0.000094 -0.000272 0.000117 0.000107 0.0000079 0.0000444 0.000083 0.000036 1997 3 8 50515 -0.180141 0.242856 -0.2312572 0.0027060 0.000075 -0.000229 0.000117 0.000107 0.0000086 0.0000446 0.000083 0.000036 1997 3 9 50516 -0.182057 0.245953 -0.2340672 0.0028580 0.000057 -0.000186 0.000118 0.000107 0.0000066 0.0000449 0.000083 0.000035 1997 3 10 50517 -0.184114 0.248918 -0.2369224 0.0028712 0.000038 -0.000144 0.000118 0.000107 0.0000083 0.0000451 0.000084 0.000035 1997 3 11 50518 -0.185942 0.251809 -0.2397156 0.0028274 0.000020 -0.000101 0.000117 0.000107 0.0000084 0.0000454 0.000084 0.000035 1997 3 12 50519 -0.186596 0.255062 -0.2423118 0.0026900 0.000001 -0.000058 0.000117 0.000107 0.0000036 0.0000456 0.000084 0.000035 1997 3 13 50520 -0.186708 0.258628 -0.2449290 0.0025350 0.000001 -0.000060 0.000117 0.000107 0.0000047 0.0000459 0.000084 0.000035 1997 3 14 50521 -0.186578 0.261912 -0.2474693 0.0024014 0.000008 -0.000076 0.000116 0.000106 0.0000077 0.0000461 0.000084 0.000035 1997 3 15 50522 -0.186244 0.265879 -0.2498996 0.0023648 0.000014 -0.000093 0.000115 0.000106 0.0000088 0.0000463 0.000084 0.000035 1997 3 16 50523 -0.186549 0.270143 -0.2522424 0.0023479 0.000020 -0.000109 0.000114 0.000105 0.0000058 0.0000465 0.000084 0.000035 1997 3 17 50524 -0.187566 0.274298 -0.2546076 0.0023419 0.000027 -0.000126 0.000113 0.000104 0.0000074 0.0000467 0.000085 0.000035 1997 3 18 50525 -0.188422 0.277783 -0.2569443 0.0023761 0.000033 -0.000142 0.000111 0.000102 0.0000078 0.0000469 0.000085 0.000035 1997 3 19 50526 -0.188716 0.281254 -0.2591808 0.0024097 0.000027 -0.000119 0.000110 0.000101 0.0000049 0.0000471 0.000084 0.000034 1997 3 20 50527 -0.188934 0.285024 -0.2615871 0.0024209 0.000091 -0.000130 0.000109 0.000100 0.0000035 0.0000473 0.000084 0.000034 1997 3 21 50528 -0.189216 0.288602 -0.2641655 0.0024671 0.000103 -0.000136 0.000107 0.000099 0.0000057 0.0000474 0.000083 0.000033 1997 3 22 50529 -0.189386 0.292320 -0.2667781 0.0024802 0.000086 -0.000134 0.000105 0.000098 0.0000077 0.0000475 0.000082 0.000032 1997 3 23 50530 -0.189612 0.296077 -0.2693100 0.0025404 0.000069 -0.000133 0.000105 0.000097 0.0000066 0.0000475 0.000081 0.000032 1997 3 24 50531 -0.189558 0.299660 -0.2717700 0.0025776 0.000052 -0.000132 0.000103 0.000096 0.0000051 0.0000475 0.000080 0.000032 1997 3 25 50532 -0.189287 0.303584 -0.2742324 0.0025658 0.000035 -0.000131 0.000101 0.000095 0.0000036 0.0000475 0.000079 0.000031 1997 3 26 50533 -0.189496 0.307728 -0.2767863 0.0025402 -0.000016 -0.000129 0.000099 0.000094 0.0000036 0.0000475 0.000078 0.000030 1997 3 27 50534 -0.189938 0.311631 -0.2794073 0.0024974 -0.000015 -0.000140 0.000097 0.000092 0.0000067 0.0000474 0.000077 0.000029 1997 3 28 50535 -0.190425 0.315388 -0.2819662 0.0024340 0.000003 -0.000155 0.000095 0.000091 0.0000095 0.0000473 0.000076 0.000029 1997 3 29 50536 -0.190625 0.319298 -0.2843833 0.0024399 0.000021 -0.000171 0.000092 0.000089 0.0000093 0.0000472 0.000074 0.000028 1997 3 30 50537 -0.191088 0.323283 -0.2867868 0.0023733 0.000039 -0.000186 0.000090 0.000087 0.0000104 0.0000470 0.000073 0.000027 1997 3 31 50538 -0.191356 0.326390 -0.2890860 0.0023891 0.000057 -0.000201 0.000088 0.000085 0.0000148 0.0000468 0.000072 0.000026 1997 4 1 50539 -0.191111 0.329700 -0.2914143 0.0024371 0.000075 -0.000217 0.000085 0.000083 0.0000192 0.0000466 0.000071 0.000026 1997 4 2 50540 -0.190505 0.332999 -0.2939006 0.0025660 -0.000033 -0.000172 0.000087 0.000084 0.0000072 0.0000463 0.000072 0.000026 1997 4 3 50541 -0.189601 0.336776 -0.2965084 0.0026736 -0.000011 -0.000177 0.000089 0.000086 0.0000042 0.0000460 0.000073 0.000027 1997 4 4 50542 -0.188331 0.340859 -0.2993870 0.0028360 0.000001 -0.000161 0.000091 0.000088 0.0000067 0.0000457 0.000074 0.000027 1997 4 5 50543 -0.187237 0.344517 -0.3023642 0.0029521 -0.000010 -0.000129 0.000093 0.000089 0.0000177 0.0000454 0.000075 0.000028 1997 4 6 50544 -0.186175 0.348141 -0.3052559 0.0029530 -0.000021 -0.000097 0.000095 0.000091 0.0000315 0.0000450 0.000076 0.000028 1997 4 7 50545 -0.185633 0.351657 -0.3081354 0.0028675 -0.000031 -0.000065 0.000097 0.000092 0.0000181 0.0000446 0.000077 0.000029 1997 4 8 50546 -0.184614 0.355034 -0.3109361 0.0027854 -0.000042 -0.000032 0.000099 0.000093 0.0000047 0.0000442 0.000078 0.000030 1997 4 9 50547 -0.183554 0.358476 -0.3136348 0.0026491 -0.000073 -0.000044 0.000100 0.000094 0.0000024 0.0000438 0.000079 0.000030 1997 4 10 50548 -0.182563 0.362120 -0.3163021 0.0024794 -0.000099 -0.000058 0.000102 0.000095 0.0000062 0.0000434 0.000080 0.000030 1997 4 11 50549 -0.181496 0.365734 -0.3188131 0.0023525 -0.000124 -0.000072 0.000103 0.000096 0.0000123 0.0000429 0.000081 0.000031 1997 4 12 50550 -0.180205 0.369732 -0.3211101 0.0022772 -0.000149 -0.000087 0.000105 0.000097 0.0000132 0.0000425 0.000083 0.000032 1997 4 13 50551 -0.179386 0.373697 -0.3233386 0.0022059 -0.000174 -0.000101 0.000106 0.000097 0.0000058 0.0000421 0.000084 0.000032 1997 4 14 50552 -0.179296 0.377458 -0.3255405 0.0021710 -0.000199 -0.000115 0.000107 0.000098 0.0000056 0.0000417 0.000085 0.000033 1997 4 15 50553 -0.179059 0.381232 -0.3276761 0.0021725 -0.000224 -0.000130 0.000108 0.000099 0.0000050 0.0000413 0.000086 0.000034 1997 4 16 50554 -0.178530 0.384291 -0.3297274 0.0022162 -0.000249 -0.000144 0.000109 0.000100 0.0000038 0.0000409 0.000087 0.000034 1997 4 17 50555 -0.177912 0.387232 -0.3319623 0.0022931 -0.000043 0.000000 0.000110 0.000100 0.0000027 0.0000406 0.000088 0.000035 1997 4 18 50556 -0.177280 0.390362 -0.3344043 0.0023336 -0.000030 0.000046 0.000111 0.000101 0.0000055 0.0000403 0.000089 0.000036 1997 4 19 50557 -0.175836 0.393510 -0.3368560 0.0023430 -0.000117 0.000035 0.000111 0.000101 0.0000068 0.0000399 0.000090 0.000036 1997 4 20 50558 -0.174795 0.397010 -0.3391870 0.0023517 -0.000204 0.000025 0.000111 0.000101 0.0000046 0.0000396 0.000091 0.000037 1997 4 21 50559 -0.173966 0.400439 -0.3414561 0.0023801 -0.000291 0.000014 0.000111 0.000101 0.0000071 0.0000394 0.000092 0.000037 1997 4 22 50560 -0.173211 0.404176 -0.3436844 0.0023112 -0.000378 0.000004 0.000111 0.000101 0.0000095 0.0000391 0.000093 0.000038 1997 4 23 50561 -0.172629 0.407774 -0.3459182 0.0022132 -0.000108 -0.000067 0.000111 0.000101 0.0000065 0.0000388 0.000093 0.000038 1997 4 24 50562 -0.172122 0.411082 -0.3481888 0.0021288 -0.000037 -0.000099 0.000111 0.000100 0.0000079 0.0000385 0.000092 0.000038 1997 4 25 50563 -0.170812 0.414140 -0.3503650 0.0020536 -0.000044 -0.000117 0.000110 0.000100 0.0000105 0.0000382 0.000092 0.000038 1997 4 26 50564 -0.168846 0.417340 -0.3523951 0.0019988 -0.000051 -0.000135 0.000110 0.000099 0.0000095 0.0000379 0.000092 0.000037 1997 4 27 50565 -0.166916 0.420597 -0.3543828 0.0019570 -0.000057 -0.000153 0.000109 0.000099 0.0000065 0.0000377 0.000091 0.000037 1997 4 28 50566 -0.165343 0.423817 -0.3563336 0.0019627 -0.000064 -0.000170 0.000108 0.000098 0.0000095 0.0000374 0.000091 0.000036 1997 4 29 50567 -0.164301 0.426930 -0.3582570 0.0019986 -0.000071 -0.000188 0.000107 0.000098 0.0000099 0.0000372 0.000090 0.000036 1997 4 30 50568 -0.163521 0.429381 -0.3601736 0.0021082 -0.000078 -0.000206 0.000106 0.000097 0.0000062 0.0000370 0.000090 0.000036 1997 5 1 50569 -0.162531 0.431797 -0.3623063 0.0022145 -0.000138 -0.000170 0.000105 0.000096 0.0000068 0.0000368 0.000089 0.000035 1997 5 2 50570 -0.161060 0.434230 -0.3646877 0.0023239 -0.000140 -0.000143 0.000104 0.000095 0.0000093 0.0000366 0.000088 0.000034 1997 5 3 50571 -0.159019 0.436851 -0.3671768 0.0024359 -0.000115 -0.000125 0.000103 0.000094 0.0000118 0.0000364 0.000086 0.000033 1997 5 4 50572 -0.156538 0.439633 -0.3696182 0.0025131 -0.000090 -0.000107 0.000101 0.000093 0.0000131 0.0000363 0.000085 0.000032 1997 5 5 50573 -0.153600 0.442756 -0.3720341 0.0025027 -0.000064 -0.000089 0.000100 0.000092 0.0000093 0.0000361 0.000083 0.000032 1997 5 6 50574 -0.150646 0.446275 -0.3744240 0.0024343 -0.000039 -0.000071 0.000098 0.000091 0.0000055 0.0000360 0.000082 0.000031 1997 5 7 50575 -0.148018 0.449542 -0.3768222 0.0023206 -0.000217 -0.000037 0.000096 0.000090 0.0000040 0.0000359 0.000080 0.000030 1997 5 8 50576 -0.145374 0.452383 -0.3791510 0.0021962 -0.000314 -0.000028 0.000094 0.000089 0.0000056 0.0000358 0.000079 0.000029 1997 5 9 50577 -0.142324 0.455298 -0.3813941 0.0020992 -0.000296 -0.000051 0.000093 0.000087 0.0000093 0.0000356 0.000077 0.000028 1997 5 10 50578 -0.139227 0.458288 -0.3835099 0.0020253 -0.000279 -0.000074 0.000091 0.000086 0.0000103 0.0000355 0.000075 0.000027 1997 5 11 50579 -0.136234 0.461302 -0.3854868 0.0019717 -0.000261 -0.000098 0.000089 0.000084 0.0000059 0.0000355 0.000073 0.000026 1997 5 12 50580 -0.133712 0.464199 -0.3874406 0.0019582 -0.000243 -0.000121 0.000087 0.000083 0.0000103 0.0000354 0.000072 0.000025 1997 5 13 50581 -0.131572 0.466827 -0.3893454 0.0019423 -0.000226 -0.000145 0.000085 0.000081 0.0000117 0.0000354 0.000070 0.000024 1997 5 14 50582 -0.129594 0.469263 -0.3911497 0.0019510 -0.000208 -0.000168 0.000083 0.000080 0.0000051 0.0000354 0.000069 0.000023 1997 5 15 50583 -0.127646 0.471610 -0.3930689 0.0019714 -0.000060 -0.000109 0.000081 0.000078 0.0000025 0.0000354 0.000068 0.000023 1997 5 16 50584 -0.125159 0.473673 -0.3951466 0.0019903 -0.000037 -0.000104 0.000079 0.000076 0.0000123 0.0000355 0.000066 0.000022 1997 5 17 50585 -0.122441 0.475739 -0.3972415 0.0020236 -0.000077 -0.000130 0.000076 0.000075 0.0000220 0.0000355 0.000064 0.000021 1997 5 18 50586 -0.119427 0.477904 -0.3992369 0.0020586 -0.000116 -0.000156 0.000074 0.000073 0.0000214 0.0000355 0.000063 0.000020 1997 5 19 50587 -0.116483 0.480467 -0.4012562 0.0020780 -0.000156 -0.000182 0.000072 0.000071 0.0000207 0.0000356 0.000061 0.000019 1997 5 20 50588 -0.113568 0.483024 -0.4032860 0.0020934 -0.000196 -0.000208 0.000069 0.000069 0.0000201 0.0000356 0.000060 0.000019 1997 5 21 50589 -0.110698 0.485917 -0.4053535 0.0020704 -0.000139 -0.000172 0.000071 0.000071 0.0000062 0.0000357 0.000060 0.000019 1997 5 22 50590 -0.108230 0.488580 -0.4075288 0.0020289 -0.000125 -0.000166 0.000073 0.000073 0.0000057 0.0000357 0.000061 0.000020 1997 5 23 50591 -0.105950 0.490846 -0.4096569 0.0019802 -0.000127 -0.000171 0.000076 0.000075 0.0000081 0.0000357 0.000062 0.000020 1997 5 24 50592 -0.103635 0.493017 -0.4116348 0.0019673 -0.000129 -0.000177 0.000078 0.000077 0.0000068 0.0000356 0.000063 0.000021 1997 5 25 50593 -0.101388 0.495314 -0.4136229 0.0020018 -0.000131 -0.000183 0.000081 0.000079 0.0000073 0.0000356 0.000064 0.000021 1997 5 26 50594 -0.099160 0.497519 -0.4156150 0.0020784 -0.000133 -0.000189 0.000083 0.000081 0.0000073 0.0000355 0.000065 0.000022 1997 5 27 50595 -0.096922 0.499791 -0.4176518 0.0021777 -0.000135 -0.000195 0.000085 0.000083 0.0000069 0.0000353 0.000067 0.000023 1997 5 28 50596 -0.094278 0.501814 -0.4197282 0.0023011 -0.000138 -0.000200 0.000087 0.000084 0.0000055 0.0000351 0.000068 0.000024 1997 5 29 50597 -0.091602 0.503834 -0.4221776 0.0024497 -0.000140 -0.000215 0.000089 0.000086 0.0000059 0.0000349 0.000069 0.000025 1997 5 30 50598 -0.089521 0.505858 -0.4247821 0.0025178 -0.000142 -0.000231 0.000091 0.000087 0.0000068 0.0000347 0.000070 0.000025 1997 5 31 50599 -0.087294 0.507737 -0.4273272 0.0024981 -0.000145 -0.000248 0.000093 0.000088 0.0000071 0.0000344 0.000071 0.000026 1997 6 1 50600 -0.084928 0.509869 -0.4297850 0.0024649 -0.000147 -0.000265 0.000095 0.000090 0.0000064 0.0000341 0.000072 0.000027 1997 6 2 50601 -0.082665 0.511727 -0.4321187 0.0023380 -0.000150 -0.000282 0.000097 0.000091 0.0000065 0.0000338 0.000073 0.000028 1997 6 3 50602 -0.080257 0.513347 -0.4342988 0.0021565 -0.000152 -0.000299 0.000099 0.000092 0.0000065 0.0000335 0.000075 0.000029 1997 6 4 50603 -0.077447 0.514999 -0.4363586 0.0019399 -0.000165 -0.000085 0.000100 0.000093 0.0000029 0.0000332 0.000075 0.000029 1997 6 5 50604 -0.074893 0.516669 -0.4383337 0.0017541 -0.000151 -0.000013 0.000102 0.000095 0.0000041 0.0000329 0.000076 0.000030 1997 6 6 50605 -0.072685 0.517946 -0.4401225 0.0015999 -0.000128 0.000013 0.000103 0.000095 0.0000065 0.0000327 0.000077 0.000030 1997 6 7 50606 -0.070397 0.518859 -0.4416798 0.0015115 -0.000105 0.000038 0.000104 0.000096 0.0000070 0.0000325 0.000079 0.000031 1997 6 8 50607 -0.068121 0.519513 -0.4431582 0.0014591 -0.000082 0.000063 0.000106 0.000097 0.0000059 0.0000323 0.000080 0.000032 1997 6 9 50608 -0.065492 0.519939 -0.4446060 0.0014667 -0.000060 0.000089 0.000107 0.000098 0.0000051 0.0000322 0.000082 0.000033 1997 6 10 50609 -0.062042 0.520257 -0.4460272 0.0015173 -0.000037 0.000114 0.000108 0.000099 0.0000052 0.0000321 0.000083 0.000034 1997 6 11 50610 -0.058102 0.521092 -0.4474084 0.0015827 -0.000014 0.000139 0.000109 0.000099 0.0000072 0.0000320 0.000085 0.000035 1997 6 12 50611 -0.054224 0.522246 -0.4490692 0.0016090 -0.000015 0.000066 0.000110 0.000100 0.0000101 0.0000319 0.000086 0.000036 1997 6 13 50612 -0.050492 0.523865 -0.4507717 0.0016052 -0.000024 -0.000041 0.000110 0.000100 0.0000126 0.0000319 0.000087 0.000037 1997 6 14 50613 -0.046779 0.525729 -0.4523677 0.0015891 -0.000033 -0.000148 0.000111 0.000100 0.0000127 0.0000318 0.000088 0.000037 1997 6 15 50614 -0.043269 0.527194 -0.4539726 0.0015455 -0.000043 -0.000255 0.000111 0.000100 0.0000112 0.0000318 0.000089 0.000038 1997 6 16 50615 -0.039763 0.528098 -0.4555277 0.0014770 -0.000052 -0.000362 0.000112 0.000100 0.0000098 0.0000318 0.000090 0.000039 1997 6 17 50616 -0.036113 0.528814 -0.4569326 0.0013880 -0.000061 -0.000469 0.000112 0.000100 0.0000074 0.0000318 0.000091 0.000039 1997 6 18 50617 -0.032498 0.529685 -0.4581085 0.0012555 0.000023 -0.000173 0.000112 0.000100 0.0000034 0.0000319 0.000092 0.000039 1997 6 19 50618 -0.028953 0.530421 -0.4593854 0.0011402 0.000058 -0.000082 0.000113 0.000100 0.0000052 0.0000319 0.000092 0.000040 1997 6 20 50619 -0.025105 0.531325 -0.4605639 0.0010371 0.000075 -0.000074 0.000113 0.000100 0.0000072 0.0000320 0.000092 0.000040 1997 6 21 50620 -0.021288 0.532005 -0.4615561 0.0009607 0.000092 -0.000066 0.000113 0.000100 0.0000069 0.0000321 0.000092 0.000040 1997 6 22 50621 -0.017241 0.532676 -0.4625237 0.0009949 0.000108 -0.000057 0.000113 0.000100 0.0000081 0.0000322 0.000093 0.000041 1997 6 23 50622 -0.012983 0.533119 -0.4635533 0.0011186 0.000125 -0.000049 0.000113 0.000100 0.0000096 0.0000324 0.000093 0.000042 1997 6 24 50623 -0.008734 0.533493 -0.4646384 0.0012146 0.000141 -0.000041 0.000113 0.000100 0.0000099 0.0000325 0.000093 0.000042 1997 6 25 50624 -0.004924 0.533950 -0.4657636 0.0013053 0.000158 -0.000032 0.000113 0.000099 0.0000081 0.0000327 0.000094 0.000043 1997 6 26 50625 -0.001236 0.534510 -0.4671900 0.0013744 0.000131 -0.000055 0.000113 0.000099 0.0000083 0.0000329 0.000093 0.000043 1997 6 27 50626 0.002499 0.535089 -0.4686729 0.0013638 0.000089 -0.000087 0.000113 0.000099 0.0000093 0.0000331 0.000093 0.000043 1997 6 28 50627 0.006251 0.535388 -0.4700192 0.0013134 0.000048 -0.000120 0.000112 0.000099 0.0000089 0.0000334 0.000092 0.000042 1997 6 29 50628 0.010515 0.535398 -0.4712449 0.0011758 0.000006 -0.000152 0.000112 0.000099 0.0000089 0.0000337 0.000092 0.000042 1997 6 30 50629 0.014979 0.535827 -0.4723551 0.0010027 -0.000035 -0.000185 0.000112 0.000099 0.0000141 0.0000340 0.000091 0.000042 1997 7 1 50630 0.019267 0.536457 0.5267299 0.0008623 -0.000077 -0.000218 0.000112 0.000098 0.0000162 0.0000344 0.000091 0.000042 1997 7 2 50631 0.023493 0.536893 0.5260870 0.0007045 -0.000118 -0.000250 0.000111 0.000098 0.0000074 0.0000348 0.000089 0.000041 1997 7 3 50632 0.027665 0.537124 0.5254097 0.0005750 -0.000144 -0.000253 0.000111 0.000098 0.0000146 0.0000353 0.000089 0.000041 1997 7 4 50633 0.031319 0.537061 0.5247358 0.0005195 -0.000144 -0.000216 0.000110 0.000098 0.0000266 0.0000358 0.000088 0.000041 1997 7 5 50634 0.035129 0.536776 0.5242161 0.0005117 -0.000144 -0.000178 0.000110 0.000098 0.0000167 0.0000363 0.000088 0.000040 1997 7 6 50635 0.038886 0.536312 0.5236567 0.0005841 -0.000144 -0.000141 0.000109 0.000097 0.0000084 0.0000367 0.000087 0.000040 1997 7 7 50636 0.042564 0.535654 0.5229887 0.0007004 -0.000145 -0.000103 0.000108 0.000097 0.0000119 0.0000372 0.000087 0.000040 1997 7 8 50637 0.046530 0.534991 0.5222888 0.0008083 -0.000145 -0.000066 0.000107 0.000097 0.0000129 0.0000377 0.000087 0.000039 1997 7 9 50638 0.050850 0.534488 0.5216533 0.0008942 -0.000145 -0.000028 0.000106 0.000096 0.0000060 0.0000382 0.000086 0.000039 1997 7 10 50639 0.054930 0.534125 0.5208014 0.0009305 -0.000246 -0.000111 0.000106 0.000096 0.0000055 0.0000386 0.000086 0.000039 1997 7 11 50640 0.058307 0.533842 0.5197199 0.0010060 -0.000235 -0.000128 0.000104 0.000095 0.0000093 0.0000391 0.000084 0.000038 1997 7 12 50641 0.061674 0.533098 0.5185675 0.0010714 -0.000170 -0.000106 0.000103 0.000095 0.0000117 0.0000397 0.000083 0.000037 1997 7 13 50642 0.065351 0.532455 0.5174932 0.0011086 -0.000104 -0.000083 0.000101 0.000094 0.0000081 0.0000402 0.000081 0.000036 1997 7 14 50643 0.069056 0.531644 0.5164621 0.0011174 -0.000039 -0.000061 0.000099 0.000093 0.0000067 0.0000408 0.000080 0.000035 1997 7 15 50644 0.072667 0.530829 0.5154488 0.0010994 0.000026 -0.000039 0.000098 0.000092 0.0000052 0.0000414 0.000079 0.000034 1997 7 16 50645 0.075890 0.530058 0.5143953 0.0010344 -0.000146 -0.000150 0.000096 0.000090 0.0000039 0.0000420 0.000077 0.000033 1997 7 17 50646 0.078902 0.529437 0.5132681 0.0010178 -0.000173 -0.000152 0.000094 0.000089 0.0000067 0.0000425 0.000076 0.000031 1997 7 18 50647 0.081597 0.528731 0.5120944 0.0010957 -0.000150 -0.000118 0.000091 0.000087 0.0000121 0.0000431 0.000074 0.000030 1997 7 19 50648 0.084509 0.527918 0.5108997 0.0012140 -0.000128 -0.000084 0.000089 0.000086 0.0000164 0.0000436 0.000072 0.000029 1997 7 20 50649 0.087744 0.526868 0.5096315 0.0013982 -0.000106 -0.000050 0.000087 0.000084 0.0000119 0.0000441 0.000070 0.000028 1997 7 21 50650 0.091786 0.525702 0.5081349 0.0016204 -0.000083 -0.000016 0.000085 0.000083 0.0000166 0.0000446 0.000069 0.000027 1997 7 22 50651 0.095805 0.524604 0.5064802 0.0017852 -0.000061 0.000017 0.000082 0.000081 0.0000170 0.0000450 0.000068 0.000026 1997 7 23 50652 0.099229 0.523506 0.5047565 0.0019152 -0.000039 0.000051 0.000080 0.000079 0.0000071 0.0000454 0.000067 0.000026 1997 7 24 50653 0.102252 0.522604 0.5028243 0.0020072 -0.000110 -0.000032 0.000077 0.000077 0.0000076 0.0000458 0.000065 0.000025 1997 7 25 50654 0.105642 0.521556 0.5007998 0.0020133 -0.000315 -0.000085 0.000075 0.000076 0.0000165 0.0000461 0.000063 0.000024 1997 7 26 50655 0.108168 0.520904 0.4987200 0.0019228 -0.000373 -0.000091 0.000076 0.000076 0.0000136 0.0000464 0.000063 0.000024 1997 7 27 50656 0.110397 0.520003 0.4967507 0.0017816 -0.000340 -0.000088 0.000079 0.000078 0.0000076 0.0000466 0.000065 0.000024 1997 7 28 50657 0.112689 0.518762 0.4950553 0.0016154 -0.000307 -0.000085 0.000081 0.000080 0.0000127 0.0000469 0.000066 0.000025 1997 7 29 50658 0.114884 0.517198 0.4935671 0.0014549 -0.000274 -0.000082 0.000083 0.000082 0.0000138 0.0000471 0.000067 0.000026 1997 7 30 50659 0.117565 0.515840 0.4923102 0.0013366 -0.000241 -0.000078 0.000086 0.000084 0.0000054 0.0000472 0.000069 0.000027 1997 7 31 50660 0.120219 0.514661 0.4909464 0.0012475 -0.000228 -0.000052 0.000088 0.000086 0.0000073 0.0000474 0.000070 0.000028 1997 8 1 50661 0.123330 0.513521 0.4896106 0.0012326 -0.000222 -0.000018 0.000091 0.000087 0.0000133 0.0000475 0.000072 0.000028 1997 8 2 50662 0.126432 0.512283 0.4883693 0.0012624 -0.000216 0.000016 0.000093 0.000089 0.0000182 0.0000477 0.000073 0.000029 1997 8 3 50663 0.129541 0.510880 0.4871063 0.0012624 -0.000210 0.000050 0.000096 0.000091 0.0000165 0.0000478 0.000075 0.000030 1997 8 4 50664 0.132375 0.509594 0.4859196 0.0012775 -0.000204 0.000084 0.000098 0.000093 0.0000110 0.0000480 0.000076 0.000031 1997 8 5 50665 0.135137 0.508011 0.4846973 0.0013496 -0.000197 0.000118 0.000100 0.000094 0.0000055 0.0000481 0.000078 0.000033 1997 8 6 50666 0.137883 0.506711 0.4833266 0.0014325 -0.000036 0.000040 0.000102 0.000096 0.0000043 0.0000481 0.000079 0.000033 1997 8 7 50667 0.140304 0.505673 0.4818030 0.0014375 -0.000017 -0.000002 0.000104 0.000097 0.0000075 0.0000482 0.000080 0.000034 1997 8 8 50668 0.142330 0.503974 0.4802470 0.0014690 -0.000057 -0.000023 0.000106 0.000098 0.0000124 0.0000483 0.000081 0.000034 1997 8 9 50669 0.144641 0.502438 0.4787762 0.0014628 -0.000096 -0.000045 0.000107 0.000099 0.0000150 0.0000484 0.000081 0.000035 1997 8 10 50670 0.147026 0.500500 0.4773813 0.0014528 -0.000136 -0.000067 0.000109 0.000099 0.0000118 0.0000486 0.000082 0.000035 1997 8 11 50671 0.149111 0.498486 0.4760461 0.0013424 -0.000176 -0.000089 0.000110 0.000100 0.0000085 0.0000487 0.000083 0.000036 1997 8 12 50672 0.151309 0.496283 0.4747876 0.0012606 -0.000216 -0.000111 0.000111 0.000100 0.0000052 0.0000489 0.000084 0.000037 1997 8 13 50673 0.153426 0.494325 0.4735365 0.0012004 -0.000139 -0.000166 0.000112 0.000101 0.0000031 0.0000491 0.000084 0.000037 1997 8 14 50674 0.155577 0.492268 0.4722240 0.0011834 -0.000148 -0.000177 0.000113 0.000102 0.0000082 0.0000493 0.000085 0.000037 1997 8 15 50675 0.157640 0.490057 0.4709736 0.0011904 -0.000185 -0.000173 0.000114 0.000102 0.0000160 0.0000496 0.000085 0.000038 1997 8 16 50676 0.159427 0.488020 0.4698033 0.0012648 -0.000223 -0.000170 0.000115 0.000103 0.0000169 0.0000498 0.000085 0.000038 1997 8 17 50677 0.161241 0.485939 0.4684644 0.0013875 -0.000260 -0.000166 0.000116 0.000103 0.0000082 0.0000501 0.000086 0.000039 1997 8 18 50678 0.163068 0.483930 0.4669522 0.0015971 -0.000298 -0.000162 0.000117 0.000104 0.0000087 0.0000504 0.000086 0.000039 1997 8 19 50679 0.164986 0.481689 0.4653410 0.0017359 -0.000335 -0.000159 0.000117 0.000104 0.0000079 0.0000507 0.000086 0.000040 1997 8 20 50680 0.167001 0.479441 0.4636956 0.0018389 -0.000373 -0.000155 0.000118 0.000105 0.0000049 0.0000510 0.000087 0.000040 1997 8 21 50681 0.169060 0.477218 0.4618318 0.0019180 -0.000083 -0.000138 0.000118 0.000105 0.0000034 0.0000513 0.000087 0.000040 1997 8 22 50682 0.171355 0.474727 0.4598489 0.0018428 -0.000021 -0.000136 0.000118 0.000105 0.0000077 0.0000515 0.000086 0.000040 1997 8 23 50683 0.174163 0.472508 0.4579621 0.0016961 -0.000084 -0.000141 0.000119 0.000105 0.0000108 0.0000517 0.000086 0.000040 1997 8 24 50684 0.177039 0.470358 0.4563007 0.0014937 -0.000147 -0.000147 0.000118 0.000105 0.0000105 0.0000519 0.000085 0.000040 1997 8 25 50685 0.179669 0.468383 0.4548414 0.0013892 -0.000211 -0.000152 0.000118 0.000105 0.0000142 0.0000521 0.000084 0.000040 1997 8 26 50686 0.181783 0.466847 0.4535559 0.0013268 -0.000274 -0.000157 0.000118 0.000105 0.0000136 0.0000522 0.000084 0.000040 1997 8 27 50687 0.183655 0.465285 0.4524081 0.0012862 -0.000193 -0.000058 0.000117 0.000105 0.0000059 0.0000523 0.000082 0.000039 1997 8 28 50688 0.186143 0.463397 0.4511029 0.0013485 -0.000113 -0.000021 0.000116 0.000104 0.0000082 0.0000524 0.000081 0.000038 1997 8 29 50689 0.188176 0.461889 0.4496876 0.0012821 -0.000048 -0.000060 0.000115 0.000103 0.0000093 0.0000525 0.000079 0.000037 1997 8 30 50690 0.190406 0.459919 0.4482778 0.0013544 0.000017 -0.000099 0.000114 0.000103 0.0000094 0.0000526 0.000078 0.000037 1997 8 31 50691 0.192467 0.457940 0.4469256 0.0013230 0.000081 -0.000137 0.000113 0.000102 0.0000073 0.0000527 0.000077 0.000036 1997 9 1 50692 0.194809 0.456133 0.4454641 0.0014934 0.000146 -0.000176 0.000112 0.000101 0.0000125 0.0000528 0.000075 0.000036 1997 9 2 50693 0.197398 0.454646 0.4439692 0.0015529 0.000211 -0.000215 0.000111 0.000100 0.0000143 0.0000529 0.000074 0.000035 1997 9 3 50694 0.200202 0.452723 0.4425354 0.0016325 0.000276 -0.000254 0.000109 0.000099 0.0000052 0.0000530 0.000073 0.000034 1997 9 4 50695 0.202984 0.450911 0.4409563 0.0016496 -0.000260 0.000054 0.000108 0.000098 0.0000053 0.0000531 0.000072 0.000034 1997 9 5 50696 0.204954 0.448873 0.4392284 0.0016100 -0.000411 0.000131 0.000106 0.000096 0.0000111 0.0000532 0.000070 0.000033 1997 9 6 50697 0.206409 0.446463 0.4375342 0.0016035 -0.000343 0.000077 0.000105 0.000095 0.0000141 0.0000532 0.000069 0.000032 1997 9 7 50698 0.207975 0.443762 0.4360362 0.0015335 -0.000275 0.000022 0.000103 0.000094 0.0000064 0.0000533 0.000067 0.000031 1997 9 8 50699 0.209539 0.441150 0.4346215 0.0014519 -0.000207 -0.000032 0.000101 0.000093 0.0000039 0.0000534 0.000065 0.000030 1997 9 9 50700 0.211472 0.438413 0.4332658 0.0014233 -0.000139 -0.000086 0.000099 0.000091 0.0000015 0.0000534 0.000064 0.000030 1997 9 10 50701 0.212717 0.436242 0.4319216 0.0013916 -0.000134 -0.000043 0.000101 0.000092 0.0000031 0.0000535 0.000065 0.000031 1997 9 11 50702 0.213975 0.433464 0.4304456 0.0013564 -0.000152 -0.000059 0.000102 0.000093 0.0000099 0.0000535 0.000067 0.000031 1997 9 12 50703 0.215408 0.430619 0.4288967 0.0015149 -0.000176 -0.000098 0.000104 0.000094 0.0000150 0.0000535 0.000068 0.000032 1997 9 13 50704 0.216928 0.428219 0.4273190 0.0016127 -0.000199 -0.000137 0.000105 0.000094 0.0000106 0.0000534 0.000070 0.000033 1997 9 14 50705 0.217787 0.426538 0.4255792 0.0018126 -0.000223 -0.000175 0.000106 0.000095 0.0000077 0.0000534 0.000072 0.000034 1997 9 15 50706 0.217977 0.424557 0.4236301 0.0020197 -0.000247 -0.000214 0.000108 0.000096 0.0000109 0.0000533 0.000074 0.000036 1997 9 16 50707 0.217965 0.421873 0.4214933 0.0022812 -0.000270 -0.000253 0.000109 0.000097 0.0000128 0.0000532 0.000076 0.000037 1997 9 17 50708 0.218042 0.419067 0.4192846 0.0024171 -0.000058 0.000007 0.000110 0.000097 0.0000108 0.0000531 0.000078 0.000038 1997 9 18 50709 0.218364 0.416648 0.4168108 0.0024579 -0.000016 0.000078 0.000111 0.000098 0.0000101 0.0000529 0.000079 0.000039 1997 9 19 50710 0.219115 0.414208 0.4143142 0.0023807 -0.000030 0.000085 0.000112 0.000099 0.0000098 0.0000528 0.000080 0.000039 1997 9 20 50711 0.219923 0.411855 0.4119853 0.0022078 -0.000045 0.000092 0.000113 0.000099 0.0000107 0.0000526 0.000081 0.000040 1997 9 21 50712 0.220532 0.409425 0.4099097 0.0020039 -0.000060 0.000099 0.000114 0.000100 0.0000135 0.0000523 0.000083 0.000040 1997 9 22 50713 0.221241 0.406937 0.4079916 0.0018663 -0.000074 0.000106 0.000115 0.000101 0.0000118 0.0000520 0.000084 0.000041 1997 9 23 50714 0.221634 0.404258 0.4062328 0.0017484 -0.000089 0.000113 0.000116 0.000101 0.0000093 0.0000517 0.000086 0.000042 1997 9 24 50715 0.221712 0.401201 0.4046234 0.0017279 -0.000104 0.000120 0.000116 0.000101 0.0000047 0.0000513 0.000088 0.000043 1997 9 25 50716 0.221315 0.398095 0.4028431 0.0017436 -0.000087 0.000096 0.000117 0.000102 0.0000072 0.0000510 0.000089 0.000043 1997 9 26 50717 0.221095 0.394692 0.4009729 0.0018287 -0.000059 0.000061 0.000118 0.000102 0.0000107 0.0000506 0.000091 0.000044 1997 9 27 50718 0.220964 0.391377 0.3990821 0.0018755 -0.000032 0.000026 0.000118 0.000103 0.0000109 0.0000502 0.000092 0.000045 1997 9 28 50719 0.220870 0.388101 0.3971305 0.0019188 -0.000004 -0.000009 0.000119 0.000103 0.0000115 0.0000497 0.000094 0.000046 1997 9 29 50720 0.221039 0.385190 0.3951428 0.0019561 0.000023 -0.000044 0.000119 0.000103 0.0000121 0.0000492 0.000096 0.000047 1997 9 30 50721 0.221078 0.382299 0.3931910 0.0020141 0.000051 -0.000079 0.000119 0.000103 0.0000116 0.0000488 0.000098 0.000047 1997 10 1 50722 0.221115 0.379580 0.3913336 0.0020301 0.000078 -0.000114 0.000120 0.000104 0.0000085 0.0000483 0.000099 0.000048 1997 10 2 50723 0.221480 0.376604 0.3892551 0.0020918 0.000051 -0.000076 0.000121 0.000104 0.0000085 0.0000477 0.000101 0.000049 1997 10 3 50724 0.221744 0.373481 0.3870997 0.0020659 0.000005 -0.000012 0.000121 0.000104 0.0000094 0.0000472 0.000102 0.000049 1997 10 4 50725 0.221837 0.370162 0.3850049 0.0019972 -0.000041 0.000051 0.000122 0.000105 0.0000084 0.0000467 0.000104 0.000049 1997 10 5 50726 0.222159 0.367152 0.3830446 0.0019147 -0.000087 0.000115 0.000122 0.000105 0.0000049 0.0000461 0.000105 0.000050 1997 10 6 50727 0.222275 0.364644 0.3811711 0.0018582 -0.000133 0.000178 0.000122 0.000105 0.0000082 0.0000455 0.000106 0.000050 1997 10 7 50728 0.222583 0.362198 0.3793826 0.0018333 -0.000179 0.000241 0.000123 0.000106 0.0000094 0.0000450 0.000107 0.000050 1997 10 8 50729 0.222635 0.359771 0.3776681 0.0018588 -0.000096 0.000187 0.000123 0.000106 0.0000061 0.0000444 0.000108 0.000050 1997 10 9 50730 0.222592 0.357428 0.3757848 0.0019162 -0.000088 0.000183 0.000123 0.000106 0.0000055 0.0000439 0.000109 0.000050 1997 10 10 50731 0.222228 0.355301 0.3737724 0.0020042 -0.000113 0.000205 0.000123 0.000106 0.0000059 0.0000434 0.000105 0.000050 1997 10 11 50732 0.222244 0.352683 0.3716316 0.0021342 -0.000139 0.000226 0.000123 0.000106 0.0000063 0.0000429 0.000105 0.000049 1997 10 12 50733 0.223026 0.349938 0.3693429 0.0022930 -0.000165 0.000247 0.000123 0.000106 0.0000070 0.0000425 0.000105 0.000049 1997 10 13 50734 0.224011 0.347293 0.3669327 0.0024480 -0.000190 0.000269 0.000123 0.000107 0.0000085 0.0000420 0.000104 0.000049 1997 10 14 50735 0.224532 0.344777 0.3644496 0.0025652 -0.000216 0.000290 0.000123 0.000107 0.0000081 0.0000416 0.000104 0.000048 1997 10 15 50736 0.224961 0.342072 0.3619963 0.0025876 -0.000242 0.000311 0.000123 0.000107 0.0000042 0.0000413 0.000104 0.000048 1997 10 16 50737 0.225553 0.339524 0.3593432 0.0025555 -0.000232 0.000296 0.000123 0.000107 0.0000081 0.0000410 0.000104 0.000048 1997 10 17 50738 0.225855 0.336777 0.3567400 0.0024475 -0.000209 0.000269 0.000123 0.000107 0.0000111 0.0000408 0.000103 0.000048 1997 10 18 50739 0.225757 0.333723 0.3543692 0.0022631 -0.000187 0.000242 0.000123 0.000107 0.0000079 0.0000406 0.000103 0.000048 1997 10 19 50740 0.226017 0.330621 0.3522054 0.0020847 -0.000165 0.000215 0.000123 0.000107 0.0000062 0.0000405 0.000103 0.000048 1997 10 20 50741 0.226700 0.327614 0.3502004 0.0019518 -0.000142 0.000188 0.000123 0.000107 0.0000072 0.0000403 0.000102 0.000048 1997 10 21 50742 0.227756 0.324852 0.3483664 0.0018553 -0.000120 0.000161 0.000123 0.000107 0.0000067 0.0000402 0.000102 0.000048 1997 10 22 50743 0.228308 0.322459 0.3466856 0.0017852 -0.000014 0.000161 0.000123 0.000108 0.0000037 0.0000402 0.000102 0.000047 1997 10 23 50744 0.228195 0.320062 0.3448431 0.0017540 -0.000003 0.000143 0.000124 0.000108 0.0000115 0.0000401 0.000102 0.000048 1997 10 24 50745 0.227667 0.317396 0.3429916 0.0017791 -0.000028 0.000118 0.000124 0.000108 0.0000163 0.0000400 0.000101 0.000048 1997 10 25 50746 0.227082 0.314723 0.3412041 0.0018294 -0.000054 0.000093 0.000124 0.000108 0.0000099 0.0000400 0.000101 0.000048 1997 10 26 50747 0.226371 0.311775 0.3393768 0.0018968 -0.000080 0.000069 0.000124 0.000109 0.0000063 0.0000399 0.000101 0.000048 1997 10 27 50748 0.225512 0.308642 0.3375297 0.0019626 -0.000106 0.000044 0.000125 0.000109 0.0000102 0.0000399 0.000101 0.000048 1997 10 28 50749 0.224410 0.305596 0.3356243 0.0020197 -0.000131 0.000019 0.000125 0.000109 0.0000142 0.0000399 0.000101 0.000048 1997 10 29 50750 0.222790 0.302418 0.3336157 0.0020385 -0.000073 0.000102 0.000126 0.000110 0.0000069 0.0000399 0.000100 0.000048 1997 10 30 50751 0.220956 0.298979 0.3315543 0.0020774 -0.000114 0.000261 0.000124 0.000109 0.0000037 0.0000400 0.000099 0.000047 1997 10 31 50752 0.219354 0.295627 0.3293836 0.0021169 -0.000122 0.000278 0.000123 0.000108 0.0000046 0.0000400 0.000098 0.000046 1997 11 1 50753 0.218141 0.292257 0.3271684 0.0021319 -0.000104 0.000234 0.000123 0.000108 0.0000065 0.0000401 0.000096 0.000045 1997 11 2 50754 0.217595 0.289400 0.3249812 0.0021001 -0.000086 0.000190 0.000122 0.000108 0.0000080 0.0000402 0.000094 0.000043 1997 11 3 50755 0.217271 0.287187 0.3228932 0.0020601 -0.000067 0.000146 0.000122 0.000108 0.0000079 0.0000402 0.000093 0.000042 1997 11 4 50756 0.216525 0.284999 0.3208825 0.0020575 -0.000049 0.000102 0.000121 0.000107 0.0000069 0.0000403 0.000091 0.000041 1997 11 5 50757 0.215888 0.282845 0.3189966 0.0020682 -0.000031 0.000057 0.000121 0.000107 0.0000030 0.0000403 0.000090 0.000041 1997 11 6 50758 0.215375 0.280421 0.3167962 0.0021566 -0.000032 0.000044 0.000120 0.000107 0.0000113 0.0000404 0.000089 0.000040 1997 11 7 50759 0.214707 0.278089 0.3144404 0.0022946 -0.000039 0.000041 0.000120 0.000107 0.0000183 0.0000404 0.000088 0.000040 1997 11 8 50760 0.213896 0.275931 0.3120832 0.0024150 -0.000047 0.000037 0.000119 0.000106 0.0000100 0.0000404 0.000087 0.000039 1997 11 9 50761 0.213296 0.273488 0.3096268 0.0025487 -0.000055 0.000034 0.000118 0.000106 0.0000069 0.0000404 0.000086 0.000039 1997 11 10 50762 0.212611 0.271158 0.3070077 0.0026593 -0.000062 0.000031 0.000118 0.000105 0.0000083 0.0000405 0.000085 0.000039 1997 11 11 50763 0.211662 0.268837 0.3043592 0.0026892 -0.000070 0.000028 0.000117 0.000105 0.0000085 0.0000405 0.000084 0.000038 1997 11 12 50764 0.210286 0.266292 0.3018451 0.0026088 -0.000078 0.000025 0.000116 0.000104 0.0000050 0.0000405 0.000084 0.000038 1997 11 13 50765 0.208733 0.263623 0.2992201 0.0024327 -0.000117 0.000167 0.000115 0.000104 0.0000079 0.0000405 0.000083 0.000038 1997 11 14 50766 0.207043 0.261270 0.2967712 0.0021990 -0.000120 0.000205 0.000114 0.000103 0.0000102 0.0000405 0.000081 0.000037 1997 11 15 50767 0.205400 0.259142 0.2947002 0.0019549 -0.000099 0.000165 0.000113 0.000103 0.0000057 0.0000405 0.000080 0.000036 1997 11 16 50768 0.203761 0.256981 0.2928833 0.0017675 -0.000079 0.000126 0.000112 0.000102 0.0000037 0.0000404 0.000078 0.000035 1997 11 17 50769 0.202558 0.254732 0.2912931 0.0016581 -0.000058 0.000086 0.000111 0.000101 0.0000027 0.0000403 0.000077 0.000034 1997 11 18 50770 0.201621 0.252697 0.2897922 0.0015862 -0.000038 0.000046 0.000109 0.000100 0.0000018 0.0000402 0.000076 0.000034 1997 11 19 50771 0.200608 0.250376 0.2882229 0.0015853 0.000061 0.000160 0.000108 0.000100 0.0000021 0.0000401 0.000075 0.000034 1997 11 20 50772 0.199280 0.248114 0.2866385 0.0015892 0.000052 0.000105 0.000107 0.000099 0.0000037 0.0000399 0.000074 0.000034 1997 11 21 50773 0.197324 0.245546 0.2850301 0.0016017 0.000007 -0.000007 0.000106 0.000099 0.0000058 0.0000397 0.000073 0.000034 1997 11 22 50774 0.195604 0.242643 0.2833046 0.0016004 0.000041 0.000026 0.000105 0.000098 0.0000060 0.0000394 0.000072 0.000034 1997 11 23 50775 0.194027 0.239774 0.2816038 0.0016350 0.000083 0.000073 0.000103 0.000097 0.0000058 0.0000391 0.000071 0.000034 1997 11 24 50776 0.192214 0.236789 0.2800620 0.0016654 0.000124 0.000120 0.000101 0.000096 0.0000043 0.0000388 0.000070 0.000034 1997 11 25 50777 0.190194 0.234295 0.2785180 0.0016443 0.000165 0.000167 0.000099 0.000095 0.0000029 0.0000384 0.000069 0.000034 1997 11 26 50778 0.188368 0.232009 0.2768817 0.0015982 0.000035 0.000029 0.000097 0.000093 0.0000033 0.0000381 0.000068 0.000033 1997 11 27 50779 0.186154 0.230234 0.2752119 0.0015389 0.000004 0.000011 0.000095 0.000092 0.0000070 0.0000377 0.000066 0.000033 1997 11 28 50780 0.183602 0.228496 0.2735731 0.0014927 0.000007 0.000034 0.000093 0.000090 0.0000118 0.0000373 0.000065 0.000032 1997 11 29 50781 0.180962 0.226657 0.2720333 0.0014498 0.000010 0.000058 0.000090 0.000089 0.0000132 0.0000369 0.000064 0.000032 1997 11 30 50782 0.178262 0.225150 0.2706206 0.0014134 0.000013 0.000081 0.000088 0.000087 0.0000084 0.0000365 0.000062 0.000031 1997 12 1 50783 0.175564 0.223385 0.2692221 0.0014039 0.000016 0.000104 0.000085 0.000085 0.0000085 0.0000360 0.000061 0.000031 1997 12 2 50784 0.173287 0.221256 0.2678821 0.0014026 0.000019 0.000127 0.000083 0.000083 0.0000078 0.0000356 0.000060 0.000031 1997 12 3 50785 0.171795 0.219079 0.2666203 0.0014387 0.000022 0.000150 0.000081 0.000081 0.0000053 0.0000353 0.000059 0.000030 1997 12 4 50786 0.170419 0.217045 0.2650948 0.0015055 0.000056 0.000521 0.000078 0.000079 0.0000078 0.0000349 0.000058 0.000030 1997 12 5 50787 0.168710 0.215516 0.2634319 0.0016305 -0.000002 0.000578 0.000076 0.000077 0.0000092 0.0000346 0.000056 0.000029 1997 12 6 50788 0.166268 0.213942 0.2617036 0.0018252 -0.000097 0.000474 0.000073 0.000075 0.0000060 0.0000344 0.000055 0.000028 1997 12 7 50789 0.163834 0.212048 0.2597875 0.0020396 -0.000193 0.000370 0.000071 0.000073 0.0000056 0.0000341 0.000053 0.000027 1997 12 8 50790 0.161411 0.210250 0.2577014 0.0022171 -0.000288 0.000266 0.000068 0.000071 0.0000055 0.0000339 0.000052 0.000026 1997 12 9 50791 0.159000 0.208441 0.2554928 0.0022803 -0.000383 0.000162 0.000066 0.000069 0.0000055 0.0000338 0.000051 0.000025 1997 12 10 50792 0.156778 0.206714 0.2532619 0.0022260 -0.000133 0.000162 0.000064 0.000067 0.0000055 0.0000336 0.000049 0.000025 1997 12 11 50793 0.155334 0.205052 0.2510987 0.0021099 -0.000059 0.000100 0.000061 0.000065 0.0000030 0.0000335 0.000048 0.000024 1997 12 12 50794 0.153895 0.203562 0.2489243 0.0019684 -0.000021 0.000069 0.000059 0.000063 0.0000039 0.0000334 0.000046 0.000023 1997 12 13 50795 0.152143 0.202248 0.2469270 0.0018054 0.000029 0.000060 0.000057 0.000061 0.0000057 0.0000333 0.000045 0.000022 1997 12 14 50796 0.149752 0.200750 0.2452425 0.0016466 0.000080 0.000050 0.000055 0.000059 0.0000056 0.0000332 0.000043 0.000021 1997 12 15 50797 0.146708 0.198384 0.2437628 0.0015346 0.000130 0.000040 0.000052 0.000057 0.0000039 0.0000331 0.000042 0.000020 1997 12 16 50798 0.143900 0.195951 0.2423616 0.0014954 0.000180 0.000031 0.000050 0.000055 0.0000023 0.0000331 0.000041 0.000019 1997 12 17 50799 0.140885 0.193810 0.2408850 0.0014890 0.000162 0.000092 0.000048 0.000053 0.0000025 0.0000331 0.000039 0.000018 1997 12 18 50800 0.138654 0.192014 0.2393974 0.0015120 0.000076 0.000053 0.000046 0.000051 0.0000147 0.0000331 0.000038 0.000017 1997 12 19 50801 0.137026 0.191103 0.2377707 0.0015524 0.000062 0.000007 0.000047 0.000052 0.0000130 0.0000331 0.000038 0.000017 1997 12 20 50802 0.135128 0.190467 0.2360802 0.0016069 0.000094 -0.000026 0.000049 0.000054 0.0000071 0.0000332 0.000039 0.000018 1997 12 21 50803 0.132215 0.189590 0.2344431 0.0016742 0.000126 -0.000060 0.000050 0.000055 0.0000081 0.0000332 0.000040 0.000018 1997 12 22 50804 0.129439 0.188095 0.2328542 0.0017332 0.000158 -0.000093 0.000052 0.000057 0.0000061 0.0000333 0.000041 0.000019 1997 12 23 50805 0.126715 0.186714 0.2312466 0.0017577 0.000190 -0.000127 0.000054 0.000059 0.0000042 0.0000334 0.000042 0.000020 1997 12 24 50806 0.123535 0.184970 0.2295516 0.0016974 -0.000048 0.000124 0.000056 0.000061 0.0000042 0.0000335 0.000043 0.000020 1997 12 25 50807 0.120572 0.182962 0.2278515 0.0016374 -0.000067 0.000153 0.000058 0.000062 0.0000046 0.0000337 0.000043 0.000021 1997 12 26 50808 0.117905 0.181513 0.2262194 0.0015465 -0.000037 0.000131 0.000060 0.000064 0.0000051 0.0000338 0.000044 0.000021 1997 12 27 50809 0.115243 0.179982 0.2246858 0.0014218 -0.000007 0.000110 0.000061 0.000066 0.0000055 0.0000340 0.000045 0.000022 1997 12 28 50810 0.112922 0.178568 0.2232703 0.0013146 0.000024 0.000089 0.000063 0.000067 0.0000063 0.0000342 0.000046 0.000022 1997 12 29 50811 0.110070 0.177284 0.2219752 0.0012851 0.000054 0.000068 0.000064 0.000068 0.0000077 0.0000344 0.000047 0.000023 1997 12 30 50812 0.107358 0.176410 0.2207477 0.0012929 0.000084 0.000047 0.000066 0.000070 0.0000070 0.0000346 0.000048 0.000024 1997 12 31 50813 0.104514 0.175512 0.2195453 0.0013518 0.000114 0.000026 0.000067 0.000071 0.0000033 0.0000348 0.000050 0.000025 1998 1 1 50814 0.102412 0.174609 0.2181138 0.0015077 0.000119 0.000009 0.000070 0.000077 0.0000045 0.0000270 0.000024 0.000032 1998 1 2 50815 0.100073 0.173743 0.2164907 0.0016757 0.000118 -0.000008 0.000071 0.000078 0.0000062 0.0000272 0.000025 0.000032 1998 1 3 50816 0.097476 0.173004 0.2146678 0.0018432 0.000118 -0.000024 0.000072 0.000079 0.0000079 0.0000275 0.000025 0.000033 1998 1 4 50817 0.095068 0.172446 0.2126666 0.0019944 0.000117 -0.000040 0.000073 0.000080 0.0000095 0.0000277 0.000026 0.000034 1998 1 5 50818 0.092710 0.172106 0.2105799 0.0020732 0.000117 -0.000056 0.000073 0.000081 0.0000105 0.0000280 0.000027 0.000035 1998 1 6 50819 0.090274 0.171713 0.2085286 0.0020328 0.000116 -0.000073 0.000074 0.000082 0.0000102 0.0000282 0.000027 0.000037 1998 1 7 50820 0.087824 0.171173 0.2066975 0.0019152 0.000116 -0.000089 0.000075 0.000082 0.0000062 0.0000285 0.000028 0.000038 1998 1 8 50821 0.085287 0.170476 0.2047751 0.0017594 0.000122 -0.000073 0.000075 0.000083 0.0000082 0.0000288 0.000029 0.000039 1998 1 9 50822 0.082342 0.169673 0.2029877 0.0015754 0.000130 -0.000046 0.000076 0.000084 0.0000112 0.0000291 0.000029 0.000040 1998 1 10 50823 0.079144 0.168952 0.2014855 0.0014478 0.000138 -0.000019 0.000076 0.000084 0.0000133 0.0000294 0.000030 0.000040 1998 1 11 50824 0.076042 0.168460 0.2001112 0.0014149 0.000147 0.000008 0.000077 0.000085 0.0000181 0.0000296 0.000030 0.000041 1998 1 12 50825 0.072685 0.168330 0.1988099 0.0014356 0.000155 0.000035 0.000077 0.000085 0.0000115 0.0000299 0.000031 0.000042 1998 1 13 50826 0.069253 0.167934 0.1974622 0.0014747 0.000163 0.000062 0.000078 0.000086 0.0000049 0.0000302 0.000031 0.000043 1998 1 14 50827 0.066484 0.167748 0.1959635 0.0015644 0.000099 0.000080 0.000078 0.000086 0.0000030 0.0000304 0.000032 0.000043 1998 1 15 50828 0.063636 0.167630 0.1942562 0.0016373 0.000074 0.000073 0.000078 0.000086 0.0000064 0.0000307 0.000032 0.000043 1998 1 16 50829 0.060252 0.167552 0.1924930 0.0016835 0.000068 0.000059 0.000078 0.000086 0.0000094 0.0000309 0.000032 0.000043 1998 1 17 50830 0.056904 0.167522 0.1908050 0.0017113 0.000062 0.000045 0.000078 0.000086 0.0000082 0.0000311 0.000032 0.000043 1998 1 18 50831 0.053955 0.167462 0.1890839 0.0017466 0.000056 0.000031 0.000079 0.000086 0.0000084 0.0000312 0.000032 0.000043 1998 1 19 50832 0.051175 0.167894 0.1873459 0.0017872 0.000050 0.000018 0.000079 0.000086 0.0000086 0.0000314 0.000032 0.000043 1998 1 20 50833 0.048068 0.168474 0.1856383 0.0018003 0.000044 0.000004 0.000079 0.000086 0.0000079 0.0000316 0.000032 0.000043 1998 1 21 50834 0.044729 0.168381 0.1840283 0.0017479 0.000038 -0.000010 0.000079 0.000086 0.0000047 0.0000317 0.000033 0.000043 1998 1 22 50835 0.041121 0.167956 0.1822366 0.0016924 0.000180 -0.000043 0.000079 0.000086 0.0000059 0.0000318 0.000033 0.000043 1998 1 23 50836 0.037730 0.167467 0.1804361 0.0017089 0.000196 -0.000043 0.000079 0.000085 0.0000071 0.0000319 0.000032 0.000042 1998 1 24 50837 0.034551 0.167138 0.1787384 0.0017180 0.000147 -0.000029 0.000078 0.000085 0.0000055 0.0000319 0.000032 0.000041 1998 1 25 50838 0.031517 0.166836 0.1770506 0.0017184 0.000098 -0.000016 0.000078 0.000084 0.0000055 0.0000319 0.000032 0.000041 1998 1 26 50839 0.028391 0.166728 0.1754453 0.0017345 0.000050 -0.000002 0.000077 0.000083 0.0000039 0.0000320 0.000032 0.000040 1998 1 27 50840 0.025648 0.166795 0.1737661 0.0018129 0.000001 0.000012 0.000077 0.000082 0.0000023 0.0000320 0.000031 0.000039 1998 1 28 50841 0.023190 0.167338 0.1718687 0.0019689 0.000117 -0.000026 0.000076 0.000081 0.0000034 0.0000320 0.000031 0.000039 1998 1 29 50842 0.020367 0.167883 0.1697335 0.0022098 0.000203 -0.000093 0.000075 0.000080 0.0000033 0.0000319 0.000031 0.000038 1998 1 30 50843 0.017307 0.168557 0.1673861 0.0024138 0.000266 -0.000168 0.000074 0.000079 0.0000026 0.0000319 0.000030 0.000037 1998 1 31 50844 0.014143 0.169101 0.1647811 0.0025169 0.000210 -0.000092 0.000073 0.000078 0.0000053 0.0000319 0.000030 0.000036 1998 2 1 50845 0.010917 0.169634 0.1621318 0.0025395 0.000155 -0.000015 0.000072 0.000076 0.0000077 0.0000318 0.000029 0.000036 1998 2 2 50846 0.007777 0.170231 0.1595883 0.0025126 0.000099 0.000061 0.000071 0.000075 0.0000090 0.0000318 0.000029 0.000035 1998 2 3 50847 0.004606 0.171086 0.1571267 0.0024702 0.000043 0.000137 0.000069 0.000074 0.0000089 0.0000318 0.000029 0.000034 1998 2 4 50848 0.001233 0.171945 0.1548125 0.0023855 -0.000039 0.000084 0.000068 0.000072 0.0000057 0.0000318 0.000028 0.000033 1998 2 5 50849 -0.002092 0.172664 0.1523604 0.0023083 -0.000159 -0.000003 0.000067 0.000070 0.0000064 0.0000318 0.000027 0.000032 1998 2 6 50850 -0.005111 0.173354 0.1499902 0.0021952 -0.000174 -0.000017 0.000065 0.000069 0.0000078 0.0000318 0.000027 0.000031 1998 2 7 50851 -0.007771 0.174241 0.1478512 0.0021012 -0.000131 0.000012 0.000064 0.000067 0.0000076 0.0000318 0.000026 0.000029 1998 2 8 50852 -0.010074 0.174913 0.1458220 0.0020653 -0.000087 0.000040 0.000063 0.000065 0.0000082 0.0000319 0.000025 0.000028 1998 2 9 50853 -0.012385 0.175230 0.1438770 0.0020161 -0.000043 0.000069 0.000061 0.000063 0.0000139 0.0000319 0.000024 0.000027 1998 2 10 50854 -0.014994 0.175478 0.1419733 0.0019692 0.000001 0.000098 0.000059 0.000061 0.0000195 0.0000320 0.000024 0.000026 1998 2 11 50855 -0.017939 0.175419 0.1400542 0.0019391 0.000013 -0.000030 0.000061 0.000063 0.0000098 0.0000320 0.000024 0.000026 1998 2 12 50856 -0.020717 0.175677 0.1381208 0.0019751 0.000066 -0.000048 0.000062 0.000065 0.0000048 0.0000320 0.000024 0.000027 1998 2 13 50857 -0.023310 0.176367 0.1361643 0.0019941 0.000135 -0.000023 0.000064 0.000066 0.0000019 0.0000320 0.000025 0.000027 1998 2 14 50858 -0.025259 0.176860 0.1340516 0.0020038 0.000091 -0.000021 0.000065 0.000068 0.0000037 0.0000320 0.000025 0.000028 1998 2 15 50859 -0.026921 0.177397 0.1319703 0.0020109 0.000047 -0.000019 0.000066 0.000070 0.0000060 0.0000320 0.000025 0.000028 1998 2 16 50860 -0.028618 0.178439 0.1299926 0.0019914 0.000003 -0.000018 0.000067 0.000071 0.0000093 0.0000320 0.000026 0.000029 1998 2 17 50861 -0.030214 0.179923 0.1280816 0.0019383 -0.000040 -0.000016 0.000069 0.000073 0.0000098 0.0000319 0.000026 0.000029 1998 2 18 50862 -0.031973 0.181328 0.1262870 0.0018570 -0.000084 -0.000014 0.000070 0.000074 0.0000057 0.0000319 0.000027 0.000030 1998 2 19 50863 -0.034576 0.182819 0.1244388 0.0018041 -0.000035 -0.000022 0.000071 0.000076 0.0000113 0.0000319 0.000027 0.000031 1998 2 20 50864 -0.037826 0.183915 0.1225792 0.0017855 0.000047 -0.000034 0.000071 0.000077 0.0000138 0.0000318 0.000028 0.000031 1998 2 21 50865 -0.041084 0.185222 0.1207346 0.0017984 0.000128 -0.000046 0.000072 0.000078 0.0000071 0.0000318 0.000028 0.000032 1998 2 22 50866 -0.044801 0.186182 0.1189086 0.0018325 0.000209 -0.000058 0.000073 0.000079 0.0000052 0.0000318 0.000028 0.000032 1998 2 23 50867 -0.048099 0.186758 0.1170396 0.0018981 0.000291 -0.000070 0.000073 0.000080 0.0000067 0.0000318 0.000029 0.000033 1998 2 24 50868 -0.050846 0.187748 0.1151231 0.0020222 0.000372 -0.000082 0.000074 0.000081 0.0000064 0.0000318 0.000029 0.000034 1998 2 25 50869 -0.053554 0.188598 0.1131445 0.0021725 0.000178 -0.000046 0.000075 0.000082 0.0000030 0.0000318 0.000030 0.000034 1998 2 26 50870 -0.056042 0.189294 0.1107916 0.0023095 0.000094 -0.000030 0.000075 0.000082 0.0000039 0.0000318 0.000030 0.000034 1998 2 27 50871 -0.057835 0.190108 0.1082965 0.0024698 0.000064 -0.000023 0.000076 0.000083 0.0000085 0.0000318 0.000031 0.000034 1998 2 28 50872 -0.058790 0.191394 0.1057682 0.0026225 0.000035 -0.000016 0.000076 0.000084 0.0000137 0.0000318 0.000031 0.000034 1998 3 1 50873 -0.059443 0.193257 0.1031015 0.0026421 0.000006 -0.000009 0.000077 0.000084 0.0000126 0.0000318 0.000031 0.000035 1998 3 2 50874 -0.060469 0.194993 0.1004568 0.0025796 -0.000023 -0.000002 0.000077 0.000085 0.0000093 0.0000318 0.000032 0.000035 1998 3 3 50875 -0.061969 0.196835 0.0979608 0.0024253 -0.000052 0.000005 0.000077 0.000086 0.0000063 0.0000318 0.000032 0.000035 1998 3 4 50876 -0.063605 0.198487 0.0957606 0.0022362 -0.000081 0.000012 0.000078 0.000086 0.0000044 0.0000318 0.000032 0.000036 1998 3 5 50877 -0.065250 0.200477 0.0935220 0.0020786 -0.000076 0.000013 0.000078 0.000086 0.0000095 0.0000317 0.000033 0.000036 1998 3 6 50878 -0.066999 0.202421 0.0914075 0.0019755 -0.000058 0.000012 0.000078 0.000087 0.0000148 0.0000317 0.000033 0.000036 1998 3 7 50879 -0.068484 0.204288 0.0895427 0.0018985 -0.000040 0.000012 0.000079 0.000087 0.0000124 0.0000316 0.000034 0.000037 1998 3 8 50880 -0.070082 0.206454 0.0877380 0.0018398 -0.000022 0.000011 0.000079 0.000088 0.0000100 0.0000315 0.000034 0.000037 1998 3 9 50881 -0.071742 0.208520 0.0859343 0.0018206 -0.000005 0.000011 0.000079 0.000088 0.0000077 0.0000314 0.000035 0.000037 1998 3 10 50882 -0.073314 0.210737 0.0840810 0.0018802 0.000013 0.000010 0.000079 0.000088 0.0000053 0.0000313 0.000035 0.000037 1998 3 11 50883 -0.074939 0.212735 0.0821487 0.0019865 0.000031 0.000009 0.000079 0.000088 0.0000030 0.0000312 0.000035 0.000038 1998 3 12 50884 -0.076222 0.214654 0.0801014 0.0020816 -0.000015 0.000030 0.000080 0.000089 0.0000022 0.0000310 0.000036 0.000038 1998 3 13 50885 -0.077282 0.216663 0.0779311 0.0021268 -0.000025 0.000029 0.000080 0.000089 0.0000029 0.0000308 0.000036 0.000039 1998 3 14 50886 -0.078349 0.218935 0.0757162 0.0021231 -0.000015 0.000016 0.000080 0.000089 0.0000040 0.0000306 0.000037 0.000039 1998 3 15 50887 -0.079974 0.221082 0.0735368 0.0020962 -0.000004 0.000003 0.000080 0.000089 0.0000049 0.0000304 0.000037 0.000039 1998 3 16 50888 -0.082362 0.222886 0.0715143 0.0020577 0.000007 -0.000010 0.000080 0.000089 0.0000052 0.0000301 0.000038 0.000040 1998 3 17 50889 -0.084724 0.224383 0.0695578 0.0019848 0.000018 -0.000023 0.000080 0.000089 0.0000054 0.0000298 0.000038 0.000040 1998 3 18 50890 -0.087029 0.226102 0.0676811 0.0019053 0.000028 -0.000035 0.000080 0.000089 0.0000057 0.0000295 0.000038 0.000040 1998 3 19 50891 -0.088945 0.227630 0.0657432 0.0018087 0.000027 -0.000023 0.000080 0.000090 0.0000111 0.0000292 0.000039 0.000040 1998 3 20 50892 -0.090659 0.229291 0.0638596 0.0017542 0.000022 -0.000001 0.000080 0.000090 0.0000154 0.0000289 0.000039 0.000040 1998 3 21 50893 -0.092693 0.231299 0.0621103 0.0017366 0.000016 0.000020 0.000080 0.000090 0.0000121 0.0000286 0.000039 0.000040 1998 3 22 50894 -0.094919 0.232864 0.0603788 0.0017642 0.000011 0.000041 0.000080 0.000090 0.0000093 0.0000283 0.000039 0.000040 1998 3 23 50895 -0.096737 0.234077 0.0586609 0.0018354 0.000006 0.000063 0.000081 0.000090 0.0000077 0.0000279 0.000040 0.000040 1998 3 24 50896 -0.098089 0.235326 0.0568308 0.0019616 0.000000 0.000084 0.000081 0.000090 0.0000060 0.0000276 0.000040 0.000040 1998 3 25 50897 -0.099264 0.237153 0.0547710 0.0021662 0.000092 -0.000039 0.000081 0.000090 0.0000028 0.0000273 0.000040 0.000040 1998 3 26 50898 -0.100733 0.239001 0.0524641 0.0023942 0.000181 -0.000037 0.000081 0.000090 0.0000038 0.0000271 0.000040 0.000040 1998 3 27 50899 -0.102172 0.240845 0.0498341 0.0025409 0.000181 -0.000063 0.000081 0.000090 0.0000065 0.0000268 0.000040 0.000040 1998 3 28 50900 -0.103874 0.242937 0.0471246 0.0025690 0.000146 -0.000116 0.000081 0.000090 0.0000076 0.0000265 0.000040 0.000041 1998 3 29 50901 -0.105830 0.245220 0.0445694 0.0025220 0.000111 -0.000168 0.000081 0.000090 0.0000062 0.0000262 0.000040 0.000041 1998 3 30 50902 -0.107845 0.247632 0.0420635 0.0023878 0.000077 -0.000221 0.000081 0.000090 0.0000096 0.0000259 0.000040 0.000041 1998 3 31 50903 -0.109156 0.249738 0.0397762 0.0022259 0.000042 -0.000273 0.000081 0.000090 0.0000109 0.0000256 0.000040 0.000041 1998 4 1 50904 -0.109955 0.252085 0.0377886 0.0020552 0.000007 -0.000326 0.000080 0.000089 0.0000074 0.0000254 0.000041 0.000042 1998 4 2 50905 -0.110443 0.254644 0.0358526 0.0019159 0.000047 -0.000338 0.000081 0.000090 0.0000207 0.0000251 0.000040 0.000042 1998 4 3 50906 -0.111023 0.257176 0.0339719 0.0018093 0.000106 -0.000332 0.000080 0.000089 0.0000367 0.0000249 0.000040 0.000042 1998 4 4 50907 -0.111816 0.259419 0.0320344 0.0017869 0.000111 -0.000274 0.000080 0.000088 0.0000189 0.0000246 0.000040 0.000041 1998 4 5 50908 -0.112883 0.261656 0.0301338 0.0018143 0.000115 -0.000216 0.000079 0.000088 0.0000044 0.0000244 0.000039 0.000040 1998 4 6 50909 -0.113811 0.263577 0.0283515 0.0018379 0.000119 -0.000159 0.000079 0.000087 0.0000040 0.0000242 0.000039 0.000039 1998 4 7 50910 -0.114128 0.265692 0.0265343 0.0018714 0.000124 -0.000101 0.000078 0.000086 0.0000036 0.0000240 0.000038 0.000038 1998 4 8 50911 -0.114110 0.268345 0.0246790 0.0019250 0.000128 -0.000043 0.000077 0.000084 0.0000032 0.0000238 0.000038 0.000038 1998 4 9 50912 -0.113979 0.271000 0.0227404 0.0019429 0.000182 0.000031 0.000076 0.000083 0.0000034 0.0000236 0.000038 0.000037 1998 4 10 50913 -0.113808 0.273853 0.0206767 0.0019453 0.000196 0.000046 0.000075 0.000082 0.0000065 0.0000235 0.000037 0.000036 1998 4 11 50914 -0.113691 0.276729 0.0186328 0.0019586 0.000189 0.000038 0.000074 0.000080 0.0000088 0.0000233 0.000036 0.000036 1998 4 12 50915 -0.113713 0.279782 0.0167170 0.0019572 0.000182 0.000029 0.000073 0.000078 0.0000073 0.0000231 0.000036 0.000035 1998 4 13 50916 -0.114155 0.282429 0.0148613 0.0018941 0.000175 0.000021 0.000072 0.000077 0.0000065 0.0000229 0.000036 0.000034 1998 4 14 50917 -0.114657 0.285105 0.0130556 0.0018295 0.000168 0.000012 0.000071 0.000075 0.0000056 0.0000228 0.000035 0.000034 1998 4 15 50918 -0.115034 0.287681 0.0112628 0.0017692 0.000053 -0.000101 0.000069 0.000073 0.0000061 0.0000226 0.000035 0.000033 1998 4 16 50919 -0.114944 0.290185 0.0095264 0.0016949 0.000068 -0.000137 0.000068 0.000071 0.0000158 0.0000225 0.000034 0.000032 1998 4 17 50920 -0.114640 0.292922 0.0077621 0.0016535 0.000008 -0.000136 0.000068 0.000071 0.0000181 0.0000224 0.000034 0.000032 1998 4 18 50921 -0.114044 0.295787 0.0060081 0.0016661 -0.000109 -0.000131 0.000069 0.000072 0.0000141 0.0000223 0.000034 0.000033 1998 4 19 50922 -0.113645 0.298833 0.0042874 0.0017372 -0.000226 -0.000125 0.000069 0.000073 0.0000095 0.0000221 0.000035 0.000034 1998 4 20 50923 -0.113676 0.301447 0.0025107 0.0018456 -0.000342 -0.000120 0.000070 0.000074 0.0000109 0.0000220 0.000035 0.000035 1998 4 21 50924 -0.113648 0.304141 0.0006466 0.0019985 -0.000459 -0.000114 0.000070 0.000075 0.0000098 0.0000219 0.000036 0.000036 1998 4 22 50925 -0.113828 0.306870 -0.0013198 0.0021845 0.000001 -0.000093 0.000071 0.000076 0.0000043 0.0000218 0.000036 0.000036 1998 4 23 50926 -0.113755 0.309807 -0.0035674 0.0023735 0.000027 0.000026 0.000071 0.000077 0.0000023 0.0000217 0.000037 0.000037 1998 4 24 50927 -0.113649 0.312822 -0.0061514 0.0025360 -0.000015 0.000058 0.000071 0.000077 0.0000054 0.0000216 0.000037 0.000037 1998 4 25 50928 -0.113592 0.315277 -0.0088218 0.0025783 -0.000029 0.000046 0.000072 0.000078 0.0000079 0.0000216 0.000037 0.000038 1998 4 26 50929 -0.113220 0.317043 -0.0113564 0.0024819 -0.000043 0.000034 0.000072 0.000078 0.0000084 0.0000215 0.000037 0.000038 1998 4 27 50930 -0.112692 0.319150 -0.0137188 0.0022801 -0.000056 0.000021 0.000072 0.000079 0.0000134 0.0000214 0.000038 0.000039 1998 4 28 50931 -0.112637 0.321340 -0.0158311 0.0020538 -0.000070 0.000009 0.000072 0.000079 0.0000141 0.0000214 0.000038 0.000039 1998 4 29 50932 -0.113061 0.323853 -0.0176822 0.0018881 -0.000083 -0.000003 0.000072 0.000080 0.0000080 0.0000213 0.000038 0.000040 1998 4 30 50933 -0.113381 0.326167 -0.0196025 0.0018178 -0.000079 0.000004 0.000073 0.000080 0.0000076 0.0000213 0.000038 0.000040 1998 5 1 50934 -0.113430 0.328280 -0.0214585 0.0018073 -0.000069 0.000017 0.000073 0.000080 0.0000082 0.0000213 0.000038 0.000040 1998 5 2 50935 -0.113504 0.330234 -0.0231918 0.0018136 -0.000060 0.000031 0.000073 0.000081 0.0000071 0.0000213 0.000038 0.000040 1998 5 3 50936 -0.113636 0.332156 -0.0249305 0.0018056 -0.000050 0.000044 0.000073 0.000081 0.0000060 0.0000213 0.000038 0.000040 1998 5 4 50937 -0.114002 0.334249 -0.0266745 0.0017800 -0.000040 0.000058 0.000073 0.000081 0.0000049 0.0000213 0.000038 0.000040 1998 5 5 50938 -0.114197 0.336366 -0.0284245 0.0017967 -0.000030 0.000071 0.000073 0.000081 0.0000038 0.0000213 0.000039 0.000040 1998 5 6 50939 -0.114517 0.339021 -0.0302079 0.0018336 0.000128 0.000020 0.000074 0.000081 0.0000026 0.0000212 0.000038 0.000040 1998 5 7 50940 -0.114565 0.341290 -0.0320443 0.0018675 0.000042 -0.000042 0.000073 0.000081 0.0000020 0.0000212 0.000038 0.000040 1998 5 8 50941 -0.114494 0.343414 -0.0339909 0.0018607 0.000003 -0.000077 0.000073 0.000081 0.0000059 0.0000211 0.000038 0.000040 1998 5 9 50942 -0.114345 0.345460 -0.0359186 0.0018245 0.000011 -0.000100 0.000073 0.000081 0.0000089 0.0000211 0.000038 0.000041 1998 5 10 50943 -0.114000 0.347416 -0.0376928 0.0017739 0.000019 -0.000123 0.000073 0.000081 0.0000057 0.0000210 0.000038 0.000041 1998 5 11 50944 -0.113345 0.349467 -0.0394240 0.0016819 0.000028 -0.000145 0.000073 0.000081 0.0000075 0.0000209 0.000038 0.000041 1998 5 12 50945 -0.112875 0.351593 -0.0410239 0.0015983 0.000036 -0.000168 0.000073 0.000081 0.0000080 0.0000207 0.000038 0.000041 1998 5 13 50946 -0.112401 0.353778 -0.0424085 0.0015061 0.000044 -0.000191 0.000073 0.000081 0.0000051 0.0000206 0.000038 0.000042 1998 5 14 50947 -0.112034 0.355984 -0.0439240 0.0014252 0.000051 -0.000181 0.000073 0.000081 0.0000059 0.0000204 0.000038 0.000042 1998 5 15 50948 -0.111487 0.357861 -0.0454290 0.0014040 0.000057 -0.000159 0.000072 0.000080 0.0000085 0.0000202 0.000038 0.000042 1998 5 16 50949 -0.110942 0.359706 -0.0468481 0.0014790 0.000063 -0.000138 0.000072 0.000080 0.0000100 0.0000200 0.000038 0.000042 1998 5 17 50950 -0.110665 0.361496 -0.0484014 0.0016155 0.000070 -0.000116 0.000072 0.000080 0.0000058 0.0000198 0.000038 0.000042 1998 5 18 50951 -0.110454 0.363305 -0.0501128 0.0017859 0.000076 -0.000095 0.000072 0.000080 0.0000083 0.0000196 0.000038 0.000042 1998 5 19 50952 -0.110104 0.364998 -0.0519874 0.0019874 0.000082 -0.000073 0.000071 0.000079 0.0000088 0.0000194 0.000037 0.000042 1998 5 20 50953 -0.109965 0.367087 -0.0539696 0.0021540 0.000089 -0.000051 0.000071 0.000079 0.0000039 0.0000191 0.000037 0.000042 1998 5 21 50954 -0.110080 0.369288 -0.0561971 0.0022849 0.000054 -0.000138 0.000071 0.000079 0.0000023 0.0000189 0.000037 0.000042 1998 5 22 50955 -0.109660 0.371746 -0.0586677 0.0023704 0.000039 -0.000160 0.000071 0.000079 0.0000058 0.0000187 0.000037 0.000042 1998 5 23 50956 -0.109206 0.374648 -0.0611627 0.0023601 0.000037 -0.000143 0.000070 0.000078 0.0000085 0.0000184 0.000038 0.000042 1998 5 24 50957 -0.108777 0.377363 -0.0634857 0.0022487 0.000035 -0.000126 0.000070 0.000078 0.0000070 0.0000182 0.000038 0.000043 1998 5 25 50958 -0.108173 0.379926 -0.0656437 0.0020493 0.000033 -0.000109 0.000070 0.000078 0.0000096 0.0000180 0.000038 0.000043 1998 5 26 50959 -0.107590 0.382343 -0.0675414 0.0018141 0.000031 -0.000092 0.000070 0.000077 0.0000102 0.0000178 0.000038 0.000043 1998 5 27 50960 -0.107377 0.384666 -0.0691162 0.0016052 0.000029 -0.000075 0.000070 0.000077 0.0000064 0.0000177 0.000038 0.000044 1998 5 28 50961 -0.107518 0.386581 -0.0707095 0.0014539 0.000032 -0.000060 0.000070 0.000077 0.0000069 0.0000176 0.000038 0.000044 1998 5 29 50962 -0.107346 0.387966 -0.0721904 0.0013577 0.000038 -0.000047 0.000069 0.000077 0.0000112 0.0000174 0.000038 0.000044 1998 5 30 50963 -0.106545 0.389412 -0.0734819 0.0013346 0.000043 -0.000034 0.000069 0.000077 0.0000181 0.0000173 0.000038 0.000044 1998 5 31 50964 -0.105827 0.391473 -0.0747626 0.0013373 0.000049 -0.000021 0.000069 0.000077 0.0000184 0.0000172 0.000038 0.000044 1998 6 1 50965 -0.105343 0.393694 -0.0761331 0.0013264 0.000055 -0.000007 0.000069 0.000077 0.0000121 0.0000171 0.000038 0.000044 1998 6 2 50966 -0.104805 0.395717 -0.0774491 0.0013211 0.000060 0.000006 0.000069 0.000077 0.0000068 0.0000170 0.000038 0.000044 1998 6 3 50967 -0.104381 0.397673 -0.0786148 0.0013230 0.000066 0.000019 0.000070 0.000077 0.0000036 0.0000169 0.000038 0.000044 1998 6 4 50968 -0.104642 0.399313 -0.0799838 0.0013073 0.000075 0.000011 0.000070 0.000077 0.0000050 0.0000169 0.000037 0.000043 1998 6 5 50969 -0.104825 0.400863 -0.0813596 0.0012661 0.000086 -0.000004 0.000070 0.000077 0.0000072 0.0000168 0.000037 0.000043 1998 6 6 50970 -0.104657 0.402517 -0.0825772 0.0011706 0.000097 -0.000019 0.000070 0.000077 0.0000080 0.0000168 0.000037 0.000043 1998 6 7 50971 -0.104190 0.403945 -0.0836568 0.0010501 0.000107 -0.000034 0.000069 0.000077 0.0000086 0.0000168 0.000037 0.000042 1998 6 8 50972 -0.103656 0.405680 -0.0846448 0.0009207 0.000118 -0.000049 0.000069 0.000076 0.0000080 0.0000167 0.000037 0.000042 1998 6 9 50973 -0.103125 0.407256 -0.0854589 0.0008131 0.000129 -0.000064 0.000069 0.000076 0.0000072 0.0000167 0.000036 0.000042 1998 6 10 50974 -0.102267 0.408823 -0.0860683 0.0007484 0.000140 -0.000079 0.000069 0.000076 0.0000057 0.0000167 0.000036 0.000042 1998 6 11 50975 -0.101226 0.410532 -0.0868321 0.0006987 0.000140 -0.000092 0.000069 0.000075 0.0000065 0.0000167 0.000036 0.000041 1998 6 12 50976 -0.100421 0.412136 -0.0876196 0.0006947 0.000136 -0.000105 0.000069 0.000075 0.0000108 0.0000168 0.000036 0.000040 1998 6 13 50977 -0.100038 0.413483 -0.0883313 0.0007613 0.000133 -0.000117 0.000069 0.000075 0.0000142 0.0000168 0.000035 0.000040 1998 6 14 50978 -0.099503 0.414584 -0.0890314 0.0008432 0.000130 -0.000130 0.000068 0.000074 0.0000078 0.0000169 0.000035 0.000039 1998 6 15 50979 -0.098379 0.415738 -0.0898043 0.0008927 0.000126 -0.000143 0.000068 0.000074 0.0000060 0.0000169 0.000035 0.000039 1998 6 16 50980 -0.097054 0.417298 -0.0906625 0.0009397 0.000123 -0.000155 0.000068 0.000074 0.0000043 0.0000170 0.000035 0.000039 1998 6 17 50981 -0.095412 0.418642 -0.0916331 0.0009898 0.000190 -0.000209 0.000068 0.000073 0.0000029 0.0000171 0.000035 0.000038 1998 6 18 50982 -0.093634 0.420511 -0.0926357 0.0009981 -0.000003 -0.000047 0.000068 0.000073 0.0000023 0.0000171 0.000034 0.000038 1998 6 19 50983 -0.091764 0.422132 -0.0937295 0.0009568 -0.000073 0.000070 0.000068 0.000072 0.0000033 0.0000172 0.000034 0.000038 1998 6 20 50984 -0.089760 0.423733 -0.0947495 0.0008636 -0.000065 0.000144 0.000067 0.000072 0.0000046 0.0000173 0.000034 0.000038 1998 6 21 50985 -0.088091 0.425043 -0.0955796 0.0007300 -0.000056 0.000218 0.000067 0.000072 0.0000064 0.0000174 0.000034 0.000038 1998 6 22 50986 -0.086446 0.426184 -0.0962820 0.0005945 -0.000048 0.000292 0.000067 0.000071 0.0000095 0.0000175 0.000034 0.000038 1998 6 23 50987 -0.084734 0.427472 -0.0967746 0.0004629 -0.000039 0.000365 0.000066 0.000071 0.0000108 0.0000176 0.000034 0.000038 1998 6 24 50988 -0.082756 0.428904 -0.0970456 0.0003854 0.000014 -0.000044 0.000066 0.000070 0.0000090 0.0000177 0.000034 0.000038 1998 6 25 50989 -0.081249 0.430722 -0.0973949 0.0003705 0.000054 -0.000060 0.000066 0.000070 0.0000033 0.0000179 0.000034 0.000037 1998 6 26 50990 -0.079870 0.432161 -0.0979138 0.0003835 0.000068 -0.000069 0.000066 0.000070 0.0000081 0.0000180 0.000034 0.000037 1998 6 27 50991 -0.078238 0.433315 -0.0984401 0.0004257 0.000071 -0.000139 0.000067 0.000071 0.0000140 0.0000181 0.000034 0.000038 1998 6 28 50992 -0.076303 0.434466 -0.0988806 0.0004846 0.000074 -0.000208 0.000068 0.000072 0.0000132 0.0000183 0.000035 0.000039 1998 6 29 50993 -0.073820 0.435626 -0.0993840 0.0005421 0.000077 -0.000278 0.000068 0.000073 0.0000147 0.0000185 0.000036 0.000040 1998 6 30 50994 -0.071139 0.437002 -0.0999152 0.0005856 0.000080 -0.000348 0.000069 0.000074 0.0000127 0.0000187 0.000037 0.000041 1998 7 1 50995 -0.068252 0.438780 -0.1004289 0.0006134 0.000102 -0.000177 0.000070 0.000075 0.0000054 0.0000189 0.000037 0.000042 1998 7 2 50996 -0.065569 0.440728 -0.1010250 0.0006042 -0.000181 0.000015 0.000070 0.000076 0.0000032 0.0000191 0.000037 0.000042 1998 7 3 50997 -0.063052 0.442166 -0.1016777 0.0005219 -0.000242 0.000049 0.000071 0.000076 0.0000095 0.0000193 0.000038 0.000042 1998 7 4 50998 -0.060470 0.443764 -0.1022480 0.0004439 -0.000183 0.000028 0.000072 0.000077 0.0000151 0.0000195 0.000038 0.000042 1998 7 5 50999 -0.058076 0.445436 -0.1026256 0.0003451 -0.000123 0.000007 0.000072 0.000078 0.0000108 0.0000197 0.000038 0.000042 1998 7 6 51000 -0.055359 0.447306 -0.1029177 0.0002512 -0.000063 -0.000013 0.000073 0.000078 0.0000125 0.0000199 0.000038 0.000043 1998 7 7 51001 -0.052889 0.448888 -0.1030683 0.0001294 -0.000003 -0.000034 0.000073 0.000079 0.0000125 0.0000200 0.000039 0.000043 1998 7 8 51002 -0.050260 0.450009 -0.1030174 0.0000400 0.000056 -0.000055 0.000073 0.000079 0.0000067 0.0000202 0.000039 0.000043 1998 7 9 51003 -0.047813 0.451097 -0.1030987 0.0000257 0.000038 -0.000069 0.000074 0.000080 0.0000093 0.0000203 0.000039 0.000043 1998 7 10 51004 -0.045214 0.452429 -0.1032279 0.0000858 -0.000007 -0.000080 0.000074 0.000080 0.0000138 0.0000204 0.000039 0.000043 1998 7 11 51005 -0.042778 0.454337 -0.1033505 0.0002393 -0.000052 -0.000091 0.000074 0.000080 0.0000139 0.0000205 0.000039 0.000043 1998 7 12 51006 -0.040208 0.456145 -0.1036150 0.0004082 -0.000096 -0.000102 0.000074 0.000080 0.0000112 0.0000205 0.000039 0.000043 1998 7 13 51007 -0.037717 0.457669 -0.1040699 0.0005697 -0.000141 -0.000113 0.000074 0.000081 0.0000085 0.0000206 0.000039 0.000042 1998 7 14 51008 -0.035372 0.459088 -0.1046816 0.0006822 -0.000179 -0.000116 0.000075 0.000081 0.0000057 0.0000206 0.000040 0.000042 1998 7 15 51009 -0.032915 0.460543 -0.1054210 0.0007402 -0.000060 0.000068 0.000075 0.000081 0.0000032 0.0000206 0.000040 0.000042 1998 7 16 51010 -0.030785 0.461675 -0.1061730 0.0007155 -0.000114 -0.000035 0.000075 0.000081 0.0000026 0.0000206 0.000040 0.000042 1998 7 17 51011 -0.028593 0.462493 -0.1069204 0.0006209 -0.000116 -0.000150 0.000075 0.000081 0.0000040 0.0000206 0.000040 0.000042 1998 7 18 51012 -0.026544 0.463315 -0.1075729 0.0004876 -0.000077 -0.000234 0.000075 0.000081 0.0000057 0.0000206 0.000040 0.000043 1998 7 19 51013 -0.024552 0.464177 -0.1080664 0.0003466 -0.000038 -0.000317 0.000074 0.000081 0.0000096 0.0000205 0.000041 0.000043 1998 7 20 51014 -0.022494 0.465086 -0.1083722 0.0002150 0.000001 -0.000400 0.000075 0.000081 0.0000201 0.0000205 0.000041 0.000044 1998 7 21 51015 -0.020532 0.465928 -0.1085086 0.0001129 0.000040 -0.000484 0.000075 0.000081 0.0000242 0.0000205 0.000041 0.000044 1998 7 22 51016 -0.018699 0.466825 -0.1084511 0.0000765 -0.000008 -0.000162 0.000075 0.000081 0.0000121 0.0000205 0.000041 0.000045 1998 7 23 51017 -0.016626 0.467705 -0.1086467 0.0000990 -0.000014 -0.000050 0.000075 0.000082 0.0000163 0.0000205 0.000041 0.000044 1998 7 24 51018 -0.014303 0.468510 -0.1089161 0.0001785 0.000001 -0.000037 0.000075 0.000082 0.0000210 0.0000205 0.000041 0.000044 1998 7 25 51019 -0.011953 0.469144 -0.1091330 0.0003134 0.000016 -0.000024 0.000075 0.000082 0.0000156 0.0000205 0.000041 0.000043 1998 7 26 51020 -0.009352 0.469876 -0.1094979 0.0004186 0.000031 -0.000011 0.000075 0.000082 0.0000153 0.0000205 0.000041 0.000043 1998 7 27 51021 -0.006654 0.470998 -0.1099503 0.0004733 0.000046 0.000002 0.000075 0.000082 0.0000150 0.0000206 0.000040 0.000042 1998 7 28 51022 -0.004208 0.472120 -0.1104006 0.0004639 0.000061 0.000015 0.000075 0.000082 0.0000126 0.0000206 0.000040 0.000042 1998 7 29 51023 -0.001851 0.473252 -0.1107492 0.0004537 0.000076 0.000028 0.000075 0.000082 0.0000051 0.0000207 0.000040 0.000042 1998 7 30 51024 0.000284 0.474475 -0.1111842 0.0004688 -0.000005 -0.000144 0.000075 0.000082 0.0000037 0.0000207 0.000040 0.000041 1998 7 31 51025 0.001996 0.475662 -0.1118023 0.0004739 -0.000043 -0.000189 0.000075 0.000082 0.0000107 0.0000208 0.000039 0.000041 1998 8 1 51026 0.003816 0.476618 -0.1123769 0.0004425 -0.000053 -0.000164 0.000075 0.000082 0.0000172 0.0000209 0.000039 0.000040 1998 8 2 51027 0.005919 0.477264 -0.1127526 0.0003988 -0.000063 -0.000138 0.000075 0.000082 0.0000178 0.0000210 0.000039 0.000039 1998 8 3 51028 0.007725 0.477561 -0.1131214 0.0003360 -0.000074 -0.000113 0.000075 0.000082 0.0000193 0.0000211 0.000038 0.000039 1998 8 4 51029 0.009656 0.477768 -0.1134110 0.0003187 -0.000084 -0.000088 0.000075 0.000081 0.0000175 0.0000212 0.000038 0.000038 1998 8 5 51030 0.011872 0.478261 -0.1135903 0.0003221 -0.000094 -0.000062 0.000075 0.000081 0.0000083 0.0000214 0.000037 0.000037 1998 8 6 51031 0.014164 0.478500 -0.1139819 0.0003597 -0.000099 -0.000067 0.000075 0.000080 0.0000093 0.0000215 0.000037 0.000036 1998 8 7 51032 0.016139 0.478836 -0.1144717 0.0004417 -0.000103 -0.000081 0.000075 0.000080 0.0000202 0.0000216 0.000036 0.000035 1998 8 8 51033 0.017758 0.478860 -0.1149989 0.0005838 -0.000106 -0.000096 0.000074 0.000079 0.0000301 0.0000218 0.000035 0.000034 1998 8 9 51034 0.019822 0.478500 -0.1156598 0.0007723 -0.000109 -0.000111 0.000074 0.000078 0.0000131 0.0000220 0.000035 0.000034 1998 8 10 51035 0.022186 0.478555 -0.1164296 0.0009193 -0.000112 -0.000125 0.000073 0.000077 0.0000073 0.0000221 0.000034 0.000033 1998 8 11 51036 0.024699 0.478620 -0.1173203 0.0009931 -0.000115 -0.000140 0.000073 0.000076 0.0000015 0.0000223 0.000034 0.000032 1998 8 12 51037 0.027570 0.478692 -0.1183150 0.0009926 -0.000133 -0.000198 0.000073 0.000077 0.0000031 0.0000225 0.000034 0.000033 1998 8 13 51038 0.030527 0.478719 -0.1193911 0.0009207 -0.000101 -0.000220 0.000074 0.000078 0.0000108 0.0000227 0.000035 0.000034 1998 8 14 51039 0.033381 0.478566 -0.1203289 0.0007615 -0.000052 -0.000227 0.000075 0.000079 0.0000148 0.0000229 0.000036 0.000035 1998 8 15 51040 0.035497 0.478500 -0.1209981 0.0005601 -0.000004 -0.000235 0.000075 0.000080 0.0000096 0.0000232 0.000037 0.000036 1998 8 16 51041 0.037246 0.478262 -0.1214888 0.0003874 0.000045 -0.000242 0.000076 0.000081 0.0000087 0.0000234 0.000037 0.000037 1998 8 17 51042 0.039311 0.477788 -0.1218028 0.0002935 0.000094 -0.000250 0.000077 0.000082 0.0000133 0.0000237 0.000038 0.000038 1998 8 18 51043 0.041633 0.477403 -0.1219848 0.0002324 0.000142 -0.000257 0.000077 0.000083 0.0000138 0.0000240 0.000039 0.000039 1998 8 19 51044 0.043871 0.477281 -0.1220677 0.0001967 -0.000151 -0.000215 0.000078 0.000084 0.0000070 0.0000243 0.000040 0.000040 1998 8 20 51045 0.046144 0.477395 -0.1223307 0.0002125 -0.000220 -0.000197 0.000079 0.000084 0.0000102 0.0000247 0.000040 0.000041 1998 8 21 51046 0.048279 0.477518 -0.1226718 0.0003055 -0.000213 -0.000187 0.000079 0.000085 0.0000155 0.0000250 0.000041 0.000041 1998 8 22 51047 0.050305 0.477290 -0.1230393 0.0004111 -0.000206 -0.000176 0.000080 0.000086 0.0000184 0.0000253 0.000041 0.000042 1998 8 23 51048 0.052242 0.476779 -0.1234806 0.0004720 -0.000199 -0.000166 0.000080 0.000087 0.0000194 0.0000256 0.000042 0.000042 1998 8 24 51049 0.054132 0.476613 -0.1239197 0.0005258 -0.000192 -0.000156 0.000081 0.000087 0.0000125 0.0000259 0.000042 0.000043 1998 8 25 51050 0.056080 0.476628 -0.1244214 0.0005782 -0.000185 -0.000146 0.000081 0.000088 0.0000056 0.0000262 0.000043 0.000043 1998 8 26 51051 0.058169 0.476715 -0.1250554 0.0006458 -0.000013 -0.000132 0.000082 0.000088 0.0000046 0.0000265 0.000043 0.000043 1998 8 27 51052 0.060370 0.476622 -0.1257258 0.0006248 -0.000057 -0.000144 0.000082 0.000089 0.0000036 0.0000268 0.000043 0.000043 1998 8 28 51053 0.063059 0.476551 -0.1264498 0.0005585 -0.000081 -0.000144 0.000082 0.000089 0.0000066 0.0000271 0.000043 0.000043 1998 8 29 51054 0.065558 0.476501 -0.1271020 0.0005115 -0.000071 -0.000137 0.000082 0.000089 0.0000103 0.0000274 0.000043 0.000043 1998 8 30 51055 0.067612 0.476584 -0.1276460 0.0005338 -0.000060 -0.000130 0.000083 0.000090 0.0000128 0.0000277 0.000044 0.000043 1998 8 31 51056 0.069500 0.476260 -0.1282145 0.0005757 -0.000050 -0.000123 0.000083 0.000090 0.0000153 0.0000279 0.000044 0.000043 1998 9 1 51057 0.071158 0.475862 -0.1287563 0.0006096 -0.000039 -0.000116 0.000083 0.000090 0.0000140 0.0000282 0.000044 0.000043 1998 9 2 51058 0.072864 0.475006 -0.1292671 0.0006558 -0.000028 -0.000109 0.000083 0.000090 0.0000068 0.0000284 0.000044 0.000043 1998 9 3 51059 0.074729 0.473719 -0.1300373 0.0007383 -0.000020 -0.000109 0.000083 0.000090 0.0000097 0.0000287 0.000044 0.000043 1998 9 4 51060 0.077016 0.472403 -0.1309357 0.0008553 -0.000012 -0.000110 0.000083 0.000090 0.0000141 0.0000289 0.000044 0.000042 1998 9 5 51061 0.079813 0.471219 -0.1318661 0.0010525 -0.000004 -0.000111 0.000083 0.000090 0.0000117 0.0000291 0.000044 0.000042 1998 9 6 51062 0.082454 0.470298 -0.1330399 0.0012446 0.000004 -0.000112 0.000083 0.000090 0.0000090 0.0000292 0.000044 0.000042 1998 9 7 51063 0.084873 0.469261 -0.1343589 0.0013975 0.000012 -0.000113 0.000083 0.000090 0.0000117 0.0000294 0.000044 0.000041 1998 9 8 51064 0.087221 0.468503 -0.1357520 0.0014646 0.000020 -0.000115 0.000083 0.000091 0.0000120 0.0000295 0.000044 0.000041 1998 9 9 51065 0.089328 0.468002 -0.1370662 0.0014436 0.000028 -0.000116 0.000084 0.000091 0.0000045 0.0000296 0.000044 0.000041 1998 9 10 51066 0.091351 0.467372 -0.1385590 0.0013342 0.000021 -0.000113 0.000084 0.000091 0.0000075 0.0000297 0.000044 0.000041 1998 9 11 51067 0.093168 0.466822 -0.1399237 0.0011469 0.000008 -0.000109 0.000084 0.000091 0.0000129 0.0000298 0.000044 0.000041 1998 9 12 51068 0.094909 0.466266 -0.1409467 0.0009508 -0.000004 -0.000105 0.000084 0.000092 0.0000134 0.0000298 0.000044 0.000041 1998 9 13 51069 0.096675 0.465900 -0.1418455 0.0007821 -0.000017 -0.000101 0.000084 0.000092 0.0000088 0.0000298 0.000044 0.000041 1998 9 14 51070 0.098927 0.465333 -0.1425594 0.0006895 -0.000029 -0.000097 0.000084 0.000092 0.0000099 0.0000298 0.000044 0.000041 1998 9 15 51071 0.101645 0.465125 -0.1431916 0.0006925 -0.000042 -0.000093 0.000085 0.000092 0.0000098 0.0000297 0.000044 0.000041 1998 9 16 51072 0.104169 0.464886 -0.1437784 0.0007538 -0.000054 -0.000089 0.000085 0.000092 0.0000062 0.0000296 0.000044 0.000042 1998 9 17 51073 0.106404 0.464592 -0.1446191 0.0008291 -0.000036 -0.000014 0.000085 0.000093 0.0000092 0.0000295 0.000044 0.000042 1998 9 18 51074 0.107908 0.464062 -0.1455760 0.0008976 -0.000023 0.000050 0.000085 0.000093 0.0000132 0.0000294 0.000043 0.000041 1998 9 19 51075 0.109080 0.462798 -0.1465304 0.0009878 -0.000046 0.000027 0.000085 0.000093 0.0000119 0.0000293 0.000043 0.000040 1998 9 20 51076 0.110389 0.461232 -0.1476150 0.0010913 -0.000068 0.000004 0.000085 0.000093 0.0000080 0.0000291 0.000042 0.000039 1998 9 21 51077 0.111979 0.459693 -0.1487434 0.0011480 -0.000091 -0.000019 0.000085 0.000093 0.0000121 0.0000290 0.000042 0.000039 1998 9 22 51078 0.113769 0.458197 -0.1498368 0.0011124 -0.000114 -0.000042 0.000085 0.000093 0.0000127 0.0000289 0.000042 0.000038 1998 9 23 51079 0.115824 0.456692 -0.1508037 0.0010491 -0.000137 -0.000064 0.000086 0.000093 0.0000044 0.0000287 0.000041 0.000037 1998 9 24 51080 0.117609 0.455203 -0.1519291 0.0009886 -0.000127 -0.000048 0.000086 0.000093 0.0000074 0.0000286 0.000041 0.000037 1998 9 25 51081 0.119165 0.453869 -0.1530260 0.0009357 -0.000105 -0.000018 0.000086 0.000093 0.0000126 0.0000284 0.000040 0.000036 1998 9 26 51082 0.120343 0.452745 -0.1539740 0.0009136 -0.000083 0.000012 0.000086 0.000093 0.0000125 0.0000282 0.000040 0.000036 1998 9 27 51083 0.121296 0.451498 -0.1548686 0.0008691 -0.000062 0.000042 0.000086 0.000093 0.0000084 0.0000280 0.000040 0.000036 1998 9 28 51084 0.122207 0.449898 -0.1556007 0.0008209 -0.000040 0.000071 0.000085 0.000092 0.0000060 0.0000279 0.000040 0.000036 1998 9 29 51085 0.123205 0.448030 -0.1563131 0.0008205 -0.000018 0.000101 0.000085 0.000092 0.0000035 0.0000277 0.000039 0.000035 1998 9 30 51086 0.124166 0.446443 -0.1571633 0.0009021 -0.000018 0.000068 0.000085 0.000092 0.0000049 0.0000275 0.000039 0.000035 1998 10 1 51087 0.125194 0.445179 -0.1581554 0.0010650 -0.000057 0.000014 0.000085 0.000091 0.0000038 0.0000274 0.000039 0.000035 1998 10 2 51088 0.126526 0.444115 -0.1593433 0.0012753 -0.000108 -0.000046 0.000085 0.000091 0.0000017 0.0000272 0.000038 0.000034 1998 10 3 51089 0.128007 0.442674 -0.1608450 0.0015217 -0.000086 -0.000048 0.000085 0.000091 0.0000038 0.0000270 0.000038 0.000034 1998 10 4 51090 0.129782 0.441305 -0.1625452 0.0017262 -0.000057 -0.000046 0.000086 0.000092 0.0000056 0.0000269 0.000039 0.000035 1998 10 5 51091 0.131498 0.439786 -0.1642756 0.0018693 -0.000027 -0.000044 0.000086 0.000093 0.0000042 0.0000267 0.000039 0.000036 1998 10 6 51092 0.132908 0.438183 -0.1660957 0.0018893 0.000002 -0.000041 0.000087 0.000093 0.0000028 0.0000266 0.000039 0.000037 1998 10 7 51093 0.134278 0.436221 -0.1679637 0.0018212 0.000056 -0.000171 0.000088 0.000094 0.0000039 0.0000265 0.000040 0.000037 1998 10 8 51094 0.135557 0.433998 -0.1697534 0.0017143 -0.000081 -0.000057 0.000088 0.000095 0.0000029 0.0000264 0.000040 0.000038 1998 10 9 51095 0.137162 0.432004 -0.1715181 0.0015888 -0.000171 -0.000005 0.000089 0.000095 0.0000051 0.0000262 0.000040 0.000039 1998 10 10 51096 0.138882 0.430615 -0.1731375 0.0014571 -0.000221 -0.000007 0.000089 0.000096 0.0000078 0.0000261 0.000041 0.000040 1998 10 11 51097 0.140254 0.429716 -0.1745454 0.0013199 -0.000271 -0.000009 0.000090 0.000097 0.0000093 0.0000260 0.000041 0.000041 1998 10 12 51098 0.141420 0.428714 -0.1758428 0.0012682 -0.000320 -0.000011 0.000090 0.000098 0.0000128 0.0000258 0.000042 0.000042 1998 10 13 51099 0.142099 0.427858 -0.1770431 0.0012625 -0.000370 -0.000013 0.000090 0.000098 0.0000128 0.0000257 0.000043 0.000043 1998 10 14 51100 0.142785 0.426201 -0.1781505 0.0013089 0.000003 -0.000078 0.000090 0.000099 0.0000063 0.0000256 0.000043 0.000044 1998 10 15 51101 0.144035 0.424580 -0.1795572 0.0013697 0.000100 -0.000095 0.000090 0.000099 0.0000072 0.0000255 0.000043 0.000044 1998 10 16 51102 0.145226 0.423307 -0.1810356 0.0013981 0.000105 -0.000095 0.000090 0.000099 0.0000107 0.0000254 0.000044 0.000045 1998 10 17 51103 0.146686 0.422174 -0.1824354 0.0014367 0.000109 -0.000096 0.000090 0.000099 0.0000120 0.0000253 0.000044 0.000046 1998 10 18 51104 0.148048 0.421176 -0.1838819 0.0014594 0.000114 -0.000096 0.000090 0.000099 0.0000110 0.0000251 0.000044 0.000047 1998 10 19 51105 0.149194 0.419948 -0.1853682 0.0014699 0.000119 -0.000096 0.000090 0.000099 0.0000159 0.0000250 0.000045 0.000047 1998 10 20 51106 0.150180 0.418594 -0.1867939 0.0014553 0.000123 -0.000096 0.000090 0.000099 0.0000155 0.0000249 0.000045 0.000048 1998 10 21 51107 0.151146 0.417094 -0.1880938 0.0014289 0.000128 -0.000096 0.000089 0.000099 0.0000057 0.0000248 0.000046 0.000049 1998 10 22 51108 0.151801 0.415049 -0.1894644 0.0013705 0.000140 -0.000037 0.000089 0.000098 0.0000032 0.0000246 0.000046 0.000050 1998 10 23 51109 0.152187 0.413030 -0.1908981 0.0012908 0.000140 0.000009 0.000089 0.000098 0.0000072 0.0000245 0.000046 0.000050 1998 10 24 51110 0.152449 0.411124 -0.1922603 0.0012569 0.000133 0.000042 0.000088 0.000097 0.0000092 0.0000244 0.000047 0.000050 1998 10 25 51111 0.152837 0.409641 -0.1935062 0.0012403 0.000127 0.000075 0.000088 0.000097 0.0000069 0.0000243 0.000047 0.000051 1998 10 26 51112 0.153387 0.408129 -0.1947425 0.0012223 0.000121 0.000108 0.000087 0.000097 0.0000089 0.0000242 0.000047 0.000051 1998 10 27 51113 0.154050 0.406414 -0.1958863 0.0011883 0.000115 0.000141 0.000087 0.000097 0.0000089 0.0000241 0.000047 0.000051 1998 10 28 51114 0.154872 0.404685 -0.1969319 0.0012348 0.000108 0.000174 0.000087 0.000096 0.0000052 0.0000240 0.000047 0.000052 1998 10 29 51115 0.155986 0.402851 -0.1982336 0.0013605 0.000136 0.000162 0.000087 0.000096 0.0000159 0.0000238 0.000047 0.000052 1998 10 30 51116 0.157127 0.401317 -0.1997356 0.0015356 0.000138 0.000148 0.000087 0.000096 0.0000306 0.0000237 0.000048 0.000053 1998 10 31 51117 0.158122 0.399822 -0.2013996 0.0017654 0.000052 0.000167 0.000086 0.000096 0.0000331 0.0000235 0.000048 0.000053 1998 11 1 51118 0.159327 0.398436 -0.2032445 0.0019865 -0.000034 0.000185 0.000086 0.000096 0.0000199 0.0000234 0.000048 0.000053 1998 11 2 51119 0.160713 0.397021 -0.2052431 0.0021238 -0.000120 0.000204 0.000086 0.000096 0.0000143 0.0000232 0.000048 0.000053 1998 11 3 51120 0.161833 0.395504 -0.2073279 0.0021135 -0.000206 0.000223 0.000087 0.000096 0.0000088 0.0000231 0.000048 0.000053 1998 11 4 51121 0.162874 0.394154 -0.2094058 0.0020143 -0.000116 0.000085 0.000087 0.000096 0.0000039 0.0000229 0.000048 0.000053 1998 11 5 51122 0.163291 0.392514 -0.2113510 0.0018719 -0.000073 -0.000065 0.000087 0.000096 0.0000020 0.0000227 0.000048 0.000052 1998 11 6 51123 0.163103 0.390715 -0.2132318 0.0017131 -0.000117 -0.000013 0.000087 0.000096 0.0000053 0.0000225 0.000048 0.000052 1998 11 7 51124 0.163147 0.388401 -0.2149543 0.0015785 -0.000133 0.000031 0.000086 0.000096 0.0000081 0.0000222 0.000048 0.000052 1998 11 8 51125 0.163576 0.386057 -0.2164476 0.0014765 -0.000120 0.000031 0.000086 0.000096 0.0000055 0.0000220 0.000047 0.000051 1998 11 9 51126 0.164273 0.383552 -0.2178745 0.0014594 -0.000107 0.000030 0.000086 0.000096 0.0000075 0.0000217 0.000047 0.000051 1998 11 10 51127 0.164875 0.381349 -0.2192699 0.0014685 -0.000094 0.000029 0.000086 0.000096 0.0000088 0.0000214 0.000047 0.000051 1998 11 11 51128 0.165474 0.378896 -0.2206152 0.0014805 -0.000081 0.000028 0.000085 0.000095 0.0000080 0.0000212 0.000047 0.000051 1998 11 12 51129 0.166163 0.376971 -0.2221854 0.0015000 -0.000066 0.000039 0.000085 0.000095 0.0000074 0.0000208 0.000047 0.000050 1998 11 13 51130 0.166671 0.375042 -0.2238046 0.0015212 -0.000050 0.000053 0.000084 0.000095 0.0000074 0.0000205 0.000047 0.000050 1998 11 14 51131 0.166663 0.372768 -0.2253276 0.0015234 -0.000046 0.000060 0.000084 0.000094 0.0000086 0.0000202 0.000046 0.000049 1998 11 15 51132 0.166199 0.370952 -0.2268480 0.0015011 -0.000051 0.000059 0.000084 0.000094 0.0000095 0.0000199 0.000046 0.000049 1998 11 16 51133 0.165390 0.368765 -0.2283196 0.0014641 -0.000056 0.000059 0.000083 0.000093 0.0000098 0.0000196 0.000046 0.000049 1998 11 17 51134 0.164608 0.366738 -0.2297080 0.0014125 -0.000061 0.000059 0.000083 0.000093 0.0000092 0.0000193 0.000046 0.000050 1998 11 18 51135 0.164015 0.364786 -0.2309563 0.0013942 -0.000065 0.000058 0.000082 0.000092 0.0000062 0.0000190 0.000046 0.000050 1998 11 19 51136 0.163851 0.362831 -0.2323683 0.0013314 -0.000056 0.000076 0.000082 0.000092 0.0000078 0.0000187 0.000045 0.000049 1998 11 20 51137 0.163312 0.361024 -0.2337740 0.0012586 -0.000042 0.000101 0.000081 0.000091 0.0000090 0.0000185 0.000045 0.000049 1998 11 21 51138 0.162150 0.359208 -0.2350446 0.0012277 -0.000028 0.000125 0.000081 0.000091 0.0000063 0.0000183 0.000044 0.000048 1998 11 22 51139 0.160074 0.357416 -0.2362740 0.0012276 -0.000014 0.000149 0.000081 0.000090 0.0000073 0.0000181 0.000044 0.000048 1998 11 23 51140 0.158069 0.355086 -0.2374976 0.0012467 -0.000001 0.000173 0.000081 0.000090 0.0000095 0.0000180 0.000043 0.000047 1998 11 24 51141 0.156414 0.353230 -0.2386920 0.0012736 0.000013 0.000197 0.000081 0.000090 0.0000098 0.0000179 0.000043 0.000047 1998 11 25 51142 0.154784 0.351256 -0.2398414 0.0013221 0.000027 0.000222 0.000081 0.000090 0.0000053 0.0000178 0.000042 0.000046 1998 11 26 51143 0.153772 0.349338 -0.2412491 0.0014516 0.000019 0.000204 0.000081 0.000090 0.0000060 0.0000177 0.000042 0.000046 1998 11 27 51144 0.152900 0.347414 -0.2428611 0.0016244 0.000003 0.000172 0.000081 0.000090 0.0000084 0.0000176 0.000042 0.000045 1998 11 28 51145 0.151934 0.345097 -0.2446230 0.0017699 -0.000014 0.000140 0.000081 0.000090 0.0000089 0.0000176 0.000041 0.000045 1998 11 29 51146 0.150899 0.342942 -0.2464717 0.0018580 -0.000030 0.000109 0.000081 0.000090 0.0000058 0.0000175 0.000041 0.000044 1998 11 30 51147 0.150239 0.340922 -0.2483468 0.0018503 -0.000046 0.000077 0.000082 0.000090 0.0000066 0.0000175 0.000040 0.000044 1998 12 1 51148 0.149349 0.339614 -0.2501092 0.0017602 -0.000062 0.000045 0.000082 0.000090 0.0000061 0.0000174 0.000040 0.000043 1998 12 2 51149 0.147992 0.337887 -0.2516270 0.0016120 -0.000078 0.000013 0.000082 0.000090 0.0000028 0.0000174 0.000040 0.000043 1998 12 3 51150 0.146994 0.336244 -0.2532192 0.0014418 -0.000089 0.000030 0.000082 0.000090 0.0000051 0.0000173 0.000040 0.000043 1998 12 4 51151 0.146644 0.335239 -0.2546807 0.0012846 -0.000098 0.000063 0.000082 0.000089 0.0000085 0.0000173 0.000040 0.000043 1998 12 5 51152 0.146101 0.334604 -0.2559054 0.0011757 -0.000106 0.000096 0.000082 0.000089 0.0000090 0.0000173 0.000040 0.000043 1998 12 6 51153 0.145015 0.333679 -0.2570260 0.0011294 -0.000115 0.000128 0.000081 0.000089 0.0000067 0.0000173 0.000040 0.000043 1998 12 7 51154 0.143750 0.332605 -0.2580341 0.0010994 -0.000124 0.000161 0.000081 0.000088 0.0000048 0.0000173 0.000040 0.000043 1998 12 8 51155 0.142332 0.331566 -0.2590273 0.0010701 -0.000133 0.000194 0.000081 0.000088 0.0000029 0.0000173 0.000040 0.000043 1998 12 9 51156 0.140956 0.330091 -0.2600971 0.0010794 -0.000055 0.000158 0.000081 0.000087 0.0000041 0.0000173 0.000040 0.000043 1998 12 10 51157 0.139645 0.328129 -0.2613007 0.0011391 -0.000101 0.000024 0.000080 0.000087 0.0000070 0.0000173 0.000040 0.000043 1998 12 11 51158 0.138658 0.326042 -0.2625582 0.0011799 -0.000164 -0.000052 0.000080 0.000086 0.0000087 0.0000173 0.000040 0.000042 1998 12 12 51159 0.137903 0.324010 -0.2637767 0.0011761 -0.000166 0.000093 0.000080 0.000085 0.0000079 0.0000173 0.000039 0.000041 1998 12 13 51160 0.137353 0.322196 -0.2649374 0.0011231 -0.000168 0.000238 0.000079 0.000085 0.0000091 0.0000173 0.000039 0.000041 1998 12 14 51161 0.137120 0.320374 -0.2660354 0.0010376 -0.000171 0.000383 0.000078 0.000084 0.0000103 0.0000173 0.000039 0.000040 1998 12 15 51162 0.137242 0.318611 -0.2670051 0.0009575 -0.000173 0.000528 0.000078 0.000083 0.0000093 0.0000173 0.000038 0.000039 1998 12 16 51163 0.137473 0.317123 -0.2678034 0.0008526 -0.000067 0.000212 0.000077 0.000082 0.0000044 0.0000174 0.000038 0.000038 1998 12 17 51164 0.137883 0.316013 -0.2686027 0.0007656 -0.000037 0.000119 0.000076 0.000081 0.0000024 0.0000174 0.000037 0.000037 1998 12 18 51165 0.138723 0.314720 -0.2694699 0.0006976 -0.000023 0.000087 0.000076 0.000080 0.0000050 0.0000175 0.000037 0.000036 1998 12 19 51166 0.139971 0.313497 -0.2702545 0.0006516 -0.000006 0.000048 0.000075 0.000079 0.0000076 0.0000175 0.000036 0.000034 1998 12 20 51167 0.141407 0.312741 -0.2708675 0.0006221 0.000012 0.000009 0.000074 0.000078 0.0000069 0.0000176 0.000035 0.000033 1998 12 21 51168 0.142554 0.311970 -0.2714183 0.0006227 0.000029 -0.000031 0.000073 0.000077 0.0000042 0.0000176 0.000035 0.000032 1998 12 22 51169 0.142889 0.310463 -0.2720079 0.0006747 0.000047 -0.000070 0.000072 0.000076 0.0000015 0.0000177 0.000034 0.000031 1998 12 23 51170 0.143113 0.308423 -0.2727388 0.0008061 0.000001 0.000067 0.000073 0.000076 0.0000026 0.0000178 0.000034 0.000032 1998 12 24 51171 0.143113 0.306891 -0.2736948 0.0009819 -0.000026 0.000101 0.000074 0.000077 0.0000037 0.0000179 0.000035 0.000032 1998 12 25 51172 0.143211 0.305548 -0.2748450 0.0011882 -0.000043 0.000089 0.000074 0.000078 0.0000046 0.0000181 0.000036 0.000033 1998 12 26 51173 0.142946 0.304078 -0.2761441 0.0013055 -0.000060 0.000077 0.000075 0.000079 0.0000054 0.0000182 0.000036 0.000034 1998 12 27 51174 0.142337 0.302629 -0.2774891 0.0013475 -0.000076 0.000065 0.000075 0.000080 0.0000058 0.0000183 0.000037 0.000035 1998 12 28 51175 0.141746 0.301445 -0.2787497 0.0013419 -0.000093 0.000053 0.000076 0.000081 0.0000052 0.0000184 0.000037 0.000036 1998 12 29 51176 0.141352 0.300272 -0.2799754 0.0013049 -0.000109 0.000041 0.000077 0.000082 0.0000046 0.0000185 0.000038 0.000037 1998 12 30 51177 0.140745 0.298956 -0.2811979 0.0012100 0.000025 -0.000096 0.000077 0.000083 0.0000043 0.0000186 0.000039 0.000038 1998 12 31 51178 0.139848 0.297724 -0.2824458 0.0010954 0.000064 -0.000125 0.000078 0.000083 0.0000064 0.0000186 0.000039 0.000039 1999 1 1 51179 0.138633 0.295943 0.7164761 0.0009738 0.000061 -0.000110 0.000096 0.000075 0.0000097 0.0000234 0.000034 0.000026 1999 1 2 51180 0.137799 0.293751 0.7156376 0.0008880 0.000059 -0.000096 0.000097 0.000076 0.0000074 0.0000234 0.000035 0.000026 1999 1 3 51181 0.137628 0.291851 0.7148191 0.0008605 0.000056 -0.000081 0.000097 0.000076 0.0000065 0.0000234 0.000035 0.000026 1999 1 4 51182 0.137342 0.290390 0.7139496 0.0008798 0.000053 -0.000067 0.000098 0.000077 0.0000082 0.0000234 0.000035 0.000027 1999 1 5 51183 0.136803 0.289155 0.7130914 0.0008935 0.000051 -0.000052 0.000099 0.000077 0.0000085 0.0000233 0.000036 0.000027 1999 1 6 51184 0.136361 0.287933 0.7122704 0.0009693 0.000048 -0.000038 0.000099 0.000077 0.0000042 0.0000232 0.000036 0.000027 1999 1 7 51185 0.136269 0.287249 0.7112291 0.0010658 0.000041 -0.000025 0.000100 0.000078 0.0000060 0.0000231 0.000036 0.000028 1999 1 8 51186 0.136170 0.286830 0.7101021 0.0010857 0.000033 -0.000013 0.000101 0.000078 0.0000083 0.0000230 0.000037 0.000028 1999 1 9 51187 0.135867 0.286432 0.7090333 0.0010715 0.000025 -0.000001 0.000101 0.000079 0.0000065 0.0000229 0.000037 0.000029 1999 1 10 51188 0.135018 0.286035 0.7079651 0.0010519 0.000017 0.000012 0.000101 0.000079 0.0000063 0.0000228 0.000038 0.000029 1999 1 11 51189 0.133656 0.285211 0.7069068 0.0010021 0.000008 0.000024 0.000102 0.000079 0.0000077 0.0000227 0.000038 0.000030 1999 1 12 51190 0.131527 0.283861 0.7059714 0.0008986 0.000000 0.000036 0.000102 0.000080 0.0000077 0.0000227 0.000039 0.000030 1999 1 13 51191 0.129164 0.282055 0.7052250 0.0007891 -0.000008 0.000048 0.000103 0.000080 0.0000032 0.0000226 0.000039 0.000031 1999 1 14 51192 0.126997 0.280203 0.7045053 0.0007236 0.000023 0.000112 0.000104 0.000081 0.0000023 0.0000226 0.000040 0.000031 1999 1 15 51193 0.124965 0.278183 0.7037846 0.0006842 0.000016 0.000140 0.000104 0.000081 0.0000065 0.0000226 0.000040 0.000032 1999 1 16 51194 0.122899 0.276237 0.7031213 0.0006091 -0.000011 0.000150 0.000105 0.000081 0.0000096 0.0000227 0.000041 0.000032 1999 1 17 51195 0.120655 0.274560 0.7025517 0.0005459 -0.000037 0.000159 0.000105 0.000082 0.0000067 0.0000227 0.000041 0.000033 1999 1 18 51196 0.118959 0.273025 0.7020073 0.0005740 -0.000063 0.000168 0.000106 0.000082 0.0000087 0.0000228 0.000042 0.000033 1999 1 19 51197 0.117665 0.271693 0.7014180 0.0006929 -0.000090 0.000178 0.000106 0.000083 0.0000090 0.0000228 0.000043 0.000034 1999 1 20 51198 0.116529 0.270147 0.7007303 0.0008527 -0.000116 0.000187 0.000107 0.000083 0.0000048 0.0000228 0.000043 0.000035 1999 1 21 51199 0.116104 0.268840 0.6997762 0.0010358 -0.000112 0.000178 0.000107 0.000084 0.0000080 0.0000229 0.000044 0.000036 1999 1 22 51200 0.116227 0.267699 0.6986102 0.0012209 -0.000099 0.000162 0.000108 0.000084 0.0000110 0.0000230 0.000045 0.000037 1999 1 23 51201 0.116465 0.266637 0.6973300 0.0013473 -0.000085 0.000147 0.000109 0.000085 0.0000087 0.0000230 0.000046 0.000038 1999 1 24 51202 0.116119 0.265662 0.6959778 0.0013865 -0.000071 0.000131 0.000109 0.000085 0.0000107 0.0000231 0.000047 0.000039 1999 1 25 51203 0.115236 0.264575 0.6945195 0.0013692 -0.000057 0.000116 0.000109 0.000085 0.0000124 0.0000232 0.000047 0.000040 1999 1 26 51204 0.114026 0.263342 0.6931586 0.0013004 -0.000043 0.000100 0.000110 0.000086 0.0000123 0.0000233 0.000048 0.000041 1999 1 27 51205 0.112874 0.262463 0.6919986 0.0012207 -0.000029 0.000084 0.000110 0.000086 0.0000079 0.0000234 0.000049 0.000042 1999 1 28 51206 0.111635 0.261648 0.6908515 0.0011562 0.000029 0.000062 0.000110 0.000086 0.0000086 0.0000235 0.000050 0.000043 1999 1 29 51207 0.110587 0.260860 0.6897082 0.0011509 0.000101 0.000038 0.000111 0.000086 0.0000037 0.0000236 0.000051 0.000044 1999 1 30 51208 0.109475 0.259865 0.6884974 0.0011811 0.000045 0.000018 0.000111 0.000086 0.0000085 0.0000237 0.000052 0.000045 1999 1 31 51209 0.108190 0.258827 0.6872704 0.0012163 -0.000011 -0.000002 0.000111 0.000086 0.0000156 0.0000239 0.000053 0.000047 1999 2 1 51210 0.106680 0.257619 0.6860585 0.0012582 -0.000068 -0.000022 0.000111 0.000086 0.0000284 0.0000240 0.000054 0.000048 1999 2 2 51211 0.105101 0.256229 0.6848061 0.0013085 -0.000124 -0.000043 0.000111 0.000086 0.0000327 0.0000242 0.000055 0.000050 1999 2 3 51212 0.103492 0.254846 0.6835348 0.0013201 -0.000114 0.000049 0.000111 0.000087 0.0000179 0.0000245 0.000056 0.000051 1999 2 4 51213 0.101828 0.253594 0.6821689 0.0013209 0.000018 0.000187 0.000112 0.000087 0.0000135 0.0000247 0.000056 0.000051 1999 2 5 51214 0.100808 0.252562 0.6807982 0.0013294 0.000191 0.000340 0.000112 0.000087 0.0000121 0.0000249 0.000056 0.000051 1999 2 6 51215 0.100481 0.252397 0.6794864 0.0013167 0.000185 0.000266 0.000112 0.000087 0.0000095 0.0000252 0.000055 0.000051 1999 2 7 51216 0.099863 0.252521 0.6782128 0.0012566 0.000178 0.000192 0.000112 0.000087 0.0000079 0.0000255 0.000055 0.000051 1999 2 8 51217 0.098589 0.252462 0.6770014 0.0011886 0.000172 0.000118 0.000112 0.000087 0.0000087 0.0000258 0.000055 0.000050 1999 2 9 51218 0.096690 0.252285 0.6758907 0.0010990 0.000165 0.000044 0.000112 0.000087 0.0000078 0.0000261 0.000055 0.000050 1999 2 10 51219 0.094735 0.252141 0.6748985 0.0010060 0.000039 -0.000032 0.000112 0.000087 0.0000036 0.0000265 0.000055 0.000049 1999 2 11 51220 0.092573 0.251399 0.6739661 0.0009122 -0.000007 -0.000193 0.000113 0.000087 0.0000140 0.0000268 0.000054 0.000050 1999 2 12 51221 0.090701 0.250323 0.6730667 0.0009005 -0.000023 -0.000384 0.000113 0.000087 0.0000291 0.0000272 0.000054 0.000049 1999 2 13 51222 0.089281 0.249518 0.6720984 0.0009361 -0.000035 -0.000336 0.000113 0.000087 0.0000165 0.0000276 0.000053 0.000049 1999 2 14 51223 0.087918 0.248512 0.6710798 0.0010122 -0.000046 -0.000289 0.000113 0.000087 0.0000077 0.0000281 0.000052 0.000048 1999 2 15 51224 0.086907 0.247560 0.6699746 0.0011501 -0.000058 -0.000241 0.000113 0.000087 0.0000089 0.0000285 0.000052 0.000047 1999 2 16 51225 0.085767 0.247027 0.6687920 0.0012834 -0.000070 -0.000180 0.000112 0.000087 0.0000084 0.0000289 0.000051 0.000046 1999 2 17 51226 0.084562 0.246881 0.6675483 0.0014464 -0.000077 0.000038 0.000112 0.000087 0.0000046 0.0000293 0.000050 0.000045 1999 2 18 51227 0.082839 0.246964 0.6660620 0.0015980 -0.000065 0.000014 0.000112 0.000086 0.0000107 0.0000297 0.000049 0.000045 1999 2 19 51228 0.080775 0.246780 0.6644192 0.0016830 -0.000047 -0.000089 0.000111 0.000086 0.0000200 0.0000301 0.000049 0.000044 1999 2 20 51229 0.079349 0.246160 0.6626780 0.0016964 -0.000034 -0.000079 0.000110 0.000085 0.0000130 0.0000304 0.000048 0.000043 1999 2 21 51230 0.078505 0.245651 0.6609698 0.0016194 -0.000020 -0.000068 0.000110 0.000085 0.0000095 0.0000308 0.000047 0.000042 1999 2 22 51231 0.078291 0.245333 0.6593864 0.0015088 -0.000006 -0.000057 0.000109 0.000084 0.0000141 0.0000311 0.000046 0.000041 1999 2 23 51232 0.078254 0.245123 0.6579850 0.0013562 0.000007 -0.000046 0.000108 0.000084 0.0000138 0.0000314 0.000045 0.000040 1999 2 24 51233 0.077797 0.244888 0.6568011 0.0011691 0.000021 -0.000035 0.000107 0.000083 0.0000054 0.0000317 0.000044 0.000039 1999 2 25 51234 0.076635 0.244605 0.6556678 0.0010368 -0.000006 -0.000013 0.000107 0.000083 0.0000074 0.0000320 0.000043 0.000038 1999 2 26 51235 0.074935 0.244065 0.6546574 0.0009558 -0.000046 0.000013 0.000105 0.000082 0.0000119 0.0000323 0.000042 0.000036 1999 2 27 51236 0.073139 0.243429 0.6537798 0.0009261 -0.000085 0.000039 0.000104 0.000081 0.0000114 0.0000325 0.000041 0.000035 1999 2 28 51237 0.071425 0.242558 0.6528954 0.0009347 -0.000125 0.000065 0.000104 0.000081 0.0000086 0.0000327 0.000040 0.000034 1999 3 1 51238 0.070047 0.242035 0.6519390 0.0009550 -0.000165 0.000091 0.000103 0.000080 0.0000124 0.0000329 0.000039 0.000033 1999 3 2 51239 0.068952 0.241610 0.6510006 0.0009800 -0.000205 0.000117 0.000102 0.000080 0.0000138 0.0000331 0.000039 0.000032 1999 3 3 51240 0.068174 0.241636 0.6501597 0.0009925 -0.000245 0.000143 0.000101 0.000079 0.0000067 0.0000332 0.000038 0.000032 1999 3 4 51241 0.067500 0.241843 0.6491554 0.0010438 -0.000218 0.000136 0.000100 0.000079 0.0000070 0.0000334 0.000037 0.000031 1999 3 5 51242 0.066650 0.242182 0.6480724 0.0010477 -0.000169 0.000119 0.000099 0.000078 0.0000085 0.0000334 0.000036 0.000030 1999 3 6 51243 0.065481 0.242605 0.6470232 0.0009507 -0.000120 0.000102 0.000098 0.000077 0.0000066 0.0000335 0.000035 0.000029 1999 3 7 51244 0.064430 0.242801 0.6461682 0.0008730 -0.000071 0.000085 0.000096 0.000076 0.0000071 0.0000335 0.000035 0.000029 1999 3 8 51245 0.063309 0.242722 0.6453765 0.0008184 -0.000022 0.000068 0.000095 0.000076 0.0000042 0.0000335 0.000034 0.000028 1999 3 9 51246 0.062404 0.242632 0.6446655 0.0007442 0.000026 0.000051 0.000094 0.000075 0.0000013 0.0000334 0.000033 0.000028 1999 3 10 51247 0.061137 0.242116 0.6439666 0.0006893 -0.000045 0.000003 0.000094 0.000075 0.0000022 0.0000334 0.000034 0.000028 1999 3 11 51248 0.060031 0.241762 0.6432793 0.0006931 -0.000066 0.000013 0.000095 0.000076 0.0000022 0.0000333 0.000034 0.000028 1999 3 12 51249 0.058988 0.241455 0.6425179 0.0007564 -0.000032 0.000046 0.000096 0.000076 0.0000054 0.0000332 0.000034 0.000028 1999 3 13 51250 0.057621 0.240995 0.6416841 0.0008389 0.000015 0.000082 0.000097 0.000077 0.0000081 0.0000331 0.000034 0.000028 1999 3 14 51251 0.056205 0.240515 0.6407893 0.0009673 0.000062 0.000117 0.000097 0.000077 0.0000056 0.0000331 0.000034 0.000029 1999 3 15 51252 0.054527 0.240000 0.6397578 0.0011346 0.000109 0.000152 0.000098 0.000077 0.0000044 0.0000330 0.000034 0.000029 1999 3 16 51253 0.052974 0.239725 0.6385561 0.0013128 0.000155 0.000187 0.000098 0.000077 0.0000032 0.0000329 0.000034 0.000029 1999 3 17 51254 0.051124 0.239181 0.6371616 0.0014408 -0.000069 0.000157 0.000099 0.000078 0.0000036 0.0000327 0.000034 0.000029 1999 3 18 51255 0.049790 0.238838 0.6355855 0.0015682 -0.000105 0.000139 0.000099 0.000078 0.0000070 0.0000326 0.000034 0.000029 1999 3 19 51256 0.048958 0.239041 0.6339225 0.0016514 -0.000069 0.000127 0.000099 0.000078 0.0000108 0.0000325 0.000034 0.000029 1999 3 20 51257 0.048221 0.239546 0.6322685 0.0016386 -0.000034 0.000114 0.000099 0.000078 0.0000106 0.0000323 0.000034 0.000029 1999 3 21 51258 0.047329 0.240145 0.6306030 0.0016014 0.000001 0.000102 0.000098 0.000077 0.0000067 0.0000321 0.000034 0.000029 1999 3 22 51259 0.046573 0.240625 0.6289922 0.0014887 0.000037 0.000090 0.000098 0.000077 0.0000084 0.0000319 0.000034 0.000030 1999 3 23 51260 0.045733 0.241161 0.6275441 0.0013508 0.000072 0.000078 0.000097 0.000076 0.0000083 0.0000317 0.000033 0.000029 1999 3 24 51261 0.044234 0.241522 0.6263099 0.0012127 0.000107 0.000065 0.000096 0.000076 0.0000039 0.0000316 0.000033 0.000029 1999 3 25 51262 0.042085 0.241516 0.6251253 0.0011454 0.000196 0.000143 0.000095 0.000075 0.0000037 0.0000314 0.000033 0.000029 1999 3 26 51263 0.039306 0.241514 0.6239134 0.0011435 0.000202 0.000138 0.000095 0.000075 0.0000060 0.0000313 0.000033 0.000029 1999 3 27 51264 0.036314 0.241570 0.6226917 0.0012180 0.000170 0.000093 0.000094 0.000074 0.0000074 0.0000312 0.000032 0.000028 1999 3 28 51265 0.033686 0.241375 0.6214664 0.0012713 0.000139 0.000047 0.000093 0.000074 0.0000066 0.0000310 0.000032 0.000028 1999 3 29 51266 0.031774 0.240955 0.6201250 0.0013388 0.000107 0.000002 0.000091 0.000073 0.0000093 0.0000309 0.000031 0.000027 1999 3 30 51267 0.030034 0.240970 0.6187670 0.0014041 0.000076 -0.000043 0.000090 0.000072 0.0000100 0.0000308 0.000031 0.000027 1999 3 31 51268 0.028081 0.241222 0.6174563 0.0014269 0.000044 -0.000089 0.000089 0.000071 0.0000059 0.0000307 0.000030 0.000027 1999 4 1 51269 0.026106 0.241144 0.6160276 0.0014210 0.000049 -0.000091 0.000088 0.000070 0.0000084 0.0000306 0.000030 0.000026 1999 4 2 51270 0.023973 0.240879 0.6145621 0.0014162 0.000066 -0.000080 0.000086 0.000070 0.0000105 0.0000305 0.000029 0.000025 1999 4 3 51271 0.021881 0.240332 0.6131517 0.0013796 0.000083 -0.000068 0.000085 0.000069 0.0000075 0.0000305 0.000029 0.000025 1999 4 4 51272 0.020090 0.239865 0.6118609 0.0012973 0.000101 -0.000056 0.000084 0.000068 0.0000071 0.0000304 0.000028 0.000024 1999 4 5 51273 0.018786 0.239739 0.6106434 0.0012113 0.000118 -0.000045 0.000082 0.000067 0.0000101 0.0000304 0.000028 0.000024 1999 4 6 51274 0.017513 0.239594 0.6094936 0.0011631 0.000135 -0.000033 0.000080 0.000065 0.0000103 0.0000303 0.000027 0.000023 1999 4 7 51275 0.015994 0.240001 0.6083997 0.0011391 0.000152 -0.000021 0.000079 0.000064 0.0000045 0.0000303 0.000027 0.000023 1999 4 8 51276 0.013874 0.240383 0.6073088 0.0011059 0.000095 0.000022 0.000077 0.000063 0.0000046 0.0000303 0.000026 0.000022 1999 4 9 51277 0.012074 0.240583 0.6061883 0.0011179 0.000053 0.000033 0.000075 0.000062 0.0000094 0.0000302 0.000026 0.000021 1999 4 10 51278 0.011061 0.240787 0.6050140 0.0011863 0.000027 0.000029 0.000073 0.000060 0.0000110 0.0000302 0.000025 0.000021 1999 4 11 51279 0.010584 0.241225 0.6037489 0.0013129 0.000001 0.000025 0.000071 0.000059 0.0000068 0.0000302 0.000025 0.000020 1999 4 12 51280 0.010316 0.242219 0.6023648 0.0015013 -0.000025 0.000021 0.000069 0.000057 0.0000107 0.0000302 0.000024 0.000019 1999 4 13 51281 0.009774 0.243212 0.6007888 0.0017218 -0.000051 0.000017 0.000067 0.000056 0.0000117 0.0000302 0.000024 0.000019 1999 4 14 51282 0.008945 0.244024 0.5990316 0.0018721 -0.000077 0.000012 0.000065 0.000055 0.0000069 0.0000302 0.000023 0.000018 1999 4 15 51283 0.008162 0.245110 0.5971342 0.0019312 -0.000042 0.000029 0.000063 0.000053 0.0000116 0.0000302 0.000023 0.000018 1999 4 16 51284 0.007460 0.246413 0.5951945 0.0019018 0.000013 0.000053 0.000061 0.000052 0.0000193 0.0000302 0.000022 0.000017 1999 4 17 51285 0.006414 0.247699 0.5932644 0.0018083 0.000060 0.000045 0.000063 0.000052 0.0000133 0.0000302 0.000023 0.000018 1999 4 18 51286 0.004944 0.248646 0.5914760 0.0016784 0.000106 0.000034 0.000064 0.000053 0.0000074 0.0000302 0.000023 0.000018 1999 4 19 51287 0.003180 0.249064 0.5899030 0.0015318 0.000153 0.000022 0.000065 0.000054 0.0000057 0.0000301 0.000024 0.000019 1999 4 20 51288 0.001535 0.249094 0.5884825 0.0013968 0.000199 0.000011 0.000067 0.000055 0.0000039 0.0000300 0.000024 0.000020 1999 4 21 51289 0.000268 0.248966 0.5871365 0.0012739 0.000258 0.000063 0.000068 0.000056 0.0000033 0.0000300 0.000025 0.000021 1999 4 22 51290 -0.000994 0.249026 0.5858741 0.0012298 0.000156 0.000046 0.000068 0.000056 0.0000035 0.0000299 0.000025 0.000021 1999 4 23 51291 -0.002152 0.249381 0.5846003 0.0012407 0.000099 0.000068 0.000069 0.000057 0.0000092 0.0000298 0.000025 0.000021 1999 4 24 51292 -0.003480 0.250181 0.5833163 0.0012999 0.000080 0.000114 0.000070 0.000057 0.0000115 0.0000296 0.000026 0.000022 1999 4 25 51293 -0.005214 0.251122 0.5820182 0.0013617 0.000061 0.000160 0.000070 0.000057 0.0000073 0.0000295 0.000026 0.000022 1999 4 26 51294 -0.006836 0.252067 0.5806447 0.0014103 0.000042 0.000205 0.000070 0.000057 0.0000082 0.0000293 0.000026 0.000022 1999 4 27 51295 -0.008025 0.252835 0.5792294 0.0014614 0.000022 0.000251 0.000070 0.000057 0.0000080 0.0000291 0.000027 0.000023 1999 4 28 51296 -0.008266 0.253930 0.5778069 0.0015067 -0.000032 0.000023 0.000070 0.000057 0.0000061 0.0000289 0.000027 0.000023 1999 4 29 51297 -0.008319 0.255218 0.5763309 0.0014774 0.000073 -0.000009 0.000070 0.000057 0.0000095 0.0000286 0.000027 0.000023 1999 4 30 51298 -0.008551 0.256653 0.5748546 0.0014077 0.000135 -0.000011 0.000069 0.000056 0.0000122 0.0000284 0.000027 0.000022 1999 5 1 51299 -0.009114 0.257986 0.5734738 0.0013125 0.000160 -0.000026 0.000069 0.000056 0.0000119 0.0000281 0.000026 0.000022 1999 5 2 51300 -0.010337 0.258977 0.5722399 0.0011978 0.000186 -0.000041 0.000068 0.000055 0.0000088 0.0000277 0.000026 0.000021 1999 5 3 51301 -0.011892 0.259612 0.5711284 0.0010878 0.000211 -0.000055 0.000067 0.000054 0.0000067 0.0000274 0.000026 0.000021 1999 5 4 51302 -0.013495 0.260003 0.5701525 0.0009512 0.000237 -0.000070 0.000066 0.000053 0.0000045 0.0000271 0.000026 0.000021 1999 5 5 51303 -0.014890 0.260032 0.5692800 0.0008061 0.000172 0.000002 0.000065 0.000052 0.0000039 0.0000267 0.000025 0.000020 1999 5 6 51304 -0.015769 0.260371 0.5685282 0.0007390 0.000044 -0.000010 0.000063 0.000051 0.0000055 0.0000264 0.000025 0.000019 1999 5 7 51305 -0.016358 0.261090 0.5677666 0.0007453 0.000000 -0.000036 0.000062 0.000050 0.0000074 0.0000260 0.000024 0.000019 1999 5 8 51306 -0.017021 0.261980 0.5669556 0.0008315 -0.000007 -0.000056 0.000060 0.000049 0.0000081 0.0000256 0.000024 0.000018 1999 5 9 51307 -0.017834 0.262847 0.5660763 0.0009589 -0.000013 -0.000076 0.000059 0.000048 0.0000076 0.0000253 0.000023 0.000017 1999 5 10 51308 -0.018437 0.263483 0.5650529 0.0011290 -0.000019 -0.000096 0.000057 0.000046 0.0000135 0.0000249 0.000023 0.000016 1999 5 11 51309 -0.018745 0.264511 0.5638436 0.0013115 -0.000025 -0.000116 0.000055 0.000045 0.0000195 0.0000246 0.000022 0.000016 1999 5 12 51310 -0.019042 0.265788 0.5624451 0.0014939 -0.000069 -0.000161 0.000057 0.000046 0.0000084 0.0000243 0.000023 0.000016 1999 5 13 51311 -0.019172 0.267209 0.5608599 0.0015898 -0.000066 -0.000154 0.000059 0.000048 0.0000062 0.0000240 0.000023 0.000016 1999 5 14 51312 -0.019128 0.268741 0.5592230 0.0015815 -0.000046 -0.000129 0.000060 0.000049 0.0000085 0.0000238 0.000023 0.000017 1999 5 15 51313 -0.018935 0.270177 0.5576882 0.0014858 -0.000026 -0.000103 0.000062 0.000050 0.0000113 0.0000235 0.000024 0.000017 1999 5 16 51314 -0.018876 0.271756 0.5563277 0.0013121 -0.000006 -0.000078 0.000064 0.000052 0.0000074 0.0000234 0.000024 0.000018 1999 5 17 51315 -0.019321 0.273435 0.5551204 0.0011272 0.000013 -0.000053 0.000066 0.000053 0.0000091 0.0000232 0.000025 0.000019 1999 5 18 51316 -0.019880 0.275076 0.5540537 0.0010223 0.000033 -0.000027 0.000067 0.000054 0.0000091 0.0000231 0.000026 0.000019 1999 5 19 51317 -0.020139 0.276229 0.5530742 0.0010266 0.000053 -0.000002 0.000069 0.000055 0.0000045 0.0000229 0.000026 0.000020 1999 5 20 51318 -0.020350 0.276980 0.5520336 0.0010702 0.000137 0.000036 0.000071 0.000057 0.0000088 0.0000228 0.000027 0.000021 1999 5 21 51319 -0.020436 0.277625 0.5508974 0.0011474 0.000155 0.000048 0.000072 0.000058 0.0000094 0.0000227 0.000027 0.000021 1999 5 22 51320 -0.020392 0.278399 0.5496759 0.0012430 0.000139 0.000048 0.000074 0.000059 0.0000073 0.0000226 0.000027 0.000022 1999 5 23 51321 -0.020369 0.279121 0.5483986 0.0012901 0.000124 0.000048 0.000075 0.000060 0.0000050 0.0000225 0.000028 0.000022 1999 5 24 51322 -0.020650 0.279902 0.5470936 0.0012979 0.000108 0.000048 0.000077 0.000060 0.0000047 0.0000225 0.000028 0.000023 1999 5 25 51323 -0.021201 0.280542 0.5458051 0.0012980 0.000093 0.000048 0.000078 0.000061 0.0000046 0.0000224 0.000029 0.000023 1999 5 26 51324 -0.022087 0.281195 0.5445988 0.0012194 0.000078 0.000048 0.000079 0.000062 0.0000051 0.0000224 0.000029 0.000024 1999 5 27 51325 -0.023052 0.281575 0.5434441 0.0010759 0.000062 0.000056 0.000080 0.000063 0.0000066 0.0000223 0.000029 0.000024 1999 5 28 51326 -0.023664 0.282185 0.5423948 0.0009403 0.000045 0.000067 0.000081 0.000063 0.0000083 0.0000223 0.000030 0.000025 1999 5 29 51327 -0.024054 0.282965 0.5415159 0.0008263 0.000029 0.000078 0.000082 0.000064 0.0000077 0.0000223 0.000030 0.000025 1999 5 30 51328 -0.024282 0.283511 0.5407671 0.0007286 0.000012 0.000088 0.000083 0.000065 0.0000063 0.0000223 0.000030 0.000025 1999 5 31 51329 -0.024602 0.283997 0.5400849 0.0006538 -0.000004 0.000099 0.000084 0.000065 0.0000061 0.0000223 0.000031 0.000026 1999 6 1 51330 -0.024996 0.284592 0.5395027 0.0005934 -0.000021 0.000110 0.000085 0.000066 0.0000056 0.0000223 0.000031 0.000026 1999 6 2 51331 -0.025655 0.285375 0.5389834 0.0005620 -0.000037 0.000120 0.000085 0.000066 0.0000047 0.0000224 0.000032 0.000027 1999 6 3 51332 -0.026588 0.286281 0.5383607 0.0005867 -0.000015 0.000088 0.000086 0.000066 0.0000098 0.0000224 0.000032 0.000027 1999 6 4 51333 -0.027275 0.287276 0.5376908 0.0006750 0.000020 0.000041 0.000086 0.000067 0.0000106 0.0000225 0.000032 0.000027 1999 6 5 51334 -0.027772 0.288504 0.5369809 0.0007827 0.000055 -0.000006 0.000086 0.000067 0.0000061 0.0000225 0.000032 0.000027 1999 6 6 51335 -0.028482 0.290192 0.5361329 0.0009116 0.000090 -0.000052 0.000087 0.000067 0.0000070 0.0000226 0.000032 0.000027 1999 6 7 51336 -0.029217 0.291726 0.5351359 0.0010635 0.000125 -0.000099 0.000087 0.000067 0.0000072 0.0000227 0.000032 0.000027 1999 6 8 51337 -0.029723 0.292896 0.5340185 0.0012148 0.000160 -0.000146 0.000087 0.000067 0.0000064 0.0000228 0.000032 0.000027 1999 6 9 51338 -0.030234 0.293798 0.5327849 0.0013387 0.000195 -0.000193 0.000087 0.000067 0.0000049 0.0000229 0.000033 0.000027 1999 6 10 51339 -0.030784 0.294168 0.5313554 0.0013913 0.000171 -0.000162 0.000086 0.000067 0.0000049 0.0000230 0.000033 0.000026 1999 6 11 51340 -0.030924 0.294538 0.5299284 0.0013191 0.000127 -0.000105 0.000086 0.000066 0.0000062 0.0000231 0.000032 0.000026 1999 6 12 51341 -0.031308 0.295109 0.5286904 0.0011530 0.000083 -0.000048 0.000085 0.000066 0.0000070 0.0000233 0.000032 0.000025 1999 6 13 51342 -0.031541 0.295786 0.5276781 0.0009323 0.000039 0.000009 0.000085 0.000065 0.0000067 0.0000234 0.000032 0.000025 1999 6 14 51343 -0.031614 0.296841 0.5268486 0.0007423 -0.000005 0.000066 0.000084 0.000065 0.0000053 0.0000236 0.000032 0.000025 1999 6 15 51344 -0.031827 0.297898 0.5261673 0.0006523 -0.000049 0.000122 0.000083 0.000064 0.0000039 0.0000238 0.000032 0.000024 1999 6 16 51345 -0.032542 0.298874 0.5255362 0.0006374 0.000032 0.000092 0.000082 0.000063 0.0000025 0.0000239 0.000032 0.000024 1999 6 17 51346 -0.032970 0.299397 0.5248881 0.0006605 0.000048 0.000067 0.000081 0.000062 0.0000087 0.0000241 0.000032 0.000024 1999 6 18 51347 -0.032904 0.299911 0.5241757 0.0007024 0.000038 0.000046 0.000079 0.000061 0.0000104 0.0000243 0.000032 0.000023 1999 6 19 51348 -0.032808 0.300477 0.5234572 0.0007324 0.000028 0.000025 0.000078 0.000060 0.0000077 0.0000245 0.000031 0.000022 1999 6 20 51349 -0.032460 0.301117 0.5227445 0.0007598 0.000018 0.000004 0.000077 0.000059 0.0000083 0.0000247 0.000031 0.000022 1999 6 21 51350 -0.032265 0.302108 0.5220214 0.0007529 0.000009 -0.000017 0.000075 0.000058 0.0000139 0.0000249 0.000031 0.000022 1999 6 22 51351 -0.032271 0.302929 0.5213319 0.0006946 -0.000001 -0.000038 0.000074 0.000057 0.0000195 0.0000250 0.000031 0.000021 1999 6 23 51352 -0.032414 0.303816 0.5206967 0.0005919 -0.000072 -0.000006 0.000075 0.000058 0.0000084 0.0000252 0.000032 0.000022 1999 6 24 51353 -0.032150 0.304590 0.5201424 0.0004652 -0.000141 0.000019 0.000077 0.000060 0.0000075 0.0000253 0.000032 0.000023 1999 6 25 51354 -0.031884 0.305486 0.5197348 0.0003145 -0.000208 0.000040 0.000078 0.000061 0.0000103 0.0000254 0.000033 0.000024 1999 6 26 51355 -0.031923 0.306571 0.5195063 0.0001801 -0.000220 0.000099 0.000080 0.000062 0.0000100 0.0000254 0.000034 0.000025 1999 6 27 51356 -0.032354 0.307589 0.5194106 0.0000681 -0.000198 0.000180 0.000081 0.000063 0.0000072 0.0000254 0.000034 0.000026 1999 6 28 51357 -0.032603 0.308422 0.5194166 -0.0000357 -0.000177 0.000261 0.000083 0.000064 0.0000093 0.0000254 0.000035 0.000026 1999 6 29 51358 -0.032537 0.309000 0.5195201 -0.0000952 -0.000156 0.000343 0.000084 0.000065 0.0000088 0.0000254 0.000035 0.000027 1999 6 30 51359 -0.032352 0.309494 0.5196931 -0.0001063 -0.000136 0.000143 0.000086 0.000066 0.0000043 0.0000254 0.000036 0.000028 1999 7 1 51360 -0.032183 0.310211 0.5198234 -0.0000623 0.000025 0.000081 0.000087 0.000067 0.0000030 0.0000253 0.000036 0.000028 1999 7 2 51361 -0.032081 0.310909 0.5198314 -0.0000012 0.000082 0.000053 0.000088 0.000068 0.0000087 0.0000252 0.000036 0.000028 1999 7 3 51362 -0.031642 0.311870 0.5197598 0.0001110 0.000083 0.000022 0.000089 0.000069 0.0000134 0.0000251 0.000036 0.000029 1999 7 4 51363 -0.031092 0.313223 0.5196487 0.0002657 0.000084 -0.000009 0.000089 0.000069 0.0000084 0.0000250 0.000036 0.000029 1999 7 5 51364 -0.030374 0.314822 0.5193114 0.0004444 0.000086 -0.000041 0.000090 0.000070 0.0000091 0.0000249 0.000036 0.000029 1999 7 6 51365 -0.029696 0.316192 0.5188037 0.0005967 0.000087 -0.000072 0.000090 0.000070 0.0000089 0.0000247 0.000036 0.000030 1999 7 7 51366 -0.028899 0.317461 0.5181962 0.0006792 0.000088 -0.000103 0.000091 0.000070 0.0000057 0.0000246 0.000036 0.000030 1999 7 8 51367 -0.027984 0.318529 0.5175141 0.0006536 0.000079 -0.000094 0.000091 0.000071 0.0000074 0.0000246 0.000036 0.000030 1999 7 9 51368 -0.026940 0.319696 0.5168860 0.0005596 0.000066 -0.000071 0.000091 0.000071 0.0000118 0.0000245 0.000036 0.000030 1999 7 10 51369 -0.026243 0.320897 0.5163953 0.0004361 0.000053 -0.000048 0.000091 0.000071 0.0000153 0.0000244 0.000036 0.000031 1999 7 11 51370 -0.025508 0.322082 0.5159929 0.0003311 0.000041 -0.000025 0.000091 0.000071 0.0000078 0.0000244 0.000036 0.000031 1999 7 12 51371 -0.024852 0.323296 0.5156999 0.0002690 0.000028 -0.000002 0.000090 0.000070 0.0000088 0.0000244 0.000036 0.000031 1999 7 13 51372 -0.024569 0.324601 0.5154535 0.0002720 0.000016 0.000021 0.000090 0.000070 0.0000084 0.0000244 0.000036 0.000031 1999 7 14 51373 -0.024482 0.325753 0.5152113 0.0003253 0.000003 0.000044 0.000090 0.000070 0.0000038 0.0000243 0.000036 0.000031 1999 7 15 51374 -0.024697 0.326803 0.5148668 0.0004056 0.000009 0.000159 0.000089 0.000070 0.0000047 0.0000243 0.000036 0.000031 1999 7 16 51375 -0.025227 0.327490 0.5143901 0.0004737 0.000018 0.000180 0.000089 0.000069 0.0000077 0.0000243 0.000036 0.000031 1999 7 17 51376 -0.025648 0.328032 0.5138346 0.0005188 0.000025 0.000157 0.000088 0.000069 0.0000099 0.0000243 0.000036 0.000031 1999 7 18 51377 -0.025785 0.328595 0.5132771 0.0005268 0.000032 0.000133 0.000087 0.000069 0.0000097 0.0000244 0.000035 0.000030 1999 7 19 51378 -0.025660 0.329188 0.5127945 0.0005000 0.000039 0.000109 0.000087 0.000068 0.0000095 0.0000244 0.000035 0.000030 1999 7 20 51379 -0.025320 0.330012 0.5123594 0.0004479 0.000046 0.000086 0.000086 0.000068 0.0000094 0.0000244 0.000035 0.000030 1999 7 21 51380 -0.024736 0.330920 0.5119376 0.0003739 -0.000058 0.000121 0.000085 0.000067 0.0000066 0.0000245 0.000034 0.000029 1999 7 22 51381 -0.024143 0.331614 0.5115635 0.0002873 -0.000036 0.000074 0.000084 0.000066 0.0000088 0.0000246 0.000034 0.000029 1999 7 23 51382 -0.023503 0.332326 0.5113035 0.0001891 0.000032 -0.000002 0.000083 0.000066 0.0000130 0.0000246 0.000033 0.000028 1999 7 24 51383 -0.023322 0.332836 0.5111922 0.0000794 0.000100 -0.000078 0.000082 0.000065 0.0000163 0.0000247 0.000033 0.000027 1999 7 25 51384 -0.023588 0.333241 0.5111235 -0.0000125 0.000168 -0.000154 0.000080 0.000064 0.0000151 0.0000248 0.000032 0.000027 1999 7 26 51385 -0.023865 0.333618 0.5111234 -0.0000417 0.000236 -0.000230 0.000079 0.000063 0.0000147 0.0000250 0.000032 0.000026 1999 7 27 51386 -0.023866 0.334073 0.5111718 -0.0000128 0.000251 -0.000263 0.000078 0.000062 0.0000123 0.0000251 0.000031 0.000025 1999 7 28 51387 -0.023752 0.334653 0.5112322 0.0000492 -0.000016 -0.000071 0.000076 0.000061 0.0000046 0.0000252 0.000030 0.000025 1999 7 29 51388 -0.023458 0.335713 0.5111646 0.0001487 -0.000211 -0.000033 0.000074 0.000059 0.0000048 0.0000254 0.000030 0.000024 1999 7 30 51389 -0.022887 0.336690 0.5109683 0.0002756 -0.000214 -0.000038 0.000072 0.000058 0.0000105 0.0000255 0.000029 0.000023 1999 7 31 51390 -0.022216 0.337668 0.5105798 0.0004509 -0.000154 -0.000040 0.000070 0.000056 0.0000138 0.0000257 0.000028 0.000022 1999 8 1 51391 -0.021534 0.338783 0.5099828 0.0006102 -0.000095 -0.000042 0.000068 0.000055 0.0000112 0.0000259 0.000027 0.000021 1999 8 2 51392 -0.020978 0.339819 0.5093301 0.0007459 -0.000035 -0.000043 0.000066 0.000054 0.0000154 0.0000261 0.000027 0.000020 1999 8 3 51393 -0.019877 0.340622 0.5085806 0.0008263 0.000024 -0.000045 0.000064 0.000052 0.0000196 0.0000263 0.000026 0.000020 1999 8 4 51394 -0.018593 0.341616 0.5077234 0.0008191 -0.000073 -0.000166 0.000066 0.000053 0.0000079 0.0000265 0.000027 0.000020 1999 8 5 51395 -0.017126 0.342423 0.5069102 0.0007154 -0.000064 -0.000176 0.000068 0.000055 0.0000118 0.0000268 0.000027 0.000021 1999 8 6 51396 -0.015605 0.343456 0.5062594 0.0005382 -0.000014 -0.000145 0.000070 0.000056 0.0000157 0.0000271 0.000028 0.000022 1999 8 7 51397 -0.014810 0.344761 0.5058113 0.0003553 0.000036 -0.000115 0.000072 0.000058 0.0000091 0.0000275 0.000029 0.000023 1999 8 8 51398 -0.014112 0.345853 0.5054865 0.0002515 0.000086 -0.000084 0.000075 0.000059 0.0000072 0.0000279 0.000030 0.000024 1999 8 9 51399 -0.013836 0.346762 0.5053091 0.0002128 0.000136 -0.000053 0.000077 0.000060 0.0000087 0.0000283 0.000031 0.000025 1999 8 10 51400 -0.013613 0.347249 0.5051476 0.0002508 0.000187 -0.000023 0.000079 0.000062 0.0000103 0.0000287 0.000032 0.000026 1999 8 11 51401 -0.013289 0.347630 0.5048816 0.0003160 0.000171 0.000000 0.000081 0.000063 0.0000048 0.0000291 0.000033 0.000027 1999 8 12 51402 -0.012812 0.347997 0.5045071 0.0004173 0.000185 -0.000071 0.000083 0.000064 0.0000051 0.0000294 0.000033 0.000028 1999 8 13 51403 -0.012327 0.348373 0.5040072 0.0004921 0.000168 -0.000093 0.000084 0.000065 0.0000088 0.0000299 0.000034 0.000029 1999 8 14 51404 -0.011762 0.348812 0.5034173 0.0005648 0.000134 -0.000087 0.000086 0.000066 0.0000106 0.0000303 0.000035 0.000029 1999 8 15 51405 -0.011645 0.349748 0.5027777 0.0006384 0.000101 -0.000081 0.000088 0.000067 0.0000088 0.0000307 0.000035 0.000030 1999 8 16 51406 -0.011770 0.350843 0.5020947 0.0006690 0.000067 -0.000075 0.000090 0.000069 0.0000092 0.0000311 0.000036 0.000031 1999 8 17 51407 -0.011027 0.352151 0.5014391 0.0006238 0.000034 -0.000069 0.000092 0.000070 0.0000084 0.0000315 0.000037 0.000032 1999 8 18 51408 -0.010291 0.353411 0.5008689 0.0005296 0.000037 -0.000003 0.000093 0.000071 0.0000056 0.0000319 0.000038 0.000032 1999 8 19 51409 -0.009789 0.354623 0.5002969 0.0004235 0.000042 0.000026 0.000095 0.000072 0.0000088 0.0000323 0.000038 0.000033 1999 8 20 51410 -0.009443 0.355744 0.4998952 0.0003251 0.000048 0.000043 0.000097 0.000073 0.0000154 0.0000326 0.000039 0.000033 1999 8 21 51411 -0.008629 0.356832 0.4996516 0.0002440 0.000054 0.000060 0.000099 0.000074 0.0000175 0.0000330 0.000039 0.000034 1999 8 22 51412 -0.008158 0.358183 0.4993246 0.0002310 0.000060 0.000077 0.000101 0.000075 0.0000093 0.0000333 0.000040 0.000035 1999 8 23 51413 -0.008200 0.359167 0.4990901 0.0002464 0.000065 0.000094 0.000102 0.000076 0.0000087 0.0000336 0.000041 0.000035 1999 8 24 51414 -0.008465 0.360180 0.4988228 0.0003031 0.000071 0.000111 0.000104 0.000077 0.0000080 0.0000339 0.000041 0.000036 1999 8 25 51415 -0.008809 0.361050 0.4984463 0.0004024 0.000128 -0.000065 0.000105 0.000078 0.0000041 0.0000341 0.000042 0.000037 1999 8 26 51416 -0.008590 0.361749 0.4978690 0.0006185 -0.000066 -0.000220 0.000107 0.000079 0.0000134 0.0000343 0.000042 0.000037 1999 8 27 51417 -0.008354 0.362408 0.4970662 0.0008582 -0.000346 -0.000354 0.000108 0.000080 0.0000175 0.0000345 0.000043 0.000038 1999 8 28 51418 -0.008249 0.362929 0.4960635 0.0010504 -0.000554 -0.000452 0.000109 0.000081 0.0000090 0.0000346 0.000043 0.000038 1999 8 29 51419 -0.007920 0.363242 0.4949363 0.0011668 -0.000405 -0.000394 0.000110 0.000081 0.0000072 0.0000347 0.000044 0.000038 1999 8 30 51420 -0.007309 0.363662 0.4937354 0.0012496 -0.000257 -0.000336 0.000112 0.000082 0.0000087 0.0000348 0.000044 0.000038 1999 8 31 51421 -0.006715 0.364209 0.4925236 0.0012024 -0.000108 -0.000278 0.000113 0.000083 0.0000084 0.0000348 0.000044 0.000038 1999 9 1 51422 -0.006452 0.364772 0.4913893 0.0010891 0.000040 -0.000220 0.000114 0.000083 0.0000054 0.0000348 0.000045 0.000038 1999 9 2 51423 -0.006390 0.364952 0.4903444 0.0009480 0.000087 -0.000166 0.000114 0.000084 0.0000076 0.0000347 0.000045 0.000038 1999 9 3 51424 -0.006299 0.365363 0.4894288 0.0008057 0.000099 -0.000113 0.000115 0.000084 0.0000114 0.0000347 0.000045 0.000038 1999 9 4 51425 -0.005861 0.365542 0.4886479 0.0007320 0.000112 -0.000061 0.000115 0.000084 0.0000125 0.0000345 0.000046 0.000038 1999 9 5 51426 -0.004984 0.366043 0.4879741 0.0007108 0.000125 -0.000008 0.000116 0.000084 0.0000086 0.0000344 0.000046 0.000038 1999 9 6 51427 -0.003753 0.366642 0.4872887 0.0007021 0.000137 0.000045 0.000116 0.000085 0.0000125 0.0000343 0.000046 0.000039 1999 9 7 51428 -0.002492 0.367253 0.4866203 0.0007256 0.000150 0.000097 0.000116 0.000085 0.0000135 0.0000341 0.000047 0.000039 1999 9 8 51429 -0.001366 0.367752 0.4859840 0.0007296 0.000162 0.000150 0.000117 0.000085 0.0000051 0.0000340 0.000047 0.000039 1999 9 9 51430 -0.000338 0.368524 0.4852314 0.0007570 0.000154 0.000114 0.000117 0.000086 0.0000078 0.0000339 0.000047 0.000039 1999 9 10 51431 0.000060 0.369097 0.4844187 0.0007755 0.000139 0.000048 0.000118 0.000086 0.0000118 0.0000337 0.000048 0.000040 1999 9 11 51432 0.000288 0.369602 0.4836235 0.0007608 0.000124 -0.000018 0.000118 0.000086 0.0000085 0.0000335 0.000049 0.000040 1999 9 12 51433 0.000707 0.370124 0.4828941 0.0007119 0.000109 -0.000084 0.000118 0.000087 0.0000066 0.0000333 0.000049 0.000041 1999 9 13 51434 0.001698 0.370726 0.4822128 0.0006217 0.000094 -0.000149 0.000119 0.000087 0.0000085 0.0000332 0.000050 0.000041 1999 9 14 51435 0.002600 0.371710 0.4816335 0.0005068 0.000079 -0.000215 0.000120 0.000088 0.0000092 0.0000330 0.000050 0.000042 1999 9 15 51436 0.003111 0.372655 0.4811822 0.0003803 0.000064 -0.000281 0.000120 0.000088 0.0000069 0.0000329 0.000051 0.000042 1999 9 16 51437 0.003463 0.373416 0.4807661 0.0002963 0.000062 -0.000283 0.000121 0.000089 0.0000104 0.0000327 0.000051 0.000042 1999 9 17 51438 0.003876 0.373824 0.4804318 0.0002378 0.000064 -0.000263 0.000121 0.000089 0.0000131 0.0000326 0.000052 0.000042 1999 9 18 51439 0.004302 0.374156 0.4801805 0.0002402 0.000067 -0.000244 0.000122 0.000090 0.0000093 0.0000325 0.000052 0.000043 1999 9 19 51440 0.004325 0.374638 0.4798722 0.0002892 0.000069 -0.000224 0.000122 0.000090 0.0000070 0.0000324 0.000053 0.000043 1999 9 20 51441 0.004423 0.375165 0.4795289 0.0004034 0.000072 -0.000205 0.000123 0.000091 0.0000066 0.0000323 0.000053 0.000043 1999 9 21 51442 0.004885 0.375456 0.4790436 0.0005568 0.000074 -0.000186 0.000123 0.000091 0.0000062 0.0000322 0.000053 0.000043 1999 9 22 51443 0.005505 0.375785 0.4783433 0.0007460 0.000178 0.000007 0.000124 0.000091 0.0000044 0.0000321 0.000054 0.000043 1999 9 23 51444 0.005510 0.375952 0.4774170 0.0009301 0.000173 0.000012 0.000125 0.000092 0.0000073 0.0000321 0.000054 0.000044 1999 9 24 51445 0.005151 0.376095 0.4763234 0.0010878 0.000128 -0.000051 0.000125 0.000092 0.0000098 0.0000320 0.000054 0.000044 1999 9 25 51446 0.004949 0.375937 0.4751633 0.0011501 0.000083 -0.000115 0.000125 0.000092 0.0000080 0.0000319 0.000054 0.000044 1999 9 26 51447 0.005077 0.375986 0.4740448 0.0011652 0.000038 -0.000178 0.000125 0.000093 0.0000073 0.0000318 0.000054 0.000045 1999 9 27 51448 0.005326 0.376258 0.4729172 0.0011142 -0.000006 -0.000242 0.000126 0.000093 0.0000063 0.0000317 0.000054 0.000045 1999 9 28 51449 0.005582 0.376844 0.4718576 0.0010148 -0.000051 -0.000305 0.000126 0.000093 0.0000053 0.0000316 0.000054 0.000045 1999 9 29 51450 0.005815 0.377491 0.4709023 0.0009086 -0.000016 -0.000208 0.000126 0.000093 0.0000048 0.0000316 0.000054 0.000044 1999 9 30 51451 0.006203 0.378319 0.4700009 0.0007946 0.000020 -0.000140 0.000126 0.000093 0.0000070 0.0000315 0.000054 0.000044 1999 10 1 51452 0.006523 0.379171 0.4692155 0.0006749 0.000052 -0.000093 0.000125 0.000092 0.0000088 0.0000314 0.000054 0.000044 1999 10 2 51453 0.006598 0.380101 0.4685714 0.0006253 0.000084 -0.000046 0.000125 0.000092 0.0000075 0.0000313 0.000053 0.000044 1999 10 3 51454 0.007165 0.380945 0.4679506 0.0007068 0.000115 0.000001 0.000124 0.000091 0.0000062 0.0000313 0.000053 0.000044 1999 10 4 51455 0.007864 0.381773 0.4671864 0.0008596 0.000147 0.000049 0.000124 0.000091 0.0000052 0.0000312 0.000053 0.000043 1999 10 5 51456 0.008447 0.382109 0.4662579 0.0010263 0.000179 0.000096 0.000123 0.000090 0.0000043 0.0000311 0.000053 0.000043 1999 10 6 51457 0.009230 0.382691 0.4651506 0.0011980 0.000064 0.000015 0.000123 0.000090 0.0000029 0.0000311 0.000053 0.000043 1999 10 7 51458 0.009831 0.382885 0.4638705 0.0012905 -0.000001 -0.000059 0.000122 0.000089 0.0000065 0.0000310 0.000053 0.000043 1999 10 8 51459 0.010383 0.382622 0.4625141 0.0013416 -0.000040 -0.000124 0.000122 0.000089 0.0000106 0.0000310 0.000054 0.000044 1999 10 9 51460 0.011241 0.382436 0.4611689 0.0013575 -0.000078 -0.000188 0.000122 0.000089 0.0000108 0.0000310 0.000054 0.000044 1999 10 10 51461 0.012271 0.382811 0.4598430 0.0013108 -0.000117 -0.000252 0.000121 0.000088 0.0000089 0.0000310 0.000054 0.000044 1999 10 11 51462 0.013301 0.382910 0.4585690 0.0011874 -0.000156 -0.000316 0.000121 0.000088 0.0000087 0.0000309 0.000055 0.000045 1999 10 12 51463 0.013950 0.382932 0.4574302 0.0010584 -0.000194 -0.000381 0.000121 0.000088 0.0000075 0.0000309 0.000055 0.000045 1999 10 13 51464 0.014276 0.382876 0.4564654 0.0009590 0.000045 -0.000058 0.000121 0.000088 0.0000046 0.0000309 0.000054 0.000045 1999 10 14 51465 0.014002 0.382777 0.4554564 0.0009040 0.000097 -0.000017 0.000121 0.000088 0.0000100 0.0000308 0.000055 0.000045 1999 10 15 51466 0.013679 0.382745 0.4545502 0.0008074 0.000086 -0.000070 0.000122 0.000088 0.0000125 0.0000307 0.000055 0.000046 1999 10 16 51467 0.013503 0.382752 0.4538195 0.0007178 0.000074 -0.000123 0.000122 0.000088 0.0000075 0.0000306 0.000055 0.000047 1999 10 17 51468 0.014034 0.382582 0.4531260 0.0007164 0.000063 -0.000176 0.000122 0.000088 0.0000076 0.0000305 0.000055 0.000048 1999 10 18 51469 0.014492 0.382440 0.4524089 0.0007929 0.000051 -0.000228 0.000123 0.000089 0.0000076 0.0000304 0.000056 0.000048 1999 10 19 51470 0.015088 0.382487 0.4515963 0.0009132 0.000040 -0.000281 0.000123 0.000089 0.0000077 0.0000303 0.000056 0.000049 1999 10 20 51471 0.015729 0.382795 0.4506104 0.0011262 0.000188 -0.000031 0.000123 0.000089 0.0000042 0.0000302 0.000056 0.000049 1999 10 21 51472 0.016479 0.383039 0.4493306 0.0013767 0.000270 0.000115 0.000124 0.000089 0.0000074 0.0000300 0.000056 0.000050 1999 10 22 51473 0.016801 0.383237 0.4478046 0.0016147 0.000321 0.000205 0.000124 0.000090 0.0000107 0.0000298 0.000056 0.000050 1999 10 23 51474 0.017060 0.383199 0.4461014 0.0018197 0.000306 -0.000110 0.000125 0.000090 0.0000097 0.0000296 0.000056 0.000050 1999 10 24 51475 0.017794 0.383375 0.4442518 0.0019293 0.000286 -0.000460 0.000125 0.000090 0.0000081 0.0000294 0.000056 0.000050 1999 10 25 51476 0.018386 0.383773 0.4423644 0.0019225 0.000211 -0.000360 0.000126 0.000091 0.0000066 0.0000291 0.000055 0.000049 1999 10 26 51477 0.018942 0.383979 0.4405356 0.0018177 0.000130 -0.000217 0.000127 0.000091 0.0000051 0.0000289 0.000055 0.000049 1999 10 27 51478 0.019500 0.383771 0.4388074 0.0016439 0.000080 -0.000098 0.000127 0.000092 0.0000061 0.0000286 0.000054 0.000048 1999 10 28 51479 0.020068 0.383511 0.4372545 0.0014418 0.000077 -0.000064 0.000128 0.000093 0.0000087 0.0000282 0.000053 0.000047 1999 10 29 51480 0.020440 0.383376 0.4358698 0.0012830 0.000088 -0.000058 0.000128 0.000093 0.0000090 0.0000279 0.000053 0.000047 1999 10 30 51481 0.020535 0.383268 0.4346124 0.0012666 0.000099 -0.000052 0.000129 0.000093 0.0000059 0.0000275 0.000052 0.000046 1999 10 31 51482 0.020783 0.383028 0.4334031 0.0013160 0.000110 -0.000045 0.000129 0.000093 0.0000056 0.0000272 0.000052 0.000045 1999 11 1 51483 0.021344 0.382741 0.4321326 0.0013518 0.000121 -0.000039 0.000129 0.000093 0.0000076 0.0000268 0.000051 0.000045 1999 11 2 51484 0.021989 0.382098 0.4307920 0.0014036 0.000132 -0.000033 0.000125 0.000092 0.0000081 0.0000264 0.000050 0.000043 1999 11 3 51485 0.022706 0.381679 0.4294001 0.0015057 0.000098 -0.000014 0.000125 0.000092 0.0000039 0.0000260 0.000050 0.000042 1999 11 4 51486 0.023158 0.381183 0.4279154 0.0015489 0.000140 0.000003 0.000124 0.000091 0.0000039 0.0000256 0.000049 0.000042 1999 11 5 51487 0.023741 0.380542 0.4263651 0.0015315 0.000138 -0.000023 0.000123 0.000091 0.0000057 0.0000253 0.000049 0.000042 1999 11 6 51488 0.024254 0.380333 0.4248372 0.0014939 0.000116 -0.000033 0.000122 0.000091 0.0000074 0.0000249 0.000049 0.000041 1999 11 7 51489 0.024530 0.379874 0.4234127 0.0014187 0.000096 -0.000028 0.000122 0.000090 0.0000094 0.0000245 0.000049 0.000041 1999 11 8 51490 0.024500 0.379245 0.4220752 0.0013281 0.000077 -0.000024 0.000120 0.000090 0.0000160 0.0000242 0.000048 0.000041 1999 11 9 51491 0.024883 0.378222 0.4208030 0.0012905 0.000058 -0.000020 0.000120 0.000089 0.0000226 0.0000239 0.000048 0.000041 1999 11 10 51492 0.025674 0.377265 0.4195343 0.0012397 0.000108 -0.000066 0.000119 0.000089 0.0000090 0.0000236 0.000048 0.000040 1999 11 11 51493 0.026754 0.376489 0.4183254 0.0011526 0.000063 -0.000026 0.000117 0.000088 0.0000168 0.0000234 0.000047 0.000040 1999 11 12 51494 0.027963 0.376323 0.4171902 0.0010879 -0.000052 -0.000013 0.000116 0.000088 0.0000180 0.0000232 0.000046 0.000039 1999 11 13 51495 0.028562 0.376665 0.4160335 0.0011298 -0.000048 -0.000023 0.000115 0.000087 0.0000139 0.0000230 0.000046 0.000038 1999 11 14 51496 0.029111 0.377530 0.4148396 0.0012197 0.000022 -0.000032 0.000113 0.000086 0.0000103 0.0000228 0.000045 0.000037 1999 11 15 51497 0.028906 0.378494 0.4136381 0.0012919 0.000092 -0.000040 0.000112 0.000085 0.0000072 0.0000226 0.000044 0.000036 1999 11 16 51498 0.028560 0.378510 0.4123277 0.0013850 0.000162 -0.000049 0.000111 0.000084 0.0000040 0.0000224 0.000043 0.000035 1999 11 17 51499 0.029146 0.378558 0.4108653 0.0015497 0.000121 -0.000114 0.000110 0.000084 0.0000022 0.0000223 0.000042 0.000034 1999 11 18 51500 0.030306 0.378452 0.4092066 0.0016868 0.000118 -0.000136 0.000108 0.000083 0.0000044 0.0000221 0.000041 0.000033 1999 11 19 51501 0.031732 0.378461 0.4074364 0.0017760 0.000129 -0.000143 0.000107 0.000082 0.0000070 0.0000220 0.000040 0.000033 1999 11 20 51502 0.032759 0.378838 0.4056471 0.0018395 0.000141 -0.000150 0.000106 0.000081 0.0000068 0.0000219 0.000039 0.000032 1999 11 21 51503 0.033290 0.378902 0.4038088 0.0018302 0.000153 -0.000157 0.000104 0.000080 0.0000071 0.0000218 0.000039 0.000031 1999 11 22 51504 0.033301 0.378893 0.4020549 0.0017029 0.000165 -0.000164 0.000103 0.000079 0.0000110 0.0000217 0.000038 0.000030 1999 11 23 51505 0.032928 0.378780 0.4004886 0.0014988 0.000177 -0.000171 0.000101 0.000078 0.0000118 0.0000216 0.000037 0.000030 1999 11 24 51506 0.032573 0.378212 0.3991877 0.0012932 0.000189 -0.000178 0.000099 0.000077 0.0000052 0.0000216 0.000036 0.000029 1999 11 25 51507 0.032296 0.377751 0.3980164 0.0011248 0.000187 -0.000167 0.000097 0.000076 0.0000053 0.0000215 0.000036 0.000028 1999 11 26 51508 0.031945 0.377366 0.3969627 0.0010098 0.000180 -0.000150 0.000095 0.000075 0.0000078 0.0000214 0.000035 0.000027 1999 11 27 51509 0.031666 0.377124 0.3959701 0.0009857 0.000173 -0.000133 0.000093 0.000073 0.0000084 0.0000214 0.000034 0.000027 1999 11 28 51510 0.031952 0.376928 0.3949584 0.0010615 0.000167 -0.000117 0.000091 0.000072 0.0000056 0.0000213 0.000033 0.000026 1999 11 29 51511 0.032659 0.377030 0.3938481 0.0011927 0.000160 -0.000100 0.000089 0.000071 0.0000061 0.0000213 0.000033 0.000025 1999 11 30 51512 0.033409 0.377192 0.3926103 0.0013428 0.000153 -0.000083 0.000087 0.000069 0.0000056 0.0000213 0.000032 0.000025 1999 12 1 51513 0.033930 0.377679 0.3912817 0.0014068 0.000146 -0.000066 0.000085 0.000068 0.0000029 0.0000214 0.000031 0.000024 1999 12 2 51514 0.034344 0.378447 0.3898934 0.0013655 0.000151 -0.000061 0.000083 0.000067 0.0000034 0.0000214 0.000031 0.000023 1999 12 3 51515 0.034454 0.379252 0.3885337 0.0012830 0.000160 -0.000060 0.000082 0.000066 0.0000050 0.0000214 0.000030 0.000023 1999 12 4 51516 0.034613 0.379449 0.3872602 0.0011817 0.000169 -0.000059 0.000080 0.000064 0.0000066 0.0000214 0.000029 0.000022 1999 12 5 51517 0.034861 0.379678 0.3861043 0.0010778 0.000177 -0.000057 0.000077 0.000063 0.0000073 0.0000215 0.000029 0.000022 1999 12 6 51518 0.034600 0.379488 0.3850880 0.0009961 0.000186 -0.000056 0.000075 0.000061 0.0000057 0.0000215 0.000028 0.000021 1999 12 7 51519 0.034377 0.379330 0.3841698 0.0009008 0.000195 -0.000054 0.000073 0.000060 0.0000040 0.0000215 0.000028 0.000021 1999 12 8 51520 0.034622 0.379060 0.3833055 0.0008086 0.000113 0.000004 0.000071 0.000059 0.0000036 0.0000215 0.000027 0.000020 1999 12 9 51521 0.035750 0.379309 0.3824424 0.0007793 0.000080 -0.000011 0.000069 0.000057 0.0000073 0.0000216 0.000027 0.000019 1999 12 10 51522 0.036766 0.379864 0.3816138 0.0007873 0.000066 -0.000054 0.000067 0.000055 0.0000106 0.0000216 0.000026 0.000019 1999 12 11 51523 0.037292 0.380334 0.3808074 0.0008455 0.000052 -0.000096 0.000065 0.000054 0.0000089 0.0000217 0.000026 0.000018 1999 12 12 51524 0.037299 0.380673 0.3799026 0.0009182 0.000038 -0.000138 0.000062 0.000052 0.0000064 0.0000218 0.000025 0.000018 1999 12 13 51525 0.037325 0.380862 0.3789297 0.0010180 0.000024 -0.000181 0.000060 0.000051 0.0000095 0.0000219 0.000025 0.000017 1999 12 14 51526 0.037553 0.381163 0.3778683 0.0011547 0.000010 -0.000223 0.000058 0.000049 0.0000093 0.0000219 0.000024 0.000017 1999 12 15 51527 0.038289 0.381584 0.3767123 0.0012741 0.000081 -0.000091 0.000056 0.000048 0.0000028 0.0000220 0.000024 0.000016 1999 12 16 51528 0.038448 0.382139 0.3753973 0.0013859 0.000181 -0.000080 0.000054 0.000046 0.0000058 0.0000220 0.000023 0.000015 1999 12 17 51529 0.038290 0.382220 0.3739082 0.0014974 0.000175 -0.000106 0.000052 0.000045 0.0000076 0.0000220 0.000023 0.000015 1999 12 18 51530 0.038076 0.382196 0.3723761 0.0015471 0.000125 -0.000131 0.000050 0.000043 0.0000154 0.0000220 0.000022 0.000014 1999 12 19 51531 0.037953 0.382247 0.3708995 0.0015240 0.000075 -0.000155 0.000048 0.000042 0.0000306 0.0000220 0.000021 0.000013 1999 12 20 51532 0.037762 0.382168 0.3694368 0.0014209 0.000025 -0.000180 0.000046 0.000040 0.0000255 0.0000219 0.000021 0.000013 1999 12 21 51533 0.037119 0.381579 0.3680878 0.0012654 -0.000025 -0.000205 0.000045 0.000039 0.0000204 0.0000219 0.000020 0.000012 1999 12 22 51534 0.036561 0.380971 0.3669094 0.0011151 0.000139 -0.000259 0.000046 0.000040 0.0000099 0.0000218 0.000021 0.000013 1999 12 23 51535 0.036440 0.379930 0.3657997 0.0010420 0.000177 -0.000244 0.000048 0.000041 0.0000095 0.0000216 0.000021 0.000013 1999 12 24 51536 0.037108 0.378771 0.3647385 0.0010357 0.000166 -0.000206 0.000050 0.000043 0.0000110 0.0000215 0.000022 0.000013 1999 12 25 51537 0.038034 0.377881 0.3636804 0.0010782 0.000155 -0.000167 0.000052 0.000044 0.0000096 0.0000214 0.000022 0.000014 1999 12 26 51538 0.039036 0.377600 0.3625449 0.0011639 0.000144 -0.000129 0.000054 0.000046 0.0000081 0.0000212 0.000023 0.000014 1999 12 27 51539 0.040093 0.377905 0.3613281 0.0012615 0.000133 -0.000091 0.000056 0.000047 0.0000067 0.0000210 0.000023 0.000015 1999 12 28 51540 0.041141 0.377947 0.3600634 0.0013118 0.000122 -0.000053 0.000058 0.000049 0.0000052 0.0000209 0.000024 0.000016 1999 12 29 51541 0.042214 0.378448 0.3588029 0.0012765 0.000112 -0.000014 0.000060 0.000050 0.0000037 0.0000207 0.000025 0.000016 1999 12 30 51542 0.042570 0.378541 0.3575917 0.0011722 -0.000002 -0.000010 0.000062 0.000052 0.0000036 0.0000206 0.000026 0.000017 1999 12 31 51543 0.042901 0.378300 0.3564311 0.0010635 -0.000026 -0.000028 0.000064 0.000053 0.0000077 0.0000205 0.000026 0.000018 2000 1 1 51544 0.043282 0.377909 0.3553880 0.0009536 -0.000005 -0.000050 0.000072 0.000048 0.0000109 0.0000097 0.000024 0.000017 2000 1 2 51545 0.043551 0.377738 0.3545048 0.0008311 0.000016 -0.000071 0.000072 0.000048 0.0000115 0.0000100 0.000024 0.000017 2000 1 3 51546 0.043681 0.377422 0.3537672 0.0006912 0.000036 -0.000093 0.000071 0.000048 0.0000121 0.0000103 0.000025 0.000017 2000 1 4 51547 0.043462 0.377133 0.3531797 0.0005566 0.000057 -0.000114 0.000071 0.000048 0.0000114 0.0000106 0.000025 0.000018 2000 1 5 51548 0.043084 0.376869 0.3527503 0.0004395 0.000078 -0.000136 0.000071 0.000048 0.0000068 0.0000109 0.000025 0.000018 2000 1 6 51549 0.043029 0.376412 0.3523245 0.0003944 0.000099 -0.000136 0.000071 0.000048 0.0000108 0.0000111 0.000025 0.000018 2000 1 7 51550 0.043535 0.376280 0.3518914 0.0004043 0.000121 -0.000130 0.000072 0.000048 0.0000155 0.0000114 0.000025 0.000019 2000 1 8 51551 0.043845 0.376262 0.3514346 0.0004180 0.000142 -0.000123 0.000072 0.000048 0.0000125 0.0000117 0.000025 0.000019 2000 1 9 51552 0.043831 0.376026 0.3510388 0.0004991 0.000164 -0.000116 0.000072 0.000049 0.0000080 0.0000120 0.000025 0.000019 2000 1 10 51553 0.043606 0.375570 0.3505347 0.0005789 0.000185 -0.000110 0.000072 0.000049 0.0000079 0.0000123 0.000025 0.000019 2000 1 11 51554 0.043690 0.375057 0.3498933 0.0007250 0.000207 -0.000103 0.000073 0.000049 0.0000078 0.0000126 0.000025 0.000020 2000 1 12 51555 0.044197 0.374815 0.3490711 0.0008825 0.000067 -0.000197 0.000073 0.000049 0.0000040 0.0000129 0.000025 0.000019 2000 1 13 51556 0.045019 0.374871 0.3480900 0.0010472 -0.000008 -0.000015 0.000073 0.000049 0.0000037 0.0000132 0.000024 0.000019 2000 1 14 51557 0.046584 0.374991 0.3469250 0.0011462 -0.000014 0.000046 0.000073 0.000050 0.0000078 0.0000135 0.000024 0.000019 2000 1 15 51558 0.047652 0.375073 0.3456908 0.0012039 -0.000005 0.000026 0.000074 0.000050 0.0000110 0.0000138 0.000023 0.000018 2000 1 16 51559 0.048551 0.374963 0.3445177 0.0011360 0.000004 0.000006 0.000074 0.000050 0.0000095 0.0000141 0.000023 0.000017 2000 1 17 51560 0.049428 0.375013 0.3434620 0.0010139 0.000013 -0.000014 0.000074 0.000050 0.0000125 0.0000144 0.000022 0.000017 2000 1 18 51561 0.050704 0.375187 0.3424991 0.0009084 0.000023 -0.000034 0.000074 0.000050 0.0000127 0.0000148 0.000022 0.000016 2000 1 19 51562 0.052041 0.375908 0.3416068 0.0008354 0.000032 -0.000054 0.000074 0.000050 0.0000056 0.0000151 0.000021 0.000016 2000 1 20 51563 0.053163 0.375867 0.3407239 0.0008026 0.000043 -0.000066 0.000074 0.000050 0.0000085 0.0000154 0.000021 0.000015 2000 1 21 51564 0.054297 0.376106 0.3398286 0.0008690 0.000054 -0.000074 0.000075 0.000050 0.0000125 0.0000157 0.000020 0.000015 2000 1 22 51565 0.055145 0.376466 0.3389162 0.0009577 0.000066 -0.000083 0.000075 0.000050 0.0000111 0.0000161 0.000020 0.000014 2000 1 23 51566 0.055844 0.377019 0.3379026 0.0011025 0.000077 -0.000092 0.000075 0.000051 0.0000109 0.0000164 0.000019 0.000014 2000 1 24 51567 0.056264 0.377371 0.3367351 0.0011877 0.000089 -0.000100 0.000075 0.000051 0.0000131 0.0000168 0.000019 0.000013 2000 1 25 51568 0.056538 0.377605 0.3354936 0.0012778 0.000100 -0.000109 0.000075 0.000051 0.0000123 0.0000171 0.000019 0.000013 2000 1 26 51569 0.056600 0.377523 0.3342519 0.0013181 0.000112 -0.000118 0.000075 0.000051 0.0000044 0.0000175 0.000018 0.000013 2000 1 27 51570 0.056911 0.377104 0.3329284 0.0012589 -0.000019 -0.000113 0.000075 0.000051 0.0000074 0.0000179 0.000018 0.000012 2000 1 28 51571 0.057432 0.376888 0.3316839 0.0011488 -0.000198 -0.000105 0.000075 0.000051 0.0000122 0.0000182 0.000017 0.000012 2000 1 29 51572 0.057244 0.376640 0.3306327 0.0009711 -0.000172 -0.000102 0.000075 0.000051 0.0000115 0.0000186 0.000017 0.000011 2000 1 30 51573 0.056960 0.376311 0.3297295 0.0008284 -0.000147 -0.000100 0.000075 0.000050 0.0000100 0.0000190 0.000016 0.000011 2000 1 31 51574 0.056972 0.376210 0.3289711 0.0007241 -0.000121 -0.000098 0.000075 0.000050 0.0000148 0.0000194 0.000016 0.000011 2000 2 1 51575 0.056990 0.375764 0.3283248 0.0006555 -0.000095 -0.000096 0.000075 0.000050 0.0000197 0.0000198 0.000016 0.000010 2000 2 2 51576 0.057184 0.375204 0.3277111 0.0005661 -0.000031 -0.000066 0.000075 0.000050 0.0000065 0.0000202 0.000016 0.000011 2000 2 3 51577 0.057629 0.374563 0.3271845 0.0005105 -0.000047 -0.000064 0.000075 0.000050 0.0000059 0.0000206 0.000017 0.000011 2000 2 4 51578 0.058248 0.373981 0.3266694 0.0004797 -0.000092 -0.000071 0.000075 0.000050 0.0000098 0.0000210 0.000017 0.000012 2000 2 5 51579 0.058980 0.373381 0.3260946 0.0005514 -0.000135 -0.000092 0.000075 0.000050 0.0000087 0.0000213 0.000018 0.000012 2000 2 6 51580 0.059991 0.372895 0.3254287 0.0007119 -0.000177 -0.000113 0.000074 0.000050 0.0000079 0.0000217 0.000018 0.000013 2000 2 7 51581 0.061145 0.372475 0.3246511 0.0008964 -0.000220 -0.000134 0.000074 0.000049 0.0000082 0.0000221 0.000019 0.000013 2000 2 8 51582 0.062204 0.372129 0.3237447 0.0010569 -0.000263 -0.000155 0.000074 0.000049 0.0000085 0.0000224 0.000019 0.000014 2000 2 9 51583 0.063500 0.372097 0.3225967 0.0011870 -0.000070 -0.000141 0.000074 0.000049 0.0000036 0.0000228 0.000020 0.000015 2000 2 10 51584 0.064867 0.371940 0.3213783 0.0012602 -0.000043 -0.000112 0.000074 0.000049 0.0000138 0.0000231 0.000020 0.000015 2000 2 11 51585 0.065953 0.371392 0.3201491 0.0011848 -0.000078 -0.000079 0.000074 0.000049 0.0000292 0.0000235 0.000021 0.000016 2000 2 12 51586 0.066402 0.370960 0.3190459 0.0010620 -0.000068 -0.000073 0.000074 0.000049 0.0000191 0.0000239 0.000021 0.000016 2000 2 13 51587 0.066212 0.370340 0.3180678 0.0008473 -0.000058 -0.000067 0.000073 0.000048 0.0000108 0.0000242 0.000021 0.000016 2000 2 14 51588 0.066047 0.369946 0.3172920 0.0007284 -0.000049 -0.000061 0.000073 0.000048 0.0000073 0.0000245 0.000021 0.000017 2000 2 15 51589 0.065976 0.369514 0.3166409 0.0006804 -0.000039 -0.000055 0.000073 0.000048 0.0000037 0.0000248 0.000022 0.000017 2000 2 16 51590 0.066612 0.368965 0.3159945 0.0006432 -0.000047 -0.000105 0.000073 0.000048 0.0000041 0.0000251 0.000022 0.000018 2000 2 17 51591 0.067406 0.368647 0.3152817 0.0006621 -0.000048 -0.000105 0.000073 0.000048 0.0000068 0.0000254 0.000022 0.000018 2000 2 18 51592 0.068119 0.368571 0.3145266 0.0007662 -0.000047 -0.000088 0.000073 0.000048 0.0000113 0.0000256 0.000022 0.000018 2000 2 19 51593 0.068547 0.368542 0.3137235 0.0009288 -0.000045 -0.000071 0.000073 0.000048 0.0000143 0.0000258 0.000023 0.000018 2000 2 20 51594 0.069060 0.368395 0.3127311 0.0011208 -0.000044 -0.000053 0.000073 0.000048 0.0000116 0.0000259 0.000023 0.000019 2000 2 21 51595 0.069323 0.368272 0.3115661 0.0012641 -0.000043 -0.000036 0.000073 0.000048 0.0000102 0.0000260 0.000023 0.000019 2000 2 22 51596 0.069109 0.367564 0.3103366 0.0012571 -0.000041 -0.000019 0.000073 0.000048 0.0000087 0.0000262 0.000023 0.000019 2000 2 23 51597 0.068886 0.366973 0.3091144 0.0012029 -0.000040 -0.000002 0.000073 0.000048 0.0000072 0.0000263 0.000023 0.000019 2000 2 24 51598 0.068517 0.366276 0.3079342 0.0010635 -0.000038 -0.000007 0.000073 0.000049 0.0000094 0.0000265 0.000023 0.000020 2000 2 25 51599 0.067957 0.365512 0.3068777 0.0009324 -0.000036 -0.000019 0.000073 0.000049 0.0000133 0.0000267 0.000023 0.000019 2000 2 26 51600 0.067429 0.364489 0.3060100 0.0008143 -0.000033 -0.000032 0.000074 0.000049 0.0000133 0.0000268 0.000023 0.000019 2000 2 27 51601 0.067020 0.363666 0.3052872 0.0006623 -0.000031 -0.000045 0.000074 0.000049 0.0000086 0.0000269 0.000023 0.000019 2000 2 28 51602 0.066583 0.362775 0.3046165 0.0005551 -0.000028 -0.000057 0.000074 0.000050 0.0000118 0.0000269 0.000023 0.000019 2000 2 29 51603 0.066512 0.362125 0.3040605 0.0005325 -0.000026 -0.000070 0.000075 0.000050 0.0000120 0.0000270 0.000023 0.000019 2000 3 1 51604 0.066345 0.361616 0.3035981 0.0005505 -0.000023 -0.000082 0.000075 0.000050 0.0000074 0.0000270 0.000023 0.000019 2000 3 2 51605 0.066499 0.361104 0.3030132 0.0005716 -0.000029 -0.000089 0.000075 0.000050 0.0000089 0.0000271 0.000023 0.000019 2000 3 3 51606 0.067093 0.360610 0.3023449 0.0006585 -0.000038 -0.000094 0.000076 0.000051 0.0000128 0.0000272 0.000023 0.000019 2000 3 4 51607 0.067859 0.360414 0.3016227 0.0007916 -0.000047 -0.000099 0.000076 0.000051 0.0000157 0.0000273 0.000022 0.000018 2000 3 5 51608 0.067994 0.360535 0.3007008 0.0009860 -0.000056 -0.000104 0.000076 0.000051 0.0000112 0.0000273 0.000022 0.000018 2000 3 6 51609 0.068076 0.360166 0.2996076 0.0011590 -0.000064 -0.000109 0.000077 0.000051 0.0000113 0.0000274 0.000022 0.000018 2000 3 7 51610 0.068510 0.359999 0.2983732 0.0013066 -0.000073 -0.000114 0.000077 0.000052 0.0000105 0.0000274 0.000022 0.000017 2000 3 8 51611 0.068897 0.359855 0.2970773 0.0013946 -0.000082 -0.000120 0.000077 0.000052 0.0000066 0.0000274 0.000021 0.000017 2000 3 9 51612 0.069186 0.359399 0.2956427 0.0013936 -0.000079 -0.000116 0.000078 0.000052 0.0000128 0.0000275 0.000021 0.000017 2000 3 10 51613 0.070155 0.359049 0.2942295 0.0013435 -0.000072 -0.000110 0.000078 0.000053 0.0000186 0.0000275 0.000021 0.000016 2000 3 11 51614 0.071688 0.358815 0.2929743 0.0012059 -0.000065 -0.000104 0.000078 0.000053 0.0000137 0.0000275 0.000020 0.000016 2000 3 12 51615 0.073143 0.358957 0.2918491 0.0010687 -0.000058 -0.000097 0.000079 0.000053 0.0000122 0.0000276 0.000020 0.000015 2000 3 13 51616 0.074031 0.358646 0.2908886 0.0009403 -0.000051 -0.000091 0.000079 0.000054 0.0000160 0.0000276 0.000020 0.000015 2000 3 14 51617 0.074604 0.358204 0.2900607 0.0008459 -0.000044 -0.000085 0.000079 0.000054 0.0000197 0.0000277 0.000019 0.000015 2000 3 15 51618 0.074769 0.357418 0.2892918 0.0007982 -0.000124 -0.000036 0.000080 0.000054 0.0000103 0.0000277 0.000020 0.000015 2000 3 16 51619 0.074915 0.356420 0.2884584 0.0008656 -0.000324 -0.000043 0.000080 0.000054 0.0000089 0.0000277 0.000020 0.000016 2000 3 17 51620 0.074698 0.355799 0.2875506 0.0009211 -0.000563 -0.000070 0.000080 0.000054 0.0000095 0.0000278 0.000021 0.000017 2000 3 18 51621 0.074260 0.354954 0.2866079 0.0009916 -0.000447 -0.000063 0.000080 0.000054 0.0000078 0.0000278 0.000021 0.000017 2000 3 19 51622 0.073971 0.354172 0.2856537 0.0010140 -0.000331 -0.000056 0.000081 0.000054 0.0000082 0.0000279 0.000022 0.000017 2000 3 20 51623 0.073725 0.353205 0.2846656 0.0010442 -0.000214 -0.000049 0.000081 0.000054 0.0000092 0.0000279 0.000022 0.000018 2000 3 21 51624 0.073931 0.352673 0.2836478 0.0010709 -0.000098 -0.000042 0.000081 0.000054 0.0000085 0.0000279 0.000022 0.000019 2000 3 22 51625 0.074115 0.352471 0.2826350 0.0010321 0.000018 -0.000035 0.000081 0.000054 0.0000031 0.0000280 0.000023 0.000019 2000 3 23 51626 0.074035 0.351743 0.2815714 0.0009889 0.000072 -0.000013 0.000081 0.000054 0.0000068 0.0000281 0.000023 0.000020 2000 3 24 51627 0.074094 0.351189 0.2806249 0.0008573 0.000104 0.000015 0.000081 0.000054 0.0000112 0.0000281 0.000024 0.000021 2000 3 25 51628 0.073861 0.350695 0.2799011 0.0006686 0.000137 0.000042 0.000080 0.000054 0.0000100 0.0000282 0.000025 0.000022 2000 3 26 51629 0.073468 0.349799 0.2793048 0.0005133 0.000170 0.000070 0.000080 0.000054 0.0000107 0.0000283 0.000025 0.000023 2000 3 27 51630 0.073137 0.348856 0.2788718 0.0004116 0.000203 0.000097 0.000080 0.000053 0.0000149 0.0000284 0.000026 0.000023 2000 3 28 51631 0.072830 0.348178 0.2784922 0.0003779 0.000236 0.000125 0.000080 0.000053 0.0000191 0.0000285 0.000027 0.000025 2000 3 29 51632 0.072618 0.347435 0.2781006 0.0004058 0.000028 0.000020 0.000079 0.000053 0.0000091 0.0000286 0.000028 0.000025 2000 3 30 51633 0.073356 0.346488 0.2776374 0.0004546 -0.000023 -0.000016 0.000079 0.000052 0.0000187 0.0000287 0.000028 0.000026 2000 3 31 51634 0.074464 0.346126 0.2771208 0.0005795 -0.000013 -0.000024 0.000078 0.000052 0.0000255 0.0000287 0.000029 0.000026 2000 4 1 51635 0.075340 0.346061 0.2765120 0.0007396 -0.000003 -0.000033 0.000078 0.000051 0.0000157 0.0000288 0.000029 0.000027 2000 4 2 51636 0.075735 0.346320 0.2755798 0.0009646 0.000006 -0.000042 0.000077 0.000051 0.0000172 0.0000288 0.000030 0.000028 2000 4 3 51637 0.076482 0.346647 0.2744741 0.0011730 0.000016 -0.000050 0.000077 0.000051 0.0000188 0.0000288 0.000030 0.000028 2000 4 4 51638 0.077226 0.347082 0.2732350 0.0012963 0.000026 -0.000059 0.000076 0.000050 0.0000176 0.0000288 0.000031 0.000029 2000 4 5 51639 0.077189 0.347143 0.2719381 0.0013450 0.000035 -0.000068 0.000075 0.000050 0.0000106 0.0000288 0.000031 0.000030 2000 4 6 51640 0.077024 0.346919 0.2705901 0.0012875 0.000037 -0.000083 0.000075 0.000049 0.0000119 0.0000287 0.000032 0.000030 2000 4 7 51641 0.077278 0.346353 0.2693075 0.0011543 0.000036 -0.000100 0.000074 0.000049 0.0000116 0.0000286 0.000032 0.000030 2000 4 8 51642 0.077731 0.345818 0.2681943 0.0009949 0.000035 -0.000117 0.000073 0.000048 0.0000059 0.0000285 0.000033 0.000031 2000 4 9 51643 0.077798 0.345231 0.2672690 0.0008150 0.000034 -0.000134 0.000073 0.000048 0.0000076 0.0000284 0.000033 0.000031 2000 4 10 51644 0.078076 0.344341 0.2664574 0.0007455 0.000033 -0.000152 0.000072 0.000047 0.0000093 0.0000283 0.000034 0.000031 2000 4 11 51645 0.079111 0.343534 0.2657062 0.0007641 0.000032 -0.000169 0.000071 0.000046 0.0000096 0.0000281 0.000034 0.000032 2000 4 12 51646 0.080331 0.343409 0.2649465 0.0008482 0.000031 -0.000186 0.000070 0.000046 0.0000069 0.0000279 0.000035 0.000032 2000 4 13 51647 0.081472 0.343411 0.2639708 0.0010021 0.000028 -0.000167 0.000070 0.000045 0.0000069 0.0000277 0.000036 0.000032 2000 4 14 51648 0.082121 0.343673 0.2628471 0.0011442 0.000026 -0.000136 0.000069 0.000045 0.0000104 0.0000275 0.000036 0.000032 2000 4 15 51649 0.082048 0.343986 0.2616345 0.0012997 0.000023 -0.000106 0.000068 0.000044 0.0000132 0.0000272 0.000036 0.000032 2000 4 16 51650 0.082160 0.344331 0.2602694 0.0014257 0.000020 -0.000075 0.000068 0.000044 0.0000080 0.0000269 0.000036 0.000032 2000 4 17 51651 0.082314 0.344301 0.2587978 0.0014729 0.000017 -0.000044 0.000067 0.000044 0.0000122 0.0000267 0.000036 0.000032 2000 4 18 51652 0.082532 0.344198 0.2573527 0.0014426 0.000015 -0.000013 0.000066 0.000043 0.0000120 0.0000263 0.000036 0.000032 2000 4 19 51653 0.082328 0.343973 0.2560271 0.0013307 0.000012 0.000017 0.000066 0.000043 0.0000038 0.0000260 0.000036 0.000032 2000 4 20 51654 0.082356 0.343225 0.2547239 0.0012301 0.000030 0.000027 0.000065 0.000043 0.0000103 0.0000257 0.000037 0.000032 2000 4 21 51655 0.082627 0.342565 0.2535506 0.0011109 0.000054 0.000030 0.000065 0.000042 0.0000168 0.0000254 0.000037 0.000032 2000 4 22 51656 0.082550 0.341903 0.2525556 0.0009861 0.000079 0.000033 0.000064 0.000042 0.0000150 0.0000251 0.000037 0.000032 2000 4 23 51657 0.082778 0.340963 0.2516960 0.0008470 0.000103 0.000036 0.000064 0.000042 0.0000132 0.0000247 0.000038 0.000033 2000 4 24 51658 0.083355 0.340230 0.2509383 0.0007318 0.000128 0.000039 0.000064 0.000041 0.0000114 0.0000244 0.000038 0.000033 2000 4 25 51659 0.084119 0.339736 0.2502349 0.0006630 0.000153 0.000042 0.000063 0.000041 0.0000096 0.0000241 0.000039 0.000033 2000 4 26 51660 0.084972 0.339378 0.2496215 0.0006399 -0.000030 -0.000019 0.000063 0.000041 0.0000050 0.0000237 0.000039 0.000033 2000 4 27 51661 0.085832 0.338986 0.2489291 0.0007086 -0.000077 -0.000009 0.000062 0.000041 0.0000079 0.0000233 0.000039 0.000033 2000 4 28 51662 0.086614 0.338790 0.2480996 0.0008665 -0.000072 0.000027 0.000062 0.000040 0.0000138 0.0000230 0.000039 0.000033 2000 4 29 51663 0.087428 0.338522 0.2471111 0.0010616 -0.000067 0.000064 0.000062 0.000040 0.0000145 0.0000226 0.000039 0.000033 2000 4 30 51664 0.088320 0.338017 0.2459782 0.0012826 -0.000062 0.000100 0.000061 0.000040 0.0000087 0.0000223 0.000039 0.000033 2000 5 1 51665 0.089160 0.337532 0.2446571 0.0014177 -0.000058 0.000136 0.000061 0.000040 0.0000100 0.0000219 0.000039 0.000032 2000 5 2 51666 0.089619 0.337245 0.2432159 0.0014969 -0.000053 0.000172 0.000061 0.000040 0.0000112 0.0000216 0.000039 0.000032 2000 5 3 51667 0.090108 0.336866 0.2417416 0.0015091 -0.000048 0.000208 0.000061 0.000040 0.0000120 0.0000214 0.000039 0.000032 2000 5 4 51668 0.089970 0.336192 0.2402162 0.0014509 -0.000027 0.000200 0.000061 0.000040 0.0000127 0.0000211 0.000039 0.000032 2000 5 5 51669 0.089517 0.335016 0.2388061 0.0013014 -0.000001 0.000176 0.000060 0.000039 0.0000129 0.0000209 0.000039 0.000032 2000 5 6 51670 0.089168 0.333928 0.2376503 0.0011231 0.000025 0.000152 0.000060 0.000039 0.0000113 0.0000207 0.000038 0.000031 2000 5 7 51671 0.088610 0.333122 0.2366587 0.0009482 0.000051 0.000128 0.000060 0.000039 0.0000098 0.0000205 0.000038 0.000030 2000 5 8 51672 0.087910 0.332071 0.2357816 0.0008590 0.000077 0.000105 0.000060 0.000039 0.0000083 0.0000203 0.000038 0.000030 2000 5 9 51673 0.087538 0.330997 0.2349413 0.0008466 0.000103 0.000081 0.000060 0.000039 0.0000067 0.0000202 0.000038 0.000030 2000 5 10 51674 0.087301 0.330222 0.2340508 0.0009375 -0.000023 -0.000123 0.000060 0.000039 0.0000061 0.0000201 0.000037 0.000029 2000 5 11 51675 0.087345 0.329786 0.2330375 0.0010657 0.000032 -0.000112 0.000060 0.000039 0.0000085 0.0000200 0.000037 0.000028 2000 5 12 51676 0.088037 0.329743 0.2318950 0.0011749 0.000021 0.000052 0.000060 0.000039 0.0000118 0.0000199 0.000036 0.000027 2000 5 13 51677 0.088864 0.329725 0.2306661 0.0012284 -0.000038 0.000243 0.000059 0.000039 0.0000133 0.0000198 0.000035 0.000026 2000 5 14 51678 0.089523 0.329858 0.2294104 0.0012776 -0.000097 0.000435 0.000059 0.000038 0.0000108 0.0000197 0.000034 0.000025 2000 5 15 51679 0.090082 0.329836 0.2281017 0.0012460 -0.000156 0.000627 0.000059 0.000038 0.0000140 0.0000197 0.000034 0.000024 2000 5 16 51680 0.090670 0.329436 0.2268849 0.0011421 -0.000215 0.000818 0.000059 0.000038 0.0000148 0.0000196 0.000033 0.000023 2000 5 17 51681 0.090943 0.328621 0.2258745 0.0010425 -0.000277 0.000094 0.000059 0.000038 0.0000093 0.0000196 0.000032 0.000022 2000 5 18 51682 0.091505 0.327809 0.2248699 0.0009322 -0.000258 -0.000095 0.000059 0.000038 0.0000099 0.0000197 0.000031 0.000021 2000 5 19 51683 0.092249 0.327219 0.2239669 0.0008039 -0.000211 -0.000106 0.000059 0.000038 0.0000124 0.0000197 0.000030 0.000020 2000 5 20 51684 0.093309 0.326704 0.2232105 0.0006667 -0.000165 -0.000117 0.000058 0.000038 0.0000149 0.0000197 0.000029 0.000019 2000 5 21 51685 0.094143 0.326295 0.2226026 0.0005588 -0.000119 -0.000128 0.000058 0.000038 0.0000170 0.0000198 0.000028 0.000018 2000 5 22 51686 0.094656 0.325813 0.2220991 0.0005046 -0.000073 -0.000139 0.000058 0.000038 0.0000184 0.0000199 0.000028 0.000017 2000 5 23 51687 0.094718 0.324964 0.2216346 0.0005135 -0.000027 -0.000150 0.000058 0.000038 0.0000199 0.0000199 0.000027 0.000016 2000 5 24 51688 0.094792 0.323558 0.2211139 0.0005245 -0.000029 -0.000141 0.000058 0.000037 0.0000093 0.0000201 0.000027 0.000017 2000 5 25 51689 0.095375 0.322523 0.2205377 0.0005707 -0.000018 -0.000139 0.000057 0.000037 0.0000093 0.0000202 0.000028 0.000018 2000 5 26 51690 0.096124 0.321709 0.2199165 0.0006244 -0.000001 -0.000139 0.000057 0.000037 0.0000147 0.0000204 0.000029 0.000018 2000 5 27 51691 0.097346 0.320982 0.2192559 0.0007196 0.000015 -0.000140 0.000057 0.000037 0.0000187 0.0000206 0.000029 0.000019 2000 5 28 51692 0.098911 0.320301 0.2184499 0.0008562 0.000032 -0.000140 0.000057 0.000037 0.0000121 0.0000208 0.000030 0.000019 2000 5 29 51693 0.100783 0.319487 0.2175801 0.0009338 0.000049 -0.000141 0.000057 0.000037 0.0000100 0.0000210 0.000030 0.000020 2000 5 30 51694 0.102450 0.318903 0.2166647 0.0009701 0.000065 -0.000142 0.000057 0.000037 0.0000100 0.0000212 0.000031 0.000021 2000 5 31 51695 0.103803 0.318226 0.2157848 0.0009149 0.000082 -0.000142 0.000056 0.000037 0.0000149 0.0000215 0.000032 0.000022 2000 6 1 51696 0.105113 0.317643 0.2149066 0.0008215 0.000074 -0.000129 0.000056 0.000037 0.0000137 0.0000218 0.000033 0.000023 2000 6 2 51697 0.106412 0.316737 0.2141359 0.0006573 0.000058 -0.000111 0.000056 0.000037 0.0000128 0.0000222 0.000033 0.000024 2000 6 3 51698 0.107800 0.315668 0.2135173 0.0005175 0.000043 -0.000094 0.000056 0.000037 0.0000143 0.0000226 0.000034 0.000024 2000 6 4 51699 0.108840 0.314688 0.2130236 0.0004368 0.000027 -0.000076 0.000056 0.000037 0.0000124 0.0000230 0.000035 0.000025 2000 6 5 51700 0.109845 0.313739 0.2125715 0.0003701 0.000011 -0.000059 0.000056 0.000037 0.0000165 0.0000235 0.000035 0.000026 2000 6 6 51701 0.111019 0.312822 0.2120987 0.0004683 -0.000005 -0.000041 0.000056 0.000037 0.0000164 0.0000239 0.000036 0.000028 2000 6 7 51702 0.111955 0.312030 0.2115706 0.0006112 -0.000021 -0.000023 0.000056 0.000037 0.0000074 0.0000243 0.000037 0.000029 2000 6 8 51703 0.112636 0.311329 0.2108056 0.0007857 -0.000085 -0.000077 0.000056 0.000037 0.0000090 0.0000247 0.000038 0.000030 2000 6 9 51704 0.112602 0.310501 0.2099035 0.0009294 -0.000165 -0.000155 0.000057 0.000037 0.0000122 0.0000251 0.000038 0.000031 2000 6 10 51705 0.112488 0.309184 0.2089655 0.0009203 -0.000161 -0.000146 0.000057 0.000037 0.0000113 0.0000256 0.000039 0.000032 2000 6 11 51706 0.112664 0.307665 0.2080718 0.0008372 -0.000158 -0.000136 0.000057 0.000037 0.0000108 0.0000261 0.000039 0.000033 2000 6 12 51707 0.113214 0.306193 0.2072988 0.0006664 -0.000154 -0.000127 0.000057 0.000037 0.0000140 0.0000266 0.000039 0.000034 2000 6 13 51708 0.113522 0.305075 0.2066738 0.0006018 -0.000150 -0.000117 0.000057 0.000037 0.0000185 0.0000270 0.000040 0.000035 2000 6 14 51709 0.113693 0.303785 0.2062372 0.0003530 -0.000147 -0.000107 0.000057 0.000037 0.0000257 0.0000273 0.000040 0.000036 2000 6 15 51710 0.113849 0.302616 0.2060271 0.0001575 0.000338 -0.000909 0.000057 0.000037 0.0000247 0.0000277 0.000040 0.000036 2000 6 16 51711 0.113217 0.301386 0.2060038 -0.0000703 0.000981 -0.001980 0.000057 0.000037 0.0000210 0.0000281 0.000040 0.000037 2000 6 17 51712 0.112244 0.300375 0.2060707 -0.0001495 0.000889 -0.001852 0.000058 0.000037 0.0000151 0.0000284 0.000040 0.000037 2000 6 18 51713 0.111057 0.299442 0.2061666 -0.0002406 0.000602 -0.001407 0.000058 0.000038 0.0000083 0.0000287 0.000040 0.000037 2000 6 19 51714 0.109902 0.297909 0.2063862 -0.0001586 0.000315 -0.000961 0.000058 0.000038 0.0000100 0.0000291 0.000039 0.000036 2000 6 20 51715 0.108857 0.296247 0.2066023 -0.0000976 0.000028 -0.000516 0.000058 0.000038 0.0000117 0.0000294 0.000039 0.000036 2000 6 21 51716 0.108158 0.294504 0.2067112 -0.0000768 -0.000062 -0.000014 0.000058 0.000038 0.0000078 0.0000299 0.000038 0.000035 2000 6 22 51717 0.107765 0.292734 0.2066504 0.0000973 -0.000073 0.000101 0.000058 0.000038 0.0000153 0.0000303 0.000037 0.000035 2000 6 23 51718 0.107582 0.290950 0.2065098 0.0001617 -0.000064 0.000087 0.000058 0.000038 0.0000180 0.0000307 0.000037 0.000034 2000 6 24 51719 0.107854 0.289269 0.2063463 0.0002610 -0.000054 0.000072 0.000058 0.000038 0.0000097 0.0000312 0.000036 0.000033 2000 6 25 51720 0.108234 0.288074 0.2060559 0.0003457 -0.000044 0.000058 0.000058 0.000038 0.0000097 0.0000316 0.000035 0.000032 2000 6 26 51721 0.108590 0.286830 0.2056618 0.0003853 -0.000035 0.000043 0.000058 0.000038 0.0000111 0.0000320 0.000034 0.000031 2000 6 27 51722 0.109021 0.285481 0.2052323 0.0004465 -0.000025 0.000028 0.000059 0.000038 0.0000097 0.0000323 0.000034 0.000030 2000 6 28 51723 0.109571 0.284098 0.2048376 0.0004088 -0.000016 0.000014 0.000059 0.000038 0.0000038 0.0000326 0.000033 0.000029 2000 6 29 51724 0.110187 0.283079 0.2044462 0.0003378 -0.000007 0.000012 0.000059 0.000038 0.0000093 0.0000330 0.000033 0.000028 2000 6 30 51725 0.110329 0.281805 0.2041666 0.0001678 0.000002 0.000016 0.000059 0.000039 0.0000141 0.0000334 0.000032 0.000028 2000 7 1 51726 0.110239 0.280109 0.2040647 0.0000944 0.000011 0.000019 0.000059 0.000039 0.0000124 0.0000338 0.000032 0.000027 2000 7 2 51727 0.110106 0.278752 0.2040858 -0.0000476 0.000019 0.000022 0.000059 0.000039 0.0000114 0.0000342 0.000032 0.000026 2000 7 3 51728 0.109621 0.277637 0.2040771 0.0000264 0.000028 0.000025 0.000060 0.000039 0.0000103 0.0000346 0.000031 0.000025 2000 7 4 51729 0.109086 0.276473 0.2039511 0.0001771 0.000037 0.000028 0.000060 0.000039 0.0000093 0.0000349 0.000031 0.000025 2000 7 5 51730 0.108261 0.275685 0.2036576 0.0002943 0.000045 0.000031 0.000060 0.000039 0.0000082 0.0000352 0.000031 0.000024 2000 7 6 51731 0.107371 0.274941 0.2031982 0.0005814 0.000054 0.000034 0.000060 0.000039 0.0000072 0.0000355 0.000030 0.000024 2000 7 7 51732 0.106970 0.274116 0.2025822 0.0005950 0.000006 0.000137 0.000061 0.000040 0.0000164 0.0000357 0.000030 0.000023 2000 7 8 51733 0.106981 0.273402 0.2019120 0.0006773 -0.000029 0.000149 0.000061 0.000040 0.0000170 0.0000360 0.000030 0.000024 2000 7 9 51734 0.106417 0.272972 0.2012677 0.0005801 -0.000050 0.000110 0.000061 0.000040 0.0000127 0.0000363 0.000031 0.000024 2000 7 10 51735 0.105561 0.272208 0.2007041 0.0005418 -0.000071 0.000071 0.000061 0.000040 0.0000084 0.0000366 0.000032 0.000025 2000 7 11 51736 0.104447 0.271613 0.2002595 0.0003985 -0.000092 0.000032 0.000062 0.000040 0.0000042 0.0000368 0.000032 0.000026 2000 7 12 51737 0.103671 0.270534 0.1999106 0.0002941 -0.000116 0.000024 0.000062 0.000040 0.0000052 0.0000370 0.000033 0.000027 2000 7 13 51738 0.102946 0.269478 0.1997052 0.0001161 0.000008 0.000017 0.000062 0.000040 0.0000050 0.0000371 0.000034 0.000028 2000 7 14 51739 0.102245 0.268223 0.1996167 0.0000212 0.000043 0.000016 0.000062 0.000040 0.0000090 0.0000372 0.000035 0.000028 2000 7 15 51740 0.101308 0.267224 0.1996400 -0.0000981 0.000027 0.000019 0.000062 0.000041 0.0000142 0.0000373 0.000035 0.000028 2000 7 16 51741 0.100084 0.265984 0.1997889 -0.0001931 0.000012 0.000023 0.000062 0.000041 0.0000143 0.0000374 0.000036 0.000029 2000 7 17 51742 0.099269 0.265027 0.1999801 -0.0002283 -0.000003 0.000026 0.000062 0.000041 0.0000143 0.0000374 0.000036 0.000029 2000 7 18 51743 0.098336 0.264133 0.2001719 -0.0001619 -0.000019 0.000029 0.000062 0.000041 0.0000135 0.0000374 0.000037 0.000030 2000 7 19 51744 0.097105 0.263129 0.2003240 -0.0001540 -0.000034 0.000032 0.000063 0.000041 0.0000072 0.0000374 0.000038 0.000030 2000 7 20 51745 0.096050 0.261735 0.2004616 -0.0000793 -0.000025 0.000023 0.000063 0.000041 0.0000078 0.0000373 0.000039 0.000031 2000 7 21 51746 0.094886 0.260340 0.2005479 -0.0000248 -0.000007 0.000010 0.000063 0.000041 0.0000097 0.0000373 0.000039 0.000031 2000 7 22 51747 0.093481 0.259256 0.2005959 0.0000354 0.000011 -0.000003 0.000063 0.000041 0.0000063 0.0000373 0.000040 0.000032 2000 7 23 51748 0.092040 0.258376 0.2005394 0.0000380 0.000029 -0.000016 0.000063 0.000041 0.0000054 0.0000373 0.000041 0.000032 2000 7 24 51749 0.091253 0.257108 0.2004521 0.0001963 0.000046 -0.000030 0.000063 0.000041 0.0000045 0.0000372 0.000042 0.000033 2000 7 25 51750 0.090781 0.256261 0.2003750 0.0001401 0.000064 -0.000043 0.000063 0.000041 0.0000036 0.0000371 0.000042 0.000033 2000 7 26 51751 0.090438 0.255796 0.2002926 0.0000368 -0.000019 -0.000105 0.000064 0.000042 0.0000064 0.0000369 0.000043 0.000034 2000 7 27 51752 0.090290 0.255342 0.2002557 -0.0000134 -0.000043 -0.000115 0.000064 0.000042 0.0000095 0.0000368 0.000044 0.000035 2000 7 28 51753 0.089950 0.254846 0.2003033 -0.0001168 -0.000045 -0.000106 0.000064 0.000042 0.0000121 0.0000366 0.000045 0.000036 2000 7 29 51754 0.089060 0.254203 0.2004192 -0.0001556 -0.000047 -0.000097 0.000064 0.000042 0.0000110 0.0000364 0.000046 0.000037 2000 7 30 51755 0.088355 0.253500 0.2006069 -0.0001430 -0.000048 -0.000088 0.000065 0.000042 0.0000090 0.0000362 0.000047 0.000038 2000 7 31 51756 0.087599 0.252614 0.2006984 -0.0000971 -0.000050 -0.000079 0.000065 0.000042 0.0000070 0.0000359 0.000048 0.000039 2000 8 1 51757 0.086972 0.251926 0.2006410 0.0000502 -0.000051 -0.000070 0.000065 0.000042 0.0000058 0.0000356 0.000049 0.000040 2000 8 2 51758 0.086351 0.251350 0.2004674 0.0002568 -0.000053 -0.000061 0.000065 0.000042 0.0000087 0.0000354 0.000051 0.000042 2000 8 3 51759 0.085922 0.250926 0.2001111 0.0003686 -0.000100 0.000012 0.000065 0.000043 0.0000077 0.0000351 0.000052 0.000042 2000 8 4 51760 0.085375 0.250533 0.1996757 0.0004628 -0.000162 0.000105 0.000066 0.000043 0.0000057 0.0000349 0.000053 0.000043 2000 8 5 51761 0.084659 0.249907 0.1992555 0.0003957 -0.000225 0.000198 0.000066 0.000043 0.0000061 0.0000346 0.000054 0.000044 2000 8 6 51762 0.083947 0.249250 0.1989341 0.0002985 -0.000287 0.000291 0.000066 0.000043 0.0000068 0.0000343 0.000055 0.000045 2000 8 7 51763 0.083269 0.248705 0.1987488 0.0001206 -0.000350 0.000384 0.000066 0.000043 0.0000076 0.0000339 0.000056 0.000046 2000 8 8 51764 0.082358 0.248329 0.1987233 0.0000295 -0.000412 0.000477 0.000067 0.000043 0.0000078 0.0000335 0.000057 0.000047 2000 8 9 51765 0.081260 0.247985 0.1988830 -0.0002117 -0.000068 0.000174 0.000067 0.000043 0.0000063 0.0000331 0.000057 0.000047 2000 8 10 51766 0.080084 0.247712 0.1990618 -0.0002321 0.000212 0.000333 0.000067 0.000044 0.0000072 0.0000328 0.000058 0.000047 2000 8 11 51767 0.078274 0.247447 0.1992794 -0.0003110 0.000314 0.000460 0.000067 0.000044 0.0000093 0.0000325 0.000058 0.000047 2000 8 12 51768 0.076590 0.246574 0.1995285 -0.0002252 0.000195 0.000323 0.000067 0.000044 0.0000124 0.0000324 0.000058 0.000047 2000 8 13 51769 0.074991 0.245841 0.1997786 -0.0003053 0.000076 0.000185 0.000067 0.000044 0.0000125 0.0000323 0.000058 0.000046 2000 8 14 51770 0.073597 0.245259 0.1999477 -0.0002181 -0.000042 0.000048 0.000068 0.000044 0.0000126 0.0000321 0.000058 0.000046 2000 8 15 51771 0.072564 0.244767 0.1999917 -0.0000328 -0.000161 -0.000089 0.000068 0.000044 0.0000127 0.0000319 0.000058 0.000046 2000 8 16 51772 0.071989 0.244294 0.1999127 0.0001643 -0.000085 0.000004 0.000068 0.000044 0.0000152 0.0000317 0.000058 0.000046 2000 8 17 51773 0.071351 0.244277 0.1996616 0.0003336 -0.000018 0.000126 0.000068 0.000044 0.0000311 0.0000315 0.000057 0.000046 2000 8 18 51774 0.070444 0.244289 0.1992471 0.0005423 0.000040 0.000252 0.000068 0.000044 0.0000514 0.0000313 0.000057 0.000045 2000 8 19 51775 0.069204 0.244415 0.1986835 0.0005890 0.000048 0.000249 0.000068 0.000045 0.0000464 0.0000311 0.000056 0.000045 2000 8 20 51776 0.067540 0.244210 0.1980283 0.0006050 0.000039 0.000204 0.000068 0.000045 0.0000331 0.0000309 0.000055 0.000044 2000 8 21 51777 0.065964 0.244069 0.1973430 0.0006402 0.000030 0.000159 0.000068 0.000045 0.0000198 0.0000307 0.000054 0.000043 2000 8 22 51778 0.063894 0.243836 0.1966840 0.0006132 0.000021 0.000114 0.000069 0.000045 0.0000065 0.0000306 0.000054 0.000043 2000 8 23 51779 0.062095 0.243576 0.1960632 0.0005591 -0.000033 0.000028 0.000069 0.000045 0.0000046 0.0000306 0.000053 0.000043 2000 8 24 51780 0.060583 0.243283 0.1955168 0.0004892 -0.000025 -0.000036 0.000069 0.000045 0.0000032 0.0000306 0.000053 0.000043 2000 8 25 51781 0.059125 0.242833 0.1950435 0.0004011 -0.000067 -0.000001 0.000069 0.000046 0.0000051 0.0000307 0.000053 0.000043 2000 8 26 51782 0.057446 0.242980 0.1946038 0.0003818 -0.000137 0.000065 0.000069 0.000046 0.0000084 0.0000309 0.000054 0.000044 2000 8 27 51783 0.055606 0.242954 0.1941889 0.0004954 -0.000207 0.000131 0.000069 0.000046 0.0000098 0.0000311 0.000054 0.000044 2000 8 28 51784 0.053815 0.242678 0.1936500 0.0005753 -0.000276 0.000198 0.000070 0.000046 0.0000112 0.0000312 0.000055 0.000045 2000 8 29 51785 0.052284 0.242385 0.1929457 0.0006738 -0.000346 0.000264 0.000070 0.000046 0.0000121 0.0000313 0.000055 0.000046 2000 8 30 51786 0.051227 0.242020 0.1920981 0.0008754 -0.000416 0.000330 0.000070 0.000046 0.0000066 0.0000315 0.000056 0.000046 2000 8 31 51787 0.050094 0.241838 0.1911337 0.0009529 -0.000225 0.000393 0.000070 0.000046 0.0000084 0.0000317 0.000056 0.000047 2000 9 1 51788 0.049149 0.242016 0.1901573 0.0009874 -0.000117 0.000367 0.000070 0.000047 0.0000122 0.0000319 0.000056 0.000047 2000 9 2 51789 0.047956 0.242121 0.1892565 0.0008480 -0.000095 0.000297 0.000070 0.000047 0.0000113 0.0000321 0.000056 0.000048 2000 9 3 51790 0.046791 0.242052 0.1885103 0.0006211 -0.000073 0.000227 0.000070 0.000047 0.0000103 0.0000322 0.000056 0.000048 2000 9 4 51791 0.045267 0.242208 0.1879522 0.0004544 -0.000052 0.000157 0.000070 0.000047 0.0000094 0.0000324 0.000056 0.000048 2000 9 5 51792 0.043388 0.242258 0.1875842 0.0003257 -0.000030 0.000086 0.000070 0.000047 0.0000085 0.0000325 0.000056 0.000047 2000 9 6 51793 0.041473 0.242320 0.1873849 0.0002227 -0.000276 0.000270 0.000070 0.000047 0.0000076 0.0000327 0.000056 0.000047 2000 9 7 51794 0.039014 0.242166 0.1872671 0.0000222 -0.000286 0.000292 0.000070 0.000047 0.0000072 0.0000329 0.000056 0.000046 2000 9 8 51795 0.036693 0.241767 0.1872382 -0.0000525 -0.000219 0.000260 0.000070 0.000046 0.0000070 0.0000331 0.000055 0.000045 2000 9 9 51796 0.034228 0.241347 0.1873232 -0.0001307 -0.000152 0.000228 0.000069 0.000046 0.0000070 0.0000333 0.000055 0.000044 2000 9 10 51797 0.031784 0.240621 0.1873649 -0.0000062 -0.000085 0.000196 0.000069 0.000046 0.0000072 0.0000335 0.000054 0.000043 2000 9 11 51798 0.029885 0.240222 0.1873297 0.0000826 -0.000018 0.000164 0.000069 0.000046 0.0000075 0.0000338 0.000053 0.000042 2000 9 12 51799 0.027876 0.239906 0.1872027 0.0001998 0.000049 0.000132 0.000069 0.000046 0.0000074 0.0000341 0.000053 0.000042 2000 9 13 51800 0.025274 0.239634 0.1870353 0.0003203 0.000116 0.000100 0.000069 0.000046 0.0000054 0.0000345 0.000052 0.000041 2000 9 14 51801 0.022086 0.239787 0.1866289 0.0005360 0.000121 0.000017 0.000068 0.000045 0.0000046 0.0000350 0.000052 0.000040 2000 9 15 51802 0.019134 0.239916 0.1860645 0.0006979 0.000106 -0.000083 0.000068 0.000045 0.0000041 0.0000355 0.000051 0.000039 2000 9 16 51803 0.016783 0.240022 0.1853734 0.0008113 0.000081 -0.000052 0.000068 0.000045 0.0000039 0.0000360 0.000051 0.000039 2000 9 17 51804 0.015191 0.240015 0.1846553 0.0008181 0.000055 -0.000010 0.000068 0.000045 0.0000037 0.0000365 0.000050 0.000038 2000 9 18 51805 0.013685 0.240526 0.1839748 0.0006622 0.000030 0.000031 0.000067 0.000045 0.0000036 0.0000370 0.000050 0.000038 2000 9 19 51806 0.012390 0.241222 0.1833788 0.0005517 0.000004 0.000073 0.000067 0.000044 0.0000034 0.0000374 0.000049 0.000037 2000 9 20 51807 0.010673 0.242265 0.1828979 0.0004962 0.000048 0.000084 0.000067 0.000044 0.0000051 0.0000378 0.000049 0.000037 2000 9 21 51808 0.008863 0.243294 0.1825035 0.0003526 0.000081 -0.000028 0.000067 0.000044 0.0000039 0.0000382 0.000049 0.000037 2000 9 22 51809 0.006863 0.243810 0.1820738 0.0003934 0.000083 -0.000062 0.000066 0.000044 0.0000062 0.0000385 0.000048 0.000037 2000 9 23 51810 0.005365 0.243669 0.1816228 0.0003983 0.000076 -0.000053 0.000066 0.000043 0.0000092 0.0000389 0.000048 0.000037 2000 9 24 51811 0.004159 0.243572 0.1812197 0.0005738 0.000069 -0.000045 0.000066 0.000043 0.0000076 0.0000392 0.000048 0.000036 2000 9 25 51812 0.002970 0.243639 0.1806392 0.0007460 0.000062 -0.000036 0.000066 0.000043 0.0000060 0.0000394 0.000048 0.000036 2000 9 26 51813 0.001745 0.243714 0.1798628 0.0007694 0.000055 -0.000027 0.000065 0.000042 0.0000044 0.0000397 0.000047 0.000036 2000 9 27 51814 0.000719 0.244100 0.1788840 0.0010437 0.000097 0.000042 0.000065 0.000042 0.0000056 0.0000399 0.000046 0.000036 2000 9 28 51815 -0.000550 0.244683 0.1777194 0.0010892 0.000076 0.000084 0.000065 0.000042 0.0000128 0.0000401 0.000046 0.000035 2000 9 29 51816 -0.002260 0.245702 0.1765529 0.0011505 0.000029 0.000109 0.000064 0.000042 0.0000187 0.0000403 0.000045 0.000035 2000 9 30 51817 -0.004300 0.246566 0.1755364 0.0010352 -0.000019 0.000135 0.000064 0.000042 0.0000144 0.0000406 0.000045 0.000035 2000 10 1 51818 -0.005834 0.247135 0.1746180 0.0009251 -0.000066 0.000161 0.000064 0.000041 0.0000185 0.0000408 0.000044 0.000034 2000 10 2 51819 -0.007143 0.247786 0.1738770 0.0006472 -0.000114 0.000187 0.000064 0.000041 0.0000225 0.0000409 0.000044 0.000034 2000 10 3 51820 -0.009083 0.248486 0.1733347 0.0004933 -0.000161 0.000213 0.000064 0.000041 0.0000229 0.0000410 0.000043 0.000034 2000 10 4 51821 -0.011243 0.248977 0.1730497 0.0002916 0.000093 0.000155 0.000064 0.000041 0.0000086 0.0000412 0.000043 0.000033 2000 10 5 51822 -0.013099 0.249524 0.1727845 0.0001809 0.000241 0.000191 0.000064 0.000041 0.0000122 0.0000414 0.000042 0.000033 2000 10 6 51823 -0.014650 0.250125 0.1725293 0.0001696 0.000335 0.000264 0.000064 0.000041 0.0000193 0.0000417 0.000041 0.000032 2000 10 7 51824 -0.016103 0.250552 0.1722681 0.0002918 0.000428 0.000337 0.000064 0.000041 0.0000165 0.0000420 0.000041 0.000031 2000 10 8 51825 -0.017586 0.250708 0.1718529 0.0004435 0.000522 0.000410 0.000064 0.000041 0.0000140 0.0000424 0.000040 0.000031 2000 10 9 51826 -0.019009 0.251060 0.1712893 0.0006438 0.000616 0.000483 0.000064 0.000041 0.0000116 0.0000427 0.000039 0.000030 2000 10 10 51827 -0.020528 0.251898 0.1705478 0.0007477 0.000710 0.000556 0.000064 0.000041 0.0000091 0.0000430 0.000039 0.000030 2000 10 11 51828 -0.021815 0.253145 0.1695963 0.0009843 0.000202 0.000320 0.000064 0.000041 0.0000061 0.0000433 0.000038 0.000029 2000 10 12 51829 -0.022870 0.254828 0.1684777 0.0012038 0.000099 0.000011 0.000064 0.000041 0.0000065 0.0000435 0.000038 0.000029 2000 10 13 51830 -0.024222 0.256585 0.1671919 0.0012761 0.000088 -0.000095 0.000064 0.000041 0.0000219 0.0000437 0.000037 0.000028 2000 10 14 51831 -0.026177 0.258129 0.1658356 0.0013665 0.000054 -0.000120 0.000064 0.000041 0.0000361 0.0000439 0.000036 0.000027 2000 10 15 51832 -0.028172 0.259351 0.1645321 0.0013190 0.000020 -0.000145 0.000064 0.000041 0.0000257 0.0000442 0.000035 0.000026 2000 10 16 51833 -0.030374 0.260496 0.1633084 0.0011811 -0.000015 -0.000170 0.000064 0.000041 0.0000153 0.0000444 0.000034 0.000026 2000 10 17 51834 -0.032251 0.261189 0.1622051 0.0011223 -0.000049 -0.000195 0.000064 0.000041 0.0000049 0.0000445 0.000034 0.000024 2000 10 18 51835 -0.033909 0.262038 0.1611801 0.0009538 0.000082 0.000054 0.000064 0.000041 0.0000050 0.0000448 0.000033 0.000024 2000 10 19 51836 -0.035688 0.262804 0.1602266 0.0009002 -0.000024 0.000087 0.000064 0.000041 0.0000037 0.0000450 0.000032 0.000023 2000 10 20 51837 -0.037464 0.263626 0.1593225 0.0008499 -0.000058 0.000071 0.000064 0.000041 0.0000196 0.0000451 0.000031 0.000022 2000 10 21 51838 -0.039128 0.264584 0.1583637 0.0009603 -0.000033 0.000070 0.000064 0.000041 0.0000365 0.0000452 0.000031 0.000021 2000 10 22 51839 -0.040589 0.265507 0.1572777 0.0012353 -0.000008 0.000069 0.000064 0.000042 0.0000311 0.0000452 0.000030 0.000020 2000 10 23 51840 -0.042007 0.266930 0.1560184 0.0013420 0.000017 0.000068 0.000064 0.000042 0.0000258 0.0000451 0.000029 0.000020 2000 10 24 51841 -0.043341 0.268602 0.1545944 0.0014149 0.000043 0.000067 0.000064 0.000042 0.0000204 0.0000448 0.000028 0.000019 2000 10 25 51842 -0.044253 0.270088 0.1530529 0.0015363 -0.000069 0.000078 0.000064 0.000042 0.0000072 0.0000442 0.000029 0.000020 2000 10 26 51843 -0.045550 0.271814 0.1514400 0.0015665 -0.000279 -0.000272 0.000065 0.000042 0.0000181 0.0000435 0.000029 0.000020 2000 10 27 51844 -0.046939 0.273705 0.1498451 0.0015250 -0.000281 -0.000343 0.000065 0.000042 0.0000306 0.0000429 0.000029 0.000021 2000 10 28 51845 -0.048327 0.275161 0.1483214 0.0014118 -0.000187 -0.000251 0.000065 0.000042 0.0000179 0.0000424 0.000030 0.000021 2000 10 29 51846 -0.049265 0.276439 0.1470379 0.0012506 -0.000093 -0.000159 0.000065 0.000042 0.0000130 0.0000420 0.000030 0.000022 2000 10 30 51847 -0.050052 0.278395 0.1459174 0.0011372 0.000001 -0.000067 0.000065 0.000042 0.0000080 0.0000416 0.000030 0.000022 2000 10 31 51848 -0.051094 0.280815 0.1449431 0.0010246 0.000095 0.000024 0.000065 0.000042 0.0000030 0.0000412 0.000030 0.000023 2000 11 1 51849 -0.052417 0.282867 0.1440416 0.0008840 0.000049 0.000116 0.000065 0.000042 0.0000038 0.0000407 0.000031 0.000024 2000 11 2 51850 -0.053694 0.284365 0.1432197 0.0007932 0.000033 0.000133 0.000065 0.000042 0.0000047 0.0000402 0.000031 0.000024 2000 11 3 51851 -0.055164 0.286178 0.1424206 0.0008473 0.000142 0.000050 0.000065 0.000042 0.0000051 0.0000397 0.000031 0.000024 2000 11 4 51852 -0.056481 0.287857 0.1415947 0.0008616 0.000112 0.000018 0.000065 0.000042 0.0000052 0.0000393 0.000031 0.000024 2000 11 5 51853 -0.057678 0.289390 0.1406988 0.0009318 0.000013 0.000017 0.000065 0.000042 0.0000050 0.0000389 0.000031 0.000024 2000 11 6 51854 -0.059210 0.291272 0.1397037 0.0010670 -0.000087 0.000017 0.000065 0.000042 0.0000049 0.0000386 0.000031 0.000024 2000 11 7 51855 -0.060754 0.293583 0.1385947 0.0010778 -0.000187 0.000016 0.000065 0.000042 0.0000049 0.0000383 0.000030 0.000024 2000 11 8 51856 -0.062173 0.295889 0.1373692 0.0012150 -0.000287 0.000015 0.000065 0.000042 0.0000051 0.0000379 0.000030 0.000024 2000 11 9 51857 -0.063771 0.297999 0.1360613 0.0012873 -0.000241 -0.000026 0.000065 0.000042 0.0000053 0.0000375 0.000030 0.000023 2000 11 10 51858 -0.065175 0.299623 0.1347210 0.0013262 -0.000147 -0.000082 0.000065 0.000043 0.0000055 0.0000372 0.000030 0.000023 2000 11 11 51859 -0.066122 0.300859 0.1334189 0.0013859 -0.000052 -0.000138 0.000065 0.000042 0.0000057 0.0000370 0.000029 0.000022 2000 11 12 51860 -0.066267 0.301790 0.1322309 0.0013194 0.000042 -0.000193 0.000064 0.000042 0.0000059 0.0000367 0.000029 0.000022 2000 11 13 51861 -0.066359 0.303416 0.1312137 0.0009852 0.000137 -0.000249 0.000064 0.000042 0.0000062 0.0000364 0.000029 0.000022 2000 11 14 51862 -0.067272 0.305461 0.1303822 0.0008214 0.000231 -0.000304 0.000064 0.000042 0.0000064 0.0000360 0.000028 0.000021 2000 11 15 51863 -0.069108 0.307209 0.1296928 0.0006303 0.000006 -0.000046 0.000064 0.000042 0.0000043 0.0000355 0.000028 0.000020 2000 11 16 51864 -0.071235 0.308677 0.1290324 0.0005660 -0.000039 0.000016 0.000064 0.000042 0.0000060 0.0000350 0.000027 0.000020 2000 11 17 51865 -0.073178 0.309937 0.1283650 0.0006261 -0.000015 0.000003 0.000064 0.000042 0.0000088 0.0000344 0.000027 0.000019 2000 11 18 51866 -0.074827 0.311678 0.1276982 0.0007143 0.000010 -0.000010 0.000065 0.000043 0.0000097 0.0000338 0.000026 0.000018 2000 11 19 51867 -0.075726 0.313629 0.1268663 0.0009664 0.000034 -0.000023 0.000065 0.000043 0.0000097 0.0000332 0.000025 0.000018 2000 11 20 51868 -0.075931 0.315766 0.1258878 0.0010965 0.000059 -0.000036 0.000065 0.000043 0.0000096 0.0000325 0.000025 0.000017 2000 11 21 51869 -0.075827 0.318170 0.1248040 0.0011172 0.000083 -0.000049 0.000065 0.000043 0.0000089 0.0000319 0.000024 0.000016 2000 11 22 51870 -0.075821 0.320485 0.1236944 0.0011586 0.000108 -0.000062 0.000065 0.000043 0.0000053 0.0000312 0.000024 0.000016 2000 11 23 51871 -0.076148 0.322508 0.1225625 0.0012137 0.000124 -0.000033 0.000065 0.000043 0.0000042 0.0000305 0.000023 0.000015 2000 11 24 51872 -0.076556 0.324300 0.1215015 0.0010547 0.000138 0.000011 0.000065 0.000043 0.0000038 0.0000298 0.000023 0.000015 2000 11 25 51873 -0.077094 0.326015 0.1205685 0.0009039 0.000151 0.000054 0.000065 0.000043 0.0000034 0.0000291 0.000022 0.000014 2000 11 26 51874 -0.077702 0.327843 0.1197780 0.0007192 0.000165 0.000098 0.000065 0.000043 0.0000030 0.0000285 0.000022 0.000014 2000 11 27 51875 -0.078454 0.329906 0.1191182 0.0005681 0.000179 0.000141 0.000065 0.000043 0.0000027 0.0000278 0.000022 0.000013 2000 11 28 51876 -0.079116 0.331758 0.1185559 0.0004306 0.000193 0.000185 0.000065 0.000043 0.0000023 0.0000271 0.000021 0.000013 2000 11 29 51877 -0.079303 0.333520 0.1180552 0.0005098 0.000243 0.000128 0.000066 0.000043 0.0000048 0.0000264 0.000021 0.000013 2000 11 30 51878 -0.079567 0.335367 0.1174664 0.0005906 0.000246 0.000090 0.000066 0.000043 0.0000090 0.0000257 0.000020 0.000012 2000 12 1 51879 -0.080088 0.337160 0.1168213 0.0005567 0.000230 0.000069 0.000066 0.000043 0.0000123 0.0000251 0.000020 0.000012 2000 12 2 51880 -0.080678 0.338938 0.1161932 0.0007162 0.000214 0.000047 0.000066 0.000043 0.0000113 0.0000245 0.000019 0.000011 2000 12 3 51881 -0.080846 0.340656 0.1154113 0.0008998 0.000197 0.000026 0.000066 0.000043 0.0000141 0.0000238 0.000019 0.000011 2000 12 4 51882 -0.080899 0.342253 0.1144831 0.0010206 0.000181 0.000005 0.000066 0.000043 0.0000169 0.0000232 0.000018 0.000010 2000 12 5 51883 -0.081176 0.343996 0.1134111 0.0011160 0.000164 -0.000017 0.000066 0.000043 0.0000198 0.0000226 0.000018 0.000010 2000 12 6 51884 -0.081761 0.345538 0.1122265 0.0012326 0.000105 -0.000010 0.000066 0.000043 0.0000079 0.0000220 0.000019 0.000011 2000 12 7 51885 -0.082310 0.347259 0.1108615 0.0013537 0.000184 0.000006 0.000066 0.000043 0.0000144 0.0000213 0.000019 0.000011 2000 12 8 51886 -0.082802 0.349206 0.1094701 0.0013604 0.000302 0.000019 0.000066 0.000043 0.0000224 0.0000207 0.000020 0.000012 2000 12 9 51887 -0.083382 0.351179 0.1082384 0.0012148 0.000319 0.000000 0.000065 0.000043 0.0000118 0.0000201 0.000020 0.000012 2000 12 10 51888 -0.083754 0.352915 0.1070813 0.0011450 0.000336 -0.000019 0.000065 0.000043 0.0000090 0.0000195 0.000021 0.000013 2000 12 11 51889 -0.083843 0.354191 0.1061022 0.0010193 0.000353 -0.000038 0.000065 0.000043 0.0000063 0.0000189 0.000021 0.000013 2000 12 12 51890 -0.083646 0.355623 0.1052996 0.0007756 0.000371 -0.000057 0.000065 0.000043 0.0000035 0.0000184 0.000022 0.000014 2000 12 13 51891 -0.082664 0.357131 0.1045911 0.0006741 0.000291 0.000055 0.000065 0.000043 0.0000047 0.0000178 0.000023 0.000015 2000 12 14 51892 -0.081393 0.359260 0.1039421 0.0006136 0.000264 0.000109 0.000065 0.000043 0.0000030 0.0000172 0.000023 0.000015 2000 12 15 51893 -0.080135 0.361383 0.1031910 0.0007310 0.000235 0.000119 0.000065 0.000043 0.0000048 0.0000167 0.000024 0.000016 2000 12 16 51894 -0.079024 0.363630 0.1023474 0.0007836 0.000195 0.000124 0.000065 0.000043 0.0000075 0.0000161 0.000024 0.000016 2000 12 17 51895 -0.078067 0.365887 0.1015430 0.0009910 0.000156 0.000130 0.000065 0.000043 0.0000074 0.0000156 0.000025 0.000016 2000 12 18 51896 -0.077727 0.368191 0.1006547 0.0009694 0.000116 0.000136 0.000065 0.000043 0.0000072 0.0000151 0.000025 0.000017 2000 12 19 51897 -0.078190 0.369885 0.0997431 0.0009221 0.000077 0.000142 0.000065 0.000043 0.0000070 0.0000146 0.000026 0.000018 2000 12 20 51898 -0.078619 0.371768 0.0987944 0.0009176 0.000176 -0.000007 0.000065 0.000043 0.0000065 0.0000141 0.000026 0.000018 2000 12 21 51899 -0.078763 0.374025 0.0978634 0.0008020 0.000202 -0.000060 0.000065 0.000043 0.0000082 0.0000137 0.000027 0.000019 2000 12 22 51900 -0.078429 0.376450 0.0970825 0.0006559 0.000200 -0.000076 0.000065 0.000043 0.0000118 0.0000132 0.000027 0.000019 2000 12 23 51901 -0.077978 0.379162 0.0965805 0.0005588 0.000197 -0.000092 0.000065 0.000043 0.0000182 0.0000128 0.000028 0.000020 2000 12 24 51902 -0.077583 0.381643 0.0960915 0.0004371 0.000195 -0.000107 0.000065 0.000043 0.0000159 0.0000123 0.000028 0.000020 2000 12 25 51903 -0.077083 0.384328 0.0957210 0.0003468 0.000192 -0.000123 0.000065 0.000043 0.0000137 0.0000119 0.000029 0.000021 2000 12 26 51904 -0.076528 0.386679 0.0954321 0.0002443 0.000189 -0.000139 0.000065 0.000043 0.0000114 0.0000115 0.000029 0.000021 2000 12 27 51905 -0.076299 0.388960 0.0951789 0.0002611 0.000187 -0.000155 0.000065 0.000043 0.0000092 0.0000111 0.000030 0.000022 2000 12 28 51906 -0.076091 0.390943 0.0949122 0.0002705 0.000184 -0.000171 0.000065 0.000043 0.0000069 0.0000107 0.000030 0.000023 2000 12 29 51907 -0.075460 0.392853 0.0946121 0.0002759 0.000177 -0.000162 0.000065 0.000043 0.0000096 0.0000104 0.000031 0.000024 2000 12 30 51908 -0.074894 0.394769 0.0942310 0.0003631 0.000168 -0.000144 0.000065 0.000043 0.0000127 0.0000100 0.000032 0.000024 2000 12 31 51909 -0.074242 0.396478 0.0937596 0.0005962 0.000159 -0.000127 0.000065 0.000043 0.0000104 0.0000097 0.000032 0.000025 2001 1 1 51910 -0.073506 0.398095 0.0931626 0.0006630 0.000150 -0.000109 0.000061 0.000048 0.0000107 0.0000131 0.000028 0.000030 2001 1 2 51911 -0.072651 0.399806 0.0924546 0.0007596 0.000141 -0.000092 0.000061 0.000048 0.0000070 0.0000131 0.000028 0.000031 2001 1 3 51912 -0.071557 0.401864 0.0916573 0.0008515 0.000132 -0.000074 0.000061 0.000047 0.0000034 0.0000131 0.000028 0.000031 2001 1 4 51913 -0.071024 0.403840 0.0907195 0.0008969 0.000149 -0.000084 0.000061 0.000047 0.0000084 0.0000132 0.000029 0.000031 2001 1 5 51914 -0.070723 0.405333 0.0897667 0.0008872 0.000174 -0.000103 0.000060 0.000047 0.0000163 0.0000132 0.000029 0.000031 2001 1 6 51915 -0.070378 0.406725 0.0889292 0.0008068 0.000199 -0.000122 0.000060 0.000047 0.0000221 0.0000132 0.000029 0.000031 2001 1 7 51916 -0.070068 0.408041 0.0882375 0.0006463 0.000224 -0.000141 0.000060 0.000047 0.0000163 0.0000132 0.000029 0.000031 2001 1 8 51917 -0.070205 0.409479 0.0876861 0.0004933 0.000250 -0.000160 0.000060 0.000047 0.0000104 0.0000132 0.000029 0.000031 2001 1 9 51918 -0.070220 0.410814 0.0872445 0.0004441 0.000275 -0.000179 0.000060 0.000046 0.0000046 0.0000132 0.000029 0.000032 2001 1 10 51919 -0.069861 0.412336 0.0868199 0.0004186 0.000270 -0.000158 0.000060 0.000046 0.0000043 0.0000133 0.000029 0.000031 2001 1 11 51920 -0.069330 0.414004 0.0864003 0.0004447 0.000155 -0.000180 0.000059 0.000046 0.0000039 0.0000133 0.000029 0.000031 2001 1 12 51921 -0.068456 0.416120 0.0858451 0.0005855 0.000106 -0.000203 0.000059 0.000046 0.0000088 0.0000133 0.000028 0.000030 2001 1 13 51922 -0.067463 0.418251 0.0851161 0.0007422 0.000095 -0.000222 0.000059 0.000046 0.0000138 0.0000133 0.000028 0.000030 2001 1 14 51923 -0.066479 0.420226 0.0842390 0.0008823 0.000084 -0.000241 0.000059 0.000046 0.0000112 0.0000134 0.000028 0.000029 2001 1 15 51924 -0.065406 0.422044 0.0833100 0.0009404 0.000072 -0.000259 0.000059 0.000046 0.0000086 0.0000134 0.000027 0.000028 2001 1 16 51925 -0.063999 0.423541 0.0824180 0.0009155 0.000061 -0.000278 0.000059 0.000046 0.0000060 0.0000134 0.000027 0.000028 2001 1 17 51926 -0.062602 0.425076 0.0816384 0.0007815 0.000050 -0.000297 0.000059 0.000046 0.0000034 0.0000135 0.000027 0.000027 2001 1 18 51927 -0.061434 0.426438 0.0809369 0.0005717 0.000307 -0.000078 0.000060 0.000046 0.0000060 0.0000135 0.000026 0.000026 2001 1 19 51928 -0.060301 0.428009 0.0803992 0.0004021 0.000387 -0.000005 0.000060 0.000046 0.0000114 0.0000135 0.000026 0.000025 2001 1 20 51929 -0.059175 0.429380 0.0801026 0.0002618 0.000335 -0.000045 0.000060 0.000046 0.0000197 0.0000136 0.000025 0.000025 2001 1 21 51930 -0.058122 0.430418 0.0799970 0.0000786 0.000284 -0.000085 0.000060 0.000046 0.0000198 0.0000136 0.000025 0.000024 2001 1 22 51931 -0.056745 0.431190 0.0799904 -0.0000387 0.000232 -0.000124 0.000060 0.000047 0.0000199 0.0000136 0.000024 0.000023 2001 1 23 51932 -0.055378 0.432515 0.0800354 -0.0000794 0.000180 -0.000164 0.000061 0.000047 0.0000200 0.0000137 0.000024 0.000022 2001 1 24 51933 -0.054038 0.434299 0.0801054 -0.0000531 0.000189 -0.000183 0.000061 0.000047 0.0000090 0.0000137 0.000024 0.000022 2001 1 25 51934 -0.052227 0.436048 0.0801105 0.0000481 0.000130 -0.000240 0.000061 0.000047 0.0000025 0.0000137 0.000023 0.000021 2001 1 26 51935 -0.050435 0.438026 0.0799589 0.0001715 0.000101 -0.000252 0.000062 0.000048 0.0000160 0.0000137 0.000023 0.000021 2001 1 27 51936 -0.049130 0.439812 0.0796787 0.0002940 0.000094 -0.000242 0.000062 0.000048 0.0000312 0.0000137 0.000022 0.000020 2001 1 28 51937 -0.047602 0.441607 0.0792944 0.0004503 0.000086 -0.000232 0.000062 0.000048 0.0000276 0.0000137 0.000022 0.000019 2001 1 29 51938 -0.045537 0.443509 0.0788172 0.0005621 0.000079 -0.000221 0.000063 0.000048 0.0000239 0.0000138 0.000021 0.000019 2001 1 30 51939 -0.043660 0.444974 0.0782782 0.0006019 0.000072 -0.000211 0.000063 0.000048 0.0000203 0.0000138 0.000021 0.000018 2001 1 31 51940 -0.042067 0.446396 0.0777060 0.0005437 0.000254 -0.000159 0.000063 0.000049 0.0000063 0.0000138 0.000021 0.000019 2001 2 1 51941 -0.040683 0.447325 0.0772066 0.0004689 0.000298 -0.000141 0.000064 0.000049 0.0000064 0.0000138 0.000022 0.000020 2001 2 2 51942 -0.039012 0.448060 0.0767917 0.0003692 0.000290 -0.000134 0.000064 0.000049 0.0000143 0.0000138 0.000022 0.000020 2001 2 3 51943 -0.037722 0.448868 0.0764837 0.0002097 0.000283 -0.000128 0.000064 0.000049 0.0000284 0.0000138 0.000023 0.000021 2001 2 4 51944 -0.036102 0.449525 0.0763497 0.0000712 0.000275 -0.000122 0.000064 0.000049 0.0000205 0.0000138 0.000023 0.000022 2001 2 5 51945 -0.034057 0.450440 0.0763128 -0.0000019 0.000268 -0.000115 0.000064 0.000050 0.0000125 0.0000138 0.000024 0.000022 2001 2 6 51946 -0.032137 0.451811 0.0762981 0.0000362 0.000260 -0.000109 0.000065 0.000050 0.0000045 0.0000138 0.000024 0.000023 2001 2 7 51947 -0.030357 0.453129 0.0761850 0.0002129 0.000204 -0.000165 0.000065 0.000050 0.0000038 0.0000138 0.000025 0.000024 2001 2 8 51948 -0.028446 0.454738 0.0758400 0.0004643 0.000204 -0.000172 0.000065 0.000050 0.0000020 0.0000138 0.000025 0.000025 2001 2 9 51949 -0.026509 0.456415 0.0751935 0.0007377 0.000196 -0.000163 0.000066 0.000051 0.0000079 0.0000138 0.000026 0.000025 2001 2 10 51950 -0.024658 0.457716 0.0742935 0.0009626 0.000175 -0.000156 0.000066 0.000051 0.0000146 0.0000138 0.000026 0.000026 2001 2 11 51951 -0.023316 0.459250 0.0732653 0.0010798 0.000154 -0.000149 0.000066 0.000051 0.0000112 0.0000138 0.000026 0.000027 2001 2 12 51952 -0.022418 0.459847 0.0721463 0.0011272 0.000134 -0.000142 0.000067 0.000052 0.0000078 0.0000139 0.000027 0.000027 2001 2 13 51953 -0.020876 0.460700 0.0710408 0.0011205 0.000113 -0.000136 0.000067 0.000052 0.0000044 0.0000139 0.000027 0.000028 2001 2 14 51954 -0.019291 0.462062 0.0699340 0.0010235 0.000107 -0.000152 0.000067 0.000052 0.0000026 0.0000139 0.000028 0.000029 2001 2 15 51955 -0.017628 0.463391 0.0689814 0.0008698 0.000115 -0.000006 0.000067 0.000052 0.0000146 0.0000139 0.000028 0.000029 2001 2 16 51956 -0.015912 0.464796 0.0680953 0.0007308 0.000140 0.000048 0.000067 0.000052 0.0000158 0.0000139 0.000028 0.000030 2001 2 17 51957 -0.014004 0.466027 0.0673214 0.0006137 0.000168 0.000048 0.000067 0.000052 0.0000122 0.0000139 0.000028 0.000030 2001 2 18 51958 -0.012265 0.467304 0.0667419 0.0005620 0.000197 0.000048 0.000067 0.000052 0.0000119 0.0000139 0.000028 0.000030 2001 2 19 51959 -0.010537 0.468393 0.0661924 0.0005720 0.000225 0.000048 0.000067 0.000052 0.0000116 0.0000139 0.000028 0.000030 2001 2 20 51960 -0.008328 0.469468 0.0656252 0.0006097 0.000253 0.000049 0.000067 0.000052 0.0000113 0.0000139 0.000028 0.000031 2001 2 21 51961 -0.005562 0.470907 0.0649768 0.0006502 0.000331 -0.000019 0.000067 0.000052 0.0000055 0.0000140 0.000028 0.000031 2001 2 22 51962 -0.002336 0.472215 0.0642795 0.0007222 0.000303 -0.000048 0.000067 0.000052 0.0000025 0.0000140 0.000028 0.000030 2001 2 23 51963 0.001092 0.474111 0.0634255 0.0008568 0.000224 -0.000058 0.000067 0.000052 0.0000060 0.0000140 0.000028 0.000030 2001 2 24 51964 0.004163 0.475950 0.0624093 0.0010183 0.000142 -0.000067 0.000067 0.000052 0.0000103 0.0000140 0.000028 0.000030 2001 2 25 51965 0.006920 0.477590 0.0612633 0.0011940 0.000059 -0.000076 0.000067 0.000052 0.0000099 0.0000140 0.000027 0.000029 2001 2 26 51966 0.009549 0.478908 0.0599988 0.0013575 -0.000024 -0.000085 0.000067 0.000052 0.0000095 0.0000141 0.000027 0.000029 2001 2 27 51967 0.012074 0.480194 0.0586442 0.0014589 -0.000106 -0.000094 0.000067 0.000052 0.0000083 0.0000141 0.000027 0.000029 2001 2 28 51968 0.014486 0.481242 0.0572066 0.0014629 0.000017 -0.000287 0.000067 0.000052 0.0000043 0.0000141 0.000026 0.000028 2001 3 1 51969 0.016313 0.482299 0.0557514 0.0013872 0.000071 -0.000325 0.000067 0.000052 0.0000082 0.0000141 0.000026 0.000027 2001 3 2 51970 0.017274 0.482873 0.0543789 0.0012300 0.000089 -0.000300 0.000067 0.000052 0.0000130 0.0000141 0.000025 0.000026 2001 3 3 51971 0.018462 0.483317 0.0531981 0.0011068 0.000107 -0.000274 0.000067 0.000052 0.0000106 0.0000141 0.000025 0.000026 2001 3 4 51972 0.020361 0.483895 0.0521985 0.0010067 0.000125 -0.000249 0.000067 0.000052 0.0000077 0.0000141 0.000025 0.000025 2001 3 5 51973 0.022732 0.484691 0.0512766 0.0009313 0.000143 -0.000224 0.000067 0.000052 0.0000047 0.0000140 0.000024 0.000024 2001 3 6 51974 0.024518 0.485505 0.0503556 0.0009546 0.000161 -0.000199 0.000067 0.000052 0.0000018 0.0000140 0.000024 0.000024 2001 3 7 51975 0.026429 0.485567 0.0493435 0.0011111 0.000165 -0.000202 0.000067 0.000052 0.0000036 0.0000140 0.000023 0.000023 2001 3 8 51976 0.028751 0.485696 0.0481262 0.0013212 0.000141 -0.000184 0.000067 0.000052 0.0000022 0.0000140 0.000023 0.000023 2001 3 9 51977 0.031152 0.485572 0.0466616 0.0015308 0.000135 -0.000178 0.000067 0.000052 0.0000055 0.0000140 0.000022 0.000022 2001 3 10 51978 0.033442 0.485468 0.0450405 0.0016346 0.000140 -0.000180 0.000067 0.000052 0.0000106 0.0000140 0.000022 0.000022 2001 3 11 51979 0.035591 0.485590 0.0434167 0.0016440 0.000144 -0.000181 0.000067 0.000052 0.0000137 0.0000139 0.000021 0.000021 2001 3 12 51980 0.038016 0.485669 0.0418513 0.0015407 0.000148 -0.000183 0.000068 0.000052 0.0000167 0.0000139 0.000021 0.000021 2001 3 13 51981 0.040989 0.485835 0.0404484 0.0013402 0.000152 -0.000185 0.000068 0.000052 0.0000198 0.0000139 0.000021 0.000020 2001 3 14 51982 0.043953 0.486209 0.0392272 0.0010951 0.000115 -0.000198 0.000068 0.000052 0.0000069 0.0000139 0.000021 0.000021 2001 3 15 51983 0.046520 0.486623 0.0382778 0.0008241 0.000122 -0.000199 0.000067 0.000052 0.0000072 0.0000139 0.000021 0.000021 2001 3 16 51984 0.048698 0.486701 0.0375436 0.0006329 0.000143 -0.000195 0.000067 0.000051 0.0000107 0.0000139 0.000022 0.000022 2001 3 17 51985 0.051018 0.487265 0.0369341 0.0005311 0.000165 -0.000191 0.000067 0.000051 0.0000083 0.0000139 0.000022 0.000022 2001 3 18 51986 0.053561 0.487517 0.0364797 0.0004552 0.000186 -0.000188 0.000067 0.000051 0.0000065 0.0000139 0.000022 0.000023 2001 3 19 51987 0.056342 0.487938 0.0360732 0.0004219 0.000207 -0.000184 0.000067 0.000051 0.0000047 0.0000139 0.000023 0.000023 2001 3 20 51988 0.059115 0.488661 0.0356550 0.0004634 0.000229 -0.000180 0.000067 0.000051 0.0000028 0.0000139 0.000023 0.000024 2001 3 21 51989 0.061695 0.489127 0.0351676 0.0005477 0.000153 -0.000249 0.000067 0.000051 0.0000061 0.0000139 0.000023 0.000024 2001 3 22 51990 0.064563 0.489220 0.0345794 0.0006486 0.000152 -0.000228 0.000067 0.000051 0.0000027 0.0000139 0.000023 0.000024 2001 3 23 51991 0.067364 0.489627 0.0338688 0.0007453 0.000142 -0.000221 0.000067 0.000051 0.0000053 0.0000139 0.000024 0.000025 2001 3 24 51992 0.070242 0.490171 0.0330302 0.0008415 0.000117 -0.000230 0.000067 0.000051 0.0000094 0.0000140 0.000024 0.000025 2001 3 25 51993 0.073398 0.490661 0.0320927 0.0009652 0.000093 -0.000239 0.000067 0.000051 0.0000070 0.0000140 0.000024 0.000025 2001 3 26 51994 0.076419 0.491045 0.0310736 0.0010799 0.000068 -0.000248 0.000067 0.000051 0.0000046 0.0000140 0.000024 0.000025 2001 3 27 51995 0.079267 0.491300 0.0300256 0.0010991 0.000044 -0.000257 0.000068 0.000051 0.0000023 0.0000140 0.000024 0.000025 2001 3 28 51996 0.081786 0.491316 0.0289568 0.0010319 0.000011 -0.000258 0.000068 0.000051 0.0000018 0.0000140 0.000024 0.000026 2001 3 29 51997 0.084074 0.491268 0.0279496 0.0009348 -0.000025 -0.000293 0.000068 0.000051 0.0000023 0.0000141 0.000024 0.000025 2001 3 30 51998 0.086376 0.491079 0.0270347 0.0008223 -0.000007 -0.000286 0.000068 0.000051 0.0000036 0.0000141 0.000024 0.000025 2001 3 31 51999 0.088668 0.490486 0.0262391 0.0007121 0.000030 -0.000260 0.000067 0.000051 0.0000049 0.0000141 0.000024 0.000025 2001 4 1 52000 0.090643 0.489891 0.0255761 0.0006439 0.000068 -0.000234 0.000067 0.000051 0.0000050 0.0000141 0.000024 0.000024 2001 4 2 52001 0.092716 0.489314 0.0249260 0.0006537 0.000106 -0.000208 0.000067 0.000051 0.0000052 0.0000141 0.000024 0.000024 2001 4 3 52002 0.094782 0.489040 0.0242036 0.0007426 0.000143 -0.000182 0.000067 0.000051 0.0000053 0.0000141 0.000024 0.000024 2001 4 4 52003 0.096877 0.488440 0.0233533 0.0009221 0.000014 -0.000222 0.000067 0.000050 0.0000039 0.0000141 0.000023 0.000023 2001 4 5 52004 0.099092 0.487414 0.0222944 0.0011577 0.000073 -0.000303 0.000066 0.000050 0.0000021 0.0000141 0.000023 0.000022 2001 4 6 52005 0.101546 0.486738 0.0210198 0.0013476 0.000089 -0.000313 0.000066 0.000050 0.0000026 0.0000141 0.000023 0.000022 2001 4 7 52006 0.104351 0.486582 0.0195985 0.0014801 0.000064 -0.000292 0.000066 0.000050 0.0000048 0.0000141 0.000022 0.000021 2001 4 8 52007 0.106806 0.486510 0.0181174 0.0014633 0.000040 -0.000271 0.000066 0.000050 0.0000096 0.0000141 0.000022 0.000020 2001 4 9 52008 0.108467 0.485965 0.0167263 0.0012896 0.000016 -0.000250 0.000065 0.000050 0.0000144 0.0000141 0.000021 0.000020 2001 4 10 52009 0.110425 0.484927 0.0155150 0.0010594 -0.000009 -0.000229 0.000065 0.000049 0.0000192 0.0000141 0.000021 0.000019 2001 4 11 52010 0.112921 0.484015 0.0145601 0.0008278 -0.000013 -0.000211 0.000065 0.000049 0.0000063 0.0000141 0.000021 0.000019 2001 4 12 52011 0.115958 0.483287 0.0137844 0.0006176 -0.000010 -0.000219 0.000064 0.000049 0.0000092 0.0000140 0.000022 0.000020 2001 4 13 52012 0.118655 0.483028 0.0131962 0.0004378 -0.000007 -0.000236 0.000064 0.000049 0.0000162 0.0000140 0.000022 0.000020 2001 4 14 52013 0.120964 0.482256 0.0128260 0.0003066 -0.000003 -0.000253 0.000064 0.000049 0.0000144 0.0000140 0.000022 0.000021 2001 4 15 52014 0.123701 0.481258 0.0125209 0.0003015 0.000000 -0.000270 0.000063 0.000048 0.0000162 0.0000140 0.000023 0.000021 2001 4 16 52015 0.126518 0.480432 0.0122048 0.0003855 0.000004 -0.000287 0.000063 0.000048 0.0000179 0.0000140 0.000023 0.000022 2001 4 17 52016 0.129622 0.479429 0.0118246 0.0005392 0.000007 -0.000304 0.000063 0.000048 0.0000196 0.0000140 0.000024 0.000022 2001 4 18 52017 0.132967 0.478701 0.0112259 0.0007127 0.000094 -0.000291 0.000063 0.000048 0.0000083 0.0000140 0.000024 0.000023 2001 4 19 52018 0.136337 0.478258 0.0104341 0.0008642 0.000041 -0.000213 0.000063 0.000048 0.0000023 0.0000140 0.000024 0.000023 2001 4 20 52019 0.139524 0.477840 0.0095192 0.0009634 0.000006 -0.000189 0.000063 0.000048 0.0000076 0.0000140 0.000024 0.000024 2001 4 21 52020 0.142401 0.477092 0.0085287 0.0010229 -0.000003 -0.000192 0.000063 0.000048 0.0000138 0.0000140 0.000025 0.000024 2001 4 22 52021 0.145000 0.476196 0.0075804 0.0010295 -0.000012 -0.000194 0.000063 0.000048 0.0000114 0.0000140 0.000025 0.000024 2001 4 23 52022 0.147438 0.475509 0.0066034 0.0009460 -0.000020 -0.000197 0.000063 0.000048 0.0000089 0.0000140 0.000025 0.000024 2001 4 24 52023 0.149332 0.474887 0.0056637 0.0008621 -0.000029 -0.000199 0.000063 0.000048 0.0000065 0.0000140 0.000025 0.000025 2001 4 25 52024 0.151074 0.473888 0.0048380 0.0008193 -0.000038 -0.000202 0.000063 0.000048 0.0000039 0.0000140 0.000026 0.000025 2001 4 26 52025 0.153489 0.472430 0.0040050 0.0007343 -0.000036 -0.000205 0.000063 0.000048 0.0000098 0.0000140 0.000026 0.000025 2001 4 27 52026 0.155870 0.471260 0.0032824 0.0006114 -0.000031 -0.000209 0.000063 0.000048 0.0000161 0.0000140 0.000026 0.000025 2001 4 28 52027 0.157884 0.469680 0.0027536 0.0005374 -0.000026 -0.000213 0.000063 0.000048 0.0000131 0.0000140 0.000026 0.000026 2001 4 29 52028 0.159634 0.468247 0.0021541 0.0005810 -0.000021 -0.000217 0.000063 0.000048 0.0000117 0.0000140 0.000026 0.000026 2001 4 30 52029 0.161412 0.466474 0.0014797 0.0007481 -0.000017 -0.000221 0.000062 0.000048 0.0000103 0.0000140 0.000026 0.000026 2001 5 1 52030 0.163343 0.464502 0.0006556 0.0009428 -0.000012 -0.000224 0.000062 0.000048 0.0000085 0.0000140 0.000026 0.000026 2001 5 2 52031 0.165079 0.462656 -0.0003386 0.0011279 -0.000007 -0.000228 0.000062 0.000048 0.0000045 0.0000140 0.000026 0.000026 2001 5 3 52032 0.167137 0.461377 -0.0015833 0.0013321 0.000052 -0.000260 0.000062 0.000047 0.0000024 0.0000140 0.000027 0.000026 2001 5 4 52033 0.169543 0.460381 -0.0030615 0.0014941 0.000033 -0.000264 0.000061 0.000047 0.0000073 0.0000140 0.000026 0.000026 2001 5 5 52034 0.171788 0.458755 -0.0046360 0.0015668 -0.000021 -0.000255 0.000061 0.000047 0.0000127 0.0000140 0.000026 0.000025 2001 5 6 52035 0.173647 0.456783 -0.0061349 0.0014709 -0.000074 -0.000245 0.000061 0.000047 0.0000113 0.0000140 0.000026 0.000025 2001 5 7 52036 0.175636 0.454616 -0.0075221 0.0012751 -0.000128 -0.000236 0.000060 0.000046 0.0000098 0.0000141 0.000026 0.000025 2001 5 8 52037 0.178388 0.452385 -0.0087289 0.0010764 -0.000181 -0.000227 0.000060 0.000046 0.0000083 0.0000141 0.000026 0.000025 2001 5 9 52038 0.181220 0.450210 -0.0097355 0.0008740 -0.000169 -0.000367 0.000060 0.000046 0.0000033 0.0000141 0.000026 0.000024 2001 5 10 52039 0.183898 0.447997 -0.0105336 0.0006946 -0.000137 -0.000341 0.000059 0.000046 0.0000152 0.0000142 0.000026 0.000024 2001 5 11 52040 0.186538 0.445818 -0.0112285 0.0005894 -0.000119 -0.000319 0.000059 0.000045 0.0000152 0.0000142 0.000026 0.000024 2001 5 12 52041 0.189232 0.444156 -0.0118507 0.0005655 -0.000106 -0.000324 0.000059 0.000045 0.0000095 0.0000142 0.000027 0.000025 2001 5 13 52042 0.191478 0.442735 -0.0124139 0.0005934 -0.000093 -0.000329 0.000058 0.000045 0.0000070 0.0000143 0.000027 0.000025 2001 5 14 52043 0.193353 0.440993 -0.0130188 0.0006813 -0.000080 -0.000334 0.000058 0.000044 0.0000045 0.0000143 0.000028 0.000026 2001 5 15 52044 0.194973 0.438827 -0.0137076 0.0008134 -0.000067 -0.000339 0.000058 0.000044 0.0000020 0.0000144 0.000028 0.000027 2001 5 16 52045 0.196751 0.436472 -0.0145694 0.0009366 -0.000054 -0.000354 0.000058 0.000044 0.0000028 0.0000145 0.000029 0.000028 2001 5 17 52046 0.198595 0.433810 -0.0155377 0.0010417 -0.000108 -0.000331 0.000058 0.000044 0.0000023 0.0000146 0.000029 0.000028 2001 5 18 52047 0.200834 0.430859 -0.0166379 0.0011353 -0.000164 -0.000223 0.000057 0.000044 0.0000031 0.0000147 0.000030 0.000029 2001 5 19 52048 0.203269 0.428087 -0.0178008 0.0011737 -0.000213 -0.000089 0.000057 0.000044 0.0000043 0.0000148 0.000030 0.000030 2001 5 20 52049 0.205242 0.425349 -0.0189066 0.0011433 -0.000239 -0.000104 0.000057 0.000044 0.0000038 0.0000149 0.000030 0.000030 2001 5 21 52050 0.206960 0.422645 -0.0199655 0.0010455 -0.000263 -0.000133 0.000057 0.000044 0.0000033 0.0000151 0.000031 0.000030 2001 5 22 52051 0.208906 0.420355 -0.0209074 0.0008991 -0.000286 -0.000161 0.000058 0.000044 0.0000029 0.0000152 0.000031 0.000031 2001 5 23 52052 0.210576 0.418261 -0.0216841 0.0006721 -0.000149 -0.000213 0.000058 0.000044 0.0000024 0.0000154 0.000031 0.000031 2001 5 24 52053 0.211964 0.415725 -0.0222413 0.0004722 -0.000049 -0.000166 0.000058 0.000044 0.0000030 0.0000156 0.000032 0.000032 2001 5 25 52054 0.213367 0.413349 -0.0226002 0.0002974 0.000022 -0.000085 0.000058 0.000044 0.0000039 0.0000158 0.000032 0.000032 2001 5 26 52055 0.214680 0.410594 -0.0228463 0.0001909 0.000009 -0.000094 0.000058 0.000044 0.0000039 0.0000161 0.000032 0.000032 2001 5 27 52056 0.215948 0.407537 -0.0230493 0.0001867 -0.000011 -0.000111 0.000058 0.000044 0.0000037 0.0000163 0.000032 0.000032 2001 5 28 52057 0.217314 0.404589 -0.0232974 0.0002925 -0.000032 -0.000127 0.000058 0.000044 0.0000036 0.0000166 0.000032 0.000032 2001 5 29 52058 0.219027 0.401915 -0.0236558 0.0004418 -0.000052 -0.000144 0.000058 0.000044 0.0000034 0.0000168 0.000033 0.000033 2001 5 30 52059 0.221009 0.399359 -0.0241466 0.0005722 -0.000072 -0.000160 0.000059 0.000045 0.0000033 0.0000171 0.000033 0.000033 2001 5 31 52060 0.222944 0.396800 -0.0247529 0.0006460 -0.000129 -0.000264 0.000059 0.000045 0.0000016 0.0000173 0.000033 0.000033 2001 6 1 52061 0.224506 0.394237 -0.0254092 0.0006424 -0.000151 -0.000284 0.000059 0.000045 0.0000013 0.0000176 0.000033 0.000034 2001 6 2 52062 0.225875 0.391518 -0.0260259 0.0005982 -0.000156 -0.000263 0.000059 0.000045 0.0000016 0.0000178 0.000034 0.000034 2001 6 3 52063 0.227305 0.388622 -0.0265173 0.0004093 -0.000162 -0.000242 0.000059 0.000045 0.0000020 0.0000180 0.000034 0.000035 2001 6 4 52064 0.228720 0.385679 -0.0268205 0.0001878 -0.000167 -0.000221 0.000058 0.000045 0.0000023 0.0000183 0.000034 0.000035 2001 6 5 52065 0.230509 0.382729 -0.0269069 -0.0000147 -0.000172 -0.000200 0.000058 0.000045 0.0000026 0.0000185 0.000035 0.000036 2001 6 6 52066 0.232448 0.380067 -0.0267549 -0.0002469 -0.000085 -0.000269 0.000058 0.000045 0.0000028 0.0000187 0.000035 0.000037 2001 6 7 52067 0.234496 0.377402 -0.0264542 -0.0004341 0.000019 -0.000246 0.000058 0.000045 0.0000059 0.0000189 0.000035 0.000037 2001 6 8 52068 0.236517 0.374857 -0.0260357 -0.0005337 0.000033 -0.000211 0.000059 0.000045 0.0000092 0.0000191 0.000035 0.000038 2001 6 9 52069 0.238041 0.372667 -0.0255254 -0.0005130 0.000003 -0.000188 0.000059 0.000045 0.0000098 0.0000193 0.000036 0.000038 2001 6 10 52070 0.239209 0.370282 -0.0251071 -0.0003962 -0.000028 -0.000164 0.000059 0.000045 0.0000088 0.0000195 0.000036 0.000038 2001 6 11 52071 0.240213 0.367616 -0.0247676 -0.0002330 -0.000058 -0.000140 0.000059 0.000045 0.0000079 0.0000196 0.000036 0.000038 2001 6 12 52072 0.241027 0.364819 -0.0245434 -0.0001051 -0.000089 -0.000116 0.000059 0.000045 0.0000069 0.0000198 0.000036 0.000038 2001 6 13 52073 0.241976 0.361794 -0.0244976 0.0000175 -0.000159 -0.000255 0.000059 0.000045 0.0000071 0.0000200 0.000036 0.000038 2001 6 14 52074 0.243189 0.358621 -0.0245786 0.0000954 -0.000177 -0.000288 0.000059 0.000045 0.0000032 0.0000202 0.000036 0.000038 2001 6 15 52075 0.244846 0.355434 -0.0247405 0.0001491 -0.000249 -0.000235 0.000059 0.000045 0.0000044 0.0000203 0.000036 0.000038 2001 6 16 52076 0.246391 0.352484 -0.0249562 0.0001780 -0.000348 -0.000170 0.000059 0.000045 0.0000071 0.0000205 0.000035 0.000038 2001 6 17 52077 0.247403 0.349751 -0.0251554 0.0001987 -0.000446 -0.000104 0.000059 0.000045 0.0000070 0.0000207 0.000035 0.000037 2001 6 18 52078 0.248324 0.346743 -0.0253282 0.0001665 -0.000545 -0.000039 0.000059 0.000045 0.0000069 0.0000208 0.000035 0.000037 2001 6 19 52079 0.248674 0.343768 -0.0254269 0.0000738 -0.000642 0.000026 0.000059 0.000045 0.0000064 0.0000210 0.000035 0.000037 2001 6 20 52080 0.248367 0.340897 -0.0254356 -0.0000594 -0.000201 0.000041 0.000059 0.000045 0.0000046 0.0000211 0.000035 0.000036 2001 6 21 52081 0.248326 0.337899 -0.0253233 -0.0001442 0.000050 0.000032 0.000060 0.000045 0.0000031 0.0000212 0.000035 0.000036 2001 6 22 52082 0.248492 0.335095 -0.0251946 -0.0001595 0.000069 0.000016 0.000060 0.000045 0.0000064 0.0000214 0.000034 0.000035 2001 6 23 52083 0.248675 0.332056 -0.0250584 -0.0001732 0.000028 -0.000001 0.000060 0.000045 0.0000100 0.0000215 0.000034 0.000034 2001 6 24 52084 0.248947 0.328995 -0.0249025 -0.0001002 -0.000014 -0.000018 0.000060 0.000045 0.0000075 0.0000216 0.000034 0.000034 2001 6 25 52085 0.249502 0.325952 -0.0249237 0.0000806 -0.000055 -0.000034 0.000060 0.000045 0.0000050 0.0000217 0.000033 0.000033 2001 6 26 52086 0.250523 0.322776 -0.0251515 0.0003239 -0.000097 -0.000051 0.000060 0.000045 0.0000025 0.0000218 0.000033 0.000032 2001 6 27 52087 0.251375 0.319902 -0.0256171 0.0005492 -0.000114 -0.000094 0.000060 0.000045 0.0000030 0.0000219 0.000033 0.000032 2001 6 28 52088 0.252063 0.317128 -0.0262284 0.0006141 0.000001 0.000035 0.000060 0.000045 0.0000026 0.0000220 0.000032 0.000031 2001 6 29 52089 0.252398 0.314177 -0.0268603 0.0005552 0.000029 0.000058 0.000060 0.000045 0.0000069 0.0000221 0.000032 0.000030 2001 6 30 52090 0.253036 0.310888 -0.0273937 0.0004282 0.000010 0.000021 0.000060 0.000045 0.0000114 0.0000221 0.000032 0.000030 2001 7 1 52091 0.253874 0.307810 -0.0277017 0.0002178 -0.000010 -0.000016 0.000060 0.000045 0.0000092 0.0000222 0.000031 0.000029 2001 7 2 52092 0.254062 0.304573 -0.0278304 0.0000367 -0.000029 -0.000053 0.000059 0.000045 0.0000071 0.0000223 0.000031 0.000028 2001 7 3 52093 0.253784 0.301280 -0.0277788 -0.0001133 -0.000048 -0.000090 0.000059 0.000045 0.0000049 0.0000224 0.000030 0.000027 2001 7 4 52094 0.254220 0.298265 -0.0275879 -0.0002499 -0.000165 -0.000120 0.000059 0.000045 0.0000058 0.0000225 0.000030 0.000027 2001 7 5 52095 0.254380 0.295688 -0.0273204 -0.0003083 -0.000190 -0.000165 0.000059 0.000045 0.0000118 0.0000226 0.000029 0.000026 2001 7 6 52096 0.253881 0.292961 -0.0270090 -0.0003080 -0.000169 -0.000216 0.000059 0.000045 0.0000194 0.0000227 0.000029 0.000025 2001 7 7 52097 0.253621 0.290226 -0.0267222 -0.0002795 -0.000152 -0.000229 0.000059 0.000045 0.0000160 0.0000228 0.000029 0.000025 2001 7 8 52098 0.252721 0.287569 -0.0264862 -0.0001978 -0.000136 -0.000238 0.000059 0.000045 0.0000116 0.0000229 0.000030 0.000026 2001 7 9 52099 0.251604 0.284336 -0.0263334 -0.0000922 -0.000119 -0.000247 0.000059 0.000045 0.0000072 0.0000230 0.000030 0.000027 2001 7 10 52100 0.251676 0.280890 -0.0262809 -0.0000221 -0.000102 -0.000256 0.000059 0.000045 0.0000028 0.0000231 0.000031 0.000028 2001 7 11 52101 0.251979 0.277734 -0.0262944 0.0000274 -0.000194 -0.000136 0.000059 0.000045 0.0000035 0.0000232 0.000031 0.000029 2001 7 12 52102 0.251517 0.274891 -0.0263410 0.0000610 -0.000295 -0.000163 0.000059 0.000045 0.0000025 0.0000233 0.000032 0.000029 2001 7 13 52103 0.250912 0.271844 -0.0264959 0.0001401 -0.000281 -0.000161 0.000059 0.000045 0.0000081 0.0000234 0.000032 0.000030 2001 7 14 52104 0.250408 0.269055 -0.0266714 0.0001355 -0.000227 -0.000126 0.000059 0.000045 0.0000145 0.0000235 0.000033 0.000031 2001 7 15 52105 0.249418 0.265886 -0.0267583 0.0000918 -0.000174 -0.000090 0.000059 0.000045 0.0000135 0.0000236 0.000033 0.000032 2001 7 16 52106 0.248423 0.262536 -0.0267545 -0.0000078 -0.000120 -0.000055 0.000059 0.000045 0.0000126 0.0000237 0.000034 0.000032 2001 7 17 52107 0.247910 0.259210 -0.0266146 -0.0001400 -0.000067 -0.000019 0.000059 0.000045 0.0000116 0.0000238 0.000034 0.000033 2001 7 18 52108 0.247977 0.256049 -0.0263774 -0.0002879 -0.000132 -0.000034 0.000059 0.000045 0.0000054 0.0000238 0.000035 0.000034 2001 7 19 52109 0.247914 0.252919 -0.0259906 -0.0004329 -0.000270 -0.000005 0.000059 0.000045 0.0000022 0.0000239 0.000035 0.000034 2001 7 20 52110 0.247667 0.249822 -0.0254891 -0.0005121 -0.000275 0.000026 0.000059 0.000045 0.0000041 0.0000240 0.000036 0.000035 2001 7 21 52111 0.247147 0.246726 -0.0249984 -0.0004896 -0.000228 0.000051 0.000059 0.000045 0.0000072 0.0000240 0.000036 0.000036 2001 7 22 52112 0.246325 0.243670 -0.0246112 -0.0003016 -0.000180 0.000077 0.000060 0.000045 0.0000096 0.0000241 0.000037 0.000036 2001 7 23 52113 0.245260 0.240773 -0.0244196 -0.0000971 -0.000133 0.000102 0.000060 0.000045 0.0000120 0.0000241 0.000037 0.000037 2001 7 24 52114 0.244240 0.238097 -0.0244210 0.0001204 -0.000086 0.000127 0.000060 0.000045 0.0000144 0.0000242 0.000038 0.000038 2001 7 25 52115 0.243601 0.235525 -0.0246198 0.0002335 -0.000146 -0.000041 0.000060 0.000046 0.0000063 0.0000242 0.000038 0.000038 2001 7 26 52116 0.243047 0.232861 -0.0248517 0.0002035 -0.000262 -0.000095 0.000061 0.000046 0.0000031 0.0000243 0.000038 0.000039 2001 7 27 52117 0.242083 0.230046 -0.0250653 0.0001129 -0.000262 -0.000081 0.000061 0.000046 0.0000063 0.0000243 0.000039 0.000039 2001 7 28 52118 0.240732 0.227022 -0.0251269 -0.0000450 -0.000214 -0.000057 0.000061 0.000046 0.0000105 0.0000243 0.000039 0.000039 2001 7 29 52119 0.239023 0.223938 -0.0249267 -0.0002545 -0.000166 -0.000034 0.000061 0.000047 0.0000126 0.0000244 0.000039 0.000039 2001 7 30 52120 0.237221 0.220905 -0.0245425 -0.0004863 -0.000118 -0.000011 0.000062 0.000047 0.0000147 0.0000244 0.000039 0.000039 2001 7 31 52121 0.235788 0.218036 -0.0239978 -0.0006399 -0.000070 0.000012 0.000062 0.000047 0.0000144 0.0000244 0.000039 0.000039 2001 8 1 52122 0.234811 0.215812 -0.0233139 -0.0006971 -0.000023 0.000036 0.000062 0.000047 0.0000053 0.0000244 0.000039 0.000039 2001 8 2 52123 0.233408 0.213706 -0.0225911 -0.0007064 -0.000203 -0.000041 0.000062 0.000047 0.0000022 0.0000245 0.000039 0.000039 2001 8 3 52124 0.231042 0.211638 -0.0219754 -0.0006448 -0.000246 -0.000033 0.000062 0.000048 0.0000084 0.0000245 0.000039 0.000040 2001 8 4 52125 0.228146 0.208922 -0.0214580 -0.0005130 -0.000212 0.000017 0.000063 0.000048 0.0000147 0.0000245 0.000040 0.000040 2001 8 5 52126 0.225844 0.205942 -0.0210070 -0.0003258 -0.000178 0.000067 0.000063 0.000048 0.0000114 0.0000245 0.000040 0.000040 2001 8 6 52127 0.223850 0.203319 -0.0207191 -0.0002166 -0.000143 0.000117 0.000063 0.000048 0.0000082 0.0000245 0.000040 0.000040 2001 8 7 52128 0.221856 0.200922 -0.0206032 -0.0000633 -0.000109 0.000167 0.000063 0.000049 0.0000049 0.0000245 0.000040 0.000041 2001 8 8 52129 0.219727 0.198738 -0.0206436 0.0000937 -0.000223 0.000092 0.000063 0.000049 0.0000036 0.0000246 0.000041 0.000041 2001 8 9 52130 0.217154 0.196708 -0.0208243 0.0002060 -0.000228 -0.000042 0.000064 0.000049 0.0000029 0.0000246 0.000041 0.000041 2001 8 10 52131 0.214324 0.194253 -0.0211344 0.0003060 -0.000202 -0.000048 0.000064 0.000049 0.0000045 0.0000246 0.000041 0.000041 2001 8 11 52132 0.211250 0.191715 -0.0214981 0.0003764 -0.000181 -0.000003 0.000064 0.000049 0.0000062 0.0000246 0.000041 0.000041 2001 8 12 52133 0.208368 0.188951 -0.0218523 0.0003560 -0.000159 0.000043 0.000064 0.000049 0.0000056 0.0000246 0.000041 0.000041 2001 8 13 52134 0.206012 0.186355 -0.0221523 0.0002644 -0.000137 0.000088 0.000064 0.000050 0.0000050 0.0000245 0.000041 0.000041 2001 8 14 52135 0.203716 0.183869 -0.0223667 0.0001582 -0.000116 0.000133 0.000064 0.000050 0.0000045 0.0000245 0.000041 0.000041 2001 8 15 52136 0.201260 0.181383 -0.0224659 0.0000471 -0.000071 0.000042 0.000065 0.000050 0.0000034 0.0000245 0.000041 0.000040 2001 8 16 52137 0.198498 0.179249 -0.0224873 0.0000053 -0.000063 0.000033 0.000065 0.000050 0.0000025 0.0000245 0.000041 0.000040 2001 8 17 52138 0.196016 0.177035 -0.0225710 0.0000915 -0.000092 0.000078 0.000065 0.000050 0.0000059 0.0000245 0.000041 0.000040 2001 8 18 52139 0.193439 0.174825 -0.0227923 0.0002784 -0.000129 0.000127 0.000065 0.000051 0.0000094 0.0000245 0.000041 0.000039 2001 8 19 52140 0.190971 0.172488 -0.0231907 0.0005205 -0.000166 0.000177 0.000065 0.000051 0.0000069 0.0000245 0.000041 0.000039 2001 8 20 52141 0.188837 0.170525 -0.0238328 0.0007613 -0.000203 0.000226 0.000066 0.000051 0.0000044 0.0000245 0.000041 0.000039 2001 8 21 52142 0.186538 0.168365 -0.0246698 0.0009167 -0.000240 0.000275 0.000066 0.000051 0.0000019 0.0000245 0.000041 0.000038 2001 8 22 52143 0.183992 0.166047 -0.0256365 0.0009585 -0.000294 0.000190 0.000066 0.000051 0.0000039 0.0000245 0.000041 0.000039 2001 8 23 52144 0.181165 0.164135 -0.0265674 0.0008570 -0.000237 -0.000030 0.000066 0.000052 0.0000027 0.0000245 0.000041 0.000039 2001 8 24 52145 0.178630 0.162319 -0.0273455 0.0006739 -0.000203 -0.000071 0.000067 0.000052 0.0000042 0.0000245 0.000041 0.000039 2001 8 25 52146 0.176420 0.160433 -0.0278912 0.0004373 -0.000192 -0.000035 0.000067 0.000052 0.0000064 0.0000246 0.000041 0.000039 2001 8 26 52147 0.174467 0.158273 -0.0281660 0.0001968 -0.000181 0.000000 0.000067 0.000052 0.0000065 0.0000246 0.000041 0.000040 2001 8 27 52148 0.172442 0.156154 -0.0282364 -0.0000321 -0.000170 0.000035 0.000067 0.000052 0.0000065 0.0000246 0.000041 0.000040 2001 8 28 52149 0.170564 0.154149 -0.0281606 -0.0001433 -0.000158 0.000071 0.000067 0.000052 0.0000066 0.0000246 0.000041 0.000041 2001 8 29 52150 0.168399 0.152565 -0.0279840 -0.0002031 -0.000166 0.000088 0.000067 0.000052 0.0000034 0.0000247 0.000041 0.000041 2001 8 30 52151 0.166078 0.151088 -0.0277682 -0.0002250 -0.000065 0.000059 0.000068 0.000052 0.0000025 0.0000247 0.000041 0.000041 2001 8 31 52152 0.163367 0.150184 -0.0276676 -0.0001175 0.000050 0.000076 0.000068 0.000052 0.0000130 0.0000247 0.000040 0.000041 2001 9 1 52153 0.160267 0.149322 -0.0276735 -0.0000001 0.000156 0.000115 0.000068 0.000052 0.0000232 0.0000248 0.000040 0.000041 2001 9 2 52154 0.157128 0.148056 -0.0277535 0.0001215 0.000262 0.000154 0.000068 0.000052 0.0000187 0.0000248 0.000040 0.000042 2001 9 3 52155 0.153938 0.146473 -0.0279627 0.0002928 0.000368 0.000192 0.000067 0.000052 0.0000142 0.0000248 0.000040 0.000042 2001 9 4 52156 0.150885 0.144997 -0.0282892 0.0004155 0.000473 0.000231 0.000067 0.000052 0.0000097 0.0000248 0.000040 0.000042 2001 9 5 52157 0.147630 0.143013 -0.0287013 0.0005003 -0.000042 0.000125 0.000067 0.000052 0.0000052 0.0000248 0.000040 0.000042 2001 9 6 52158 0.144428 0.140847 -0.0292214 0.0005341 -0.000155 0.000218 0.000067 0.000052 0.0000029 0.0000248 0.000040 0.000041 2001 9 7 52159 0.141802 0.139324 -0.0297413 0.0004633 -0.000151 0.000236 0.000067 0.000052 0.0000060 0.0000248 0.000039 0.000041 2001 9 8 52160 0.139450 0.137944 -0.0301747 0.0003333 -0.000152 0.000202 0.000067 0.000051 0.0000093 0.0000248 0.000039 0.000041 2001 9 9 52161 0.137251 0.136953 -0.0304317 0.0002037 -0.000154 0.000167 0.000067 0.000051 0.0000070 0.0000247 0.000039 0.000040 2001 9 10 52162 0.134864 0.135817 -0.0305606 0.0000832 -0.000155 0.000133 0.000067 0.000051 0.0000048 0.0000247 0.000038 0.000040 2001 9 11 52163 0.132093 0.134614 -0.0305633 -0.0000071 -0.000157 0.000098 0.000066 0.000051 0.0000025 0.0000246 0.000038 0.000040 2001 9 12 52164 0.128825 0.133420 -0.0304898 -0.0001003 -0.000034 -0.000083 0.000066 0.000050 0.0000028 0.0000246 0.000038 0.000039 2001 9 13 52165 0.125793 0.132301 -0.0303884 -0.0000604 -0.000086 -0.000025 0.000066 0.000050 0.0000026 0.0000246 0.000037 0.000039 2001 9 14 52166 0.122506 0.131183 -0.0303941 0.0000502 -0.000128 0.000005 0.000066 0.000050 0.0000050 0.0000246 0.000037 0.000039 2001 9 15 52167 0.118894 0.130049 -0.0306045 0.0003165 -0.000140 -0.000007 0.000066 0.000050 0.0000078 0.0000246 0.000037 0.000038 2001 9 16 52168 0.115057 0.129252 -0.0310867 0.0006035 -0.000153 -0.000019 0.000065 0.000049 0.0000081 0.0000245 0.000037 0.000038 2001 9 17 52169 0.111659 0.128302 -0.0318335 0.0009022 -0.000165 -0.000032 0.000065 0.000049 0.0000084 0.0000245 0.000036 0.000037 2001 9 18 52170 0.108287 0.127584 -0.0327573 0.0009751 -0.000178 -0.000044 0.000065 0.000049 0.0000079 0.0000245 0.000036 0.000037 2001 9 19 52171 0.104669 0.126693 -0.0336927 0.0009396 -0.000190 -0.000056 0.000065 0.000049 0.0000043 0.0000245 0.000036 0.000036 2001 9 20 52172 0.101253 0.126131 -0.0345777 0.0008287 -0.000082 0.000269 0.000065 0.000049 0.0000157 0.0000245 0.000035 0.000036 2001 9 21 52173 0.097825 0.125594 -0.0353388 0.0006440 -0.000064 0.000341 0.000065 0.000049 0.0000143 0.0000244 0.000035 0.000036 2001 9 22 52174 0.094443 0.125083 -0.0358926 0.0004590 -0.000092 0.000281 0.000065 0.000049 0.0000079 0.0000244 0.000035 0.000036 2001 9 23 52175 0.091408 0.124460 -0.0362243 0.0002791 -0.000120 0.000220 0.000065 0.000049 0.0000062 0.0000244 0.000035 0.000036 2001 9 24 52176 0.088580 0.123455 -0.0364020 0.0001296 -0.000149 0.000160 0.000065 0.000049 0.0000044 0.0000244 0.000035 0.000036 2001 9 25 52177 0.085561 0.122211 -0.0364957 0.0000640 -0.000177 0.000099 0.000065 0.000049 0.0000027 0.0000244 0.000035 0.000036 2001 9 26 52178 0.082376 0.121069 -0.0365656 0.0000688 -0.000086 -0.000190 0.000065 0.000049 0.0000023 0.0000244 0.000035 0.000036 2001 9 27 52179 0.078988 0.120026 -0.0366581 0.0001267 0.000030 0.000032 0.000065 0.000049 0.0000020 0.0000244 0.000035 0.000036 2001 9 28 52180 0.075369 0.119164 -0.0368586 0.0002353 0.000038 0.000122 0.000065 0.000049 0.0000068 0.0000244 0.000035 0.000036 2001 9 29 52181 0.071758 0.118710 -0.0371945 0.0003827 0.000005 0.000098 0.000065 0.000049 0.0000116 0.0000244 0.000035 0.000036 2001 9 30 52182 0.068681 0.118297 -0.0376643 0.0005349 -0.000029 0.000074 0.000065 0.000049 0.0000089 0.0000244 0.000035 0.000036 2001 10 1 52183 0.065487 0.117977 -0.0382807 0.0006332 -0.000062 0.000051 0.000065 0.000049 0.0000063 0.0000244 0.000035 0.000037 2001 10 2 52184 0.061719 0.117811 -0.0390216 0.0007952 -0.000096 0.000027 0.000065 0.000049 0.0000036 0.0000245 0.000035 0.000037 2001 10 3 52185 0.057809 0.117662 -0.0398822 0.0008544 -0.000029 -0.000042 0.000065 0.000049 0.0000031 0.0000245 0.000035 0.000037 2001 10 4 52186 0.054796 0.117488 -0.0407630 0.0008897 -0.000009 0.000047 0.000065 0.000049 0.0000020 0.0000245 0.000035 0.000037 2001 10 5 52187 0.052116 0.117560 -0.0416739 0.0008764 -0.000015 0.000098 0.000065 0.000049 0.0000048 0.0000245 0.000035 0.000037 2001 10 6 52188 0.049011 0.117875 -0.0425210 0.0007741 -0.000024 0.000116 0.000065 0.000049 0.0000084 0.0000245 0.000035 0.000037 2001 10 7 52189 0.046000 0.117982 -0.0432084 0.0006267 -0.000032 0.000134 0.000065 0.000049 0.0000088 0.0000246 0.000035 0.000038 2001 10 8 52190 0.043151 0.117919 -0.0437917 0.0005179 -0.000041 0.000153 0.000065 0.000049 0.0000092 0.0000246 0.000035 0.000038 2001 10 9 52191 0.039906 0.117880 -0.0442981 0.0004898 -0.000050 0.000171 0.000065 0.000049 0.0000088 0.0000246 0.000035 0.000039 2001 10 10 52192 0.036279 0.117781 -0.0447901 0.0005417 -0.000058 0.000189 0.000065 0.000049 0.0000052 0.0000246 0.000035 0.000039 2001 10 11 52193 0.031894 0.117373 -0.0453847 0.0006191 -0.000124 0.000313 0.000065 0.000049 0.0000114 0.0000246 0.000035 0.000040 2001 10 12 52194 0.027433 0.117359 -0.0461135 0.0007707 -0.000119 0.000329 0.000065 0.000049 0.0000176 0.0000246 0.000035 0.000040 2001 10 13 52195 0.023005 0.117694 -0.0469645 0.0010232 -0.000077 0.000287 0.000065 0.000049 0.0000127 0.0000246 0.000035 0.000039 2001 10 14 52196 0.019309 0.117804 -0.0481702 0.0013196 -0.000035 0.000244 0.000065 0.000049 0.0000123 0.0000246 0.000035 0.000039 2001 10 15 52197 0.015882 0.118440 -0.0496038 0.0015055 0.000007 0.000202 0.000065 0.000049 0.0000120 0.0000246 0.000035 0.000039 2001 10 16 52198 0.012768 0.119030 -0.0511607 0.0016221 0.000048 0.000159 0.000066 0.000050 0.0000106 0.0000246 0.000035 0.000039 2001 10 17 52199 0.009838 0.119639 -0.0526935 0.0015565 0.000007 0.000175 0.000066 0.000050 0.0000051 0.0000246 0.000035 0.000038 2001 10 18 52200 0.006773 0.119974 -0.0541391 0.0013898 0.000008 -0.000026 0.000066 0.000050 0.0000051 0.0000246 0.000034 0.000038 2001 10 19 52201 0.003162 0.120528 -0.0553635 0.0010853 0.000020 -0.000176 0.000066 0.000050 0.0000096 0.0000246 0.000034 0.000037 2001 10 20 52202 -0.000601 0.121113 -0.0563044 0.0007947 0.000043 -0.000157 0.000066 0.000050 0.0000098 0.0000246 0.000033 0.000036 2001 10 21 52203 -0.004479 0.121950 -0.0570190 0.0006501 0.000070 -0.000087 0.000066 0.000050 0.0000079 0.0000246 0.000033 0.000035 2001 10 22 52204 -0.008558 0.122876 -0.0575867 0.0005559 0.000098 -0.000018 0.000067 0.000050 0.0000060 0.0000246 0.000032 0.000034 2001 10 23 52205 -0.012659 0.123839 -0.0580855 0.0005267 0.000126 0.000051 0.000067 0.000050 0.0000042 0.0000245 0.000032 0.000034 2001 10 24 52206 -0.016547 0.124706 -0.0586009 0.0005590 0.000123 0.000069 0.000067 0.000051 0.0000045 0.0000245 0.000031 0.000033 2001 10 25 52207 -0.020134 0.125825 -0.0591479 0.0006125 0.000112 0.000149 0.000067 0.000051 0.0000055 0.0000245 0.000031 0.000032 2001 10 26 52208 -0.023530 0.126984 -0.0598194 0.0007494 0.000113 0.000158 0.000067 0.000051 0.0000054 0.0000245 0.000030 0.000030 2001 10 27 52209 -0.027001 0.128301 -0.0606325 0.0009140 0.000118 0.000131 0.000067 0.000051 0.0000060 0.0000245 0.000029 0.000029 2001 10 28 52210 -0.030409 0.129230 -0.0615973 0.0010491 0.000123 0.000105 0.000067 0.000051 0.0000106 0.0000244 0.000028 0.000028 2001 10 29 52211 -0.033434 0.130425 -0.0626614 0.0011127 0.000127 0.000078 0.000067 0.000051 0.0000151 0.0000244 0.000028 0.000027 2001 10 30 52212 -0.036454 0.131496 -0.0637878 0.0011051 0.000132 0.000051 0.000067 0.000051 0.0000196 0.0000244 0.000027 0.000026 2001 10 31 52213 -0.039629 0.132664 -0.0648977 0.0011060 0.000068 -0.000016 0.000067 0.000050 0.0000063 0.0000244 0.000028 0.000027 2001 11 1 52214 -0.042955 0.133861 -0.0659634 0.0010246 0.000029 -0.000003 0.000067 0.000050 0.0000051 0.0000244 0.000028 0.000028 2001 11 2 52215 -0.046575 0.134963 -0.0669350 0.0008530 0.000028 0.000042 0.000066 0.000050 0.0000108 0.0000243 0.000028 0.000028 2001 11 3 52216 -0.050455 0.135991 -0.0677579 0.0006886 0.000037 0.000090 0.000066 0.000050 0.0000153 0.0000243 0.000029 0.000029 2001 11 4 52217 -0.054051 0.137004 -0.0683868 0.0005596 0.000045 0.000138 0.000066 0.000050 0.0000113 0.0000243 0.000029 0.000029 2001 11 5 52218 -0.056982 0.137998 -0.0688916 0.0005384 0.000054 0.000186 0.000066 0.000050 0.0000074 0.0000243 0.000030 0.000030 2001 11 6 52219 -0.059340 0.139382 -0.0693335 0.0004768 0.000063 0.000234 0.000066 0.000050 0.0000035 0.0000243 0.000030 0.000030 2001 11 7 52220 -0.061688 0.141051 -0.0698102 0.0005197 0.000164 0.000141 0.000066 0.000050 0.0000031 0.0000243 0.000030 0.000031 2001 11 8 52221 -0.063544 0.142860 -0.0703931 0.0006808 0.000137 0.000238 0.000066 0.000050 0.0000030 0.0000243 0.000031 0.000031 2001 11 9 52222 -0.065420 0.145143 -0.0712588 0.0009749 0.000126 0.000271 0.000066 0.000050 0.0000047 0.0000243 0.000031 0.000031 2001 11 10 52223 -0.067853 0.147696 -0.0723937 0.0012688 0.000140 0.000251 0.000065 0.000049 0.0000070 0.0000243 0.000031 0.000032 2001 11 11 52224 -0.069965 0.150069 -0.0737247 0.0014709 0.000154 0.000232 0.000065 0.000049 0.0000091 0.0000243 0.000031 0.000032 2001 11 12 52225 -0.071446 0.152724 -0.0752294 0.0015723 0.000168 0.000212 0.000065 0.000049 0.0000112 0.0000243 0.000032 0.000033 2001 11 13 52226 -0.073233 0.155335 -0.0767953 0.0015829 0.000182 0.000192 0.000065 0.000049 0.0000133 0.0000243 0.000032 0.000033 2001 11 14 52227 -0.075320 0.157488 -0.0783475 0.0014476 0.000022 0.000191 0.000065 0.000049 0.0000049 0.0000243 0.000033 0.000034 2001 11 15 52228 -0.077874 0.159278 -0.0796701 0.0011847 0.000004 0.000107 0.000065 0.000049 0.0000017 0.0000242 0.000033 0.000034 2001 11 16 52229 -0.080514 0.160857 -0.0807360 0.0009163 0.000027 0.000076 0.000065 0.000049 0.0000037 0.0000242 0.000033 0.000034 2001 11 17 52230 -0.082640 0.162781 -0.0815832 0.0007271 0.000044 0.000075 0.000065 0.000049 0.0000062 0.0000242 0.000033 0.000034 2001 11 18 52231 -0.084487 0.164622 -0.0822917 0.0006044 0.000060 0.000073 0.000065 0.000049 0.0000064 0.0000242 0.000034 0.000035 2001 11 19 52232 -0.086579 0.166608 -0.0828895 0.0005718 0.000077 0.000072 0.000065 0.000049 0.0000066 0.0000242 0.000034 0.000035 2001 11 20 52233 -0.088882 0.168702 -0.0834244 0.0005623 0.000094 0.000071 0.000065 0.000049 0.0000064 0.0000242 0.000034 0.000036 2001 11 21 52234 -0.091579 0.170699 -0.0838884 0.0005834 0.000111 0.000070 0.000066 0.000049 0.0000045 0.0000242 0.000035 0.000036 2001 11 22 52235 -0.094433 0.173109 -0.0844900 0.0006680 0.000126 0.000099 0.000066 0.000049 0.0000064 0.0000242 0.000035 0.000036 2001 11 23 52236 -0.097344 0.175818 -0.0852094 0.0007776 0.000139 0.000138 0.000066 0.000049 0.0000096 0.0000242 0.000035 0.000036 2001 11 24 52237 -0.100633 0.178320 -0.0860291 0.0008057 0.000153 0.000178 0.000066 0.000049 0.0000127 0.0000243 0.000035 0.000037 2001 11 25 52238 -0.103663 0.180707 -0.0869360 0.0009259 0.000166 0.000217 0.000066 0.000050 0.0000159 0.0000243 0.000035 0.000037 2001 11 26 52239 -0.106091 0.183323 -0.0879012 0.0009872 0.000180 0.000257 0.000066 0.000050 0.0000190 0.0000243 0.000036 0.000037 2001 11 27 52240 -0.108071 0.185710 -0.0888787 0.0009956 0.000193 0.000296 0.000066 0.000050 0.0000189 0.0000243 0.000036 0.000037 2001 11 28 52241 -0.110143 0.188101 -0.0898036 0.0009355 0.000144 0.000147 0.000066 0.000050 0.0000066 0.0000243 0.000036 0.000037 2001 11 29 52242 -0.112485 0.190409 -0.0906856 0.0008257 0.000034 0.000072 0.000066 0.000050 0.0000022 0.0000243 0.000036 0.000036 2001 11 30 52243 -0.115251 0.192945 -0.0915155 0.0007198 0.000019 0.000064 0.000066 0.000050 0.0000032 0.0000243 0.000036 0.000035 2001 12 1 52244 -0.118395 0.195719 -0.0921774 0.0005401 0.000048 0.000069 0.000066 0.000050 0.0000057 0.0000243 0.000035 0.000035 2001 12 2 52245 -0.121719 0.198252 -0.0925708 0.0003652 0.000076 0.000074 0.000066 0.000050 0.0000101 0.0000243 0.000035 0.000034 2001 12 3 52246 -0.124545 0.200385 -0.0928521 0.0002650 0.000104 0.000080 0.000066 0.000050 0.0000146 0.0000242 0.000035 0.000034 2001 12 4 52247 -0.127137 0.202510 -0.0931037 0.0002607 0.000132 0.000085 0.000066 0.000050 0.0000190 0.0000242 0.000035 0.000034 2001 12 5 52248 -0.129471 0.205343 -0.0934012 0.0003524 0.000348 -0.000018 0.000066 0.000050 0.0000073 0.0000242 0.000035 0.000034 2001 12 6 52249 -0.131684 0.208683 -0.0938399 0.0005420 0.000197 0.000108 0.000066 0.000050 0.0000023 0.0000242 0.000035 0.000034 2001 12 7 52250 -0.134438 0.211940 -0.0945106 0.0007663 0.000100 0.000196 0.000066 0.000050 0.0000073 0.0000242 0.000035 0.000034 2001 12 8 52251 -0.137742 0.214601 -0.0954088 0.0009469 0.000073 0.000238 0.000066 0.000050 0.0000125 0.0000242 0.000035 0.000034 2001 12 9 52252 -0.141044 0.217014 -0.0964959 0.0011268 0.000047 0.000281 0.000066 0.000050 0.0000103 0.0000242 0.000035 0.000035 2001 12 10 52253 -0.143805 0.219732 -0.0976613 0.0012196 0.000020 0.000324 0.000066 0.000050 0.0000080 0.0000242 0.000035 0.000035 2001 12 11 52254 -0.146679 0.222735 -0.0988019 0.0011496 -0.000006 0.000367 0.000066 0.000050 0.0000057 0.0000242 0.000035 0.000036 2001 12 12 52255 -0.149828 0.225535 -0.0998237 0.0009812 0.000019 0.000228 0.000066 0.000050 0.0000035 0.0000242 0.000035 0.000035 2001 12 13 52256 -0.152747 0.228098 -0.1007032 0.0008130 0.000097 0.000190 0.000066 0.000050 0.0000031 0.0000243 0.000034 0.000035 2001 12 14 52257 -0.155174 0.230602 -0.1014000 0.0005739 0.000192 0.000192 0.000066 0.000050 0.0000035 0.0000243 0.000034 0.000035 2001 12 15 52258 -0.157768 0.233332 -0.1018719 0.0003928 0.000220 0.000145 0.000066 0.000050 0.0000051 0.0000243 0.000034 0.000035 2001 12 16 52259 -0.160003 0.235945 -0.1022331 0.0003066 0.000243 0.000093 0.000066 0.000050 0.0000069 0.0000244 0.000034 0.000035 2001 12 17 52260 -0.161960 0.238770 -0.1025628 0.0003264 0.000266 0.000042 0.000066 0.000050 0.0000087 0.0000244 0.000033 0.000035 2001 12 18 52261 -0.163863 0.241642 -0.1029266 0.0004146 0.000289 -0.000009 0.000066 0.000050 0.0000089 0.0000245 0.000033 0.000034 2001 12 19 52262 -0.165888 0.244995 -0.1033672 0.0005319 0.000312 -0.000061 0.000066 0.000050 0.0000036 0.0000245 0.000033 0.000034 2001 12 20 52263 -0.167906 0.248560 -0.1039476 0.0006585 0.000132 0.000110 0.000065 0.000050 0.0000024 0.0000246 0.000032 0.000034 2001 12 21 52264 -0.169257 0.251974 -0.1047719 0.0009012 0.000081 0.000154 0.000065 0.000049 0.0000054 0.0000247 0.000032 0.000034 2001 12 22 52265 -0.170277 0.255526 -0.1057653 0.0010794 0.000103 0.000126 0.000065 0.000049 0.0000087 0.0000247 0.000032 0.000033 2001 12 23 52266 -0.171403 0.259108 -0.1068267 0.0011493 0.000124 0.000097 0.000065 0.000049 0.0000088 0.0000248 0.000031 0.000033 2001 12 24 52267 -0.172094 0.262625 -0.1079853 0.0011599 0.000146 0.000069 0.000065 0.000049 0.0000089 0.0000249 0.000031 0.000033 2001 12 25 52268 -0.172623 0.266496 -0.1091946 0.0011699 0.000167 0.000041 0.000065 0.000049 0.0000091 0.0000250 0.000030 0.000032 2001 12 26 52269 -0.173033 0.270573 -0.1104015 0.0011629 0.000189 0.000012 0.000065 0.000049 0.0000092 0.0000251 0.000030 0.000032 2001 12 27 52270 -0.173475 0.274824 -0.1115409 0.0010927 0.000211 -0.000016 0.000064 0.000049 0.0000083 0.0000252 0.000030 0.000032 2001 12 28 52271 -0.174635 0.278732 -0.1125373 0.0009887 0.000232 -0.000045 0.000064 0.000049 0.0000034 0.0000253 0.000029 0.000031 2001 12 29 52272 -0.175382 0.282445 -0.1134581 0.0008606 0.000225 -0.000054 0.000064 0.000049 0.0000034 0.0000253 0.000029 0.000031 2001 12 30 52273 -0.175973 0.286626 -0.1142840 0.0008038 0.000208 -0.000058 0.000064 0.000048 0.0000049 0.0000254 0.000029 0.000031 2001 12 31 52274 -0.176684 0.290471 -0.1150562 0.0007687 0.000191 -0.000061 0.000064 0.000048 0.0000065 0.0000255 0.000028 0.000031 2002 1 1 52275 -0.176989 0.294107 -0.1158581 0.0007910 0.000174 -0.000064 0.000093 0.000074 0.0000101 0.0000328 0.000030 0.000035 2002 1 2 52276 -0.177457 0.297920 -0.1167317 0.0009331 0.000158 -0.000068 0.000093 0.000074 0.0000099 0.0000328 0.000030 0.000034 2002 1 3 52277 -0.178403 0.301070 -0.1177654 0.0011236 0.000141 -0.000071 0.000093 0.000074 0.0000090 0.0000329 0.000030 0.000034 2002 1 4 52278 -0.179041 0.303809 -0.1189180 0.0012984 0.000124 -0.000075 0.000092 0.000073 0.0000051 0.0000330 0.000030 0.000034 2002 1 5 52279 -0.179568 0.306633 -0.1202473 0.0013289 0.000133 -0.000043 0.000092 0.000073 0.0000038 0.0000331 0.000029 0.000034 2002 1 6 52280 -0.179987 0.309664 -0.1216143 0.0013249 0.000151 0.000002 0.000092 0.000073 0.0000035 0.0000332 0.000029 0.000033 2002 1 7 52281 -0.180604 0.312922 -0.1228856 0.0012456 0.000170 0.000046 0.000092 0.000073 0.0000033 0.0000333 0.000028 0.000033 2002 1 8 52282 -0.181644 0.315670 -0.1239677 0.0010045 0.000188 0.000091 0.000092 0.000073 0.0000030 0.0000334 0.000028 0.000033 2002 1 9 52283 -0.182807 0.318387 -0.1248561 0.0007289 0.000218 0.000066 0.000092 0.000073 0.0000078 0.0000335 0.000028 0.000032 2002 1 10 52284 -0.183132 0.321327 -0.1254810 0.0004812 0.000250 0.000023 0.000092 0.000073 0.0000115 0.0000336 0.000027 0.000031 2002 1 11 52285 -0.182964 0.324311 -0.1258153 0.0002993 0.000283 -0.000020 0.000093 0.000073 0.0000053 0.0000337 0.000027 0.000031 2002 1 12 52286 -0.182737 0.327567 -0.1259692 0.0001253 0.000285 -0.000058 0.000093 0.000074 0.0000032 0.0000338 0.000026 0.000030 2002 1 13 52287 -0.182301 0.330647 -0.1260119 0.0000335 0.000275 -0.000094 0.000093 0.000074 0.0000025 0.0000338 0.000026 0.000029 2002 1 14 52288 -0.181602 0.333659 -0.1260155 -0.0000293 0.000266 -0.000130 0.000093 0.000074 0.0000019 0.0000338 0.000025 0.000029 2002 1 15 52289 -0.181285 0.336962 -0.1260456 0.0000178 0.000256 -0.000166 0.000093 0.000074 0.0000013 0.0000338 0.000025 0.000028 2002 1 16 52290 -0.180625 0.339887 -0.1261215 0.0001231 0.000244 -0.000134 0.000093 0.000074 0.0000085 0.0000338 0.000025 0.000028 2002 1 17 52291 -0.179800 0.343101 -0.1262971 0.0002286 0.000230 -0.000083 0.000093 0.000074 0.0000177 0.0000337 0.000024 0.000027 2002 1 18 52292 -0.179301 0.346269 -0.1265846 0.0003543 0.000202 -0.000133 0.000093 0.000074 0.0000075 0.0000337 0.000024 0.000028 2002 1 19 52293 -0.178714 0.349408 -0.1270203 0.0004853 0.000203 -0.000137 0.000093 0.000074 0.0000027 0.0000337 0.000025 0.000028 2002 1 20 52294 -0.178370 0.352433 -0.1275548 0.0005452 0.000217 -0.000111 0.000093 0.000074 0.0000023 0.0000336 0.000025 0.000028 2002 1 21 52295 -0.178142 0.355441 -0.1281383 0.0006079 0.000231 -0.000085 0.000094 0.000075 0.0000019 0.0000335 0.000025 0.000029 2002 1 22 52296 -0.177729 0.358602 -0.1287333 0.0006050 0.000245 -0.000060 0.000094 0.000075 0.0000015 0.0000334 0.000026 0.000029 2002 1 23 52297 -0.177025 0.362003 -0.1293023 0.0005659 0.000259 -0.000034 0.000094 0.000075 0.0000011 0.0000334 0.000026 0.000030 2002 1 24 52298 -0.176533 0.365519 -0.1298272 0.0005044 0.000183 -0.000092 0.000094 0.000075 0.0000014 0.0000334 0.000026 0.000030 2002 1 25 52299 -0.175801 0.368884 -0.1302786 0.0003755 0.000083 -0.000172 0.000094 0.000075 0.0000018 0.0000334 0.000027 0.000031 2002 1 26 52300 -0.174992 0.372323 -0.1306254 0.0002929 0.000072 -0.000164 0.000094 0.000075 0.0000018 0.0000335 0.000027 0.000031 2002 1 27 52301 -0.174353 0.375666 -0.1309415 0.0003237 0.000093 -0.000124 0.000094 0.000076 0.0000017 0.0000335 0.000028 0.000032 2002 1 28 52302 -0.173541 0.378964 -0.1313295 0.0004697 0.000114 -0.000085 0.000094 0.000076 0.0000016 0.0000335 0.000028 0.000032 2002 1 29 52303 -0.172972 0.382324 -0.1318943 0.0006946 0.000136 -0.000045 0.000095 0.000076 0.0000014 0.0000335 0.000028 0.000033 2002 1 30 52304 -0.172248 0.385321 -0.1327265 0.0009775 0.000141 -0.000120 0.000095 0.000076 0.0000018 0.0000335 0.000029 0.000033 2002 1 31 52305 -0.170789 0.388424 -0.1338323 0.0012448 0.000142 -0.000096 0.000095 0.000076 0.0000028 0.0000334 0.000029 0.000034 2002 2 1 52306 -0.168917 0.391716 -0.1351711 0.0014143 0.000143 -0.000033 0.000095 0.000076 0.0000041 0.0000334 0.000030 0.000035 2002 2 2 52307 -0.167365 0.394941 -0.1366707 0.0015050 0.000145 -0.000004 0.000095 0.000076 0.0000041 0.0000334 0.000030 0.000036 2002 2 3 52308 -0.166402 0.398091 -0.1381758 0.0014504 0.000148 0.000013 0.000095 0.000076 0.0000038 0.0000333 0.000031 0.000036 2002 2 4 52309 -0.165582 0.401103 -0.1395539 0.0012640 0.000150 0.000031 0.000095 0.000076 0.0000035 0.0000333 0.000031 0.000037 2002 2 5 52310 -0.164323 0.403730 -0.1407259 0.0010874 0.000152 0.000049 0.000095 0.000076 0.0000031 0.0000333 0.000032 0.000038 2002 2 6 52311 -0.163218 0.406598 -0.1416917 0.0008959 0.000250 0.000074 0.000095 0.000076 0.0000095 0.0000332 0.000032 0.000038 2002 2 7 52312 -0.162222 0.409646 -0.1424499 0.0006088 0.000373 0.000100 0.000095 0.000076 0.0000176 0.0000332 0.000033 0.000039 2002 2 8 52313 -0.161212 0.412583 -0.1430135 0.0004777 0.000252 -0.000086 0.000095 0.000076 0.0000076 0.0000332 0.000033 0.000039 2002 2 9 52314 -0.159853 0.415569 -0.1434476 0.0003868 0.000170 -0.000115 0.000094 0.000076 0.0000033 0.0000333 0.000033 0.000039 2002 2 10 52315 -0.157926 0.418994 -0.1438450 0.0003480 0.000130 -0.000061 0.000094 0.000076 0.0000032 0.0000333 0.000033 0.000039 2002 2 11 52316 -0.155958 0.422653 -0.1442761 0.0004470 0.000090 -0.000007 0.000094 0.000076 0.0000031 0.0000333 0.000033 0.000039 2002 2 12 52317 -0.154384 0.425954 -0.1447897 0.0005851 0.000051 0.000046 0.000094 0.000076 0.0000030 0.0000332 0.000033 0.000039 2002 2 13 52318 -0.153205 0.428984 -0.1454049 0.0006913 0.000062 -0.000018 0.000094 0.000076 0.0000079 0.0000332 0.000033 0.000039 2002 2 14 52319 -0.152516 0.431930 -0.1461319 0.0007820 0.000128 -0.000087 0.000094 0.000076 0.0000071 0.0000332 0.000033 0.000038 2002 2 15 52320 -0.151526 0.434716 -0.1469725 0.0008606 0.000206 -0.000148 0.000094 0.000076 0.0000043 0.0000333 0.000033 0.000038 2002 2 16 52321 -0.150118 0.437262 -0.1479661 0.0009200 0.000213 -0.000172 0.000094 0.000076 0.0000137 0.0000333 0.000032 0.000037 2002 2 17 52322 -0.148520 0.439961 -0.1490333 0.0010539 0.000193 -0.000183 0.000094 0.000076 0.0000276 0.0000333 0.000032 0.000036 2002 2 18 52323 -0.146688 0.442534 -0.1501068 0.0010751 0.000173 -0.000193 0.000094 0.000076 0.0000415 0.0000333 0.000032 0.000035 2002 2 19 52324 -0.145224 0.445458 -0.1511274 0.0010263 0.000153 -0.000203 0.000094 0.000075 0.0000449 0.0000333 0.000031 0.000035 2002 2 20 52325 -0.143755 0.448150 -0.1520123 0.0009013 0.000133 -0.000214 0.000094 0.000075 0.0000086 0.0000333 0.000031 0.000034 2002 2 21 52326 -0.141967 0.450975 -0.1528688 0.0008315 0.000165 -0.000232 0.000094 0.000075 0.0000029 0.0000333 0.000031 0.000034 2002 2 22 52327 -0.140221 0.454163 -0.1536440 0.0007108 0.000212 -0.000253 0.000094 0.000075 0.0000051 0.0000333 0.000030 0.000033 2002 2 23 52328 -0.138469 0.457354 -0.1543206 0.0006440 0.000201 -0.000253 0.000094 0.000075 0.0000048 0.0000333 0.000030 0.000032 2002 2 24 52329 -0.136625 0.460936 -0.1549848 0.0006883 0.000169 -0.000246 0.000094 0.000075 0.0000037 0.0000334 0.000029 0.000031 2002 2 25 52330 -0.134147 0.463939 -0.1557471 0.0008524 0.000137 -0.000239 0.000094 0.000075 0.0000025 0.0000334 0.000029 0.000031 2002 2 26 52331 -0.131005 0.467077 -0.1567104 0.0010710 0.000105 -0.000232 0.000094 0.000075 0.0000013 0.0000333 0.000029 0.000030 2002 2 27 52332 -0.128321 0.470409 -0.1579537 0.0013673 0.000105 -0.000195 0.000094 0.000075 0.0000065 0.0000333 0.000028 0.000029 2002 2 28 52333 -0.125980 0.473663 -0.1594387 0.0015793 0.000113 -0.000150 0.000095 0.000075 0.0000108 0.0000333 0.000028 0.000029 2002 3 1 52334 -0.123412 0.476748 -0.1610155 0.0016449 0.000121 -0.000105 0.000095 0.000075 0.0000057 0.0000333 0.000028 0.000028 2002 3 2 52335 -0.120630 0.479911 -0.1626930 0.0016782 0.000147 -0.000111 0.000095 0.000075 0.0000072 0.0000333 0.000027 0.000027 2002 3 3 52336 -0.118406 0.483124 -0.1642874 0.0015108 0.000179 -0.000135 0.000095 0.000075 0.0000112 0.0000332 0.000027 0.000027 2002 3 4 52337 -0.116623 0.486109 -0.1656682 0.0012770 0.000211 -0.000159 0.000095 0.000075 0.0000152 0.0000331 0.000027 0.000026 2002 3 5 52338 -0.114487 0.489179 -0.1667899 0.0009964 0.000244 -0.000183 0.000095 0.000075 0.0000192 0.0000331 0.000026 0.000026 2002 3 6 52339 -0.111910 0.491939 -0.1676889 0.0008162 0.000153 -0.000165 0.000096 0.000075 0.0000057 0.0000330 0.000026 0.000025 2002 3 7 52340 -0.108778 0.494567 -0.1684134 0.0006473 0.000100 -0.000127 0.000096 0.000075 0.0000156 0.0000330 0.000026 0.000025 2002 3 8 52341 -0.105577 0.497244 -0.1690237 0.0005517 0.000175 -0.000155 0.000096 0.000075 0.0000071 0.0000329 0.000026 0.000025 2002 3 9 52342 -0.102260 0.499847 -0.1695682 0.0005099 0.000210 -0.000181 0.000095 0.000075 0.0000057 0.0000329 0.000027 0.000026 2002 3 10 52343 -0.099104 0.502663 -0.1701278 0.0005521 0.000217 -0.000199 0.000095 0.000074 0.0000102 0.0000328 0.000027 0.000026 2002 3 11 52344 -0.096798 0.505392 -0.1707576 0.0006665 0.000224 -0.000216 0.000095 0.000074 0.0000146 0.0000328 0.000027 0.000027 2002 3 12 52345 -0.094990 0.507801 -0.1714830 0.0008028 0.000231 -0.000234 0.000095 0.000074 0.0000191 0.0000327 0.000028 0.000028 2002 3 13 52346 -0.092791 0.509964 -0.1723681 0.0009665 0.000171 -0.000183 0.000095 0.000074 0.0000065 0.0000327 0.000028 0.000029 2002 3 14 52347 -0.090172 0.512402 -0.1733294 0.0010306 0.000170 -0.000140 0.000095 0.000074 0.0000024 0.0000326 0.000029 0.000030 2002 3 15 52348 -0.087650 0.514508 -0.1743371 0.0009778 0.000213 -0.000188 0.000095 0.000074 0.0000022 0.0000326 0.000029 0.000030 2002 3 16 52349 -0.084921 0.516617 -0.1753097 0.0009062 0.000216 -0.000205 0.000095 0.000074 0.0000020 0.0000326 0.000030 0.000031 2002 3 17 52350 -0.081853 0.518766 -0.1762255 0.0008587 0.000203 -0.000201 0.000095 0.000074 0.0000018 0.0000325 0.000030 0.000031 2002 3 18 52351 -0.078647 0.520428 -0.1770564 0.0008368 0.000190 -0.000197 0.000095 0.000074 0.0000015 0.0000325 0.000030 0.000032 2002 3 19 52352 -0.075615 0.522477 -0.1777704 0.0007381 0.000177 -0.000192 0.000095 0.000074 0.0000013 0.0000324 0.000031 0.000033 2002 3 20 52353 -0.072546 0.524217 -0.1783721 0.0005384 0.000230 -0.000084 0.000095 0.000074 0.0000335 0.0000323 0.000031 0.000034 2002 3 21 52354 -0.069300 0.525854 -0.1788523 0.0004326 0.000253 -0.000046 0.000095 0.000074 0.0000740 0.0000323 0.000031 0.000034 2002 3 22 52355 -0.065768 0.527713 -0.1792270 0.0003606 0.000223 -0.000117 0.000095 0.000074 0.0000245 0.0000322 0.000032 0.000035 2002 3 23 52356 -0.062320 0.529397 -0.1795951 0.0003974 0.000198 -0.000151 0.000095 0.000074 0.0000028 0.0000322 0.000032 0.000035 2002 3 24 52357 -0.058847 0.530826 -0.1800334 0.0005314 0.000180 -0.000161 0.000094 0.000074 0.0000023 0.0000322 0.000032 0.000035 2002 3 25 52358 -0.055204 0.532442 -0.1806388 0.0006926 0.000162 -0.000171 0.000094 0.000074 0.0000018 0.0000322 0.000032 0.000035 2002 3 26 52359 -0.051400 0.534244 -0.1815028 0.0009820 0.000144 -0.000181 0.000094 0.000074 0.0000013 0.0000321 0.000032 0.000035 2002 3 27 52360 -0.047859 0.536048 -0.1826702 0.0012976 0.000139 -0.000046 0.000094 0.000074 0.0000020 0.0000321 0.000032 0.000035 2002 3 28 52361 -0.044859 0.537526 -0.1840939 0.0015473 0.000143 -0.000087 0.000094 0.000073 0.0000030 0.0000320 0.000032 0.000036 2002 3 29 52362 -0.041763 0.538781 -0.1856407 0.0015611 0.000177 -0.000122 0.000093 0.000073 0.0000043 0.0000320 0.000032 0.000035 2002 3 30 52363 -0.038212 0.539711 -0.1871605 0.0013663 0.000222 -0.000128 0.000093 0.000073 0.0000057 0.0000319 0.000032 0.000035 2002 3 31 52364 -0.034506 0.540454 -0.1885094 0.0011472 0.000266 -0.000134 0.000093 0.000073 0.0000070 0.0000318 0.000031 0.000035 2002 4 1 52365 -0.030744 0.540991 -0.1895996 0.0009545 0.000311 -0.000140 0.000093 0.000073 0.0000084 0.0000317 0.000031 0.000034 2002 4 2 52366 -0.026972 0.541407 -0.1903930 0.0007114 0.000356 -0.000146 0.000092 0.000073 0.0000083 0.0000315 0.000031 0.000034 2002 4 3 52367 -0.022961 0.541916 -0.1908770 0.0004727 0.000400 -0.000152 0.000092 0.000073 0.0000028 0.0000314 0.000031 0.000034 2002 4 4 52368 -0.018867 0.543087 -0.1912919 0.0004115 0.000342 -0.000267 0.000092 0.000073 0.0000016 0.0000312 0.000031 0.000034 2002 4 5 52369 -0.014798 0.544475 -0.1916691 0.0003810 0.000170 -0.000269 0.000092 0.000073 0.0000020 0.0000311 0.000031 0.000034 2002 4 6 52370 -0.011554 0.546005 -0.1920675 0.0004355 0.000088 -0.000224 0.000092 0.000073 0.0000021 0.0000309 0.000031 0.000034 2002 4 7 52371 -0.008701 0.547255 -0.1925421 0.0005682 0.000049 -0.000178 0.000092 0.000073 0.0000020 0.0000307 0.000031 0.000034 2002 4 8 52372 -0.006114 0.548173 -0.1931253 0.0006077 0.000009 -0.000131 0.000092 0.000073 0.0000019 0.0000305 0.000031 0.000034 2002 4 9 52373 -0.003795 0.548795 -0.1938286 0.0007457 -0.000030 -0.000085 0.000092 0.000073 0.0000018 0.0000303 0.000031 0.000034 2002 4 10 52374 -0.001836 0.549518 -0.1946371 0.0008449 0.000150 -0.000231 0.000091 0.000073 0.0000025 0.0000302 0.000032 0.000035 2002 4 11 52375 0.000499 0.549851 -0.1955506 0.0009279 0.000179 -0.000244 0.000091 0.000072 0.0000030 0.0000301 0.000032 0.000035 2002 4 12 52376 0.003769 0.550515 -0.1965090 0.0010216 0.000146 -0.000204 0.000090 0.000072 0.0000035 0.0000299 0.000032 0.000035 2002 4 13 52377 0.006763 0.551493 -0.1974265 0.0009384 0.000157 -0.000169 0.000090 0.000071 0.0000032 0.0000299 0.000032 0.000035 2002 4 14 52378 0.009897 0.552041 -0.1982633 0.0007667 0.000184 -0.000135 0.000090 0.000071 0.0000026 0.0000298 0.000032 0.000036 2002 4 15 52379 0.012969 0.552774 -0.1989814 0.0006289 0.000211 -0.000101 0.000089 0.000071 0.0000020 0.0000297 0.000032 0.000036 2002 4 16 52380 0.015611 0.553451 -0.1995508 0.0004566 0.000238 -0.000068 0.000089 0.000071 0.0000014 0.0000297 0.000032 0.000036 2002 4 17 52381 0.018794 0.553890 -0.1999561 0.0002853 0.000297 -0.000205 0.000088 0.000070 0.0000047 0.0000296 0.000032 0.000036 2002 4 18 52382 0.022181 0.554400 -0.2002337 0.0002248 0.000365 -0.000387 0.000088 0.000070 0.0000074 0.0000295 0.000033 0.000036 2002 4 19 52383 0.025478 0.554742 -0.2004590 0.0002162 0.000247 -0.000306 0.000088 0.000070 0.0000040 0.0000294 0.000033 0.000036 2002 4 20 52384 0.029049 0.555043 -0.2006600 0.0002058 0.000165 -0.000250 0.000087 0.000069 0.0000027 0.0000294 0.000033 0.000036 2002 4 21 52385 0.032011 0.555211 -0.2009581 0.0003369 0.000119 -0.000235 0.000087 0.000069 0.0000023 0.0000293 0.000033 0.000036 2002 4 22 52386 0.034855 0.555200 -0.2014649 0.0006047 0.000072 -0.000219 0.000086 0.000069 0.0000019 0.0000292 0.000033 0.000036 2002 4 23 52387 0.037785 0.555049 -0.2022487 0.0008988 0.000026 -0.000204 0.000086 0.000068 0.0000015 0.0000291 0.000033 0.000036 2002 4 24 52388 0.041220 0.554805 -0.2033162 0.0011629 0.000155 -0.000236 0.000086 0.000068 0.0000047 0.0000290 0.000033 0.000035 2002 4 25 52389 0.044829 0.554685 -0.2046042 0.0013348 0.000207 -0.000238 0.000086 0.000068 0.0000072 0.0000290 0.000033 0.000035 2002 4 26 52390 0.048749 0.554481 -0.2060012 0.0014326 0.000223 -0.000227 0.000085 0.000068 0.0000034 0.0000290 0.000033 0.000034 2002 4 27 52391 0.052499 0.554125 -0.2073477 0.0013272 0.000192 -0.000227 0.000085 0.000067 0.0000023 0.0000290 0.000032 0.000034 2002 4 28 52392 0.056245 0.553418 -0.2084963 0.0010311 0.000144 -0.000231 0.000085 0.000067 0.0000022 0.0000290 0.000032 0.000033 2002 4 29 52393 0.059916 0.553121 -0.2093712 0.0006934 0.000097 -0.000235 0.000085 0.000067 0.0000021 0.0000290 0.000032 0.000033 2002 4 30 52394 0.063505 0.552809 -0.2099808 0.0004459 0.000049 -0.000238 0.000085 0.000067 0.0000020 0.0000290 0.000032 0.000032 2002 5 1 52395 0.066837 0.552746 -0.2103807 0.0002837 0.000031 -0.000236 0.000085 0.000067 0.0000108 0.0000290 0.000032 0.000031 2002 5 2 52396 0.069948 0.552450 -0.2106403 0.0001934 0.000020 -0.000231 0.000085 0.000067 0.0000171 0.0000290 0.000032 0.000031 2002 5 3 52397 0.073367 0.552148 -0.2107647 0.0001909 0.000010 -0.000226 0.000085 0.000067 0.0000057 0.0000290 0.000031 0.000030 2002 5 4 52398 0.076810 0.552065 -0.2110185 0.0002942 0.000047 -0.000184 0.000085 0.000067 0.0000025 0.0000290 0.000031 0.000029 2002 5 5 52399 0.080670 0.551914 -0.2114097 0.0004348 0.000101 -0.000129 0.000085 0.000067 0.0000023 0.0000290 0.000031 0.000029 2002 5 6 52400 0.084691 0.551849 -0.2119392 0.0006473 0.000155 -0.000073 0.000085 0.000067 0.0000022 0.0000290 0.000031 0.000028 2002 5 7 52401 0.088606 0.551445 -0.2126113 0.0007894 0.000209 -0.000017 0.000085 0.000067 0.0000021 0.0000290 0.000031 0.000028 2002 5 8 52402 0.091564 0.550976 -0.2134389 0.0008994 0.000157 -0.000176 0.000085 0.000067 0.0000028 0.0000290 0.000030 0.000027 2002 5 9 52403 0.094161 0.550121 -0.2143555 0.0009603 0.000061 -0.000218 0.000085 0.000067 0.0000159 0.0000290 0.000030 0.000026 2002 5 10 52404 0.097776 0.549311 -0.2153233 0.0009985 0.000029 -0.000193 0.000085 0.000067 0.0000092 0.0000289 0.000030 0.000027 2002 5 11 52405 0.101178 0.549055 -0.2162937 0.0009516 0.000054 -0.000183 0.000086 0.000067 0.0000048 0.0000289 0.000031 0.000027 2002 5 12 52406 0.103904 0.548650 -0.2172091 0.0008513 0.000091 -0.000179 0.000086 0.000067 0.0000042 0.0000288 0.000031 0.000028 2002 5 13 52407 0.106812 0.547859 -0.2180266 0.0007812 0.000128 -0.000176 0.000086 0.000067 0.0000036 0.0000288 0.000032 0.000029 2002 5 14 52408 0.109760 0.547001 -0.2187254 0.0006847 0.000165 -0.000173 0.000086 0.000067 0.0000031 0.0000287 0.000032 0.000030 2002 5 15 52409 0.112084 0.545798 -0.2193356 0.0005459 0.000196 -0.000225 0.000086 0.000068 0.0000130 0.0000286 0.000033 0.000030 2002 5 16 52410 0.114120 0.544307 -0.2198592 0.0004767 0.000224 -0.000313 0.000087 0.000068 0.0000067 0.0000285 0.000033 0.000031 2002 5 17 52411 0.116371 0.542528 -0.2203421 0.0004669 0.000207 -0.000168 0.000087 0.000068 0.0000036 0.0000284 0.000034 0.000031 2002 5 18 52412 0.119062 0.541399 -0.2208798 0.0005726 0.000160 -0.000108 0.000087 0.000068 0.0000031 0.0000283 0.000034 0.000032 2002 5 19 52413 0.121941 0.540636 -0.2215713 0.0007469 0.000106 -0.000108 0.000087 0.000068 0.0000027 0.0000282 0.000034 0.000032 2002 5 20 52414 0.125158 0.540125 -0.2224808 0.0009965 0.000052 -0.000107 0.000087 0.000068 0.0000023 0.0000281 0.000034 0.000033 2002 5 21 52415 0.128548 0.539707 -0.2236248 0.0012447 -0.000002 -0.000107 0.000087 0.000068 0.0000019 0.0000280 0.000035 0.000033 2002 5 22 52416 0.131246 0.539079 -0.2249740 0.0014295 -0.000010 -0.000121 0.000087 0.000068 0.0000047 0.0000279 0.000035 0.000034 2002 5 23 52417 0.133621 0.538173 -0.2264162 0.0014016 -0.000004 -0.000140 0.000087 0.000068 0.0000071 0.0000278 0.000036 0.000035 2002 5 24 52418 0.135951 0.537192 -0.2278052 0.0013518 0.000001 -0.000159 0.000087 0.000068 0.0000047 0.0000277 0.000036 0.000035 2002 5 25 52419 0.138156 0.536200 -0.2290133 0.0010611 0.000019 -0.000140 0.000087 0.000069 0.0000038 0.0000276 0.000036 0.000036 2002 5 26 52420 0.140476 0.535178 -0.2299381 0.0008629 0.000041 -0.000108 0.000087 0.000069 0.0000034 0.0000275 0.000037 0.000037 2002 5 27 52421 0.143130 0.533996 -0.2305450 0.0003079 0.000064 -0.000076 0.000087 0.000069 0.0000029 0.0000274 0.000037 0.000038 2002 5 28 52422 0.146194 0.532905 -0.2308681 0.0000810 0.000086 -0.000043 0.000087 0.000069 0.0000025 0.0000272 0.000037 0.000039 2002 5 29 52423 0.149090 0.531671 -0.2309870 0.0001534 0.000108 -0.000011 0.000087 0.000069 0.0000021 0.0000271 0.000038 0.000039 2002 5 30 52424 0.151879 0.530288 -0.2310365 -0.0000075 0.000088 -0.000060 0.000087 0.000069 0.0000026 0.0000271 0.000038 0.000040 2002 5 31 52425 0.154727 0.528792 -0.2310670 0.0001009 0.000014 -0.000146 0.000087 0.000069 0.0000032 0.0000270 0.000039 0.000041 2002 6 1 52426 0.157315 0.527276 -0.2311269 0.0000555 0.000023 -0.000155 0.000087 0.000069 0.0000031 0.0000269 0.000039 0.000041 2002 6 2 52427 0.159825 0.525502 -0.2312395 0.0001479 0.000068 -0.000134 0.000087 0.000068 0.0000027 0.0000268 0.000039 0.000042 2002 6 3 52428 0.162454 0.523596 -0.2314053 0.0001729 0.000113 -0.000114 0.000087 0.000068 0.0000022 0.0000268 0.000039 0.000042 2002 6 4 52429 0.165191 0.521834 -0.2316072 0.0002338 0.000158 -0.000093 0.000087 0.000068 0.0000018 0.0000267 0.000040 0.000043 2002 6 5 52430 0.168363 0.520219 -0.2318125 0.0001655 0.000197 -0.000080 0.000087 0.000068 0.0000073 0.0000266 0.000040 0.000043 2002 6 6 52431 0.171408 0.518677 -0.2319643 0.0000679 0.000124 -0.000144 0.000087 0.000068 0.0000121 0.0000266 0.000040 0.000043 2002 6 7 52432 0.174535 0.516983 -0.2319693 -0.0000526 0.000019 -0.000231 0.000087 0.000068 0.0000084 0.0000265 0.000040 0.000044 2002 6 8 52433 0.177659 0.515276 -0.2318916 -0.0001834 0.000022 -0.000235 0.000087 0.000068 0.0000065 0.0000264 0.000040 0.000043 2002 6 9 52434 0.180734 0.513684 -0.2316730 -0.0003336 0.000064 -0.000210 0.000087 0.000068 0.0000053 0.0000264 0.000040 0.000043 2002 6 10 52435 0.183619 0.512029 -0.2312821 -0.0004694 0.000107 -0.000185 0.000087 0.000068 0.0000042 0.0000263 0.000041 0.000043 2002 6 11 52436 0.186150 0.510117 -0.2307281 -0.0006106 0.000149 -0.000160 0.000087 0.000068 0.0000030 0.0000262 0.000041 0.000043 2002 6 12 52437 0.188443 0.508078 -0.2300771 -0.0006776 0.000146 -0.000224 0.000087 0.000068 0.0000029 0.0000261 0.000041 0.000043 2002 6 13 52438 0.190718 0.505967 -0.2293875 -0.0007133 0.000131 -0.000311 0.000087 0.000068 0.0000031 0.0000261 0.000041 0.000044 2002 6 14 52439 0.193215 0.504169 -0.2287069 -0.0006469 0.000056 -0.000280 0.000087 0.000068 0.0000043 0.0000260 0.000041 0.000044 2002 6 15 52440 0.195855 0.502465 -0.2281840 -0.0004366 0.000064 -0.000242 0.000087 0.000068 0.0000043 0.0000259 0.000041 0.000045 2002 6 16 52441 0.199113 0.500378 -0.2278932 -0.0001690 0.000110 -0.000217 0.000087 0.000068 0.0000038 0.0000258 0.000042 0.000045 2002 6 17 52442 0.202368 0.498025 -0.2278577 0.0000824 0.000156 -0.000191 0.000086 0.000068 0.0000033 0.0000257 0.000042 0.000045 2002 6 18 52443 0.204951 0.495553 -0.2280564 0.0002395 0.000202 -0.000166 0.000086 0.000068 0.0000028 0.0000257 0.000042 0.000045 2002 6 19 52444 0.207457 0.493051 -0.2283681 0.0003002 0.000253 -0.000385 0.000086 0.000067 0.0000137 0.0000256 0.000042 0.000046 2002 6 20 52445 0.210298 0.490721 -0.2287207 0.0003180 0.000197 -0.000367 0.000086 0.000067 0.0000220 0.0000256 0.000042 0.000046 2002 6 21 52446 0.212701 0.488984 -0.2290003 0.0002558 0.000025 -0.000186 0.000086 0.000067 0.0000089 0.0000255 0.000042 0.000046 2002 6 22 52447 0.214640 0.487012 -0.2292410 0.0001622 0.000028 -0.000132 0.000086 0.000067 0.0000048 0.0000255 0.000041 0.000045 2002 6 23 52448 0.216612 0.484612 -0.2293419 0.0000208 0.000106 -0.000134 0.000086 0.000067 0.0000040 0.0000255 0.000041 0.000044 2002 6 24 52449 0.218292 0.482120 -0.2292807 -0.0001143 0.000184 -0.000136 0.000086 0.000067 0.0000033 0.0000255 0.000041 0.000044 2002 6 25 52450 0.219538 0.479496 -0.2291146 -0.0001659 0.000262 -0.000139 0.000086 0.000067 0.0000025 0.0000255 0.000040 0.000043 2002 6 26 52451 0.220825 0.476554 -0.2289517 -0.0001459 0.000016 -0.000173 0.000086 0.000067 0.0000032 0.0000255 0.000040 0.000043 2002 6 27 52452 0.222501 0.473468 -0.2288132 -0.0000925 0.000064 -0.000268 0.000086 0.000067 0.0000032 0.0000255 0.000040 0.000043 2002 6 28 52453 0.224487 0.470314 -0.2287711 -0.0000211 0.000222 -0.000377 0.000086 0.000066 0.0000029 0.0000256 0.000040 0.000042 2002 6 29 52454 0.226027 0.467450 -0.2288049 0.0000757 0.000218 -0.000375 0.000086 0.000066 0.0000027 0.0000256 0.000039 0.000042 2002 6 30 52455 0.227156 0.464699 -0.2289542 0.0001933 0.000155 -0.000332 0.000086 0.000066 0.0000024 0.0000256 0.000039 0.000042 2002 7 1 52456 0.228113 0.461846 -0.2292213 0.0002778 0.000091 -0.000289 0.000086 0.000066 0.0000021 0.0000256 0.000039 0.000042 2002 7 2 52457 0.228853 0.458778 -0.2295695 0.0004180 0.000027 -0.000245 0.000086 0.000066 0.0000019 0.0000257 0.000038 0.000042 2002 7 3 52458 0.229539 0.455789 -0.2300060 0.0004557 0.000059 -0.000292 0.000086 0.000066 0.0000033 0.0000257 0.000038 0.000042 2002 7 4 52459 0.229947 0.452933 -0.2305184 0.0004047 0.000073 -0.000305 0.000086 0.000066 0.0000141 0.0000257 0.000038 0.000042 2002 7 5 52460 0.230338 0.449875 -0.2308968 0.0003348 0.000072 -0.000297 0.000086 0.000066 0.0000163 0.0000257 0.000038 0.000042 2002 7 6 52461 0.230733 0.446637 -0.2311160 0.0001855 0.000071 -0.000289 0.000086 0.000066 0.0000125 0.0000258 0.000037 0.000041 2002 7 7 52462 0.231490 0.442949 -0.2311969 0.0000357 0.000070 -0.000281 0.000086 0.000066 0.0000091 0.0000258 0.000037 0.000041 2002 7 8 52463 0.232404 0.439738 -0.2311260 -0.0000929 0.000069 -0.000273 0.000086 0.000066 0.0000057 0.0000258 0.000037 0.000041 2002 7 9 52464 0.233026 0.436567 -0.2309234 -0.0001976 0.000068 -0.000265 0.000086 0.000066 0.0000023 0.0000258 0.000037 0.000041 2002 7 10 52465 0.233976 0.433469 -0.2306615 -0.0002671 -0.000002 -0.000274 0.000086 0.000066 0.0000036 0.0000259 0.000037 0.000041 2002 7 11 52466 0.235381 0.430601 -0.2303843 -0.0002622 -0.000056 -0.000354 0.000086 0.000066 0.0000031 0.0000259 0.000037 0.000041 2002 7 12 52467 0.236822 0.427723 -0.2301795 -0.0001272 0.000047 -0.000212 0.000086 0.000066 0.0000023 0.0000259 0.000036 0.000040 2002 7 13 52468 0.238125 0.424693 -0.2301992 0.0000869 0.000094 -0.000164 0.000086 0.000066 0.0000024 0.0000260 0.000036 0.000040 2002 7 14 52469 0.239210 0.421598 -0.2304584 0.0003494 0.000103 -0.000180 0.000086 0.000066 0.0000026 0.0000260 0.000036 0.000040 2002 7 15 52470 0.240273 0.418473 -0.2309121 0.0005502 0.000111 -0.000196 0.000085 0.000066 0.0000029 0.0000261 0.000036 0.000040 2002 7 16 52471 0.241173 0.415699 -0.2314758 0.0005872 0.000119 -0.000212 0.000085 0.000066 0.0000031 0.0000261 0.000036 0.000040 2002 7 17 52472 0.241869 0.413001 -0.2320543 0.0005260 0.000074 -0.000268 0.000085 0.000066 0.0000077 0.0000261 0.000036 0.000040 2002 7 18 52473 0.242939 0.410458 -0.2325139 0.0003962 0.000014 -0.000334 0.000085 0.000065 0.0000134 0.0000261 0.000036 0.000040 2002 7 19 52474 0.243973 0.408415 -0.2328049 0.0001675 -0.000029 -0.000349 0.000085 0.000065 0.0000066 0.0000262 0.000036 0.000040 2002 7 20 52475 0.244356 0.405900 -0.2327950 -0.0001417 -0.000032 -0.000304 0.000085 0.000065 0.0000032 0.0000262 0.000035 0.000039 2002 7 21 52476 0.244728 0.403009 -0.2325080 -0.0004165 -0.000022 -0.000244 0.000085 0.000065 0.0000025 0.0000263 0.000035 0.000039 2002 7 22 52477 0.245497 0.399922 -0.2320148 -0.0005875 -0.000012 -0.000183 0.000084 0.000065 0.0000019 0.0000263 0.000035 0.000038 2002 7 23 52478 0.246280 0.397189 -0.2313951 -0.0006591 -0.000002 -0.000122 0.000084 0.000065 0.0000013 0.0000263 0.000034 0.000037 2002 7 24 52479 0.246715 0.394323 -0.2306804 -0.0007307 -0.000001 -0.000192 0.000085 0.000065 0.0000011 0.0000264 0.000034 0.000037 2002 7 25 52480 0.247003 0.391311 -0.2299869 -0.0006719 -0.000004 -0.000295 0.000085 0.000065 0.0000011 0.0000264 0.000034 0.000037 2002 7 26 52481 0.246932 0.388185 -0.2294102 -0.0005316 0.000205 -0.000284 0.000085 0.000065 0.0000032 0.0000265 0.000035 0.000037 2002 7 27 52482 0.246778 0.384632 -0.2289887 -0.0004129 0.000256 -0.000257 0.000085 0.000065 0.0000039 0.0000265 0.000035 0.000038 2002 7 28 52483 0.247126 0.380795 -0.2286873 -0.0002459 0.000221 -0.000238 0.000084 0.000065 0.0000037 0.0000266 0.000036 0.000038 2002 7 29 52484 0.247572 0.377043 -0.2284686 -0.0001519 0.000187 -0.000219 0.000085 0.000066 0.0000036 0.0000266 0.000036 0.000039 2002 7 30 52485 0.248397 0.373423 -0.2282933 -0.0001887 0.000152 -0.000200 0.000085 0.000066 0.0000034 0.0000267 0.000037 0.000039 2002 7 31 52486 0.249777 0.370069 -0.2281304 -0.0002377 0.000052 -0.000247 0.000085 0.000066 0.0000088 0.0000267 0.000037 0.000040 2002 8 1 52487 0.251309 0.366988 -0.2279057 -0.0002901 -0.000064 -0.000311 0.000085 0.000066 0.0000129 0.0000267 0.000038 0.000040 2002 8 2 52488 0.252295 0.364409 -0.2275276 -0.0003884 -0.000181 -0.000376 0.000085 0.000066 0.0000059 0.0000268 0.000038 0.000041 2002 8 3 52489 0.252917 0.361810 -0.2270763 -0.0004595 -0.000139 -0.000352 0.000085 0.000066 0.0000038 0.0000268 0.000039 0.000041 2002 8 4 52490 0.253955 0.359173 -0.2265215 -0.0006274 -0.000038 -0.000296 0.000085 0.000066 0.0000034 0.0000268 0.000039 0.000042 2002 8 5 52491 0.255019 0.356614 -0.2258649 -0.0007108 0.000063 -0.000240 0.000085 0.000066 0.0000030 0.0000268 0.000039 0.000042 2002 8 6 52492 0.255699 0.353621 -0.2251527 -0.0007436 0.000164 -0.000184 0.000086 0.000067 0.0000026 0.0000268 0.000040 0.000042 2002 8 7 52493 0.256712 0.350416 -0.2244402 -0.0006678 -0.000002 -0.000237 0.000086 0.000067 0.0000033 0.0000269 0.000040 0.000042 2002 8 8 52494 0.257950 0.347577 -0.2238570 -0.0004733 0.000009 -0.000228 0.000086 0.000067 0.0000038 0.0000269 0.000040 0.000042 2002 8 9 52495 0.259031 0.345017 -0.2235098 -0.0002296 0.000093 -0.000193 0.000086 0.000067 0.0000043 0.0000269 0.000041 0.000043 2002 8 10 52496 0.260005 0.342511 -0.2234779 0.0000863 0.000054 -0.000140 0.000086 0.000067 0.0000040 0.0000269 0.000041 0.000043 2002 8 11 52497 0.260529 0.339986 -0.2237452 0.0003550 -0.000032 -0.000080 0.000086 0.000067 0.0000034 0.0000269 0.000041 0.000043 2002 8 12 52498 0.260530 0.337124 -0.2242263 0.0005621 -0.000117 -0.000020 0.000086 0.000067 0.0000029 0.0000269 0.000041 0.000043 2002 8 13 52499 0.260701 0.333928 -0.2247921 0.0005835 -0.000202 0.000040 0.000086 0.000067 0.0000023 0.0000269 0.000041 0.000042 2002 8 14 52500 0.260889 0.331064 -0.2253233 0.0004884 -0.000165 -0.000068 0.000087 0.000067 0.0000091 0.0000269 0.000041 0.000043 2002 8 15 52501 0.260808 0.328379 -0.2256950 0.0002661 -0.000094 -0.000220 0.000087 0.000067 0.0000179 0.0000269 0.000041 0.000043 2002 8 16 52502 0.260597 0.325788 -0.2258538 0.0000416 -0.000189 -0.000224 0.000086 0.000067 0.0000094 0.0000269 0.000041 0.000042 2002 8 17 52503 0.260300 0.323216 -0.2257620 -0.0001770 -0.000184 -0.000216 0.000086 0.000067 0.0000051 0.0000269 0.000041 0.000042 2002 8 18 52504 0.259745 0.320502 -0.2254901 -0.0002985 -0.000121 -0.000222 0.000086 0.000067 0.0000045 0.0000269 0.000041 0.000041 2002 8 19 52505 0.259169 0.317811 -0.2251288 -0.0003828 -0.000059 -0.000228 0.000086 0.000067 0.0000040 0.0000269 0.000040 0.000041 2002 8 20 52506 0.258501 0.314894 -0.2247614 -0.0003818 0.000004 -0.000234 0.000086 0.000067 0.0000034 0.0000269 0.000040 0.000040 2002 8 21 52507 0.257852 0.311945 -0.2244727 -0.0002812 -0.000022 -0.000236 0.000086 0.000067 0.0000082 0.0000269 0.000040 0.000040 2002 8 22 52508 0.257215 0.308911 -0.2243019 -0.0000836 -0.000070 -0.000238 0.000086 0.000067 0.0000115 0.0000269 0.000039 0.000040 2002 8 23 52509 0.256721 0.305649 -0.2242634 0.0000509 -0.000118 -0.000240 0.000086 0.000067 0.0000039 0.0000269 0.000039 0.000039 2002 8 24 52510 0.256320 0.302336 -0.2243616 0.0001741 -0.000057 -0.000164 0.000086 0.000067 0.0000018 0.0000269 0.000039 0.000039 2002 8 25 52511 0.255507 0.298938 -0.2245734 0.0002257 0.000045 -0.000060 0.000087 0.000067 0.0000017 0.0000269 0.000039 0.000039 2002 8 26 52512 0.254848 0.295356 -0.2248574 0.0002697 0.000114 -0.000004 0.000087 0.000067 0.0000016 0.0000269 0.000039 0.000039 2002 8 27 52513 0.254554 0.291924 -0.2251610 0.0003318 0.000019 -0.000191 0.000087 0.000067 0.0000015 0.0000269 0.000039 0.000039 2002 8 28 52514 0.254525 0.288539 -0.2254962 0.0002814 -0.000009 -0.000260 0.000087 0.000067 0.0000087 0.0000269 0.000039 0.000039 2002 8 29 52515 0.254605 0.285680 -0.2257500 0.0001835 -0.000019 -0.000298 0.000087 0.000067 0.0000140 0.0000269 0.000039 0.000040 2002 8 30 52516 0.254164 0.282551 -0.2258202 0.0000234 -0.000138 -0.000234 0.000087 0.000067 0.0000048 0.0000269 0.000039 0.000040 2002 8 31 52517 0.253597 0.279436 -0.2257853 -0.0000935 -0.000171 -0.000189 0.000087 0.000067 0.0000022 0.0000268 0.000038 0.000040 2002 9 1 52518 0.252821 0.276297 -0.2256395 -0.0001668 -0.000158 -0.000163 0.000087 0.000067 0.0000022 0.0000268 0.000038 0.000039 2002 9 2 52519 0.251657 0.273045 -0.2254075 -0.0002221 -0.000145 -0.000137 0.000087 0.000066 0.0000021 0.0000267 0.000038 0.000039 2002 9 3 52520 0.250006 0.269897 -0.2251525 -0.0002608 -0.000132 -0.000112 0.000087 0.000066 0.0000020 0.0000267 0.000038 0.000039 2002 9 4 52521 0.249046 0.266788 -0.2249688 -0.0001223 -0.000040 -0.000177 0.000087 0.000066 0.0000020 0.0000266 0.000037 0.000039 2002 9 5 52522 0.248301 0.263804 -0.2249285 0.0000956 -0.000092 -0.000223 0.000087 0.000066 0.0000023 0.0000265 0.000037 0.000039 2002 9 6 52523 0.247499 0.260749 -0.2251533 0.0003690 -0.000206 -0.000301 0.000087 0.000066 0.0000027 0.0000265 0.000037 0.000038 2002 9 7 52524 0.246305 0.258164 -0.2257261 0.0006680 -0.000159 -0.000447 0.000087 0.000066 0.0000032 0.0000264 0.000037 0.000038 2002 9 8 52525 0.244708 0.255874 -0.2265809 0.0009302 -0.000048 -0.000614 0.000087 0.000066 0.0000037 0.0000263 0.000036 0.000038 2002 9 9 52526 0.242815 0.253396 -0.2275852 0.0010339 0.000010 -0.000649 0.000087 0.000066 0.0000042 0.0000263 0.000036 0.000037 2002 9 10 52527 0.240979 0.250652 -0.2285805 0.0009637 -0.000093 -0.000288 0.000087 0.000066 0.0000047 0.0000263 0.000036 0.000037 2002 9 11 52528 0.239335 0.248251 -0.2293883 0.0007161 -0.000237 -0.000213 0.000087 0.000066 0.0000070 0.0000263 0.000035 0.000036 2002 9 12 52529 0.237488 0.245737 -0.2299407 0.0004365 -0.000392 -0.000217 0.000087 0.000066 0.0000097 0.0000263 0.000035 0.000035 2002 9 13 52530 0.235829 0.242950 -0.2302852 0.0002381 -0.000117 -0.000256 0.000087 0.000066 0.0000050 0.0000264 0.000034 0.000035 2002 9 14 52531 0.234210 0.239875 -0.2304247 0.0000641 -0.000010 -0.000234 0.000087 0.000066 0.0000028 0.0000264 0.000034 0.000034 2002 9 15 52532 0.232915 0.236859 -0.2304252 -0.0000285 -0.000018 -0.000184 0.000087 0.000066 0.0000025 0.0000264 0.000033 0.000033 2002 9 16 52533 0.231803 0.234741 -0.2303787 -0.0000352 -0.000026 -0.000134 0.000087 0.000066 0.0000022 0.0000264 0.000033 0.000032 2002 9 17 52534 0.230233 0.232833 -0.2303632 0.0000108 -0.000034 -0.000084 0.000087 0.000067 0.0000019 0.0000264 0.000032 0.000031 2002 9 18 52535 0.228071 0.231111 -0.2303896 0.0000762 -0.000125 -0.000133 0.000087 0.000067 0.0000027 0.0000265 0.000032 0.000031 2002 9 19 52536 0.225427 0.229361 -0.2305098 0.0001941 -0.000132 -0.000121 0.000087 0.000067 0.0000028 0.0000265 0.000031 0.000030 2002 9 20 52537 0.222387 0.227448 -0.2307472 0.0002894 -0.000108 -0.000085 0.000088 0.000067 0.0000026 0.0000265 0.000031 0.000030 2002 9 21 52538 0.219379 0.225159 -0.2311013 0.0003712 -0.000086 -0.000105 0.000088 0.000067 0.0000023 0.0000265 0.000030 0.000029 2002 9 22 52539 0.216670 0.222972 -0.2315284 0.0004367 -0.000064 -0.000146 0.000088 0.000067 0.0000020 0.0000265 0.000030 0.000029 2002 9 23 52540 0.214367 0.220649 -0.2319762 0.0004635 -0.000043 -0.000186 0.000088 0.000068 0.0000017 0.0000265 0.000029 0.000028 2002 9 24 52541 0.212302 0.218067 -0.2323925 0.0004024 -0.000022 -0.000227 0.000088 0.000068 0.0000014 0.0000265 0.000029 0.000027 2002 9 25 52542 0.210524 0.215654 -0.2327483 0.0003254 -0.000102 -0.000177 0.000088 0.000068 0.0000086 0.0000265 0.000029 0.000027 2002 9 26 52543 0.208813 0.213319 -0.2329947 0.0001652 -0.000207 -0.000103 0.000088 0.000068 0.0000178 0.0000265 0.000028 0.000027 2002 9 27 52544 0.206830 0.211099 -0.2331166 0.0000865 -0.000013 -0.000087 0.000088 0.000068 0.0000079 0.0000265 0.000028 0.000027 2002 9 28 52545 0.204789 0.208782 -0.2331211 -0.0000276 0.000053 -0.000092 0.000088 0.000068 0.0000035 0.0000265 0.000028 0.000027 2002 9 29 52546 0.202712 0.206136 -0.2330287 -0.0000938 0.000034 -0.000098 0.000088 0.000068 0.0000034 0.0000266 0.000028 0.000028 2002 9 30 52547 0.200623 0.203428 -0.2328879 -0.0001538 0.000016 -0.000104 0.000088 0.000068 0.0000033 0.0000266 0.000029 0.000028 2002 10 1 52548 0.198440 0.200669 -0.2327765 -0.0000662 -0.000002 -0.000109 0.000088 0.000068 0.0000032 0.0000266 0.000029 0.000029 2002 10 2 52549 0.196606 0.198370 -0.2328145 0.0000998 -0.000014 -0.000083 0.000088 0.000068 0.0000053 0.0000266 0.000029 0.000029 2002 10 3 52550 0.194707 0.195796 -0.2330127 0.0003346 -0.000024 -0.000047 0.000088 0.000068 0.0000051 0.0000266 0.000029 0.000030 2002 10 4 52551 0.192572 0.193644 -0.2334596 0.0006089 -0.000033 -0.000012 0.000088 0.000069 0.0000028 0.0000266 0.000028 0.000030 2002 10 5 52552 0.189948 0.191558 -0.2342660 0.0009301 -0.000053 -0.000011 0.000088 0.000069 0.0000022 0.0000266 0.000028 0.000030 2002 10 6 52553 0.187277 0.189506 -0.2353226 0.0011285 -0.000075 -0.000023 0.000088 0.000069 0.0000021 0.0000266 0.000028 0.000031 2002 10 7 52554 0.185037 0.187399 -0.2364663 0.0011588 -0.000097 -0.000034 0.000089 0.000069 0.0000020 0.0000266 0.000028 0.000031 2002 10 8 52555 0.182510 0.185214 -0.2375308 0.0010194 -0.000120 -0.000046 0.000089 0.000069 0.0000019 0.0000266 0.000028 0.000031 2002 10 9 52556 0.180045 0.182961 -0.2384023 0.0007586 -0.000142 -0.000072 0.000089 0.000070 0.0000056 0.0000266 0.000028 0.000031 2002 10 10 52557 0.178012 0.180845 -0.2390073 0.0004684 -0.000104 -0.000074 0.000089 0.000070 0.0000104 0.0000266 0.000028 0.000031 2002 10 11 52558 0.175571 0.179135 -0.2393592 0.0002300 -0.000069 -0.000026 0.000089 0.000070 0.0000052 0.0000266 0.000028 0.000031 2002 10 12 52559 0.173134 0.177116 -0.2395457 0.0001210 -0.000051 0.000013 0.000090 0.000070 0.0000027 0.0000266 0.000028 0.000031 2002 10 13 52560 0.171017 0.175299 -0.2396706 0.0001297 -0.000037 0.000044 0.000090 0.000070 0.0000024 0.0000266 0.000028 0.000031 2002 10 14 52561 0.168562 0.173675 -0.2398288 0.0002223 -0.000022 0.000075 0.000090 0.000070 0.0000021 0.0000266 0.000028 0.000031 2002 10 15 52562 0.165847 0.171858 -0.2400890 0.0003320 -0.000008 0.000106 0.000090 0.000070 0.0000017 0.0000266 0.000027 0.000031 2002 10 16 52563 0.163462 0.170301 -0.2404748 0.0004505 -0.000109 0.000028 0.000090 0.000070 0.0000083 0.0000265 0.000027 0.000031 2002 10 17 52564 0.161230 0.169015 -0.2410129 0.0006052 -0.000124 -0.000121 0.000090 0.000070 0.0000040 0.0000265 0.000027 0.000031 2002 10 18 52565 0.158414 0.167978 -0.2416911 0.0007342 -0.000107 -0.000141 0.000090 0.000070 0.0000014 0.0000265 0.000027 0.000030 2002 10 19 52566 0.154602 0.166908 -0.2424254 0.0007493 -0.000095 -0.000110 0.000090 0.000070 0.0000012 0.0000264 0.000027 0.000030 2002 10 20 52567 0.150335 0.165623 -0.2431869 0.0007452 -0.000097 -0.000061 0.000090 0.000070 0.0000155 0.0000264 0.000026 0.000030 2002 10 21 52568 0.146480 0.164148 -0.2439441 0.0007383 -0.000104 -0.000015 0.000091 0.000070 0.0000200 0.0000264 0.000026 0.000030 2002 10 22 52569 0.143185 0.162883 -0.2446792 0.0007089 -0.000126 0.000018 0.000091 0.000070 0.0000200 0.0000263 0.000026 0.000030 2002 10 23 52570 0.139949 0.161621 -0.2453496 0.0006373 -0.000092 -0.000015 0.000091 0.000070 0.0000200 0.0000263 0.000026 0.000030 2002 10 24 52571 0.136713 0.160260 -0.2459098 0.0004996 -0.000098 -0.000054 0.000091 0.000070 0.0000057 0.0000262 0.000026 0.000030 2002 10 25 52572 0.133080 0.158626 -0.2463345 0.0003620 -0.000109 -0.000094 0.000091 0.000070 0.0000014 0.0000262 0.000026 0.000030 2002 10 26 52573 0.129476 0.156895 -0.2466295 0.0002614 -0.000070 -0.000160 0.000091 0.000070 0.0000016 0.0000262 0.000026 0.000030 2002 10 27 52574 0.125891 0.155503 -0.2468453 0.0002138 -0.000050 -0.000206 0.000091 0.000070 0.0000017 0.0000261 0.000026 0.000030 2002 10 28 52575 0.122291 0.154154 -0.2470227 0.0002258 -0.000063 -0.000161 0.000091 0.000070 0.0000015 0.0000260 0.000026 0.000030 2002 10 29 52576 0.118927 0.153058 -0.2471994 0.0002389 -0.000060 -0.000146 0.000091 0.000070 0.0000155 0.0000259 0.000027 0.000030 2002 10 30 52577 0.115481 0.152290 -0.2475166 0.0004446 -0.000104 -0.000110 0.000091 0.000070 0.0000200 0.0000259 0.000027 0.000030 2002 10 31 52578 0.111594 0.151750 -0.2480809 0.0007260 -0.000129 -0.000072 0.000091 0.000070 0.0000200 0.0000259 0.000027 0.000030 2002 11 1 52579 0.107583 0.150889 -0.2489220 0.0009979 -0.000081 -0.000072 0.000091 0.000070 0.0000066 0.0000259 0.000027 0.000031 2002 11 2 52580 0.103502 0.150251 -0.2500245 0.0012140 -0.000084 -0.000067 0.000091 0.000070 0.0000052 0.0000260 0.000027 0.000031 2002 11 3 52581 0.099891 0.149530 -0.2512754 0.0012999 -0.000106 -0.000062 0.000091 0.000070 0.0000098 0.0000260 0.000028 0.000031 2002 11 4 52582 0.096541 0.149177 -0.2525156 0.0011815 -0.000129 -0.000056 0.000091 0.000070 0.0000144 0.0000260 0.000028 0.000032 2002 11 5 52583 0.092819 0.148515 -0.2535903 0.0009690 -0.000151 -0.000051 0.000091 0.000070 0.0000191 0.0000260 0.000028 0.000032 2002 11 6 52584 0.088866 0.147705 -0.2544330 0.0007074 -0.000125 -0.000101 0.000091 0.000070 0.0000132 0.0000260 0.000028 0.000033 2002 11 7 52585 0.084801 0.147181 -0.2549883 0.0004652 -0.000023 -0.000108 0.000091 0.000070 0.0000047 0.0000260 0.000029 0.000033 2002 11 8 52586 0.080743 0.146285 -0.2553335 0.0002729 -0.000054 -0.000035 0.000091 0.000070 0.0000024 0.0000260 0.000029 0.000033 2002 11 9 52587 0.076685 0.145679 -0.2554726 0.0001533 -0.000087 -0.000010 0.000091 0.000070 0.0000023 0.0000259 0.000029 0.000034 2002 11 10 52588 0.072831 0.145095 -0.2555482 0.0000820 -0.000103 -0.000011 0.000091 0.000070 0.0000023 0.0000259 0.000030 0.000034 2002 11 11 52589 0.069194 0.144758 -0.2556745 0.0001278 -0.000119 -0.000012 0.000091 0.000070 0.0000022 0.0000258 0.000030 0.000035 2002 11 12 52590 0.065876 0.144442 -0.2559047 0.0002250 -0.000134 -0.000013 0.000091 0.000070 0.0000022 0.0000258 0.000030 0.000035 2002 11 13 52591 0.062939 0.144006 -0.2562603 0.0004237 -0.000190 -0.000109 0.000091 0.000070 0.0000139 0.0000257 0.000030 0.000036 2002 11 14 52592 0.060100 0.143902 -0.2567527 0.0005541 -0.000271 -0.000176 0.000091 0.000070 0.0000187 0.0000256 0.000030 0.000036 2002 11 15 52593 0.056427 0.143891 -0.2573361 0.0005930 -0.000300 -0.000183 0.000091 0.000070 0.0000067 0.0000256 0.000030 0.000036 2002 11 16 52594 0.053035 0.143862 -0.2579736 0.0006412 -0.000259 -0.000150 0.000090 0.000070 0.0000020 0.0000256 0.000030 0.000036 2002 11 17 52595 0.049796 0.143950 -0.2586203 0.0006466 -0.000198 -0.000109 0.000090 0.000070 0.0000017 0.0000255 0.000030 0.000036 2002 11 18 52596 0.046280 0.143346 -0.2592278 0.0005832 -0.000138 -0.000067 0.000090 0.000070 0.0000015 0.0000255 0.000030 0.000036 2002 11 19 52597 0.042772 0.142825 -0.2597546 0.0004492 -0.000078 -0.000025 0.000090 0.000070 0.0000012 0.0000254 0.000030 0.000036 2002 11 20 52598 0.039028 0.142296 -0.2601356 0.0003227 -0.000126 -0.000024 0.000090 0.000070 0.0000052 0.0000254 0.000030 0.000036 2002 11 21 52599 0.035598 0.141807 -0.2603859 0.0001903 -0.000096 0.000000 0.000090 0.000070 0.0000073 0.0000253 0.000030 0.000036 2002 11 22 52600 0.032513 0.141715 -0.2605716 0.0001727 0.000008 -0.000074 0.000090 0.000070 0.0000034 0.0000253 0.000029 0.000036 2002 11 23 52601 0.029552 0.141921 -0.2607249 0.0001481 0.000020 -0.000096 0.000090 0.000069 0.0000018 0.0000253 0.000029 0.000035 2002 11 24 52602 0.026266 0.142141 -0.2608897 0.0001908 -0.000006 -0.000087 0.000090 0.000069 0.0000017 0.0000254 0.000029 0.000035 2002 11 25 52603 0.023057 0.142322 -0.2611394 0.0003260 -0.000032 -0.000077 0.000090 0.000069 0.0000015 0.0000254 0.000029 0.000034 2002 11 26 52604 0.020427 0.142308 -0.2615552 0.0005169 -0.000059 -0.000068 0.000090 0.000069 0.0000014 0.0000254 0.000028 0.000034 2002 11 27 52605 0.017829 0.142172 -0.2622069 0.0007845 -0.000134 -0.000102 0.000090 0.000069 0.0000017 0.0000254 0.000028 0.000034 2002 11 28 52606 0.014661 0.141847 -0.2631524 0.0010515 -0.000157 -0.000107 0.000090 0.000069 0.0000056 0.0000254 0.000028 0.000034 2002 11 29 52607 0.011113 0.141705 -0.2643336 0.0012643 -0.000156 -0.000097 0.000090 0.000069 0.0000091 0.0000254 0.000028 0.000033 2002 11 30 52608 0.007556 0.141580 -0.2656861 0.0014208 -0.000156 -0.000087 0.000090 0.000069 0.0000117 0.0000255 0.000028 0.000033 2002 12 1 52609 0.004159 0.141432 -0.2671019 0.0014207 -0.000155 -0.000077 0.000090 0.000069 0.0000143 0.0000255 0.000028 0.000033 2002 12 2 52610 0.000966 0.141369 -0.2684353 0.0012560 -0.000155 -0.000067 0.000090 0.000069 0.0000168 0.0000255 0.000027 0.000033 2002 12 3 52611 -0.002085 0.141690 -0.2695626 0.0010406 -0.000154 -0.000056 0.000090 0.000069 0.0000194 0.0000255 0.000027 0.000033 2002 12 4 52612 -0.005116 0.142363 -0.2704282 0.0007586 -0.000159 0.000105 0.000090 0.000069 0.0000128 0.0000255 0.000027 0.000033 2002 12 5 52613 -0.008461 0.143326 -0.2710430 0.0004767 -0.000090 0.000065 0.000089 0.000069 0.0000034 0.0000256 0.000027 0.000033 2002 12 6 52614 -0.012365 0.144458 -0.2714172 0.0003108 0.000012 -0.000066 0.000089 0.000069 0.0000018 0.0000256 0.000027 0.000033 2002 12 7 52615 -0.016697 0.145777 -0.2717540 0.0003445 0.000028 -0.000091 0.000089 0.000069 0.0000053 0.0000256 0.000027 0.000032 2002 12 8 52616 -0.021004 0.147012 -0.2721532 0.0004660 0.000012 -0.000075 0.000089 0.000069 0.0000099 0.0000256 0.000027 0.000032 2002 12 9 52617 -0.024296 0.147790 -0.2726706 0.0006009 -0.000005 -0.000058 0.000089 0.000069 0.0000145 0.0000256 0.000027 0.000032 2002 12 10 52618 -0.027076 0.149247 -0.2733367 0.0007683 -0.000022 -0.000042 0.000089 0.000069 0.0000191 0.0000256 0.000027 0.000032 2002 12 11 52619 -0.030031 0.150767 -0.2741971 0.0009304 -0.000128 -0.000047 0.000089 0.000069 0.0000200 0.0000256 0.000027 0.000031 2002 12 12 52620 -0.032871 0.152544 -0.2751827 0.0010288 -0.000178 -0.000056 0.000088 0.000068 0.0000200 0.0000256 0.000027 0.000031 2002 12 13 52621 -0.036315 0.153885 -0.2762058 0.0010494 -0.000146 -0.000063 0.000088 0.000068 0.0000090 0.0000257 0.000027 0.000031 2002 12 14 52622 -0.040037 0.155060 -0.2772390 0.0010494 -0.000129 -0.000051 0.000088 0.000068 0.0000043 0.0000257 0.000027 0.000031 2002 12 15 52623 -0.044181 0.156073 -0.2782267 0.0009353 -0.000125 -0.000033 0.000088 0.000068 0.0000034 0.0000257 0.000027 0.000031 2002 12 16 52624 -0.048147 0.156751 -0.2791120 0.0007926 -0.000121 -0.000014 0.000088 0.000068 0.0000024 0.0000258 0.000027 0.000032 2002 12 17 52625 -0.051643 0.157544 -0.2798541 0.0006337 -0.000117 0.000005 0.000088 0.000068 0.0000015 0.0000258 0.000027 0.000032 2002 12 18 52626 -0.054589 0.158506 -0.2804320 0.0004843 -0.000020 0.000056 0.000087 0.000068 0.0000019 0.0000258 0.000027 0.000032 2002 12 19 52627 -0.056962 0.159964 -0.2808047 0.0002846 -0.000047 0.000012 0.000087 0.000067 0.0000021 0.0000259 0.000028 0.000032 2002 12 20 52628 -0.059105 0.161873 -0.2810331 0.0001663 -0.000117 -0.000062 0.000087 0.000067 0.0000022 0.0000259 0.000028 0.000032 2002 12 21 52629 -0.061535 0.164238 -0.2812020 0.0001884 -0.000145 -0.000042 0.000087 0.000067 0.0000048 0.0000260 0.000028 0.000032 2002 12 22 52630 -0.064272 0.166664 -0.2813868 0.0002082 -0.000157 0.000012 0.000087 0.000067 0.0000082 0.0000261 0.000028 0.000032 2002 12 23 52631 -0.066804 0.168829 -0.2816736 0.0003323 -0.000170 0.000066 0.000086 0.000067 0.0000117 0.0000261 0.000028 0.000032 2002 12 24 52632 -0.069022 0.171068 -0.2821510 0.0005479 -0.000182 0.000120 0.000086 0.000067 0.0000143 0.0000262 0.000028 0.000032 2002 12 25 52633 -0.071585 0.173428 -0.2828950 0.0008380 -0.000195 0.000174 0.000086 0.000066 0.0000137 0.0000262 0.000029 0.000033 2002 12 26 52634 -0.074238 0.175403 -0.2838618 0.0010856 -0.000207 0.000229 0.000086 0.000066 0.0000131 0.0000263 0.000029 0.000033 2002 12 27 52635 -0.076449 0.177018 -0.2849853 0.0012091 -0.000220 0.000283 0.000086 0.000066 0.0000122 0.0000264 0.000029 0.000033 2002 12 28 52636 -0.078717 0.178994 -0.2861318 0.0011938 -0.000183 0.000266 0.000086 0.000066 0.0000105 0.0000264 0.000029 0.000033 2002 12 29 52637 -0.081128 0.181392 -0.2872324 0.0010885 -0.000136 0.000236 0.000086 0.000066 0.0000099 0.0000265 0.000029 0.000032 2002 12 30 52638 -0.083466 0.183429 -0.2881800 0.0008502 -0.000089 0.000205 0.000086 0.000066 0.0000092 0.0000265 0.000029 0.000032 2002 12 31 52639 -0.085605 0.185700 -0.2889043 0.0006367 -0.000042 0.000175 0.000086 0.000066 0.0000086 0.0000265 0.000029 0.000032 2003 1 1 52640 -0.088403 0.188136 -0.2894427 0.0004510 -0.000037 0.000110 0.000074 0.000074 0.0000082 0.0000247 0.000039 0.000036 2003 1 2 52641 -0.091526 0.190449 -0.2898142 0.0003215 -0.000043 0.000036 0.000074 0.000074 0.0000057 0.0000247 0.000039 0.000036 2003 1 3 52642 -0.094470 0.192855 -0.2901024 0.0002957 -0.000049 -0.000037 0.000074 0.000074 0.0000033 0.0000246 0.000039 0.000035 2003 1 4 52643 -0.097576 0.195433 -0.2903910 0.0003592 -0.000053 -0.000044 0.000074 0.000075 0.0000058 0.0000244 0.000039 0.000035 2003 1 5 52644 -0.100656 0.197637 -0.2907776 0.0004692 -0.000057 -0.000025 0.000075 0.000075 0.0000102 0.0000243 0.000039 0.000034 2003 1 6 52645 -0.103554 0.199542 -0.2913162 0.0006118 -0.000060 -0.000007 0.000075 0.000075 0.0000147 0.0000241 0.000039 0.000034 2003 1 7 52646 -0.105967 0.201423 -0.2920137 0.0007611 -0.000063 0.000012 0.000075 0.000075 0.0000191 0.0000240 0.000038 0.000033 2003 1 8 52647 -0.108585 0.203581 -0.2928409 0.0008631 -0.000099 0.000038 0.000075 0.000075 0.0000159 0.0000238 0.000039 0.000034 2003 1 9 52648 -0.111103 0.205623 -0.2937582 0.0008689 -0.000142 0.000066 0.000075 0.000075 0.0000108 0.0000237 0.000040 0.000035 2003 1 10 52649 -0.113163 0.208112 -0.2946408 0.0009212 -0.000081 -0.000024 0.000075 0.000075 0.0000041 0.0000236 0.000040 0.000035 2003 1 11 52650 -0.115240 0.210590 -0.2955754 0.0009178 -0.000065 -0.000036 0.000075 0.000076 0.0000023 0.0000235 0.000041 0.000036 2003 1 12 52651 -0.117285 0.212902 -0.2964746 0.0008216 -0.000078 -0.000004 0.000076 0.000076 0.0000026 0.0000235 0.000041 0.000036 2003 1 13 52652 -0.119012 0.214991 -0.2972604 0.0007358 -0.000091 0.000028 0.000076 0.000076 0.0000029 0.0000234 0.000041 0.000036 2003 1 14 52653 -0.120363 0.217102 -0.2979039 0.0005921 -0.000104 0.000060 0.000076 0.000076 0.0000032 0.0000233 0.000042 0.000037 2003 1 15 52654 -0.121697 0.219412 -0.2984007 0.0004240 -0.000096 0.000024 0.000076 0.000076 0.0000025 0.0000232 0.000042 0.000037 2003 1 16 52655 -0.122929 0.221767 -0.2987585 0.0002959 -0.000083 -0.000029 0.000076 0.000077 0.0000015 0.0000231 0.000042 0.000038 2003 1 17 52656 -0.124238 0.224328 -0.2989952 0.0001501 -0.000078 -0.000056 0.000077 0.000077 0.0000017 0.0000231 0.000043 0.000038 2003 1 18 52657 -0.126095 0.226730 -0.2992013 0.0001797 -0.000077 -0.000034 0.000077 0.000077 0.0000061 0.0000231 0.000043 0.000039 2003 1 19 52658 -0.127695 0.229010 -0.2994652 0.0003794 -0.000076 0.000002 0.000077 0.000077 0.0000119 0.0000231 0.000044 0.000039 2003 1 20 52659 -0.128820 0.231181 -0.2998665 0.0005116 -0.000075 0.000039 0.000077 0.000077 0.0000177 0.0000231 0.000044 0.000040 2003 1 21 52660 -0.129901 0.233614 -0.3004580 0.0005891 -0.000074 0.000075 0.000077 0.000077 0.0000235 0.0000231 0.000044 0.000040 2003 1 22 52661 -0.130921 0.236493 -0.3011546 0.0007421 -0.000147 0.000135 0.000077 0.000078 0.0000056 0.0000231 0.000045 0.000040 2003 1 23 52662 -0.132153 0.239989 -0.3019698 0.0008765 -0.000148 0.000153 0.000077 0.000078 0.0000130 0.0000231 0.000045 0.000040 2003 1 24 52663 -0.133562 0.242675 -0.3028630 0.0009493 -0.000024 0.000152 0.000078 0.000078 0.0000064 0.0000232 0.000045 0.000040 2003 1 25 52664 -0.135112 0.245044 -0.3037625 0.0008371 -0.000013 0.000122 0.000078 0.000078 0.0000025 0.0000233 0.000045 0.000040 2003 1 26 52665 -0.136860 0.247191 -0.3045163 0.0006141 -0.000056 0.000082 0.000078 0.000078 0.0000021 0.0000233 0.000045 0.000040 2003 1 27 52666 -0.138170 0.249505 -0.3050371 0.0004480 -0.000099 0.000042 0.000078 0.000078 0.0000016 0.0000233 0.000045 0.000039 2003 1 28 52667 -0.139063 0.252277 -0.3053147 0.0002284 -0.000142 0.000002 0.000078 0.000078 0.0000011 0.0000234 0.000045 0.000039 2003 1 29 52668 -0.139362 0.255314 -0.3053968 0.0000078 -0.000086 0.000019 0.000078 0.000079 0.0000031 0.0000234 0.000045 0.000039 2003 1 30 52669 -0.139317 0.258471 -0.3053857 -0.0000669 -0.000108 -0.000003 0.000078 0.000079 0.0000191 0.0000234 0.000045 0.000040 2003 1 31 52670 -0.139771 0.261553 -0.3053450 -0.0000401 -0.000096 -0.000062 0.000078 0.000079 0.0000105 0.0000234 0.000045 0.000040 2003 2 1 52671 -0.141099 0.264267 -0.3053256 -0.0000177 -0.000088 -0.000049 0.000078 0.000079 0.0000049 0.0000234 0.000045 0.000040 2003 2 2 52672 -0.142574 0.266929 -0.3054377 0.0001853 -0.000089 -0.000006 0.000079 0.000079 0.0000037 0.0000234 0.000045 0.000040 2003 2 3 52673 -0.144077 0.269862 -0.3057284 0.0003880 -0.000090 0.000036 0.000079 0.000079 0.0000026 0.0000234 0.000045 0.000039 2003 2 4 52674 -0.145329 0.272790 -0.3061862 0.0005907 -0.000091 0.000079 0.000079 0.000079 0.0000014 0.0000234 0.000045 0.000039 2003 2 5 52675 -0.146065 0.275623 -0.3068613 0.0007465 -0.000018 0.000086 0.000079 0.000079 0.0000042 0.0000234 0.000045 0.000039 2003 2 6 52676 -0.147291 0.278265 -0.3076315 0.0008221 0.000053 0.000069 0.000079 0.000079 0.0000039 0.0000234 0.000045 0.000040 2003 2 7 52677 -0.148324 0.280576 -0.3084175 0.0007487 0.000034 0.000042 0.000079 0.000079 0.0000024 0.0000233 0.000045 0.000040 2003 2 8 52678 -0.149527 0.283438 -0.3091170 0.0006867 -0.000007 0.000030 0.000079 0.000079 0.0000020 0.0000233 0.000045 0.000039 2003 2 9 52679 -0.151289 0.286170 -0.3097170 0.0005322 -0.000045 0.000025 0.000078 0.000079 0.0000020 0.0000233 0.000045 0.000039 2003 2 10 52680 -0.152964 0.288836 -0.3102081 0.0004285 -0.000083 0.000019 0.000078 0.000078 0.0000020 0.0000233 0.000045 0.000039 2003 2 11 52681 -0.154288 0.291587 -0.3105819 0.0003112 -0.000121 0.000014 0.000078 0.000078 0.0000020 0.0000233 0.000045 0.000039 2003 2 12 52682 -0.155415 0.294288 -0.3108697 0.0002354 -0.000052 -0.000006 0.000078 0.000078 0.0000016 0.0000233 0.000045 0.000039 2003 2 13 52683 -0.155947 0.297053 -0.3110928 0.0002538 0.000045 -0.000031 0.000078 0.000077 0.0000011 0.0000232 0.000044 0.000039 2003 2 14 52684 -0.156243 0.299709 -0.3113770 0.0003205 0.000023 -0.000098 0.000078 0.000077 0.0000017 0.0000232 0.000044 0.000039 2003 2 15 52685 -0.156352 0.302352 -0.3117118 0.0003617 -0.000011 -0.000090 0.000078 0.000077 0.0000066 0.0000231 0.000044 0.000039 2003 2 16 52686 -0.156356 0.304809 -0.3121977 0.0005599 -0.000035 -0.000049 0.000077 0.000077 0.0000129 0.0000230 0.000044 0.000039 2003 2 17 52687 -0.155738 0.307170 -0.3129257 0.0008139 -0.000059 -0.000008 0.000077 0.000076 0.0000192 0.0000229 0.000044 0.000039 2003 2 18 52688 -0.155179 0.310201 -0.3138875 0.0010357 -0.000083 0.000033 0.000077 0.000076 0.0000208 0.0000228 0.000044 0.000039 2003 2 19 52689 -0.154897 0.313731 -0.3149501 0.0012181 -0.000107 0.000073 0.000077 0.000076 0.0000049 0.0000227 0.000044 0.000039 2003 2 20 52690 -0.154595 0.317721 -0.3161952 0.0012634 -0.000058 0.000035 0.000077 0.000076 0.0000019 0.0000226 0.000044 0.000039 2003 2 21 52691 -0.155056 0.321738 -0.3174304 0.0012249 0.000010 -0.000023 0.000077 0.000076 0.0000021 0.0000225 0.000044 0.000039 2003 2 22 52692 -0.155489 0.324641 -0.3185333 0.0010309 0.000020 -0.000028 0.000077 0.000075 0.0000020 0.0000223 0.000044 0.000039 2003 2 23 52693 -0.155458 0.327548 -0.3193995 0.0006849 0.000008 -0.000014 0.000077 0.000075 0.0000018 0.0000222 0.000044 0.000039 2003 2 24 52694 -0.155050 0.330616 -0.3199944 0.0004531 -0.000005 0.000001 0.000076 0.000075 0.0000016 0.0000221 0.000044 0.000039 2003 2 25 52695 -0.154607 0.333626 -0.3203546 0.0003573 -0.000017 0.000015 0.000076 0.000075 0.0000013 0.0000219 0.000044 0.000039 2003 2 26 52696 -0.154535 0.336618 -0.3206238 0.0002296 -0.000025 -0.000020 0.000076 0.000075 0.0000148 0.0000218 0.000044 0.000040 2003 2 27 52697 -0.154696 0.339488 -0.3208523 0.0001655 -0.000034 -0.000069 0.000076 0.000074 0.0000318 0.0000218 0.000044 0.000040 2003 2 28 52698 -0.154353 0.342340 -0.3210599 0.0002253 0.000051 0.000062 0.000076 0.000074 0.0000147 0.0000219 0.000044 0.000040 2003 3 1 52699 -0.153849 0.344794 -0.3213284 0.0003096 0.000061 0.000100 0.000076 0.000074 0.0000061 0.0000219 0.000044 0.000040 2003 3 2 52700 -0.153096 0.347278 -0.3217267 0.0004710 0.000032 0.000082 0.000076 0.000074 0.0000046 0.0000220 0.000044 0.000039 2003 3 3 52701 -0.152721 0.350426 -0.3222652 0.0006153 0.000004 0.000064 0.000076 0.000074 0.0000031 0.0000220 0.000043 0.000039 2003 3 4 52702 -0.153024 0.353356 -0.3229181 0.0006624 -0.000024 0.000047 0.000076 0.000074 0.0000017 0.0000221 0.000043 0.000039 2003 3 5 52703 -0.153356 0.356077 -0.3236132 0.0006877 -0.000012 0.000138 0.000075 0.000074 0.0000016 0.0000222 0.000043 0.000038 2003 3 6 52704 -0.153744 0.358535 -0.3243197 0.0007049 -0.000057 0.000158 0.000075 0.000074 0.0000019 0.0000222 0.000042 0.000037 2003 3 7 52705 -0.154117 0.360926 -0.3249941 0.0007045 -0.000122 0.000147 0.000075 0.000074 0.0000021 0.0000223 0.000041 0.000036 2003 3 8 52706 -0.154519 0.363702 -0.3256560 0.0006189 -0.000119 0.000145 0.000075 0.000074 0.0000055 0.0000224 0.000041 0.000036 2003 3 9 52707 -0.154800 0.366529 -0.3262417 0.0005469 -0.000089 0.000146 0.000075 0.000074 0.0000100 0.0000225 0.000040 0.000035 2003 3 10 52708 -0.154791 0.369529 -0.3267221 0.0004353 -0.000060 0.000146 0.000075 0.000074 0.0000146 0.0000225 0.000040 0.000034 2003 3 11 52709 -0.155560 0.372650 -0.3271095 0.0003543 -0.000030 0.000147 0.000075 0.000074 0.0000191 0.0000226 0.000039 0.000033 2003 3 12 52710 -0.156470 0.375685 -0.3274389 0.0003161 0.000011 0.000124 0.000075 0.000074 0.0000200 0.0000226 0.000039 0.000033 2003 3 13 52711 -0.157077 0.378857 -0.3277590 0.0003150 0.000056 0.000095 0.000075 0.000074 0.0000200 0.0000226 0.000039 0.000032 2003 3 14 52712 -0.157462 0.381670 -0.3281156 0.0003932 0.000044 0.000114 0.000075 0.000074 0.0000077 0.0000227 0.000039 0.000032 2003 3 15 52713 -0.157201 0.384138 -0.3286184 0.0005537 0.000033 0.000111 0.000075 0.000074 0.0000029 0.0000227 0.000039 0.000033 2003 3 16 52714 -0.156933 0.387101 -0.3293608 0.0008153 0.000028 0.000092 0.000074 0.000074 0.0000023 0.0000228 0.000039 0.000033 2003 3 17 52715 -0.156710 0.389936 -0.3303942 0.0011969 0.000024 0.000074 0.000074 0.000074 0.0000017 0.0000228 0.000039 0.000034 2003 3 18 52716 -0.156037 0.392827 -0.3317057 0.0014301 0.000020 0.000055 0.000074 0.000074 0.0000012 0.0000228 0.000040 0.000035 2003 3 19 52717 -0.154945 0.395852 -0.3332181 0.0015361 -0.000132 -0.000150 0.000074 0.000074 0.0000069 0.0000228 0.000040 0.000035 2003 3 20 52718 -0.153782 0.399794 -0.3347522 0.0014969 -0.000114 -0.000143 0.000074 0.000074 0.0000058 0.0000228 0.000040 0.000036 2003 3 21 52719 -0.153126 0.403719 -0.3361518 0.0012885 -0.000036 -0.000060 0.000074 0.000074 0.0000022 0.0000228 0.000040 0.000036 2003 3 22 52720 -0.152313 0.406835 -0.3372928 0.0009930 -0.000012 -0.000022 0.000074 0.000074 0.0000014 0.0000228 0.000041 0.000037 2003 3 23 52721 -0.151514 0.409834 -0.3381203 0.0006299 -0.000007 -0.000001 0.000074 0.000074 0.0000016 0.0000228 0.000041 0.000037 2003 3 24 52722 -0.150569 0.412600 -0.3386600 0.0003907 -0.000003 0.000021 0.000074 0.000074 0.0000019 0.0000228 0.000041 0.000038 2003 3 25 52723 -0.149108 0.415551 -0.3389983 0.0002975 0.000002 0.000042 0.000074 0.000074 0.0000021 0.0000227 0.000042 0.000038 2003 3 26 52724 -0.147594 0.418522 -0.3392541 0.0002151 0.000027 -0.000006 0.000074 0.000074 0.0000021 0.0000227 0.000042 0.000039 2003 3 27 52725 -0.145818 0.421332 -0.3395330 0.0002996 0.000068 -0.000018 0.000074 0.000074 0.0000021 0.0000228 0.000042 0.000039 2003 3 28 52726 -0.143390 0.424229 -0.3399295 0.0004409 0.000064 0.000005 0.000074 0.000074 0.0000028 0.0000228 0.000042 0.000039 2003 3 29 52727 -0.140614 0.427059 -0.3404593 0.0005933 0.000050 0.000006 0.000074 0.000074 0.0000029 0.0000230 0.000042 0.000039 2003 3 30 52728 -0.137753 0.430056 -0.3411445 0.0007846 0.000039 -0.000002 0.000074 0.000074 0.0000026 0.0000231 0.000042 0.000039 2003 3 31 52729 -0.135312 0.433070 -0.3419749 0.0008878 0.000027 -0.000011 0.000073 0.000074 0.0000023 0.0000232 0.000042 0.000040 2003 4 1 52730 -0.133278 0.435795 -0.3429089 0.0009209 0.000015 -0.000020 0.000073 0.000074 0.0000020 0.0000233 0.000042 0.000040 2003 4 2 52731 -0.131283 0.438766 -0.3439029 0.0010073 0.000067 0.000002 0.000073 0.000074 0.0000045 0.0000234 0.000042 0.000040 2003 4 3 52732 -0.129062 0.441945 -0.3448845 0.0009929 0.000135 0.000031 0.000073 0.000073 0.0000064 0.0000236 0.000042 0.000040 2003 4 4 52733 -0.127010 0.444933 -0.3457871 0.0008614 0.000202 0.000060 0.000073 0.000073 0.0000034 0.0000237 0.000042 0.000040 2003 4 5 52734 -0.124693 0.447663 -0.3466145 0.0008228 0.000193 0.000082 0.000073 0.000073 0.0000024 0.0000239 0.000042 0.000040 2003 4 6 52735 -0.122107 0.450921 -0.3473208 0.0006652 0.000155 0.000102 0.000072 0.000073 0.0000022 0.0000240 0.000042 0.000040 2003 4 7 52736 -0.119732 0.454312 -0.3478923 0.0005034 0.000117 0.000121 0.000072 0.000072 0.0000020 0.0000241 0.000042 0.000040 2003 4 8 52737 -0.117650 0.457220 -0.3483517 0.0004093 0.000079 0.000141 0.000072 0.000072 0.0000018 0.0000243 0.000042 0.000040 2003 4 9 52738 -0.116085 0.459954 -0.3487037 0.0003222 0.000121 0.000124 0.000072 0.000072 0.0000130 0.0000244 0.000042 0.000040 2003 4 10 52739 -0.114728 0.462602 -0.3490221 0.0003408 0.000132 0.000105 0.000072 0.000072 0.0000111 0.0000245 0.000042 0.000040 2003 4 11 52740 -0.113336 0.465062 -0.3494097 0.0004388 0.000129 0.000087 0.000072 0.000071 0.0000047 0.0000245 0.000041 0.000039 2003 4 12 52741 -0.111454 0.467643 -0.3500279 0.0006366 0.000119 0.000066 0.000071 0.000071 0.0000061 0.0000246 0.000041 0.000039 2003 4 13 52742 -0.109355 0.470581 -0.3508580 0.0009197 0.000106 0.000044 0.000071 0.000071 0.0000104 0.0000247 0.000040 0.000038 2003 4 14 52743 -0.107142 0.473073 -0.3519321 0.0012350 0.000093 0.000022 0.000071 0.000071 0.0000148 0.0000247 0.000040 0.000038 2003 4 15 52744 -0.105275 0.475586 -0.3532350 0.0014439 0.000080 0.000000 0.000071 0.000071 0.0000191 0.0000247 0.000040 0.000038 2003 4 16 52745 -0.103926 0.477661 -0.3546994 0.0015010 0.000079 0.000034 0.000071 0.000071 0.0000132 0.0000248 0.000039 0.000037 2003 4 17 52746 -0.102324 0.479421 -0.3561213 0.0012941 0.000082 0.000083 0.000071 0.000071 0.0000046 0.0000248 0.000039 0.000037 2003 4 18 52747 -0.100367 0.481349 -0.3573237 0.0010380 0.000081 0.000078 0.000071 0.000071 0.0000083 0.0000248 0.000039 0.000037 2003 4 19 52748 -0.098132 0.483592 -0.3581973 0.0006903 0.000080 0.000052 0.000071 0.000071 0.0000122 0.0000248 0.000039 0.000037 2003 4 20 52749 -0.095481 0.485872 -0.3586675 0.0003236 0.000079 0.000025 0.000071 0.000070 0.0000109 0.0000249 0.000039 0.000037 2003 4 21 52750 -0.093075 0.488020 -0.3588496 0.0000808 0.000078 -0.000001 0.000071 0.000070 0.0000151 0.0000249 0.000038 0.000037 2003 4 22 52751 -0.090732 0.489881 -0.3588837 -0.0000001 0.000077 -0.000027 0.000071 0.000070 0.0000192 0.0000248 0.000038 0.000037 2003 4 23 52752 -0.088640 0.491975 -0.3589154 0.0000741 0.000077 0.000019 0.000071 0.000070 0.0000126 0.0000248 0.000038 0.000037 2003 4 24 52753 -0.086040 0.493929 -0.3590294 0.0001442 0.000125 0.000006 0.000071 0.000070 0.0000033 0.0000248 0.000038 0.000036 2003 4 25 52754 -0.082786 0.495914 -0.3592827 0.0003421 0.000147 0.000050 0.000071 0.000070 0.0000015 0.0000248 0.000038 0.000036 2003 4 26 52755 -0.079982 0.498263 -0.3597071 0.0004633 0.000148 0.000073 0.000071 0.000070 0.0000015 0.0000248 0.000038 0.000036 2003 4 27 52756 -0.077659 0.500297 -0.3602748 0.0006162 0.000145 0.000077 0.000071 0.000070 0.0000015 0.0000247 0.000038 0.000036 2003 4 28 52757 -0.075235 0.502705 -0.3609405 0.0007058 0.000142 0.000082 0.000071 0.000070 0.0000014 0.0000247 0.000038 0.000036 2003 4 29 52758 -0.072945 0.504679 -0.3616498 0.0007613 0.000139 0.000086 0.000071 0.000070 0.0000013 0.0000246 0.000038 0.000036 2003 4 30 52759 -0.070445 0.506411 -0.3624025 0.0007488 0.000087 0.000095 0.000071 0.000070 0.0000016 0.0000246 0.000038 0.000036 2003 5 1 52760 -0.066975 0.508184 -0.3630912 0.0006301 0.000085 0.000101 0.000071 0.000070 0.0000057 0.0000245 0.000038 0.000036 2003 5 2 52761 -0.063131 0.510122 -0.3636379 0.0004608 0.000108 0.000105 0.000071 0.000070 0.0000098 0.0000245 0.000038 0.000036 2003 5 3 52762 -0.059450 0.511754 -0.3639690 0.0002653 0.000130 0.000110 0.000071 0.000070 0.0000081 0.0000244 0.000038 0.000036 2003 5 4 52763 -0.056097 0.513622 -0.3641128 0.0000934 0.000152 0.000114 0.000071 0.000070 0.0000061 0.0000244 0.000038 0.000036 2003 5 5 52764 -0.053251 0.515619 -0.3641160 -0.0001024 0.000174 0.000118 0.000071 0.000070 0.0000042 0.0000243 0.000038 0.000036 2003 5 6 52765 -0.050190 0.517716 -0.3640238 -0.0000987 0.000197 0.000122 0.000071 0.000070 0.0000022 0.0000242 0.000038 0.000036 2003 5 7 52766 -0.047203 0.519978 -0.3639005 -0.0001053 0.000257 0.000082 0.000071 0.000070 0.0000016 0.0000241 0.000038 0.000036 2003 5 8 52767 -0.044674 0.521838 -0.3638253 -0.0000270 0.000180 0.000061 0.000071 0.000070 0.0000014 0.0000240 0.000038 0.000036 2003 5 9 52768 -0.042140 0.523547 -0.3639068 0.0001575 0.000067 0.000094 0.000071 0.000070 0.0000018 0.0000239 0.000038 0.000036 2003 5 10 52769 -0.039675 0.525328 -0.3642674 0.0003890 0.000054 0.000088 0.000071 0.000069 0.0000077 0.0000238 0.000038 0.000037 2003 5 11 52770 -0.037708 0.526863 -0.3648076 0.0006290 0.000077 0.000062 0.000071 0.000069 0.0000082 0.0000237 0.000038 0.000037 2003 5 12 52771 -0.036050 0.528129 -0.3655747 0.0009085 0.000101 0.000035 0.000071 0.000069 0.0000049 0.0000236 0.000039 0.000038 2003 5 13 52772 -0.034497 0.529554 -0.3665649 0.0011343 0.000124 0.000009 0.000071 0.000069 0.0000017 0.0000235 0.000039 0.000038 2003 5 14 52773 -0.032631 0.530820 -0.3677701 0.0011975 0.000180 0.000358 0.000071 0.000069 0.0000015 0.0000234 0.000040 0.000038 2003 5 15 52774 -0.030467 0.532074 -0.3689375 0.0011211 0.000204 0.000275 0.000070 0.000069 0.0000020 0.0000233 0.000040 0.000039 2003 5 16 52775 -0.028221 0.533378 -0.3698946 0.0008482 0.000215 0.000031 0.000070 0.000069 0.0000026 0.0000233 0.000040 0.000039 2003 5 17 52776 -0.025920 0.534528 -0.3705519 0.0005019 0.000206 0.000009 0.000070 0.000069 0.0000048 0.0000232 0.000040 0.000039 2003 5 18 52777 -0.023650 0.535750 -0.3709147 0.0002355 0.000189 0.000071 0.000070 0.000069 0.0000050 0.0000231 0.000041 0.000039 2003 5 19 52778 -0.021383 0.536747 -0.3710931 0.0001221 0.000172 0.000132 0.000070 0.000069 0.0000038 0.0000230 0.000041 0.000039 2003 5 20 52779 -0.018647 0.537687 -0.3712212 0.0001624 0.000155 0.000194 0.000071 0.000069 0.0000027 0.0000230 0.000041 0.000039 2003 5 21 52780 -0.015466 0.538879 -0.3714259 0.0002347 0.000166 0.000099 0.000071 0.000070 0.0000035 0.0000229 0.000041 0.000040 2003 5 22 52781 -0.012505 0.539926 -0.3717454 0.0003862 0.000235 -0.000030 0.000071 0.000070 0.0000034 0.0000228 0.000042 0.000040 2003 5 23 52782 -0.009823 0.540834 -0.3721989 0.0005011 0.000188 -0.000039 0.000071 0.000070 0.0000023 0.0000228 0.000042 0.000040 2003 5 24 52783 -0.007001 0.541231 -0.3728384 0.0006090 0.000151 -0.000024 0.000071 0.000070 0.0000077 0.0000227 0.000042 0.000040 2003 5 25 52784 -0.004038 0.541454 -0.3734870 0.0006622 0.000134 -0.000014 0.000071 0.000070 0.0000088 0.0000226 0.000042 0.000040 2003 5 26 52785 -0.001013 0.541717 -0.3741091 0.0006616 0.000117 -0.000004 0.000071 0.000070 0.0000066 0.0000226 0.000042 0.000040 2003 5 27 52786 0.002399 0.542207 -0.3746898 0.0005688 0.000100 0.000006 0.000071 0.000070 0.0000043 0.0000225 0.000041 0.000040 2003 5 28 52787 0.005897 0.542914 -0.3751699 0.0004614 0.000083 0.000016 0.000071 0.000070 0.0000021 0.0000224 0.000041 0.000040 2003 5 29 52788 0.009385 0.543905 -0.3755545 0.0003189 0.000094 -0.000060 0.000071 0.000070 0.0000179 0.0000224 0.000042 0.000040 2003 5 30 52789 0.012554 0.544850 -0.3757786 0.0001538 0.000176 0.000044 0.000071 0.000070 0.0000071 0.0000223 0.000041 0.000039 2003 5 31 52790 0.015654 0.545760 -0.3758113 -0.0000530 0.000215 0.000090 0.000071 0.000070 0.0000049 0.0000222 0.000041 0.000039 2003 6 1 52791 0.018457 0.546694 -0.3756586 -0.0002061 0.000230 0.000090 0.000071 0.000070 0.0000096 0.0000222 0.000041 0.000039 2003 6 2 52792 0.021330 0.547246 -0.3753574 -0.0003437 0.000244 0.000091 0.000071 0.000070 0.0000143 0.0000221 0.000041 0.000038 2003 6 3 52793 0.024300 0.547834 -0.3749686 -0.0004430 0.000259 0.000091 0.000071 0.000070 0.0000190 0.0000220 0.000041 0.000038 2003 6 4 52794 0.027743 0.548009 -0.3745405 -0.0004763 0.000222 0.000050 0.000071 0.000070 0.0000203 0.0000219 0.000041 0.000038 2003 6 5 52795 0.031567 0.548118 -0.3741427 -0.0004282 0.000171 -0.000003 0.000070 0.000070 0.0000182 0.0000218 0.000041 0.000038 2003 6 6 52796 0.035059 0.548104 -0.3737683 -0.0002507 0.000121 -0.000055 0.000070 0.000070 0.0000066 0.0000217 0.000042 0.000039 2003 6 7 52797 0.038191 0.548068 -0.3736959 0.0000260 0.000098 -0.000036 0.000070 0.000069 0.0000201 0.0000216 0.000042 0.000039 2003 6 8 52798 0.041359 0.548061 -0.3738944 0.0002747 0.000086 0.000010 0.000070 0.000069 0.0000221 0.0000215 0.000042 0.000039 2003 6 9 52799 0.044795 0.548141 -0.3742871 0.0004889 0.000074 0.000056 0.000070 0.000069 0.0000132 0.0000213 0.000042 0.000040 2003 6 10 52800 0.048331 0.548256 -0.3747758 0.0005291 0.000061 0.000102 0.000070 0.000069 0.0000042 0.0000212 0.000042 0.000040 2003 6 11 52801 0.051775 0.548417 -0.3753160 0.0004205 0.000155 0.000038 0.000070 0.000069 0.0000106 0.0000211 0.000043 0.000040 2003 6 12 52802 0.055242 0.547989 -0.3756720 0.0001907 0.000276 -0.000054 0.000070 0.000069 0.0000175 0.0000210 0.000043 0.000041 2003 6 13 52803 0.058733 0.547515 -0.3756368 -0.0001082 0.000397 -0.000146 0.000070 0.000069 0.0000119 0.0000209 0.000043 0.000041 2003 6 14 52804 0.062057 0.546849 -0.3753290 -0.0004345 0.000365 -0.000162 0.000069 0.000069 0.0000156 0.0000208 0.000043 0.000041 2003 6 15 52805 0.065804 0.546382 -0.3747764 -0.0006505 0.000277 -0.000150 0.000069 0.000069 0.0000149 0.0000207 0.000043 0.000041 2003 6 16 52806 0.069706 0.545819 -0.3740969 -0.0007261 0.000189 -0.000138 0.000069 0.000068 0.0000102 0.0000206 0.000043 0.000041 2003 6 17 52807 0.074065 0.545227 -0.3734277 -0.0006458 0.000101 -0.000127 0.000070 0.000069 0.0000054 0.0000205 0.000043 0.000041 2003 6 18 52808 0.078586 0.545099 -0.3728949 -0.0005065 0.000009 -0.000081 0.000070 0.000069 0.0000129 0.0000204 0.000043 0.000041 2003 6 19 52809 0.083051 0.544896 -0.3724766 -0.0003424 0.000050 -0.000080 0.000070 0.000068 0.0000051 0.0000203 0.000042 0.000041 2003 6 20 52810 0.087774 0.544778 -0.3722358 -0.0001538 0.000277 -0.000112 0.000070 0.000068 0.0000036 0.0000203 0.000042 0.000041 2003 6 21 52811 0.092038 0.544732 -0.3721088 -0.0000679 0.000329 -0.000110 0.000069 0.000068 0.0000038 0.0000203 0.000042 0.000041 2003 6 22 52812 0.095892 0.544298 -0.3720318 -0.0000263 0.000298 -0.000093 0.000069 0.000068 0.0000031 0.0000203 0.000042 0.000041 2003 6 23 52813 0.099870 0.543853 -0.3719484 -0.0000745 0.000267 -0.000077 0.000069 0.000068 0.0000025 0.0000202 0.000042 0.000041 2003 6 24 52814 0.103545 0.543334 -0.3718022 -0.0001997 0.000236 -0.000060 0.000069 0.000068 0.0000018 0.0000202 0.000042 0.000041 2003 6 25 52815 0.107288 0.542674 -0.3715214 -0.0003203 -0.000054 0.000226 0.000069 0.000068 0.0000063 0.0000202 0.000043 0.000041 2003 6 26 52816 0.110945 0.542280 -0.3711000 -0.0004733 -0.000067 0.000264 0.000069 0.000068 0.0000099 0.0000203 0.000042 0.000040 2003 6 27 52817 0.114760 0.541687 -0.3705589 -0.0006083 0.000022 0.000206 0.000069 0.000068 0.0000052 0.0000203 0.000042 0.000040 2003 6 28 52818 0.118644 0.541223 -0.3698898 -0.0007967 0.000076 0.000124 0.000069 0.000068 0.0000068 0.0000204 0.000042 0.000040 2003 6 29 52819 0.122644 0.540586 -0.3690694 -0.0008822 0.000116 0.000034 0.000069 0.000068 0.0000066 0.0000205 0.000042 0.000039 2003 6 30 52820 0.126832 0.540074 -0.3681546 -0.0009073 0.000157 -0.000057 0.000069 0.000068 0.0000042 0.0000205 0.000042 0.000039 2003 7 1 52821 0.130520 0.539565 -0.3672304 -0.0008715 0.000198 -0.000148 0.000069 0.000068 0.0000018 0.0000205 0.000042 0.000039 2003 7 2 52822 0.134007 0.538879 -0.3663884 -0.0007803 0.000207 -0.000101 0.000069 0.000068 0.0000023 0.0000206 0.000041 0.000038 2003 7 3 52823 0.137022 0.537812 -0.3656851 -0.0006413 0.000208 -0.000018 0.000069 0.000068 0.0000035 0.0000207 0.000041 0.000038 2003 7 4 52824 0.139941 0.536118 -0.3651224 -0.0004681 0.000214 -0.000016 0.000069 0.000067 0.0000037 0.0000207 0.000041 0.000038 2003 7 5 52825 0.143110 0.534266 -0.3647389 -0.0003110 0.000221 -0.000043 0.000068 0.000067 0.0000037 0.0000208 0.000041 0.000037 2003 7 6 52826 0.146587 0.532790 -0.3645198 -0.0001720 0.000229 -0.000070 0.000068 0.000067 0.0000036 0.0000208 0.000040 0.000037 2003 7 7 52827 0.149618 0.531456 -0.3643933 -0.0001336 0.000237 -0.000097 0.000068 0.000067 0.0000036 0.0000208 0.000040 0.000037 2003 7 8 52828 0.153100 0.529993 -0.3642563 -0.0001964 0.000245 -0.000124 0.000068 0.000067 0.0000035 0.0000207 0.000040 0.000036 2003 7 9 52829 0.156681 0.528473 -0.3639952 -0.0003828 0.000169 -0.000156 0.000069 0.000068 0.0000099 0.0000208 0.000039 0.000036 2003 7 10 52830 0.160541 0.526803 -0.3635256 -0.0005915 0.000072 -0.000191 0.000069 0.000068 0.0000180 0.0000207 0.000039 0.000036 2003 7 11 52831 0.164078 0.525583 -0.3628065 -0.0008442 0.000224 -0.000133 0.000069 0.000068 0.0000079 0.0000207 0.000039 0.000036 2003 7 12 52832 0.167614 0.524131 -0.3619517 -0.0009723 0.000293 -0.000079 0.000069 0.000068 0.0000108 0.0000207 0.000040 0.000037 2003 7 13 52833 0.170683 0.522956 -0.3609902 -0.0009769 0.000302 -0.000038 0.000069 0.000068 0.0000112 0.0000206 0.000041 0.000038 2003 7 14 52834 0.173194 0.521428 -0.3600365 -0.0009001 0.000311 0.000003 0.000069 0.000068 0.0000069 0.0000206 0.000041 0.000038 2003 7 15 52835 0.175676 0.519909 -0.3592165 -0.0007520 0.000320 0.000044 0.000069 0.000068 0.0000026 0.0000205 0.000042 0.000039 2003 7 16 52836 0.178211 0.518361 -0.3586081 -0.0005306 0.000229 -0.000086 0.000069 0.000068 0.0000059 0.0000205 0.000043 0.000040 2003 7 17 52837 0.180996 0.516833 -0.3582315 -0.0002951 0.000155 -0.000214 0.000069 0.000068 0.0000030 0.0000205 0.000043 0.000041 2003 7 18 52838 0.183577 0.514978 -0.3580166 -0.0001430 0.000038 -0.000270 0.000069 0.000068 0.0000020 0.0000205 0.000044 0.000041 2003 7 19 52839 0.186328 0.512860 -0.3578685 -0.0001118 0.000012 -0.000273 0.000069 0.000068 0.0000020 0.0000206 0.000045 0.000041 2003 7 20 52840 0.189402 0.510846 -0.3577482 -0.0001076 0.000025 -0.000262 0.000069 0.000068 0.0000020 0.0000207 0.000045 0.000042 2003 7 21 52841 0.192070 0.508839 -0.3576060 -0.0001994 0.000038 -0.000252 0.000069 0.000068 0.0000020 0.0000207 0.000046 0.000042 2003 7 22 52842 0.194352 0.506515 -0.3573904 -0.0002860 0.000051 -0.000241 0.000069 0.000068 0.0000019 0.0000208 0.000046 0.000042 2003 7 23 52843 0.197199 0.504038 -0.3570946 -0.0004151 0.000244 -0.000256 0.000069 0.000068 0.0000062 0.0000209 0.000047 0.000043 2003 7 24 52844 0.200047 0.501804 -0.3566648 -0.0005249 0.000484 -0.000277 0.000069 0.000067 0.0000094 0.0000210 0.000048 0.000043 2003 7 25 52845 0.202558 0.499792 -0.3560520 -0.0006360 0.000346 -0.000023 0.000069 0.000067 0.0000046 0.0000211 0.000048 0.000044 2003 7 26 52846 0.204779 0.497473 -0.3554227 -0.0006608 0.000237 0.000012 0.000068 0.000067 0.0000033 0.0000212 0.000049 0.000044 2003 7 27 52847 0.206853 0.495025 -0.3547735 -0.0006198 0.000182 -0.000065 0.000068 0.000067 0.0000034 0.0000213 0.000049 0.000044 2003 7 28 52848 0.208982 0.492356 -0.3541406 -0.0005841 0.000126 -0.000142 0.000068 0.000067 0.0000034 0.0000213 0.000050 0.000044 2003 7 29 52849 0.211282 0.489445 -0.3536011 -0.0005137 0.000071 -0.000220 0.000068 0.000067 0.0000035 0.0000214 0.000051 0.000045 2003 7 30 52850 0.213780 0.486614 -0.3532822 -0.0002986 0.000353 0.000068 0.000068 0.000067 0.0000078 0.0000214 0.000051 0.000045 2003 7 31 52851 0.216563 0.484040 -0.3531586 -0.0000656 0.000352 0.000005 0.000068 0.000066 0.0000108 0.0000215 0.000052 0.000045 2003 8 1 52852 0.219232 0.481745 -0.3531137 0.0001234 0.000241 -0.000192 0.000068 0.000066 0.0000048 0.0000215 0.000052 0.000045 2003 8 2 52853 0.221546 0.479741 -0.3533370 0.0002875 0.000201 -0.000239 0.000068 0.000066 0.0000032 0.0000215 0.000052 0.000045 2003 8 3 52854 0.223049 0.477497 -0.3537008 0.0003762 0.000188 -0.000232 0.000067 0.000066 0.0000032 0.0000216 0.000052 0.000045 2003 8 4 52855 0.224816 0.474958 -0.3540657 0.0003465 0.000174 -0.000224 0.000067 0.000066 0.0000031 0.0000216 0.000053 0.000045 2003 8 5 52856 0.226391 0.472627 -0.3543153 0.0001814 0.000160 -0.000217 0.000067 0.000066 0.0000031 0.0000216 0.000053 0.000045 2003 8 6 52857 0.228148 0.469865 -0.3544122 -0.0000622 0.000157 -0.000229 0.000067 0.000065 0.0000052 0.0000216 0.000053 0.000045 2003 8 7 52858 0.230140 0.466789 -0.3542497 -0.0002818 0.000156 -0.000246 0.000067 0.000065 0.0000071 0.0000216 0.000054 0.000046 2003 8 8 52859 0.232229 0.463851 -0.3537530 -0.0005252 0.000156 -0.000263 0.000067 0.000065 0.0000054 0.0000216 0.000054 0.000046 2003 8 9 52860 0.234048 0.461232 -0.3531687 -0.0006303 0.000293 0.000078 0.000067 0.000065 0.0000046 0.0000216 0.000054 0.000046 2003 8 10 52861 0.235920 0.458976 -0.3525799 -0.0005642 0.000394 0.000312 0.000067 0.000065 0.0000040 0.0000216 0.000055 0.000047 2003 8 11 52862 0.237711 0.457020 -0.3520840 -0.0003865 0.000311 0.000037 0.000066 0.000065 0.0000034 0.0000216 0.000055 0.000047 2003 8 12 52863 0.239586 0.454681 -0.3517652 -0.0002126 0.000228 -0.000237 0.000066 0.000064 0.0000028 0.0000216 0.000055 0.000048 2003 8 13 52864 0.241357 0.452363 -0.3516701 0.0000008 0.000096 -0.000352 0.000066 0.000064 0.0000049 0.0000215 0.000055 0.000049 2003 8 14 52865 0.243114 0.449934 -0.3517665 0.0001768 0.000191 -0.000324 0.000066 0.000064 0.0000054 0.0000215 0.000055 0.000049 2003 8 15 52866 0.244711 0.447708 -0.3519919 0.0002748 0.000356 -0.000268 0.000066 0.000064 0.0000051 0.0000214 0.000055 0.000049 2003 8 16 52867 0.245953 0.445036 -0.3523138 0.0003112 0.000335 -0.000241 0.000066 0.000064 0.0000045 0.0000213 0.000055 0.000049 2003 8 17 52868 0.247564 0.441943 -0.3526224 0.0003082 0.000247 -0.000225 0.000066 0.000064 0.0000038 0.0000212 0.000055 0.000049 2003 8 18 52869 0.249161 0.438902 -0.3528316 0.0001768 0.000158 -0.000209 0.000066 0.000064 0.0000031 0.0000210 0.000055 0.000049 2003 8 19 52870 0.250634 0.435652 -0.3528921 -0.0000468 0.000069 -0.000193 0.000066 0.000064 0.0000024 0.0000208 0.000055 0.000049 2003 8 20 52871 0.252296 0.432590 -0.3526916 -0.0002704 0.000145 -0.000335 0.000066 0.000064 0.0000386 0.0000207 0.000055 0.000050 2003 8 21 52872 0.253810 0.429909 -0.3522963 -0.0004465 0.000264 -0.000518 0.000066 0.000064 0.0000844 0.0000205 0.000055 0.000050 2003 8 22 52873 0.255078 0.427475 -0.3518205 -0.0005666 0.000191 -0.000456 0.000066 0.000064 0.0000276 0.0000203 0.000055 0.000049 2003 8 23 52874 0.255893 0.425189 -0.3512706 -0.0006195 0.000124 -0.000363 0.000067 0.000065 0.0000129 0.0000201 0.000054 0.000049 2003 8 24 52875 0.256967 0.422302 -0.3506192 -0.0006293 0.000084 -0.000289 0.000067 0.000065 0.0000145 0.0000199 0.000054 0.000049 2003 8 25 52876 0.258269 0.419048 -0.3499921 -0.0005379 0.000043 -0.000214 0.000067 0.000065 0.0000101 0.0000196 0.000054 0.000049 2003 8 26 52877 0.259380 0.415902 -0.3495234 -0.0003692 0.000003 -0.000140 0.000067 0.000065 0.0000057 0.0000194 0.000054 0.000048 2003 8 27 52878 0.260081 0.412566 -0.3493290 -0.0000838 -0.000022 -0.000191 0.000067 0.000065 0.0000039 0.0000191 0.000053 0.000048 2003 8 28 52879 0.261206 0.409186 -0.3494338 0.0003337 0.000002 -0.000258 0.000067 0.000065 0.0000027 0.0000189 0.000053 0.000048 2003 8 29 52880 0.262387 0.406372 -0.3498610 0.0005516 0.000138 -0.000233 0.000068 0.000065 0.0000026 0.0000186 0.000053 0.000047 2003 8 30 52881 0.263379 0.403477 -0.3505902 0.0007286 0.000139 -0.000191 0.000068 0.000066 0.0000177 0.0000184 0.000053 0.000047 2003 8 31 52882 0.264482 0.400742 -0.3513423 0.0008291 0.000078 -0.000154 0.000068 0.000066 0.0000206 0.0000181 0.000052 0.000047 2003 9 1 52883 0.265362 0.397675 -0.3519826 0.0005928 0.000017 -0.000117 0.000068 0.000065 0.0000145 0.0000179 0.000052 0.000046 2003 9 2 52884 0.265674 0.394646 -0.3524338 0.0003446 -0.000045 -0.000081 0.000067 0.000065 0.0000085 0.0000176 0.000052 0.000046 2003 9 3 52885 0.265422 0.391453 -0.3526331 0.0000616 0.000101 -0.000078 0.000067 0.000065 0.0000024 0.0000173 0.000051 0.000045 2003 9 4 52886 0.265394 0.388163 -0.3525710 -0.0001645 0.000146 -0.000125 0.000067 0.000065 0.0000185 0.0000171 0.000051 0.000045 2003 9 5 52887 0.265283 0.384726 -0.3523580 -0.0002907 0.000188 -0.000209 0.000067 0.000065 0.0000076 0.0000168 0.000051 0.000045 2003 9 6 52888 0.265171 0.380992 -0.3521375 -0.0003202 0.000196 -0.000235 0.000067 0.000065 0.0000112 0.0000165 0.000051 0.000044 2003 9 7 52889 0.265081 0.377663 -0.3518478 -0.0002325 0.000188 -0.000237 0.000067 0.000065 0.0000126 0.0000162 0.000050 0.000044 2003 9 8 52890 0.264970 0.374381 -0.3516188 -0.0001199 0.000180 -0.000240 0.000067 0.000065 0.0000081 0.0000159 0.000050 0.000043 2003 9 9 52891 0.264717 0.371404 -0.3515630 0.0000865 0.000172 -0.000242 0.000067 0.000065 0.0000036 0.0000156 0.000050 0.000043 2003 9 10 52892 0.264446 0.368082 -0.3517338 0.0002578 0.000158 -0.000218 0.000067 0.000065 0.0000024 0.0000153 0.000050 0.000043 2003 9 11 52893 0.264748 0.364714 -0.3520572 0.0003875 0.000142 -0.000188 0.000067 0.000065 0.0000020 0.0000150 0.000049 0.000042 2003 9 12 52894 0.264508 0.361557 -0.3524534 0.0003752 0.000065 -0.000164 0.000067 0.000065 0.0000017 0.0000147 0.000049 0.000042 2003 9 13 52895 0.264228 0.358116 -0.3528634 0.0003158 0.000104 -0.000115 0.000067 0.000066 0.0000115 0.0000144 0.000049 0.000042 2003 9 14 52896 0.264263 0.354942 -0.3531921 0.0002253 0.000194 -0.000056 0.000067 0.000066 0.0000129 0.0000140 0.000048 0.000042 2003 9 15 52897 0.264293 0.351908 -0.3533972 0.0001854 0.000100 -0.000088 0.000067 0.000066 0.0000081 0.0000139 0.000048 0.000041 2003 9 16 52898 0.264182 0.349059 -0.3534614 0.0000749 -0.000020 -0.000132 0.000067 0.000066 0.0000033 0.0000140 0.000047 0.000041 2003 9 17 52899 0.264031 0.346142 -0.3534919 -0.0000324 -0.000067 -0.000091 0.000067 0.000066 0.0000131 0.0000143 0.000047 0.000040 2003 9 18 52900 0.263977 0.343201 -0.3533475 -0.0001930 0.000042 -0.000081 0.000068 0.000066 0.0000048 0.0000146 0.000047 0.000040 2003 9 19 52901 0.263777 0.340003 -0.3530907 -0.0002860 0.000175 -0.000169 0.000068 0.000066 0.0000034 0.0000149 0.000046 0.000039 2003 9 20 52902 0.263071 0.336649 -0.3528608 -0.0002765 0.000205 -0.000195 0.000068 0.000066 0.0000107 0.0000152 0.000046 0.000040 2003 9 21 52903 0.262433 0.332988 -0.3526150 -0.0002516 0.000198 -0.000188 0.000068 0.000067 0.0000109 0.0000155 0.000046 0.000040 2003 9 22 52904 0.262577 0.329751 -0.3524485 -0.0000448 0.000191 -0.000180 0.000068 0.000067 0.0000067 0.0000158 0.000046 0.000040 2003 9 23 52905 0.262639 0.327218 -0.3524807 0.0001891 0.000184 -0.000173 0.000068 0.000067 0.0000025 0.0000161 0.000046 0.000041 2003 9 24 52906 0.261914 0.324395 -0.3528110 0.0004292 -0.000115 -0.000153 0.000068 0.000067 0.0000084 0.0000163 0.000046 0.000041 2003 9 25 52907 0.260937 0.321078 -0.3534232 0.0007277 -0.000103 -0.000193 0.000068 0.000067 0.0000131 0.0000166 0.000046 0.000041 2003 9 26 52908 0.259978 0.317600 -0.3542364 0.0009060 0.000021 -0.000252 0.000068 0.000067 0.0000037 0.0000169 0.000046 0.000041 2003 9 27 52909 0.259551 0.314124 -0.3552080 0.0009510 0.000044 -0.000254 0.000068 0.000067 0.0000062 0.0000171 0.000046 0.000041 2003 9 28 52910 0.259436 0.311276 -0.3561094 0.0007879 0.000029 -0.000235 0.000068 0.000067 0.0000068 0.0000174 0.000046 0.000041 2003 9 29 52911 0.259225 0.308578 -0.3568154 0.0006162 0.000014 -0.000216 0.000068 0.000067 0.0000043 0.0000177 0.000046 0.000041 2003 9 30 52912 0.259156 0.306445 -0.3572667 0.0004030 0.000000 -0.000197 0.000067 0.000067 0.0000018 0.0000180 0.000046 0.000041 2003 10 1 52913 0.258508 0.304390 -0.3575263 0.0001615 0.000006 -0.000227 0.000067 0.000067 0.0001163 0.0000183 0.000046 0.000042 2003 10 2 52914 0.257400 0.301625 -0.3576060 -0.0000253 0.000017 -0.000270 0.000067 0.000066 0.0002610 0.0000186 0.000046 0.000042 2003 10 3 52915 0.256216 0.298906 -0.3575419 -0.0000265 0.000027 -0.000289 0.000067 0.000066 0.0000768 0.0000189 0.000046 0.000042 2003 10 4 52916 0.254948 0.296407 -0.3575700 0.0000538 0.000047 -0.000233 0.000067 0.000066 0.0000051 0.0000192 0.000046 0.000042 2003 10 5 52917 0.253569 0.293725 -0.3577407 0.0002547 0.000070 -0.000152 0.000067 0.000066 0.0000053 0.0000195 0.000046 0.000042 2003 10 6 52918 0.252292 0.290665 -0.3580855 0.0004242 0.000093 -0.000071 0.000067 0.000066 0.0000042 0.0000197 0.000046 0.000042 2003 10 7 52919 0.250890 0.287567 -0.3586166 0.0006201 0.000117 0.000010 0.000067 0.000066 0.0000030 0.0000200 0.000047 0.000042 2003 10 8 52920 0.249648 0.284847 -0.3592662 0.0007521 0.000107 -0.000140 0.000067 0.000066 0.0000028 0.0000202 0.000047 0.000042 2003 10 9 52921 0.248038 0.282276 -0.3599969 0.0007039 0.000088 -0.000349 0.000067 0.000066 0.0000029 0.0000205 0.000047 0.000043 2003 10 10 52922 0.246586 0.279466 -0.3607426 0.0006929 0.000063 -0.000397 0.000067 0.000066 0.0000029 0.0000207 0.000046 0.000043 2003 10 11 52923 0.244496 0.276741 -0.3614165 0.0005809 0.000061 -0.000333 0.000068 0.000066 0.0000027 0.0000209 0.000046 0.000043 2003 10 12 52924 0.242033 0.273907 -0.3619679 0.0004438 0.000067 -0.000247 0.000068 0.000066 0.0000023 0.0000211 0.000046 0.000043 2003 10 13 52925 0.239810 0.270942 -0.3623646 0.0003249 0.000073 -0.000161 0.000068 0.000066 0.0000020 0.0000213 0.000046 0.000043 2003 10 14 52926 0.237737 0.267742 -0.3625962 0.0001745 0.000080 -0.000074 0.000068 0.000067 0.0000016 0.0000215 0.000046 0.000043 2003 10 15 52927 0.235765 0.264413 -0.3626993 0.0000641 0.000080 -0.000115 0.000068 0.000067 0.0000030 0.0000217 0.000046 0.000044 2003 10 16 52928 0.233923 0.261215 -0.3626718 -0.0000529 0.000104 -0.000193 0.000068 0.000067 0.0000037 0.0000219 0.000046 0.000044 2003 10 17 52929 0.231820 0.258184 -0.3625892 -0.0000979 0.000136 -0.000273 0.000068 0.000067 0.0000041 0.0000221 0.000046 0.000044 2003 10 18 52930 0.229815 0.255164 -0.3625714 -0.0000443 0.000141 -0.000273 0.000068 0.000067 0.0000072 0.0000223 0.000046 0.000044 2003 10 19 52931 0.227937 0.252662 -0.3626499 0.0001469 0.000135 -0.000245 0.000069 0.000067 0.0000070 0.0000225 0.000046 0.000044 2003 10 20 52932 0.226040 0.250288 -0.3628980 0.0004341 0.000130 -0.000217 0.000069 0.000067 0.0000045 0.0000227 0.000046 0.000044 2003 10 21 52933 0.223989 0.247589 -0.3633939 0.0006765 0.000124 -0.000189 0.000069 0.000067 0.0000021 0.0000229 0.000046 0.000044 2003 10 22 52934 0.221916 0.244947 -0.3642177 0.0009597 0.000095 -0.000150 0.000069 0.000068 0.0000023 0.0000231 0.000046 0.000044 2003 10 23 52935 0.220142 0.242380 -0.3653203 0.0012221 0.000073 -0.000143 0.000069 0.000068 0.0000033 0.0000233 0.000046 0.000044 2003 10 24 52936 0.219261 0.240108 -0.3666055 0.0013563 0.000038 -0.000201 0.000070 0.000068 0.0000020 0.0000235 0.000046 0.000044 2003 10 25 52937 0.218579 0.237968 -0.3679656 0.0012826 0.000019 -0.000230 0.000070 0.000068 0.0000081 0.0000237 0.000046 0.000045 2003 10 26 52938 0.218212 0.235955 -0.3691184 0.0010479 0.000007 -0.000243 0.000070 0.000068 0.0000089 0.0000238 0.000046 0.000045 2003 10 27 52939 0.217205 0.234001 -0.3699463 0.0006784 -0.000004 -0.000255 0.000070 0.000068 0.0000055 0.0000240 0.000046 0.000045 2003 10 28 52940 0.215503 0.231827 -0.3704269 0.0003263 -0.000015 -0.000267 0.000070 0.000068 0.0000021 0.0000241 0.000046 0.000045 2003 10 29 52941 0.213703 0.229427 -0.3705922 0.0000455 0.000094 -0.000275 0.000070 0.000068 0.0000098 0.0000243 0.000046 0.000046 2003 10 30 52942 0.212472 0.227100 -0.3705476 -0.0000925 0.000118 -0.000309 0.000070 0.000069 0.0000161 0.0000244 0.000046 0.000046 2003 10 31 52943 0.211123 0.225283 -0.3704254 -0.0000778 0.000107 -0.000352 0.000070 0.000069 0.0000070 0.0000245 0.000046 0.000046 2003 11 1 52944 0.209279 0.223623 -0.3703964 -0.0000303 0.000083 -0.000332 0.000070 0.000069 0.0000053 0.0000246 0.000046 0.000046 2003 11 2 52945 0.207286 0.221884 -0.3704860 0.0001406 0.000053 -0.000290 0.000070 0.000069 0.0000047 0.0000247 0.000046 0.000046 2003 11 3 52946 0.205062 0.219834 -0.3707230 0.0003455 0.000023 -0.000247 0.000070 0.000069 0.0000035 0.0000248 0.000046 0.000046 2003 11 4 52947 0.202736 0.217271 -0.3711073 0.0005128 -0.000007 -0.000205 0.000071 0.000069 0.0000023 0.0000248 0.000046 0.000046 2003 11 5 52948 0.200224 0.214317 -0.3716312 0.0005590 -0.000060 -0.000249 0.000071 0.000069 0.0000031 0.0000248 0.000046 0.000046 2003 11 6 52949 0.198195 0.211339 -0.3722099 0.0005531 -0.000024 -0.000307 0.000071 0.000069 0.0000043 0.0000249 0.000046 0.000046 2003 11 7 52950 0.196266 0.208453 -0.3727364 0.0004792 0.000060 -0.000271 0.000071 0.000069 0.0000022 0.0000250 0.000046 0.000045 2003 11 8 52951 0.194628 0.205915 -0.3732032 0.0003937 0.000058 -0.000234 0.000071 0.000069 0.0000048 0.0000251 0.000046 0.000046 2003 11 9 52952 0.192778 0.203648 -0.3735416 0.0002574 0.000022 -0.000207 0.000071 0.000069 0.0000052 0.0000251 0.000046 0.000046 2003 11 10 52953 0.190337 0.201456 -0.3737335 0.0001444 -0.000014 -0.000180 0.000070 0.000069 0.0000035 0.0000252 0.000046 0.000046 2003 11 11 52954 0.187129 0.198872 -0.3737937 0.0000481 -0.000049 -0.000153 0.000070 0.000069 0.0000019 0.0000252 0.000046 0.000046 2003 11 12 52955 0.184403 0.196333 -0.3737647 -0.0000469 -0.000004 -0.000190 0.000070 0.000069 0.0000110 0.0000252 0.000046 0.000046 2003 11 13 52956 0.182114 0.193998 -0.3737131 -0.0000258 0.000080 -0.000261 0.000070 0.000069 0.0000249 0.0000252 0.000046 0.000047 2003 11 14 52957 0.179798 0.191575 -0.3736869 0.0000183 0.000134 -0.000171 0.000070 0.000069 0.0000102 0.0000253 0.000046 0.000047 2003 11 15 52958 0.177373 0.189291 -0.3737759 0.0000970 0.000121 -0.000136 0.000070 0.000069 0.0000078 0.0000253 0.000046 0.000047 2003 11 16 52959 0.175118 0.187199 -0.3739516 0.0002624 0.000087 -0.000142 0.000070 0.000069 0.0000080 0.0000253 0.000046 0.000047 2003 11 17 52960 0.172917 0.185693 -0.3742898 0.0004966 0.000053 -0.000147 0.000070 0.000069 0.0000054 0.0000252 0.000046 0.000047 2003 11 18 52961 0.170056 0.184040 -0.3748661 0.0006828 0.000018 -0.000153 0.000070 0.000069 0.0000028 0.0000252 0.000046 0.000047 2003 11 19 52962 0.167299 0.182015 -0.3756679 0.0008500 0.000135 -0.000216 0.000070 0.000069 0.0000072 0.0000252 0.000046 0.000047 2003 11 20 52963 0.164379 0.180650 -0.3766359 0.0010094 0.000209 -0.000219 0.000070 0.000069 0.0000287 0.0000251 0.000046 0.000047 2003 11 21 52964 0.161747 0.179379 -0.3776796 0.0010775 0.000135 -0.000220 0.000070 0.000069 0.0000107 0.0000251 0.000045 0.000046 2003 11 22 52965 0.159437 0.178613 -0.3788062 0.0010643 0.000088 -0.000215 0.000070 0.000069 0.0000034 0.0000251 0.000045 0.000046 2003 11 23 52966 0.156622 0.178052 -0.3797496 0.0007957 0.000066 -0.000206 0.000070 0.000069 0.0000036 0.0000251 0.000044 0.000046 2003 11 24 52967 0.153600 0.177030 -0.3803788 0.0005204 0.000045 -0.000196 0.000070 0.000069 0.0000029 0.0000251 0.000044 0.000045 2003 11 25 52968 0.149612 0.175843 -0.3806963 0.0002368 0.000023 -0.000187 0.000070 0.000069 0.0000021 0.0000251 0.000044 0.000045 2003 11 26 52969 0.145206 0.174374 -0.3807688 -0.0000036 -0.000067 -0.000178 0.000070 0.000069 0.0000026 0.0000251 0.000043 0.000045 2003 11 27 52970 0.141083 0.173118 -0.3807211 -0.0000621 -0.000215 0.000024 0.000070 0.000068 0.0000065 0.0000250 0.000043 0.000045 2003 11 28 52971 0.137967 0.172009 -0.3806971 0.0000218 -0.000378 0.000295 0.000069 0.000068 0.0000116 0.0000249 0.000043 0.000045 2003 11 29 52972 0.134377 0.170891 -0.3807992 0.0001938 -0.000312 0.000231 0.000069 0.000068 0.0000167 0.0000249 0.000042 0.000044 2003 11 30 52973 0.130384 0.169202 -0.3810488 0.0003454 -0.000225 0.000135 0.000069 0.000068 0.0000146 0.0000248 0.000042 0.000043 2003 12 1 52974 0.126302 0.167983 -0.3814389 0.0004452 -0.000138 0.000040 0.000069 0.000068 0.0000088 0.0000247 0.000041 0.000043 2003 12 2 52975 0.123077 0.166803 -0.3819273 0.0005436 -0.000051 -0.000056 0.000070 0.000068 0.0000030 0.0000246 0.000041 0.000042 2003 12 3 52976 0.120093 0.165585 -0.3824625 0.0005015 -0.000019 -0.000091 0.000070 0.000068 0.0000076 0.0000246 0.000040 0.000042 2003 12 4 52977 0.116969 0.164609 -0.3829654 0.0004573 0.000000 -0.000132 0.000070 0.000068 0.0000140 0.0000245 0.000040 0.000041 2003 12 5 52978 0.114048 0.164061 -0.3833504 0.0003297 -0.000022 -0.000144 0.000070 0.000068 0.0000059 0.0000245 0.000039 0.000040 2003 12 6 52979 0.111377 0.163780 -0.3836641 0.0002431 -0.000031 -0.000172 0.000070 0.000068 0.0000168 0.0000244 0.000038 0.000039 2003 12 7 52980 0.108493 0.163287 -0.3838310 0.0000596 -0.000032 -0.000211 0.000070 0.000068 0.0000196 0.0000244 0.000037 0.000038 2003 12 8 52981 0.105420 0.162723 -0.3838149 -0.0000900 -0.000032 -0.000249 0.000070 0.000068 0.0000138 0.0000243 0.000037 0.000037 2003 12 9 52982 0.102475 0.162223 -0.3836138 -0.0002849 -0.000033 -0.000287 0.000070 0.000068 0.0000108 0.0000242 0.000036 0.000036 2003 12 10 52983 0.099787 0.161814 -0.3832111 -0.0004092 0.000037 -0.000165 0.000070 0.000068 0.0000183 0.0000241 0.000035 0.000035 2003 12 11 52984 0.096848 0.161305 -0.3827967 -0.0003770 0.000141 -0.000134 0.000070 0.000068 0.0000192 0.0000241 0.000034 0.000034 2003 12 12 52985 0.093398 0.160611 -0.3824298 -0.0003388 0.000250 -0.000216 0.000070 0.000068 0.0000065 0.0000241 0.000033 0.000033 2003 12 13 52986 0.089686 0.159694 -0.3821588 -0.0002104 0.000239 -0.000230 0.000070 0.000068 0.0000075 0.0000241 0.000032 0.000032 2003 12 14 52987 0.086365 0.158898 -0.3819817 -0.0000760 0.000184 -0.000209 0.000070 0.000068 0.0000082 0.0000240 0.000032 0.000030 2003 12 15 52988 0.083520 0.158729 -0.3819895 0.0001470 0.000128 -0.000188 0.000070 0.000068 0.0000054 0.0000240 0.000031 0.000029 2003 12 16 52989 0.080602 0.158731 -0.3822470 0.0003320 0.000073 -0.000167 0.000070 0.000068 0.0000025 0.0000240 0.000030 0.000028 2003 12 17 52990 0.077647 0.158365 -0.3827532 0.0006181 0.000039 -0.000150 0.000070 0.000068 0.0000090 0.0000239 0.000029 0.000027 2003 12 18 52991 0.074429 0.157925 -0.3834460 0.0007740 0.000012 -0.000134 0.000070 0.000068 0.0000181 0.0000239 0.000028 0.000026 2003 12 19 52992 0.071446 0.157462 -0.3842290 0.0008364 -0.000014 -0.000122 0.000070 0.000068 0.0000059 0.0000240 0.000028 0.000026 2003 12 20 52993 0.068896 0.157144 -0.3850590 0.0007931 0.000006 -0.000107 0.000070 0.000068 0.0000067 0.0000240 0.000029 0.000027 2003 12 21 52994 0.066392 0.156667 -0.3857097 0.0005659 0.000044 -0.000091 0.000070 0.000068 0.0000074 0.0000240 0.000029 0.000027 2003 12 22 52995 0.063589 0.156108 -0.3861041 0.0003205 0.000081 -0.000075 0.000070 0.000068 0.0000047 0.0000240 0.000029 0.000027 2003 12 23 52996 0.060432 0.155650 -0.3862828 0.0001239 0.000119 -0.000059 0.000070 0.000068 0.0000021 0.0000240 0.000030 0.000028 2003 12 24 52997 0.056666 0.155297 -0.3863175 0.0000512 0.000111 -0.000065 0.000070 0.000068 0.0000016 0.0000240 0.000030 0.000028 2003 12 25 52998 0.052581 0.154963 -0.3863491 0.0001169 0.000092 -0.000076 0.000070 0.000068 0.0000017 0.0000240 0.000031 0.000029 2003 12 26 52999 0.048811 0.154680 -0.3864927 0.0002527 0.000073 -0.000088 0.000070 0.000068 0.0000019 0.0000240 0.000031 0.000029 2003 12 27 53000 0.045865 0.154673 -0.3868057 0.0003924 0.000054 -0.000099 0.000070 0.000068 0.0000020 0.0000240 0.000032 0.000030 2003 12 28 53001 0.042906 0.154955 -0.3872830 0.0005208 0.000035 -0.000111 0.000070 0.000068 0.0000021 0.0000240 0.000032 0.000030 2003 12 29 53002 0.039909 0.155028 -0.3878733 0.0005910 0.000016 -0.000123 0.000070 0.000069 0.0000022 0.0000240 0.000033 0.000031 2003 12 30 53003 0.036981 0.154689 -0.3885056 0.0005801 -0.000003 -0.000134 0.000070 0.000069 0.0000024 0.0000240 0.000034 0.000032 2003 12 31 53004 0.034060 0.154396 -0.3891131 0.0005253 0.000012 -0.000129 0.000070 0.000069 0.0000283 0.0000239 0.000034 0.000032 2004 1 1 53005 0.031182 0.154037 -0.3896519 0.0004656 0.000035 -0.000120 0.000071 0.000066 0.0000438 0.0000173 0.000030 0.000032 2004 1 2 53006 0.028859 0.153811 -0.3901435 0.0004166 0.000059 -0.000111 0.000071 0.000066 0.0000269 0.0000173 0.000030 0.000033 2004 1 3 53007 0.026738 0.154042 -0.3904792 0.0002684 0.000083 -0.000101 0.000071 0.000066 0.0000127 0.0000173 0.000030 0.000034 2004 1 4 53008 0.024264 0.154439 -0.3905850 0.0000895 0.000107 -0.000092 0.000071 0.000066 0.0000100 0.0000173 0.000031 0.000035 2004 1 5 53009 0.021611 0.155070 -0.3905816 -0.0000481 0.000131 -0.000083 0.000071 0.000066 0.0000073 0.0000173 0.000031 0.000035 2004 1 6 53010 0.018737 0.155647 -0.3905118 -0.0001348 0.000154 -0.000073 0.000072 0.000067 0.0000046 0.0000173 0.000032 0.000036 2004 1 7 53011 0.015921 0.156373 -0.3904522 -0.0000465 0.000131 -0.000124 0.000072 0.000067 0.0000104 0.0000174 0.000032 0.000037 2004 1 8 53012 0.012958 0.157159 -0.3904617 0.0000842 0.000096 -0.000190 0.000072 0.000067 0.0000185 0.0000174 0.000033 0.000037 2004 1 9 53013 0.009999 0.157615 -0.3906090 0.0002429 0.000136 -0.000176 0.000072 0.000067 0.0000079 0.0000174 0.000033 0.000037 2004 1 10 53014 0.007654 0.157896 -0.3910345 0.0004901 0.000137 -0.000172 0.000072 0.000067 0.0000091 0.0000174 0.000033 0.000037 2004 1 11 53015 0.005360 0.158067 -0.3916682 0.0007453 0.000113 -0.000182 0.000072 0.000067 0.0000095 0.0000175 0.000033 0.000037 2004 1 12 53016 0.003094 0.158520 -0.3925178 0.0010105 0.000090 -0.000192 0.000072 0.000067 0.0000061 0.0000175 0.000033 0.000037 2004 1 13 53017 0.000858 0.159253 -0.3935833 0.0011986 0.000067 -0.000202 0.000073 0.000068 0.0000026 0.0000175 0.000033 0.000037 2004 1 14 53018 -0.001068 0.160130 -0.3948316 0.0012673 0.000005 0.000159 0.000073 0.000068 0.0000050 0.0000176 0.000033 0.000037 2004 1 15 53019 -0.003298 0.161622 -0.3960892 0.0012237 -0.000038 0.000110 0.000073 0.000068 0.0000045 0.0000176 0.000033 0.000037 2004 1 16 53020 -0.005420 0.162910 -0.3972557 0.0010769 -0.000074 -0.000085 0.000073 0.000068 0.0000028 0.0000176 0.000033 0.000037 2004 1 17 53021 -0.007586 0.163947 -0.3983360 0.0008181 -0.000065 -0.000118 0.000073 0.000068 0.0000093 0.0000177 0.000033 0.000037 2004 1 18 53022 -0.010106 0.165272 -0.3991003 0.0005833 -0.000039 -0.000092 0.000073 0.000068 0.0000113 0.0000177 0.000033 0.000037 2004 1 19 53023 -0.013276 0.166668 -0.3995496 0.0003601 -0.000013 -0.000066 0.000073 0.000068 0.0000091 0.0000177 0.000033 0.000037 2004 1 20 53024 -0.016222 0.167427 -0.3997511 0.0001916 0.000012 -0.000040 0.000073 0.000068 0.0000125 0.0000177 0.000033 0.000037 2004 1 21 53025 -0.018729 0.168547 -0.3998543 0.0001978 0.000038 -0.000014 0.000073 0.000068 0.0000187 0.0000177 0.000033 0.000037 2004 1 22 53026 -0.021135 0.170299 -0.4000605 0.0002945 0.000018 -0.000055 0.000073 0.000068 0.0000134 0.0000177 0.000033 0.000037 2004 1 23 53027 -0.023886 0.172143 -0.4004338 0.0004310 -0.000014 -0.000114 0.000073 0.000068 0.0000050 0.0000177 0.000033 0.000037 2004 1 24 53028 -0.026364 0.173449 -0.4010208 0.0006081 -0.000032 -0.000127 0.000073 0.000067 0.0000092 0.0000177 0.000033 0.000037 2004 1 25 53029 -0.027934 0.174714 -0.4017504 0.0007713 -0.000044 -0.000124 0.000073 0.000067 0.0000140 0.0000177 0.000033 0.000037 2004 1 26 53030 -0.029140 0.176082 -0.4025442 0.0008364 -0.000056 -0.000121 0.000073 0.000067 0.0000167 0.0000177 0.000034 0.000037 2004 1 27 53031 -0.030156 0.177648 -0.4033209 0.0008062 -0.000068 -0.000117 0.000073 0.000067 0.0000194 0.0000177 0.000034 0.000037 2004 1 28 53032 -0.031525 0.179417 -0.4040886 0.0007036 -0.000044 -0.000147 0.000073 0.000067 0.0000139 0.0000177 0.000034 0.000037 2004 1 29 53033 -0.033402 0.181302 -0.4047004 0.0004881 -0.000010 -0.000186 0.000072 0.000067 0.0000071 0.0000177 0.000034 0.000037 2004 1 30 53034 -0.035828 0.183195 -0.4050386 0.0002476 0.000024 -0.000224 0.000072 0.000067 0.0000037 0.0000177 0.000034 0.000037 2004 1 31 53035 -0.038902 0.184915 -0.4052487 0.0000293 0.000048 -0.000194 0.000072 0.000067 0.0000214 0.0000177 0.000034 0.000037 2004 2 1 53036 -0.042090 0.186140 -0.4052226 -0.0001076 0.000068 -0.000137 0.000072 0.000066 0.0000235 0.0000176 0.000035 0.000038 2004 2 2 53037 -0.044907 0.187290 -0.4050110 -0.0001997 0.000088 -0.000081 0.000072 0.000066 0.0000137 0.0000176 0.000035 0.000038 2004 2 3 53038 -0.047984 0.188318 -0.4047132 -0.0002595 0.000108 -0.000025 0.000072 0.000066 0.0000039 0.0000176 0.000035 0.000038 2004 2 4 53039 -0.051244 0.189262 -0.4044064 -0.0002338 0.000113 -0.000046 0.000072 0.000066 0.0000129 0.0000176 0.000035 0.000038 2004 2 5 53040 -0.054250 0.190031 -0.4041732 -0.0001601 0.000113 -0.000087 0.000072 0.000066 0.0000268 0.0000176 0.000036 0.000039 2004 2 6 53041 -0.056601 0.190925 -0.4041086 0.0000385 0.000095 -0.000135 0.000072 0.000066 0.0000094 0.0000175 0.000036 0.000039 2004 2 7 53042 -0.058876 0.192202 -0.4042450 0.0002722 0.000056 -0.000126 0.000072 0.000066 0.0000240 0.0000175 0.000036 0.000039 2004 2 8 53043 -0.060564 0.193720 -0.4046445 0.0005495 0.000012 -0.000095 0.000072 0.000066 0.0000270 0.0000175 0.000036 0.000039 2004 2 9 53044 -0.062459 0.195594 -0.4052920 0.0007411 -0.000032 -0.000065 0.000072 0.000066 0.0000161 0.0000175 0.000036 0.000039 2004 2 10 53045 -0.064814 0.197386 -0.4061169 0.0008872 -0.000075 -0.000034 0.000072 0.000065 0.0000052 0.0000175 0.000036 0.000039 2004 2 11 53046 -0.067581 0.199368 -0.4070562 0.0009493 -0.000026 -0.000102 0.000072 0.000065 0.0000126 0.0000175 0.000036 0.000039 2004 2 12 53047 -0.070720 0.201140 -0.4079949 0.0008775 0.000010 -0.000112 0.000072 0.000065 0.0000584 0.0000175 0.000036 0.000039 2004 2 13 53048 -0.073714 0.202857 -0.4087628 0.0006852 0.000003 -0.000059 0.000071 0.000065 0.0000215 0.0000175 0.000036 0.000039 2004 2 14 53049 -0.076768 0.204700 -0.4093465 0.0004599 0.000029 -0.000047 0.000071 0.000065 0.0000131 0.0000175 0.000036 0.000038 2004 2 15 53050 -0.079610 0.206423 -0.4096876 0.0002338 0.000071 -0.000055 0.000071 0.000065 0.0000181 0.0000175 0.000036 0.000038 2004 2 16 53051 -0.081530 0.208269 -0.4098440 0.0001146 0.000070 -0.000071 0.000071 0.000065 0.0000189 0.0000175 0.000035 0.000037 2004 2 17 53052 -0.082966 0.210374 -0.4099407 0.0000528 0.000009 -0.000097 0.000071 0.000065 0.0000198 0.0000176 0.000035 0.000037 2004 2 18 53053 -0.084124 0.212467 -0.4100613 0.0001690 0.000007 -0.000148 0.000071 0.000065 0.0000182 0.0000176 0.000035 0.000037 2004 2 19 53054 -0.086414 0.215176 -0.4103436 0.0003817 0.000024 -0.000175 0.000071 0.000065 0.0000623 0.0000176 0.000036 0.000037 2004 2 20 53055 -0.089868 0.217396 -0.4108239 0.0005993 0.000009 -0.000140 0.000071 0.000065 0.0000220 0.0000176 0.000035 0.000037 2004 2 21 53056 -0.093077 0.219769 -0.4115971 0.0008064 -0.000005 -0.000136 0.000071 0.000065 0.0000056 0.0000176 0.000035 0.000036 2004 2 22 53057 -0.095745 0.222187 -0.4125660 0.0010108 -0.000014 -0.000149 0.000071 0.000065 0.0000101 0.0000176 0.000035 0.000036 2004 2 23 53058 -0.097946 0.224543 -0.4136063 0.0011050 -0.000023 -0.000163 0.000071 0.000064 0.0000146 0.0000176 0.000035 0.000035 2004 2 24 53059 -0.099966 0.226572 -0.4146157 0.0010246 -0.000032 -0.000177 0.000071 0.000064 0.0000191 0.0000177 0.000035 0.000035 2004 2 25 53060 -0.101269 0.228863 -0.4156323 0.0008946 -0.000027 -0.000199 0.000071 0.000065 0.0000202 0.0000177 0.000035 0.000035 2004 2 26 53061 -0.102528 0.231215 -0.4164744 0.0006636 -0.000017 -0.000223 0.000071 0.000065 0.0000180 0.0000177 0.000035 0.000035 2004 2 27 53062 -0.103830 0.233623 -0.4169958 0.0005323 -0.000008 -0.000247 0.000071 0.000065 0.0000060 0.0000178 0.000035 0.000035 2004 2 28 53063 -0.105962 0.236197 -0.4174240 0.0002685 -0.000010 -0.000220 0.000071 0.000065 0.0000119 0.0000178 0.000035 0.000035 2004 2 29 53064 -0.108374 0.238073 -0.4175595 0.0000213 -0.000016 -0.000175 0.000071 0.000065 0.0000128 0.0000178 0.000035 0.000034 2004 3 1 53065 -0.110549 0.240135 -0.4174832 -0.0001064 -0.000022 -0.000129 0.000071 0.000065 0.0000079 0.0000179 0.000034 0.000034 2004 3 2 53066 -0.112345 0.242265 -0.4173376 -0.0001529 -0.000029 -0.000083 0.000071 0.000065 0.0000029 0.0000179 0.000034 0.000034 2004 3 3 53067 -0.113935 0.244452 -0.4172138 -0.0001248 0.000048 -0.000049 0.000071 0.000065 0.0000016 0.0000180 0.000034 0.000034 2004 3 4 53068 -0.115454 0.246481 -0.4171838 0.0000851 0.000100 -0.000087 0.000071 0.000065 0.0000011 0.0000180 0.000034 0.000034 2004 3 5 53069 -0.117262 0.249116 -0.4173441 0.0002674 0.000078 -0.000152 0.000071 0.000065 0.0000021 0.0000181 0.000034 0.000034 2004 3 6 53070 -0.119064 0.251623 -0.4177374 0.0004867 0.000047 -0.000144 0.000070 0.000065 0.0000168 0.0000181 0.000034 0.000034 2004 3 7 53071 -0.120252 0.254397 -0.4183773 0.0007398 0.000021 -0.000109 0.000070 0.000064 0.0000182 0.0000181 0.000034 0.000034 2004 3 8 53072 -0.121686 0.256560 -0.4192064 0.0009199 -0.000006 -0.000073 0.000070 0.000064 0.0000105 0.0000182 0.000034 0.000034 2004 3 9 53073 -0.122368 0.258192 -0.4201195 0.0009438 -0.000032 -0.000037 0.000070 0.000064 0.0000028 0.0000182 0.000034 0.000034 2004 3 10 53074 -0.123028 0.260247 -0.4210157 0.0008425 -0.000140 -0.000226 0.000070 0.000064 0.0000023 0.0000183 0.000034 0.000034 2004 3 11 53075 -0.123782 0.262242 -0.4217282 0.0005965 -0.000159 -0.000231 0.000070 0.000064 0.0000024 0.0000183 0.000034 0.000034 2004 3 12 53076 -0.124409 0.264377 -0.4221956 0.0003295 -0.000143 -0.000160 0.000070 0.000064 0.0000021 0.0000183 0.000034 0.000035 2004 3 13 53077 -0.125144 0.266401 -0.4225004 0.0001447 -0.000098 -0.000103 0.000070 0.000064 0.0000069 0.0000183 0.000034 0.000035 2004 3 14 53078 -0.126037 0.268743 -0.4225549 -0.0000170 -0.000041 -0.000051 0.000070 0.000064 0.0000085 0.0000183 0.000034 0.000035 2004 3 15 53079 -0.126911 0.270824 -0.4224788 -0.0000414 0.000015 0.000001 0.000070 0.000064 0.0000074 0.0000183 0.000035 0.000036 2004 3 16 53080 -0.128100 0.273033 -0.4224487 0.0000624 0.000072 0.000053 0.000070 0.000064 0.0000064 0.0000183 0.000035 0.000037 2004 3 17 53081 -0.129240 0.274986 -0.4225482 0.0002155 0.000040 0.000020 0.000070 0.000065 0.0000112 0.0000183 0.000035 0.000037 2004 3 18 53082 -0.130044 0.277233 -0.4228892 0.0004696 -0.000014 -0.000034 0.000070 0.000065 0.0000175 0.0000183 0.000035 0.000037 2004 3 19 53083 -0.131194 0.279784 -0.4234873 0.0007354 -0.000053 -0.000020 0.000070 0.000065 0.0000085 0.0000183 0.000035 0.000038 2004 3 20 53084 -0.131815 0.282046 -0.4244206 0.0009815 -0.000069 -0.000019 0.000070 0.000065 0.0000105 0.0000183 0.000035 0.000038 2004 3 21 53085 -0.131828 0.284868 -0.4255020 0.0011573 -0.000079 -0.000030 0.000070 0.000065 0.0000107 0.0000183 0.000035 0.000037 2004 3 22 53086 -0.131918 0.288049 -0.4266247 0.0011591 -0.000088 -0.000041 0.000070 0.000065 0.0000070 0.0000183 0.000035 0.000037 2004 3 23 53087 -0.131886 0.291466 -0.4277222 0.0011424 -0.000098 -0.000052 0.000070 0.000065 0.0000033 0.0000183 0.000035 0.000037 2004 3 24 53088 -0.131984 0.295174 -0.4288123 0.0010432 -0.000040 -0.000080 0.000070 0.000065 0.0000027 0.0000183 0.000035 0.000037 2004 3 25 53089 -0.132868 0.298587 -0.4297816 0.0008723 0.000036 -0.000111 0.000070 0.000065 0.0000030 0.0000183 0.000034 0.000037 2004 3 26 53090 -0.134021 0.302033 -0.4305911 0.0007608 0.000112 -0.000142 0.000070 0.000065 0.0000032 0.0000183 0.000034 0.000037 2004 3 27 53091 -0.135595 0.305548 -0.4312954 0.0005692 0.000092 -0.000122 0.000070 0.000065 0.0000052 0.0000183 0.000034 0.000037 2004 3 28 53092 -0.137007 0.308564 -0.4317735 0.0004179 0.000037 -0.000084 0.000070 0.000065 0.0000093 0.0000183 0.000034 0.000037 2004 3 29 53093 -0.137937 0.311745 -0.4321309 0.0003375 -0.000018 -0.000045 0.000070 0.000065 0.0000142 0.0000182 0.000034 0.000036 2004 3 30 53094 -0.138782 0.314991 -0.4325012 0.0004168 -0.000072 -0.000007 0.000071 0.000065 0.0000190 0.0000182 0.000033 0.000036 2004 3 31 53095 -0.139512 0.318005 -0.4330090 0.0005505 -0.000049 -0.000025 0.000071 0.000065 0.0000154 0.0000182 0.000033 0.000036 2004 4 1 53096 -0.140236 0.320816 -0.4336706 0.0007414 -0.000006 -0.000058 0.000071 0.000065 0.0000095 0.0000182 0.000033 0.000036 2004 4 2 53097 -0.140796 0.323536 -0.4344830 0.0009426 0.000037 -0.000090 0.000071 0.000065 0.0000038 0.0000181 0.000033 0.000036 2004 4 3 53098 -0.140779 0.326227 -0.4355984 0.0012111 0.000015 -0.000101 0.000071 0.000065 0.0000068 0.0000181 0.000033 0.000036 2004 4 4 53099 -0.140922 0.328934 -0.4369516 0.0014437 -0.000030 -0.000103 0.000071 0.000065 0.0000074 0.0000181 0.000033 0.000036 2004 4 5 53100 -0.141265 0.331212 -0.4384475 0.0015523 -0.000076 -0.000105 0.000071 0.000065 0.0000051 0.0000180 0.000034 0.000036 2004 4 6 53101 -0.140865 0.333414 -0.4399623 0.0015308 -0.000122 -0.000107 0.000071 0.000065 0.0000029 0.0000180 0.000034 0.000036 2004 4 7 53102 -0.140125 0.336313 -0.4414030 0.0013527 -0.000127 -0.000072 0.000071 0.000065 0.0000026 0.0000179 0.000034 0.000037 2004 4 8 53103 -0.139920 0.339558 -0.4426138 0.0010652 -0.000058 -0.000034 0.000071 0.000065 0.0000029 0.0000179 0.000034 0.000037 2004 4 9 53104 -0.139811 0.342715 -0.4435571 0.0007714 -0.000032 -0.000008 0.000071 0.000065 0.0000068 0.0000178 0.000034 0.000037 2004 4 10 53105 -0.139248 0.345939 -0.4442523 0.0005347 -0.000027 0.000015 0.000071 0.000065 0.0000114 0.0000177 0.000034 0.000037 2004 4 11 53106 -0.138676 0.349416 -0.4446692 0.0003535 -0.000023 0.000037 0.000071 0.000065 0.0000097 0.0000177 0.000034 0.000037 2004 4 12 53107 -0.138920 0.352596 -0.4449729 0.0003058 -0.000018 0.000060 0.000071 0.000065 0.0000065 0.0000176 0.000033 0.000037 2004 4 13 53108 -0.139182 0.355477 -0.4453517 0.0004489 -0.000014 0.000082 0.000072 0.000065 0.0000033 0.0000176 0.000033 0.000037 2004 4 14 53109 -0.139194 0.358233 -0.4459425 0.0006960 -0.000015 0.000015 0.000072 0.000065 0.0000016 0.0000175 0.000033 0.000038 2004 4 15 53110 -0.138718 0.361010 -0.4467361 0.0008825 0.000014 0.000058 0.000072 0.000065 0.0000153 0.0000175 0.000034 0.000038 2004 4 16 53111 -0.137441 0.363846 -0.4476894 0.0010158 -0.000020 0.000177 0.000072 0.000065 0.0000074 0.0000175 0.000034 0.000038 2004 4 17 53112 -0.135920 0.367242 -0.4487946 0.0010620 0.000016 0.000200 0.000072 0.000065 0.0000067 0.0000175 0.000034 0.000038 2004 4 18 53113 -0.134733 0.370679 -0.4498582 0.0009968 0.000086 0.000183 0.000072 0.000065 0.0000073 0.0000174 0.000034 0.000038 2004 4 19 53114 -0.133425 0.373922 -0.4507956 0.0009070 0.000157 0.000166 0.000072 0.000065 0.0000056 0.0000174 0.000034 0.000038 2004 4 20 53115 -0.132692 0.377552 -0.4515632 0.0007526 0.000227 0.000149 0.000072 0.000066 0.0000038 0.0000174 0.000034 0.000038 2004 4 21 53116 -0.132949 0.380665 -0.4521845 0.0004550 0.000239 0.000141 0.000072 0.000066 0.0000069 0.0000174 0.000034 0.000038 2004 4 22 53117 -0.133211 0.382964 -0.4525664 0.0002195 0.000233 0.000136 0.000072 0.000066 0.0000094 0.0000174 0.000034 0.000038 2004 4 23 53118 -0.132993 0.385454 -0.4526325 0.0000045 0.000228 0.000130 0.000072 0.000066 0.0000042 0.0000174 0.000034 0.000038 2004 4 24 53119 -0.132877 0.387533 -0.4525861 -0.0001459 0.000197 0.000120 0.000072 0.000066 0.0000102 0.0000175 0.000034 0.000038 2004 4 25 53120 -0.132196 0.389263 -0.4523983 -0.0002477 0.000158 0.000109 0.000072 0.000066 0.0000109 0.0000175 0.000034 0.000038 2004 4 26 53121 -0.130689 0.391071 -0.4521566 -0.0001945 0.000118 0.000098 0.000072 0.000066 0.0000066 0.0000175 0.000034 0.000038 2004 4 27 53122 -0.128516 0.393063 -0.4519764 -0.0000576 0.000079 0.000086 0.000072 0.000066 0.0000022 0.0000174 0.000034 0.000037 2004 4 28 53123 -0.126785 0.395323 -0.4520316 0.0001260 0.000246 0.000128 0.000072 0.000066 0.0000087 0.0000174 0.000034 0.000037 2004 4 29 53124 -0.125054 0.398148 -0.4522923 0.0003442 0.000467 0.000184 0.000072 0.000066 0.0000142 0.0000174 0.000034 0.000038 2004 4 30 53125 -0.123529 0.401280 -0.4526927 0.0006059 0.000324 0.000136 0.000072 0.000066 0.0000053 0.0000174 0.000034 0.000037 2004 5 1 53126 -0.121380 0.404499 -0.4534258 0.0009090 0.000245 0.000097 0.000072 0.000066 0.0000026 0.0000174 0.000034 0.000037 2004 5 2 53127 -0.119682 0.407691 -0.4544221 0.0010429 0.000206 0.000064 0.000072 0.000066 0.0000024 0.0000174 0.000034 0.000036 2004 5 3 53128 -0.118416 0.410805 -0.4555628 0.0011460 0.000167 0.000031 0.000072 0.000066 0.0000021 0.0000174 0.000034 0.000036 2004 5 4 53129 -0.117076 0.413788 -0.4567058 0.0011173 0.000127 -0.000002 0.000072 0.000066 0.0000018 0.0000174 0.000033 0.000035 2004 5 5 53130 -0.115826 0.416674 -0.4577699 0.0009548 0.000179 -0.000050 0.000072 0.000066 0.0000018 0.0000174 0.000033 0.000035 2004 5 6 53131 -0.115045 0.419423 -0.4586120 0.0007356 0.000255 -0.000102 0.000072 0.000066 0.0000018 0.0000174 0.000033 0.000035 2004 5 7 53132 -0.114064 0.421835 -0.4592344 0.0005145 0.000215 -0.000083 0.000072 0.000066 0.0000032 0.0000174 0.000033 0.000035 2004 5 8 53133 -0.112556 0.424144 -0.4597362 0.0003591 0.000129 -0.000093 0.000072 0.000066 0.0000109 0.0000174 0.000033 0.000035 2004 5 9 53134 -0.111199 0.426408 -0.4600592 0.0003226 0.000040 -0.000123 0.000072 0.000066 0.0000114 0.0000174 0.000033 0.000035 2004 5 10 53135 -0.109702 0.428899 -0.4603831 0.0004185 0.000071 -0.000111 0.000071 0.000066 0.0000071 0.0000174 0.000033 0.000036 2004 5 11 53136 -0.108035 0.431879 -0.4608730 0.0005833 0.000104 -0.000099 0.000071 0.000066 0.0000028 0.0000173 0.000033 0.000036 2004 5 12 53137 -0.106069 0.434710 -0.4615467 0.0007352 0.000111 -0.000055 0.000071 0.000066 0.0000019 0.0000173 0.000033 0.000036 2004 5 13 53138 -0.103940 0.437435 -0.4623687 0.0008936 0.000080 0.000105 0.000071 0.000066 0.0000018 0.0000172 0.000033 0.000036 2004 5 14 53139 -0.102191 0.440264 -0.4633332 0.0010087 0.000147 0.000114 0.000071 0.000066 0.0000026 0.0000172 0.000034 0.000037 2004 5 15 53140 -0.101194 0.442673 -0.4644447 0.0010390 0.000152 0.000084 0.000071 0.000065 0.0000130 0.0000171 0.000034 0.000037 2004 5 16 53141 -0.100594 0.444366 -0.4655004 0.0009907 0.000123 0.000056 0.000071 0.000065 0.0000141 0.0000170 0.000034 0.000037 2004 5 17 53142 -0.100191 0.445888 -0.4664166 0.0008834 0.000094 0.000029 0.000071 0.000065 0.0000088 0.0000170 0.000035 0.000037 2004 5 18 53143 -0.099768 0.447056 -0.4671627 0.0007165 0.000065 0.000001 0.000071 0.000065 0.0000035 0.0000169 0.000035 0.000038 2004 5 19 53144 -0.098990 0.448463 -0.4677619 0.0004880 0.000081 -0.000100 0.000070 0.000065 0.0000036 0.0000168 0.000035 0.000038 2004 5 20 53145 -0.097735 0.449684 -0.4681654 0.0002980 0.000109 -0.000219 0.000070 0.000065 0.0000052 0.0000168 0.000036 0.000039 2004 5 21 53146 -0.096282 0.451327 -0.4684037 0.0001221 0.000129 -0.000202 0.000070 0.000065 0.0000077 0.0000167 0.000036 0.000040 2004 5 22 53147 -0.095187 0.452546 -0.4685215 -0.0000252 0.000147 -0.000133 0.000070 0.000064 0.0000142 0.0000167 0.000037 0.000040 2004 5 23 53148 -0.094227 0.453767 -0.4684875 -0.0000925 0.000164 -0.000064 0.000070 0.000064 0.0000173 0.0000166 0.000037 0.000041 2004 5 24 53149 -0.093254 0.455212 -0.4683629 -0.0001007 0.000182 0.000004 0.000069 0.000064 0.0000104 0.0000166 0.000038 0.000042 2004 5 25 53150 -0.091830 0.456855 -0.4682812 -0.0000080 0.000199 0.000073 0.000069 0.000064 0.0000036 0.0000165 0.000038 0.000042 2004 5 26 53151 -0.090860 0.458610 -0.4683236 0.0001017 0.000278 -0.000077 0.000069 0.000064 0.0000068 0.0000165 0.000039 0.000043 2004 5 27 53152 -0.090126 0.460091 -0.4685165 0.0002573 0.000290 -0.000088 0.000069 0.000063 0.0000125 0.0000165 0.000039 0.000043 2004 5 28 53153 -0.089400 0.461690 -0.4688621 0.0004390 0.000261 -0.000082 0.000069 0.000063 0.0000075 0.0000164 0.000039 0.000044 2004 5 29 53154 -0.088318 0.463305 -0.4693716 0.0004991 0.000226 -0.000083 0.000069 0.000063 0.0000082 0.0000164 0.000040 0.000044 2004 5 30 53155 -0.087199 0.464696 -0.4699542 0.0005398 0.000197 -0.000065 0.000068 0.000063 0.0000092 0.0000164 0.000040 0.000044 2004 5 31 53156 -0.085617 0.465896 -0.4705186 0.0005346 0.000168 -0.000047 0.000068 0.000063 0.0000072 0.0000164 0.000040 0.000044 2004 6 1 53157 -0.083861 0.467342 -0.4709577 0.0004110 0.000140 -0.000029 0.000068 0.000063 0.0000051 0.0000164 0.000040 0.000044 2004 6 2 53158 -0.082021 0.469284 -0.4711645 0.0001735 0.000111 -0.000011 0.000068 0.000062 0.0000031 0.0000164 0.000041 0.000044 2004 6 3 53159 -0.079983 0.470913 -0.4711919 -0.0000856 0.000143 0.000031 0.000068 0.000062 0.0000026 0.0000164 0.000041 0.000045 2004 6 4 53160 -0.077623 0.472446 -0.4710123 -0.0002449 0.000191 0.000079 0.000068 0.000062 0.0000025 0.0000164 0.000041 0.000045 2004 6 5 53161 -0.075809 0.473956 -0.4707595 -0.0003214 0.000167 0.000094 0.000068 0.000062 0.0000128 0.0000165 0.000042 0.000045 2004 6 6 53162 -0.074487 0.475665 -0.4704721 -0.0002408 0.000116 0.000096 0.000068 0.000062 0.0000138 0.0000165 0.000042 0.000046 2004 6 7 53163 -0.073446 0.477189 -0.4703033 -0.0000409 0.000065 0.000098 0.000068 0.000062 0.0000083 0.0000165 0.000043 0.000046 2004 6 8 53164 -0.071896 0.478506 -0.4703594 0.0001581 0.000014 0.000101 0.000069 0.000062 0.0000027 0.0000166 0.000043 0.000047 2004 6 9 53165 -0.070003 0.480177 -0.4706675 0.0003419 0.000071 -0.000219 0.000069 0.000062 0.0000071 0.0000166 0.000044 0.000048 2004 6 10 53166 -0.068427 0.481801 -0.4711013 0.0004176 0.000143 -0.000146 0.000069 0.000062 0.0000113 0.0000167 0.000045 0.000049 2004 6 11 53167 -0.066791 0.483228 -0.4714613 0.0004676 0.000212 0.000069 0.000069 0.000062 0.0000057 0.0000168 0.000045 0.000050 2004 6 12 53168 -0.064999 0.484704 -0.4719483 0.0004346 0.000234 0.000122 0.000069 0.000062 0.0000140 0.0000169 0.000045 0.000050 2004 6 13 53169 -0.062835 0.486105 -0.4723558 0.0003633 0.000238 0.000116 0.000069 0.000063 0.0000153 0.0000170 0.000046 0.000051 2004 6 14 53170 -0.060434 0.487516 -0.4725853 0.0001983 0.000243 0.000110 0.000069 0.000063 0.0000105 0.0000171 0.000046 0.000051 2004 6 15 53171 -0.057966 0.488769 -0.4726199 -0.0000643 0.000248 0.000104 0.000069 0.000063 0.0000058 0.0000172 0.000046 0.000051 2004 6 16 53172 -0.054953 0.490072 -0.4724316 -0.0003040 0.000070 0.000118 0.000070 0.000063 0.0000053 0.0000174 0.000047 0.000052 2004 6 17 53173 -0.051573 0.491700 -0.4720111 -0.0005104 -0.000028 0.000075 0.000070 0.000063 0.0000094 0.0000175 0.000047 0.000052 2004 6 18 53174 -0.048266 0.493550 -0.4714616 -0.0005551 0.000019 0.000061 0.000070 0.000063 0.0000064 0.0000177 0.000047 0.000052 2004 6 19 53175 -0.045161 0.495659 -0.4708726 -0.0005659 0.000075 0.000039 0.000070 0.000063 0.0000045 0.0000179 0.000047 0.000052 2004 6 20 53176 -0.041907 0.497228 -0.4702900 -0.0005541 0.000123 0.000010 0.000070 0.000063 0.0000041 0.0000182 0.000047 0.000051 2004 6 21 53177 -0.038484 0.498594 -0.4697723 -0.0004942 0.000170 -0.000020 0.000070 0.000063 0.0000036 0.0000184 0.000047 0.000051 2004 6 22 53178 -0.035191 0.499901 -0.4693775 -0.0003677 0.000217 -0.000049 0.000070 0.000063 0.0000032 0.0000187 0.000047 0.000051 2004 6 23 53179 -0.031852 0.501198 -0.4691171 -0.0001892 0.000174 -0.000145 0.000070 0.000063 0.0000067 0.0000189 0.000047 0.000050 2004 6 24 53180 -0.028549 0.502335 -0.4690292 -0.0000008 0.000107 -0.000257 0.000070 0.000063 0.0000112 0.0000191 0.000046 0.000050 2004 6 25 53181 -0.024980 0.503477 -0.4691327 0.0001728 0.000027 -0.000166 0.000070 0.000063 0.0000057 0.0000193 0.000046 0.000049 2004 6 26 53182 -0.021980 0.505058 -0.4693331 0.0002092 0.000024 -0.000075 0.000070 0.000063 0.0000030 0.0000195 0.000046 0.000049 2004 6 27 53183 -0.019158 0.506265 -0.4695613 0.0001698 0.000052 -0.000010 0.000070 0.000063 0.0000025 0.0000197 0.000046 0.000048 2004 6 28 53184 -0.016293 0.507410 -0.4697178 0.0000622 0.000080 0.000056 0.000070 0.000063 0.0000020 0.0000199 0.000045 0.000048 2004 6 29 53185 -0.013163 0.508215 -0.4696878 -0.0000966 0.000108 0.000121 0.000070 0.000063 0.0000016 0.0000201 0.000045 0.000047 2004 6 30 53186 -0.010313 0.509307 -0.4694974 -0.0003252 0.000143 0.000077 0.000070 0.000063 0.0000077 0.0000203 0.000045 0.000047 2004 7 1 53187 -0.007596 0.510388 -0.4690542 -0.0005283 0.000180 0.000003 0.000070 0.000063 0.0000126 0.0000205 0.000045 0.000047 2004 7 2 53188 -0.004629 0.511228 -0.4683793 -0.0007021 0.000217 -0.000071 0.000070 0.000063 0.0000063 0.0000207 0.000045 0.000047 2004 7 3 53189 -0.001840 0.511879 -0.4676345 -0.0007874 0.000147 -0.000114 0.000070 0.000063 0.0000170 0.0000209 0.000045 0.000047 2004 7 4 53190 0.000447 0.512566 -0.4669416 -0.0006572 0.000038 -0.000146 0.000070 0.000063 0.0000191 0.0000210 0.000045 0.000047 2004 7 5 53191 0.002680 0.513270 -0.4664199 -0.0004068 -0.000071 -0.000178 0.000070 0.000063 0.0000138 0.0000212 0.000045 0.000047 2004 7 6 53192 0.005084 0.513958 -0.4661070 -0.0002097 -0.000179 -0.000211 0.000070 0.000064 0.0000085 0.0000214 0.000045 0.000047 2004 7 7 53193 0.007311 0.514519 -0.4659519 -0.0001130 0.000022 -0.000120 0.000071 0.000064 0.0000032 0.0000215 0.000045 0.000047 2004 7 8 53194 0.009446 0.515019 -0.4658649 -0.0000997 0.000142 -0.000055 0.000071 0.000064 0.0000044 0.0000217 0.000045 0.000047 2004 7 9 53195 0.012245 0.515377 -0.4657502 -0.0001638 0.000269 0.000006 0.000071 0.000064 0.0000046 0.0000218 0.000045 0.000046 2004 7 10 53196 0.015390 0.516377 -0.4655548 -0.0003090 0.000269 0.000026 0.000071 0.000064 0.0000180 0.0000220 0.000044 0.000046 2004 7 11 53197 0.018185 0.517197 -0.4651848 -0.0004816 0.000219 0.000032 0.000071 0.000064 0.0000195 0.0000221 0.000044 0.000046 2004 7 12 53198 0.021493 0.517972 -0.4646178 -0.0006235 0.000168 0.000037 0.000071 0.000064 0.0000124 0.0000223 0.000044 0.000045 2004 7 13 53199 0.024297 0.518919 -0.4638690 -0.0008173 0.000118 0.000043 0.000071 0.000064 0.0000054 0.0000224 0.000044 0.000045 2004 7 14 53200 0.026266 0.519457 -0.4629531 -0.0010083 0.000028 -0.000061 0.000071 0.000064 0.0000033 0.0000226 0.000043 0.000044 2004 7 15 53201 0.028258 0.520109 -0.4619262 -0.0010672 0.000030 -0.000133 0.000071 0.000064 0.0000028 0.0000227 0.000043 0.000044 2004 7 16 53202 0.030232 0.520641 -0.4608671 -0.0010607 0.000106 -0.000143 0.000070 0.000064 0.0000027 0.0000228 0.000043 0.000044 2004 7 17 53203 0.032644 0.520925 -0.4599028 -0.0009752 0.000130 -0.000099 0.000070 0.000063 0.0000230 0.0000230 0.000043 0.000044 2004 7 18 53204 0.035723 0.521069 -0.4590000 -0.0008360 0.000130 -0.000040 0.000070 0.000063 0.0000254 0.0000231 0.000043 0.000044 2004 7 19 53205 0.038773 0.521022 -0.4582292 -0.0006709 0.000130 0.000019 0.000070 0.000063 0.0000151 0.0000232 0.000043 0.000044 2004 7 20 53206 0.041349 0.520734 -0.4576632 -0.0004707 0.000130 0.000077 0.000070 0.000063 0.0000048 0.0000233 0.000043 0.000044 2004 7 21 53207 0.043931 0.520416 -0.4573220 -0.0002355 -0.000042 0.000018 0.000070 0.000063 0.0000034 0.0000235 0.000043 0.000044 2004 7 22 53208 0.046931 0.519976 -0.4571902 -0.0000501 -0.000012 -0.000067 0.000070 0.000063 0.0000047 0.0000236 0.000044 0.000044 2004 7 23 53209 0.050019 0.519661 -0.4572106 0.0000472 0.000089 -0.000152 0.000070 0.000063 0.0000062 0.0000237 0.000044 0.000044 2004 7 24 53210 0.052965 0.519372 -0.4573480 0.0000679 0.000112 -0.000123 0.000070 0.000063 0.0000179 0.0000238 0.000044 0.000044 2004 7 25 53211 0.056062 0.519279 -0.4574084 0.0000153 0.000105 -0.000051 0.000070 0.000062 0.0000193 0.0000240 0.000044 0.000044 2004 7 26 53212 0.059103 0.519319 -0.4573073 -0.0001516 0.000098 0.000021 0.000069 0.000062 0.0000136 0.0000241 0.000044 0.000044 2004 7 27 53213 0.061519 0.519284 -0.4570018 -0.0003795 0.000090 0.000093 0.000069 0.000062 0.0000078 0.0000242 0.000045 0.000044 2004 7 28 53214 0.063977 0.518911 -0.4564820 -0.0006010 0.000140 0.000075 0.000069 0.000062 0.0000089 0.0000243 0.000045 0.000044 2004 7 29 53215 0.066451 0.518584 -0.4557879 -0.0007566 0.000204 0.000033 0.000069 0.000062 0.0000117 0.0000244 0.000045 0.000044 2004 7 30 53216 0.068364 0.517946 -0.4550344 -0.0007184 0.000250 -0.000108 0.000069 0.000062 0.0000054 0.0000245 0.000044 0.000043 2004 7 31 53217 0.070300 0.517215 -0.4543853 -0.0005838 0.000229 -0.000140 0.000069 0.000062 0.0000142 0.0000246 0.000044 0.000043 2004 8 1 53218 0.072757 0.516401 -0.4539581 -0.0002917 0.000185 -0.000120 0.000069 0.000062 0.0000157 0.0000247 0.000044 0.000042 2004 8 2 53219 0.075501 0.515872 -0.4538057 0.0000035 0.000141 -0.000099 0.000069 0.000062 0.0000101 0.0000248 0.000044 0.000042 2004 8 3 53220 0.078263 0.515508 -0.4539040 0.0001776 0.000098 -0.000078 0.000069 0.000062 0.0000045 0.0000249 0.000043 0.000042 2004 8 4 53221 0.081082 0.515453 -0.4541786 0.0002573 0.000102 -0.000026 0.000069 0.000062 0.0000070 0.0000249 0.000043 0.000042 2004 8 5 53222 0.083870 0.515319 -0.4544702 0.0001977 0.000118 0.000034 0.000069 0.000062 0.0000099 0.0000250 0.000043 0.000042 2004 8 6 53223 0.086457 0.515236 -0.4545838 0.0001027 0.000135 0.000094 0.000069 0.000062 0.0000068 0.0000250 0.000043 0.000042 2004 8 7 53224 0.088786 0.515070 -0.4546423 -0.0000107 0.000148 0.000115 0.000069 0.000062 0.0000055 0.0000251 0.000043 0.000042 2004 8 8 53225 0.091671 0.514347 -0.4545494 -0.0001511 0.000161 0.000121 0.000069 0.000062 0.0000048 0.0000251 0.000043 0.000042 2004 8 9 53226 0.094810 0.513943 -0.4542675 -0.0003469 0.000173 0.000126 0.000069 0.000062 0.0000041 0.0000251 0.000043 0.000042 2004 8 10 53227 0.097254 0.513503 -0.4538190 -0.0005212 0.000185 0.000132 0.000069 0.000062 0.0000034 0.0000251 0.000043 0.000042 2004 8 11 53228 0.099722 0.512987 -0.4532925 -0.0005887 0.000172 0.000130 0.000069 0.000062 0.0000092 0.0000252 0.000042 0.000042 2004 8 12 53229 0.102642 0.513053 -0.4526861 -0.0006268 0.000150 0.000126 0.000069 0.000062 0.0000261 0.0000252 0.000042 0.000042 2004 8 13 53230 0.105709 0.513396 -0.4519745 -0.0006173 0.000129 0.000121 0.000069 0.000062 0.0000774 0.0000252 0.000042 0.000042 2004 8 14 53231 0.108721 0.513841 -0.4513690 -0.0005212 0.000141 0.000077 0.000069 0.000062 0.0000748 0.0000253 0.000042 0.000042 2004 8 15 53232 0.111505 0.513980 -0.4509251 -0.0003714 0.000166 0.000018 0.000070 0.000062 0.0000521 0.0000253 0.000042 0.000042 2004 8 16 53233 0.114599 0.513748 -0.4506873 -0.0001367 0.000190 -0.000041 0.000070 0.000062 0.0000295 0.0000254 0.000041 0.000042 2004 8 17 53234 0.117236 0.513308 -0.4506817 0.0000893 0.000215 -0.000100 0.000070 0.000062 0.0000068 0.0000254 0.000041 0.000041 2004 8 18 53235 0.119746 0.512539 -0.4509195 0.0003273 0.000167 -0.000254 0.000070 0.000062 0.0000032 0.0000254 0.000041 0.000041 2004 8 19 53236 0.121976 0.511989 -0.4513381 0.0004709 0.000148 -0.000275 0.000070 0.000062 0.0000168 0.0000255 0.000041 0.000042 2004 8 20 53237 0.124270 0.511317 -0.4518710 0.0005561 0.000176 -0.000175 0.000070 0.000062 0.0000093 0.0000255 0.000041 0.000042 2004 8 21 53238 0.126489 0.510635 -0.4523927 0.0004903 0.000178 -0.000146 0.000070 0.000062 0.0000047 0.0000256 0.000041 0.000041 2004 8 22 53239 0.128265 0.509572 -0.4527967 0.0003061 0.000165 -0.000153 0.000070 0.000062 0.0000042 0.0000256 0.000040 0.000041 2004 8 23 53240 0.130107 0.508232 -0.4530061 0.0000808 0.000152 -0.000161 0.000070 0.000062 0.0000037 0.0000256 0.000040 0.000040 2004 8 24 53241 0.132233 0.506535 -0.4529877 -0.0001172 0.000139 -0.000168 0.000070 0.000062 0.0000032 0.0000257 0.000040 0.000040 2004 8 25 53242 0.134378 0.505109 -0.4527707 -0.0002587 0.000138 -0.000182 0.000070 0.000062 0.0000024 0.0000257 0.000039 0.000039 2004 8 26 53243 0.136072 0.504076 -0.4524431 -0.0003407 0.000139 -0.000199 0.000070 0.000062 0.0000017 0.0000257 0.000039 0.000039 2004 8 27 53244 0.138404 0.502726 -0.4520906 -0.0003087 0.000125 -0.000128 0.000070 0.000063 0.0000038 0.0000257 0.000039 0.000039 2004 8 28 53245 0.141004 0.501591 -0.4518776 -0.0001771 0.000155 -0.000088 0.000070 0.000063 0.0000156 0.0000258 0.000039 0.000040 2004 8 29 53246 0.143657 0.500216 -0.4518732 0.0000868 0.000204 -0.000069 0.000070 0.000063 0.0000181 0.0000258 0.000039 0.000040 2004 8 30 53247 0.146837 0.498962 -0.4521316 0.0003915 0.000252 -0.000050 0.000070 0.000063 0.0000119 0.0000258 0.000040 0.000041 2004 8 31 53248 0.149606 0.497687 -0.4525887 0.0005331 0.000300 -0.000031 0.000070 0.000063 0.0000044 0.0000258 0.000040 0.000041 2004 9 1 53249 0.152207 0.495916 -0.4532007 0.0005742 0.000274 -0.000053 0.000070 0.000063 0.0000074 0.0000258 0.000040 0.000042 2004 9 2 53250 0.154856 0.494274 -0.4537613 0.0004747 0.000227 -0.000085 0.000070 0.000063 0.0000106 0.0000257 0.000040 0.000042 2004 9 3 53251 0.157019 0.492277 -0.4541041 0.0002922 0.000181 -0.000118 0.000070 0.000063 0.0000047 0.0000257 0.000039 0.000042 2004 9 4 53252 0.159234 0.490069 -0.4543136 0.0000444 0.000204 -0.000186 0.000070 0.000063 0.0000123 0.0000257 0.000039 0.000042 2004 9 5 53253 0.161638 0.487616 -0.4542274 -0.0002472 0.000253 -0.000268 0.000070 0.000063 0.0000126 0.0000257 0.000039 0.000042 2004 9 6 53254 0.163720 0.485074 -0.4538210 -0.0004838 0.000302 -0.000349 0.000070 0.000063 0.0000082 0.0000257 0.000039 0.000043 2004 9 7 53255 0.165335 0.482867 -0.4531809 -0.0006966 0.000350 -0.000429 0.000070 0.000063 0.0000049 0.0000257 0.000039 0.000043 2004 9 8 53256 0.167339 0.481023 -0.4524191 -0.0007818 0.000012 -0.000224 0.000070 0.000063 0.0000019 0.0000257 0.000039 0.000042 2004 9 9 53257 0.169398 0.479124 -0.4516232 -0.0007965 -0.000118 -0.000122 0.000070 0.000063 0.0000014 0.0000257 0.000038 0.000042 2004 9 10 53258 0.171667 0.477290 -0.4508890 -0.0006488 0.000071 0.000033 0.000070 0.000063 0.0000016 0.0000257 0.000038 0.000042 2004 9 11 53259 0.173926 0.475616 -0.4503845 -0.0004714 0.000152 0.000038 0.000070 0.000063 0.0000061 0.0000257 0.000038 0.000042 2004 9 12 53260 0.176129 0.473376 -0.4501217 -0.0001196 0.000160 -0.000023 0.000070 0.000064 0.0000096 0.0000257 0.000037 0.000042 2004 9 13 53261 0.178044 0.471088 -0.4501398 0.0001938 0.000168 -0.000084 0.000070 0.000064 0.0000075 0.0000256 0.000037 0.000042 2004 9 14 53262 0.179674 0.468691 -0.4504319 0.0004006 0.000177 -0.000145 0.000070 0.000064 0.0000034 0.0000256 0.000037 0.000042 2004 9 15 53263 0.181035 0.466383 -0.4509643 0.0006080 0.000183 -0.000149 0.000070 0.000064 0.0000041 0.0000257 0.000037 0.000042 2004 9 16 53264 0.182153 0.464071 -0.4516256 0.0006850 0.000157 -0.000074 0.000070 0.000064 0.0000033 0.0000258 0.000037 0.000042 2004 9 17 53265 0.183621 0.461616 -0.4523031 0.0006255 0.000142 -0.000002 0.000070 0.000064 0.0000018 0.0000259 0.000037 0.000041 2004 9 18 53266 0.184953 0.459384 -0.4528452 0.0004220 0.000138 0.000001 0.000070 0.000064 0.0000036 0.0000259 0.000037 0.000041 2004 9 19 53267 0.186447 0.457073 -0.4531758 0.0001627 0.000136 -0.000019 0.000070 0.000064 0.0000066 0.0000260 0.000037 0.000041 2004 9 20 53268 0.187851 0.454762 -0.4532256 -0.0000643 0.000133 -0.000039 0.000070 0.000064 0.0000060 0.0000260 0.000036 0.000041 2004 9 21 53269 0.189697 0.452266 -0.4530353 -0.0002024 0.000131 -0.000060 0.000070 0.000063 0.0000035 0.0000261 0.000036 0.000041 2004 9 22 53270 0.191665 0.450085 -0.4527674 -0.0003097 0.000150 -0.000107 0.000070 0.000063 0.0000142 0.0000261 0.000036 0.000041 2004 9 23 53271 0.193457 0.448205 -0.4524870 -0.0002428 0.000174 -0.000162 0.000070 0.000063 0.0000227 0.0000261 0.000036 0.000041 2004 9 24 53272 0.194960 0.446790 -0.4522690 -0.0000582 0.000198 -0.000217 0.000070 0.000063 0.0000100 0.0000262 0.000036 0.000041 2004 9 25 53273 0.195569 0.445036 -0.4523540 0.0002006 0.000175 -0.000203 0.000070 0.000063 0.0000082 0.0000262 0.000036 0.000040 2004 9 26 53274 0.195765 0.443084 -0.4526902 0.0004311 0.000134 -0.000163 0.000070 0.000063 0.0000094 0.0000263 0.000036 0.000040 2004 9 27 53275 0.196191 0.441038 -0.4532369 0.0006658 0.000094 -0.000124 0.000070 0.000063 0.0000072 0.0000263 0.000036 0.000040 2004 9 28 53276 0.197096 0.438852 -0.4539432 0.0007928 0.000053 -0.000084 0.000071 0.000063 0.0000037 0.0000263 0.000036 0.000039 2004 9 29 53277 0.197868 0.436713 -0.4547292 0.0007752 0.000112 -0.000056 0.000071 0.000063 0.0000176 0.0000263 0.000036 0.000039 2004 9 30 53278 0.198093 0.434223 -0.4554485 0.0006263 0.000196 -0.000030 0.000071 0.000064 0.0000285 0.0000264 0.000036 0.000039 2004 10 1 53279 0.198379 0.431826 -0.4559716 0.0004522 0.000112 -0.000184 0.000071 0.000064 0.0000103 0.0000264 0.000036 0.000039 2004 10 2 53280 0.198989 0.429396 -0.4563628 0.0003022 0.000089 -0.000208 0.000071 0.000064 0.0000113 0.0000265 0.000036 0.000039 2004 10 3 53281 0.199856 0.426852 -0.4565895 0.0001358 0.000108 -0.000164 0.000071 0.000064 0.0000112 0.0000265 0.000036 0.000039 2004 10 4 53282 0.200679 0.424371 -0.4566675 0.0000339 0.000128 -0.000119 0.000071 0.000064 0.0000070 0.0000265 0.000036 0.000039 2004 10 5 53283 0.201322 0.422058 -0.4566528 0.0000179 0.000148 -0.000075 0.000072 0.000064 0.0000028 0.0000265 0.000036 0.000038 2004 10 6 53284 0.201815 0.419568 -0.4566673 0.0000540 0.000094 -0.000051 0.000072 0.000064 0.0000020 0.0000266 0.000036 0.000038 2004 10 7 53285 0.202613 0.416963 -0.4567408 0.0001434 0.000183 -0.000185 0.000072 0.000064 0.0000017 0.0000266 0.000036 0.000038 2004 10 8 53286 0.203156 0.414603 -0.4568944 0.0002017 0.000318 -0.000195 0.000072 0.000064 0.0000036 0.0000267 0.000036 0.000038 2004 10 9 53287 0.203542 0.412303 -0.4571415 0.0003405 0.000317 -0.000179 0.000072 0.000065 0.0000040 0.0000267 0.000036 0.000039 2004 10 10 53288 0.203432 0.410317 -0.4575744 0.0005305 0.000267 -0.000174 0.000072 0.000065 0.0000035 0.0000268 0.000036 0.000039 2004 10 11 53289 0.203217 0.407842 -0.4582341 0.0007564 0.000216 -0.000170 0.000072 0.000065 0.0000030 0.0000268 0.000036 0.000039 2004 10 12 53290 0.203389 0.405423 -0.4591033 0.0009439 0.000166 -0.000165 0.000072 0.000065 0.0000025 0.0000268 0.000037 0.000039 2004 10 13 53291 0.203575 0.402909 -0.4601708 0.0010934 0.000171 -0.000138 0.000072 0.000065 0.0000042 0.0000269 0.000037 0.000039 2004 10 14 53292 0.203820 0.400049 -0.4612954 0.0011277 0.000191 -0.000105 0.000073 0.000065 0.0000064 0.0000269 0.000037 0.000040 2004 10 15 53293 0.204530 0.397230 -0.4623684 0.0009868 0.000187 0.000094 0.000073 0.000065 0.0000039 0.0000269 0.000037 0.000040 2004 10 16 53294 0.205392 0.394940 -0.4633121 0.0007685 0.000187 0.000107 0.000073 0.000065 0.0000067 0.0000269 0.000038 0.000040 2004 10 17 53295 0.205828 0.392800 -0.4639237 0.0004605 0.000190 0.000032 0.000073 0.000065 0.0000073 0.0000269 0.000038 0.000041 2004 10 18 53296 0.206049 0.390646 -0.4641869 0.0001642 0.000194 -0.000043 0.000073 0.000066 0.0000051 0.0000269 0.000038 0.000041 2004 10 19 53297 0.205956 0.388811 -0.4642336 0.0000116 0.000197 -0.000118 0.000073 0.000066 0.0000025 0.0000269 0.000038 0.000041 2004 10 20 53298 0.205880 0.386634 -0.4642354 0.0000235 0.000218 -0.000093 0.000073 0.000066 0.0000147 0.0000269 0.000038 0.000041 2004 10 21 53299 0.206033 0.384704 -0.4642995 0.0001406 0.000243 -0.000042 0.000073 0.000066 0.0000243 0.0000269 0.000039 0.000042 2004 10 22 53300 0.206019 0.382754 -0.4645086 0.0003310 0.000269 0.000008 0.000073 0.000066 0.0000098 0.0000269 0.000039 0.000042 2004 10 23 53301 0.205969 0.380897 -0.4649853 0.0005423 0.000247 -0.000027 0.000073 0.000066 0.0000075 0.0000268 0.000040 0.000043 2004 10 24 53302 0.205493 0.379190 -0.4656671 0.0007443 0.000207 -0.000095 0.000073 0.000066 0.0000102 0.0000268 0.000040 0.000043 2004 10 25 53303 0.204995 0.377016 -0.4664709 0.0008706 0.000168 -0.000163 0.000073 0.000066 0.0000078 0.0000267 0.000040 0.000044 2004 10 26 53304 0.205271 0.374877 -0.4673310 0.0008663 0.000128 -0.000231 0.000073 0.000066 0.0000028 0.0000267 0.000041 0.000044 2004 10 27 53305 0.205842 0.372687 -0.4682255 0.0008566 0.000264 -0.000184 0.000073 0.000066 0.0000121 0.0000267 0.000041 0.000044 2004 10 28 53306 0.206671 0.370334 -0.4690441 0.0007405 0.000252 -0.000179 0.000073 0.000067 0.0000050 0.0000266 0.000041 0.000045 2004 10 29 53307 0.207188 0.368097 -0.4696894 0.0005257 0.000148 -0.000147 0.000074 0.000067 0.0000024 0.0000266 0.000042 0.000045 2004 10 30 53308 0.207239 0.365973 -0.4701204 0.0002558 0.000132 -0.000126 0.000074 0.000067 0.0000104 0.0000265 0.000042 0.000046 2004 10 31 53309 0.206917 0.363835 -0.4703152 0.0000871 0.000151 -0.000115 0.000073 0.000067 0.0000106 0.0000265 0.000043 0.000046 2004 11 1 53310 0.207261 0.361540 -0.4703406 0.0000059 0.000170 -0.000104 0.000073 0.000067 0.0000068 0.0000264 0.000043 0.000047 2004 11 2 53311 0.208117 0.359450 -0.4702916 -0.0000209 0.000189 -0.000094 0.000074 0.000067 0.0000037 0.0000263 0.000044 0.000047 2004 11 3 53312 0.208249 0.357341 -0.4702707 -0.0000063 0.000266 -0.000141 0.000074 0.000067 0.0000056 0.0000263 0.000044 0.000048 2004 11 4 53313 0.208089 0.355076 -0.4703235 0.0001133 0.000358 -0.000205 0.000074 0.000067 0.0000075 0.0000263 0.000044 0.000048 2004 11 5 53314 0.207723 0.352388 -0.4704621 0.0002607 0.000197 -0.000209 0.000074 0.000067 0.0000045 0.0000263 0.000045 0.000048 2004 11 6 53315 0.207846 0.349577 -0.4708763 0.0005189 0.000125 -0.000229 0.000074 0.000067 0.0000093 0.0000262 0.000045 0.000049 2004 11 7 53316 0.207903 0.347003 -0.4715444 0.0007671 0.000116 -0.000262 0.000074 0.000067 0.0000104 0.0000262 0.000045 0.000049 2004 11 8 53317 0.208054 0.344715 -0.4724478 0.0010321 0.000108 -0.000294 0.000074 0.000067 0.0000070 0.0000262 0.000046 0.000050 2004 11 9 53318 0.208041 0.343007 -0.4735624 0.0012099 0.000099 -0.000326 0.000074 0.000067 0.0000027 0.0000262 0.000046 0.000050 2004 11 10 53319 0.208023 0.341230 -0.4748664 0.0013178 -0.000015 -0.000509 0.000074 0.000067 0.0000269 0.0000261 0.000047 0.000051 2004 11 11 53320 0.207927 0.339280 -0.4761684 0.0012729 0.000059 -0.000412 0.000074 0.000067 0.0000223 0.0000261 0.000047 0.000051 2004 11 12 53321 0.207795 0.336884 -0.4773461 0.0011070 0.000196 -0.000223 0.000074 0.000067 0.0000072 0.0000261 0.000047 0.000051 2004 11 13 53322 0.208037 0.334492 -0.4783802 0.0008539 0.000231 -0.000185 0.000074 0.000068 0.0000093 0.0000260 0.000047 0.000051 2004 11 14 53323 0.207899 0.332232 -0.4790798 0.0005605 0.000228 -0.000203 0.000074 0.000068 0.0000100 0.0000260 0.000047 0.000051 2004 11 15 53324 0.207675 0.329463 -0.4795109 0.0003628 0.000224 -0.000221 0.000074 0.000068 0.0000072 0.0000260 0.000047 0.000052 2004 11 16 53325 0.207457 0.326990 -0.4798321 0.0003305 0.000221 -0.000239 0.000074 0.000068 0.0000046 0.0000260 0.000048 0.000052 2004 11 17 53326 0.207180 0.324556 -0.4801965 0.0004306 0.000238 -0.000247 0.000074 0.000068 0.0000073 0.0000259 0.000048 0.000052 2004 11 18 53327 0.206952 0.322230 -0.4806547 0.0005940 0.000375 -0.000153 0.000074 0.000068 0.0000162 0.0000259 0.000048 0.000052 2004 11 19 53328 0.206675 0.319976 -0.4813719 0.0008268 0.000264 -0.000216 0.000074 0.000068 0.0000079 0.0000259 0.000047 0.000051 2004 11 20 53329 0.206010 0.317994 -0.4823390 0.0010179 0.000204 -0.000238 0.000075 0.000068 0.0000066 0.0000258 0.000047 0.000051 2004 11 21 53330 0.205616 0.315679 -0.4834310 0.0011284 0.000193 -0.000226 0.000075 0.000068 0.0000082 0.0000258 0.000047 0.000051 2004 11 22 53331 0.205029 0.313541 -0.4845596 0.0011281 0.000182 -0.000214 0.000075 0.000068 0.0000084 0.0000258 0.000047 0.000051 2004 11 23 53332 0.204271 0.311349 -0.4856383 0.0010675 0.000171 -0.000202 0.000075 0.000068 0.0000084 0.0000257 0.000047 0.000051 2004 11 24 53333 0.203105 0.309229 -0.4866025 0.0008832 0.000297 -0.000053 0.000075 0.000068 0.0000087 0.0000257 0.000047 0.000051 2004 11 25 53334 0.201776 0.306908 -0.4873686 0.0006837 0.000298 -0.000103 0.000075 0.000068 0.0000082 0.0000257 0.000047 0.000051 2004 11 26 53335 0.200535 0.304532 -0.4879059 0.0004675 0.000240 -0.000240 0.000075 0.000068 0.0000074 0.0000257 0.000047 0.000050 2004 11 27 53336 0.199824 0.302093 -0.4882234 0.0001916 0.000226 -0.000186 0.000075 0.000068 0.0000067 0.0000257 0.000046 0.000049 2004 11 28 53337 0.199476 0.300020 -0.4883594 0.0000680 0.000213 -0.000129 0.000075 0.000068 0.0000059 0.0000258 0.000045 0.000048 2004 11 29 53338 0.199221 0.298096 -0.4883762 -0.0000173 0.000200 -0.000072 0.000075 0.000068 0.0000051 0.0000258 0.000045 0.000047 2004 11 30 53339 0.198533 0.296012 -0.4883504 -0.0000360 0.000187 -0.000015 0.000075 0.000068 0.0000043 0.0000258 0.000044 0.000046 2004 12 1 53340 0.197499 0.293669 -0.4883461 0.0000568 0.000232 -0.000068 0.000075 0.000068 0.0000128 0.0000258 0.000044 0.000046 2004 12 2 53341 0.195940 0.291458 -0.4884545 0.0002103 0.000208 -0.000219 0.000075 0.000068 0.0000047 0.0000258 0.000043 0.000045 2004 12 3 53342 0.193964 0.288932 -0.4887257 0.0003613 0.000212 -0.000438 0.000075 0.000068 0.0000031 0.0000258 0.000043 0.000045 2004 12 4 53343 0.192122 0.286572 -0.4892188 0.0005608 0.000218 -0.000466 0.000075 0.000068 0.0000131 0.0000259 0.000043 0.000045 2004 12 5 53344 0.190480 0.284617 -0.4899091 0.0007719 0.000218 -0.000419 0.000075 0.000068 0.0000129 0.0000259 0.000043 0.000045 2004 12 6 53345 0.188776 0.282791 -0.4907559 0.0009344 0.000219 -0.000372 0.000075 0.000068 0.0000083 0.0000259 0.000043 0.000045 2004 12 7 53346 0.187374 0.280572 -0.4917328 0.0010792 0.000219 -0.000324 0.000075 0.000068 0.0000048 0.0000259 0.000043 0.000045 2004 12 8 53347 0.186313 0.278674 -0.4928297 0.0010936 0.000187 -0.000305 0.000075 0.000068 0.0000048 0.0000258 0.000042 0.000045 2004 12 9 53348 0.184303 0.277100 -0.4938651 0.0009545 0.000014 -0.000412 0.000075 0.000068 0.0000095 0.0000258 0.000042 0.000046 2004 12 10 53349 0.182218 0.274808 -0.4946839 0.0007199 0.000189 -0.000539 0.000075 0.000068 0.0000102 0.0000258 0.000042 0.000045 2004 12 11 53350 0.180311 0.272814 -0.4953529 0.0004783 0.000248 -0.000531 0.000075 0.000068 0.0000091 0.0000257 0.000041 0.000045 2004 12 12 53351 0.178442 0.270911 -0.4957343 0.0002876 0.000221 -0.000470 0.000075 0.000068 0.0000069 0.0000257 0.000041 0.000044 2004 12 13 53352 0.176593 0.268813 -0.4959235 0.0001792 0.000195 -0.000409 0.000075 0.000068 0.0000043 0.0000256 0.000040 0.000043 2004 12 14 53353 0.174718 0.266767 -0.4961086 0.0002500 0.000168 -0.000349 0.000075 0.000068 0.0000017 0.0000255 0.000040 0.000043 2004 12 15 53354 0.173165 0.264468 -0.4965091 0.0005080 0.000093 -0.000283 0.000075 0.000068 0.0000028 0.0000255 0.000040 0.000042 2004 12 16 53355 0.171762 0.262413 -0.4971348 0.0007129 0.000168 -0.000269 0.000075 0.000068 0.0000040 0.0000254 0.000040 0.000042 2004 12 17 53356 0.170232 0.260650 -0.4979092 0.0009223 0.000226 -0.000275 0.000075 0.000068 0.0000022 0.0000254 0.000039 0.000041 2004 12 18 53357 0.169280 0.259006 -0.4989305 0.0010412 0.000197 -0.000296 0.000075 0.000068 0.0000058 0.0000253 0.000039 0.000041 2004 12 19 53358 0.168686 0.257496 -0.5000220 0.0010499 0.000142 -0.000322 0.000075 0.000068 0.0000073 0.0000253 0.000039 0.000040 2004 12 20 53359 0.167525 0.256086 -0.5010499 0.0009941 0.000088 -0.000349 0.000075 0.000068 0.0000051 0.0000252 0.000039 0.000040 2004 12 21 53360 0.165939 0.254249 -0.5019347 0.0008117 0.000033 -0.000375 0.000075 0.000068 0.0000020 0.0000252 0.000039 0.000040 2004 12 22 53361 0.164464 0.252347 -0.5026258 0.0005417 0.000081 -0.000234 0.000075 0.000068 0.0000019 0.0000252 0.000039 0.000040 2004 12 23 53362 0.163037 0.250328 -0.5030892 0.0003687 0.000156 -0.000049 0.000075 0.000068 0.0000024 0.0000253 0.000039 0.000040 2004 12 24 53363 0.161470 0.248787 -0.5033355 0.0001592 0.000144 -0.000024 0.000075 0.000068 0.0000031 0.0000253 0.000039 0.000040 2004 12 25 53364 0.159784 0.247418 -0.5033907 -0.0000870 0.000099 -0.000057 0.000076 0.000068 0.0000038 0.0000253 0.000039 0.000040 2004 12 26 53365 0.158236 0.246633 -0.5033060 -0.0001381 0.000054 -0.000090 0.000076 0.000069 0.0000045 0.0000253 0.000039 0.000040 2004 12 27 53366 0.156367 0.245814 -0.5031521 -0.0001428 0.000009 -0.000124 0.000076 0.000069 0.0000052 0.0000254 0.000039 0.000040 2004 12 28 53367 0.154498 0.244030 -0.5030061 -0.0001201 -0.000036 -0.000157 0.000076 0.000069 0.0000060 0.0000254 0.000039 0.000040 2004 12 29 53368 0.152852 0.242500 -0.5029177 -0.0000171 0.000019 -0.000238 0.000076 0.000069 0.0000046 0.0000255 0.000039 0.000040 2004 12 30 53369 0.151072 0.241154 -0.5029619 0.0001127 0.000102 -0.000333 0.000076 0.000069 0.0000027 0.0000255 0.000039 0.000040 2004 12 31 53370 0.149967 0.239387 -0.5032262 0.0003514 0.000106 -0.000367 0.000076 0.000069 0.0000036 0.0000256 0.000039 0.000040 2005 1 1 53371 0.149088 0.238172 -0.5036955 0.0005354 0.000080 -0.000379 0.000073 0.000071 0.0000060 0.0000253 0.000046 0.000044 2005 1 2 53372 0.148626 0.236999 -0.5043413 0.0006944 0.000055 -0.000390 0.000073 0.000071 0.0000073 0.0000254 0.000046 0.000045 2005 1 3 53373 0.148673 0.235973 -0.5050791 0.0008110 0.000029 -0.000402 0.000073 0.000071 0.0000074 0.0000255 0.000046 0.000045 2005 1 4 53374 0.148433 0.235016 -0.5058696 0.0008450 0.000003 -0.000414 0.000073 0.000071 0.0000069 0.0000255 0.000046 0.000045 2005 1 5 53375 0.148032 0.233585 -0.5067085 0.0007698 0.000006 -0.000390 0.000073 0.000071 0.0000150 0.0000256 0.000046 0.000046 2005 1 6 53376 0.146875 0.231987 -0.5074322 0.0006017 0.000016 -0.000357 0.000073 0.000071 0.0000209 0.0000257 0.000047 0.000046 2005 1 7 53377 0.145062 0.230078 -0.5078790 0.0003652 0.000026 -0.000324 0.000073 0.000071 0.0000097 0.0000257 0.000047 0.000047 2005 1 8 53378 0.143407 0.228186 -0.5082069 0.0001923 0.000042 -0.000324 0.000073 0.000071 0.0000072 0.0000258 0.000047 0.000047 2005 1 9 53379 0.141885 0.227052 -0.5083876 0.0001463 0.000061 -0.000336 0.000073 0.000071 0.0000093 0.0000259 0.000047 0.000047 2005 1 10 53380 0.139863 0.225857 -0.5085225 0.0002226 0.000080 -0.000348 0.000073 0.000070 0.0000087 0.0000260 0.000047 0.000048 2005 1 11 53381 0.137274 0.224639 -0.5087813 0.0004203 0.000098 -0.000360 0.000073 0.000070 0.0000062 0.0000261 0.000047 0.000048 2005 1 12 53382 0.135134 0.223347 -0.5093157 0.0007159 0.000213 -0.000410 0.000073 0.000070 0.0000077 0.0000261 0.000047 0.000049 2005 1 13 53383 0.133504 0.222204 -0.5101598 0.0009812 0.000203 -0.000422 0.000073 0.000070 0.0000101 0.0000262 0.000047 0.000049 2005 1 14 53384 0.131823 0.221194 -0.5112550 0.0011798 0.000079 -0.000375 0.000073 0.000070 0.0000076 0.0000263 0.000047 0.000049 2005 1 15 53385 0.129974 0.220049 -0.5124927 0.0012154 0.000058 -0.000484 0.000073 0.000070 0.0000074 0.0000265 0.000047 0.000049 2005 1 16 53386 0.128598 0.218676 -0.5137071 0.0011732 0.000082 -0.000657 0.000073 0.000070 0.0000080 0.0000266 0.000047 0.000049 2005 1 17 53387 0.127348 0.217547 -0.5148107 0.0010337 0.000107 -0.000830 0.000073 0.000070 0.0000069 0.0000267 0.000047 0.000050 2005 1 18 53388 0.125856 0.216463 -0.5157296 0.0008353 0.000131 -0.001003 0.000073 0.000070 0.0000053 0.0000268 0.000046 0.000050 2005 1 19 53389 0.124053 0.215957 -0.5164186 0.0005978 -0.000031 -0.000429 0.000073 0.000070 0.0000036 0.0000269 0.000046 0.000049 2005 1 20 53390 0.121576 0.215407 -0.5168931 0.0003954 -0.000045 -0.000297 0.000073 0.000070 0.0000030 0.0000270 0.000046 0.000049 2005 1 21 53391 0.119194 0.214327 -0.5172191 0.0002566 0.000148 -0.000346 0.000073 0.000070 0.0000053 0.0000272 0.000046 0.000049 2005 1 22 53392 0.117093 0.213470 -0.5174463 0.0001335 0.000174 -0.000359 0.000073 0.000070 0.0000061 0.0000273 0.000046 0.000050 2005 1 23 53393 0.114606 0.212634 -0.5175424 0.0000665 0.000117 -0.000353 0.000072 0.000070 0.0000076 0.0000274 0.000046 0.000050 2005 1 24 53394 0.112378 0.211659 -0.5175505 0.0000436 0.000060 -0.000346 0.000072 0.000069 0.0000072 0.0000275 0.000047 0.000050 2005 1 25 53395 0.109985 0.210771 -0.5175815 0.0000304 0.000003 -0.000339 0.000072 0.000069 0.0000056 0.0000276 0.000047 0.000050 2005 1 26 53396 0.107590 0.209752 -0.5177112 0.0001728 0.000035 -0.000286 0.000072 0.000069 0.0000131 0.0000276 0.000047 0.000051 2005 1 27 53397 0.105423 0.209386 -0.5179836 0.0003966 0.000101 -0.000248 0.000072 0.000069 0.0000230 0.0000277 0.000047 0.000051 2005 1 28 53398 0.103223 0.209165 -0.5184417 0.0005622 0.000151 -0.000198 0.000072 0.000069 0.0000111 0.0000277 0.000047 0.000051 2005 1 29 53399 0.100740 0.209172 -0.5190872 0.0006660 0.000141 -0.000181 0.000072 0.000069 0.0000081 0.0000278 0.000046 0.000050 2005 1 30 53400 0.097497 0.208953 -0.5197472 0.0006958 0.000111 -0.000178 0.000072 0.000069 0.0000100 0.0000278 0.000046 0.000050 2005 1 31 53401 0.094633 0.208522 -0.5204613 0.0007355 0.000080 -0.000176 0.000072 0.000069 0.0000094 0.0000278 0.000046 0.000049 2005 2 1 53402 0.091946 0.208519 -0.5211936 0.0007178 0.000049 -0.000173 0.000072 0.000069 0.0000078 0.0000278 0.000046 0.000049 2005 2 2 53403 0.089160 0.207869 -0.5218835 0.0006142 0.000075 -0.000107 0.000072 0.000069 0.0000142 0.0000278 0.000045 0.000049 2005 2 3 53404 0.086517 0.207056 -0.5224131 0.0004246 0.000084 -0.000094 0.000072 0.000069 0.0000165 0.0000279 0.000045 0.000048 2005 2 4 53405 0.083834 0.206384 -0.5227505 0.0002314 0.000062 -0.000353 0.000072 0.000069 0.0000073 0.0000279 0.000044 0.000047 2005 2 5 53406 0.081471 0.206035 -0.5229630 0.0001862 0.000044 -0.000429 0.000072 0.000069 0.0000082 0.0000279 0.000044 0.000046 2005 2 6 53407 0.078851 0.206020 -0.5232340 0.0002706 0.000031 -0.000406 0.000072 0.000069 0.0000084 0.0000279 0.000043 0.000046 2005 2 7 53408 0.076054 0.206024 -0.5235507 0.0004181 0.000017 -0.000384 0.000072 0.000069 0.0000062 0.0000279 0.000043 0.000045 2005 2 8 53409 0.073079 0.205719 -0.5240565 0.0006633 0.000004 -0.000361 0.000072 0.000070 0.0000042 0.0000279 0.000042 0.000044 2005 2 9 53410 0.069978 0.205219 -0.5248692 0.0010023 -0.000071 -0.000178 0.000072 0.000070 0.0000031 0.0000278 0.000042 0.000044 2005 2 10 53411 0.066735 0.204505 -0.5260268 0.0012866 0.000030 -0.000206 0.000072 0.000070 0.0000047 0.0000278 0.000041 0.000044 2005 2 11 53412 0.064062 0.203836 -0.5274541 0.0015419 0.000032 -0.000207 0.000072 0.000070 0.0000039 0.0000278 0.000041 0.000043 2005 2 12 53413 0.061492 0.203425 -0.5290445 0.0015789 0.000013 -0.000224 0.000072 0.000070 0.0000063 0.0000278 0.000041 0.000043 2005 2 13 53414 0.059239 0.203151 -0.5305907 0.0014256 0.000004 -0.000258 0.000072 0.000069 0.0000064 0.0000277 0.000041 0.000043 2005 2 14 53415 0.057272 0.203380 -0.5319072 0.0011938 -0.000005 -0.000293 0.000072 0.000069 0.0000051 0.0000277 0.000041 0.000043 2005 2 15 53416 0.054751 0.203537 -0.5329684 0.0009551 -0.000014 -0.000327 0.000072 0.000069 0.0000042 0.0000276 0.000041 0.000043 2005 2 16 53417 0.051772 0.203322 -0.5337671 0.0006456 -0.000033 -0.000441 0.000072 0.000069 0.0000577 0.0000276 0.000041 0.000043 2005 2 17 53418 0.048485 0.203081 -0.5343056 0.0004146 -0.000024 -0.000513 0.000071 0.000069 0.0000245 0.0000275 0.000041 0.000043 2005 2 18 53419 0.045495 0.203341 -0.5347018 0.0003790 0.000023 -0.000456 0.000071 0.000069 0.0000046 0.0000274 0.000041 0.000043 2005 2 19 53420 0.042583 0.204032 -0.5351414 0.0004636 0.000039 -0.000397 0.000071 0.000069 0.0000053 0.0000274 0.000041 0.000042 2005 2 20 53421 0.040175 0.204680 -0.5356752 0.0005860 0.000039 -0.000352 0.000071 0.000069 0.0000061 0.0000273 0.000041 0.000042 2005 2 21 53422 0.037676 0.205485 -0.5363086 0.0007274 0.000039 -0.000308 0.000071 0.000069 0.0000049 0.0000272 0.000041 0.000042 2005 2 22 53423 0.035443 0.205952 -0.5371029 0.0009172 0.000039 -0.000263 0.000071 0.000069 0.0000032 0.0000271 0.000041 0.000041 2005 2 23 53424 0.033268 0.206342 -0.5381132 0.0010933 0.000013 -0.000256 0.000071 0.000069 0.0000082 0.0000270 0.000041 0.000041 2005 2 24 53425 0.031458 0.206307 -0.5393396 0.0013172 -0.000021 -0.000258 0.000071 0.000069 0.0000124 0.0000270 0.000041 0.000040 2005 2 25 53426 0.030356 0.206829 -0.5407080 0.0015254 -0.000054 -0.000261 0.000071 0.000069 0.0000065 0.0000269 0.000041 0.000040 2005 2 26 53427 0.029291 0.207702 -0.5423395 0.0016920 -0.000075 -0.000288 0.000071 0.000069 0.0000077 0.0000269 0.000040 0.000040 2005 2 27 53428 0.027691 0.208794 -0.5440821 0.0017223 -0.000091 -0.000324 0.000071 0.000069 0.0000107 0.0000268 0.000040 0.000039 2005 2 28 53429 0.025851 0.209941 -0.5457738 0.0016362 -0.000107 -0.000360 0.000070 0.000068 0.0000085 0.0000268 0.000040 0.000039 2005 3 1 53430 0.024087 0.211438 -0.5473574 0.0015604 -0.000123 -0.000396 0.000071 0.000068 0.0000038 0.0000267 0.000040 0.000038 2005 3 2 53431 0.021836 0.213078 -0.5488606 0.0013744 -0.000106 -0.000419 0.000071 0.000068 0.0000119 0.0000266 0.000040 0.000038 2005 3 3 53432 0.019350 0.214344 -0.5501639 0.0011886 -0.000080 -0.000438 0.000071 0.000068 0.0000183 0.0000266 0.000040 0.000038 2005 3 4 53433 0.017092 0.215268 -0.5512345 0.0010358 -0.000054 -0.000457 0.000071 0.000068 0.0000056 0.0000266 0.000040 0.000038 2005 3 5 53434 0.015138 0.216096 -0.5522401 0.0009613 -0.000023 -0.000435 0.000071 0.000068 0.0000047 0.0000265 0.000040 0.000038 2005 3 6 53435 0.012688 0.216774 -0.5531766 0.0009303 0.000009 -0.000398 0.000071 0.000068 0.0000062 0.0000265 0.000040 0.000039 2005 3 7 53436 0.010530 0.217180 -0.5541217 0.0010035 0.000042 -0.000361 0.000071 0.000068 0.0000051 0.0000264 0.000040 0.000039 2005 3 8 53437 0.008759 0.217966 -0.5552302 0.0011663 0.000074 -0.000323 0.000071 0.000068 0.0000032 0.0000264 0.000040 0.000039 2005 3 9 53438 0.006826 0.218806 -0.5565089 0.0013373 0.000035 -0.000262 0.000071 0.000068 0.0000102 0.0000263 0.000040 0.000039 2005 3 10 53439 0.004732 0.219640 -0.5579480 0.0014650 -0.000022 -0.000194 0.000071 0.000068 0.0000157 0.0000263 0.000041 0.000040 2005 3 11 53440 0.002473 0.220491 -0.5594054 0.0015260 -0.000080 -0.000126 0.000071 0.000068 0.0000064 0.0000263 0.000041 0.000040 2005 3 12 53441 0.000430 0.221410 -0.5609322 0.0014798 -0.000081 -0.000113 0.000071 0.000068 0.0000058 0.0000262 0.000041 0.000040 2005 3 13 53442 -0.001543 0.222222 -0.5623245 0.0012717 -0.000060 -0.000120 0.000071 0.000068 0.0000053 0.0000261 0.000041 0.000040 2005 3 14 53443 -0.002587 0.222649 -0.5634050 0.0009778 -0.000039 -0.000127 0.000071 0.000068 0.0000051 0.0000261 0.000042 0.000041 2005 3 15 53444 -0.003794 0.223282 -0.5641554 0.0006054 -0.000018 -0.000133 0.000071 0.000068 0.0000057 0.0000260 0.000042 0.000041 2005 3 16 53445 -0.005622 0.223507 -0.5645723 0.0002913 0.000012 -0.000197 0.000071 0.000068 0.0000057 0.0000260 0.000042 0.000041 2005 3 17 53446 -0.006911 0.223787 -0.5647578 0.0000990 0.000001 -0.000301 0.000071 0.000068 0.0000055 0.0000259 0.000042 0.000041 2005 3 18 53447 -0.008073 0.224199 -0.5648134 0.0000279 0.000082 -0.000316 0.000071 0.000068 0.0000042 0.0000259 0.000042 0.000041 2005 3 19 53448 -0.008995 0.224958 -0.5648804 0.0000625 0.000079 -0.000302 0.000071 0.000068 0.0000048 0.0000258 0.000042 0.000041 2005 3 20 53449 -0.009845 0.225999 -0.5649555 0.0001430 0.000031 -0.000291 0.000071 0.000068 0.0000067 0.0000258 0.000042 0.000041 2005 3 21 53450 -0.010682 0.227026 -0.5651098 0.0002364 -0.000017 -0.000279 0.000071 0.000068 0.0000058 0.0000257 0.000042 0.000041 2005 3 22 53451 -0.011720 0.228376 -0.5654391 0.0004026 -0.000064 -0.000267 0.000072 0.000068 0.0000034 0.0000257 0.000042 0.000042 2005 3 23 53452 -0.013260 0.230378 -0.5660395 0.0007129 0.000058 -0.000316 0.000072 0.000068 0.0000043 0.0000256 0.000042 0.000042 2005 3 24 53453 -0.015268 0.231983 -0.5668744 0.0009870 -0.000020 -0.000223 0.000072 0.000068 0.0000060 0.0000256 0.000042 0.000042 2005 3 25 53454 -0.016593 0.233186 -0.5679183 0.0011799 -0.000066 -0.000195 0.000072 0.000068 0.0000060 0.0000255 0.000042 0.000042 2005 3 26 53455 -0.017797 0.234616 -0.5690893 0.0012209 -0.000073 -0.000208 0.000072 0.000068 0.0000053 0.0000255 0.000042 0.000041 2005 3 27 53456 -0.019258 0.236328 -0.5702828 0.0011524 -0.000080 -0.000220 0.000072 0.000068 0.0000047 0.0000254 0.000041 0.000041 2005 3 28 53457 -0.020756 0.238067 -0.5713910 0.0010139 -0.000087 -0.000232 0.000072 0.000068 0.0000041 0.0000254 0.000041 0.000041 2005 3 29 53458 -0.022615 0.239361 -0.5723190 0.0008129 -0.000094 -0.000244 0.000072 0.000068 0.0000035 0.0000253 0.000041 0.000041 2005 3 30 53459 -0.024699 0.240368 -0.5729579 0.0005150 -0.000111 -0.000289 0.000072 0.000069 0.0000030 0.0000253 0.000041 0.000040 2005 3 31 53460 -0.026890 0.241358 -0.5733457 0.0002519 -0.000130 -0.000342 0.000072 0.000069 0.0000026 0.0000252 0.000041 0.000040 2005 4 1 53461 -0.028783 0.242814 -0.5735279 0.0000689 0.000042 -0.000290 0.000072 0.000069 0.0000033 0.0000252 0.000041 0.000040 2005 4 2 53462 -0.030786 0.244139 -0.5736871 0.0001137 0.000060 -0.000265 0.000073 0.000069 0.0000054 0.0000252 0.000041 0.000040 2005 4 3 53463 -0.032436 0.245137 -0.5739347 0.0003233 -0.000003 -0.000261 0.000073 0.000069 0.0000078 0.0000253 0.000042 0.000041 2005 4 4 53464 -0.033506 0.245843 -0.5743755 0.0006019 -0.000065 -0.000257 0.000073 0.000069 0.0000102 0.0000253 0.000042 0.000041 2005 4 5 53465 -0.034501 0.246104 -0.5750866 0.0008914 -0.000127 -0.000253 0.000073 0.000069 0.0000126 0.0000253 0.000042 0.000041 2005 4 6 53466 -0.035010 0.246525 -0.5760663 0.0010895 -0.000167 -0.000274 0.000073 0.000069 0.0000110 0.0000253 0.000042 0.000041 2005 4 7 53467 -0.035501 0.248014 -0.5772352 0.0012293 -0.000182 -0.000312 0.000073 0.000070 0.0000053 0.0000253 0.000042 0.000041 2005 4 8 53468 -0.036571 0.250285 -0.5785146 0.0012902 -0.000091 -0.000240 0.000073 0.000070 0.0000041 0.0000253 0.000042 0.000040 2005 4 9 53469 -0.038421 0.252528 -0.5798337 0.0011818 -0.000060 -0.000222 0.000073 0.000070 0.0000046 0.0000253 0.000041 0.000040 2005 4 10 53470 -0.040678 0.254115 -0.5808621 0.0009042 -0.000063 -0.000238 0.000073 0.000070 0.0000041 0.0000252 0.000041 0.000039 2005 4 11 53471 -0.042574 0.255456 -0.5815815 0.0005834 -0.000066 -0.000253 0.000073 0.000070 0.0000030 0.0000252 0.000041 0.000039 2005 4 12 53472 -0.044257 0.256944 -0.5820669 0.0003452 -0.000070 -0.000269 0.000073 0.000070 0.0000019 0.0000252 0.000041 0.000039 2005 4 13 53473 -0.045491 0.258781 -0.5824080 0.0002306 -0.000078 -0.000232 0.000073 0.000070 0.0000053 0.0000252 0.000041 0.000039 2005 4 14 53474 -0.046144 0.260547 -0.5826471 0.0002092 -0.000089 -0.000181 0.000073 0.000070 0.0000081 0.0000252 0.000041 0.000039 2005 4 15 53475 -0.046718 0.262504 -0.5828579 0.0002565 -0.000099 -0.000130 0.000073 0.000070 0.0000046 0.0000251 0.000041 0.000039 2005 4 16 53476 -0.047848 0.264970 -0.5832088 0.0003683 -0.000080 -0.000112 0.000073 0.000070 0.0000074 0.0000251 0.000041 0.000039 2005 4 17 53477 -0.049356 0.267392 -0.5837106 0.0005330 -0.000052 -0.000106 0.000073 0.000070 0.0000093 0.0000251 0.000041 0.000039 2005 4 18 53478 -0.051000 0.269644 -0.5843354 0.0007191 -0.000023 -0.000100 0.000073 0.000070 0.0000071 0.0000251 0.000041 0.000039 2005 4 19 53479 -0.052486 0.271896 -0.5851496 0.0009447 0.000006 -0.000094 0.000073 0.000070 0.0000036 0.0000251 0.000040 0.000039 2005 4 20 53480 -0.053902 0.274269 -0.5861711 0.0011300 -0.000020 -0.000133 0.000073 0.000070 0.0000062 0.0000251 0.000041 0.000039 2005 4 21 53481 -0.054955 0.276505 -0.5873938 0.0013195 -0.000060 -0.000184 0.000073 0.000070 0.0000103 0.0000250 0.000041 0.000039 2005 4 22 53482 -0.055780 0.278697 -0.5887502 0.0014054 -0.000050 -0.000206 0.000073 0.000070 0.0000058 0.0000250 0.000041 0.000038 2005 4 23 53483 -0.056842 0.280981 -0.5902131 0.0014608 -0.000037 -0.000195 0.000073 0.000070 0.0000081 0.0000250 0.000041 0.000038 2005 4 24 53484 -0.057740 0.283414 -0.5916380 0.0013863 -0.000030 -0.000176 0.000073 0.000070 0.0000115 0.0000249 0.000041 0.000038 2005 4 25 53485 -0.058455 0.285283 -0.5929500 0.0012391 -0.000022 -0.000157 0.000073 0.000070 0.0000093 0.0000249 0.000041 0.000037 2005 4 26 53486 -0.058853 0.286977 -0.5940547 0.0009786 -0.000015 -0.000138 0.000073 0.000070 0.0000049 0.0000248 0.000041 0.000037 2005 4 27 53487 -0.058925 0.288600 -0.5948810 0.0007023 0.000026 -0.000115 0.000073 0.000070 0.0000039 0.0000247 0.000041 0.000037 2005 4 28 53488 -0.058530 0.290459 -0.5954902 0.0005079 0.000076 -0.000091 0.000073 0.000070 0.0000037 0.0000247 0.000041 0.000037 2005 4 29 53489 -0.057862 0.292511 -0.5959643 0.0004273 0.000075 -0.000225 0.000073 0.000070 0.0000051 0.0000246 0.000041 0.000037 2005 4 30 53490 -0.057221 0.294834 -0.5964629 0.0005409 0.000057 -0.000257 0.000073 0.000070 0.0000054 0.0000245 0.000041 0.000037 2005 5 1 53491 -0.057254 0.297695 -0.5971120 0.0007441 0.000039 -0.000232 0.000073 0.000070 0.0000051 0.0000244 0.000041 0.000037 2005 5 2 53492 -0.057805 0.300205 -0.5979888 0.0009824 0.000022 -0.000207 0.000073 0.000069 0.0000048 0.0000243 0.000041 0.000037 2005 5 3 53493 -0.059093 0.302228 -0.5991110 0.0012273 0.000004 -0.000181 0.000073 0.000069 0.0000046 0.0000242 0.000041 0.000038 2005 5 4 53494 -0.060038 0.304033 -0.6004588 0.0013689 -0.000015 -0.000179 0.000073 0.000069 0.0000065 0.0000241 0.000041 0.000038 2005 5 5 53495 -0.060689 0.306079 -0.6018874 0.0013778 -0.000034 -0.000182 0.000073 0.000069 0.0000082 0.0000240 0.000041 0.000038 2005 5 6 53496 -0.060953 0.307889 -0.6032003 0.0013012 -0.000054 -0.000186 0.000073 0.000069 0.0000074 0.0000240 0.000041 0.000039 2005 5 7 53497 -0.060752 0.309854 -0.6044358 0.0011448 -0.000003 -0.000132 0.000073 0.000069 0.0000062 0.0000239 0.000041 0.000039 2005 5 8 53498 -0.060650 0.311576 -0.6054720 0.0009257 0.000073 -0.000057 0.000073 0.000069 0.0000049 0.0000238 0.000041 0.000039 2005 5 9 53499 -0.060664 0.313176 -0.6062543 0.0006776 0.000149 0.000017 0.000073 0.000069 0.0000036 0.0000237 0.000041 0.000039 2005 5 10 53500 -0.060890 0.314778 -0.6068018 0.0004406 0.000226 0.000092 0.000073 0.000069 0.0000024 0.0000236 0.000041 0.000040 2005 5 11 53501 -0.061311 0.316227 -0.6071676 0.0003014 0.000105 0.000072 0.000073 0.000069 0.0000024 0.0000235 0.000041 0.000040 2005 5 12 53502 -0.062046 0.317580 -0.6074300 0.0002436 0.000041 -0.000003 0.000073 0.000069 0.0000028 0.0000234 0.000041 0.000040 2005 5 13 53503 -0.063076 0.318990 -0.6076706 0.0002664 0.000060 -0.000102 0.000073 0.000069 0.0000032 0.0000233 0.000041 0.000039 2005 5 14 53504 -0.064651 0.320368 -0.6079566 0.0003010 0.000045 -0.000123 0.000073 0.000069 0.0000044 0.0000232 0.000041 0.000039 2005 5 15 53505 -0.065824 0.321742 -0.6083497 0.0004402 0.000019 -0.000121 0.000073 0.000069 0.0000058 0.0000232 0.000041 0.000039 2005 5 16 53506 -0.066858 0.323630 -0.6088892 0.0006195 -0.000007 -0.000119 0.000073 0.000069 0.0000072 0.0000231 0.000040 0.000039 2005 5 17 53507 -0.067540 0.325137 -0.6095879 0.0008126 -0.000032 -0.000116 0.000073 0.000069 0.0000087 0.0000230 0.000040 0.000039 2005 5 18 53508 -0.068356 0.326519 -0.6104296 0.0009345 -0.000118 -0.000159 0.000073 0.000069 0.0000064 0.0000229 0.000040 0.000039 2005 5 19 53509 -0.069203 0.327814 -0.6113802 0.0009994 -0.000220 -0.000214 0.000073 0.000069 0.0000031 0.0000229 0.000040 0.000039 2005 5 20 53510 -0.070080 0.329285 -0.6123914 0.0010091 -0.000078 -0.000198 0.000073 0.000069 0.0000044 0.0000228 0.000040 0.000039 2005 5 21 53511 -0.070718 0.330669 -0.6133859 0.0009524 -0.000033 -0.000162 0.000073 0.000069 0.0000092 0.0000228 0.000041 0.000039 2005 5 22 53512 -0.071004 0.332304 -0.6142648 0.0007775 -0.000055 -0.000126 0.000073 0.000068 0.0000114 0.0000227 0.000041 0.000039 2005 5 23 53513 -0.071264 0.334019 -0.6148623 0.0004992 -0.000076 -0.000091 0.000073 0.000068 0.0000087 0.0000227 0.000041 0.000039 2005 5 24 53514 -0.071523 0.335628 -0.6151401 0.0001196 -0.000097 -0.000055 0.000073 0.000068 0.0000044 0.0000226 0.000041 0.000040 2005 5 25 53515 -0.071503 0.337307 -0.6150878 -0.0001619 -0.000079 -0.000106 0.000073 0.000068 0.0000132 0.0000225 0.000041 0.000040 2005 5 26 53516 -0.070566 0.339295 -0.6148446 -0.0002991 -0.000050 -0.000179 0.000073 0.000068 0.0000254 0.0000224 0.000042 0.000041 2005 5 27 53517 -0.068994 0.341578 -0.6145669 -0.0002357 0.000095 -0.000258 0.000073 0.000068 0.0000099 0.0000224 0.000042 0.000041 2005 5 28 53518 -0.068091 0.343799 -0.6144457 -0.0000088 0.000154 -0.000229 0.000073 0.000068 0.0000087 0.0000223 0.000042 0.000041 2005 5 29 53519 -0.067173 0.345850 -0.6145570 0.0001911 0.000167 -0.000160 0.000073 0.000068 0.0000160 0.0000223 0.000042 0.000042 2005 5 30 53520 -0.066060 0.348075 -0.6149058 0.0004278 0.000179 -0.000092 0.000073 0.000068 0.0000148 0.0000223 0.000042 0.000042 2005 5 31 53521 -0.064580 0.349825 -0.6154541 0.0006553 0.000059 -0.000134 0.000073 0.000068 0.0000092 0.0000222 0.000042 0.000042 2005 6 1 53522 -0.062981 0.351208 -0.6161108 0.0007082 -0.000095 -0.000203 0.000073 0.000068 0.0000036 0.0000222 0.000042 0.000042 2005 6 2 53523 -0.061597 0.352644 -0.6167936 0.0006386 -0.000119 -0.000157 0.000073 0.000068 0.0000148 0.0000221 0.000042 0.000042 2005 6 3 53524 -0.060465 0.354482 -0.6173541 0.0004516 -0.000113 -0.000086 0.000073 0.000068 0.0000103 0.0000221 0.000041 0.000042 2005 6 4 53525 -0.059952 0.356571 -0.6176999 0.0001846 -0.000144 -0.000052 0.000073 0.000068 0.0000089 0.0000221 0.000041 0.000042 2005 6 5 53526 -0.059565 0.358292 -0.6178264 -0.0000419 -0.000176 -0.000017 0.000073 0.000068 0.0000158 0.0000221 0.000041 0.000042 2005 6 6 53527 -0.059169 0.359842 -0.6176839 -0.0002269 -0.000207 0.000017 0.000073 0.000068 0.0000133 0.0000220 0.000041 0.000042 2005 6 7 53528 -0.058680 0.361184 -0.6173190 -0.0004023 -0.000238 0.000052 0.000073 0.000068 0.0000055 0.0000220 0.000041 0.000042 2005 6 8 53529 -0.058212 0.362408 -0.6168465 -0.0005426 0.000116 -0.000004 0.000073 0.000068 0.0000111 0.0000220 0.000041 0.000042 2005 6 9 53530 -0.057737 0.363335 -0.6163144 -0.0005674 0.000158 -0.000082 0.000073 0.000069 0.0000162 0.0000220 0.000041 0.000042 2005 6 10 53531 -0.056626 0.364789 -0.6157584 -0.0004721 0.000079 -0.000158 0.000073 0.000069 0.0000064 0.0000220 0.000041 0.000042 2005 6 11 53532 -0.055500 0.366956 -0.6153777 -0.0003571 0.000048 -0.000155 0.000073 0.000069 0.0000099 0.0000220 0.000041 0.000042 2005 6 12 53533 -0.054406 0.369002 -0.6151080 -0.0002279 0.000035 -0.000123 0.000073 0.000069 0.0000099 0.0000220 0.000041 0.000042 2005 6 13 53534 -0.053288 0.371124 -0.6149363 -0.0000952 0.000022 -0.000090 0.000073 0.000069 0.0000078 0.0000220 0.000041 0.000042 2005 6 14 53535 -0.052473 0.373297 -0.6149162 0.0000550 0.000009 -0.000057 0.000073 0.000069 0.0000067 0.0000220 0.000041 0.000042 2005 6 15 53536 -0.052058 0.375047 -0.6150831 0.0002182 -0.000115 -0.000135 0.000073 0.000069 0.0000137 0.0000220 0.000040 0.000042 2005 6 16 53537 -0.051462 0.376436 -0.6153655 0.0003566 -0.000267 -0.000241 0.000073 0.000069 0.0000228 0.0000220 0.000040 0.000042 2005 6 17 53538 -0.050556 0.377946 -0.6157642 0.0004065 -0.000069 -0.000078 0.000073 0.000069 0.0000107 0.0000220 0.000040 0.000042 2005 6 18 53539 -0.049577 0.379490 -0.6161342 0.0002905 0.000012 -0.000004 0.000074 0.000069 0.0000086 0.0000221 0.000040 0.000042 2005 6 19 53540 -0.048309 0.381131 -0.6163182 0.0000754 0.000007 0.000005 0.000074 0.000069 0.0000100 0.0000221 0.000039 0.000041 2005 6 20 53541 -0.047165 0.382897 -0.6162522 -0.0001921 0.000003 0.000013 0.000074 0.000069 0.0000076 0.0000221 0.000039 0.000041 2005 6 21 53542 -0.046270 0.384352 -0.6159476 -0.0003812 -0.000001 0.000022 0.000074 0.000069 0.0000039 0.0000221 0.000039 0.000041 2005 6 22 53543 -0.045630 0.386008 -0.6154722 -0.0005114 -0.000006 -0.000111 0.000074 0.000069 0.0000027 0.0000221 0.000039 0.000041 2005 6 23 53544 -0.045037 0.387293 -0.6149811 -0.0004780 0.000018 -0.000129 0.000074 0.000070 0.0000035 0.0000221 0.000039 0.000041 2005 6 24 53545 -0.044546 0.388490 -0.6145922 -0.0003190 0.000050 -0.000104 0.000074 0.000070 0.0000048 0.0000222 0.000039 0.000041 2005 6 25 53546 -0.043730 0.389700 -0.6144484 -0.0000516 0.000047 -0.000075 0.000074 0.000070 0.0000083 0.0000222 0.000039 0.000041 2005 6 26 53547 -0.042909 0.390877 -0.6145775 0.0001811 0.000030 -0.000044 0.000074 0.000070 0.0000116 0.0000222 0.000039 0.000040 2005 6 27 53548 -0.041519 0.391877 -0.6148287 0.0003177 0.000013 -0.000013 0.000074 0.000070 0.0000097 0.0000222 0.000039 0.000040 2005 6 28 53549 -0.040348 0.393470 -0.6151323 0.0003249 -0.000004 0.000018 0.000075 0.000070 0.0000054 0.0000222 0.000039 0.000040 2005 6 29 53550 -0.039823 0.394835 -0.6154240 0.0002161 0.000023 -0.000005 0.000075 0.000070 0.0000045 0.0000223 0.000039 0.000040 2005 6 30 53551 -0.039926 0.396196 -0.6155578 0.0000211 -0.000045 -0.000084 0.000075 0.000070 0.0000040 0.0000223 0.000039 0.000040 2005 7 1 53552 -0.040014 0.397026 -0.6154491 -0.0002208 0.000057 -0.000001 0.000075 0.000070 0.0000079 0.0000223 0.000040 0.000041 2005 7 2 53553 -0.039359 0.398048 -0.6151436 -0.0004688 0.000128 0.000145 0.000075 0.000070 0.0000170 0.0000224 0.000040 0.000041 2005 7 3 53554 -0.038570 0.399016 -0.6144742 -0.0008044 0.000161 0.000294 0.000075 0.000070 0.0000121 0.0000224 0.000040 0.000042 2005 7 4 53555 -0.037499 0.399884 -0.6135687 -0.0010173 0.000193 0.000442 0.000075 0.000070 0.0000067 0.0000224 0.000041 0.000042 2005 7 5 53556 -0.036248 0.401306 -0.6125449 -0.0010809 0.000222 0.000564 0.000075 0.000070 0.0000048 0.0000224 0.000041 0.000043 2005 7 6 53557 -0.034491 0.402817 -0.6114665 -0.0010236 0.000121 0.000040 0.000075 0.000070 0.0000030 0.0000225 0.000041 0.000043 2005 7 7 53558 -0.032757 0.404719 -0.6104822 -0.0009176 0.000155 -0.000045 0.000075 0.000070 0.0000034 0.0000225 0.000041 0.000043 2005 7 8 53559 -0.031285 0.406440 -0.6096197 -0.0008152 0.000224 -0.000016 0.000075 0.000070 0.0000045 0.0000225 0.000041 0.000043 2005 7 9 53560 -0.029857 0.407605 -0.6088890 -0.0006645 0.000250 0.000141 0.000075 0.000070 0.0000451 0.0000226 0.000042 0.000043 2005 7 10 53561 -0.028574 0.408188 -0.6083579 -0.0004473 0.000324 0.000164 0.000075 0.000070 0.0000265 0.0000226 0.000042 0.000043 2005 7 11 53562 -0.027621 0.408829 -0.6080214 -0.0002651 0.000285 0.000057 0.000075 0.000070 0.0000064 0.0000226 0.000042 0.000043 2005 7 12 53563 -0.026801 0.409478 -0.6078418 -0.0001024 0.000167 -0.000077 0.000075 0.000070 0.0000032 0.0000226 0.000042 0.000043 2005 7 13 53564 -0.025789 0.410250 -0.6077717 -0.0000208 0.000154 -0.000149 0.000075 0.000070 0.0000021 0.0000226 0.000042 0.000043 2005 7 14 53565 -0.024414 0.411322 -0.6077651 -0.0000372 0.000068 0.000006 0.000075 0.000070 0.0000124 0.0000226 0.000042 0.000043 2005 7 15 53566 -0.023040 0.412663 -0.6076704 -0.0001390 0.000009 0.000030 0.000074 0.000069 0.0000075 0.0000227 0.000042 0.000043 2005 7 16 53567 -0.021696 0.413799 -0.6075173 -0.0002784 -0.000029 -0.000033 0.000074 0.000069 0.0000127 0.0000227 0.000042 0.000042 2005 7 17 53568 -0.020396 0.414513 -0.6071437 -0.0004931 -0.000066 -0.000106 0.000074 0.000069 0.0000131 0.0000227 0.000042 0.000042 2005 7 18 53569 -0.019737 0.414987 -0.6065135 -0.0006660 -0.000056 -0.000125 0.000074 0.000069 0.0000089 0.0000227 0.000042 0.000042 2005 7 19 53570 -0.019256 0.415366 -0.6056964 -0.0007895 0.000030 -0.000057 0.000074 0.000069 0.0000051 0.0000227 0.000042 0.000042 2005 7 20 53571 -0.018480 0.415361 -0.6048016 -0.0008374 0.000065 -0.000032 0.000074 0.000069 0.0000175 0.0000227 0.000042 0.000042 2005 7 21 53572 -0.016930 0.415615 -0.6039853 -0.0007532 0.000087 -0.000019 0.000074 0.000069 0.0000342 0.0000227 0.000042 0.000042 2005 7 22 53573 -0.015374 0.416373 -0.6033941 -0.0004557 0.000108 -0.000005 0.000074 0.000069 0.0000160 0.0000227 0.000042 0.000042 2005 7 23 53574 -0.013977 0.417168 -0.6031520 -0.0000718 0.000093 -0.000009 0.000074 0.000069 0.0000108 0.0000226 0.000042 0.000042 2005 7 24 53575 -0.013020 0.418017 -0.6032693 0.0002632 0.000068 -0.000016 0.000074 0.000069 0.0000175 0.0000226 0.000042 0.000042 2005 7 25 53576 -0.012104 0.418798 -0.6036511 0.0004740 0.000043 -0.000024 0.000074 0.000069 0.0000141 0.0000225 0.000042 0.000042 2005 7 26 53577 -0.011322 0.419359 -0.6041329 0.0004959 0.000018 -0.000031 0.000074 0.000069 0.0000066 0.0000225 0.000043 0.000042 2005 7 27 53578 -0.010366 0.419731 -0.6045917 0.0003788 0.000018 -0.000017 0.000074 0.000069 0.0000151 0.0000224 0.000043 0.000042 2005 7 28 53579 -0.009375 0.420185 -0.6048678 0.0001259 0.000024 0.000002 0.000074 0.000069 0.0000226 0.0000224 0.000043 0.000042 2005 7 29 53580 -0.008253 0.420296 -0.6048561 -0.0001051 0.000030 0.000021 0.000074 0.000069 0.0000107 0.0000223 0.000043 0.000042 2005 7 30 53581 -0.006462 0.420530 -0.6046316 -0.0003225 0.000035 0.000031 0.000074 0.000069 0.0000105 0.0000223 0.000043 0.000042 2005 7 31 53582 -0.004537 0.420904 -0.6042166 -0.0005444 0.000040 0.000038 0.000074 0.000069 0.0000147 0.0000222 0.000043 0.000042 2005 8 1 53583 -0.002929 0.421375 -0.6036516 -0.0006065 0.000046 0.000044 0.000074 0.000069 0.0000131 0.0000222 0.000043 0.000042 2005 8 2 53584 -0.001338 0.421622 -0.6030170 -0.0006600 0.000051 0.000051 0.000074 0.000069 0.0000086 0.0000222 0.000044 0.000042 2005 8 3 53585 0.000694 0.421768 -0.6023820 -0.0006424 0.000126 0.000057 0.000074 0.000069 0.0000090 0.0000222 0.000044 0.000042 2005 8 4 53586 0.003011 0.422026 -0.6018023 -0.0005663 0.000219 0.000062 0.000074 0.000069 0.0000095 0.0000222 0.000044 0.000042 2005 8 5 53587 0.004800 0.422441 -0.6012612 -0.0004061 0.000311 0.000068 0.000074 0.000069 0.0000057 0.0000223 0.000044 0.000042 2005 8 6 53588 0.006544 0.422636 -0.6009648 -0.0002054 0.000308 0.000050 0.000074 0.000069 0.0000137 0.0000223 0.000044 0.000042 2005 8 7 53589 0.008573 0.423082 -0.6009220 0.0000505 0.000269 0.000024 0.000074 0.000069 0.0000159 0.0000223 0.000044 0.000042 2005 8 8 53590 0.010946 0.423504 -0.6010898 0.0002502 0.000231 -0.000002 0.000074 0.000069 0.0000121 0.0000223 0.000044 0.000041 2005 8 9 53591 0.013764 0.424276 -0.6013970 0.0003941 0.000192 -0.000029 0.000074 0.000069 0.0000080 0.0000223 0.000044 0.000041 2005 8 10 53592 0.016230 0.425379 -0.6018204 0.0004120 0.000124 -0.000100 0.000074 0.000069 0.0000145 0.0000223 0.000044 0.000042 2005 8 11 53593 0.018376 0.426514 -0.6022463 0.0003694 0.000047 -0.000183 0.000074 0.000069 0.0000238 0.0000223 0.000044 0.000042 2005 8 12 53594 0.020019 0.427269 -0.6025464 0.0002215 0.000119 -0.000008 0.000074 0.000069 0.0000115 0.0000223 0.000044 0.000042 2005 8 13 53595 0.021639 0.427910 -0.6026901 -0.0000028 0.000154 0.000021 0.000074 0.000069 0.0000139 0.0000224 0.000044 0.000042 2005 8 14 53596 0.022758 0.428534 -0.6026157 -0.0002392 0.000158 -0.000036 0.000074 0.000069 0.0000159 0.0000224 0.000043 0.000041 2005 8 15 53597 0.023812 0.429087 -0.6022774 -0.0003822 0.000162 -0.000092 0.000074 0.000069 0.0000116 0.0000224 0.000043 0.000041 2005 8 16 53598 0.024877 0.429425 -0.6017794 -0.0004151 0.000166 -0.000148 0.000074 0.000069 0.0000060 0.0000224 0.000043 0.000041 2005 8 17 53599 0.026007 0.429544 -0.6013014 -0.0003898 0.000138 -0.000093 0.000074 0.000070 0.0000039 0.0000224 0.000042 0.000040 2005 8 18 53600 0.027081 0.429451 -0.6009741 -0.0002448 0.000102 -0.000010 0.000074 0.000070 0.0000026 0.0000224 0.000042 0.000040 2005 8 19 53601 0.028430 0.429160 -0.6008939 0.0000436 0.000220 0.000007 0.000074 0.000070 0.0000032 0.0000225 0.000042 0.000040 2005 8 20 53602 0.029796 0.429060 -0.6011440 0.0003923 0.000258 -0.000027 0.000074 0.000070 0.0000133 0.0000225 0.000042 0.000040 2005 8 21 53603 0.031345 0.429129 -0.6017337 0.0006691 0.000248 -0.000072 0.000074 0.000070 0.0000177 0.0000225 0.000042 0.000040 2005 8 22 53604 0.032706 0.429095 -0.6024441 0.0007120 0.000237 -0.000116 0.000074 0.000070 0.0000133 0.0000225 0.000042 0.000040 2005 8 23 53605 0.034148 0.428791 -0.6030809 0.0005520 0.000227 -0.000160 0.000075 0.000070 0.0000067 0.0000225 0.000043 0.000040 2005 8 24 53606 0.035549 0.428723 -0.6035210 0.0002915 0.000151 -0.000089 0.000075 0.000070 0.0000050 0.0000225 0.000043 0.000040 2005 8 25 53607 0.036960 0.428483 -0.6036598 0.0000248 0.000059 0.000013 0.000075 0.000070 0.0000045 0.0000224 0.000042 0.000039 2005 8 26 53608 0.038277 0.428039 -0.6035195 -0.0002686 0.000157 0.000012 0.000075 0.000070 0.0000056 0.0000224 0.000042 0.000039 2005 8 27 53609 0.039386 0.427112 -0.6030743 -0.0005567 0.000213 0.000017 0.000075 0.000070 0.0000152 0.0000223 0.000043 0.000039 2005 8 28 53610 0.040639 0.426126 -0.6024138 -0.0007723 0.000230 0.000037 0.000075 0.000071 0.0000186 0.0000223 0.000042 0.000039 2005 8 29 53611 0.041447 0.425696 -0.6015598 -0.0009067 0.000246 0.000056 0.000075 0.000071 0.0000132 0.0000222 0.000042 0.000039 2005 8 30 53612 0.041811 0.425347 -0.6006465 -0.0008825 0.000263 0.000076 0.000075 0.000071 0.0000057 0.0000221 0.000042 0.000039 2005 8 31 53613 0.041836 0.425046 -0.5998146 -0.0007719 0.000241 0.000064 0.000076 0.000071 0.0000042 0.0000220 0.000042 0.000039 2005 9 1 53614 0.042046 0.425199 -0.5991338 -0.0005850 0.000208 0.000044 0.000076 0.000071 0.0000044 0.0000219 0.000042 0.000038 2005 9 2 53615 0.042041 0.425656 -0.5986573 -0.0003038 0.000175 0.000024 0.000076 0.000071 0.0000046 0.0000218 0.000042 0.000038 2005 9 3 53616 0.042235 0.425484 -0.5985407 -0.0000072 0.000176 -0.000123 0.000076 0.000071 0.0000102 0.0000217 0.000042 0.000038 2005 9 4 53617 0.042705 0.424872 -0.5986402 0.0001999 0.000188 -0.000318 0.000076 0.000071 0.0000143 0.0000215 0.000042 0.000038 2005 9 5 53618 0.043537 0.424220 -0.5988852 0.0003185 0.000200 -0.000512 0.000076 0.000071 0.0000133 0.0000214 0.000042 0.000038 2005 9 6 53619 0.044700 0.423687 -0.5992519 0.0004168 0.000212 -0.000705 0.000076 0.000072 0.0000106 0.0000213 0.000042 0.000037 2005 9 7 53620 0.045908 0.423286 -0.5996709 0.0004427 0.000146 -0.000241 0.000076 0.000072 0.0000079 0.0000211 0.000041 0.000037 2005 9 8 53621 0.047270 0.422901 -0.6001203 0.0004215 0.000157 -0.000031 0.000077 0.000072 0.0000467 0.0000210 0.000041 0.000036 2005 9 9 53622 0.048524 0.422938 -0.6005023 0.0003205 0.000134 -0.000116 0.000077 0.000072 0.0000191 0.0000208 0.000040 0.000035 2005 9 10 53623 0.049421 0.423132 -0.6007498 0.0001180 0.000144 -0.000138 0.000077 0.000072 0.0000095 0.0000207 0.000040 0.000034 2005 9 11 53624 0.050113 0.423359 -0.6007792 -0.0000944 0.000173 -0.000109 0.000077 0.000073 0.0000097 0.0000205 0.000039 0.000033 2005 9 12 53625 0.050544 0.423267 -0.6006106 -0.0002054 0.000202 -0.000081 0.000078 0.000073 0.0000062 0.0000203 0.000038 0.000033 2005 9 13 53626 0.050356 0.422597 -0.6004053 -0.0001125 0.000230 -0.000052 0.000078 0.000073 0.0000023 0.0000201 0.000038 0.000032 2005 9 14 53627 0.050072 0.421552 -0.6003749 0.0001092 0.000226 -0.000040 0.000078 0.000073 0.0000015 0.0000198 0.000037 0.000031 2005 9 15 53628 0.050050 0.421136 -0.6005910 0.0003515 0.000157 -0.000054 0.000079 0.000073 0.0000016 0.0000196 0.000037 0.000031 2005 9 16 53629 0.050860 0.421270 -0.6011440 0.0007367 0.000106 -0.000054 0.000079 0.000074 0.0000027 0.0000193 0.000036 0.000030 2005 9 17 53630 0.051911 0.421566 -0.6020731 0.0010793 0.000112 -0.000039 0.000079 0.000074 0.0000018 0.0000191 0.000036 0.000030 2005 9 18 53631 0.052559 0.421923 -0.6032781 0.0012492 0.000123 -0.000022 0.000079 0.000074 0.0000014 0.0000188 0.000036 0.000029 2005 9 19 53632 0.052662 0.421889 -0.6045744 0.0012868 0.000142 0.000000 0.000079 0.000074 0.0000012 0.0000185 0.000036 0.000029 2005 9 20 53633 0.052629 0.421132 -0.6057827 0.0011063 0.000160 0.000006 0.000079 0.000074 0.0000013 0.0000182 0.000035 0.000029 2005 9 21 53634 0.052959 0.420274 -0.6067481 0.0008256 0.000175 -0.000016 0.000079 0.000074 0.0000014 0.0000179 0.000035 0.000029 2005 9 22 53635 0.053582 0.419465 -0.6073933 0.0004907 0.000197 -0.000023 0.000079 0.000074 0.0000020 0.0000176 0.000036 0.000030 2005 9 23 53636 0.054345 0.418919 -0.6077232 0.0002046 0.000232 -0.000004 0.000079 0.000074 0.0000016 0.0000173 0.000036 0.000030 2005 9 24 53637 0.055297 0.418340 -0.6077795 -0.0000330 0.000250 0.000003 0.000079 0.000073 0.0000014 0.0000170 0.000036 0.000030 2005 9 25 53638 0.056156 0.417750 -0.6076531 -0.0001631 0.000236 -0.000016 0.000079 0.000073 0.0000026 0.0000167 0.000036 0.000030 2005 9 26 53639 0.056672 0.417350 -0.6074671 -0.0001665 0.000198 -0.000067 0.000079 0.000073 0.0000019 0.0000164 0.000036 0.000030 2005 9 27 53640 0.057072 0.417042 -0.6073129 -0.0001244 0.000184 -0.000004 0.000078 0.000073 0.0000014 0.0000161 0.000037 0.000031 2005 9 28 53641 0.057880 0.416795 -0.6072422 -0.0000149 0.000175 0.000014 0.000078 0.000073 0.0000021 0.0000157 0.000037 0.000031 2005 9 29 53642 0.058647 0.416994 -0.6073179 0.0001927 0.000167 0.000013 0.000078 0.000072 0.0000031 0.0000154 0.000038 0.000032 2005 9 30 53643 0.058901 0.417334 -0.6075987 0.0003790 0.000290 0.000017 0.000078 0.000072 0.0000040 0.0000151 0.000038 0.000032 2005 10 1 53644 0.058710 0.417293 -0.6080823 0.0005557 0.000319 -0.000001 0.000077 0.000072 0.0000040 0.0000148 0.000038 0.000033 2005 10 2 53645 0.058606 0.417034 -0.6087226 0.0007231 0.000298 -0.000028 0.000077 0.000071 0.0000037 0.0000146 0.000039 0.000034 2005 10 3 53646 0.058807 0.416479 -0.6094595 0.0007685 0.000276 -0.000055 0.000077 0.000071 0.0000033 0.0000143 0.000039 0.000034 2005 10 4 53647 0.059762 0.415758 -0.6102184 0.0007098 0.000255 -0.000082 0.000077 0.000071 0.0000030 0.0000141 0.000040 0.000035 2005 10 5 53648 0.060843 0.415382 -0.6108656 0.0005486 0.000278 -0.000064 0.000076 0.000071 0.0000119 0.0000139 0.000040 0.000036 2005 10 6 53649 0.062178 0.415336 -0.6113624 0.0004180 0.000313 -0.000036 0.000076 0.000071 0.0000233 0.0000137 0.000041 0.000037 2005 10 7 53650 0.063372 0.415724 -0.6117077 0.0002916 0.000324 0.000010 0.000076 0.000071 0.0000132 0.0000135 0.000041 0.000037 2005 10 8 53651 0.064005 0.415809 -0.6119570 0.0001303 0.000301 0.000018 0.000076 0.000071 0.0000079 0.0000133 0.000041 0.000038 2005 10 9 53652 0.064473 0.415260 -0.6120590 0.0000250 0.000268 0.000009 0.000076 0.000070 0.0000090 0.0000131 0.000042 0.000038 2005 10 10 53653 0.065121 0.414455 -0.6120388 0.0000178 0.000234 0.000001 0.000076 0.000070 0.0000104 0.0000129 0.000042 0.000039 2005 10 11 53654 0.065218 0.413733 -0.6120525 0.0000765 0.000201 -0.000008 0.000076 0.000070 0.0000116 0.0000127 0.000042 0.000039 2005 10 12 53655 0.065316 0.412876 -0.6122360 0.0002750 0.000320 0.000021 0.000076 0.000070 0.0000177 0.0000126 0.000042 0.000039 2005 10 13 53656 0.065694 0.412325 -0.6126797 0.0005617 0.000359 0.000085 0.000076 0.000070 0.0000206 0.0000124 0.000042 0.000039 2005 10 14 53657 0.066281 0.411202 -0.6133688 0.0008949 0.000363 0.000157 0.000075 0.000070 0.0000068 0.0000123 0.000042 0.000039 2005 10 15 53658 0.066920 0.409955 -0.6144111 0.0011235 0.000315 0.000205 0.000075 0.000070 0.0000054 0.0000121 0.000043 0.000040 2005 10 16 53659 0.067905 0.408713 -0.6155846 0.0011797 0.000248 0.000244 0.000075 0.000070 0.0000066 0.0000120 0.000043 0.000040 2005 10 17 53660 0.069335 0.408135 -0.6167406 0.0011066 0.000181 0.000283 0.000075 0.000070 0.0000054 0.0000119 0.000043 0.000040 2005 10 18 53661 0.070442 0.408044 -0.6177524 0.0009423 0.000114 0.000322 0.000075 0.000070 0.0000034 0.0000118 0.000043 0.000041 2005 10 19 53662 0.071007 0.407784 -0.6185773 0.0007065 0.000088 0.000065 0.000075 0.000070 0.0000059 0.0000117 0.000043 0.000041 2005 10 20 53663 0.070985 0.407422 -0.6191592 0.0004761 0.000171 -0.000084 0.000075 0.000070 0.0000069 0.0000116 0.000043 0.000041 2005 10 21 53664 0.071067 0.407041 -0.6195088 0.0002746 0.000284 -0.000180 0.000075 0.000070 0.0000072 0.0000115 0.000043 0.000041 2005 10 22 53665 0.071048 0.406475 -0.6197635 0.0001475 0.000328 -0.000190 0.000075 0.000070 0.0000090 0.0000114 0.000043 0.000041 2005 10 23 53666 0.070939 0.405762 -0.6199078 0.0001513 0.000347 -0.000169 0.000075 0.000070 0.0000094 0.0000113 0.000043 0.000041 2005 10 24 53667 0.070914 0.405130 -0.6200293 0.0002255 0.000367 -0.000148 0.000075 0.000070 0.0000065 0.0000112 0.000043 0.000041 2005 10 25 53668 0.070905 0.404581 -0.6202415 0.0002490 0.000386 -0.000128 0.000075 0.000070 0.0000026 0.0000112 0.000043 0.000041 2005 10 26 53669 0.070625 0.403880 -0.6205422 0.0003773 0.000369 -0.000117 0.000075 0.000071 0.0000076 0.0000111 0.000043 0.000041 2005 10 27 53670 0.070077 0.402992 -0.6210045 0.0005369 0.000344 -0.000109 0.000075 0.000071 0.0000118 0.0000110 0.000043 0.000041 2005 10 28 53671 0.069790 0.402222 -0.6216458 0.0007184 0.000318 -0.000101 0.000075 0.000071 0.0000043 0.0000110 0.000043 0.000041 2005 10 29 53672 0.069463 0.401721 -0.6225241 0.0009176 0.000301 -0.000082 0.000075 0.000071 0.0000024 0.0000109 0.000043 0.000042 2005 10 30 53673 0.069291 0.400616 -0.6235455 0.0010653 0.000287 -0.000058 0.000075 0.000071 0.0000026 0.0000109 0.000043 0.000042 2005 10 31 53674 0.070060 0.399731 -0.6246144 0.0011071 0.000273 -0.000035 0.000075 0.000071 0.0000027 0.0000108 0.000044 0.000043 2005 11 1 53675 0.071301 0.399028 -0.6256474 0.0009909 0.000259 -0.000012 0.000075 0.000071 0.0000029 0.0000108 0.000044 0.000043 2005 11 2 53676 0.072343 0.398472 -0.6265668 0.0008366 0.000233 -0.000055 0.000075 0.000071 0.0000070 0.0000107 0.000044 0.000044 2005 11 3 53677 0.073016 0.397779 -0.6273004 0.0006015 0.000204 -0.000115 0.000075 0.000071 0.0000122 0.0000107 0.000044 0.000045 2005 11 4 53678 0.073140 0.397176 -0.6277907 0.0003798 0.000300 -0.000172 0.000075 0.000071 0.0000084 0.0000106 0.000044 0.000045 2005 11 5 53679 0.073093 0.396626 -0.6281206 0.0001947 0.000327 -0.000163 0.000075 0.000071 0.0000079 0.0000106 0.000044 0.000045 2005 11 6 53680 0.072891 0.396182 -0.6282824 0.0001391 0.000313 -0.000131 0.000075 0.000071 0.0000073 0.0000106 0.000044 0.000046 2005 11 7 53681 0.072674 0.395574 -0.6284300 0.0002334 0.000299 -0.000098 0.000075 0.000071 0.0000056 0.0000105 0.000044 0.000046 2005 11 8 53682 0.072466 0.395181 -0.6287332 0.0004176 0.000284 -0.000065 0.000075 0.000071 0.0000040 0.0000105 0.000044 0.000046 2005 11 9 53683 0.072511 0.395025 -0.6293340 0.0007865 0.000277 -0.000165 0.000075 0.000071 0.0000140 0.0000104 0.000044 0.000046 2005 11 10 53684 0.072206 0.394762 -0.6302842 0.0011410 0.000287 -0.000213 0.000075 0.000071 0.0000137 0.0000104 0.000044 0.000046 2005 11 11 53685 0.071543 0.394052 -0.6315474 0.0013727 0.000409 -0.000138 0.000075 0.000070 0.0000055 0.0000104 0.000044 0.000046 2005 11 12 53686 0.070805 0.393432 -0.6330083 0.0014895 0.000408 -0.000080 0.000075 0.000070 0.0000082 0.0000104 0.000043 0.000045 2005 11 13 53687 0.070023 0.393210 -0.6344893 0.0014209 0.000348 -0.000040 0.000075 0.000070 0.0000073 0.0000103 0.000043 0.000045 2005 11 14 53688 0.069153 0.392808 -0.6358172 0.0012597 0.000287 0.000000 0.000075 0.000070 0.0000043 0.0000103 0.000042 0.000045 2005 11 15 53689 0.068925 0.392217 -0.6369084 0.0009551 0.000227 0.000039 0.000075 0.000070 0.0000023 0.0000103 0.000042 0.000044 2005 11 16 53690 0.069534 0.392074 -0.6377069 0.0006775 0.000244 -0.000159 0.000075 0.000070 0.0000016 0.0000103 0.000042 0.000044 2005 11 17 53691 0.069791 0.392823 -0.6382597 0.0004646 0.000305 -0.000225 0.000075 0.000070 0.0000175 0.0000103 0.000041 0.000044 2005 11 18 53692 0.069361 0.392875 -0.6385865 0.0002413 0.000374 -0.000117 0.000074 0.000070 0.0000094 0.0000103 0.000041 0.000044 2005 11 19 53693 0.068946 0.392360 -0.6388073 0.0001901 0.000367 -0.000088 0.000074 0.000070 0.0000053 0.0000103 0.000041 0.000044 2005 11 20 53694 0.068067 0.392171 -0.6390416 0.0002979 0.000333 -0.000102 0.000074 0.000070 0.0000065 0.0000102 0.000041 0.000044 2005 11 21 53695 0.066840 0.391625 -0.6393628 0.0004178 0.000299 -0.000116 0.000075 0.000070 0.0000069 0.0000102 0.000041 0.000044 2005 11 22 53696 0.065805 0.390731 -0.6398130 0.0005500 0.000265 -0.000131 0.000075 0.000070 0.0000068 0.0000102 0.000041 0.000044 2005 11 23 53697 0.065137 0.389437 -0.6404060 0.0006830 0.000241 -0.000190 0.000075 0.000070 0.0000032 0.0000102 0.000041 0.000043 2005 11 24 53698 0.065225 0.388439 -0.6411576 0.0007837 0.000289 -0.000059 0.000075 0.000070 0.0000028 0.0000101 0.000041 0.000043 2005 11 25 53699 0.066099 0.388041 -0.6420544 0.0009337 0.000363 0.000146 0.000075 0.000070 0.0000039 0.0000101 0.000041 0.000043 2005 11 26 53700 0.067013 0.388231 -0.6430568 0.0010526 0.000272 0.000102 0.000075 0.000070 0.0000049 0.0000101 0.000041 0.000043 2005 11 27 53701 0.067647 0.388192 -0.6441214 0.0010348 0.000180 0.000057 0.000075 0.000070 0.0000064 0.0000100 0.000041 0.000042 2005 11 28 53702 0.068482 0.388090 -0.6451107 0.0009333 0.000089 0.000013 0.000075 0.000070 0.0000071 0.0000100 0.000040 0.000042 2005 11 29 53703 0.068969 0.388595 -0.6459610 0.0007630 -0.000002 -0.000031 0.000075 0.000070 0.0000074 0.0000099 0.000040 0.000041 2005 11 30 53704 0.069189 0.389122 -0.6466403 0.0005577 0.000231 -0.000136 0.000075 0.000070 0.0000063 0.0000099 0.000040 0.000041 2005 12 1 53705 0.068969 0.389511 -0.6471144 0.0003345 0.000304 -0.000197 0.000075 0.000070 0.0000050 0.0000098 0.000040 0.000040 2005 12 2 53706 0.068541 0.389811 -0.6473635 0.0001957 0.000300 -0.000240 0.000075 0.000070 0.0000038 0.0000098 0.000040 0.000040 2005 12 3 53707 0.067704 0.390302 -0.6475265 0.0001250 0.000310 -0.000239 0.000075 0.000070 0.0000056 0.0000097 0.000040 0.000040 2005 12 4 53708 0.066951 0.390632 -0.6476429 0.0001049 0.000326 -0.000222 0.000075 0.000070 0.0000070 0.0000096 0.000040 0.000039 2005 12 5 53709 0.066311 0.391001 -0.6477484 0.0001808 0.000341 -0.000204 0.000075 0.000070 0.0000056 0.0000096 0.000040 0.000039 2005 12 6 53710 0.066068 0.391121 -0.6480147 0.0003921 0.000356 -0.000186 0.000075 0.000070 0.0000032 0.0000095 0.000040 0.000039 2005 12 7 53711 0.066120 0.391137 -0.6485471 0.0006917 0.000227 -0.000146 0.000075 0.000071 0.0000023 0.0000095 0.000040 0.000039 2005 12 8 53712 0.066225 0.390998 -0.6493248 0.0008684 0.000128 -0.000097 0.000075 0.000071 0.0000017 0.0000095 0.000040 0.000039 2005 12 9 53713 0.066017 0.390612 -0.6502630 0.0009687 0.000185 -0.000154 0.000075 0.000071 0.0000022 0.0000094 0.000040 0.000039 2005 12 10 53714 0.065341 0.390018 -0.6512829 0.0009414 0.000224 -0.000170 0.000075 0.000071 0.0000040 0.0000094 0.000040 0.000039 2005 12 11 53715 0.064243 0.389226 -0.6521846 0.0008301 0.000241 -0.000157 0.000075 0.000071 0.0000056 0.0000094 0.000041 0.000040 2005 12 12 53716 0.063352 0.388358 -0.6529295 0.0006648 0.000257 -0.000145 0.000075 0.000071 0.0000064 0.0000094 0.000041 0.000040 2005 12 13 53717 0.062967 0.387947 -0.6534675 0.0004547 0.000274 -0.000133 0.000076 0.000071 0.0000068 0.0000093 0.000041 0.000040 2005 12 14 53718 0.063282 0.387655 -0.6537918 0.0002357 0.000248 -0.000162 0.000076 0.000071 0.0000063 0.0000093 0.000042 0.000041 2005 12 15 53719 0.064104 0.387828 -0.6539380 0.0000876 0.000269 -0.000218 0.000076 0.000071 0.0000054 0.0000093 0.000042 0.000041 2005 12 16 53720 0.064745 0.388291 -0.6539928 0.0000234 0.000321 -0.000130 0.000076 0.000071 0.0000050 0.0000093 0.000042 0.000041 2005 12 17 53721 0.065031 0.388954 -0.6540682 0.0000634 0.000361 -0.000139 0.000076 0.000071 0.0000065 0.0000093 0.000042 0.000041 2005 12 18 53722 0.065138 0.389434 -0.6541417 0.0001458 0.000394 -0.000202 0.000076 0.000071 0.0000060 0.0000093 0.000043 0.000042 2005 12 19 53723 0.064891 0.389490 -0.6543134 0.0002525 0.000427 -0.000264 0.000076 0.000071 0.0000066 0.0000093 0.000043 0.000042 2005 12 20 53724 0.063832 0.389456 -0.6546615 0.0004342 0.000460 -0.000327 0.000076 0.000071 0.0000082 0.0000093 0.000044 0.000043 2005 12 21 53725 0.062665 0.388684 -0.6552121 0.0006424 0.000312 -0.000250 0.000076 0.000071 0.0000052 0.0000093 0.000044 0.000043 2005 12 22 53726 0.062357 0.387917 -0.6559518 0.0008079 0.000279 -0.000229 0.000076 0.000071 0.0000038 0.0000093 0.000045 0.000043 2005 12 23 53727 0.061793 0.387713 -0.6568241 0.0008886 0.000294 -0.000234 0.000075 0.000071 0.0000032 0.0000093 0.000045 0.000043 2005 12 24 53728 0.061187 0.387352 -0.6577649 0.0009226 0.000275 -0.000246 0.000075 0.000071 0.0000034 0.0000093 0.000045 0.000043 2005 12 25 53729 0.060643 0.387312 -0.6587060 0.0008695 0.000242 -0.000261 0.000075 0.000071 0.0000040 0.0000093 0.000045 0.000043 2005 12 26 53730 0.059470 0.387433 -0.6595719 0.0008198 0.000210 -0.000276 0.000075 0.000071 0.0000045 0.0000093 0.000046 0.000043 2005 12 27 53731 0.058133 0.387329 -0.6602872 0.0006520 0.000177 -0.000291 0.000075 0.000070 0.0000051 0.0000093 0.000046 0.000043 2005 12 28 53732 0.056995 0.386722 -0.6607923 0.0003857 0.000145 -0.000305 0.000075 0.000070 0.0000056 0.0000094 0.000046 0.000043 2005 12 29 53733 0.055890 0.385904 -0.6610502 0.0001775 0.000185 -0.000301 0.000075 0.000070 0.0000239 0.0000094 0.000047 0.000043 2005 12 30 53734 0.054842 0.385063 -0.6611274 0.0000372 0.000244 -0.000292 0.000075 0.000070 0.0000108 0.0000094 0.000047 0.000043 2005 12 31 53735 0.053753 0.384213 -0.6611087 0.0000521 0.000265 -0.000281 0.000075 0.000070 0.0000039 0.0000094 0.000047 0.000043 2006 1 1 53736 0.052618 0.383669 0.3388662 0.0001553 0.000272 -0.000270 0.000064 0.000077 0.0000041 0.0000123 0.000041 0.000037 2006 1 2 53737 0.051716 0.383305 0.3386554 0.0003318 0.000280 -0.000260 0.000064 0.000077 0.0000048 0.0000123 0.000041 0.000037 2006 1 3 53738 0.050885 0.383073 0.3381739 0.0006279 0.000288 -0.000249 0.000064 0.000077 0.0000055 0.0000123 0.000041 0.000037 2006 1 4 53739 0.050084 0.382757 0.3374218 0.0007812 0.000296 -0.000238 0.000064 0.000077 0.0000062 0.0000123 0.000042 0.000037 2006 1 5 53740 0.049445 0.382383 0.3365376 0.0009411 0.000242 -0.000228 0.000064 0.000076 0.0000073 0.0000122 0.000042 0.000037 2006 1 6 53741 0.049391 0.382095 0.3355455 0.0009415 0.000219 -0.000212 0.000064 0.000076 0.0000065 0.0000122 0.000042 0.000037 2006 1 7 53742 0.049528 0.382000 0.3346200 0.0008719 0.000213 -0.000194 0.000064 0.000076 0.0000051 0.0000121 0.000042 0.000036 2006 1 8 53743 0.049467 0.381986 0.3339074 0.0005876 0.000208 -0.000176 0.000064 0.000076 0.0000054 0.0000119 0.000042 0.000036 2006 1 9 53744 0.049447 0.381664 0.3334623 0.0003162 0.000202 -0.000158 0.000065 0.000077 0.0000066 0.0000118 0.000042 0.000036 2006 1 10 53745 0.049596 0.381511 0.3332835 0.0000861 0.000197 -0.000140 0.000065 0.000077 0.0000078 0.0000117 0.000042 0.000036 2006 1 11 53746 0.049224 0.381450 0.3332870 -0.0000846 0.000181 -0.000180 0.000065 0.000077 0.0000095 0.0000116 0.000042 0.000036 2006 1 12 53747 0.048695 0.381045 0.3334524 -0.0002586 0.000162 -0.000236 0.000065 0.000077 0.0000102 0.0000116 0.000042 0.000036 2006 1 13 53748 0.048462 0.380774 0.3337641 -0.0002700 0.000143 -0.000291 0.000065 0.000077 0.0000067 0.0000116 0.000042 0.000035 2006 1 14 53749 0.048575 0.380278 0.3339728 -0.0001278 0.000125 -0.000312 0.000065 0.000077 0.0000076 0.0000116 0.000042 0.000035 2006 1 15 53750 0.049168 0.380111 0.3340550 0.0000052 0.000109 -0.000320 0.000065 0.000077 0.0000072 0.0000116 0.000042 0.000035 2006 1 16 53751 0.049997 0.379915 0.3340711 0.0000066 0.000092 -0.000327 0.000065 0.000077 0.0000058 0.0000116 0.000042 0.000035 2006 1 17 53752 0.050434 0.380288 0.3339479 0.0001341 0.000075 -0.000334 0.000065 0.000077 0.0000046 0.0000116 0.000041 0.000034 2006 1 18 53753 0.050588 0.380711 0.3336410 0.0003946 0.000167 -0.000290 0.000065 0.000077 0.0000035 0.0000115 0.000041 0.000034 2006 1 19 53754 0.050758 0.381017 0.3331396 0.0005945 0.000241 -0.000269 0.000065 0.000077 0.0000082 0.0000114 0.000041 0.000034 2006 1 20 53755 0.050438 0.381320 0.3325511 0.0006074 0.000156 -0.000197 0.000065 0.000077 0.0000056 0.0000114 0.000041 0.000034 2006 1 21 53756 0.050154 0.381472 0.3318791 0.0006511 0.000126 -0.000176 0.000065 0.000077 0.0000057 0.0000113 0.000040 0.000033 2006 1 22 53757 0.050098 0.381740 0.3311860 0.0006636 0.000134 -0.000181 0.000065 0.000077 0.0000077 0.0000112 0.000040 0.000033 2006 1 23 53758 0.050167 0.381076 0.3305411 0.0006290 0.000143 -0.000187 0.000065 0.000077 0.0000098 0.0000111 0.000040 0.000033 2006 1 24 53759 0.050305 0.380534 0.3299956 0.0005506 0.000151 -0.000192 0.000065 0.000077 0.0000118 0.0000109 0.000040 0.000033 2006 1 25 53760 0.050126 0.380623 0.3295051 0.0004214 0.000112 -0.000260 0.000066 0.000077 0.0000084 0.0000108 0.000039 0.000032 2006 1 26 53761 0.050045 0.380937 0.3291150 0.0003938 0.000042 -0.000355 0.000066 0.000078 0.0000036 0.0000108 0.000039 0.000031 2006 1 27 53762 0.050263 0.381024 0.3287296 0.0004159 0.000177 -0.000364 0.000066 0.000078 0.0000031 0.0000107 0.000038 0.000031 2006 1 28 53763 0.050658 0.381352 0.3282646 0.0005037 0.000211 -0.000357 0.000066 0.000078 0.0000056 0.0000106 0.000038 0.000031 2006 1 29 53764 0.051141 0.381729 0.3276802 0.0006850 0.000184 -0.000356 0.000066 0.000078 0.0000088 0.0000106 0.000038 0.000031 2006 1 30 53765 0.051516 0.381982 0.3268665 0.0009740 0.000156 -0.000354 0.000066 0.000078 0.0000074 0.0000105 0.000038 0.000031 2006 1 31 53766 0.051615 0.382531 0.3257254 0.0012134 0.000128 -0.000353 0.000066 0.000078 0.0000037 0.0000104 0.000037 0.000031 2006 2 1 53767 0.051335 0.383353 0.3243126 0.0014711 0.000071 -0.000278 0.000066 0.000078 0.0000098 0.0000103 0.000037 0.000031 2006 2 2 53768 0.050654 0.384059 0.3227352 0.0015801 0.000028 -0.000265 0.000066 0.000078 0.0000048 0.0000103 0.000037 0.000031 2006 2 3 53769 0.050106 0.384476 0.3211773 0.0014767 0.000052 -0.000300 0.000066 0.000078 0.0000047 0.0000102 0.000037 0.000031 2006 2 4 53770 0.050019 0.384851 0.3197616 0.0013398 0.000088 -0.000301 0.000066 0.000078 0.0000072 0.0000102 0.000037 0.000032 2006 2 5 53771 0.050220 0.384890 0.3186067 0.0009818 0.000122 -0.000286 0.000066 0.000078 0.0000097 0.0000101 0.000038 0.000032 2006 2 6 53772 0.050939 0.384731 0.3177817 0.0007485 0.000156 -0.000271 0.000066 0.000078 0.0000082 0.0000101 0.000038 0.000032 2006 2 7 53773 0.051145 0.384812 0.3172218 0.0005327 0.000189 -0.000256 0.000066 0.000078 0.0000046 0.0000100 0.000038 0.000032 2006 2 8 53774 0.051373 0.384583 0.3168287 0.0003589 0.000139 -0.000261 0.000066 0.000078 0.0000048 0.0000100 0.000038 0.000032 2006 2 9 53775 0.052620 0.384549 0.3164704 0.0003609 0.000156 -0.000254 0.000066 0.000078 0.0000119 0.0000100 0.000039 0.000033 2006 2 10 53776 0.053783 0.384758 0.3160763 0.0003853 0.000283 -0.000367 0.000066 0.000078 0.0000064 0.0000100 0.000039 0.000033 2006 2 11 53777 0.055065 0.384848 0.3155714 0.0005013 0.000297 -0.000381 0.000066 0.000078 0.0000085 0.0000100 0.000039 0.000033 2006 2 12 53778 0.056394 0.384755 0.3149398 0.0007649 0.000259 -0.000343 0.000066 0.000078 0.0000109 0.0000100 0.000040 0.000034 2006 2 13 53779 0.057363 0.384414 0.3142098 0.0008930 0.000221 -0.000306 0.000066 0.000079 0.0000084 0.0000099 0.000040 0.000034 2006 2 14 53780 0.058105 0.384098 0.3133451 0.0009088 0.000183 -0.000268 0.000066 0.000079 0.0000046 0.0000099 0.000040 0.000034 2006 2 15 53781 0.058914 0.383879 0.3123960 0.0009619 0.000131 -0.000314 0.000066 0.000079 0.0000156 0.0000099 0.000041 0.000035 2006 2 16 53782 0.060272 0.383845 0.3113420 0.0009981 0.000129 -0.000342 0.000066 0.000079 0.0000141 0.0000099 0.000041 0.000035 2006 2 17 53783 0.061965 0.384259 0.3102504 0.0010772 0.000143 -0.000359 0.000066 0.000079 0.0000078 0.0000099 0.000042 0.000036 2006 2 18 53784 0.064241 0.384896 0.3091132 0.0010850 0.000151 -0.000384 0.000066 0.000079 0.0000062 0.0000098 0.000042 0.000036 2006 2 19 53785 0.065865 0.385293 0.3080381 0.0009813 0.000158 -0.000411 0.000066 0.000079 0.0000076 0.0000098 0.000042 0.000036 2006 2 20 53786 0.066846 0.385126 0.3071198 0.0008798 0.000165 -0.000439 0.000066 0.000079 0.0000073 0.0000097 0.000042 0.000036 2006 2 21 53787 0.067444 0.384911 0.3063790 0.0006745 0.000172 -0.000466 0.000066 0.000079 0.0000058 0.0000097 0.000042 0.000037 2006 2 22 53788 0.067407 0.384545 0.3058099 0.0005033 0.000182 -0.000350 0.000067 0.000079 0.0000125 0.0000096 0.000043 0.000037 2006 2 23 53789 0.067619 0.384089 0.3053768 0.0003395 0.000193 -0.000196 0.000067 0.000080 0.0000179 0.0000096 0.000043 0.000037 2006 2 24 53790 0.067930 0.383836 0.3050412 0.0004115 0.000228 -0.000334 0.000067 0.000080 0.0000100 0.0000095 0.000043 0.000037 2006 2 25 53791 0.068802 0.383328 0.3044967 0.0005874 0.000207 -0.000366 0.000067 0.000080 0.0000082 0.0000094 0.000043 0.000037 2006 2 26 53792 0.070167 0.383042 0.3036767 0.0010299 0.000162 -0.000324 0.000067 0.000080 0.0000166 0.0000093 0.000043 0.000036 2006 2 27 53793 0.071444 0.383035 0.3024761 0.0014564 0.000116 -0.000282 0.000067 0.000080 0.0000149 0.0000093 0.000042 0.000036 2006 2 28 53794 0.072005 0.383284 0.3008930 0.0017680 0.000071 -0.000239 0.000068 0.000081 0.0000061 0.0000092 0.000042 0.000035 2006 3 1 53795 0.072313 0.383157 0.2989653 0.0020181 0.000091 -0.000250 0.000068 0.000081 0.0000082 0.0000091 0.000042 0.000035 2006 3 2 53796 0.073502 0.383442 0.2969639 0.0018322 0.000130 -0.000277 0.000068 0.000081 0.0000118 0.0000090 0.000042 0.000035 2006 3 3 53797 0.074846 0.383527 0.2951765 0.0017963 0.000169 -0.000304 0.000068 0.000081 0.0000090 0.0000090 0.000042 0.000036 2006 3 4 53798 0.076841 0.383250 0.2935596 0.0014633 0.000154 -0.000307 0.000068 0.000081 0.0000069 0.0000089 0.000042 0.000035 2006 3 5 53799 0.078753 0.383620 0.2922692 0.0010574 0.000120 -0.000301 0.000068 0.000081 0.0000081 0.0000089 0.000042 0.000035 2006 3 6 53800 0.079971 0.383763 0.2913707 0.0007164 0.000086 -0.000296 0.000068 0.000081 0.0000069 0.0000088 0.000041 0.000035 2006 3 7 53801 0.080747 0.383596 0.2907565 0.0005716 0.000051 -0.000291 0.000068 0.000080 0.0000037 0.0000088 0.000041 0.000035 2006 3 8 53802 0.081283 0.383045 0.2902915 0.0004591 0.000117 -0.000295 0.000068 0.000080 0.0000085 0.0000088 0.000041 0.000035 2006 3 9 53803 0.081164 0.382632 0.2899070 0.0003351 0.000209 -0.000301 0.000068 0.000080 0.0000132 0.0000088 0.000042 0.000036 2006 3 10 53804 0.080468 0.382486 0.2895682 0.0003543 0.000300 -0.000308 0.000068 0.000080 0.0000095 0.0000088 0.000042 0.000036 2006 3 11 53805 0.080339 0.382636 0.2891410 0.0004825 0.000276 -0.000314 0.000068 0.000080 0.0000067 0.0000089 0.000042 0.000036 2006 3 12 53806 0.080585 0.382641 0.2886364 0.0006208 0.000209 -0.000321 0.000068 0.000080 0.0000056 0.0000089 0.000042 0.000037 2006 3 13 53807 0.081252 0.381797 0.2879557 0.0008145 0.000142 -0.000328 0.000068 0.000080 0.0000057 0.0000089 0.000042 0.000037 2006 3 14 53808 0.082256 0.380970 0.2871084 0.0008617 0.000075 -0.000335 0.000068 0.000080 0.0000060 0.0000090 0.000042 0.000037 2006 3 15 53809 0.083465 0.380403 0.2860859 0.0010316 0.000063 -0.000374 0.000068 0.000080 0.0000133 0.0000090 0.000043 0.000037 2006 3 16 53810 0.085421 0.379708 0.2850123 0.0009990 0.000066 -0.000420 0.000068 0.000080 0.0000199 0.0000090 0.000043 0.000038 2006 3 17 53811 0.088016 0.379359 0.2840332 0.0010033 0.000068 -0.000466 0.000068 0.000080 0.0000168 0.0000091 0.000043 0.000038 2006 3 18 53812 0.089831 0.379227 0.2830712 0.0009220 0.000066 -0.000436 0.000068 0.000080 0.0000118 0.0000091 0.000043 0.000038 2006 3 19 53813 0.091290 0.378846 0.2821765 0.0008377 0.000061 -0.000379 0.000068 0.000080 0.0000092 0.0000092 0.000043 0.000038 2006 3 20 53814 0.092707 0.378449 0.2814524 0.0007061 0.000056 -0.000321 0.000068 0.000080 0.0000083 0.0000092 0.000043 0.000038 2006 3 21 53815 0.093852 0.378137 0.2808876 0.0005520 0.000051 -0.000263 0.000067 0.000079 0.0000074 0.0000093 0.000043 0.000038 2006 3 22 53816 0.095092 0.378025 0.2803367 0.0005161 -0.000140 -0.000299 0.000067 0.000079 0.0000120 0.0000093 0.000043 0.000038 2006 3 23 53817 0.096184 0.377869 0.2798129 0.0005425 -0.000016 -0.000301 0.000067 0.000079 0.0000151 0.0000094 0.000042 0.000038 2006 3 24 53818 0.097268 0.377330 0.2793173 0.0006830 0.000213 -0.000286 0.000067 0.000079 0.0000075 0.0000094 0.000042 0.000037 2006 3 25 53819 0.097979 0.377135 0.2784846 0.0009418 0.000225 -0.000306 0.000067 0.000079 0.0000062 0.0000095 0.000042 0.000037 2006 3 26 53820 0.098535 0.376979 0.2773033 0.0013728 0.000156 -0.000340 0.000067 0.000079 0.0000060 0.0000095 0.000041 0.000036 2006 3 27 53821 0.099249 0.376775 0.2757856 0.0016197 0.000087 -0.000373 0.000067 0.000079 0.0000047 0.0000095 0.000041 0.000036 2006 3 28 53822 0.099978 0.376222 0.2739599 0.0018813 0.000019 -0.000407 0.000067 0.000079 0.0000030 0.0000095 0.000041 0.000036 2006 3 29 53823 0.100873 0.375819 0.2719039 0.0020797 -0.000162 -0.000315 0.000067 0.000080 0.0000026 0.0000095 0.000041 0.000036 2006 3 30 53824 0.101415 0.375335 0.2698608 0.0019923 -0.000210 -0.000240 0.000067 0.000080 0.0000025 0.0000094 0.000041 0.000036 2006 3 31 53825 0.101936 0.374866 0.2680188 0.0016845 -0.000053 -0.000313 0.000067 0.000080 0.0000040 0.0000094 0.000041 0.000036 2006 4 1 53826 0.102648 0.374367 0.2664800 0.0013332 0.000007 -0.000326 0.000067 0.000080 0.0000066 0.0000093 0.000041 0.000037 2006 4 2 53827 0.103294 0.373787 0.2653116 0.0009306 0.000010 -0.000300 0.000067 0.000080 0.0000121 0.0000092 0.000042 0.000037 2006 4 3 53828 0.103538 0.373301 0.2645186 0.0006713 0.000014 -0.000275 0.000067 0.000080 0.0000112 0.0000091 0.000042 0.000037 2006 4 4 53829 0.103995 0.373004 0.2639504 0.0005997 0.000018 -0.000249 0.000067 0.000080 0.0000064 0.0000091 0.000042 0.000038 2006 4 5 53830 0.104454 0.372691 0.2633918 0.0005805 0.000057 -0.000296 0.000067 0.000081 0.0000073 0.0000090 0.000042 0.000038 2006 4 6 53831 0.104464 0.372187 0.2628109 0.0006407 0.000106 -0.000360 0.000067 0.000081 0.0000088 0.0000090 0.000043 0.000039 2006 4 7 53832 0.104262 0.372023 0.2621867 0.0007006 0.000155 -0.000425 0.000067 0.000081 0.0000066 0.0000090 0.000043 0.000040 2006 4 8 53833 0.103983 0.371775 0.2613931 0.0008565 0.000157 -0.000413 0.000067 0.000081 0.0000060 0.0000090 0.000044 0.000041 2006 4 9 53834 0.104246 0.371156 0.2604043 0.0011252 0.000141 -0.000373 0.000067 0.000081 0.0000048 0.0000091 0.000044 0.000041 2006 4 10 53835 0.104515 0.370704 0.2592712 0.0012104 0.000126 -0.000332 0.000067 0.000080 0.0000046 0.0000091 0.000044 0.000042 2006 4 11 53836 0.103967 0.369827 0.2580350 0.0012043 0.000110 -0.000292 0.000067 0.000080 0.0000051 0.0000091 0.000045 0.000043 2006 4 12 53837 0.103508 0.368833 0.2567778 0.0011971 -0.000006 -0.000232 0.000067 0.000080 0.0000049 0.0000091 0.000045 0.000043 2006 4 13 53838 0.103339 0.368321 0.2555385 0.0012027 0.000062 -0.000257 0.000067 0.000080 0.0000046 0.0000091 0.000045 0.000043 2006 4 14 53839 0.103217 0.367761 0.2543738 0.0010913 0.000068 -0.000266 0.000067 0.000080 0.0000043 0.0000091 0.000045 0.000043 2006 4 15 53840 0.102439 0.367266 0.2533437 0.0009061 0.000026 -0.000258 0.000067 0.000080 0.0000041 0.0000091 0.000044 0.000043 2006 4 16 53841 0.101771 0.366572 0.2524866 0.0007561 -0.000017 -0.000250 0.000067 0.000080 0.0000039 0.0000091 0.000044 0.000043 2006 4 17 53842 0.101894 0.366266 0.2518087 0.0005901 -0.000059 -0.000242 0.000067 0.000080 0.0000037 0.0000091 0.000044 0.000042 2006 4 18 53843 0.102006 0.366114 0.2512773 0.0005559 -0.000101 -0.000233 0.000067 0.000080 0.0000035 0.0000091 0.000044 0.000042 2006 4 19 53844 0.102092 0.365589 0.2508193 0.0005288 -0.000143 -0.000225 0.000067 0.000080 0.0000033 0.0000091 0.000043 0.000042 2006 4 20 53845 0.102827 0.364841 0.2503256 0.0005958 -0.000044 -0.000264 0.000067 0.000080 0.0000047 0.0000090 0.000043 0.000042 2006 4 21 53846 0.103703 0.364397 0.2496745 0.0006997 0.000091 -0.000315 0.000067 0.000080 0.0000065 0.0000090 0.000043 0.000042 2006 4 22 53847 0.104294 0.364093 0.2487600 0.0009824 0.000108 -0.000327 0.000067 0.000080 0.0000073 0.0000090 0.000042 0.000041 2006 4 23 53848 0.105025 0.363747 0.2475301 0.0013903 0.000079 -0.000324 0.000067 0.000080 0.0000157 0.0000089 0.000042 0.000040 2006 4 24 53849 0.105644 0.363173 0.2460060 0.0017328 0.000050 -0.000321 0.000067 0.000080 0.0000167 0.0000089 0.000041 0.000040 2006 4 25 53850 0.105991 0.362566 0.2442586 0.0017613 0.000022 -0.000318 0.000067 0.000080 0.0000121 0.0000088 0.000041 0.000039 2006 4 26 53851 0.106188 0.362183 0.2424188 0.0017755 -0.000073 -0.000276 0.000067 0.000080 0.0000053 0.0000088 0.000041 0.000039 2006 4 27 53852 0.106398 0.361994 0.2406439 0.0017024 -0.000067 -0.000149 0.000067 0.000080 0.0000033 0.0000087 0.000040 0.000039 2006 4 28 53853 0.107182 0.361777 0.2390411 0.0014922 0.000005 -0.000074 0.000067 0.000080 0.0000051 0.0000087 0.000040 0.000039 2006 4 29 53854 0.108509 0.361534 0.2376846 0.0011860 0.000042 -0.000103 0.000067 0.000080 0.0000063 0.0000086 0.000041 0.000039 2006 4 30 53855 0.109431 0.361063 0.2366893 0.0008258 0.000061 -0.000161 0.000067 0.000080 0.0000079 0.0000086 0.000041 0.000039 2006 5 1 53856 0.109738 0.360471 0.2359089 0.0007205 0.000080 -0.000219 0.000067 0.000080 0.0000081 0.0000085 0.000041 0.000039 2006 5 2 53857 0.109824 0.359919 0.2352005 0.0007531 0.000100 -0.000277 0.000067 0.000080 0.0000073 0.0000084 0.000041 0.000039 2006 5 3 53858 0.109899 0.359320 0.2344736 0.0008370 0.000119 -0.000336 0.000067 0.000080 0.0000065 0.0000084 0.000041 0.000039 2006 5 4 53859 0.109599 0.358368 0.2336302 0.0009541 0.000109 -0.000269 0.000067 0.000080 0.0000068 0.0000084 0.000041 0.000040 2006 5 5 53860 0.109169 0.357214 0.2326332 0.0010662 0.000091 -0.000171 0.000067 0.000080 0.0000074 0.0000083 0.000041 0.000040 2006 5 6 53861 0.108602 0.355942 0.2314541 0.0012169 0.000078 -0.000176 0.000067 0.000080 0.0000060 0.0000083 0.000041 0.000041 2006 5 7 53862 0.108586 0.354619 0.2301833 0.0013006 0.000066 -0.000218 0.000067 0.000080 0.0000219 0.0000083 0.000041 0.000041 2006 5 8 53863 0.108239 0.353789 0.2288287 0.0013956 0.000054 -0.000261 0.000067 0.000080 0.0000219 0.0000083 0.000041 0.000041 2006 5 9 53864 0.107938 0.353088 0.2273875 0.0014454 0.000042 -0.000304 0.000067 0.000080 0.0000089 0.0000083 0.000041 0.000041 2006 5 10 53865 0.107660 0.352447 0.2258515 0.0014924 0.000067 -0.000333 0.000067 0.000080 0.0000123 0.0000083 0.000041 0.000042 2006 5 11 53866 0.107376 0.352042 0.2243375 0.0014845 0.000102 -0.000359 0.000067 0.000080 0.0000167 0.0000083 0.000042 0.000042 2006 5 12 53867 0.107399 0.351837 0.2229347 0.0014193 0.000137 -0.000385 0.000067 0.000080 0.0000090 0.0000083 0.000042 0.000042 2006 5 13 53868 0.107665 0.351068 0.2216153 0.0013108 0.000130 -0.000371 0.000067 0.000080 0.0000086 0.0000083 0.000042 0.000042 2006 5 14 53869 0.108442 0.350202 0.2204624 0.0010233 0.000108 -0.000343 0.000068 0.000080 0.0000096 0.0000083 0.000042 0.000042 2006 5 15 53870 0.109626 0.349488 0.2195137 0.0008653 0.000086 -0.000314 0.000068 0.000080 0.0000114 0.0000083 0.000041 0.000041 2006 5 16 53871 0.110765 0.348976 0.2187078 0.0008113 0.000064 -0.000285 0.000068 0.000080 0.0000137 0.0000083 0.000041 0.000041 2006 5 17 53872 0.111031 0.348266 0.2179593 0.0007454 0.000080 -0.000277 0.000068 0.000080 0.0000124 0.0000083 0.000041 0.000041 2006 5 18 53873 0.111109 0.347435 0.2171657 0.0008263 0.000105 -0.000274 0.000068 0.000081 0.0000101 0.0000083 0.000041 0.000040 2006 5 19 53874 0.111280 0.346554 0.2162785 0.0009673 0.000130 -0.000271 0.000068 0.000081 0.0000074 0.0000083 0.000040 0.000040 2006 5 20 53875 0.111492 0.345776 0.2151104 0.0012225 0.000100 -0.000277 0.000068 0.000081 0.0000148 0.0000083 0.000040 0.000039 2006 5 21 53876 0.111837 0.345412 0.2137404 0.0014152 0.000050 -0.000287 0.000068 0.000081 0.0000129 0.0000082 0.000040 0.000039 2006 5 22 53877 0.112211 0.344979 0.2122369 0.0015936 0.000000 -0.000296 0.000068 0.000081 0.0000078 0.0000082 0.000040 0.000038 2006 5 23 53878 0.112834 0.344447 0.2106862 0.0015341 -0.000050 -0.000306 0.000068 0.000081 0.0000044 0.0000082 0.000039 0.000038 2006 5 24 53879 0.113519 0.343672 0.2091575 0.0014415 -0.000121 -0.000209 0.000068 0.000081 0.0000040 0.0000082 0.000039 0.000038 2006 5 25 53880 0.114378 0.342561 0.2077703 0.0012359 -0.000087 -0.000172 0.000068 0.000081 0.0000044 0.0000082 0.000039 0.000038 2006 5 26 53881 0.115151 0.341478 0.2066767 0.0009294 -0.000022 -0.000162 0.000068 0.000081 0.0000048 0.0000082 0.000039 0.000038 2006 5 27 53882 0.115847 0.340402 0.2058929 0.0005783 -0.000028 -0.000261 0.000068 0.000081 0.0000108 0.0000082 0.000039 0.000038 2006 5 28 53883 0.117113 0.339192 0.2054465 0.0002722 -0.000060 -0.000400 0.000068 0.000081 0.0000164 0.0000082 0.000039 0.000038 2006 5 29 53884 0.118373 0.338257 0.2052330 0.0001550 -0.000092 -0.000539 0.000068 0.000081 0.0000142 0.0000082 0.000039 0.000038 2006 5 30 53885 0.119365 0.337275 0.2050883 0.0001519 -0.000124 -0.000676 0.000068 0.000082 0.0000090 0.0000082 0.000039 0.000038 2006 5 31 53886 0.119990 0.336537 0.2049027 0.0002637 -0.000033 -0.000270 0.000069 0.000082 0.0000037 0.0000082 0.000038 0.000038 2006 6 1 53887 0.120523 0.335727 0.2045798 0.0004155 0.000007 -0.000219 0.000069 0.000082 0.0000037 0.0000082 0.000038 0.000038 2006 6 2 53888 0.121110 0.334974 0.2041148 0.0005609 0.000033 -0.000259 0.000069 0.000082 0.0000051 0.0000082 0.000038 0.000038 2006 6 3 53889 0.121536 0.334077 0.2034914 0.0007478 0.000043 -0.000242 0.000069 0.000082 0.0000051 0.0000082 0.000039 0.000038 2006 6 4 53890 0.122241 0.332803 0.2027546 0.0007891 0.000047 -0.000203 0.000069 0.000082 0.0000044 0.0000082 0.000039 0.000038 2006 6 5 53891 0.122559 0.331501 0.2019626 0.0007502 0.000051 -0.000164 0.000069 0.000082 0.0000038 0.0000081 0.000039 0.000038 2006 6 6 53892 0.122493 0.330154 0.2011778 0.0007243 0.000055 -0.000124 0.000069 0.000082 0.0000031 0.0000081 0.000039 0.000038 2006 6 7 53893 0.122645 0.328736 0.2004694 0.0006070 0.000059 -0.000085 0.000069 0.000082 0.0000025 0.0000080 0.000039 0.000038 2006 6 8 53894 0.123147 0.327327 0.1999145 0.0004788 -0.000056 -0.000129 0.000069 0.000082 0.0000036 0.0000080 0.000039 0.000039 2006 6 9 53895 0.123362 0.326070 0.1995632 0.0002071 -0.000068 -0.000241 0.000069 0.000082 0.0000051 0.0000080 0.000039 0.000039 2006 6 10 53896 0.123364 0.324855 0.1994533 -0.0000364 -0.000008 -0.000269 0.000069 0.000082 0.0000137 0.0000079 0.000039 0.000038 2006 6 11 53897 0.123542 0.323403 0.1995980 -0.0002313 0.000061 -0.000261 0.000069 0.000082 0.0000123 0.0000079 0.000039 0.000038 2006 6 12 53898 0.123906 0.321604 0.1999403 -0.0003829 0.000131 -0.000253 0.000070 0.000082 0.0000072 0.0000079 0.000039 0.000038 2006 6 13 53899 0.124370 0.319845 0.2003563 -0.0003865 0.000201 -0.000245 0.000070 0.000082 0.0000033 0.0000079 0.000039 0.000038 2006 6 14 53900 0.125136 0.318325 0.2006605 -0.0001816 0.000006 -0.000440 0.000070 0.000082 0.0000051 0.0000079 0.000039 0.000038 2006 6 15 53901 0.125742 0.317348 0.2007661 0.0000059 -0.000067 -0.000471 0.000070 0.000082 0.0000110 0.0000079 0.000039 0.000038 2006 6 16 53902 0.125981 0.316491 0.2005942 0.0003060 -0.000070 -0.000423 0.000070 0.000082 0.0000179 0.0000078 0.000040 0.000038 2006 6 17 53903 0.126149 0.315692 0.2001034 0.0005889 -0.000073 -0.000375 0.000070 0.000082 0.0000204 0.0000078 0.000040 0.000038 2006 6 18 53904 0.126272 0.314653 0.1993264 0.0008338 -0.000076 -0.000327 0.000070 0.000082 0.0000199 0.0000078 0.000040 0.000038 2006 6 19 53905 0.126404 0.313373 0.1984916 0.0009138 -0.000079 -0.000279 0.000070 0.000082 0.0000151 0.0000077 0.000040 0.000038 2006 6 20 53906 0.126207 0.312306 0.1976915 0.0008029 -0.000082 -0.000231 0.000070 0.000082 0.0000047 0.0000077 0.000040 0.000038 2006 6 21 53907 0.125996 0.311188 0.1969784 0.0005729 -0.000034 -0.000179 0.000070 0.000082 0.0000234 0.0000076 0.000041 0.000038 2006 6 22 53908 0.125511 0.310392 0.1964702 0.0003785 0.000028 -0.000127 0.000070 0.000082 0.0000496 0.0000076 0.000041 0.000038 2006 6 23 53909 0.124810 0.309571 0.1962126 0.0001416 0.000032 -0.000099 0.000070 0.000082 0.0000203 0.0000075 0.000041 0.000038 2006 6 24 53910 0.124740 0.308490 0.1960973 -0.0000152 0.000022 -0.000095 0.000070 0.000082 0.0000077 0.0000075 0.000041 0.000037 2006 6 25 53911 0.125144 0.307237 0.1961682 -0.0000850 0.000014 -0.000096 0.000070 0.000082 0.0000106 0.0000074 0.000041 0.000037 2006 6 26 53912 0.125613 0.306059 0.1962882 -0.0001045 0.000005 -0.000097 0.000070 0.000082 0.0000089 0.0000073 0.000041 0.000037 2006 6 27 53913 0.125978 0.304914 0.1963141 0.0000461 -0.000003 -0.000098 0.000070 0.000082 0.0000043 0.0000073 0.000041 0.000036 2006 6 28 53914 0.126181 0.303916 0.1961610 0.0002532 0.000050 -0.000141 0.000070 0.000082 0.0000038 0.0000072 0.000041 0.000036 2006 6 29 53915 0.126642 0.302665 0.1958341 0.0004918 0.000152 -0.000101 0.000070 0.000082 0.0000032 0.0000071 0.000041 0.000036 2006 6 30 53916 0.127500 0.301287 0.1952760 0.0006772 0.000127 -0.000144 0.000070 0.000082 0.0000055 0.0000071 0.000041 0.000036 2006 7 1 53917 0.128398 0.299901 0.1944912 0.0008533 0.000106 -0.000149 0.000070 0.000082 0.0000102 0.0000070 0.000041 0.000036 2006 7 2 53918 0.128783 0.298884 0.1935634 0.0009789 0.000103 -0.000128 0.000070 0.000082 0.0000114 0.0000070 0.000041 0.000035 2006 7 3 53919 0.128893 0.297732 0.1925842 0.0009863 0.000100 -0.000106 0.000071 0.000082 0.0000132 0.0000069 0.000041 0.000035 2006 7 4 53920 0.128791 0.296532 0.1916096 0.0009518 0.000097 -0.000085 0.000071 0.000082 0.0000146 0.0000068 0.000041 0.000035 2006 7 5 53921 0.128802 0.295325 0.1906798 0.0008763 0.000035 -0.000115 0.000071 0.000082 0.0000096 0.0000067 0.000040 0.000035 2006 7 6 53922 0.128706 0.294506 0.1898986 0.0007423 -0.000027 -0.000145 0.000071 0.000083 0.0000047 0.0000067 0.000040 0.000034 2006 7 7 53923 0.128394 0.293690 0.1892951 0.0005150 0.000041 -0.000261 0.000071 0.000083 0.0000077 0.0000066 0.000040 0.000034 2006 7 8 53924 0.128145 0.292433 0.1888762 0.0002706 0.000050 -0.000277 0.000071 0.000083 0.0000119 0.0000065 0.000040 0.000034 2006 7 9 53925 0.127493 0.291132 0.1887230 0.0000645 0.000026 -0.000246 0.000071 0.000083 0.0000117 0.0000065 0.000040 0.000034 2006 7 10 53926 0.126814 0.289755 0.1887430 -0.0000210 0.000003 -0.000216 0.000071 0.000083 0.0000083 0.0000064 0.000040 0.000034 2006 7 11 53927 0.126120 0.288345 0.1887655 0.0000374 -0.000021 -0.000186 0.000071 0.000083 0.0000043 0.0000063 0.000040 0.000033 2006 7 12 53928 0.125970 0.286898 0.1886776 0.0001536 -0.000120 -0.000191 0.000071 0.000083 0.0000038 0.0000062 0.000040 0.000033 2006 7 13 53929 0.125512 0.285696 0.1884410 0.0004396 -0.000153 -0.000264 0.000071 0.000083 0.0000262 0.0000062 0.000040 0.000034 2006 7 14 53930 0.124555 0.284870 0.1878098 0.0007536 -0.000023 -0.000218 0.000071 0.000083 0.0000141 0.0000062 0.000040 0.000034 2006 7 15 53931 0.123357 0.284203 0.1868578 0.0010506 -0.000002 -0.000210 0.000071 0.000083 0.0000110 0.0000062 0.000040 0.000034 2006 7 16 53932 0.122628 0.283238 0.1857432 0.0011252 -0.000038 -0.000232 0.000071 0.000083 0.0000099 0.0000062 0.000040 0.000035 2006 7 17 53933 0.122073 0.282116 0.1846697 0.0010580 -0.000074 -0.000254 0.000071 0.000083 0.0000067 0.0000061 0.000040 0.000035 2006 7 18 53934 0.121576 0.281062 0.1837781 0.0008498 -0.000110 -0.000276 0.000071 0.000083 0.0000041 0.0000061 0.000040 0.000035 2006 7 19 53935 0.121165 0.280255 0.1830817 0.0005600 -0.000071 -0.000153 0.000071 0.000083 0.0000037 0.0000061 0.000041 0.000035 2006 7 20 53936 0.120679 0.279484 0.1826624 0.0002740 -0.000012 0.000007 0.000071 0.000083 0.0000037 0.0000061 0.000041 0.000036 2006 7 21 53937 0.120055 0.278719 0.1825117 -0.0000199 0.000035 -0.000123 0.000071 0.000083 0.0000045 0.0000061 0.000041 0.000036 2006 7 22 53938 0.119320 0.277851 0.1825561 -0.0001624 0.000077 -0.000184 0.000071 0.000083 0.0000101 0.0000061 0.000041 0.000036 2006 7 23 53939 0.118757 0.276910 0.1827780 -0.0002707 0.000119 -0.000184 0.000071 0.000083 0.0000110 0.0000061 0.000041 0.000037 2006 7 24 53940 0.117908 0.275956 0.1830410 -0.0002656 0.000161 -0.000184 0.000071 0.000083 0.0000087 0.0000061 0.000042 0.000037 2006 7 25 53941 0.117279 0.274688 0.1832249 -0.0001163 0.000203 -0.000184 0.000071 0.000083 0.0000063 0.0000061 0.000042 0.000037 2006 7 26 53942 0.116872 0.273574 0.1832699 0.0000354 0.000142 -0.000180 0.000071 0.000083 0.0001950 0.0000061 0.000042 0.000038 2006 7 27 53943 0.116371 0.272883 0.1831565 0.0001907 0.000053 -0.000176 0.000070 0.000083 0.0004335 0.0000061 0.000042 0.000038 2006 7 28 53944 0.116219 0.272491 0.1829029 0.0002821 -0.000035 -0.000171 0.000070 0.000083 0.0001490 0.0000061 0.000042 0.000038 2006 7 29 53945 0.116092 0.272535 0.1825314 0.0004140 -0.000052 -0.000176 0.000070 0.000083 0.0000158 0.0000060 0.000042 0.000039 2006 7 30 53946 0.115074 0.272554 0.1820789 0.0004858 -0.000045 -0.000185 0.000070 0.000082 0.0000183 0.0000060 0.000043 0.000039 2006 7 31 53947 0.113778 0.271817 0.1815992 0.0005022 -0.000037 -0.000194 0.000070 0.000082 0.0000173 0.0000060 0.000043 0.000039 2006 8 1 53948 0.112453 0.271160 0.1811635 0.0004146 -0.000030 -0.000203 0.000070 0.000082 0.0000145 0.0000059 0.000043 0.000039 2006 8 2 53949 0.111273 0.270617 0.1807966 0.0003119 -0.000042 -0.000222 0.000070 0.000083 0.0000091 0.0000059 0.000043 0.000039 2006 8 3 53950 0.110206 0.269965 0.1805664 0.0001494 -0.000070 -0.000244 0.000070 0.000083 0.0000148 0.0000059 0.000042 0.000039 2006 8 4 53951 0.109279 0.269021 0.1804954 0.0000043 -0.000108 -0.000294 0.000070 0.000083 0.0000097 0.0000059 0.000042 0.000039 2006 8 5 53952 0.108734 0.267850 0.1805136 -0.0001391 -0.000121 -0.000280 0.000070 0.000082 0.0000125 0.0000059 0.000042 0.000038 2006 8 6 53953 0.108476 0.266511 0.1806675 -0.0002164 -0.000124 -0.000239 0.000070 0.000082 0.0000183 0.0000059 0.000041 0.000038 2006 8 7 53954 0.108297 0.265208 0.1808892 -0.0001840 -0.000126 -0.000198 0.000070 0.000082 0.0000153 0.0000059 0.000041 0.000037 2006 8 8 53955 0.108449 0.264119 0.1809939 -0.0000070 -0.000128 -0.000157 0.000070 0.000082 0.0000082 0.0000059 0.000040 0.000037 2006 8 9 53956 0.108446 0.263498 0.1808146 0.0003176 -0.000121 -0.000164 0.000070 0.000082 0.0000136 0.0000059 0.000040 0.000036 2006 8 10 53957 0.107809 0.262837 0.1802984 0.0006548 -0.000111 -0.000184 0.000070 0.000082 0.0000184 0.0000059 0.000039 0.000036 2006 8 11 53958 0.106930 0.261782 0.1794876 0.0009778 -0.000101 -0.000204 0.000070 0.000082 0.0000091 0.0000059 0.000039 0.000035 2006 8 12 53959 0.105990 0.260834 0.1784048 0.0010876 -0.000095 -0.000191 0.000070 0.000082 0.0000150 0.0000059 0.000038 0.000035 2006 8 13 53960 0.105128 0.259995 0.1772783 0.0010820 -0.000090 -0.000165 0.000070 0.000082 0.0000149 0.0000059 0.000038 0.000034 2006 8 14 53961 0.104447 0.259455 0.1763026 0.0009151 -0.000086 -0.000140 0.000070 0.000082 0.0000135 0.0000059 0.000037 0.000033 2006 8 15 53962 0.103483 0.258934 0.1755904 0.0006338 -0.000082 -0.000115 0.000070 0.000082 0.0000133 0.0000059 0.000037 0.000033 2006 8 16 53963 0.102129 0.258713 0.1751815 0.0002916 -0.000078 -0.000090 0.000070 0.000082 0.0000091 0.0000059 0.000036 0.000032 2006 8 17 53964 0.100615 0.258105 0.1750511 0.0000417 -0.000074 -0.000065 0.000070 0.000082 0.0000049 0.0000059 0.000036 0.000032 2006 8 18 53965 0.099404 0.257389 0.1751023 -0.0001581 -0.000064 -0.000138 0.000070 0.000082 0.0000100 0.0000059 0.000035 0.000032 2006 8 19 53966 0.098123 0.256555 0.1752365 -0.0001735 -0.000063 -0.000166 0.000070 0.000082 0.0000118 0.0000059 0.000035 0.000031 2006 8 20 53967 0.096563 0.255837 0.1753961 -0.0001360 -0.000066 -0.000168 0.000070 0.000082 0.0000142 0.0000059 0.000034 0.000031 2006 8 21 53968 0.095053 0.255476 0.1754496 -0.0000227 -0.000069 -0.000170 0.000070 0.000083 0.0000111 0.0000059 0.000034 0.000031 2006 8 22 53969 0.093961 0.255277 0.1753320 0.0001816 -0.000073 -0.000171 0.000070 0.000083 0.0000048 0.0000058 0.000033 0.000031 2006 8 23 53970 0.092932 0.254984 0.1750183 0.0003743 -0.000030 -0.000262 0.000070 0.000083 0.0000026 0.0000058 0.000033 0.000030 2006 8 24 53971 0.091518 0.254428 0.1745218 0.0005708 0.000028 -0.000380 0.000071 0.000083 0.0000017 0.0000058 0.000033 0.000030 2006 8 25 53972 0.090503 0.253985 0.1738813 0.0007020 -0.000088 -0.000203 0.000071 0.000083 0.0000041 0.0000058 0.000033 0.000030 2006 8 26 53973 0.089681 0.254041 0.1731744 0.0007568 -0.000128 -0.000121 0.000071 0.000083 0.0000157 0.0000057 0.000033 0.000030 2006 8 27 53974 0.088548 0.254157 0.1724272 0.0007236 -0.000120 -0.000111 0.000071 0.000083 0.0000138 0.0000057 0.000032 0.000030 2006 8 28 53975 0.087095 0.254275 0.1717179 0.0006818 -0.000111 -0.000100 0.000071 0.000083 0.0000081 0.0000057 0.000032 0.000030 2006 8 29 53976 0.085793 0.254109 0.1711133 0.0005930 -0.000102 -0.000090 0.000071 0.000083 0.0000047 0.0000057 0.000032 0.000030 2006 8 30 53977 0.084538 0.254165 0.1706349 0.0004252 -0.000122 -0.000069 0.000071 0.000083 0.0000032 0.0000056 0.000032 0.000031 2006 8 31 53978 0.083366 0.254132 0.1703128 0.0002546 -0.000149 -0.000046 0.000071 0.000083 0.0000022 0.0000057 0.000031 0.000031 2006 9 1 53979 0.082464 0.254220 0.1701813 0.0000586 -0.000009 -0.000112 0.000071 0.000084 0.0000069 0.0000057 0.000032 0.000031 2006 9 2 53980 0.081259 0.254303 0.1701208 0.0000047 -0.000007 -0.000152 0.000071 0.000084 0.0000102 0.0000057 0.000032 0.000031 2006 9 3 53981 0.079716 0.254388 0.1700971 0.0000010 -0.000076 -0.000171 0.000072 0.000083 0.0000097 0.0000057 0.000032 0.000031 2006 9 4 53982 0.078218 0.254431 0.1699897 0.0001270 -0.000145 -0.000189 0.000072 0.000083 0.0000080 0.0000057 0.000032 0.000031 2006 9 5 53983 0.077178 0.254422 0.1696457 0.0005172 -0.000213 -0.000207 0.000072 0.000084 0.0000063 0.0000057 0.000032 0.000031 2006 9 6 53984 0.076818 0.254490 0.1689549 0.0008666 -0.000085 -0.000124 0.000072 0.000084 0.0000045 0.0000058 0.000032 0.000031 2006 9 7 53985 0.076194 0.254817 0.1678763 0.0012664 -0.000060 0.000068 0.000072 0.000084 0.0000049 0.0000058 0.000032 0.000031 2006 9 8 53986 0.075102 0.255152 0.1664764 0.0015181 -0.000064 0.000290 0.000072 0.000084 0.0000058 0.0000058 0.000032 0.000031 2006 9 9 53987 0.073795 0.254922 0.1648752 0.0015814 -0.000077 0.000275 0.000072 0.000084 0.0000314 0.0000058 0.000032 0.000031 2006 9 10 53988 0.072459 0.254604 0.1633437 0.0014973 -0.000095 0.000173 0.000072 0.000084 0.0000199 0.0000058 0.000032 0.000031 2006 9 11 53989 0.070753 0.254174 0.1620501 0.0011904 -0.000112 0.000070 0.000072 0.000084 0.0000065 0.0000059 0.000032 0.000030 2006 9 12 53990 0.069082 0.253889 0.1610726 0.0009146 -0.000129 -0.000033 0.000072 0.000084 0.0000029 0.0000059 0.000032 0.000030 2006 9 13 53991 0.067292 0.253431 0.1603390 0.0006322 -0.000060 -0.000010 0.000072 0.000084 0.0000025 0.0000059 0.000032 0.000030 2006 9 14 53992 0.065828 0.252641 0.1598335 0.0004462 -0.000019 -0.000056 0.000072 0.000084 0.0000029 0.0000059 0.000032 0.000030 2006 9 15 53993 0.064596 0.252192 0.1594832 0.0002679 0.000039 -0.000127 0.000072 0.000084 0.0000125 0.0000059 0.000032 0.000030 2006 9 16 53994 0.063355 0.252152 0.1591672 0.0003262 0.000050 -0.000111 0.000072 0.000084 0.0000115 0.0000060 0.000032 0.000030 2006 9 17 53995 0.061836 0.252239 0.1588043 0.0003856 0.000041 -0.000062 0.000072 0.000084 0.0000118 0.0000060 0.000032 0.000030 2006 9 18 53996 0.060231 0.252241 0.1583418 0.0005097 0.000032 -0.000013 0.000072 0.000084 0.0000096 0.0000060 0.000032 0.000030 2006 9 19 53997 0.058538 0.252706 0.1577206 0.0006954 0.000023 0.000035 0.000072 0.000085 0.0000045 0.0000060 0.000032 0.000031 2006 9 20 53998 0.056453 0.253051 0.1568938 0.0008614 -0.000178 0.000371 0.000072 0.000085 0.0000024 0.0000060 0.000032 0.000031 2006 9 21 53999 0.054216 0.253160 0.1558915 0.0010735 -0.000102 0.000346 0.000072 0.000085 0.0000033 0.0000061 0.000032 0.000031 2006 9 22 54000 0.051710 0.253348 0.1547731 0.0011353 0.000071 0.000192 0.000072 0.000085 0.0000048 0.0000061 0.000032 0.000031 2006 9 23 54001 0.049141 0.253107 0.1536046 0.0011486 0.000121 0.000118 0.000072 0.000085 0.0000049 0.0000062 0.000032 0.000031 2006 9 24 54002 0.047171 0.252906 0.1524494 0.0011572 0.000126 0.000074 0.000072 0.000085 0.0000045 0.0000063 0.000032 0.000031 2006 9 25 54003 0.045016 0.252726 0.1513660 0.0010710 0.000131 0.000029 0.000072 0.000085 0.0000040 0.0000063 0.000032 0.000031 2006 9 26 54004 0.043253 0.252314 0.1503983 0.0009474 0.000136 -0.000015 0.000072 0.000085 0.0000036 0.0000064 0.000032 0.000031 2006 9 27 54005 0.041665 0.252097 0.1495318 0.0007825 0.000122 -0.000014 0.000072 0.000085 0.0000116 0.0000065 0.000032 0.000031 2006 9 28 54006 0.039898 0.252170 0.1488009 0.0006762 0.000104 0.000000 0.000072 0.000085 0.0000182 0.0000065 0.000032 0.000032 2006 9 29 54007 0.037470 0.252317 0.1482181 0.0006536 0.000085 0.000013 0.000072 0.000085 0.0000113 0.0000066 0.000032 0.000032 2006 9 30 54008 0.035031 0.252322 0.1475667 0.0006394 0.000056 0.000005 0.000072 0.000085 0.0000099 0.0000067 0.000032 0.000032 2006 10 1 54009 0.032540 0.252664 0.1468202 0.0007675 0.000023 -0.000012 0.000072 0.000085 0.0000101 0.0000067 0.000032 0.000032 2006 10 2 54010 0.030295 0.252823 0.1459824 0.0009678 -0.000011 -0.000029 0.000072 0.000085 0.0000072 0.0000068 0.000032 0.000032 2006 10 3 54011 0.028269 0.253057 0.1448826 0.0012144 -0.000044 -0.000045 0.000072 0.000085 0.0000029 0.0000068 0.000031 0.000032 2006 10 4 54012 0.026894 0.253402 0.1434199 0.0015914 -0.000060 -0.000077 0.000072 0.000085 0.0000021 0.0000069 0.000031 0.000032 2006 10 5 54013 0.026045 0.253970 0.1415916 0.0019783 -0.000070 -0.000112 0.000072 0.000085 0.0000022 0.0000070 0.000032 0.000032 2006 10 6 54014 0.025223 0.254239 0.1394473 0.0022660 -0.000056 0.000053 0.000072 0.000085 0.0000053 0.0000070 0.000032 0.000032 2006 10 7 54015 0.024272 0.254650 0.1371601 0.0022551 -0.000039 0.000099 0.000072 0.000085 0.0000077 0.0000071 0.000032 0.000032 2006 10 8 54016 0.023577 0.255213 0.1349797 0.0020887 -0.000022 0.000075 0.000072 0.000085 0.0000090 0.0000072 0.000032 0.000032 2006 10 9 54017 0.022350 0.256172 0.1331007 0.0017566 -0.000006 0.000051 0.000072 0.000085 0.0000074 0.0000073 0.000032 0.000032 2006 10 10 54018 0.020385 0.257294 0.1315838 0.0014446 0.000010 0.000027 0.000072 0.000085 0.0000044 0.0000073 0.000032 0.000033 2006 10 11 54019 0.018254 0.257960 0.1303260 0.0011383 -0.000043 0.000073 0.000072 0.000085 0.0000113 0.0000074 0.000032 0.000033 2006 10 12 54020 0.015686 0.258306 0.1292889 0.0010044 -0.000065 0.000039 0.000072 0.000085 0.0000171 0.0000075 0.000032 0.000033 2006 10 13 54021 0.012980 0.258022 0.1284041 0.0008569 -0.000072 -0.000023 0.000072 0.000085 0.0000084 0.0000077 0.000032 0.000032 2006 10 14 54022 0.011140 0.257619 0.1275783 0.0008581 -0.000044 -0.000033 0.000072 0.000085 0.0000054 0.0000078 0.000032 0.000032 2006 10 15 54023 0.009785 0.257880 0.1266898 0.0008897 -0.000004 -0.000021 0.000071 0.000085 0.0000046 0.0000079 0.000031 0.000032 2006 10 16 54024 0.008391 0.258766 0.1256693 0.0009484 0.000037 -0.000010 0.000071 0.000084 0.0000039 0.0000080 0.000031 0.000032 2006 10 17 54025 0.007183 0.259870 0.1245031 0.0011918 0.000078 0.000001 0.000071 0.000084 0.0000031 0.0000081 0.000031 0.000031 2006 10 18 54026 0.006147 0.260601 0.1231942 0.0013310 0.000121 0.000043 0.000071 0.000084 0.0000070 0.0000081 0.000031 0.000032 2006 10 19 54027 0.005199 0.261547 0.1217800 0.0014334 0.000165 0.000093 0.000071 0.000084 0.0000105 0.0000082 0.000031 0.000032 2006 10 20 54028 0.004152 0.262288 0.1203127 0.0015232 0.000209 0.000144 0.000071 0.000084 0.0000081 0.0000083 0.000031 0.000032 2006 10 21 54029 0.003442 0.263090 0.1188018 0.0014726 0.000188 0.000133 0.000071 0.000084 0.0000078 0.0000084 0.000031 0.000032 2006 10 22 54030 0.002975 0.264065 0.1173489 0.0013827 0.000143 0.000099 0.000071 0.000084 0.0000101 0.0000084 0.000031 0.000032 2006 10 23 54031 0.002267 0.265053 0.1159950 0.0013431 0.000098 0.000065 0.000071 0.000084 0.0000085 0.0000084 0.000031 0.000032 2006 10 24 54032 0.001035 0.266298 0.1147879 0.0012029 0.000053 0.000032 0.000071 0.000084 0.0000045 0.0000084 0.000031 0.000032 2006 10 25 54033 -0.000596 0.267407 0.1137354 0.0009728 0.000038 -0.000012 0.000072 0.000084 0.0000094 0.0000084 0.000031 0.000032 2006 10 26 54034 -0.002019 0.267979 0.1128334 0.0008328 0.000030 -0.000058 0.000072 0.000084 0.0000141 0.0000084 0.000031 0.000032 2006 10 27 54035 -0.002515 0.268604 0.1120481 0.0007433 0.000022 -0.000104 0.000072 0.000084 0.0000098 0.0000084 0.000030 0.000031 2006 10 28 54036 -0.002963 0.269051 0.1112964 0.0007403 0.000036 -0.000091 0.000072 0.000084 0.0000066 0.0000084 0.000030 0.000031 2006 10 29 54037 -0.003178 0.269617 0.1105056 0.0009063 0.000060 -0.000056 0.000072 0.000085 0.0000049 0.0000083 0.000030 0.000030 2006 10 30 54038 -0.003279 0.270697 0.1095367 0.0010636 0.000083 -0.000021 0.000072 0.000085 0.0000037 0.0000083 0.000029 0.000030 2006 10 31 54039 -0.003871 0.271727 0.1082855 0.0013390 0.000106 0.000015 0.000072 0.000085 0.0000025 0.0000082 0.000029 0.000029 2006 11 1 54040 -0.004186 0.272858 0.1067014 0.0016911 0.000112 0.000077 0.000073 0.000085 0.0000033 0.0000082 0.000029 0.000029 2006 11 2 54041 -0.004286 0.274166 0.1048562 0.0019697 0.000114 0.000146 0.000073 0.000085 0.0000046 0.0000082 0.000029 0.000029 2006 11 3 54042 -0.004584 0.275383 0.1028856 0.0020677 0.000116 0.000215 0.000073 0.000085 0.0000060 0.0000081 0.000029 0.000029 2006 11 4 54043 -0.005115 0.276067 0.1008890 0.0019831 0.000120 0.000189 0.000073 0.000085 0.0000095 0.0000081 0.000029 0.000029 2006 11 5 54044 -0.005786 0.276840 0.0991173 0.0016508 0.000126 0.000129 0.000073 0.000086 0.0000094 0.0000081 0.000029 0.000028 2006 11 6 54045 -0.006490 0.277730 0.0977066 0.0012598 0.000131 0.000068 0.000073 0.000086 0.0000062 0.0000080 0.000028 0.000028 2006 11 7 54046 -0.007283 0.279311 0.0966416 0.0009722 0.000136 0.000008 0.000073 0.000086 0.0000025 0.0000080 0.000028 0.000028 2006 11 8 54047 -0.008838 0.281238 0.0958246 0.0007447 0.000079 0.000066 0.000074 0.000086 0.0000096 0.0000080 0.000028 0.000028 2006 11 9 54048 -0.010696 0.282362 0.0951318 0.0006519 0.000090 0.000094 0.000074 0.000086 0.0000042 0.0000080 0.000028 0.000027 2006 11 10 54049 -0.012376 0.283298 0.0944748 0.0006817 0.000154 0.000078 0.000074 0.000086 0.0000055 0.0000080 0.000028 0.000027 2006 11 11 54050 -0.014033 0.283966 0.0936953 0.0008065 0.000171 0.000069 0.000074 0.000086 0.0000070 0.0000079 0.000029 0.000028 2006 11 12 54051 -0.014794 0.284752 0.0927572 0.0010427 0.000167 0.000066 0.000074 0.000087 0.0000075 0.0000079 0.000029 0.000028 2006 11 13 54052 -0.015761 0.285804 0.0917094 0.0011009 0.000163 0.000064 0.000074 0.000087 0.0000059 0.0000079 0.000029 0.000028 2006 11 14 54053 -0.016828 0.286772 0.0905485 0.0012104 0.000159 0.000061 0.000074 0.000087 0.0000031 0.0000078 0.000029 0.000029 2006 11 15 54054 -0.017800 0.287523 0.0893216 0.0012161 0.000141 0.000092 0.000074 0.000087 0.0000344 0.0000078 0.000029 0.000029 2006 11 16 54055 -0.018528 0.288233 0.0880866 0.0011919 0.000128 0.000102 0.000074 0.000087 0.0000117 0.0000078 0.000029 0.000029 2006 11 17 54056 -0.019707 0.289412 0.0868477 0.0012010 0.000115 0.000020 0.000074 0.000087 0.0000046 0.0000078 0.000029 0.000029 2006 11 18 54057 -0.021264 0.290367 0.0856359 0.0011179 0.000120 0.000014 0.000074 0.000087 0.0000062 0.0000079 0.000029 0.000029 2006 11 19 54058 -0.022709 0.291097 0.0845604 0.0010080 0.000131 0.000047 0.000074 0.000087 0.0000065 0.0000079 0.000029 0.000030 2006 11 20 54059 -0.024160 0.291528 0.0835953 0.0009530 0.000143 0.000080 0.000074 0.000087 0.0000048 0.0000080 0.000029 0.000030 2006 11 21 54060 -0.025791 0.292214 0.0827685 0.0007662 0.000154 0.000113 0.000074 0.000087 0.0000023 0.0000081 0.000029 0.000030 2006 11 22 54061 -0.026830 0.293060 0.0820733 0.0006866 0.000266 0.000037 0.000074 0.000087 0.0000037 0.0000081 0.000030 0.000030 2006 11 23 54062 -0.028106 0.294562 0.0814956 0.0005780 0.000302 0.000003 0.000074 0.000087 0.0000047 0.0000082 0.000030 0.000030 2006 11 24 54063 -0.029651 0.296071 0.0809393 0.0005526 0.000301 -0.000005 0.000074 0.000087 0.0000052 0.0000083 0.000030 0.000031 2006 11 25 54064 -0.031234 0.297579 0.0802923 0.0006989 0.000299 -0.000012 0.000074 0.000087 0.0000057 0.0000084 0.000031 0.000031 2006 11 26 54065 -0.032914 0.299122 0.0794740 0.0009255 0.000298 -0.000020 0.000074 0.000087 0.0000048 0.0000085 0.000031 0.000031 2006 11 27 54066 -0.034546 0.300480 0.0783930 0.0012481 0.000297 -0.000027 0.000074 0.000087 0.0000046 0.0000086 0.000031 0.000031 2006 11 28 54067 -0.035853 0.301473 0.0770158 0.0014572 0.000296 -0.000035 0.000074 0.000087 0.0000052 0.0000087 0.000031 0.000032 2006 11 29 54068 -0.036703 0.302099 0.0753835 0.0016874 0.000195 0.000034 0.000074 0.000088 0.0000053 0.0000089 0.000032 0.000032 2006 11 30 54069 -0.037453 0.303160 0.0736095 0.0018010 0.000117 0.000047 0.000074 0.000088 0.0000119 0.0000091 0.000032 0.000032 2006 12 1 54070 -0.038274 0.304142 0.0718091 0.0017724 0.000076 0.000031 0.000074 0.000088 0.0000083 0.0000093 0.000032 0.000032 2006 12 2 54071 -0.038612 0.305137 0.0700942 0.0015826 0.000071 0.000028 0.000074 0.000088 0.0000055 0.0000095 0.000031 0.000032 2006 12 3 54072 -0.038681 0.306751 0.0687043 0.0012525 0.000075 0.000031 0.000074 0.000088 0.0000047 0.0000098 0.000031 0.000032 2006 12 4 54073 -0.038686 0.308655 0.0676050 0.0009757 0.000079 0.000033 0.000074 0.000088 0.0000038 0.0000100 0.000031 0.000031 2006 12 5 54074 -0.038759 0.310444 0.0667376 0.0008280 0.000084 0.000036 0.000074 0.000088 0.0000027 0.0000103 0.000031 0.000031 2006 12 6 54075 -0.039279 0.312265 0.0660005 0.0006951 0.000132 0.000086 0.000074 0.000088 0.0000046 0.0000106 0.000031 0.000031 2006 12 7 54076 -0.040255 0.314257 0.0653070 0.0007490 0.000100 0.000121 0.000074 0.000088 0.0000025 0.0000109 0.000031 0.000031 2006 12 8 54077 -0.041540 0.316249 0.0644942 0.0008632 0.000080 0.000081 0.000074 0.000088 0.0000054 0.0000112 0.000031 0.000031 2006 12 9 54078 -0.042620 0.317760 0.0635363 0.0010525 0.000083 0.000069 0.000074 0.000088 0.0000081 0.0000115 0.000031 0.000031 2006 12 10 54079 -0.043383 0.318855 0.0624337 0.0012194 0.000091 0.000079 0.000074 0.000087 0.0000050 0.0000117 0.000031 0.000031 2006 12 11 54080 -0.044228 0.319751 0.0611500 0.0013304 0.000098 0.000088 0.000074 0.000087 0.0000040 0.0000120 0.000031 0.000031 2006 12 12 54081 -0.044874 0.320664 0.0597521 0.0014187 0.000106 0.000097 0.000074 0.000087 0.0000030 0.0000123 0.000031 0.000031 2006 12 13 54082 -0.045599 0.322248 0.0583115 0.0014211 0.000314 -0.000039 0.000073 0.000087 0.0000022 0.0000126 0.000031 0.000031 2006 12 14 54083 -0.046638 0.323796 0.0569350 0.0013306 0.000371 -0.000086 0.000073 0.000087 0.0000038 0.0000129 0.000032 0.000031 2006 12 15 54084 -0.047984 0.325200 0.0556448 0.0012319 0.000368 -0.000095 0.000073 0.000087 0.0000062 0.0000132 0.000032 0.000032 2006 12 16 54085 -0.049021 0.326550 0.0544113 0.0011251 0.000339 -0.000070 0.000073 0.000087 0.0000071 0.0000135 0.000032 0.000032 2006 12 17 54086 -0.049618 0.327987 0.0533448 0.0009277 0.000299 -0.000032 0.000073 0.000086 0.0000076 0.0000138 0.000032 0.000032 2006 12 18 54087 -0.050193 0.329524 0.0524968 0.0007536 0.000260 0.000005 0.000072 0.000086 0.0000061 0.0000141 0.000033 0.000032 2006 12 19 54088 -0.050506 0.331048 0.0518373 0.0006512 0.000220 0.000043 0.000072 0.000086 0.0000037 0.0000143 0.000033 0.000033 2006 12 20 54089 -0.051138 0.332254 0.0512331 0.0005543 0.000244 0.000038 0.000072 0.000086 0.0000067 0.0000146 0.000033 0.000033 2006 12 21 54090 -0.051984 0.333169 0.0506879 0.0005047 0.000284 0.000021 0.000072 0.000085 0.0000099 0.0000149 0.000033 0.000033 2006 12 22 54091 -0.052687 0.333523 0.0501859 0.0006005 0.000325 0.000005 0.000072 0.000085 0.0000084 0.0000152 0.000034 0.000034 2006 12 23 54092 -0.052676 0.334104 0.0495079 0.0008191 0.000311 -0.000013 0.000072 0.000085 0.0000081 0.0000155 0.000034 0.000034 2006 12 24 54093 -0.052095 0.335145 0.0485740 0.0011004 0.000277 -0.000032 0.000072 0.000085 0.0000083 0.0000157 0.000034 0.000034 2006 12 25 54094 -0.051278 0.336829 0.0473537 0.0013351 0.000243 -0.000052 0.000071 0.000085 0.0000085 0.0000160 0.000034 0.000034 2006 12 26 54095 -0.050713 0.338643 0.0458791 0.0015324 0.000209 -0.000071 0.000071 0.000085 0.0000087 0.0000162 0.000035 0.000035 2006 12 27 54096 -0.050402 0.340383 0.0442443 0.0016382 0.000175 -0.000090 0.000071 0.000085 0.0000089 0.0000165 0.000035 0.000035 2006 12 28 54097 -0.050300 0.342145 0.0425833 0.0016250 0.000141 -0.000109 0.000071 0.000085 0.0000091 0.0000168 0.000035 0.000035 2006 12 29 54098 -0.049892 0.343852 0.0410174 0.0015052 0.000217 0.000026 0.000071 0.000085 0.0000053 0.0000170 0.000035 0.000035 2006 12 30 54099 -0.049485 0.345504 0.0396270 0.0013444 0.000200 0.000038 0.000071 0.000084 0.0000044 0.0000173 0.000035 0.000035 2006 12 31 54100 -0.049445 0.346471 0.0385024 0.0010595 0.000139 -0.000009 0.000071 0.000084 0.0000049 0.0000175 0.000035 0.000035 2007 1 1 54101 -0.049367 0.347325 0.0376484 0.0007459 0.000077 -0.000057 0.000063 0.000062 0.0000071 0.0000355 0.000042 0.000040 2007 1 2 54102 -0.049899 0.348614 0.0369907 0.0005840 0.000016 -0.000104 0.000063 0.000062 0.0000078 0.0000358 0.000042 0.000040 2007 1 3 54103 -0.051090 0.349944 0.0364176 0.0005216 -0.000045 -0.000152 0.000063 0.000062 0.0000085 0.0000361 0.000042 0.000040 2007 1 4 54104 -0.052994 0.351297 0.0358979 0.0005440 -0.000004 -0.000159 0.000063 0.000062 0.0000074 0.0000363 0.000041 0.000039 2007 1 5 54105 -0.054542 0.352665 0.0352765 0.0007220 0.000063 -0.000156 0.000063 0.000062 0.0000059 0.0000365 0.000041 0.000039 2007 1 6 54106 -0.056058 0.354214 0.0344666 0.0009089 0.000141 -0.000104 0.000063 0.000062 0.0000085 0.0000367 0.000041 0.000038 2007 1 7 54107 -0.056758 0.355518 0.0334679 0.0010650 0.000222 -0.000035 0.000063 0.000062 0.0000127 0.0000368 0.000040 0.000037 2007 1 8 54108 -0.057202 0.357118 0.0323037 0.0011881 0.000303 0.000035 0.000063 0.000062 0.0000161 0.0000369 0.000040 0.000037 2007 1 9 54109 -0.057554 0.359010 0.0310278 0.0013170 0.000384 0.000103 0.000063 0.000062 0.0000158 0.0000370 0.000039 0.000036 2007 1 10 54110 -0.058086 0.361269 0.0297124 0.0013459 0.000251 -0.000149 0.000063 0.000062 0.0000035 0.0000371 0.000039 0.000035 2007 1 11 54111 -0.059064 0.363159 0.0283744 0.0013143 0.000244 -0.000158 0.000063 0.000062 0.0000022 0.0000372 0.000038 0.000035 2007 1 12 54112 -0.059272 0.364648 0.0270906 0.0012358 0.000269 -0.000104 0.000063 0.000062 0.0000037 0.0000373 0.000039 0.000035 2007 1 13 54113 -0.058677 0.366468 0.0258248 0.0011269 0.000280 -0.000117 0.000063 0.000062 0.0000078 0.0000375 0.000039 0.000036 2007 1 14 54114 -0.058374 0.368166 0.0247384 0.0010121 0.000286 -0.000156 0.000063 0.000062 0.0000110 0.0000376 0.000039 0.000036 2007 1 15 54115 -0.058011 0.369740 0.0238229 0.0008796 0.000292 -0.000195 0.000063 0.000062 0.0000090 0.0000378 0.000039 0.000036 2007 1 16 54116 -0.057333 0.371407 0.0230136 0.0008090 0.000299 -0.000234 0.000063 0.000062 0.0000049 0.0000379 0.000039 0.000037 2007 1 17 54117 -0.056958 0.373251 0.0222070 0.0007997 0.000651 -0.000185 0.000063 0.000062 0.0000076 0.0000380 0.000039 0.000037 2007 1 18 54118 -0.056474 0.374949 0.0213645 0.0008890 0.001093 -0.000114 0.000063 0.000062 0.0000110 0.0000381 0.000040 0.000038 2007 1 19 54119 -0.055853 0.377216 0.0204554 0.0010734 0.000622 -0.000069 0.000063 0.000062 0.0000097 0.0000383 0.000040 0.000038 2007 1 20 54120 -0.055650 0.379858 0.0192122 0.0013738 0.000377 -0.000087 0.000063 0.000062 0.0000134 0.0000384 0.000040 0.000038 2007 1 21 54121 -0.055646 0.381719 0.0176583 0.0016887 0.000328 -0.000125 0.000063 0.000062 0.0000153 0.0000385 0.000040 0.000038 2007 1 22 54122 -0.055313 0.383380 0.0158345 0.0019636 0.000280 -0.000163 0.000063 0.000062 0.0000105 0.0000386 0.000039 0.000038 2007 1 23 54123 -0.055089 0.385116 0.0138105 0.0021129 0.000231 -0.000201 0.000063 0.000062 0.0000033 0.0000387 0.000039 0.000037 2007 1 24 54124 -0.054794 0.386978 0.0116718 0.0021005 0.000201 -0.000213 0.000063 0.000062 0.0000024 0.0000387 0.000039 0.000037 2007 1 25 54125 -0.054674 0.388974 0.0096158 0.0019347 0.000177 -0.000219 0.000063 0.000062 0.0000031 0.0000389 0.000039 0.000037 2007 1 26 54126 -0.054364 0.390574 0.0077868 0.0017034 0.000198 -0.000202 0.000063 0.000062 0.0000052 0.0000390 0.000039 0.000037 2007 1 27 54127 -0.053761 0.392276 0.0061898 0.0014406 0.000204 -0.000192 0.000063 0.000062 0.0000106 0.0000392 0.000039 0.000037 2007 1 28 54128 -0.052928 0.393878 0.0048621 0.0011677 0.000200 -0.000188 0.000063 0.000062 0.0000116 0.0000393 0.000039 0.000037 2007 1 29 54129 -0.051854 0.395794 0.0037848 0.0010259 0.000195 -0.000185 0.000063 0.000062 0.0000093 0.0000395 0.000039 0.000037 2007 1 30 54130 -0.050792 0.397818 0.0028249 0.0009821 0.000191 -0.000181 0.000063 0.000062 0.0000067 0.0000396 0.000039 0.000037 2007 1 31 54131 -0.050192 0.399671 0.0018045 0.0010479 0.000177 -0.000178 0.000063 0.000062 0.0000135 0.0000397 0.000039 0.000037 2007 2 1 54132 -0.049827 0.401156 0.0006839 0.0011734 0.000162 -0.000175 0.000063 0.000062 0.0000189 0.0000398 0.000039 0.000037 2007 2 2 54133 -0.049287 0.402243 -0.0005293 0.0013556 0.000147 -0.000173 0.000063 0.000062 0.0000093 0.0000399 0.000039 0.000037 2007 2 3 54134 -0.047794 0.403015 -0.0019714 0.0015232 0.000166 -0.000176 0.000063 0.000062 0.0000092 0.0000400 0.000039 0.000037 2007 2 4 54135 -0.045645 0.404238 -0.0035613 0.0016410 0.000198 -0.000182 0.000063 0.000062 0.0000101 0.0000401 0.000039 0.000037 2007 2 5 54136 -0.043540 0.405812 -0.0052278 0.0016705 0.000230 -0.000187 0.000063 0.000062 0.0000069 0.0000401 0.000039 0.000037 2007 2 6 54137 -0.041200 0.407791 -0.0069263 0.0017066 0.000262 -0.000192 0.000063 0.000062 0.0000022 0.0000402 0.000039 0.000037 2007 2 7 54138 -0.039460 0.410236 -0.0086051 0.0016377 0.000167 -0.000186 0.000063 0.000062 0.0000044 0.0000403 0.000039 0.000037 2007 2 8 54139 -0.038519 0.412672 -0.0102085 0.0015452 0.000140 -0.000153 0.000063 0.000062 0.0000237 0.0000403 0.000040 0.000037 2007 2 9 54140 -0.037759 0.415060 -0.0116637 0.0013590 0.000126 -0.000153 0.000063 0.000062 0.0000118 0.0000404 0.000040 0.000038 2007 2 10 54141 -0.036879 0.416876 -0.0129870 0.0011715 0.000163 -0.000177 0.000063 0.000062 0.0000089 0.0000405 0.000040 0.000038 2007 2 11 54142 -0.036069 0.418512 -0.0141245 0.0010251 0.000222 -0.000204 0.000063 0.000062 0.0000115 0.0000407 0.000040 0.000038 2007 2 12 54143 -0.035047 0.420147 -0.0150490 0.0008919 0.000281 -0.000231 0.000063 0.000062 0.0000090 0.0000408 0.000040 0.000039 2007 2 13 54144 -0.033846 0.421962 -0.0158129 0.0007491 0.000339 -0.000258 0.000063 0.000062 0.0000046 0.0000408 0.000040 0.000039 2007 2 14 54145 -0.032704 0.423563 -0.0165190 0.0007532 0.000410 -0.000272 0.000063 0.000062 0.0000134 0.0000408 0.000040 0.000039 2007 2 15 54146 -0.031474 0.425244 -0.0172769 0.0008367 0.000401 -0.000250 0.000064 0.000062 0.0000205 0.0000409 0.000040 0.000040 2007 2 16 54147 -0.030840 0.426811 -0.0181218 0.0009429 0.000326 -0.000211 0.000064 0.000062 0.0000088 0.0000409 0.000040 0.000039 2007 2 17 54148 -0.030359 0.427883 -0.0191450 0.0011353 0.000284 -0.000259 0.000064 0.000062 0.0000102 0.0000410 0.000040 0.000039 2007 2 18 54149 -0.029493 0.429161 -0.0203976 0.0014023 0.000259 -0.000339 0.000064 0.000062 0.0000177 0.0000411 0.000040 0.000039 2007 2 19 54150 -0.028578 0.430580 -0.0219073 0.0015746 0.000234 -0.000420 0.000064 0.000062 0.0000184 0.0000412 0.000040 0.000039 2007 2 20 54151 -0.027702 0.431906 -0.0235178 0.0015881 0.000209 -0.000501 0.000064 0.000062 0.0000147 0.0000413 0.000040 0.000039 2007 2 21 54152 -0.027070 0.433349 -0.0250133 0.0014004 0.000256 -0.000319 0.000064 0.000062 0.0000056 0.0000415 0.000039 0.000038 2007 2 22 54153 -0.025722 0.434556 -0.0262852 0.0011164 0.000336 -0.000171 0.000064 0.000062 0.0000066 0.0000416 0.000039 0.000038 2007 2 23 54154 -0.023499 0.435982 -0.0272777 0.0008545 0.000356 -0.000111 0.000064 0.000062 0.0000052 0.0000418 0.000039 0.000038 2007 2 24 54155 -0.021354 0.437152 -0.0280710 0.0006183 0.000353 -0.000130 0.000064 0.000062 0.0000064 0.0000420 0.000039 0.000037 2007 2 25 54156 -0.019107 0.438078 -0.0286387 0.0004712 0.000351 -0.000168 0.000064 0.000062 0.0000075 0.0000421 0.000039 0.000037 2007 2 26 54157 -0.017553 0.439274 -0.0290417 0.0004301 0.000348 -0.000205 0.000064 0.000062 0.0000061 0.0000422 0.000039 0.000037 2007 2 27 54158 -0.015927 0.440437 -0.0294302 0.0004464 0.000346 -0.000243 0.000063 0.000062 0.0000038 0.0000423 0.000039 0.000038 2007 2 28 54159 -0.014594 0.442049 -0.0299257 0.0005795 0.000337 -0.000201 0.000063 0.000062 0.0000093 0.0000424 0.000039 0.000038 2007 3 1 54160 -0.013801 0.443704 -0.0305653 0.0007057 0.000327 -0.000139 0.000063 0.000062 0.0000140 0.0000424 0.000039 0.000038 2007 3 2 54161 -0.013122 0.445593 -0.0313037 0.0008496 0.000317 -0.000077 0.000063 0.000062 0.0000077 0.0000425 0.000039 0.000038 2007 3 3 54162 -0.012799 0.447506 -0.0322772 0.0010378 0.000314 -0.000093 0.000063 0.000062 0.0000096 0.0000425 0.000039 0.000038 2007 3 4 54163 -0.012367 0.448832 -0.0333776 0.0011571 0.000313 -0.000137 0.000063 0.000062 0.0000092 0.0000426 0.000039 0.000038 2007 3 5 54164 -0.011611 0.450141 -0.0345640 0.0012391 0.000312 -0.000182 0.000063 0.000062 0.0000062 0.0000427 0.000039 0.000038 2007 3 6 54165 -0.011214 0.451280 -0.0357806 0.0012251 0.000311 -0.000227 0.000063 0.000062 0.0000033 0.0000427 0.000039 0.000038 2007 3 7 54166 -0.010641 0.452331 -0.0369902 0.0011941 0.000269 -0.000130 0.000063 0.000062 0.0000087 0.0000427 0.000039 0.000038 2007 3 8 54167 -0.009897 0.453853 -0.0381787 0.0011539 0.000248 -0.000104 0.000063 0.000062 0.0000115 0.0000428 0.000039 0.000038 2007 3 9 54168 -0.009118 0.455076 -0.0392529 0.0009729 0.000239 -0.000119 0.000063 0.000061 0.0000125 0.0000428 0.000039 0.000038 2007 3 10 54169 -0.008216 0.455975 -0.0401645 0.0007721 0.000230 -0.000135 0.000063 0.000062 0.0000135 0.0000428 0.000039 0.000038 2007 3 11 54170 -0.007367 0.456901 -0.0409049 0.0006535 0.000221 -0.000150 0.000063 0.000062 0.0000143 0.0000427 0.000039 0.000038 2007 3 12 54171 -0.006423 0.457669 -0.0414953 0.0005689 0.000212 -0.000165 0.000063 0.000062 0.0000109 0.0000427 0.000038 0.000038 2007 3 13 54172 -0.005768 0.458702 -0.0420258 0.0005297 0.000203 -0.000180 0.000063 0.000062 0.0000053 0.0000426 0.000038 0.000038 2007 3 14 54173 -0.005342 0.459857 -0.0425985 0.0006258 0.000550 -0.000280 0.000063 0.000062 0.0000084 0.0000425 0.000038 0.000038 2007 3 15 54174 -0.004578 0.460964 -0.0433167 0.0007726 0.000561 -0.000241 0.000063 0.000062 0.0000117 0.0000425 0.000038 0.000038 2007 3 16 54175 -0.002976 0.462120 -0.0442182 0.0010957 0.000435 -0.000152 0.000063 0.000062 0.0000068 0.0000425 0.000038 0.000038 2007 3 17 54176 -0.000921 0.463408 -0.0455666 0.0015173 0.000366 -0.000168 0.000063 0.000062 0.0000088 0.0000424 0.000038 0.000038 2007 3 18 54177 0.001276 0.464641 -0.0473030 0.0018885 0.000318 -0.000225 0.000063 0.000062 0.0000088 0.0000424 0.000038 0.000038 2007 3 19 54178 0.003414 0.466490 -0.0493108 0.0020515 0.000270 -0.000282 0.000063 0.000062 0.0000059 0.0000423 0.000038 0.000038 2007 3 20 54179 0.005162 0.468969 -0.0513869 0.0021028 0.000222 -0.000338 0.000063 0.000062 0.0000028 0.0000421 0.000038 0.000037 2007 3 21 54180 0.006455 0.470764 -0.0534175 0.0018981 0.000237 -0.000275 0.000063 0.000062 0.0000057 0.0000420 0.000038 0.000037 2007 3 22 54181 0.006905 0.471715 -0.0551496 0.0015037 0.000269 -0.000181 0.000063 0.000063 0.0000088 0.0000418 0.000038 0.000037 2007 3 23 54182 0.007349 0.472338 -0.0564136 0.0010747 0.000301 -0.000086 0.000064 0.000063 0.0000066 0.0000416 0.000038 0.000037 2007 3 24 54183 0.008195 0.472972 -0.0573825 0.0008078 0.000303 -0.000087 0.000064 0.000063 0.0000128 0.0000413 0.000038 0.000037 2007 3 25 54184 0.009474 0.473496 -0.0581705 0.0006945 0.000295 -0.000123 0.000064 0.000063 0.0000173 0.0000410 0.000038 0.000036 2007 3 26 54185 0.010663 0.474043 -0.0588471 0.0007051 0.000287 -0.000158 0.000064 0.000063 0.0000126 0.0000407 0.000038 0.000036 2007 3 27 54186 0.011628 0.474833 -0.0595476 0.0007772 0.000278 -0.000194 0.000064 0.000063 0.0000045 0.0000403 0.000038 0.000036 2007 3 28 54187 0.013419 0.475549 -0.0604038 0.0009546 0.000287 -0.000212 0.000064 0.000063 0.0000027 0.0000400 0.000038 0.000036 2007 3 29 54188 0.015696 0.476246 -0.0614362 0.0011326 0.000282 -0.000222 0.000064 0.000063 0.0000025 0.0000397 0.000038 0.000036 2007 3 30 54189 0.018180 0.477106 -0.0626422 0.0013038 0.000326 -0.000311 0.000064 0.000063 0.0000059 0.0000394 0.000038 0.000036 2007 3 31 54190 0.020400 0.478073 -0.0639927 0.0013436 0.000333 -0.000328 0.000064 0.000063 0.0000091 0.0000391 0.000038 0.000036 2007 4 1 54191 0.022607 0.478806 -0.0654044 0.0014774 0.000321 -0.000309 0.000064 0.000063 0.0000119 0.0000388 0.000038 0.000036 2007 4 2 54192 0.025179 0.479621 -0.0669079 0.0015466 0.000309 -0.000290 0.000064 0.000063 0.0000090 0.0000384 0.000038 0.000036 2007 4 3 54193 0.027931 0.480688 -0.0684452 0.0015891 0.000296 -0.000270 0.000064 0.000063 0.0000034 0.0000381 0.000038 0.000037 2007 4 4 54194 0.030665 0.482064 -0.0699714 0.0015174 0.000275 -0.000282 0.000064 0.000063 0.0000035 0.0000379 0.000038 0.000037 2007 4 5 54195 0.033194 0.483144 -0.0714163 0.0013920 0.000250 -0.000302 0.000064 0.000063 0.0000050 0.0000376 0.000038 0.000038 2007 4 6 54196 0.035736 0.484204 -0.0728009 0.0012748 0.000254 -0.000309 0.000064 0.000063 0.0000057 0.0000373 0.000038 0.000038 2007 4 7 54197 0.038138 0.485192 -0.0740905 0.0012008 0.000267 -0.000313 0.000064 0.000063 0.0000061 0.0000371 0.000039 0.000038 2007 4 8 54198 0.040128 0.485971 -0.0753123 0.0012231 0.000281 -0.000316 0.000064 0.000063 0.0000092 0.0000368 0.000039 0.000038 2007 4 9 54199 0.041475 0.486688 -0.0764655 0.0011952 0.000295 -0.000320 0.000064 0.000063 0.0000087 0.0000366 0.000039 0.000039 2007 4 10 54200 0.042573 0.487341 -0.0776229 0.0011984 0.000309 -0.000323 0.000064 0.000063 0.0000059 0.0000364 0.000039 0.000039 2007 4 11 54201 0.044022 0.487755 -0.0788883 0.0012912 0.000322 -0.000327 0.000064 0.000063 0.0000030 0.0000361 0.000039 0.000040 2007 4 12 54202 0.045503 0.488426 -0.0802463 0.0014612 0.000479 -0.000307 0.000064 0.000063 0.0000039 0.0000359 0.000040 0.000040 2007 4 13 54203 0.046946 0.488832 -0.0818513 0.0017200 0.000286 -0.000218 0.000064 0.000063 0.0000058 0.0000358 0.000040 0.000040 2007 4 14 54204 0.048715 0.489214 -0.0837833 0.0020342 0.000226 -0.000199 0.000064 0.000063 0.0000087 0.0000357 0.000040 0.000040 2007 4 15 54205 0.050399 0.489650 -0.0859190 0.0022145 0.000259 -0.000213 0.000064 0.000063 0.0000091 0.0000356 0.000040 0.000040 2007 4 16 54206 0.052275 0.490088 -0.0882186 0.0023325 0.000292 -0.000227 0.000064 0.000063 0.0000100 0.0000355 0.000040 0.000040 2007 4 17 54207 0.054315 0.490414 -0.0904692 0.0021695 0.000325 -0.000241 0.000064 0.000063 0.0000102 0.0000354 0.000040 0.000040 2007 4 18 54208 0.056345 0.490379 -0.0924425 0.0018521 0.000175 -0.000303 0.000064 0.000063 0.0000046 0.0000353 0.000040 0.000040 2007 4 19 54209 0.058178 0.490300 -0.0940604 0.0014395 0.000183 -0.000307 0.000064 0.000063 0.0000040 0.0000352 0.000040 0.000040 2007 4 20 54210 0.059788 0.490368 -0.0953107 0.0010358 0.000236 -0.000294 0.000064 0.000063 0.0000047 0.0000351 0.000040 0.000040 2007 4 21 54211 0.061253 0.490373 -0.0962896 0.0008414 0.000250 -0.000282 0.000064 0.000063 0.0000068 0.0000350 0.000039 0.000040 2007 4 22 54212 0.062594 0.490344 -0.0970979 0.0007923 0.000249 -0.000269 0.000064 0.000063 0.0000116 0.0000349 0.000040 0.000040 2007 4 23 54213 0.063772 0.490401 -0.0978969 0.0008535 0.000249 -0.000256 0.000064 0.000063 0.0000100 0.0000348 0.000040 0.000040 2007 4 24 54214 0.065241 0.490413 -0.0988008 0.0009490 0.000248 -0.000243 0.000064 0.000063 0.0000044 0.0000348 0.000040 0.000040 2007 4 25 54215 0.066836 0.490393 -0.0998248 0.0010819 0.000238 -0.000286 0.000064 0.000063 0.0000037 0.0000347 0.000040 0.000040 2007 4 26 54216 0.068883 0.490529 -0.1009998 0.0012619 0.000225 -0.000344 0.000064 0.000063 0.0000041 0.0000347 0.000040 0.000041 2007 4 27 54217 0.071019 0.490963 -0.1023279 0.0014169 0.000273 -0.000326 0.000064 0.000063 0.0000050 0.0000347 0.000040 0.000041 2007 4 28 54218 0.073101 0.491215 -0.1038000 0.0014682 0.000289 -0.000306 0.000064 0.000063 0.0000094 0.0000348 0.000040 0.000041 2007 4 29 54219 0.075211 0.491217 -0.1052855 0.0014896 0.000284 -0.000294 0.000064 0.000062 0.0000106 0.0000348 0.000041 0.000042 2007 4 30 54220 0.077192 0.491135 -0.1067365 0.0014573 0.000280 -0.000281 0.000064 0.000062 0.0000106 0.0000348 0.000041 0.000042 2007 5 1 54221 0.079115 0.491066 -0.1081044 0.0013428 0.000276 -0.000269 0.000064 0.000062 0.0000120 0.0000348 0.000041 0.000042 2007 5 2 54222 0.080842 0.490943 -0.1093330 0.0011654 0.000272 -0.000256 0.000064 0.000062 0.0000171 0.0000349 0.000041 0.000043 2007 5 3 54223 0.082712 0.490528 -0.1103971 0.0010181 0.000268 -0.000244 0.000064 0.000062 0.0000221 0.0000349 0.000042 0.000043 2007 5 4 54224 0.085073 0.489882 -0.1113401 0.0009096 0.000352 -0.000392 0.000064 0.000062 0.0000095 0.0000349 0.000042 0.000043 2007 5 5 54225 0.087402 0.489221 -0.1121784 0.0007682 0.000365 -0.000430 0.000064 0.000062 0.0000082 0.0000350 0.000042 0.000043 2007 5 6 54226 0.089597 0.488246 -0.1129025 0.0006615 0.000342 -0.000412 0.000064 0.000062 0.0000111 0.0000350 0.000042 0.000043 2007 5 7 54227 0.091628 0.487270 -0.1135341 0.0006311 0.000319 -0.000394 0.000064 0.000062 0.0000092 0.0000350 0.000042 0.000043 2007 5 8 54228 0.093637 0.486485 -0.1142264 0.0007799 0.000297 -0.000376 0.000064 0.000062 0.0000053 0.0000350 0.000042 0.000043 2007 5 9 54229 0.095424 0.485848 -0.1151525 0.0010230 0.000280 -0.000339 0.000064 0.000062 0.0000096 0.0000349 0.000042 0.000043 2007 5 10 54230 0.097391 0.484943 -0.1163533 0.0013347 0.000265 -0.000297 0.000064 0.000063 0.0000135 0.0000349 0.000042 0.000043 2007 5 11 54231 0.099612 0.484401 -0.1178260 0.0016406 0.000250 -0.000255 0.000064 0.000063 0.0000074 0.0000349 0.000042 0.000043 2007 5 12 54232 0.101449 0.483891 -0.1196972 0.0019929 0.000225 -0.000257 0.000064 0.000063 0.0000120 0.0000348 0.000042 0.000043 2007 5 13 54233 0.103857 0.483201 -0.1218424 0.0022356 0.000198 -0.000275 0.000064 0.000063 0.0000112 0.0000348 0.000042 0.000043 2007 5 14 54234 0.106478 0.482464 -0.1240416 0.0021997 0.000170 -0.000293 0.000064 0.000063 0.0000081 0.0000347 0.000042 0.000043 2007 5 15 54235 0.109477 0.481651 -0.1261050 0.0019641 0.000142 -0.000311 0.000064 0.000063 0.0000061 0.0000346 0.000042 0.000043 2007 5 16 54236 0.112320 0.480858 -0.1278719 0.0015787 0.000214 -0.000428 0.000065 0.000064 0.0000041 0.0000345 0.000042 0.000043 2007 5 17 54237 0.114893 0.479933 -0.1292652 0.0012267 0.000147 -0.000473 0.000065 0.000064 0.0000046 0.0000344 0.000042 0.000043 2007 5 18 54238 0.117165 0.479057 -0.1303398 0.0009452 0.000032 -0.000490 0.000065 0.000064 0.0000058 0.0000342 0.000043 0.000044 2007 5 19 54239 0.119146 0.477973 -0.1312253 0.0008777 0.000028 -0.000471 0.000065 0.000064 0.0000147 0.0000341 0.000043 0.000044 2007 5 20 54240 0.120903 0.476875 -0.1321251 0.0008903 0.000066 -0.000439 0.000065 0.000064 0.0000158 0.0000340 0.000043 0.000044 2007 5 21 54241 0.122415 0.475475 -0.1329974 0.0008889 0.000105 -0.000407 0.000065 0.000064 0.0000106 0.0000339 0.000043 0.000044 2007 5 22 54242 0.124314 0.473942 -0.1339315 0.0009319 0.000143 -0.000376 0.000065 0.000064 0.0000048 0.0000338 0.000043 0.000044 2007 5 23 54243 0.126707 0.473067 -0.1349489 0.0010441 0.000389 -0.000302 0.000065 0.000064 0.0000070 0.0000337 0.000043 0.000044 2007 5 24 54244 0.129005 0.472708 -0.1360808 0.0012072 0.000364 -0.000219 0.000065 0.000064 0.0000096 0.0000337 0.000043 0.000044 2007 5 25 54245 0.131415 0.471893 -0.1373430 0.0013254 0.000243 -0.000136 0.000065 0.000064 0.0000062 0.0000338 0.000043 0.000044 2007 5 26 54246 0.133763 0.471020 -0.1386618 0.0012877 0.000263 -0.000207 0.000065 0.000064 0.0000090 0.0000340 0.000043 0.000044 2007 5 27 54247 0.135546 0.470207 -0.1399097 0.0011814 0.000335 -0.000335 0.000065 0.000064 0.0000162 0.0000341 0.000043 0.000043 2007 5 28 54248 0.137170 0.468940 -0.1410492 0.0010965 0.000408 -0.000463 0.000065 0.000064 0.0000155 0.0000342 0.000044 0.000043 2007 5 29 54249 0.138784 0.467432 -0.1420393 0.0009451 0.000480 -0.000591 0.000065 0.000064 0.0000103 0.0000343 0.000044 0.000043 2007 5 30 54250 0.140714 0.465690 -0.1428378 0.0007497 0.000220 -0.000397 0.000065 0.000064 0.0000051 0.0000344 0.000044 0.000042 2007 5 31 54251 0.143439 0.463777 -0.1434733 0.0005888 0.000188 -0.000332 0.000065 0.000064 0.0000048 0.0000345 0.000044 0.000042 2007 6 1 54252 0.146350 0.462137 -0.1439372 0.0003365 0.000235 -0.000320 0.000065 0.000064 0.0000058 0.0000346 0.000044 0.000042 2007 6 2 54253 0.149224 0.460433 -0.1442499 0.0002055 0.000225 -0.000332 0.000065 0.000064 0.0000126 0.0000347 0.000044 0.000042 2007 6 3 54254 0.151605 0.458950 -0.1444176 0.0001580 0.000195 -0.000352 0.000065 0.000064 0.0000116 0.0000348 0.000044 0.000042 2007 6 4 54255 0.153875 0.457259 -0.1446164 0.0002347 0.000165 -0.000372 0.000065 0.000064 0.0000070 0.0000349 0.000044 0.000041 2007 6 5 54256 0.156432 0.455884 -0.1449515 0.0004372 0.000135 -0.000393 0.000065 0.000064 0.0000030 0.0000350 0.000044 0.000041 2007 6 6 54257 0.158828 0.454678 -0.1455135 0.0006548 0.000141 -0.000367 0.000065 0.000064 0.0000090 0.0000351 0.000044 0.000042 2007 6 7 54258 0.160598 0.453129 -0.1462986 0.0008501 0.000156 -0.000329 0.000065 0.000063 0.0000150 0.0000352 0.000044 0.000042 2007 6 8 54259 0.162407 0.451447 -0.1472425 0.0009977 0.000172 -0.000291 0.000065 0.000063 0.0000111 0.0000353 0.000044 0.000043 2007 6 9 54260 0.164423 0.449953 -0.1483605 0.0011090 0.000155 -0.000300 0.000065 0.000063 0.0000118 0.0000353 0.000044 0.000043 2007 6 10 54261 0.166772 0.448637 -0.1494979 0.0011512 0.000126 -0.000327 0.000064 0.000063 0.0000101 0.0000354 0.000044 0.000044 2007 6 11 54262 0.169210 0.447221 -0.1505814 0.0010612 0.000097 -0.000355 0.000064 0.000063 0.0000069 0.0000354 0.000044 0.000044 2007 6 12 54263 0.171378 0.445462 -0.1514651 0.0007976 0.000068 -0.000382 0.000064 0.000063 0.0000038 0.0000354 0.000044 0.000044 2007 6 13 54264 0.173381 0.443208 -0.1520649 0.0004536 0.000256 -0.000424 0.000064 0.000063 0.0000101 0.0000355 0.000044 0.000044 2007 6 14 54265 0.175085 0.441177 -0.1523535 0.0001491 0.000220 -0.000340 0.000064 0.000063 0.0000161 0.0000355 0.000045 0.000045 2007 6 15 54266 0.176593 0.439045 -0.1523610 -0.0000296 0.000101 -0.000217 0.000064 0.000062 0.0000117 0.0000356 0.000045 0.000045 2007 6 16 54267 0.178312 0.437126 -0.1523195 -0.0000378 0.000092 -0.000223 0.000064 0.000062 0.0000108 0.0000357 0.000045 0.000045 2007 6 17 54268 0.180230 0.435256 -0.1523446 0.0000966 0.000124 -0.000276 0.000064 0.000062 0.0000102 0.0000358 0.000044 0.000044 2007 6 18 54269 0.182478 0.433578 -0.1525133 0.0002454 0.000156 -0.000330 0.000064 0.000062 0.0000079 0.0000358 0.000044 0.000044 2007 6 19 54270 0.184778 0.431904 -0.1528706 0.0004407 0.000188 -0.000383 0.000064 0.000062 0.0000051 0.0000359 0.000044 0.000044 2007 6 20 54271 0.187171 0.430677 -0.1534492 0.0006166 0.000180 -0.000367 0.000064 0.000062 0.0000067 0.0000360 0.000044 0.000044 2007 6 21 54272 0.189368 0.429275 -0.1541547 0.0007566 0.000163 -0.000331 0.000064 0.000062 0.0000085 0.0000361 0.000044 0.000044 2007 6 22 54273 0.191580 0.427212 -0.1548764 0.0007458 0.000145 -0.000296 0.000064 0.000062 0.0000067 0.0000362 0.000044 0.000044 2007 6 23 54274 0.193620 0.424838 -0.1556110 0.0007095 0.000127 -0.000298 0.000064 0.000062 0.0000070 0.0000364 0.000044 0.000044 2007 6 24 54275 0.195654 0.422806 -0.1562444 0.0005847 0.000108 -0.000313 0.000064 0.000062 0.0000078 0.0000366 0.000044 0.000043 2007 6 25 54276 0.197949 0.420727 -0.1567500 0.0004766 0.000090 -0.000328 0.000064 0.000062 0.0000064 0.0000367 0.000043 0.000043 2007 6 26 54277 0.200755 0.419105 -0.1571083 0.0003414 0.000071 -0.000343 0.000064 0.000062 0.0000039 0.0000369 0.000043 0.000043 2007 6 27 54278 0.203349 0.417726 -0.1573357 0.0001531 0.000148 -0.000380 0.000064 0.000062 0.0000056 0.0000370 0.000043 0.000043 2007 6 28 54279 0.205283 0.416372 -0.1574249 0.0000532 0.000178 -0.000347 0.000064 0.000062 0.0000070 0.0000371 0.000044 0.000043 2007 6 29 54280 0.206793 0.414859 -0.1574153 -0.0000259 0.000223 -0.000359 0.000064 0.000062 0.0000131 0.0000372 0.000044 0.000044 2007 6 30 54281 0.207974 0.413336 -0.1574021 -0.0000623 0.000199 -0.000390 0.000064 0.000062 0.0000122 0.0000372 0.000044 0.000044 2007 7 1 54282 0.208668 0.411661 -0.1573684 0.0000095 0.000145 -0.000418 0.000064 0.000062 0.0000116 0.0000373 0.000044 0.000044 2007 7 2 54283 0.209113 0.409542 -0.1574498 0.0001552 0.000091 -0.000446 0.000064 0.000062 0.0000091 0.0000374 0.000044 0.000044 2007 7 3 54284 0.209735 0.407199 -0.1577473 0.0004243 0.000037 -0.000475 0.000064 0.000062 0.0000049 0.0000374 0.000044 0.000044 2007 7 4 54285 0.210675 0.405063 -0.1582846 0.0006615 -0.000007 -0.000619 0.000064 0.000062 0.0000067 0.0000374 0.000044 0.000044 2007 7 5 54286 0.211760 0.403047 -0.1590504 0.0008283 0.000064 -0.000587 0.000064 0.000062 0.0000101 0.0000374 0.000044 0.000044 2007 7 6 54287 0.213098 0.400833 -0.1599753 0.0009282 0.000166 -0.000495 0.000064 0.000062 0.0000135 0.0000374 0.000045 0.000044 2007 7 7 54288 0.214370 0.398635 -0.1609788 0.0009464 0.000157 -0.000444 0.000064 0.000062 0.0000126 0.0000374 0.000044 0.000044 2007 7 8 54289 0.215139 0.396268 -0.1618556 0.0007418 0.000102 -0.000410 0.000064 0.000062 0.0000103 0.0000373 0.000044 0.000043 2007 7 9 54290 0.215804 0.393709 -0.1624716 0.0005148 0.000047 -0.000377 0.000064 0.000061 0.0000080 0.0000373 0.000044 0.000043 2007 7 10 54291 0.216652 0.391029 -0.1627865 0.0002194 -0.000009 -0.000343 0.000064 0.000062 0.0000056 0.0000373 0.000044 0.000042 2007 7 11 54292 0.217686 0.388233 -0.1628580 -0.0000141 0.000026 -0.000508 0.000064 0.000062 0.0000087 0.0000372 0.000044 0.000042 2007 7 12 54293 0.218420 0.385711 -0.1627246 -0.0001815 0.000065 -0.000487 0.000063 0.000061 0.0000111 0.0000372 0.000044 0.000042 2007 7 13 54294 0.219450 0.383096 -0.1624691 -0.0002929 0.000098 -0.000396 0.000063 0.000061 0.0000128 0.0000371 0.000045 0.000042 2007 7 14 54295 0.220736 0.380456 -0.1622077 -0.0002395 0.000085 -0.000390 0.000063 0.000061 0.0000104 0.0000371 0.000045 0.000042 2007 7 15 54296 0.221997 0.377814 -0.1620338 -0.0000701 0.000055 -0.000417 0.000063 0.000061 0.0000100 0.0000371 0.000045 0.000042 2007 7 16 54297 0.223148 0.375366 -0.1620111 0.0000303 0.000025 -0.000444 0.000063 0.000061 0.0000092 0.0000371 0.000045 0.000042 2007 7 17 54298 0.224539 0.372922 -0.1621606 0.0002290 -0.000005 -0.000470 0.000063 0.000061 0.0000074 0.0000371 0.000045 0.000042 2007 7 18 54299 0.225900 0.370458 -0.1625008 0.0003413 0.000003 -0.000438 0.000063 0.000061 0.0000106 0.0000372 0.000045 0.000042 2007 7 19 54300 0.227100 0.367984 -0.1629094 0.0004137 0.000020 -0.000390 0.000063 0.000061 0.0000134 0.0000372 0.000045 0.000042 2007 7 20 54301 0.227879 0.365404 -0.1632630 0.0003368 0.000037 -0.000343 0.000063 0.000061 0.0000100 0.0000373 0.000045 0.000042 2007 7 21 54302 0.228531 0.362522 -0.1635753 0.0002277 0.000040 -0.000365 0.000063 0.000061 0.0000086 0.0000374 0.000045 0.000042 2007 7 22 54303 0.229118 0.359673 -0.1637561 0.0000953 0.000038 -0.000414 0.000063 0.000061 0.0000101 0.0000375 0.000045 0.000042 2007 7 23 54304 0.229704 0.356926 -0.1637345 -0.0000771 0.000036 -0.000463 0.000063 0.000062 0.0000106 0.0000376 0.000045 0.000041 2007 7 24 54305 0.230154 0.355032 -0.1635142 -0.0002651 0.000033 -0.000512 0.000064 0.000062 0.0000100 0.0000376 0.000045 0.000041 2007 7 25 54306 0.230274 0.352885 -0.1631334 -0.0004744 -0.000041 0.000008 0.000064 0.000062 0.0000109 0.0000377 0.000045 0.000041 2007 7 26 54307 0.230297 0.350623 -0.1626059 -0.0005776 0.000030 -0.000013 0.000064 0.000062 0.0000114 0.0000377 0.000045 0.000041 2007 7 27 54308 0.230129 0.348462 -0.1619548 -0.0006192 0.000150 -0.000242 0.000064 0.000062 0.0000090 0.0000377 0.000045 0.000040 2007 7 28 54309 0.229164 0.345834 -0.1613735 -0.0005256 0.000148 -0.000319 0.000064 0.000062 0.0000088 0.0000378 0.000045 0.000040 2007 7 29 54310 0.228540 0.342872 -0.1609575 -0.0003276 0.000101 -0.000340 0.000064 0.000062 0.0000104 0.0000378 0.000044 0.000040 2007 7 30 54311 0.228151 0.339963 -0.1607463 -0.0001011 0.000054 -0.000361 0.000064 0.000062 0.0000102 0.0000379 0.000044 0.000039 2007 7 31 54312 0.227615 0.337040 -0.1608168 0.0002001 0.000007 -0.000381 0.000064 0.000062 0.0000088 0.0000379 0.000044 0.000039 2007 8 1 54313 0.227061 0.334128 -0.1611945 0.0004507 0.000005 -0.000298 0.000064 0.000062 0.0000064 0.0000379 0.000044 0.000039 2007 8 2 54314 0.226635 0.331455 -0.1618236 0.0006797 -0.000032 -0.000298 0.000064 0.000062 0.0000056 0.0000379 0.000043 0.000039 2007 8 3 54315 0.226338 0.329108 -0.1626077 0.0008086 -0.000104 -0.000361 0.000064 0.000062 0.0000087 0.0000380 0.000044 0.000039 2007 8 4 54316 0.226013 0.326453 -0.1633706 0.0006687 -0.000111 -0.000374 0.000064 0.000062 0.0000115 0.0000380 0.000044 0.000039 2007 8 5 54317 0.225415 0.323576 -0.1639937 0.0004989 -0.000090 -0.000363 0.000064 0.000062 0.0000147 0.0000380 0.000044 0.000039 2007 8 6 54318 0.224181 0.320873 -0.1643302 0.0002504 -0.000070 -0.000353 0.000064 0.000062 0.0000119 0.0000381 0.000044 0.000039 2007 8 7 54319 0.222866 0.318460 -0.1643551 -0.0000682 -0.000049 -0.000343 0.000064 0.000062 0.0000061 0.0000382 0.000044 0.000039 2007 8 8 54320 0.221457 0.316022 -0.1641427 -0.0002802 0.000044 -0.000279 0.000064 0.000062 0.0000114 0.0000384 0.000044 0.000039 2007 8 9 54321 0.219664 0.313356 -0.1637637 -0.0004375 0.000156 -0.000202 0.000064 0.000062 0.0000172 0.0000385 0.000044 0.000039 2007 8 10 54322 0.218056 0.310845 -0.1632862 -0.0004340 0.000109 -0.000350 0.000064 0.000062 0.0000137 0.0000387 0.000044 0.000039 2007 8 11 54323 0.217228 0.308176 -0.1629278 -0.0003548 0.000062 -0.000380 0.000064 0.000062 0.0000107 0.0000389 0.000044 0.000039 2007 8 12 54324 0.216890 0.305650 -0.1627644 -0.0000745 0.000035 -0.000339 0.000064 0.000062 0.0000099 0.0000391 0.000044 0.000039 2007 8 13 54325 0.216692 0.303226 -0.1627514 0.0000266 0.000009 -0.000298 0.000064 0.000062 0.0000094 0.0000392 0.000044 0.000039 2007 8 14 54326 0.216314 0.300986 -0.1628854 0.0001739 -0.000018 -0.000257 0.000064 0.000062 0.0000086 0.0000394 0.000043 0.000039 2007 8 15 54327 0.215459 0.299003 -0.1631466 0.0002437 -0.000045 -0.000250 0.000064 0.000062 0.0000106 0.0000396 0.000043 0.000039 2007 8 16 54328 0.214197 0.297383 -0.1634394 0.0002629 -0.000072 -0.000252 0.000064 0.000062 0.0000122 0.0000398 0.000043 0.000039 2007 8 17 54329 0.212692 0.295508 -0.1636450 0.0002082 -0.000099 -0.000254 0.000064 0.000062 0.0000090 0.0000400 0.000043 0.000038 2007 8 18 54330 0.211494 0.292801 -0.1638834 0.0002163 -0.000094 -0.000259 0.000064 0.000062 0.0000086 0.0000402 0.000043 0.000038 2007 8 19 54331 0.210859 0.289895 -0.1640198 0.0001053 -0.000078 -0.000264 0.000064 0.000062 0.0000110 0.0000404 0.000042 0.000038 2007 8 20 54332 0.210413 0.286847 -0.1640143 -0.0000370 -0.000062 -0.000270 0.000064 0.000062 0.0000089 0.0000406 0.000042 0.000037 2007 8 21 54333 0.210335 0.284153 -0.1638574 -0.0001763 -0.000045 -0.000275 0.000064 0.000062 0.0000040 0.0000408 0.000042 0.000037 2007 8 22 54334 0.209721 0.281994 -0.1635593 -0.0003454 -0.000060 -0.000297 0.000064 0.000062 0.0000089 0.0000409 0.000042 0.000037 2007 8 23 54335 0.208459 0.279622 -0.1631436 -0.0004477 -0.000083 -0.000322 0.000064 0.000062 0.0000141 0.0000410 0.000041 0.000037 2007 8 24 54336 0.206645 0.277321 -0.1626079 -0.0005193 -0.000106 -0.000348 0.000064 0.000062 0.0000106 0.0000411 0.000041 0.000037 2007 8 25 54337 0.204736 0.274897 -0.1621923 -0.0003692 -0.000098 -0.000352 0.000064 0.000062 0.0000115 0.0000412 0.000041 0.000037 2007 8 26 54338 0.202977 0.272484 -0.1619264 -0.0001297 -0.000080 -0.000349 0.000064 0.000062 0.0000162 0.0000412 0.000041 0.000037 2007 8 27 54339 0.201781 0.270254 -0.1619020 0.0001593 -0.000061 -0.000346 0.000064 0.000062 0.0000122 0.0000412 0.000041 0.000037 2007 8 28 54340 0.200958 0.268510 -0.1622047 0.0004347 -0.000042 -0.000342 0.000064 0.000062 0.0000033 0.0000412 0.000041 0.000036 2007 8 29 54341 0.200088 0.266958 -0.1628668 0.0007308 -0.000068 -0.000322 0.000064 0.000062 0.0000084 0.0000411 0.000041 0.000037 2007 8 30 54342 0.199417 0.265458 -0.1637566 0.0009316 -0.000106 -0.000298 0.000064 0.000062 0.0000145 0.0000411 0.000041 0.000037 2007 8 31 54343 0.198713 0.263827 -0.1647060 0.0009780 -0.000144 -0.000274 0.000064 0.000062 0.0000104 0.0000411 0.000041 0.000037 2007 9 1 54344 0.197955 0.261826 -0.1656545 0.0008561 -0.000160 -0.000254 0.000065 0.000062 0.0000120 0.0000410 0.000041 0.000037 2007 9 2 54345 0.196759 0.259815 -0.1664218 0.0006313 -0.000169 -0.000236 0.000065 0.000062 0.0000112 0.0000409 0.000041 0.000037 2007 9 3 54346 0.195382 0.257709 -0.1668889 0.0004008 -0.000178 -0.000218 0.000065 0.000062 0.0000064 0.0000409 0.000041 0.000037 2007 9 4 54347 0.194077 0.255856 -0.1671013 0.0001388 -0.000186 -0.000201 0.000065 0.000063 0.0000037 0.0000407 0.000040 0.000037 2007 9 5 54348 0.192673 0.253720 -0.1671773 0.0000444 -0.000109 -0.000243 0.000065 0.000063 0.0000024 0.0000406 0.000040 0.000037 2007 9 6 54349 0.190664 0.251813 -0.1672148 0.0000693 -0.000061 -0.000222 0.000065 0.000063 0.0000046 0.0000405 0.000040 0.000037 2007 9 7 54350 0.188447 0.249631 -0.1673456 0.0001991 -0.000022 -0.000185 0.000065 0.000063 0.0000077 0.0000404 0.000040 0.000037 2007 9 8 54351 0.186883 0.247609 -0.1676447 0.0004090 -0.000015 -0.000191 0.000065 0.000063 0.0000113 0.0000402 0.000040 0.000037 2007 9 9 54352 0.185555 0.245968 -0.1681826 0.0006030 -0.000020 -0.000214 0.000065 0.000063 0.0000113 0.0000401 0.000040 0.000037 2007 9 10 54353 0.184348 0.244392 -0.1688780 0.0007393 -0.000026 -0.000237 0.000065 0.000063 0.0000078 0.0000399 0.000039 0.000036 2007 9 11 54354 0.182891 0.242582 -0.1696973 0.0008476 -0.000031 -0.000260 0.000065 0.000063 0.0000036 0.0000398 0.000039 0.000036 2007 9 12 54355 0.181075 0.240495 -0.1706233 0.0008838 0.000017 -0.000254 0.000065 0.000063 0.0000035 0.0000396 0.000039 0.000036 2007 9 13 54356 0.179320 0.238399 -0.1715595 0.0009126 -0.000038 -0.000184 0.000065 0.000063 0.0000045 0.0000394 0.000039 0.000037 2007 9 14 54357 0.177430 0.236321 -0.1724436 0.0008272 -0.000115 -0.000102 0.000065 0.000063 0.0000061 0.0000393 0.000040 0.000037 2007 9 15 54358 0.175241 0.234149 -0.1732566 0.0007228 -0.000140 -0.000092 0.000065 0.000063 0.0000135 0.0000391 0.000040 0.000037 2007 9 16 54359 0.172395 0.232226 -0.1738962 0.0005375 -0.000147 -0.000108 0.000065 0.000063 0.0000139 0.0000389 0.000040 0.000037 2007 9 17 54360 0.169641 0.230162 -0.1743688 0.0004382 -0.000154 -0.000125 0.000065 0.000063 0.0000094 0.0000388 0.000040 0.000037 2007 9 18 54361 0.167244 0.228493 -0.1747109 0.0003169 -0.000162 -0.000141 0.000065 0.000063 0.0000049 0.0000386 0.000040 0.000037 2007 9 19 54362 0.165225 0.226569 -0.1749658 0.0002531 -0.000279 0.000143 0.000065 0.000063 0.0000112 0.0000384 0.000040 0.000037 2007 9 20 54363 0.163218 0.224729 -0.1751967 0.0003050 -0.000178 0.000070 0.000065 0.000063 0.0000166 0.0000383 0.000040 0.000037 2007 9 21 54364 0.160595 0.222888 -0.1754816 0.0003664 -0.000004 -0.000132 0.000065 0.000063 0.0000078 0.0000381 0.000040 0.000037 2007 9 22 54365 0.157626 0.220999 -0.1759403 0.0005521 0.000031 -0.000196 0.000065 0.000064 0.0000115 0.0000380 0.000040 0.000037 2007 9 23 54366 0.154794 0.219552 -0.1766291 0.0008140 0.000015 -0.000208 0.000065 0.000064 0.0000120 0.0000379 0.000040 0.000037 2007 9 24 54367 0.151695 0.217959 -0.1775619 0.0010378 -0.000001 -0.000220 0.000065 0.000064 0.0000087 0.0000378 0.000040 0.000037 2007 9 25 54368 0.149027 0.216225 -0.1787945 0.0013899 -0.000018 -0.000232 0.000065 0.000064 0.0000054 0.0000377 0.000040 0.000037 2007 9 26 54369 0.146558 0.214822 -0.1804262 0.0016768 -0.000067 -0.000215 0.000065 0.000064 0.0000129 0.0000376 0.000040 0.000037 2007 9 27 54370 0.144040 0.212929 -0.1821841 0.0017024 -0.000124 -0.000190 0.000065 0.000064 0.0000189 0.0000374 0.000040 0.000037 2007 9 28 54371 0.141604 0.211073 -0.1837614 0.0015655 -0.000182 -0.000166 0.000065 0.000064 0.0000084 0.0000372 0.000041 0.000037 2007 9 29 54372 0.138699 0.209423 -0.1851988 0.0012991 -0.000176 -0.000154 0.000065 0.000064 0.0000113 0.0000370 0.000041 0.000037 2007 9 30 54373 0.136112 0.207629 -0.1863396 0.0009975 -0.000146 -0.000147 0.000065 0.000064 0.0000188 0.0000367 0.000041 0.000037 2007 10 1 54374 0.133671 0.206384 -0.1871491 0.0007168 -0.000117 -0.000139 0.000065 0.000064 0.0000161 0.0000365 0.000041 0.000037 2007 10 2 54375 0.130581 0.205170 -0.1877194 0.0005899 -0.000087 -0.000132 0.000065 0.000064 0.0000084 0.0000362 0.000041 0.000037 2007 10 3 54376 0.127581 0.203893 -0.1882051 0.0005426 -0.000056 -0.000147 0.000065 0.000064 0.0000088 0.0000360 0.000041 0.000038 2007 10 4 54377 0.124565 0.202818 -0.1887206 0.0005319 -0.000025 -0.000168 0.000065 0.000064 0.0000113 0.0000359 0.000041 0.000038 2007 10 5 54378 0.121534 0.201554 -0.1893548 0.0006274 0.000006 -0.000189 0.000065 0.000064 0.0000139 0.0000357 0.000042 0.000038 2007 10 6 54379 0.118610 0.200420 -0.1901031 0.0007410 0.000002 -0.000178 0.000065 0.000064 0.0000120 0.0000355 0.000042 0.000038 2007 10 7 54380 0.115661 0.199238 -0.1909687 0.0008897 -0.000016 -0.000156 0.000065 0.000064 0.0000159 0.0000353 0.000042 0.000038 2007 10 8 54381 0.112862 0.198140 -0.1919301 0.0010311 -0.000034 -0.000134 0.000065 0.000064 0.0000159 0.0000351 0.000042 0.000038 2007 10 9 54382 0.109802 0.197459 -0.1929890 0.0010367 -0.000051 -0.000112 0.000066 0.000064 0.0000110 0.0000349 0.000042 0.000038 2007 10 10 54383 0.106657 0.196694 -0.1940738 0.0011204 -0.000069 -0.000090 0.000066 0.000064 0.0000054 0.0000347 0.000042 0.000038 2007 10 11 54384 0.103276 0.195901 -0.1951649 0.0010886 -0.000133 -0.000091 0.000066 0.000064 0.0000046 0.0000345 0.000042 0.000038 2007 10 12 54385 0.100221 0.194942 -0.1961621 0.0009686 -0.000063 -0.000023 0.000066 0.000064 0.0000050 0.0000342 0.000042 0.000038 2007 10 13 54386 0.097550 0.194235 -0.1970303 0.0008198 -0.000040 -0.000022 0.000066 0.000064 0.0000082 0.0000340 0.000042 0.000038 2007 10 14 54387 0.094938 0.193462 -0.1977061 0.0005856 -0.000050 -0.000055 0.000066 0.000064 0.0000115 0.0000337 0.000043 0.000039 2007 10 15 54388 0.092082 0.192877 -0.1982427 0.0004616 -0.000061 -0.000088 0.000066 0.000064 0.0000100 0.0000335 0.000043 0.000039 2007 10 16 54389 0.088963 0.192489 -0.1986730 0.0003905 -0.000071 -0.000121 0.000066 0.000064 0.0000067 0.0000333 0.000043 0.000040 2007 10 17 54390 0.085837 0.192044 -0.1990415 0.0004330 -0.000082 -0.000155 0.000066 0.000064 0.0000039 0.0000332 0.000043 0.000040 2007 10 18 54391 0.083023 0.191769 -0.1994811 0.0005083 0.000062 -0.000272 0.000066 0.000064 0.0000041 0.0000331 0.000044 0.000040 2007 10 19 54392 0.079862 0.191404 -0.2000346 0.0006369 -0.000025 -0.000119 0.000066 0.000064 0.0000052 0.0000331 0.000044 0.000041 2007 10 20 54393 0.076641 0.190925 -0.2007599 0.0008410 -0.000079 -0.000074 0.000066 0.000064 0.0000102 0.0000331 0.000044 0.000041 2007 10 21 54394 0.073323 0.190453 -0.2017344 0.0010366 -0.000090 -0.000101 0.000066 0.000064 0.0000150 0.0000331 0.000044 0.000041 2007 10 22 54395 0.070729 0.189994 -0.2028810 0.0012436 -0.000102 -0.000129 0.000066 0.000064 0.0000117 0.0000331 0.000045 0.000041 2007 10 23 54396 0.068573 0.190073 -0.2042352 0.0014956 -0.000113 -0.000156 0.000066 0.000064 0.0000047 0.0000331 0.000045 0.000042 2007 10 24 54397 0.066453 0.190343 -0.2058668 0.0016765 -0.000077 -0.000120 0.000066 0.000064 0.0000108 0.0000330 0.000045 0.000042 2007 10 25 54398 0.064128 0.190363 -0.2075420 0.0016268 -0.000029 -0.000067 0.000066 0.000064 0.0000203 0.0000329 0.000045 0.000042 2007 10 26 54399 0.061627 0.189981 -0.2090572 0.0014160 -0.000138 -0.000170 0.000066 0.000064 0.0000115 0.0000328 0.000046 0.000043 2007 10 27 54400 0.058873 0.190086 -0.2102384 0.0010201 -0.000170 -0.000187 0.000066 0.000064 0.0000100 0.0000326 0.000046 0.000042 2007 10 28 54401 0.056272 0.190086 -0.2110636 0.0006791 -0.000152 -0.000152 0.000066 0.000064 0.0000136 0.0000324 0.000046 0.000042 2007 10 29 54402 0.053431 0.190346 -0.2116760 0.0005207 -0.000135 -0.000117 0.000066 0.000064 0.0000108 0.0000322 0.000046 0.000042 2007 10 30 54403 0.050676 0.190569 -0.2121644 0.0004912 -0.000117 -0.000083 0.000066 0.000064 0.0000047 0.0000321 0.000046 0.000042 2007 10 31 54404 0.047805 0.190969 -0.2126395 0.0005471 0.000021 -0.000069 0.000066 0.000064 0.0000059 0.0000319 0.000046 0.000042 2007 11 1 54405 0.044779 0.190958 -0.2131904 0.0006032 0.000053 -0.000074 0.000066 0.000064 0.0000064 0.0000317 0.000046 0.000043 2007 11 2 54406 0.042246 0.190972 -0.2139011 0.0007660 0.000035 -0.000085 0.000066 0.000064 0.0000060 0.0000316 0.000046 0.000043 2007 11 3 54407 0.040283 0.191337 -0.2147698 0.0009046 0.000016 -0.000096 0.000066 0.000064 0.0000063 0.0000315 0.000047 0.000043 2007 11 4 54408 0.038285 0.192054 -0.2157590 0.0009872 -0.000003 -0.000106 0.000066 0.000064 0.0000083 0.0000313 0.000047 0.000043 2007 11 5 54409 0.035887 0.192515 -0.2167878 0.0010145 -0.000022 -0.000117 0.000066 0.000064 0.0000066 0.0000312 0.000047 0.000043 2007 11 6 54410 0.033998 0.192695 -0.2178025 0.0010224 -0.000040 -0.000128 0.000066 0.000064 0.0000034 0.0000311 0.000047 0.000043 2007 11 7 54411 0.032381 0.193049 -0.2188575 0.0010680 -0.000002 0.000088 0.000066 0.000064 0.0000148 0.0000310 0.000048 0.000044 2007 11 8 54412 0.030245 0.193166 -0.2198968 0.0009834 -0.000007 0.000180 0.000066 0.000064 0.0000208 0.0000310 0.000048 0.000045 2007 11 9 54413 0.027868 0.193416 -0.2208330 0.0008820 -0.000037 0.000100 0.000066 0.000064 0.0000106 0.0000310 0.000048 0.000045 2007 11 10 54414 0.025342 0.193384 -0.2215945 0.0006486 -0.000052 0.000058 0.000066 0.000064 0.0000097 0.0000309 0.000048 0.000045 2007 11 11 54415 0.022808 0.193450 -0.2221748 0.0005007 -0.000060 0.000044 0.000066 0.000064 0.0000143 0.0000309 0.000049 0.000045 2007 11 12 54416 0.020069 0.194068 -0.2225801 0.0003621 -0.000068 0.000031 0.000066 0.000064 0.0000127 0.0000308 0.000049 0.000046 2007 11 13 54417 0.016988 0.194634 -0.2229103 0.0003336 -0.000076 0.000017 0.000066 0.000064 0.0000078 0.0000307 0.000049 0.000046 2007 11 14 54418 0.014123 0.194838 -0.2232483 0.0004014 -0.000108 0.000032 0.000066 0.000064 0.0000098 0.0000307 0.000049 0.000046 2007 11 15 54419 0.011164 0.195392 -0.2237161 0.0005928 -0.000052 0.000079 0.000066 0.000064 0.0000109 0.0000306 0.000049 0.000047 2007 11 16 54420 0.007943 0.196019 -0.2244367 0.0008915 0.000069 0.000105 0.000066 0.000064 0.0000071 0.0000305 0.000049 0.000047 2007 11 17 54421 0.004583 0.196284 -0.2254242 0.0011152 0.000076 0.000084 0.000066 0.000064 0.0000087 0.0000304 0.000049 0.000047 2007 11 18 54422 0.001378 0.196877 -0.2267166 0.0013929 0.000037 0.000050 0.000066 0.000064 0.0000120 0.0000303 0.000049 0.000047 2007 11 19 54423 -0.001551 0.198046 -0.2282996 0.0016843 -0.000001 0.000016 0.000066 0.000065 0.0000092 0.0000302 0.000049 0.000046 2007 11 20 54424 -0.004193 0.199297 -0.2301250 0.0019105 -0.000040 -0.000018 0.000066 0.000065 0.0000036 0.0000300 0.000048 0.000046 2007 11 21 54425 -0.006937 0.200704 -0.2320941 0.0019717 -0.000037 0.000124 0.000066 0.000065 0.0000048 0.0000299 0.000048 0.000046 2007 11 22 54426 -0.009411 0.202217 -0.2341050 0.0019352 -0.000063 0.000230 0.000066 0.000065 0.0000065 0.0000297 0.000048 0.000046 2007 11 23 54427 -0.011765 0.203811 -0.2359611 0.0017482 -0.000103 0.000305 0.000066 0.000065 0.0000078 0.0000295 0.000048 0.000046 2007 11 24 54428 -0.014750 0.204461 -0.2375406 0.0014380 -0.000064 0.000239 0.000066 0.000065 0.0000090 0.0000292 0.000048 0.000046 2007 11 25 54429 -0.018157 0.204799 -0.2387924 0.0011238 -0.000025 0.000172 0.000067 0.000065 0.0000134 0.0000289 0.000047 0.000045 2007 11 26 54430 -0.020904 0.205007 -0.2397827 0.0009278 0.000014 0.000106 0.000067 0.000065 0.0000107 0.0000286 0.000047 0.000045 2007 11 27 54431 -0.022941 0.205769 -0.2406896 0.0009514 0.000053 0.000039 0.000067 0.000065 0.0000036 0.0000283 0.000047 0.000044 2007 11 28 54432 -0.025304 0.206880 -0.2416404 0.0010005 0.000063 0.000000 0.000067 0.000065 0.0000055 0.0000280 0.000046 0.000044 2007 11 29 54433 -0.027305 0.208099 -0.2427543 0.0011997 0.000090 -0.000010 0.000067 0.000065 0.0000134 0.0000278 0.000046 0.000044 2007 11 30 54434 -0.028699 0.209460 -0.2440654 0.0014026 0.000114 -0.000013 0.000067 0.000065 0.0000083 0.0000276 0.000046 0.000044 2007 12 1 54435 -0.029563 0.211013 -0.2455832 0.0015242 0.000083 -0.000007 0.000067 0.000065 0.0000071 0.0000273 0.000046 0.000044 2007 12 2 54436 -0.030630 0.212598 -0.2471563 0.0015991 0.000052 -0.000002 0.000067 0.000065 0.0000094 0.0000271 0.000045 0.000044 2007 12 3 54437 -0.031919 0.214132 -0.2487456 0.0015813 0.000020 0.000003 0.000067 0.000065 0.0000077 0.0000268 0.000045 0.000043 2007 12 4 54438 -0.033890 0.215810 -0.2502637 0.0014465 -0.000011 0.000008 0.000067 0.000065 0.0000039 0.0000265 0.000045 0.000043 2007 12 5 54439 -0.036684 0.217117 -0.2515806 0.0012057 -0.000005 -0.000154 0.000067 0.000065 0.0000033 0.0000262 0.000045 0.000043 2007 12 6 54440 -0.039663 0.218546 -0.2526781 0.0009647 -0.000008 -0.000049 0.000067 0.000065 0.0000035 0.0000258 0.000044 0.000043 2007 12 7 54441 -0.042441 0.219803 -0.2535092 0.0007069 -0.000062 0.000191 0.000067 0.000065 0.0000056 0.0000255 0.000044 0.000043 2007 12 8 54442 -0.044575 0.221116 -0.2541005 0.0004648 -0.000068 0.000207 0.000067 0.000065 0.0000067 0.0000251 0.000044 0.000043 2007 12 9 54443 -0.046304 0.222327 -0.2544630 0.0002801 -0.000052 0.000134 0.000067 0.000065 0.0000068 0.0000250 0.000044 0.000043 2007 12 10 54444 -0.047627 0.223950 -0.2546738 0.0001914 -0.000035 0.000061 0.000067 0.000065 0.0000052 0.0000250 0.000044 0.000043 2007 12 11 54445 -0.049084 0.225449 -0.2548244 0.0001761 -0.000019 -0.000012 0.000067 0.000065 0.0000027 0.0000252 0.000043 0.000043 2007 12 12 54446 -0.050232 0.226621 -0.2550421 0.0003048 0.000045 0.000006 0.000067 0.000065 0.0000033 0.0000253 0.000044 0.000043 2007 12 13 54447 -0.051566 0.227711 -0.2553847 0.0004505 0.000067 0.000041 0.000067 0.000065 0.0000047 0.0000254 0.000044 0.000042 2007 12 14 54448 -0.053118 0.228775 -0.2559030 0.0006356 -0.000074 -0.000055 0.000067 0.000065 0.0000056 0.0000255 0.000044 0.000042 2007 12 15 54449 -0.054649 0.230185 -0.2566552 0.0008453 -0.000118 -0.000058 0.000067 0.000065 0.0000083 0.0000256 0.000044 0.000042 2007 12 16 54450 -0.056216 0.231752 -0.2576438 0.0011170 -0.000107 -0.000012 0.000067 0.000065 0.0000078 0.0000256 0.000044 0.000041 2007 12 17 54451 -0.057538 0.233335 -0.2588368 0.0012978 -0.000097 0.000034 0.000067 0.000065 0.0000052 0.0000257 0.000044 0.000041 2007 12 18 54452 -0.058939 0.235024 -0.2601549 0.0013362 -0.000086 0.000080 0.000067 0.000065 0.0000027 0.0000257 0.000044 0.000040 2007 12 19 54453 -0.060046 0.236262 -0.2615019 0.0013271 -0.000094 0.000087 0.000067 0.000065 0.0000077 0.0000257 0.000044 0.000041 2007 12 20 54454 -0.061027 0.237690 -0.2627460 0.0011949 -0.000107 0.000084 0.000067 0.000065 0.0000121 0.0000257 0.000044 0.000041 2007 12 21 54455 -0.061804 0.239231 -0.2638268 0.0009554 -0.000120 0.000081 0.000067 0.000065 0.0000069 0.0000257 0.000045 0.000042 2007 12 22 54456 -0.062727 0.241033 -0.2646391 0.0006753 -0.000234 -0.000212 0.000067 0.000065 0.0000099 0.0000256 0.000045 0.000042 2007 12 23 54457 -0.063715 0.242601 -0.2652263 0.0005114 -0.000349 -0.000533 0.000067 0.000065 0.0000110 0.0000256 0.000045 0.000043 2007 12 24 54458 -0.065190 0.244464 -0.2656693 0.0004943 -0.000252 -0.000400 0.000067 0.000065 0.0000091 0.0000255 0.000045 0.000043 2007 12 25 54459 -0.067266 0.246069 -0.2661373 0.0005778 -0.000154 -0.000268 0.000067 0.000065 0.0000071 0.0000255 0.000045 0.000043 2007 12 26 54460 -0.069571 0.247591 -0.2667687 0.0007396 -0.000057 -0.000135 0.000067 0.000065 0.0000051 0.0000254 0.000045 0.000043 2007 12 27 54461 -0.071330 0.249049 -0.2676180 0.0009149 0.000041 -0.000002 0.000067 0.000065 0.0000031 0.0000253 0.000045 0.000043 2007 12 28 54462 -0.072872 0.250875 -0.2686144 0.0010901 -0.000056 0.000233 0.000067 0.000065 0.0000048 0.0000251 0.000046 0.000043 2007 12 29 54463 -0.074705 0.252653 -0.2697671 0.0012013 -0.000088 0.000280 0.000067 0.000065 0.0000053 0.0000250 0.000046 0.000043 2007 12 30 54464 -0.076374 0.254709 -0.2709916 0.0011953 -0.000078 0.000247 0.000067 0.000065 0.0000049 0.0000248 0.000046 0.000044 2007 12 31 54465 -0.078621 0.256961 -0.2721999 0.0010665 -0.000068 0.000214 0.000067 0.000065 0.0000045 0.0000246 0.000047 0.000044 2008 1 1 54466 -0.080508 0.258331 -0.2733294 0.0010450 -0.000056 0.000185 0.000072 0.000071 0.0000054 0.0000137 0.000050 0.000053 2008 1 2 54467 -0.081835 0.260037 -0.2743369 0.0009194 -0.000046 0.000153 0.000072 0.000071 0.0000049 0.0000136 0.000051 0.000054 2008 1 3 54468 -0.083273 0.261861 -0.2751956 0.0008086 -0.000036 0.000120 0.000072 0.000071 0.0000044 0.0000135 0.000052 0.000055 2008 1 4 54469 -0.085454 0.263849 -0.2759510 0.0006927 0.000057 -0.000210 0.000072 0.000071 0.0000140 0.0000134 0.000052 0.000056 2008 1 5 54470 -0.087894 0.265512 -0.2766139 0.0006169 0.000081 -0.000232 0.000072 0.000071 0.0000111 0.0000132 0.000053 0.000057 2008 1 6 54471 -0.090225 0.267117 -0.2772133 0.0005564 0.000070 -0.000107 0.000072 0.000071 0.0000095 0.0000131 0.000053 0.000057 2008 1 7 54472 -0.092639 0.268713 -0.2777360 0.0005345 0.000059 0.000017 0.000073 0.000071 0.0000092 0.0000129 0.000054 0.000058 2008 1 8 54473 -0.094409 0.270555 -0.2782618 0.0005497 0.000049 0.000142 0.000073 0.000072 0.0000077 0.0000127 0.000054 0.000058 2008 1 9 54474 -0.095990 0.272518 -0.2788232 0.0006424 -0.000043 0.001347 0.000073 0.000072 0.0000090 0.0000126 0.000054 0.000059 2008 1 10 54475 -0.097556 0.274858 -0.2795323 0.0008228 0.000006 0.001093 0.000073 0.000072 0.0000110 0.0000124 0.000055 0.000059 2008 1 11 54476 -0.099489 0.277428 -0.2804466 0.0009689 0.000107 0.000293 0.000073 0.000072 0.0000131 0.0000123 0.000055 0.000059 2008 1 12 54477 -0.101615 0.280050 -0.2815621 0.0011710 0.000114 0.000081 0.000073 0.000072 0.0000125 0.0000121 0.000055 0.000059 2008 1 13 54478 -0.103379 0.282761 -0.2828432 0.0013368 0.000087 0.000085 0.000073 0.000072 0.0000110 0.0000120 0.000055 0.000059 2008 1 14 54479 -0.104938 0.285695 -0.2842305 0.0014296 0.000060 0.000090 0.000073 0.000072 0.0000120 0.0000119 0.000055 0.000059 2008 1 15 54480 -0.106904 0.288697 -0.2856046 0.0013790 0.000033 0.000094 0.000073 0.000072 0.0000143 0.0000119 0.000055 0.000059 2008 1 16 54481 -0.108891 0.291033 -0.2868987 0.0012110 -0.000033 0.000082 0.000073 0.000072 0.0000169 0.0000118 0.000055 0.000059 2008 1 17 54482 -0.110411 0.292900 -0.2879860 0.0009416 -0.000109 0.000066 0.000073 0.000072 0.0000195 0.0000118 0.000054 0.000059 2008 1 18 54483 -0.112147 0.294940 -0.2887883 0.0006762 -0.000074 0.000086 0.000073 0.000073 0.0000123 0.0000117 0.000054 0.000058 2008 1 19 54484 -0.114053 0.297018 -0.2893522 0.0004618 -0.000028 0.000101 0.000073 0.000073 0.0000071 0.0000116 0.000054 0.000058 2008 1 20 54485 -0.115207 0.299110 -0.2897761 0.0004205 0.000008 0.000111 0.000073 0.000073 0.0000077 0.0000116 0.000053 0.000057 2008 1 21 54486 -0.115091 0.301540 -0.2902131 0.0005330 0.000044 0.000120 0.000074 0.000073 0.0000102 0.0000116 0.000053 0.000057 2008 1 22 54487 -0.115005 0.304463 -0.2908063 0.0007002 0.000080 0.000128 0.000074 0.000073 0.0000126 0.0000116 0.000053 0.000057 2008 1 23 54488 -0.115269 0.306737 -0.2916425 0.0009659 0.000137 0.000032 0.000074 0.000073 0.0000151 0.0000116 0.000052 0.000056 2008 1 24 54489 -0.115823 0.308970 -0.2927599 0.0012207 0.000156 -0.000020 0.000074 0.000073 0.0000078 0.0000115 0.000052 0.000055 2008 1 25 54490 -0.116620 0.311485 -0.2940904 0.0014179 0.000235 0.000064 0.000074 0.000073 0.0000123 0.0000115 0.000052 0.000055 2008 1 26 54491 -0.117498 0.313804 -0.2955917 0.0015221 0.000227 0.000095 0.000074 0.000073 0.0000103 0.0000115 0.000052 0.000055 2008 1 27 54492 -0.117846 0.316446 -0.2971182 0.0015000 0.000177 0.000091 0.000073 0.000073 0.0000074 0.0000115 0.000052 0.000055 2008 1 28 54493 -0.117941 0.319311 -0.2985991 0.0014341 0.000127 0.000087 0.000073 0.000073 0.0000065 0.0000115 0.000052 0.000056 2008 1 29 54494 -0.118440 0.321812 -0.2999632 0.0012483 0.000077 0.000083 0.000073 0.000073 0.0000060 0.0000116 0.000053 0.000056 2008 1 30 54495 -0.119154 0.324015 -0.3011193 0.0010359 -0.000163 0.000018 0.000073 0.000073 0.0000233 0.0000116 0.000053 0.000057 2008 1 31 54496 -0.119672 0.326370 -0.3020627 0.0007995 -0.000385 -0.000049 0.000073 0.000073 0.0000360 0.0000116 0.000053 0.000057 2008 2 1 54497 -0.119704 0.329023 -0.3027604 0.0006555 0.000125 0.000037 0.000073 0.000072 0.0000133 0.0000116 0.000053 0.000057 2008 2 2 54498 -0.119460 0.332328 -0.3034044 0.0005960 0.000240 0.000058 0.000073 0.000072 0.0000094 0.0000116 0.000053 0.000057 2008 2 3 54499 -0.119790 0.335623 -0.3039696 0.0005554 0.000207 0.000055 0.000073 0.000072 0.0000071 0.0000116 0.000053 0.000057 2008 2 4 54500 -0.120551 0.338335 -0.3045432 0.0006219 0.000175 0.000051 0.000073 0.000072 0.0000062 0.0000117 0.000053 0.000057 2008 2 5 54501 -0.120820 0.341094 -0.3052181 0.0007813 0.000143 0.000048 0.000073 0.000072 0.0000074 0.0000117 0.000053 0.000057 2008 2 6 54502 -0.121238 0.343992 -0.3060716 0.0009859 0.000112 0.000038 0.000073 0.000072 0.0000096 0.0000118 0.000053 0.000057 2008 2 7 54503 -0.122019 0.346863 -0.3071350 0.0012085 0.000140 0.000101 0.000073 0.000072 0.0000446 0.0000118 0.000053 0.000057 2008 2 8 54504 -0.122833 0.349396 -0.3084556 0.0014366 0.000235 0.000005 0.000073 0.000072 0.0000196 0.0000118 0.000053 0.000056 2008 2 9 54505 -0.123527 0.351903 -0.3099740 0.0015658 0.000216 -0.000023 0.000073 0.000072 0.0000083 0.0000118 0.000052 0.000056 2008 2 10 54506 -0.123924 0.354800 -0.3115812 0.0016443 0.000149 -0.000005 0.000073 0.000072 0.0000082 0.0000118 0.000052 0.000055 2008 2 11 54507 -0.124709 0.357674 -0.3132469 0.0016527 0.000083 0.000013 0.000073 0.000072 0.0000103 0.0000118 0.000052 0.000054 2008 2 12 54508 -0.125680 0.359909 -0.3148239 0.0014748 0.000016 0.000032 0.000073 0.000072 0.0000141 0.0000119 0.000051 0.000053 2008 2 13 54509 -0.126200 0.361798 -0.3161807 0.0012534 0.000022 0.000040 0.000073 0.000072 0.0000131 0.0000119 0.000051 0.000053 2008 2 14 54510 -0.125736 0.364364 -0.3173284 0.0010339 0.000102 0.000056 0.000074 0.000072 0.0000135 0.0000119 0.000051 0.000052 2008 2 15 54511 -0.125208 0.367121 -0.3182287 0.0007765 0.000161 -0.000020 0.000074 0.000072 0.0000091 0.0000119 0.000050 0.000051 2008 2 16 54512 -0.125169 0.369424 -0.3189266 0.0006042 0.000197 -0.000084 0.000073 0.000072 0.0000089 0.0000119 0.000049 0.000049 2008 2 17 54513 -0.125661 0.371322 -0.3194983 0.0005521 0.000230 -0.000131 0.000073 0.000072 0.0000083 0.0000119 0.000049 0.000048 2008 2 18 54514 -0.126485 0.373867 -0.3200926 0.0006780 0.000262 -0.000179 0.000073 0.000072 0.0000057 0.0000120 0.000048 0.000047 2008 2 19 54515 -0.126952 0.376693 -0.3208923 0.0009357 0.000295 -0.000227 0.000073 0.000072 0.0000052 0.0000120 0.000048 0.000046 2008 2 20 54516 -0.127170 0.379559 -0.3219256 0.0011347 0.000216 -0.000056 0.000074 0.000072 0.0000062 0.0000120 0.000047 0.000045 2008 2 21 54517 -0.127372 0.382075 -0.3231548 0.0013113 0.000275 0.000020 0.000074 0.000072 0.0000047 0.0000120 0.000046 0.000044 2008 2 22 54518 -0.127377 0.384852 -0.3244930 0.0013375 0.000268 -0.000010 0.000074 0.000072 0.0000048 0.0000120 0.000046 0.000043 2008 2 23 54519 -0.127498 0.387781 -0.3258499 0.0013240 0.000262 -0.000009 0.000073 0.000072 0.0000091 0.0000120 0.000045 0.000043 2008 2 24 54520 -0.127212 0.390864 -0.3271385 0.0012208 0.000268 0.000013 0.000073 0.000072 0.0000085 0.0000120 0.000044 0.000042 2008 2 25 54521 -0.126921 0.393801 -0.3283051 0.0011038 0.000274 0.000035 0.000073 0.000072 0.0000058 0.0000120 0.000044 0.000041 2008 2 26 54522 -0.126365 0.396415 -0.3292896 0.0008952 0.000280 0.000057 0.000073 0.000072 0.0000036 0.0000121 0.000043 0.000040 2008 2 27 54523 -0.125469 0.398923 -0.3300771 0.0006604 0.000327 -0.000008 0.000073 0.000072 0.0000089 0.0000121 0.000042 0.000040 2008 2 28 54524 -0.124161 0.401588 -0.3306476 0.0004609 0.000326 -0.000011 0.000073 0.000072 0.0000136 0.0000121 0.000042 0.000040 2008 2 29 54525 -0.122866 0.404004 -0.3309715 0.0002996 0.000306 0.000010 0.000073 0.000072 0.0000084 0.0000122 0.000041 0.000039 2008 3 1 54526 -0.121295 0.406668 -0.3312212 0.0002252 0.000303 -0.000006 0.000073 0.000072 0.0000123 0.0000122 0.000041 0.000038 2008 3 2 54527 -0.120141 0.409758 -0.3314760 0.0002611 0.000306 -0.000035 0.000073 0.000072 0.0000128 0.0000122 0.000040 0.000038 2008 3 3 54528 -0.119073 0.412657 -0.3317862 0.0003763 0.000309 -0.000065 0.000073 0.000072 0.0000082 0.0000123 0.000039 0.000037 2008 3 4 54529 -0.118145 0.415896 -0.3322417 0.0005806 0.000312 -0.000094 0.000073 0.000072 0.0000028 0.0000124 0.000039 0.000036 2008 3 5 54530 -0.117022 0.418945 -0.3329945 0.0008723 0.000293 -0.000090 0.000073 0.000072 0.0000080 0.0000125 0.000039 0.000036 2008 3 6 54531 -0.115681 0.421761 -0.3340262 0.0011575 0.000268 -0.000077 0.000073 0.000072 0.0000134 0.0000126 0.000039 0.000037 2008 3 7 54532 -0.114749 0.424333 -0.3352705 0.0013787 0.000243 -0.000065 0.000073 0.000071 0.0000088 0.0000127 0.000039 0.000037 2008 3 8 54533 -0.113387 0.426623 -0.3367626 0.0015539 0.000247 -0.000050 0.000073 0.000071 0.0000067 0.0000127 0.000039 0.000037 2008 3 9 54534 -0.111885 0.429366 -0.3383492 0.0015267 0.000263 -0.000033 0.000073 0.000071 0.0000073 0.0000129 0.000039 0.000037 2008 3 10 54535 -0.110667 0.431680 -0.3398203 0.0013668 0.000279 -0.000017 0.000073 0.000071 0.0000076 0.0000131 0.000039 0.000038 2008 3 11 54536 -0.109338 0.434373 -0.3410867 0.0011188 0.000294 -0.000001 0.000073 0.000071 0.0000065 0.0000133 0.000039 0.000038 2008 3 12 54537 -0.108037 0.437531 -0.3420858 0.0008215 0.000310 0.000015 0.000073 0.000071 0.0000046 0.0000136 0.000039 0.000038 2008 3 13 54538 -0.106559 0.440368 -0.3428038 0.0005955 0.000311 -0.000012 0.000072 0.000071 0.0000069 0.0000139 0.000039 0.000038 2008 3 14 54539 -0.104909 0.443233 -0.3433263 0.0004452 0.000309 -0.000049 0.000072 0.000071 0.0000103 0.0000141 0.000039 0.000038 2008 3 15 54540 -0.103013 0.445924 -0.3437843 0.0004456 0.000319 -0.000042 0.000072 0.000071 0.0000089 0.0000144 0.000039 0.000038 2008 3 16 54541 -0.100944 0.448887 -0.3443076 0.0005508 0.000334 -0.000017 0.000072 0.000071 0.0000112 0.0000147 0.000039 0.000038 2008 3 17 54542 -0.098577 0.452054 -0.3449560 0.0007748 0.000349 0.000007 0.000072 0.000072 0.0000090 0.0000150 0.000039 0.000038 2008 3 18 54543 -0.096339 0.455103 -0.3458154 0.0009952 0.000364 0.000032 0.000072 0.000072 0.0000032 0.0000152 0.000038 0.000038 2008 3 19 54544 -0.094092 0.457904 -0.3469473 0.0012475 0.000305 -0.000025 0.000072 0.000072 0.0000045 0.0000155 0.000039 0.000038 2008 3 20 54545 -0.091541 0.460865 -0.3482841 0.0013785 0.000228 -0.000102 0.000072 0.000072 0.0000075 0.0000157 0.000039 0.000039 2008 3 21 54546 -0.088896 0.463818 -0.3497562 0.0014602 0.000228 -0.000096 0.000072 0.000072 0.0000137 0.0000160 0.000039 0.000039 2008 3 22 54547 -0.086165 0.466983 -0.3512487 0.0014684 0.000257 -0.000057 0.000072 0.000072 0.0000151 0.0000162 0.000039 0.000039 2008 3 23 54548 -0.083333 0.470181 -0.3526792 0.0014208 0.000286 -0.000019 0.000072 0.000071 0.0000068 0.0000164 0.000039 0.000039 2008 3 24 54549 -0.080689 0.473122 -0.3540527 0.0013097 0.000315 0.000019 0.000073 0.000071 0.0000057 0.0000166 0.000039 0.000040 2008 3 25 54550 -0.078445 0.475834 -0.3552855 0.0011641 0.000345 0.000057 0.000073 0.000071 0.0000050 0.0000168 0.000039 0.000040 2008 3 26 54551 -0.076234 0.478315 -0.3563462 0.0009801 0.000374 0.000095 0.000073 0.000071 0.0000043 0.0000170 0.000039 0.000040 2008 3 27 54552 -0.074078 0.480658 -0.3572070 0.0007888 0.000387 0.000035 0.000073 0.000071 0.0000047 0.0000172 0.000040 0.000040 2008 3 28 54553 -0.072210 0.482852 -0.3579461 0.0006758 0.000396 -0.000051 0.000073 0.000071 0.0000054 0.0000174 0.000040 0.000041 2008 3 29 54554 -0.070676 0.484946 -0.3586104 0.0006367 0.000373 -0.000073 0.000073 0.000071 0.0000072 0.0000175 0.000040 0.000041 2008 3 30 54555 -0.068753 0.486676 -0.3592894 0.0007174 0.000340 -0.000070 0.000073 0.000071 0.0000095 0.0000177 0.000040 0.000041 2008 3 31 54556 -0.066576 0.488121 -0.3600608 0.0008710 0.000306 -0.000067 0.000073 0.000071 0.0000082 0.0000178 0.000040 0.000041 2008 4 1 54557 -0.064549 0.489750 -0.3610049 0.0010807 0.000273 -0.000065 0.000073 0.000071 0.0000052 0.0000180 0.000040 0.000041 2008 4 2 54558 -0.062030 0.491570 -0.3621873 0.0013148 0.000222 -0.000123 0.000073 0.000071 0.0000084 0.0000181 0.000040 0.000041 2008 4 3 54559 -0.058993 0.493545 -0.3636285 0.0015633 0.000295 -0.000172 0.000073 0.000071 0.0000077 0.0000182 0.000041 0.000041 2008 4 4 54560 -0.056047 0.495387 -0.3652888 0.0017499 0.000312 -0.000151 0.000073 0.000071 0.0000078 0.0000183 0.000041 0.000042 2008 4 5 54561 -0.053616 0.496997 -0.3671364 0.0019029 0.000283 -0.000098 0.000073 0.000071 0.0000092 0.0000185 0.000041 0.000042 2008 4 6 54562 -0.050859 0.498675 -0.3690552 0.0018691 0.000248 -0.000041 0.000073 0.000071 0.0000083 0.0000186 0.000041 0.000042 2008 4 7 54563 -0.047870 0.500381 -0.3707910 0.0015987 0.000212 0.000016 0.000073 0.000071 0.0000057 0.0000187 0.000040 0.000042 2008 4 8 54564 -0.045078 0.502340 -0.3722138 0.0012297 0.000177 0.000073 0.000073 0.000070 0.0000029 0.0000188 0.000040 0.000042 2008 4 9 54565 -0.042901 0.504718 -0.3732717 0.0008955 0.000153 0.000017 0.000073 0.000070 0.0000036 0.0000189 0.000041 0.000043 2008 4 10 54566 -0.041151 0.506820 -0.3740438 0.0006567 0.000132 -0.000068 0.000072 0.000070 0.0000051 0.0000190 0.000041 0.000044 2008 4 11 54567 -0.038926 0.508650 -0.3746280 0.0005365 0.000260 -0.000166 0.000072 0.000070 0.0000068 0.0000190 0.000042 0.000045 2008 4 12 54568 -0.036674 0.510351 -0.3751673 0.0005562 0.000291 -0.000165 0.000072 0.000070 0.0000073 0.0000191 0.000042 0.000046 2008 4 13 54569 -0.034213 0.511855 -0.3757920 0.0006942 0.000268 -0.000127 0.000072 0.000070 0.0000065 0.0000192 0.000043 0.000046 2008 4 14 54570 -0.031612 0.512979 -0.3766197 0.0009222 0.000245 -0.000089 0.000072 0.000070 0.0000050 0.0000192 0.000043 0.000047 2008 4 15 54571 -0.029062 0.513792 -0.3776605 0.0011783 0.000222 -0.000051 0.000072 0.000070 0.0000034 0.0000193 0.000043 0.000047 2008 4 16 54572 -0.026537 0.514506 -0.3788917 0.0013009 0.000274 -0.000069 0.000072 0.000070 0.0000042 0.0000193 0.000044 0.000048 2008 4 17 54573 -0.023704 0.515554 -0.3802337 0.0013579 0.000346 -0.000101 0.000072 0.000070 0.0000055 0.0000193 0.000044 0.000049 2008 4 18 54574 -0.020398 0.517251 -0.3816034 0.0013426 0.000417 -0.000134 0.000072 0.000070 0.0000069 0.0000194 0.000045 0.000050 2008 4 19 54575 -0.016953 0.519317 -0.3829408 0.0012884 0.000298 0.000067 0.000072 0.000070 0.0000073 0.0000194 0.000045 0.000051 2008 4 20 54576 -0.013677 0.521563 -0.3841848 0.0011653 0.000108 0.000355 0.000072 0.000070 0.0000083 0.0000194 0.000046 0.000052 2008 4 21 54577 -0.010961 0.523823 -0.3852515 0.0009906 -0.000082 0.000642 0.000072 0.000070 0.0000075 0.0000194 0.000046 0.000052 2008 4 22 54578 -0.008240 0.525806 -0.3861629 0.0008474 -0.000272 0.000930 0.000072 0.000070 0.0000115 0.0000194 0.000047 0.000053 2008 4 23 54579 -0.005806 0.527535 -0.3869350 0.0007079 0.000192 0.000052 0.000072 0.000070 0.0000189 0.0000194 0.000047 0.000054 2008 4 24 54580 -0.003131 0.528414 -0.3875922 0.0006308 0.000337 -0.000126 0.000072 0.000070 0.0000156 0.0000194 0.000047 0.000054 2008 4 25 54581 -0.000089 0.529142 -0.3881944 0.0005814 0.000388 -0.000108 0.000072 0.000070 0.0000095 0.0000194 0.000047 0.000054 2008 4 26 54582 0.003053 0.529867 -0.3887823 0.0006092 0.000388 -0.000111 0.000072 0.000070 0.0000066 0.0000193 0.000047 0.000054 2008 4 27 54583 0.006143 0.530668 -0.3894242 0.0006912 0.000369 -0.000121 0.000072 0.000070 0.0000073 0.0000193 0.000047 0.000054 2008 4 28 54584 0.009569 0.531684 -0.3902086 0.0008869 0.000350 -0.000131 0.000072 0.000070 0.0000072 0.0000193 0.000047 0.000053 2008 4 29 54585 0.012940 0.533144 -0.3912111 0.0011367 0.000331 -0.000141 0.000072 0.000070 0.0000061 0.0000193 0.000047 0.000053 2008 4 30 54586 0.016005 0.534686 -0.3925121 0.0014456 0.000310 -0.000164 0.000072 0.000070 0.0000086 0.0000193 0.000047 0.000053 2008 5 1 54587 0.018994 0.536002 -0.3940636 0.0016447 0.000312 -0.000171 0.000072 0.000070 0.0000117 0.0000192 0.000047 0.000053 2008 5 2 54588 0.021756 0.537009 -0.3958091 0.0017744 0.000324 -0.000170 0.000072 0.000070 0.0000132 0.0000192 0.000047 0.000053 2008 5 3 54589 0.024439 0.537702 -0.3976431 0.0018469 0.000336 -0.000168 0.000073 0.000070 0.0000096 0.0000192 0.000047 0.000052 2008 5 4 54590 0.027085 0.538331 -0.3994898 0.0017983 0.000348 -0.000167 0.000073 0.000071 0.0000094 0.0000192 0.000047 0.000052 2008 5 5 54591 0.029956 0.538549 -0.4011655 0.0015818 0.000360 -0.000166 0.000073 0.000071 0.0000087 0.0000192 0.000047 0.000052 2008 5 6 54592 0.033517 0.538711 -0.4025692 0.0012716 0.000371 -0.000165 0.000073 0.000071 0.0000072 0.0000191 0.000047 0.000052 2008 5 7 54593 0.036924 0.539210 -0.4036504 0.0009812 0.000442 -0.000459 0.000073 0.000071 0.0000062 0.0000191 0.000047 0.000051 2008 5 8 54594 0.039778 0.539880 -0.4045484 0.0008303 0.000484 -0.000166 0.000073 0.000071 0.0000053 0.0000191 0.000047 0.000051 2008 5 9 54595 0.042508 0.540628 -0.4054308 0.0008671 0.000472 -0.000050 0.000073 0.000071 0.0000105 0.0000191 0.000047 0.000050 2008 5 10 54596 0.044808 0.541496 -0.4063968 0.0010172 0.000446 -0.000074 0.000073 0.000071 0.0000146 0.0000191 0.000047 0.000049 2008 5 11 54597 0.047299 0.541796 -0.4075084 0.0012600 0.000420 -0.000098 0.000073 0.000071 0.0000090 0.0000191 0.000047 0.000049 2008 5 12 54598 0.049995 0.542274 -0.4089011 0.0014925 0.000393 -0.000121 0.000073 0.000071 0.0000068 0.0000191 0.000047 0.000048 2008 5 13 54599 0.052797 0.542546 -0.4104774 0.0016119 0.000367 -0.000145 0.000073 0.000071 0.0000055 0.0000191 0.000047 0.000047 2008 5 14 54600 0.056330 0.542645 -0.4121482 0.0016832 0.000358 -0.000124 0.000073 0.000071 0.0000049 0.0000192 0.000047 0.000047 2008 5 15 54601 0.060250 0.542600 -0.4138181 0.0016237 0.000353 -0.000091 0.000073 0.000071 0.0000046 0.0000192 0.000048 0.000048 2008 5 16 54602 0.064154 0.542638 -0.4154062 0.0015295 0.000316 -0.000074 0.000073 0.000071 0.0000062 0.0000192 0.000048 0.000048 2008 5 17 54603 0.068008 0.542602 -0.4168436 0.0013116 0.000287 -0.000080 0.000073 0.000071 0.0000104 0.0000192 0.000049 0.000049 2008 5 18 54604 0.071438 0.542675 -0.4180447 0.0010946 0.000265 -0.000093 0.000073 0.000071 0.0000124 0.0000192 0.000049 0.000050 2008 5 19 54605 0.074630 0.542656 -0.4190349 0.0008966 0.000243 -0.000105 0.000073 0.000071 0.0000183 0.0000193 0.000050 0.000051 2008 5 20 54606 0.077625 0.542660 -0.4198149 0.0006556 0.000220 -0.000118 0.000073 0.000071 0.0000268 0.0000193 0.000051 0.000052 2008 5 21 54607 0.080901 0.542347 -0.4203497 0.0004614 0.000263 -0.000097 0.000073 0.000071 0.0000231 0.0000193 0.000051 0.000053 2008 5 22 54608 0.084289 0.541881 -0.4207330 0.0003320 0.000322 -0.000068 0.000073 0.000071 0.0000162 0.0000193 0.000052 0.000054 2008 5 23 54609 0.088160 0.541486 -0.4210329 0.0002789 0.000271 -0.000265 0.000073 0.000071 0.0000090 0.0000193 0.000052 0.000054 2008 5 24 54610 0.092259 0.541453 -0.4213510 0.0003367 0.000201 -0.000391 0.000073 0.000071 0.0000100 0.0000193 0.000052 0.000055 2008 5 25 54611 0.096072 0.541302 -0.4217552 0.0004990 0.000138 -0.000462 0.000073 0.000071 0.0000123 0.0000193 0.000053 0.000056 2008 5 26 54612 0.100039 0.541247 -0.4223252 0.0007003 0.000075 -0.000534 0.000073 0.000071 0.0000124 0.0000193 0.000053 0.000056 2008 5 27 54613 0.103781 0.541531 -0.4230769 0.0008542 0.000013 -0.000603 0.000073 0.000071 0.0000115 0.0000193 0.000054 0.000057 2008 5 28 54614 0.107551 0.541461 -0.4240236 0.0010131 0.000122 -0.000297 0.000073 0.000071 0.0000104 0.0000193 0.000054 0.000057 2008 5 29 54615 0.111278 0.541201 -0.4251396 0.0011738 0.000277 -0.000083 0.000073 0.000071 0.0000136 0.0000193 0.000054 0.000058 2008 5 30 54616 0.114540 0.540668 -0.4263617 0.0012701 0.000444 0.000106 0.000073 0.000071 0.0000180 0.0000193 0.000054 0.000058 2008 5 31 54617 0.117347 0.540042 -0.4276335 0.0012229 0.000451 0.000090 0.000073 0.000071 0.0000207 0.0000193 0.000054 0.000057 2008 6 1 54618 0.119992 0.539768 -0.4287759 0.0010372 0.000398 -0.000002 0.000073 0.000071 0.0000136 0.0000193 0.000054 0.000057 2008 6 2 54619 0.122593 0.539275 -0.4296889 0.0008120 0.000345 -0.000095 0.000073 0.000071 0.0000073 0.0000193 0.000054 0.000056 2008 6 3 54620 0.125594 0.538471 -0.4303377 0.0005679 0.000292 -0.000188 0.000073 0.000071 0.0000040 0.0000193 0.000054 0.000056 2008 6 4 54621 0.129007 0.537409 -0.4307715 0.0003777 0.000366 -0.000224 0.000073 0.000071 0.0000138 0.0000192 0.000054 0.000056 2008 6 5 54622 0.132819 0.536081 -0.4310988 0.0003117 0.000307 -0.000184 0.000073 0.000071 0.0000215 0.0000192 0.000054 0.000057 2008 6 6 54623 0.136485 0.534924 -0.4314389 0.0003653 0.000201 -0.000127 0.000073 0.000071 0.0000082 0.0000192 0.000054 0.000057 2008 6 7 54624 0.139879 0.533747 -0.4319460 0.0005299 0.000221 -0.000189 0.000073 0.000071 0.0000145 0.0000192 0.000054 0.000057 2008 6 8 54625 0.143279 0.532748 -0.4325636 0.0007200 0.000288 -0.000295 0.000073 0.000071 0.0000150 0.0000192 0.000054 0.000057 2008 6 9 54626 0.146543 0.531730 -0.4333556 0.0008359 0.000355 -0.000401 0.000073 0.000071 0.0000108 0.0000191 0.000054 0.000057 2008 6 10 54627 0.150203 0.530521 -0.4342693 0.0009705 0.000423 -0.000507 0.000073 0.000071 0.0000074 0.0000191 0.000055 0.000058 2008 6 11 54628 0.153699 0.529270 -0.4352686 0.0009826 0.000308 -0.000203 0.000073 0.000071 0.0000086 0.0000190 0.000055 0.000058 2008 6 12 54629 0.157108 0.527631 -0.4361850 0.0008398 0.000267 -0.000110 0.000074 0.000071 0.0000140 0.0000190 0.000055 0.000058 2008 6 13 54630 0.160608 0.526041 -0.4369507 0.0006488 0.000271 -0.000137 0.000074 0.000071 0.0000194 0.0000189 0.000055 0.000058 2008 6 14 54631 0.163971 0.524700 -0.4375296 0.0004620 0.000275 -0.000163 0.000074 0.000071 0.0000163 0.0000189 0.000055 0.000058 2008 6 15 54632 0.166818 0.523300 -0.4378563 0.0002420 0.000278 -0.000189 0.000074 0.000071 0.0000143 0.0000188 0.000055 0.000058 2008 6 16 54633 0.169548 0.521922 -0.4380331 0.0001283 0.000282 -0.000215 0.000074 0.000072 0.0000121 0.0000187 0.000055 0.000057 2008 6 17 54634 0.172469 0.520598 -0.4380719 0.0000346 0.000286 -0.000241 0.000074 0.000072 0.0000052 0.0000186 0.000055 0.000057 2008 6 18 54635 0.175183 0.519064 -0.4380141 -0.0000361 0.000858 0.000026 0.000074 0.000072 0.0000055 0.0000185 0.000055 0.000058 2008 6 19 54636 0.177750 0.517428 -0.4379278 -0.0000653 0.001043 0.000094 0.000074 0.000072 0.0000077 0.0000184 0.000055 0.000059 2008 6 20 54637 0.180362 0.515845 -0.4378894 -0.0000415 0.000595 -0.000163 0.000074 0.000072 0.0000099 0.0000183 0.000056 0.000059 2008 6 21 54638 0.183576 0.514362 -0.4379184 0.0000913 0.000439 -0.000255 0.000074 0.000072 0.0000111 0.0000182 0.000056 0.000059 2008 6 22 54639 0.187012 0.512869 -0.4381258 0.0002880 0.000392 -0.000287 0.000074 0.000072 0.0000107 0.0000181 0.000056 0.000060 2008 6 23 54640 0.190285 0.511323 -0.4385515 0.0005378 0.000345 -0.000319 0.000074 0.000072 0.0000123 0.0000180 0.000056 0.000060 2008 6 24 54641 0.193432 0.509868 -0.4391956 0.0007377 0.000298 -0.000352 0.000075 0.000072 0.0000152 0.0000179 0.000056 0.000060 2008 6 25 54642 0.196492 0.508347 -0.4400439 0.0009268 0.000326 -0.000334 0.000075 0.000072 0.0000119 0.0000179 0.000056 0.000060 2008 6 26 54643 0.199516 0.507091 -0.4410335 0.0010286 0.000298 -0.000221 0.000075 0.000072 0.0000153 0.0000179 0.000056 0.000060 2008 6 27 54644 0.201850 0.505839 -0.4420573 0.0010027 0.000240 -0.000324 0.000075 0.000072 0.0000113 0.0000179 0.000056 0.000060 2008 6 28 54645 0.204235 0.504030 -0.4429864 0.0008907 0.000214 -0.000331 0.000075 0.000072 0.0000112 0.0000180 0.000056 0.000060 2008 6 29 54646 0.206535 0.502119 -0.4438005 0.0006945 0.000202 -0.000273 0.000075 0.000072 0.0000112 0.0000180 0.000055 0.000060 2008 6 30 54647 0.208757 0.499807 -0.4443954 0.0004932 0.000190 -0.000214 0.000074 0.000072 0.0000103 0.0000181 0.000055 0.000060 2008 7 1 54648 0.211219 0.497484 -0.4447537 0.0002837 0.000177 -0.000155 0.000074 0.000072 0.0000096 0.0000182 0.000055 0.000059 2008 7 2 54649 0.213568 0.495285 -0.4449296 0.0001550 0.000314 -0.000372 0.000074 0.000072 0.0000137 0.0000182 0.000054 0.000059 2008 7 3 54650 0.216090 0.493223 -0.4450855 0.0001747 0.000490 -0.000662 0.000074 0.000072 0.0000191 0.0000183 0.000054 0.000059 2008 7 4 54651 0.218852 0.491171 -0.4453694 0.0003505 0.000492 -0.000671 0.000074 0.000072 0.0000177 0.0000184 0.000053 0.000058 2008 7 5 54652 0.221719 0.489026 -0.4458540 0.0005444 0.000429 -0.000576 0.000074 0.000072 0.0000137 0.0000184 0.000053 0.000058 2008 7 6 54653 0.224732 0.487211 -0.4464948 0.0007135 0.000366 -0.000480 0.000074 0.000072 0.0000132 0.0000185 0.000053 0.000057 2008 7 7 54654 0.227288 0.485449 -0.4472616 0.0008098 0.000303 -0.000385 0.000074 0.000072 0.0000130 0.0000185 0.000052 0.000057 2008 7 8 54655 0.229647 0.483235 -0.4480601 0.0007576 0.000240 -0.000290 0.000074 0.000072 0.0000123 0.0000186 0.000052 0.000056 2008 7 9 54656 0.231916 0.481105 -0.4487816 0.0006334 -0.000036 -0.000306 0.000075 0.000072 0.0000093 0.0000186 0.000051 0.000055 2008 7 10 54657 0.234148 0.479142 -0.4493424 0.0004859 0.000060 -0.000164 0.000075 0.000072 0.0000057 0.0000187 0.000051 0.000054 2008 7 11 54658 0.236497 0.477292 -0.4497275 0.0002757 0.000246 -0.000237 0.000075 0.000072 0.0000152 0.0000187 0.000050 0.000054 2008 7 12 54659 0.238771 0.474963 -0.4498886 0.0000345 0.000308 -0.000294 0.000075 0.000072 0.0000145 0.0000187 0.000050 0.000054 2008 7 13 54660 0.241266 0.472481 -0.4498146 -0.0001722 0.000327 -0.000311 0.000075 0.000072 0.0000146 0.0000188 0.000050 0.000053 2008 7 14 54661 0.243360 0.469912 -0.4495614 -0.0003108 0.000347 -0.000328 0.000075 0.000072 0.0000119 0.0000188 0.000049 0.000053 2008 7 15 54662 0.245285 0.466931 -0.4491919 -0.0003867 0.000367 -0.000345 0.000075 0.000073 0.0000062 0.0000188 0.000049 0.000053 2008 7 16 54663 0.247822 0.464020 -0.4487941 -0.0003945 0.000352 -0.000278 0.000075 0.000073 0.0000196 0.0000189 0.000049 0.000052 2008 7 17 54664 0.250626 0.461523 -0.4484374 -0.0003284 0.000329 -0.000190 0.000075 0.000073 0.0000381 0.0000189 0.000049 0.000052 2008 7 18 54665 0.252946 0.459105 -0.4481691 -0.0001924 0.000174 -0.000337 0.000075 0.000073 0.0000191 0.0000189 0.000048 0.000052 2008 7 19 54666 0.254962 0.456620 -0.4480820 0.0000118 0.000115 -0.000384 0.000075 0.000073 0.0000153 0.0000190 0.000048 0.000052 2008 7 20 54667 0.257155 0.453747 -0.4482069 0.0002680 0.000107 -0.000364 0.000075 0.000073 0.0000194 0.0000190 0.000047 0.000051 2008 7 21 54668 0.259611 0.450908 -0.4485968 0.0005103 0.000099 -0.000344 0.000075 0.000073 0.0000161 0.0000190 0.000046 0.000051 2008 7 22 54669 0.262206 0.447627 -0.4492145 0.0006791 0.000092 -0.000325 0.000075 0.000073 0.0000097 0.0000191 0.000046 0.000050 2008 7 23 54670 0.265124 0.444109 -0.4499584 0.0007503 0.000532 0.000001 0.000075 0.000073 0.0000092 0.0000191 0.000045 0.000050 2008 7 24 54671 0.267798 0.440638 -0.4507472 0.0007669 0.000461 -0.000099 0.000075 0.000073 0.0000102 0.0000191 0.000045 0.000049 2008 7 25 54672 0.270293 0.437298 -0.4514783 0.0007087 0.000203 -0.000351 0.000075 0.000073 0.0000113 0.0000192 0.000044 0.000048 2008 7 26 54673 0.272844 0.434739 -0.4520976 0.0005361 0.000140 -0.000387 0.000075 0.000073 0.0000104 0.0000192 0.000043 0.000047 2008 7 27 54674 0.275015 0.432349 -0.4525170 0.0003229 0.000150 -0.000343 0.000075 0.000073 0.0000087 0.0000192 0.000042 0.000046 2008 7 28 54675 0.276792 0.429641 -0.4527173 0.0001020 0.000159 -0.000299 0.000075 0.000073 0.0000070 0.0000192 0.000041 0.000045 2008 7 29 54676 0.278307 0.426780 -0.4527609 0.0000119 0.000169 -0.000256 0.000075 0.000073 0.0000054 0.0000192 0.000041 0.000044 2008 7 30 54677 0.279510 0.424010 -0.4527535 0.0000146 -0.000016 -0.000323 0.000076 0.000073 0.0000101 0.0000193 0.000040 0.000043 2008 7 31 54678 0.280198 0.421356 -0.4527883 0.0001131 0.000041 -0.000364 0.000076 0.000073 0.0000110 0.0000193 0.000039 0.000042 2008 8 1 54679 0.281044 0.418278 -0.4530063 0.0002792 0.000184 -0.000390 0.000076 0.000073 0.0000104 0.0000193 0.000039 0.000041 2008 8 2 54680 0.282229 0.415078 -0.4534413 0.0005272 0.000198 -0.000382 0.000076 0.000074 0.0000108 0.0000193 0.000038 0.000040 2008 8 3 54681 0.283687 0.411551 -0.4540709 0.0006885 0.000164 -0.000363 0.000076 0.000074 0.0000115 0.0000193 0.000037 0.000039 2008 8 4 54682 0.285281 0.408032 -0.4548415 0.0007969 0.000130 -0.000344 0.000076 0.000074 0.0000108 0.0000192 0.000036 0.000038 2008 8 5 54683 0.286947 0.404561 -0.4556257 0.0007330 0.000096 -0.000324 0.000076 0.000074 0.0000096 0.0000192 0.000036 0.000037 2008 8 6 54684 0.288609 0.401224 -0.4563126 0.0005933 -0.000116 -0.000383 0.000077 0.000074 0.0000089 0.0000192 0.000035 0.000036 2008 8 7 54685 0.290074 0.398308 -0.4568281 0.0003939 -0.000220 -0.000370 0.000077 0.000074 0.0000085 0.0000192 0.000034 0.000035 2008 8 8 54686 0.290780 0.395538 -0.4571402 0.0002227 -0.000279 -0.000330 0.000077 0.000074 0.0000080 0.0000193 0.000033 0.000034 2008 8 9 54687 0.291442 0.392612 -0.4572514 0.0000797 -0.000228 -0.000315 0.000077 0.000075 0.0000262 0.0000193 0.000033 0.000033 2008 8 10 54688 0.291948 0.389533 -0.4572767 -0.0000703 -0.000137 -0.000310 0.000077 0.000075 0.0000190 0.0000193 0.000032 0.000032 2008 8 11 54689 0.292417 0.385913 -0.4571473 -0.0001604 -0.000045 -0.000304 0.000077 0.000075 0.0000156 0.0000193 0.000031 0.000031 2008 8 12 54690 0.292814 0.382673 -0.4569287 -0.0002327 0.000046 -0.000299 0.000078 0.000075 0.0000088 0.0000193 0.000030 0.000030 2008 8 13 54691 0.293004 0.379247 -0.4567249 -0.0001679 0.000141 -0.000329 0.000078 0.000076 0.0000025 0.0000193 0.000030 0.000029 2008 8 14 54692 0.293078 0.376319 -0.4565987 -0.0000606 0.000227 -0.000385 0.000078 0.000076 0.0000030 0.0000193 0.000030 0.000029 2008 8 15 54693 0.292876 0.373357 -0.4566097 0.0000978 0.000226 -0.000358 0.000078 0.000076 0.0000029 0.0000193 0.000029 0.000028 2008 8 16 54694 0.293603 0.370539 -0.4567874 0.0002679 0.000219 -0.000359 0.000079 0.000076 0.0000027 0.0000192 0.000029 0.000028 2008 8 17 54695 0.294262 0.368083 -0.4571482 0.0004368 0.000207 -0.000388 0.000079 0.000076 0.0000027 0.0000192 0.000029 0.000028 2008 8 18 54696 0.294495 0.365096 -0.4577135 0.0006519 0.000171 -0.000364 0.000079 0.000077 0.0000027 0.0000192 0.000029 0.000028 2008 8 19 54697 0.294800 0.361863 -0.4584646 0.0008075 0.000135 -0.000340 0.000079 0.000077 0.0000030 0.0000191 0.000029 0.000028 2008 8 20 54698 0.295343 0.358691 -0.4593186 0.0008563 0.000132 -0.000352 0.000079 0.000077 0.0000030 0.0000191 0.000029 0.000028 2008 8 21 54699 0.296113 0.355627 -0.4601314 0.0007373 0.000130 -0.000362 0.000079 0.000077 0.0000032 0.0000190 0.000029 0.000028 2008 8 22 54700 0.297038 0.352262 -0.4607849 0.0005582 0.000161 -0.000307 0.000079 0.000077 0.0000030 0.0000190 0.000029 0.000028 2008 8 23 54701 0.298153 0.349030 -0.4612398 0.0003459 0.000165 -0.000272 0.000079 0.000077 0.0000026 0.0000189 0.000029 0.000028 2008 8 24 54702 0.298643 0.346088 -0.4614902 0.0001724 0.000143 -0.000263 0.000079 0.000077 0.0000029 0.0000188 0.000029 0.000028 2008 8 25 54703 0.298256 0.343075 -0.4615811 0.0000504 0.000168 -0.000316 0.000079 0.000077 0.0000032 0.0000187 0.000029 0.000029 2008 8 26 54704 0.297816 0.339451 -0.4616473 0.0000750 0.000139 -0.000306 0.000079 0.000077 0.0000055 0.0000187 0.000030 0.000029 2008 8 27 54705 0.298079 0.335794 -0.4618019 0.0002179 0.000095 -0.000253 0.000078 0.000076 0.0000104 0.0000186 0.000030 0.000030 2008 8 28 54706 0.298242 0.332549 -0.4620757 0.0003691 0.000089 -0.000222 0.000078 0.000076 0.0000146 0.0000186 0.000031 0.000030 2008 8 29 54707 0.298306 0.329497 -0.4625409 0.0005970 0.000133 -0.000229 0.000078 0.000076 0.0000093 0.0000185 0.000031 0.000031 2008 8 30 54708 0.298443 0.326218 -0.4633195 0.0008751 0.000125 -0.000292 0.000078 0.000076 0.0000146 0.0000185 0.000032 0.000031 2008 8 31 54709 0.298650 0.322365 -0.4643005 0.0010149 0.000092 -0.000371 0.000078 0.000076 0.0000158 0.0000185 0.000032 0.000032 2008 9 1 54710 0.298664 0.318536 -0.4653563 0.0010670 0.000059 -0.000450 0.000078 0.000076 0.0000123 0.0000184 0.000033 0.000032 2008 9 2 54711 0.298936 0.314622 -0.4663777 0.0009726 0.000027 -0.000528 0.000078 0.000076 0.0000080 0.0000184 0.000033 0.000033 2008 9 3 54712 0.299264 0.310804 -0.4672694 0.0007794 0.000081 -0.000392 0.000078 0.000076 0.0000035 0.0000184 0.000034 0.000033 2008 9 4 54713 0.299166 0.307213 -0.4679642 0.0005954 0.000076 -0.000348 0.000078 0.000076 0.0000033 0.0000184 0.000034 0.000034 2008 9 5 54714 0.298686 0.303467 -0.4684658 0.0003784 0.000053 -0.000373 0.000077 0.000076 0.0000098 0.0000184 0.000035 0.000035 2008 9 6 54715 0.298263 0.299852 -0.4688018 0.0002401 0.000072 -0.000368 0.000077 0.000076 0.0000122 0.0000184 0.000035 0.000036 2008 9 7 54716 0.297868 0.296360 -0.4689717 0.0001246 0.000106 -0.000348 0.000077 0.000075 0.0000178 0.0000185 0.000036 0.000037 2008 9 8 54717 0.297558 0.292972 -0.4690748 0.0001261 0.000139 -0.000327 0.000077 0.000075 0.0000150 0.0000185 0.000037 0.000038 2008 9 9 54718 0.297281 0.289769 -0.4692037 0.0001909 0.000173 -0.000306 0.000077 0.000075 0.0000065 0.0000185 0.000038 0.000039 2008 9 10 54719 0.296920 0.286620 -0.4694314 0.0003202 0.000161 -0.000268 0.000077 0.000075 0.0000092 0.0000186 0.000039 0.000040 2008 9 11 54720 0.296503 0.283724 -0.4698353 0.0004831 0.000202 -0.000242 0.000076 0.000075 0.0000149 0.0000186 0.000039 0.000042 2008 9 12 54721 0.295857 0.280801 -0.4704744 0.0007596 0.000144 -0.000301 0.000076 0.000075 0.0000090 0.0000186 0.000040 0.000043 2008 9 13 54722 0.294501 0.277710 -0.4714297 0.0010886 -0.000079 -0.000220 0.000076 0.000075 0.0000121 0.0000186 0.000041 0.000044 2008 9 14 54723 0.292778 0.274526 -0.4726549 0.0013431 -0.000348 -0.000077 0.000076 0.000074 0.0000146 0.0000186 0.000041 0.000045 2008 9 15 54724 0.291424 0.271252 -0.4741117 0.0015380 -0.000253 -0.000163 0.000076 0.000074 0.0000129 0.0000186 0.000042 0.000046 2008 9 16 54725 0.290477 0.268147 -0.4757031 0.0016195 0.000037 -0.000370 0.000076 0.000074 0.0000105 0.0000186 0.000043 0.000047 2008 9 17 54726 0.289452 0.265044 -0.4773068 0.0015630 0.000140 -0.000345 0.000076 0.000074 0.0000087 0.0000186 0.000043 0.000048 2008 9 18 54727 0.287902 0.261668 -0.4787789 0.0013741 0.000049 -0.000278 0.000076 0.000074 0.0000070 0.0000186 0.000043 0.000048 2008 9 19 54728 0.286022 0.258149 -0.4800182 0.0010781 -0.000087 -0.000217 0.000076 0.000074 0.0000054 0.0000186 0.000044 0.000049 2008 9 20 54729 0.284176 0.254567 -0.4810042 0.0008509 -0.000102 -0.000202 0.000076 0.000074 0.0000107 0.0000186 0.000044 0.000049 2008 9 21 54730 0.282211 0.251182 -0.4817002 0.0006420 -0.000072 -0.000205 0.000075 0.000073 0.0000131 0.0000185 0.000044 0.000049 2008 9 22 54731 0.280171 0.247789 -0.4822647 0.0005700 -0.000043 -0.000207 0.000075 0.000073 0.0000101 0.0000185 0.000044 0.000050 2008 9 23 54732 0.278311 0.244264 -0.4828449 0.0006138 -0.000014 -0.000210 0.000075 0.000073 0.0000056 0.0000185 0.000044 0.000050 2008 9 24 54733 0.276555 0.240878 -0.4834869 0.0007104 0.000069 -0.000341 0.000075 0.000073 0.0000092 0.0000185 0.000045 0.000051 2008 9 25 54734 0.274731 0.237608 -0.4843171 0.0009195 0.000053 -0.000328 0.000075 0.000073 0.0000097 0.0000185 0.000045 0.000051 2008 9 26 54735 0.273024 0.234334 -0.4853687 0.0011644 0.000004 -0.000263 0.000075 0.000073 0.0000086 0.0000185 0.000045 0.000051 2008 9 27 54736 0.271296 0.230987 -0.4866305 0.0013112 -0.000012 -0.000281 0.000075 0.000073 0.0000134 0.0000185 0.000045 0.000051 2008 9 28 54737 0.269795 0.227826 -0.4880168 0.0014154 -0.000017 -0.000328 0.000075 0.000073 0.0000135 0.0000185 0.000045 0.000051 2008 9 29 54738 0.268291 0.225339 -0.4894439 0.0014033 -0.000021 -0.000376 0.000075 0.000072 0.0000091 0.0000186 0.000045 0.000051 2008 9 30 54739 0.266489 0.222780 -0.4907890 0.0012884 -0.000025 -0.000424 0.000075 0.000072 0.0000040 0.0000186 0.000045 0.000051 2008 10 1 54740 0.264631 0.220283 -0.4920073 0.0011116 0.000079 -0.000476 0.000075 0.000072 0.0000121 0.0000186 0.000046 0.000052 2008 10 2 54741 0.262519 0.217664 -0.4930111 0.0008668 0.000212 -0.000530 0.000074 0.000072 0.0000195 0.0000186 0.000046 0.000052 2008 10 3 54742 0.259859 0.214934 -0.4937445 0.0006478 0.000104 -0.000418 0.000074 0.000072 0.0000110 0.0000186 0.000046 0.000053 2008 10 4 54743 0.256815 0.212284 -0.4942856 0.0004465 0.000047 -0.000356 0.000074 0.000072 0.0000086 0.0000186 0.000046 0.000053 2008 10 5 54744 0.254320 0.209618 -0.4946805 0.0003689 0.000039 -0.000333 0.000074 0.000071 0.0000078 0.0000186 0.000046 0.000053 2008 10 6 54745 0.252101 0.207496 -0.4950082 0.0003316 0.000031 -0.000309 0.000074 0.000071 0.0000078 0.0000186 0.000047 0.000053 2008 10 7 54746 0.249697 0.205500 -0.4953601 0.0003944 0.000023 -0.000286 0.000074 0.000071 0.0000082 0.0000186 0.000047 0.000054 2008 10 8 54747 0.247209 0.203489 -0.4958568 0.0005668 0.000106 -0.000251 0.000074 0.000071 0.0000488 0.0000186 0.000047 0.000054 2008 10 9 54748 0.244818 0.200800 -0.4965249 0.0007805 0.000126 -0.000294 0.000074 0.000071 0.0000400 0.0000187 0.000047 0.000054 2008 10 10 54749 0.242389 0.197811 -0.4974110 0.0010101 0.000019 -0.000463 0.000074 0.000071 0.0000133 0.0000187 0.000047 0.000053 2008 10 11 54750 0.239609 0.194618 -0.4985482 0.0012524 -0.000039 -0.000480 0.000074 0.000071 0.0000076 0.0000187 0.000047 0.000053 2008 10 12 54751 0.237115 0.191615 -0.4999222 0.0014533 -0.000067 -0.000427 0.000074 0.000071 0.0000097 0.0000187 0.000047 0.000053 2008 10 13 54752 0.234729 0.189080 -0.5014414 0.0015671 -0.000094 -0.000375 0.000074 0.000071 0.0000101 0.0000187 0.000047 0.000053 2008 10 14 54753 0.232574 0.186723 -0.5030154 0.0015817 -0.000122 -0.000322 0.000074 0.000071 0.0000095 0.0000188 0.000047 0.000053 2008 10 15 54754 0.229741 0.184680 -0.5045378 0.0014563 -0.000149 -0.000269 0.000074 0.000071 0.0000089 0.0000188 0.000047 0.000053 2008 10 16 54755 0.227076 0.182447 -0.5059427 0.0012948 -0.000112 -0.000302 0.000074 0.000072 0.0000107 0.0000188 0.000047 0.000053 2008 10 17 54756 0.224412 0.180273 -0.5071391 0.0011347 -0.000058 -0.000358 0.000074 0.000072 0.0000131 0.0000188 0.000047 0.000053 2008 10 18 54757 0.221637 0.177796 -0.5081537 0.0009640 -0.000038 -0.000350 0.000074 0.000072 0.0000111 0.0000188 0.000047 0.000052 2008 10 19 54758 0.218903 0.175114 -0.5090686 0.0009661 -0.000031 -0.000320 0.000074 0.000072 0.0000087 0.0000188 0.000047 0.000052 2008 10 20 54759 0.216232 0.172705 -0.5100177 0.0010133 -0.000023 -0.000289 0.000074 0.000072 0.0000063 0.0000188 0.000047 0.000051 2008 10 21 54760 0.213678 0.170484 -0.5111038 0.0011620 -0.000015 -0.000258 0.000074 0.000072 0.0000034 0.0000188 0.000047 0.000051 2008 10 22 54761 0.211374 0.168644 -0.5123172 0.0013192 -0.000034 -0.000284 0.000074 0.000072 0.0000047 0.0000188 0.000048 0.000051 2008 10 23 54762 0.208489 0.166835 -0.5137301 0.0014788 -0.000059 -0.000325 0.000074 0.000072 0.0000071 0.0000188 0.000049 0.000052 2008 10 24 54763 0.205040 0.164895 -0.5153234 0.0016224 -0.000085 -0.000366 0.000074 0.000072 0.0000095 0.0000189 0.000049 0.000052 2008 10 25 54764 0.201165 0.162471 -0.5169633 0.0016514 -0.000088 -0.000365 0.000074 0.000072 0.0000187 0.0000189 0.000050 0.000053 2008 10 26 54765 0.197651 0.159772 -0.5186246 0.0015949 -0.000083 -0.000347 0.000075 0.000072 0.0000318 0.0000189 0.000051 0.000054 2008 10 27 54766 0.195201 0.157777 -0.5202393 0.0015491 -0.000078 -0.000330 0.000075 0.000072 0.0000281 0.0000188 0.000051 0.000055 2008 10 28 54767 0.193299 0.156615 -0.5217037 0.0014251 -0.000073 -0.000312 0.000075 0.000072 0.0000156 0.0000188 0.000052 0.000055 2008 10 29 54768 0.191272 0.155838 -0.5230063 0.0011892 -0.000088 -0.000295 0.000075 0.000072 0.0000121 0.0000188 0.000052 0.000056 2008 10 30 54769 0.188520 0.154366 -0.5240949 0.0009555 -0.000107 -0.000279 0.000075 0.000072 0.0000124 0.0000188 0.000053 0.000056 2008 10 31 54770 0.185694 0.152943 -0.5249606 0.0008174 -0.000127 -0.000262 0.000075 0.000073 0.0000183 0.0000188 0.000053 0.000057 2008 11 1 54771 0.182601 0.151432 -0.5256889 0.0006657 -0.000120 -0.000262 0.000075 0.000073 0.0000108 0.0000188 0.000053 0.000057 2008 11 2 54772 0.179435 0.149559 -0.5263202 0.0006273 -0.000104 -0.000268 0.000075 0.000073 0.0000092 0.0000188 0.000054 0.000058 2008 11 3 54773 0.176550 0.148392 -0.5269231 0.0006378 -0.000088 -0.000274 0.000075 0.000073 0.0000091 0.0000188 0.000054 0.000058 2008 11 4 54774 0.173314 0.147709 -0.5275769 0.0006587 -0.000073 -0.000281 0.000075 0.000073 0.0000071 0.0000187 0.000054 0.000058 2008 11 5 54775 0.169782 0.146664 -0.5282666 0.0007760 -0.000068 -0.000222 0.000075 0.000073 0.0000269 0.0000187 0.000055 0.000059 2008 11 6 54776 0.166482 0.145568 -0.5291036 0.0009312 -0.000067 -0.000147 0.000075 0.000073 0.0000525 0.0000187 0.000055 0.000059 2008 11 7 54777 0.163837 0.144672 -0.5301687 0.0011373 -0.000107 -0.000260 0.000075 0.000073 0.0000218 0.0000187 0.000055 0.000060 2008 11 8 54778 0.160979 0.143853 -0.5314366 0.0013418 -0.000134 -0.000290 0.000075 0.000073 0.0000089 0.0000187 0.000055 0.000060 2008 11 9 54779 0.157775 0.142956 -0.5329028 0.0015615 -0.000151 -0.000265 0.000075 0.000073 0.0000081 0.0000186 0.000056 0.000061 2008 11 10 54780 0.154103 0.142245 -0.5345332 0.0016620 -0.000168 -0.000240 0.000076 0.000073 0.0000066 0.0000186 0.000056 0.000061 2008 11 11 54781 0.150308 0.141049 -0.5361857 0.0016405 -0.000185 -0.000216 0.000076 0.000073 0.0000052 0.0000185 0.000056 0.000061 2008 11 12 54782 0.146792 0.140258 -0.5377822 0.0015284 -0.000248 -0.000331 0.000076 0.000074 0.0000107 0.0000185 0.000056 0.000062 2008 11 13 54783 0.142602 0.139317 -0.5391873 0.0012658 -0.000206 -0.000373 0.000076 0.000074 0.0000365 0.0000185 0.000057 0.000063 2008 11 14 54784 0.138324 0.137888 -0.5402950 0.0009982 -0.000198 -0.000266 0.000076 0.000074 0.0000198 0.0000184 0.000057 0.000063 2008 11 15 54785 0.134512 0.136734 -0.5411528 0.0007858 -0.000164 -0.000220 0.000076 0.000074 0.0000097 0.0000184 0.000057 0.000063 2008 11 16 54786 0.130933 0.136077 -0.5419368 0.0008142 -0.000111 -0.000210 0.000076 0.000074 0.0000107 0.0000183 0.000057 0.000063 2008 11 17 54787 0.126951 0.135733 -0.5428013 0.0009548 -0.000059 -0.000201 0.000076 0.000074 0.0000130 0.0000183 0.000057 0.000064 2008 11 18 54788 0.123187 0.135425 -0.5438709 0.0012100 -0.000006 -0.000191 0.000076 0.000074 0.0000153 0.0000183 0.000058 0.000064 2008 11 19 54789 0.120508 0.135042 -0.5452608 0.0015673 0.000125 -0.000275 0.000076 0.000074 0.0000252 0.0000182 0.000058 0.000064 2008 11 20 54790 0.118465 0.135095 -0.5469385 0.0017665 -0.000014 -0.000381 0.000076 0.000074 0.0000302 0.0000182 0.000058 0.000064 2008 11 21 54791 0.116988 0.135450 -0.5487597 0.0018617 -0.000069 -0.000160 0.000076 0.000074 0.0000149 0.0000182 0.000057 0.000063 2008 11 22 54792 0.115426 0.135975 -0.5506442 0.0018757 -0.000114 -0.000077 0.000076 0.000074 0.0000099 0.0000182 0.000057 0.000062 2008 11 23 54793 0.113433 0.136258 -0.5524895 0.0017615 -0.000177 -0.000087 0.000076 0.000074 0.0000208 0.0000181 0.000056 0.000062 2008 11 24 54794 0.110974 0.136599 -0.5541857 0.0016137 -0.000240 -0.000097 0.000076 0.000074 0.0000191 0.0000181 0.000056 0.000061 2008 11 25 54795 0.107927 0.137368 -0.5557025 0.0014622 -0.000303 -0.000108 0.000076 0.000074 0.0000086 0.0000181 0.000056 0.000061 2008 11 26 54796 0.104396 0.137191 -0.5570743 0.0013137 -0.000265 -0.000037 0.000076 0.000074 0.0000129 0.0000180 0.000055 0.000060 2008 11 27 54797 0.101251 0.136567 -0.5582931 0.0011508 -0.000242 -0.000132 0.000076 0.000074 0.0000144 0.0000180 0.000055 0.000059 2008 11 28 54798 0.098338 0.136185 -0.5593653 0.0010207 -0.000236 -0.000295 0.000076 0.000074 0.0000133 0.0000180 0.000054 0.000058 2008 11 29 54799 0.095180 0.135899 -0.5603336 0.0009262 -0.000213 -0.000279 0.000076 0.000074 0.0000123 0.0000179 0.000053 0.000057 2008 11 30 54800 0.091685 0.135567 -0.5612083 0.0008720 -0.000191 -0.000262 0.000076 0.000074 0.0000089 0.0000179 0.000053 0.000055 2008 12 1 54801 0.088281 0.135322 -0.5620935 0.0009144 -0.000169 -0.000246 0.000077 0.000074 0.0000056 0.0000179 0.000052 0.000054 2008 12 2 54802 0.084682 0.135160 -0.5630662 0.0010318 -0.000147 -0.000230 0.000077 0.000075 0.0000030 0.0000178 0.000051 0.000053 2008 12 3 54803 0.080548 0.135106 -0.5641125 0.0010910 -0.000077 -0.000123 0.000077 0.000075 0.0000162 0.0000178 0.000051 0.000053 2008 12 4 54804 0.075930 0.134978 -0.5653060 0.0012449 -0.000109 -0.000137 0.000077 0.000075 0.0000156 0.0000177 0.000051 0.000053 2008 12 5 54805 0.071735 0.135227 -0.5666588 0.0014704 -0.000176 -0.000192 0.000077 0.000075 0.0000098 0.0000176 0.000051 0.000052 2008 12 6 54806 0.068039 0.135359 -0.5681802 0.0016013 -0.000195 -0.000205 0.000077 0.000075 0.0000078 0.0000176 0.000050 0.000052 2008 12 7 54807 0.064548 0.135162 -0.5698345 0.0016935 -0.000197 -0.000202 0.000077 0.000075 0.0000076 0.0000175 0.000050 0.000052 2008 12 8 54808 0.061416 0.134533 -0.5715368 0.0016600 -0.000199 -0.000199 0.000077 0.000075 0.0000066 0.0000174 0.000050 0.000051 2008 12 9 54809 0.059046 0.134236 -0.5731247 0.0014906 -0.000201 -0.000196 0.000077 0.000075 0.0000054 0.0000173 0.000049 0.000051 2008 12 10 54810 0.056723 0.134787 -0.5744951 0.0012675 -0.000203 -0.000193 0.000077 0.000075 0.0000042 0.0000172 0.000049 0.000050 2008 12 11 54811 0.053646 0.135040 -0.5755993 0.0009892 -0.000194 -0.000156 0.000077 0.000075 0.0000051 0.0000171 0.000049 0.000050 2008 12 12 54812 0.050457 0.134492 -0.5764728 0.0007603 -0.000182 -0.000109 0.000077 0.000075 0.0000065 0.0000170 0.000049 0.000050 2008 12 13 54813 0.047174 0.134409 -0.5771481 0.0006714 -0.000178 -0.000117 0.000077 0.000075 0.0000055 0.0000168 0.000048 0.000050 2008 12 14 54814 0.044693 0.134237 -0.5778595 0.0007902 -0.000176 -0.000147 0.000077 0.000075 0.0000066 0.0000167 0.000048 0.000050 2008 12 15 54815 0.042826 0.134469 -0.5787741 0.0010460 -0.000175 -0.000176 0.000077 0.000075 0.0000057 0.0000166 0.000048 0.000049 2008 12 16 54816 0.040167 0.134867 -0.5799221 0.0012665 -0.000173 -0.000205 0.000077 0.000075 0.0000032 0.0000164 0.000047 0.000049 2008 12 17 54817 0.036904 0.135055 -0.5812425 0.0013810 -0.000162 -0.000243 0.000077 0.000075 0.0000066 0.0000163 0.000048 0.000049 2008 12 18 54818 0.033655 0.135432 -0.5826649 0.0014475 -0.000140 -0.000196 0.000077 0.000075 0.0000057 0.0000161 0.000048 0.000050 2008 12 19 54819 0.030506 0.136005 -0.5841249 0.0014483 -0.000088 -0.000093 0.000077 0.000075 0.0000085 0.0000159 0.000048 0.000050 2008 12 20 54820 0.027465 0.136510 -0.5855222 0.0013523 -0.000099 -0.000083 0.000077 0.000075 0.0000088 0.0000158 0.000048 0.000051 2008 12 21 54821 0.024509 0.137344 -0.5867493 0.0011186 -0.000135 -0.000110 0.000077 0.000075 0.0000081 0.0000156 0.000049 0.000051 2008 12 22 54822 0.021210 0.138120 -0.5877763 0.0009132 -0.000172 -0.000136 0.000077 0.000075 0.0000069 0.0000154 0.000049 0.000052 2008 12 23 54823 0.017967 0.138675 -0.5885878 0.0007418 -0.000209 -0.000163 0.000077 0.000075 0.0000053 0.0000153 0.000049 0.000052 2008 12 24 54824 0.014545 0.139000 -0.5891944 0.0005206 -0.000445 -0.000171 0.000077 0.000075 0.0000900 0.0000151 0.000050 0.000053 2008 12 25 54825 0.010903 0.139414 -0.5895836 0.0003501 -0.000469 -0.000175 0.000077 0.000075 0.0000925 0.0000149 0.000050 0.000053 2008 12 26 54826 0.006718 0.139883 -0.5898430 0.0002087 -0.000397 -0.000179 0.000077 0.000075 0.0000569 0.0000147 0.000049 0.000053 2008 12 27 54827 0.002867 0.140355 -0.5900627 0.0002421 -0.000325 -0.000184 0.000077 0.000075 0.0000212 0.0000145 0.000049 0.000053 2008 12 28 54828 -0.000983 0.141714 -0.5903182 0.0002744 -0.000253 -0.000188 0.000077 0.000075 0.0000097 0.0000143 0.000049 0.000053 2008 12 29 54829 -0.005270 0.143011 -0.5906552 0.0003785 -0.000181 -0.000193 0.000077 0.000075 0.0000078 0.0000141 0.000049 0.000054 2008 12 30 54830 -0.009652 0.144157 -0.5911423 0.0005455 -0.000109 -0.000197 0.000077 0.000075 0.0000049 0.0000139 0.000049 0.000054 2008 12 31 54831 -0.013460 0.144958 -0.5918665 0.0008157 -0.000143 -0.000433 0.000077 0.000075 0.0000124 0.0000137 0.000049 0.000054 2009 1 1 54832 -0.017053 0.146181 0.4071435 0.0010451 -0.000173 -0.000466 0.000077 0.000075 0.0000107 0.0000134 0.000049 0.000053 2009 1 2 54833 -0.020459 0.147402 0.4059555 0.0012313 -0.000187 -0.000379 0.000071 0.000064 0.0000109 0.0000204 0.000036 0.000032 2009 1 3 54834 -0.023237 0.149035 0.4046525 0.0013077 -0.000205 -0.000303 0.000071 0.000064 0.0000105 0.0000203 0.000035 0.000031 2009 1 4 54835 -0.025669 0.150631 0.4033375 0.0013171 -0.000222 -0.000228 0.000071 0.000064 0.0000080 0.0000202 0.000035 0.000031 2009 1 5 54836 -0.028928 0.152679 0.4020601 0.0012206 -0.000240 -0.000152 0.000071 0.000064 0.0000055 0.0000200 0.000035 0.000031 2009 1 6 54837 -0.033330 0.154460 0.4009087 0.0010639 -0.000258 -0.000077 0.000071 0.000064 0.0000030 0.0000199 0.000034 0.000030 2009 1 7 54838 -0.037527 0.156178 0.3999378 0.0008272 -0.000257 -0.000066 0.000072 0.000064 0.0000085 0.0000197 0.000034 0.000030 2009 1 8 54839 -0.041733 0.157987 0.3991882 0.0005972 -0.000252 -0.000073 0.000072 0.000064 0.0000131 0.0000195 0.000034 0.000030 2009 1 9 54840 -0.045902 0.159627 0.3986776 0.0005288 -0.000246 -0.000080 0.000072 0.000064 0.0000062 0.0000193 0.000034 0.000030 2009 1 10 54841 -0.049601 0.161108 0.3981247 0.0006152 -0.000231 -0.000113 0.000072 0.000065 0.0000084 0.0000191 0.000034 0.000030 2009 1 11 54842 -0.053076 0.162674 0.3974354 0.0007922 -0.000212 -0.000155 0.000072 0.000065 0.0000099 0.0000190 0.000034 0.000030 2009 1 12 54843 -0.056510 0.164314 0.3964965 0.0011031 -0.000193 -0.000198 0.000072 0.000065 0.0000076 0.0000189 0.000034 0.000030 2009 1 13 54844 -0.059587 0.166079 0.3952878 0.0013234 -0.000174 -0.000240 0.000072 0.000065 0.0000044 0.0000188 0.000034 0.000030 2009 1 14 54845 -0.062410 0.167667 0.3938595 0.0015007 -0.000159 -0.000150 0.000072 0.000065 0.0000116 0.0000187 0.000034 0.000030 2009 1 15 54846 -0.065314 0.169258 0.3923477 0.0015115 -0.000207 -0.000080 0.000072 0.000065 0.0000096 0.0000186 0.000034 0.000030 2009 1 16 54847 -0.068207 0.170274 0.3908933 0.0013871 -0.000274 -0.000026 0.000072 0.000065 0.0000041 0.0000185 0.000034 0.000030 2009 1 17 54848 -0.070738 0.171334 0.3895976 0.0011899 -0.000328 -0.000014 0.000072 0.000065 0.0000094 0.0000183 0.000034 0.000029 2009 1 18 54849 -0.073260 0.172986 0.3885235 0.0009605 -0.000377 -0.000016 0.000072 0.000065 0.0000136 0.0000182 0.000034 0.000029 2009 1 19 54850 -0.075675 0.174813 0.3877562 0.0006350 -0.000427 -0.000018 0.000073 0.000065 0.0000114 0.0000182 0.000034 0.000029 2009 1 20 54851 -0.078271 0.176995 0.3872620 0.0003752 -0.000476 -0.000020 0.000073 0.000066 0.0000073 0.0000181 0.000034 0.000029 2009 1 21 54852 -0.081096 0.179481 0.3869761 0.0002337 -0.000230 -0.000049 0.000073 0.000066 0.0000031 0.0000181 0.000034 0.000028 2009 1 22 54853 -0.084401 0.181845 0.3868388 0.0000820 -0.000151 -0.000112 0.000073 0.000066 0.0000021 0.0000180 0.000034 0.000028 2009 1 23 54854 -0.087601 0.184158 0.3867876 0.0000532 -0.000185 -0.000123 0.000073 0.000066 0.0000020 0.0000180 0.000034 0.000028 2009 1 24 54855 -0.090170 0.186637 0.3867344 0.0000828 -0.000167 -0.000060 0.000073 0.000066 0.0000070 0.0000179 0.000034 0.000028 2009 1 25 54856 -0.091616 0.189303 0.3866085 0.0002158 -0.000121 0.000024 0.000073 0.000066 0.0000080 0.0000178 0.000035 0.000029 2009 1 26 54857 -0.093195 0.192200 0.3863351 0.0003615 -0.000076 0.000108 0.000073 0.000066 0.0000101 0.0000178 0.000035 0.000029 2009 1 27 54858 -0.094435 0.194761 0.3858806 0.0005479 -0.000030 0.000191 0.000073 0.000065 0.0000144 0.0000178 0.000035 0.000030 2009 1 28 54859 -0.095886 0.197442 0.3851861 0.0007279 -0.000057 0.000150 0.000073 0.000065 0.0000181 0.0000178 0.000035 0.000030 2009 1 29 54860 -0.098039 0.199983 0.3843295 0.0009091 -0.000104 0.000077 0.000073 0.000065 0.0000185 0.0000178 0.000035 0.000030 2009 1 30 54861 -0.100229 0.202552 0.3834283 0.0009738 -0.000151 0.000003 0.000073 0.000065 0.0000068 0.0000177 0.000035 0.000030 2009 1 31 54862 -0.102850 0.205270 0.3824607 0.0009668 -0.000167 -0.000012 0.000073 0.000065 0.0000073 0.0000176 0.000035 0.000030 2009 2 1 54863 -0.105547 0.207977 0.3815331 0.0008676 -0.000172 -0.000005 0.000073 0.000066 0.0000094 0.0000176 0.000035 0.000031 2009 2 2 54864 -0.107599 0.210579 0.3807125 0.0007141 -0.000178 0.000002 0.000073 0.000066 0.0000071 0.0000176 0.000035 0.000031 2009 2 3 54865 -0.108471 0.213476 0.3800410 0.0005622 -0.000183 0.000010 0.000073 0.000066 0.0000033 0.0000176 0.000035 0.000031 2009 2 4 54866 -0.109015 0.216931 0.3795297 0.0004453 -0.000214 -0.000085 0.000073 0.000066 0.0000052 0.0000176 0.000036 0.000032 2009 2 5 54867 -0.110005 0.220683 0.3791001 0.0004231 -0.000212 -0.000101 0.000073 0.000066 0.0000358 0.0000176 0.000036 0.000032 2009 2 6 54868 -0.111620 0.224388 0.3786449 0.0004642 -0.000172 -0.000055 0.000073 0.000066 0.0000143 0.0000175 0.000037 0.000033 2009 2 7 54869 -0.113806 0.227982 0.3781118 0.0006331 -0.000172 -0.000060 0.000073 0.000065 0.0000080 0.0000175 0.000037 0.000033 2009 2 8 54870 -0.115913 0.231397 0.3773339 0.0008873 -0.000188 -0.000088 0.000073 0.000065 0.0000111 0.0000174 0.000037 0.000034 2009 2 9 54871 -0.118127 0.234389 0.3762964 0.0011527 -0.000205 -0.000116 0.000073 0.000065 0.0000088 0.0000174 0.000037 0.000034 2009 2 10 54872 -0.119767 0.237102 0.3750238 0.0013927 -0.000222 -0.000144 0.000073 0.000065 0.0000047 0.0000175 0.000038 0.000035 2009 2 11 54873 -0.120574 0.240305 0.3736042 0.0014533 -0.000287 -0.000063 0.000073 0.000065 0.0000137 0.0000174 0.000038 0.000035 2009 2 12 54874 -0.121352 0.244048 0.3721673 0.0013855 -0.000273 0.000017 0.000073 0.000065 0.0000219 0.0000174 0.000038 0.000035 2009 2 13 54875 -0.122343 0.247667 0.3708957 0.0011499 -0.000086 -0.000004 0.000073 0.000065 0.0000092 0.0000174 0.000038 0.000035 2009 2 14 54876 -0.123670 0.251166 0.3699140 0.0008531 -0.000035 -0.000003 0.000072 0.000065 0.0000102 0.0000173 0.000038 0.000035 2009 2 15 54877 -0.125248 0.254898 0.3691801 0.0006340 -0.000053 0.000016 0.000072 0.000065 0.0000105 0.0000173 0.000038 0.000034 2009 2 16 54878 -0.126775 0.258718 0.3686365 0.0004208 -0.000070 0.000036 0.000072 0.000065 0.0000091 0.0000173 0.000038 0.000034 2009 2 17 54879 -0.128611 0.262126 0.3682746 0.0003088 -0.000087 0.000055 0.000072 0.000064 0.0000073 0.0000173 0.000038 0.000034 2009 2 18 54880 -0.130483 0.265062 0.3680571 0.0002010 -0.000105 0.000075 0.000072 0.000064 0.0000038 0.0000173 0.000038 0.000034 2009 2 19 54881 -0.132392 0.267951 0.3679187 0.0001436 -0.000120 -0.000158 0.000072 0.000064 0.0000066 0.0000173 0.000038 0.000034 2009 2 20 54882 -0.133416 0.270385 0.3677819 0.0001886 -0.000181 -0.000006 0.000072 0.000064 0.0000058 0.0000173 0.000038 0.000034 2009 2 21 54883 -0.133767 0.273001 0.3675957 0.0002323 -0.000186 0.000070 0.000072 0.000064 0.0000119 0.0000172 0.000038 0.000034 2009 2 22 54884 -0.134206 0.275728 0.3673264 0.0003434 -0.000164 0.000062 0.000072 0.000064 0.0000133 0.0000172 0.000038 0.000035 2009 2 23 54885 -0.133787 0.278610 0.3668570 0.0005870 -0.000143 0.000054 0.000072 0.000064 0.0000127 0.0000172 0.000038 0.000035 2009 2 24 54886 -0.133072 0.282072 0.3661489 0.0008446 -0.000121 0.000046 0.000072 0.000064 0.0000094 0.0000172 0.000038 0.000035 2009 2 25 54887 -0.133320 0.285628 0.3652188 0.0009943 -0.000058 0.000089 0.000072 0.000064 0.0000038 0.0000172 0.000038 0.000035 2009 2 26 54888 -0.133544 0.288921 0.3640897 0.0011798 -0.000044 0.000071 0.000072 0.000064 0.0000039 0.0000172 0.000038 0.000035 2009 2 27 54889 -0.133614 0.292500 0.3628416 0.0012667 -0.000045 0.000034 0.000072 0.000064 0.0000055 0.0000172 0.000038 0.000035 2009 2 28 54890 -0.133959 0.296149 0.3615663 0.0012437 -0.000068 0.000027 0.000072 0.000064 0.0000088 0.0000171 0.000038 0.000035 2009 3 1 54891 -0.134386 0.299816 0.3603364 0.0011774 -0.000098 0.000031 0.000072 0.000064 0.0000082 0.0000171 0.000038 0.000035 2009 3 2 54892 -0.134834 0.303239 0.3591913 0.0010442 -0.000129 0.000035 0.000072 0.000064 0.0000056 0.0000171 0.000038 0.000034 2009 3 3 54893 -0.134821 0.306323 0.3581891 0.0009535 -0.000159 0.000039 0.000072 0.000064 0.0000032 0.0000171 0.000037 0.000034 2009 3 4 54894 -0.134187 0.309596 0.3573157 0.0008108 -0.000084 0.000102 0.000072 0.000064 0.0000179 0.0000171 0.000037 0.000034 2009 3 5 54895 -0.133699 0.313184 0.3565658 0.0007188 -0.000052 0.000047 0.000072 0.000064 0.0000156 0.0000170 0.000037 0.000034 2009 3 6 54896 -0.133416 0.316800 0.3557903 0.0008383 -0.000041 -0.000047 0.000072 0.000064 0.0000068 0.0000170 0.000037 0.000033 2009 3 7 54897 -0.133150 0.320693 0.3548775 0.0010275 -0.000047 -0.000046 0.000072 0.000064 0.0000082 0.0000169 0.000036 0.000033 2009 3 8 54898 -0.133002 0.324577 0.3537724 0.0012155 -0.000059 -0.000009 0.000072 0.000064 0.0000099 0.0000169 0.000036 0.000032 2009 3 9 54899 -0.132832 0.328792 0.3523789 0.0015357 -0.000071 0.000027 0.000072 0.000064 0.0000094 0.0000169 0.000036 0.000032 2009 3 10 54900 -0.132508 0.332929 0.3507474 0.0017307 -0.000083 0.000063 0.000072 0.000064 0.0000070 0.0000169 0.000035 0.000031 2009 3 11 54901 -0.132157 0.336777 0.3490096 0.0017706 -0.000096 0.000100 0.000072 0.000064 0.0000037 0.0000169 0.000035 0.000031 2009 3 12 54902 -0.132009 0.340618 0.3472847 0.0016690 -0.000129 0.000120 0.000072 0.000064 0.0000035 0.0000169 0.000035 0.000030 2009 3 13 54903 -0.131800 0.343855 0.3457014 0.0014983 -0.000169 0.000136 0.000072 0.000064 0.0000042 0.0000168 0.000035 0.000030 2009 3 14 54904 -0.130924 0.346694 0.3442850 0.0012703 -0.000164 0.000139 0.000072 0.000064 0.0000460 0.0000168 0.000035 0.000030 2009 3 15 54905 -0.130357 0.350105 0.3431745 0.0010083 -0.000142 0.000137 0.000072 0.000064 0.0000309 0.0000168 0.000035 0.000030 2009 3 16 54906 -0.129490 0.353263 0.3422886 0.0008362 -0.000121 0.000135 0.000072 0.000064 0.0000098 0.0000168 0.000035 0.000030 2009 3 17 54907 -0.128463 0.356563 0.3415471 0.0006490 -0.000100 0.000134 0.000072 0.000064 0.0000037 0.0000168 0.000035 0.000030 2009 3 18 54908 -0.127685 0.359846 0.3409379 0.0005672 -0.000080 0.000112 0.000072 0.000064 0.0000027 0.0000168 0.000035 0.000030 2009 3 19 54909 -0.127284 0.363323 0.3403549 0.0005952 -0.000060 0.000085 0.000072 0.000064 0.0000032 0.0000168 0.000035 0.000031 2009 3 20 54910 -0.126884 0.366791 0.3397125 0.0006636 -0.000041 0.000058 0.000072 0.000064 0.0000036 0.0000168 0.000035 0.000031 2009 3 21 54911 -0.126042 0.370090 0.3389364 0.0008604 -0.000046 0.000069 0.000072 0.000064 0.0000085 0.0000167 0.000036 0.000031 2009 3 22 54912 -0.124886 0.373600 0.3379322 0.0011358 -0.000061 0.000095 0.000072 0.000064 0.0000117 0.0000167 0.000036 0.000032 2009 3 23 54913 -0.123473 0.376806 0.3366831 0.0013492 -0.000075 0.000120 0.000072 0.000064 0.0000091 0.0000168 0.000036 0.000032 2009 3 24 54914 -0.122067 0.380424 0.3352237 0.0015390 -0.000090 0.000146 0.000072 0.000064 0.0000043 0.0000168 0.000037 0.000032 2009 3 25 54915 -0.120897 0.384307 0.3336133 0.0016351 -0.000120 0.000101 0.000072 0.000064 0.0000081 0.0000168 0.000037 0.000032 2009 3 26 54916 -0.119873 0.387919 0.3319239 0.0016709 -0.000155 0.000038 0.000072 0.000064 0.0000117 0.0000168 0.000037 0.000033 2009 3 27 54917 -0.119172 0.391560 0.3302884 0.0016253 -0.000077 0.000056 0.000072 0.000064 0.0000061 0.0000168 0.000037 0.000032 2009 3 28 54918 -0.118443 0.394921 0.3287291 0.0014933 -0.000036 0.000087 0.000072 0.000064 0.0000076 0.0000167 0.000037 0.000032 2009 3 29 54919 -0.118004 0.398157 0.3273503 0.0012593 -0.000008 0.000123 0.000072 0.000064 0.0000097 0.0000167 0.000037 0.000032 2009 3 30 54920 -0.118376 0.400813 0.3262107 0.0010045 0.000019 0.000159 0.000071 0.000064 0.0000077 0.0000167 0.000037 0.000032 2009 3 31 54921 -0.118972 0.403551 0.3252896 0.0008384 0.000047 0.000195 0.000071 0.000063 0.0000041 0.0000167 0.000037 0.000031 2009 4 1 54922 -0.118909 0.405905 0.3244933 0.0007816 0.000069 0.000167 0.000071 0.000063 0.0000035 0.0000167 0.000037 0.000031 2009 4 2 54923 -0.117845 0.408306 0.3237170 0.0008287 0.000090 0.000122 0.000071 0.000063 0.0000037 0.0000167 0.000037 0.000031 2009 4 3 54924 -0.116487 0.410914 0.3228417 0.0009390 0.000112 0.000078 0.000071 0.000063 0.0000039 0.0000167 0.000037 0.000031 2009 4 4 54925 -0.115185 0.413639 0.3218176 0.0011153 0.000079 0.000099 0.000071 0.000063 0.0000072 0.0000166 0.000036 0.000030 2009 4 5 54926 -0.113298 0.416387 0.3205732 0.0013212 0.000026 0.000144 0.000071 0.000063 0.0000074 0.0000166 0.000036 0.000030 2009 4 6 54927 -0.110754 0.419490 0.3191025 0.0015715 -0.000027 0.000190 0.000071 0.000063 0.0000056 0.0000166 0.000036 0.000030 2009 4 7 54928 -0.108392 0.423079 0.3174741 0.0017296 -0.000079 0.000235 0.000071 0.000063 0.0000037 0.0000166 0.000036 0.000029 2009 4 8 54929 -0.106843 0.426127 0.3157101 0.0017741 0.000079 0.000184 0.000071 0.000063 0.0000029 0.0000166 0.000036 0.000029 2009 4 9 54930 -0.105304 0.428841 0.3139828 0.0016345 0.000102 0.000075 0.000071 0.000063 0.0000080 0.0000166 0.000036 0.000029 2009 4 10 54931 -0.103770 0.431639 0.3123869 0.0014706 0.000097 0.000061 0.000071 0.000063 0.0000118 0.0000165 0.000036 0.000029 2009 4 11 54932 -0.102321 0.434601 0.3110027 0.0012902 0.000103 0.000086 0.000071 0.000063 0.0000121 0.0000165 0.000036 0.000029 2009 4 12 54933 -0.100753 0.437083 0.3098686 0.0010404 0.000109 0.000110 0.000071 0.000063 0.0000135 0.0000165 0.000036 0.000029 2009 4 13 54934 -0.098622 0.439492 0.3089493 0.0008206 0.000114 0.000134 0.000071 0.000063 0.0000125 0.0000165 0.000035 0.000029 2009 4 14 54935 -0.096561 0.442381 0.3081687 0.0007026 0.000120 0.000159 0.000070 0.000063 0.0000079 0.0000164 0.000035 0.000029 2009 4 15 54936 -0.094102 0.445592 0.3074334 0.0007445 0.000126 0.000183 0.000070 0.000063 0.0000033 0.0000164 0.000035 0.000029 2009 4 16 54937 -0.091421 0.449126 0.3066503 0.0008240 0.000076 0.000155 0.000070 0.000063 0.0000068 0.0000164 0.000035 0.000029 2009 4 17 54938 -0.088929 0.452444 0.3057535 0.0009625 0.000078 0.000142 0.000070 0.000063 0.0000052 0.0000163 0.000035 0.000028 2009 4 18 54939 -0.086865 0.455384 0.3047113 0.0011086 0.000076 0.000108 0.000070 0.000062 0.0000088 0.0000162 0.000035 0.000028 2009 4 19 54940 -0.084839 0.458188 0.3035233 0.0012653 0.000065 0.000063 0.000070 0.000062 0.0000105 0.0000162 0.000035 0.000028 2009 4 20 54941 -0.082719 0.460829 0.3021439 0.0014797 0.000053 0.000017 0.000070 0.000062 0.0000082 0.0000162 0.000035 0.000028 2009 4 21 54942 -0.080472 0.463474 0.3005765 0.0016901 0.000042 -0.000028 0.000070 0.000062 0.0000050 0.0000162 0.000035 0.000028 2009 4 22 54943 -0.078487 0.466323 0.2988254 0.0018296 0.000033 -0.000012 0.000070 0.000063 0.0000030 0.0000162 0.000035 0.000027 2009 4 23 54944 -0.076882 0.469242 0.2970232 0.0018033 0.000025 0.000078 0.000070 0.000063 0.0000045 0.0000161 0.000035 0.000027 2009 4 24 54945 -0.075915 0.471600 0.2952631 0.0016823 0.000016 0.000185 0.000070 0.000063 0.0000068 0.0000161 0.000036 0.000027 2009 4 25 54946 -0.075008 0.473811 0.2936368 0.0015171 0.000036 0.000196 0.000070 0.000063 0.0000105 0.0000161 0.000036 0.000027 2009 4 26 54947 -0.073801 0.476103 0.2922287 0.0013051 0.000066 0.000173 0.000070 0.000063 0.0000120 0.0000160 0.000036 0.000027 2009 4 27 54948 -0.072005 0.478033 0.2910227 0.0011059 0.000096 0.000149 0.000070 0.000063 0.0000086 0.0000161 0.000036 0.000027 2009 4 28 54949 -0.069822 0.480077 0.2899653 0.0010258 0.000125 0.000125 0.000071 0.000063 0.0000034 0.0000161 0.000036 0.000027 2009 4 29 54950 -0.067653 0.482263 0.2889698 0.0010179 0.000165 0.000163 0.000071 0.000063 0.0000031 0.0000161 0.000036 0.000027 2009 4 30 54951 -0.065236 0.484340 0.2879086 0.0010934 0.000208 0.000218 0.000071 0.000063 0.0000041 0.0000161 0.000036 0.000027 2009 5 1 54952 -0.062359 0.486436 0.2866979 0.0013197 0.000183 0.000221 0.000071 0.000063 0.0000075 0.0000161 0.000036 0.000028 2009 5 2 54953 -0.059562 0.488649 0.2852853 0.0015013 0.000134 0.000206 0.000071 0.000063 0.0000118 0.0000160 0.000036 0.000028 2009 5 3 54954 -0.056728 0.490447 0.2836683 0.0017047 0.000085 0.000191 0.000071 0.000063 0.0000140 0.0000160 0.000036 0.000028 2009 5 4 54955 -0.053909 0.492383 0.2819113 0.0018126 0.000035 0.000175 0.000071 0.000063 0.0000129 0.0000161 0.000036 0.000028 2009 5 5 54956 -0.051590 0.494270 0.2801297 0.0017508 -0.000014 0.000160 0.000071 0.000063 0.0000106 0.0000161 0.000036 0.000028 2009 5 6 54957 -0.048995 0.495821 0.2784292 0.0016628 0.000043 0.000163 0.000072 0.000064 0.0000076 0.0000161 0.000036 0.000028 2009 5 7 54958 -0.045810 0.497630 0.2769037 0.0014184 0.000127 0.000172 0.000072 0.000064 0.0000044 0.0000162 0.000036 0.000028 2009 5 8 54959 -0.042756 0.499717 0.2756356 0.0011141 0.000140 0.000161 0.000072 0.000064 0.0000072 0.0000162 0.000036 0.000027 2009 5 9 54960 -0.039659 0.502086 0.2746515 0.0008759 0.000128 0.000144 0.000072 0.000064 0.0000119 0.0000162 0.000036 0.000027 2009 5 10 54961 -0.036628 0.504356 0.2739072 0.0006784 0.000115 0.000126 0.000072 0.000064 0.0000106 0.0000162 0.000036 0.000026 2009 5 11 54962 -0.033630 0.506097 0.2732871 0.0005504 0.000103 0.000108 0.000072 0.000064 0.0000069 0.0000162 0.000035 0.000026 2009 5 12 54963 -0.031113 0.507812 0.2727621 0.0005261 0.000090 0.000091 0.000072 0.000064 0.0000031 0.0000162 0.000035 0.000026 2009 5 13 54964 -0.028548 0.509829 0.2722362 0.0005456 0.000104 0.000070 0.000072 0.000064 0.0000023 0.0000163 0.000035 0.000025 2009 5 14 54965 -0.025798 0.511814 0.2716504 0.0006413 0.000124 0.000048 0.000073 0.000064 0.0000023 0.0000163 0.000035 0.000025 2009 5 15 54966 -0.023132 0.513842 0.2709409 0.0007801 0.000176 0.000077 0.000073 0.000064 0.0000028 0.0000163 0.000035 0.000026 2009 5 16 54967 -0.020229 0.515407 0.2700837 0.0009252 0.000186 0.000084 0.000073 0.000064 0.0000123 0.0000162 0.000035 0.000026 2009 5 17 54968 -0.016658 0.516863 0.2690887 0.0010471 0.000177 0.000075 0.000073 0.000064 0.0000144 0.0000162 0.000036 0.000026 2009 5 18 54969 -0.013001 0.518503 0.2679578 0.0012022 0.000167 0.000067 0.000073 0.000064 0.0000095 0.0000163 0.000036 0.000027 2009 5 19 54970 -0.009398 0.520179 0.2666888 0.0013775 0.000157 0.000058 0.000073 0.000064 0.0000038 0.0000163 0.000036 0.000027 2009 5 20 54971 -0.005986 0.521636 0.2652501 0.0014927 0.000178 -0.000139 0.000073 0.000064 0.0000029 0.0000163 0.000036 0.000028 2009 5 21 54972 -0.002641 0.522674 0.2637763 0.0014552 0.000203 -0.000106 0.000073 0.000064 0.0000032 0.0000164 0.000036 0.000028 2009 5 22 54973 0.000612 0.524000 0.2623811 0.0013192 0.000226 0.000011 0.000073 0.000064 0.0000035 0.0000164 0.000036 0.000029 2009 5 23 54974 0.003583 0.525282 0.2611662 0.0011359 0.000227 0.000043 0.000073 0.000064 0.0000112 0.0000164 0.000037 0.000029 2009 5 24 54975 0.007038 0.526213 0.2601180 0.0009754 0.000219 0.000042 0.000073 0.000064 0.0000124 0.0000164 0.000037 0.000030 2009 5 25 54976 0.010812 0.527455 0.2592484 0.0008079 0.000211 0.000042 0.000073 0.000064 0.0000116 0.0000164 0.000037 0.000031 2009 5 26 54977 0.013860 0.528772 0.2585230 0.0007267 0.000203 0.000041 0.000073 0.000064 0.0000086 0.0000165 0.000038 0.000031 2009 5 27 54978 0.016578 0.530093 0.2577892 0.0007660 0.000245 0.000119 0.000073 0.000064 0.0000040 0.0000165 0.000038 0.000032 2009 5 28 54979 0.019338 0.531562 0.2569361 0.0009229 0.000218 0.000055 0.000073 0.000064 0.0000036 0.0000165 0.000038 0.000032 2009 5 29 54980 0.021744 0.532723 0.2558836 0.0011702 0.000172 -0.000046 0.000072 0.000064 0.0000042 0.0000165 0.000038 0.000033 2009 5 30 54981 0.024489 0.533386 0.2546023 0.0013831 0.000164 -0.000054 0.000072 0.000064 0.0000104 0.0000165 0.000039 0.000033 2009 5 31 54982 0.027770 0.533710 0.2531507 0.0014574 0.000169 -0.000028 0.000072 0.000064 0.0000150 0.0000165 0.000039 0.000033 2009 6 1 54983 0.031482 0.533557 0.2516973 0.0013960 0.000173 -0.000002 0.000072 0.000064 0.0000139 0.0000166 0.000039 0.000034 2009 6 2 54984 0.035442 0.533661 0.2503438 0.0013021 0.000178 0.000024 0.000072 0.000064 0.0000110 0.0000166 0.000039 0.000034 2009 6 3 54985 0.039497 0.534331 0.2491542 0.0011107 0.000183 0.000050 0.000072 0.000064 0.0000080 0.0000166 0.000039 0.000034 2009 6 4 54986 0.043741 0.535168 0.2481759 0.0008626 0.000151 0.000007 0.000072 0.000064 0.0000087 0.0000166 0.000039 0.000035 2009 6 5 54987 0.048067 0.536517 0.2474236 0.0006116 0.000109 -0.000055 0.000072 0.000064 0.0000105 0.0000166 0.000040 0.000035 2009 6 6 54988 0.051774 0.537832 0.2468890 0.0004575 0.000108 -0.000049 0.000072 0.000064 0.0000113 0.0000166 0.000039 0.000034 2009 6 7 54989 0.055247 0.538817 0.2464878 0.0003231 0.000121 -0.000018 0.000072 0.000064 0.0000137 0.0000165 0.000039 0.000034 2009 6 8 54990 0.058638 0.539490 0.2462047 0.0002374 0.000134 0.000013 0.000072 0.000064 0.0000103 0.0000165 0.000039 0.000034 2009 6 9 54991 0.061713 0.540076 0.2459647 0.0002556 0.000148 0.000044 0.000072 0.000064 0.0000037 0.0000165 0.000039 0.000033 2009 6 10 54992 0.064290 0.540500 0.2456586 0.0003509 0.000181 0.000026 0.000072 0.000064 0.0000028 0.0000165 0.000039 0.000033 2009 6 11 54993 0.067455 0.540336 0.2452444 0.0004718 0.000220 -0.000005 0.000072 0.000064 0.0000034 0.0000165 0.000039 0.000033 2009 6 12 54994 0.071011 0.540513 0.2446380 0.0006745 0.000233 -0.000019 0.000072 0.000063 0.0000114 0.0000164 0.000039 0.000034 2009 6 13 54995 0.074687 0.541041 0.2438876 0.0008237 0.000238 -0.000027 0.000072 0.000063 0.0000190 0.0000164 0.000039 0.000034 2009 6 14 54996 0.078521 0.541533 0.2430614 0.0008888 0.000242 -0.000034 0.000072 0.000063 0.0000182 0.0000163 0.000039 0.000035 2009 6 15 54997 0.082225 0.541868 0.2421289 0.0009488 0.000247 -0.000041 0.000072 0.000063 0.0000156 0.0000163 0.000040 0.000035 2009 6 16 54998 0.085615 0.541835 0.2411449 0.0010353 0.000251 -0.000049 0.000072 0.000063 0.0000113 0.0000163 0.000040 0.000036 2009 6 17 54999 0.088589 0.541738 0.2401099 0.0010271 0.000203 -0.000015 0.000072 0.000063 0.0000087 0.0000163 0.000040 0.000036 2009 6 18 55000 0.091163 0.541160 0.2391441 0.0008861 0.000141 0.000029 0.000072 0.000063 0.0000065 0.0000163 0.000040 0.000036 2009 6 19 55001 0.094032 0.540640 0.2383439 0.0007175 0.000078 0.000073 0.000072 0.000063 0.0000043 0.0000163 0.000040 0.000036 2009 6 20 55002 0.097209 0.540459 0.2377284 0.0005254 0.000087 0.000064 0.000072 0.000063 0.0000115 0.0000163 0.000040 0.000036 2009 6 21 55003 0.100322 0.540346 0.2373304 0.0003289 0.000122 0.000035 0.000072 0.000063 0.0000158 0.0000163 0.000040 0.000037 2009 6 22 55004 0.103094 0.539800 0.2371297 0.0001705 0.000157 0.000006 0.000072 0.000063 0.0000120 0.0000163 0.000040 0.000037 2009 6 23 55005 0.105938 0.539081 0.2369989 0.0001181 0.000192 -0.000023 0.000072 0.000063 0.0000057 0.0000163 0.000040 0.000037 2009 6 24 55006 0.109188 0.538398 0.2368314 0.0002202 0.000190 -0.000056 0.000072 0.000063 0.0000145 0.0000163 0.000041 0.000037 2009 6 25 55007 0.112476 0.537946 0.2365320 0.0003939 0.000234 -0.000037 0.000072 0.000063 0.0000133 0.0000163 0.000041 0.000037 2009 6 26 55008 0.115400 0.537547 0.2360367 0.0005645 0.000294 -0.000003 0.000072 0.000063 0.0000080 0.0000163 0.000041 0.000038 2009 6 27 55009 0.118050 0.537266 0.2353492 0.0007064 0.000282 -0.000015 0.000071 0.000063 0.0000138 0.0000163 0.000041 0.000038 2009 6 28 55010 0.120813 0.536685 0.2346059 0.0007424 0.000242 -0.000045 0.000071 0.000063 0.0000201 0.0000163 0.000041 0.000038 2009 6 29 55011 0.123634 0.535923 0.2339186 0.0006174 0.000203 -0.000074 0.000071 0.000063 0.0000149 0.0000163 0.000042 0.000038 2009 6 30 55012 0.126771 0.534727 0.2333902 0.0004073 0.000163 -0.000103 0.000071 0.000063 0.0000051 0.0000163 0.000042 0.000038 2009 7 1 55013 0.130350 0.533629 0.2330926 0.0001549 0.000205 -0.000031 0.000071 0.000063 0.0000040 0.0000163 0.000042 0.000039 2009 7 2 55014 0.134265 0.532541 0.2330292 -0.0000530 0.000268 0.000067 0.000071 0.000063 0.0000051 0.0000163 0.000043 0.000039 2009 7 3 55015 0.138448 0.531559 0.2331450 -0.0002126 0.000255 0.000067 0.000071 0.000063 0.0000086 0.0000163 0.000043 0.000040 2009 7 4 55016 0.142514 0.531010 0.2334145 -0.0003274 0.000214 0.000031 0.000071 0.000063 0.0000129 0.0000163 0.000044 0.000041 2009 7 5 55017 0.146031 0.530369 0.2337901 -0.0004333 0.000174 -0.000004 0.000071 0.000063 0.0000128 0.0000163 0.000044 0.000041 2009 7 6 55018 0.149156 0.529582 0.2342189 -0.0004417 0.000133 -0.000040 0.000071 0.000063 0.0000093 0.0000163 0.000045 0.000042 2009 7 7 55019 0.152133 0.528726 0.2346263 -0.0003865 0.000092 -0.000076 0.000072 0.000063 0.0000053 0.0000164 0.000045 0.000043 2009 7 8 55020 0.154831 0.527633 0.2349503 -0.0002706 0.000142 -0.000022 0.000072 0.000063 0.0000051 0.0000164 0.000046 0.000043 2009 7 9 55021 0.157212 0.526706 0.2351440 -0.0001287 0.000216 0.000055 0.000072 0.000063 0.0000058 0.0000164 0.000046 0.000044 2009 7 10 55022 0.159832 0.525691 0.2351992 -0.0000101 0.000138 -0.000119 0.000072 0.000063 0.0000061 0.0000165 0.000047 0.000044 2009 7 11 55023 0.162750 0.524901 0.2351159 0.0001369 0.000115 -0.000143 0.000072 0.000064 0.0000152 0.0000165 0.000047 0.000045 2009 7 12 55024 0.165839 0.524146 0.2348761 0.0003007 0.000131 -0.000082 0.000072 0.000064 0.0000147 0.0000165 0.000047 0.000045 2009 7 13 55025 0.168986 0.523402 0.2345838 0.0003149 0.000146 -0.000021 0.000072 0.000064 0.0000095 0.0000165 0.000047 0.000045 2009 7 14 55026 0.171922 0.522299 0.2342849 0.0003025 0.000162 0.000040 0.000072 0.000064 0.0000053 0.0000166 0.000048 0.000045 2009 7 15 55027 0.175535 0.521192 0.2339957 0.0002678 0.000168 0.000010 0.000072 0.000064 0.0000051 0.0000166 0.000048 0.000045 2009 7 16 55028 0.179211 0.520062 0.2337961 0.0000948 0.000172 -0.000043 0.000072 0.000064 0.0000058 0.0000166 0.000048 0.000045 2009 7 17 55029 0.182725 0.518871 0.2337415 -0.0000092 0.000176 -0.000097 0.000072 0.000064 0.0000066 0.0000166 0.000048 0.000045 2009 7 18 55030 0.185930 0.518315 0.2337926 -0.0001148 0.000180 -0.000100 0.000072 0.000064 0.0000109 0.0000166 0.000049 0.000045 2009 7 19 55031 0.188836 0.517323 0.2339470 -0.0001626 0.000183 -0.000083 0.000072 0.000064 0.0000196 0.0000166 0.000049 0.000045 2009 7 20 55032 0.191894 0.515938 0.2341207 -0.0001089 0.000186 -0.000067 0.000073 0.000064 0.0000449 0.0000167 0.000049 0.000045 2009 7 21 55033 0.194967 0.514816 0.2341910 -0.0000092 0.000189 -0.000050 0.000073 0.000064 0.0000778 0.0000167 0.000049 0.000044 2009 7 22 55034 0.197942 0.513584 0.2341102 0.0001532 0.000298 -0.000045 0.000073 0.000064 0.0000177 0.0000167 0.000049 0.000044 2009 7 23 55035 0.200699 0.512213 0.2338207 0.0003754 0.000313 -0.000073 0.000073 0.000064 0.0000054 0.0000168 0.000048 0.000043 2009 7 24 55036 0.203111 0.510605 0.2332871 0.0005924 0.000283 -0.000040 0.000073 0.000064 0.0000055 0.0000168 0.000048 0.000043 2009 7 25 55037 0.205401 0.508760 0.2325548 0.0007545 0.000276 -0.000056 0.000073 0.000064 0.0000092 0.0000167 0.000048 0.000042 2009 7 26 55038 0.207804 0.506869 0.2317889 0.0007288 0.000280 -0.000097 0.000073 0.000064 0.0000141 0.0000167 0.000048 0.000042 2009 7 27 55039 0.210596 0.504791 0.2310801 0.0006372 0.000284 -0.000139 0.000073 0.000064 0.0000133 0.0000168 0.000047 0.000042 2009 7 28 55040 0.213304 0.502761 0.2305487 0.0004691 0.000288 -0.000180 0.000073 0.000064 0.0000096 0.0000168 0.000047 0.000041 2009 7 29 55041 0.215607 0.500224 0.2302534 0.0002152 0.000247 -0.000181 0.000073 0.000064 0.0000071 0.0000168 0.000047 0.000041 2009 7 30 55042 0.217599 0.497833 0.2301803 -0.0000284 0.000195 -0.000170 0.000073 0.000064 0.0000049 0.0000168 0.000047 0.000040 2009 7 31 55043 0.219511 0.495528 0.2303164 -0.0001991 0.000230 -0.000030 0.000073 0.000064 0.0000058 0.0000168 0.000047 0.000040 2009 8 1 55044 0.221772 0.492945 0.2305639 -0.0003059 0.000270 -0.000009 0.000073 0.000064 0.0000146 0.0000167 0.000047 0.000040 2009 8 2 55045 0.223951 0.490333 0.2309289 -0.0003315 0.000301 -0.000048 0.000073 0.000064 0.0000184 0.0000167 0.000047 0.000040 2009 8 3 55046 0.225934 0.487611 0.2312319 -0.0002410 0.000331 -0.000088 0.000073 0.000064 0.0000173 0.0000167 0.000047 0.000041 2009 8 4 55047 0.227921 0.485014 0.2314042 -0.0001207 0.000362 -0.000127 0.000073 0.000064 0.0000156 0.0000168 0.000047 0.000041 2009 8 5 55048 0.229989 0.482357 0.2314710 0.0000111 0.000340 -0.000125 0.000073 0.000064 0.0000195 0.0000168 0.000047 0.000041 2009 8 6 55049 0.231987 0.479942 0.2313662 0.0001931 0.000305 -0.000111 0.000073 0.000064 0.0000211 0.0000168 0.000047 0.000040 2009 8 7 55050 0.234179 0.477546 0.2310590 0.0003799 0.000269 -0.000097 0.000073 0.000064 0.0000080 0.0000167 0.000047 0.000040 2009 8 8 55051 0.236330 0.475321 0.2306060 0.0005322 0.000281 -0.000059 0.000073 0.000064 0.0000098 0.0000167 0.000047 0.000040 2009 8 9 55052 0.238379 0.473157 0.2300057 0.0006254 0.000310 -0.000011 0.000073 0.000064 0.0000147 0.0000167 0.000047 0.000041 2009 8 10 55053 0.240417 0.470745 0.2293411 0.0006508 0.000338 0.000037 0.000073 0.000064 0.0000139 0.0000168 0.000047 0.000041 2009 8 11 55054 0.242375 0.468255 0.2287046 0.0006089 0.000367 0.000085 0.000073 0.000064 0.0000110 0.0000168 0.000048 0.000041 2009 8 12 55055 0.244498 0.465657 0.2281772 0.0004779 0.000255 0.000031 0.000073 0.000064 0.0000088 0.0000169 0.000048 0.000042 2009 8 13 55056 0.246681 0.463301 0.2278050 0.0002667 0.000105 -0.000050 0.000073 0.000064 0.0000069 0.0000169 0.000048 0.000042 2009 8 14 55057 0.248550 0.461304 0.2276092 0.0001029 -0.000045 -0.000131 0.000073 0.000064 0.0000050 0.0000169 0.000048 0.000042 2009 8 15 55058 0.249930 0.459166 0.2275898 -0.0000429 -0.000003 -0.000142 0.000073 0.000064 0.0000142 0.0000169 0.000048 0.000042 2009 8 16 55059 0.251524 0.456832 0.2276471 -0.0000996 0.000110 -0.000126 0.000073 0.000064 0.0000148 0.0000169 0.000048 0.000042 2009 8 17 55060 0.252871 0.454374 0.2277038 -0.0000030 0.000224 -0.000110 0.000073 0.000065 0.0000099 0.0000170 0.000048 0.000042 2009 8 18 55061 0.253980 0.451996 0.2276204 0.0002358 0.000337 -0.000094 0.000073 0.000065 0.0000055 0.0000170 0.000048 0.000042 2009 8 19 55062 0.254936 0.449604 0.2272310 0.0005319 0.000282 -0.000099 0.000073 0.000065 0.0000096 0.0000170 0.000048 0.000042 2009 8 20 55063 0.256190 0.447091 0.2265509 0.0007584 0.000184 -0.000109 0.000073 0.000065 0.0000135 0.0000170 0.000049 0.000043 2009 8 21 55064 0.257962 0.444729 0.2256787 0.0009482 0.000085 -0.000119 0.000073 0.000065 0.0000086 0.0000170 0.000049 0.000043 2009 8 22 55065 0.259765 0.442483 0.2246937 0.0010098 0.000088 -0.000113 0.000073 0.000065 0.0002352 0.0000170 0.000049 0.000043 2009 8 23 55066 0.260874 0.440347 0.2237316 0.0008710 0.000127 -0.000101 0.000073 0.000065 0.0001277 0.0000170 0.000049 0.000043 2009 8 24 55067 0.261909 0.438033 0.2229126 0.0006870 0.000167 -0.000088 0.000073 0.000065 0.0000153 0.0000171 0.000049 0.000044 2009 8 25 55068 0.263037 0.435819 0.2223147 0.0004741 0.000206 -0.000076 0.000073 0.000065 0.0000095 0.0000171 0.000049 0.000044 2009 8 26 55069 0.264223 0.433536 0.2219418 0.0002838 0.000210 -0.000072 0.000073 0.000065 0.0000121 0.0000171 0.000049 0.000044 2009 8 27 55070 0.265349 0.431150 0.2217324 0.0001282 0.000236 -0.000144 0.000073 0.000065 0.0000168 0.0000171 0.000049 0.000044 2009 8 28 55071 0.266402 0.428723 0.2216388 0.0000406 0.000272 -0.000238 0.000073 0.000065 0.0000216 0.0000171 0.000049 0.000043 2009 8 29 55072 0.267565 0.426184 0.2215504 0.0000516 0.000301 -0.000235 0.000073 0.000065 0.0000455 0.0000171 0.000048 0.000043 2009 8 30 55073 0.268856 0.423541 0.2214840 0.0000898 0.000329 -0.000204 0.000073 0.000065 0.0000311 0.0000171 0.000048 0.000042 2009 8 31 55074 0.269878 0.420804 0.2213859 0.0001719 0.000356 -0.000174 0.000073 0.000065 0.0000136 0.0000172 0.000048 0.000042 2009 9 1 55075 0.270475 0.417989 0.2211660 0.0002784 0.000383 -0.000143 0.000073 0.000065 0.0000054 0.0000172 0.000047 0.000041 2009 9 2 55076 0.270872 0.414848 0.2207647 0.0004660 0.000348 -0.000146 0.000073 0.000065 0.0000181 0.0000172 0.000047 0.000041 2009 9 3 55077 0.271334 0.411674 0.2201914 0.0006405 0.000297 -0.000156 0.000073 0.000065 0.0000288 0.0000173 0.000047 0.000041 2009 9 4 55078 0.272133 0.408799 0.2194929 0.0008239 0.000256 -0.000278 0.000073 0.000065 0.0000113 0.0000173 0.000047 0.000042 2009 9 5 55079 0.272764 0.406234 0.2186152 0.0009223 0.000240 -0.000267 0.000073 0.000065 0.0000088 0.0000173 0.000047 0.000042 2009 9 6 55080 0.272826 0.403560 0.2176577 0.0009868 0.000232 -0.000194 0.000073 0.000065 0.0000118 0.0000173 0.000047 0.000042 2009 9 7 55081 0.272475 0.400585 0.2167136 0.0009171 0.000224 -0.000121 0.000073 0.000065 0.0000266 0.0000173 0.000047 0.000042 2009 9 8 55082 0.272308 0.397412 0.2158545 0.0007986 0.000216 -0.000047 0.000073 0.000065 0.0000474 0.0000174 0.000047 0.000042 2009 9 9 55083 0.272131 0.394458 0.2151637 0.0006181 0.000250 -0.000165 0.000074 0.000065 0.0000123 0.0000174 0.000047 0.000042 2009 9 10 55084 0.271847 0.391728 0.2146537 0.0004451 0.000227 -0.000229 0.000074 0.000065 0.0000088 0.0000174 0.000047 0.000042 2009 9 11 55085 0.271466 0.388953 0.2143016 0.0003003 0.000190 -0.000279 0.000074 0.000065 0.0000135 0.0000174 0.000047 0.000042 2009 9 12 55086 0.271548 0.385881 0.2140206 0.0002664 0.000187 -0.000271 0.000074 0.000065 0.0000142 0.0000174 0.000046 0.000042 2009 9 13 55087 0.271905 0.382726 0.2137304 0.0003538 0.000195 -0.000241 0.000074 0.000065 0.0000142 0.0000174 0.000046 0.000041 2009 9 14 55088 0.272442 0.379702 0.2133208 0.0005262 0.000204 -0.000212 0.000074 0.000065 0.0000111 0.0000175 0.000046 0.000041 2009 9 15 55089 0.273143 0.376507 0.2126896 0.0007394 0.000213 -0.000182 0.000074 0.000065 0.0000063 0.0000175 0.000045 0.000040 2009 9 16 55090 0.274180 0.373617 0.2117962 0.0009805 0.000182 -0.000160 0.000074 0.000065 0.0000054 0.0000176 0.000045 0.000040 2009 9 17 55091 0.275213 0.370978 0.2106477 0.0012597 0.000140 -0.000141 0.000074 0.000065 0.0000055 0.0000176 0.000045 0.000040 2009 9 18 55092 0.275672 0.368374 0.2093299 0.0013552 0.000099 -0.000121 0.000074 0.000065 0.0000056 0.0000176 0.000045 0.000040 2009 9 19 55093 0.275583 0.365770 0.2079893 0.0013200 0.000110 -0.000138 0.000074 0.000065 0.0000148 0.0000175 0.000044 0.000040 2009 9 20 55094 0.274911 0.363251 0.2067093 0.0011897 0.000141 -0.000168 0.000074 0.000065 0.0000139 0.0000176 0.000044 0.000039 2009 9 21 55095 0.274070 0.360496 0.2056406 0.0009417 0.000172 -0.000198 0.000074 0.000065 0.0000109 0.0000176 0.000044 0.000039 2009 9 22 55096 0.273396 0.357589 0.2048393 0.0006540 0.000203 -0.000228 0.000074 0.000065 0.0000101 0.0000176 0.000043 0.000039 2009 9 23 55097 0.272765 0.354481 0.2042882 0.0004386 0.000265 -0.000192 0.000074 0.000065 0.0000122 0.0000176 0.000043 0.000038 2009 9 24 55098 0.271994 0.351315 0.2039145 0.0003469 0.000335 -0.000139 0.000074 0.000065 0.0000149 0.0000176 0.000042 0.000037 2009 9 25 55099 0.271193 0.347937 0.2036183 0.0002927 0.000342 -0.000094 0.000075 0.000065 0.0000066 0.0000176 0.000042 0.000037 2009 9 26 55100 0.270241 0.344976 0.2033413 0.0002782 0.000310 -0.000093 0.000075 0.000065 0.0000085 0.0000176 0.000041 0.000036 2009 9 27 55101 0.269102 0.341920 0.2030546 0.0003059 0.000271 -0.000108 0.000075 0.000065 0.0000110 0.0000176 0.000041 0.000036 2009 9 28 55102 0.268214 0.338911 0.2026594 0.0004514 0.000232 -0.000123 0.000075 0.000065 0.0000080 0.0000176 0.000040 0.000035 2009 9 29 55103 0.267526 0.336610 0.2020876 0.0007019 0.000193 -0.000138 0.000075 0.000066 0.0000035 0.0000176 0.000040 0.000035 2009 9 30 55104 0.266518 0.334095 0.2012021 0.0009680 0.000190 -0.000157 0.000075 0.000066 0.0000067 0.0000176 0.000040 0.000035 2009 10 1 55105 0.265645 0.331312 0.2001066 0.0012017 0.000197 -0.000177 0.000075 0.000066 0.0000100 0.0000176 0.000040 0.000034 2009 10 2 55106 0.265000 0.328337 0.1988982 0.0012658 0.000204 -0.000198 0.000075 0.000066 0.0000057 0.0000176 0.000040 0.000034 2009 10 3 55107 0.264673 0.325574 0.1975968 0.0013092 0.000205 -0.000218 0.000075 0.000066 0.0000075 0.0000176 0.000040 0.000034 2009 10 4 55108 0.264204 0.322932 0.1962547 0.0013194 0.000204 -0.000239 0.000075 0.000066 0.0000127 0.0000175 0.000040 0.000034 2009 10 5 55109 0.263705 0.320289 0.1950044 0.0012169 0.000203 -0.000260 0.000075 0.000066 0.0000129 0.0000176 0.000040 0.000034 2009 10 6 55110 0.263098 0.317818 0.1939110 0.0010044 0.000203 -0.000281 0.000075 0.000066 0.0000103 0.0000176 0.000040 0.000035 2009 10 7 55111 0.262362 0.315482 0.1929751 0.0008433 0.000096 -0.000311 0.000075 0.000066 0.0000248 0.0000176 0.000040 0.000034 2009 10 8 55112 0.261888 0.313337 0.1922182 0.0006962 0.000053 -0.000277 0.000075 0.000066 0.0000085 0.0000175 0.000039 0.000034 2009 10 9 55113 0.261986 0.310889 0.1915881 0.0006271 0.000152 -0.000247 0.000075 0.000066 0.0000039 0.0000175 0.000039 0.000034 2009 10 10 55114 0.261793 0.308471 0.1909778 0.0005931 0.000201 -0.000240 0.000075 0.000066 0.0000144 0.0000175 0.000039 0.000034 2009 10 11 55115 0.261131 0.305901 0.1903665 0.0006590 0.000217 -0.000239 0.000075 0.000066 0.0000152 0.0000174 0.000039 0.000034 2009 10 12 55116 0.260149 0.303593 0.1896743 0.0008150 0.000233 -0.000238 0.000075 0.000066 0.0000088 0.0000174 0.000039 0.000034 2009 10 13 55117 0.258870 0.301360 0.1887401 0.0010636 0.000250 -0.000237 0.000075 0.000066 0.0000055 0.0000174 0.000039 0.000034 2009 10 14 55118 0.257103 0.299122 0.1875448 0.0012821 0.000266 -0.000236 0.000075 0.000066 0.0000044 0.0000174 0.000039 0.000034 2009 10 15 55119 0.254889 0.296180 0.1861560 0.0014283 0.000138 -0.000181 0.000075 0.000066 0.0000042 0.0000174 0.000039 0.000034 2009 10 16 55120 0.253459 0.293014 0.1846794 0.0014826 0.000074 -0.000230 0.000075 0.000066 0.0000041 0.0000174 0.000039 0.000034 2009 10 17 55121 0.252719 0.290456 0.1832013 0.0014308 0.000072 -0.000231 0.000075 0.000066 0.0000108 0.0000173 0.000039 0.000034 2009 10 18 55122 0.251867 0.287899 0.1818821 0.0012200 0.000082 -0.000201 0.000075 0.000066 0.0000124 0.0000173 0.000039 0.000034 2009 10 19 55123 0.250970 0.285474 0.1807765 0.0009741 0.000092 -0.000171 0.000075 0.000066 0.0000106 0.0000173 0.000039 0.000033 2009 10 20 55124 0.249989 0.283378 0.1798915 0.0007902 0.000102 -0.000141 0.000075 0.000066 0.0000090 0.0000174 0.000038 0.000033 2009 10 21 55125 0.249087 0.281484 0.1791856 0.0006477 -0.000089 -0.000041 0.000075 0.000066 0.0000047 0.0000174 0.000038 0.000033 2009 10 22 55126 0.247993 0.279272 0.1785861 0.0005742 -0.000041 -0.000150 0.000075 0.000066 0.0000044 0.0000174 0.000038 0.000033 2009 10 23 55127 0.247300 0.276618 0.1780321 0.0005665 0.000094 -0.000327 0.000075 0.000066 0.0000055 0.0000174 0.000038 0.000034 2009 10 24 55128 0.246085 0.273872 0.1774891 0.0005419 0.000128 -0.000352 0.000075 0.000066 0.0000126 0.0000174 0.000038 0.000034 2009 10 25 55129 0.244765 0.270977 0.1769336 0.0006380 0.000123 -0.000320 0.000075 0.000066 0.0000157 0.0000174 0.000038 0.000034 2009 10 26 55130 0.243942 0.268748 0.1762209 0.0007942 0.000119 -0.000287 0.000075 0.000066 0.0000111 0.0000174 0.000038 0.000034 2009 10 27 55131 0.243015 0.266564 0.1753286 0.0009862 0.000115 -0.000255 0.000075 0.000066 0.0000041 0.0000174 0.000038 0.000034 2009 10 28 55132 0.241834 0.264237 0.1742942 0.0011296 0.000095 -0.000222 0.000075 0.000066 0.0000034 0.0000174 0.000038 0.000035 2009 10 29 55133 0.240739 0.262142 0.1731269 0.0012229 0.000072 -0.000188 0.000075 0.000066 0.0000043 0.0000174 0.000039 0.000035 2009 10 30 55134 0.239462 0.259751 0.1718631 0.0012517 0.000048 -0.000155 0.000075 0.000066 0.0000052 0.0000174 0.000039 0.000036 2009 10 31 55135 0.237669 0.257566 0.1705643 0.0012959 0.000049 -0.000180 0.000075 0.000066 0.0000083 0.0000174 0.000039 0.000036 2009 11 1 55136 0.235587 0.255610 0.1693127 0.0011754 0.000059 -0.000228 0.000075 0.000066 0.0000110 0.0000174 0.000038 0.000036 2009 11 2 55137 0.234448 0.253323 0.1681793 0.0010367 0.000069 -0.000275 0.000075 0.000066 0.0000094 0.0000174 0.000038 0.000036 2009 11 3 55138 0.234348 0.251564 0.1672139 0.0009306 0.000079 -0.000322 0.000075 0.000066 0.0000059 0.0000174 0.000038 0.000036 2009 11 4 55139 0.234012 0.250071 0.1663777 0.0007467 0.000102 -0.000327 0.000075 0.000066 0.0000119 0.0000175 0.000038 0.000036 2009 11 5 55140 0.233401 0.248273 0.1656772 0.0006736 0.000129 -0.000322 0.000075 0.000066 0.0000165 0.0000175 0.000038 0.000036 2009 11 6 55141 0.232055 0.246261 0.1650268 0.0006787 0.000155 -0.000316 0.000075 0.000066 0.0000061 0.0000174 0.000038 0.000036 2009 11 7 55142 0.229766 0.243720 0.1643651 0.0007333 0.000149 -0.000308 0.000075 0.000066 0.0000071 0.0000174 0.000038 0.000036 2009 11 8 55143 0.227145 0.241047 0.1636032 0.0008348 0.000130 -0.000298 0.000075 0.000066 0.0000076 0.0000174 0.000037 0.000037 2009 11 9 55144 0.224930 0.238583 0.1627271 0.0009765 0.000112 -0.000289 0.000075 0.000066 0.0000074 0.0000174 0.000037 0.000037 2009 11 10 55145 0.222863 0.236357 0.1616830 0.0011352 0.000093 -0.000279 0.000075 0.000066 0.0000082 0.0000174 0.000037 0.000037 2009 11 11 55146 0.220624 0.234314 0.1604715 0.0012776 0.000069 -0.000217 0.000075 0.000066 0.0000548 0.0000174 0.000037 0.000037 2009 11 12 55147 0.218085 0.232202 0.1591639 0.0013457 0.000071 -0.000131 0.000075 0.000066 0.0000522 0.0000174 0.000037 0.000036 2009 11 13 55148 0.215687 0.230182 0.1578255 0.0012951 0.000108 -0.000059 0.000075 0.000066 0.0000163 0.0000174 0.000036 0.000035 2009 11 14 55149 0.212923 0.228293 0.1566477 0.0010773 0.000129 -0.000069 0.000075 0.000066 0.0000066 0.0000174 0.000035 0.000035 2009 11 15 55150 0.209674 0.226602 0.1556979 0.0008519 0.000141 -0.000106 0.000075 0.000066 0.0000078 0.0000173 0.000035 0.000034 2009 11 16 55151 0.206205 0.225091 0.1549559 0.0006477 0.000153 -0.000144 0.000075 0.000066 0.0000060 0.0000174 0.000034 0.000033 2009 11 17 55152 0.203146 0.223697 0.1543998 0.0005167 0.000166 -0.000182 0.000075 0.000066 0.0000031 0.0000174 0.000034 0.000032 2009 11 18 55153 0.200502 0.222322 0.1539496 0.0004391 0.000050 -0.000080 0.000075 0.000066 0.0000037 0.0000173 0.000033 0.000032 2009 11 19 55154 0.198006 0.220883 0.1535972 0.0003559 0.000109 -0.000071 0.000075 0.000066 0.0000058 0.0000173 0.000033 0.000031 2009 11 20 55155 0.195683 0.219370 0.1532354 0.0003574 0.000190 -0.000181 0.000075 0.000066 0.0000081 0.0000173 0.000033 0.000031 2009 11 21 55156 0.193537 0.218019 0.1527842 0.0005103 0.000186 -0.000234 0.000075 0.000066 0.0000090 0.0000172 0.000032 0.000031 2009 11 22 55157 0.191431 0.216733 0.1521542 0.0007145 0.000154 -0.000257 0.000075 0.000066 0.0000088 0.0000172 0.000032 0.000031 2009 11 23 55158 0.189659 0.215260 0.1513226 0.0009322 0.000122 -0.000280 0.000075 0.000066 0.0000069 0.0000171 0.000032 0.000030 2009 11 24 55159 0.187811 0.213911 0.1503085 0.0010610 0.000091 -0.000303 0.000075 0.000066 0.0000043 0.0000171 0.000032 0.000030 2009 11 25 55160 0.185857 0.212772 0.1491691 0.0011803 -0.000149 -0.000371 0.000075 0.000066 0.0000066 0.0000171 0.000031 0.000030 2009 11 26 55161 0.183609 0.212388 0.1478948 0.0012752 -0.000244 -0.000360 0.000075 0.000066 0.0000082 0.0000170 0.000031 0.000029 2009 11 27 55162 0.180914 0.211921 0.1465452 0.0013504 -0.000264 -0.000316 0.000075 0.000066 0.0000091 0.0000170 0.000030 0.000029 2009 11 28 55163 0.177998 0.211007 0.1451960 0.0013100 -0.000196 -0.000287 0.000075 0.000066 0.0000099 0.0000169 0.000030 0.000028 2009 11 29 55164 0.174948 0.210046 0.1439380 0.0011855 -0.000128 -0.000259 0.000075 0.000066 0.0000080 0.0000169 0.000029 0.000027 2009 11 30 55165 0.172178 0.209447 0.1428485 0.0010030 -0.000060 -0.000230 0.000075 0.000066 0.0000052 0.0000169 0.000028 0.000026 2009 12 1 55166 0.168825 0.208746 0.1419507 0.0008024 0.000008 -0.000202 0.000075 0.000066 0.0000026 0.0000168 0.000028 0.000026 2009 12 2 55167 0.165133 0.207659 0.1412194 0.0006497 0.000027 -0.000231 0.000075 0.000066 0.0000052 0.0000168 0.000027 0.000025 2009 12 3 55168 0.161724 0.206190 0.1406016 0.0006329 0.000032 -0.000275 0.000075 0.000066 0.0000090 0.0000168 0.000027 0.000025 2009 12 4 55169 0.158901 0.204712 0.1399584 0.0007284 0.000119 -0.000257 0.000075 0.000066 0.0000071 0.0000167 0.000027 0.000025 2009 12 5 55170 0.156571 0.203238 0.1391852 0.0008869 0.000148 -0.000255 0.000075 0.000066 0.0000070 0.0000166 0.000028 0.000025 2009 12 6 55171 0.154436 0.202071 0.1382413 0.0010252 0.000145 -0.000267 0.000075 0.000066 0.0000062 0.0000166 0.000028 0.000026 2009 12 7 55172 0.152200 0.201213 0.1371176 0.0012269 0.000142 -0.000280 0.000074 0.000066 0.0000044 0.0000166 0.000028 0.000026 2009 12 8 55173 0.149659 0.200516 0.1358293 0.0013666 0.000140 -0.000292 0.000074 0.000066 0.0000026 0.0000166 0.000029 0.000027 2009 12 9 55174 0.147221 0.199624 0.1344324 0.0014362 0.000064 -0.000174 0.000074 0.000066 0.0000027 0.0000165 0.000029 0.000027 2009 12 10 55175 0.145087 0.198535 0.1330514 0.0013667 0.000063 -0.000155 0.000074 0.000066 0.0000034 0.0000165 0.000030 0.000028 2009 12 11 55176 0.142570 0.197641 0.1317856 0.0011665 0.000089 -0.000177 0.000074 0.000066 0.0000040 0.0000165 0.000030 0.000028 2009 12 12 55177 0.140283 0.196693 0.1307385 0.0009249 0.000081 -0.000189 0.000074 0.000066 0.0000053 0.0000164 0.000030 0.000028 2009 12 13 55178 0.138336 0.196109 0.1298906 0.0007678 0.000060 -0.000199 0.000074 0.000066 0.0000072 0.0000163 0.000031 0.000028 2009 12 14 55179 0.136221 0.195907 0.1291896 0.0006562 0.000040 -0.000208 0.000074 0.000066 0.0000058 0.0000163 0.000031 0.000029 2009 12 15 55180 0.133249 0.195621 0.1286022 0.0005622 0.000019 -0.000217 0.000074 0.000066 0.0000028 0.0000163 0.000031 0.000029 2009 12 16 55181 0.130467 0.195125 0.1280413 0.0005841 0.000144 -0.000097 0.000074 0.000066 0.0000042 0.0000163 0.000031 0.000029 2009 12 17 55182 0.127788 0.194628 0.1274404 0.0006392 0.000187 -0.000029 0.000074 0.000065 0.0000030 0.0000163 0.000032 0.000030 2009 12 18 55183 0.125343 0.193947 0.1267789 0.0007056 0.000053 -0.000007 0.000074 0.000065 0.0000060 0.0000163 0.000032 0.000030 2009 12 19 55184 0.123368 0.193607 0.1260232 0.0008164 0.000018 -0.000050 0.000074 0.000065 0.0000075 0.0000162 0.000032 0.000030 2009 12 20 55185 0.121746 0.193599 0.1251143 0.0009900 0.000037 -0.000114 0.000074 0.000065 0.0000068 0.0000162 0.000032 0.000029 2009 12 21 55186 0.120035 0.193569 0.1240445 0.0011400 0.000056 -0.000178 0.000074 0.000065 0.0000048 0.0000162 0.000032 0.000029 2009 12 22 55187 0.118132 0.193217 0.1228456 0.0012620 0.000075 -0.000243 0.000074 0.000065 0.0000023 0.0000163 0.000032 0.000029 2009 12 23 55188 0.115995 0.192921 0.1215382 0.0013471 0.000105 -0.000211 0.000074 0.000065 0.0000031 0.0000163 0.000033 0.000029 2009 12 24 55189 0.113839 0.192466 0.1202286 0.0012829 0.000096 -0.000195 0.000074 0.000065 0.0000046 0.0000163 0.000033 0.000029 2009 12 25 55190 0.112035 0.192027 0.1189637 0.0012384 0.000071 -0.000193 0.000074 0.000065 0.0000061 0.0000163 0.000033 0.000030 2009 12 26 55191 0.110406 0.191808 0.1177956 0.0010991 0.000045 -0.000192 0.000074 0.000065 0.0000075 0.0000163 0.000033 0.000030 2009 12 27 55192 0.108636 0.191754 0.1167686 0.0009545 0.000020 -0.000190 0.000074 0.000065 0.0000091 0.0000163 0.000033 0.000030 2009 12 28 55193 0.106812 0.191804 0.1159325 0.0007782 -0.000005 -0.000188 0.000074 0.000065 0.0000074 0.0000164 0.000034 0.000030 2009 12 29 55194 0.104815 0.191849 0.1152991 0.0005295 -0.000030 -0.000187 0.000074 0.000065 0.0000040 0.0000165 0.000034 0.000031 2009 12 30 55195 0.102800 0.191953 0.1148715 0.0003704 0.000075 -0.000067 0.000074 0.000065 0.0000061 0.0000165 0.000034 0.000031 2009 12 31 55196 0.100694 0.192256 0.1144889 0.0003918 0.000108 -0.000045 0.000074 0.000065 0.0000222 0.0000166 0.000034 0.000031 2010 1 1 55197 0.098695 0.192853 0.1140330 0.0005515 0.000102 -0.000071 0.000082 0.000061 0.0000304 0.0000133 0.000046 0.000049 2010 1 2 55198 0.096604 0.193232 0.1134203 0.0007741 0.000095 -0.000097 0.000082 0.000061 0.0000151 0.0000133 0.000046 0.000049 2010 1 3 55199 0.094676 0.193107 0.1125087 0.0010575 0.000088 -0.000124 0.000082 0.000061 0.0000103 0.0000133 0.000047 0.000049 2010 1 4 55200 0.092786 0.193416 0.1113329 0.0012465 0.000081 -0.000150 0.000083 0.000061 0.0000076 0.0000134 0.000047 0.000050 2010 1 5 55201 0.090576 0.193734 0.1100064 0.0014238 0.000074 -0.000176 0.000083 0.000061 0.0000034 0.0000135 0.000048 0.000050 2010 1 6 55202 0.087665 0.194098 0.1086158 0.0013382 0.000057 -0.000176 0.000083 0.000061 0.0000099 0.0000135 0.000048 0.000050 2010 1 7 55203 0.084302 0.194269 0.1073280 0.0011750 0.000038 -0.000169 0.000083 0.000061 0.0000157 0.0000136 0.000049 0.000051 2010 1 8 55204 0.081206 0.194426 0.1062553 0.0009798 0.000019 -0.000162 0.000083 0.000061 0.0000079 0.0000136 0.000049 0.000052 2010 1 9 55205 0.077933 0.194511 0.1053959 0.0007406 0.000006 -0.000172 0.000083 0.000061 0.0000087 0.0000136 0.000050 0.000052 2010 1 10 55206 0.074185 0.194387 0.1047965 0.0004832 -0.000005 -0.000189 0.000083 0.000061 0.0000102 0.0000137 0.000050 0.000052 2010 1 11 55207 0.070451 0.194278 0.1044057 0.0003239 -0.000015 -0.000205 0.000083 0.000061 0.0000075 0.0000137 0.000050 0.000052 2010 1 12 55208 0.067550 0.194324 0.1041319 0.0002571 -0.000025 -0.000221 0.000083 0.000061 0.0000033 0.0000138 0.000051 0.000052 2010 1 13 55209 0.064903 0.194517 0.1038825 0.0002516 0.000208 -0.000228 0.000083 0.000061 0.0000062 0.0000138 0.000051 0.000053 2010 1 14 55210 0.062148 0.194893 0.1036160 0.0002606 0.000505 -0.000232 0.000083 0.000061 0.0000090 0.0000139 0.000051 0.000053 2010 1 15 55211 0.059184 0.195238 0.1033179 0.0003822 0.000165 -0.000283 0.000083 0.000062 0.0000042 0.0000139 0.000051 0.000053 2010 1 16 55212 0.055824 0.195599 0.1028507 0.0005624 0.000076 -0.000335 0.000083 0.000062 0.0000077 0.0000139 0.000051 0.000053 2010 1 17 55213 0.052402 0.195750 0.1021916 0.0007431 0.000157 -0.000382 0.000083 0.000062 0.0000102 0.0000140 0.000051 0.000053 2010 1 18 55214 0.048865 0.195960 0.1013568 0.0008983 0.000239 -0.000428 0.000084 0.000062 0.0000096 0.0000140 0.000051 0.000053 2010 1 19 55215 0.044993 0.196133 0.1004243 0.0009685 0.000319 -0.000474 0.000084 0.000062 0.0000071 0.0000141 0.000051 0.000053 2010 1 20 55216 0.040975 0.196420 0.0994233 0.0009677 0.000078 -0.000307 0.000084 0.000062 0.0000040 0.0000141 0.000050 0.000052 2010 1 21 55217 0.036965 0.196820 0.0983926 0.0009927 0.000030 -0.000248 0.000084 0.000062 0.0000042 0.0000141 0.000050 0.000052 2010 1 22 55218 0.033475 0.197121 0.0973826 0.0010056 0.000032 -0.000219 0.000084 0.000062 0.0000052 0.0000141 0.000050 0.000052 2010 1 23 55219 0.030544 0.197134 0.0964038 0.0009600 0.000008 -0.000200 0.000084 0.000062 0.0000091 0.0000141 0.000050 0.000051 2010 1 24 55220 0.028109 0.197335 0.0954957 0.0008384 -0.000025 -0.000184 0.000084 0.000062 0.0000096 0.0000141 0.000050 0.000050 2010 1 25 55221 0.025536 0.197977 0.0947361 0.0006806 -0.000058 -0.000169 0.000084 0.000062 0.0000064 0.0000141 0.000050 0.000050 2010 1 26 55222 0.022960 0.198520 0.0940955 0.0005814 -0.000092 -0.000154 0.000084 0.000062 0.0000025 0.0000142 0.000050 0.000049 2010 1 27 55223 0.020546 0.199214 0.0935434 0.0005628 -0.000029 -0.000125 0.000084 0.000062 0.0000021 0.0000142 0.000050 0.000049 2010 1 28 55224 0.018828 0.200275 0.0929250 0.0006921 0.000059 -0.000092 0.000084 0.000062 0.0000026 0.0000142 0.000051 0.000050 2010 1 29 55225 0.017856 0.201814 0.0921063 0.0009498 -0.000063 -0.000272 0.000084 0.000062 0.0000066 0.0000142 0.000051 0.000050 2010 1 30 55226 0.016469 0.204049 0.0910101 0.0012696 -0.000114 -0.000332 0.000084 0.000062 0.0000090 0.0000142 0.000051 0.000050 2010 1 31 55227 0.014153 0.206378 0.0895895 0.0015927 -0.000114 -0.000321 0.000084 0.000062 0.0000100 0.0000141 0.000052 0.000050 2010 2 1 55228 0.011543 0.208043 0.0878535 0.0018282 -0.000114 -0.000310 0.000084 0.000062 0.0000076 0.0000142 0.000052 0.000050 2010 2 2 55229 0.008709 0.209258 0.0859781 0.0018664 -0.000114 -0.000299 0.000084 0.000062 0.0000035 0.0000142 0.000052 0.000050 2010 2 3 55230 0.005991 0.210335 0.0841118 0.0018061 -0.000226 -0.000201 0.000084 0.000062 0.0000083 0.0000142 0.000053 0.000051 2010 2 4 55231 0.003249 0.211885 0.0823402 0.0015493 -0.000284 -0.000173 0.000084 0.000062 0.0000617 0.0000142 0.000053 0.000051 2010 2 5 55232 0.000818 0.212814 0.0809846 0.0012845 -0.000313 -0.000175 0.000084 0.000062 0.0001119 0.0000142 0.000053 0.000051 2010 2 6 55233 -0.001112 0.213375 0.0798431 0.0010595 -0.000273 -0.000196 0.000084 0.000062 0.0000434 0.0000142 0.000053 0.000051 2010 2 7 55234 -0.002886 0.214073 0.0789044 0.0008372 -0.000209 -0.000225 0.000084 0.000062 0.0000066 0.0000142 0.000053 0.000050 2010 2 8 55235 -0.004840 0.214986 0.0781738 0.0006724 -0.000144 -0.000253 0.000084 0.000062 0.0000053 0.0000142 0.000054 0.000050 2010 2 9 55236 -0.006457 0.216197 0.0775465 0.0005685 -0.000079 -0.000281 0.000084 0.000062 0.0000029 0.0000142 0.000054 0.000049 2010 2 10 55237 -0.008240 0.217817 0.0770015 0.0005556 -0.000035 -0.000193 0.000084 0.000062 0.0000359 0.0000142 0.000054 0.000049 2010 2 11 55238 -0.010699 0.219448 0.0763959 0.0006655 -0.000068 -0.000153 0.000084 0.000062 0.0000290 0.0000142 0.000054 0.000048 2010 2 12 55239 -0.013651 0.221000 0.0756577 0.0008138 -0.000035 -0.000251 0.000084 0.000063 0.0000123 0.0000142 0.000054 0.000047 2010 2 13 55240 -0.015975 0.222534 0.0747526 0.0009913 -0.000027 -0.000278 0.000084 0.000063 0.0000082 0.0000142 0.000053 0.000046 2010 2 14 55241 -0.017871 0.224372 0.0736823 0.0011489 -0.000040 -0.000266 0.000084 0.000063 0.0000074 0.0000142 0.000053 0.000045 2010 2 15 55242 -0.019579 0.226266 0.0724261 0.0013115 -0.000053 -0.000253 0.000085 0.000063 0.0000058 0.0000142 0.000053 0.000044 2010 2 16 55243 -0.021226 0.228566 0.0710346 0.0014281 -0.000065 -0.000240 0.000085 0.000063 0.0000038 0.0000143 0.000052 0.000042 2010 2 17 55244 -0.022594 0.230866 0.0695762 0.0014871 -0.000078 -0.000227 0.000085 0.000063 0.0000019 0.0000143 0.000052 0.000041 2010 2 18 55245 -0.023477 0.232950 0.0680591 0.0015032 -0.000028 -0.000382 0.000085 0.000063 0.0000017 0.0000143 0.000052 0.000041 2010 2 19 55246 -0.024193 0.235189 0.0665792 0.0014143 -0.000087 -0.000182 0.000085 0.000063 0.0000021 0.0000143 0.000052 0.000041 2010 2 20 55247 -0.025101 0.237302 0.0651978 0.0013080 -0.000090 -0.000143 0.000085 0.000063 0.0000060 0.0000142 0.000052 0.000042 2010 2 21 55248 -0.026369 0.239204 0.0639573 0.0011703 -0.000059 -0.000207 0.000085 0.000063 0.0000067 0.0000142 0.000052 0.000042 2010 2 22 55249 -0.027577 0.240849 0.0628517 0.0010787 -0.000027 -0.000272 0.000085 0.000063 0.0000047 0.0000142 0.000052 0.000043 2010 2 23 55250 -0.028379 0.242535 0.0618273 0.0009798 0.000004 -0.000336 0.000085 0.000063 0.0000027 0.0000143 0.000052 0.000043 2010 2 24 55251 -0.029184 0.244473 0.0608376 0.0010071 -0.000022 -0.000292 0.000085 0.000063 0.0000067 0.0000143 0.000053 0.000044 2010 2 25 55252 -0.030442 0.246623 0.0597472 0.0011801 -0.000063 -0.000220 0.000085 0.000063 0.0000109 0.0000143 0.000053 0.000045 2010 2 26 55253 -0.031549 0.248672 0.0584521 0.0014491 -0.000105 -0.000148 0.000085 0.000063 0.0000099 0.0000143 0.000053 0.000047 2010 2 27 55254 -0.032519 0.251034 0.0568890 0.0017289 -0.000128 -0.000123 0.000085 0.000063 0.0000118 0.0000142 0.000053 0.000048 2010 2 28 55255 -0.034025 0.253426 0.0550258 0.0019684 -0.000146 -0.000117 0.000085 0.000063 0.0000113 0.0000142 0.000054 0.000049 2010 3 1 55256 -0.035067 0.255573 0.0529802 0.0020910 -0.000163 -0.000111 0.000085 0.000063 0.0000081 0.0000142 0.000054 0.000050 2010 3 2 55257 -0.035898 0.257681 0.0509260 0.0020035 -0.000180 -0.000105 0.000085 0.000063 0.0000045 0.0000142 0.000054 0.000051 2010 3 3 55258 -0.036923 0.259831 0.0490187 0.0017662 0.000481 -0.000613 0.000085 0.000063 0.0000098 0.0000142 0.000054 0.000053 2010 3 4 55259 -0.038289 0.261873 0.0473680 0.0014810 0.000408 -0.000567 0.000085 0.000063 0.0000146 0.0000142 0.000054 0.000053 2010 3 5 55260 -0.039103 0.263895 0.0460213 0.0012198 0.000066 -0.000317 0.000085 0.000063 0.0000085 0.0000142 0.000054 0.000054 2010 3 6 55261 -0.039911 0.265980 0.0449084 0.0009674 -0.000057 -0.000232 0.000085 0.000063 0.0000085 0.0000142 0.000054 0.000054 2010 3 7 55262 -0.041276 0.267733 0.0440081 0.0008299 -0.000099 -0.000207 0.000085 0.000063 0.0000084 0.0000141 0.000054 0.000055 2010 3 8 55263 -0.042960 0.269473 0.0432120 0.0007660 -0.000141 -0.000183 0.000086 0.000063 0.0000065 0.0000141 0.000054 0.000055 2010 3 9 55264 -0.044865 0.270984 0.0424382 0.0008359 -0.000183 -0.000158 0.000086 0.000063 0.0000042 0.0000141 0.000053 0.000055 2010 3 10 55265 -0.046217 0.272436 0.0415117 0.0009248 -0.000127 -0.000135 0.000086 0.000063 0.0000159 0.0000141 0.000053 0.000055 2010 3 11 55266 -0.047130 0.273920 0.0405179 0.0009789 -0.000045 -0.000111 0.000086 0.000063 0.0000244 0.0000141 0.000053 0.000055 2010 3 12 55267 -0.048042 0.275671 0.0395710 0.0010768 0.000036 -0.000087 0.000086 0.000063 0.0000074 0.0000141 0.000053 0.000055 2010 3 13 55268 -0.048717 0.277615 0.0384831 0.0011385 0.000026 -0.000083 0.000086 0.000063 0.0000082 0.0000140 0.000053 0.000055 2010 3 14 55269 -0.049654 0.280085 0.0373665 0.0011203 -0.000019 -0.000085 0.000086 0.000063 0.0000082 0.0000140 0.000053 0.000055 2010 3 15 55270 -0.050847 0.282755 0.0362124 0.0011672 -0.000063 -0.000087 0.000086 0.000063 0.0000067 0.0000140 0.000053 0.000055 2010 3 16 55271 -0.051892 0.285445 0.0350336 0.0012024 -0.000108 -0.000089 0.000086 0.000063 0.0000062 0.0000140 0.000053 0.000055 2010 3 17 55272 -0.052583 0.287740 0.0337682 0.0012285 -0.000081 -0.000115 0.000086 0.000063 0.0000065 0.0000140 0.000053 0.000055 2010 3 18 55273 -0.053229 0.289689 0.0325611 0.0011975 -0.000035 -0.000147 0.000086 0.000063 0.0000071 0.0000140 0.000053 0.000055 2010 3 19 55274 -0.053959 0.291129 0.0314879 0.0009974 0.000011 -0.000180 0.000086 0.000063 0.0000076 0.0000140 0.000053 0.000054 2010 3 20 55275 -0.054441 0.292448 0.0306082 0.0008303 -0.000007 -0.000141 0.000086 0.000063 0.0000070 0.0000139 0.000053 0.000054 2010 3 21 55276 -0.054525 0.294069 0.0298895 0.0006723 -0.000050 -0.000076 0.000086 0.000063 0.0000059 0.0000139 0.000053 0.000053 2010 3 22 55277 -0.054464 0.296033 0.0292716 0.0005625 -0.000092 -0.000010 0.000086 0.000063 0.0000049 0.0000139 0.000053 0.000053 2010 3 23 55278 -0.054658 0.298235 0.0286717 0.0005380 -0.000134 0.000055 0.000086 0.000063 0.0000038 0.0000139 0.000053 0.000052 2010 3 24 55279 -0.055165 0.300796 0.0280488 0.0006564 -0.000142 0.000005 0.000086 0.000063 0.0000050 0.0000138 0.000053 0.000051 2010 3 25 55280 -0.056019 0.303630 0.0272378 0.0009532 -0.000139 -0.000077 0.000086 0.000063 0.0000060 0.0000138 0.000053 0.000051 2010 3 26 55281 -0.057042 0.306201 0.0261280 0.0012942 -0.000111 -0.000176 0.000086 0.000063 0.0000039 0.0000137 0.000052 0.000050 2010 3 27 55282 -0.057657 0.308245 0.0246781 0.0016093 -0.000115 -0.000177 0.000086 0.000063 0.0000050 0.0000137 0.000052 0.000049 2010 3 28 55283 -0.058257 0.310476 0.0229438 0.0018513 -0.000130 -0.000142 0.000086 0.000063 0.0000054 0.0000136 0.000051 0.000048 2010 3 29 55284 -0.058869 0.312672 0.0210007 0.0019802 -0.000145 -0.000107 0.000086 0.000063 0.0000042 0.0000136 0.000051 0.000047 2010 3 30 55285 -0.059911 0.314898 0.0190432 0.0019200 -0.000160 -0.000072 0.000086 0.000063 0.0000027 0.0000136 0.000051 0.000047 2010 3 31 55286 -0.060817 0.316812 0.0172747 0.0016449 -0.000130 -0.000057 0.000086 0.000063 0.0000058 0.0000135 0.000051 0.000047 2010 4 1 55287 -0.061112 0.319193 0.0157570 0.0013232 -0.000089 -0.000046 0.000086 0.000063 0.0000101 0.0000135 0.000051 0.000048 2010 4 2 55288 -0.061578 0.321989 0.0145642 0.0010245 -0.000097 -0.000054 0.000086 0.000063 0.0000091 0.0000134 0.000051 0.000048 2010 4 3 55289 -0.062084 0.324630 0.0136222 0.0008388 -0.000123 -0.000067 0.000086 0.000063 0.0000077 0.0000133 0.000051 0.000048 2010 4 4 55290 -0.062902 0.327306 0.0128386 0.0007689 -0.000148 -0.000081 0.000086 0.000063 0.0000100 0.0000132 0.000051 0.000048 2010 4 5 55291 -0.064155 0.329523 0.0120363 0.0008055 -0.000174 -0.000095 0.000086 0.000063 0.0000086 0.0000132 0.000051 0.000048 2010 4 6 55292 -0.065869 0.331312 0.0111785 0.0008833 -0.000200 -0.000109 0.000086 0.000063 0.0000059 0.0000131 0.000051 0.000049 2010 4 7 55293 -0.067169 0.332862 0.0102304 0.0010370 -0.000226 -0.000123 0.000086 0.000063 0.0000032 0.0000131 0.000051 0.000049 2010 4 8 55294 -0.067861 0.334856 0.0091338 0.0011813 0.000088 -0.000182 0.000086 0.000063 0.0000036 0.0000131 0.000051 0.000049 2010 4 9 55295 -0.068236 0.337157 0.0078772 0.0013211 -0.000061 -0.000136 0.000085 0.000063 0.0000045 0.0000130 0.000051 0.000049 2010 4 10 55296 -0.068489 0.339617 0.0065022 0.0014169 -0.000145 -0.000084 0.000085 0.000063 0.0000052 0.0000130 0.000051 0.000049 2010 4 11 55297 -0.068321 0.342212 0.0050500 0.0014943 -0.000144 -0.000043 0.000085 0.000063 0.0000064 0.0000130 0.000051 0.000050 2010 4 12 55298 -0.068100 0.345076 0.0035182 0.0015558 -0.000143 -0.000002 0.000085 0.000062 0.0000072 0.0000131 0.000051 0.000050 2010 4 13 55299 -0.068098 0.348000 0.0019548 0.0015950 -0.000142 0.000039 0.000084 0.000062 0.0000078 0.0000131 0.000051 0.000050 2010 4 14 55300 -0.068434 0.350761 0.0003875 0.0015272 -0.000272 0.000057 0.000084 0.000062 0.0000039 0.0000131 0.000051 0.000050 2010 4 15 55301 -0.068905 0.353118 -0.0011024 0.0014165 -0.000214 0.000007 0.000084 0.000062 0.0000045 0.0000131 0.000051 0.000050 2010 4 16 55302 -0.068898 0.355249 -0.0024625 0.0012975 -0.000090 -0.000062 0.000084 0.000062 0.0000069 0.0000131 0.000051 0.000051 2010 4 17 55303 -0.069040 0.357459 -0.0036776 0.0011547 -0.000074 -0.000072 0.000084 0.000062 0.0000060 0.0000131 0.000051 0.000051 2010 4 18 55304 -0.069241 0.359669 -0.0047710 0.0010607 -0.000099 -0.000061 0.000084 0.000062 0.0000062 0.0000131 0.000051 0.000051 2010 4 19 55305 -0.069011 0.362003 -0.0057957 0.0010184 -0.000124 -0.000049 0.000084 0.000062 0.0000065 0.0000131 0.000051 0.000052 2010 4 20 55306 -0.068827 0.364624 -0.0068501 0.0010884 -0.000148 -0.000038 0.000084 0.000062 0.0000062 0.0000131 0.000050 0.000052 2010 4 21 55307 -0.068888 0.366961 -0.0080242 0.0012651 -0.000154 -0.000043 0.000084 0.000062 0.0000103 0.0000131 0.000050 0.000052 2010 4 22 55308 -0.069347 0.369356 -0.0093930 0.0014893 -0.000154 -0.000053 0.000084 0.000062 0.0000132 0.0000131 0.000050 0.000052 2010 4 23 55309 -0.069994 0.371843 -0.0109741 0.0016875 -0.000154 -0.000063 0.000084 0.000062 0.0000069 0.0000131 0.000050 0.000052 2010 4 24 55310 -0.070343 0.374067 -0.0127474 0.0018430 -0.000156 -0.000068 0.000084 0.000062 0.0000058 0.0000131 0.000050 0.000052 2010 4 25 55311 -0.070748 0.376327 -0.0146273 0.0019197 -0.000158 -0.000072 0.000084 0.000062 0.0000073 0.0000131 0.000050 0.000052 2010 4 26 55312 -0.071127 0.378538 -0.0165350 0.0018314 -0.000161 -0.000076 0.000084 0.000062 0.0000073 0.0000131 0.000050 0.000052 2010 4 27 55313 -0.070811 0.380923 -0.0183205 0.0017409 -0.000163 -0.000079 0.000084 0.000063 0.0000062 0.0000131 0.000049 0.000053 2010 4 28 55314 -0.070783 0.383514 -0.0199388 0.0014943 -0.000185 -0.000079 0.000085 0.000063 0.0000056 0.0000131 0.000049 0.000053 2010 4 29 55315 -0.071096 0.385501 -0.0212834 0.0012022 -0.000212 -0.000077 0.000085 0.000063 0.0000052 0.0000131 0.000049 0.000052 2010 4 30 55316 -0.071151 0.387503 -0.0223468 0.0009186 -0.000239 -0.000075 0.000085 0.000063 0.0000048 0.0000131 0.000049 0.000052 2010 5 1 55317 -0.070889 0.389509 -0.0231571 0.0007075 -0.000225 -0.000060 0.000085 0.000063 0.0000058 0.0000131 0.000049 0.000052 2010 5 2 55318 -0.070352 0.391382 -0.0238185 0.0006194 -0.000195 -0.000041 0.000085 0.000063 0.0000074 0.0000131 0.000049 0.000052 2010 5 3 55319 -0.069619 0.393385 -0.0243697 0.0005445 -0.000165 -0.000021 0.000085 0.000063 0.0000065 0.0000131 0.000049 0.000051 2010 5 4 55320 -0.068441 0.395353 -0.0249087 0.0005372 -0.000134 -0.000002 0.000085 0.000063 0.0000044 0.0000131 0.000048 0.000051 2010 5 5 55321 -0.066768 0.397344 -0.0254723 0.0005935 -0.000103 -0.000054 0.000085 0.000063 0.0000116 0.0000131 0.000048 0.000051 2010 5 6 55322 -0.064988 0.399772 -0.0260985 0.0006623 -0.000081 -0.000063 0.000085 0.000063 0.0000097 0.0000130 0.000048 0.000050 2010 5 7 55323 -0.062980 0.402354 -0.0268336 0.0007932 -0.000062 -0.000054 0.000086 0.000063 0.0000044 0.0000130 0.000047 0.000048 2010 5 8 55324 -0.060470 0.405199 -0.0277227 0.0009490 -0.000075 -0.000060 0.000086 0.000063 0.0000085 0.0000129 0.000047 0.000048 2010 5 9 55325 -0.058870 0.408089 -0.0287558 0.0011273 -0.000100 -0.000073 0.000086 0.000063 0.0000079 0.0000128 0.000047 0.000047 2010 5 10 55326 -0.057838 0.410657 -0.0299344 0.0012142 -0.000125 -0.000085 0.000086 0.000063 0.0000053 0.0000128 0.000046 0.000046 2010 5 11 55327 -0.056625 0.413079 -0.0311512 0.0012440 -0.000149 -0.000098 0.000086 0.000063 0.0000037 0.0000128 0.000046 0.000046 2010 5 12 55328 -0.055577 0.415356 -0.0322956 0.0011576 -0.000124 -0.000070 0.000086 0.000063 0.0000030 0.0000128 0.000045 0.000045 2010 5 13 55329 -0.054505 0.417503 -0.0333394 0.0009593 -0.000085 -0.000033 0.000086 0.000063 0.0000027 0.0000128 0.000045 0.000044 2010 5 14 55330 -0.053390 0.419467 -0.0342664 0.0007991 -0.000045 0.000005 0.000086 0.000063 0.0000023 0.0000128 0.000045 0.000044 2010 5 15 55331 -0.051930 0.421518 -0.0349856 0.0006303 -0.000034 0.000013 0.000086 0.000063 0.0000057 0.0000128 0.000045 0.000044 2010 5 16 55332 -0.050600 0.423440 -0.0356508 0.0006503 -0.000034 0.000009 0.000086 0.000063 0.0000098 0.0000128 0.000046 0.000046 2010 5 17 55333 -0.049145 0.425006 -0.0363480 0.0007415 -0.000033 0.000005 0.000086 0.000063 0.0000103 0.0000129 0.000046 0.000047 2010 5 18 55334 -0.047476 0.426278 -0.0371631 0.0009164 -0.000032 0.000001 0.000086 0.000063 0.0000092 0.0000129 0.000047 0.000048 2010 5 19 55335 -0.045434 0.427724 -0.0382163 0.0011518 -0.000076 -0.000008 0.000086 0.000063 0.0000207 0.0000129 0.000048 0.000049 2010 5 20 55336 -0.043512 0.429567 -0.0395040 0.0013984 -0.000155 -0.000032 0.000085 0.000063 0.0000315 0.0000130 0.000048 0.000050 2010 5 21 55337 -0.041575 0.431436 -0.0410187 0.0015980 -0.000297 -0.000072 0.000085 0.000063 0.0000107 0.0000130 0.000049 0.000050 2010 5 22 55338 -0.039468 0.433377 -0.0426922 0.0016967 -0.000340 -0.000079 0.000085 0.000063 0.0000068 0.0000130 0.000049 0.000050 2010 5 23 55339 -0.037516 0.435488 -0.0443925 0.0016377 -0.000341 -0.000072 0.000085 0.000063 0.0000144 0.0000130 0.000049 0.000050 2010 5 24 55340 -0.035658 0.437537 -0.0459217 0.0014338 -0.000341 -0.000066 0.000085 0.000062 0.0000145 0.0000130 0.000049 0.000051 2010 5 25 55341 -0.034013 0.439605 -0.0472195 0.0011804 -0.000342 -0.000059 0.000085 0.000062 0.0000104 0.0000130 0.000049 0.000051 2010 5 26 55342 -0.032545 0.441688 -0.0482669 0.0009442 -0.000343 -0.000053 0.000085 0.000062 0.0000063 0.0000130 0.000049 0.000052 2010 5 27 55343 -0.031455 0.443778 -0.0491371 0.0007650 -0.000275 -0.000018 0.000084 0.000062 0.0000061 0.0000130 0.000049 0.000052 2010 5 28 55344 -0.030491 0.445400 -0.0498140 0.0006333 -0.000189 0.000023 0.000084 0.000062 0.0000070 0.0000130 0.000049 0.000052 2010 5 29 55345 -0.029014 0.446661 -0.0503486 0.0004798 -0.000152 0.000039 0.000084 0.000062 0.0000080 0.0000130 0.000049 0.000052 2010 5 30 55346 -0.027402 0.448075 -0.0507575 0.0003835 -0.000133 0.000044 0.000084 0.000062 0.0000082 0.0000130 0.000049 0.000052 2010 5 31 55347 -0.025966 0.450033 -0.0511310 0.0004053 -0.000114 0.000050 0.000084 0.000062 0.0000096 0.0000130 0.000049 0.000052 2010 6 1 55348 -0.024145 0.451898 -0.0516012 0.0005246 -0.000096 0.000055 0.000084 0.000062 0.0000080 0.0000130 0.000050 0.000052 2010 6 2 55349 -0.022396 0.453634 -0.0521712 0.0006401 -0.000077 0.000061 0.000084 0.000062 0.0000047 0.0000130 0.000050 0.000052 2010 6 3 55350 -0.020867 0.454992 -0.0528355 0.0007368 -0.000048 0.000061 0.000084 0.000062 0.0000051 0.0000130 0.000050 0.000052 2010 6 4 55351 -0.019408 0.456439 -0.0535710 0.0007211 -0.000018 0.000060 0.000084 0.000062 0.0000065 0.0000130 0.000050 0.000053 2010 6 5 55352 -0.017434 0.457752 -0.0543194 0.0007422 -0.000011 0.000063 0.000084 0.000062 0.0000093 0.0000130 0.000050 0.000053 2010 6 6 55353 -0.014600 0.459267 -0.0550444 0.0006990 -0.000013 0.000069 0.000084 0.000062 0.0000088 0.0000129 0.000050 0.000053 2010 6 7 55354 -0.011955 0.461092 -0.0556878 0.0005999 -0.000015 0.000075 0.000084 0.000062 0.0000082 0.0000129 0.000051 0.000053 2010 6 8 55355 -0.009581 0.462649 -0.0562229 0.0004906 -0.000016 0.000080 0.000083 0.000062 0.0000086 0.0000130 0.000051 0.000054 2010 6 9 55356 -0.006625 0.464221 -0.0566585 0.0003781 -0.000026 0.000069 0.000083 0.000062 0.0000201 0.0000130 0.000051 0.000054 2010 6 10 55357 -0.003769 0.466070 -0.0569602 0.0002519 -0.000038 0.000052 0.000083 0.000062 0.0000276 0.0000130 0.000051 0.000054 2010 6 11 55358 -0.001222 0.467682 -0.0571681 0.0001272 -0.000050 0.000036 0.000083 0.000062 0.0000096 0.0000129 0.000051 0.000054 2010 6 12 55359 0.001632 0.469277 -0.0572520 0.0000266 -0.000044 0.000027 0.000083 0.000062 0.0000092 0.0000129 0.000051 0.000053 2010 6 13 55360 0.004931 0.470844 -0.0573093 0.0000794 -0.000032 0.000020 0.000083 0.000062 0.0000097 0.0000129 0.000051 0.000053 2010 6 14 55361 0.007785 0.472344 -0.0573934 0.0001567 -0.000020 0.000014 0.000083 0.000062 0.0000068 0.0000129 0.000051 0.000052 2010 6 15 55362 0.010248 0.473411 -0.0576002 0.0002575 -0.000008 0.000008 0.000083 0.000062 0.0000036 0.0000130 0.000051 0.000052 2010 6 16 55363 0.012860 0.474390 -0.0579658 0.0004163 -0.000003 -0.000010 0.000083 0.000062 0.0000046 0.0000130 0.000052 0.000052 2010 6 17 55364 0.015881 0.475366 -0.0584914 0.0005621 0.000000 -0.000031 0.000083 0.000062 0.0000066 0.0000130 0.000052 0.000051 2010 6 18 55365 0.019171 0.476434 -0.0591078 0.0006417 0.000003 -0.000052 0.000083 0.000062 0.0000087 0.0000130 0.000052 0.000043 2010 6 19 55366 0.022355 0.477589 -0.0597487 0.0005796 0.000014 -0.000026 0.000083 0.000062 0.0000087 0.0000130 0.000052 0.000042 2010 6 20 55367 0.024862 0.478547 -0.0602116 0.0003381 0.000027 0.000017 0.000083 0.000062 0.0000090 0.0000130 0.000052 0.000041 2010 6 21 55368 0.027534 0.478811 -0.0604370 0.0001022 0.000039 0.000060 0.000083 0.000062 0.0000075 0.0000130 0.000052 0.000040 2010 6 22 55369 0.030546 0.478909 -0.0604120 -0.0001492 0.000052 0.000103 0.000083 0.000062 0.0000049 0.0000130 0.000053 0.000040 2010 6 23 55370 0.034027 0.478810 -0.0601573 -0.0003619 0.000015 0.000032 0.000083 0.000062 0.0000035 0.0000130 0.000053 0.000039 2010 6 24 55371 0.037845 0.479052 -0.0597063 -0.0005408 0.000025 -0.000001 0.000083 0.000062 0.0000023 0.0000130 0.000053 0.000038 2010 6 25 55372 0.041363 0.479675 -0.0591314 -0.0006155 0.000132 0.000057 0.000083 0.000062 0.0000076 0.0000131 0.000053 0.000037 2010 6 26 55373 0.044202 0.480396 -0.0585118 -0.0005876 0.000128 0.000096 0.000083 0.000062 0.0000103 0.0000131 0.000054 0.000037 2010 6 27 55374 0.047112 0.481227 -0.0579371 -0.0005441 0.000073 0.000119 0.000083 0.000062 0.0000076 0.0000131 0.000054 0.000036 2010 6 28 55375 0.050132 0.481943 -0.0574625 -0.0004341 0.000018 0.000141 0.000083 0.000062 0.0000051 0.0000131 0.000055 0.000035 2010 6 29 55376 0.053502 0.482481 -0.0571160 -0.0002674 -0.000037 0.000164 0.000083 0.000062 0.0000035 0.0000131 0.000056 0.000035 2010 6 30 55377 0.056917 0.482884 -0.0569194 -0.0001421 -0.000194 -0.000020 0.000083 0.000062 0.0000154 0.0000131 0.000057 0.000034 2010 7 1 55378 0.060810 0.483121 -0.0568332 -0.0000346 -0.000129 -0.000057 0.000083 0.000061 0.0000158 0.0000131 0.000057 0.000033 2010 7 2 55379 0.064626 0.483582 -0.0568266 0.0000181 0.000008 -0.000035 0.000083 0.000061 0.0000118 0.0000131 0.000058 0.000033 2010 7 3 55380 0.067976 0.483884 -0.0568832 0.0000403 -0.000021 0.000023 0.000083 0.000061 0.0000098 0.0000131 0.000058 0.000032 2010 7 4 55381 0.070986 0.484031 -0.0569131 0.0000126 -0.000113 0.000094 0.000083 0.000061 0.0000101 0.0000131 0.000059 0.000031 2010 7 5 55382 0.074367 0.484068 -0.0568753 -0.0001123 -0.000204 0.000166 0.000083 0.000061 0.0000115 0.0000131 0.000060 0.000030 2010 7 6 55383 0.077826 0.484044 -0.0566838 -0.0002617 -0.000295 0.000237 0.000083 0.000061 0.0000106 0.0000132 0.000060 0.000029 2010 7 7 55384 0.080999 0.484349 -0.0563295 -0.0004223 -0.000094 0.000117 0.000083 0.000061 0.0000087 0.0000132 0.000061 0.000028 2010 7 8 55385 0.083778 0.484272 -0.0558396 -0.0005764 -0.000083 0.000072 0.000083 0.000061 0.0000072 0.0000132 0.000061 0.000027 2010 7 9 55386 0.086306 0.484011 -0.0552345 -0.0006137 -0.000121 0.000046 0.000083 0.000061 0.0000058 0.0000132 0.000061 0.000025 2010 7 10 55387 0.088541 0.483899 -0.0546065 -0.0005899 -0.000124 0.000031 0.000083 0.000061 0.0000069 0.0000132 0.000061 0.000024 2010 7 11 55388 0.090780 0.483796 -0.0540633 -0.0004672 -0.000113 0.000020 0.000083 0.000061 0.0000085 0.0000132 0.000061 0.000023 2010 7 12 55389 0.093097 0.483718 -0.0536588 -0.0003110 -0.000102 0.000008 0.000083 0.000061 0.0000070 0.0000131 0.000062 0.000022 2010 7 13 55390 0.095416 0.483728 -0.0534821 -0.0000907 -0.000092 -0.000003 0.000083 0.000061 0.0000041 0.0000131 0.000062 0.000021 2010 7 14 55391 0.098109 0.483750 -0.0535452 0.0001289 -0.000175 -0.000013 0.000082 0.000061 0.0000120 0.0000129 0.000062 0.000020 2010 7 15 55392 0.100401 0.483838 -0.0537931 0.0002576 -0.000283 -0.000023 0.000082 0.000061 0.0000189 0.0000128 0.000063 0.000019 2010 7 16 55393 0.102279 0.483413 -0.0540779 0.0003175 -0.000391 -0.000032 0.000082 0.000061 0.0000116 0.0000127 0.000063 0.000018 2010 7 17 55394 0.104112 0.482891 -0.0544073 0.0002575 -0.000386 0.000002 0.000082 0.000061 0.0000124 0.0000126 0.000063 0.000018 2010 7 18 55395 0.106421 0.481735 -0.0545882 0.0001249 -0.000341 0.000053 0.000082 0.000061 0.0000130 0.0000125 0.000063 0.000017 2010 7 19 55396 0.109402 0.480563 -0.0546070 -0.0000826 -0.000295 0.000103 0.000082 0.000061 0.0000117 0.0000125 0.000063 0.000016 2010 7 20 55397 0.112152 0.479416 -0.0544256 -0.0003088 -0.000250 0.000154 0.000082 0.000060 0.0000101 0.0000125 0.000064 0.000015 2010 7 21 55398 0.114580 0.478594 -0.0540092 -0.0005304 0.000037 0.000009 0.000082 0.000060 0.0000116 0.0000124 0.000063 0.000015 2010 7 22 55399 0.117015 0.477854 -0.0533528 -0.0007219 0.000098 -0.000043 0.000082 0.000060 0.0000104 0.0000123 0.000063 0.000014 2010 7 23 55400 0.119505 0.477162 -0.0526044 -0.0007840 0.000074 -0.000053 0.000081 0.000060 0.0000082 0.0000123 0.000063 0.000013 2010 7 24 55401 0.121712 0.476392 -0.0518747 -0.0007306 0.000074 -0.000037 0.000081 0.000060 0.0000111 0.0000122 0.000063 0.000013 2010 7 25 55402 0.123699 0.474996 -0.0511642 -0.0006408 0.000083 -0.000011 0.000081 0.000059 0.0000110 0.0000121 0.000063 0.000012 2010 7 26 55403 0.126179 0.473547 -0.0506020 -0.0004839 0.000092 0.000016 0.000080 0.000059 0.0000098 0.0000121 0.000063 0.000011 2010 7 27 55404 0.128850 0.472249 -0.0502011 -0.0003028 0.000101 0.000042 0.000080 0.000059 0.0000092 0.0000120 0.000063 0.000011 2010 7 28 55405 0.131256 0.471261 -0.0499644 -0.0001904 0.000145 0.000026 0.000079 0.000058 0.0000094 0.0000119 0.000063 0.000010 2010 7 29 55406 0.133367 0.470462 -0.0498368 -0.0000805 0.000198 -0.000001 0.000079 0.000058 0.0000099 0.0000119 0.000064 0.000010 2010 7 30 55407 0.135254 0.469502 -0.0497688 -0.0000443 0.000251 -0.000027 0.000078 0.000058 0.0000103 0.0000118 0.000064 0.000010 2010 7 31 55408 0.137226 0.467986 -0.0496578 -0.0000946 0.000242 -0.000035 0.000078 0.000057 0.0000104 0.0000117 0.000064 0.000009 2010 8 1 55409 0.139425 0.466663 -0.0494963 -0.0001981 0.000209 -0.000035 0.000077 0.000057 0.0000104 0.0000116 0.000064 0.000009 2010 8 2 55410 0.141578 0.465484 -0.0492694 -0.0002862 0.000176 -0.000036 0.000077 0.000056 0.0000104 0.0000115 0.000063 0.000008 2010 8 3 55411 0.143833 0.464537 -0.0489529 -0.0003622 0.000143 -0.000036 0.000076 0.000056 0.0000103 0.0000115 0.000063 0.000008 2010 8 4 55412 0.145887 0.463659 -0.0485744 -0.0004220 0.000119 -0.000010 0.000075 0.000055 0.0000082 0.0000114 0.000063 0.000008 2010 8 5 55413 0.147707 0.462578 -0.0481275 -0.0004417 -0.000017 0.000074 0.000074 0.000055 0.0000055 0.0000113 0.000063 0.000007 2010 8 6 55414 0.149451 0.461308 -0.0476756 -0.0004036 -0.000051 0.000223 0.000074 0.000054 0.0000086 0.0000112 0.000062 0.000007 2010 8 7 55415 0.151576 0.459965 -0.0472704 -0.0003093 -0.000032 0.000253 0.000074 0.000054 0.0000107 0.0000111 0.000062 0.000007 2010 8 8 55416 0.153888 0.458896 -0.0470216 -0.0001409 -0.000010 0.000233 0.000075 0.000055 0.0000116 0.0000110 0.000062 0.000007 2010 8 9 55417 0.156099 0.457815 -0.0470316 0.0001312 0.000013 0.000214 0.000076 0.000056 0.0000126 0.0000109 0.000061 0.000008 2010 8 10 55418 0.158406 0.456708 -0.0473476 0.0004405 0.000035 0.000194 0.000077 0.000057 0.0000136 0.0000108 0.000061 0.000008 2010 8 11 55419 0.161054 0.455365 -0.0479588 0.0006678 -0.000046 0.000177 0.000078 0.000057 0.0000152 0.0000107 0.000061 0.000009 2010 8 12 55420 0.164080 0.454296 -0.0487261 0.0007496 -0.000154 0.000161 0.000079 0.000058 0.0000151 0.0000106 0.000060 0.000009 2010 8 13 55421 0.166586 0.452974 -0.0494394 0.0006663 0.000097 0.000150 0.000080 0.000058 0.0000078 0.0000105 0.000060 0.000009 2010 8 14 55422 0.168932 0.451457 -0.0500724 0.0005146 0.000172 0.000127 0.000080 0.000059 0.0000056 0.0000103 0.000059 0.000010 2010 8 15 55423 0.171277 0.449593 -0.0504865 0.0002693 0.000137 0.000100 0.000081 0.000059 0.0000052 0.0000102 0.000058 0.000010 2010 8 16 55424 0.174463 0.447951 -0.0506289 0.0000554 0.000103 0.000074 0.000081 0.000060 0.0000048 0.0000101 0.000058 0.000010 2010 8 17 55425 0.177699 0.447037 -0.0505329 -0.0001848 0.000068 0.000047 0.000082 0.000060 0.0000044 0.0000100 0.000057 0.000011 2010 8 18 55426 0.180229 0.446014 -0.0502360 -0.0003272 0.000085 0.000046 0.000082 0.000061 0.0000053 0.0000098 0.000057 0.000011 2010 8 19 55427 0.182479 0.444890 -0.0498519 -0.0003916 0.000117 0.000053 0.000083 0.000061 0.0000066 0.0000097 0.000057 0.000012 2010 8 20 55428 0.184445 0.443119 -0.0494712 -0.0003644 0.000148 0.000060 0.000083 0.000061 0.0000078 0.0000095 0.000057 0.000012 2010 8 21 55429 0.186656 0.441252 -0.0491318 -0.0002608 0.000144 0.000052 0.000084 0.000062 0.0000175 0.0000093 0.000057 0.000013 2010 8 22 55430 0.189059 0.439196 -0.0489340 -0.0001168 0.000127 0.000038 0.000084 0.000062 0.0000190 0.0000092 0.000057 0.000013 2010 8 23 55431 0.191992 0.437190 -0.0489083 0.0000469 0.000111 0.000024 0.000084 0.000062 0.0000130 0.0000090 0.000057 0.000014 2010 8 24 55432 0.194864 0.435748 -0.0490340 0.0001689 0.000094 0.000009 0.000085 0.000062 0.0000062 0.0000088 0.000057 0.000015 2010 8 25 55433 0.197366 0.434523 -0.0492887 0.0002825 0.000101 -0.000008 0.000085 0.000062 0.0000058 0.0000086 0.000057 0.000015 2010 8 26 55434 0.199402 0.433293 -0.0496304 0.0003681 0.000113 -0.000026 0.000085 0.000063 0.0000071 0.0000085 0.000057 0.000016 2010 8 27 55435 0.201141 0.431739 -0.0500080 0.0003949 0.000125 -0.000045 0.000085 0.000063 0.0000084 0.0000083 0.000057 0.000017 2010 8 28 55436 0.202368 0.429940 -0.0503284 0.0003361 0.000139 -0.000056 0.000085 0.000063 0.0000125 0.0000081 0.000057 0.000018 2010 8 29 55437 0.203337 0.428392 -0.0505966 0.0002379 0.000153 -0.000064 0.000085 0.000063 0.0000167 0.0000079 0.000057 0.000018 2010 8 30 55438 0.204352 0.427105 -0.0508042 0.0001428 0.000167 -0.000072 0.000085 0.000063 0.0000130 0.0000077 0.000057 0.000019 2010 8 31 55439 0.205638 0.425705 -0.0509107 0.0000397 0.000181 -0.000080 0.000085 0.000063 0.0000055 0.0000076 0.000057 0.000020 2010 9 1 55440 0.206919 0.424624 -0.0509038 -0.0000354 0.000165 -0.000086 0.000086 0.000063 0.0000058 0.0000074 0.000058 0.000021 2010 9 2 55441 0.207575 0.423109 -0.0508241 -0.0000895 0.000141 -0.000092 0.000086 0.000063 0.0000082 0.0000072 0.000058 0.000023 2010 9 3 55442 0.208700 0.421266 -0.0507399 -0.0000703 0.000117 -0.000097 0.000086 0.000063 0.0000105 0.0000070 0.000058 0.000024 2010 9 4 55443 0.210002 0.419352 -0.0507097 0.0000465 0.000108 -0.000084 0.000086 0.000063 0.0000141 0.0000068 0.000058 0.000025 2010 9 5 55444 0.211518 0.417752 -0.0508555 0.0002736 0.000103 -0.000065 0.000086 0.000064 0.0000180 0.0000066 0.000058 0.000026 2010 9 6 55445 0.212677 0.416266 -0.0512576 0.0005146 0.000099 -0.000046 0.000087 0.000064 0.0000249 0.0000065 0.000058 0.000028 2010 9 7 55446 0.214091 0.414439 -0.0519407 0.0007755 0.000095 -0.000026 0.000087 0.000064 0.0000331 0.0000063 0.000058 0.000029 2010 9 8 55447 0.215749 0.412655 -0.0528593 0.0010049 0.000151 0.000050 0.000087 0.000064 0.0000162 0.0000061 0.000058 0.000031 2010 9 9 55448 0.217134 0.410857 -0.0539362 0.0010643 0.000122 0.000061 0.000087 0.000064 0.0000108 0.0000059 0.000058 0.000032 2010 9 10 55449 0.218691 0.408761 -0.0549671 0.0009349 0.000070 0.000055 0.000087 0.000065 0.0000083 0.0000058 0.000057 0.000033 2010 9 11 55450 0.220329 0.406584 -0.0557592 0.0006611 0.000051 0.000060 0.000087 0.000065 0.0000181 0.0000056 0.000057 0.000034 2010 9 12 55451 0.221801 0.404395 -0.0563034 0.0004088 0.000045 0.000069 0.000087 0.000065 0.0000148 0.0000054 0.000057 0.000036 2010 9 13 55452 0.222791 0.402247 -0.0565484 0.0001253 0.000039 0.000077 0.000087 0.000065 0.0000100 0.0000053 0.000057 0.000037 2010 9 14 55453 0.223636 0.399846 -0.0565559 -0.0000859 0.000033 0.000085 0.000088 0.000065 0.0000088 0.0000051 0.000057 0.000039 2010 9 15 55454 0.224828 0.396984 -0.0564331 -0.0001400 0.000108 0.000062 0.000088 0.000065 0.0000120 0.0000050 0.000057 0.000040 2010 9 16 55455 0.226559 0.394674 -0.0562857 -0.0001400 0.000227 0.000084 0.000087 0.000065 0.0000127 0.0000048 0.000058 0.000042 2010 9 17 55456 0.228017 0.392853 -0.0561820 -0.0000651 0.000353 0.000122 0.000087 0.000065 0.0000123 0.0000047 0.000058 0.000043 2010 9 18 55457 0.229302 0.391083 -0.0561765 0.0000447 0.000328 0.000099 0.000087 0.000065 0.0000168 0.0000045 0.000058 0.000045 2010 9 19 55458 0.230654 0.389452 -0.0563129 0.0002124 0.000247 0.000055 0.000087 0.000065 0.0000188 0.0000044 0.000058 0.000046 2010 9 20 55459 0.231450 0.387975 -0.0565573 0.0003037 0.000165 0.000010 0.000087 0.000065 0.0000159 0.0000042 0.000058 0.000047 2010 9 21 55460 0.232062 0.386045 -0.0569043 0.0003369 0.000083 -0.000035 0.000087 0.000066 0.0000118 0.0000041 0.000058 0.000049 2010 9 22 55461 0.232323 0.383907 -0.0573029 0.0004201 0.000284 0.000070 0.000087 0.000066 0.0000182 0.0000041 0.000058 0.000050 2010 9 23 55462 0.233112 0.381778 -0.0577824 0.0004966 0.000284 0.000140 0.000087 0.000066 0.0000148 0.0000041 0.000057 0.000051 2010 9 24 55463 0.234312 0.380122 -0.0582727 0.0005829 0.000202 0.000188 0.000088 0.000066 0.0000076 0.0000042 0.000057 0.000052 2010 9 25 55464 0.234823 0.378507 -0.0587331 0.0004552 0.000228 0.000140 0.000088 0.000066 0.0000118 0.0000043 0.000057 0.000052 2010 9 26 55465 0.235263 0.376735 -0.0591584 0.0003731 0.000294 0.000057 0.000088 0.000066 0.0000142 0.0000045 0.000057 0.000068 2010 9 27 55466 0.235266 0.374902 -0.0594678 0.0002664 0.000360 -0.000027 0.000088 0.000066 0.0000117 0.0000046 0.000057 0.000067 2010 9 28 55467 0.235347 0.372741 -0.0596697 0.0001390 0.000425 -0.000110 0.000088 0.000066 0.0000082 0.0000048 0.000057 0.000066 2010 9 29 55468 0.235143 0.370387 -0.0597782 0.0000905 0.000430 -0.000070 0.000088 0.000066 0.0000118 0.0000049 0.000056 0.000065 2010 9 30 55469 0.234770 0.368065 -0.0598876 0.0001433 0.000418 0.000001 0.000089 0.000066 0.0000146 0.0000051 0.000056 0.000063 2010 10 1 55470 0.234206 0.365784 -0.0600999 0.0002405 0.000406 0.000073 0.000089 0.000066 0.0000074 0.0000052 0.000056 0.000062 2010 10 2 55471 0.234008 0.363473 -0.0604511 0.0004651 0.000389 0.000066 0.000089 0.000066 0.0000098 0.0000054 0.000056 0.000060 2010 10 3 55472 0.233983 0.360948 -0.0611065 0.0008261 0.000369 0.000030 0.000089 0.000066 0.0000150 0.0000055 0.000056 0.000059 2010 10 4 55473 0.233968 0.358523 -0.0621353 0.0011711 0.000350 -0.000005 0.000089 0.000066 0.0000149 0.0000057 0.000055 0.000058 2010 10 5 55474 0.234187 0.356204 -0.0634901 0.0014717 0.000331 -0.000041 0.000090 0.000066 0.0000122 0.0000059 0.000055 0.000056 2010 10 6 55475 0.234848 0.353787 -0.0651007 0.0016452 0.000421 -0.000068 0.000090 0.000066 0.0000065 0.0000060 0.000055 0.000055 2010 10 7 55476 0.235042 0.351597 -0.0667967 0.0016732 0.000341 -0.000066 0.000090 0.000066 0.0000052 0.0000062 0.000055 0.000054 2010 10 8 55477 0.234905 0.349100 -0.0684245 0.0015244 0.000200 -0.000058 0.000090 0.000067 0.0000055 0.0000064 0.000054 0.000053 2010 10 9 55478 0.234465 0.346542 -0.0698513 0.0013084 0.000162 -0.000033 0.000090 0.000067 0.0000086 0.0000066 0.000054 0.000051 2010 10 10 55479 0.234147 0.344121 -0.0710536 0.0010737 0.000163 -0.000002 0.000090 0.000067 0.0000074 0.0000067 0.000054 0.000050 2010 10 11 55480 0.233924 0.341941 -0.0720112 0.0009009 0.000163 0.000030 0.000090 0.000067 0.0000078 0.0000069 0.000054 0.000049 2010 10 12 55481 0.233758 0.339405 -0.0728329 0.0008046 0.000163 0.000061 0.000090 0.000067 0.0000074 0.0000071 0.000053 0.000047 2010 10 13 55482 0.233849 0.337180 -0.0736104 0.0007676 0.000163 0.000092 0.000090 0.000067 0.0000056 0.0000073 0.000053 0.000046 2010 10 14 55483 0.234146 0.335496 -0.0743761 0.0007972 0.000214 -0.000065 0.000091 0.000067 0.0000029 0.0000075 0.000053 0.000045 2010 10 15 55484 0.234363 0.333927 -0.0752142 0.0008856 0.000088 0.000003 0.000091 0.000067 0.0000062 0.0000076 0.000053 0.000046 2010 10 16 55485 0.234103 0.332492 -0.0761102 0.0009448 0.000094 0.000033 0.000090 0.000067 0.0000070 0.0000078 0.000053 0.000048 2010 10 17 55486 0.233525 0.330797 -0.0771057 0.0010346 0.000171 0.000019 0.000090 0.000067 0.0000071 0.0000080 0.000054 0.000049 2010 10 18 55487 0.233222 0.328919 -0.0781982 0.0011280 0.000247 0.000005 0.000090 0.000067 0.0000116 0.0000081 0.000054 0.000050 2010 10 19 55488 0.232914 0.326948 -0.0793537 0.0012417 0.000323 -0.000009 0.000091 0.000067 0.0000180 0.0000083 0.000055 0.000052 2010 10 20 55489 0.232445 0.325003 -0.0806178 0.0012538 0.000323 -0.000027 0.000091 0.000067 0.0000210 0.0000085 0.000055 0.000053 2010 10 21 55490 0.231861 0.323025 -0.0818582 0.0011776 0.000303 -0.000047 0.000091 0.000067 0.0000229 0.0000087 0.000056 0.000054 2010 10 22 55491 0.231333 0.320619 -0.0829506 0.0010932 0.000283 -0.000068 0.000091 0.000067 0.0000238 0.0000088 0.000056 0.000056 2010 10 23 55492 0.230646 0.318324 -0.0839396 0.0009445 0.000247 -0.000046 0.000091 0.000067 0.0000167 0.0000090 0.000056 0.000057 2010 10 24 55493 0.230121 0.316431 -0.0847952 0.0008074 0.000206 -0.000007 0.000091 0.000067 0.0000114 0.0000091 0.000056 0.000058 2010 10 25 55494 0.229024 0.314946 -0.0855127 0.0006763 0.000164 0.000031 0.000091 0.000067 0.0000087 0.0000093 0.000056 0.000059 2010 10 26 55495 0.227437 0.312977 -0.0861201 0.0005881 0.000123 0.000070 0.000091 0.000067 0.0000060 0.0000094 0.000056 0.000060 2010 10 27 55496 0.226259 0.310680 -0.0866387 0.0005507 0.000208 0.000056 0.000092 0.000067 0.0000119 0.0000095 0.000056 0.000060 2010 10 28 55497 0.225378 0.308305 -0.0871737 0.0005610 0.000326 0.000027 0.000092 0.000067 0.0000200 0.0000097 0.000056 0.000060 2010 10 29 55498 0.224622 0.305988 -0.0878244 0.0007233 0.000444 -0.000001 0.000092 0.000067 0.0000282 0.0000098 0.000056 0.000061 2010 10 30 55499 0.224126 0.303539 -0.0886605 0.0009582 0.000446 0.000002 0.000092 0.000068 0.0000160 0.0000100 0.000055 0.000061 2010 10 31 55500 0.223354 0.301632 -0.0897496 0.0012110 0.000403 0.000018 0.000092 0.000067 0.0000101 0.0000101 0.000055 0.000060 2010 11 1 55501 0.222529 0.299570 -0.0911248 0.0014787 0.000360 0.000033 0.000092 0.000067 0.0000115 0.0000103 0.000054 0.000060 2010 11 2 55502 0.221458 0.297248 -0.0927329 0.0016847 0.000316 0.000049 0.000092 0.000067 0.0000105 0.0000104 0.000054 0.000059 2010 11 3 55503 0.220874 0.294257 -0.0944537 0.0017539 0.000273 0.000065 0.000092 0.000067 0.0000076 0.0000106 0.000053 0.000059 2010 11 4 55504 0.220587 0.291814 -0.0961615 0.0016279 0.000284 0.000045 0.000092 0.000067 0.0000068 0.0000107 0.000053 0.000058 2010 11 5 55505 0.220418 0.289494 -0.0977173 0.0014353 0.000310 0.000016 0.000092 0.000067 0.0000065 0.0000108 0.000053 0.000058 2010 11 6 55506 0.220287 0.287268 -0.0990923 0.0012262 0.000329 0.000000 0.000092 0.000067 0.0000065 0.0000110 0.000052 0.000057 2010 11 7 55507 0.219517 0.285400 -0.1001737 0.0009736 0.000344 -0.000012 0.000091 0.000067 0.0000069 0.0000111 0.000052 0.000057 2010 11 8 55508 0.217646 0.283043 -0.1009893 0.0007521 0.000359 -0.000024 0.000091 0.000067 0.0000099 0.0000113 0.000052 0.000056 2010 11 9 55509 0.216167 0.280636 -0.1016684 0.0006267 0.000375 -0.000036 0.000091 0.000067 0.0000142 0.0000114 0.000052 0.000056 2010 11 10 55510 0.214940 0.278714 -0.1022454 0.0005720 0.000351 -0.000083 0.000091 0.000067 0.0000142 0.0000116 0.000051 0.000055 2010 11 11 55511 0.213761 0.276854 -0.1028453 0.0006328 0.000317 -0.000139 0.000091 0.000067 0.0000130 0.0000117 0.000051 0.000054 2010 11 12 55512 0.212691 0.275041 -0.1035313 0.0007448 0.000283 -0.000196 0.000091 0.000067 0.0000119 0.0000118 0.000051 0.000053 2010 11 13 55513 0.211945 0.273506 -0.1043664 0.0009034 0.000286 -0.000183 0.000091 0.000067 0.0000104 0.0000119 0.000050 0.000052 2010 11 14 55514 0.210984 0.272302 -0.1053536 0.0010341 0.000303 -0.000145 0.000091 0.000067 0.0000083 0.0000120 0.000050 0.000050 2010 11 15 55515 0.209958 0.270695 -0.1064500 0.0011549 0.000321 -0.000108 0.000091 0.000067 0.0000070 0.0000121 0.000049 0.000049 2010 11 16 55516 0.208823 0.268637 -0.1075981 0.0011886 0.000338 -0.000070 0.000091 0.000067 0.0000061 0.0000122 0.000049 0.000048 2010 11 17 55517 0.207907 0.266088 -0.1087634 0.0011381 0.000393 -0.000073 0.000091 0.000067 0.0000119 0.0000123 0.000048 0.000047 2010 11 18 55518 0.207105 0.263486 -0.1098764 0.0010611 0.000373 -0.000109 0.000091 0.000067 0.0000049 0.0000124 0.000048 0.000046 2010 11 19 55519 0.206379 0.260891 -0.1108910 0.0009335 0.000338 -0.000148 0.000091 0.000067 0.0000132 0.0000125 0.000048 0.000047 2010 11 20 55520 0.205526 0.258292 -0.1117420 0.0007689 0.000321 -0.000147 0.000090 0.000067 0.0000116 0.0000126 0.000048 0.000048 2010 11 21 55521 0.205090 0.256079 -0.1124284 0.0006211 0.000311 -0.000131 0.000090 0.000067 0.0000095 0.0000126 0.000049 0.000048 2010 11 22 55522 0.204853 0.254145 -0.1129852 0.0005231 0.000300 -0.000115 0.000090 0.000067 0.0000087 0.0000127 0.000049 0.000049 2010 11 23 55523 0.204288 0.252302 -0.1134635 0.0004799 0.000289 -0.000099 0.000090 0.000067 0.0000071 0.0000128 0.000050 0.000049 2010 11 24 55524 0.202870 0.250666 -0.1139499 0.0005019 0.000217 -0.000273 0.000090 0.000067 0.0000087 0.0000128 0.000050 0.000050 2010 11 25 55525 0.201220 0.248748 -0.1145148 0.0006343 0.000351 -0.000439 0.000090 0.000067 0.0000085 0.0000129 0.000050 0.000050 2010 11 26 55526 0.199921 0.246924 -0.1152321 0.0008123 0.000566 -0.000583 0.000090 0.000067 0.0000071 0.0000129 0.000050 0.000050 2010 11 27 55527 0.198784 0.245550 -0.1161515 0.0010410 0.000498 -0.000474 0.000090 0.000067 0.0000058 0.0000129 0.000050 0.000049 2010 11 28 55528 0.197267 0.244398 -0.1173305 0.0012968 0.000430 -0.000365 0.000090 0.000067 0.0000063 0.0000130 0.000050 0.000048 2010 11 29 55529 0.195818 0.242781 -0.1186656 0.0013695 0.000362 -0.000256 0.000090 0.000067 0.0000061 0.0000130 0.000050 0.000048 2010 11 30 55530 0.194729 0.241042 -0.1200619 0.0013603 0.000294 -0.000146 0.000090 0.000067 0.0000051 0.0000131 0.000050 0.000047 2010 12 1 55531 0.193551 0.239662 -0.1214508 0.0012953 -0.000141 -0.000270 0.000090 0.000067 0.0000180 0.0000133 0.000050 0.000047 2010 12 2 55532 0.192122 0.238421 -0.1226957 0.0011182 -0.000672 -0.000455 0.000090 0.000067 0.0000331 0.0000134 0.000050 0.000047 2010 12 3 55533 0.191051 0.236888 -0.1236679 0.0008970 -0.001204 -0.000639 0.000090 0.000067 0.0000427 0.0000134 0.000049 0.000046 2010 12 4 55534 0.190090 0.235407 -0.1244067 0.0006320 -0.001034 -0.000593 0.000090 0.000067 0.0000189 0.0000134 0.000049 0.000046 2010 12 5 55535 0.188372 0.234016 -0.1249515 0.0004653 -0.000604 -0.000460 0.000091 0.000067 0.0000073 0.0000134 0.000049 0.000045 2010 12 6 55536 0.186403 0.232395 -0.1253878 0.0004156 -0.000173 -0.000328 0.000091 0.000067 0.0000062 0.0000134 0.000048 0.000044 2010 12 7 55537 0.184857 0.230824 -0.1257855 0.0004469 0.000257 -0.000195 0.000091 0.000067 0.0000043 0.0000134 0.000048 0.000044 2010 12 8 55538 0.183787 0.229456 -0.1262427 0.0005080 0.000330 -0.000190 0.000091 0.000067 0.0000024 0.0000134 0.000048 0.000043 2010 12 9 55539 0.183114 0.228396 -0.1268057 0.0006329 0.000209 -0.000191 0.000091 0.000067 0.0000033 0.0000134 0.000048 0.000044 2010 12 10 55540 0.181894 0.227732 -0.1274673 0.0006999 0.000301 -0.000309 0.000091 0.000067 0.0000051 0.0000134 0.000048 0.000045 2010 12 11 55541 0.179959 0.226774 -0.1281858 0.0007179 0.000357 -0.000323 0.000091 0.000067 0.0000085 0.0000133 0.000049 0.000045 2010 12 12 55542 0.177839 0.225763 -0.1289152 0.0007310 0.000369 -0.000282 0.000091 0.000067 0.0000078 0.0000133 0.000049 0.000046 2010 12 13 55543 0.175228 0.225170 -0.1296415 0.0007270 0.000381 -0.000241 0.000091 0.000067 0.0000056 0.0000133 0.000049 0.000046 2010 12 14 55544 0.171865 0.224034 -0.1303463 0.0006899 0.000393 -0.000199 0.000091 0.000067 0.0000037 0.0000133 0.000049 0.000047 2010 12 15 55545 0.168293 0.222431 -0.1309912 0.0005839 0.000353 -0.000156 0.000091 0.000068 0.0000101 0.0000133 0.000050 0.000047 2010 12 16 55546 0.165854 0.220751 -0.1315524 0.0005228 0.000253 -0.000090 0.000091 0.000068 0.0000154 0.0000133 0.000050 0.000047 2010 12 17 55547 0.164837 0.219684 -0.1320368 0.0004482 0.000227 -0.000113 0.000091 0.000068 0.0000085 0.0000133 0.000050 0.000047 2010 12 18 55548 0.164170 0.218808 -0.1324176 0.0003281 0.000238 -0.000151 0.000091 0.000068 0.0000090 0.0000132 0.000050 0.000047 2010 12 19 55549 0.163287 0.217770 -0.1326897 0.0002052 0.000251 -0.000182 0.000091 0.000068 0.0000122 0.0000132 0.000049 0.000047 2010 12 20 55550 0.161480 0.216698 -0.1328195 0.0000906 0.000265 -0.000213 0.000091 0.000068 0.0000095 0.0000133 0.000049 0.000046 2010 12 21 55551 0.159235 0.215500 -0.1329022 0.0000914 0.000278 -0.000245 0.000091 0.000068 0.0000038 0.0000133 0.000049 0.000046 2010 12 22 55552 0.157000 0.214400 -0.1330838 0.0002538 0.000273 -0.000264 0.000091 0.000068 0.0000032 0.0000133 0.000049 0.000046 2010 12 23 55553 0.154803 0.213210 -0.1334306 0.0004622 0.000263 -0.000281 0.000091 0.000068 0.0000039 0.0000133 0.000049 0.000046 2010 12 24 55554 0.153098 0.212273 -0.1339840 0.0006646 0.000242 -0.000278 0.000091 0.000068 0.0000052 0.0000132 0.000049 0.000046 2010 12 25 55555 0.151504 0.211571 -0.1347659 0.0008407 0.000217 -0.000269 0.000091 0.000068 0.0000067 0.0000132 0.000048 0.000045 2010 12 26 55556 0.149624 0.210657 -0.1357365 0.0010748 0.000192 -0.000259 0.000091 0.000068 0.0000082 0.0000132 0.000048 0.000045 2010 12 27 55557 0.147412 0.209379 -0.1368427 0.0011528 0.000167 -0.000250 0.000092 0.000068 0.0000070 0.0000132 0.000048 0.000044 2010 12 28 55558 0.144647 0.207774 -0.1379514 0.0010561 0.000142 -0.000241 0.000092 0.000068 0.0000043 0.0000132 0.000048 0.000044 2010 12 29 55559 0.141028 0.206536 -0.1389040 0.0008484 0.000142 -0.000233 0.000092 0.000068 0.0000039 0.0000133 0.000047 0.000043 2010 12 30 55560 0.137269 0.205248 -0.1396538 0.0006553 0.000148 -0.000225 0.000092 0.000068 0.0000040 0.0000133 0.000047 0.000043 2010 12 31 55561 0.134028 0.204139 -0.1402040 0.0004831 0.000162 -0.000225 0.000092 0.000068 0.0000057 0.0000133 0.000046 0.000042 2011 1 1 55562 0.130959 0.203165 -0.1405619 0.0002813 0.000179 -0.000227 0.000063 0.000067 0.0000087 0.0000131 0.000058 0.000045 2011 1 2 55563 0.127715 0.202326 -0.1407870 0.0002121 0.000197 -0.000230 0.000063 0.000067 0.0000079 0.0000131 0.000058 0.000045 2011 1 3 55564 0.124413 0.201437 -0.1409510 0.0001566 0.000214 -0.000232 0.000063 0.000067 0.0000055 0.0000132 0.000057 0.000044 2011 1 4 55565 0.121377 0.200654 -0.1411264 0.0002032 0.000231 -0.000235 0.000063 0.000067 0.0000030 0.0000132 0.000056 0.000044 2011 1 5 55566 0.117734 0.200388 -0.1413407 0.0002471 0.000228 -0.000245 0.000063 0.000067 0.0000100 0.0000133 0.000056 0.000044 2011 1 6 55567 0.113744 0.199890 -0.1416521 0.0003623 0.000218 -0.000258 0.000063 0.000067 0.0000153 0.0000133 0.000056 0.000044 2011 1 7 55568 0.110096 0.199324 -0.1420692 0.0004851 0.000209 -0.000270 0.000063 0.000068 0.0000053 0.0000133 0.000056 0.000044 2011 1 8 55569 0.106247 0.198743 -0.1425732 0.0005516 0.000204 -0.000277 0.000063 0.000068 0.0000074 0.0000133 0.000055 0.000044 2011 1 9 55570 0.103002 0.197677 -0.1431340 0.0005781 0.000201 -0.000282 0.000063 0.000068 0.0000092 0.0000133 0.000055 0.000045 2011 1 10 55571 0.100999 0.196737 -0.1437331 0.0005890 0.000198 -0.000287 0.000063 0.000068 0.0000065 0.0000133 0.000055 0.000045 2011 1 11 55572 0.099966 0.196028 -0.1443309 0.0005829 0.000194 -0.000291 0.000063 0.000068 0.0000027 0.0000133 0.000054 0.000045 2011 1 12 55573 0.099121 0.196001 -0.1449331 0.0005607 0.000300 -0.000287 0.000063 0.000068 0.0000226 0.0000133 0.000054 0.000045 2011 1 13 55574 0.097707 0.196138 -0.1454783 0.0005278 0.000435 -0.000281 0.000063 0.000068 0.0000379 0.0000133 0.000055 0.000046 2011 1 14 55575 0.095398 0.196117 -0.1459545 0.0004414 0.000569 -0.000275 0.000063 0.000068 0.0000124 0.0000132 0.000055 0.000046 2011 1 15 55576 0.092370 0.195878 -0.1463280 0.0003428 0.000503 -0.000281 0.000063 0.000068 0.0000083 0.0000132 0.000055 0.000047 2011 1 16 55577 0.088884 0.195837 -0.1466479 0.0002888 0.000360 -0.000292 0.000063 0.000068 0.0000098 0.0000132 0.000056 0.000047 2011 1 17 55578 0.084953 0.195543 -0.1469091 0.0002484 0.000217 -0.000303 0.000063 0.000068 0.0000079 0.0000132 0.000056 0.000047 2011 1 18 55579 0.081304 0.195001 -0.1471746 0.0003402 0.000075 -0.000314 0.000063 0.000067 0.0000055 0.0000132 0.000056 0.000047 2011 1 19 55580 0.077908 0.194827 -0.1475565 0.0004163 0.000089 -0.000393 0.000063 0.000067 0.0000036 0.0000132 0.000056 0.000047 2011 1 20 55581 0.074672 0.194828 -0.1480615 0.0005909 0.000129 -0.000361 0.000063 0.000067 0.0000037 0.0000133 0.000056 0.000047 2011 1 21 55582 0.071357 0.194739 -0.1487896 0.0008407 0.000175 -0.000300 0.000063 0.000067 0.0000044 0.0000132 0.000057 0.000047 2011 1 22 55583 0.067931 0.194482 -0.1497184 0.0010305 0.000174 -0.000277 0.000063 0.000068 0.0000082 0.0000132 0.000057 0.000047 2011 1 23 55584 0.064827 0.194605 -0.1508300 0.0011396 0.000156 -0.000266 0.000064 0.000068 0.0000125 0.0000132 0.000058 0.000047 2011 1 24 55585 0.061692 0.194921 -0.1520081 0.0011102 0.000137 -0.000256 0.000064 0.000068 0.0000103 0.0000133 0.000058 0.000047 2011 1 25 55586 0.058609 0.195582 -0.1530958 0.0009949 0.000118 -0.000246 0.000064 0.000068 0.0000052 0.0000133 0.000058 0.000047 2011 1 26 55587 0.055408 0.196337 -0.1540122 0.0008030 0.000144 -0.000230 0.000064 0.000068 0.0000046 0.0000134 0.000059 0.000047 2011 1 27 55588 0.052335 0.197310 -0.1547148 0.0005899 0.000180 -0.000213 0.000064 0.000068 0.0000051 0.0000134 0.000059 0.000048 2011 1 28 55589 0.049358 0.198111 -0.1552211 0.0003578 0.000217 -0.000195 0.000064 0.000068 0.0000057 0.0000134 0.000059 0.000048 2011 1 29 55590 0.047472 0.198614 -0.1555766 0.0003126 0.000299 -0.000214 0.000064 0.000068 0.0000084 0.0000134 0.000060 0.000049 2011 1 30 55591 0.046055 0.199363 -0.1558746 0.0002644 0.000349 -0.000251 0.000064 0.000068 0.0000090 0.0000135 0.000060 0.000049 2011 1 31 55592 0.045108 0.199778 -0.1561888 0.0003226 0.000255 -0.000300 0.000064 0.000068 0.0000067 0.0000135 0.000060 0.000049 2011 2 1 55593 0.044446 0.200635 -0.1565741 0.0003970 0.000160 -0.000349 0.000064 0.000068 0.0000036 0.0000136 0.000060 0.000049 2011 2 2 55594 0.043737 0.201480 -0.1570585 0.0005690 0.000092 -0.000337 0.000064 0.000068 0.0000059 0.0000136 0.000060 0.000050 2011 2 3 55595 0.042881 0.202305 -0.1577068 0.0006870 0.000002 -0.000310 0.000064 0.000068 0.0000194 0.0000137 0.000060 0.000050 2011 2 4 55596 0.041602 0.202613 -0.1584274 0.0007851 0.000061 -0.000283 0.000064 0.000068 0.0000094 0.0000137 0.000060 0.000050 2011 2 5 55597 0.040235 0.202880 -0.1592139 0.0008092 0.000099 -0.000272 0.000064 0.000067 0.0000080 0.0000137 0.000060 0.000051 2011 2 6 55598 0.039049 0.203345 -0.1599990 0.0007780 0.000110 -0.000267 0.000063 0.000067 0.0000092 0.0000137 0.000060 0.000051 2011 2 7 55599 0.038219 0.204293 -0.1607575 0.0007354 0.000121 -0.000262 0.000063 0.000067 0.0000083 0.0000138 0.000060 0.000051 2011 2 8 55600 0.037562 0.205738 -0.1614635 0.0006693 0.000132 -0.000257 0.000063 0.000067 0.0000073 0.0000138 0.000059 0.000051 2011 2 9 55601 0.036289 0.207354 -0.1620869 0.0005930 0.000120 -0.000312 0.000063 0.000067 0.0000431 0.0000138 0.000059 0.000051 2011 2 10 55602 0.034283 0.208674 -0.1626188 0.0005157 0.000107 -0.000324 0.000063 0.000067 0.0000434 0.0000139 0.000059 0.000051 2011 2 11 55603 0.032074 0.209600 -0.1630842 0.0004241 0.000111 -0.000252 0.000063 0.000067 0.0000134 0.0000139 0.000058 0.000050 2011 2 12 55604 0.030655 0.210516 -0.1634765 0.0003772 0.000126 -0.000288 0.000063 0.000066 0.0000087 0.0000139 0.000057 0.000049 2011 2 13 55605 0.029416 0.211613 -0.1638268 0.0003597 0.000142 -0.000373 0.000063 0.000066 0.0000156 0.0000139 0.000056 0.000049 2011 2 14 55606 0.027752 0.212398 -0.1641900 0.0004118 0.000158 -0.000457 0.000063 0.000066 0.0000139 0.0000140 0.000055 0.000048 2011 2 15 55607 0.026118 0.213089 -0.1646675 0.0005640 0.000174 -0.000542 0.000063 0.000066 0.0000079 0.0000140 0.000054 0.000047 2011 2 16 55608 0.024923 0.214428 -0.1653742 0.0008510 0.000168 -0.000556 0.000063 0.000066 0.0000065 0.0000141 0.000053 0.000046 2011 2 17 55609 0.023469 0.216313 -0.1663660 0.0011584 0.000156 -0.000550 0.000063 0.000066 0.0000062 0.0000141 0.000052 0.000044 2011 2 18 55610 0.021796 0.217912 -0.1676491 0.0014004 0.000144 -0.000545 0.000063 0.000066 0.0000059 0.0000141 0.000051 0.000043 2011 2 19 55611 0.020058 0.218973 -0.1691320 0.0015975 0.000119 -0.000517 0.000063 0.000066 0.0000088 0.0000141 0.000050 0.000042 2011 2 20 55612 0.018543 0.220071 -0.1707632 0.0016650 0.000090 -0.000482 0.000063 0.000066 0.0000106 0.0000141 0.000050 0.000041 2011 2 21 55613 0.016808 0.220756 -0.1723881 0.0015498 0.000061 -0.000446 0.000063 0.000066 0.0000082 0.0000142 0.000049 0.000040 2011 2 22 55614 0.015200 0.221295 -0.1738330 0.0013124 0.000032 -0.000410 0.000063 0.000066 0.0000042 0.0000142 0.000048 0.000039 2011 2 23 55615 0.013824 0.221991 -0.1749976 0.0010253 0.000007 -0.000332 0.000063 0.000066 0.0000019 0.0000142 0.000047 0.000038 2011 2 24 55616 0.012317 0.222942 -0.1758512 0.0007054 -0.000025 -0.000387 0.000063 0.000066 0.0000020 0.0000142 0.000047 0.000038 2011 2 25 55617 0.010225 0.223995 -0.1764740 0.0005387 -0.000062 -0.000332 0.000063 0.000066 0.0000119 0.0000142 0.000048 0.000039 2011 2 26 55618 0.007649 0.224742 -0.1769661 0.0004488 -0.000036 -0.000320 0.000063 0.000066 0.0000118 0.0000142 0.000048 0.000039 2011 2 27 55619 0.004921 0.225662 -0.1773972 0.0004188 0.000014 -0.000341 0.000063 0.000066 0.0000097 0.0000141 0.000049 0.000040 2011 2 28 55620 0.002538 0.226931 -0.1778730 0.0005011 0.000064 -0.000362 0.000062 0.000066 0.0000077 0.0000142 0.000049 0.000040 2011 3 1 55621 0.000784 0.228256 -0.1784590 0.0006744 0.000114 -0.000383 0.000062 0.000066 0.0000051 0.0000142 0.000050 0.000041 2011 3 2 55622 -0.000748 0.229385 -0.1792056 0.0007967 0.000062 -0.000329 0.000062 0.000066 0.0000077 0.0000142 0.000051 0.000041 2011 3 3 55623 -0.001851 0.230499 -0.1801076 0.0009676 -0.000017 -0.000256 0.000062 0.000065 0.0000112 0.0000142 0.000051 0.000042 2011 3 4 55624 -0.002654 0.231928 -0.1811639 0.0011063 -0.000096 -0.000182 0.000062 0.000065 0.0000133 0.0000141 0.000052 0.000043 2011 3 5 55625 -0.003043 0.233484 -0.1823118 0.0012030 -0.000084 -0.000205 0.000062 0.000065 0.0000102 0.0000141 0.000052 0.000044 2011 3 6 55626 -0.003364 0.235548 -0.1835199 0.0011789 -0.000039 -0.000264 0.000062 0.000065 0.0000106 0.0000141 0.000053 0.000045 2011 3 7 55627 -0.004451 0.237570 -0.1846795 0.0010882 0.000006 -0.000323 0.000062 0.000065 0.0000082 0.0000141 0.000053 0.000045 2011 3 8 55628 -0.005825 0.238983 -0.1857534 0.0009949 0.000051 -0.000382 0.000062 0.000065 0.0000031 0.0000140 0.000053 0.000046 2011 3 9 55629 -0.006991 0.240511 -0.1867518 0.0009075 0.000052 -0.000394 0.000062 0.000065 0.0000050 0.0000140 0.000054 0.000047 2011 3 10 55630 -0.007834 0.242297 -0.1876395 0.0008166 0.000043 -0.000393 0.000062 0.000065 0.0000086 0.0000140 0.000055 0.000048 2011 3 11 55631 -0.008872 0.244268 -0.1884119 0.0007438 0.000034 -0.000393 0.000062 0.000065 0.0000122 0.0000139 0.000056 0.000049 2011 3 12 55632 -0.010334 0.246257 -0.1890680 0.0006400 -0.000008 -0.000368 0.000062 0.000065 0.0000124 0.0000138 0.000056 0.000049 2011 3 13 55633 -0.011741 0.248056 -0.1896712 0.0005769 -0.000062 -0.000334 0.000062 0.000065 0.0000114 0.0000138 0.000057 0.000050 2011 3 14 55634 -0.013522 0.249734 -0.1903022 0.0006329 -0.000116 -0.000300 0.000062 0.000065 0.0000104 0.0000138 0.000058 0.000051 2011 3 15 55635 -0.015266 0.250625 -0.1910495 0.0008559 -0.000170 -0.000267 0.000062 0.000065 0.0000096 0.0000137 0.000058 0.000051 2011 3 16 55636 -0.016856 0.251676 -0.1920012 0.0010870 -0.000223 -0.000233 0.000062 0.000065 0.0000099 0.0000137 0.000059 0.000052 2011 3 17 55637 -0.018366 0.253061 -0.1931996 0.0013546 -0.000122 -0.000274 0.000062 0.000065 0.0000124 0.0000136 0.000059 0.000052 2011 3 18 55638 -0.019579 0.254441 -0.1946409 0.0015298 0.000021 -0.000336 0.000062 0.000065 0.0000156 0.0000135 0.000060 0.000052 2011 3 19 55639 -0.020644 0.255977 -0.1962253 0.0016219 0.000041 -0.000368 0.000062 0.000065 0.0000227 0.0000134 0.000060 0.000052 2011 3 20 55640 -0.021628 0.257712 -0.1978407 0.0015955 0.000013 -0.000390 0.000062 0.000065 0.0000313 0.0000133 0.000060 0.000052 2011 3 21 55641 -0.022752 0.259790 -0.1993796 0.0014715 -0.000015 -0.000411 0.000062 0.000065 0.0000240 0.0000133 0.000060 0.000052 2011 3 22 55642 -0.024444 0.261866 -0.2007296 0.0012445 -0.000043 -0.000433 0.000062 0.000065 0.0000086 0.0000132 0.000061 0.000051 2011 3 23 55643 -0.025805 0.263506 -0.2018371 0.0009710 -0.000213 -0.000197 0.000062 0.000065 0.0000159 0.0000131 0.000061 0.000051 2011 3 24 55644 -0.026918 0.265314 -0.2027541 0.0008173 -0.000345 -0.000087 0.000062 0.000065 0.0000154 0.0000130 0.000061 0.000051 2011 3 25 55645 -0.027203 0.267054 -0.2035673 0.0008382 -0.000121 -0.000285 0.000062 0.000065 0.0000107 0.0000129 0.000061 0.000051 2011 3 26 55646 -0.027449 0.268992 -0.2043220 0.0008616 -0.000022 -0.000353 0.000062 0.000065 0.0000336 0.0000128 0.000060 0.000050 2011 3 27 55647 -0.028407 0.270804 -0.2051301 0.0009423 -0.000009 -0.000342 0.000062 0.000065 0.0000667 0.0000128 0.000060 0.000049 2011 3 28 55648 -0.029389 0.272689 -0.2062086 0.0010899 0.000004 -0.000331 0.000062 0.000065 0.0000518 0.0000127 0.000060 0.000049 2011 3 29 55649 -0.030328 0.274343 -0.2075017 0.0012352 0.000016 -0.000321 0.000062 0.000065 0.0000131 0.0000126 0.000060 0.000048 2011 3 30 55650 -0.030921 0.275789 -0.2088378 0.0013610 -0.000018 -0.000315 0.000062 0.000065 0.0000026 0.0000126 0.000059 0.000047 2011 3 31 55651 -0.031677 0.277491 -0.2102414 0.0014338 -0.000024 -0.000275 0.000062 0.000066 0.0000032 0.0000125 0.000060 0.000047 2011 4 1 55652 -0.033017 0.279117 -0.2117083 0.0014747 -0.000072 -0.000195 0.000062 0.000066 0.0000048 0.0000124 0.000060 0.000047 2011 4 2 55653 -0.034732 0.280664 -0.2132326 0.0014853 -0.000091 -0.000199 0.000062 0.000066 0.0000181 0.0000123 0.000059 0.000046 2011 4 3 55654 -0.036196 0.281940 -0.2147146 0.0014342 -0.000090 -0.000236 0.000062 0.000066 0.0000186 0.0000122 0.000059 0.000046 2011 4 4 55655 -0.037434 0.283587 -0.2160709 0.0013021 -0.000089 -0.000273 0.000063 0.000066 0.0000182 0.0000121 0.000059 0.000045 2011 4 5 55656 -0.039358 0.285463 -0.2172828 0.0011327 -0.000089 -0.000311 0.000063 0.000066 0.0000184 0.0000120 0.000059 0.000045 2011 4 6 55657 -0.041465 0.286987 -0.2183356 0.0009817 -0.000046 -0.000394 0.000063 0.000066 0.0000055 0.0000119 0.000059 0.000044 2011 4 7 55658 -0.042481 0.288653 -0.2192283 0.0008197 -0.000015 -0.000393 0.000063 0.000066 0.0000042 0.0000118 0.000060 0.000044 2011 4 8 55659 -0.042997 0.290905 -0.2199957 0.0007210 0.000010 -0.000363 0.000063 0.000066 0.0000064 0.0000116 0.000060 0.000045 2011 4 9 55660 -0.043367 0.293435 -0.2207528 0.0007470 0.000006 -0.000333 0.000063 0.000067 0.0000165 0.0000115 0.000061 0.000045 2011 4 10 55661 -0.043303 0.295747 -0.2215252 0.0008137 -0.000008 -0.000304 0.000063 0.000067 0.0000205 0.0000113 0.000062 0.000044 2011 4 11 55662 -0.043606 0.297661 -0.2223485 0.0009070 -0.000023 -0.000275 0.000063 0.000067 0.0000143 0.0000112 0.000062 0.000044 2011 4 12 55663 -0.043919 0.299556 -0.2233115 0.0010778 -0.000037 -0.000245 0.000063 0.000067 0.0000052 0.0000111 0.000063 0.000044 2011 4 13 55664 -0.044071 0.301830 -0.2244345 0.0012569 -0.000114 -0.000335 0.000063 0.000067 0.0000030 0.0000109 0.000064 0.000044 2011 4 14 55665 -0.044192 0.304163 -0.2257791 0.0014140 -0.000184 -0.000368 0.000063 0.000067 0.0000027 0.0000108 0.000064 0.000044 2011 4 15 55666 -0.044047 0.306682 -0.2272981 0.0015652 -0.000225 -0.000281 0.000063 0.000067 0.0000064 0.0000106 0.000064 0.000044 2011 4 16 55667 -0.043834 0.309388 -0.2289499 0.0016601 -0.000216 -0.000242 0.000063 0.000067 0.0000139 0.0000105 0.000065 0.000045 2011 4 17 55668 -0.044036 0.311987 -0.2306067 0.0016082 -0.000191 -0.000232 0.000063 0.000067 0.0000166 0.0000103 0.000065 0.000045 2011 4 18 55669 -0.044266 0.314399 -0.2321451 0.0014367 -0.000166 -0.000223 0.000063 0.000067 0.0000127 0.0000102 0.000066 0.000045 2011 4 19 55670 -0.044554 0.316390 -0.2334610 0.0012275 -0.000142 -0.000213 0.000063 0.000067 0.0000071 0.0000100 0.000066 0.000045 2011 4 20 55671 -0.044658 0.318431 -0.2345577 0.0009821 -0.000155 -0.000226 0.000063 0.000067 0.0000042 0.0000099 0.000067 0.000045 2011 4 21 55672 -0.044951 0.320493 -0.2354274 0.0007913 -0.000163 -0.000247 0.000063 0.000067 0.0000054 0.0000098 0.000067 0.000046 2011 4 22 55673 -0.045061 0.322255 -0.2361793 0.0006990 -0.000164 -0.000268 0.000063 0.000067 0.0000080 0.0000097 0.000067 0.000046 2011 4 23 55674 -0.045223 0.323974 -0.2369210 0.0007162 -0.000165 -0.000290 0.000063 0.000067 0.0000120 0.0000096 0.000068 0.000047 2011 4 24 55675 -0.045872 0.325841 -0.2377161 0.0008321 -0.000167 -0.000311 0.000063 0.000066 0.0000227 0.0000095 0.000068 0.000047 2011 4 25 55676 -0.046204 0.327522 -0.2385787 0.0009145 -0.000168 -0.000332 0.000063 0.000066 0.0000213 0.0000094 0.000068 0.000048 2011 4 26 55677 -0.046033 0.329198 -0.2395275 0.0009987 -0.000169 -0.000354 0.000063 0.000066 0.0000135 0.0000093 0.000069 0.000048 2011 4 27 55678 -0.045764 0.331315 -0.2405602 0.0010776 -0.000171 -0.000375 0.000063 0.000066 0.0000057 0.0000093 0.000069 0.000049 2011 4 28 55679 -0.045322 0.333610 -0.2416513 0.0011136 -0.000175 -0.000251 0.000063 0.000066 0.0000057 0.0000092 0.000070 0.000049 2011 4 29 55680 -0.045118 0.336163 -0.2427721 0.0011371 -0.000180 -0.000089 0.000063 0.000066 0.0000076 0.0000091 0.000070 0.000050 2011 4 30 55681 -0.044729 0.338550 -0.2438839 0.0010813 -0.000159 -0.000068 0.000063 0.000066 0.0000189 0.0000091 0.000071 0.000050 2011 5 1 55682 -0.044035 0.341157 -0.2449508 0.0010037 -0.000128 -0.000100 0.000063 0.000066 0.0000189 0.0000090 0.000071 0.000050 2011 5 2 55683 -0.043214 0.344088 -0.2459456 0.0009590 -0.000096 -0.000132 0.000063 0.000066 0.0000117 0.0000089 0.000071 0.000050 2011 5 3 55684 -0.042665 0.346820 -0.2468539 0.0009202 -0.000065 -0.000163 0.000063 0.000066 0.0000045 0.0000089 0.000071 0.000050 2011 5 4 55685 -0.042415 0.349165 -0.2477550 0.0008898 -0.000272 -0.000035 0.000063 0.000066 0.0000167 0.0000088 0.000072 0.000051 2011 5 5 55686 -0.041914 0.351288 -0.2486052 0.0008241 -0.000331 -0.000018 0.000063 0.000066 0.0000276 0.0000088 0.000073 0.000052 2011 5 6 55687 -0.041626 0.353512 -0.2494023 0.0007898 -0.000328 -0.000047 0.000063 0.000066 0.0000142 0.0000087 0.000073 0.000052 2011 5 7 55688 -0.041477 0.355393 -0.2502269 0.0008501 -0.000300 -0.000081 0.000063 0.000066 0.0000118 0.0000087 0.000074 0.000053 2011 5 8 55689 -0.041738 0.357403 -0.2511237 0.0009128 -0.000263 -0.000115 0.000063 0.000066 0.0000120 0.0000086 0.000074 0.000053 2011 5 9 55690 -0.041856 0.359025 -0.2521313 0.0011327 -0.000226 -0.000150 0.000063 0.000066 0.0000122 0.0000086 0.000074 0.000053 2011 5 10 55691 -0.041271 0.360768 -0.2533310 0.0013572 -0.000190 -0.000185 0.000063 0.000066 0.0000129 0.0000085 0.000074 0.000054 2011 5 11 55692 -0.039942 0.362890 -0.2547550 0.0015288 -0.000246 -0.000200 0.000063 0.000066 0.0000110 0.0000085 0.000075 0.000054 2011 5 12 55693 -0.038511 0.365453 -0.2563879 0.0016961 -0.000328 -0.000209 0.000063 0.000066 0.0000085 0.0000084 0.000075 0.000054 2011 5 13 55694 -0.036572 0.368222 -0.2581611 0.0018016 -0.000409 -0.000219 0.000062 0.000066 0.0000059 0.0000084 0.000075 0.000053 2011 5 14 55695 -0.034708 0.371242 -0.2600319 0.0018203 -0.000395 -0.000199 0.000062 0.000066 0.0000155 0.0000083 0.000076 0.000053 2011 5 15 55696 -0.033334 0.374177 -0.2618333 0.0017419 -0.000345 -0.000168 0.000062 0.000065 0.0000136 0.0000083 0.000076 0.000053 2011 5 16 55697 -0.032579 0.376489 -0.2634599 0.0015356 -0.000295 -0.000136 0.000062 0.000065 0.0000085 0.0000082 0.000077 0.000053 2011 5 17 55698 -0.031938 0.378039 -0.2648445 0.0012930 -0.000246 -0.000105 0.000062 0.000065 0.0000055 0.0000082 0.000077 0.000053 2011 5 18 55699 -0.031316 0.380013 -0.2660323 0.0010569 -0.000160 -0.000403 0.000062 0.000065 0.0000129 0.0000081 0.000078 0.000054 2011 5 19 55700 -0.030721 0.381689 -0.2670231 0.0008909 -0.000064 -0.000786 0.000062 0.000065 0.0000187 0.0000081 0.000078 0.000054 2011 5 20 55701 -0.029879 0.383300 -0.2678021 0.0007722 -0.000160 -0.000301 0.000062 0.000065 0.0000077 0.0000080 0.000079 0.000055 2011 5 21 55702 -0.029016 0.384828 -0.2685896 0.0007755 -0.000184 -0.000100 0.000062 0.000065 0.0000118 0.0000080 0.000079 0.000055 2011 5 22 55703 -0.028123 0.386241 -0.2694060 0.0008258 -0.000159 -0.000112 0.000062 0.000065 0.0000125 0.0000079 0.000079 0.000055 2011 5 23 55704 -0.026840 0.387733 -0.2702331 0.0008625 -0.000134 -0.000124 0.000062 0.000065 0.0000106 0.0000079 0.000079 0.000056 2011 5 24 55705 -0.025487 0.389221 -0.2710990 0.0009183 -0.000109 -0.000136 0.000062 0.000065 0.0000096 0.0000078 0.000079 0.000057 2011 5 25 55706 -0.023707 0.390859 -0.2719979 0.0008877 -0.000448 0.000044 0.000062 0.000065 0.0000091 0.0000078 0.000079 0.000058 2011 5 26 55707 -0.021970 0.393124 -0.2729265 0.0009486 -0.000357 -0.000043 0.000062 0.000065 0.0000091 0.0000077 0.000079 0.000058 2011 5 27 55708 -0.020288 0.395679 -0.2739062 0.0009980 -0.000108 -0.000225 0.000062 0.000065 0.0000100 0.0000077 0.000079 0.000058 2011 5 28 55709 -0.019013 0.397426 -0.2749010 0.0009308 -0.000070 -0.000239 0.000062 0.000065 0.0000150 0.0000077 0.000079 0.000058 2011 5 29 55710 -0.017931 0.398983 -0.2757977 0.0008815 -0.000111 -0.000192 0.000062 0.000065 0.0000177 0.0000077 0.000078 0.000058 2011 5 30 55711 -0.017330 0.400737 -0.2766323 0.0007449 -0.000151 -0.000145 0.000062 0.000066 0.0000230 0.0000077 0.000077 0.000058 2011 5 31 55712 -0.016522 0.402063 -0.2773235 0.0006270 -0.000191 -0.000097 0.000062 0.000066 0.0000197 0.0000076 0.000077 0.000058 2011 6 1 55713 -0.015324 0.403275 -0.2778924 0.0005607 -0.000231 -0.000050 0.000063 0.000066 0.0000116 0.0000076 0.000076 0.000058 2011 6 2 55714 -0.014267 0.404459 -0.2784052 0.0005021 -0.000192 -0.000054 0.000063 0.000066 0.0000115 0.0000076 0.000076 0.000057 2011 6 3 55715 -0.013135 0.405701 -0.2789059 0.0004623 -0.000132 -0.000071 0.000063 0.000066 0.0000133 0.0000076 0.000075 0.000057 2011 6 4 55716 -0.011679 0.407482 -0.2794125 0.0005542 -0.000168 -0.000074 0.000063 0.000066 0.0000217 0.0000076 0.000075 0.000056 2011 6 5 55717 -0.009893 0.409353 -0.2800870 0.0007415 -0.000240 -0.000073 0.000063 0.000066 0.0000188 0.0000076 0.000074 0.000055 2011 6 6 55718 -0.007741 0.410795 -0.2809045 0.0008993 -0.000312 -0.000071 0.000063 0.000066 0.0000121 0.0000076 0.000073 0.000054 2011 6 7 55719 -0.005640 0.412293 -0.2818704 0.0010603 -0.000384 -0.000069 0.000063 0.000066 0.0000067 0.0000075 0.000072 0.000053 2011 6 8 55720 -0.003247 0.414012 -0.2829558 0.0011651 -0.000337 -0.000095 0.000063 0.000066 0.0000068 0.0000075 0.000072 0.000052 2011 6 9 55721 -0.001012 0.415720 -0.2841241 0.0011571 -0.000259 -0.000127 0.000063 0.000066 0.0000084 0.0000075 0.000071 0.000051 2011 6 10 55722 0.001708 0.416882 -0.2852942 0.0010978 -0.000181 -0.000160 0.000063 0.000066 0.0000100 0.0000075 0.000071 0.000051 2011 6 11 55723 0.004998 0.418218 -0.2864047 0.0009835 -0.000167 -0.000153 0.000063 0.000066 0.0000133 0.0000075 0.000070 0.000050 2011 6 12 55724 0.008069 0.419855 -0.2873090 0.0007833 -0.000177 -0.000131 0.000063 0.000066 0.0000128 0.0000075 0.000069 0.000049 2011 6 13 55725 0.010668 0.421166 -0.2880049 0.0005833 -0.000187 -0.000110 0.000063 0.000067 0.0000102 0.0000075 0.000068 0.000048 2011 6 14 55726 0.013211 0.422235 -0.2884886 0.0004447 -0.000197 -0.000088 0.000063 0.000067 0.0000076 0.0000075 0.000068 0.000047 2011 6 15 55727 0.015196 0.422966 -0.2887905 0.0002784 -0.000207 -0.000066 0.000063 0.000067 0.0000050 0.0000075 0.000067 0.000046 2011 6 16 55728 0.017066 0.423543 -0.2889945 0.0001895 -0.000376 -0.000199 0.000064 0.000067 0.0000051 0.0000075 0.000067 0.000046 2011 6 17 55729 0.018898 0.424431 -0.2891855 0.0001951 -0.000291 -0.000132 0.000064 0.000067 0.0000058 0.0000075 0.000066 0.000046 2011 6 18 55730 0.020820 0.425416 -0.2894221 0.0002688 -0.000257 -0.000089 0.000064 0.000067 0.0000180 0.0000075 0.000065 0.000045 2011 6 19 55731 0.022775 0.426473 -0.2897378 0.0003432 -0.000278 -0.000085 0.000064 0.000067 0.0000168 0.0000075 0.000065 0.000044 2011 6 20 55732 0.024993 0.427077 -0.2900941 0.0003750 -0.000299 -0.000080 0.000064 0.000067 0.0000105 0.0000075 0.000064 0.000044 2011 6 21 55733 0.027121 0.427768 -0.2904804 0.0003980 -0.000320 -0.000076 0.000064 0.000067 0.0000058 0.0000075 0.000063 0.000043 2011 6 22 55734 0.029112 0.428453 -0.2908692 0.0003702 -0.000299 -0.000073 0.000064 0.000067 0.0000043 0.0000075 0.000063 0.000043 2011 6 23 55735 0.031092 0.429287 -0.2912247 0.0003313 -0.000207 -0.000105 0.000064 0.000067 0.0000044 0.0000075 0.000063 0.000042 2011 6 24 55736 0.032762 0.430196 -0.2915099 0.0002413 -0.000097 -0.000146 0.000064 0.000067 0.0000049 0.0000075 0.000062 0.000042 2011 6 25 55737 0.033619 0.430838 -0.2916926 0.0001197 -0.000084 -0.000122 0.000064 0.000067 0.0000092 0.0000075 0.000062 0.000042 2011 6 26 55738 0.034598 0.431514 -0.2917544 0.0000123 -0.000107 -0.000073 0.000064 0.000067 0.0000105 0.0000075 0.000061 0.000041 2011 6 27 55739 0.036571 0.432215 -0.2917353 -0.0000577 -0.000130 -0.000024 0.000064 0.000067 0.0000083 0.0000075 0.000061 0.000041 2011 6 28 55740 0.038492 0.433112 -0.2916167 -0.0001258 -0.000153 0.000024 0.000064 0.000067 0.0000054 0.0000075 0.000060 0.000040 2011 6 29 55741 0.040160 0.433810 -0.2914345 -0.0001967 -0.000232 0.000028 0.000064 0.000067 0.0000024 0.0000075 0.000060 0.000040 2011 6 30 55742 0.042120 0.434694 -0.2911537 -0.0002851 -0.000137 0.000028 0.000064 0.000067 0.0000021 0.0000075 0.000060 0.000041 2011 7 1 55743 0.043694 0.435593 -0.2908780 -0.0002971 0.000014 0.000029 0.000064 0.000067 0.0000026 0.0000075 0.000061 0.000041 2011 7 2 55744 0.045224 0.436417 -0.2906434 -0.0001781 -0.000124 0.000028 0.000064 0.000067 0.0000095 0.0000075 0.000062 0.000042 2011 7 3 55745 0.046621 0.437146 -0.2905597 0.0000006 -0.000369 0.000025 0.000064 0.000067 0.0000147 0.0000075 0.000063 0.000042 2011 7 4 55746 0.048193 0.437878 -0.2906978 0.0002735 -0.000614 0.000022 0.000064 0.000067 0.0000288 0.0000075 0.000064 0.000043 2011 7 5 55747 0.050369 0.438983 -0.2910636 0.0004495 -0.000858 0.000020 0.000064 0.000067 0.0000250 0.0000075 0.000064 0.000044 2011 7 6 55748 0.052419 0.440200 -0.2915676 0.0004983 -0.000352 0.000062 0.000064 0.000067 0.0000110 0.0000075 0.000065 0.000044 2011 7 7 55749 0.055104 0.440811 -0.2920688 0.0004629 -0.000257 0.000054 0.000064 0.000067 0.0000079 0.0000075 0.000065 0.000044 2011 7 8 55750 0.057647 0.441385 -0.2924910 0.0003619 -0.000270 0.000033 0.000064 0.000067 0.0000077 0.0000075 0.000066 0.000044 2011 7 9 55751 0.059871 0.441740 -0.2928016 0.0001848 -0.000291 0.000051 0.000064 0.000067 0.0000110 0.0000075 0.000066 0.000044 2011 7 10 55752 0.062155 0.442144 -0.2929001 -0.0000277 -0.000315 0.000082 0.000064 0.000067 0.0000126 0.0000075 0.000066 0.000044 2011 7 11 55753 0.064413 0.442987 -0.2927792 -0.0001703 -0.000339 0.000114 0.000064 0.000067 0.0000123 0.0000075 0.000066 0.000044 2011 7 12 55754 0.065812 0.443892 -0.2925010 -0.0002951 -0.000364 0.000146 0.000064 0.000067 0.0000116 0.0000075 0.000066 0.000044 2011 7 13 55755 0.067122 0.444416 -0.2921571 -0.0003420 -0.000212 0.000026 0.000064 0.000067 0.0000047 0.0000075 0.000066 0.000044 2011 7 14 55756 0.068743 0.444817 -0.2918199 -0.0002947 -0.000140 -0.000001 0.000064 0.000067 0.0000030 0.0000075 0.000067 0.000044 2011 7 15 55757 0.070584 0.445141 -0.2915625 -0.0002391 -0.000105 0.000011 0.000064 0.000067 0.0000033 0.0000075 0.000067 0.000044 2011 7 16 55758 0.072264 0.445594 -0.2913939 -0.0001387 -0.000117 0.000038 0.000064 0.000067 0.0000077 0.0000075 0.000067 0.000045 2011 7 17 55759 0.074418 0.446357 -0.2913537 -0.0000020 -0.000146 0.000071 0.000064 0.000067 0.0000132 0.0000075 0.000067 0.000046 2011 7 18 55760 0.076529 0.447250 -0.2914350 0.0001316 -0.000176 0.000104 0.000064 0.000067 0.0000127 0.0000075 0.000067 0.000046 2011 7 19 55761 0.078637 0.447654 -0.2915937 0.0002237 -0.000206 0.000137 0.000064 0.000067 0.0000094 0.0000075 0.000067 0.000047 2011 7 20 55762 0.081093 0.447905 -0.2918102 0.0002363 0.000083 -0.000105 0.000064 0.000067 0.0000077 0.0000076 0.000067 0.000048 2011 7 21 55763 0.083766 0.448199 -0.2920144 0.0001413 0.000185 -0.000230 0.000064 0.000067 0.0000063 0.0000076 0.000067 0.000049 2011 7 22 55764 0.086614 0.448685 -0.2921558 0.0000860 -0.000083 -0.000075 0.000064 0.000067 0.0000050 0.0000076 0.000067 0.000049 2011 7 23 55765 0.089071 0.449477 -0.2922284 0.0000234 -0.000165 -0.000033 0.000064 0.000067 0.0000095 0.0000076 0.000066 0.000050 2011 7 24 55766 0.091010 0.449831 -0.2922234 -0.0000507 -0.000141 -0.000062 0.000064 0.000067 0.0000107 0.0000076 0.000066 0.000050 2011 7 25 55767 0.093183 0.449763 -0.2920967 -0.0001499 -0.000118 -0.000091 0.000064 0.000067 0.0000094 0.0000076 0.000066 0.000050 2011 7 26 55768 0.094917 0.449701 -0.2918661 -0.0002713 -0.000094 -0.000119 0.000064 0.000067 0.0000082 0.0000076 0.000066 0.000051 2011 7 27 55769 0.096202 0.448804 -0.2915549 -0.0003182 -0.000086 0.000014 0.000064 0.000067 0.0000107 0.0000076 0.000065 0.000051 2011 7 28 55770 0.097817 0.447335 -0.2912283 -0.0003117 -0.000081 0.000190 0.000064 0.000067 0.0000127 0.0000076 0.000065 0.000051 2011 7 29 55771 0.099905 0.446290 -0.2909199 -0.0002411 -0.000076 0.000366 0.000064 0.000067 0.0000092 0.0000076 0.000064 0.000051 2011 7 30 55772 0.101608 0.445878 -0.2907520 -0.0000760 -0.000085 0.000362 0.000064 0.000067 0.0000114 0.0000077 0.000064 0.000050 2011 7 31 55773 0.103086 0.445805 -0.2908265 0.0001753 -0.000100 0.000292 0.000064 0.000067 0.0000125 0.0000077 0.000064 0.000050 2011 8 1 55774 0.104809 0.445717 -0.2911466 0.0004161 -0.000115 0.000222 0.000064 0.000067 0.0000104 0.0000077 0.000063 0.000050 2011 8 2 55775 0.106924 0.445038 -0.2916574 0.0006115 -0.000130 0.000152 0.000064 0.000067 0.0000075 0.0000077 0.000063 0.000049 2011 8 3 55776 0.109275 0.444478 -0.2923189 0.0006777 -0.000155 0.000082 0.000064 0.000067 0.0000071 0.0000077 0.000062 0.000049 2011 8 4 55777 0.111727 0.443837 -0.2930173 0.0006439 -0.000172 0.000096 0.000064 0.000068 0.0000073 0.0000077 0.000062 0.000049 2011 8 5 55778 0.114577 0.443253 -0.2935977 0.0005166 -0.000187 0.000135 0.000064 0.000068 0.0000075 0.0000077 0.000061 0.000049 2011 8 6 55779 0.117304 0.442826 -0.2940002 0.0002633 -0.000185 0.000143 0.000064 0.000068 0.0000142 0.0000077 0.000061 0.000049 2011 8 7 55780 0.119290 0.442446 -0.2941726 0.0000657 -0.000177 0.000140 0.000065 0.000068 0.0000128 0.0000077 0.000060 0.000049 2011 8 8 55781 0.121117 0.441914 -0.2941351 -0.0000776 -0.000169 0.000138 0.000065 0.000068 0.0000096 0.0000078 0.000060 0.000049 2011 8 9 55782 0.123204 0.441196 -0.2939776 -0.0001642 -0.000161 0.000135 0.000065 0.000068 0.0000080 0.0000078 0.000059 0.000049 2011 8 10 55783 0.125604 0.440541 -0.2937158 -0.0001929 -0.000108 0.000035 0.000065 0.000068 0.0001512 0.0000078 0.000059 0.000049 2011 8 11 55784 0.127833 0.440128 -0.2935351 -0.0001592 -0.000131 -0.000071 0.000065 0.000068 0.0001206 0.0000078 0.000058 0.000049 2011 8 12 55785 0.129649 0.439566 -0.2934627 -0.0000682 -0.000224 -0.000090 0.000065 0.000068 0.0000276 0.0000078 0.000057 0.000048 2011 8 13 55786 0.131495 0.439093 -0.2934675 0.0000261 -0.000245 -0.000041 0.000065 0.000068 0.0000114 0.0000078 0.000056 0.000048 2011 8 14 55787 0.133051 0.438586 -0.2935795 0.0001128 -0.000232 0.000024 0.000065 0.000068 0.0000115 0.0000078 0.000055 0.000047 2011 8 15 55788 0.134744 0.437484 -0.2937438 0.0002147 -0.000220 0.000090 0.000065 0.000068 0.0000099 0.0000078 0.000054 0.000047 2011 8 16 55789 0.136642 0.436701 -0.2939669 0.0002309 -0.000207 0.000155 0.000065 0.000068 0.0000101 0.0000078 0.000053 0.000046 2011 8 17 55790 0.138513 0.435983 -0.2942454 0.0002307 -0.000195 0.000220 0.000065 0.000068 0.0000095 0.0000078 0.000052 0.000046 2011 8 18 55791 0.140347 0.435452 -0.2944791 0.0002343 0.000020 0.000086 0.000065 0.000068 0.0000090 0.0000078 0.000051 0.000046 2011 8 19 55792 0.141916 0.434659 -0.2946368 0.0001363 0.000089 0.000060 0.000065 0.000068 0.0000085 0.0000078 0.000050 0.000045 2011 8 20 55793 0.143242 0.433838 -0.2947019 0.0000161 0.000056 0.000108 0.000065 0.000068 0.0000080 0.0000078 0.000049 0.000045 2011 8 21 55794 0.144138 0.432820 -0.2946787 -0.0000869 0.000009 0.000165 0.000065 0.000068 0.0000095 0.0000078 0.000048 0.000044 2011 8 22 55795 0.145468 0.431508 -0.2945603 -0.0001389 -0.000037 0.000221 0.000065 0.000068 0.0000116 0.0000079 0.000047 0.000043 2011 8 23 55796 0.146639 0.430496 -0.2943923 -0.0001570 -0.000083 0.000278 0.000065 0.000068 0.0000135 0.0000079 0.000046 0.000042 2011 8 24 55797 0.147633 0.429203 -0.2942407 -0.0001217 -0.000032 0.000110 0.000065 0.000068 0.0000160 0.0000079 0.000045 0.000041 2011 8 25 55798 0.148797 0.428122 -0.2941647 -0.0000436 -0.000016 0.000109 0.000065 0.000068 0.0000166 0.0000079 0.000044 0.000040 2011 8 26 55799 0.150174 0.427095 -0.2942142 0.0001763 -0.000019 0.000174 0.000065 0.000068 0.0000091 0.0000079 0.000043 0.000039 2011 8 27 55800 0.151876 0.426071 -0.2945410 0.0004503 -0.000030 0.000196 0.000065 0.000068 0.0000110 0.0000079 0.000041 0.000038 2011 8 28 55801 0.153559 0.424857 -0.2951141 0.0006887 -0.000045 0.000203 0.000065 0.000068 0.0000113 0.0000079 0.000040 0.000037 2011 8 29 55802 0.155587 0.423557 -0.2959225 0.0009110 -0.000060 0.000209 0.000065 0.000068 0.0000092 0.0000080 0.000039 0.000036 2011 8 30 55803 0.157453 0.422659 -0.2969014 0.0009885 -0.000074 0.000216 0.000065 0.000068 0.0000070 0.0000080 0.000038 0.000035 2011 8 31 55804 0.159198 0.421677 -0.2979366 0.0009969 -0.000096 0.000208 0.000065 0.000068 0.0000086 0.0000080 0.000037 0.000034 2011 9 1 55805 0.161074 0.420863 -0.2988971 0.0009075 -0.000120 0.000195 0.000065 0.000068 0.0000100 0.0000080 0.000036 0.000033 2011 9 2 55806 0.162542 0.419869 -0.2997146 0.0007126 -0.000143 0.000183 0.000066 0.000069 0.0000070 0.0000080 0.000035 0.000032 2011 9 3 55807 0.163890 0.418703 -0.3003226 0.0004648 -0.000158 0.000159 0.000066 0.000069 0.0000177 0.0000080 0.000035 0.000031 2011 9 4 55808 0.165300 0.417125 -0.3006788 0.0002706 -0.000168 0.000131 0.000066 0.000069 0.0000139 0.0000080 0.000034 0.000031 2011 9 5 55809 0.166550 0.415662 -0.3008935 0.0001854 -0.000179 0.000104 0.000066 0.000069 0.0000165 0.0000080 0.000033 0.000030 2011 9 6 55810 0.167420 0.414389 -0.3010474 0.0001762 -0.000190 0.000076 0.000066 0.000069 0.0000143 0.0000081 0.000032 0.000029 2011 9 7 55811 0.168513 0.413247 -0.3012208 0.0002415 -0.000035 0.000231 0.000066 0.000069 0.0000069 0.0000081 0.000031 0.000028 2011 9 8 55812 0.170074 0.411944 -0.3014812 0.0003127 -0.000043 0.000224 0.000066 0.000069 0.0000044 0.0000081 0.000030 0.000028 2011 9 9 55813 0.172075 0.410686 -0.3018570 0.0004102 -0.000095 0.000175 0.000066 0.000070 0.0000032 0.0000081 0.000030 0.000027 2011 9 10 55814 0.174348 0.409406 -0.3022935 0.0004711 -0.000090 0.000178 0.000067 0.000070 0.0000096 0.0000081 0.000029 0.000026 2011 9 11 55815 0.176222 0.408117 -0.3028329 0.0005680 -0.000064 0.000202 0.000067 0.000070 0.0000103 0.0000081 0.000028 0.000025 2011 9 12 55816 0.177582 0.406884 -0.3034489 0.0006216 -0.000038 0.000225 0.000067 0.000070 0.0000090 0.0000082 0.000027 0.000024 2011 9 13 55817 0.178636 0.405683 -0.3040916 0.0006801 -0.000012 0.000249 0.000067 0.000070 0.0000086 0.0000082 0.000027 0.000024 2011 9 14 55818 0.179705 0.404619 -0.3048120 0.0007340 0.000005 0.000235 0.000067 0.000071 0.0000060 0.0000082 0.000026 0.000023 2011 9 15 55819 0.180607 0.403717 -0.3055097 0.0006754 0.000020 0.000211 0.000068 0.000071 0.0000030 0.0000082 0.000025 0.000022 2011 9 16 55820 0.181466 0.402594 -0.3061272 0.0005719 0.000068 0.000210 0.000068 0.000071 0.0000017 0.0000082 0.000025 0.000022 2011 9 17 55821 0.182170 0.401461 -0.3066351 0.0004436 0.000104 0.000233 0.000068 0.000072 0.0000017 0.0000082 0.000024 0.000022 2011 9 18 55822 0.182353 0.400283 -0.3070703 0.0004239 0.000102 0.000251 0.000069 0.000072 0.0000020 0.0000082 0.000024 0.000021 2011 9 19 55823 0.182116 0.399197 -0.3074796 0.0004057 0.000102 0.000262 0.000069 0.000072 0.0000017 0.0000083 0.000024 0.000021 2011 9 20 55824 0.181934 0.397227 -0.3078934 0.0004317 0.000087 0.000240 0.000069 0.000072 0.0000015 0.0000083 0.000024 0.000021 2011 9 21 55825 0.182247 0.394968 -0.3083892 0.0005721 0.000065 0.000203 0.000069 0.000073 0.0000020 0.0000083 0.000023 0.000021 2011 9 22 55826 0.182362 0.393003 -0.3090352 0.0007381 0.000090 0.000173 0.000069 0.000073 0.0000019 0.0000083 0.000023 0.000021 2011 9 23 55827 0.182336 0.391242 -0.3098923 0.0009796 0.000116 0.000142 0.000069 0.000073 0.0000014 0.0000083 0.000023 0.000020 2011 9 24 55828 0.182622 0.389628 -0.3110082 0.0012504 0.000111 0.000166 0.000069 0.000073 0.0000015 0.0000083 0.000023 0.000020 2011 9 25 55829 0.182593 0.388101 -0.3123875 0.0014966 0.000099 0.000201 0.000069 0.000073 0.0000017 0.0000084 0.000023 0.000020 2011 9 26 55830 0.182032 0.386351 -0.3139962 0.0016841 0.000074 0.000202 0.000069 0.000073 0.0000013 0.0000084 0.000023 0.000020 2011 9 27 55831 0.181313 0.384483 -0.3157499 0.0017910 0.000049 0.000200 0.000069 0.000073 0.0000011 0.0000084 0.000023 0.000020 2011 9 28 55832 0.180435 0.382574 -0.3175137 0.0017189 0.000034 0.000188 0.000069 0.000072 0.0000011 0.0000084 0.000023 0.000020 2011 9 29 55833 0.179816 0.380528 -0.3191208 0.0014794 0.000036 0.000190 0.000069 0.000072 0.0000012 0.0000084 0.000023 0.000021 2011 9 30 55834 0.179794 0.378744 -0.3204869 0.0012481 0.000051 0.000203 0.000068 0.000072 0.0000038 0.0000084 0.000024 0.000021 2011 10 1 55835 0.179956 0.376861 -0.3216323 0.0010731 0.000060 0.000212 0.000068 0.000072 0.0000089 0.0000084 0.000024 0.000022 2011 10 2 55836 0.180020 0.375016 -0.3226271 0.0009502 0.000069 0.000221 0.000068 0.000071 0.0000108 0.0000084 0.000025 0.000022 2011 10 3 55837 0.180124 0.373219 -0.3235328 0.0009161 0.000079 0.000229 0.000068 0.000071 0.0000077 0.0000084 0.000026 0.000023 2011 10 4 55838 0.180722 0.371297 -0.3244463 0.0009607 0.000088 0.000238 0.000068 0.000071 0.0000042 0.0000084 0.000026 0.000024 2011 10 5 55839 0.181801 0.369402 -0.3254779 0.0010897 0.000221 0.000211 0.000067 0.000071 0.0000095 0.0000084 0.000027 0.000024 2011 10 6 55840 0.183023 0.367953 -0.3266289 0.0012241 0.000386 0.000174 0.000067 0.000071 0.0000138 0.0000083 0.000028 0.000025 2011 10 7 55841 0.183864 0.366670 -0.3278876 0.0013014 0.000361 0.000134 0.000067 0.000071 0.0000055 0.0000083 0.000028 0.000026 2011 10 8 55842 0.184909 0.365410 -0.3292346 0.0013670 0.000284 0.000164 0.000067 0.000071 0.0000100 0.0000083 0.000029 0.000027 2011 10 9 55843 0.185881 0.364234 -0.3306392 0.0013870 0.000212 0.000221 0.000067 0.000071 0.0000130 0.0000083 0.000030 0.000027 2011 10 10 55844 0.186334 0.362838 -0.3320341 0.0013760 0.000140 0.000278 0.000067 0.000071 0.0000096 0.0000083 0.000031 0.000028 2011 10 11 55845 0.186289 0.361310 -0.3333686 0.0013425 0.000068 0.000335 0.000067 0.000071 0.0000046 0.0000083 0.000031 0.000028 2011 10 12 55846 0.186121 0.359944 -0.3346509 0.0012357 0.000115 0.000316 0.000067 0.000071 0.0000031 0.0000083 0.000032 0.000029 2011 10 13 55847 0.185859 0.358538 -0.3358072 0.0010592 0.000193 0.000278 0.000067 0.000071 0.0000025 0.0000082 0.000033 0.000030 2011 10 14 55848 0.185559 0.356947 -0.3367681 0.0008607 0.000171 0.000224 0.000067 0.000070 0.0000039 0.0000082 0.000034 0.000030 2011 10 15 55849 0.185076 0.355091 -0.3375327 0.0006890 0.000180 0.000179 0.000067 0.000070 0.0000071 0.0000082 0.000034 0.000031 2011 10 16 55850 0.184507 0.353072 -0.3381594 0.0005662 0.000212 0.000141 0.000067 0.000070 0.0000108 0.0000082 0.000035 0.000032 2011 10 17 55851 0.184359 0.351178 -0.3386815 0.0005220 0.000245 0.000103 0.000067 0.000070 0.0000091 0.0000082 0.000036 0.000032 2011 10 18 55852 0.184575 0.349662 -0.3391686 0.0005307 0.000277 0.000064 0.000067 0.000070 0.0000050 0.0000082 0.000037 0.000033 2011 10 19 55853 0.185322 0.348241 -0.3397253 0.0006313 0.000263 0.000038 0.000067 0.000070 0.0000043 0.0000082 0.000038 0.000034 2011 10 20 55854 0.186161 0.346968 -0.3404194 0.0007870 0.000246 0.000058 0.000067 0.000070 0.0000076 0.0000081 0.000039 0.000035 2011 10 21 55855 0.186818 0.345295 -0.3412976 0.0009790 0.000233 0.000093 0.000067 0.000070 0.0000122 0.0000081 0.000040 0.000036 2011 10 22 55856 0.186945 0.343891 -0.3423944 0.0011853 0.000220 0.000129 0.000066 0.000070 0.0000167 0.0000081 0.000041 0.000036 2011 10 23 55857 0.186982 0.342687 -0.3437086 0.0014083 0.000207 0.000164 0.000066 0.000070 0.0000212 0.0000081 0.000042 0.000037 2011 10 24 55858 0.187253 0.341740 -0.3451960 0.0015557 0.000193 0.000200 0.000066 0.000070 0.0000158 0.0000081 0.000043 0.000039 2011 10 25 55859 0.187686 0.340505 -0.3467510 0.0015766 0.000180 0.000235 0.000066 0.000070 0.0000067 0.0000081 0.000044 0.000040 2011 10 26 55860 0.187699 0.338950 -0.3482856 0.0014651 0.000266 0.000179 0.000066 0.000070 0.0000077 0.0000080 0.000045 0.000041 2011 10 27 55861 0.187543 0.337022 -0.3496642 0.0012779 0.000378 0.000099 0.000066 0.000070 0.0000106 0.0000080 0.000046 0.000042 2011 10 28 55862 0.187462 0.334997 -0.3508069 0.0010522 0.000178 0.000163 0.000066 0.000070 0.0000105 0.0000080 0.000047 0.000043 2011 10 29 55863 0.187615 0.332768 -0.3517677 0.0008832 0.000100 0.000195 0.000066 0.000070 0.0000104 0.0000080 0.000048 0.000043 2011 10 30 55864 0.187602 0.330366 -0.3526141 0.0008063 0.000109 0.000196 0.000066 0.000070 0.0000098 0.0000079 0.000049 0.000044 2011 10 31 55865 0.187283 0.328182 -0.3534278 0.0008439 0.000119 0.000197 0.000066 0.000070 0.0000167 0.0000079 0.000050 0.000045 2011 11 1 55866 0.186820 0.326374 -0.3543057 0.0009442 0.000128 0.000198 0.000066 0.000070 0.0000286 0.0000079 0.000051 0.000045 2011 11 2 55867 0.186727 0.324828 -0.3553012 0.0010624 0.000137 0.000200 0.000066 0.000070 0.0000434 0.0000079 0.000053 0.000046 2011 11 3 55868 0.187001 0.323857 -0.3564122 0.0011672 0.000185 0.000233 0.000066 0.000070 0.0000138 0.0000079 0.000053 0.000046 2011 11 4 55869 0.187158 0.323075 -0.3576727 0.0013411 0.000171 0.000202 0.000066 0.000070 0.0000049 0.0000078 0.000054 0.000046 2011 11 5 55870 0.186871 0.322000 -0.3590637 0.0014132 0.000174 0.000208 0.000066 0.000070 0.0000160 0.0000078 0.000055 0.000047 2011 11 6 55871 0.186209 0.320395 -0.3604876 0.0014111 0.000190 0.000233 0.000066 0.000070 0.0000130 0.0000078 0.000056 0.000047 2011 11 7 55872 0.185453 0.318394 -0.3618803 0.0013693 0.000206 0.000259 0.000066 0.000070 0.0000084 0.0000078 0.000056 0.000047 2011 11 8 55873 0.184737 0.316143 -0.3631993 0.0012670 0.000221 0.000284 0.000066 0.000070 0.0000063 0.0000078 0.000057 0.000048 2011 11 9 55874 0.184668 0.314212 -0.3643872 0.0010958 0.000341 0.000276 0.000066 0.000070 0.0000763 0.0000078 0.000058 0.000048 2011 11 10 55875 0.184861 0.312767 -0.3653772 0.0009146 0.000407 0.000234 0.000066 0.000070 0.0001005 0.0000078 0.000058 0.000048 2011 11 11 55876 0.184390 0.311057 -0.3662289 0.0008044 0.000402 0.000170 0.000066 0.000070 0.0000311 0.0000078 0.000058 0.000047 2011 11 12 55877 0.183246 0.309335 -0.3669779 0.0007019 0.000391 0.000146 0.000066 0.000070 0.0000072 0.0000077 0.000058 0.000046 2011 11 13 55878 0.181686 0.307528 -0.3676536 0.0006577 0.000383 0.000139 0.000066 0.000070 0.0000077 0.0000077 0.000058 0.000046 2011 11 14 55879 0.180471 0.305773 -0.3683096 0.0006738 0.000376 0.000132 0.000066 0.000070 0.0000061 0.0000077 0.000058 0.000045 2011 11 15 55880 0.179351 0.304544 -0.3690021 0.0007497 0.000368 0.000124 0.000067 0.000070 0.0000038 0.0000077 0.000058 0.000044 2011 11 16 55881 0.178286 0.303253 -0.3697859 0.0008558 0.000380 0.000134 0.000067 0.000070 0.0000069 0.0000077 0.000058 0.000044 2011 11 17 55882 0.177396 0.302333 -0.3707342 0.0010401 0.000350 0.000192 0.000067 0.000070 0.0000056 0.0000077 0.000058 0.000043 2011 11 18 55883 0.176711 0.301674 -0.3718691 0.0012188 0.000377 0.000151 0.000067 0.000070 0.0000027 0.0000077 0.000058 0.000043 2011 11 19 55884 0.176032 0.300752 -0.3732129 0.0014146 0.000369 0.000111 0.000067 0.000070 0.0000067 0.0000077 0.000058 0.000043 2011 11 20 55885 0.175326 0.299620 -0.3747230 0.0015359 0.000340 0.000085 0.000067 0.000071 0.0000111 0.0000077 0.000058 0.000042 2011 11 21 55886 0.174443 0.298742 -0.3762567 0.0015267 0.000310 0.000060 0.000067 0.000071 0.0000092 0.0000077 0.000058 0.000042 2011 11 22 55887 0.173153 0.297599 -0.3777423 0.0014789 0.000281 0.000034 0.000067 0.000071 0.0000049 0.0000077 0.000058 0.000041 2011 11 23 55888 0.171585 0.296172 -0.3791593 0.0013413 0.000254 0.000051 0.000067 0.000071 0.0000053 0.0000077 0.000058 0.000041 2011 11 24 55889 0.170120 0.294516 -0.3803896 0.0011370 0.000248 0.000061 0.000067 0.000071 0.0000067 0.0000077 0.000058 0.000041 2011 11 25 55890 0.168392 0.292651 -0.3814113 0.0009231 0.000250 0.000064 0.000067 0.000071 0.0000082 0.0000077 0.000058 0.000041 2011 11 26 55891 0.166862 0.290803 -0.3822744 0.0007767 0.000252 0.000068 0.000067 0.000071 0.0000096 0.0000077 0.000058 0.000040 2011 11 27 55892 0.166234 0.289450 -0.3830460 0.0007496 0.000254 0.000071 0.000067 0.000071 0.0000095 0.0000077 0.000058 0.000040 2011 11 28 55893 0.165720 0.288768 -0.3837961 0.0007940 0.000256 0.000074 0.000067 0.000071 0.0000074 0.0000077 0.000058 0.000040 2011 11 29 55894 0.164126 0.287937 -0.3846108 0.0008536 0.000258 0.000078 0.000067 0.000071 0.0000047 0.0000077 0.000059 0.000039 2011 11 30 55895 0.162429 0.286620 -0.3855271 0.0009645 0.000320 0.000073 0.000067 0.000071 0.0000046 0.0000077 0.000059 0.000039 2011 12 1 55896 0.160989 0.285214 -0.3865995 0.0010916 0.000315 0.000057 0.000067 0.000071 0.0000040 0.0000077 0.000059 0.000039 2011 12 2 55897 0.160440 0.284068 -0.3877421 0.0011951 0.000303 0.000066 0.000067 0.000071 0.0000031 0.0000077 0.000058 0.000039 2011 12 3 55898 0.160103 0.283256 -0.3889332 0.0011595 0.000311 0.000083 0.000067 0.000071 0.0000078 0.0000077 0.000058 0.000039 2011 12 4 55899 0.159758 0.282267 -0.3900280 0.0010374 0.000324 0.000099 0.000067 0.000071 0.0000112 0.0000077 0.000058 0.000038 2011 12 5 55900 0.159530 0.281582 -0.3910273 0.0009667 0.000337 0.000115 0.000067 0.000071 0.0000086 0.0000077 0.000058 0.000038 2011 12 6 55901 0.158940 0.281182 -0.3919312 0.0008526 0.000350 0.000131 0.000067 0.000071 0.0000040 0.0000077 0.000058 0.000038 2011 12 7 55902 0.157738 0.280633 -0.3927082 0.0006900 0.000333 0.000119 0.000067 0.000071 0.0000037 0.0000077 0.000058 0.000038 2011 12 8 55903 0.156018 0.279930 -0.3933570 0.0005730 0.000326 0.000091 0.000067 0.000071 0.0000033 0.0000077 0.000058 0.000038 2011 12 9 55904 0.154532 0.279067 -0.3939111 0.0005740 0.000325 0.000060 0.000067 0.000071 0.0000027 0.0000078 0.000058 0.000037 2011 12 10 55905 0.153917 0.278310 -0.3944668 0.0005661 0.000337 0.000074 0.000067 0.000071 0.0000059 0.0000078 0.000057 0.000037 2011 12 11 55906 0.152962 0.277862 -0.3950278 0.0005616 0.000355 0.000104 0.000067 0.000070 0.0000093 0.0000078 0.000057 0.000037 2011 12 12 55907 0.152109 0.277187 -0.3956046 0.0006181 0.000372 0.000134 0.000067 0.000070 0.0000081 0.0000078 0.000057 0.000037 2011 12 13 55908 0.151304 0.276563 -0.3962746 0.0007766 0.000390 0.000164 0.000067 0.000070 0.0000050 0.0000078 0.000057 0.000037 2011 12 14 55909 0.149948 0.276095 -0.3971246 0.0009453 0.000336 0.000167 0.000067 0.000070 0.0000038 0.0000078 0.000057 0.000037 2011 12 15 55910 0.148406 0.275471 -0.3981640 0.0011177 0.000263 0.000163 0.000067 0.000070 0.0000031 0.0000078 0.000056 0.000037 2011 12 16 55911 0.147158 0.274898 -0.3993855 0.0013270 0.000191 0.000158 0.000067 0.000070 0.0000024 0.0000079 0.000056 0.000037 2011 12 17 55912 0.145669 0.274759 -0.4007880 0.0014376 0.000209 0.000125 0.000067 0.000070 0.0000104 0.0000079 0.000056 0.000037 2011 12 18 55913 0.144419 0.274702 -0.4022627 0.0014949 0.000261 0.000080 0.000067 0.000070 0.0000101 0.0000079 0.000055 0.000037 2011 12 19 55914 0.142722 0.274528 -0.4037324 0.0014757 0.000312 0.000035 0.000067 0.000070 0.0000078 0.0000079 0.000055 0.000038 2011 12 20 55915 0.140358 0.273397 -0.4051201 0.0013266 0.000364 -0.000009 0.000067 0.000070 0.0000067 0.0000079 0.000055 0.000038 2011 12 21 55916 0.138041 0.272039 -0.4063433 0.0011507 0.000312 -0.000029 0.000067 0.000070 0.0000030 0.0000079 0.000054 0.000038 2011 12 22 55917 0.135712 0.270840 -0.4073802 0.0009056 0.000204 -0.000003 0.000067 0.000070 0.0000051 0.0000079 0.000054 0.000038 2011 12 23 55918 0.134026 0.269699 -0.4082653 0.0007433 0.000197 -0.000014 0.000066 0.000070 0.0000059 0.0000079 0.000055 0.000038 2011 12 24 55919 0.132699 0.268687 -0.4090835 0.0007400 0.000231 -0.000043 0.000066 0.000070 0.0000057 0.0000079 0.000055 0.000038 2011 12 25 55920 0.131430 0.268026 -0.4099305 0.0008677 0.000264 -0.000073 0.000066 0.000070 0.0000054 0.0000079 0.000055 0.000038 2011 12 26 55921 0.129580 0.267480 -0.4108846 0.0010494 0.000297 -0.000103 0.000066 0.000070 0.0000051 0.0000078 0.000056 0.000039 2011 12 27 55922 0.127652 0.266829 -0.4119865 0.0012700 0.000330 -0.000132 0.000066 0.000070 0.0000049 0.0000078 0.000056 0.000039 2011 12 28 55923 0.126141 0.266425 -0.4132321 0.0014075 0.000363 -0.000162 0.000066 0.000070 0.0000046 0.0000078 0.000057 0.000039 2011 12 29 55924 0.124444 0.265764 -0.4146757 0.0014918 0.000398 -0.000135 0.000066 0.000070 0.0000039 0.0000078 0.000057 0.000039 2011 12 30 55925 0.122735 0.264966 -0.4161923 0.0014976 0.000432 -0.000094 0.000066 0.000070 0.0000030 0.0000078 0.000057 0.000039 2011 12 31 55926 0.120714 0.264241 -0.4176669 0.0014137 0.000443 -0.000071 0.000066 0.000070 0.0000090 0.0000078 0.000057 0.000039 2012 1 1 55927 0.118607 0.263266 -0.4190280 0.0012692 0.000444 -0.000055 0.000067 0.000054 0.0000143 0.0000150 0.000054 0.000056 2012 1 2 55928 0.117456 0.262472 -0.4202700 0.0011724 0.000445 -0.000040 0.000067 0.000054 0.0000170 0.0000150 0.000054 0.000056 2012 1 3 55929 0.115935 0.261720 -0.4213955 0.0010807 0.000447 -0.000024 0.000067 0.000054 0.0000132 0.0000150 0.000054 0.000056 2012 1 4 55930 0.114543 0.260620 -0.4223919 0.0009439 0.000448 -0.000008 0.000067 0.000054 0.0000065 0.0000150 0.000054 0.000056 2012 1 5 55931 0.113334 0.260231 -0.4232682 0.0008346 0.000420 -0.000078 0.000067 0.000054 0.0000058 0.0000150 0.000054 0.000056 2012 1 6 55932 0.111530 0.260009 -0.4240514 0.0007447 0.000385 -0.000171 0.000067 0.000054 0.0000068 0.0000150 0.000054 0.000056 2012 1 7 55933 0.108874 0.259776 -0.4247937 0.0007255 0.000376 -0.000188 0.000067 0.000054 0.0000109 0.0000150 0.000054 0.000056 2012 1 8 55934 0.106402 0.258961 -0.4255511 0.0007845 0.000377 -0.000176 0.000067 0.000054 0.0000114 0.0000150 0.000055 0.000056 2012 1 9 55935 0.104231 0.258131 -0.4263593 0.0009069 0.000377 -0.000164 0.000067 0.000054 0.0000082 0.0000150 0.000055 0.000056 2012 1 10 55936 0.101721 0.257329 -0.4272823 0.0009763 0.000377 -0.000152 0.000067 0.000054 0.0000044 0.0000151 0.000055 0.000055 2012 1 11 55937 0.099712 0.256051 -0.4283659 0.0011369 0.000372 -0.000198 0.000067 0.000054 0.0000051 0.0000151 0.000055 0.000056 2012 1 12 55938 0.098313 0.255039 -0.4296191 0.0013247 0.000365 -0.000259 0.000067 0.000054 0.0000068 0.0000151 0.000056 0.000056 2012 1 13 55939 0.097324 0.254481 -0.4310125 0.0014954 0.000358 -0.000321 0.000067 0.000054 0.0000086 0.0000151 0.000056 0.000057 2012 1 14 55940 0.096138 0.254323 -0.4325344 0.0015359 0.000347 -0.000301 0.000067 0.000054 0.0000108 0.0000151 0.000056 0.000057 2012 1 15 55941 0.094933 0.254411 -0.4340314 0.0014494 0.000334 -0.000251 0.000067 0.000054 0.0000110 0.0000151 0.000056 0.000058 2012 1 16 55942 0.093651 0.254583 -0.4354355 0.0013366 0.000322 -0.000201 0.000067 0.000054 0.0000097 0.0000151 0.000056 0.000058 2012 1 17 55943 0.091751 0.255027 -0.4366748 0.0011456 0.000309 -0.000151 0.000067 0.000054 0.0000077 0.0000152 0.000056 0.000058 2012 1 18 55944 0.089560 0.254900 -0.4377235 0.0009649 0.000281 -0.000236 0.000068 0.000054 0.0000054 0.0000152 0.000056 0.000057 2012 1 19 55945 0.087356 0.254503 -0.4385770 0.0007897 0.000389 -0.000272 0.000068 0.000054 0.0000052 0.0000152 0.000056 0.000057 2012 1 20 55946 0.085465 0.254164 -0.4393130 0.0006925 0.000533 -0.000296 0.000068 0.000054 0.0000056 0.0000152 0.000056 0.000057 2012 1 21 55947 0.083280 0.254725 -0.4400366 0.0007308 0.000526 -0.000319 0.000068 0.000054 0.0000074 0.0000152 0.000056 0.000057 2012 1 22 55948 0.080601 0.254981 -0.4408166 0.0008279 0.000426 -0.000341 0.000067 0.000054 0.0000101 0.0000152 0.000056 0.000056 2012 1 23 55949 0.078597 0.255121 -0.4417035 0.0009622 0.000325 -0.000364 0.000067 0.000054 0.0000102 0.0000153 0.000056 0.000056 2012 1 24 55950 0.076570 0.255694 -0.4427066 0.0010559 0.000224 -0.000386 0.000067 0.000054 0.0000089 0.0000153 0.000056 0.000056 2012 1 25 55951 0.074255 0.255879 -0.4437951 0.0011160 0.000287 -0.000235 0.000067 0.000054 0.0000051 0.0000153 0.000056 0.000056 2012 1 26 55952 0.071917 0.256172 -0.4449238 0.0011230 0.000267 -0.000209 0.000067 0.000054 0.0000049 0.0000154 0.000056 0.000056 2012 1 27 55953 0.069358 0.256232 -0.4460363 0.0010929 0.000211 -0.000233 0.000067 0.000054 0.0000059 0.0000154 0.000056 0.000056 2012 1 28 55954 0.066738 0.256300 -0.4470825 0.0009990 0.000234 -0.000230 0.000067 0.000054 0.0000077 0.0000154 0.000056 0.000056 2012 1 29 55955 0.064276 0.256287 -0.4480069 0.0008605 0.000287 -0.000217 0.000067 0.000054 0.0000099 0.0000154 0.000056 0.000056 2012 1 30 55956 0.061833 0.256047 -0.4488023 0.0007499 0.000340 -0.000204 0.000067 0.000054 0.0000088 0.0000154 0.000056 0.000056 2012 1 31 55957 0.059248 0.255907 -0.4494690 0.0006005 0.000392 -0.000191 0.000067 0.000054 0.0000062 0.0000155 0.000056 0.000056 2012 2 1 55958 0.056853 0.255597 -0.4499960 0.0004689 0.000328 -0.000160 0.000067 0.000054 0.0000054 0.0000155 0.000057 0.000056 2012 2 2 55959 0.054659 0.255356 -0.4504295 0.0003935 0.000234 -0.000124 0.000067 0.000054 0.0000051 0.0000156 0.000057 0.000057 2012 2 3 55960 0.052977 0.254902 -0.4508222 0.0004282 0.000331 -0.000138 0.000068 0.000054 0.0000049 0.0000156 0.000057 0.000057 2012 2 4 55961 0.051430 0.254434 -0.4512807 0.0004924 0.000360 -0.000179 0.000068 0.000054 0.0000076 0.0000156 0.000057 0.000056 2012 2 5 55962 0.049316 0.254113 -0.4517988 0.0005599 0.000342 -0.000224 0.000068 0.000054 0.0000079 0.0000156 0.000058 0.000056 2012 2 6 55963 0.047297 0.254025 -0.4524509 0.0007607 0.000323 -0.000268 0.000068 0.000054 0.0000059 0.0000157 0.000058 0.000056 2012 2 7 55964 0.045651 0.254251 -0.4533073 0.0010014 0.000304 -0.000313 0.000068 0.000054 0.0000038 0.0000157 0.000058 0.000056 2012 2 8 55965 0.044293 0.254593 -0.4544126 0.0012256 0.000293 -0.000278 0.000068 0.000054 0.0000033 0.0000158 0.000058 0.000056 2012 2 9 55966 0.043161 0.255080 -0.4557258 0.0013912 0.000283 -0.000221 0.000068 0.000054 0.0000034 0.0000158 0.000058 0.000057 2012 2 10 55967 0.042130 0.255832 -0.4571673 0.0014873 0.000369 -0.000315 0.000068 0.000054 0.0000077 0.0000158 0.000059 0.000057 2012 2 11 55968 0.041274 0.256768 -0.4586352 0.0014677 0.000332 -0.000330 0.000068 0.000054 0.0000085 0.0000158 0.000059 0.000058 2012 2 12 55969 0.040348 0.257508 -0.4600478 0.0013430 0.000238 -0.000297 0.000068 0.000054 0.0000087 0.0000158 0.000059 0.000058 2012 2 13 55970 0.038878 0.258176 -0.4613111 0.0011704 0.000143 -0.000264 0.000068 0.000054 0.0000088 0.0000159 0.000060 0.000059 2012 2 14 55971 0.037043 0.258638 -0.4623691 0.0009093 0.000048 -0.000231 0.000068 0.000054 0.0000087 0.0000159 0.000060 0.000059 2012 2 15 55972 0.035674 0.259600 -0.4631618 0.0006917 0.000150 -0.000188 0.000068 0.000054 0.0000341 0.0000160 0.000061 0.000060 2012 2 16 55973 0.034316 0.260993 -0.4637889 0.0005567 0.000226 -0.000184 0.000068 0.000054 0.0000661 0.0000160 0.000061 0.000061 2012 2 17 55974 0.033031 0.262020 -0.4643437 0.0005503 0.000195 -0.000248 0.000068 0.000054 0.0000222 0.0000160 0.000062 0.000062 2012 2 18 55975 0.031581 0.263142 -0.4649210 0.0006032 0.000163 -0.000285 0.000068 0.000054 0.0000077 0.0000160 0.000062 0.000063 2012 2 19 55976 0.030581 0.264061 -0.4655914 0.0007337 0.000141 -0.000304 0.000068 0.000054 0.0000096 0.0000160 0.000063 0.000064 2012 2 20 55977 0.029762 0.265139 -0.4663682 0.0008450 0.000119 -0.000324 0.000068 0.000054 0.0000094 0.0000161 0.000064 0.000065 2012 2 21 55978 0.028405 0.265748 -0.4672331 0.0008931 0.000097 -0.000343 0.000068 0.000054 0.0000096 0.0000161 0.000065 0.000067 2012 2 22 55979 0.026718 0.266349 -0.4681565 0.0009143 0.000075 -0.000362 0.000068 0.000054 0.0000100 0.0000161 0.000066 0.000068 2012 2 23 55980 0.024666 0.267104 -0.4690471 0.0008660 0.000135 -0.000347 0.000068 0.000054 0.0000085 0.0000162 0.000066 0.000069 2012 2 24 55981 0.022739 0.267853 -0.4698850 0.0007607 0.000217 -0.000322 0.000068 0.000054 0.0000065 0.0000162 0.000067 0.000071 2012 2 25 55982 0.021482 0.268959 -0.4706373 0.0006793 0.000246 -0.000346 0.000068 0.000054 0.0000164 0.0000161 0.000068 0.000072 2012 2 26 55983 0.020541 0.270373 -0.4712748 0.0005668 0.000257 -0.000389 0.000068 0.000054 0.0000308 0.0000161 0.000069 0.000073 2012 2 27 55984 0.020104 0.271285 -0.4718307 0.0004942 0.000267 -0.000431 0.000068 0.000054 0.0000236 0.0000162 0.000070 0.000075 2012 2 28 55985 0.019701 0.272020 -0.4722813 0.0004228 0.000278 -0.000473 0.000068 0.000054 0.0000083 0.0000162 0.000071 0.000076 2012 2 29 55986 0.019007 0.273043 -0.4726370 0.0003169 0.000408 -0.000677 0.000068 0.000054 0.0000295 0.0000162 0.000072 0.000078 2012 3 1 55987 0.018741 0.274292 -0.4729311 0.0002387 0.000401 -0.000675 0.000068 0.000054 0.0000601 0.0000162 0.000073 0.000079 2012 3 2 55988 0.018946 0.275699 -0.4732008 0.0002874 0.000177 -0.000370 0.000068 0.000054 0.0000290 0.0000162 0.000073 0.000080 2012 3 3 55989 0.018571 0.277292 -0.4735444 0.0003882 0.000113 -0.000291 0.000068 0.000054 0.0000195 0.0000162 0.000073 0.000080 2012 3 4 55990 0.017739 0.278255 -0.4740170 0.0005353 0.000128 -0.000323 0.000068 0.000054 0.0000253 0.0000162 0.000074 0.000079 2012 3 5 55991 0.017393 0.279120 -0.4746213 0.0007011 0.000143 -0.000355 0.000068 0.000054 0.0000195 0.0000162 0.000074 0.000079 2012 3 6 55992 0.016976 0.280060 -0.4754416 0.0009176 0.000158 -0.000388 0.000068 0.000054 0.0000095 0.0000162 0.000074 0.000079 2012 3 7 55993 0.015739 0.280848 -0.4764587 0.0011303 0.000144 -0.000376 0.000068 0.000054 0.0000155 0.0000163 0.000074 0.000079 2012 3 8 55994 0.014389 0.281482 -0.4776866 0.0012824 0.000122 -0.000353 0.000068 0.000054 0.0000217 0.0000163 0.000074 0.000079 2012 3 9 55995 0.013195 0.282549 -0.4790644 0.0014266 0.000100 -0.000330 0.000068 0.000054 0.0000126 0.0000162 0.000074 0.000079 2012 3 10 55996 0.012093 0.283834 -0.4805653 0.0014498 0.000080 -0.000328 0.000068 0.000054 0.0000149 0.0000162 0.000074 0.000079 2012 3 11 55997 0.011072 0.285069 -0.4820405 0.0014574 0.000061 -0.000335 0.000068 0.000054 0.0000216 0.0000162 0.000074 0.000079 2012 3 12 55998 0.009674 0.286390 -0.4834013 0.0012797 0.000041 -0.000342 0.000068 0.000054 0.0000273 0.0000162 0.000074 0.000079 2012 3 13 55999 0.008686 0.287476 -0.4846316 0.0011724 0.000022 -0.000349 0.000068 0.000054 0.0000283 0.0000163 0.000074 0.000079 2012 3 14 56000 0.007839 0.288929 -0.4857628 0.0011212 0.000002 -0.000356 0.000068 0.000054 0.0000125 0.0000163 0.000074 0.000079 2012 3 15 56001 0.006413 0.290145 -0.4868827 0.0011181 0.000042 -0.000338 0.000068 0.000054 0.0000096 0.0000163 0.000074 0.000078 2012 3 16 56002 0.004966 0.291356 -0.4880519 0.0012296 0.000096 -0.000313 0.000069 0.000054 0.0000102 0.0000163 0.000074 0.000078 2012 3 17 56003 0.003420 0.292509 -0.4893769 0.0013716 0.000134 -0.000290 0.000069 0.000054 0.0000114 0.0000162 0.000074 0.000078 2012 3 18 56004 0.001651 0.293885 -0.4908432 0.0014931 0.000166 -0.000269 0.000069 0.000055 0.0000128 0.0000162 0.000074 0.000078 2012 3 19 56005 -0.000106 0.295150 -0.4923519 0.0015901 0.000198 -0.000248 0.000069 0.000055 0.0000117 0.0000162 0.000074 0.000077 2012 3 20 56006 -0.001515 0.296051 -0.4939173 0.0016033 0.000229 -0.000226 0.000069 0.000055 0.0000096 0.0000162 0.000073 0.000077 2012 3 21 56007 -0.002657 0.296982 -0.4954533 0.0015461 0.000529 -0.000453 0.000069 0.000055 0.0000081 0.0000162 0.000073 0.000077 2012 3 22 56008 -0.003699 0.298235 -0.4969557 0.0014573 0.000564 -0.000489 0.000069 0.000055 0.0000068 0.0000162 0.000073 0.000077 2012 3 23 56009 -0.004514 0.299610 -0.4983929 0.0013626 0.000203 -0.000222 0.000069 0.000055 0.0000054 0.0000162 0.000072 0.000076 2012 3 24 56010 -0.004590 0.300954 -0.4997667 0.0013086 0.000147 -0.000164 0.000069 0.000055 0.0000086 0.0000162 0.000072 0.000075 2012 3 25 56011 -0.005000 0.302697 -0.5010341 0.0012031 0.000204 -0.000183 0.000069 0.000055 0.0000135 0.0000161 0.000071 0.000074 2012 3 26 56012 -0.005757 0.304086 -0.5021744 0.0011099 0.000261 -0.000203 0.000069 0.000055 0.0000110 0.0000161 0.000071 0.000074 2012 3 27 56013 -0.006691 0.305141 -0.5032085 0.0010382 0.000318 -0.000222 0.000069 0.000055 0.0000059 0.0000161 0.000071 0.000073 2012 3 28 56014 -0.007629 0.305806 -0.5041821 0.0010005 0.000112 -0.000282 0.000069 0.000055 0.0000217 0.0000161 0.000070 0.000073 2012 3 29 56015 -0.008133 0.307011 -0.5051721 0.0009917 -0.000020 -0.000385 0.000069 0.000055 0.0000196 0.0000161 0.000070 0.000073 2012 3 30 56016 -0.008837 0.308801 -0.5061940 0.0010267 0.000096 -0.000511 0.000069 0.000055 0.0000106 0.0000161 0.000070 0.000072 2012 3 31 56017 -0.009560 0.310692 -0.5073079 0.0011522 0.000146 -0.000518 0.000069 0.000055 0.0000139 0.0000160 0.000069 0.000071 2012 4 1 56018 -0.010237 0.312804 -0.5085227 0.0013210 0.000147 -0.000479 0.000069 0.000055 0.0000147 0.0000160 0.000068 0.000069 2012 4 2 56019 -0.011375 0.314912 -0.5098815 0.0014498 0.000147 -0.000441 0.000069 0.000055 0.0000112 0.0000160 0.000068 0.000068 2012 4 3 56020 -0.012315 0.316925 -0.5114292 0.0016305 0.000148 -0.000403 0.000069 0.000055 0.0000071 0.0000160 0.000067 0.000067 2012 4 4 56021 -0.012939 0.318717 -0.5131576 0.0017914 0.000132 -0.000326 0.000069 0.000055 0.0000060 0.0000160 0.000067 0.000066 2012 4 5 56022 -0.013376 0.320328 -0.5149966 0.0018650 0.000340 -0.000212 0.000069 0.000055 0.0000076 0.0000160 0.000066 0.000066 2012 4 6 56023 -0.013766 0.322198 -0.5168769 0.0018619 0.000379 -0.000201 0.000069 0.000055 0.0000101 0.0000160 0.000066 0.000066 2012 4 7 56024 -0.013722 0.324209 -0.5186753 0.0016751 0.000328 -0.000231 0.000069 0.000055 0.0000128 0.0000159 0.000065 0.000065 2012 4 8 56025 -0.013139 0.326001 -0.5202117 0.0014407 0.000276 -0.000261 0.000069 0.000055 0.0000164 0.0000159 0.000065 0.000065 2012 4 9 56026 -0.012305 0.327893 -0.5215509 0.0012234 0.000225 -0.000291 0.000069 0.000055 0.0000153 0.0000159 0.000064 0.000064 2012 4 10 56027 -0.011628 0.330111 -0.5226988 0.0010671 0.000173 -0.000321 0.000069 0.000055 0.0000123 0.0000159 0.000064 0.000063 2012 4 11 56028 -0.010931 0.332570 -0.5237181 0.0009808 0.000122 -0.000351 0.000069 0.000055 0.0000093 0.0000159 0.000063 0.000063 2012 4 12 56029 -0.009902 0.334881 -0.5247550 0.0010490 0.000129 -0.000241 0.000069 0.000055 0.0000067 0.0000159 0.000063 0.000063 2012 4 13 56030 -0.008873 0.337193 -0.5258453 0.0011623 0.000039 -0.000299 0.000069 0.000055 0.0000043 0.0000158 0.000062 0.000062 2012 4 14 56031 -0.008019 0.339221 -0.5270634 0.0012109 0.000019 -0.000335 0.000069 0.000055 0.0000175 0.0000158 0.000061 0.000061 2012 4 15 56032 -0.007257 0.341165 -0.5283026 0.0012676 0.000036 -0.000339 0.000069 0.000055 0.0000140 0.0000158 0.000061 0.000060 2012 4 16 56033 -0.006354 0.342980 -0.5295690 0.0013177 0.000053 -0.000343 0.000069 0.000055 0.0000077 0.0000158 0.000060 0.000059 2012 4 17 56034 -0.005200 0.344961 -0.5308789 0.0013274 0.000071 -0.000346 0.000069 0.000055 0.0000051 0.0000158 0.000060 0.000059 2012 4 18 56035 -0.004216 0.347186 -0.5321994 0.0012935 0.000069 -0.000349 0.000070 0.000055 0.0000041 0.0000158 0.000059 0.000058 2012 4 19 56036 -0.003413 0.349542 -0.5334838 0.0012706 0.000063 -0.000352 0.000070 0.000055 0.0000035 0.0000158 0.000059 0.000058 2012 4 20 56037 -0.002878 0.352017 -0.5347227 0.0011860 0.000095 -0.000305 0.000069 0.000055 0.0000055 0.0000157 0.000059 0.000058 2012 4 21 56038 -0.002439 0.354239 -0.5358474 0.0010712 0.000097 -0.000298 0.000069 0.000055 0.0000121 0.0000157 0.000059 0.000058 2012 4 22 56039 -0.001548 0.356047 -0.5368877 0.0009951 0.000083 -0.000313 0.000069 0.000055 0.0000133 0.0000157 0.000059 0.000058 2012 4 23 56040 -0.000249 0.358010 -0.5378149 0.0008812 0.000070 -0.000328 0.000069 0.000055 0.0000099 0.0000157 0.000059 0.000058 2012 4 24 56041 0.000663 0.359987 -0.5386364 0.0007737 0.000056 -0.000342 0.000069 0.000055 0.0000057 0.0000157 0.000059 0.000058 2012 4 25 56042 0.001336 0.361845 -0.5394113 0.0007670 0.000063 -0.000342 0.000069 0.000054 0.0000049 0.0000156 0.000059 0.000059 2012 4 26 56043 0.002116 0.363462 -0.5401670 0.0007561 0.000076 -0.000338 0.000069 0.000054 0.0000051 0.0000156 0.000059 0.000059 2012 4 27 56044 0.003358 0.364874 -0.5409457 0.0008144 0.000089 -0.000334 0.000069 0.000054 0.0000053 0.0000156 0.000059 0.000059 2012 4 28 56045 0.004333 0.366263 -0.5417990 0.0008880 0.000073 -0.000328 0.000069 0.000054 0.0000088 0.0000155 0.000059 0.000059 2012 4 29 56046 0.005250 0.367488 -0.5426959 0.0009475 0.000048 -0.000322 0.000069 0.000054 0.0000134 0.0000155 0.000060 0.000059 2012 4 30 56047 0.006270 0.368823 -0.5436964 0.0010676 0.000022 -0.000316 0.000068 0.000054 0.0000149 0.0000154 0.000060 0.000060 2012 5 1 56048 0.007669 0.369969 -0.5448935 0.0012747 -0.000003 -0.000310 0.000068 0.000054 0.0000128 0.0000154 0.000060 0.000060 2012 5 2 56049 0.009205 0.370919 -0.5462556 0.0014125 -0.000029 -0.000304 0.000068 0.000054 0.0000095 0.0000154 0.000060 0.000060 2012 5 3 56050 0.010508 0.371909 -0.5477068 0.0014798 -0.000055 -0.000297 0.000068 0.000054 0.0000063 0.0000153 0.000060 0.000060 2012 5 4 56051 0.011828 0.373260 -0.5491808 0.0014499 -0.000118 -0.000437 0.000068 0.000054 0.0000052 0.0000152 0.000061 0.000060 2012 5 5 56052 0.013268 0.374750 -0.5505998 0.0013537 -0.000136 -0.000477 0.000068 0.000054 0.0000129 0.0000151 0.000061 0.000060 2012 5 6 56053 0.015132 0.376335 -0.5518625 0.0011977 -0.000133 -0.000466 0.000067 0.000053 0.0000143 0.0000151 0.000061 0.000060 2012 5 7 56054 0.016326 0.378068 -0.5529385 0.0009627 -0.000131 -0.000454 0.000067 0.000053 0.0000112 0.0000150 0.000062 0.000060 2012 5 8 56055 0.017013 0.379454 -0.5538710 0.0008565 -0.000129 -0.000443 0.000067 0.000053 0.0000080 0.0000150 0.000062 0.000060 2012 5 9 56056 0.017568 0.380843 -0.5546703 0.0008602 -0.000102 -0.000364 0.000067 0.000053 0.0000254 0.0000149 0.000063 0.000061 2012 5 10 56057 0.017647 0.382021 -0.5555255 0.0008894 -0.000082 -0.000321 0.000067 0.000053 0.0000204 0.0000148 0.000063 0.000061 2012 5 11 56058 0.017665 0.382766 -0.5564726 0.0009297 -0.000066 -0.000295 0.000067 0.000053 0.0000070 0.0000148 0.000063 0.000061 2012 5 12 56059 0.018218 0.383425 -0.5574823 0.0009884 -0.000051 -0.000319 0.000066 0.000053 0.0000147 0.0000147 0.000063 0.000061 2012 5 13 56060 0.019577 0.384075 -0.5585049 0.0010470 -0.000037 -0.000362 0.000066 0.000053 0.0000169 0.0000146 0.000063 0.000061 2012 5 14 56061 0.021499 0.384758 -0.5595626 0.0010731 -0.000022 -0.000406 0.000066 0.000053 0.0000117 0.0000146 0.000063 0.000062 2012 5 15 56062 0.023632 0.385645 -0.5606233 0.0010991 -0.000007 -0.000449 0.000066 0.000053 0.0000060 0.0000146 0.000063 0.000062 2012 5 16 56063 0.025913 0.386736 -0.5617029 0.0010650 -0.000047 -0.000820 0.000066 0.000053 0.0000082 0.0000145 0.000064 0.000063 2012 5 17 56064 0.027849 0.387563 -0.5627124 0.0009584 -0.000089 -0.000704 0.000066 0.000052 0.0000108 0.0000145 0.000064 0.000064 2012 5 18 56065 0.029248 0.388431 -0.5636031 0.0008306 -0.000127 -0.000407 0.000066 0.000052 0.0000072 0.0000145 0.000064 0.000065 2012 5 19 56066 0.030336 0.388972 -0.5643395 0.0006695 -0.000129 -0.000312 0.000066 0.000052 0.0000081 0.0000144 0.000064 0.000066 2012 5 20 56067 0.031417 0.389093 -0.5649387 0.0005017 -0.000117 -0.000293 0.000066 0.000052 0.0000107 0.0000144 0.000065 0.000066 2012 5 21 56068 0.032226 0.389298 -0.5654095 0.0004069 -0.000106 -0.000273 0.000066 0.000052 0.0000102 0.0000144 0.000065 0.000067 2012 5 22 56069 0.033158 0.389771 -0.5657975 0.0004062 -0.000095 -0.000254 0.000066 0.000052 0.0000081 0.0000143 0.000065 0.000068 2012 5 23 56070 0.034138 0.390555 -0.5661864 0.0004043 -0.000219 -0.000449 0.000066 0.000052 0.0000078 0.0000143 0.000066 0.000069 2012 5 24 56071 0.035346 0.391265 -0.5666054 0.0004473 -0.000185 -0.000394 0.000066 0.000052 0.0000080 0.0000143 0.000066 0.000070 2012 5 25 56072 0.036975 0.391939 -0.5670968 0.0005182 -0.000092 -0.000246 0.000066 0.000052 0.0000082 0.0000143 0.000066 0.000070 2012 5 26 56073 0.039025 0.392515 -0.5677080 0.0006671 -0.000112 -0.000258 0.000066 0.000053 0.0000159 0.0000143 0.000066 0.000071 2012 5 27 56074 0.041087 0.393199 -0.5684545 0.0008013 -0.000173 -0.000328 0.000066 0.000053 0.0000203 0.0000143 0.000067 0.000071 2012 5 28 56075 0.042938 0.393862 -0.5693249 0.0009342 -0.000235 -0.000399 0.000066 0.000053 0.0000176 0.0000143 0.000067 0.000071 2012 5 29 56076 0.044755 0.394722 -0.5703346 0.0010679 -0.000231 -0.000430 0.000066 0.000053 0.0000129 0.0000143 0.000067 0.000071 2012 5 30 56077 0.045660 0.395517 -0.5714595 0.0011617 -0.000150 -0.000413 0.000067 0.000053 0.0000082 0.0000144 0.000067 0.000071 2012 5 31 56078 0.046276 0.396001 -0.5726653 0.0012251 -0.000099 -0.000423 0.000067 0.000053 0.0000196 0.0000144 0.000067 0.000071 2012 6 1 56079 0.046843 0.396564 -0.5738795 0.0011889 -0.000097 -0.000446 0.000067 0.000053 0.0000108 0.0000144 0.000067 0.000070 2012 6 2 56080 0.047677 0.397233 -0.5750105 0.0010696 -0.000121 -0.000431 0.000067 0.000053 0.0000131 0.0000145 0.000067 0.000069 2012 6 3 56081 0.048822 0.397651 -0.5759807 0.0008974 -0.000150 -0.000400 0.000067 0.000053 0.0000167 0.0000145 0.000066 0.000069 2012 6 4 56082 0.050123 0.397921 -0.5768086 0.0007136 -0.000179 -0.000370 0.000067 0.000053 0.0000139 0.0000145 0.000066 0.000069 2012 6 5 56083 0.051720 0.398105 -0.5774606 0.0005988 -0.000208 -0.000340 0.000068 0.000053 0.0000107 0.0000146 0.000066 0.000069 2012 6 6 56084 0.053281 0.398714 -0.5780331 0.0006063 -0.000237 -0.000310 0.000068 0.000053 0.0000085 0.0000146 0.000066 0.000069 2012 6 7 56085 0.054757 0.398962 -0.5786987 0.0006945 0.000016 -0.000238 0.000068 0.000053 0.0000076 0.0000147 0.000066 0.000069 2012 6 8 56086 0.056518 0.399542 -0.5794623 0.0008169 -0.000084 -0.000273 0.000068 0.000054 0.0000070 0.0000147 0.000066 0.000069 2012 6 9 56087 0.058188 0.400041 -0.5803636 0.0008875 -0.000159 -0.000297 0.000068 0.000054 0.0000143 0.0000147 0.000065 0.000068 2012 6 10 56088 0.059927 0.400426 -0.5812656 0.0008798 -0.000172 -0.000304 0.000068 0.000054 0.0000169 0.0000147 0.000065 0.000068 2012 6 11 56089 0.061698 0.401408 -0.5820963 0.0008057 -0.000185 -0.000310 0.000068 0.000054 0.0000131 0.0000148 0.000065 0.000068 2012 6 12 56090 0.063541 0.402544 -0.5828605 0.0007464 -0.000198 -0.000316 0.000068 0.000054 0.0000092 0.0000148 0.000065 0.000067 2012 6 13 56091 0.064991 0.403973 -0.5835394 0.0006205 -0.000210 -0.000323 0.000068 0.000054 0.0000073 0.0000148 0.000065 0.000067 2012 6 14 56092 0.065963 0.404835 -0.5840934 0.0004768 -0.000172 -0.000252 0.000069 0.000054 0.0000078 0.0000148 0.000064 0.000067 2012 6 15 56093 0.066892 0.405263 -0.5844978 0.0003313 -0.000121 -0.000161 0.000069 0.000054 0.0000088 0.0000149 0.000064 0.000067 2012 6 16 56094 0.067534 0.405469 -0.5847894 0.0002036 -0.000120 -0.000193 0.000069 0.000054 0.0000139 0.0000149 0.000064 0.000066 2012 6 17 56095 0.068583 0.405645 -0.5849710 0.0001153 -0.000138 -0.000271 0.000069 0.000054 0.0000166 0.0000149 0.000064 0.000066 2012 6 18 56096 0.070006 0.405877 -0.5850143 0.0000135 -0.000155 -0.000349 0.000069 0.000054 0.0000148 0.0000149 0.000064 0.000065 2012 6 19 56097 0.071924 0.406247 -0.5849705 -0.0000588 -0.000173 -0.000427 0.000069 0.000054 0.0000118 0.0000149 0.000064 0.000065 2012 6 20 56098 0.073693 0.406832 -0.5848565 -0.0000986 -0.000077 -0.000147 0.000069 0.000054 0.0000408 0.0000150 0.000064 0.000064 2012 6 21 56099 0.075510 0.407389 -0.5847607 -0.0000809 -0.000114 -0.000116 0.000069 0.000054 0.0000351 0.0000150 0.000064 0.000063 2012 6 22 56100 0.077397 0.408003 -0.5847363 -0.0000116 -0.000205 -0.000199 0.000069 0.000055 0.0000151 0.0000150 0.000063 0.000062 2012 6 23 56101 0.078844 0.408562 -0.5848064 0.0001244 -0.000251 -0.000227 0.000070 0.000055 0.0000129 0.0000150 0.000063 0.000060 2012 6 24 56102 0.080795 0.408545 -0.5850132 0.0002556 -0.000282 -0.000233 0.000070 0.000055 0.0000147 0.0000150 0.000062 0.000059 2012 6 25 56103 0.083094 0.408563 -0.5853390 0.0003906 -0.000312 -0.000240 0.000070 0.000055 0.0000129 0.0000150 0.000062 0.000058 2012 6 26 56104 0.085257 0.408585 -0.5857339 0.0004651 -0.000343 -0.000247 0.000070 0.000055 0.0000100 0.0000150 0.000061 0.000056 2012 6 27 56105 0.087427 0.408674 -0.5861591 0.0004179 -0.000233 -0.000200 0.000070 0.000055 0.0000076 0.0000150 0.000061 0.000055 2012 6 28 56106 0.089498 0.409048 -0.5865314 0.0003017 -0.000086 -0.000139 0.000070 0.000055 0.0000054 0.0000150 0.000060 0.000054 2012 6 29 56107 0.091392 0.409300 -0.5867638 0.0001658 -0.000219 -0.000249 0.000070 0.000055 0.0000037 0.0000150 0.000060 0.000054 2012 6 30 56108 0.092798 0.409462 -0.5868529 0.0000011 -0.000269 -0.000283 0.000070 0.000055 0.0000182 0.0000150 0.000060 0.000053 2012 7 1 56109 0.094001 0.409204 0.4132316 -0.0001232 -0.000254 -0.000268 0.000070 0.000055 0.0000204 0.0000150 0.000060 0.000053 2012 7 2 56110 0.095552 0.408988 0.4134366 -0.0002278 -0.000239 -0.000253 0.000070 0.000055 0.0000134 0.0000151 0.000060 0.000053 2012 7 3 56111 0.097220 0.408704 0.4136679 -0.0002174 -0.000223 -0.000238 0.000070 0.000055 0.0000064 0.0000151 0.000059 0.000053 2012 7 4 56112 0.098889 0.408322 0.4138690 -0.0001326 -0.000471 -0.000312 0.000070 0.000055 0.0000052 0.0000151 0.000059 0.000053 2012 7 5 56113 0.100407 0.408021 0.4139576 -0.0000423 -0.000397 -0.000289 0.000070 0.000055 0.0000054 0.0000152 0.000059 0.000053 2012 7 6 56114 0.102365 0.407534 0.4139097 0.0000945 -0.000208 -0.000229 0.000070 0.000055 0.0000057 0.0000152 0.000058 0.000053 2012 7 7 56115 0.104996 0.407511 0.4137093 0.0001994 -0.000183 -0.000216 0.000070 0.000055 0.0000150 0.0000151 0.000058 0.000053 2012 7 8 56116 0.107666 0.407629 0.4134575 0.0002823 -0.000218 -0.000220 0.000070 0.000055 0.0000193 0.0000151 0.000058 0.000053 2012 7 9 56117 0.110110 0.407811 0.4131700 0.0002993 -0.000253 -0.000224 0.000070 0.000055 0.0000137 0.0000151 0.000058 0.000053 2012 7 10 56118 0.111861 0.407867 0.4129120 0.0002372 -0.000288 -0.000228 0.000070 0.000055 0.0000053 0.0000152 0.000058 0.000054 2012 7 11 56119 0.113407 0.407609 0.4127368 0.0001155 -0.000245 -0.000148 0.000071 0.000055 0.0000079 0.0000152 0.000058 0.000054 2012 7 12 56120 0.114792 0.407317 0.4127437 -0.0000765 -0.000220 -0.000175 0.000071 0.000055 0.0000078 0.0000152 0.000058 0.000054 2012 7 13 56121 0.116615 0.407043 0.4128820 -0.0002243 -0.000206 -0.000242 0.000071 0.000055 0.0000061 0.0000152 0.000057 0.000054 2012 7 14 56122 0.118254 0.407159 0.4130768 -0.0002983 -0.000209 -0.000219 0.000071 0.000055 0.0000336 0.0000152 0.000057 0.000054 2012 7 15 56123 0.119899 0.407422 0.4133906 -0.0003178 -0.000217 -0.000164 0.000071 0.000055 0.0000261 0.0000151 0.000057 0.000054 2012 7 16 56124 0.121318 0.407356 0.4137415 -0.0003135 -0.000226 -0.000109 0.000071 0.000055 0.0000123 0.0000152 0.000057 0.000054 2012 7 17 56125 0.122718 0.407099 0.4140525 -0.0002562 -0.000234 -0.000054 0.000071 0.000055 0.0000073 0.0000152 0.000057 0.000054 2012 7 18 56126 0.124354 0.406901 0.4142058 -0.0001170 -0.000207 -0.000054 0.000071 0.000055 0.0000058 0.0000151 0.000057 0.000054 2012 7 19 56127 0.126187 0.406721 0.4142108 0.0000842 -0.000171 -0.000069 0.000071 0.000055 0.0000053 0.0000151 0.000058 0.000054 2012 7 20 56128 0.127693 0.406349 0.4140546 0.0002859 -0.000135 -0.000083 0.000071 0.000055 0.0000048 0.0000151 0.000058 0.000055 2012 7 21 56129 0.129162 0.405870 0.4137338 0.0003972 -0.000148 -0.000113 0.000071 0.000055 0.0000126 0.0000151 0.000058 0.000055 2012 7 22 56130 0.130723 0.405186 0.4132561 0.0004926 -0.000179 -0.000149 0.000070 0.000055 0.0000173 0.0000151 0.000059 0.000055 2012 7 23 56131 0.132336 0.404574 0.4127059 0.0005648 -0.000211 -0.000184 0.000070 0.000055 0.0000148 0.0000151 0.000059 0.000055 2012 7 24 56132 0.133881 0.404092 0.4121283 0.0005695 -0.000243 -0.000220 0.000070 0.000055 0.0000102 0.0000151 0.000059 0.000056 2012 7 25 56133 0.135552 0.403353 0.4115477 0.0005049 -0.000271 -0.000135 0.000070 0.000055 0.0000204 0.0000151 0.000059 0.000056 2012 7 26 56134 0.137210 0.402572 0.4110649 0.0004147 -0.000299 -0.000019 0.000070 0.000055 0.0000276 0.0000150 0.000060 0.000056 2012 7 27 56135 0.138930 0.401842 0.4107679 0.0002744 -0.000328 0.000004 0.000070 0.000055 0.0000090 0.0000150 0.000060 0.000055 2012 7 28 56136 0.140922 0.401193 0.4105430 0.0001846 -0.000308 -0.000026 0.000070 0.000055 0.0000145 0.0000150 0.000060 0.000055 2012 7 29 56137 0.142510 0.401105 0.4104150 0.0000914 -0.000271 -0.000065 0.000070 0.000055 0.0000156 0.0000150 0.000059 0.000055 2012 7 30 56138 0.143441 0.400775 0.4103339 0.0000909 -0.000233 -0.000103 0.000070 0.000055 0.0000104 0.0000150 0.000059 0.000055 2012 7 31 56139 0.144548 0.400273 0.4102120 0.0001960 -0.000196 -0.000142 0.000070 0.000055 0.0000054 0.0000150 0.000059 0.000055 2012 8 1 56140 0.145891 0.399896 0.4099242 0.0003108 -0.000211 -0.000102 0.000070 0.000055 0.0000383 0.0000150 0.000059 0.000055 2012 8 2 56141 0.147300 0.399405 0.4095069 0.0004460 -0.000240 -0.000041 0.000070 0.000055 0.0000629 0.0000150 0.000059 0.000055 2012 8 3 56142 0.148482 0.398871 0.4090523 0.0005396 -0.000268 0.000020 0.000070 0.000055 0.0000173 0.0000149 0.000059 0.000055 2012 8 4 56143 0.149225 0.398181 0.4084912 0.0005550 -0.000291 0.000022 0.000070 0.000055 0.0000133 0.0000149 0.000059 0.000056 2012 8 5 56144 0.149935 0.397652 0.4078885 0.0005721 -0.000310 0.000002 0.000070 0.000055 0.0000146 0.0000149 0.000059 0.000056 2012 8 6 56145 0.150628 0.397075 0.4073568 0.0005053 -0.000330 -0.000017 0.000070 0.000055 0.0000117 0.0000149 0.000059 0.000056 2012 8 7 56146 0.151391 0.396373 0.4069442 0.0003397 -0.000349 -0.000036 0.000070 0.000055 0.0000092 0.0000148 0.000059 0.000056 2012 8 8 56147 0.152426 0.395953 0.4066792 0.0001661 -0.000326 0.000005 0.000070 0.000055 0.0000135 0.0000148 0.000058 0.000056 2012 8 9 56148 0.153656 0.395312 0.4065640 0.0000371 -0.000291 0.000062 0.000070 0.000055 0.0000187 0.0000148 0.000058 0.000056 2012 8 10 56149 0.155281 0.394270 0.4065853 -0.0000307 -0.000156 0.000004 0.000070 0.000055 0.0000193 0.0000148 0.000058 0.000056 2012 8 11 56150 0.156903 0.393449 0.4066553 -0.0000902 -0.000122 -0.000047 0.000070 0.000055 0.0000154 0.0000147 0.000058 0.000056 2012 8 12 56151 0.158492 0.392945 0.4068155 -0.0001898 -0.000136 -0.000080 0.000070 0.000055 0.0000181 0.0000147 0.000058 0.000056 2012 8 13 56152 0.160190 0.392391 0.4070188 -0.0001966 -0.000151 -0.000113 0.000070 0.000055 0.0000163 0.0000146 0.000058 0.000056 2012 8 14 56153 0.162158 0.391920 0.4071781 -0.0000889 -0.000165 -0.000146 0.000071 0.000055 0.0000122 0.0000146 0.000058 0.000056 2012 8 15 56154 0.163366 0.391505 0.4072260 0.0000211 -0.000181 -0.000123 0.000071 0.000055 0.0000092 0.0000146 0.000058 0.000055 2012 8 16 56155 0.164269 0.390762 0.4071277 0.0001737 -0.000198 -0.000084 0.000071 0.000055 0.0000064 0.0000145 0.000057 0.000055 2012 8 17 56156 0.165561 0.390066 0.4068583 0.0003561 -0.000215 -0.000046 0.000071 0.000055 0.0000037 0.0000145 0.000057 0.000054 2012 8 18 56157 0.167073 0.389100 0.4064496 0.0005073 -0.000230 -0.000041 0.000071 0.000055 0.0000159 0.0000144 0.000057 0.000054 2012 8 19 56158 0.168555 0.388010 0.4058641 0.0006279 -0.000246 -0.000049 0.000071 0.000055 0.0000193 0.0000143 0.000056 0.000054 2012 8 20 56159 0.169913 0.386831 0.4051797 0.0006642 -0.000261 -0.000057 0.000071 0.000055 0.0000128 0.0000143 0.000056 0.000054 2012 8 21 56160 0.171279 0.385449 0.4044971 0.0006251 -0.000277 -0.000066 0.000071 0.000055 0.0000049 0.0000142 0.000056 0.000054 2012 8 22 56161 0.172355 0.384355 0.4038933 0.0005229 -0.000299 -0.000031 0.000071 0.000055 0.0000042 0.0000141 0.000056 0.000055 2012 8 23 56162 0.173411 0.383089 0.4034157 0.0003797 -0.000322 0.000016 0.000071 0.000055 0.0000053 0.0000141 0.000056 0.000055 2012 8 24 56163 0.174070 0.382076 0.4031116 0.0002318 -0.000319 -0.000096 0.000071 0.000056 0.0000048 0.0000140 0.000056 0.000055 2012 8 25 56164 0.174622 0.380949 0.4029138 0.0001370 -0.000325 -0.000109 0.000071 0.000056 0.0000180 0.0000139 0.000056 0.000055 2012 8 26 56165 0.175202 0.380020 0.4027863 0.0001333 -0.000337 -0.000065 0.000071 0.000056 0.0000179 0.0000138 0.000056 0.000055 2012 8 27 56166 0.175608 0.378883 0.4025834 0.0002493 -0.000349 -0.000022 0.000071 0.000056 0.0000117 0.0000137 0.000056 0.000056 2012 8 28 56167 0.176004 0.377364 0.4022449 0.0004552 -0.000361 0.000021 0.000071 0.000056 0.0000070 0.0000136 0.000057 0.000056 2012 8 29 56168 0.176341 0.375815 0.4017238 0.0005988 -0.000213 -0.000005 0.000071 0.000056 0.0000100 0.0000135 0.000057 0.000056 2012 8 30 56169 0.176706 0.374297 0.4010457 0.0007448 -0.000185 -0.000019 0.000071 0.000056 0.0000084 0.0000134 0.000057 0.000056 2012 8 31 56170 0.177100 0.373141 0.4002442 0.0008230 -0.000206 -0.000024 0.000071 0.000056 0.0000049 0.0000133 0.000057 0.000055 2012 9 1 56171 0.177281 0.372026 0.3993541 0.0008663 -0.000230 0.000028 0.000071 0.000056 0.0000110 0.0000131 0.000057 0.000055 2012 9 2 56172 0.176983 0.370934 0.3985290 0.0008248 -0.000254 0.000100 0.000071 0.000056 0.0000136 0.0000130 0.000058 0.000055 2012 9 3 56173 0.176616 0.369645 0.3977296 0.0007964 -0.000279 0.000172 0.000071 0.000056 0.0000091 0.0000129 0.000058 0.000056 2012 9 4 56174 0.176296 0.368435 0.3970185 0.0006528 -0.000303 0.000244 0.000071 0.000056 0.0000064 0.0000128 0.000058 0.000056 2012 9 5 56175 0.176159 0.366913 0.3964406 0.0004866 -0.000050 0.000045 0.000071 0.000056 0.0000053 0.0000127 0.000059 0.000055 2012 9 6 56176 0.176023 0.365384 0.3960312 0.0003611 -0.000059 -0.000017 0.000071 0.000056 0.0000054 0.0000125 0.000059 0.000055 2012 9 7 56177 0.175901 0.363645 0.3957327 0.0002671 -0.000136 -0.000043 0.000071 0.000056 0.0000059 0.0000124 0.000059 0.000055 2012 9 8 56178 0.175869 0.362282 0.3954902 0.0001911 -0.000160 -0.000038 0.000071 0.000056 0.0000107 0.0000122 0.000059 0.000056 2012 9 9 56179 0.175738 0.360991 0.3952964 0.0002287 -0.000165 -0.000021 0.000071 0.000056 0.0000141 0.0000121 0.000059 0.000056 2012 9 10 56180 0.175572 0.359715 0.3950372 0.0003258 -0.000169 -0.000004 0.000071 0.000056 0.0000113 0.0000120 0.000059 0.000056 2012 9 11 56181 0.175641 0.358341 0.3946532 0.0004811 -0.000174 0.000013 0.000071 0.000056 0.0000062 0.0000118 0.000059 0.000056 2012 9 12 56182 0.175981 0.357292 0.3941010 0.0006435 -0.000101 0.000153 0.000071 0.000056 0.0000069 0.0000117 0.000059 0.000057 2012 9 13 56183 0.176139 0.356222 0.3933494 0.0008376 -0.000007 0.000325 0.000071 0.000056 0.0000085 0.0000115 0.000060 0.000057 2012 9 14 56184 0.176713 0.355059 0.3923835 0.0010754 -0.000135 0.000175 0.000071 0.000056 0.0000076 0.0000114 0.000059 0.000058 2012 9 15 56185 0.177439 0.353948 0.3911408 0.0013646 -0.000202 0.000084 0.000071 0.000056 0.0000120 0.0000112 0.000059 0.000058 2012 9 16 56186 0.177817 0.352886 0.3897444 0.0014332 -0.000219 0.000053 0.000071 0.000056 0.0000144 0.0000112 0.000059 0.000058 2012 9 17 56187 0.177842 0.352005 0.3883295 0.0014099 -0.000236 0.000022 0.000071 0.000056 0.0000113 0.0000112 0.000059 0.000058 2012 9 18 56188 0.177753 0.350895 0.3869760 0.0012693 -0.000253 -0.000009 0.000071 0.000056 0.0000064 0.0000112 0.000059 0.000058 2012 9 19 56189 0.177475 0.349820 0.3857870 0.0011095 -0.000411 0.000030 0.000071 0.000056 0.0000057 0.0000113 0.000059 0.000058 2012 9 20 56190 0.177152 0.348315 0.3847756 0.0008787 -0.000312 0.000050 0.000071 0.000056 0.0000061 0.0000114 0.000059 0.000058 2012 9 21 56191 0.176563 0.346422 0.3839179 0.0007321 -0.000126 0.000061 0.000071 0.000056 0.0000065 0.0000115 0.000059 0.000058 2012 9 22 56192 0.176107 0.344599 0.3832346 0.0006762 -0.000093 0.000071 0.000071 0.000056 0.0000165 0.0000117 0.000058 0.000058 2012 9 23 56193 0.175898 0.343248 0.3825826 0.0007079 -0.000117 0.000082 0.000071 0.000056 0.0000188 0.0000118 0.000058 0.000058 2012 9 24 56194 0.175631 0.342118 0.3818598 0.0007768 -0.000141 0.000092 0.000071 0.000056 0.0000136 0.0000119 0.000058 0.000057 2012 9 25 56195 0.174991 0.341585 0.3810230 0.0009143 -0.000165 0.000103 0.000071 0.000056 0.0000074 0.0000121 0.000058 0.000057 2012 9 26 56196 0.173929 0.341220 0.3800091 0.0011231 -0.000160 0.000125 0.000072 0.000056 0.0000087 0.0000122 0.000058 0.000057 2012 9 27 56197 0.173144 0.340672 0.3787851 0.0012846 -0.000134 0.000160 0.000072 0.000056 0.0000072 0.0000123 0.000058 0.000057 2012 9 28 56198 0.172129 0.340005 0.3774633 0.0013584 -0.000103 0.000199 0.000072 0.000056 0.0000043 0.0000124 0.000057 0.000057 2012 9 29 56199 0.170648 0.338792 0.3761236 0.0013337 -0.000096 0.000187 0.000072 0.000056 0.0000093 0.0000125 0.000057 0.000056 2012 9 30 56200 0.169401 0.336766 0.3748318 0.0012474 -0.000098 0.000156 0.000072 0.000056 0.0000195 0.0000125 0.000057 0.000056 2012 10 1 56201 0.168868 0.334506 0.3736899 0.0010615 -0.000101 0.000125 0.000072 0.000056 0.0000175 0.0000126 0.000057 0.000056 2012 10 2 56202 0.168522 0.332881 0.3727053 0.0008837 -0.000103 0.000094 0.000072 0.000056 0.0000089 0.0000127 0.000057 0.000056 2012 10 3 56203 0.168225 0.331558 0.3719126 0.0007203 -0.000130 0.000117 0.000072 0.000057 0.0000088 0.0000128 0.000057 0.000056 2012 10 4 56204 0.168281 0.330762 0.3712539 0.0006181 -0.000127 0.000129 0.000072 0.000057 0.0000050 0.0000128 0.000057 0.000056 2012 10 5 56205 0.167805 0.329787 0.3706768 0.0005570 -0.000170 0.000165 0.000072 0.000056 0.0000038 0.0000129 0.000057 0.000055 2012 10 6 56206 0.166838 0.328555 0.3701586 0.0005114 -0.000183 0.000177 0.000072 0.000056 0.0000129 0.0000129 0.000057 0.000056 2012 10 7 56207 0.165748 0.327320 0.3696580 0.0005104 -0.000179 0.000176 0.000072 0.000056 0.0000130 0.0000130 0.000057 0.000056 2012 10 8 56208 0.164810 0.326260 0.3691179 0.0006193 -0.000175 0.000175 0.000072 0.000056 0.0000098 0.0000130 0.000058 0.000057 2012 10 9 56209 0.163822 0.325364 0.3684100 0.0007972 -0.000170 0.000174 0.000072 0.000056 0.0000298 0.0000130 0.000058 0.000057 2012 10 10 56210 0.162630 0.324124 0.3675277 0.0009531 -0.000166 0.000173 0.000072 0.000056 0.0000492 0.0000131 0.000058 0.000057 2012 10 11 56211 0.161702 0.322885 0.3664890 0.0011430 -0.000101 0.000155 0.000072 0.000056 0.0000282 0.0000131 0.000059 0.000057 2012 10 12 56212 0.160587 0.322202 0.3652668 0.0012944 -0.000075 0.000113 0.000072 0.000056 0.0000084 0.0000131 0.000059 0.000057 2012 10 13 56213 0.159086 0.321474 0.3638793 0.0014418 -0.000091 0.000109 0.000072 0.000056 0.0000089 0.0000131 0.000059 0.000057 2012 10 14 56214 0.157636 0.320617 0.3623751 0.0015103 -0.000118 0.000119 0.000071 0.000056 0.0000152 0.0000131 0.000059 0.000057 2012 10 15 56215 0.156080 0.320044 0.3608727 0.0014778 -0.000145 0.000130 0.000071 0.000056 0.0000124 0.0000131 0.000059 0.000057 2012 10 16 56216 0.154188 0.319470 0.3594748 0.0013380 -0.000172 0.000141 0.000071 0.000056 0.0000054 0.0000131 0.000059 0.000057 2012 10 17 56217 0.152110 0.318358 0.3582116 0.0011660 0.000072 0.000124 0.000071 0.000056 0.0000232 0.0000130 0.000059 0.000057 2012 10 18 56218 0.150676 0.317269 0.3571392 0.0009748 0.000089 0.000155 0.000071 0.000056 0.0000372 0.0000130 0.000059 0.000057 2012 10 19 56219 0.149592 0.316724 0.3562680 0.0008233 0.000018 0.000202 0.000071 0.000056 0.0000123 0.0000129 0.000060 0.000057 2012 10 20 56220 0.148049 0.316209 0.3554881 0.0007779 0.000006 0.000203 0.000071 0.000056 0.0000102 0.0000129 0.000060 0.000058 2012 10 21 56221 0.146531 0.315415 0.3547235 0.0007792 0.000015 0.000188 0.000071 0.000056 0.0000093 0.0000128 0.000060 0.000059 2012 10 22 56222 0.145398 0.314470 0.3539140 0.0008468 0.000024 0.000172 0.000071 0.000056 0.0000086 0.0000127 0.000060 0.000060 2012 10 23 56223 0.144905 0.313299 0.3530156 0.0009496 0.000033 0.000157 0.000071 0.000056 0.0000097 0.0000126 0.000061 0.000060 2012 10 24 56224 0.145147 0.312469 0.3519919 0.0010536 -0.000017 0.000169 0.000071 0.000056 0.0000100 0.0000125 0.000061 0.000061 2012 10 25 56225 0.145598 0.311892 0.3508927 0.0011278 -0.000082 0.000188 0.000071 0.000056 0.0000100 0.0000124 0.000061 0.000062 2012 10 26 56226 0.145953 0.311575 0.3497646 0.0011663 -0.000147 0.000207 0.000071 0.000056 0.0000101 0.0000123 0.000062 0.000062 2012 10 27 56227 0.146144 0.311395 0.3486057 0.0011259 -0.000132 0.000231 0.000071 0.000056 0.0000155 0.0000121 0.000062 0.000063 2012 10 28 56228 0.145956 0.311549 0.3474783 0.0010673 -0.000086 0.000257 0.000071 0.000057 0.0000216 0.0000120 0.000062 0.000063 2012 10 29 56229 0.144971 0.311737 0.3464581 0.0009645 -0.000040 0.000284 0.000071 0.000057 0.0000181 0.0000119 0.000063 0.000063 2012 10 30 56230 0.144095 0.311375 0.3455478 0.0008856 0.000005 0.000310 0.000071 0.000057 0.0000100 0.0000117 0.000063 0.000064 2012 10 31 56231 0.143979 0.311398 0.3447087 0.0008158 0.000023 0.000302 0.000071 0.000057 0.0000110 0.0000116 0.000063 0.000064 2012 11 1 56232 0.143360 0.311376 0.3439414 0.0007244 0.000035 0.000286 0.000071 0.000057 0.0000122 0.0000114 0.000064 0.000064 2012 11 2 56233 0.142496 0.311300 0.3432297 0.0007050 0.000046 0.000269 0.000071 0.000057 0.0000057 0.0000113 0.000064 0.000064 2012 11 3 56234 0.141499 0.311223 0.3425378 0.0006979 0.000076 0.000270 0.000071 0.000057 0.0000091 0.0000111 0.000064 0.000065 2012 11 4 56235 0.140639 0.310457 0.3417863 0.0008113 0.000112 0.000279 0.000071 0.000057 0.0000111 0.0000110 0.000065 0.000066 2012 11 5 56236 0.139628 0.309599 0.3409500 0.0008829 0.000149 0.000287 0.000071 0.000057 0.0000125 0.0000108 0.000065 0.000067 2012 11 6 56237 0.138632 0.308445 0.3400057 0.0010188 0.000186 0.000295 0.000071 0.000057 0.0000149 0.0000106 0.000066 0.000068 2012 11 7 56238 0.138082 0.307675 0.3388799 0.0011494 0.000068 0.000182 0.000071 0.000057 0.0001822 0.0000104 0.000066 0.000068 2012 11 8 56239 0.137671 0.306975 0.3376999 0.0012763 -0.000011 0.000098 0.000071 0.000057 0.0000988 0.0000103 0.000066 0.000068 2012 11 9 56240 0.137520 0.306725 0.3363831 0.0013642 0.000025 0.000118 0.000071 0.000057 0.0000197 0.0000101 0.000066 0.000067 2012 11 10 56241 0.136406 0.306978 0.3349804 0.0014156 0.000030 0.000147 0.000071 0.000057 0.0000124 0.0000099 0.000065 0.000067 2012 11 11 56242 0.135091 0.306697 0.3335078 0.0014804 0.000011 0.000169 0.000071 0.000057 0.0000151 0.0000097 0.000065 0.000066 2012 11 12 56243 0.134264 0.306352 0.3319903 0.0015071 -0.000007 0.000191 0.000071 0.000057 0.0000114 0.0000096 0.000065 0.000066 2012 11 13 56244 0.133353 0.305825 0.3305227 0.0014574 -0.000026 0.000213 0.000071 0.000057 0.0000058 0.0000094 0.000064 0.000066 2012 11 14 56245 0.132329 0.305634 0.3291285 0.0013469 -0.000168 0.000309 0.000071 0.000057 0.0000101 0.0000093 0.000064 0.000065 2012 11 15 56246 0.131245 0.305463 0.3278155 0.0012995 -0.000135 0.000313 0.000071 0.000057 0.0000170 0.0000092 0.000064 0.000065 2012 11 16 56247 0.130273 0.305073 0.3265317 0.0012885 0.000093 0.000204 0.000071 0.000057 0.0000132 0.0000091 0.000064 0.000064 2012 11 17 56248 0.129960 0.304536 0.3252176 0.0013451 0.000141 0.000168 0.000071 0.000057 0.0000120 0.0000090 0.000063 0.000063 2012 11 18 56249 0.129677 0.304695 0.3237759 0.0015091 0.000105 0.000168 0.000071 0.000057 0.0000106 0.0000089 0.000063 0.000062 2012 11 19 56250 0.128912 0.304591 0.3221869 0.0016651 0.000069 0.000168 0.000071 0.000057 0.0000088 0.0000088 0.000062 0.000061 2012 11 20 56251 0.127757 0.304176 0.3204831 0.0017276 0.000033 0.000168 0.000071 0.000057 0.0000073 0.0000088 0.000062 0.000060 2012 11 21 56252 0.126266 0.303799 0.3187450 0.0017442 0.000136 0.000185 0.000071 0.000057 0.0000053 0.0000087 0.000061 0.000059 2012 11 22 56253 0.124792 0.303069 0.3169896 0.0016953 0.000063 0.000369 0.000071 0.000057 0.0001454 0.0000087 0.000061 0.000059 2012 11 23 56254 0.123666 0.302293 0.3153034 0.0016340 -0.000088 0.000612 0.000071 0.000057 0.0001819 0.0000086 0.000061 0.000059 2012 11 24 56255 0.122847 0.301818 0.3137397 0.0015195 -0.000041 0.000534 0.000071 0.000057 0.0000570 0.0000086 0.000060 0.000058 2012 11 25 56256 0.121407 0.301373 0.3123086 0.0013608 0.000006 0.000455 0.000071 0.000057 0.0000131 0.0000086 0.000060 0.000058 2012 11 26 56257 0.120251 0.300702 0.3110208 0.0012224 0.000053 0.000376 0.000071 0.000057 0.0000102 0.0000085 0.000059 0.000057 2012 11 27 56258 0.120107 0.300386 0.3098757 0.0010821 0.000100 0.000298 0.000071 0.000057 0.0000077 0.0000085 0.000059 0.000057 2012 11 28 56259 0.119785 0.300710 0.3088516 0.0009918 0.000112 0.000185 0.000071 0.000057 0.0000052 0.0000085 0.000059 0.000056 2012 11 29 56260 0.119246 0.300664 0.3079063 0.0009329 0.000135 0.000128 0.000071 0.000057 0.0000043 0.0000084 0.000059 0.000056 2012 11 30 56261 0.118878 0.300650 0.3070091 0.0008680 0.000147 0.000183 0.000071 0.000057 0.0000040 0.0000084 0.000058 0.000056 2012 12 1 56262 0.118463 0.300293 0.3061302 0.0009130 0.000154 0.000182 0.000071 0.000057 0.0000090 0.0000084 0.000058 0.000055 2012 12 2 56263 0.117794 0.299833 0.3051642 0.0010040 0.000160 0.000148 0.000071 0.000057 0.0000108 0.0000084 0.000058 0.000055 2012 12 3 56264 0.116633 0.299517 0.3041396 0.0010702 0.000166 0.000114 0.000071 0.000057 0.0000088 0.0000084 0.000058 0.000055 2012 12 4 56265 0.115784 0.299236 0.3030387 0.0011345 0.000173 0.000079 0.000071 0.000057 0.0000063 0.0000083 0.000058 0.000054 2012 12 5 56266 0.115219 0.299591 0.3018411 0.0012537 0.000107 0.000113 0.000071 0.000057 0.0000062 0.0000083 0.000058 0.000054 2012 12 6 56267 0.114103 0.299547 0.3005395 0.0013248 0.000023 0.000164 0.000072 0.000057 0.0000068 0.0000083 0.000058 0.000055 2012 12 7 56268 0.112573 0.299348 0.2991782 0.0013703 0.000067 0.000138 0.000072 0.000057 0.0000061 0.0000083 0.000058 0.000055 2012 12 8 56269 0.110661 0.299191 0.2977975 0.0013448 0.000090 0.000134 0.000072 0.000057 0.0000131 0.0000083 0.000058 0.000055 2012 12 9 56270 0.109555 0.298402 0.2964312 0.0013327 0.000089 0.000148 0.000071 0.000057 0.0000192 0.0000083 0.000058 0.000056 2012 12 10 56271 0.108698 0.297781 0.2951039 0.0013070 0.000089 0.000163 0.000071 0.000057 0.0000160 0.0000083 0.000058 0.000056 2012 12 11 56272 0.107383 0.297137 0.2938919 0.0011542 0.000089 0.000177 0.000071 0.000057 0.0000092 0.0000082 0.000058 0.000056 2012 12 12 56273 0.106194 0.296756 0.2928187 0.0010096 0.000116 0.000219 0.000071 0.000057 0.0000062 0.0000082 0.000058 0.000057 2012 12 13 56274 0.104778 0.296462 0.2918601 0.0009132 0.000110 0.000225 0.000071 0.000057 0.0000050 0.0000082 0.000058 0.000057 2012 12 14 56275 0.103080 0.295684 0.2909485 0.0009299 0.000129 0.000238 0.000071 0.000057 0.0000040 0.0000082 0.000058 0.000057 2012 12 15 56276 0.101080 0.294900 0.2900026 0.0009653 0.000141 0.000222 0.000071 0.000057 0.0000069 0.0000081 0.000058 0.000058 2012 12 16 56277 0.099010 0.293967 0.2889966 0.0010463 0.000146 0.000193 0.000071 0.000057 0.0000165 0.0000081 0.000059 0.000058 2012 12 17 56278 0.096873 0.293472 0.2879384 0.0010838 0.000150 0.000165 0.000071 0.000057 0.0000126 0.0000081 0.000059 0.000058 2012 12 18 56279 0.094601 0.292734 0.2868233 0.0011289 0.000154 0.000136 0.000071 0.000057 0.0000072 0.0000080 0.000059 0.000058 2012 12 19 56280 0.093114 0.291778 0.2857020 0.0011225 0.000159 0.000107 0.000071 0.000057 0.0000057 0.0000080 0.000059 0.000058 2012 12 20 56281 0.091452 0.291400 0.2846994 0.0009404 0.000059 0.000256 0.000071 0.000057 0.0000053 0.0000080 0.000059 0.000059 2012 12 21 56282 0.090011 0.291172 0.2838105 0.0007950 0.000161 0.000192 0.000071 0.000057 0.0000053 0.0000080 0.000059 0.000059 2012 12 22 56283 0.088515 0.291292 0.2830266 0.0007247 0.000218 0.000147 0.000071 0.000057 0.0000122 0.0000079 0.000059 0.000059 2012 12 23 56284 0.087432 0.290763 0.2823120 0.0006972 0.000234 0.000138 0.000071 0.000056 0.0000138 0.0000079 0.000059 0.000059 2012 12 24 56285 0.086873 0.290368 0.2816746 0.0006315 0.000250 0.000129 0.000071 0.000056 0.0000161 0.0000079 0.000060 0.000059 2012 12 25 56286 0.086377 0.290255 0.2811267 0.0005137 0.000266 0.000120 0.000071 0.000056 0.0000206 0.0000079 0.000060 0.000059 2012 12 26 56287 0.085745 0.290454 0.2806435 0.0004474 0.000282 0.000111 0.000071 0.000056 0.0000252 0.0000079 0.000060 0.000059 2012 12 27 56288 0.084825 0.290572 0.2801842 0.0004679 0.000298 0.000102 0.000071 0.000057 0.0000298 0.0000079 0.000060 0.000059 2012 12 28 56289 0.082967 0.290564 0.2797191 0.0004648 0.000246 0.000142 0.000071 0.000057 0.0000101 0.0000079 0.000060 0.000059 2012 12 29 56290 0.080704 0.290251 0.2792372 0.0005027 0.000246 0.000157 0.000071 0.000057 0.0000092 0.0000079 0.000060 0.000058 2012 12 30 56291 0.078956 0.289983 0.2786123 0.0006508 0.000272 0.000156 0.000071 0.000057 0.0000163 0.0000079 0.000060 0.000058 2012 12 31 56292 0.077226 0.289981 0.2778998 0.0007661 0.000297 0.000156 0.000071 0.000057 0.0000122 0.0000079 0.000060 0.000057 2013 1 1 56293 0.075311 0.289933 0.2770733 0.0008908 0.000322 0.000156 0.000065 0.000062 0.0000074 0.0000084 0.000045 0.000041 2013 1 2 56294 0.073263 0.289986 0.2761073 0.0010380 0.000347 0.000156 0.000065 0.000062 0.0000069 0.0000084 0.000045 0.000041 2013 1 3 56295 0.071343 0.289771 0.2750342 0.0011409 0.000373 0.000156 0.000065 0.000063 0.0000064 0.0000085 0.000045 0.000040 2013 1 4 56296 0.070023 0.289588 0.2738599 0.0012019 0.000244 0.000110 0.000065 0.000063 0.0000041 0.0000085 0.000045 0.000040 2013 1 5 56297 0.069000 0.289604 0.2726428 0.0012066 0.000185 0.000071 0.000065 0.000063 0.0000152 0.0000085 0.000045 0.000040 2013 1 6 56298 0.068165 0.289674 0.2714446 0.0011391 0.000166 0.000038 0.000065 0.000063 0.0000163 0.0000085 0.000045 0.000040 2013 1 7 56299 0.067223 0.290116 0.2703909 0.0009850 0.000147 0.000006 0.000066 0.000063 0.0000099 0.0000085 0.000045 0.000040 2013 1 8 56300 0.066251 0.290552 0.2694696 0.0008888 0.000128 -0.000027 0.000066 0.000063 0.0000036 0.0000085 0.000045 0.000040 2013 1 9 56301 0.065348 0.291376 0.2686090 0.0008315 0.000167 0.000118 0.000066 0.000063 0.0000020 0.0000085 0.000045 0.000041 2013 1 10 56302 0.064418 0.292248 0.2677610 0.0008859 0.000233 0.000185 0.000066 0.000063 0.0000016 0.0000085 0.000045 0.000040 2013 1 11 56303 0.063242 0.293086 0.2668054 0.0010276 0.000273 0.000053 0.000066 0.000063 0.0000034 0.0000085 0.000045 0.000040 2013 1 12 56304 0.061991 0.293682 0.2657105 0.0011763 0.000264 0.000030 0.000066 0.000063 0.0000089 0.0000085 0.000045 0.000040 2013 1 13 56305 0.060508 0.294356 0.2644765 0.0013109 0.000241 0.000067 0.000066 0.000063 0.0000092 0.0000085 0.000045 0.000041 2013 1 14 56306 0.059252 0.295183 0.2630607 0.0014629 0.000218 0.000104 0.000066 0.000063 0.0000111 0.0000085 0.000045 0.000041 2013 1 15 56307 0.058334 0.296001 0.2615521 0.0015359 0.000203 0.000122 0.000066 0.000063 0.0000120 0.0000085 0.000045 0.000041 2013 1 16 56308 0.057061 0.296556 0.2600806 0.0014533 0.000233 0.000043 0.000066 0.000063 0.0000040 0.0000085 0.000045 0.000040 2013 1 17 56309 0.055424 0.297495 0.2586844 0.0013488 0.000218 0.000025 0.000066 0.000063 0.0000024 0.0000085 0.000045 0.000040 2013 1 18 56310 0.053896 0.298480 0.2573767 0.0012530 0.000191 0.000023 0.000066 0.000063 0.0000025 0.0000085 0.000045 0.000040 2013 1 19 56311 0.052957 0.299381 0.2561106 0.0012012 0.000168 -0.000054 0.000066 0.000063 0.0000087 0.0000085 0.000045 0.000040 2013 1 20 56312 0.051718 0.300807 0.2549491 0.0011213 0.000148 -0.000159 0.000066 0.000063 0.0000171 0.0000085 0.000045 0.000040 2013 1 21 56313 0.050256 0.301917 0.2538439 0.0010740 0.000127 -0.000263 0.000066 0.000062 0.0000146 0.0000085 0.000045 0.000040 2013 1 22 56314 0.049362 0.302844 0.2527727 0.0010638 0.000136 -0.000316 0.000066 0.000062 0.0000087 0.0000085 0.000046 0.000040 2013 1 23 56315 0.048655 0.304129 0.2517270 0.0010841 0.000249 0.000010 0.000066 0.000063 0.0000037 0.0000085 0.000045 0.000039 2013 1 24 56316 0.047844 0.305256 0.2506537 0.0011081 0.000172 0.000032 0.000066 0.000063 0.0000035 0.0000086 0.000045 0.000039 2013 1 25 56317 0.047080 0.305956 0.2495288 0.0011205 0.000046 -0.000026 0.000066 0.000063 0.0000046 0.0000086 0.000045 0.000039 2013 1 26 56318 0.046328 0.306582 0.2483738 0.0011736 0.000055 -0.000044 0.000066 0.000063 0.0000082 0.0000086 0.000045 0.000039 2013 1 27 56319 0.045576 0.306920 0.2471277 0.0013019 0.000114 -0.000046 0.000066 0.000063 0.0000101 0.0000086 0.000045 0.000039 2013 1 28 56320 0.044920 0.307242 0.2457648 0.0014110 0.000174 -0.000049 0.000066 0.000063 0.0000076 0.0000086 0.000045 0.000039 2013 1 29 56321 0.043974 0.307636 0.2443026 0.0014984 0.000233 -0.000052 0.000066 0.000063 0.0000036 0.0000086 0.000045 0.000038 2013 1 30 56322 0.043052 0.308184 0.2427638 0.0015462 0.000233 -0.000043 0.000066 0.000063 0.0000127 0.0000086 0.000045 0.000038 2013 1 31 56323 0.042733 0.309243 0.2412122 0.0015434 0.000262 -0.000071 0.000066 0.000063 0.0000199 0.0000086 0.000045 0.000039 2013 2 1 56324 0.042307 0.310564 0.2397387 0.0014218 0.000304 -0.000111 0.000066 0.000063 0.0000069 0.0000087 0.000045 0.000039 2013 2 2 56325 0.042565 0.311910 0.2383410 0.0012953 0.000292 -0.000148 0.000066 0.000063 0.0000089 0.0000087 0.000046 0.000039 2013 2 3 56326 0.042556 0.313623 0.2371329 0.0011535 0.000262 -0.000184 0.000066 0.000063 0.0000107 0.0000087 0.000046 0.000040 2013 2 4 56327 0.041961 0.314752 0.2360361 0.0010689 0.000231 -0.000221 0.000066 0.000063 0.0000078 0.0000087 0.000047 0.000040 2013 2 5 56328 0.040987 0.315647 0.2350318 0.0009328 0.000200 -0.000258 0.000066 0.000063 0.0000039 0.0000087 0.000047 0.000040 2013 2 6 56329 0.039917 0.316854 0.2340878 0.0009198 0.000187 -0.000235 0.000066 0.000063 0.0000035 0.0000087 0.000048 0.000041 2013 2 7 56330 0.038911 0.318577 0.2331423 0.0009909 0.000179 -0.000197 0.000066 0.000063 0.0000040 0.0000087 0.000048 0.000042 2013 2 8 56331 0.037403 0.319854 0.2321261 0.0011237 0.000171 -0.000159 0.000066 0.000063 0.0000045 0.0000088 0.000049 0.000043 2013 2 9 56332 0.036088 0.320567 0.2309282 0.0012763 0.000152 -0.000108 0.000066 0.000063 0.0000078 0.0000088 0.000050 0.000043 2013 2 10 56333 0.035434 0.321256 0.2296031 0.0013759 0.000129 -0.000052 0.000066 0.000063 0.0000095 0.0000088 0.000050 0.000044 2013 2 11 56334 0.035162 0.322147 0.2281975 0.0014362 0.000105 0.000003 0.000066 0.000063 0.0000344 0.0000088 0.000051 0.000045 2013 2 12 56335 0.034953 0.323255 0.2267689 0.0013880 0.000082 0.000058 0.000066 0.000063 0.0000716 0.0000088 0.000052 0.000046 2013 2 13 56336 0.034408 0.324163 0.2254444 0.0012134 0.000176 -0.000077 0.000066 0.000063 0.0000184 0.0000089 0.000052 0.000047 2013 2 14 56337 0.033748 0.324632 0.2242842 0.0010509 0.000282 -0.000166 0.000066 0.000064 0.0000024 0.0000089 0.000053 0.000048 2013 2 15 56338 0.033854 0.325158 0.2232784 0.0009396 0.000309 -0.000045 0.000066 0.000064 0.0000017 0.0000089 0.000053 0.000048 2013 2 16 56339 0.033944 0.325995 0.2223751 0.0008369 0.000309 -0.000014 0.000066 0.000064 0.0000075 0.0000090 0.000053 0.000048 2013 2 17 56340 0.033659 0.326959 0.2215763 0.0007366 0.000308 -0.000038 0.000066 0.000064 0.0000105 0.0000090 0.000054 0.000049 2013 2 18 56341 0.033288 0.327869 0.2208975 0.0006448 0.000306 -0.000061 0.000066 0.000064 0.0000088 0.0000091 0.000054 0.000050 2013 2 19 56342 0.032983 0.329206 0.2202815 0.0005863 0.000304 -0.000084 0.000066 0.000064 0.0000059 0.0000091 0.000055 0.000050 2013 2 20 56343 0.032922 0.330362 0.2196575 0.0006594 0.000235 -0.000154 0.000066 0.000064 0.0000081 0.0000092 0.000055 0.000051 2013 2 21 56344 0.032768 0.331461 0.2189314 0.0007652 0.000220 -0.000178 0.000066 0.000064 0.0000078 0.0000092 0.000055 0.000051 2013 2 22 56345 0.032541 0.332466 0.2180783 0.0009435 0.000277 -0.000141 0.000066 0.000064 0.0000064 0.0000093 0.000055 0.000051 2013 2 23 56346 0.032011 0.333495 0.2170539 0.0011225 0.000288 -0.000146 0.000066 0.000064 0.0000074 0.0000094 0.000055 0.000051 2013 2 24 56347 0.031551 0.334442 0.2158510 0.0012904 0.000274 -0.000172 0.000066 0.000064 0.0000077 0.0000095 0.000055 0.000050 2013 2 25 56348 0.030716 0.335000 0.2144735 0.0014588 0.000260 -0.000198 0.000066 0.000064 0.0000066 0.0000096 0.000055 0.000050 2013 2 26 56349 0.029613 0.335127 0.2129265 0.0016370 0.000246 -0.000224 0.000066 0.000064 0.0000052 0.0000097 0.000054 0.000050 2013 2 27 56350 0.029181 0.335809 0.2112230 0.0017356 0.000240 -0.000226 0.000066 0.000064 0.0000147 0.0000098 0.000054 0.000049 2013 2 28 56351 0.029538 0.336818 0.2094548 0.0017356 0.000238 -0.000221 0.000066 0.000064 0.0000220 0.0000099 0.000054 0.000049 2013 3 1 56352 0.030228 0.338183 0.2077328 0.0017292 0.000235 -0.000217 0.000066 0.000064 0.0000105 0.0000100 0.000053 0.000049 2013 3 2 56353 0.030508 0.339800 0.2060765 0.0015897 0.000233 -0.000226 0.000066 0.000064 0.0000078 0.0000102 0.000053 0.000048 2013 3 3 56354 0.030810 0.341317 0.2045314 0.0014927 0.000232 -0.000240 0.000066 0.000064 0.0000078 0.0000104 0.000052 0.000047 2013 3 4 56355 0.031141 0.342877 0.2030446 0.0014688 0.000231 -0.000254 0.000066 0.000064 0.0000060 0.0000106 0.000051 0.000047 2013 3 5 56356 0.031568 0.344071 0.2015923 0.0014735 0.000230 -0.000268 0.000066 0.000064 0.0000033 0.0000108 0.000051 0.000046 2013 3 6 56357 0.031980 0.345080 0.2001178 0.0015099 0.000218 -0.000231 0.000067 0.000064 0.0000029 0.0000109 0.000050 0.000046 2013 3 7 56358 0.032861 0.345739 0.1985736 0.0016168 0.000203 -0.000180 0.000067 0.000064 0.0000030 0.0000111 0.000050 0.000045 2013 3 8 56359 0.034204 0.346436 0.1969145 0.0017040 0.000189 -0.000130 0.000067 0.000064 0.0000031 0.0000113 0.000049 0.000045 2013 3 9 56360 0.035541 0.347380 0.1951483 0.0018194 0.000189 -0.000100 0.000067 0.000064 0.0000064 0.0000115 0.000049 0.000045 2013 3 10 56361 0.036619 0.348529 0.1932676 0.0019040 0.000195 -0.000078 0.000067 0.000064 0.0000122 0.0000117 0.000049 0.000044 2013 3 11 56362 0.037638 0.349952 0.1913735 0.0018998 0.000202 -0.000056 0.000067 0.000064 0.0000105 0.0000118 0.000049 0.000044 2013 3 12 56363 0.038793 0.351874 0.1894884 0.0018711 0.000208 -0.000034 0.000067 0.000064 0.0000067 0.0000120 0.000048 0.000044 2013 3 13 56364 0.039907 0.354162 0.1876533 0.0017781 0.000214 -0.000012 0.000067 0.000064 0.0000048 0.0000121 0.000048 0.000044 2013 3 14 56365 0.040538 0.356068 0.1859071 0.0016723 0.000222 -0.000046 0.000067 0.000064 0.0000045 0.0000123 0.000048 0.000043 2013 3 15 56366 0.040952 0.357486 0.1843035 0.0015482 0.000231 -0.000094 0.000067 0.000064 0.0000045 0.0000124 0.000047 0.000043 2013 3 16 56367 0.040887 0.358706 0.1828133 0.0014157 0.000253 -0.000135 0.000067 0.000065 0.0000090 0.0000126 0.000047 0.000042 2013 3 17 56368 0.040975 0.359641 0.1814599 0.0013046 0.000279 -0.000172 0.000067 0.000065 0.0000124 0.0000127 0.000046 0.000042 2013 3 18 56369 0.041530 0.360311 0.1802067 0.0012321 0.000305 -0.000210 0.000067 0.000065 0.0000101 0.0000129 0.000046 0.000041 2013 3 19 56370 0.042428 0.360712 0.1790100 0.0011480 0.000331 -0.000247 0.000067 0.000065 0.0000055 0.0000130 0.000046 0.000041 2013 3 20 56371 0.043572 0.361292 0.1778473 0.0011545 0.000328 -0.000126 0.000067 0.000065 0.0000082 0.0000131 0.000045 0.000040 2013 3 21 56372 0.044690 0.362195 0.1766711 0.0011914 0.000317 0.000037 0.000067 0.000065 0.0000103 0.0000133 0.000045 0.000040 2013 3 22 56373 0.045148 0.363217 0.1754811 0.0012585 0.000237 -0.000083 0.000067 0.000065 0.0000035 0.0000134 0.000044 0.000039 2013 3 23 56374 0.045636 0.364449 0.1741399 0.0014257 0.000211 -0.000134 0.000067 0.000065 0.0000111 0.0000135 0.000043 0.000038 2013 3 24 56375 0.046494 0.365575 0.1726491 0.0015786 0.000214 -0.000125 0.000067 0.000065 0.0000157 0.0000136 0.000043 0.000037 2013 3 25 56376 0.047552 0.366953 0.1710111 0.0017030 0.000217 -0.000115 0.000067 0.000065 0.0000109 0.0000137 0.000042 0.000037 2013 3 26 56377 0.048035 0.368228 0.1692365 0.0018518 0.000220 -0.000106 0.000067 0.000065 0.0000033 0.0000138 0.000042 0.000036 2013 3 27 56378 0.048589 0.369493 0.1673192 0.0019554 0.000175 -0.000118 0.000067 0.000065 0.0000014 0.0000139 0.000042 0.000036 2013 3 28 56379 0.049531 0.370939 0.1653403 0.0019499 0.000169 -0.000145 0.000067 0.000065 0.0000118 0.0000140 0.000042 0.000036 2013 3 29 56380 0.050469 0.372139 0.1633911 0.0018911 0.000182 -0.000173 0.000067 0.000065 0.0000224 0.0000141 0.000042 0.000036 2013 3 30 56381 0.051097 0.373351 0.1615324 0.0017897 0.000195 -0.000202 0.000067 0.000065 0.0000204 0.0000142 0.000042 0.000036 2013 3 31 56382 0.051465 0.374470 0.1598065 0.0016856 0.000208 -0.000231 0.000067 0.000065 0.0000167 0.0000143 0.000042 0.000036 2013 4 1 56383 0.051243 0.375362 0.1581798 0.0016203 0.000221 -0.000260 0.000068 0.000065 0.0000113 0.0000143 0.000042 0.000036 2013 4 2 56384 0.050849 0.376099 0.1566140 0.0015651 0.000234 -0.000288 0.000068 0.000065 0.0000069 0.0000144 0.000042 0.000036 2013 4 3 56385 0.050910 0.376790 0.1550287 0.0015671 0.000247 -0.000317 0.000068 0.000065 0.0000025 0.0000145 0.000042 0.000036 2013 4 4 56386 0.051450 0.377420 0.1534221 0.0016253 0.000188 -0.000247 0.000068 0.000065 0.0000019 0.0000145 0.000042 0.000037 2013 4 5 56387 0.052286 0.378138 0.1517310 0.0017599 0.000110 -0.000151 0.000068 0.000065 0.0000022 0.0000146 0.000042 0.000037 2013 4 6 56388 0.052841 0.378806 0.1498885 0.0018642 0.000128 -0.000126 0.000068 0.000065 0.0000116 0.0000146 0.000042 0.000037 2013 4 7 56389 0.053079 0.379354 0.1479962 0.0018990 0.000183 -0.000128 0.000068 0.000065 0.0000176 0.0000147 0.000042 0.000037 2013 4 8 56390 0.053489 0.380033 0.1461143 0.0018727 0.000237 -0.000130 0.000068 0.000065 0.0000131 0.0000147 0.000042 0.000037 2013 4 9 56391 0.054072 0.381235 0.1442868 0.0018038 0.000292 -0.000132 0.000068 0.000065 0.0000050 0.0000147 0.000042 0.000038 2013 4 10 56392 0.054962 0.382432 0.1425417 0.0016741 0.000215 -0.000123 0.000068 0.000065 0.0000026 0.0000147 0.000042 0.000038 2013 4 11 56393 0.055508 0.383574 0.1409411 0.0015045 0.000220 -0.000199 0.000068 0.000065 0.0000057 0.0000148 0.000043 0.000039 2013 4 12 56394 0.055501 0.384312 0.1395086 0.0013633 0.000294 -0.000247 0.000068 0.000065 0.0000049 0.0000148 0.000043 0.000039 2013 4 13 56395 0.055436 0.385129 0.1382103 0.0012303 0.000311 -0.000243 0.000068 0.000065 0.0000119 0.0000148 0.000043 0.000040 2013 4 14 56396 0.055457 0.385712 0.1370216 0.0011527 0.000302 -0.000228 0.000068 0.000065 0.0000135 0.0000147 0.000043 0.000040 2013 4 15 56397 0.055562 0.386062 0.1359141 0.0010929 0.000293 -0.000212 0.000068 0.000065 0.0000092 0.0000147 0.000044 0.000041 2013 4 16 56398 0.055865 0.386438 0.1348138 0.0011176 0.000284 -0.000196 0.000068 0.000065 0.0000064 0.0000147 0.000044 0.000042 2013 4 17 56399 0.056437 0.386990 0.1336824 0.0011613 0.000275 -0.000181 0.000068 0.000065 0.0000048 0.0000147 0.000044 0.000042 2013 4 18 56400 0.057487 0.387546 0.1325258 0.0011959 0.000016 -0.000212 0.000068 0.000065 0.0000034 0.0000146 0.000045 0.000043 2013 4 19 56401 0.058643 0.388716 0.1312766 0.0013074 0.000234 -0.000211 0.000068 0.000065 0.0000021 0.0000146 0.000045 0.000043 2013 4 20 56402 0.059379 0.390006 0.1298811 0.0014754 0.000330 -0.000232 0.000068 0.000065 0.0000094 0.0000146 0.000045 0.000043 2013 4 21 56403 0.059982 0.391007 0.1283435 0.0015923 0.000315 -0.000266 0.000068 0.000065 0.0000128 0.0000145 0.000045 0.000044 2013 4 22 56404 0.060976 0.392025 0.1266947 0.0016977 0.000300 -0.000301 0.000067 0.000065 0.0000094 0.0000144 0.000046 0.000044 2013 4 23 56405 0.061979 0.392889 0.1249550 0.0017958 0.000285 -0.000336 0.000067 0.000065 0.0000044 0.0000144 0.000046 0.000044 2013 4 24 56406 0.062952 0.393425 0.1231493 0.0018230 0.000077 -0.000098 0.000067 0.000065 0.0000050 0.0000143 0.000047 0.000045 2013 4 25 56407 0.063869 0.393925 0.1213230 0.0017928 0.000064 -0.000147 0.000067 0.000065 0.0000054 0.0000143 0.000047 0.000046 2013 4 26 56408 0.064803 0.394246 0.1195762 0.0017021 0.000123 -0.000302 0.000067 0.000065 0.0000053 0.0000142 0.000048 0.000046 2013 4 27 56409 0.065665 0.394813 0.1179651 0.0015426 0.000136 -0.000338 0.000067 0.000065 0.0000132 0.0000141 0.000048 0.000047 2013 4 28 56410 0.066063 0.395283 0.1165016 0.0013950 0.000132 -0.000330 0.000067 0.000065 0.0000141 0.0000141 0.000048 0.000048 2013 4 29 56411 0.066852 0.395523 0.1151293 0.0013614 0.000128 -0.000322 0.000067 0.000065 0.0000107 0.0000140 0.000049 0.000048 2013 4 30 56412 0.067865 0.396036 0.1137648 0.0013765 0.000124 -0.000314 0.000067 0.000065 0.0000075 0.0000140 0.000049 0.000049 2013 5 1 56413 0.069025 0.396180 0.1123639 0.0014226 0.000109 -0.000290 0.000067 0.000065 0.0000062 0.0000139 0.000049 0.000050 2013 5 2 56414 0.070527 0.396898 0.1108750 0.0015343 0.000093 -0.000261 0.000067 0.000065 0.0000054 0.0000138 0.000050 0.000050 2013 5 3 56415 0.072161 0.397682 0.1092913 0.0016588 0.000076 -0.000233 0.000067 0.000065 0.0000046 0.0000138 0.000050 0.000051 2013 5 4 56416 0.073905 0.398179 0.1076238 0.0016978 0.000131 -0.000233 0.000067 0.000065 0.0000061 0.0000138 0.000050 0.000051 2013 5 5 56417 0.075392 0.398755 0.1059290 0.0016712 0.000213 -0.000245 0.000067 0.000065 0.0000083 0.0000137 0.000051 0.000052 2013 5 6 56418 0.076739 0.399258 0.1042659 0.0016513 0.000296 -0.000257 0.000067 0.000065 0.0000106 0.0000137 0.000051 0.000052 2013 5 7 56419 0.077687 0.399573 0.1026670 0.0015733 0.000378 -0.000268 0.000067 0.000065 0.0000118 0.0000136 0.000051 0.000052 2013 5 8 56420 0.078725 0.399726 0.1011230 0.0014590 0.000248 -0.000090 0.000067 0.000065 0.0000088 0.0000136 0.000051 0.000052 2013 5 9 56421 0.080078 0.400193 0.0997635 0.0012814 0.000111 -0.000058 0.000067 0.000065 0.0000086 0.0000136 0.000052 0.000053 2013 5 10 56422 0.081684 0.400536 0.0985567 0.0011249 0.000013 -0.000173 0.000067 0.000065 0.0000091 0.0000135 0.000052 0.000052 2013 5 11 56423 0.084152 0.400866 0.0974615 0.0010251 0.000031 -0.000211 0.000067 0.000065 0.0000138 0.0000135 0.000052 0.000051 2013 5 12 56424 0.086383 0.401465 0.0964513 0.0009404 0.000089 -0.000206 0.000067 0.000065 0.0000201 0.0000135 0.000051 0.000050 2013 5 13 56425 0.088340 0.402205 0.0955436 0.0009047 0.000146 -0.000201 0.000067 0.000065 0.0000148 0.0000134 0.000051 0.000050 2013 5 14 56426 0.089529 0.403293 0.0946587 0.0009003 0.000204 -0.000196 0.000067 0.000065 0.0000053 0.0000134 0.000051 0.000049 2013 5 15 56427 0.090703 0.404054 0.0937165 0.0009594 0.000159 -0.000199 0.000067 0.000065 0.0000044 0.0000134 0.000051 0.000049 2013 5 16 56428 0.091108 0.404666 0.0927077 0.0010320 0.000104 -0.000291 0.000067 0.000065 0.0000044 0.0000134 0.000051 0.000050 2013 5 17 56429 0.091561 0.404812 0.0915998 0.0011958 0.000053 -0.000409 0.000067 0.000064 0.0000039 0.0000134 0.000052 0.000051 2013 5 18 56430 0.092183 0.404978 0.0903395 0.0013148 0.000088 -0.000334 0.000067 0.000064 0.0000092 0.0000134 0.000053 0.000052 2013 5 19 56431 0.093244 0.404859 0.0889514 0.0014225 0.000154 -0.000188 0.000067 0.000064 0.0000166 0.0000133 0.000053 0.000053 2013 5 20 56432 0.094778 0.404863 0.0874681 0.0014982 0.000221 -0.000042 0.000067 0.000064 0.0000353 0.0000133 0.000054 0.000055 2013 5 21 56433 0.096646 0.405104 0.0859344 0.0015116 0.000288 0.000104 0.000067 0.000064 0.0000583 0.0000133 0.000055 0.000056 2013 5 22 56434 0.098087 0.405815 0.0844135 0.0014402 0.000354 0.000250 0.000067 0.000064 0.0000812 0.0000133 0.000056 0.000058 2013 5 23 56435 0.099424 0.406665 0.0829814 0.0013784 0.000287 0.000074 0.000067 0.000064 0.0000864 0.0000133 0.000056 0.000059 2013 5 24 56436 0.100672 0.407207 0.0817119 0.0012580 0.000186 -0.000186 0.000067 0.000064 0.0000258 0.0000133 0.000057 0.000060 2013 5 25 56437 0.101496 0.407265 0.0805181 0.0011409 0.000139 -0.000337 0.000067 0.000064 0.0000132 0.0000133 0.000057 0.000061 2013 5 26 56438 0.102284 0.407252 0.0794325 0.0010312 0.000114 -0.000448 0.000067 0.000064 0.0000184 0.0000133 0.000058 0.000062 2013 5 27 56439 0.102837 0.407320 0.0784968 0.0009175 0.000088 -0.000559 0.000067 0.000064 0.0000180 0.0000133 0.000058 0.000063 2013 5 28 56440 0.103468 0.407198 0.0776036 0.0009108 0.000042 -0.000556 0.000067 0.000064 0.0000156 0.0000133 0.000059 0.000063 2013 5 29 56441 0.104057 0.407260 0.0766822 0.0009119 -0.000028 -0.000416 0.000067 0.000064 0.0000132 0.0000133 0.000059 0.000063 2013 5 30 56442 0.104772 0.407130 0.0757515 0.0009371 -0.000044 -0.000333 0.000067 0.000064 0.0000114 0.0000133 0.000058 0.000063 2013 5 31 56443 0.106250 0.406961 0.0748157 0.0009083 -0.000045 -0.000265 0.000067 0.000064 0.0000097 0.0000133 0.000058 0.000062 2013 6 1 56444 0.108260 0.406678 0.0739657 0.0008125 -0.000003 -0.000234 0.000067 0.000064 0.0000125 0.0000133 0.000058 0.000061 2013 6 2 56445 0.110238 0.406535 0.0732150 0.0006963 0.000055 -0.000218 0.000067 0.000064 0.0000170 0.0000133 0.000057 0.000060 2013 6 3 56446 0.111880 0.406443 0.0725063 0.0006465 0.000114 -0.000202 0.000067 0.000064 0.0000139 0.0000132 0.000057 0.000059 2013 6 4 56447 0.113287 0.406036 0.0719077 0.0005541 0.000172 -0.000185 0.000068 0.000064 0.0000079 0.0000132 0.000056 0.000058 2013 6 5 56448 0.114222 0.405478 0.0714164 0.0004204 0.000123 -0.000203 0.000068 0.000064 0.0000096 0.0000132 0.000056 0.000058 2013 6 6 56449 0.114604 0.404655 0.0710478 0.0003183 0.000045 -0.000230 0.000068 0.000065 0.0000116 0.0000132 0.000055 0.000057 2013 6 7 56450 0.114997 0.403825 0.0707807 0.0002378 -0.000033 -0.000258 0.000068 0.000065 0.0000070 0.0000131 0.000055 0.000056 2013 6 8 56451 0.115635 0.402946 0.0706302 0.0001403 -0.000020 -0.000274 0.000068 0.000065 0.0000057 0.0000131 0.000054 0.000055 2013 6 9 56452 0.116268 0.402131 0.0705272 0.0000820 0.000025 -0.000287 0.000068 0.000065 0.0000057 0.0000131 0.000054 0.000054 2013 6 10 56453 0.117307 0.401368 0.0704108 0.0001016 0.000071 -0.000300 0.000068 0.000065 0.0000056 0.0000131 0.000053 0.000053 2013 6 11 56454 0.118210 0.401117 0.0702382 0.0002011 0.000116 -0.000313 0.000068 0.000065 0.0000055 0.0000130 0.000053 0.000052 2013 6 12 56455 0.119114 0.400692 0.0699931 0.0002879 0.000084 -0.000274 0.000068 0.000065 0.0000057 0.0000130 0.000052 0.000051 2013 6 13 56456 0.120642 0.400080 0.0696368 0.0004226 0.000032 -0.000221 0.000068 0.000065 0.0000060 0.0000130 0.000052 0.000050 2013 6 14 56457 0.122357 0.399538 0.0691516 0.0005604 -0.000020 -0.000167 0.000068 0.000065 0.0000062 0.0000130 0.000051 0.000049 2013 6 15 56458 0.123862 0.398951 0.0684908 0.0006894 -0.000054 -0.000203 0.000068 0.000065 0.0000229 0.0000129 0.000051 0.000048 2013 6 16 56459 0.125637 0.398579 0.0676997 0.0007732 -0.000081 -0.000270 0.000068 0.000065 0.0000456 0.0000129 0.000050 0.000047 2013 6 17 56460 0.127327 0.398307 0.0669085 0.0008433 -0.000109 -0.000338 0.000068 0.000065 0.0000345 0.0000129 0.000050 0.000046 2013 6 18 56461 0.129251 0.397879 0.0661099 0.0008712 -0.000136 -0.000406 0.000068 0.000065 0.0000109 0.0000129 0.000050 0.000046 2013 6 19 56462 0.131165 0.397933 0.0652706 0.0008211 -0.000095 -0.000364 0.000069 0.000066 0.0000055 0.0000129 0.000049 0.000045 2013 6 20 56463 0.132622 0.397806 0.0644819 0.0007709 -0.000037 -0.000293 0.000069 0.000066 0.0000048 0.0000128 0.000048 0.000044 2013 6 21 56464 0.134144 0.397070 0.0637749 0.0006593 -0.000031 -0.000305 0.000069 0.000066 0.0000028 0.0000128 0.000048 0.000043 2013 6 22 56465 0.135348 0.396517 0.0631586 0.0005808 -0.000039 -0.000317 0.000069 0.000066 0.0000025 0.0000128 0.000048 0.000043 2013 6 23 56466 0.136112 0.395972 0.0625930 0.0005616 -0.000046 -0.000318 0.000069 0.000066 0.0000031 0.0000128 0.000049 0.000043 2013 6 24 56467 0.136395 0.395663 0.0620134 0.0006036 -0.000052 -0.000320 0.000069 0.000066 0.0000036 0.0000128 0.000049 0.000044 2013 6 25 56468 0.136903 0.395025 0.0613647 0.0007057 -0.000059 -0.000322 0.000069 0.000066 0.0000042 0.0000128 0.000049 0.000044 2013 6 26 56469 0.137507 0.394414 0.0606340 0.0007645 -0.000065 -0.000260 0.000069 0.000066 0.0000074 0.0000128 0.000050 0.000044 2013 6 27 56470 0.137909 0.393820 0.0598371 0.0007990 -0.000039 -0.000266 0.000069 0.000066 0.0000052 0.0000128 0.000050 0.000044 2013 6 28 56471 0.138669 0.392917 0.0590462 0.0007593 -0.000083 -0.000285 0.000069 0.000066 0.0000022 0.0000128 0.000050 0.000044 2013 6 29 56472 0.140149 0.392020 0.0583264 0.0006512 -0.000090 -0.000266 0.000069 0.000066 0.0000089 0.0000128 0.000050 0.000044 2013 6 30 56473 0.141473 0.391466 0.0577434 0.0004923 -0.000075 -0.000234 0.000069 0.000066 0.0000191 0.0000128 0.000050 0.000045 2013 7 1 56474 0.142539 0.390858 0.0573555 0.0002903 -0.000059 -0.000203 0.000069 0.000065 0.0000147 0.0000128 0.000051 0.000045 2013 7 2 56475 0.144023 0.390190 0.0571643 0.0001182 -0.000043 -0.000171 0.000069 0.000065 0.0000050 0.0000128 0.000051 0.000045 2013 7 3 56476 0.145661 0.389620 0.0571541 -0.0000571 -0.000084 -0.000225 0.000069 0.000065 0.0000053 0.0000128 0.000052 0.000046 2013 7 4 56477 0.146693 0.388854 0.0573059 -0.0002287 -0.000113 -0.000305 0.000069 0.000065 0.0000091 0.0000128 0.000052 0.000047 2013 7 5 56478 0.147627 0.387628 0.0575760 -0.0002912 -0.000128 -0.000370 0.000068 0.000065 0.0000132 0.0000128 0.000053 0.000048 2013 7 6 56479 0.148912 0.386223 0.0579190 -0.0003477 -0.000118 -0.000342 0.000068 0.000065 0.0000191 0.0000129 0.000053 0.000048 2013 7 7 56480 0.150303 0.384908 0.0582998 -0.0003593 -0.000108 -0.000314 0.000068 0.000065 0.0000316 0.0000129 0.000054 0.000049 2013 7 8 56481 0.151516 0.383569 0.0585873 -0.0002522 -0.000099 -0.000286 0.000068 0.000065 0.0000241 0.0000129 0.000054 0.000050 2013 7 9 56482 0.152960 0.382258 0.0587691 -0.0001149 -0.000089 -0.000258 0.000068 0.000065 0.0000092 0.0000130 0.000055 0.000050 2013 7 10 56483 0.154497 0.381112 0.0588261 0.0000077 0.000040 0.000035 0.000068 0.000065 0.0000071 0.0000130 0.000055 0.000051 2013 7 11 56484 0.156047 0.380758 0.0587462 0.0001672 0.000034 0.000008 0.000068 0.000065 0.0000082 0.0000130 0.000055 0.000051 2013 7 12 56485 0.156842 0.380698 0.0585307 0.0002560 -0.000025 -0.000141 0.000068 0.000065 0.0000093 0.0000131 0.000056 0.000051 2013 7 13 56486 0.157999 0.380151 0.0582181 0.0003605 -0.000049 -0.000198 0.000068 0.000065 0.0000124 0.0000131 0.000056 0.000051 2013 7 14 56487 0.159031 0.379509 0.0578244 0.0004030 -0.000059 -0.000221 0.000068 0.000065 0.0000162 0.0000132 0.000056 0.000051 2013 7 15 56488 0.159869 0.378293 0.0574029 0.0004258 -0.000069 -0.000244 0.000068 0.000065 0.0000192 0.0000132 0.000056 0.000051 2013 7 16 56489 0.160867 0.377205 0.0569745 0.0004286 -0.000080 -0.000267 0.000068 0.000065 0.0000189 0.0000133 0.000056 0.000051 2013 7 17 56490 0.161806 0.376293 0.0565401 0.0003925 -0.000090 -0.000290 0.000068 0.000065 0.0000079 0.0000133 0.000056 0.000051 2013 7 18 56491 0.162510 0.375481 0.0561690 0.0003277 -0.000083 -0.000240 0.000068 0.000065 0.0000045 0.0000134 0.000056 0.000051 2013 7 19 56492 0.162870 0.374748 0.0558747 0.0002735 -0.000070 -0.000172 0.000068 0.000065 0.0000030 0.0000134 0.000056 0.000051 2013 7 20 56493 0.163780 0.373917 0.0556450 0.0002354 -0.000095 -0.000162 0.000068 0.000065 0.0000063 0.0000135 0.000057 0.000051 2013 7 21 56494 0.164543 0.373202 0.0554100 0.0002105 -0.000133 -0.000174 0.000068 0.000065 0.0000112 0.0000135 0.000057 0.000052 2013 7 22 56495 0.164730 0.371897 0.0551500 0.0002807 -0.000171 -0.000186 0.000068 0.000065 0.0000100 0.0000136 0.000058 0.000052 2013 7 23 56496 0.165231 0.370380 0.0547788 0.0004278 -0.000209 -0.000198 0.000068 0.000065 0.0000066 0.0000136 0.000058 0.000053 2013 7 24 56497 0.165974 0.369025 0.0542736 0.0005583 -0.000219 -0.000214 0.000068 0.000065 0.0000192 0.0000137 0.000059 0.000054 2013 7 25 56498 0.166323 0.367973 0.0536557 0.0006296 -0.000185 -0.000220 0.000069 0.000065 0.0000114 0.0000137 0.000059 0.000054 2013 7 26 56499 0.166728 0.366709 0.0530040 0.0006564 -0.000063 -0.000168 0.000069 0.000065 0.0000052 0.0000138 0.000059 0.000054 2013 7 27 56500 0.167633 0.365562 0.0523629 0.0006092 -0.000009 -0.000150 0.000069 0.000065 0.0000080 0.0000138 0.000060 0.000054 2013 7 28 56501 0.168716 0.364800 0.0518137 0.0004846 0.000009 -0.000151 0.000069 0.000065 0.0000132 0.0000139 0.000060 0.000054 2013 7 29 56502 0.169699 0.364067 0.0513906 0.0003568 0.000028 -0.000152 0.000069 0.000065 0.0000181 0.0000139 0.000060 0.000055 2013 7 30 56503 0.170573 0.363004 0.0511034 0.0002257 0.000047 -0.000153 0.000069 0.000065 0.0000230 0.0000140 0.000060 0.000055 2013 7 31 56504 0.171200 0.361756 0.0509457 0.0001170 0.000073 -0.000228 0.000069 0.000065 0.0000376 0.0000140 0.000060 0.000055 2013 8 1 56505 0.171584 0.360841 0.0508848 0.0000434 -0.000042 -0.000176 0.000069 0.000065 0.0000444 0.0000141 0.000060 0.000054 2013 8 2 56506 0.171430 0.359964 0.0508783 -0.0000191 -0.000199 -0.000081 0.000069 0.000065 0.0000120 0.0000141 0.000060 0.000053 2013 8 3 56507 0.171752 0.358845 0.0508340 -0.0000291 -0.000212 -0.000067 0.000069 0.000065 0.0000187 0.0000142 0.000060 0.000052 2013 8 4 56508 0.172180 0.357545 0.0507491 -0.0000111 -0.000171 -0.000084 0.000069 0.000065 0.0000399 0.0000142 0.000060 0.000052 2013 8 5 56509 0.172376 0.356300 0.0507629 0.0000697 -0.000130 -0.000101 0.000069 0.000065 0.0000301 0.0000142 0.000059 0.000052 2013 8 6 56510 0.172494 0.355281 0.0507483 0.0001832 -0.000089 -0.000117 0.000069 0.000065 0.0000088 0.0000143 0.000059 0.000052 2013 8 7 56511 0.172699 0.354291 0.0505603 0.0002741 -0.000237 -0.000082 0.000069 0.000065 0.0000043 0.0000143 0.000059 0.000052 2013 8 8 56512 0.173404 0.353367 0.0502464 0.0003302 -0.000381 -0.000049 0.000069 0.000065 0.0000043 0.0000144 0.000059 0.000052 2013 8 9 56513 0.173693 0.352980 0.0498354 0.0004365 -0.000332 -0.000068 0.000069 0.000065 0.0000043 0.0000144 0.000059 0.000051 2013 8 10 56514 0.173874 0.352127 0.0493279 0.0005279 -0.000314 -0.000096 0.000069 0.000066 0.0000117 0.0000144 0.000059 0.000051 2013 8 11 56515 0.173973 0.351349 0.0487762 0.0005378 -0.000307 -0.000127 0.000069 0.000066 0.0000217 0.0000145 0.000059 0.000050 2013 8 12 56516 0.173727 0.350269 0.0482574 0.0004871 -0.000300 -0.000158 0.000069 0.000066 0.0000186 0.0000145 0.000059 0.000050 2013 8 13 56517 0.173596 0.348967 0.0477935 0.0004243 -0.000293 -0.000189 0.000069 0.000066 0.0000107 0.0000145 0.000059 0.000050 2013 8 14 56518 0.173664 0.347824 0.0473992 0.0003647 -0.000219 -0.000116 0.000069 0.000066 0.0000065 0.0000145 0.000058 0.000049 2013 8 15 56519 0.173730 0.346434 0.0470576 0.0003132 -0.000189 -0.000113 0.000069 0.000066 0.0000108 0.0000146 0.000058 0.000049 2013 8 16 56520 0.173632 0.345207 0.0467511 0.0002967 -0.000181 -0.000146 0.000069 0.000066 0.0000180 0.0000146 0.000058 0.000049 2013 8 17 56521 0.173307 0.343951 0.0464336 0.0003818 -0.000173 -0.000180 0.000069 0.000066 0.0000289 0.0000146 0.000058 0.000049 2013 8 18 56522 0.173225 0.342947 0.0460411 0.0005532 -0.000166 -0.000213 0.000069 0.000066 0.0000535 0.0000146 0.000058 0.000049 2013 8 19 56523 0.173145 0.341957 0.0454580 0.0006305 -0.000158 -0.000246 0.000069 0.000066 0.0000401 0.0000146 0.000058 0.000049 2013 8 20 56524 0.173084 0.340806 0.0446897 0.0007825 -0.000151 -0.000280 0.000069 0.000066 0.0000125 0.0000146 0.000058 0.000049 2013 8 21 56525 0.172378 0.339452 0.0438471 0.0008623 -0.000219 -0.000112 0.000070 0.000066 0.0000073 0.0000146 0.000058 0.000048 2013 8 22 56526 0.171662 0.337878 0.0429590 0.0008898 -0.000281 -0.000126 0.000070 0.000066 0.0000072 0.0000146 0.000058 0.000049 2013 8 23 56527 0.170580 0.336508 0.0420853 0.0008374 -0.000220 -0.000139 0.000070 0.000066 0.0000057 0.0000146 0.000058 0.000048 2013 8 24 56528 0.169716 0.334993 0.0412694 0.0007660 -0.000207 -0.000121 0.000070 0.000066 0.0000108 0.0000146 0.000058 0.000048 2013 8 25 56529 0.169112 0.333637 0.0405769 0.0006468 -0.000227 -0.000101 0.000070 0.000066 0.0000183 0.0000146 0.000058 0.000048 2013 8 26 56530 0.168864 0.332253 0.0399921 0.0005439 -0.000247 -0.000081 0.000070 0.000066 0.0000336 0.0000146 0.000057 0.000049 2013 8 27 56531 0.168452 0.330771 0.0395351 0.0003996 -0.000266 -0.000061 0.000070 0.000066 0.0000516 0.0000146 0.000057 0.000049 2013 8 28 56532 0.168403 0.329438 0.0391671 0.0002964 -0.000251 -0.000065 0.000070 0.000067 0.0000438 0.0000146 0.000057 0.000048 2013 8 29 56533 0.168158 0.328306 0.0388828 0.0002559 -0.000227 -0.000075 0.000070 0.000067 0.0000280 0.0000146 0.000056 0.000048 2013 8 30 56534 0.167666 0.327165 0.0386808 0.0002515 -0.000157 -0.000119 0.000070 0.000067 0.0000075 0.0000146 0.000056 0.000047 2013 8 31 56535 0.166524 0.325783 0.0384740 0.0002250 -0.000148 -0.000147 0.000070 0.000067 0.0000083 0.0000146 0.000055 0.000046 2013 9 1 56536 0.165762 0.324121 0.0382110 0.0003020 -0.000168 -0.000164 0.000070 0.000067 0.0000170 0.0000146 0.000055 0.000046 2013 9 2 56537 0.165522 0.322697 0.0378712 0.0004263 -0.000187 -0.000181 0.000070 0.000067 0.0000240 0.0000146 0.000055 0.000046 2013 9 3 56538 0.165319 0.321433 0.0374043 0.0005082 -0.000207 -0.000197 0.000070 0.000067 0.0000183 0.0000146 0.000054 0.000046 2013 9 4 56539 0.164795 0.320516 0.0367986 0.0006425 -0.000189 -0.000064 0.000070 0.000067 0.0000072 0.0000146 0.000054 0.000045 2013 9 5 56540 0.164319 0.319550 0.0360415 0.0008064 -0.000269 -0.000105 0.000070 0.000067 0.0000040 0.0000146 0.000053 0.000044 2013 9 6 56541 0.164302 0.318390 0.0351753 0.0009107 -0.000374 -0.000193 0.000070 0.000067 0.0000028 0.0000145 0.000052 0.000043 2013 9 7 56542 0.163914 0.317379 0.0342211 0.0009740 -0.000375 -0.000183 0.000070 0.000067 0.0000072 0.0000145 0.000052 0.000043 2013 9 8 56543 0.163487 0.316433 0.0332465 0.0009391 -0.000337 -0.000136 0.000070 0.000067 0.0000136 0.0000145 0.000052 0.000043 2013 9 9 56544 0.162930 0.315370 0.0323482 0.0008822 -0.000299 -0.000089 0.000070 0.000067 0.0000164 0.0000145 0.000051 0.000043 2013 9 10 56545 0.162046 0.314234 0.0315186 0.0007755 -0.000262 -0.000042 0.000070 0.000067 0.0000192 0.0000145 0.000051 0.000043 2013 9 11 56546 0.161079 0.312849 0.0307669 0.0007056 -0.000219 -0.000003 0.000070 0.000067 0.0000199 0.0000145 0.000051 0.000043 2013 9 12 56547 0.159894 0.311536 0.0301115 0.0006663 -0.000175 0.000034 0.000070 0.000067 0.0000082 0.0000144 0.000051 0.000043 2013 9 13 56548 0.158658 0.310005 0.0294810 0.0006449 -0.000277 0.000208 0.000070 0.000067 0.0000028 0.0000144 0.000051 0.000042 2013 9 14 56549 0.157686 0.308473 0.0288014 0.0007250 -0.000275 0.000267 0.000070 0.000067 0.0000083 0.0000144 0.000051 0.000043 2013 9 15 56550 0.157285 0.306927 0.0280076 0.0008702 -0.000215 0.000266 0.000070 0.000067 0.0000170 0.0000144 0.000051 0.000043 2013 9 16 56551 0.157114 0.305952 0.0270598 0.0010222 -0.000156 0.000266 0.000070 0.000067 0.0000142 0.0000144 0.000051 0.000043 2013 9 17 56552 0.156544 0.305543 0.0259398 0.0012024 -0.000142 0.000227 0.000070 0.000067 0.0000090 0.0000143 0.000051 0.000043 2013 9 18 56553 0.155359 0.305444 0.0246687 0.0013377 -0.000305 0.000042 0.000070 0.000067 0.0000083 0.0000143 0.000051 0.000043 2013 9 19 56554 0.153916 0.304869 0.0233110 0.0013853 -0.000290 0.000057 0.000071 0.000067 0.0000057 0.0000143 0.000050 0.000042 2013 9 20 56555 0.152835 0.304021 0.0219582 0.0013010 -0.000228 0.000124 0.000071 0.000068 0.0000026 0.0000142 0.000050 0.000042 2013 9 21 56556 0.151468 0.303256 0.0207271 0.0011423 -0.000219 0.000112 0.000071 0.000068 0.0000082 0.0000142 0.000050 0.000042 2013 9 22 56557 0.149277 0.302433 0.0196382 0.0010214 -0.000230 0.000072 0.000071 0.000068 0.0000170 0.0000141 0.000050 0.000042 2013 9 23 56558 0.146634 0.301494 0.0186897 0.0008944 -0.000241 0.000032 0.000071 0.000068 0.0000171 0.0000141 0.000050 0.000042 2013 9 24 56559 0.144771 0.300370 0.0178128 0.0008450 -0.000253 -0.000009 0.000071 0.000068 0.0000124 0.0000140 0.000050 0.000042 2013 9 25 56560 0.143504 0.299644 0.0169732 0.0008191 -0.000264 -0.000049 0.000071 0.000068 0.0000056 0.0000140 0.000050 0.000042 2013 9 26 56561 0.142035 0.298888 0.0161882 0.0007756 -0.000173 0.000029 0.000071 0.000068 0.0000099 0.0000140 0.000050 0.000043 2013 9 27 56562 0.140873 0.297982 0.0154469 0.0007198 -0.000072 0.000031 0.000071 0.000068 0.0000050 0.0000141 0.000050 0.000043 2013 9 28 56563 0.139511 0.297333 0.0147489 0.0007003 -0.000065 0.000046 0.000071 0.000068 0.0000105 0.0000141 0.000050 0.000043 2013 9 29 56564 0.137665 0.296309 0.0140103 0.0007465 -0.000090 0.000078 0.000071 0.000067 0.0000214 0.0000142 0.000050 0.000044 2013 9 30 56565 0.135471 0.295206 0.0131784 0.0008861 -0.000116 0.000110 0.000070 0.000067 0.0000173 0.0000142 0.000050 0.000044 2013 10 1 56566 0.132996 0.294189 0.0122339 0.0009851 -0.000142 0.000143 0.000070 0.000067 0.0000076 0.0000143 0.000050 0.000045 2013 10 2 56567 0.130959 0.292934 0.0111900 0.0011245 -0.000321 0.000196 0.000070 0.000067 0.0000063 0.0000143 0.000051 0.000046 2013 10 3 56568 0.129438 0.292066 0.0100165 0.0011812 -0.000334 0.000203 0.000070 0.000067 0.0000089 0.0000144 0.000051 0.000046 2013 10 4 56569 0.128473 0.291082 0.0087955 0.0012572 -0.000210 0.000081 0.000070 0.000067 0.0000054 0.0000144 0.000051 0.000046 2013 10 5 56570 0.127962 0.290177 0.0075035 0.0012910 -0.000201 0.000044 0.000070 0.000067 0.0000056 0.0000144 0.000051 0.000046 2013 10 6 56571 0.126768 0.289609 0.0062059 0.0012733 -0.000244 0.000051 0.000070 0.000067 0.0000078 0.0000144 0.000051 0.000046 2013 10 7 56572 0.124795 0.289183 0.0049334 0.0012192 -0.000287 0.000059 0.000070 0.000067 0.0000069 0.0000144 0.000051 0.000046 2013 10 8 56573 0.123114 0.288197 0.0037325 0.0011707 -0.000330 0.000067 0.000070 0.000067 0.0000048 0.0000144 0.000051 0.000047 2013 10 9 56574 0.121820 0.287321 0.0025652 0.0011339 -0.000018 -0.000032 0.000070 0.000067 0.0000140 0.0000144 0.000051 0.000047 2013 10 10 56575 0.120522 0.286790 0.0014458 0.0011061 -0.000025 -0.000007 0.000070 0.000067 0.0000206 0.0000144 0.000050 0.000047 2013 10 11 56576 0.118673 0.286134 0.0003789 0.0011101 -0.000155 0.000064 0.000069 0.000066 0.0000066 0.0000144 0.000050 0.000047 2013 10 12 56577 0.116765 0.285305 -0.0007375 0.0011577 -0.000181 0.000085 0.000069 0.000066 0.0000062 0.0000144 0.000050 0.000046 2013 10 13 56578 0.115030 0.284844 -0.0019565 0.0012431 -0.000169 0.000089 0.000069 0.000066 0.0000108 0.0000144 0.000050 0.000046 2013 10 14 56579 0.113802 0.284597 -0.0032686 0.0013816 -0.000157 0.000092 0.000069 0.000066 0.0000126 0.0000143 0.000049 0.000046 2013 10 15 56580 0.112811 0.284080 -0.0047081 0.0014959 -0.000156 0.000124 0.000069 0.000066 0.0000148 0.0000143 0.000049 0.000046 2013 10 16 56581 0.111762 0.283825 -0.0062269 0.0015403 -0.000198 0.000266 0.000069 0.000066 0.0000161 0.0000142 0.000049 0.000046 2013 10 17 56582 0.110237 0.283660 -0.0077680 0.0015102 -0.000214 0.000218 0.000069 0.000066 0.0000113 0.0000142 0.000048 0.000046 2013 10 18 56583 0.108365 0.283441 -0.0092482 0.0014385 -0.000222 0.000120 0.000069 0.000066 0.0000048 0.0000141 0.000048 0.000045 2013 10 19 56584 0.105949 0.283204 -0.0105862 0.0012853 -0.000190 0.000138 0.000069 0.000066 0.0000052 0.0000141 0.000048 0.000045 2013 10 20 56585 0.103699 0.282693 -0.0117699 0.0011053 -0.000144 0.000199 0.000069 0.000066 0.0000081 0.0000140 0.000048 0.000046 2013 10 21 56586 0.101715 0.282555 -0.0127666 0.0009064 -0.000097 0.000260 0.000069 0.000066 0.0000076 0.0000140 0.000048 0.000046 2013 10 22 56587 0.099901 0.282351 -0.0136356 0.0007936 -0.000050 0.000321 0.000069 0.000066 0.0000058 0.0000139 0.000048 0.000046 2013 10 23 56588 0.098499 0.282289 -0.0144408 0.0007584 -0.000118 0.000286 0.000069 0.000066 0.0000054 0.0000139 0.000047 0.000046 2013 10 24 56589 0.096899 0.282593 -0.0152294 0.0008042 -0.000185 0.000232 0.000069 0.000066 0.0000054 0.0000138 0.000047 0.000046 2013 10 25 56590 0.094999 0.282712 -0.0160484 0.0009433 -0.000132 0.000199 0.000069 0.000066 0.0000054 0.0000138 0.000047 0.000046 2013 10 26 56591 0.093349 0.282561 -0.0169963 0.0010364 -0.000118 0.000204 0.000069 0.000066 0.0000089 0.0000137 0.000047 0.000045 2013 10 27 56592 0.092330 0.282369 -0.0180690 0.0011019 -0.000117 0.000224 0.000069 0.000066 0.0000137 0.0000137 0.000046 0.000045 2013 10 28 56593 0.091798 0.282949 -0.0192767 0.0012716 -0.000116 0.000243 0.000069 0.000067 0.0000103 0.0000137 0.000046 0.000045 2013 10 29 56594 0.091203 0.283739 -0.0206140 0.0014087 -0.000116 0.000262 0.000069 0.000067 0.0000039 0.0000136 0.000046 0.000045 2013 10 30 56595 0.090463 0.284185 -0.0220581 0.0015023 -0.000147 0.000204 0.000069 0.000067 0.0000036 0.0000136 0.000046 0.000045 2013 10 31 56596 0.089562 0.284274 -0.0235858 0.0015320 -0.000186 0.000126 0.000070 0.000067 0.0000049 0.0000136 0.000045 0.000045 2013 11 1 56597 0.088054 0.284270 -0.0250817 0.0014698 -0.000162 0.000178 0.000070 0.000067 0.0000104 0.0000135 0.000045 0.000044 2013 11 2 56598 0.086765 0.284387 -0.0265327 0.0013811 -0.000116 0.000278 0.000070 0.000067 0.0000169 0.0000135 0.000045 0.000044 2013 11 3 56599 0.085485 0.284789 -0.0278886 0.0013043 -0.000069 0.000378 0.000070 0.000067 0.0000214 0.0000135 0.000045 0.000044 2013 11 4 56600 0.084398 0.284933 -0.0292512 0.0013043 -0.000023 0.000478 0.000070 0.000067 0.0000176 0.0000134 0.000045 0.000044 2013 11 5 56601 0.083118 0.285518 -0.0305387 0.0012651 -0.000003 0.000516 0.000070 0.000067 0.0000107 0.0000134 0.000044 0.000044 2013 11 6 56602 0.081773 0.285857 -0.0317349 0.0012149 -0.000088 0.000315 0.000070 0.000067 0.0000038 0.0000134 0.000044 0.000043 2013 11 7 56603 0.081100 0.286200 -0.0328871 0.0011385 -0.000082 0.000223 0.000070 0.000068 0.0000017 0.0000134 0.000044 0.000043 2013 11 8 56604 0.079915 0.286770 -0.0340353 0.0011564 -0.000096 0.000231 0.000070 0.000068 0.0000026 0.0000133 0.000044 0.000043 2013 11 9 56605 0.077910 0.286728 -0.0352053 0.0012022 -0.000111 0.000230 0.000070 0.000068 0.0000049 0.0000133 0.000044 0.000043 2013 11 10 56606 0.076178 0.286187 -0.0364604 0.0013002 -0.000122 0.000216 0.000070 0.000068 0.0000075 0.0000133 0.000044 0.000044 2013 11 11 56607 0.074778 0.285825 -0.0378139 0.0013773 -0.000133 0.000203 0.000070 0.000068 0.0000172 0.0000133 0.000045 0.000044 2013 11 12 56608 0.073613 0.285258 -0.0392264 0.0014437 -0.000144 0.000189 0.000070 0.000068 0.0000295 0.0000133 0.000045 0.000044 2013 11 13 56609 0.073066 0.284979 -0.0407182 0.0015010 -0.000163 0.000196 0.000070 0.000068 0.0000083 0.0000132 0.000045 0.000045 2013 11 14 56610 0.072519 0.284963 -0.0421982 0.0014418 -0.000203 0.000211 0.000070 0.000068 0.0000347 0.0000132 0.000046 0.000045 2013 11 15 56611 0.071889 0.285170 -0.0435577 0.0012787 -0.000255 0.000233 0.000070 0.000068 0.0000131 0.0000132 0.000046 0.000045 2013 11 16 56612 0.070307 0.285503 -0.0447834 0.0011450 -0.000194 0.000257 0.000070 0.000068 0.0000067 0.0000132 0.000046 0.000045 2013 11 17 56613 0.068331 0.285991 -0.0458832 0.0010649 -0.000091 0.000282 0.000070 0.000068 0.0000128 0.0000132 0.000046 0.000046 2013 11 18 56614 0.066609 0.286858 -0.0468825 0.0009562 0.000013 0.000306 0.000070 0.000068 0.0000102 0.0000132 0.000047 0.000046 2013 11 19 56615 0.065136 0.287651 -0.0478077 0.0009092 0.000116 0.000331 0.000070 0.000068 0.0000045 0.0000132 0.000047 0.000046 2013 11 20 56616 0.063662 0.288233 -0.0486815 0.0008690 -0.000007 0.000277 0.000070 0.000068 0.0000070 0.0000132 0.000048 0.000047 2013 11 21 56617 0.062281 0.288815 -0.0495622 0.0008779 -0.000088 0.000230 0.000070 0.000068 0.0000152 0.0000132 0.000048 0.000048 2013 11 22 56618 0.061361 0.289229 -0.0504540 0.0009145 -0.000082 0.000183 0.000070 0.000068 0.0000085 0.0000132 0.000048 0.000048 2013 11 23 56619 0.060916 0.289535 -0.0514536 0.0010387 -0.000056 0.000176 0.000070 0.000068 0.0000104 0.0000132 0.000048 0.000048 2013 11 24 56620 0.060132 0.290238 -0.0525633 0.0011639 -0.000031 0.000186 0.000070 0.000068 0.0000176 0.0000131 0.000049 0.000048 2013 11 25 56621 0.059463 0.290747 -0.0537420 0.0012337 -0.000005 0.000196 0.000070 0.000068 0.0000138 0.0000131 0.000049 0.000049 2013 11 26 56622 0.059054 0.291623 -0.0550095 0.0013016 0.000020 0.000205 0.000070 0.000068 0.0000084 0.0000131 0.000049 0.000049 2013 11 27 56623 0.058488 0.292239 -0.0563689 0.0013907 -0.000033 0.000411 0.000070 0.000068 0.0000112 0.0000131 0.000049 0.000049 2013 11 28 56624 0.057838 0.292856 -0.0577935 0.0014582 -0.000084 0.000504 0.000071 0.000068 0.0000121 0.0000131 0.000049 0.000049 2013 11 29 56625 0.057425 0.293396 -0.0592413 0.0014041 -0.000073 0.000448 0.000071 0.000068 0.0000284 0.0000131 0.000049 0.000049 2013 11 30 56626 0.057543 0.293803 -0.0606331 0.0013588 -0.000035 0.000356 0.000071 0.000068 0.0000503 0.0000130 0.000049 0.000049 2013 12 1 56627 0.057914 0.294200 -0.0619990 0.0013435 0.000011 0.000265 0.000071 0.000068 0.0000479 0.0000130 0.000049 0.000049 2013 12 2 56628 0.057839 0.294924 -0.0632772 0.0012458 0.000020 0.000214 0.000071 0.000068 0.0000424 0.0000130 0.000049 0.000048 2013 12 3 56629 0.057194 0.295668 -0.0644756 0.0011527 -0.000057 0.000252 0.000071 0.000068 0.0000104 0.0000129 0.000048 0.000047 2013 12 4 56630 0.056918 0.296444 -0.0656209 0.0011485 -0.000126 0.000389 0.000071 0.000068 0.0000123 0.0000129 0.000048 0.000047 2013 12 5 56631 0.057140 0.297418 -0.0667769 0.0011580 -0.000066 0.000346 0.000071 0.000069 0.0000252 0.0000129 0.000047 0.000046 2013 12 6 56632 0.057071 0.298691 -0.0679634 0.0012450 0.000033 0.000242 0.000072 0.000069 0.0000088 0.0000129 0.000047 0.000046 2013 12 7 56633 0.056992 0.300509 -0.0692558 0.0013655 0.000071 0.000301 0.000072 0.000069 0.0000129 0.0000128 0.000047 0.000045 2013 12 8 56634 0.056938 0.301651 -0.0706430 0.0014145 0.000054 0.000319 0.000072 0.000069 0.0000242 0.0000128 0.000046 0.000045 2013 12 9 56635 0.057219 0.302570 -0.0720747 0.0014267 -0.000006 0.000253 0.000072 0.000069 0.0000253 0.0000128 0.000046 0.000044 2013 12 10 56636 0.057085 0.303912 -0.0734639 0.0013498 -0.000066 0.000187 0.000072 0.000069 0.0000078 0.0000127 0.000045 0.000043 2013 12 11 56637 0.056894 0.305244 -0.0747629 0.0012567 -0.000072 0.000153 0.000072 0.000069 0.0000229 0.0000127 0.000045 0.000042 2013 12 12 56638 0.056884 0.306338 -0.0759614 0.0011469 -0.000070 0.000125 0.000072 0.000070 0.0000084 0.0000127 0.000044 0.000041 2013 12 13 56639 0.056551 0.307369 -0.0770606 0.0010580 0.000005 0.000179 0.000072 0.000070 0.0000022 0.0000126 0.000044 0.000041 2013 12 14 56640 0.055765 0.308392 -0.0780468 0.0009192 0.000058 0.000224 0.000072 0.000070 0.0000180 0.0000126 0.000043 0.000040 2013 12 15 56641 0.054607 0.308780 -0.0788703 0.0007803 0.000091 0.000253 0.000072 0.000070 0.0000236 0.0000126 0.000043 0.000040 2013 12 16 56642 0.053207 0.308627 -0.0796080 0.0006877 0.000111 0.000280 0.000073 0.000070 0.0000169 0.0000126 0.000043 0.000039 2013 12 17 56643 0.051747 0.308124 -0.0802390 0.0006188 -0.000024 0.000288 0.000073 0.000070 0.0000105 0.0000126 0.000042 0.000039 2013 12 18 56644 0.049948 0.308089 -0.0808494 0.0006070 -0.000048 0.000241 0.000073 0.000070 0.0000046 0.0000126 0.000042 0.000038 2013 12 19 56645 0.048273 0.308191 -0.0814842 0.0006785 0.000007 0.000195 0.000073 0.000070 0.0000017 0.0000126 0.000041 0.000038 2013 12 20 56646 0.047064 0.308707 -0.0821956 0.0007629 0.000073 0.000202 0.000073 0.000070 0.0000016 0.0000126 0.000041 0.000037 2013 12 21 56647 0.046035 0.309134 -0.0830511 0.0009297 0.000086 0.000177 0.000073 0.000070 0.0000046 0.0000125 0.000041 0.000037 2013 12 22 56648 0.045171 0.309786 -0.0840450 0.0010592 0.000078 0.000134 0.000073 0.000071 0.0000087 0.0000125 0.000040 0.000037 2013 12 23 56649 0.044273 0.310487 -0.0851666 0.0011598 0.000071 0.000090 0.000073 0.000071 0.0000098 0.0000125 0.000040 0.000036 2013 12 24 56650 0.043536 0.311211 -0.0864052 0.0012651 0.000063 0.000047 0.000073 0.000071 0.0000100 0.0000125 0.000040 0.000036 2013 12 25 56651 0.042681 0.312389 -0.0877381 0.0013238 0.000052 0.000038 0.000073 0.000071 0.0000077 0.0000125 0.000040 0.000036 2013 12 26 56652 0.041817 0.313465 -0.0891304 0.0013841 0.000039 0.000039 0.000073 0.000071 0.0000048 0.0000125 0.000040 0.000036 2013 12 27 56653 0.041024 0.314925 -0.0905397 0.0014322 0.000027 0.000039 0.000073 0.000071 0.0000019 0.0000125 0.000040 0.000036 2013 12 28 56654 0.040472 0.316045 -0.0919746 0.0014002 0.000024 0.000060 0.000073 0.000071 0.0000072 0.0000125 0.000040 0.000036 2013 12 29 56655 0.040086 0.316906 -0.0933653 0.0013948 0.000025 0.000089 0.000073 0.000071 0.0000156 0.0000125 0.000040 0.000036 2013 12 30 56656 0.039580 0.317719 -0.0946525 0.0012934 0.000026 0.000118 0.000073 0.000071 0.0000116 0.0000125 0.000040 0.000036 2013 12 31 56657 0.038942 0.318303 -0.0958694 0.0012211 0.000027 0.000147 0.000073 0.000071 0.0000031 0.0000125 0.000040 0.000036 2014 1 1 56658 0.038625 0.318929 -0.0970337 0.0011952 0.000008 0.000163 0.000048 0.000048 0.0000042 0.0000230 0.000047 0.000031 2014 1 2 56659 0.038411 0.319622 -0.0982274 0.0012339 -0.000016 0.000175 0.000048 0.000048 0.0000055 0.0000230 0.000048 0.000032 2014 1 3 56660 0.037804 0.320458 -0.0995076 0.0013011 -0.000041 0.000188 0.000048 0.000048 0.0000068 0.0000230 0.000049 0.000032 2014 1 4 56661 0.037059 0.320811 -0.1008557 0.0013803 -0.000026 0.000192 0.000048 0.000048 0.0000196 0.0000230 0.000049 0.000033 2014 1 5 56662 0.036698 0.321223 -0.1022601 0.0014192 0.000004 0.000193 0.000048 0.000048 0.0000168 0.0000230 0.000050 0.000033 2014 1 6 56663 0.036122 0.321908 -0.1036685 0.0013885 0.000034 0.000195 0.000049 0.000048 0.0000088 0.0000230 0.000051 0.000033 2014 1 7 56664 0.035263 0.322840 -0.1049943 0.0012674 0.000064 0.000196 0.000049 0.000048 0.0000027 0.0000230 0.000051 0.000034 2014 1 8 56665 0.034235 0.323974 -0.1061704 0.0010994 0.000102 0.000178 0.000049 0.000048 0.0000127 0.0000230 0.000052 0.000034 2014 1 9 56666 0.033904 0.324984 -0.1071902 0.0009721 0.000142 0.000155 0.000049 0.000048 0.0000210 0.0000230 0.000053 0.000034 2014 1 10 56667 0.033577 0.326468 -0.1080927 0.0008292 0.000068 0.000232 0.000049 0.000048 0.0000074 0.0000229 0.000053 0.000035 2014 1 11 56668 0.032842 0.327905 -0.1088467 0.0006654 0.000049 0.000258 0.000049 0.000048 0.0000123 0.0000229 0.000054 0.000035 2014 1 12 56669 0.031625 0.328991 -0.1094693 0.0005909 0.000064 0.000252 0.000049 0.000048 0.0000128 0.0000229 0.000054 0.000035 2014 1 13 56670 0.030240 0.330037 -0.1100268 0.0005450 0.000079 0.000247 0.000049 0.000048 0.0000089 0.0000229 0.000055 0.000035 2014 1 14 56671 0.029382 0.330675 -0.1105795 0.0005509 0.000095 0.000241 0.000049 0.000048 0.0000055 0.0000229 0.000055 0.000035 2014 1 15 56672 0.028560 0.331788 -0.1111660 0.0006293 0.000123 0.000207 0.000049 0.000048 0.0000047 0.0000230 0.000055 0.000035 2014 1 16 56673 0.027405 0.332652 -0.1118310 0.0007043 0.000155 0.000165 0.000049 0.000048 0.0000046 0.0000230 0.000055 0.000034 2014 1 17 56674 0.026585 0.333747 -0.1126033 0.0008169 0.000188 0.000123 0.000049 0.000048 0.0000045 0.0000230 0.000056 0.000034 2014 1 18 56675 0.025858 0.335129 -0.1135020 0.0009733 0.000214 0.000098 0.000049 0.000049 0.0000127 0.0000230 0.000056 0.000034 2014 1 19 56676 0.024785 0.336444 -0.1145585 0.0011195 0.000238 0.000080 0.000049 0.000049 0.0000127 0.0000231 0.000056 0.000034 2014 1 20 56677 0.023705 0.337475 -0.1157163 0.0012016 0.000263 0.000061 0.000049 0.000049 0.0000137 0.0000231 0.000056 0.000034 2014 1 21 56678 0.023636 0.338291 -0.1169543 0.0012565 0.000282 0.000045 0.000049 0.000049 0.0000118 0.0000231 0.000056 0.000033 2014 1 22 56679 0.024050 0.339040 -0.1182385 0.0012901 0.000150 0.000083 0.000049 0.000049 0.0000074 0.0000232 0.000055 0.000033 2014 1 23 56680 0.024359 0.339986 -0.1195022 0.0012505 0.000170 0.000095 0.000049 0.000049 0.0000057 0.0000232 0.000055 0.000032 2014 1 24 56681 0.024502 0.340785 -0.1207223 0.0011427 0.000230 0.000099 0.000049 0.000049 0.0000048 0.0000232 0.000054 0.000031 2014 1 25 56682 0.024346 0.341404 -0.1218576 0.0010841 0.000227 0.000085 0.000049 0.000049 0.0000175 0.0000232 0.000054 0.000031 2014 1 26 56683 0.024091 0.341819 -0.1229218 0.0010054 0.000201 0.000064 0.000050 0.000049 0.0000248 0.0000231 0.000054 0.000031 2014 1 27 56684 0.024192 0.342557 -0.1238792 0.0009439 0.000175 0.000043 0.000050 0.000049 0.0000168 0.0000231 0.000054 0.000031 2014 1 28 56685 0.024382 0.343913 -0.1248207 0.0009566 0.000149 0.000021 0.000050 0.000050 0.0000100 0.0000231 0.000054 0.000031 2014 1 29 56686 0.024523 0.345557 -0.1258202 0.0010696 0.000123 0.000000 0.000050 0.000050 0.0000066 0.0000231 0.000054 0.000031 2014 1 30 56687 0.024560 0.347002 -0.1269700 0.0012412 0.000101 0.000000 0.000050 0.000050 0.0000062 0.0000231 0.000054 0.000031 2014 1 31 56688 0.024272 0.348034 -0.1282650 0.0013455 0.000193 0.000027 0.000050 0.000050 0.0000065 0.0000231 0.000054 0.000031 2014 2 1 56689 0.023720 0.348846 -0.1296369 0.0014088 0.000181 0.000049 0.000050 0.000050 0.0000120 0.0000231 0.000054 0.000031 2014 2 2 56690 0.023527 0.349533 -0.1310635 0.0013966 0.000118 0.000067 0.000050 0.000050 0.0000141 0.0000231 0.000054 0.000031 2014 2 3 56691 0.023561 0.350124 -0.1324606 0.0013401 0.000055 0.000085 0.000050 0.000050 0.0000099 0.0000231 0.000054 0.000031 2014 2 4 56692 0.023735 0.351002 -0.1337440 0.0012129 -0.000008 0.000103 0.000050 0.000050 0.0000039 0.0000232 0.000054 0.000031 2014 2 5 56693 0.023864 0.352351 -0.1348497 0.0010118 0.000004 0.000135 0.000050 0.000050 0.0000035 0.0000232 0.000054 0.000032 2014 2 6 56694 0.024364 0.353748 -0.1357764 0.0008329 0.000060 0.000158 0.000050 0.000050 0.0000046 0.0000233 0.000055 0.000032 2014 2 7 56695 0.024526 0.355359 -0.1365467 0.0007076 0.000206 0.000130 0.000050 0.000050 0.0000057 0.0000233 0.000054 0.000032 2014 2 8 56696 0.024479 0.356729 -0.1372258 0.0006317 0.000221 0.000146 0.000050 0.000050 0.0000184 0.0000233 0.000054 0.000032 2014 2 9 56697 0.024393 0.358211 -0.1378255 0.0005625 0.000188 0.000177 0.000050 0.000050 0.0000198 0.0000234 0.000054 0.000032 2014 2 10 56698 0.024197 0.359803 -0.1383963 0.0005991 0.000155 0.000209 0.000050 0.000050 0.0000133 0.0000234 0.000054 0.000032 2014 2 11 56699 0.024040 0.361819 -0.1389977 0.0006722 0.000122 0.000240 0.000050 0.000050 0.0000067 0.0000235 0.000054 0.000031 2014 2 12 56700 0.023543 0.363777 -0.1396740 0.0007413 0.000138 0.000186 0.000050 0.000050 0.0000097 0.0000235 0.000054 0.000031 2014 2 13 56701 0.022785 0.365441 -0.1404630 0.0008543 0.000167 0.000110 0.000050 0.000050 0.0000128 0.0000236 0.000054 0.000031 2014 2 14 56702 0.022059 0.367134 -0.1413957 0.0009903 0.000289 0.000047 0.000050 0.000050 0.0000072 0.0000236 0.000055 0.000032 2014 2 15 56703 0.021459 0.368685 -0.1424475 0.0011131 0.000287 0.000033 0.000050 0.000050 0.0000175 0.0000237 0.000055 0.000033 2014 2 16 56704 0.021003 0.370446 -0.1436550 0.0012701 0.000229 0.000034 0.000050 0.000050 0.0000219 0.0000237 0.000056 0.000034 2014 2 17 56705 0.020474 0.372215 -0.1449579 0.0013350 0.000170 0.000035 0.000050 0.000050 0.0000175 0.0000238 0.000057 0.000034 2014 2 18 56706 0.019775 0.373461 -0.1463110 0.0013584 0.000111 0.000036 0.000050 0.000050 0.0000115 0.0000238 0.000057 0.000035 2014 2 19 56707 0.019852 0.374879 -0.1477017 0.0013881 0.000143 0.000075 0.000050 0.000051 0.0000143 0.0000239 0.000058 0.000036 2014 2 20 56708 0.020092 0.376167 -0.1490673 0.0013344 0.000199 0.000123 0.000050 0.000051 0.0000167 0.0000239 0.000058 0.000037 2014 2 21 56709 0.020334 0.377408 -0.1503415 0.0012212 0.000268 0.000041 0.000050 0.000051 0.0000090 0.0000240 0.000058 0.000037 2014 2 22 56710 0.020535 0.378564 -0.1515516 0.0011444 0.000294 0.000018 0.000050 0.000051 0.0000163 0.0000240 0.000058 0.000037 2014 2 23 56711 0.020713 0.380002 -0.1526832 0.0011380 0.000302 0.000034 0.000050 0.000051 0.0000186 0.0000241 0.000058 0.000037 2014 2 24 56712 0.020489 0.381457 -0.1538268 0.0011862 0.000310 0.000050 0.000050 0.000051 0.0000149 0.0000241 0.000058 0.000037 2014 2 25 56713 0.019581 0.382823 -0.1550466 0.0012721 0.000318 0.000066 0.000050 0.000051 0.0000110 0.0000241 0.000058 0.000037 2014 2 26 56714 0.018713 0.383668 -0.1563948 0.0014481 0.000234 0.000042 0.000050 0.000051 0.0000115 0.0000242 0.000057 0.000037 2014 2 27 56715 0.018762 0.384182 -0.1579400 0.0016767 0.000179 0.000014 0.000051 0.000051 0.0000117 0.0000242 0.000057 0.000037 2014 2 28 56716 0.019281 0.385242 -0.1597418 0.0018938 0.000204 -0.000011 0.000051 0.000051 0.0000064 0.0000242 0.000056 0.000036 2014 3 1 56717 0.019851 0.386589 -0.1616862 0.0019870 0.000218 -0.000005 0.000051 0.000051 0.0000119 0.0000242 0.000055 0.000035 2014 3 2 56718 0.020242 0.387918 -0.1636857 0.0019830 0.000222 0.000012 0.000051 0.000051 0.0000154 0.0000242 0.000053 0.000034 2014 3 3 56719 0.020430 0.389451 -0.1656596 0.0019172 0.000226 0.000029 0.000051 0.000051 0.0000121 0.0000242 0.000052 0.000033 2014 3 4 56720 0.020506 0.390971 -0.1675271 0.0017830 0.000230 0.000046 0.000051 0.000051 0.0000067 0.0000242 0.000051 0.000032 2014 3 5 56721 0.020362 0.392074 -0.1692341 0.0015948 0.000255 0.000039 0.000051 0.000051 0.0000114 0.0000242 0.000050 0.000031 2014 3 6 56722 0.020424 0.393010 -0.1707613 0.0014176 0.000285 0.000026 0.000051 0.000051 0.0000157 0.0000242 0.000049 0.000030 2014 3 7 56723 0.020313 0.394045 -0.1721222 0.0012988 0.000315 0.000013 0.000051 0.000051 0.0000085 0.0000242 0.000048 0.000030 2014 3 8 56724 0.020135 0.395140 -0.1733613 0.0011755 0.000317 0.000001 0.000051 0.000051 0.0000131 0.0000242 0.000047 0.000029 2014 3 9 56725 0.019846 0.396188 -0.1744938 0.0010661 0.000308 -0.000011 0.000051 0.000051 0.0000127 0.0000242 0.000046 0.000028 2014 3 10 56726 0.019509 0.396953 -0.1755689 0.0010893 0.000299 -0.000022 0.000051 0.000051 0.0000103 0.0000242 0.000045 0.000027 2014 3 11 56727 0.019197 0.398041 -0.1766179 0.0010649 0.000290 -0.000034 0.000051 0.000051 0.0000090 0.0000242 0.000044 0.000026 2014 3 12 56728 0.019420 0.399147 -0.1776735 0.0010592 0.000281 -0.000045 0.000051 0.000051 0.0000075 0.0000242 0.000044 0.000026 2014 3 13 56729 0.020234 0.400258 -0.1787999 0.0011575 0.000347 0.000061 0.000051 0.000051 0.0000071 0.0000242 0.000043 0.000025 2014 3 14 56730 0.021455 0.401268 -0.1799905 0.0012469 0.000318 0.000100 0.000051 0.000051 0.0000071 0.0000242 0.000042 0.000024 2014 3 15 56731 0.022504 0.402454 -0.1812187 0.0012929 0.000278 0.000094 0.000051 0.000051 0.0000175 0.0000242 0.000040 0.000023 2014 3 16 56732 0.023637 0.403738 -0.1825057 0.0012959 0.000248 0.000084 0.000051 0.000051 0.0000219 0.0000242 0.000039 0.000022 2014 3 17 56733 0.024470 0.405052 -0.1837803 0.0012448 0.000217 0.000073 0.000051 0.000051 0.0000181 0.0000242 0.000038 0.000021 2014 3 18 56734 0.024858 0.405660 -0.1850332 0.0012335 0.000186 0.000062 0.000051 0.000051 0.0000128 0.0000242 0.000037 0.000021 2014 3 19 56735 0.025303 0.406020 -0.1862720 0.0011909 0.000203 0.000106 0.000051 0.000051 0.0000148 0.0000241 0.000036 0.000020 2014 3 20 56736 0.026121 0.406476 -0.1874632 0.0011623 0.000244 0.000141 0.000051 0.000051 0.0000186 0.0000241 0.000036 0.000019 2014 3 21 56737 0.027395 0.407082 -0.1885929 0.0011168 0.000330 0.000089 0.000051 0.000051 0.0000225 0.0000241 0.000034 0.000018 2014 3 22 56738 0.028278 0.408420 -0.1896888 0.0011114 0.000355 0.000046 0.000051 0.000051 0.0000184 0.0000241 0.000033 0.000017 2014 3 23 56739 0.029408 0.409838 -0.1908400 0.0011640 0.000358 0.000007 0.000051 0.000051 0.0000207 0.0000240 0.000032 0.000017 2014 3 24 56740 0.030866 0.411323 -0.1920471 0.0012655 0.000361 -0.000032 0.000051 0.000051 0.0000169 0.0000240 0.000031 0.000016 2014 3 25 56741 0.032258 0.412702 -0.1933412 0.0013746 0.000364 -0.000070 0.000051 0.000051 0.0000077 0.0000240 0.000031 0.000015 2014 3 26 56742 0.033605 0.414229 -0.1947883 0.0015393 0.000336 -0.000059 0.000051 0.000051 0.0000166 0.0000240 0.000030 0.000015 2014 3 27 56743 0.034995 0.415246 -0.1963914 0.0016747 0.000301 -0.000034 0.000051 0.000051 0.0000244 0.0000240 0.000029 0.000014 2014 3 28 56744 0.036741 0.416007 -0.1980908 0.0017359 0.000258 -0.000007 0.000051 0.000051 0.0000098 0.0000240 0.000028 0.000014 2014 3 29 56745 0.038453 0.416886 -0.1998624 0.0018000 0.000240 0.000020 0.000051 0.000051 0.0000124 0.0000240 0.000027 0.000013 2014 3 30 56746 0.040414 0.418056 -0.2016841 0.0017891 0.000231 0.000048 0.000051 0.000051 0.0000233 0.0000240 0.000026 0.000012 2014 3 31 56747 0.042244 0.419490 -0.2034168 0.0016708 0.000222 0.000075 0.000050 0.000051 0.0000187 0.0000240 0.000026 0.000012 2014 4 1 56748 0.043621 0.420985 -0.2050033 0.0014932 0.000213 0.000102 0.000050 0.000050 0.0000060 0.0000240 0.000025 0.000011 2014 4 2 56749 0.044738 0.422571 -0.2064962 0.0014019 0.000270 0.000046 0.000050 0.000050 0.0000135 0.0000240 0.000025 0.000012 2014 4 3 56750 0.045494 0.423930 -0.2078544 0.0013076 0.000318 0.000015 0.000050 0.000050 0.0000209 0.0000240 0.000026 0.000012 2014 4 4 56751 0.045956 0.425019 -0.2090911 0.0012133 0.000326 0.000024 0.000050 0.000050 0.0000073 0.0000240 0.000027 0.000013 2014 4 5 56752 0.046317 0.425769 -0.2102960 0.0012089 0.000340 0.000033 0.000050 0.000050 0.0000121 0.0000240 0.000027 0.000013 2014 4 6 56753 0.046765 0.426367 -0.2115022 0.0011916 0.000362 0.000038 0.000050 0.000050 0.0000185 0.0000240 0.000028 0.000014 2014 4 7 56754 0.047654 0.426425 -0.2126763 0.0011847 0.000384 0.000043 0.000050 0.000050 0.0000139 0.0000240 0.000028 0.000014 2014 4 8 56755 0.049103 0.427191 -0.2138595 0.0011804 0.000406 0.000048 0.000050 0.000050 0.0000053 0.0000239 0.000029 0.000015 2014 4 9 56756 0.050693 0.428280 -0.2150828 0.0012427 0.000402 0.000053 0.000050 0.000050 0.0000082 0.0000239 0.000029 0.000015 2014 4 10 56757 0.052161 0.429119 -0.2163621 0.0012837 0.000392 0.000059 0.000050 0.000050 0.0000115 0.0000239 0.000030 0.000016 2014 4 11 56758 0.053265 0.429894 -0.2176827 0.0013690 0.000355 -0.000017 0.000050 0.000050 0.0000045 0.0000238 0.000031 0.000016 2014 4 12 56759 0.054207 0.430571 -0.2190735 0.0014100 0.000335 -0.000057 0.000050 0.000050 0.0000083 0.0000238 0.000031 0.000017 2014 4 13 56760 0.054917 0.430856 -0.2205121 0.0014564 0.000324 -0.000073 0.000050 0.000050 0.0000131 0.0000237 0.000031 0.000017 2014 4 14 56761 0.055763 0.431160 -0.2219651 0.0014828 0.000313 -0.000088 0.000050 0.000050 0.0000105 0.0000237 0.000032 0.000018 2014 4 15 56762 0.056648 0.432092 -0.2233979 0.0013962 0.000302 -0.000104 0.000050 0.000050 0.0000049 0.0000236 0.000032 0.000018 2014 4 16 56763 0.057283 0.432755 -0.2247224 0.0012634 0.000198 -0.000131 0.000050 0.000050 0.0000045 0.0000236 0.000033 0.000019 2014 4 17 56764 0.058233 0.433316 -0.2259735 0.0011786 0.000185 -0.000141 0.000050 0.000050 0.0000114 0.0000236 0.000033 0.000019 2014 4 18 56765 0.059547 0.434438 -0.2271611 0.0012207 0.000216 -0.000142 0.000050 0.000050 0.0000205 0.0000236 0.000033 0.000020 2014 4 19 56766 0.060235 0.435938 -0.2283262 0.0012048 0.000247 -0.000144 0.000049 0.000049 0.0000224 0.0000237 0.000034 0.000020 2014 4 20 56767 0.060944 0.436953 -0.2295574 0.0012852 0.000278 -0.000146 0.000049 0.000049 0.0000148 0.0000237 0.000034 0.000021 2014 4 21 56768 0.062152 0.437984 -0.2308630 0.0013677 0.000309 -0.000147 0.000049 0.000049 0.0000130 0.0000236 0.000034 0.000021 2014 4 22 56769 0.063753 0.438706 -0.2322999 0.0015262 0.000340 -0.000149 0.000049 0.000049 0.0000097 0.0000236 0.000035 0.000022 2014 4 23 56770 0.065273 0.439403 -0.2338988 0.0016696 0.000370 -0.000150 0.000049 0.000049 0.0000064 0.0000236 0.000035 0.000022 2014 4 24 56771 0.066868 0.439919 -0.2356298 0.0017856 0.000421 -0.000193 0.000049 0.000049 0.0000053 0.0000236 0.000035 0.000023 2014 4 25 56772 0.068557 0.440457 -0.2374814 0.0019238 0.000283 -0.000099 0.000049 0.000049 0.0000049 0.0000235 0.000035 0.000023 2014 4 26 56773 0.070301 0.441033 -0.2394680 0.0020142 0.000232 -0.000068 0.000049 0.000049 0.0000123 0.0000235 0.000035 0.000023 2014 4 27 56774 0.071794 0.441789 -0.2414444 0.0019416 0.000238 -0.000080 0.000049 0.000049 0.0000185 0.0000234 0.000035 0.000023 2014 4 28 56775 0.072950 0.442413 -0.2433097 0.0017730 0.000243 -0.000091 0.000049 0.000049 0.0000137 0.0000233 0.000035 0.000023 2014 4 29 56776 0.074283 0.442691 -0.2450254 0.0015938 0.000249 -0.000102 0.000049 0.000049 0.0000046 0.0000232 0.000035 0.000023 2014 4 30 56777 0.076090 0.442797 -0.2465423 0.0014226 0.000306 -0.000104 0.000049 0.000049 0.0000033 0.0000231 0.000034 0.000023 2014 5 1 56778 0.077991 0.443171 -0.2478612 0.0012415 0.000427 -0.000091 0.000049 0.000049 0.0000095 0.0000231 0.000034 0.000023 2014 5 2 56779 0.079707 0.443594 -0.2490457 0.0011000 0.000526 -0.000080 0.000049 0.000049 0.0000177 0.0000230 0.000034 0.000023 2014 5 3 56780 0.081701 0.444023 -0.2501393 0.0010920 0.000474 -0.000090 0.000049 0.000049 0.0000217 0.0000229 0.000033 0.000022 2014 5 4 56781 0.083839 0.444603 -0.2512148 0.0011010 0.000422 -0.000099 0.000049 0.000049 0.0000176 0.0000229 0.000033 0.000022 2014 5 5 56782 0.085302 0.444896 -0.2523558 0.0011384 0.000369 -0.000109 0.000049 0.000048 0.0000142 0.0000228 0.000032 0.000021 2014 5 6 56783 0.086169 0.445015 -0.2535595 0.0012071 0.000317 -0.000118 0.000049 0.000048 0.0000178 0.0000228 0.000032 0.000021 2014 5 7 56784 0.087354 0.445500 -0.2548236 0.0012801 0.000241 -0.000119 0.000049 0.000048 0.0000265 0.0000227 0.000031 0.000021 2014 5 8 56785 0.088953 0.446179 -0.2561154 0.0013765 0.000177 -0.000127 0.000049 0.000048 0.0000138 0.0000227 0.000031 0.000020 2014 5 9 56786 0.090410 0.446838 -0.2575214 0.0014356 0.000149 -0.000149 0.000049 0.000048 0.0000143 0.0000227 0.000031 0.000020 2014 5 10 56787 0.091448 0.446928 -0.2589579 0.0014455 0.000162 -0.000159 0.000049 0.000048 0.0000194 0.0000226 0.000031 0.000020 2014 5 11 56788 0.093022 0.446752 -0.2604021 0.0014303 0.000174 -0.000189 0.000049 0.000048 0.0000239 0.0000226 0.000031 0.000020 2014 5 12 56789 0.095388 0.446663 -0.2618058 0.0013703 0.000183 -0.000231 0.000049 0.000048 0.0000214 0.0000226 0.000031 0.000020 2014 5 13 56790 0.097793 0.447033 -0.2631278 0.0012425 0.000172 -0.000224 0.000049 0.000048 0.0000197 0.0000226 0.000031 0.000020 2014 5 14 56791 0.099835 0.447593 -0.2643018 0.0011465 0.000159 -0.000218 0.000049 0.000048 0.0000143 0.0000225 0.000031 0.000020 2014 5 15 56792 0.101380 0.447965 -0.2654058 0.0010614 0.000152 -0.000217 0.000049 0.000048 0.0000205 0.0000225 0.000032 0.000020 2014 5 16 56793 0.102773 0.448091 -0.2664370 0.0010122 0.000145 -0.000224 0.000049 0.000048 0.0000112 0.0000225 0.000032 0.000020 2014 5 17 56794 0.103974 0.448095 -0.2674275 0.0010074 0.000153 -0.000250 0.000049 0.000048 0.0000214 0.0000225 0.000032 0.000020 2014 5 18 56795 0.104886 0.448053 -0.2684662 0.0010721 0.000160 -0.000272 0.000049 0.000048 0.0000237 0.0000225 0.000033 0.000020 2014 5 19 56796 0.105789 0.447827 -0.2696226 0.0011993 0.000163 -0.000258 0.000049 0.000048 0.0000173 0.0000225 0.000033 0.000021 2014 5 20 56797 0.107192 0.447596 -0.2708936 0.0013561 0.000155 -0.000224 0.000049 0.000048 0.0000155 0.0000225 0.000034 0.000021 2014 5 21 56798 0.108971 0.447681 -0.2722819 0.0014540 0.000154 -0.000195 0.000049 0.000048 0.0000266 0.0000225 0.000035 0.000022 2014 5 22 56799 0.110876 0.448090 -0.2737383 0.0014685 0.000171 -0.000193 0.000049 0.000048 0.0000176 0.0000225 0.000035 0.000023 2014 5 23 56800 0.112186 0.448320 -0.2752160 0.0014057 0.000198 -0.000224 0.000049 0.000048 0.0000085 0.0000225 0.000036 0.000023 2014 5 24 56801 0.113624 0.448153 -0.2766438 0.0013568 0.000222 -0.000230 0.000049 0.000048 0.0000255 0.0000225 0.000037 0.000024 2014 5 25 56802 0.115166 0.447752 -0.2779093 0.0011844 0.000244 -0.000223 0.000049 0.000048 0.0000228 0.0000224 0.000037 0.000025 2014 5 26 56803 0.116676 0.447032 -0.2790022 0.0010353 0.000267 -0.000216 0.000049 0.000048 0.0000188 0.0000224 0.000038 0.000025 2014 5 27 56804 0.117995 0.446337 -0.2799498 0.0008506 0.000274 -0.000206 0.000049 0.000048 0.0000138 0.0000224 0.000038 0.000026 2014 5 28 56805 0.120028 0.445450 -0.2807300 0.0006934 0.000226 -0.000181 0.000049 0.000048 0.0000055 0.0000223 0.000039 0.000026 2014 5 29 56806 0.122722 0.444989 -0.2813422 0.0005765 0.000269 -0.000186 0.000049 0.000048 0.0000052 0.0000223 0.000039 0.000026 2014 5 30 56807 0.125448 0.444196 -0.2818370 0.0004270 0.000336 -0.000199 0.000049 0.000048 0.0000069 0.0000223 0.000039 0.000027 2014 5 31 56808 0.127792 0.443582 -0.2822336 0.0003875 0.000340 -0.000202 0.000049 0.000048 0.0000178 0.0000222 0.000040 0.000027 2014 6 1 56809 0.129432 0.442969 -0.2826206 0.0003861 0.000320 -0.000202 0.000049 0.000048 0.0000254 0.0000222 0.000040 0.000027 2014 6 2 56810 0.130659 0.441989 -0.2830270 0.0004316 0.000300 -0.000201 0.000049 0.000048 0.0000179 0.0000221 0.000040 0.000027 2014 6 3 56811 0.131623 0.440971 -0.2834733 0.0004573 0.000280 -0.000201 0.000049 0.000048 0.0000047 0.0000221 0.000040 0.000028 2014 6 4 56812 0.132920 0.439732 -0.2839887 0.0005776 0.000156 -0.000243 0.000049 0.000048 0.0000030 0.0000220 0.000041 0.000028 2014 6 5 56813 0.134409 0.438871 -0.2845746 0.0006242 0.000050 -0.000285 0.000049 0.000049 0.0000042 0.0000219 0.000041 0.000029 2014 6 6 56814 0.136298 0.437899 -0.2852241 0.0006883 0.000112 -0.000285 0.000049 0.000049 0.0000055 0.0000219 0.000042 0.000029 2014 6 7 56815 0.138445 0.437426 -0.2859356 0.0007217 0.000140 -0.000278 0.000049 0.000049 0.0000141 0.0000218 0.000042 0.000030 2014 6 8 56816 0.140269 0.436641 -0.2866940 0.0007559 0.000155 -0.000269 0.000049 0.000049 0.0000229 0.0000218 0.000042 0.000030 2014 6 9 56817 0.142155 0.435910 -0.2874275 0.0007266 0.000170 -0.000260 0.000049 0.000049 0.0000207 0.0000217 0.000043 0.000030 2014 6 10 56818 0.143882 0.435310 -0.2881208 0.0006863 0.000186 -0.000251 0.000049 0.000049 0.0000135 0.0000217 0.000043 0.000031 2014 6 11 56819 0.145712 0.434788 -0.2887730 0.0006755 0.000201 -0.000242 0.000049 0.000049 0.0000063 0.0000216 0.000044 0.000031 2014 6 12 56820 0.147454 0.434331 -0.2894124 0.0006469 0.000176 -0.000252 0.000049 0.000049 0.0000057 0.0000216 0.000044 0.000032 2014 6 13 56821 0.149072 0.433571 -0.2900425 0.0006355 0.000167 -0.000258 0.000049 0.000049 0.0000067 0.0000216 0.000044 0.000032 2014 6 14 56822 0.150687 0.432747 -0.2906768 0.0006830 0.000157 -0.000252 0.000049 0.000049 0.0000182 0.0000215 0.000044 0.000032 2014 6 15 56823 0.152467 0.431594 -0.2914131 0.0007749 0.000143 -0.000242 0.000049 0.000049 0.0000203 0.0000215 0.000044 0.000032 2014 6 16 56824 0.154205 0.430675 -0.2922623 0.0008931 0.000129 -0.000232 0.000049 0.000049 0.0000152 0.0000215 0.000044 0.000031 2014 6 17 56825 0.155906 0.430018 -0.2932489 0.0010498 0.000115 -0.000221 0.000049 0.000049 0.0000103 0.0000215 0.000044 0.000031 2014 6 18 56826 0.157273 0.429526 -0.2943594 0.0011388 0.000102 -0.000211 0.000049 0.000049 0.0000062 0.0000214 0.000044 0.000031 2014 6 19 56827 0.158483 0.428948 -0.2955342 0.0011750 0.000098 -0.000230 0.000049 0.000048 0.0000055 0.0000214 0.000043 0.000031 2014 6 20 56828 0.159844 0.428208 -0.2966861 0.0011245 0.000097 -0.000256 0.000049 0.000048 0.0000058 0.0000214 0.000043 0.000031 2014 6 21 56829 0.160902 0.427331 -0.2977375 0.0009952 0.000101 -0.000256 0.000049 0.000048 0.0000187 0.0000214 0.000043 0.000031 2014 6 22 56830 0.161798 0.426296 -0.2986676 0.0008271 0.000106 -0.000247 0.000049 0.000048 0.0000204 0.0000214 0.000043 0.000031 2014 6 23 56831 0.163185 0.425165 -0.2994180 0.0006524 0.000112 -0.000237 0.000049 0.000048 0.0000127 0.0000214 0.000042 0.000030 2014 6 24 56832 0.164706 0.423924 -0.2999887 0.0005008 0.000117 -0.000228 0.000049 0.000048 0.0000042 0.0000215 0.000042 0.000030 2014 6 25 56833 0.166035 0.422622 -0.3004161 0.0003708 0.000102 -0.000202 0.000049 0.000048 0.0000146 0.0000215 0.000042 0.000030 2014 6 26 56834 0.166814 0.421486 -0.3007143 0.0002363 0.000143 -0.000227 0.000049 0.000048 0.0000234 0.0000215 0.000042 0.000031 2014 6 27 56835 0.167410 0.420250 -0.3008726 0.0001369 0.000108 -0.000400 0.000049 0.000048 0.0000077 0.0000215 0.000043 0.000031 2014 6 28 56836 0.168082 0.419125 -0.3010385 0.0001574 0.000127 -0.000426 0.000049 0.000048 0.0000326 0.0000216 0.000044 0.000032 2014 6 29 56837 0.168840 0.417887 -0.3013155 0.0002359 0.000177 -0.000382 0.000049 0.000048 0.0000465 0.0000216 0.000044 0.000032 2014 6 30 56838 0.169594 0.416506 -0.3015851 0.0003267 0.000228 -0.000337 0.000049 0.000048 0.0000318 0.0000216 0.000045 0.000032 2014 7 1 56839 0.170517 0.414989 -0.3018654 0.0003603 0.000279 -0.000292 0.000049 0.000048 0.0000093 0.0000217 0.000046 0.000033 2014 7 2 56840 0.171839 0.413813 -0.3022527 0.0004170 0.000236 -0.000304 0.000049 0.000049 0.0000049 0.0000217 0.000047 0.000033 2014 7 3 56841 0.173207 0.412782 -0.3027059 0.0004943 0.000170 -0.000331 0.000049 0.000049 0.0000052 0.0000217 0.000048 0.000034 2014 7 4 56842 0.174537 0.411740 -0.3032096 0.0005533 0.000046 -0.000343 0.000049 0.000049 0.0000232 0.0000218 0.000049 0.000034 2014 7 5 56843 0.175544 0.410980 -0.3037341 0.0005303 0.000019 -0.000342 0.000049 0.000049 0.0000478 0.0000218 0.000050 0.000035 2014 7 6 56844 0.176331 0.409901 -0.3042797 0.0004511 0.000040 -0.000337 0.000049 0.000049 0.0000377 0.0000218 0.000051 0.000035 2014 7 7 56845 0.176963 0.408784 -0.3047156 0.0003724 0.000061 -0.000333 0.000049 0.000049 0.0000204 0.0000218 0.000052 0.000036 2014 7 8 56846 0.177568 0.407721 -0.3050576 0.0003203 0.000082 -0.000329 0.000049 0.000048 0.0000080 0.0000219 0.000053 0.000036 2014 7 9 56847 0.178334 0.406816 -0.3053481 0.0002874 0.000204 -0.000266 0.000049 0.000048 0.0000165 0.0000219 0.000054 0.000037 2014 7 10 56848 0.179003 0.405922 -0.3056221 0.0002785 0.000353 -0.000188 0.000049 0.000048 0.0000243 0.0000220 0.000054 0.000037 2014 7 11 56849 0.179999 0.404805 -0.3059680 0.0003485 0.000242 -0.000231 0.000049 0.000048 0.0000083 0.0000220 0.000055 0.000037 2014 7 12 56850 0.181095 0.403719 -0.3063918 0.0004342 0.000141 -0.000321 0.000049 0.000048 0.0000420 0.0000220 0.000056 0.000037 2014 7 13 56851 0.181992 0.402777 -0.3069513 0.0006071 0.000138 -0.000356 0.000049 0.000048 0.0000530 0.0000221 0.000057 0.000038 2014 7 14 56852 0.182710 0.401754 -0.3076598 0.0007955 0.000156 -0.000337 0.000049 0.000048 0.0000336 0.0000221 0.000057 0.000038 2014 7 15 56853 0.183128 0.400753 -0.3085064 0.0008930 0.000132 -0.000319 0.000049 0.000048 0.0000092 0.0000222 0.000058 0.000039 2014 7 16 56854 0.183572 0.399306 -0.3094238 0.0009350 0.000090 -0.000322 0.000049 0.000048 0.0000051 0.0000222 0.000059 0.000039 2014 7 17 56855 0.184004 0.397938 -0.3103375 0.0008810 0.000057 -0.000323 0.000049 0.000048 0.0000062 0.0000222 0.000059 0.000040 2014 7 18 56856 0.184324 0.396284 -0.3111677 0.0007486 0.000081 -0.000291 0.000049 0.000048 0.0000074 0.0000222 0.000060 0.000040 2014 7 19 56857 0.185282 0.394576 -0.3119354 0.0006159 0.000014 -0.000325 0.000049 0.000048 0.0000263 0.0000222 0.000060 0.000040 2014 7 20 56858 0.186442 0.393167 -0.3124358 0.0004702 0.000013 -0.000327 0.000049 0.000048 0.0000358 0.0000223 0.000060 0.000040 2014 7 21 56859 0.187768 0.391877 -0.3127697 0.0003040 0.000074 -0.000309 0.000049 0.000049 0.0000251 0.0000223 0.000061 0.000040 2014 7 22 56860 0.188776 0.391088 -0.3129932 0.0001590 0.000101 -0.000327 0.000049 0.000049 0.0000082 0.0000223 0.000061 0.000040 2014 7 23 56861 0.189330 0.390086 -0.3130876 0.0000636 0.000123 -0.000333 0.000049 0.000049 0.0000132 0.0000223 0.000061 0.000040 2014 7 24 56862 0.189604 0.389317 -0.3131198 0.0000276 0.000144 -0.000336 0.000049 0.000049 0.0000192 0.0000223 0.000061 0.000040 2014 7 25 56863 0.189957 0.388196 -0.3131499 0.0000425 0.000164 -0.000340 0.000049 0.000049 0.0000068 0.0000223 0.000062 0.000040 2014 7 26 56864 0.190306 0.387104 -0.3131883 0.0000340 0.000160 -0.000334 0.000049 0.000049 0.0000177 0.0000223 0.000062 0.000040 2014 7 27 56865 0.190886 0.385974 -0.3132543 0.0000811 0.000146 -0.000324 0.000049 0.000049 0.0000249 0.0000223 0.000062 0.000040 2014 7 28 56866 0.191948 0.384988 -0.3134156 0.0001978 0.000132 -0.000315 0.000049 0.000049 0.0000172 0.0000223 0.000063 0.000040 2014 7 29 56867 0.193134 0.384040 -0.3136677 0.0003117 0.000118 -0.000305 0.000049 0.000049 0.0000050 0.0000223 0.000063 0.000040 2014 7 30 56868 0.194129 0.382977 -0.3140392 0.0004155 0.000090 -0.000310 0.000049 0.000049 0.0000111 0.0000223 0.000063 0.000040 2014 7 31 56869 0.194675 0.381798 -0.3144689 0.0004358 0.000057 -0.000318 0.000049 0.000049 0.0000174 0.0000223 0.000063 0.000040 2014 8 1 56870 0.195457 0.380267 -0.3149162 0.0004283 0.000025 -0.000326 0.000049 0.000049 0.0000064 0.0000223 0.000063 0.000040 2014 8 2 56871 0.196024 0.379105 -0.3153203 0.0003568 0.000015 -0.000350 0.000049 0.000048 0.0000221 0.0000223 0.000063 0.000040 2014 8 3 56872 0.196578 0.377704 -0.3156533 0.0002954 0.000014 -0.000381 0.000049 0.000048 0.0000457 0.0000222 0.000063 0.000040 2014 8 4 56873 0.197529 0.376172 -0.3159233 0.0002374 0.000012 -0.000411 0.000049 0.000048 0.0000330 0.0000222 0.000064 0.000040 2014 8 5 56874 0.198517 0.374548 -0.3161174 0.0001793 0.000011 -0.000441 0.000049 0.000048 0.0000204 0.0000222 0.000064 0.000040 2014 8 6 56875 0.199814 0.373207 -0.3162285 0.0001111 0.000000 -0.000411 0.000049 0.000048 0.0000278 0.0000221 0.000064 0.000040 2014 8 7 56876 0.201138 0.372224 -0.3162780 0.0000630 -0.000011 -0.000364 0.000049 0.000048 0.0000300 0.0000221 0.000064 0.000040 2014 8 8 56877 0.202110 0.371260 -0.3164044 0.0001574 -0.000011 -0.000313 0.000049 0.000048 0.0000125 0.0000221 0.000064 0.000041 2014 8 9 56878 0.203072 0.370155 -0.3166652 0.0003472 0.000008 -0.000215 0.000049 0.000048 0.0000323 0.0000220 0.000064 0.000041 2014 8 10 56879 0.204233 0.369115 -0.3170624 0.0004935 0.000042 -0.000079 0.000049 0.000048 0.0000379 0.0000220 0.000064 0.000041 2014 8 11 56880 0.205434 0.368324 -0.3176562 0.0006577 0.000069 -0.000081 0.000049 0.000048 0.0000269 0.0000219 0.000063 0.000041 2014 8 12 56881 0.206552 0.367630 -0.3183974 0.0007707 0.000080 -0.000246 0.000049 0.000048 0.0000305 0.0000219 0.000063 0.000041 2014 8 13 56882 0.207344 0.366930 -0.3192193 0.0008367 0.000039 -0.000255 0.000049 0.000048 0.0000360 0.0000218 0.000063 0.000041 2014 8 14 56883 0.207916 0.366107 -0.3200515 0.0008272 -0.000014 -0.000226 0.000049 0.000048 0.0000222 0.0000218 0.000062 0.000041 2014 8 15 56884 0.208768 0.364934 -0.3207972 0.0006988 -0.000067 -0.000197 0.000049 0.000048 0.0000084 0.0000218 0.000062 0.000041 2014 8 16 56885 0.209644 0.363552 -0.3214559 0.0005775 -0.000118 -0.000122 0.000049 0.000048 0.0000198 0.0000218 0.000062 0.000041 2014 8 17 56886 0.210184 0.362144 -0.3219576 0.0004673 -0.000117 -0.000157 0.000049 0.000048 0.0000203 0.0000218 0.000061 0.000041 2014 8 18 56887 0.210356 0.360801 -0.3223541 0.0003839 -0.000046 -0.000267 0.000049 0.000048 0.0000123 0.0000219 0.000061 0.000041 2014 8 19 56888 0.209991 0.359346 -0.3226677 0.0002631 0.000044 -0.000326 0.000049 0.000048 0.0000049 0.0000219 0.000061 0.000041 2014 8 20 56889 0.209665 0.357813 -0.3228809 0.0002015 0.000072 -0.000249 0.000049 0.000048 0.0000168 0.0000219 0.000061 0.000041 2014 8 21 56890 0.209518 0.356180 -0.3230539 0.0001729 0.000085 -0.000138 0.000049 0.000048 0.0000268 0.0000219 0.000061 0.000042 2014 8 22 56891 0.209650 0.354452 -0.3232207 0.0001671 0.000025 -0.000200 0.000049 0.000048 0.0000104 0.0000219 0.000060 0.000042 2014 8 23 56892 0.209523 0.352597 -0.3234365 0.0002339 0.000004 -0.000232 0.000049 0.000048 0.0000245 0.0000219 0.000060 0.000042 2014 8 24 56893 0.209522 0.350709 -0.3236747 0.0002419 0.000007 -0.000233 0.000049 0.000048 0.0000393 0.0000219 0.000059 0.000041 2014 8 25 56894 0.209484 0.348871 -0.3239175 0.0002575 0.000010 -0.000233 0.000049 0.000048 0.0000282 0.0000219 0.000059 0.000041 2014 8 26 56895 0.209253 0.347009 -0.3242071 0.0003412 0.000013 -0.000233 0.000049 0.000048 0.0000067 0.0000218 0.000058 0.000041 2014 8 27 56896 0.209076 0.345043 -0.3246118 0.0004376 0.000113 -0.000237 0.000049 0.000048 0.0000104 0.0000218 0.000058 0.000041 2014 8 28 56897 0.208912 0.342820 -0.3250768 0.0004746 0.000115 -0.000217 0.000049 0.000048 0.0000170 0.0000219 0.000058 0.000041 2014 8 29 56898 0.209008 0.340884 -0.3255682 0.0004909 0.000082 -0.000190 0.000049 0.000048 0.0000098 0.0000219 0.000058 0.000041 2014 8 30 56899 0.209416 0.339468 -0.3260948 0.0004949 0.000006 -0.000189 0.000049 0.000048 0.0000240 0.0000219 0.000058 0.000041 2014 8 31 56900 0.209545 0.338267 -0.3265890 0.0004942 -0.000064 -0.000175 0.000049 0.000048 0.0000230 0.0000219 0.000058 0.000041 2014 9 1 56901 0.209595 0.336935 -0.3270994 0.0005483 -0.000099 -0.000202 0.000049 0.000048 0.0000150 0.0000219 0.000057 0.000040 2014 9 2 56902 0.209626 0.335285 -0.3276173 0.0005216 -0.000117 -0.000293 0.000049 0.000049 0.0000092 0.0000219 0.000057 0.000040 2014 9 3 56903 0.209207 0.333429 -0.3281375 0.0005158 -0.000025 -0.000372 0.000049 0.000049 0.0000033 0.0000219 0.000056 0.000039 2014 9 4 56904 0.208955 0.331540 -0.3286670 0.0005516 -0.000003 -0.000351 0.000049 0.000049 0.0000031 0.0000219 0.000056 0.000039 2014 9 5 56905 0.209032 0.329830 -0.3292852 0.0006789 -0.000044 -0.000389 0.000049 0.000049 0.0000043 0.0000218 0.000057 0.000039 2014 9 6 56906 0.209219 0.328282 -0.3300561 0.0008398 -0.000088 -0.000377 0.000049 0.000049 0.0000246 0.0000218 0.000058 0.000040 2014 9 7 56907 0.209087 0.326947 -0.3309914 0.0010232 -0.000126 -0.000337 0.000049 0.000049 0.0000299 0.0000218 0.000058 0.000040 2014 9 8 56908 0.208577 0.325706 -0.3321224 0.0011861 -0.000116 -0.000396 0.000049 0.000049 0.0000199 0.0000218 0.000059 0.000040 2014 9 9 56909 0.207970 0.324129 -0.3333936 0.0013372 -0.000102 -0.000464 0.000049 0.000049 0.0000079 0.0000218 0.000060 0.000041 2014 9 10 56910 0.207057 0.322201 -0.3346599 0.0012617 -0.000229 -0.000546 0.000049 0.000049 0.0000060 0.0000217 0.000061 0.000041 2014 9 11 56911 0.205694 0.319875 -0.3358564 0.0011358 -0.000388 -0.000627 0.000050 0.000049 0.0000067 0.0000217 0.000061 0.000042 2014 9 12 56912 0.204722 0.317446 -0.3369194 0.0009389 -0.000424 -0.000542 0.000050 0.000049 0.0000075 0.0000217 0.000062 0.000042 2014 9 13 56913 0.203675 0.315460 -0.3377903 0.0007620 -0.000282 -0.000432 0.000050 0.000049 0.0000248 0.0000217 0.000062 0.000042 2014 9 14 56914 0.203262 0.313648 -0.3385051 0.0006502 -0.000075 -0.000313 0.000050 0.000049 0.0000336 0.0000216 0.000063 0.000042 2014 9 15 56915 0.203044 0.312312 -0.3391232 0.0006127 -0.000090 -0.000273 0.000050 0.000049 0.0000236 0.0000216 0.000063 0.000042 2014 9 16 56916 0.202683 0.310879 -0.3396788 0.0006086 -0.000144 -0.000246 0.000050 0.000049 0.0000079 0.0000216 0.000063 0.000042 2014 9 17 56917 0.201948 0.309570 -0.3402897 0.0006063 -0.000150 -0.000250 0.000050 0.000049 0.0000134 0.0000216 0.000064 0.000042 2014 9 18 56918 0.201114 0.308136 -0.3409352 0.0006791 -0.000118 -0.000253 0.000050 0.000049 0.0000199 0.0000217 0.000064 0.000042 2014 9 19 56919 0.200440 0.306759 -0.3416136 0.0007166 -0.000042 -0.000242 0.000050 0.000049 0.0000091 0.0000217 0.000064 0.000042 2014 9 20 56920 0.199649 0.305017 -0.3423379 0.0007388 -0.000040 -0.000261 0.000050 0.000049 0.0000325 0.0000217 0.000064 0.000042 2014 9 21 56921 0.198822 0.303322 -0.3430967 0.0007746 -0.000066 -0.000289 0.000050 0.000049 0.0000314 0.0000218 0.000064 0.000042 2014 9 22 56922 0.198177 0.301495 -0.3439301 0.0008783 -0.000085 -0.000257 0.000050 0.000049 0.0000174 0.0000218 0.000064 0.000041 2014 9 23 56923 0.197695 0.299640 -0.3448281 0.0009292 -0.000104 -0.000225 0.000050 0.000049 0.0000062 0.0000218 0.000064 0.000041 2014 9 24 56924 0.196653 0.297948 -0.3457480 0.0009224 -0.000185 -0.000263 0.000050 0.000049 0.0000047 0.0000219 0.000064 0.000040 2014 9 25 56925 0.196227 0.296445 -0.3466688 0.0009403 -0.000246 -0.000298 0.000050 0.000049 0.0000057 0.0000219 0.000064 0.000040 2014 9 26 56926 0.195457 0.295357 -0.3475647 0.0008552 -0.000175 -0.000256 0.000050 0.000049 0.0000068 0.0000219 0.000064 0.000040 2014 9 27 56927 0.194278 0.294186 -0.3483902 0.0007900 -0.000119 -0.000241 0.000050 0.000049 0.0000221 0.0000219 0.000064 0.000040 2014 9 28 56928 0.193090 0.293164 -0.3491628 0.0007225 -0.000068 -0.000236 0.000050 0.000049 0.0000407 0.0000220 0.000064 0.000040 2014 9 29 56929 0.192102 0.291906 -0.3498846 0.0006901 -0.000018 -0.000231 0.000050 0.000049 0.0000321 0.0000220 0.000064 0.000040 2014 9 30 56930 0.190837 0.290467 -0.3505708 0.0007180 0.000033 -0.000225 0.000050 0.000049 0.0000104 0.0000221 0.000065 0.000041 2014 10 1 56931 0.189281 0.288878 -0.3512755 0.0007455 -0.000034 -0.000268 0.000050 0.000049 0.0000052 0.0000221 0.000065 0.000041 2014 10 2 56932 0.187923 0.287409 -0.3520497 0.0008348 -0.000096 -0.000242 0.000050 0.000049 0.0000043 0.0000221 0.000065 0.000041 2014 10 3 56933 0.186357 0.286375 -0.3529360 0.0009774 -0.000086 -0.000219 0.000050 0.000049 0.0000119 0.0000222 0.000065 0.000041 2014 10 4 56934 0.184573 0.285157 -0.3540107 0.0011675 -0.000054 -0.000206 0.000050 0.000049 0.0000227 0.0000222 0.000064 0.000041 2014 10 5 56935 0.182934 0.283964 -0.3553184 0.0013608 -0.000050 -0.000202 0.000050 0.000049 0.0000303 0.0000222 0.000064 0.000041 2014 10 6 56936 0.180736 0.282714 -0.3567588 0.0014912 -0.000107 -0.000247 0.000050 0.000049 0.0000240 0.0000222 0.000064 0.000041 2014 10 7 56937 0.178466 0.281171 -0.3582977 0.0015977 -0.000198 -0.000330 0.000050 0.000049 0.0000114 0.0000222 0.000064 0.000041 2014 10 8 56938 0.176371 0.279490 -0.3599127 0.0016026 -0.000202 -0.000363 0.000050 0.000049 0.0000226 0.0000222 0.000064 0.000041 2014 10 9 56939 0.174483 0.277962 -0.3614586 0.0014743 -0.000183 -0.000382 0.000050 0.000049 0.0000319 0.0000222 0.000064 0.000041 2014 10 10 56940 0.172103 0.276934 -0.3628154 0.0012636 -0.000118 -0.000270 0.000050 0.000049 0.0000096 0.0000222 0.000063 0.000040 2014 10 11 56941 0.169442 0.275719 -0.3639980 0.0011261 -0.000031 -0.000200 0.000050 0.000049 0.0000194 0.0000222 0.000063 0.000040 2014 10 12 56942 0.167003 0.274337 -0.3650957 0.0010552 -0.000004 -0.000158 0.000050 0.000049 0.0000331 0.0000222 0.000063 0.000040 2014 10 13 56943 0.164792 0.272933 -0.3660750 0.0009508 -0.000085 -0.000145 0.000050 0.000049 0.0000305 0.0000221 0.000062 0.000039 2014 10 14 56944 0.163125 0.271630 -0.3669794 0.0008888 -0.000212 -0.000165 0.000050 0.000049 0.0000632 0.0000221 0.000061 0.000039 2014 10 15 56945 0.161791 0.270650 -0.3678828 0.0009194 -0.000240 0.000055 0.000050 0.000049 0.0000880 0.0000221 0.000061 0.000038 2014 10 16 56946 0.160324 0.269618 -0.3688284 0.0009535 -0.000206 0.000012 0.000050 0.000049 0.0000248 0.0000221 0.000061 0.000038 2014 10 17 56947 0.158854 0.268431 -0.3697731 0.0009662 -0.000161 -0.000129 0.000050 0.000049 0.0000104 0.0000221 0.000062 0.000039 2014 10 18 56948 0.157609 0.267480 -0.3707763 0.0010576 -0.000164 -0.000200 0.000050 0.000049 0.0000118 0.0000220 0.000062 0.000039 2014 10 19 56949 0.156166 0.266450 -0.3718673 0.0011260 -0.000152 -0.000236 0.000050 0.000049 0.0000218 0.0000220 0.000063 0.000039 2014 10 20 56950 0.154882 0.265184 -0.3730523 0.0012088 -0.000108 -0.000266 0.000050 0.000049 0.0000177 0.0000220 0.000063 0.000039 2014 10 21 56951 0.153538 0.264166 -0.3742981 0.0013029 -0.000141 -0.000147 0.000050 0.000049 0.0000058 0.0000220 0.000063 0.000039 2014 10 22 56952 0.152544 0.263225 -0.3756384 0.0013749 -0.000151 -0.000184 0.000050 0.000049 0.0000068 0.0000219 0.000064 0.000040 2014 10 23 56953 0.151239 0.262643 -0.3769722 0.0013446 -0.000159 -0.000205 0.000050 0.000049 0.0000146 0.0000219 0.000065 0.000040 2014 10 24 56954 0.149410 0.261644 -0.3782630 0.0012606 -0.000170 -0.000201 0.000050 0.000049 0.0000237 0.0000219 0.000065 0.000040 2014 10 25 56955 0.147282 0.260354 -0.3794855 0.0011416 -0.000181 -0.000198 0.000050 0.000050 0.0000647 0.0000219 0.000066 0.000041 2014 10 26 56956 0.144735 0.259080 -0.3805842 0.0010407 -0.000193 -0.000195 0.000050 0.000050 0.0001692 0.0000219 0.000066 0.000041 2014 10 27 56957 0.142502 0.257796 -0.3816063 0.0009890 -0.000204 -0.000191 0.000050 0.000050 0.0001285 0.0000219 0.000067 0.000041 2014 10 28 56958 0.140629 0.257088 -0.3825955 0.0009880 -0.000215 -0.000188 0.000050 0.000050 0.0000296 0.0000219 0.000068 0.000041 2014 10 29 56959 0.138839 0.256769 -0.3836062 0.0010442 -0.000005 -0.000204 0.000050 0.000050 0.0000203 0.0000219 0.000068 0.000042 2014 10 30 56960 0.137045 0.256364 -0.3846781 0.0011223 -0.000013 -0.000207 0.000050 0.000050 0.0000283 0.0000218 0.000069 0.000042 2014 10 31 56961 0.134899 0.256104 -0.3858199 0.0011983 -0.000102 -0.000204 0.000050 0.000050 0.0000121 0.0000218 0.000069 0.000041 2014 11 1 56962 0.132510 0.255501 -0.3871542 0.0013920 -0.000255 -0.000135 0.000050 0.000050 0.0000119 0.0000218 0.000070 0.000041 2014 11 2 56963 0.130131 0.254642 -0.3886745 0.0016206 -0.000326 -0.000101 0.000050 0.000050 0.0000174 0.0000217 0.000070 0.000041 2014 11 3 56964 0.128037 0.253599 -0.3903258 0.0017047 -0.000272 -0.000122 0.000050 0.000050 0.0000141 0.0000217 0.000070 0.000041 2014 11 4 56965 0.126501 0.252992 -0.3920206 0.0016664 -0.000199 -0.000138 0.000050 0.000050 0.0000065 0.0000217 0.000070 0.000041 2014 11 5 56966 0.125128 0.253058 -0.3936623 0.0015902 -0.000126 -0.000170 0.000050 0.000050 0.0000192 0.0000216 0.000070 0.000041 2014 11 6 56967 0.123775 0.253108 -0.3951827 0.0014298 -0.000054 -0.000205 0.000050 0.000050 0.0000294 0.0000215 0.000070 0.000041 2014 11 7 56968 0.122213 0.252747 -0.3965300 0.0012717 -0.000130 -0.000116 0.000050 0.000050 0.0000094 0.0000214 0.000070 0.000041 2014 11 8 56969 0.120675 0.252135 -0.3977362 0.0011134 -0.000158 -0.000068 0.000050 0.000050 0.0000182 0.0000214 0.000071 0.000041 2014 11 9 56970 0.118672 0.251874 -0.3987622 0.0009707 -0.000150 -0.000049 0.000050 0.000050 0.0000352 0.0000213 0.000071 0.000041 2014 11 10 56971 0.116077 0.251414 -0.3996631 0.0008642 -0.000142 -0.000031 0.000050 0.000050 0.0000293 0.0000212 0.000072 0.000042 2014 11 11 56972 0.113418 0.251114 -0.4005145 0.0008320 -0.000134 -0.000013 0.000050 0.000050 0.0000126 0.0000212 0.000072 0.000042 2014 11 12 56973 0.111204 0.251036 -0.4013791 0.0008738 0.000009 -0.000049 0.000050 0.000050 0.0000129 0.0000211 0.000073 0.000043 2014 11 13 56974 0.109956 0.251239 -0.4022790 0.0009461 0.000045 -0.000074 0.000050 0.000050 0.0000145 0.0000211 0.000073 0.000043 2014 11 14 56975 0.109004 0.251506 -0.4032322 0.0009880 -0.000078 -0.000100 0.000050 0.000050 0.0000044 0.0000210 0.000073 0.000043 2014 11 15 56976 0.107378 0.251884 -0.4042393 0.0010350 -0.000222 -0.000133 0.000050 0.000050 0.0000160 0.0000210 0.000074 0.000043 2014 11 16 56977 0.105134 0.252139 -0.4053039 0.0010698 -0.000219 -0.000126 0.000050 0.000050 0.0000165 0.0000209 0.000074 0.000043 2014 11 17 56978 0.103088 0.252261 -0.4064685 0.0011902 -0.000147 -0.000118 0.000050 0.000050 0.0000107 0.0000209 0.000075 0.000044 2014 11 18 56979 0.101164 0.252945 -0.4076939 0.0012793 -0.000146 -0.000148 0.000050 0.000050 0.0000065 0.0000209 0.000076 0.000044 2014 11 19 56980 0.098786 0.253582 -0.4089339 0.0012494 -0.000088 -0.000152 0.000050 0.000050 0.0000050 0.0000208 0.000077 0.000045 2014 11 20 56981 0.096569 0.253797 -0.4101584 0.0011788 -0.000030 -0.000128 0.000050 0.000050 0.0000043 0.0000208 0.000078 0.000045 2014 11 21 56982 0.094763 0.254100 -0.4113394 0.0011212 -0.000052 -0.000096 0.000050 0.000050 0.0000035 0.0000207 0.000078 0.000046 2014 11 22 56983 0.092996 0.254389 -0.4124775 0.0010830 -0.000152 -0.000075 0.000050 0.000050 0.0000244 0.0000206 0.000079 0.000046 2014 11 23 56984 0.091010 0.254396 -0.4135328 0.0010276 -0.000164 -0.000073 0.000050 0.000050 0.0000250 0.0000206 0.000079 0.000047 2014 11 24 56985 0.089436 0.254044 -0.4145335 0.0009903 -0.000129 -0.000072 0.000050 0.000050 0.0000152 0.0000205 0.000080 0.000047 2014 11 25 56986 0.088520 0.253857 -0.4155285 0.0009859 -0.000158 -0.000059 0.000050 0.000050 0.0000072 0.0000204 0.000080 0.000047 2014 11 26 56987 0.087483 0.253994 -0.4165163 0.0010077 -0.000189 -0.000013 0.000050 0.000050 0.0000039 0.0000204 0.000081 0.000047 2014 11 27 56988 0.086929 0.254403 -0.4175848 0.0010868 -0.000176 -0.000181 0.000050 0.000050 0.0000107 0.0000203 0.000081 0.000047 2014 11 28 56989 0.086434 0.255298 -0.4187766 0.0012598 -0.000147 -0.000430 0.000050 0.000050 0.0000207 0.0000203 0.000081 0.000048 2014 11 29 56990 0.085125 0.256069 -0.4200917 0.0014277 -0.000219 -0.000298 0.000050 0.000050 0.0000307 0.0000202 0.000082 0.000048 2014 11 30 56991 0.083130 0.256693 -0.4215179 0.0014970 -0.000293 -0.000161 0.000050 0.000050 0.0000280 0.0000202 0.000082 0.000048 2014 12 1 56992 0.080966 0.257680 -0.4230049 0.0014804 -0.000281 -0.000066 0.000050 0.000050 0.0000184 0.0000201 0.000082 0.000048 2014 12 2 56993 0.078974 0.258800 -0.4244809 0.0014297 -0.000185 -0.000015 0.000050 0.000050 0.0000086 0.0000200 0.000082 0.000048 2014 12 3 56994 0.076865 0.259527 -0.4259088 0.0013722 -0.000226 -0.000018 0.000050 0.000050 0.0000058 0.0000199 0.000083 0.000049 2014 12 4 56995 0.074702 0.259938 -0.4272337 0.0012983 -0.000303 -0.000035 0.000050 0.000050 0.0000048 0.0000199 0.000083 0.000049 2014 12 5 56996 0.073004 0.260085 -0.4284372 0.0011664 -0.000249 -0.000051 0.000050 0.000050 0.0000037 0.0000198 0.000084 0.000050 2014 12 6 56997 0.072013 0.260898 -0.4295162 0.0010364 -0.000137 -0.000167 0.000050 0.000050 0.0000166 0.0000197 0.000085 0.000051 2014 12 7 56998 0.070768 0.261979 -0.4304906 0.0009505 0.000065 -0.000216 0.000050 0.000050 0.0000176 0.0000196 0.000086 0.000051 2014 12 8 56999 0.069509 0.262609 -0.4314549 0.0009562 0.000149 -0.000154 0.000050 0.000050 0.0000136 0.0000195 0.000087 0.000052 2014 12 9 57000 0.067620 0.263634 -0.4324454 0.0010040 0.000031 -0.000086 0.000051 0.000050 0.0000108 0.0000195 0.000088 0.000053 2014 12 10 57001 0.065125 0.264334 -0.4334766 0.0010626 -0.000087 -0.000018 0.000051 0.000050 0.0000078 0.0000194 0.000089 0.000054 2014 12 11 57002 0.062785 0.265099 -0.4345643 0.0011111 -0.000103 -0.000015 0.000051 0.000050 0.0000065 0.0000193 0.000089 0.000054 2014 12 12 57003 0.060531 0.266098 -0.4357170 0.0011981 -0.000236 -0.000097 0.000051 0.000050 0.0000057 0.0000192 0.000090 0.000055 2014 12 13 57004 0.058291 0.267349 -0.4369258 0.0012503 -0.000488 -0.000146 0.000051 0.000050 0.0000154 0.0000191 0.000090 0.000055 2014 12 14 57005 0.055689 0.268371 -0.4381561 0.0012203 -0.000657 -0.000057 0.000051 0.000050 0.0000230 0.0000191 0.000090 0.000055 2014 12 15 57006 0.052981 0.269414 -0.4394119 0.0012059 -0.000522 0.000091 0.000051 0.000050 0.0000195 0.0000190 0.000091 0.000055 2014 12 16 57007 0.050204 0.270689 -0.4406732 0.0012979 -0.000191 0.000178 0.000051 0.000050 0.0000118 0.0000189 0.000091 0.000055 2014 12 17 57008 0.047309 0.271783 -0.4419626 0.0013046 -0.000178 0.000109 0.000051 0.000050 0.0000138 0.0000189 0.000091 0.000055 2014 12 18 57009 0.044749 0.272214 -0.4432143 0.0012038 -0.000247 0.000000 0.000051 0.000050 0.0000164 0.0000189 0.000091 0.000055 2014 12 19 57010 0.043326 0.272558 -0.4443922 0.0011412 -0.000224 -0.000046 0.000051 0.000050 0.0000118 0.0000189 0.000090 0.000055 2014 12 20 57011 0.042125 0.273351 -0.4454795 0.0010073 -0.000117 0.000048 0.000051 0.000050 0.0000121 0.0000190 0.000090 0.000055 2014 12 21 57012 0.040801 0.273639 -0.4464599 0.0009414 0.000012 0.000188 0.000051 0.000050 0.0000195 0.0000191 0.000090 0.000055 2014 12 22 57013 0.039547 0.274006 -0.4473938 0.0009210 -0.000069 0.000146 0.000051 0.000050 0.0000168 0.0000191 0.000089 0.000054 2014 12 23 57014 0.038609 0.274229 -0.4483571 0.0009864 -0.000199 0.000000 0.000051 0.000050 0.0000077 0.0000192 0.000089 0.000053 2014 12 24 57015 0.037843 0.274933 -0.4494026 0.0010938 -0.000272 0.000021 0.000051 0.000050 0.0000060 0.0000193 0.000088 0.000053 2014 12 25 57016 0.037160 0.275556 -0.4506018 0.0012906 -0.000271 0.000037 0.000051 0.000050 0.0000094 0.0000194 0.000088 0.000053 2014 12 26 57017 0.036174 0.276368 -0.4519395 0.0013915 -0.000247 0.000034 0.000051 0.000050 0.0000139 0.0000195 0.000088 0.000053 2014 12 27 57018 0.035201 0.276925 -0.4533686 0.0014638 -0.000224 0.000032 0.000051 0.000050 0.0000184 0.0000195 0.000088 0.000053 2014 12 28 57019 0.034631 0.277763 -0.4548790 0.0015300 -0.000201 0.000029 0.000051 0.000050 0.0000226 0.0000196 0.000088 0.000054 2014 12 29 57020 0.034265 0.278674 -0.4563538 0.0014279 -0.000177 0.000027 0.000051 0.000050 0.0000181 0.0000197 0.000088 0.000054 2014 12 30 57021 0.033568 0.279581 -0.4577153 0.0012587 -0.000154 0.000025 0.000051 0.000050 0.0000093 0.0000198 0.000087 0.000055 2014 12 31 57022 0.032223 0.280408 -0.4589078 0.0011173 -0.000097 -0.000014 0.000051 0.000050 0.0000110 0.0000199 0.000087 0.000055 2015 1 1 57023 0.030695 0.280799 -0.4599543 0.0009615 -0.000101 0.000013 0.000048 0.000054 0.0000339 0.0000091 0.000045 0.000045 2015 1 2 57024 0.029535 0.281258 -0.4608547 0.0008648 -0.000133 0.000046 0.000048 0.000054 0.0000682 0.0000091 0.000045 0.000045 2015 1 3 57025 0.028852 0.281599 -0.4616403 0.0007718 -0.000165 0.000080 0.000048 0.000054 0.0000718 0.0000091 0.000045 0.000045 2015 1 4 57026 0.028659 0.282071 -0.4623373 0.0006626 -0.000196 0.000113 0.000048 0.000054 0.0000313 0.0000091 0.000044 0.000045 2015 1 5 57027 0.028436 0.282762 -0.4629963 0.0006474 -0.000228 0.000147 0.000049 0.000054 0.0000229 0.0000092 0.000044 0.000045 2015 1 6 57028 0.027941 0.283523 -0.4636581 0.0006354 -0.000260 0.000181 0.000049 0.000054 0.0000154 0.0000092 0.000044 0.000045 2015 1 7 57029 0.027106 0.284514 -0.4643704 0.0006989 -0.000184 0.000162 0.000049 0.000054 0.0000131 0.0000092 0.000044 0.000044 2015 1 8 57030 0.025808 0.285522 -0.4651583 0.0008336 -0.000080 0.000129 0.000049 0.000054 0.0000123 0.0000092 0.000043 0.000044 2015 1 9 57031 0.024562 0.286030 -0.4660317 0.0009939 0.000025 0.000097 0.000049 0.000054 0.0000114 0.0000092 0.000043 0.000044 2015 1 10 57032 0.023502 0.286657 -0.4670556 0.0011003 -0.000006 0.000094 0.000050 0.000054 0.0000237 0.0000093 0.000043 0.000044 2015 1 11 57033 0.022549 0.287832 -0.4681815 0.0011057 -0.000058 0.000076 0.000050 0.000054 0.0000308 0.0000093 0.000042 0.000043 2015 1 12 57034 0.021527 0.288833 -0.4692885 0.0011079 -0.000099 0.000047 0.000050 0.000054 0.0000198 0.0000093 0.000042 0.000043 2015 1 13 57035 0.020409 0.289837 -0.4704035 0.0011142 -0.000140 0.000018 0.000050 0.000054 0.0000080 0.0000093 0.000041 0.000042 2015 1 14 57036 0.018915 0.290855 -0.4715393 0.0011430 -0.000181 -0.000011 0.000050 0.000054 0.0000024 0.0000093 0.000041 0.000042 2015 1 15 57037 0.017149 0.292205 -0.4726793 0.0011212 -0.000181 0.000050 0.000051 0.000054 0.0000033 0.0000093 0.000041 0.000041 2015 1 16 57038 0.015043 0.293679 -0.4737919 0.0011303 -0.000173 0.000114 0.000051 0.000054 0.0000058 0.0000093 0.000041 0.000041 2015 1 17 57039 0.012945 0.294570 -0.4748877 0.0010957 -0.000162 0.000246 0.000051 0.000054 0.0000163 0.0000094 0.000040 0.000041 2015 1 18 57040 0.010735 0.295317 -0.4759595 0.0010653 -0.000086 0.000315 0.000051 0.000054 0.0000212 0.0000094 0.000040 0.000041 2015 1 19 57041 0.009200 0.296111 -0.4770233 0.0010936 -0.000013 0.000212 0.000051 0.000054 0.0000135 0.0000094 0.000040 0.000041 2015 1 20 57042 0.008071 0.296847 -0.4781495 0.0011695 -0.000005 0.000025 0.000051 0.000054 0.0000469 0.0000094 0.000040 0.000040 2015 1 21 57043 0.007336 0.297606 -0.4793960 0.0013179 -0.000111 -0.000006 0.000051 0.000054 0.0001010 0.0000094 0.000040 0.000040 2015 1 22 57044 0.006884 0.298570 -0.4808011 0.0014773 -0.000151 -0.000021 0.000051 0.000054 0.0000708 0.0000094 0.000040 0.000040 2015 1 23 57045 0.006188 0.299575 -0.4823227 0.0015487 -0.000173 -0.000032 0.000051 0.000054 0.0000185 0.0000094 0.000040 0.000040 2015 1 24 57046 0.005096 0.300175 -0.4838844 0.0015457 -0.000239 -0.000051 0.000051 0.000054 0.0000169 0.0000094 0.000040 0.000040 2015 1 25 57047 0.003994 0.301223 -0.4854229 0.0014780 -0.000188 -0.000016 0.000051 0.000054 0.0000259 0.0000094 0.000040 0.000040 2015 1 26 57048 0.002781 0.302216 -0.4868111 0.0012869 -0.000126 0.000033 0.000051 0.000054 0.0000242 0.0000094 0.000040 0.000040 2015 1 27 57049 0.002319 0.303047 -0.4880236 0.0011485 -0.000183 0.000042 0.000051 0.000054 0.0000192 0.0000094 0.000040 0.000040 2015 1 28 57050 0.002218 0.304433 -0.4890647 0.0009765 -0.000174 -0.000004 0.000051 0.000053 0.0000195 0.0000094 0.000040 0.000040 2015 1 29 57051 0.002153 0.306113 -0.4899752 0.0008593 -0.000153 0.000012 0.000051 0.000053 0.0000185 0.0000095 0.000039 0.000040 2015 1 30 57052 0.002830 0.308450 -0.4908278 0.0008438 -0.000116 0.000088 0.000050 0.000053 0.0000070 0.0000095 0.000039 0.000039 2015 1 31 57053 0.003738 0.310857 -0.4916578 0.0008547 -0.000096 0.000127 0.000050 0.000053 0.0000337 0.0000095 0.000039 0.000039 2015 2 1 57054 0.004622 0.313179 -0.4925369 0.0008861 -0.000084 0.000147 0.000050 0.000053 0.0000470 0.0000095 0.000039 0.000039 2015 2 2 57055 0.004661 0.315579 -0.4934539 0.0009431 -0.000118 0.000109 0.000050 0.000052 0.0000340 0.0000095 0.000039 0.000039 2015 2 3 57056 0.004205 0.317836 -0.4944347 0.0010584 -0.000153 0.000065 0.000050 0.000052 0.0000147 0.0000095 0.000039 0.000039 2015 2 4 57057 0.003871 0.319825 -0.4955093 0.0011308 -0.000095 0.000097 0.000049 0.000052 0.0000145 0.0000095 0.000039 0.000038 2015 2 5 57058 0.003146 0.321302 -0.4966677 0.0011609 0.000006 0.000144 0.000049 0.000051 0.0000165 0.0000095 0.000039 0.000038 2015 2 6 57059 0.002621 0.322729 -0.4978706 0.0012531 -0.000040 0.000187 0.000049 0.000051 0.0000080 0.0000095 0.000039 0.000038 2015 2 7 57060 0.002050 0.324442 -0.4991359 0.0013243 -0.000155 0.000201 0.000048 0.000050 0.0000180 0.0000095 0.000038 0.000037 2015 2 8 57061 0.001844 0.325757 -0.5004983 0.0013780 -0.000144 0.000098 0.000048 0.000050 0.0000344 0.0000095 0.000038 0.000037 2015 2 9 57062 0.001987 0.327116 -0.5018499 0.0013159 -0.000095 0.000019 0.000047 0.000049 0.0000274 0.0000095 0.000038 0.000036 2015 2 10 57063 0.002154 0.328323 -0.5031573 0.0012451 -0.000113 0.000121 0.000047 0.000049 0.0000088 0.0000096 0.000038 0.000036 2015 2 11 57064 0.002193 0.329751 -0.5043748 0.0011702 -0.000088 0.000050 0.000046 0.000048 0.0000099 0.0000096 0.000038 0.000036 2015 2 12 57065 0.002218 0.331176 -0.5055428 0.0011660 -0.000051 0.000044 0.000046 0.000048 0.0000136 0.0000096 0.000037 0.000035 2015 2 13 57066 0.002402 0.332462 -0.5067174 0.0011692 -0.000057 0.000070 0.000045 0.000047 0.0000074 0.0000096 0.000037 0.000035 2015 2 14 57067 0.002696 0.333459 -0.5078755 0.0011760 -0.000052 0.000004 0.000044 0.000046 0.0000123 0.0000096 0.000037 0.000034 2015 2 15 57068 0.002744 0.334610 -0.5090477 0.0011865 -0.000057 -0.000014 0.000044 0.000046 0.0000213 0.0000096 0.000037 0.000034 2015 2 16 57069 0.002822 0.335673 -0.5102615 0.0012650 -0.000044 -0.000008 0.000043 0.000045 0.0000188 0.0000096 0.000037 0.000034 2015 2 17 57070 0.002845 0.337285 -0.5115845 0.0014008 0.000016 -0.000016 0.000043 0.000044 0.0000104 0.0000096 0.000037 0.000033 2015 2 18 57071 0.002692 0.338426 -0.5130870 0.0015868 -0.000103 0.000070 0.000042 0.000044 0.0000141 0.0000096 0.000036 0.000033 2015 2 19 57072 0.002764 0.339644 -0.5147495 0.0017203 -0.000131 0.000183 0.000042 0.000043 0.0000173 0.0000097 0.000036 0.000033 2015 2 20 57073 0.002560 0.341038 -0.5165063 0.0017617 -0.000109 0.000182 0.000041 0.000043 0.0000072 0.0000097 0.000036 0.000033 2015 2 21 57074 0.002270 0.342684 -0.5182588 0.0017040 -0.000105 0.000170 0.000041 0.000043 0.0000171 0.0000097 0.000036 0.000033 2015 2 22 57075 0.002367 0.344452 -0.5199492 0.0016234 -0.000055 0.000107 0.000041 0.000042 0.0000224 0.0000097 0.000036 0.000033 2015 2 23 57076 0.003018 0.346367 -0.5215097 0.0014695 -0.000042 0.000092 0.000040 0.000042 0.0000165 0.0000097 0.000036 0.000033 2015 2 24 57077 0.003345 0.348567 -0.5228816 0.0012572 -0.000054 0.000106 0.000040 0.000042 0.0000080 0.0000097 0.000036 0.000033 2015 2 25 57078 0.003112 0.350389 -0.5240488 0.0010767 -0.000104 0.000012 0.000040 0.000042 0.0000065 0.0000097 0.000036 0.000033 2015 2 26 57079 0.003101 0.351766 -0.5250547 0.0009486 -0.000134 0.000062 0.000040 0.000041 0.0000067 0.0000098 0.000036 0.000033 2015 2 27 57080 0.003285 0.353145 -0.5259535 0.0008515 -0.000015 0.000278 0.000040 0.000041 0.0000070 0.0000098 0.000036 0.000033 2015 2 28 57081 0.003137 0.354799 -0.5268047 0.0008573 0.000108 0.000425 0.000040 0.000041 0.0000211 0.0000098 0.000036 0.000033 2015 3 1 57082 0.003079 0.356588 -0.5276786 0.0009084 0.000089 0.000251 0.000040 0.000041 0.0000271 0.0000098 0.000036 0.000033 2015 3 2 57083 0.003431 0.358666 -0.5285920 0.0009417 0.000044 0.000159 0.000040 0.000041 0.0000187 0.0000098 0.000036 0.000033 2015 3 3 57084 0.003846 0.360670 -0.5295616 0.0010134 0.000008 0.000148 0.000039 0.000041 0.0000102 0.0000098 0.000036 0.000033 2015 3 4 57085 0.003862 0.362286 -0.5306071 0.0011002 -0.000027 0.000137 0.000039 0.000041 0.0000067 0.0000098 0.000036 0.000032 2015 3 5 57086 0.004178 0.363767 -0.5317004 0.0011306 0.000001 0.000117 0.000039 0.000041 0.0000068 0.0000098 0.000036 0.000032 2015 3 6 57087 0.004803 0.364965 -0.5328650 0.0011755 0.000045 0.000094 0.000039 0.000041 0.0000079 0.0000098 0.000035 0.000032 2015 3 7 57088 0.005019 0.366190 -0.5340851 0.0012428 0.000050 0.000083 0.000039 0.000041 0.0000176 0.0000098 0.000035 0.000033 2015 3 8 57089 0.004640 0.367354 -0.5353674 0.0012730 0.000041 0.000076 0.000039 0.000040 0.0000233 0.0000098 0.000036 0.000033 2015 3 9 57090 0.003960 0.368201 -0.5366988 0.0013483 0.000031 0.000070 0.000039 0.000040 0.0000205 0.0000098 0.000036 0.000033 2015 3 10 57091 0.003553 0.369261 -0.5380452 0.0013895 0.000022 0.000063 0.000039 0.000040 0.0000153 0.0000099 0.000036 0.000033 2015 3 11 57092 0.003344 0.370507 -0.5394424 0.0013864 0.000145 0.000067 0.000039 0.000040 0.0000170 0.0000099 0.000036 0.000033 2015 3 12 57093 0.003160 0.371635 -0.5408460 0.0014202 0.000134 0.000082 0.000039 0.000040 0.0000584 0.0000098 0.000036 0.000033 2015 3 13 57094 0.002889 0.372722 -0.5422526 0.0013963 0.000028 0.000100 0.000039 0.000040 0.0002447 0.0000098 0.000036 0.000034 2015 3 14 57095 0.002645 0.373662 -0.5436896 0.0014665 -0.000008 0.000103 0.000039 0.000040 0.0001098 0.0000098 0.000036 0.000034 2015 3 15 57096 0.002777 0.374588 -0.5452054 0.0015617 0.000066 0.000060 0.000039 0.000040 0.0000216 0.0000098 0.000036 0.000034 2015 3 16 57097 0.002732 0.375527 -0.5467979 0.0016745 0.000132 0.000080 0.000039 0.000040 0.0000144 0.0000098 0.000036 0.000034 2015 3 17 57098 0.002803 0.376478 -0.5485410 0.0018220 0.000112 0.000204 0.000039 0.000040 0.0000064 0.0000098 0.000036 0.000034 2015 3 18 57099 0.002691 0.377484 -0.5504543 0.0020005 0.000096 0.000193 0.000039 0.000040 0.0000046 0.0000098 0.000036 0.000034 2015 3 19 57100 0.003320 0.378375 -0.5525471 0.0021842 0.000081 0.000147 0.000039 0.000040 0.0000044 0.0000098 0.000036 0.000034 2015 3 20 57101 0.004531 0.379476 -0.5547657 0.0022426 0.000067 0.000101 0.000039 0.000040 0.0000042 0.0000098 0.000036 0.000034 2015 3 21 57102 0.006224 0.381259 -0.5570527 0.0022666 0.000142 0.000008 0.000039 0.000040 0.0000212 0.0000098 0.000036 0.000034 2015 3 22 57103 0.007594 0.383355 -0.5592698 0.0021225 0.000198 -0.000019 0.000039 0.000040 0.0000252 0.0000098 0.000036 0.000034 2015 3 23 57104 0.008497 0.385284 -0.5613431 0.0019439 0.000163 0.000094 0.000039 0.000040 0.0000167 0.0000098 0.000036 0.000034 2015 3 24 57105 0.009311 0.387188 -0.5632364 0.0018118 0.000090 0.000263 0.000039 0.000040 0.0000069 0.0000098 0.000036 0.000034 2015 3 25 57106 0.010068 0.388624 -0.5650215 0.0016964 0.000110 0.000283 0.000039 0.000040 0.0000138 0.0000098 0.000036 0.000034 2015 3 26 57107 0.010611 0.389793 -0.5666588 0.0015510 0.000154 0.000265 0.000039 0.000040 0.0000204 0.0000097 0.000036 0.000034 2015 3 27 57108 0.010868 0.390995 -0.5681223 0.0014322 0.000096 0.000239 0.000039 0.000040 0.0000097 0.0000097 0.000036 0.000034 2015 3 28 57109 0.011039 0.392148 -0.5695450 0.0013901 0.000094 0.000185 0.000039 0.000040 0.0000135 0.0000097 0.000036 0.000035 2015 3 29 57110 0.011437 0.393231 -0.5709452 0.0013813 0.000135 0.000130 0.000039 0.000040 0.0000196 0.0000097 0.000036 0.000035 2015 3 30 57111 0.012018 0.394106 -0.5723159 0.0013815 0.000122 0.000111 0.000039 0.000040 0.0000155 0.0000097 0.000036 0.000035 2015 3 31 57112 0.012515 0.395256 -0.5736790 0.0013836 0.000048 0.000119 0.000039 0.000040 0.0000070 0.0000097 0.000036 0.000035 2015 4 1 57113 0.013716 0.396431 -0.5750400 0.0013756 -0.000013 0.000101 0.000039 0.000040 0.0000075 0.0000097 0.000037 0.000036 2015 4 2 57114 0.015672 0.397887 -0.5764041 0.0013630 0.000015 0.000130 0.000039 0.000040 0.0000103 0.0000097 0.000037 0.000036 2015 4 3 57115 0.017465 0.399739 -0.5777184 0.0013066 0.000055 0.000147 0.000039 0.000040 0.0000133 0.0000097 0.000037 0.000036 2015 4 4 57116 0.018520 0.401679 -0.5789914 0.0012411 0.000091 0.000154 0.000039 0.000040 0.0000152 0.0000097 0.000037 0.000036 2015 4 5 57117 0.019090 0.403465 -0.5801957 0.0011933 0.000128 0.000160 0.000039 0.000040 0.0000165 0.0000097 0.000037 0.000036 2015 4 6 57118 0.019555 0.404876 -0.5814340 0.0012102 0.000164 0.000166 0.000039 0.000040 0.0000151 0.0000096 0.000036 0.000036 2015 4 7 57119 0.020175 0.406077 -0.5826732 0.0012627 0.000200 0.000173 0.000039 0.000040 0.0000114 0.0000096 0.000036 0.000036 2015 4 8 57120 0.020871 0.407006 -0.5838883 0.0012587 0.000236 0.000179 0.000039 0.000040 0.0000077 0.0000096 0.000036 0.000036 2015 4 9 57121 0.021403 0.407897 -0.5851319 0.0012434 0.000236 0.000212 0.000039 0.000040 0.0000099 0.0000096 0.000036 0.000036 2015 4 10 57122 0.021486 0.409268 -0.5864009 0.0013136 0.000203 0.000205 0.000039 0.000040 0.0000135 0.0000096 0.000036 0.000035 2015 4 11 57123 0.021165 0.410679 -0.5877604 0.0014187 0.000188 0.000114 0.000039 0.000040 0.0000171 0.0000096 0.000036 0.000035 2015 4 12 57124 0.021007 0.411696 -0.5892538 0.0015789 0.000230 0.000033 0.000039 0.000040 0.0000168 0.0000096 0.000036 0.000035 2015 4 13 57125 0.021148 0.412412 -0.5908875 0.0017213 0.000257 0.000040 0.000039 0.000040 0.0000132 0.0000095 0.000036 0.000035 2015 4 14 57126 0.021406 0.413180 -0.5926764 0.0018478 0.000223 0.000099 0.000039 0.000040 0.0000088 0.0000095 0.000036 0.000035 2015 4 15 57127 0.021875 0.414254 -0.5945568 0.0019428 0.000170 0.000098 0.000039 0.000040 0.0000081 0.0000095 0.000036 0.000035 2015 4 16 57128 0.023194 0.415333 -0.5965329 0.0020359 0.000112 0.000081 0.000039 0.000040 0.0000084 0.0000095 0.000036 0.000035 2015 4 17 57129 0.024213 0.416970 -0.5985428 0.0019374 0.000054 0.000064 0.000039 0.000040 0.0000087 0.0000095 0.000036 0.000035 2015 4 18 57130 0.025233 0.417892 -0.6004369 0.0018167 0.000138 0.000036 0.000039 0.000040 0.0000150 0.0000095 0.000036 0.000035 2015 4 19 57131 0.026174 0.418968 -0.6021849 0.0016324 0.000217 0.000084 0.000039 0.000040 0.0000162 0.0000095 0.000036 0.000035 2015 4 20 57132 0.027094 0.419708 -0.6037249 0.0014182 0.000215 0.000171 0.000039 0.000040 0.0000124 0.0000094 0.000036 0.000035 2015 4 21 57133 0.028005 0.420919 -0.6050505 0.0012008 0.000190 0.000218 0.000039 0.000040 0.0000079 0.0000094 0.000036 0.000035 2015 4 22 57134 0.028855 0.421738 -0.6061816 0.0010388 0.000178 0.000229 0.000039 0.000040 0.0000310 0.0000094 0.000037 0.000035 2015 4 23 57135 0.030091 0.422514 -0.6072056 0.0010055 0.000170 0.000229 0.000039 0.000040 0.0000485 0.0000094 0.000037 0.000036 2015 4 24 57136 0.031146 0.423867 -0.6082140 0.0010083 0.000168 0.000220 0.000039 0.000040 0.0000178 0.0000094 0.000037 0.000036 2015 4 25 57137 0.032038 0.425089 -0.6092759 0.0011117 0.000254 0.000174 0.000039 0.000040 0.0000130 0.0000093 0.000037 0.000037 2015 4 26 57138 0.033500 0.426243 -0.6104401 0.0012049 0.000341 0.000183 0.000039 0.000040 0.0000137 0.0000093 0.000038 0.000037 2015 4 27 57139 0.035296 0.427761 -0.6116831 0.0012912 0.000357 0.000200 0.000039 0.000040 0.0000102 0.0000093 0.000038 0.000038 2015 4 28 57140 0.036872 0.429343 -0.6129919 0.0013206 0.000333 0.000161 0.000039 0.000040 0.0000057 0.0000093 0.000038 0.000038 2015 4 29 57141 0.038124 0.430575 -0.6143441 0.0013883 0.000285 0.000122 0.000039 0.000040 0.0000053 0.0000093 0.000038 0.000038 2015 4 30 57142 0.038959 0.431577 -0.6157300 0.0014155 0.000229 0.000082 0.000039 0.000040 0.0000061 0.0000093 0.000038 0.000039 2015 5 1 57143 0.039789 0.432347 -0.6171285 0.0013919 0.000162 0.000050 0.000039 0.000041 0.0000104 0.0000092 0.000038 0.000039 2015 5 2 57144 0.040039 0.433233 -0.6185091 0.0013384 0.000161 0.000050 0.000039 0.000041 0.0000160 0.0000092 0.000039 0.000040 2015 5 3 57145 0.040200 0.434149 -0.6197799 0.0012373 0.000189 0.000061 0.000039 0.000041 0.0000186 0.0000092 0.000039 0.000040 2015 5 4 57146 0.040717 0.435545 -0.6209594 0.0011577 0.000217 0.000073 0.000039 0.000041 0.0000166 0.0000092 0.000039 0.000040 2015 5 5 57147 0.041544 0.436949 -0.6220701 0.0010663 0.000245 0.000085 0.000039 0.000041 0.0000131 0.0000092 0.000039 0.000041 2015 5 6 57148 0.042196 0.438368 -0.6231067 0.0010071 0.000090 0.000130 0.000039 0.000041 0.0000203 0.0000092 0.000039 0.000041 2015 5 7 57149 0.043412 0.439605 -0.6241126 0.0010321 0.000050 0.000096 0.000039 0.000041 0.0000255 0.0000092 0.000039 0.000042 2015 5 8 57150 0.045034 0.440906 -0.6251602 0.0010707 0.000148 0.000095 0.000039 0.000041 0.0000120 0.0000091 0.000039 0.000042 2015 5 9 57151 0.047080 0.442215 -0.6262808 0.0011909 0.000217 0.000239 0.000039 0.000041 0.0000240 0.0000091 0.000039 0.000042 2015 5 10 57152 0.048996 0.443710 -0.6275273 0.0013281 0.000246 0.000319 0.000039 0.000041 0.0000237 0.0000091 0.000039 0.000042 2015 5 11 57153 0.050576 0.444633 -0.6289633 0.0015309 0.000243 0.000218 0.000039 0.000041 0.0000149 0.0000091 0.000039 0.000042 2015 5 12 57154 0.052150 0.445111 -0.6305941 0.0017303 0.000225 0.000046 0.000039 0.000041 0.0000073 0.0000091 0.000039 0.000042 2015 5 13 57155 0.053755 0.445640 -0.6323609 0.0018279 0.000279 -0.000072 0.000039 0.000041 0.0000061 0.0000090 0.000039 0.000042 2015 5 14 57156 0.055421 0.446067 -0.6342359 0.0018796 0.000258 -0.000057 0.000039 0.000041 0.0000067 0.0000090 0.000039 0.000042 2015 5 15 57157 0.057188 0.446859 -0.6361499 0.0019234 0.000167 0.000031 0.000039 0.000041 0.0000073 0.0000090 0.000039 0.000042 2015 5 16 57158 0.059002 0.447116 -0.6380194 0.0017868 0.000195 0.000054 0.000039 0.000041 0.0000078 0.0000090 0.000038 0.000042 2015 5 17 57159 0.061366 0.447256 -0.6397679 0.0016472 0.000316 0.000056 0.000039 0.000041 0.0000083 0.0000089 0.000038 0.000042 2015 5 18 57160 0.063768 0.448162 -0.6413505 0.0014927 0.000366 0.000118 0.000039 0.000041 0.0000087 0.0000089 0.000038 0.000042 2015 5 19 57161 0.065714 0.448969 -0.6427619 0.0013664 0.000300 0.000235 0.000039 0.000041 0.0000092 0.0000089 0.000038 0.000041 2015 5 20 57162 0.067868 0.449294 -0.6440787 0.0012620 0.000353 0.000290 0.000039 0.000041 0.0000169 0.0000089 0.000037 0.000041 2015 5 21 57163 0.069986 0.449474 -0.6452950 0.0011669 0.000381 0.000243 0.000039 0.000041 0.0000217 0.0000089 0.000037 0.000041 2015 5 22 57164 0.071737 0.449523 -0.6464116 0.0010972 0.000265 0.000143 0.000040 0.000041 0.0000087 0.0000088 0.000036 0.000040 2015 5 23 57165 0.073918 0.449803 -0.6475071 0.0010969 0.000230 0.000101 0.000040 0.000041 0.0000210 0.0000088 0.000036 0.000039 2015 5 24 57166 0.075693 0.450726 -0.6485679 0.0010307 0.000239 0.000082 0.000040 0.000041 0.0000259 0.0000088 0.000035 0.000039 2015 5 25 57167 0.077406 0.451246 -0.6495972 0.0010334 0.000248 0.000064 0.000040 0.000041 0.0000209 0.0000088 0.000035 0.000038 2015 5 26 57168 0.079196 0.452110 -0.6506220 0.0010343 0.000258 0.000046 0.000040 0.000041 0.0000153 0.0000088 0.000034 0.000037 2015 5 27 57169 0.080922 0.452648 -0.6516442 0.0010174 0.000267 0.000027 0.000040 0.000041 0.0000096 0.0000088 0.000034 0.000037 2015 5 28 57170 0.083022 0.453257 -0.6526740 0.0010404 0.000235 0.000009 0.000040 0.000041 0.0000092 0.0000088 0.000034 0.000036 2015 5 29 57171 0.085102 0.453918 -0.6536724 0.0009864 0.000192 -0.000010 0.000040 0.000041 0.0000101 0.0000087 0.000033 0.000036 2015 5 30 57172 0.087207 0.454653 -0.6545748 0.0009111 0.000183 -0.000020 0.000040 0.000041 0.0000298 0.0000087 0.000033 0.000035 2015 5 31 57173 0.089062 0.455462 -0.6554604 0.0008119 0.000187 -0.000028 0.000040 0.000041 0.0000310 0.0000087 0.000033 0.000035 2015 6 1 57174 0.091020 0.456028 -0.6562478 0.0007370 0.000191 0.000001 0.000040 0.000041 0.0000190 0.0000087 0.000032 0.000034 2015 6 2 57175 0.092379 0.456502 -0.6569312 0.0006753 0.000197 0.000064 0.000040 0.000041 0.0000067 0.0000087 0.000032 0.000034 2015 6 3 57176 0.093209 0.456907 -0.6575803 0.0006416 0.000287 -0.000026 0.000040 0.000041 0.0000205 0.0000087 0.000032 0.000034 2015 6 4 57177 0.093765 0.457088 -0.6582044 0.0006207 0.000236 -0.000090 0.000040 0.000041 0.0000323 0.0000087 0.000031 0.000033 2015 6 5 57178 0.094807 0.456930 -0.6588364 0.0006772 0.000204 -0.000061 0.000040 0.000041 0.0000106 0.0000087 0.000031 0.000033 2015 6 6 57179 0.096044 0.456852 -0.6595758 0.0008004 0.000249 -0.000027 0.000040 0.000041 0.0000214 0.0000087 0.000031 0.000033 2015 6 7 57180 0.096631 0.456717 -0.6604105 0.0009103 0.000160 0.000051 0.000040 0.000041 0.0000276 0.0000087 0.000031 0.000033 2015 6 8 57181 0.097074 0.456127 -0.6613568 0.0010386 0.000158 0.000046 0.000040 0.000041 0.0000277 0.0000087 0.000031 0.000033 2015 6 9 57182 0.098010 0.455627 -0.6624113 0.0010804 0.000217 -0.000001 0.000040 0.000041 0.0000198 0.0000087 0.000031 0.000033 2015 6 10 57183 0.099021 0.455357 -0.6635178 0.0010382 0.000276 -0.000049 0.000040 0.000041 0.0000077 0.0000087 0.000031 0.000033 2015 6 11 57184 0.100404 0.455235 -0.6645587 0.0010035 0.000288 -0.000049 0.000040 0.000041 0.0000055 0.0000087 0.000031 0.000033 2015 6 12 57185 0.102261 0.455187 -0.6655042 0.0009009 0.000246 -0.000068 0.000040 0.000041 0.0000059 0.0000087 0.000031 0.000033 2015 6 13 57186 0.104595 0.454965 -0.6663060 0.0007463 0.000188 -0.000101 0.000040 0.000041 0.0000329 0.0000087 0.000031 0.000033 2015 6 14 57187 0.107193 0.454709 -0.6669671 0.0005545 0.000146 -0.000178 0.000040 0.000041 0.0000382 0.0000087 0.000031 0.000033 2015 6 15 57188 0.109902 0.454492 -0.6674415 0.0003893 0.000166 -0.000146 0.000040 0.000041 0.0000274 0.0000087 0.000031 0.000033 2015 6 16 57189 0.112539 0.454093 -0.6677659 0.0002901 0.000208 -0.000062 0.000040 0.000041 0.0000164 0.0000087 0.000031 0.000034 2015 6 17 57190 0.114992 0.453650 -0.6679851 0.0001969 0.000264 -0.000063 0.000040 0.000041 0.0000153 0.0000087 0.000031 0.000034 2015 6 18 57191 0.117012 0.453424 -0.6681826 0.0001943 0.000284 -0.000067 0.000040 0.000041 0.0000167 0.0000087 0.000031 0.000034 2015 6 19 57192 0.119054 0.453240 -0.6684352 0.0003184 0.000249 -0.000040 0.000040 0.000041 0.0000170 0.0000087 0.000031 0.000033 2015 6 20 57193 0.121221 0.453030 -0.6688172 0.0004046 0.000287 -0.000001 0.000040 0.000041 0.0000188 0.0000087 0.000031 0.000033 2015 6 21 57194 0.123066 0.453006 -0.6692903 0.0005299 0.000294 -0.000007 0.000040 0.000041 0.0000268 0.0000087 0.000031 0.000033 2015 6 22 57195 0.125018 0.452941 -0.6698768 0.0006041 0.000271 -0.000022 0.000040 0.000041 0.0000182 0.0000087 0.000031 0.000033 2015 6 23 57196 0.127019 0.452379 -0.6705553 0.0006953 0.000228 -0.000010 0.000040 0.000041 0.0000058 0.0000087 0.000031 0.000033 2015 6 24 57197 0.129112 0.451992 -0.6713150 0.0008057 0.000204 0.000027 0.000040 0.000041 0.0000083 0.0000087 0.000031 0.000033 2015 6 25 57198 0.131408 0.451564 -0.6721249 0.0008098 0.000209 -0.000013 0.000040 0.000041 0.0000123 0.0000087 0.000031 0.000033 2015 6 26 57199 0.133996 0.451194 -0.6729622 0.0008132 0.000197 -0.000051 0.000040 0.000041 0.0000076 0.0000087 0.000031 0.000033 2015 6 27 57200 0.136123 0.450900 -0.6738120 0.0008241 0.000200 -0.000103 0.000040 0.000041 0.0000369 0.0000087 0.000031 0.000033 2015 6 28 57201 0.137844 0.450492 -0.6746323 0.0007879 0.000211 -0.000164 0.000040 0.000041 0.0000353 0.0000087 0.000031 0.000033 2015 6 29 57202 0.139412 0.449703 -0.6753621 0.0006911 0.000210 -0.000174 0.000040 0.000041 0.0000201 0.0000087 0.000031 0.000033 2015 6 30 57203 0.140756 0.448901 -0.6760316 0.0005964 0.000198 -0.000132 0.000040 0.000041 0.0000088 0.0000087 0.000030 0.000032 2015 7 1 57204 0.142127 0.448194 0.3233730 0.0005810 0.000201 -0.000136 0.000040 0.000041 0.0000059 0.0000087 0.000030 0.000032 2015 7 2 57205 0.143562 0.447358 0.3227664 0.0006338 0.000207 -0.000152 0.000039 0.000041 0.0000052 0.0000087 0.000030 0.000032 2015 7 3 57206 0.145001 0.446688 0.3220722 0.0007374 0.000204 -0.000150 0.000039 0.000041 0.0000165 0.0000087 0.000030 0.000032 2015 7 4 57207 0.146503 0.445636 0.3212454 0.0009120 0.000202 -0.000148 0.000039 0.000040 0.0000323 0.0000087 0.000030 0.000031 2015 7 5 57208 0.148539 0.444658 0.3202267 0.0011193 0.000199 -0.000145 0.000039 0.000040 0.0000302 0.0000087 0.000030 0.000031 2015 7 6 57209 0.150847 0.444056 0.3190425 0.0012351 0.000197 -0.000142 0.000039 0.000040 0.0000191 0.0000087 0.000030 0.000031 2015 7 7 57210 0.152801 0.443836 0.3177556 0.0013021 0.000194 -0.000139 0.000039 0.000040 0.0000080 0.0000087 0.000030 0.000031 2015 7 8 57211 0.154840 0.443816 0.3164239 0.0013532 0.000191 -0.000146 0.000039 0.000040 0.0000178 0.0000087 0.000030 0.000030 2015 7 9 57212 0.156741 0.443548 0.3151156 0.0012911 0.000188 -0.000155 0.000039 0.000040 0.0000270 0.0000087 0.000030 0.000030 2015 7 10 57213 0.158507 0.442868 0.3138523 0.0011784 0.000185 -0.000164 0.000039 0.000040 0.0000131 0.0000087 0.000030 0.000030 2015 7 11 57214 0.160488 0.441819 0.3127139 0.0010265 0.000176 -0.000154 0.000039 0.000040 0.0000373 0.0000087 0.000030 0.000030 2015 7 12 57215 0.162914 0.440601 0.3118151 0.0008439 0.000166 -0.000137 0.000039 0.000040 0.0000353 0.0000087 0.000030 0.000030 2015 7 13 57216 0.165633 0.439462 0.3111205 0.0006366 0.000155 -0.000120 0.000039 0.000040 0.0000197 0.0000087 0.000030 0.000030 2015 7 14 57217 0.168192 0.438530 0.3105539 0.0004972 0.000145 -0.000103 0.000039 0.000040 0.0000073 0.0000087 0.000030 0.000030 2015 7 15 57218 0.170379 0.437604 0.3101367 0.0004294 0.000218 -0.000146 0.000039 0.000040 0.0000197 0.0000087 0.000030 0.000030 2015 7 16 57219 0.172151 0.436384 0.3097491 0.0004372 0.000198 -0.000093 0.000039 0.000040 0.0000310 0.0000087 0.000030 0.000030 2015 7 17 57220 0.173761 0.434958 0.3092665 0.0004466 0.000206 -0.000069 0.000039 0.000040 0.0000134 0.0000087 0.000030 0.000030 2015 7 18 57221 0.175689 0.433910 0.3087877 0.0004831 0.000219 -0.000100 0.000039 0.000040 0.0000246 0.0000087 0.000030 0.000030 2015 7 19 57222 0.177368 0.432910 0.3083295 0.0004740 0.000226 -0.000143 0.000039 0.000040 0.0000269 0.0000087 0.000030 0.000030 2015 7 20 57223 0.178840 0.432093 0.3078466 0.0004895 0.000233 -0.000186 0.000039 0.000040 0.0000185 0.0000087 0.000029 0.000030 2015 7 21 57224 0.180085 0.431388 0.3073386 0.0005077 0.000239 -0.000229 0.000039 0.000040 0.0000098 0.0000087 0.000029 0.000030 2015 7 22 57225 0.181025 0.430441 0.3068129 0.0005295 0.000189 -0.000218 0.000039 0.000040 0.0000073 0.0000088 0.000029 0.000030 2015 7 23 57226 0.181986 0.429582 0.3062979 0.0005119 0.000124 -0.000192 0.000039 0.000040 0.0000064 0.0000088 0.000030 0.000030 2015 7 24 57227 0.182964 0.428822 0.3058125 0.0004754 0.000059 -0.000166 0.000039 0.000040 0.0000055 0.0000088 0.000030 0.000030 2015 7 25 57228 0.184454 0.427926 0.3053051 0.0004889 0.000079 -0.000163 0.000039 0.000040 0.0000191 0.0000088 0.000030 0.000030 2015 7 26 57229 0.185816 0.426848 0.3048779 0.0004395 0.000131 -0.000169 0.000039 0.000040 0.0000359 0.0000088 0.000030 0.000030 2015 7 27 57230 0.187240 0.425462 0.3044913 0.0003941 0.000182 -0.000174 0.000039 0.000040 0.0000298 0.0000088 0.000029 0.000030 2015 7 28 57231 0.189193 0.424118 0.3041009 0.0003808 0.000234 -0.000179 0.000039 0.000040 0.0000127 0.0000088 0.000029 0.000030 2015 7 29 57232 0.191113 0.423023 0.3037083 0.0004169 0.000204 -0.000193 0.000039 0.000040 0.0000207 0.0000088 0.000030 0.000030 2015 7 30 57233 0.192901 0.421615 0.3032419 0.0005372 0.000154 -0.000210 0.000039 0.000040 0.0000270 0.0000089 0.000030 0.000030 2015 7 31 57234 0.194568 0.420239 0.3026413 0.0006923 0.000103 -0.000226 0.000039 0.000040 0.0000130 0.0000089 0.000030 0.000030 2015 8 1 57235 0.196269 0.418716 0.3018647 0.0008805 0.000010 -0.000246 0.000039 0.000040 0.0000289 0.0000089 0.000030 0.000030 2015 8 2 57236 0.198073 0.417383 0.3008636 0.0010813 -0.000098 -0.000267 0.000039 0.000040 0.0000332 0.0000089 0.000030 0.000030 2015 8 3 57237 0.200058 0.415892 0.2997053 0.0011937 -0.000206 -0.000288 0.000039 0.000040 0.0000214 0.0000090 0.000030 0.000030 2015 8 4 57238 0.202147 0.414654 0.2984615 0.0012601 -0.000314 -0.000308 0.000039 0.000040 0.0000130 0.0000090 0.000030 0.000030 2015 8 5 57239 0.204545 0.413509 0.2972126 0.0012289 0.000054 -0.000218 0.000039 0.000040 0.0000101 0.0000090 0.000030 0.000030 2015 8 6 57240 0.206882 0.412321 0.2960421 0.0011261 0.000102 -0.000173 0.000039 0.000040 0.0000086 0.0000090 0.000029 0.000030 2015 8 7 57241 0.208706 0.411162 0.2950026 0.0009620 0.000066 -0.000141 0.000039 0.000040 0.0000075 0.0000091 0.000029 0.000029 2015 8 8 57242 0.209991 0.410135 0.2941224 0.0008258 0.000058 -0.000138 0.000039 0.000040 0.0000110 0.0000091 0.000029 0.000029 2015 8 9 57243 0.210591 0.408583 0.2933769 0.0007054 0.000060 -0.000145 0.000039 0.000040 0.0000163 0.0000091 0.000029 0.000029 2015 8 10 57244 0.211260 0.406666 0.2927241 0.0006097 0.000062 -0.000152 0.000039 0.000040 0.0000216 0.0000091 0.000029 0.000029 2015 8 11 57245 0.212044 0.404959 0.2921203 0.0005542 0.000064 -0.000159 0.000039 0.000040 0.0000218 0.0000091 0.000029 0.000029 2015 8 12 57246 0.212698 0.403420 0.2915253 0.0005903 0.000066 -0.000166 0.000039 0.000040 0.0000073 0.0000091 0.000029 0.000029 2015 8 13 57247 0.213666 0.401462 0.2908846 0.0006606 0.000100 -0.000174 0.000039 0.000040 0.0000051 0.0000091 0.000029 0.000029 2015 8 14 57248 0.215302 0.399612 0.2901864 0.0007481 0.000141 -0.000182 0.000039 0.000040 0.0000061 0.0000091 0.000029 0.000029 2015 8 15 57249 0.217012 0.398044 0.2894182 0.0007832 0.000155 -0.000175 0.000039 0.000040 0.0000249 0.0000091 0.000029 0.000029 2015 8 16 57250 0.218438 0.396851 0.2886155 0.0008057 0.000158 -0.000162 0.000039 0.000040 0.0000225 0.0000092 0.000029 0.000029 2015 8 17 57251 0.219447 0.395513 0.2877733 0.0008469 0.000162 -0.000149 0.000039 0.000040 0.0000141 0.0000092 0.000029 0.000029 2015 8 18 57252 0.219906 0.394072 0.2869278 0.0008121 0.000165 -0.000136 0.000039 0.000040 0.0000127 0.0000092 0.000029 0.000029 2015 8 19 57253 0.219403 0.392400 0.2861171 0.0008006 0.000152 -0.000157 0.000039 0.000040 0.0000161 0.0000092 0.000029 0.000029 2015 8 20 57254 0.219408 0.390472 0.2852742 0.0008118 0.000135 -0.000187 0.000039 0.000040 0.0000123 0.0000092 0.000029 0.000029 2015 8 21 57255 0.219978 0.388524 0.2844624 0.0008384 0.000118 -0.000217 0.000039 0.000040 0.0000085 0.0000092 0.000030 0.000029 2015 8 22 57256 0.221210 0.386466 0.2836407 0.0008121 0.000114 -0.000200 0.000039 0.000040 0.0000129 0.0000092 0.000030 0.000030 2015 8 23 57257 0.222207 0.384690 0.2828758 0.0007589 0.000114 -0.000164 0.000039 0.000040 0.0000247 0.0000093 0.000030 0.000030 2015 8 24 57258 0.223045 0.382854 0.2821117 0.0007865 0.000114 -0.000129 0.000039 0.000040 0.0000210 0.0000093 0.000030 0.000030 2015 8 25 57259 0.224034 0.381145 0.2813070 0.0008454 0.000115 -0.000094 0.000039 0.000040 0.0000085 0.0000093 0.000030 0.000030 2015 8 26 57260 0.225332 0.379202 0.2804470 0.0009214 0.000077 -0.000199 0.000039 0.000040 0.0000165 0.0000093 0.000030 0.000031 2015 8 27 57261 0.226008 0.377222 0.2794739 0.0010307 0.000126 -0.000273 0.000039 0.000040 0.0000220 0.0000093 0.000031 0.000031 2015 8 28 57262 0.226101 0.374951 0.2783470 0.0012168 0.000168 -0.000270 0.000039 0.000040 0.0000085 0.0000093 0.000031 0.000031 2015 8 29 57263 0.226099 0.373246 0.2770184 0.0013967 0.000149 -0.000258 0.000039 0.000040 0.0000212 0.0000093 0.000031 0.000031 2015 8 30 57264 0.225941 0.371908 0.2755072 0.0016063 0.000112 -0.000250 0.000039 0.000040 0.0000291 0.0000093 0.000031 0.000031 2015 8 31 57265 0.226057 0.370658 0.2737918 0.0017501 0.000074 -0.000242 0.000039 0.000040 0.0000219 0.0000093 0.000031 0.000031 2015 9 1 57266 0.226121 0.369720 0.2719870 0.0018078 0.000037 -0.000234 0.000039 0.000040 0.0000108 0.0000093 0.000031 0.000031 2015 9 2 57267 0.226209 0.368722 0.2701948 0.0017411 0.000007 -0.000369 0.000039 0.000040 0.0000163 0.0000093 0.000031 0.000031 2015 9 3 57268 0.226590 0.367259 0.2685232 0.0015876 0.000018 -0.000318 0.000038 0.000040 0.0000215 0.0000094 0.000031 0.000031 2015 9 4 57269 0.227390 0.365681 0.2670339 0.0014125 0.000040 -0.000200 0.000038 0.000040 0.0000086 0.0000094 0.000031 0.000031 2015 9 5 57270 0.227896 0.364643 0.2657100 0.0012820 0.000081 -0.000176 0.000038 0.000040 0.0000213 0.0000094 0.000031 0.000031 2015 9 6 57271 0.227920 0.363363 0.2644765 0.0011837 0.000129 -0.000186 0.000038 0.000040 0.0000270 0.0000094 0.000031 0.000031 2015 9 7 57272 0.228074 0.361846 0.2633555 0.0011191 0.000177 -0.000197 0.000038 0.000040 0.0000283 0.0000094 0.000031 0.000031 2015 9 8 57273 0.227866 0.360285 0.2623086 0.0010497 0.000226 -0.000207 0.000038 0.000040 0.0000200 0.0000094 0.000031 0.000031 2015 9 9 57274 0.227444 0.358375 0.2612617 0.0010483 0.000158 -0.000215 0.000038 0.000040 0.0000065 0.0000094 0.000031 0.000030 2015 9 10 57275 0.226624 0.356478 0.2602228 0.0010437 0.000087 -0.000210 0.000038 0.000040 0.0000045 0.0000094 0.000031 0.000030 2015 9 11 57276 0.225631 0.354602 0.2591434 0.0010881 0.000037 -0.000182 0.000038 0.000040 0.0000056 0.0000095 0.000031 0.000030 2015 9 12 57277 0.224839 0.352343 0.2579439 0.0012109 0.000023 -0.000172 0.000038 0.000040 0.0000274 0.0000095 0.000030 0.000030 2015 9 13 57278 0.224801 0.350371 0.2566794 0.0013051 0.000020 -0.000170 0.000038 0.000040 0.0000310 0.0000095 0.000030 0.000029 2015 9 14 57279 0.224778 0.348415 0.2553711 0.0013343 0.000016 -0.000168 0.000038 0.000040 0.0000196 0.0000095 0.000030 0.000029 2015 9 15 57280 0.224615 0.346578 0.2540437 0.0013117 0.000013 -0.000167 0.000038 0.000040 0.0000071 0.0000095 0.000030 0.000029 2015 9 16 57281 0.224248 0.345228 0.2527679 0.0012563 0.000011 -0.000149 0.000038 0.000040 0.0000051 0.0000095 0.000030 0.000028 2015 9 17 57282 0.223519 0.343771 0.2515283 0.0012156 0.000009 -0.000127 0.000038 0.000040 0.0000058 0.0000095 0.000030 0.000028 2015 9 18 57283 0.222416 0.342352 0.2503235 0.0011790 0.000007 -0.000105 0.000037 0.000040 0.0000066 0.0000095 0.000030 0.000028 2015 9 19 57284 0.221373 0.340446 0.2491320 0.0011827 0.000018 -0.000097 0.000037 0.000040 0.0000147 0.0000095 0.000030 0.000028 2015 9 20 57285 0.220488 0.338505 0.2479621 0.0011859 0.000032 -0.000094 0.000037 0.000040 0.0000206 0.0000095 0.000030 0.000028 2015 9 21 57286 0.219418 0.336309 0.2467769 0.0012116 0.000047 -0.000092 0.000037 0.000040 0.0000160 0.0000095 0.000030 0.000028 2015 9 22 57287 0.218754 0.334077 0.2455414 0.0012961 0.000061 -0.000089 0.000037 0.000040 0.0000073 0.0000095 0.000030 0.000028 2015 9 23 57288 0.218274 0.332070 0.2442125 0.0013747 0.000065 -0.000142 0.000036 0.000040 0.0000135 0.0000095 0.000030 0.000028 2015 9 24 57289 0.218105 0.329985 0.2427581 0.0014843 0.000065 -0.000208 0.000036 0.000040 0.0000191 0.0000095 0.000030 0.000029 2015 9 25 57290 0.218080 0.328259 0.2411888 0.0016979 0.000065 -0.000275 0.000036 0.000040 0.0000079 0.0000095 0.000030 0.000029 2015 9 26 57291 0.218193 0.326800 0.2393644 0.0019386 0.000093 -0.000105 0.000036 0.000040 0.0000177 0.0000095 0.000030 0.000029 2015 9 27 57292 0.217654 0.325182 0.2373373 0.0020936 0.000081 -0.000007 0.000036 0.000040 0.0000181 0.0000095 0.000030 0.000029 2015 9 28 57293 0.216334 0.323550 0.2352195 0.0021247 0.000021 -0.000066 0.000037 0.000040 0.0000109 0.0000095 0.000030 0.000028 2015 9 29 57294 0.214312 0.321277 0.2331201 0.0020573 -0.000039 -0.000126 0.000037 0.000040 0.0000041 0.0000095 0.000030 0.000028 2015 9 30 57295 0.212079 0.318788 0.2311442 0.0019025 -0.000111 -0.000091 0.000037 0.000040 0.0000186 0.0000094 0.000030 0.000028 2015 10 1 57296 0.210115 0.315962 0.2293614 0.0016842 -0.000072 -0.000122 0.000037 0.000040 0.0000303 0.0000094 0.000029 0.000028 2015 10 2 57297 0.209323 0.313734 0.2278130 0.0014153 0.000002 -0.000182 0.000037 0.000040 0.0000105 0.0000094 0.000029 0.000028 2015 10 3 57298 0.209265 0.312006 0.2264607 0.0012736 0.000028 -0.000173 0.000037 0.000040 0.0000198 0.0000094 0.000029 0.000028 2015 10 4 57299 0.209005 0.310109 0.2252193 0.0012311 0.000038 -0.000140 0.000037 0.000040 0.0000248 0.0000094 0.000029 0.000027 2015 10 5 57300 0.208601 0.307991 0.2239927 0.0012466 0.000047 -0.000107 0.000037 0.000040 0.0000172 0.0000093 0.000029 0.000027 2015 10 6 57301 0.208149 0.306281 0.2227439 0.0013024 0.000057 -0.000073 0.000037 0.000040 0.0000071 0.0000093 0.000029 0.000027 2015 10 7 57302 0.207375 0.304666 0.2214187 0.0013588 -0.000034 -0.000119 0.000037 0.000040 0.0000159 0.0000093 0.000029 0.000027 2015 10 8 57303 0.206673 0.303281 0.2200277 0.0013979 0.000022 -0.000152 0.000037 0.000040 0.0000236 0.0000093 0.000029 0.000027 2015 10 9 57304 0.205782 0.302045 0.2186087 0.0014613 0.000129 -0.000174 0.000037 0.000040 0.0000082 0.0000092 0.000029 0.000027 2015 10 10 57305 0.204276 0.300741 0.2170719 0.0015849 0.000128 -0.000174 0.000037 0.000040 0.0000132 0.0000092 0.000028 0.000026 2015 10 11 57306 0.202050 0.299171 0.2154596 0.0016419 0.000127 -0.000173 0.000037 0.000040 0.0000150 0.0000092 0.000028 0.000026 2015 10 12 57307 0.199937 0.297475 0.2138063 0.0016621 0.000127 -0.000172 0.000037 0.000040 0.0000198 0.0000092 0.000028 0.000026 2015 10 13 57308 0.197933 0.295795 0.2121604 0.0016252 0.000126 -0.000171 0.000037 0.000040 0.0000157 0.0000091 0.000028 0.000026 2015 10 14 57309 0.195960 0.294054 0.2105428 0.0015690 0.000125 -0.000170 0.000037 0.000040 0.0000057 0.0000091 0.000028 0.000026 2015 10 15 57310 0.193973 0.292087 0.2090434 0.0014527 0.000096 -0.000143 0.000037 0.000040 0.0000045 0.0000091 0.000028 0.000026 2015 10 16 57311 0.192073 0.290384 0.2076127 0.0013854 0.000059 -0.000109 0.000037 0.000040 0.0000056 0.0000091 0.000028 0.000026 2015 10 17 57312 0.190031 0.288956 0.2061891 0.0014458 0.000037 -0.000107 0.000037 0.000040 0.0000081 0.0000090 0.000027 0.000026 2015 10 18 57313 0.188309 0.287256 0.2047354 0.0015338 0.000021 -0.000117 0.000037 0.000040 0.0000169 0.0000090 0.000027 0.000025 2015 10 19 57314 0.186830 0.285661 0.2032274 0.0015544 0.000005 -0.000127 0.000037 0.000040 0.0000143 0.0000090 0.000027 0.000025 2015 10 20 57315 0.185734 0.284268 0.2016548 0.0015483 -0.000011 -0.000137 0.000038 0.000040 0.0000047 0.0000090 0.000027 0.000025 2015 10 21 57316 0.184796 0.283258 0.2000859 0.0015983 -0.000001 -0.000150 0.000038 0.000040 0.0000042 0.0000090 0.000027 0.000025 2015 10 22 57317 0.183750 0.282419 0.1983957 0.0017636 0.000015 -0.000164 0.000038 0.000040 0.0000061 0.0000090 0.000027 0.000026 2015 10 23 57318 0.182457 0.281561 0.1965255 0.0019671 0.000032 -0.000179 0.000038 0.000040 0.0000080 0.0000090 0.000027 0.000026 2015 10 24 57319 0.180741 0.280341 0.1944588 0.0021294 0.000023 -0.000163 0.000038 0.000040 0.0000339 0.0000090 0.000027 0.000026 2015 10 25 57320 0.179087 0.278953 0.1922366 0.0022674 0.000004 -0.000136 0.000038 0.000040 0.0000369 0.0000090 0.000027 0.000026 2015 10 26 57321 0.178033 0.277787 0.1899316 0.0023240 -0.000015 -0.000110 0.000038 0.000040 0.0000219 0.0000089 0.000027 0.000026 2015 10 27 57322 0.177413 0.276646 0.1876564 0.0022558 -0.000034 -0.000083 0.000038 0.000040 0.0000060 0.0000089 0.000027 0.000026 2015 10 28 57323 0.176411 0.275698 0.1854603 0.0021072 -0.000043 -0.000076 0.000038 0.000040 0.0000093 0.0000089 0.000027 0.000026 2015 10 29 57324 0.174571 0.275037 0.1834430 0.0019115 -0.000049 -0.000075 0.000038 0.000040 0.0000147 0.0000089 0.000027 0.000026 2015 10 30 57325 0.171913 0.274124 0.1816532 0.0017204 -0.000055 -0.000074 0.000038 0.000040 0.0000086 0.0000089 0.000027 0.000026 2015 10 31 57326 0.168767 0.272504 0.1800455 0.0015679 -0.000048 -0.000073 0.000038 0.000040 0.0000092 0.0000089 0.000027 0.000027 2015 11 1 57327 0.166102 0.270756 0.1785271 0.0014978 -0.000036 -0.000074 0.000038 0.000040 0.0000093 0.0000089 0.000027 0.000027 2015 11 2 57328 0.164164 0.269336 0.1770174 0.0014665 -0.000023 -0.000074 0.000038 0.000040 0.0000219 0.0000089 0.000027 0.000027 2015 11 3 57329 0.162376 0.268477 0.1755891 0.0014161 -0.000011 -0.000074 0.000038 0.000040 0.0000195 0.0000089 0.000027 0.000027 2015 11 4 57330 0.160989 0.267865 0.1741802 0.0014240 0.000001 -0.000075 0.000038 0.000040 0.0000072 0.0000088 0.000027 0.000027 2015 11 5 57331 0.159855 0.267521 0.1727222 0.0014698 -0.000002 -0.000062 0.000038 0.000040 0.0000052 0.0000088 0.000027 0.000027 2015 11 6 57332 0.158045 0.267044 0.1712218 0.0015440 -0.000009 -0.000046 0.000038 0.000040 0.0000060 0.0000088 0.000028 0.000027 2015 11 7 57333 0.155981 0.266166 0.1696517 0.0016072 -0.000015 -0.000056 0.000038 0.000040 0.0000097 0.0000088 0.000028 0.000028 2015 11 8 57334 0.154401 0.265069 0.1680337 0.0016029 -0.000021 -0.000076 0.000038 0.000040 0.0000087 0.0000088 0.000028 0.000028 2015 11 9 57335 0.153131 0.264120 0.1664352 0.0015866 -0.000027 -0.000096 0.000038 0.000040 0.0000110 0.0000088 0.000028 0.000028 2015 11 10 57336 0.151410 0.263461 0.1648736 0.0015325 -0.000032 -0.000117 0.000038 0.000040 0.0000163 0.0000088 0.000028 0.000028 2015 11 11 57337 0.149725 0.262706 0.1633551 0.0014850 -0.000020 -0.000100 0.000038 0.000040 0.0000193 0.0000088 0.000028 0.000028 2015 11 12 57338 0.148063 0.261849 0.1618895 0.0014473 -0.000022 -0.000153 0.000038 0.000040 0.0000189 0.0000088 0.000028 0.000029 2015 11 13 57339 0.146286 0.260988 0.1604744 0.0013727 -0.000044 -0.000124 0.000038 0.000039 0.0000079 0.0000088 0.000028 0.000029 2015 11 14 57340 0.144424 0.260057 0.1590894 0.0013568 -0.000042 -0.000102 0.000038 0.000039 0.0000124 0.0000088 0.000028 0.000029 2015 11 15 57341 0.142668 0.259258 0.1577298 0.0013755 -0.000029 -0.000096 0.000038 0.000039 0.0000109 0.0000088 0.000029 0.000029 2015 11 16 57342 0.140839 0.258822 0.1563511 0.0014358 -0.000017 -0.000089 0.000038 0.000039 0.0000064 0.0000088 0.000029 0.000029 2015 11 17 57343 0.138874 0.258473 0.1549210 0.0014657 -0.000004 -0.000083 0.000038 0.000039 0.0000033 0.0000088 0.000029 0.000028 2015 11 18 57344 0.136905 0.257749 0.1534481 0.0015220 -0.000059 0.000006 0.000038 0.000039 0.0000099 0.0000088 0.000029 0.000029 2015 11 19 57345 0.134535 0.257018 0.1518866 0.0015938 -0.000101 -0.000002 0.000038 0.000039 0.0000152 0.0000088 0.000029 0.000029 2015 11 20 57346 0.132085 0.256178 0.1502557 0.0016779 -0.000068 -0.000176 0.000038 0.000039 0.0000062 0.0000088 0.000029 0.000029 2015 11 21 57347 0.129930 0.255587 0.1484979 0.0017774 -0.000039 -0.000203 0.000038 0.000039 0.0000106 0.0000088 0.000029 0.000029 2015 11 22 57348 0.127901 0.255440 0.1466954 0.0018304 -0.000019 -0.000158 0.000038 0.000039 0.0000102 0.0000088 0.000029 0.000029 2015 11 23 57349 0.125580 0.255259 0.1448629 0.0018344 0.000001 -0.000114 0.000038 0.000039 0.0000087 0.0000087 0.000029 0.000029 2015 11 24 57350 0.123036 0.254725 0.1430745 0.0017535 0.000021 -0.000069 0.000038 0.000039 0.0000092 0.0000087 0.000029 0.000028 2015 11 25 57351 0.120691 0.254103 0.1413786 0.0016550 -0.000031 -0.000075 0.000038 0.000039 0.0000069 0.0000087 0.000029 0.000028 2015 11 26 57352 0.119422 0.254087 0.1398214 0.0015465 -0.000059 -0.000105 0.000038 0.000039 0.0000067 0.0000087 0.000029 0.000028 2015 11 27 57353 0.118458 0.254320 0.1383787 0.0013901 -0.000067 -0.000119 0.000038 0.000039 0.0000076 0.0000087 0.000029 0.000028 2015 11 28 57354 0.117751 0.254358 0.1369969 0.0013537 -0.000073 -0.000125 0.000038 0.000039 0.0000085 0.0000087 0.000029 0.000028 2015 11 29 57355 0.116428 0.254428 0.1355960 0.0014299 -0.000079 -0.000130 0.000038 0.000039 0.0000103 0.0000087 0.000028 0.000028 2015 11 30 57356 0.114569 0.254059 0.1341305 0.0014981 -0.000086 -0.000135 0.000038 0.000039 0.0000081 0.0000087 0.000028 0.000028 2015 12 1 57357 0.112664 0.253828 0.1325921 0.0015792 -0.000092 -0.000141 0.000038 0.000039 0.0000039 0.0000087 0.000028 0.000027 2015 12 2 57358 0.110580 0.253555 0.1309918 0.0016377 -0.000069 -0.000120 0.000038 0.000040 0.0000088 0.0000087 0.000028 0.000027 2015 12 3 57359 0.108713 0.253248 0.1293286 0.0017014 -0.000037 -0.000093 0.000038 0.000040 0.0000139 0.0000087 0.000028 0.000027 2015 12 4 57360 0.107155 0.253293 0.1276232 0.0016930 0.000036 -0.000062 0.000038 0.000040 0.0000104 0.0000087 0.000028 0.000027 2015 12 5 57361 0.105923 0.253126 0.1259459 0.0016636 0.000036 -0.000057 0.000038 0.000040 0.0000077 0.0000087 0.000028 0.000027 2015 12 6 57362 0.104955 0.252928 0.1242876 0.0016503 0.000004 -0.000061 0.000038 0.000040 0.0000105 0.0000087 0.000028 0.000027 2015 12 7 57363 0.103606 0.252731 0.1226034 0.0016810 -0.000029 -0.000065 0.000038 0.000040 0.0000090 0.0000086 0.000028 0.000027 2015 12 8 57364 0.102372 0.252184 0.1209410 0.0016653 -0.000061 -0.000069 0.000038 0.000040 0.0000041 0.0000086 0.000028 0.000027 2015 12 9 57365 0.101135 0.251610 0.1193057 0.0016217 -0.000109 -0.000088 0.000038 0.000040 0.0000037 0.0000086 0.000028 0.000027 2015 12 10 57366 0.099216 0.251255 0.1177301 0.0015634 -0.000148 -0.000104 0.000038 0.000040 0.0000044 0.0000086 0.000028 0.000027 2015 12 11 57367 0.096409 0.250768 0.1162190 0.0014753 -0.000184 -0.000118 0.000038 0.000040 0.0000052 0.0000086 0.000028 0.000027 2015 12 12 57368 0.093842 0.250509 0.1147890 0.0014301 -0.000171 -0.000121 0.000038 0.000040 0.0000092 0.0000085 0.000028 0.000028 2015 12 13 57369 0.091502 0.250520 0.1133847 0.0013892 -0.000140 -0.000121 0.000038 0.000040 0.0000074 0.0000085 0.000028 0.000028 2015 12 14 57370 0.089378 0.250595 0.1119775 0.0014084 -0.000109 -0.000120 0.000038 0.000040 0.0000045 0.0000085 0.000028 0.000028 2015 12 15 57371 0.087121 0.250740 0.1105065 0.0015095 -0.000078 -0.000120 0.000038 0.000040 0.0000028 0.0000085 0.000028 0.000028 2015 12 16 57372 0.085009 0.250349 0.1089304 0.0016321 -0.000224 0.000072 0.000038 0.000040 0.0000206 0.0000085 0.000028 0.000028 2015 12 17 57373 0.083462 0.249879 0.1072276 0.0017403 -0.000223 0.000083 0.000038 0.000040 0.0000371 0.0000085 0.000029 0.000028 2015 12 18 57374 0.082049 0.250132 0.1054034 0.0018793 -0.000117 -0.000111 0.000038 0.000040 0.0000292 0.0000085 0.000029 0.000029 2015 12 19 57375 0.080121 0.250779 0.1034897 0.0019660 -0.000085 -0.000178 0.000038 0.000040 0.0000188 0.0000084 0.000029 0.000029 2015 12 20 57376 0.078021 0.251184 0.1014947 0.0020065 -0.000085 -0.000182 0.000038 0.000040 0.0000160 0.0000084 0.000029 0.000029 2015 12 21 57377 0.075738 0.251428 0.0995085 0.0019283 -0.000085 -0.000185 0.000038 0.000040 0.0000119 0.0000084 0.000029 0.000029 2015 12 22 57378 0.073389 0.251567 0.0976170 0.0018040 -0.000085 -0.000189 0.000038 0.000040 0.0000051 0.0000084 0.000029 0.000029 2015 12 23 57379 0.071317 0.251618 0.0958869 0.0016556 0.000005 -0.000008 0.000038 0.000040 0.0000031 0.0000084 0.000029 0.000029 2015 12 24 57380 0.069043 0.252123 0.0943447 0.0015032 0.000021 0.000047 0.000038 0.000040 0.0000052 0.0000084 0.000029 0.000029 2015 12 25 57381 0.066432 0.253019 0.0929084 0.0014242 0.000001 0.000037 0.000038 0.000040 0.0000084 0.0000084 0.000029 0.000029 2015 12 26 57382 0.063927 0.253405 0.0915019 0.0014033 -0.000019 0.000027 0.000038 0.000039 0.0000116 0.0000084 0.000030 0.000029 2015 12 27 57383 0.061886 0.253809 0.0900897 0.0014386 -0.000039 0.000018 0.000038 0.000039 0.0000161 0.0000084 0.000030 0.000030 2015 12 28 57384 0.059652 0.254404 0.0885825 0.0015334 -0.000059 0.000008 0.000038 0.000040 0.0000133 0.0000084 0.000030 0.000030 2015 12 29 57385 0.057516 0.254957 0.0869674 0.0016433 -0.000079 -0.000002 0.000038 0.000040 0.0000065 0.0000084 0.000030 0.000030 2015 12 30 57386 0.055374 0.255689 0.0852533 0.0017386 -0.000188 0.000052 0.000038 0.000040 0.0000041 0.0000084 0.000030 0.000030 2015 12 31 57387 0.053399 0.256161 0.0834255 0.0018316 -0.000210 0.000056 0.000038 0.000040 0.0000133 0.0000084 0.000030 0.000030 2016 1 1 57388 0.051152 0.256768 0.0815311 0.0019440 -0.000196 0.000053 0.000059 0.000045 0.0000212 0.0000142 0.000035 0.000032 2016 1 2 57389 0.048842 0.257368 0.0796376 0.0019247 -0.000175 0.000032 0.000059 0.000045 0.0000152 0.0000142 0.000035 0.000032 2016 1 3 57390 0.047033 0.257664 0.0777240 0.0019192 -0.000154 0.000011 0.000059 0.000045 0.0000132 0.0000142 0.000035 0.000032 2016 1 4 57391 0.045667 0.258493 0.0757783 0.0019464 -0.000133 -0.000010 0.000059 0.000045 0.0000102 0.0000142 0.000035 0.000032 2016 1 5 57392 0.044153 0.260161 0.0738438 0.0018880 -0.000111 -0.000031 0.000059 0.000045 0.0000057 0.0000142 0.000034 0.000032 2016 1 6 57393 0.042266 0.261822 0.0719583 0.0018752 -0.000083 -0.000086 0.000059 0.000045 0.0000065 0.0000143 0.000034 0.000032 2016 1 7 57394 0.040622 0.263290 0.0701201 0.0018211 -0.000052 -0.000150 0.000058 0.000045 0.0000086 0.0000143 0.000035 0.000032 2016 1 8 57395 0.039556 0.265043 0.0683188 0.0017789 -0.000021 -0.000213 0.000058 0.000045 0.0000106 0.0000143 0.000035 0.000032 2016 1 9 57396 0.037950 0.267199 0.0665714 0.0017627 -0.000046 -0.000182 0.000058 0.000045 0.0000116 0.0000143 0.000034 0.000031 2016 1 10 57397 0.035859 0.268880 0.0648150 0.0017891 -0.000091 -0.000117 0.000058 0.000045 0.0000150 0.0000144 0.000034 0.000031 2016 1 11 57398 0.034212 0.270663 0.0629732 0.0018826 -0.000136 -0.000051 0.000058 0.000045 0.0000183 0.0000144 0.000034 0.000031 2016 1 12 57399 0.032690 0.272535 0.0610318 0.0019873 -0.000156 -0.000026 0.000058 0.000045 0.0000161 0.0000144 0.000034 0.000030 2016 1 13 57400 0.031105 0.274426 0.0589932 0.0021027 -0.000093 -0.000136 0.000058 0.000045 0.0000060 0.0000145 0.000034 0.000030 2016 1 14 57401 0.029487 0.275674 0.0568475 0.0022124 -0.000058 -0.000114 0.000058 0.000045 0.0000063 0.0000145 0.000034 0.000030 2016 1 15 57402 0.028220 0.276671 0.0546433 0.0021994 -0.000145 -0.000126 0.000058 0.000044 0.0000094 0.0000145 0.000034 0.000030 2016 1 16 57403 0.026690 0.278122 0.0524926 0.0021257 -0.000168 -0.000115 0.000058 0.000044 0.0000143 0.0000146 0.000034 0.000030 2016 1 17 57404 0.024996 0.279528 0.0504060 0.0020493 -0.000155 -0.000086 0.000057 0.000044 0.0000122 0.0000146 0.000033 0.000029 2016 1 18 57405 0.023229 0.281340 0.0483894 0.0019451 -0.000142 -0.000057 0.000057 0.000044 0.0000083 0.0000147 0.000033 0.000029 2016 1 19 57406 0.021297 0.283184 0.0464968 0.0018298 -0.000130 -0.000029 0.000057 0.000044 0.0000053 0.0000147 0.000033 0.000029 2016 1 20 57407 0.018978 0.285065 0.0447528 0.0016883 -0.000156 -0.000131 0.000057 0.000044 0.0000203 0.0000148 0.000033 0.000029 2016 1 21 57408 0.016411 0.286465 0.0431234 0.0015924 -0.000122 -0.000106 0.000058 0.000044 0.0000288 0.0000148 0.000033 0.000029 2016 1 22 57409 0.013862 0.287801 0.0415616 0.0015388 -0.000067 -0.000032 0.000058 0.000044 0.0000105 0.0000148 0.000033 0.000029 2016 1 23 57410 0.010999 0.288857 0.0400087 0.0015775 -0.000084 -0.000047 0.000058 0.000044 0.0000169 0.0000148 0.000033 0.000029 2016 1 24 57411 0.008498 0.289400 0.0384439 0.0016348 -0.000128 -0.000096 0.000058 0.000044 0.0000185 0.0000149 0.000034 0.000030 2016 1 25 57412 0.006727 0.289848 0.0368283 0.0016124 -0.000171 -0.000144 0.000058 0.000044 0.0000153 0.0000149 0.000034 0.000030 2016 1 26 57413 0.005614 0.290553 0.0351993 0.0016113 -0.000215 -0.000192 0.000058 0.000044 0.0000369 0.0000149 0.000034 0.000030 2016 1 27 57414 0.004646 0.291738 0.0335758 0.0016191 -0.000086 -0.000102 0.000058 0.000044 0.0000732 0.0000149 0.000034 0.000030 2016 1 28 57415 0.003464 0.293011 0.0319966 0.0015451 0.000024 -0.000074 0.000058 0.000044 0.0000523 0.0000149 0.000034 0.000030 2016 1 29 57416 0.002295 0.294099 0.0304597 0.0015319 -0.000002 -0.000115 0.000058 0.000045 0.0000166 0.0000150 0.000034 0.000030 2016 1 30 57417 0.000856 0.295760 0.0289753 0.0014524 -0.000038 -0.000117 0.000058 0.000045 0.0000141 0.0000150 0.000034 0.000031 2016 1 31 57418 -0.001322 0.297566 0.0275838 0.0013131 -0.000063 -0.000099 0.000058 0.000045 0.0000178 0.0000150 0.000035 0.000031 2016 2 1 57419 -0.003328 0.299556 0.0262579 0.0012906 -0.000089 -0.000081 0.000059 0.000045 0.0000130 0.0000150 0.000035 0.000031 2016 2 2 57420 -0.004797 0.301385 0.0249918 0.0012604 -0.000114 -0.000063 0.000059 0.000045 0.0000055 0.0000151 0.000035 0.000031 2016 2 3 57421 -0.005710 0.302684 0.0237813 0.0012092 -0.000100 -0.000083 0.000059 0.000045 0.0000052 0.0000151 0.000035 0.000032 2016 2 4 57422 -0.006449 0.304508 0.0225960 0.0011889 -0.000082 -0.000081 0.000059 0.000045 0.0000067 0.0000152 0.000035 0.000032 2016 2 5 57423 -0.007507 0.306500 0.0213968 0.0011780 -0.000065 -0.000071 0.000059 0.000045 0.0000083 0.0000152 0.000036 0.000032 2016 2 6 57424 -0.008681 0.308137 0.0201401 0.0013136 -0.000073 -0.000075 0.000059 0.000045 0.0000182 0.0000153 0.000036 0.000032 2016 2 7 57425 -0.009586 0.309827 0.0187401 0.0015140 -0.000091 -0.000084 0.000059 0.000045 0.0000225 0.0000153 0.000036 0.000033 2016 2 8 57426 -0.009637 0.311463 0.0171296 0.0016983 -0.000108 -0.000093 0.000059 0.000045 0.0000166 0.0000154 0.000036 0.000033 2016 2 9 57427 -0.009694 0.313165 0.0153150 0.0018781 -0.000126 -0.000102 0.000060 0.000045 0.0000077 0.0000154 0.000037 0.000034 2016 2 10 57428 -0.009868 0.314978 0.0133295 0.0020506 -0.000147 -0.000055 0.000060 0.000045 0.0000160 0.0000155 0.000037 0.000034 2016 2 11 57429 -0.010539 0.317140 0.0112354 0.0020868 -0.000144 -0.000069 0.000060 0.000045 0.0000239 0.0000155 0.000037 0.000034 2016 2 12 57430 -0.011225 0.319009 0.0091523 0.0020513 -0.000191 -0.000083 0.000060 0.000045 0.0000134 0.0000155 0.000038 0.000035 2016 2 13 57431 -0.011910 0.321091 0.0071486 0.0019540 -0.000204 -0.000075 0.000060 0.000045 0.0000177 0.0000156 0.000038 0.000035 2016 2 14 57432 -0.012498 0.323297 0.0052577 0.0018157 -0.000197 -0.000062 0.000060 0.000045 0.0000208 0.0000156 0.000038 0.000035 2016 2 15 57433 -0.013087 0.325399 0.0035034 0.0016667 -0.000190 -0.000048 0.000060 0.000045 0.0000164 0.0000156 0.000038 0.000035 2016 2 16 57434 -0.013939 0.327088 0.0019068 0.0015268 -0.000184 -0.000035 0.000060 0.000045 0.0000098 0.0000157 0.000038 0.000035 2016 2 17 57435 -0.014740 0.328481 0.0004702 0.0013776 -0.000199 0.000074 0.000060 0.000045 0.0000245 0.0000157 0.000039 0.000035 2016 2 18 57436 -0.015988 0.330427 -0.0008679 0.0012886 -0.000136 0.000018 0.000060 0.000045 0.0000360 0.0000157 0.000039 0.000035 2016 2 19 57437 -0.017369 0.332407 -0.0021484 0.0012948 -0.000047 -0.000093 0.000060 0.000045 0.0000148 0.0000157 0.000039 0.000035 2016 2 20 57438 -0.018661 0.334094 -0.0034600 0.0013740 -0.000046 -0.000111 0.000060 0.000045 0.0000148 0.0000158 0.000039 0.000035 2016 2 21 57439 -0.019368 0.335478 -0.0048806 0.0014910 -0.000077 -0.000093 0.000060 0.000045 0.0000190 0.0000158 0.000039 0.000035 2016 2 22 57440 -0.019902 0.337640 -0.0064281 0.0015985 -0.000108 -0.000075 0.000060 0.000045 0.0000148 0.0000158 0.000039 0.000035 2016 2 23 57441 -0.020930 0.339857 -0.0080755 0.0016762 -0.000139 -0.000058 0.000060 0.000045 0.0000075 0.0000159 0.000039 0.000035 2016 2 24 57442 -0.021637 0.342085 -0.0097951 0.0017372 -0.000447 -0.000185 0.000060 0.000045 0.0000157 0.0000159 0.000039 0.000035 2016 2 25 57443 -0.021940 0.344439 -0.0115755 0.0018358 -0.000398 -0.000123 0.000060 0.000045 0.0000233 0.0000159 0.000039 0.000035 2016 2 26 57444 -0.022045 0.346329 -0.0134142 0.0018353 -0.000199 -0.000044 0.000060 0.000045 0.0000132 0.0000159 0.000039 0.000035 2016 2 27 57445 -0.022289 0.348436 -0.0152085 0.0017630 -0.000133 -0.000042 0.000060 0.000045 0.0000153 0.0000160 0.000039 0.000035 2016 2 28 57446 -0.023277 0.350847 -0.0169590 0.0017169 -0.000118 -0.000062 0.000060 0.000045 0.0000205 0.0000160 0.000039 0.000034 2016 2 29 57447 -0.024279 0.352883 -0.0186780 0.0017251 -0.000103 -0.000082 0.000060 0.000045 0.0000165 0.0000160 0.000039 0.000034 2016 3 1 57448 -0.024973 0.354461 -0.0203641 0.0016496 -0.000087 -0.000103 0.000060 0.000045 0.0000083 0.0000161 0.000039 0.000034 2016 3 2 57449 -0.024706 0.355922 -0.0220462 0.0016720 -0.000073 -0.000068 0.000060 0.000045 0.0000078 0.0000161 0.000039 0.000034 2016 3 3 57450 -0.024044 0.357842 -0.0237308 0.0017206 -0.000058 -0.000018 0.000060 0.000045 0.0000092 0.0000161 0.000039 0.000034 2016 3 4 57451 -0.023669 0.360214 -0.0254463 0.0017331 -0.000043 0.000031 0.000060 0.000045 0.0000106 0.0000162 0.000039 0.000034 2016 3 5 57452 -0.023810 0.362640 -0.0272269 0.0018577 -0.000027 0.000019 0.000060 0.000045 0.0000159 0.0000162 0.000039 0.000034 2016 3 6 57453 -0.023671 0.365052 -0.0292061 0.0020488 -0.000010 -0.000016 0.000060 0.000045 0.0000227 0.0000163 0.000039 0.000034 2016 3 7 57454 -0.024052 0.367592 -0.0313092 0.0022054 0.000007 -0.000051 0.000060 0.000045 0.0000180 0.0000163 0.000039 0.000034 2016 3 8 57455 -0.024476 0.370073 -0.0335557 0.0022947 0.000024 -0.000085 0.000060 0.000045 0.0000076 0.0000163 0.000039 0.000034 2016 3 9 57456 -0.024878 0.372544 -0.0359172 0.0023851 -0.000008 -0.000064 0.000060 0.000045 0.0000123 0.0000164 0.000040 0.000035 2016 3 10 57457 -0.025122 0.374941 -0.0383731 0.0024776 -0.000052 -0.000027 0.000060 0.000045 0.0000178 0.0000164 0.000040 0.000035 2016 3 11 57458 -0.025091 0.377069 -0.0408670 0.0024413 -0.000097 0.000009 0.000060 0.000045 0.0000109 0.0000164 0.000041 0.000036 2016 3 12 57459 -0.025193 0.378968 -0.0432775 0.0023569 -0.000093 0.000017 0.000060 0.000045 0.0000135 0.0000164 0.000041 0.000037 2016 3 13 57460 -0.025306 0.380843 -0.0455735 0.0022081 -0.000072 0.000015 0.000060 0.000045 0.0000161 0.0000164 0.000041 0.000037 2016 3 14 57461 -0.024822 0.382618 -0.0477393 0.0020945 -0.000050 0.000012 0.000060 0.000045 0.0000127 0.0000163 0.000042 0.000038 2016 3 15 57462 -0.024022 0.384795 -0.0497668 0.0019461 -0.000029 0.000010 0.000059 0.000045 0.0000070 0.0000163 0.000042 0.000038 2016 3 16 57463 -0.022801 0.387139 -0.0516599 0.0018421 -0.000147 -0.000109 0.000059 0.000045 0.0000190 0.0000163 0.000043 0.000039 2016 3 17 57464 -0.020890 0.389461 -0.0534883 0.0018373 -0.000191 -0.000012 0.000059 0.000045 0.0000285 0.0000162 0.000044 0.000040 2016 3 18 57465 -0.018313 0.392010 -0.0552844 0.0018170 -0.000082 0.000080 0.000059 0.000045 0.0000106 0.0000162 0.000044 0.000041 2016 3 19 57466 -0.016112 0.394477 -0.0571439 0.0018948 -0.000054 0.000081 0.000059 0.000045 0.0000150 0.0000161 0.000045 0.000042 2016 3 20 57467 -0.014503 0.396999 -0.0590834 0.0019925 -0.000071 0.000058 0.000059 0.000045 0.0000162 0.0000161 0.000045 0.000042 2016 3 21 57468 -0.013710 0.399530 -0.0611071 0.0020901 -0.000088 0.000035 0.000059 0.000045 0.0000119 0.0000160 0.000046 0.000043 2016 3 22 57469 -0.013517 0.402065 -0.0631927 0.0020973 -0.000105 0.000013 0.000059 0.000045 0.0000077 0.0000159 0.000046 0.000044 2016 3 23 57470 -0.013682 0.404393 -0.0652635 0.0020860 -0.000240 0.000146 0.000059 0.000045 0.0000111 0.0000159 0.000047 0.000045 2016 3 24 57471 -0.013706 0.406417 -0.0673267 0.0020113 -0.000257 0.000188 0.000058 0.000045 0.0000166 0.0000158 0.000047 0.000046 2016 3 25 57472 -0.013303 0.408441 -0.0693774 0.0020276 -0.000233 0.000165 0.000058 0.000045 0.0000163 0.0000158 0.000047 0.000046 2016 3 26 57473 -0.012660 0.410478 -0.0713853 0.0020450 -0.000210 0.000133 0.000058 0.000045 0.0000158 0.0000157 0.000048 0.000046 2016 3 27 57474 -0.011884 0.412670 -0.0733848 0.0019707 -0.000188 0.000101 0.000058 0.000045 0.0000174 0.0000157 0.000048 0.000046 2016 3 28 57475 -0.011143 0.414543 -0.0753197 0.0018830 -0.000165 0.000069 0.000058 0.000045 0.0000150 0.0000157 0.000048 0.000047 2016 3 29 57476 -0.010316 0.416384 -0.0771721 0.0018257 -0.000142 0.000037 0.000058 0.000045 0.0000119 0.0000156 0.000048 0.000047 2016 3 30 57477 -0.009370 0.418043 -0.0789646 0.0017604 -0.000120 0.000005 0.000058 0.000046 0.0000087 0.0000156 0.000048 0.000047 2016 3 31 57478 -0.008734 0.419766 -0.0807077 0.0017370 -0.000071 0.000026 0.000059 0.000046 0.0000080 0.0000156 0.000048 0.000048 2016 4 1 57479 -0.008461 0.421248 -0.0824550 0.0017700 -0.000058 0.000069 0.000059 0.000046 0.0000080 0.0000156 0.000048 0.000048 2016 4 2 57480 -0.008136 0.422708 -0.0842540 0.0018564 -0.000052 0.000164 0.000059 0.000046 0.0000093 0.0000155 0.000048 0.000048 2016 4 3 57481 -0.007657 0.424142 -0.0861405 0.0019470 0.000045 0.000131 0.000059 0.000046 0.0000093 0.0000155 0.000048 0.000048 2016 4 4 57482 -0.006509 0.425845 -0.0881463 0.0020879 0.000092 0.000009 0.000059 0.000046 0.0000077 0.0000155 0.000048 0.000048 2016 4 5 57483 -0.004836 0.427915 -0.0903044 0.0022195 0.000001 -0.000055 0.000060 0.000046 0.0000057 0.0000155 0.000048 0.000047 2016 4 6 57484 -0.002559 0.429858 -0.0925838 0.0023333 -0.000103 0.000060 0.000060 0.000046 0.0000109 0.0000155 0.000048 0.000048 2016 4 7 57485 -0.000754 0.432237 -0.0949320 0.0023360 -0.000103 0.000132 0.000060 0.000046 0.0000150 0.0000155 0.000048 0.000048 2016 4 8 57486 0.000641 0.434748 -0.0972855 0.0023206 -0.000128 0.000074 0.000060 0.000046 0.0000078 0.0000155 0.000047 0.000048 2016 4 9 57487 0.002066 0.437150 -0.0995828 0.0022217 -0.000113 0.000068 0.000060 0.000046 0.0000148 0.0000155 0.000047 0.000047 2016 4 10 57488 0.003303 0.439073 -0.1017106 0.0020390 -0.000075 0.000094 0.000060 0.000046 0.0000145 0.0000155 0.000047 0.000047 2016 4 11 57489 0.004570 0.441005 -0.1036653 0.0018538 -0.000038 0.000120 0.000060 0.000046 0.0000109 0.0000155 0.000047 0.000047 2016 4 12 57490 0.006073 0.442728 -0.1054787 0.0017374 -0.000001 0.000146 0.000061 0.000046 0.0000088 0.0000155 0.000047 0.000047 2016 4 13 57491 0.007766 0.444248 -0.1071537 0.0016337 0.000231 0.000219 0.000061 0.000046 0.0000136 0.0000155 0.000047 0.000047 2016 4 14 57492 0.009075 0.445669 -0.1087588 0.0015514 0.000194 0.000190 0.000061 0.000046 0.0000181 0.0000155 0.000047 0.000047 2016 4 15 57493 0.010432 0.447448 -0.1103011 0.0015700 0.000062 0.000127 0.000061 0.000046 0.0000142 0.0000154 0.000047 0.000046 2016 4 16 57494 0.011906 0.449649 -0.1119013 0.0016225 0.000033 0.000102 0.000061 0.000046 0.0000124 0.0000154 0.000047 0.000046 2016 4 17 57495 0.013613 0.451939 -0.1135368 0.0016399 0.000043 0.000092 0.000061 0.000046 0.0000147 0.0000154 0.000047 0.000046 2016 4 18 57496 0.015467 0.454135 -0.1152136 0.0017172 0.000052 0.000081 0.000061 0.000046 0.0000134 0.0000153 0.000047 0.000045 2016 4 19 57497 0.017033 0.455945 -0.1169144 0.0017531 0.000061 0.000071 0.000061 0.000046 0.0000095 0.0000153 0.000047 0.000045 2016 4 20 57498 0.018493 0.456808 -0.1186274 0.0017356 0.000014 0.000152 0.000061 0.000046 0.0000136 0.0000153 0.000047 0.000044 2016 4 21 57499 0.020289 0.457653 -0.1203189 0.0016876 -0.000092 0.000209 0.000061 0.000046 0.0000185 0.0000152 0.000047 0.000045 2016 4 22 57500 0.022010 0.458695 -0.1219770 0.0016384 0.000005 0.000124 0.000061 0.000046 0.0000187 0.0000152 0.000048 0.000046 2016 4 23 57501 0.024057 0.460226 -0.1235732 0.0016199 0.000066 0.000103 0.000061 0.000046 0.0000125 0.0000152 0.000048 0.000046 2016 4 24 57502 0.025770 0.461901 -0.1250957 0.0014860 0.000088 0.000121 0.000061 0.000046 0.0000124 0.0000152 0.000049 0.000047 2016 4 25 57503 0.027052 0.463501 -0.1265210 0.0013205 0.000109 0.000140 0.000061 0.000046 0.0000144 0.0000151 0.000049 0.000047 2016 4 26 57504 0.028032 0.465383 -0.1278100 0.0012194 0.000130 0.000158 0.000061 0.000046 0.0000125 0.0000151 0.000049 0.000048 2016 4 27 57505 0.028815 0.467046 -0.1290383 0.0012411 0.000152 0.000177 0.000061 0.000046 0.0000095 0.0000151 0.000050 0.000048 2016 4 28 57506 0.029665 0.468574 -0.1303342 0.0013327 0.000147 0.000169 0.000061 0.000046 0.0000101 0.0000151 0.000050 0.000049 2016 4 29 57507 0.030492 0.469965 -0.1317046 0.0014406 0.000136 0.000154 0.000061 0.000046 0.0000116 0.0000151 0.000050 0.000050 2016 4 30 57508 0.032080 0.470879 -0.1331866 0.0015611 0.000126 0.000142 0.000061 0.000046 0.0000094 0.0000151 0.000051 0.000051 2016 5 1 57509 0.034534 0.472283 -0.1347965 0.0017072 0.000117 0.000131 0.000061 0.000046 0.0000091 0.0000150 0.000051 0.000052 2016 5 2 57510 0.036661 0.474024 -0.1365722 0.0018511 0.000107 0.000120 0.000061 0.000046 0.0000103 0.0000150 0.000052 0.000053 2016 5 3 57511 0.038551 0.475584 -0.1385393 0.0020441 0.000098 0.000109 0.000061 0.000046 0.0000109 0.0000150 0.000052 0.000054 2016 5 4 57512 0.040634 0.476861 -0.1406800 0.0021898 0.000088 0.000097 0.000061 0.000046 0.0000100 0.0000150 0.000053 0.000055 2016 5 5 57513 0.042304 0.478048 -0.1428769 0.0021765 0.000188 0.000095 0.000061 0.000046 0.0000214 0.0000149 0.000054 0.000056 2016 5 6 57514 0.043399 0.479115 -0.1450247 0.0020809 0.000316 0.000096 0.000061 0.000046 0.0000360 0.0000149 0.000054 0.000057 2016 5 7 57515 0.044862 0.480243 -0.1470165 0.0019468 0.000319 0.000105 0.000061 0.000046 0.0000230 0.0000148 0.000055 0.000058 2016 5 8 57516 0.046556 0.481562 -0.1488460 0.0017682 0.000277 0.000117 0.000061 0.000046 0.0000141 0.0000148 0.000055 0.000059 2016 5 9 57517 0.048313 0.482876 -0.1505136 0.0015855 0.000235 0.000129 0.000061 0.000046 0.0000143 0.0000148 0.000056 0.000060 2016 5 10 57518 0.050135 0.484151 -0.1520617 0.0014446 0.000192 0.000141 0.000060 0.000046 0.0000153 0.0000147 0.000056 0.000061 2016 5 11 57519 0.052202 0.485315 -0.1534782 0.0013836 0.000057 0.000114 0.000060 0.000046 0.0000176 0.0000147 0.000056 0.000063 2016 5 12 57520 0.054252 0.486392 -0.1548696 0.0013799 -0.000102 0.000077 0.000060 0.000046 0.0000227 0.0000146 0.000057 0.000064 2016 5 13 57521 0.056354 0.487351 -0.1562749 0.0014811 -0.000031 0.000108 0.000060 0.000046 0.0000368 0.0000146 0.000057 0.000064 2016 5 14 57522 0.058409 0.488249 -0.1578092 0.0016000 0.000051 0.000164 0.000060 0.000046 0.0000257 0.0000145 0.000058 0.000065 2016 5 15 57523 0.060452 0.488861 -0.1594537 0.0016889 0.000108 0.000221 0.000060 0.000046 0.0000140 0.0000145 0.000058 0.000065 2016 5 16 57524 0.062493 0.489144 -0.1611664 0.0017591 0.000166 0.000277 0.000060 0.000046 0.0000110 0.0000144 0.000058 0.000065 2016 5 17 57525 0.064546 0.489647 -0.1629081 0.0017718 0.000223 0.000334 0.000060 0.000045 0.0000102 0.0000144 0.000058 0.000065 2016 5 18 57526 0.066361 0.490358 -0.1646480 0.0016953 0.000080 0.000113 0.000060 0.000045 0.0000093 0.0000144 0.000058 0.000065 2016 5 19 57527 0.068039 0.491179 -0.1662934 0.0016246 0.000129 0.000124 0.000060 0.000045 0.0000165 0.0000143 0.000058 0.000065 2016 5 20 57528 0.069414 0.492172 -0.1678722 0.0015272 0.000233 0.000202 0.000060 0.000045 0.0000257 0.0000143 0.000058 0.000065 2016 5 21 57529 0.070449 0.493141 -0.1693848 0.0014942 0.000243 0.000195 0.000060 0.000045 0.0000212 0.0000143 0.000058 0.000064 2016 5 22 57530 0.071111 0.493729 -0.1708410 0.0014586 0.000218 0.000155 0.000060 0.000045 0.0000141 0.0000142 0.000057 0.000064 2016 5 23 57531 0.072319 0.493842 -0.1723116 0.0014782 0.000194 0.000115 0.000060 0.000045 0.0000125 0.0000142 0.000057 0.000064 2016 5 24 57532 0.074267 0.494197 -0.1737698 0.0014557 0.000169 0.000075 0.000060 0.000045 0.0000129 0.0000141 0.000057 0.000063 2016 5 25 57533 0.076323 0.494867 -0.1751318 0.0013919 0.000087 0.000117 0.000060 0.000045 0.0000301 0.0000141 0.000057 0.000063 2016 5 26 57534 0.078685 0.495472 -0.1764903 0.0013730 -0.000009 0.000179 0.000060 0.000045 0.0000517 0.0000141 0.000057 0.000062 2016 5 27 57535 0.080860 0.496177 -0.1779051 0.0014305 -0.000106 0.000242 0.000060 0.000045 0.0000733 0.0000140 0.000057 0.000062 2016 5 28 57536 0.082653 0.496582 -0.1793940 0.0015328 -0.000102 0.000237 0.000060 0.000045 0.0000417 0.0000140 0.000056 0.000061 2016 5 29 57537 0.084898 0.496738 -0.1809659 0.0016757 -0.000062 0.000207 0.000060 0.000045 0.0000201 0.0000140 0.000056 0.000060 2016 5 30 57538 0.087791 0.496563 -0.1827392 0.0017874 -0.000021 0.000177 0.000060 0.000045 0.0000329 0.0000139 0.000055 0.000058 2016 5 31 57539 0.090397 0.496554 -0.1845600 0.0018344 0.000020 0.000147 0.000060 0.000045 0.0000292 0.0000139 0.000055 0.000057 2016 6 1 57540 0.092768 0.496642 -0.1863750 0.0018511 0.000061 0.000117 0.000060 0.000045 0.0000135 0.0000139 0.000054 0.000057 2016 6 2 57541 0.095115 0.496983 -0.1882111 0.0018021 0.000089 0.000090 0.000060 0.000045 0.0000186 0.0000139 0.000054 0.000056 2016 6 3 57542 0.097043 0.497219 -0.1899457 0.0016637 0.000113 0.000065 0.000060 0.000045 0.0000292 0.0000138 0.000054 0.000055 2016 6 4 57543 0.098815 0.497433 -0.1914782 0.0014499 0.000121 0.000050 0.000060 0.000045 0.0000203 0.0000138 0.000053 0.000054 2016 6 5 57544 0.100057 0.497503 -0.1928282 0.0012417 0.000122 0.000040 0.000060 0.000045 0.0000177 0.0000138 0.000053 0.000053 2016 6 6 57545 0.101491 0.497548 -0.1940490 0.0011530 0.000123 0.000029 0.000060 0.000045 0.0000187 0.0000138 0.000052 0.000053 2016 6 7 57546 0.102675 0.497937 -0.1951599 0.0010471 0.000125 0.000019 0.000060 0.000045 0.0000173 0.0000137 0.000052 0.000052 2016 6 8 57547 0.103601 0.497953 -0.1961923 0.0009825 0.000126 0.000008 0.000060 0.000045 0.0000139 0.0000137 0.000051 0.000051 2016 6 9 57548 0.104775 0.497770 -0.1971626 0.0009252 0.000252 0.000051 0.000060 0.000045 0.0000146 0.0000137 0.000051 0.000051 2016 6 10 57549 0.106026 0.497222 -0.1981136 0.0009080 0.000259 0.000088 0.000060 0.000045 0.0000164 0.0000137 0.000051 0.000050 2016 6 11 57550 0.107586 0.496388 -0.1990544 0.0009032 0.000220 0.000094 0.000060 0.000045 0.0000142 0.0000137 0.000051 0.000050 2016 6 12 57551 0.109445 0.495380 -0.1999716 0.0008935 0.000183 0.000092 0.000060 0.000045 0.0000134 0.0000137 0.000050 0.000049 2016 6 13 57552 0.112146 0.494212 -0.2008590 0.0008535 0.000146 0.000090 0.000060 0.000045 0.0000110 0.0000137 0.000050 0.000048 2016 6 14 57553 0.115219 0.494001 -0.2016869 0.0007761 0.000109 0.000088 0.000060 0.000045 0.0000073 0.0000137 0.000050 0.000048 2016 6 15 57554 0.117955 0.494533 -0.2024258 0.0006907 0.000074 -0.000015 0.000059 0.000045 0.0000080 0.0000137 0.000050 0.000048 2016 6 16 57555 0.120723 0.494872 -0.2030611 0.0005530 0.000067 -0.000017 0.000059 0.000045 0.0000100 0.0000136 0.000050 0.000048 2016 6 17 57556 0.123660 0.494609 -0.2035862 0.0004863 0.000070 0.000018 0.000059 0.000045 0.0000119 0.0000136 0.000050 0.000048 2016 6 18 57557 0.126273 0.494039 -0.2040250 0.0003727 0.000086 0.000028 0.000059 0.000045 0.0000124 0.0000136 0.000051 0.000048 2016 6 19 57558 0.128241 0.493253 -0.2043427 0.0003016 0.000108 0.000028 0.000059 0.000045 0.0000131 0.0000136 0.000051 0.000048 2016 6 20 57559 0.130393 0.492201 -0.2045931 0.0002314 0.000129 0.000029 0.000059 0.000045 0.0000118 0.0000136 0.000051 0.000048 2016 6 21 57560 0.132214 0.491519 -0.2048291 0.0002263 0.000151 0.000030 0.000059 0.000045 0.0000091 0.0000136 0.000051 0.000048 2016 6 22 57561 0.134110 0.490680 -0.2050920 0.0002929 0.000049 0.000096 0.000058 0.000045 0.0000184 0.0000136 0.000052 0.000049 2016 6 23 57562 0.136391 0.490257 -0.2054332 0.0004053 0.000115 0.000135 0.000058 0.000045 0.0000258 0.0000135 0.000052 0.000049 2016 6 24 57563 0.138668 0.489614 -0.2058916 0.0005418 0.000306 0.000036 0.000058 0.000045 0.0000139 0.0000135 0.000052 0.000049 2016 6 25 57564 0.140635 0.488946 -0.2065099 0.0007166 0.000311 -0.000012 0.000058 0.000045 0.0000201 0.0000135 0.000052 0.000050 2016 6 26 57565 0.142509 0.488753 -0.2073079 0.0008883 0.000238 -0.000025 0.000058 0.000045 0.0000197 0.0000134 0.000052 0.000050 2016 6 27 57566 0.144356 0.488207 -0.2082591 0.0010144 0.000165 -0.000039 0.000058 0.000045 0.0000131 0.0000134 0.000052 0.000050 2016 6 28 57567 0.146435 0.487237 -0.2093096 0.0011040 0.000092 -0.000052 0.000058 0.000045 0.0000068 0.0000134 0.000052 0.000050 2016 6 29 57568 0.148602 0.486290 -0.2104187 0.0011035 0.000125 0.000028 0.000058 0.000045 0.0000086 0.0000133 0.000052 0.000050 2016 6 30 57569 0.150223 0.485430 -0.2114917 0.0010122 0.000163 0.000062 0.000058 0.000045 0.0000110 0.0000133 0.000052 0.000050 2016 7 1 57570 0.152140 0.483905 -0.2124423 0.0009305 0.000093 0.000049 0.000057 0.000045 0.0000073 0.0000133 0.000052 0.000050 2016 7 2 57571 0.154436 0.482617 -0.2133267 0.0008295 0.000060 0.000034 0.000057 0.000045 0.0000174 0.0000133 0.000052 0.000049 2016 7 3 57572 0.156546 0.481608 -0.2140991 0.0007191 0.000053 0.000019 0.000057 0.000045 0.0000180 0.0000133 0.000051 0.000049 2016 7 4 57573 0.158553 0.480623 -0.2147379 0.0006060 0.000045 0.000005 0.000057 0.000045 0.0000153 0.0000133 0.000051 0.000048 2016 7 5 57574 0.160538 0.479588 -0.2153134 0.0005502 0.000038 -0.000009 0.000057 0.000045 0.0000147 0.0000133 0.000051 0.000048 2016 7 6 57575 0.162457 0.478505 -0.2158272 0.0005176 0.000131 0.000031 0.000057 0.000045 0.0000185 0.0000133 0.000051 0.000048 2016 7 7 57576 0.164345 0.477368 -0.2163505 0.0005176 0.000251 0.000087 0.000057 0.000045 0.0000209 0.0000133 0.000051 0.000047 2016 7 8 57577 0.166417 0.476352 -0.2169175 0.0005564 0.000286 0.000079 0.000057 0.000045 0.0000132 0.0000133 0.000051 0.000047 2016 7 9 57578 0.168576 0.475197 -0.2175113 0.0006041 0.000260 0.000055 0.000057 0.000045 0.0000232 0.0000133 0.000051 0.000047 2016 7 10 57579 0.171340 0.473700 -0.2181389 0.0006113 0.000222 0.000031 0.000057 0.000045 0.0000202 0.0000133 0.000051 0.000047 2016 7 11 57580 0.174086 0.472310 -0.2186923 0.0005165 0.000184 0.000008 0.000057 0.000045 0.0000131 0.0000133 0.000051 0.000047 2016 7 12 57581 0.176852 0.471135 -0.2191498 0.0004369 0.000146 -0.000015 0.000057 0.000045 0.0000089 0.0000133 0.000051 0.000047 2016 7 13 57582 0.179283 0.470265 -0.2195325 0.0003725 0.000073 0.000000 0.000057 0.000045 0.0000076 0.0000133 0.000052 0.000047 2016 7 14 57583 0.180966 0.469235 -0.2198169 0.0002372 0.000055 0.000083 0.000057 0.000045 0.0000071 0.0000133 0.000052 0.000047 2016 7 15 57584 0.182727 0.468092 -0.2199981 0.0000864 0.000200 0.000049 0.000057 0.000045 0.0000066 0.0000133 0.000052 0.000047 2016 7 16 57585 0.184853 0.466743 -0.2200469 0.0000064 0.000244 0.000015 0.000057 0.000045 0.0000137 0.0000133 0.000052 0.000046 2016 7 17 57586 0.187119 0.465535 -0.2200312 -0.0000195 0.000233 -0.000004 0.000057 0.000045 0.0000197 0.0000133 0.000051 0.000046 2016 7 18 57587 0.189583 0.464318 -0.2200092 -0.0000165 0.000221 -0.000022 0.000057 0.000045 0.0000172 0.0000133 0.000051 0.000045 2016 7 19 57588 0.192173 0.463129 -0.2200025 0.0000523 0.000210 -0.000041 0.000057 0.000045 0.0000113 0.0000133 0.000051 0.000045 2016 7 20 57589 0.194353 0.462010 -0.2200762 0.0001371 0.000127 0.000005 0.000057 0.000045 0.0000153 0.0000133 0.000051 0.000045 2016 7 21 57590 0.196143 0.460971 -0.2202537 0.0002249 0.000126 0.000060 0.000056 0.000045 0.0000194 0.0000133 0.000051 0.000044 2016 7 22 57591 0.198067 0.459761 -0.2205521 0.0003643 0.000187 0.000021 0.000056 0.000045 0.0000138 0.0000133 0.000050 0.000044 2016 7 23 57592 0.200137 0.458644 -0.2209468 0.0004642 0.000195 -0.000007 0.000056 0.000045 0.0000155 0.0000133 0.000050 0.000043 2016 7 24 57593 0.202202 0.457604 -0.2214263 0.0005055 0.000179 -0.000019 0.000056 0.000045 0.0000217 0.0000133 0.000049 0.000042 2016 7 25 57594 0.204203 0.456680 -0.2219975 0.0005674 0.000164 -0.000032 0.000056 0.000045 0.0000171 0.0000133 0.000049 0.000042 2016 7 26 57595 0.206098 0.456038 -0.2226051 0.0005927 0.000149 -0.000044 0.000056 0.000045 0.0000069 0.0000134 0.000049 0.000041 2016 7 27 57596 0.207480 0.455158 -0.2232066 0.0005690 0.000114 0.000003 0.000056 0.000045 0.0000175 0.0000134 0.000049 0.000041 2016 7 28 57597 0.208744 0.454254 -0.2237563 0.0005498 0.000128 -0.000027 0.000056 0.000045 0.0000279 0.0000134 0.000049 0.000042 2016 7 29 57598 0.210064 0.453198 -0.2242657 0.0004669 0.000182 -0.000027 0.000056 0.000045 0.0000167 0.0000134 0.000049 0.000042 2016 7 30 57599 0.211452 0.451874 -0.2246999 0.0003987 0.000208 -0.000018 0.000056 0.000045 0.0000160 0.0000134 0.000050 0.000043 2016 7 31 57600 0.212526 0.450649 -0.2250569 0.0003419 0.000221 -0.000014 0.000056 0.000045 0.0000232 0.0000134 0.000050 0.000043 2016 8 1 57601 0.213141 0.449375 -0.2254179 0.0003731 0.000233 -0.000009 0.000056 0.000045 0.0000220 0.0000134 0.000050 0.000044 2016 8 2 57602 0.213247 0.448089 -0.2258422 0.0004225 0.000246 -0.000005 0.000057 0.000045 0.0000155 0.0000134 0.000050 0.000044 2016 8 3 57603 0.214244 0.446084 -0.2263367 0.0005503 0.000231 0.000004 0.000057 0.000045 0.0000163 0.0000134 0.000051 0.000044 2016 8 4 57604 0.215724 0.444661 -0.2269184 0.0006048 0.000208 0.000014 0.000057 0.000045 0.0000181 0.0000134 0.000051 0.000045 2016 8 5 57605 0.217083 0.443288 -0.2275668 0.0006440 0.000185 0.000024 0.000057 0.000045 0.0000162 0.0000135 0.000051 0.000045 2016 8 6 57606 0.218353 0.442149 -0.2282361 0.0006942 0.000183 0.000014 0.000057 0.000045 0.0000157 0.0000135 0.000051 0.000045 2016 8 7 57607 0.219346 0.440612 -0.2289430 0.0007126 0.000188 -0.000004 0.000057 0.000045 0.0000164 0.0000135 0.000051 0.000045 2016 8 8 57608 0.220520 0.439128 -0.2296771 0.0006972 0.000193 -0.000022 0.000057 0.000045 0.0000135 0.0000135 0.000051 0.000045 2016 8 9 57609 0.221565 0.437722 -0.2303774 0.0006504 0.000198 -0.000040 0.000057 0.000045 0.0000087 0.0000135 0.000051 0.000045 2016 8 10 57610 0.222606 0.436125 -0.2310234 0.0006483 0.000320 -0.000202 0.000058 0.000045 0.0000080 0.0000135 0.000051 0.000046 2016 8 11 57611 0.223350 0.434346 -0.2315908 0.0005481 0.000259 -0.000146 0.000058 0.000045 0.0000084 0.0000136 0.000051 0.000046 2016 8 12 57612 0.224324 0.432086 -0.2320766 0.0004201 0.000134 -0.000015 0.000058 0.000045 0.0000089 0.0000136 0.000051 0.000046 2016 8 13 57613 0.225436 0.429820 -0.2324464 0.0003054 0.000108 -0.000019 0.000058 0.000045 0.0000152 0.0000136 0.000051 0.000046 2016 8 14 57614 0.225985 0.427479 -0.2327195 0.0002572 0.000117 -0.000073 0.000059 0.000045 0.0000161 0.0000137 0.000052 0.000047 2016 8 15 57615 0.226088 0.425029 -0.2329880 0.0003006 0.000126 -0.000126 0.000059 0.000045 0.0000186 0.0000137 0.000052 0.000047 2016 8 16 57616 0.226415 0.422458 -0.2333320 0.0004157 0.000135 -0.000179 0.000059 0.000045 0.0000243 0.0000138 0.000052 0.000047 2016 8 17 57617 0.226668 0.420238 -0.2338018 0.0005477 0.000144 -0.000233 0.000059 0.000045 0.0000308 0.0000138 0.000052 0.000048 2016 8 18 57618 0.226841 0.418160 -0.2344336 0.0006964 0.000175 -0.000063 0.000059 0.000045 0.0000239 0.0000139 0.000052 0.000048 2016 8 19 57619 0.227296 0.416125 -0.2352444 0.0009155 0.000235 -0.000068 0.000060 0.000045 0.0000135 0.0000139 0.000052 0.000048 2016 8 20 57620 0.227522 0.414279 -0.2362120 0.0010231 0.000236 -0.000079 0.000060 0.000045 0.0000157 0.0000139 0.000052 0.000047 2016 8 21 57621 0.227604 0.412217 -0.2373060 0.0010965 0.000213 -0.000067 0.000060 0.000045 0.0000210 0.0000140 0.000052 0.000047 2016 8 22 57622 0.227820 0.410289 -0.2384478 0.0011286 0.000189 -0.000055 0.000060 0.000045 0.0000191 0.0000140 0.000051 0.000047 2016 8 23 57623 0.228221 0.407939 -0.2395542 0.0010761 0.000166 -0.000043 0.000060 0.000045 0.0000141 0.0000140 0.000051 0.000047 2016 8 24 57624 0.229186 0.405729 -0.2406044 0.0009996 -0.000016 0.000033 0.000060 0.000045 0.0000114 0.0000140 0.000051 0.000047 2016 8 25 57625 0.230234 0.403877 -0.2415364 0.0008647 0.000011 0.000038 0.000060 0.000045 0.0000093 0.0000141 0.000051 0.000047 2016 8 26 57626 0.231403 0.401995 -0.2423422 0.0007515 0.000011 -0.000048 0.000060 0.000045 0.0000072 0.0000141 0.000051 0.000047 2016 8 27 57627 0.232494 0.399972 -0.2430413 0.0006699 0.000030 -0.000082 0.000060 0.000045 0.0000139 0.0000141 0.000050 0.000047 2016 8 28 57628 0.233736 0.397650 -0.2436926 0.0006241 0.000069 -0.000089 0.000060 0.000045 0.0000172 0.0000141 0.000050 0.000047 2016 8 29 57629 0.234724 0.395782 -0.2443096 0.0006206 0.000108 -0.000096 0.000060 0.000045 0.0000146 0.0000142 0.000050 0.000047 2016 8 30 57630 0.235370 0.393332 -0.2449574 0.0006923 0.000147 -0.000103 0.000060 0.000045 0.0000108 0.0000142 0.000050 0.000047 2016 8 31 57631 0.235955 0.391033 -0.2456656 0.0007476 0.000154 -0.000078 0.000060 0.000045 0.0000189 0.0000142 0.000050 0.000047 2016 9 1 57632 0.236393 0.389256 -0.2464483 0.0007890 0.000154 -0.000045 0.000060 0.000045 0.0000253 0.0000143 0.000050 0.000047 2016 9 2 57633 0.236879 0.388053 -0.2472901 0.0008418 0.000153 -0.000011 0.000059 0.000045 0.0000133 0.0000143 0.000050 0.000047 2016 9 3 57634 0.236658 0.387128 -0.2481783 0.0008936 0.000140 0.000030 0.000059 0.000045 0.0000161 0.0000143 0.000050 0.000047 2016 9 4 57635 0.235996 0.385778 -0.2491163 0.0009480 0.000122 0.000075 0.000059 0.000045 0.0000168 0.0000143 0.000050 0.000047 2016 9 5 57636 0.235115 0.384087 -0.2500960 0.0009586 0.000104 0.000120 0.000059 0.000045 0.0000309 0.0000143 0.000049 0.000047 2016 9 6 57637 0.234472 0.382150 -0.2510406 0.0009188 0.000086 0.000165 0.000059 0.000045 0.0000277 0.0000144 0.000049 0.000047 2016 9 7 57638 0.234323 0.380175 -0.2519211 0.0008827 0.000047 0.000121 0.000059 0.000045 0.0000127 0.0000144 0.000049 0.000047 2016 9 8 57639 0.234424 0.377967 -0.2527417 0.0008006 0.000041 -0.000001 0.000059 0.000045 0.0000082 0.0000144 0.000049 0.000047 2016 9 9 57640 0.234708 0.375722 -0.2535062 0.0007232 0.000170 -0.000114 0.000059 0.000045 0.0000066 0.0000144 0.000049 0.000046 2016 9 10 57641 0.234649 0.373790 -0.2541895 0.0006806 0.000214 -0.000142 0.000058 0.000045 0.0000104 0.0000144 0.000048 0.000046 2016 9 11 57642 0.234577 0.371762 -0.2548767 0.0007244 0.000213 -0.000143 0.000058 0.000045 0.0000121 0.0000143 0.000048 0.000046 2016 9 12 57643 0.235107 0.369866 -0.2556014 0.0007604 0.000212 -0.000144 0.000058 0.000045 0.0000144 0.0000143 0.000048 0.000045 2016 9 13 57644 0.235655 0.367878 -0.2564017 0.0008097 0.000211 -0.000144 0.000058 0.000045 0.0000181 0.0000143 0.000048 0.000045 2016 9 14 57645 0.236079 0.366133 -0.2572712 0.0009578 0.000186 -0.000105 0.000058 0.000045 0.0000247 0.0000143 0.000048 0.000045 2016 9 15 57646 0.236237 0.364448 -0.2583016 0.0011389 0.000155 -0.000056 0.000058 0.000045 0.0000276 0.0000143 0.000047 0.000044 2016 9 16 57647 0.236870 0.362505 -0.2595464 0.0013142 0.000156 -0.000052 0.000058 0.000045 0.0000136 0.0000142 0.000047 0.000045 2016 9 17 57648 0.237252 0.360538 -0.2609258 0.0014372 0.000114 -0.000040 0.000058 0.000045 0.0000112 0.0000142 0.000047 0.000045 2016 9 18 57649 0.237559 0.358723 -0.2623966 0.0014991 0.000051 -0.000018 0.000058 0.000045 0.0000138 0.0000141 0.000048 0.000045 2016 9 19 57650 0.237444 0.357041 -0.2639124 0.0014807 -0.000011 0.000003 0.000058 0.000045 0.0000125 0.0000141 0.000048 0.000045 2016 9 20 57651 0.237317 0.355128 -0.2653748 0.0014407 -0.000074 0.000024 0.000058 0.000045 0.0000090 0.0000141 0.000048 0.000046 2016 9 21 57652 0.236929 0.353154 -0.2667351 0.0013239 -0.000024 -0.000131 0.000058 0.000045 0.0000093 0.0000140 0.000048 0.000046 2016 9 22 57653 0.236569 0.350977 -0.2679718 0.0011642 0.000006 -0.000273 0.000058 0.000045 0.0000106 0.0000140 0.000048 0.000047 2016 9 23 57654 0.236312 0.348986 -0.2691091 0.0010848 0.000070 -0.000097 0.000058 0.000045 0.0000119 0.0000139 0.000048 0.000047 2016 9 24 57655 0.235703 0.346927 -0.2701980 0.0010751 0.000105 -0.000032 0.000057 0.000045 0.0000189 0.0000139 0.000047 0.000047 2016 9 25 57656 0.235081 0.344573 -0.2712536 0.0011037 0.000122 -0.000047 0.000057 0.000045 0.0000139 0.0000139 0.000047 0.000046 2016 9 26 57657 0.234805 0.342187 -0.2723677 0.0011511 0.000140 -0.000061 0.000057 0.000044 0.0000100 0.0000138 0.000047 0.000046 2016 9 27 57658 0.234129 0.339789 -0.2735732 0.0012263 0.000158 -0.000075 0.000057 0.000045 0.0000101 0.0000138 0.000046 0.000046 2016 9 28 57659 0.233591 0.336998 -0.2748195 0.0012886 0.000164 -0.000077 0.000058 0.000045 0.0000195 0.0000138 0.000046 0.000046 2016 9 29 57660 0.233869 0.334436 -0.2761407 0.0013834 0.000169 -0.000076 0.000058 0.000045 0.0000261 0.0000137 0.000046 0.000046 2016 9 30 57661 0.234124 0.332622 -0.2775743 0.0014143 0.000173 -0.000074 0.000058 0.000045 0.0000127 0.0000137 0.000046 0.000046 2016 10 1 57662 0.233663 0.331060 -0.2789780 0.0013830 0.000169 -0.000046 0.000058 0.000045 0.0000078 0.0000137 0.000045 0.000046 2016 10 2 57663 0.232649 0.329526 -0.2803389 0.0013213 0.000162 -0.000007 0.000058 0.000045 0.0000094 0.0000136 0.000045 0.000046 2016 10 3 57664 0.231347 0.327916 -0.2816060 0.0012177 0.000155 0.000032 0.000058 0.000045 0.0000188 0.0000136 0.000045 0.000046 2016 10 4 57665 0.229599 0.326157 -0.2827870 0.0011397 0.000148 0.000071 0.000058 0.000045 0.0000225 0.0000136 0.000045 0.000045 2016 10 5 57666 0.227411 0.324763 -0.2838976 0.0010774 0.000111 -0.000068 0.000058 0.000045 0.0000138 0.0000135 0.000045 0.000045 2016 10 6 57667 0.225223 0.322979 -0.2849405 0.0010312 0.000103 -0.000129 0.000058 0.000045 0.0000121 0.0000135 0.000044 0.000044 2016 10 7 57668 0.223381 0.321426 -0.2859351 0.0009841 0.000093 -0.000053 0.000058 0.000045 0.0000122 0.0000134 0.000044 0.000044 2016 10 8 57669 0.221706 0.319581 -0.2868949 0.0009527 0.000074 0.000088 0.000058 0.000045 0.0000134 0.0000134 0.000043 0.000044 2016 10 9 57670 0.220836 0.317742 -0.2878706 0.0010105 0.000075 0.000175 0.000058 0.000045 0.0000154 0.0000134 0.000043 0.000043 2016 10 10 57671 0.220770 0.315995 -0.2889343 0.0011585 0.000111 0.000111 0.000058 0.000045 0.0000173 0.0000133 0.000042 0.000042 2016 10 11 57672 0.220726 0.314067 -0.2901532 0.0013327 0.000147 0.000048 0.000058 0.000045 0.0000156 0.0000133 0.000042 0.000041 2016 10 12 57673 0.220459 0.312511 -0.2915675 0.0015183 0.000183 -0.000016 0.000058 0.000045 0.0000107 0.0000133 0.000041 0.000040 2016 10 13 57674 0.220083 0.311198 -0.2931891 0.0017220 0.000156 -0.000050 0.000058 0.000046 0.0000093 0.0000132 0.000041 0.000039 2016 10 14 57675 0.219073 0.310393 -0.2950153 0.0019229 0.000111 -0.000077 0.000058 0.000046 0.0000089 0.0000132 0.000040 0.000038 2016 10 15 57676 0.217426 0.309297 -0.2970271 0.0020646 0.000103 -0.000064 0.000057 0.000046 0.0000101 0.0000132 0.000040 0.000038 2016 10 16 57677 0.215439 0.307937 -0.2991181 0.0020995 0.000108 -0.000036 0.000057 0.000045 0.0000084 0.0000132 0.000040 0.000037 2016 10 17 57678 0.213453 0.306180 -0.3011669 0.0019810 0.000112 -0.000009 0.000058 0.000046 0.0000086 0.0000132 0.000039 0.000037 2016 10 18 57679 0.211719 0.304036 -0.3030933 0.0018540 0.000117 0.000019 0.000058 0.000046 0.0000107 0.0000132 0.000039 0.000037 2016 10 19 57680 0.209987 0.302133 -0.3048657 0.0016686 0.000080 0.000061 0.000058 0.000046 0.0000219 0.0000132 0.000039 0.000037 2016 10 20 57681 0.208021 0.300077 -0.3064684 0.0015030 0.000089 -0.000026 0.000058 0.000046 0.0000299 0.0000133 0.000039 0.000036 2016 10 21 57682 0.206202 0.298149 -0.3079124 0.0014445 0.000114 -0.000153 0.000058 0.000046 0.0000163 0.0000133 0.000039 0.000036 2016 10 22 57683 0.204198 0.296511 -0.3093297 0.0014135 0.000096 -0.000211 0.000059 0.000046 0.0000103 0.0000133 0.000038 0.000036 2016 10 23 57684 0.202693 0.294771 -0.3107438 0.0014213 0.000062 -0.000245 0.000059 0.000045 0.0000108 0.0000133 0.000038 0.000035 2016 10 24 57685 0.201446 0.293579 -0.3121565 0.0014261 0.000028 -0.000278 0.000059 0.000045 0.0000096 0.0000134 0.000038 0.000035 2016 10 25 57686 0.199955 0.291877 -0.3135985 0.0014683 0.000146 -0.000049 0.000059 0.000046 0.0000068 0.0000134 0.000038 0.000034 2016 10 26 57687 0.198792 0.289876 -0.3150530 0.0014881 0.000156 -0.000029 0.000059 0.000046 0.0000067 0.0000134 0.000038 0.000034 2016 10 27 57688 0.196981 0.288215 -0.3165269 0.0014522 0.000128 -0.000080 0.000059 0.000046 0.0000073 0.0000134 0.000038 0.000034 2016 10 28 57689 0.194869 0.286761 -0.3180064 0.0014768 0.000101 -0.000131 0.000059 0.000045 0.0000079 0.0000135 0.000038 0.000034 2016 10 29 57690 0.192860 0.285478 -0.3195138 0.0014924 0.000114 -0.000127 0.000059 0.000045 0.0000077 0.0000135 0.000038 0.000034 2016 10 30 57691 0.191495 0.284577 -0.3210008 0.0014978 0.000141 -0.000103 0.000059 0.000045 0.0000072 0.0000135 0.000038 0.000034 2016 10 31 57692 0.190104 0.283674 -0.3224372 0.0013882 0.000168 -0.000078 0.000060 0.000045 0.0000066 0.0000135 0.000038 0.000035 2016 11 1 57693 0.188731 0.282474 -0.3238172 0.0013562 0.000195 -0.000054 0.000060 0.000045 0.0000061 0.0000135 0.000038 0.000035 2016 11 2 57694 0.187220 0.281567 -0.3251186 0.0013057 -0.000030 -0.000057 0.000060 0.000045 0.0000077 0.0000135 0.000038 0.000035 2016 11 3 57695 0.185855 0.280464 -0.3263755 0.0012214 -0.000011 -0.000105 0.000060 0.000045 0.0000099 0.0000135 0.000038 0.000035 2016 11 4 57696 0.185037 0.279393 -0.3276200 0.0012321 0.000100 -0.000165 0.000060 0.000045 0.0000121 0.0000135 0.000038 0.000036 2016 11 5 57697 0.183900 0.279012 -0.3288930 0.0013043 0.000159 -0.000253 0.000060 0.000045 0.0000168 0.0000135 0.000038 0.000036 2016 11 6 57698 0.182032 0.278925 -0.3302327 0.0014031 0.000199 -0.000352 0.000060 0.000045 0.0000230 0.0000135 0.000038 0.000036 2016 11 7 57699 0.179421 0.278828 -0.3316843 0.0015265 0.000239 -0.000450 0.000060 0.000045 0.0000212 0.0000135 0.000039 0.000036 2016 11 8 57700 0.176398 0.278359 -0.3332744 0.0016311 0.000053 -0.000271 0.000060 0.000045 0.0000154 0.0000135 0.000038 0.000036 2016 11 9 57701 0.173529 0.277724 -0.3350148 0.0018162 0.000024 -0.000203 0.000060 0.000045 0.0000181 0.0000135 0.000038 0.000036 2016 11 10 57702 0.171280 0.277052 -0.3369164 0.0019794 0.000051 -0.000181 0.000060 0.000045 0.0000202 0.0000135 0.000038 0.000036 2016 11 11 57703 0.169402 0.276453 -0.3389584 0.0020965 0.000077 -0.000159 0.000060 0.000045 0.0000111 0.0000135 0.000038 0.000036 2016 11 12 57704 0.167402 0.275406 -0.3411206 0.0021530 0.000082 -0.000160 0.000060 0.000045 0.0000111 0.0000134 0.000038 0.000035 2016 11 13 57705 0.165517 0.274307 -0.3432560 0.0021253 0.000080 -0.000171 0.000060 0.000045 0.0000089 0.0000134 0.000038 0.000035 2016 11 14 57706 0.163537 0.273295 -0.3452691 0.0019546 0.000077 -0.000182 0.000059 0.000045 0.0000074 0.0000134 0.000037 0.000035 2016 11 15 57707 0.161296 0.272251 -0.3471086 0.0017234 0.000074 -0.000192 0.000059 0.000045 0.0000077 0.0000134 0.000037 0.000034 2016 11 16 57708 0.158897 0.271440 -0.3486768 0.0014896 0.000032 -0.000078 0.000059 0.000045 0.0000159 0.0000133 0.000037 0.000034 2016 11 17 57709 0.156605 0.270791 -0.3500638 0.0013418 0.000041 -0.000021 0.000059 0.000045 0.0000218 0.0000133 0.000037 0.000034 2016 11 18 57710 0.155013 0.270445 -0.3513618 0.0012468 0.000068 0.000010 0.000059 0.000045 0.0000116 0.0000133 0.000037 0.000034 2016 11 19 57711 0.153277 0.270280 -0.3526354 0.0013094 0.000091 -0.000023 0.000059 0.000045 0.0000201 0.0000132 0.000037 0.000034 2016 11 20 57712 0.151011 0.270031 -0.3539512 0.0013743 0.000112 -0.000080 0.000059 0.000045 0.0000219 0.0000132 0.000037 0.000034 2016 11 21 57713 0.148204 0.269564 -0.3553472 0.0014405 0.000134 -0.000137 0.000058 0.000045 0.0000164 0.0000132 0.000037 0.000034 2016 11 22 57714 0.145951 0.268970 -0.3568130 0.0015158 0.000155 -0.000193 0.000058 0.000045 0.0000105 0.0000132 0.000037 0.000034 2016 11 23 57715 0.143976 0.268693 -0.3583369 0.0015698 0.000034 -0.000133 0.000058 0.000045 0.0000107 0.0000131 0.000037 0.000034 2016 11 24 57716 0.142480 0.268409 -0.3599070 0.0015995 -0.000060 -0.000072 0.000058 0.000045 0.0000104 0.0000131 0.000037 0.000034 2016 11 25 57717 0.141233 0.268427 -0.3614841 0.0015613 -0.000130 -0.000021 0.000058 0.000045 0.0000093 0.0000131 0.000037 0.000034 2016 11 26 57718 0.140234 0.268357 -0.3630348 0.0015101 -0.000096 -0.000023 0.000058 0.000045 0.0000082 0.0000131 0.000037 0.000033 2016 11 27 57719 0.139078 0.268566 -0.3645165 0.0014440 -0.000038 -0.000040 0.000058 0.000045 0.0000129 0.0000131 0.000036 0.000033 2016 11 28 57720 0.137030 0.268788 -0.3659122 0.0013380 0.000020 -0.000057 0.000058 0.000045 0.0000126 0.0000131 0.000036 0.000032 2016 11 29 57721 0.134379 0.268397 -0.3672301 0.0012437 0.000078 -0.000073 0.000058 0.000045 0.0000084 0.0000131 0.000036 0.000032 2016 11 30 57722 0.131994 0.267943 -0.3684958 0.0012233 0.000078 -0.000094 0.000058 0.000045 0.0000177 0.0000131 0.000036 0.000032 2016 12 1 57723 0.129832 0.267400 -0.3697168 0.0012328 0.000063 -0.000116 0.000058 0.000045 0.0000249 0.0000131 0.000036 0.000032 2016 12 2 57724 0.127954 0.267030 -0.3709275 0.0012053 0.000076 -0.000091 0.000058 0.000045 0.0000104 0.0000131 0.000036 0.000032 2016 12 3 57725 0.126002 0.266872 -0.3721002 0.0012100 0.000057 -0.000086 0.000058 0.000045 0.0000305 0.0000131 0.000036 0.000032 2016 12 4 57726 0.124085 0.266525 -0.3732960 0.0012421 0.000023 -0.000095 0.000059 0.000045 0.0000534 0.0000131 0.000036 0.000032 2016 12 5 57727 0.122393 0.266328 -0.3746066 0.0013272 -0.000012 -0.000103 0.000059 0.000045 0.0000411 0.0000131 0.000036 0.000032 2016 12 6 57728 0.120654 0.266038 -0.3760460 0.0014364 -0.000046 -0.000112 0.000059 0.000045 0.0000139 0.0000131 0.000036 0.000033 2016 12 7 57729 0.119472 0.265733 -0.3775534 0.0015514 -0.000031 -0.000124 0.000059 0.000045 0.0000120 0.0000131 0.000036 0.000033 2016 12 8 57730 0.118582 0.265535 -0.3791758 0.0016740 -0.000003 -0.000136 0.000059 0.000045 0.0000153 0.0000132 0.000036 0.000033 2016 12 9 57731 0.118189 0.265614 -0.3809210 0.0017681 0.000026 -0.000148 0.000059 0.000045 0.0000131 0.0000132 0.000037 0.000034 2016 12 10 57732 0.118028 0.265966 -0.3827214 0.0017989 -0.000100 0.000030 0.000059 0.000045 0.0000117 0.0000132 0.000037 0.000034 2016 12 11 57733 0.118031 0.266302 -0.3844930 0.0017287 -0.000141 0.000035 0.000059 0.000045 0.0000127 0.0000132 0.000037 0.000034 2016 12 12 57734 0.117616 0.266860 -0.3861689 0.0016212 -0.000124 -0.000061 0.000059 0.000045 0.0000113 0.0000132 0.000037 0.000033 2016 12 13 57735 0.116406 0.267312 -0.3877018 0.0014156 -0.000107 -0.000156 0.000059 0.000045 0.0000082 0.0000132 0.000037 0.000033 2016 12 14 57736 0.114651 0.267469 -0.3890412 0.0012522 -0.000108 -0.000226 0.000059 0.000045 0.0000105 0.0000132 0.000037 0.000033 2016 12 15 57737 0.113006 0.267433 -0.3902622 0.0012599 -0.000112 -0.000290 0.000059 0.000045 0.0000143 0.0000132 0.000037 0.000033 2016 12 16 57738 0.111724 0.267275 -0.3914918 0.0012507 -0.000106 -0.000286 0.000059 0.000045 0.0000132 0.0000132 0.000037 0.000033 2016 12 17 57739 0.110800 0.266540 -0.3927496 0.0012781 -0.000096 -0.000257 0.000058 0.000044 0.0000103 0.0000132 0.000037 0.000033 2016 12 18 57740 0.109722 0.266098 -0.3940176 0.0012716 -0.000087 -0.000229 0.000058 0.000044 0.0000161 0.0000132 0.000038 0.000033 2016 12 19 57741 0.108457 0.265841 -0.3952855 0.0012702 -0.000077 -0.000200 0.000058 0.000044 0.0000179 0.0000132 0.000038 0.000033 2016 12 20 57742 0.106494 0.266073 -0.3965694 0.0012730 -0.000067 -0.000172 0.000058 0.000044 0.0000132 0.0000132 0.000038 0.000033 2016 12 21 57743 0.103625 0.265958 -0.3978541 0.0012843 -0.000057 -0.000143 0.000058 0.000044 0.0000070 0.0000133 0.000038 0.000033 2016 12 22 57744 0.100723 0.265754 -0.3991151 0.0012433 -0.000043 -0.000126 0.000058 0.000044 0.0000058 0.0000134 0.000039 0.000034 2016 12 23 57745 0.098040 0.265178 -0.4003409 0.0012013 -0.000037 -0.000108 0.000058 0.000044 0.0000105 0.0000134 0.000039 0.000035 2016 12 24 57746 0.095526 0.264675 -0.4014972 0.0011302 -0.000034 -0.000089 0.000058 0.000044 0.0000168 0.0000134 0.000040 0.000035 2016 12 25 57747 0.093310 0.264487 -0.4025647 0.0010570 -0.000032 -0.000070 0.000058 0.000044 0.0000231 0.0000135 0.000041 0.000036 2016 12 26 57748 0.091137 0.264644 -0.4035423 0.0009473 -0.000029 -0.000051 0.000058 0.000044 0.0000295 0.0000135 0.000041 0.000037 2016 12 27 57749 0.089117 0.264604 -0.4044438 0.0008670 -0.000026 -0.000032 0.000058 0.000044 0.0000257 0.0000136 0.000042 0.000038 2016 12 28 57750 0.086769 0.264747 -0.4052887 0.0008161 -0.000023 -0.000012 0.000059 0.000044 0.0000172 0.0000136 0.000043 0.000039 2016 12 29 57751 0.084557 0.264197 -0.4060978 0.0008055 -0.000024 -0.000054 0.000059 0.000044 0.0000125 0.0000137 0.000044 0.000040 2016 12 30 57752 0.082873 0.263556 -0.4069175 0.0008525 -0.000025 -0.000111 0.000059 0.000045 0.0000088 0.0000138 0.000044 0.000041 2016 12 31 57753 0.081284 0.263013 -0.4077492 0.0009173 -0.000032 -0.000127 0.000059 0.000045 0.0000088 0.0000139 0.000045 0.000041 2017 1 1 57754 0.080406 0.263110 0.5912977 0.0010160 -0.000041 -0.000127 0.000060 0.000045 0.0000116 0.0000140 0.000046 0.000042 2017 1 2 57755 0.080234 0.263612 0.5901980 0.0011845 -0.000051 -0.000127 0.000059 0.000044 0.0000163 0.0000138 0.000043 0.000040 2017 1 3 57756 0.080325 0.264049 0.5889489 0.0013554 -0.000060 -0.000127 0.000059 0.000044 0.0000209 0.0000138 0.000044 0.000040 2017 1 4 57757 0.080085 0.264248 0.5875560 0.0014755 -0.000069 -0.000128 0.000060 0.000045 0.0000256 0.0000139 0.000044 0.000040 2017 1 5 57758 0.078979 0.264771 0.5860113 0.0015833 -0.000071 -0.000156 0.000060 0.000045 0.0000241 0.0000140 0.000045 0.000040 2017 1 6 57759 0.076659 0.265079 0.5844176 0.0015733 -0.000065 -0.000153 0.000060 0.000045 0.0000229 0.0000141 0.000045 0.000040 2017 1 7 57760 0.074997 0.264999 0.5828289 0.0015881 -0.000056 -0.000138 0.000061 0.000046 0.0000223 0.0000141 0.000042 0.000039 2017 1 8 57761 0.073590 0.265346 0.5812971 0.0015171 -0.000048 -0.000122 0.000061 0.000046 0.0000218 0.0000142 0.000042 0.000039 2017 1 9 57762 0.072292 0.265405 0.5798632 0.0013991 -0.000041 -0.000104 0.000061 0.000046 0.0000241 0.0000143 0.000042 0.000039 2017 1 10 57763 0.070974 0.265630 0.5785447 0.0012681 -0.000058 -0.000086 0.000062 0.000046 0.0000278 0.0000144 0.000043 0.000039 2017 1 11 57764 0.069188 0.266009 0.5773226 0.0011980 -0.000056 -0.000068 0.000062 0.000046 0.0000315 0.0000145 0.000043 0.000039 2017 1 12 57765 0.067206 0.266760 0.5761501 0.0011623 -0.000068 -0.000029 0.000063 0.000047 0.0000243 0.0000146 0.000042 0.000038 2017 1 13 57766 0.065434 0.267601 0.5749710 0.0011970 -0.000083 0.000015 0.000062 0.000046 0.0000143 0.0000142 0.000040 0.000037 2017 1 14 57767 0.064123 0.268514 0.5737486 0.0012671 -0.000062 0.000014 0.000062 0.000046 0.0000249 0.0000143 0.000041 0.000037 2017 1 15 57768 0.062094 0.269403 0.5724482 0.0013292 -0.000026 -0.000003 0.000062 0.000046 0.0000253 0.0000143 0.000041 0.000038 2017 1 16 57769 0.059790 0.270125 0.5710855 0.0013475 0.000010 -0.000023 0.000061 0.000045 0.0000157 0.0000142 0.000040 0.000037 2017 1 17 57770 0.056596 0.270860 0.5697355 0.0012962 0.000045 -0.000043 0.000061 0.000046 0.0000100 0.0000142 0.000040 0.000036 2017 1 18 57771 0.053236 0.271069 0.5684687 0.0012312 0.000081 -0.000062 0.000061 0.000046 0.0000136 0.0000143 0.000040 0.000036 2017 1 19 57772 0.049831 0.271594 0.5672621 0.0011544 0.000003 -0.000066 0.000061 0.000046 0.0000130 0.0000143 0.000040 0.000036 2017 1 20 57773 0.046722 0.272046 0.5661354 0.0010835 -0.000100 -0.000078 0.000062 0.000046 0.0000114 0.0000144 0.000038 0.000032 2017 1 21 57774 0.044253 0.272777 0.5650772 0.0010396 -0.000095 -0.000089 0.000062 0.000046 0.0000171 0.0000144 0.000038 0.000034 2017 1 22 57775 0.042223 0.273622 0.5640539 0.0009761 -0.000037 -0.000136 0.000061 0.000046 0.0000166 0.0000143 0.000042 0.000037 2017 1 23 57776 0.040821 0.274538 0.5631156 0.0009027 -0.000035 -0.000148 0.000061 0.000046 0.0000145 0.0000144 0.000042 0.000037 2017 1 24 57777 0.039583 0.275760 0.5622595 0.0008250 -0.000032 -0.000159 0.000061 0.000046 0.0000137 0.0000144 0.000042 0.000037 2017 1 25 57778 0.038517 0.276614 0.5614608 0.0007689 -0.000038 -0.000159 0.000062 0.000046 0.0000166 0.0000145 0.000042 0.000038 2017 1 26 57779 0.037014 0.277717 0.5606755 0.0007617 -0.000045 -0.000156 0.000062 0.000046 0.0000181 0.0000144 0.000040 0.000036 2017 1 27 57780 0.035647 0.278508 0.5598651 0.0008294 -0.000052 -0.000153 0.000062 0.000046 0.0000111 0.0000144 0.000039 0.000037 2017 1 28 57781 0.034439 0.279471 0.5589886 0.0009339 -0.000037 -0.000165 0.000062 0.000046 0.0000155 0.0000144 0.000038 0.000035 2017 1 29 57782 0.033163 0.280636 0.5579999 0.0010635 -0.000014 -0.000180 0.000062 0.000047 0.0000193 0.0000145 0.000039 0.000035 2017 1 30 57783 0.032188 0.281673 0.5568596 0.0012118 0.000009 -0.000196 0.000063 0.000047 0.0000181 0.0000145 0.000039 0.000035 2017 1 31 57784 0.031679 0.282720 0.5555742 0.0013455 0.000032 -0.000212 0.000063 0.000047 0.0000156 0.0000146 0.000039 0.000035 2017 2 1 57785 0.031191 0.283698 0.5541788 0.0014251 -0.000072 -0.000062 0.000063 0.000047 0.0000298 0.0000147 0.000040 0.000035 2017 2 2 57786 0.030748 0.284679 0.5527206 0.0014521 -0.000124 -0.000093 0.000064 0.000047 0.0000398 0.0000148 0.000040 0.000035 2017 2 3 57787 0.030524 0.285671 0.5512606 0.0014618 -0.000151 -0.000192 0.000064 0.000048 0.0000168 0.0000149 0.000038 0.000038 2017 2 4 57788 0.030066 0.286876 0.5498336 0.0014133 -0.000148 -0.000214 0.000064 0.000048 0.0000177 0.0000150 0.000040 0.000037 2017 2 5 57789 0.029276 0.288333 0.5484764 0.0013301 -0.000132 -0.000208 0.000065 0.000048 0.0000238 0.0000151 0.000038 0.000036 2017 2 6 57790 0.027940 0.289708 0.5471907 0.0012443 -0.000117 -0.000202 0.000062 0.000047 0.0000202 0.0000148 0.000039 0.000037 2017 2 7 57791 0.025783 0.290937 0.5459617 0.0011784 -0.000101 -0.000195 0.000063 0.000047 0.0000126 0.0000148 0.000040 0.000037 2017 2 8 57792 0.023504 0.291995 0.5447813 0.0011966 -0.000132 -0.000121 0.000063 0.000047 0.0000117 0.0000149 0.000040 0.000038 2017 2 9 57793 0.021386 0.293084 0.5435687 0.0012574 -0.000174 -0.000029 0.000063 0.000047 0.0000127 0.0000150 0.000040 0.000038 2017 2 10 57794 0.019705 0.294105 0.5422705 0.0013534 -0.000171 -0.000154 0.000063 0.000047 0.0000141 0.0000151 0.000040 0.000038 2017 2 11 57795 0.018117 0.295030 0.5408616 0.0014923 -0.000154 -0.000207 0.000063 0.000047 0.0000277 0.0000152 0.000040 0.000038 2017 2 12 57796 0.016533 0.296190 0.5393236 0.0015821 -0.000138 -0.000207 0.000064 0.000048 0.0000337 0.0000152 0.000040 0.000038 2017 2 13 57797 0.014945 0.297050 0.5376803 0.0016412 -0.000122 -0.000208 0.000063 0.000047 0.0000270 0.0000150 0.000040 0.000038 2017 2 14 57798 0.013603 0.298053 0.5360022 0.0016773 -0.000106 -0.000208 0.000063 0.000056 0.0000168 0.0000112 0.000043 0.000040 2017 2 15 57799 0.012199 0.298908 0.5343223 0.0016530 -0.000112 -0.000184 0.000063 0.000056 0.0000182 0.0000111 0.000043 0.000040 2017 2 16 57800 0.010653 0.299914 0.5327041 0.0015749 -0.000123 -0.000155 0.000062 0.000047 0.0000203 0.0000145 0.000043 0.000041 2017 2 17 57801 0.009096 0.300662 0.5311837 0.0014455 -0.000135 -0.000126 0.000062 0.000047 0.0000137 0.0000145 0.000043 0.000041 2017 2 18 57802 0.008066 0.301408 0.5298432 0.0012789 -0.000132 -0.000141 0.000062 0.000047 0.0000234 0.0000146 0.000043 0.000041 2017 2 19 57803 0.007626 0.302891 0.5286507 0.0011131 -0.000123 -0.000171 0.000063 0.000047 0.0000393 0.0000147 0.000043 0.000041 2017 2 20 57804 0.007330 0.304749 0.5275398 0.0009881 -0.000115 -0.000202 0.000063 0.000047 0.0000638 0.0000147 0.000043 0.000041 2017 2 21 57805 0.006830 0.306848 0.5265701 0.0009153 -0.000106 -0.000232 0.000063 0.000047 0.0000509 0.0000147 0.000043 0.000041 2017 2 22 57806 0.006292 0.308971 0.5256816 0.0009103 -0.000106 -0.000159 0.000062 0.000047 0.0000191 0.0000148 0.000043 0.000041 2017 2 23 57807 0.006313 0.310992 0.5247251 0.0009917 -0.000079 -0.000133 0.000062 0.000047 0.0000145 0.0000148 0.000043 0.000041 2017 2 24 57808 0.006506 0.313447 0.5237032 0.0010771 -0.000044 -0.000127 0.000062 0.000047 0.0000171 0.0000147 0.000044 0.000041 2017 2 25 57809 0.006351 0.315906 0.5226220 0.0011600 -0.000056 -0.000143 0.000062 0.000047 0.0000255 0.0000147 0.000044 0.000041 2017 2 26 57810 0.005864 0.317660 0.5214174 0.0012737 -0.000087 -0.000167 0.000062 0.000047 0.0000260 0.0000146 0.000044 0.000042 2017 2 27 57811 0.004992 0.319182 0.5200555 0.0014175 -0.000117 -0.000191 0.000062 0.000047 0.0000209 0.0000146 0.000044 0.000042 2017 2 28 57812 0.004458 0.320769 0.5185559 0.0015372 -0.000147 -0.000214 0.000062 0.000046 0.0000156 0.0000145 0.000045 0.000042 2017 3 1 57813 0.004201 0.322772 0.5169206 0.0016149 -0.000133 -0.000225 0.000061 0.000046 0.0000324 0.0000144 0.000045 0.000043 2017 3 2 57814 0.004435 0.324530 0.5152707 0.0016207 -0.000107 -0.000231 0.000061 0.000046 0.0000467 0.0000144 0.000045 0.000043 2017 3 3 57815 0.004753 0.326399 0.5137386 0.0015313 -0.000081 -0.000238 0.000061 0.000046 0.0000295 0.0000143 0.000046 0.000044 2017 3 4 57816 0.004922 0.328387 0.5122784 0.0014347 -0.000098 -0.000197 0.000061 0.000046 0.0000329 0.0000143 0.000046 0.000044 2017 3 5 57817 0.005038 0.330067 0.5108909 0.0013442 -0.000130 -0.000138 0.000061 0.000046 0.0000347 0.0000142 0.000046 0.000044 2017 3 6 57818 0.004656 0.331886 0.5095838 0.0012611 -0.000163 -0.000079 0.000061 0.000046 0.0000292 0.0000142 0.000046 0.000045 2017 3 7 57819 0.003842 0.333541 0.5083262 0.0012567 -0.000196 -0.000020 0.000061 0.000046 0.0000223 0.0000141 0.000046 0.000045 2017 3 8 57820 0.003361 0.335017 0.5070546 0.0013135 -0.000219 0.000002 0.000061 0.000046 0.0000208 0.0000140 0.000047 0.000045 2017 3 9 57821 0.003516 0.336230 0.5057278 0.0013630 -0.000239 0.000014 0.000060 0.000046 0.0000237 0.0000140 0.000047 0.000046 2017 3 10 57822 0.004054 0.337739 0.5043303 0.0014235 -0.000288 -0.000048 0.000060 0.000045 0.0000379 0.0000139 0.000047 0.000046 2017 3 11 57823 0.004522 0.339497 0.5028649 0.0015119 -0.000290 -0.000082 0.000060 0.000045 0.0000284 0.0000139 0.000047 0.000046 2017 3 12 57824 0.004623 0.341460 0.5012981 0.0016026 -0.000271 -0.000095 0.000060 0.000045 0.0000203 0.0000138 0.000047 0.000046 2017 3 13 57825 0.004329 0.343151 0.4996338 0.0016806 -0.000253 -0.000108 0.000060 0.000045 0.0000183 0.0000137 0.000046 0.000046 2017 3 14 57826 0.004108 0.344483 0.4979534 0.0016946 -0.000235 -0.000122 0.000060 0.000045 0.0000168 0.0000137 0.000046 0.000045 2017 3 15 57827 0.003946 0.345936 0.4963503 0.0015974 -0.000252 -0.000086 0.000061 0.000045 0.0000151 0.0000136 0.000046 0.000045 2017 3 16 57828 0.003934 0.347162 0.4948329 0.0014473 -0.000279 -0.000037 0.000061 0.000045 0.0000133 0.0000136 0.000046 0.000045 2017 3 17 57829 0.004042 0.348900 0.4934113 0.0013260 -0.000126 -0.000152 0.000061 0.000045 0.0000114 0.0000135 0.000046 0.000045 2017 3 18 57830 0.004447 0.350950 0.4921127 0.0012046 -0.000070 -0.000130 0.000061 0.000045 0.0000157 0.0000135 0.000046 0.000046 2017 3 19 57831 0.004857 0.353166 0.4909106 0.0011585 -0.000072 -0.000037 0.000060 0.000045 0.0000222 0.0000134 0.000046 0.000046 2017 3 20 57832 0.005254 0.355662 0.4897700 0.0011271 -0.000075 0.000055 0.000060 0.000045 0.0000286 0.0000134 0.000047 0.000046 2017 3 21 57833 0.005426 0.358050 0.4886539 0.0011271 -0.000077 0.000148 0.000060 0.000045 0.0000351 0.0000134 0.000047 0.000047 2017 3 22 57834 0.005638 0.360271 0.4875037 0.0012074 -0.000207 0.000131 0.000060 0.000045 0.0000269 0.0000134 0.000048 0.000047 2017 3 23 57835 0.005959 0.362598 0.4862691 0.0013346 -0.000193 0.000029 0.000060 0.000045 0.0000182 0.0000133 0.000048 0.000047 2017 3 24 57836 0.005500 0.364846 0.4848670 0.0014359 -0.000128 -0.000089 0.000060 0.000045 0.0000225 0.0000133 0.000048 0.000046 2017 3 25 57837 0.005014 0.366667 0.4833895 0.0015687 -0.000127 -0.000097 0.000060 0.000045 0.0000228 0.0000133 0.000047 0.000046 2017 3 26 57838 0.004885 0.368375 0.4817351 0.0017442 -0.000150 -0.000063 0.000060 0.000045 0.0000190 0.0000133 0.000047 0.000046 2017 3 27 57839 0.004890 0.370263 0.4799358 0.0018584 -0.000173 -0.000030 0.000060 0.000045 0.0000147 0.0000133 0.000047 0.000045 2017 3 28 57840 0.004992 0.372010 0.4780207 0.0019526 -0.000196 0.000003 0.000060 0.000045 0.0000132 0.0000133 0.000047 0.000045 2017 3 29 57841 0.005269 0.373530 0.4760266 0.0020072 -0.000475 0.000063 0.000060 0.000045 0.0000152 0.0000133 0.000047 0.000045 2017 3 30 57842 0.005359 0.375029 0.4740320 0.0019058 -0.000437 -0.000007 0.000060 0.000045 0.0000187 0.0000133 0.000048 0.000045 2017 3 31 57843 0.004895 0.376308 0.4721706 0.0017391 -0.000142 -0.000086 0.000060 0.000045 0.0000355 0.0000133 0.000048 0.000044 2017 4 1 57844 0.005294 0.377543 0.4704666 0.0016269 -0.000054 -0.000086 0.000060 0.000045 0.0000219 0.0000132 0.000047 0.000044 2017 4 2 57845 0.005726 0.379066 0.4689063 0.0014914 -0.000060 -0.000063 0.000060 0.000045 0.0000132 0.0000132 0.000047 0.000043 2017 4 3 57846 0.006227 0.379825 0.4674913 0.0013746 -0.000065 -0.000039 0.000060 0.000045 0.0000146 0.0000132 0.000047 0.000042 2017 4 4 57847 0.007153 0.380838 0.4661507 0.0013230 -0.000070 -0.000016 0.000060 0.000045 0.0000170 0.0000132 0.000046 0.000041 2017 4 5 57848 0.008418 0.382508 0.4648247 0.0013373 -0.000051 0.000194 0.000060 0.000046 0.0000178 0.0000132 0.000046 0.000041 2017 4 6 57849 0.009587 0.384603 0.4634343 0.0014635 -0.000063 0.000300 0.000060 0.000046 0.0000179 0.0000132 0.000046 0.000041 2017 4 7 57850 0.010455 0.386575 0.4619097 0.0015867 -0.000137 0.000050 0.000060 0.000046 0.0000166 0.0000131 0.000046 0.000040 2017 4 8 57851 0.010555 0.388428 0.4603054 0.0016542 -0.000132 -0.000039 0.000060 0.000046 0.0000151 0.0000131 0.000045 0.000040 2017 4 9 57852 0.010582 0.390108 0.4586447 0.0016711 -0.000093 -0.000030 0.000060 0.000046 0.0000146 0.0000131 0.000045 0.000039 2017 4 10 57853 0.010954 0.391815 0.4570130 0.0016200 -0.000054 -0.000022 0.000060 0.000046 0.0000138 0.0000131 0.000044 0.000038 2017 4 11 57854 0.011615 0.393605 0.4554115 0.0015628 -0.000014 -0.000014 0.000060 0.000046 0.0000127 0.0000131 0.000044 0.000038 2017 4 12 57855 0.012353 0.395189 0.4538072 0.0015655 -0.000032 -0.000011 0.000060 0.000046 0.0000165 0.0000130 0.000044 0.000038 2017 4 13 57856 0.014173 0.396821 0.4522472 0.0015977 -0.000065 -0.000009 0.000060 0.000046 0.0000216 0.0000130 0.000044 0.000038 2017 4 14 57857 0.016279 0.398825 0.4507197 0.0015318 -0.000080 0.000004 0.000060 0.000046 0.0000233 0.0000130 0.000043 0.000038 2017 4 15 57858 0.018224 0.401065 0.4492444 0.0014306 -0.000088 0.000023 0.000060 0.000046 0.0000239 0.0000130 0.000043 0.000038 2017 4 16 57859 0.019709 0.403514 0.4478193 0.0014057 -0.000096 0.000041 0.000060 0.000046 0.0000162 0.0000130 0.000043 0.000037 2017 4 17 57860 0.021176 0.405745 0.4463842 0.0014669 -0.000103 0.000060 0.000060 0.000045 0.0000131 0.0000130 0.000043 0.000037 2017 4 18 57861 0.022689 0.407739 0.4449259 0.0014977 -0.000111 0.000078 0.000060 0.000045 0.0000145 0.0000130 0.000043 0.000037 2017 4 19 57862 0.023887 0.409771 0.4434259 0.0015095 -0.000119 0.000096 0.000060 0.000046 0.0000159 0.0000130 0.000043 0.000037 2017 4 20 57863 0.024672 0.411357 0.4419414 0.0015148 -0.000124 0.000057 0.000060 0.000045 0.0000193 0.0000130 0.000043 0.000037 2017 4 21 57864 0.026074 0.412745 0.4403657 0.0016288 -0.000142 0.000018 0.000060 0.000045 0.0000232 0.0000131 0.000042 0.000037 2017 4 22 57865 0.027893 0.414973 0.4386298 0.0018037 -0.000141 0.000008 0.000060 0.000045 0.0000191 0.0000131 0.000042 0.000037 2017 4 23 57866 0.029188 0.417538 0.4367309 0.0020108 -0.000132 0.000007 0.000060 0.000045 0.0000146 0.0000131 0.000042 0.000037 2017 4 24 57867 0.029775 0.419822 0.4346461 0.0021600 -0.000123 0.000006 0.000060 0.000045 0.0000242 0.0000131 0.000041 0.000037 2017 4 25 57868 0.030533 0.421627 0.4324562 0.0022208 -0.000114 0.000005 0.000060 0.000045 0.0000402 0.0000131 0.000041 0.000037 2017 4 26 57869 0.031503 0.423256 0.4302575 0.0021462 -0.000215 0.000086 0.000060 0.000045 0.0000346 0.0000131 0.000041 0.000036 2017 4 27 57870 0.032210 0.424548 0.4281606 0.0020042 -0.000195 0.000128 0.000060 0.000045 0.0000230 0.0000131 0.000040 0.000036 2017 4 28 57871 0.033208 0.425930 0.4262633 0.0017946 -0.000178 0.000093 0.000060 0.000045 0.0000101 0.0000131 0.000040 0.000036 2017 4 29 57872 0.034628 0.427532 0.4246052 0.0015522 -0.000168 0.000079 0.000060 0.000045 0.0000190 0.0000131 0.000040 0.000036 2017 4 30 57873 0.036275 0.429467 0.4231249 0.0014037 -0.000153 0.000080 0.000060 0.000045 0.0000178 0.0000131 0.000040 0.000035 2017 5 1 57874 0.037902 0.431334 0.4217257 0.0013892 -0.000139 0.000081 0.000060 0.000045 0.0000140 0.0000131 0.000040 0.000035 2017 5 2 57875 0.039389 0.432900 0.4203557 0.0013941 -0.000125 0.000082 0.000060 0.000045 0.0000132 0.0000131 0.000040 0.000035 2017 5 3 57876 0.040572 0.434223 0.4189708 0.0013856 -0.000210 0.000149 0.000060 0.000046 0.0000125 0.0000131 0.000040 0.000035 2017 5 4 57877 0.041577 0.435189 0.4175587 0.0014286 -0.000219 0.000209 0.000060 0.000046 0.0000115 0.0000131 0.000040 0.000035 2017 5 5 57878 0.043196 0.436527 0.4160970 0.0015356 -0.000119 0.000119 0.000060 0.000046 0.0000103 0.0000131 0.000040 0.000036 2017 5 6 57879 0.045141 0.437894 0.4145443 0.0016338 -0.000083 0.000097 0.000060 0.000046 0.0000155 0.0000131 0.000040 0.000036 2017 5 7 57880 0.047704 0.438989 0.4129179 0.0016287 -0.000080 0.000115 0.000060 0.000046 0.0000583 0.0000131 0.000040 0.000036 2017 5 8 57881 0.050056 0.440496 0.4113774 0.0015006 -0.000077 0.000133 0.000059 0.000046 0.0000560 0.0000130 0.000040 0.000037 2017 5 9 57882 0.051965 0.441775 0.4099350 0.0013823 -0.000074 0.000152 0.000059 0.000046 0.0000220 0.0000130 0.000040 0.000038 2017 5 10 57883 0.053989 0.443124 0.4085580 0.0013309 0.000032 0.000215 0.000059 0.000046 0.0000174 0.0000130 0.000041 0.000038 2017 5 11 57884 0.056190 0.444377 0.4072740 0.0012501 0.000030 0.000246 0.000059 0.000046 0.0000206 0.0000130 0.000041 0.000039 2017 5 12 57885 0.058581 0.445931 0.4060909 0.0011401 -0.000011 0.000263 0.000059 0.000046 0.0000237 0.0000130 0.000041 0.000039 2017 5 13 57886 0.060692 0.447295 0.4049824 0.0010663 -0.000053 0.000278 0.000059 0.000046 0.0000219 0.0000130 0.000041 0.000040 2017 5 14 57887 0.062928 0.448435 0.4039607 0.0010183 -0.000094 0.000292 0.000059 0.000046 0.0000237 0.0000130 0.000041 0.000040 2017 5 15 57888 0.064749 0.449370 0.4029798 0.0009724 -0.000136 0.000306 0.000058 0.000046 0.0000209 0.0000130 0.000041 0.000040 2017 5 16 57889 0.066769 0.449808 0.4019951 0.0010301 -0.000177 0.000320 0.000058 0.000046 0.0000143 0.0000130 0.000041 0.000040 2017 5 17 57890 0.068683 0.450261 0.4009243 0.0011089 -0.000062 0.000292 0.000058 0.000046 0.0000135 0.0000129 0.000041 0.000040 2017 5 18 57891 0.070545 0.450676 0.3997859 0.0011737 -0.000078 0.000258 0.000058 0.000046 0.0000124 0.0000129 0.000040 0.000040 2017 5 19 57892 0.072542 0.451760 0.3985764 0.0012451 -0.000157 0.000211 0.000058 0.000046 0.0000106 0.0000129 0.000040 0.000039 2017 5 20 57893 0.074412 0.452910 0.3972817 0.0013513 -0.000169 0.000180 0.000058 0.000046 0.0000388 0.0000129 0.000039 0.000039 2017 5 21 57894 0.076326 0.453653 0.3958681 0.0014966 -0.000153 0.000156 0.000058 0.000046 0.0000351 0.0000129 0.000039 0.000038 2017 5 22 57895 0.078346 0.454504 0.3942892 0.0016203 -0.000137 0.000131 0.000058 0.000046 0.0000213 0.0000129 0.000039 0.000038 2017 5 23 57896 0.079818 0.455090 0.3926231 0.0016921 -0.000121 0.000107 0.000058 0.000046 0.0000133 0.0000129 0.000038 0.000037 2017 5 24 57897 0.081147 0.455475 0.3909289 0.0016664 -0.000175 0.000186 0.000058 0.000046 0.0000239 0.0000129 0.000038 0.000037 2017 5 25 57898 0.082343 0.455649 0.3893134 0.0015630 -0.000170 0.000195 0.000058 0.000046 0.0000335 0.0000129 0.000038 0.000037 2017 5 26 57899 0.083957 0.455917 0.3878318 0.0013526 -0.000141 0.000175 0.000058 0.000046 0.0000206 0.0000129 0.000037 0.000037 2017 5 27 57900 0.085484 0.456291 0.3865631 0.0011527 -0.000124 0.000153 0.000058 0.000046 0.0000224 0.0000129 0.000037 0.000036 2017 5 28 57901 0.087442 0.456398 0.3854661 0.0010372 -0.000111 0.000130 0.000058 0.000046 0.0000221 0.0000129 0.000036 0.000036 2017 5 29 57902 0.089864 0.456519 0.3844115 0.0010581 -0.000098 0.000107 0.000058 0.000046 0.0000218 0.0000129 0.000036 0.000036 2017 5 30 57903 0.092119 0.457095 0.3832675 0.0011626 -0.000086 0.000084 0.000058 0.000046 0.0000200 0.0000129 0.000036 0.000036 2017 5 31 57904 0.094026 0.457366 0.3820383 0.0012646 -0.000073 0.000061 0.000058 0.000046 0.0000165 0.0000129 0.000035 0.000035 2017 6 1 57905 0.095973 0.457506 0.3807131 0.0013420 -0.000077 0.000087 0.000058 0.000046 0.0000178 0.0000129 0.000035 0.000035 2017 6 2 57906 0.097757 0.457787 0.3793404 0.0013639 -0.000086 0.000126 0.000057 0.000046 0.0000202 0.0000129 0.000035 0.000036 2017 6 3 57907 0.099567 0.458215 0.3779862 0.0013285 -0.000071 0.000133 0.000057 0.000046 0.0000262 0.0000129 0.000035 0.000036 2017 6 4 57908 0.101117 0.458581 0.3766834 0.0012553 -0.000047 0.000128 0.000057 0.000046 0.0000360 0.0000128 0.000035 0.000036 2017 6 5 57909 0.102695 0.458523 0.3754598 0.0011671 -0.000023 0.000124 0.000057 0.000046 0.0000352 0.0000128 0.000035 0.000036 2017 6 6 57910 0.103952 0.458428 0.3743504 0.0010432 0.000001 0.000119 0.000057 0.000046 0.0000286 0.0000128 0.000035 0.000036 2017 6 7 57911 0.105355 0.458308 0.3733798 0.0009034 0.000024 0.000114 0.000057 0.000046 0.0000219 0.0000128 0.000035 0.000036 2017 6 8 57912 0.106868 0.458048 0.3725887 0.0007231 0.000122 0.000166 0.000057 0.000045 0.0000152 0.0000128 0.000035 0.000036 2017 6 9 57913 0.108532 0.457811 0.3719481 0.0005379 0.000006 0.000178 0.000057 0.000045 0.0000085 0.0000128 0.000034 0.000036 2017 6 10 57914 0.109980 0.457484 0.3714596 0.0004535 -0.000034 0.000187 0.000057 0.000045 0.0000196 0.0000127 0.000034 0.000036 2017 6 11 57915 0.111451 0.457234 0.3710437 0.0004149 -0.000018 0.000201 0.000057 0.000045 0.0000194 0.0000127 0.000034 0.000036 2017 6 12 57916 0.112994 0.456975 0.3706514 0.0003977 -0.000003 0.000216 0.000057 0.000045 0.0000148 0.0000127 0.000034 0.000035 2017 6 13 57917 0.114578 0.457220 0.3702609 0.0003921 0.000013 0.000230 0.000058 0.000045 0.0000125 0.0000127 0.000034 0.000035 2017 6 14 57918 0.116272 0.457399 0.3698380 0.0004550 0.000003 0.000200 0.000058 0.000045 0.0000170 0.0000126 0.000034 0.000035 2017 6 15 57919 0.118300 0.457308 0.3693452 0.0005437 -0.000013 0.000158 0.000058 0.000045 0.0000234 0.0000126 0.000034 0.000036 2017 6 16 57920 0.120585 0.457118 0.3687665 0.0006577 -0.000014 0.000148 0.000058 0.000045 0.0000251 0.0000126 0.000034 0.000036 2017 6 17 57921 0.122593 0.456680 0.3680847 0.0007541 -0.000010 0.000149 0.000058 0.000045 0.0000251 0.0000126 0.000034 0.000035 2017 6 18 57922 0.124179 0.456211 0.3672999 0.0007959 -0.000005 0.000151 0.000057 0.000045 0.0000187 0.0000126 0.000034 0.000035 2017 6 19 57923 0.125730 0.455709 0.3664782 0.0008290 0.000000 0.000152 0.000057 0.000045 0.0000151 0.0000125 0.000034 0.000035 2017 6 20 57924 0.127862 0.455315 0.3656602 0.0008472 0.000004 0.000154 0.000058 0.000045 0.0000144 0.0000125 0.000034 0.000035 2017 6 21 57925 0.130457 0.454990 0.3648458 0.0008045 -0.000007 0.000149 0.000058 0.000045 0.0000148 0.0000125 0.000034 0.000035 2017 6 22 57926 0.133152 0.454762 0.3641273 0.0006638 -0.000023 0.000143 0.000058 0.000045 0.0000155 0.0000125 0.000034 0.000035 2017 6 23 57927 0.136000 0.454478 0.3635410 0.0004858 -0.000039 0.000138 0.000059 0.000045 0.0000162 0.0000125 0.000035 0.000035 2017 6 24 57928 0.138788 0.454113 0.3631326 0.0003972 -0.000038 0.000138 0.000059 0.000045 0.0000252 0.0000125 0.000035 0.000035 2017 6 25 57929 0.141007 0.454000 0.3627390 0.0003835 -0.000029 0.000141 0.000059 0.000045 0.0000354 0.0000125 0.000035 0.000035 2017 6 26 57930 0.143021 0.453452 0.3623006 0.0004419 -0.000021 0.000144 0.000059 0.000045 0.0000299 0.0000125 0.000035 0.000035 2017 6 27 57931 0.145147 0.452649 0.3618042 0.0005187 -0.000013 0.000147 0.000059 0.000045 0.0000170 0.0000125 0.000035 0.000034 2017 6 28 57932 0.147212 0.451658 0.3612434 0.0005636 -0.000041 0.000205 0.000059 0.000045 0.0000181 0.0000125 0.000035 0.000034 2017 6 29 57933 0.149572 0.450811 0.3606418 0.0005790 -0.000077 0.000278 0.000060 0.000045 0.0000203 0.0000125 0.000035 0.000035 2017 6 30 57934 0.152473 0.449903 0.3600727 0.0005539 -0.000003 0.000261 0.000060 0.000045 0.0000128 0.0000125 0.000035 0.000035 2017 7 1 57935 0.155696 0.449250 0.3595126 0.0005590 0.000023 0.000214 0.000060 0.000045 0.0000148 0.0000125 0.000035 0.000035 2017 7 2 57936 0.159025 0.448761 0.3589361 0.0005418 0.000017 0.000166 0.000060 0.000045 0.0000275 0.0000125 0.000036 0.000036 2017 7 3 57937 0.162254 0.448332 0.3584609 0.0004434 0.000011 0.000119 0.000060 0.000045 0.0000300 0.0000125 0.000036 0.000036 2017 7 4 57938 0.165708 0.447674 0.3581064 0.0003019 0.000006 0.000071 0.000060 0.000045 0.0000257 0.0000125 0.000037 0.000037 2017 7 5 57939 0.168962 0.447193 0.3578547 0.0002085 0.000018 0.000073 0.000060 0.000045 0.0000223 0.0000125 0.000037 0.000037 2017 7 6 57940 0.171987 0.446681 0.3576899 0.0001454 0.000036 0.000088 0.000060 0.000045 0.0000198 0.0000125 0.000037 0.000038 2017 7 7 57941 0.174976 0.445962 0.3575860 0.0000802 0.000053 0.000103 0.000060 0.000045 0.0000200 0.0000125 0.000038 0.000038 2017 7 8 57942 0.177786 0.445212 0.3575080 0.0000763 0.000062 0.000121 0.000060 0.000045 0.0000200 0.0000125 0.000038 0.000038 2017 7 9 57943 0.180221 0.444721 0.3574431 0.0000742 0.000067 0.000140 0.000060 0.000045 0.0000229 0.0000125 0.000038 0.000039 2017 7 10 57944 0.182001 0.443926 0.3573311 0.0001460 0.000072 0.000160 0.000060 0.000045 0.0000244 0.0000125 0.000038 0.000039 2017 7 11 57945 0.183758 0.442796 0.3571391 0.0002704 0.000078 0.000179 0.000060 0.000045 0.0000245 0.0000125 0.000039 0.000039 2017 7 12 57946 0.185216 0.441706 0.3568049 0.0004019 0.000071 0.000153 0.000060 0.000045 0.0000412 0.0000126 0.000039 0.000039 2017 7 13 57947 0.187119 0.440577 0.3563455 0.0005121 0.000062 0.000114 0.000060 0.000045 0.0000485 0.0000126 0.000039 0.000040 2017 7 14 57948 0.189361 0.439329 0.3557732 0.0005981 0.000053 0.000076 0.000060 0.000045 0.0000241 0.0000126 0.000040 0.000040 2017 7 15 57949 0.191161 0.438169 0.3551376 0.0006275 0.000069 0.000087 0.000060 0.000045 0.0000174 0.0000126 0.000040 0.000040 2017 7 16 57950 0.192339 0.436690 0.3545254 0.0005909 0.000095 0.000115 0.000060 0.000045 0.0000183 0.0000126 0.000040 0.000040 2017 7 17 57951 0.193490 0.435030 0.3539270 0.0005814 0.000121 0.000144 0.000060 0.000045 0.0000160 0.0000127 0.000041 0.000040 2017 7 18 57952 0.194733 0.433766 0.3533529 0.0005388 0.000147 0.000172 0.000060 0.000045 0.0000162 0.0000127 0.000041 0.000041 2017 7 19 57953 0.195900 0.432299 0.3528581 0.0004642 0.000173 0.000201 0.000061 0.000045 0.0000196 0.0000127 0.000041 0.000041 2017 7 20 57954 0.197066 0.430717 0.3524275 0.0003825 0.000140 0.000202 0.000061 0.000045 0.0000179 0.0000128 0.000042 0.000041 2017 7 21 57955 0.197923 0.428948 0.3520860 0.0003165 0.000091 0.000195 0.000061 0.000045 0.0000148 0.0000128 0.000042 0.000042 2017 7 22 57956 0.198629 0.426561 0.3518093 0.0002704 0.000078 0.000169 0.000061 0.000045 0.0000150 0.0000128 0.000042 0.000042 2017 7 23 57957 0.199930 0.424439 0.3515352 0.0002800 0.000078 0.000136 0.000061 0.000045 0.0000178 0.0000129 0.000043 0.000043 2017 7 24 57958 0.201761 0.422658 0.3512073 0.0003484 0.000078 0.000103 0.000061 0.000045 0.0000196 0.0000129 0.000043 0.000043 2017 7 25 57959 0.203423 0.421227 0.3507753 0.0004816 0.000078 0.000070 0.000061 0.000045 0.0000207 0.0000130 0.000044 0.000044 2017 7 26 57960 0.204802 0.419916 0.3501881 0.0005927 0.000107 0.000213 0.000061 0.000045 0.0000219 0.0000130 0.000044 0.000045 2017 7 27 57961 0.206134 0.418494 0.3495150 0.0006871 0.000144 0.000403 0.000061 0.000045 0.0000230 0.0000131 0.000045 0.000046 2017 7 28 57962 0.207107 0.416880 0.3488203 0.0006952 0.000167 0.000374 0.000061 0.000045 0.0000242 0.0000131 0.000045 0.000046 2017 7 29 57963 0.207742 0.415305 0.3481523 0.0006325 0.000159 0.000310 0.000061 0.000045 0.0000277 0.0000132 0.000045 0.000046 2017 7 30 57964 0.208296 0.413679 0.3475431 0.0005502 0.000142 0.000260 0.000061 0.000045 0.0000251 0.0000132 0.000045 0.000045 2017 7 31 57965 0.208825 0.411811 0.3470427 0.0004607 0.000125 0.000210 0.000061 0.000045 0.0000232 0.0000133 0.000045 0.000045 2017 8 1 57966 0.209835 0.409886 0.3466598 0.0003137 0.000108 0.000160 0.000061 0.000045 0.0000233 0.0000133 0.000045 0.000045 2017 8 2 57967 0.211398 0.408248 0.3464200 0.0001727 0.000100 0.000163 0.000062 0.000046 0.0000251 0.0000134 0.000045 0.000044 2017 8 3 57968 0.213291 0.406601 0.3462795 0.0000993 0.000095 0.000181 0.000062 0.000046 0.0000274 0.0000134 0.000045 0.000044 2017 8 4 57969 0.214709 0.405433 0.3462009 0.0000931 0.000090 0.000198 0.000062 0.000046 0.0000298 0.0000135 0.000045 0.000043 2017 8 5 57970 0.215447 0.404172 0.3461365 0.0001136 0.000083 0.000187 0.000062 0.000046 0.0000334 0.0000135 0.000045 0.000043 2017 8 6 57971 0.216162 0.402972 0.3459953 0.0001351 0.000075 0.000165 0.000062 0.000046 0.0000353 0.0000136 0.000045 0.000042 2017 8 7 57972 0.217134 0.401528 0.3458381 0.0001868 0.000066 0.000143 0.000062 0.000046 0.0000302 0.0000136 0.000044 0.000041 2017 8 8 57973 0.218544 0.399806 0.3456227 0.0002779 0.000058 0.000121 0.000062 0.000046 0.0000221 0.0000136 0.000044 0.000041 2017 8 9 57974 0.220136 0.398184 0.3452912 0.0004027 0.000094 0.000126 0.000062 0.000046 0.0000263 0.0000136 0.000044 0.000040 2017 8 10 57975 0.221888 0.396576 0.3448193 0.0005551 0.000142 0.000138 0.000062 0.000046 0.0000294 0.0000137 0.000044 0.000040 2017 8 11 57976 0.223520 0.394783 0.3441755 0.0006498 0.000189 0.000149 0.000063 0.000046 0.0000163 0.0000137 0.000044 0.000039 2017 8 12 57977 0.224272 0.393044 0.3435062 0.0006914 0.000187 0.000159 0.000063 0.000046 0.0000184 0.0000138 0.000044 0.000039 2017 8 13 57978 0.224896 0.391349 0.3428387 0.0006686 0.000166 0.000168 0.000063 0.000047 0.0000197 0.0000138 0.000042 0.000038 2017 8 14 57979 0.225434 0.389550 0.3422042 0.0005853 0.000146 0.000177 0.000063 0.000047 0.0000179 0.0000139 0.000041 0.000037 2017 8 15 57980 0.225504 0.387912 0.3416548 0.0004652 0.000125 0.000185 0.000063 0.000047 0.0000163 0.0000139 0.000041 0.000037 2017 8 16 57981 0.225102 0.385969 0.3412337 0.0003525 0.000105 0.000174 0.000063 0.000047 0.0000232 0.0000140 0.000041 0.000037 2017 8 17 57982 0.225340 0.383821 0.3409345 0.0002400 0.000085 0.000158 0.000064 0.000047 0.0000288 0.0000141 0.000040 0.000037 2017 8 18 57983 0.226326 0.381367 0.3407294 0.0002003 0.000091 0.000158 0.000062 0.000046 0.0000206 0.0000137 0.000041 0.000037 2017 8 19 57984 0.227537 0.379678 0.3405044 0.0002042 0.000119 0.000173 0.000062 0.000046 0.0000275 0.0000138 0.000042 0.000037 2017 8 20 57985 0.228598 0.378522 0.3403106 0.0002715 0.000150 0.000190 0.000063 0.000046 0.0000246 0.0000138 0.000042 0.000037 2017 8 21 57986 0.229558 0.377439 0.3399784 0.0004262 0.000181 0.000208 0.000063 0.000046 0.0000211 0.0000139 0.000041 0.000036 2017 8 22 57987 0.230232 0.375700 0.3394944 0.0005179 0.000212 0.000225 0.000063 0.000047 0.0000212 0.0000139 0.000041 0.000036 2017 8 23 57988 0.230696 0.373866 0.3390036 0.0005317 0.000182 0.000208 0.000063 0.000047 0.0000181 0.0000140 0.000041 0.000036 2017 8 24 57989 0.231049 0.371805 0.3384781 0.0005067 0.000135 0.000181 0.000063 0.000047 0.0000147 0.0000140 0.000041 0.000036 2017 8 25 57990 0.231829 0.369601 0.3379075 0.0004783 0.000088 0.000153 0.000063 0.000047 0.0000132 0.0000141 0.000041 0.000035 2017 8 26 57991 0.232957 0.367826 0.3374465 0.0004120 0.000072 0.000154 0.000062 0.000046 0.0000164 0.0000137 0.000040 0.000034 2017 8 27 57992 0.233753 0.366209 0.3370878 0.0003330 0.000066 0.000165 0.000062 0.000046 0.0000165 0.0000138 0.000040 0.000034 2017 8 28 57993 0.234245 0.364398 0.3367924 0.0002433 0.000060 0.000177 0.000061 0.000046 0.0000134 0.0000136 0.000040 0.000034 2017 8 29 57994 0.234844 0.362943 0.3365842 0.0001331 0.000055 0.000188 0.000062 0.000046 0.0000179 0.0000136 0.000041 0.000035 2017 8 30 57995 0.235156 0.361481 0.3364611 0.0000932 0.000074 0.000203 0.000062 0.000046 0.0000284 0.0000137 0.000041 0.000035 2017 8 31 57996 0.235394 0.359463 0.3363733 0.0001055 0.000099 0.000219 0.000062 0.000046 0.0000215 0.0000137 0.000041 0.000035 2017 9 1 57997 0.235563 0.357060 0.3362970 0.0001351 0.000123 0.000238 0.000062 0.000046 0.0000146 0.0000138 0.000041 0.000035 2017 9 2 57998 0.236028 0.355000 0.3361941 0.0001463 0.000139 0.000228 0.000062 0.000046 0.0000142 0.0000138 0.000041 0.000035 2017 9 3 57999 0.236808 0.353230 0.3360359 0.0002014 0.000152 0.000208 0.000061 0.000046 0.0000192 0.0000136 0.000041 0.000035 2017 9 4 58000 0.237536 0.351605 0.3357933 0.0003011 0.000165 0.000188 0.000061 0.000046 0.0000154 0.0000137 0.000042 0.000036 2017 9 5 58001 0.237920 0.350129 0.3353965 0.0004775 0.000177 0.000168 0.000062 0.000046 0.0000159 0.0000137 0.000042 0.000036 2017 9 6 58002 0.238534 0.348089 0.3348249 0.0006648 0.000190 0.000149 0.000062 0.000046 0.0000208 0.0000138 0.000043 0.000036 2017 9 7 58003 0.239949 0.346217 0.3340654 0.0008328 0.000166 0.000156 0.000062 0.000046 0.0000202 0.0000138 0.000042 0.000035 2017 9 8 58004 0.241033 0.344387 0.3331719 0.0009041 0.000131 0.000170 0.000062 0.000046 0.0000181 0.0000138 0.000039 0.000033 2017 9 9 58005 0.241460 0.342815 0.3322438 0.0009404 0.000128 0.000143 0.000062 0.000046 0.0000154 0.0000139 0.000039 0.000034 2017 9 10 58006 0.241406 0.341734 0.3312789 0.0009249 0.000137 0.000101 0.000061 0.000045 0.0000158 0.0000136 0.000037 0.000032 2017 9 11 58007 0.241149 0.340693 0.3303711 0.0008592 0.000145 0.000059 0.000061 0.000045 0.0000144 0.0000137 0.000037 0.000032 2017 9 12 58008 0.240712 0.339184 0.3295699 0.0007488 0.000154 0.000017 0.000061 0.000045 0.0000112 0.0000137 0.000037 0.000032 2017 9 13 58009 0.239490 0.337433 0.3289039 0.0006369 0.000161 0.000050 0.000061 0.000046 0.0000145 0.0000138 0.000038 0.000032 2017 9 14 58010 0.237894 0.335801 0.3283142 0.0005645 0.000180 0.000106 0.000062 0.000046 0.0000175 0.0000139 0.000040 0.000034 2017 9 15 58011 0.236997 0.334277 0.3277308 0.0005783 0.000194 0.000161 0.000062 0.000046 0.0000127 0.0000139 0.000040 0.000034 2017 9 16 58012 0.236151 0.333110 0.3271296 0.0006602 0.000201 0.000178 0.000062 0.000046 0.0000154 0.0000140 0.000042 0.000036 2017 9 17 58013 0.235437 0.331475 0.3263790 0.0008362 0.000206 0.000181 0.000062 0.000046 0.0000210 0.0000140 0.000039 0.000034 2017 9 18 58014 0.234932 0.329981 0.3254469 0.0010116 0.000210 0.000184 0.000063 0.000047 0.0000187 0.0000141 0.000039 0.000034 2017 9 19 58015 0.234376 0.328251 0.3243832 0.0010991 0.000215 0.000187 0.000063 0.000047 0.0000124 0.0000142 0.000040 0.000035 2017 9 20 58016 0.233504 0.326435 0.3232856 0.0011158 0.000210 0.000174 0.000063 0.000047 0.0000152 0.0000143 0.000040 0.000035 2017 9 21 58017 0.232368 0.324511 0.3221774 0.0010613 0.000202 0.000156 0.000062 0.000046 0.0000205 0.0000139 0.000041 0.000036 2017 9 22 58018 0.231480 0.322598 0.3211052 0.0009977 0.000193 0.000139 0.000062 0.000046 0.0000257 0.0000139 0.000042 0.000037 2017 9 23 58019 0.230275 0.320849 0.3201659 0.0009103 0.000203 0.000156 0.000062 0.000046 0.0000223 0.0000139 0.000043 0.000038 2017 9 24 58020 0.229146 0.318541 0.3193171 0.0008010 0.000200 0.000203 0.000062 0.000046 0.0000168 0.0000140 0.000050 0.000037 2017 9 25 58021 0.228437 0.316331 0.3186011 0.0006364 0.000198 0.000251 0.000061 0.000046 0.0000282 0.0000137 0.000052 0.000039 2017 9 26 58022 0.227384 0.314024 0.3180127 0.0005399 0.000196 0.000298 0.000061 0.000046 0.0000478 0.0000137 0.000053 0.000040 2017 9 27 58023 0.226738 0.311756 0.3174763 0.0005185 0.000205 0.000263 0.000061 0.000046 0.0000342 0.0000138 0.000053 0.000040 2017 9 28 58024 0.226108 0.309713 0.3169636 0.0005437 0.000217 0.000206 0.000061 0.000046 0.0000237 0.0000138 0.000053 0.000039 2017 9 29 58025 0.225592 0.307796 0.3163823 0.0006093 0.000229 0.000149 0.000062 0.000046 0.0000585 0.0000138 0.000052 0.000038 2017 9 30 58026 0.224857 0.305629 0.3157773 0.0006513 0.000245 0.000127 0.000062 0.000046 0.0000327 0.0000138 0.000043 0.000038 2017 10 1 58027 0.224071 0.303037 0.3151520 0.0006489 0.000262 0.000118 0.000061 0.000046 0.0000133 0.0000135 0.000043 0.000037 2017 10 2 58028 0.222819 0.300646 0.3145029 0.0006786 0.000279 0.000109 0.000061 0.000046 0.0000136 0.0000135 0.000046 0.000038 2017 10 3 58029 0.222129 0.298414 0.3137523 0.0008123 0.000296 0.000100 0.000061 0.000046 0.0000166 0.0000135 0.000046 0.000038 2017 10 4 58030 0.221797 0.296685 0.3128743 0.0009580 0.000296 0.000093 0.000061 0.000046 0.0000196 0.0000135 0.000047 0.000038 2017 10 5 58031 0.221944 0.294777 0.3118597 0.0010656 0.000292 0.000087 0.000061 0.000046 0.0000205 0.0000135 0.000055 0.000036 2017 10 6 58032 0.221694 0.293830 0.3107083 0.0011534 0.000288 0.000080 0.000061 0.000046 0.0000131 0.0000135 0.000055 0.000036 2017 10 7 58033 0.220172 0.293025 0.3095429 0.0011747 0.000273 0.000076 0.000061 0.000046 0.0000171 0.0000135 0.000055 0.000036 2017 10 8 58034 0.218361 0.292105 0.3084078 0.0011144 0.000254 0.000074 0.000060 0.000046 0.0000201 0.0000132 0.000055 0.000036 2017 10 9 58035 0.216190 0.290860 0.3073780 0.0009523 0.000235 0.000072 0.000060 0.000046 0.0000166 0.0000132 0.000054 0.000036 2017 10 10 58036 0.214075 0.289134 0.3064886 0.0008137 0.000216 0.000070 0.000060 0.000046 0.0000156 0.0000132 0.000054 0.000036 2017 10 11 58037 0.212230 0.287377 0.3057000 0.0007520 0.000197 0.000067 0.000060 0.000046 0.0000165 0.0000132 0.000053 0.000035 2017 10 12 58038 0.210250 0.285371 0.3049588 0.0007432 0.000199 0.000078 0.000060 0.000046 0.0000172 0.0000133 0.000054 0.000036 2017 10 13 58039 0.208688 0.283429 0.3041878 0.0008181 0.000207 0.000092 0.000060 0.000046 0.0000179 0.0000133 0.000055 0.000037 2017 10 14 58040 0.207152 0.281526 0.3033061 0.0009286 0.000206 0.000095 0.000059 0.000046 0.0000171 0.0000133 0.000047 0.000038 2017 10 15 58041 0.205699 0.279734 0.3023366 0.0010431 0.000198 0.000094 0.000059 0.000046 0.0000161 0.0000134 0.000047 0.000037 2017 10 16 58042 0.204789 0.278139 0.3012098 0.0012003 0.000192 0.000093 0.000059 0.000046 0.0000185 0.0000134 0.000048 0.000038 2017 10 17 58043 0.203852 0.276870 0.2999400 0.0013201 0.000186 0.000093 0.000060 0.000047 0.0000225 0.0000135 0.000048 0.000038 2017 10 18 58044 0.202570 0.275423 0.2985802 0.0013856 0.000195 0.000105 0.000060 0.000047 0.0000256 0.0000136 0.000048 0.000038 2017 10 19 58045 0.201228 0.273719 0.2971914 0.0013915 0.000209 0.000122 0.000059 0.000046 0.0000263 0.0000132 0.000050 0.000040 2017 10 20 58046 0.199944 0.272093 0.2958171 0.0013185 0.000222 0.000138 0.000059 0.000046 0.0000189 0.0000132 0.000051 0.000041 2017 10 21 58047 0.198720 0.270643 0.2945597 0.0011990 0.000236 0.000118 0.000059 0.000046 0.0000227 0.0000132 0.000047 0.000039 2017 10 22 58048 0.197301 0.269564 0.2933902 0.0011196 0.000250 0.000085 0.000059 0.000046 0.0000227 0.0000133 0.000047 0.000039 2017 10 23 58049 0.196020 0.268412 0.2923027 0.0010418 0.000264 0.000052 0.000058 0.000045 0.0000216 0.0000130 0.000048 0.000040 2017 10 24 58050 0.194584 0.266918 0.2913105 0.0009175 0.000278 0.000019 0.000058 0.000045 0.0000218 0.0000130 0.000048 0.000040 2017 10 25 58051 0.192750 0.265653 0.2904360 0.0008474 0.000294 0.000049 0.000058 0.000046 0.0000211 0.0000130 0.000048 0.000039 2017 10 26 58052 0.190522 0.264053 0.2896147 0.0008123 0.000311 0.000095 0.000058 0.000046 0.0000202 0.0000131 0.000050 0.000041 2017 10 27 58053 0.188640 0.262493 0.2887939 0.0008334 0.000327 0.000141 0.000059 0.000046 0.0000192 0.0000131 0.000051 0.000041 2017 10 28 58054 0.186601 0.261204 0.2879459 0.0008936 0.000328 0.000145 0.000059 0.000046 0.0000168 0.0000131 0.000052 0.000043 2017 10 29 58055 0.184638 0.259903 0.2869850 0.0010265 0.000324 0.000134 0.000058 0.000045 0.0000241 0.0000128 0.000051 0.000043 2017 10 30 58056 0.183111 0.258826 0.2859308 0.0011120 0.000319 0.000122 0.000058 0.000045 0.0000264 0.0000128 0.000049 0.000042 2017 10 31 58057 0.181829 0.257809 0.2847593 0.0012724 0.000314 0.000111 0.000058 0.000045 0.0000236 0.0000129 0.000049 0.000043 2017 11 1 58058 0.180296 0.256856 0.2834260 0.0013777 0.000305 0.000085 0.000059 0.000045 0.0000259 0.0000129 0.000050 0.000043 2017 11 2 58059 0.179139 0.255937 0.2819666 0.0014899 0.000295 0.000055 0.000059 0.000045 0.0000285 0.0000129 0.000045 0.000041 2017 11 3 58060 0.178168 0.255529 0.2804309 0.0015674 0.000285 0.000025 0.000059 0.000045 0.0000270 0.0000129 0.000046 0.000042 2017 11 4 58061 0.176819 0.255000 0.2788424 0.0015059 0.000300 0.000038 0.000059 0.000045 0.0000222 0.0000130 0.000047 0.000043 2017 11 5 58062 0.175227 0.254016 0.2773391 0.0014047 0.000325 0.000066 0.000060 0.000046 0.0000194 0.0000130 0.000051 0.000043 2017 11 6 58063 0.173465 0.252887 0.2760567 0.0012567 0.000349 0.000094 0.000060 0.000046 0.0000286 0.0000130 0.000051 0.000043 2017 11 7 58064 0.171798 0.251605 0.2749413 0.0010899 0.000373 0.000122 0.000060 0.000046 0.0000431 0.0000131 0.000050 0.000043 2017 11 8 58065 0.170596 0.250256 0.2738988 0.0010311 0.000359 0.000124 0.000060 0.000046 0.0000322 0.0000131 0.000050 0.000043 2017 11 9 58066 0.169120 0.249358 0.2728644 0.0010728 0.000335 0.000118 0.000060 0.000045 0.0000207 0.0000128 0.000055 0.000047 2017 11 10 58067 0.167646 0.247946 0.2717606 0.0011765 0.000311 0.000112 0.000060 0.000045 0.0000319 0.0000128 0.000055 0.000047 2017 11 11 58068 0.166396 0.246848 0.2705042 0.0013010 0.000289 0.000098 0.000060 0.000045 0.0000250 0.0000128 0.000056 0.000048 2017 11 12 58069 0.164923 0.246174 0.2691669 0.0013675 0.000268 0.000080 0.000060 0.000045 0.0000191 0.0000129 0.000049 0.000045 2017 11 13 58070 0.163368 0.245937 0.2677576 0.0014516 0.000248 0.000062 0.000060 0.000045 0.0000199 0.0000129 0.000049 0.000045 2017 11 14 58071 0.161570 0.245403 0.2663008 0.0015009 0.000227 0.000044 0.000060 0.000046 0.0000221 0.0000130 0.000048 0.000045 2017 11 15 58072 0.160062 0.244625 0.2648310 0.0014389 0.000248 0.000016 0.000061 0.000046 0.0000216 0.0000130 0.000047 0.000045 2017 11 16 58073 0.158441 0.244147 0.2634238 0.0013377 0.000281 -0.000015 0.000061 0.000046 0.0000204 0.0000131 0.000047 0.000045 2017 11 17 58074 0.156031 0.243545 0.2621434 0.0012121 0.000313 -0.000047 0.000061 0.000046 0.0000192 0.0000131 0.000047 0.000045 2017 11 18 58075 0.153245 0.242360 0.2610143 0.0010708 0.000304 -0.000041 0.000061 0.000046 0.0000398 0.0000132 0.000055 0.000048 2017 11 19 58076 0.150733 0.241508 0.2599935 0.0009289 0.000280 -0.000022 0.000061 0.000046 0.0000686 0.0000133 0.000051 0.000050 2017 11 20 58077 0.148216 0.240689 0.2591342 0.0007991 0.000256 -0.000004 0.000061 0.000046 0.0000628 0.0000131 0.000051 0.000050 2017 11 21 58078 0.145643 0.239916 0.2584099 0.0006741 0.000232 0.000015 0.000061 0.000046 0.0000396 0.0000132 0.000048 0.000051 2017 11 22 58079 0.143796 0.239140 0.2577664 0.0005958 0.000261 0.000004 0.000062 0.000046 0.0000228 0.0000132 0.000048 0.000051 2017 11 23 58080 0.141993 0.238659 0.2571255 0.0006479 0.000276 -0.000006 0.000062 0.000047 0.0000169 0.0000133 0.000048 0.000050 2017 11 24 58081 0.139593 0.238267 0.2564500 0.0007206 0.000280 -0.000013 0.000063 0.000047 0.0000146 0.0000134 0.000047 0.000050 2017 11 25 58082 0.136821 0.237907 0.2557083 0.0008135 0.000280 -0.000019 0.000063 0.000047 0.0000127 0.0000136 0.000051 0.000044 2017 11 26 58083 0.135302 0.237390 0.2548803 0.0008983 0.000284 -0.000026 0.000063 0.000047 0.0000126 0.0000134 0.000046 0.000044 2017 11 27 58084 0.133543 0.237050 0.2539082 0.0010037 0.000287 -0.000032 0.000063 0.000047 0.0000126 0.0000135 0.000045 0.000043 2017 11 28 58085 0.131125 0.236745 0.2527766 0.0011990 0.000286 -0.000061 0.000048 0.000035 0.0000073 0.0000112 0.000042 0.000034 2017 11 29 58086 0.128797 0.236939 0.2514787 0.0013712 0.000374 -0.000093 0.000048 0.000035 0.0000072 0.0000113 0.000041 0.000034 2017 11 30 58087 0.126354 0.237180 0.2500223 0.0014800 0.000372 -0.000094 0.000048 0.000035 0.0000072 0.0000113 0.000041 0.000034 2017 12 1 58088 0.124093 0.236688 0.2485146 0.0015526 0.000337 -0.000066 0.000048 0.000035 0.0000073 0.0000113 0.000041 0.000035 2017 12 2 58089 0.121669 0.236396 0.2469845 0.0014888 0.000307 -0.000074 0.000049 0.000035 0.0000074 0.0000113 0.000042 0.000035 2017 12 3 58090 0.119232 0.235541 0.2455790 0.0013598 0.000271 -0.000103 0.000049 0.000036 0.0000075 0.0000113 0.000042 0.000036 2017 12 4 58091 0.116892 0.234876 0.2442675 0.0012433 0.000233 -0.000115 0.000049 0.000036 0.0000076 0.0000113 0.000042 0.000037 2017 12 5 58092 0.114703 0.233893 0.2430519 0.0011899 0.000254 -0.000106 0.000049 0.000036 0.0000078 0.0000113 0.000042 0.000037 2017 12 6 58093 0.112573 0.233274 0.2418883 0.0012004 0.000274 -0.000097 0.000049 0.000036 0.0000079 0.0000113 0.000043 0.000038 2017 12 7 58094 0.109471 0.233507 0.2406610 0.0012285 0.000295 -0.000088 0.000050 0.000036 0.0000081 0.0000113 0.000043 0.000039 2017 12 8 58095 0.106820 0.233390 0.2393921 0.0013084 0.000304 -0.000089 0.000050 0.000036 0.0000082 0.0000113 0.000043 0.000040 2017 12 9 58096 0.104779 0.233975 0.2380590 0.0014075 0.000302 -0.000101 0.000050 0.000036 0.0000084 0.0000113 0.000043 0.000041 2017 12 10 58097 0.102552 0.234646 0.2366194 0.0014623 0.000313 -0.000101 0.000051 0.000036 0.0000085 0.0000113 0.000044 0.000041 2017 12 11 58098 0.100164 0.235436 0.2351531 0.0014388 0.000335 -0.000089 0.000051 0.000036 0.0000087 0.0000113 0.000044 0.000042 2017 12 12 58099 0.097687 0.236146 0.2337292 0.0013979 0.000346 -0.000078 0.000051 0.000037 0.0000089 0.0000113 0.000044 0.000043 2017 12 13 58100 0.095346 0.236563 0.2323789 0.0012996 0.000346 -0.000066 0.000051 0.000037 0.0000092 0.0000113 0.000045 0.000045 2017 12 14 58101 0.092869 0.237048 0.2311805 0.0011260 0.000346 -0.000055 0.000052 0.000037 0.0000095 0.0000113 0.000045 0.000047 2017 12 15 58102 0.090256 0.237578 0.2301449 0.0009664 0.000212 -0.000057 0.000052 0.000037 0.0000098 0.0000113 0.000046 0.000050 2017 12 16 58103 0.087663 0.238079 0.2292828 0.0008096 0.000210 -0.000061 0.000052 0.000037 0.0000101 0.0000113 0.000046 0.000052 2017 12 17 58104 0.084775 0.238599 0.2285224 0.0006581 0.000208 -0.000064 0.000053 0.000037 0.0000104 0.0000113 0.000047 0.000054 2017 12 18 58105 0.081905 0.239044 0.2279421 0.0005536 0.000243 -0.000055 0.000053 0.000037 0.0000107 0.0000113 0.000047 0.000056 2017 12 19 58106 0.078820 0.239525 0.2274388 0.0005109 0.000210 -0.000069 0.000053 0.000037 0.0000110 0.0000113 0.000048 0.000058 2017 12 20 58107 0.075952 0.239470 0.2269498 0.0005232 0.000194 -0.000068 0.000053 0.000037 0.0000113 0.0000113 0.000048 0.000060 2017 12 21 58108 0.073645 0.238795 0.2263773 0.0005487 0.000182 -0.000062 0.000054 0.000037 0.0000115 0.0000113 0.000048 0.000062 2017 12 22 58109 0.071910 0.238294 0.2258219 0.0005620 0.000170 -0.000057 0.000054 0.000037 0.0000118 0.0000114 0.000049 0.000063 2017 12 23 58110 0.070537 0.238466 0.2252380 0.0006447 0.000158 -0.000051 0.000054 0.000038 0.0000121 0.0000114 0.000049 0.000065 2017 12 24 58111 0.069324 0.239063 0.2245258 0.0007923 0.000146 -0.000046 0.000054 0.000038 0.0000124 0.0000114 0.000050 0.000067 2017 12 25 58112 0.068299 0.239814 0.2236718 0.0009227 0.000134 -0.000040 0.000055 0.000038 0.0000126 0.0000114 0.000050 0.000070 2017 12 26 58113 0.067657 0.240686 0.2226951 0.0010303 0.000123 -0.000035 0.000055 0.000038 0.0000128 0.0000114 0.000051 0.000073 2017 12 27 58114 0.067318 0.241626 0.2216122 0.0011376 0.000111 -0.000029 0.000055 0.000038 0.0000130 0.0000114 0.000051 0.000076 2017 12 28 58115 0.066650 0.243120 0.2204482 0.0011573 0.000120 0.000161 0.000055 0.000038 0.0000132 0.0000114 0.000051 0.000079 2017 12 29 58116 0.064878 0.244392 0.2192942 0.0011094 0.000092 0.000031 0.000055 0.000038 0.0000133 0.0000115 0.000052 0.000080 2017 12 30 58117 0.063071 0.245448 0.2182464 0.0010466 0.000086 -0.000018 0.000056 0.000038 0.0000134 0.0000115 0.000052 0.000081 2017 12 31 58118 0.061214 0.246580 0.2172353 0.0009457 0.000090 -0.000022 0.000056 0.000038 0.0000135 0.0000115 0.000052 0.000080 2018 1 1 58119 0.059224 0.247646 0.2163654 0.0008241 0.000207 -0.000160 0.000056 0.000038 0.0000135 0.0000115 0.000024 0.000034 2018 1 2 58120 0.057406 0.248566 0.2156078 0.0007355 0.000208 -0.000188 0.000056 0.000038 0.0000136 0.0000115 0.000025 0.000036 2018 1 3 58121 0.055667 0.249547 0.2148691 0.0007464 0.000209 -0.000215 0.000056 0.000038 0.0000136 0.0000115 0.000025 0.000037 2018 1 4 58122 0.054388 0.250409 0.2140616 0.0008484 0.000249 -0.000192 0.000056 0.000038 0.0000136 0.0000115 0.000025 0.000039 2018 1 5 58123 0.053497 0.251568 0.2131861 0.0008848 0.000300 -0.000157 0.000056 0.000038 0.0000136 0.0000115 0.000026 0.000040 2018 1 6 58124 0.052593 0.252938 0.2122905 0.0008868 0.000312 -0.000156 0.000056 0.000038 0.0000135 0.0000116 0.000026 0.000041 2018 1 7 58125 0.050970 0.254226 0.2114201 0.0008519 0.000309 -0.000167 0.000057 0.000038 0.0000135 0.0000116 0.000026 0.000042 2018 1 8 58126 0.049223 0.255002 0.2106218 0.0007565 0.000307 -0.000179 0.000057 0.000038 0.0000135 0.0000116 0.000027 0.000044 2018 1 9 58127 0.047987 0.255808 0.2099302 0.0006126 0.000304 -0.000191 0.000057 0.000039 0.0000134 0.0000116 0.000027 0.000045 2018 1 10 58128 0.046686 0.257130 0.2093475 0.0005072 0.000274 -0.000188 0.000057 0.000039 0.0000133 0.0000116 0.000027 0.000046 2018 1 11 58129 0.045008 0.258580 0.2088731 0.0004246 0.000236 -0.000181 0.000057 0.000039 0.0000131 0.0000116 0.000027 0.000046 2018 1 12 58130 0.043355 0.259855 0.2085075 0.0003018 0.000198 -0.000174 0.000057 0.000039 0.0000130 0.0000117 0.000028 0.000046 2018 1 13 58131 0.041402 0.260606 0.2082775 0.0001676 0.000174 -0.000184 0.000057 0.000039 0.0000129 0.0000117 0.000028 0.000047 2018 1 14 58132 0.039860 0.260774 0.2081607 0.0000794 0.000155 -0.000199 0.000057 0.000039 0.0000129 0.0000117 0.000028 0.000048 2018 1 15 58133 0.038639 0.261182 0.2081094 0.0000335 0.000136 -0.000215 0.000057 0.000039 0.0000128 0.0000117 0.000029 0.000049 2018 1 16 58134 0.037810 0.261913 0.2080798 0.0000282 0.000117 -0.000230 0.000057 0.000039 0.0000128 0.0000117 0.000029 0.000050 2018 1 17 58135 0.037169 0.263221 0.2080186 0.0000780 0.000150 -0.000225 0.000057 0.000039 0.0000127 0.0000117 0.000029 0.000050 2018 1 18 58136 0.036146 0.264989 0.2078912 0.0001477 0.000197 -0.000214 0.000057 0.000039 0.0000127 0.0000118 0.000029 0.000051 2018 1 19 58137 0.034752 0.266831 0.2076636 0.0002862 0.000245 -0.000203 0.000057 0.000039 0.0000126 0.0000118 0.000030 0.000051 2018 1 20 58138 0.032747 0.268633 0.2073080 0.0004294 0.000252 -0.000199 0.000057 0.000039 0.0000125 0.0000118 0.000030 0.000051 2018 1 21 58139 0.030561 0.270346 0.2067994 0.0005816 0.000245 -0.000198 0.000057 0.000039 0.0000124 0.0000118 0.000030 0.000051 2018 1 22 58140 0.028676 0.272068 0.2061278 0.0007363 0.000238 -0.000196 0.000057 0.000039 0.0000123 0.0000118 0.000031 0.000051 2018 1 23 58141 0.027384 0.273712 0.2053153 0.0008662 0.000231 -0.000195 0.000057 0.000039 0.0000121 0.0000118 0.000031 0.000051 2018 1 24 58142 0.026021 0.275528 0.2044009 0.0009243 0.000209 -0.000212 0.000057 0.000039 0.0000121 0.0000119 0.000031 0.000051 2018 1 25 58143 0.024129 0.277399 0.2034218 0.0009929 0.000184 -0.000233 0.000057 0.000039 0.0000121 0.0000119 0.000031 0.000051 2018 1 26 58144 0.022368 0.279079 0.2024259 0.0010030 0.000158 -0.000254 0.000057 0.000039 0.0000121 0.0000119 0.000032 0.000051 2018 1 27 58145 0.020849 0.280621 0.2014710 0.0009578 0.000161 -0.000255 0.000057 0.000039 0.0000121 0.0000119 0.000032 0.000051 2018 1 28 58146 0.019338 0.281805 0.2005689 0.0008831 0.000175 -0.000247 0.000058 0.000039 0.0000121 0.0000119 0.000032 0.000050 2018 1 29 58147 0.018277 0.282895 0.1996857 0.0008961 0.000188 -0.000239 0.000058 0.000039 0.0000122 0.0000120 0.000032 0.000050 2018 1 30 58148 0.017699 0.284465 0.1987616 0.0009826 0.000201 -0.000232 0.000058 0.000039 0.0000122 0.0000120 0.000033 0.000049 2018 1 31 58149 0.016664 0.286211 0.1977227 0.0011157 0.000173 -0.000248 0.000058 0.000039 0.0000122 0.0000120 0.000033 0.000048 2018 2 1 58150 0.015367 0.288248 0.1965069 0.0012990 0.000134 -0.000270 0.000058 0.000039 0.0000122 0.0000120 0.000033 0.000047 2018 2 2 58151 0.014067 0.290203 0.1950929 0.0015264 0.000094 -0.000292 0.000058 0.000039 0.0000122 0.0000120 0.000033 0.000046 2018 2 3 58152 0.012458 0.291691 0.1935028 0.0016713 0.000085 -0.000296 0.000058 0.000039 0.0000122 0.0000120 0.000034 0.000045 2018 2 4 58153 0.010601 0.293313 0.1918164 0.0016883 0.000087 -0.000294 0.000058 0.000039 0.0000122 0.0000121 0.000034 0.000044 2018 2 5 58154 0.008260 0.295375 0.1901389 0.0016217 0.000089 -0.000291 0.000058 0.000039 0.0000122 0.0000121 0.000034 0.000043 2018 2 6 58155 0.006624 0.296675 0.1885561 0.0014783 0.000091 -0.000289 0.000058 0.000039 0.0000122 0.0000121 0.000034 0.000042 2018 2 7 58156 0.006188 0.297813 0.1871202 0.0013497 0.000093 -0.000272 0.000058 0.000039 0.0000122 0.0000121 0.000034 0.000041 2018 2 8 58157 0.005592 0.299623 0.1858660 0.0011840 0.000095 -0.000252 0.000058 0.000039 0.0000121 0.0000121 0.000034 0.000040 2018 2 9 58158 0.004664 0.301372 0.1847954 0.0009818 0.000097 -0.000231 0.000057 0.000039 0.0000121 0.0000121 0.000035 0.000038 2018 2 10 58159 0.004091 0.303167 0.1839041 0.0008318 0.000109 -0.000242 0.000057 0.000039 0.0000121 0.0000121 0.000035 0.000038 2018 2 11 58160 0.003494 0.305155 0.1831267 0.0007473 0.000124 -0.000265 0.000057 0.000039 0.0000120 0.0000121 0.000035 0.000038 2018 2 12 58161 0.003276 0.307207 0.1823799 0.0007322 0.000138 -0.000288 0.000057 0.000039 0.0000120 0.0000121 0.000035 0.000038 2018 2 13 58162 0.002984 0.309331 0.1816279 0.0007615 0.000153 -0.000311 0.000057 0.000039 0.0000119 0.0000122 0.000035 0.000038 2018 2 14 58163 0.002565 0.311263 0.1808512 0.0007852 0.000149 -0.000308 0.000057 0.000039 0.0000118 0.0000122 0.000036 0.000038 2018 2 15 58164 0.001884 0.313278 0.1800285 0.0008537 0.000140 -0.000297 0.000056 0.000039 0.0000118 0.0000122 0.000036 0.000038 2018 2 16 58165 0.001348 0.315040 0.1791409 0.0009340 0.000130 -0.000287 0.000056 0.000039 0.0000118 0.0000122 0.000036 0.000038 2018 2 17 58166 0.001023 0.316434 0.1781745 0.0010498 0.000127 -0.000285 0.000056 0.000039 0.0000118 0.0000122 0.000036 0.000038 2018 2 18 58167 0.000643 0.317986 0.1771163 0.0011086 0.000125 -0.000286 0.000056 0.000039 0.0000119 0.0000122 0.000037 0.000038 2018 2 19 58168 0.000907 0.319569 0.1759756 0.0011378 0.000124 -0.000287 0.000057 0.000039 0.0000119 0.0000122 0.000037 0.000038 2018 2 20 58169 0.001162 0.321719 0.1747959 0.0011246 0.000122 -0.000288 0.000056 0.000039 0.0000120 0.0000122 0.000037 0.000039 2018 2 21 58170 0.002029 0.324307 0.1736372 0.0011258 0.000113 -0.000286 0.000056 0.000039 0.0000121 0.0000122 0.000037 0.000038 2018 2 22 58171 0.002404 0.327028 0.1725392 0.0010527 0.000102 -0.000283 0.000056 0.000039 0.0000121 0.0000122 0.000038 0.000038 2018 2 23 58172 0.002546 0.329196 0.1715292 0.0009602 0.000091 -0.000280 0.000056 0.000039 0.0000121 0.0000122 0.000038 0.000038 2018 2 24 58173 0.002346 0.331737 0.1706169 0.0008620 0.000084 -0.000267 0.000056 0.000039 0.0000122 0.0000122 0.000038 0.000037 2018 2 25 58174 0.001950 0.333862 0.1697908 0.0007958 0.000080 -0.000251 0.000056 0.000039 0.0000122 0.0000122 0.000038 0.000037 2018 2 26 58175 0.001248 0.336065 0.1690150 0.0007669 0.000075 -0.000234 0.000056 0.000039 0.0000122 0.0000122 0.000039 0.000037 2018 2 27 58176 0.000269 0.337967 0.1682352 0.0008250 0.000071 -0.000217 0.000056 0.000039 0.0000122 0.0000122 0.000039 0.000036 2018 2 28 58177 -0.000516 0.339621 0.1673848 0.0009292 0.000065 -0.000248 0.000056 0.000039 0.0000121 0.0000122 0.000039 0.000037 2018 3 1 58178 -0.000331 0.341456 0.1664040 0.0010315 0.000060 -0.000292 0.000056 0.000039 0.0000121 0.0000122 0.000040 0.000038 2018 3 2 58179 0.001126 0.343708 0.1652728 0.0011896 0.000054 -0.000336 0.000056 0.000039 0.0000121 0.0000122 0.000040 0.000039 2018 3 3 58180 0.002712 0.346327 0.1640424 0.0012725 0.000077 -0.000301 0.000056 0.000039 0.0000122 0.0000122 0.000040 0.000040 2018 3 4 58181 0.003975 0.349010 0.1627918 0.0012376 0.000112 -0.000236 0.000056 0.000039 0.0000124 0.0000122 0.000041 0.000041 2018 3 5 58182 0.005332 0.351687 0.1615893 0.0011401 0.000147 -0.000172 0.000056 0.000039 0.0000125 0.0000122 0.000041 0.000043 2018 3 6 58183 0.006531 0.354263 0.1604864 0.0009967 0.000182 -0.000107 0.000056 0.000039 0.0000126 0.0000122 0.000042 0.000044 2018 3 7 58184 0.007274 0.356696 0.1594963 0.0009130 0.000149 -0.000118 0.000056 0.000039 0.0000127 0.0000122 0.000042 0.000045 2018 3 8 58185 0.007637 0.358777 0.1586161 0.0008357 0.000098 -0.000150 0.000055 0.000039 0.0000128 0.0000122 0.000042 0.000045 2018 3 9 58186 0.007944 0.360408 0.1578248 0.0007524 0.000047 -0.000181 0.000055 0.000039 0.0000128 0.0000122 0.000043 0.000045 2018 3 10 58187 0.008378 0.361611 0.1570935 0.0006874 0.000025 -0.000192 0.000056 0.000039 0.0000129 0.0000122 0.000043 0.000046 2018 3 11 58188 0.009615 0.362571 0.1563865 0.0006912 0.000014 -0.000197 0.000056 0.000039 0.0000130 0.0000122 0.000043 0.000047 2018 3 12 58189 0.011419 0.363948 0.1556864 0.0007115 0.000003 -0.000201 0.000056 0.000039 0.0000131 0.0000122 0.000044 0.000048 2018 3 13 58190 0.012950 0.365561 0.1549527 0.0007747 -0.000007 -0.000205 0.000056 0.000039 0.0000132 0.0000121 0.000044 0.000050 2018 3 14 58191 0.013959 0.367340 0.1541281 0.0008772 -0.000023 -0.000243 0.000056 0.000039 0.0000132 0.0000121 0.000044 0.000050 2018 3 15 58192 0.014539 0.369281 0.1532194 0.0009668 -0.000040 -0.000291 0.000056 0.000039 0.0000132 0.0000121 0.000045 0.000050 2018 3 16 58193 0.014779 0.371257 0.1522313 0.0010444 -0.000056 -0.000339 0.000056 0.000039 0.0000132 0.0000121 0.000045 0.000051 2018 3 17 58194 0.014886 0.373052 0.1511761 0.0011224 -0.000050 -0.000324 0.000056 0.000039 0.0000131 0.0000122 0.000045 0.000050 2018 3 18 58195 0.015019 0.374488 0.1500468 0.0011740 -0.000034 -0.000284 0.000056 0.000039 0.0000131 0.0000122 0.000045 0.000049 2018 3 19 58196 0.015609 0.375890 0.1488428 0.0012189 -0.000018 -0.000245 0.000056 0.000039 0.0000130 0.0000122 0.000045 0.000048 2018 3 20 58197 0.016813 0.377449 0.1475917 0.0012435 -0.000002 -0.000205 0.000056 0.000039 0.0000129 0.0000122 0.000046 0.000047 2018 3 21 58198 0.017650 0.378784 0.1463366 0.0012241 -0.000004 -0.000191 0.000056 0.000039 0.0000129 0.0000122 0.000046 0.000047 2018 3 22 58199 0.019086 0.379665 0.1451449 0.0011419 -0.000011 -0.000184 0.000056 0.000039 0.0000130 0.0000122 0.000046 0.000048 2018 3 23 58200 0.020817 0.381008 0.1440622 0.0010292 -0.000018 -0.000177 0.000056 0.000039 0.0000131 0.0000122 0.000046 0.000048 2018 3 24 58201 0.022159 0.382614 0.1430972 0.0009171 -0.000024 -0.000175 0.000056 0.000039 0.0000132 0.0000122 0.000047 0.000049 2018 3 25 58202 0.023438 0.384261 0.1422092 0.0008399 -0.000029 -0.000176 0.000056 0.000039 0.0000134 0.0000122 0.000047 0.000050 2018 3 26 58203 0.024380 0.385508 0.1413379 0.0008807 -0.000034 -0.000176 0.000056 0.000039 0.0000135 0.0000122 0.000047 0.000050 2018 3 27 58204 0.025665 0.386420 0.1404065 0.0010139 -0.000039 -0.000176 0.000056 0.000039 0.0000135 0.0000122 0.000047 0.000051 2018 3 28 58205 0.026966 0.387391 0.1393347 0.0011568 -0.000002 -0.000167 0.000056 0.000039 0.0000136 0.0000121 0.000048 0.000051 2018 3 29 58206 0.028097 0.388998 0.1381541 0.0012561 0.000010 -0.000156 0.000056 0.000039 0.0000137 0.0000121 0.000048 0.000051 2018 3 30 58207 0.029413 0.390776 0.1368509 0.0013371 0.000009 -0.000145 0.000056 0.000039 0.0000138 0.0000121 0.000048 0.000051 2018 3 31 58208 0.031024 0.392661 0.1354288 0.0013923 0.000008 -0.000135 0.000056 0.000039 0.0000140 0.0000121 0.000048 0.000051 2018 4 1 58209 0.032262 0.394493 0.1340372 0.0013722 0.000007 -0.000124 0.000056 0.000039 0.0000141 0.0000121 0.000048 0.000052 2018 4 2 58210 0.033078 0.396270 0.1327228 0.0012839 0.000006 -0.000114 0.000056 0.000039 0.0000142 0.0000121 0.000049 0.000052 2018 4 3 58211 0.033726 0.398187 0.1315290 0.0011210 0.000005 -0.000103 0.000056 0.000039 0.0000142 0.0000121 0.000049 0.000052 2018 4 4 58212 0.034053 0.400233 0.1304899 0.0009570 0.000004 -0.000093 0.000056 0.000039 0.0000142 0.0000121 0.000049 0.000052 2018 4 5 58213 0.034315 0.402096 0.1296118 0.0007920 -0.000018 -0.000109 0.000056 0.000039 0.0000142 0.0000121 0.000049 0.000053 2018 4 6 58214 0.034383 0.403888 0.1288635 0.0006835 -0.000045 -0.000132 0.000056 0.000039 0.0000142 0.0000121 0.000049 0.000053 2018 4 7 58215 0.034304 0.405470 0.1281968 0.0006690 -0.000039 -0.000140 0.000055 0.000039 0.0000142 0.0000121 0.000049 0.000054 2018 4 8 58216 0.034814 0.407120 0.1275568 0.0006626 -0.000021 -0.000142 0.000055 0.000039 0.0000142 0.0000121 0.000049 0.000054 2018 4 9 58217 0.035585 0.408611 0.1268920 0.0006681 -0.000003 -0.000143 0.000055 0.000039 0.0000141 0.0000121 0.000050 0.000054 2018 4 10 58218 0.036758 0.410135 0.1261868 0.0006805 0.000015 -0.000145 0.000055 0.000039 0.0000141 0.0000121 0.000050 0.000054 2018 4 11 58219 0.037937 0.411910 0.1254467 0.0007539 0.000006 -0.000131 0.000055 0.000039 0.0000139 0.0000121 0.000050 0.000054 2018 4 12 58220 0.038729 0.413822 0.1246552 0.0008512 -0.000010 -0.000114 0.000055 0.000039 0.0000138 0.0000121 0.000050 0.000054 2018 4 13 58221 0.038891 0.415750 0.1237615 0.0009701 -0.000026 -0.000096 0.000055 0.000039 0.0000136 0.0000121 0.000050 0.000054 2018 4 14 58222 0.039901 0.417161 0.1227404 0.0011177 -0.000020 -0.000076 0.000055 0.000039 0.0000135 0.0000121 0.000050 0.000055 2018 4 15 58223 0.041810 0.418839 0.1215701 0.0012640 -0.000005 -0.000054 0.000055 0.000039 0.0000133 0.0000121 0.000050 0.000055 2018 4 16 58224 0.044022 0.420295 0.1202380 0.0013772 0.000009 -0.000032 0.000055 0.000039 0.0000132 0.0000121 0.000050 0.000056 2018 4 17 58225 0.045901 0.421593 0.1188655 0.0013269 0.000024 -0.000011 0.000055 0.000039 0.0000131 0.0000120 0.000050 0.000056 2018 4 18 58226 0.047414 0.422322 0.1176157 0.0011790 -0.000014 -0.000003 0.000055 0.000039 0.0000129 0.0000120 0.000050 0.000056 2018 4 19 58227 0.049409 0.423167 0.1164865 0.0010522 -0.000065 0.000001 0.000055 0.000038 0.0000128 0.0000120 0.000050 0.000055 2018 4 20 58228 0.051700 0.424507 0.1154525 0.0009750 -0.000117 0.000005 0.000055 0.000038 0.0000126 0.0000120 0.000050 0.000054 2018 4 21 58229 0.053949 0.426011 0.1144821 0.0009481 -0.000104 -0.000020 0.000055 0.000038 0.0000125 0.0000120 0.000050 0.000053 2018 4 22 58230 0.056126 0.427544 0.1135260 0.0009773 -0.000067 -0.000056 0.000055 0.000038 0.0000124 0.0000120 0.000050 0.000052 2018 4 23 58231 0.057956 0.429171 0.1125234 0.0010753 -0.000030 -0.000091 0.000055 0.000038 0.0000124 0.0000120 0.000050 0.000051 2018 4 24 58232 0.059869 0.430738 0.1113951 0.0012418 0.000006 -0.000127 0.000055 0.000038 0.0000125 0.0000120 0.000050 0.000050 2018 4 25 58233 0.061417 0.432190 0.1100992 0.0013921 -0.000039 -0.000087 0.000055 0.000038 0.0000125 0.0000119 0.000049 0.000050 2018 4 26 58234 0.062620 0.433033 0.1086636 0.0014991 -0.000106 -0.000028 0.000055 0.000038 0.0000125 0.0000119 0.000049 0.000049 2018 4 27 58235 0.063635 0.433952 0.1071450 0.0015208 -0.000174 0.000032 0.000055 0.000038 0.0000124 0.0000119 0.000049 0.000048 2018 4 28 58236 0.064945 0.434755 0.1055951 0.0015117 -0.000182 -0.000043 0.000055 0.000038 0.0000124 0.0000119 0.000049 0.000048 2018 4 29 58237 0.066326 0.435745 0.1041191 0.0014257 -0.000168 -0.000169 0.000055 0.000038 0.0000124 0.0000119 0.000049 0.000047 2018 4 30 58238 0.067601 0.436689 0.1028034 0.0012537 -0.000155 -0.000296 0.000055 0.000038 0.0000124 0.0000119 0.000049 0.000046 2018 5 1 58239 0.068765 0.437662 0.1016513 0.0010894 -0.000158 -0.000265 0.000055 0.000038 0.0000125 0.0000119 0.000049 0.000045 2018 5 2 58240 0.069520 0.438837 0.1006354 0.0009498 -0.000165 -0.000193 0.000055 0.000038 0.0000125 0.0000119 0.000049 0.000045 2018 5 3 58241 0.070349 0.439382 0.0997424 0.0008206 -0.000173 -0.000121 0.000055 0.000038 0.0000125 0.0000119 0.000048 0.000044 2018 5 4 58242 0.071442 0.439846 0.0989734 0.0007079 -0.000134 -0.000093 0.000055 0.000038 0.0000125 0.0000119 0.000048 0.000044 2018 5 5 58243 0.072190 0.440340 0.0982642 0.0006546 -0.000099 -0.000101 0.000055 0.000038 0.0000124 0.0000119 0.000048 0.000044 2018 5 6 58244 0.073183 0.441116 0.0976011 0.0006706 -0.000070 -0.000117 0.000054 0.000038 0.0000123 0.0000119 0.000048 0.000044 2018 5 7 58245 0.074056 0.441974 0.0969513 0.0006702 -0.000042 -0.000133 0.000054 0.000038 0.0000123 0.0000118 0.000048 0.000044 2018 5 8 58246 0.075289 0.442794 0.0962777 0.0007266 -0.000014 -0.000149 0.000054 0.000038 0.0000123 0.0000118 0.000048 0.000044 2018 5 9 58247 0.076503 0.443814 0.0955178 0.0008166 0.000014 -0.000165 0.000054 0.000038 0.0000124 0.0000118 0.000048 0.000044 2018 5 10 58248 0.077859 0.444662 0.0946444 0.0009443 -0.000004 -0.000159 0.000054 0.000038 0.0000124 0.0000118 0.000048 0.000044 2018 5 11 58249 0.078921 0.445387 0.0936809 0.0009918 -0.000035 -0.000148 0.000054 0.000038 0.0000123 0.0000118 0.000048 0.000044 2018 5 12 58250 0.080633 0.445320 0.0926207 0.0010798 -0.000055 -0.000128 0.000054 0.000038 0.0000124 0.0000118 0.000048 0.000043 2018 5 13 58251 0.083066 0.445202 0.0915097 0.0011393 -0.000071 -0.000106 0.000054 0.000038 0.0000126 0.0000118 0.000048 0.000043 2018 5 14 58252 0.085130 0.445100 0.0904261 0.0010683 -0.000087 -0.000083 0.000054 0.000038 0.0000127 0.0000118 0.000048 0.000043 2018 5 15 58253 0.087493 0.445214 0.0894081 0.0009538 -0.000102 -0.000060 0.000054 0.000038 0.0000128 0.0000118 0.000048 0.000042 2018 5 16 58254 0.089595 0.445498 0.0885287 0.0007773 -0.000121 -0.000076 0.000054 0.000038 0.0000129 0.0000118 0.000048 0.000042 2018 5 17 58255 0.091800 0.445717 0.0877927 0.0006490 -0.000141 -0.000101 0.000054 0.000038 0.0000129 0.0000118 0.000049 0.000043 2018 5 18 58256 0.093988 0.446225 0.0871846 0.0005571 -0.000160 -0.000127 0.000054 0.000038 0.0000130 0.0000118 0.000049 0.000044 2018 5 19 58257 0.095672 0.446942 0.0866198 0.0005359 -0.000128 -0.000133 0.000054 0.000038 0.0000131 0.0000118 0.000049 0.000044 2018 5 20 58258 0.096977 0.447467 0.0860403 0.0006025 -0.000076 -0.000132 0.000054 0.000038 0.0000131 0.0000118 0.000049 0.000044 2018 5 21 58259 0.098121 0.447749 0.0854020 0.0007001 -0.000106 -0.000108 0.000054 0.000038 0.0000132 0.0000118 0.000049 0.000044 2018 5 22 58260 0.099178 0.447686 0.0846313 0.0008201 -0.000149 -0.000081 0.000054 0.000038 0.0000133 0.0000118 0.000049 0.000045 2018 5 23 58261 0.100747 0.447750 0.0837199 0.0009697 -0.000193 -0.000054 0.000054 0.000038 0.0000133 0.0000118 0.000049 0.000045 2018 5 24 58262 0.102548 0.447827 0.0826952 0.0010442 -0.000192 -0.000078 0.000054 0.000038 0.0000133 0.0000118 0.000049 0.000045 2018 5 25 58263 0.104514 0.447972 0.0816500 0.0010393 -0.000179 -0.000116 0.000054 0.000038 0.0000133 0.0000118 0.000049 0.000046 2018 5 26 58264 0.105963 0.447994 0.0806253 0.0009715 -0.000179 -0.000127 0.000054 0.000038 0.0000133 0.0000118 0.000049 0.000046 2018 5 27 58265 0.107448 0.447738 0.0796856 0.0008876 -0.000183 -0.000128 0.000054 0.000038 0.0000132 0.0000118 0.000049 0.000047 2018 5 28 58266 0.109050 0.447462 0.0788342 0.0007686 -0.000188 -0.000129 0.000054 0.000038 0.0000132 0.0000118 0.000050 0.000049 2018 5 29 58267 0.110654 0.447233 0.0781916 0.0005957 -0.000192 -0.000130 0.000054 0.000038 0.0000131 0.0000118 0.000050 0.000050 2018 5 30 58268 0.112145 0.447210 0.0777028 0.0004489 -0.000196 -0.000132 0.000054 0.000038 0.0000131 0.0000118 0.000050 0.000051 2018 5 31 58269 0.113238 0.447171 0.0773029 0.0003526 -0.000187 -0.000098 0.000054 0.000038 0.0000131 0.0000118 0.000050 0.000052 2018 6 1 58270 0.114210 0.446949 0.0769859 0.0003037 -0.000175 -0.000054 0.000054 0.000038 0.0000131 0.0000118 0.000050 0.000053 2018 6 2 58271 0.116000 0.446795 0.0766843 0.0003065 -0.000180 -0.000052 0.000054 0.000038 0.0000131 0.0000118 0.000050 0.000054 2018 6 3 58272 0.117672 0.446819 0.0763717 0.0003404 -0.000192 -0.000065 0.000055 0.000039 0.0000132 0.0000118 0.000050 0.000054 2018 6 4 58273 0.118894 0.446915 0.0760220 0.0003991 -0.000203 -0.000078 0.000055 0.000039 0.0000134 0.0000118 0.000050 0.000054 2018 6 5 58274 0.120342 0.446952 0.0756060 0.0004776 -0.000214 -0.000092 0.000055 0.000039 0.0000135 0.0000118 0.000050 0.000054 2018 6 6 58275 0.121747 0.447225 0.0751102 0.0005681 -0.000201 -0.000090 0.000055 0.000039 0.0000136 0.0000118 0.000050 0.000053 2018 6 7 58276 0.122644 0.447324 0.0744992 0.0006524 -0.000182 -0.000084 0.000055 0.000039 0.0000137 0.0000118 0.000050 0.000053 2018 6 8 58277 0.123501 0.447248 0.0737808 0.0007832 -0.000163 -0.000078 0.000055 0.000039 0.0000138 0.0000118 0.000050 0.000052 2018 6 9 58278 0.124610 0.446848 0.0729647 0.0008502 -0.000104 -0.000107 0.000055 0.000039 0.0000139 0.0000118 0.000050 0.000052 2018 6 10 58279 0.125717 0.446336 0.0720932 0.0008620 -0.000030 -0.000149 0.000055 0.000039 0.0000140 0.0000118 0.000050 0.000052 2018 6 11 58280 0.127341 0.445679 0.0712602 0.0007992 -0.000071 -0.000106 0.000055 0.000039 0.0000141 0.0000118 0.000050 0.000052 2018 6 12 58281 0.128905 0.445424 0.0705446 0.0006350 -0.000164 -0.000025 0.000055 0.000039 0.0000142 0.0000118 0.000050 0.000052 2018 6 13 58282 0.130659 0.445312 0.0699876 0.0004698 -0.000200 -0.000058 0.000055 0.000038 0.0000141 0.0000118 0.000050 0.000052 2018 6 14 58283 0.132046 0.445215 0.0695863 0.0003253 -0.000222 -0.000120 0.000054 0.000038 0.0000141 0.0000117 0.000050 0.000053 2018 6 15 58284 0.133109 0.444532 0.0693087 0.0002358 -0.000244 -0.000182 0.000054 0.000038 0.0000141 0.0000117 0.000050 0.000053 2018 6 16 58285 0.134123 0.443412 0.0690922 0.0002020 -0.000228 -0.000159 0.000054 0.000038 0.0000140 0.0000117 0.000050 0.000052 2018 6 17 58286 0.135386 0.442035 0.0688800 0.0002342 -0.000198 -0.000104 0.000054 0.000038 0.0000140 0.0000117 0.000050 0.000052 2018 6 18 58287 0.136764 0.440775 0.0685978 0.0003425 -0.000168 -0.000048 0.000053 0.000038 0.0000139 0.0000117 0.000050 0.000051 2018 6 19 58288 0.138420 0.439691 0.0682100 0.0004256 -0.000138 0.000007 0.000053 0.000038 0.0000139 0.0000117 0.000050 0.000050 2018 6 20 58289 0.140390 0.438615 0.0677780 0.0004504 -0.000141 -0.000009 0.000053 0.000038 0.0000138 0.0000117 0.000050 0.000050 2018 6 21 58290 0.142450 0.438071 0.0673423 0.0003833 -0.000152 -0.000044 0.000052 0.000038 0.0000137 0.0000117 0.000050 0.000049 2018 6 22 58291 0.144511 0.437432 0.0669892 0.0002672 -0.000164 -0.000078 0.000052 0.000038 0.0000136 0.0000117 0.000050 0.000049 2018 6 23 58292 0.146600 0.436646 0.0668460 0.0000814 -0.000177 -0.000076 0.000052 0.000038 0.0000137 0.0000117 0.000050 0.000049 2018 6 24 58293 0.148455 0.435852 0.0669409 -0.0001473 -0.000192 -0.000059 0.000052 0.000038 0.0000139 0.0000117 0.000050 0.000049 2018 6 25 58294 0.150195 0.435051 0.0671880 -0.0003268 -0.000207 -0.000042 0.000052 0.000038 0.0000141 0.0000117 0.000050 0.000049 2018 6 26 58295 0.152116 0.433889 0.0675349 -0.0004823 -0.000221 -0.000025 0.000052 0.000038 0.0000142 0.0000117 0.000050 0.000048 2018 6 27 58296 0.153952 0.432657 0.0680172 -0.0005866 -0.000197 -0.000005 0.000052 0.000038 0.0000144 0.0000117 0.000050 0.000049 2018 6 28 58297 0.156053 0.431580 0.0686157 -0.0006457 -0.000162 0.000017 0.000052 0.000038 0.0000145 0.0000117 0.000050 0.000049 2018 6 29 58298 0.158519 0.430881 0.0692978 -0.0006204 -0.000128 0.000038 0.000053 0.000038 0.0000146 0.0000117 0.000051 0.000049 2018 6 30 58299 0.160961 0.430375 0.0699969 -0.0006147 -0.000119 0.000036 0.000053 0.000038 0.0000147 0.0000117 0.000051 0.000049 2018 7 1 58300 0.162871 0.429780 0.0706673 -0.0005928 -0.000119 0.000026 0.000053 0.000038 0.0000148 0.0000117 0.000051 0.000050 2018 7 2 58301 0.164852 0.428652 0.0712428 -0.0005769 -0.000120 0.000016 0.000053 0.000037 0.0000148 0.0000117 0.000051 0.000050 2018 7 3 58302 0.166885 0.427192 0.0716877 -0.0004792 -0.000120 0.000006 0.000052 0.000037 0.0000148 0.0000117 0.000051 0.000051 2018 7 4 58303 0.169493 0.425894 0.0720020 -0.0003125 -0.000109 -0.000011 0.000052 0.000037 0.0000148 0.0000117 0.000051 0.000051 2018 7 5 58304 0.172372 0.425368 0.0722155 -0.0001618 -0.000094 -0.000030 0.000052 0.000037 0.0000148 0.0000117 0.000051 0.000051 2018 7 6 58305 0.174544 0.425409 0.0723399 -0.0000079 -0.000079 -0.000050 0.000052 0.000037 0.0000148 0.0000117 0.000052 0.000050 2018 7 7 58306 0.176281 0.425151 0.0723312 0.0000967 -0.000099 -0.000053 0.000052 0.000037 0.0000148 0.0000117 0.000052 0.000050 2018 7 8 58307 0.177822 0.425068 0.0722035 0.0001420 -0.000133 -0.000050 0.000052 0.000037 0.0000148 0.0000117 0.000052 0.000050 2018 7 9 58308 0.178757 0.424807 0.0720414 0.0001328 -0.000167 -0.000048 0.000052 0.000037 0.0000148 0.0000117 0.000052 0.000049 2018 7 10 58309 0.179172 0.423852 0.0718882 0.0001034 -0.000201 -0.000046 0.000051 0.000036 0.0000147 0.0000117 0.000052 0.000049 2018 7 11 58310 0.180186 0.422669 0.0717859 0.0000650 -0.000175 -0.000011 0.000051 0.000036 0.0000146 0.0000117 0.000052 0.000048 2018 7 12 58311 0.181301 0.421677 0.0717594 -0.0000210 -0.000131 0.000031 0.000051 0.000036 0.0000144 0.0000118 0.000052 0.000048 2018 7 13 58312 0.182418 0.420426 0.0717762 -0.0000531 -0.000088 0.000074 0.000050 0.000036 0.0000143 0.0000118 0.000052 0.000048 2018 7 14 58313 0.184079 0.419376 0.0717853 0.0000123 -0.000100 0.000092 0.000050 0.000036 0.0000142 0.0000118 0.000053 0.000047 2018 7 15 58314 0.185564 0.418707 0.0716902 0.0001510 -0.000133 0.000100 0.000050 0.000036 0.0000142 0.0000118 0.000053 0.000047 2018 7 16 58315 0.186391 0.418469 0.0714208 0.0003376 -0.000166 0.000109 0.000049 0.000036 0.0000142 0.0000118 0.000053 0.000047 2018 7 17 58316 0.187240 0.418109 0.0709820 0.0004982 -0.000199 0.000117 0.000049 0.000036 0.0000142 0.0000118 0.000053 0.000047 2018 7 18 58317 0.188227 0.417540 0.0704302 0.0005515 -0.000202 0.000108 0.000049 0.000036 0.0000142 0.0000118 0.000053 0.000047 2018 7 19 58318 0.189238 0.416763 0.0698823 0.0005042 -0.000197 0.000095 0.000049 0.000036 0.0000141 0.0000118 0.000054 0.000048 2018 7 20 58319 0.190448 0.415788 0.0694402 0.0003588 -0.000193 0.000081 0.000049 0.000036 0.0000140 0.0000118 0.000054 0.000049 2018 7 21 58320 0.191637 0.414675 0.0691558 0.0001953 -0.000179 0.000083 0.000049 0.000036 0.0000139 0.0000119 0.000054 0.000050 2018 7 22 58321 0.192614 0.413612 0.0690418 0.0000312 -0.000161 0.000092 0.000049 0.000036 0.0000139 0.0000119 0.000054 0.000051 2018 7 23 58322 0.193731 0.412738 0.0690641 -0.0000813 -0.000144 0.000100 0.000049 0.000036 0.0000138 0.0000119 0.000055 0.000052 2018 7 24 58323 0.194740 0.412257 0.0691774 -0.0001218 -0.000126 0.000109 0.000049 0.000036 0.0000138 0.0000119 0.000055 0.000053 2018 7 25 58324 0.195441 0.411953 0.0693378 -0.0001512 -0.000129 0.000096 0.000050 0.000036 0.0000138 0.0000119 0.000056 0.000055 2018 7 26 58325 0.195783 0.411402 0.0695047 -0.0001754 -0.000136 0.000077 0.000050 0.000037 0.0000138 0.0000120 0.000056 0.000056 2018 7 27 58326 0.196299 0.410511 0.0696524 -0.0001537 -0.000144 0.000059 0.000050 0.000037 0.0000138 0.0000120 0.000056 0.000058 2018 7 28 58327 0.196883 0.409820 0.0698066 -0.0001301 -0.000130 0.000069 0.000050 0.000037 0.0000137 0.0000120 0.000057 0.000060 2018 7 29 58328 0.197516 0.408770 0.0699385 -0.0000860 -0.000107 0.000090 0.000050 0.000037 0.0000135 0.0000120 0.000057 0.000061 2018 7 30 58329 0.198295 0.407726 0.0699910 -0.0000152 -0.000085 0.000111 0.000050 0.000037 0.0000134 0.0000121 0.000058 0.000062 2018 7 31 58330 0.198408 0.406559 0.0699410 0.0000754 -0.000062 0.000132 0.000050 0.000037 0.0000132 0.0000121 0.000058 0.000064 2018 8 1 58331 0.198567 0.405230 0.0697827 0.0001948 -0.000067 0.000088 0.000050 0.000037 0.0000129 0.0000121 0.000058 0.000066 2018 8 2 58332 0.198928 0.404282 0.0695405 0.0002858 -0.000079 0.000027 0.000050 0.000037 0.0000127 0.0000122 0.000059 0.000067 2018 8 3 58333 0.199383 0.403118 0.0692490 0.0003289 -0.000092 -0.000035 0.000050 0.000037 0.0000125 0.0000122 0.000059 0.000070 2018 8 4 58334 0.199965 0.402113 0.0689270 0.0003065 -0.000140 -0.000048 0.000050 0.000037 0.0000123 0.0000122 0.000059 0.000072 2018 8 5 58335 0.200232 0.401033 0.0686353 0.0002713 -0.000202 -0.000043 0.000050 0.000038 0.0000121 0.0000123 0.000060 0.000075 2018 8 6 58336 0.200431 0.399820 0.0684321 0.0001688 -0.000264 -0.000038 0.000050 0.000038 0.0000119 0.0000123 0.000060 0.000078 2018 8 7 58337 0.200636 0.398585 0.0683256 0.0000637 -0.000326 -0.000033 0.000049 0.000038 0.0000117 0.0000123 0.000060 0.000081 2018 8 8 58338 0.200792 0.397380 0.0683069 -0.0000044 -0.000282 -0.000002 0.000050 0.000038 0.0000119 0.0000124 0.000061 0.000082 2018 8 9 58339 0.200735 0.396172 0.0682933 0.0000438 -0.000212 0.000035 0.000050 0.000038 0.0000122 0.0000124 0.000061 0.000084 2018 8 10 58340 0.201186 0.394671 0.0682018 0.0001696 -0.000141 0.000073 0.000050 0.000038 0.0000125 0.0000125 0.000061 0.000085 2018 8 11 58341 0.202013 0.393049 0.0679453 0.0003397 -0.000147 0.000079 0.000050 0.000038 0.0000127 0.0000123 0.000061 0.000086 2018 8 12 58342 0.203168 0.391474 0.0675175 0.0005155 -0.000183 0.000072 0.000050 0.000038 0.0000129 0.0000124 0.000061 0.000086 2018 8 13 58343 0.203873 0.390131 0.0669514 0.0005994 -0.000218 0.000066 0.000049 0.000037 0.0000131 0.0000122 0.000061 0.000086 2018 8 14 58344 0.204204 0.388855 0.0663162 0.0006048 -0.000253 0.000060 0.000050 0.000038 0.0000133 0.0000122 0.000061 0.000086 2018 8 15 58345 0.204222 0.387607 0.0657262 0.0005749 -0.000215 0.000109 0.000050 0.000038 0.0000134 0.0000123 0.000061 0.000085 2018 8 16 58346 0.204491 0.386161 0.0651953 0.0004866 -0.000159 0.000172 0.000050 0.000038 0.0000136 0.0000123 0.000061 0.000083 2018 8 17 58347 0.204697 0.384858 0.0647660 0.0003637 -0.000102 0.000235 0.000050 0.000038 0.0000137 0.0000124 0.000061 0.000082 2018 8 18 58348 0.205208 0.383290 0.0644980 0.0001888 -0.000066 0.000260 0.000050 0.000038 0.0000139 0.0000125 0.000061 0.000082 2018 8 19 58349 0.205710 0.381891 0.0644053 0.0000218 -0.000038 0.000271 0.000050 0.000037 0.0000141 0.0000122 0.000061 0.000084 2018 8 20 58350 0.206205 0.380975 0.0644261 -0.0000671 -0.000041 0.000210 0.000051 0.000038 0.0000143 0.0000123 0.000061 0.000085 2018 8 21 58351 0.207158 0.380236 0.0645243 -0.0001217 -0.000050 0.000134 0.000051 0.000038 0.0000146 0.0000123 0.000061 0.000085 2018 8 22 58352 0.207972 0.379551 0.0646862 -0.0001424 -0.000031 0.000151 0.000052 0.000038 0.0000148 0.0000124 0.000061 0.000084 2018 8 23 58353 0.208582 0.378510 0.0648586 -0.0001537 -0.000005 0.000192 0.000052 0.000038 0.0000144 0.0000124 0.000060 0.000083 2018 8 24 58354 0.209114 0.377213 0.0650048 -0.0001779 0.000021 0.000233 0.000053 0.000038 0.0000146 0.0000125 0.000060 0.000081 2018 8 25 58355 0.209678 0.376017 0.0651013 -0.0001032 -0.000004 0.000245 0.000053 0.000039 0.0000147 0.0000125 0.000060 0.000079 2018 8 26 58356 0.210426 0.375049 0.0651186 0.0000334 -0.000048 0.000246 0.000053 0.000039 0.0000149 0.0000126 0.000060 0.000078 2018 8 27 58357 0.210969 0.373850 0.0650147 0.0001808 -0.000092 0.000247 0.000053 0.000038 0.0000150 0.0000123 0.000059 0.000076 2018 8 28 58358 0.211157 0.372845 0.0647918 0.0003014 -0.000136 0.000248 0.000053 0.000038 0.0000152 0.0000123 0.000059 0.000074 2018 8 29 58359 0.211142 0.371729 0.0644813 0.0003395 -0.000113 0.000225 0.000053 0.000039 0.0000154 0.0000124 0.000059 0.000072 2018 8 30 58360 0.211548 0.370511 0.0641044 0.0003904 -0.000072 0.000197 0.000054 0.000039 0.0000156 0.0000124 0.000058 0.000069 2018 8 31 58361 0.211819 0.369442 0.0636996 0.0004154 -0.000031 0.000168 0.000054 0.000039 0.0000158 0.0000125 0.000058 0.000067 2018 9 1 58362 0.211659 0.367906 0.0633163 0.0003848 -0.000041 0.000201 0.000054 0.000039 0.0000158 0.0000126 0.000057 0.000066 2018 9 2 58363 0.211577 0.366188 0.0629941 0.0002587 -0.000070 0.000258 0.000054 0.000039 0.0000161 0.0000126 0.000057 0.000066 2018 9 3 58364 0.211673 0.364479 0.0627594 0.0001541 -0.000081 0.000279 0.000055 0.000039 0.0000164 0.0000127 0.000057 0.000066 2018 9 4 58365 0.211634 0.363167 0.0626152 0.0001077 -0.000051 0.000218 0.000055 0.000040 0.0000166 0.0000128 0.000057 0.000068 2018 9 5 58366 0.211640 0.361805 0.0625141 0.0001020 -0.000039 0.000212 0.000055 0.000040 0.0000168 0.0000128 0.000056 0.000068 2018 9 6 58367 0.212048 0.360904 0.0623951 0.0001653 -0.000031 0.000219 0.000054 0.000039 0.0000171 0.0000125 0.000056 0.000068 2018 9 7 58368 0.212541 0.360446 0.0621697 0.0002882 -0.000024 0.000226 0.000055 0.000039 0.0000169 0.0000125 0.000056 0.000068 2018 9 8 58369 0.212705 0.359876 0.0617750 0.0004833 -0.000048 0.000261 0.000055 0.000039 0.0000171 0.0000126 0.000055 0.000068 2018 9 9 58370 0.212593 0.359172 0.0611591 0.0007147 -0.000084 0.000304 0.000055 0.000039 0.0000174 0.0000126 0.000055 0.000069 2018 9 10 58371 0.212953 0.358347 0.0603230 0.0009400 -0.000121 0.000348 0.000054 0.000039 0.0000176 0.0000123 0.000055 0.000070 2018 9 11 58372 0.213677 0.357568 0.0593573 0.0009847 -0.000157 0.000392 0.000054 0.000039 0.0000179 0.0000124 0.000054 0.000071 2018 9 12 58373 0.214091 0.356765 0.0583947 0.0009403 -0.000142 0.000337 0.000054 0.000039 0.0000181 0.0000124 0.000054 0.000070 2018 9 13 58374 0.213972 0.355925 0.0575376 0.0007586 -0.000113 0.000256 0.000054 0.000039 0.0000180 0.0000124 0.000053 0.000070 2018 9 14 58375 0.213400 0.355115 0.0568606 0.0005625 -0.000085 0.000175 0.000054 0.000039 0.0000169 0.0000125 0.000053 0.000069 2018 9 15 58376 0.212829 0.354057 0.0563961 0.0003670 -0.000074 0.000192 0.000054 0.000039 0.0000172 0.0000125 0.000053 0.000068 2018 9 16 58377 0.212199 0.352900 0.0561269 0.0002203 -0.000070 0.000246 0.000053 0.000039 0.0000173 0.0000122 0.000052 0.000067 2018 9 17 58378 0.211977 0.351630 0.0559831 0.0001201 -0.000066 0.000299 0.000053 0.000039 0.0000175 0.0000123 0.000052 0.000066 2018 9 18 58379 0.212054 0.350327 0.0559101 0.0000571 -0.000062 0.000353 0.000053 0.000039 0.0000177 0.0000123 0.000051 0.000065 2018 9 19 58380 0.212096 0.348780 0.0558825 0.0000390 -0.000028 0.000336 0.000053 0.000039 0.0000179 0.0000123 0.000051 0.000062 2018 9 20 58381 0.211925 0.347173 0.0558190 0.0000949 0.000014 0.000301 0.000053 0.000039 0.0000167 0.0000124 0.000050 0.000060 2018 9 21 58382 0.211828 0.345665 0.0556640 0.0002158 0.000056 0.000266 0.000052 0.000039 0.0000130 0.0000124 0.000050 0.000058 2018 9 22 58383 0.211821 0.344294 0.0553655 0.0003614 0.000075 0.000258 0.000052 0.000039 0.0000132 0.0000125 0.000049 0.000056 2018 9 23 58384 0.211590 0.342637 0.0549109 0.0005122 0.000084 0.000259 0.000052 0.000039 0.0000134 0.0000126 0.000048 0.000054 2018 9 24 58385 0.211872 0.340887 0.0543066 0.0006748 0.000094 0.000260 0.000052 0.000039 0.0000137 0.0000122 0.000048 0.000052 2018 9 25 58386 0.211960 0.339315 0.0535719 0.0008149 0.000104 0.000262 0.000052 0.000039 0.0000139 0.0000123 0.000047 0.000051 2018 9 26 58387 0.211289 0.337662 0.0527362 0.0008751 0.000113 0.000263 0.000051 0.000039 0.0000141 0.0000123 0.000047 0.000049 2018 9 27 58388 0.210522 0.336045 0.0518376 0.0009016 0.000122 0.000269 0.000051 0.000039 0.0000146 0.0000124 0.000046 0.000047 2018 9 28 58389 0.210397 0.334750 0.0509139 0.0009203 0.000130 0.000277 0.000051 0.000039 0.0000137 0.0000124 0.000046 0.000045 2018 9 29 58390 0.210482 0.333693 0.0500141 0.0008681 0.000130 0.000283 0.000051 0.000039 0.0000139 0.0000125 0.000045 0.000043 2018 9 30 58391 0.210513 0.332262 0.0491808 0.0007725 0.000126 0.000288 0.000052 0.000039 0.0000142 0.0000125 0.000045 0.000040 2018 10 1 58392 0.210528 0.330843 0.0484320 0.0006964 0.000122 0.000293 0.000051 0.000039 0.0000142 0.0000122 0.000044 0.000038 2018 10 2 58393 0.210618 0.329823 0.0477521 0.0006496 0.000118 0.000298 0.000051 0.000039 0.0000144 0.0000122 0.000043 0.000036 2018 10 3 58394 0.210355 0.328630 0.0470980 0.0006627 0.000140 0.000306 0.000051 0.000039 0.0000145 0.0000123 0.000043 0.000035 2018 10 4 58395 0.209699 0.327678 0.0463869 0.0007689 0.000169 0.000315 0.000050 0.000039 0.0000147 0.0000123 0.000043 0.000035 2018 10 5 58396 0.208569 0.326669 0.0455337 0.0009519 0.000199 0.000324 0.000050 0.000039 0.0000148 0.0000124 0.000042 0.000034 2018 10 6 58397 0.207798 0.325015 0.0444666 0.0011845 0.000196 0.000328 0.000050 0.000039 0.0000149 0.0000124 0.000042 0.000034 2018 10 7 58398 0.207422 0.323667 0.0431936 0.0013610 0.000181 0.000331 0.000049 0.000039 0.0000152 0.0000121 0.000042 0.000034 2018 10 8 58399 0.207032 0.322683 0.0417907 0.0014287 0.000166 0.000334 0.000049 0.000039 0.0000154 0.0000122 0.000042 0.000033 2018 10 9 58400 0.206379 0.321901 0.0403497 0.0013973 0.000151 0.000337 0.000049 0.000039 0.0000157 0.0000122 0.000041 0.000033 2018 10 10 58401 0.205780 0.321116 0.0389687 0.0012980 0.000190 0.000331 0.000049 0.000039 0.0000159 0.0000122 0.000041 0.000034 2018 10 11 58402 0.204962 0.320079 0.0377295 0.0011636 0.000243 0.000322 0.000049 0.000039 0.0000162 0.0000123 0.000041 0.000035 2018 10 12 58403 0.204071 0.318663 0.0366742 0.0009740 0.000297 0.000314 0.000049 0.000039 0.0000164 0.0000123 0.000041 0.000036 2018 10 13 58404 0.203072 0.316938 0.0357993 0.0007920 0.000280 0.000317 0.000049 0.000039 0.0000167 0.0000124 0.000041 0.000037 2018 10 14 58405 0.202237 0.315398 0.0350913 0.0006451 0.000236 0.000325 0.000049 0.000039 0.0000169 0.0000124 0.000041 0.000038 2018 10 15 58406 0.201709 0.314253 0.0345237 0.0005261 0.000193 0.000333 0.000048 0.000038 0.0000172 0.0000121 0.000041 0.000039 2018 10 16 58407 0.201587 0.313377 0.0340535 0.0004738 0.000149 0.000341 0.000048 0.000038 0.0000175 0.0000122 0.000041 0.000039 2018 10 17 58408 0.201061 0.312464 0.0336228 0.0004420 0.000155 0.000331 0.000048 0.000038 0.0000178 0.0000122 0.000041 0.000040 2018 10 18 58409 0.200195 0.311053 0.0331706 0.0004956 0.000173 0.000316 0.000048 0.000038 0.0000179 0.0000122 0.000041 0.000041 2018 10 19 58410 0.199086 0.309868 0.0326354 0.0005882 0.000192 0.000301 0.000048 0.000039 0.0000183 0.0000123 0.000040 0.000042 2018 10 20 58411 0.197901 0.308640 0.0319874 0.0007321 0.000222 0.000291 0.000048 0.000039 0.0000185 0.0000123 0.000040 0.000043 2018 10 21 58412 0.196795 0.307520 0.0311912 0.0008843 0.000258 0.000283 0.000048 0.000039 0.0000173 0.0000124 0.000040 0.000044 2018 10 22 58413 0.195484 0.306314 0.0302229 0.0010232 0.000294 0.000275 0.000048 0.000039 0.0000174 0.0000125 0.000040 0.000044 2018 10 23 58414 0.194680 0.304994 0.0290990 0.0011954 0.000329 0.000266 0.000048 0.000039 0.0000175 0.0000125 0.000040 0.000045 2018 10 24 58415 0.193785 0.304246 0.0278631 0.0012869 0.000300 0.000269 0.000049 0.000039 0.0000176 0.0000126 0.000040 0.000045 2018 10 25 58416 0.193195 0.303702 0.0265748 0.0012844 0.000254 0.000274 0.000048 0.000038 0.0000175 0.0000122 0.000039 0.000046 2018 10 26 58417 0.192548 0.303242 0.0253051 0.0011730 0.000207 0.000280 0.000049 0.000039 0.0000175 0.0000123 0.000039 0.000046 2018 10 27 58418 0.192071 0.302535 0.0241148 0.0011236 0.000203 0.000271 0.000049 0.000039 0.0000174 0.0000124 0.000039 0.000046 2018 10 28 58419 0.191657 0.302139 0.0230447 0.0010507 0.000215 0.000257 0.000050 0.000039 0.0000172 0.0000124 0.000039 0.000045 2018 10 29 58420 0.190191 0.301362 0.0220904 0.0009204 0.000227 0.000243 0.000050 0.000039 0.0000170 0.0000125 0.000039 0.000045 2018 10 30 58421 0.188153 0.300142 0.0212105 0.0008419 0.000239 0.000229 0.000051 0.000039 0.0000168 0.0000125 0.000038 0.000045 2018 10 31 58422 0.186298 0.298764 0.0203477 0.0008863 0.000258 0.000247 0.000052 0.000039 0.0000168 0.0000126 0.000038 0.000045 2018 11 1 58423 0.184510 0.297031 0.0194049 0.0010019 0.000290 0.000242 0.000052 0.000040 0.0000168 0.0000127 0.000038 0.000046 2018 11 2 58424 0.183144 0.295254 0.0183388 0.0011360 0.000327 0.000224 0.000053 0.000040 0.0000167 0.0000128 0.000038 0.000046 2018 11 3 58425 0.182231 0.293548 0.0171490 0.0012288 0.000364 0.000207 0.000054 0.000040 0.0000167 0.0000129 0.000037 0.000046 2018 11 4 58426 0.181200 0.292497 0.0159215 0.0012681 0.000385 0.000187 0.000053 0.000039 0.0000167 0.0000125 0.000037 0.000046 2018 11 5 58427 0.180114 0.291721 0.0146529 0.0012425 0.000363 0.000160 0.000053 0.000039 0.0000167 0.0000122 0.000037 0.000046 2018 11 6 58428 0.179336 0.291078 0.0134069 0.0012003 0.000341 0.000134 0.000054 0.000039 0.0000167 0.0000122 0.000036 0.000047 2018 11 7 58429 0.178247 0.290503 0.0122412 0.0011079 0.000436 0.000167 0.000027 0.000022 0.0000102 0.0000064 0.000036 0.000047 2018 11 8 58430 0.177661 0.289421 0.0111876 0.0009951 0.000563 0.000216 0.000028 0.000022 0.0000101 0.0000064 0.000036 0.000047 2018 11 9 58431 0.177501 0.288243 0.0102529 0.0008568 0.000426 0.000249 0.000028 0.000022 0.0000101 0.0000064 0.000035 0.000047 2018 11 10 58432 0.176916 0.286977 0.0094525 0.0007531 0.000350 0.000252 0.000028 0.000022 0.0000100 0.0000064 0.000035 0.000046 2018 11 11 58433 0.175896 0.285895 0.0087502 0.0006728 0.000328 0.000246 0.000028 0.000023 0.0000099 0.0000064 0.000035 0.000045 2018 11 12 58434 0.174771 0.284813 0.0080933 0.0006445 0.000307 0.000240 0.000028 0.000023 0.0000099 0.0000064 0.000034 0.000044 2018 11 13 58435 0.173670 0.283804 0.0074412 0.0006762 0.000285 0.000233 0.000028 0.000023 0.0000098 0.0000064 0.000034 0.000043 2018 11 14 58436 0.172446 0.282819 0.0067457 0.0007411 0.000277 0.000222 0.000028 0.000023 0.0000097 0.0000064 0.000033 0.000042 2018 11 15 58437 0.171170 0.281693 0.0059726 0.0008234 0.000273 0.000210 0.000028 0.000023 0.0000097 0.0000064 0.000033 0.000041 2018 11 16 58438 0.169491 0.280662 0.0050997 0.0008890 0.000269 0.000198 0.000028 0.000023 0.0000096 0.0000064 0.000033 0.000041 2018 11 17 58439 0.168053 0.279704 0.0041430 0.0010038 0.000282 0.000172 0.000028 0.000023 0.0000096 0.0000064 0.000032 0.000040 2018 11 18 58440 0.167032 0.279192 0.0030788 0.0011294 0.000301 0.000141 0.000028 0.000023 0.0000096 0.0000064 0.000032 0.000039 2018 11 19 58441 0.166027 0.278644 0.0018622 0.0012732 0.000321 0.000110 0.000029 0.000023 0.0000095 0.0000064 0.000032 0.000039 2018 11 20 58442 0.164954 0.278351 0.0005233 0.0013792 0.000341 0.000079 0.000029 0.000023 0.0000095 0.0000064 0.000031 0.000038 2018 11 21 58443 0.163866 0.278087 -0.0008724 0.0014208 0.000273 0.000112 0.000029 0.000023 0.0000095 0.0000064 0.000031 0.000038 2018 11 22 58444 0.162902 0.277650 -0.0022440 0.0013873 0.000380 0.000242 0.000029 0.000023 0.0000095 0.0000064 0.000030 0.000036 2018 11 23 58445 0.161893 0.277324 -0.0035499 0.0012594 0.000565 0.000403 0.000029 0.000023 0.0000096 0.0000064 0.000030 0.000035 2018 11 24 58446 0.160485 0.277286 -0.0047834 0.0011370 0.000521 0.000378 0.000029 0.000023 0.0000096 0.0000064 0.000029 0.000034 2018 11 25 58447 0.159235 0.277088 -0.0058934 0.0010245 0.000432 0.000316 0.000029 0.000023 0.0000095 0.0000064 0.000029 0.000032 2018 11 26 58448 0.158313 0.276843 -0.0068777 0.0009646 0.000342 0.000253 0.000029 0.000023 0.0000095 0.0000064 0.000029 0.000030 2018 11 27 58449 0.156839 0.276929 -0.0078373 0.0009866 0.000252 0.000190 0.000029 0.000023 0.0000095 0.0000064 0.000028 0.000029 2018 11 28 58450 0.154662 0.276653 -0.0088268 0.0010576 0.000263 0.000148 0.000029 0.000023 0.0000095 0.0000064 0.000028 0.000028 2018 11 29 58451 0.152413 0.276054 -0.0099233 0.0011645 0.000300 0.000111 0.000057 0.000039 0.0000137 0.0000127 0.000027 0.000028 2018 11 30 58452 0.150563 0.275167 -0.0111364 0.0012871 0.000337 0.000074 0.000057 0.000039 0.0000139 0.0000127 0.000027 0.000027 2018 12 1 58453 0.148511 0.274295 -0.0124404 0.0013301 0.000348 0.000100 0.000057 0.000040 0.0000155 0.0000128 0.000027 0.000027 2018 12 2 58454 0.146188 0.273492 -0.0137573 0.0012950 0.000349 0.000148 0.000058 0.000040 0.0000158 0.0000129 0.000026 0.000026 2018 12 3 58455 0.143733 0.272864 -0.0150086 0.0012135 0.000350 0.000197 0.000057 0.000039 0.0000159 0.0000126 0.000026 0.000025 2018 12 4 58456 0.141902 0.272288 -0.0161171 0.0010113 0.000351 0.000246 0.000057 0.000039 0.0000162 0.0000126 0.000026 0.000025 2018 12 5 58457 0.139736 0.272071 -0.0170051 0.0007823 0.000330 0.000223 0.000057 0.000039 0.0000164 0.0000127 0.000025 0.000024 2018 12 6 58458 0.137181 0.271827 -0.0176993 0.0006074 0.000303 0.000182 0.000057 0.000039 0.0000165 0.0000127 0.000025 0.000023 2018 12 7 58459 0.134745 0.271478 -0.0182430 0.0005137 0.000276 0.000140 0.000057 0.000039 0.0000164 0.0000128 0.000025 0.000022 2018 12 8 58460 0.132922 0.271000 -0.0187018 0.0004389 0.000290 0.000125 0.000057 0.000040 0.0000166 0.0000129 0.000024 0.000021 2018 12 9 58461 0.131771 0.270813 -0.0191110 0.0003767 0.000318 0.000120 0.000057 0.000040 0.0000167 0.0000129 0.000024 0.000020 2018 12 10 58462 0.130336 0.271024 -0.0194946 0.0003776 0.000346 0.000116 0.000057 0.000040 0.0000170 0.0000130 0.000024 0.000019 2018 12 11 58463 0.128667 0.271114 -0.0198879 0.0004417 0.000375 0.000111 0.000056 0.000040 0.0000139 0.0000131 0.000023 0.000018 2018 12 12 58464 0.126861 0.271006 -0.0203412 0.0004915 0.000372 0.000100 0.000056 0.000040 0.0000141 0.0000131 0.000023 0.000017 2018 12 13 58465 0.124815 0.270460 -0.0208707 0.0005611 0.000363 0.000088 0.000057 0.000040 0.0000143 0.0000132 0.000023 0.000016 2018 12 14 58466 0.123182 0.270033 -0.0214888 0.0006532 0.000353 0.000076 0.000056 0.000039 0.0000145 0.0000129 0.000022 0.000016 2018 12 15 58467 0.121105 0.269581 -0.0221963 0.0007461 0.000350 0.000071 0.000057 0.000040 0.0000146 0.0000129 0.000022 0.000015 2018 12 16 58468 0.119215 0.268992 -0.0230150 0.0008557 0.000349 0.000068 0.000057 0.000040 0.0000148 0.0000130 0.000022 0.000014 2018 12 17 58469 0.117513 0.268466 -0.0239543 0.0009899 0.000348 0.000065 0.000057 0.000040 0.0000148 0.0000131 0.000021 0.000013 2018 12 18 58470 0.115378 0.268031 -0.0249722 0.0010471 0.000347 0.000063 0.000057 0.000040 0.0000149 0.0000131 0.000021 0.000012 2018 12 19 58471 0.113310 0.267412 -0.0259807 0.0009827 0.000361 0.000033 0.000058 0.000040 0.0000149 0.0000132 0.000021 0.000013 2018 12 20 58472 0.111645 0.267029 -0.0268884 0.0008161 0.000380 -0.000003 0.000057 0.000040 0.0000149 0.0000129 0.000021 0.000014 2018 12 21 58473 0.109928 0.266784 -0.0276359 0.0006370 0.000398 -0.000040 0.000057 0.000040 0.0000149 0.0000130 0.000021 0.000014 2018 12 22 58474 0.107844 0.266547 -0.0282166 0.0005040 0.000389 -0.000035 0.000058 0.000040 0.0000149 0.0000130 0.000022 0.000015 2018 12 23 58475 0.105771 0.266523 -0.0286836 0.0004507 0.000371 -0.000015 0.000058 0.000040 0.0000149 0.0000131 0.000022 0.000016 2018 12 24 58476 0.103568 0.266619 -0.0291417 0.0004771 0.000352 0.000006 0.000058 0.000040 0.0000149 0.0000132 0.000022 0.000017 2018 12 25 58477 0.101399 0.266731 -0.0296751 0.0005616 0.000333 0.000026 0.000058 0.000040 0.0000150 0.0000133 0.000022 0.000018 2018 12 26 58478 0.099191 0.267291 -0.0302990 0.0007122 0.000314 0.000047 0.000059 0.000040 0.0000152 0.0000133 0.000022 0.000019 2018 12 27 58479 0.097243 0.268068 -0.0310764 0.0008673 0.000295 0.000067 0.000059 0.000041 0.0000153 0.0000135 0.000022 0.000020 2018 12 28 58480 0.095386 0.268935 -0.0320059 0.0010205 0.000303 -0.000007 0.000059 0.000041 0.0000154 0.0000135 0.000023 0.000021 2018 12 29 58481 0.093289 0.269801 -0.0330198 0.0011069 0.000345 -0.000102 0.000060 0.000041 0.0000150 0.0000137 0.000023 0.000022 2018 12 30 58482 0.090829 0.270475 -0.0340678 0.0010617 0.000388 -0.000173 0.000060 0.000041 0.0000151 0.0000138 0.000023 0.000023 2018 12 31 58483 0.088414 0.270763 -0.0351611 0.0009706 0.000383 -0.000138 0.000058 0.000040 0.0000152 0.0000130 0.000023 0.000023 2019 1 1 58484 0.086360 0.271107 -0.0361345 0.0009196 0.000379 -0.000102 0.000058 0.000040 0.0000152 0.0000130 0.000023 0.000023 2019 1 2 58485 0.084450 0.272019 -0.0370076 0.0008103 0.000374 -0.000066 0.000059 0.000040 0.0000153 0.0000131 0.000023 0.000023 2019 1 3 58486 0.081750 0.272569 -0.0377478 0.0006117 0.000370 -0.000030 0.000058 0.000040 0.0000109 0.0000132 0.000023 0.000023 2019 1 4 58487 0.079016 0.272577 -0.0382792 0.0004701 0.000395 -0.000077 0.000058 0.000040 0.0000108 0.0000132 0.000023 0.000023 2019 1 5 58488 0.076411 0.272536 -0.0387496 0.0004125 0.000387 -0.000101 0.000059 0.000040 0.0000142 0.0000133 0.000023 0.000022 2019 1 6 58489 0.074159 0.272895 -0.0391547 0.0003598 0.000366 -0.000108 0.000058 0.000040 0.0000139 0.0000130 0.000023 0.000022 2019 1 7 58490 0.072162 0.273364 -0.0394760 0.0003132 0.000344 -0.000116 0.000058 0.000040 0.0000129 0.0000131 0.000023 0.000021 2019 1 8 58491 0.071062 0.273800 -0.0397729 0.0003272 0.000323 -0.000124 0.000059 0.000040 0.0000129 0.0000131 0.000023 0.000021 2019 1 9 58492 0.070637 0.274756 -0.0401419 0.0004111 0.000351 -0.000133 0.000059 0.000040 0.0000128 0.0000132 0.000023 0.000020 2019 1 10 58493 0.069750 0.275757 -0.0405867 0.0004624 0.000393 -0.000143 0.000059 0.000040 0.0000126 0.0000133 0.000023 0.000019 2019 1 11 58494 0.068810 0.276031 -0.0410933 0.0005626 0.000434 -0.000152 0.000059 0.000040 0.0000125 0.0000133 0.000022 0.000018 2019 1 12 58495 0.068327 0.276958 -0.0417183 0.0006858 0.000431 -0.000146 0.000059 0.000040 0.0000124 0.0000134 0.000022 0.000018 2019 1 13 58496 0.067619 0.278392 -0.0424490 0.0007617 0.000405 -0.000131 0.000059 0.000040 0.0000115 0.0000131 0.000022 0.000017 2019 1 14 58497 0.067041 0.280037 -0.0432643 0.0008473 0.000380 -0.000117 0.000059 0.000040 0.0000114 0.0000132 0.000022 0.000016 2019 1 15 58498 0.066278 0.281989 -0.0441419 0.0008947 0.000354 -0.000102 0.000059 0.000040 0.0000114 0.0000132 0.000022 0.000016 2019 1 16 58499 0.065560 0.283745 -0.0450371 0.0008947 0.000317 -0.000097 0.000058 0.000040 0.0000114 0.0000133 0.000022 0.000016 2019 1 17 58500 0.064413 0.285541 -0.0459084 0.0008434 0.000277 -0.000094 0.000058 0.000040 0.0000110 0.0000134 0.000023 0.000017 2019 1 18 58501 0.063021 0.286806 -0.0467215 0.0007935 0.000237 -0.000091 0.000059 0.000040 0.0000110 0.0000134 0.000023 0.000017 2019 1 19 58502 0.061886 0.287736 -0.0474810 0.0007474 0.000231 -0.000104 0.000058 0.000040 0.0000108 0.0000135 0.000023 0.000018 2019 1 20 58503 0.060924 0.288663 -0.0482192 0.0007625 0.000237 -0.000122 0.000058 0.000039 0.0000107 0.0000132 0.000023 0.000019 2019 1 21 58504 0.059951 0.289646 -0.0490001 0.0008539 0.000244 -0.000141 0.000057 0.000039 0.0000098 0.0000132 0.000024 0.000020 2019 1 22 58505 0.059500 0.290588 -0.0499002 0.0009738 0.000250 -0.000160 0.000057 0.000039 0.0000098 0.0000133 0.000024 0.000021 2019 1 23 58506 0.059020 0.291974 -0.0509753 0.0011441 0.000257 -0.000178 0.000058 0.000039 0.0000099 0.0000133 0.000024 0.000021 2019 1 24 58507 0.058404 0.293938 -0.0522360 0.0013438 0.000228 -0.000173 0.000058 0.000040 0.0000099 0.0000134 0.000024 0.000022 2019 1 25 58508 0.057037 0.295895 -0.0536317 0.0014479 0.000189 -0.000160 0.000058 0.000040 0.0000094 0.0000135 0.000025 0.000023 2019 1 26 58509 0.055392 0.297230 -0.0550842 0.0014242 0.000207 -0.000156 0.000058 0.000040 0.0000095 0.0000136 0.000025 0.000024 2019 1 27 58510 0.054208 0.298636 -0.0565001 0.0013738 0.000246 -0.000154 0.000058 0.000039 0.0000095 0.0000132 0.000025 0.000024 2019 1 28 58511 0.053443 0.300145 -0.0577925 0.0012435 0.000284 -0.000153 0.000058 0.000039 0.0000096 0.0000133 0.000026 0.000025 2019 1 29 58512 0.052614 0.301578 -0.0589106 0.0010153 0.000323 -0.000151 0.000058 0.000039 0.0000096 0.0000133 0.000026 0.000026 2019 1 30 58513 0.051577 0.302934 -0.0598406 0.0008170 0.000306 -0.000143 0.000058 0.000040 0.0000096 0.0000134 0.000026 0.000027 2019 1 31 58514 0.050593 0.304306 -0.0605800 0.0006817 0.000273 -0.000132 0.000058 0.000040 0.0000094 0.0000135 0.000027 0.000027 2019 2 1 58515 0.049834 0.306171 -0.0611621 0.0005584 0.000241 -0.000122 0.000058 0.000040 0.0000093 0.0000135 0.000027 0.000028 2019 2 2 58516 0.049056 0.308504 -0.0616373 0.0004658 0.000251 -0.000143 0.000058 0.000040 0.0000094 0.0000136 0.000027 0.000028 2019 2 3 58517 0.047559 0.310550 -0.0620986 0.0005001 0.000278 -0.000177 0.000058 0.000039 0.0000094 0.0000133 0.000027 0.000029 2019 2 4 58518 0.045944 0.311689 -0.0626460 0.0005894 0.000305 -0.000211 0.000058 0.000039 0.0000091 0.0000133 0.000028 0.000029 2019 2 5 58519 0.044745 0.312776 -0.0633149 0.0007100 0.000332 -0.000244 0.000058 0.000040 0.0000091 0.0000133 0.000028 0.000030 2019 2 6 58520 0.043838 0.313876 -0.0640945 0.0008363 0.000317 -0.000240 0.000058 0.000040 0.0000091 0.0000134 0.000028 0.000031 2019 2 7 58521 0.043000 0.314914 -0.0649870 0.0009471 0.000291 -0.000225 0.000058 0.000040 0.0000090 0.0000135 0.000029 0.000031 2019 2 8 58522 0.042225 0.316266 -0.0659817 0.0010463 0.000265 -0.000210 0.000058 0.000040 0.0000088 0.0000135 0.000029 0.000032 2019 2 9 58523 0.041812 0.318184 -0.0670693 0.0011151 0.000270 -0.000186 0.000058 0.000040 0.0000087 0.0000136 0.000029 0.000032 2019 2 10 58524 0.041158 0.320405 -0.0682263 0.0011816 0.000287 -0.000159 0.000058 0.000040 0.0000087 0.0000132 0.000030 0.000033 2019 2 11 58525 0.040091 0.322109 -0.0694157 0.0011896 0.000305 -0.000132 0.000058 0.000040 0.0000086 0.0000133 0.000030 0.000034 2019 2 12 58526 0.038728 0.323345 -0.0706131 0.0011548 0.000322 -0.000106 0.000057 0.000040 0.0000086 0.0000133 0.000030 0.000034 2019 2 13 58527 0.037643 0.323847 -0.0717962 0.0011475 0.000319 -0.000138 0.000057 0.000040 0.0000085 0.0000134 0.000031 0.000035 2019 2 14 58528 0.036400 0.324163 -0.0729229 0.0010705 0.000312 -0.000186 0.000057 0.000040 0.0000085 0.0000134 0.000031 0.000036 2019 2 15 58529 0.035202 0.324437 -0.0739690 0.0010196 0.000304 -0.000234 0.000057 0.000040 0.0000084 0.0000135 0.000032 0.000037 2019 2 16 58530 0.034898 0.325551 -0.0749476 0.0009527 0.000243 -0.000240 0.000057 0.000040 0.0000084 0.0000135 0.000032 0.000038 2019 2 17 58531 0.035382 0.326979 -0.0759113 0.0009808 0.000178 -0.000234 0.000057 0.000040 0.0000085 0.0000132 0.000032 0.000039 2019 2 18 58532 0.036402 0.328814 -0.0769283 0.0010855 0.000203 -0.000244 0.000057 0.000040 0.0000086 0.0000132 0.000033 0.000040 2019 2 19 58533 0.037158 0.330699 -0.0781012 0.0012574 0.000228 -0.000254 0.000057 0.000040 0.0000086 0.0000133 0.000033 0.000040 2019 2 20 58534 0.037516 0.332551 -0.0794595 0.0014033 0.000252 -0.000264 0.000057 0.000040 0.0000087 0.0000133 0.000033 0.000041 2019 2 21 58535 0.037409 0.334157 -0.0809464 0.0015192 0.000250 -0.000223 0.000058 0.000040 0.0000088 0.0000134 0.000033 0.000042 2019 2 22 58536 0.036823 0.335959 -0.0824905 0.0015702 0.000240 -0.000168 0.000058 0.000040 0.0000089 0.0000134 0.000034 0.000043 2019 2 23 58537 0.035746 0.337468 -0.0840100 0.0014712 0.000248 -0.000155 0.000058 0.000040 0.0000086 0.0000135 0.000034 0.000043 2019 2 24 58538 0.035260 0.338447 -0.0853945 0.0012778 0.000263 -0.000159 0.000058 0.000040 0.0000087 0.0000131 0.000034 0.000043 2019 2 25 58539 0.035478 0.339220 -0.0865600 0.0010413 0.000278 -0.000164 0.000058 0.000040 0.0000087 0.0000132 0.000035 0.000043 2019 2 26 58540 0.035848 0.340191 -0.0874895 0.0008125 0.000293 -0.000168 0.000058 0.000040 0.0000087 0.0000132 0.000035 0.000043 2019 2 27 58541 0.036335 0.341340 -0.0882138 0.0006230 0.000297 -0.000171 0.000058 0.000040 0.0000087 0.0000133 0.000035 0.000043 2019 2 28 58542 0.037308 0.342419 -0.0887866 0.0005456 0.000299 -0.000174 0.000058 0.000040 0.0000086 0.0000134 0.000035 0.000043 2019 3 1 58543 0.038585 0.344058 -0.0892695 0.0004493 0.000301 -0.000177 0.000059 0.000040 0.0000085 0.0000134 0.000036 0.000044 2019 3 2 58544 0.040115 0.345746 -0.0897285 0.0004525 0.000303 -0.000185 0.000043 0.000029 0.0000062 0.0000097 0.000036 0.000044 2019 3 3 58545 0.041705 0.347321 -0.0902115 0.0005032 0.000306 -0.000194 0.000043 0.000029 0.0000061 0.0000096 0.000036 0.000045 2019 3 4 58546 0.043027 0.348978 -0.0907359 0.0005849 0.000309 -0.000204 0.000043 0.000029 0.0000061 0.0000098 0.000037 0.000045 2019 3 5 58547 0.043941 0.350881 -0.0913366 0.0006457 0.000312 -0.000214 0.000043 0.000029 0.0000062 0.0000098 0.000037 0.000046 2019 3 6 58548 0.044629 0.352612 -0.0920497 0.0007774 0.000290 -0.000221 0.000044 0.000029 0.0000062 0.0000099 0.000037 0.000046 2019 3 7 58549 0.045490 0.354228 -0.0928815 0.0009090 0.000261 -0.000228 0.000044 0.000029 0.0000062 0.0000099 0.000037 0.000047 2019 3 8 58550 0.045755 0.355899 -0.0938209 0.0009788 0.000232 -0.000236 0.000044 0.000029 0.0000063 0.0000099 0.000038 0.000047 2019 3 9 58551 0.045492 0.356807 -0.0948250 0.0010281 0.000229 -0.000240 0.000044 0.000029 0.0000063 0.0000099 0.000038 0.000047 2019 3 10 58552 0.045250 0.357817 -0.0958689 0.0010329 0.000235 -0.000244 0.000044 0.000029 0.0000064 0.0000100 0.000038 0.000047 2019 3 11 58553 0.045393 0.359065 -0.0969307 0.0010556 0.000241 -0.000248 0.000044 0.000029 0.0000064 0.0000099 0.000038 0.000047 2019 3 12 58554 0.045392 0.360610 -0.0979533 0.0009685 0.000248 -0.000252 0.000043 0.000029 0.0000064 0.0000098 0.000038 0.000047 2019 3 13 58555 0.044941 0.361834 -0.0988761 0.0008698 0.000251 -0.000239 0.000043 0.000029 0.0000065 0.0000098 0.000038 0.000047 2019 3 14 58556 0.044600 0.363157 -0.0997021 0.0007680 0.000254 -0.000222 0.000043 0.000029 0.0000062 0.0000099 0.000039 0.000046 2019 3 15 58557 0.044689 0.364244 -0.1004688 0.0007574 0.000257 -0.000204 0.000043 0.000029 0.0000062 0.0000099 0.000039 0.000046 2019 3 16 58558 0.044882 0.365639 -0.1012581 0.0008150 0.000243 -0.000205 0.000043 0.000029 0.0000062 0.0000100 0.000039 0.000045 2019 3 17 58559 0.045118 0.366716 -0.1021314 0.0009185 0.000223 -0.000214 0.000043 0.000029 0.0000062 0.0000100 0.000039 0.000044 2019 3 18 58560 0.045569 0.367665 -0.1031393 0.0011095 0.000203 -0.000223 0.000043 0.000029 0.0000062 0.0000100 0.000039 0.000043 2019 3 19 58561 0.045849 0.368711 -0.1043490 0.0013120 0.000184 -0.000232 0.000043 0.000029 0.0000062 0.0000100 0.000039 0.000043 2019 3 20 58562 0.045602 0.369656 -0.1057537 0.0015004 0.000243 -0.000206 0.000043 0.000029 0.0000062 0.0000101 0.000039 0.000042 2019 3 21 58563 0.045363 0.370584 -0.1073331 0.0016399 0.000324 -0.000171 0.000043 0.000029 0.0000061 0.0000101 0.000039 0.000041 2019 3 22 58564 0.045163 0.371781 -0.1090042 0.0016718 0.000239 -0.000265 0.000043 0.000029 0.0000061 0.0000101 0.000039 0.000040 2019 3 23 58565 0.045059 0.373068 -0.1106258 0.0015653 0.000200 -0.000254 0.000043 0.000029 0.0000061 0.0000102 0.000039 0.000040 2019 3 24 58566 0.045366 0.374421 -0.1121099 0.0013668 0.000199 -0.000189 0.000042 0.000029 0.0000061 0.0000098 0.000039 0.000039 2019 3 25 58567 0.045815 0.375834 -0.1133803 0.0011510 0.000197 -0.000124 0.000042 0.000029 0.0000061 0.0000098 0.000039 0.000039 2019 3 26 58568 0.045966 0.377276 -0.1144432 0.0009612 0.000196 -0.000059 0.000042 0.000029 0.0000061 0.0000098 0.000039 0.000039 2019 3 27 58569 0.045903 0.378402 -0.1153100 0.0008170 0.000188 -0.000077 0.000042 0.000029 0.0000061 0.0000099 0.000039 0.000038 2019 3 28 58570 0.046141 0.379230 -0.1160950 0.0007469 0.000177 -0.000116 0.000042 0.000029 0.0000061 0.0000099 0.000039 0.000038 2019 3 29 58571 0.046500 0.380235 -0.1168183 0.0006843 0.000166 -0.000155 0.000042 0.000029 0.0000061 0.0000099 0.000039 0.000038 2019 3 30 58572 0.047100 0.381203 -0.1175404 0.0007409 0.000160 -0.000179 0.000042 0.000029 0.0000062 0.0000100 0.000040 0.000038 2019 3 31 58573 0.047984 0.382645 -0.1183133 0.0008329 0.000155 -0.000197 0.000042 0.000029 0.0000062 0.0000100 0.000040 0.000038 2019 4 1 58574 0.048795 0.384044 -0.1191791 0.0009226 0.000149 -0.000216 0.000042 0.000029 0.0000061 0.0000100 0.000040 0.000037 2019 4 2 58575 0.049786 0.385278 -0.1201631 0.0010292 0.000144 -0.000234 0.000042 0.000029 0.0000062 0.0000100 0.000040 0.000037 2019 4 3 58576 0.050547 0.386499 -0.1212445 0.0011882 0.000148 -0.000224 0.000042 0.000029 0.0000062 0.0000100 0.000040 0.000037 2019 4 4 58577 0.051078 0.387917 -0.1224765 0.0012751 0.000154 -0.000207 0.000042 0.000029 0.0000061 0.0000098 0.000040 0.000038 2019 4 5 58578 0.051313 0.389067 -0.1237650 0.0012629 0.000159 -0.000190 0.000042 0.000029 0.0000061 0.0000099 0.000040 0.000038 2019 4 6 58579 0.051595 0.390130 -0.1250294 0.0012887 0.000156 -0.000186 0.000042 0.000029 0.0000061 0.0000099 0.000040 0.000038 2019 4 7 58580 0.051785 0.391337 -0.1263223 0.0012566 0.000149 -0.000186 0.000042 0.000028 0.0000062 0.0000097 0.000040 0.000038 2019 4 8 58581 0.051821 0.392345 -0.1275976 0.0012183 0.000142 -0.000186 0.000042 0.000029 0.0000063 0.0000098 0.000040 0.000038 2019 4 9 58582 0.052091 0.393318 -0.1287589 0.0011124 0.000135 -0.000187 0.000042 0.000029 0.0000064 0.0000098 0.000040 0.000038 2019 4 10 58583 0.052480 0.394328 -0.1297840 0.0009744 0.000149 -0.000165 0.000042 0.000029 0.0000064 0.0000098 0.000041 0.000039 2019 4 11 58584 0.053117 0.395119 -0.1307304 0.0008031 0.000167 -0.000138 0.000042 0.000029 0.0000065 0.0000098 0.000041 0.000039 2019 4 12 58585 0.053769 0.396173 -0.1314543 0.0007505 0.000186 -0.000111 0.000042 0.000029 0.0000065 0.0000098 0.000041 0.000040 2019 4 13 58586 0.054679 0.397319 -0.1322260 0.0008202 0.000184 -0.000124 0.000042 0.000029 0.0000066 0.0000098 0.000041 0.000041 2019 4 14 58587 0.055085 0.398276 -0.1330707 0.0009118 0.000174 -0.000153 0.000042 0.000029 0.0000066 0.0000098 0.000041 0.000041 2019 4 15 58588 0.055163 0.399057 -0.1340708 0.0010927 0.000165 -0.000182 0.000042 0.000028 0.0000068 0.0000096 0.000041 0.000042 2019 4 16 58589 0.055809 0.399974 -0.1352472 0.0012953 0.000155 -0.000211 0.000042 0.000029 0.0000068 0.0000096 0.000041 0.000042 2019 4 17 58590 0.056668 0.400687 -0.1365967 0.0014476 0.000103 -0.000210 0.000042 0.000029 0.0000069 0.0000096 0.000041 0.000043 2019 4 18 58591 0.057766 0.401049 -0.1380786 0.0014767 0.000039 -0.000202 0.000042 0.000029 0.0000069 0.0000097 0.000041 0.000044 2019 4 19 58592 0.058599 0.401935 -0.1394963 0.0013893 -0.000041 -0.000235 0.000042 0.000029 0.0000069 0.0000096 0.000041 0.000044 2019 4 20 58593 0.059160 0.402829 -0.1408141 0.0012170 -0.000126 -0.000284 0.000042 0.000029 0.0000069 0.0000097 0.000041 0.000044 2019 4 21 58594 0.060249 0.403665 -0.1419326 0.0010019 -0.000114 -0.000268 0.000042 0.000028 0.0000068 0.0000095 0.000041 0.000043 2019 4 22 58595 0.061350 0.404826 -0.1427672 0.0007530 -0.000053 -0.000221 0.000042 0.000028 0.0000068 0.0000095 0.000041 0.000043 2019 4 23 58596 0.062199 0.406269 -0.1433845 0.0005894 0.000009 -0.000173 0.000042 0.000029 0.0000068 0.0000095 0.000041 0.000042 2019 4 24 58597 0.062809 0.407465 -0.1440057 0.0005152 0.000070 -0.000125 0.000042 0.000029 0.0000068 0.0000095 0.000041 0.000042 2019 4 25 58598 0.063457 0.408277 -0.1444919 0.0004827 0.000067 -0.000122 0.000042 0.000029 0.0000068 0.0000096 0.000041 0.000042 2019 4 26 58599 0.064471 0.408795 -0.1449987 0.0005138 0.000047 -0.000130 0.000042 0.000029 0.0000067 0.0000096 0.000041 0.000043 2019 4 27 58600 0.065708 0.409250 -0.1455687 0.0005617 0.000030 -0.000204 0.000042 0.000029 0.0000067 0.0000095 0.000041 0.000043 2019 4 28 58601 0.067070 0.409477 -0.1461789 0.0006526 0.000014 -0.000304 0.000042 0.000029 0.0000066 0.0000096 0.000041 0.000042 2019 4 29 58602 0.068612 0.409997 -0.1468502 0.0007258 0.000113 -0.000247 0.000042 0.000029 0.0000066 0.0000097 0.000041 0.000042 2019 4 30 58603 0.070177 0.410662 -0.1476395 0.0008642 0.000221 -0.000176 0.000042 0.000029 0.0000066 0.0000096 0.000041 0.000041 2019 5 1 58604 0.072222 0.411351 -0.1485556 0.0010083 0.000203 -0.000173 0.000042 0.000029 0.0000066 0.0000096 0.000041 0.000040 2019 5 2 58605 0.074216 0.412141 -0.1496023 0.0010507 0.000152 -0.000188 0.000042 0.000029 0.0000067 0.0000094 0.000040 0.000039 2019 5 3 58606 0.075847 0.412864 -0.1506622 0.0010023 0.000100 -0.000202 0.000042 0.000029 0.0000066 0.0000094 0.000040 0.000038 2019 5 4 58607 0.076746 0.413367 -0.1516396 0.0009372 0.000080 -0.000205 0.000042 0.000029 0.0000066 0.0000095 0.000040 0.000037 2019 5 5 58608 0.077564 0.413858 -0.1525399 0.0008497 0.000071 -0.000202 0.000042 0.000028 0.0000066 0.0000093 0.000040 0.000036 2019 5 6 58609 0.078131 0.414792 -0.1533570 0.0007607 0.000063 -0.000199 0.000042 0.000028 0.0000066 0.0000093 0.000040 0.000035 2019 5 7 58610 0.078967 0.415625 -0.1540793 0.0006757 0.000054 -0.000197 0.000042 0.000028 0.0000066 0.0000093 0.000040 0.000034 2019 5 8 58611 0.080111 0.416276 -0.1547104 0.0005839 0.000046 -0.000194 0.000042 0.000029 0.0000066 0.0000093 0.000039 0.000034 2019 5 9 58612 0.081678 0.416736 -0.1552848 0.0005478 0.000054 -0.000173 0.000042 0.000029 0.0000066 0.0000093 0.000039 0.000033 2019 5 10 58613 0.083198 0.417395 -0.1558351 0.0005435 0.000067 -0.000148 0.000042 0.000029 0.0000066 0.0000093 0.000039 0.000033 2019 5 11 58614 0.084358 0.418035 -0.1564141 0.0006254 0.000073 -0.000143 0.000042 0.000029 0.0000067 0.0000093 0.000039 0.000033 2019 5 12 58615 0.085071 0.418630 -0.1571147 0.0007676 0.000075 -0.000145 0.000042 0.000029 0.0000067 0.0000092 0.000039 0.000032 2019 5 13 58616 0.085813 0.418754 -0.1579536 0.0009279 0.000078 -0.000148 0.000042 0.000029 0.0000067 0.0000093 0.000039 0.000032 2019 5 14 58617 0.086600 0.419108 -0.1589774 0.0011158 0.000081 -0.000151 0.000042 0.000029 0.0000068 0.0000092 0.000039 0.000032 2019 5 15 58618 0.087514 0.419659 -0.1601841 0.0012695 0.000067 -0.000145 0.000042 0.000029 0.0000068 0.0000092 0.000039 0.000032 2019 5 16 58619 0.088999 0.420446 -0.1614640 0.0012897 0.000048 -0.000136 0.000042 0.000029 0.0000069 0.0000092 0.000039 0.000033 2019 5 17 58620 0.090613 0.421097 -0.1627193 0.0012090 0.000029 -0.000128 0.000042 0.000029 0.0000069 0.0000092 0.000039 0.000034 2019 5 18 58621 0.092152 0.421974 -0.1637982 0.0009581 0.000049 -0.000242 0.000043 0.000029 0.0000070 0.0000091 0.000039 0.000034 2019 5 19 58622 0.093282 0.422813 -0.1646108 0.0006955 0.000083 -0.000404 0.000042 0.000029 0.0000070 0.0000090 0.000039 0.000035 2019 5 20 58623 0.094326 0.423729 -0.1652087 0.0004967 0.000058 -0.000314 0.000042 0.000029 0.0000070 0.0000090 0.000039 0.000035 2019 5 21 58624 0.095131 0.424424 -0.1656005 0.0003204 0.000033 -0.000223 0.000042 0.000029 0.0000070 0.0000090 0.000039 0.000035 2019 5 22 58625 0.096224 0.424661 -0.1658605 0.0002467 0.000031 -0.000186 0.000042 0.000029 0.0000070 0.0000090 0.000039 0.000035 2019 5 23 58626 0.097554 0.425052 -0.1660855 0.0002189 0.000036 -0.000164 0.000043 0.000029 0.0000070 0.0000090 0.000039 0.000036 2019 5 24 58627 0.099078 0.425636 -0.1663191 0.0002588 0.000041 -0.000141 0.000043 0.000029 0.0000069 0.0000090 0.000039 0.000037 2019 5 25 58628 0.100677 0.426354 -0.1665911 0.0002955 0.000050 -0.000147 0.000043 0.000029 0.0000068 0.0000090 0.000039 0.000038 2019 5 26 58629 0.101998 0.427131 -0.1669195 0.0003554 0.000059 -0.000163 0.000043 0.000029 0.0000068 0.0000090 0.000039 0.000038 2019 5 27 58630 0.102789 0.428011 -0.1673156 0.0004345 0.000068 -0.000179 0.000043 0.000029 0.0000068 0.0000089 0.000039 0.000038 2019 5 28 58631 0.103380 0.428645 -0.1677794 0.0005092 0.000077 -0.000195 0.000043 0.000029 0.0000068 0.0000089 0.000039 0.000039 2019 5 29 58632 0.104189 0.429128 -0.1683015 0.0005697 0.000087 -0.000211 0.000043 0.000029 0.0000068 0.0000090 0.000039 0.000040 2019 5 30 58633 0.105214 0.429435 -0.1688666 0.0006065 0.000066 -0.000203 0.000043 0.000029 0.0000068 0.0000090 0.000039 0.000040 2019 5 31 58634 0.106824 0.429366 -0.1694735 0.0006029 0.000037 -0.000187 0.000043 0.000029 0.0000067 0.0000090 0.000039 0.000040 2019 6 1 58635 0.109192 0.429288 -0.1700445 0.0005755 0.000047 -0.000178 0.000043 0.000029 0.0000068 0.0000090 0.000039 0.000039 2019 6 2 58636 0.111767 0.429661 -0.1705907 0.0004583 0.000072 -0.000171 0.000043 0.000029 0.0000068 0.0000090 0.000039 0.000039 2019 6 3 58637 0.114354 0.430266 -0.1709787 0.0003102 0.000097 -0.000165 0.000043 0.000029 0.0000068 0.0000091 0.000038 0.000038 2019 6 4 58638 0.117030 0.430851 -0.1712318 0.0002154 0.000121 -0.000158 0.000044 0.000029 0.0000068 0.0000090 0.000038 0.000037 2019 6 5 58639 0.119239 0.431321 -0.1714035 0.0001493 0.000089 -0.000139 0.000044 0.000029 0.0000069 0.0000090 0.000038 0.000037 2019 6 6 58640 0.121052 0.431429 -0.1715420 0.0001022 0.000041 -0.000116 0.000044 0.000029 0.0000068 0.0000090 0.000038 0.000037 2019 6 7 58641 0.122690 0.430872 -0.1716602 0.0001382 -0.000007 -0.000093 0.000044 0.000029 0.0000065 0.0000090 0.000038 0.000037 2019 6 8 58642 0.124490 0.430649 -0.1718378 0.0002370 -0.000022 -0.000097 0.000044 0.000029 0.0000065 0.0000091 0.000038 0.000037 2019 6 9 58643 0.126185 0.430126 -0.1721356 0.0003910 -0.000025 -0.000111 0.000044 0.000030 0.0000065 0.0000090 0.000038 0.000036 2019 6 10 58644 0.128346 0.429871 -0.1725999 0.0005326 -0.000029 -0.000125 0.000044 0.000030 0.0000065 0.0000091 0.000038 0.000036 2019 6 11 58645 0.130420 0.429746 -0.1732075 0.0006185 -0.000032 -0.000139 0.000044 0.000030 0.0000067 0.0000091 0.000037 0.000035 2019 6 12 58646 0.132347 0.429558 -0.1738778 0.0006416 -0.000035 -0.000153 0.000044 0.000030 0.0000064 0.0000090 0.000037 0.000035 2019 6 13 58647 0.134380 0.429399 -0.1744966 0.0005803 -0.000015 -0.000167 0.000044 0.000030 0.0000064 0.0000091 0.000037 0.000035 2019 6 14 58648 0.136665 0.429210 -0.1750200 0.0004295 0.000011 -0.000182 0.000044 0.000029 0.0000064 0.0000090 0.000037 0.000036 2019 6 15 58649 0.138696 0.429013 -0.1753572 0.0002232 0.000023 -0.000153 0.000044 0.000029 0.0000067 0.0000090 0.000037 0.000036 2019 6 16 58650 0.140244 0.428691 -0.1754768 0.0000056 0.000030 -0.000107 0.000044 0.000029 0.0000065 0.0000089 0.000037 0.000037 2019 6 17 58651 0.141742 0.428108 -0.1753998 -0.0001226 0.000037 -0.000062 0.000044 0.000029 0.0000065 0.0000090 0.000037 0.000037 2019 6 18 58652 0.143306 0.427548 -0.1752467 -0.0001850 0.000044 -0.000016 0.000044 0.000029 0.0000065 0.0000090 0.000037 0.000037 2019 6 19 58653 0.144520 0.426783 -0.1750128 -0.0002563 0.000034 -0.000085 0.000044 0.000029 0.0000066 0.0000090 0.000037 0.000037 2019 6 20 58654 0.145785 0.426239 -0.1747707 -0.0002204 0.000020 -0.000184 0.000044 0.000030 0.0000065 0.0000091 0.000037 0.000037 2019 6 21 58655 0.147173 0.426049 -0.1745848 -0.0001854 0.000045 -0.000225 0.000044 0.000030 0.0000065 0.0000091 0.000037 0.000037 2019 6 22 58656 0.148438 0.425869 -0.1744462 -0.0001293 0.000058 -0.000222 0.000044 0.000030 0.0000065 0.0000091 0.000037 0.000037 2019 6 23 58657 0.149329 0.425822 -0.1743743 -0.0000398 0.000060 -0.000210 0.000044 0.000030 0.0000066 0.0000090 0.000037 0.000037 2019 6 24 58658 0.149642 0.425359 -0.1743632 0.0000263 0.000063 -0.000199 0.000044 0.000030 0.0000067 0.0000090 0.000037 0.000038 2019 6 25 58659 0.150443 0.424519 -0.1744216 0.0000533 0.000065 -0.000187 0.000044 0.000030 0.0000067 0.0000091 0.000037 0.000038 2019 6 26 58660 0.151503 0.423564 -0.1744781 0.0000439 0.000074 -0.000172 0.000044 0.000030 0.0000068 0.0000091 0.000037 0.000038 2019 6 27 58661 0.153050 0.422505 -0.1745257 0.0000453 0.000085 -0.000155 0.000044 0.000030 0.0000068 0.0000092 0.000037 0.000038 2019 6 28 58662 0.154952 0.422105 -0.1745566 0.0000056 0.000038 -0.000172 0.000044 0.000030 0.0000068 0.0000092 0.000037 0.000038 2019 6 29 58663 0.156506 0.421788 -0.1745339 -0.0000611 0.000009 -0.000206 0.000044 0.000030 0.0000069 0.0000092 0.000037 0.000038 2019 6 30 58664 0.157773 0.421437 -0.1744325 -0.0001824 -0.000007 -0.000241 0.000044 0.000030 0.0000069 0.0000093 0.000037 0.000038 2019 7 1 58665 0.158510 0.420694 -0.1741775 -0.0003108 -0.000023 -0.000277 0.000044 0.000030 0.0000070 0.0000093 0.000037 0.000039 2019 7 2 58666 0.158923 0.419603 -0.1738182 -0.0004383 -0.000039 -0.000313 0.000044 0.000030 0.0000070 0.0000093 0.000037 0.000039 2019 7 3 58667 0.159301 0.418248 -0.1733282 -0.0005289 -0.000035 -0.000285 0.000044 0.000030 0.0000071 0.0000094 0.000037 0.000039 2019 7 4 58668 0.159771 0.417182 -0.1727712 -0.0005358 -0.000027 -0.000239 0.000044 0.000030 0.0000072 0.0000093 0.000037 0.000040 2019 7 5 58669 0.160760 0.416147 -0.1722981 -0.0004260 -0.000018 -0.000193 0.000044 0.000030 0.0000072 0.0000093 0.000037 0.000041 2019 7 6 58670 0.162741 0.415345 -0.1719953 -0.0002040 -0.000013 -0.000167 0.000044 0.000030 0.0000072 0.0000093 0.000037 0.000041 2019 7 7 58671 0.165082 0.415030 -0.1719175 -0.0000221 -0.000008 -0.000149 0.000044 0.000030 0.0000072 0.0000094 0.000036 0.000040 2019 7 8 58672 0.167058 0.414824 -0.1719241 0.0000585 -0.000004 -0.000131 0.000044 0.000029 0.0000073 0.0000093 0.000036 0.000040 2019 7 9 58673 0.168829 0.414243 -0.1720129 0.0000734 0.000000 -0.000113 0.000044 0.000029 0.0000073 0.0000093 0.000036 0.000040 2019 7 10 58674 0.170656 0.413399 -0.1720373 0.0000259 -0.000029 -0.000104 0.000044 0.000029 0.0000074 0.0000093 0.000036 0.000040 2019 7 11 58675 0.172168 0.412428 -0.1720134 -0.0001153 -0.000067 -0.000097 0.000044 0.000030 0.0000074 0.0000094 0.000036 0.000039 2019 7 12 58676 0.173303 0.411231 -0.1717954 -0.0003342 -0.000106 -0.000091 0.000044 0.000030 0.0000074 0.0000094 0.000036 0.000039 2019 7 13 58677 0.174483 0.409932 -0.1713282 -0.0005760 -0.000114 -0.000096 0.000044 0.000030 0.0000075 0.0000094 0.000036 0.000039 2019 7 14 58678 0.176050 0.408613 -0.1706787 -0.0007695 -0.000110 -0.000105 0.000044 0.000029 0.0000073 0.0000094 0.000036 0.000039 2019 7 15 58679 0.177687 0.407424 -0.1698085 -0.0009133 -0.000107 -0.000114 0.000044 0.000029 0.0000074 0.0000094 0.000036 0.000039 2019 7 16 58680 0.179332 0.406414 -0.1688618 -0.0009571 -0.000103 -0.000123 0.000044 0.000029 0.0000074 0.0000094 0.000036 0.000039 2019 7 17 58681 0.180565 0.406010 -0.1679382 -0.0009163 -0.000066 -0.000108 0.000044 0.000029 0.0000074 0.0000094 0.000036 0.000038 2019 7 18 58682 0.181617 0.405295 -0.1670432 -0.0008163 -0.000020 -0.000087 0.000044 0.000029 0.0000074 0.0000095 0.000036 0.000038 2019 7 19 58683 0.182544 0.404573 -0.1662851 -0.0006897 0.000027 -0.000066 0.000044 0.000029 0.0000072 0.0000095 0.000036 0.000038 2019 7 20 58684 0.183047 0.403589 -0.1656322 -0.0005755 0.000016 -0.000096 0.000044 0.000029 0.0000073 0.0000095 0.000036 0.000038 2019 7 21 58685 0.183724 0.402446 -0.1651379 -0.0004998 -0.000014 -0.000144 0.000044 0.000030 0.0000072 0.0000096 0.000036 0.000037 2019 7 22 58686 0.184514 0.401331 -0.1646548 -0.0004473 -0.000045 -0.000193 0.000044 0.000030 0.0000072 0.0000096 0.000036 0.000036 2019 7 23 58687 0.185834 0.400342 -0.1642195 -0.0003851 -0.000075 -0.000241 0.000044 0.000030 0.0000072 0.0000096 0.000036 0.000036 2019 7 24 58688 0.187682 0.399458 -0.1638659 -0.0003124 -0.000079 -0.000221 0.000044 0.000030 0.0000072 0.0000098 0.000036 0.000036 2019 7 25 58689 0.189630 0.398277 -0.1635104 -0.0003293 -0.000075 -0.000182 0.000044 0.000030 0.0000067 0.0000097 0.000036 0.000036 2019 7 26 58690 0.191786 0.396756 -0.1631804 -0.0003897 -0.000071 -0.000144 0.000044 0.000029 0.0000066 0.0000096 0.000036 0.000036 2019 7 27 58691 0.194250 0.395533 -0.1627645 -0.0004129 -0.000067 -0.000125 0.000044 0.000029 0.0000066 0.0000096 0.000036 0.000036 2019 7 28 58692 0.196630 0.394957 -0.1623692 -0.0004457 -0.000063 -0.000113 0.000044 0.000029 0.0000066 0.0000096 0.000036 0.000035 2019 7 29 58693 0.198637 0.394721 -0.1618353 -0.0005432 -0.000059 -0.000101 0.000043 0.000029 0.0000065 0.0000095 0.000036 0.000035 2019 7 30 58694 0.200514 0.394157 -0.1612463 -0.0006170 -0.000054 -0.000089 0.000043 0.000029 0.0000065 0.0000095 0.000036 0.000034 2019 7 31 58695 0.202626 0.393370 -0.1606707 -0.0005429 -0.000056 -0.000081 0.000043 0.000029 0.0000064 0.0000096 0.000036 0.000034 2019 8 1 58696 0.204690 0.392301 -0.1602267 -0.0004012 -0.000059 -0.000074 0.000043 0.000029 0.0000064 0.0000096 0.000036 0.000035 2019 8 2 58697 0.206262 0.391220 -0.1598692 -0.0002143 -0.000062 -0.000067 0.000043 0.000029 0.0000063 0.0000096 0.000037 0.000035 2019 8 3 58698 0.207816 0.390218 -0.1597619 0.0000136 -0.000073 -0.000056 0.000043 0.000029 0.0000063 0.0000097 0.000037 0.000035 2019 8 4 58699 0.209328 0.389372 -0.1598705 0.0002047 -0.000088 -0.000044 0.000043 0.000029 0.0000063 0.0000095 0.000037 0.000036 2019 8 5 58700 0.210566 0.388756 -0.1601388 0.0002868 -0.000102 -0.000033 0.000043 0.000029 0.0000063 0.0000095 0.000037 0.000036 2019 8 6 58701 0.211602 0.388370 -0.1604604 0.0002509 -0.000117 -0.000021 0.000043 0.000029 0.0000063 0.0000096 0.000037 0.000037 2019 8 7 58702 0.212386 0.388019 -0.1606720 0.0001189 -0.000095 -0.000017 0.000043 0.000029 0.0000063 0.0000096 0.000038 0.000038 2019 8 8 58703 0.212729 0.387457 -0.1606950 -0.0000725 -0.000064 -0.000015 0.000043 0.000029 0.0000063 0.0000097 0.000038 0.000039 2019 8 9 58704 0.213213 0.386456 -0.1605177 -0.0002884 -0.000032 -0.000013 0.000043 0.000029 0.0000063 0.0000097 0.000038 0.000040 2019 8 10 58705 0.213618 0.385343 -0.1600900 -0.0005104 -0.000025 -0.000003 0.000043 0.000029 0.0000063 0.0000097 0.000038 0.000040 2019 8 11 58706 0.213982 0.383799 -0.1595070 -0.0006517 -0.000027 0.000011 0.000043 0.000029 0.0000062 0.0000098 0.000038 0.000041 2019 8 12 58707 0.214516 0.382169 -0.1588184 -0.0007450 -0.000029 0.000025 0.000042 0.000029 0.0000063 0.0000096 0.000039 0.000042 2019 8 13 58708 0.214944 0.380545 -0.1580556 -0.0007526 -0.000031 0.000039 0.000042 0.000029 0.0000063 0.0000097 0.000039 0.000042 2019 8 14 58709 0.215570 0.378976 -0.1573339 -0.0006479 -0.000031 0.000025 0.000042 0.000029 0.0000063 0.0000097 0.000039 0.000043 2019 8 15 58710 0.216255 0.377777 -0.1567325 -0.0005263 -0.000031 0.000003 0.000042 0.000029 0.0000063 0.0000097 0.000039 0.000044 2019 8 16 58711 0.216650 0.376719 -0.1562758 -0.0004420 -0.000031 -0.000019 0.000043 0.000029 0.0000063 0.0000098 0.000039 0.000046 2019 8 17 58712 0.216754 0.375676 -0.1558223 -0.0003914 -0.000016 -0.000041 0.000043 0.000029 0.0000063 0.0000098 0.000040 0.000046 2019 8 18 58713 0.216967 0.374479 -0.1555081 -0.0003343 0.000005 -0.000065 0.000042 0.000029 0.0000063 0.0000096 0.000040 0.000047 2019 8 19 58714 0.216955 0.373221 -0.1552168 -0.0002577 0.000027 -0.000088 0.000042 0.000029 0.0000063 0.0000096 0.000040 0.000048 2019 8 20 58715 0.217091 0.371942 -0.1549961 -0.0001989 0.000048 -0.000111 0.000042 0.000029 0.0000063 0.0000096 0.000040 0.000048 2019 8 21 58716 0.217230 0.370375 -0.1548084 -0.0001647 0.000005 -0.000050 0.000042 0.000029 0.0000063 0.0000096 0.000040 0.000048 2019 8 22 58717 0.217272 0.368758 -0.1546673 -0.0001669 -0.000055 0.000032 0.000042 0.000029 0.0000063 0.0000097 0.000040 0.000048 2019 8 23 58718 0.217196 0.367299 -0.1545252 -0.0001604 -0.000114 0.000115 0.000042 0.000029 0.0000062 0.0000098 0.000040 0.000047 2019 8 24 58719 0.216899 0.365602 -0.1543575 -0.0002102 -0.000123 0.000111 0.000042 0.000029 0.0000062 0.0000097 0.000040 0.000046 2019 8 25 58720 0.216628 0.363656 -0.1540886 -0.0003062 -0.000114 0.000075 0.000042 0.000028 0.0000062 0.0000095 0.000040 0.000045 2019 8 26 58721 0.216427 0.361682 -0.1537159 -0.0004026 -0.000104 0.000039 0.000042 0.000029 0.0000063 0.0000095 0.000040 0.000044 2019 8 27 58722 0.216384 0.359848 -0.1533169 -0.0004038 -0.000094 0.000003 0.000042 0.000029 0.0000063 0.0000095 0.000040 0.000043 2019 8 28 58723 0.216234 0.357990 -0.1529938 -0.0002607 -0.000089 -0.000001 0.000042 0.000029 0.0000063 0.0000095 0.000040 0.000043 2019 8 29 58724 0.215974 0.356213 -0.1528093 -0.0000692 -0.000086 0.000003 0.000042 0.000029 0.0000062 0.0000096 0.000040 0.000042 2019 8 30 58725 0.215295 0.354392 -0.1528582 0.0001634 -0.000083 0.000007 0.000042 0.000029 0.0000062 0.0000096 0.000040 0.000042 2019 8 31 58726 0.214589 0.352607 -0.1531164 0.0003889 -0.000090 0.000020 0.000042 0.000029 0.0000062 0.0000096 0.000040 0.000041 2019 9 1 58727 0.214251 0.351024 -0.1536230 0.0005509 -0.000102 0.000037 0.000042 0.000028 0.0000063 0.0000095 0.000040 0.000041 2019 9 2 58728 0.214229 0.349770 -0.1542362 0.0006158 -0.000114 0.000054 0.000042 0.000028 0.0000063 0.0000095 0.000040 0.000040 2019 9 3 58729 0.213821 0.348481 -0.1548126 0.0005143 -0.000126 0.000071 0.000042 0.000028 0.0000063 0.0000095 0.000040 0.000039 2019 9 4 58730 0.213451 0.346759 -0.1552653 0.0003387 -0.000129 0.000075 0.000042 0.000029 0.0000064 0.0000095 0.000040 0.000039 2019 9 5 58731 0.213287 0.345150 -0.1555174 0.0001664 -0.000131 0.000077 0.000042 0.000029 0.0000064 0.0000095 0.000040 0.000038 2019 9 6 58732 0.213284 0.343292 -0.1555427 -0.0000562 -0.000132 0.000078 0.000042 0.000029 0.0000064 0.0000095 0.000040 0.000038 2019 9 7 58733 0.213605 0.341584 -0.1553511 -0.0002258 -0.000095 0.000075 0.000042 0.000029 0.0000065 0.0000095 0.000040 0.000037 2019 9 8 58734 0.213748 0.340214 -0.1551104 -0.0003264 -0.000044 0.000071 0.000042 0.000029 0.0000065 0.0000095 0.000040 0.000037 2019 9 9 58735 0.213582 0.338873 -0.1547174 -0.0003835 0.000008 0.000066 0.000042 0.000028 0.0000065 0.0000094 0.000040 0.000037 2019 9 10 58736 0.212916 0.337633 -0.1543020 -0.0003792 0.000059 0.000062 0.000042 0.000028 0.0000065 0.0000094 0.000040 0.000037 2019 9 11 58737 0.211643 0.336271 -0.1539400 -0.0003457 0.000034 0.000068 0.000042 0.000028 0.0000066 0.0000093 0.000041 0.000037 2019 9 12 58738 0.210279 0.334464 -0.1535993 -0.0003023 -0.000010 0.000078 0.000042 0.000028 0.0000066 0.0000094 0.000041 0.000038 2019 9 13 58739 0.209357 0.332511 -0.1533809 -0.0001592 -0.000054 0.000087 0.000042 0.000028 0.0000065 0.0000093 0.000041 0.000039 2019 9 14 58740 0.208780 0.330745 -0.1532910 -0.0000117 -0.000056 0.000098 0.000042 0.000028 0.0000066 0.0000092 0.000041 0.000039 2019 9 15 58741 0.208414 0.329530 -0.1533171 0.0000314 -0.000042 0.000109 0.000042 0.000028 0.0000066 0.0000092 0.000041 0.000039 2019 9 16 58742 0.207861 0.328404 -0.1533320 -0.0000025 -0.000029 0.000120 0.000042 0.000028 0.0000066 0.0000092 0.000042 0.000039 2019 9 17 58743 0.207375 0.326891 -0.1533303 -0.0000354 -0.000015 0.000132 0.000042 0.000028 0.0000066 0.0000092 0.000042 0.000040 2019 9 18 58744 0.206919 0.325493 -0.1532853 -0.0000746 -0.000012 0.000135 0.000042 0.000028 0.0000066 0.0000092 0.000042 0.000040 2019 9 19 58745 0.206058 0.324124 -0.1531654 -0.0001887 -0.000012 0.000136 0.000042 0.000028 0.0000067 0.0000092 0.000042 0.000041 2019 9 20 58746 0.204867 0.323038 -0.1529207 -0.0003054 -0.000012 0.000138 0.000042 0.000028 0.0000067 0.0000092 0.000043 0.000042 2019 9 21 58747 0.203740 0.321672 -0.1525495 -0.0004187 0.000004 0.000154 0.000042 0.000028 0.0000067 0.0000091 0.000043 0.000043 2019 9 22 58748 0.202952 0.320373 -0.1521046 -0.0004659 0.000026 0.000175 0.000042 0.000028 0.0000068 0.0000090 0.000043 0.000043 2019 9 23 58749 0.202247 0.319367 -0.1516530 -0.0004642 0.000049 0.000197 0.000041 0.000028 0.0000068 0.0000090 0.000043 0.000044 2019 9 24 58750 0.201645 0.318571 -0.1512166 -0.0003760 0.000071 0.000219 0.000041 0.000028 0.0000068 0.0000090 0.000044 0.000045 2019 9 25 58751 0.201081 0.317719 -0.1508992 -0.0001448 0.000085 0.000191 0.000041 0.000028 0.0000069 0.0000090 0.000044 0.000045 2019 9 26 58752 0.200126 0.317163 -0.1508833 0.0001271 0.000096 0.000150 0.000041 0.000028 0.0000069 0.0000090 0.000044 0.000046 2019 9 27 58753 0.199436 0.316266 -0.1512096 0.0004451 0.000107 0.000110 0.000042 0.000028 0.0000069 0.0000090 0.000044 0.000046 2019 9 28 58754 0.199110 0.315576 -0.1518123 0.0006726 0.000076 0.000093 0.000042 0.000028 0.0000070 0.0000089 0.000045 0.000047 2019 9 29 58755 0.198862 0.314678 -0.1525147 0.0007271 0.000030 0.000086 0.000042 0.000028 0.0000070 0.0000088 0.000045 0.000048 2019 9 30 58756 0.198848 0.313423 -0.1532049 0.0006476 -0.000016 0.000079 0.000042 0.000028 0.0000071 0.0000088 0.000045 0.000049 2019 10 1 58757 0.198410 0.312207 -0.1537485 0.0003901 -0.000063 0.000072 0.000042 0.000028 0.0000071 0.0000088 0.000045 0.000051 2019 10 2 58758 0.197567 0.311034 -0.1539883 0.0000893 -0.000052 0.000123 0.000042 0.000028 0.0000072 0.0000088 0.000045 0.000051 2019 10 3 58759 0.196521 0.310013 -0.1539122 -0.0001661 -0.000029 0.000146 0.000042 0.000028 0.0000073 0.0000087 0.000046 0.000051 2019 10 4 58760 0.195512 0.308733 -0.1536855 -0.0003216 -0.000007 0.000153 0.000042 0.000028 0.0000073 0.0000087 0.000046 0.000050 2019 10 5 58761 0.194646 0.307613 -0.1532978 -0.0004249 0.000015 0.000160 0.000042 0.000028 0.0000074 0.0000087 0.000046 0.000050 2019 10 6 58762 0.193612 0.306147 -0.1528333 -0.0004566 0.000037 0.000167 0.000042 0.000027 0.0000070 0.0000086 0.000046 0.000049 2019 10 7 58763 0.192696 0.304968 -0.1523685 -0.0004190 0.000059 0.000174 0.000042 0.000027 0.0000069 0.0000086 0.000046 0.000048 2019 10 8 58764 0.191558 0.303570 -0.1519645 -0.0003952 0.000081 0.000181 0.000042 0.000027 0.0000068 0.0000086 0.000046 0.000048 2019 10 9 58765 0.190547 0.301914 -0.1516533 -0.0002629 0.000103 0.000188 0.000042 0.000027 0.0000068 0.0000086 0.000046 0.000047 2019 10 10 58766 0.189439 0.300716 -0.1514464 -0.0001207 0.000044 0.000190 0.000042 0.000027 0.0000067 0.0000085 0.000046 0.000046 2019 10 11 58767 0.188637 0.299690 -0.1513803 0.0000031 -0.000035 0.000191 0.000042 0.000027 0.0000066 0.0000085 0.000046 0.000044 2019 10 12 58768 0.187871 0.299356 -0.1514616 0.0001639 -0.000022 0.000178 0.000042 0.000027 0.0000066 0.0000085 0.000046 0.000044 2019 10 13 58769 0.186230 0.299271 -0.1516517 0.0002330 0.000025 0.000159 0.000042 0.000027 0.0000066 0.0000084 0.000046 0.000043 2019 10 14 58770 0.184374 0.298532 -0.1519120 0.0002854 0.000072 0.000141 0.000042 0.000027 0.0000065 0.0000084 0.000046 0.000043 2019 10 15 58771 0.182663 0.297785 -0.1522347 0.0003192 0.000119 0.000122 0.000042 0.000027 0.0000065 0.0000083 0.000046 0.000042 2019 10 16 58772 0.181451 0.297182 -0.1525644 0.0003320 0.000110 0.000133 0.000042 0.000027 0.0000065 0.0000084 0.000046 0.000041 2019 10 17 58773 0.179963 0.296654 -0.1528796 0.0002835 0.000087 0.000151 0.000042 0.000027 0.0000063 0.0000084 0.000046 0.000041 2019 10 18 58774 0.178272 0.295649 -0.1531347 0.0002222 0.000063 0.000169 0.000042 0.000027 0.0000063 0.0000083 0.000046 0.000040 2019 10 19 58775 0.176769 0.294516 -0.1533264 0.0001545 0.000060 0.000171 0.000042 0.000027 0.0000062 0.0000083 0.000046 0.000040 2019 10 20 58776 0.175243 0.293466 -0.1534304 0.0000914 0.000064 0.000167 0.000042 0.000027 0.0000062 0.0000083 0.000046 0.000041 2019 10 21 58777 0.173642 0.292375 -0.1535058 0.0000687 0.000069 0.000162 0.000042 0.000027 0.0000062 0.0000083 0.000046 0.000042 2019 10 22 58778 0.172439 0.291301 -0.1536109 0.0001472 0.000074 0.000158 0.000042 0.000027 0.0000061 0.0000083 0.000046 0.000042 2019 10 23 58779 0.171356 0.290381 -0.1538184 0.0003219 0.000086 0.000173 0.000042 0.000027 0.0000061 0.0000083 0.000046 0.000042 2019 10 24 58780 0.170144 0.289971 -0.1542370 0.0005318 0.000101 0.000194 0.000042 0.000026 0.0000058 0.0000082 0.000046 0.000042 2019 10 25 58781 0.168762 0.289141 -0.1549127 0.0007802 0.000115 0.000214 0.000042 0.000026 0.0000056 0.0000082 0.000046 0.000042 2019 10 26 58782 0.167818 0.287812 -0.1558032 0.0009548 0.000109 0.000208 0.000041 0.000026 0.0000056 0.0000080 0.000046 0.000042 2019 10 27 58783 0.167273 0.286523 -0.1568092 0.0009718 0.000095 0.000193 0.000041 0.000026 0.0000055 0.0000080 0.000046 0.000042 2019 10 28 58784 0.167133 0.285481 -0.1577255 0.0008493 0.000081 0.000178 0.000041 0.000026 0.0000055 0.0000080 0.000046 0.000042 2019 10 29 58785 0.166908 0.284350 -0.1584554 0.0006110 0.000067 0.000162 0.000041 0.000026 0.0000054 0.0000080 0.000046 0.000041 2019 10 30 58786 0.167018 0.283062 -0.1589241 0.0003454 0.000055 0.000185 0.000041 0.000026 0.0000054 0.0000080 0.000046 0.000042 2019 10 31 58787 0.166656 0.282117 -0.1591501 0.0001216 0.000043 0.000217 0.000040 0.000026 0.0000053 0.0000080 0.000046 0.000043 2019 11 1 58788 0.166024 0.281083 -0.1592044 0.0000290 0.000058 0.000223 0.000040 0.000026 0.0000053 0.0000080 0.000047 0.000043 2019 11 2 58789 0.165338 0.280270 -0.1591866 -0.0000229 0.000082 0.000220 0.000040 0.000026 0.0000053 0.0000080 0.000047 0.000044 2019 11 3 58790 0.164712 0.279387 -0.1591777 0.0000031 0.000106 0.000217 0.000040 0.000026 0.0000053 0.0000079 0.000047 0.000044 2019 11 4 58791 0.163921 0.278764 -0.1591947 0.0000618 0.000130 0.000213 0.000040 0.000026 0.0000053 0.0000078 0.000047 0.000045 2019 11 5 58792 0.163092 0.278229 -0.1592855 0.0001031 0.000154 0.000210 0.000040 0.000026 0.0000052 0.0000079 0.000047 0.000045 2019 11 6 58793 0.162362 0.277999 -0.1594469 0.0002318 0.000155 0.000182 0.000040 0.000026 0.0000052 0.0000079 0.000047 0.000046 2019 11 7 58794 0.161420 0.277887 -0.1597681 0.0003988 0.000148 0.000148 0.000040 0.000026 0.0000051 0.0000079 0.000047 0.000046 2019 11 8 58795 0.160475 0.277218 -0.1602407 0.0005640 0.000142 0.000113 0.000039 0.000026 0.0000051 0.0000078 0.000047 0.000046 2019 11 9 58796 0.159241 0.276588 -0.1608634 0.0006676 0.000123 0.000111 0.000039 0.000026 0.0000051 0.0000078 0.000047 0.000046 2019 11 10 58797 0.157895 0.275927 -0.1615582 0.0007108 0.000099 0.000120 0.000039 0.000026 0.0000051 0.0000078 0.000047 0.000046 2019 11 11 58798 0.156727 0.275260 -0.1622553 0.0006808 0.000076 0.000129 0.000039 0.000026 0.0000051 0.0000078 0.000047 0.000046 2019 11 12 58799 0.155603 0.274984 -0.1629060 0.0006010 0.000052 0.000138 0.000039 0.000026 0.0000051 0.0000078 0.000047 0.000046 2019 11 13 58800 0.154311 0.275077 -0.1634446 0.0004930 0.000037 0.000174 0.000039 0.000026 0.0000051 0.0000077 0.000047 0.000045 2019 11 14 58801 0.153268 0.274960 -0.1639043 0.0003652 0.000026 0.000216 0.000054 0.000037 0.0000057 0.0000116 0.000047 0.000044 2019 11 15 58802 0.152222 0.274968 -0.1641959 0.0002686 0.000014 0.000258 0.000054 0.000037 0.0000057 0.0000117 0.000047 0.000043 2019 11 16 58803 0.150295 0.275080 -0.1643655 0.0001742 0.000022 0.000250 0.000054 0.000037 0.0000058 0.0000117 0.000047 0.000043 2019 11 17 58804 0.147587 0.274490 -0.1644541 0.0000196 0.000039 0.000222 0.000054 0.000038 0.0000059 0.0000117 0.000047 0.000043 2019 11 18 58805 0.145289 0.273683 -0.1645155 0.0000739 0.000055 0.000194 0.000054 0.000038 0.0000060 0.0000117 0.000047 0.000042 2019 11 19 58806 0.143281 0.273081 -0.1646594 0.0002184 0.000071 0.000166 0.000054 0.000038 0.0000061 0.0000118 0.000046 0.000042 2019 11 20 58807 0.141572 0.272389 -0.1650117 0.0004566 0.000102 0.000167 0.000054 0.000038 0.0000062 0.0000118 0.000047 0.000042 2019 11 21 58808 0.139739 0.271754 -0.1655856 0.0006891 0.000137 0.000174 0.000054 0.000038 0.0000063 0.0000118 0.000047 0.000043 2019 11 22 58809 0.137935 0.270986 -0.1663474 0.0008501 0.000172 0.000182 0.000054 0.000038 0.0000064 0.0000119 0.000047 0.000044 2019 11 23 58810 0.135854 0.270490 -0.1672098 0.0008984 0.000145 0.000194 0.000054 0.000038 0.0000065 0.0000119 0.000047 0.000045 2019 11 24 58811 0.133695 0.270065 -0.1680987 0.0008706 0.000095 0.000208 0.000054 0.000038 0.0000066 0.0000120 0.000047 0.000045 2019 11 25 58812 0.131862 0.269518 -0.1688806 0.0007028 0.000045 0.000222 0.000053 0.000038 0.0000067 0.0000118 0.000047 0.000046 2019 11 26 58813 0.130125 0.269096 -0.1694679 0.0004439 -0.000005 0.000236 0.000053 0.000038 0.0000067 0.0000118 0.000047 0.000046 2019 11 27 58814 0.128691 0.269088 -0.1698161 0.0002162 -0.000021 0.000212 0.000053 0.000038 0.0000069 0.0000119 0.000047 0.000047 2019 11 28 58815 0.127259 0.269277 -0.1699512 0.0001048 0.000013 0.000173 0.000052 0.000038 0.0000053 0.0000119 0.000047 0.000048 2019 11 29 58816 0.126025 0.269630 -0.1700093 0.0000503 0.000062 0.000133 0.000052 0.000038 0.0000054 0.0000120 0.000047 0.000049 2019 11 30 58817 0.124622 0.269887 -0.1700295 0.0000065 0.000095 0.000121 0.000052 0.000038 0.0000056 0.0000120 0.000047 0.000050 2019 12 1 58818 0.122977 0.270474 -0.1700083 0.0000115 0.000126 0.000111 0.000053 0.000038 0.0000058 0.0000121 0.000047 0.000052 2019 12 2 58819 0.121295 0.270919 -0.1700652 0.0001125 0.000156 0.000102 0.000053 0.000038 0.0000060 0.0000119 0.000047 0.000053 2019 12 3 58820 0.119056 0.271391 -0.1702069 0.0002032 0.000187 0.000093 0.000053 0.000038 0.0000061 0.0000119 0.000048 0.000054 2019 12 4 58821 0.116202 0.271402 -0.1704075 0.0002412 0.000394 0.000129 0.000053 0.000038 0.0000063 0.0000120 0.000048 0.000055 2019 12 5 58822 0.113387 0.271331 -0.1706831 0.0002888 0.000357 0.000094 0.000053 0.000038 0.0000064 0.0000121 0.000048 0.000056 2019 12 6 58823 0.111157 0.271130 -0.1710324 0.0003641 0.000235 0.000034 0.000053 0.000039 0.0000065 0.0000121 0.000048 0.000056 2019 12 7 58824 0.109446 0.271083 -0.1714476 0.0004120 0.000179 0.000043 0.000053 0.000039 0.0000067 0.0000122 0.000048 0.000057 2019 12 8 58825 0.107845 0.270977 -0.1718773 0.0004384 0.000148 0.000076 0.000053 0.000038 0.0000069 0.0000120 0.000048 0.000057 2019 12 9 58826 0.106731 0.270915 -0.1722563 0.0003279 0.000118 0.000110 0.000053 0.000039 0.0000072 0.0000120 0.000048 0.000058 2019 12 10 58827 0.105853 0.271007 -0.1725299 0.0001560 0.000087 0.000144 0.000053 0.000039 0.0000075 0.0000121 0.000048 0.000058 2019 12 11 58828 0.105246 0.271040 -0.1726501 0.0000269 0.000098 0.000136 0.000053 0.000039 0.0000077 0.0000122 0.000048 0.000057 2019 12 12 58829 0.104919 0.271256 -0.1726192 -0.0001170 0.000121 0.000117 0.000054 0.000039 0.0000078 0.0000123 0.000048 0.000056 2019 12 13 58830 0.104891 0.271967 -0.1724695 -0.0001672 0.000143 0.000097 0.000055 0.000039 0.0000080 0.0000124 0.000047 0.000056 2019 12 14 58831 0.104387 0.273241 -0.1722776 -0.0001813 0.000172 0.000104 0.000055 0.000039 0.0000083 0.0000125 0.000047 0.000056 2019 12 15 58832 0.103420 0.274169 -0.1721003 -0.0001567 0.000202 0.000119 0.000055 0.000039 0.0000086 0.0000122 0.000047 0.000057 2019 12 16 58833 0.101523 0.274834 -0.1719915 -0.0000768 0.000233 0.000135 0.000055 0.000039 0.0000088 0.0000123 0.000047 0.000058 2019 12 17 58834 0.099491 0.275064 -0.1720193 0.0001269 0.000264 0.000150 0.000056 0.000039 0.0000090 0.0000124 0.000047 0.000059 2019 12 18 58835 0.097486 0.275323 -0.1722457 0.0003512 0.000295 0.000166 0.000056 0.000039 0.0000092 0.0000125 0.000047 0.000060 2019 12 19 58836 0.095902 0.275669 -0.1727030 0.0005690 0.000230 0.000107 0.000056 0.000039 0.0000093 0.0000125 0.000047 0.000060 2019 12 20 58837 0.095103 0.276115 -0.1733419 0.0006708 0.000140 0.000029 0.000057 0.000039 0.0000095 0.0000126 0.000047 0.000061 2019 12 21 58838 0.094742 0.276421 -0.1740825 0.0006995 0.000139 0.000001 0.000057 0.000039 0.0000097 0.0000127 0.000047 0.000062 2019 12 22 58839 0.094482 0.277227 -0.1748044 0.0006483 0.000173 -0.000008 0.000057 0.000039 0.0000100 0.0000124 0.000046 0.000063 2019 12 23 58840 0.093397 0.278386 -0.1753803 0.0005092 0.000206 -0.000017 0.000057 0.000039 0.0000105 0.0000125 0.000046 0.000064 2019 12 24 58841 0.091836 0.279097 -0.1757728 0.0003494 0.000239 -0.000026 0.000057 0.000039 0.0000108 0.0000126 0.000046 0.000066 2019 12 25 58842 0.090305 0.279607 -0.1760220 0.0001839 0.000227 0.000020 0.000057 0.000039 0.0000110 0.0000126 0.000046 0.000066 2019 12 26 58843 0.088530 0.280066 -0.1761523 0.0000805 0.000203 0.000080 0.000057 0.000039 0.0000107 0.0000127 0.000046 0.000066 2019 12 27 58844 0.086894 0.280745 -0.1762143 0.0000471 0.000180 0.000140 0.000058 0.000040 0.0000109 0.0000128 0.000045 0.000066 2019 12 28 58845 0.085073 0.281330 -0.1762581 0.0000518 0.000201 0.000123 0.000058 0.000040 0.0000111 0.0000128 0.000045 0.000064 2019 12 29 58846 0.082939 0.281710 -0.1763377 0.0001236 0.000239 0.000079 0.000057 0.000039 0.0000118 0.0000125 0.000045 0.000063 2019 12 30 58847 0.080306 0.281800 -0.1764974 0.0002229 0.000276 0.000034 0.000057 0.000039 0.0000120 0.0000125 0.000044 0.000061 2019 12 31 58848 0.078246 0.281929 -0.1767593 0.0003452 0.000314 -0.000011 0.000057 0.000039 0.0000122 0.0000126 0.000044 0.000060 2020 1 1 58849 0.076609 0.282358 -0.1771222 0.0004455 0.000348 0.000003 0.000057 0.000039 0.0000123 0.0000126 0.000044 0.000057 2020 1 2 58850 0.074635 0.282666 -0.1775806 0.0004667 0.000382 0.000033 0.000057 0.000039 0.0000115 0.0000127 0.000043 0.000055 2020 1 3 58851 0.072663 0.283156 -0.1781029 0.0004803 0.000416 0.000062 0.000057 0.000040 0.0000115 0.0000127 0.000043 0.000053 2020 1 4 58852 0.071338 0.284013 -0.1786507 0.0004801 0.000382 0.000067 0.000057 0.000040 0.0000115 0.0000128 0.000042 0.000050 2020 1 5 58853 0.070121 0.284887 -0.1791377 0.0004064 0.000322 0.000064 0.000056 0.000039 0.0000112 0.0000124 0.000042 0.000047 2020 1 6 58854 0.068393 0.285277 -0.1794674 0.0002265 0.000263 0.000060 0.000056 0.000039 0.0000111 0.0000124 0.000041 0.000045 2020 1 7 58855 0.066587 0.285482 -0.1796058 0.0000717 0.000203 0.000056 0.000056 0.000039 0.0000110 0.0000125 0.000041 0.000043 2020 1 8 58856 0.064905 0.285932 -0.1795597 -0.0000717 0.000144 0.000053 0.000056 0.000039 0.0000109 0.0000125 0.000040 0.000041 2020 1 9 58857 0.063591 0.286537 -0.1793746 -0.0002132 0.000127 0.000036 0.000056 0.000039 0.0000108 0.0000126 0.000040 0.000039 2020 1 10 58858 0.062631 0.287462 -0.1791201 -0.0002979 0.000121 0.000017 0.000056 0.000039 0.0000101 0.0000126 0.000039 0.000037 2020 1 11 58859 0.061854 0.288667 -0.1788961 -0.0002007 0.000119 0.000019 0.000055 0.000039 0.0000099 0.0000127 0.000039 0.000035 2020 1 12 58860 0.061134 0.289907 -0.1788057 -0.0000038 0.000117 0.000029 0.000055 0.000039 0.0000092 0.0000123 0.000038 0.000033 2020 1 13 58861 0.060864 0.291018 -0.1789353 0.0002968 0.000116 0.000039 0.000054 0.000039 0.0000091 0.0000123 0.000038 0.000032 2020 1 14 58862 0.060557 0.292386 -0.1793255 0.0005750 0.000115 0.000049 0.000054 0.000039 0.0000089 0.0000124 0.000037 0.000030 2020 1 15 58863 0.059588 0.293794 -0.1799543 0.0007465 0.000150 0.000019 0.000054 0.000039 0.0000087 0.0000124 0.000037 0.000030 2020 1 16 58864 0.058520 0.295343 -0.1807846 0.0008774 0.000195 -0.000020 0.000054 0.000039 0.0000086 0.0000124 0.000037 0.000030 2020 1 17 58865 0.057430 0.296819 -0.1817437 0.0010052 0.000239 -0.000059 0.000054 0.000039 0.0000085 0.0000124 0.000037 0.000029 2020 1 18 58866 0.056515 0.297636 -0.1827608 0.0010297 0.000228 -0.000048 0.000053 0.000039 0.0000081 0.0000125 0.000036 0.000029 2020 1 19 58867 0.055634 0.298582 -0.1837339 0.0009318 0.000195 -0.000018 0.000053 0.000038 0.0000080 0.0000122 0.000036 0.000029 2020 1 20 58868 0.054617 0.299454 -0.1845425 0.0007783 0.000163 0.000012 0.000052 0.000038 0.0000078 0.0000122 0.000036 0.000029 2020 1 21 58869 0.053801 0.300237 -0.1852307 0.0005888 0.000130 0.000042 0.000052 0.000038 0.0000077 0.0000122 0.000036 0.000028 2020 1 22 58870 0.053304 0.301090 -0.1857979 0.0004516 0.000098 0.000072 0.000052 0.000038 0.0000075 0.0000122 0.000036 0.000028 2020 1 23 58871 0.052618 0.302469 -0.1861858 0.0003157 0.000129 0.000084 0.000052 0.000038 0.0000074 0.0000123 0.000036 0.000028 2020 1 24 58872 0.051965 0.303572 -0.1864849 0.0002606 0.000178 0.000092 0.000052 0.000038 0.0000072 0.0000123 0.000036 0.000029 2020 1 25 58873 0.051957 0.304776 -0.1867979 0.0003582 0.000217 0.000090 0.000052 0.000038 0.0000072 0.0000124 0.000036 0.000029 2020 1 26 58874 0.051500 0.306324 -0.1871882 0.0004438 0.000254 0.000085 0.000053 0.000038 0.0000072 0.0000124 0.000036 0.000029 2020 1 27 58875 0.050488 0.307421 -0.1876943 0.0005593 0.000291 0.000079 0.000052 0.000038 0.0000073 0.0000121 0.000036 0.000029 2020 1 28 58876 0.049407 0.308653 -0.1883290 0.0006623 0.000327 0.000074 0.000052 0.000038 0.0000073 0.0000121 0.000036 0.000029 2020 1 29 58877 0.048378 0.310139 -0.1890559 0.0007174 0.000299 0.000059 0.000052 0.000038 0.0000073 0.0000122 0.000036 0.000030 2020 1 30 58878 0.047078 0.311687 -0.1898028 0.0007392 0.000255 0.000042 0.000052 0.000038 0.0000072 0.0000122 0.000036 0.000030 2020 1 31 58879 0.045724 0.312939 -0.1905245 0.0006980 0.000210 0.000025 0.000053 0.000038 0.0000071 0.0000123 0.000036 0.000031 2020 2 1 58880 0.044494 0.314392 -0.1911699 0.0005988 0.000223 0.000025 0.000053 0.000038 0.0000072 0.0000123 0.000036 0.000031 2020 2 2 58881 0.043505 0.316036 -0.1917194 0.0004836 0.000257 0.000031 0.000053 0.000037 0.0000070 0.0000120 0.000036 0.000031 2020 2 3 58882 0.042727 0.317663 -0.1921721 0.0003794 0.000291 0.000038 0.000053 0.000038 0.0000071 0.0000121 0.000036 0.000031 2020 2 4 58883 0.042236 0.319419 -0.1925141 0.0002354 0.000324 0.000044 0.000053 0.000038 0.0000071 0.0000121 0.000036 0.000032 2020 2 5 58884 0.042192 0.321224 -0.1927412 0.0001382 0.000323 0.000039 0.000053 0.000038 0.0000073 0.0000121 0.000037 0.000033 2020 2 6 58885 0.041387 0.322939 -0.1928644 0.0000870 0.000311 0.000031 0.000054 0.000038 0.0000075 0.0000122 0.000037 0.000034 2020 2 7 58886 0.040107 0.323988 -0.1929351 0.0000853 0.000300 0.000023 0.000054 0.000038 0.0000078 0.0000123 0.000037 0.000035 2020 2 8 58887 0.038702 0.324883 -0.1930242 0.0001418 0.000279 0.000004 0.000055 0.000039 0.0000081 0.0000123 0.000038 0.000036 2020 2 9 58888 0.037913 0.325300 -0.1932662 0.0003533 0.000253 -0.000020 0.000055 0.000039 0.0000084 0.0000124 0.000038 0.000038 2020 2 10 58889 0.037635 0.326014 -0.1937899 0.0006718 0.000228 -0.000043 0.000055 0.000038 0.0000081 0.0000121 0.000038 0.000039 2020 2 11 58890 0.037317 0.327316 -0.1945859 0.0008996 0.000203 -0.000067 0.000055 0.000038 0.0000083 0.0000121 0.000039 0.000041 2020 2 12 58891 0.037414 0.328670 -0.1955386 0.0009962 0.000209 -0.000043 0.000056 0.000039 0.0000085 0.0000122 0.000039 0.000043 2020 2 13 58892 0.037440 0.330236 -0.1965300 0.0009626 0.000223 -0.000008 0.000056 0.000039 0.0000087 0.0000123 0.000039 0.000044 2020 2 14 58893 0.036532 0.331984 -0.1974312 0.0007962 0.000236 0.000028 0.000056 0.000039 0.0000089 0.0000123 0.000040 0.000046 2020 2 15 58894 0.034910 0.333280 -0.1981377 0.0005980 0.000254 0.000020 0.000056 0.000039 0.0000092 0.0000124 0.000040 0.000047 2020 2 16 58895 0.033056 0.334012 -0.1986185 0.0004101 0.000274 -0.000005 0.000056 0.000039 0.0000094 0.0000121 0.000040 0.000048 2020 2 17 58896 0.031510 0.334883 -0.1989191 0.0002210 0.000294 -0.000030 0.000056 0.000039 0.0000096 0.0000121 0.000040 0.000050 2020 2 18 58897 0.030655 0.336009 -0.1990725 0.0000639 0.000315 -0.000055 0.000057 0.000039 0.0000098 0.0000122 0.000041 0.000051 2020 2 19 58898 0.030313 0.337617 -0.1991016 0.0000235 0.000324 -0.000036 0.000057 0.000039 0.0000101 0.0000122 0.000041 0.000052 2020 2 20 58899 0.029598 0.339041 -0.1991206 0.0000386 0.000331 -0.000006 0.000057 0.000039 0.0000103 0.0000123 0.000041 0.000053 2020 2 21 58900 0.028482 0.340031 -0.1992279 0.0001792 0.000338 0.000024 0.000057 0.000039 0.0000104 0.0000124 0.000041 0.000054 2020 2 22 58901 0.027450 0.340780 -0.1995108 0.0004273 0.000326 0.000031 0.000057 0.000039 0.0000106 0.0000124 0.000041 0.000055 2020 2 23 58902 0.026983 0.341571 -0.1999703 0.0005556 0.000306 0.000028 0.000057 0.000039 0.0000110 0.0000122 0.000042 0.000055 2020 2 24 58903 0.027040 0.342668 -0.2005609 0.0006445 0.000286 0.000026 0.000057 0.000039 0.0000112 0.0000122 0.000042 0.000055 2020 2 25 58904 0.027405 0.344602 -0.2012484 0.0006880 0.000267 0.000024 0.000057 0.000039 0.0000115 0.0000123 0.000042 0.000056 2020 2 26 58905 0.027969 0.346651 -0.2019948 0.0007245 0.000266 0.000022 0.000057 0.000039 0.0000117 0.0000123 0.000042 0.000057 2020 2 27 58906 0.028570 0.348892 -0.2027642 0.0007973 0.000270 0.000020 0.000057 0.000039 0.0000119 0.0000124 0.000042 0.000057 2020 2 28 58907 0.028790 0.351114 -0.2035270 0.0008132 0.000274 0.000019 0.000057 0.000039 0.0000119 0.0000125 0.000042 0.000058 2020 2 29 58908 0.028282 0.353263 -0.2042647 0.0007321 0.000285 0.000016 0.000057 0.000039 0.0000120 0.0000125 0.000042 0.000058 2020 3 1 58909 0.027663 0.355257 -0.2049580 0.0006589 0.000299 0.000013 0.000057 0.000039 0.0000095 0.0000126 0.000042 0.000058 2020 3 2 58910 0.027052 0.357171 -0.2055930 0.0005935 0.000312 0.000011 0.000056 0.000039 0.0000095 0.0000123 0.000042 0.000058 2020 3 3 58911 0.026374 0.359002 -0.2061635 0.0005165 0.000326 0.000008 0.000056 0.000039 0.0000094 0.0000124 0.000042 0.000057 2020 3 4 58912 0.026040 0.360668 -0.2066763 0.0004635 0.000330 0.000007 0.000056 0.000039 0.0000093 0.0000124 0.000042 0.000057 2020 3 5 58913 0.026271 0.362020 -0.2071658 0.0005028 0.000331 0.000006 0.000056 0.000039 0.0000092 0.0000125 0.000042 0.000055 2020 3 6 58914 0.026971 0.363910 -0.2076964 0.0006226 0.000332 0.000006 0.000056 0.000039 0.0000089 0.0000126 0.000042 0.000054 2020 3 7 58915 0.027743 0.365695 -0.2083559 0.0008000 0.000311 -0.000028 0.000056 0.000039 0.0000087 0.0000123 0.000042 0.000053 2020 3 8 58916 0.028156 0.367442 -0.2092279 0.0009841 0.000282 -0.000074 0.000056 0.000038 0.0000081 0.0000124 0.000042 0.000051 2020 3 9 58917 0.028068 0.369116 -0.2103544 0.0012166 0.000254 -0.000121 0.000055 0.000038 0.0000077 0.0000124 0.000042 0.000050 2020 3 10 58918 0.028186 0.370679 -0.2117167 0.0014868 0.000225 -0.000167 0.000055 0.000039 0.0000075 0.0000125 0.000041 0.000048 2020 3 11 58919 0.028655 0.372325 -0.2132290 0.0015777 0.000236 -0.000130 0.000055 0.000039 0.0000073 0.0000126 0.000041 0.000047 2020 3 12 58920 0.029168 0.373782 -0.2147503 0.0014394 0.000258 -0.000071 0.000055 0.000039 0.0000071 0.0000126 0.000041 0.000045 2020 3 13 58921 0.030390 0.375474 -0.2161386 0.0012287 0.000280 -0.000012 0.000054 0.000039 0.0000069 0.0000127 0.000041 0.000044 2020 3 14 58922 0.031837 0.377519 -0.2172921 0.0009841 0.000289 0.000024 0.000054 0.000039 0.0000067 0.0000128 0.000041 0.000042 2020 3 15 58923 0.033166 0.379483 -0.2181787 0.0007350 0.000293 0.000051 0.000053 0.000038 0.0000062 0.0000125 0.000040 0.000040 2020 3 16 58924 0.034196 0.380925 -0.2188244 0.0005614 0.000297 0.000078 0.000053 0.000038 0.0000060 0.0000125 0.000040 0.000038 2020 3 17 58925 0.034810 0.382174 -0.2192893 0.0004298 0.000301 0.000105 0.000052 0.000038 0.0000057 0.0000126 0.000040 0.000037 2020 3 18 58926 0.035518 0.383028 -0.2196482 0.0003245 0.000282 0.000050 0.000052 0.000038 0.0000056 0.0000126 0.000039 0.000036 2020 3 19 58927 0.036746 0.383993 -0.2199551 0.0002934 0.000256 -0.000027 0.000052 0.000038 0.0000054 0.0000127 0.000039 0.000035 2020 3 20 58928 0.038706 0.385063 -0.2202542 0.0003209 0.000230 -0.000104 0.000051 0.000038 0.0000053 0.0000127 0.000039 0.000034 2020 3 21 58929 0.040911 0.386045 -0.2205675 0.0003708 0.000243 -0.000126 0.000051 0.000038 0.0000052 0.0000128 0.000039 0.000033 2020 3 22 58930 0.042767 0.387279 -0.2209353 0.0004059 0.000270 -0.000127 0.000051 0.000038 0.0000051 0.0000125 0.000039 0.000032 2020 3 23 58931 0.043796 0.388552 -0.2213969 0.0004873 0.000298 -0.000129 0.000050 0.000038 0.0000049 0.0000126 0.000038 0.000032 2020 3 24 58932 0.044596 0.389940 -0.2219350 0.0005568 0.000325 -0.000131 0.000050 0.000038 0.0000048 0.0000126 0.000038 0.000031 2020 3 25 58933 0.044822 0.391441 -0.2224998 0.0005687 0.000293 -0.000088 0.000050 0.000038 0.0000048 0.0000127 0.000038 0.000031 2020 3 26 58934 0.044435 0.393108 -0.2230571 0.0005525 0.000246 -0.000032 0.000050 0.000038 0.0000049 0.0000127 0.000038 0.000031 2020 3 27 58935 0.043828 0.394126 -0.2235761 0.0004775 0.000199 0.000023 0.000050 0.000038 0.0000049 0.0000128 0.000038 0.000032 2020 3 28 58936 0.044672 0.395067 -0.2240329 0.0004229 0.000213 0.000025 0.000051 0.000038 0.0000049 0.0000129 0.000038 0.000032 2020 3 29 58937 0.045829 0.396454 -0.2244108 0.0003321 0.000251 0.000006 0.000051 0.000037 0.0000050 0.0000125 0.000038 0.000032 2020 3 30 58938 0.047045 0.398009 -0.2247096 0.0002516 0.000289 -0.000013 0.000051 0.000037 0.0000051 0.0000125 0.000038 0.000032 2020 3 31 58939 0.048812 0.399638 -0.2249477 0.0002144 0.000327 -0.000032 0.000051 0.000037 0.0000050 0.0000126 0.000039 0.000032 2020 4 1 58940 0.050857 0.401270 -0.2251625 0.0002453 0.000299 -0.000071 0.000051 0.000037 0.0000051 0.0000126 0.000039 0.000033 2020 4 2 58941 0.052653 0.403240 -0.2254211 0.0003060 0.000254 -0.000114 0.000052 0.000037 0.0000053 0.0000127 0.000039 0.000033 2020 4 3 58942 0.054027 0.405231 -0.2258088 0.0004711 0.000209 -0.000158 0.000052 0.000037 0.0000054 0.0000127 0.000039 0.000034 2020 4 4 58943 0.054964 0.406848 -0.2264201 0.0007577 0.000205 -0.000159 0.000052 0.000037 0.0000056 0.0000128 0.000039 0.000034 2020 4 5 58944 0.055428 0.407980 -0.2273265 0.0010730 0.000215 -0.000146 0.000052 0.000037 0.0000057 0.0000125 0.000039 0.000034 2020 4 6 58945 0.055966 0.408880 -0.2285432 0.0013584 0.000226 -0.000132 0.000053 0.000037 0.0000057 0.0000125 0.000039 0.000034 2020 4 7 58946 0.056183 0.409449 -0.2300159 0.0015401 0.000236 -0.000119 0.000053 0.000037 0.0000058 0.0000125 0.000039 0.000034 2020 4 8 58947 0.056906 0.409913 -0.2316246 0.0016364 0.000183 -0.000104 0.000053 0.000037 0.0000059 0.0000126 0.000039 0.000035 2020 4 9 58948 0.057714 0.411016 -0.2332083 0.0015201 0.000114 -0.000088 0.000053 0.000037 0.0000060 0.0000126 0.000039 0.000035 2020 4 10 58949 0.058140 0.412006 -0.2346158 0.0012941 0.000102 -0.000073 0.000053 0.000036 0.0000060 0.0000127 0.000039 0.000035 2020 4 11 58950 0.058541 0.412979 -0.2357568 0.0009873 0.000110 -0.000058 0.000053 0.000036 0.0000060 0.0000127 0.000039 0.000034 2020 4 12 58951 0.059089 0.413985 -0.2366150 0.0007077 0.000119 -0.000043 0.000052 0.000036 0.0000060 0.0000125 0.000039 0.000034 2020 4 13 58952 0.059763 0.415408 -0.2372105 0.0004790 0.000127 -0.000028 0.000052 0.000036 0.0000060 0.0000125 0.000039 0.000034 2020 4 14 58953 0.060958 0.416729 -0.2375994 0.0003122 0.000136 -0.000013 0.000052 0.000036 0.0000060 0.0000125 0.000040 0.000033 2020 4 15 58954 0.062096 0.418082 -0.2378589 0.0001702 0.000144 0.000002 0.000052 0.000036 0.0000059 0.0000126 0.000040 0.000033 2020 4 16 58955 0.062913 0.419660 -0.2380460 0.0001722 0.000181 -0.000021 0.000053 0.000036 0.0000060 0.0000126 0.000040 0.000034 2020 4 17 58956 0.063849 0.421394 -0.2382560 0.0002674 0.000226 -0.000055 0.000053 0.000036 0.0000061 0.0000127 0.000040 0.000035 2020 4 18 58957 0.064558 0.422987 -0.2385852 0.0004043 0.000228 -0.000034 0.000053 0.000036 0.0000062 0.0000127 0.000040 0.000036 2020 4 19 58958 0.064398 0.424255 -0.2390202 0.0004905 0.000214 0.000005 0.000053 0.000036 0.0000062 0.0000125 0.000040 0.000036 2020 4 20 58959 0.063813 0.425119 -0.2395002 0.0004897 0.000200 0.000045 0.000053 0.000036 0.0000063 0.0000126 0.000040 0.000037 2020 4 21 58960 0.063199 0.425896 -0.2399975 0.0004841 0.000186 0.000085 0.000053 0.000036 0.0000065 0.0000126 0.000041 0.000038 2020 4 22 58961 0.063315 0.426486 -0.2405026 0.0004852 0.000203 0.000029 0.000053 0.000036 0.0000065 0.0000127 0.000041 0.000039 2020 4 23 58962 0.064241 0.427347 -0.2409715 0.0004599 0.000228 -0.000053 0.000053 0.000036 0.0000067 0.0000127 0.000041 0.000039 2020 4 24 58963 0.065516 0.428239 -0.2413900 0.0003616 0.000224 -0.000076 0.000054 0.000036 0.0000068 0.0000128 0.000041 0.000040 2020 4 25 58964 0.067108 0.429319 -0.2416852 0.0002295 0.000209 -0.000078 0.000054 0.000036 0.0000069 0.0000128 0.000041 0.000040 2020 4 26 58965 0.068444 0.430783 -0.2418475 0.0001213 0.000194 -0.000079 0.000054 0.000036 0.0000070 0.0000125 0.000041 0.000040 2020 4 27 58966 0.069374 0.431979 -0.2419828 0.0000962 0.000179 -0.000080 0.000054 0.000036 0.0000068 0.0000126 0.000041 0.000040 2020 4 28 58967 0.070651 0.432914 -0.2420713 0.0000758 0.000164 -0.000081 0.000054 0.000036 0.0000068 0.0000127 0.000041 0.000040 2020 4 29 58968 0.072257 0.433716 -0.2421323 0.0000576 0.000156 -0.000073 0.000054 0.000036 0.0000068 0.0000127 0.000041 0.000040 2020 4 30 58969 0.074184 0.434641 -0.2422391 0.0001523 0.000149 -0.000063 0.000055 0.000036 0.0000068 0.0000128 0.000041 0.000039 2020 5 1 58970 0.075876 0.435873 -0.2424745 0.0003425 0.000161 -0.000074 0.000055 0.000037 0.0000068 0.0000128 0.000041 0.000038 2020 5 2 58971 0.077588 0.436915 -0.2429170 0.0005860 0.000179 -0.000093 0.000054 0.000036 0.0000068 0.0000129 0.000041 0.000037 2020 5 3 58972 0.079720 0.438133 -0.2436308 0.0008396 0.000197 -0.000112 0.000054 0.000036 0.0000068 0.0000130 0.000041 0.000036 2020 5 4 58973 0.081539 0.439339 -0.2445748 0.0010690 0.000216 -0.000131 0.000054 0.000036 0.0000068 0.0000130 0.000041 0.000035 2020 5 5 58974 0.083001 0.440397 -0.2456700 0.0011321 0.000234 -0.000149 0.000054 0.000037 0.0000068 0.0000131 0.000041 0.000034 2020 5 6 58975 0.084371 0.441298 -0.2468040 0.0011108 0.000219 -0.000162 0.000054 0.000037 0.0000069 0.0000132 0.000041 0.000034 2020 5 7 58976 0.085880 0.442199 -0.2478448 0.0009728 0.000195 -0.000173 0.000054 0.000037 0.0000070 0.0000132 0.000041 0.000034 2020 5 8 58977 0.087577 0.442774 -0.2486936 0.0007462 0.000172 -0.000184 0.000053 0.000036 0.0000071 0.0000129 0.000042 0.000035 2020 5 9 58978 0.089488 0.443500 -0.2493145 0.0005172 0.000159 -0.000168 0.000053 0.000036 0.0000072 0.0000129 0.000042 0.000035 2020 5 10 58979 0.091613 0.444552 -0.2497270 0.0003195 0.000151 -0.000142 0.000052 0.000035 0.0000073 0.0000126 0.000042 0.000035 2020 5 11 58980 0.093236 0.445566 -0.2499850 0.0001858 0.000142 -0.000116 0.000052 0.000035 0.0000074 0.0000126 0.000042 0.000036 2020 5 12 58981 0.094612 0.446353 -0.2501641 0.0001770 0.000133 -0.000090 0.000052 0.000035 0.0000074 0.0000127 0.000042 0.000036 2020 5 13 58982 0.095989 0.446778 -0.2503571 0.0001767 0.000145 -0.000093 0.000052 0.000034 0.0000075 0.0000127 0.000043 0.000036 2020 5 14 58983 0.097182 0.446651 -0.2505619 0.0001941 0.000162 -0.000103 0.000052 0.000034 0.0000076 0.0000128 0.000043 0.000037 2020 5 15 58984 0.098876 0.446341 -0.2507604 0.0002778 0.000180 -0.000114 0.000052 0.000034 0.0000076 0.0000128 0.000043 0.000037 2020 5 16 58985 0.100314 0.446369 -0.2510803 0.0003654 0.000170 -0.000114 0.000052 0.000034 0.0000076 0.0000129 0.000043 0.000038 2020 5 17 58986 0.101760 0.446093 -0.2514781 0.0004799 0.000150 -0.000110 0.000051 0.000033 0.0000076 0.0000126 0.000044 0.000038 2020 5 18 58987 0.102987 0.446067 -0.2520116 0.0005811 0.000129 -0.000106 0.000050 0.000033 0.0000076 0.0000126 0.000044 0.000038 2020 5 19 58988 0.104425 0.445811 -0.2526084 0.0005937 0.000109 -0.000102 0.000050 0.000033 0.0000076 0.0000126 0.000044 0.000038 2020 5 20 58989 0.106126 0.445938 -0.2531595 0.0005169 0.000118 -0.000097 0.000050 0.000033 0.0000077 0.0000127 0.000044 0.000039 2020 5 21 58990 0.107451 0.446340 -0.2536215 0.0004139 0.000135 -0.000093 0.000050 0.000033 0.0000079 0.0000127 0.000045 0.000041 2020 5 22 58991 0.108276 0.446830 -0.2539584 0.0002708 0.000152 -0.000088 0.000050 0.000033 0.0000080 0.0000128 0.000045 0.000043 2020 5 23 58992 0.108413 0.447082 -0.2541455 0.0001033 0.000143 -0.000084 0.000050 0.000033 0.0000082 0.0000128 0.000045 0.000044 2020 5 24 58993 0.108453 0.446641 -0.2541522 -0.0000695 0.000125 -0.000079 0.000049 0.000032 0.0000083 0.0000126 0.000046 0.000045 2020 5 25 58994 0.108379 0.446015 -0.2540079 -0.0001838 0.000107 -0.000075 0.000049 0.000032 0.0000085 0.0000126 0.000046 0.000046 2020 5 26 58995 0.108296 0.445345 -0.2538363 -0.0002193 0.000089 -0.000071 0.000049 0.000032 0.0000086 0.0000127 0.000046 0.000047 2020 5 27 58996 0.109175 0.444412 -0.2536837 -0.0001520 0.000071 -0.000067 0.000049 0.000032 0.0000088 0.0000127 0.000047 0.000048 2020 5 28 58997 0.110181 0.443910 -0.2535569 -0.0000617 0.000132 -0.000121 0.000049 0.000032 0.0000089 0.0000127 0.000047 0.000050 2020 5 29 58998 0.110932 0.443391 -0.2535459 0.0000737 0.000213 -0.000191 0.000049 0.000032 0.0000091 0.0000128 0.000048 0.000052 2020 5 30 58999 0.112039 0.442888 -0.2537140 0.0002698 0.000211 -0.000201 0.000049 0.000032 0.0000091 0.0000128 0.000048 0.000053 2020 5 31 59000 0.113109 0.442390 -0.2540926 0.0004718 0.000177 -0.000189 0.000048 0.000031 0.0000093 0.0000126 0.000048 0.000054 2020 6 1 59001 0.114095 0.441605 -0.2546428 0.0006051 0.000144 -0.000176 0.000048 0.000031 0.0000095 0.0000126 0.000048 0.000056 2020 6 2 59002 0.115356 0.440965 -0.2552636 0.0005944 0.000111 -0.000164 0.000048 0.000031 0.0000096 0.0000127 0.000049 0.000057 2020 6 3 59003 0.116557 0.440577 -0.2558111 0.0004238 0.000078 -0.000152 0.000049 0.000031 0.0000097 0.0000127 0.000049 0.000058 2020 6 4 59004 0.117960 0.440275 -0.2561433 0.0001999 0.000086 -0.000144 0.000049 0.000031 0.0000098 0.0000128 0.000049 0.000059 2020 6 5 59005 0.119592 0.440373 -0.2562125 -0.0000442 0.000106 -0.000138 0.000049 0.000031 0.0000097 0.0000128 0.000049 0.000060 2020 6 6 59006 0.121341 0.440754 -0.2560362 -0.0002611 0.000109 -0.000129 0.000049 0.000032 0.0000099 0.0000129 0.000050 0.000061 2020 6 7 59007 0.123021 0.441349 -0.2556732 -0.0004235 0.000107 -0.000119 0.000049 0.000032 0.0000102 0.0000130 0.000050 0.000062 2020 6 8 59008 0.124214 0.441730 -0.2551905 -0.0005518 0.000105 -0.000109 0.000048 0.000031 0.0000100 0.0000127 0.000050 0.000062 2020 6 9 59009 0.125342 0.441604 -0.2546373 -0.0006060 0.000103 -0.000099 0.000048 0.000031 0.0000101 0.0000127 0.000050 0.000063 2020 6 10 59010 0.126901 0.441125 -0.2540253 -0.0006402 0.000098 -0.000095 0.000049 0.000031 0.0000102 0.0000128 0.000050 0.000063 2020 6 11 59011 0.128704 0.440696 -0.2533824 -0.0006234 0.000092 -0.000092 0.000049 0.000031 0.0000102 0.0000128 0.000050 0.000064 2020 6 12 59012 0.130552 0.440812 -0.2527082 -0.0006319 0.000145 -0.000061 0.000049 0.000031 0.0000102 0.0000129 0.000050 0.000063 2020 6 13 59013 0.132365 0.440839 -0.2520923 -0.0005984 0.000221 -0.000018 0.000049 0.000031 0.0000102 0.0000129 0.000050 0.000062 2020 6 14 59014 0.134367 0.440694 -0.2515698 -0.0004699 0.000297 0.000025 0.000049 0.000031 0.0000102 0.0000130 0.000050 0.000061 2020 6 15 59015 0.136361 0.440461 -0.2511455 -0.0003956 0.000373 0.000067 0.000048 0.000031 0.0000102 0.0000127 0.000050 0.000060 2020 6 16 59016 0.138330 0.439889 -0.2507551 -0.0004115 0.000449 0.000110 0.000048 0.000031 0.0000102 0.0000127 0.000050 0.000059 2020 6 17 59017 0.140357 0.439316 -0.2502728 -0.0004882 0.000386 0.000059 0.000048 0.000031 0.0000102 0.0000128 0.000050 0.000058 2020 6 18 59018 0.142486 0.438802 -0.2496915 -0.0006405 0.000287 -0.000016 0.000048 0.000031 0.0000100 0.0000128 0.000050 0.000056 2020 6 19 59019 0.144941 0.438049 -0.2490204 -0.0008280 0.000187 -0.000092 0.000048 0.000031 0.0000099 0.0000129 0.000050 0.000054 2020 6 20 59020 0.147096 0.437587 -0.2481020 -0.0010077 0.000161 -0.000111 0.000048 0.000031 0.0000099 0.0000129 0.000050 0.000052 2020 6 21 59021 0.149313 0.437067 -0.2470621 -0.0011348 0.000162 -0.000109 0.000048 0.000031 0.0000096 0.0000130 0.000049 0.000050 2020 6 22 59022 0.151173 0.436544 -0.2459006 -0.0011882 0.000163 -0.000107 0.000048 0.000031 0.0000096 0.0000131 0.000049 0.000048 2020 6 23 59023 0.152501 0.435847 -0.2447075 -0.0011609 0.000163 -0.000106 0.000048 0.000031 0.0000096 0.0000131 0.000049 0.000046 2020 6 24 59024 0.153957 0.435016 -0.2435776 -0.0010590 0.000191 -0.000102 0.000046 0.000031 0.0000096 0.0000129 0.000049 0.000046 2020 6 25 59025 0.155435 0.434459 -0.2426081 -0.0008700 0.000227 -0.000098 0.000046 0.000031 0.0000098 0.0000129 0.000049 0.000046 2020 6 26 59026 0.156934 0.433845 -0.2418658 -0.0006289 0.000262 -0.000094 0.000046 0.000031 0.0000097 0.0000130 0.000049 0.000046 2020 6 27 59027 0.158898 0.433340 -0.2413584 -0.0003980 0.000243 -0.000101 0.000046 0.000031 0.0000097 0.0000131 0.000049 0.000046 2020 6 28 59028 0.160843 0.432785 -0.2410263 -0.0002585 0.000203 -0.000111 0.000045 0.000030 0.0000096 0.0000122 0.000049 0.000045 2020 6 29 59029 0.162741 0.432243 -0.2408089 -0.0002157 0.000163 -0.000121 0.000045 0.000030 0.0000095 0.0000123 0.000049 0.000045 2020 6 30 59030 0.164819 0.432093 -0.2405730 -0.0003266 0.000123 -0.000131 0.000045 0.000030 0.0000094 0.0000123 0.000049 0.000044 2020 7 1 59031 0.166926 0.431645 -0.2401540 -0.0005330 0.000117 -0.000151 0.000045 0.000031 0.0000094 0.0000123 0.000049 0.000044 2020 7 2 59032 0.168557 0.431033 -0.2394930 -0.0007733 0.000119 -0.000173 0.000045 0.000031 0.0000093 0.0000124 0.000049 0.000044 2020 7 3 59033 0.170032 0.430055 -0.2386042 -0.0009919 0.000132 -0.000181 0.000045 0.000031 0.0000094 0.0000124 0.000049 0.000043 2020 7 4 59034 0.171560 0.428853 -0.2374976 -0.0011888 0.000148 -0.000184 0.000045 0.000031 0.0000092 0.0000125 0.000048 0.000043 2020 7 5 59035 0.173368 0.427397 -0.2362157 -0.0013336 0.000164 -0.000187 0.000045 0.000031 0.0000092 0.0000125 0.000048 0.000042 2020 7 6 59036 0.175553 0.426079 -0.2348932 -0.0013264 0.000180 -0.000190 0.000045 0.000031 0.0000092 0.0000126 0.000048 0.000041 2020 7 7 59037 0.177661 0.424849 -0.2336113 -0.0012547 0.000196 -0.000193 0.000045 0.000031 0.0000092 0.0000126 0.000048 0.000040 2020 7 8 59038 0.179613 0.423425 -0.2324088 -0.0011768 0.000173 -0.000177 0.000046 0.000032 0.0000092 0.0000127 0.000048 0.000040 2020 7 9 59039 0.181521 0.421864 -0.2312898 -0.0010791 0.000139 -0.000156 0.000045 0.000031 0.0000092 0.0000123 0.000048 0.000041 2020 7 10 59040 0.183418 0.420421 -0.2302231 -0.0009941 0.000106 -0.000136 0.000045 0.000031 0.0000092 0.0000123 0.000048 0.000042 2020 7 11 59041 0.185188 0.419417 -0.2292534 -0.0009766 0.000102 -0.000134 0.000045 0.000031 0.0000092 0.0000124 0.000048 0.000042 2020 7 12 59042 0.186700 0.418240 -0.2282505 -0.0010200 0.000108 -0.000140 0.000046 0.000031 0.0000092 0.0000124 0.000048 0.000042 2020 7 13 59043 0.187629 0.416964 -0.2272025 -0.0010697 0.000115 -0.000146 0.000045 0.000031 0.0000092 0.0000121 0.000049 0.000042 2020 7 14 59044 0.188400 0.415662 -0.2261191 -0.0011213 0.000121 -0.000152 0.000045 0.000031 0.0000093 0.0000121 0.000049 0.000042 2020 7 15 59045 0.189708 0.414695 -0.2249892 -0.0011788 0.000130 -0.000152 0.000045 0.000031 0.0000094 0.0000121 0.000049 0.000043 2020 7 16 59046 0.190936 0.413918 -0.2237845 -0.0012457 0.000140 -0.000152 0.000046 0.000031 0.0000096 0.0000122 0.000049 0.000043 2020 7 17 59047 0.192195 0.412935 -0.2224785 -0.0013164 0.000149 -0.000151 0.000046 0.000031 0.0000098 0.0000122 0.000049 0.000044 2020 7 18 59048 0.193260 0.411933 -0.2211074 -0.0014070 0.000159 -0.000153 0.000046 0.000031 0.0000099 0.0000122 0.000049 0.000044 2020 7 19 59049 0.193896 0.410755 -0.2196918 -0.0014663 0.000169 -0.000156 0.000046 0.000031 0.0000102 0.0000123 0.000049 0.000044 2020 7 20 59050 0.194356 0.409458 -0.2182373 -0.0014190 0.000178 -0.000159 0.000046 0.000031 0.0000104 0.0000119 0.000049 0.000045 2020 7 21 59051 0.194688 0.408238 -0.2168640 -0.0012724 0.000188 -0.000162 0.000046 0.000031 0.0000105 0.0000120 0.000049 0.000045 2020 7 22 59052 0.195127 0.406704 -0.2156688 -0.0010646 0.000163 -0.000153 0.000046 0.000031 0.0000107 0.0000120 0.000050 0.000046 2020 7 23 59053 0.195548 0.405185 -0.2147063 -0.0008562 0.000128 -0.000142 0.000046 0.000031 0.0000102 0.0000120 0.000050 0.000048 2020 7 24 59054 0.196360 0.403989 -0.2139791 -0.0006416 0.000093 -0.000131 0.000046 0.000031 0.0000103 0.0000121 0.000050 0.000049 2020 7 25 59055 0.197205 0.402836 -0.2134367 -0.0005213 0.000106 -0.000123 0.000046 0.000031 0.0000104 0.0000121 0.000050 0.000051 2020 7 26 59056 0.197779 0.401664 -0.2129757 -0.0004897 0.000136 -0.000117 0.000046 0.000031 0.0000106 0.0000122 0.000051 0.000052 2020 7 27 59057 0.198067 0.400506 -0.2124662 -0.0005643 0.000167 -0.000110 0.000046 0.000031 0.0000107 0.0000118 0.000051 0.000054 2020 7 28 59058 0.198139 0.399287 -0.2118373 -0.0006872 0.000198 -0.000103 0.000046 0.000031 0.0000109 0.0000119 0.000051 0.000056 2020 7 29 59059 0.198581 0.398202 -0.2110818 -0.0008293 0.000183 -0.000082 0.000046 0.000031 0.0000110 0.0000119 0.000051 0.000057 2020 7 30 59060 0.199254 0.397133 -0.2101850 -0.0009562 0.000157 -0.000056 0.000046 0.000031 0.0000110 0.0000120 0.000052 0.000058 2020 7 31 59061 0.199858 0.395993 -0.2091724 -0.0010540 0.000130 -0.000031 0.000046 0.000031 0.0000111 0.0000120 0.000052 0.000060 2020 8 1 59062 0.200916 0.394791 -0.2081196 -0.0010540 0.000112 -0.000013 0.000046 0.000031 0.0000105 0.0000120 0.000052 0.000061 2020 8 2 59063 0.202618 0.394109 -0.2070472 -0.0010157 0.000097 0.000003 0.000046 0.000031 0.0000105 0.0000121 0.000052 0.000063 2020 8 3 59064 0.203857 0.393712 -0.2060676 -0.0009380 0.000082 0.000018 0.000046 0.000031 0.0000105 0.0000121 0.000053 0.000064 2020 8 4 59065 0.204978 0.393256 -0.2052248 -0.0007909 0.000066 0.000034 0.000046 0.000031 0.0000105 0.0000122 0.000053 0.000066 2020 8 5 59066 0.206149 0.392575 -0.2044963 -0.0006824 0.000077 0.000022 0.000046 0.000031 0.0000103 0.0000123 0.000053 0.000067 2020 8 6 59067 0.207131 0.391715 -0.2038968 -0.0005592 0.000094 0.000003 0.000046 0.000031 0.0000120 0.0000119 0.000053 0.000067 2020 8 7 59068 0.207997 0.390904 -0.2034232 -0.0004263 0.000111 -0.000016 0.000046 0.000031 0.0000121 0.0000119 0.000053 0.000067 2020 8 8 59069 0.208823 0.389508 -0.2030598 -0.0003350 0.000127 -0.000032 0.000046 0.000031 0.0000122 0.0000120 0.000053 0.000066 2020 8 9 59070 0.209912 0.388019 -0.2027319 -0.0003316 0.000143 -0.000047 0.000046 0.000031 0.0000118 0.0000117 0.000054 0.000066 2020 8 10 59071 0.210987 0.386680 -0.2023438 -0.0004217 0.000159 -0.000062 0.000046 0.000031 0.0000118 0.0000117 0.000054 0.000065 2020 8 11 59072 0.212000 0.385344 -0.2018452 -0.0005731 0.000175 -0.000077 0.000046 0.000031 0.0000118 0.0000118 0.000054 0.000064 2020 8 12 59073 0.213138 0.383934 -0.2012087 -0.0007229 0.000191 -0.000092 0.000046 0.000031 0.0000118 0.0000118 0.000054 0.000064 2020 8 13 59074 0.214369 0.382229 -0.2004326 -0.0008567 0.000195 -0.000106 0.000046 0.000031 0.0000116 0.0000118 0.000054 0.000062 2020 8 14 59075 0.215208 0.380501 -0.1995089 -0.0009856 0.000195 -0.000120 0.000046 0.000031 0.0000115 0.0000119 0.000054 0.000060 2020 8 15 59076 0.215710 0.379116 -0.1984422 -0.0010961 0.000192 -0.000136 0.000046 0.000032 0.0000114 0.0000119 0.000053 0.000058 2020 8 16 59077 0.216181 0.377875 -0.1972937 -0.0011496 0.000187 -0.000152 0.000046 0.000031 0.0000125 0.0000117 0.000053 0.000057 2020 8 17 59078 0.216815 0.377092 -0.1961824 -0.0010903 0.000183 -0.000169 0.000046 0.000031 0.0000124 0.0000117 0.000053 0.000055 2020 8 18 59079 0.217198 0.376427 -0.1951499 -0.0009586 0.000179 -0.000185 0.000046 0.000031 0.0000123 0.0000117 0.000053 0.000054 2020 8 19 59080 0.217097 0.375794 -0.1942910 -0.0007516 0.000174 -0.000201 0.000046 0.000031 0.0000121 0.0000118 0.000053 0.000052 2020 8 20 59081 0.216740 0.374898 -0.1936905 -0.0004787 0.000208 -0.000180 0.000046 0.000031 0.0000121 0.0000118 0.000053 0.000052 2020 8 21 59082 0.216769 0.373565 -0.1933538 -0.0002135 0.000253 -0.000149 0.000046 0.000031 0.0000115 0.0000119 0.000053 0.000053 2020 8 22 59083 0.216932 0.371778 -0.1932222 -0.0000596 0.000217 -0.000130 0.000046 0.000032 0.0000114 0.0000119 0.000053 0.000052 2020 8 23 59084 0.217580 0.370054 -0.1931667 -0.0000789 0.000151 -0.000115 0.000046 0.000032 0.0000116 0.0000120 0.000053 0.000051 2020 8 24 59085 0.218417 0.368646 -0.1930381 -0.0002268 0.000086 -0.000100 0.000046 0.000032 0.0000115 0.0000120 0.000053 0.000051 2020 8 25 59086 0.218821 0.367280 -0.1927121 -0.0004572 0.000021 -0.000085 0.000046 0.000032 0.0000114 0.0000121 0.000053 0.000050 2020 8 26 59087 0.218848 0.366011 -0.1921170 -0.0007332 0.000038 -0.000090 0.000046 0.000032 0.0000115 0.0000122 0.000053 0.000051 2020 8 27 59088 0.218568 0.364900 -0.1912433 -0.0009788 0.000077 -0.000101 0.000046 0.000032 0.0000115 0.0000122 0.000054 0.000052 2020 8 28 59089 0.218460 0.363753 -0.1901406 -0.0011675 0.000116 -0.000111 0.000046 0.000033 0.0000116 0.0000123 0.000054 0.000054 2020 8 29 59090 0.218163 0.363164 -0.1888889 -0.0012589 0.000142 -0.000102 0.000047 0.000033 0.0000117 0.0000124 0.000054 0.000055 2020 8 30 59091 0.217507 0.362331 -0.1876041 -0.0012675 0.000164 -0.000086 0.000046 0.000032 0.0000115 0.0000120 0.000054 0.000056 2020 8 31 59092 0.216816 0.361537 -0.1864039 -0.0011495 0.000185 -0.000069 0.000046 0.000033 0.0000114 0.0000120 0.000054 0.000058 2020 9 1 59093 0.215870 0.360680 -0.1853447 -0.0009829 0.000206 -0.000053 0.000046 0.000033 0.0000114 0.0000121 0.000055 0.000059 2020 9 2 59094 0.214888 0.359360 -0.1844359 -0.0008078 0.000218 -0.000059 0.000046 0.000033 0.0000114 0.0000122 0.000055 0.000059 2020 9 3 59095 0.214008 0.357869 -0.1836718 -0.0006993 0.000228 -0.000071 0.000046 0.000033 0.0000114 0.0000122 0.000055 0.000059 2020 9 4 59096 0.213234 0.356016 -0.1830210 -0.0006290 0.000237 -0.000082 0.000046 0.000033 0.0000113 0.0000123 0.000055 0.000059 2020 9 5 59097 0.212795 0.354430 -0.1824364 -0.0005731 0.000230 -0.000085 0.000046 0.000033 0.0000111 0.0000124 0.000055 0.000059 2020 9 6 59098 0.212274 0.353191 -0.1818721 -0.0005450 0.000217 -0.000084 0.000046 0.000033 0.0000110 0.0000125 0.000055 0.000058 2020 9 7 59099 0.211790 0.351835 -0.1812925 -0.0005934 0.000204 -0.000084 0.000045 0.000032 0.0000110 0.0000117 0.000055 0.000058 2020 9 8 59100 0.211193 0.350339 -0.1806562 -0.0006743 0.000191 -0.000083 0.000045 0.000031 0.0000109 0.0000117 0.000055 0.000057 2020 9 9 59101 0.210918 0.349451 -0.1799467 -0.0007776 0.000178 -0.000082 0.000045 0.000031 0.0000109 0.0000118 0.000055 0.000057 2020 9 10 59102 0.210855 0.348811 -0.1791721 -0.0008106 0.000137 -0.000059 0.000045 0.000031 0.0000109 0.0000118 0.000055 0.000057 2020 9 11 59103 0.210933 0.348368 -0.1783511 -0.0007954 0.000090 -0.000029 0.000045 0.000031 0.0000114 0.0000119 0.000055 0.000057 2020 9 12 59104 0.210314 0.347629 -0.1775178 -0.0007983 0.000085 -0.000019 0.000045 0.000031 0.0000117 0.0000119 0.000055 0.000056 2020 9 13 59105 0.209427 0.346406 -0.1767408 -0.0007225 0.000097 -0.000017 0.000045 0.000031 0.0000117 0.0000117 0.000055 0.000055 2020 9 14 59106 0.208717 0.345499 -0.1761147 -0.0005314 0.000108 -0.000014 0.000045 0.000031 0.0000117 0.0000117 0.000055 0.000055 2020 9 15 59107 0.208051 0.344156 -0.1757085 -0.0002763 0.000120 -0.000012 0.000045 0.000031 0.0000117 0.0000118 0.000055 0.000054 2020 9 16 59108 0.207856 0.342757 -0.1755535 -0.0000032 0.000082 -0.000038 0.000045 0.000031 0.0000118 0.0000118 0.000056 0.000054 2020 9 17 59109 0.207763 0.341482 -0.1756637 0.0002120 0.000030 -0.000071 0.000045 0.000031 0.0000120 0.0000118 0.000056 0.000056 2020 9 18 59110 0.207499 0.340031 -0.1759844 0.0003569 -0.000021 -0.000104 0.000045 0.000031 0.0000126 0.0000119 0.000056 0.000057 2020 9 19 59111 0.206755 0.338625 -0.1764092 0.0004253 -0.000017 -0.000110 0.000045 0.000031 0.0000128 0.0000120 0.000056 0.000058 2020 9 20 59112 0.205778 0.337224 -0.1767967 0.0003203 0.000009 -0.000106 0.000045 0.000031 0.0000134 0.0000120 0.000056 0.000060 2020 9 21 59113 0.204647 0.335988 -0.1770190 0.0001175 0.000034 -0.000102 0.000045 0.000031 0.0000136 0.0000117 0.000057 0.000062 2020 9 22 59114 0.203448 0.334984 -0.1770237 -0.0001062 0.000059 -0.000097 0.000045 0.000031 0.0000138 0.0000118 0.000057 0.000064 2020 9 23 59115 0.202369 0.333990 -0.1768324 -0.0002892 0.000033 -0.000089 0.000045 0.000031 0.0000141 0.0000118 0.000057 0.000065 2020 9 24 59116 0.201447 0.333000 -0.1764820 -0.0004005 -0.000006 -0.000079 0.000045 0.000031 0.0000142 0.0000118 0.000057 0.000066 2020 9 25 59117 0.200100 0.331835 -0.1760287 -0.0004429 -0.000045 -0.000069 0.000045 0.000031 0.0000144 0.0000119 0.000057 0.000067 2020 9 26 59118 0.198705 0.330548 -0.1755265 -0.0004754 -0.000024 -0.000032 0.000046 0.000031 0.0000145 0.0000119 0.000057 0.000067 2020 9 27 59119 0.197236 0.329251 -0.1750164 -0.0005323 0.000020 0.000015 0.000046 0.000031 0.0000145 0.0000120 0.000057 0.000066 2020 9 28 59120 0.196127 0.327949 -0.1745224 -0.0005057 0.000063 0.000062 0.000046 0.000031 0.0000147 0.0000121 0.000057 0.000066 2020 9 29 59121 0.195040 0.326608 -0.1740769 -0.0003921 0.000107 0.000108 0.000046 0.000032 0.0000148 0.0000121 0.000057 0.000065 2020 9 30 59122 0.194222 0.325303 -0.1737113 -0.0002857 0.000132 0.000080 0.000046 0.000032 0.0000150 0.0000122 0.000058 0.000065 2020 10 1 59123 0.193592 0.324399 -0.1734352 -0.0002262 0.000152 0.000032 0.000047 0.000032 0.0000152 0.0000123 0.000058 0.000065 2020 10 2 59124 0.192652 0.323725 -0.1732413 -0.0001769 0.000171 -0.000016 0.000047 0.000032 0.0000153 0.0000123 0.000058 0.000065 2020 10 3 59125 0.191328 0.322856 -0.1731044 -0.0001385 0.000158 -0.000014 0.000047 0.000032 0.0000154 0.0000124 0.000058 0.000065 2020 10 4 59126 0.190376 0.321580 -0.1729735 -0.0001437 0.000132 0.000006 0.000048 0.000033 0.0000155 0.0000125 0.000058 0.000065 2020 10 5 59127 0.190057 0.320101 -0.1727946 -0.0002063 0.000106 0.000026 0.000048 0.000033 0.0000156 0.0000126 0.000058 0.000064 2020 10 6 59128 0.189565 0.319194 -0.1725157 -0.0003291 0.000080 0.000046 0.000049 0.000033 0.0000156 0.0000127 0.000058 0.000064 2020 10 7 59129 0.188477 0.318544 -0.1720944 -0.0004769 0.000075 0.000044 0.000046 0.000031 0.0000157 0.0000117 0.000058 0.000063 2020 10 8 59130 0.187213 0.317589 -0.1715545 -0.0005752 0.000075 0.000036 0.000047 0.000031 0.0000156 0.0000117 0.000058 0.000063 2020 10 9 59131 0.185866 0.316267 -0.1709438 -0.0006027 0.000075 0.000028 0.000047 0.000031 0.0000156 0.0000118 0.000058 0.000062 2020 10 10 59132 0.184598 0.314938 -0.1703470 -0.0005638 0.000081 0.000028 0.000047 0.000031 0.0000156 0.0000118 0.000058 0.000061 2020 10 11 59133 0.183096 0.313821 -0.1698266 -0.0004507 0.000089 0.000030 0.000047 0.000032 0.0000156 0.0000118 0.000058 0.000060 2020 10 12 59134 0.181364 0.312491 -0.1694229 -0.0002698 0.000096 0.000032 0.000048 0.000032 0.0000156 0.0000118 0.000058 0.000059 2020 10 13 59135 0.180150 0.311276 -0.1692873 0.0000023 0.000104 0.000034 0.000048 0.000032 0.0000156 0.0000119 0.000058 0.000058 2020 10 14 59136 0.179028 0.310496 -0.1694783 0.0003013 0.000112 0.000036 0.000048 0.000032 0.0000157 0.0000119 0.000058 0.000057 2020 10 15 59137 0.178273 0.309566 -0.1699480 0.0005931 0.000131 0.000024 0.000048 0.000032 0.0000158 0.0000120 0.000058 0.000058 2020 10 16 59138 0.177870 0.308850 -0.1706403 0.0007682 0.000152 0.000008 0.000049 0.000032 0.0000159 0.0000120 0.000058 0.000059 2020 10 17 59139 0.177728 0.308173 -0.1714530 0.0007984 0.000134 0.000009 0.000049 0.000032 0.0000159 0.0000121 0.000058 0.000060 2020 10 18 59140 0.177883 0.307413 -0.1722056 0.0006699 0.000102 0.000015 0.000049 0.000032 0.0000160 0.0000122 0.000059 0.000061 2020 10 19 59141 0.177193 0.306640 -0.1727351 0.0003985 0.000069 0.000022 0.000049 0.000032 0.0000161 0.0000122 0.000059 0.000062 2020 10 20 59142 0.175829 0.305561 -0.1730135 0.0001477 0.000037 0.000029 0.000049 0.000033 0.0000162 0.0000123 0.000059 0.000063 2020 10 21 59143 0.174443 0.304709 -0.1731105 0.0000250 0.000201 0.000094 0.000049 0.000033 0.0000162 0.0000124 0.000059 0.000064 2020 10 22 59144 0.173243 0.304010 -0.1731120 0.0000231 0.000249 0.000130 0.000049 0.000032 0.0000162 0.0000121 0.000059 0.000064 2020 10 23 59145 0.172122 0.303220 -0.1731129 0.0000584 0.000248 0.000152 0.000049 0.000033 0.0000161 0.0000121 0.000059 0.000063 2020 10 24 59146 0.170979 0.302398 -0.1731915 0.0001102 0.000236 0.000123 0.000050 0.000033 0.0000161 0.0000122 0.000059 0.000063 2020 10 25 59147 0.169567 0.301498 -0.1733234 0.0001512 0.000219 0.000074 0.000050 0.000033 0.0000162 0.0000119 0.000059 0.000063 2020 10 26 59148 0.168213 0.300588 -0.1735104 0.0002021 0.000203 0.000025 0.000050 0.000033 0.0000164 0.0000120 0.000059 0.000062 2020 10 27 59149 0.167025 0.299828 -0.1737708 0.0003055 0.000186 -0.000024 0.000051 0.000034 0.0000165 0.0000120 0.000059 0.000062 2020 10 28 59150 0.165274 0.299221 -0.1741049 0.0003277 0.000210 0.000012 0.000052 0.000034 0.0000168 0.0000121 0.000059 0.000061 2020 10 29 59151 0.163658 0.298406 -0.1744617 0.0003476 0.000245 0.000070 0.000052 0.000034 0.0000169 0.0000122 0.000059 0.000060 2020 10 30 59152 0.162242 0.298257 -0.1747434 0.0003315 0.000280 0.000128 0.000053 0.000035 0.0000171 0.0000122 0.000059 0.000058 2020 10 31 59153 0.160455 0.297779 -0.1750666 0.0002816 0.000277 0.000138 0.000053 0.000035 0.0000174 0.0000123 0.000059 0.000057 2020 11 1 59154 0.158546 0.297059 -0.1753208 0.0002180 0.000261 0.000131 0.000054 0.000035 0.0000175 0.0000124 0.000059 0.000056 2020 11 2 59155 0.156760 0.296584 -0.1754892 0.0001127 0.000244 0.000123 0.000054 0.000036 0.0000177 0.0000124 0.000059 0.000054 2020 11 3 59156 0.155022 0.296077 -0.1755506 -0.0000052 0.000228 0.000116 0.000055 0.000036 0.0000178 0.0000125 0.000059 0.000053 2020 11 4 59157 0.153756 0.295403 -0.1755009 -0.0001017 0.000211 0.000109 0.000055 0.000037 0.0000178 0.0000126 0.000059 0.000052 2020 11 5 59158 0.153116 0.294628 -0.1753222 -0.0002389 0.000133 0.000118 0.000055 0.000037 0.0000177 0.0000127 0.000059 0.000050 2020 11 6 59159 0.152204 0.293485 -0.1750506 -0.0003217 0.000038 0.000132 0.000056 0.000037 0.0000179 0.0000128 0.000058 0.000048 2020 11 7 59160 0.150933 0.292707 -0.1747265 -0.0002549 0.000064 0.000114 0.000056 0.000038 0.0000179 0.0000129 0.000058 0.000046 2020 11 8 59161 0.149316 0.292406 -0.1745355 -0.0000783 0.000133 0.000085 0.000056 0.000038 0.0000177 0.0000130 0.000058 0.000044 2020 11 9 59162 0.147825 0.292052 -0.1745810 0.0001968 0.000203 0.000056 0.000057 0.000038 0.0000178 0.0000131 0.000058 0.000041 2020 11 10 59163 0.146154 0.291593 -0.1748950 0.0004636 0.000272 0.000027 0.000057 0.000039 0.0000179 0.0000132 0.000057 0.000040 2020 11 11 59164 0.144139 0.291248 -0.1754908 0.0006676 0.000264 0.000019 0.000057 0.000039 0.0000181 0.0000133 0.000058 0.000040 2020 11 12 59165 0.142123 0.290642 -0.1762784 0.0008387 0.000236 0.000017 0.000057 0.000039 0.0000183 0.0000134 0.000058 0.000042 2020 11 13 59166 0.140177 0.290279 -0.1771548 0.0008941 0.000208 0.000015 0.000058 0.000040 0.0000183 0.0000135 0.000059 0.000044 2020 11 14 59167 0.137794 0.289624 -0.1779689 0.0007757 0.000162 0.000020 0.000058 0.000040 0.0000189 0.0000136 0.000060 0.000045 2020 11 15 59168 0.135204 0.288983 -0.1786182 0.0005395 0.000109 0.000029 0.000058 0.000041 0.0000190 0.0000138 0.000060 0.000046 2020 11 16 59169 0.132881 0.288419 -0.1790137 0.0002432 0.000057 0.000038 0.000059 0.000041 0.0000123 0.0000139 0.000061 0.000047 2020 11 17 59170 0.130805 0.288003 -0.1791225 -0.0000384 0.000004 0.000047 0.000050 0.000038 0.0000111 0.0000072 0.000061 0.000048 2020 11 18 59171 0.129000 0.287331 -0.1790233 -0.0002270 0.000028 0.000053 0.000051 0.000039 0.0000111 0.0000072 0.000062 0.000049 2020 11 19 59172 0.127530 0.286787 -0.1787553 -0.0002633 0.000073 0.000058 0.000051 0.000039 0.0000112 0.0000073 0.000063 0.000051 2020 11 20 59173 0.126286 0.286684 -0.1784481 -0.0002468 0.000118 0.000063 0.000052 0.000040 0.0000112 0.0000073 0.000064 0.000053 2020 11 21 59174 0.125104 0.286777 -0.1781848 -0.0001944 0.000137 0.000062 0.000053 0.000041 0.0000112 0.0000074 0.000064 0.000053 2020 11 22 59175 0.124481 0.286278 -0.1780687 -0.0000424 0.000147 0.000060 0.000054 0.000043 0.0000112 0.0000074 0.000065 0.000054 2020 11 23 59176 0.124228 0.286214 -0.1781330 0.0001506 0.000157 0.000058 0.000055 0.000044 0.0000113 0.0000075 0.000066 0.000055 2020 11 24 59177 0.123617 0.286438 -0.1783447 0.0002542 0.000167 0.000055 0.000057 0.000046 0.0000113 0.0000075 0.000066 0.000055 2020 11 25 59178 0.122556 0.286916 -0.1786339 0.0002858 0.000177 0.000053 0.000058 0.000048 0.0000113 0.0000076 0.000067 0.000056 2020 11 26 59179 0.120973 0.287505 -0.1789614 0.0002630 0.000156 0.000114 0.000060 0.000050 0.0000114 0.0000077 0.000068 0.000058 2020 11 27 59180 0.118868 0.287888 -0.1791698 0.0001765 0.000126 0.000192 0.000061 0.000052 0.0000114 0.0000077 0.000069 0.000061 2020 11 28 59181 0.116181 0.288266 -0.1793065 0.0000654 0.000098 0.000193 0.000063 0.000053 0.0000114 0.0000078 0.000070 0.000064 2020 11 29 59182 0.113478 0.288418 -0.1792998 -0.0000570 0.000071 0.000165 0.000064 0.000055 0.0000115 0.0000078 0.000071 0.000067 2020 11 30 59183 0.110735 0.288608 -0.1792037 -0.0001561 0.000045 0.000137 0.000065 0.000057 0.0000115 0.0000079 0.000072 0.000070 2020 12 1 59184 0.108321 0.288148 -0.1790069 -0.0002546 0.000018 0.000108 0.000066 0.000059 0.0000116 0.0000080 0.000073 0.000073 2020 12 2 59185 0.106317 0.287572 -0.1787175 -0.0003630 0.000023 0.000041 0.000067 0.000061 0.0000117 0.0000080 0.000074 0.000076 2020 12 3 59186 0.104638 0.287348 -0.1783211 -0.0004220 0.000037 -0.000038 0.000067 0.000062 0.0000117 0.0000081 0.000075 0.000080 2020 12 4 59187 0.102958 0.287742 -0.1779212 -0.0003645 0.000051 -0.000116 0.000068 0.000064 0.0000117 0.0000081 0.000076 0.000084 2020 12 5 59188 0.101346 0.288801 -0.1776326 -0.0001936 0.000055 -0.000130 0.000068 0.000066 0.0000117 0.0000082 0.000077 0.000087 2020 12 6 59189 0.099422 0.289616 -0.1775418 -0.0000216 0.000056 -0.000121 0.000069 0.000067 0.0000117 0.0000082 0.000078 0.000090 2020 12 7 59190 0.097392 0.289604 -0.1776428 0.0002074 0.000056 -0.000112 0.000069 0.000069 0.0000118 0.0000083 0.000079 0.000093 2020 12 8 59191 0.095366 0.289667 -0.1779633 0.0004263 0.000056 -0.000103 0.000069 0.000070 0.0000119 0.0000083 0.000080 0.000097 2020 12 9 59192 0.093289 0.289586 -0.1785100 0.0005628 0.000086 -0.000091 0.000070 0.000071 0.0000120 0.0000083 0.000081 0.000099 2020 12 10 59193 0.091596 0.289267 -0.1791348 0.0006352 0.000123 -0.000078 0.000070 0.000071 0.0000120 0.0000084 0.000082 0.000101 2020 12 11 59194 0.090377 0.289317 -0.1797372 0.0005418 0.000160 -0.000065 0.000071 0.000072 0.0000120 0.0000077 0.000083 0.000104 2020 12 12 59195 0.089352 0.289933 -0.1801889 0.0003407 0.000137 -0.000041 0.000042 0.000032 0.0000121 0.0000073 0.000082 0.000105 2020 12 13 59196 0.088122 0.291099 -0.1803980 0.0000936 0.000092 -0.000014 0.000042 0.000032 0.0000121 0.0000068 0.000069 0.000093 2020 12 14 59197 0.086753 0.292095 -0.1803677 -0.0001487 0.000047 0.000013 0.000042 0.000032 0.0000121 0.0000073 0.000071 0.000095 2020 12 15 59198 0.085413 0.292842 -0.1801153 -0.0003569 0.000002 0.000041 0.000042 0.000032 0.0000122 0.0000073 0.000072 0.000097 2020 12 16 59199 0.084102 0.293335 -0.1797032 -0.0004950 -0.000003 0.000002 0.000042 0.000032 0.0000122 0.0000074 0.000073 0.000100 2020 12 17 59200 0.082931 0.293953 -0.1792128 -0.0004784 0.000002 -0.000053 0.000042 0.000032 0.0000123 0.0000068 0.000074 0.000105 2020 12 18 59201 0.082113 0.294634 -0.1787692 -0.0003551 0.000007 -0.000109 0.000042 0.000032 0.0000122 0.0000073 0.000076 0.000110 2020 12 19 59202 0.081252 0.294893 -0.1784509 -0.0002153 0.000055 -0.000102 0.000042 0.000032 0.0000122 0.0000073 0.000076 0.000113 2020 12 20 59203 0.080081 0.295269 -0.1783092 -0.0000815 0.000117 -0.000072 0.000042 0.000032 0.0000122 0.0000073 0.000077 0.000117 2020 12 21 59204 0.078855 0.295467 -0.1782871 0.0000540 0.000179 -0.000042 0.000042 0.000032 0.0000123 0.0000073 0.000078 0.000120 2020 12 22 59205 0.077844 0.295794 -0.1783855 0.0001406 0.000242 -0.000012 0.000043 0.000032 0.0000124 0.0000073 0.000073 0.000124 2020 12 23 59206 0.077211 0.296035 -0.1785628 0.0001221 0.000137 0.000157 0.000043 0.000032 0.0000114 0.0000069 0.000074 0.000127 2020 12 24 59207 0.077016 0.296473 -0.1786707 0.0000410 0.000076 0.000222 0.000043 0.000032 0.0000113 0.0000068 0.000074 0.000127 2020 12 25 59208 0.076715 0.297267 -0.1786670 -0.0000506 0.000046 0.000236 0.000044 0.000032 0.0000112 0.0000073 0.000077 0.000127 2020 12 26 59209 0.076045 0.297941 -0.1785195 -0.0002103 0.000016 0.000244 0.000044 0.000033 0.0000113 0.0000073 0.000078 0.000164 2020 12 27 59210 0.075038 0.298659 -0.1782183 -0.0003764 -0.000014 0.000256 0.000045 0.000033 0.0000110 0.0000070 0.000079 0.000170 2020 12 28 59211 0.074030 0.299926 -0.1777849 -0.0004947 -0.000043 0.000267 0.000078 0.000077 0.0000110 0.0000087 0.000080 0.000178 2020 12 29 59212 0.072622 0.301626 -0.1772430 -0.0005595 -0.000073 0.000279 0.000077 0.000077 0.0000110 0.0000087 0.000081 0.000185 2020 12 30 59213 0.071147 0.302690 -0.1766472 -0.0006211 -0.000035 0.000180 0.000077 0.000076 0.0000109 0.0000087 0.000080 0.000173 2020 12 31 59214 0.069721 0.303116 -0.1760010 -0.0006564 0.000003 0.000133 0.000076 0.000075 0.0000108 0.0000086 0.000080 0.000171 2021 1 1 59215 0.068685 0.304111 -0.1753710 -0.0005759 0.000035 0.000126 0.000075 0.000074 0.0000107 0.0000078 0.000079 0.000109 2021 1 2 59216 0.067783 0.305455 -0.1748394 -0.0004419 0.000066 0.000106 0.000074 0.000073 0.0000105 0.0000077 0.000081 0.000164 2021 1 3 59217 0.066068 0.306714 -0.1744761 -0.0002389 0.000098 0.000096 0.000074 0.000072 0.0000104 0.0000077 0.000081 0.000099 2021 1 4 59218 0.063906 0.307809 -0.1743246 -0.0000472 0.000129 0.000081 0.000074 0.000071 0.0000103 0.0000076 0.000082 0.000095 2021 1 5 59219 0.061685 0.308623 -0.1743819 0.0001362 0.000161 0.000066 0.000073 0.000069 0.0000102 0.0000076 0.000082 0.000091 2021 1 6 59220 0.060391 0.309503 -0.1746023 0.0002499 0.000217 0.000116 0.000072 0.000067 0.0000101 0.0000076 0.000083 0.000087 2021 1 7 59221 0.059466 0.310304 -0.1748751 0.0002552 0.000280 0.000183 0.000071 0.000066 0.0000100 0.0000075 0.000083 0.000083 2021 1 8 59222 0.059005 0.311054 -0.1750757 0.0001439 0.000343 0.000250 0.000070 0.000065 0.0000099 0.0000075 0.000083 0.000079 2021 1 9 59223 0.058270 0.311975 -0.1750823 -0.0000968 0.000324 0.000250 0.000069 0.000063 0.0000097 0.0000074 0.000080 0.000075 2021 1 10 59224 0.058057 0.313002 -0.1748654 -0.0003119 0.000274 0.000224 0.000068 0.000062 0.0000096 0.0000074 0.000092 0.000067 2021 1 11 59225 0.057636 0.314178 -0.1744765 -0.0004727 0.000223 0.000197 0.000067 0.000060 0.0000094 0.0000073 0.000094 0.000064 2021 1 12 59226 0.057033 0.314438 -0.1739724 -0.0005349 0.000172 0.000171 0.000065 0.000059 0.0000093 0.0000073 0.000093 0.000061 2021 1 13 59227 0.056028 0.315487 -0.1734272 -0.0005343 0.000217 0.000094 0.000028 0.000024 0.0000099 0.0000072 0.000093 0.000062 2021 1 14 59228 0.054873 0.316051 -0.1729081 -0.0004820 0.000286 0.000003 0.000025 0.000020 0.0000102 0.0000064 0.000094 0.000064 2021 1 15 59229 0.054335 0.316875 -0.1724606 -0.0004365 0.000356 -0.000087 0.000024 0.000020 0.0000114 0.0000064 0.000096 0.000066 2021 1 16 59230 0.053758 0.317833 -0.1721004 -0.0003468 0.000345 -0.000055 0.000024 0.000021 0.0000116 0.0000065 0.000094 0.000068 2021 1 17 59231 0.052962 0.318726 -0.1718081 -0.0002251 0.000302 0.000023 0.000024 0.000021 0.0000119 0.0000065 0.000100 0.000070 2021 1 18 59232 0.052474 0.319502 -0.1715790 -0.0001821 0.000261 0.000101 0.000024 0.000021 0.0000122 0.0000065 0.000098 0.000073 2021 1 19 59233 0.052506 0.319950 -0.1714126 -0.0001740 0.000219 0.000179 0.000024 0.000021 0.0000122 0.0000066 0.000099 0.000075 2021 1 20 59234 0.052837 0.320909 -0.1712427 -0.0001911 0.000232 0.000156 0.000023 0.000021 0.0000124 0.0000066 0.000094 0.000077 2021 1 21 59235 0.052498 0.321943 -0.1710484 -0.0002353 0.000259 0.000108 0.000024 0.000023 0.0000129 0.0000069 0.000095 0.000079 2021 1 22 59236 0.052370 0.323115 -0.1707975 -0.0002896 0.000287 0.000060 0.000024 0.000023 0.0000122 0.0000069 0.000096 0.000081 2021 1 23 59237 0.052397 0.324238 -0.1704758 -0.0004014 0.000284 0.000056 0.000024 0.000023 0.0000122 0.0000070 0.000096 0.000082 2021 1 24 59238 0.051888 0.325635 -0.1700327 -0.0005333 0.000269 0.000069 0.000025 0.000023 0.0000123 0.0000070 0.000097 0.000082 2021 1 25 59239 0.050946 0.327158 -0.1694247 -0.0006595 0.000255 0.000083 0.000025 0.000024 0.0000126 0.0000071 0.000097 0.000083 2021 1 26 59240 0.050305 0.328651 -0.1687165 -0.0007026 0.000241 0.000096 0.000025 0.000024 0.0000124 0.0000071 0.000098 0.000083 2021 1 27 59241 0.050009 0.330496 -0.1680026 -0.0006860 0.000276 0.000078 0.000025 0.000024 0.0000124 0.0000072 0.000098 0.000084 2021 1 28 59242 0.049854 0.332424 -0.1673675 -0.0005433 0.000324 0.000051 0.000025 0.000023 0.0000124 0.0000071 0.000099 0.000084 2021 1 29 59243 0.049925 0.334359 -0.1669073 -0.0003382 0.000372 0.000024 0.000026 0.000023 0.0000123 0.0000071 0.000087 0.000078 2021 1 30 59244 0.049593 0.336126 -0.1666565 -0.0001087 0.000334 0.000020 0.000026 0.000023 0.0000119 0.0000072 0.000087 0.000076 2021 1 31 59245 0.049315 0.337874 -0.1666887 0.0001728 0.000261 0.000024 0.000026 0.000023 0.0000119 0.0000072 0.000084 0.000075 2021 2 1 59246 0.049420 0.339866 -0.1670204 0.0004253 0.000188 0.000028 0.000026 0.000022 0.0000114 0.0000072 0.000083 0.000074 2021 2 2 59247 0.049490 0.341692 -0.1675614 0.0006019 0.000115 0.000032 0.000027 0.000022 0.0000125 0.0000073 0.000083 0.000073 2021 2 3 59248 0.049274 0.343178 -0.1681920 0.0006439 0.000107 0.000061 0.000027 0.000022 0.0000128 0.0000073 0.000084 0.000075 2021 2 4 59249 0.049231 0.344351 -0.1688000 0.0005490 0.000117 0.000097 0.000027 0.000022 0.0000128 0.0000073 0.000085 0.000078 2021 2 5 59250 0.049262 0.345628 -0.1692802 0.0003550 0.000126 0.000132 0.000027 0.000022 0.0000129 0.0000073 0.000086 0.000081 2021 2 6 59251 0.049156 0.346983 -0.1696139 0.0001374 0.000140 0.000158 0.000027 0.000022 0.0000129 0.0000073 0.000087 0.000084 2021 2 7 59252 0.049075 0.348358 -0.1696850 -0.0000406 0.000156 0.000180 0.000027 0.000021 0.0000131 0.0000074 0.000091 0.000086 2021 2 8 59253 0.049311 0.349885 -0.1694924 -0.0001406 0.000172 0.000202 0.000027 0.000021 0.0000126 0.0000072 0.000092 0.000088 2021 2 9 59254 0.049922 0.351343 -0.1693373 -0.0001271 0.000188 0.000224 0.000027 0.000021 0.0000127 0.0000072 0.000091 0.000090 2021 2 10 59255 0.050607 0.352626 -0.1692436 -0.0000444 0.000222 0.000170 0.000026 0.000021 0.0000126 0.0000073 0.000092 0.000092 2021 2 11 59256 0.051207 0.353801 -0.1692657 0.0000908 0.000261 0.000095 0.000026 0.000021 0.0000131 0.0000073 0.000094 0.000093 2021 2 12 59257 0.051383 0.354941 -0.1694090 0.0002396 0.000301 0.000020 0.000026 0.000021 0.0000130 0.0000073 0.000095 0.000095 2021 2 13 59258 0.051474 0.355706 -0.1697045 0.0004123 0.000308 0.000024 0.000026 0.000021 0.0000129 0.0000074 0.000096 0.000096 2021 2 14 59259 0.051922 0.356756 -0.1701305 0.0005143 0.000302 0.000059 0.000025 0.000021 0.0000128 0.0000074 0.000095 0.000097 2021 2 15 59260 0.051716 0.358143 -0.1706473 0.0005197 0.000296 0.000095 0.000024 0.000021 0.0000131 0.0000073 0.000097 0.000099 2021 2 16 59261 0.050949 0.359283 -0.1711965 0.0004778 0.000290 0.000131 0.000024 0.000021 0.0000125 0.0000073 0.000094 0.000100 2021 2 17 59262 0.050326 0.360338 -0.1716669 0.0003633 0.000284 0.000166 0.000024 0.000021 0.0000124 0.0000074 0.000095 0.000101 2021 2 18 59263 0.050378 0.361154 -0.1719511 0.0001677 0.000247 0.000200 0.000024 0.000021 0.0000130 0.0000074 0.000096 0.000103 2021 2 19 59264 0.050885 0.361987 -0.1720228 -0.0000263 0.000202 0.000234 0.000024 0.000021 0.0000131 0.0000074 0.000098 0.000106 2021 2 20 59265 0.051501 0.363070 -0.1719007 -0.0002145 0.000198 0.000191 0.000023 0.000021 0.0000123 0.0000073 0.000100 0.000109 2021 2 21 59266 0.051463 0.363914 -0.1715820 -0.0004374 0.000209 0.000120 0.000023 0.000020 0.0000123 0.0000073 0.000104 0.000111 2021 2 22 59267 0.050700 0.364562 -0.1710795 -0.0005628 0.000219 0.000048 0.000022 0.000021 0.0000125 0.0000073 0.000105 0.000114 2021 2 23 59268 0.049836 0.365309 -0.1704677 -0.0006244 0.000230 -0.000023 0.000023 0.000021 0.0000125 0.0000073 0.000101 0.000117 2021 2 24 59269 0.049396 0.365588 -0.1698548 -0.0005855 0.000207 -0.000047 0.000023 0.000021 0.0000132 0.0000072 0.000102 0.000119 2021 2 25 59270 0.049801 0.366059 -0.1693475 -0.0003937 0.000174 -0.000058 0.000023 0.000020 0.0000130 0.0000072 0.000103 0.000121 2021 2 26 59271 0.050306 0.367069 -0.1690477 -0.0001387 0.000142 -0.000069 0.000023 0.000020 0.0000128 0.0000072 0.000104 0.000122 2021 2 27 59272 0.050431 0.368528 -0.1690351 0.0001377 0.000151 -0.000054 0.000023 0.000020 0.0000129 0.0000072 0.000105 0.000123 2021 2 28 59273 0.050498 0.370227 -0.1693081 0.0003809 0.000176 -0.000029 0.000024 0.000020 0.0000129 0.0000065 0.000104 0.000130 2021 3 1 59274 0.050616 0.371982 -0.1697877 0.0005501 0.000201 -0.000004 0.000024 0.000020 0.0000126 0.0000072 0.000105 0.000129 2021 3 2 59275 0.050706 0.373771 -0.1703934 0.0006476 0.000226 0.000022 0.000024 0.000020 0.0000127 0.0000072 0.000105 0.000129 2021 3 3 59276 0.050584 0.375262 -0.1710261 0.0006133 0.000212 0.000040 0.000024 0.000020 0.0000127 0.0000072 0.000106 0.000129 2021 3 4 59277 0.051059 0.376549 -0.1715540 0.0004339 0.000188 0.000057 0.000024 0.000020 0.0000134 0.0000072 0.000106 0.000130 2021 3 5 59278 0.052201 0.377870 -0.1718838 0.0001699 0.000164 0.000073 0.000024 0.000020 0.0000129 0.0000072 0.000107 0.000130 2021 3 6 59279 0.053360 0.379379 -0.1719881 -0.0000526 0.000164 0.000048 0.000024 0.000019 0.0000129 0.0000072 0.000110 0.000126 2021 3 7 59280 0.054561 0.380833 -0.1718731 -0.0001992 0.000173 0.000007 0.000024 0.000019 0.0000129 0.0000072 0.000104 0.000120 2021 3 8 59281 0.056191 0.382351 -0.1716080 -0.0002890 0.000183 -0.000033 0.000024 0.000019 0.0000128 0.0000072 0.000104 0.000117 2021 3 9 59282 0.057662 0.383909 -0.1713243 -0.0002599 0.000192 -0.000074 0.000024 0.000019 0.0000130 0.0000072 0.000101 0.000115 2021 3 10 59283 0.058750 0.385265 -0.1710993 -0.0001499 0.000200 -0.000097 0.000023 0.000018 0.0000140 0.0000070 0.000101 0.000112 2021 3 11 59284 0.059621 0.386346 -0.1710012 -0.0000302 0.000207 -0.000115 0.000023 0.000018 0.0000141 0.0000070 0.000101 0.000109 2021 3 12 59285 0.060542 0.387744 -0.1710599 0.0001393 0.000214 -0.000132 0.000023 0.000018 0.0000134 0.0000070 0.000100 0.000106 2021 3 13 59286 0.061723 0.389349 -0.1712387 0.0002694 0.000230 -0.000102 0.000022 0.000018 0.0000135 0.0000070 0.000100 0.000103 2021 3 14 59287 0.063046 0.391028 -0.1715574 0.0003398 0.000248 -0.000055 0.000022 0.000018 0.0000136 0.0000069 0.000067 0.000092 2021 3 15 59288 0.064331 0.392504 -0.1719515 0.0003290 0.000267 -0.000007 0.000022 0.000018 0.0000135 0.0000069 0.000067 0.000089 2021 3 16 59289 0.065375 0.394218 -0.1722335 0.0002248 0.000286 0.000040 0.000022 0.000018 0.0000134 0.0000069 0.000066 0.000086 2021 3 17 59290 0.065657 0.395943 -0.1724026 0.0000715 0.000272 0.000050 0.000021 0.000017 0.0000131 0.0000068 0.000065 0.000087 2021 3 18 59291 0.065853 0.397460 -0.1724204 -0.0000538 0.000249 0.000049 0.000021 0.000017 0.0000125 0.0000068 0.000065 0.000084 2021 3 19 59292 0.066235 0.398938 -0.1722871 -0.0001722 0.000226 0.000048 0.000021 0.000017 0.0000120 0.0000067 0.000064 0.000081 2021 3 20 59293 0.066580 0.400421 -0.1720284 -0.0003318 0.000219 0.000055 0.000021 0.000017 0.0000118 0.0000067 0.000061 0.000078 2021 3 21 59294 0.067507 0.401767 -0.1716900 -0.0003582 0.000218 0.000065 0.000021 0.000017 0.0000151 0.0000067 0.000061 0.000075 2021 3 22 59295 0.068766 0.403525 -0.1713132 -0.0003644 0.000218 0.000075 0.000021 0.000017 0.0000161 0.0000067 0.000060 0.000072 2021 3 23 59296 0.070017 0.405095 -0.1709575 -0.0003337 0.000217 0.000085 0.000021 0.000016 0.0000159 0.0000067 0.000059 0.000069 2021 3 24 59297 0.071509 0.406504 -0.1706787 -0.0002430 0.000216 0.000095 0.000022 0.000016 0.0000155 0.0000067 0.000059 0.000067 2021 3 25 59298 0.072812 0.407873 -0.1705313 -0.0000510 0.000225 0.000066 0.000022 0.000016 0.0000153 0.0000067 0.000058 0.000066 2021 3 26 59299 0.073728 0.409056 -0.1705938 0.0002010 0.000236 0.000026 0.000022 0.000016 0.0000138 0.0000067 0.000058 0.000065 2021 3 27 59300 0.074948 0.409668 -0.1709185 0.0004661 0.000252 0.000016 0.000023 0.000016 0.0000139 0.0000067 0.000057 0.000065 2021 3 28 59301 0.076573 0.409823 -0.1714942 0.0006701 0.000270 0.000018 0.000023 0.000016 0.0000142 0.0000067 0.000057 0.000065 2021 3 29 59302 0.078236 0.410129 -0.1722454 0.0007908 0.000287 0.000019 0.000024 0.000016 0.0000144 0.0000067 0.000057 0.000066 2021 3 30 59303 0.079581 0.410456 -0.1730409 0.0007669 0.000305 0.000020 0.000024 0.000016 0.0000145 0.0000067 0.000055 0.000066 2021 3 31 59304 0.080692 0.411065 -0.1737315 0.0005975 0.000345 -0.000003 0.000024 0.000016 0.0000145 0.0000068 0.000054 0.000065 2021 4 1 59305 0.081597 0.411745 -0.1742201 0.0003752 0.000392 -0.000034 0.000024 0.000016 0.0000147 0.0000067 0.000054 0.000064 2021 4 2 59306 0.082266 0.412527 -0.1744884 0.0001577 0.000373 -0.000016 0.000024 0.000016 0.0000147 0.0000067 0.000054 0.000062 2021 4 3 59307 0.082863 0.413394 -0.1745594 -0.0000218 0.000331 0.000018 0.000025 0.000017 0.0000149 0.0000067 0.000050 0.000060 2021 4 4 59308 0.083694 0.413955 -0.1744710 -0.0001093 0.000288 0.000052 0.000025 0.000017 0.0000131 0.0000067 0.000050 0.000058 2021 4 5 59309 0.084866 0.414476 -0.1744009 -0.0000380 0.000246 0.000086 0.000025 0.000017 0.0000131 0.0000067 0.000048 0.000056 2021 4 6 59310 0.085863 0.415604 -0.1744328 0.0000917 0.000204 0.000120 0.000026 0.000017 0.0000138 0.0000067 0.000048 0.000055 2021 4 7 59311 0.086636 0.416842 -0.1745974 0.0002245 0.000162 0.000154 0.000026 0.000017 0.0000128 0.0000067 0.000048 0.000053 2021 4 8 59312 0.087374 0.417758 -0.1748862 0.0003464 0.000190 0.000100 0.000026 0.000017 0.0000128 0.0000066 0.000047 0.000051 2021 4 9 59313 0.087621 0.418801 -0.1752874 0.0004559 0.000238 0.000022 0.000026 0.000017 0.0000120 0.0000066 0.000047 0.000049 2021 4 10 59314 0.087511 0.419908 -0.1757729 0.0005100 0.000264 0.000007 0.000027 0.000017 0.0000121 0.0000066 0.000047 0.000047 2021 4 11 59315 0.087081 0.420785 -0.1762939 0.0005274 0.000281 0.000015 0.000027 0.000017 0.0000121 0.0000066 0.000045 0.000045 2021 4 12 59316 0.086768 0.421358 -0.1767986 0.0004752 0.000299 0.000023 0.000027 0.000017 0.0000119 0.0000066 0.000044 0.000043 2021 4 13 59317 0.086839 0.421892 -0.1772455 0.0004063 0.000316 0.000031 0.000028 0.000017 0.0000124 0.0000067 0.000043 0.000041 2021 4 14 59318 0.087692 0.422398 -0.1776055 0.0002914 0.000299 0.000020 0.000027 0.000017 0.0000128 0.0000067 0.000042 0.000039 2021 4 15 59319 0.088768 0.423267 -0.1778557 0.0001882 0.000272 0.000005 0.000027 0.000017 0.0000127 0.0000067 0.000042 0.000037 2021 4 16 59320 0.089996 0.423845 -0.1779907 0.0000721 0.000246 -0.000009 0.000027 0.000017 0.0000125 0.0000067 0.000036 0.000035 2021 4 17 59321 0.092158 0.424284 -0.1780250 -0.0000067 0.000213 -0.000020 0.000027 0.000017 0.0000125 0.0000068 0.000036 0.000033 2021 4 18 59322 0.094246 0.425257 -0.1779868 -0.0000674 0.000179 -0.000029 0.000027 0.000017 0.0000123 0.0000068 0.000036 0.000023 2021 4 19 59323 0.095947 0.426181 -0.1779103 -0.0000733 0.000144 -0.000039 0.000027 0.000017 0.0000123 0.0000068 0.000035 0.000022 2021 4 20 59324 0.097266 0.427588 -0.1778571 -0.0000075 0.000110 -0.000048 0.000027 0.000017 0.0000117 0.0000065 0.000034 0.000021 2021 4 21 59325 0.098245 0.428908 -0.1779160 0.0001384 0.000136 -0.000061 0.000027 0.000017 0.0000116 0.0000067 0.000034 0.000020 2021 4 22 59326 0.099005 0.430149 -0.1781298 0.0003258 0.000179 -0.000074 0.000027 0.000017 0.0000110 0.0000067 0.000034 0.000019 2021 4 23 59327 0.099573 0.431096 -0.1785406 0.0005455 0.000222 -0.000087 0.000026 0.000017 0.0000110 0.0000066 0.000033 0.000018 2021 4 24 59328 0.099809 0.432023 -0.1791390 0.0007338 0.000228 -0.000120 0.000026 0.000017 0.0000112 0.0000067 0.000032 0.000018 2021 4 25 59329 0.100034 0.432771 -0.1799364 0.0009053 0.000222 -0.000173 0.000026 0.000017 0.0000113 0.0000067 0.000035 0.000025 2021 4 26 59330 0.100355 0.433380 -0.1809123 0.0009884 0.000216 -0.000221 0.000026 0.000017 0.0000114 0.0000067 0.000035 0.000027 2021 4 27 59331 0.101324 0.433851 -0.1819026 0.0008952 0.000210 -0.000268 0.000026 0.000017 0.0000117 0.0000067 0.000036 0.000028 2021 4 28 59332 0.102654 0.434414 -0.1826964 0.0006420 0.000244 -0.000185 0.000026 0.000017 0.0000117 0.0000067 0.000036 0.000029 2021 4 29 59333 0.104008 0.434868 -0.1831982 0.0003262 0.000288 -0.000071 0.000026 0.000016 0.0000117 0.0000066 0.000036 0.000030 2021 4 30 59334 0.105404 0.435218 -0.1833833 0.0000436 0.000332 0.000043 0.000026 0.000016 0.0000116 0.0000066 0.000036 0.000031 2021 5 1 59335 0.106820 0.435779 -0.1833089 -0.0001567 0.000316 0.000058 0.000026 0.000016 0.0000117 0.0000066 0.000036 0.000031 2021 5 2 59336 0.108188 0.436419 -0.1830909 -0.0002640 0.000276 0.000037 0.000026 0.000017 0.0000118 0.0000066 0.000036 0.000032 2021 5 3 59337 0.109767 0.437441 -0.1827909 -0.0002949 0.000237 0.000016 0.000026 0.000017 0.0000118 0.0000066 0.000037 0.000033 2021 5 4 59338 0.111592 0.438462 -0.1825243 -0.0002191 0.000197 -0.000006 0.000026 0.000017 0.0000113 0.0000066 0.000037 0.000033 2021 5 5 59339 0.113313 0.439364 -0.1823978 -0.0000554 0.000182 -0.000033 0.000025 0.000017 0.0000112 0.0000066 0.000037 0.000034 2021 5 6 59340 0.115279 0.440309 -0.1824200 0.0000973 0.000173 -0.000063 0.000025 0.000017 0.0000109 0.0000065 0.000038 0.000035 2021 5 7 59341 0.117172 0.441478 -0.1825670 0.0002145 0.000164 -0.000092 0.000025 0.000017 0.0000103 0.0000065 0.000038 0.000036 2021 5 8 59342 0.118681 0.442646 -0.1827886 0.0002700 0.000166 -0.000099 0.000025 0.000017 0.0000104 0.0000065 0.000039 0.000036 2021 5 9 59343 0.120432 0.443435 -0.1830318 0.0002301 0.000172 -0.000097 0.000025 0.000018 0.0000105 0.0000065 0.000043 0.000036 2021 5 10 59344 0.122013 0.444253 -0.1832398 0.0001781 0.000178 -0.000096 0.000025 0.000018 0.0000112 0.0000065 0.000038 0.000039 2021 5 11 59345 0.123229 0.444950 -0.1833696 0.0000832 0.000184 -0.000094 0.000025 0.000018 0.0000111 0.0000065 0.000038 0.000039 2021 5 12 59346 0.124570 0.445119 -0.1834050 -0.0000417 0.000197 -0.000091 0.000025 0.000018 0.0000107 0.0000065 0.000038 0.000038 2021 5 13 59347 0.126398 0.444900 -0.1833166 -0.0001604 0.000212 -0.000088 0.000025 0.000018 0.0000104 0.0000064 0.000038 0.000037 2021 5 14 59348 0.128393 0.445000 -0.1831001 -0.0002467 0.000228 -0.000084 0.000025 0.000018 0.0000104 0.0000065 0.000039 0.000037 2021 5 15 59349 0.130276 0.445421 -0.1828031 -0.0003065 0.000226 -0.000081 0.000025 0.000019 0.0000105 0.0000065 0.000039 0.000036 2021 5 16 59350 0.132466 0.445767 -0.1824802 -0.0003050 0.000219 -0.000079 0.000025 0.000019 0.0000106 0.0000065 0.000038 0.000034 2021 5 17 59351 0.134899 0.446354 -0.1822601 -0.0002399 0.000212 -0.000076 0.000024 0.000018 0.0000111 0.0000065 0.000038 0.000033 2021 5 18 59352 0.137096 0.446653 -0.1820734 -0.0001333 0.000204 -0.000073 0.000024 0.000018 0.0000111 0.0000065 0.000038 0.000033 2021 5 19 59353 0.139382 0.446488 -0.1819842 0.0000440 0.000197 -0.000071 0.000024 0.000018 0.0000112 0.0000066 0.000038 0.000032 2021 5 20 59354 0.142062 0.446194 -0.1821300 0.0002771 0.000227 -0.000129 0.000024 0.000018 0.0000111 0.0000066 0.000038 0.000031 2021 5 21 59355 0.144518 0.446092 -0.1825058 0.0004653 0.000267 -0.000204 0.000024 0.000018 0.0000113 0.0000066 0.000038 0.000029 2021 5 22 59356 0.146638 0.446087 -0.1830591 0.0006161 0.000254 -0.000207 0.000023 0.000018 0.0000116 0.0000066 0.000037 0.000028 2021 5 23 59357 0.148357 0.446319 -0.1837359 0.0007012 0.000222 -0.000183 0.000023 0.000018 0.0000120 0.0000066 0.000037 0.000026 2021 5 24 59358 0.150055 0.446007 -0.1844377 0.0006778 0.000190 -0.000159 0.000023 0.000018 0.0000128 0.0000065 0.000037 0.000025 2021 5 25 59359 0.151671 0.445578 -0.1850358 0.0005120 0.000157 -0.000135 0.000022 0.000017 0.0000131 0.0000065 0.000037 0.000024 2021 5 26 59360 0.153177 0.445002 -0.1854186 0.0002683 0.000125 -0.000111 0.000022 0.000017 0.0000135 0.0000066 0.000037 0.000023 2021 5 27 59361 0.154610 0.444641 -0.1855433 -0.0000135 0.000155 -0.000132 0.000022 0.000017 0.0000140 0.0000065 0.000037 0.000024 2021 5 28 59362 0.156083 0.444149 -0.1854061 -0.0002723 0.000203 -0.000165 0.000022 0.000017 0.0000135 0.0000065 0.000037 0.000026 2021 5 29 59363 0.157787 0.443296 -0.1850586 -0.0004259 0.000216 -0.000173 0.000023 0.000017 0.0000138 0.0000065 0.000038 0.000027 2021 5 30 59364 0.159496 0.443194 -0.1846181 -0.0004360 0.000215 -0.000173 0.000023 0.000017 0.0000142 0.0000065 0.000038 0.000028 2021 5 31 59365 0.160764 0.443056 -0.1841962 -0.0003658 0.000215 -0.000172 0.000023 0.000018 0.0000145 0.0000065 0.000039 0.000030 2021 6 1 59366 0.162221 0.442541 -0.1838763 -0.0002431 0.000215 -0.000172 0.000023 0.000018 0.0000140 0.0000065 0.000040 0.000032 2021 6 2 59367 0.163505 0.442197 -0.1837088 -0.0001118 0.000238 -0.000157 0.000023 0.000018 0.0000136 0.0000066 0.000041 0.000034 2021 6 3 59368 0.164269 0.441835 -0.1836734 0.0000119 0.000267 -0.000139 0.000023 0.000018 0.0000136 0.0000065 0.000041 0.000036 2021 6 4 59369 0.165264 0.441101 -0.1837182 0.0000536 0.000296 -0.000120 0.000023 0.000018 0.0000137 0.0000065 0.000042 0.000038 2021 6 5 59370 0.166494 0.439959 -0.1837435 -0.0000156 0.000285 -0.000120 0.000024 0.000018 0.0000139 0.0000065 0.000043 0.000039 2021 6 6 59371 0.167443 0.438760 -0.1837213 -0.0001340 0.000260 -0.000126 0.000024 0.000018 0.0000141 0.0000065 0.000042 0.000041 2021 6 7 59372 0.168452 0.437773 -0.1835146 -0.0002761 0.000235 -0.000131 0.000024 0.000018 0.0000151 0.0000065 0.000043 0.000043 2021 6 8 59373 0.169988 0.437038 -0.1831307 -0.0004348 0.000210 -0.000137 0.000024 0.000018 0.0000159 0.0000066 0.000042 0.000045 2021 6 9 59374 0.171662 0.436466 -0.1825961 -0.0006056 0.000198 -0.000126 0.000024 0.000019 0.0000160 0.0000066 0.000043 0.000046 2021 6 10 59375 0.173060 0.436107 -0.1819126 -0.0007632 0.000190 -0.000111 0.000024 0.000019 0.0000161 0.0000066 0.000043 0.000048 2021 6 11 59376 0.174245 0.435720 -0.1810931 -0.0008734 0.000205 -0.000105 0.000024 0.000019 0.0000153 0.0000066 0.000044 0.000049 2021 6 12 59377 0.175463 0.435402 -0.1802017 -0.0009192 0.000228 -0.000104 0.000024 0.000019 0.0000156 0.0000067 0.000044 0.000050 2021 6 13 59378 0.176463 0.435076 -0.1792824 -0.0009227 0.000251 -0.000102 0.000024 0.000019 0.0000157 0.0000067 0.000045 0.000052 2021 6 14 59379 0.177561 0.434800 -0.1783898 -0.0008460 0.000274 -0.000100 0.000024 0.000019 0.0000158 0.0000066 0.000047 0.000054 2021 6 15 59380 0.178436 0.434544 -0.1776041 -0.0007086 0.000297 -0.000098 0.000025 0.000019 0.0000158 0.0000066 0.000047 0.000056 2021 6 16 59381 0.179161 0.433958 -0.1769638 -0.0005221 0.000273 -0.000128 0.000025 0.000019 0.0000147 0.0000066 0.000048 0.000057 2021 6 17 59382 0.179975 0.433150 -0.1765219 -0.0003366 0.000235 -0.000167 0.000025 0.000019 0.0000141 0.0000065 0.000048 0.000057 2021 6 18 59383 0.181538 0.431985 -0.1762920 -0.0001418 0.000198 -0.000206 0.000025 0.000019 0.0000139 0.0000066 0.000049 0.000058 2021 6 19 59384 0.183459 0.431221 -0.1762499 -0.0000088 0.000195 -0.000200 0.000026 0.000019 0.0000139 0.0000066 0.000048 0.000059 2021 6 20 59385 0.185268 0.430690 -0.1762848 0.0000040 0.000204 -0.000177 0.000026 0.000019 0.0000139 0.0000066 0.000049 0.000059 2021 6 21 59386 0.187008 0.430371 -0.1762299 -0.0001366 0.000213 -0.000153 0.000026 0.000019 0.0000138 0.0000066 0.000050 0.000059 2021 6 22 59387 0.188612 0.429729 -0.1759694 -0.0003671 0.000223 -0.000130 0.000026 0.000019 0.0000121 0.0000067 0.000050 0.000059 2021 6 23 59388 0.190249 0.428692 -0.1754577 -0.0006531 0.000211 -0.000157 0.000026 0.000019 0.0000120 0.0000067 0.000051 0.000059 2021 6 24 59389 0.191984 0.427561 -0.1746551 -0.0009461 0.000193 -0.000198 0.000026 0.000019 0.0000118 0.0000066 0.000051 0.000058 2021 6 25 59390 0.193895 0.426260 -0.1736026 -0.0011467 0.000175 -0.000239 0.000026 0.000019 0.0000112 0.0000066 0.000050 0.000057 2021 6 26 59391 0.195529 0.424979 -0.1723902 -0.0012514 0.000169 -0.000232 0.000026 0.000019 0.0000110 0.0000067 0.000050 0.000056 2021 6 27 59392 0.197249 0.423941 -0.1711520 -0.0012122 0.000169 -0.000206 0.000026 0.000019 0.0000108 0.0000067 0.000050 0.000055 2021 6 28 59393 0.199016 0.423212 -0.1700013 -0.0010808 0.000168 -0.000180 0.000026 0.000019 0.0000103 0.0000067 0.000052 0.000053 2021 6 29 59394 0.201014 0.422014 -0.1689979 -0.0008954 0.000167 -0.000155 0.000026 0.000019 0.0000107 0.0000067 0.000052 0.000052 2021 6 30 59395 0.203151 0.420682 -0.1681557 -0.0007509 0.000175 -0.000142 0.000026 0.000019 0.0000104 0.0000068 0.000053 0.000053 2021 7 1 59396 0.205011 0.419357 -0.1674255 -0.0007061 0.000185 -0.000133 0.000026 0.000019 0.0000105 0.0000068 0.000054 0.000054 2021 7 2 59397 0.206921 0.418137 -0.1667352 -0.0007290 0.000195 -0.000125 0.000026 0.000019 0.0000107 0.0000068 0.000054 0.000054 2021 7 3 59398 0.209024 0.416956 -0.1660067 -0.0007956 0.000213 -0.000118 0.000027 0.000019 0.0000108 0.0000069 0.000053 0.000055 2021 7 4 59399 0.211331 0.415811 -0.1651797 -0.0008841 0.000234 -0.000112 0.000027 0.000020 0.0000110 0.0000069 0.000054 0.000056 2021 7 5 59400 0.213414 0.414996 -0.1642095 -0.0010197 0.000255 -0.000106 0.000027 0.000020 0.0000111 0.0000070 0.000055 0.000056 2021 7 6 59401 0.215650 0.414027 -0.1630892 -0.0011760 0.000276 -0.000100 0.000026 0.000019 0.0000111 0.0000068 0.000055 0.000057 2021 7 7 59402 0.218140 0.413172 -0.1618291 -0.0013002 0.000297 -0.000094 0.000026 0.000020 0.0000109 0.0000068 0.000056 0.000057 2021 7 8 59403 0.220214 0.412138 -0.1604574 -0.0014004 0.000276 -0.000077 0.000026 0.000019 0.0000104 0.0000068 0.000057 0.000058 2021 7 9 59404 0.221832 0.410821 -0.1590228 -0.0014520 0.000245 -0.000059 0.000026 0.000019 0.0000103 0.0000068 0.000058 0.000059 2021 7 10 59405 0.223600 0.409097 -0.1575892 -0.0014271 0.000240 -0.000056 0.000026 0.000020 0.0000103 0.0000068 0.000057 0.000059 2021 7 11 59406 0.225666 0.407615 -0.1562169 -0.0013154 0.000245 -0.000060 0.000026 0.000020 0.0000103 0.0000068 0.000058 0.000058 2021 7 12 59407 0.227521 0.406499 -0.1549674 -0.0011382 0.000250 -0.000064 0.000026 0.000020 0.0000101 0.0000069 0.000058 0.000058 2021 7 13 59408 0.229363 0.405735 -0.1538980 -0.0009647 0.000256 -0.000067 0.000026 0.000020 0.0000098 0.0000069 0.000057 0.000058 2021 7 14 59409 0.230852 0.405177 -0.1530567 -0.0007412 0.000239 -0.000073 0.000026 0.000020 0.0000099 0.0000069 0.000058 0.000059 2021 7 15 59410 0.232364 0.404183 -0.1524225 -0.0005190 0.000216 -0.000080 0.000026 0.000019 0.0000109 0.0000069 0.000059 0.000061 2021 7 16 59411 0.233932 0.403085 -0.1520045 -0.0003391 0.000193 -0.000086 0.000026 0.000019 0.0000107 0.0000069 0.000060 0.000063 2021 7 17 59412 0.235568 0.402256 -0.1517411 -0.0002516 0.000192 -0.000098 0.000026 0.000019 0.0000110 0.0000069 0.000061 0.000064 2021 7 18 59413 0.236938 0.401571 -0.1515176 -0.0002888 0.000197 -0.000111 0.000027 0.000019 0.0000112 0.0000070 0.000062 0.000065 2021 7 19 59414 0.238366 0.400312 -0.1511975 -0.0003898 0.000202 -0.000125 0.000027 0.000019 0.0000114 0.0000070 0.000062 0.000066 2021 7 20 59415 0.239941 0.398929 -0.1507114 -0.0005551 0.000207 -0.000138 0.000027 0.000019 0.0000109 0.0000070 0.000061 0.000066 2021 7 21 59416 0.241402 0.397614 -0.1500616 -0.0007199 0.000224 -0.000143 0.000027 0.000020 0.0000113 0.0000071 0.000062 0.000068 2021 7 22 59417 0.242550 0.396349 -0.1492653 -0.0008670 0.000244 -0.000145 0.000027 0.000019 0.0000117 0.0000070 0.000062 0.000069 2021 7 23 59418 0.243559 0.394850 -0.1483896 -0.0009224 0.000263 -0.000148 0.000027 0.000019 0.0000116 0.0000070 0.000063 0.000071 2021 7 24 59419 0.244504 0.393363 -0.1475216 -0.0008550 0.000241 -0.000137 0.000028 0.000020 0.0000117 0.0000070 0.000065 0.000073 2021 7 25 59420 0.244659 0.392108 -0.1467385 -0.0007245 0.000205 -0.000120 0.000028 0.000020 0.0000119 0.0000071 0.000066 0.000073 2021 7 26 59421 0.244282 0.390818 -0.1460743 -0.0006021 0.000168 -0.000104 0.000028 0.000020 0.0000114 0.0000071 0.000067 0.000074 2021 7 27 59422 0.244021 0.389282 -0.1455380 -0.0004795 0.000132 -0.000087 0.000028 0.000020 0.0000110 0.0000071 0.000068 0.000075 2021 7 28 59423 0.243957 0.387023 -0.1451164 -0.0004072 0.000131 -0.000079 0.000028 0.000020 0.0000114 0.0000071 0.000069 0.000076 2021 7 29 59424 0.244271 0.384533 -0.1447485 -0.0003704 0.000140 -0.000073 0.000027 0.000020 0.0000125 0.0000070 0.000070 0.000077 2021 7 30 59425 0.245054 0.382456 -0.1443684 -0.0004102 0.000149 -0.000067 0.000027 0.000020 0.0000126 0.0000070 0.000068 0.000077 2021 7 31 59426 0.246021 0.381094 -0.1439172 -0.0005170 0.000182 -0.000083 0.000027 0.000020 0.0000128 0.0000071 0.000068 0.000078 2021 8 1 59427 0.246780 0.380162 -0.1433541 -0.0006384 0.000223 -0.000105 0.000027 0.000020 0.0000130 0.0000071 0.000069 0.000078 2021 8 2 59428 0.247724 0.379020 -0.1426563 -0.0007555 0.000264 -0.000127 0.000027 0.000020 0.0000131 0.0000071 0.000070 0.000078 2021 8 3 59429 0.248665 0.377672 -0.1418281 -0.0008856 0.000305 -0.000149 0.000027 0.000020 0.0000125 0.0000071 0.000070 0.000078 2021 8 4 59430 0.249247 0.376225 -0.1408819 -0.0009926 0.000295 -0.000110 0.000027 0.000020 0.0000134 0.0000071 0.000071 0.000078 2021 8 5 59431 0.250318 0.374716 -0.1398588 -0.0010475 0.000272 -0.000054 0.000027 0.000020 0.0000130 0.0000070 0.000071 0.000078 2021 8 6 59432 0.251557 0.373439 -0.1388293 -0.0010580 0.000256 -0.000038 0.000027 0.000020 0.0000125 0.0000070 0.000074 0.000077 2021 8 7 59433 0.252384 0.372189 -0.1377997 -0.0010329 0.000244 -0.000034 0.000027 0.000020 0.0000125 0.0000071 0.000072 0.000076 2021 8 8 59434 0.252618 0.370959 -0.1367543 -0.0009699 0.000231 -0.000031 0.000027 0.000020 0.0000124 0.0000070 0.000072 0.000075 2021 8 9 59435 0.251958 0.369547 -0.1358220 -0.0008438 0.000219 -0.000028 0.000028 0.000020 0.0000129 0.0000070 0.000072 0.000074 2021 8 10 59436 0.250843 0.367504 -0.1350686 -0.0006799 0.000206 -0.000025 0.000028 0.000020 0.0000121 0.0000071 0.000072 0.000073 2021 8 11 59437 0.250176 0.365255 -0.1345085 -0.0004603 0.000194 -0.000022 0.000028 0.000020 0.0000115 0.0000071 0.000073 0.000072 2021 8 12 59438 0.249897 0.363348 -0.1341190 -0.0003252 0.000182 -0.000080 0.000028 0.000020 0.0000111 0.0000071 0.000073 0.000071 2021 8 13 59439 0.249586 0.361519 -0.1338317 -0.0003000 0.000169 -0.000157 0.000027 0.000019 0.0000108 0.0000070 0.000074 0.000071 2021 8 14 59440 0.249168 0.359749 -0.1335458 -0.0003549 0.000169 -0.000170 0.000027 0.000019 0.0000107 0.0000070 0.000071 0.000069 2021 8 15 59441 0.248726 0.358103 -0.1331531 -0.0004593 0.000172 -0.000160 0.000027 0.000019 0.0000105 0.0000071 0.000072 0.000067 2021 8 16 59442 0.248321 0.356538 -0.1325675 -0.0006686 0.000176 -0.000150 0.000026 0.000019 0.0000105 0.0000071 0.000072 0.000065 2021 8 17 59443 0.248130 0.354895 -0.1317488 -0.0009228 0.000179 -0.000140 0.000026 0.000019 0.0000103 0.0000071 0.000073 0.000063 2021 8 18 59444 0.248008 0.353279 -0.1307185 -0.0010982 0.000183 -0.000131 0.000026 0.000019 0.0000102 0.0000071 0.000073 0.000062 2021 8 19 59445 0.247978 0.351653 -0.1295488 -0.0011741 0.000203 -0.000126 0.000026 0.000018 0.0000100 0.0000071 0.000074 0.000063 2021 8 20 59446 0.247731 0.350108 -0.1283563 -0.0011739 0.000229 -0.000124 0.000026 0.000018 0.0000098 0.0000072 0.000070 0.000064 2021 8 21 59447 0.247290 0.348276 -0.1272649 -0.0010243 0.000268 -0.000114 0.000025 0.000018 0.0000099 0.0000072 0.000070 0.000065 2021 8 22 59448 0.246822 0.346558 -0.1263384 -0.0008459 0.000313 -0.000103 0.000025 0.000018 0.0000099 0.0000072 0.000070 0.000066 2021 8 23 59449 0.246343 0.344554 -0.1255763 -0.0006538 0.000357 -0.000091 0.000025 0.000018 0.0000095 0.0000071 0.000064 0.000065 2021 8 24 59450 0.245986 0.342232 -0.1249636 -0.0005235 0.000401 -0.000080 0.000024 0.000018 0.0000102 0.0000071 0.000064 0.000066 2021 8 25 59451 0.246006 0.340077 -0.1244735 -0.0004466 0.000360 -0.000093 0.000024 0.000018 0.0000108 0.0000071 0.000064 0.000067 2021 8 26 59452 0.246029 0.338309 -0.1240162 -0.0004798 0.000296 -0.000112 0.000024 0.000017 0.0000110 0.0000070 0.000065 0.000067 2021 8 27 59453 0.246039 0.336463 -0.1235117 -0.0005674 0.000233 -0.000131 0.000024 0.000017 0.0000108 0.0000070 0.000056 0.000066 2021 8 28 59454 0.246083 0.334712 -0.1228899 -0.0006892 0.000223 -0.000091 0.000024 0.000017 0.0000110 0.0000070 0.000056 0.000065 2021 8 29 59455 0.246022 0.333214 -0.1221387 -0.0008198 0.000231 -0.000031 0.000024 0.000017 0.0000112 0.0000070 0.000056 0.000064 2021 8 30 59456 0.245834 0.331664 -0.1212791 -0.0008920 0.000239 0.000029 0.000024 0.000017 0.0000108 0.0000070 0.000056 0.000063 2021 8 31 59457 0.245060 0.329881 -0.1203267 -0.0009814 0.000247 0.000089 0.000024 0.000017 0.0000109 0.0000070 0.000055 0.000062 2021 9 1 59458 0.244291 0.327776 -0.1193071 -0.0010322 0.000253 0.000051 0.000024 0.000017 0.0000105 0.0000070 0.000055 0.000061 2021 9 2 59459 0.243859 0.325972 -0.1182574 -0.0010516 0.000260 -0.000013 0.000023 0.000017 0.0000106 0.0000070 0.000055 0.000059 2021 9 3 59460 0.243838 0.324135 -0.1172280 -0.0010009 0.000266 -0.000077 0.000023 0.000017 0.0000105 0.0000069 0.000055 0.000057 2021 9 4 59461 0.243924 0.322819 -0.1162657 -0.0008934 0.000233 -0.000089 0.000023 0.000017 0.0000106 0.0000069 0.000052 0.000055 2021 9 5 59462 0.243284 0.321221 -0.1154565 -0.0007065 0.000188 -0.000083 0.000023 0.000017 0.0000107 0.0000069 0.000049 0.000054 2021 9 6 59463 0.242288 0.319291 -0.1149183 -0.0004500 0.000143 -0.000077 0.000024 0.000017 0.0000113 0.0000069 0.000050 0.000053 2021 9 7 59464 0.241085 0.317267 -0.1145864 -0.0002230 0.000097 -0.000071 0.000024 0.000017 0.0000109 0.0000069 0.000050 0.000051 2021 9 8 59465 0.240168 0.315380 -0.1144389 -0.0000487 0.000052 -0.000065 0.000024 0.000017 0.0000107 0.0000069 0.000049 0.000050 2021 9 9 59466 0.239509 0.313682 -0.1144456 0.0000445 0.000108 -0.000082 0.000024 0.000017 0.0000093 0.0000068 0.000049 0.000050 2021 9 10 59467 0.239055 0.311944 -0.1145001 0.0000481 0.000190 -0.000103 0.000024 0.000017 0.0000091 0.0000069 0.000049 0.000049 2021 9 11 59468 0.238903 0.310398 -0.1145067 -0.0000661 0.000217 -0.000108 0.000024 0.000017 0.0000091 0.0000068 0.000048 0.000047 2021 9 12 59469 0.239057 0.309176 -0.1143417 -0.0002835 0.000225 -0.000108 0.000023 0.000017 0.0000090 0.0000068 0.000047 0.000046 2021 9 13 59470 0.239061 0.308241 -0.1139194 -0.0005446 0.000233 -0.000107 0.000023 0.000017 0.0000091 0.0000068 0.000046 0.000045 2021 9 14 59471 0.238135 0.306840 -0.1132542 -0.0007658 0.000240 -0.000106 0.000023 0.000017 0.0000089 0.0000069 0.000046 0.000043 2021 9 15 59472 0.236855 0.305424 -0.1124265 -0.0008470 0.000260 -0.000133 0.000023 0.000018 0.0000089 0.0000069 0.000046 0.000043 2021 9 16 59473 0.235175 0.304217 -0.1115600 -0.0008380 0.000282 -0.000168 0.000023 0.000017 0.0000090 0.0000068 0.000045 0.000042 2021 9 17 59474 0.234052 0.302470 -0.1107776 -0.0006952 0.000304 -0.000203 0.000023 0.000018 0.0000091 0.0000068 0.000045 0.000042 2021 9 18 59475 0.233267 0.300669 -0.1101847 -0.0004981 0.000294 -0.000179 0.000023 0.000018 0.0000091 0.0000068 0.000043 0.000041 2021 9 19 59476 0.231901 0.298971 -0.1097908 -0.0003079 0.000271 -0.000133 0.000023 0.000018 0.0000092 0.0000068 0.000062 0.000040 2021 9 20 59477 0.230860 0.297082 -0.1095369 -0.0001935 0.000250 -0.000088 0.000024 0.000018 0.0000090 0.0000069 0.000043 0.000039 2021 9 21 59478 0.230386 0.295169 -0.1093835 -0.0001309 0.000229 -0.000021 0.000024 0.000018 0.0000091 0.0000068 0.000040 0.000034 2021 9 22 59479 0.230280 0.293410 -0.1092939 -0.0000808 0.000215 -0.000032 0.000024 0.000019 0.0000092 0.0000068 0.000040 0.000034 2021 9 23 59480 0.229745 0.291932 -0.1092075 -0.0001148 0.000201 -0.000063 0.000024 0.000018 0.0000085 0.0000067 0.000039 0.000034 2021 9 24 59481 0.229059 0.290744 -0.1090710 -0.0001808 0.000187 -0.000093 0.000024 0.000019 0.0000086 0.0000068 0.000039 0.000034 2021 9 25 59482 0.228196 0.289721 -0.1088548 -0.0002793 0.000198 -0.000095 0.000024 0.000019 0.0000087 0.0000068 0.000040 0.000033 2021 9 26 59483 0.226765 0.288616 -0.1085235 -0.0004236 0.000218 -0.000088 0.000025 0.000019 0.0000088 0.0000068 0.000040 0.000032 2021 9 27 59484 0.224983 0.286909 -0.1080259 -0.0005541 0.000237 -0.000081 0.000025 0.000019 0.0000076 0.0000068 0.000037 0.000031 2021 9 28 59485 0.223233 0.285091 -0.1073996 -0.0006578 0.000257 -0.000075 0.000025 0.000019 0.0000075 0.0000068 0.000037 0.000030 2021 9 29 59486 0.221642 0.283266 -0.1067014 -0.0007266 0.000266 -0.000086 0.000025 0.000019 0.0000073 0.0000068 0.000037 0.000029 2021 9 30 59487 0.220649 0.281274 -0.1059687 -0.0007290 0.000272 -0.000102 0.000025 0.000020 0.0000072 0.0000068 0.000037 0.000028 2021 10 1 59488 0.219900 0.279843 -0.1052566 -0.0006552 0.000278 -0.000118 0.000025 0.000019 0.0000072 0.0000067 0.000037 0.000027 2021 10 2 59489 0.219232 0.278385 -0.1046635 -0.0005041 0.000288 -0.000132 0.000025 0.000020 0.0000072 0.0000068 0.000037 0.000026 2021 10 3 59490 0.218114 0.277440 -0.1042262 -0.0003168 0.000301 -0.000145 0.000025 0.000020 0.0000071 0.0000068 0.000036 0.000024 2021 10 4 59491 0.216463 0.276398 -0.1040412 -0.0000538 0.000314 -0.000158 0.000025 0.000020 0.0000070 0.0000068 0.000036 0.000023 2021 10 5 59492 0.214966 0.275265 -0.1041427 0.0002367 0.000326 -0.000172 0.000025 0.000020 0.0000067 0.0000068 0.000035 0.000022 2021 10 6 59493 0.212886 0.274073 -0.1045130 0.0004438 0.000255 -0.000172 0.000025 0.000020 0.0000065 0.0000068 0.000036 0.000023 2021 10 7 59494 0.210670 0.272310 -0.1050355 0.0005448 0.000164 -0.000169 0.000025 0.000020 0.0000068 0.0000067 0.000036 0.000024 2021 10 8 59495 0.208740 0.270354 -0.1055552 0.0004758 0.000073 -0.000166 0.000024 0.000020 0.0000071 0.0000068 0.000037 0.000025 2021 10 9 59496 0.206987 0.268630 -0.1059176 0.0002801 0.000080 -0.000140 0.000024 0.000020 0.0000073 0.0000068 0.000038 0.000027 2021 10 10 59497 0.205587 0.267049 -0.1060489 0.0000458 0.000123 -0.000105 0.000025 0.000020 0.0000075 0.0000068 0.000061 0.000028 2021 10 11 59498 0.204294 0.265940 -0.1059506 -0.0002003 0.000164 -0.000071 0.000025 0.000020 0.0000075 0.0000068 0.000038 0.000029 2021 10 12 59499 0.202929 0.265318 -0.1056985 -0.0003003 0.000206 -0.000037 0.000025 0.000020 0.0000075 0.0000068 0.000039 0.000031 2021 10 13 59500 0.201347 0.265115 -0.1053769 -0.0003296 0.000249 -0.000003 0.000025 0.000020 0.0000076 0.0000068 0.000039 0.000032 2021 10 14 59501 0.199531 0.264474 -0.1050561 -0.0002785 0.000253 -0.000031 0.000025 0.000020 0.0000074 0.0000069 0.000040 0.000033 2021 10 15 59502 0.197144 0.264052 -0.1048215 -0.0001786 0.000247 -0.000076 0.000025 0.000019 0.0000075 0.0000068 0.000040 0.000035 2021 10 16 59503 0.194540 0.263311 -0.1047296 -0.0000160 0.000238 -0.000079 0.000025 0.000019 0.0000077 0.0000068 0.000041 0.000035 2021 10 17 59504 0.192522 0.262732 -0.1047961 0.0001436 0.000228 -0.000068 0.000025 0.000019 0.0000079 0.0000068 0.000041 0.000036 2021 10 18 59505 0.190330 0.262116 -0.1049797 0.0002729 0.000218 -0.000056 0.000025 0.000019 0.0000080 0.0000068 0.000041 0.000037 2021 10 19 59506 0.188419 0.261094 -0.1053261 0.0003283 0.000207 -0.000044 0.000025 0.000019 0.0000075 0.0000068 0.000041 0.000037 2021 10 20 59507 0.186951 0.260372 -0.1056852 0.0003063 0.000226 -0.000066 0.000025 0.000019 0.0000077 0.0000068 0.000042 0.000039 2021 10 21 59508 0.185890 0.259671 -0.1059933 0.0002542 0.000253 -0.000096 0.000025 0.000019 0.0000079 0.0000069 0.000042 0.000041 2021 10 22 59509 0.185109 0.258931 -0.1061695 0.0001074 0.000280 -0.000127 0.000025 0.000019 0.0000078 0.0000068 0.000043 0.000043 2021 10 23 59510 0.183997 0.258126 -0.1061599 -0.0001073 0.000282 -0.000110 0.000025 0.000019 0.0000080 0.0000068 0.000042 0.000044 2021 10 24 59511 0.182170 0.256859 -0.1059532 -0.0003135 0.000275 -0.000073 0.000025 0.000018 0.0000082 0.0000068 0.000042 0.000045 2021 10 25 59512 0.180765 0.255674 -0.1055673 -0.0004478 0.000267 -0.000036 0.000025 0.000018 0.0000083 0.0000069 0.000043 0.000047 2021 10 26 59513 0.179443 0.255135 -0.1050710 -0.0004914 0.000259 0.000001 0.000025 0.000018 0.0000086 0.0000069 0.000043 0.000048 2021 10 27 59514 0.177475 0.254614 -0.1045560 -0.0004736 0.000244 -0.000029 0.000025 0.000018 0.0000088 0.0000069 0.000044 0.000049 2021 10 28 59515 0.174986 0.254210 -0.1040921 -0.0004235 0.000226 -0.000076 0.000025 0.000018 0.0000090 0.0000070 0.000044 0.000050 2021 10 29 59516 0.172883 0.253703 -0.1037503 -0.0002679 0.000209 -0.000124 0.000025 0.000018 0.0000088 0.0000070 0.000045 0.000050 2021 10 30 59517 0.171153 0.253485 -0.1035881 -0.0000628 0.000211 -0.000123 0.000025 0.000018 0.0000090 0.0000070 0.000045 0.000050 2021 10 31 59518 0.169153 0.253030 -0.1036762 0.0002284 0.000221 -0.000105 0.000025 0.000018 0.0000091 0.0000071 0.000045 0.000050 2021 11 1 59519 0.167161 0.252590 -0.1040619 0.0005226 0.000230 -0.000087 0.000025 0.000018 0.0000095 0.0000069 0.000045 0.000050 2021 11 2 59520 0.165421 0.252037 -0.1047142 0.0007367 0.000239 -0.000069 0.000025 0.000018 0.0000096 0.0000070 0.000046 0.000050 2021 11 3 59521 0.164345 0.251154 -0.1055305 0.0008486 0.000249 -0.000051 0.000025 0.000018 0.0000099 0.0000070 0.000046 0.000050 2021 11 4 59522 0.163380 0.250407 -0.1063597 0.0007779 0.000200 -0.000036 0.000025 0.000018 0.0000096 0.0000070 0.000046 0.000050 2021 11 5 59523 0.161527 0.249780 -0.1070350 0.0005185 0.000135 -0.000022 0.000026 0.000018 0.0000094 0.0000070 0.000047 0.000050 2021 11 6 59524 0.158959 0.249274 -0.1074216 0.0002206 0.000153 -0.000034 0.000026 0.000018 0.0000096 0.0000071 0.000047 0.000051 2021 11 7 59525 0.156428 0.248766 -0.1075061 -0.0000193 0.000204 -0.000058 0.000026 0.000019 0.0000098 0.0000071 0.000044 0.000051 2021 11 8 59526 0.154365 0.248057 -0.1073849 -0.0001713 0.000254 -0.000081 0.000026 0.000018 0.0000100 0.0000070 0.000045 0.000053 2021 11 9 59527 0.152501 0.247567 -0.1071716 -0.0002182 0.000304 -0.000104 0.000026 0.000019 0.0000102 0.0000070 0.000045 0.000054 2021 11 10 59528 0.150781 0.247125 -0.1069620 -0.0001425 0.000289 -0.000093 0.000026 0.000019 0.0000103 0.0000070 0.000046 0.000054 2021 11 11 59529 0.149470 0.246785 -0.1068772 0.0000166 0.000255 -0.000072 0.000026 0.000019 0.0000100 0.0000070 0.000046 0.000054 2021 11 12 59530 0.148470 0.246564 -0.1069721 0.0001709 0.000222 -0.000052 0.000026 0.000019 0.0000103 0.0000068 0.000046 0.000054 2021 11 13 59531 0.147692 0.246455 -0.1072523 0.0003196 0.000220 -0.000061 0.000026 0.000019 0.0000104 0.0000069 0.000047 0.000053 2021 11 14 59532 0.147041 0.246459 -0.1076527 0.0003813 0.000230 -0.000082 0.000027 0.000019 0.0000105 0.0000069 0.000047 0.000052 2021 11 15 59533 0.145836 0.246338 -0.1080024 0.0003295 0.000239 -0.000102 0.000027 0.000019 0.0000096 0.0000069 0.000047 0.000051 2021 11 16 59534 0.143555 0.246023 -0.1082774 0.0002430 0.000249 -0.000122 0.000027 0.000019 0.0000096 0.0000069 0.000047 0.000050 2021 11 17 59535 0.141392 0.245346 -0.1084806 0.0001504 0.000247 -0.000082 0.000027 0.000019 0.0000097 0.0000069 0.000047 0.000048 2021 11 18 59536 0.139789 0.245077 -0.1085552 0.0000024 0.000242 -0.000025 0.000027 0.000019 0.0000093 0.0000070 0.000047 0.000047 2021 11 19 59537 0.137868 0.245245 -0.1084680 -0.0001716 0.000237 0.000032 0.000026 0.000019 0.0000089 0.0000069 0.000048 0.000045 2021 11 20 59538 0.135470 0.245267 -0.1081943 -0.0003451 0.000242 0.000032 0.000026 0.000019 0.0000090 0.0000069 0.000047 0.000044 2021 11 21 59539 0.133433 0.245936 -0.1077699 -0.0004589 0.000250 0.000011 0.000026 0.000019 0.0000091 0.0000069 0.000052 0.000043 2021 11 22 59540 0.131584 0.246933 -0.1072664 -0.0005149 0.000257 -0.000010 0.000026 0.000019 0.0000091 0.0000069 0.000046 0.000042 2021 11 23 59541 0.129614 0.247350 -0.1067281 -0.0005456 0.000265 -0.000031 0.000026 0.000019 0.0000079 0.0000069 0.000046 0.000041 2021 11 24 59542 0.127746 0.247246 -0.1062044 -0.0005261 0.000273 -0.000052 0.000026 0.000019 0.0000075 0.0000069 0.000046 0.000041 2021 11 25 59543 0.126546 0.247694 -0.1057277 -0.0004280 0.000305 -0.000029 0.000026 0.000019 0.0000069 0.0000069 0.000046 0.000041 2021 11 26 59544 0.125318 0.248339 -0.1053900 -0.0002261 0.000344 0.000006 0.000026 0.000019 0.0000068 0.0000068 0.000046 0.000041 2021 11 27 59545 0.123926 0.249137 -0.1053000 0.0000260 0.000321 -0.000017 0.000027 0.000020 0.0000068 0.0000068 0.000046 0.000040 2021 11 28 59546 0.122510 0.250182 -0.1054501 0.0002285 0.000278 -0.000060 0.000027 0.000020 0.0000067 0.0000068 0.000047 0.000040 2021 11 29 59547 0.120935 0.250800 -0.1057693 0.0003902 0.000234 -0.000103 0.000026 0.000019 0.0000067 0.0000067 0.000047 0.000039 2021 11 30 59548 0.119462 0.251409 -0.1062356 0.0005403 0.000190 -0.000147 0.000026 0.000019 0.0000066 0.0000067 0.000047 0.000038 2021 12 1 59549 0.117908 0.252101 -0.1068219 0.0005712 0.000205 -0.000142 0.000026 0.000020 0.0000066 0.0000066 0.000048 0.000038 2021 12 2 59550 0.116646 0.253077 -0.1073817 0.0004702 0.000235 -0.000125 0.000026 0.000020 0.0000067 0.0000066 0.000048 0.000038 2021 12 3 59551 0.115236 0.254139 -0.1077758 0.0002768 0.000265 -0.000108 0.000026 0.000020 0.0000067 0.0000065 0.000048 0.000039 2021 12 4 59552 0.113528 0.254463 -0.1079062 -0.0000071 0.000270 -0.000106 0.000026 0.000020 0.0000069 0.0000065 0.000047 0.000039 2021 12 5 59553 0.112210 0.254544 -0.1077891 -0.0002049 0.000266 -0.000109 0.000026 0.000020 0.0000070 0.0000065 0.000047 0.000040 2021 12 6 59554 0.110933 0.255126 -0.1075299 -0.0002631 0.000263 -0.000112 0.000025 0.000019 0.0000072 0.0000064 0.000047 0.000041 2021 12 7 59555 0.109262 0.255631 -0.1072636 -0.0001957 0.000259 -0.000116 0.000025 0.000019 0.0000073 0.0000063 0.000047 0.000041 2021 12 8 59556 0.106686 0.256326 -0.1071092 -0.0000541 0.000249 -0.000116 0.000025 0.000019 0.0000071 0.0000063 0.000047 0.000042 2021 12 9 59557 0.103984 0.256757 -0.1071653 0.0001373 0.000237 -0.000116 0.000025 0.000019 0.0000072 0.0000063 0.000047 0.000043 2021 12 10 59558 0.101414 0.257116 -0.1074002 0.0003090 0.000225 -0.000115 0.000025 0.000019 0.0000071 0.0000062 0.000047 0.000043 2021 12 11 59559 0.098426 0.257383 -0.1077748 0.0004257 0.000239 -0.000111 0.000025 0.000019 0.0000073 0.0000062 0.000047 0.000044 2021 12 12 59560 0.095231 0.257384 -0.1082102 0.0004477 0.000263 -0.000105 0.000025 0.000019 0.0000074 0.0000062 0.000047 0.000044 2021 12 13 59561 0.092509 0.257408 -0.1086201 0.0003713 0.000286 -0.000099 0.000025 0.000019 0.0000076 0.0000062 0.000047 0.000045 2021 12 14 59562 0.090306 0.258026 -0.1089586 0.0002966 0.000310 -0.000093 0.000025 0.000019 0.0000071 0.0000062 0.000047 0.000045 2021 12 15 59563 0.087829 0.258992 -0.1091980 0.0001665 0.000278 -0.000106 0.000025 0.000019 0.0000069 0.0000062 0.000047 0.000046 2021 12 16 59564 0.085353 0.259707 -0.1093060 0.0000223 0.000232 -0.000124 0.000025 0.000019 0.0000069 0.0000061 0.000047 0.000046 2021 12 17 59565 0.082621 0.260745 -0.1092661 -0.0001186 0.000186 -0.000142 0.000025 0.000019 0.0000067 0.0000061 0.000048 0.000047 2021 12 18 59566 0.080179 0.261328 -0.1090678 -0.0002676 0.000193 -0.000128 0.000025 0.000018 0.0000069 0.0000061 0.000047 0.000047 2021 12 19 59567 0.078732 0.261660 -0.1087469 -0.0003304 0.000220 -0.000102 0.000025 0.000018 0.0000069 0.0000061 0.000047 0.000046 2021 12 20 59568 0.077355 0.262569 -0.1083780 -0.0003631 0.000247 -0.000076 0.000026 0.000018 0.0000069 0.0000061 0.000047 0.000046 2021 12 21 59569 0.075405 0.263444 -0.1079991 -0.0003958 0.000274 -0.000050 0.000026 0.000018 0.0000068 0.0000061 0.000045 0.000045 2021 12 22 59570 0.073133 0.264278 -0.1076234 -0.0003472 0.000250 -0.000038 0.000026 0.000018 0.0000070 0.0000061 0.000046 0.000046 2021 12 23 59571 0.070881 0.265173 -0.1073418 -0.0001681 0.000213 -0.000030 0.000026 0.000018 0.0000070 0.0000061 0.000046 0.000048 2021 12 24 59572 0.068514 0.266510 -0.1072445 0.0000386 0.000223 -0.000071 0.000030 0.000021 0.0000071 0.0000065 0.000044 0.000049 2021 12 25 59573 0.066054 0.267813 -0.1073681 0.0002146 0.000252 -0.000130 0.000029 0.000022 0.0000072 0.0000065 0.000044 0.000050 2021 12 26 59574 0.064264 0.268977 -0.1077173 0.0004337 0.000280 -0.000190 0.000029 0.000022 0.0000073 0.0000066 0.000044 0.000051 2021 12 27 59575 0.062771 0.270366 -0.1082590 0.0006074 0.000309 -0.000249 0.000029 0.000022 0.0000074 0.0000066 0.000044 0.000052 2021 12 28 59576 0.061119 0.271893 -0.1089162 0.0006456 0.000337 -0.000309 0.000029 0.000022 0.0000078 0.0000066 0.000044 0.000053 2021 12 29 59577 0.059184 0.273531 -0.1095688 0.0005855 0.000221 -0.000316 0.000029 0.000022 0.0000076 0.0000066 0.000044 0.000053 2021 12 30 59578 0.057753 0.274728 -0.1101029 0.0004366 0.000068 -0.000309 0.000029 0.000022 0.0000078 0.0000066 0.000044 0.000053 2021 12 31 59579 0.056304 0.275973 -0.1104355 0.0001907 0.000040 -0.000287 0.000028 0.000022 0.0000080 0.0000065 0.000043 0.000052 2022 1 1 59580 0.054574 0.276983 -0.1105197 -0.0000357 0.000059 -0.000259 0.000028 0.000022 0.0000082 0.0000066 0.000044 0.000051 2022 1 2 59581 0.053381 0.277886 -0.1103891 -0.0002254 0.000077 -0.000230 0.000027 0.000022 0.0000083 0.0000066 0.000044 0.000049 2022 1 3 59582 0.052855 0.278999 -0.1101398 -0.0002593 0.000095 -0.000202 0.000027 0.000022 0.0000084 0.0000066 0.000043 0.000048 2022 1 4 59583 0.053294 0.280607 -0.1099190 -0.0001210 0.000114 -0.000174 0.000027 0.000022 0.0000075 0.0000067 0.000043 0.000047 2022 1 5 59584 0.053559 0.282963 -0.1098692 0.0000832 0.000132 -0.000152 0.000026 0.000022 0.0000074 0.0000067 0.000043 0.000046 2022 1 6 59585 0.053042 0.285048 -0.1100259 0.0002481 0.000150 -0.000132 0.000026 0.000022 0.0000073 0.0000068 0.000043 0.000045 2022 1 7 59586 0.051849 0.286983 -0.1103610 0.0003632 0.000169 -0.000113 0.000026 0.000022 0.0000071 0.0000068 0.000042 0.000044 2022 1 8 59587 0.050225 0.288671 -0.1107892 0.0004361 0.000194 -0.000092 0.000025 0.000022 0.0000071 0.0000069 0.000042 0.000042 2022 1 9 59588 0.048602 0.290231 -0.1112277 0.0004120 0.000222 -0.000071 0.000025 0.000022 0.0000071 0.0000069 0.000042 0.000041 2022 1 10 59589 0.047155 0.291472 -0.1116091 0.0003188 0.000249 -0.000050 0.000025 0.000022 0.0000069 0.0000070 0.000042 0.000039 2022 1 11 59590 0.045595 0.292576 -0.1118697 0.0001719 0.000277 -0.000029 0.000025 0.000022 0.0000068 0.0000069 0.000042 0.000038 2022 1 12 59591 0.044205 0.293449 -0.1119606 -0.0000010 0.000266 -0.000035 0.000025 0.000022 0.0000067 0.0000069 0.000042 0.000037 2022 1 13 59592 0.043394 0.294345 -0.1118677 -0.0001786 0.000244 -0.000047 0.000025 0.000022 0.0000066 0.0000070 0.000042 0.000036 2022 1 14 59593 0.043106 0.295839 -0.1115941 -0.0003603 0.000223 -0.000060 0.000025 0.000021 0.0000065 0.0000069 0.000041 0.000036 2022 1 15 59594 0.043114 0.297844 -0.1111643 -0.0004983 0.000205 -0.000078 0.000025 0.000021 0.0000066 0.0000069 0.000041 0.000035 2022 1 16 59595 0.042534 0.299918 -0.1106129 -0.0005991 0.000188 -0.000097 0.000025 0.000022 0.0000066 0.0000070 0.000041 0.000034 2022 1 17 59596 0.041549 0.301463 -0.1100064 -0.0006154 0.000172 -0.000117 0.000025 0.000022 0.0000067 0.0000070 0.000041 0.000034 2022 1 18 59597 0.039912 0.303016 -0.1093760 -0.0006054 0.000155 -0.000136 0.000025 0.000022 0.0000067 0.0000071 0.000041 0.000033 2022 1 19 59598 0.038420 0.303951 -0.1088179 -0.0004807 0.000139 -0.000156 0.000025 0.000022 0.0000066 0.0000071 0.000041 0.000033 2022 1 20 59599 0.037831 0.305025 -0.1084531 -0.0002680 0.000157 -0.000185 0.000025 0.000021 0.0000063 0.0000070 0.000041 0.000032 2022 1 21 59600 0.037456 0.306196 -0.1082981 -0.0000409 0.000184 -0.000218 0.000025 0.000021 0.0000059 0.0000071 0.000041 0.000031 2022 1 22 59601 0.036968 0.307328 -0.1083306 0.0001170 0.000174 -0.000208 0.000025 0.000021 0.0000059 0.0000071 0.000041 0.000031 2022 1 23 59602 0.036011 0.308634 -0.1085119 0.0002229 0.000149 -0.000180 0.000025 0.000021 0.0000060 0.0000071 0.000041 0.000031 2022 1 24 59603 0.034458 0.310100 -0.1087689 0.0002555 0.000124 -0.000153 0.000026 0.000021 0.0000059 0.0000072 0.000041 0.000030 2022 1 25 59604 0.032747 0.311519 -0.1090294 0.0002359 0.000100 -0.000126 0.000026 0.000021 0.0000059 0.0000072 0.000041 0.000030 2022 1 26 59605 0.031327 0.312793 -0.1092242 0.0001302 0.000124 -0.000137 0.000027 0.000021 0.0000059 0.0000072 0.000041 0.000030 2022 1 27 59606 0.030254 0.314102 -0.1092764 -0.0000451 0.000162 -0.000159 0.000027 0.000021 0.0000054 0.0000073 0.000041 0.000030 2022 1 28 59607 0.029060 0.315654 -0.1091370 -0.0002362 0.000200 -0.000181 0.000028 0.000021 0.0000054 0.0000073 0.000041 0.000030 2022 1 29 59608 0.028306 0.317130 -0.1088191 -0.0004108 0.000198 -0.000190 0.000028 0.000021 0.0000054 0.0000074 0.000042 0.000030 2022 1 30 59609 0.027664 0.318978 -0.1083658 -0.0004934 0.000181 -0.000195 0.000029 0.000021 0.0000054 0.0000074 0.000042 0.000030 2022 1 31 59610 0.026619 0.320963 -0.1078483 -0.0004966 0.000165 -0.000200 0.000028 0.000020 0.0000054 0.0000072 0.000042 0.000030 2022 2 1 59611 0.026107 0.323014 -0.1073994 -0.0003435 0.000148 -0.000205 0.000029 0.000020 0.0000055 0.0000073 0.000042 0.000030 2022 2 2 59612 0.025834 0.325489 -0.1071431 -0.0001248 0.000154 -0.000230 0.000029 0.000020 0.0000056 0.0000073 0.000043 0.000031 2022 2 3 59613 0.025683 0.327751 -0.1070987 0.0000410 0.000165 -0.000260 0.000029 0.000020 0.0000057 0.0000074 0.000043 0.000033 2022 2 4 59614 0.025779 0.330022 -0.1072225 0.0001631 0.000176 -0.000290 0.000029 0.000020 0.0000058 0.0000073 0.000044 0.000035 2022 2 5 59615 0.025738 0.332211 -0.1074267 0.0002001 0.000179 -0.000241 0.000029 0.000020 0.0000059 0.0000073 0.000045 0.000036 2022 2 6 59616 0.025676 0.333942 -0.1076113 0.0001192 0.000180 -0.000162 0.000029 0.000020 0.0000061 0.0000073 0.000045 0.000037 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/iers/data/update_builtin_iers.sh0000755000175100001710000000060400000000000023352 0ustar00vstsdocker#!/bin/sh set -euv # This script should be run every time an astropy release is made. # It downloads up-to-date versions of the earth rotation and leap # second tables. rm Leap_Second.dat rm eopc04_IAU2000.62-now # iers.IERS_B_URL wget http://hpiers.obspm.fr/iers/eop/eopc04/eopc04_IAU2000.62-now # iers.IERS_LEAP_SECOND_URL wget https://hpiers.obspm.fr/iers/bul/bulc/Leap_Second.dat ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/iers/iers.py0000644000175100001710000013353600000000000017377 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ The astropy.utils.iers package provides access to the tables provided by the International Earth Rotation and Reference Systems Service, in particular allowing interpolation of published UT1-UTC values for given times. These are used in `astropy.time` to provide UT1 values. The polar motions are also used for determining earth orientation for celestial-to-terrestrial coordinate transformations (in `astropy.coordinates`). """ import re from datetime import datetime from warnings import warn from urllib.parse import urlparse import numpy as np import erfa from astropy.time import Time, TimeDelta from astropy import config as _config from astropy import units as u from astropy.table import QTable, MaskedColumn from astropy.utils.data import (get_pkg_data_filename, clear_download_cache, is_url_in_cache, get_readable_fileobj) from astropy.utils.state import ScienceState from astropy import utils from astropy.utils.exceptions import AstropyWarning __all__ = ['Conf', 'conf', 'earth_orientation_table', 'IERS', 'IERS_B', 'IERS_A', 'IERS_Auto', 'FROM_IERS_B', 'FROM_IERS_A', 'FROM_IERS_A_PREDICTION', 'TIME_BEFORE_IERS_RANGE', 'TIME_BEYOND_IERS_RANGE', 'IERS_A_FILE', 'IERS_A_URL', 'IERS_A_URL_MIRROR', 'IERS_A_README', 'IERS_B_FILE', 'IERS_B_URL', 'IERS_B_README', 'IERSRangeError', 'IERSStaleWarning', 'LeapSeconds', 'IERS_LEAP_SECOND_FILE', 'IERS_LEAP_SECOND_URL', 'IETF_LEAP_SECOND_URL'] # IERS-A default file name, URL, and ReadMe with content description IERS_A_FILE = 'finals2000A.all' IERS_A_URL = 'ftp://anonymous:mail%40astropy.org@gdc.cddis.eosdis.nasa.gov/pub/products/iers/finals2000A.all' # noqa: E501 IERS_A_URL_MIRROR = 'https://datacenter.iers.org/data/9/finals2000A.all' IERS_A_README = get_pkg_data_filename('data/ReadMe.finals2000A') # IERS-B default file name, URL, and ReadMe with content description IERS_B_FILE = get_pkg_data_filename('data/eopc04_IAU2000.62-now') IERS_B_URL = 'http://hpiers.obspm.fr/iers/eop/eopc04/eopc04_IAU2000.62-now' IERS_B_README = get_pkg_data_filename('data/ReadMe.eopc04_IAU2000') # LEAP SECONDS default file name, URL, and alternative format/URL IERS_LEAP_SECOND_FILE = get_pkg_data_filename('data/Leap_Second.dat') IERS_LEAP_SECOND_URL = 'https://hpiers.obspm.fr/iers/bul/bulc/Leap_Second.dat' IETF_LEAP_SECOND_URL = 'https://www.ietf.org/timezones/data/leap-seconds.list' # Status/source values returned by IERS.ut1_utc FROM_IERS_B = 0 FROM_IERS_A = 1 FROM_IERS_A_PREDICTION = 2 TIME_BEFORE_IERS_RANGE = -1 TIME_BEYOND_IERS_RANGE = -2 MJD_ZERO = 2400000.5 INTERPOLATE_ERROR = """\ interpolating from IERS_Auto using predictive values that are more than {0} days old. Normally you should not see this error because this class automatically downloads the latest IERS-A table. Perhaps you are offline? If you understand what you are doing then this error can be suppressed by setting the auto_max_age configuration variable to ``None``: from astropy.utils.iers import conf conf.auto_max_age = None """ MONTH_ABBR = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] def download_file(*args, **kwargs): """ Overload astropy.utils.data.download_file within iers module to use a custom (longer) wait time. This just passes through ``*args`` and ``**kwargs`` after temporarily setting the download_file remote timeout to the local ``iers.conf.remote_timeout`` value. """ kwargs.setdefault('http_headers', {'User-Agent': 'astropy/iers', 'Accept': '*/*'}) with utils.data.conf.set_temp('remote_timeout', conf.remote_timeout): return utils.data.download_file(*args, **kwargs) def _none_to_float(value): """ Convert None to a valid floating point value. Especially for auto_max_age = None. """ return (value if value is not None else np.finfo(float).max) class IERSStaleWarning(AstropyWarning): pass class Conf(_config.ConfigNamespace): """ Configuration parameters for `astropy.utils.iers`. """ auto_download = _config.ConfigItem( True, 'Enable auto-downloading of the latest IERS data. If set to False ' 'then the local IERS-B file will be used by default (even if the ' 'full IERS file with predictions was already downloaded and cached). ' 'This parameter also controls whether internet resources will be ' 'queried to update the leap second table if the installed version is ' 'out of date. Default is True.') auto_max_age = _config.ConfigItem( 30.0, 'Maximum age (days) of predictive data before auto-downloading. ' 'See "Auto refresh behavior" in astropy.utils.iers documentation for details. ' 'Default is 30.') iers_auto_url = _config.ConfigItem( IERS_A_URL, 'URL for auto-downloading IERS file data.') iers_auto_url_mirror = _config.ConfigItem( IERS_A_URL_MIRROR, 'Mirror URL for auto-downloading IERS file data.') remote_timeout = _config.ConfigItem( 10.0, 'Remote timeout downloading IERS file data (seconds).') system_leap_second_file = _config.ConfigItem( '', 'System file with leap seconds.') iers_leap_second_auto_url = _config.ConfigItem( IERS_LEAP_SECOND_URL, 'URL for auto-downloading leap seconds.') ietf_leap_second_auto_url = _config.ConfigItem( IETF_LEAP_SECOND_URL, 'Alternate URL for auto-downloading leap seconds.') conf = Conf() class IERSRangeError(IndexError): """ Any error for when dates are outside of the valid range for IERS """ class IERS(QTable): """Generic IERS table class, defining interpolation functions. Sub-classed from `astropy.table.QTable`. The table should hold columns 'MJD', 'UT1_UTC', 'dX_2000A'/'dY_2000A', and 'PM_x'/'PM_y'. """ iers_table = None """Cached table, returned if ``open`` is called without arguments.""" @classmethod def open(cls, file=None, cache=False, **kwargs): """Open an IERS table, reading it from a file if not loaded before. Parameters ---------- file : str or None full local or network path to the ascii file holding IERS data, for passing on to the ``read`` class methods (further optional arguments that are available for some IERS subclasses can be added). If None, use the default location from the ``read`` class method. cache : bool Whether to use cache. Defaults to False, since IERS files are regularly updated. Returns ------- IERS An IERS table class instance Notes ----- On the first call in a session, the table will be memoized (in the ``iers_table`` class attribute), and further calls to ``open`` will return this stored table if ``file=None`` (the default). If a table needs to be re-read from disk, pass on an explicit file location or use the (sub-class) close method and re-open. If the location is a network location it is first downloaded via download_file. For the IERS class itself, an IERS_B sub-class instance is opened. """ if file is not None or cls.iers_table is None: if file is not None: if urlparse(file).netloc: kwargs.update(file=download_file(file, cache=cache)) else: kwargs.update(file=file) # TODO: the below is really ugly and probably a bad idea. Instead, # there should probably be an IERSBase class, which provides # useful methods but cannot really be used on its own, and then # *perhaps* an IERS class which provides best defaults. But for # backwards compatibility, we use the IERS_B reader for IERS here. if cls is IERS: cls.iers_table = IERS_B.read(**kwargs) else: cls.iers_table = cls.read(**kwargs) return cls.iers_table @classmethod def close(cls): """Remove the IERS table from the class. This allows the table to be re-read from disk during one's session (e.g., if one finds it is out of date and has updated the file). """ cls.iers_table = None def mjd_utc(self, jd1, jd2=0.): """Turn a time to MJD, returning integer and fractional parts. Parameters ---------- jd1 : float, array, or `~astropy.time.Time` first part of two-part JD, or Time object jd2 : float or array, optional second part of two-part JD. Default is 0., ignored if jd1 is `~astropy.time.Time`. Returns ------- mjd : float or array integer part of MJD utc : float or array fractional part of MJD """ try: # see if this is a Time object jd1, jd2 = jd1.utc.jd1, jd1.utc.jd2 except Exception: pass mjd = np.floor(jd1 - MJD_ZERO + jd2) utc = jd1 - (MJD_ZERO+mjd) + jd2 return mjd, utc def ut1_utc(self, jd1, jd2=0., return_status=False): """Interpolate UT1-UTC corrections in IERS Table for given dates. Parameters ---------- jd1 : float, array of float, or `~astropy.time.Time` object first part of two-part JD, or Time object jd2 : float or float array, optional second part of two-part JD. Default is 0., ignored if jd1 is `~astropy.time.Time`. return_status : bool Whether to return status values. If False (default), raise ``IERSRangeError`` if any time is out of the range covered by the IERS table. Returns ------- ut1_utc : float or float array UT1-UTC, interpolated in IERS Table status : int or int array Status values (if ``return_status``=``True``):: ``iers.FROM_IERS_B`` ``iers.FROM_IERS_A`` ``iers.FROM_IERS_A_PREDICTION`` ``iers.TIME_BEFORE_IERS_RANGE`` ``iers.TIME_BEYOND_IERS_RANGE`` """ return self._interpolate(jd1, jd2, ['UT1_UTC'], self.ut1_utc_source if return_status else None) def dcip_xy(self, jd1, jd2=0., return_status=False): """Interpolate CIP corrections in IERS Table for given dates. Parameters ---------- jd1 : float, array of float, or `~astropy.time.Time` object first part of two-part JD, or Time object jd2 : float or float array, optional second part of two-part JD (default 0., ignored if jd1 is Time) return_status : bool Whether to return status values. If False (default), raise ``IERSRangeError`` if any time is out of the range covered by the IERS table. Returns ------- D_x : `~astropy.units.Quantity` ['angle'] x component of CIP correction for the requested times. D_y : `~astropy.units.Quantity` ['angle'] y component of CIP correction for the requested times status : int or int array Status values (if ``return_status``=``True``):: ``iers.FROM_IERS_B`` ``iers.FROM_IERS_A`` ``iers.FROM_IERS_A_PREDICTION`` ``iers.TIME_BEFORE_IERS_RANGE`` ``iers.TIME_BEYOND_IERS_RANGE`` """ return self._interpolate(jd1, jd2, ['dX_2000A', 'dY_2000A'], self.dcip_source if return_status else None) def pm_xy(self, jd1, jd2=0., return_status=False): """Interpolate polar motions from IERS Table for given dates. Parameters ---------- jd1 : float, array of float, or `~astropy.time.Time` object first part of two-part JD, or Time object jd2 : float or float array, optional second part of two-part JD. Default is 0., ignored if jd1 is `~astropy.time.Time`. return_status : bool Whether to return status values. If False (default), raise ``IERSRangeError`` if any time is out of the range covered by the IERS table. Returns ------- PM_x : `~astropy.units.Quantity` ['angle'] x component of polar motion for the requested times. PM_y : `~astropy.units.Quantity` ['angle'] y component of polar motion for the requested times. status : int or int array Status values (if ``return_status``=``True``):: ``iers.FROM_IERS_B`` ``iers.FROM_IERS_A`` ``iers.FROM_IERS_A_PREDICTION`` ``iers.TIME_BEFORE_IERS_RANGE`` ``iers.TIME_BEYOND_IERS_RANGE`` """ return self._interpolate(jd1, jd2, ['PM_x', 'PM_y'], self.pm_source if return_status else None) def _check_interpolate_indices(self, indices_orig, indices_clipped, max_input_mjd): """ Check that the indices from interpolation match those after clipping to the valid table range. This method gets overridden in the IERS_Auto class because it has different requirements. """ if np.any(indices_orig != indices_clipped): raise IERSRangeError('(some) times are outside of range covered ' 'by IERS table.') def _interpolate(self, jd1, jd2, columns, source=None): mjd, utc = self.mjd_utc(jd1, jd2) # enforce array is_scalar = not hasattr(mjd, '__array__') or mjd.ndim == 0 if is_scalar: mjd = np.array([mjd]) utc = np.array([utc]) elif mjd.size == 0: # Short-cut empty input. return np.array([]) self._refresh_table_as_needed(mjd) # For typical format, will always find a match (since MJD are integer) # hence, important to define which side we will be; this ensures # self['MJD'][i-1]<=mjd predictive_mjd and self.time_now.mjd - predictive_mjd > auto_max_age): raise ValueError(INTERPOLATE_ERROR.format(auto_max_age)) def _refresh_table_as_needed(self, mjd): """Potentially update the IERS table in place depending on the requested time values in ``mjd`` and the time span of the table. For IERS_Auto the behavior is that the table is refreshed from the IERS server if both the following apply: - Any of the requested IERS values are predictive. The IERS-A table contains predictive data out for a year after the available definitive values. - The first predictive values are at least ``conf.auto_max_age days`` old. In other words the IERS-A table was created by IERS long enough ago that it can be considered stale for predictions. """ max_input_mjd = np.max(mjd) now_mjd = self.time_now.mjd # IERS-A table contains predictive data out for a year after # the available definitive values. fpi = self.meta['predictive_index'] predictive_mjd = self.meta['predictive_mjd'] # Update table in place if necessary auto_max_age = _none_to_float(conf.auto_max_age) # If auto_max_age is smaller than IERS update time then repeated downloads may # occur without getting updated values (giving a IERSStaleWarning). if auto_max_age < 10: raise ValueError('IERS auto_max_age configuration value must be larger than 10 days') if (max_input_mjd > predictive_mjd and (now_mjd - predictive_mjd) > auto_max_age): all_urls = (conf.iers_auto_url, conf.iers_auto_url_mirror) # Get the latest version try: filename = download_file( all_urls[0], sources=all_urls, cache="update") except Exception as err: # Issue a warning here, perhaps user is offline. An exception # will be raised downstream when actually trying to interpolate # predictive values. warn(AstropyWarning( f'failed to download {" and ".join(all_urls)}: {err}.\n' 'A coordinate or time-related ' 'calculation might be compromised or fail because the dates are ' 'not covered by the available IERS file. See the ' '"IERS data access" section of the astropy documentation ' 'for additional information on working offline.')) return new_table = self.__class__.read(file=filename) new_table.meta['data_url'] = str(all_urls[0]) # New table has new values? if new_table['MJD'][-1] > self['MJD'][-1]: # Replace *replace* current values from the first predictive index through # the end of the current table. This replacement is much faster than just # deleting all rows and then using add_row for the whole duration. new_fpi = np.searchsorted(new_table['MJD'].value, predictive_mjd, side='right') n_replace = len(self) - fpi self[fpi:] = new_table[new_fpi:new_fpi + n_replace] # Sanity check for continuity if new_table['MJD'][new_fpi + n_replace] - self['MJD'][-1] != 1.0 * u.d: raise ValueError('unexpected gap in MJD when refreshing IERS table') # Now add new rows in place for row in new_table[new_fpi + n_replace:]: self.add_row(row) self.meta.update(new_table.meta) else: warn(IERSStaleWarning( 'IERS_Auto predictive values are older than {} days but downloading ' 'the latest table did not find newer values'.format(conf.auto_max_age))) @classmethod def _substitute_iers_b(cls, table): """Substitute IERS B values with those from a real IERS B table. IERS-A has IERS-B values included, but for reasons unknown these do not match the latest IERS-B values (see comments in #4436). Here, we use the bundled astropy IERS-B table to overwrite the values in the downloaded IERS-A table. """ iers_b = IERS_B.open() # Substitute IERS-B values for existing B values in IERS-A table mjd_b = table['MJD'][np.isfinite(table['UT1_UTC_B'])] i0 = np.searchsorted(iers_b['MJD'], mjd_b[0], side='left') i1 = np.searchsorted(iers_b['MJD'], mjd_b[-1], side='right') iers_b = iers_b[i0:i1] n_iers_b = len(iers_b) # If there is overlap then replace IERS-A values from available IERS-B if n_iers_b > 0: # Sanity check that we are overwriting the correct values if not u.allclose(table['MJD'][:n_iers_b], iers_b['MJD']): raise ValueError('unexpected mismatch when copying ' 'IERS-B values into IERS-A table.') # Finally do the overwrite table['UT1_UTC_B'][:n_iers_b] = iers_b['UT1_UTC'] table['PM_X_B'][:n_iers_b] = iers_b['PM_x'] table['PM_Y_B'][:n_iers_b] = iers_b['PM_y'] table['dX_2000A_B'][:n_iers_b] = iers_b['dX_2000A'] table['dY_2000A_B'][:n_iers_b] = iers_b['dY_2000A'] return table class earth_orientation_table(ScienceState): """Default IERS table for Earth rotation and reference systems service. These tables are used to calculate the offsets between ``UT1`` and ``UTC`` and for conversion to Earth-based coordinate systems. The state itself is an IERS table, as an instance of one of the `~astropy.utils.iers.IERS` classes. The default, the auto-updating `~astropy.utils.iers.IERS_Auto` class, should suffice for most purposes. Examples -------- To temporarily use the IERS-B file packaged with astropy:: >>> from astropy.utils import iers >>> from astropy.time import Time >>> iers_b = iers.IERS_B.open(iers.IERS_B_FILE) >>> with iers.earth_orientation_table.set(iers_b): ... print(Time('2000-01-01').ut1.isot) 2000-01-01T00:00:00.355 To use the most recent IERS-A file for the whole session:: >>> iers_a = iers.IERS_A.open(iers.IERS_A_URL) # doctest: +SKIP >>> iers.earth_orientation_table.set(iers_a) # doctest: +SKIP ...> To go back to the default (of `~astropy.utils.iers.IERS_Auto`):: >>> iers.earth_orientation_table.set(None) # doctest: +SKIP ...> """ _value = None @classmethod def validate(cls, value): if value is None: value = IERS_Auto.open() if not isinstance(value, IERS): raise ValueError("earth_orientation_table requires an IERS Table.") return value class LeapSeconds(QTable): """Leap seconds class, holding TAI-UTC differences. The table should hold columns 'year', 'month', 'tai_utc'. Methods are provided to initialize the table from IERS ``Leap_Second.dat``, IETF/ntp ``leap-seconds.list``, or built-in ERFA/SOFA, and to update the list used by ERFA. Notes ----- Astropy has a built-in ``iers.IERS_LEAP_SECONDS_FILE``. Up to date versions can be downloaded from ``iers.IERS_LEAP_SECONDS_URL`` or ``iers.LEAP_SECONDS_LIST_URL``. Many systems also store a version of ``leap-seconds.list`` for use with ``ntp`` (e.g., on Debian/Ubuntu systems, ``/usr/share/zoneinfo/leap-seconds.list``). To prevent querying internet resources if the available local leap second file(s) are out of date, set ``iers.conf.auto_download = False``. This must be done prior to performing any ``Time`` scale transformations related to UTC (e.g. converting from UTC to TAI). """ # Note: Time instances in this class should use scale='tai' to avoid # needing leap seconds in their creation or interpretation. _re_expires = re.compile(r'^#.*File expires on[:\s]+(\d+\s\w+\s\d+)\s*$') _expires = None _auto_open_files = ['erfa', IERS_LEAP_SECOND_FILE, 'system_leap_second_file', 'iers_leap_second_auto_url', 'ietf_leap_second_auto_url'] """Files or conf attributes to try in auto_open.""" @classmethod def open(cls, file=None, cache=False): """Open a leap-second list. Parameters ---------- file : path-like or None Full local or network path to the file holding leap-second data, for passing on to the various ``from_`` class methods. If 'erfa', return the data used by the ERFA library. If `None`, use default locations from file and configuration to find a table that is not expired. cache : bool Whether to use cache. Defaults to False, since leap-second files are regularly updated. Returns ------- leap_seconds : `~astropy.utils.iers.LeapSeconds` Table with 'year', 'month', and 'tai_utc' columns, plus possibly others. Notes ----- Bulletin C is released about 10 days after a possible leap second is introduced, i.e., mid-January or mid-July. Expiration days are thus generally at least 150 days after the present. For the auto-loading, a list comprised of the table shipped with astropy, and files and URLs in `~astropy.utils.iers.Conf` are tried, returning the first that is sufficiently new, or the newest among them all. """ if file is None: return cls.auto_open() if file.lower() == 'erfa': return cls.from_erfa() if urlparse(file).netloc: file = download_file(file, cache=cache) # Just try both reading methods. try: return cls.from_iers_leap_seconds(file) except Exception: return cls.from_leap_seconds_list(file) @staticmethod def _today(): # Get current day in scale='tai' without going through a scale change # (so we do not need leap seconds). s = '{0.year:04d}-{0.month:02d}-{0.day:02d}'.format(datetime.utcnow()) return Time(s, scale='tai', format='iso', out_subfmt='date') @classmethod def auto_open(cls, files=None): """Attempt to get an up-to-date leap-second list. The routine will try the files in sequence until it finds one whose expiration date is "good enough" (see below). If none are good enough, it returns the one with the most recent expiration date, warning if that file is expired. For remote files that are cached already, the cached file is tried first before attempting to retrieve it again. Parameters ---------- files : list of path-like, optional List of files/URLs to attempt to open. By default, uses ``cls._auto_open_files``. Returns ------- leap_seconds : `~astropy.utils.iers.LeapSeconds` Up to date leap-second table Notes ----- Bulletin C is released about 10 days after a possible leap second is introduced, i.e., mid-January or mid-July. Expiration days are thus generally at least 150 days after the present. We look for a file that expires more than 180 - `~astropy.utils.iers.Conf.auto_max_age` after the present. """ offset = 180 - (30 if conf.auto_max_age is None else conf.auto_max_age) good_enough = cls._today() + TimeDelta(offset, format='jd') if files is None: # Basic files to go over (entries in _auto_open_files can be # configuration items, which we want to be sure are up to date). files = [getattr(conf, f, f) for f in cls._auto_open_files] # Remove empty entries. files = [f for f in files if f] # Our trials start with normal files and remote ones that are # already in cache. The bools here indicate that the cache # should be used. trials = [(f, True) for f in files if not urlparse(f).netloc or is_url_in_cache(f)] # If we are allowed to download, we try downloading new versions # if none of the above worked. if conf.auto_download: trials += [(f, False) for f in files if urlparse(f).netloc] self = None err_list = [] # Go through all entries, and return the first one that # is not expired, or the most up to date one. for f, allow_cache in trials: if not allow_cache: clear_download_cache(f) try: trial = cls.open(f, cache=True) except Exception as exc: err_list.append(exc) continue if self is None or trial.expires > self.expires: self = trial self.meta['data_url'] = str(f) if self.expires > good_enough: break if self is None: raise ValueError('none of the files could be read. The ' 'following errors were raised:\n' + str(err_list)) if self.expires < self._today() and conf.auto_max_age is not None: warn('leap-second file is expired.', IERSStaleWarning) return self @property def expires(self): """The limit of validity of the table.""" return self._expires @classmethod def _read_leap_seconds(cls, file, **kwargs): """Read a file, identifying expiration by matching 'File expires'""" expires = None # Find expiration date. with get_readable_fileobj(file) as fh: lines = fh.readlines() for line in lines: match = cls._re_expires.match(line) if match: day, month, year = match.groups()[0].split() month_nb = MONTH_ABBR.index(month[:3]) + 1 expires = Time(f'{year}-{month_nb:02d}-{day}', scale='tai', out_subfmt='date') break else: raise ValueError(f'did not find expiration date in {file}') self = cls.read(lines, format='ascii.no_header', **kwargs) self._expires = expires return self @classmethod def from_iers_leap_seconds(cls, file=IERS_LEAP_SECOND_FILE): """Create a table from a file like the IERS ``Leap_Second.dat``. Parameters ---------- file : path-like, optional Full local or network path to the file holding leap-second data in a format consistent with that used by IERS. By default, uses ``iers.IERS_LEAP_SECOND_FILE``. Notes ----- The file *must* contain the expiration date in a comment line, like '# File expires on 28 June 2020' """ return cls._read_leap_seconds( file, names=['mjd', 'day', 'month', 'year', 'tai_utc']) @classmethod def from_leap_seconds_list(cls, file): """Create a table from a file like the IETF ``leap-seconds.list``. Parameters ---------- file : path-like, optional Full local or network path to the file holding leap-second data in a format consistent with that used by IETF. Up to date versions can be retrieved from ``iers.IETF_LEAP_SECOND_URL``. Notes ----- The file *must* contain the expiration date in a comment line, like '# File expires on: 28 June 2020' """ from astropy.io.ascii import convert_numpy # Here to avoid circular import names = ['ntp_seconds', 'tai_utc', 'comment', 'day', 'month', 'year'] # Note: ntp_seconds does not fit in 32 bit, so causes problems on # 32-bit systems without the np.int64 converter. self = cls._read_leap_seconds( file, names=names, include_names=names[:2], converters={'ntp_seconds': [convert_numpy(np.int64)]}) self['mjd'] = (self['ntp_seconds']/86400 + 15020).round() # Note: cannot use Time.ymdhms, since that might require leap seconds. isot = Time(self['mjd'], format='mjd', scale='tai').isot ymd = np.array([[int(part) for part in t.partition('T')[0].split('-')] for t in isot]) self['year'], self['month'], self['day'] = ymd.T return self @classmethod def from_erfa(cls, built_in=False): """Create table from the leap-second list in ERFA. Parameters ---------- built_in : bool If `False` (default), retrieve the list currently used by ERFA, which may have been updated. If `True`, retrieve the list shipped with erfa. """ current = cls(erfa.leap_seconds.get()) current._expires = Time('{0.year:04d}-{0.month:02d}-{0.day:02d}' .format(erfa.leap_seconds.expires), scale='tai') if not built_in: return current try: erfa.leap_seconds.set(None) # reset to defaults return cls.from_erfa(built_in=False) finally: erfa.leap_seconds.set(current) def update_erfa_leap_seconds(self, initialize_erfa=False): """Add any leap seconds not already present to the ERFA table. This method matches leap seconds with those present in the ERFA table, and extends the latter as necessary. Parameters ---------- initialize_erfa : bool, or 'only', or 'empty' Initialize the ERFA leap second table to its built-in value before trying to expand it. This is generally not needed but can help in case it somehow got corrupted. If equal to 'only', the ERFA table is reinitialized and no attempt it made to update it. If 'empty', the leap second table is emptied before updating, i.e., it is overwritten altogether (note that this may break things in surprising ways, as most leap second tables do not include pre-1970 pseudo leap-seconds; you were warned). Returns ------- n_update : int Number of items updated. Raises ------ ValueError If the leap seconds in the table are not on 1st of January or July, or if the matches are inconsistent. This would normally suggest a corrupted leap second table, but might also indicate that the ERFA table was corrupted. If needed, the ERFA table can be reset by calling this method with an appropriate value for ``initialize_erfa``. """ if initialize_erfa == 'empty': # Initialize to empty and update is the same as overwrite. erfa.leap_seconds.set(self) return len(self) if initialize_erfa: erfa.leap_seconds.set() if initialize_erfa == 'only': return 0 return erfa.leap_seconds.update(self) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1952538 astropy-5.0.2/astropy/utils/iers/tests/0000755000175100001710000000000000000000000017212 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/iers/tests/__init__.py0000644000175100001710000000000000000000000021311 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1952538 astropy-5.0.2/astropy/utils/iers/tests/data/0000755000175100001710000000000000000000000020123 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/iers/tests/data/finals2000A-2016-02-30-test0000644000175100001710000010235200000000000023732 0ustar00vstsdocker16 2 1 57359.00 I -0.003225 0.000031 0.299494 0.000025 I 0.0262864 0.0000042 1.3154 0.0035 I -0.094 0.119 -0.077 0.029 -0.003291 0.299534 0.0262719 -0.094 -0.169 16 2 2 57360.00 I -0.004706 0.000030 0.301252 0.000024 I 0.0249911 0.0000057 1.2412 0.0034 I -0.108 0.119 -0.082 0.035 -0.004751 0.301342 0.0249958 -0.128 -0.151 16 2 3 57361.00 I -0.005690 0.000031 0.302711 0.000025 I 0.0238039 0.0000054 1.1674 0.0040 I -0.112 0.045 -0.102 0.034 -0.005725 0.302649 0.0238016 -0.137 -0.154 16 2 4 57362.00 I -0.006490 0.000030 0.304493 0.000023 I 0.0226216 0.0000057 1.1976 0.0040 I -0.105 0.045 -0.115 0.034 -0.006418 0.304497 0.0226308 -0.139 -0.163 16 2 5 57363.00 I -0.007499 0.000030 0.306410 0.000020 I 0.0214229 0.0000059 1.1850 0.0048 I -0.094 0.045 -0.114 0.034 -0.007481 0.306466 0.0214306 -0.142 -0.171 16 2 6 57364.00 I -0.008637 0.000024 0.308121 0.000018 I 0.0201799 0.0000077 1.3874 0.0042 I -0.094 0.070 -0.115 0.034 -0.008646 0.308134 0.0201501 -0.145 -0.180 16 2 7 57365.00 I -0.009431 0.000032 0.309779 0.000020 I 0.0186616 0.0000061 1.5494 0.0050 I -0.103 0.053 -0.117 0.032 -0.009564 0.309799 0.0187256 -0.146 -0.188 16 2 8 57366.00 I -0.009639 0.000035 0.311456 0.000019 I 0.0171013 0.0000064 1.6508 0.0052 I -0.118 0.052 -0.112 0.039 -0.009602 0.311455 0.0171286 -0.150 -0.197 16 2 9 57367.00 I -0.009707 0.000034 0.313146 0.000017 I 0.0153086 0.0000083 1.9064 0.0048 I -0.137 0.119 -0.106 0.046 -0.009695 0.313158 0.0153216 -0.151 -0.205 16 210 57368.00 I -0.009949 0.000035 0.315007 0.000024 I 0.0133131 0.0000072 2.0881 0.0053 I -0.163 0.119 -0.110 0.053 -0.009848 0.314971 0.0133091 -0.162 -0.134 16 211 57369.00 I -0.010522 0.000036 0.317056 0.000024 I 0.0111967 0.0000067 2.0770 0.0049 I -0.189 0.119 -0.121 0.053 -0.010525 0.317115 0.0112339 -0.182 -0.133 16 212 57370.00 I -0.011219 0.000037 0.319016 0.000025 I 0.0091589 0.0000066 2.0665 0.0055 I -0.206 0.119 -0.119 0.053 -0.011200 0.319001 0.0091407 -0.206 -0.158 16 213 57371.00 I -0.011874 0.000031 0.321066 0.000024 I 0.0070911 0.0000088 1.9738 0.0047 I -0.211 0.119 -0.106 0.072 -0.011889 0.321068 0.0071356 -0.208 -0.158 16 214 57372.00 I -0.012456 0.000029 0.323240 0.000028 I 0.0052399 0.0000068 1.7954 0.0055 I -0.210 0.119 -0.093 0.047 -0.012445 0.323271 0.0052511 -0.202 -0.149 16 215 57373.00 I -0.013108 0.000027 0.325311 0.000027 I 0.0034804 0.0000065 1.6767 0.0047 I -0.209 0.119 -0.080 0.056 -0.013071 0.325381 0.0035069 -0.194 -0.140 16 216 57374.00 I -0.013911 0.000023 0.327010 0.000022 I 0.0019144 0.0000065 1.4745 0.0042 I -0.203 0.045 -0.057 0.050 -0.013912 0.327076 0.0019126 -0.187 -0.130 16 217 57375.00 I -0.014798 0.000021 0.328533 0.000023 I 0.0004966 0.0000052 1.3769 0.0045 I -0.186 0.045 -0.032 0.050 -0.014734 0.328472 0.0004608 -0.191 -0.037 16 218 57376.00 I -0.015972 0.000018 0.330387 0.000023 I-0.0008425 0.0000063 1.2886 0.0043 I -0.166 0.045 -0.025 0.050 -0.015929 0.330417 -0.0008581 -0.186 -0.027 16 219 57377.00 I -0.017359 0.000017 0.332361 0.000022 I-0.0021162 0.0000068 1.3072 0.0107 I -0.150 0.045 -0.032 0.050 -0.017369 0.332401 -0.0021130 -0.179 -0.049 16 220 57378.00 I -0.018572 0.000019 0.334012 0.000020 I-0.0034607 0.0000205 1.3373 0.0040 I -0.135 0.082 -0.033 0.156 -0.018639 0.334094 -0.0034487 -0.171 -0.071 16 221 57379.00 I -0.019315 0.000033 0.335553 0.000023 I-0.0048274 0.0000044 1.4772 0.0105 I -0.120 0.119 -0.029 0.011 -0.019329 0.335459 -0.0048827 -0.164 -0.092 16 222 57380.00 I -0.019952 0.000034 0.337603 0.000023 I-0.0064226 0.0000046 1.6395 0.0033 I -0.108 0.119 -0.038 0.011 -0.019862 0.337623 -0.0064324 -0.156 -0.114 16 223 57381.00 I -0.020869 0.000035 0.339814 0.000022 I-0.0080691 0.0000049 1.6897 0.0032 I -0.103 0.119 -0.063 0.027 -0.020905 0.339830 -0.0080787 -0.149 -0.136 16 224 57382.00 I -0.021582 0.000037 0.342052 0.000026 I-0.0098083 0.0000045 1.7588 0.0034 I -0.096 0.119 -0.079 0.033 -0.021616 0.342062 -0.0097889 -0.143 -0.149 16 225 57383.00 I -0.021898 0.000037 0.344332 0.000025 I-0.0115839 0.0000046 1.8195 0.0036 I -0.093 0.119 -0.073 0.033 -0.021911 0.344416 -0.0115637 -0.139 -0.160 16 226 57384.00 I -0.022036 0.000036 0.346321 0.000022 I-0.0134316 0.0000055 1.8329 0.0048 I -0.102 0.119 -0.062 0.033 -0.022011 0.346307 -0.0134119 -0.133 -0.171 16 227 57385.00 I -0.022387 0.000024 0.348429 0.000019 I-0.0152292 0.0000084 1.7846 0.0042 I -0.118 0.119 -0.064 0.059 -0.022273 0.348402 -0.0152189 -0.129 -0.181 16 228 57386.00 I -0.023235 0.000025 0.350749 0.000020 I-0.0170194 0.0000064 1.7921 0.0052 I -0.122 0.119 -0.082 0.035 -0.023218 0.350815 -0.0169781 -0.124 -0.192 16 229 57387.00 I -0.024219 0.000023 0.352784 0.000020 I-0.0187707 0.0000062 1.6716 0.0053 I -0.111 0.119 -0.105 0.027 -0.024254 0.352863 -0.0186952 -0.119 -0.203 16 3 1 57388.00 I -0.024807 0.000023 0.354400 0.000014 I-0.0203703 0.0000084 1.5743 0.0046 I -0.088 0.119 -0.125 0.011 -0.024918 0.354451 -0.0203678 -0.114 -0.214 16 3 2 57389.00 I -0.024651 0.000025 0.355942 0.000020 I-0.0219780 0.0000067 1.6532 0.0052 I -0.055 0.119 -0.125 0.049 16 3 3 57390.00 I -0.024054 0.000025 0.357866 0.000019 I-0.0236772 0.0000060 1.7337 0.0044 I -0.016 0.119 -0.093 0.049 16 3 4 57391.00 I -0.023735 0.000027 0.360180 0.000019 I-0.0254270 0.0000057 1.7591 0.0052 I 0.008 0.119 -0.056 0.049 16 3 5 57392.00 I -0.023740 0.000026 0.362598 0.000018 I-0.0272149 0.0000084 1.8430 0.0041 I 0.011 0.119 -0.053 0.091 16 3 6 57393.00 I -0.023745 0.000027 0.365029 0.000018 I-0.0291495 0.0000060 2.0365 0.0052 I 0.010 0.119 -0.081 0.052 16 3 7 57394.00 I -0.024021 0.000024 0.367538 0.000018 I-0.0312844 0.0000060 2.2194 0.0045 I 0.021 0.119 -0.095 0.052 16 3 8 57395.00 I -0.024457 0.000021 0.370024 0.000012 I-0.0335554 0.0000066 2.3035 0.0044 I 0.036 0.119 -0.085 0.026 16 3 9 57396.00 I -0.024829 0.000022 0.372483 0.000011 I-0.0359012 0.0000065 2.4168 0.0045 I 0.037 0.119 -0.072 0.026 16 310 57397.00 I -0.025066 0.000020 0.374873 0.000011 I-0.0383738 0.0000062 2.4843 0.0044 I 0.025 0.119 -0.063 0.026 16 311 57398.00 I -0.025097 0.000017 0.377004 0.000011 I-0.0408388 0.0000060 2.4588 0.0080 I 0.011 0.119 -0.053 0.026 16 312 57399.00 I -0.025181 0.000017 0.378932 0.000012 I-0.0432700 0.0000148 2.3690 0.0040 I 0.008 0.119 -0.040 0.150 16 313 57400.00 I -0.025188 0.000024 0.380780 0.000016 I-0.0455624 0.0000054 2.2359 0.0079 I 0.013 0.119 -0.031 0.150 16 314 57401.00 I -0.024758 0.000026 0.382629 0.000016 I-0.0477465 0.0000056 2.1168 0.0038 I 0.011 0.119 -0.012 0.150 16 315 57402.00 I -0.023945 0.000025 0.384773 0.000017 I-0.0497744 0.0000053 1.9330 0.0037 I -0.002 0.119 0.022 0.150 16 316 57403.00 I -0.022702 0.000026 0.387109 0.000023 I-0.0516492 0.0000048 1.8593 0.0035 I -0.012 0.042 0.057 0.020 16 317 57404.00 I -0.020782 0.000026 0.389469 0.000023 I-0.0535037 0.0000047 1.8176 0.0034 I -0.009 0.042 0.067 0.020 16 318 57405.00 I -0.018391 0.000025 0.391971 0.000022 I-0.0552954 0.0000047 1.8089 0.0041 I 0.001 0.042 0.060 0.020 16 319 57406.00 I -0.016187 0.000017 0.394472 0.000020 I-0.0571458 0.0000067 1.8730 0.0036 I 0.003 0.047 0.046 0.029 16 320 57407.00 I -0.014601 0.000025 0.396962 0.000029 I-0.0590734 0.0000055 2.0332 0.0044 I -0.007 0.052 0.033 0.049 16 321 57408.00 I -0.013767 0.000026 0.399494 0.000030 I-0.0611669 0.0000057 2.0575 0.0043 I -0.028 0.052 0.021 0.056 16 322 57409.00 I -0.013562 0.000024 0.402015 0.000024 I-0.0631898 0.0000065 2.0861 0.0043 I -0.054 0.059 0.010 0.076 16 323 57410.00 I -0.013645 0.000024 0.404333 0.000024 I-0.0653380 0.0000064 2.1115 0.0046 I -0.074 0.059 0.009 0.076 16 324 57411.00 I -0.013616 0.000024 0.406392 0.000024 I-0.0673565 0.0000066 1.9679 0.0046 I -0.088 0.059 0.018 0.076 16 325 57412.00 I -0.013255 0.000024 0.408403 0.000024 I-0.0693406 0.0000065 2.0248 0.0063 I -0.109 0.059 0.024 0.076 16 326 57413.00 I -0.012617 0.000013 0.410472 0.000013 I-0.0713968 0.0000108 2.0538 0.0066 I -0.134 0.119 0.017 0.225 16 327 57414.00 I -0.011855 0.000011 0.412577 0.000013 I-0.0734180 0.0000116 1.9922 0.0069 I -0.144 0.119 -0.003 0.150 16 328 57415.00 I -0.011092 0.000023 0.414506 0.000021 I-0.0753619 0.0000085 1.8727 0.0072 I -0.132 0.058 -0.029 0.069 16 329 57416.00 I -0.010256 0.000023 0.416297 0.000022 I-0.0771761 0.0000085 1.7914 0.0055 I -0.106 0.058 -0.054 0.069 16 330 57417.00 I -0.009394 0.000023 0.418007 0.000023 I-0.0789625 0.0000070 1.7637 0.0055 I -0.070 0.047 -0.058 0.063 16 331 57418.00 I -0.008769 0.000022 0.419685 0.000025 I-0.0807036 0.0000069 1.7363 0.0049 I -0.034 0.047 -0.029 0.063 16 4 1 57419.00 I -0.008414 0.000022 0.421202 0.000027 I-0.0824533 0.0000068 1.7634 0.0049 I -0.021 0.047 0.000 0.063 16 4 2 57420.00 I -0.008088 0.000022 0.422663 0.000027 I-0.0842517 0.0000069 1.8544 0.0042 I -0.036 0.047 -0.021 0.063 16 4 3 57421.00 I -0.007515 0.000013 0.424137 0.000024 I-0.0861632 0.0000050 1.9487 0.0047 I -0.052 0.119 -0.082 0.024 16 4 4 57422.00 I -0.006419 0.000021 0.425858 0.000023 I-0.0881549 0.0000064 2.0606 0.0045 I -0.040 0.119 -0.113 0.024 16 4 5 57423.00 I -0.004709 0.000022 0.427854 0.000022 I-0.0902894 0.0000074 2.1876 0.0049 I -0.016 0.119 -0.084 0.014 16 4 6 57424.00 I -0.002606 0.000022 0.429902 0.000021 I-0.0925256 0.0000073 2.3011 0.0052 I -0.002 0.119 -0.031 0.014 16 4 7 57425.00 I -0.000789 0.000022 0.432202 0.000018 I-0.0948791 0.0000073 2.3772 0.0052 I 0.000 0.119 0.010 0.014 16 4 8 57426.00 I 0.000664 0.000022 0.434713 0.000016 I-0.0972531 0.0000073 2.3725 0.0122 I -0.002 0.119 0.040 0.014 16 4 9 57427.00 I 0.002059 0.000023 0.437042 0.000013 I-0.0995861 0.0000232 2.2539 0.0054 I -0.006 0.119 0.063 0.150 16 410 57428.00 I 0.003347 0.000021 0.439038 0.000016 I-0.1017251 0.0000079 2.0278 0.0120 I -0.008 0.119 0.072 0.061 16 411 57429.00 I 0.004628 0.000019 0.440926 0.000015 I-0.1036627 0.0000060 1.8647 0.0049 I -0.005 0.119 0.078 0.061 16 412 57430.00 I 0.006143 0.000019 0.442665 0.000016 I-0.1054713 0.0000059 1.7520 0.0042 I 0.004 0.119 0.096 0.061 16 413 57431.00 I 0.007737 0.000020 0.444189 0.000016 I-0.1071693 0.0000060 1.6470 0.0044 I 0.019 0.119 0.114 0.061 16 414 57432.00 I 0.009116 0.000020 0.445678 0.000016 I-0.1087724 0.0000066 1.5633 0.0046 I 0.046 0.119 0.118 0.061 16 415 57433.00 I 0.010471 0.000019 0.447462 0.000017 I-0.1103218 0.0000069 1.5574 0.0087 I 0.076 0.119 0.108 0.061 16 416 57434.00 I 0.011967 0.000020 0.449627 0.000018 I-0.1119079 0.0000162 1.6135 0.0060 I 0.095 0.119 0.095 0.150 16 417 57435.00 I 0.013661 0.000025 0.451890 0.000023 I-0.1135287 0.0000097 1.6091 0.0095 I 0.099 0.119 0.086 0.013 16 418 57436.00 I 0.015451 0.000028 0.454016 0.000028 I-0.1151529 0.0000098 1.6851 0.0068 I 0.090 0.119 0.090 0.013 16 419 57437.00 I 0.017078 0.000032 0.455707 0.000031 I-0.1169025 0.0000096 1.7719 0.0070 I 0.070 0.119 0.113 0.013 16 420 57438.00 I 0.018626 0.000041 0.456788 0.000041 I-0.1186505 0.0000101 1.7201 0.0062 P 0.011 0.239 0.092 0.600 16 421 57439.00 I 0.020312 0.000044 0.457663 0.000043 I-0.1203383 0.0000079 1.6551 0.0058 P 0.002 0.239 0.097 0.600 16 422 57440.00 I 0.022149 0.000091 0.458767 0.000093 I-0.1219712 0.0000056 1.6216 0.0057 P -0.002 0.239 0.074 0.600 16 423 57441.00 I 0.024059 0.000091 0.460210 0.000092 I-0.1235866 0.0000083 1.6033 0.0048 P -0.009 0.239 0.041 0.600 16 424 57442.00 I 0.025767 0.000091 0.461829 0.000092 I-0.1251404 0.0000079 1.4728 0.0092 P -0.007 0.239 0.018 0.600 16 425 57443.00 I 0.027084 0.000091 0.463531 0.000093 I-0.1265278 0.0000165 1.3290 0.0090 P 0.013 0.239 0.007 0.600 16 426 57444.00 I 0.028086 0.000091 0.465338 0.000093 I-0.1278231 0.0000161 1.2593 0.0118 P 0.040 0.239 0.003 0.600 16 427 57445.00 I 0.028928 0.000091 0.467015 0.000092 I-0.1290372 0.0000169 1.1618 0.0123 P 0.065 0.239 0.008 0.600 16 428 57446.00 I 0.029730 0.000092 0.468564 0.000091 I-0.1303716 0.0000185 P 0.083 0.239 0.035 0.600 16 429 57447.00 P 0.030798 0.000622 0.469783 0.000448 P-0.1317429 0.0001080 P 0.085 0.239 0.066 0.600 16 430 57448.00 P 0.031994 0.000923 0.470993 0.000737 P-0.1331878 0.0002041 P 0.065 0.239 0.057 0.600 16 5 1 57449.00 P 0.033490 0.001163 0.472083 0.000987 P-0.1347405 0.0003028 P 0.040 0.239 0.007 0.600 16 5 2 57450.00 P 0.035183 0.001370 0.473116 0.001215 P-0.1364495 0.0004021 P 0.034 0.239 -0.028 0.600 16 5 3 57451.00 P 0.036987 0.001556 0.474102 0.001426 P-0.1383398 0.0005017 P 0.043 0.239 -0.006 0.600 16 5 4 57452.00 P 0.038845 0.001727 0.475046 0.001626 P-0.1403703 0.0006014 P 0.046 0.239 0.044 0.600 16 5 5 57453.00 P 0.040719 0.001885 0.475994 0.001817 P-0.1424457 0.0007012 P 0.037 0.239 0.082 0.600 16 5 6 57454.00 P 0.042581 0.002035 0.476950 0.002001 P-0.1444593 0.0007500 P 0.028 0.239 0.101 0.600 16 5 7 57455.00 P 0.044425 0.002176 0.477871 0.002178 P-0.1463307 0.0005500 P 0.014 0.239 0.107 0.600 16 5 8 57456.00 P 0.046286 0.002310 0.478748 0.002349 P-0.1480080 0.0007548 P -0.006 0.239 0.096 0.600 16 5 9 57457.00 P 0.048207 0.002439 0.479583 0.002516 P-0.1494885 0.0009344 P -0.019 0.239 0.073 0.600 16 510 57458.00 P 0.050193 0.002564 0.480379 0.002679 P-0.1508450 0.0010994 P -0.012 0.239 0.056 0.600 16 511 57459.00 P 0.052250 0.002683 0.481153 0.002838 P-0.1521313 0.0012543 P 0.016 0.239 0.051 0.600 16 512 57460.00 P 0.054368 0.002799 0.481924 0.002993 P-0.1533788 0.0014016 P 0.052 0.239 0.053 0.600 16 513 57461.00 P 0.056522 0.002911 0.482690 0.003146 P-0.1546475 0.0015429 P 0.077 0.239 0.062 0.600 16 514 57462.00 P 0.058696 0.003020 0.483452 0.003295 P-0.1559391 0.0016792 P 0.082 0.239 0.068 0.600 16 515 57463.00 P 0.060870 0.003127 0.484205 0.003442 P-0.1572557 0.0018113 P 0.077 0.239 0.061 0.600 16 516 57464.00 P 0.063031 0.003230 0.484931 0.003587 P-0.1585736 0.0019399 P 0.067 0.239 0.062 0.600 16 517 57465.00 P 0.065179 0.003331 0.485615 0.003729 P-0.1598755 0.0020652 P 0.046 0.239 0.087 0.600 16 518 57466.00 P 0.067327 0.003430 0.486255 0.003870 P-0.1611463 0.0021877 P 0.017 0.239 0.124 0.600 16 519 57467.00 P 0.069480 0.003527 0.486853 0.004008 P-0.1623693 0.0023077 P -0.001 0.239 0.132 0.600 16 520 57468.00 P 0.071641 0.003621 0.487411 0.004145 P-0.1635235 0.0024255 P 0.001 0.239 0.103 0.600 16 521 57469.00 P 0.073815 0.003714 0.487931 0.004279 P-0.1645892 0.0025411 P 0.009 0.239 0.066 0.600 16 522 57470.00 P 0.076004 0.003806 0.488420 0.004413 P-0.1655561 0.0026548 P 0.018 0.239 0.050 0.600 16 523 57471.00 P 0.078203 0.003895 0.488880 0.004544 P-0.1664451 0.0027668 P 0.037 0.239 0.053 0.600 16 524 57472.00 P 0.080408 0.003983 0.489309 0.004674 P-0.1672908 0.0028772 P 0.059 0.239 0.062 0.600 16 525 57473.00 P 0.082617 0.004070 0.489704 0.004803 P-0.1681336 0.0029860 P 0.067 0.239 0.075 0.600 16 526 57474.00 P 0.084827 0.004155 0.490064 0.004930 P-0.1690194 0.0030934 P 0.059 0.239 0.093 0.600 16 527 57475.00 P 0.087040 0.004239 0.490383 0.005057 P-0.1699970 0.0031995 P 0.047 0.239 0.110 0.600 16 528 57476.00 P 0.089257 0.004322 0.490663 0.005182 P-0.1710955 0.0033043 P 0.037 0.239 0.111 0.600 16 529 57477.00 P 0.091478 0.004403 0.490904 0.005305 P-0.1723451 0.0034080 P 0.027 0.239 0.088 0.600 16 530 57478.00 P 0.093706 0.004484 0.491106 0.005428 P-0.1737501 0.0035105 P 0.023 0.239 0.065 0.600 16 531 57479.00 P 0.095941 0.004563 0.491273 0.005550 P-0.1752782 0.0036120 P 0.025 0.239 0.063 0.600 16 6 1 57480.00 P 0.098182 0.004641 0.491405 0.005670 P-0.1768742 0.0037124 P 0.023 0.239 0.083 0.600 16 6 2 57481.00 P 0.100428 0.004719 0.491506 0.005790 P-0.1784618 0.0038119 P 0.012 0.239 0.109 0.600 16 6 3 57482.00 P 0.102675 0.004795 0.491574 0.005908 P-0.1799593 0.0039105 P 0.000 0.239 0.131 0.600 16 6 4 57483.00 P 0.104924 0.004871 0.491610 0.006026 P-0.1813071 0.0040082 P -0.005 0.239 0.137 0.600 16 6 5 57484.00 P 0.107172 0.004945 0.491612 0.006143 P-0.1824904 0.0041051 P -0.005 0.239 0.124 0.600 16 6 6 57485.00 P 0.109420 0.005019 0.491579 0.006259 P-0.1835411 0.0042012 P -0.003 0.239 0.101 0.600 16 6 7 57486.00 P 0.111667 0.005092 0.491512 0.006374 P-0.1845091 0.0042965 P 0.007 0.239 0.085 0.600 16 6 8 57487.00 P 0.113913 0.005164 0.491411 0.006488 P-0.1854466 0.0043911 P 0.030 0.239 0.084 0.600 16 6 9 57488.00 P 0.116157 0.005235 0.491274 0.006602 P-0.1863873 0.0044849 P 0.055 0.239 0.098 0.600 16 610 57489.00 P 0.118399 0.005306 0.491104 0.006715 P-0.1873523 0.0045781 P 0.065 0.239 0.127 0.600 16 611 57490.00 P 0.120639 0.005376 0.490901 0.006827 P-0.1883409 0.0046706 P 0.060 0.239 0.154 0.600 16 612 57491.00 P 0.122875 0.005445 0.490664 0.006938 P-0.1893388 0.0047625 P 0.052 0.239 0.159 0.600 16 613 57492.00 P 0.125106 0.005514 0.490394 0.007049 P-0.1903249 0.0048537 P 0.046 0.239 0.145 0.600 16 614 57493.00 P 0.127331 0.005582 0.490090 0.007159 P-0.1912717 0.0049444 P 0.032 0.239 0.141 0.600 16 615 57494.00 P 0.129551 0.005650 0.489753 0.007268 P-0.1921561 0.0050344 P 0.005 0.239 0.154 0.600 16 616 57495.00 P 0.131763 0.005716 0.489382 0.007377 P-0.1929601 0.0051240 P -0.012 0.239 0.159 0.600 16 617 57496.00 P 0.133969 0.005782 0.488978 0.007485 P-0.1936729 0.0052129 P -0.009 0.239 0.143 0.600 16 618 57497.00 P 0.136167 0.005848 0.488539 0.007592 P-0.1942946 0.0053014 P 0.004 0.239 0.122 0.600 16 619 57498.00 P 0.138356 0.005913 0.488067 0.007699 P-0.1948369 0.0053893 P 0.015 0.239 0.115 0.600 16 620 57499.00 P 0.140538 0.005978 0.487561 0.007806 P-0.1953178 0.0054768 P 0.029 0.239 0.117 0.600 16 621 57500.00 P 0.142710 0.006042 0.487022 0.007911 P-0.1957658 0.0055637 P 0.048 0.239 0.121 0.600 16 622 57501.00 P 0.144872 0.006105 0.486450 0.008017 P-0.1962213 0.0056502 P 0.056 0.239 0.132 0.600 16 623 57502.00 P 0.147024 0.006168 0.485846 0.008121 P-0.1967329 0.0057362 P 0.040 0.239 0.147 0.600 16 624 57503.00 P 0.149165 0.006231 0.485208 0.008226 P-0.1973441 0.0058218 P 0.019 0.239 0.155 0.600 16 625 57504.00 P 0.151294 0.006293 0.484538 0.008329 P-0.1980871 0.0059070 P 0.009 0.239 0.148 0.600 16 626 57505.00 P 0.153411 0.006355 0.483836 0.008432 P-0.1989695 0.0059917 P 0.009 0.239 0.141 0.600 16 627 57506.00 P 0.155515 0.006416 0.483101 0.008535 P-0.1999726 0.0060760 P 0.010 0.239 0.141 0.600 16 628 57507.00 P 0.157606 0.006477 0.482334 0.008637 P-0.2010510 0.0061599 P 0.007 0.239 0.138 0.600 16 629 57508.00 P 0.159683 0.006537 0.481535 0.008739 P-0.2021438 0.0062434 P 0.002 0.239 0.130 0.600 16 630 57509.00 P 0.161745 0.006597 0.480705 0.008840 P-0.2031853 0.0063266 P -0.007 0.239 0.133 0.600 16 7 1 57510.00 P 0.163793 0.006656 0.479843 0.008941 P-0.2041214 0.0064093 P -0.016 0.239 0.151 0.600 16 7 2 57511.00 P 0.165825 0.006715 0.478950 0.009041 P-0.2049288 0.0064917 P -0.018 0.239 0.166 0.600 16 7 3 57512.00 P 0.167840 0.006774 0.478026 0.009141 P-0.2056188 0.0065737 P -0.007 0.239 0.157 0.600 16 7 4 57513.00 P 0.169839 0.006832 0.477071 0.009241 P-0.2062331 0.0066554 P 0.011 0.239 0.140 0.600 16 7 5 57514.00 P 0.171821 0.006890 0.476086 0.009340 P-0.2068275 0.0067368 P 0.024 0.239 0.138 0.600 16 7 6 57515.00 P 0.173785 0.006948 0.475071 0.009439 P-0.2074512 0.0068177 P 0.031 0.239 0.152 0.600 16 7 7 57516.00 P 0.175730 0.007005 0.474025 0.009537 P-0.2081302 0.0068984 P 0.033 0.239 0.174 0.600 16 7 8 57517.00 P 0.177656 0.007062 0.472950 0.009635 P-0.2088663 0.0069788 P 0.031 0.239 0.202 0.600 16 7 9 57518.00 P 0.179563 0.007118 0.471846 0.009732 P-0.2096451 0.0070588 P 0.027 0.239 0.235 0.600 16 710 57519.00 P 0.181450 0.007175 0.470713 0.009829 P-0.2104419 0.0071385 P 0.025 0.239 0.250 0.600 16 711 57520.00 P 0.183317 0.007230 0.469550 0.009926 P-0.2112284 0.0072179 P 0.024 0.239 0.237 0.600 16 712 57521.00 P 0.185162 0.007286 0.468360 0.010023 P-0.2119781 0.0072970 P 0.013 0.239 0.216 0.600 16 713 57522.00 P 0.186986 0.007341 0.467141 0.010119 P-0.2126684 0.0073758 P -0.003 0.239 0.205 0.600 16 714 57523.00 P 0.188788 0.007396 0.465894 0.010214 P-0.2132848 0.0074544 P -0.011 0.239 0.203 0.600 16 715 57524.00 P 0.190567 0.007451 0.464620 0.010310 P-0.2138206 0.0075326 P -0.007 0.239 0.193 0.600 16 716 57525.00 P 0.192324 0.007505 0.463319 0.010405 P-0.2142803 0.0076106 P 0.000 0.239 0.179 0.600 16 717 57526.00 P 0.194056 0.007559 0.461990 0.010499 P-0.2146833 0.0076883 P 0.004 0.239 0.170 0.600 16 718 57527.00 P 0.195765 0.007613 0.460636 0.010594 P-0.2150602 0.0077657 P 0.013 0.239 0.165 0.600 16 719 57528.00 P 0.197449 0.007666 0.459255 0.010688 P-0.2154534 0.0078428 16 720 57529.00 P 0.199109 0.007719 0.457848 0.010781 P-0.2159127 0.0079197 16 721 57530.00 P 0.200742 0.007772 0.456416 0.010875 P-0.2164842 0.0079964 16 722 57531.00 P 0.202351 0.007825 0.454960 0.010968 P-0.2172005 0.0080728 16 723 57532.00 P 0.203932 0.007877 0.453478 0.011060 P-0.2180702 0.0081489 16 724 57533.00 P 0.205487 0.007929 0.451972 0.011153 P-0.2190692 0.0082248 16 725 57534.00 P 0.207015 0.007981 0.450443 0.011245 P-0.2201448 0.0083005 16 726 57535.00 P 0.208515 0.008033 0.448890 0.011337 P-0.2212286 0.0083759 16 727 57536.00 P 0.209988 0.008084 0.447315 0.011428 P-0.2222556 0.0084511 16 728 57537.00 P 0.211431 0.008135 0.445716 0.011520 P-0.2231750 0.0085261 16 729 57538.00 P 0.212846 0.008186 0.444096 0.011611 P-0.2239618 0.0086008 16 730 57539.00 P 0.214232 0.008236 0.442454 0.011701 P-0.2246227 0.0086754 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/iers/tests/data/finals2000A-2016-04-30-test0000644000175100001710000010217500000000000023737 0ustar00vstsdocker16 2 1 57419.00 I -0.003225 0.000031 0.299494 0.000025 I 0.0262864 0.0000042 1.3154 0.0035 I -0.094 0.119 -0.077 0.029 -0.003291 0.299534 0.0262719 -0.094 -0.169 16 2 2 57420.00 I -0.004706 0.000030 0.301252 0.000024 I 0.0249911 0.0000057 1.2412 0.0034 I -0.108 0.119 -0.082 0.035 -0.004751 0.301342 0.0249958 -0.128 -0.151 16 2 3 57421.00 I -0.005690 0.000031 0.302711 0.000025 I 0.0238039 0.0000054 1.1674 0.0040 I -0.112 0.045 -0.102 0.034 -0.005725 0.302649 0.0238016 -0.137 -0.154 16 2 4 57422.00 I -0.006490 0.000030 0.304493 0.000023 I 0.0226216 0.0000057 1.1976 0.0040 I -0.105 0.045 -0.115 0.034 -0.006418 0.304497 0.0226308 -0.139 -0.163 16 2 5 57423.00 I -0.007499 0.000030 0.306410 0.000020 I 0.0214229 0.0000059 1.1850 0.0048 I -0.094 0.045 -0.114 0.034 -0.007481 0.306466 0.0214306 -0.142 -0.171 16 2 6 57424.00 I -0.008637 0.000024 0.308121 0.000018 I 0.0201799 0.0000077 1.3874 0.0042 I -0.094 0.070 -0.115 0.034 -0.008646 0.308134 0.0201501 -0.145 -0.180 16 2 7 57425.00 I -0.009431 0.000032 0.309779 0.000020 I 0.0186616 0.0000061 1.5494 0.0050 I -0.103 0.053 -0.117 0.032 -0.009564 0.309799 0.0187256 -0.146 -0.188 16 2 8 57426.00 I -0.009639 0.000035 0.311456 0.000019 I 0.0171013 0.0000064 1.6508 0.0052 I -0.118 0.052 -0.112 0.039 -0.009602 0.311455 0.0171286 -0.150 -0.197 16 2 9 57427.00 I -0.009707 0.000034 0.313146 0.000017 I 0.0153086 0.0000083 1.9064 0.0048 I -0.137 0.119 -0.106 0.046 -0.009695 0.313158 0.0153216 -0.151 -0.205 16 210 57428.00 I -0.009949 0.000035 0.315007 0.000024 I 0.0133131 0.0000072 2.0881 0.0053 I -0.163 0.119 -0.110 0.053 -0.009848 0.314971 0.0133091 -0.162 -0.134 16 211 57429.00 I -0.010522 0.000036 0.317056 0.000024 I 0.0111967 0.0000067 2.0770 0.0049 I -0.189 0.119 -0.121 0.053 -0.010525 0.317115 0.0112339 -0.182 -0.133 16 212 57430.00 I -0.011219 0.000037 0.319016 0.000025 I 0.0091589 0.0000066 2.0665 0.0055 I -0.206 0.119 -0.119 0.053 -0.011200 0.319001 0.0091407 -0.206 -0.158 16 213 57431.00 I -0.011874 0.000031 0.321066 0.000024 I 0.0070911 0.0000088 1.9738 0.0047 I -0.211 0.119 -0.106 0.072 -0.011889 0.321068 0.0071356 -0.208 -0.158 16 214 57432.00 I -0.012456 0.000029 0.323240 0.000028 I 0.0052399 0.0000068 1.7954 0.0055 I -0.210 0.119 -0.093 0.047 -0.012445 0.323271 0.0052511 -0.202 -0.149 16 215 57433.00 I -0.013108 0.000027 0.325311 0.000027 I 0.0034804 0.0000065 1.6767 0.0047 I -0.209 0.119 -0.080 0.056 -0.013071 0.325381 0.0035069 -0.194 -0.140 16 216 57434.00 I -0.013911 0.000023 0.327010 0.000022 I 0.0019144 0.0000065 1.4745 0.0042 I -0.203 0.045 -0.057 0.050 -0.013912 0.327076 0.0019126 -0.187 -0.130 16 217 57435.00 I -0.014798 0.000021 0.328533 0.000023 I 0.0004966 0.0000052 1.3769 0.0045 I -0.186 0.045 -0.032 0.050 -0.014734 0.328472 0.0004608 -0.191 -0.037 16 218 57436.00 I -0.015972 0.000018 0.330387 0.000023 I-0.0008425 0.0000063 1.2886 0.0043 I -0.166 0.045 -0.025 0.050 -0.015929 0.330417 -0.0008581 -0.186 -0.027 16 219 57437.00 I -0.017359 0.000017 0.332361 0.000022 I-0.0021162 0.0000068 1.3072 0.0107 I -0.150 0.045 -0.032 0.050 -0.017369 0.332401 -0.0021130 -0.179 -0.049 16 220 57438.00 I -0.018572 0.000019 0.334012 0.000020 I-0.0034607 0.0000205 1.3373 0.0040 I -0.135 0.082 -0.033 0.156 -0.018639 0.334094 -0.0034487 -0.171 -0.071 16 221 57439.00 I -0.019315 0.000033 0.335553 0.000023 I-0.0048274 0.0000044 1.4772 0.0105 I -0.120 0.119 -0.029 0.011 -0.019329 0.335459 -0.0048827 -0.164 -0.092 16 222 57440.00 I -0.019952 0.000034 0.337603 0.000023 I-0.0064226 0.0000046 1.6395 0.0033 I -0.108 0.119 -0.038 0.011 -0.019862 0.337623 -0.0064324 -0.156 -0.114 16 223 57441.00 I -0.020869 0.000035 0.339814 0.000022 I-0.0080691 0.0000049 1.6897 0.0032 I -0.103 0.119 -0.063 0.027 -0.020905 0.339830 -0.0080787 -0.149 -0.136 16 224 57442.00 I -0.021582 0.000037 0.342052 0.000026 I-0.0098083 0.0000045 1.7588 0.0034 I -0.096 0.119 -0.079 0.033 -0.021616 0.342062 -0.0097889 -0.143 -0.149 16 225 57443.00 I -0.021898 0.000037 0.344332 0.000025 I-0.0115839 0.0000046 1.8195 0.0036 I -0.093 0.119 -0.073 0.033 -0.021911 0.344416 -0.0115637 -0.139 -0.160 16 226 57444.00 I -0.022036 0.000036 0.346321 0.000022 I-0.0134316 0.0000055 1.8329 0.0048 I -0.102 0.119 -0.062 0.033 -0.022011 0.346307 -0.0134119 -0.133 -0.171 16 227 57445.00 I -0.022387 0.000024 0.348429 0.000019 I-0.0152292 0.0000084 1.7846 0.0042 I -0.118 0.119 -0.064 0.059 -0.022273 0.348402 -0.0152189 -0.129 -0.181 16 228 57446.00 I -0.023235 0.000025 0.350749 0.000020 I-0.0170194 0.0000064 1.7921 0.0052 I -0.122 0.119 -0.082 0.035 -0.023218 0.350815 -0.0169781 -0.124 -0.192 16 229 57447.00 I -0.024219 0.000023 0.352784 0.000020 I-0.0187707 0.0000062 1.6716 0.0053 I -0.111 0.119 -0.105 0.027 -0.024254 0.352863 -0.0186952 -0.119 -0.203 16 3 1 57448.00 I -0.024807 0.000023 0.354400 0.000014 I-0.0203703 0.0000084 1.5743 0.0046 I -0.088 0.119 -0.125 0.011 -0.024918 0.354451 -0.0203678 -0.114 -0.214 16 3 2 57449.00 I -0.024651 0.000025 0.355942 0.000020 I-0.0219780 0.0000067 1.6532 0.0052 I -0.055 0.119 -0.125 0.049 16 3 3 57450.00 I -0.024054 0.000025 0.357866 0.000019 I-0.0236772 0.0000060 1.7337 0.0044 I -0.016 0.119 -0.093 0.049 16 3 4 57451.00 I -0.023735 0.000027 0.360180 0.000019 I-0.0254270 0.0000057 1.7591 0.0052 I 0.008 0.119 -0.056 0.049 16 3 5 57452.00 I -0.023740 0.000026 0.362598 0.000018 I-0.0272149 0.0000084 1.8430 0.0041 I 0.011 0.119 -0.053 0.091 16 3 6 57453.00 I -0.023745 0.000027 0.365029 0.000018 I-0.0291495 0.0000060 2.0365 0.0052 I 0.010 0.119 -0.081 0.052 16 3 7 57454.00 I -0.024021 0.000024 0.367538 0.000018 I-0.0312844 0.0000060 2.2194 0.0045 I 0.021 0.119 -0.095 0.052 16 3 8 57455.00 I -0.024457 0.000021 0.370024 0.000012 I-0.0335554 0.0000066 2.3035 0.0044 I 0.036 0.119 -0.085 0.026 16 3 9 57456.00 I -0.024829 0.000022 0.372483 0.000011 I-0.0359012 0.0000065 2.4168 0.0045 I 0.037 0.119 -0.072 0.026 16 310 57457.00 I -0.025066 0.000020 0.374873 0.000011 I-0.0383738 0.0000062 2.4843 0.0044 I 0.025 0.119 -0.063 0.026 16 311 57458.00 I -0.025097 0.000017 0.377004 0.000011 I-0.0408388 0.0000060 2.4588 0.0080 I 0.011 0.119 -0.053 0.026 16 312 57459.00 I -0.025181 0.000017 0.378932 0.000012 I-0.0432700 0.0000148 2.3690 0.0040 I 0.008 0.119 -0.040 0.150 16 313 57460.00 I -0.025188 0.000024 0.380780 0.000016 I-0.0455624 0.0000054 2.2359 0.0079 I 0.013 0.119 -0.031 0.150 16 314 57461.00 I -0.024758 0.000026 0.382629 0.000016 I-0.0477465 0.0000056 2.1168 0.0038 I 0.011 0.119 -0.012 0.150 16 315 57462.00 I -0.023945 0.000025 0.384773 0.000017 I-0.0497744 0.0000053 1.9330 0.0037 I -0.002 0.119 0.022 0.150 16 316 57463.00 I -0.022702 0.000026 0.387109 0.000023 I-0.0516492 0.0000048 1.8593 0.0035 I -0.012 0.042 0.057 0.020 16 317 57464.00 I -0.020782 0.000026 0.389469 0.000023 I-0.0535037 0.0000047 1.8176 0.0034 I -0.009 0.042 0.067 0.020 16 318 57465.00 I -0.018391 0.000025 0.391971 0.000022 I-0.0552954 0.0000047 1.8089 0.0041 I 0.001 0.042 0.060 0.020 16 319 57466.00 I -0.016187 0.000017 0.394472 0.000020 I-0.0571458 0.0000067 1.8730 0.0036 I 0.003 0.047 0.046 0.029 16 320 57467.00 I -0.014601 0.000025 0.396962 0.000029 I-0.0590734 0.0000055 2.0332 0.0044 I -0.007 0.052 0.033 0.049 16 321 57468.00 I -0.013767 0.000026 0.399494 0.000030 I-0.0611669 0.0000057 2.0575 0.0043 I -0.028 0.052 0.021 0.056 16 322 57469.00 I -0.013562 0.000024 0.402015 0.000024 I-0.0631898 0.0000065 2.0861 0.0043 I -0.054 0.059 0.010 0.076 16 323 57470.00 I -0.013645 0.000024 0.404333 0.000024 I-0.0653380 0.0000064 2.1115 0.0046 I -0.074 0.059 0.009 0.076 16 324 57471.00 I -0.013616 0.000024 0.406392 0.000024 I-0.0673565 0.0000066 1.9679 0.0046 I -0.088 0.059 0.018 0.076 16 325 57472.00 I -0.013255 0.000024 0.408403 0.000024 I-0.0693406 0.0000065 2.0248 0.0063 I -0.109 0.059 0.024 0.076 16 326 57473.00 I -0.012617 0.000013 0.410472 0.000013 I-0.0713968 0.0000108 2.0538 0.0066 I -0.134 0.119 0.017 0.225 16 327 57474.00 I -0.011855 0.000011 0.412577 0.000013 I-0.0734180 0.0000116 1.9922 0.0069 I -0.144 0.119 -0.003 0.150 16 328 57475.00 I -0.011092 0.000023 0.414506 0.000021 I-0.0753619 0.0000085 1.8727 0.0072 I -0.132 0.058 -0.029 0.069 16 329 57476.00 I -0.010256 0.000023 0.416297 0.000022 I-0.0771761 0.0000085 1.7914 0.0055 I -0.106 0.058 -0.054 0.069 16 330 57477.00 I -0.009394 0.000023 0.418007 0.000023 I-0.0789625 0.0000070 1.7637 0.0055 I -0.070 0.047 -0.058 0.063 16 331 57478.00 I -0.008769 0.000022 0.419685 0.000025 I-0.0807036 0.0000069 1.7363 0.0049 I -0.034 0.047 -0.029 0.063 16 4 1 57479.00 I -0.008414 0.000022 0.421202 0.000027 I-0.0824533 0.0000068 1.7634 0.0049 I -0.021 0.047 0.000 0.063 16 4 2 57480.00 I -0.008088 0.000022 0.422663 0.000027 I-0.0842517 0.0000069 1.8544 0.0042 I -0.036 0.047 -0.021 0.063 16 4 3 57481.00 I -0.007515 0.000013 0.424137 0.000024 I-0.0861632 0.0000050 1.9487 0.0047 I -0.052 0.119 -0.082 0.024 16 4 4 57482.00 I -0.006419 0.000021 0.425858 0.000023 I-0.0881549 0.0000064 2.0606 0.0045 I -0.040 0.119 -0.113 0.024 16 4 5 57483.00 I -0.004709 0.000022 0.427854 0.000022 I-0.0902894 0.0000074 2.1876 0.0049 I -0.016 0.119 -0.084 0.014 16 4 6 57484.00 I -0.002606 0.000022 0.429902 0.000021 I-0.0925256 0.0000073 2.3011 0.0052 I -0.002 0.119 -0.031 0.014 16 4 7 57485.00 I -0.000789 0.000022 0.432202 0.000018 I-0.0948791 0.0000073 2.3772 0.0052 I 0.000 0.119 0.010 0.014 16 4 8 57486.00 I 0.000664 0.000022 0.434713 0.000016 I-0.0972531 0.0000073 2.3725 0.0122 I -0.002 0.119 0.040 0.014 16 4 9 57487.00 I 0.002059 0.000023 0.437042 0.000013 I-0.0995861 0.0000232 2.2539 0.0054 I -0.006 0.119 0.063 0.150 16 410 57488.00 I 0.003347 0.000021 0.439038 0.000016 I-0.1017251 0.0000079 2.0278 0.0120 I -0.008 0.119 0.072 0.061 16 411 57489.00 I 0.004628 0.000019 0.440926 0.000015 I-0.1036627 0.0000060 1.8647 0.0049 I -0.005 0.119 0.078 0.061 16 412 57490.00 I 0.006143 0.000019 0.442665 0.000016 I-0.1054713 0.0000059 1.7520 0.0042 I 0.004 0.119 0.096 0.061 16 413 57491.00 I 0.007737 0.000020 0.444189 0.000016 I-0.1071693 0.0000060 1.6470 0.0044 I 0.019 0.119 0.114 0.061 16 414 57492.00 I 0.009116 0.000020 0.445678 0.000016 I-0.1087724 0.0000066 1.5633 0.0046 I 0.046 0.119 0.118 0.061 16 415 57493.00 I 0.010471 0.000019 0.447462 0.000017 I-0.1103218 0.0000069 1.5574 0.0087 I 0.076 0.119 0.108 0.061 16 416 57494.00 I 0.011967 0.000020 0.449627 0.000018 I-0.1119079 0.0000162 1.6135 0.0060 I 0.095 0.119 0.095 0.150 16 417 57495.00 I 0.013661 0.000025 0.451890 0.000023 I-0.1135287 0.0000097 1.6091 0.0095 I 0.099 0.119 0.086 0.013 16 418 57496.00 I 0.015451 0.000028 0.454016 0.000028 I-0.1151529 0.0000098 1.6851 0.0068 I 0.090 0.119 0.090 0.013 16 419 57497.00 I 0.017078 0.000032 0.455707 0.000031 I-0.1169025 0.0000096 1.7719 0.0070 I 0.070 0.119 0.113 0.013 16 420 57498.00 I 0.018626 0.000041 0.456788 0.000041 I-0.1186505 0.0000101 1.7201 0.0062 P 0.011 0.239 0.092 0.600 16 421 57499.00 I 0.020312 0.000044 0.457663 0.000043 I-0.1203383 0.0000079 1.6551 0.0058 P 0.002 0.239 0.097 0.600 16 422 57500.00 I 0.022149 0.000091 0.458767 0.000093 I-0.1219712 0.0000056 1.6216 0.0057 P -0.002 0.239 0.074 0.600 16 423 57501.00 I 0.024059 0.000091 0.460210 0.000092 I-0.1235866 0.0000083 1.6033 0.0048 P -0.009 0.239 0.041 0.600 16 424 57502.00 I 0.025767 0.000091 0.461829 0.000092 I-0.1251404 0.0000079 1.4728 0.0092 P -0.007 0.239 0.018 0.600 16 425 57503.00 I 0.027084 0.000091 0.463531 0.000093 I-0.1265278 0.0000165 1.3290 0.0090 P 0.013 0.239 0.007 0.600 16 426 57504.00 I 0.028086 0.000091 0.465338 0.000093 I-0.1278231 0.0000161 1.2593 0.0118 P 0.040 0.239 0.003 0.600 16 427 57505.00 I 0.028928 0.000091 0.467015 0.000092 I-0.1290372 0.0000169 1.1618 0.0123 P 0.065 0.239 0.008 0.600 16 428 57506.00 I 0.029730 0.000092 0.468564 0.000091 I-0.1303716 0.0000185 P 0.083 0.239 0.035 0.600 16 429 57507.00 P 0.030798 0.000622 0.469783 0.000448 P-0.1317429 0.0001080 P 0.085 0.239 0.066 0.600 16 430 57508.00 P 0.031994 0.000923 0.470993 0.000737 P-0.1331878 0.0002041 P 0.065 0.239 0.057 0.600 16 5 1 57509.00 P 0.033490 0.001163 0.472083 0.000987 P-0.1347405 0.0003028 P 0.040 0.239 0.007 0.600 16 5 2 57510.00 P 0.035183 0.001370 0.473116 0.001215 P-0.1364495 0.0004021 P 0.034 0.239 -0.028 0.600 16 5 3 57511.00 P 0.036987 0.001556 0.474102 0.001426 P-0.1383398 0.0005017 P 0.043 0.239 -0.006 0.600 16 5 4 57512.00 P 0.038845 0.001727 0.475046 0.001626 P-0.1403703 0.0006014 P 0.046 0.239 0.044 0.600 16 5 5 57513.00 P 0.040719 0.001885 0.475994 0.001817 P-0.1424457 0.0007012 P 0.037 0.239 0.082 0.600 16 5 6 57514.00 P 0.042581 0.002035 0.476950 0.002001 P-0.1444593 0.0007500 P 0.028 0.239 0.101 0.600 16 5 7 57515.00 P 0.044425 0.002176 0.477871 0.002178 P-0.1463307 0.0005500 P 0.014 0.239 0.107 0.600 16 5 8 57516.00 P 0.046286 0.002310 0.478748 0.002349 P-0.1480080 0.0007548 P -0.006 0.239 0.096 0.600 16 5 9 57517.00 P 0.048207 0.002439 0.479583 0.002516 P-0.1494885 0.0009344 P -0.019 0.239 0.073 0.600 16 510 57518.00 P 0.050193 0.002564 0.480379 0.002679 P-0.1508450 0.0010994 P -0.012 0.239 0.056 0.600 16 511 57519.00 P 0.052250 0.002683 0.481153 0.002838 P-0.1521313 0.0012543 P 0.016 0.239 0.051 0.600 16 512 57520.00 P 0.054368 0.002799 0.481924 0.002993 P-0.1533788 0.0014016 P 0.052 0.239 0.053 0.600 16 513 57521.00 P 0.056522 0.002911 0.482690 0.003146 P-0.1546475 0.0015429 P 0.077 0.239 0.062 0.600 16 514 57522.00 P 0.058696 0.003020 0.483452 0.003295 P-0.1559391 0.0016792 P 0.082 0.239 0.068 0.600 16 515 57523.00 P 0.060870 0.003127 0.484205 0.003442 P-0.1572557 0.0018113 P 0.077 0.239 0.061 0.600 16 516 57524.00 P 0.063031 0.003230 0.484931 0.003587 P-0.1585736 0.0019399 P 0.067 0.239 0.062 0.600 16 517 57525.00 P 0.065179 0.003331 0.485615 0.003729 P-0.1598755 0.0020652 P 0.046 0.239 0.087 0.600 16 518 57526.00 P 0.067327 0.003430 0.486255 0.003870 P-0.1611463 0.0021877 P 0.017 0.239 0.124 0.600 16 519 57527.00 P 0.069480 0.003527 0.486853 0.004008 P-0.1623693 0.0023077 P -0.001 0.239 0.132 0.600 16 520 57528.00 P 0.071641 0.003621 0.487411 0.004145 P-0.1635235 0.0024255 P 0.001 0.239 0.103 0.600 16 521 57529.00 P 0.073815 0.003714 0.487931 0.004279 P-0.1645892 0.0025411 P 0.009 0.239 0.066 0.600 16 522 57530.00 P 0.076004 0.003806 0.488420 0.004413 P-0.1655561 0.0026548 P 0.018 0.239 0.050 0.600 16 523 57531.00 P 0.078203 0.003895 0.488880 0.004544 P-0.1664451 0.0027668 P 0.037 0.239 0.053 0.600 16 524 57532.00 P 0.080408 0.003983 0.489309 0.004674 P-0.1672908 0.0028772 P 0.059 0.239 0.062 0.600 16 525 57533.00 P 0.082617 0.004070 0.489704 0.004803 P-0.1681336 0.0029860 P 0.067 0.239 0.075 0.600 16 526 57534.00 P 0.084827 0.004155 0.490064 0.004930 P-0.1690194 0.0030934 P 0.059 0.239 0.093 0.600 16 527 57535.00 P 0.087040 0.004239 0.490383 0.005057 P-0.1699970 0.0031995 P 0.047 0.239 0.110 0.600 16 528 57536.00 P 0.089257 0.004322 0.490663 0.005182 P-0.1710955 0.0033043 P 0.037 0.239 0.111 0.600 16 529 57537.00 P 0.091478 0.004403 0.490904 0.005305 P-0.1723451 0.0034080 P 0.027 0.239 0.088 0.600 16 530 57538.00 P 0.093706 0.004484 0.491106 0.005428 P-0.1737501 0.0035105 P 0.023 0.239 0.065 0.600 16 531 57539.00 P 0.095941 0.004563 0.491273 0.005550 P-0.1752782 0.0036120 P 0.025 0.239 0.063 0.600 16 6 1 57540.00 P 0.098182 0.004641 0.491405 0.005670 P-0.1768742 0.0037124 P 0.023 0.239 0.083 0.600 16 6 2 57541.00 P 0.100428 0.004719 0.491506 0.005790 P-0.1784618 0.0038119 P 0.012 0.239 0.109 0.600 16 6 3 57542.00 P 0.102675 0.004795 0.491574 0.005908 P-0.1799593 0.0039105 P 0.000 0.239 0.131 0.600 16 6 4 57543.00 P 0.104924 0.004871 0.491610 0.006026 P-0.1813071 0.0040082 P -0.005 0.239 0.137 0.600 16 6 5 57544.00 P 0.107172 0.004945 0.491612 0.006143 P-0.1824904 0.0041051 P -0.005 0.239 0.124 0.600 16 6 6 57545.00 P 0.109420 0.005019 0.491579 0.006259 P-0.1835411 0.0042012 P -0.003 0.239 0.101 0.600 16 6 7 57546.00 P 0.111667 0.005092 0.491512 0.006374 P-0.1845091 0.0042965 P 0.007 0.239 0.085 0.600 16 6 8 57547.00 P 0.113913 0.005164 0.491411 0.006488 P-0.1854466 0.0043911 P 0.030 0.239 0.084 0.600 16 6 9 57548.00 P 0.116157 0.005235 0.491274 0.006602 P-0.1863873 0.0044849 P 0.055 0.239 0.098 0.600 16 610 57549.00 P 0.118399 0.005306 0.491104 0.006715 P-0.1873523 0.0045781 P 0.065 0.239 0.127 0.600 16 611 57550.00 P 0.120639 0.005376 0.490901 0.006827 P-0.1883409 0.0046706 P 0.060 0.239 0.154 0.600 16 612 57551.00 P 0.122875 0.005445 0.490664 0.006938 P-0.1893388 0.0047625 P 0.052 0.239 0.159 0.600 16 613 57552.00 P 0.125106 0.005514 0.490394 0.007049 P-0.1903249 0.0048537 P 0.046 0.239 0.145 0.600 16 614 57553.00 P 0.127331 0.005582 0.490090 0.007159 P-0.1912717 0.0049444 P 0.032 0.239 0.141 0.600 16 615 57554.00 P 0.129551 0.005650 0.489753 0.007268 P-0.1921561 0.0050344 P 0.005 0.239 0.154 0.600 16 616 57555.00 P 0.131763 0.005716 0.489382 0.007377 P-0.1929601 0.0051240 P -0.012 0.239 0.159 0.600 16 617 57556.00 P 0.133969 0.005782 0.488978 0.007485 P-0.1936729 0.0052129 P -0.009 0.239 0.143 0.600 16 618 57557.00 P 0.136167 0.005848 0.488539 0.007592 P-0.1942946 0.0053014 P 0.004 0.239 0.122 0.600 16 619 57558.00 P 0.138356 0.005913 0.488067 0.007699 P-0.1948369 0.0053893 P 0.015 0.239 0.115 0.600 16 620 57559.00 P 0.140538 0.005978 0.487561 0.007806 P-0.1953178 0.0054768 P 0.029 0.239 0.117 0.600 16 621 57560.00 P 0.142710 0.006042 0.487022 0.007911 P-0.1957658 0.0055637 P 0.048 0.239 0.121 0.600 16 622 57561.00 P 0.144872 0.006105 0.486450 0.008017 P-0.1962213 0.0056502 P 0.056 0.239 0.132 0.600 16 623 57562.00 P 0.147024 0.006168 0.485846 0.008121 P-0.1967329 0.0057362 P 0.040 0.239 0.147 0.600 16 624 57563.00 P 0.149165 0.006231 0.485208 0.008226 P-0.1973441 0.0058218 P 0.019 0.239 0.155 0.600 16 625 57564.00 P 0.151294 0.006293 0.484538 0.008329 P-0.1980871 0.0059070 P 0.009 0.239 0.148 0.600 16 626 57565.00 P 0.153411 0.006355 0.483836 0.008432 P-0.1989695 0.0059917 P 0.009 0.239 0.141 0.600 16 627 57566.00 P 0.155515 0.006416 0.483101 0.008535 P-0.1999726 0.0060760 P 0.010 0.239 0.141 0.600 16 628 57567.00 P 0.157606 0.006477 0.482334 0.008637 P-0.2010510 0.0061599 P 0.007 0.239 0.138 0.600 16 629 57568.00 P 0.159683 0.006537 0.481535 0.008739 P-0.2021438 0.0062434 P 0.002 0.239 0.130 0.600 16 630 57569.00 P 0.161745 0.006597 0.480705 0.008840 P-0.2031853 0.0063266 P -0.007 0.239 0.133 0.600 16 7 1 57570.00 P 0.163793 0.006656 0.479843 0.008941 P-0.2041214 0.0064093 P -0.016 0.239 0.151 0.600 16 7 2 57571.00 P 0.165825 0.006715 0.478950 0.009041 P-0.2049288 0.0064917 P -0.018 0.239 0.166 0.600 16 7 3 57572.00 P 0.167840 0.006774 0.478026 0.009141 P-0.2056188 0.0065737 P -0.007 0.239 0.157 0.600 16 7 4 57573.00 P 0.169839 0.006832 0.477071 0.009241 P-0.2062331 0.0066554 P 0.011 0.239 0.140 0.600 16 7 5 57574.00 P 0.171821 0.006890 0.476086 0.009340 P-0.2068275 0.0067368 P 0.024 0.239 0.138 0.600 16 7 6 57575.00 P 0.173785 0.006948 0.475071 0.009439 P-0.2074512 0.0068177 P 0.031 0.239 0.152 0.600 16 7 7 57576.00 P 0.175730 0.007005 0.474025 0.009537 P-0.2081302 0.0068984 P 0.033 0.239 0.174 0.600 16 7 8 57577.00 P 0.177656 0.007062 0.472950 0.009635 P-0.2088663 0.0069788 P 0.031 0.239 0.202 0.600 16 7 9 57578.00 P 0.179563 0.007118 0.471846 0.009732 P-0.2096451 0.0070588 P 0.027 0.239 0.235 0.600 16 710 57579.00 P 0.181450 0.007175 0.470713 0.009829 P-0.2104419 0.0071385 P 0.025 0.239 0.250 0.600 16 711 57580.00 P 0.183317 0.007230 0.469550 0.009926 P-0.2112284 0.0072179 P 0.024 0.239 0.237 0.600 16 712 57581.00 P 0.185162 0.007286 0.468360 0.010023 P-0.2119781 0.0072970 P 0.013 0.239 0.216 0.600 16 713 57582.00 P 0.186986 0.007341 0.467141 0.010119 P-0.2126684 0.0073758 P -0.003 0.239 0.205 0.600 16 714 57583.00 P 0.188788 0.007396 0.465894 0.010214 P-0.2132848 0.0074544 P -0.011 0.239 0.203 0.600 16 715 57584.00 P 0.190567 0.007451 0.464620 0.010310 P-0.2138206 0.0075326 P -0.007 0.239 0.193 0.600 16 716 57585.00 P 0.192324 0.007505 0.463319 0.010405 P-0.2142803 0.0076106 P 0.000 0.239 0.179 0.600 16 717 57586.00 P 0.194056 0.007559 0.461990 0.010499 P-0.2146833 0.0076883 P 0.004 0.239 0.170 0.600 16 718 57587.00 P 0.195765 0.007613 0.460636 0.010594 P-0.2150602 0.0077657 P 0.013 0.239 0.165 0.600 16 719 57588.00 P 0.197449 0.007666 0.459255 0.010688 P-0.2154534 0.0078428 16 720 57589.00 P 0.199109 0.007719 0.457848 0.010781 P-0.2159127 0.0079197 16 721 57590.00 P 0.200742 0.007772 0.456416 0.010875 P-0.2164842 0.0079964 16 722 57591.00 P 0.202351 0.007825 0.454960 0.010968 P-0.2172005 0.0080728 16 723 57592.00 P 0.203932 0.007877 0.453478 0.011060 P-0.2180702 0.0081489 16 724 57593.00 P 0.205487 0.007929 0.451972 0.011153 P-0.2190692 0.0082248 16 725 57594.00 P 0.207015 0.007981 0.450443 0.011245 P-0.2201448 0.0083005 16 726 57595.00 P 0.208515 0.008033 0.448890 0.011337 P-0.2212286 0.0083759 16 727 57596.00 P 0.209988 0.008084 0.447315 0.011428 P-0.2222556 0.0084511 16 728 57597.00 P 0.211431 0.008135 0.445716 0.011520 P-0.2231750 0.0085261 16 729 57598.00 P 0.212846 0.008186 0.444096 0.011611 P-0.2239618 0.0086008 16 730 57599.00 P 0.214232 0.008236 0.442454 0.011701 P-0.3000000 0.0086754 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/iers/tests/data/iers_a_excerpt0000644000175100001710000002602000000000000023042 0ustar00vstsdocker15 126 57048.00 I 0.002902 0.000024 0.302160 0.000040 I-0.4867876 0.0000073 1.2748 0.0071 I -0.155 0.119 -0.040 0.034 0.002890 0.302200 -0.4867861 -0.194 -0.055 15 127 57049.00 I 0.002371 0.000039 0.303081 0.000035 I-0.4880090 0.0000121 1.1461 0.0051 I -0.148 0.049 -0.021 0.073 0.002389 0.303074 -0.4880195 -0.193 -0.060 15 128 57050.00 I 0.002261 0.000048 0.304429 0.000038 I-0.4890652 0.0000071 0.9738 0.0068 I -0.144 0.119 0.011 0.055 0.002280 0.304472 -0.4890627 -0.166 -0.016 15 129 57051.00 I 0.002244 0.000048 0.306179 0.000035 I-0.4899792 0.0000060 0.8694 0.0047 I -0.133 0.119 0.034 0.055 0.002250 0.306164 -0.4899632 -0.132 0.035 15 130 57052.00 I 0.002854 0.000048 0.308403 0.000035 I-0.4908258 0.0000062 0.8305 0.0039 I -0.115 0.119 0.040 0.055 0.002907 0.308446 -0.4908208 -0.089 0.086 15 131 57053.00 I 0.003759 0.000045 0.310804 0.000024 I-0.4916596 0.0000051 0.8499 0.0043 I -0.101 0.119 0.042 0.054 0.003734 0.310824 -0.4916557 -0.086 0.094 15 2 1 57054.00 I 0.004544 0.000061 0.313148 0.000030 I-0.4925306 0.0000060 0.8845 0.0039 I -0.094 0.119 0.052 0.059 0.004581 0.313150 -0.4925323 -0.093 0.081 15 2 2 57055.00 I 0.004623 0.000051 0.315517 0.000029 I-0.4934373 0.0000058 0.9452 0.0061 I -0.087 0.119 0.072 0.053 15 2 3 57056.00 I 0.004190 0.000042 0.317761 0.000025 I-0.4944317 0.0000107 1.0378 0.0041 I -0.082 0.119 0.089 0.075 15 2 4 57057.00 I 0.003858 0.000052 0.319727 0.000027 I-0.4955079 0.0000059 1.1152 0.0061 I -0.075 0.119 0.103 0.048 15 2 5 57058.00 I 0.003203 0.000052 0.321256 0.000026 I-0.4966586 0.0000058 1.1820 0.0040 I -0.063 0.119 0.126 0.048 15 2 6 57059.00 I 0.002604 0.000052 0.322746 0.000026 I-0.4978678 0.0000053 1.2367 0.0033 I -0.053 0.119 0.163 0.048 15 2 7 57060.00 I 0.002144 0.000032 0.324351 0.000019 I-0.4991451 0.0000033 1.3309 0.0034 I -0.056 0.119 0.201 0.024 15 2 8 57061.00 I 0.001898 0.000037 0.325746 0.000023 I-0.5005174 0.0000043 1.3884 0.0027 I -0.071 0.119 0.225 0.052 15 2 9 57062.00 I 0.002025 0.000037 0.327045 0.000021 I-0.5018830 0.0000043 1.3290 0.0036 I -0.086 0.119 0.228 0.052 15 210 57063.00 I 0.002138 0.000021 0.328333 0.000019 I-0.5031643 0.0000058 1.2363 0.0030 I -0.098 0.119 0.202 0.062 15 211 57064.00 I 0.002223 0.000032 0.329713 0.000023 I-0.5043650 0.0000043 1.1720 0.0036 I -0.100 0.119 0.149 0.047 15 212 57065.00 I 0.002256 0.000032 0.331138 0.000024 I-0.5055269 0.0000042 1.1636 0.0030 I -0.079 0.119 0.095 0.047 15 213 57066.00 I 0.002424 0.000032 0.332371 0.000024 I-0.5067041 0.0000042 1.1909 0.0026 I -0.036 0.119 0.066 0.047 15 214 57067.00 I 0.002704 0.000026 0.333462 0.000020 I-0.5078936 0.0000030 1.1728 0.0027 I 0.003 0.119 0.045 0.027 15 215 57068.00 I 0.002772 0.000033 0.334534 0.000024 I-0.5090570 0.0000033 1.1764 0.0023 I 0.027 0.045 0.008 0.037 15 216 57069.00 I 0.002854 0.000033 0.335722 0.000025 I-0.5102715 0.0000035 1.2552 0.0033 I 0.045 0.045 -0.015 0.037 15 217 57070.00 I 0.002844 0.000023 0.337156 0.000022 I-0.5115860 0.0000058 1.3897 0.0024 I 0.055 0.066 0.003 0.050 15 218 57071.00 I 0.002756 0.000033 0.338410 0.000025 I-0.5130736 0.0000033 1.5925 0.0034 I 0.043 0.040 0.046 0.036 15 219 57072.00 I 0.002769 0.000032 0.339609 0.000025 I-0.5147512 0.0000034 1.7361 0.0025 I 0.012 0.040 0.080 0.036 15 220 57073.00 I 0.002580 0.000032 0.341034 0.000026 I-0.5165088 0.0000037 1.7687 0.0027 I -0.024 0.040 0.101 0.036 15 221 57074.00 I 0.002345 0.000025 0.342662 0.000021 I-0.5182664 0.0000042 1.7345 0.0024 I -0.052 0.119 0.114 0.023 15 222 57075.00 I 0.002461 0.000030 0.344425 0.000024 I-0.5199568 0.0000031 1.6371 0.0026 I -0.059 0.119 0.108 0.036 15 223 57076.00 I 0.003021 0.000030 0.346361 0.000024 I-0.5215198 0.0000029 1.4774 0.0026 I -0.043 0.119 0.092 0.036 15 224 57077.00 I 0.003313 0.000020 0.348467 0.000020 I-0.5228871 0.0000042 1.2443 0.0026 I -0.020 0.119 0.100 0.044 15 225 57078.00 I 0.003151 0.000020 0.350293 0.000019 I-0.5240195 0.0000044 1.0446 0.0031 I -0.004 0.119 0.151 0.045 15 226 57079.00 I 0.003153 0.000020 0.351720 0.000019 I-0.5250116 0.0000045 0.9509 0.0033 I 0.012 0.119 0.220 0.045 15 227 57080.00 I 0.003288 0.000021 0.353151 0.000021 I-0.5259330 0.0000050 0.8925 0.0063 I 0.041 0.119 0.284 0.045 15 228 57081.00 I 0.003184 0.000011 0.354780 0.000015 I-0.5268057 0.0000118 0.8616 0.0064 P -0.006 0.239 0.108 0.600 15 3 1 57082.00 I 0.003159 0.000012 0.356592 0.000017 I-0.5276758 0.0000118 0.8894 0.0080 P 0.007 0.239 0.093 0.600 15 3 2 57083.00 I 0.003484 0.000091 0.358608 0.000092 I-0.5285954 0.0000109 0.9498 0.0107 P 0.017 0.239 0.086 0.600 15 3 3 57084.00 I 0.003836 0.000092 0.360558 0.000092 I-0.5295768 0.0000179 1.0144 0.0094 P 0.025 0.239 0.094 0.600 15 3 4 57085.00 I 0.003961 0.000092 0.362222 0.000093 I-0.5306268 0.0000154 1.0866 0.0108 P 0.027 0.239 0.117 0.600 15 3 5 57086.00 I 0.004269 0.000093 0.363666 0.000093 I-0.5317409 0.0000122 1.1313 0.0089 P 0.027 0.239 0.139 0.600 15 3 6 57087.00 I 0.004778 0.000092 0.364949 0.000092 I-0.5328903 0.0000088 1.1785 0.0079 P 0.027 0.239 0.149 0.600 15 3 7 57088.00 I 0.004988 0.000092 0.366147 0.000092 I-0.5340985 0.0000100 1.2274 0.0066 P 0.015 0.239 0.146 0.600 15 3 8 57089.00 I 0.004638 0.000091 0.367236 0.000093 I-0.5353452 0.0000099 1.2765 0.0070 P -0.009 0.239 0.142 0.600 15 3 9 57090.00 I 0.004036 0.000092 0.368200 0.000093 I-0.5366619 0.0000099 1.3567 0.0070 P -0.033 0.239 0.135 0.600 15 310 57091.00 I 0.003585 0.000091 0.369259 0.000092 I-0.5380421 0.0000098 1.3875 0.0070 P -0.045 0.239 0.117 0.600 15 311 57092.00 I 0.003343 0.000092 0.370447 0.000093 I-0.5394314 0.0000100 1.4018 0.0068 P -0.040 0.239 0.091 0.600 15 312 57093.00 I 0.003194 0.000092 0.371602 0.000093 I-0.5408469 0.0000094 1.4197 0.0068 P -0.015 0.239 0.085 0.600 15 313 57094.00 I 0.002917 0.000091 0.372658 0.000092 I-0.5422589 0.0000091 1.4020 0.0065 P 0.019 0.239 0.117 0.600 15 314 57095.00 I 0.002739 0.000092 0.373613 0.000092 I-0.5436785 0.0000090 1.4673 0.0056 P 0.029 0.239 0.148 0.600 15 315 57096.00 I 0.002778 0.000091 0.374548 0.000091 I-0.5452040 0.0000066 1.5642 0.0053 P 0.008 0.239 0.132 0.600 15 316 57097.00 I 0.002789 0.000091 0.375473 0.000093 I-0.5468035 0.0000056 1.6509 0.0042 P -0.012 0.239 0.085 0.600 15 317 57098.00 I 0.002799 0.000091 0.376430 0.000094 I-0.5485481 0.0000051 1.8644 0.0326 P -0.009 0.239 0.068 0.600 15 318 57099.00 I 0.002880 0.000091 0.377429 0.000094 I-0.5504555 0.0000650 1.8477 0.0277 P 0.007 0.239 0.099 0.600 15 319 57100.00 I 0.003450 0.000091 0.378351 0.000091 I-0.5525515 0.0000552 P 0.014 0.239 0.137 0.600 15 320 57101.00 P 0.004024 0.000697 0.379498 0.000414 P-0.5547450 0.0001080 P 0.011 0.239 0.163 0.600 15 321 57102.00 P 0.004848 0.001034 0.380682 0.000681 P-0.5569577 0.0002041 P 0.005 0.239 0.177 0.600 15 322 57103.00 P 0.005564 0.001303 0.381927 0.000912 P-0.5590933 0.0003028 P -0.001 0.239 0.180 0.600 15 323 57104.00 P 0.006227 0.001536 0.383232 0.001122 P-0.5610707 0.0004021 P -0.006 0.239 0.167 0.600 15 324 57105.00 P 0.006860 0.001744 0.384571 0.001318 P-0.5628741 0.0005017 P -0.012 0.239 0.152 0.600 15 325 57106.00 P 0.007427 0.001935 0.385947 0.001503 P-0.5645205 0.0006014 P -0.015 0.239 0.145 0.600 15 326 57107.00 P 0.007984 0.002113 0.387309 0.001679 P-0.5660324 0.0007012 P -0.010 0.239 0.143 0.600 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/iers/tests/data/leap-seconds.list0000644000175100001710000002464600000000000023411 0ustar00vstsdocker# # In the following text, the symbol '#' introduces # a comment, which continues from that symbol until # the end of the line. A plain comment line has a # whitespace character following the comment indicator. # There are also special comment lines defined below. # A special comment will always have a non-whitespace # character in column 2. # # A blank line should be ignored. # # The following table shows the corrections that must # be applied to compute International Atomic Time (TAI) # from the Coordinated Universal Time (UTC) values that # are transmitted by almost all time services. # # The first column shows an epoch as a number of seconds # since 1 January 1900, 00:00:00 (1900.0 is also used to # indicate the same epoch.) Both of these time stamp formats # ignore the complexities of the time scales that were # used before the current definition of UTC at the start # of 1972. (See note 3 below.) # The second column shows the number of seconds that # must be added to UTC to compute TAI for any timestamp # at or after that epoch. The value on each line is # valid from the indicated initial instant until the # epoch given on the next one or indefinitely into the # future if there is no next line. # (The comment on each line shows the representation of # the corresponding initial epoch in the usual # day-month-year format. The epoch always begins at # 00:00:00 UTC on the indicated day. See Note 5 below.) # # Important notes: # # 1. Coordinated Universal Time (UTC) is often referred to # as Greenwich Mean Time (GMT). The GMT time scale is no # longer used, and the use of GMT to designate UTC is # discouraged. # # 2. The UTC time scale is realized by many national # laboratories and timing centers. Each laboratory # identifies its realization with its name: Thus # UTC(NIST), UTC(USNO), etc. The differences among # these different realizations are typically on the # order of a few nanoseconds (i.e., 0.000 000 00x s) # and can be ignored for many purposes. These differences # are tabulated in Circular T, which is published monthly # by the International Bureau of Weights and Measures # (BIPM). See www.bipm.org for more information. # # 3. The current definition of the relationship between UTC # and TAI dates from 1 January 1972. A number of different # time scales were in use before that epoch, and it can be # quite difficult to compute precise timestamps and time # intervals in those "prehistoric" days. For more information, # consult: # # The Explanatory Supplement to the Astronomical # Ephemeris. # or # Terry Quinn, "The BIPM and the Accurate Measurement # of Time," Proc. of the IEEE, Vol. 79, pp. 894-905, # July, 1991. # reprinted in: # Christine Hackman and Donald B Sullivan (eds.) # Time and Frequency Measurement # American Association of Physics Teachers (1996) # , pp. 75-86 # # 4. The decision to insert a leap second into UTC is currently # the responsibility of the International Earth Rotation and # Reference Systems Service. (The name was changed from the # International Earth Rotation Service, but the acronym IERS # is still used.) # # Leap seconds are announced by the IERS in its Bulletin C. # # See www.iers.org for more details. # # Every national laboratory and timing center uses the # data from the BIPM and the IERS to construct UTC(lab), # their local realization of UTC. # # Although the definition also includes the possibility # of dropping seconds ("negative" leap seconds), this has # never been done and is unlikely to be necessary in the # foreseeable future. # # 5. If your system keeps time as the number of seconds since # some epoch (e.g., NTP timestamps), then the algorithm for # assigning a UTC time stamp to an event that happens during a positive # leap second is not well defined. The official name of that leap # second is 23:59:60, but there is no way of representing that time # in these systems. # Many systems of this type effectively stop the system clock for # one second during the leap second and use a time that is equivalent # to 23:59:59 UTC twice. For these systems, the corresponding TAI # timestamp would be obtained by advancing to the next entry in the # following table when the time equivalent to 23:59:59 UTC # is used for the second time. Thus the leap second which # occurred on 30 June 1972 at 23:59:59 UTC would have TAI # timestamps computed as follows: # # ... # 30 June 1972 23:59:59 (2287785599, first time): TAI= UTC + 10 seconds # 30 June 1972 23:59:60 (2287785599,second time): TAI= UTC + 11 seconds # 1 July 1972 00:00:00 (2287785600) TAI= UTC + 11 seconds # ... # # If your system realizes the leap second by repeating 00:00:00 UTC twice # (this is possible but not usual), then the advance to the next entry # in the table must occur the second time that a time equivalent to # 00:00:00 UTC is used. Thus, using the same example as above: # # ... # 30 June 1972 23:59:59 (2287785599): TAI= UTC + 10 seconds # 30 June 1972 23:59:60 (2287785600, first time): TAI= UTC + 10 seconds # 1 July 1972 00:00:00 (2287785600,second time): TAI= UTC + 11 seconds # ... # # in both cases the use of timestamps based on TAI produces a smooth # time scale with no discontinuity in the time interval. However, # although the long-term behavior of the time scale is correct in both # methods, the second method is technically not correct because it adds # the extra second to the wrong day. # # This complexity would not be needed for negative leap seconds (if they # are ever used). The UTC time would skip 23:59:59 and advance from # 23:59:58 to 00:00:00 in that case. The TAI offset would decrease by # 1 second at the same instant. This is a much easier situation to deal # with, since the difficulty of unambiguously representing the epoch # during the leap second does not arise. # # Some systems implement leap seconds by amortizing the leap second # over the last few minutes of the day. The frequency of the local # clock is decreased (or increased) to realize the positive (or # negative) leap second. This method removes the time step described # above. Although the long-term behavior of the time scale is correct # in this case, this method introduces an error during the adjustment # period both in time and in frequency with respect to the official # definition of UTC. # # Questions or comments to: # Judah Levine # Time and Frequency Division # NIST # Boulder, Colorado # Judah.Levine@nist.gov # # Last Update of leap second values: 8 July 2016 # # The following line shows this last update date in NTP timestamp # format. This is the date on which the most recent change to # the leap second data was added to the file. This line can # be identified by the unique pair of characters in the first two # columns as shown below. # #$ 3676924800 # # The NTP timestamps are in units of seconds since the NTP epoch, # which is 1 January 1900, 00:00:00. The Modified Julian Day number # corresponding to the NTP time stamp, X, can be computed as # # X/86400 + 15020 # # where the first term converts seconds to days and the second # term adds the MJD corresponding to the time origin defined above. # The integer portion of the result is the integer MJD for that # day, and any remainder is the time of day, expressed as the # fraction of the day since 0 hours UTC. The conversion from day # fraction to seconds or to hours, minutes, and seconds may involve # rounding or truncation, depending on the method used in the # computation. # # The data in this file will be updated periodically as new leap # seconds are announced. In addition to being entered on the line # above, the update time (in NTP format) will be added to the basic # file name leap-seconds to form the name leap-seconds.. # In addition, the generic name leap-seconds.list will always point to # the most recent version of the file. # # This update procedure will be performed only when a new leap second # is announced. # # The following entry specifies the expiration date of the data # in this file in units of seconds since the origin at the instant # 1 January 1900, 00:00:00. This expiration date will be changed # at least twice per year whether or not a new leap second is # announced. These semi-annual changes will be made no later # than 1 June and 1 December of each year to indicate what # action (if any) is to be taken on 30 June and 31 December, # respectively. (These are the customary effective dates for new # leap seconds.) This expiration date will be identified by a # unique pair of characters in columns 1 and 2 as shown below. # In the unlikely event that a leap second is announced with an # effective date other than 30 June or 31 December, then this # file will be edited to include that leap second as soon as it is # announced or at least one month before the effective date # (whichever is later). # If an announcement by the IERS specifies that no leap second is # scheduled, then only the expiration date of the file will # be advanced to show that the information in the file is still # current -- the update time stamp, the data and the name of the file # will not change. # # Updated through IERS Bulletin C58 # File expires on: 28 June 2020 # #@ 3802291200 # 2272060800 10 # 1 Jan 1972 2287785600 11 # 1 Jul 1972 2303683200 12 # 1 Jan 1973 2335219200 13 # 1 Jan 1974 2366755200 14 # 1 Jan 1975 2398291200 15 # 1 Jan 1976 2429913600 16 # 1 Jan 1977 2461449600 17 # 1 Jan 1978 2492985600 18 # 1 Jan 1979 2524521600 19 # 1 Jan 1980 2571782400 20 # 1 Jul 1981 2603318400 21 # 1 Jul 1982 2634854400 22 # 1 Jul 1983 2698012800 23 # 1 Jul 1985 2776982400 24 # 1 Jan 1988 2840140800 25 # 1 Jan 1990 2871676800 26 # 1 Jan 1991 2918937600 27 # 1 Jul 1992 2950473600 28 # 1 Jul 1993 2982009600 29 # 1 Jul 1994 3029443200 30 # 1 Jan 1996 3076704000 31 # 1 Jul 1997 3124137600 32 # 1 Jan 1999 3345062400 33 # 1 Jan 2006 3439756800 34 # 1 Jan 2009 3550089600 35 # 1 Jul 2012 3644697600 36 # 1 Jul 2015 3692217600 37 # 1 Jan 2017 # # the following special comment contains the # hash value of the data in this file computed # use the secure hash algorithm as specified # by FIPS 180-1. See the files in ~/pub/sha for # the details of how this hash value is # computed. Note that the hash computation # ignores comments and whitespace characters # in data lines. It includes the NTP values # of both the last modification time and the # expiration time of the file, but not the # white space on those lines. # the hash line is also ignored in the # computation. # #h f28827d2 f263b6c3 ec0f19eb a3e0dbf0 97f3fa30 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/iers/tests/test_iers.py0000644000175100001710000004033100000000000021566 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import os import warnings from pathlib import Path import pytest import numpy as np from astropy.tests.helper import assert_quantity_allclose from astropy.utils.data import get_pkg_data_filename from astropy.utils.iers import iers from astropy import units as u from astropy.table import QTable from astropy.time import Time, TimeDelta CI = os.environ.get('CI', False) FILE_NOT_FOUND_ERROR = getattr(__builtins__, 'FileNotFoundError', OSError) try: iers.IERS_A.open('finals2000A.all') # check if IERS_A is available except OSError: HAS_IERS_A = False else: HAS_IERS_A = True IERS_A_EXCERPT = get_pkg_data_filename(os.path.join('data', 'iers_a_excerpt')) def setup_module(): # Need auto_download so that IERS_B won't be loaded and cause tests to # fail. Files to be downloaded are handled appropriately in the tests. iers.conf.auto_download = True def teardown_module(): # This setting is to be consistent with astropy/conftest.py iers.conf.auto_download = False class TestBasic(): """Basic tests that IERS_B returns correct values""" @pytest.mark.parametrize('iers_cls', (iers.IERS_B, iers.IERS)) def test_simple(self, iers_cls): """Test the default behaviour for IERS_B and IERS.""" # Arguably, IERS itself should not be used at all, but it used to # provide IERS_B by default so we check that it continues to do so. # Eventually, IERS should probably be deprecated. iers_cls.close() assert iers_cls.iers_table is None iers_tab = iers_cls.open() assert iers_cls.iers_table is not None assert iers_cls.iers_table is iers_tab assert isinstance(iers_tab, QTable) assert isinstance(iers_tab, iers.IERS_B) assert (iers_tab['UT1_UTC'].unit / u.second).is_unity() assert (iers_tab['PM_x'].unit / u.arcsecond).is_unity() assert (iers_tab['PM_y'].unit / u.arcsecond).is_unity() jd1 = np.array([2456108.5, 2456108.5, 2456108.5, 2456109.5, 2456109.5]) jd2 = np.array([0.49999421, 0.99997685, 0.99998843, 0., 0.5]) ut1_utc = iers_tab.ut1_utc(jd1, jd2) assert isinstance(ut1_utc, u.Quantity) assert (ut1_utc.unit / u.second).is_unity() # IERS files change at the 0.1 ms level; see gh-6981 assert_quantity_allclose(ut1_utc, [-0.5868211, -0.5868184, -0.5868184, 0.4131816, 0.41328895] * u.s, atol=0.1*u.ms) # should be future-proof; surely we've moved to another planet by then with pytest.raises(IndexError): ut1_utc2, status2 = iers_tab.ut1_utc(1e11, 0.) # also check it returns the right status ut1_utc2, status2 = iers_tab.ut1_utc(jd1, jd2, return_status=True) assert np.all(status2 == iers.FROM_IERS_B) ut1_utc4, status4 = iers_tab.ut1_utc(1e11, 0., return_status=True) assert status4 == iers.TIME_BEYOND_IERS_RANGE # check it works via Time too t = Time(jd1, jd2, format='jd', scale='utc') ut1_utc3 = iers_tab.ut1_utc(t) assert_quantity_allclose(ut1_utc3, [-0.5868211, -0.5868184, -0.5868184, 0.4131816, 0.41328895] * u.s, atol=0.1*u.ms) # Table behaves properly as a table (e.g. can be sliced) assert len(iers_tab[:2]) == 2 def test_open_filename(self): iers.IERS_B.close() iers.IERS_B.open(iers.IERS_B_FILE) assert iers.IERS_B.iers_table is not None assert isinstance(iers.IERS_B.iers_table, QTable) iers.IERS_B.close() with pytest.raises(FILE_NOT_FOUND_ERROR): iers.IERS_B.open('surely this does not exist') def test_open_network_url(self): iers.IERS_A.close() iers.IERS_A.open(Path(IERS_A_EXCERPT).as_uri()) assert iers.IERS_A.iers_table is not None assert isinstance(iers.IERS_A.iers_table, QTable) iers.IERS_A.close() class TestIERS_AExcerpt(): def test_simple(self): # Test the IERS A reader. It is also a regression tests that ensures # values do not get overridden by IERS B; see #4933. iers_tab = iers.IERS_A.open(IERS_A_EXCERPT) assert (iers_tab['UT1_UTC'].unit / u.second).is_unity() assert 'P' in iers_tab['UT1Flag'] assert 'I' in iers_tab['UT1Flag'] assert 'B' in iers_tab['UT1Flag'] assert np.all((iers_tab['UT1Flag'] == 'I') | (iers_tab['UT1Flag'] == 'P') | (iers_tab['UT1Flag'] == 'B')) assert (iers_tab['dX_2000A'].unit / u.marcsec).is_unity() assert (iers_tab['dY_2000A'].unit / u.marcsec).is_unity() assert 'P' in iers_tab['NutFlag'] assert 'I' in iers_tab['NutFlag'] assert 'B' in iers_tab['NutFlag'] assert np.all((iers_tab['NutFlag'] == 'P') | (iers_tab['NutFlag'] == 'I') | (iers_tab['NutFlag'] == 'B')) assert (iers_tab['PM_x'].unit / u.arcsecond).is_unity() assert (iers_tab['PM_y'].unit / u.arcsecond).is_unity() assert 'P' in iers_tab['PolPMFlag'] assert 'I' in iers_tab['PolPMFlag'] assert 'B' in iers_tab['PolPMFlag'] assert np.all((iers_tab['PolPMFlag'] == 'P') | (iers_tab['PolPMFlag'] == 'I') | (iers_tab['PolPMFlag'] == 'B')) t = Time([57053., 57054., 57055.], format='mjd') ut1_utc, status = iers_tab.ut1_utc(t, return_status=True) assert status[0] == iers.FROM_IERS_B assert np.all(status[1:] == iers.FROM_IERS_A) # These values are *exactly* as given in the table, so they should # match to double precision accuracy. assert_quantity_allclose(ut1_utc, [-0.4916557, -0.4925323, -0.4934373] * u.s, atol=0.1*u.ms) dcip_x, dcip_y, status = iers_tab.dcip_xy(t, return_status=True) assert status[0] == iers.FROM_IERS_B assert np.all(status[1:] == iers.FROM_IERS_A) # These values are *exactly* as given in the table, so they should # match to double precision accuracy. print(dcip_x) print(dcip_y) assert_quantity_allclose(dcip_x, [-0.086, -0.093, -0.087] * u.marcsec, atol=1.*u.narcsec) assert_quantity_allclose(dcip_y, [0.094, 0.081, 0.072] * u.marcsec, atol=1*u.narcsec) pm_x, pm_y, status = iers_tab.pm_xy(t, return_status=True) assert status[0] == iers.FROM_IERS_B assert np.all(status[1:] == iers.FROM_IERS_A) assert_quantity_allclose(pm_x, [0.003734, 0.004581, 0.004623] * u.arcsec, atol=0.1*u.marcsec) assert_quantity_allclose(pm_y, [0.310824, 0.313150, 0.315517] * u.arcsec, atol=0.1*u.marcsec) # Table behaves properly as a table (e.g. can be sliced) assert len(iers_tab[:2]) == 2 @pytest.mark.skipif('not HAS_IERS_A') class TestIERS_A(): def test_simple(self): """Test that open() by default reads a 'finals2000A.all' file.""" # Ensure we remove any cached table (gh-5131). iers.IERS_A.close() iers_tab = iers.IERS_A.open() jd1 = np.array([2456108.5, 2456108.5, 2456108.5, 2456109.5, 2456109.5]) jd2 = np.array([0.49999421, 0.99997685, 0.99998843, 0., 0.5]) ut1_utc, status = iers_tab.ut1_utc(jd1, jd2, return_status=True) assert np.all(status == iers.FROM_IERS_B) assert_quantity_allclose(ut1_utc, [-0.5868211, -0.5868184, -0.5868184, 0.4131816, 0.41328895] * u.s, atol=0.1*u.ms) ut1_utc2, status2 = iers_tab.ut1_utc(1e11, 0., return_status=True) assert status2 == iers.TIME_BEYOND_IERS_RANGE tnow = Time.now() ut1_utc3, status3 = iers_tab.ut1_utc(tnow, return_status=True) assert status3 == iers.FROM_IERS_A_PREDICTION assert ut1_utc3 != 0. class TestIERS_Auto(): def setup_class(self): """Set up useful data for the tests. """ self.N = 40 self.ame = 30.0 self.iers_a_file_1 = get_pkg_data_filename( os.path.join('data', 'finals2000A-2016-02-30-test')) self.iers_a_file_2 = get_pkg_data_filename( os.path.join('data', 'finals2000A-2016-04-30-test')) self.iers_a_url_1 = Path(self.iers_a_file_1).as_uri() self.iers_a_url_2 = Path(self.iers_a_file_2).as_uri() self.t = Time.now() + TimeDelta(10, format='jd') * np.arange(self.N) def teardown_method(self, method): """Run this after every test. """ iers.IERS_Auto.close() def test_interpolate_error_formatting(self): """Regression test: make sure the error message in IERS_Auto._check_interpolate_indices() is formatted correctly. """ with iers.conf.set_temp('iers_auto_url', self.iers_a_url_1): with iers.conf.set_temp('iers_auto_url_mirror', self.iers_a_url_1): with iers.conf.set_temp('auto_max_age', self.ame): with pytest.raises(ValueError) as err: iers_table = iers.IERS_Auto.open() with warnings.catch_warnings(): # Ignoring this if it comes up -- IERS_Auto predictive # values are older than 30.0 days but downloading the # latest table did not find newer values warnings.simplefilter('ignore', iers.IERSStaleWarning) iers_table.ut1_utc(self.t.jd1, self.t.jd2) assert str(err.value) == iers.INTERPOLATE_ERROR.format(self.ame) def test_auto_max_age_none(self): """Make sure that iers.INTERPOLATE_ERROR's advice about setting auto_max_age = None actually works. """ with iers.conf.set_temp('iers_auto_url', self.iers_a_url_1): with iers.conf.set_temp('auto_max_age', None): iers_table = iers.IERS_Auto.open() delta = iers_table.ut1_utc(self.t.jd1, self.t.jd2) assert isinstance(delta, np.ndarray) assert delta.shape == (self.N,) assert_quantity_allclose(delta, np.array([-0.2246227]*self.N)*u.s) def test_auto_max_age_minimum(self): """Check that the minimum auto_max_age is enforced. """ with iers.conf.set_temp('iers_auto_url', self.iers_a_url_1): with iers.conf.set_temp('auto_max_age', 5.0): with pytest.raises(ValueError) as err: iers_table = iers.IERS_Auto.open() _ = iers_table.ut1_utc(self.t.jd1, self.t.jd2) assert str(err.value) == 'IERS auto_max_age configuration value must be larger than 10 days' def test_no_auto_download(self): with iers.conf.set_temp('auto_download', False): t = iers.IERS_Auto.open() assert type(t) is iers.IERS_B @pytest.mark.remote_data def test_simple(self): with iers.conf.set_temp('iers_auto_url', self.iers_a_url_1): dat = iers.IERS_Auto.open() assert dat['MJD'][0] == 57359.0 * u.d assert dat['MJD'][-1] == 57539.0 * u.d # Pretend we are accessing at a time 7 days after start of predictive data predictive_mjd = dat.meta['predictive_mjd'] dat._time_now = Time(predictive_mjd, format='mjd') + 7 * u.d # Look at times before and after the test file begins. 0.1292905 is # the IERS-B value from MJD=57359. The value in # finals2000A-2016-02-30-test has been replaced at this point. assert np.allclose(dat.ut1_utc(Time(50000, format='mjd').jd).value, 0.1293286) assert np.allclose(dat.ut1_utc(Time(60000, format='mjd').jd).value, -0.2246227) # Now pretend we are accessing at time 60 days after start of predictive data. # There will be a warning when downloading the file doesn't give new data # and an exception when extrapolating into the future with insufficient data. dat._time_now = Time(predictive_mjd, format='mjd') + 60 * u.d assert np.allclose(dat.ut1_utc(Time(50000, format='mjd').jd).value, 0.1293286) with pytest.warns(iers.IERSStaleWarning, match='IERS_Auto predictive ' 'values are older') as warns, \ pytest.raises(ValueError, match='interpolating from IERS_Auto ' 'using predictive values'): dat.ut1_utc(Time(60000, format='mjd').jd) assert len(warns) == 1 # Warning only if we are getting return status with pytest.warns(iers.IERSStaleWarning, match='IERS_Auto ' 'predictive values are older') as warns: dat.ut1_utc(Time(60000, format='mjd').jd, return_status=True) assert len(warns) == 1 # Now set auto_max_age = None which says that we don't care how old the # available IERS-A file is. There should be no warnings or exceptions. with iers.conf.set_temp('auto_max_age', None): dat.ut1_utc(Time(60000, format='mjd').jd) # Now point to a later file with same values but MJD increased by # 60 days and see that things work. dat._time_now is still the same value # as before, i.e. right around the start of predictive values for the new file. # (In other words this is like downloading the latest file online right now). with iers.conf.set_temp('iers_auto_url', self.iers_a_url_2): # Look at times before and after the test file begins. This forces a new download. assert np.allclose(dat.ut1_utc(Time(50000, format='mjd').jd).value, 0.1293286) assert np.allclose(dat.ut1_utc(Time(60000, format='mjd').jd).value, -0.3) # Now the time range should be different. assert dat['MJD'][0] == 57359.0 * u.d assert dat['MJD'][-1] == (57539.0 + 60) * u.d @pytest.mark.remote_data def test_IERS_B_parameters_loading_into_IERS_Auto(): A = iers.IERS_Auto.open() B = iers.IERS_B.open() ok_A = A["MJD"] <= B["MJD"][-1] assert not np.all(ok_A), "IERS B covers all of IERS A: should not happen" # We only overwrite IERS_B values in the IERS_A table that were already # there in the first place. Better take that into account. ok_A &= np.isfinite(A["UT1_UTC_B"]) i_B = np.searchsorted(B["MJD"], A["MJD"][ok_A]) assert np.all(np.diff(i_B) == 1), "Valid region not contiguous" assert np.all(A["MJD"][ok_A] == B["MJD"][i_B]) # Check that values are copied correctly. Since units are not # necessarily the same, we use allclose with very strict tolerance. for name in ("UT1_UTC", "PM_x", "PM_y", "dX_2000A", "dY_2000A"): assert_quantity_allclose( A[name][ok_A], B[name][i_B], rtol=1e-15, err_msg=("Bug #9206 IERS B parameter {} not copied over " "correctly to IERS Auto".format(name))) # Issue with FTP, rework test into previous one when it's fixed @pytest.mark.skipif("CI", reason="Flaky on CI") @pytest.mark.remote_data def test_iers_a_dl(): iersa_tab = iers.IERS_A.open(iers.IERS_A_URL, cache=False) try: # some basic checks to ensure the format makes sense assert len(iersa_tab) > 0 assert 'UT1_UTC_A' in iersa_tab.colnames finally: iers.IERS_A.close() @pytest.mark.remote_data def test_iers_a_dl_mirror(): iersa_tab = iers.IERS_A.open(iers.IERS_A_URL_MIRROR, cache=False) try: # some basic checks to ensure the format makes sense assert len(iersa_tab) > 0 assert 'UT1_UTC_A' in iersa_tab.colnames finally: iers.IERS_A.close() @pytest.mark.remote_data def test_iers_b_dl(): iersb_tab = iers.IERS_B.open(iers.IERS_B_URL, cache=False) try: # some basic checks to ensure the format makes sense assert len(iersb_tab) > 0 assert 'UT1_UTC' in iersb_tab.colnames finally: iers.IERS_B.close() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/iers/tests/test_leap_second.py0000644000175100001710000005147200000000000023110 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import urllib.request import os import locale import platform import pytest import numpy as np from numpy.testing import assert_array_equal import erfa from astropy.time import Time, TimeDelta from astropy.utils.iers import iers from astropy.utils.data import get_pkg_data_filename from astropy.tests.tests.test_imports import test_imports # Import every top-level astropy module as a test that the ERFA leap second # table is not updated for normal imports. test_imports() # Now test that the erfa leap_seconds table has not been updated. This must be # done at the module level, which unfortunately will abort the entire test run # if if fails. Running within a normal pytest test will not work because the # other tests will end up updating this attribute by virtue of doing Time UTC # transformations. assert erfa.leap_seconds._expires is None # Tests in this module assume that the erfa.leap_seconds attribute has been # updated from the `erfa` package built-in table to the astropy built-in # leap-second table. That has the effect of ensuring that the # `erfa.leap_seconds.expires` property is sufficiently in the future. iers_table = iers.LeapSeconds.auto_open() erfa.leap_seconds.update(iers_table) assert erfa.leap_seconds._expires is not None SYSTEM_FILE = '/usr/share/zoneinfo/leap-seconds.list' # Test leap_seconds.list in test/data. LEAP_SECOND_LIST = get_pkg_data_filename('data/leap-seconds.list') def test_configuration(): # This test just ensures things stay consistent. # Adjust if changes are made. assert iers.conf.iers_leap_second_auto_url == iers.IERS_LEAP_SECOND_URL assert iers.conf.ietf_leap_second_auto_url == iers.IETF_LEAP_SECOND_URL class TestReading: """Basic tests that leap seconds can be read.""" def verify_day_month_year(self, ls): assert np.all(ls['day'] == 1) assert np.all((ls['month'] == 1) | (ls['month'] == 7) | (ls['year'] < 1970)) assert np.all(ls['year'] >= 1960) t = Time({'year': ls['year'], 'month': ls['month'], 'day': ls['day']}, format='ymdhms') assert np.all(t == Time(ls['mjd'], format='mjd')) def test_read_leap_second_dat(self): ls = iers.LeapSeconds.from_iers_leap_seconds( iers.IERS_LEAP_SECOND_FILE) # Below, >= to take into account we might ship and updated file. assert ls.expires >= Time('2020-06-28', scale='tai') assert ls['mjd'][0] == 41317 assert ls['tai_utc'][0] == 10 assert ls['mjd'][-1] >= 57754 assert ls['tai_utc'][-1] >= 37 self.verify_day_month_year(ls) def test_read_leap_second_dat_locale(self): current = locale.setlocale(locale.LC_ALL) try: if platform.system() == 'Darwin': locale.setlocale(locale.LC_ALL, 'fr_FR') else: locale.setlocale(locale.LC_ALL, 'fr_FR.utf8') ls = iers.LeapSeconds.from_iers_leap_seconds( iers.IERS_LEAP_SECOND_FILE) except locale.Error as e: pytest.skip(f'Locale error: {e}') finally: locale.setlocale(locale.LC_ALL, current) # Below, >= to take into account we might ship and updated file. assert ls.expires >= Time('2020-06-28', scale='tai') def test_open_leap_second_dat(self): ls = iers.LeapSeconds.from_iers_leap_seconds( iers.IERS_LEAP_SECOND_FILE) ls2 = iers.LeapSeconds.open(iers.IERS_LEAP_SECOND_FILE) assert np.all(ls == ls2) @pytest.mark.parametrize('file', ( LEAP_SECOND_LIST, "file:" + urllib.request.pathname2url(LEAP_SECOND_LIST))) def test_read_leap_seconds_list(self, file): ls = iers.LeapSeconds.from_leap_seconds_list(file) assert ls.expires == Time('2020-06-28', scale='tai') assert ls['mjd'][0] == 41317 assert ls['tai_utc'][0] == 10 assert ls['mjd'][-1] == 57754 assert ls['tai_utc'][-1] == 37 self.verify_day_month_year(ls) @pytest.mark.parametrize('file', ( LEAP_SECOND_LIST, "file:" + urllib.request.pathname2url(LEAP_SECOND_LIST))) def test_open_leap_seconds_list(self, file): ls = iers.LeapSeconds.from_leap_seconds_list(file) ls2 = iers.LeapSeconds.open(file) assert np.all(ls == ls2) @pytest.mark.skipif(not os.path.isfile(SYSTEM_FILE), reason=f'system does not have {SYSTEM_FILE}') def test_open_system_file(self): ls = iers.LeapSeconds.open(SYSTEM_FILE) expired = ls.expires < Time.now() if expired: pytest.skip("System leap second file is expired.") assert not expired def make_fake_file(expiration, tmpdir): """copy the built-in IERS file but set a different expiration date.""" ls = iers.LeapSeconds.from_iers_leap_seconds() fake_file = str(tmpdir.join('fake_leap_seconds.dat')) with open(fake_file, 'w') as fh: fh.write('\n'.join([f'# File expires on {expiration}'] + str(ls).split('\n')[2:-1])) return fake_file def test_fake_file(tmpdir): fake_file = make_fake_file('28 June 2345', tmpdir) fake = iers.LeapSeconds.from_iers_leap_seconds(fake_file) assert fake.expires == Time('2345-06-28', scale='tai') class TestAutoOpenExplicitLists: # For this set of tests, leap-seconds are allowed to be expired # except as explicitly tested. @pytest.mark.filterwarnings(iers.IERSStaleWarning) def test_auto_open_simple(self): ls = iers.LeapSeconds.auto_open([iers.IERS_LEAP_SECOND_FILE]) assert ls.meta['data_url'] == iers.IERS_LEAP_SECOND_FILE @pytest.mark.filterwarnings(iers.IERSStaleWarning) def test_auto_open_erfa(self): ls = iers.LeapSeconds.auto_open(['erfa', iers.IERS_LEAP_SECOND_FILE]) assert ls.meta['data_url'] in ['erfa', iers.IERS_LEAP_SECOND_FILE] @pytest.mark.filterwarnings(iers.IERSStaleWarning) def test_fake_future_file(self, tmpdir): fake_file = make_fake_file('28 June 2345', tmpdir) # Try as system file for auto_open, setting auto_max_age such # that any ERFA or system files are guaranteed to be expired, # while the fake file is guaranteed to be OK. with iers.conf.set_temp('auto_max_age', -100000): ls = iers.LeapSeconds.auto_open([ 'erfa', iers.IERS_LEAP_SECOND_FILE, fake_file]) assert ls.expires == Time('2345-06-28', scale='tai') assert ls.meta['data_url'] == str(fake_file) # And as URL fake_url = "file:" + urllib.request.pathname2url(fake_file) ls2 = iers.LeapSeconds.auto_open([ 'erfa', iers.IERS_LEAP_SECOND_FILE, fake_url]) assert ls2.expires == Time('2345-06-28', scale='tai') assert ls2.meta['data_url'] == str(fake_url) def test_fake_expired_file(self, tmpdir): fake_file1 = make_fake_file('28 June 2010', tmpdir) fake_file2 = make_fake_file('27 June 2012', tmpdir) # Between these and the built-in one, the built-in file is best. ls = iers.LeapSeconds.auto_open([fake_file1, fake_file2, iers.IERS_LEAP_SECOND_FILE]) assert ls.meta['data_url'] == iers.IERS_LEAP_SECOND_FILE # But if we remove the built-in one, the least expired one will be # used and we get a warning that it is stale. with pytest.warns(iers.IERSStaleWarning): ls2 = iers.LeapSeconds.auto_open([fake_file1, fake_file2]) assert ls2.meta['data_url'] == fake_file2 assert ls2.expires == Time('2012-06-27', scale='tai') # Use the fake files to make sure auto_max_age is safe. # Should have no warning in either example. with iers.conf.set_temp('auto_max_age', None): ls3 = iers.LeapSeconds.auto_open([fake_file1, iers.IERS_LEAP_SECOND_FILE]) assert ls3.meta['data_url'] == iers.IERS_LEAP_SECOND_FILE with iers.conf.set_temp('auto_max_age', None): ls4 = iers.LeapSeconds.auto_open([fake_file1, fake_file2]) assert ls4.meta['data_url'] == fake_file2 @pytest.mark.remote_data class TestRemoteURLs: def setup_class(cls): # Need auto_download so that IERS_B won't be loaded and cause tests to # fail. iers.conf.auto_download = True def teardown_class(cls): # This setting is to be consistent with astropy/conftest.py iers.conf.auto_download = False # In these tests, the results may be cached. # This is fine - no need to download again. def test_iers_url(self): ls = iers.LeapSeconds.auto_open([iers.IERS_LEAP_SECOND_URL]) assert ls.expires > Time.now() def test_ietf_url(self): ls = iers.LeapSeconds.auto_open([iers.IETF_LEAP_SECOND_URL]) assert ls.expires > Time.now() class TestDefaultAutoOpen: """Test auto_open with different _auto_open_files.""" def setup(self): # Identical to what is used in LeapSeconds.auto_open(). self.good_enough = (iers.LeapSeconds._today() + TimeDelta(180 - iers._none_to_float(iers.conf.auto_max_age), format='jd')) self._auto_open_files = iers.LeapSeconds._auto_open_files.copy() def teardown(self): iers.LeapSeconds._auto_open_files = self._auto_open_files def remove_auto_open_files(self, *files): """Remove some files from the auto-opener. The default set is restored in teardown. """ for f in files: iers.LeapSeconds._auto_open_files.remove(f) def test_erfa_found(self): # Set huge maximum age such that whatever ERFA has is OK. # Since it is checked first, it should thus be found. with iers.conf.set_temp('auto_max_age', 100000): ls = iers.LeapSeconds.open() assert ls.meta['data_url'] == 'erfa' def test_builtin_found(self): # Set huge maximum age such that built-in file is always OK. # If we remove 'erfa', it should thus be found. self.remove_auto_open_files('erfa') with iers.conf.set_temp('auto_max_age', 100000): ls = iers.LeapSeconds.open() assert ls.meta['data_url'] == iers.IERS_LEAP_SECOND_FILE # The test below is marked remote_data only to ensure it runs # as an allowed-fail job on CI: i.e., we will notice it (eventually) # but will not be misled in thinking that a PR is bad. @pytest.mark.remote_data def test_builtin_not_expired(self): # TODO: would be nice to have automatic PRs for this! ls = iers.LeapSeconds.open(iers.IERS_LEAP_SECOND_FILE) assert ls.expires > self.good_enough, ( "The leap second file built in to astropy is expired. Fix with:\n" "cd astropy/utils/iers/data/; . update_builtin_iers.sh\n" "and commit as a PR (for details, see release procedure).") def test_fake_future_file(self, tmpdir): fake_file = make_fake_file('28 June 2345', tmpdir) # Try as system file for auto_open, setting auto_max_age such # that any ERFA or system files are guaranteed to be expired. with iers.conf.set_temp('auto_max_age', -100000), \ iers.conf.set_temp('system_leap_second_file', fake_file): ls = iers.LeapSeconds.open() assert ls.expires == Time('2345-06-28', scale='tai') assert ls.meta['data_url'] == str(fake_file) # And as URL fake_url = "file:" + urllib.request.pathname2url(fake_file) with iers.conf.set_temp('auto_max_age', -100000), \ iers.conf.set_temp('iers_leap_second_auto_url', fake_url): ls2 = iers.LeapSeconds.open() assert ls2.expires == Time('2345-06-28', scale='tai') assert ls2.meta['data_url'] == str(fake_url) def test_fake_expired_file(self, tmpdir): self.remove_auto_open_files('erfa', 'iers_leap_second_auto_url', 'ietf_leap_second_auto_url') fake_file = make_fake_file('28 June 2010', tmpdir) with iers.conf.set_temp('system_leap_second_file', fake_file): # If we try this directly, the built-in file will be found. ls = iers.LeapSeconds.open() assert ls.meta['data_url'] == iers.IERS_LEAP_SECOND_FILE # But if we remove the built-in one, the expired one will be # used and we get a warning that it is stale. self.remove_auto_open_files(iers.IERS_LEAP_SECOND_FILE) with pytest.warns(iers.IERSStaleWarning): ls2 = iers.LeapSeconds.open() assert ls2.meta['data_url'] == fake_file assert ls2.expires == Time('2010-06-28', scale='tai') @pytest.mark.skipif(not os.path.isfile(SYSTEM_FILE), reason=f'system does not have {SYSTEM_FILE}') def test_system_file_used_if_not_expired(self, tmpdir): # We skip the test if the system file is on a CI and is expired - # we should not depend on CI keeping it up to date, but if it is, # we should check that it is used if possible. if (iers.LeapSeconds.open(SYSTEM_FILE).expires <= self.good_enough): pytest.skip("System leap second file is expired.") self.remove_auto_open_files('erfa') with iers.conf.set_temp('system_leap_second_file', SYSTEM_FILE): ls = iers.LeapSeconds.open() assert ls.expires > self.good_enough assert ls.meta['data_url'] in (iers.IERS_LEAP_SECOND_FILE, SYSTEM_FILE) # Also check with a "built-in" file that is expired fake_file = make_fake_file('28 June 2017', tmpdir) iers.LeapSeconds._auto_open_files[0] = fake_file ls2 = iers.LeapSeconds.open() assert ls2.expires > Time.now() assert ls2.meta['data_url'] == SYSTEM_FILE @pytest.mark.remote_data def test_auto_open_urls_always_good_enough(self): # Avoid using the erfa, built-in and system files, as they might # be good enough already. try: # Need auto_download so that IERS_B won't be loaded and # cause tests to fail. iers.conf.auto_download = True self.remove_auto_open_files('erfa', iers.IERS_LEAP_SECOND_FILE, 'system_leap_second_file') ls = iers.LeapSeconds.open() assert ls.expires > self.good_enough assert ls.meta['data_url'].startswith('http') finally: # This setting is to be consistent with astropy/conftest.py iers.conf.auto_download = False class ERFALeapSecondsSafe: """Base class for tests that change the ERFA leap-second tables. It ensures the original state is restored. """ def setup(self): # Keep current leap-second table and expiration. self.erfa_ls = self._erfa_ls = erfa.leap_seconds.get() self.erfa_expires = self._expires = erfa.leap_seconds._expires def teardown(self): # Restore leap-second table and expiration. erfa.leap_seconds.set(self.erfa_ls) erfa.leap_seconds._expires = self._expires class TestFromERFA(ERFALeapSecondsSafe): def test_get_erfa_ls(self): ls = iers.LeapSeconds.from_erfa() assert ls.colnames == ['year', 'month', 'tai_utc'] assert isinstance(ls.expires, Time) assert ls.expires == self.erfa_expires ls_array = np.array(ls['year', 'month', 'tai_utc']) assert np.all(ls_array == self.erfa_ls) def test_get_built_in_erfa_ls(self): ls = iers.LeapSeconds.from_erfa(built_in=True) assert ls.colnames == ['year', 'month', 'tai_utc'] assert isinstance(ls.expires, Time) ls_array = np.array(ls['year', 'month', 'tai_utc']) assert np.all(ls_array == self.erfa_ls[:len(ls_array)]) def test_get_modified_erfa_ls(self): erfa.leap_seconds.set(self.erfa_ls[:-10]) ls = iers.LeapSeconds.from_erfa() assert len(ls) == len(self.erfa_ls)-10 ls_array = np.array(ls['year', 'month', 'tai_utc']) assert np.all(ls_array == self.erfa_ls[:-10]) ls2 = iers.LeapSeconds.from_erfa(built_in=True) assert len(ls2) > len(ls) erfa.leap_seconds.set(None) erfa_built_in = erfa.leap_seconds.get() assert len(ls2) == len(erfa_built_in) ls2_array = np.array(ls2['year', 'month', 'tai_utc']) assert np.all(ls2_array == erfa_built_in) def test_open(self): ls = iers.LeapSeconds.open('erfa') assert isinstance(ls.expires, Time) assert ls.expires == self.erfa_expires ls_array = np.array(ls['year', 'month', 'tai_utc']) assert np.all(ls_array == self.erfa_ls) class TestUpdateLeapSeconds(ERFALeapSecondsSafe): def setup(self): super().setup() # Read default leap second table. self.ls = iers.LeapSeconds.from_iers_leap_seconds() # For tests, reset ERFA table to built-in default. erfa.leap_seconds.set() self.erfa_ls = erfa.leap_seconds.get() def test_built_in_up_to_date(self): """Leap second should match between built-in and ERFA.""" erfa_since_1970 = self.erfa_ls[self.erfa_ls['year'] > 1970] assert len(self.ls) >= len(erfa_since_1970), \ "built-in leap seconds out of date" assert len(self.ls) <= len(erfa_since_1970), \ "ERFA leap seconds out of date" overlap = np.array(self.ls['year', 'month', 'tai_utc']) assert np.all(overlap == erfa_since_1970.astype(overlap.dtype)) def test_update_with_built_in(self): """An update with built-in should not do anything.""" n_update = self.ls.update_erfa_leap_seconds() assert n_update == 0 new_erfa_ls = erfa.leap_seconds.get() assert np.all(new_erfa_ls == self.erfa_ls) @pytest.mark.parametrize('n_short', (1, 3)) def test_update(self, n_short): """Check whether we can recover removed leap seconds.""" erfa.leap_seconds.set(self.erfa_ls[:-n_short]) n_update = self.ls.update_erfa_leap_seconds() assert n_update == n_short new_erfa_ls = erfa.leap_seconds.get() assert_array_equal(new_erfa_ls, self.erfa_ls) # Check that a second update does not do anything. n_update2 = self.ls.update_erfa_leap_seconds() assert n_update2 == 0 new_erfa_ls2 = erfa.leap_seconds.get() assert_array_equal(new_erfa_ls2, self.erfa_ls) def test_update_initialize_erfa(self): # With pre-initialization, update does nothing. erfa.leap_seconds.set(self.erfa_ls[:-2]) n_update = self.ls.update_erfa_leap_seconds(initialize_erfa=True) assert n_update == 0 new_erfa_ls = erfa.leap_seconds.get() assert_array_equal(new_erfa_ls, self.erfa_ls) def test_update_overwrite(self): n_update = self.ls.update_erfa_leap_seconds(initialize_erfa='empty') assert n_update == len(self.ls) new_erfa_ls = erfa.leap_seconds.get() assert new_erfa_ls['year'].min() > 1970 n_update2 = self.ls.update_erfa_leap_seconds() assert n_update2 == 0 new_erfa_ls2 = erfa.leap_seconds.get() assert_array_equal(new_erfa_ls2, new_erfa_ls) n_update3 = self.ls.update_erfa_leap_seconds(initialize_erfa=True) assert n_update3 == 0 new_erfa_ls3 = erfa.leap_seconds.get() assert_array_equal(new_erfa_ls3, self.erfa_ls) def test_bad_jump(self): erfa.leap_seconds.set(self.erfa_ls[:-2]) bad = self.ls.copy() bad['tai_utc'][-1] = 5 with pytest.raises(ValueError, match='jump'): bad.update_erfa_leap_seconds() # With an error the ERFA table should not change. assert_array_equal(erfa.leap_seconds.get(), self.erfa_ls[:-2]) # Unless we initialized it beforehand. with pytest.raises(ValueError, match='jump'): bad.update_erfa_leap_seconds(initialize_erfa=True) assert_array_equal(erfa.leap_seconds.get(), self.erfa_ls) # Of course, we get no errors if we initialize only. erfa.leap_seconds.set(self.erfa_ls[:-2]) n_update = bad.update_erfa_leap_seconds(initialize_erfa='only') assert n_update == 0 new_erfa_ls = erfa.leap_seconds.get() assert_array_equal(new_erfa_ls, self.erfa_ls) def test_bad_day(self): erfa.leap_seconds.set(self.erfa_ls[:-2]) bad = self.ls.copy() bad['day'][-1] = 5 with pytest.raises(ValueError, match='not on 1st'): bad.update_erfa_leap_seconds() def test_bad_month(self): erfa.leap_seconds.set(self.erfa_ls[:-2]) bad = self.ls.copy() bad['month'][-1] = 5 with pytest.raises(ValueError, match='January'): bad.update_erfa_leap_seconds() assert_array_equal(erfa.leap_seconds.get(), self.erfa_ls[:-2]) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/introspection.py0000644000175100001710000003571400000000000020372 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """Functions related to Python runtime introspection.""" import collections import inspect import os import sys import types import importlib from importlib import metadata from packaging.version import Version from astropy.utils.decorators import deprecated_renamed_argument __all__ = ['resolve_name', 'minversion', 'find_current_module', 'isinstancemethod'] __doctest_skip__ = ['find_current_module'] if sys.version_info[:2] >= (3, 10): from importlib.metadata import packages_distributions else: def packages_distributions(): """ Return a mapping of top-level packages to their distributions. Note: copied from https://github.com/python/importlib_metadata/pull/287 """ pkg_to_dist = collections.defaultdict(list) for dist in metadata.distributions(): for pkg in (dist.read_text('top_level.txt') or '').split(): pkg_to_dist[pkg].append(dist.metadata['Name']) return dict(pkg_to_dist) def resolve_name(name, *additional_parts): """Resolve a name like ``module.object`` to an object and return it. This ends up working like ``from module import object`` but is easier to deal with than the `__import__` builtin and supports digging into submodules. Parameters ---------- name : `str` A dotted path to a Python object--that is, the name of a function, class, or other object in a module with the full path to that module, including parent modules, separated by dots. Also known as the fully qualified name of the object. additional_parts : iterable, optional If more than one positional arguments are given, those arguments are automatically dotted together with ``name``. Examples -------- >>> resolve_name('astropy.utils.introspection.resolve_name') >>> resolve_name('astropy', 'utils', 'introspection', 'resolve_name') Raises ------ `ImportError` If the module or named object is not found. """ additional_parts = '.'.join(additional_parts) if additional_parts: name = name + '.' + additional_parts parts = name.split('.') if len(parts) == 1: # No dots in the name--just a straight up module import cursor = 1 fromlist = [] else: cursor = len(parts) - 1 fromlist = [parts[-1]] module_name = parts[:cursor] while cursor > 0: try: ret = __import__('.'.join(module_name), fromlist=fromlist) break except ImportError: if cursor == 0: raise cursor -= 1 module_name = parts[:cursor] fromlist = [parts[cursor]] ret = '' for part in parts[cursor:]: try: ret = getattr(ret, part) except AttributeError: raise ImportError(name) return ret @deprecated_renamed_argument('version_path', None, '5.0') def minversion(module, version, inclusive=True, version_path='__version__'): """ Returns `True` if the specified Python module satisfies a minimum version requirement, and `False` if not. .. deprecated:: ``version_path`` is not used anymore and is deprecated in ``astropy`` 5.0. Parameters ---------- module : module or `str` An imported module of which to check the version, or the name of that module (in which case an import of that module is attempted-- if this fails `False` is returned). version : `str` The version as a string that this module must have at a minimum (e.g. ``'0.12'``). inclusive : `bool` The specified version meets the requirement inclusively (i.e. ``>=``) as opposed to strictly greater than (default: `True`). Examples -------- >>> import astropy >>> minversion(astropy, '0.4.4') True """ if isinstance(module, types.ModuleType): module_name = module.__name__ module_version = getattr(module, '__version__', None) elif isinstance(module, str): module_name = module module_version = None try: module = resolve_name(module_name) except ImportError: return False else: raise ValueError('module argument must be an actual imported ' 'module, or the import name of the module; ' f'got {repr(module)}') if module_version is None: try: module_version = metadata.version(module_name) except metadata.PackageNotFoundError: # Maybe the distribution name is different from package name. # Calling packages_distributions is costly so we do it only # if necessary, as only a few packages don't have the same # distribution name. dist_names = packages_distributions() module_version = metadata.version(dist_names[module_name][0]) if inclusive: return Version(module_version) >= Version(version) else: return Version(module_version) > Version(version) def find_current_module(depth=1, finddiff=False): """ Determines the module/package from which this function is called. This function has two modes, determined by the ``finddiff`` option. it will either simply go the requested number of frames up the call stack (if ``finddiff`` is False), or it will go up the call stack until it reaches a module that is *not* in a specified set. Parameters ---------- depth : int Specifies how far back to go in the call stack (0-indexed, so that passing in 0 gives back `astropy.utils.misc`). finddiff : bool or list If False, the returned ``mod`` will just be ``depth`` frames up from the current frame. Otherwise, the function will start at a frame ``depth`` up from current, and continue up the call stack to the first module that is *different* from those in the provided list. In this case, ``finddiff`` can be a list of modules or modules names. Alternatively, it can be True, which will use the module ``depth`` call stack frames up as the module the returned module most be different from. Returns ------- mod : module or None The module object or None if the package cannot be found. The name of the module is available as the ``__name__`` attribute of the returned object (if it isn't None). Raises ------ ValueError If ``finddiff`` is a list with an invalid entry. Examples -------- The examples below assume that there are two modules in a package named ``pkg``. ``mod1.py``:: def find1(): from astropy.utils import find_current_module print find_current_module(1).__name__ def find2(): from astropy.utils import find_current_module cmod = find_current_module(2) if cmod is None: print 'None' else: print cmod.__name__ def find_diff(): from astropy.utils import find_current_module print find_current_module(0,True).__name__ ``mod2.py``:: def find(): from .mod1 import find2 find2() With these modules in place, the following occurs:: >>> from pkg import mod1, mod2 >>> from astropy.utils import find_current_module >>> mod1.find1() pkg.mod1 >>> mod1.find2() None >>> mod2.find() pkg.mod2 >>> find_current_module(0) >>> mod1.find_diff() pkg.mod1 """ frm = inspect.currentframe() for i in range(depth): frm = frm.f_back if frm is None: return None if finddiff: currmod = _get_module_from_frame(frm) if finddiff is True: diffmods = [currmod] else: diffmods = [] for fd in finddiff: if inspect.ismodule(fd): diffmods.append(fd) elif isinstance(fd, str): diffmods.append(importlib.import_module(fd)) elif fd is True: diffmods.append(currmod) else: raise ValueError('invalid entry in finddiff') while frm: frmb = frm.f_back modb = _get_module_from_frame(frmb) if modb not in diffmods: return modb frm = frmb else: return _get_module_from_frame(frm) def _get_module_from_frame(frm): """Uses inspect.getmodule() to get the module that the current frame's code is running in. However, this does not work reliably for code imported from a zip file, so this provides a fallback mechanism for that case which is less reliable in general, but more reliable than inspect.getmodule() for this particular case. """ mod = inspect.getmodule(frm) if mod is not None: return mod # Check to see if we're importing from a bundle file. First ensure that # __file__ is available in globals; this is cheap to check to bail out # immediately if this fails if '__file__' in frm.f_globals and '__name__' in frm.f_globals: filename = frm.f_globals['__file__'] # Using __file__ from the frame's globals and getting it into the form # of an absolute path name with .py at the end works pretty well for # looking up the module using the same means as inspect.getmodule if filename[-4:].lower() in ('.pyc', '.pyo'): filename = filename[:-4] + '.py' filename = os.path.realpath(os.path.abspath(filename)) if filename in inspect.modulesbyfile: return sys.modules.get(inspect.modulesbyfile[filename]) # On Windows, inspect.modulesbyfile appears to have filenames stored # in lowercase, so we check for this case too. if filename.lower() in inspect.modulesbyfile: return sys.modules.get(inspect.modulesbyfile[filename.lower()]) # Otherwise there are still some even trickier things that might be possible # to track down the module, but we'll leave those out unless we find a case # where it's really necessary. So return None if the module is not found. return None def find_mod_objs(modname, onlylocals=False): """ Returns all the public attributes of a module referenced by name. .. note:: The returned list *not* include subpackages or modules of ``modname``, nor does it include private attributes (those that begin with '_' or are not in `__all__`). Parameters ---------- modname : str The name of the module to search. onlylocals : bool or list of str If `True`, only attributes that are either members of ``modname`` OR one of its modules or subpackages will be included. If it is a list of strings, those specify the possible packages that will be considered "local". Returns ------- localnames : list of str A list of the names of the attributes as they are named in the module ``modname`` . fqnames : list of str A list of the full qualified names of the attributes (e.g., ``astropy.utils.introspection.find_mod_objs``). For attributes that are simple variables, this is based on the local name, but for functions or classes it can be different if they are actually defined elsewhere and just referenced in ``modname``. objs : list of objects A list of the actual attributes themselves (in the same order as the other arguments) """ mod = resolve_name(modname) if hasattr(mod, '__all__'): pkgitems = [(k, mod.__dict__[k]) for k in mod.__all__] else: pkgitems = [(k, mod.__dict__[k]) for k in dir(mod) if k[0] != '_'] # filter out modules and pull the names and objs out ismodule = inspect.ismodule localnames = [k for k, v in pkgitems if not ismodule(v)] objs = [v for k, v in pkgitems if not ismodule(v)] # fully qualified names can be determined from the object's module fqnames = [] for obj, lnm in zip(objs, localnames): if hasattr(obj, '__module__') and hasattr(obj, '__name__'): fqnames.append(obj.__module__ + '.' + obj.__name__) else: fqnames.append(modname + '.' + lnm) if onlylocals: if onlylocals is True: onlylocals = [modname] valids = [any(fqn.startswith(nm) for nm in onlylocals) for fqn in fqnames] localnames = [e for i, e in enumerate(localnames) if valids[i]] fqnames = [e for i, e in enumerate(fqnames) if valids[i]] objs = [e for i, e in enumerate(objs) if valids[i]] return localnames, fqnames, objs # Note: I would have preferred call this is_instancemethod, but this naming is # for consistency with other functions in the `inspect` module def isinstancemethod(cls, obj): """ Returns `True` if the given object is an instance method of the class it is defined on (as opposed to a `staticmethod` or a `classmethod`). This requires both the class the object is a member of as well as the object itself in order to make this determination. Parameters ---------- cls : `type` The class on which this method was defined. obj : `object` A member of the provided class (the membership is not checked directly, but this function will always return `False` if the given object is not a member of the given class). Examples -------- >>> class MetaClass(type): ... def a_classmethod(cls): pass ... >>> class MyClass(metaclass=MetaClass): ... def an_instancemethod(self): pass ... ... @classmethod ... def another_classmethod(cls): pass ... ... @staticmethod ... def a_staticmethod(): pass ... >>> isinstancemethod(MyClass, MyClass.a_classmethod) False >>> isinstancemethod(MyClass, MyClass.another_classmethod) False >>> isinstancemethod(MyClass, MyClass.a_staticmethod) False >>> isinstancemethod(MyClass, MyClass.an_instancemethod) True """ return _isinstancemethod(cls, obj) def _isinstancemethod(cls, obj): if not isinstance(obj, types.FunctionType): return False # Unfortunately it seems the easiest way to get to the original # staticmethod object is to look in the class's __dict__, though we # also need to look up the MRO in case the method is not in the given # class's dict name = obj.__name__ for basecls in cls.mro(): # This includes cls if name in basecls.__dict__: return not isinstance(basecls.__dict__[name], staticmethod) # This shouldn't happen, though this is the most sensible response if # it does. raise AttributeError(name) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1952538 astropy-5.0.2/astropy/utils/masked/0000755000175100001710000000000000000000000016352 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/masked/__init__.py0000644000175100001710000000056100000000000020465 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ Built-in mask mixin class. The design uses `Masked` as a factory class which automatically generates new subclasses for any data class that is itself a subclass of a predefined masked class, with `MaskedNDArray` providing such a predefined class for `~numpy.ndarray`. """ from .core import * # noqa ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/masked/core.py0000644000175100001710000013142400000000000017661 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """ Built-in mask mixin class. The design uses `Masked` as a factory class which automatically generates new subclasses for any data class that is itself a subclass of a predefined masked class, with `MaskedNDArray` providing such a predefined class for `~numpy.ndarray`. Generally, any new predefined class should override the ``from_unmasked(data, mask, copy=False)`` class method that creates an instance from unmasked data and a mask, as well as the ``unmasked`` property that returns just the data. The `Masked` class itself provides a base ``mask`` property, which can also be overridden if needed. """ import builtins import numpy as np from astropy.utils.shapes import NDArrayShapeMethods from astropy.utils.data_info import ParentDtypeInfo from .function_helpers import (MASKED_SAFE_FUNCTIONS, APPLY_TO_BOTH_FUNCTIONS, DISPATCHED_FUNCTIONS, UNSUPPORTED_FUNCTIONS) __all__ = ['Masked', 'MaskedNDArray'] get__doc__ = """Masked version of {0.__name__}. Except for the ability to pass in a ``mask``, parameters are as for `{0.__module__}.{0.__name__}`. """.format class Masked(NDArrayShapeMethods): """A scalar value or array of values with associated mask. The resulting instance will take its exact type from whatever the contents are, with the type generated on the fly as needed. Parameters ---------- data : array-like The data for which a mask is to be added. The result will be a a subclass of the type of ``data``. mask : array-like of bool, optional The initial mask to assign. If not given, taken from the data. copy : bool Whether the data and mask should be copied. Default: `False`. """ _base_classes = {} """Explicitly defined masked classes keyed by their unmasked counterparts. For subclasses of these unmasked classes, masked counterparts can be generated. """ _masked_classes = {} """Masked classes keyed by their unmasked data counterparts.""" def __new__(cls, *args, **kwargs): if cls is Masked: # Initializing with Masked itself means we're in "factory mode". if not kwargs and len(args) == 1 and isinstance(args[0], type): # Create a new masked class. return cls._get_masked_cls(args[0]) else: return cls._get_masked_instance(*args, **kwargs) else: # Otherwise we're a subclass and should just pass information on. return super().__new__(cls, *args, **kwargs) def __init_subclass__(cls, base_cls=None, data_cls=None, **kwargs): """Register a Masked subclass. Parameters ---------- base_cls : type, optional If given, it is taken to mean that ``cls`` can be used as a base for masked versions of all subclasses of ``base_cls``, so it is registered as such in ``_base_classes``. data_cls : type, optional If given, ``cls`` should will be registered as the masked version of ``data_cls``. Will set the private ``cls._data_cls`` attribute, and auto-generate a docstring if not present already. **kwargs Passed on for possible further initialization by superclasses. """ if base_cls is not None: Masked._base_classes[base_cls] = cls if data_cls is not None: cls._data_cls = data_cls cls._masked_classes[data_cls] = cls if cls.__doc__ is None: cls.__doc__ = get__doc__(data_cls) super().__init_subclass__(**kwargs) # This base implementation just uses the class initializer. # Subclasses can override this in case the class does not work # with this signature, or to provide a faster implementation. @classmethod def from_unmasked(cls, data, mask=None, copy=False): """Create an instance from unmasked data and a mask.""" return cls(data, mask=mask, copy=copy) @classmethod def _get_masked_instance(cls, data, mask=None, copy=False): data, data_mask = cls._get_data_and_mask(data) if mask is None: mask = False if data_mask is None else data_mask masked_cls = cls._get_masked_cls(data.__class__) return masked_cls.from_unmasked(data, mask, copy) @classmethod def _get_masked_cls(cls, data_cls): """Get the masked wrapper for a given data class. If the data class does not exist yet but is a subclass of any of the registered base data classes, it is automatically generated (except we skip `~numpy.ma.MaskedArray` subclasses, since then the masking mechanisms would interfere). """ if issubclass(data_cls, (Masked, np.ma.MaskedArray)): return data_cls masked_cls = cls._masked_classes.get(data_cls) if masked_cls is None: # Walk through MRO and find closest base data class. # Note: right now, will basically always be ndarray, but # one could imagine needing some special care for one subclass, # which would then get its own entry. E.g., if MaskedAngle # defined something special, then MaskedLongitude should depend # on it. for mro_item in data_cls.__mro__: base_cls = cls._base_classes.get(mro_item) if base_cls is not None: break else: # Just hope that MaskedNDArray can handle it. # TODO: this covers the case where a user puts in a list or so, # but for those one could just explicitly do something like # _masked_classes[list] = MaskedNDArray. return MaskedNDArray # Create (and therefore register) new Masked subclass for the # given data_cls. masked_cls = type('Masked' + data_cls.__name__, (data_cls, base_cls), {}, data_cls=data_cls) return masked_cls @classmethod def _get_data_and_mask(cls, data, allow_ma_masked=False): """Split data into unmasked and mask, if present. Parameters ---------- data : array-like Possibly masked item, judged by whether it has a ``mask`` attribute. If so, checks for being an instance of `~astropy.utils.masked.Masked` or `~numpy.ma.MaskedArray`, and gets unmasked data appropriately. allow_ma_masked : bool, optional Whether or not to process `~numpy.ma.masked`, i.e., an item that implies no data but the presence of a mask. Returns ------- unmasked, mask : array-like Unmasked will be `None` for `~numpy.ma.masked`. Raises ------ ValueError If `~numpy.ma.masked` is passed in and ``allow_ma_masked`` is not set. """ mask = getattr(data, 'mask', None) if mask is not None: try: data = data.unmasked except AttributeError: if not isinstance(data, np.ma.MaskedArray): raise if data is np.ma.masked: if allow_ma_masked: data = None else: raise ValueError('cannot handle np.ma.masked here.') from None else: data = data.data return data, mask @classmethod def _get_data_and_masks(cls, *args): data_masks = [cls._get_data_and_mask(arg) for arg in args] return (tuple(data for data, _ in data_masks), tuple(mask for _, mask in data_masks)) def _get_mask(self): """The mask. If set, replace the original mask, with whatever it is set with, using a view if no broadcasting or type conversion is required. """ return self._mask def _set_mask(self, mask, copy=False): self_dtype = getattr(self, 'dtype', None) mask_dtype = (np.ma.make_mask_descr(self_dtype) if self_dtype and self_dtype.names else np.dtype('?')) ma = np.asanyarray(mask, dtype=mask_dtype) if ma.shape != self.shape: # This will fail (correctly) if not broadcastable. self._mask = np.empty(self.shape, dtype=mask_dtype) self._mask[...] = ma elif ma is mask: # Even if not copying use a view so that shape setting # does not propagate. self._mask = mask.copy() if copy else mask.view() else: self._mask = ma mask = property(_get_mask, _set_mask) # Note: subclass should generally override the unmasked property. # This one assumes the unmasked data is stored in a private attribute. @property def unmasked(self): """The unmasked values. See Also -------- astropy.utils.masked.Masked.filled """ return self._unmasked def filled(self, fill_value): """Get a copy of the underlying data, with masked values filled in. Parameters ---------- fill_value : object Value to replace masked values with. See Also -------- astropy.utils.masked.Masked.unmasked """ unmasked = self.unmasked.copy() if self.mask.dtype.names: np.ma.core._recursive_filled(unmasked, self.mask, fill_value) else: unmasked[self.mask] = fill_value return unmasked def _apply(self, method, *args, **kwargs): # Required method for NDArrayShapeMethods, to help provide __getitem__ # and shape-changing methods. if callable(method): data = method(self.unmasked, *args, **kwargs) mask = method(self.mask, *args, **kwargs) else: data = getattr(self.unmasked, method)(*args, **kwargs) mask = getattr(self.mask, method)(*args, **kwargs) result = self.from_unmasked(data, mask, copy=False) if 'info' in self.__dict__: result.info = self.info return result def __setitem__(self, item, value): value, mask = self._get_data_and_mask(value, allow_ma_masked=True) if value is not None: self.unmasked[item] = value self.mask[item] = mask class MaskedInfoBase: mask_val = np.ma.masked def __init__(self, bound=False): super().__init__(bound) # If bound to a data object instance then create the dict of attributes # which stores the info attribute values. if bound: # Specify how to serialize this object depending on context. self.serialize_method = {'fits': 'null_value', 'ecsv': 'null_value', 'hdf5': 'data_mask', 'parquet': 'data_mask', None: 'null_value'} class MaskedNDArrayInfo(MaskedInfoBase, ParentDtypeInfo): """ Container for meta information like name, description, format. """ # Add `serialize_method` attribute to the attrs that MaskedNDArrayInfo knows # about. This allows customization of the way that MaskedColumn objects # get written to file depending on format. The default is to use whatever # the writer would normally do, which in the case of FITS or ECSV is to use # a NULL value within the data itself. If serialize_method is 'data_mask' # then the mask is explicitly written out as a separate column if there # are any masked values. This is the same as for MaskedColumn. attr_names = ParentDtypeInfo.attr_names | {'serialize_method'} # When `serialize_method` is 'data_mask', and data and mask are being written # as separate columns, use column names and .mask (instead # of default encoding as .data and .mask). _represent_as_dict_primary_data = 'data' def _represent_as_dict(self): out = super()._represent_as_dict() masked_array = self._parent # If the serialize method for this context (e.g. 'fits' or 'ecsv') is # 'data_mask', that means to serialize using an explicit mask column. method = self.serialize_method[self._serialize_context] if method == 'data_mask': out['data'] = masked_array.unmasked if np.any(masked_array.mask): # Only if there are actually masked elements do we add the ``mask`` column out['mask'] = masked_array.mask elif method == 'null_value': out['data'] = np.ma.MaskedArray(masked_array.unmasked, mask=masked_array.mask) else: raise ValueError('serialize method must be either "data_mask" or "null_value"') return out def _construct_from_dict(self, map): # Override usual handling, since MaskedNDArray takes shape and buffer # as input, which is less useful here. # The map can contain either a MaskedColumn or a Column and a mask. # Extract the mask for the former case. map.setdefault('mask', getattr(map['data'], 'mask', False)) return self._parent_cls.from_unmasked(**map) class MaskedArraySubclassInfo(MaskedInfoBase): """Mixin class to create a subclasses such as MaskedQuantityInfo.""" # This is used below in __init_subclass__, which also inserts a # 'serialize_method' attribute in attr_names. def _represent_as_dict(self): # Use the data_cls as the class name for serialization, # so that we do not have to store all possible masked classes # in astropy.table.serialize.__construct_mixin_classes. out = super()._represent_as_dict() data_cls = self._parent._data_cls out.setdefault('__class__', data_cls.__module__ + '.' + data_cls.__name__) return out def _comparison_method(op): """ Create a comparison operator for MaskedNDArray. Needed since for string dtypes the base operators bypass __array_ufunc__ and hence return unmasked results. """ def _compare(self, other): other_data, other_mask = self._get_data_and_mask(other) result = getattr(self.unmasked, op)(other_data) if result is NotImplemented: return NotImplemented mask = self.mask | (other_mask if other_mask is not None else False) return self._masked_result(result, mask, None) return _compare class MaskedIterator: """ Flat iterator object to iterate over Masked Arrays. A `~astropy.utils.masked.MaskedIterator` iterator is returned by ``m.flat`` for any masked array ``m``. It allows iterating over the array as if it were a 1-D array, either in a for-loop or by calling its `next` method. Iteration is done in C-contiguous style, with the last index varying the fastest. The iterator can also be indexed using basic slicing or advanced indexing. Notes ----- The design of `~astropy.utils.masked.MaskedIterator` follows that of `~numpy.ma.core.MaskedIterator`. It is not exported by the `~astropy.utils.masked` module. Instead of instantiating directly, use the ``flat`` method in the masked array instance. """ def __init__(self, m): self._masked = m self._dataiter = m.unmasked.flat self._maskiter = m.mask.flat def __iter__(self): return self def __getitem__(self, indx): out = self._dataiter.__getitem__(indx) mask = self._maskiter.__getitem__(indx) # For single elements, ndarray.flat.__getitem__ returns scalars; these # need a new view as a Masked array. if not isinstance(out, np.ndarray): out = out[...] mask = mask[...] return self._masked.from_unmasked(out, mask, copy=False) def __setitem__(self, index, value): data, mask = self._masked._get_data_and_mask(value, allow_ma_masked=True) if data is not None: self._dataiter[index] = data self._maskiter[index] = mask def __next__(self): """ Return the next value, or raise StopIteration. """ out = next(self._dataiter)[...] mask = next(self._maskiter)[...] return self._masked.from_unmasked(out, mask, copy=False) next = __next__ class MaskedNDArray(Masked, np.ndarray, base_cls=np.ndarray, data_cls=np.ndarray): _mask = None info = MaskedNDArrayInfo() def __new__(cls, *args, mask=None, **kwargs): """Get data class instance from arguments and then set mask.""" self = super().__new__(cls, *args, **kwargs) if mask is not None: self.mask = mask elif self._mask is None: self.mask = False return self def __init_subclass__(cls, **kwargs): super().__init_subclass__(cls, **kwargs) # For all subclasses we should set a default __new__ that passes on # arguments other than mask to the data class, and then sets the mask. if '__new__' not in cls.__dict__: def __new__(newcls, *args, mask=None, **kwargs): """Get data class instance from arguments and then set mask.""" # Need to explicitly mention classes outside of class definition. self = super(cls, newcls).__new__(newcls, *args, **kwargs) if mask is not None: self.mask = mask elif self._mask is None: self.mask = False return self cls.__new__ = __new__ if 'info' not in cls.__dict__ and hasattr(cls._data_cls, 'info'): data_info = cls._data_cls.info attr_names = data_info.attr_names | {'serialize_method'} new_info = type(cls.__name__+'Info', (MaskedArraySubclassInfo, data_info.__class__), dict(attr_names=attr_names)) cls.info = new_info() # The two pieces typically overridden. @classmethod def from_unmasked(cls, data, mask=None, copy=False): # Note: have to override since __new__ would use ndarray.__new__ # which expects the shape as its first argument, not an array. data = np.array(data, subok=True, copy=copy) self = data.view(cls) self._set_mask(mask, copy=copy) return self @property def unmasked(self): return super().view(self._data_cls) @classmethod def _get_masked_cls(cls, data_cls): # Short-cuts if data_cls is np.ndarray: return MaskedNDArray elif data_cls is None: # for .view() return cls return super()._get_masked_cls(data_cls) @property def flat(self): """A 1-D iterator over the Masked array. This returns a ``MaskedIterator`` instance, which behaves the same as the `~numpy.flatiter` instance returned by `~numpy.ndarray.flat`, and is similar to Python's built-in iterator, except that it also allows assignment. """ return MaskedIterator(self) @property def _baseclass(self): """Work-around for MaskedArray initialization. Allows the base class to be inferred correctly when a masked instance is used to initialize (or viewed as) a `~numpy.ma.MaskedArray`. """ return self._data_cls def view(self, dtype=None, type=None): """New view of the masked array. Like `numpy.ndarray.view`, but always returning a masked array subclass. """ if type is None and (isinstance(dtype, builtins.type) and issubclass(dtype, np.ndarray)): return super().view(self._get_masked_cls(dtype)) if dtype is None: return super().view(self._get_masked_cls(type)) dtype = np.dtype(dtype) if not (dtype.itemsize == self.dtype.itemsize and (dtype.names is None or len(dtype.names) == len(self.dtype.names))): raise NotImplementedError( f"{self.__class__} cannot be viewed with a dtype with a " f"with a different number of fields or size.") return super().view(dtype, self._get_masked_cls(type)) def __array_finalize__(self, obj): # If we're a new object or viewing an ndarray, nothing has to be done. if obj is None or obj.__class__ is np.ndarray: return # Logically, this should come from ndarray and hence be None, but # just in case someone creates a new mixin, we check. super_array_finalize = super().__array_finalize__ if super_array_finalize: # pragma: no cover super_array_finalize(obj) if self._mask is None: # Got here after, e.g., a view of another masked class. # Get its mask, or initialize ours. self._set_mask(getattr(obj, '_mask', False)) if 'info' in obj.__dict__: self.info = obj.info @property def shape(self): """The shape of the data and the mask. Usually used to get the current shape of an array, but may also be used to reshape the array in-place by assigning a tuple of array dimensions to it. As with `numpy.reshape`, one of the new shape dimensions can be -1, in which case its value is inferred from the size of the array and the remaining dimensions. Raises ------ AttributeError If a copy is required, of either the data or the mask. """ # Redefinition to allow defining a setter and add a docstring. return super().shape @shape.setter def shape(self, shape): old_shape = self.shape self._mask.shape = shape # Reshape array proper in try/except just in case some broadcasting # or so causes it to fail. try: super(MaskedNDArray, type(self)).shape.__set__(self, shape) except Exception as exc: self._mask.shape = old_shape # Given that the mask reshaping succeeded, the only logical # reason for an exception is something like a broadcast error in # in __array_finalize__, or a different memory ordering between # mask and data. For those, give a more useful error message; # otherwise just raise the error. if 'could not broadcast' in exc.args[0]: raise AttributeError( 'Incompatible shape for in-place modification. ' 'Use `.reshape()` to make a copy with the desired ' 'shape.') from None else: # pragma: no cover raise _eq_simple = _comparison_method('__eq__') _ne_simple = _comparison_method('__ne__') __lt__ = _comparison_method('__lt__') __le__ = _comparison_method('__le__') __gt__ = _comparison_method('__gt__') __ge__ = _comparison_method('__ge__') def __eq__(self, other): if not self.dtype.names: return self._eq_simple(other) # For structured arrays, we treat this as a reduction over the fields, # where masked fields are skipped and thus do not influence the result. other = np.asanyarray(other, dtype=self.dtype) result = np.stack([self[field] == other[field] for field in self.dtype.names], axis=-1) return result.all(axis=-1) def __ne__(self, other): if not self.dtype.names: return self._ne_simple(other) # For structured arrays, we treat this as a reduction over the fields, # where masked fields are skipped and thus do not influence the result. other = np.asanyarray(other, dtype=self.dtype) result = np.stack([self[field] != other[field] for field in self.dtype.names], axis=-1) return result.any(axis=-1) def _combine_masks(self, masks, out=None): masks = [m for m in masks if m is not None and m is not False] if not masks: return False if len(masks) == 1: if out is None: return masks[0].copy() else: np.copyto(out, masks[0]) return out out = np.logical_or(masks[0], masks[1], out=out) for mask in masks[2:]: np.logical_or(out, mask, out=out) return out def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): out = kwargs.pop('out', None) out_unmasked = None out_mask = None if out is not None: out_unmasked, out_masks = self._get_data_and_masks(*out) for d, m in zip(out_unmasked, out_masks): if m is None: # TODO: allow writing to unmasked output if nothing is masked? if d is not None: raise TypeError('cannot write to unmasked output') elif out_mask is None: out_mask = m unmasked, masks = self._get_data_and_masks(*inputs) if ufunc.signature: # We're dealing with a gufunc. For now, only deal with # np.matmul and gufuncs for which the mask of any output always # depends on all core dimension values of all inputs. # Also ignore axes keyword for now... # TODO: in principle, it should be possible to generate the mask # purely based on the signature. if 'axes' in kwargs: raise NotImplementedError("Masked does not yet support gufunc " "calls with 'axes'.") if ufunc is np.matmul: # np.matmul is tricky and its signature cannot be parsed by # _parse_gufunc_signature. unmasked = np.atleast_1d(*unmasked) mask0, mask1 = masks masks = [] is_mat1 = unmasked[1].ndim >= 2 if mask0 is not None: masks.append( np.logical_or.reduce(mask0, axis=-1, keepdims=is_mat1)) if mask1 is not None: masks.append( np.logical_or.reduce(mask1, axis=-2, keepdims=True) if is_mat1 else np.logical_or.reduce(mask1)) mask = self._combine_masks(masks, out=out_mask) else: # Parse signature with private numpy function. Note it # cannot handle spaces in tuples, so remove those. in_sig, out_sig = np.lib.function_base._parse_gufunc_signature( ufunc.signature.replace(' ', '')) axis = kwargs.get('axis', -1) keepdims = kwargs.get('keepdims', False) in_masks = [] for sig, mask in zip(in_sig, masks): if mask is not None: if sig: # Input has core dimensions. Assume that if any # value in those is masked, the output will be # masked too (TODO: for multiple core dimensions # this may be too strong). mask = np.logical_or.reduce( mask, axis=axis, keepdims=keepdims) in_masks.append(mask) mask = self._combine_masks(in_masks) result_masks = [] for os in out_sig: if os: # Output has core dimensions. Assume all those # get the same mask. result_mask = np.expand_dims(mask, axis) else: result_mask = mask result_masks.append(result_mask) mask = result_masks if len(result_masks) > 1 else result_masks[0] elif method == '__call__': # Regular ufunc call. mask = self._combine_masks(masks, out=out_mask) elif method == 'outer': # Must have two arguments; adjust masks as will be done for data. assert len(masks) == 2 masks = [(m if m is not None else False) for m in masks] mask = np.logical_or.outer(masks[0], masks[1], out=out_mask) elif method in {'reduce', 'accumulate'}: # Reductions like np.add.reduce (sum). if masks[0] is not None: # By default, we simply propagate masks, since for # things like np.sum, it makes no sense to do otherwise. # Individual methods need to override as needed. # TODO: take care of 'out' too? if method == 'reduce': axis = kwargs.get('axis', None) keepdims = kwargs.get('keepdims', False) where = kwargs.get('where', True) mask = np.logical_or.reduce(masks[0], where=where, axis=axis, keepdims=keepdims, out=out_mask) if where is not True: # Mask also whole rows that were not selected by where, # so would have been left as unmasked above. mask |= np.logical_and.reduce(masks[0], where=where, axis=axis, keepdims=keepdims) else: # Accumulate axis = kwargs.get('axis', 0) mask = np.logical_or.accumulate(masks[0], axis=axis, out=out_mask) elif out is not None: mask = False else: # pragma: no cover # Can only get here if neither input nor output was masked, but # perhaps axis or where was masked (in numpy < 1.21 this is # possible). We don't support this. return NotImplemented elif method in {'reduceat', 'at'}: # pragma: no cover # TODO: implement things like np.add.accumulate (used for cumsum). raise NotImplementedError("masked instances cannot yet deal with " "'reduceat' or 'at'.") if out_unmasked is not None: kwargs['out'] = out_unmasked result = getattr(ufunc, method)(*unmasked, **kwargs) if result is None: # pragma: no cover # This happens for the "at" method. return result if out is not None and len(out) == 1: out = out[0] return self._masked_result(result, mask, out) def __array_function__(self, function, types, args, kwargs): # TODO: go through functions systematically to see which ones # work and/or can be supported. if function in MASKED_SAFE_FUNCTIONS: return super().__array_function__(function, types, args, kwargs) elif function in APPLY_TO_BOTH_FUNCTIONS: helper = APPLY_TO_BOTH_FUNCTIONS[function] try: helper_result = helper(*args, **kwargs) except NotImplementedError: return self._not_implemented_or_raise(function, types) data_args, mask_args, kwargs, out = helper_result if out is not None: if not isinstance(out, Masked): return self._not_implemented_or_raise(function, types) function(*mask_args, out=out.mask, **kwargs) function(*data_args, out=out.unmasked, **kwargs) return out mask = function(*mask_args, **kwargs) result = function(*data_args, **kwargs) elif function in DISPATCHED_FUNCTIONS: dispatched_function = DISPATCHED_FUNCTIONS[function] try: dispatched_result = dispatched_function(*args, **kwargs) except NotImplementedError: return self._not_implemented_or_raise(function, types) if not isinstance(dispatched_result, tuple): return dispatched_result result, mask, out = dispatched_result elif function in UNSUPPORTED_FUNCTIONS: return NotImplemented else: # pragma: no cover # By default, just pass it through for now. return super().__array_function__(function, types, args, kwargs) if mask is None: return result else: return self._masked_result(result, mask, out) def _not_implemented_or_raise(self, function, types): # Our function helper or dispatcher found that the function does not # work with Masked. In principle, there may be another class that # knows what to do with us, for which we should return NotImplemented. # But if there is ndarray (or a non-Masked subclass of it) around, # it quite likely coerces, so we should just break. if any(issubclass(t, np.ndarray) and not issubclass(t, Masked) for t in types): raise TypeError("the MaskedNDArray implementation cannot handle {} " "with the given arguments." .format(function)) from None else: return NotImplemented def _masked_result(self, result, mask, out): if isinstance(result, tuple): if out is None: out = (None,) * len(result) if not isinstance(mask, (list, tuple)): mask = (mask,) * len(result) return tuple(self._masked_result(result_, mask_, out_) for (result_, mask_, out_) in zip(result, mask, out)) if out is None: # Note that we cannot count on result being the same class as # 'self' (e.g., comparison of quantity results in an ndarray, most # operations on Longitude and Latitude result in Angle or # Quantity), so use Masked to determine the appropriate class. return Masked(result, mask) # TODO: remove this sanity check once test cases are more complete. assert isinstance(out, Masked) # If we have an output, the result was written in-place, so we should # also write the mask in-place (if not done already in the code). if out._mask is not mask: out._mask[...] = mask return out # Below are ndarray methods that need to be overridden as masked elements # need to be skipped and/or an initial value needs to be set. def _reduce_defaults(self, kwargs, initial_func=None): """Get default where and initial for masked reductions. Generally, the default should be to skip all masked elements. For reductions such as np.minimum.reduce, we also need an initial value, which can be determined using ``initial_func``. """ if 'where' not in kwargs: kwargs['where'] = ~self.mask if initial_func is not None and 'initial' not in kwargs: kwargs['initial'] = initial_func(self.unmasked) return kwargs def trace(self, offset=0, axis1=0, axis2=1, dtype=None, out=None): # Unfortunately, cannot override the call to diagonal inside trace, so # duplicate implementation in numpy/core/src/multiarray/calculation.c. diagonal = self.diagonal(offset=offset, axis1=axis1, axis2=axis2) return diagonal.sum(-1, dtype=dtype, out=out) def min(self, axis=None, out=None, **kwargs): return super().min(axis=axis, out=out, **self._reduce_defaults(kwargs, np.nanmax)) def max(self, axis=None, out=None, **kwargs): return super().max(axis=axis, out=out, **self._reduce_defaults(kwargs, np.nanmin)) def nonzero(self): unmasked_nonzero = self.unmasked.nonzero() if self.ndim >= 1: not_masked = ~self.mask[unmasked_nonzero] return tuple(u[not_masked] for u in unmasked_nonzero) else: return unmasked_nonzero if not self.mask else np.nonzero(0) def compress(self, condition, axis=None, out=None): if out is not None: raise NotImplementedError('cannot yet give output') return self._apply('compress', condition, axis=axis) def repeat(self, repeats, axis=None): return self._apply('repeat', repeats, axis=axis) def choose(self, choices, out=None, mode='raise'): # Let __array_function__ take care since choices can be masked too. return np.choose(self, choices, out=out, mode=mode) def argmin(self, axis=None, out=None): # Todo: should this return a masked integer array, with masks # if all elements were masked? at_min = self == self.min(axis=axis, keepdims=True) return at_min.filled(False).argmax(axis=axis, out=out) def argmax(self, axis=None, out=None): at_max = self == self.max(axis=axis, keepdims=True) return at_max.filled(False).argmax(axis=axis, out=out) def argsort(self, axis=-1, kind=None, order=None): """Returns the indices that would sort an array. Perform an indirect sort along the given axis on both the array and the mask, with masked items being sorted to the end. Parameters ---------- axis : int or None, optional Axis along which to sort. The default is -1 (the last axis). If None, the flattened array is used. kind : str or None, ignored. The kind of sort. Present only to allow subclasses to work. order : str or list of str. For an array with fields defined, the fields to compare first, second, etc. A single field can be specified as a string, and not all fields need be specified, but unspecified fields will still be used, in dtype order, to break ties. Returns ------- index_array : ndarray, int Array of indices that sorts along the specified ``axis``. Use ``np.take_along_axis(self, index_array, axis=axis)`` to obtain the sorted array. """ if axis is None: data = self.ravel() axis = -1 else: data = self if self.dtype.names: # As done inside the argsort implementation in multiarray/methods.c. if order is None: order = self.dtype.names else: order = np.core._internal._newnames(self.dtype, order) keys = tuple(data[name] for name in order[::-1]) elif order is not None: raise ValueError('Cannot specify order when the array has no fields.') else: keys = (data,) return np.lexsort(keys, axis=axis) def sort(self, axis=-1, kind=None, order=None): """Sort an array in-place. Refer to `numpy.sort` for full documentation.""" # TODO: probably possible to do this faster than going through argsort! indices = self.argsort(axis, kind=kind, order=order) self[:] = np.take_along_axis(self, indices, axis=axis) def argpartition(self, kth, axis=-1, kind='introselect', order=None): # TODO: should be possible to do this faster than with a full argsort! return self.argsort(axis=axis, order=order) def partition(self, kth, axis=-1, kind='introselect', order=None): # TODO: should be possible to do this faster than with a full argsort! return self.sort(axis=axis, order=None) def cumsum(self, axis=None, dtype=None, out=None): if axis is None: self = self.ravel() axis = 0 return np.add.accumulate(self, axis=axis, dtype=dtype, out=out) def cumprod(self, axis=None, dtype=None, out=None): if axis is None: self = self.ravel() axis = 0 return np.multiply.accumulate(self, axis=axis, dtype=dtype, out=out) def clip(self, min=None, max=None, out=None, **kwargs): """Return an array whose values are limited to ``[min, max]``. Like `~numpy.clip`, but any masked values in ``min`` and ``max`` are ignored for clipping. The mask of the input array is propagated. """ # TODO: implement this at the ufunc level. dmin, mmin = self._get_data_and_mask(min) dmax, mmax = self._get_data_and_mask(max) if mmin is None and mmax is None: # Fast path for unmasked max, min. return super().clip(min, max, out=out, **kwargs) masked_out = np.positive(self, out=out) out = masked_out.unmasked if dmin is not None: np.maximum(out, dmin, out=out, where=True if mmin is None else ~mmin) if dmax is not None: np.minimum(out, dmax, out=out, where=True if mmax is None else ~mmax) return masked_out def mean(self, axis=None, dtype=None, out=None, keepdims=False): # Implementation based on that in numpy/core/_methods.py # Cast bool, unsigned int, and int to float64 by default, # and do float16 at higher precision. is_float16_result = False if dtype is None: if issubclass(self.dtype.type, (np.integer, np.bool_)): dtype = np.dtype('f8') elif issubclass(self.dtype.type, np.float16): dtype = np.dtype('f4') is_float16_result = out is None result = self.sum(axis=axis, dtype=dtype, out=out, keepdims=keepdims, where=~self.mask) n = np.add.reduce(~self.mask, axis=axis, keepdims=keepdims) result /= n if is_float16_result: result = result.astype(self.dtype) return result def var(self, axis=None, dtype=None, out=None, ddof=0, keepdims=False): # Simplified implementation based on that in numpy/core/_methods.py n = np.add.reduce(~self.mask, axis=axis, keepdims=keepdims)[...] # Cast bool, unsigned int, and int to float64 by default. if dtype is None and issubclass(self.dtype.type, (np.integer, np.bool_)): dtype = np.dtype('f8') mean = self.mean(axis=axis, dtype=dtype, keepdims=True) x = self - mean x *= x.conjugate() # Conjugate just returns x if not complex. result = x.sum(axis=axis, dtype=dtype, out=out, keepdims=keepdims, where=~x.mask) n -= ddof n = np.maximum(n, 0, out=n) result /= n result._mask |= (n == 0) return result def std(self, axis=None, dtype=None, out=None, ddof=0, keepdims=False): result = self.var(axis=axis, dtype=dtype, out=out, ddof=ddof, keepdims=keepdims) return np.sqrt(result, out=result) def __bool__(self): # First get result from array itself; this will error if not a scalar. result = super().__bool__() return result and not self.mask def any(self, axis=None, out=None, keepdims=False): return np.logical_or.reduce(self, axis=axis, out=out, keepdims=keepdims, where=~self.mask) def all(self, axis=None, out=None, keepdims=False): return np.logical_and.reduce(self, axis=axis, out=out, keepdims=keepdims, where=~self.mask) # Following overrides needed since somehow the ndarray implementation # does not actually call these. def __str__(self): return np.array_str(self) def __repr__(self): return np.array_repr(self) def __format__(self, format_spec): string = super().__format__(format_spec) if self.shape == () and self.mask: n = min(3, max(1, len(string))) return ' ' * (len(string)-n) + '\u2014' * n else: return string class MaskedRecarray(np.recarray, MaskedNDArray, data_cls=np.recarray): # Explicit definition since we need to override some methods. def __array_finalize__(self, obj): # recarray.__array_finalize__ does not do super, so we do it # explicitly. super().__array_finalize__(obj) super(np.recarray, self).__array_finalize__(obj) # __getattribute__, __setattr__, and field use these somewhat # obscrure ndarray methods. TODO: override in MaskedNDArray? def getfield(self, dtype, offset=0): for field, info in self.dtype.fields.items(): if offset == info[1] and dtype == info[0]: return self[field] raise NotImplementedError('can only get existing field from ' 'structured dtype.') def setfield(self, val, dtype, offset=0): for field, info in self.dtype.fields.items(): if offset == info[1] and dtype == info[0]: self[field] = val return raise NotImplementedError('can only set existing field from ' 'structured dtype.') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/masked/function_helpers.py0000644000175100001710000010331500000000000022276 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """Helpers for letting numpy functions interact with Masked arrays. The module supplies helper routines for numpy functions that propagate masks appropriately., for use in the ``__array_function__`` implementation of `~astropy.utils.masked.MaskedNDArray`. They are not very useful on their own, but the ones with docstrings are included in the documentation so that there is a place to find out how the mask is interpreted. """ import numpy as np from astropy.units.quantity_helper.function_helpers import ( FunctionAssigner) from astropy.utils.compat import NUMPY_LT_1_19, NUMPY_LT_1_20, NUMPY_LT_1_23 # This module should not really be imported, but we define __all__ # such that sphinx can typeset the functions with docstrings. # The latter are added to __all__ at the end. __all__ = ['MASKED_SAFE_FUNCTIONS', 'APPLY_TO_BOTH_FUNCTIONS', 'DISPATCHED_FUNCTIONS', 'UNSUPPORTED_FUNCTIONS'] MASKED_SAFE_FUNCTIONS = set() """Set of functions that work fine on Masked classes already. Most of these internally use `numpy.ufunc` or other functions that are already covered. """ APPLY_TO_BOTH_FUNCTIONS = {} """Dict of functions that should apply to both data and mask. The `dict` is keyed by the numpy function and the values are functions that take the input arguments of the numpy function and organize these for passing the data and mask to the numpy function. Returns ------- data_args : tuple Arguments to pass on to the numpy function for the unmasked data. mask_args : tuple Arguments to pass on to the numpy function for the masked data. kwargs : dict Keyword arguments to pass on for both unmasked data and mask. out : `~astropy.utils.masked.Masked` instance or None Optional instance in which to store the output. Raises ------ NotImplementedError When an arguments is masked when it should not be or vice versa. """ DISPATCHED_FUNCTIONS = {} """Dict of functions that provide the numpy function's functionality. These are for more complicated versions where the numpy function itself cannot easily be used. It should return either the result of the function, or a tuple consisting of the unmasked result, the mask for the result and a possible output instance. It should raise `NotImplementedError` if one of the arguments is masked when it should not be or vice versa. """ UNSUPPORTED_FUNCTIONS = set() """Set of numpy functions that are not supported for masked arrays. For most, masked input simply makes no sense, but for others it may have been lack of time. Issues or PRs for support for functions are welcome. """ # Almost all from np.core.fromnumeric defer to methods so are OK. MASKED_SAFE_FUNCTIONS |= set( getattr(np, name) for name in np.core.fromnumeric.__all__ if name not in ({'choose', 'put', 'resize', 'searchsorted', 'where', 'alen'})) MASKED_SAFE_FUNCTIONS |= { # built-in from multiarray np.may_share_memory, np.can_cast, np.min_scalar_type, np.result_type, np.shares_memory, # np.core.arrayprint np.array_repr, # np.core.function_base np.linspace, np.logspace, np.geomspace, # np.core.numeric np.isclose, np.allclose, np.flatnonzero, np.argwhere, # np.core.shape_base np.atleast_1d, np.atleast_2d, np.atleast_3d, np.stack, np.hstack, np.vstack, # np.lib.function_base np.average, np.diff, np.extract, np.meshgrid, np.trapz, np.gradient, # np.lib.index_tricks np.diag_indices_from, np.triu_indices_from, np.tril_indices_from, np.fill_diagonal, # np.lib.shape_base np.column_stack, np.row_stack, np.dstack, np.array_split, np.split, np.hsplit, np.vsplit, np.dsplit, np.expand_dims, np.apply_along_axis, np.kron, np.tile, np.take_along_axis, np.put_along_axis, # np.lib.type_check (all but asfarray, nan_to_num) np.iscomplexobj, np.isrealobj, np.imag, np.isreal, np.real, np.real_if_close, np.common_type, # np.lib.ufunclike np.fix, np.isneginf, np.isposinf, # np.lib.function_base np.angle, np.i0, } IGNORED_FUNCTIONS = { # I/O - useless for Masked, since no way to store the mask. np.save, np.savez, np.savetxt, np.savez_compressed, # Polynomials np.poly, np.polyadd, np.polyder, np.polydiv, np.polyfit, np.polyint, np.polymul, np.polysub, np.polyval, np.roots, np.vander} if NUMPY_LT_1_20: # financial IGNORED_FUNCTIONS |= {np.fv, np.ipmt, np.irr, np.mirr, np.nper, np.npv, np.pmt, np.ppmt, np.pv, np.rate} # TODO: some of the following could in principle be supported. IGNORED_FUNCTIONS |= { np.pad, np.searchsorted, np.digitize, np.is_busday, np.busday_count, np.busday_offset, # numpy.lib.function_base np.cov, np.corrcoef, np.trim_zeros, # numpy.core.numeric np.correlate, np.convolve, # numpy.lib.histograms np.histogram, np.histogram2d, np.histogramdd, np.histogram_bin_edges, # TODO!! np.dot, np.vdot, np.inner, np.tensordot, np.cross, np.einsum, np.einsum_path, } # Really should do these... IGNORED_FUNCTIONS |= set(getattr(np, setopsname) for setopsname in np.lib.arraysetops.__all__) if NUMPY_LT_1_23: IGNORED_FUNCTIONS |= { # Deprecated, removed in numpy 1.23 np.asscalar, np.alen, } # Explicitly unsupported functions UNSUPPORTED_FUNCTIONS |= { np.unravel_index, np.ravel_multi_index, np.ix_, } # No support for the functions also not supported by Quantity # (io, polynomial, etc.). UNSUPPORTED_FUNCTIONS |= IGNORED_FUNCTIONS apply_to_both = FunctionAssigner(APPLY_TO_BOTH_FUNCTIONS) dispatched_function = FunctionAssigner(DISPATCHED_FUNCTIONS) def _get_data_and_masks(*args): """Separate out arguments into tuples of data and masks. An all-False mask is created if an argument does not have a mask. """ from .core import Masked data, masks = Masked._get_data_and_masks(*args) masks = tuple(m if m is not None else np.zeros(np.shape(d), bool) for d, m in zip(data, masks)) return data, masks # Following are simple ufunc-like functions which should just copy the mask. @dispatched_function def datetime_as_string(arr, *args, **kwargs): return (np.datetime_as_string(arr.unmasked, *args, **kwargs), arr.mask.copy(), None) @dispatched_function def sinc(x): return np.sinc(x.unmasked), x.mask.copy(), None @dispatched_function def iscomplex(x): return np.iscomplex(x.unmasked), x.mask.copy(), None @dispatched_function def unwrap(p, *args, **kwargs): return np.unwrap(p.unmasked, *args, **kwargs), p.mask.copy(), None @dispatched_function def nan_to_num(x, copy=True, nan=0.0, posinf=None, neginf=None): data = np.nan_to_num(x.unmasked, copy=copy, nan=nan, posinf=posinf, neginf=neginf) return (data, x.mask.copy(), None) if copy else x # Following are simple functions related to shapes, where the same function # should be applied to the data and the mask. They cannot all share the # same helper, because the first arguments have different names. @apply_to_both(helps={ np.copy, np.asfarray, np.resize, np.moveaxis, np.rollaxis, np.roll}) def masked_a_helper(a, *args, **kwargs): data, mask = _get_data_and_masks(a) return data + args, mask + args, kwargs, None @apply_to_both(helps={np.flip, np.flipud, np.fliplr, np.rot90, np.triu, np.tril}) def masked_m_helper(m, *args, **kwargs): data, mask = _get_data_and_masks(m) return data + args, mask + args, kwargs, None @apply_to_both(helps={np.diag, np.diagflat}) def masked_v_helper(v, *args, **kwargs): data, mask = _get_data_and_masks(v) return data + args, mask + args, kwargs, None @apply_to_both(helps={np.delete}) def masked_arr_helper(array, *args, **kwargs): data, mask = _get_data_and_masks(array) return data + args, mask + args, kwargs, None @apply_to_both def broadcast_to(array, shape, subok=False): """Broadcast array to the given shape. Like `numpy.broadcast_to`, and applied to both unmasked data and mask. Note that ``subok`` is taken to mean whether or not subclasses of the unmasked data and mask are allowed, i.e., for ``subok=False``, a `~astropy.utils.masked.MaskedNDArray` will be returned. """ data, mask = _get_data_and_masks(array) return data, mask, dict(shape=shape, subok=subok), None @dispatched_function def outer(a, b, out=None): return np.multiply.outer(np.ravel(a), np.ravel(b), out=out) @dispatched_function def empty_like(prototype, dtype=None, order='K', subok=True, shape=None): """Return a new array with the same shape and type as a given array. Like `numpy.empty_like`, but will add an empty mask. """ unmasked = np.empty_like(prototype.unmasked, dtype=dtype, order=order, subok=subok, shape=shape) if dtype is not None: dtype = (np.ma.make_mask_descr(unmasked.dtype) if unmasked.dtype.names else np.dtype('?')) mask = np.empty_like(prototype.mask, dtype=dtype, order=order, subok=subok, shape=shape) return unmasked, mask, None @dispatched_function def zeros_like(a, dtype=None, order='K', subok=True, shape=None): """Return an array of zeros with the same shape and type as a given array. Like `numpy.zeros_like`, but will add an all-false mask. """ unmasked = np.zeros_like(a.unmasked, dtype=dtype, order=order, subok=subok, shape=shape) return unmasked, False, None @dispatched_function def ones_like(a, dtype=None, order='K', subok=True, shape=None): """Return an array of ones with the same shape and type as a given array. Like `numpy.ones_like`, but will add an all-false mask. """ unmasked = np.ones_like(a.unmasked, dtype=dtype, order=order, subok=subok, shape=shape) return unmasked, False, None @dispatched_function def full_like(a, fill_value, dtype=None, order='K', subok=True, shape=None): """Return a full array with the same shape and type as a given array. Like `numpy.full_like`, but with a mask that is also set. If ``fill_value`` is `numpy.ma.masked`, the data will be left unset (i.e., as created by `numpy.empty_like`). """ result = np.empty_like(a, dtype=dtype, order=order, subok=subok, shape=shape) result[...] = fill_value return result @dispatched_function def put(a, ind, v, mode='raise'): """Replaces specified elements of an array with given values. Like `numpy.put`, but for masked array ``a`` and possibly masked value ``v``. Masked indices ``ind`` are not supported. """ from astropy.utils.masked import Masked if isinstance(ind, Masked) or not isinstance(a, Masked): raise NotImplementedError v_data, v_mask = a._get_data_and_mask(v) if v_data is not None: np.put(a.unmasked, ind, v_data, mode=mode) # v_mask of None will be correctly interpreted as False. np.put(a.mask, ind, v_mask, mode=mode) return None @dispatched_function def putmask(a, mask, values): """Changes elements of an array based on conditional and input values. Like `numpy.putmask`, but for masked array ``a`` and possibly masked ``values``. Masked ``mask`` is not supported. """ from astropy.utils.masked import Masked if isinstance(mask, Masked) or not isinstance(a, Masked): raise NotImplementedError values_data, values_mask = a._get_data_and_mask(values) if values_data is not None: np.putmask(a.unmasked, mask, values_data) np.putmask(a.mask, mask, values_mask) return None @dispatched_function def place(arr, mask, vals): """Change elements of an array based on conditional and input values. Like `numpy.place`, but for masked array ``a`` and possibly masked ``values``. Masked ``mask`` is not supported. """ from astropy.utils.masked import Masked if isinstance(mask, Masked) or not isinstance(arr, Masked): raise NotImplementedError vals_data, vals_mask = arr._get_data_and_mask(vals) if vals_data is not None: np.place(arr.unmasked, mask, vals_data) np.place(arr.mask, mask, vals_mask) return None @dispatched_function def copyto(dst, src, casting='same_kind', where=True): """Copies values from one array to another, broadcasting as necessary. Like `numpy.copyto`, but for masked destination ``dst`` and possibly masked source ``src``. """ from astropy.utils.masked import Masked if not isinstance(dst, Masked) or isinstance(where, Masked): raise NotImplementedError src_data, src_mask = dst._get_data_and_mask(src) if src_data is not None: np.copyto(dst.unmasked, src_data, casting=casting, where=where) if src_mask is not None: np.copyto(dst.mask, src_mask, where=where) return None @dispatched_function def packbits(a, *args, **kwargs): result = np.packbits(a.unmasked, *args, **kwargs) mask = np.packbits(a.mask, *args, **kwargs).astype(bool) return result, mask, None @dispatched_function def unpackbits(a, *args, **kwargs): result = np.unpackbits(a.unmasked, *args, **kwargs) mask = np.zeros(a.shape, dtype='u1') mask[a.mask] = 255 mask = np.unpackbits(mask, *args, **kwargs).astype(bool) return result, mask, None @dispatched_function def bincount(x, weights=None, minlength=0): """Count number of occurrences of each value in array of non-negative ints. Like `numpy.bincount`, but masked entries in ``x`` will be skipped. Any masked entries in ``weights`` will lead the corresponding bin to be masked. """ from astropy.utils.masked import Masked if weights is not None: weights = np.asanyarray(weights) if isinstance(x, Masked) and x.ndim <= 1: # let other dimensions lead to errors. if weights is not None and weights.ndim == x.ndim: weights = weights[~x.mask] x = x.unmasked[~x.mask] mask = None if weights is not None: weights, w_mask = Masked._get_data_and_mask(weights) if w_mask is not None: mask = np.bincount(x, w_mask.astype(int), minlength=minlength).astype(bool) result = np.bincount(x, weights, minlength=0) return result, mask, None @dispatched_function def msort(a): result = a.copy() result.sort(axis=0) return result @dispatched_function def sort_complex(a): # Just a copy of function_base.sort_complex, to avoid the asarray. b = a.copy() b.sort() if not issubclass(b.dtype.type, np.complexfloating): # pragma: no cover if b.dtype.char in 'bhBH': return b.astype('F') elif b.dtype.char == 'g': return b.astype('G') else: return b.astype('D') else: return b @apply_to_both def concatenate(arrays, axis=0, out=None): data, masks = _get_data_and_masks(*arrays) return (data,), (masks,), dict(axis=axis), out @apply_to_both def append(arr, values, axis=None): data, masks = _get_data_and_masks(arr, values) return data, masks, dict(axis=axis), None @dispatched_function def block(arrays): # We need to override block since the numpy implementation can take two # different paths, one for concatenation, one for creating a large empty # result array in which parts are set. Each assumes array input and # cannot be used directly. Since it would be very costly to inspect all # arrays and then turn them back into a nested list, we just copy here the # second implementation, np.core.shape_base._block_slicing, since it is # shortest and easiest. from astropy.utils.masked import Masked (arrays, list_ndim, result_ndim, final_size) = np.core.shape_base._block_setup(arrays) shape, slices, arrays = np.core.shape_base._block_info_recursion( arrays, list_ndim, result_ndim) dtype = np.result_type(*[arr.dtype for arr in arrays]) F_order = all(arr.flags['F_CONTIGUOUS'] for arr in arrays) C_order = all(arr.flags['C_CONTIGUOUS'] for arr in arrays) order = 'F' if F_order and not C_order else 'C' result = Masked(np.empty(shape=shape, dtype=dtype, order=order)) for the_slice, arr in zip(slices, arrays): result[(Ellipsis,) + the_slice] = arr return result @dispatched_function def broadcast_arrays(*args, subok=True): """Broadcast arrays to a common shape. Like `numpy.broadcast_arrays`, applied to both unmasked data and masks. Note that ``subok`` is taken to mean whether or not subclasses of the unmasked data and masks are allowed, i.e., for ``subok=False``, `~astropy.utils.masked.MaskedNDArray` instances will be returned. """ from .core import Masked are_masked = [isinstance(arg, Masked) for arg in args] data = [(arg.unmasked if is_masked else arg) for arg, is_masked in zip(args, are_masked)] results = np.broadcast_arrays(*data, subok=subok) shape = results[0].shape if isinstance(results, list) else results.shape masks = [(np.broadcast_to(arg.mask, shape, subok=subok) if is_masked else None) for arg, is_masked in zip(args, are_masked)] results = [(Masked(result, mask) if mask is not None else result) for (result, mask) in zip(results, masks)] return results if len(results) > 1 else results[0] @apply_to_both def insert(arr, obj, values, axis=None): """Insert values along the given axis before the given indices. Like `numpy.insert` but for possibly masked ``arr`` and ``values``. Masked ``obj`` is not supported. """ from astropy.utils.masked import Masked if isinstance(obj, Masked) or not isinstance(arr, Masked): raise NotImplementedError (arr_data, val_data), (arr_mask, val_mask) = _get_data_and_masks(arr, values) return ((arr_data, obj, val_data, axis), (arr_mask, obj, val_mask, axis), {}, None) if NUMPY_LT_1_19: @dispatched_function def count_nonzero(a, axis=None): """Counts the number of non-zero values in the array ``a``. Like `numpy.count_nonzero`, with masked values counted as 0 or `False`. """ filled = a.filled(np.zeros((), a.dtype)) return np.count_nonzero(filled, axis) else: @dispatched_function def count_nonzero(a, axis=None, *, keepdims=False): """Counts the number of non-zero values in the array ``a``. Like `numpy.count_nonzero`, with masked values counted as 0 or `False`. """ filled = a.filled(np.zeros((), a.dtype)) return np.count_nonzero(filled, axis, keepdims=keepdims) if NUMPY_LT_1_19: def _zeros_like(a, dtype=None, order='K', subok=True, shape=None): if shape != (): return np.zeros_like(a, dtype=dtype, order=order, subok=subok, shape=shape) else: return np.zeros_like(a, dtype=dtype, order=order, subok=subok, shape=(1,))[0] else: _zeros_like = np.zeros_like def _masked_median_1d(a, overwrite_input): # TODO: need an in-place mask-sorting option. unmasked = a.unmasked[~a.mask] if unmasked.size: return a.from_unmasked( np.median(unmasked, overwrite_input=overwrite_input)) else: return a.from_unmasked(_zeros_like(a.unmasked, shape=(1,))[0], mask=True) def _masked_median(a, axis=None, out=None, overwrite_input=False): # As for np.nanmedian, but without a fast option as yet. if axis is None or a.ndim == 1: part = a.ravel() result = _masked_median_1d(part, overwrite_input) else: result = np.apply_along_axis(_masked_median_1d, axis, a, overwrite_input) if out is not None: out[...] = result return result @dispatched_function def median(a, axis=None, out=None, overwrite_input=False, keepdims=False): from astropy.utils.masked import Masked if out is not None and not isinstance(out, Masked): raise NotImplementedError a = Masked(a) r, k = np.lib.function_base._ureduce( a, func=_masked_median, axis=axis, out=out, overwrite_input=overwrite_input) return (r.reshape(k) if keepdims else r) if out is None else out def _masked_quantile_1d(a, q, **kwargs): """ Private function for rank 1 arrays. Compute quantile ignoring NaNs. See nanpercentile for parameter usage """ unmasked = a.unmasked[~a.mask] if unmasked.size: result = np.lib.function_base._quantile_unchecked(unmasked, q, **kwargs) return a.from_unmasked(result) else: return a.from_unmasked(_zeros_like(a.unmasked, shape=q.shape), True) def _masked_quantile(a, q, axis=None, out=None, **kwargs): # As for np.nanmedian, but without a fast option as yet. if axis is None or a.ndim == 1: part = a.ravel() result = _masked_quantile_1d(part, q, **kwargs) else: result = np.apply_along_axis(_masked_quantile_1d, axis, a, q, **kwargs) # apply_along_axis fills in collapsed axis with results. # Move that axis to the beginning to match percentile's # convention. if q.ndim != 0: result = np.moveaxis(result, axis, 0) if out is not None: out[...] = result return result @dispatched_function def quantile(a, q, axis=None, out=None, **kwargs): from astropy.utils.masked import Masked if isinstance(q, Masked) or out is not None and not isinstance(out, Masked): raise NotImplementedError a = Masked(a) q = np.asanyarray(q) if not np.lib.function_base._quantile_is_valid(q): raise ValueError("Quantiles must be in the range [0, 1]") keepdims = kwargs.pop('keepdims', False) r, k = np.lib.function_base._ureduce( a, func=_masked_quantile, q=q, axis=axis, out=out, **kwargs) return (r.reshape(k) if keepdims else r) if out is None else out @dispatched_function def percentile(a, q, *args, **kwargs): q = np.true_divide(q, 100) return quantile(a, q, *args, **kwargs) @dispatched_function def array_equal(a1, a2, equal_nan=False): (a1d, a2d), (a1m, a2m) = _get_data_and_masks(a1, a2) if a1d.shape != a2d.shape: return False equal = (a1d == a2d) if equal_nan: equal |= np.isnan(a1d) & np.isnan(a2d) return bool((equal | a1m | a2m).all()) @dispatched_function def array_equiv(a1, a2): return bool((a1 == a2).all()) @dispatched_function def where(condition, *args): from astropy.utils.masked import Masked if not args: return condition.nonzero(), None, None condition, c_mask = Masked._get_data_and_mask(condition) data, masks = _get_data_and_masks(*args) unmasked = np.where(condition, *data) mask = np.where(condition, *masks) if c_mask is not None: mask |= c_mask return Masked(unmasked, mask=mask) @dispatched_function def choose(a, choices, out=None, mode='raise'): """Construct an array from an index array and a set of arrays to choose from. Like `numpy.choose`. Masked indices in ``a`` will lead to masked output values and underlying data values are ignored if out of bounds (for ``mode='raise'``). Any values masked in ``choices`` will be propagated if chosen. """ from astropy.utils.masked import Masked a_data, a_mask = Masked._get_data_and_mask(a) if a_mask is not None and mode == 'raise': # Avoid raising on masked indices. a_data = a.filled(fill_value=0) kwargs = {'mode': mode} if out is not None: if not isinstance(out, Masked): raise NotImplementedError kwargs['out'] = out.unmasked data, masks = _get_data_and_masks(*choices) data_chosen = np.choose(a_data, data, **kwargs) if out is not None: kwargs['out'] = out.mask mask_chosen = np.choose(a_data, masks, **kwargs) if a_mask is not None: mask_chosen |= a_mask return Masked(data_chosen, mask_chosen) if out is None else out @apply_to_both def select(condlist, choicelist, default=0): """Return an array drawn from elements in choicelist, depending on conditions. Like `numpy.select`, with masks in ``choicelist`` are propagated. Any masks in ``condlist`` are ignored. """ from astropy.utils.masked import Masked condlist = [c.unmasked if isinstance(c, Masked) else c for c in condlist] data_list, mask_list = _get_data_and_masks(*choicelist) default = Masked(default) if default is not np.ma.masked else Masked(0, mask=True) return ((condlist, data_list, default.unmasked), (condlist, mask_list, default.mask), {}, None) @dispatched_function def piecewise(x, condlist, funclist, *args, **kw): """Evaluate a piecewise-defined function. Like `numpy.piecewise` but for masked input array ``x``. Any masks in ``condlist`` are ignored. """ # Copied implementation from numpy.lib.function_base.piecewise, # just to ensure output is Masked. n2 = len(funclist) # undocumented: single condition is promoted to a list of one condition if np.isscalar(condlist) or ( not isinstance(condlist[0], (list, np.ndarray)) and x.ndim != 0): # pragma: no cover condlist = [condlist] condlist = np.array(condlist, dtype=bool) n = len(condlist) if n == n2 - 1: # compute the "otherwise" condition. condelse = ~np.any(condlist, axis=0, keepdims=True) condlist = np.concatenate([condlist, condelse], axis=0) n += 1 elif n != n2: raise ValueError( f"with {n} condition(s), either {n} or {n + 1} functions are expected" ) # The one real change... y = np.zeros_like(x) where = [] what = [] for k in range(n): item = funclist[k] if not callable(item): where.append(condlist[k]) what.append(item) else: vals = x[condlist[k]] if vals.size > 0: where.append(condlist[k]) what.append(item(vals, *args, **kw)) for item, value in zip(where, what): y[item] = value return y @dispatched_function def interp(x, xp, fp, *args, **kwargs): """One-dimensional linear interpolation. Like `numpy.interp`, but any masked points in ``xp`` and ``fp`` are ignored. Any masked values in ``x`` will still be evaluated, but masked on output. """ from astropy.utils.masked import Masked xd, xm = Masked._get_data_and_mask(x) if isinstance(xp, Masked) or isinstance(fp, Masked): (xp, fp), (xpm, fpm) = _get_data_and_masks(xp, fp) if xp.ndim == fp.ndim == 1: # Avoid making arrays 1-D; will just raise below. m = xpm | fpm xp = xp[m] fp = fp[m] result = np.interp(xd, xp, fp, *args, **kwargs) return result if xm is None else Masked(result, xm.copy()) @dispatched_function def lexsort(keys, axis=-1): """Perform an indirect stable sort using a sequence of keys. Like `numpy.lexsort` but for possibly masked ``keys``. Masked values are sorted towards the end for each key. """ # Sort masks to the end. from .core import Masked new_keys = [] for key in keys: if isinstance(key, Masked): # If there are other keys below, want to be sure that # for masked values, those other keys set the order. new_key = key.unmasked if new_keys and key.mask.any(): new_key = new_key.copy() new_key[key.mask] = new_key.flat[0] new_keys.extend([new_key, key.mask]) else: new_keys.append(key) return np.lexsort(new_keys, axis=axis) @dispatched_function def apply_over_axes(func, a, axes): # Copied straight from numpy/lib/shape_base, just to omit its # val = asarray(a); if only it had been asanyarray, or just not there # since a is assumed to an an array in the next line... # Which is what we do here - we can only get here if it is Masked. val = a N = a.ndim if np.array(axes).ndim == 0: axes = (axes,) for axis in axes: if axis < 0: axis = N + axis args = (val, axis) res = func(*args) if res.ndim == val.ndim: val = res else: res = np.expand_dims(res, axis) if res.ndim == val.ndim: val = res else: raise ValueError("function is not returning " "an array of the correct shape") return val class MaskedFormat: """Formatter for masked array scalars. For use in `numpy.array2string`, wrapping the regular formatters such that if a value is masked, its formatted string is replaced. Typically initialized using the ``from_data`` class method. """ def __init__(self, format_function): self.format_function = format_function # Special case for structured void: we need to make all the # format functions for the items masked as well. # TODO: maybe is a separate class is more logical? ffs = getattr(format_function, 'format_functions', None) if ffs: self.format_function.format_functions = [MaskedFormat(ff) for ff in ffs] def __call__(self, x): if x.dtype.names: # The replacement of x with a list is needed because the function # inside StructuredVoidFormat iterates over x, which works for an # np.void but not an array scalar. return self.format_function([x[field] for field in x.dtype.names]) string = self.format_function(x.unmasked[()]) if x.mask: # Strikethrough would be neat, but terminal needs a different # formatting than, say, jupyter notebook. # return "\x1B[9m"+string+"\x1B[29m" # return ''.join(s+'\u0336' for s in string) n = min(3, max(1, len(string))) return ' ' * (len(string)-n) + '\u2014' * n else: return string @classmethod def from_data(cls, data, **options): from numpy.core.arrayprint import _get_format_function return cls(_get_format_function(data, **options)) def _array2string(a, options, separator=' ', prefix=""): # Mostly copied from numpy.core.arrayprint, except: # - The format function is wrapped in a mask-aware class; # - Arrays scalars are not cast as arrays. from numpy.core.arrayprint import _leading_trailing, _formatArray data = np.asarray(a) if a.size > options['threshold']: summary_insert = "..." data = _leading_trailing(data, options['edgeitems']) else: summary_insert = "" # find the right formatting function for the array format_function = MaskedFormat.from_data(data, **options) # skip over "[" next_line_prefix = " " # skip over array( next_line_prefix += " "*len(prefix) lst = _formatArray(a, format_function, options['linewidth'], next_line_prefix, separator, options['edgeitems'], summary_insert, options['legacy']) return lst @dispatched_function def array2string(a, max_line_width=None, precision=None, suppress_small=None, separator=' ', prefix="", style=np._NoValue, formatter=None, threshold=None, edgeitems=None, sign=None, floatmode=None, suffix=""): # Copied from numpy.core.arrayprint, but using _array2string above. from numpy.core.arrayprint import _make_options_dict, _format_options overrides = _make_options_dict(precision, threshold, edgeitems, max_line_width, suppress_small, None, None, sign, formatter, floatmode) options = _format_options.copy() options.update(overrides) options['linewidth'] -= len(suffix) # treat as a null array if any of shape elements == 0 if a.size == 0: return "[]" return _array2string(a, options, separator, prefix) @dispatched_function def array_str(a, max_line_width=None, precision=None, suppress_small=None): # Override to avoid special treatment of array scalars. return array2string(a, max_line_width, precision, suppress_small, ' ', "") # For the nanfunctions, we just treat any nan as an additional mask. _nanfunc_fill_values = {'nansum': 0, 'nancumsum': 0, 'nanprod': 1, 'nancumprod': 1} def masked_nanfunc(nanfuncname): np_func = getattr(np, nanfuncname[3:]) fill_value = _nanfunc_fill_values.get(nanfuncname, None) def nanfunc(a, *args, **kwargs): from astropy.utils.masked import Masked a, mask = Masked._get_data_and_mask(a) if issubclass(a.dtype.type, np.inexact): nans = np.isnan(a) mask = nans if mask is None else (nans | mask) if mask is not None: a = Masked(a, mask) if fill_value is not None: a = a.filled(fill_value) return np_func(a, *args, **kwargs) doc = f"Like `numpy.{nanfuncname}`, skipping masked values as well.\n\n" if fill_value is not None: # sum, cumsum, prod, cumprod doc += (f"Masked/NaN values are replaced with {fill_value}. " "The output is not masked.") elif "arg" in nanfuncname: doc += ("No exceptions are raised for fully masked/NaN slices.\n" "Instead, these give index 0.") else: doc += ("No warnings are given for fully masked/NaN slices.\n" "Instead, they are masked in the output.") nanfunc.__doc__ = doc nanfunc.__name__ = nanfuncname return nanfunc for nanfuncname in np.lib.nanfunctions.__all__: globals()[nanfuncname] = dispatched_function(masked_nanfunc(nanfuncname), helps=getattr(np, nanfuncname)) # Add any dispatched or helper function that has a docstring to # __all__, so they will be typeset by sphinx. The logic is that for # those presumably the use of the mask is not entirely obvious. __all__ += sorted(helper.__name__ for helper in ( set(APPLY_TO_BOTH_FUNCTIONS.values()) | set(DISPATCHED_FUNCTIONS.values())) if helper.__doc__) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1952538 astropy-5.0.2/astropy/utils/masked/tests/0000755000175100001710000000000000000000000017514 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/masked/tests/__init__.py0000644000175100001710000000000000000000000021613 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/masked/tests/test_containers.py0000644000175100001710000001153700000000000023301 0ustar00vstsdocker# coding: utf-8 # Licensed under a 3-clause BSD style license - see LICENSE.rst import numpy as np from numpy.testing import assert_array_equal import pytest from astropy import units as u from astropy.coordinates import SkyCoord, representation as r from astropy.time import Time from astropy.utils.masked import Masked class TestRepresentations: def setup_class(self): self.x = np.array([3., 5., 0.]) << u.m self.y = np.array([4., 12., 1.]) << u.m self.z = np.array([0., 0., 1.]) << u.m self.c = r.CartesianRepresentation(self.x, self.y, self.z) self.mask = np.array([False, False, True]) self.mx = Masked(self.x, self.mask) self.my = Masked(self.y, self.mask) self.mz = Masked(self.z, self.mask) self.mc = r.CartesianRepresentation(self.mx, self.my, self.mz) def test_initialization(self): check = self.mc.z == self.mz assert_array_equal(check.unmasked, np.ones(3, bool)) assert_array_equal(check.mask, self.mask) assert_array_equal(self.mc.x, self.mx) assert_array_equal(self.mc.y, self.my) assert_array_equal(self.mc.z, self.mz) def test_norm(self): # Need stacking and erfa override. norm = self.mc.norm() assert_array_equal(norm.unmasked, self.c.norm()) assert_array_equal(norm.mask, self.mask) def test_transformation(self): msr = self.mc.represent_as(r.SphericalRepresentation) sr = self.c.represent_as(r.SphericalRepresentation) for comp in msr.components: mc = getattr(msr, comp) c = getattr(sr, comp) assert_array_equal(mc.unmasked, c) assert_array_equal(mc.mask, self.mask) # Transformation back. This also tests erfa.ufunc.s2p, which # is special in having a core dimension only in the output. cr2 = sr.represent_as(r.CartesianRepresentation) mcr2 = msr.represent_as(r.CartesianRepresentation) for comp in mcr2.components: mc = getattr(mcr2, comp) c = getattr(cr2, comp) assert_array_equal(mc.unmasked, c) assert_array_equal(mc.mask, self.mask) class TestSkyCoord: def setup_class(self): self.ra = np.array([3., 5., 0.]) << u.hourangle self.dec = np.array([4., 12., 1.]) << u.deg self.sc = SkyCoord(self.ra, self.dec) self.mask = np.array([False, False, True]) self.mra = Masked(self.ra, self.mask) self.mdec = Masked(self.dec, self.mask) self.msc = SkyCoord(self.mra, self.mdec) def test_initialization(self): check = self.msc.dec == self.mdec assert_array_equal(check.unmasked, np.ones(3, bool)) assert_array_equal(check.mask, self.mask) assert_array_equal(self.msc.data.lon, self.mra) assert_array_equal(self.msc.data.lat, self.mdec) def test_transformation(self): gcrs = self.sc.gcrs mgcrs = self.msc.gcrs assert_array_equal(mgcrs.data.lon.mask, self.msc.data.lon.mask) assert_array_equal(mgcrs.data.lon.unmasked, gcrs.data.lon) assert_array_equal(mgcrs.data.lat.unmasked, gcrs.data.lat) class TestTime: def setup_class(self): self.s = np.array(['2010-11-12T13:14:15.160', '2010-11-12T13:14:15.161', '2011-12-13T14:15:16.170']) self.t = Time(self.s) # Time formats will currently strip any ndarray subtypes, so we cannot # initialize a Time with a Masked version of self.s yet. Instead, we # work around it, for now only testing that masked are preserved by # transformations. self.mask = np.array([False, False, True]) self.mt = self.t._apply(Masked, self.mask) def test_initialization(self): assert_array_equal(self.mt.jd1.mask, self.mask) assert_array_equal(self.mt.jd2.mask, self.mask) assert_array_equal(self.mt.jd1.unmasked, self.t.jd1) assert_array_equal(self.mt.jd2.unmasked, self.t.jd2) @pytest.mark.parametrize('format_', ['jd', 'cxcsec', 'jyear']) def test_different_formats(self, format_): # Formats do not yet work with everything; e.g., isot is not supported # since the Masked class does not yet support structured arrays. tfmt = getattr(self.t, format_) mtfmt = getattr(self.mt, format_) check = mtfmt == tfmt assert_array_equal(check.unmasked, np.ones(3, bool)) assert_array_equal(check.mask, self.mask) @pytest.mark.parametrize('scale', ['tai', 'tcb', 'ut1']) def test_transformation(self, scale): tscl = getattr(self.t, scale) mtscl = getattr(self.mt, scale) assert_array_equal(mtscl.jd1.mask, self.mask) assert_array_equal(mtscl.jd2.mask, self.mask) assert_array_equal(mtscl.jd1.unmasked, tscl.jd1) assert_array_equal(mtscl.jd2.unmasked, tscl.jd2) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/masked/tests/test_function_helpers.py0000644000175100001710000014011400000000000024475 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """Test all functions covered by __array_function__. Here, run through all functions, with simple tests just to check the helpers. More complicated tests of functionality, including with subclasses, are done in test_functions. TODO: finish full coverage (see also `~astropy.utils.masked.function_helpers`) - np.linalg - np.fft (is there any point?) - np.lib.nanfunctions """ import inspect import itertools import pytest import numpy as np from numpy.testing import assert_array_equal from astropy.utils.compat import NUMPY_LT_1_19, NUMPY_LT_1_20, NUMPY_LT_1_23 from astropy.units.tests.test_quantity_non_ufuncs import ( get_wrapped_functions) from astropy.utils.masked import Masked, MaskedNDArray from astropy.utils.masked.function_helpers import ( MASKED_SAFE_FUNCTIONS, APPLY_TO_BOTH_FUNCTIONS, DISPATCHED_FUNCTIONS, IGNORED_FUNCTIONS, UNSUPPORTED_FUNCTIONS) from .test_masked import assert_masked_equal, MaskedArraySetup all_wrapped_functions = get_wrapped_functions(np) all_wrapped = set(all_wrapped_functions.values()) class BasicTestSetup(MaskedArraySetup): def check(self, func, *args, **kwargs): out = func(self.ma, *args, **kwargs) expected = Masked(func(self.a, *args, **kwargs), mask=func(self.mask_a, *args, **kwargs)) assert_masked_equal(out, expected) def check2(self, func, *args, **kwargs): out = func(self.ma, self.mb, *args, **kwargs) expected = Masked(func(self.a, self.b, *args, **kwargs), mask=func(self.mask_a, self.mask_b, *args, **kwargs)) if isinstance(out, (tuple, list)): for o, x in zip(out, expected): assert_masked_equal(o, x) else: assert_masked_equal(out, expected) class NoMaskTestSetup(MaskedArraySetup): def check(self, func, *args, **kwargs): o = func(self.ma, *args, **kwargs) expected = func(self.a, *args, **kwargs) assert_array_equal(o, expected) class InvariantMaskTestSetup(MaskedArraySetup): def check(self, func, *args, **kwargs): o = func(self.ma, *args, **kwargs) expected = func(self.a, *args, **kwargs) assert_array_equal(o.unmasked, expected) assert_array_equal(o.mask, self.mask_a) class TestShapeInformation(BasicTestSetup): def test_shape(self): assert np.shape(self.ma) == (2, 3) def test_size(self): assert np.size(self.ma) == 6 def test_ndim(self): assert np.ndim(self.ma) == 2 class TestShapeManipulation(BasicTestSetup): # Note: do not parametrize the below, since test names are used # to check coverage. def test_reshape(self): self.check(np.reshape, (6, 1)) def test_ravel(self): self.check(np.ravel) def test_moveaxis(self): self.check(np.moveaxis, 0, 1) def test_rollaxis(self): self.check(np.rollaxis, 0, 2) def test_swapaxes(self): self.check(np.swapaxes, 0, 1) def test_transpose(self): self.check(np.transpose) def test_atleast_1d(self): self.check(np.atleast_1d) o, so = np.atleast_1d(self.mb[0], self.mc[0]) assert o.shape == o.mask.shape == so.shape == so.mask.shape == (1,) def test_atleast_2d(self): self.check(np.atleast_2d) o, so = np.atleast_2d(self.mb[0], self.mc[0]) assert o.shape == o.mask.shape == so.shape == so.mask.shape == (1, 1) def test_atleast_3d(self): self.check(np.atleast_3d) o, so = np.atleast_3d(self.mb[0], self.mc[0]) assert o.shape == o.mask.shape == so.shape == so.mask.shape == (1, 1, 1) def test_expand_dims(self): self.check(np.expand_dims, 1) def test_squeeze(self): o = np.squeeze(self.mc) assert o.shape == o.mask.shape == (2,) assert_array_equal(o.unmasked, self.c.squeeze()) assert_array_equal(o.mask, self.mask_c.squeeze()) def test_flip(self): self.check(np.flip) def test_fliplr(self): self.check(np.fliplr) def test_flipud(self): self.check(np.flipud) def test_rot90(self): self.check(np.rot90) def test_broadcast_to(self): self.check(np.broadcast_to, (3, 2, 3)) self.check(np.broadcast_to, (3, 2, 3), subok=False) def test_broadcast_arrays(self): self.check2(np.broadcast_arrays) self.check2(np.broadcast_arrays, subok=False) class TestArgFunctions(MaskedArraySetup): def check(self, function, *args, fill_value=np.nan, **kwargs): o = function(self.ma, *args, **kwargs) a_filled = self.ma.filled(fill_value=fill_value) expected = function(a_filled, *args, **kwargs) assert_array_equal(o, expected) def test_argmin(self): self.check(np.argmin, fill_value=np.inf) def test_argmax(self): self.check(np.argmax, fill_value=-np.inf) def test_argsort(self): self.check(np.argsort, fill_value=np.nan) def test_lexsort(self): self.check(np.lexsort, fill_value=np.nan) def test_nonzero(self): self.check(np.nonzero, fill_value=0.) @pytest.mark.filterwarnings('ignore:Calling nonzero on 0d arrays is deprecated') def test_nonzero_0d(self): res1 = Masked(1, mask=False).nonzero() assert len(res1) == 1 assert_array_equal(res1[0], np.ones(()).nonzero()[0]) res2 = Masked(1, mask=True).nonzero() assert len(res2) == 1 assert_array_equal(res2[0], np.zeros(()).nonzero()[0]) def test_argwhere(self): self.check(np.argwhere, fill_value=0.) def test_argpartition(self): self.check(np.argpartition, 2, fill_value=np.inf) def test_flatnonzero(self): self.check(np.flatnonzero, fill_value=0.) class TestAlongAxis(MaskedArraySetup): def test_take_along_axis(self): indices = np.expand_dims(np.argmax(self.ma, axis=0), axis=0) out = np.take_along_axis(self.ma, indices, axis=0) expected = np.take_along_axis(self.a, indices, axis=0) expected_mask = np.take_along_axis(self.mask_a, indices, axis=0) assert_array_equal(out.unmasked, expected) assert_array_equal(out.mask, expected_mask) def test_put_along_axis(self): ma = self.ma.copy() indices = np.expand_dims(np.argmax(self.ma, axis=0), axis=0) np.put_along_axis(ma, indices, axis=0, values=-1) expected = self.a.copy() np.put_along_axis(expected, indices, axis=0, values=-1) assert_array_equal(ma.unmasked, expected) assert_array_equal(ma.mask, self.mask_a) np.put_along_axis(ma, indices, axis=0, values=np.ma.masked) assert_array_equal(ma.unmasked, expected) expected_mask = self.mask_a.copy() np.put_along_axis(expected_mask, indices, axis=0, values=True) assert_array_equal(ma.mask, expected_mask) @pytest.mark.parametrize('axis', (0, 1)) def test_apply_along_axis(self, axis): out = np.apply_along_axis(np.square, axis, self.ma) expected = np.apply_along_axis(np.square, axis, self.a) assert_array_equal(out.unmasked, expected) assert_array_equal(out.mask, self.mask_a) @pytest.mark.parametrize('axes', [(1,), 0, (0, -1)]) def test_apply_over_axes(self, axes): def function(x, axis): return np.mean(np.square(x), axis) out = np.apply_over_axes(function, self.ma, axes) expected = self.ma for axis in (axes if isinstance(axes, tuple) else (axes,)): expected = (expected**2).mean(axis, keepdims=True) assert_array_equal(out.unmasked, expected.unmasked) assert_array_equal(out.mask, expected.mask) def test_apply_over_axes_no_reduction(self): out = np.apply_over_axes(np.cumsum, self.ma, 0) expected = self.ma.cumsum(axis=0) assert_masked_equal(out, expected) def test_apply_over_axes_wrong_size(self): with pytest.raises(ValueError, match='not.*correct shape'): np.apply_over_axes(lambda x, axis: x[..., np.newaxis], self.ma, 0) class TestIndicesFrom(NoMaskTestSetup): @classmethod def setup_class(self): self.a = np.arange(9).reshape(3, 3) self.mask_a = np.eye(3, dtype=bool) self.ma = Masked(self.a, self.mask_a) def test_diag_indices_from(self): self.check(np.diag_indices_from) def test_triu_indices_from(self): self.check(np.triu_indices_from) def test_tril_indices_from(self): self.check(np.tril_indices_from) class TestRealImag(InvariantMaskTestSetup): @classmethod def setup_class(self): self.a = np.array([1+2j, 3+4j]) self.mask_a = np.array([True, False]) self.ma = Masked(self.a, mask=self.mask_a) def test_real(self): self.check(np.real) def test_imag(self): self.check(np.imag) class TestCopyAndCreation(InvariantMaskTestSetup): def test_copy(self): self.check(np.copy) # Also as kwarg copy = np.copy(a=self.ma) assert_array_equal(copy, self.ma) def test_asfarray(self): self.check(np.asfarray) farray = np.asfarray(a=self.ma) assert_array_equal(farray, self.ma) class TestArrayCreation(MaskedArraySetup): def test_empty_like(self): o = np.empty_like(self.ma) assert o.shape == (2, 3) assert isinstance(o, Masked) assert isinstance(o, np.ndarray) o2 = np.empty_like(prototype=self.ma) assert o2.shape == (2, 3) assert isinstance(o2, Masked) assert isinstance(o2, np.ndarray) o3 = np.empty_like(self.ma, subok=False) assert type(o3) is MaskedNDArray def test_zeros_like(self): o = np.zeros_like(self.ma) assert_array_equal(o.unmasked, np.zeros_like(self.a)) assert_array_equal(o.mask, np.zeros_like(self.mask_a)) o2 = np.zeros_like(a=self.ma) assert_array_equal(o2.unmasked, np.zeros_like(self.a)) assert_array_equal(o2.mask, np.zeros_like(self.mask_a)) def test_ones_like(self): o = np.ones_like(self.ma) assert_array_equal(o.unmasked, np.ones_like(self.a)) assert_array_equal(o.mask, np.zeros_like(self.mask_a)) o2 = np.ones_like(a=self.ma) assert_array_equal(o2.unmasked, np.ones_like(self.a)) assert_array_equal(o2.mask, np.zeros_like(self.mask_a)) @pytest.mark.parametrize('value', [0.5, Masked(0.5, mask=True), np.ma.masked]) def test_full_like(self, value): o = np.full_like(self.ma, value) if value is np.ma.masked: expected = Masked(o.unmasked, True) else: expected = Masked(np.empty_like(self.a)) expected[...] = value assert_array_equal(o.unmasked, expected.unmasked) assert_array_equal(o.mask, expected.mask) class TestAccessingParts(BasicTestSetup): def test_diag(self): self.check(np.diag) def test_diag_1d_input(self): ma = self.ma.ravel() o = np.diag(ma) assert_array_equal(o.unmasked, np.diag(self.a.ravel())) assert_array_equal(o.mask, np.diag(self.mask_a.ravel())) def test_diagonal(self): self.check(np.diagonal) def test_diagflat(self): self.check(np.diagflat) def test_compress(self): o = np.compress([True, False], self.ma, axis=0) expected = np.compress([True, False], self.a, axis=0) expected_mask = np.compress([True, False], self.mask_a, axis=0) assert_array_equal(o.unmasked, expected) assert_array_equal(o.mask, expected_mask) def test_extract(self): o = np.extract([True, False, True], self.ma) expected = np.extract([True, False, True], self.a) expected_mask = np.extract([True, False, True], self.mask_a) assert_array_equal(o.unmasked, expected) assert_array_equal(o.mask, expected_mask) def test_delete(self): self.check(np.delete, slice(1, 2), 0) self.check(np.delete, [0, 2], 1) def test_roll(self): self.check(np.roll, 1) self.check(np.roll, 1, axis=0) def test_take(self): self.check(np.take, [0, 1], axis=1) self.check(np.take, 1) class TestSettingParts(MaskedArraySetup): def test_put(self): ma = self.ma.copy() v = Masked([50, 150], [False, True]) np.put(ma, [0, 2], v) expected = self.a.copy() np.put(expected, [0, 2], [50, 150]) expected_mask = self.mask_a.copy() np.put(expected_mask, [0, 2], [False, True]) assert_array_equal(ma.unmasked, expected) assert_array_equal(ma.mask, expected_mask) with pytest.raises(TypeError): # Indices cannot be masked. np.put(ma, Masked([0, 2]), v) with pytest.raises(TypeError): # Array to put masked values in must be masked. np.put(self.a.copy(), [0, 2], v) def test_putmask(self): ma = self.ma.flatten() mask = [True, False, False, False, True, False] values = Masked(np.arange(100, 650, 100), mask=[False, True, True, True, False, False]) np.putmask(ma, mask, values) expected = self.a.flatten() np.putmask(expected, mask, values.unmasked) expected_mask = self.mask_a.flatten() np.putmask(expected_mask, mask, values.mask) assert_array_equal(ma.unmasked, expected) assert_array_equal(ma.mask, expected_mask) with pytest.raises(TypeError): np.putmask(self.a.flatten(), mask, values) def test_place(self): ma = self.ma.flatten() mask = [True, False, False, False, True, False] values = Masked([100, 200], mask=[False, True]) np.place(ma, mask, values) expected = self.a.flatten() np.place(expected, mask, values.unmasked) expected_mask = self.mask_a.flatten() np.place(expected_mask, mask, values.mask) assert_array_equal(ma.unmasked, expected) assert_array_equal(ma.mask, expected_mask) with pytest.raises(TypeError): np.place(self.a.flatten(), mask, values) def test_copyto(self): ma = self.ma.flatten() mask = [True, False, False, False, True, False] values = Masked(np.arange(100, 650, 100), mask=[False, True, True, True, False, False]) np.copyto(ma, values, where=mask) expected = self.a.flatten() np.copyto(expected, values.unmasked, where=mask) expected_mask = self.mask_a.flatten() np.copyto(expected_mask, values.mask, where=mask) assert_array_equal(ma.unmasked, expected) assert_array_equal(ma.mask, expected_mask) with pytest.raises(TypeError): np.copyto(self.a.flatten(), values, where=mask) @pytest.mark.parametrize('value', [0.25, np.ma.masked]) def test_fill_diagonal(self, value): ma = self.ma[:2, :2].copy() np.fill_diagonal(ma, value) expected = ma.copy() expected[np.diag_indices_from(expected)] = value assert_array_equal(ma.unmasked, expected.unmasked) assert_array_equal(ma.mask, expected.mask) class TestRepeat(BasicTestSetup): def test_tile(self): self.check(np.tile, 2) def test_repeat(self): self.check(np.repeat, 2) def test_resize(self): self.check(np.resize, (4, 4)) class TestConcatenate(MaskedArraySetup): # More tests at TestMaskedArrayConcatenation in test_functions. def check(self, func, *args, **kwargs): ma_list = kwargs.pop('ma_list', [self.ma, self.ma]) a_list = [Masked(ma).unmasked for ma in ma_list] m_list = [Masked(ma).mask for ma in ma_list] o = func(ma_list, *args, **kwargs) expected = func(a_list, *args, **kwargs) expected_mask = func(m_list, *args, **kwargs) assert_array_equal(o.unmasked, expected) assert_array_equal(o.mask, expected_mask) def test_concatenate(self): self.check(np.concatenate) self.check(np.concatenate, axis=1) self.check(np.concatenate, ma_list=[self.a, self.ma]) out = Masked(np.empty((4, 3))) result = np.concatenate([self.ma, self.ma], out=out) assert out is result expected = np.concatenate([self.a, self.a]) expected_mask = np.concatenate([self.mask_a, self.mask_a]) assert_array_equal(out.unmasked, expected) assert_array_equal(out.mask, expected_mask) with pytest.raises(TypeError): np.concatenate([self.ma, self.ma], out=np.empty((4, 3))) def test_stack(self): self.check(np.stack) def test_column_stack(self): self.check(np.column_stack) def test_hstack(self): self.check(np.hstack) def test_vstack(self): self.check(np.vstack) def test_dstack(self): self.check(np.dstack) def test_block(self): self.check(np.block) out = np.block([[0., Masked(1., True)], [Masked(1, False), Masked(2, False)]]) expected = np.array([[0, 1.], [1, 2]]) expected_mask = np.array([[False, True], [False, False]]) assert_array_equal(out.unmasked, expected) assert_array_equal(out.mask, expected_mask) def test_append(self): out = np.append(self.ma, self.mc, axis=1) expected = np.append(self.a, self.c, axis=1) expected_mask = np.append(self.mask_a, self.mask_c, axis=1) assert_array_equal(out.unmasked, expected) assert_array_equal(out.mask, expected_mask) def test_insert(self): obj = (1, 1) values = Masked([50., 25.], mask=[True, False]) out = np.insert(self.ma.flatten(), obj, values) expected = np.insert(self.a.flatten(), obj, [50., 25.]) expected_mask = np.insert(self.mask_a.flatten(), obj, [True, False]) assert_array_equal(out.unmasked, expected) assert_array_equal(out.mask, expected_mask) with pytest.raises(TypeError): np.insert(self.a.flatten(), obj, values) with pytest.raises(TypeError): np.insert(self.ma.flatten(), Masked(obj), values) class TestSplit: @classmethod def setup_class(self): self.a = np.arange(54.).reshape(3, 3, 6) self.mask_a = np.zeros(self.a.shape, dtype=bool) self.mask_a[1, 1, 1] = True self.mask_a[0, 1, 4] = True self.mask_a[1, 2, 5] = True self.ma = Masked(self.a, mask=self.mask_a) def check(self, func, *args, **kwargs): out = func(self.ma, *args, **kwargs) expected = func(self.a, *args, **kwargs) expected_mask = func(self.mask_a, *args, **kwargs) assert len(out) == len(expected) for o, x, xm in zip(out, expected, expected_mask): assert_array_equal(o.unmasked, x) assert_array_equal(o.mask, xm) def test_split(self): self.check(np.split, [1]) def test_array_split(self): self.check(np.array_split, 2) def test_hsplit(self): self.check(np.hsplit, [1, 4]) def test_vsplit(self): self.check(np.vsplit, [1]) def test_dsplit(self): self.check(np.dsplit, [1]) class TestMethodLikes(MaskedArraySetup): def check(self, function, *args, method=None, **kwargs): if method is None: method = function.__name__ o = function(self.ma, *args, **kwargs) x = getattr(self.ma, method)(*args, **kwargs) assert_masked_equal(o, x) def test_amax(self): self.check(np.amax, method='max') def test_amin(self): self.check(np.amin, method='min') def test_sum(self): self.check(np.sum) def test_cumsum(self): self.check(np.cumsum) def test_any(self): self.check(np.any) def test_all(self): self.check(np.all) def test_sometrue(self): self.check(np.sometrue, method='any') def test_alltrue(self): self.check(np.alltrue, method='all') def test_prod(self): self.check(np.prod) def test_product(self): self.check(np.product, method='prod') def test_cumprod(self): self.check(np.cumprod) def test_cumproduct(self): self.check(np.cumproduct, method='cumprod') def test_ptp(self): self.check(np.ptp) self.check(np.ptp, axis=0) def test_round_(self): self.check(np.round_, method='round') def test_around(self): self.check(np.around, method='round') def test_clip(self): self.check(np.clip, 2., 4.) self.check(np.clip, self.mb, self.mc) def test_mean(self): self.check(np.mean) def test_std(self): self.check(np.std) def test_var(self): self.check(np.var) class TestUfuncLike(InvariantMaskTestSetup): def test_fix(self): self.check(np.fix) def test_angle(self): a = np.array([1+0j, 0+1j, 1+1j, 0+0j]) mask_a = np.array([True, False, True, False]) ma = Masked(a, mask=mask_a) out = np.angle(ma) expected = np.angle(ma.unmasked) assert_array_equal(out.unmasked, expected) assert_array_equal(out.mask, mask_a) def test_i0(self): self.check(np.i0) def test_sinc(self): self.check(np.sinc) def test_where(self): mask = [True, False, True] out = np.where(mask, self.ma, 1000.) expected = np.where(mask, self.a, 1000.) expected_mask = np.where(mask, self.mask_a, False) assert_array_equal(out.unmasked, expected) assert_array_equal(out.mask, expected_mask) mask2 = Masked(mask, [True, False, False]) out2 = np.where(mask2, self.ma, 1000.) expected2 = np.where(mask, self.a, 1000.) expected_mask2 = np.where(mask, self.mask_a, False) | mask2.mask assert_array_equal(out2.unmasked, expected2) assert_array_equal(out2.mask, expected_mask2) def test_where_single_arg(self): m = Masked(np.arange(3), mask=[True, False, False]) out = np.where(m) expected = m.nonzero() assert isinstance(out, tuple) and len(out) == 1 assert_array_equal(out[0], expected[0]) def test_where_wrong_number_of_arg(self): with pytest.raises(ValueError, match='either both or neither'): np.where([True, False, False], self.a) def test_choose(self): a = np.array([0, 1]).reshape((2, 1)) result = np.choose(a, (self.ma, self.mb)) expected = np.choose(a, (self.a, self.b)) expected_mask = np.choose(a, (self.mask_a, self.mask_b)) assert_array_equal(result.unmasked, expected) assert_array_equal(result.mask, expected_mask) out = np.zeros_like(result) result2 = np.choose(a, (self.ma, self.mb), out=out) assert result2 is out assert_array_equal(result2, result) with pytest.raises(TypeError): np.choose(a, (self.ma, self.mb), out=np.zeros_like(expected)) def test_choose_masked(self): ma = Masked(np.array([-1, 1]), mask=[True, False]).reshape((2, 1)) out = ma.choose((self.ma, self.mb)) expected = np.choose(ma.filled(0), (self.a, self.b)) expected_mask = np.choose(ma.filled(0), (self.mask_a, self.mask_b)) | ma.mask assert_array_equal(out.unmasked, expected) assert_array_equal(out.mask, expected_mask) with pytest.raises(ValueError): ma.unmasked.choose((self.ma, self.mb)) @pytest.mark.parametrize('default', [-1., np.ma.masked, Masked(-1, mask=True)]) def test_select(self, default): a, mask_a, ma = self.a, self.mask_a, self.ma out = np.select([a < 1.5, a > 3.5], [ma, ma+1], default=default) expected = np.select([a < 1.5, a > 3.5], [a, a+1], default=-1 if default is not np.ma.masked else 0) expected_mask = np.select([a < 1.5, a > 3.5], [mask_a, mask_a], default=getattr(default, 'mask', False)) assert_array_equal(out.unmasked, expected) assert_array_equal(out.mask, expected_mask) def test_real_if_close(self): a = np.array([1+0j, 0+1j, 1+1j, 0+0j]) mask_a = np.array([True, False, True, False]) ma = Masked(a, mask=mask_a) out = np.real_if_close(ma) expected = np.real_if_close(a) assert_array_equal(out.unmasked, expected) assert_array_equal(out.mask, mask_a) def test_tril(self): self.check(np.tril) def test_triu(self): self.check(np.triu) def test_unwrap(self): self.check(np.unwrap) def test_nan_to_num(self): self.check(np.nan_to_num) ma = Masked([np.nan, 1.], mask=[True, False]) o = np.nan_to_num(ma, copy=False) assert_masked_equal(o, Masked([0., 1.], mask=[True, False])) assert ma is o class TestUfuncLikeTests: @classmethod def setup_class(self): self.a = np.array([[-np.inf, +np.inf, np.nan, 3., 4.]]*2) self.mask_a = np.array([[False]*5, [True]*4+[False]]) self.ma = Masked(self.a, mask=self.mask_a) self.b = np.array([[3.0001], [3.9999]]) self.mask_b = np.array([[True], [False]]) self.mb = Masked(self.b, mask=self.mask_b) def check(self, func): out = func(self.ma) expected = func(self.a) assert type(out) is MaskedNDArray assert out.dtype.kind == 'b' assert_array_equal(out.unmasked, expected) assert_array_equal(out.mask, self.mask_a) assert not np.may_share_memory(out.mask, self.mask_a) def test_isposinf(self): self.check(np.isposinf) def test_isneginf(self): self.check(np.isneginf) def test_isreal(self): self.check(np.isreal) o = np.isreal(Masked([1. + 1j], mask=False)) assert not o.unmasked and not o.mask o = np.isreal(Masked([1. + 1j], mask=True)) assert not o.unmasked and o.mask def test_iscomplex(self): self.check(np.iscomplex) o = np.iscomplex(Masked([1. + 1j], mask=False)) assert o.unmasked and not o.mask o = np.iscomplex(Masked([1. + 1j], mask=True)) assert o.unmasked and o.mask def test_isclose(self): out = np.isclose(self.ma, self.mb, atol=0.01) expected = np.isclose(self.ma, self.mb, atol=0.01) expected_mask = self.mask_a | self.mask_b assert_array_equal(out.unmasked, expected) assert_array_equal(out.mask, expected_mask) def test_allclose(self): out = np.allclose(self.ma, self.mb, atol=0.01) expected = np.isclose(self.ma, self.mb, atol=0.01)[self.mask_a | self.mask_b].all() assert_array_equal(out, expected) def test_array_equal(self): assert not np.array_equal(self.ma, self.ma) assert not np.array_equal(self.ma, self.a) if not NUMPY_LT_1_19: assert np.array_equal(self.ma, self.ma, equal_nan=True) assert np.array_equal(self.ma, self.a, equal_nan=True) assert not np.array_equal(self.ma, self.mb) ma2 = self.ma.copy() ma2.mask |= np.isnan(self.a) assert np.array_equal(ma2, self.ma) def test_array_equiv(self): assert np.array_equiv(self.mb, self.mb) assert np.array_equiv(self.mb, self.b) assert not np.array_equiv(self.ma, self.mb) assert np.array_equiv(self.mb, np.stack([self.mb, self.mb])) class TestOuterLikeFunctions(MaskedArraySetup): def test_outer(self): result = np.outer(self.ma, self.mb) expected_data = np.outer(self.a.ravel(), self.b.ravel()) expected_mask = np.logical_or.outer(self.mask_a.ravel(), self.mask_b.ravel()) assert_array_equal(result.unmasked, expected_data) assert_array_equal(result.mask, expected_mask) out = np.zeros_like(result) result2 = np.outer(self.ma, self.mb, out=out) assert result2 is out assert result2 is not result assert_masked_equal(result2, result) out2 = np.zeros_like(result.unmasked) with pytest.raises(TypeError): np.outer(self.ma, self.mb, out=out2) def test_kron(self): result = np.kron(self.ma, self.mb) expected_data = np.kron(self.a, self.b) expected_mask = np.logical_or.outer(self.mask_a, self.mask_b).reshape(result.shape) assert_array_equal(result.unmasked, expected_data) assert_array_equal(result.mask, expected_mask) class TestReductionLikeFunctions(MaskedArraySetup): def test_average(self): o = np.average(self.ma) assert_masked_equal(o, self.ma.mean()) o = np.average(self.ma, weights=self.mb, axis=-1) expected = np.average(self.a, weights=self.b, axis=-1) expected_mask = (self.mask_a | self.mask_b).any(-1) assert_array_equal(o.unmasked, expected) assert_array_equal(o.mask, expected_mask) def test_trace(self): o = np.trace(self.ma) expected = np.trace(self.a) expected_mask = np.trace(self.mask_a).astype(bool) assert_array_equal(o.unmasked, expected) assert_array_equal(o.mask, expected_mask) @pytest.mark.parametrize('axis', [0, 1, None]) def test_count_nonzero(self, axis): o = np.count_nonzero(self.ma, axis=axis) expected = np.count_nonzero(self.ma.filled(0), axis=axis) assert_array_equal(o, expected) @pytest.mark.filterwarnings('ignore:all-nan') class TestPartitionLikeFunctions: @classmethod def setup_class(self): self.a = np.arange(36.).reshape(6, 6) self.mask_a = np.zeros_like(self.a, bool) # On purpose fill diagonal, so we get all masked elements. self.mask_a[np.tril_indices_from(self.a)] = True self.ma = Masked(self.a, mask=self.mask_a) def check(self, function, *args, **kwargs): o = function(self.ma, *args, **kwargs) nanfunc = getattr(np, 'nan'+function.__name__) nanfilled = self.ma.filled(np.nan) expected = nanfunc(nanfilled, *args, **kwargs) assert_array_equal(o.filled(np.nan), expected) assert_array_equal(o.mask, np.isnan(expected)) if not kwargs.get('axis', 1): # no need to test for all return out = np.zeros_like(o) o2 = function(self.ma, *args, out=out, **kwargs) assert o2 is out assert_masked_equal(o2, o) with pytest.raises(TypeError): function(self.ma, *args, out=np.zeros_like(expected), **kwargs) @pytest.mark.parametrize('axis', [None, 0, 1]) def test_median(self, axis): self.check(np.median, axis=axis) @pytest.mark.parametrize('axis', [None, 0, 1]) def test_quantile(self, axis): self.check(np.quantile, q=[0.25, 0.5], axis=axis) def test_quantile_out_of_range(self): with pytest.raises(ValueError, match='must be in the range'): np.quantile(self.ma, q=1.5) @pytest.mark.parametrize('axis', [None, 0, 1]) def test_percentile(self, axis): self.check(np.percentile, q=50, axis=axis) class TestIntDiffFunctions(MaskedArraySetup): def test_diff(self): out = np.diff(self.ma) expected = np.diff(self.a) expected_mask = self.mask_a[:, 1:] | self.mask_a[:, :-1] assert_array_equal(out.unmasked, expected) assert_array_equal(out.mask, expected_mask) def test_diff_prepend_append(self): out = np.diff(self.ma, prepend=Masked(-1, mask=True), append=1) expected = np.diff(self.a, prepend=-1, append=1.) mask = np.concatenate([np.ones((2, 1), bool), self.mask_a, np.zeros((2, 1), bool)], axis=-1) expected_mask = mask[:, 1:] | mask[:, :-1] assert_array_equal(out.unmasked, expected) assert_array_equal(out.mask, expected_mask) def test_trapz(self): ma = self.ma.copy() ma.mask[1] = False out = np.trapz(ma) assert_array_equal(out.unmasked, np.trapz(self.a)) assert_array_equal(out.mask, np.array([True, False])) def test_gradient(self): out = np.gradient(self.ma) expected = np.gradient(self.a) expected_mask = [(self.mask_a[1:] | self.mask_a[:-1]).repeat(2, axis=0), np.stack([ self.mask_a[:, 0] | self.mask_a[:, 1], self.mask_a[:, 0] | self.mask_a[:, 2], self.mask_a[:, 1] | self.mask_a[:, 2]], axis=-1)] for o, x, m in zip(out, expected, expected_mask): assert_array_equal(o.unmasked, x) assert_array_equal(o.mask, m) class TestSpaceFunctions: @classmethod def setup_class(self): self.a = np.arange(1., 7.).reshape(2, 3) self.mask_a = np.array([[True, False, False], [False, True, False]]) self.ma = Masked(self.a, mask=self.mask_a) self.b = np.array([2.5, 10., 3.]) self.mask_b = np.array([False, True, False]) self.mb = Masked(self.b, mask=self.mask_b) def check(self, function, *args, **kwargs): out = function(self.ma, self.mb, 5) expected = function(self.a, self.b, 5) expected_mask = np.broadcast_to(self.mask_a | self.mask_b, expected.shape).copy() # TODO: make implementation that also ensures start point mask is # determined just by start point? (as for geomspace in numpy 1.20)? expected_mask[-1] = self.mask_b if not NUMPY_LT_1_20 and function is np.geomspace: expected_mask[0] = self.mask_a assert_array_equal(out.unmasked, expected) assert_array_equal(out.mask, expected_mask) def test_linspace(self): self.check(np.linspace, 5) def test_logspace(self): self.check(np.logspace, 10) def test_geomspace(self): self.check(np.geomspace, 5) class TestInterpolationFunctions(MaskedArraySetup): def test_interp(self): xp = np.arange(5.) fp = np.array([1., 5., 6., 19., 20.]) mask_fp = np.array([False, False, False, True, False]) mfp = Masked(fp, mask=mask_fp) x = np.array([1.5, 17.]) mask_x = np.array([False, True]) mx = Masked(x, mask=mask_x) out = np.interp(mx, xp, mfp) expected = np.interp(x, xp[mask_fp], fp[mask_fp]) assert_array_equal(out.unmasked, expected) assert_array_equal(out.mask, mask_x) def test_piecewise(self): condlist = [self.a < 1, self.a >= 1] out = np.piecewise(self.ma, condlist, [Masked(-1, mask=True), 1.]) expected = np.piecewise(self.a, condlist, [-1, 1.]) expected_mask = np.piecewise(self.mask_a, condlist, [True, False]) assert_array_equal(out.unmasked, expected) assert_array_equal(out.mask, expected_mask) condlist2 = [self.a < 1, self.a >= 3] out2 = np.piecewise(self.ma, condlist2, [Masked(-1, True), 1, lambda x: Masked(np.full_like(x, 2.), mask=~x.mask)]) expected = np.piecewise(self.a, condlist2, [-1, 1, 2]) expected_mask = np.piecewise(self.mask_a, condlist2, [True, False, lambda x: ~x]) assert_array_equal(out2.unmasked, expected) assert_array_equal(out2.mask, expected_mask) with pytest.raises(ValueError, match='with 2 condition'): np.piecewise(self.ma, condlist2, []) class TestBincount(MaskedArraySetup): def test_bincount(self): i = np.array([1, 1, 2, 3, 2, 4]) mask_i = np.array([True, False, False, True, False, False]) mi = Masked(i, mask=mask_i) out = np.bincount(mi) expected = np.bincount(i[~mask_i]) assert_array_equal(out, expected) w = np.arange(len(i)) mask_w = np.array([True]+[False]*5) mw = Masked(w, mask=mask_w) out2 = np.bincount(i, mw) expected = np.bincount(i, w) expected_mask = np.array([False, True, False, False, False]) assert_array_equal(out2.unmasked, expected) assert_array_equal(out2.mask, expected_mask) out3 = np.bincount(mi, mw) expected = np.bincount(i[~mask_i], w[~mask_i]) expected_mask = np.array([False, False, False, False, False]) assert_array_equal(out3.unmasked, expected) assert_array_equal(out3.mask, expected_mask) class TestSortFunctions(MaskedArraySetup): def test_sort(self): o = np.sort(self.ma) expected = self.ma.copy() expected.sort() assert_masked_equal(o, expected) def test_sort_complex(self): ma = Masked(np.array([1+2j, 0+4j, 3+0j, -1-1j]), mask=[True, False, False, False]) o = np.sort_complex(ma) indx = np.lexsort((ma.unmasked.imag, ma.unmasked.real, ma.mask)) expected = ma[indx] assert_masked_equal(o, expected) def test_msort(self): o = np.msort(self.ma) expected = np.sort(self.ma, axis=0) assert_masked_equal(o, expected) def test_partition(self): o = np.partition(self.ma, 1) expected = self.ma.copy() expected.partition(1) assert_masked_equal(o, expected) class TestStringFunctions: # More elaborate tests done in test_masked.py @classmethod def setup_class(self): self.ma = Masked(np.arange(3), mask=[True, False, False]) def test_array2string(self): out0 = np.array2string(self.ma) assert out0 == '[— 1 2]' # Arguments are interpreted as usual. out1 = np.array2string(self.ma, separator=', ') assert out1 == '[—, 1, 2]' # If we do pass in a formatter, though, it should be used. out2 = np.array2string(self.ma, separator=', ', formatter={'all': hex}) assert out2 == '[———, 0x1, 0x2]' # Also as positional argument (no, nobody will do this!) out3 = np.array2string(self.ma, None, None, None, ', ', '', np._NoValue, {'int': hex}) assert out3 == out2 # But not if the formatter is not relevant for us. out4 = np.array2string(self.ma, separator=', ', formatter={'float': hex}) assert out4 == out1 def test_array_repr(self): out = np.array_repr(self.ma) assert out == 'MaskedNDArray([—, 1, 2])' ma2 = self.ma.astype('f4') out2 = np.array_repr(ma2) assert out2 == 'MaskedNDArray([——, 1., 2.], dtype=float32)' def test_array_str(self): out = np.array_str(self.ma) assert out == '[— 1 2]' class TestBitFunctions: @classmethod def setup_class(self): self.a = np.array([15, 255, 0], dtype='u1') self.mask_a = np.array([False, True, False]) self.ma = Masked(self.a, mask=self.mask_a) self.b = np.unpackbits(self.a).reshape(6, 4) self.mask_b = np.array([False]*15 + [True, True] + [False]*7).reshape(6, 4) self.mb = Masked(self.b, mask=self.mask_b) @pytest.mark.parametrize('axis', [None, 1, 0]) def test_packbits(self, axis): out = np.packbits(self.mb, axis=axis) if axis is None: expected = self.a else: expected = np.packbits(self.b, axis=axis) expected_mask = np.packbits(self.mask_b, axis=axis) > 0 assert_array_equal(out.unmasked, expected) assert_array_equal(out.mask, expected_mask) def test_unpackbits(self): out = np.unpackbits(self.ma) mask = np.where(self.mask_a, np.uint8(255), np.uint8(0)) expected_mask = np.unpackbits(mask) > 0 assert_array_equal(out.unmasked, self.b.ravel()) assert_array_equal(out.mask, expected_mask) class TestIndexFunctions(MaskedArraySetup): """Does not seem much sense to support these...""" def test_unravel_index(self): with pytest.raises(TypeError): np.unravel_index(self.ma, 3) def test_ravel_multi_index(self): with pytest.raises(TypeError): np.ravel_multi_index((self.ma,), 3) def test_ix_(self): with pytest.raises(TypeError): np.ix_(self.ma) class TestDtypeFunctions(MaskedArraySetup): def check(self, function, *args, **kwargs): out = function(self.ma, *args, **kwargs) expected = function(self.a, *args, **kwargs) assert out == expected def test_common_type(self): self.check(np.common_type) def test_result_type(self): self.check(np.result_type) def test_can_cast(self): self.check(np.can_cast, self.a.dtype) self.check(np.can_cast, 'f4') def test_min_scalar_type(self): out = np.min_scalar_type(self.ma[0, 0]) expected = np.min_scalar_type(self.a[0, 0]) assert out == expected def test_iscomplexobj(self): self.check(np.iscomplexobj) def test_isrealobj(self): self.check(np.isrealobj) class TestMeshGrid(MaskedArraySetup): def test_meshgrid(self): a = np.arange(1., 4.) mask_a = np.array([True, False, False]) ma = Masked(a, mask=mask_a) b = np.array([2.5, 10., 3., 4.]) mask_b = np.array([False, True, False, True]) mb = Masked(b, mask=mask_b) oa, ob = np.meshgrid(ma, mb) xa, xb = np.broadcast_arrays(a, b[:, np.newaxis]) ma, mb = np.broadcast_arrays(mask_a, mask_b[:, np.newaxis]) for o, x, m in ((oa, xa, ma), (ob, xb, mb)): assert_array_equal(o.unmasked, x) assert_array_equal(o.mask, m) class TestMemoryFunctions(MaskedArraySetup): def test_shares_memory(self): assert np.shares_memory(self.ma, self.ma.unmasked) assert not np.shares_memory(self.ma, self.ma.mask) def test_may_share_memory(self): assert np.may_share_memory(self.ma, self.ma.unmasked) assert not np.may_share_memory(self.ma, self.ma.mask) class TestDatetimeFunctions: # Could in principle support np.is_busday, np.busday_count, np.busday_offset. @classmethod def setup_class(self): self.a = np.array(['2020-12-31', '2021-01-01', '2021-01-02'], dtype='M') self.mask_a = np.array([False, True, False]) self.ma = Masked(self.a, mask=self.mask_a) self.b = np.array([['2021-01-07'], ['2021-01-31']], dtype='M') self.mask_b = np.array([[False], [True]]) self.mb = Masked(self.b, mask=self.mask_b) def test_datetime_as_string(self): out = np.datetime_as_string(self.ma) expected = np.datetime_as_string(self.a) assert_array_equal(out.unmasked, expected) assert_array_equal(out.mask, self.mask_a) @pytest.mark.filterwarnings('ignore:all-nan') class TestNaNFunctions: def setup_class(self): self.a = np.array([[np.nan, np.nan, 3.], [4., 5., 6.]]) self.mask_a = np.array([[True, False, False], [False, True, False]]) self.b = np.arange(1, 7).reshape(2, 3) self.mask_b = self.mask_a self.ma = Masked(self.a, mask=self.mask_a) self.mb = Masked(self.b, mask=self.mask_b) def check(self, function, exact_fill_value=None, masked_result=True, **kwargs): result = function(self.ma, **kwargs) expected_data = function(self.ma.filled(np.nan), **kwargs) expected_mask = np.isnan(expected_data) if masked_result: assert isinstance(result, Masked) assert_array_equal(result.mask, expected_mask) assert np.all(result == expected_data) else: assert not isinstance(result, Masked) assert_array_equal(result, expected_data) assert not np.any(expected_mask) out = np.zeros_like(result) result2 = function(self.ma, out=out, **kwargs) assert result2 is out assert_array_equal(result2, result) def check_arg(self, function, **kwargs): # arg functions do not have an 'out' argument, so just test directly. result = function(self.ma, **kwargs) assert not isinstance(result, Masked) expected = function(self.ma.filled(np.nan), **kwargs) assert_array_equal(result, expected) def test_nanmin(self): self.check(np.nanmin) self.check(np.nanmin, axis=0) self.check(np.nanmin, axis=1) resi = np.nanmin(self.mb, axis=1) assert_array_equal(resi.unmasked, np.array([2, 4])) assert_array_equal(resi.mask, np.array([False, False])) def test_nanmax(self): self.check(np.nanmax) def test_nanargmin(self): self.check_arg(np.nanargmin) self.check_arg(np.nanargmin, axis=1) def test_nanargmax(self): self.check_arg(np.nanargmax) def test_nansum(self): self.check(np.nansum, masked_result=False) resi = np.nansum(self.mb, axis=1) assert not isinstance(resi, Masked) assert_array_equal(resi, np.array([5, 10])) def test_nanprod(self): self.check(np.nanprod, masked_result=False) resi = np.nanprod(self.mb, axis=1) assert not isinstance(resi, Masked) assert_array_equal(resi, np.array([6, 24])) def test_nancumsum(self): self.check(np.nancumsum, masked_result=False) resi = np.nancumsum(self.mb, axis=1) assert not isinstance(resi, Masked) assert_array_equal(resi, np.array([[0, 2, 5], [4, 4, 10]])) def test_nancumprod(self): self.check(np.nancumprod, masked_result=False) resi = np.nancumprod(self.mb, axis=1) assert not isinstance(resi, Masked) assert_array_equal(resi, np.array([[1, 2, 6], [4, 4, 24]])) def test_nanmean(self): self.check(np.nanmean) resi = np.nanmean(self.mb, axis=1) assert_array_equal(resi.unmasked, np.mean(self.mb, axis=1).unmasked) assert_array_equal(resi.mask, np.array([False, False])) def test_nanvar(self): self.check(np.nanvar) self.check(np.nanvar, ddof=1) def test_nanstd(self): self.check(np.nanstd) def test_nanmedian(self): self.check(np.nanmedian) def test_nanquantile(self): self.check(np.nanquantile, q=0.5) def test_nanpercentile(self): self.check(np.nanpercentile, q=50) untested_functions = set() if NUMPY_LT_1_20: financial_functions = {f for f in all_wrapped_functions.values() if f in np.lib.financial.__dict__.values()} untested_functions |= financial_functions if NUMPY_LT_1_23: deprecated_functions = { # Deprecated, removed in numpy 1.23 np.asscalar, np.alen, } else: deprecated_functions = set() untested_functions |= deprecated_functions io_functions = {np.save, np.savez, np.savetxt, np.savez_compressed} untested_functions |= io_functions poly_functions = { np.poly, np.polyadd, np.polyder, np.polydiv, np.polyfit, np.polyint, np.polymul, np.polysub, np.polyval, np.roots, np.vander } untested_functions |= poly_functions # Get covered functions tested_functions = set() for cov_cls in list(filter(inspect.isclass, locals().values())): for k, v in cov_cls.__dict__.items(): if inspect.isfunction(v) and k.startswith('test'): f = k.replace('test_', '') if f in all_wrapped_functions: tested_functions.add(all_wrapped_functions[f]) def test_basic_testing_completeness(): assert all_wrapped == (tested_functions | IGNORED_FUNCTIONS | UNSUPPORTED_FUNCTIONS) @pytest.mark.xfail(reason='coverage not completely set up yet') def test_testing_completeness(): assert not tested_functions.intersection(untested_functions) assert all_wrapped == (tested_functions | untested_functions) class TestFunctionHelpersCompleteness: @pytest.mark.parametrize('one, two', itertools.combinations( (MASKED_SAFE_FUNCTIONS, UNSUPPORTED_FUNCTIONS, set(APPLY_TO_BOTH_FUNCTIONS.keys()), set(DISPATCHED_FUNCTIONS.keys())), 2)) def test_no_duplicates(self, one, two): assert not one.intersection(two) def test_all_included(self): included_in_helpers = (MASKED_SAFE_FUNCTIONS | UNSUPPORTED_FUNCTIONS | set(APPLY_TO_BOTH_FUNCTIONS.keys()) | set(DISPATCHED_FUNCTIONS.keys())) assert all_wrapped == included_in_helpers @pytest.mark.xfail(reason='coverage not completely set up yet') def test_ignored_are_untested(self): assert IGNORED_FUNCTIONS == untested_functions ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/masked/tests/test_functions.py0000644000175100001710000003250000000000000023135 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """Test numpy functions and ufuncs on Masked arrays and quantities. The tests here are fairly detailed but do not aim for complete coverage. Complete coverage of all numpy functions is done with less detailed tests in test_function_helpers. """ import pytest import numpy as np from numpy.testing import assert_array_equal from astropy import units as u from astropy.units import Quantity from astropy.utils.masked.core import Masked from .test_masked import (MaskedArraySetup, QuantitySetup, LongitudeSetup, assert_masked_equal) class MaskedUfuncTests(MaskedArraySetup): @pytest.mark.parametrize('ufunc', (np.add, np.subtract, np.divide, np.arctan2, np.minimum)) def test_2op_ufunc(self, ufunc): ma_mb = ufunc(self.ma, self.mb) expected_data = ufunc(self.a, self.b) expected_mask = (self.ma.mask | self.mb.mask) # Note: assert_array_equal also checks type, i.e., that, e.g., # Longitude decays into an Angle. assert_array_equal(ma_mb.unmasked, expected_data) assert_array_equal(ma_mb.mask, expected_mask) @pytest.mark.parametrize('ufunc', (np.add, np.subtract, np.divide, np.arctan2, np.minimum)) def test_ufunc_inplace(self, ufunc): ma_mb = ufunc(self.ma, self.mb) out = Masked(np.zeros_like(ma_mb.unmasked)) result = ufunc(self.ma, self.mb, out=out) assert result is out assert_masked_equal(result, ma_mb) def test_ufunc_inplace_no_masked_input(self): a_b = np.add(self.a, self.b) out = Masked(np.zeros_like(a_b)) result = np.add(self.a, self.b, out=out) assert result is out assert_array_equal(result.unmasked, a_b) assert_array_equal(result.mask, np.zeros(a_b.shape, bool)) def test_ufunc_inplace_error(self): out = np.zeros(self.ma.shape) with pytest.raises(TypeError): np.add(self.ma, self.mb, out=out) @pytest.mark.parametrize('ufunc', (np.add.outer, np.minimum.outer)) def test_2op_ufunc_outer(self, ufunc): ma_mb = ufunc(self.ma, self.mb) expected_data = ufunc(self.a, self.b) expected_mask = np.logical_or.outer(self.mask_a, self.mask_b) # Note: assert_array_equal also checks type, i.e., that, e.g., # Longitude decays into an Angle. assert_array_equal(ma_mb.unmasked, expected_data) assert_array_equal(ma_mb.mask, expected_mask) def test_3op_ufunc(self): ma_mb = np.clip(self.ma, self.b, self.c) expected_data = np.clip(self.a, self.b, self.c) expected_mask = self.mask_a assert_array_equal(ma_mb.unmasked, expected_data) assert_array_equal(ma_mb.mask, expected_mask) @pytest.mark.parametrize('axis', (0, 1, None)) def test_add_reduce(self, axis): ma_reduce = np.add.reduce(self.ma, axis=axis) expected_data = np.add.reduce(self.a, axis=axis) expected_mask = np.logical_or.reduce(self.ma.mask, axis=axis) assert_array_equal(ma_reduce.unmasked, expected_data) assert_array_equal(ma_reduce.mask, expected_mask) out = Masked(np.zeros_like(ma_reduce.unmasked), np.ones_like(ma_reduce.mask)) ma_reduce2 = np.add.reduce(self.ma, axis=axis, out=out) assert ma_reduce2 is out assert_masked_equal(ma_reduce2, ma_reduce) def test_add_reduce_no_masked_input(self): a_reduce = np.add.reduce(self.a, axis=0) out = Masked(np.zeros_like(a_reduce), np.ones(a_reduce.shape, bool)) result = np.add.reduce(self.a, axis=0, out=out) assert result is out assert_array_equal(out.unmasked, a_reduce) assert_array_equal(out.mask, np.zeros(a_reduce.shape, bool)) @pytest.mark.parametrize('axis', (0, 1, None)) def test_minimum_reduce(self, axis): ma_reduce = np.minimum.reduce(self.ma, axis=axis) expected_data = np.minimum.reduce(self.a, axis=axis) expected_mask = np.logical_or.reduce(self.ma.mask, axis=axis) assert_array_equal(ma_reduce.unmasked, expected_data) assert_array_equal(ma_reduce.mask, expected_mask) @pytest.mark.parametrize('axis', (0, 1, None)) def test_maximum_reduce(self, axis): ma_reduce = np.maximum.reduce(self.ma, axis=axis) expected_data = np.maximum.reduce(self.a, axis=axis) expected_mask = np.logical_or.reduce(self.ma.mask, axis=axis) assert_array_equal(ma_reduce.unmasked, expected_data) assert_array_equal(ma_reduce.mask, expected_mask) class TestMaskedArrayUfuncs(MaskedUfuncTests): # multiply.reduce does not work with units, so test only for plain array. @pytest.mark.parametrize('axis', (0, 1, None)) def test_multiply_reduce(self, axis): ma_reduce = np.multiply.reduce(self.ma, axis=axis) expected_data = np.multiply.reduce(self.a, axis=axis) expected_mask = np.logical_or.reduce(self.ma.mask, axis=axis) assert_array_equal(ma_reduce.unmasked, expected_data) assert_array_equal(ma_reduce.mask, expected_mask) def test_ufunc_not_implemented_for_other(self): """ If the unmasked operation returns NotImplemented, this should lead to a TypeError also for the masked version. """ a = np.array([1, 2]) b = 3 * u.m with pytest.raises(TypeError): a & b ma = Masked(a) with pytest.raises(TypeError): ma & b class TestMaskedQuantityUfuncs(MaskedUfuncTests, QuantitySetup): def test_ufunc_inplace_error2(self): out = Masked(np.zeros(self.ma.shape)) with pytest.raises(TypeError): np.add(self.ma, self.mb, out=out) class TestMaskedLongitudeUfuncs(MaskedUfuncTests, LongitudeSetup): def test_ufunc_inplace_quantity_initial(self): out = Masked(np.zeros(self.ma.shape) << u.m) result = np.add(self.ma, self.mb, out=out) assert result is out expected = np.add(self.ma, self.mb).view(Quantity) assert_masked_equal(result, expected) class TestMaskedArrayConcatenation(MaskedArraySetup): def test_concatenate(self): mb = self.mb[np.newaxis] concat_a_b = np.concatenate((self.ma, mb), axis=0) expected_data = np.concatenate((self.a, self.b[np.newaxis]), axis=0) expected_mask = np.concatenate((self.mask_a, self.mask_b[np.newaxis]), axis=0) assert_array_equal(concat_a_b.unmasked, expected_data) assert_array_equal(concat_a_b.mask, expected_mask) def test_concatenate_not_all_masked(self): mb = self.mb[np.newaxis] concat_a_b = np.concatenate((self.a, mb), axis=0) expected_data = np.concatenate((self.a, self.b[np.newaxis]), axis=0) expected_mask = np.concatenate((np.zeros(self.a.shape, bool), self.mask_b[np.newaxis]), axis=0) assert_array_equal(concat_a_b.unmasked, expected_data) assert_array_equal(concat_a_b.mask, expected_mask) @pytest.mark.parametrize('obj', (1, slice(2, 3))) def test_insert(self, obj): mc_in_a = np.insert(self.ma, obj, self.mc, axis=-1) expected = Masked(np.insert(self.a, obj, self.c, axis=-1), np.insert(self.mask_a, obj, self.mask_c, axis=-1)) assert_masked_equal(mc_in_a, expected) def test_insert_masked_obj(self): with pytest.raises(TypeError): np.insert(self.ma, Masked(1, mask=False), self.mc, axis=-1) def test_append(self): mc_to_a = np.append(self.ma, self.mc, axis=-1) expected = Masked(np.append(self.a, self.c, axis=-1), np.append(self.mask_a, self.mask_c, axis=-1)) assert_masked_equal(mc_to_a, expected) class TestMaskedQuantityConcatenation(TestMaskedArrayConcatenation, QuantitySetup): pass class TestMaskedLongitudeConcatenation(TestMaskedArrayConcatenation, LongitudeSetup): pass class TestMaskedArrayBroadcast(MaskedArraySetup): def test_broadcast_to(self): shape = self.ma.shape ba = np.broadcast_to(self.mb, shape, subok=True) assert ba.shape == shape assert ba.mask.shape == shape expected = Masked(np.broadcast_to(self.mb.unmasked, shape, subok=True), np.broadcast_to(self.mb.mask, shape, subok=True)) assert_masked_equal(ba, expected) def test_broadcast_to_using_apply(self): # Partially just to ensure we cover the relevant part of _apply. shape = self.ma.shape ba = self.mb._apply(np.broadcast_to, shape=shape, subok=True) assert ba.shape == shape assert ba.mask.shape == shape expected = Masked(np.broadcast_to(self.mb.unmasked, shape, subok=True), np.broadcast_to(self.mb.mask, shape, subok=True)) assert_masked_equal(ba, expected) def test_broadcast_arrays(self): mb = np.broadcast_arrays(self.ma, self.mb, self.mc, subok=True) b = np.broadcast_arrays(self.a, self.b, self.c, subok=True) bm = np.broadcast_arrays(self.mask_a, self.mask_b, self.mask_c) for mb_, b_, bm_ in zip(mb, b, bm): assert_array_equal(mb_.unmasked, b_) assert_array_equal(mb_.mask, bm_) def test_broadcast_arrays_not_all_masked(self): mb = np.broadcast_arrays(self.a, self.mb, self.c, subok=True) assert_array_equal(mb[0], self.a) expected1 = np.broadcast_to(self.mb, self.a.shape, subok=True) assert_masked_equal(mb[1], expected1) expected2 = np.broadcast_to(self.c, self.a.shape, subok=True) assert_array_equal(mb[2], expected2) def test_broadcast_arrays_subok_false(self): # subok affects ndarray subclasses but not masking itself. mb = np.broadcast_arrays(self.ma, self.mb, self.mc, subok=False) assert all(type(mb_.unmasked) is np.ndarray for mb_ in mb) b = np.broadcast_arrays(self.a, self.b, self.c, subok=False) mask_b = np.broadcast_arrays(self.mask_a, self.mask_b, self.mask_c, subok=False) for mb_, b_, mask_ in zip(mb, b, mask_b): assert_array_equal(mb_.unmasked, b_) assert_array_equal(mb_.mask, mask_) class TestMaskedQuantityBroadcast(TestMaskedArrayBroadcast, QuantitySetup): pass class TestMaskedLongitudeBroadcast(TestMaskedArrayBroadcast, LongitudeSetup): pass class TestMaskedArrayCalculation(MaskedArraySetup): @pytest.mark.parametrize('n,axis', [(1, -1), (2, -1), (1, 0)]) def test_diff(self, n, axis): mda = np.diff(self.ma, n=n, axis=axis) expected_data = np.diff(self.a, n, axis) nan_mask = np.zeros_like(self.a) nan_mask[self.ma.mask] = np.nan expected_mask = np.isnan(np.diff(nan_mask, n=n, axis=axis)) assert_array_equal(mda.unmasked, expected_data) assert_array_equal(mda.mask, expected_mask) def test_diff_explicit(self): ma = Masked(np.arange(8.), [True, False, False, False, False, True, False, False]) mda = np.diff(ma) assert np.all(mda.unmasked == 1.) assert np.all(mda.mask == [True, False, False, False, True, True, False]) mda = np.diff(ma, n=2) assert np.all(mda.unmasked == 0.) assert np.all(mda.mask == [True, False, False, True, True, True]) class TestMaskedQuantityCalculation(TestMaskedArrayCalculation, QuantitySetup): pass class TestMaskedLongitudeCalculation(TestMaskedArrayCalculation, LongitudeSetup): pass class TestMaskedArraySorting(MaskedArraySetup): @pytest.mark.parametrize('axis', [-1, 0]) def test_lexsort1(self, axis): ma_lexsort = np.lexsort((self.ma,), axis=axis) filled = self.a.copy() filled[self.mask_a] = 9e9 expected_data = filled.argsort(axis) assert_array_equal(ma_lexsort, expected_data) @pytest.mark.parametrize('axis', [-1, 0]) def test_lexsort2(self, axis): mb = np.broadcast_to(-self.mb, self.ma.shape).copy() mamb_lexsort = np.lexsort((self.ma, mb), axis=axis) filled_a = self.ma.filled(9e9) filled_b = mb.filled(9e9) expected_ab = np.lexsort((filled_a, filled_b), axis=axis) assert_array_equal(mamb_lexsort, expected_ab) mbma_lexsort = np.lexsort((mb, self.ma), axis=axis) expected_ba = np.lexsort((filled_b, filled_a), axis=axis) assert_array_equal(mbma_lexsort, expected_ba) mbma_lexsort2 = np.lexsort(np.stack([mb, self.ma], axis=0), axis=axis) assert_array_equal(mbma_lexsort2, expected_ba) @pytest.mark.parametrize('axis', [-1, 0]) def test_lexsort_mix(self, axis): mb = np.broadcast_to(-self.mb, self.ma.shape).copy() mamb_lexsort = np.lexsort((self.a, mb), axis=axis) filled_b = mb.filled(9e9) expected_ab = np.lexsort((self.a, filled_b), axis=axis) assert_array_equal(mamb_lexsort, expected_ab) mbma_lexsort = np.lexsort((mb, self.a), axis=axis) expected_ba = np.lexsort((filled_b, self.a), axis=axis) assert_array_equal(mbma_lexsort, expected_ba) mbma_lexsort2 = np.lexsort(np.stack([mb, self.a], axis=0), axis=axis) assert_array_equal(mbma_lexsort2, expected_ba) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/masked/tests/test_masked.py0000644000175100001710000013175100000000000022401 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """Test masked class initialization, methods, and operators. Functions, including ufuncs, are tested in test_functions.py """ import operator import numpy as np from numpy.testing import assert_array_equal import pytest from astropy import units as u from astropy.units import Quantity from astropy.coordinates import Longitude from astropy.utils.masked import Masked, MaskedNDArray def assert_masked_equal(a, b): assert_array_equal(a.unmasked, b.unmasked) assert_array_equal(a.mask, b.mask) VARIOUS_ITEMS = [ (1, 1), slice(None, 1), (), 1] class ArraySetup: _data_cls = np.ndarray @classmethod def setup_class(self): self.a = np.arange(6.).reshape(2, 3) self.mask_a = np.array([[True, False, False], [False, True, False]]) self.b = np.array([-3., -2., -1.]) self.mask_b = np.array([False, True, False]) self.c = np.array([[0.25], [0.5]]) self.mask_c = np.array([[False], [True]]) self.sdt = np.dtype([('a', 'f8'), ('b', 'f8')]) self.mask_sdt = np.dtype([('a', '?'), ('b', '?')]) self.sa = np.array([[(1., 2.), (3., 4.)], [(11., 12.), (13., 14.)]], dtype=self.sdt) self.mask_sa = np.array([[(True, True), (False, False)], [(False, True), (True, False)]], dtype=self.mask_sdt) self.sb = np.array([(1., 2.), (-3., 4.)], dtype=self.sdt) self.mask_sb = np.array([(True, False), (False, False)], dtype=self.mask_sdt) class QuantitySetup(ArraySetup): _data_cls = Quantity @classmethod def setup_class(self): super().setup_class() self.a = Quantity(self.a, u.m) self.b = Quantity(self.b, u.cm) self.c = Quantity(self.c, u.km) self.sa = Quantity(self.sa, u.m, dtype=self.sdt) self.sb = Quantity(self.sb, u.cm, dtype=self.sdt) class LongitudeSetup(ArraySetup): _data_cls = Longitude @classmethod def setup_class(self): super().setup_class() self.a = Longitude(self.a, u.deg) self.b = Longitude(self.b, u.deg) self.c = Longitude(self.c, u.deg) # Note: Longitude does not work on structured arrays, so # leaving it as regular array (which just reruns some tests). class TestMaskedArrayInitialization(ArraySetup): def test_simple(self): ma = Masked(self.a, mask=self.mask_a) assert isinstance(ma, np.ndarray) assert isinstance(ma, type(self.a)) assert isinstance(ma, Masked) assert_array_equal(ma.unmasked, self.a) assert_array_equal(ma.mask, self.mask_a) assert ma.mask is not self.mask_a assert np.may_share_memory(ma.mask, self.mask_a) def test_structured(self): ma = Masked(self.sa, mask=self.mask_sa) assert isinstance(ma, np.ndarray) assert isinstance(ma, type(self.sa)) assert isinstance(ma, Masked) assert_array_equal(ma.unmasked, self.sa) assert_array_equal(ma.mask, self.mask_sa) assert ma.mask is not self.mask_sa assert np.may_share_memory(ma.mask, self.mask_sa) def test_masked_ndarray_init(): # Note: as a straight ndarray subclass, MaskedNDArray passes on # the arguments relevant for np.ndarray, not np.array. a_in = np.arange(3, dtype=int) m_in = np.array([True, False, False]) buff = a_in.tobytes() # Check we're doing things correctly using regular ndarray. a = np.ndarray(shape=(3,), dtype=int, buffer=buff) assert_array_equal(a, a_in) # Check with and without mask. ma = MaskedNDArray((3,), dtype=int, mask=m_in, buffer=buff) assert_array_equal(ma.unmasked, a_in) assert_array_equal(ma.mask, m_in) ma = MaskedNDArray((3,), dtype=int, buffer=buff) assert_array_equal(ma.unmasked, a_in) assert_array_equal(ma.mask, np.zeros(3, bool)) def test_cannot_initialize_with_masked(): with pytest.raises(ValueError, match='cannot handle np.ma.masked'): Masked(np.ma.masked) def test_cannot_just_use_anything_with_a_mask_attribute(): class my_array(np.ndarray): mask = True a = np.array([1., 2.]).view(my_array) with pytest.raises(AttributeError, match='unmasked'): Masked(a) class TestMaskedClassCreation: """Try creating a MaskedList and subclasses. By no means meant to be realistic, just to check that the basic machinery allows it. """ @classmethod def setup_class(self): self._base_classes_orig = Masked._base_classes.copy() self._masked_classes_orig = Masked._masked_classes.copy() class MaskedList(Masked, list, base_cls=list, data_cls=list): def __new__(cls, *args, mask=None, copy=False, **kwargs): self = super().__new__(cls) self._unmasked = self._data_cls(*args, **kwargs) self.mask = mask return self # Need to have shape for basics to work. @property def shape(self): return (len(self._unmasked),) self.MaskedList = MaskedList def teardown_class(self): Masked._base_classes = self._base_classes_orig Masked._masked_classes = self._masked_classes_orig def test_setup(self): assert issubclass(self.MaskedList, Masked) assert issubclass(self.MaskedList, list) assert Masked(list) is self.MaskedList def test_masked_list(self): ml = self.MaskedList(range(3), mask=[True, False, False]) assert ml.unmasked == [0, 1, 2] assert_array_equal(ml.mask, np.array([True, False, False])) ml01 = ml[:2] assert ml01.unmasked == [0, 1] assert_array_equal(ml01.mask, np.array([True, False])) def test_from_list(self): ml = Masked([1, 2, 3], mask=[True, False, False]) assert ml.unmasked == [1, 2, 3] assert_array_equal(ml.mask, np.array([True, False, False])) def test_masked_list_subclass(self): class MyList(list): pass ml = MyList(range(3)) mml = Masked(ml, mask=[False, True, False]) assert isinstance(mml, Masked) assert isinstance(mml, MyList) assert isinstance(mml.unmasked, MyList) assert mml.unmasked == [0, 1, 2] assert_array_equal(mml.mask, np.array([False, True, False])) assert Masked(MyList) is type(mml) class TestMaskedNDArraySubclassCreation: """Test that masked subclasses can be created directly and indirectly.""" @classmethod def setup_class(self): class MyArray(np.ndarray): def __new__(cls, *args, **kwargs): return np.asanyarray(*args, **kwargs).view(cls) self.MyArray = MyArray self.a = np.array([1., 2.]).view(self.MyArray) self.m = np.array([True, False], dtype=bool) def teardown_method(self, method): Masked._masked_classes.pop(self.MyArray, None) def test_direct_creation(self): assert self.MyArray not in Masked._masked_classes mcls = Masked(self.MyArray) assert issubclass(mcls, Masked) assert issubclass(mcls, self.MyArray) assert mcls.__name__ == 'MaskedMyArray' assert mcls.__doc__.startswith('Masked version of MyArray') mms = mcls(self.a, mask=self.m) assert isinstance(mms, mcls) assert_array_equal(mms.unmasked, self.a) assert_array_equal(mms.mask, self.m) def test_initialization_without_mask(self): # Default for not giving a mask should be False. mcls = Masked(self.MyArray) mms = mcls(self.a) assert isinstance(mms, mcls) assert_array_equal(mms.unmasked, self.a) assert_array_equal(mms.mask, np.zeros(mms.shape, bool)) @pytest.mark.parametrize('masked_array', [Masked, np.ma.MaskedArray]) def test_initialization_with_masked_values(self, masked_array): mcls = Masked(self.MyArray) ma = masked_array(np.asarray(self.a), mask=self.m) mms = mcls(ma) assert isinstance(mms, Masked) assert isinstance(mms, self.MyArray) assert_array_equal(mms.unmasked, self.a) assert_array_equal(mms.mask, self.m) def test_indirect_creation(self): assert self.MyArray not in Masked._masked_classes mms = Masked(self.a, mask=self.m) assert isinstance(mms, Masked) assert isinstance(mms, self.MyArray) assert_array_equal(mms.unmasked, self.a) assert_array_equal(mms.mask, self.m) assert self.MyArray in Masked._masked_classes assert Masked(self.MyArray) is type(mms) def test_can_initialize_with_masked_values(self): mcls = Masked(self.MyArray) mms = mcls(Masked(np.asarray(self.a), mask=self.m)) assert isinstance(mms, Masked) assert isinstance(mms, self.MyArray) assert_array_equal(mms.unmasked, self.a) assert_array_equal(mms.mask, self.m) def test_viewing(self): mms = Masked(self.a, mask=self.m) mms2 = mms.view() assert type(mms2) is mms.__class__ assert_masked_equal(mms2, mms) ma = mms.view(np.ndarray) assert type(ma) is MaskedNDArray assert_array_equal(ma.unmasked, self.a.view(np.ndarray)) assert_array_equal(ma.mask, self.m) class TestMaskedQuantityInitialization(TestMaskedArrayInitialization, QuantitySetup): def test_masked_quantity_class_init(self): # TODO: class definitions should be more easily accessible. mcls = Masked._masked_classes[self.a.__class__] # This is not a very careful test. mq = mcls([1., 2.], mask=[True, False], unit=u.s) assert mq.unit == u.s assert np.all(mq.value.unmasked == [1., 2.]) assert np.all(mq.value.mask == [True, False]) assert np.all(mq.mask == [True, False]) def test_masked_quantity_getting(self): mcls = Masked._masked_classes[self.a.__class__] MQ = Masked(Quantity) assert MQ is mcls def test_initialization_without_mask(self): # Default for not giving a mask should be False. MQ = Masked(Quantity) mq = MQ([1., 2.], u.s) assert mq.unit == u.s assert np.all(mq.value.unmasked == [1., 2.]) assert np.all(mq.mask == [False, False]) @pytest.mark.parametrize('masked_array', [Masked, np.ma.MaskedArray]) def test_initialization_with_masked_values(self, masked_array): MQ = Masked(Quantity) a = np.array([1., 2.]) m = np.array([True, False]) ma = masked_array(a, m) mq = MQ(ma) assert isinstance(mq, Masked) assert isinstance(mq, Quantity) assert_array_equal(mq.value.unmasked, a) assert_array_equal(mq.mask, m) class TestMaskSetting(ArraySetup): def test_whole_mask_setting_simple(self): ma = Masked(self.a) assert ma.mask.shape == ma.shape assert not ma.mask.any() ma.mask = True assert ma.mask.shape == ma.shape assert ma.mask.all() ma.mask = [[True], [False]] assert ma.mask.shape == ma.shape assert_array_equal(ma.mask, np.array([[True] * 3, [False] * 3])) ma.mask = self.mask_a assert ma.mask.shape == ma.shape assert_array_equal(ma.mask, self.mask_a) assert ma.mask is not self.mask_a assert np.may_share_memory(ma.mask, self.mask_a) def test_whole_mask_setting_structured(self): ma = Masked(self.sa) assert ma.mask.shape == ma.shape assert not ma.mask['a'].any() and not ma.mask['b'].any() ma.mask = True assert ma.mask.shape == ma.shape assert ma.mask['a'].all() and ma.mask['b'].all() ma.mask = [[True], [False]] assert ma.mask.shape == ma.shape assert_array_equal(ma.mask, np.array( [[(True, True)] * 2, [(False, False)] * 2], dtype=self.mask_sdt)) ma.mask = self.mask_sa assert ma.mask.shape == ma.shape assert_array_equal(ma.mask, self.mask_sa) assert ma.mask is not self.mask_sa assert np.may_share_memory(ma.mask, self.mask_sa) @pytest.mark.parametrize('item', VARIOUS_ITEMS) def test_part_mask_setting(self, item): ma = Masked(self.a) ma.mask[item] = True expected = np.zeros(ma.shape, bool) expected[item] = True assert_array_equal(ma.mask, expected) ma.mask[item] = False assert_array_equal(ma.mask, np.zeros(ma.shape, bool)) # Mask propagation mask = np.zeros(self.a.shape, bool) ma = Masked(self.a, mask) ma.mask[item] = True assert np.may_share_memory(ma.mask, mask) assert_array_equal(ma.mask, mask) @pytest.mark.parametrize('item', ['a'] + VARIOUS_ITEMS) def test_part_mask_setting_structured(self, item): ma = Masked(self.sa) ma.mask[item] = True expected = np.zeros(ma.shape, self.mask_sdt) expected[item] = True assert_array_equal(ma.mask, expected) ma.mask[item] = False assert_array_equal(ma.mask, np.zeros(ma.shape, self.mask_sdt)) # Mask propagation mask = np.zeros(self.sa.shape, self.mask_sdt) ma = Masked(self.sa, mask) ma.mask[item] = True assert np.may_share_memory(ma.mask, mask) assert_array_equal(ma.mask, mask) # Following are tests where we trust the initializer works. class MaskedArraySetup(ArraySetup): @classmethod def setup_class(self): super().setup_class() self.ma = Masked(self.a, mask=self.mask_a) self.mb = Masked(self.b, mask=self.mask_b) self.mc = Masked(self.c, mask=self.mask_c) self.msa = Masked(self.sa, mask=self.mask_sa) self.msb = Masked(self.sb, mask=self.mask_sb) class TestViewing(MaskedArraySetup): def test_viewing_as_new_type(self): ma2 = self.ma.view(type(self.ma)) assert_masked_equal(ma2, self.ma) ma3 = self.ma.view() assert_masked_equal(ma3, self.ma) def test_viewing_as_new_dtype(self): # Not very meaningful, but possible... ma2 = self.ma.view('c8') assert_array_equal(ma2.unmasked, self.a.view('c8')) assert_array_equal(ma2.mask, self.mask_a) @pytest.mark.parametrize('new_dtype', ['2f4', 'f8,f8,f8']) def test_viewing_as_new_dtype_not_implemented(self, new_dtype): # But cannot (yet) view in way that would need to create a new mask, # even though that view is possible for a regular array. check = self.a.view(new_dtype) with pytest.raises(NotImplementedError, match='different.*size'): self.ma.view(check.dtype) def test_viewing_as_something_impossible(self): with pytest.raises(TypeError): # Use intp to ensure have the same size as object, # otherwise we get a different error message Masked(np.array([1, 2], dtype=np.intp)).view(Masked) class TestMaskedArrayCopyFilled(MaskedArraySetup): def test_copy(self): ma_copy = self.ma.copy() assert type(ma_copy) is type(self.ma) assert_array_equal(ma_copy.unmasked, self.ma.unmasked) assert_array_equal(ma_copy.mask, self.ma.mask) assert not np.may_share_memory(ma_copy.unmasked, self.ma.unmasked) assert not np.may_share_memory(ma_copy.mask, self.ma.mask) @pytest.mark.parametrize('fill_value', (0, 1)) def test_filled(self, fill_value): fill_value = fill_value * getattr(self.a, 'unit', 1) expected = self.a.copy() expected[self.ma.mask] = fill_value result = self.ma.filled(fill_value) assert_array_equal(expected, result) def test_filled_no_fill_value(self): with pytest.raises(TypeError, match='missing 1 required'): self.ma.filled() @pytest.mark.parametrize('fill_value', [(0, 1), (-1, -1)]) def test_filled_structured(self, fill_value): fill_value = np.array(fill_value, dtype=self.sdt) if hasattr(self.sa, 'unit'): fill_value = fill_value << self.sa.unit expected = self.sa.copy() expected['a'][self.msa.mask['a']] = fill_value['a'] expected['b'][self.msa.mask['b']] = fill_value['b'] result = self.msa.filled(fill_value) assert_array_equal(expected, result) def test_flat(self): ma_copy = self.ma.copy() ma_flat = ma_copy.flat # Check that single item keeps class and mask ma_flat1 = ma_flat[1] assert ma_flat1.unmasked == self.a.flat[1] assert ma_flat1.mask == self.mask_a.flat[1] # As well as getting items via iteration. assert all((ma.unmasked == a and ma.mask == m) for (ma, a, m) in zip(self.ma.flat, self.a.flat, self.mask_a.flat)) # check that flat works like a view of the real array ma_flat[1] = self.b[1] assert ma_flat[1] == self.b[1] assert ma_copy[0, 1] == self.b[1] class TestMaskedQuantityCopyFilled(TestMaskedArrayCopyFilled, QuantitySetup): pass class TestMaskedLongitudeCopyFilled(TestMaskedArrayCopyFilled, LongitudeSetup): pass class TestMaskedArrayShaping(MaskedArraySetup): def test_reshape(self): ma_reshape = self.ma.reshape((6,)) expected_data = self.a.reshape((6,)) expected_mask = self.mask_a.reshape((6,)) assert ma_reshape.shape == expected_data.shape assert_array_equal(ma_reshape.unmasked, expected_data) assert_array_equal(ma_reshape.mask, expected_mask) def test_shape_setting(self): ma_reshape = self.ma.copy() ma_reshape.shape = 6, expected_data = self.a.reshape((6,)) expected_mask = self.mask_a.reshape((6,)) assert ma_reshape.shape == expected_data.shape assert_array_equal(ma_reshape.unmasked, expected_data) assert_array_equal(ma_reshape.mask, expected_mask) def test_shape_setting_failure(self): ma = self.ma.copy() with pytest.raises(ValueError, match='cannot reshape'): ma.shape = 5, assert ma.shape == self.ma.shape assert ma.mask.shape == self.ma.shape # Here, mask can be reshaped but array cannot. ma2 = Masked(np.broadcast_to([[1.], [2.]], self.a.shape), mask=self.mask_a) with pytest.raises(AttributeError, match='ncompatible shape'): ma2.shape = 6, assert ma2.shape == self.ma.shape assert ma2.mask.shape == self.ma.shape # Here, array can be reshaped but mask cannot. ma3 = Masked(self.a.copy(), mask=np.broadcast_to([[True], [False]], self.mask_a.shape)) with pytest.raises(AttributeError, match='ncompatible shape'): ma3.shape = 6, assert ma3.shape == self.ma.shape assert ma3.mask.shape == self.ma.shape def test_ravel(self): ma_ravel = self.ma.ravel() expected_data = self.a.ravel() expected_mask = self.mask_a.ravel() assert ma_ravel.shape == expected_data.shape assert_array_equal(ma_ravel.unmasked, expected_data) assert_array_equal(ma_ravel.mask, expected_mask) def test_transpose(self): ma_transpose = self.ma.transpose() expected_data = self.a.transpose() expected_mask = self.mask_a.transpose() assert ma_transpose.shape == expected_data.shape assert_array_equal(ma_transpose.unmasked, expected_data) assert_array_equal(ma_transpose.mask, expected_mask) def test_iter(self): for ma, d, m in zip(self.ma, self.a, self.mask_a): assert_array_equal(ma.unmasked, d) assert_array_equal(ma.mask, m) class MaskedItemTests(MaskedArraySetup): @pytest.mark.parametrize('item', VARIOUS_ITEMS) def test_getitem(self, item): ma_part = self.ma[item] expected_data = self.a[item] expected_mask = self.mask_a[item] assert_array_equal(ma_part.unmasked, expected_data) assert_array_equal(ma_part.mask, expected_mask) @pytest.mark.parametrize('item', ['a'] + VARIOUS_ITEMS) def test_getitem_structured(self, item): ma_part = self.msa[item] expected_data = self.sa[item] expected_mask = self.mask_sa[item] assert_array_equal(ma_part.unmasked, expected_data) assert_array_equal(ma_part.mask, expected_mask) @pytest.mark.parametrize('indices,axis', [ ([0, 1], 1), ([0, 1], 0), ([0, 1], None), ([[0, 1], [2, 3]], None)]) def test_take(self, indices, axis): ma_take = self.ma.take(indices, axis=axis) expected_data = self.a.take(indices, axis=axis) expected_mask = self.mask_a.take(indices, axis=axis) assert_array_equal(ma_take.unmasked, expected_data) assert_array_equal(ma_take.mask, expected_mask) ma_take2 = np.take(self.ma, indices, axis=axis) assert_masked_equal(ma_take2, ma_take) @pytest.mark.parametrize('item', VARIOUS_ITEMS) @pytest.mark.parametrize('mask', [None, True, False]) def test_setitem(self, item, mask): base = self.ma.copy() expected_data = self.a.copy() expected_mask = self.mask_a.copy() value = self.a[0, 0] if mask is None else Masked(self.a[0, 0], mask) base[item] = value expected_data[item] = value if mask is None else value.unmasked expected_mask[item] = False if mask is None else value.mask assert_array_equal(base.unmasked, expected_data) assert_array_equal(base.mask, expected_mask) @pytest.mark.parametrize('item', ['a'] + VARIOUS_ITEMS) @pytest.mark.parametrize('mask', [None, True, False]) def test_setitem_structured(self, item, mask): base = self.msa.copy() expected_data = self.sa.copy() expected_mask = self.mask_sa.copy() value = self.sa['b'] if item == 'a' else self.sa[0, 0] if mask is not None: value = Masked(value, mask) base[item] = value expected_data[item] = value if mask is None else value.unmasked expected_mask[item] = False if mask is None else value.mask assert_array_equal(base.unmasked, expected_data) assert_array_equal(base.mask, expected_mask) @pytest.mark.parametrize('item', VARIOUS_ITEMS) def test_setitem_np_ma_masked(self, item): base = self.ma.copy() expected_mask = self.mask_a.copy() base[item] = np.ma.masked expected_mask[item] = True assert_array_equal(base.unmasked, self.a) assert_array_equal(base.mask, expected_mask) class TestMaskedArrayItems(MaskedItemTests): @classmethod def setup_class(self): super().setup_class() self.d = np.array(['aa', 'bb']) self.mask_d = np.array([True, False]) self.md = Masked(self.d, self.mask_d) # Quantity, Longitude cannot hold strings. def test_getitem_strings(self): md = self.md.copy() md0 = md[0] assert md0.unmasked == self.d[0] assert md0.mask md_all = md[:] assert_masked_equal(md_all, md) def test_setitem_strings_np_ma_masked(self): md = self.md.copy() md[1] = np.ma.masked assert_array_equal(md.unmasked, self.d) assert_array_equal(md.mask, np.ones(2, bool)) class TestMaskedQuantityItems(MaskedItemTests, QuantitySetup): pass class TestMaskedLongitudeItems(MaskedItemTests, LongitudeSetup): pass class MaskedOperatorTests(MaskedArraySetup): @pytest.mark.parametrize('op', (operator.add, operator.sub)) def test_add_subtract(self, op): mapmb = op(self.ma, self.mb) expected_data = op(self.a, self.b) expected_mask = (self.ma.mask | self.mb.mask) # Note: assert_array_equal also checks type, i.e., that, e.g., # Longitude decays into an Angle. assert_array_equal(mapmb.unmasked, expected_data) assert_array_equal(mapmb.mask, expected_mask) @pytest.mark.parametrize('op', (operator.eq, operator.ne)) def test_equality(self, op): mapmb = op(self.ma, self.mb) expected_data = op(self.a, self.b) expected_mask = (self.ma.mask | self.mb.mask) # Note: assert_array_equal also checks type, i.e., that boolean # output is represented as plain Masked ndarray. assert_array_equal(mapmb.unmasked, expected_data) assert_array_equal(mapmb.mask, expected_mask) def test_not_implemented(self): with pytest.raises(TypeError): self.ma > 'abc' @pytest.mark.parametrize('different_names', [False, True]) @pytest.mark.parametrize('op', (operator.eq, operator.ne)) def test_structured_equality(self, op, different_names): msb = self.msb if different_names: msb = msb.astype([(f'different_{name}', dt) for name, dt in msb.dtype.fields.items()]) mapmb = op(self.msa, self.msb) # Expected is a bit tricky here: only unmasked fields count expected_data = np.ones(mapmb.shape, bool) expected_mask = np.ones(mapmb.shape, bool) for field in self.sdt.names: fa, mfa = self.sa[field], self.mask_sa[field] fb, mfb = self.sb[field], self.mask_sb[field] mfequal = mfa | mfb fequal = (fa == fb) | mfequal expected_data &= fequal expected_mask &= mfequal if op is operator.ne: expected_data = ~expected_data # Note: assert_array_equal also checks type, i.e., that boolean # output is represented as plain Masked ndarray. assert_array_equal(mapmb.unmasked, expected_data) assert_array_equal(mapmb.mask, expected_mask) def test_matmul(self): result = self.ma.T @ self.ma assert_array_equal(result.unmasked, self.a.T @ self.a) mask1 = np.any(self.mask_a, axis=0) expected_mask = np.logical_or.outer(mask1, mask1) assert_array_equal(result.mask, expected_mask) result2 = self.ma.T @ self.a assert_array_equal(result2.unmasked, self.a.T @ self.a) expected_mask2 = np.logical_or.outer(mask1, np.zeros(3, bool)) assert_array_equal(result2.mask, expected_mask2) result3 = self.a.T @ self.ma assert_array_equal(result3.unmasked, self.a.T @ self.a) expected_mask3 = np.logical_or.outer(np.zeros(3, bool), mask1) assert_array_equal(result3.mask, expected_mask3) def test_matvec(self): result = self.ma @ self.mb assert np.all(result.mask) assert_array_equal(result.unmasked, self.a @ self.b) # Just using the masked vector still has all elements masked. result2 = self.a @ self.mb assert np.all(result2.mask) assert_array_equal(result2.unmasked, self.a @ self.b) new_ma = self.ma.copy() new_ma.mask[0, 0] = False result3 = new_ma @ self.b assert_array_equal(result3.unmasked, self.a @ self.b) assert_array_equal(result3.mask, new_ma.mask.any(-1)) def test_vecmat(self): result = self.mb @ self.ma.T assert np.all(result.mask) assert_array_equal(result.unmasked, self.b @ self.a.T) result2 = self.b @ self.ma.T assert np.all(result2.mask) assert_array_equal(result2.unmasked, self.b @ self.a.T) new_ma = self.ma.T.copy() new_ma.mask[0, 0] = False result3 = self.b @ new_ma assert_array_equal(result3.unmasked, self.b @ self.a.T) assert_array_equal(result3.mask, new_ma.mask.any(0)) def test_vecvec(self): result = self.mb @ self.mb assert result.shape == () assert result.mask assert result.unmasked == self.b @ self.b mb_no_mask = Masked(self.b, False) result2 = mb_no_mask @ mb_no_mask assert not result2.mask class TestMaskedArrayOperators(MaskedOperatorTests): # Some further tests that use strings, which are not useful for Quantity. @pytest.mark.parametrize('op', (operator.eq, operator.ne)) def test_equality_strings(self, op): m1 = Masked(np.array(['a', 'b', 'c']), mask=[True, False, False]) m2 = Masked(np.array(['a', 'b', 'd']), mask=[False, False, False]) result = op(m1, m2) assert_array_equal(result.unmasked, op(m1.unmasked, m2.unmasked)) assert_array_equal(result.mask, m1.mask | m2.mask) result2 = op(m1, m2.unmasked) assert_masked_equal(result2, result) def test_not_implemented(self): with pytest.raises(TypeError): Masked(['a', 'b']) > object() class TestMaskedQuantityOperators(MaskedOperatorTests, QuantitySetup): pass class TestMaskedLongitudeOperators(MaskedOperatorTests, LongitudeSetup): pass class TestMaskedArrayMethods(MaskedArraySetup): def test_round(self): # Goes via ufunc, hence easy. mrc = self.mc.round() expected = Masked(self.c.round(), self.mask_c) assert_masked_equal(mrc, expected) @pytest.mark.parametrize('axis', (0, 1, None)) def test_sum(self, axis): ma_sum = self.ma.sum(axis) expected_data = self.a.sum(axis) expected_mask = self.ma.mask.any(axis) assert_array_equal(ma_sum.unmasked, expected_data) assert_array_equal(ma_sum.mask, expected_mask) @pytest.mark.parametrize('axis', (0, 1, None)) def test_cumsum(self, axis): ma_sum = self.ma.cumsum(axis) expected_data = self.a.cumsum(axis) mask = self.mask_a if axis is None: mask = mask.ravel() expected_mask = np.logical_or.accumulate(mask, axis=axis) assert_array_equal(ma_sum.unmasked, expected_data) assert_array_equal(ma_sum.mask, expected_mask) @pytest.mark.parametrize('axis', (0, 1, None)) def test_mean(self, axis): ma_mean = self.ma.mean(axis) filled = self.a.copy() filled[self.mask_a] = 0. count = 1 - self.ma.mask.astype(int) expected_data = filled.sum(axis) / count.sum(axis) expected_mask = self.ma.mask.all(axis) assert_array_equal(ma_mean.unmasked, expected_data) assert_array_equal(ma_mean.mask, expected_mask) def test_mean_int16(self): ma = self.ma.astype('i2') ma_mean = ma.mean() assert ma_mean.dtype == 'f8' expected = ma.astype('f8').mean() assert_masked_equal(ma_mean, expected) def test_mean_float16(self): ma = self.ma.astype('f2') ma_mean = ma.mean() assert ma_mean.dtype == 'f2' expected = self.ma.mean().astype('f2') assert_masked_equal(ma_mean, expected) def test_mean_inplace(self): expected = self.ma.mean(1) out = Masked(np.zeros_like(expected.unmasked)) result = self.ma.mean(1, out=out) assert result is out assert_masked_equal(out, expected) @pytest.mark.filterwarnings("ignore:.*encountered in.*divide") @pytest.mark.parametrize('axis', (0, 1, None)) def test_var(self, axis): ma_var = self.ma.var(axis) filled = (self.a - self.ma.mean(axis, keepdims=True))**2 filled[self.mask_a] = 0. count = (1 - self.ma.mask.astype(int)).sum(axis) expected_data = filled.sum(axis) / count expected_mask = self.ma.mask.all(axis) assert_array_equal(ma_var.unmasked, expected_data) assert_array_equal(ma_var.mask, expected_mask) ma_var1 = self.ma.var(axis, ddof=1) expected_data1 = filled.sum(axis) / (count - 1) expected_mask1 = self.ma.mask.all(axis) | (count <= 1) assert_array_equal(ma_var1.unmasked, expected_data1) assert_array_equal(ma_var1.mask, expected_mask1) ma_var5 = self.ma.var(axis, ddof=5) assert np.all(~np.isfinite(ma_var5.unmasked)) assert ma_var5.mask.all() def test_var_int16(self): ma = self.ma.astype('i2') ma_var = ma.var() assert ma_var.dtype == 'f8' expected = ma.astype('f8').var() assert_masked_equal(ma_var, expected) def test_std(self): ma_std = self.ma.std(1, ddof=1) ma_var1 = self.ma.var(1, ddof=1) expected = np.sqrt(ma_var1) assert_masked_equal(ma_std, expected) def test_std_inplace(self): expected = self.ma.std(1, ddof=1) out = Masked(np.zeros_like(expected.unmasked)) result = self.ma.std(1, ddof=1, out=out) assert result is out assert_masked_equal(result, expected) @pytest.mark.parametrize('axis', (0, 1, None)) def test_min(self, axis): ma_min = self.ma.min(axis) filled = self.a.copy() filled[self.mask_a] = self.a.max() expected_data = filled.min(axis) assert_array_equal(ma_min.unmasked, expected_data) assert not np.any(ma_min.mask) def test_min_with_masked_nan(self): ma = Masked([3., np.nan, 2.], mask=[False, True, False]) ma_min = ma.min() assert_array_equal(ma_min.unmasked, np.array(2.)) assert not ma_min.mask @pytest.mark.parametrize('axis', (0, 1, None)) def test_max(self, axis): ma_max = self.ma.max(axis) filled = self.a.copy() filled[self.mask_a] = self.a.min() expected_data = filled.max(axis) assert_array_equal(ma_max.unmasked, expected_data) assert not np.any(ma_max.mask) @pytest.mark.parametrize('axis', (0, 1, None)) def test_argmin(self, axis): ma_argmin = self.ma.argmin(axis) filled = self.a.copy() filled[self.mask_a] = self.a.max() expected_data = filled.argmin(axis) assert_array_equal(ma_argmin, expected_data) def test_argmin_only_one_unmasked_element(self): # Regression test for example from @taldcroft at # https://github.com/astropy/astropy/pull/11127#discussion_r600864559 ma = Masked(data=[1, 2], mask=[True, False]) assert ma.argmin() == 1 @pytest.mark.parametrize('axis', (0, 1, None)) def test_argmax(self, axis): ma_argmax = self.ma.argmax(axis) filled = self.a.copy() filled[self.mask_a] = self.a.min() expected_data = filled.argmax(axis) assert_array_equal(ma_argmax, expected_data) @pytest.mark.parametrize('axis', (0, 1, None)) def test_argsort(self, axis): ma_argsort = self.ma.argsort(axis) filled = self.a.copy() filled[self.mask_a] = self.a.max() * 1.1 expected_data = filled.argsort(axis) assert_array_equal(ma_argsort, expected_data) @pytest.mark.parametrize('order', [None, 'a', ('a', 'b'), ('b', 'a')]) @pytest.mark.parametrize('axis', [0, 1]) def test_structured_argsort(self, axis, order): ma_argsort = self.msa.argsort(axis, order=order) filled = self.msa.filled(fill_value=np.array((np.inf, np.inf), dtype=self.sdt)) expected_data = filled.argsort(axis, order=order) assert_array_equal(ma_argsort, expected_data) def test_argsort_error(self): with pytest.raises(ValueError, match='when the array has no fields'): self.ma.argsort(axis=0, order='a') @pytest.mark.parametrize('axis', (0, 1)) def test_sort(self, axis): ma_sort = self.ma.copy() ma_sort.sort(axis) indices = self.ma.argsort(axis) expected_data = np.take_along_axis(self.ma.unmasked, indices, axis) expected_mask = np.take_along_axis(self.ma.mask, indices, axis) assert_array_equal(ma_sort.unmasked, expected_data) assert_array_equal(ma_sort.mask, expected_mask) @pytest.mark.parametrize('kth', [1, 3]) def test_argpartition(self, kth): ma = self.ma.ravel() ma_argpartition = ma.argpartition(kth) partitioned = ma[ma_argpartition] assert (partitioned[:kth] < partitioned[kth]).all() assert (partitioned[kth:] >= partitioned[kth]).all() if partitioned[kth].mask: assert all(partitioned.mask[kth:]) else: assert not any(partitioned.mask[:kth]) @pytest.mark.parametrize('kth', [1, 3]) def test_partition(self, kth): partitioned = self.ma.flatten() partitioned.partition(kth) assert (partitioned[:kth] < partitioned[kth]).all() assert (partitioned[kth:] >= partitioned[kth]).all() if partitioned[kth].mask: assert all(partitioned.mask[kth:]) else: assert not any(partitioned.mask[:kth]) def test_all_explicit(self): a1 = np.array([[1., 2.], [3., 4.]]) a2 = np.array([[1., 0.], [3., 4.]]) if self._data_cls is not np.ndarray: a1 = self._data_cls(a1, self.a.unit) a2 = self._data_cls(a2, self.a.unit) ma1 = Masked(a1, mask=[[False, False], [True, True]]) ma2 = Masked(a2, mask=[[False, True], [False, True]]) ma1_eq_ma2 = ma1 == ma2 assert_array_equal(ma1_eq_ma2.unmasked, np.array([[True, False], [True, True]])) assert_array_equal(ma1_eq_ma2.mask, np.array([[False, True], [True, True]])) assert ma1_eq_ma2.all() assert not (ma1 != ma2).all() ma_eq1 = ma1_eq_ma2.all(1) assert_array_equal(ma_eq1.mask, np.array([False, True])) assert bool(ma_eq1[0]) is True assert bool(ma_eq1[1]) is False ma_eq0 = ma1_eq_ma2.all(0) assert_array_equal(ma_eq0.mask, np.array([False, True])) assert bool(ma_eq1[0]) is True assert bool(ma_eq1[1]) is False @pytest.mark.parametrize('method', ['any', 'all']) @pytest.mark.parametrize('array,axis', [ ('a', 0), ('a', 1), ('a', None), ('b', None), ('c', 0), ('c', 1), ('c', None)]) def test_all_and_any(self, array, axis, method): ma = getattr(self, 'm'+array) ma_eq = ma == ma ma_all_or_any = getattr(ma_eq, method)(axis=axis) filled = ma_eq.unmasked.copy() filled[ma_eq.mask] = method == 'all' a_all_or_any = getattr(filled, method)(axis=axis) all_masked = ma.mask.all(axis) assert_array_equal(ma_all_or_any.mask, all_masked) assert_array_equal(ma_all_or_any.unmasked, a_all_or_any) # interpretation as bool as_bool = [bool(a) for a in ma_all_or_any.ravel()] expected = [bool(a) for a in (a_all_or_any & ~all_masked).ravel()] assert as_bool == expected def test_any_inplace(self): ma_eq = self.ma == self.ma expected = ma_eq.any(1) out = Masked(np.zeros_like(expected.unmasked)) result = ma_eq.any(1, out=out) assert result is out assert_masked_equal(result, expected) @pytest.mark.parametrize('offset', (0, 1)) def test_diagonal(self, offset): mda = self.ma.diagonal(offset=offset) expected = Masked(self.a.diagonal(offset=offset), self.mask_a.diagonal(offset=offset)) assert_masked_equal(mda, expected) @pytest.mark.parametrize('offset', (0, 1)) def test_trace(self, offset): mta = self.ma.trace(offset=offset) expected = Masked(self.a.trace(offset=offset), self.mask_a.trace(offset=offset, dtype=bool)) assert_masked_equal(mta, expected) def test_clip(self): maclip = self.ma.clip(self.b, self.c) expected = Masked(self.a.clip(self.b, self.c), self.mask_a) assert_masked_equal(maclip, expected) def test_clip_masked_min_max(self): maclip = self.ma.clip(self.mb, self.mc) # Need to be careful with min, max because of Longitude, which wraps. dmax = np.maximum(np.maximum(self.a, self.b), self.c).max() dmin = np.minimum(np.minimum(self.a, self.b), self.c).min() expected = Masked(self.a.clip(self.mb.filled(dmin), self.mc.filled(dmax)), mask=self.mask_a) assert_masked_equal(maclip, expected) class TestMaskedQuantityMethods(TestMaskedArrayMethods, QuantitySetup): pass class TestMaskedLongitudeMethods(TestMaskedArrayMethods, LongitudeSetup): pass class TestMaskedArrayProductMethods(MaskedArraySetup): # These cannot work on Quantity, so done separately @pytest.mark.parametrize('axis', (0, 1, None)) def test_prod(self, axis): ma_sum = self.ma.prod(axis) expected_data = self.a.prod(axis) expected_mask = self.ma.mask.any(axis) assert_array_equal(ma_sum.unmasked, expected_data) assert_array_equal(ma_sum.mask, expected_mask) @pytest.mark.parametrize('axis', (0, 1, None)) def test_cumprod(self, axis): ma_sum = self.ma.cumprod(axis) expected_data = self.a.cumprod(axis) mask = self.mask_a if axis is None: mask = mask.ravel() expected_mask = np.logical_or.accumulate(mask, axis=axis) assert_array_equal(ma_sum.unmasked, expected_data) assert_array_equal(ma_sum.mask, expected_mask) def test_masked_str_explicit(): sa = np.array([(1., 2.), (3., 4.)], dtype='f8,f8') msa = Masked(sa, [(False, True), (False, False)]) assert str(msa) == "[(1., ——) (3., 4.)]" assert str(msa[0]) == "(1., ——)" assert str(msa[1]) == "(3., 4.)" with np.printoptions(precision=3, floatmode='fixed'): assert str(msa) == "[(1.000, ———) (3.000, 4.000)]" def test_masked_repr_explicit(): # Use explicit endianness to ensure tests pass on all architectures sa = np.array([(1., 2.), (3., 4.)], dtype='>f8,>f8') msa = Masked(sa, [(False, True), (False, False)]) assert repr(msa) == ("MaskedNDArray([(1., ——), (3., 4.)], " "dtype=[('f0', '>f8'), ('f1', '>f8')])") assert repr(msa[0]) == ("MaskedNDArray((1., ——), " "dtype=[('f0', '>f8'), ('f1', '>f8')])") assert repr(msa[1]) == ("MaskedNDArray((3., 4.), " "dtype=[('f0', '>f8'), ('f1', '>f8')])") def test_masked_repr_summary(): ma = Masked(np.arange(15.), mask=[True]+[False]*14) with np.printoptions(threshold=2): assert repr(ma) == ( "MaskedNDArray([———, 1., 2., ..., 12., 13., 14.])") def test_masked_repr_nodata(): assert repr(Masked([])) == "MaskedNDArray([], dtype=float64)" class TestMaskedArrayRepr(MaskedArraySetup): def test_array_str(self): # very blunt check they work at all. str(self.ma) str(self.mb) str(self.mc) str(self.msa) str(self.msb) def test_scalar_str(self): assert self.mb[0].shape == () str(self.mb[0]) assert self.msb[0].shape == () str(self.msb[0]) def test_array_repr(self): repr(self.ma) repr(self.mb) repr(self.mc) repr(self.msa) repr(self.msb) def test_scalar_repr(self): repr(self.mb[0]) repr(self.msb[0]) class TestMaskedQuantityRepr(TestMaskedArrayRepr, QuantitySetup): pass class TestMaskedRecarray(MaskedArraySetup): @classmethod def setup_class(self): super().setup_class() self.ra = self.sa.view(np.recarray) self.mra = Masked(self.ra, mask=self.mask_sa) def test_recarray_setup(self): assert isinstance(self.mra, Masked) assert isinstance(self.mra, np.recarray) assert np.all(self.mra.unmasked == self.ra) assert np.all(self.mra.mask == self.mask_sa) assert_array_equal(self.mra.view(np.ndarray), self.sa) assert isinstance(self.mra.a, Masked) assert_array_equal(self.mra.a.unmasked, self.sa['a']) assert_array_equal(self.mra.a.mask, self.mask_sa['a']) def test_recarray_setting(self): mra = self.mra.copy() mra.a = self.msa['b'] assert_array_equal(mra.a.unmasked, self.msa['b'].unmasked) assert_array_equal(mra.a.mask, self.msa['b'].mask) @pytest.mark.parametrize('attr', [0, 'a']) def test_recarray_field_getting(self, attr): mra_a = self.mra.field(attr) assert isinstance(mra_a, Masked) assert_array_equal(mra_a.unmasked, self.sa['a']) assert_array_equal(mra_a.mask, self.mask_sa['a']) @pytest.mark.parametrize('attr', [0, 'a']) def test_recarray_field_setting(self, attr): mra = self.mra.copy() mra.field(attr, self.msa['b']) assert_array_equal(mra.a.unmasked, self.msa['b'].unmasked) assert_array_equal(mra.a.mask, self.msa['b'].mask) class TestMaskedArrayInteractionWithNumpyMA(MaskedArraySetup): def test_masked_array_from_masked(self): """Check that we can initialize a MaskedArray properly.""" np_ma = np.ma.MaskedArray(self.ma) assert type(np_ma) is np.ma.MaskedArray assert type(np_ma.data) is self._data_cls assert type(np_ma.mask) is np.ndarray assert_array_equal(np_ma.data, self.a) assert_array_equal(np_ma.mask, self.mask_a) def test_view_as_masked_array(self): """Test that we can be viewed as a MaskedArray.""" np_ma = self.ma.view(np.ma.MaskedArray) assert type(np_ma) is np.ma.MaskedArray assert type(np_ma.data) is self._data_cls assert type(np_ma.mask) is np.ndarray assert_array_equal(np_ma.data, self.a) assert_array_equal(np_ma.mask, self.mask_a) class TestMaskedQuantityInteractionWithNumpyMA( TestMaskedArrayInteractionWithNumpyMA, QuantitySetup): pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/masked/tests/test_table.py0000644000175100001710000001474200000000000022224 0ustar00vstsdocker# coding: utf-8 # Licensed under a 3-clause BSD style license - see LICENSE.rst import numpy as np from numpy.testing import assert_array_equal import pytest from astropy import units as u from astropy.table import QTable, hstack, vstack, join from astropy.utils.masked import Masked from astropy.utils.compat.optional_deps import HAS_H5PY from .test_masked import assert_masked_equal FILE_FORMATS = ['ecsv', 'fits'] if HAS_H5PY: FILE_FORMATS.append('h5') class MaskedArrayTableSetup: @classmethod def setup_arrays(self): self.a = np.array([3., 5., 0.]) self.mask_a = np.array([True, False, False]) @classmethod def setup_class(self): self.setup_arrays() self.ma = Masked(self.a, mask=self.mask_a) self.ma.info.format = '.1f' self.t = QTable([self.ma], names=['ma']) class MaskedQuantityTableSetup(MaskedArrayTableSetup): @classmethod def setup_arrays(self): self.a = np.array([3., 5., 0.]) << u.m self.mask_a = np.array([True, False, False]) class TestMaskedArrayTable(MaskedArrayTableSetup): def test_table_initialization(self): assert_array_equal(self.t['ma'].unmasked, self.a) assert_array_equal(self.t['ma'].mask, self.mask_a) assert repr(self.t).splitlines()[-3:] == [ ' ———', ' 5.0', ' 0.0'] def test_info_basics(self): assert self.t['ma'].info.name == 'ma' assert 'serialize_method' in self.t['ma'].info.attr_names t2 = self.t.copy() t2['ma'].info.format = '.2f' t2['ma'].info.serialize_method['fits'] = 'nonsense' assert repr(t2).splitlines()[-3:] == [ ' ———', ' 5.00', ' 0.00'] # Check that if we slice, things get copied over correctly. t3 = t2[:2] assert t3['ma'].info.name == 'ma' assert t3['ma'].info.format == '.2f' assert 'serialize_method' in t3['ma'].info.attr_names assert t3['ma'].info.serialize_method['fits'] == 'nonsense' @pytest.mark.parametrize('file_format', FILE_FORMATS) def test_table_write(self, file_format, tmpdir): name = str(tmpdir.join(f"a.{file_format}")) kwargs = {} if file_format == 'h5': kwargs['path'] = 'trial' kwargs['serialize_meta'] = True self.t.write(name, **kwargs) t2 = QTable.read(name) assert isinstance(t2['ma'], self.ma.__class__) assert np.all(t2['ma'] == self.ma) assert np.all(t2['ma'].mask == self.mask_a) if file_format == 'fits': # Imperfect roundtrip through FITS native format description. assert self.t['ma'].info.format in t2['ma'].info.format else: assert t2['ma'].info.format == self.t['ma'].info.format @pytest.mark.parametrize('serialize_method', ['data_mask', 'null_value']) def test_table_write_serialization(self, serialize_method, tmpdir): name = str(tmpdir.join("test.ecsv")) self.t.write(name, serialize_method=serialize_method) with open(name) as fh: lines = fh.readlines() t2 = QTable.read(name) assert isinstance(t2['ma'], self.ma.__class__) if serialize_method == 'data_mask': # Will data_mask, we have data and mask columns and should # exactly round-trip. assert len(lines[-1].split()) == 2 assert_masked_equal(t2['ma'], self.ma) else: # With null_value we have just a data column with null values # marked, so we lost information on the data below the mask. assert len(lines[-1].split()) == 1 assert np.all(t2['ma'] == self.ma) assert np.all(t2['ma'].mask == self.mask_a) def test_non_existing_serialize_method(self, tmpdir): name = str(tmpdir.join('bad.ecsv')) with pytest.raises(ValueError, match='serialize method must be'): self.t.write(name, serialize_method='bad_serialize_method') class TestMaskedQuantityTable(TestMaskedArrayTable, MaskedQuantityTableSetup): # Runs tests from TestMaskedArrayTable as well as some extra ones. def test_table_operations_requiring_masking(self): t1 = self.t t2 = QTable({'ma2': Masked([1, 2] * u.m)}) t12 = hstack([t1, t2], join_type='outer') assert np.all(t12['ma'].mask == [True, False, False]) # 'ma2' is shorter by one so we expect one True from hstack so length matches assert np.all(t12['ma2'].mask == [False, False, True]) t12 = hstack([t1, t2], join_type='inner') assert np.all(t12['ma'].mask == [True, False]) assert np.all(t12['ma2'].mask == [False, False]) # Vstack tables with different column names. In this case we get masked # values t12 = vstack([t1, t2], join_type='outer') # ma ma2 # m m # --- --- # —— —— # 5.0 —— # 0.0 —— # —— 1.0 # —— 2.0 assert np.all(t12['ma'].mask == [True, False, False, True, True]) assert np.all(t12['ma2'].mask == [True, True, True, False, False]) def test_table_operations_requiring_masking_auto_promote(self): MaskedQuantity = Masked(u.Quantity) t1 = QTable({'ma1': [1, 2] * u.m}) t2 = QTable({'ma2': [3, 4, 5] * u.m}) t12 = hstack([t1, t2], join_type='outer') assert isinstance(t12['ma1'], MaskedQuantity) assert np.all(t12['ma1'].mask == [False, False, True]) assert np.all(t12['ma1'] == [1, 2, 0] * u.m) assert not isinstance(t12['ma2'], MaskedQuantity) assert isinstance(t12['ma2'], u.Quantity) assert np.all(t12['ma2'] == [3, 4, 5] * u.m) t12 = hstack([t1, t2], join_type='inner') assert isinstance(t12['ma1'], u.Quantity) assert not isinstance(t12['ma1'], MaskedQuantity) assert isinstance(t12['ma2'], u.Quantity) assert not isinstance(t12['ma2'], MaskedQuantity) # Vstack tables with different column names. In this case we get masked # values t12 = vstack([t1, t2], join_type='outer') assert np.all(t12['ma1'].mask == [False, False, True, True, True]) assert np.all(t12['ma2'].mask == [True, True, False, False, False]) t1['a'] = [1, 2] t2['a'] = [1, 3, 4] t12 = join(t1, t2, join_type='outer') assert np.all(t12['ma1'].mask == [False, False, True, True]) assert np.all(t12['ma2'].mask == [False, True, False, False]) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/metadata.py0000644000175100001710000004344700000000000017254 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This module contains helper functions and classes for handling metadata. """ from functools import wraps import warnings from collections import OrderedDict from collections.abc import Mapping from copy import deepcopy import numpy as np from astropy.utils.exceptions import AstropyWarning from astropy.utils.misc import dtype_bytes_or_chars __all__ = ['MergeConflictError', 'MergeConflictWarning', 'MERGE_STRATEGIES', 'common_dtype', 'MergePlus', 'MergeNpConcatenate', 'MergeStrategy', 'MergeStrategyMeta', 'enable_merge_strategies', 'merge', 'MetaData', 'MetaAttribute'] class MergeConflictError(TypeError): pass class MergeConflictWarning(AstropyWarning): pass MERGE_STRATEGIES = [] def common_dtype(arrs): """ Use numpy to find the common dtype for a list of ndarrays. Only allow arrays within the following fundamental numpy data types: ``np.bool_``, ``np.object_``, ``np.number``, ``np.character``, ``np.void`` Parameters ---------- arrs : list of ndarray Arrays for which to find the common dtype Returns ------- dtype_str : str String representation of dytpe (dtype ``str`` attribute) """ def dtype(arr): return getattr(arr, 'dtype', np.dtype('O')) np_types = (np.bool_, np.object_, np.number, np.character, np.void) uniq_types = set(tuple(issubclass(dtype(arr).type, np_type) for np_type in np_types) for arr in arrs) if len(uniq_types) > 1: # Embed into the exception the actual list of incompatible types. incompat_types = [dtype(arr).name for arr in arrs] tme = MergeConflictError(f'Arrays have incompatible types {incompat_types}') tme._incompat_types = incompat_types raise tme arrs = [np.empty(1, dtype=dtype(arr)) for arr in arrs] # For string-type arrays need to explicitly fill in non-zero # values or the final arr_common = .. step is unpredictable. for i, arr in enumerate(arrs): if arr.dtype.kind in ('S', 'U'): arrs[i] = [('0' if arr.dtype.kind == 'U' else b'0') * dtype_bytes_or_chars(arr.dtype)] arr_common = np.array([arr[0] for arr in arrs]) return arr_common.dtype.str class MergeStrategyMeta(type): """ Metaclass that registers MergeStrategy subclasses into the MERGE_STRATEGIES registry. """ def __new__(mcls, name, bases, members): cls = super().__new__(mcls, name, bases, members) # Wrap ``merge`` classmethod to catch any exception and re-raise as # MergeConflictError. if 'merge' in members and isinstance(members['merge'], classmethod): orig_merge = members['merge'].__func__ @wraps(orig_merge) def merge(cls, left, right): try: return orig_merge(cls, left, right) except Exception as err: raise MergeConflictError(err) cls.merge = classmethod(merge) # Register merging class (except for base MergeStrategy class) if 'types' in members: types = members['types'] if isinstance(types, tuple): types = [types] for left, right in reversed(types): MERGE_STRATEGIES.insert(0, (left, right, cls)) return cls class MergeStrategy(metaclass=MergeStrategyMeta): """ Base class for defining a strategy for merging metadata from two sources, left and right, into a single output. The primary functionality for the class is the ``merge(cls, left, right)`` class method. This takes ``left`` and ``right`` side arguments and returns a single merged output. The first class attribute is ``types``. This is defined as a list of (left_types, right_types) tuples that indicate for which input types the merge strategy applies. In determining whether to apply this merge strategy to a pair of (left, right) objects, a test is done: ``isinstance(left, left_types) and isinstance(right, right_types)``. For example:: types = [(np.ndarray, np.ndarray), # Two ndarrays (np.ndarray, (list, tuple)), # ndarray and (list or tuple) ((list, tuple), np.ndarray)] # (list or tuple) and ndarray As a convenience, ``types`` can be defined as a single two-tuple instead of a list of two-tuples, e.g. ``types = (np.ndarray, np.ndarray)``. The other class attribute is ``enabled``, which defaults to ``False`` in the base class. By defining a subclass of ``MergeStrategy`` the new merge strategy is automatically registered to be available for use in merging. However, by default the new merge strategy is *not enabled*. This prevents inadvertently changing the behavior of unrelated code that is performing metadata merge operations. In most cases (particularly in library code that others might use) it is recommended to leave custom strategies disabled and use the `~astropy.utils.metadata.enable_merge_strategies` context manager to locally enable the desired strategies. However, if one is confident that the new strategy will not produce unexpected behavior, then one can globally enable it by setting the ``enabled`` class attribute to ``True``. Examples -------- Here we define a custom merge strategy that takes an int or float on the left and right sides and returns a list with the two values. >>> from astropy.utils.metadata import MergeStrategy >>> class MergeNumbersAsList(MergeStrategy): ... types = ((int, float), (int, float)) # (left_types, right_types) ... ... @classmethod ... def merge(cls, left, right): ... return [left, right] """ # Set ``enabled = True`` to globally enable applying this merge strategy. # This is not generally recommended. enabled = False # types = [(left_types, right_types), ...] class MergePlus(MergeStrategy): """ Merge ``left`` and ``right`` objects using the plus operator. This merge strategy is globally enabled by default. """ types = [(list, list), (tuple, tuple)] enabled = True @classmethod def merge(cls, left, right): return left + right class MergeNpConcatenate(MergeStrategy): """ Merge ``left`` and ``right`` objects using np.concatenate. This merge strategy is globally enabled by default. This will upcast a list or tuple to np.ndarray and the output is always ndarray. """ types = [(np.ndarray, np.ndarray), (np.ndarray, (list, tuple)), ((list, tuple), np.ndarray)] enabled = True @classmethod def merge(cls, left, right): left, right = np.asanyarray(left), np.asanyarray(right) common_dtype([left, right]) # Ensure left and right have compatible dtype return np.concatenate([left, right]) def _both_isinstance(left, right, cls): return isinstance(left, cls) and isinstance(right, cls) def _not_equal(left, right): try: return bool(left != right) except Exception: return True class _EnableMergeStrategies: def __init__(self, *merge_strategies): self.merge_strategies = merge_strategies self.orig_enabled = {} for left_type, right_type, merge_strategy in MERGE_STRATEGIES: if issubclass(merge_strategy, merge_strategies): self.orig_enabled[merge_strategy] = merge_strategy.enabled merge_strategy.enabled = True def __enter__(self): pass def __exit__(self, type, value, tb): for merge_strategy, enabled in self.orig_enabled.items(): merge_strategy.enabled = enabled def enable_merge_strategies(*merge_strategies): """ Context manager to temporarily enable one or more custom metadata merge strategies. Examples -------- Here we define a custom merge strategy that takes an int or float on the left and right sides and returns a list with the two values. >>> from astropy.utils.metadata import MergeStrategy >>> class MergeNumbersAsList(MergeStrategy): ... types = ((int, float), # left side types ... (int, float)) # right side types ... @classmethod ... def merge(cls, left, right): ... return [left, right] By defining this class the merge strategy is automatically registered to be available for use in merging. However, by default new merge strategies are *not enabled*. This prevents inadvertently changing the behavior of unrelated code that is performing metadata merge operations. In order to use the new merge strategy, use this context manager as in the following example:: >>> from astropy.table import Table, vstack >>> from astropy.utils.metadata import enable_merge_strategies >>> t1 = Table([[1]], names=['a']) >>> t2 = Table([[2]], names=['a']) >>> t1.meta = {'m': 1} >>> t2.meta = {'m': 2} >>> with enable_merge_strategies(MergeNumbersAsList): ... t12 = vstack([t1, t2]) >>> t12.meta['m'] [1, 2] One can supply further merge strategies as additional arguments to the context manager. As a convenience, the enabling operation is actually done by checking whether the registered strategies are subclasses of the context manager arguments. This means one can define a related set of merge strategies and then enable them all at once by enabling the base class. As a trivial example, *all* registered merge strategies can be enabled with:: >>> with enable_merge_strategies(MergeStrategy): ... t12 = vstack([t1, t2]) Parameters ---------- *merge_strategies : `~astropy.utils.metadata.MergeStrategy` Merge strategies that will be enabled. """ return _EnableMergeStrategies(*merge_strategies) def _warn_str_func(key, left, right): out = ('Cannot merge meta key {0!r} types {1!r}' ' and {2!r}, choosing {0}={3!r}' .format(key, type(left), type(right), right)) return out def _error_str_func(key, left, right): out = f'Cannot merge meta key {key!r} types {type(left)!r} and {type(right)!r}' return out def merge(left, right, merge_func=None, metadata_conflicts='warn', warn_str_func=_warn_str_func, error_str_func=_error_str_func): """ Merge the ``left`` and ``right`` metadata objects. This is a simplistic and limited implementation at this point. """ if not _both_isinstance(left, right, dict): raise MergeConflictError('Can only merge two dict-based objects') out = deepcopy(left) for key, val in right.items(): # If no conflict then insert val into out dict and continue if key not in out: out[key] = deepcopy(val) continue # There is a conflict that must be resolved if _both_isinstance(left[key], right[key], dict): out[key] = merge(left[key], right[key], merge_func, metadata_conflicts=metadata_conflicts) else: try: if merge_func is None: for left_type, right_type, merge_cls in MERGE_STRATEGIES: if not merge_cls.enabled: continue if (isinstance(left[key], left_type) and isinstance(right[key], right_type)): out[key] = merge_cls.merge(left[key], right[key]) break else: raise MergeConflictError else: out[key] = merge_func(left[key], right[key]) except MergeConflictError: # Pick the metadata item that is not None, or they are both not # None, then if they are equal, there is no conflict, and if # they are different, there is a conflict and we pick the one # on the right (or raise an error). if left[key] is None: # This may not seem necessary since out[key] gets set to # right[key], but not all objects support != which is # needed for one of the if clauses. out[key] = right[key] elif right[key] is None: out[key] = left[key] elif _not_equal(left[key], right[key]): if metadata_conflicts == 'warn': warnings.warn(warn_str_func(key, left[key], right[key]), MergeConflictWarning) elif metadata_conflicts == 'error': raise MergeConflictError(error_str_func(key, left[key], right[key])) elif metadata_conflicts != 'silent': raise ValueError('metadata_conflicts argument must be one ' 'of "silent", "warn", or "error"') out[key] = right[key] else: out[key] = right[key] return out class MetaData: """ A descriptor for classes that have a ``meta`` property. This can be set to any valid `~collections.abc.Mapping`. Parameters ---------- doc : `str`, optional Documentation for the attribute of the class. Default is ``""``. .. versionadded:: 1.2 copy : `bool`, optional If ``True`` the the value is deepcopied before setting, otherwise it is saved as reference. Default is ``True``. .. versionadded:: 1.2 """ def __init__(self, doc="", copy=True): self.__doc__ = doc self.copy = copy def __get__(self, instance, owner): if instance is None: return self if not hasattr(instance, '_meta'): instance._meta = OrderedDict() return instance._meta def __set__(self, instance, value): if value is None: instance._meta = OrderedDict() else: if isinstance(value, Mapping): if self.copy: instance._meta = deepcopy(value) else: instance._meta = value else: raise TypeError("meta attribute must be dict-like") class MetaAttribute: """ Descriptor to define custom attribute which gets stored in the object ``meta`` dict and can have a defined default. This descriptor is intended to provide a convenient way to add attributes to a subclass of a complex class such as ``Table`` or ``NDData``. This requires that the object has an attribute ``meta`` which is a dict-like object. The value of the MetaAttribute will be stored in a new dict meta['__attributes__'] that is created when required. Classes that define MetaAttributes are encouraged to support initializing the attributes via the class ``__init__``. For example:: for attr in list(kwargs): descr = getattr(self.__class__, attr, None) if isinstance(descr, MetaAttribute): setattr(self, attr, kwargs.pop(attr)) The name of a ``MetaAttribute`` cannot be the same as any of the following: - Keyword argument in the owner class ``__init__`` - Method or attribute of the "parent class", where the parent class is taken to be ``owner.__mro__[1]``. :param default: default value """ def __init__(self, default=None): self.default = default def __get__(self, instance, owner): # When called without an instance, return self to allow access # to descriptor attributes. if instance is None: return self # If default is None and value has not been set already then return None # without doing touching meta['__attributes__'] at all. This helps e.g. # with the Table._hidden_columns attribute so it doesn't auto-create # meta['__attributes__'] always. if (self.default is None and self.name not in instance.meta.get('__attributes__', {})): return None # Get the __attributes__ dict and create if not there already. attributes = instance.meta.setdefault('__attributes__', {}) try: value = attributes[self.name] except KeyError: if self.default is not None: attributes[self.name] = deepcopy(self.default) # Return either specified default or None value = attributes.get(self.name) return value def __set__(self, instance, value): # Get the __attributes__ dict and create if not there already. attributes = instance.meta.setdefault('__attributes__', {}) attributes[self.name] = value def __delete__(self, instance): # Remove this attribute from meta['__attributes__'] if it exists. if '__attributes__' in instance.meta: attrs = instance.meta['__attributes__'] if self.name in attrs: del attrs[self.name] # If this was the last attribute then remove the meta key as well if not attrs: del instance.meta['__attributes__'] def __set_name__(self, owner, name): import inspect params = [param.name for param in inspect.signature(owner).parameters.values() if param.kind not in (inspect.Parameter.VAR_KEYWORD, inspect.Parameter.VAR_POSITIONAL)] # Reject names from existing params or best guess at parent class if name in params or hasattr(owner.__mro__[1], name): raise ValueError(f'{name} not allowed as {self.__class__.__name__}') self.name = name def __repr__(self): return f'<{self.__class__.__name__} name={self.name} default={self.default}>' ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/misc.py0000644000175100001710000007327000000000000016424 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst """ A "grab bag" of relatively small general-purpose utilities that don't have a clear module/package to live in. """ import abc import contextlib import difflib import inspect import json import os import signal import sys import traceback import unicodedata import locale import threading import re from contextlib import contextmanager from collections import defaultdict, OrderedDict from astropy.utils.decorators import deprecated __all__ = ['isiterable', 'silence', 'format_exception', 'NumpyRNGContext', 'find_api_page', 'is_path_hidden', 'walk_skip_hidden', 'JsonCustomEncoder', 'indent', 'dtype_bytes_or_chars', 'OrderedDescriptor', 'OrderedDescriptorContainer'] # Because they are deprecated. __doctest_skip__ = ['OrderedDescriptor', 'OrderedDescriptorContainer'] NOT_OVERWRITING_MSG = ('File {} already exists. If you mean to replace it ' 'then use the argument "overwrite=True".') # A useful regex for tests. _NOT_OVERWRITING_MSG_MATCH = (r'File .* already exists\. If you mean to ' r'replace it then use the argument ' r'"overwrite=True"\.') def isiterable(obj): """Returns `True` if the given object is iterable.""" try: iter(obj) return True except TypeError: return False def indent(s, shift=1, width=4): """Indent a block of text. The indentation is applied to each line.""" indented = '\n'.join(' ' * (width * shift) + l if l else '' for l in s.splitlines()) if s[-1] == '\n': indented += '\n' return indented class _DummyFile: """A noop writeable object.""" def write(self, s): pass @contextlib.contextmanager def silence(): """A context manager that silences sys.stdout and sys.stderr.""" old_stdout = sys.stdout old_stderr = sys.stderr sys.stdout = _DummyFile() sys.stderr = _DummyFile() yield sys.stdout = old_stdout sys.stderr = old_stderr def format_exception(msg, *args, **kwargs): """ Given an exception message string, uses new-style formatting arguments ``{filename}``, ``{lineno}``, ``{func}`` and/or ``{text}`` to fill in information about the exception that occurred. For example: try: 1/0 except: raise ZeroDivisionError( format_except('A divide by zero occurred in {filename} at ' 'line {lineno} of function {func}.')) Any additional positional or keyword arguments passed to this function are also used to format the message. .. note:: This uses `sys.exc_info` to gather up the information needed to fill in the formatting arguments. Since `sys.exc_info` is not carried outside a handled exception, it's not wise to use this outside of an ``except`` clause - if it is, this will substitute '' for the 4 formatting arguments. """ tb = traceback.extract_tb(sys.exc_info()[2], limit=1) if len(tb) > 0: filename, lineno, func, text = tb[0] else: filename = lineno = func = text = '' return msg.format(*args, filename=filename, lineno=lineno, func=func, text=text, **kwargs) class NumpyRNGContext: """ A context manager (for use with the ``with`` statement) that will seed the numpy random number generator (RNG) to a specific value, and then restore the RNG state back to whatever it was before. This is primarily intended for use in the astropy testing suit, but it may be useful in ensuring reproducibility of Monte Carlo simulations in a science context. Parameters ---------- seed : int The value to use to seed the numpy RNG Examples -------- A typical use case might be:: with NumpyRNGContext(): from numpy import random randarr = random.randn(100) ... run your test using `randarr` ... #Any code using numpy.random at this indent level will act just as it #would have if it had been before the with statement - e.g. whatever #the default seed is. """ def __init__(self, seed): self.seed = seed def __enter__(self): from numpy import random self.startstate = random.get_state() random.seed(self.seed) def __exit__(self, exc_type, exc_value, traceback): from numpy import random random.set_state(self.startstate) def find_api_page(obj, version=None, openinbrowser=True, timeout=None): """ Determines the URL of the API page for the specified object, and optionally open that page in a web browser. .. note:: You must be connected to the internet for this to function even if ``openinbrowser`` is `False`, unless you provide a local version of the documentation to ``version`` (e.g., ``file:///path/to/docs``). Parameters ---------- obj The object to open the docs for or its fully-qualified name (as a str). version : str The doc version - either a version number like '0.1', 'dev' for the development/latest docs, or a URL to point to a specific location that should be the *base* of the documentation. Defaults to latest if you are on aren't on a release, otherwise, the version you are on. openinbrowser : bool If `True`, the `webbrowser` package will be used to open the doc page in a new web browser window. timeout : number, optional The number of seconds to wait before timing-out the query to the astropy documentation. If not given, the default python stdlib timeout will be used. Returns ------- url : str The loaded URL Raises ------ ValueError If the documentation can't be found """ import webbrowser from zlib import decompress from astropy.utils.data import get_readable_fileobj if (not isinstance(obj, str) and hasattr(obj, '__module__') and hasattr(obj, '__name__')): obj = obj.__module__ + '.' + obj.__name__ elif inspect.ismodule(obj): obj = obj.__name__ if version is None: from astropy import version if version.release: version = 'v' + version.version else: version = 'dev' if '://' in version: if version.endswith('index.html'): baseurl = version[:-10] elif version.endswith('/'): baseurl = version else: baseurl = version + '/' elif version == 'dev' or version == 'latest': baseurl = 'http://devdocs.astropy.org/' else: baseurl = f'https://docs.astropy.org/en/{version}/' # Custom request headers; see # https://github.com/astropy/astropy/issues/8990 url = baseurl + 'objects.inv' headers = {'User-Agent': f'Astropy/{version}'} with get_readable_fileobj(url, encoding='binary', remote_timeout=timeout, http_headers=headers) as uf: oiread = uf.read() # need to first read/remove the first four lines, which have info before # the compressed section with the actual object inventory idx = -1 headerlines = [] for _ in range(4): oldidx = idx idx = oiread.index(b'\n', oldidx + 1) headerlines.append(oiread[(oldidx+1):idx].decode('utf-8')) # intersphinx version line, project name, and project version ivers, proj, vers, compr = headerlines if 'The remainder of this file is compressed using zlib' not in compr: raise ValueError('The file downloaded from {} does not seem to be' 'the usual Sphinx objects.inv format. Maybe it ' 'has changed?'.format(baseurl + 'objects.inv')) compressed = oiread[(idx+1):] decompressed = decompress(compressed).decode('utf-8') resurl = None for l in decompressed.strip().splitlines(): ls = l.split() name = ls[0] loc = ls[3] if loc.endswith('$'): loc = loc[:-1] + name if name == obj: resurl = baseurl + loc break if resurl is None: raise ValueError(f'Could not find the docs for the object {obj}') elif openinbrowser: webbrowser.open(resurl) return resurl def signal_number_to_name(signum): """ Given an OS signal number, returns a signal name. If the signal number is unknown, returns ``'UNKNOWN'``. """ # Since these numbers and names are platform specific, we use the # builtin signal module and build a reverse mapping. signal_to_name_map = dict((k, v) for v, k in signal.__dict__.items() if v.startswith('SIG')) return signal_to_name_map.get(signum, 'UNKNOWN') if sys.platform == 'win32': import ctypes def _has_hidden_attribute(filepath): """ Returns True if the given filepath has the hidden attribute on MS-Windows. Based on a post here: https://stackoverflow.com/questions/284115/cross-platform-hidden-file-detection """ if isinstance(filepath, bytes): filepath = filepath.decode(sys.getfilesystemencoding()) try: attrs = ctypes.windll.kernel32.GetFileAttributesW(filepath) result = bool(attrs & 2) and attrs != -1 except AttributeError: result = False return result else: def _has_hidden_attribute(filepath): return False def is_path_hidden(filepath): """ Determines if a given file or directory is hidden. Parameters ---------- filepath : str The path to a file or directory Returns ------- hidden : bool Returns `True` if the file is hidden """ name = os.path.basename(os.path.abspath(filepath)) if isinstance(name, bytes): is_dotted = name.startswith(b'.') else: is_dotted = name.startswith('.') return is_dotted or _has_hidden_attribute(filepath) def walk_skip_hidden(top, onerror=None, followlinks=False): """ A wrapper for `os.walk` that skips hidden files and directories. This function does not have the parameter ``topdown`` from `os.walk`: the directories must always be recursed top-down when using this function. See also -------- os.walk : For a description of the parameters """ for root, dirs, files in os.walk( top, topdown=True, onerror=onerror, followlinks=followlinks): # These lists must be updated in-place so os.walk will skip # hidden directories dirs[:] = [d for d in dirs if not is_path_hidden(d)] files[:] = [f for f in files if not is_path_hidden(f)] yield root, dirs, files class JsonCustomEncoder(json.JSONEncoder): """Support for data types that JSON default encoder does not do. This includes: * Numpy array or number * Complex number * Set * Bytes * astropy.UnitBase * astropy.Quantity Examples -------- >>> import json >>> import numpy as np >>> from astropy.utils.misc import JsonCustomEncoder >>> json.dumps(np.arange(3), cls=JsonCustomEncoder) '[0, 1, 2]' """ def default(self, obj): from astropy import units as u import numpy as np if isinstance(obj, u.Quantity): return dict(value=obj.value, unit=obj.unit.to_string()) if isinstance(obj, (np.number, np.ndarray)): return obj.tolist() elif isinstance(obj, complex): return [obj.real, obj.imag] elif isinstance(obj, set): return list(obj) elif isinstance(obj, bytes): # pragma: py3 return obj.decode() elif isinstance(obj, (u.UnitBase, u.FunctionUnitBase)): if obj == u.dimensionless_unscaled: obj = 'dimensionless_unit' else: return obj.to_string() return json.JSONEncoder.default(self, obj) def strip_accents(s): """ Remove accents from a Unicode string. This helps with matching "ÃĨngstrÃļm" to "angstrom", for example. """ return ''.join( c for c in unicodedata.normalize('NFD', s) if unicodedata.category(c) != 'Mn') def did_you_mean(s, candidates, n=3, cutoff=0.8, fix=None): """ When a string isn't found in a set of candidates, we can be nice to provide a list of alternatives in the exception. This convenience function helps to format that part of the exception. Parameters ---------- s : str candidates : sequence of str or dict of str keys n : int The maximum number of results to include. See `difflib.get_close_matches`. cutoff : float In the range [0, 1]. Possibilities that don't score at least that similar to word are ignored. See `difflib.get_close_matches`. fix : callable A callable to modify the results after matching. It should take a single string and return a sequence of strings containing the fixed matches. Returns ------- message : str Returns the string "Did you mean X, Y, or Z?", or the empty string if no alternatives were found. """ if isinstance(s, str): s = strip_accents(s) s_lower = s.lower() # Create a mapping from the lower case name to all capitalization # variants of that name. candidates_lower = {} for candidate in candidates: candidate_lower = candidate.lower() candidates_lower.setdefault(candidate_lower, []) candidates_lower[candidate_lower].append(candidate) # The heuristic here is to first try "singularizing" the word. If # that doesn't match anything use difflib to find close matches in # original, lower and upper case. if s_lower.endswith('s') and s_lower[:-1] in candidates_lower: matches = [s_lower[:-1]] else: matches = difflib.get_close_matches( s_lower, candidates_lower, n=n, cutoff=cutoff) if len(matches): capitalized_matches = set() for match in matches: capitalized_matches.update(candidates_lower[match]) matches = capitalized_matches if fix is not None: mapped_matches = [] for match in matches: mapped_matches.extend(fix(match)) matches = mapped_matches matches = list(set(matches)) matches = sorted(matches) if len(matches) == 1: matches = matches[0] else: matches = (', '.join(matches[:-1]) + ' or ' + matches[-1]) return f'Did you mean {matches}?' return '' _ordered_descriptor_deprecation_message = """\ The {func} {obj_type} is deprecated and may be removed in a future version. You can replace its functionality with a combination of the __init_subclass__ and __set_name__ magic methods introduced in Python 3.6. See https://github.com/astropy/astropy/issues/11094 for recipes on how to replicate their functionality. """ @deprecated('4.3', _ordered_descriptor_deprecation_message) class OrderedDescriptor(metaclass=abc.ABCMeta): """ Base class for descriptors whose order in the class body should be preserved. Intended for use in concert with the `OrderedDescriptorContainer` metaclass. Subclasses of `OrderedDescriptor` must define a value for a class attribute called ``_class_attribute_``. This is the name of a class attribute on the *container* class for these descriptors, which will be set to an `~collections.OrderedDict` at class creation time. This `~collections.OrderedDict` will contain a mapping of all class attributes that were assigned instances of the `OrderedDescriptor` subclass, to the instances themselves. See the documentation for `OrderedDescriptorContainer` for a concrete example. Optionally, subclasses of `OrderedDescriptor` may define a value for a class attribute called ``_name_attribute_``. This should be the name of an attribute on instances of the subclass. When specified, during creation of a class containing these descriptors, the name attribute on each instance will be set to the name of the class attribute it was assigned to on the class. .. note:: Although this class is intended for use with *descriptors* (i.e. classes that define any of the ``__get__``, ``__set__``, or ``__delete__`` magic methods), this base class is not itself a descriptor, and technically this could be used for classes that are not descriptors too. However, use with descriptors is the original intended purpose. """ # This id increments for each OrderedDescriptor instance created, so they # are always ordered in the order they were created. Class bodies are # guaranteed to be executed from top to bottom. Not sure if this is # thread-safe though. _nextid = 1 @property @abc.abstractmethod def _class_attribute_(self): """ Subclasses should define this attribute to the name of an attribute on classes containing this subclass. That attribute will contain the mapping of all instances of that `OrderedDescriptor` subclass defined in the class body. If the same descriptor needs to be used with different classes, each with different names of this attribute, multiple subclasses will be needed. """ _name_attribute_ = None """ Subclasses may optionally define this attribute to specify the name of an attribute on instances of the class that should be filled with the instance's attribute name at class creation time. """ def __init__(self, *args, **kwargs): # The _nextid attribute is shared across all subclasses so that # different subclasses of OrderedDescriptors can be sorted correctly # between themselves self.__order = OrderedDescriptor._nextid OrderedDescriptor._nextid += 1 super().__init__() def __lt__(self, other): """ Defined for convenient sorting of `OrderedDescriptor` instances, which are defined to sort in their creation order. """ if (isinstance(self, OrderedDescriptor) and isinstance(other, OrderedDescriptor)): try: return self.__order < other.__order except AttributeError: raise RuntimeError( 'Could not determine ordering for {} and {}; at least ' 'one of them is not calling super().__init__ in its ' '__init__.'.format(self, other)) else: return NotImplemented @deprecated('4.3', _ordered_descriptor_deprecation_message) class OrderedDescriptorContainer(type): """ Classes should use this metaclass if they wish to use `OrderedDescriptor` attributes, which are class attributes that "remember" the order in which they were defined in the class body. Every subclass of `OrderedDescriptor` has an attribute called ``_class_attribute_``. For example, if we have .. code:: python class ExampleDecorator(OrderedDescriptor): _class_attribute_ = '_examples_' Then when a class with the `OrderedDescriptorContainer` metaclass is created, it will automatically be assigned a class attribute ``_examples_`` referencing an `~collections.OrderedDict` containing all instances of ``ExampleDecorator`` defined in the class body, mapped to by the names of the attributes they were assigned to. When subclassing a class with this metaclass, the descriptor dict (i.e. ``_examples_`` in the above example) will *not* contain descriptors inherited from the base class. That is, this only works by default with decorators explicitly defined in the class body. However, the subclass *may* define an attribute ``_inherit_decorators_`` which lists `OrderedDescriptor` classes that *should* be added from base classes. See the examples section below for an example of this. Examples -------- >>> from astropy.utils import OrderedDescriptor, OrderedDescriptorContainer >>> class TypedAttribute(OrderedDescriptor): ... \"\"\" ... Attributes that may only be assigned objects of a specific type, ... or subclasses thereof. For some reason we care about their order. ... \"\"\" ... ... _class_attribute_ = 'typed_attributes' ... _name_attribute_ = 'name' ... # A default name so that instances not attached to a class can ... # still be repr'd; useful for debugging ... name = '' ... ... def __init__(self, type): ... # Make sure not to forget to call the super __init__ ... super().__init__() ... self.type = type ... ... def __get__(self, obj, objtype=None): ... if obj is None: ... return self ... if self.name in obj.__dict__: ... return obj.__dict__[self.name] ... else: ... raise AttributeError(self.name) ... ... def __set__(self, obj, value): ... if not isinstance(value, self.type): ... raise ValueError('{0}.{1} must be of type {2!r}'.format( ... obj.__class__.__name__, self.name, self.type)) ... obj.__dict__[self.name] = value ... ... def __delete__(self, obj): ... if self.name in obj.__dict__: ... del obj.__dict__[self.name] ... else: ... raise AttributeError(self.name) ... ... def __repr__(self): ... if isinstance(self.type, tuple) and len(self.type) > 1: ... typestr = '({0})'.format( ... ', '.join(t.__name__ for t in self.type)) ... else: ... typestr = self.type.__name__ ... return '<{0}(name={1}, type={2})>'.format( ... self.__class__.__name__, self.name, typestr) ... Now let's create an example class that uses this ``TypedAttribute``:: >>> class Point2D(metaclass=OrderedDescriptorContainer): ... x = TypedAttribute((float, int)) ... y = TypedAttribute((float, int)) ... ... def __init__(self, x, y): ... self.x, self.y = x, y ... >>> p1 = Point2D(1.0, 2.0) >>> p1.x 1.0 >>> p1.y 2.0 >>> p2 = Point2D('a', 'b') # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... ValueError: Point2D.x must be of type (float, int>) We see that ``TypedAttribute`` works more or less as advertised, but there's nothing special about that. Let's see what `OrderedDescriptorContainer` did for us:: >>> Point2D.typed_attributes OrderedDict([('x', ), ('y', )]) If we create a subclass, it does *not* by default add inherited descriptors to ``typed_attributes``:: >>> class Point3D(Point2D): ... z = TypedAttribute((float, int)) ... >>> Point3D.typed_attributes OrderedDict([('z', )]) However, if we specify ``_inherit_descriptors_`` from ``Point2D`` then it will do so:: >>> class Point3D(Point2D): ... _inherit_descriptors_ = (TypedAttribute,) ... z = TypedAttribute((float, int)) ... >>> Point3D.typed_attributes OrderedDict([('x', ), ('y', ), ('z', )]) .. note:: Hopefully it is clear from these examples that this construction also allows a class of type `OrderedDescriptorContainer` to use multiple different `OrderedDescriptor` classes simultaneously. """ _inherit_descriptors_ = () def __init__(cls, cls_name, bases, members): descriptors = defaultdict(list) seen = set() inherit_descriptors = () descr_bases = {} for mro_cls in cls.__mro__: for name, obj in mro_cls.__dict__.items(): if name in seen: # Checks if we've already seen an attribute of the given # name (if so it will override anything of the same name in # any base class) continue seen.add(name) if (not isinstance(obj, OrderedDescriptor) or (inherit_descriptors and not isinstance(obj, inherit_descriptors))): # The second condition applies when checking any # subclasses, to see if we can inherit any descriptors of # the given type from subclasses (by default inheritance is # disabled unless the class has _inherit_descriptors_ # defined) continue if obj._name_attribute_ is not None: setattr(obj, obj._name_attribute_, name) # Don't just use the descriptor's class directly; instead go # through its MRO and find the class on which _class_attribute_ # is defined directly. This way subclasses of some # OrderedDescriptor *may* override _class_attribute_ and have # its own _class_attribute_, but by default all subclasses of # some OrderedDescriptor are still grouped together # TODO: It might be worth clarifying this in the docs if obj.__class__ not in descr_bases: for obj_cls_base in obj.__class__.__mro__: if '_class_attribute_' in obj_cls_base.__dict__: descr_bases[obj.__class__] = obj_cls_base descriptors[obj_cls_base].append((obj, name)) break else: # Make sure to put obj first for sorting purposes obj_cls_base = descr_bases[obj.__class__] descriptors[obj_cls_base].append((obj, name)) if not getattr(mro_cls, '_inherit_descriptors_', False): # If _inherit_descriptors_ is undefined then we don't inherit # any OrderedDescriptors from any of the base classes, and # there's no reason to continue through the MRO break else: inherit_descriptors = mro_cls._inherit_descriptors_ for descriptor_cls, instances in descriptors.items(): instances.sort() instances = OrderedDict((key, value) for value, key in instances) setattr(cls, descriptor_cls._class_attribute_, instances) super(OrderedDescriptorContainer, cls).__init__(cls_name, bases, members) LOCALE_LOCK = threading.Lock() @contextmanager def _set_locale(name): """ Context manager to temporarily set the locale to ``name``. An example is setting locale to "C" so that the C strtod() function will use "." as the decimal point to enable consistent numerical string parsing. Note that one cannot nest multiple _set_locale() context manager statements as this causes a threading lock. This code taken from https://stackoverflow.com/questions/18593661/how-do-i-strftime-a-date-object-in-a-different-locale. Parameters ========== name : str Locale name, e.g. "C" or "fr_FR". """ name = str(name) with LOCALE_LOCK: saved = locale.setlocale(locale.LC_ALL) if saved == name: # Don't do anything if locale is already the requested locale yield else: try: locale.setlocale(locale.LC_ALL, name) yield finally: locale.setlocale(locale.LC_ALL, saved) set_locale = deprecated('4.0')(_set_locale) set_locale.__doc__ = """Deprecated version of :func:`_set_locale` above. See https://github.com/astropy/astropy/issues/9196 """ def dtype_bytes_or_chars(dtype): """ Parse the number out of a dtype.str value like ' 0 def __getitem__(self, item): try: return self._apply('__getitem__', item) except IndexError: if self.isscalar: raise TypeError('scalar {!r} object is not subscriptable.' .format(self.__class__.__name__)) else: raise def __iter__(self): if self.isscalar: raise TypeError('scalar {!r} object is not iterable.' .format(self.__class__.__name__)) # We cannot just write a generator here, since then the above error # would only be raised once we try to use the iterator, rather than # upon its definition using iter(self). def self_iter(): for idx in range(len(self)): yield self[idx] return self_iter() # Functions that change shape or essentially do indexing. _APPLICABLE_FUNCTIONS = { np.moveaxis, np.rollaxis, np.atleast_1d, np.atleast_2d, np.atleast_3d, np.expand_dims, np.broadcast_to, np.flip, np.fliplr, np.flipud, np.rot90, np.roll, np.delete, } # Functions that themselves defer to a method. Those are all # defined in np.core.fromnumeric, but exclude alen as well as # sort and partition, which make copies before calling the method. _METHOD_FUNCTIONS = {getattr(np, name): {'amax': 'max', 'amin': 'min', 'around': 'round', 'round_': 'round', 'alltrue': 'all', 'sometrue': 'any'}.get(name, name) for name in np.core.fromnumeric.__all__ if name not in ['alen', 'sort', 'partition']} # Add np.copy, which we may as well let defer to our method. _METHOD_FUNCTIONS[np.copy] = 'copy' # Could be made to work with a bit of effort: # np.where, np.compress, np.extract, # np.diag_indices_from, np.triu_indices_from, np.tril_indices_from # np.tile, np.repeat (need .repeat method) # TODO: create a proper implementation. # Furthermore, some arithmetic functions such as np.mean, np.median, # could work for Time, and many more for TimeDelta, so those should # override __array_function__. def __array_function__(self, function, types, args, kwargs): """Wrap numpy functions that make sense.""" if function in self._APPLICABLE_FUNCTIONS: if function is np.broadcast_to: # Ensure that any ndarray subclasses used are # properly propagated. kwargs.setdefault('subok', True) elif (function in {np.atleast_1d, np.atleast_2d, np.atleast_3d} and len(args) > 1): return tuple(function(arg, **kwargs) for arg in args) if self is not args[0]: return NotImplemented return self._apply(function, *args[1:], **kwargs) # For functions that defer to methods, use the corresponding # method/attribute if we have it. Otherwise, fall through. if self is args[0] and function in self._METHOD_FUNCTIONS: method = getattr(self, self._METHOD_FUNCTIONS[function], None) if method is not None: if callable(method): return method(*args[1:], **kwargs) else: # For np.shape, etc., just return the attribute. return method # Fall-back, just pass the arguments on since perhaps the function # works already (see above). return function.__wrapped__(*args, **kwargs) class IncompatibleShapeError(ValueError): def __init__(self, shape_a, shape_a_idx, shape_b, shape_b_idx): super().__init__(shape_a, shape_a_idx, shape_b, shape_b_idx) def check_broadcast(*shapes): """ Determines whether two or more Numpy arrays can be broadcast with each other based on their shape tuple alone. Parameters ---------- *shapes : tuple All shapes to include in the comparison. If only one shape is given it is passed through unmodified. If no shapes are given returns an empty `tuple`. Returns ------- broadcast : `tuple` If all shapes are mutually broadcastable, returns a tuple of the full broadcast shape. """ if len(shapes) == 0: return () elif len(shapes) == 1: return shapes[0] reversed_shapes = (reversed(shape) for shape in shapes) full_shape = [] for dims in zip_longest(*reversed_shapes, fillvalue=1): max_dim = 1 max_dim_idx = None for idx, dim in enumerate(dims): if dim == 1: continue if max_dim == 1: # The first dimension of size greater than 1 max_dim = dim max_dim_idx = idx elif dim != max_dim: raise IncompatibleShapeError( shapes[max_dim_idx], max_dim_idx, shapes[idx], idx) full_shape.append(max_dim) return tuple(full_shape[::-1]) def unbroadcast(array): """ Given an array, return a new array that is the smallest subset of the original array that can be re-broadcasted back to the original array. See https://stackoverflow.com/questions/40845769/un-broadcasting-numpy-arrays for more details. """ if array.ndim == 0: return array array = array[tuple((slice(0, 1) if stride == 0 else slice(None)) for stride in array.strides)] # Remove leading ones, which are not needed in numpy broadcasting. first_not_unity = next((i for (i, s) in enumerate(array.shape) if s > 1), array.ndim) return array.reshape(array.shape[first_not_unity:]) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1952538 astropy-5.0.2/astropy/utils/src/0000755000175100001710000000000000000000000015675 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/src/compiler.c0000644000175100001710000000516500000000000017662 0ustar00vstsdocker#include /*************************************************************************** * Macros for determining the compiler version. * * These are borrowed from boost, and majorly abridged to include only * the compilers we care about. ***************************************************************************/ #define STRINGIZE(X) DO_STRINGIZE(X) #define DO_STRINGIZE(X) #X #if defined __clang__ /* Clang C++ emulates GCC, so it has to appear early. */ # define COMPILER "Clang version " __clang_version__ #elif defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC) /* Intel */ # if defined(__INTEL_COMPILER) # define INTEL_VERSION __INTEL_COMPILER # elif defined(__ICL) # define INTEL_VERSION __ICL # elif defined(__ICC) # define INTEL_VERSION __ICC # elif defined(__ECC) # define INTEL_VERSION __ECC # endif # define COMPILER "Intel C compiler version " STRINGIZE(INTEL_VERSION) #elif defined(__GNUC__) /* gcc */ # define COMPILER "GCC version " __VERSION__ #elif defined(__SUNPRO_CC) /* Sun Workshop Compiler */ # define COMPILER "Sun compiler version " STRINGIZE(__SUNPRO_CC) #elif defined(_MSC_VER) /* Microsoft Visual C/C++ Must be last since other compilers define _MSC_VER for compatibility as well */ # if _MSC_VER < 1200 # define COMPILER_VERSION 5.0 # elif _MSC_VER < 1300 # define COMPILER_VERSION 6.0 # elif _MSC_VER == 1300 # define COMPILER_VERSION 7.0 # elif _MSC_VER == 1310 # define COMPILER_VERSION 7.1 # elif _MSC_VER == 1400 # define COMPILER_VERSION 8.0 # elif _MSC_VER == 1500 # define COMPILER_VERSION 9.0 # elif _MSC_VER == 1600 # define COMPILER_VERSION 10.0 # else # define COMPILER_VERSION _MSC_VER # endif # define COMPILER "Microsoft Visual C++ version " STRINGIZE(COMPILER_VERSION) #else /* Fallback */ # define COMPILER "Unknown compiler" #endif /*************************************************************************** * Module-level ***************************************************************************/ struct module_state { /* The Sun compiler can't handle empty structs */ #if defined(__SUNPRO_C) || defined(_MSC_VER) int _dummy; #endif }; static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, "_compiler", NULL, sizeof(struct module_state), NULL, NULL, NULL, NULL, NULL }; PyMODINIT_FUNC PyInit__compiler(void) { PyObject* m; m = PyModule_Create(&moduledef); if (m == NULL) return NULL; PyModule_AddStringConstant(m, "compiler", COMPILER); return m; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/state.py0000644000175100001710000000415200000000000016602 0ustar00vstsdocker""" A simple class to manage a piece of global science state. See :ref:`astropy:config-developer` for more details. """ __all__ = ['ScienceState'] class ScienceState: """ Science state subclasses are used to manage global items that can affect science results. Subclasses will generally override `validate` to convert from any of the acceptable inputs (such as strings) to the appropriate internal objects, and set an initial value to the ``_value`` member so it has a default. Examples -------- :: class MyState(ScienceState): @classmethod def validate(cls, value): if value not in ('A', 'B', 'C'): raise ValueError("Must be one of A, B, C") return value """ def __init__(self): raise RuntimeError( "This class is a singleton. Do not instantiate.") @classmethod def get(cls): """ Get the current science state value. """ return cls.validate(cls._value) @classmethod def set(cls, value): """ Set the current science state value. """ class _Context: def __init__(self, parent, value): self._value = value self._parent = parent def __enter__(self): pass def __exit__(self, type, value, tb): self._parent._value = self._value def __repr__(self): # Ensure we have a single-line repr, just in case our # value is not something simple like a string. value_repr, lb, _ = repr(self._parent._value).partition('\n') if lb: value_repr += '...' return (f'') ctx = _Context(cls, cls._value) value = cls.validate(value) cls._value = value return ctx @classmethod def validate(cls, value): """ Validate the value and convert it to its native type, if necessary. """ return value ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.1992543 astropy-5.0.2/astropy/utils/tests/0000755000175100001710000000000000000000000016250 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/__init__.py0000644000175100001710000000000000000000000020347 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2112553 astropy-5.0.2/astropy/utils/tests/data/0000755000175100001710000000000000000000000017161 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/data/.hidden_file.txt0000644000175100001710000000004400000000000022230 0ustar00vstsdockerThis is a deliberately hidden file. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/data/alias.cfg0000644000175100001710000000005200000000000020730 0ustar00vstsdocker[cosmology.core] default_cosmology = WMAP7././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2112553 astropy-5.0.2/astropy/utils/tests/data/dataurl/0000755000175100001710000000000000000000000020615 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/data/dataurl/index.html0000644000175100001710000000000000000000000022600 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2112553 astropy-5.0.2/astropy/utils/tests/data/dataurl_mirror/0000755000175100001710000000000000000000000022207 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/data/dataurl_mirror/index.html0000644000175100001710000000000000000000000024172 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/data/local.dat0000644000175100001710000000010500000000000020741 0ustar00vstsdockerThis file is used in the test_local_data_* testing functions CONTENT ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/data/local.dat.bz20000644000175100001710000000014000000000000021434 0ustar00vstsdockerBZh91AY&SYa”fc W€@ „¯åŽ Hj™yCzBx ‰j!i‚ÁÅWÃr,Ī#X–Ë$g á+¨ãqÍL÷OŒ*TÉĀ„ĻĸoÅܑN$e˜Ā././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/data/local.dat.gz0000644000175100001710000000013600000000000021364 0ustar00vstsdocker‹ŒpPlocal.dat ÉČ,VHËĖIUŌĨÅŠ) ™y %Š %ŠÅ%ņ9ųɉ9ņ)‰%‰ņZ`‘Ėŧt…´Ōŧä’Ėüŧb.gŋWŋ.%/+gE././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/data/local.dat.xz0000644000175100001710000000020000000000000021375 0ustar00vstsdockerũ7zXZæÖ´F!t/åŖāDB]* 'd°8sʋ Ņp@BĻ2N™I4ܯš´ŌDx˜wä˙EF•ˇ*—ųęæ˙ē BEO/ŋА÷€’le•ĩîŽÔ^Eîpļķ}YZ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2112553 astropy-5.0.2/astropy/utils/tests/data/test_package/0000755000175100001710000000000000000000000021613 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/data/test_package/__init__.py0000644000175100001710000000020100000000000023715 0ustar00vstsdockerfrom astropy.utils.data import get_pkg_data_filename def get_data_filename(): return get_pkg_data_filename('data/foo.txt') ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2112553 astropy-5.0.2/astropy/utils/tests/data/test_package/data/0000755000175100001710000000000000000000000022524 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/data/test_package/data/foo.txt0000644000175100001710000000000000000000000024036 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/data/unicode.txt0000644000175100001710000000007200000000000021347 0ustar00vstsdocker# -*- coding: utf-8 -*- האסטרונומי פיי×Ēון ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/data/unicode.txt.bz20000644000175100001710000000013100000000000022037 0ustar00vstsdockerBZh91AY&SY:kôÅŲ˛HP Ą†FaäP€ 1@ĐÕSČڃFjxįģ(Uč""$“J*ŅWˆī{ĖjØ4ÎwrE8P:kôÅ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/data/unicode.txt.gz0000644000175100001710000000012600000000000021766 0ustar00vstsdocker‹0gQunicode.txtSVĐÕŌUHÎOÉĖKˇR(-IĶĩ‰p]Ÿr}Âõ…×g\_q}ęõ@<īúL…ëKŽĪÂU@î|.AFØ:././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/data/unicode.txt.xz0000644000175100001710000000016400000000000022011 0ustar00vstsdockerũ7zXZæÖ´F!t/åŖ9# -*- coding: utf-8 -*- האסטרונומי פיי×Ēון ãY+ŦáBl6R:OSnļķ}YZ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/test_codegen.py0000644000175100001710000000245100000000000021267 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import sys import traceback import pytest from astropy.utils.codegen import make_function_with_signature def test_make_function_with_signature_lineno(): """ Tests that a function made with ``make_function_with_signature`` is give the correct line number into the module it was created from (i.e. the line ``make_function_with_signature`` was called from). """ def crashy_function(*args, **kwargs): 1 / 0 # Make a wrapper around this function with the signature: # crashy_function(a, b) # Note: the signature is not really relevant to this test wrapped = make_function_with_signature(crashy_function, ('a', 'b')) line = """ wrapped = make_function_with_signature(crashy_function, ('a', 'b')) """.strip() try: wrapped(1, 2) except Exception: exc_cls, exc, tb = sys.exc_info() assert exc_cls is ZeroDivisionError # The *last* line in the traceback should be the 1 / 0 line in # crashy_function; the next line up should be the line that the # make_function_with_signature call was one tb_lines = traceback.format_tb(tb) assert '1 / 0' in tb_lines[-1] else: pytest.fail('This should have caused an exception') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/test_collections.py0000644000175100001710000000331000000000000022174 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import pytest from astropy.utils import collections def test_homogeneous_list(): l = collections.HomogeneousList(int) with pytest.raises(TypeError): l.append(5.0) def test_homogeneous_list2(): l = collections.HomogeneousList(int) with pytest.raises(TypeError): l.extend([5.0]) def test_homogeneous_list3(): l = collections.HomogeneousList(int) l.append(5) assert l == [5] def test_homogeneous_list4(): l = collections.HomogeneousList(int) l.extend([5]) assert l == [5] def test_homogeneous_list5(): l = collections.HomogeneousList(int, [1, 2, 3]) with pytest.raises(TypeError): l[1] = 5.0 def test_homogeneous_list_setitem_works(): l = collections.HomogeneousList(int, [1, 2, 3]) l[1] = 5 assert l == [1, 5, 3] def test_homogeneous_list_setitem_works_with_slice(): l = collections.HomogeneousList(int, [1, 2, 3]) l[0:1] = [10, 20, 30] assert l == [10, 20, 30, 2, 3] l[:] = [5, 4, 3] assert l == [5, 4, 3] l[::2] = [2, 1] assert l == [2, 4, 1] def test_homogeneous_list_init_got_invalid_type(): with pytest.raises(TypeError): collections.HomogeneousList(int, [1, 2., 3]) def test_homogeneous_list_works_with_generators(): hl = collections.HomogeneousList(int, (i for i in range(3))) assert hl == [0, 1, 2] hl = collections.HomogeneousList(int) hl.extend(i for i in range(3)) assert hl == [0, 1, 2] hl = collections.HomogeneousList(int) hl[0:1] = (i for i in range(3)) assert hl == [0, 1, 2] hl = collections.HomogeneousList(int) hl += (i for i in range(3)) assert hl == [0, 1, 2] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/test_console.py0000644000175100001710000001227400000000000021331 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst # -*- coding: utf-8 -*- import io import pytest from . import test_progress_bar_func from astropy.utils import console from astropy import units as u class FakeTTY(io.StringIO): """IOStream that fakes a TTY; provide an encoding to emulate an output stream with a specific encoding. """ def __new__(cls, encoding=None): # Return a new subclass of FakeTTY with the requested encoding if encoding is None: return super().__new__(cls) encoding = encoding cls = type(encoding.title() + cls.__name__, (cls,), {'encoding': encoding}) return cls.__new__(cls) def __init__(self, encoding=None): super().__init__() def write(self, s): if isinstance(s, bytes): # Just allow this case to work s = s.decode('latin-1') elif self.encoding is not None: s.encode(self.encoding) return super().write(s) def isatty(self): return True def test_fake_tty(): # First test without a specified encoding; we should be able to write # arbitrary unicode strings f1 = FakeTTY() assert f1.isatty() f1.write('☃') assert f1.getvalue() == '☃' # Now test an ASCII-only TTY--it should raise a UnicodeEncodeError when # trying to write a string containing non-ASCII characters f2 = FakeTTY('ascii') assert f2.isatty() assert f2.__class__.__name__ == 'AsciiFakeTTY' assert pytest.raises(UnicodeEncodeError, f2.write, '☃') assert f2.getvalue() == '' @pytest.mark.skipif("sys.platform.startswith('win')") def test_color_text(): assert console._color_text("foo", "green") == '\033[0;32mfoo\033[0m' def test_color_print(): # This stuff is hard to test, at least smoke test it console.color_print("foo", "green") console.color_print("foo", "green", "bar", "red") def test_color_print2(): # Test that this automatically detects that io.StringIO is # not a tty stream = io.StringIO() console.color_print("foo", "green", file=stream) assert stream.getvalue() == 'foo\n' stream = io.StringIO() console.color_print("foo", "green", "bar", "red", "baz", file=stream) assert stream.getvalue() == 'foobarbaz\n' @pytest.mark.skipif("sys.platform.startswith('win')") def test_color_print3(): # Test that this thinks the FakeTTY is a tty and applies colors. stream = FakeTTY() console.color_print("foo", "green", file=stream) assert stream.getvalue() == '\x1b[0;32mfoo\x1b[0m\n' stream = FakeTTY() console.color_print("foo", "green", "bar", "red", "baz", file=stream) assert stream.getvalue() == '\x1b[0;32mfoo\x1b[0m\x1b[0;31mbar\x1b[0mbaz\n' def test_color_print_unicode(): console.color_print("ÃŧberbÃĻr", "red") def test_color_print_invalid_color(): console.color_print("foo", "unknown") def test_spinner_non_unicode_console(): """Regression test for #1760 Ensures that the spinner can fall go into fallback mode when using the unicode spinner on a terminal whose default encoding cannot encode the unicode characters. """ stream = FakeTTY('ascii') chars = console.Spinner._default_unicode_chars with console.Spinner("Reticulating splines", file=stream, chars=chars) as s: next(s) def test_progress_bar(): # This stuff is hard to test, at least smoke test it with console.ProgressBar(50) as bar: for i in range(50): bar.update() def test_progress_bar2(): for x in console.ProgressBar(range(50)): pass def test_progress_bar3(): def do_nothing(*args, **kwargs): pass console.ProgressBar.map(do_nothing, range(50)) def test_zero_progress_bar(): with console.ProgressBar(0) as bar: pass def test_progress_bar_as_generator(): sum = 0 for x in console.ProgressBar(range(50)): sum += x assert sum == 1225 sum = 0 for x in console.ProgressBar(50): sum += x assert sum == 1225 def test_progress_bar_map(): items = list(range(100)) result = console.ProgressBar.map(test_progress_bar_func.func, items, step=10, multiprocess=True) assert items == result result1 = console.ProgressBar.map(test_progress_bar_func.func, items, step=10, multiprocess=2) assert items == result1 @pytest.mark.parametrize(("seconds", "string"), [(864088, " 1w 3d"), (187213, " 2d 4h"), (3905, " 1h 5m"), (64, " 1m 4s"), (15, " 15s"), (2, " 2s")] ) def test_human_time(seconds, string): human_time = console.human_time(seconds) assert human_time == string @pytest.mark.parametrize(("size", "string"), [(8640882, "8.6M"), (187213, "187k"), (3905, "3.9k"), (64, " 64 "), (2, " 2 "), (10*u.GB, " 10G")] ) def test_human_file_size(size, string): human_time = console.human_file_size(size) assert human_time == string @pytest.mark.parametrize("size", (50*u.km, 100*u.g)) def test_bad_human_file_size(size): assert pytest.raises(u.UnitConversionError, console.human_file_size, size) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/test_data.py0000644000175100001710000021477700000000000020614 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst import io import os import sys import stat import errno import base64 import random import shutil import hashlib import pathlib import platform import tempfile import warnings import itertools import contextlib import urllib.error import urllib.parse import urllib.request from itertools import islice from concurrent.futures import ThreadPoolExecutor from tempfile import NamedTemporaryFile, TemporaryDirectory import py.path import pytest from astropy import units as _u # u is taken from astropy.config import paths import astropy.utils.data from astropy.utils.exceptions import AstropyWarning from astropy.utils.data import ( CacheMissingWarning, CacheDamaged, conf, _deltemps, compute_hash, download_file, cache_contents, _tempfilestodel, get_cached_urls, is_url_in_cache, cache_total_size, get_file_contents, check_download_cache, clear_download_cache, get_pkg_data_fileobj, get_readable_fileobj, import_file_to_cache, export_download_cache, get_pkg_data_contents, get_pkg_data_filename, import_download_cache, get_free_space_in_dir, check_free_space_in_dir, _get_download_cache_loc, download_files_in_parallel, is_url, get_pkg_data_path ) CI = os.environ.get('CI', False) == "true" TESTURL = "http://www.astropy.org" TESTURL2 = "http://www.astropy.org/about.html" TESTURL_SSL = "https://www.astropy.org" TESTLOCAL = get_pkg_data_filename(os.path.join("data", "local.dat")) # NOTE: Python can be built without bz2 or lzma. from astropy.utils.compat.optional_deps import HAS_BZ2, HAS_LZMA # For when we need "some" test URLs FEW = 5 # For stress testing the locking system using multiprocessing N_PARALLEL_HAMMER = 5 # as high as 500 to replicate a bug # For stress testing the locking system using threads # (cheaper, works with coverage) N_THREAD_HAMMER = 10 # as high as 1000 to replicate a bug def can_rename_directory_in_use(): with TemporaryDirectory() as d: d1 = os.path.join(d, "a") d2 = os.path.join(d, "b") f1 = os.path.join(d1, "file") os.mkdir(d1) with open(f1, "wt") as f: f.write("some contents\n") try: with open(f1, "rt"): os.rename(d1, d2) except PermissionError: return False else: return True CAN_RENAME_DIRECTORY_IN_USE = can_rename_directory_in_use() def url_to(path): return pathlib.Path(path).resolve().as_uri() @pytest.fixture def valid_urls(tmpdir): def _valid_urls(tmpdir): for i in itertools.count(): c = os.urandom(16).hex() fn = os.path.join(tmpdir, "valid_" + str(i)) with open(fn, "w") as f: f.write(c) u = url_to(fn) yield u, c return _valid_urls(tmpdir) @pytest.fixture def invalid_urls(tmpdir): def _invalid_urls(tmpdir): for i in itertools.count(): fn = os.path.join(tmpdir, "invalid_" + str(i)) if not os.path.exists(fn): yield url_to(fn) return _invalid_urls(tmpdir) @pytest.fixture def temp_cache(tmpdir): with paths.set_temp_cache(tmpdir): yield None check_download_cache() def change_tree_permission(d, writable=False): if writable: dirperm = stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR fileperm = stat.S_IRUSR | stat.S_IWUSR else: dirperm = stat.S_IRUSR | stat.S_IXUSR fileperm = stat.S_IRUSR for dirpath, dirnames, filenames in os.walk(d): os.chmod(dirpath, dirperm) for f in filenames: os.chmod(os.path.join(dirpath, f), fileperm) def is_dir_readonly(d): try: with NamedTemporaryFile(dir=d): return False except PermissionError: return True @contextlib.contextmanager def readonly_dir(d): try: change_tree_permission(d, writable=False) yield finally: change_tree_permission(d, writable=True) @pytest.fixture def readonly_cache(tmpdir, valid_urls): with TemporaryDirectory(dir=tmpdir) as d: # other fixtures use the same tmpdir so we need a subdirectory # to make into the cache d = pathlib.Path(d) with paths.set_temp_cache(d): us = set(u for u, c in islice(valid_urls, FEW)) urls = {u: download_file(u, cache=True) for u in us} files = set(d.iterdir()) with readonly_dir(d): if not is_dir_readonly(d): pytest.skip("Unable to make directory readonly") yield urls assert set(d.iterdir()) == files check_download_cache() @pytest.fixture def fake_readonly_cache(tmpdir, valid_urls, monkeypatch): def no_mkdir(path, mode=None): raise OSError(errno.EPERM, "os.mkdir monkeypatched out") def no_mkdtemp(*args, **kwargs): """On Windows, mkdtemp uses mkdir in a loop and therefore hangs with it monkeypatched out. """ raise OSError(errno.EPERM, "os.mkdtemp monkeypatched out") def no_TemporaryDirectory(*args, **kwargs): raise OSError(errno.EPERM, "_SafeTemporaryDirectory monkeypatched out") with TemporaryDirectory(dir=tmpdir) as d: # other fixtures use the same tmpdir so we need a subdirectory # to make into the cache d = pathlib.Path(d) with paths.set_temp_cache(d): us = set(u for u, c in islice(valid_urls, FEW)) urls = {u: download_file(u, cache=True) for u in us} files = set(d.iterdir()) monkeypatch.setattr(os, "mkdir", no_mkdir) monkeypatch.setattr(tempfile, "mkdtemp", no_mkdtemp) monkeypatch.setattr(astropy.utils.data, "_SafeTemporaryDirectory", no_TemporaryDirectory) yield urls assert set(d.iterdir()) == files check_download_cache() def test_download_file_basic(valid_urls, temp_cache): u, c = next(valid_urls) assert get_file_contents(download_file(u, cache=False)) == c assert not is_url_in_cache(u) assert get_file_contents(download_file(u, cache=True)) == c # Cache miss assert is_url_in_cache(u) assert get_file_contents(download_file(u, cache=True)) == c # Cache hit assert get_file_contents(download_file(u, cache=True, sources=[])) == c def test_download_file_absolute_path(valid_urls, temp_cache): def is_abs(p): return p == os.path.abspath(p) u, c = next(valid_urls) assert is_abs(download_file(u, cache=False)) # no cache assert is_abs(download_file(u, cache=True)) # not in cache assert is_abs(download_file(u, cache=True)) # in cache for k, v in cache_contents().items(): assert is_abs(v) def test_unicode_url(valid_urls, temp_cache): u, c = next(valid_urls) unicode_url = "http://Ê—☃—è.com" download_file(unicode_url, cache=False, sources=[u]) download_file(unicode_url, cache=True, sources=[u]) download_file(unicode_url, cache=True, sources=[]) assert is_url_in_cache(unicode_url) assert unicode_url in cache_contents() def test_too_long_url(valid_urls, temp_cache): u, c = next(valid_urls) long_url = "http://"+"a"*256+".com" download_file(long_url, cache=False, sources=[u]) download_file(long_url, cache=True, sources=[u]) download_file(long_url, cache=True, sources=[]) def test_case_collision(valid_urls, temp_cache): u, c = next(valid_urls) u2, c2 = next(valid_urls) f1 = download_file("http://example.com/thing", cache=True, sources=[u]) f2 = download_file("http://example.com/THING", cache=True, sources=[u2]) assert f1 != f2 assert get_file_contents(f1) != get_file_contents(f2) def test_domain_name_case(valid_urls, temp_cache): u, c = next(valid_urls) download_file("http://Example.com/thing", cache=True, sources=[u]) assert is_url_in_cache("http://EXAMPLE.com/thing") download_file("http://EXAMPLE.com/thing", cache=True, sources=[]) assert is_url_in_cache("Http://example.com/thing") download_file("Http://example.com/thing", cache=True, sources=[]) @pytest.mark.remote_data(source="astropy") def test_download_nocache_from_internet(): fnout = download_file(TESTURL, cache=False) assert os.path.isfile(fnout) @pytest.fixture def a_binary_file(tmp_path): fn = tmp_path / "file" b_contents = b"\xde\xad\xbe\xef" with open(fn, "wb") as f: f.write(b_contents) yield fn, b_contents @pytest.fixture def a_file(tmp_path): fn = tmp_path / "file.txt" contents = "contents\n" with open(fn, "w") as f: f.write(contents) yield fn, contents def test_temp_cache(tmpdir): dldir0 = _get_download_cache_loc() check_download_cache() with paths.set_temp_cache(tmpdir): dldir1 = _get_download_cache_loc() check_download_cache() assert dldir1 != dldir0 dldir2 = _get_download_cache_loc() check_download_cache() assert dldir2 != dldir1 assert dldir2 == dldir0 # Check that things are okay even if we exit via an exception class Special(Exception): pass try: with paths.set_temp_cache(tmpdir): dldir3 = _get_download_cache_loc() check_download_cache() assert dldir3 == dldir1 raise Special except Special: pass dldir4 = _get_download_cache_loc() check_download_cache() assert dldir4 != dldir3 assert dldir4 == dldir0 @pytest.mark.parametrize("parallel", [False, True]) def test_download_with_sources_and_bogus_original( valid_urls, invalid_urls, temp_cache, parallel): # This is a combined test because the parallel version triggered a nasty # bug and I was trying to track it down by comparing with the non-parallel # version. I think the bug was that the parallel downloader didn't respect # temporary cache settings. # Make a big list of test URLs u, c = next(valid_urls) # as tuples (URL, right_content, wrong_content) urls = [(u, c, None)] # where to download the contents sources = {} # Set up some URLs to download where the "true" URL is not in the sources # list; make the true URL valid with different contents so we can tell if # it was loaded by mistake. for i, (um, c_bad) in enumerate(islice(valid_urls, FEW)): assert not is_url_in_cache(um) sources[um] = [] # For many of them the sources list starts with invalid URLs for iu in islice(invalid_urls, i): sources[um].append(iu) u, c = next(valid_urls) sources[um].append(u) urls.append((um, c, c_bad)) # Now fetch them all if parallel: rs = download_files_in_parallel([u for (u, c, c_bad) in urls], cache=True, sources=sources) else: rs = [ download_file(u, cache=True, sources=sources.get(u, None)) for (u, c, c_bad) in urls ] assert len(rs) == len(urls) for r, (u, c, c_bad) in zip(rs, urls): assert get_file_contents(r) == c assert get_file_contents(r) != c_bad assert is_url_in_cache(u) @pytest.mark.skipif((sys.platform.startswith('win') and CI), reason="flaky cache error on Windows CI") def test_download_file_threaded_many(temp_cache, valid_urls): """Hammer download_file with multiple threaded requests. The goal is to stress-test the locking system. Normal parallel downloading also does this but coverage tools lose track of which paths are explored. """ urls = list(islice(valid_urls, N_THREAD_HAMMER)) with ThreadPoolExecutor(max_workers=len(urls)) as P: r = list(P.map(lambda u: download_file(u, cache=True), [u for (u, c) in urls])) check_download_cache() assert len(r) == len(urls) for r, (u, c) in zip(r, urls): assert get_file_contents(r) == c @pytest.mark.skipif((sys.platform.startswith('win') and CI), reason="flaky cache error on Windows CI") def test_threaded_segfault(valid_urls): """Demonstrate urllib's segfault.""" def slurp_url(u): with urllib.request.urlopen(u) as remote: block = True while block: block = remote.read(1024) urls = list(islice(valid_urls, N_THREAD_HAMMER)) with ThreadPoolExecutor(max_workers=len(urls)) as P: list(P.map(lambda u: slurp_url(u), [u for (u, c) in urls])) @pytest.mark.skipif((sys.platform.startswith('win') and CI), reason="flaky cache error on Windows CI") def test_download_file_threaded_many_partial_success( temp_cache, valid_urls, invalid_urls): """Hammer download_file with multiple threaded requests. Because some of these requests fail, the locking context manager is exercised with exceptions as well as success returns. I do not expect many surprises from the threaded version, but the process version gave trouble here. """ urls = [] contents = {} for (u, c), i in islice(zip(valid_urls, invalid_urls), N_THREAD_HAMMER): urls.append(u) contents[u] = c urls.append(i) def get(u): try: return download_file(u, cache=True) except OSError: return None with ThreadPoolExecutor(max_workers=len(urls)) as P: r = list(P.map(get, urls)) check_download_cache() assert len(r) == len(urls) for r, u in zip(r, urls): if u in contents: assert get_file_contents(r) == contents[u] else: assert r is None def test_clear_download_cache(valid_urls): u1, c1 = next(valid_urls) download_file(u1, cache=True) u2, c2 = next(valid_urls) download_file(u2, cache=True) assert is_url_in_cache(u2) clear_download_cache(u2) assert not is_url_in_cache(u2) assert is_url_in_cache(u1) u3, c3 = next(valid_urls) f3 = download_file(u3, cache=True) assert is_url_in_cache(u3) clear_download_cache(f3) assert not is_url_in_cache(u3) assert is_url_in_cache(u1) u4, c4 = next(valid_urls) f4 = download_file(u4, cache=True) assert is_url_in_cache(u4) clear_download_cache(compute_hash(f4)) assert not is_url_in_cache(u4) assert is_url_in_cache(u1) def test_clear_download_multiple_references_doesnt_corrupt_storage(temp_cache, tmpdir): """Check that files with the same hash don't confuse the storage.""" content = "Test data; doesn't matter much.\n" def make_url(): with NamedTemporaryFile("w", dir=str(tmpdir), delete=False) as f: f.write(content) url = url_to(f.name) clear_download_cache(url) filename = download_file(url, cache=True) return url, filename a_url, a_filename = make_url() clear_download_cache(a_filename) assert not is_url_in_cache(a_url) f_url, f_filename = make_url() g_url, g_filename = make_url() assert f_url != g_url assert is_url_in_cache(f_url) assert is_url_in_cache(g_url) clear_download_cache(f_url) assert not is_url_in_cache(f_url) assert is_url_in_cache(g_url) assert os.path.exists( g_filename ), "Contents should not be deleted while a reference exists" clear_download_cache(g_url) assert not os.path.exists( g_filename ), "No reference exists any more, file should be deleted" @pytest.mark.parametrize("use_cache", [False, True]) def test_download_file_local_cache_survives(tmpdir, temp_cache, use_cache): """Confirm that downloading a local file does not delete it. When implemented with urlretrieve (rather than urlopen) local files are not copied to create temporaries, so importing them to the cache deleted the original from wherever it was in the filesystem. I lost some built-in astropy data. """ fn = tmpdir / "file" contents = "some text" with open(fn, "w") as f: f.write(contents) u = url_to(fn) f = download_file(u, cache=use_cache) assert fn not in _tempfilestodel, "File should not be deleted!" assert os.path.isfile(fn), "File should not be deleted!" assert get_file_contents(f) == contents def test_sources_normal(temp_cache, valid_urls, invalid_urls): primary, contents = next(valid_urls) fallback1 = next(invalid_urls) f = download_file(primary, cache=True, sources=[primary, fallback1]) assert get_file_contents(f) == contents assert is_url_in_cache(primary) assert not is_url_in_cache(fallback1) def test_sources_fallback(temp_cache, valid_urls, invalid_urls): primary = next(invalid_urls) fallback1, contents = next(valid_urls) f = download_file(primary, cache=True, sources=[primary, fallback1]) assert get_file_contents(f) == contents assert is_url_in_cache(primary) assert not is_url_in_cache(fallback1) def test_sources_ignore_primary(temp_cache, valid_urls, invalid_urls): primary, bogus = next(valid_urls) fallback1, contents = next(valid_urls) f = download_file(primary, cache=True, sources=[fallback1]) assert get_file_contents(f) == contents assert is_url_in_cache(primary) assert not is_url_in_cache(fallback1) def test_sources_multiple(temp_cache, valid_urls, invalid_urls): primary = next(invalid_urls) fallback1 = next(invalid_urls) fallback2, contents = next(valid_urls) f = download_file(primary, cache=True, sources=[primary, fallback1, fallback2]) assert get_file_contents(f) == contents assert is_url_in_cache(primary) assert not is_url_in_cache(fallback1) assert not is_url_in_cache(fallback2) def test_sources_multiple_missing(temp_cache, valid_urls, invalid_urls): primary = next(invalid_urls) fallback1 = next(invalid_urls) fallback2 = next(invalid_urls) with pytest.raises(urllib.error.URLError): download_file(primary, cache=True, sources=[primary, fallback1, fallback2]) assert not is_url_in_cache(primary) assert not is_url_in_cache(fallback1) assert not is_url_in_cache(fallback2) def test_update_url(tmpdir, temp_cache): with TemporaryDirectory(dir=tmpdir) as d: f_name = os.path.join(d, "f") with open(f_name, "w") as f: f.write("old") f_url = url_to(f.name) assert get_file_contents(download_file(f_url, cache=True)) == "old" with open(f_name, "w") as f: f.write("new") assert get_file_contents(download_file(f_url, cache=True)) == "old" assert get_file_contents(download_file(f_url, cache="update")) == "new" # Now the URL doesn't exist any more. assert not os.path.exists(f_name) with pytest.raises(urllib.error.URLError): # Direct download should fail download_file(f_url, cache=False) assert get_file_contents(download_file(f_url, cache=True)) == "new", \ "Cached version should still exist" with pytest.raises(urllib.error.URLError): # cannot download new version to check for updates download_file(f_url, cache="update") assert get_file_contents(download_file(f_url, cache=True)) == "new", \ "Failed update should not remove the current version" @pytest.mark.remote_data(source="astropy") def test_download_noprogress(): fnout = download_file(TESTURL, cache=False, show_progress=False) assert os.path.isfile(fnout) @pytest.mark.remote_data(source="astropy") def test_download_cache(): download_dir = _get_download_cache_loc() # Download the test URL and make sure it exists, then clear just that # URL and make sure it got deleted. fnout = download_file(TESTURL, cache=True) assert os.path.isdir(download_dir) assert os.path.isfile(fnout) clear_download_cache(TESTURL) assert not os.path.exists(fnout) # Clearing download cache succeeds even if the URL does not exist. clear_download_cache("http://this_was_never_downloaded_before.com") # Make sure lockdir was released lockdir = os.path.join(download_dir, "lock") assert not os.path.isdir(lockdir), "Cache dir lock was not released!" @pytest.mark.remote_data(source="astropy") def test_download_certificate_verification_failed(): """Tests for https://github.com/astropy/astropy/pull/10434""" # First test the expected exception when download fails due to a # certificate verification error; we simulate this by passing a bogus # CA directory to the ssl_context argument ssl_context = {'cafile': None, 'capath': '/does/not/exist'} msg = f'Verification of TLS/SSL certificate at {TESTURL_SSL} failed' with pytest.raises(urllib.error.URLError, match=msg): download_file(TESTURL_SSL, cache=False, ssl_context=ssl_context) with pytest.warns(AstropyWarning, match=msg) as warning_lines: fnout = download_file(TESTURL_SSL, cache=False, ssl_context=ssl_context, allow_insecure=True) assert len(warning_lines) == 1 assert os.path.isfile(fnout) def test_download_cache_after_clear(tmpdir, temp_cache, valid_urls): testurl, contents = next(valid_urls) # Test issues raised in #4427 with clear_download_cache() without a URL, # followed by subsequent download. download_dir = _get_download_cache_loc() fnout = download_file(testurl, cache=True) assert os.path.isfile(fnout) clear_download_cache() assert not os.path.exists(fnout) assert not os.path.exists(download_dir) fnout = download_file(testurl, cache=True) assert os.path.isfile(fnout) @pytest.mark.remote_data(source="astropy") def test_download_parallel_from_internet_works(temp_cache): main_url = conf.dataurl mirror_url = conf.dataurl_mirror fileloc = "intersphinx/README" urls = [] sources = {} for s in ["", fileloc]: urls.append(main_url + s) sources[urls[-1]] = [urls[-1], mirror_url+s] fnout = download_files_in_parallel(urls, sources=sources) assert all([os.path.isfile(f) for f in fnout]), fnout @pytest.mark.parametrize("method", [None, "spawn"]) def test_download_parallel_fills_cache(tmpdir, valid_urls, method): urls = [] # tmpdir is shared between many tests, and that can cause weird # interactions if we set the temporary cache too directly with paths.set_temp_cache(tmpdir): for um, c in islice(valid_urls, FEW): assert not is_url_in_cache(um) urls.append((um, c)) rs = download_files_in_parallel( [u for (u, c) in urls], multiprocessing_start_method=method ) assert len(rs) == len(urls) url_set = set(u for (u, c) in urls) assert url_set <= set(get_cached_urls()) for r, (u, c) in zip(rs, urls): assert get_file_contents(r) == c check_download_cache() assert not url_set.intersection(get_cached_urls()) check_download_cache() def test_download_parallel_with_empty_sources(valid_urls, temp_cache): urls = [] sources = {} for um, c in islice(valid_urls, FEW): assert not is_url_in_cache(um) urls.append((um, c)) rs = download_files_in_parallel([u for (u, c) in urls], sources=sources) assert len(rs) == len(urls) # u = set(u for (u, c) in urls) # assert u <= set(get_cached_urls()) check_download_cache() for r, (u, c) in zip(rs, urls): assert get_file_contents(r) == c def test_download_parallel_with_sources_and_bogus_original( valid_urls, invalid_urls, temp_cache ): u, c = next(valid_urls) urls = [(u, c, None)] sources = {} for i, (um, c_bad) in enumerate(islice(valid_urls, FEW)): assert not is_url_in_cache(um) sources[um] = [] for iu in islice(invalid_urls, i): sources[um].append(iu) u, c = next(valid_urls) sources[um].append(u) urls.append((um, c, c_bad)) rs = download_files_in_parallel([u for (u, c, c_bad) in urls], sources=sources) assert len(rs) == len(urls) # u = set(u for (u, c, c_bad) in urls) # assert u <= set(get_cached_urls()) for r, (u, c, c_bad) in zip(rs, urls): assert get_file_contents(r) == c assert get_file_contents(r) != c_bad def test_download_parallel_many(temp_cache, valid_urls): td = list(islice(valid_urls, N_PARALLEL_HAMMER)) r = download_files_in_parallel([u for (u, c) in td]) assert len(r) == len(td) for r, (u, c) in zip(r, td): assert get_file_contents(r) == c def test_download_parallel_partial_success(temp_cache, valid_urls, invalid_urls): """Check that a partially successful download works. Even in the presence of many requested URLs, presumably hitting all the parallelism this system can manage, a download failure leads to a tidy shutdown. """ td = list(islice(valid_urls, N_PARALLEL_HAMMER)) u_bad = next(invalid_urls) with pytest.raises(urllib.request.URLError): download_files_in_parallel([u_bad] + [u for (u, c) in td]) # Actually some files may get downloaded, others not. # Is this good? Should we stubbornly keep trying? # assert not any([is_url_in_cache(u) for (u, c) in td]) def test_download_parallel_partial_success_lock_safe(temp_cache, valid_urls, invalid_urls): """Check that a partially successful parallel download leaves the cache unlocked. This needs to be repeated many times because race conditions are what cause this sort of thing, especially situations where a process might be forcibly shut down while it holds the lock. """ s = random.getstate() try: random.seed(0) for _ in range(N_PARALLEL_HAMMER): td = list(islice(valid_urls, FEW)) u_bad = next(invalid_urls) urls = [u_bad] + [u for (u, c) in td] random.shuffle(urls) with pytest.raises(urllib.request.URLError): download_files_in_parallel(urls) finally: random.setstate(s) def test_download_parallel_update(temp_cache, tmpdir): td = [] for i in range(N_PARALLEL_HAMMER): c = f"{i:04d}" fn = os.path.join(tmpdir, c) with open(fn, "w") as f: f.write(c) u = url_to(fn) clear_download_cache(u) td.append((fn, u, c)) r1 = download_files_in_parallel([u for (fn, u, c) in td]) assert len(r1) == len(td) for r_1, (fn, u, c) in zip(r1, td): assert get_file_contents(r_1) == c td2 = [] for (fn, u, c) in td: c_plus = c + " updated" fn = os.path.join(tmpdir, c) with open(fn, "w") as f: f.write(c_plus) td2.append((fn, u, c, c_plus)) r2 = download_files_in_parallel([u for (fn, u, c) in td], cache=True) assert len(r2) == len(td) for r_2, (fn, u, c, c_plus) in zip(r2, td2): assert get_file_contents(r_2) == c assert c != c_plus r3 = download_files_in_parallel([u for (fn, u, c) in td], cache="update") assert len(r3) == len(td) for r_3, (fn, u, c, c_plus) in zip(r3, td2): assert get_file_contents(r_3) != c assert get_file_contents(r_3) == c_plus @pytest.mark.skipif((sys.platform.startswith('win') and CI), reason="flaky cache error on Windows CI") def test_update_parallel(temp_cache, valid_urls): u, c = next(valid_urls) u2, c2 = next(valid_urls) f = download_file(u, cache=True) assert get_file_contents(f) == c def update(i): return download_file(u, cache="update", sources=[u2]) with ThreadPoolExecutor(max_workers=N_THREAD_HAMMER) as P: r = set(P.map(update, range(N_THREAD_HAMMER))) check_download_cache() for f in r: assert get_file_contents(f) == c2 @pytest.mark.skipif((sys.platform.startswith('win') and CI), reason="flaky cache error on Windows CI") def test_update_parallel_multi(temp_cache, valid_urls): u, c = next(valid_urls) iucs = list(islice(valid_urls, N_THREAD_HAMMER)) f = download_file(u, cache=True) assert get_file_contents(f) == c def update(uc): u2, c2 = uc return download_file(u, cache="update", sources=[u2]), c2 with ThreadPoolExecutor(max_workers=len(iucs)) as P: r = list(P.map(update, iucs)) check_download_cache() assert any(get_file_contents(f) == c for (f, c) in r) @pytest.mark.remote_data(source="astropy") def test_url_nocache(): with get_readable_fileobj(TESTURL, cache=False, encoding="utf-8") as page: assert page.read().find("Astropy") > -1 def test_find_by_hash(valid_urls, temp_cache): testurl, contents = next(valid_urls) p = download_file(testurl, cache=True) hash = compute_hash(p) hashstr = "hash/" + hash fnout = get_pkg_data_filename(hashstr) assert os.path.isfile(fnout) clear_download_cache(fnout) assert not os.path.isfile(fnout) @pytest.mark.remote_data(source="astropy") def test_find_invalid(): # this is of course not a real data file and not on any remote server, but # it should *try* to go to the remote server with pytest.raises(urllib.error.URLError): get_pkg_data_filename( "kjfrhgjklahgiulrhgiuraehgiurhgiuhreglhurieghruelighiuerahiulruli" ) @pytest.mark.parametrize("package", [None, "astropy", "numpy"]) def test_get_invalid(package): """Test can create a file path to an invalid file.""" path = get_pkg_data_path("kjfrhgjkla", "hgiulrhgiu", package=package) assert not os.path.isfile(path) assert not os.path.isdir(path) # Package data functions @pytest.mark.parametrize( ("filename"), ["local.dat", "local.dat.gz", "local.dat.bz2", "local.dat.xz"] ) def test_local_data_obj(filename): if ((not HAS_BZ2 and "bz2" in filename) or (not HAS_LZMA and "xz" in filename)): with pytest.raises(ValueError) as e: with get_pkg_data_fileobj( os.path.join("data", filename), encoding="binary" ) as f: f.readline() # assert f.read().rstrip() == b'CONTENT' assert " format files are not supported" in str(e.value) else: with get_pkg_data_fileobj( os.path.join("data", filename), encoding="binary" ) as f: f.readline() assert f.read().rstrip() == b"CONTENT" @pytest.fixture(params=["invalid.dat.bz2", "invalid.dat.gz"]) def bad_compressed(request, tmpdir): # These contents have valid headers for their respective file formats, but # are otherwise malformed and invalid. bz_content = b"BZhinvalid" gz_content = b"\x1f\x8b\x08invalid" datafile = tmpdir.join(request.param) filename = datafile.strpath if filename.endswith(".bz2"): contents = bz_content elif filename.endswith(".gz"): contents = gz_content else: contents = "invalid" datafile.write(contents, mode="wb") return filename def test_local_data_obj_invalid(bad_compressed): is_bz2 = bad_compressed.endswith(".bz2") is_xz = bad_compressed.endswith(".xz") # Note, since these invalid files are created on the fly in order to avoid # problems with detection by antivirus software # (see https://github.com/astropy/astropy/issues/6520), it is no longer # possible to use ``get_pkg_data_fileobj`` to read the files. Technically, # they're not local anymore: they just live in a temporary directory # created by pytest. However, we can still use get_readable_fileobj for the # test. if (not HAS_BZ2 and is_bz2) or (not HAS_LZMA and is_xz): with pytest.raises(ModuleNotFoundError, match=r'does not provide the [lb]z[2m]a? module\.'): with get_readable_fileobj(bad_compressed, encoding="binary") as f: f.read() else: with get_readable_fileobj(bad_compressed, encoding="binary") as f: assert f.read().rstrip().endswith(b"invalid") def test_local_data_name(): assert os.path.isfile(TESTLOCAL) and TESTLOCAL.endswith("local.dat") # TODO: if in the future, the root data/ directory is added in, the below # test should be uncommented and the README.rst should be replaced with # whatever file is there # get something in the astropy root # fnout2 = get_pkg_data_filename('../../data/README.rst') # assert os.path.isfile(fnout2) and fnout2.endswith('README.rst') def test_data_name_third_party_package(): """Regression test for issue #1256 Tests that `get_pkg_data_filename` works in a third-party package that doesn't make any relative imports from the module it's used from. Uses a test package under ``data/test_package``. """ # Get the actual data dir: data_dir = os.path.join(os.path.dirname(__file__), "data") sys.path.insert(0, data_dir) try: import test_package filename = test_package.get_data_filename() assert os.path.normcase(filename) == ( os.path.normcase(os.path.join(data_dir, "test_package", "data", "foo.txt")) ) finally: sys.path.pop(0) def test_local_data_nonlocalfail(): # this would go *outside* the astropy tree with pytest.raises(RuntimeError): get_pkg_data_filename("../../../data/README.rst") def test_compute_hash(tmpdir): rands = b"1234567890abcdefghijklmnopqrstuvwxyz" filename = tmpdir.join("tmp.dat").strpath with open(filename, "wb") as ntf: ntf.write(rands) ntf.flush() chhash = compute_hash(filename) shash = hashlib.md5(rands).hexdigest() assert chhash == shash def test_get_pkg_data_contents(): with get_pkg_data_fileobj("data/local.dat") as f: contents1 = f.read() contents2 = get_pkg_data_contents("data/local.dat") assert contents1 == contents2 @pytest.mark.remote_data(source="astropy") def test_data_noastropy_fallback(monkeypatch): """ Tests to make sure the default behavior when the cache directory can't be located is correct """ # better yet, set the configuration to make sure the temp files are deleted conf.delete_temporary_downloads_at_exit = True # make sure the config and cache directories are not searched monkeypatch.setenv("XDG_CONFIG_HOME", "foo") monkeypatch.delenv("XDG_CONFIG_HOME") monkeypatch.setenv("XDG_CACHE_HOME", "bar") monkeypatch.delenv("XDG_CACHE_HOME") monkeypatch.setattr(paths.set_temp_config, "_temp_path", None) monkeypatch.setattr(paths.set_temp_cache, "_temp_path", None) # make sure the _find_or_create_astropy_dir function fails as though the # astropy dir could not be accessed def osraiser(dirnm, linkto, pkgname=None): raise OSError() monkeypatch.setattr(paths, '_find_or_create_root_dir', osraiser) with pytest.raises(OSError): # make sure the config dir search fails paths.get_cache_dir(rootname='astropy') with pytest.warns(CacheMissingWarning) as warning_lines: fnout = download_file(TESTURL, cache=True) n_warns = len(warning_lines) partial_warn_msgs = ['remote data cache could not be accessed', 'temporary file'] if n_warns == 4: partial_warn_msgs.extend(['socket', 'socket']) for wl in warning_lines: cur_w = str(wl).lower() for i, partial_msg in enumerate(partial_warn_msgs): if partial_msg in cur_w: del partial_warn_msgs[i] break assert len(partial_warn_msgs) == 0, f'Got some unexpected warnings: {partial_warn_msgs}' assert n_warns in (2, 4), f'Expected 2 or 4 warnings, got {n_warns}' assert os.path.isfile(fnout) # clearing the cache should be a no-up that doesn't affect fnout with pytest.warns(CacheMissingWarning, match=r".*Not clearing data cache - cache inaccessible.*"): clear_download_cache(TESTURL) assert os.path.isfile(fnout) # now remove it so tests don't clutter up the temp dir this should get # called at exit, anyway, but we do it here just to make sure it's working # correctly _deltemps() assert not os.path.isfile(fnout) # now try with no cache fnnocache = download_file(TESTURL, cache=False) with open(fnnocache, "rb") as page: assert page.read().decode("utf-8").find("Astropy") > -1 # no warnings should be raise in fileobj because cache is unnecessary @pytest.mark.parametrize( ("filename"), [ "unicode.txt", "unicode.txt.gz", pytest.param( "unicode.txt.bz2", marks=pytest.mark.xfail(not HAS_BZ2, reason="no bz2 support"), ), pytest.param( "unicode.txt.xz", marks=pytest.mark.xfail(not HAS_LZMA, reason="no lzma support"), ), ], ) def test_read_unicode(filename): contents = get_pkg_data_contents(os.path.join("data", filename), encoding="utf-8") assert isinstance(contents, str) contents = contents.splitlines()[1] assert contents == "האסטרונומי פיי×Ēון" contents = get_pkg_data_contents(os.path.join("data", filename), encoding="binary") assert isinstance(contents, bytes) x = contents.splitlines()[1] assert x == ( b"\xff\xd7\x94\xd7\x90\xd7\xa1\xd7\x98\xd7\xa8\xd7\x95\xd7\xa0" b"\xd7\x95\xd7\x9e\xd7\x99 \xd7\xa4\xd7\x99\xd7\x99\xd7\xaa\xd7\x95\xd7\x9f"[1:] ) def test_compressed_stream(): gzipped_data = ( b"H4sICIxwG1AAA2xvY2FsLmRhdAALycgsVkjLzElVANKlxakpCpl5CiUZqQ" b"olqcUl8Tn5yYk58SmJJYnxWmCRzLx0hbTSvOSSzPy8Yi5nf78QV78QLgAlLytnRQAAAA==" ) gzipped_data = base64.b64decode(gzipped_data) assert isinstance(gzipped_data, bytes) class FakeStream: """ A fake stream that has `read`, but no `seek`. """ def __init__(self, data): self.data = data def read(self, nbytes=None): if nbytes is None: result = self.data self.data = b"" else: result = self.data[:nbytes] self.data = self.data[nbytes:] return result stream = FakeStream(gzipped_data) with get_readable_fileobj(stream, encoding="binary") as f: f.readline() assert f.read().rstrip() == b"CONTENT" @pytest.mark.remote_data(source="astropy") def test_invalid_location_download_raises_urlerror(): """ checks that download_file gives a URLError and not an AttributeError, as its code pathway involves some fiddling with the exception. """ with pytest.raises(urllib.error.URLError): download_file("http://www.astropy.org/nonexistentfile") def test_invalid_location_download_noconnect(): """ checks that download_file gives an OSError if the socket is blocked """ # This should invoke socket's monkeypatched failure with pytest.raises(OSError): download_file("http://astropy.org/nonexistentfile") @pytest.mark.remote_data(source="astropy") def test_is_url_in_cache_remote(): assert not is_url_in_cache("http://astropy.org/nonexistentfile") download_file(TESTURL, cache=True, show_progress=False) assert is_url_in_cache(TESTURL) def test_is_url_in_cache_local(temp_cache, valid_urls, invalid_urls): testurl, contents = next(valid_urls) nonexistent = next(invalid_urls) assert not is_url_in_cache(testurl) assert not is_url_in_cache(nonexistent) download_file(testurl, cache=True, show_progress=False) assert is_url_in_cache(testurl) assert not is_url_in_cache(nonexistent) # If non-deterministic failure happens see # https://github.com/astropy/astropy/issues/9765 def test_check_download_cache(tmpdir, temp_cache, valid_urls, invalid_urls): testurl, testurl_contents = next(valid_urls) testurl2, testurl2_contents = next(valid_urls) zip_file_name = os.path.join(tmpdir, "the.zip") clear_download_cache() assert not check_download_cache() download_file(testurl, cache=True) check_download_cache() download_file(testurl2, cache=True) check_download_cache() export_download_cache(zip_file_name, [testurl, testurl2]) check_download_cache() clear_download_cache(testurl2) check_download_cache() import_download_cache(zip_file_name, [testurl]) check_download_cache() def test_export_import_roundtrip_one(tmpdir, temp_cache, valid_urls): testurl, contents = next(valid_urls) f = download_file(testurl, cache=True, show_progress=False) assert get_file_contents(f) == contents initial_urls_in_cache = set(get_cached_urls()) zip_file_name = os.path.join(tmpdir, "the.zip") export_download_cache(zip_file_name, [testurl]) clear_download_cache(testurl) import_download_cache(zip_file_name) assert is_url_in_cache(testurl) assert set(get_cached_urls()) == initial_urls_in_cache assert ( get_file_contents(download_file(testurl, cache=True, show_progress=False)) == contents ) def test_export_url_not_present(temp_cache, valid_urls): testurl, contents = next(valid_urls) with NamedTemporaryFile("wb") as zip_file: assert not is_url_in_cache(testurl) with pytest.raises(KeyError): export_download_cache(zip_file, [testurl]) def test_import_one(tmpdir, temp_cache, valid_urls): testurl, testurl_contents = next(valid_urls) testurl2, testurl2_contents = next(valid_urls) zip_file_name = os.path.join(tmpdir, "the.zip") download_file(testurl, cache=True) download_file(testurl2, cache=True) assert is_url_in_cache(testurl2) export_download_cache(zip_file_name, [testurl, testurl2]) clear_download_cache(testurl) clear_download_cache(testurl2) import_download_cache(zip_file_name, [testurl]) assert is_url_in_cache(testurl) assert not is_url_in_cache(testurl2) def test_export_import_roundtrip(tmpdir, temp_cache, valid_urls): zip_file_name = os.path.join(tmpdir, "the.zip") for u, c in islice(valid_urls, FEW): download_file(u, cache=True) initial_urls_in_cache = set(get_cached_urls()) export_download_cache(zip_file_name) clear_download_cache() import_download_cache(zip_file_name) assert set(get_cached_urls()) == initial_urls_in_cache def test_export_import_roundtrip_stream(temp_cache, valid_urls): for u, c in islice(valid_urls, FEW): download_file(u, cache=True) initial_urls_in_cache = set(get_cached_urls()) with io.BytesIO() as f: export_download_cache(f) b = f.getvalue() clear_download_cache() with io.BytesIO(b) as f: import_download_cache(f) assert set(get_cached_urls()) == initial_urls_in_cache def test_export_overwrite_flag_works(temp_cache, valid_urls, tmpdir): fn = tmpdir / "f.zip" c = b"Some contents\nto check later" with open(fn, "wb") as f: f.write(c) for u, _ in islice(valid_urls, FEW): download_file(u, cache=True) with pytest.raises(FileExistsError): export_download_cache(fn) assert get_file_contents(fn, encoding='binary') == c export_download_cache(fn, overwrite=True) assert get_file_contents(fn, encoding='binary') != c def test_export_import_roundtrip_different_location(tmpdir, valid_urls): original_cache = tmpdir / "original" os.mkdir(original_cache) zip_file_name = tmpdir / "the.zip" urls = list(islice(valid_urls, FEW)) initial_urls_in_cache = set(u for (u, c) in urls) with paths.set_temp_cache(original_cache): for u, c in urls: download_file(u, cache=True) assert set(get_cached_urls()) == initial_urls_in_cache export_download_cache(zip_file_name) new_cache = tmpdir / "new" os.mkdir(new_cache) with paths.set_temp_cache(new_cache): import_download_cache(zip_file_name) check_download_cache() assert set(get_cached_urls()) == initial_urls_in_cache for (u, c) in urls: assert get_file_contents(download_file(u, cache=True)) == c def test_cache_size_is_zero_when_empty(temp_cache): assert not get_cached_urls() assert cache_total_size() == 0 def test_cache_size_changes_correctly_when_files_are_added_and_removed( temp_cache, valid_urls ): u, c = next(valid_urls) clear_download_cache(u) s_i = cache_total_size() download_file(u, cache=True) assert cache_total_size() == s_i + len(c) + len(u.encode("utf-8")) clear_download_cache(u) assert cache_total_size() == s_i def test_cache_contents_agrees_with_get_urls(temp_cache, valid_urls): r = [] for a, a_c in islice(valid_urls, FEW): a_f = download_file(a, cache=True) r.append((a, a_c, a_f)) assert set(cache_contents().keys()) == set(get_cached_urls()) for (u, c, h) in r: assert cache_contents()[u] == h @pytest.mark.parametrize('desired_size', [1_000_000_000_000_000_000, 1 * _u.Ebyte]) def test_free_space_checker_huge(tmpdir, desired_size): with pytest.raises(OSError): check_free_space_in_dir(str(tmpdir), desired_size) def test_get_free_space_file_directory(tmpdir): fn = tmpdir / "file" with open(fn, "w"): pass with pytest.raises(OSError): get_free_space_in_dir(str(fn)) free_space = get_free_space_in_dir(str(tmpdir)) assert free_space > 0 and not hasattr(free_space, 'unit') # TODO: If unit=True starts to auto-guess prefix, this needs updating. free_space = get_free_space_in_dir(str(tmpdir), unit=True) assert free_space > 0 and free_space.unit == _u.byte free_space = get_free_space_in_dir(str(tmpdir), unit=_u.Mbit) assert free_space > 0 and free_space.unit == _u.Mbit def test_download_file_bogus_settings(invalid_urls, temp_cache): u = next(invalid_urls) with pytest.raises(KeyError): download_file(u, sources=[]) def test_download_file_local_directory(tmpdir): """Make sure we get a URLError rather than OSError even if it's a local directory.""" with pytest.raises(urllib.request.URLError): download_file(url_to(tmpdir)) def test_download_file_schedules_deletion(valid_urls): u, c = next(valid_urls) f = download_file(u) assert f in _tempfilestodel # how to test deletion actually occurs? def test_clear_download_cache_refuses_to_delete_outside_the_cache(tmpdir): fn = os.path.abspath(os.path.join(tmpdir, "file")) with open(fn, "w") as f: f.write("content") assert os.path.exists(fn) with pytest.raises(RuntimeError): clear_download_cache(fn) assert os.path.exists(fn) def test_check_download_cache_finds_bogus_entries(temp_cache, valid_urls): u, c = next(valid_urls) download_file(u, cache=True) dldir = _get_download_cache_loc() bf = os.path.abspath(os.path.join(dldir, "bogus")) with open(bf, "wt") as f: f.write("bogus file that exists") with pytest.raises(CacheDamaged) as e: check_download_cache() assert bf in e.value.bad_files clear_download_cache() def test_check_download_cache_finds_bogus_subentries(temp_cache, valid_urls): u, c = next(valid_urls) f = download_file(u, cache=True) bf = os.path.abspath(os.path.join(os.path.dirname(f), "bogus")) with open(bf, "wt") as f: f.write("bogus file that exists") with pytest.raises(CacheDamaged) as e: check_download_cache() assert bf in e.value.bad_files clear_download_cache() def test_check_download_cache_cleanup(temp_cache, valid_urls): u, c = next(valid_urls) fn = download_file(u, cache=True) dldir = _get_download_cache_loc() bf1 = os.path.abspath(os.path.join(dldir, "bogus1")) with open(bf1, "wt") as f: f.write("bogus file that exists") bf2 = os.path.abspath(os.path.join(os.path.dirname(fn), "bogus2")) with open(bf2, "wt") as f: f.write("other bogus file that exists") bf3 = os.path.abspath(os.path.join(dldir, "contents")) with open(bf3, "wt") as f: f.write("awkwardly-named bogus file that exists") u2, c2 = next(valid_urls) f2 = download_file(u, cache=True) os.unlink(f2) bf4 = os.path.dirname(f2) with pytest.raises(CacheDamaged) as e: check_download_cache() assert set(e.value.bad_files) == set([bf1, bf2, bf3, bf4]) for bf in e.value.bad_files: clear_download_cache(bf) # download cache will be checked on exit def test_download_cache_update_doesnt_damage_cache(temp_cache, valid_urls): u, _ = next(valid_urls) download_file(u, cache=True) download_file(u, cache="update") def test_cache_dir_is_actually_a_file(tmpdir, valid_urls): """Ensure that bogus cache settings are handled sensibly. Because the user can specify the cache location in a config file, and because they might try to deduce the location by looking around at what's in their directory tree, and because the cache directory is actual several tree levels down from the directory set in the config file, it's important to check what happens if each of the steps in the path is wrong somehow. """ def check_quietly_ignores_bogus_cache(): """We want a broken cache to produce a warning but then astropy should act like there isn't a cache. """ with pytest.warns(CacheMissingWarning): assert not get_cached_urls() with pytest.warns(CacheMissingWarning): assert not is_url_in_cache("http://www.example.com/") with pytest.warns(CacheMissingWarning): assert not cache_contents() with pytest.warns(CacheMissingWarning): u, c = next(valid_urls) r = download_file(u, cache=True) assert get_file_contents(r) == c # check the filename r appears in a warning message? # check r is added to the delete_at_exit list? # in fact should there be testing of the delete_at_exit mechanism, # as far as that is possible? with pytest.warns(CacheMissingWarning): assert not is_url_in_cache(u) with pytest.warns(CacheMissingWarning): with pytest.raises(OSError): check_download_cache() dldir = _get_download_cache_loc() # set_temp_cache acts weird if it is pointed at a file (see below) # but we want to see what happens when the cache is pointed # at a file instead of a directory, so make a directory we can # replace later. fn = str(tmpdir / "file") ct = "contents\n" os.mkdir(fn) with paths.set_temp_cache(fn): shutil.rmtree(fn) with open(fn, "w") as f: f.write(ct) with pytest.raises(OSError): paths.get_cache_dir() check_quietly_ignores_bogus_cache() assert dldir == _get_download_cache_loc() assert get_file_contents(fn) == ct, "File should not be harmed." # See what happens when set_temp_cache is pointed at a file with pytest.raises(OSError): with paths.set_temp_cache(fn): pass assert dldir == _get_download_cache_loc() assert get_file_contents(str(fn)) == ct # Now the cache directory is normal but the subdirectory it wants # to make is a file cd = str(tmpdir / "astropy") with open(cd, "w") as f: f.write(ct) with paths.set_temp_cache(tmpdir): check_quietly_ignores_bogus_cache() assert dldir == _get_download_cache_loc() assert get_file_contents(cd) == ct os.remove(cd) # Ditto one level deeper os.makedirs(cd) cd = str(tmpdir / "astropy" / "download") with open(cd, "w") as f: f.write(ct) with paths.set_temp_cache(tmpdir): check_quietly_ignores_bogus_cache() assert dldir == _get_download_cache_loc() assert get_file_contents(cd) == ct os.remove(cd) # Ditto another level deeper os.makedirs(cd) cd = str(tmpdir / "astropy" / "download" / "url") with open(cd, "w") as f: f.write(ct) with paths.set_temp_cache(tmpdir): check_quietly_ignores_bogus_cache() assert dldir == _get_download_cache_loc() assert get_file_contents(cd) == ct os.remove(cd) def test_get_fileobj_str(a_file): fn, c = a_file with get_readable_fileobj(str(fn)) as rf: assert rf.read() == c def test_get_fileobj_localpath(a_file): fn, c = a_file with get_readable_fileobj(py.path.local(fn)) as rf: assert rf.read() == c def test_get_fileobj_pathlib(a_file): fn, c = a_file with get_readable_fileobj(pathlib.Path(fn)) as rf: assert rf.read() == c def test_get_fileobj_binary(a_binary_file): fn, c = a_binary_file with get_readable_fileobj(fn, encoding="binary") as rf: assert rf.read() == c def test_get_fileobj_already_open_text(a_file): fn, c = a_file with open(fn, "r") as f: with get_readable_fileobj(f) as rf: with pytest.raises(TypeError): rf.read() def test_get_fileobj_already_open_binary(a_file): fn, c = a_file with open(fn, "rb") as f: with get_readable_fileobj(f) as rf: assert rf.read() == c def test_get_fileobj_binary_already_open_binary(a_binary_file): fn, c = a_binary_file with open(fn, "rb") as f: with get_readable_fileobj(f, encoding="binary") as rf: assert rf.read() == c def test_cache_contents_not_writable(temp_cache, valid_urls): c = cache_contents() with pytest.raises(TypeError): c["foo"] = 7 u, _ = next(valid_urls) download_file(u, cache=True) c = cache_contents() assert u in c with pytest.raises(TypeError): c["foo"] = 7 def test_cache_relocatable(tmpdir, valid_urls): u, c = next(valid_urls) d1 = tmpdir / "1" d2 = tmpdir / "2" os.mkdir(d1) with paths.set_temp_cache(d1): p1 = download_file(u, cache=True) assert is_url_in_cache(u) assert get_file_contents(p1) == c shutil.copytree(d1, d2) clear_download_cache() with paths.set_temp_cache(d2): assert is_url_in_cache(u) p2 = download_file(u, cache=True) assert p1 != p2 assert os.path.exists(p2) clear_download_cache(p2) check_download_cache() def test_get_readable_fileobj_cleans_up_temporary_files(tmpdir, monkeypatch): """checks that get_readable_fileobj leaves no temporary files behind""" # Create a 'file://' URL pointing to a path on the local filesystem url = url_to(TESTLOCAL) # Save temporary files to a known location monkeypatch.setattr(tempfile, "tempdir", str(tmpdir)) # Call get_readable_fileobj() as a context manager with get_readable_fileobj(url) as f: f.read() # Get listing of files in temporary directory tempdir_listing = tmpdir.listdir() # Assert that the temporary file was empty after get_readable_fileobj() # context manager finished running assert len(tempdir_listing) == 0 def test_path_objects_get_readable_fileobj(): fpath = pathlib.Path(TESTLOCAL) with get_readable_fileobj(fpath) as f: assert f.read().rstrip() == ( "This file is used in the test_local_data_* testing functions\nCONTENT" ) def test_nested_get_readable_fileobj(): """Ensure fileobj state is as expected when get_readable_fileobj() is called inside another get_readable_fileobj(). """ with get_readable_fileobj(TESTLOCAL, encoding="binary") as fileobj: with get_readable_fileobj(fileobj, encoding="UTF-8") as fileobj2: fileobj2.seek(1) fileobj.seek(1) # Theoretically, fileobj2 should be closed already here but it is not. # See https://github.com/astropy/astropy/pull/8675. # UNCOMMENT THIS WHEN PYTHON FINALLY LETS IT HAPPEN. # assert fileobj2.closed assert fileobj.closed and fileobj2.closed def test_download_file_wrong_size(monkeypatch): @contextlib.contextmanager def mockurl(remote_url, timeout=None): yield MockURL() def mockurl_builder(*args, tlscontext=None, **kwargs): mock_opener = type('MockOpener', (object,), {})() mock_opener.open = mockurl return mock_opener class MockURL: def __init__(self): self.reader = io.BytesIO(b"a" * real_length) def info(self): return {"Content-Length": str(report_length)} def read(self, length=None): return self.reader.read(length) monkeypatch.setattr(astropy.utils.data, "_build_urlopener", mockurl_builder) with pytest.raises(urllib.error.ContentTooShortError): report_length = 1024 real_length = 1023 download_file(TESTURL, cache=False) with pytest.raises(urllib.error.URLError): report_length = 1023 real_length = 1024 download_file(TESTURL, cache=False) report_length = 1023 real_length = 1023 fn = download_file(TESTURL, cache=False) with open(fn, "rb") as f: assert f.read() == b"a" * real_length report_length = None real_length = 1023 fn = download_file(TESTURL, cache=False) with open(fn, "rb") as f: assert f.read() == b"a" * real_length def test_can_make_directories_readonly(tmpdir): try: with readonly_dir(tmpdir): assert is_dir_readonly(tmpdir) except AssertionError: if hasattr(os, "geteuid") and os.geteuid() == 0: pytest.skip( "We are root, we can't make a directory un-writable with chmod." ) elif platform.system() == "Windows": pytest.skip( "It seems we can't make a driectory un-writable under Windows " "with chmod, in spite of the documentation." ) else: raise def test_can_make_files_readonly(tmpdir): fn = tmpdir / "test" c = "contents\n" with open(fn, "w") as f: f.write(c) with readonly_dir(tmpdir): try: with open(fn, "w+") as f: f.write("more contents\n") except PermissionError: pass else: if hasattr(os, "geteuid") and os.geteuid() == 0: pytest.skip("We are root, we can't make a file un-writable with chmod.") assert get_file_contents(fn) == c def test_read_cache_readonly(readonly_cache): assert cache_contents() == readonly_cache def test_download_file_cache_readonly(readonly_cache): for u in readonly_cache: f = download_file(u, cache=True) assert f == readonly_cache[u] def test_import_file_cache_readonly(readonly_cache, tmpdir): filename = os.path.join(tmpdir, "test-file") content = "Some text or other" url = "http://example.com/" with open(filename, "wt") as f: f.write(content) with pytest.raises(OSError): import_file_to_cache(url, filename, remove_original=True) assert not is_url_in_cache(url) def test_download_file_cache_readonly_cache_miss(readonly_cache, valid_urls): u, c = next(valid_urls) with pytest.warns(CacheMissingWarning): f = download_file(u, cache=True) assert get_file_contents(f) == c assert not is_url_in_cache(u) def test_download_file_cache_readonly_update(readonly_cache): for u in readonly_cache: with pytest.warns(CacheMissingWarning): f = download_file(u, cache="update") assert f != readonly_cache[u] assert compute_hash(f) == compute_hash(readonly_cache[u]) def test_check_download_cache_works_if_readonly(readonly_cache): check_download_cache() # On Windows I can't make directories readonly. On CircleCI I can't make # anything readonly because the test suite runs as root. So on those platforms # none of the "real" tests above can be run. I can use monkeypatch to trigger # the readonly code paths, see the "fake" versions of the tests below, but I # don't totally trust those to completely explore what happens either, so we # have both. I couldn't see an easy way to parameterize over fixtures and share # tests. def test_read_cache_fake_readonly(fake_readonly_cache): assert cache_contents() == fake_readonly_cache def test_download_file_cache_fake_readonly(fake_readonly_cache): for u in fake_readonly_cache: f = download_file(u, cache=True) assert f == fake_readonly_cache[u] def test_mkdtemp_cache_fake_readonly(fake_readonly_cache): with pytest.raises(OSError): tempfile.mkdtemp() def test_TD_cache_fake_readonly(fake_readonly_cache): with pytest.raises(OSError): with TemporaryDirectory(): pass def test_import_file_cache_fake_readonly(fake_readonly_cache, tmpdir): filename = os.path.join(tmpdir, "test-file") content = "Some text or other" url = "http://example.com/" with open(filename, "wt") as f: f.write(content) with pytest.raises(OSError): import_file_to_cache(url, filename, remove_original=True) assert not is_url_in_cache(url) def test_download_file_cache_fake_readonly_cache_miss(fake_readonly_cache, valid_urls): u, c = next(valid_urls) with pytest.warns(CacheMissingWarning): f = download_file(u, cache=True) assert not is_url_in_cache(u) assert get_file_contents(f) == c def test_download_file_cache_fake_readonly_update(fake_readonly_cache): for u in fake_readonly_cache: with pytest.warns(CacheMissingWarning): f = download_file(u, cache="update") assert f != fake_readonly_cache[u] assert compute_hash(f) == compute_hash(fake_readonly_cache[u]) def test_check_download_cache_works_if_fake_readonly(fake_readonly_cache): check_download_cache() def test_pkgname_isolation(temp_cache, valid_urls): a = "bogus_cache_name" assert not get_cached_urls() assert not get_cached_urls(pkgname=a) for u, _ in islice(valid_urls, FEW): download_file(u, cache=True, pkgname=a) assert not get_cached_urls() assert len(get_cached_urls(pkgname=a)) == FEW assert cache_total_size() < cache_total_size(pkgname=a) for u, _ in islice(valid_urls, FEW+1): download_file(u, cache=True) assert len(get_cached_urls()) == FEW+1 assert len(get_cached_urls(pkgname=a)) == FEW assert cache_total_size() > cache_total_size(pkgname=a) assert set(get_cached_urls()) == set(cache_contents().keys()) assert set(get_cached_urls(pkgname=a)) == set(cache_contents(pkgname=a).keys()) for i in get_cached_urls(): assert is_url_in_cache(i) assert not is_url_in_cache(i, pkgname=a) for i in get_cached_urls(pkgname=a): assert not is_url_in_cache(i) assert is_url_in_cache(i, pkgname=a) # FIXME: need to break a cache to test whether we check the right one check_download_cache() check_download_cache(pkgname=a) # FIXME: check that cache='update' works u = get_cached_urls()[0] with pytest.raises(KeyError): download_file(u, cache=True, sources=[], pkgname=a) clear_download_cache(u, pkgname=a) assert len(get_cached_urls()) == FEW+1, "wrong pkgname should do nothing" assert len(get_cached_urls(pkgname=a)) == FEW, "wrong pkgname should do nothing" f = download_file(u, sources=[], cache=True) with pytest.raises(RuntimeError): clear_download_cache(f, pkgname=a) ua = get_cached_urls(pkgname=a)[0] with pytest.raises(KeyError): download_file(ua, cache=True, sources=[]) fa = download_file(ua, sources=[], cache=True, pkgname=a) with pytest.raises(RuntimeError): clear_download_cache(fa) clear_download_cache(ua, pkgname=a) assert len(get_cached_urls()) == FEW+1 assert len(get_cached_urls(pkgname=a)) == FEW-1 clear_download_cache(u) assert len(get_cached_urls()) == FEW assert len(get_cached_urls(pkgname=a)) == FEW-1 clear_download_cache(pkgname=a) assert len(get_cached_urls()) == FEW assert not get_cached_urls(pkgname=a) clear_download_cache() assert not get_cached_urls() assert not get_cached_urls(pkgname=a) def test_transport_cache_via_zip(temp_cache, valid_urls): a = "bogus_cache_name" assert not get_cached_urls() assert not get_cached_urls(pkgname=a) for u, _ in islice(valid_urls, FEW): download_file(u, cache=True) with io.BytesIO() as f: export_download_cache(f) b = f.getvalue() with io.BytesIO(b) as f: import_download_cache(f, pkgname=a) check_download_cache() check_download_cache(pkgname=a) assert set(get_cached_urls()) == set(get_cached_urls(pkgname=a)) cca = cache_contents(pkgname=a) for k, v in cache_contents().items(): assert v != cca[k] assert get_file_contents(v) == get_file_contents(cca[k]) clear_download_cache() with io.BytesIO() as f: export_download_cache(f, pkgname=a) b = f.getvalue() with io.BytesIO(b) as f: import_download_cache(f) assert set(get_cached_urls()) == set(get_cached_urls(pkgname=a)) def test_download_parallel_respects_pkgname(temp_cache, valid_urls): a = "bogus_cache_name" assert not get_cached_urls() assert not get_cached_urls(pkgname=a) download_files_in_parallel([u for (u, c) in islice(valid_urls, FEW)], pkgname=a) assert not get_cached_urls() assert len(get_cached_urls(pkgname=a)) == FEW @pytest.mark.skipif(not CAN_RENAME_DIRECTORY_IN_USE, reason="This platform is unable to rename directories that are in use.") def test_removal_of_open_files(temp_cache, valid_urls): u, c = next(valid_urls) with open(download_file(u, cache=True)): clear_download_cache(u) assert not is_url_in_cache(u) check_download_cache() @pytest.mark.skipif(not CAN_RENAME_DIRECTORY_IN_USE, reason="This platform is unable to rename directories that are in use.") def test_update_of_open_files(temp_cache, valid_urls): u, c = next(valid_urls) with open(download_file(u, cache=True)): u2, c2 = next(valid_urls) f = download_file(u, cache='update', sources=[u2]) check_download_cache() assert is_url_in_cache(u) assert get_file_contents(f) == c2 assert is_url_in_cache(u) def test_removal_of_open_files_windows(temp_cache, valid_urls, monkeypatch): def no_rmtree(*args, **kwargs): warnings.warn(CacheMissingWarning("in use")) raise PermissionError if CAN_RENAME_DIRECTORY_IN_USE: # This platform is able to remove files while in use. monkeypatch.setattr(astropy.utils.data, "_rmtree", no_rmtree) u, c = next(valid_urls) with open(download_file(u, cache=True)): with pytest.warns(CacheMissingWarning, match=r".*in use.*"): clear_download_cache(u) def test_update_of_open_files_windows(temp_cache, valid_urls, monkeypatch): def no_rmtree(*args, **kwargs): warnings.warn(CacheMissingWarning("in use")) raise PermissionError if CAN_RENAME_DIRECTORY_IN_USE: # This platform is able to remove files while in use. monkeypatch.setattr(astropy.utils.data, "_rmtree", no_rmtree) u, c = next(valid_urls) with open(download_file(u, cache=True)): u2, c2 = next(valid_urls) with pytest.warns(CacheMissingWarning, match=r".*in use.*"): f = download_file(u, cache='update', sources=[u2]) check_download_cache() assert is_url_in_cache(u) assert get_file_contents(f) == c2 assert get_file_contents(download_file(u, cache=True, sources=[])) == c def test_no_allow_internet(temp_cache, valid_urls): u, c = next(valid_urls) with conf.set_temp('allow_internet', False): with pytest.raises(urllib.error.URLError): download_file(u) assert not is_url_in_cache(u) with pytest.raises(urllib.error.URLError): # This will trigger the remote data error if it's allowed to touch the internet download_file(TESTURL) def test_clear_download_cache_not_too_aggressive(temp_cache, valid_urls): u, c = next(valid_urls) download_file(u, cache=True) dldir = _get_download_cache_loc() bad_filename = os.path.join(dldir, "contents") assert is_url_in_cache(u) clear_download_cache(bad_filename) assert is_url_in_cache(u) def test_clear_download_cache_variants(temp_cache, valid_urls): # deletion by contents filename u, c = next(valid_urls) f = download_file(u, cache=True) clear_download_cache(f) assert not is_url_in_cache(u) # deletion by url filename u, c = next(valid_urls) f = download_file(u, cache=True) clear_download_cache(os.path.join(os.path.dirname(f), 'url')) assert not is_url_in_cache(u) # deletion by hash directory name u, c = next(valid_urls) f = download_file(u, cache=True) clear_download_cache(os.path.dirname(f)) assert not is_url_in_cache(u) # deletion by directory name with trailing slash u, c = next(valid_urls) f = download_file(u, cache=True) clear_download_cache(os.path.dirname(f)+'/') assert not is_url_in_cache(u) # deletion by hash of file contents u, c = next(valid_urls) f = download_file(u, cache=True) h = compute_hash(f) clear_download_cache(h) assert not is_url_in_cache(u) @pytest.mark.skipif("CI", reason="Flaky on CI") @pytest.mark.remote_data def test_ftp_tls_auto(temp_cache): url = "ftp://anonymous:mail%40astropy.org@gdc.cddis.eosdis.nasa.gov/pub/products/iers/finals2000A.all" # noqa download_file(url) @pytest.mark.parametrize('base', ["http://example.com", "https://example.com"]) def test_url_trailing_slash(temp_cache, valid_urls, base): slash = base + "/" no_slash = base u, c = next(valid_urls) download_file(slash, cache=True, sources=[u]) assert is_url_in_cache(no_slash) download_file(no_slash, cache=True, sources=[]) clear_download_cache(no_slash) assert not is_url_in_cache(no_slash) assert not is_url_in_cache(slash) download_file(no_slash, cache=True, sources=[u]) # see if implicit check_download_cache squawks def test_empty_url(temp_cache, valid_urls): u, c = next(valid_urls) download_file('file://', cache=True, sources=[u]) assert not is_url_in_cache('file:///') @pytest.mark.remote_data def test_download_ftp_file_properly_handles_socket_error(): faulty_url = "ftp://anonymous:mail%40astropy.org@nonexisting/pub/products/iers/finals2000A.all" with pytest.raises(urllib.error.URLError) as excinfo: download_file(faulty_url) errmsg = excinfo.exconly() found_msg = False possible_msgs = ['Name or service not known', 'nodename nor servname provided, or not known', 'getaddrinfo failed', 'Temporary failure in name resolution', 'No address associated with hostname'] for cur_msg in possible_msgs: if cur_msg in errmsg: found_msg = True break assert found_msg, f'Got {errmsg}, expected one of these: {",".join(possible_msgs)}' @pytest.mark.parametrize( ('s', 'ans'), [('http://googlecom', True), ('https://google.com', True), ('ftp://google.com', True), ('sftp://google.com', True), ('ssh://google.com', True), ('file:///c:/path/to/the%20file.txt', True), ('google.com', False), ('C:\\\\path\\\\file.docx', False), ('data://file', False)]) def test_string_is_url_check(s, ans): assert is_url(s) is ans ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/test_data_info.py0000644000175100001710000000571700000000000021617 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst import pytest import numpy as np from astropy.utils.data_info import dtype_info_name from astropy.table import QTable from astropy.table.index import SlicedIndex from astropy.time import Time from astropy.coordinates import SkyCoord import astropy.units as u STRING_TYPE_NAMES = {(True, 'S'): 'bytes', (True, 'U'): 'str'} DTYPE_TESTS = ((np.array(b'abcd').dtype, STRING_TYPE_NAMES[(True, 'S')] + '4'), (np.array('abcd').dtype, STRING_TYPE_NAMES[(True, 'U')] + '4'), ('S4', STRING_TYPE_NAMES[(True, 'S')] + '4'), ('U4', STRING_TYPE_NAMES[(True, 'U')] + '4'), (np.void, 'void'), (np.int32, 'int32'), (bool, 'bool'), (float, 'float64'), ('' in out assert 'b>' in out def test_diff_types(): """ Regression test for https://github.com/astropy/astropy/issues/4122 """ f = io.StringIO() a = 1.0 b = '1.0' identical = report_diff_values(a, b, fileobj=f) assert not identical out = f.getvalue() assert out == (" (float) a> 1.0\n" " (str) b> '1.0'\n" " ? + +\n") def test_diff_numeric_scalar_types(): """ Test comparison of different numeric scalar types. """ f = io.StringIO() assert not report_diff_values(1.0, 1, fileobj=f) out = f.getvalue() assert out == ' (float) a> 1.0\n (int) b> 1\n' def test_array_comparison(): """ Test diff-ing two arrays. """ f = io.StringIO() a = np.arange(9).reshape(3, 3) b = a + 1 identical = report_diff_values(a, b, fileobj=f) assert not identical out = f.getvalue() assert out == (' at [0, 0]:\n' ' a> 0\n' ' b> 1\n' ' at [0, 1]:\n' ' a> 1\n' ' b> 2\n' ' at [0, 2]:\n' ' a> 2\n' ' b> 3\n' ' ...and at 6 more indices.\n') def test_diff_shaped_array_comparison(): """ Test diff-ing two differently shaped arrays. """ f = io.StringIO() a = np.empty((1, 2, 3)) identical = report_diff_values(a, a[0], fileobj=f) assert not identical out = f.getvalue() assert out == (' Different array shapes:\n' ' a> (1, 2, 3)\n' ' ? ---\n' ' b> (2, 3)\n') def test_tablediff(): """ Test diff-ing two simple Table objects. """ a = Table.read("""name obs_date mag_b mag_v M31 2012-01-02 17.0 16.0 M82 2012-10-29 16.2 15.2 M101 2012-10-31 15.1 15.5""", format='ascii') b = Table.read("""name obs_date mag_b mag_v M31 2012-01-02 17.0 16.5 M82 2012-10-29 16.2 15.2 M101 2012-10-30 15.1 15.5 NEW 2018-05-08 nan 9.0""", format='ascii') f = io.StringIO() identical = report_diff_values(a, b, fileobj=f) assert not identical out = f.getvalue() assert out == (' name obs_date mag_b mag_v\n' ' ---- ---------- ----- -----\n' ' a> M31 2012-01-02 17.0 16.0\n' ' ? ^\n' ' b> M31 2012-01-02 17.0 16.5\n' ' ? ^\n' ' M82 2012-10-29 16.2 15.2\n' ' a> M101 2012-10-31 15.1 15.5\n' ' ? ^\n' ' b> M101 2012-10-30 15.1 15.5\n' ' ? ^\n' ' b> NEW 2018-05-08 nan 9.0\n') # Identical assert report_diff_values(a, a, fileobj=f) @pytest.mark.parametrize('kwargs', [{}, {'atol': 0, 'rtol': 0}]) def test_where_not_allclose(kwargs): a = np.array([1, np.nan, np.inf, 4.5]) b = np.array([1, np.inf, np.nan, 4.6]) assert where_not_allclose(a, b, **kwargs) == ([3], ) assert len(where_not_allclose(a, a, **kwargs)[0]) == 0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/test_introspection.py0000644000175100001710000000653600000000000022573 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst # namedtuple is needed for find_mod_objs so it can have a non-local module from collections import namedtuple from unittest import mock import pytest import yaml from astropy.utils import introspection from astropy.utils.introspection import (find_current_module, find_mod_objs, minversion) def test_pkg_finder(): """ Tests that the `find_current_module` function works. Note that this also implicitly tests compat.misc._patched_getmodule """ mod1 = 'astropy.utils.introspection' mod2 = 'astropy.utils.tests.test_introspection' mod3 = 'astropy.utils.tests.test_introspection' assert find_current_module(0).__name__ == mod1 assert find_current_module(1).__name__ == mod2 assert find_current_module(0, True).__name__ == mod3 def test_find_current_mod(): from sys import getrecursionlimit thismodnm = __name__ assert find_current_module(0) is introspection assert find_current_module(1).__name__ == thismodnm assert find_current_module(getrecursionlimit() + 1) is None assert find_current_module(0, True).__name__ == thismodnm assert find_current_module(0, [introspection]).__name__ == thismodnm assert find_current_module(0, ['astropy.utils.introspection']).__name__ == thismodnm with pytest.raises(ImportError): find_current_module(0, ['faddfdsasewrweriopunjlfiurrhujnkflgwhu']) def test_find_mod_objs(): lnms, fqns, objs = find_mod_objs('astropy') # this import is after the above call intentionally to make sure # find_mod_objs properly imports astropy on its own import astropy # just check for astropy.test ... other things might be added, so we # shouldn't check that it's the only thing assert 'test' in lnms assert astropy.test in objs lnms, fqns, objs = find_mod_objs(__name__, onlylocals=False) assert 'namedtuple' in lnms assert 'collections.namedtuple' in fqns assert namedtuple in objs lnms, fqns, objs = find_mod_objs(__name__, onlylocals=True) assert 'namedtuple' not in lnms assert 'collections.namedtuple' not in fqns assert namedtuple not in objs def test_minversion(): import numpy good_versions = ['1.16', '1.16.1', '1.16.0.dev', '1.16dev'] bad_versions = ['100000', '100000.2rc1'] for version in good_versions: assert minversion(numpy, version) assert minversion("numpy", version) for version in bad_versions: assert not minversion(numpy, version) assert not minversion("numpy", version) assert minversion(yaml, '3.1') assert minversion('yaml', '3.1') def test_find_current_module_bundle(): """ Tests that the `find_current_module` function would work if used inside an application bundle. Since we can't test this directly, we test what would happen if inspect.getmodule returned `None`, which is what happens inside PyInstaller and py2app bundles. """ with mock.patch('inspect.getmodule', return_value=None): mod1 = 'astropy.utils.introspection' mod2 = 'astropy.utils.tests.test_introspection' mod3 = 'astropy.utils.tests.test_introspection' assert find_current_module(0).__name__ == mod1 assert find_current_module(1).__name__ == mod2 assert find_current_module(0, True).__name__ == mod3 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/test_metadata.py0000644000175100001710000001463100000000000021446 0ustar00vstsdockerimport abc from collections import OrderedDict import pytest import numpy as np from astropy.utils.metadata import MetaData, MergeConflictError, merge, enable_merge_strategies from astropy.utils.metadata import common_dtype from astropy.utils import metadata from astropy.io import fits class OrderedDictSubclass(OrderedDict): pass class MetaBaseTest: __metaclass__ = abc.ABCMeta def test_none(self): d = self.test_class(*self.args) assert isinstance(d.meta, OrderedDict) assert len(d.meta) == 0 @pytest.mark.parametrize(('meta'), ([dict([('a', 1)]), OrderedDict([('a', 1)]), OrderedDictSubclass([('a', 1)])])) def test_mapping_init(self, meta): d = self.test_class(*self.args, meta=meta) assert type(d.meta) == type(meta) assert d.meta['a'] == 1 @pytest.mark.parametrize(('meta'), (["ceci n'est pas un meta", 1.2, [1, 2, 3]])) def test_non_mapping_init(self, meta): with pytest.raises(TypeError): self.test_class(*self.args, meta=meta) @pytest.mark.parametrize(('meta'), ([dict([('a', 1)]), OrderedDict([('a', 1)]), OrderedDictSubclass([('a', 1)])])) def test_mapping_set(self, meta): d = self.test_class(*self.args, meta=meta) assert type(d.meta) == type(meta) assert d.meta['a'] == 1 @pytest.mark.parametrize(('meta'), (["ceci n'est pas un meta", 1.2, [1, 2, 3]])) def test_non_mapping_set(self, meta): with pytest.raises(TypeError): d = self.test_class(*self.args, meta=meta) def test_meta_fits_header(self): header = fits.header.Header() header.set('observer', 'Edwin Hubble') header.set('exptime', '3600') d = self.test_class(*self.args, meta=header) assert d.meta['OBSERVER'] == 'Edwin Hubble' class ExampleData: meta = MetaData() def __init__(self, meta=None): self.meta = meta class TestMetaExampleData(MetaBaseTest): test_class = ExampleData args = () def test_metadata_merging_conflict_exception(): """Regression test for issue #3294. Ensure that an exception is raised when a metadata conflict exists and ``metadata_conflicts='error'`` has been set. """ data1 = ExampleData() data2 = ExampleData() data1.meta['somekey'] = {'x': 1, 'y': 1} data2.meta['somekey'] = {'x': 1, 'y': 999} with pytest.raises(MergeConflictError): merge(data1.meta, data2.meta, metadata_conflicts='error') def test_metadata_merging(): # Recursive merge meta1 = {'k1': {'k1': [1, 2], 'k2': 2}, 'k2': 2, 'k4': (1, 2)} meta2 = {'k1': {'k1': [3]}, 'k3': 3, 'k4': (3,)} out = merge(meta1, meta2, metadata_conflicts='error') assert out == {'k1': {'k2': 2, 'k1': [1, 2, 3]}, 'k2': 2, 'k3': 3, 'k4': (1, 2, 3)} # Merge two ndarrays meta1 = {'k1': np.array([1, 2])} meta2 = {'k1': np.array([3])} out = merge(meta1, meta2, metadata_conflicts='error') assert np.all(out['k1'] == np.array([1, 2, 3])) # Merge list and np.ndarray meta1 = {'k1': [1, 2]} meta2 = {'k1': np.array([3])} assert np.all(out['k1'] == np.array([1, 2, 3])) # Can't merge two scalar types meta1 = {'k1': 1} meta2 = {'k1': 2} with pytest.raises(MergeConflictError): merge(meta1, meta2, metadata_conflicts='error') # Conflicting shape meta1 = {'k1': np.array([1, 2])} meta2 = {'k1': np.array([[3]])} with pytest.raises(MergeConflictError): merge(meta1, meta2, metadata_conflicts='error') # Conflicting array type meta1 = {'k1': np.array([1, 2])} meta2 = {'k1': np.array(['3'])} with pytest.raises(MergeConflictError): merge(meta1, meta2, metadata_conflicts='error') # Conflicting array type with 'silent' merging meta1 = {'k1': np.array([1, 2])} meta2 = {'k1': np.array(['3'])} out = merge(meta1, meta2, metadata_conflicts='silent') assert np.all(out['k1'] == np.array(['3'])) def test_metadata_merging_new_strategy(): original_merge_strategies = list(metadata.MERGE_STRATEGIES) class MergeNumbersAsList(metadata.MergeStrategy): """ Scalar float or int values are joined in a list. """ types = ((int, float), (int, float)) @classmethod def merge(cls, left, right): return [left, right] class MergeConcatStrings(metadata.MergePlus): """ Scalar string values are concatenated """ types = (str, str) enabled = False # Normally can't merge two scalar types meta1 = {'k1': 1, 'k2': 'a'} meta2 = {'k1': 2, 'k2': 'b'} # Enable new merge strategy with enable_merge_strategies(MergeNumbersAsList, MergeConcatStrings): assert MergeNumbersAsList.enabled assert MergeConcatStrings.enabled out = merge(meta1, meta2, metadata_conflicts='error') assert out['k1'] == [1, 2] assert out['k2'] == 'ab' assert not MergeNumbersAsList.enabled assert not MergeConcatStrings.enabled # Confirm the default enabled=False behavior with pytest.raises(MergeConflictError): merge(meta1, meta2, metadata_conflicts='error') # Enable all MergeStrategy subclasses with enable_merge_strategies(metadata.MergeStrategy): assert MergeNumbersAsList.enabled assert MergeConcatStrings.enabled out = merge(meta1, meta2, metadata_conflicts='error') assert out['k1'] == [1, 2] assert out['k2'] == 'ab' assert not MergeNumbersAsList.enabled assert not MergeConcatStrings.enabled metadata.MERGE_STRATEGIES = original_merge_strategies def test_common_dtype_string(): u3 = np.array(['123']) u4 = np.array(['1234']) b3 = np.array([b'123']) b5 = np.array([b'12345']) assert common_dtype([u3, u4]).endswith('U4') assert common_dtype([b5, u4]).endswith('U5') assert common_dtype([b3, b5]).endswith('S5') def test_common_dtype_basic(): i8 = np.array(1, dtype=np.int64) f8 = np.array(1, dtype=np.float64) u3 = np.array('123') with pytest.raises(MergeConflictError): common_dtype([i8, u3]) assert common_dtype([i8, i8]).endswith('i8') assert common_dtype([i8, f8]).endswith('f8') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/test_misc.py0000644000175100001710000001210100000000000020607 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import json import locale import os import urllib.error from datetime import datetime import pytest import numpy as np from astropy.utils import data, misc from astropy.io import fits def test_isiterable(): assert misc.isiterable(2) is False assert misc.isiterable([2]) is True assert misc.isiterable([1, 2, 3]) is True assert misc.isiterable(np.array(2)) is False assert misc.isiterable(np.array([1, 2, 3])) is True def test_signal_number_to_name_no_failure(): # Regression test for #5340: ensure signal_number_to_name throws no # AttributeError (it used ".iteritems()" which was removed in Python3). misc.signal_number_to_name(0) @pytest.mark.remote_data def test_api_lookup(): try: strurl = misc.find_api_page('astropy.utils.misc', 'dev', False, timeout=5) objurl = misc.find_api_page(misc, 'dev', False, timeout=5) except urllib.error.URLError: if os.environ.get('CI', False): pytest.xfail('Timed out in CI') else: raise assert strurl == objurl assert strurl == 'http://devdocs.astropy.org/utils/index.html#module-astropy.utils.misc' # noqa # Try a non-dev version objurl = misc.find_api_page(misc, 'v3.2.1', False, timeout=3) assert objurl == 'https://docs.astropy.org/en/v3.2.1/utils/index.html#module-astropy.utils.misc' # noqa def test_skip_hidden(): path = data.get_pkg_data_path('data') for root, dirs, files in os.walk(path): assert '.hidden_file.txt' in files assert 'local.dat' in files # break after the first level since the data dir contains some other # subdirectories that don't have these files break for root, dirs, files in misc.walk_skip_hidden(path): assert '.hidden_file.txt' not in files assert 'local.dat' in files break def test_JsonCustomEncoder(): from astropy import units as u assert json.dumps(np.arange(3), cls=misc.JsonCustomEncoder) == '[0, 1, 2]' assert json.dumps(1+2j, cls=misc.JsonCustomEncoder) == '[1.0, 2.0]' assert json.dumps(set([1, 2, 1]), cls=misc.JsonCustomEncoder) == '[1, 2]' assert json.dumps(b'hello world \xc3\x85', cls=misc.JsonCustomEncoder) == '"hello world \\u00c5"' assert json.dumps({1: 2}, cls=misc.JsonCustomEncoder) == '{"1": 2}' # default assert json.dumps({1: u.m}, cls=misc.JsonCustomEncoder) == '{"1": "m"}' # Quantities tmp = json.dumps({'a': 5*u.cm}, cls=misc.JsonCustomEncoder) newd = json.loads(tmp) tmpd = {"a": {"unit": "cm", "value": 5.0}} assert newd == tmpd tmp2 = json.dumps({'a': np.arange(2)*u.cm}, cls=misc.JsonCustomEncoder) newd = json.loads(tmp2) tmpd = {"a": {"unit": "cm", "value": [0., 1.]}} assert newd == tmpd tmp3 = json.dumps({'a': np.arange(2)*u.erg/u.s}, cls=misc.JsonCustomEncoder) newd = json.loads(tmp3) tmpd = {"a": {"unit": "erg / s", "value": [0., 1.]}} assert newd == tmpd def test_JsonCustomEncoder_FITS_rec_from_files(): with fits.open(fits.util.get_testdata_filepath('variable_length_table.fits')) as hdul: assert json.dumps(hdul[1].data, cls=misc.JsonCustomEncoder) == \ "[[[45, 56], [11, 3]], [[11, 12, 13], [12, 4]]]" with fits.open(fits.util.get_testdata_filepath('btable.fits')) as hdul: assert json.dumps(hdul[1].data, cls=misc.JsonCustomEncoder) == \ '[[1, "Sirius", -1.4500000476837158, "A1V"], ' \ '[2, "Canopus", -0.7300000190734863, "F0Ib"], ' \ '[3, "Rigil Kent", -0.10000000149011612, "G2V"]]' with fits.open(fits.util.get_testdata_filepath('table.fits')) as hdul: assert json.dumps(hdul[1].data, cls=misc.JsonCustomEncoder) == \ '[["NGC1001", 11.100000381469727], ' \ '["NGC1002", 12.300000190734863], ' \ '["NGC1003", 15.199999809265137]]' def test_set_locale(): # First, test if the required locales are available current = locale.setlocale(locale.LC_ALL) try: locale.setlocale(locale.LC_ALL, 'en_US.utf8') locale.setlocale(locale.LC_ALL, 'fr_FR.utf8') except locale.Error as e: pytest.skip(f'Locale error: {e}') finally: locale.setlocale(locale.LC_ALL, current) date = datetime(2000, 10, 1, 0, 0, 0) day_mon = date.strftime('%a, %b') with misc._set_locale('en_US.utf8'): assert date.strftime('%a, %b') == 'Sun, Oct' with misc._set_locale('fr_FR.utf8'): assert date.strftime('%a, %b') == 'dim., oct.' # Back to original assert date.strftime('%a, %b') == day_mon with misc._set_locale(current): assert date.strftime('%a, %b') == day_mon def test_dtype_bytes_or_chars(): assert misc.dtype_bytes_or_chars(np.dtype(np.float64)) == 8 assert misc.dtype_bytes_or_chars(np.dtype(object)) is None assert misc.dtype_bytes_or_chars(np.dtype(np.int32)) == 4 assert misc.dtype_bytes_or_chars(np.array(b'12345').dtype) == 5 assert misc.dtype_bytes_or_chars(np.array('12345').dtype) == 5 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/test_parsing.py0000644000175100001710000000454100000000000021330 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import importlib import secrets import sys from textwrap import dedent import pytest from astropy.utils.parsing import lex, yacc, _TAB_HEADER def _docstring_canary(): """Docstring that's here just to check for -OO.""" @pytest.mark.skipif(not _docstring_canary.__doc__, reason="Test cannot be run with -OO") def test_generate_parser(tmp_path, monkeypatch): # Write Python code into the temporary directory, so that the # generated tables will also go into the temporary directory. # We use a unique suffix so that the test can be run multiple times # without weirdness due to module caching. suffix = secrets.token_hex(16) lexer_file = tmp_path / f'test_parsing_lexer_{suffix}.py' lexer_file.write_text(dedent(fr""" from astropy.utils.parsing import lex def make_lexer(): tokens = ('NUMBER', 'PLUS') t_PLUS = r'\+' def t_NUMBER(t): r'\d+' t.value = int(t.value) return t return lex('test_parsing_lextab_{suffix}', 'test_parsing_lexer_{suffix}') """)) parser_file = tmp_path / f'test_parsing_parser_{suffix}.py' parser_file.write_text(dedent(fr""" from astropy.utils.parsing import yacc def make_parser(): tokens = ('NUMBER', 'PLUS') def p_expression_number(p): 'expression : NUMBER' p[0] = p[1] def p_expression_plus(p): 'expression : expression PLUS NUMBER' p[0] = p[1] + p[3] return yacc('test_parsing_parsetab_{suffix}', 'test_parsing_parser_{suffix}') """)) monkeypatch.syspath_prepend(tmp_path) lexer_mod = importlib.import_module(f'test_parsing_lexer_{suffix}') lexer = lexer_mod.make_lexer() parser_mod = importlib.import_module(f'test_parsing_parser_{suffix}') parser = parser_mod.make_parser() result = parser.parse('1+2+3', lexer=lexer) assert result == 6 lextab = (tmp_path / f'test_parsing_lextab_{suffix}.py').read_text() assert lextab.startswith(_TAB_HEADER.format(package=f'test_parsing_lexer_{suffix}')) parsetab = (tmp_path / f'test_parsing_parsetab_{suffix}.py').read_text() assert parsetab.startswith(_TAB_HEADER.format(package=f'test_parsing_parser_{suffix}')) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/test_progress_bar_func.py0000644000175100001710000000111100000000000023356 0ustar00vstsdockerimport time import numpy as np from astropy.utils.misc import NumpyRNGContext def func(i): """An identity function that jitters its execution time by a pseudo-random amount. FIXME: This function should be defined in test_console.py, but Astropy's test runner interacts strangely with Python's `multiprocessing` module. I was getting a mysterious PicklingError until I moved this function into a separate module. (It worked fine in a standalone pytest script.)""" with NumpyRNGContext(i): time.sleep(np.random.uniform(0, 0.01)) return i ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/test_shapes.py0000644000175100001710000000140600000000000021145 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import pytest import numpy as np from astropy.utils.shapes import check_broadcast, unbroadcast def test_check_broadcast(): assert check_broadcast((10, 1), (3,)) == (10, 3) assert check_broadcast((10, 1), (3,), (4, 1, 1, 3)) == (4, 1, 10, 3) with pytest.raises(ValueError): check_broadcast((10, 2), (3,)) with pytest.raises(ValueError): check_broadcast((10, 1), (3,), (4, 1, 2, 3)) def test_unbroadcast(): x = np.array([1, 2, 3]) y = np.broadcast_to(x, (2, 4, 3)) z = unbroadcast(y) assert z.shape == (3,) np.testing.assert_equal(z, x) x = np.ones((3, 5)) y = np.broadcast_to(x, (5, 3, 5)) z = unbroadcast(y) assert z.shape == (3, 5) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/test_state.py0000644000175100001710000000113100000000000020775 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst from astropy.utils.state import ScienceState def test_ScienceState_and_Context(): """ Tests a ScienceState and spawned contexts. """ class MyState(ScienceState): _value = "A" _state = dict(foo="bar") state = {"foo": "bar"} # test created ScienceState assert MyState.get() == "A" assert MyState.validate("B") == "B" assert MyState._state == state # test setting with MyState.set("B"): assert MyState.get() == "B" assert MyState.get() == "A" # test returning ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/tests/test_xml.py0000644000175100001710000000614200000000000020464 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import io import pytest from astropy.utils.xml import check, unescaper, writer from astropy.utils.compat.optional_deps import HAS_BLEACH # noqa def test_writer(): fh = io.StringIO() w = writer.XMLWriter(fh) with w.tag("html"): with w.tag("body"): w.data("This is the content") w.comment("comment") value = ''.join(fh.getvalue().split()) assert value == 'Thisisthecontent' def test_check_id(): assert check.check_id("Fof32") assert check.check_id("_Fof32") assert not check.check_id("32Fof") def test_fix_id(): assert check.fix_id("Fof32") == "Fof32" assert check.fix_id("@#f") == "___f" def test_check_token(): assert check.check_token("token") assert not check.check_token("token\rtoken") def test_check_mime_content_type(): assert check.check_mime_content_type("image/jpeg") assert not check.check_mime_content_type("image") def test_check_anyuri(): assert check.check_anyuri("https://github.com/astropy/astropy") def test_unescape_all(): # str url_in = 'http://casu.ast.cam.ac.uk/ag/iphas-dsa%2FSubmitCone?' \ 'DSACAT=IDR&amp;DSATAB=Emitters&amp;' url_out = 'http://casu.ast.cam.ac.uk/ag/iphas-dsa/SubmitCone?' \ 'DSACAT=IDR&DSATAB=Emitters&' assert unescaper.unescape_all(url_in) == url_out # bytes url_in = b'http://casu.ast.cam.ac.uk/ag/iphas-dsa%2FSubmitCone?' \ b'DSACAT=IDR&amp;DSATAB=Emitters&amp;' url_out = b'http://casu.ast.cam.ac.uk/ag/iphas-dsa/SubmitCone?' \ b'DSACAT=IDR&DSATAB=Emitters&' assert unescaper.unescape_all(url_in) == url_out def test_escape_xml(): s = writer.xml_escape('This & That') assert type(s) == str assert s == 'This & That' s = writer.xml_escape(1) assert type(s) == str assert s == '1' s = writer.xml_escape(b'This & That') assert type(s) == bytes assert s == b'This & That' @pytest.mark.skipif('HAS_BLEACH') def test_escape_xml_without_bleach(): fh = io.StringIO() w = writer.XMLWriter(fh) with pytest.raises(ValueError) as err: with w.xml_cleaning_method('bleach_clean'): pass assert 'bleach package is required when HTML escaping is disabled' in str(err.value) @pytest.mark.skipif('not HAS_BLEACH') def test_escape_xml_with_bleach(): fh = io.StringIO() w = writer.XMLWriter(fh) # Turn off XML escaping, but still sanitize unsafe tags like OK') w.end(indent=False) assert fh.getvalue() == '<script>x</script> OK\n' fh = io.StringIO() w = writer.XMLWriter(fh) # Default is True (all XML tags escaped) with w.xml_cleaning_method(): w.start('td') w.data(' OK') w.end(indent=False) assert fh.getvalue() == '<script>x</script> <em>OK</em>\n' ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2112553 astropy-5.0.2/astropy/utils/xml/0000755000175100001710000000000000000000000015706 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/xml/__init__.py0000644000175100001710000000000000000000000020005 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/xml/check.py0000644000175100001710000000411400000000000017335 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ A collection of functions for checking various XML-related strings for standards compliance. """ import re import urllib.parse def check_id(ID): """ Returns `True` if *ID* is a valid XML ID. """ return re.match(r"^[A-Za-z_][A-Za-z0-9_\.\-]*$", ID) is not None def fix_id(ID): """ Given an arbitrary string, create one that can be used as an xml id. This is rather simplistic at the moment, since it just replaces non-valid characters with underscores. """ if re.match(r"^[A-Za-z_][A-Za-z0-9_\.\-]*$", ID): return ID if len(ID): corrected = ID if not len(corrected) or re.match('^[^A-Za-z_]$', corrected[0]): corrected = '_' + corrected corrected = (re.sub(r"[^A-Za-z_]", '_', corrected[0]) + re.sub(r"[^A-Za-z0-9_\.\-]", "_", corrected[1:])) return corrected return '' _token_regex = r"(?![\r\l\t ])[^\r\l\t]*(?![\r\l\t ])" def check_token(token): """ Returns `True` if *token* is a valid XML token, as defined by XML Schema Part 2. """ return (token == '' or re.match( r"[^\r\n\t ]?([^\r\n\t ]| [^\r\n\t ])*[^\r\n\t ]?$", token) is not None) def check_mime_content_type(content_type): """ Returns `True` if *content_type* is a valid MIME content type (syntactically at least), as defined by RFC 2045. """ ctrls = ''.join(chr(x) for x in range(0, 0x20)) token_regex = f'[^()<>@,;:\\\"/[\\]?= {ctrls}\x7f]+' return re.match( fr'(?P{token_regex})/(?P{token_regex})$', content_type) is not None def check_anyuri(uri): """ Returns `True` if *uri* is a valid URI as defined in RFC 2396. """ if (re.match( (r"(([a-zA-Z][0-9a-zA-Z+\-\.]*:)?/{0,2}[0-9a-zA-Z;" + r"/?:@&=+$\.\-_!~*'()%]+)?(#[0-9a-zA-Z;/?:@&=+$\.\-_!~*'()%]+)?"), uri) is None): return False try: urllib.parse.urlparse(uri) except Exception: return False return True ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/xml/iterparser.py0000644000175100001710000001364300000000000020447 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This module includes a fast iterator-based XML parser. """ # STDLIB import contextlib import io import sys # ASTROPY from astropy.utils import data __all__ = ['get_xml_iterator', 'get_xml_encoding', 'xml_readlines'] @contextlib.contextmanager def _convert_to_fd_or_read_function(fd): """ Returns a function suitable for streaming input, or a file object. This function is only useful if passing off to C code where: - If it's a real file object, we want to use it as a real C file object to avoid the Python overhead. - If it's not a real file object, it's much handier to just have a Python function to call. This is somewhat quirky behavior, of course, which is why it is private. For a more useful version of similar behavior, see `astropy.utils.misc.get_readable_fileobj`. Parameters ---------- fd : object May be: - a file object. If the file is uncompressed, this raw file object is returned verbatim. Otherwise, the read method is returned. - a function that reads from a stream, in which case it is returned verbatim. - a file path, in which case it is opened. Again, like a file object, if it's uncompressed, a raw file object is returned, otherwise its read method. - an object with a :meth:`read` method, in which case that method is returned. Returns ------- fd : context-dependent See above. """ if callable(fd): yield fd return with data.get_readable_fileobj(fd, encoding='binary') as new_fd: if sys.platform.startswith('win'): yield new_fd.read else: if isinstance(new_fd, io.FileIO): yield new_fd else: yield new_fd.read def _fast_iterparse(fd, buffersize=2 ** 10): from xml.parsers import expat if not callable(fd): read = fd.read else: read = fd queue = [] text = [] def start(name, attr): queue.append((True, name, attr, (parser.CurrentLineNumber, parser.CurrentColumnNumber))) del text[:] def end(name): queue.append((False, name, ''.join(text).strip(), (parser.CurrentLineNumber, parser.CurrentColumnNumber))) parser = expat.ParserCreate() parser.specified_attributes = True parser.StartElementHandler = start parser.EndElementHandler = end parser.CharacterDataHandler = text.append Parse = parser.Parse data = read(buffersize) while data: Parse(data, False) for elem in queue: yield elem del queue[:] data = read(buffersize) Parse('', True) for elem in queue: yield elem # Try to import the C version of the iterparser, otherwise fall back # to the Python implementation above. _slow_iterparse = _fast_iterparse try: from . import _iterparser _fast_iterparse = _iterparser.IterParser except ImportError: pass @contextlib.contextmanager def get_xml_iterator(source, _debug_python_based_parser=False): """ Returns an iterator over the elements of an XML file. The iterator doesn't ever build a tree, so it is much more memory and time efficient than the alternative in ``cElementTree``. Parameters ---------- source : path-like, readable file-like, or callable Handle that contains the data or function that reads it. If a function or callable object, it must directly read from a stream. Non-callable objects must define a ``read`` method. Returns ------- parts : iterator The iterator returns 4-tuples (*start*, *tag*, *data*, *pos*): - *start*: when `True` is a start element event, otherwise an end element event. - *tag*: The name of the element - *data*: Depends on the value of *event*: - if *start* == `True`, data is a dictionary of attributes - if *start* == `False`, data is a string containing the text content of the element - *pos*: Tuple (*line*, *col*) indicating the source of the event. """ with _convert_to_fd_or_read_function(source) as fd: if _debug_python_based_parser: context = _slow_iterparse(fd) else: context = _fast_iterparse(fd) yield iter(context) def get_xml_encoding(source): """ Determine the encoding of an XML file by reading its header. Parameters ---------- source : path-like, readable file-like, or callable Handle that contains the data or function that reads it. If a function or callable object, it must directly read from a stream. Non-callable objects must define a ``read`` method. Returns ------- encoding : str """ with get_xml_iterator(source) as iterator: start, tag, data, pos = next(iterator) if not start or tag != 'xml': raise OSError('Invalid XML file') # The XML spec says that no encoding === utf-8 return data.get('encoding') or 'utf-8' def xml_readlines(source): """ Get the lines from a given XML file. Correctly determines the encoding and always returns unicode. Parameters ---------- source : path-like, readable file-like, or callable Handle that contains the data or function that reads it. If a function or callable object, it must directly read from a stream. Non-callable objects must define a ``read`` method. Returns ------- lines : list of unicode """ encoding = get_xml_encoding(source) with data.get_readable_fileobj(source, encoding=encoding) as input: input.seek(0) xml_lines = input.readlines() return xml_lines ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/xml/setup_package.py0000644000175100001710000000311500000000000021073 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import os from collections import defaultdict from setuptools import Extension from os.path import join import sys from extension_helpers import pkg_config def get_extensions(build_type='release'): XML_DIR = 'astropy/utils/xml/src' cfg = defaultdict(list) cfg['sources'] = [join(XML_DIR, "iterparse.c")] if (int(os.environ.get('ASTROPY_USE_SYSTEM_EXPAT', 0)) or int(os.environ.get('ASTROPY_USE_SYSTEM_ALL', 0))): for k, v in pkg_config(['expat'], ['expat']).items(): cfg[k].extend(v) else: EXPAT_DIR = 'cextern/expat/lib' cfg['sources'].extend([ join(EXPAT_DIR, fn) for fn in ["xmlparse.c", "xmlrole.c", "xmltok.c", "xmltok_impl.c"]]) cfg['include_dirs'].extend([XML_DIR, EXPAT_DIR]) if sys.platform.startswith('linux'): # This is to ensure we only export the Python entry point # symbols and the linker won't try to use the system expat in # place of ours. cfg['extra_link_args'].extend([ f"-Wl,--version-script={join(XML_DIR, 'iterparse.map')}" ]) cfg['define_macros'].append(("HAVE_EXPAT_CONFIG_H", 1)) if sys.byteorder == 'big': cfg['define_macros'].append(('BYTEORDER', '4321')) else: cfg['define_macros'].append(('BYTEORDER', '1234')) if sys.platform != 'win32': cfg['define_macros'].append(('HAVE_UNISTD_H', None)) return [Extension("astropy.utils.xml._iterparser", **cfg)] ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2112553 astropy-5.0.2/astropy/utils/xml/src/0000755000175100001710000000000000000000000016475 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/xml/src/.gitignore0000644000175100001710000000000500000000000020460 0ustar00vstsdocker!*.c ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/xml/src/expat_config.h0000644000175100001710000000737400000000000021327 0ustar00vstsdocker/* expat_config.h. Generated from expat_config.h.in by configure. */ /* expat_config.h.in. Generated from configure.ac by autoheader. */ /* Define if building universal (internal helper macro) */ /* #undef AC_APPLE_UNIVERSAL_BUILD */ /* 1234 = LILENDIAN, 4321 = BIGENDIAN */ #define BYTEORDER 1234 /* Define to 1 if you have the `arc4random' function. */ /* #undef HAVE_ARC4RANDOM */ /* Define to 1 if you have the `arc4random_buf' function. */ /* #undef HAVE_ARC4RANDOM_BUF */ /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 /* Define to 1 if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define to 1 if you have the `getpagesize' function. */ #define HAVE_GETPAGESIZE 1 /* Define to 1 if you have the `getrandom' function. */ /* #undef HAVE_GETRANDOM */ /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the `bsd' library (-lbsd). */ /* #undef HAVE_LIBBSD */ /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have a working `mmap' system call. */ #define HAVE_MMAP 1 /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have `syscall' and `SYS_getrandom'. */ /* #undef HAVE_SYSCALL_GETRANDOM */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_PARAM_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to the sub-directory where libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" /* Name of package */ #define PACKAGE "expat" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "expat-bugs@libexpat.org" /* Define to the full name of this package. */ #define PACKAGE_NAME "expat" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "expat 2.2.9" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "expat" /* Define to the home page for this package. */ #define PACKAGE_URL "" /* Define to the version of this package. */ #define PACKAGE_VERSION "2.2.9" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ #define VERSION "2.2.9" /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN /* # undef WORDS_BIGENDIAN */ # endif #endif /* Define to allow retrieving the byte offsets for attribute names and values. */ /* #undef XML_ATTR_INFO */ /* Define to specify how much context to retain around the current parse point. */ #define XML_CONTEXT_BYTES 1024 /* Define to include code reading entropy from `/dev/urandom'. */ #define XML_DEV_URANDOM 1 /* Define to make parameter entity parsing functionality available. */ #define XML_DTD 1 /* Define to make XML Namespaces functionality available. */ #define XML_NS 1 /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Define to `long int' if does not define. */ /* #undef off_t */ /* Define to `unsigned int' if does not define. */ /* #undef size_t */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/xml/src/iterparse.c0000644000175100001710000011474700000000000020655 0ustar00vstsdocker/****************************************************************************** * C extension code for astropy.utils.xml.iterparse * * Everything in this file has an alternate Python implementation and * is included for performance reasons only. * * It has two main parts: * * - An IterParser object which parses an XML file using the expat * library, feeding expat events through a Python iterator. It is * faster and more memory efficient than the alternatives in the * Python standard library because it does not build a tree of * objects, and also throws away most text nodes, since for * astropy.io.votable (the primary user of this library) we only * care about simple text nodes contained between a single pair of * open/close element nodes. It also has an optimization for * recognizing the most commonly occurring element in a VO file, * "TD". * * - Two functions, escape_xml() and escape_xml_cdata() that escape * XML much faster than the alternatives in the Python standard * library. ******************************************************************************/ #include #include #include "structmember.h" #include "expat.h" /****************************************************************************** * Convenience macros and functions ******************************************************************************/ #ifdef _MSC_VER #define inline #endif #undef CLAMP #define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) static Py_ssize_t next_power_of_2(Py_ssize_t n) { /* Calculate the next-higher power of two that is >= 'n' */ /* These instructions are intended for uint32_t and originally from http://www-graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 Py_ssize_t is the same as the C datatype ssize_t and is 32/64-bits on 32-bit and 64-bit systems respectively. The implementation here accounts for both. Limitations: Since a signed size_t (ssize_t) was required for the underlying CPython implementation, on 32 bit systems, it will not be possible to allocate memory sizes between SSIZE_MAX and SIZE_MAX (i.e, for allocations in the range [2^31, 2^32 - 1] bytes) even though such memory might be available and accessible on the (32-bit) computer. That said, since the underlying CPython implementation *also* uses Py_ssize_t (i.e., ssize_t), it is safe to assume that such memory allocations would probably not be usable anyway. TLDR: Will work on 64-bit machines but be careful on 32 bit machines when reading in ~ 2+ GB of memory -- @manodeep 2020-03-27 */ n--; n |= n >> 1; n |= n >> 2; n |= n >> 4; n |= n >> 8; n |= n >> 16; if(sizeof(Py_ssize_t) > 4) { n |= n >> 32; /* this works for 64-bit systems but will need to be updated if (Py)_ssize_t ever increases beyond 64-bits */ } n++; return n; } /****************************************************************************** * Python version compatibility macros ******************************************************************************/ #if BYTEORDER == 1234 # define TD_AS_INT 0x00004454 # define TD_AS_INT_MASK 0x00ffffff #else # define TD_AS_INT 0x54440000 # define TD_AS_INT_MASK 0xffffff00 #endif /* Clang doesn't like the hackish stuff PyTuple_SET_ITEM does... */ #ifdef __clang__ #undef PyTuple_SET_ITEM #define PyTuple_SET_ITEM(a, b, c) PyTuple_SetItem((a), (b), (c)) #endif /****************************************************************************** * IterParser type ******************************************************************************/ typedef struct { PyObject_HEAD XML_Parser parser; /* The expat parser */ int done; /* True when expat parser has read to EOF */ /* File-like object reading */ PyObject* fd; /* Python file object */ int file; /* C file descriptor */ PyObject* read; /* The read method on the file object */ Py_ssize_t buffersize; /* The size of the read buffer */ XML_Char* buffer; /* The read buffer */ /* Text nodes */ Py_ssize_t text_alloc; /* The allocated size of the text buffer */ Py_ssize_t text_size; /* The size of the content in the text buffer */ XML_Char* text; /* Text buffer (for returning text nodes) */ int keep_text; /* Flag: keep appending text chunks to the current text node */ /* XML event queue */ PyObject** queue; Py_ssize_t queue_size; Py_ssize_t queue_read_idx; Py_ssize_t queue_write_idx; /* Store the last Python exception so it can be returned when dequeing events */ PyObject* error_type; PyObject* error_value; PyObject* error_traceback; /* Store the position for any XML exceptions that may be returned later */ unsigned long last_line; unsigned long last_col; /* "Constants" for efficiency */ PyObject* dict_singleton; /* Empty dict */ PyObject* td_singleton; /* String "TD" */ PyObject* read_args; /* (buffersize) */ } IterParser; /****************************************************************************** * Tuple queue ******************************************************************************/ /** * Extend the tuple queue based on the new length of the textual XML input. * This helps to cope with situations where the input is longer than * requested (as occurs with transparent decompression of the input * stream), and for the initial allocation to combine the logic in one place. */ static int queue_realloc(IterParser *self, Py_ssize_t req_size) { PyObject** new_queue; Py_ssize_t n = req_size / 2; if (n <= self->queue_size) return 0; new_queue = realloc(self->queue, sizeof(PyObject*) * (size_t)n); if (new_queue == NULL) { PyErr_SetString(PyExc_MemoryError, "Out of memory for XML parsing queue."); /* * queue_realloc() is only called from IterParser_init() or * IterParser_next() in situations where the queue is clear * and empty. If this function were to be used in other * situations it would be wise to iterate over the queue and * clear/decrement the individual references, to save work for * the garbage collector (in an out-of-memory situation). */ goto fail; } self->queue = new_queue; self->queue_size = n; return 0; fail: free(self->queue); self->queue = NULL; self->queue_size = 0; return -1; } /****************************************************************************** * Text buffer ******************************************************************************/ /** * Reallocate text buffer to the next highest power of two that fits the * requested size. */ static int text_realloc(IterParser *self, Py_ssize_t req_size) { Py_ssize_t n = req_size; char *new_mem = NULL; if (req_size < self->text_alloc) { return 0; } /* Calculate the next-highest power of two */ n = next_power_of_2(n); if (n < req_size) { PyErr_SetString(PyExc_MemoryError, "Out of memory for XML text."); return -1; } new_mem = malloc(n * sizeof(XML_Char)); if (new_mem == NULL) { PyErr_SetString(PyExc_MemoryError, "Out of memory for XML text."); return -1; } memcpy(new_mem, self->text, (size_t)(self->text_size + 1) * sizeof(XML_Char)); free(self->text); self->text = new_mem; self->text_alloc = n; return 0; } #define IS_WHITESPACE(c) ((c) == (XML_Char)0x20 || \ (c) == (XML_Char)0x0d || \ (c) == (XML_Char)0x0a || \ (c) == (XML_Char)0x09) /* * Append text to the text buffer. * * For the first chunk of text, all whitespace characters before the * first non-whitespace character are stripped. This saves time * stripping on the Python side later. */ static int text_append(IterParser *self, const XML_Char *data, Py_ssize_t len) { Py_ssize_t new_size; if (len == 0) { return 0; } /* If this is the first chunk, handle whitespace */ if (self->text_size == 0) { while (len && IS_WHITESPACE(*data)) { ++data; --len; } } /* Grow text buffer if necessary */ new_size = self->text_size + len; if (text_realloc(self, new_size + 1)) { return -1; } memcpy(self->text + self->text_size, data, (size_t)len * sizeof(XML_Char)); self->text_size = new_size; self->text[self->text_size] = (XML_Char)0x0; return 0; } /* * Erase all content from the text buffer. */ static void text_clear(IterParser *self) { self->text[0] = (XML_Char)0; self->text_size = 0; } /****************************************************************************** * XML event handling ******************************************************************************/ /* * Make a "position tuple" from the current expat parser state. This * is used to communicate the position of the parser within the file * to the Python side for generation of meaningful error messages. * * It is of the form (line, col), where line and col are both PyInts. */ static inline PyObject* make_pos(const IterParser *self) { return Py_BuildValue( "(nn)", (size_t)self->last_line, (size_t)self->last_col); } /* * Removes the namespace from an element or attribute name, that is, * remove everything before the first colon. The namespace is not * needed to parse standards-compliant VOTable files. * * The returned pointer is an internal pointer to the buffer passed * in. */ static const XML_Char * remove_namespace(const XML_Char *name) { const XML_Char* name_start = NULL; /* If there is a namespace specifier, just chop it off */ for (name_start = name; *name_start != '\0'; ++name_start) { if (*name_start == ':') { break; } } if (*name_start == ':') { ++name_start; } else { name_start = name; } return name_start; } /* * Handle the expat startElement event. */ static void startElement(IterParser *self, const XML_Char *name, const XML_Char **atts) { PyObject* pyname = NULL; PyObject* pyatts = NULL; const XML_Char** att_ptr = atts; const XML_Char* name_start = NULL; PyObject* tuple = NULL; PyObject* key = NULL; PyObject* val = NULL; PyObject* pos = NULL; /* If we've already had an error in a previous call, don't make things worse. */ if (PyErr_Occurred() != NULL) { XML_StopParser(self->parser, 0); return; } /* Don't overflow the queue -- in practice this should *never* happen */ if (self->queue_write_idx < self->queue_size) { tuple = PyTuple_New(4); if (tuple == NULL) { goto fail; } Py_INCREF(Py_True); PyTuple_SET_ITEM(tuple, 0, Py_True); /* This is an egregious but effective optimization. Since by far the most frequently occurring element name in a large VOTABLE file is TD, we explicitly check for it here with integer comparison to avoid the lookup in the interned string table in PyString_InternFromString, and return a singleton string for "TD" */ if ((*(int*)name & TD_AS_INT_MASK) == TD_AS_INT) { Py_INCREF(self->td_singleton); PyTuple_SetItem(tuple, 1, self->td_singleton); } else { name_start = remove_namespace(name); pyname = PyUnicode_FromString(name_start); if (pyname == NULL) { goto fail; } PyTuple_SetItem(tuple, 1, pyname); pyname = NULL; } if (*att_ptr) { pyatts = PyDict_New(); if (pyatts == NULL) { goto fail; } do { key = PyUnicode_FromString(*att_ptr); if (key == NULL) { goto fail; } val = PyUnicode_FromString(*(att_ptr + 1)); if (val == NULL) { Py_DECREF(key); goto fail; } if (PyDict_SetItem(pyatts, key, val)) { Py_DECREF(key); Py_DECREF(val); goto fail; } Py_DECREF(key); Py_DECREF(val); key = val = NULL; att_ptr += 2; } while (*att_ptr); } else { Py_INCREF(self->dict_singleton); pyatts = self->dict_singleton; } PyTuple_SetItem(tuple, 2, pyatts); pyatts = NULL; self->last_line = (unsigned long)XML_GetCurrentLineNumber( self->parser); self->last_col = (unsigned long)XML_GetCurrentColumnNumber( self->parser); pos = make_pos(self); if (pos == NULL) { goto fail; } PyTuple_SetItem(tuple, 3, pos); pos = NULL; text_clear(self); self->keep_text = 1; self->queue[self->queue_write_idx++] = tuple; } else { PyErr_SetString( PyExc_RuntimeError, "XML queue overflow in startElement. This most likely indicates an internal bug."); goto fail; } return; fail: Py_XDECREF(tuple); Py_XDECREF(pyatts); XML_StopParser(self->parser, 0); } /* * Handle the expat endElement event. */ static void endElement(IterParser *self, const XML_Char *name) { PyObject* pyname = NULL; PyObject* tuple = NULL; PyObject* pytext = NULL; const XML_Char* name_start = NULL; XML_Char* end; PyObject* pos = NULL; /* If we've already had an error in a previous call, don't make things worse. */ if (PyErr_Occurred() != NULL) { XML_StopParser(self->parser, 0); return; } /* Don't overflow the queue -- in practice this should *never* happen */ if (self->queue_write_idx < self->queue_size) { tuple = PyTuple_New(4); if (tuple == NULL) { goto fail; } Py_INCREF(Py_False); PyTuple_SET_ITEM(tuple, 0, Py_False); /* This is an egregious but effective optimization. Since by far the most frequently occurring element name in a large VOTABLE file is TD, we explicitly check for it here with integer comparison to avoid the lookup in the interned string table in PyString_InternFromString, and return a singleton string for "TD" */ if ((*(int*)name & TD_AS_INT_MASK) == TD_AS_INT) { Py_INCREF(self->td_singleton); PyTuple_SetItem(tuple, 1, self->td_singleton); } else { name_start = remove_namespace(name); pyname = PyUnicode_FromString(name_start); if (pyname == NULL) { goto fail; } PyTuple_SetItem(tuple, 1, pyname); pyname = NULL; } /* Cut whitespace off the end of the string */ end = self->text + self->text_size - 1; while (end >= self->text && IS_WHITESPACE(*end)) { --end; --self->text_size; } pytext = PyUnicode_FromStringAndSize(self->text, self->text_size); if (pytext == NULL) { goto fail; } PyTuple_SetItem(tuple, 2, pytext); pytext = NULL; pos = make_pos(self); if (pos == NULL) { goto fail; } PyTuple_SetItem(tuple, 3, pos); pos = NULL; self->keep_text = 0; self->queue[self->queue_write_idx++] = tuple; } else { PyErr_SetString( PyExc_RuntimeError, "XML queue overflow in endElement. This most likely indicates an internal bug."); goto fail; } return; fail: Py_XDECREF(tuple); XML_StopParser(self->parser, 0); } /* * Handle the expat characterData event. */ static void characterData(IterParser *self, const XML_Char *text, int len) { /* If we've already had an error in a previous call, don't make things worse. */ if (PyErr_Occurred() != NULL) { XML_StopParser(self->parser, 0); return; } if (self->text_size == 0) { self->last_line = (unsigned long)XML_GetCurrentLineNumber( self->parser); self->last_col = (unsigned long)XML_GetCurrentColumnNumber( self->parser); } if (self->keep_text) { (void)text_append(self, text, (Py_ssize_t)len); } } /* * Handle the XML declaration so that we can determine its encoding. */ static void xmlDecl(IterParser *self, const XML_Char *version, const XML_Char *encoding, int standalone) { PyObject* tuple = NULL; PyObject* xml_str = NULL; PyObject* attrs = NULL; PyObject* encoding_str = NULL; PyObject* version_str = NULL; PyObject* pos = NULL; if (self->queue_write_idx < self->queue_size) { tuple = PyTuple_New(4); if (tuple == NULL) { goto fail; } Py_INCREF(Py_True); PyTuple_SET_ITEM(tuple, 0, Py_True); xml_str = PyUnicode_FromString("xml"); if (xml_str == NULL) { goto fail; } PyTuple_SET_ITEM(tuple, 1, xml_str); xml_str = NULL; attrs = PyDict_New(); if (attrs == NULL) { goto fail; } if (encoding) { encoding_str = PyUnicode_FromString(encoding); } else { encoding_str = PyUnicode_FromString(""); } if (encoding_str == NULL) { goto fail; } if (PyDict_SetItemString(attrs, "encoding", encoding_str)) { Py_DECREF(encoding_str); goto fail; } Py_DECREF(encoding_str); encoding_str = NULL; if (version) { version_str = PyUnicode_FromString(version); } else { version_str = PyUnicode_FromString(""); } if (version_str == NULL) { goto fail; } if (PyDict_SetItemString(attrs, "version", version_str)) { Py_DECREF(version_str); goto fail; } Py_DECREF(version_str); version_str = NULL; PyTuple_SET_ITEM(tuple, 2, attrs); attrs = NULL; self->last_line = (unsigned long)XML_GetCurrentLineNumber( self->parser); self->last_col = (unsigned long)XML_GetCurrentColumnNumber( self->parser); pos = make_pos(self); if (pos == NULL) { goto fail; } PyTuple_SetItem(tuple, 3, pos); pos = NULL; self->queue[self->queue_write_idx++] = tuple; } else { PyErr_SetString( PyExc_RuntimeError, "XML queue overflow in xmlDecl. This most likely indicates an internal bug."); goto fail; } return; fail: Py_XDECREF(tuple); Py_XDECREF(attrs); XML_StopParser(self->parser, 0); } /* * The object itself is an iterator, just return self for "iter(self)" * on the Python side. */ static PyObject * IterParser_iter(IterParser* self) { Py_INCREF(self); return (PyObject*) self; } /* * Get the next element from the iterator. * * The expat event handlers above (startElement, endElement, characterData) add * elements to the queue, which are then dequeued by this method. * * Care must be taken to store and later raise exceptions. Any * exceptions raised in the expat callbacks must be stored and then * later thrown once the queue is emptied, otherwise the exception is * raised "too early" in queue order. */ static PyObject * IterParser_next(IterParser* self) { PyObject* data = NULL; XML_Char* buf; Py_ssize_t buflen; /* Is there anything in the queue to return? */ if (self->queue_read_idx < self->queue_write_idx) { return self->queue[self->queue_read_idx++]; } /* Now that the queue is empty, is there an error we need to raise? */ if (self->error_type) { PyErr_Restore(self->error_type, self->error_value, self->error_traceback); self->error_type = NULL; self->error_value = NULL; self->error_traceback = NULL; return NULL; } /* The queue is empty -- have we already fed the entire file to expat? If so, we are done and indicate the end of the iterator by simply returning NULL. */ if (self->done) { return NULL; } self->queue_read_idx = 0; self->queue_write_idx = 0; do { /* Handle a generic Python read method */ if (self->read) { data = PyObject_CallObject(self->read, self->read_args); if (data == NULL) { goto fail; } if (PyBytes_AsStringAndSize(data, &buf, &buflen) == -1) { Py_DECREF(data); goto fail; } if (buflen < self->buffersize) { /* EOF detection method only works for local regular files */ self->done = 1; } /* Handle a real C file descriptor or handle -- this is faster if we've got one. */ } else { buflen = (Py_ssize_t)read( self->file, self->buffer, (size_t)self->buffersize); if (buflen == -1) { PyErr_SetFromErrno(PyExc_OSError); goto fail; } else if (buflen < self->buffersize) { /* EOF detection method only works for local regular files */ self->done = 1; } buf = self->buffer; } if(queue_realloc(self, buflen)) { Py_XDECREF(data); goto fail; } /* Feed the read buffer to expat, which will call the event handlers */ if (XML_Parse(self->parser, buf, (int)buflen, self->done) == XML_STATUS_ERROR) { /* One of the event handlers raised a Python error, make note of it -- it won't be thrown until the queue is emptied. */ if (PyErr_Occurred() != NULL) { goto fail; } /* expat raised an error, make note of it -- it won't be thrown until the queue is emptied. */ Py_XDECREF(data); PyErr_Format( PyExc_ValueError, "%lu:%lu: %s", XML_GetCurrentLineNumber(self->parser), XML_GetCurrentColumnNumber(self->parser), XML_ErrorString(XML_GetErrorCode(self->parser))); goto fail; } Py_XDECREF(data); if (PyErr_Occurred() != NULL) { goto fail; } } while (self->queue_write_idx == 0 && self->done == 0); if (self->queue_write_idx == 0) { return NULL; } if (self->queue_write_idx >= self->queue_size) { PyErr_SetString( PyExc_RuntimeError, "XML queue overflow. This most likely indicates an internal bug."); return NULL; } return self->queue[self->queue_read_idx++]; fail: /* We got an exception somewhere along the way. Store the exception in the IterParser object, but clear the exception in the Python interpreter, so we can empty the event queue and raise the exception later. */ PyErr_Fetch(&self->error_type, &self->error_value, &self->error_traceback); PyErr_Clear(); if (self->queue_read_idx < self->queue_write_idx) { return self->queue[self->queue_read_idx++]; } PyErr_Restore(self->error_type, self->error_value, self->error_traceback); self->error_type = NULL; self->error_value = NULL; self->error_traceback = NULL; return NULL; } /****************************************************************************** * IterParser object lifetime ******************************************************************************/ /* To support cyclical garbage collection, all PyObject's must be visited. */ static int IterParser_traverse(IterParser *self, visitproc visit, void *arg) { int vret; Py_ssize_t read_index; read_index = self->queue_read_idx; while (read_index < self->queue_write_idx) { vret = visit(self->queue[read_index++], arg); if (vret != 0) return vret; } if (self->fd) { vret = visit(self->fd, arg); if (vret != 0) return vret; } if (self->read) { vret = visit(self->read, arg); if (vret != 0) return vret; } if (self->read_args) { vret = visit(self->read_args, arg); if (vret != 0) return vret; } if (self->dict_singleton) { vret = visit(self->dict_singleton, arg); if (vret != 0) return vret; } if (self->td_singleton) { vret = visit(self->td_singleton, arg); if (vret != 0) return vret; } if (self->error_type) { vret = visit(self->error_type, arg); if (vret != 0) return vret; } if (self->error_value) { vret = visit(self->error_value, arg); if (vret != 0) return vret; } if (self->error_traceback) { vret = visit(self->error_traceback, arg); if (vret != 0) return vret; } return 0; } /* To support cyclical garbage collection */ static int IterParser_clear(IterParser *self) { PyObject *tmp; while (self->queue_read_idx < self->queue_write_idx) { tmp = self->queue[self->queue_read_idx]; self->queue[self->queue_read_idx] = NULL; Py_XDECREF(tmp); self->queue_read_idx++; } tmp = self->fd; self->fd = NULL; Py_XDECREF(tmp); tmp = self->read; self->read = NULL; Py_XDECREF(tmp); tmp = self->read_args; self->read_args = NULL; Py_XDECREF(tmp); tmp = self->dict_singleton; self->dict_singleton = NULL; Py_XDECREF(tmp); tmp = self->td_singleton; self->td_singleton = NULL; Py_XDECREF(tmp); tmp = self->error_type; self->error_type = NULL; Py_XDECREF(tmp); tmp = self->error_value; self->error_value = NULL; Py_XDECREF(tmp); tmp = self->error_traceback; self->error_traceback = NULL; Py_XDECREF(tmp); return 0; } /* * Deallocate the IterParser object. For the internal PyObject*, just * punt to IterParser_clear. */ static void IterParser_dealloc(IterParser* self) { IterParser_clear(self); free(self->buffer); self->buffer = NULL; free(self->queue); self->queue = NULL; free(self->text); self->text = NULL; if (self->parser != NULL) { XML_ParserFree(self->parser); self->parser = NULL; } Py_TYPE(self)->tp_free((PyObject*)self); } /* * Initialize the memory for an IterParser object */ static PyObject * IterParser_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { IterParser *self = NULL; self = (IterParser *)type->tp_alloc(type, 0); if (self != NULL) { self->parser = NULL; self->fd = NULL; self->file = -1; self->read = NULL; self->read_args = NULL; self->dict_singleton = NULL; self->td_singleton = NULL; self->buffersize = 0; self->buffer = NULL; self->queue_read_idx = 0; self->queue_write_idx = 0; self->text_alloc = 0; self->text_size = 0; self->text = NULL; self->keep_text = 0; self->done = 0; self->queue_size = 0; self->queue = NULL; self->error_type = NULL; self->error_value = NULL; self->error_traceback = NULL; } return (PyObject *)self; } /* * Initialize an IterParser object * * The Python arguments are: * * *fd*: A Python file object or a callable object * *buffersize*: The size of the read buffer */ static int IterParser_init(IterParser *self, PyObject *args, PyObject *kwds) { PyObject* fd = NULL; PyObject* read = NULL; Py_ssize_t buffersize = 1 << 14; static char *kwlist[] = {"fd", "buffersize", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:IterParser.__init__", kwlist, &fd, &buffersize)) { return -1; } /* Keep the buffersize within a reasonable range */ self->buffersize = CLAMP(buffersize, (Py_ssize_t)(1 << 10), (Py_ssize_t)(1 << 24)); #ifdef __clang__ /* Clang can't handle the file descriptors Python gives us, so in that case, we just call the object's read method. */ read = PyObject_GetAttrString(fd, "read"); if (read != NULL) { fd = read; } #else self->file = PyObject_AsFileDescriptor(fd); if (self->file != -1) { /* This is a real C file handle or descriptor. We therefore need to allocate our own read buffer, and get the real C object. */ self->buffer = malloc((size_t)self->buffersize); if (self->buffer == NULL) { PyErr_SetString(PyExc_MemoryError, "Out of memory"); goto fail; } self->fd = fd; Py_INCREF(self->fd); lseek(self->file, 0, SEEK_SET); } else #endif if (PyCallable_Check(fd)) { /* fd is a Python callable */ self->fd = fd; Py_INCREF(self->fd); self->read = fd; Py_INCREF(self->read); } else { PyErr_SetString( PyExc_TypeError, "Arg 1 to iterparser must be a file object or callable object"); goto fail; } PyErr_Clear(); self->queue_read_idx = 0; self->queue_write_idx = 0; self->done = 0; self->text = malloc((size_t)buffersize * sizeof(XML_Char)); self->text_alloc = buffersize; if (self->text == NULL) { PyErr_SetString(PyExc_MemoryError, "Out of memory"); goto fail; } text_clear(self); self->read_args = Py_BuildValue("(n)", buffersize); if (self->read_args == NULL) { goto fail; } self->dict_singleton = PyDict_New(); if (self->dict_singleton == NULL) { goto fail; } self->td_singleton = PyUnicode_FromString("TD"); if (self->td_singleton == NULL) { goto fail; } if (queue_realloc(self, buffersize)) { goto fail; } /* Set up an expat parser with our callbacks */ self->parser = XML_ParserCreate(NULL); if (self->parser == NULL) { PyErr_SetString(PyExc_MemoryError, "Out of memory"); goto fail; } XML_SetUserData(self->parser, self); XML_SetElementHandler( self->parser, (XML_StartElementHandler)startElement, (XML_EndElementHandler)endElement); XML_SetCharacterDataHandler( self->parser, (XML_CharacterDataHandler)characterData); XML_SetXmlDeclHandler( self->parser, (XML_XmlDeclHandler)xmlDecl); Py_XDECREF(read); return 0; fail: Py_XDECREF(read); Py_XDECREF(self->fd); Py_XDECREF(self->read); free(self->text); Py_XDECREF(self->dict_singleton); Py_XDECREF(self->td_singleton); Py_XDECREF(self->read_args); free(self->queue); return -1; } static PyMemberDef IterParser_members[] = { {NULL} /* Sentinel */ }; static PyMethodDef IterParser_methods[] = { {NULL} /* Sentinel */ }; static PyTypeObject IterParserType = { PyVarObject_HEAD_INIT(NULL, 0) "astropy.utils.xml._iterparser.IterParser", /*tp_name*/ sizeof(IterParser), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)IterParser_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash */ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ "IterParser objects", /* tp_doc */ (traverseproc)IterParser_traverse, /* tp_traverse */ (inquiry)IterParser_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ (getiterfunc)IterParser_iter, /* tp_iter */ (iternextfunc)IterParser_next, /* tp_iternext */ IterParser_methods, /* tp_methods */ IterParser_members, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)IterParser_init, /* tp_init */ 0, /* tp_alloc */ IterParser_new, /* tp_new */ }; /****************************************************************************** * XML escaping ******************************************************************************/ /* These are in reverse order by input character */ static const char* escapes_cdata[] = { ">", ">", "<", "<", "&", "&", "\0", "\0", }; /* These are in reverse order by input character */ static const char* escapes[] = { ">", ">", "<", "<", "'", "'", "&", "&", "\"", """, "\0", "\0" }; /* Implementation of escape_xml. * * Returns: * * 0 : No need to escape * * >0 : output is escaped * * -1 : error */ static Py_ssize_t _escape_xml_impl(const char *input, Py_ssize_t input_len, char **output, const char **escapes) { Py_ssize_t i; int count = 0; char *p = NULL; const char** esc; const char* ent; for (i = 0; i < input_len; ++i) { for (esc = escapes; ; esc += 2) { if ((unsigned char)input[i] > **esc) { break; } else if (input[i] == **esc) { ++count; break; } } } if (!count) { return 0; } p = malloc((input_len + 1 + count * 5) * sizeof(char)); if (p == NULL) { PyErr_SetString(PyExc_MemoryError, "Out of memory"); return -1; } *output = p; for (i = 0; i < input_len; ++i) { for (esc = escapes; ; esc += 2) { if ((unsigned char)input[i] > **esc) { *(p++) = input[i]; break; } else if (input[i] == **esc) { for (ent = *(esc + 1); *ent != '\0'; ++ent) { *(p++) = *ent; } break; } } } *p = 0; return p - *output; } /* * Returns a copy of the given string (8-bit or Unicode) with the XML * control characters converted to XML character entities. * * If an 8-bit string is passed in, an 8-bit string is returned. If a * Unicode string is passed in, a Unicode string is returned. */ static PyObject* _escape_xml(PyObject* self, PyObject *args, const char** escapes) { PyObject* input_obj; PyObject* input_coerce = NULL; PyObject* output_obj; char* input = NULL; Py_ssize_t input_len; char* output = NULL; Py_ssize_t output_len; if (!PyArg_ParseTuple(args, "O:escape_xml", &input_obj)) { return NULL; } /* First, try as Unicode */ if (!PyBytes_Check(input_obj)) { input_coerce = PyObject_Str(input_obj); } if (input_coerce) { input = (char*)PyUnicode_AsUTF8AndSize(input_coerce, &input_len); if (input == NULL) { Py_DECREF(input_coerce); return NULL; } output_len = _escape_xml_impl(input, input_len, &output, escapes); if (output_len < 0) { Py_DECREF(input_coerce); return NULL; } if (output_len > 0) { Py_DECREF(input_coerce); output_obj = PyUnicode_FromStringAndSize(output, output_len); free(output); return output_obj; } return input_coerce; } /* Now try as bytes */ input_coerce = PyObject_Bytes(input_obj); if (input_coerce) { if (PyBytes_AsStringAndSize(input_coerce, &input, &input_len) == -1) { Py_DECREF(input_coerce); return NULL; } output_len = _escape_xml_impl(input, input_len, &output, escapes); if (output_len < 0) { Py_DECREF(input_coerce); return NULL; } if (output_len > 0) { Py_DECREF(input_coerce); output_obj = PyBytes_FromStringAndSize(output, output_len); free(output); return output_obj; } return input_coerce; } PyErr_SetString(PyExc_TypeError, "must be convertible to str or bytes"); return NULL; } static PyObject* escape_xml(PyObject* self, PyObject *args) { return _escape_xml(self, args, escapes); } static PyObject* escape_xml_cdata(PyObject* self, PyObject *args) { return _escape_xml(self, args, escapes_cdata); } /****************************************************************************** * Module setup ******************************************************************************/ static PyMethodDef module_methods[] = { {"escape_xml", (PyCFunction)escape_xml, METH_VARARGS, "Fast method to escape XML strings"}, {"escape_xml_cdata", (PyCFunction)escape_xml_cdata, METH_VARARGS, "Fast method to escape XML strings"}, {NULL} /* Sentinel */ }; struct module_state { void* none; }; static int module_traverse(PyObject* m, visitproc visit, void* arg) { return 0; } static int module_clear(PyObject* m) { return 0; } static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, "_iterparser", "Fast XML parser", sizeof(struct module_state), module_methods, NULL, module_traverse, module_clear, NULL }; PyMODINIT_FUNC PyInit__iterparser(void) { PyObject* m; m = PyModule_Create(&moduledef); if (m == NULL) return NULL; if (PyType_Ready(&IterParserType) < 0) return NULL; Py_INCREF(&IterParserType); PyModule_AddObject(m, "IterParser", (PyObject *)&IterParserType); return m; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/xml/src/iterparse.map0000644000175100001710000000013500000000000021171 0ustar00vstsdockerVERS_1.0 { global: init_iterparser; PyInit__iterparser; local: *; }; ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2112553 astropy-5.0.2/astropy/utils/xml/tests/0000755000175100001710000000000000000000000017050 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/xml/tests/__init__.py0000644000175100001710000000000000000000000021147 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/xml/tests/test_iterparse.py0000644000175100001710000001133600000000000022463 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst # LOCAL from astropy.utils.xml.iterparser import _fast_iterparse # SYSTEM import io import zlib # The C-based XML parser for VOTables previously used fixed-sized # buffers (allocated at __init__() time). This test will # only pass with the patch that allows a dynamic realloc() of # the queue. This addresses the bugs: # # - "RuntimeError: XML queue overflow" # https://github.com/astropy/astropy/issues/5824 # (Kudos to Stefan Becker---ARI/ZAH Heidelberg) # # - "iterparse.c: add queue_realloc() + move 'buffersize / 2' logic there" # https://github.com/astropy/astropy/issues/5869 # # This test code can emulate a combination of network buffering and # gzip decompression---with different request sizes, it can be used to # demonstrate both under-reading and over-reading. # # Using the 512-tag VOTABLE XML sample input, and various combinations # of minimum/maximum fetch sizes, the following situations can be # generated: # # maximum_fetch = 1 (ValueError, no element found) still within gzip headers # maximum_fetch = 80 (ValueError, unclosed token) short read # maximum_fetch =217 passes, because decompressed_length > requested # && <512 tags in a single parse # maximum_fetch =218 (RuntimeError, XML queue overflow) # # The test provided here covers the over-reading identified in #5824 # (equivalent to the 217). # Firstly, assemble a minimal VOTABLE header, table contents and footer. # This is done in textual form, as the aim is to only test the parser, not # the outputter! HEADER = """ """ ROW = """ """ FOOTER = """
0
""" # minimum passable buffer size => 1024 # 1024 / 2 => 512 tags for overflow # 512 - 7 tags in header, - 5 tags in footer = 500 tags required for overflow # 500 / 4 tags () per row == 125 rows required for overflow VOTABLE_XML = HEADER + 125*ROW + FOOTER # UngzipFileWrapper() wraps an existing file-like Object, # decompressing the content and returning the plaintext. # This therefore emulates the behavior of the Python 'requests' # library when transparently decompressing Gzip HTTP responses. # # The critical behavior is that---because of the # decompression---read() can return considerably more # bytes than were requested! (But, read() can also return less). # # inspiration: # http://stackoverflow.com/questions/4013843/how-to-wrap-file-object-read-and-write-operation-which-are-readonly class UngzipFileWrapper: def __init__(self, fd, **kwargs): self._file = fd self._z = zlib.decompressobj(16 + zlib.MAX_WBITS) def read(self, requested_length): # emulate network buffering dynamics by clamping the read size clamped_length = max(1, min(1 << 24, requested_length)) compressed = self._file.read(clamped_length) plaintext = self._z.decompress(compressed) # Only for real local files---just for the testcase if len(compressed) == 0: self.close() return plaintext def __getattr__(self, attr): return getattr(self._file, attr) # test_iterparser_over_read_simple() is a very cut down test, # of the original more flexible test-case, but without external # dependencies. The plaintext is compressed and then decompressed # to provide a better emulation of the original situation where # the bug was observed. # # If a dependency upon 'zlib' is not desired, it would be possible to # simplify this testcase by replacing the compress/decompress with a # read() method emulation that always returned more from a buffer # that was requested. def test_iterparser_over_read_simple(): # Take the plaintext of 512 tags, and compression it with a # Gzip-style header (+16), to most closely emulate the behavior # of most HTTP servers. zlib_GZIP_STYLE_HEADER = 16 compo = zlib.compressobj(zlib.Z_BEST_COMPRESSION, zlib.DEFLATED, zlib.MAX_WBITS + zlib_GZIP_STYLE_HEADER) # Bytes vs. String .encode()/.decode() for compatibility with Python 3.5. s = compo.compress(VOTABLE_XML.encode()) s = s + compo.flush() fd = io.BytesIO(s) fd.seek(0) # Finally setup the test of the C-based '_fast_iterparse()' iterator # and a situation in which it can be called a-la the VOTable Parser. MINIMUM_REQUESTABLE_BUFFER_SIZE = 1024 uncompressed_fd = UngzipFileWrapper(fd) iterable = _fast_iterparse(uncompressed_fd.read, MINIMUM_REQUESTABLE_BUFFER_SIZE) list(iterable) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/xml/unescaper.py0000644000175100001710000000260500000000000020250 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """URL unescaper functions.""" # STDLIB from xml.sax import saxutils __all__ = ['unescape_all'] # This is DIY _bytes_entities = {b'&': b'&', b'<': b'<', b'>': b'>', b'&&': b'&', b'&&': b'&', b'%2F': b'/'} _bytes_keys = [b'&&', b'&&', b'&', b'<', b'>', b'%2F'] # This is used by saxutils _str_entities = {'&&': '&', '&&': '&', '%2F': '/'} _str_keys = ['&&', '&&', '&', '<', '>', '%2F'] def unescape_all(url): """Recursively unescape a given URL. .. note:: '&&' becomes a single '&'. Parameters ---------- url : str or bytes URL to unescape. Returns ------- clean_url : str or bytes Unescaped URL. """ if isinstance(url, bytes): func2use = _unescape_bytes keys2use = _bytes_keys else: func2use = _unescape_str keys2use = _str_keys clean_url = func2use(url) not_done = [clean_url.count(key) > 0 for key in keys2use] if True in not_done: return unescape_all(clean_url) else: return clean_url def _unescape_str(url): return saxutils.unescape(url, _str_entities) def _unescape_bytes(url): clean_url = url for key in _bytes_keys: clean_url = clean_url.replace(key, _bytes_entities[key]) return clean_url ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/xml/validate.py0000644000175100001710000000310200000000000020045 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ Functions to do XML schema and DTD validation. At the moment, this makes a subprocess call to xmllint. This could use a Python-based library at some point in the future, if something appropriate could be found. """ import os import subprocess def validate_schema(filename, schema_file): """ Validates an XML file against a schema or DTD. Parameters ---------- filename : str The path to the XML file to validate schema_file : str The path to the XML schema or DTD Returns ------- returncode, stdout, stderr : int, str, str Returns the returncode from xmllint and the stdout and stderr as strings """ base, ext = os.path.splitext(schema_file) if ext == '.xsd': schema_part = '--schema ' + schema_file elif ext == '.dtd': schema_part = '--dtdvalid ' + schema_file else: raise TypeError("schema_file must be a path to an XML Schema or DTD") p = subprocess.Popen( f"xmllint --noout --nonet {schema_part} {filename}", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() if p.returncode == 127: raise OSError( "xmllint not found, so can not validate schema") elif p.returncode < 0: from astropy.utils.misc import signal_number_to_name raise OSError( "xmllint was terminated by signal '{}'".format( signal_number_to_name(-p.returncode))) return p.returncode, stdout, stderr ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/utils/xml/writer.py0000644000175100001710000002422500000000000017601 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ Contains a class that makes it simple to stream out well-formed and nicely-indented XML. """ # STDLIB import contextlib import textwrap try: from . import _iterparser except ImportError: def xml_escape_cdata(s): """ Escapes &, < and > in an XML CDATA string. """ s = s.replace("&", "&") s = s.replace("<", "<") s = s.replace(">", ">") return s def xml_escape(s): """ Escapes &, ', ", < and > in an XML attribute value. """ s = s.replace("&", "&") s = s.replace("'", "'") s = s.replace("\"", """) s = s.replace("<", "<") s = s.replace(">", ">") return s else: xml_escape_cdata = _iterparser.escape_xml_cdata xml_escape = _iterparser.escape_xml class XMLWriter: """ A class to write well-formed and nicely indented XML. Use like this:: w = XMLWriter(fh) with w.tag('html'): with w.tag('body'): w.data('This is the content') Which produces:: This is the content """ def __init__(self, file): """ Parameters ---------- file : writable file-like """ self.write = file.write if hasattr(file, "flush"): self.flush = file.flush self._open = 0 # true if start tag is open self._tags = [] self._data = [] self._indentation = " " * 64 self.xml_escape_cdata = xml_escape_cdata self.xml_escape = xml_escape def _flush(self, indent=True, wrap=False): """ Flush internal buffers. """ if self._open: if indent: self.write(">\n") else: self.write(">") self._open = 0 if self._data: data = ''.join(self._data) if wrap: indent = self.get_indentation_spaces(1) data = textwrap.fill( data, initial_indent=indent, subsequent_indent=indent) self.write('\n') self.write(self.xml_escape_cdata(data)) self.write('\n') self.write(self.get_indentation_spaces()) else: self.write(self.xml_escape_cdata(data)) self._data = [] def start(self, tag, attrib={}, **extra): """ Opens a new element. Attributes can be given as keyword arguments, or as a string/string dictionary. The method returns an opaque identifier that can be passed to the :meth:`close` method, to close all open elements up to and including this one. Parameters ---------- tag : str The element name attrib : dict of str -> str Attribute dictionary. Alternatively, attributes can be given as keyword arguments. Returns ------- id : int Returns an element identifier. """ self._flush() # This is just busy work -- we know our tag names are clean # tag = xml_escape_cdata(tag) self._data = [] self._tags.append(tag) self.write(self.get_indentation_spaces(-1)) self.write(f"<{tag}") if attrib or extra: attrib = attrib.copy() attrib.update(extra) attrib = list(attrib.items()) attrib.sort() for k, v in attrib: if v is not None: # This is just busy work -- we know our keys are clean # k = xml_escape_cdata(k) v = self.xml_escape(v) self.write(f" {k}=\"{v}\"") self._open = 1 return len(self._tags) @contextlib.contextmanager def xml_cleaning_method(self, method='escape_xml', **clean_kwargs): """Context manager to control how XML data tags are cleaned (escaped) to remove potentially unsafe characters or constructs. The default (``method='escape_xml'``) applies brute-force escaping of certain key XML characters like ``<``, ``>``, and ``&`` to ensure that the output is not valid XML. In order to explicitly allow certain XML tags (e.g. link reference or emphasis tags), use ``method='bleach_clean'``. This sanitizes the data string using the ``clean`` function of the `bleach `_ package. Any additional keyword arguments will be passed directly to the ``clean`` function. Finally, use ``method='none'`` to disable any sanitization. This should be used sparingly. Example:: w = writer.XMLWriter(ListWriter(lines)) with w.xml_cleaning_method('bleach_clean'): w.start('td') w.data('google.com') w.end() Parameters ---------- method : str Cleaning method. Allowed values are "escape_xml", "bleach_clean", and "none". **clean_kwargs : keyword args Additional keyword args that are passed to the bleach.clean() function. """ current_xml_escape_cdata = self.xml_escape_cdata if method == 'bleach_clean': # NOTE: bleach is imported locally to avoid importing it when # it is not nocessary try: import bleach except ImportError: raise ValueError('bleach package is required when HTML escaping is disabled.\n' 'Use "pip install bleach".') if clean_kwargs is None: clean_kwargs = {} self.xml_escape_cdata = lambda x: bleach.clean(x, **clean_kwargs) elif method == "none": self.xml_escape_cdata = lambda x: x elif method != 'escape_xml': raise ValueError('allowed values of method are "escape_xml", "bleach_clean", and "none"') yield self.xml_escape_cdata = current_xml_escape_cdata @contextlib.contextmanager def tag(self, tag, attrib={}, **extra): """ A convenience method for creating wrapper elements using the ``with`` statement. Examples -------- >>> with writer.tag('foo'): # doctest: +SKIP ... writer.element('bar') ... # is implicitly closed here ... Parameters are the same as to `start`. """ self.start(tag, attrib, **extra) yield self.end(tag) def comment(self, comment): """ Adds a comment to the output stream. Parameters ---------- comment : str Comment text, as a Unicode string. """ self._flush() self.write(self.get_indentation_spaces()) self.write(f"\n") def data(self, text): """ Adds character data to the output stream. Parameters ---------- text : str Character data, as a Unicode string. """ self._data.append(text) def end(self, tag=None, indent=True, wrap=False): """ Closes the current element (opened by the most recent call to `start`). Parameters ---------- tag : str Element name. If given, the tag must match the start tag. If omitted, the current element is closed. """ if tag: if not self._tags: raise ValueError(f"unbalanced end({tag})") if tag != self._tags[-1]: raise ValueError(f"expected end({self._tags[-1]}), got {tag}") else: if not self._tags: raise ValueError("unbalanced end()") tag = self._tags.pop() if self._data: self._flush(indent, wrap) elif self._open: self._open = 0 self.write("/>\n") return if indent: self.write(self.get_indentation_spaces()) self.write(f"\n") def close(self, id): """ Closes open elements, up to (and including) the element identified by the given identifier. Parameters ---------- id : int Element identifier, as returned by the `start` method. """ while len(self._tags) > id: self.end() def element(self, tag, text=None, wrap=False, attrib={}, **extra): """ Adds an entire element. This is the same as calling `start`, `data`, and `end` in sequence. The ``text`` argument can be omitted. """ self.start(tag, attrib, **extra) if text: self.data(text) self.end(indent=False, wrap=wrap) def flush(self): pass # replaced by the constructor def get_indentation(self): """ Returns the number of indentation levels the file is currently in. """ return len(self._tags) def get_indentation_spaces(self, offset=0): """ Returns a string of spaces that matches the current indentation level. """ return self._indentation[:len(self._tags) + offset] @staticmethod def object_attrs(obj, attrs): """ Converts an object with a bunch of attributes on an object into a dictionary for use by the `XMLWriter`. Parameters ---------- obj : object Any Python object attrs : sequence of str Attribute names to pull from the object Returns ------- attrs : dict Maps attribute names to the values retrieved from ``obj.attr``. If any of the attributes is `None`, it will not appear in the output dictionary. """ d = {} for attr in attrs: if getattr(obj, attr) is not None: d[attr.replace('_', '-')] = str(getattr(obj, attr)) return d ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/version.py0000644000175100001710000000172300000000000016010 0ustar00vstsdocker# NOTE: First try _dev.scm_version if it exists and setuptools_scm is installed # This file is not included in astropy wheels/tarballs, so otherwise it will # fall back on the generated _version module. try: try: from ._dev.scm_version import version except ImportError: from ._version import version except Exception: import warnings warnings.warn( f'could not determine {__name__.split(".")[0]} package version; ' f'this indicates a broken installation') del warnings version = '0.0.0' # We use Version to define major, minor, micro, but ignore any suffixes. def split_version(version): pieces = [0, 0, 0] try: from packaging.version import Version v = Version(version) pieces = [v.major, v.minor, v.micro] except Exception: pass return pieces major, minor, bugfix = split_version(version) del split_version # clean up namespace. release = 'dev' not in version ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2112553 astropy-5.0.2/astropy/visualization/0000755000175100001710000000000000000000000016647 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/__init__.py0000644000175100001710000000042600000000000020762 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst from .hist import * from .interval import * from .mpl_normalize import * from .mpl_style import * from .stretch import * from .transform import * from .units import * from .time import * from .lupton_rgb import * ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/hist.py0000644000175100001710000000461100000000000020172 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst from astropy.stats.histogram import calculate_bin_edges __all__ = ['hist'] def hist(x, bins=10, ax=None, max_bins=1e5, **kwargs): """Enhanced histogram function This is a histogram function that enables the use of more sophisticated algorithms for determining bins. Aside from the ``bins`` argument allowing a string specified how bins are computed, the parameters are the same as pylab.hist(). This function was ported from astroML: https://www.astroml.org/ Parameters ---------- x : array-like array of data to be histogrammed bins : int, list, or str, optional If bins is a string, then it must be one of: - 'blocks' : use bayesian blocks for dynamic bin widths - 'knuth' : use Knuth's rule to determine bins - 'scott' : use Scott's rule to determine bins - 'freedman' : use the Freedman-Diaconis rule to determine bins ax : `~matplotlib.axes.Axes` instance, optional Specify the Axes on which to draw the histogram. If not specified, then the current active axes will be used. max_bins : int, optional Maximum number of bins allowed. With more than a few thousand bins the performance of matplotlib will not be great. If the number of bins is large *and* the number of input data points is large then the it will take a very long time to compute the histogram. **kwargs : other keyword arguments are described in ``plt.hist()``. Notes ----- Return values are the same as for ``plt.hist()`` See Also -------- astropy.stats.histogram """ # Note that we only calculate the bin edges...matplotlib will calculate # the actual histogram. range = kwargs.get('range', None) weights = kwargs.get('weights', None) bins = calculate_bin_edges(x, bins, range=range, weights=weights) if len(bins) > max_bins: raise ValueError('Histogram has too many bins: ' '{nbin}. Use max_bins to increase the number ' 'of allowed bins or range to restrict ' 'the histogram range.'.format(nbin=len(bins))) if ax is None: # optional dependency; only import if strictly needed. import matplotlib.pyplot as plt ax = plt.gca() return ax.hist(x, bins, **kwargs) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/interval.py0000644000175100001710000002237200000000000021053 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ Classes that deal with computing intervals from arrays of values based on various criteria. """ import abc import numpy as np from .transform import BaseTransform __all__ = ['BaseInterval', 'ManualInterval', 'MinMaxInterval', 'AsymmetricPercentileInterval', 'PercentileInterval', 'ZScaleInterval'] class BaseInterval(BaseTransform): """ Base class for the interval classes, which, when called with an array of values, return an interval computed following different algorithms. """ @abc.abstractmethod def get_limits(self, values): """ Return the minimum and maximum value in the interval based on the values provided. Parameters ---------- values : ndarray The image values. Returns ------- vmin, vmax : float The mininium and maximum image value in the interval. """ raise NotImplementedError('Needs to be implemented in a subclass.') def __call__(self, values, clip=True, out=None): """ Transform values using this interval. Parameters ---------- values : array-like The input values. clip : bool, optional If `True` (default), values outside the [0:1] range are clipped to the [0:1] range. out : ndarray, optional If specified, the output values will be placed in this array (typically used for in-place calculations). Returns ------- result : ndarray The transformed values. """ vmin, vmax = self.get_limits(values) if out is None: values = np.subtract(values, float(vmin)) else: if out.dtype.kind != 'f': raise TypeError('Can only do in-place scaling for ' 'floating-point arrays') values = np.subtract(values, float(vmin), out=out) if (vmax - vmin) != 0: np.true_divide(values, vmax - vmin, out=values) if clip: np.clip(values, 0., 1., out=values) return values class ManualInterval(BaseInterval): """ Interval based on user-specified values. Parameters ---------- vmin : float, optional The minimum value in the scaling. Defaults to the image minimum (ignoring NaNs) vmax : float, optional The maximum value in the scaling. Defaults to the image maximum (ignoring NaNs) """ def __init__(self, vmin=None, vmax=None): self.vmin = vmin self.vmax = vmax def get_limits(self, values): # Make sure values is a Numpy array values = np.asarray(values).ravel() # Filter out invalid values (inf, nan) values = values[np.isfinite(values)] vmin = np.min(values) if self.vmin is None else self.vmin vmax = np.max(values) if self.vmax is None else self.vmax return vmin, vmax class MinMaxInterval(BaseInterval): """ Interval based on the minimum and maximum values in the data. """ def get_limits(self, values): # Make sure values is a Numpy array values = np.asarray(values).ravel() # Filter out invalid values (inf, nan) values = values[np.isfinite(values)] return np.min(values), np.max(values) class AsymmetricPercentileInterval(BaseInterval): """ Interval based on a keeping a specified fraction of pixels (can be asymmetric). Parameters ---------- lower_percentile : float The lower percentile below which to ignore pixels. upper_percentile : float The upper percentile above which to ignore pixels. n_samples : int, optional Maximum number of values to use. If this is specified, and there are more values in the dataset as this, then values are randomly sampled from the array (with replacement). """ def __init__(self, lower_percentile, upper_percentile, n_samples=None): self.lower_percentile = lower_percentile self.upper_percentile = upper_percentile self.n_samples = n_samples def get_limits(self, values): # Make sure values is a Numpy array values = np.asarray(values).ravel() # If needed, limit the number of samples. We sample with replacement # since this is much faster. if self.n_samples is not None and values.size > self.n_samples: values = np.random.choice(values, self.n_samples) # Filter out invalid values (inf, nan) values = values[np.isfinite(values)] # Determine values at percentiles vmin, vmax = np.percentile(values, (self.lower_percentile, self.upper_percentile)) return vmin, vmax class PercentileInterval(AsymmetricPercentileInterval): """ Interval based on a keeping a specified fraction of pixels. Parameters ---------- percentile : float The fraction of pixels to keep. The same fraction of pixels is eliminated from both ends. n_samples : int, optional Maximum number of values to use. If this is specified, and there are more values in the dataset as this, then values are randomly sampled from the array (with replacement). """ def __init__(self, percentile, n_samples=None): lower_percentile = (100 - percentile) * 0.5 upper_percentile = 100 - lower_percentile super().__init__( lower_percentile, upper_percentile, n_samples=n_samples) class ZScaleInterval(BaseInterval): """ Interval based on IRAF's zscale. https://iraf.net/forum/viewtopic.php?showtopic=134139 Original implementation: https://github.com/spacetelescope/stsci.numdisplay/blob/master/lib/stsci/numdisplay/zscale.py Licensed under a 3-clause BSD style license (see AURA_LICENSE.rst). Parameters ---------- nsamples : int, optional The number of points in the array to sample for determining scaling factors. Defaults to 1000. contrast : float, optional The scaling factor (between 0 and 1) for determining the minimum and maximum value. Larger values increase the difference between the minimum and maximum values used for display. Defaults to 0.25. max_reject : float, optional If more than ``max_reject * npixels`` pixels are rejected, then the returned values are the minimum and maximum of the data. Defaults to 0.5. min_npixels : int, optional If there are less than ``min_npixels`` pixels remaining after the pixel rejection, then the returned values are the minimum and maximum of the data. Defaults to 5. krej : float, optional The number of sigma used for the rejection. Defaults to 2.5. max_iterations : int, optional The maximum number of iterations for the rejection. Defaults to 5. """ def __init__(self, nsamples=1000, contrast=0.25, max_reject=0.5, min_npixels=5, krej=2.5, max_iterations=5): self.nsamples = nsamples self.contrast = contrast self.max_reject = max_reject self.min_npixels = min_npixels self.krej = krej self.max_iterations = max_iterations def get_limits(self, values): # Sample the image values = np.asarray(values) values = values[np.isfinite(values)] stride = int(max(1.0, values.size / self.nsamples)) samples = values[::stride][:self.nsamples] samples.sort() npix = len(samples) vmin = samples[0] vmax = samples[-1] # Fit a line to the sorted array of samples minpix = max(self.min_npixels, int(npix * self.max_reject)) x = np.arange(npix) ngoodpix = npix last_ngoodpix = npix + 1 # Bad pixels mask used in k-sigma clipping badpix = np.zeros(npix, dtype=bool) # Kernel used to dilate the bad pixels mask ngrow = max(1, int(npix * 0.01)) kernel = np.ones(ngrow, dtype=bool) for _ in range(self.max_iterations): if ngoodpix >= last_ngoodpix or ngoodpix < minpix: break fit = np.polyfit(x, samples, deg=1, w=(~badpix).astype(int)) fitted = np.poly1d(fit)(x) # Subtract fitted line from the data array flat = samples - fitted # Compute the k-sigma rejection threshold threshold = self.krej * flat[~badpix].std() # Detect and reject pixels further than k*sigma from the # fitted line badpix[(flat < - threshold) | (flat > threshold)] = True # Convolve with a kernel of length ngrow badpix = np.convolve(badpix, kernel, mode='same') last_ngoodpix = ngoodpix ngoodpix = np.sum(~badpix) if ngoodpix >= minpix: slope, _ = fit if self.contrast > 0: slope = slope / self.contrast center_pixel = (npix - 1) // 2 median = np.median(samples) vmin = max(vmin, median - (center_pixel - 1) * slope) vmax = min(vmax, median + (npix - center_pixel) * slope) return vmin, vmax ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/lupton_rgb.py0000644000175100001710000003035400000000000021401 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ Combine 3 images to produce a properly-scaled RGB image following Lupton et al. (2004). The three images must be aligned and have the same pixel scale and size. For details, see : https://ui.adsabs.harvard.edu/abs/2004PASP..116..133L """ import numpy as np from . import ZScaleInterval __all__ = ['make_lupton_rgb'] def compute_intensity(image_r, image_g=None, image_b=None): """ Return a naive total intensity from the red, blue, and green intensities. Parameters ---------- image_r : ndarray Intensity of image to be mapped to red; or total intensity if ``image_g`` and ``image_b`` are None. image_g : ndarray, optional Intensity of image to be mapped to green. image_b : ndarray, optional Intensity of image to be mapped to blue. Returns ------- intensity : ndarray Total intensity from the red, blue and green intensities, or ``image_r`` if green and blue images are not provided. """ if image_g is None or image_b is None: if not (image_g is None and image_b is None): raise ValueError("please specify either a single image " "or red, green, and blue images.") return image_r intensity = (image_r + image_g + image_b)/3.0 # Repack into whatever type was passed to us return np.asarray(intensity, dtype=image_r.dtype) class Mapping: """ Baseclass to map red, blue, green intensities into uint8 values. Parameters ---------- minimum : float or sequence(3) Intensity that should be mapped to black (a scalar or array for R, G, B). image : ndarray, optional An image used to calculate some parameters of some mappings. """ def __init__(self, minimum=None, image=None): self._uint8Max = float(np.iinfo(np.uint8).max) try: len(minimum) except TypeError: minimum = 3*[minimum] if len(minimum) != 3: raise ValueError("please provide 1 or 3 values for minimum.") self.minimum = minimum self._image = np.asarray(image) def make_rgb_image(self, image_r, image_g, image_b): """ Convert 3 arrays, image_r, image_g, and image_b into an 8-bit RGB image. Parameters ---------- image_r : ndarray Image to map to red. image_g : ndarray Image to map to green. image_b : ndarray Image to map to blue. Returns ------- RGBimage : ndarray RGB (integer, 8-bits per channel) color image as an NxNx3 numpy array. """ image_r = np.asarray(image_r) image_g = np.asarray(image_g) image_b = np.asarray(image_b) if (image_r.shape != image_g.shape) or (image_g.shape != image_b.shape): msg = "The image shapes must match. r: {}, g: {} b: {}" raise ValueError(msg.format(image_r.shape, image_g.shape, image_b.shape)) return np.dstack(self._convert_images_to_uint8(image_r, image_g, image_b)).astype(np.uint8) def intensity(self, image_r, image_g, image_b): """ Return the total intensity from the red, blue, and green intensities. This is a naive computation, and may be overridden by subclasses. Parameters ---------- image_r : ndarray Intensity of image to be mapped to red; or total intensity if ``image_g`` and ``image_b`` are None. image_g : ndarray, optional Intensity of image to be mapped to green. image_b : ndarray, optional Intensity of image to be mapped to blue. Returns ------- intensity : ndarray Total intensity from the red, blue and green intensities, or ``image_r`` if green and blue images are not provided. """ return compute_intensity(image_r, image_g, image_b) def map_intensity_to_uint8(self, I): """ Return an array which, when multiplied by an image, returns that image mapped to the range of a uint8, [0, 255] (but not converted to uint8). The intensity is assumed to have had minimum subtracted (as that can be done per-band). Parameters ---------- I : ndarray Intensity to be mapped. Returns ------- mapped_I : ndarray ``I`` mapped to uint8 """ with np.errstate(invalid='ignore', divide='ignore'): return np.clip(I, 0, self._uint8Max) def _convert_images_to_uint8(self, image_r, image_g, image_b): """Use the mapping to convert images image_r, image_g, and image_b to a triplet of uint8 images""" image_r = image_r - self.minimum[0] # n.b. makes copy image_g = image_g - self.minimum[1] image_b = image_b - self.minimum[2] fac = self.map_intensity_to_uint8(self.intensity(image_r, image_g, image_b)) image_rgb = [image_r, image_g, image_b] for c in image_rgb: c *= fac with np.errstate(invalid='ignore'): c[c < 0] = 0 # individual bands can still be < 0, even if fac isn't pixmax = self._uint8Max r0, g0, b0 = image_rgb # copies -- could work row by row to minimise memory usage with np.errstate(invalid='ignore', divide='ignore'): # n.b. np.where can't and doesn't short-circuit for i, c in enumerate(image_rgb): c = np.where(r0 > g0, np.where(r0 > b0, np.where(r0 >= pixmax, c*pixmax/r0, c), np.where(b0 >= pixmax, c*pixmax/b0, c)), np.where(g0 > b0, np.where(g0 >= pixmax, c*pixmax/g0, c), np.where(b0 >= pixmax, c*pixmax/b0, c))).astype(np.uint8) c[c > pixmax] = pixmax image_rgb[i] = c return image_rgb class LinearMapping(Mapping): """ A linear map map of red, blue, green intensities into uint8 values. A linear stretch from [minimum, maximum]. If one or both are omitted use image min and/or max to set them. Parameters ---------- minimum : float Intensity that should be mapped to black (a scalar or array for R, G, B). maximum : float Intensity that should be mapped to white (a scalar). """ def __init__(self, minimum=None, maximum=None, image=None): if minimum is None or maximum is None: if image is None: raise ValueError("you must provide an image if you don't " "set both minimum and maximum") if minimum is None: minimum = image.min() if maximum is None: maximum = image.max() Mapping.__init__(self, minimum=minimum, image=image) self.maximum = maximum if maximum is None: self._range = None else: if maximum == minimum: raise ValueError("minimum and maximum values must not be equal") self._range = float(maximum - minimum) def map_intensity_to_uint8(self, I): with np.errstate(invalid='ignore', divide='ignore'): # n.b. np.where can't and doesn't short-circuit return np.where(I <= 0, 0, np.where(I >= self._range, self._uint8Max/I, self._uint8Max/self._range)) class AsinhMapping(Mapping): """ A mapping for an asinh stretch (preserving colours independent of brightness) x = asinh(Q (I - minimum)/stretch)/Q This reduces to a linear stretch if Q == 0 See https://ui.adsabs.harvard.edu/abs/2004PASP..116..133L Parameters ---------- minimum : float Intensity that should be mapped to black (a scalar or array for R, G, B). stretch : float The linear stretch of the image. Q : float The asinh softening parameter. """ def __init__(self, minimum, stretch, Q=8): Mapping.__init__(self, minimum) epsilon = 1.0/2**23 # 32bit floating point machine epsilon; sys.float_info.epsilon is 64bit if abs(Q) < epsilon: Q = 0.1 else: Qmax = 1e10 if Q > Qmax: Q = Qmax frac = 0.1 # gradient estimated using frac*stretch is _slope self._slope = frac*self._uint8Max/np.arcsinh(frac*Q) self._soften = Q/float(stretch) def map_intensity_to_uint8(self, I): with np.errstate(invalid='ignore', divide='ignore'): # n.b. np.where can't and doesn't short-circuit return np.where(I <= 0, 0, np.arcsinh(I*self._soften)*self._slope/I) class AsinhZScaleMapping(AsinhMapping): """ A mapping for an asinh stretch, estimating the linear stretch by zscale. x = asinh(Q (I - z1)/(z2 - z1))/Q Parameters ---------- image1 : ndarray or a list of arrays The image to analyse, or a list of 3 images to be converted to an intensity image. image2 : ndarray, optional the second image to analyse (must be specified with image3). image3 : ndarray, optional the third image to analyse (must be specified with image2). Q : float, optional The asinh softening parameter. Default is 8. pedestal : float or sequence(3), optional The value, or array of 3 values, to subtract from the images; or None. Notes ----- pedestal, if not None, is removed from the images when calculating the zscale stretch, and added back into Mapping.minimum[] """ def __init__(self, image1, image2=None, image3=None, Q=8, pedestal=None): """ """ if image2 is None or image3 is None: if not (image2 is None and image3 is None): raise ValueError("please specify either a single image " "or three images.") image = [image1] else: image = [image1, image2, image3] if pedestal is not None: try: len(pedestal) except TypeError: pedestal = 3*[pedestal] if len(pedestal) != 3: raise ValueError("please provide 1 or 3 pedestals.") image = list(image) # needs to be mutable for i, im in enumerate(image): if pedestal[i] != 0.0: image[i] = im - pedestal[i] # n.b. a copy else: pedestal = len(image)*[0.0] image = compute_intensity(*image) zscale_limits = ZScaleInterval().get_limits(image) zscale = LinearMapping(*zscale_limits, image=image) stretch = zscale.maximum - zscale.minimum[0] # zscale.minimum is always a triple minimum = zscale.minimum for i, level in enumerate(pedestal): minimum[i] += level AsinhMapping.__init__(self, minimum, stretch, Q) self._image = image def make_lupton_rgb(image_r, image_g, image_b, minimum=0, stretch=5, Q=8, filename=None): """ Return a Red/Green/Blue color image from up to 3 images using an asinh stretch. The input images can be int or float, and in any range or bit-depth. For a more detailed look at the use of this method, see the document :ref:`astropy:astropy-visualization-rgb`. Parameters ---------- image_r : ndarray Image to map to red. image_g : ndarray Image to map to green. image_b : ndarray Image to map to blue. minimum : float Intensity that should be mapped to black (a scalar or array for R, G, B). stretch : float The linear stretch of the image. Q : float The asinh softening parameter. filename : str Write the resulting RGB image to a file (file type determined from extension). Returns ------- rgb : ndarray RGB (integer, 8-bits per channel) color image as an NxNx3 numpy array. """ asinhMap = AsinhMapping(minimum, stretch, Q) rgb = asinhMap.make_rgb_image(image_r, image_g, image_b) if filename: import matplotlib.image matplotlib.image.imsave(filename, rgb, origin='lower') return rgb ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/mpl_normalize.py0000644000175100001710000003266300000000000022103 0ustar00vstsdocker""" Normalization class for Matplotlib that can be used to produce colorbars. """ import inspect import numpy as np from numpy import ma from .interval import (PercentileInterval, AsymmetricPercentileInterval, ManualInterval, MinMaxInterval, BaseInterval) from .stretch import (LinearStretch, SqrtStretch, PowerStretch, LogStretch, AsinhStretch, BaseStretch) try: import matplotlib # pylint: disable=W0611 from matplotlib.colors import Normalize from matplotlib import pyplot as plt except ImportError: class Normalize: def __init__(self, *args, **kwargs): raise ImportError('matplotlib is required in order to use this ' 'class.') __all__ = ['ImageNormalize', 'simple_norm', 'imshow_norm'] __doctest_requires__ = {'*': ['matplotlib']} class ImageNormalize(Normalize): """ Normalization class to be used with Matplotlib. Parameters ---------- data : ndarray, optional The image array. This input is used only if ``interval`` is also input. ``data`` and ``interval`` are used to compute the vmin and/or vmax values only if ``vmin`` or ``vmax`` are not input. interval : `~astropy.visualization.BaseInterval` subclass instance, optional The interval object to apply to the input ``data`` to determine the ``vmin`` and ``vmax`` values. This input is used only if ``data`` is also input. ``data`` and ``interval`` are used to compute the vmin and/or vmax values only if ``vmin`` or ``vmax`` are not input. vmin, vmax : float, optional The minimum and maximum levels to show for the data. The ``vmin`` and ``vmax`` inputs override any calculated values from the ``interval`` and ``data`` inputs. stretch : `~astropy.visualization.BaseStretch` subclass instance The stretch object to apply to the data. The default is `~astropy.visualization.LinearStretch`. clip : bool, optional If `True`, data values outside the [0:1] range are clipped to the [0:1] range. invalid : None or float, optional Value to assign NaN values generated by this class. NaNs in the input ``data`` array are not changed. For matplotlib normalization, the ``invalid`` value should map to the matplotlib colormap "under" value (i.e., any finite value < 0). If `None`, then NaN values are not replaced. This keyword has no effect if ``clip=True``. """ def __init__(self, data=None, interval=None, vmin=None, vmax=None, stretch=LinearStretch(), clip=False, invalid=-1.0): # this super call checks for matplotlib super().__init__(vmin=vmin, vmax=vmax, clip=clip) self.vmin = vmin self.vmax = vmax if stretch is None: raise ValueError('stretch must be input') if not isinstance(stretch, BaseStretch): raise TypeError('stretch must be an instance of a BaseStretch ' 'subclass') self.stretch = stretch if interval is not None and not isinstance(interval, BaseInterval): raise TypeError('interval must be an instance of a BaseInterval ' 'subclass') self.interval = interval self.inverse_stretch = stretch.inverse self.clip = clip self.invalid = invalid # Define vmin and vmax if not None and data was input if data is not None: self._set_limits(data) def _set_limits(self, data): if self.vmin is not None and self.vmax is not None: return # Define vmin and vmax from the interval class if not None if self.interval is None: if self.vmin is None: self.vmin = np.min(data[np.isfinite(data)]) if self.vmax is None: self.vmax = np.max(data[np.isfinite(data)]) else: _vmin, _vmax = self.interval.get_limits(data) if self.vmin is None: self.vmin = _vmin if self.vmax is None: self.vmax = _vmax def __call__(self, values, clip=None, invalid=None): """ Transform values using this normalization. Parameters ---------- values : array-like The input values. clip : bool, optional If `True`, values outside the [0:1] range are clipped to the [0:1] range. If `None` then the ``clip`` value from the `ImageNormalize` instance is used (the default of which is `False`). invalid : None or float, optional Value to assign NaN values generated by this class. NaNs in the input ``data`` array are not changed. For matplotlib normalization, the ``invalid`` value should map to the matplotlib colormap "under" value (i.e., any finite value < 0). If `None`, then the `ImageNormalize` instance value is used. This keyword has no effect if ``clip=True``. """ if clip is None: clip = self.clip if invalid is None: invalid = self.invalid if isinstance(values, ma.MaskedArray): if clip: mask = False else: mask = values.mask values = values.filled(self.vmax) else: mask = False # Make sure scalars get broadcast to 1-d if np.isscalar(values): values = np.array([values], dtype=float) else: # copy because of in-place operations after values = np.array(values, copy=True, dtype=float) # Define vmin and vmax if not None self._set_limits(values) # Normalize based on vmin and vmax np.subtract(values, self.vmin, out=values) np.true_divide(values, self.vmax - self.vmin, out=values) # Clip to the 0 to 1 range if clip: values = np.clip(values, 0., 1., out=values) # Stretch values if self.stretch._supports_invalid_kw: values = self.stretch(values, out=values, clip=False, invalid=invalid) else: values = self.stretch(values, out=values, clip=False) # Convert to masked array for matplotlib return ma.array(values, mask=mask) def inverse(self, values, invalid=None): # Find unstretched values in range 0 to 1 if self.inverse_stretch._supports_invalid_kw: values_norm = self.inverse_stretch(values, clip=False, invalid=invalid) else: values_norm = self.inverse_stretch(values, clip=False) # Scale to original range return values_norm * (self.vmax - self.vmin) + self.vmin def simple_norm(data, stretch='linear', power=1.0, asinh_a=0.1, min_cut=None, max_cut=None, min_percent=None, max_percent=None, percent=None, clip=False, log_a=1000, invalid=-1.0): """ Return a Normalization class that can be used for displaying images with Matplotlib. This function enables only a subset of image stretching functions available in `~astropy.visualization.mpl_normalize.ImageNormalize`. This function is used by the ``astropy.visualization.scripts.fits2bitmap`` script. Parameters ---------- data : ndarray The image array. stretch : {'linear', 'sqrt', 'power', log', 'asinh'}, optional The stretch function to apply to the image. The default is 'linear'. power : float, optional The power index for ``stretch='power'``. The default is 1.0. asinh_a : float, optional For ``stretch='asinh'``, the value where the asinh curve transitions from linear to logarithmic behavior, expressed as a fraction of the normalized image. Must be in the range between 0 and 1. The default is 0.1. min_cut : float, optional The pixel value of the minimum cut level. Data values less than ``min_cut`` will set to ``min_cut`` before stretching the image. The default is the image minimum. ``min_cut`` overrides ``min_percent``. max_cut : float, optional The pixel value of the maximum cut level. Data values greater than ``min_cut`` will set to ``min_cut`` before stretching the image. The default is the image maximum. ``max_cut`` overrides ``max_percent``. min_percent : float, optional The percentile value used to determine the pixel value of minimum cut level. The default is 0.0. ``min_percent`` overrides ``percent``. max_percent : float, optional The percentile value used to determine the pixel value of maximum cut level. The default is 100.0. ``max_percent`` overrides ``percent``. percent : float, optional The percentage of the image values used to determine the pixel values of the minimum and maximum cut levels. The lower cut level will set at the ``(100 - percent) / 2`` percentile, while the upper cut level will be set at the ``(100 + percent) / 2`` percentile. The default is 100.0. ``percent`` is ignored if either ``min_percent`` or ``max_percent`` is input. clip : bool, optional If `True`, data values outside the [0:1] range are clipped to the [0:1] range. log_a : float, optional The log index for ``stretch='log'``. The default is 1000. invalid : None or float, optional Value to assign NaN values generated by the normalization. NaNs in the input ``data`` array are not changed. For matplotlib normalization, the ``invalid`` value should map to the matplotlib colormap "under" value (i.e., any finite value < 0). If `None`, then NaN values are not replaced. This keyword has no effect if ``clip=True``. Returns ------- result : `ImageNormalize` instance An `ImageNormalize` instance that can be used for displaying images with Matplotlib. """ if percent is not None: interval = PercentileInterval(percent) elif min_percent is not None or max_percent is not None: interval = AsymmetricPercentileInterval(min_percent or 0., max_percent or 100.) elif min_cut is not None or max_cut is not None: interval = ManualInterval(min_cut, max_cut) else: interval = MinMaxInterval() if stretch == 'linear': stretch = LinearStretch() elif stretch == 'sqrt': stretch = SqrtStretch() elif stretch == 'power': stretch = PowerStretch(power) elif stretch == 'log': stretch = LogStretch(log_a) elif stretch == 'asinh': stretch = AsinhStretch(asinh_a) else: raise ValueError(f'Unknown stretch: {stretch}.') vmin, vmax = interval.get_limits(data) return ImageNormalize(vmin=vmin, vmax=vmax, stretch=stretch, clip=clip, invalid=invalid) # used in imshow_norm _norm_sig = inspect.signature(ImageNormalize) def imshow_norm(data, ax=None, **kwargs): """ A convenience function to call matplotlib's `matplotlib.pyplot.imshow` function, using an `ImageNormalize` object as the normalization. Parameters ---------- data : 2D or 3D array-like The data to show. Can be whatever `~matplotlib.pyplot.imshow` and `ImageNormalize` both accept. See `~matplotlib.pyplot.imshow`. ax : None or `~matplotlib.axes.Axes`, optional If None, use pyplot's imshow. Otherwise, calls ``imshow`` method of the supplied axes. **kwargs : dict, optional All other keyword arguments are parsed first by the `ImageNormalize` initializer, then to `~matplotlib.pyplot.imshow`. Returns ------- result : tuple A tuple containing the `~matplotlib.image.AxesImage` generated by `~matplotlib.pyplot.imshow` as well as the `ImageNormalize` instance. Notes ----- The ``norm`` matplotlib keyword is not supported. Examples -------- .. plot:: :include-source: import numpy as np import matplotlib.pyplot as plt from astropy.visualization import (imshow_norm, MinMaxInterval, SqrtStretch) # Generate and display a test image image = np.arange(65536).reshape((256, 256)) fig = plt.figure() ax = fig.add_subplot(1, 1, 1) im, norm = imshow_norm(image, ax, origin='lower', interval=MinMaxInterval(), stretch=SqrtStretch()) fig.colorbar(im) """ if 'X' in kwargs: raise ValueError('Cannot give both ``X`` and ``data``') if 'norm' in kwargs: raise ValueError('There is no point in using imshow_norm if you give ' 'the ``norm`` keyword - use imshow directly if you ' 'want that.') imshow_kwargs = dict(kwargs) norm_kwargs = {'data': data} for pname in _norm_sig.parameters: if pname in kwargs: norm_kwargs[pname] = imshow_kwargs.pop(pname) imshow_kwargs['norm'] = ImageNormalize(**norm_kwargs) if ax is None: imshow_result = plt.imshow(data, **imshow_kwargs) else: imshow_result = ax.imshow(data, **imshow_kwargs) return imshow_result, imshow_kwargs['norm'] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/mpl_style.py0000644000175100001710000000422300000000000021232 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst # This module contains dictionaries that can be used to set a matplotlib # plotting style. It is no longer documented/recommended as of Astropy v3.0 # but is kept here for backward-compatibility. __all__ = ['astropy_mpl_style_1', 'astropy_mpl_style'] # Version 1 astropy plotting style for matplotlib astropy_mpl_style_1 = { # Lines 'lines.linewidth': 1.7, 'lines.antialiased': True, # Patches 'patch.linewidth': 1.0, 'patch.facecolor': '#348ABD', 'patch.edgecolor': '#CCCCCC', 'patch.antialiased': True, # Images 'image.cmap': 'gist_heat', 'image.origin': 'upper', # Font 'font.size': 12.0, # Axes 'axes.facecolor': '#FFFFFF', 'axes.edgecolor': '#AAAAAA', 'axes.linewidth': 1.0, 'axes.grid': True, 'axes.titlesize': 'x-large', 'axes.labelsize': 'large', 'axes.labelcolor': 'k', 'axes.axisbelow': True, # Ticks 'xtick.major.size': 0, 'xtick.minor.size': 0, 'xtick.major.pad': 6, 'xtick.minor.pad': 6, 'xtick.color': '#565656', 'xtick.direction': 'in', 'ytick.major.size': 0, 'ytick.minor.size': 0, 'ytick.major.pad': 6, 'ytick.minor.pad': 6, 'ytick.color': '#565656', 'ytick.direction': 'in', # Legend 'legend.fancybox': True, 'legend.loc': 'best', # Figure 'figure.figsize': [8, 6], 'figure.facecolor': '1.0', 'figure.edgecolor': '0.50', 'figure.subplot.hspace': 0.5, # Other 'savefig.dpi': 72, } color_cycle = ['#348ABD', # blue '#7A68A6', # purple '#A60628', # red '#467821', # green '#CF4457', # pink '#188487', # turquoise '#E24A33'] # orange try: # This is a dependency of matplotlib, so should be present if matplotlib # is installed. from cycler import cycler astropy_mpl_style_1['axes.prop_cycle'] = cycler('color', color_cycle) except ImportError: astropy_mpl_style_1['axes.color_cycle'] = color_cycle astropy_mpl_style = astropy_mpl_style_1 """The most recent version of the astropy plotting style.""" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2112553 astropy-5.0.2/astropy/visualization/scripts/0000755000175100001710000000000000000000000020336 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/scripts/__init__.py0000644000175100001710000000010000000000000022436 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/scripts/fits2bitmap.py0000644000175100001710000001630400000000000023140 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import os from astropy.visualization.mpl_normalize import simple_norm from astropy import log from astropy.io.fits import getdata def fits2bitmap(filename, ext=0, out_fn=None, stretch='linear', power=1.0, asinh_a=0.1, min_cut=None, max_cut=None, min_percent=None, max_percent=None, percent=None, cmap='Greys_r'): """ Create a bitmap file from a FITS image, applying a stretching transform between minimum and maximum cut levels and a matplotlib colormap. Parameters ---------- filename : str The filename of the FITS file. ext : int FITS extension name or number of the image to convert. The default is 0. out_fn : str The filename of the output bitmap image. The type of bitmap is determined by the filename extension (e.g. '.jpg', '.png'). The default is a PNG file with the same name as the FITS file. stretch : {'linear', 'sqrt', 'power', log', 'asinh'} The stretching function to apply to the image. The default is 'linear'. power : float, optional The power index for ``stretch='power'``. The default is 1.0. asinh_a : float, optional For ``stretch='asinh'``, the value where the asinh curve transitions from linear to logarithmic behavior, expressed as a fraction of the normalized image. Must be in the range between 0 and 1. The default is 0.1. min_cut : float, optional The pixel value of the minimum cut level. Data values less than ``min_cut`` will set to ``min_cut`` before stretching the image. The default is the image minimum. ``min_cut`` overrides ``min_percent``. max_cut : float, optional The pixel value of the maximum cut level. Data values greater than ``min_cut`` will set to ``min_cut`` before stretching the image. The default is the image maximum. ``max_cut`` overrides ``max_percent``. min_percent : float, optional The percentile value used to determine the pixel value of minimum cut level. The default is 0.0. ``min_percent`` overrides ``percent``. max_percent : float, optional The percentile value used to determine the pixel value of maximum cut level. The default is 100.0. ``max_percent`` overrides ``percent``. percent : float, optional The percentage of the image values used to determine the pixel values of the minimum and maximum cut levels. The lower cut level will set at the ``(100 - percent) / 2`` percentile, while the upper cut level will be set at the ``(100 + percent) / 2`` percentile. The default is 100.0. ``percent`` is ignored if either ``min_percent`` or ``max_percent`` is input. cmap : str The matplotlib color map name. The default is 'Greys_r'. """ import matplotlib import matplotlib.cm as cm import matplotlib.image as mimg # __main__ gives ext as a string try: ext = int(ext) except ValueError: pass try: image = getdata(filename, ext) except Exception as e: log.critical(e) return 1 if image.ndim != 2: log.critical(f'data in FITS extension {ext} is not a 2D array') if out_fn is None: out_fn = os.path.splitext(filename)[0] if out_fn.endswith('.fits'): out_fn = os.path.splitext(out_fn)[0] out_fn += '.png' # explicitly define the output format out_format = os.path.splitext(out_fn)[1][1:] try: cm.get_cmap(cmap) except ValueError: log.critical(f'{cmap} is not a valid matplotlib colormap name.') return 1 norm = simple_norm(image, stretch=stretch, power=power, asinh_a=asinh_a, min_cut=min_cut, max_cut=max_cut, min_percent=min_percent, max_percent=max_percent, percent=percent) mimg.imsave(out_fn, norm(image), cmap=cmap, origin='lower', format=out_format) log.info(f'Saved file to {out_fn}.') def main(args=None): import argparse parser = argparse.ArgumentParser( description='Create a bitmap file from a FITS image.') parser.add_argument('-e', '--ext', metavar='hdu', default=0, help='Specify the HDU extension number or name ' '(Default is 0).') parser.add_argument('-o', metavar='filename', type=str, default=None, help='Filename for the output image (Default is a ' 'PNG file with the same name as the FITS file).') parser.add_argument('--stretch', type=str, default='linear', help='Type of image stretching ("linear", "sqrt", ' '"power", "log", or "asinh") (Default is "linear").') parser.add_argument('--power', type=float, default=1.0, help='Power index for "power" stretching (Default is ' '1.0).') parser.add_argument('--asinh_a', type=float, default=0.1, help='The value in normalized image where the asinh ' 'curve transitions from linear to logarithmic ' 'behavior (used only for "asinh" stretch) ' '(Default is 0.1).') parser.add_argument('--min_cut', type=float, default=None, help='The pixel value of the minimum cut level ' '(Default is the image minimum).') parser.add_argument('--max_cut', type=float, default=None, help='The pixel value of the maximum cut level ' '(Default is the image maximum).') parser.add_argument('--min_percent', type=float, default=None, help='The percentile value used to determine the ' 'minimum cut level (Default is 0).') parser.add_argument('--max_percent', type=float, default=None, help='The percentile value used to determine the ' 'maximum cut level (Default is 100).') parser.add_argument('--percent', type=float, default=None, help='The percentage of the image values used to ' 'determine the pixel values of the minimum and ' 'maximum cut levels (Default is 100).') parser.add_argument('--cmap', metavar='colormap_name', type=str, default='Greys_r', help='matplotlib color map name ' '(Default is "Greys_r").') parser.add_argument('filename', nargs='+', help='Path to one or more FITS files to convert') args = parser.parse_args(args) for filename in args.filename: fits2bitmap(filename, ext=args.ext, out_fn=args.o, stretch=args.stretch, min_cut=args.min_cut, max_cut=args.max_cut, min_percent=args.min_percent, max_percent=args.max_percent, percent=args.percent, power=args.power, asinh_a=args.asinh_a, cmap=args.cmap) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2112553 astropy-5.0.2/astropy/visualization/scripts/tests/0000755000175100001710000000000000000000000021500 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/scripts/tests/__init__.py0000644000175100001710000000010000000000000023600 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/scripts/tests/test_fits2bitmap.py0000644000175100001710000000437300000000000025344 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import pytest import numpy as np from astropy.io import fits from astropy.utils.compat.optional_deps import HAS_MATPLOTLIB if HAS_MATPLOTLIB: import matplotlib.image as mpimg from astropy.visualization.scripts.fits2bitmap import fits2bitmap, main @pytest.mark.skipif('not HAS_MATPLOTLIB') class TestFits2Bitmap: def setup_class(self): self.filename = 'test.fits' self.array = np.arange(16384).reshape((128, 128)) def test_function(self, tmpdir): filename = tmpdir.join(self.filename).strpath fits.writeto(filename, self.array) fits2bitmap(filename) def test_script(self, tmpdir): filename = tmpdir.join(self.filename).strpath fits.writeto(filename, self.array) main([filename, '-e', '0']) def test_exten_num(self, tmpdir): filename = tmpdir.join(self.filename).strpath hdu1 = fits.PrimaryHDU() hdu2 = fits.ImageHDU(self.array) hdulist = fits.HDUList([hdu1, hdu2]) hdulist.writeto(filename) main([filename, '-e', '1']) def test_exten_name(self, tmpdir): filename = tmpdir.join(self.filename).strpath hdu1 = fits.PrimaryHDU() extname = 'SCI' hdu2 = fits.ImageHDU(self.array) hdu2.header['EXTNAME'] = extname hdulist = fits.HDUList([hdu1, hdu2]) hdulist.writeto(filename) main([filename, '-e', extname]) @pytest.mark.parametrize('file_exten', ['.gz', '.bz2']) def test_compressed_fits(self, tmpdir, file_exten): filename = tmpdir.join('test.fits' + file_exten).strpath fits.writeto(filename, self.array) main([filename, '-e', '0']) def test_orientation(self, tmpdir): """ Regression test to check the image vertical orientation/origin. """ filename = tmpdir.join(self.filename).strpath out_filename = 'fits2bitmap_test.png' out_filename = tmpdir.join(out_filename).strpath data = np.zeros((32, 32)) data[0:16, :] = 1. fits.writeto(filename, data) main([filename, '-e', '0', '-o', out_filename]) img = mpimg.imread(out_filename) assert img[0, 0, 0] == 0 assert img[31, 31, 0] == 1 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/stretch.py0000644000175100001710000005121400000000000020700 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ Classes that deal with stretching, i.e. mapping a range of [0:1] values onto another set of [0:1] values with a transformation """ import numpy as np from .transform import BaseTransform from .transform import CompositeTransform __all__ = ["BaseStretch", "LinearStretch", "SqrtStretch", "PowerStretch", "PowerDistStretch", "SquaredStretch", "LogStretch", "AsinhStretch", "SinhStretch", "HistEqStretch", "ContrastBiasStretch", "CompositeStretch"] def _logn(n, x, out=None): """Calculate the log base n of x.""" # We define this because numpy.lib.scimath.logn doesn't support out= if out is None: return np.log(x) / np.log(n) else: np.log(x, out=out) np.true_divide(out, np.log(n), out=out) return out def _prepare(values, clip=True, out=None): """ Prepare the data by optionally clipping and copying, and return the array that should be subsequently used for in-place calculations. """ if clip: return np.clip(values, 0., 1., out=out) else: if out is None: return np.array(values, copy=True) else: out[:] = np.asarray(values) return out class BaseStretch(BaseTransform): """ Base class for the stretch classes, which, when called with an array of values in the range [0:1], return an transformed array of values, also in the range [0:1]. """ @property def _supports_invalid_kw(self): return False def __add__(self, other): return CompositeStretch(other, self) def __call__(self, values, clip=True, out=None): """ Transform values using this stretch. Parameters ---------- values : array-like The input values, which should already be normalized to the [0:1] range. clip : bool, optional If `True` (default), values outside the [0:1] range are clipped to the [0:1] range. out : ndarray, optional If specified, the output values will be placed in this array (typically used for in-place calculations). Returns ------- result : ndarray The transformed values. """ @property def inverse(self): """A stretch object that performs the inverse operation.""" class LinearStretch(BaseStretch): """ A linear stretch with a slope and offset. The stretch is given by: .. math:: y = slope x + intercept Parameters ---------- slope : float, optional The ``slope`` parameter used in the above formula. Default is 1. intercept : float, optional The ``intercept`` parameter used in the above formula. Default is 0. """ def __init__(self, slope=1, intercept=0): super().__init__() self.slope = slope self.intercept = intercept def __call__(self, values, clip=True, out=None): values = _prepare(values, clip=clip, out=out) if self.slope != 1: np.multiply(values, self.slope, out=values) if self.intercept != 0: np.add(values, self.intercept, out=values) return values @property def inverse(self): """A stretch object that performs the inverse operation.""" return LinearStretch(1. / self.slope, - self.intercept / self.slope) class SqrtStretch(BaseStretch): r""" A square root stretch. The stretch is given by: .. math:: y = \sqrt{x} """ @property def _supports_invalid_kw(self): return True def __call__(self, values, clip=True, out=None, invalid=None): """ Transform values using this stretch. Parameters ---------- values : array-like The input values, which should already be normalized to the [0:1] range. clip : bool, optional If `True` (default), values outside the [0:1] range are clipped to the [0:1] range. out : ndarray, optional If specified, the output values will be placed in this array (typically used for in-place calculations). invalid : None or float, optional Value to assign NaN values generated by this class. NaNs in the input ``values`` array are not changed. This option is generally used with matplotlib normalization classes, where the ``invalid`` value should map to the matplotlib colormap "under" value (i.e., any finite value < 0). If `None`, then NaN values are not replaced. This keyword has no effect if ``clip=True``. Returns ------- result : ndarray The transformed values. """ values = _prepare(values, clip=clip, out=out) replace_invalid = not clip and invalid is not None with np.errstate(invalid='ignore'): if replace_invalid: idx = (values < 0) np.sqrt(values, out=values) if replace_invalid: # Assign new NaN (i.e., NaN not in the original input # values, but generated by this class) to the invalid value. values[idx] = invalid return values @property def inverse(self): """A stretch object that performs the inverse operation.""" return PowerStretch(2) class PowerStretch(BaseStretch): r""" A power stretch. The stretch is given by: .. math:: y = x^a Parameters ---------- a : float The power index (see the above formula). ``a`` must be greater than 0. """ @property def _supports_invalid_kw(self): return True def __init__(self, a): super().__init__() if a <= 0: raise ValueError("a must be > 0") self.power = a def __call__(self, values, clip=True, out=None, invalid=None): """ Transform values using this stretch. Parameters ---------- values : array-like The input values, which should already be normalized to the [0:1] range. clip : bool, optional If `True` (default), values outside the [0:1] range are clipped to the [0:1] range. out : ndarray, optional If specified, the output values will be placed in this array (typically used for in-place calculations). invalid : None or float, optional Value to assign NaN values generated by this class. NaNs in the input ``values`` array are not changed. This option is generally used with matplotlib normalization classes, where the ``invalid`` value should map to the matplotlib colormap "under" value (i.e., any finite value < 0). If `None`, then NaN values are not replaced. This keyword has no effect if ``clip=True``. Returns ------- result : ndarray The transformed values. """ values = _prepare(values, clip=clip, out=out) replace_invalid = (not clip and invalid is not None and ((-1 < self.power < 0) or (0 < self.power < 1))) with np.errstate(invalid='ignore'): if replace_invalid: idx = (values < 0) np.power(values, self.power, out=values) if replace_invalid: # Assign new NaN (i.e., NaN not in the original input # values, but generated by this class) to the invalid value. values[idx] = invalid return values @property def inverse(self): """A stretch object that performs the inverse operation.""" return PowerStretch(1. / self.power) class PowerDistStretch(BaseStretch): r""" An alternative power stretch. The stretch is given by: .. math:: y = \frac{a^x - 1}{a - 1} Parameters ---------- a : float, optional The ``a`` parameter used in the above formula. ``a`` must be greater than or equal to 0, but cannot be set to 1. Default is 1000. """ def __init__(self, a=1000.0): if a < 0 or a == 1: # singularity raise ValueError("a must be >= 0, but cannot be set to 1") super().__init__() self.exp = a def __call__(self, values, clip=True, out=None): values = _prepare(values, clip=clip, out=out) np.power(self.exp, values, out=values) np.subtract(values, 1, out=values) np.true_divide(values, self.exp - 1.0, out=values) return values @property def inverse(self): """A stretch object that performs the inverse operation.""" return InvertedPowerDistStretch(a=self.exp) class InvertedPowerDistStretch(BaseStretch): r""" Inverse transformation for `~astropy.image.scaling.PowerDistStretch`. The stretch is given by: .. math:: y = \frac{\log(y (a-1) + 1)}{\log a} Parameters ---------- a : float, optional The ``a`` parameter used in the above formula. ``a`` must be greater than or equal to 0, but cannot be set to 1. Default is 1000. """ def __init__(self, a=1000.0): if a < 0 or a == 1: # singularity raise ValueError("a must be >= 0, but cannot be set to 1") super().__init__() self.exp = a def __call__(self, values, clip=True, out=None): values = _prepare(values, clip=clip, out=out) np.multiply(values, self.exp - 1.0, out=values) np.add(values, 1, out=values) _logn(self.exp, values, out=values) return values @property def inverse(self): """A stretch object that performs the inverse operation.""" return PowerDistStretch(a=self.exp) class SquaredStretch(PowerStretch): r""" A convenience class for a power stretch of 2. The stretch is given by: .. math:: y = x^2 """ def __init__(self): super().__init__(2) @property def inverse(self): """A stretch object that performs the inverse operation.""" return SqrtStretch() class LogStretch(BaseStretch): r""" A log stretch. The stretch is given by: .. math:: y = \frac{\log{(a x + 1)}}{\log{(a + 1)}} Parameters ---------- a : float The ``a`` parameter used in the above formula. ``a`` must be greater than 0. Default is 1000. """ @property def _supports_invalid_kw(self): return True def __init__(self, a=1000.0): super().__init__() if a <= 0: # singularity raise ValueError("a must be > 0") self.exp = a def __call__(self, values, clip=True, out=None, invalid=None): """ Transform values using this stretch. Parameters ---------- values : array-like The input values, which should already be normalized to the [0:1] range. clip : bool, optional If `True` (default), values outside the [0:1] range are clipped to the [0:1] range. out : ndarray, optional If specified, the output values will be placed in this array (typically used for in-place calculations). invalid : None or float, optional Value to assign NaN values generated by this class. NaNs in the input ``values`` array are not changed. This option is generally used with matplotlib normalization classes, where the ``invalid`` value should map to the matplotlib colormap "under" value (i.e., any finite value < 0). If `None`, then NaN values are not replaced. This keyword has no effect if ``clip=True``. Returns ------- result : ndarray The transformed values. """ values = _prepare(values, clip=clip, out=out) replace_invalid = not clip and invalid is not None with np.errstate(invalid='ignore'): if replace_invalid: idx = (values < 0) np.multiply(values, self.exp, out=values) np.add(values, 1., out=values) np.log(values, out=values) np.true_divide(values, np.log(self.exp + 1.), out=values) if replace_invalid: # Assign new NaN (i.e., NaN not in the original input # values, but generated by this class) to the invalid value. values[idx] = invalid return values @property def inverse(self): """A stretch object that performs the inverse operation.""" return InvertedLogStretch(self.exp) class InvertedLogStretch(BaseStretch): r""" Inverse transformation for `~astropy.image.scaling.LogStretch`. The stretch is given by: .. math:: y = \frac{e^{y \log{a + 1}} - 1}{a} \\ y = \frac{e^{y} (a + 1) - 1}{a} Parameters ---------- a : float, optional The ``a`` parameter used in the above formula. ``a`` must be greater than 0. Default is 1000. """ def __init__(self, a): super().__init__() if a <= 0: # singularity raise ValueError("a must be > 0") self.exp = a def __call__(self, values, clip=True, out=None): values = _prepare(values, clip=clip, out=out) np.multiply(values, np.log(self.exp + 1.), out=values) np.exp(values, out=values) np.subtract(values, 1., out=values) np.true_divide(values, self.exp, out=values) return values @property def inverse(self): """A stretch object that performs the inverse operation.""" return LogStretch(self.exp) class AsinhStretch(BaseStretch): r""" An asinh stretch. The stretch is given by: .. math:: y = \frac{{\rm asinh}(x / a)}{{\rm asinh}(1 / a)}. Parameters ---------- a : float, optional The ``a`` parameter used in the above formula. The value of this parameter is where the asinh curve transitions from linear to logarithmic behavior, expressed as a fraction of the normalized image. ``a`` must be greater than 0 and less than or equal to 1 (0 < a <= 1). Default is 0.1. """ def __init__(self, a=0.1): super().__init__() if a <= 0 or a > 1: raise ValueError("a must be > 0 and <= 1") self.a = a def __call__(self, values, clip=True, out=None): values = _prepare(values, clip=clip, out=out) np.true_divide(values, self.a, out=values) np.arcsinh(values, out=values) np.true_divide(values, np.arcsinh(1. / self.a), out=values) return values @property def inverse(self): """A stretch object that performs the inverse operation.""" return SinhStretch(a=1. / np.arcsinh(1. / self.a)) class SinhStretch(BaseStretch): r""" A sinh stretch. The stretch is given by: .. math:: y = \frac{{\rm sinh}(x / a)}{{\rm sinh}(1 / a)} Parameters ---------- a : float, optional The ``a`` parameter used in the above formula. ``a`` must be greater than 0 and less than or equal to 1 (0 < a <= 1). Default is 1/3. """ def __init__(self, a=1./3.): super().__init__() if a <= 0 or a > 1: raise ValueError("a must be > 0 and <= 1") self.a = a def __call__(self, values, clip=True, out=None): values = _prepare(values, clip=clip, out=out) np.true_divide(values, self.a, out=values) np.sinh(values, out=values) np.true_divide(values, np.sinh(1. / self.a), out=values) return values @property def inverse(self): """A stretch object that performs the inverse operation.""" return AsinhStretch(a=1. / np.sinh(1. / self.a)) class HistEqStretch(BaseStretch): """ A histogram equalization stretch. Parameters ---------- data : array-like The data defining the equalization. values : array-like, optional The input image values, which should already be normalized to the [0:1] range. """ def __init__(self, data, values=None): # Assume data is not necessarily normalized at this point self.data = np.sort(data.ravel()) self.data = self.data[np.isfinite(self.data)] vmin = self.data.min() vmax = self.data.max() self.data = (self.data - vmin) / (vmax - vmin) # Compute relative position of each pixel if values is None: self.values = np.linspace(0., 1., len(self.data)) else: self.values = values def __call__(self, values, clip=True, out=None): values = _prepare(values, clip=clip, out=out) values[:] = np.interp(values, self.data, self.values) return values @property def inverse(self): """A stretch object that performs the inverse operation.""" return InvertedHistEqStretch(self.data, values=self.values) class InvertedHistEqStretch(BaseStretch): """ Inverse transformation for `~astropy.image.scaling.HistEqStretch`. Parameters ---------- data : array-like The data defining the equalization. values : array-like, optional The input image values, which should already be normalized to the [0:1] range. """ def __init__(self, data, values=None): self.data = data[np.isfinite(data)] if values is None: self.values = np.linspace(0., 1., len(self.data)) else: self.values = values def __call__(self, values, clip=True, out=None): values = _prepare(values, clip=clip, out=out) values[:] = np.interp(values, self.values, self.data) return values @property def inverse(self): """A stretch object that performs the inverse operation.""" return HistEqStretch(self.data, values=self.values) class ContrastBiasStretch(BaseStretch): r""" A stretch that takes into account contrast and bias. The stretch is given by: .. math:: y = (x - {\rm bias}) * {\rm contrast} + 0.5 and the output values are clipped to the [0:1] range. Parameters ---------- contrast : float The contrast parameter (see the above formula). bias : float The bias parameter (see the above formula). """ def __init__(self, contrast, bias): super().__init__() self.contrast = contrast self.bias = bias def __call__(self, values, clip=True, out=None): # As a special case here, we only clip *after* the # transformation since it does not map [0:1] to [0:1] values = _prepare(values, clip=False, out=out) np.subtract(values, self.bias, out=values) np.multiply(values, self.contrast, out=values) np.add(values, 0.5, out=values) if clip: np.clip(values, 0, 1, out=values) return values @property def inverse(self): """A stretch object that performs the inverse operation.""" return InvertedContrastBiasStretch(self.contrast, self.bias) class InvertedContrastBiasStretch(BaseStretch): """ Inverse transformation for ContrastBiasStretch. Parameters ---------- contrast : float The contrast parameter (see `~astropy.visualization.ConstrastBiasStretch). bias : float The bias parameter (see `~astropy.visualization.ConstrastBiasStretch). """ def __init__(self, contrast, bias): super().__init__() self.contrast = contrast self.bias = bias def __call__(self, values, clip=True, out=None): # As a special case here, we only clip *after* the # transformation since it does not map [0:1] to [0:1] values = _prepare(values, clip=False, out=out) np.subtract(values, 0.5, out=values) np.true_divide(values, self.contrast, out=values) np.add(values, self.bias, out=values) if clip: np.clip(values, 0, 1, out=values) return values @property def inverse(self): """A stretch object that performs the inverse operation.""" return ContrastBiasStretch(self.contrast, self.bias) class CompositeStretch(CompositeTransform, BaseStretch): """ A combination of two stretches. Parameters ---------- stretch_1 : :class:`astropy.visualization.BaseStretch` The first stretch to apply. stretch_2 : :class:`astropy.visualization.BaseStretch` The second stretch to apply. """ def __call__(self, values, clip=True, out=None): return self.transform_2( self.transform_1(values, clip=clip, out=out), clip=clip, out=out) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2152557 astropy-5.0.2/astropy/visualization/tests/0000755000175100001710000000000000000000000020011 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/tests/__init__.py0000644000175100001710000000010000000000000022111 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/tests/test_histogram.py0000644000175100001710000000437300000000000023426 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst from numpy.testing import assert_allclose from astropy.utils.compat.optional_deps import HAS_PLT, HAS_SCIPY if HAS_PLT: import matplotlib.pyplot as plt import pytest import numpy as np from astropy.visualization import hist from astropy.stats import histogram @pytest.mark.skipif('not HAS_PLT') def test_hist_basic(rseed=0): rng = np.random.default_rng(rseed) x = rng.standard_normal(100) for range in [None, (-2, 2)]: n1, bins1, patches1 = plt.hist(x, 10, range=range) n2, bins2, patches2 = hist(x, 10, range=range) assert_allclose(n1, n2) assert_allclose(bins1, bins2) @pytest.mark.skipif('not HAS_PLT') def test_hist_specify_ax(rseed=0): rng = np.random.default_rng(rseed) x = rng.standard_normal(100) fig, ax = plt.subplots(2) n1, bins1, patches1 = hist(x, 10, ax=ax[0]) assert patches1[0].axes is ax[0] n2, bins2, patches2 = hist(x, 10, ax=ax[1]) assert patches2[0].axes is ax[1] @pytest.mark.skipif('not HAS_PLT') def test_hist_autobin(rseed=0): rng = np.random.default_rng(rseed) x = rng.standard_normal(100) # 'knuth' bintype depends on scipy that is optional dependency if HAS_SCIPY: bintypes = [10, np.arange(-3, 3, 10), 'knuth', 'scott', 'freedman', 'blocks'] else: bintypes = [10, np.arange(-3, 3, 10), 'scott', 'freedman', 'blocks'] for bintype in bintypes: for range in [None, (-3, 3)]: n1, bins1 = histogram(x, bintype, range=range) n2, bins2, patches = hist(x, bintype, range=range) assert_allclose(n1, n2) assert_allclose(bins1, bins2) def test_histogram_pathological_input(): # Regression test for https://github.com/astropy/astropy/issues/7758 # The key feature of the data below is that one of the points is very, # very different than the rest. That leads to a large number of bins. data = [9.99999914e+05, -8.31312483e-03, 6.52755852e-02, 1.43104653e-03, -2.26311017e-02, 2.82660007e-03, 1.80307521e-02, 9.26294279e-03, 5.06606026e-02, 2.05418011e-03] with pytest.raises(ValueError): hist(data, bins='freedman', max_bins=10000) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/tests/test_interval.py0000644000175100001710000001220100000000000023242 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import pytest import numpy as np from astropy.utils import NumpyRNGContext from astropy.visualization.interval import (ManualInterval, MinMaxInterval, PercentileInterval, AsymmetricPercentileInterval, ZScaleInterval) class TestInterval: data = np.linspace(-20., 60., 100) def test_manual(self): interval = ManualInterval(-10., +15.) vmin, vmax = interval.get_limits(self.data) np.testing.assert_allclose(vmin, -10.) np.testing.assert_allclose(vmax, +15.) def test_manual_defaults(self): interval = ManualInterval(vmin=-10.) vmin, vmax = interval.get_limits(self.data) np.testing.assert_allclose(vmin, -10.) np.testing.assert_allclose(vmax, np.max(self.data)) interval = ManualInterval(vmax=15.) vmin, vmax = interval.get_limits(self.data) np.testing.assert_allclose(vmin, np.min(self.data)) np.testing.assert_allclose(vmax, 15.) def test_manual_zero_limit(self): # Regression test for a bug that caused ManualInterval to compute the # limit (min or max) if it was set to zero. interval = ManualInterval(vmin=0, vmax=0) vmin, vmax = interval.get_limits(self.data) np.testing.assert_allclose(vmin, 0) np.testing.assert_allclose(vmax, 0) def test_manual_defaults_with_nan(self): interval = ManualInterval() data = np.copy(self.data) data[0] = np.nan vmin, vmax = interval.get_limits(self.data) np.testing.assert_allclose(vmin, -20) np.testing.assert_allclose(vmax, +60) def test_minmax(self): interval = MinMaxInterval() vmin, vmax = interval.get_limits(self.data) np.testing.assert_allclose(vmin, -20.) np.testing.assert_allclose(vmax, +60.) def test_percentile(self): interval = PercentileInterval(62.2) vmin, vmax = interval.get_limits(self.data) np.testing.assert_allclose(vmin, -4.88) np.testing.assert_allclose(vmax, 44.88) def test_asymmetric_percentile(self): interval = AsymmetricPercentileInterval(10.5, 70.5) vmin, vmax = interval.get_limits(self.data) np.testing.assert_allclose(vmin, -11.6) np.testing.assert_allclose(vmax, 36.4) def test_asymmetric_percentile_nsamples(self): with NumpyRNGContext(12345): interval = AsymmetricPercentileInterval(10.5, 70.5, n_samples=20) vmin, vmax = interval.get_limits(self.data) np.testing.assert_allclose(vmin, -14.367676767676768) np.testing.assert_allclose(vmax, 40.266666666666666) class TestIntervalList(TestInterval): # Make sure intervals work with lists data = np.linspace(-20., 60., 100).tolist() class TestInterval2D(TestInterval): # Make sure intervals work with 2d arrays data = np.linspace(-20., 60., 100).reshape(100, 1) def test_zscale(): np.random.seed(42) data = np.random.randn(100, 100) * 5 + 10 interval = ZScaleInterval() vmin, vmax = interval.get_limits(data) np.testing.assert_allclose(vmin, -9.6, atol=0.1) np.testing.assert_allclose(vmax, 25.4, atol=0.1) data = list(range(1000)) + [np.nan] interval = ZScaleInterval() vmin, vmax = interval.get_limits(data) np.testing.assert_allclose(vmin, 0, atol=0.1) np.testing.assert_allclose(vmax, 999, atol=0.1) data = list(range(100)) interval = ZScaleInterval() vmin, vmax = interval.get_limits(data) np.testing.assert_allclose(vmin, 0, atol=0.1) np.testing.assert_allclose(vmax, 99, atol=0.1) def test_zscale_npoints(): """ Regression test to ensure ZScaleInterval returns the minimum and maximum of the data if the number of data points is less than ``min_pixels``. """ data = np.arange(4).reshape((2, 2)) interval = ZScaleInterval(min_npixels=5) vmin, vmax = interval.get_limits(data) assert vmin == 0 assert vmax == 3 def test_integers(): # Need to make sure integers get cast to float interval = MinMaxInterval() values = interval([1, 3, 4, 5, 6]) np.testing.assert_allclose(values, [0., 0.4, 0.6, 0.8, 1.0]) # Don't accept integer array in output out = np.zeros(5, dtype=int) with pytest.raises(TypeError) as exc: values = interval([1, 3, 4, 5, 6], out=out) assert exc.value.args[0] == ("Can only do in-place scaling for " "floating-point arrays") # But integer input and floating point output is fine out = np.zeros(5, dtype=float) interval([1, 3, 4, 5, 6], out=out) np.testing.assert_allclose(out, [0., 0.4, 0.6, 0.8, 1.0]) def test_constant_data(): """Test intervals with constant data (avoiding divide-by-zero).""" shape = (10, 10) data = np.ones(shape) interval = MinMaxInterval() limits = interval.get_limits(data) values = interval(data) np.testing.assert_allclose(limits, (1., 1.)) np.testing.assert_allclose(values, np.zeros(shape)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/tests/test_lupton_rgb.py0000644000175100001710000002201000000000000023570 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ Tests for RGB Images """ import sys import os import tempfile import pytest import numpy as np from numpy.testing import assert_equal from astropy.convolution import convolve, Gaussian2DKernel from astropy.visualization import lupton_rgb from astropy.utils.compat.optional_deps import HAS_MATPLOTLIB # noqa # Set display=True to get matplotlib imshow windows to help with debugging. display = False def display_rgb(rgb, title=None): """Display an rgb image using matplotlib (useful for debugging)""" import matplotlib.pyplot as plt plt.imshow(rgb, interpolation='nearest', origin='lower') if title: plt.title(title) plt.show() return plt def saturate(image, satValue): """ Return image with all points above satValue set to NaN. Simulates saturation on an image, so we can test 'replace_saturated_pixels' """ result = image.copy() saturated = image > satValue result[saturated] = np.nan return result def random_array(dtype, N=100): return np.array(np.random.random(10)*100, dtype=dtype) def test_compute_intensity_1_float(): image_r = random_array(np.float64) intensity = lupton_rgb.compute_intensity(image_r) assert image_r.dtype == intensity.dtype assert_equal(image_r, intensity) def test_compute_intensity_1_uint(): image_r = random_array(np.uint8) intensity = lupton_rgb.compute_intensity(image_r) assert image_r.dtype == intensity.dtype assert_equal(image_r, intensity) def test_compute_intensity_3_float(): image_r = random_array(np.float64) image_g = random_array(np.float64) image_b = random_array(np.float64) intensity = lupton_rgb.compute_intensity(image_r, image_g, image_b) assert image_r.dtype == intensity.dtype assert_equal(intensity, (image_r+image_g+image_b)/3.0) def test_compute_intensity_3_uint(): image_r = random_array(np.uint8) image_g = random_array(np.uint8) image_b = random_array(np.uint8) intensity = lupton_rgb.compute_intensity(image_r, image_g, image_b) assert image_r.dtype == intensity.dtype assert_equal(intensity, (image_r+image_g+image_b)//3) class TestLuptonRgb: """A test case for Rgb""" def setup_method(self, method): np.random.seed(1000) # so we always get the same images. self.min_, self.stretch_, self.Q = 0, 5, 20 # asinh width, height = 85, 75 self.width = width self.height = height shape = (width, height) image_r = np.zeros(shape) image_g = np.zeros(shape) image_b = np.zeros(shape) # pixel locations, values and colors points = [[15, 15], [50, 45], [30, 30], [45, 15]] values = [1000, 5500, 600, 20000] g_r = [1.0, -1.0, 1.0, 1.0] r_i = [2.0, -0.5, 2.5, 1.0] # Put pixels in the images. for p, v, gr, ri in zip(points, values, g_r, r_i): image_r[p[0], p[1]] = v*pow(10, 0.4*ri) image_g[p[0], p[1]] = v*pow(10, 0.4*gr) image_b[p[0], p[1]] = v # convolve the image with a reasonable PSF, and add Gaussian background noise def convolve_with_noise(image, psf): convolvedImage = convolve(image, psf, boundary='extend', normalize_kernel=True) randomImage = np.random.normal(0, 2, image.shape) return randomImage + convolvedImage psf = Gaussian2DKernel(2.5) self.image_r = convolve_with_noise(image_r, psf) self.image_g = convolve_with_noise(image_g, psf) self.image_b = convolve_with_noise(image_b, psf) def test_Asinh(self): """Test creating an RGB image using an asinh stretch""" asinhMap = lupton_rgb.AsinhMapping(self.min_, self.stretch_, self.Q) rgbImage = asinhMap.make_rgb_image(self.image_r, self.image_g, self.image_b) if display: display_rgb(rgbImage, title=sys._getframe().f_code.co_name) def test_AsinhZscale(self): """Test creating an RGB image using an asinh stretch estimated using zscale""" map = lupton_rgb.AsinhZScaleMapping(self.image_r, self.image_g, self.image_b) rgbImage = map.make_rgb_image(self.image_r, self.image_g, self.image_b) if display: display_rgb(rgbImage, title=sys._getframe().f_code.co_name) def test_AsinhZscaleIntensity(self): """Test creating an RGB image using an asinh stretch estimated using zscale on the intensity""" map = lupton_rgb.AsinhZScaleMapping(self.image_r, self.image_g, self.image_b) rgbImage = map.make_rgb_image(self.image_r, self.image_g, self.image_b) if display: display_rgb(rgbImage, title=sys._getframe().f_code.co_name) def test_AsinhZscaleIntensityPedestal(self): """Test creating an RGB image using an asinh stretch estimated using zscale on the intensity where the images each have a pedestal added""" pedestal = [100, 400, -400] self.image_r += pedestal[0] self.image_g += pedestal[1] self.image_b += pedestal[2] map = lupton_rgb.AsinhZScaleMapping(self.image_r, self.image_g, self.image_b, pedestal=pedestal) rgbImage = map.make_rgb_image(self.image_r, self.image_g, self.image_b) if display: display_rgb(rgbImage, title=sys._getframe().f_code.co_name) def test_AsinhZscaleIntensityBW(self): """Test creating a black-and-white image using an asinh stretch estimated using zscale on the intensity""" map = lupton_rgb.AsinhZScaleMapping(self.image_r) rgbImage = map.make_rgb_image(self.image_r, self.image_r, self.image_r) if display: display_rgb(rgbImage, title=sys._getframe().f_code.co_name) @pytest.mark.skipif('not HAS_MATPLOTLIB') def test_make_rgb(self): """Test the function that does it all""" satValue = 1000.0 with tempfile.NamedTemporaryFile(suffix=".png") as temp: red = saturate(self.image_r, satValue) green = saturate(self.image_g, satValue) blue = saturate(self.image_b, satValue) lupton_rgb.make_lupton_rgb(red, green, blue, self.min_, self.stretch_, self.Q, filename=temp) assert os.path.exists(temp.name) def test_make_rgb_saturated_fix(self): pytest.skip('saturation correction is not implemented') satValue = 1000.0 # TODO: Cannot test with these options yet, as that part of the code is not implemented. with tempfile.NamedTemporaryFile(suffix=".png") as temp: red = saturate(self.image_r, satValue) green = saturate(self.image_g, satValue) blue = saturate(self.image_b, satValue) lupton_rgb.make_lupton_rgb(red, green, blue, self.min_, self.stretch_, self.Q, saturated_border_width=1, saturated_pixel_value=2000, filename=temp) def test_linear(self): """Test using a specified linear stretch""" map = lupton_rgb.LinearMapping(-8.45, 13.44) rgbImage = map.make_rgb_image(self.image_r, self.image_g, self.image_b) if display: display_rgb(rgbImage, title=sys._getframe().f_code.co_name) def test_linear_min_max(self): """Test using a min/max linear stretch determined from one image""" map = lupton_rgb.LinearMapping(image=self.image_b) rgbImage = map.make_rgb_image(self.image_r, self.image_g, self.image_b) if display: display_rgb(rgbImage, title=sys._getframe().f_code.co_name) def test_saturated(self): """Test interpolationolating saturated pixels""" pytest.skip('replaceSaturatedPixels is not implemented in astropy yet') satValue = 1000.0 self.image_r = saturate(self.image_r, satValue) self.image_g = saturate(self.image_g, satValue) self.image_b = saturate(self.image_b, satValue) lupton_rgb.replaceSaturatedPixels(self.image_r, self.image_g, self.image_b, 1, 2000) # Check that we replaced those NaNs with some reasonable value assert np.isfinite(self.image_r.getImage().getArray()).all() assert np.isfinite(self.image_g.getImage().getArray()).all() assert np.isfinite(self.image_b.getImage().getArray()).all() # Prepare for generating an output file self.imagesR = self.imagesR.getImage() self.imagesR = self.imagesG.getImage() self.imagesR = self.imagesB.getImage() asinhMap = lupton_rgb.AsinhMapping(self.min_, self.stretch_, self.Q) rgbImage = asinhMap.make_rgb_image(self.image_r, self.image_g, self.image_b) if display: display_rgb(rgbImage, title=sys._getframe().f_code.co_name) def test_different_shapes_asserts(self): with pytest.raises(ValueError) as excinfo: # just swap the dimensions to get a differently-shaped 'r' image_r = self.image_r.reshape(self.height, self.width) lupton_rgb.make_lupton_rgb(image_r, self.image_g, self.image_b) assert "shapes must match" in str(excinfo.value) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/tests/test_norm.py0000644000175100001710000002607700000000000022411 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst from packaging.version import Version import pytest import numpy as np from numpy import ma from numpy.testing import assert_allclose, assert_equal from astropy.utils.exceptions import AstropyDeprecationWarning from astropy.visualization.mpl_normalize import ImageNormalize, simple_norm, imshow_norm from astropy.visualization.interval import ManualInterval, PercentileInterval from astropy.visualization.stretch import LogStretch, PowerStretch, SqrtStretch from astropy.utils.compat.optional_deps import HAS_MATPLOTLIB, HAS_PLT # noqa if HAS_MATPLOTLIB: import matplotlib MATPLOTLIB_LT_32 = Version(matplotlib.__version__) < Version('3.2') DATA = np.linspace(0., 15., 6) DATA2 = np.arange(3) DATA2SCL = 0.5 * DATA2 DATA3 = np.linspace(-3., 3., 7) STRETCHES = (SqrtStretch(), PowerStretch(0.5), LogStretch()) INVALID = (None, -np.inf, -1) @pytest.mark.skipif('HAS_MATPLOTLIB') def test_normalize_error_message(): with pytest.raises(ImportError) as exc: ImageNormalize() assert (exc.value.args[0] == "matplotlib is required in order to use " "this class.") @pytest.mark.skipif('not HAS_MATPLOTLIB') class TestNormalize: def test_invalid_interval(self): with pytest.raises(TypeError): ImageNormalize(vmin=2., vmax=10., interval=ManualInterval, clip=True) def test_invalid_stretch(self): with pytest.raises(TypeError): ImageNormalize(vmin=2., vmax=10., stretch=SqrtStretch, clip=True) def test_stretch_none(self): with pytest.raises(ValueError): ImageNormalize(vmin=2., vmax=10., stretch=None) def test_scalar(self): norm = ImageNormalize(vmin=2., vmax=10., stretch=SqrtStretch(), clip=True) norm2 = ImageNormalize(data=6, interval=ManualInterval(2, 10), stretch=SqrtStretch(), clip=True) assert_allclose(norm(6), 0.70710678) assert_allclose(norm(6), norm2(6)) def test_clip(self): norm = ImageNormalize(vmin=2., vmax=10., stretch=SqrtStretch(), clip=True) norm2 = ImageNormalize(DATA, interval=ManualInterval(2, 10), stretch=SqrtStretch(), clip=True) output = norm(DATA) expected = [0., 0.35355339, 0.70710678, 0.93541435, 1., 1.] assert_allclose(output, expected) assert_allclose(output.mask, [0, 0, 0, 0, 0, 0]) assert_allclose(output, norm2(DATA)) def test_noclip(self): norm = ImageNormalize(vmin=2., vmax=10., stretch=SqrtStretch(), clip=False, invalid=None) norm2 = ImageNormalize(DATA, interval=ManualInterval(2, 10), stretch=SqrtStretch(), clip=False, invalid=None) output = norm(DATA) expected = [np.nan, 0.35355339, 0.70710678, 0.93541435, 1.11803399, 1.27475488] assert_allclose(output, expected) assert_allclose(output.mask, [0, 0, 0, 0, 0, 0]) assert_allclose(norm.inverse(norm(DATA))[1:], DATA[1:]) assert_allclose(output, norm2(DATA)) def test_implicit_autoscale(self): norm = ImageNormalize(vmin=None, vmax=10., stretch=SqrtStretch(), clip=False) norm2 = ImageNormalize(DATA, interval=ManualInterval(None, 10), stretch=SqrtStretch(), clip=False) output = norm(DATA) assert norm.vmin == np.min(DATA) assert norm.vmax == 10. assert_allclose(output, norm2(DATA)) norm = ImageNormalize(vmin=2., vmax=None, stretch=SqrtStretch(), clip=False) norm2 = ImageNormalize(DATA, interval=ManualInterval(2, None), stretch=SqrtStretch(), clip=False) output = norm(DATA) assert norm.vmin == 2. assert norm.vmax == np.max(DATA) assert_allclose(output, norm2(DATA)) def test_call_clip(self): """Test that the clip keyword is used when calling the object.""" data = np.arange(5) norm = ImageNormalize(vmin=1., vmax=3., clip=False) output = norm(data, clip=True) assert_equal(output.data, [0, 0, 0.5, 1.0, 1.0]) assert np.all(~output.mask) output = norm(data, clip=False) assert_equal(output.data, [-0.5, 0, 0.5, 1.0, 1.5]) assert np.all(~output.mask) def test_masked_clip(self): mdata = ma.array(DATA, mask=[0, 0, 1, 0, 0, 0]) norm = ImageNormalize(vmin=2., vmax=10., stretch=SqrtStretch(), clip=True) norm2 = ImageNormalize(mdata, interval=ManualInterval(2, 10), stretch=SqrtStretch(), clip=True) output = norm(mdata) expected = [0., 0.35355339, 1., 0.93541435, 1., 1.] assert_allclose(output.filled(-10), expected) assert_allclose(output.mask, [0, 0, 0, 0, 0, 0]) assert_allclose(output, norm2(mdata)) def test_masked_noclip(self): mdata = ma.array(DATA, mask=[0, 0, 1, 0, 0, 0]) norm = ImageNormalize(vmin=2., vmax=10., stretch=SqrtStretch(), clip=False, invalid=None) norm2 = ImageNormalize(mdata, interval=ManualInterval(2, 10), stretch=SqrtStretch(), clip=False, invalid=None) output = norm(mdata) expected = [np.nan, 0.35355339, -10, 0.93541435, 1.11803399, 1.27475488] assert_allclose(output.filled(-10), expected) assert_allclose(output.mask, [0, 0, 1, 0, 0, 0]) assert_allclose(norm.inverse(norm(DATA))[1:], DATA[1:]) assert_allclose(output, norm2(mdata)) def test_invalid_data(self): data = np.arange(25.).reshape((5, 5)) data[2, 2] = np.nan data[1, 2] = np.inf percent = 85.0 interval = PercentileInterval(percent) # initialized without data norm = ImageNormalize(interval=interval) norm(data) # sets vmin/vmax assert_equal((norm.vmin, norm.vmax), (1.65, 22.35)) # initialized with data norm2 = ImageNormalize(data, interval=interval) assert_equal((norm2.vmin, norm2.vmax), (norm.vmin, norm.vmax)) norm3 = simple_norm(data, 'linear', percent=percent) assert_equal((norm3.vmin, norm3.vmax), (norm.vmin, norm.vmax)) assert_allclose(norm(data), norm2(data)) assert_allclose(norm(data), norm3(data)) norm4 = ImageNormalize() norm4(data) # sets vmin/vmax assert_equal((norm4.vmin, norm4.vmax), (0, 24)) norm5 = ImageNormalize(data) assert_equal((norm5.vmin, norm5.vmax), (norm4.vmin, norm4.vmax)) @pytest.mark.parametrize('stretch', STRETCHES) def test_invalid_keyword(self, stretch): norm1 = ImageNormalize(stretch=stretch, vmin=-1, vmax=1, clip=False, invalid=None) norm2 = ImageNormalize(stretch=stretch, vmin=-1, vmax=1, clip=False) norm3 = ImageNormalize(DATA3, stretch=stretch, vmin=-1, vmax=1, clip=False, invalid=-1.) result1 = norm1(DATA3) result2 = norm2(DATA3) result3 = norm3(DATA3) assert_equal(result1[0:2], (np.nan, np.nan)) assert_equal(result2[0:2], (-1., -1.)) assert_equal(result1[2:], result2[2:]) assert_equal(result2, result3) @pytest.mark.skipif('not HAS_MATPLOTLIB') class TestImageScaling: def test_linear(self): """Test linear scaling.""" norm = simple_norm(DATA2, stretch='linear') assert_allclose(norm(DATA2), DATA2SCL, atol=0, rtol=1.e-5) def test_sqrt(self): """Test sqrt scaling.""" norm1 = simple_norm(DATA2, stretch='sqrt') assert_allclose(norm1(DATA2), np.sqrt(DATA2SCL), atol=0, rtol=1.e-5) @pytest.mark.parametrize('invalid', INVALID) def test_sqrt_invalid_kw(self, invalid): stretch = SqrtStretch() norm1 = simple_norm(DATA3, stretch='sqrt', min_cut=-1, max_cut=1, clip=False, invalid=invalid) norm2 = ImageNormalize(stretch=stretch, vmin=-1, vmax=1, clip=False, invalid=invalid) assert_equal(norm1(DATA3), norm2(DATA3)) def test_power(self): """Test power scaling.""" power = 3.0 norm = simple_norm(DATA2, stretch='power', power=power) assert_allclose(norm(DATA2), DATA2SCL ** power, atol=0, rtol=1.e-5) def test_log(self): """Test log10 scaling.""" norm = simple_norm(DATA2, stretch='log') ref = np.log10(1000 * DATA2SCL + 1.0) / np.log10(1001.0) assert_allclose(norm(DATA2), ref, atol=0, rtol=1.e-5) def test_log_with_log_a(self): """Test log10 scaling with a custom log_a.""" log_a = 100 norm = simple_norm(DATA2, stretch='log', log_a=log_a) ref = np.log10(log_a * DATA2SCL + 1.0) / np.log10(log_a + 1) assert_allclose(norm(DATA2), ref, atol=0, rtol=1.e-5) def test_asinh(self): """Test asinh scaling.""" norm = simple_norm(DATA2, stretch='asinh') ref = np.arcsinh(10 * DATA2SCL) / np.arcsinh(10) assert_allclose(norm(DATA2), ref, atol=0, rtol=1.e-5) def test_asinh_with_asinh_a(self): """Test asinh scaling with a custom asinh_a.""" asinh_a = 0.5 norm = simple_norm(DATA2, stretch='asinh', asinh_a=asinh_a) ref = np.arcsinh(DATA2SCL / asinh_a) / np.arcsinh(1. / asinh_a) assert_allclose(norm(DATA2), ref, atol=0, rtol=1.e-5) def test_min(self): """Test linear scaling.""" norm = simple_norm(DATA2, stretch='linear', min_cut=1., clip=True) assert_allclose(norm(DATA2), [0., 0., 1.], atol=0, rtol=1.e-5) def test_percent(self): """Test percent keywords.""" norm = simple_norm(DATA2, stretch='linear', percent=99., clip=True) assert_allclose(norm(DATA2), DATA2SCL, atol=0, rtol=1.e-5) norm2 = simple_norm(DATA2, stretch='linear', min_percent=0.5, max_percent=99.5, clip=True) assert_allclose(norm(DATA2), norm2(DATA2), atol=0, rtol=1.e-5) def test_invalid_stretch(self): """Test invalid stretch keyword.""" with pytest.raises(ValueError): simple_norm(DATA2, stretch='invalid') @pytest.mark.skipif('not HAS_PLT') def test_imshow_norm(): import matplotlib.pyplot as plt image = np.random.randn(10, 10) ax = plt.subplot(label='test_imshow_norm') imshow_norm(image, ax=ax) with pytest.raises(ValueError): # X and data are the same, can't give both imshow_norm(image, X=image, ax=ax) with pytest.raises(ValueError): # illegal to manually pass in normalization since that defeats the point imshow_norm(image, ax=ax, norm=ImageNormalize()) imshow_norm(image, ax=ax, vmin=0, vmax=1) # make sure the pyplot version works imres, norm = imshow_norm(image, ax=None) assert isinstance(norm, ImageNormalize) plt.close('all') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/tests/test_stretch.py0000644000175100001710000001366300000000000023107 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import pytest import numpy as np from numpy.testing import assert_equal from astropy.visualization.stretch import (LinearStretch, SqrtStretch, PowerStretch, PowerDistStretch, InvertedPowerDistStretch, SquaredStretch, LogStretch, InvertedLogStretch, AsinhStretch, SinhStretch, HistEqStretch, InvertedHistEqStretch, ContrastBiasStretch) DATA = np.array([0.00, 0.25, 0.50, 0.75, 1.00]) RESULTS = {} RESULTS[LinearStretch()] = np.array([0.00, 0.25, 0.50, 0.75, 1.00]) RESULTS[LinearStretch(intercept=0.5) + LinearStretch(slope=0.5)] = \ np.array([0.5, 0.625, 0.75, 0.875, 1.]) RESULTS[SqrtStretch()] = np.array([0., 0.5, 0.70710678, 0.8660254, 1.]) RESULTS[SquaredStretch()] = np.array([0., 0.0625, 0.25, 0.5625, 1.]) RESULTS[PowerStretch(0.5)] = np.array([0., 0.5, 0.70710678, 0.8660254, 1.]) RESULTS[PowerDistStretch()] = np.array([0., 0.004628, 0.030653, 0.177005, 1.]) RESULTS[LogStretch()] = np.array([0., 0.799776, 0.899816, 0.958408, 1.]) RESULTS[AsinhStretch()] = np.array([0., 0.549402, 0.77127, 0.904691, 1.]) RESULTS[SinhStretch()] = np.array([0., 0.082085, 0.212548, 0.46828, 1.]) RESULTS[ContrastBiasStretch(contrast=2., bias=0.4)] = np.array([-0.3, 0.2, 0.7, 1.2, 1.7]) RESULTS[HistEqStretch(DATA)] = DATA RESULTS[HistEqStretch(DATA[::-1])] = DATA RESULTS[HistEqStretch(DATA ** 0.5)] = np.array([0., 0.125, 0.25, 0.5674767, 1.]) class TestStretch: @pytest.mark.parametrize('stretch', RESULTS.keys()) def test_no_clip(self, stretch): np.testing.assert_allclose(stretch(DATA, clip=False), RESULTS[stretch], atol=1.e-6) @pytest.mark.parametrize('ndim', [2, 3]) @pytest.mark.parametrize('stretch', RESULTS.keys()) def test_clip_ndimensional(self, stretch, ndim): new_shape = DATA.shape + (1,) * ndim np.testing.assert_allclose(stretch(DATA.reshape(new_shape), clip=True).ravel(), np.clip(RESULTS[stretch], 0., 1), atol=1.e-6) @pytest.mark.parametrize('stretch', RESULTS.keys()) def test_clip(self, stretch): np.testing.assert_allclose(stretch(DATA, clip=True), np.clip(RESULTS[stretch], 0., 1), atol=1.e-6) @pytest.mark.parametrize('stretch', RESULTS.keys()) def test_inplace(self, stretch): data_in = DATA.copy() result = np.zeros(DATA.shape) stretch(data_in, out=result, clip=False) np.testing.assert_allclose(result, RESULTS[stretch], atol=1.e-6) np.testing.assert_allclose(data_in, DATA) @pytest.mark.parametrize('stretch', RESULTS.keys()) def test_round_trip(self, stretch): np.testing.assert_allclose(stretch.inverse(stretch(DATA, clip=False), clip=False), DATA) @pytest.mark.parametrize('stretch', RESULTS.keys()) def test_inplace_roundtrip(self, stretch): result = np.zeros(DATA.shape) stretch(DATA, out=result, clip=False) stretch.inverse(result, out=result, clip=False) np.testing.assert_allclose(result, DATA) @pytest.mark.parametrize('stretch', RESULTS.keys()) def test_double_inverse(self, stretch): np.testing.assert_allclose(stretch.inverse.inverse(DATA), stretch(DATA), atol=1.e-6) def test_inverted(self): stretch_1 = SqrtStretch().inverse stretch_2 = PowerStretch(2) np.testing.assert_allclose(stretch_1(DATA), stretch_2(DATA)) def test_chaining(self): stretch_1 = SqrtStretch() + SqrtStretch() stretch_2 = PowerStretch(0.25) stretch_3 = PowerStretch(4.) np.testing.assert_allclose(stretch_1(DATA), stretch_2(DATA)) np.testing.assert_allclose(stretch_1.inverse(DATA), stretch_3(DATA)) def test_clip_invalid(): stretch = SqrtStretch() values = stretch([-1., 0., 0.5, 1., 1.5]) np.testing.assert_allclose(values, [0., 0., 0.70710678, 1., 1.]) values = stretch([-1., 0., 0.5, 1., 1.5], clip=False) np.testing.assert_allclose(values, [np.nan, 0., 0.70710678, 1., 1.2247448]) @pytest.mark.parametrize('a', [-2., -1, 1.]) def test_invalid_powerdist_a(a): match = 'a must be >= 0, but cannot be set to 1' with pytest.raises(ValueError, match=match): PowerDistStretch(a=a) with pytest.raises(ValueError, match=match): InvertedPowerDistStretch(a=a) @pytest.mark.parametrize('a', [-2., -1, 0.]) def test_invalid_power_log_a(a): match = 'a must be > 0' with pytest.raises(ValueError, match=match): PowerStretch(a=a) with pytest.raises(ValueError, match=match): LogStretch(a=a) with pytest.raises(ValueError, match=match): InvertedLogStretch(a=a) @pytest.mark.parametrize('a', [-2., -1, 0., 1.5]) def test_invalid_sinh_a(a): match = 'a must be > 0 and <= 1' with pytest.raises(ValueError, match=match): AsinhStretch(a=a) with pytest.raises(ValueError, match=match): SinhStretch(a=a) def test_histeqstretch_invalid(): data = np.array([-np.inf, 0.00, 0.25, 0.50, 0.75, 1.00, np.inf]) result = np.array([0.0, 0.0, 0.25, 0.5, 0.75, 1.0, 1.0]) assert_equal(HistEqStretch(data)(data), result) assert_equal(InvertedHistEqStretch(data)(data), result) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/tests/test_time.py0000644000175100001710000002006600000000000022364 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst import pytest pytest.importorskip('matplotlib') # noqa import matplotlib.pyplot as plt import matplotlib.dates from contextlib import nullcontext from erfa import ErfaWarning from astropy.time import Time from astropy.visualization.time import time_support # Matplotlib 3.3 added a settable epoch for plot dates and changed the default # from 0000-12-31 to 1970-01-01. This can be checked by the existence of # get_epoch() in matplotlib.dates. MPL_EPOCH_1970 = hasattr(matplotlib.dates, 'get_epoch') # Since some of the examples below use times/dates in the future, we use the # TAI time scale to avoid ERFA warnings about dubious years. DEFAULT_SCALE = 'tai' def get_ticklabels(axis): axis.figure.canvas.draw() return [x.get_text() for x in axis.get_ticklabels()] def teardown_function(function): plt.close('all') # We first check that we get the expected labels for different time intervals # for standard ISO formatting. This is a way to check both the locator and # formatter code. RANGE_CASES = [ # Interval of many years (('2014-03-22T12:30:30.9', '2077-03-22T12:30:32.1'), ['2020-01-01', '2040-01-01', '2060-01-01']), # Interval of a few years (('2014-03-22T12:30:30.9', '2017-03-22T12:30:32.1'), ['2015-01-01', '2016-01-01', '2017-01-01']), # Interval of just under a year (('2014-03-22T12:30:30.9', '2015-01-22T12:30:32.1'), ['2014-05-01', '2014-10-01']), # Interval of a few months (('2014-11-22T12:30:30.9', '2015-02-22T12:30:32.1'), ['2014-12-01', '2015-01-01', '2015-02-01']), # Interval of just over a month (('2014-03-22T12:30:30.9', '2014-04-23T12:30:32.1'), ['2014-04-01']), # Interval of just under a month (('2014-03-22T12:30:30.9', '2014-04-21T12:30:32.1'), ['2014-03-24', '2014-04-03', '2014-04-13']), # Interval of just over an hour (('2014-03-22T12:30:30.9', '2014-03-22T13:31:30.9'), ['2014-03-22T12:40:00.000', '2014-03-22T13:00:00.000', '2014-03-22T13:20:00.000']), # Interval of just under an hour (('2014-03-22T12:30:30.9', '2014-03-22T13:28:30.9'), ['2014-03-22T12:40:00.000', '2014-03-22T13:00:00.000', '2014-03-22T13:20:00.000']), # Interval of a few minutes (('2014-03-22T12:30:30.9', '2014-03-22T12:38:30.9'), ['2014-03-22T12:33:00.000', '2014-03-22T12:36:00.000']), # Interval of a few seconds (('2014-03-22T12:30:30.9', '2014-03-22T12:30:40.9'), ['2014-03-22T12:30:33.000', '2014-03-22T12:30:36.000', '2014-03-22T12:30:39.000']), # Interval of a couple of seconds (('2014-03-22T12:30:30.9', '2014-03-22T12:30:32.1'), ['2014-03-22T12:30:31.000', '2014-03-22T12:30:31.500', '2014-03-22T12:30:32.000']), # Interval of under a second (('2014-03-22T12:30:30.89', '2014-03-22T12:30:31.19'), ['2014-03-22T12:30:30.900', '2014-03-22T12:30:31.000', '2014-03-22T12:30:31.100']), ] @pytest.mark.parametrize(('interval', 'expected'), RANGE_CASES) def test_formatter_locator(interval, expected): # Check that the ticks and labels returned for the above cases are correct. with time_support(): fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.set_xlim(Time(interval[0], scale=DEFAULT_SCALE), Time(interval[1], scale=DEFAULT_SCALE)) assert get_ticklabels(ax.xaxis) == expected FORMAT_CASES = [ ('byear', ['2020', '2040', '2060']), ('byear_str', ['B2020.000', 'B2040.000', 'B2060.000']), ('cxcsec', ['1000000000', '1500000000', '2000000000', '2500000000']), ('decimalyear', ['2020', '2040', '2060']), ('fits', ['2020-01-01T00:00:00.000', '2040-01-01T00:00:00.000', '2060-01-01T00:00:00.000']), ('gps', ['1500000000', '2000000000', '2500000000', '3000000000']), ('iso', ['2020-01-01 00:00:00.000', '2040-01-01 00:00:00.000', '2060-01-01 00:00:00.000']), ('isot', ['2020-01-01T00:00:00.000', '2040-01-01T00:00:00.000', '2060-01-01T00:00:00.000']), ('jd', ['2458000', '2464000', '2470000', '2476000']), ('jyear', ['2020', '2040', '2060']), ('jyear_str', ['J2020.000', 'J2040.000', 'J2060.000']), ('mjd', ['60000', '66000', '72000', '78000']), ('plot_date', (['18000', '24000', '30000', '36000'] if MPL_EPOCH_1970 else ['738000', '744000', '750000', '756000'])), ('unix', ['1500000000', '2000000000', '2500000000', '3000000000']), ('yday', ['2020:001:00:00:00.000', '2040:001:00:00:00.000', '2060:001:00:00:00.000']), ] @pytest.mark.parametrize(('format', 'expected'), FORMAT_CASES) def test_formats(format, expected): # Check that the locators/formatters work fine for all time formats with time_support(format=format, simplify=False): fig = plt.figure() ax = fig.add_subplot(1, 1, 1) # Getting unix time and plot_date requires going through a scale for # which ERFA emits a warning about the date being dubious with pytest.warns(ErfaWarning) if format in ['unix', 'plot_date'] else nullcontext(): ax.set_xlim(Time('2014-03-22T12:30:30.9', scale=DEFAULT_SCALE), Time('2077-03-22T12:30:32.1', scale=DEFAULT_SCALE)) assert get_ticklabels(ax.xaxis) == expected ax.get_xlabel() == f'Time ({format})' @pytest.mark.parametrize(('format', 'expected'), FORMAT_CASES) def test_auto_formats(format, expected): # Check that the format/scale is taken from the first time used. with time_support(simplify=False): fig = plt.figure() ax = fig.add_subplot(1, 1, 1) # Getting unix time and plot_date requires going through a scale for # which ERFA emits a warning about the date being dubious with pytest.warns(ErfaWarning) if format in ['unix', 'plot_date'] else nullcontext(): ax.set_xlim(Time(Time('2014-03-22T12:30:30.9', scale=DEFAULT_SCALE), format=format), Time('2077-03-22T12:30:32.1', scale=DEFAULT_SCALE)) assert get_ticklabels(ax.xaxis) == expected ax.get_xlabel() == f'Time ({format})' FORMAT_CASES_SIMPLIFY = [ ('fits', ['2020-01-01', '2040-01-01', '2060-01-01']), ('iso', ['2020-01-01', '2040-01-01', '2060-01-01']), ('isot', ['2020-01-01', '2040-01-01', '2060-01-01']), ('yday', ['2020', '2040', '2060']), ] @pytest.mark.parametrize(('format', 'expected'), FORMAT_CASES_SIMPLIFY) def test_formats_simplify(format, expected): # Check the use of the simplify= option with time_support(format=format, simplify=True): fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.set_xlim(Time('2014-03-22T12:30:30.9', scale=DEFAULT_SCALE), Time('2077-03-22T12:30:32.1', scale=DEFAULT_SCALE)) assert get_ticklabels(ax.xaxis) == expected def test_plot(): # Make sure that plot() works properly with time_support(): fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.set_xlim(Time('2014-03-22T12:30:30.9', scale=DEFAULT_SCALE), Time('2077-03-22T12:30:32.1', scale=DEFAULT_SCALE)) ax.plot(Time(['2015-03-22T12:30:30.9', '2018-03-22T12:30:30.9', '2021-03-22T12:30:30.9'], scale=DEFAULT_SCALE)) def test_nested(): with time_support(format='iso', simplify=False): with time_support(format='yday', simplify=True): fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.set_xlim(Time('2014-03-22T12:30:30.9', scale=DEFAULT_SCALE), Time('2077-03-22T12:30:32.1', scale=DEFAULT_SCALE)) assert get_ticklabels(ax.xaxis) == ['2020', '2040', '2060'] fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.set_xlim(Time('2014-03-22T12:30:30.9', scale=DEFAULT_SCALE), Time('2077-03-22T12:30:32.1', scale=DEFAULT_SCALE)) assert get_ticklabels(ax.xaxis) == ['2020-01-01 00:00:00.000', '2040-01-01 00:00:00.000', '2060-01-01 00:00:00.000'] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/tests/test_units.py0000644000175100001710000000750200000000000022570 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst import io import pytest from astropy.utils.compat.optional_deps import HAS_PLT if HAS_PLT: import matplotlib.pyplot as plt import numpy as np from astropy import units as u from astropy.coordinates import Angle from astropy.visualization.units import quantity_support def teardown_function(function): plt.close('all') @pytest.mark.skipif('not HAS_PLT') def test_units(): plt.figure() with quantity_support(): buff = io.BytesIO() plt.plot([1, 2, 3] * u.m, [3, 4, 5] * u.kg, label='label') plt.plot([105, 210, 315] * u.cm, [3050, 3025, 3010] * u.g) plt.legend() # Also test fill_between, which requires actual conversion to ndarray # with numpy >=1.10 (#4654). plt.fill_between([1, 3] * u.m, [3, 5] * u.kg, [3050, 3010] * u.g) plt.savefig(buff, format='svg') assert plt.gca().xaxis.get_units() == u.m assert plt.gca().yaxis.get_units() == u.kg @pytest.mark.skipif('not HAS_PLT') def test_units_errbarr(): pytest.importorskip("matplotlib") plt.figure() with quantity_support(): x = [1, 2, 3] * u.s y = [1, 2, 3] * u.m yerr = [3, 2, 1] * u.cm fig, ax = plt.subplots() ax.errorbar(x, y, yerr=yerr) assert ax.xaxis.get_units() == u.s assert ax.yaxis.get_units() == u.m @pytest.mark.skipif('not HAS_PLT') def test_incompatible_units(): # NOTE: minversion check does not work properly for matplotlib dev. try: # https://github.com/matplotlib/matplotlib/pull/13005 from matplotlib.units import ConversionError except ImportError: err_type = u.UnitConversionError else: err_type = ConversionError plt.figure() with quantity_support(): plt.plot([1, 2, 3] * u.m) with pytest.raises(err_type): plt.plot([105, 210, 315] * u.kg) @pytest.mark.skipif('not HAS_PLT') def test_quantity_subclass(): """Check that subclasses are recognized. This sadly is not done by matplotlib.units itself, though there is a PR to change it: https://github.com/matplotlib/matplotlib/pull/13536 """ plt.figure() with quantity_support(): plt.scatter(Angle([1, 2, 3], u.deg), [3, 4, 5] * u.kg) plt.scatter([105, 210, 315] * u.arcsec, [3050, 3025, 3010] * u.g) plt.plot(Angle([105, 210, 315], u.arcsec), [3050, 3025, 3010] * u.g) assert plt.gca().xaxis.get_units() == u.deg assert plt.gca().yaxis.get_units() == u.kg @pytest.mark.skipif('not HAS_PLT') def test_nested(): with quantity_support(): with quantity_support(): fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.scatter(Angle([1, 2, 3], u.deg), [3, 4, 5] * u.kg) assert ax.xaxis.get_units() == u.deg assert ax.yaxis.get_units() == u.kg fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.scatter(Angle([1, 2, 3], u.arcsec), [3, 4, 5] * u.pc) assert ax.xaxis.get_units() == u.arcsec assert ax.yaxis.get_units() == u.pc @pytest.mark.skipif('not HAS_PLT') def test_empty_hist(): with quantity_support(): fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.hist([1, 2, 3, 4] * u.mmag, bins=100) # The second call results in an empty list being passed to the # unit converter in matplotlib >= 3.1 ax.hist([] * u.mmag, bins=100) @pytest.mark.skipif('not HAS_PLT') def test_radian_formatter(): with quantity_support(): fig, ax = plt.subplots() ax.plot([1, 2, 3], [1, 2, 3] * u.rad * np.pi) fig.canvas.draw() labels = [tl.get_text() for tl in ax.yaxis.get_ticklabels()] assert labels == ['Ī€/2', 'Ī€', '3Ī€/2', '2Ī€', '5Ī€/2', '3Ī€', '7Ī€/2'] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/time.py0000644000175100001710000002261200000000000020162 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst import numpy as np from datetime import datetime from astropy.time import Time from astropy import units as u __all__ = ['time_support'] __doctest_requires__ = {'time_support': ['matplotlib']} UNSUPPORTED_FORMATS = ('datetime', 'datetime64') YMDHMS_FORMATS = ('fits', 'iso', 'isot', 'yday') STR_FORMATS = YMDHMS_FORMATS + ('byear_str', 'jyear_str') def time_support(*, scale=None, format=None, simplify=True): """ Enable support for plotting `astropy.time.Time` instances in matplotlib. May be (optionally) used with a ``with`` statement. >>> import matplotlib.pyplot as plt >>> from astropy import units as u >>> from astropy import visualization >>> with visualization.time_support(): # doctest: +IGNORE_OUTPUT ... plt.figure() ... plt.plot(Time(['2016-03-22T12:30:31', '2016-03-22T12:30:38', '2016-03-22T12:34:40'])) ... plt.draw() Parameters ---------- scale : str, optional The time scale to use for the times on the axis. If not specified, the scale of the first Time object passed to Matplotlib is used. format : str, optional The time format to use for the times on the axis. If not specified, the format of the first Time object passed to Matplotlib is used. simplify : bool, optional If possible, simplify labels, e.g. by removing 00:00:00.000 times from ISO strings if all labels fall on that time. """ import matplotlib.units as units from matplotlib.ticker import MaxNLocator, ScalarFormatter from astropy.visualization.wcsaxes.utils import select_step_hour, select_step_scalar class AstropyTimeLocator(MaxNLocator): # Note: we default to AutoLocator since many time formats # can just use this. def __init__(self, converter, *args, **kwargs): kwargs['nbins'] = 4 super().__init__(*args, **kwargs) self._converter = converter def tick_values(self, vmin, vmax): # Where we put the ticks depends on the format we are using if self._converter.format in YMDHMS_FORMATS: # If we are here, we need to check what the range of values # is and decide how to find tick locations accordingly vrange = vmax - vmin if (self._converter.format != 'yday' and vrange > 31) or vrange > 366: # greater than a month # We need to be careful here since not all years and months have # the same length # Start off by converting the values from the range to # datetime objects, so that we can easily extract the year and # month. tmin = Time(vmin, scale=self._converter.scale, format='mjd').datetime tmax = Time(vmax, scale=self._converter.scale, format='mjd').datetime # Find the range of years ymin = tmin.year ymax = tmax.year if ymax > ymin + 1: # greater than a year # Find the step we want to use ystep = int(select_step_scalar(max(1, (ymax - ymin) / 3))) ymin = ystep * (ymin // ystep) # Generate the years for these steps times = [] for year in range(ymin, ymax + 1, ystep): times.append(datetime(year=year, month=1, day=1)) else: # greater than a month but less than a year mmin = tmin.month mmax = tmax.month + 12 * (ymax - ymin) mstep = int(select_step_scalar(max(1, (mmax - mmin) / 3))) mmin = mstep * max(1, mmin // mstep) # Generate the months for these steps times = [] for month in range(mmin, mmax + 1, mstep): times.append(datetime(year=ymin + (month - 1) // 12, month=(month - 1) % 12 + 1, day=1)) # Convert back to MJD values = Time(times, scale=self._converter.scale).mjd elif vrange > 1: # greater than a day self.set_params(steps=[1, 2, 5, 10]) values = super().tick_values(vmin, vmax) else: # Determine ideal step dv = (vmax - vmin) / 3 * 24 << u.hourangle # And round to nearest sensible value dv = select_step_hour(dv).to_value(u.hourangle) / 24 # Determine tick locations imin = np.ceil(vmin / dv) imax = np.floor(vmax / dv) values = np.arange(imin, imax + 1, dtype=np.int64) * dv else: values = super().tick_values(vmin, vmax) # Get rid of values outside of the input interval values = values[(values >= vmin) & (values <= vmax)] return values def __call__(self): vmin, vmax = self.axis.get_view_interval() return self.tick_values(vmin, vmax) class AstropyTimeFormatter(ScalarFormatter): def __init__(self, converter, *args, **kwargs): super().__init__(*args, **kwargs) self._converter = converter self.set_useOffset(False) self.set_scientific(False) def __call__(self, value, pos=None): # Needed for Matplotlib <3.1 if self._converter.format in STR_FORMATS: return self.format_ticks([value])[0] else: return super().__call__(value, pos=pos) def format_ticks(self, values): if len(values) == 0: return [] if self._converter.format in YMDHMS_FORMATS: times = Time(values, format='mjd', scale=self._converter.scale) formatted = getattr(times, self._converter.format) if self._converter.simplify: if self._converter.format in ('fits', 'iso', 'isot'): if all([x.endswith('00:00:00.000') for x in formatted]): split = ' ' if self._converter.format == 'iso' else 'T' formatted = [x.split(split)[0] for x in formatted] elif self._converter.format == 'yday': if all([x.endswith(':001:00:00:00.000') for x in formatted]): formatted = [x.split(':', 1)[0] for x in formatted] return formatted elif self._converter.format == 'byear_str': return Time(values, format='byear', scale=self._converter.scale).byear_str elif self._converter.format == 'jyear_str': return Time(values, format='jyear', scale=self._converter.scale).jyear_str else: return super().format_ticks(values) class MplTimeConverter(units.ConversionInterface): def __init__(self, scale=None, format=None, simplify=None): super().__init__() self.format = format self.scale = scale self.simplify = simplify # Keep track of original converter in case the context manager is # used in a nested way. self._original_converter = units.registry.get(Time) units.registry[Time] = self @property def format(self): return self._format @format.setter def format(self, value): if value in UNSUPPORTED_FORMATS: raise ValueError(f'time_support does not support format={value}') self._format = value def __enter__(self): return self def __exit__(self, type, value, tb): if self._original_converter is None: del units.registry[Time] else: units.registry[Time] = self._original_converter def default_units(self, x, axis): if isinstance(x, tuple): x = x[0] if self.format is None: self.format = x.format if self.scale is None: self.scale = x.scale return 'astropy_time' def convert(self, value, unit, axis): """ Convert a Time value to a scalar or array. """ scaled = getattr(value, self.scale) if self.format in YMDHMS_FORMATS: return scaled.mjd elif self.format == 'byear_str': return scaled.byear elif self.format == 'jyear_str': return scaled.jyear else: return getattr(scaled, self.format) def axisinfo(self, unit, axis): """ Return major and minor tick locators and formatters. """ majloc = AstropyTimeLocator(self) majfmt = AstropyTimeFormatter(self) return units.AxisInfo(majfmt=majfmt, majloc=majloc, label=f'Time ({self.scale})') return MplTimeConverter(scale=scale, format=format, simplify=simplify) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/transform.py0000644000175100001710000000213100000000000021231 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst __all__ = ['BaseTransform', 'CompositeTransform'] class BaseTransform: """ A transformation object. This is used to construct transformations such as scaling, stretching, and so on. """ def __add__(self, other): return CompositeTransform(other, self) class CompositeTransform(BaseTransform): """ A combination of two transforms. Parameters ---------- transform_1 : :class:`astropy.visualization.BaseTransform` The first transform to apply. transform_2 : :class:`astropy.visualization.BaseTransform` The second transform to apply. """ def __init__(self, transform_1, transform_2): super().__init__() self.transform_1 = transform_1 self.transform_2 = transform_2 def __call__(self, values, clip=True): return self.transform_2(self.transform_1(values, clip=clip), clip=clip) @property def inverse(self): return self.__class__(self.transform_2.inverse, self.transform_1.inverse) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/units.py0000644000175100001710000000755200000000000020374 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst import numpy as np __doctest_skip__ = ['quantity_support'] def quantity_support(format='latex_inline'): """ Enable support for plotting `astropy.units.Quantity` instances in matplotlib. May be (optionally) used with a ``with`` statement. >>> import matplotlib.pyplot as plt >>> from astropy import units as u >>> from astropy import visualization >>> with visualization.quantity_support(): ... plt.figure() ... plt.plot([1, 2, 3] * u.m) [...] ... plt.plot([101, 125, 150] * u.cm) [...] ... plt.draw() Parameters ---------- format : `astropy.units.format.Base` instance or str The name of a format or a formatter object. If not provided, defaults to ``latex_inline``. """ from astropy import units as u # import Angle just so we have a more or less complete list of Quantity # subclasses loaded - matplotlib needs them all separately! # NOTE: in matplotlib >=3.2, subclasses will be recognized automatically, # and once that becomes our minimum version, we can remove this, # adding just u.Quantity itself to the registry. from astropy.coordinates import Angle # noqa from matplotlib import units from matplotlib import ticker # Get all subclass for Quantity, since matplotlib checks on class, # not subclass. def all_issubclass(cls): return {cls}.union( [s for c in cls.__subclasses__() for s in all_issubclass(c)]) def rad_fn(x, pos=None): n = int((x / np.pi) * 2.0 + 0.25) if n == 0: return '0' elif n == 1: return 'Ī€/2' elif n == 2: return 'Ī€' elif n % 2 == 0: return f'{n // 2}Ī€' else: return f'{n}Ī€/2' class MplQuantityConverter(units.ConversionInterface): _all_issubclass_quantity = all_issubclass(u.Quantity) def __init__(self): # Keep track of original converter in case the context manager is # used in a nested way. self._original_converter = {} for cls in self._all_issubclass_quantity: self._original_converter[cls] = units.registry.get(cls) units.registry[cls] = self @staticmethod def axisinfo(unit, axis): if unit == u.radian: return units.AxisInfo( majloc=ticker.MultipleLocator(base=np.pi/2), majfmt=ticker.FuncFormatter(rad_fn), label=unit.to_string(), ) elif unit == u.degree: return units.AxisInfo( majloc=ticker.AutoLocator(), majfmt=ticker.FormatStrFormatter('%i°'), label=unit.to_string(), ) elif unit is not None: return units.AxisInfo(label=unit.to_string(format)) return None @staticmethod def convert(val, unit, axis): if isinstance(val, u.Quantity): return val.to_value(unit) elif isinstance(val, list) and val and isinstance(val[0], u.Quantity): return [v.to_value(unit) for v in val] else: return val @staticmethod def default_units(x, axis): if hasattr(x, 'unit'): return x.unit return None def __enter__(self): return self def __exit__(self, type, value, tb): for cls in self._all_issubclass_quantity: if self._original_converter[cls] is None: del units.registry[cls] else: units.registry[cls] = self._original_converter[cls] return MplQuantityConverter() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2152557 astropy-5.0.2/astropy/visualization/wcsaxes/0000755000175100001710000000000000000000000020324 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/__init__.py0000644000175100001710000000220700000000000022436 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst # The following few lines skip this module when running tests if matplotlib is # not available (and will have no impact otherwise) try: import pytest pytest.importorskip("matplotlib") del pytest except ImportError: pass from .core import * from .coordinate_helpers import CoordinateHelper from .coordinates_map import CoordinatesMap from .patches import * from astropy import config as _config class Conf(_config.ConfigNamespace): """ Configuration parameters for `astropy.visualization.wcsaxes`. """ coordinate_range_samples = _config.ConfigItem(50, 'The number of samples along each image axis when determining ' 'the range of coordinates in a plot.') frame_boundary_samples = _config.ConfigItem(1000, 'How many points to sample along the axes when determining ' 'tick locations.') grid_samples = _config.ConfigItem(1000, 'How many points to sample along grid lines.') contour_grid_samples = _config.ConfigItem(200, 'The grid size to use when drawing a grid using contours') conf = Conf() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/axislabels.py0000644000175100001710000001117400000000000023031 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import numpy as np from matplotlib import rcParams from matplotlib.text import Text import matplotlib.transforms as mtransforms from .frame import RectangularFrame class AxisLabels(Text): def __init__(self, frame, minpad=1, *args, **kwargs): # Use rcParams if the following parameters were not specified explicitly if 'weight' not in kwargs: kwargs['weight'] = rcParams['axes.labelweight'] if 'size' not in kwargs: kwargs['size'] = rcParams['axes.labelsize'] if 'color' not in kwargs: kwargs['color'] = rcParams['axes.labelcolor'] self._frame = frame super().__init__(*args, **kwargs) self.set_clip_on(True) self.set_visible_axes('all') self.set_ha('center') self.set_va('center') self._minpad = minpad self._visibility_rule = 'labels' def get_minpad(self, axis): try: return self._minpad[axis] except TypeError: return self._minpad def set_visible_axes(self, visible_axes): self._visible_axes = visible_axes def get_visible_axes(self): if self._visible_axes == 'all': return self._frame.keys() else: return [x for x in self._visible_axes if x in self._frame] def set_minpad(self, minpad): self._minpad = minpad def set_visibility_rule(self, value): allowed = ['always', 'labels', 'ticks'] if value not in allowed: raise ValueError(f"Axis label visibility rule must be one of{' / '.join(allowed)}") self._visibility_rule = value def get_visibility_rule(self): return self._visibility_rule def draw(self, renderer, bboxes, ticklabels_bbox, coord_ticklabels_bbox, ticks_locs, visible_ticks): if not self.get_visible(): return text_size = renderer.points_to_pixels(self.get_size()) # Flatten the bboxes for all coords and all axes ticklabels_bbox_list = [] for bbcoord in ticklabels_bbox.values(): for bbaxis in bbcoord.values(): ticklabels_bbox_list += bbaxis for axis in self.get_visible_axes(): if self.get_visibility_rule() == 'ticks': if not ticks_locs[axis]: continue elif self.get_visibility_rule() == 'labels': if not coord_ticklabels_bbox: continue padding = text_size * self.get_minpad(axis) # Find position of the axis label. For now we pick the mid-point # along the path but in future we could allow this to be a # parameter. x, y, normal_angle = self._frame[axis]._halfway_x_y_angle() label_angle = (normal_angle - 90.) % 360. if 135 < label_angle < 225: label_angle += 180 self.set_rotation(label_angle) # Find label position by looking at the bounding box of ticks' # labels and the image. It sets the default padding at 1 times the # axis label font size which can also be changed by setting # the minpad parameter. if isinstance(self._frame, RectangularFrame): if len(ticklabels_bbox_list) > 0 and ticklabels_bbox_list[0] is not None: coord_ticklabels_bbox[axis] = [mtransforms.Bbox.union(ticklabels_bbox_list)] else: coord_ticklabels_bbox[axis] = [None] visible = axis in visible_ticks and coord_ticklabels_bbox[axis][0] is not None if axis == 'l': if visible: x = coord_ticklabels_bbox[axis][0].xmin x = x - padding elif axis == 'r': if visible: x = coord_ticklabels_bbox[axis][0].x1 x = x + padding elif axis == 'b': if visible: y = coord_ticklabels_bbox[axis][0].ymin y = y - padding elif axis == 't': if visible: y = coord_ticklabels_bbox[axis][0].y1 y = y + padding else: # arbitrary axis x = x + np.cos(np.radians(normal_angle)) * (padding + text_size * 1.5) y = y + np.sin(np.radians(normal_angle)) * (padding + text_size * 1.5) self.set_position((x, y)) super().draw(renderer) bb = super().get_window_extent(renderer) bboxes.append(bb) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/coordinate_helpers.py0000644000175100001710000012565700000000000024567 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This file defines the classes used to represent a 'coordinate', which includes axes, ticks, tick labels, and grid lines. """ import warnings import numpy as np from matplotlib.ticker import Formatter from matplotlib.transforms import Affine2D, ScaledTranslation from matplotlib.patches import PathPatch from matplotlib.path import Path from matplotlib import rcParams from astropy import units as u from astropy.utils.exceptions import AstropyDeprecationWarning from .frame import RectangularFrame1D, EllipticalFrame from .formatter_locator import AngleFormatterLocator, ScalarFormatterLocator from .ticks import Ticks from .ticklabels import TickLabels from .axislabels import AxisLabels from .grid_paths import get_lon_lat_path, get_gridline_path __all__ = ['CoordinateHelper'] # Matplotlib's gridlines use Line2D, but ours use PathPatch. # Patches take a slightly different format of linestyle argument. LINES_TO_PATCHES_LINESTYLE = {'-': 'solid', '--': 'dashed', '-.': 'dashdot', ':': 'dotted', 'none': 'none', 'None': 'none', ' ': 'none', '': 'none'} def wrap_angle_at(values, coord_wrap): # On ARM processors, np.mod emits warnings if there are NaN values in the # array, although this doesn't seem to happen on other processors. with np.errstate(invalid='ignore'): return np.mod(values - coord_wrap, 360.) - (360. - coord_wrap) class CoordinateHelper: """ Helper class to control one of the coordinates in the :class:`~astropy.visualization.wcsaxes.WCSAxes`. Parameters ---------- parent_axes : :class:`~astropy.visualization.wcsaxes.WCSAxes` The axes the coordinate helper belongs to. parent_map : :class:`~astropy.visualization.wcsaxes.CoordinatesMap` The :class:`~astropy.visualization.wcsaxes.CoordinatesMap` object this coordinate belongs to. transform : `~matplotlib.transforms.Transform` The transform corresponding to this coordinate system. coord_index : int The index of this coordinate in the :class:`~astropy.visualization.wcsaxes.CoordinatesMap`. coord_type : {'longitude', 'latitude', 'scalar'} The type of this coordinate, which is used to determine the wrapping and boundary behavior of coordinates. Longitudes wrap at ``coord_wrap``, latitudes have to be in the range -90 to 90, and scalars are unbounded and do not wrap. coord_unit : `~astropy.units.Unit` The unit that this coordinate is in given the output of transform. format_unit : `~astropy.units.Unit`, optional The unit to use to display the coordinates. coord_wrap : float The angle at which the longitude wraps (defaults to 360) frame : `~astropy.visualization.wcsaxes.frame.BaseFrame` The frame of the :class:`~astropy.visualization.wcsaxes.WCSAxes`. """ def __init__(self, parent_axes=None, parent_map=None, transform=None, coord_index=None, coord_type='scalar', coord_unit=None, coord_wrap=None, frame=None, format_unit=None, default_label=None): # Keep a reference to the parent axes and the transform self.parent_axes = parent_axes self.parent_map = parent_map self.transform = transform self.coord_index = coord_index self.coord_unit = coord_unit self._format_unit = format_unit self.frame = frame self.default_label = default_label or '' self._auto_axislabel = True # Disable auto label for elliptical frames as it puts labels in # annoying places. if issubclass(self.parent_axes.frame_class, EllipticalFrame): self._auto_axislabel = False self.set_coord_type(coord_type, coord_wrap) # Initialize ticks self.dpi_transform = Affine2D() self.offset_transform = ScaledTranslation(0, 0, self.dpi_transform) self.ticks = Ticks(transform=parent_axes.transData + self.offset_transform) # Initialize tick labels self.ticklabels = TickLabels(self.frame, transform=None, # display coordinates figure=parent_axes.get_figure()) self.ticks.display_minor_ticks(rcParams['xtick.minor.visible']) self.minor_frequency = 5 # Initialize axis labels self.axislabels = AxisLabels(self.frame, transform=None, # display coordinates figure=parent_axes.get_figure()) # Initialize container for the grid lines self.grid_lines = [] # Initialize grid style. Take defaults from matplotlib.rcParams. # Based on matplotlib.axis.YTick._get_gridline. self.grid_lines_kwargs = {'visible': False, 'facecolor': 'none', 'edgecolor': rcParams['grid.color'], 'linestyle': LINES_TO_PATCHES_LINESTYLE[rcParams['grid.linestyle']], 'linewidth': rcParams['grid.linewidth'], 'alpha': rcParams['grid.alpha'], 'transform': self.parent_axes.transData} def grid(self, draw_grid=True, grid_type=None, **kwargs): """ Plot grid lines for this coordinate. Standard matplotlib appearance options (color, alpha, etc.) can be passed as keyword arguments. Parameters ---------- draw_grid : bool Whether to show the gridlines grid_type : {'lines', 'contours'} Whether to plot the contours by determining the grid lines in world coordinates and then plotting them in world coordinates (``'lines'``) or by determining the world coordinates at many positions in the image and then drawing contours (``'contours'``). The first is recommended for 2-d images, while for 3-d (or higher dimensional) cubes, the ``'contours'`` option is recommended. By default, 'lines' is used if the transform has an inverse, otherwise 'contours' is used. """ if grid_type == 'lines' and not self.transform.has_inverse: raise ValueError('The specified transform has no inverse, so the ' 'grid cannot be drawn using grid_type=\'lines\'') if grid_type is None: grid_type = 'lines' if self.transform.has_inverse else 'contours' if grid_type in ('lines', 'contours'): self._grid_type = grid_type else: raise ValueError("grid_type should be 'lines' or 'contours'") if 'color' in kwargs: kwargs['edgecolor'] = kwargs.pop('color') self.grid_lines_kwargs.update(kwargs) if self.grid_lines_kwargs['visible']: if not draw_grid: self.grid_lines_kwargs['visible'] = False else: self.grid_lines_kwargs['visible'] = True def set_coord_type(self, coord_type, coord_wrap=None): """ Set the coordinate type for the axis. Parameters ---------- coord_type : str One of 'longitude', 'latitude' or 'scalar' coord_wrap : float, optional The value to wrap at for angular coordinates """ self.coord_type = coord_type if coord_type == 'longitude' and coord_wrap is None: self.coord_wrap = 360 elif coord_type != 'longitude' and coord_wrap is not None: raise NotImplementedError('coord_wrap is not yet supported ' 'for non-longitude coordinates') else: self.coord_wrap = coord_wrap # Initialize tick formatter/locator if coord_type == 'scalar': self._coord_scale_to_deg = None self._formatter_locator = ScalarFormatterLocator(unit=self.coord_unit) elif coord_type in ['longitude', 'latitude']: if self.coord_unit is u.deg: self._coord_scale_to_deg = None else: self._coord_scale_to_deg = self.coord_unit.to(u.deg) self._formatter_locator = AngleFormatterLocator(unit=self.coord_unit, format_unit=self._format_unit) else: raise ValueError("coord_type should be one of 'scalar', 'longitude', or 'latitude'") def set_major_formatter(self, formatter): """ Set the formatter to use for the major tick labels. Parameters ---------- formatter : str or `~matplotlib.ticker.Formatter` The format or formatter to use. """ if isinstance(formatter, Formatter): raise NotImplementedError() # figure out how to swap out formatter elif isinstance(formatter, str): self._formatter_locator.format = formatter else: raise TypeError("formatter should be a string or a Formatter " "instance") def format_coord(self, value, format='auto'): """ Given the value of a coordinate, will format it according to the format of the formatter_locator. Parameters ---------- value : float The value to format format : {'auto', 'ascii', 'latex'}, optional The format to use - by default the formatting will be adjusted depending on whether Matplotlib is using LaTeX or MathTex. To get plain ASCII strings, use format='ascii'. """ if not hasattr(self, "_fl_spacing"): return "" # _update_ticks has not been called yet fl = self._formatter_locator if isinstance(fl, AngleFormatterLocator): # Convert to degrees if needed if self._coord_scale_to_deg is not None: value *= self._coord_scale_to_deg if self.coord_type == 'longitude': value = wrap_angle_at(value, self.coord_wrap) value = value * u.degree value = value.to_value(fl._unit) spacing = self._fl_spacing string = fl.formatter(values=[value] * fl._unit, spacing=spacing, format=format) return string[0] def set_separator(self, separator): """ Set the separator to use for the angle major tick labels. Parameters ---------- separator : str or tuple or None The separator between numbers in sexagesimal representation. Can be either a string or a tuple (or `None` for default). """ if not (self._formatter_locator.__class__ == AngleFormatterLocator): raise TypeError("Separator can only be specified for angle coordinates") if isinstance(separator, (str, tuple)) or separator is None: self._formatter_locator.sep = separator else: raise TypeError("separator should be a string, a tuple, or None") def set_format_unit(self, unit, decimal=None, show_decimal_unit=True): """ Set the unit for the major tick labels. Parameters ---------- unit : class:`~astropy.units.Unit` The unit to which the tick labels should be converted to. decimal : bool, optional Whether to use decimal formatting. By default this is `False` for degrees or hours (which therefore use sexagesimal formatting) and `True` for all other units. show_decimal_unit : bool, optional Whether to include units when in decimal mode. """ self._formatter_locator.format_unit = u.Unit(unit) self._formatter_locator.decimal = decimal self._formatter_locator.show_decimal_unit = show_decimal_unit def get_format_unit(self): """ Get the unit for the major tick labels. """ return self._formatter_locator.format_unit def set_ticks(self, values=None, spacing=None, number=None, size=None, width=None, color=None, alpha=None, direction=None, exclude_overlapping=None): """ Set the location and properties of the ticks. At most one of the options from ``values``, ``spacing``, or ``number`` can be specified. Parameters ---------- values : iterable, optional The coordinate values at which to show the ticks. spacing : float, optional The spacing between ticks. number : float, optional The approximate number of ticks shown. size : float, optional The length of the ticks in points color : str or tuple, optional A valid Matplotlib color for the ticks alpha : float, optional The alpha value (transparency) for the ticks. direction : {'in','out'}, optional Whether the ticks should point inwards or outwards. """ if sum([values is None, spacing is None, number is None]) < 2: raise ValueError("At most one of values, spacing, or number should " "be specified") if values is not None: self._formatter_locator.values = values elif spacing is not None: self._formatter_locator.spacing = spacing elif number is not None: self._formatter_locator.number = number if size is not None: self.ticks.set_ticksize(size) if width is not None: self.ticks.set_linewidth(width) if color is not None: self.ticks.set_color(color) if alpha is not None: self.ticks.set_alpha(alpha) if direction is not None: if direction in ('in', 'out'): self.ticks.set_tick_out(direction == 'out') else: raise ValueError("direction should be 'in' or 'out'") if exclude_overlapping is not None: warnings.warn("exclude_overlapping= should be passed to " "set_ticklabel instead of set_ticks", AstropyDeprecationWarning) self.ticklabels.set_exclude_overlapping(exclude_overlapping) def set_ticks_position(self, position): """ Set where ticks should appear Parameters ---------- position : str The axes on which the ticks for this coordinate should appear. Should be a string containing zero or more of ``'b'``, ``'t'``, ``'l'``, ``'r'``. For example, ``'lb'`` will lead the ticks to be shown on the left and bottom axis. """ self.ticks.set_visible_axes(position) def set_ticks_visible(self, visible): """ Set whether ticks are visible or not. Parameters ---------- visible : bool The visibility of ticks. Setting as ``False`` will hide ticks along this coordinate. """ self.ticks.set_visible(visible) def set_ticklabel(self, color=None, size=None, pad=None, exclude_overlapping=None, **kwargs): """ Set the visual properties for the tick labels. Parameters ---------- size : float, optional The size of the ticks labels in points color : str or tuple, optional A valid Matplotlib color for the tick labels pad : float, optional Distance in points between tick and label. exclude_overlapping : bool, optional Whether to exclude tick labels that overlap over each other. **kwargs Other keyword arguments are passed to :class:`matplotlib.text.Text`. """ if size is not None: self.ticklabels.set_size(size) if color is not None: self.ticklabels.set_color(color) if pad is not None: self.ticklabels.set_pad(pad) if exclude_overlapping is not None: self.ticklabels.set_exclude_overlapping(exclude_overlapping) self.ticklabels.set(**kwargs) def set_ticklabel_position(self, position): """ Set where tick labels should appear Parameters ---------- position : str The axes on which the tick labels for this coordinate should appear. Should be a string containing zero or more of ``'b'``, ``'t'``, ``'l'``, ``'r'``. For example, ``'lb'`` will lead the tick labels to be shown on the left and bottom axis. """ self.ticklabels.set_visible_axes(position) def set_ticklabel_visible(self, visible): """ Set whether the tick labels are visible or not. Parameters ---------- visible : bool The visibility of ticks. Setting as ``False`` will hide this coordinate's tick labels. """ self.ticklabels.set_visible(visible) def set_axislabel(self, text, minpad=1, **kwargs): """ Set the text and optionally visual properties for the axis label. Parameters ---------- text : str The axis label text. minpad : float, optional The padding for the label in terms of axis label font size. **kwargs Keywords are passed to :class:`matplotlib.text.Text`. These can include keywords to set the ``color``, ``size``, ``weight``, and other text properties. """ fontdict = kwargs.pop('fontdict', None) # NOTE: When using plt.xlabel/plt.ylabel, minpad can get set explicitly # to None so we need to make sure that in that case we change to a # default numerical value. if minpad is None: minpad = 1 self.axislabels.set_text(text) self.axislabels.set_minpad(minpad) self.axislabels.set(**kwargs) if fontdict is not None: self.axislabels.update(fontdict) def get_axislabel(self): """ Get the text for the axis label Returns ------- label : str The axis label """ return self.axislabels.get_text() def set_auto_axislabel(self, auto_label): """ Render default axis labels if no explicit label is provided. Parameters ---------- auto_label : `bool` `True` if default labels will be rendered. """ self._auto_axislabel = bool(auto_label) def get_auto_axislabel(self): """ Render default axis labels if no explicit label is provided. Returns ------- auto_axislabel : `bool` `True` if default labels will be rendered. """ return self._auto_axislabel def _get_default_axislabel(self): unit = self.get_format_unit() or self.coord_unit if not unit or unit is u.one or self.coord_type in ('longitude', 'latitude'): return f"{self.default_label}" else: return f"{self.default_label} [{unit:latex}]" def set_axislabel_position(self, position): """ Set where axis labels should appear Parameters ---------- position : str The axes on which the axis label for this coordinate should appear. Should be a string containing zero or more of ``'b'``, ``'t'``, ``'l'``, ``'r'``. For example, ``'lb'`` will lead the axis label to be shown on the left and bottom axis. """ self.axislabels.set_visible_axes(position) def set_axislabel_visibility_rule(self, rule): """ Set the rule used to determine when the axis label is drawn. Parameters ---------- rule : str If the rule is 'always' axis labels will always be drawn on the axis. If the rule is 'ticks' the label will only be drawn if ticks were drawn on that axis. If the rule is 'labels' the axis label will only be drawn if tick labels were drawn on that axis. """ self.axislabels.set_visibility_rule(rule) def get_axislabel_visibility_rule(self, rule): """ Get the rule used to determine when the axis label is drawn. """ return self.axislabels.get_visibility_rule() @property def locator(self): return self._formatter_locator.locator @property def formatter(self): return self._formatter_locator.formatter def _draw_grid(self, renderer): renderer.open_group('grid lines') self._update_ticks() if self.grid_lines_kwargs['visible']: if isinstance(self.frame, RectangularFrame1D): self._update_grid_lines_1d() else: if self._grid_type == 'lines': self._update_grid_lines() else: self._update_grid_contour() if self._grid_type == 'lines': frame_patch = self.frame.patch for path in self.grid_lines: p = PathPatch(path, **self.grid_lines_kwargs) p.set_clip_path(frame_patch) p.draw(renderer) elif self._grid is not None: for line in self._grid.collections: line.set(**self.grid_lines_kwargs) line.draw(renderer) renderer.close_group('grid lines') def _draw_ticks(self, renderer, bboxes, ticklabels_bbox): """ Draw all ticks and ticklabels. """ renderer.open_group('ticks') self.ticks.draw(renderer) self.ticklabels.draw(renderer, bboxes=bboxes, ticklabels_bbox=ticklabels_bbox, tick_out_size=self.ticks.out_size) renderer.close_group('ticks') def _draw_axislabels(self, renderer, bboxes, ticklabels_bbox, visible_ticks): # Render the default axis label if no axis label is set. if self._auto_axislabel and not self.get_axislabel(): self.set_axislabel(self._get_default_axislabel()) renderer.open_group('axis labels') self.axislabels.draw(renderer, bboxes=bboxes, ticklabels_bbox=ticklabels_bbox, coord_ticklabels_bbox=ticklabels_bbox[self], ticks_locs=self.ticks.ticks_locs, visible_ticks=visible_ticks) renderer.close_group('axis labels') def _update_ticks(self): if self.coord_index is None: return # TODO: this method should be optimized for speed # Here we determine the location and rotation of all the ticks. For # each axis, we can check the intersections for the specific # coordinate and once we have the tick positions, we can use the WCS # to determine the rotations. # Find the range of coordinates in all directions coord_range = self.parent_map.get_coord_range() # First find the ticks we want to show tick_world_coordinates, self._fl_spacing = self.locator(*coord_range[self.coord_index]) if self.ticks.get_display_minor_ticks(): minor_ticks_w_coordinates = self._formatter_locator.minor_locator(self._fl_spacing, self.get_minor_frequency(), *coord_range[self.coord_index]) # We want to allow non-standard rectangular frames, so we just rely on # the parent axes to tell us what the bounding frame is. from . import conf frame = self.frame.sample(conf.frame_boundary_samples) self.ticks.clear() self.ticklabels.clear() self.lblinfo = [] self.lbl_world = [] # Look up parent axes' transform from data to figure coordinates. # # See: # https://matplotlib.org/stable/tutorials/advanced/transforms_tutorial.html#the-transformation-pipeline transData = self.parent_axes.transData invertedTransLimits = transData.inverted() for axis, spine in frame.items(): if not isinstance(self.frame, RectangularFrame1D): # Determine tick rotation in display coordinates and compare to # the normal angle in display coordinates. pixel0 = spine.data world0 = spine.world[:, self.coord_index] with np.errstate(invalid='ignore'): world0 = self.transform.transform(pixel0)[:, self.coord_index] axes0 = transData.transform(pixel0) # Advance 2 pixels in figure coordinates pixel1 = axes0.copy() pixel1[:, 0] += 2.0 pixel1 = invertedTransLimits.transform(pixel1) with np.errstate(invalid='ignore'): world1 = self.transform.transform(pixel1)[:, self.coord_index] # Advance 2 pixels in figure coordinates pixel2 = axes0.copy() pixel2[:, 1] += 2.0 if self.frame.origin == 'lower' else -2.0 pixel2 = invertedTransLimits.transform(pixel2) with np.errstate(invalid='ignore'): world2 = self.transform.transform(pixel2)[:, self.coord_index] dx = (world1 - world0) dy = (world2 - world0) # Rotate by 90 degrees dx, dy = -dy, dx if self.coord_type == 'longitude': if self._coord_scale_to_deg is not None: dx *= self._coord_scale_to_deg dy *= self._coord_scale_to_deg # Here we wrap at 180 not self.coord_wrap since we want to # always ensure abs(dx) < 180 and abs(dy) < 180 dx = wrap_angle_at(dx, 180.) dy = wrap_angle_at(dy, 180.) tick_angle = np.degrees(np.arctan2(dy, dx)) normal_angle_full = np.hstack([spine.normal_angle, spine.normal_angle[-1]]) with np.errstate(invalid='ignore'): reset = (((normal_angle_full - tick_angle) % 360 > 90.) & ((tick_angle - normal_angle_full) % 360 > 90.)) tick_angle[reset] -= 180. else: rotation = 90 if axis == 'b' else -90 tick_angle = np.zeros((conf.frame_boundary_samples,)) + rotation # We find for each interval the starting and ending coordinate, # ensuring that we take wrapping into account correctly for # longitudes. w1 = spine.world[:-1, self.coord_index] w2 = spine.world[1:, self.coord_index] if self.coord_type == 'longitude': if self._coord_scale_to_deg is not None: w1 = w1 * self._coord_scale_to_deg w2 = w2 * self._coord_scale_to_deg w1 = wrap_angle_at(w1, self.coord_wrap) w2 = wrap_angle_at(w2, self.coord_wrap) with np.errstate(invalid='ignore'): w1[w2 - w1 > 180.] += 360 w2[w1 - w2 > 180.] += 360 if self._coord_scale_to_deg is not None: w1 = w1 / self._coord_scale_to_deg w2 = w2 / self._coord_scale_to_deg # For longitudes, we need to check ticks as well as ticks + 360, # since the above can produce pairs such as 359 to 361 or 0.5 to # 1.5, both of which would match a tick at 0.75. Otherwise we just # check the ticks determined above. self._compute_ticks(tick_world_coordinates, spine, axis, w1, w2, tick_angle) if self.ticks.get_display_minor_ticks(): self._compute_ticks(minor_ticks_w_coordinates, spine, axis, w1, w2, tick_angle, ticks='minor') # format tick labels, add to scene text = self.formatter(self.lbl_world * tick_world_coordinates.unit, spacing=self._fl_spacing) for kwargs, txt in zip(self.lblinfo, text): self.ticklabels.add(text=txt, **kwargs) def _compute_ticks(self, tick_world_coordinates, spine, axis, w1, w2, tick_angle, ticks='major'): if self.coord_type == 'longitude': tick_world_coordinates_values = tick_world_coordinates.to_value(u.deg) tick_world_coordinates_values = np.hstack([tick_world_coordinates_values, tick_world_coordinates_values + 360]) tick_world_coordinates_values *= u.deg.to(self.coord_unit) else: tick_world_coordinates_values = tick_world_coordinates.to_value(self.coord_unit) for t in tick_world_coordinates_values: # Find steps where a tick is present. We have to check # separately for the case where the tick falls exactly on the # frame points, otherwise we'll get two matches, one for w1 and # one for w2. with np.errstate(invalid='ignore'): intersections = np.hstack([np.nonzero((t - w1) == 0)[0], np.nonzero(((t - w1) * (t - w2)) < 0)[0]]) # But we also need to check for intersection with the last w2 if t - w2[-1] == 0: intersections = np.append(intersections, len(w2) - 1) # Loop over ticks, and find exact pixel coordinates by linear # interpolation for imin in intersections: imax = imin + 1 if np.allclose(w1[imin], w2[imin], rtol=1.e-13, atol=1.e-13): continue # tick is exactly aligned with frame else: frac = (t - w1[imin]) / (w2[imin] - w1[imin]) x_data_i = spine.data[imin, 0] + frac * (spine.data[imax, 0] - spine.data[imin, 0]) y_data_i = spine.data[imin, 1] + frac * (spine.data[imax, 1] - spine.data[imin, 1]) x_pix_i = spine.pixel[imin, 0] + frac * (spine.pixel[imax, 0] - spine.pixel[imin, 0]) y_pix_i = spine.pixel[imin, 1] + frac * (spine.pixel[imax, 1] - spine.pixel[imin, 1]) delta_angle = tick_angle[imax] - tick_angle[imin] if delta_angle > 180.: delta_angle -= 360. elif delta_angle < -180.: delta_angle += 360. angle_i = tick_angle[imin] + frac * delta_angle if self.coord_type == 'longitude': if self._coord_scale_to_deg is not None: t *= self._coord_scale_to_deg world = wrap_angle_at(t, self.coord_wrap) if self._coord_scale_to_deg is not None: world /= self._coord_scale_to_deg else: world = t if ticks == 'major': self.ticks.add(axis=axis, pixel=(x_data_i, y_data_i), world=world, angle=angle_i, axis_displacement=imin + frac) # store information to pass to ticklabels.add # it's faster to format many ticklabels at once outside # of the loop self.lblinfo.append(dict(axis=axis, pixel=(x_pix_i, y_pix_i), world=world, angle=spine.normal_angle[imin], axis_displacement=imin + frac)) self.lbl_world.append(world) else: self.ticks.add_minor(minor_axis=axis, minor_pixel=(x_data_i, y_data_i), minor_world=world, minor_angle=angle_i, minor_axis_displacement=imin + frac) def display_minor_ticks(self, display_minor_ticks): """ Display minor ticks for this coordinate. Parameters ---------- display_minor_ticks : bool Whether or not to display minor ticks. """ self.ticks.display_minor_ticks(display_minor_ticks) def get_minor_frequency(self): return self.minor_frequency def set_minor_frequency(self, frequency): """ Set the frequency of minor ticks per major ticks. Parameters ---------- frequency : int The number of minor ticks per major ticks. """ self.minor_frequency = frequency def _update_grid_lines_1d(self): if self.coord_index is None: return x_ticks_pos = [a[0] for a in self.ticks.pixel['b']] ymin, ymax = self.parent_axes.get_ylim() self.grid_lines = [] for x_coord in x_ticks_pos: pixel = [[x_coord, ymin], [x_coord, ymax]] self.grid_lines.append(Path(pixel)) def _update_grid_lines(self): # For 3-d WCS with a correlated third axis, the *proper* way of # drawing a grid should be to find the world coordinates of all pixels # and drawing contours. What we are doing here assumes that we can # define the grid lines with just two of the coordinates (and # therefore assumes that the other coordinates are fixed and set to # the value in the slice). Here we basically assume that if the WCS # had a third axis, it has been abstracted away in the transformation. if self.coord_index is None: return coord_range = self.parent_map.get_coord_range() tick_world_coordinates, spacing = self.locator(*coord_range[self.coord_index]) tick_world_coordinates_values = tick_world_coordinates.to_value(self.coord_unit) n_coord = len(tick_world_coordinates_values) from . import conf n_samples = conf.grid_samples xy_world = np.zeros((n_samples * n_coord, 2)) self.grid_lines = [] for iw, w in enumerate(tick_world_coordinates_values): subset = slice(iw * n_samples, (iw + 1) * n_samples) if self.coord_index == 0: xy_world[subset, 0] = np.repeat(w, n_samples) xy_world[subset, 1] = np.linspace(coord_range[1][0], coord_range[1][1], n_samples) else: xy_world[subset, 0] = np.linspace(coord_range[0][0], coord_range[0][1], n_samples) xy_world[subset, 1] = np.repeat(w, n_samples) # We now convert all the world coordinates to pixel coordinates in a # single go rather than doing this in the gridline to path conversion # to fully benefit from vectorized coordinate transformations. # Transform line to pixel coordinates pixel = self.transform.inverted().transform(xy_world) # Create round-tripped values for checking xy_world_round = self.transform.transform(pixel) for iw in range(n_coord): subset = slice(iw * n_samples, (iw + 1) * n_samples) self.grid_lines.append(self._get_gridline(xy_world[subset], pixel[subset], xy_world_round[subset])) def _get_gridline(self, xy_world, pixel, xy_world_round): if self.coord_type == 'scalar': return get_gridline_path(xy_world, pixel) else: return get_lon_lat_path(xy_world, pixel, xy_world_round) def _clear_grid_contour(self): if hasattr(self, '_grid') and self._grid: for line in self._grid.collections: line.remove() def _update_grid_contour(self): if self.coord_index is None: return xmin, xmax = self.parent_axes.get_xlim() ymin, ymax = self.parent_axes.get_ylim() from . import conf res = conf.contour_grid_samples x, y = np.meshgrid(np.linspace(xmin, xmax, res), np.linspace(ymin, ymax, res)) pixel = np.array([x.ravel(), y.ravel()]).T world = self.transform.transform(pixel) field = world[:, self.coord_index].reshape(res, res).T coord_range = self.parent_map.get_coord_range() tick_world_coordinates, spacing = self.locator(*coord_range[self.coord_index]) # tick_world_coordinates is a Quantities array and we only needs its values tick_world_coordinates_values = tick_world_coordinates.value if self.coord_type == 'longitude': # Find biggest gap in tick_world_coordinates and wrap in middle # For now just assume spacing is equal, so any mid-point will do mid = 0.5 * (tick_world_coordinates_values[0] + tick_world_coordinates_values[1]) field = wrap_angle_at(field, mid) tick_world_coordinates_values = wrap_angle_at(tick_world_coordinates_values, mid) # Replace wraps by NaN with np.errstate(invalid='ignore'): reset = (np.abs(np.diff(field[:, :-1], axis=0)) > 180) | (np.abs(np.diff(field[:-1, :], axis=1)) > 180) field[:-1, :-1][reset] = np.nan field[1:, :-1][reset] = np.nan field[:-1, 1:][reset] = np.nan field[1:, 1:][reset] = np.nan if len(tick_world_coordinates_values) > 0: with np.errstate(invalid='ignore'): self._grid = self.parent_axes.contour(x, y, field.transpose(), levels=np.sort(tick_world_coordinates_values)) else: self._grid = None def tick_params(self, which='both', **kwargs): """ Method to set the tick and tick label parameters in the same way as the :meth:`~matplotlib.axes.Axes.tick_params` method in Matplotlib. This is provided for convenience, but the recommended API is to use :meth:`~astropy.visualization.wcsaxes.CoordinateHelper.set_ticks`, :meth:`~astropy.visualization.wcsaxes.CoordinateHelper.set_ticklabel`, :meth:`~astropy.visualization.wcsaxes.CoordinateHelper.set_ticks_position`, :meth:`~astropy.visualization.wcsaxes.CoordinateHelper.set_ticklabel_position`, and :meth:`~astropy.visualization.wcsaxes.CoordinateHelper.grid`. Parameters ---------- which : {'both', 'major', 'minor'}, optional Which ticks to apply the settings to. By default, setting are applied to both major and minor ticks. Note that if ``'minor'`` is specified, only the length of the ticks can be set currently. direction : {'in', 'out'}, optional Puts ticks inside the axes, or outside the axes. length : float, optional Tick length in points. width : float, optional Tick width in points. color : color, optional Tick color (accepts any valid Matplotlib color) pad : float, optional Distance in points between tick and label. labelsize : float or str, optional Tick label font size in points or as a string (e.g., 'large'). labelcolor : color, optional Tick label color (accepts any valid Matplotlib color) colors : color, optional Changes the tick color and the label color to the same value (accepts any valid Matplotlib color). bottom, top, left, right : bool, optional Where to draw the ticks. Note that this will not work correctly if the frame is not rectangular. labelbottom, labeltop, labelleft, labelright : bool, optional Where to draw the tick labels. Note that this will not work correctly if the frame is not rectangular. grid_color : color, optional The color of the grid lines (accepts any valid Matplotlib color). grid_alpha : float, optional Transparency of grid lines: 0 (transparent) to 1 (opaque). grid_linewidth : float, optional Width of grid lines in points. grid_linestyle : str, optional The style of the grid lines (accepts any valid Matplotlib line style). """ # First do some sanity checking on the keyword arguments # colors= is a fallback default for color and labelcolor if 'colors' in kwargs: if 'color' not in kwargs: kwargs['color'] = kwargs['colors'] if 'labelcolor' not in kwargs: kwargs['labelcolor'] = kwargs['colors'] # The only property that can be set *specifically* for minor ticks is # the length. In future we could consider having a separate Ticks instance # for minor ticks so that e.g. the color can be set separately. if which == 'minor': if len(set(kwargs) - {'length'}) > 0: raise ValueError("When setting which='minor', the only " "property that can be set at the moment is " "'length' (the minor tick length)") else: if 'length' in kwargs: self.ticks.set_minor_ticksize(kwargs['length']) return # At this point, we can now ignore the 'which' argument. # Set the tick arguments self.set_ticks(size=kwargs.get('length'), width=kwargs.get('width'), color=kwargs.get('color'), direction=kwargs.get('direction')) # Set the tick position position = None for arg in ('bottom', 'left', 'top', 'right'): if arg in kwargs and position is None: position = '' if kwargs.get(arg): position += arg[0] if position is not None: self.set_ticks_position(position) # Set the tick label arguments. self.set_ticklabel(color=kwargs.get('labelcolor'), size=kwargs.get('labelsize'), pad=kwargs.get('pad')) # Set the tick label position position = None for arg in ('bottom', 'left', 'top', 'right'): if 'label' + arg in kwargs and position is None: position = '' if kwargs.get('label' + arg): position += arg[0] if position is not None: self.set_ticklabel_position(position) # And the grid settings if 'grid_color' in kwargs: self.grid_lines_kwargs['edgecolor'] = kwargs['grid_color'] if 'grid_alpha' in kwargs: self.grid_lines_kwargs['alpha'] = kwargs['grid_alpha'] if 'grid_linewidth' in kwargs: self.grid_lines_kwargs['linewidth'] = kwargs['grid_linewidth'] if 'grid_linestyle' in kwargs: if kwargs['grid_linestyle'] in LINES_TO_PATCHES_LINESTYLE: self.grid_lines_kwargs['linestyle'] = LINES_TO_PATCHES_LINESTYLE[kwargs['grid_linestyle']] else: self.grid_lines_kwargs['linestyle'] = kwargs['grid_linestyle'] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/coordinate_range.py0000644000175100001710000001132200000000000024200 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import warnings import numpy as np from astropy import units as u # Algorithm inspired by PGSBOX from WCSLIB by M. Calabretta LONLAT = {'longitude', 'latitude'} def wrap_180(values): values_new = values % 360. with np.errstate(invalid='ignore'): values_new[values_new > 180.] -= 360 return values_new def find_coordinate_range(transform, extent, coord_types, coord_units, coord_wraps): """ Find the range of coordinates to use for ticks/grids Parameters ---------- transform : func Function to transform pixel to world coordinates. Should take two values (the pixel coordinates) and return two values (the world coordinates). extent : iterable The range of the image viewport in pixel coordinates, given as [xmin, xmax, ymin, ymax]. coord_types : list of str Whether each coordinate is a ``'longitude'``, ``'latitude'``, or ``'scalar'`` value. coord_units : list of `astropy.units.Unit` The units for each coordinate. coord_wraps : list of float The wrap angles for longitudes. """ # Sample coordinates on a NX x NY grid. from . import conf if len(extent) == 4: nx = ny = conf.coordinate_range_samples x = np.linspace(extent[0], extent[1], nx + 1) y = np.linspace(extent[2], extent[3], ny + 1) xp, yp = np.meshgrid(x, y) with np.errstate(invalid='ignore'): world = transform.transform(np.vstack([xp.ravel(), yp.ravel()]).transpose()) else: nx = conf.coordinate_range_samples xp = np.linspace(extent[0], extent[1], nx + 1)[None] with np.errstate(invalid='ignore'): world = transform.transform(xp.T) ranges = [] for coord_index, coord_type in enumerate(coord_types): xw = world[:, coord_index].reshape(xp.shape) if coord_type in LONLAT: unit = coord_units[coord_index] xw = xw * unit.to(u.deg) # Iron out coordinates along first row wjump = xw[0, 1:] - xw[0, :-1] with np.errstate(invalid='ignore'): reset = np.abs(wjump) > 180. if np.any(reset): wjump = wjump + np.sign(wjump) * 180. wjump = 360. * (wjump / 360.).astype(int) xw[0, 1:][reset] -= wjump[reset] # Now iron out coordinates along all columns, starting with first row. wjump = xw[1:] - xw[:1] with np.errstate(invalid='ignore'): reset = np.abs(wjump) > 180. if np.any(reset): wjump = wjump + np.sign(wjump) * 180. wjump = 360. * (wjump / 360.).astype(int) xw[1:][reset] -= wjump[reset] with warnings.catch_warnings(): warnings.simplefilter("ignore", RuntimeWarning) xw_min = np.nanmin(xw) xw_max = np.nanmax(xw) # Check if range is smaller when normalizing to the range 0 to 360 if coord_type in LONLAT: with warnings.catch_warnings(): warnings.simplefilter("ignore", RuntimeWarning) xw_min_check = np.nanmin(xw % 360.) xw_max_check = np.nanmax(xw % 360.) if xw_max_check - xw_min_check <= xw_max - xw_min < 360.: xw_min = xw_min_check xw_max = xw_max_check # Check if range is smaller when normalizing to the range -180 to 180 if coord_type in LONLAT: with warnings.catch_warnings(): warnings.simplefilter("ignore", RuntimeWarning) xw_min_check = np.nanmin(wrap_180(xw)) xw_max_check = np.nanmax(wrap_180(xw)) if xw_max_check - xw_min_check < 360. and xw_max - xw_min >= xw_max_check - xw_min_check: xw_min = xw_min_check xw_max = xw_max_check x_range = xw_max - xw_min if coord_type == 'longitude': if x_range > 300.: xw_min = coord_wraps[coord_index] - 360 xw_max = coord_wraps[coord_index] - np.spacing(360.) elif xw_min < 0.: xw_min = max(-180., xw_min - 0.1 * x_range) xw_max = min(+180., xw_max + 0.1 * x_range) else: xw_min = max(0., xw_min - 0.1 * x_range) xw_max = min(360., xw_max + 0.1 * x_range) elif coord_type == 'latitude': xw_min = max(-90., xw_min - 0.1 * x_range) xw_max = min(+90., xw_max + 0.1 * x_range) if coord_type in LONLAT: xw_min *= u.deg.to(unit) xw_max *= u.deg.to(unit) ranges.append((xw_min, xw_max)) return ranges ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/coordinates_map.py0000644000175100001710000001721100000000000024047 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst from textwrap import indent from collections import OrderedDict from .coordinate_helpers import CoordinateHelper from .frame import RectangularFrame, RectangularFrame1D from .coordinate_range import find_coordinate_range class CoordinatesMap: """ A container for coordinate helpers that represents a coordinate system. This object can be used to access coordinate helpers by index (like a list) or by name (like a dictionary). Parameters ---------- axes : :class:`~astropy.visualization.wcsaxes.WCSAxes` The axes the coordinate map belongs to. transform : `~matplotlib.transforms.Transform`, optional The transform for the data. coord_meta : dict, optional A dictionary providing additional metadata. This should include the keys ``type``, ``wrap``, and ``unit``. Each of these should be a list with as many items as the dimension of the coordinate system. The ``type`` entries should be one of ``longitude``, ``latitude``, or ``scalar``, the ``wrap`` entries should give, for the longitude, the angle at which the coordinate wraps (and `None` otherwise), and the ``unit`` should give the unit of the coordinates as :class:`~astropy.units.Unit` instances. This can optionally also include a ``format_unit`` entry giving the units to use for the tick labels (if not specified, this defaults to ``unit``). frame_class : type, optional The class for the frame, which should be a subclass of :class:`~astropy.visualization.wcsaxes.frame.BaseFrame`. The default is to use a :class:`~astropy.visualization.wcsaxes.frame.RectangularFrame` previous_frame_path : `~matplotlib.path.Path`, optional When changing the WCS of the axes, the frame instance will change but we might want to keep re-using the same underlying matplotlib `~matplotlib.path.Path` - in that case, this can be passed to this keyword argument. """ def __init__(self, axes, transform=None, coord_meta=None, frame_class=RectangularFrame, previous_frame_path=None): self._axes = axes self._transform = transform self.frame = frame_class(axes, self._transform, path=previous_frame_path) # Set up coordinates self._coords = [] self._aliases = {} visible_count = 0 for index in range(len(coord_meta['type'])): # Extract coordinate metadata coord_type = coord_meta['type'][index] coord_wrap = coord_meta['wrap'][index] coord_unit = coord_meta['unit'][index] name = coord_meta['name'][index] visible = True if 'visible' in coord_meta: visible = coord_meta['visible'][index] format_unit = None if 'format_unit' in coord_meta: format_unit = coord_meta['format_unit'][index] default_label = name[0] if isinstance(name, (tuple, list)) else name if 'default_axis_label' in coord_meta: default_label = coord_meta['default_axis_label'][index] coord_index = None if visible: visible_count += 1 coord_index = visible_count - 1 self._coords.append(CoordinateHelper(parent_axes=axes, parent_map=self, transform=self._transform, coord_index=coord_index, coord_type=coord_type, coord_wrap=coord_wrap, coord_unit=coord_unit, format_unit=format_unit, frame=self.frame, default_label=default_label)) # Set up aliases for coordinates if isinstance(name, tuple): for nm in name: nm = nm.lower() # Do not replace an alias already in the map if we have # more than one alias for this axis. if nm not in self._aliases: self._aliases[nm] = index else: self._aliases[name.lower()] = index def __getitem__(self, item): if isinstance(item, str): return self._coords[self._aliases[item.lower()]] else: return self._coords[item] def __contains__(self, item): if isinstance(item, str): return item.lower() in self._aliases else: return 0 <= item < len(self._coords) def set_visible(self, visibility): raise NotImplementedError() def __iter__(self): for coord in self._coords: yield coord def grid(self, draw_grid=True, grid_type=None, **kwargs): """ Plot gridlines for both coordinates. Standard matplotlib appearance options (color, alpha, etc.) can be passed as keyword arguments. Parameters ---------- draw_grid : bool Whether to show the gridlines grid_type : { 'lines' | 'contours' } Whether to plot the contours by determining the grid lines in world coordinates and then plotting them in world coordinates (``'lines'``) or by determining the world coordinates at many positions in the image and then drawing contours (``'contours'``). The first is recommended for 2-d images, while for 3-d (or higher dimensional) cubes, the ``'contours'`` option is recommended. By default, 'lines' is used if the transform has an inverse, otherwise 'contours' is used. """ for coord in self: coord.grid(draw_grid=draw_grid, grid_type=grid_type, **kwargs) def get_coord_range(self): xmin, xmax = self._axes.get_xlim() if isinstance(self.frame, RectangularFrame1D): extent = [xmin, xmax] else: ymin, ymax = self._axes.get_ylim() extent = [xmin, xmax, ymin, ymax] return find_coordinate_range(self._transform, extent, [coord.coord_type for coord in self if coord.coord_index is not None], [coord.coord_unit for coord in self if coord.coord_index is not None], [coord.coord_wrap for coord in self if coord.coord_index is not None]) def _as_table(self): # Import Table here to avoid importing the astropy.table package # every time astropy.visualization.wcsaxes is imported. from astropy.table import Table # noqa rows = [] for icoord, coord in enumerate(self._coords): aliases = [key for key, value in self._aliases.items() if value == icoord] row = OrderedDict([('index', icoord), ('aliases', ' '.join(aliases)), ('type', coord.coord_type), ('unit', coord.coord_unit), ('wrap', coord.coord_wrap), ('format_unit', coord.get_format_unit()), ('visible', 'no' if coord.coord_index is None else 'yes')]) rows.append(row) return Table(rows=rows) def __repr__(self): s = f'' ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/core.py0000644000175100001710000007557700000000000021653 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst from functools import partial from collections import defaultdict import numpy as np from matplotlib import rcParams from matplotlib.artist import Artist from matplotlib.axes import Axes, subplot_class_factory from matplotlib.transforms import Affine2D, Bbox, Transform import astropy.units as u from astropy.coordinates import SkyCoord, BaseCoordinateFrame from astropy.wcs import WCS from astropy.wcs.wcsapi import BaseHighLevelWCS, BaseLowLevelWCS from .transforms import CoordinateTransform from .coordinates_map import CoordinatesMap from .utils import get_coord_meta, transform_contour_set_inplace from .frame import RectangularFrame, RectangularFrame1D from .wcsapi import IDENTITY, transform_coord_meta_from_wcs __all__ = ['WCSAxes', 'WCSAxesSubplot'] VISUAL_PROPERTIES = ['facecolor', 'edgecolor', 'linewidth', 'alpha', 'linestyle'] class _WCSAxesArtist(Artist): """This is a dummy artist to enforce the correct z-order of axis ticks, tick labels, and gridlines. FIXME: This is a bit of a hack. ``Axes.draw`` sorts the artists by zorder and then renders them in sequence. For normal Matplotlib axes, the ticks, tick labels, and gridlines are included in this list of artists and hence are automatically drawn in the correct order. However, ``WCSAxes`` disables the native ticks, labels, and gridlines. Instead, ``WCSAxes.draw`` renders ersatz ticks, labels, and gridlines by explicitly calling the functions ``CoordinateHelper._draw_ticks``, ``CoordinateHelper._draw_grid``, etc. This hack would not be necessary if ``WCSAxes`` drew ticks, tick labels, and gridlines in the standary way.""" def draw(self, renderer, *args, **kwargs): self.axes.draw_wcsaxes(renderer) class WCSAxes(Axes): """ The main axes class that can be used to show world coordinates from a WCS. Parameters ---------- fig : `~matplotlib.figure.Figure` The figure to add the axes to rect : list The position of the axes in the figure in relative units. Should be given as ``[left, bottom, width, height]``. wcs : :class:`~astropy.wcs.WCS`, optional The WCS for the data. If this is specified, ``transform`` cannot be specified. transform : `~matplotlib.transforms.Transform`, optional The transform for the data. If this is specified, ``wcs`` cannot be specified. coord_meta : dict, optional A dictionary providing additional metadata when ``transform`` is specified. This should include the keys ``type``, ``wrap``, and ``unit``. Each of these should be a list with as many items as the dimension of the WCS. The ``type`` entries should be one of ``longitude``, ``latitude``, or ``scalar``, the ``wrap`` entries should give, for the longitude, the angle at which the coordinate wraps (and `None` otherwise), and the ``unit`` should give the unit of the coordinates as :class:`~astropy.units.Unit` instances. This can optionally also include a ``format_unit`` entry giving the units to use for the tick labels (if not specified, this defaults to ``unit``). transData : `~matplotlib.transforms.Transform`, optional Can be used to override the default data -> pixel mapping. slices : tuple, optional For WCS transformations with more than two dimensions, we need to choose which dimensions are being shown in the 2D image. The slice should contain one ``x`` entry, one ``y`` entry, and the rest of the values should be integers indicating the slice through the data. The order of the items in the slice should be the same as the order of the dimensions in the :class:`~astropy.wcs.WCS`, and the opposite of the order of the dimensions in Numpy. For example, ``(50, 'x', 'y')`` means that the first WCS dimension (last Numpy dimension) will be sliced at an index of 50, the second WCS and Numpy dimension will be shown on the x axis, and the final WCS dimension (first Numpy dimension) will be shown on the y-axis (and therefore the data will be plotted using ``data[:, :, 50].transpose()``) frame_class : type, optional The class for the frame, which should be a subclass of :class:`~astropy.visualization.wcsaxes.frame.BaseFrame`. The default is to use a :class:`~astropy.visualization.wcsaxes.frame.RectangularFrame` """ def __init__(self, fig, rect, wcs=None, transform=None, coord_meta=None, transData=None, slices=None, frame_class=None, **kwargs): """ """ super().__init__(fig, rect, **kwargs) self._bboxes = [] if frame_class is not None: self.frame_class = frame_class elif (wcs is not None and (wcs.pixel_n_dim == 1 or (slices is not None and 'y' not in slices))): self.frame_class = RectangularFrame1D else: self.frame_class = RectangularFrame if not (transData is None): # User wants to override the transform for the final # data->pixel mapping self.transData = transData self.reset_wcs(wcs=wcs, slices=slices, transform=transform, coord_meta=coord_meta) self._hide_parent_artists() self.format_coord = self._display_world_coords self._display_coords_index = 0 fig.canvas.mpl_connect('key_press_event', self._set_cursor_prefs) self.patch = self.coords.frame.patch self._wcsaxesartist = _WCSAxesArtist() self.add_artist(self._wcsaxesartist) self._drawn = False def _display_world_coords(self, x, y): if not self._drawn: return "" if self._display_coords_index == -1: return f"{x} {y} (pixel)" pixel = np.array([x, y]) coords = self._all_coords[self._display_coords_index] world = coords._transform.transform(np.array([pixel]))[0] coord_strings = [] for idx, coord in enumerate(coords): if coord.coord_index is not None: coord_strings.append(coord.format_coord(world[coord.coord_index], format='ascii')) coord_string = ' '.join(coord_strings) if self._display_coords_index == 0: system = "world" else: system = f"world, overlay {self._display_coords_index}" coord_string = f"{coord_string} ({system})" return coord_string def _set_cursor_prefs(self, event, **kwargs): if event.key == 'w': self._display_coords_index += 1 if self._display_coords_index + 1 > len(self._all_coords): self._display_coords_index = -1 def _hide_parent_artists(self): # Turn off spines and current axes for s in self.spines.values(): s.set_visible(False) self.xaxis.set_visible(False) if self.frame_class is not RectangularFrame1D: self.yaxis.set_visible(False) # We now overload ``imshow`` because we need to make sure that origin is # set to ``lower`` for all images, which means that we need to flip RGB # images. def imshow(self, X, *args, **kwargs): """ Wrapper to Matplotlib's :meth:`~matplotlib.axes.Axes.imshow`. If an RGB image is passed as a PIL object, it will be flipped vertically and ``origin`` will be set to ``lower``, since WCS transformations - like FITS files - assume that the origin is the lower left pixel of the image (whereas RGB images have the origin in the top left). All arguments are passed to :meth:`~matplotlib.axes.Axes.imshow`. """ origin = kwargs.pop('origin', 'lower') # plt.imshow passes origin as None, which we should default to lower. if origin is None: origin = 'lower' elif origin == 'upper': raise ValueError("Cannot use images with origin='upper' in WCSAxes.") # To check whether the image is a PIL image we can check if the data # has a 'getpixel' attribute - this is what Matplotlib's AxesImage does try: from PIL.Image import Image, FLIP_TOP_BOTTOM except ImportError: # We don't need to worry since PIL is not installed, so user cannot # have passed RGB image. pass else: if isinstance(X, Image) or hasattr(X, 'getpixel'): X = X.transpose(FLIP_TOP_BOTTOM) return super().imshow(X, *args, origin=origin, **kwargs) def contour(self, *args, **kwargs): """ Plot contours. This is a custom implementation of :meth:`~matplotlib.axes.Axes.contour` which applies the transform (if specified) to all contours in one go for performance rather than to each contour line individually. All positional and keyword arguments are the same as for :meth:`~matplotlib.axes.Axes.contour`. """ # In Matplotlib, when calling contour() with a transform, each # individual path in the contour map is transformed separately. However, # this is much too slow for us since each call to the transforms results # in an Astropy coordinate transformation, which has a non-negligible # overhead - therefore a better approach is to override contour(), call # the Matplotlib one with no transform, then apply the transform in one # go to all the segments that make up the contour map. transform = kwargs.pop('transform', None) cset = super().contour(*args, **kwargs) if transform is not None: # The transform passed to self.contour will normally include # a transData component at the end, but we can remove that since # we are already working in data space. transform = transform - self.transData transform_contour_set_inplace(cset, transform) return cset def contourf(self, *args, **kwargs): """ Plot filled contours. This is a custom implementation of :meth:`~matplotlib.axes.Axes.contourf` which applies the transform (if specified) to all contours in one go for performance rather than to each contour line individually. All positional and keyword arguments are the same as for :meth:`~matplotlib.axes.Axes.contourf`. """ # See notes for contour above. transform = kwargs.pop('transform', None) cset = super().contourf(*args, **kwargs) if transform is not None: # The transform passed to self.contour will normally include # a transData component at the end, but we can remove that since # we are already working in data space. transform = transform - self.transData transform_contour_set_inplace(cset, transform) return cset def plot_coord(self, *args, **kwargs): """ Plot `~astropy.coordinates.SkyCoord` or `~astropy.coordinates.BaseCoordinateFrame` objects onto the axes. The first argument to :meth:`~astropy.visualization.wcsaxes.WCSAxes.plot_coord` should be a coordinate, which will then be converted to the first two parameters to `matplotlib.axes.Axes.plot`. All other arguments are the same as `matplotlib.axes.Axes.plot`. If not specified a ``transform`` keyword argument will be created based on the coordinate. Parameters ---------- coordinate : `~astropy.coordinates.SkyCoord` or `~astropy.coordinates.BaseCoordinateFrame` The coordinate object to plot on the axes. This is converted to the first two arguments to `matplotlib.axes.Axes.plot`. See Also -------- matplotlib.axes.Axes.plot : This method is called from this function with all arguments passed to it. """ if isinstance(args[0], (SkyCoord, BaseCoordinateFrame)): # Extract the frame from the first argument. frame0 = args[0] if isinstance(frame0, SkyCoord): frame0 = frame0.frame native_frame = self._transform_pixel2world.frame_out # Transform to the native frame of the plot frame0 = frame0.transform_to(native_frame) plot_data = [] for coord in self.coords: if coord.coord_type == 'longitude': plot_data.append(frame0.spherical.lon.to_value(u.deg)) elif coord.coord_type == 'latitude': plot_data.append(frame0.spherical.lat.to_value(u.deg)) else: raise NotImplementedError("Coordinates cannot be plotted with this " "method because the WCS does not represent longitude/latitude.") if 'transform' in kwargs.keys(): raise TypeError("The 'transform' keyword argument is not allowed," " as it is automatically determined by the input coordinate frame.") transform = self.get_transform(native_frame) kwargs.update({'transform': transform}) args = tuple(plot_data) + args[1:] return super().plot(*args, **kwargs) def reset_wcs(self, wcs=None, slices=None, transform=None, coord_meta=None): """ Reset the current Axes, to use a new WCS object. """ # Here determine all the coordinate axes that should be shown. if wcs is None and transform is None: self.wcs = IDENTITY else: # We now force call 'set', which ensures the WCS object is # consistent, which will only be important if the WCS has been set # by hand. For example if the user sets a celestial WCS by hand and # forgets to set the units, WCS.wcs.set() will do this. if wcs is not None: # Check if the WCS object is an instance of `astropy.wcs.WCS` # This check is necessary as only `astropy.wcs.WCS` supports # wcs.set() method if isinstance(wcs, WCS): wcs.wcs.set() if isinstance(wcs, BaseHighLevelWCS): wcs = wcs.low_level_wcs self.wcs = wcs # If we are making a new WCS, we need to preserve the path object since # it may already be used by objects that have been plotted, and we need # to continue updating it. CoordinatesMap will create a new frame # instance, but we can tell that instance to keep using the old path. if hasattr(self, 'coords'): previous_frame = {'path': self.coords.frame._path, 'color': self.coords.frame.get_color(), 'linewidth': self.coords.frame.get_linewidth()} else: previous_frame = {'path': None} if self.wcs is not None: transform, coord_meta = transform_coord_meta_from_wcs(self.wcs, self.frame_class, slices=slices) self.coords = CoordinatesMap(self, transform=transform, coord_meta=coord_meta, frame_class=self.frame_class, previous_frame_path=previous_frame['path']) self._transform_pixel2world = transform if previous_frame['path'] is not None: self.coords.frame.set_color(previous_frame['color']) self.coords.frame.set_linewidth(previous_frame['linewidth']) self._all_coords = [self.coords] # Common default settings for Rectangular Frame for ind, pos in enumerate(coord_meta.get('default_axislabel_position', ['b', 'l'])): self.coords[ind].set_axislabel_position(pos) for ind, pos in enumerate(coord_meta.get('default_ticklabel_position', ['b', 'l'])): self.coords[ind].set_ticklabel_position(pos) for ind, pos in enumerate(coord_meta.get('default_ticks_position', ['bltr', 'bltr'])): self.coords[ind].set_ticks_position(pos) if rcParams['axes.grid']: self.grid() def draw_wcsaxes(self, renderer): if not self.axison: return # Here need to find out range of all coordinates, and update range for # each coordinate axis. For now, just assume it covers the whole sky. self._bboxes = [] # This generates a structure like [coords][axis] = [...] ticklabels_bbox = defaultdict(partial(defaultdict, list)) visible_ticks = [] for coords in self._all_coords: coords.frame.update() for coord in coords: coord._draw_grid(renderer) for coords in self._all_coords: for coord in coords: coord._draw_ticks(renderer, bboxes=self._bboxes, ticklabels_bbox=ticklabels_bbox[coord]) visible_ticks.extend(coord.ticklabels.get_visible_axes()) for coords in self._all_coords: for coord in coords: coord._draw_axislabels(renderer, bboxes=self._bboxes, ticklabels_bbox=ticklabels_bbox, visible_ticks=visible_ticks) self.coords.frame.draw(renderer) def draw(self, renderer, **kwargs): """Draw the axes.""" # Before we do any drawing, we need to remove any existing grid lines # drawn with contours, otherwise if we try and remove the contours # part way through drawing, we end up with the issue mentioned in # https://github.com/astropy/astropy/issues/12446 for coords in self._all_coords: for coord in coords: coord._clear_grid_contour() # In Axes.draw, the following code can result in the xlim and ylim # values changing, so we need to force call this here to make sure that # the limits are correct before we update the patch. locator = self.get_axes_locator() if locator: pos = locator(self, renderer) self.apply_aspect(pos) else: self.apply_aspect() if self._axisbelow is True: self._wcsaxesartist.set_zorder(0.5) elif self._axisbelow is False: self._wcsaxesartist.set_zorder(2.5) else: # 'line': above patches, below lines self._wcsaxesartist.set_zorder(1.5) # We need to make sure that that frame path is up to date self.coords.frame._update_patch_path() super().draw(renderer, **kwargs) self._drawn = True # Matplotlib internally sometimes calls set_xlabel(label=...). def set_xlabel(self, xlabel=None, labelpad=1, loc=None, **kwargs): """Set x-label.""" if xlabel is None: xlabel = kwargs.pop('label', None) if xlabel is None: raise TypeError("set_xlabel() missing 1 required positional argument: 'xlabel'") for coord in self.coords: if ('b' in coord.axislabels.get_visible_axes() or 'h' in coord.axislabels.get_visible_axes()): coord.set_axislabel(xlabel, minpad=labelpad, **kwargs) break def set_ylabel(self, ylabel=None, labelpad=1, loc=None, **kwargs): """Set y-label""" if ylabel is None: ylabel = kwargs.pop('label', None) if ylabel is None: raise TypeError("set_ylabel() missing 1 required positional argument: 'ylabel'") if self.frame_class is RectangularFrame1D: return super().set_ylabel(ylabel, labelpad=labelpad, **kwargs) for coord in self.coords: if ('l' in coord.axislabels.get_visible_axes() or 'c' in coord.axislabels.get_visible_axes()): coord.set_axislabel(ylabel, minpad=labelpad, **kwargs) break def get_xlabel(self): for coord in self.coords: if ('b' in coord.axislabels.get_visible_axes() or 'h' in coord.axislabels.get_visible_axes()): return coord.get_axislabel() def get_ylabel(self): if self.frame_class is RectangularFrame1D: return super().get_ylabel() for coord in self.coords: if ('l' in coord.axislabels.get_visible_axes() or 'c' in coord.axislabels.get_visible_axes()): return coord.get_axislabel() def get_coords_overlay(self, frame, coord_meta=None): # Here we can't use get_transform because that deals with # pixel-to-pixel transformations when passing a WCS object. if isinstance(frame, WCS): transform, coord_meta = transform_coord_meta_from_wcs(frame, self.frame_class) else: transform = self._get_transform_no_transdata(frame) if coord_meta is None: coord_meta = get_coord_meta(frame) coords = CoordinatesMap(self, transform=transform, coord_meta=coord_meta, frame_class=self.frame_class) self._all_coords.append(coords) # Common settings for overlay coords[0].set_axislabel_position('t') coords[1].set_axislabel_position('r') coords[0].set_ticklabel_position('t') coords[1].set_ticklabel_position('r') self.overlay_coords = coords return coords def get_transform(self, frame): """ Return a transform from the specified frame to display coordinates. This does not include the transData transformation Parameters ---------- frame : :class:`~astropy.wcs.WCS` or :class:`~matplotlib.transforms.Transform` or str The ``frame`` parameter can have several possible types: * :class:`~astropy.wcs.WCS` instance: assumed to be a transformation from pixel to world coordinates, where the world coordinates are the same as those in the WCS transformation used for this ``WCSAxes`` instance. This is used for example to show contours, since this involves plotting an array in pixel coordinates that are not the final data coordinate and have to be transformed to the common world coordinate system first. * :class:`~matplotlib.transforms.Transform` instance: it is assumed to be a transform to the world coordinates that are part of the WCS used to instantiate this ``WCSAxes`` instance. * ``'pixel'`` or ``'world'``: return a transformation that allows users to plot in pixel/data coordinates (essentially an identity transform) and ``world`` (the default world-to-pixel transformation used to instantiate the ``WCSAxes`` instance). * ``'fk5'`` or ``'galactic'``: return a transformation from the specified frame to the pixel/data coordinates. * :class:`~astropy.coordinates.BaseCoordinateFrame` instance. """ return self._get_transform_no_transdata(frame).inverted() + self.transData def _get_transform_no_transdata(self, frame): """ Return a transform from data to the specified frame """ if isinstance(frame, (BaseLowLevelWCS, BaseHighLevelWCS)): if isinstance(frame, BaseHighLevelWCS): frame = frame.low_level_wcs transform, coord_meta = transform_coord_meta_from_wcs(frame, self.frame_class) transform_world2pixel = transform.inverted() if self._transform_pixel2world.frame_out == transform_world2pixel.frame_in: return self._transform_pixel2world + transform_world2pixel else: return (self._transform_pixel2world + CoordinateTransform(self._transform_pixel2world.frame_out, transform_world2pixel.frame_in) + transform_world2pixel) elif isinstance(frame, str) and frame == 'pixel': return Affine2D() elif isinstance(frame, Transform): return self._transform_pixel2world + frame else: if isinstance(frame, str) and frame == 'world': return self._transform_pixel2world else: coordinate_transform = CoordinateTransform(self._transform_pixel2world.frame_out, frame) if coordinate_transform.same_frames: return self._transform_pixel2world else: return self._transform_pixel2world + coordinate_transform def get_tightbbox(self, renderer, *args, **kwargs): # FIXME: we should determine what to do with the extra arguments here. # Note that the expected signature of this method is different in # Matplotlib 3.x compared to 2.x, but we only support 3.x now. if not self.get_visible(): return bb = [b for b in self._bboxes if b and (b.width != 0 or b.height != 0)] bb.append(super().get_tightbbox(renderer, *args, **kwargs)) if bb: _bbox = Bbox.union(bb) return _bbox else: return self.get_window_extent(renderer) def grid(self, b=None, axis='both', *, which='major', **kwargs): """ Plot gridlines for both coordinates. Standard matplotlib appearance options (color, alpha, etc.) can be passed as keyword arguments. This behaves like `matplotlib.axes.Axes` except that if no arguments are specified, the grid is shown rather than toggled. Parameters ---------- b : bool Whether to show the gridlines. axis : 'both', 'x', 'y' Which axis to turn the gridlines on/off for. which : str Currently only ``'major'`` is supported. """ if not hasattr(self, 'coords'): return if which != 'major': raise NotImplementedError('Plotting the grid for the minor ticks is ' 'not supported.') if axis == 'both': self.coords.grid(draw_grid=b, **kwargs) elif axis == 'x': self.coords[0].grid(draw_grid=b, **kwargs) elif axis == 'y': self.coords[1].grid(draw_grid=b, **kwargs) else: raise ValueError('axis should be one of x/y/both') def tick_params(self, axis='both', **kwargs): """ Method to set the tick and tick label parameters in the same way as the :meth:`~matplotlib.axes.Axes.tick_params` method in Matplotlib. This is provided for convenience, but the recommended API is to use :meth:`~astropy.visualization.wcsaxes.CoordinateHelper.set_ticks`, :meth:`~astropy.visualization.wcsaxes.CoordinateHelper.set_ticklabel`, :meth:`~astropy.visualization.wcsaxes.CoordinateHelper.set_ticks_position`, :meth:`~astropy.visualization.wcsaxes.CoordinateHelper.set_ticklabel_position`, and :meth:`~astropy.visualization.wcsaxes.CoordinateHelper.grid`. Parameters ---------- axis : int or str, optional Which axis to apply the parameters to. This defaults to 'both' but this can also be set to an `int` or `str` that refers to the axis to apply it to, following the valid values that can index ``ax.coords``. Note that ``'x'`` and ``'y``' are also accepted in the case of rectangular axes. which : {'both', 'major', 'minor'}, optional Which ticks to apply the settings to. By default, setting are applied to both major and minor ticks. Note that if ``'minor'`` is specified, only the length of the ticks can be set currently. direction : {'in', 'out'}, optional Puts ticks inside the axes, or outside the axes. length : float, optional Tick length in points. width : float, optional Tick width in points. color : color, optional Tick color (accepts any valid Matplotlib color) pad : float, optional Distance in points between tick and label. labelsize : float or str, optional Tick label font size in points or as a string (e.g., 'large'). labelcolor : color, optional Tick label color (accepts any valid Matplotlib color) colors : color, optional Changes the tick color and the label color to the same value (accepts any valid Matplotlib color). bottom, top, left, right : bool, optional Where to draw the ticks. Note that this can only be given if a specific coordinate is specified via the ``axis`` argument, and it will not work correctly if the frame is not rectangular. labelbottom, labeltop, labelleft, labelright : bool, optional Where to draw the tick labels. Note that this can only be given if a specific coordinate is specified via the ``axis`` argument, and it will not work correctly if the frame is not rectangular. grid_color : color, optional The color of the grid lines (accepts any valid Matplotlib color). grid_alpha : float, optional Transparency of grid lines: 0 (transparent) to 1 (opaque). grid_linewidth : float, optional Width of grid lines in points. grid_linestyle : str, optional The style of the grid lines (accepts any valid Matplotlib line style). """ if not hasattr(self, 'coords'): # Axes haven't been fully initialized yet, so just ignore, as # Axes.__init__ calls this method return if axis == 'both': for pos in ('bottom', 'left', 'top', 'right'): if pos in kwargs: raise ValueError(f"Cannot specify {pos}= when axis='both'") if 'label' + pos in kwargs: raise ValueError(f"Cannot specify label{pos}= when axis='both'") for coord in self.coords: coord.tick_params(**kwargs) elif axis in self.coords: self.coords[axis].tick_params(**kwargs) elif axis in ('x', 'y') and self.frame_class is RectangularFrame: spine = 'b' if axis == 'x' else 'l' for coord in self.coords: if spine in coord.axislabels.get_visible_axes(): coord.tick_params(**kwargs) # In the following, we put the generated subplot class in a temporary class and # we then inherit it - if we don't do this, the generated class appears to # belong in matplotlib, not in WCSAxes, from the API's point of view. class WCSAxesSubplot(subplot_class_factory(WCSAxes)): """ A subclass class for WCSAxes """ pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/formatter_locator.py0000644000175100001710000005140000000000000024424 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst # This file defines the AngleFormatterLocator class which is a class that # provides both a method for a formatter and one for a locator, for a given # label spacing. The advantage of keeping the two connected is that we need to # make sure that the formatter can correctly represent the spacing requested and # vice versa. For example, a format of dd:mm cannot work with a tick spacing # that is not a multiple of one arcminute. import re import warnings import numpy as np from matplotlib import rcParams from astropy import units as u from astropy.units import UnitsError from astropy.coordinates import Angle DMS_RE = re.compile('^dd(:mm(:ss(.(s)+)?)?)?$') HMS_RE = re.compile('^hh(:mm(:ss(.(s)+)?)?)?$') DDEC_RE = re.compile('^d(.(d)+)?$') DMIN_RE = re.compile('^m(.(m)+)?$') DSEC_RE = re.compile('^s(.(s)+)?$') SCAL_RE = re.compile('^x(.(x)+)?$') # Units with custom representations - see the note where it is used inside # AngleFormatterLocator.formatter for more details. CUSTOM_UNITS = { u.degree: u.def_unit('custom_degree', represents=u.degree, format={'generic': '\xb0', 'latex': r'^\circ', 'unicode': '°'}), u.arcmin: u.def_unit('custom_arcmin', represents=u.arcmin, format={'generic': "'", 'latex': r'^\prime', 'unicode': '′'}), u.arcsec: u.def_unit('custom_arcsec', represents=u.arcsec, format={'generic': '"', 'latex': r'^{\prime\prime}', 'unicode': 'â€ŗ'}), u.hourangle: u.def_unit('custom_hourangle', represents=u.hourangle, format={'generic': 'h', 'latex': r'^{\mathrm{h}}', 'unicode': r'$\mathregular{^h}$'})} class BaseFormatterLocator: """ A joint formatter/locator """ def __init__(self, values=None, number=None, spacing=None, format=None, unit=None, format_unit=None): if len([x for x in (values, number, spacing) if x is None]) < 2: raise ValueError("At most one of values/number/spacing can be specified") self._unit = unit self._format_unit = format_unit or unit if values is not None: self.values = values elif number is not None: self.number = number elif spacing is not None: self.spacing = spacing else: self.number = 5 self.format = format @property def values(self): return self._values @values.setter def values(self, values): if not isinstance(values, u.Quantity) or (not values.ndim == 1): raise TypeError("values should be an astropy.units.Quantity array") if not values.unit.is_equivalent(self._unit): raise UnitsError("value should be in units compatible with " "coordinate units ({}) but found {}".format(self._unit, values.unit)) self._number = None self._spacing = None self._values = values @property def number(self): return self._number @number.setter def number(self, number): self._number = number self._spacing = None self._values = None @property def spacing(self): return self._spacing @spacing.setter def spacing(self, spacing): self._number = None self._spacing = spacing self._values = None def minor_locator(self, spacing, frequency, value_min, value_max): if self.values is not None: return [] * self._unit minor_spacing = spacing.value / frequency values = self._locate_values(value_min, value_max, minor_spacing) index = np.where((values % frequency) == 0) index = index[0][0] values = np.delete(values, np.s_[index::frequency]) return values * minor_spacing * self._unit @property def format_unit(self): return self._format_unit @format_unit.setter def format_unit(self, unit): self._format_unit = u.Unit(unit) @staticmethod def _locate_values(value_min, value_max, spacing): imin = np.ceil(value_min / spacing) imax = np.floor(value_max / spacing) values = np.arange(imin, imax + 1, dtype=int) return values class AngleFormatterLocator(BaseFormatterLocator): """ A joint formatter/locator """ def __init__(self, values=None, number=None, spacing=None, format=None, unit=None, decimal=None, format_unit=None, show_decimal_unit=True): if unit is None: unit = u.degree if format_unit is None: format_unit = unit if format_unit not in (u.degree, u.hourangle, u.hour): if decimal is False: raise UnitsError("Units should be degrees or hours when using non-decimal (sexagesimal) mode") self._decimal = decimal self._sep = None self.show_decimal_unit = show_decimal_unit super().__init__(values=values, number=number, spacing=spacing, format=format, unit=unit, format_unit=format_unit) @property def decimal(self): decimal = self._decimal if self.format_unit not in (u.degree, u.hourangle, u.hour): if self._decimal is None: decimal = True elif self._decimal is False: raise UnitsError("Units should be degrees or hours when using non-decimal (sexagesimal) mode") elif self._decimal is None: decimal = False return decimal @decimal.setter def decimal(self, value): self._decimal = value @property def spacing(self): return self._spacing @spacing.setter def spacing(self, spacing): if spacing is not None and (not isinstance(spacing, u.Quantity) or spacing.unit.physical_type != 'angle'): raise TypeError("spacing should be an astropy.units.Quantity " "instance with units of angle") self._number = None self._spacing = spacing self._values = None @property def sep(self): return self._sep @sep.setter def sep(self, separator): self._sep = separator @property def format(self): return self._format @format.setter def format(self, value): self._format = value if value is None: return if DMS_RE.match(value) is not None: self._decimal = False self._format_unit = u.degree if '.' in value: self._precision = len(value) - value.index('.') - 1 self._fields = 3 else: self._precision = 0 self._fields = value.count(':') + 1 elif HMS_RE.match(value) is not None: self._decimal = False self._format_unit = u.hourangle if '.' in value: self._precision = len(value) - value.index('.') - 1 self._fields = 3 else: self._precision = 0 self._fields = value.count(':') + 1 elif DDEC_RE.match(value) is not None: self._decimal = True self._format_unit = u.degree self._fields = 1 if '.' in value: self._precision = len(value) - value.index('.') - 1 else: self._precision = 0 elif DMIN_RE.match(value) is not None: self._decimal = True self._format_unit = u.arcmin self._fields = 1 if '.' in value: self._precision = len(value) - value.index('.') - 1 else: self._precision = 0 elif DSEC_RE.match(value) is not None: self._decimal = True self._format_unit = u.arcsec self._fields = 1 if '.' in value: self._precision = len(value) - value.index('.') - 1 else: self._precision = 0 else: raise ValueError(f"Invalid format: {value}") if self.spacing is not None and self.spacing < self.base_spacing: warnings.warn("Spacing is too small - resetting spacing to match format") self.spacing = self.base_spacing if self.spacing is not None: ratio = (self.spacing / self.base_spacing).decompose().value remainder = ratio - np.round(ratio) if abs(remainder) > 1.e-10: warnings.warn("Spacing is not a multiple of base spacing - resetting spacing to match format") self.spacing = self.base_spacing * max(1, round(ratio)) @property def base_spacing(self): if self.decimal: spacing = self._format_unit / (10. ** self._precision) else: if self._fields == 1: spacing = 1. * u.degree elif self._fields == 2: spacing = 1. * u.arcmin elif self._fields == 3: if self._precision == 0: spacing = 1. * u.arcsec else: spacing = u.arcsec / (10. ** self._precision) if self._format_unit is u.hourangle: spacing *= 15 return spacing def locator(self, value_min, value_max): if self.values is not None: # values were manually specified return self.values, 1.1 * u.arcsec else: # In the special case where value_min is the same as value_max, we # don't locate any ticks. This can occur for example when taking a # slice for a cube (along the dimension sliced). We return a # non-zero spacing in case the caller needs to format a single # coordinate, e.g. for mousover. if value_min == value_max: return [] * self._unit, 1 * u.arcsec if self.spacing is not None: # spacing was manually specified spacing_value = self.spacing.to_value(self._unit) elif self.number is not None: # number of ticks was specified, work out optimal spacing # first compute the exact spacing dv = abs(float(value_max - value_min)) / self.number * self._unit if self.format is not None and dv < self.base_spacing: # if the spacing is less than the minimum spacing allowed by the format, simply # use the format precision instead. spacing_value = self.base_spacing.to_value(self._unit) else: # otherwise we clip to the nearest 'sensible' spacing if self.decimal: from .utils import select_step_scalar spacing_value = select_step_scalar(dv.to_value(self._format_unit)) * self._format_unit.to(self._unit) else: if self._format_unit is u.degree: from .utils import select_step_degree spacing_value = select_step_degree(dv).to_value(self._unit) else: from .utils import select_step_hour spacing_value = select_step_hour(dv).to_value(self._unit) # We now find the interval values as multiples of the spacing and # generate the tick positions from this. values = self._locate_values(value_min, value_max, spacing_value) return values * spacing_value * self._unit, spacing_value * self._unit def formatter(self, values, spacing, format='auto'): if not isinstance(values, u.Quantity) and values is not None: raise TypeError("values should be a Quantities array") if len(values) > 0: decimal = self.decimal unit = self._format_unit if unit is u.hour: unit = u.hourangle if self.format is None: if decimal: # Here we assume the spacing can be arbitrary, so for example # 1.000223 degrees, in which case we don't want to have a # format that rounds to degrees. So we find the number of # decimal places we get from representing the spacing as a # string in the desired units. The easiest way to find # the smallest number of decimal places required is to # format the number as a decimal float and strip any zeros # from the end. We do this rather than just trusting e.g. # str() because str(15.) == 15.0. We format using 10 decimal # places by default before stripping the zeros since this # corresponds to a resolution of less than a microarcecond, # which should be sufficient. spacing = spacing.to_value(unit) fields = 0 precision = len(f"{spacing:.10f}".replace('0', ' ').strip().split('.', 1)[1]) else: spacing = spacing.to_value(unit / 3600) if spacing >= 3600: fields = 1 precision = 0 elif spacing >= 60: fields = 2 precision = 0 elif spacing >= 1: fields = 3 precision = 0 else: fields = 3 precision = -int(np.floor(np.log10(spacing))) else: fields = self._fields precision = self._precision is_latex = format == 'latex' or (format == 'auto' and rcParams['text.usetex']) if decimal: # At the moment, the Angle class doesn't have a consistent way # to always convert angles to strings in decimal form with # symbols for units (instead of e.g 3arcsec). So as a workaround # we take advantage of the fact that Angle.to_string converts # the unit to a string manually when decimal=False and the unit # is not strictly u.degree or u.hourangle if self.show_decimal_unit: decimal = False sep = 'fromunit' if is_latex: fmt = 'latex' else: if unit is u.hourangle: fmt = 'unicode' else: fmt = None unit = CUSTOM_UNITS.get(unit, unit) else: sep = None fmt = None elif self.sep is not None: sep = self.sep fmt = None else: sep = 'fromunit' if unit == u.degree: if is_latex: fmt = 'latex' else: sep = ('\xb0', "'", '"') fmt = None else: if format == 'ascii': fmt = None elif is_latex: fmt = 'latex' else: # Here we still use LaTeX but this is for Matplotlib's # LaTeX engine - we can't use fmt='latex' as this # doesn't produce LaTeX output that respects the fonts. sep = (r'$\mathregular{^h}$', r'$\mathregular{^m}$', r'$\mathregular{^s}$') fmt = None angles = Angle(values) string = angles.to_string(unit=unit, precision=precision, decimal=decimal, fields=fields, sep=sep, format=fmt).tolist() return string else: return [] class ScalarFormatterLocator(BaseFormatterLocator): """ A joint formatter/locator """ def __init__(self, values=None, number=None, spacing=None, format=None, unit=None, format_unit=None): if unit is not None: unit = unit format_unit = format_unit or unit elif spacing is not None: unit = spacing.unit format_unit = format_unit or spacing.unit elif values is not None: unit = values.unit format_unit = format_unit or values.unit super().__init__(values=values, number=number, spacing=spacing, format=format, unit=unit, format_unit=format_unit) @property def spacing(self): return self._spacing @spacing.setter def spacing(self, spacing): if spacing is not None and not isinstance(spacing, u.Quantity): raise TypeError("spacing should be an astropy.units.Quantity instance") self._number = None self._spacing = spacing self._values = None @property def format(self): return self._format @format.setter def format(self, value): self._format = value if value is None: return if SCAL_RE.match(value) is not None: if '.' in value: self._precision = len(value) - value.index('.') - 1 else: self._precision = 0 if self.spacing is not None and self.spacing < self.base_spacing: warnings.warn("Spacing is too small - resetting spacing to match format") self.spacing = self.base_spacing if self.spacing is not None: ratio = (self.spacing / self.base_spacing).decompose().value remainder = ratio - np.round(ratio) if abs(remainder) > 1.e-10: warnings.warn("Spacing is not a multiple of base spacing - resetting spacing to match format") self.spacing = self.base_spacing * max(1, round(ratio)) elif not value.startswith('%'): raise ValueError(f"Invalid format: {value}") @property def base_spacing(self): return self._format_unit / (10. ** self._precision) def locator(self, value_min, value_max): if self.values is not None: # values were manually specified return self.values, 1.1 * self._unit else: # In the special case where value_min is the same as value_max, we # don't locate any ticks. This can occur for example when taking a # slice for a cube (along the dimension sliced). if value_min == value_max: return [] * self._unit, 0 * self._unit if self.spacing is not None: # spacing was manually specified spacing = self.spacing.to_value(self._unit) elif self.number is not None: # number of ticks was specified, work out optimal spacing # first compute the exact spacing dv = abs(float(value_max - value_min)) / self.number * self._unit if self.format is not None and (not self.format.startswith('%')) and dv < self.base_spacing: # if the spacing is less than the minimum spacing allowed by the format, simply # use the format precision instead. spacing = self.base_spacing.to_value(self._unit) else: from .utils import select_step_scalar spacing = select_step_scalar(dv.to_value(self._format_unit)) * self._format_unit.to(self._unit) # We now find the interval values as multiples of the spacing and # generate the tick positions from this values = self._locate_values(value_min, value_max, spacing) return values * spacing * self._unit, spacing * self._unit def formatter(self, values, spacing, format='auto'): if len(values) > 0: if self.format is None: if spacing.value < 1.: precision = -int(np.floor(np.log10(spacing.value))) else: precision = 0 elif self.format.startswith('%'): return [(self.format % x.value) for x in values] else: precision = self._precision return [("{0:." + str(precision) + "f}").format(x.to_value(self._format_unit)) for x in values] else: return [] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/frame.py0000644000175100001710000002463100000000000021776 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import abc from collections import OrderedDict import numpy as np from matplotlib import rcParams from matplotlib.lines import Line2D, Path from matplotlib.patches import PathPatch __all__ = ['RectangularFrame1D', 'Spine', 'BaseFrame', 'RectangularFrame', 'EllipticalFrame'] class Spine: """ A single side of an axes. This does not need to be a straight line, but represents a 'side' when determining which part of the frame to put labels and ticks on. """ def __init__(self, parent_axes, transform): self.parent_axes = parent_axes self.transform = transform self.data = None self.pixel = None self.world = None @property def data(self): return self._data @data.setter def data(self, value): if value is None: self._data = None self._pixel = None self._world = None else: self._data = value self._pixel = self.parent_axes.transData.transform(self._data) with np.errstate(invalid='ignore'): self._world = self.transform.transform(self._data) self._update_normal() @property def pixel(self): return self._pixel @pixel.setter def pixel(self, value): if value is None: self._data = None self._pixel = None self._world = None else: self._data = self.parent_axes.transData.inverted().transform(self._data) self._pixel = value self._world = self.transform.transform(self._data) self._update_normal() @property def world(self): return self._world @world.setter def world(self, value): if value is None: self._data = None self._pixel = None self._world = None else: self._data = self.transform.transform(value) self._pixel = self.parent_axes.transData.transform(self._data) self._world = value self._update_normal() def _update_normal(self): # Find angle normal to border and inwards, in display coordinate dx = self.pixel[1:, 0] - self.pixel[:-1, 0] dy = self.pixel[1:, 1] - self.pixel[:-1, 1] self.normal_angle = np.degrees(np.arctan2(dx, -dy)) def _halfway_x_y_angle(self): """ Return the x, y, normal_angle values halfway along the spine """ x_disp, y_disp = self.pixel[:, 0], self.pixel[:, 1] # Get distance along the path d = np.hstack([0., np.cumsum(np.sqrt(np.diff(x_disp) ** 2 + np.diff(y_disp) ** 2))]) xcen = np.interp(d[-1] / 2., d, x_disp) ycen = np.interp(d[-1] / 2., d, y_disp) # Find segment along which the mid-point lies imin = np.searchsorted(d, d[-1] / 2.) - 1 # Find normal of the axis label facing outwards on that segment normal_angle = self.normal_angle[imin] + 180. return xcen, ycen, normal_angle class SpineXAligned(Spine): """ A single side of an axes, aligned with the X data axis. This does not need to be a straight line, but represents a 'side' when determining which part of the frame to put labels and ticks on. """ @property def data(self): return self._data @data.setter def data(self, value): if value is None: self._data = None self._pixel = None self._world = None else: self._data = value self._pixel = self.parent_axes.transData.transform(self._data) with np.errstate(invalid='ignore'): self._world = self.transform.transform(self._data[:,0:1]) self._update_normal() @property def pixel(self): return self._pixel @pixel.setter def pixel(self, value): if value is None: self._data = None self._pixel = None self._world = None else: self._data = self.parent_axes.transData.inverted().transform(self._data) self._pixel = value self._world = self.transform.transform(self._data[:,0:1]) self._update_normal() class BaseFrame(OrderedDict, metaclass=abc.ABCMeta): """ Base class for frames, which are collections of :class:`~astropy.visualization.wcsaxes.frame.Spine` instances. """ spine_class = Spine def __init__(self, parent_axes, transform, path=None): super().__init__() self.parent_axes = parent_axes self._transform = transform self._linewidth = rcParams['axes.linewidth'] self._color = rcParams['axes.edgecolor'] self._path = path for axis in self.spine_names: self[axis] = self.spine_class(parent_axes, transform) @property def origin(self): ymin, ymax = self.parent_axes.get_ylim() return 'lower' if ymin < ymax else 'upper' @property def transform(self): return self._transform @transform.setter def transform(self, value): self._transform = value for axis in self: self[axis].transform = value def _update_patch_path(self): self.update_spines() x, y = [], [] for axis in self: x.append(self[axis].data[:, 0]) y.append(self[axis].data[:, 1]) vertices = np.vstack([np.hstack(x), np.hstack(y)]).transpose() if self._path is None: self._path = Path(vertices) else: self._path.vertices = vertices @property def patch(self): self._update_patch_path() return PathPatch(self._path, transform=self.parent_axes.transData, facecolor=rcParams['axes.facecolor'], edgecolor='white') def draw(self, renderer): for axis in self: x, y = self[axis].pixel[:, 0], self[axis].pixel[:, 1] line = Line2D(x, y, linewidth=self._linewidth, color=self._color, zorder=1000) line.draw(renderer) def sample(self, n_samples): self.update_spines() spines = OrderedDict() for axis in self: data = self[axis].data p = np.linspace(0., 1., data.shape[0]) p_new = np.linspace(0., 1., n_samples) spines[axis] = self.spine_class(self.parent_axes, self.transform) spines[axis].data = np.array([np.interp(p_new, p, d) for d in data.T]).transpose() return spines def set_color(self, color): """ Sets the color of the frame. Parameters ---------- color : str The color of the frame. """ self._color = color def get_color(self): return self._color def set_linewidth(self, linewidth): """ Sets the linewidth of the frame. Parameters ---------- linewidth : float The linewidth of the frame in points. """ self._linewidth = linewidth def get_linewidth(self): return self._linewidth @abc.abstractmethod def update_spines(self): raise NotImplementedError("") class RectangularFrame1D(BaseFrame): """ A classic rectangular frame. """ spine_names = 'bt' spine_class = SpineXAligned def update_spines(self): xmin, xmax = self.parent_axes.get_xlim() ymin, ymax = self.parent_axes.get_ylim() self['b'].data = np.array(([xmin, ymin], [xmax, ymin])) self['t'].data = np.array(([xmax, ymax], [xmin, ymax])) def _update_patch_path(self): self.update_spines() xmin, xmax = self.parent_axes.get_xlim() ymin, ymax = self.parent_axes.get_ylim() x = [xmin, xmax, xmax, xmin, xmin] y = [ymin, ymin, ymax, ymax, ymin] vertices = np.vstack([np.hstack(x), np.hstack(y)]).transpose() if self._path is None: self._path = Path(vertices) else: self._path.vertices = vertices def draw(self, renderer): xmin, xmax = self.parent_axes.get_xlim() ymin, ymax = self.parent_axes.get_ylim() x = [xmin, xmax, xmax, xmin, xmin] y = [ymin, ymin, ymax, ymax, ymin] line = Line2D(x, y, linewidth=self._linewidth, color=self._color, zorder=1000, transform=self.parent_axes.transData) line.draw(renderer) class RectangularFrame(BaseFrame): """ A classic rectangular frame. """ spine_names = 'brtl' def update_spines(self): xmin, xmax = self.parent_axes.get_xlim() ymin, ymax = self.parent_axes.get_ylim() self['b'].data = np.array(([xmin, ymin], [xmax, ymin])) self['r'].data = np.array(([xmax, ymin], [xmax, ymax])) self['t'].data = np.array(([xmax, ymax], [xmin, ymax])) self['l'].data = np.array(([xmin, ymax], [xmin, ymin])) class EllipticalFrame(BaseFrame): """ An elliptical frame. """ spine_names = 'chv' def update_spines(self): xmin, xmax = self.parent_axes.get_xlim() ymin, ymax = self.parent_axes.get_ylim() xmid = 0.5 * (xmax + xmin) ymid = 0.5 * (ymax + ymin) dx = xmid - xmin dy = ymid - ymin theta = np.linspace(0., 2 * np.pi, 1000) self['c'].data = np.array([xmid + dx * np.cos(theta), ymid + dy * np.sin(theta)]).transpose() self['h'].data = np.array([np.linspace(xmin, xmax, 1000), np.repeat(ymid, 1000)]).transpose() self['v'].data = np.array([np.repeat(xmid, 1000), np.linspace(ymin, ymax, 1000)]).transpose() def _update_patch_path(self): """Override path patch to include only the outer ellipse, not the major and minor axes in the middle.""" self.update_spines() vertices = self['c'].data if self._path is None: self._path = Path(vertices) else: self._path.vertices = vertices def draw(self, renderer): """Override to draw only the outer ellipse, not the major and minor axes in the middle. FIXME: we may want to add a general method to give the user control over which spines are drawn.""" axis = 'c' x, y = self[axis].pixel[:, 0], self[axis].pixel[:, 1] line = Line2D(x, y, linewidth=self._linewidth, color=self._color, zorder=1000) line.draw(renderer) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/grid_paths.py0000644000175100001710000000774200000000000023034 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import numpy as np from matplotlib.lines import Path from astropy.coordinates.angle_utilities import angular_separation # Tolerance for WCS round-tripping, relative to the scale size ROUND_TRIP_RTOL = 1. # Tolerance for discontinuities relative to the median DISCONT_FACTOR = 10. def get_lon_lat_path(lon_lat, pixel, lon_lat_check): """ Draw a curve, taking into account discontinuities. Parameters ---------- lon_lat : ndarray The longitude and latitude values along the curve, given as a (n,2) array. pixel : ndarray The pixel coordinates corresponding to ``lon_lat`` lon_lat_check : ndarray The world coordinates derived from converting from ``pixel``, which is used to ensure round-tripping. """ # In some spherical projections, some parts of the curve are 'behind' or # 'in front of' the plane of the image, so we find those by reversing the # transformation and finding points where the result is not consistent. sep = angular_separation(np.radians(lon_lat[:, 0]), np.radians(lon_lat[:, 1]), np.radians(lon_lat_check[:, 0]), np.radians(lon_lat_check[:, 1])) # Define the relevant scale size using the separation between the first two points scale_size = angular_separation(*np.radians(lon_lat[0, :]), *np.radians(lon_lat[1, :])) with np.errstate(invalid='ignore'): sep[sep > np.pi] -= 2. * np.pi mask = np.abs(sep > ROUND_TRIP_RTOL * scale_size) # Mask values with invalid pixel positions mask = mask | np.isnan(pixel[:, 0]) | np.isnan(pixel[:, 1]) # We can now start to set up the codes for the Path. codes = np.zeros(lon_lat.shape[0], dtype=np.uint8) codes[:] = Path.LINETO codes[0] = Path.MOVETO codes[mask] = Path.MOVETO # Also need to move to point *after* a hidden value codes[1:][mask[:-1]] = Path.MOVETO # We now go through and search for discontinuities in the curve that would # be due to the curve going outside the field of view, invalid WCS values, # or due to discontinuities in the projection. # We start off by pre-computing the step in pixel coordinates from one # point to the next. The idea is to look for large jumps that might indicate # discontinuities. step = np.sqrt((pixel[1:, 0] - pixel[:-1, 0]) ** 2 + (pixel[1:, 1] - pixel[:-1, 1]) ** 2) # We search for discontinuities by looking for places where the step # is larger by more than a given factor compared to the median # discontinuous = step > DISCONT_FACTOR * np.median(step) discontinuous = step[1:] > DISCONT_FACTOR * step[:-1] # Skip over discontinuities codes[2:][discontinuous] = Path.MOVETO # The above missed the first step, so check that too if step[0] > DISCONT_FACTOR * step[1]: codes[1] = Path.MOVETO # Create the path path = Path(pixel, codes=codes) return path def get_gridline_path(world, pixel): """ Draw a grid line Parameters ---------- world : ndarray The longitude and latitude values along the curve, given as a (n,2) array. pixel : ndarray The pixel coordinates corresponding to ``lon_lat`` """ # Mask values with invalid pixel positions mask = np.isnan(pixel[:, 0]) | np.isnan(pixel[:, 1]) # We can now start to set up the codes for the Path. codes = np.zeros(world.shape[0], dtype=np.uint8) codes[:] = Path.LINETO codes[0] = Path.MOVETO codes[mask] = Path.MOVETO # Also need to move to point *after* a hidden value codes[1:][mask[:-1]] = Path.MOVETO # We now go through and search for discontinuities in the curve that would # be due to the curve going outside the field of view, invalid WCS values, # or due to discontinuities in the projection. # Create the path path = Path(pixel, codes=codes) return path ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/patches.py0000644000175100001710000001676300000000000022342 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import numpy as np import warnings from matplotlib.patches import Polygon from astropy import units as u from astropy.coordinates import SkyCoord from astropy.coordinates.representation import UnitSphericalRepresentation, SphericalRepresentation from astropy.coordinates.matrix_utilities import rotation_matrix, matrix_product from astropy.utils.exceptions import AstropyUserWarning __all__ = ['Quadrangle', 'SphericalCircle'] # Monkey-patch the docs to fix CapStyle and JoinStyle subs. # TODO! delete when upstream fix matplotlib/matplotlib#19839 Polygon.__init__.__doc__ = Polygon.__init__.__doc__.replace( "`.CapStyle`", "``matplotlib._enums.CapStyle``") Polygon.__init__.__doc__ = Polygon.__init__.__doc__.replace( "`.JoinStyle`", "``matplotlib._enums.JoinStyle``") Polygon.set_capstyle.__doc__ = Polygon.set_capstyle.__doc__.replace( "`.CapStyle`", "``matplotlib._enums.CapStyle``") Polygon.set_joinstyle.__doc__ = Polygon.set_joinstyle.__doc__.replace( "`.JoinStyle`", "``matplotlib._enums.JoinStyle``") def _rotate_polygon(lon, lat, lon0, lat0): """ Given a polygon with vertices defined by (lon, lat), rotate the polygon such that the North pole of the spherical coordinates is now at (lon0, lat0). Therefore, to end up with a polygon centered on (lon0, lat0), the polygon should initially be drawn around the North pole. """ # Create a representation object polygon = UnitSphericalRepresentation(lon=lon, lat=lat) # Determine rotation matrix to make it so that the circle is centered # on the correct longitude/latitude. m1 = rotation_matrix(-(0.5 * np.pi * u.radian - lat0), axis='y') m2 = rotation_matrix(-lon0, axis='z') transform_matrix = matrix_product(m2, m1) # Apply 3D rotation polygon = polygon.to_cartesian() polygon = polygon.transform(transform_matrix) polygon = UnitSphericalRepresentation.from_cartesian(polygon) return polygon.lon, polygon.lat class SphericalCircle(Polygon): """ Create a patch representing a spherical circle - that is, a circle that is formed of all the points that are within a certain angle of the central coordinates on a sphere. Here we assume that latitude goes from -90 to +90 This class is needed in cases where the user wants to add a circular patch to a celestial image, since otherwise the circle will be distorted, because a fixed interval in longitude corresponds to a different angle on the sky depending on the latitude. Parameters ---------- center : tuple or `~astropy.units.Quantity` ['angle'] This can be either a tuple of two `~astropy.units.Quantity` objects, or a single `~astropy.units.Quantity` array with two elements or a `~astropy.coordinates.SkyCoord` object. radius : `~astropy.units.Quantity` ['angle'] The radius of the circle resolution : int, optional The number of points that make up the circle - increase this to get a smoother circle. vertex_unit : `~astropy.units.Unit` The units in which the resulting polygon should be defined - this should match the unit that the transformation (e.g. the WCS transformation) expects as input. Notes ----- Additional keyword arguments are passed to `~matplotlib.patches.Polygon` """ def __init__(self, center, radius, resolution=100, vertex_unit=u.degree, **kwargs): # Extract longitude/latitude, either from a SkyCoord object, or # from a tuple of two quantities or a single 2-element Quantity. # The SkyCoord is converted to SphericalRepresentation, if not already. if isinstance(center, SkyCoord): rep_type = center.representation_type if not issubclass(rep_type, (SphericalRepresentation, UnitSphericalRepresentation)): warnings.warn(f'Received `center` of representation type {rep_type} ' 'will be converted to SphericalRepresentation ', AstropyUserWarning) longitude, latitude = center.spherical.lon, center.spherical.lat else: longitude, latitude = center # Start off by generating the circle around the North pole lon = np.linspace(0., 2 * np.pi, resolution + 1)[:-1] * u.radian lat = np.repeat(0.5 * np.pi - radius.to_value(u.radian), resolution) * u.radian lon, lat = _rotate_polygon(lon, lat, longitude, latitude) # Extract new longitude/latitude in the requested units lon = lon.to_value(vertex_unit) lat = lat.to_value(vertex_unit) # Create polygon vertices vertices = np.array([lon, lat]).transpose() super().__init__(vertices, **kwargs) class Quadrangle(Polygon): """ Create a patch representing a latitude-longitude quadrangle. The edges of the quadrangle lie on two lines of constant longitude and two lines of constant latitude (or the equivalent component names in the coordinate frame of interest, such as right ascension and declination). Note that lines of constant latitude are not great circles. Unlike `matplotlib.patches.Rectangle`, the edges of this patch will render as curved lines if appropriate for the WCS transformation. Parameters ---------- anchor : tuple or `~astropy.units.Quantity` ['angle'] This can be either a tuple of two `~astropy.units.Quantity` objects, or a single `~astropy.units.Quantity` array with two elements. width : `~astropy.units.Quantity` ['angle'] The width of the quadrangle in longitude (or, e.g., right ascension) height : `~astropy.units.Quantity` ['angle'] The height of the quadrangle in latitude (or, e.g., declination) resolution : int, optional The number of points that make up each side of the quadrangle - increase this to get a smoother quadrangle. vertex_unit : `~astropy.units.Unit` ['angle'] The units in which the resulting polygon should be defined - this should match the unit that the transformation (e.g. the WCS transformation) expects as input. Notes ----- Additional keyword arguments are passed to `~matplotlib.patches.Polygon` """ def __init__(self, anchor, width, height, resolution=100, vertex_unit=u.degree, **kwargs): # Extract longitude/latitude, either from a tuple of two quantities, or # a single 2-element Quantity. longitude, latitude = u.Quantity(anchor).to_value(vertex_unit) # Convert the quadrangle dimensions to the appropriate units width = width.to_value(vertex_unit) height = height.to_value(vertex_unit) # Create progressions in longitude and latitude lon_seq = longitude + np.linspace(0, width, resolution + 1) lat_seq = latitude + np.linspace(0, height, resolution + 1) # Trace the path of the quadrangle lon = np.concatenate([lon_seq[:-1], np.repeat(lon_seq[-1], resolution), np.flip(lon_seq[1:]), np.repeat(lon_seq[0], resolution)]) lat = np.concatenate([np.repeat(lat_seq[0], resolution), lat_seq[:-1], np.repeat(lat_seq[-1], resolution), np.flip(lat_seq[1:])]) # Create polygon vertices vertices = np.array([lon, lat]).transpose() super().__init__(vertices, **kwargs) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2192562 astropy-5.0.2/astropy/visualization/wcsaxes/tests/0000755000175100001710000000000000000000000021466 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/tests/__init__.py0000644000175100001710000000045400000000000023602 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst # This sub-package makes use of image testing with the pytest-mpl package: # # https://pypi.org/project/pytest-mpl # # For more information on writing image tests, see the 'Image tests with # pytest-mpl' section of the developer docs. ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2192562 astropy-5.0.2/astropy/visualization/wcsaxes/tests/data/0000755000175100001710000000000000000000000022377 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/tests/data/2MASS_k_header0000644000175100001710000000215500000000000024774 0ustar00vstsdockerWCSAXES = 2 / Number of coordinate axes CRPIX1 = 361.0 / Pixel coordinate of reference point CRPIX2 = 360.5 / Pixel coordinate of reference point CDELT1 = -0.001388889 / [deg] Coordinate increment at reference point CDELT2 = 0.001388889 / [deg] Coordinate increment at reference point CUNIT1 = 'deg' / Units of coordinate increment and value CUNIT2 = 'deg' / Units of coordinate increment and value CTYPE1 = 'RA---TAN' / Right ascension, gnomonic projection CTYPE2 = 'DEC--TAN' / Declination, gnomonic projection CRVAL1 = 266.4 / [deg] Coordinate value at reference point CRVAL2 = -28.93333 / [deg] Coordinate value at reference point LONPOLE = 180.0 / [deg] Native longitude of celestial pole LATPOLE = -28.93333 / [deg] Native latitude of celestial pole EQUINOX = 2000.0 / [yr] Equinox of equatorial coordinates ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/tests/data/cube_header0000644000175100001710000000312300000000000024547 0ustar00vstsdockerWCSAXES = 3 / Number of coordinate axes CRPIX1 = -799.0 / Pixel coordinate of reference point CRPIX2 = -4741.913 / Pixel coordinate of reference point CRPIX3 = -187.0 / Pixel coordinate of reference point CDELT1 = -0.006388889 / [deg] Coordinate increment at reference point CDELT2 = 0.006388889 / [deg] Coordinate increment at reference point CDELT3 = 66.42361 / [m s-1] Coordinate increment at reference point CUNIT1 = 'deg' / Units of coordinate increment and value CUNIT2 = 'deg' / Units of coordinate increment and value CUNIT3 = 'm s-1' / Units of coordinate increment and value CTYPE1 = 'RA---SFL' / Right ascension, Sanson-Flamsteed projection CTYPE2 = 'DEC--SFL' / Declination, Sanson-Flamsteed projection CTYPE3 = 'VOPT' / Optical velocity (linear) CRVAL1 = 57.6599999999 / [deg] Coordinate value at reference point CRVAL2 = 0.0 / [deg] Coordinate value at reference point CRVAL3 = -9959.44378305 / [m s-1] Coordinate value at reference point LONPOLE = 0.0 / [deg] Native longitude of celestial pole LATPOLE = 90.0 / [deg] Native latitude of celestial pole EQUINOX = 0.0 / [yr] Equinox of equatorial coordinates SPECSYS = 'LSRK' / Reference frame of spectral coordinates ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/tests/data/msx_header0000644000175100001710000000203400000000000024440 0ustar00vstsdockerWCSAXES = 2 / Number of coordinate axes CRPIX1 = 75.907 / Pixel coordinate of reference point CRPIX2 = 74.8485 / Pixel coordinate of reference point CDELT1 = -0.006666666828 / [deg] Coordinate increment at reference point CDELT2 = 0.006666666828 / [deg] Coordinate increment at reference point CUNIT1 = 'deg' / Units of coordinate increment and value CUNIT2 = 'deg' / Units of coordinate increment and value CTYPE1 = 'GLON-CAR' / galactic longitude, plate caree projection CTYPE2 = 'GLAT-CAR' / galactic latitude, plate caree projection CRVAL1 = 0.0 / [deg] Coordinate value at reference point CRVAL2 = 0.0 / [deg] Coordinate value at reference point LONPOLE = 0.0 / [deg] Native longitude of celestial pole LATPOLE = 90.0 / [deg] Native latitude of celestial pole ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/tests/data/rosat_header0000644000175100001710000000203400000000000024761 0ustar00vstsdockerWCSAXES = 2 / Number of coordinate axes CRPIX1 = 240.5 / Pixel coordinate of reference point CRPIX2 = 120.5 / Pixel coordinate of reference point CDELT1 = -0.675 / [deg] Coordinate increment at reference point CDELT2 = 0.675 / [deg] Coordinate increment at reference point CUNIT1 = 'deg' / Units of coordinate increment and value CUNIT2 = 'deg' / Units of coordinate increment and value CTYPE1 = 'GLON-AIT' / galactic longitude, Hammer-Aitoff projection CTYPE2 = 'GLAT-AIT' / galactic latitude, Hammer-Aitoff projection CRVAL1 = 0.0 / [deg] Coordinate value at reference point CRVAL2 = 0.0 / [deg] Coordinate value at reference point LONPOLE = 0.0 / [deg] Native longitude of celestial pole LATPOLE = 90.0 / [deg] Native latitude of celestial pole ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/tests/data/slice_header0000644000175100001710000000214300000000000024731 0ustar00vstsdockerWCSAXES = 2 / Number of coordinate axes CRPIX1 = 1.0 / Pixel coordinate of reference point CRPIX2 = 99.0 / Pixel coordinate of reference point CDELT1 = 0.00416666666667 / [deg] Coordinate increment at reference point CDELT2 = 1000.0 / [m s-1] Coordinate increment at reference point CUNIT1 = 'deg' / Units of coordinate increment and value CUNIT2 = 'm s-1' / Units of coordinate increment and value CTYPE1 = 'OFFSET' / Coordinate type code CTYPE2 = 'VRAD' / Radio velocity (linear) CRVAL1 = 0.0 / [deg] Coordinate value at reference point CRVAL2 = 50000.0 / [m s-1] Coordinate value at reference point LONPOLE = 0.0 / [deg] Native longitude of celestial pole LATPOLE = 90.0 / [deg] Native latitude of celestial pole RESTFRQ = 4829659400.0 / [Hz] Line rest frequency EQUINOX = 2000.0 / [yr] Equinox of equatorial coordinates SPECSYS = 'LSRK' / Reference frame of spectral coordinates ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/tests/test_coordinate_helpers.py0000644000175100001710000000634700000000000026762 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import os from unittest.mock import patch import pytest import matplotlib.pyplot as plt from astropy.wcs import WCS from astropy.io import fits from astropy.utils.data import get_pkg_data_filename from astropy.visualization.wcsaxes.core import WCSAxes from astropy import units as u MSX_HEADER = fits.Header.fromtextfile(get_pkg_data_filename('data/msx_header')) def teardown_function(function): plt.close('all') def test_getaxislabel(ignore_matplotlibrc): fig = plt.figure() ax = WCSAxes(fig, [0.1, 0.1, 0.8, 0.8], aspect='equal') ax.coords[0].set_axislabel("X") ax.coords[1].set_axislabel("Y") assert ax.coords[0].get_axislabel() == "X" assert ax.coords[1].get_axislabel() == "Y" @pytest.fixture def ax(): fig = plt.figure() ax = WCSAxes(fig, [0.1, 0.1, 0.8, 0.8], aspect='equal') fig.add_axes(ax) return ax def assert_label_draw(ax, x_label, y_label): ax.coords[0].set_axislabel("Label 1") ax.coords[1].set_axislabel("Label 2") with patch.object(ax.coords[0].axislabels, 'set_position') as pos1: with patch.object(ax.coords[1].axislabels, 'set_position') as pos2: ax.figure.canvas.draw() assert pos1.call_count == x_label assert pos2.call_count == y_label def test_label_visibility_rules_default(ignore_matplotlibrc, ax): assert_label_draw(ax, True, True) def test_label_visibility_rules_label(ignore_matplotlibrc, ax): ax.coords[0].set_ticklabel_visible(False) ax.coords[1].set_ticks(values=[-9999]*u.one) assert_label_draw(ax, False, False) def test_label_visibility_rules_ticks(ignore_matplotlibrc, ax): ax.coords[0].set_axislabel_visibility_rule('ticks') ax.coords[1].set_axislabel_visibility_rule('ticks') ax.coords[0].set_ticklabel_visible(False) ax.coords[1].set_ticks(values=[-9999]*u.one) assert_label_draw(ax, True, False) def test_label_visibility_rules_always(ignore_matplotlibrc, ax): ax.coords[0].set_axislabel_visibility_rule('always') ax.coords[1].set_axislabel_visibility_rule('always') ax.coords[0].set_ticklabel_visible(False) ax.coords[1].set_ticks(values=[-9999]*u.one) assert_label_draw(ax, True, True) def test_format_unit(tmpdir): fig = plt.figure() ax = WCSAxes(fig, [0.1, 0.1, 0.8, 0.8], wcs=WCS(MSX_HEADER)) fig.add_axes(ax) # Force a draw which is required for format_coord to work ax.figure.canvas.draw() ori_fu = ax.coords[1].get_format_unit() assert ori_fu == "deg" ax.coords[1].set_format_unit("arcsec") fu = ax.coords[1].get_format_unit() assert fu == "arcsec" def test_set_separator(tmpdir): fig = plt.figure() ax = WCSAxes(fig, [0.1, 0.1, 0.8, 0.8], wcs=WCS(MSX_HEADER)) fig.add_axes(ax) # Force a draw which is required for format_coord to work ax.figure.canvas.draw() ax.coords[1].set_format_unit('deg') assert ax.coords[1].format_coord(4) == '4\xb000\'00\"' ax.coords[1].set_separator((':', ':', '')) assert ax.coords[1].format_coord(4) == '4:00:00' ax.coords[1].set_separator('abc') assert ax.coords[1].format_coord(4) == '4a00b00c' ax.coords[1].set_separator(None) assert ax.coords[1].format_coord(4) == '4\xb000\'00\"' ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/tests/test_display_world_coordinates.py0000644000175100001710000001455300000000000030355 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import matplotlib.pyplot as plt import pytest from matplotlib.backend_bases import KeyEvent import numpy as np import astropy.units as u from astropy.coordinates import FK5, SkyCoord from astropy.io import fits from astropy.time import Time from astropy.utils.data import get_pkg_data_filename from astropy.visualization.wcsaxes.core import WCSAxes from astropy.wcs import WCS from astropy.coordinates import galactocentric_frame_defaults from .test_images import BaseImageTests class TestDisplayWorldCoordinate(BaseImageTests): def teardown_method(self, method): plt.close('all') def test_overlay_coords(self, ignore_matplotlibrc, tmpdir): wcs = WCS(self.msx_header) fig = plt.figure(figsize=(4, 4)) canvas = fig.canvas ax = WCSAxes(fig, [0.1, 0.1, 0.8, 0.8], wcs=wcs) fig.add_axes(ax) # On some systems, fig.canvas.draw is not enough to force a draw, so we # save to a temporary file. fig.savefig(tmpdir.join('test1.png').strpath) # Testing default displayed world coordinates string_world = ax._display_world_coords(0.523412, 0.518311) assert string_world == '0\xb029\'45" -0\xb029\'20" (world)' # Test pixel coordinates event1 = KeyEvent('test_pixel_coords', canvas, 'w') fig.canvas.key_press_event(event1.key, guiEvent=event1) string_pixel = ax._display_world_coords(0.523412, 0.523412) assert string_pixel == "0.523412 0.523412 (pixel)" event3 = KeyEvent('test_pixel_coords', canvas, 'w') fig.canvas.key_press_event(event3.key, guiEvent=event3) # Test that it still displays world coords when there are no overlay coords string_world2 = ax._display_world_coords(0.523412, 0.518311) assert string_world2 == '0\xb029\'45" -0\xb029\'20" (world)' overlay = ax.get_coords_overlay('fk5') # Regression test for bug that caused format to always be taken from # main world coordinates. overlay[0].set_major_formatter('d.ddd') # On some systems, fig.canvas.draw is not enough to force a draw, so we # save to a temporary file. fig.savefig(tmpdir.join('test2.png').strpath) event4 = KeyEvent('test_pixel_coords', canvas, 'w') fig.canvas.key_press_event(event4.key, guiEvent=event4) # Test that it displays the overlay world coordinates string_world3 = ax._display_world_coords(0.523412, 0.518311) assert string_world3 == '267.176\xb0 -28\xb045\'56" (world, overlay 1)' overlay = ax.get_coords_overlay(FK5()) # Regression test for bug that caused format to always be taken from # main world coordinates. overlay[0].set_major_formatter('d.ddd') # On some systems, fig.canvas.draw is not enough to force a draw, so we # save to a temporary file. fig.savefig(tmpdir.join('test3.png').strpath) event5 = KeyEvent('test_pixel_coords', canvas, 'w') fig.canvas.key_press_event(event4.key, guiEvent=event4) # Test that it displays the overlay world coordinates string_world4 = ax._display_world_coords(0.523412, 0.518311) assert string_world4 == '267.176\xb0 -28\xb045\'56" (world, overlay 2)' overlay = ax.get_coords_overlay(FK5(equinox=Time("J2030"))) # Regression test for bug that caused format to always be taken from # main world coordinates. overlay[0].set_major_formatter('d.ddd') # On some systems, fig.canvas.draw is not enough to force a draw, so we # save to a temporary file. fig.savefig(tmpdir.join('test4.png').strpath) event6 = KeyEvent('test_pixel_coords', canvas, 'w') fig.canvas.key_press_event(event5.key, guiEvent=event6) # Test that it displays the overlay world coordinates string_world5 = ax._display_world_coords(0.523412, 0.518311) assert string_world5 == '267.652\xb0 -28\xb046\'23" (world, overlay 3)' def test_cube_coords(self, ignore_matplotlibrc, tmpdir): wcs = WCS(self.cube_header) fig = plt.figure(figsize=(4, 4)) canvas = fig.canvas ax = WCSAxes(fig, [0.1, 0.1, 0.8, 0.8], wcs=wcs, slices=('y', 50, 'x')) fig.add_axes(ax) # On some systems, fig.canvas.draw is not enough to force a draw, so we # save to a temporary file. fig.savefig(tmpdir.join('test.png').strpath) # Testing default displayed world coordinates string_world = ax._display_world_coords(0.523412, 0.518311) assert string_world == '3h26m52.0s 30\xb037\'17\" 2563 (world)' # Test pixel coordinates event1 = KeyEvent('test_pixel_coords', canvas, 'w') fig.canvas.key_press_event(event1.key, guiEvent=event1) string_pixel = ax._display_world_coords(0.523412, 0.523412) assert string_pixel == "0.523412 0.523412 (pixel)" def test_cube_coords_uncorr_slicing(self, ignore_matplotlibrc, tmpdir): # Regression test for a bug that occurred with coordinate formatting if # some dimensions were uncorrelated and sliced out. wcs = WCS(self.cube_header) fig = plt.figure(figsize=(4, 4)) canvas = fig.canvas ax = WCSAxes(fig, [0.1, 0.1, 0.8, 0.8], wcs=wcs, slices=('x', 'y', 2)) fig.add_axes(ax) # On some systems, fig.canvas.draw is not enough to force a draw, so we # save to a temporary file. fig.savefig(tmpdir.join('test.png').strpath) # Testing default displayed world coordinates string_world = ax._display_world_coords(0.523412, 0.518311) assert string_world == '3h26m56.6s 30\xb018\'19\" (world)' # Test pixel coordinates event1 = KeyEvent('test_pixel_coords', canvas, 'w') fig.canvas.key_press_event(event1.key, guiEvent=event1) string_pixel = ax._display_world_coords(0.523412, 0.523412) assert string_pixel == "0.523412 0.523412 (pixel)" def test_plot_coord_3d_transform(self): wcs = WCS(self.msx_header) with galactocentric_frame_defaults.set('latest'): coord = SkyCoord(0 * u.kpc, 0 * u.kpc, 0 * u.kpc, frame='galactocentric') fig = plt.figure() ax = fig.add_subplot(1, 1, 1, projection=wcs) point, = ax.plot_coord(coord, 'ro') np.testing.assert_allclose(point.get_xydata()[0], [0, 0], atol=1e-4) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/tests/test_formatter_locator.py0000644000175100001710000005371500000000000026640 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import pytest import numpy as np from numpy.testing import assert_almost_equal from matplotlib import rc_context from astropy import units as u from astropy.tests.helper import assert_quantity_allclose from astropy.units import UnitsError from astropy.visualization.wcsaxes.formatter_locator import AngleFormatterLocator, ScalarFormatterLocator class TestAngleFormatterLocator: def test_no_options(self): fl = AngleFormatterLocator() assert fl.values is None assert fl.number == 5 assert fl.spacing is None def test_too_many_options(self): with pytest.raises(ValueError) as exc: AngleFormatterLocator(values=[1., 2.], number=5) assert exc.value.args[0] == "At most one of values/number/spacing can be specified" with pytest.raises(ValueError) as exc: AngleFormatterLocator(values=[1., 2.], spacing=5. * u.deg) assert exc.value.args[0] == "At most one of values/number/spacing can be specified" with pytest.raises(ValueError) as exc: AngleFormatterLocator(number=5, spacing=5. * u.deg) assert exc.value.args[0] == "At most one of values/number/spacing can be specified" with pytest.raises(ValueError) as exc: AngleFormatterLocator(values=[1., 2.], number=5, spacing=5. * u.deg) assert exc.value.args[0] == "At most one of values/number/spacing can be specified" def test_values(self): fl = AngleFormatterLocator(values=[0.1, 1., 14.] * u.degree) assert fl.values.to_value(u.degree).tolist() == [0.1, 1., 14.] assert fl.number is None assert fl.spacing is None values, spacing = fl.locator(34.3, 55.4) assert_almost_equal(values.to_value(u.degree), [0.1, 1., 14.]) def test_number(self): fl = AngleFormatterLocator(number=7) assert fl.values is None assert fl.number == 7 assert fl.spacing is None values, spacing = fl.locator(34.3, 55.4) assert_almost_equal(values.to_value(u.degree), [35., 40., 45., 50., 55.]) values, spacing = fl.locator(34.3, 36.1) assert_almost_equal(values.to_value(u.degree), [34.5, 34.75, 35., 35.25, 35.5, 35.75, 36.]) fl.format = 'dd' values, spacing = fl.locator(34.3, 36.1) assert_almost_equal(values.to_value(u.degree), [35., 36.]) def test_spacing(self): with pytest.raises(TypeError) as exc: AngleFormatterLocator(spacing=3.) assert exc.value.args[0] == "spacing should be an astropy.units.Quantity instance with units of angle" fl = AngleFormatterLocator(spacing=3. * u.degree) assert fl.values is None assert fl.number is None assert fl.spacing == 3. * u.degree values, spacing = fl.locator(34.3, 55.4) assert_almost_equal(values.to_value(u.degree), [36., 39., 42., 45., 48., 51., 54.]) fl.spacing = 30. * u.arcmin values, spacing = fl.locator(34.3, 36.1) assert_almost_equal(values.to_value(u.degree), [34.5, 35., 35.5, 36.]) with pytest.warns(UserWarning, match=r'Spacing is too small'): fl.format = 'dd' values, spacing = fl.locator(34.3, 36.1) assert_almost_equal(values.to_value(u.degree), [35., 36.]) def test_minor_locator(self): fl = AngleFormatterLocator() values, spacing = fl.locator(34.3, 55.4) minor_values = fl.minor_locator(spacing, 5, 34.3, 55.4) assert_almost_equal(minor_values.to_value(u.degree), [36., 37., 38., 39., 41., 42., 43., 44., 46., 47., 48., 49., 51., 52., 53., 54.]) minor_values = fl.minor_locator(spacing, 2, 34.3, 55.4) assert_almost_equal(minor_values.to_value(u.degree), [37.5, 42.5, 47.5, 52.5]) fl.values = [0.1, 1., 14.] * u.degree values, spacing = fl.locator(34.3, 36.1) minor_values = fl.minor_locator(spacing, 2, 34.3, 55.4) assert_almost_equal(minor_values.to_value(u.degree), []) @pytest.mark.parametrize(('format', 'string'), [('dd', '15\xb0'), ('dd:mm', '15\xb024\''), ('dd:mm:ss', '15\xb023\'32"'), ('dd:mm:ss.s', '15\xb023\'32.0"'), ('dd:mm:ss.ssss', '15\xb023\'32.0316"'), ('hh', '1h'), ('hh:mm', '1h02m'), ('hh:mm:ss', '1h01m34s'), ('hh:mm:ss.s', '1h01m34.1s'), ('hh:mm:ss.ssss', '1h01m34.1354s'), ('d', '15\xb0'), ('d.d', '15.4\xb0'), ('d.dd', '15.39\xb0'), ('d.ddd', '15.392\xb0'), ('m', '924\''), ('m.m', '923.5\''), ('m.mm', '923.53\''), ('s', '55412"'), ('s.s', '55412.0"'), ('s.ss', '55412.03"'), ]) def test_format(self, format, string): fl = AngleFormatterLocator(number=5, format=format) assert fl.formatter([15.392231] * u.degree, None, format='ascii')[0] == string @pytest.mark.parametrize(('separator', 'format', 'string'), [(('deg', "'", '"'), 'dd', '15deg'), (('deg', "'", '"'), 'dd:mm', '15deg24\''), (('deg', "'", '"'), 'dd:mm:ss', '15deg23\'32"'), ((':', "-", 's'), 'dd:mm:ss.s', '15:23-32.0s'), (':', 'dd:mm:ss.s', '15:23:32.0'), ((':', ":", 's'), 'hh', '1:'), (('-', "-", 's'), 'hh:mm:ss.ssss', '1-01-34.1354s'), (('d', ":", '"'), 'd', '15\xb0'), (('d', ":", '"'), 'd.d', '15.4\xb0'), ]) def test_separator(self, separator, format, string): fl = AngleFormatterLocator(number=5, format=format) fl.sep = separator assert fl.formatter([15.392231] * u.degree, None)[0] == string def test_latex_format(self): fl = AngleFormatterLocator(number=5, format="dd:mm:ss") assert fl.formatter([15.392231] * u.degree, None)[0] == '15\xb023\'32"' with rc_context(rc={'text.usetex': True}): assert fl.formatter([15.392231] * u.degree, None)[0] == "$15^\\circ23{}^\\prime32{}^{\\prime\\prime}$" @pytest.mark.parametrize(('format'), ['x.xxx', 'dd.ss', 'dd:ss', 'mdd:mm:ss']) def test_invalid_formats(self, format): fl = AngleFormatterLocator(number=5) with pytest.raises(ValueError) as exc: fl.format = format assert exc.value.args[0] == "Invalid format: " + format @pytest.mark.parametrize(('format', 'base_spacing'), [('dd', 1. * u.deg), ('dd:mm', 1. * u.arcmin), ('dd:mm:ss', 1. * u.arcsec), ('dd:mm:ss.ss', 0.01 * u.arcsec), ('hh', 15. * u.deg), ('hh:mm', 15. * u.arcmin), ('hh:mm:ss', 15. * u.arcsec), ('hh:mm:ss.ss', 0.15 * u.arcsec), ('d', 1. * u.deg), ('d.d', 0.1 * u.deg), ('d.dd', 0.01 * u.deg), ('d.ddd', 0.001 * u.deg), ('m', 1. * u.arcmin), ('m.m', 0.1 * u.arcmin), ('m.mm', 0.01 * u.arcmin), ('s', 1. * u.arcsec), ('s.s', 0.1 * u.arcsec), ('s.ss', 0.01 * u.arcsec), ]) def test_base_spacing(self, format, base_spacing): fl = AngleFormatterLocator(number=5, format=format) assert fl.base_spacing == base_spacing def test_incorrect_spacing(self): fl = AngleFormatterLocator() fl.spacing = 0.032 * u.deg with pytest.warns(UserWarning, match=r'Spacing is not a multiple of base spacing'): fl.format = 'dd:mm:ss' assert_almost_equal(fl.spacing.to_value(u.arcsec), 115.) def test_decimal_values(self): # Regression test for a bug that meant that the spacing was not # determined correctly for decimal coordinates fl = AngleFormatterLocator() fl.format = 'd.dddd' assert_quantity_allclose(fl.locator(266.9730, 266.9750)[0], [266.9735, 266.9740, 266.9745, 266.9750] * u.deg) fl = AngleFormatterLocator(decimal=True, format_unit=u.hourangle, number=4) assert_quantity_allclose(fl.locator(266.9730, 266.9750)[0], [17.79825, 17.79830] * u.hourangle) def test_values_unit(self): # Make sure that the intrinsic unit and format unit are correctly # taken into account when using the locator fl = AngleFormatterLocator(unit=u.arcsec, format_unit=u.arcsec, decimal=True) assert_quantity_allclose(fl.locator(850, 2150)[0], [1000., 1200., 1400., 1600., 1800., 2000.] * u.arcsec) fl = AngleFormatterLocator(unit=u.arcsec, format_unit=u.degree, decimal=False) assert_quantity_allclose(fl.locator(850, 2150)[0], [15., 20., 25., 30., 35.] * u.arcmin) fl = AngleFormatterLocator(unit=u.arcsec, format_unit=u.hourangle, decimal=False) assert_quantity_allclose(fl.locator(850, 2150)[0], [60., 75., 90., 105., 120., 135.] * (15 * u.arcsec)) fl = AngleFormatterLocator(unit=u.arcsec) fl.format = 'dd:mm:ss' assert_quantity_allclose(fl.locator(0.9, 1.1)[0], [1] * u.arcsec) fl = AngleFormatterLocator(unit=u.arcsec, spacing=0.2 * u.arcsec) assert_quantity_allclose(fl.locator(0.3, 0.9)[0], [0.4, 0.6, 0.8] * u.arcsec) @pytest.mark.parametrize(('spacing', 'string'), [(2 * u.deg, '15\xb0'), (2 * u.arcmin, '15\xb024\''), (2 * u.arcsec, '15\xb023\'32"'), (0.1 * u.arcsec, '15\xb023\'32.0"')]) def test_formatter_no_format(self, spacing, string): fl = AngleFormatterLocator() assert fl.formatter([15.392231] * u.degree, spacing)[0] == string @pytest.mark.parametrize(('format_unit', 'decimal', 'show_decimal_unit', 'spacing', 'ascii', 'latex'), [(u.degree, False, True, 2 * u.degree, '15\xb0', r'$15^\circ$'), (u.degree, False, True, 2 * u.arcmin, '15\xb024\'', r'$15^\circ24{}^\prime$'), (u.degree, False, True, 2 * u.arcsec, '15\xb023\'32"', r'$15^\circ23{}^\prime32{}^{\prime\prime}$'), (u.degree, False, True, 0.1 * u.arcsec, '15\xb023\'32.0"', r'$15^\circ23{}^\prime32.0{}^{\prime\prime}$'), (u.hourangle, False, True, 15 * u.degree, '1h', r'$1^{\mathrm{h}}$'), (u.hourangle, False, True, 15 * u.arcmin, '1h02m', r'$1^{\mathrm{h}}02^{\mathrm{m}}$'), (u.hourangle, False, True, 15 * u.arcsec, '1h01m34s', r'$1^{\mathrm{h}}01^{\mathrm{m}}34^{\mathrm{s}}$'), (u.hourangle, False, True, 1.5 * u.arcsec, '1h01m34.1s', r'$1^{\mathrm{h}}01^{\mathrm{m}}34.1^{\mathrm{s}}$'), (u.degree, True, True, 15 * u.degree, '15\xb0', r'$15\mathrm{^\circ}$'), (u.degree, True, True, 0.12 * u.degree, '15.39\xb0', r'$15.39\mathrm{^\circ}$'), (u.degree, True, True, 0.0036 * u.arcsec, '15.392231\xb0', r'$15.392231\mathrm{^\circ}$'), (u.arcmin, True, True, 15 * u.degree, '924\'', r'$924\mathrm{^\prime}$'), (u.arcmin, True, True, 0.12 * u.degree, '923.5\'', r'$923.5\mathrm{^\prime}$'), (u.arcmin, True, True, 0.1 * u.arcmin, '923.5\'', r'$923.5\mathrm{^\prime}$'), (u.arcmin, True, True, 0.0002 * u.arcmin, '923.5339\'', r'$923.5339\mathrm{^\prime}$'), (u.arcsec, True, True, 0.01 * u.arcsec, '55412.03"', r'$55412.03\mathrm{^{\prime\prime}}$'), (u.arcsec, True, True, 0.001 * u.arcsec, '55412.032"', r'$55412.032\mathrm{^{\prime\prime}}$'), (u.mas, True, True, 0.001 * u.arcsec, '55412032mas', r'$55412032\mathrm{mas}$'), (u.degree, True, False, 15 * u.degree, '15', '15'), (u.degree, True, False, 0.12 * u.degree, '15.39', '15.39'), (u.degree, True, False, 0.0036 * u.arcsec, '15.392231', '15.392231'), (u.arcmin, True, False, 15 * u.degree, '924', '924'), (u.arcmin, True, False, 0.12 * u.degree, '923.5', '923.5'), (u.arcmin, True, False, 0.1 * u.arcmin, '923.5', '923.5'), (u.arcmin, True, False, 0.0002 * u.arcmin, '923.5339', '923.5339'), (u.arcsec, True, False, 0.01 * u.arcsec, '55412.03', '55412.03'), (u.arcsec, True, False, 0.001 * u.arcsec, '55412.032', '55412.032'), (u.mas, True, False, 0.001 * u.arcsec, '55412032', '55412032'), # Make sure that specifying None defaults to # decimal for non-degree or non-hour angles (u.arcsec, None, True, 0.01 * u.arcsec, '55412.03"', r'$55412.03\mathrm{^{\prime\prime}}$')]) def test_formatter_no_format_with_units(self, format_unit, decimal, show_decimal_unit, spacing, ascii, latex): # Check the formatter works when specifying the default units and # decimal behavior to use. fl = AngleFormatterLocator(unit=u.degree, format_unit=format_unit, decimal=decimal, show_decimal_unit=show_decimal_unit) assert fl.formatter([15.392231] * u.degree, spacing, format='ascii')[0] == ascii assert fl.formatter([15.392231] * u.degree, spacing, format='latex')[0] == latex def test_incompatible_unit_decimal(self): with pytest.raises(UnitsError) as exc: AngleFormatterLocator(unit=u.arcmin, decimal=False) assert exc.value.args[0] == 'Units should be degrees or hours when using non-decimal (sexagesimal) mode' class TestScalarFormatterLocator: def test_no_options(self): fl = ScalarFormatterLocator(unit=u.m) assert fl.values is None assert fl.number == 5 assert fl.spacing is None def test_too_many_options(self): with pytest.raises(ValueError) as exc: ScalarFormatterLocator(values=[1., 2.] * u.m, number=5) assert exc.value.args[0] == "At most one of values/number/spacing can be specified" with pytest.raises(ValueError) as exc: ScalarFormatterLocator(values=[1., 2.] * u.m, spacing=5. * u.m) assert exc.value.args[0] == "At most one of values/number/spacing can be specified" with pytest.raises(ValueError) as exc: ScalarFormatterLocator(number=5, spacing=5. * u.m) assert exc.value.args[0] == "At most one of values/number/spacing can be specified" with pytest.raises(ValueError) as exc: ScalarFormatterLocator(values=[1., 2.] * u.m, number=5, spacing=5. * u.m) assert exc.value.args[0] == "At most one of values/number/spacing can be specified" def test_values(self): fl = ScalarFormatterLocator(values=[0.1, 1., 14.] * u.m, unit=u.m) assert fl.values.value.tolist() == [0.1, 1., 14.] assert fl.number is None assert fl.spacing is None values, spacing = fl.locator(34.3, 55.4) assert_almost_equal(values.value, [0.1, 1., 14.]) def test_number(self): fl = ScalarFormatterLocator(number=7, unit=u.m) assert fl.values is None assert fl.number == 7 assert fl.spacing is None values, spacing = fl.locator(34.3, 55.4) assert_almost_equal(values.value, np.linspace(36., 54., 10)) values, spacing = fl.locator(34.3, 36.1) assert_almost_equal(values.value, np.linspace(34.4, 36, 9)) fl.format = 'x' values, spacing = fl.locator(34.3, 36.1) assert_almost_equal(values.value, [35., 36.]) def test_spacing(self): fl = ScalarFormatterLocator(spacing=3. * u.m) assert fl.values is None assert fl.number is None assert fl.spacing == 3. * u.m values, spacing = fl.locator(34.3, 55.4) assert_almost_equal(values.value, [36., 39., 42., 45., 48., 51., 54.]) fl.spacing = 0.5 * u.m values, spacing = fl.locator(34.3, 36.1) assert_almost_equal(values.value, [34.5, 35., 35.5, 36.]) with pytest.warns(UserWarning, match=r'Spacing is too small'): fl.format = 'x' values, spacing = fl.locator(34.3, 36.1) assert_almost_equal(values.value, [35., 36.]) def test_minor_locator(self): fl = ScalarFormatterLocator(unit=u.m) values, spacing = fl.locator(34.3, 55.4) minor_values = fl.minor_locator(spacing, 5, 34.3, 55.4) assert_almost_equal(minor_values.value, [36., 37., 38., 39., 41., 42., 43., 44., 46., 47., 48., 49., 51., 52., 53., 54.]) minor_values = fl.minor_locator(spacing, 2, 34.3, 55.4) assert_almost_equal(minor_values.value, [37.5, 42.5, 47.5, 52.5]) fl.values = [0.1, 1., 14.] * u.m values, spacing = fl.locator(34.3, 36.1) minor_values = fl.minor_locator(spacing, 2, 34.3, 55.4) assert_almost_equal(minor_values.value, []) @pytest.mark.parametrize(('format', 'string'), [('x', '15'), ('x.x', '15.4'), ('x.xx', '15.39'), ('x.xxx', '15.392'), ('%g', '15.3922'), ('%f', '15.392231'), ('%.2f', '15.39'), ('%.3f', '15.392')]) def test_format(self, format, string): fl = ScalarFormatterLocator(number=5, format=format, unit=u.m) assert fl.formatter([15.392231] * u.m, None)[0] == string @pytest.mark.parametrize(('format', 'string'), [('x', '1539'), ('x.x', '1539.2'), ('x.xx', '1539.22'), ('x.xxx', '1539.223')]) def test_format_unit(self, format, string): fl = ScalarFormatterLocator(number=5, format=format, unit=u.m) fl.format_unit = u.cm assert fl.formatter([15.392231] * u.m, None)[0] == string @pytest.mark.parametrize(('format'), ['dd', 'dd:mm', 'xx:mm', 'mx.xxx']) def test_invalid_formats(self, format): fl = ScalarFormatterLocator(number=5, unit=u.m) with pytest.raises(ValueError) as exc: fl.format = format assert exc.value.args[0] == "Invalid format: " + format @pytest.mark.parametrize(('format', 'base_spacing'), [('x', 1. * u.m), ('x.x', 0.1 * u.m), ('x.xxx', 0.001 * u.m)]) def test_base_spacing(self, format, base_spacing): fl = ScalarFormatterLocator(number=5, format=format, unit=u.m) assert fl.base_spacing == base_spacing def test_incorrect_spacing(self): fl = ScalarFormatterLocator(unit=u.m) fl.spacing = 0.032 * u.m with pytest.warns(UserWarning, match=r'Spacing is not a multiple of base spacing'): fl.format = 'x.xx' assert_almost_equal(fl.spacing.to_value(u.m), 0.03) def test_values_unit(self): # Make sure that the intrinsic unit and format unit are correctly # taken into account when using the locator fl = ScalarFormatterLocator(unit=u.cm, format_unit=u.m) assert_quantity_allclose(fl.locator(850, 2150)[0], [1000., 1200., 1400., 1600., 1800., 2000.] * u.cm) fl = ScalarFormatterLocator(unit=u.cm, format_unit=u.m) fl.format = 'x.x' assert_quantity_allclose(fl.locator(1, 19)[0], [10] * u.cm) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/tests/test_frame.py0000644000175100001710000001225200000000000024173 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import pytest import numpy as np import matplotlib.pyplot as plt from astropy.wcs import WCS from astropy.visualization.wcsaxes import WCSAxes from astropy.visualization.wcsaxes.frame import BaseFrame from astropy.tests.image_tests import IMAGE_REFERENCE_DIR from .test_images import BaseImageTests class HexagonalFrame(BaseFrame): spine_names = 'abcdef' def update_spines(self): xmin, xmax = self.parent_axes.get_xlim() ymin, ymax = self.parent_axes.get_ylim() ymid = 0.5 * (ymin + ymax) xmid1 = (xmin + xmax) / 4. xmid2 = (xmin + xmax) * 3. / 4. self['a'].data = np.array(([xmid1, ymin], [xmid2, ymin])) self['b'].data = np.array(([xmid2, ymin], [xmax, ymid])) self['c'].data = np.array(([xmax, ymid], [xmid2, ymax])) self['d'].data = np.array(([xmid2, ymax], [xmid1, ymax])) self['e'].data = np.array(([xmid1, ymax], [xmin, ymid])) self['f'].data = np.array(([xmin, ymid], [xmid1, ymin])) class TestFrame(BaseImageTests): @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_custom_frame(self): wcs = WCS(self.msx_header) fig = plt.figure(figsize=(4, 4)) ax = WCSAxes(fig, [0.15, 0.15, 0.7, 0.7], wcs=wcs, frame_class=HexagonalFrame) fig.add_axes(ax) ax.coords.grid(color='white') im = ax.imshow(np.ones((149, 149)), vmin=0., vmax=2., origin='lower', cmap=plt.cm.gist_heat) minpad = {} minpad['a'] = minpad['d'] = 1 minpad['b'] = minpad['c'] = minpad['e'] = minpad['f'] = 2.75 ax.coords['glon'].set_axislabel("Longitude", minpad=minpad) ax.coords['glon'].set_axislabel_position('ad') ax.coords['glat'].set_axislabel("Latitude", minpad=minpad) ax.coords['glat'].set_axislabel_position('bcef') ax.coords['glon'].set_ticklabel_position('ad') ax.coords['glat'].set_ticklabel_position('bcef') # Set limits so that no labels overlap ax.set_xlim(5.5, 100.5) ax.set_ylim(5.5, 110.5) # Clip the image to the frame im.set_clip_path(ax.coords.frame.patch) return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_update_clip_path_rectangular(self, tmpdir): fig = plt.figure() ax = WCSAxes(fig, [0.1, 0.1, 0.8, 0.8], aspect='equal') fig.add_axes(ax) ax.set_xlim(0., 2.) ax.set_ylim(0., 2.) # Force drawing, which freezes the clip path returned by WCSAxes fig.savefig(tmpdir.join('nothing').strpath) ax.imshow(np.zeros((12, 4))) ax.set_xlim(-0.5, 3.5) ax.set_ylim(-0.5, 11.5) ax.coords[0].set_auto_axislabel(False) ax.coords[1].set_auto_axislabel(False) return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_update_clip_path_nonrectangular(self, tmpdir): fig = plt.figure() ax = WCSAxes(fig, [0.1, 0.1, 0.8, 0.8], aspect='equal', frame_class=HexagonalFrame) fig.add_axes(ax) ax.set_xlim(0., 2.) ax.set_ylim(0., 2.) # Force drawing, which freezes the clip path returned by WCSAxes fig.savefig(tmpdir.join('nothing').strpath) ax.imshow(np.zeros((12, 4))) ax.set_xlim(-0.5, 3.5) ax.set_ylim(-0.5, 11.5) return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_update_clip_path_change_wcs(self, tmpdir): # When WCS is changed, a new frame is created, so we need to make sure # that the path is carried over to the new frame. fig = plt.figure() ax = WCSAxes(fig, [0.1, 0.1, 0.8, 0.8], aspect='equal') fig.add_axes(ax) ax.set_xlim(0., 2.) ax.set_ylim(0., 2.) # Force drawing, which freezes the clip path returned by WCSAxes fig.savefig(tmpdir.join('nothing').strpath) ax.reset_wcs() ax.imshow(np.zeros((12, 4))) ax.set_xlim(-0.5, 3.5) ax.set_ylim(-0.5, 11.5) ax.coords[0].set_auto_axislabel(False) ax.coords[1].set_auto_axislabel(False) return fig def test_copy_frame_properties_change_wcs(self): # When WCS is changed, a new frame is created, so we need to make sure # that the color and linewidth are transferred over fig = plt.figure() ax = WCSAxes(fig, [0.1, 0.1, 0.8, 0.8]) fig.add_axes(ax) ax.coords.frame.set_linewidth(5) ax.coords.frame.set_color('purple') ax.reset_wcs() assert ax.coords.frame.get_linewidth() == 5 assert ax.coords.frame.get_color() == 'purple' ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/tests/test_grid_paths.py0000644000175100001710000000203200000000000025220 0ustar00vstsdockerimport numpy as np import pytest from matplotlib.lines import Path from astropy.visualization.wcsaxes.grid_paths import get_lon_lat_path @pytest.mark.parametrize('step_in_degrees', [10, 1, 0.01]) def test_round_trip_visibility(step_in_degrees): zero = np.zeros(100) # The pixel values are irrelevant for this test pixel = np.stack([zero, zero]).T # Create a grid line of constant latitude with a point every step line = np.stack([np.arange(100), zero]).T * step_in_degrees # Create a modified grid line where the point spacing is larger by 5% # Starting with point 20, the discrepancy between `line` and `line_round` is greater than `step` line_round = line * 1.05 # Perform the round-trip check path = get_lon_lat_path(line, pixel, line_round) # The grid line should be visible for only the initial part line (19 points) codes_check = np.full(100, Path.MOVETO) codes_check[line_round[:, 0] - line[:, 0] < step_in_degrees] = Path.LINETO assert np.all(path.codes[1:] == codes_check[1:]) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/tests/test_images.py0000644000175100001710000011700500000000000024350 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import matplotlib.lines import matplotlib.pyplot as plt import pytest from matplotlib import rc_context from matplotlib.patches import Circle, Rectangle import numpy as np from astropy import units as u from astropy.coordinates import SkyCoord from astropy.io import fits from astropy.tests.image_tests import IMAGE_REFERENCE_DIR from astropy.utils.data import get_pkg_data_filename from astropy.utils.exceptions import AstropyUserWarning from astropy.visualization.wcsaxes import WCSAxes from astropy.visualization.wcsaxes.frame import EllipticalFrame from astropy.visualization.wcsaxes.patches import Quadrangle, SphericalCircle from astropy.wcs import WCS class BaseImageTests: @classmethod def setup_class(cls): msx_header = get_pkg_data_filename('data/msx_header') cls.msx_header = fits.Header.fromtextfile(msx_header) rosat_header = get_pkg_data_filename('data/rosat_header') cls.rosat_header = fits.Header.fromtextfile(rosat_header) twoMASS_k_header = get_pkg_data_filename('data/2MASS_k_header') cls.twoMASS_k_header = fits.Header.fromtextfile(twoMASS_k_header) cube_header = get_pkg_data_filename('data/cube_header') cls.cube_header = fits.Header.fromtextfile(cube_header) slice_header = get_pkg_data_filename('data/slice_header') cls.slice_header = fits.Header.fromtextfile(slice_header) def teardown_method(self, method): plt.close('all') class TestBasic(BaseImageTests): @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_image_plot(self): # Test for plotting image and also setting values of ticks fig = plt.figure(figsize=(6, 6)) ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], projection=WCS(self.msx_header), aspect='equal') ax.set_xlim(-0.5, 148.5) ax.set_ylim(-0.5, 148.5) ax.coords[0].set_ticks([-0.30, 0., 0.20] * u.degree, size=5, width=1) return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_axes_off(self): # Test for turning the axes off fig = plt.figure(figsize=(3, 3)) ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], projection=WCS(self.msx_header)) ax.imshow(np.arange(12).reshape((3, 4))) ax.set_axis_off() return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=1.5, style={}) @pytest.mark.parametrize('axisbelow', [True, False, 'line']) def test_axisbelow(self, axisbelow): # Test that tick marks, labels, and gridlines are drawn with the # correct zorder controlled by the axisbelow property. fig = plt.figure(figsize=(6, 6)) ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], projection=WCS(self.msx_header), aspect='equal') ax.set_axisbelow(axisbelow) ax.set_xlim(-0.5, 148.5) ax.set_ylim(-0.5, 148.5) ax.coords[0].set_ticks([-0.30, 0., 0.20] * u.degree, size=5, width=1) ax.grid() ax.coords[0].set_auto_axislabel(False) ax.coords[1].set_auto_axislabel(False) # Add an image (default zorder=0). ax.imshow(np.zeros((64, 64))) # Add a patch (default zorder=1). r = Rectangle((30., 50.), 60., 50., facecolor='green', edgecolor='red') ax.add_patch(r) # Add a line (default zorder=2). ax.plot([32, 128], [32, 128], linewidth=10) return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_contour_overlay(self): # Test for overlaying contours on images path = get_pkg_data_filename('galactic_center/gc_msx_e.fits') with fits.open(path) as pf: data = pf[0].data wcs_msx = WCS(self.msx_header) fig = plt.figure(figsize=(6, 6)) ax = fig.add_axes([0.15, 0.15, 0.8, 0.8], projection=WCS(self.twoMASS_k_header), aspect='equal') ax.set_xlim(-0.5, 720.5) ax.set_ylim(-0.5, 720.5) # Overplot contour ax.contour(data, transform=ax.get_transform(wcs_msx), colors='orange', levels=[2.5e-5, 5e-5, 1.e-4]) ax.coords[0].set_ticks(size=5, width=1) ax.coords[1].set_ticks(size=5, width=1) ax.set_xlim(0., 720.) ax.set_ylim(0., 720.) # In previous versions, all angle axes defaulted to being displayed in # degrees. We now automatically show RA axes in hour angle units, but # for backward-compatibility with previous reference images we # explicitly use degrees here. ax.coords[0].set_format_unit(u.degree) return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_contourf_overlay(self): # Test for overlaying contours on images path = get_pkg_data_filename('galactic_center/gc_msx_e.fits') with fits.open(path) as pf: data = pf[0].data wcs_msx = WCS(self.msx_header) fig = plt.figure(figsize=(6, 6)) ax = fig.add_axes([0.15, 0.15, 0.8, 0.8], projection=WCS(self.twoMASS_k_header), aspect='equal') ax.set_xlim(-0.5, 720.5) ax.set_ylim(-0.5, 720.5) # Overplot contour ax.contourf(data, transform=ax.get_transform(wcs_msx), levels=[2.5e-5, 5e-5, 1.e-4]) ax.coords[0].set_ticks(size=5, width=1) ax.coords[1].set_ticks(size=5, width=1) ax.set_xlim(0., 720.) ax.set_ylim(0., 720.) # In previous versions, all angle axes defaulted to being displayed in # degrees. We now automatically show RA axes in hour angle units, but # for backward-compatibility with previous reference images we # explicitly use degrees here. ax.coords[0].set_format_unit(u.degree) return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_overlay_features_image(self): # Test for overlaying grid, changing format of ticks, setting spacing # and number of ticks fig = plt.figure(figsize=(6, 6)) ax = fig.add_axes([0.25, 0.25, 0.65, 0.65], projection=WCS(self.msx_header), aspect='equal') # Change the format of the ticks ax.coords[0].set_major_formatter('dd:mm:ss') ax.coords[1].set_major_formatter('dd:mm:ss.ssss') # Overlay grid on image ax.grid(color='red', alpha=1.0, lw=1, linestyle='dashed') # Set the spacing of ticks on the 'glon' axis to 4 arcsec ax.coords['glon'].set_ticks(spacing=4 * u.arcsec, size=5, width=1) # Set the number of ticks on the 'glat' axis to 9 ax.coords['glat'].set_ticks(number=9, size=5, width=1) # Set labels on axes ax.coords['glon'].set_axislabel('Galactic Longitude', minpad=1.6) ax.coords['glat'].set_axislabel('Galactic Latitude', minpad=-0.75) # Change the frame linewidth and color ax.coords.frame.set_color('red') ax.coords.frame.set_linewidth(2) assert ax.coords.frame.get_color() == 'red' assert ax.coords.frame.get_linewidth() == 2 return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_curvilinear_grid_patches_image(self): # Overlay curvilinear grid and patches on image fig = plt.figure(figsize=(8, 8)) ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], projection=WCS(self.rosat_header), aspect='equal') ax.set_xlim(-0.5, 479.5) ax.set_ylim(-0.5, 239.5) ax.grid(color='black', alpha=1.0, lw=1, linestyle='dashed') p = Circle((300, 100), radius=40, ec='yellow', fc='none') ax.add_patch(p) p = Circle((30., 20.), radius=20., ec='orange', fc='none', transform=ax.get_transform('world')) ax.add_patch(p) p = Circle((60., 50.), radius=20., ec='red', fc='none', transform=ax.get_transform('fk5')) ax.add_patch(p) p = Circle((40., 60.), radius=20., ec='green', fc='none', transform=ax.get_transform('galactic')) ax.add_patch(p) return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_cube_slice_image(self): # Test for cube slicing fig = plt.figure() ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], projection=WCS(self.cube_header), slices=(50, 'y', 'x'), aspect='equal') ax.set_xlim(-0.5, 52.5) ax.set_ylim(-0.5, 106.5) ax.coords[2].set_axislabel('Velocity m/s') ax.coords[1].set_ticks(spacing=0.2 * u.deg, width=1) ax.coords[2].set_ticks(spacing=400 * u.m / u.s, width=1) ax.coords[1].set_ticklabel(exclude_overlapping=True) ax.coords[2].set_ticklabel(exclude_overlapping=True) ax.coords[0].grid(grid_type='contours', color='purple', linestyle='solid') ax.coords[1].grid(grid_type='contours', color='orange', linestyle='solid') ax.coords[2].grid(grid_type='contours', color='red', linestyle='solid') return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_cube_slice_image_lonlat(self): # Test for cube slicing. Here we test with longitude and latitude since # there is some longitude-specific code in _update_grid_contour. fig = plt.figure() ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], projection=WCS(self.cube_header), slices=('x', 'y', 50), aspect='equal') ax.set_xlim(-0.5, 106.5) ax.set_ylim(-0.5, 106.5) ax.coords[0].grid(grid_type='contours', color='blue', linestyle='solid') ax.coords[1].grid(grid_type='contours', color='red', linestyle='solid') # In previous versions, all angle axes defaulted to being displayed in # degrees. We now automatically show RA axes in hour angle units, but # for backward-compatibility with previous reference images we # explicitly use degrees here. ax.coords[0].set_format_unit(u.degree) return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_plot_coord(self): fig = plt.figure(figsize=(6, 6)) ax = fig.add_axes([0.15, 0.15, 0.8, 0.8], projection=WCS(self.twoMASS_k_header), aspect='equal') ax.set_xlim(-0.5, 720.5) ax.set_ylim(-0.5, 720.5) c = SkyCoord(266 * u.deg, -29 * u.deg) lines = ax.plot_coord(c, 'o') # Test that plot_coord returns the results from ax.plot assert isinstance(lines, list) assert isinstance(lines[0], matplotlib.lines.Line2D) # In previous versions, all angle axes defaulted to being displayed in # degrees. We now automatically show RA axes in hour angle units, but # for backward-compatibility with previous reference images we # explicitly use degrees here. ax.coords[0].set_format_unit(u.degree) return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_plot_line(self): fig = plt.figure(figsize=(6, 6)) ax = fig.add_axes([0.15, 0.15, 0.8, 0.8], projection=WCS(self.twoMASS_k_header), aspect='equal') ax.set_xlim(-0.5, 720.5) ax.set_ylim(-0.5, 720.5) c = SkyCoord([266, 266.8] * u.deg, [-29, -28.9] * u.deg) ax.plot_coord(c) # In previous versions, all angle axes defaulted to being displayed in # degrees. We now automatically show RA axes in hour angle units, but # for backward-compatibility with previous reference images we # explicitly use degrees here. ax.coords[0].set_format_unit(u.degree) return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_changed_axis_units(self): # Test to see if changing the units of axis works fig = plt.figure() ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], projection=WCS(self.cube_header), slices=(50, 'y', 'x'), aspect='equal') ax.set_xlim(-0.5, 52.5) ax.set_ylim(-0.5, 106.5) ax.coords[0].set_ticks_position('') ax.coords[0].set_ticklabel_position('') ax.coords[0].set_axislabel_position('') ax.coords[1].set_ticks_position('lr') ax.coords[1].set_ticklabel_position('l') ax.coords[1].set_axislabel_position('l') ax.coords[2].set_ticks_position('bt') ax.coords[2].set_ticklabel_position('b') ax.coords[2].set_axislabel_position('b') ax.coords[2].set_major_formatter('x.xx') ax.coords[2].set_format_unit(u.km / u.s) ax.coords[2].set_axislabel('Velocity km/s') ax.coords[1].set_ticks(width=1) ax.coords[2].set_ticks(width=1) ax.coords[1].set_ticklabel(exclude_overlapping=True) ax.coords[2].set_ticklabel(exclude_overlapping=True) return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_minor_ticks(self): # Test for drawing minor ticks fig = plt.figure() ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], projection=WCS(self.cube_header), slices=(50, 'y', 'x'), aspect='equal') ax.set_xlim(-0.5, 52.5) ax.set_ylim(-0.5, 106.5) ax.coords[0].set_ticks_position('') ax.coords[0].set_ticklabel_position('') ax.coords[0].set_axislabel_position('') ax.coords[1].set_ticks_position('lr') ax.coords[1].set_ticklabel_position('l') ax.coords[1].set_axislabel_position('l') ax.coords[2].set_ticks_position('bt') ax.coords[2].set_ticklabel_position('b') ax.coords[2].set_axislabel_position('b') ax.coords[2].set_ticklabel(exclude_overlapping=True) ax.coords[1].set_ticklabel(exclude_overlapping=True) ax.coords[2].display_minor_ticks(True) ax.coords[1].display_minor_ticks(True) ax.coords[2].set_minor_frequency(3) ax.coords[1].set_minor_frequency(10) return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_ticks_labels(self): fig = plt.figure(figsize=(6, 6)) ax = WCSAxes(fig, [0.1, 0.1, 0.7, 0.7], wcs=None) fig.add_axes(ax) ax.set_xlim(-0.5, 2) ax.set_ylim(-0.5, 2) ax.coords[0].set_ticks(size=10, color='blue', alpha=0.2, width=1) ax.coords[1].set_ticks(size=20, color='red', alpha=0.9, width=1) ax.coords[0].set_ticks_position('all') ax.coords[1].set_ticks_position('all') ax.coords[0].set_axislabel('X-axis', size=20) ax.coords[1].set_axislabel('Y-axis', color='green', size=25, weight='regular', style='normal', family='cmtt10') ax.coords[0].set_axislabel_position('t') ax.coords[1].set_axislabel_position('r') ax.coords[0].set_ticklabel(color='purple', size=15, alpha=1, weight='light', style='normal', family='cmss10') ax.coords[1].set_ticklabel(color='black', size=18, alpha=0.9, weight='bold', family='cmr10') ax.coords[0].set_ticklabel_position('all') ax.coords[1].set_ticklabel_position('r') return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_rcparams(self): # Test custom rcParams with rc_context({ 'axes.labelcolor': 'purple', 'axes.labelsize': 14, 'axes.labelweight': 'bold', 'axes.linewidth': 3, 'axes.facecolor': '0.5', 'axes.edgecolor': 'green', 'xtick.color': 'red', 'xtick.labelsize': 8, 'xtick.direction': 'in', 'xtick.minor.visible': True, 'xtick.minor.size': 5, 'xtick.major.size': 20, 'xtick.major.width': 3, 'xtick.major.pad': 10, 'grid.color': 'blue', 'grid.linestyle': ':', 'grid.linewidth': 1, 'grid.alpha': 0.5}): fig = plt.figure(figsize=(6, 6)) ax = WCSAxes(fig, [0.15, 0.1, 0.7, 0.7], wcs=None) fig.add_axes(ax) ax.set_xlim(-0.5, 2) ax.set_ylim(-0.5, 2) ax.grid() ax.set_xlabel('X label') ax.set_ylabel('Y label') ax.coords[0].set_ticklabel(exclude_overlapping=True) ax.coords[1].set_ticklabel(exclude_overlapping=True) return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_tick_angles(self): # Test that tick marks point in the correct direction, even when the # axes limits extend only over a few FITS pixels. Addresses #45, #46. w = WCS() w.wcs.ctype = ['RA---TAN', 'DEC--TAN'] w.wcs.crval = [90, 70] w.wcs.cdelt = [16, 16] w.wcs.crpix = [1, 1] w.wcs.radesys = 'ICRS' w.wcs.equinox = 2000.0 fig = plt.figure(figsize=(3, 3)) ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], projection=w) ax.set_xlim(1, -1) ax.set_ylim(-1, 1) ax.grid(color='gray', alpha=0.5, linestyle='solid') ax.coords['ra'].set_ticks(color='red', size=20) ax.coords['dec'].set_ticks(color='red', size=20) # In previous versions, all angle axes defaulted to being displayed in # degrees. We now automatically show RA axes in hour angle units, but # for backward-compatibility with previous reference images we # explicitly use degrees here. ax.coords[0].set_format_unit(u.degree) return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_tick_angles_non_square_axes(self): # Test that tick marks point in the correct direction, even when the # axes limits extend only over a few FITS pixels, and the axes are # non-square. w = WCS() w.wcs.ctype = ['RA---TAN', 'DEC--TAN'] w.wcs.crval = [90, 70] w.wcs.cdelt = [16, 16] w.wcs.crpix = [1, 1] w.wcs.radesys = 'ICRS' w.wcs.equinox = 2000.0 fig = plt.figure(figsize=(6, 3)) ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], projection=w) ax.set_xlim(1, -1) ax.set_ylim(-1, 1) ax.grid(color='gray', alpha=0.5, linestyle='solid') ax.coords['ra'].set_ticks(color='red', size=20) ax.coords['dec'].set_ticks(color='red', size=20) # In previous versions, all angle axes defaulted to being displayed in # degrees. We now automatically show RA axes in hour angle units, but # for backward-compatibility with previous reference images we # explicitly use degrees here. ax.coords[0].set_format_unit(u.degree) return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_set_coord_type(self): # Test for setting coord_type fig = plt.figure(figsize=(3, 3)) ax = fig.add_axes([0.2, 0.2, 0.6, 0.6], projection=WCS(self.msx_header), aspect='equal') ax.set_xlim(-0.5, 148.5) ax.set_ylim(-0.5, 148.5) ax.coords[0].set_coord_type('scalar') ax.coords[1].set_coord_type('scalar') ax.coords[0].set_major_formatter('x.xxx') ax.coords[1].set_major_formatter('x.xxx') ax.coords[0].set_ticklabel(exclude_overlapping=True) ax.coords[1].set_ticklabel(exclude_overlapping=True) return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_ticks_regression(self): # Regression test for a bug that caused ticks aligned exactly with a # sampled frame point to not appear. This also checks that tick labels # don't get added more than once, and that no error occurs when e.g. # the top part of the frame is all at the same coordinate as one of the # potential ticks (which causes the tick angle calculation to return # NaN). wcs = WCS(self.slice_header) fig = plt.figure(figsize=(3, 3)) ax = fig.add_axes([0.25, 0.25, 0.5, 0.5], projection=wcs, aspect='auto') limits = wcs.wcs_world2pix([0, 0], [35e3, 80e3], 0)[1] ax.set_ylim(*limits) ax.coords[0].set_ticks(spacing=0.002 * u.deg) ax.coords[1].set_ticks(spacing=5 * u.km / u.s) ax.coords[0].set_ticklabel(alpha=0.5) # to see multiple labels ax.coords[1].set_ticklabel(alpha=0.5) ax.coords[0].set_ticklabel_position('all') ax.coords[1].set_ticklabel_position('all') return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, savefig_kwargs={'bbox_inches': 'tight'}, tolerance=0, style={}) def test_axislabels_regression(self): # Regression test for a bug that meant that if tick labels were made # invisible with ``set_visible(False)``, they were still added to the # list of bounding boxes for tick labels, but with default values of 0 # to 1, which caused issues. wcs = WCS(self.msx_header) fig = plt.figure(figsize=(3, 3)) ax = fig.add_axes([0.25, 0.25, 0.5, 0.5], projection=wcs, aspect='auto') ax.coords[0].set_axislabel("Label 1") ax.coords[1].set_axislabel("Label 2") ax.coords[1].set_axislabel_visibility_rule('always') ax.coords[1].ticklabels.set_visible(False) return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, savefig_kwargs={'bbox_inches': 'tight'}, tolerance=0, style={}) def test_noncelestial_angular(self, tmpdir): # Regression test for a bug that meant that when passing a WCS that had # angular axes and using set_coord_type to set the coordinates to # longitude/latitude, but where the WCS wasn't recognized as celestial, # the WCS units are not converted to deg, so we can't assume that # transform will always return degrees. wcs = WCS(naxis=2) wcs.wcs.ctype = ['solar-x', 'solar-y'] wcs.wcs.cunit = ['arcsec', 'arcsec'] fig = plt.figure(figsize=(3, 3)) ax = fig.add_subplot(1, 1, 1, projection=wcs) ax.imshow(np.zeros([1024, 1024]), origin='lower') ax.coords[0].set_coord_type('longitude', coord_wrap=180) ax.coords[1].set_coord_type('latitude') ax.coords[0].set_major_formatter('s.s') ax.coords[1].set_major_formatter('s.s') ax.coords[0].set_format_unit(u.arcsec, show_decimal_unit=False) ax.coords[1].set_format_unit(u.arcsec, show_decimal_unit=False) ax.grid(color='white', ls='solid') # Force drawing (needed for format_coord) fig.savefig(tmpdir.join('nothing').strpath) assert ax.format_coord(512, 512) == '513.0 513.0 (world)' return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, savefig_kwargs={'bbox_inches': 'tight'}, tolerance=0, style={}) def test_patches_distortion(self, tmpdir): # Check how patches get distorted (and make sure that scatter markers # and SphericalCircle don't) wcs = WCS(self.msx_header) fig = plt.figure(figsize=(3, 3)) ax = fig.add_axes([0.25, 0.25, 0.5, 0.5], projection=wcs, aspect='equal') # Pixel coordinates r = Rectangle((30., 50.), 60., 50., edgecolor='green', facecolor='none') ax.add_patch(r) # FK5 coordinates r = Rectangle((266.4, -28.9), 0.3, 0.3, edgecolor='cyan', facecolor='none', transform=ax.get_transform('fk5')) ax.add_patch(r) # FK5 coordinates c = Circle((266.4, -29.1), 0.15, edgecolor='magenta', facecolor='none', transform=ax.get_transform('fk5')) ax.add_patch(c) # Pixel coordinates ax.scatter([40, 100, 130], [30, 130, 60], s=100, edgecolor='red', facecolor=(1, 0, 0, 0.5)) # World coordinates (should not be distorted) ax.scatter(266.78238, -28.769255, transform=ax.get_transform('fk5'), s=300, edgecolor='red', facecolor='none') # World coordinates (should not be distorted) r1 = SphericalCircle((266.4 * u.deg, -29.1 * u.deg), 0.15 * u.degree, edgecolor='purple', facecolor='none', transform=ax.get_transform('fk5')) ax.add_patch(r1) r2 = SphericalCircle(SkyCoord(266.4 * u.deg, -29.1 * u.deg), 0.15 * u.degree, edgecolor='purple', facecolor='none', transform=ax.get_transform('fk5')) with pytest.warns(AstropyUserWarning, match="Received `center` of representation type " " " "will be converted to SphericalRepresentation"): r3 = SphericalCircle(SkyCoord(x=-0.05486461, y=-0.87204803, z=-0.48633538, representation_type='cartesian'), 0.15 * u.degree, edgecolor='purple', facecolor='none', transform=ax.get_transform('fk5')) ax.coords[0].set_ticklabel_visible(False) ax.coords[1].set_ticklabel_visible(False) # Test to verify that SphericalCircle works irrespective of whether # the input(center) is a tuple or a SkyCoord object. assert (r1.get_xy() == r2.get_xy()).all() assert np.allclose(r1.get_xy(), r3.get_xy()) assert np.allclose(r2.get_xy()[0], [266.4, -29.25]) return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_quadrangle(self, tmpdir): # Test that Quadrangle can have curved edges while Rectangle does not wcs = WCS(self.msx_header) fig = plt.figure(figsize=(3, 3)) ax = fig.add_axes([0.25, 0.25, 0.5, 0.5], projection=wcs, aspect='equal') ax.set_xlim(0, 10000) ax.set_ylim(-10000, 0) # Add a quadrangle patch (100 degrees by 20 degrees) q = Quadrangle((255, -70)*u.deg, 100*u.deg, 20*u.deg, label='Quadrangle', edgecolor='blue', facecolor='none', transform=ax.get_transform('icrs')) ax.add_patch(q) # Add a rectangle patch (100 degrees by 20 degrees) r = Rectangle((255, -70), 100, 20, label='Rectangle', edgecolor='red', facecolor='none', linestyle='--', transform=ax.get_transform('icrs')) ax.add_patch(r) ax.coords[0].set_ticklabel_visible(False) ax.coords[1].set_ticklabel_visible(False) return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_elliptical_frame(self): # Regression test for a bug (astropy/astropy#6063) that caused labels to # be incorrectly simplified. wcs = WCS(self.msx_header) fig = plt.figure(figsize=(5, 3)) fig.add_axes([0.2, 0.2, 0.6, 0.6], projection=wcs, frame_class=EllipticalFrame) return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_hms_labels(self): # This tests the apparance of the hms superscripts in tick labels fig = plt.figure(figsize=(3, 3)) ax = fig.add_axes([0.3, 0.2, 0.65, 0.6], projection=WCS(self.twoMASS_k_header), aspect='equal') ax.set_xlim(-0.5, 0.5) ax.set_ylim(-0.5, 0.5) ax.coords[0].set_ticks(spacing=0.2 * 15 * u.arcsec) return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={'text.usetex': True}) def test_latex_labels(self): fig = plt.figure(figsize=(3, 3)) ax = fig.add_axes([0.3, 0.2, 0.65, 0.6], projection=WCS(self.twoMASS_k_header), aspect='equal') ax.set_xlim(-0.5, 0.5) ax.set_ylim(-0.5, 0.5) ax.coords[0].set_ticks(spacing=0.2 * 15 * u.arcsec) return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_tick_params(self): # This is a test to make sure that tick_params works correctly. We try # and test as much as possible with a single reference image. wcs = WCS() wcs.wcs.ctype = ['lon', 'lat'] fig = plt.figure(figsize=(6, 6)) # The first subplot tests: # - that plt.tick_params works # - that by default both axes are changed # - changing the tick direction and appearance, the label appearance and padding ax = fig.add_subplot(2, 2, 1, projection=wcs) plt.tick_params(direction='in', length=20, width=5, pad=6, labelsize=6, color='red', labelcolor='blue') ax.coords[0].set_auto_axislabel(False) ax.coords[1].set_auto_axislabel(False) # The second subplot tests: # - that specifying grid parameters doesn't actually cause the grid to # be shown (as expected) # - that axis= can be given integer coordinates or their string name # - that the tick positioning works (bottom/left/top/right) # Make sure that we can pass things that can index coords ax = fig.add_subplot(2, 2, 2, projection=wcs) plt.tick_params(axis=0, direction='in', length=20, width=5, pad=4, labelsize=6, color='red', labelcolor='blue', bottom=True, grid_color='purple') plt.tick_params(axis='lat', direction='out', labelsize=8, color='blue', labelcolor='purple', left=True, right=True, grid_color='red') ax.coords[0].set_auto_axislabel(False) ax.coords[1].set_auto_axislabel(False) # The third subplot tests: # - that ax.tick_params works # - that the grid has the correct settings once shown explicitly # - that we can use axis='x' and axis='y' ax = fig.add_subplot(2, 2, 3, projection=wcs) ax.tick_params(axis='x', direction='in', length=20, width=5, pad=20, labelsize=6, color='red', labelcolor='blue', bottom=True, grid_color='purple') ax.tick_params(axis='y', direction='out', labelsize=8, color='blue', labelcolor='purple', left=True, right=True, grid_color='red') plt.grid() ax.coords[0].set_auto_axislabel(False) ax.coords[1].set_auto_axislabel(False) # The final subplot tests: # - that we can use tick_params on a specific coordinate # - that the label positioning can be customized # - that the colors argument works # - that which='minor' works ax = fig.add_subplot(2, 2, 4, projection=wcs) ax.coords[0].tick_params(length=4, pad=2, colors='orange', labelbottom=True, labeltop=True, labelsize=10) ax.coords[1].display_minor_ticks(True) ax.coords[1].tick_params(which='minor', length=6) ax.coords[0].set_auto_axislabel(False) ax.coords[1].set_auto_axislabel(False) return fig @pytest.fixture def wave_wcs_1d(): wcs = WCS(naxis=1) wcs.wcs.ctype = ['WAVE'] wcs.wcs.cunit = ['m'] wcs.wcs.crpix = [1] wcs.wcs.cdelt = [5] wcs.wcs.crval = [45] wcs.wcs.set() return wcs @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_1d_plot_1d_wcs(wave_wcs_1d): fig = plt.figure() ax = fig.add_subplot(1, 1, 1, projection=wave_wcs_1d) lines, = ax.plot([10, 12, 14, 12, 10]) ax.set_xlabel("this is the x-axis") ax.set_ylabel("this is the y-axis") return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_1d_plot_1d_wcs_format_unit(wave_wcs_1d): """ This test ensures that the format unit is updated and displayed for both the axis ticks and default axis labels. """ fig = plt.figure() ax = fig.add_subplot(1, 1, 1, projection=wave_wcs_1d) lines, = ax.plot([10, 12, 14, 12, 10]) ax.coords[0].set_format_unit("nm") return fig @pytest.fixture def spatial_wcs_2d(): wcs = WCS(naxis=2) wcs.wcs.ctype = ['GLON-TAN', 'GLAT-TAN'] wcs.wcs.crpix = [3.0] * 2 wcs.wcs.cdelt = [15] * 2 wcs.wcs.crval = [50.0] * 2 wcs.wcs.set() return wcs @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_1d_plot_2d_wcs_correlated(spatial_wcs_2d): fig = plt.figure() ax = fig.add_subplot(1, 1, 1, projection=spatial_wcs_2d, slices=('x', 0)) lines, = ax.plot([10, 12, 14, 12, 10], '-o', color="orange") ax.coords['glon'].set_ticks(color="red") ax.coords['glon'].set_ticklabel(color="red") ax.coords['glon'].grid(color="red") ax.coords['glat'].set_ticks(color="blue") ax.coords['glat'].set_ticklabel(color="blue") ax.coords['glat'].grid(color="blue") return fig @pytest.fixture def spatial_wcs_2d_small_angle(): """ This WCS has an almost linear correlation between the pixel and world axes close to the reference pixel. """ wcs = WCS(naxis=2) wcs.wcs.ctype = ['HPLN-TAN', 'HPLT-TAN'] wcs.wcs.crpix = [3.0] * 2 wcs.wcs.cdelt = [10/3600, 5/3600] wcs.wcs.crval = [0] * 2 wcs.wcs.set() return wcs @pytest.mark.parametrize("slices, bottom_axis", [ # Remember SLLWCS takes slices in array order (np.s_[0, :], 'custom:pos.helioprojective.lon'), (np.s_[:, 0], 'custom:pos.helioprojective.lat')]) @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_1d_plot_1d_sliced_low_level_wcs(spatial_wcs_2d_small_angle, slices, bottom_axis): """ Test that a SLLWCS through a coupled 2D WCS plots as line OK. """ fig = plt.figure() ax = fig.add_subplot(1, 1, 1, projection=spatial_wcs_2d_small_angle[slices]) lines, = ax.plot([10, 12, 14, 12, 10], '-o', color="orange") # Draw to trigger rendering the ticks. plt.draw() assert ax.coords[bottom_axis].ticks.get_visible_axes() == ['b'] return fig @pytest.mark.parametrize("slices, bottom_axis", [ (('x', 0), 'hpln'), ((0, 'x'), 'hplt')]) @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_1d_plot_put_varying_axis_on_bottom_lon(spatial_wcs_2d_small_angle, slices, bottom_axis): """ When we plot a 1D slice through spatial axes, we want to put the axis which actually changes on the bottom. For example an aligned wcs, pixel grid where you plot a lon slice through a lat axis, you would end up with no ticks on the bottom as the lon doesn't change, and a set of lat ticks on the top because it does but it's the correlated axis not the actual one you are plotting against. """ fig = plt.figure() ax = fig.add_subplot(1, 1, 1, projection=spatial_wcs_2d_small_angle, slices=slices) lines, = ax.plot([10, 12, 14, 12, 10], '-o', color="orange") # Draw to trigger rendering the ticks. plt.draw() assert ax.coords[bottom_axis].ticks.get_visible_axes() == ['b'] return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_allsky_labels_wrap(): # Regression test for a bug that caused some tick labels to not be shown # when looking at all-sky maps in the case where coord_wrap < 360 fig = plt.figure(figsize=(4, 4)) icen = 0 for ctype in [('GLON-CAR', 'GLAT-CAR'), ('HGLN-CAR', 'HGLT-CAR')]: for cen in [0, 90, 180, 270]: icen += 1 wcs = WCS(naxis=2) wcs.wcs.ctype = ctype wcs.wcs.crval = cen, 0 wcs.wcs.crpix = 360.5, 180.5 wcs.wcs.cdelt = -0.5, 0.5 ax = fig.add_subplot(8, 1, icen, projection=wcs) ax.set_xlim(-0.5, 719.5) ax.coords[0].set_ticks(spacing=50 * u.deg) ax.coords[0].set_ticks_position('b') ax.coords[0].set_auto_axislabel(False) ax.coords[1].set_auto_axislabel(False) ax.coords[1].set_ticklabel_visible(False) ax.coords[1].set_ticks_visible(False) fig.subplots_adjust(hspace=2, left=0.05, right=0.95, bottom=0.1, top=0.95) return fig ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/tests/test_misc.py0000644000175100001710000004242000000000000024034 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import warnings from packaging.version import Version import pytest import numpy as np import matplotlib import matplotlib.pyplot as plt from matplotlib.contour import QuadContourSet from astropy import units as u from astropy.wcs import WCS from astropy.io import fits from astropy.coordinates import SkyCoord from astropy.utils.data import get_pkg_data_filename from astropy.wcs.wcsapi import SlicedLowLevelWCS, HighLevelWCSWrapper from astropy.visualization.wcsaxes.core import WCSAxes from astropy.visualization.wcsaxes.frame import ( EllipticalFrame, RectangularFrame, RectangularFrame1D) from astropy.visualization.wcsaxes.utils import get_coord_meta from astropy.visualization.wcsaxes.transforms import CurvedTransform ft_version = Version(matplotlib.ft2font.__freetype_version__) FREETYPE_261 = ft_version == Version("2.6.1") TEX_UNAVAILABLE = not matplotlib.checkdep_usetex(True) MATPLOTLIB_DEV = Version(matplotlib.__version__).is_devrelease def teardown_function(function): plt.close('all') def test_grid_regression(ignore_matplotlibrc): # Regression test for a bug that meant that if the rc parameter # axes.grid was set to True, WCSAxes would crash upon initialization. plt.rc('axes', grid=True) fig = plt.figure(figsize=(3, 3)) WCSAxes(fig, [0.1, 0.1, 0.8, 0.8]) def test_format_coord_regression(ignore_matplotlibrc, tmpdir): # Regression test for a bug that meant that if format_coord was called by # Matplotlib before the axes were drawn, an error occurred. fig = plt.figure(figsize=(3, 3)) ax = WCSAxes(fig, [0.1, 0.1, 0.8, 0.8]) fig.add_axes(ax) assert ax.format_coord(10, 10) == "" assert ax.coords[0].format_coord(10) == "" assert ax.coords[1].format_coord(10) == "" fig.savefig(tmpdir.join('nothing').strpath) assert ax.format_coord(10, 10) == "10.0 10.0 (world)" assert ax.coords[0].format_coord(10) == "10.0" assert ax.coords[1].format_coord(10) == "10.0" TARGET_HEADER = fits.Header.fromstring(""" NAXIS = 2 NAXIS1 = 200 NAXIS2 = 100 CTYPE1 = 'RA---MOL' CRPIX1 = 500 CRVAL1 = 180.0 CDELT1 = -0.4 CUNIT1 = 'deg ' CTYPE2 = 'DEC--MOL' CRPIX2 = 400 CRVAL2 = 0.0 CDELT2 = 0.4 CUNIT2 = 'deg ' COORDSYS= 'icrs ' """, sep='\n') @pytest.mark.parametrize('grid_type', ['lines', 'contours']) def test_no_numpy_warnings(ignore_matplotlibrc, tmpdir, grid_type): fig = plt.figure() ax = fig.add_subplot(1, 1, 1, projection=WCS(TARGET_HEADER)) ax.imshow(np.zeros((100, 200))) ax.coords.grid(color='white', grid_type=grid_type) # There should be no warnings raised if some pixels are outside WCS # (since this is normal). # BUT our own catch_warning was ignoring some warnings before, so now we # have to catch it. Otherwise, the pytest filterwarnings=error # setting in setup.cfg will fail this test. # There are actually multiple warnings but they are all similar. with warnings.catch_warnings(): warnings.filterwarnings('ignore', message=r'.*converting a masked element to nan.*') warnings.filterwarnings('ignore', message=r'.*No contour levels were found within the data range.*') warnings.filterwarnings('ignore', message=r'.*np\.asscalar\(a\) is deprecated since NumPy v1\.16.*') warnings.filterwarnings('ignore', message=r'.*PY_SSIZE_T_CLEAN will be required.*') fig.savefig(tmpdir.join('test.png').strpath) def test_invalid_frame_overlay(ignore_matplotlibrc): # Make sure a nice error is returned if a frame doesn't exist ax = plt.subplot(1, 1, 1, projection=WCS(TARGET_HEADER)) with pytest.raises(ValueError) as exc: ax.get_coords_overlay('banana') assert exc.value.args[0] == 'Frame banana not found' with pytest.raises(ValueError) as exc: get_coord_meta('banana') assert exc.value.args[0] == 'Unknown frame: banana' def test_plot_coord_transform(ignore_matplotlibrc): twoMASS_k_header = get_pkg_data_filename('data/2MASS_k_header') twoMASS_k_header = fits.Header.fromtextfile(twoMASS_k_header) fig = plt.figure(figsize=(6, 6)) ax = fig.add_axes([0.15, 0.15, 0.8, 0.8], projection=WCS(twoMASS_k_header), aspect='equal') ax.set_xlim(-0.5, 720.5) ax.set_ylim(-0.5, 720.5) c = SkyCoord(359.76045223*u.deg, 0.26876217*u.deg) with pytest.raises(TypeError): ax.plot_coord(c, 'o', transform=ax.get_transform('galactic')) def test_set_label_properties(ignore_matplotlibrc): # Regression test to make sure that arguments passed to # set_xlabel/set_ylabel are passed to the underlying coordinate helpers ax = plt.subplot(1, 1, 1, projection=WCS(TARGET_HEADER)) ax.set_xlabel('Test x label', labelpad=2, color='red') ax.set_ylabel('Test y label', labelpad=3, color='green') assert ax.coords[0].axislabels.get_text() == 'Test x label' assert ax.coords[0].axislabels.get_minpad('b') == 2 assert ax.coords[0].axislabels.get_color() == 'red' assert ax.coords[1].axislabels.get_text() == 'Test y label' assert ax.coords[1].axislabels.get_minpad('l') == 3 assert ax.coords[1].axislabels.get_color() == 'green' assert ax.get_xlabel() == 'Test x label' assert ax.get_ylabel() == 'Test y label' GAL_HEADER = fits.Header.fromstring(""" SIMPLE = T / conforms to FITS standard BITPIX = -32 / array data type NAXIS = 3 / number of array dimensions NAXIS1 = 31 NAXIS2 = 2881 NAXIS3 = 480 EXTEND = T CTYPE1 = 'DISTMOD ' CRVAL1 = 3.5 CDELT1 = 0.5 CRPIX1 = 1.0 CTYPE2 = 'GLON-CAR' CRVAL2 = 180.0 CDELT2 = -0.125 CRPIX2 = 1.0 CTYPE3 = 'GLAT-CAR' CRVAL3 = 0.0 CDELT3 = 0.125 CRPIX3 = 241.0 """, sep='\n') def test_slicing_warnings(ignore_matplotlibrc, tmpdir): # Regression test to make sure that no warnings are emitted by the tick # locator for the sliced axis when slicing a cube. # Scalar case wcs3d = WCS(naxis=3) wcs3d.wcs.ctype = ['x', 'y', 'z'] wcs3d.wcs.cunit = ['deg', 'deg', 'km/s'] wcs3d.wcs.crpix = [614.5, 856.5, 333] wcs3d.wcs.cdelt = [6.25, 6.25, 23] wcs3d.wcs.crval = [0., 0., 1.] with warnings.catch_warnings(): # https://github.com/astropy/astropy/issues/9690 warnings.filterwarnings('ignore', message=r'.*PY_SSIZE_T_CLEAN.*') plt.subplot(1, 1, 1, projection=wcs3d, slices=('x', 'y', 1)) plt.savefig(tmpdir.join('test.png').strpath) # Angle case wcs3d = WCS(GAL_HEADER) with warnings.catch_warnings(): # https://github.com/astropy/astropy/issues/9690 warnings.filterwarnings('ignore', message=r'.*PY_SSIZE_T_CLEAN.*') plt.subplot(1, 1, 1, projection=wcs3d, slices=('x', 'y', 2)) plt.savefig(tmpdir.join('test.png').strpath) def test_plt_xlabel_ylabel(tmpdir): # Regression test for a bug that happened when using plt.xlabel # and plt.ylabel with Matplotlib 3.0 plt.subplot(projection=WCS()) plt.xlabel('Galactic Longitude') plt.ylabel('Galactic Latitude') plt.savefig(tmpdir.join('test.png').strpath) def test_grid_type_contours_transform(tmpdir): # Regression test for a bug that caused grid_type='contours' to not work # with custom transforms class CustomTransform(CurvedTransform): # We deliberately don't define the inverse, and has_inverse should # default to False. def transform(self, values): return values * 1.3 transform = CustomTransform() coord_meta = {'type': ('scalar', 'scalar'), 'unit': (u.m, u.s), 'wrap': (None, None), 'name': ('x', 'y')} fig = plt.figure() ax = WCSAxes(fig, [0.1, 0.1, 0.8, 0.8], transform=transform, coord_meta=coord_meta) fig.add_axes(ax) ax.grid(grid_type='contours') fig.savefig(tmpdir.join('test.png').strpath) def test_plt_imshow_origin(): # Regression test for a bug that caused origin to be set to upper when # plt.imshow was called. ax = plt.subplot(projection=WCS()) plt.imshow(np.ones((2, 2))) assert ax.get_xlim() == (-0.5, 1.5) assert ax.get_ylim() == (-0.5, 1.5) def test_ax_imshow_origin(): # Regression test for a bug that caused origin to be set to upper when # ax.imshow was called with no origin ax = plt.subplot(projection=WCS()) ax.imshow(np.ones((2, 2))) assert ax.get_xlim() == (-0.5, 1.5) assert ax.get_ylim() == (-0.5, 1.5) def test_grid_contour_large_spacing(tmpdir): # Regression test for a bug that caused a crash when grid was called and # didn't produce grid lines (due e.g. to too large spacing) and was then # called again. filename = tmpdir.join('test.png').strpath ax = plt.subplot(projection=WCS()) ax.set_xlim(-0.5, 1.5) ax.set_ylim(-0.5, 1.5) ax.coords[0].set_ticks(values=[] * u.one) ax.coords[0].grid(grid_type='contours') plt.savefig(filename) ax.coords[0].grid(grid_type='contours') plt.savefig(filename) def test_contour_return(): # Regression test for a bug that caused contour and contourf to return None # instead of the contour object. fig = plt.figure() ax = WCSAxes(fig, [0.1, 0.1, 0.8, 0.8]) fig.add_axes(ax) cset = ax.contour(np.arange(16).reshape(4, 4), transform=ax.get_transform('world')) assert isinstance(cset, QuadContourSet) cset = ax.contourf(np.arange(16).reshape(4, 4), transform=ax.get_transform('world')) assert isinstance(cset, QuadContourSet) def test_contour_empty(): # Regression test for a bug that caused contour to crash if no contours # were present. fig = plt.figure() ax = WCSAxes(fig, [0.1, 0.1, 0.8, 0.8]) fig.add_axes(ax) with pytest.warns(UserWarning, match='No contour levels were found within the data range'): ax.contour(np.zeros((4, 4)), transform=ax.get_transform('world')) def test_iterate_coords(ignore_matplotlibrc, tmpdir): # Regression test for a bug that caused ax.coords to return too few axes wcs3d = WCS(naxis=3) wcs3d.wcs.ctype = ['x', 'y', 'z'] wcs3d.wcs.cunit = ['deg', 'deg', 'km/s'] wcs3d.wcs.crpix = [614.5, 856.5, 333] wcs3d.wcs.cdelt = [6.25, 6.25, 23] wcs3d.wcs.crval = [0., 0., 1.] ax = plt.subplot(1, 1, 1, projection=wcs3d, slices=('x', 'y', 1)) x, y, z = ax.coords def test_invalid_slices_errors(ignore_matplotlibrc): # Make sure that users get a clear message when specifying a WCS with # >2 dimensions without giving the 'slices' argument, or if the 'slices' # argument has too many/few elements. wcs3d = WCS(naxis=3) wcs3d.wcs.ctype = ['x', 'y', 'z'] plt.subplot(1, 1, 1, projection=wcs3d, slices=('x', 'y', 1)) with pytest.raises(ValueError) as exc: plt.subplot(1, 1, 1, projection=wcs3d) assert exc.value.args[0] == ("WCS has more than 2 pixel dimensions, so " "'slices' should be set") with pytest.raises(ValueError) as exc: plt.subplot(1, 1, 1, projection=wcs3d, slices=('x', 'y', 1, 2)) assert exc.value.args[0] == ("'slices' should have as many elements as " "WCS has pixel dimensions (should be 3)") wcs2d = WCS(naxis=2) wcs2d.wcs.ctype = ['x', 'y'] ax = plt.subplot(1, 1, 1, projection=wcs2d) assert ax.frame_class is RectangularFrame ax = plt.subplot(1, 1, 1, projection=wcs2d, slices=('x', 'y')) assert ax.frame_class is RectangularFrame ax = plt.subplot(1, 1, 1, projection=wcs2d, slices=('y', 'x')) assert ax.frame_class is RectangularFrame ax = plt.subplot(1, 1, 1, projection=wcs2d, slices=['x', 'y']) assert ax.frame_class is RectangularFrame ax = plt.subplot(1, 1, 1, projection=wcs2d, slices=(1, 'x')) assert ax.frame_class is RectangularFrame1D wcs1d = WCS(naxis=1) wcs1d.wcs.ctype = ['x'] ax = plt.subplot(1, 1, 1, projection=wcs1d) assert ax.frame_class is RectangularFrame1D with pytest.raises(ValueError): plt.subplot(1, 1, 1, projection=wcs2d, slices=(1, 'y')) EXPECTED_REPR_1 = """ """.strip() EXPECTED_REPR_2 = """ """.strip() def test_repr(ignore_matplotlibrc): # Unit test to make sure __repr__ looks as expected wcs3d = WCS(GAL_HEADER) # Cube header has world coordinates as distance, lon, lat, so start off # by slicing in a way that we select just lon,lat: ax = plt.subplot(1, 1, 1, projection=wcs3d, slices=(1, 'x', 'y')) assert repr(ax.coords) == EXPECTED_REPR_1 # Now slice in a way that all world coordinates are still present: ax = plt.subplot(1, 1, 1, projection=wcs3d, slices=('x', 'y', 1)) assert repr(ax.coords) == EXPECTED_REPR_2 @pytest.fixture def time_spectral_wcs_2d(): wcs = WCS(naxis=2) wcs.wcs.ctype = ['FREQ', 'TIME'] wcs.wcs.set() return wcs def test_time_wcs(time_spectral_wcs_2d): # Regression test for a bug that caused WCSAxes to error when using a WCS # with a time axis. plt.subplot(projection=time_spectral_wcs_2d) @pytest.mark.skipif('TEX_UNAVAILABLE') def test_simplify_labels_usetex(ignore_matplotlibrc, tmpdir): """Regression test for https://github.com/astropy/astropy/issues/8004.""" plt.rc('text', usetex=True) header = { 'NAXIS': 2, 'NAXIS1': 360, 'NAXIS2': 180, 'CRPIX1': 180.5, 'CRPIX2': 90.5, 'CRVAL1': 180.0, 'CRVAL2': 0.0, 'CDELT1': -2 * np.sqrt(2) / np.pi, 'CDELT2': 2 * np.sqrt(2) / np.pi, 'CTYPE1': 'RA---MOL', 'CTYPE2': 'DEC--MOL', 'RADESYS': 'ICRS'} wcs = WCS(header) fig, ax = plt.subplots( subplot_kw=dict(frame_class=EllipticalFrame, projection=wcs)) ax.set_xlim(-0.5, header['NAXIS1'] - 0.5) ax.set_ylim(-0.5, header['NAXIS2'] - 0.5) ax.coords[0].set_ticklabel(exclude_overlapping=True) ax.coords[1].set_ticklabel(exclude_overlapping=True) ax.coords[0].set_ticks(spacing=45 * u.deg) ax.coords[1].set_ticks(spacing=30 * u.deg) ax.grid() fig.savefig(tmpdir / 'plot.png') @pytest.mark.parametrize('frame_class', [RectangularFrame, EllipticalFrame]) def test_set_labels_with_coords(ignore_matplotlibrc, frame_class): """Test if ``axis.set_xlabel()`` calls the correct ``coords[i]_set_axislabel()`` in a WCS plot. Regression test for https://github.com/astropy/astropy/issues/10435. """ labels = ['RA', 'Declination'] header = { 'NAXIS': 2, 'NAXIS1': 360, 'NAXIS2': 180, 'CRPIX1': 180.5, 'CRPIX2': 90.5, 'CRVAL1': 180.0, 'CRVAL2': 0.0, 'CDELT1': -2 * np.sqrt(2) / np.pi, 'CDELT2': 2 * np.sqrt(2) / np.pi, 'CTYPE1': 'RA---AIT', 'CTYPE2': 'DEC--AIT'} wcs = WCS(header) fig, ax = plt.subplots( subplot_kw=dict(frame_class=frame_class, projection=wcs)) ax.set_xlabel(labels[0]) ax.set_ylabel(labels[1]) assert ax.get_xlabel() == labels[0] assert ax.get_ylabel() == labels[1] for i in range(2): assert ax.coords[i].get_axislabel() == labels[i] @pytest.mark.parametrize('atol', [0.2, 1.0e-8]) def test_bbox_size(atol): # Test for the size of a WCSAxes bbox (only have Matplotlib >= 3.0 now) extents = [11.38888888888889, 3.5, 576.0, 432.0] fig = plt.figure() ax = WCSAxes(fig, [0.1, 0.1, 0.8, 0.8]) fig.add_axes(ax) fig.canvas.draw() renderer = fig.canvas.renderer ax_bbox = ax.get_tightbbox(renderer) # Enforce strict test only with reference Freetype version if atol < 0.1 and not FREETYPE_261: pytest.xfail("Exact BoundingBox dimensions are only ensured with FreeType 2.6.1") assert np.allclose(ax_bbox.extents, extents, atol=atol) def test_wcs_type_transform_regression(): wcs = WCS(TARGET_HEADER) sliced_wcs = SlicedLowLevelWCS(wcs, np.s_[1:-1, 1:-1]) ax = plt.subplot(1, 1, 1, projection=wcs) ax.get_transform(sliced_wcs) high_wcs = HighLevelWCSWrapper(sliced_wcs) ax.get_transform(sliced_wcs) def test_multiple_draws_grid_contours(tmpdir): fig = plt.figure() ax = fig.add_subplot(1, 1, 1, projection=WCS()) ax.grid(color='black', grid_type='contours') fig.savefig(tmpdir / 'plot.png') fig.savefig(tmpdir / 'plot.png') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/tests/test_transform_coord_meta.py0000644000175100001710000001212300000000000027305 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import pytest import numpy as np import matplotlib.pyplot as plt from astropy import units as u from astropy.wcs import WCS from astropy.visualization.wcsaxes import WCSAxes from .test_images import BaseImageTests from astropy.visualization.wcsaxes.transforms import CurvedTransform from astropy.tests.image_tests import IMAGE_REFERENCE_DIR # Create fake transforms that roughly mimic a polar projection class DistanceToLonLat(CurvedTransform): has_inverse = True def __init__(self, R=6e3): super().__init__() self.R = R def transform(self, xy): x, y = xy[:, 0], xy[:, 1] lam = np.degrees(np.arctan2(y, x)) phi = 90. - np.degrees(np.hypot(x, y) / self.R) return np.array((lam, phi)).transpose() transform_non_affine = transform def inverted(self): return LonLatToDistance(R=self.R) class LonLatToDistance(CurvedTransform): def __init__(self, R=6e3): super().__init__() self.R = R def transform(self, lamphi): lam, phi = lamphi[:, 0], lamphi[:, 1] r = np.radians(90 - phi) * self.R x = r * np.cos(np.radians(lam)) y = r * np.sin(np.radians(lam)) return np.array((x, y)).transpose() transform_non_affine = transform def inverted(self): return DistanceToLonLat(R=self.R) class TestTransformCoordMeta(BaseImageTests): @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_coords_overlay(self): # Set up a simple WCS that maps pixels to non-projected distances wcs = WCS(naxis=2) wcs.wcs.ctype = ['x', 'y'] wcs.wcs.cunit = ['km', 'km'] wcs.wcs.crpix = [614.5, 856.5] wcs.wcs.cdelt = [6.25, 6.25] wcs.wcs.crval = [0., 0.] fig = plt.figure(figsize=(4, 4)) ax = WCSAxes(fig, [0.15, 0.15, 0.7, 0.7], wcs=wcs) fig.add_axes(ax) s = DistanceToLonLat(R=6378.273) ax.coords['x'].set_ticklabel_position('') ax.coords['y'].set_ticklabel_position('') coord_meta = {} coord_meta['type'] = ('longitude', 'latitude') coord_meta['wrap'] = (360., None) coord_meta['unit'] = (u.deg, u.deg) coord_meta['name'] = 'lon', 'lat' overlay = ax.get_coords_overlay(s, coord_meta=coord_meta) overlay.grid(color='red') overlay['lon'].grid(color='red', linestyle='solid', alpha=0.3) overlay['lat'].grid(color='blue', linestyle='solid', alpha=0.3) overlay['lon'].set_ticklabel(size=7, exclude_overlapping=True) overlay['lat'].set_ticklabel(size=7, exclude_overlapping=True) overlay['lon'].set_ticklabel_position('brtl') overlay['lat'].set_ticklabel_position('brtl') overlay['lon'].set_ticks(spacing=10. * u.deg) overlay['lat'].set_ticks(spacing=10. * u.deg) ax.set_xlim(-0.5, 1215.5) ax.set_ylim(-0.5, 1791.5) return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_coords_overlay_auto_coord_meta(self): fig = plt.figure(figsize=(4, 4)) ax = WCSAxes(fig, [0.15, 0.15, 0.7, 0.7], wcs=WCS(self.msx_header)) fig.add_axes(ax) ax.grid(color='red', alpha=0.5, linestyle='solid') overlay = ax.get_coords_overlay('fk5') # automatically sets coord_meta overlay.grid(color='black', alpha=0.5, linestyle='solid') overlay['ra'].set_ticks(color='black') overlay['dec'].set_ticks(color='black') ax.set_xlim(-0.5, 148.5) ax.set_ylim(-0.5, 148.5) return fig @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_direct_init(self): s = DistanceToLonLat(R=6378.273) coord_meta = {} coord_meta['type'] = ('longitude', 'latitude') coord_meta['wrap'] = (360., None) coord_meta['unit'] = (u.deg, u.deg) coord_meta['name'] = 'lon', 'lat' fig = plt.figure(figsize=(4, 4)) ax = WCSAxes(fig, [0.15, 0.15, 0.7, 0.7], transform=s, coord_meta=coord_meta) fig.add_axes(ax) ax.coords['lon'].grid(color='red', linestyle='solid', alpha=0.3) ax.coords['lat'].grid(color='blue', linestyle='solid', alpha=0.3) ax.coords['lon'].set_auto_axislabel(False) ax.coords['lat'].set_auto_axislabel(False) ax.coords['lon'].set_ticklabel(size=7, exclude_overlapping=True) ax.coords['lat'].set_ticklabel(size=7, exclude_overlapping=True) ax.coords['lon'].set_ticklabel_position('brtl') ax.coords['lat'].set_ticklabel_position('brtl') ax.coords['lon'].set_ticks(spacing=10. * u.deg) ax.coords['lat'].set_ticks(spacing=10. * u.deg) ax.set_xlim(-400., 500.) ax.set_ylim(-300., 400.) return fig ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/tests/test_transforms.py0000644000175100001710000000010000000000000025264 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/tests/test_utils.py0000644000175100001710000000700100000000000024235 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst from numpy.testing import assert_almost_equal from astropy import units as u from astropy.visualization.wcsaxes.utils import select_step_degree, select_step_hour, select_step_scalar from astropy.tests.helper import (assert_quantity_allclose as assert_almost_equal_quantity) def test_select_step_degree(): assert_almost_equal_quantity(select_step_degree(127 * u.deg), 180. * u.deg) assert_almost_equal_quantity(select_step_degree(44 * u.deg), 45. * u.deg) assert_almost_equal_quantity(select_step_degree(18 * u.arcmin), 15 * u.arcmin) assert_almost_equal_quantity(select_step_degree(3.4 * u.arcmin), 3 * u.arcmin) assert_almost_equal_quantity(select_step_degree(2 * u.arcmin), 2 * u.arcmin) assert_almost_equal_quantity(select_step_degree(59 * u.arcsec), 1 * u.arcmin) assert_almost_equal_quantity(select_step_degree(33 * u.arcsec), 30 * u.arcsec) assert_almost_equal_quantity(select_step_degree(2.2 * u.arcsec), 2 * u.arcsec) assert_almost_equal_quantity(select_step_degree(0.8 * u.arcsec), 1 * u.arcsec) assert_almost_equal_quantity(select_step_degree(0.2 * u.arcsec), 0.2 * u.arcsec) assert_almost_equal_quantity(select_step_degree(0.11 * u.arcsec), 0.1 * u.arcsec) assert_almost_equal_quantity(select_step_degree(0.022 * u.arcsec), 0.02 * u.arcsec) assert_almost_equal_quantity(select_step_degree(0.0043 * u.arcsec), 0.005 * u.arcsec) assert_almost_equal_quantity(select_step_degree(0.00083 * u.arcsec), 0.001 * u.arcsec) assert_almost_equal_quantity(select_step_degree(0.000027 * u.arcsec), 0.00002 * u.arcsec) def test_select_step_hour(): assert_almost_equal_quantity(select_step_hour(127 * u.deg), 8. * u.hourangle) assert_almost_equal_quantity(select_step_hour(44 * u.deg), 3. * u.hourangle) assert_almost_equal_quantity(select_step_hour(18 * u.arcmin), 15 * u.arcmin) assert_almost_equal_quantity(select_step_hour(3.4 * u.arcmin), 3 * u.arcmin) assert_almost_equal_quantity(select_step_hour(2 * u.arcmin), 1.5 * u.arcmin) assert_almost_equal_quantity(select_step_hour(59 * u.arcsec), 1 * u.arcmin) assert_almost_equal_quantity(select_step_hour(33 * u.arcsec), 30 * u.arcsec) assert_almost_equal_quantity(select_step_hour(2.2 * u.arcsec), 3. * u.arcsec) assert_almost_equal_quantity(select_step_hour(0.8 * u.arcsec), 0.75 * u.arcsec) assert_almost_equal_quantity(select_step_hour(0.2 * u.arcsec), 0.15 * u.arcsec) assert_almost_equal_quantity(select_step_hour(0.11 * u.arcsec), 0.15 * u.arcsec) assert_almost_equal_quantity(select_step_hour(0.022 * u.arcsec), 0.03 * u.arcsec) assert_almost_equal_quantity(select_step_hour(0.0043 * u.arcsec), 0.003 * u.arcsec) assert_almost_equal_quantity(select_step_hour(0.00083 * u.arcsec), 0.00075 * u.arcsec) assert_almost_equal_quantity(select_step_hour(0.000027 * u.arcsec), 0.00003 * u.arcsec) def test_select_step_scalar(): assert_almost_equal(select_step_scalar(33122.), 50000.) assert_almost_equal(select_step_scalar(433.), 500.) assert_almost_equal(select_step_scalar(12.3), 10) assert_almost_equal(select_step_scalar(3.3), 5.) assert_almost_equal(select_step_scalar(0.66), 0.5) assert_almost_equal(select_step_scalar(0.0877), 0.1) assert_almost_equal(select_step_scalar(0.00577), 0.005) assert_almost_equal(select_step_scalar(0.00022), 0.0002) assert_almost_equal(select_step_scalar(0.000012), 0.00001) assert_almost_equal(select_step_scalar(0.000000443), 0.0000005) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/tests/test_wcsapi.py0000644000175100001710000004274600000000000024402 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import os import warnings from textwrap import dedent import pytest import numpy as np import matplotlib.pyplot as plt from matplotlib.transforms import Affine2D, IdentityTransform from astropy.io import fits from astropy import units as u from astropy.wcs.wcsapi import BaseLowLevelWCS, SlicedLowLevelWCS from astropy.coordinates import SkyCoord from astropy.time import Time from astropy.units import Quantity from astropy.tests.image_tests import IMAGE_REFERENCE_DIR from astropy.utils.data import get_pkg_data_filename from astropy.wcs import WCS from astropy.visualization.wcsaxes.frame import RectangularFrame, RectangularFrame1D from astropy.visualization.wcsaxes.wcsapi import (WCSWorld2PixelTransform, transform_coord_meta_from_wcs, apply_slices) @pytest.fixture def plt_close(): yield plt.close('all') WCS2D = WCS(naxis=2) WCS2D.wcs.ctype = ['x', 'y'] WCS2D.wcs.cunit = ['km', 'km'] WCS2D.wcs.crpix = [614.5, 856.5] WCS2D.wcs.cdelt = [6.25, 6.25] WCS2D.wcs.crval = [0., 0.] WCS3D = WCS(naxis=3) WCS3D.wcs.ctype = ['x', 'y', 'z'] WCS3D.wcs.cunit = ['km', 'km', 'km'] WCS3D.wcs.crpix = [614.5, 856.5, 333] WCS3D.wcs.cdelt = [6.25, 6.25, 23] WCS3D.wcs.crval = [0., 0., 1.] @pytest.fixture def wcs_4d(): header = dedent("""\ WCSAXES = 4 / Number of coordinate axes CRPIX1 = 0.0 / Pixel coordinate of reference point CRPIX2 = 0.0 / Pixel coordinate of reference point CRPIX3 = 0.0 / Pixel coordinate of reference point CRPIX4 = 5.0 / Pixel coordinate of reference point CDELT1 = 0.4 / [min] Coordinate increment at reference point CDELT2 = 2E-11 / [m] Coordinate increment at reference point CDELT3 = 0.0027777777777778 / [deg] Coordinate increment at reference point CDELT4 = 0.0013888888888889 / [deg] Coordinate increment at reference point CUNIT1 = 'min' / Units of coordinate increment and value CUNIT2 = 'm' / Units of coordinate increment and value CUNIT3 = 'deg' / Units of coordinate increment and value CUNIT4 = 'deg' / Units of coordinate increment and value CTYPE1 = 'TIME' / Coordinate type code CTYPE2 = 'WAVE' / Vacuum wavelength (linear) CTYPE3 = 'HPLT-TAN' / Coordinate type codegnomonic projection CTYPE4 = 'HPLN-TAN' / Coordinate type codegnomonic projection CRVAL1 = 0.0 / [min] Coordinate value at reference point CRVAL2 = 0.0 / [m] Coordinate value at reference point CRVAL3 = 0.0 / [deg] Coordinate value at reference point CRVAL4 = 0.0 / [deg] Coordinate value at reference point LONPOLE = 180.0 / [deg] Native longitude of celestial pole LATPOLE = 0.0 / [deg] Native latitude of celestial pole """) return WCS(header=fits.Header.fromstring(header, sep='\n')) @pytest.fixture def cube_wcs(): cube_header = get_pkg_data_filename('data/cube_header') header = fits.Header.fromtextfile(cube_header) return WCS(header=header) def test_shorthand_inversion(): """ Test that the Matplotlib subtraction shorthand for composing and inverting transformations works. """ w1 = WCS(naxis=2) w1.wcs.ctype = ['RA---TAN', 'DEC--TAN'] w1.wcs.crpix = [256.0, 256.0] w1.wcs.cdelt = [-0.05, 0.05] w1.wcs.crval = [120.0, -19.0] w2 = WCS(naxis=2) w2.wcs.ctype = ['RA---SIN', 'DEC--SIN'] w2.wcs.crpix = [256.0, 256.0] w2.wcs.cdelt = [-0.05, 0.05] w2.wcs.crval = [235.0, +23.7] t1 = WCSWorld2PixelTransform(w1) t2 = WCSWorld2PixelTransform(w2) assert t1 - t2 == t1 + t2.inverted() assert t1 - t2 != t2.inverted() + t1 assert t1 - t1 == IdentityTransform() # We add Affine2D to catch the fact that in Matplotlib, having a Composite # transform can end up in more strict requirements for the dimensionality. def test_2d(): world = np.ones((10, 2)) w1 = WCSWorld2PixelTransform(WCS2D) + Affine2D() pixel = w1.transform(world) world_2 = w1.inverted().transform(pixel) np.testing.assert_allclose(world, world_2) def test_3d(): world = np.ones((10, 2)) w1 = WCSWorld2PixelTransform(WCS3D[:, 0, :]) + Affine2D() pixel = w1.transform(world) world_2 = w1.inverted().transform(pixel) np.testing.assert_allclose(world[:, 0], world_2[:, 0]) np.testing.assert_allclose(world[:, 1], world_2[:, 1]) def test_coord_type_from_ctype(cube_wcs): _, coord_meta = transform_coord_meta_from_wcs(cube_wcs, RectangularFrame, slices=(50, 'y', 'x')) axislabel_position = coord_meta['default_axislabel_position'] ticklabel_position = coord_meta['default_ticklabel_position'] ticks_position = coord_meta['default_ticks_position'] # These axes are swapped due to the pixel derivatives assert axislabel_position == ['l', 'r', 'b'] assert ticklabel_position == ['l', 'r', 'b'] assert ticks_position == ['l', 'r', 'b'] wcs = WCS(naxis=2) wcs.wcs.ctype = ['GLON-TAN', 'GLAT-TAN'] wcs.wcs.crpix = [256.0] * 2 wcs.wcs.cdelt = [-0.05] * 2 wcs.wcs.crval = [50.0] * 2 wcs.wcs.cname = ['Longitude', ''] wcs.wcs.set() _, coord_meta = transform_coord_meta_from_wcs(wcs, RectangularFrame) assert coord_meta['type'] == ['longitude', 'latitude'] assert coord_meta['format_unit'] == [u.deg, u.deg] assert coord_meta['wrap'] == [None, None] assert coord_meta['default_axis_label'] == ['Longitude', 'pos.galactic.lat'] assert coord_meta['name'] == [('pos.galactic.lon', 'glon-tan', 'glon', 'Longitude'), ('pos.galactic.lat', 'glat-tan', 'glat')] wcs = WCS(naxis=2) wcs.wcs.ctype = ['HPLN-TAN', 'HPLT-TAN'] wcs.wcs.crpix = [256.0] * 2 wcs.wcs.cdelt = [-0.05] * 2 wcs.wcs.crval = [50.0] * 2 wcs.wcs.set() _, coord_meta = transform_coord_meta_from_wcs(wcs, RectangularFrame) assert coord_meta['type'] == ['longitude', 'latitude'] assert coord_meta['format_unit'] == [u.arcsec, u.arcsec] assert coord_meta['wrap'] == [180., None] _, coord_meta = transform_coord_meta_from_wcs(wcs, RectangularFrame, slices=('y', 'x')) axislabel_position = coord_meta['default_axislabel_position'] ticklabel_position = coord_meta['default_ticklabel_position'] ticks_position = coord_meta['default_ticks_position'] # These axes should be swapped because of slices assert axislabel_position == ['l', 'b'] assert ticklabel_position == ['l', 'b'] assert ticks_position == ['bltr', 'bltr'] wcs = WCS(naxis=2) wcs.wcs.ctype = ['HGLN-TAN', 'HGLT-TAN'] wcs.wcs.crpix = [256.0] * 2 wcs.wcs.cdelt = [-0.05] * 2 wcs.wcs.crval = [50.0] * 2 wcs.wcs.set() _, coord_meta = transform_coord_meta_from_wcs(wcs, RectangularFrame) assert coord_meta['type'] == ['longitude', 'latitude'] assert coord_meta['format_unit'] == [u.deg, u.deg] assert coord_meta['wrap'] == [180., None] wcs = WCS(naxis=2) wcs.wcs.ctype = ['CRLN-TAN', 'CRLT-TAN'] wcs.wcs.crpix = [256.0] * 2 wcs.wcs.cdelt = [-0.05] * 2 wcs.wcs.crval = [50.0] * 2 wcs.wcs.set() _, coord_meta = transform_coord_meta_from_wcs(wcs, RectangularFrame) assert coord_meta['type'] == ['longitude', 'latitude'] assert coord_meta['format_unit'] == [u.deg, u.deg] assert coord_meta['wrap'] == [360., None] wcs = WCS(naxis=2) wcs.wcs.ctype = ['RA---TAN', 'DEC--TAN'] wcs.wcs.crpix = [256.0] * 2 wcs.wcs.cdelt = [-0.05] * 2 wcs.wcs.crval = [50.0] * 2 wcs.wcs.set() _, coord_meta = transform_coord_meta_from_wcs(wcs, RectangularFrame) assert coord_meta['type'] == ['longitude', 'latitude'] assert coord_meta['format_unit'] == [u.hourangle, u.deg] assert coord_meta['wrap'] == [None, None] wcs = WCS(naxis=2) wcs.wcs.ctype = ['spam', 'spam'] wcs.wcs.crpix = [256.0] * 2 wcs.wcs.cdelt = [-0.05] * 2 wcs.wcs.crval = [50.0] * 2 wcs.wcs.set() _, coord_meta = transform_coord_meta_from_wcs(wcs, RectangularFrame) assert coord_meta['type'] == ['scalar', 'scalar'] assert coord_meta['format_unit'] == [u.one, u.one] assert coord_meta['wrap'] == [None, None] def test_coord_type_1d_1d_wcs(): wcs = WCS(naxis=1) wcs.wcs.ctype = ['WAVE'] wcs.wcs.crpix = [256.0] wcs.wcs.cdelt = [-0.05] wcs.wcs.crval = [50.0] wcs.wcs.set() _, coord_meta = transform_coord_meta_from_wcs(wcs, RectangularFrame1D) assert coord_meta['type'] == ['scalar'] assert coord_meta['format_unit'] == [u.m] assert coord_meta['wrap'] == [None] def test_coord_type_1d_2d_wcs_correlated(): wcs = WCS(naxis=2) wcs.wcs.ctype = ['GLON-TAN', 'GLAT-TAN'] wcs.wcs.crpix = [256.0] * 2 wcs.wcs.cdelt = [-0.05] * 2 wcs.wcs.crval = [50.0] * 2 wcs.wcs.set() _, coord_meta = transform_coord_meta_from_wcs(wcs, RectangularFrame1D, slices=('x', 0)) assert coord_meta['type'] == ['longitude', 'latitude'] assert coord_meta['format_unit'] == [u.deg, u.deg] assert coord_meta['wrap'] == [None, None] assert coord_meta['visible'] == [True, True] def test_coord_type_1d_2d_wcs_uncorrelated(): wcs = WCS(naxis=2) wcs.wcs.ctype = ['WAVE', 'UTC'] wcs.wcs.crpix = [256.0] * 2 wcs.wcs.cdelt = [-0.05] * 2 wcs.wcs.crval = [50.0] * 2 wcs.wcs.cunit = ['nm', 's'] wcs.wcs.set() _, coord_meta = transform_coord_meta_from_wcs(wcs, RectangularFrame1D, slices=('x', 0)) assert coord_meta['type'] == ['scalar', 'scalar'] assert coord_meta['format_unit'] == [u.m, u.s] assert coord_meta['wrap'] == [None, None] assert coord_meta['visible'] == [True, False] def test_coord_meta_4d(wcs_4d): _, coord_meta = transform_coord_meta_from_wcs(wcs_4d, RectangularFrame, slices=(0, 0, 'x', 'y')) axislabel_position = coord_meta['default_axislabel_position'] ticklabel_position = coord_meta['default_ticklabel_position'] ticks_position = coord_meta['default_ticks_position'] assert axislabel_position == ['', '', 'b', 'l'] assert ticklabel_position == ['', '', 'b', 'l'] assert ticks_position == ['', '', 'bltr', 'bltr'] def test_coord_meta_4d_line_plot(wcs_4d): _, coord_meta = transform_coord_meta_from_wcs(wcs_4d, RectangularFrame1D, slices=(0, 0, 0, 'x')) axislabel_position = coord_meta['default_axislabel_position'] ticklabel_position = coord_meta['default_ticklabel_position'] ticks_position = coord_meta['default_ticks_position'] # These axes are swapped due to the pixel derivatives assert axislabel_position == ['', '', 't', 'b'] assert ticklabel_position == ['', '', 't', 'b'] assert ticks_position == ['', '', 't', 'b'] @pytest.fixture def sub_wcs(wcs_4d, wcs_slice): return SlicedLowLevelWCS(wcs_4d, wcs_slice) @pytest.mark.parametrize(("wcs_slice", "wcsaxes_slices", "world_map", "ndim"), [ (np.s_[...], [0,0,'x','y'], (2, 3), 2), (np.s_[...], [0,'x',0,'y'], (1, 2, 3), 3), (np.s_[...], ['x',0,0,'y'], (0, 2, 3), 3), (np.s_[...], ['x','y',0,0], (0, 1), 2), (np.s_[:,:,0,:], [0, 'x', 'y'], (1, 2), 2), (np.s_[:,:,0,:], ['x', 0, 'y'], (0, 1, 2), 3), (np.s_[:,:,0,:], ['x', 'y', 0], (0, 1, 2), 3), (np.s_[:,0,:,:], ['x', 'y', 0], (0, 1), 2), ]) def test_apply_slices(sub_wcs, wcs_slice, wcsaxes_slices, world_map, ndim): transform_wcs, _, out_world_map = apply_slices(sub_wcs, wcsaxes_slices) assert transform_wcs.world_n_dim == ndim assert out_world_map == world_map # parametrize here to pass to the fixture @pytest.mark.parametrize("wcs_slice", [np.s_[:,:,0,:]]) def test_sliced_ND_input(wcs_4d, sub_wcs, wcs_slice, plt_close): slices_wcsaxes = [0, 'x', 'y'] for sub_wcs in (sub_wcs, SlicedLowLevelWCS(wcs_4d, wcs_slice)): with warnings.catch_warnings(): warnings.filterwarnings('ignore', category=FutureWarning) _, coord_meta = transform_coord_meta_from_wcs(sub_wcs, RectangularFrame, slices=slices_wcsaxes) assert all(len(x) == 3 for x in coord_meta.values()) assert coord_meta['name'] == ['time', ('custom:pos.helioprojective.lat', 'hplt-tan', 'hplt'), ('custom:pos.helioprojective.lon', 'hpln-tan', 'hpln')] assert coord_meta['type'] == ['scalar', 'latitude', 'longitude'] assert coord_meta['wrap'] == [None, None, 180.0] assert coord_meta['unit'] == [u.Unit("min"), u.Unit("deg"), u.Unit("deg")] assert coord_meta['visible'] == [False, True, True] assert coord_meta['format_unit'] == [u.Unit("min"), u.Unit("arcsec"), u.Unit("arcsec")] assert coord_meta['default_axislabel_position'] == ['', 'b', 'l'] assert coord_meta['default_ticklabel_position'] == ['', 'b', 'l'] assert coord_meta['default_ticks_position'] == ['', 'bltr', 'bltr'] # Validate the axes initialize correctly plt.subplot(projection=sub_wcs, slices=slices_wcsaxes) class LowLevelWCS5D(BaseLowLevelWCS): pixel_dim = 2 @property def pixel_n_dim(self): return self.pixel_dim @property def world_n_dim(self): return 5 @property def world_axis_physical_types(self): return ['em.freq', 'time', 'pos.eq.ra', 'pos.eq.dec', 'phys.polarization.stokes'] @property def world_axis_units(self): return ['Hz', 'day', 'deg', 'deg', ''] @property def world_axis_names(self): return ['Frequency', '', 'RA', 'DEC', ''] def pixel_to_world_values(self, *pixel_arrays): pixel_arrays = (list(pixel_arrays) * 3)[:-1] # make list have 5 elements return [np.asarray(pix) * scale for pix, scale in zip(pixel_arrays, [10, 0.2, 0.4, 0.39, 2])] def world_to_pixel_values(self, *world_arrays): world_arrays = world_arrays[:2] # make list have 2 elements return [np.asarray(world) / scale for world, scale in zip(world_arrays, [10, 0.2])] @property def world_axis_object_components(self): return [('freq', 0, 'value'), ('time', 0, 'mjd'), ('celestial', 0, 'spherical.lon.degree'), ('celestial', 1, 'spherical.lat.degree'), ('stokes', 0, 'value')] @property def world_axis_object_classes(self): return {'celestial': (SkyCoord, (), {'unit': 'deg'}), 'time': (Time, (), {'format': 'mjd'}), 'freq': (Quantity, (), {'unit': 'Hz'}), 'stokes': (Quantity, (), {'unit': 'one'})} def test_edge_axes(): # Check that axes on the edge of a spherical projection are shown properley # (see https://github.com/astropy/astropy/issues/10441) shape = [180, 360] data = np.random.rand(*shape) header = {'wcsaxes': 2, 'crpix1': 180.5, 'crpix2': 90.5, 'cdelt1': 1.0, 'cdelt2': 1.0, 'cunit1': 'deg', 'cunit2': 'deg', 'ctype1': 'CRLN-CAR', 'ctype2': 'CRLT-CAR', 'crval1': 0.0, 'crval2': 0.0, 'lonpole': 0.0, 'latpole': 90.0, } wcs = WCS(header) fig = plt.figure() ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], projection=wcs) ax.imshow(data, origin='lower') # By default the x- and y- axes should be drawn lon = ax.coords[0] lat = ax.coords[1] fig.canvas.draw() np.testing.assert_equal(lon.ticks.world['b'], np.array([90.0, 180.0, 180.0, 270.0, 0.0])) np.testing.assert_equal(lat.ticks.world['l'], np.array([-90.0, -60.0, -30.0, 0.0, 30.0, 60.0, 90.0])) def test_coord_meta_wcsapi(): wcs = LowLevelWCS5D() wcs.pixel_dim = 5 _, coord_meta = transform_coord_meta_from_wcs(wcs, RectangularFrame, slices=[0, 0, 'x', 'y', 0]) assert coord_meta['name'] == [('em.freq', 'Frequency'), 'time', ('pos.eq.ra', 'RA'), ('pos.eq.dec', 'DEC'), 'phys.polarization.stokes'] assert coord_meta['type'] == ['scalar', 'scalar', 'longitude', 'latitude', 'scalar'] assert coord_meta['wrap'] == [None, None, None, None, None] assert coord_meta['unit'] == [u.Unit("Hz"), u.Unit("d"), u.Unit("deg"), u.Unit("deg"), u.one] assert coord_meta['visible'] == [True, True, True, True, True] assert coord_meta['format_unit'] == [u.Unit("Hz"), u.Unit("d"), u.Unit("hourangle"), u.Unit("deg"), u.one] assert coord_meta['default_axislabel_position'] == ['b', 'l', 't', 'r', ''] assert coord_meta['default_ticklabel_position'] == ['b', 'l', 't', 'r', ''] assert coord_meta['default_ticks_position'] == ['b', 'l', 't', 'r', ''] assert coord_meta['default_axis_label'] == ['Frequency', 'time', 'RA', 'DEC', 'phys.polarization.stokes'] @pytest.mark.remote_data(source='astropy') @pytest.mark.mpl_image_compare(baseline_dir=IMAGE_REFERENCE_DIR, tolerance=0, style={}) def test_wcsapi_5d_with_names(plt_close): # Test for plotting image and also setting values of ticks fig = plt.figure(figsize=(6, 6)) ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], projection=LowLevelWCS5D()) ax.set_xlim(-0.5, 148.5) ax.set_ylim(-0.5, 148.5) return fig ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/ticklabels.py0000644000175100001710000002314000000000000023013 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import numpy as np from matplotlib import rcParams from matplotlib.text import Text from .frame import RectangularFrame def sort_using(X, Y): return [x for (y, x) in sorted(zip(Y, X))] class TickLabels(Text): def __init__(self, frame, *args, **kwargs): self.clear() self._frame = frame super().__init__(*args, **kwargs) self.set_clip_on(True) self.set_visible_axes('all') self.set_pad(rcParams['xtick.major.pad']) self._exclude_overlapping = False # Stale if either xy positions haven't been calculated, or if # something changes that requires recomputing the positions self._stale = True # Check rcParams if 'color' not in kwargs: self.set_color(rcParams['xtick.color']) if 'size' not in kwargs: self.set_size(rcParams['xtick.labelsize']) def clear(self): self.world = {} self.pixel = {} self.angle = {} self.text = {} self.disp = {} def add(self, axis, world, pixel, angle, text, axis_displacement): if axis not in self.world: self.world[axis] = [world] self.pixel[axis] = [pixel] self.angle[axis] = [angle] self.text[axis] = [text] self.disp[axis] = [axis_displacement] else: self.world[axis].append(world) self.pixel[axis].append(pixel) self.angle[axis].append(angle) self.text[axis].append(text) self.disp[axis].append(axis_displacement) self._stale = True def sort(self): """ Sort by axis displacement, which allows us to figure out which parts of labels to not repeat. """ for axis in self.world: self.world[axis] = sort_using(self.world[axis], self.disp[axis]) self.pixel[axis] = sort_using(self.pixel[axis], self.disp[axis]) self.angle[axis] = sort_using(self.angle[axis], self.disp[axis]) self.text[axis] = sort_using(self.text[axis], self.disp[axis]) self.disp[axis] = sort_using(self.disp[axis], self.disp[axis]) self._stale = True def simplify_labels(self): """ Figure out which parts of labels can be dropped to avoid repetition. """ self.sort() for axis in self.world: t1 = self.text[axis][0] for i in range(1, len(self.world[axis])): t2 = self.text[axis][i] if len(t1) != len(t2): t1 = self.text[axis][i] continue start = 0 # In the following loop, we need to ignore the last character, # hence the len(t1) - 1. This is because if we have two strings # like 13d14m15s we want to make sure that we keep the last # part (15s) even if the two labels are identical. for j in range(len(t1) - 1): if t1[j] != t2[j]: break if t1[j] not in '-0123456789.': start = j + 1 t1 = self.text[axis][i] if start != 0: starts_dollar = self.text[axis][i].startswith('$') self.text[axis][i] = self.text[axis][i][start:] if starts_dollar: self.text[axis][i] = '$' + self.text[axis][i] # Remove any empty LaTeX inline math mode string if self.text[axis][i] == '$$': self.text[axis][i] = '' self._stale = True def set_pad(self, value): self._pad = value self._stale = True def get_pad(self): return self._pad def set_visible_axes(self, visible_axes): self._visible_axes = visible_axes self._stale = True def get_visible_axes(self): if self._visible_axes == 'all': return self.world.keys() else: return [x for x in self._visible_axes if x in self.world] def set_exclude_overlapping(self, exclude_overlapping): self._exclude_overlapping = exclude_overlapping def _set_xy_alignments(self, renderer, tick_out_size): """ Compute and set the x, y positions and the horizontal/vertical alignment of each label. """ if not self._stale: return self.simplify_labels() text_size = renderer.points_to_pixels(self.get_size()) visible_axes = self.get_visible_axes() self.xy = {axis: {} for axis in visible_axes} self.ha = {axis: {} for axis in visible_axes} self.va = {axis: {} for axis in visible_axes} for axis in visible_axes: for i in range(len(self.world[axis])): # In the event that the label is empty (which is not expected # but could happen in unforeseen corner cases), we should just # skip to the next label. if self.text[axis][i] == '': continue x, y = self.pixel[axis][i] pad = renderer.points_to_pixels(self.get_pad() + tick_out_size) if isinstance(self._frame, RectangularFrame): # This is just to preserve the current results, but can be # removed next time the reference images are re-generated. if np.abs(self.angle[axis][i]) < 45.: ha = 'right' va = 'bottom' dx = -pad dy = -text_size * 0.5 elif np.abs(self.angle[axis][i] - 90.) < 45: ha = 'center' va = 'bottom' dx = 0 dy = -text_size - pad elif np.abs(self.angle[axis][i] - 180.) < 45: ha = 'left' va = 'bottom' dx = pad dy = -text_size * 0.5 else: ha = 'center' va = 'bottom' dx = 0 dy = pad x = x + dx y = y + dy else: # This is the more general code for arbitrarily oriented # axes # Set initial position and find bounding box self.set_text(self.text[axis][i]) self.set_position((x, y)) bb = super().get_window_extent(renderer) # Find width and height, as well as angle at which we # transition which side of the label we use to anchor the # label. width = bb.width height = bb.height # Project axis angle onto bounding box ax = np.cos(np.radians(self.angle[axis][i])) ay = np.sin(np.radians(self.angle[axis][i])) # Set anchor point for label if np.abs(self.angle[axis][i]) < 45.: dx = width dy = ay * height elif np.abs(self.angle[axis][i] - 90.) < 45: dx = ax * width dy = height elif np.abs(self.angle[axis][i] - 180.) < 45: dx = -width dy = ay * height else: dx = ax * width dy = -height dx *= 0.5 dy *= 0.5 # Find normalized vector along axis normal, so as to be # able to nudge the label away by a constant padding factor dist = np.hypot(dx, dy) ddx = dx / dist ddy = dy / dist dx += ddx * pad dy += ddy * pad x = x - dx y = y - dy ha = 'center' va = 'center' self.xy[axis][i] = (x, y) self.ha[axis][i] = ha self.va[axis][i] = va self._stale = False def _get_bb(self, axis, i, renderer): """ Get the bounding box of an individual label. n.b. _set_xy_alignment() must be called before this method. """ if self.text[axis][i] == '': return self.set_text(self.text[axis][i]) self.set_position(self.xy[axis][i]) self.set_ha(self.ha[axis][i]) self.set_va(self.va[axis][i]) return super().get_window_extent(renderer) def draw(self, renderer, bboxes, ticklabels_bbox, tick_out_size): if not self.get_visible(): return self._set_xy_alignments(renderer, tick_out_size) for axis in self.get_visible_axes(): for i in range(len(self.world[axis])): # This implicitly sets the label text, position, alignment bb = self._get_bb(axis, i, renderer) if bb is None: continue # TODO: the problem here is that we might get rid of a label # that has a key starting bit such as -0:30 where the -0 # might be dropped from all other labels. if not self._exclude_overlapping or bb.count_overlaps(bboxes) == 0: super().draw(renderer) bboxes.append(bb) ticklabels_bbox[axis].append(bb) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/ticks.py0000644000175100001710000001520100000000000022012 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst from collections import defaultdict import numpy as np from matplotlib.lines import Path, Line2D from matplotlib.transforms import Affine2D from matplotlib import rcParams class Ticks(Line2D): """ Ticks are derived from Line2D, and note that ticks themselves are markers. Thus, you should use set_mec, set_mew, etc. To change the tick size (length), you need to use set_ticksize. To change the direction of the ticks (ticks are in opposite direction of ticklabels by default), use set_tick_out(False). Note that Matplotlib's defaults dictionary :data:`~matplotlib.rcParams` contains default settings (color, size, width) of the form `xtick.*` and `ytick.*`. In a WCS projection, there may not be a clear relationship between axes of the projection and 'x' or 'y' axes. For this reason, we read defaults from `xtick.*`. The following settings affect the default appearance of ticks: * `xtick.direction` * `xtick.major.size` * `xtick.major.width` * `xtick.minor.size` * `xtick.color` Attributes ---------- ticks_locs : dict This is set when the ticks are drawn, and is a mapping from axis to the locations of the ticks for that axis. """ def __init__(self, ticksize=None, tick_out=None, **kwargs): if ticksize is None: ticksize = rcParams['xtick.major.size'] self.set_ticksize(ticksize) self.set_minor_ticksize(rcParams['xtick.minor.size']) self.set_tick_out(rcParams['xtick.direction'] == 'out') self.clear() line2d_kwargs = {'color': rcParams['xtick.color'], 'linewidth': rcParams['xtick.major.width']} line2d_kwargs.update(kwargs) Line2D.__init__(self, [0.], [0.], **line2d_kwargs) self.set_visible_axes('all') self._display_minor_ticks = False def display_minor_ticks(self, display_minor_ticks): self._display_minor_ticks = display_minor_ticks def get_display_minor_ticks(self): return self._display_minor_ticks def set_tick_out(self, tick_out): """ set True if tick need to be rotated by 180 degree. """ self._tick_out = tick_out def get_tick_out(self): """ Return True if the tick will be rotated by 180 degree. """ return self._tick_out def set_ticksize(self, ticksize): """ set length of the ticks in points. """ self._ticksize = ticksize def get_ticksize(self): """ Return length of the ticks in points. """ return self._ticksize def set_minor_ticksize(self, ticksize): """ set length of the minor ticks in points. """ self._minor_ticksize = ticksize def get_minor_ticksize(self): """ Return length of the minor ticks in points. """ return self._minor_ticksize @property def out_size(self): if self._tick_out: return self._ticksize else: return 0. def set_visible_axes(self, visible_axes): self._visible_axes = visible_axes def get_visible_axes(self): if self._visible_axes == 'all': return self.world.keys() else: return [x for x in self._visible_axes if x in self.world] def clear(self): self.world = {} self.pixel = {} self.angle = {} self.disp = {} self.minor_world = {} self.minor_pixel = {} self.minor_angle = {} self.minor_disp = {} def add(self, axis, world, pixel, angle, axis_displacement): if axis not in self.world: self.world[axis] = [world] self.pixel[axis] = [pixel] self.angle[axis] = [angle] self.disp[axis] = [axis_displacement] else: self.world[axis].append(world) self.pixel[axis].append(pixel) self.angle[axis].append(angle) self.disp[axis].append(axis_displacement) def get_minor_world(self): return self.minor_world def add_minor(self, minor_axis, minor_world, minor_pixel, minor_angle, minor_axis_displacement): if minor_axis not in self.minor_world: self.minor_world[minor_axis] = [minor_world] self.minor_pixel[minor_axis] = [minor_pixel] self.minor_angle[minor_axis] = [minor_angle] self.minor_disp[minor_axis] = [minor_axis_displacement] else: self.minor_world[minor_axis].append(minor_world) self.minor_pixel[minor_axis].append(minor_pixel) self.minor_angle[minor_axis].append(minor_angle) self.minor_disp[minor_axis].append(minor_axis_displacement) def __len__(self): return len(self.world) _tickvert_path = Path([[0., 0.], [1., 0.]]) def draw(self, renderer): """ Draw the ticks. """ self.ticks_locs = defaultdict(list) if not self.get_visible(): return offset = renderer.points_to_pixels(self.get_ticksize()) self._draw_ticks(renderer, self.pixel, self.angle, offset) if self._display_minor_ticks: offset = renderer.points_to_pixels(self.get_minor_ticksize()) self._draw_ticks(renderer, self.minor_pixel, self.minor_angle, offset) def _draw_ticks(self, renderer, pixel_array, angle_array, offset): """ Draw the minor ticks. """ path_trans = self.get_transform() gc = renderer.new_gc() gc.set_foreground(self.get_color()) gc.set_alpha(self.get_alpha()) gc.set_linewidth(self.get_linewidth()) marker_scale = Affine2D().scale(offset, offset) marker_rotation = Affine2D() marker_transform = marker_scale + marker_rotation initial_angle = 180. if self.get_tick_out() else 0. for axis in self.get_visible_axes(): if axis not in pixel_array: continue for loc, angle in zip(pixel_array[axis], angle_array[axis]): # Set the rotation for this tick marker_rotation.rotate_deg(initial_angle + angle) # Draw the markers locs = path_trans.transform_non_affine(np.array([loc, loc])) renderer.draw_markers(gc, self._tickvert_path, marker_transform, Path(locs), path_trans.get_affine()) # Reset the tick rotation before moving to the next tick marker_rotation.clear() self.ticks_locs[axis].append(locs) gc.restore() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/transforms.py0000644000175100001710000001320100000000000023071 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst # Note: This file includes code derived from pywcsgrid2 # # This file contains Matplotlib transformation objects (e.g. from pixel to world # coordinates, but also world-to-world). import abc import numpy as np from matplotlib.path import Path from matplotlib.transforms import Transform from astropy import units as u from astropy.coordinates import (SkyCoord, frame_transform_graph, UnitSphericalRepresentation, BaseCoordinateFrame) __all__ = ['CurvedTransform', 'CoordinateTransform', 'World2PixelTransform', 'Pixel2WorldTransform'] class CurvedTransform(Transform, metaclass=abc.ABCMeta): """ Abstract base class for non-affine curved transforms """ input_dims = 2 output_dims = 2 is_separable = False def transform_path(self, path): """ Transform a Matplotlib Path Parameters ---------- path : :class:`~matplotlib.path.Path` The path to transform Returns ------- path : :class:`~matplotlib.path.Path` The resulting path """ return Path(self.transform(path.vertices), path.codes) transform_path_non_affine = transform_path def transform(self, input): raise NotImplementedError("") def inverted(self): raise NotImplementedError("") class CoordinateTransform(CurvedTransform): has_inverse = True def __init__(self, input_system, output_system): super().__init__() self._input_system_name = input_system self._output_system_name = output_system if isinstance(self._input_system_name, str): frame_cls = frame_transform_graph.lookup_name(self._input_system_name) if frame_cls is None: raise ValueError(f"Frame {self._input_system_name} not found") else: self.input_system = frame_cls() elif isinstance(self._input_system_name, BaseCoordinateFrame): self.input_system = self._input_system_name else: raise TypeError("input_system should be a WCS instance, string, or a coordinate frame instance") if isinstance(self._output_system_name, str): frame_cls = frame_transform_graph.lookup_name(self._output_system_name) if frame_cls is None: raise ValueError(f"Frame {self._output_system_name} not found") else: self.output_system = frame_cls() elif isinstance(self._output_system_name, BaseCoordinateFrame): self.output_system = self._output_system_name else: raise TypeError("output_system should be a WCS instance, string, or a coordinate frame instance") if self.output_system == self.input_system: self.same_frames = True else: self.same_frames = False @property def same_frames(self): return self._same_frames @same_frames.setter def same_frames(self, same_frames): self._same_frames = same_frames def transform(self, input_coords): """ Transform one set of coordinates to another """ if self.same_frames: return input_coords input_coords = input_coords*u.deg x_in, y_in = input_coords[:, 0], input_coords[:, 1] c_in = SkyCoord(UnitSphericalRepresentation(x_in, y_in), frame=self.input_system) # We often need to transform arrays that contain NaN values, and filtering # out the NaN values would have a performance hit, so instead we just pass # on all values and just ignore Numpy warnings with np.errstate(all='ignore'): c_out = c_in.transform_to(self.output_system) lon = c_out.spherical.lon.deg lat = c_out.spherical.lat.deg return np.concatenate((lon[:, np.newaxis], lat[:, np.newaxis]), axis=1) transform_non_affine = transform def inverted(self): """ Return the inverse of the transform """ return CoordinateTransform(self._output_system_name, self._input_system_name) class World2PixelTransform(CurvedTransform, metaclass=abc.ABCMeta): """ Base transformation from world to pixel coordinates """ has_inverse = True frame_in = None @property @abc.abstractmethod def input_dims(self): """ The number of input world dimensions """ @abc.abstractmethod def transform(self, world): """ Transform world to pixel coordinates. You should pass in a NxM array where N is the number of points to transform, and M is the number of dimensions. This then returns the (x, y) pixel coordinates as a Nx2 array. """ @abc.abstractmethod def inverted(self): """ Return the inverse of the transform """ class Pixel2WorldTransform(CurvedTransform, metaclass=abc.ABCMeta): """ Base transformation from pixel to world coordinates """ has_inverse = True frame_out = None @property @abc.abstractmethod def output_dims(self): """ The number of output world dimensions """ @abc.abstractmethod def transform(self, pixel): """ Transform pixel to world coordinates. You should pass in a Nx2 array of (x, y) pixel coordinates to transform to world coordinates. This will then return an NxM array where M is the number of dimensions. """ @abc.abstractmethod def inverted(self): """ Return the inverse of the transform """ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/utils.py0000644000175100001710000001305400000000000022041 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import numpy as np from astropy import units as u from astropy.coordinates import BaseCoordinateFrame __all__ = ['select_step_degree', 'select_step_hour', 'select_step_scalar', 'transform_contour_set_inplace'] def select_step_degree(dv): # Modified from axis_artist, supports astropy.units if dv > 1. * u.arcsec: degree_limits_ = [1.5, 3, 7, 13, 20, 40, 70, 120, 270, 520] degree_steps_ = [1, 2, 5, 10, 15, 30, 45, 90, 180, 360] degree_units = [u.degree] * len(degree_steps_) minsec_limits_ = [1.5, 2.5, 3.5, 8, 11, 18, 25, 45] minsec_steps_ = [1, 2, 3, 5, 10, 15, 20, 30] minute_limits_ = np.array(minsec_limits_) / 60. minute_units = [u.arcmin] * len(minute_limits_) second_limits_ = np.array(minsec_limits_) / 3600. second_units = [u.arcsec] * len(second_limits_) degree_limits = np.concatenate([second_limits_, minute_limits_, degree_limits_]) degree_steps = minsec_steps_ + minsec_steps_ + degree_steps_ degree_units = second_units + minute_units + degree_units n = degree_limits.searchsorted(dv.to(u.degree)) step = degree_steps[n] unit = degree_units[n] return step * unit else: return select_step_scalar(dv.to_value(u.arcsec)) * u.arcsec def select_step_hour(dv): if dv > 15. * u.arcsec: hour_limits_ = [1.5, 2.5, 3.5, 5, 7, 10, 15, 21, 36] hour_steps_ = [1, 2, 3, 4, 6, 8, 12, 18, 24] hour_units = [u.hourangle] * len(hour_steps_) minsec_limits_ = [1.5, 2.5, 3.5, 4.5, 5.5, 8, 11, 14, 18, 25, 45] minsec_steps_ = [1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30] minute_limits_ = np.array(minsec_limits_) / 60. minute_units = [15. * u.arcmin] * len(minute_limits_) second_limits_ = np.array(minsec_limits_) / 3600. second_units = [15. * u.arcsec] * len(second_limits_) hour_limits = np.concatenate([second_limits_, minute_limits_, hour_limits_]) hour_steps = minsec_steps_ + minsec_steps_ + hour_steps_ hour_units = second_units + minute_units + hour_units n = hour_limits.searchsorted(dv.to(u.hourangle)) step = hour_steps[n] unit = hour_units[n] return step * unit else: return select_step_scalar(dv.to_value(15. * u.arcsec)) * (15. * u.arcsec) def select_step_scalar(dv): log10_dv = np.log10(dv) base = np.floor(log10_dv) frac = log10_dv - base steps = np.log10([1, 2, 5, 10]) imin = np.argmin(np.abs(frac - steps)) return 10. ** (base + steps[imin]) def get_coord_meta(frame): coord_meta = {} coord_meta['type'] = ('longitude', 'latitude') coord_meta['wrap'] = (None, None) coord_meta['unit'] = (u.deg, u.deg) from astropy.coordinates import frame_transform_graph if isinstance(frame, str): initial_frame = frame frame = frame_transform_graph.lookup_name(frame) if frame is None: raise ValueError(f"Unknown frame: {initial_frame}") if not isinstance(frame, BaseCoordinateFrame): frame = frame() names = list(frame.representation_component_names.keys()) coord_meta['name'] = names[:2] return coord_meta def transform_contour_set_inplace(cset, transform): """ Transform a contour set in-place using a specified :class:`matplotlib.transform.Transform` Using transforms with the native Matplotlib contour/contourf can be slow if the transforms have a non-negligible overhead (which is the case for WCS/SkyCoord transforms) since the transform is called for each individual contour line. It is more efficient to stack all the contour lines together temporarily and transform them in one go. """ # The contours are represented as paths grouped into levels. Each can have # one or more paths. The approach we take here is to stack the vertices of # all paths and transform them in one go. The pos_level list helps us keep # track of where the set of segments for each overall contour level ends. # The pos_segments list helps us keep track of where each segmnt ends for # each contour level. all_paths = [] pos_level = [] pos_segments = [] for collection in cset.collections: paths = collection.get_paths() if len(paths) == 0: continue all_paths.append(paths) # The last item in pos isn't needed for np.split and in fact causes # issues if we keep it because it will cause an extra empty array to be # returned. pos = np.cumsum([len(x) for x in paths]) pos_segments.append(pos[:-1]) pos_level.append(pos[-1]) # As above the last item isn't needed pos_level = np.cumsum(pos_level)[:-1] # Stack all the segments into a single (n, 2) array vertices = [path.vertices for paths in all_paths for path in paths] if len(vertices) > 0: vertices = np.concatenate(vertices) else: return # Transform all coordinates in one go vertices = transform.transform(vertices) # Split up into levels again vertices = np.split(vertices, pos_level) # Now re-populate the segments in the line collections for ilevel, vert in enumerate(vertices): vert = np.split(vert, pos_segments[ilevel]) for iseg, ivert in enumerate(vert): all_paths[ilevel][iseg].vertices = ivert ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/visualization/wcsaxes/wcsapi.py0000644000175100001710000003233600000000000022173 0ustar00vstsdocker# Functions/classes for WCSAxes related to APE14 WCSes import numpy as np from astropy.coordinates import SkyCoord, ICRS, BaseCoordinateFrame from astropy import units as u from astropy.wcs import WCS from astropy.wcs.utils import local_partial_pixel_derivatives from astropy.wcs.wcsapi import SlicedLowLevelWCS from .frame import RectangularFrame, EllipticalFrame, RectangularFrame1D from .transforms import CurvedTransform __all__ = ['transform_coord_meta_from_wcs', 'WCSWorld2PixelTransform', 'WCSPixel2WorldTransform'] IDENTITY = WCS(naxis=2) IDENTITY.wcs.ctype = ["X", "Y"] IDENTITY.wcs.crval = [0., 0.] IDENTITY.wcs.crpix = [1., 1.] IDENTITY.wcs.cdelt = [1., 1.] def transform_coord_meta_from_wcs(wcs, frame_class, slices=None): if slices is not None: slices = tuple(slices) if wcs.pixel_n_dim > 2: if slices is None: raise ValueError("WCS has more than 2 pixel dimensions, so " "'slices' should be set") elif len(slices) != wcs.pixel_n_dim: raise ValueError("'slices' should have as many elements as WCS " "has pixel dimensions (should be {})" .format(wcs.pixel_n_dim)) is_fits_wcs = isinstance(wcs, WCS) or (isinstance(wcs, SlicedLowLevelWCS) and isinstance(wcs._wcs, WCS)) coord_meta = {} coord_meta['name'] = [] coord_meta['type'] = [] coord_meta['wrap'] = [] coord_meta['unit'] = [] coord_meta['visible'] = [] coord_meta['format_unit'] = [] for idx in range(wcs.world_n_dim): axis_type = wcs.world_axis_physical_types[idx] axis_unit = u.Unit(wcs.world_axis_units[idx]) coord_wrap = None format_unit = axis_unit coord_type = 'scalar' if axis_type is not None: axis_type_split = axis_type.split('.') if "pos.helioprojective.lon" in axis_type: coord_wrap = 180. format_unit = u.arcsec coord_type = "longitude" elif "pos.helioprojective.lat" in axis_type: format_unit = u.arcsec coord_type = "latitude" elif "pos.heliographic.stonyhurst.lon" in axis_type: coord_wrap = 180. format_unit = u.deg coord_type = "longitude" elif "pos.heliographic.stonyhurst.lat" in axis_type: format_unit = u.deg coord_type = "latitude" elif "pos.heliographic.carrington.lon" in axis_type: coord_wrap = 360. format_unit = u.deg coord_type = "longitude" elif "pos.heliographic.carrington.lat" in axis_type: format_unit = u.deg coord_type = "latitude" elif "pos" in axis_type_split: if "lon" in axis_type_split: coord_type = "longitude" elif "lat" in axis_type_split: coord_type = "latitude" elif "ra" in axis_type_split: coord_type = "longitude" format_unit = u.hourangle elif "dec" in axis_type_split: coord_type = "latitude" elif "alt" in axis_type_split: coord_type = "longitude" elif "az" in axis_type_split: coord_type = "latitude" elif "long" in axis_type_split: coord_type = "longitude" coord_meta['type'].append(coord_type) coord_meta['wrap'].append(coord_wrap) coord_meta['format_unit'].append(format_unit) coord_meta['unit'].append(axis_unit) # For FITS-WCS, for backward-compatibility, we need to make sure that we # provide aliases based on CTYPE for the name. if is_fits_wcs: name = [] if isinstance(wcs, WCS): name.append(wcs.wcs.ctype[idx].lower()) name.append(wcs.wcs.ctype[idx][:4].replace('-', '').lower()) elif isinstance(wcs, SlicedLowLevelWCS): name.append(wcs._wcs.wcs.ctype[wcs._world_keep[idx]].lower()) name.append(wcs._wcs.wcs.ctype[wcs._world_keep[idx]][:4].replace('-', '').lower()) if name[0] == name[1]: name = name[0:1] if axis_type: if axis_type not in name: name.insert(0, axis_type) if wcs.world_axis_names and wcs.world_axis_names[idx]: if wcs.world_axis_names[idx] not in name: name.append(wcs.world_axis_names[idx]) name = tuple(name) if len(name) > 1 else name[0] else: name = axis_type or '' if wcs.world_axis_names: name = (name, wcs.world_axis_names[idx]) if wcs.world_axis_names[idx] else name coord_meta['name'].append(name) coord_meta['default_axislabel_position'] = [''] * wcs.world_n_dim coord_meta['default_ticklabel_position'] = [''] * wcs.world_n_dim coord_meta['default_ticks_position'] = [''] * wcs.world_n_dim # If the world axis has a name use it, else display the world axis physical type. fallback_labels = [name[0] if isinstance(name, (list, tuple)) else name for name in coord_meta['name']] coord_meta['default_axis_label'] = [wcs.world_axis_names[i] or fallback_label for i, fallback_label in enumerate(fallback_labels)] transform_wcs, invert_xy, world_map = apply_slices(wcs, slices) transform = WCSPixel2WorldTransform(transform_wcs, invert_xy=invert_xy) for i in range(len(coord_meta['type'])): coord_meta['visible'].append(i in world_map) inv_all_corr = [False] * wcs.world_n_dim m = transform_wcs.axis_correlation_matrix.copy() if invert_xy: inv_all_corr = np.all(m, axis=1) m = m[:, ::-1] if frame_class is RectangularFrame: for i, spine_name in enumerate('bltr'): pos = np.nonzero(m[:, i % 2])[0] # If all the axes we have are correlated with each other and we # have inverted the axes, then we need to reverse the index so we # put the 'y' on the left. if inv_all_corr[i % 2]: pos = pos[::-1] if len(pos) > 0: index = world_map[pos[0]] coord_meta['default_axislabel_position'][index] = spine_name coord_meta['default_ticklabel_position'][index] = spine_name coord_meta['default_ticks_position'][index] = spine_name m[pos[0], :] = 0 # In the special and common case where the frame is rectangular and # we are dealing with 2-d WCS (after slicing), we show all ticks on # all axes for backward-compatibility. if len(world_map) == 2: for index in world_map: coord_meta['default_ticks_position'][index] = 'bltr' elif frame_class is RectangularFrame1D: derivs = np.abs(local_partial_pixel_derivatives(transform_wcs, *[0]*transform_wcs.pixel_n_dim, normalize_by_world=False))[:, 0] for i, spine_name in enumerate('bt'): # Here we are iterating over the correlated axes in world axis order. # We want to sort the correlated axes by their partial derivatives, # so we put the most rapidly changing world axis on the bottom. pos = np.nonzero(m[:, 0])[0] order = np.argsort(derivs[pos])[::-1] # Sort largest to smallest pos = pos[order] if len(pos) > 0: index = world_map[pos[0]] coord_meta['default_axislabel_position'][index] = spine_name coord_meta['default_ticklabel_position'][index] = spine_name coord_meta['default_ticks_position'][index] = spine_name m[pos[0], :] = 0 # In the special and common case where the frame is rectangular and # we are dealing with 2-d WCS (after slicing), we show all ticks on # all axes for backward-compatibility. if len(world_map) == 1: for index in world_map: coord_meta['default_ticks_position'][index] = 'bt' elif frame_class is EllipticalFrame: if 'longitude' in coord_meta['type']: lon_idx = coord_meta['type'].index('longitude') coord_meta['default_axislabel_position'][lon_idx] = 'h' coord_meta['default_ticklabel_position'][lon_idx] = 'h' coord_meta['default_ticks_position'][lon_idx] = 'h' if 'latitude' in coord_meta['type']: lat_idx = coord_meta['type'].index('latitude') coord_meta['default_axislabel_position'][lat_idx] = 'c' coord_meta['default_ticklabel_position'][lat_idx] = 'c' coord_meta['default_ticks_position'][lat_idx] = 'c' else: for index in range(len(coord_meta['type'])): if index in world_map: coord_meta['default_axislabel_position'][index] = frame_class.spine_names coord_meta['default_ticklabel_position'][index] = frame_class.spine_names coord_meta['default_ticks_position'][index] = frame_class.spine_names return transform, coord_meta def apply_slices(wcs, slices): """ Take the input WCS and slices and return a sliced WCS for the transform and a mapping of world axes in the sliced WCS to the input WCS. """ if isinstance(wcs, SlicedLowLevelWCS): world_keep = list(wcs._world_keep) else: world_keep = list(range(wcs.world_n_dim)) # world_map is the index of the world axis in the input WCS for a given # axis in the transform_wcs world_map = list(range(wcs.world_n_dim)) transform_wcs = wcs invert_xy = False if slices is not None: wcs_slice = list(slices) wcs_slice[wcs_slice.index("x")] = slice(None) if 'y' in slices: wcs_slice[wcs_slice.index("y")] = slice(None) invert_xy = slices.index('x') > slices.index('y') transform_wcs = SlicedLowLevelWCS(wcs, wcs_slice[::-1]) world_map = tuple(world_keep.index(i) for i in transform_wcs._world_keep) return transform_wcs, invert_xy, world_map def wcsapi_to_celestial_frame(wcs): for cls, _, kwargs, *_ in wcs.world_axis_object_classes.values(): if issubclass(cls, SkyCoord): return kwargs.get('frame', ICRS()) elif issubclass(cls, BaseCoordinateFrame): return cls(**kwargs) class WCSWorld2PixelTransform(CurvedTransform): """ WCS transformation from world to pixel coordinates """ has_inverse = True frame_in = None def __init__(self, wcs, invert_xy=False): super().__init__() if wcs.pixel_n_dim > 2: raise ValueError('Only pixel_n_dim =< 2 is supported') self.wcs = wcs self.invert_xy = invert_xy self.frame_in = wcsapi_to_celestial_frame(wcs) def __eq__(self, other): return (isinstance(other, type(self)) and self.wcs is other.wcs and self.invert_xy == other.invert_xy) @property def input_dims(self): return self.wcs.world_n_dim def transform(self, world): # Convert to a list of arrays world = list(world.T) if len(world) != self.wcs.world_n_dim: raise ValueError(f"Expected {self.wcs.world_n_dim} world coordinates, got {len(world)} ") if len(world[0]) == 0: pixel = np.zeros((0, 2)) else: pixel = self.wcs.world_to_pixel_values(*world) if self.invert_xy: pixel = pixel[::-1] pixel = np.array(pixel).T return pixel transform_non_affine = transform def inverted(self): """ Return the inverse of the transform """ return WCSPixel2WorldTransform(self.wcs, invert_xy=self.invert_xy) class WCSPixel2WorldTransform(CurvedTransform): """ WCS transformation from pixel to world coordinates """ has_inverse = True def __init__(self, wcs, invert_xy=False): super().__init__() if wcs.pixel_n_dim > 2: raise ValueError('Only pixel_n_dim =< 2 is supported') self.wcs = wcs self.invert_xy = invert_xy self.frame_out = wcsapi_to_celestial_frame(wcs) def __eq__(self, other): return (isinstance(other, type(self)) and self.wcs is other.wcs and self.invert_xy == other.invert_xy) @property def output_dims(self): return self.wcs.world_n_dim def transform(self, pixel): # Convert to a list of arrays pixel = list(pixel.T) if len(pixel) != self.wcs.pixel_n_dim: raise ValueError(f"Expected {self.wcs.pixel_n_dim} world coordinates, got {len(pixel)} ") if self.invert_xy: pixel = pixel[::-1] if len(pixel[0]) == 0: world = np.zeros((0, self.wcs.world_n_dim)) else: world = self.wcs.pixel_to_world_values(*pixel) if self.wcs.world_n_dim == 1: world = [world] world = np.array(world).T return world transform_non_affine = transform def inverted(self): """ Return the inverse of the transform """ return WCSWorld2PixelTransform(self.wcs, invert_xy=self.invert_xy) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2192562 astropy-5.0.2/astropy/wcs/0000755000175100001710000000000000000000000014542 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/__init__.py0000644000175100001710000000250300000000000016653 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ .. _wcslib: https://www.atnf.csiro.au/people/mcalabre/WCS/wcslib/index.html .. _distortion paper: https://www.atnf.csiro.au/people/mcalabre/WCS/dcs_20040422.pdf .. _SIP: https://irsa.ipac.caltech.edu/data/SPITZER/docs/files/spitzer/shupeADASS.pdf .. _FITS WCS standard: https://fits.gsfc.nasa.gov/fits_wcs.html `astropy.wcs` contains utilities for managing World Coordinate System (WCS) transformations in FITS files. These transformations map the pixel locations in an image to their real-world units, such as their position on the sky sphere. It performs three separate classes of WCS transformations: - Core WCS, as defined in the `FITS WCS standard`_, based on Mark Calabretta's `wcslib`_. See `~astropy.wcs.Wcsprm`. - Simple Imaging Polynomial (`SIP`_) convention. See `~astropy.wcs.Sip`. - table lookup distortions as defined in WCS `distortion paper`_. See `~astropy.wcs.DistortionLookupTable`. Each of these transformations can be used independently or together in a standard pipeline. """ from .wcs import * from .wcs import InvalidTabularParametersError # just for docs from . import utils def get_include(): """ Get the path to astropy.wcs's C header files. """ import os return os.path.join(os.path.dirname(__file__), "include") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/docstrings.py0000644000175100001710000020646100000000000017304 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst # It gets to be really tedious to type long docstrings in ANSI C # syntax (since multi-line string literals are not valid). # Therefore, the docstrings are written here in doc/docstrings.py, # which are then converted by setup.py into docstrings.h, which is # included by pywcs.c __all__ = ['TWO_OR_MORE_ARGS', 'RETURNS', 'ORIGIN', 'RA_DEC_ORDER'] def _fix(content, indent=0): lines = content.split('\n') indent = '\n' + ' ' * indent return indent.join(lines) def TWO_OR_MORE_ARGS(naxis, indent=0): return _fix( f"""*args There are two accepted forms for the positional arguments: - 2 arguments: An *N* x *{naxis}* array of coordinates, and an *origin*. - more than 2 arguments: An array for each axis, followed by an *origin*. These arrays must be broadcastable to one another. Here, *origin* is the coordinate in the upper left corner of the image. In FITS and Fortran standards, this is 1. In Numpy and C standards this is 0. """, indent) def RETURNS(out_type, indent=0): return _fix(f"""result : array Returns the {out_type}. If the input was a single array and origin, a single array is returned, otherwise a tuple of arrays is returned.""", indent) def ORIGIN(indent=0): return _fix( """ origin : int Specifies the origin of pixel values. The Fortran and FITS standards use an origin of 1. Numpy and C use array indexing with origin at 0. """, indent) def RA_DEC_ORDER(indent=0): return _fix( """ ra_dec_order : bool, optional When `True` will ensure that world coordinates are always given and returned in as (*ra*, *dec*) pairs, regardless of the order of the axes specified by the in the ``CTYPE`` keywords. Default is `False`. """, indent) a = """ ``double array[a_order+1][a_order+1]`` Focal plane transformation matrix. The `SIP`_ ``A_i_j`` matrix used for pixel to focal plane transformation. Its values may be changed in place, but it may not be resized, without creating a new `~astropy.wcs.Sip` object. """ a_order = """ ``int`` (read-only) Order of the polynomial (``A_ORDER``). """ all_pix2world = """ all_pix2world(pixcrd, origin) -> ``double array[ncoord][nelem]`` Transforms pixel coordinates to world coordinates. Does the following: - Detector to image plane correction (if present) - SIP distortion correction (if present) - FITS WCS distortion correction (if present) - wcslib "core" WCS transformation The first three (the distortion corrections) are done in parallel. Parameters ---------- pixcrd : ndarray Array of pixel coordinates as ``double array[ncoord][nelem]``. {} Returns ------- world : ndarray Returns an array of world coordinates as ``double array[ncoord][nelem]``. Raises ------ MemoryError Memory allocation failed. SingularMatrixError Linear transformation matrix is singular. InconsistentAxisTypesError Inconsistent or unrecognized coordinate axis types. ValueError Invalid parameter value. ValueError Invalid coordinate transformation parameters. ValueError x- and y-coordinate arrays are not the same size. InvalidTransformError Invalid coordinate transformation. InvalidTransformError Ill-conditioned coordinate transformation parameters. """.format(ORIGIN()) alt = """ ``str`` Character code for alternate coordinate descriptions. For example, the ``"a"`` in keyword names such as ``CTYPEia``. This is a space character for the primary coordinate description, or one of the 26 upper-case letters, A-Z. """ ap = """ ``double array[ap_order+1][ap_order+1]`` Focal plane to pixel transformation matrix. The `SIP`_ ``AP_i_j`` matrix used for focal plane to pixel transformation. Its values may be changed in place, but it may not be resized, without creating a new `~astropy.wcs.Sip` object. """ ap_order = """ ``int`` (read-only) Order of the polynomial (``AP_ORDER``). """ aux = """ `~astropy.wcs.Auxprm` Auxiliary coordinate system information of a specialist nature. """ Auxprm = """ Class that contains auxiliary coordinate system information of a specialist nature. This class can not be constructed directly from Python, but instead is returned from `~astropy.wcs.Wcsprm.aux`. """ axis_types = """ ``int array[naxis]`` An array of four-digit type codes for each axis. - First digit (i.e. 1000s): - 0: Non-specific coordinate type. - 1: Stokes coordinate. - 2: Celestial coordinate (including ``CUBEFACE``). - 3: Spectral coordinate. - Second digit (i.e. 100s): - 0: Linear axis. - 1: Quantized axis (``STOKES``, ``CUBEFACE``). - 2: Non-linear celestial axis. - 3: Non-linear spectral axis. - 4: Logarithmic axis. - 5: Tabular axis. - Third digit (i.e. 10s): - 0: Group number, e.g. lookup table number - The fourth digit is used as a qualifier depending on the axis type. - For celestial axes: - 0: Longitude coordinate. - 1: Latitude coordinate. - 2: ``CUBEFACE`` number. - For lookup tables: the axis number in a multidimensional table. ``CTYPEia`` in ``"4-3"`` form with unrecognized algorithm code will have its type set to -1 and generate an error. """ b = """ ``double array[b_order+1][b_order+1]`` Pixel to focal plane transformation matrix. The `SIP`_ ``B_i_j`` matrix used for pixel to focal plane transformation. Its values may be changed in place, but it may not be resized, without creating a new `~astropy.wcs.Sip` object. """ b_order = """ ``int`` (read-only) Order of the polynomial (``B_ORDER``). """ bounds_check = """ bounds_check(pix2world, world2pix) Enable/disable bounds checking. Parameters ---------- pix2world : bool, optional When `True`, enable bounds checking for the pixel-to-world (p2x) transformations. Default is `True`. world2pix : bool, optional When `True`, enable bounds checking for the world-to-pixel (s2x) transformations. Default is `True`. Notes ----- Note that by default (without calling `bounds_check`) strict bounds checking is enabled. """ bp = """ ``double array[bp_order+1][bp_order+1]`` Focal plane to pixel transformation matrix. The `SIP`_ ``BP_i_j`` matrix used for focal plane to pixel transformation. Its values may be changed in place, but it may not be resized, without creating a new `~astropy.wcs.Sip` object. """ bp_order = """ ``int`` (read-only) Order of the polynomial (``BP_ORDER``). """ cd = """ ``double array[naxis][naxis]`` The ``CDi_ja`` linear transformation matrix. For historical compatibility, three alternate specifications of the linear transformations are available in wcslib. The canonical ``PCi_ja`` with ``CDELTia``, ``CDi_ja``, and the deprecated ``CROTAia`` keywords. Although the latter may not formally co-exist with ``PCi_ja``, the approach here is simply to ignore them if given in conjunction with ``PCi_ja``. `~astropy.wcs.Wcsprm.has_pc`, `~astropy.wcs.Wcsprm.has_cd` and `~astropy.wcs.Wcsprm.has_crota` can be used to determine which of these alternatives are present in the header. These alternate specifications of the linear transformation matrix are translated immediately to ``PCi_ja`` by `~astropy.wcs.Wcsprm.set` and are nowhere visible to the lower-level routines. In particular, `~astropy.wcs.Wcsprm.set` resets `~astropy.wcs.Wcsprm.cdelt` to unity if ``CDi_ja`` is present (and no ``PCi_ja``). If no ``CROTAia`` is associated with the latitude axis, `~astropy.wcs.Wcsprm.set` reverts to a unity ``PCi_ja`` matrix. """ cdelt = """ ``double array[naxis]`` Coordinate increments (``CDELTia``) for each coord axis. If a ``CDi_ja`` linear transformation matrix is present, a warning is raised and `~astropy.wcs.Wcsprm.cdelt` is ignored. The ``CDi_ja`` matrix may be deleted by:: del wcs.wcs.cd An undefined value is represented by NaN. """ cdfix = """ cdfix() Fix erroneously omitted ``CDi_ja`` keywords. Sets the diagonal element of the ``CDi_ja`` matrix to unity if all ``CDi_ja`` keywords associated with a given axis were omitted. According to Paper I, if any ``CDi_ja`` keywords at all are given in a FITS header then those not given default to zero. This results in a singular matrix with an intersecting row and column of zeros. Returns ------- success : int Returns ``0`` for success; ``-1`` if no change required. """ cel_offset = """ ``boolean`` Is there an offset? If `True`, an offset will be applied to ``(x, y)`` to force ``(x, y) = (0, 0)`` at the fiducial point, (phi_0, theta_0). Default is `False`. """ celfix = """ Translates AIPS-convention celestial projection types, ``-NCP`` and ``-GLS``. Returns ------- success : int Returns ``0`` for success; ``-1`` if no change required. """ cname = """ ``list of strings`` A list of the coordinate axis names, from ``CNAMEia``. """ colax = """ ``int array[naxis]`` An array recording the column numbers for each axis in a pixel list. """ colnum = """ ``int`` Column of FITS binary table associated with this WCS. Where the coordinate representation is associated with an image-array column in a FITS binary table, this property may be used to record the relevant column number. It should be set to zero for an image header or pixel list. """ compare = """ compare(other, cmp=0, tolerance=0.0) Compare two Wcsprm objects for equality. Parameters ---------- other : Wcsprm The other Wcsprm object to compare to. cmp : int, optional A bit field controlling the strictness of the comparison. When 0, (the default), all fields must be identical. The following constants, defined in the `astropy.wcs` module, may be or'ed together to loosen the comparison. - ``WCSCOMPARE_ANCILLARY``: Ignores ancillary keywords that don't change the WCS transformation, such as ``XPOSURE`` or ``EQUINOX``. Note that this also ignores ``DATE-OBS``, which does change the WCS transformation in some cases. - ``WCSCOMPARE_TILING``: Ignore integral differences in ``CRPIXja``. This is the 'tiling' condition, where two WCSes cover different regions of the same map projection and align on the same map grid. - ``WCSCOMPARE_CRPIX``: Ignore any differences at all in ``CRPIXja``. The two WCSes cover different regions of the same map projection but may not align on the same grid map. Overrides ``WCSCOMPARE_TILING``. tolerance : float, optional The amount of tolerance required. For example, for a value of 1e-6, all floating-point values in the objects must be equal to the first 6 decimal places. The default value of 0.0 implies exact equality. Returns ------- equal : bool """ convert = """ convert(array) Perform the unit conversion on the elements of the given *array*, returning an array of the same shape. """ coord = """ ``double array[K_M]...[K_2][K_1][M]`` The tabular coordinate array. Has the dimensions:: (K_M, ... K_2, K_1, M) (see `~astropy.wcs.Tabprm.K`) i.e. with the `M` dimension varying fastest so that the `M` elements of a coordinate vector are stored contiguously in memory. """ copy = """ Creates a deep copy of the WCS object. """ cpdis1 = """ `~astropy.wcs.DistortionLookupTable` The pre-linear transformation distortion lookup table, ``CPDIS1``. """ cpdis2 = """ `~astropy.wcs.DistortionLookupTable` The pre-linear transformation distortion lookup table, ``CPDIS2``. """ crder = """ ``double array[naxis]`` The random error in each coordinate axis, ``CRDERia``. An undefined value is represented by NaN. """ crln_obs = """ ``double`` Carrington heliographic longitude of the observer (deg). If undefined, this is set to `None`. """ crota = """ ``double array[naxis]`` ``CROTAia`` keyvalues for each coordinate axis. For historical compatibility, three alternate specifications of the linear transformations are available in wcslib. The canonical ``PCi_ja`` with ``CDELTia``, ``CDi_ja``, and the deprecated ``CROTAia`` keywords. Although the latter may not formally co-exist with ``PCi_ja``, the approach here is simply to ignore them if given in conjunction with ``PCi_ja``. `~astropy.wcs.Wcsprm.has_pc`, `~astropy.wcs.Wcsprm.has_cd` and `~astropy.wcs.Wcsprm.has_crota` can be used to determine which of these alternatives are present in the header. These alternate specifications of the linear transformation matrix are translated immediately to ``PCi_ja`` by `~astropy.wcs.Wcsprm.set` and are nowhere visible to the lower-level routines. In particular, `~astropy.wcs.Wcsprm.set` resets `~astropy.wcs.Wcsprm.cdelt` to unity if ``CDi_ja`` is present (and no ``PCi_ja``). If no ``CROTAia`` is associated with the latitude axis, `~astropy.wcs.Wcsprm.set` reverts to a unity ``PCi_ja`` matrix. """ crpix = """ ``double array[naxis]`` Coordinate reference pixels (``CRPIXja``) for each pixel axis. """ crval = """ ``double array[naxis]`` Coordinate reference values (``CRVALia``) for each coordinate axis. """ crval_tabprm = """ ``double array[M]`` Index values for the reference pixel for each of the tabular coord axes. """ csyer = """ ``double array[naxis]`` The systematic error in the coordinate value axes, ``CSYERia``. An undefined value is represented by NaN. """ ctype = """ ``list of strings[naxis]`` List of ``CTYPEia`` keyvalues. The `~astropy.wcs.Wcsprm.ctype` keyword values must be in upper case and there must be zero or one pair of matched celestial axis types, and zero or one spectral axis. """ cubeface = """ ``int`` Index into the ``pixcrd`` (pixel coordinate) array for the ``CUBEFACE`` axis. This is used for quadcube projections where the cube faces are stored on a separate axis. The quadcube projections (``TSC``, ``CSC``, ``QSC``) may be represented in FITS in either of two ways: - The six faces may be laid out in one plane and numbered as follows:: 0 4 3 2 1 4 3 2 5 Faces 2, 3 and 4 may appear on one side or the other (or both). The world-to-pixel routines map faces 2, 3 and 4 to the left but the pixel-to-world routines accept them on either side. - The ``COBE`` convention in which the six faces are stored in a three-dimensional structure using a ``CUBEFACE`` axis indexed from 0 to 5 as above. These routines support both methods; `~astropy.wcs.Wcsprm.set` determines which is being used by the presence or absence of a ``CUBEFACE`` axis in `~astropy.wcs.Wcsprm.ctype`. `~astropy.wcs.Wcsprm.p2s` and `~astropy.wcs.Wcsprm.s2p` translate the ``CUBEFACE`` axis representation to the single plane representation understood by the lower-level projection routines. """ cunit = """ ``list of astropy.UnitBase[naxis]`` List of ``CUNITia`` keyvalues as `astropy.units.UnitBase` instances. These define the units of measurement of the ``CRVALia``, ``CDELTia`` and ``CDi_ja`` keywords. As ``CUNITia`` is an optional header keyword, `~astropy.wcs.Wcsprm.cunit` may be left blank but otherwise is expected to contain a standard units specification as defined by WCS Paper I. `~astropy.wcs.Wcsprm.unitfix` is available to translate commonly used non-standard units specifications but this must be done as a separate step before invoking `~astropy.wcs.Wcsprm.set`. For celestial axes, if `~astropy.wcs.Wcsprm.cunit` is not blank, `~astropy.wcs.Wcsprm.set` uses ``wcsunits`` to parse it and scale `~astropy.wcs.Wcsprm.cdelt`, `~astropy.wcs.Wcsprm.crval`, and `~astropy.wcs.Wcsprm.cd` to decimal degrees. It then resets `~astropy.wcs.Wcsprm.cunit` to ``"deg"``. For spectral axes, if `~astropy.wcs.Wcsprm.cunit` is not blank, `~astropy.wcs.Wcsprm.set` uses ``wcsunits`` to parse it and scale `~astropy.wcs.Wcsprm.cdelt`, `~astropy.wcs.Wcsprm.crval`, and `~astropy.wcs.Wcsprm.cd` to SI units. It then resets `~astropy.wcs.Wcsprm.cunit` accordingly. `~astropy.wcs.Wcsprm.set` ignores `~astropy.wcs.Wcsprm.cunit` for other coordinate types; `~astropy.wcs.Wcsprm.cunit` may be used to label coordinate values. """ cylfix = """ cylfix() Fixes WCS keyvalues for malformed cylindrical projections. Returns ------- success : int Returns ``0`` for success; ``-1`` if no change required. """ data = """ ``float array`` The array data for the `~astropy.wcs.DistortionLookupTable`. """ data_wtbarr = """ ``double array`` The array data for the BINTABLE. """ dateavg = """ ``string`` Representative mid-point of the date of observation. In ISO format, ``yyyy-mm-ddThh:mm:ss``. See also -------- astropy.wcs.Wcsprm.dateobs """ dateobs = """ ``string`` Start of the date of observation. In ISO format, ``yyyy-mm-ddThh:mm:ss``. See also -------- astropy.wcs.Wcsprm.dateavg """ datfix = """ datfix() Translates the old ``DATE-OBS`` date format to year-2000 standard form ``(yyyy-mm-ddThh:mm:ss)`` and derives ``MJD-OBS`` from it if not already set. Alternatively, if `~astropy.wcs.Wcsprm.mjdobs` is set and `~astropy.wcs.Wcsprm.dateobs` isn't, then `~astropy.wcs.Wcsprm.datfix` derives `~astropy.wcs.Wcsprm.dateobs` from it. If both are set but disagree by more than half a day then `ValueError` is raised. Returns ------- success : int Returns ``0`` for success; ``-1`` if no change required. """ delta = """ ``double array[M]`` (read-only) Interpolated indices into the coord array. Array of interpolated indices into the coordinate array such that Upsilon_m, as defined in Paper III, is equal to (`~astropy.wcs.Tabprm.p0` [m] + 1) + delta[m]. """ det2im = """ Convert detector coordinates to image plane coordinates. """ det2im1 = """ A `~astropy.wcs.DistortionLookupTable` object for detector to image plane correction in the *x*-axis. """ det2im2 = """ A `~astropy.wcs.DistortionLookupTable` object for detector to image plane correction in the *y*-axis. """ dims = """ ``int array[ndim]`` (read-only) The dimensions of the tabular array `~astropy.wcs.Wtbarr.data`. """ DistortionLookupTable = """ DistortionLookupTable(*table*, *crpix*, *crval*, *cdelt*) Represents a single lookup table for a `distortion paper`_ transformation. Parameters ---------- table : 2-dimensional array The distortion lookup table. crpix : 2-tuple The distortion array reference pixel crval : 2-tuple The image array pixel coordinate cdelt : 2-tuple The grid step size """ dsun_obs = """ ``double`` Distance between the centre of the Sun and the observer (m). If undefined, this is set to `None`. """ equinox = """ ``double`` The equinox associated with dynamical equatorial or ecliptic coordinate systems. ``EQUINOXa`` (or ``EPOCH`` in older headers). Not applicable to ICRS equatorial or ecliptic coordinates. An undefined value is represented by NaN. """ extlev = """ ``int`` (read-only) ``EXTLEV`` identifying the binary table extension. """ extnam = """ ``str`` (read-only) ``EXTNAME`` identifying the binary table extension. """ extrema = """ ``double array[K_M]...[K_2][2][M]`` (read-only) An array recording the minimum and maximum value of each element of the coordinate vector in each row of the coordinate array, with the dimensions:: (K_M, ... K_2, 2, M) (see `~astropy.wcs.Tabprm.K`). The minimum is recorded in the first element of the compressed K_1 dimension, then the maximum. This array is used by the inverse table lookup function to speed up table searches. """ extver = """ ``int`` (read-only) ``EXTVER`` identifying the binary table extension. """ find_all_wcs = """ find_all_wcs(relax=0, keysel=0) Find all WCS transformations in the header. Parameters ---------- header : str The raw FITS header data. relax : bool or int Degree of permissiveness: - `False`: Recognize only FITS keywords defined by the published WCS standard. - `True`: Admit all recognized informal extensions of the WCS standard. - `int`: a bit field selecting specific extensions to accept. See :ref:`astropy:relaxread` for details. keysel : sequence of flags Used to restrict the keyword types considered: - ``WCSHDR_IMGHEAD``: Image header keywords. - ``WCSHDR_BIMGARR``: Binary table image array. - ``WCSHDR_PIXLIST``: Pixel list keywords. If zero, there is no restriction. If -1, `wcspih` is called, rather than `wcstbh`. Returns ------- wcs_list : list of `~astropy.wcs.Wcsprm` """ fix = """ fix(translate_units='', naxis=0) Applies all of the corrections handled separately by `~astropy.wcs.Wcsprm.datfix`, `~astropy.wcs.Wcsprm.unitfix`, `~astropy.wcs.Wcsprm.celfix`, `~astropy.wcs.Wcsprm.spcfix`, `~astropy.wcs.Wcsprm.cylfix` and `~astropy.wcs.Wcsprm.cdfix`. Parameters ---------- translate_units : str, optional Specify which potentially unsafe translations of non-standard unit strings to perform. By default, performs all. Although ``"S"`` is commonly used to represent seconds, its translation to ``"s"`` is potentially unsafe since the standard recognizes ``"S"`` formally as Siemens, however rarely that may be used. The same applies to ``"H"`` for hours (Henry), and ``"D"`` for days (Debye). This string controls what to do in such cases, and is case-insensitive. - If the string contains ``"s"``, translate ``"S"`` to ``"s"``. - If the string contains ``"h"``, translate ``"H"`` to ``"h"``. - If the string contains ``"d"``, translate ``"D"`` to ``"d"``. Thus ``''`` doesn't do any unsafe translations, whereas ``'shd'`` does all of them. naxis : int array, optional Image axis lengths. If this array is set to zero or ``None``, then `~astropy.wcs.Wcsprm.cylfix` will not be invoked. Returns ------- status : dict Returns a dictionary containing the following keys, each referring to a status string for each of the sub-fix functions that were called: - `~astropy.wcs.Wcsprm.cdfix` - `~astropy.wcs.Wcsprm.datfix` - `~astropy.wcs.Wcsprm.unitfix` - `~astropy.wcs.Wcsprm.celfix` - `~astropy.wcs.Wcsprm.spcfix` - `~astropy.wcs.Wcsprm.cylfix` """ get_offset = """ get_offset(x, y) -> (x, y) Returns the offset as defined in the distortion lookup table. Returns ------- coordinate : (2,) tuple The offset from the distortion table for pixel point (*x*, *y*). """ get_cdelt = """ get_cdelt() -> numpy.ndarray Coordinate increments (``CDELTia``) for each coord axis as ``double array[naxis]``. Returns the ``CDELT`` offsets in read-only form. Unlike the `~astropy.wcs.Wcsprm.cdelt` property, this works even when the header specifies the linear transformation matrix in one of the alternative ``CDi_ja`` or ``CROTAia`` forms. This is useful when you want access to the linear transformation matrix, but don't care how it was specified in the header. """ get_pc = """ get_pc() -> numpy.ndarray Returns the ``PC`` matrix in read-only form as ``double array[naxis][naxis]``. Unlike the `~astropy.wcs.Wcsprm.pc` property, this works even when the header specifies the linear transformation matrix in one of the alternative ``CDi_ja`` or ``CROTAia`` forms. This is useful when you want access to the linear transformation matrix, but don't care how it was specified in the header. """ get_ps = """ get_ps() -> list Returns ``PSi_ma`` keywords for each *i* and *m* as list of tuples. Returns ------- ps : list Returned as a list of tuples of the form (*i*, *m*, *value*): - *i*: int. Axis number, as in ``PSi_ma``, (i.e. 1-relative) - *m*: int. Parameter number, as in ``PSi_ma``, (i.e. 0-relative) - *value*: string. Parameter value. See also -------- astropy.wcs.Wcsprm.set_ps : Set ``PSi_ma`` values """ get_pv = """ get_pv() -> list Returns ``PVi_ma`` keywords for each *i* and *m* as list of tuples. Returns ------- sequence of tuple Returned as a list of tuples of the form (*i*, *m*, *value*): - *i*: int. Axis number, as in ``PVi_ma``, (i.e. 1-relative) - *m*: int. Parameter number, as in ``PVi_ma``, (i.e. 0-relative) - *value*: string. Parameter value. See also -------- astropy.wcs.Wcsprm.set_pv : Set ``PVi_ma`` values Notes ----- Note that, if they were not given, `~astropy.wcs.Wcsprm.set` resets the entries for ``PVi_1a``, ``PVi_2a``, ``PVi_3a``, and ``PVi_4a`` for longitude axis *i* to match (``phi_0``, ``theta_0``), the native longitude and latitude of the reference point given by ``LONPOLEa`` and ``LATPOLEa``. """ has_cd = """ has_cd() -> bool Returns `True` if ``CDi_ja`` is present. ``CDi_ja`` is an alternate specification of the linear transformation matrix, maintained for historical compatibility. Matrix elements in the IRAF convention are equivalent to the product ``CDi_ja = CDELTia * PCi_ja``, but the defaults differ from that of the ``PCi_ja`` matrix. If one or more ``CDi_ja`` keywords are present then all unspecified ``CDi_ja`` default to zero. If no ``CDi_ja`` (or ``CROTAia``) keywords are present, then the header is assumed to be in ``PCi_ja`` form whether or not any ``PCi_ja`` keywords are present since this results in an interpretation of ``CDELTia`` consistent with the original FITS specification. While ``CDi_ja`` may not formally co-exist with ``PCi_ja``, it may co-exist with ``CDELTia`` and ``CROTAia`` which are to be ignored. See also -------- astropy.wcs.Wcsprm.cd : Get the raw ``CDi_ja`` values. """ has_cdi_ja = """ has_cdi_ja() -> bool Alias for `~astropy.wcs.Wcsprm.has_cd`. Maintained for backward compatibility. """ has_crota = """ has_crota() -> bool Returns `True` if ``CROTAia`` is present. ``CROTAia`` is an alternate specification of the linear transformation matrix, maintained for historical compatibility. In the AIPS convention, ``CROTAia`` may only be associated with the latitude axis of a celestial axis pair. It specifies a rotation in the image plane that is applied *after* the ``CDELTia``; any other ``CROTAia`` keywords are ignored. ``CROTAia`` may not formally co-exist with ``PCi_ja``. ``CROTAia`` and ``CDELTia`` may formally co-exist with ``CDi_ja`` but if so are to be ignored. See also -------- astropy.wcs.Wcsprm.crota : Get the raw ``CROTAia`` values """ has_crotaia = """ has_crotaia() -> bool Alias for `~astropy.wcs.Wcsprm.has_crota`. Maintained for backward compatibility. """ has_pc = """ has_pc() -> bool Returns `True` if ``PCi_ja`` is present. ``PCi_ja`` is the recommended way to specify the linear transformation matrix. See also -------- astropy.wcs.Wcsprm.pc : Get the raw ``PCi_ja`` values """ has_pci_ja = """ has_pci_ja() -> bool Alias for `~astropy.wcs.Wcsprm.has_pc`. Maintained for backward compatibility. """ hgln_obs = """ ``double`` Stonyhurst heliographic longitude of the observer. If undefined, this is set to `None`. """ hglt_obs = """ ``double`` Heliographic latitude (Carrington or Stonyhurst) of the observer (deg). If undefined, this is set to `None`. """ i = """ ``int`` (read-only) Image axis number. """ imgpix_matrix = """ ``double array[2][2]`` (read-only) Inverse of the ``CDELT`` or ``PC`` matrix. Inverse containing the product of the ``CDELTia`` diagonal matrix and the ``PCi_ja`` matrix. """ is_unity = """ is_unity() -> bool Returns `True` if the linear transformation matrix (`~astropy.wcs.Wcsprm.cd`) is unity. """ K = """ ``int array[M]`` (read-only) The lengths of the axes of the coordinate array. An array of length `M` whose elements record the lengths of the axes of the coordinate array and of each indexing vector. """ kind = """ ``str`` (read-only) ``wcstab`` array type. Character identifying the ``wcstab`` array type: - ``'c'``: coordinate array, - ``'i'``: index vector. """ lat = """ ``int`` (read-only) The index into the world coord array containing latitude values. """ latpole = """ ``double`` The native latitude of the celestial pole, ``LATPOLEa`` (deg). """ lattyp = """ ``string`` (read-only) Celestial axis type for latitude. For example, "RA", "DEC", "GLON", "GLAT", etc. extracted from "RA--", "DEC-", "GLON", "GLAT", etc. in the first four characters of ``CTYPEia`` but with trailing dashes removed. """ lng = """ ``int`` (read-only) The index into the world coord array containing longitude values. """ lngtyp = """ ``string`` (read-only) Celestial axis type for longitude. For example, "RA", "DEC", "GLON", "GLAT", etc. extracted from "RA--", "DEC-", "GLON", "GLAT", etc. in the first four characters of ``CTYPEia`` but with trailing dashes removed. """ lonpole = """ ``double`` The native longitude of the celestial pole. ``LONPOLEa`` (deg). """ M = """ ``int`` (read-only) Number of tabular coordinate axes. """ m = """ ``int`` (read-only) ``wcstab`` axis number for index vectors. """ map = """ ``int array[M]`` Association between axes. A vector of length `~astropy.wcs.Tabprm.M` that defines the association between axis *m* in the *M*-dimensional coordinate array (1 <= *m* <= *M*) and the indices of the intermediate world coordinate and world coordinate arrays. When the intermediate and world coordinate arrays contain the full complement of coordinate elements in image-order, as will usually be the case, then ``map[m-1] == i-1`` for axis *i* in the *N*-dimensional image (1 <= *i* <= *N*). In terms of the FITS keywords:: map[PVi_3a - 1] == i - 1. However, a different association may result if the intermediate coordinates, for example, only contains a (relevant) subset of intermediate world coordinate elements. For example, if *M* == 1 for an image with *N* > 1, it is possible to fill the intermediate coordinates with the relevant coordinate element with ``nelem`` set to 1. In this case ``map[0] = 0`` regardless of the value of *i*. """ mix = """ mix(mixpix, mixcel, vspan, vstep, viter, world, pixcrd, origin) Given either the celestial longitude or latitude plus an element of the pixel coordinate, solves for the remaining elements by iterating on the unknown celestial coordinate element using `~astropy.wcs.Wcsprm.s2p`. Parameters ---------- mixpix : int Which element on the pixel coordinate is given. mixcel : int Which element of the celestial coordinate is given. If *mixcel* = ``1``, celestial longitude is given in ``world[self.lng]``, latitude returned in ``world[self.lat]``. If *mixcel* = ``2``, celestial latitude is given in ``world[self.lat]``, longitude returned in ``world[self.lng]``. vspan : (float, float) Solution interval for the celestial coordinate, in degrees. The ordering of the two limits is irrelevant. Longitude ranges may be specified with any convenient normalization, for example ``(-120,+120)`` is the same as ``(240,480)``, except that the solution will be returned with the same normalization, i.e. lie within the interval specified. vstep : float Step size for solution search, in degrees. If ``0``, a sensible, although perhaps non-optimal default will be used. viter : int If a solution is not found then the step size will be halved and the search recommenced. *viter* controls how many times the step size is halved. The allowed range is 5 - 10. world : ndarray World coordinate elements as ``double array[naxis]``. ``world[self.lng]`` and ``world[self.lat]`` are the celestial longitude and latitude, in degrees. Which is given and which returned depends on the value of *mixcel*. All other elements are given. The results will be written to this array in-place. pixcrd : ndarray Pixel coordinates as ``double array[naxis]``. The element indicated by *mixpix* is given and the remaining elements will be written in-place. {} Returns ------- result : dict Returns a dictionary with the following keys: - *phi* (``double array[naxis]``) - *theta* (``double array[naxis]``) - Longitude and latitude in the native coordinate system of the projection, in degrees. - *imgcrd* (``double array[naxis]``) - Image coordinate elements. ``imgcrd[self.lng]`` and ``imgcrd[self.lat]`` are the projected *x*- and *y*-coordinates, in decimal degrees. - *world* (``double array[naxis]``) - Another reference to the *world* argument passed in. Raises ------ MemoryError Memory allocation failed. SingularMatrixError Linear transformation matrix is singular. InconsistentAxisTypesError Inconsistent or unrecognized coordinate axis types. ValueError Invalid parameter value. InvalidTransformError Invalid coordinate transformation parameters. InvalidTransformError Ill-conditioned coordinate transformation parameters. InvalidCoordinateError Invalid world coordinate. NoSolutionError No solution found in the specified interval. See also -------- astropy.wcs.Wcsprm.lat, astropy.wcs.Wcsprm.lng Get the axes numbers for latitude and longitude Notes ----- Initially, the specified solution interval is checked to see if it's a \"crossing\" interval. If it isn't, a search is made for a crossing solution by iterating on the unknown celestial coordinate starting at the upper limit of the solution interval and decrementing by the specified step size. A crossing is indicated if the trial value of the pixel coordinate steps through the value specified. If a crossing interval is found then the solution is determined by a modified form of \"regula falsi\" division of the crossing interval. If no crossing interval was found within the specified solution interval then a search is made for a \"non-crossing\" solution as may arise from a point of tangency. The process is complicated by having to make allowance for the discontinuities that occur in all map projections. Once one solution has been determined others may be found by subsequent invocations of `~astropy.wcs.Wcsprm.mix` with suitably restricted solution intervals. Note the circumstance that arises when the solution point lies at a native pole of a projection in which the pole is represented as a finite curve, for example the zenithals and conics. In such cases two or more valid solutions may exist but `~astropy.wcs.Wcsprm.mix` only ever returns one. Because of its generality, `~astropy.wcs.Wcsprm.mix` is very compute-intensive. For compute-limited applications, more efficient special-case solvers could be written for simple projections, for example non-oblique cylindrical projections. """.format(ORIGIN()) mjdavg = """ ``double`` Modified Julian Date corresponding to ``DATE-AVG``. ``(MJD = JD - 2400000.5)``. An undefined value is represented by NaN. See also -------- astropy.wcs.Wcsprm.mjdobs """ mjdobs = """ ``double`` Modified Julian Date corresponding to ``DATE-OBS``. ``(MJD = JD - 2400000.5)``. An undefined value is represented by NaN. See also -------- astropy.wcs.Wcsprm.mjdavg """ name = """ ``string`` The name given to the coordinate representation ``WCSNAMEa``. """ naxis = """ ``int`` (read-only) The number of axes (pixel and coordinate). Given by the ``NAXIS`` or ``WCSAXESa`` keyvalues. The number of coordinate axes is determined at parsing time, and can not be subsequently changed. It is determined from the highest of the following: 1. ``NAXIS`` 2. ``WCSAXESa`` 3. The highest axis number in any parameterized WCS keyword. The keyvalue, as well as the keyword, must be syntactically valid otherwise it will not be considered. If none of these keyword types is present, i.e. if the header only contains auxiliary WCS keywords for a particular coordinate representation, then no coordinate description is constructed for it. This value may differ for different coordinate representations of the same image. """ nc = """ ``int`` (read-only) Total number of coord vectors in the coord array. Total number of coordinate vectors in the coordinate array being the product K_1 * K_2 * ... * K_M. """ ndim = """ ``int`` (read-only) Expected dimensionality of the ``wcstab`` array. """ obsgeo = """ ``double array[3]`` Location of the observer in a standard terrestrial reference frame. ``OBSGEO-X``, ``OBSGEO-Y``, ``OBSGEO-Z`` (in meters). An undefined value is represented by NaN. """ p0 = """ ``int array[M]`` Interpolated indices into the coordinate array. Vector of length `~astropy.wcs.Tabprm.M` of interpolated indices into the coordinate array such that Upsilon_m, as defined in Paper III, is equal to ``(p0[m] + 1) + delta[m]``. """ p2s = """ p2s(pixcrd, origin) Converts pixel to world coordinates. Parameters ---------- pixcrd : ndarray Array of pixel coordinates as ``double array[ncoord][nelem]``. {} Returns ------- result : dict Returns a dictionary with the following keys: - *imgcrd*: ndarray - Array of intermediate world coordinates as ``double array[ncoord][nelem]``. For celestial axes, ``imgcrd[][self.lng]`` and ``imgcrd[][self.lat]`` are the projected *x*-, and *y*-coordinates, in pseudo degrees. For spectral axes, ``imgcrd[][self.spec]`` is the intermediate spectral coordinate, in SI units. - *phi*: ndarray - Array as ``double array[ncoord]``. - *theta*: ndarray - Longitude and latitude in the native coordinate system of the projection, in degrees, as ``double array[ncoord]``. - *world*: ndarray - Array of world coordinates as ``double array[ncoord][nelem]``. For celestial axes, ``world[][self.lng]`` and ``world[][self.lat]`` are the celestial longitude and latitude, in degrees. For spectral axes, ``world[][self.spec]`` is the intermediate spectral coordinate, in SI units. - *stat*: ndarray - Status return value for each coordinate as ``int array[ncoord]``. ``0`` for success, ``1+`` for invalid pixel coordinate. Raises ------ MemoryError Memory allocation failed. SingularMatrixError Linear transformation matrix is singular. InconsistentAxisTypesError Inconsistent or unrecognized coordinate axis types. ValueError Invalid parameter value. ValueError *x*- and *y*-coordinate arrays are not the same size. InvalidTransformError Invalid coordinate transformation parameters. InvalidTransformError Ill-conditioned coordinate transformation parameters. See also -------- astropy.wcs.Wcsprm.lat, astropy.wcs.Wcsprm.lng Definition of the latitude and longitude axes """.format(ORIGIN()) p4_pix2foc = """ p4_pix2foc(*pixcrd, origin*) -> ``double array[ncoord][nelem]`` Convert pixel coordinates to focal plane coordinates using `distortion paper`_ lookup-table correction. Parameters ---------- pixcrd : ndarray Array of pixel coordinates as ``double array[ncoord][nelem]``. {} Returns ------- foccrd : ndarray Returns an array of focal plane coordinates as ``double array[ncoord][nelem]``. Raises ------ MemoryError Memory allocation failed. ValueError Invalid coordinate transformation parameters. """.format(ORIGIN()) pc = """ ``double array[naxis][naxis]`` The ``PCi_ja`` (pixel coordinate) transformation matrix. The order is:: [[PC1_1, PC1_2], [PC2_1, PC2_2]] For historical compatibility, three alternate specifications of the linear transformations are available in wcslib. The canonical ``PCi_ja`` with ``CDELTia``, ``CDi_ja``, and the deprecated ``CROTAia`` keywords. Although the latter may not formally co-exist with ``PCi_ja``, the approach here is simply to ignore them if given in conjunction with ``PCi_ja``. `~astropy.wcs.Wcsprm.has_pc`, `~astropy.wcs.Wcsprm.has_cd` and `~astropy.wcs.Wcsprm.has_crota` can be used to determine which of these alternatives are present in the header. These alternate specifications of the linear transformation matrix are translated immediately to ``PCi_ja`` by `~astropy.wcs.Wcsprm.set` and are nowhere visible to the lower-level routines. In particular, `~astropy.wcs.Wcsprm.set` resets `~astropy.wcs.Wcsprm.cdelt` to unity if ``CDi_ja`` is present (and no ``PCi_ja``). If no ``CROTAia`` is associated with the latitude axis, `~astropy.wcs.Wcsprm.set` reverts to a unity ``PCi_ja`` matrix. """ phi0 = """ ``double`` The native latitude of the fiducial point. The point whose celestial coordinates are given in ``ref[1:2]``. If undefined (NaN) the initialization routine, `~astropy.wcs.Wcsprm.set`, will set this to a projection-specific default. See also -------- astropy.wcs.Wcsprm.theta0 """ pix2foc = """ pix2foc(*pixcrd, origin*) -> ``double array[ncoord][nelem]`` Perform both `SIP`_ polynomial and `distortion paper`_ lookup-table correction in parallel. Parameters ---------- pixcrd : ndarray Array of pixel coordinates as ``double array[ncoord][nelem]``. {} Returns ------- foccrd : ndarray Returns an array of focal plane coordinates as ``double array[ncoord][nelem]``. Raises ------ MemoryError Memory allocation failed. ValueError Invalid coordinate transformation parameters. """.format(ORIGIN()) piximg_matrix = """ ``double array[2][2]`` (read-only) Matrix containing the product of the ``CDELTia`` diagonal matrix and the ``PCi_ja`` matrix. """ print_contents = """ print_contents() Print the contents of the `~astropy.wcs.Wcsprm` object to stdout. Probably only useful for debugging purposes, and may be removed in the future. To get a string of the contents, use `repr`. """ print_contents_tabprm = """ print_contents() Print the contents of the `~astropy.wcs.Tabprm` object to stdout. Probably only useful for debugging purposes, and may be removed in the future. To get a string of the contents, use `repr`. """ print_contents_wtbarr = """ print_contents() Print the contents of the `~astropy.wcs.Wtbarr` object to stdout. Probably only useful for debugging purposes, and may be removed in the future. To get a string of the contents, use `repr`. """ radesys = """ ``string`` The equatorial or ecliptic coordinate system type, ``RADESYSa``. """ restfrq = """ ``double`` Rest frequency (Hz) from ``RESTFRQa``. An undefined value is represented by NaN. """ restwav = """ ``double`` Rest wavelength (m) from ``RESTWAVa``. An undefined value is represented by NaN. """ row = """ ``int`` (read-only) Table row number. """ rsun_ref = """ ``double`` Reference radius of the Sun used in coordinate calculations (m). If undefined, this is set to `None`. """ s2p = """ s2p(world, origin) Transforms world coordinates to pixel coordinates. Parameters ---------- world : ndarray Array of world coordinates, in decimal degrees, as ``double array[ncoord][nelem]``. {} Returns ------- result : dict Returns a dictionary with the following keys: - *phi*: ``double array[ncoord]`` - *theta*: ``double array[ncoord]`` - Longitude and latitude in the native coordinate system of the projection, in degrees. - *imgcrd*: ``double array[ncoord][nelem]`` - Array of intermediate world coordinates. For celestial axes, ``imgcrd[][self.lng]`` and ``imgcrd[][self.lat]`` are the projected *x*-, and *y*-coordinates, in pseudo \"degrees\". For quadcube projections with a ``CUBEFACE`` axis, the face number is also returned in ``imgcrd[][self.cubeface]``. For spectral axes, ``imgcrd[][self.spec]`` is the intermediate spectral coordinate, in SI units. - *pixcrd*: ``double array[ncoord][nelem]`` - Array of pixel coordinates. Pixel coordinates are zero-based. - *stat*: ``int array[ncoord]`` - Status return value for each coordinate. ``0`` for success, ``1+`` for invalid pixel coordinate. Raises ------ MemoryError Memory allocation failed. SingularMatrixError Linear transformation matrix is singular. InconsistentAxisTypesError Inconsistent or unrecognized coordinate axis types. ValueError Invalid parameter value. InvalidTransformError Invalid coordinate transformation parameters. InvalidTransformError Ill-conditioned coordinate transformation parameters. See also -------- astropy.wcs.Wcsprm.lat, astropy.wcs.Wcsprm.lng Definition of the latitude and longitude axes """.format(ORIGIN()) sense = """ ``int array[M]`` +1 if monotonically increasing, -1 if decreasing. A vector of length `~astropy.wcs.Tabprm.M` whose elements indicate whether the corresponding indexing vector is monotonically increasing (+1), or decreasing (-1). """ set = """ set() Sets up a WCS object for use according to information supplied within it. Note that this routine need not be called directly; it will be invoked by `~astropy.wcs.Wcsprm.p2s` and `~astropy.wcs.Wcsprm.s2p` if necessary. Some attributes that are based on other attributes (such as `~astropy.wcs.Wcsprm.lattyp` on `~astropy.wcs.Wcsprm.ctype`) may not be correct until after `~astropy.wcs.Wcsprm.set` is called. `~astropy.wcs.Wcsprm.set` strips off trailing blanks in all string members. `~astropy.wcs.Wcsprm.set` recognizes the ``NCP`` projection and converts it to the equivalent ``SIN`` projection and it also recognizes ``GLS`` as a synonym for ``SFL``. It does alias translation for the AIPS spectral types (``FREQ-LSR``, ``FELO-HEL``, etc.) but without changing the input header keywords. Raises ------ MemoryError Memory allocation failed. SingularMatrixError Linear transformation matrix is singular. InconsistentAxisTypesError Inconsistent or unrecognized coordinate axis types. ValueError Invalid parameter value. InvalidTransformError Invalid coordinate transformation parameters. InvalidTransformError Ill-conditioned coordinate transformation parameters. """ set_tabprm = """ set() Allocates memory for work arrays. Also sets up the class according to information supplied within it. Note that this routine need not be called directly; it will be invoked by functions that need it. Raises ------ MemoryError Memory allocation failed. InvalidTabularParametersError Invalid tabular parameters. """ set_ps = """ set_ps(ps) Sets ``PSi_ma`` keywords for each *i* and *m*. Parameters ---------- ps : sequence of tuple The input must be a sequence of tuples of the form (*i*, *m*, *value*): - *i*: int. Axis number, as in ``PSi_ma``, (i.e. 1-relative) - *m*: int. Parameter number, as in ``PSi_ma``, (i.e. 0-relative) - *value*: string. Parameter value. See also -------- astropy.wcs.Wcsprm.get_ps """ set_pv = """ set_pv(pv) Sets ``PVi_ma`` keywords for each *i* and *m*. Parameters ---------- pv : list of tuple The input must be a sequence of tuples of the form (*i*, *m*, *value*): - *i*: int. Axis number, as in ``PVi_ma``, (i.e. 1-relative) - *m*: int. Parameter number, as in ``PVi_ma``, (i.e. 0-relative) - *value*: float. Parameter value. See also -------- astropy.wcs.Wcsprm.get_pv """ sip = """ Get/set the `~astropy.wcs.Sip` object for performing `SIP`_ distortion correction. """ Sip = """ Sip(*a, b, ap, bp, crpix*) The `~astropy.wcs.Sip` class performs polynomial distortion correction using the `SIP`_ convention in both directions. Parameters ---------- a : ndarray The ``A_i_j`` polynomial for pixel to focal plane transformation as ``double array[m+1][m+1]``. Its size must be (*m* + 1, *m* + 1) where *m* = ``A_ORDER``. b : ndarray The ``B_i_j`` polynomial for pixel to focal plane transformation as ``double array[m+1][m+1]``. Its size must be (*m* + 1, *m* + 1) where *m* = ``B_ORDER``. ap : ndarray The ``AP_i_j`` polynomial for pixel to focal plane transformation as ``double array[m+1][m+1]``. Its size must be (*m* + 1, *m* + 1) where *m* = ``AP_ORDER``. bp : ndarray The ``BP_i_j`` polynomial for pixel to focal plane transformation as ``double array[m+1][m+1]``. Its size must be (*m* + 1, *m* + 1) where *m* = ``BP_ORDER``. crpix : ndarray The reference pixel as ``double array[2]``. Notes ----- Shupe, D. L., M. Moshir, J. Li, D. Makovoz and R. Narron. 2005. "The SIP Convention for Representing Distortion in FITS Image Headers." ADASS XIV. """ sip_foc2pix = """ sip_foc2pix(*foccrd, origin*) -> ``double array[ncoord][nelem]`` Convert focal plane coordinates to pixel coordinates using the `SIP`_ polynomial distortion convention. Parameters ---------- foccrd : ndarray Array of focal plane coordinates as ``double array[ncoord][nelem]``. {} Returns ------- pixcrd : ndarray Returns an array of pixel coordinates as ``double array[ncoord][nelem]``. Raises ------ MemoryError Memory allocation failed. ValueError Invalid coordinate transformation parameters. """.format(ORIGIN()) sip_pix2foc = """ sip_pix2foc(*pixcrd, origin*) -> ``double array[ncoord][nelem]`` Convert pixel coordinates to focal plane coordinates using the `SIP`_ polynomial distortion convention. Parameters ---------- pixcrd : ndarray Array of pixel coordinates as ``double array[ncoord][nelem]``. {} Returns ------- foccrd : ndarray Returns an array of focal plane coordinates as ``double array[ncoord][nelem]``. Raises ------ MemoryError Memory allocation failed. ValueError Invalid coordinate transformation parameters. """.format(ORIGIN()) spcfix = """ spcfix() -> int Translates AIPS-convention spectral coordinate types. {``FREQ``, ``VELO``, ``FELO``}-{``OBS``, ``HEL``, ``LSR``} (e.g. ``FREQ-LSR``, ``VELO-OBS``, ``FELO-HEL``) Returns ------- success : int Returns ``0`` for success; ``-1`` if no change required. """ spec = """ ``int`` (read-only) The index containing the spectral axis values. """ specsys = """ ``string`` Spectral reference frame (standard of rest), ``SPECSYSa``. See also -------- astropy.wcs.Wcsprm.ssysobs, astropy.wcs.Wcsprm.velosys """ sptr = """ sptr(ctype, i=-1) Translates the spectral axis in a WCS object. For example, a ``FREQ`` axis may be translated into ``ZOPT-F2W`` and vice versa. Parameters ---------- ctype : str Required spectral ``CTYPEia``, maximum of 8 characters. The first four characters are required to be given and are never modified. The remaining four, the algorithm code, are completely determined by, and must be consistent with, the first four characters. Wildcarding may be used, i.e. if the final three characters are specified as ``\"???\"``, or if just the eighth character is specified as ``\"?\"``, the correct algorithm code will be substituted and returned. i : int Index of the spectral axis (0-relative). If ``i < 0`` (or not provided), it will be set to the first spectral axis identified from the ``CTYPE`` keyvalues in the FITS header. Raises ------ MemoryError Memory allocation failed. SingularMatrixError Linear transformation matrix is singular. InconsistentAxisTypesError Inconsistent or unrecognized coordinate axis types. ValueError Invalid parameter value. InvalidTransformError Invalid coordinate transformation parameters. InvalidTransformError Ill-conditioned coordinate transformation parameters. InvalidSubimageSpecificationError Invalid subimage specification (no spectral axis). """ ssysobs = """ ``string`` Spectral reference frame. The spectral reference frame in which there is no differential variation in the spectral coordinate across the field-of-view, ``SSYSOBSa``. See also -------- astropy.wcs.Wcsprm.specsys, astropy.wcs.Wcsprm.velosys """ ssyssrc = """ ``string`` Spectral reference frame for redshift. The spectral reference frame (standard of rest) in which the redshift was measured, ``SSYSSRCa``. """ sub = """ sub(axes) Extracts the coordinate description for a subimage from a `~astropy.wcs.WCS` object. The world coordinate system of the subimage must be separable in the sense that the world coordinates at any point in the subimage must depend only on the pixel coordinates of the axes extracted. In practice, this means that the ``PCi_ja`` matrix of the original image must not contain non-zero off-diagonal terms that associate any of the subimage axes with any of the non-subimage axes. `sub` can also add axes to a wcsprm object. The new axes will be created using the defaults set by the Wcsprm constructor which produce a simple, unnamed, linear axis with world coordinates equal to the pixel coordinate. These default values can be changed before invoking `set`. Parameters ---------- axes : int or a sequence. - If an int, include the first *N* axes in their original order. - If a sequence, may contain a combination of image axis numbers (1-relative) or special axis identifiers (see below). Order is significant; ``axes[0]`` is the axis number of the input image that corresponds to the first axis in the subimage, etc. Use an axis number of 0 to create a new axis using the defaults. - If ``0``, ``[]`` or ``None``, do a deep copy. Coordinate axes types may be specified using either strings or special integer constants. The available types are: - ``'longitude'`` / ``WCSSUB_LONGITUDE``: Celestial longitude - ``'latitude'`` / ``WCSSUB_LATITUDE``: Celestial latitude - ``'cubeface'`` / ``WCSSUB_CUBEFACE``: Quadcube ``CUBEFACE`` axis - ``'spectral'`` / ``WCSSUB_SPECTRAL``: Spectral axis - ``'stokes'`` / ``WCSSUB_STOKES``: Stokes axis - ``'celestial'`` / ``WCSSUB_CELESTIAL``: An alias for the combination of ``'longitude'``, ``'latitude'`` and ``'cubeface'``. Returns ------- new_wcs : `~astropy.wcs.WCS` object Raises ------ MemoryError Memory allocation failed. InvalidSubimageSpecificationError Invalid subimage specification (no spectral axis). NonseparableSubimageCoordinateSystemError Non-separable subimage coordinate system. Notes ----- Combinations of subimage axes of particular types may be extracted in the same order as they occur in the input image by combining the integer constants with the 'binary or' (``|``) operator. For example:: wcs.sub([WCSSUB_LONGITUDE | WCSSUB_LATITUDE | WCSSUB_SPECTRAL]) would extract the longitude, latitude, and spectral axes in the same order as the input image. If one of each were present, the resulting object would have three dimensions. For convenience, ``WCSSUB_CELESTIAL`` is defined as the combination ``WCSSUB_LONGITUDE | WCSSUB_LATITUDE | WCSSUB_CUBEFACE``. The codes may also be negated to extract all but the types specified, for example:: wcs.sub([ WCSSUB_LONGITUDE, WCSSUB_LATITUDE, WCSSUB_CUBEFACE, -(WCSSUB_SPECTRAL | WCSSUB_STOKES)]) The last of these specifies all axis types other than spectral or Stokes. Extraction is done in the order specified by ``axes``, i.e. a longitude axis (if present) would be extracted first (via ``axes[0]``) and not subsequently (via ``axes[3]``). Likewise for the latitude and cubeface axes in this example. The number of dimensions in the returned object may be less than or greater than the length of ``axes``. However, it will never exceed the number of axes in the input image. """ tab = """ ``list of Tabprm`` Tabular coordinate objects. A list of tabular coordinate objects associated with this WCS. """ Tabprm = """ A class to store the information related to tabular coordinates, i.e., coordinates that are defined via a lookup table. This class can not be constructed directly from Python, but instead is returned from `~astropy.wcs.Wcsprm.tab`. """ theta0 = """ ``double`` The native longitude of the fiducial point. The point whose celestial coordinates are given in ``ref[1:2]``. If undefined (NaN) the initialization routine, `~astropy.wcs.Wcsprm.set`, will set this to a projection-specific default. See also -------- astropy.wcs.Wcsprm.phi0 """ to_header = """ to_header(relax=False) `to_header` translates a WCS object into a FITS header. The details of the header depends on context: - If the `~astropy.wcs.Wcsprm.colnum` member is non-zero then a binary table image array header will be produced. - Otherwise, if the `~astropy.wcs.Wcsprm.colax` member is set non-zero then a pixel list header will be produced. - Otherwise, a primary image or image extension header will be produced. The output header will almost certainly differ from the input in a number of respects: 1. The output header only contains WCS-related keywords. In particular, it does not contain syntactically-required keywords such as ``SIMPLE``, ``NAXIS``, ``BITPIX``, or ``END``. 2. Deprecated (e.g. ``CROTAn``) or non-standard usage will be translated to standard (this is partially dependent on whether ``fix`` was applied). 3. Quantities will be converted to the units used internally, basically SI with the addition of degrees. 4. Floating-point quantities may be given to a different decimal precision. 5. Elements of the ``PCi_j`` matrix will be written if and only if they differ from the unit matrix. Thus, if the matrix is unity then no elements will be written. 6. Additional keywords such as ``WCSAXES``, ``CUNITia``, ``LONPOLEa`` and ``LATPOLEa`` may appear. 7. The original keycomments will be lost, although `~astropy.wcs.Wcsprm.to_header` tries hard to write meaningful comments. 8. Keyword order may be changed. Keywords can be translated between the image array, binary table, and pixel lists forms by manipulating the `~astropy.wcs.Wcsprm.colnum` or `~astropy.wcs.Wcsprm.colax` members of the `~astropy.wcs.WCS` object. Parameters ---------- relax : bool or int Degree of permissiveness: - `False`: Recognize only FITS keywords defined by the published WCS standard. - `True`: Admit all recognized informal extensions of the WCS standard. - `int`: a bit field selecting specific extensions to write. See :ref:`astropy:relaxwrite` for details. Returns ------- header : str Raw FITS header as a string. """ ttype = """ ``str`` (read-only) ``TTYPEn`` identifying the column of the binary table that contains the wcstab array. """ unitfix = """ unitfix(translate_units='') Translates non-standard ``CUNITia`` keyvalues. For example, ``DEG`` -> ``deg``, also stripping off unnecessary whitespace. Parameters ---------- translate_units : str, optional Do potentially unsafe translations of non-standard unit strings. Although ``\"S\"`` is commonly used to represent seconds, its recognizes ``\"S\"`` formally as Siemens, however rarely that may be translation to ``\"s\"`` is potentially unsafe since the standard used. The same applies to ``\"H\"`` for hours (Henry), and ``\"D\"`` for days (Debye). This string controls what to do in such cases, and is case-insensitive. - If the string contains ``\"s\"``, translate ``\"S\"`` to ``\"s\"``. - If the string contains ``\"h\"``, translate ``\"H\"`` to ``\"h\"``. - If the string contains ``\"d\"``, translate ``\"D\"`` to ``\"d\"``. Thus ``''`` doesn't do any unsafe translations, whereas ``'shd'`` does all of them. Returns ------- success : int Returns ``0`` for success; ``-1`` if no change required. """ velangl = """ ``double`` Velocity angle. The angle in degrees that should be used to decompose an observed velocity into radial and transverse components. An undefined value is represented by NaN. """ velosys = """ ``double`` Relative radial velocity. The relative radial velocity (m/s) between the observer and the selected standard of rest in the direction of the celestial reference coordinate, ``VELOSYSa``. An undefined value is represented by NaN. See also -------- astropy.wcs.Wcsprm.specsys, astropy.wcs.Wcsprm.ssysobs """ velref = """ ``int`` AIPS velocity code. From ``VELREF`` keyword. """ wcs = """ A `~astropy.wcs.Wcsprm` object to perform the basic `wcslib`_ WCS transformation. """ Wcs = """ Wcs(*sip, cpdis, wcsprm, det2im*) Wcs objects amalgamate basic WCS (as provided by `wcslib`_), with `SIP`_ and `distortion paper`_ operations. To perform all distortion corrections and WCS transformation, use ``all_pix2world``. Parameters ---------- sip : `~astropy.wcs.Sip` object or None cpdis : (2,) tuple of `~astropy.wcs.DistortionLookupTable` or None wcsprm : `~astropy.wcs.Wcsprm` det2im : (2,) tuple of `~astropy.wcs.DistortionLookupTable` or None """ Wcsprm = """ Wcsprm(header=None, key=' ', relax=False, naxis=2, keysel=0, colsel=None) `~astropy.wcs.Wcsprm` performs the core WCS transformations. .. note:: The members of this object correspond roughly to the key/value pairs in the FITS header. However, they are adjusted and normalized in a number of ways that make performing the WCS transformation easier. Therefore, they can not be relied upon to get the original values in the header. For that, use `astropy.io.fits.Header` directly. The FITS header parsing enforces correct FITS "keyword = value" syntax with regard to the equals sign occurring in columns 9 and 10. However, it does recognize free-format character (NOST 100-2.0, Sect. 5.2.1), integer (Sect. 5.2.3), and floating-point values (Sect. 5.2.4) for all keywords. .. warning:: Many of the attributes of this class require additional processing when modifying underlying C structure. When needed, this additional processing is implemented in attribute setters. Therefore, for mutable attributes, one should always set the attribute rather than a slice of its current value (or its individual elements) since the latter may lead the class instance to be in an invalid state. For example, attribute ``crpix`` of a 2D WCS' ``Wcsprm`` object ``wcs`` should be set as ``wcs.crpix = [crpix1, crpix2]`` instead of ``wcs.crpix[0] = crpix1; wcs.crpix[1] = crpix2]``. Parameters ---------- header : `~astropy.io.fits.Header`, str, or None. If ``None``, the object will be initialized to default values. key : str, optional The key referring to a particular WCS transform in the header. This may be either ``' '`` or ``'A'``-``'Z'`` and corresponds to the ``\"a\"`` part of ``\"CTYPEia\"``. (*key* may only be provided if *header* is also provided.) relax : bool or int, optional Degree of permissiveness: - `False`: Recognize only FITS keywords defined by the published WCS standard. - `True`: Admit all recognized informal extensions of the WCS standard. - `int`: a bit field selecting specific extensions to accept. See :ref:`astropy:relaxread` for details. naxis : int, optional The number of world coordinates axes for the object. (*naxis* may only be provided if *header* is `None`.) keysel : sequence of flag bits, optional Vector of flag bits that may be used to restrict the keyword types considered: - ``WCSHDR_IMGHEAD``: Image header keywords. - ``WCSHDR_BIMGARR``: Binary table image array. - ``WCSHDR_PIXLIST``: Pixel list keywords. If zero, there is no restriction. If -1, the underlying wcslib function ``wcspih()`` is called, rather than ``wcstbh()``. colsel : sequence of int A sequence of table column numbers used to restrict the keywords considered. `None` indicates no restriction. Raises ------ MemoryError Memory allocation failed. ValueError Invalid key. KeyError Key not found in FITS header. """ wtb = """ ``list of Wtbarr`` objects to construct coordinate lookup tables from BINTABLE. """ Wtbarr = """ Classes to construct coordinate lookup tables from a binary table extension (BINTABLE). This class can not be constructed directly from Python, but instead is returned from `~astropy.wcs.Wcsprm.wtb`. """ zsource = """ ``double`` The redshift, ``ZSOURCEa``, of the source. An undefined value is represented by NaN. """ WcsError = """ Base class of all invalid WCS errors. """ SingularMatrix = """ SingularMatrixError() The linear transformation matrix is singular. """ InconsistentAxisTypes = """ InconsistentAxisTypesError() The WCS header inconsistent or unrecognized coordinate axis type(s). """ InvalidTransform = """ InvalidTransformError() The WCS transformation is invalid, or the transformation parameters are invalid. """ InvalidCoordinate = """ InvalidCoordinateError() One or more of the world coordinates is invalid. """ NoSolution = """ NoSolutionError() No solution can be found in the given interval. """ InvalidSubimageSpecification = """ InvalidSubimageSpecificationError() The subimage specification is invalid. """ NonseparableSubimageCoordinateSystem = """ NonseparableSubimageCoordinateSystemError() Non-separable subimage coordinate system. """ NoWcsKeywordsFound = """ NoWcsKeywordsFoundError() No WCS keywords were found in the given header. """ InvalidTabularParameters = """ InvalidTabularParametersError() The given tabular parameters are invalid. """ mjdbeg = """ ``double`` Modified Julian Date corresponding to ``DATE-BEG``. ``(MJD = JD - 2400000.5)``. An undefined value is represented by NaN. See also -------- astropy.wcs.Wcsprm.mjdbeg """ mjdend = """ ``double`` Modified Julian Date corresponding to ``DATE-END``. ``(MJD = JD - 2400000.5)``. An undefined value is represented by NaN. See also -------- astropy.wcs.Wcsprm.mjdend """ mjdref = """ ``double`` Modified Julian Date corresponding to ``DATE-REF``. ``(MJD = JD - 2400000.5)``. An undefined value is represented by NaN. See also -------- astropy.wcs.Wcsprm.dateref """ bepoch = """ ``double`` Equivalent to ``DATE-OBS``. Expressed as a Besselian epoch. See also -------- astropy.wcs.Wcsprm.dateobs """ jepoch = """ ``double`` Equivalent to ``DATE-OBS``. Expressed as a Julian epoch. See also -------- astropy.wcs.Wcsprm.dateobs """ datebeg = """ ``string`` Date at the start of the observation. In ISO format, ``yyyy-mm-ddThh:mm:ss``. See also -------- astropy.wcs.Wcsprm.datebeg """ dateend = """ ``string`` Date at the end of the observation. In ISO format, ``yyyy-mm-ddThh:mm:ss``. See also -------- astropy.wcs.Wcsprm.dateend """ dateref = """ ``string`` Date of a reference epoch relative to which other time measurements refer. See also -------- astropy.wcs.Wcsprm.dateref """ timesys = """ ``string`` Time scale (UTC, TAI, etc.) in which all other time-related auxiliary header values are recorded. Also defines the time scale for an image axis with CTYPEia set to 'TIME'. See also -------- astropy.wcs.Wcsprm.timesys """ trefpos = """ ``string`` Location in space where the recorded time is valid. See also -------- astropy.wcs.Wcsprm.trefpos """ trefdir = """ ``string`` Reference direction used in calculating a pathlength delay. See also -------- astropy.wcs.Wcsprm.trefdir """ timeunit = """ ``string`` Time units in which the following header values are expressed: ``TSTART``, ``TSTOP``, ``TIMEOFFS``, ``TIMSYER``, ``TIMRDER``, ``TIMEDEL``. It also provides the default value for ``CUNITia`` for time axes. See also -------- astropy.wcs.Wcsprm.trefdir """ plephem = """ ``string`` The Solar System ephemeris used for calculating a pathlength delay. See also -------- astropy.wcs.Wcsprm.plephem """ tstart = """ ``double`` equivalent to DATE-BEG expressed as a time in units of TIMEUNIT relative to DATEREF+TIMEOFFS. See also -------- astropy.wcs.Wcsprm.tstop """ tstop = """ ``double`` equivalent to DATE-END expressed as a time in units of TIMEUNIT relative to DATEREF+TIMEOFFS. See also -------- astropy.wcs.Wcsprm.tstart """ telapse = """ ``double`` equivalent to the elapsed time between DATE-BEG and DATE-END, in units of TIMEUNIT. See also -------- astropy.wcs.Wcsprm.tstart """ timeoffs = """ ``double`` Time offset, which may be used, for example, to provide a uniform clock correction for times referenced to DATEREF. See also -------- astropy.wcs.Wcsprm.timeoffs """ timsyer = """ ``double`` the absolute error of the time values, in units of TIMEUNIT. See also -------- astropy.wcs.Wcsprm.timrder """ timrder = """ ``double`` the accuracy of time stamps relative to each other, in units of TIMEUNIT. See also -------- astropy.wcs.Wcsprm.timsyer """ timedel = """ ``double`` the resolution of the time stamps. See also -------- astropy.wcs.Wcsprm.timedel """ timepixr = """ ``double`` relative position of the time stamps in binned time intervals, a value between 0.0 and 1.0. See also -------- astropy.wcs.Wcsprm.timepixr """ obsorbit = """ ``string`` URI, URL, or name of an orbit ephemeris file giving spacecraft coordinates relating to TREFPOS. See also -------- astropy.wcs.Wcsprm.trefpos """ xposure = """ ``double`` effective exposure time in units of TIMEUNIT. See also -------- astropy.wcs.Wcsprm.timeunit """ czphs = """ ``double array[naxis]`` The time at the zero point of a phase axis, ``CSPHSia``. An undefined value is represented by NaN. """ cperi = """ ``double array[naxis]`` period of a phase axis, CPERIia. An undefined value is represented by NaN. """ ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2192562 astropy-5.0.2/astropy/wcs/include/0000755000175100001710000000000000000000000016165 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/include/.gitignore0000644000175100001710000000003100000000000020147 0ustar00vstsdockerdocstrings.h wcsconfig.h ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2192562 astropy-5.0.2/astropy/wcs/include/astropy_wcs/0000755000175100001710000000000000000000000020542 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/include/astropy_wcs/astropy_wcs.h0000644000175100001710000000074200000000000023273 0ustar00vstsdocker/* Author: Michael Droettboom mdroe@stsci.edu */ #ifndef __ASTROPY_WCS_H__ #define __ASTROPY_WCS_H__ /* util.h must be imported first */ #include "pyutil.h" #include "pipeline.h" typedef struct { PyObject_HEAD pipeline_t x; /*@shared@*/ PyObject* py_det2im[2]; /*@null@*/ /*@shared@*/ PyObject* py_sip; /*@shared@*/ PyObject* py_distortion_lookup[2]; /*@null@*/ /*@shared@*/ PyObject* py_wcsprm; } Wcs; #endif /* __ASTROPY_WCS_H__ */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/include/astropy_wcs/astropy_wcs_api.h0000644000175100001710000001126400000000000024125 0ustar00vstsdocker#ifndef ASTROPY_WCS_API_H #define ASTROPY_WCS_API_H #include "wcsconfig.h" #include "pyutil.h" #include "distortion.h" #include "pipeline.h" #include "sip.h" #include "wcs.h" #include "wcsprintf.h" /* HOW TO UPDATE THE PUBLIC API This code uses a table of function pointers to dynamically expose the public API to other code that wants to use astropy.wcs from C. Each function should be: 1) Declared, as usual for C, in a .h file 2) Defined in a .c file that is compiled as part of the _wcs.so file 3) Have a macro that maps the function name to a position in the function table. That macro should go in this file (astropy_wcs_api.h) 4) An entry in the function table, which lives in astropy_wcs_api.c Every time the function signatures change, or functions are added or removed from the table, the value of REVISION should be incremented. This allows for a rudimentary version check upon dynamic linking to the astropy._wcs module. */ #define REVISION 4 #ifdef ASTROPY_WCS_BUILD int _setup_api(PyObject* m); #else #if defined(NO_IMPORT_ASTROPY_WCS_API) extern void** AstropyWcs_API; #else void** AstropyWcs_API; #endif /* defined(NO_IMPORT_ASTROPY_PYWCS_API) */ /* Function macros that delegate to a function pointer in the AstropyWcs_API table */ #define AstropyWcs_GetCVersion (*(int (*)(void)) AstropyWcs_API[0]) #define wcsprm_python2c (*(void (*)(struct wcsprm*)) AstropyWcs_API[1]) #define wcsprm_c2python (*(void (*)(struct wcsprm*)) AstropyWcs_API[2]) #define distortion_lookup_t_init (*(int (*)(distortion_lookup_t* lookup)) AstropyWcs_API[3]) #define distortion_lookup_t_free (*(void (*)(distortion_lookup_t* lookup)) AstropyWcs_API[4]) #define get_distortion_offset (*(double (*)(const distortion_lookup_t*, const double* const)) AstropyWcs_API[5]) #define p4_pix2foc (*(int (*)(const unsigned int, const distortion_lookup_t**, const unsigned int, const double *, double *)) AstropyWcs_API[6]) #define p4_pix2deltas (*(int (*)(const unsigned int, const distortion_lookup_t**, const unsigned int, const double *, double *)) AstropyWcs_API[7]) #define sip_clear (*(void (*)(sip_t*) AstropyWcs_API[8])) #define sip_init (*(int (*)(sip_t*, unsigned int, double*, unsigned int, double*, unsigned int, double*, unsigned int, double*, double*)) AstropyWcs_API[9]) #define sip_free (*(void (*)(sip_t*) AstropyWcs_API[10])) #define sip_pix2foc (*(int (*)(sip_t*, unsigned int, unsigned int, double*, double*)) AstropyWcs_API[11]) #define sip_pix2deltas (*(int (*)(sip_t*, unsigned int, unsigned int, double*, double*)) AstropyWcs_API[12]) #define sip_foc2pix (*(int (*)(sip_t*, unsigned int, unsigned int, double*, double*)) AstropyWcs_API[13]) #define sip_foc2deltas (*(int (*)(sip_t*, unsigned int, unsigned int, double*, double*)) AstropyWcs_API[14]) #define pipeline_clear (*(void (*)(pipeline_t*)) AstropyWcs_API[15]) #define pipeline_init (*(void (*)(pipeline_t*, sip_t*, distortion_lookup_t**, struct wcsprm*)) AstropyWcs_API[16]) #define pipeline_free (*(void (*)(pipeline_t*)) AstropyWcs_API[17]) #define pipeline_all_pixel2world (*(int (*)(pipeline_t*, unsigned int, unsigned int, double*, double*)) AstropyWcs_API[18]) #define pipeline_pix2foc (*(int (*)(pipeline_t*, unsigned int, unsigned int, double*, double*)) AstropyWcs_API[19]) #define wcsp2s (*(int (*)(struct wcsprm *, int, int, const double[], double[], double[], double[], double[], int[])) AstropyWcs_API[20]) #define wcss2p (*(int (*)(struct wcsprm *, int, int, const double[], double[], double[], double[], double[], int[])) AstropyWcs_API[21]) #define wcsprt (*(int (*)(struct wcsprm *)) AstropyWcs_API[22]) #define wcslib_get_error_message (*(const char* (*)(int)) AstropyWcs_API[23]) #define wcsprintf_buf (*(const char * (*)()) AstropyWcs_API[24]) #ifndef NO_IMPORT_ASTROPY_WCS_API int import_astropy_wcs(void) { PyObject *wcs_module = NULL; PyObject *c_api = NULL; int status = -1; wcs_module = PyImport_ImportModule("astropy.wcs._wcs"); if (wcs_module == NULL) goto exit; c_api = PyObject_GetAttrString(wcs_module, "_ASTROPY_WCS_API"); if (c_api == NULL) goto exit; AstropyWcs_API = (void **)PyCapsule_GetPointer(c_api, "_wcs._ASTROPY_WCS_API"); if (AstropyWcs_API == NULL) goto exit; /* Perform runtime check of C API version */ if (REVISION != AstropyWcs_GetCVersion()) { PyErr_Format( PyExc_ImportError, "module compiled against " \ "ABI version '%x' but this version of astropy.wcs is '%x'", \ (int)REVISION, (int)AstropyWcs_GetCVersion()); return -1; } exit: Py_XDECREF(wcs_module); Py_XDECREF(c_api); return status; } #endif /* !defined(NO_IMPORT_ASTROPY_WCS_API) */ #endif /* ASTROPY_WCS_BUILD */ #endif /* ASTROPY_WCS_API_H */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/include/astropy_wcs/distortion.h0000644000175100001710000000514000000000000023111 0ustar00vstsdocker/* Author: Michael Droettboom mdroe@stsci.edu */ #ifndef __DISTORTION_H__ #define __DISTORTION_H__ #include "util.h" /* TODO: This is all two-dimensional. Should be made multi-dimensional in the future. */ #define NAXES 2 #define MAXAXES 6 /** A structure to contain the information for a single distortion lookup table */ typedef struct { unsigned int naxis[NAXES]; /* size of distortion image */ double crpix[NAXES]; double crval[NAXES]; double cdelt[NAXES]; /* The data is not "owned" by this structure. It is the user's responsibility to free it. */ /*@shared@*/ /*@null@*/ float *data; } distortion_lookup_t; /** Initialize a lookup table to reasonable default values. */ int distortion_lookup_t_init(distortion_lookup_t* lookup); /** Cleanup after a lookup table. Currently does nothing, but may do something in the future, so please call it when you are done with the lookup table. It does not free the data pointed to be the lookup table -- it is the user's responsibility to free that array. */ void distortion_lookup_t_free(distortion_lookup_t* lookup); /** Lookup the distortion offset for a particular pixel coordinate in the lookup table. @param lookup A lookup table object @param A coordinate pair @return The offset as determined by binlinear interpolation in the lookup table */ double get_distortion_offset( const distortion_lookup_t * const lookup, const double * const img /* [NAXES] */); /** Perform just the distortion table part of the FITS WCS distortion paper. @param naxes @param lookups A pair of lookup table objects @param nelem @param pix [in]: An array of pixel coordinates @param foc [out]: An array of focal plane coordinates @return A wcslib error code */ int p4_pix2foc( const unsigned int naxes, const distortion_lookup_t** lookups, /* [NAXES] */ const unsigned int nelem, const double* pix, /* [NAXES][nelem] */ double *foc /* [NAXES][nelem] */); /** Perform just the distortion table part of the FITS WCS distortion paper, by adding distortion to the values already in place in foc. @param naxes @param lookups A pair of lookup table objects @param nelem @param pix [in]: An array of pixel coordinates @param foc [in/out]: An array of focal plane coordinates @return A wcslib error code */ int p4_pix2deltas( const unsigned int naxes, const distortion_lookup_t** lookups, /* [NAXES] */ const unsigned int nelem, const double* pix, /* [NAXES][nelem] */ double *foc /* [NAXES][nelem] */); #endif /* __DISTORTION_H__ */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/include/astropy_wcs/distortion_wrap.h0000644000175100001710000000062300000000000024143 0ustar00vstsdocker/* Author: Michael Droettboom mdroe@stsci.edu */ #ifndef __DISTORTION_WRAP_H__ #define __DISTORTION_WRAP_H__ #include "pyutil.h" #include "distortion.h" extern PyTypeObject PyDistLookupType; typedef struct { PyObject_HEAD distortion_lookup_t x; /*@null@*/ /*@shared@*/ PyArrayObject* py_data; } PyDistLookup; int _setup_distortion_type( PyObject* m); #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921587.0 astropy-5.0.2/astropy/wcs/include/astropy_wcs/docstrings.h0000644000175100001710000001247700000000000023105 0ustar00vstsdocker/* DO NOT EDIT! This file is autogenerated by astropy/wcs/setup_package.py. To edit its contents, edit astropy/wcs/docstrings.py */ #ifndef __DOCSTRINGS_H__ #define __DOCSTRINGS_H__ extern char doc_Auxprm[198]; extern char doc_DistortionLookupTable[371]; extern char doc_InconsistentAxisTypes[100]; extern char doc_InvalidCoordinate[76]; extern char doc_InvalidSubimageSpecification[77]; extern char doc_InvalidTabularParameters[76]; extern char doc_InvalidTransform[107]; extern char doc_K[202]; extern char doc_M[56]; extern char doc_NoSolution[68]; extern char doc_NoWcsKeywordsFound[76]; extern char doc_NonseparableSubimageCoordinateSystem[88]; extern char doc_SingularMatrix[70]; extern char doc_Sip[1115]; extern char doc_Tabprm[234]; extern char doc_Wcs[463]; extern char doc_WcsError[39]; extern char doc_Wcsprm[3022]; extern char doc_Wtbarr[202]; extern char doc_a[264]; extern char doc_a_order[60]; extern char doc_all_pix2world[1305]; extern char doc_alt[236]; extern char doc_ap[276]; extern char doc_ap_order[61]; extern char doc_aux[87]; extern char doc_axis_types[916]; extern char doc_b[273]; extern char doc_b_order[60]; extern char doc_bepoch[119]; extern char doc_bounds_check[469]; extern char doc_bp[276]; extern char doc_bp_order[61]; extern char doc_cd[1059]; extern char doc_cdelt[308]; extern char doc_cdfix[480]; extern char doc_cel_offset[176]; extern char doc_celfix[171]; extern char doc_cname[76]; extern char doc_colax[91]; extern char doc_colnum[290]; extern char doc_compare[1412]; extern char doc_convert[121]; extern char doc_coord[277]; extern char doc_copy[40]; extern char doc_cpdis1[106]; extern char doc_cpdis2[106]; extern char doc_cperi[101]; extern char doc_crder[123]; extern char doc_crln_obs[106]; extern char doc_crota[1055]; extern char doc_crpix[88]; extern char doc_crval[93]; extern char doc_crval_tabprm[94]; extern char doc_csyer[132]; extern char doc_ctype[228]; extern char doc_cubeface[1236]; extern char doc_cunit[1323]; extern char doc_cylfix[162]; extern char doc_czphs[125]; extern char doc_data[78]; extern char doc_data_wtbarr[52]; extern char doc_dateavg[152]; extern char doc_datebeg[137]; extern char doc_dateend[135]; extern char doc_dateobs[133]; extern char doc_dateref[133]; extern char doc_datfix[512]; extern char doc_delta[238]; extern char doc_det2im[58]; extern char doc_det2im1[103]; extern char doc_det2im2[103]; extern char doc_dims[98]; extern char doc_dsun_obs[110]; extern char doc_equinox[243]; extern char doc_extlev[72]; extern char doc_extnam[73]; extern char doc_extrema[439]; extern char doc_extver[72]; extern char doc_find_all_wcs[866]; extern char doc_fix[1679]; extern char doc_get_cdelt[474]; extern char doc_get_offset[201]; extern char doc_get_pc[413]; extern char doc_get_ps[431]; extern char doc_get_pv[741]; extern char doc_has_cd[911]; extern char doc_has_cdi_ja[103]; extern char doc_has_crota[652]; extern char doc_has_crotaia[107]; extern char doc_has_pc[213]; extern char doc_has_pci_ja[103]; extern char doc_hgln_obs[100]; extern char doc_hglt_obs[122]; extern char doc_i[40]; extern char doc_imgpix_matrix[173]; extern char doc_is_unity[109]; extern char doc_jepoch[116]; extern char doc_kind[157]; extern char doc_lat[86]; extern char doc_latpole[75]; extern char doc_lattyp[236]; extern char doc_lng[87]; extern char doc_lngtyp[237]; extern char doc_lonpole[77]; extern char doc_m[63]; extern char doc_map[967]; extern char doc_mix[4851]; extern char doc_mjdavg[181]; extern char doc_mjdbeg[181]; extern char doc_mjdend[181]; extern char doc_mjdobs[181]; extern char doc_mjdref[182]; extern char doc_name[74]; extern char doc_naxis[761]; extern char doc_nc[172]; extern char doc_ndim[70]; extern char doc_obsgeo[187]; extern char doc_obsorbit[155]; extern char doc_p0[244]; extern char doc_p2s[2113]; extern char doc_p4_pix2foc[682]; extern char doc_pc[1126]; extern char doc_phi0[289]; extern char doc_pix2foc[667]; extern char doc_piximg_matrix[128]; extern char doc_plephem[126]; extern char doc_print_contents[210]; extern char doc_print_contents_tabprm[211]; extern char doc_print_contents_wtbarr[210]; extern char doc_radesys[77]; extern char doc_restfrq[94]; extern char doc_restwav[94]; extern char doc_row[39]; extern char doc_rsun_ref[114]; extern char doc_s2p[1946]; extern char doc_sense[232]; extern char doc_set[1206]; extern char doc_set_ps[413]; extern char doc_set_pv[408]; extern char doc_set_tabprm[330]; extern char doc_sip[84]; extern char doc_sip_foc2pix[683]; extern char doc_sip_pix2foc[683]; extern char doc_spcfix[272]; extern char doc_spec[68]; extern char doc_specsys[145]; extern char doc_sptr[1370]; extern char doc_ssysobs[253]; extern char doc_ssyssrc[150]; extern char doc_sub[3445]; extern char doc_tab[112]; extern char doc_telapse[141]; extern char doc_theta0[289]; extern char doc_timedel[93]; extern char doc_timeoffs[186]; extern char doc_timepixr[151]; extern char doc_timesys[230]; extern char doc_timeunit[264]; extern char doc_timrder[132]; extern char doc_timsyer[119]; extern char doc_to_header[2232]; extern char doc_trefdir[118]; extern char doc_trefpos[110]; extern char doc_tstart[150]; extern char doc_tstop[151]; extern char doc_ttype[107]; extern char doc_unitfix[1047]; extern char doc_velangl[186]; extern char doc_velosys[316]; extern char doc_velref[55]; extern char doc_wcs[83]; extern char doc_wtb[82]; extern char doc_xposure[105]; extern char doc_zsource[98]; #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/include/astropy_wcs/isnan.h0000644000175100001710000000223600000000000022026 0ustar00vstsdocker#ifndef __ISNAN_H__ #define __ISNAN_H__ #include "wcsconfig.h" typedef unsigned WCSLIB_INT64 Int64; #if !defined(U64) #define U64(u) (* (Int64 *) &(u) ) #endif /* U64 */ #if !defined(isnan64) #if !defined(_MSC_VER) #define isnan64(u) \ ( (( U64(u) & 0x7ff0000000000000LL) == 0x7ff0000000000000LL) && ((U64(u) & 0x000fffffffffffffLL) != 0)) ? 1:0 #else #define isnan64(u) \ ( (( U64(u) & 0x7ff0000000000000i64) == 0x7ff0000000000000i64) && ((U64(u) & 0x000fffffffffffffi64) != 0)) ? 1:0 #endif #endif /* isnan64 */ #if !defined(isinf64) #if !defined(_MSC_VER) #define isinf64(u) \ ( (( U64(u) & 0x7ff0000000000000LL) == 0x7ff0000000000000LL) && ((U64(u) & 0x000fffffffffffffLL) == 0)) ? 1:0 #else #define isinf64(u) \ ( (( U64(u) & 0x7ff0000000000000i64) == 0x7ff0000000000000i64) && ((U64(u) & 0x000fffffffffffffi64) == 0)) ? 1:0 #endif #endif /* isinf64 */ #if !defined(isfinite64) #if !defined(_MSC_VER) #define isfinite64(u) \ ( (( U64(u) & 0x7ff0000000000000LL) != 0x7ff0000000000000LL)) ? 1:0 #else #define isfinite64(u) \ ( (( U64(u) & 0x7ff0000000000000i64) != 0x7ff0000000000000i64)) ? 1:0 #endif #endif /* isfinite64 */ #endif /* __ISNAN_H__ */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/include/astropy_wcs/pipeline.h0000644000175100001710000000442700000000000022527 0ustar00vstsdocker/* Author: Michael Droettboom mdroe@stsci.edu */ #ifndef __PIPELINE_H__ #define __PIPELINE_H__ #include "sip.h" #include "distortion.h" #include "wcs.h" typedef struct { distortion_lookup_t* det2im[2]; /*@shared@*/ /*@null@*/ sip_t* sip; distortion_lookup_t* cpdis[2]; /*@shared@*/ /*@null@*/ struct wcsprm* wcs; struct wcserr* err; } pipeline_t; /** Initialize all the values in a pipeline_t to NULL. */ void pipeline_clear( pipeline_t* pipeline); /** Set all the values of a pipeline_t. */ void pipeline_init( pipeline_t* pipeline, /*@shared@*/ distortion_lookup_t** det2im /* [2] */, /*@shared@*/ sip_t* sip, /*@shared@*/ distortion_lookup_t** cpdis /* [2] */, /*@shared@*/ struct wcsprm* wcs); /** Free all the temporary buffers of a pipeline_t. It does not free the underlying sip_t, distortion_lookup_t or wcsprm objects. */ void pipeline_free( pipeline_t* pipeline); /** Perform the entire pipeline from pixel coordinates to world coordinates, in the following order: - Detector to image plane correction (optionally) - SIP distortion correction (optionally) - FITS WCS distortion paper correction (optionally) - wcslib WCS transformation @param ncoord: @param nelem: @param pixcrd [in]: Array of pixel coordinates. @param world [out]: Array of world coordinates (output). @return: A wcslib error code. */ int pipeline_all_pixel2world( pipeline_t* pipeline, const unsigned int ncoord, const unsigned int nelem, const double* const pixcrd /* [ncoord][nelem] */, double* world /* [ncoord][nelem] */); /** Perform just the distortion correction part of the pipeline from pixel coordinates to focal plane coordinates. - Detector to image plane correction (optionally) - SIP distortion correction (optionally) - FITS WCS distortion paper correction (optionally) @param ncoord: @param nelem: @param pixcrd [in]: Array of pixel coordinates. @param foc [out]: Array of focal plane coordinates. @return: A wcslib error code. */ int pipeline_pix2foc( pipeline_t* pipeline, const unsigned int ncoord, const unsigned int nelem, const double* const pixcrd /* [ncoord][nelem] */, double* foc /* [ncoord][nelem] */); #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/include/astropy_wcs/pyutil.h0000644000175100001710000001464200000000000022250 0ustar00vstsdocker/* Author: Michael Droettboom mdroe@stsci.edu */ #ifndef __PYUTIL_H__ #define __PYUTIL_H__ #include "util.h" #define PY_ARRAY_UNIQUE_SYMBOL astropy_wcs_numpy_api #include #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #include #include PyObject* PyArrayProxy_New( PyObject* self, int nd, const npy_intp* dims, int typenum, const void* data); PyObject* PyArrayReadOnlyProxy_New( PyObject* self, int nd, const npy_intp* dims, int typenum, const void* data); /*@null@*/ PyObject * PyStrListProxy_New( PyObject* owner, Py_ssize_t size, Py_ssize_t maxsize, char (*array)[72] ); int _setup_str_list_proxy_type( PyObject* m); static INLINE void offset_c_array( double* value, npy_intp size, double offset) { double* end = value + size; for ( ; value != end; ++value) { *value += offset; } } static INLINE void nan2undefined( double* value, unsigned int nvalues) { double* end = value + nvalues; for ( ; value != end; ++value) { if (isnan64(*value)) { *value = UNDEFINED; } } } static INLINE void undefined2nan( double* value, unsigned int nvalues) { double* end = value + nvalues; for ( ; value != end; ++value) { if (*value == UNDEFINED) { *value = (double)NPY_NAN; } } } void preoffset_array( PyArrayObject* array, int value); void unoffset_array( PyArrayObject* array, int value); void copy_array_to_c_double( PyArrayObject* array, double* dest); void copy_array_to_c_int( PyArrayObject* array, int* dest); /** Returns TRUE if pointer is NULL, and sets Python exception */ int is_null(/*@null@*/ void *); typedef void (*value_fixer_t)(double*, unsigned int); void wcsprm_c2python( /*@null@*/ struct wcsprm* x); void wcsprm_python2c( /*@null@*/ struct wcsprm* x); /*************************************************************************** * Exceptions * ***************************************************************************/ extern PyObject* WcsExc_SingularMatrix; extern PyObject* WcsExc_InconsistentAxisTypes; extern PyObject* WcsExc_InvalidTransform; extern PyObject* WcsExc_InvalidCoordinate; extern PyObject* WcsExc_NoSolution; extern PyObject* WcsExc_InvalidSubimageSpecification; extern PyObject* WcsExc_NonseparableSubimageCoordinateSystem; extern PyObject* WcsExc_NoWcsKeywordsFound; extern PyObject* WcsExc_InvalidTabularParameters; /* This is an array mapping the wcs status codes to Python exception * types. The exception string is stored as part of wcslib itself in * wcs_errmsg. */ extern PyObject** wcs_errexc[14]; #define WCS_ERRMSG_MAX 14 #define WCSFIX_ERRMSG_MAX 11 int _define_exceptions(PyObject* m); const char* wcslib_get_error_message(int stat); void wcserr_to_python_exc(const struct wcserr *err); void wcs_to_python_exc(const struct wcsprm *wcs); void wcshdr_err_to_python_exc(int status, const struct wcsprm *wcs); void wcserr_fix_to_python_exc(const struct wcserr *err); /*************************************************************************** Property helpers ***************************************************************************/ static INLINE int check_delete( const char* propname, PyObject* value) { if (value == NULL) { PyErr_Format(PyExc_TypeError, "'%s' can not be deleted", propname); return -1; } return 0; } static INLINE PyObject* get_string( /*@unused@*/ const char* propname, const char* value) { return PyUnicode_FromString(value); } int set_string( const char* propname, PyObject* value, char* dest, Py_ssize_t maxlen); static INLINE PyObject* get_bool( /*@unused@*/ const char* propname, long value) { return PyBool_FromLong(value); } int set_bool( const char* propname, PyObject* value, int* dest); static INLINE PyObject* get_int( /*@unused@*/ const char* propname, long value) { return PyLong_FromLong(value); } int set_int( const char* propname, PyObject* value, int* dest); static INLINE PyObject* get_double( const char* propname, double value) { return PyFloat_FromDouble(value); } int set_double( const char* propname, PyObject* value, double* dest); /*@null@*/ static INLINE PyObject* get_double_array( /*@unused@*/ const char* propname, double* value, int ndims, const npy_intp* dims, /*@shared@*/ PyObject* owner) { return PyArrayProxy_New(owner, ndims, dims, NPY_DOUBLE, value); } /*@null@*/ static INLINE PyObject* get_double_array_readonly( /*@unused@*/ const char* propname, double* value, int ndims, const npy_intp* dims, /*@shared@*/ PyObject* owner) { return PyArrayReadOnlyProxy_New(owner, ndims, dims, NPY_DOUBLE, value); } int set_double_array( const char* propname, PyObject* value, int ndims, const npy_intp* dims, double* dest); /*@null@*/ static INLINE PyObject* get_int_array( /*@unused@*/ const char* propname, int* value, int ndims, const npy_intp* dims, /*@shared@*/ PyObject* owner) { return PyArrayProxy_New(owner, ndims, dims, NPY_INT, value); } int set_int_array( const char* propname, PyObject* value, int ndims, const npy_intp* dims, int* dest); static INLINE PyObject* get_str_list( /*@unused@*/ const char* propname, char (*array)[72], Py_ssize_t len, Py_ssize_t maxlen, PyObject* owner) { return PyStrListProxy_New(owner, len, maxlen, array); } int set_str_list( const char* propname, PyObject* value, Py_ssize_t len, Py_ssize_t maxlen, char (*dest)[72]); PyObject* get_pscards( const char* propname, struct pscard* ps, int nps); int set_pscards( const char* propname, PyObject* value, struct pscard** ps, int *nps, int *npsmax); PyObject* get_pvcards( const char* propname, struct pvcard* pv, int npv); int set_pvcards( const char* propname, PyObject* value, struct pvcard** pv, int *npv, int *npvmax); PyObject* get_deepcopy( PyObject* obj, PyObject* memo); /*************************************************************************** Miscellaneous helper functions ***************************************************************************/ int parse_unsafe_unit_conversion_spec( const char* arg, int* ctrl); #endif /* __PYUTIL_H__ */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/include/astropy_wcs/sip.h0000644000175100001710000001016000000000000021504 0ustar00vstsdocker/* Author: Michael Droettboom mdroe@stsci.edu */ #ifndef __SIP_H__ #define __SIP_H__ #include "util.h" typedef struct { unsigned int a_order; /*@null@*/ /*@shared@*/ double* a; unsigned int b_order; /*@null@*/ /*@shared@*/ double* b; unsigned int ap_order; /*@null@*/ /*@shared@*/ double* ap; unsigned int bp_order; /*@null@*/ /*@shared@*/ double* bp; double crpix[2]; /*@null@*/ double* scratch; struct wcserr* err; } sip_t; /** Sets all the values of the sip_t structure to NULLs or zeros. */ void sip_clear(sip_t* sip); /** Set the values of the sip_t structure. The values expected are all exactly as defined in the FITS SIP header keywords. The arrays/matrices are all *copied* into the SIP struct. To free the memory that sip_t allocates for itself, call sip_free. @param a_order: The order of the A_i_j matrix @param a: The A_i_j array, which must be of size [a_order+1][a_order+1] @param b_order: The order of the B_i_j matrix @param b: The B_i_j array, which must be of size [b_order+1][b_order+1] @param ap_order: The order of the AP_i_j matrix @param ap: The AP_i_j array, which must be of size [ap_order+1][ap_order+1] @param bp_order: The order of the BP_i_j matrix @param bp: The BP_i_j array, which must be of size [bp_order+1][bp_order+1] @param crpix: The position of the reference pixel */ int sip_init( sip_t* sip, const unsigned int a_order, const double* a, const unsigned int b_order, const double* b, const unsigned int ap_order, const double* ap, const unsigned int bp_order, const double* bp, const double* crpix /* [2] */); /** Frees the memory allocated for the sip_t struct. */ void sip_free(sip_t* sip); /** Converts pixel coordinates to focal plane coordinates using the SIP polynomial distortion convention, and the values stored in the sip_t struct. @param naxes @param nelem @param pix [in]: An array of pixel coordinates @param foc [out]: An array of focal plane coordinates @return A wcslib error code */ int sip_pix2foc( const sip_t* sip, const unsigned int naxes, const unsigned int nelem, const double* pix /* [NAXES][nelem] */, double* foc /* [NAXES][nelem] */); /** Computes the offset deltas necessary to convert pixel coordinates to focal plane coordinates using the SIP polynomial distortion convention, and the values stored in the sip_t struct. The deltas are added to the existing values in pix. @param naxes @param nelem @param pix [in]: An array of pixel coordinates @param foc [in/out]: An array of deltas, that when added to pix results in focal plane coordinates. @return A wcslib error code */ int sip_pix2deltas( const sip_t* sip, const unsigned int naxes, const unsigned int nelem, const double* pix /* [NAXES][nelem] */, double* foc /* [NAXES][nelem] */); /** Adds the offset deltas necessary to convert focal plane coordinates to pixel coordinates using the SIP polynomial distortion convention, and the values stored in the sip_t struct. The deltas are added to the existing values in pix. @param naxes @param nelem @param foc [in]: An array of focal plane coordinates @param pix [in/out]: An array of pixel coordinates @return A wcslib error code */ int sip_foc2pix( const sip_t* sip, const unsigned int naxes, const unsigned int nelem, const double* foc /* [NAXES][nelem] */, double* pix /* [NAXES][nelem] */); /** Computes the offset deltas necessary to convert focal plane coordinates to pixel coordinates using the SIP polynomial distortion convention, and the values stored in the sip_t struct. The deltas are added to the existing values in foc. @param naxes @param nelem @param foc [in]: An array of focal plane coordinates @param foc [in/out]: An array of deltas, that when added to pix results in focal plane coordinates. @return A wcslib error code */ int sip_foc2deltas( const sip_t* sip, const unsigned int naxes, const unsigned int nelem, const double* foc /* [NAXES][nelem] */, double* deltas /* [NAXES][nelem] */); #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/include/astropy_wcs/sip_wrap.h0000644000175100001710000000042600000000000022541 0ustar00vstsdocker/* Author: Michael Droettboom mdroe@stsci.edu */ #ifndef __SIP_WRAP_H__ #define __SIP_WRAP_H__ #include "pyutil.h" #include "sip.h" extern PyTypeObject PySipType; typedef struct { PyObject_HEAD sip_t x; } PySip; int _setup_sip_type( PyObject* m); #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/include/astropy_wcs/str_list_proxy.h0000644000175100001710000000144400000000000024022 0ustar00vstsdocker/* Author: Michael Droettboom mdroe@stsci.edu */ #ifndef __STR_LIST_PROXY_H__ #define __STR_LIST_PROXY_H__ #include "pyutil.h" /*************************************************************************** * List-of-strings proxy object * * A Python object that looks like a list of strings, but is back by a C * char * list[]; ***************************************************************************/ typedef int (*str_verify_fn)(const char *); /*@null@*/ PyObject * PyStrListProxy_New( PyObject* owner, Py_ssize_t size, Py_ssize_t maxsize, char (*array)[72] ); /*@null@*/ PyObject* str_list_proxy_repr( char (*array)[72], Py_ssize_t size, Py_ssize_t maxsize); int _setup_str_list_proxy_type( PyObject* m); #endif /* __STR_LIST_PROXY_H__ */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/include/astropy_wcs/unit_list_proxy.h0000644000175100001710000000167000000000000024172 0ustar00vstsdocker/* Author: Michael Droettboom mdroe@stsci.edu */ #ifndef __UNIT_LIST_PROXY_H__ #define __UNIT_LIST_PROXY_H__ #include "pyutil.h" /*************************************************************************** * List-of-units proxy object * * A Python object that looks like a list of units, but is back by a C * char * list[]; ***************************************************************************/ /*@null@*/ PyObject * PyUnitListProxy_New( PyObject* owner, Py_ssize_t size, char (*array)[72] ); int _setup_unit_list_proxy_type( PyObject* m); static INLINE PyObject* get_unit_list( /*@unused@*/ const char* propname, char (*array)[72], Py_ssize_t len, PyObject* owner) { return PyUnitListProxy_New(owner, len, array); } int set_unit_list( PyObject *owner, const char* propname, PyObject* value, Py_ssize_t len, char (*dest)[72]); #endif /* __UNIT_LIST_PROXY_H__ */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/include/astropy_wcs/util.h0000644000175100001710000000103200000000000021664 0ustar00vstsdocker/* Author: Michael Droettboom mdroe@stsci.edu */ #ifndef __UTIL_H__ #define __UTIL_H__ #ifdef __SUNPRO_C #define INLINE #endif #ifdef _MSC_VER #define INLINE __inline #endif #ifndef INLINE #define INLINE inline #endif #include #include #include "isnan.h" #undef CLAMP #define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) void set_invalid_to_nan( const int ncoord, const int nelem, double* const data, const int* const stat); #endif /* __UTIL_H__ */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921587.0 astropy-5.0.2/astropy/wcs/include/astropy_wcs/wcsconfig.h0000644000175100001710000000160300000000000022675 0ustar00vstsdocker /* The bundled version has WCSLIB_VERSION */ #define HAVE_WCSLIB_VERSION 1 /* WCSLIB library version number. */ #define WCSLIB_VERSION 7.7 /* 64-bit integer data type. */ #define WCSLIB_INT64 long long int /* Windows needs some other defines to prevent inclusion of wcsset() which conflicts with wcslib's wcsset(). These need to be set on code that *uses* astropy.wcs, in addition to astropy.wcs itself. */ #if defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) || defined (__MINGW64__) #ifndef YY_NO_UNISTD_H #define YY_NO_UNISTD_H #endif #ifndef _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #endif #ifndef _NO_OLDNAMES #define _NO_OLDNAMES #endif #ifndef NO_OLDNAMES #define NO_OLDNAMES #endif #ifndef __STDC__ #define __STDC__ 1 #endif #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/include/astropy_wcs/wcslib_auxprm_wrap.h0000644000175100001710000000051400000000000024623 0ustar00vstsdocker#ifndef __WCSLIB_AUXPRM_WRAP_H__ #define __WCSLIB_AUXPRM_WRAP_H__ #include "pyutil.h" #include "wcs.h" extern PyTypeObject PyAuxprmType; typedef struct { PyObject_HEAD struct auxprm* x; PyObject* owner; } PyAuxprm; PyAuxprm* PyAuxprm_cnew(PyObject* wcsprm, struct auxprm* x); int _setup_auxprm_type(PyObject* m); #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/include/astropy_wcs/wcslib_tabprm_wrap.h0000644000175100001710000000061000000000000024571 0ustar00vstsdocker/* Author: Michael Droettboom mdroe@stsci.edu */ #ifndef __WCSLIB_TABPRM_WRAP_H__ #define __WCSLIB_TABPRM_WRAP_H__ #include "pyutil.h" #include "wcs.h" extern PyTypeObject PyTabprmType; typedef struct { PyObject_HEAD struct tabprm* x; PyObject* owner; } PyTabprm; PyTabprm* PyTabprm_cnew(PyObject* wcsprm, struct tabprm* x); int _setup_tabprm_type(PyObject* m); #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/include/astropy_wcs/wcslib_units_wrap.h0000644000175100001710000000102000000000000024442 0ustar00vstsdocker/* Author: Michael Droettboom mdroe@stsci.edu */ #ifndef __WCSLIB_UNITS_WRAP_H__ #define __WCSLIB_UNITS_WRAP_H__ #include "pyutil.h" #include "wcsunits.h" extern PyTypeObject PyUnitsType; typedef struct { PyObject_HEAD char have[80]; char want[80]; double scale; double offset; double power; } PyUnits; PyUnits* PyUnits_cnew( const char* const have, const char* const want, const double scale, const double offset, const double power); int _setup_units_type(PyObject* m); #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/include/astropy_wcs/wcslib_wrap.h0000644000175100001710000000072600000000000023234 0ustar00vstsdocker/* Author: Michael Droettboom */ #ifndef __WCSLIB_WRAP_H__ #define __WCSLIB_WRAP_H__ #include "pyutil.h" extern PyTypeObject PyWcsprmType; typedef struct { PyObject_HEAD struct wcsprm x; } PyWcsprm; int _setup_wcsprm_type(PyObject* m); PyObject* PyWcsprm_find_all_wcs( PyObject* self, PyObject* args, PyObject* kwds); int _update_wtbarr_from_hdulist(PyObject *hdulist, struct wtbarr *wtb); void _set_wtbarr_callback(PyObject* callback); #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/include/astropy_wcs/wcslib_wtbarr_wrap.h0000644000175100001710000000061000000000000024605 0ustar00vstsdocker/* Author: Michael Droettboom mdroe@stsci.edu */ #ifndef __WCSLIB_WTBARR_WRAP_H__ #define __WCSLIB_WTBARR_WRAP_H__ #include "pyutil.h" #include "wcs.h" extern PyTypeObject PyWtbarrType; typedef struct { PyObject_HEAD struct wtbarr* x; PyObject* owner; } PyWtbarr; PyWtbarr* PyWtbarr_cnew(PyObject* wcsprm, struct wtbarr* x); int _setup_wtbarr_type(PyObject* m); #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/include/astropy_wcs_api.h0000644000175100001710000000015100000000000021541 0ustar00vstsdocker#error "Since version 0.3, astropy.wcs public API should be imported as \"astropy_wcs/astropy_wcs_api.h" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921587.0 astropy-5.0.2/astropy/wcs/include/wcsconfig.h0000644000175100001710000000160300000000000020320 0ustar00vstsdocker /* The bundled version has WCSLIB_VERSION */ #define HAVE_WCSLIB_VERSION 1 /* WCSLIB library version number. */ #define WCSLIB_VERSION 7.7 /* 64-bit integer data type. */ #define WCSLIB_INT64 long long int /* Windows needs some other defines to prevent inclusion of wcsset() which conflicts with wcslib's wcsset(). These need to be set on code that *uses* astropy.wcs, in addition to astropy.wcs itself. */ #if defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) || defined (__MINGW64__) #ifndef YY_NO_UNISTD_H #define YY_NO_UNISTD_H #endif #ifndef _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #endif #ifndef _NO_OLDNAMES #define _NO_OLDNAMES #endif #ifndef NO_OLDNAMES #define NO_OLDNAMES #endif #ifndef __STDC__ #define __STDC__ 1 #endif #endif ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2272568 astropy-5.0.2/astropy/wcs/include/wcslib/0000755000175100001710000000000000000000000017450 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/include/wcslib/.empty0000644000175100001710000000000000000000000020575 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/include/wcslib/.gitignore0000644000175100001710000000013700000000000021441 0ustar00vstsdocker# We copy header files here from `cextern/wcslib/C`, but they should # be ignored by git. *.h ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921587.0 astropy-5.0.2/astropy/wcs/include/wcslib/cel.h0000644000175100001710000004600300000000000020367 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: cel.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the cel routines * --------------------------- * Routines in this suite implement the part of the FITS World Coordinate * System (WCS) standard that deals with celestial coordinates, as described in * = "Representations of world coordinates in FITS", = Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (WCS Paper I) = = "Representations of celestial coordinates in FITS", = Calabretta, M.R., & Greisen, E.W. 2002, A&A, 395, 1077 (WCS Paper II) * * These routines define methods to be used for computing celestial world * coordinates from intermediate world coordinates (a linear transformation * of image pixel coordinates), and vice versa. They are based on the celprm * struct which contains all information needed for the computations. This * struct contains some elements that must be set by the user, and others that * are maintained by these routines, somewhat like a C++ class but with no * encapsulation. * * Routine celini() is provided to initialize the celprm struct with default * values, celfree() reclaims any memory that may have been allocated to store * an error message, celsize() computes its total size including allocated * memory, and celprt() prints its contents. * * celperr() prints the error message(s), if any, stored in a celprm struct and * the prjprm struct that it contains. * * A setup routine, celset(), computes intermediate values in the celprm struct * from parameters in it that were supplied by the user. The struct always * needs to be set up by celset() but it need not be called explicitly - refer * to the explanation of celprm::flag. * * celx2s() and cels2x() implement the WCS celestial coordinate * transformations. In fact, they are high level driver routines for the lower * level spherical coordinate rotation and projection routines described in * sph.h and prj.h. * * * celini() - Default constructor for the celprm struct * ---------------------------------------------------- * celini() sets all members of a celprm struct to default values. It should * be used to initialize every celprm struct. * * PLEASE NOTE: If the celprm struct has already been initialized, then before * reinitializing, it celfree() should be used to free any memory that may have * been allocated to store an error message. A memory leak may otherwise * result. * * Returned: * cel struct celprm* * Celestial transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null celprm pointer passed. * * * celfree() - Destructor for the celprm struct * -------------------------------------------- * celfree() frees any memory that may have been allocated to store an error * message in the celprm struct. * * Given: * cel struct celprm* * Celestial transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null celprm pointer passed. * * * celsize() - Compute the size of a celprm struct * ----------------------------------------------- * celsize() computes the full size of a celprm struct, including allocated * memory. * * Given: * cel const struct celprm* * Celestial transformation parameters. * * If NULL, the base size of the struct and the allocated * size are both set to zero. * * Returned: * sizes int[2] The first element is the base size of the struct as * returned by sizeof(struct celprm). The second element * is the total allocated size, in bytes. This figure * includes memory allocated for the constituent struct, * celprm::err. * * It is not an error for the struct not to have been set * up via celset(). * * Function return value: * int Status return value: * 0: Success. * * * celprt() - Print routine for the celprm struct * ---------------------------------------------- * celprt() prints the contents of a celprm struct using wcsprintf(). Mainly * intended for diagnostic purposes. * * Given: * cel const struct celprm* * Celestial transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null celprm pointer passed. * * * celperr() - Print error messages from a celprm struct * ----------------------------------------------------- * celperr() prints the error message(s), if any, stored in a celprm struct and * the prjprm struct that it contains. If there are no errors then nothing is * printed. It uses wcserr_prt(), q.v. * * Given: * cel const struct celprm* * Coordinate transformation parameters. * * prefix const char * * If non-NULL, each output line will be prefixed with * this string. * * Function return value: * int Status return value: * 0: Success. * 1: Null celprm pointer passed. * * * celset() - Setup routine for the celprm struct * ---------------------------------------------- * celset() sets up a celprm struct according to information supplied within * it. * * Note that this routine need not be called directly; it will be invoked by * celx2s() and cels2x() if celprm::flag is anything other than a predefined * magic value. * * Given and returned: * cel struct celprm* * Celestial transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null celprm pointer passed. * 2: Invalid projection parameters. * 3: Invalid coordinate transformation parameters. * 4: Ill-conditioned coordinate transformation * parameters. * * For returns > 1, a detailed error message is set in * celprm::err if enabled, see wcserr_enable(). * * * celx2s() - Pixel-to-world celestial transformation * -------------------------------------------------- * celx2s() transforms (x,y) coordinates in the plane of projection to * celestial coordinates (lng,lat). * * Given and returned: * cel struct celprm* * Celestial transformation parameters. * * Given: * nx,ny int Vector lengths. * * sxy,sll int Vector strides. * * x,y const double[] * Projected coordinates in pseudo "degrees". * * Returned: * phi,theta double[] Longitude and latitude (phi,theta) in the native * coordinate system of the projection [deg]. * * lng,lat double[] Celestial longitude and latitude (lng,lat) of the * projected point [deg]. * * stat int[] Status return value for each vector element: * 0: Success. * 1: Invalid value of (x,y). * * Function return value: * int Status return value: * 0: Success. * 1: Null celprm pointer passed. * 2: Invalid projection parameters. * 3: Invalid coordinate transformation parameters. * 4: Ill-conditioned coordinate transformation * parameters. * 5: One or more of the (x,y) coordinates were * invalid, as indicated by the stat vector. * * For returns > 1, a detailed error message is set in * celprm::err if enabled, see wcserr_enable(). * * * cels2x() - World-to-pixel celestial transformation * -------------------------------------------------- * cels2x() transforms celestial coordinates (lng,lat) to (x,y) coordinates in * the plane of projection. * * Given and returned: * cel struct celprm* * Celestial transformation parameters. * * Given: * nlng,nlat int Vector lengths. * * sll,sxy int Vector strides. * * lng,lat const double[] * Celestial longitude and latitude (lng,lat) of the * projected point [deg]. * * Returned: * phi,theta double[] Longitude and latitude (phi,theta) in the native * coordinate system of the projection [deg]. * * x,y double[] Projected coordinates in pseudo "degrees". * * stat int[] Status return value for each vector element: * 0: Success. * 1: Invalid value of (lng,lat). * * Function return value: * int Status return value: * 0: Success. * 1: Null celprm pointer passed. * 2: Invalid projection parameters. * 3: Invalid coordinate transformation parameters. * 4: Ill-conditioned coordinate transformation * parameters. * 6: One or more of the (lng,lat) coordinates were * invalid, as indicated by the stat vector. * * For returns > 1, a detailed error message is set in * celprm::err if enabled, see wcserr_enable(). * * * celprm struct - Celestial transformation parameters * --------------------------------------------------- * The celprm struct contains information required to transform celestial * coordinates. It consists of certain members that must be set by the user * ("given") and others that are set by the WCSLIB routines ("returned"). Some * of the latter are supplied for informational purposes and others are for * internal use only. * * Returned celprm struct members must not be modified by the user. * * int flag * (Given and returned) This flag must be set to zero whenever any of the * following celprm struct members are set or changed: * * - celprm::offset, * - celprm::phi0, * - celprm::theta0, * - celprm::ref[4], * - celprm::prj: * - prjprm::code, * - prjprm::r0, * - prjprm::pv[], * - prjprm::phi0, * - prjprm::theta0. * * This signals the initialization routine, celset(), to recompute the * returned members of the celprm struct. celset() will reset flag to * indicate that this has been done. * * int offset * (Given) If true (non-zero), an offset will be applied to (x,y) to * force (x,y) = (0,0) at the fiducial point, (phi_0,theta_0). * Default is 0 (false). * * double phi0 * (Given) The native longitude, phi_0 [deg], and ... * * double theta0 * (Given) ... the native latitude, theta_0 [deg], of the fiducial point, * i.e. the point whose celestial coordinates are given in * celprm::ref[1:2]. If undefined (set to a magic value by prjini()) the * initialization routine, celset(), will set this to a projection-specific * default. * * double ref[4] * (Given) The first pair of values should be set to the celestial * longitude and latitude of the fiducial point [deg] - typically right * ascension and declination. These are given by the CRVALia keywords in * FITS. * * (Given and returned) The second pair of values are the native longitude, * phi_p [deg], and latitude, theta_p [deg], of the celestial pole (the * latter is the same as the celestial latitude of the native pole, * delta_p) and these are given by the FITS keywords LONPOLEa and LATPOLEa * (or by PVi_2a and PVi_3a attached to the longitude axis which take * precedence if defined). * * LONPOLEa defaults to phi_0 (see above) if the celestial latitude of the * fiducial point of the projection is greater than or equal to the native * latitude, otherwise phi_0 + 180 [deg]. (This is the condition for the * celestial latitude to increase in the same direction as the native * latitude at the fiducial point.) ref[2] may be set to UNDEFINED (from * wcsmath.h) or 999.0 to indicate that the correct default should be * substituted. * * theta_p, the native latitude of the celestial pole (or equally the * celestial latitude of the native pole, delta_p) is often determined * uniquely by CRVALia and LONPOLEa in which case LATPOLEa is ignored. * However, in some circumstances there are two valid solutions for theta_p * and LATPOLEa is used to choose between them. LATPOLEa is set in ref[3] * and the solution closest to this value is used to reset ref[3]. It is * therefore legitimate, for example, to set ref[3] to +90.0 to choose the * more northerly solution - the default if the LATPOLEa keyword is omitted * from the FITS header. For the special case where the fiducial point of * the projection is at native latitude zero, its celestial latitude is * zero, and LONPOLEa = +/- 90.0 then the celestial latitude of the native * pole is not determined by the first three reference values and LATPOLEa * specifies it completely. * * The returned value, celprm::latpreq, specifies how LATPOLEa was actually * used. * * struct prjprm prj * (Given and returned) Projection parameters described in the prologue to * prj.h. * * double euler[5] * (Returned) Euler angles and associated intermediaries derived from the * coordinate reference values. The first three values are the Z-, X-, and * Z'-Euler angles [deg], and the remaining two are the cosine and sine of * the X-Euler angle. * * int latpreq * (Returned) For informational purposes, this indicates how the LATPOLEa * keyword was used * - 0: Not required, theta_p (== delta_p) was determined uniquely by the * CRVALia and LONPOLEa keywords. * - 1: Required to select between two valid solutions of theta_p. * - 2: theta_p was specified solely by LATPOLEa. * * int isolat * (Returned) True if the spherical rotation preserves the magnitude of the * latitude, which occurs iff the axes of the native and celestial * coordinates are coincident. It signals an opportunity to cache * intermediate calculations common to all elements in a vector * computation. * * struct wcserr *err * (Returned) If enabled, when an error status is returned, this struct * contains detailed information about the error, see wcserr_enable(). * * void *padding * (An unused variable inserted for alignment purposes only.) * * Global variable: const char *cel_errmsg[] - Status return messages * ------------------------------------------------------------------ * Status messages to match the status value returned from each function. * *===========================================================================*/ #ifndef WCSLIB_CEL #define WCSLIB_CEL #include "prj.h" #ifdef __cplusplus extern "C" { #endif extern const char *cel_errmsg[]; enum cel_errmsg_enum { CELERR_SUCCESS = 0, // Success. CELERR_NULL_POINTER = 1, // Null celprm pointer passed. CELERR_BAD_PARAM = 2, // Invalid projection parameters. CELERR_BAD_COORD_TRANS = 3, // Invalid coordinate transformation // parameters. CELERR_ILL_COORD_TRANS = 4, // Ill-conditioned coordinated transformation // parameters. CELERR_BAD_PIX = 5, // One or more of the (x,y) coordinates were // invalid. CELERR_BAD_WORLD = 6 // One or more of the (lng,lat) coordinates // were invalid. }; struct celprm { // Initialization flag (see the prologue above). //-------------------------------------------------------------------------- int flag; // Set to zero to force initialization. // Parameters to be provided (see the prologue above). //-------------------------------------------------------------------------- int offset; // Force (x,y) = (0,0) at (phi_0,theta_0). double phi0, theta0; // Native coordinates of fiducial point. double ref[4]; // Celestial coordinates of fiducial // point and native coordinates of // celestial pole. struct prjprm prj; // Projection parameters (see prj.h). // Information derived from the parameters supplied. //-------------------------------------------------------------------------- double euler[5]; // Euler angles and functions thereof. int latpreq; // LATPOLEa requirement. int isolat; // True if |latitude| is preserved. // Error handling //-------------------------------------------------------------------------- struct wcserr *err; // Private //-------------------------------------------------------------------------- void *padding; // (Dummy inserted for alignment purposes.) }; // Size of the celprm struct in int units, used by the Fortran wrappers. #define CELLEN (sizeof(struct celprm)/sizeof(int)) int celini(struct celprm *cel); int celfree(struct celprm *cel); int celsize(const struct celprm *cel, int sizes[2]); int celprt(const struct celprm *cel); int celperr(const struct celprm *cel, const char *prefix); int celset(struct celprm *cel); int celx2s(struct celprm *cel, int nx, int ny, int sxy, int sll, const double x[], const double y[], double phi[], double theta[], double lng[], double lat[], int stat[]); int cels2x(struct celprm *cel, int nlng, int nlat, int sll, int sxy, const double lng[], const double lat[], double phi[], double theta[], double x[], double y[], int stat[]); // Deprecated. #define celini_errmsg cel_errmsg #define celprt_errmsg cel_errmsg #define celset_errmsg cel_errmsg #define celx2s_errmsg cel_errmsg #define cels2x_errmsg cel_errmsg #ifdef __cplusplus } #endif #endif // WCSLIB_CEL ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921587.0 astropy-5.0.2/astropy/wcs/include/wcslib/lin.h0000644000175100001710000007051300000000000020411 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: lin.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the lin routines * --------------------------- * Routines in this suite apply the linear transformation defined by the FITS * World Coordinate System (WCS) standard, as described in * = "Representations of world coordinates in FITS", = Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (WCS Paper I) * * These routines are based on the linprm struct which contains all information * needed for the computations. The struct contains some members that must be * set by the user, and others that are maintained by these routines, somewhat * like a C++ class but with no encapsulation. * * Six routines, linini(), lininit(), lindis(), lindist() lincpy(), and * linfree() are provided to manage the linprm struct, linsize() computes its * total size including allocated memory, and linprt() prints its contents. * * linperr() prints the error message(s) (if any) stored in a linprm struct, * and the disprm structs that it may contain. * * A setup routine, linset(), computes intermediate values in the linprm struct * from parameters in it that were supplied by the user. The struct always * needs to be set up by linset() but need not be called explicitly - refer to * the explanation of linprm::flag. * * linp2x() and linx2p() implement the WCS linear transformations. * * An auxiliary routine, linwarp(), computes various measures of the distortion * over a specified range of pixel coordinates. * * An auxiliary matrix inversion routine, matinv(), is included. It uses * LU-triangular factorization with scaled partial pivoting. * * * linini() - Default constructor for the linprm struct * ---------------------------------------------------- * linini() is a thin wrapper on lininit(). It invokes it with ndpmax set * to -1 which causes it to use the value of the global variable NDPMAX. It * is thereby potentially thread-unsafe if NDPMAX is altered dynamically via * disndp(). Use lininit() for a thread-safe alternative in this case. * * * lininit() - Default constructor for the linprm struct * ----------------------------------------------------- * lininit() allocates memory for arrays in a linprm struct and sets all * members of the struct to default values. * * PLEASE NOTE: every linprm struct must be initialized by lininit(), possibly * repeatedly. On the first invokation, and only the first invokation, * linprm::flag must be set to -1 to initialize memory management, regardless * of whether lininit() will actually be used to allocate memory. * * Given: * alloc int If true, allocate memory unconditionally for arrays in * the linprm struct. * * If false, it is assumed that pointers to these arrays * have been set by the user except if they are null * pointers in which case memory will be allocated for * them regardless. (In other words, setting alloc true * saves having to initalize these pointers to zero.) * * naxis int The number of world coordinate axes, used to determine * array sizes. * * Given and returned: * lin struct linprm* * Linear transformation parameters. Note that, in order * to initialize memory management linprm::flag should be * set to -1 when lin is initialized for the first time * (memory leaks may result if it had already been * initialized). * * Given: * ndpmax int The number of DPja or DQia keywords to allocate space * for. If set to -1, the value of the global variable * NDPMAX will be used. This is potentially * thread-unsafe if disndp() is being used dynamically to * alter its value. * * Function return value: * int Status return value: * 0: Success. * 1: Null linprm pointer passed. * 2: Memory allocation failed. * * For returns > 1, a detailed error message is set in * linprm::err if enabled, see wcserr_enable(). * * * lindis() - Assign a distortion to a linprm struct * ------------------------------------------------- * lindis() is a thin wrapper on lindist(). It invokes it with ndpmax set * to -1 which causes the value of the global variable NDPMAX to be used (by * disinit()). It is thereby potentially thread-unsafe if NDPMAX is altered * dynamically via disndp(). Use lindist() for a thread-safe alternative in * this case. * * * lindist() - Assign a distortion to a linprm struct * -------------------------------------------------- * lindist() may be used to assign the address of a disprm struct to * linprm::dispre or linprm::disseq. The linprm struct must already have been * initialized by lininit(). * * The disprm struct must have been allocated from the heap (e.g. using * malloc(), calloc(), etc.). lindist() will immediately initialize it via a * call to disini() using the value of linprm::naxis. Subsequently, it will be * reinitialized by calls to lininit(), and freed by linfree(), neither of * which would happen if the disprm struct was assigned directly. * * If the disprm struct had previously been assigned via lindist(), it will be * freed before reassignment. It is also permissable for a null disprm pointer * to be assigned to disable the distortion correction. * * Given: * sequence int Is it a prior or sequent distortion? * 1: Prior, the assignment is to linprm::dispre. * 2: Sequent, the assignment is to linprm::disseq. * * Anything else is an error. * * Given and returned: * lin struct linprm* * Linear transformation parameters. * * dis struct disprm* * Distortion function parameters. * * Given: * ndpmax int The number of DPja or DQia keywords to allocate space * for. If set to -1, the value of the global variable * NDPMAX will be used. This is potentially * thread-unsafe if disndp() is being used dynamically to * alter its value. * * Function return value: * int Status return value: * 0: Success. * 1: Null linprm pointer passed. * 4: Invalid sequence. * * * lincpy() - Copy routine for the linprm struct * --------------------------------------------- * lincpy() does a deep copy of one linprm struct to another, using lininit() * to allocate memory for its arrays if required. Only the "information to be * provided" part of the struct is copied; a call to linset() is required to * initialize the remainder. * * Given: * alloc int If true, allocate memory for the crpix, pc, and cdelt * arrays in the destination. Otherwise, it is assumed * that pointers to these arrays have been set by the * user except if they are null pointers in which case * memory will be allocated for them regardless. * * linsrc const struct linprm* * Struct to copy from. * * Given and returned: * lindst struct linprm* * Struct to copy to. linprm::flag should be set to -1 * if lindst was not previously initialized (memory leaks * may result if it was previously initialized). * * Function return value: * int Status return value: * 0: Success. * 1: Null linprm pointer passed. * 2: Memory allocation failed. * * For returns > 1, a detailed error message is set in * linprm::err if enabled, see wcserr_enable(). * * * linfree() - Destructor for the linprm struct * -------------------------------------------- * linfree() frees memory allocated for the linprm arrays by lininit() and/or * linset(). lininit() keeps a record of the memory it allocates and linfree() * will only attempt to free this. * * PLEASE NOTE: linfree() must not be invoked on a linprm struct that was not * initialized by lininit(). * * Given: * lin struct linprm* * Linear transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null linprm pointer passed. * * * linsize() - Compute the size of a linprm struct * ----------------------------------------------- * linsize() computes the full size of a linprm struct, including allocated * memory. * * Given: * lin const struct linprm* * Linear transformation parameters. * * If NULL, the base size of the struct and the allocated * size are both set to zero. * * Returned: * sizes int[2] The first element is the base size of the struct as * returned by sizeof(struct linprm). * * The second element is the total size of memory * allocated in the struct, in bytes, assuming that the * allocation was done by linini(). This figure includes * memory allocated for members of constituent structs, * such as linprm::dispre. * * It is not an error for the struct not to have been set * up via linset(), which normally results in additional * memory allocation. * * Function return value: * int Status return value: * 0: Success. * * * linprt() - Print routine for the linprm struct * ---------------------------------------------- * linprt() prints the contents of a linprm struct using wcsprintf(). Mainly * intended for diagnostic purposes. * * Given: * lin const struct linprm* * Linear transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null linprm pointer passed. * * * linperr() - Print error messages from a linprm struct * ----------------------------------------------------- * linperr() prints the error message(s) (if any) stored in a linprm struct, * and the disprm structs that it may contain. If there are no errors then * nothing is printed. It uses wcserr_prt(), q.v. * * Given: * lin const struct linprm* * Coordinate transformation parameters. * * prefix const char * * If non-NULL, each output line will be prefixed with * this string. * * Function return value: * int Status return value: * 0: Success. * 1: Null linprm pointer passed. * * * linset() - Setup routine for the linprm struct * ---------------------------------------------- * linset(), if necessary, allocates memory for the linprm::piximg and * linprm::imgpix arrays and sets up the linprm struct according to information * supplied within it - refer to the explanation of linprm::flag. * * Note that this routine need not be called directly; it will be invoked by * linp2x() and linx2p() if the linprm::flag is anything other than a * predefined magic value. * * Given and returned: * lin struct linprm* * Linear transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null linprm pointer passed. * 2: Memory allocation failed. * 3: PCi_ja matrix is singular. * * For returns > 1, a detailed error message is set in * linprm::err if enabled, see wcserr_enable(). * * * linp2x() - Pixel-to-world linear transformation * ----------------------------------------------- * linp2x() transforms pixel coordinates to intermediate world coordinates. * * Given and returned: * lin struct linprm* * Linear transformation parameters. * * Given: * ncoord, * nelem int The number of coordinates, each of vector length nelem * but containing lin.naxis coordinate elements. * * pixcrd const double[ncoord][nelem] * Array of pixel coordinates. * * Returned: * imgcrd double[ncoord][nelem] * Array of intermediate world coordinates. * * Function return value: * int Status return value: * 0: Success. * 1: Null linprm pointer passed. * 2: Memory allocation failed. * 3: PCi_ja matrix is singular. * * For returns > 1, a detailed error message is set in * linprm::err if enabled, see wcserr_enable(). * * * linx2p() - World-to-pixel linear transformation * ----------------------------------------------- * linx2p() transforms intermediate world coordinates to pixel coordinates. * * Given and returned: * lin struct linprm* * Linear transformation parameters. * * Given: * ncoord, * nelem int The number of coordinates, each of vector length nelem * but containing lin.naxis coordinate elements. * * imgcrd const double[ncoord][nelem] * Array of intermediate world coordinates. * * Returned: * pixcrd double[ncoord][nelem] * Array of pixel coordinates. * * int Status return value: * 0: Success. * 1: Null linprm pointer passed. * 2: Memory allocation failed. * 3: PCi_ja matrix is singular. * * For returns > 1, a detailed error message is set in * linprm::err if enabled, see wcserr_enable(). * * * linwarp() - Compute measures of distortion * ------------------------------------------ * linwarp() computes various measures of the distortion over a specified range * of pixel coordinates. * * All distortion measures are specified as an offset in pixel coordinates, * as given directly by prior distortions. The offset in intermediate pixel * coordinates given by sequent distortions is translated back to pixel * coordinates by applying the inverse of the linear transformation matrix * (PCi_ja or CDi_ja). The difference may be significant if the matrix * introduced a scaling. * * If all distortions are prior, then linwarp() uses diswarp(), q.v. * * Given and returned: * lin struct linprm* * Linear transformation parameters plus distortions. * * Given: * pixblc const double[naxis] * Start of the range of pixel coordinates (i.e. "bottom * left-hand corner" in the conventional FITS image * display orientation). May be specified as a NULL * pointer which is interpreted as (1,1,...). * * pixtrc const double[naxis] * End of the range of pixel coordinates (i.e. "top * right-hand corner" in the conventional FITS image * display orientation). * * pixsamp const double[naxis] * If positive or zero, the increment on the particular * axis, starting at pixblc[]. Zero is interpreted as a * unit increment. pixsamp may also be specified as a * NULL pointer which is interpreted as all zeroes, i.e. * unit increments on all axes. * * If negative, the grid size on the particular axis (the * absolute value being rounded to the nearest integer). * For example, if pixsamp is (-128.0,-128.0,...) then * each axis will be sampled at 128 points between * pixblc[] and pixtrc[] inclusive. Use caution when * using this option on non-square images. * * Returned: * nsamp int* The number of pixel coordinates sampled. * * Can be specified as a NULL pointer if not required. * * maxdis double[naxis] * For each individual distortion function, the * maximum absolute value of the distortion. * * Can be specified as a NULL pointer if not required. * * maxtot double* For the combination of all distortion functions, the * maximum absolute value of the distortion. * * Can be specified as a NULL pointer if not required. * * avgdis double[naxis] * For each individual distortion function, the * mean value of the distortion. * * Can be specified as a NULL pointer if not required. * * avgtot double* For the combination of all distortion functions, the * mean value of the distortion. * * Can be specified as a NULL pointer if not required. * * rmsdis double[naxis] * For each individual distortion function, the * root mean square deviation of the distortion. * * Can be specified as a NULL pointer if not required. * * rmstot double* For the combination of all distortion functions, the * root mean square deviation of the distortion. * * Can be specified as a NULL pointer if not required. * * Function return value: * int Status return value: * 0: Success. * 1: Null linprm pointer passed. * 2: Memory allocation failed. * 3: Invalid parameter. * 4: Distort error. * * * linprm struct - Linear transformation parameters * ------------------------------------------------ * The linprm struct contains all of the information required to perform a * linear transformation. It consists of certain members that must be set by * the user ("given") and others that are set by the WCSLIB routines * ("returned"). * * int flag * (Given and returned) This flag must be set to zero whenever any of the * following members of the linprm struct are set or modified: * * - linprm::naxis (q.v., not normally set by the user), * - linprm::pc, * - linprm::cdelt, * - linprm::dispre. * - linprm::disseq. * * This signals the initialization routine, linset(), to recompute the * returned members of the linprm struct. linset() will reset flag to * indicate that this has been done. * * PLEASE NOTE: flag should be set to -1 when lininit() is called for the * first time for a particular linprm struct in order to initialize memory * management. It must ONLY be used on the first initialization otherwise * memory leaks may result. * * int naxis * (Given or returned) Number of pixel and world coordinate elements. * * If lininit() is used to initialize the linprm struct (as would normally * be the case) then it will set naxis from the value passed to it as a * function argument. The user should not subsequently modify it. * * double *crpix * (Given) Pointer to the first element of an array of double containing * the coordinate reference pixel, CRPIXja. * * It is not necessary to reset the linprm struct (via linset()) when * linprm::crpix is changed. * * double *pc * (Given) Pointer to the first element of the PCi_ja (pixel coordinate) * transformation matrix. The expected order is * = struct linprm lin; = lin.pc = {PC1_1, PC1_2, PC2_1, PC2_2}; * * This may be constructed conveniently from a 2-D array via * = double m[2][2] = {{PC1_1, PC1_2}, = {PC2_1, PC2_2}}; * * which is equivalent to * = double m[2][2]; = m[0][0] = PC1_1; = m[0][1] = PC1_2; = m[1][0] = PC2_1; = m[1][1] = PC2_2; * * The storage order for this 2-D array is the same as for the 1-D array, * whence * = lin.pc = *m; * * would be legitimate. * * double *cdelt * (Given) Pointer to the first element of an array of double containing * the coordinate increments, CDELTia. * * struct disprm *dispre * (Given) Pointer to a disprm struct holding parameters for prior * distortion functions, or a null (0x0) pointer if there are none. * * Function lindist() may be used to assign a disprm pointer to a linprm * struct, allowing it to take control of any memory allocated for it, as * in the following example: * = void add_distortion(struct linprm *lin) = { = struct disprm *dispre; = = dispre = malloc(sizeof(struct disprm)); = dispre->flag = -1; = lindist(1, lin, dispre, ndpmax); = : = (Set up dispre.) = : = = return; = } * * Here, after the distortion function parameters etc. are copied into * dispre, dispre is assigned using lindist() which takes control of the * allocated memory. It will be freed later when linfree() is invoked on * the linprm struct. * * Consider also the following erroneous code: * = void bad_code(struct linprm *lin) = { = struct disprm dispre; = = dispre.flag = -1; = lindist(1, lin, &dispre, ndpmax); // WRONG. = : = = return; = } * * Here, dispre is declared as a struct, rather than a pointer. When the * function returns, dispre will go out of scope and its memory will most * likely be reused, thereby trashing its contents. Later, a segfault will * occur when linfree() tries to free dispre's stale address. * * struct disprm *disseq * (Given) Pointer to a disprm struct holding parameters for sequent * distortion functions, or a null (0x0) pointer if there are none. * * Refer to the comments and examples given for disprm::dispre. * * double *piximg * (Returned) Pointer to the first element of the matrix containing the * product of the CDELTia diagonal matrix and the PCi_ja matrix. * * double *imgpix * (Returned) Pointer to the first element of the inverse of the * linprm::piximg matrix. * * int i_naxis * (Returned) The dimension of linprm::piximg and linprm::imgpix (normally * equal to naxis). * * int unity * (Returned) True if the linear transformation matrix is unity. * * int affine * (Returned) True if there are no distortions. * * int simple * (Returned) True if unity and no distortions. * * struct wcserr *err * (Returned) If enabled, when an error status is returned, this struct * contains detailed information about the error, see wcserr_enable(). * * double *tmpcrd * (For internal use only.) * int m_flag * (For internal use only.) * int m_naxis * (For internal use only.) * double *m_crpix * (For internal use only.) * double *m_pc * (For internal use only.) * double *m_cdelt * (For internal use only.) * struct disprm *m_dispre * (For internal use only.) * struct disprm *m_disseq * (For internal use only.) * * * Global variable: const char *lin_errmsg[] - Status return messages * ------------------------------------------------------------------ * Error messages to match the status value returned from each function. * *===========================================================================*/ #ifndef WCSLIB_LIN #define WCSLIB_LIN #ifdef __cplusplus extern "C" { #endif extern const char *lin_errmsg[]; enum lin_errmsg_enum { LINERR_SUCCESS = 0, // Success. LINERR_NULL_POINTER = 1, // Null linprm pointer passed. LINERR_MEMORY = 2, // Memory allocation failed. LINERR_SINGULAR_MTX = 3, // PCi_ja matrix is singular. LINERR_DISTORT_INIT = 4, // Failed to initialise distortions. LINERR_DISTORT = 5, // Distort error. LINERR_DEDISTORT = 6 // De-distort error. }; struct linprm { // Initialization flag (see the prologue above). //-------------------------------------------------------------------------- int flag; // Set to zero to force initialization. // Parameters to be provided (see the prologue above). //-------------------------------------------------------------------------- int naxis; // The number of axes, given by NAXIS. double *crpix; // CRPIXja keywords for each pixel axis. double *pc; // PCi_ja linear transformation matrix. double *cdelt; // CDELTia keywords for each coord axis. struct disprm *dispre; // Prior distortion parameters, if any. struct disprm *disseq; // Sequent distortion parameters, if any. // Information derived from the parameters supplied. //-------------------------------------------------------------------------- double *piximg; // Product of CDELTia and PCi_ja matrices. double *imgpix; // Inverse of the piximg matrix. int i_naxis; // Dimension of piximg and imgpix. int unity; // True if the PCi_ja matrix is unity. int affine; // True if there are no distortions. int simple; // True if unity and no distortions. // Error handling, if enabled. //-------------------------------------------------------------------------- struct wcserr *err; // Private - the remainder are for internal use. //-------------------------------------------------------------------------- double *tmpcrd; int m_flag, m_naxis; double *m_crpix, *m_pc, *m_cdelt; struct disprm *m_dispre, *m_disseq; }; // Size of the linprm struct in int units, used by the Fortran wrappers. #define LINLEN (sizeof(struct linprm)/sizeof(int)) int linini(int alloc, int naxis, struct linprm *lin); int lininit(int alloc, int naxis, struct linprm *lin, int ndpmax); int lindis(int sequence, struct linprm *lin, struct disprm *dis); int lindist(int sequence, struct linprm *lin, struct disprm *dis, int ndpmax); int lincpy(int alloc, const struct linprm *linsrc, struct linprm *lindst); int linfree(struct linprm *lin); int linsize(const struct linprm *lin, int sizes[2]); int linprt(const struct linprm *lin); int linperr(const struct linprm *lin, const char *prefix); int linset(struct linprm *lin); int linp2x(struct linprm *lin, int ncoord, int nelem, const double pixcrd[], double imgcrd[]); int linx2p(struct linprm *lin, int ncoord, int nelem, const double imgcrd[], double pixcrd[]); int linwarp(struct linprm *lin, const double pixblc[], const double pixtrc[], const double pixsamp[], int *nsamp, double maxdis[], double *maxtot, double avgdis[], double *avgtot, double rmsdis[], double *rmstot); int matinv(int n, const double mat[], double inv[]); // Deprecated. #define linini_errmsg lin_errmsg #define lincpy_errmsg lin_errmsg #define linfree_errmsg lin_errmsg #define linprt_errmsg lin_errmsg #define linset_errmsg lin_errmsg #define linp2x_errmsg lin_errmsg #define linx2p_errmsg lin_errmsg #ifdef __cplusplus } #endif #endif // WCSLIB_LIN ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921587.0 astropy-5.0.2/astropy/wcs/include/wcslib/prj.h0000644000175100001710000007713500000000000020431 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: prj.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the prj routines * --------------------------- * Routines in this suite implement the spherical map projections defined by * the FITS World Coordinate System (WCS) standard, as described in * = "Representations of world coordinates in FITS", = Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (WCS Paper I) = = "Representations of celestial coordinates in FITS", = Calabretta, M.R., & Greisen, E.W. 2002, A&A, 395, 1077 (WCS Paper II) = = "Mapping on the HEALPix grid", = Calabretta, M.R., & Roukema, B.F. 2007, MNRAS, 381, 865 (WCS Paper V) = = "Representing the 'Butterfly' Projection in FITS -- Projection Code XPH", = Calabretta, M.R., & Lowe, S.R. 2013, PASA, 30, e050 (WCS Paper VI) * * These routines are based on the prjprm struct which contains all information * needed for the computations. The struct contains some members that must be * set by the user, and others that are maintained by these routines, somewhat * like a C++ class but with no encapsulation. * * Routine prjini() is provided to initialize the prjprm struct with default * values, prjfree() reclaims any memory that may have been allocated to store * an error message, prjsize() computes its total size including allocated * memory, and prjprt() prints its contents. * * prjperr() prints the error message(s) (if any) stored in a prjprm struct. * prjbchk() performs bounds checking on native spherical coordinates. * * Setup routines for each projection with names of the form ???set(), where * "???" is the down-cased three-letter projection code, compute intermediate * values in the prjprm struct from parameters in it that were supplied by the * user. The struct always needs to be set by the projection's setup routine * but that need not be called explicitly - refer to the explanation of * prjprm::flag. * * Each map projection is implemented via separate functions for the spherical * projection, ???s2x(), and deprojection, ???x2s(). * * A set of driver routines, prjset(), prjx2s(), and prjs2x(), provides a * generic interface to the specific projection routines which they invoke * via pointers-to-functions stored in the prjprm struct. * * In summary, the routines are: * - prjini() Initialization routine for the prjprm struct. * - prjfree() Reclaim memory allocated for error messages. * - prjsize() Compute total size of a prjprm struct. * - prjprt() Print a prjprm struct. * - prjperr() Print error message (if any). * - prjbchk() Bounds checking on native coordinates. * * - prjset(), prjx2s(), prjs2x(): Generic driver routines * * - azpset(), azpx2s(), azps2x(): AZP (zenithal/azimuthal perspective) * - szpset(), szpx2s(), szps2x(): SZP (slant zenithal perspective) * - tanset(), tanx2s(), tans2x(): TAN (gnomonic) * - stgset(), stgx2s(), stgs2x(): STG (stereographic) * - sinset(), sinx2s(), sins2x(): SIN (orthographic/synthesis) * - arcset(), arcx2s(), arcs2x(): ARC (zenithal/azimuthal equidistant) * - zpnset(), zpnx2s(), zpns2x(): ZPN (zenithal/azimuthal polynomial) * - zeaset(), zeax2s(), zeas2x(): ZEA (zenithal/azimuthal equal area) * - airset(), airx2s(), airs2x(): AIR (Airy) * - cypset(), cypx2s(), cyps2x(): CYP (cylindrical perspective) * - ceaset(), ceax2s(), ceas2x(): CEA (cylindrical equal area) * - carset(), carx2s(), cars2x(): CAR (Plate carree) * - merset(), merx2s(), mers2x(): MER (Mercator) * - sflset(), sflx2s(), sfls2x(): SFL (Sanson-Flamsteed) * - parset(), parx2s(), pars2x(): PAR (parabolic) * - molset(), molx2s(), mols2x(): MOL (Mollweide) * - aitset(), aitx2s(), aits2x(): AIT (Hammer-Aitoff) * - copset(), copx2s(), cops2x(): COP (conic perspective) * - coeset(), coex2s(), coes2x(): COE (conic equal area) * - codset(), codx2s(), cods2x(): COD (conic equidistant) * - cooset(), coox2s(), coos2x(): COO (conic orthomorphic) * - bonset(), bonx2s(), bons2x(): BON (Bonne) * - pcoset(), pcox2s(), pcos2x(): PCO (polyconic) * - tscset(), tscx2s(), tscs2x(): TSC (tangential spherical cube) * - cscset(), cscx2s(), cscs2x(): CSC (COBE spherical cube) * - qscset(), qscx2s(), qscs2x(): QSC (quadrilateralized spherical cube) * - hpxset(), hpxx2s(), hpxs2x(): HPX (HEALPix) * - xphset(), xphx2s(), xphs2x(): XPH (HEALPix polar, aka "butterfly") * * Argument checking (projection routines): * ---------------------------------------- * The values of phi and theta (the native longitude and latitude) normally lie * in the range [-180,180] for phi, and [-90,90] for theta. However, all * projection routines will accept any value of phi and will not normalize it. * * The projection routines do not explicitly check that theta lies within the * range [-90,90]. They do check for any value of theta that produces an * invalid argument to the projection equations (e.g. leading to division by * zero). The projection routines for AZP, SZP, TAN, SIN, ZPN, and COP also * return error 2 if (phi,theta) corresponds to the overlapped (far) side of * the projection but also return the corresponding value of (x,y). This * strict bounds checking may be relaxed at any time by setting * prjprm::bounds%2 to 0 (rather than 1); the projections need not be * reinitialized. * * Argument checking (deprojection routines): * ------------------------------------------ * Error checking on the projected coordinates (x,y) is limited to that * required to ascertain whether a solution exists. Where a solution does * exist, an optional check is made that the value of phi and theta obtained * lie within the ranges [-180,180] for phi, and [-90,90] for theta. This * check, performed by prjbchk(), is enabled by default. It may be disabled by * setting prjprm::bounds%4 to 0 (rather than 1); the projections need not be * reinitialized. * * Accuracy: * --------- * No warranty is given for the accuracy of these routines (refer to the * copyright notice); intending users must satisfy for themselves their * adequacy for the intended purpose. However, closure to a precision of at * least 1E-10 degree of longitude and latitude has been verified for typical * projection parameters on the 1 degree graticule of native longitude and * latitude (to within 5 degrees of any latitude where the projection may * diverge). Refer to the tprj1.c and tprj2.c test routines that accompany * this software. * * * prjini() - Default constructor for the prjprm struct * ---------------------------------------------------- * prjini() sets all members of a prjprm struct to default values. It should * be used to initialize every prjprm struct. * * PLEASE NOTE: If the prjprm struct has already been initialized, then before * reinitializing, it prjfree() should be used to free any memory that may have * been allocated to store an error message. A memory leak may otherwise * result. * * Returned: * prj struct prjprm* * Projection parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null prjprm pointer passed. * * * prjfree() - Destructor for the prjprm struct * -------------------------------------------- * prjfree() frees any memory that may have been allocated to store an error * message in the prjprm struct. * * Given: * prj struct prjprm* * Projection parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null prjprm pointer passed. * * * prjsize() - Compute the size of a prjprm struct * ----------------------------------------------- * prjsize() computes the full size of a prjprm struct, including allocated * memory. * * Given: * prj const struct prjprm* * Projection parameters. * * If NULL, the base size of the struct and the allocated * size are both set to zero. * * Returned: * sizes int[2] The first element is the base size of the struct as * returned by sizeof(struct prjprm). The second element * is the total allocated size, in bytes. This figure * includes memory allocated for the constituent struct, * prjprm::err. * * It is not an error for the struct not to have been set * up via prjset(). * * Function return value: * int Status return value: * 0: Success. * * * prjprt() - Print routine for the prjprm struct * ---------------------------------------------- * prjprt() prints the contents of a prjprm struct using wcsprintf(). Mainly * intended for diagnostic purposes. * * Given: * prj const struct prjprm* * Projection parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null prjprm pointer passed. * * * prjperr() - Print error messages from a prjprm struct * ----------------------------------------------------- * prjperr() prints the error message(s) (if any) stored in a prjprm struct. * If there are no errors then nothing is printed. It uses wcserr_prt(), q.v. * * Given: * prj const struct prjprm* * Projection parameters. * * prefix const char * * If non-NULL, each output line will be prefixed with * this string. * * Function return value: * int Status return value: * 0: Success. * 1: Null prjprm pointer passed. * * * prjbchk() - Bounds checking on native coordinates * ------------------------------------------------- * prjbchk() performs bounds checking on native spherical coordinates. As * returned by the deprojection (x2s) routines, native longitude is expected * to lie in the closed interval [-180,180], with latitude in [-90,90]. * * A tolerance may be specified to provide a small allowance for numerical * imprecision. Values that lie outside the allowed range by not more than * the specified tolerance will be adjusted back into range. * * If prjprm::bounds&4 is set, as it is by prjini(), then prjbchk() will be * invoked automatically by the Cartesian-to-spherical deprojection (x2s) * routines with an appropriate tolerance set for each projection. * * Given: * tol double Tolerance for the bounds check [deg]. * * nphi, * ntheta int Vector lengths. * * spt int Vector stride. * * Given and returned: * phi,theta double[] Native longitude and latitude (phi,theta) [deg]. * * Returned: * stat int[] Status value for each vector element: * 0: Valid value of (phi,theta). * 1: Invalid value. * * Function return value: * int Status return value: * 0: Success. * 1: One or more of the (phi,theta) coordinates * were, invalid, as indicated by the stat vector. * * * prjset() - Generic setup routine for the prjprm struct * ------------------------------------------------------ * prjset() sets up a prjprm struct according to information supplied within * it. * * Note that this routine need not be called directly; it will be invoked by * prjx2s() and prjs2x() if prj.flag is anything other than a predefined magic * value. * * The one important distinction between prjset() and the setup routines for * the specific projections is that the projection code must be defined in the * prjprm struct in order for prjset() to identify the required projection. * Once prjset() has initialized the prjprm struct, prjx2s() and prjs2x() use * the pointers to the specific projection and deprojection routines contained * therein. * * Given and returned: * prj struct prjprm* * Projection parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null prjprm pointer passed. * 2: Invalid projection parameters. * * For returns > 1, a detailed error message is set in * prjprm::err if enabled, see wcserr_enable(). * * * prjx2s() - Generic Cartesian-to-spherical deprojection * ------------------------------------------------------ * Deproject Cartesian (x,y) coordinates in the plane of projection to native * spherical coordinates (phi,theta). * * The projection is that specified by prjprm::code. * * Given and returned: * prj struct prjprm* * Projection parameters. * * Given: * nx,ny int Vector lengths. * * sxy,spt int Vector strides. * * x,y const double[] * Projected coordinates. * * Returned: * phi,theta double[] Longitude and latitude (phi,theta) of the projected * point in native spherical coordinates [deg]. * * stat int[] Status value for each vector element: * 0: Success. * 1: Invalid value of (x,y). * * Function return value: * int Status return value: * 0: Success. * 1: Null prjprm pointer passed. * 2: Invalid projection parameters. * 3: One or more of the (x,y) coordinates were * invalid, as indicated by the stat vector. * * For returns > 1, a detailed error message is set in * prjprm::err if enabled, see wcserr_enable(). * * * prjs2x() - Generic spherical-to-Cartesian projection * ---------------------------------------------------- * Project native spherical coordinates (phi,theta) to Cartesian (x,y) * coordinates in the plane of projection. * * The projection is that specified by prjprm::code. * * Given and returned: * prj struct prjprm* * Projection parameters. * * Given: * nphi, * ntheta int Vector lengths. * * spt,sxy int Vector strides. * * phi,theta const double[] * Longitude and latitude (phi,theta) of the projected * point in native spherical coordinates [deg]. * * Returned: * x,y double[] Projected coordinates. * * stat int[] Status value for each vector element: * 0: Success. * 1: Invalid value of (phi,theta). * * Function return value: * int Status return value: * 0: Success. * 1: Null prjprm pointer passed. * 2: Invalid projection parameters. * 4: One or more of the (phi,theta) coordinates * were, invalid, as indicated by the stat vector. * * For returns > 1, a detailed error message is set in * prjprm::err if enabled, see wcserr_enable(). * * * ???set() - Specific setup routines for the prjprm struct * -------------------------------------------------------- * Set up a prjprm struct for a particular projection according to information * supplied within it. * * Given and returned: * prj struct prjprm* * Projection parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null prjprm pointer passed. * 2: Invalid projection parameters. * * For returns > 1, a detailed error message is set in * prjprm::err if enabled, see wcserr_enable(). * * * ???x2s() - Specific Cartesian-to-spherical deprojection routines * ---------------------------------------------------------------- * Transform (x,y) coordinates in the plane of projection to native spherical * coordinates (phi,theta). * * Given and returned: * prj struct prjprm* * Projection parameters. * * Given: * nx,ny int Vector lengths. * * sxy,spt int Vector strides. * * x,y const double[] * Projected coordinates. * * Returned: * phi,theta double[] Longitude and latitude of the projected point in * native spherical coordinates [deg]. * * stat int[] Status value for each vector element: * 0: Success. * 1: Invalid value of (x,y). * * Function return value: * int Status return value: * 0: Success. * 1: Null prjprm pointer passed. * 2: Invalid projection parameters. * 3: One or more of the (x,y) coordinates were * invalid, as indicated by the stat vector. * * For returns > 1, a detailed error message is set in * prjprm::err if enabled, see wcserr_enable(). * * * ???s2x() - Specific spherical-to-Cartesian projection routines *--------------------------------------------------------------- * Transform native spherical coordinates (phi,theta) to (x,y) coordinates in * the plane of projection. * * Given and returned: * prj struct prjprm* * Projection parameters. * * Given: * nphi, * ntheta int Vector lengths. * * spt,sxy int Vector strides. * * phi,theta const double[] * Longitude and latitude of the projected point in * native spherical coordinates [deg]. * * Returned: * x,y double[] Projected coordinates. * * stat int[] Status value for each vector element: * 0: Success. * 1: Invalid value of (phi,theta). * * Function return value: * int Status return value: * 0: Success. * 1: Null prjprm pointer passed. * 2: Invalid projection parameters. * 4: One or more of the (phi,theta) coordinates * were, invalid, as indicated by the stat vector. * * For returns > 1, a detailed error message is set in * prjprm::err if enabled, see wcserr_enable(). * * * prjprm struct - Projection parameters * ------------------------------------- * The prjprm struct contains all information needed to project or deproject * native spherical coordinates. It consists of certain members that must be * set by the user ("given") and others that are set by the WCSLIB routines * ("returned"). Some of the latter are supplied for informational purposes * while others are for internal use only. * * int flag * (Given and returned) This flag must be set to zero whenever any of the * following prjprm struct members are set or changed: * * - prjprm::code, * - prjprm::r0, * - prjprm::pv[], * - prjprm::phi0, * - prjprm::theta0. * * This signals the initialization routine (prjset() or ???set()) to * recompute the returned members of the prjprm struct. flag will then be * reset to indicate that this has been done. * * Note that flag need not be reset when prjprm::bounds is changed. * * char code[4] * (Given) Three-letter projection code defined by the FITS standard. * * double r0 * (Given) The radius of the generating sphere for the projection, a linear * scaling parameter. If this is zero, it will be reset to its default * value of 180/pi (the value for FITS WCS). * * double pv[30] * (Given) Projection parameters. These correspond to the PVi_ma keywords * in FITS, so pv[0] is PVi_0a, pv[1] is PVi_1a, etc., where i denotes the * latitude-like axis. Many projections use pv[1] (PVi_1a), some also use * pv[2] (PVi_2a) and SZP uses pv[3] (PVi_3a). ZPN is currently the only * projection that uses any of the others. * * Usage of the pv[] array as it applies to each projection is described in * the prologue to each trio of projection routines in prj.c. * * double phi0 * (Given) The native longitude, phi_0 [deg], and ... * double theta0 * (Given) ... the native latitude, theta_0 [deg], of the reference point, * i.e. the point (x,y) = (0,0). If undefined (set to a magic value by * prjini()) the initialization routine will set this to a * projection-specific default. * * int bounds * (Given) Controls bounds checking. If bounds&1 then enable strict bounds * checking for the spherical-to-Cartesian (s2x) transformation for the * AZP, SZP, TAN, SIN, ZPN, and COP projections. If bounds&2 then enable * strict bounds checking for the Cartesian-to-spherical transformation * (x2s) for the HPX and XPH projections. If bounds&4 then the Cartesian- * to-spherical transformations (x2s) will invoke prjbchk() to perform * bounds checking on the computed native coordinates, with a tolerance set * to suit each projection. bounds is set to 7 by prjini() by default * which enables all checks. Zero it to disable all checking. * * It is not necessary to reset the prjprm struct (via prjset() or * ???set()) when prjprm::bounds is changed. * * The remaining members of the prjprm struct are maintained by the setup * routines and must not be modified elsewhere: * * char name[40] * (Returned) Long name of the projection. * * Provided for information only, not used by the projection routines. * * int category * (Returned) Projection category matching the value of the relevant global * variable: * * - ZENITHAL, * - CYLINDRICAL, * - PSEUDOCYLINDRICAL, * - CONVENTIONAL, * - CONIC, * - POLYCONIC, * - QUADCUBE, and * - HEALPIX. * * The category name may be identified via the prj_categories character * array, e.g. * = struct prjprm prj; = ... = printf("%s\n", prj_categories[prj.category]); * * Provided for information only, not used by the projection routines. * * int pvrange * (Returned) Range of projection parameter indices: 100 times the first * allowed index plus the number of parameters, e.g. TAN is 0 (no * parameters), SZP is 103 (1 to 3), and ZPN is 30 (0 to 29). * * Provided for information only, not used by the projection routines. * * int simplezen * (Returned) True if the projection is a radially-symmetric zenithal * projection. * * Provided for information only, not used by the projection routines. * * int equiareal * (Returned) True if the projection is equal area. * * Provided for information only, not used by the projection routines. * * int conformal * (Returned) True if the projection is conformal. * * Provided for information only, not used by the projection routines. * * int global * (Returned) True if the projection can represent the whole sphere in a * finite, non-overlapped mapping. * * Provided for information only, not used by the projection routines. * * int divergent * (Returned) True if the projection diverges in latitude. * * Provided for information only, not used by the projection routines. * * double x0 * (Returned) The offset in x, and ... * double y0 * (Returned) ... the offset in y used to force (x,y) = (0,0) at * (phi_0,theta_0). * * struct wcserr *err * (Returned) If enabled, when an error status is returned, this struct * contains detailed information about the error, see wcserr_enable(). * * void *padding * (An unused variable inserted for alignment purposes only.) * * double w[10] * (Returned) Intermediate floating-point values derived from the * projection parameters, cached here to save recomputation. * * Usage of the w[] array as it applies to each projection is described in * the prologue to each trio of projection routines in prj.c. * * int n * (Returned) Intermediate integer value (used only for the ZPN and HPX * projections). * * int (*prjx2s)(PRJX2S_ARGS) * (Returned) Pointer to the spherical projection ... * int (*prjs2x)(PRJ_ARGS) * (Returned) ... and deprojection routines. * * * Global variable: const char *prj_errmsg[] - Status return messages * ------------------------------------------------------------------ * Error messages to match the status value returned from each function. * *===========================================================================*/ #ifndef WCSLIB_PROJ #define WCSLIB_PROJ #ifdef __cplusplus extern "C" { #endif // Total number of projection parameters; 0 to PVN-1. #define PVN 30 extern const char *prj_errmsg[]; enum prj_errmsg_enum { PRJERR_SUCCESS = 0, // Success. PRJERR_NULL_POINTER = 1, // Null prjprm pointer passed. PRJERR_BAD_PARAM = 2, // Invalid projection parameters. PRJERR_BAD_PIX = 3, // One or more of the (x, y) coordinates were // invalid. PRJERR_BAD_WORLD = 4 // One or more of the (phi, theta) coordinates // were invalid. }; extern const int CONIC, CONVENTIONAL, CYLINDRICAL, POLYCONIC, PSEUDOCYLINDRICAL, QUADCUBE, ZENITHAL, HEALPIX; extern const char prj_categories[9][32]; extern const int prj_ncode; extern const char prj_codes[28][4]; #ifdef PRJX2S_ARGS #undef PRJX2S_ARGS #endif #ifdef PRJS2X_ARGS #undef PRJS2X_ARGS #endif // For use in declaring deprojection function prototypes. #define PRJX2S_ARGS struct prjprm *prj, int nx, int ny, int sxy, int spt, \ const double x[], const double y[], double phi[], double theta[], int stat[] // For use in declaring projection function prototypes. #define PRJS2X_ARGS struct prjprm *prj, int nx, int ny, int sxy, int spt, \ const double phi[], const double theta[], double x[], double y[], int stat[] struct prjprm { // Initialization flag (see the prologue above). //-------------------------------------------------------------------------- int flag; // Set to zero to force initialization. // Parameters to be provided (see the prologue above). //-------------------------------------------------------------------------- char code[4]; // Three-letter projection code. double r0; // Radius of the generating sphere. double pv[PVN]; // Projection parameters. double phi0, theta0; // Fiducial native coordinates. int bounds; // Controls bounds checking. // Information derived from the parameters supplied. //-------------------------------------------------------------------------- char name[40]; // Projection name. int category; // Projection category. int pvrange; // Range of projection parameter indices. int simplezen; // Is it a simple zenithal projection? int equiareal; // Is it an equal area projection? int conformal; // Is it a conformal projection? int global; // Can it map the whole sphere? int divergent; // Does the projection diverge in latitude? double x0, y0; // Fiducial offsets. // Error handling //-------------------------------------------------------------------------- struct wcserr *err; // Private //-------------------------------------------------------------------------- void *padding; // (Dummy inserted for alignment purposes.) double w[10]; // Intermediate values. int m, n; // Intermediate values. int (*prjx2s)(PRJX2S_ARGS); // Pointers to the spherical projection and int (*prjs2x)(PRJS2X_ARGS); // deprojection functions. }; // Size of the prjprm struct in int units, used by the Fortran wrappers. #define PRJLEN (sizeof(struct prjprm)/sizeof(int)) int prjini(struct prjprm *prj); int prjfree(struct prjprm *prj); int prjsize(const struct prjprm *prj, int sizes[2]); int prjprt(const struct prjprm *prj); int prjperr(const struct prjprm *prj, const char *prefix); int prjbchk(double tol, int nphi, int ntheta, int spt, double phi[], double theta[], int stat[]); // Use the preprocessor to help declare function prototypes (see above). int prjset(struct prjprm *prj); int prjx2s(PRJX2S_ARGS); int prjs2x(PRJS2X_ARGS); int azpset(struct prjprm *prj); int azpx2s(PRJX2S_ARGS); int azps2x(PRJS2X_ARGS); int szpset(struct prjprm *prj); int szpx2s(PRJX2S_ARGS); int szps2x(PRJS2X_ARGS); int tanset(struct prjprm *prj); int tanx2s(PRJX2S_ARGS); int tans2x(PRJS2X_ARGS); int stgset(struct prjprm *prj); int stgx2s(PRJX2S_ARGS); int stgs2x(PRJS2X_ARGS); int sinset(struct prjprm *prj); int sinx2s(PRJX2S_ARGS); int sins2x(PRJS2X_ARGS); int arcset(struct prjprm *prj); int arcx2s(PRJX2S_ARGS); int arcs2x(PRJS2X_ARGS); int zpnset(struct prjprm *prj); int zpnx2s(PRJX2S_ARGS); int zpns2x(PRJS2X_ARGS); int zeaset(struct prjprm *prj); int zeax2s(PRJX2S_ARGS); int zeas2x(PRJS2X_ARGS); int airset(struct prjprm *prj); int airx2s(PRJX2S_ARGS); int airs2x(PRJS2X_ARGS); int cypset(struct prjprm *prj); int cypx2s(PRJX2S_ARGS); int cyps2x(PRJS2X_ARGS); int ceaset(struct prjprm *prj); int ceax2s(PRJX2S_ARGS); int ceas2x(PRJS2X_ARGS); int carset(struct prjprm *prj); int carx2s(PRJX2S_ARGS); int cars2x(PRJS2X_ARGS); int merset(struct prjprm *prj); int merx2s(PRJX2S_ARGS); int mers2x(PRJS2X_ARGS); int sflset(struct prjprm *prj); int sflx2s(PRJX2S_ARGS); int sfls2x(PRJS2X_ARGS); int parset(struct prjprm *prj); int parx2s(PRJX2S_ARGS); int pars2x(PRJS2X_ARGS); int molset(struct prjprm *prj); int molx2s(PRJX2S_ARGS); int mols2x(PRJS2X_ARGS); int aitset(struct prjprm *prj); int aitx2s(PRJX2S_ARGS); int aits2x(PRJS2X_ARGS); int copset(struct prjprm *prj); int copx2s(PRJX2S_ARGS); int cops2x(PRJS2X_ARGS); int coeset(struct prjprm *prj); int coex2s(PRJX2S_ARGS); int coes2x(PRJS2X_ARGS); int codset(struct prjprm *prj); int codx2s(PRJX2S_ARGS); int cods2x(PRJS2X_ARGS); int cooset(struct prjprm *prj); int coox2s(PRJX2S_ARGS); int coos2x(PRJS2X_ARGS); int bonset(struct prjprm *prj); int bonx2s(PRJX2S_ARGS); int bons2x(PRJS2X_ARGS); int pcoset(struct prjprm *prj); int pcox2s(PRJX2S_ARGS); int pcos2x(PRJS2X_ARGS); int tscset(struct prjprm *prj); int tscx2s(PRJX2S_ARGS); int tscs2x(PRJS2X_ARGS); int cscset(struct prjprm *prj); int cscx2s(PRJX2S_ARGS); int cscs2x(PRJS2X_ARGS); int qscset(struct prjprm *prj); int qscx2s(PRJX2S_ARGS); int qscs2x(PRJS2X_ARGS); int hpxset(struct prjprm *prj); int hpxx2s(PRJX2S_ARGS); int hpxs2x(PRJS2X_ARGS); int xphset(struct prjprm *prj); int xphx2s(PRJX2S_ARGS); int xphs2x(PRJS2X_ARGS); // Deprecated. #define prjini_errmsg prj_errmsg #define prjprt_errmsg prj_errmsg #define prjset_errmsg prj_errmsg #define prjx2s_errmsg prj_errmsg #define prjs2x_errmsg prj_errmsg #ifdef __cplusplus } #endif #endif // WCSLIB_PROJ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921587.0 astropy-5.0.2/astropy/wcs/include/wcslib/spc.h0000644000175100001710000011643700000000000020422 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: spc.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the spc routines * --------------------------- * Routines in this suite implement the part of the FITS World Coordinate * System (WCS) standard that deals with spectral coordinates, as described in * = "Representations of world coordinates in FITS", = Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (WCS Paper I) = = "Representations of spectral coordinates in FITS", = Greisen, E.W., Calabretta, M.R., Valdes, F.G., & Allen, S.L. = 2006, A&A, 446, 747 (WCS Paper III) * * These routines define methods to be used for computing spectral world * coordinates from intermediate world coordinates (a linear transformation * of image pixel coordinates), and vice versa. They are based on the spcprm * struct which contains all information needed for the computations. The * struct contains some members that must be set by the user, and others that * are maintained by these routines, somewhat like a C++ class but with no * encapsulation. * * Routine spcini() is provided to initialize the spcprm struct with default * values, spcfree() reclaims any memory that may have been allocated to store * an error message, spcsize() computes its total size including allocated * memory, and spcprt() prints its contents. * * spcperr() prints the error message(s) (if any) stored in a spcprm struct. * * A setup routine, spcset(), computes intermediate values in the spcprm struct * from parameters in it that were supplied by the user. The struct always * needs to be set up by spcset() but it need not be called explicitly - refer * to the explanation of spcprm::flag. * * spcx2s() and spcs2x() implement the WCS spectral coordinate transformations. * In fact, they are high level driver routines for the lower level spectral * coordinate transformation routines described in spx.h. * * A number of routines are provided to aid in analysing or synthesising sets * of FITS spectral axis keywords: * * - spctype() checks a spectral CTYPEia keyword for validity and returns * information derived from it. * * - Spectral keyword analysis routine spcspxe() computes the values of the * X-type spectral variables for the S-type variables supplied. * * - Spectral keyword synthesis routine, spcxpse(), computes the S-type * variables for the X-types supplied. * * - Given a set of spectral keywords, a translation routine, spctrne(), * produces the corresponding set for the specified spectral CTYPEia. * * - spcaips() translates AIPS-convention spectral CTYPEia and VELREF * keyvalues. * * Spectral variable types - S, P, and X: * -------------------------------------- * A few words of explanation are necessary regarding spectral variable types * in FITS. * * Every FITS spectral axis has three associated spectral variables: * * S-type: the spectral variable in which coordinates are to be * expressed. Each S-type is encoded as four characters and is * linearly related to one of four basic types as follows: * * F (Frequency): * - 'FREQ': frequency * - 'AFRQ': angular frequency * - 'ENER': photon energy * - 'WAVN': wave number * - 'VRAD': radio velocity * * W (Wavelength in vacuo): * - 'WAVE': wavelength * - 'VOPT': optical velocity * - 'ZOPT': redshift * * A (wavelength in Air): * - 'AWAV': wavelength in air * * V (Velocity): * - 'VELO': relativistic velocity * - 'BETA': relativistic beta factor * * The S-type forms the first four characters of the CTYPEia keyvalue, * and CRVALia and CDELTia are expressed as S-type quantities so that * they provide a first-order approximation to the S-type variable at * the reference point. * * Note that 'AFRQ', angular frequency, is additional to the variables * defined in WCS Paper III. * * P-type: the basic spectral variable (F, W, A, or V) with which the * S-type variable is associated (see list above). * * For non-grism axes, the P-type is encoded as the eighth character of * CTYPEia. * * X-type: the basic spectral variable (F, W, A, or V) for which the * spectral axis is linear, grisms excluded (see below). * * For non-grism axes, the X-type is encoded as the sixth character of * CTYPEia. * * Grisms: Grism axes have normal S-, and P-types but the axis is linear, * not in any spectral variable, but in a special "grism parameter". * The X-type spectral variable is either W or A for grisms in vacuo or * air respectively, but is encoded as 'w' or 'a' to indicate that an * additional transformation is required to convert to or from the * grism parameter. The spectral algorithm code for grisms also has a * special encoding in CTYPEia, either 'GRI' (in vacuo) or 'GRA' (in air). * * In the algorithm chain, the non-linear transformation occurs between the * X-type and the P-type variables; the transformation between P-type and * S-type variables is always linear. * * When the P-type and X-type variables are the same, the spectral axis is * linear in the S-type variable and the second four characters of CTYPEia * are blank. This can never happen for grism axes. * * As an example, correlating radio spectrometers always produce spectra that * are regularly gridded in frequency; a redshift scale on such a spectrum is * non-linear. The required value of CTYPEia would be 'ZOPT-F2W', where the * desired S-type is 'ZOPT' (redshift), the P-type is necessarily 'W' * (wavelength), and the X-type is 'F' (frequency) by the nature of the * instrument. * * Air-to-vacuum wavelength conversion: * ------------------------------------ * Please refer to the prologue of spx.h for important comments relating to the * air-to-vacuum wavelength conversion. * * Argument checking: * ------------------ * The input spectral values are only checked for values that would result in * floating point exceptions. In particular, negative frequencies and * wavelengths are allowed, as are velocities greater than the speed of * light. The same is true for the spectral parameters - rest frequency and * wavelength. * * Accuracy: * --------- * No warranty is given for the accuracy of these routines (refer to the * copyright notice); intending users must satisfy for themselves their * adequacy for the intended purpose. However, closure effectively to within * double precision rounding error was demonstrated by test routine tspc.c * which accompanies this software. * * * spcini() - Default constructor for the spcprm struct * ---------------------------------------------------- * spcini() sets all members of a spcprm struct to default values. It should * be used to initialize every spcprm struct. * * PLEASE NOTE: If the spcprm struct has already been initialized, then before * reinitializing, it spcfree() should be used to free any memory that may have * been allocated to store an error message. A memory leak may otherwise * result. * * Given and returned: * spc struct spcprm* * Spectral transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null spcprm pointer passed. * * * spcfree() - Destructor for the spcprm struct * -------------------------------------------- * spcfree() frees any memory that may have been allocated to store an error * message in the spcprm struct. * * Given: * spc struct spcprm* * Spectral transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null spcprm pointer passed. * * * spcsize() - Compute the size of a spcprm struct * ----------------------------------------------- * spcsize() computes the full size of a spcprm struct, including allocated * memory. * * Given: * spc const struct spcprm* * Spectral transformation parameters. * * If NULL, the base size of the struct and the allocated * size are both set to zero. * * Returned: * sizes int[2] The first element is the base size of the struct as * returned by sizeof(struct spcprm). The second element * is the total allocated size, in bytes. This figure * includes memory allocated for the constituent struct, * spcprm::err. * * It is not an error for the struct not to have been set * up via spcset(). * * Function return value: * int Status return value: * 0: Success. * * * spcprt() - Print routine for the spcprm struct * ---------------------------------------------- * spcprt() prints the contents of a spcprm struct using wcsprintf(). Mainly * intended for diagnostic purposes. * * Given: * spc const struct spcprm* * Spectral transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null spcprm pointer passed. * * * spcperr() - Print error messages from a spcprm struct * ----------------------------------------------------- * spcperr() prints the error message(s) (if any) stored in a spcprm struct. * If there are no errors then nothing is printed. It uses wcserr_prt(), q.v. * * Given: * spc const struct spcprm* * Spectral transformation parameters. * * prefix const char * * If non-NULL, each output line will be prefixed with * this string. * * Function return value: * int Status return value: * 0: Success. * 1: Null spcprm pointer passed. * * * spcset() - Setup routine for the spcprm struct * ---------------------------------------------- * spcset() sets up a spcprm struct according to information supplied within * it. * * Note that this routine need not be called directly; it will be invoked by * spcx2s() and spcs2x() if spcprm::flag is anything other than a predefined * magic value. * * Given and returned: * spc struct spcprm* * Spectral transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null spcprm pointer passed. * 2: Invalid spectral parameters. * * For returns > 1, a detailed error message is set in * spcprm::err if enabled, see wcserr_enable(). * * * spcx2s() - Transform to spectral coordinates * -------------------------------------------- * spcx2s() transforms intermediate world coordinates to spectral coordinates. * * Given and returned: * spc struct spcprm* * Spectral transformation parameters. * * Given: * nx int Vector length. * * sx int Vector stride. * * sspec int Vector stride. * * x const double[] * Intermediate world coordinates, in SI units. * * Returned: * spec double[] Spectral coordinates, in SI units. * * stat int[] Status return value status for each vector element: * 0: Success. * 1: Invalid value of x. * * Function return value: * int Status return value: * 0: Success. * 1: Null spcprm pointer passed. * 2: Invalid spectral parameters. * 3: One or more of the x coordinates were invalid, * as indicated by the stat vector. * * For returns > 1, a detailed error message is set in * spcprm::err if enabled, see wcserr_enable(). * * * spcs2x() - Transform spectral coordinates * ----------------------------------------- * spcs2x() transforms spectral world coordinates to intermediate world * coordinates. * * Given and returned: * spc struct spcprm* * Spectral transformation parameters. * * Given: * nspec int Vector length. * * sspec int Vector stride. * * sx int Vector stride. * * spec const double[] * Spectral coordinates, in SI units. * * Returned: * x double[] Intermediate world coordinates, in SI units. * * stat int[] Status return value status for each vector element: * 0: Success. * 1: Invalid value of spec. * * Function return value: * int Status return value: * 0: Success. * 1: Null spcprm pointer passed. * 2: Invalid spectral parameters. * 4: One or more of the spec coordinates were * invalid, as indicated by the stat vector. * * For returns > 1, a detailed error message is set in * spcprm::err if enabled, see wcserr_enable(). * * * spctype() - Spectral CTYPEia keyword analysis * --------------------------------------------- * spctype() checks whether a CTYPEia keyvalue is a valid spectral axis type * and if so returns information derived from it relating to the associated S-, * P-, and X-type spectral variables (see explanation above). * * The return arguments are guaranteed not be modified if CTYPEia is not a * valid spectral type; zero-pointers may be specified for any that are not of * interest. * * A deprecated form of this function, spctyp(), lacks the wcserr** parameter. * * Given: * ctype const char[9] * The CTYPEia keyvalue, (eight characters with null * termination). * * Returned: * stype char[] The four-letter name of the S-type spectral variable * copied or translated from ctype. If a non-zero * pointer is given, the array must accomodate a null- * terminated string of length 5. * * scode char[] The three-letter spectral algorithm code copied or * translated from ctype. Logarithmic ('LOG') and * tabular ('TAB') codes are also recognized. If a * non-zero pointer is given, the array must accomodate a * null-terminated string of length 4. * * sname char[] Descriptive name of the S-type spectral variable. * If a non-zero pointer is given, the array must * accomodate a null-terminated string of length 22. * * units char[] SI units of the S-type spectral variable. If a * non-zero pointer is given, the array must accomodate a * null-terminated string of length 8. * * ptype char* Character code for the P-type spectral variable * derived from ctype, one of 'F', 'W', 'A', or 'V'. * * xtype char* Character code for the X-type spectral variable * derived from ctype, one of 'F', 'W', 'A', or 'V'. * Also, 'w' and 'a' are synonymous to 'W' and 'A' for * grisms in vacuo and air respectively. Set to 'L' or * 'T' for logarithmic ('LOG') and tabular ('TAB') axes. * * restreq int* Multivalued flag that indicates whether rest * frequency or wavelength is required to compute * spectral variables for this CTYPEia: * 0: Not required. * 1: Required for the conversion between S- and * P-types (e.g. 'ZOPT-F2W'). * 2: Required for the conversion between P- and * X-types (e.g. 'BETA-W2V'). * 3: Required for the conversion between S- and * P-types, and between P- and X-types, but not * between S- and X-types (this applies only for * 'VRAD-V2F', 'VOPT-V2W', and 'ZOPT-V2W'). * Thus the rest frequency or wavelength is required for * spectral coordinate computations (i.e. between S- and * X-types) only if restreq%3 != 0. * * err struct wcserr ** * If enabled, for function return values > 1, this * struct will contain a detailed error message, see * wcserr_enable(). May be NULL if an error message is * not desired. Otherwise, the user is responsible for * deleting the memory allocated for the wcserr struct. * * Function return value: * int Status return value: * 0: Success. * 2: Invalid spectral parameters (not a spectral * CTYPEia). * * * spcspxe() - Spectral keyword analysis * ------------------------------------ * spcspxe() analyses the CTYPEia and CRVALia FITS spectral axis keyword values * and returns information about the associated X-type spectral variable. * * A deprecated form of this function, spcspx(), lacks the wcserr** parameter. * * Given: * ctypeS const char[9] * Spectral axis type, i.e. the CTYPEia keyvalue, (eight * characters with null termination). For non-grism * axes, the character code for the P-type spectral * variable in the algorithm code (i.e. the eighth * character of CTYPEia) may be set to '?' (it will not * be reset). * * crvalS double Value of the S-type spectral variable at the reference * point, i.e. the CRVALia keyvalue, SI units. * * restfrq, * restwav double Rest frequency [Hz] and rest wavelength in vacuo [m], * only one of which need be given, the other should be * set to zero. * * Returned: * ptype char* Character code for the P-type spectral variable * derived from ctypeS, one of 'F', 'W', 'A', or 'V'. * * xtype char* Character code for the X-type spectral variable * derived from ctypeS, one of 'F', 'W', 'A', or 'V'. * Also, 'w' and 'a' are synonymous to 'W' and 'A' for * grisms in vacuo and air respectively; crvalX and dXdS * (see below) will conform to these. * * restreq int* Multivalued flag that indicates whether rest frequency * or wavelength is required to compute spectral * variables for this CTYPEia, as for spctype(). * * crvalX double* Value of the X-type spectral variable at the reference * point, SI units. * * dXdS double* The derivative, dX/dS, evaluated at the reference * point, SI units. Multiply the CDELTia keyvalue by * this to get the pixel spacing in the X-type spectral * coordinate. * * err struct wcserr ** * If enabled, for function return values > 1, this * struct will contain a detailed error message, see * wcserr_enable(). May be NULL if an error message is * not desired. Otherwise, the user is responsible for * deleting the memory allocated for the wcserr struct. * * Function return value: * int Status return value: * 0: Success. * 2: Invalid spectral parameters. * * * spcxpse() - Spectral keyword synthesis * ------------------------------------- * spcxpse(), for the spectral axis type specified and the value provided for * the X-type spectral variable at the reference point, deduces the value of * the FITS spectral axis keyword CRVALia and also the derivative dS/dX which * may be used to compute CDELTia. See above for an explanation of the S-, * P-, and X-type spectral variables. * * A deprecated form of this function, spcxps(), lacks the wcserr** parameter. * * Given: * ctypeS const char[9] * The required spectral axis type, i.e. the CTYPEia * keyvalue, (eight characters with null termination). * For non-grism axes, the character code for the P-type * spectral variable in the algorithm code (i.e. the * eighth character of CTYPEia) may be set to '?' (it * will not be reset). * * crvalX double Value of the X-type spectral variable at the reference * point (N.B. NOT the CRVALia keyvalue), SI units. * * restfrq, * restwav double Rest frequency [Hz] and rest wavelength in vacuo [m], * only one of which need be given, the other should be * set to zero. * * Returned: * ptype char* Character code for the P-type spectral variable * derived from ctypeS, one of 'F', 'W', 'A', or 'V'. * * xtype char* Character code for the X-type spectral variable * derived from ctypeS, one of 'F', 'W', 'A', or 'V'. * Also, 'w' and 'a' are synonymous to 'W' and 'A' for * grisms; crvalX and cdeltX must conform to these. * * restreq int* Multivalued flag that indicates whether rest frequency * or wavelength is required to compute spectral * variables for this CTYPEia, as for spctype(). * * crvalS double* Value of the S-type spectral variable at the reference * point (i.e. the appropriate CRVALia keyvalue), SI * units. * * dSdX double* The derivative, dS/dX, evaluated at the reference * point, SI units. Multiply this by the pixel spacing * in the X-type spectral coordinate to get the CDELTia * keyvalue. * * err struct wcserr ** * If enabled, for function return values > 1, this * struct will contain a detailed error message, see * wcserr_enable(). May be NULL if an error message is * not desired. Otherwise, the user is responsible for * deleting the memory allocated for the wcserr struct. * * Function return value: * int Status return value: * 0: Success. * 2: Invalid spectral parameters. * * * spctrne() - Spectral keyword translation * --------------------------------------- * spctrne() translates a set of FITS spectral axis keywords into the * corresponding set for the specified spectral axis type. For example, a * 'FREQ' axis may be translated into 'ZOPT-F2W' and vice versa. * * A deprecated form of this function, spctrn(), lacks the wcserr** parameter. * * Given: * ctypeS1 const char[9] * Spectral axis type, i.e. the CTYPEia keyvalue, (eight * characters with null termination). For non-grism * axes, the character code for the P-type spectral * variable in the algorithm code (i.e. the eighth * character of CTYPEia) may be set to '?' (it will not * be reset). * * crvalS1 double Value of the S-type spectral variable at the reference * point, i.e. the CRVALia keyvalue, SI units. * * cdeltS1 double Increment of the S-type spectral variable at the * reference point, SI units. * * restfrq, * restwav double Rest frequency [Hz] and rest wavelength in vacuo [m], * only one of which need be given, the other should be * set to zero. Neither are required if the translation * is between wave-characteristic types, or between * velocity-characteristic types. E.g., required for * 'FREQ' -> 'ZOPT-F2W', but not required for * 'VELO-F2V' -> 'ZOPT-F2W'. * * Given and returned: * ctypeS2 char[9] Required spectral axis type (eight characters with * null termination). The first four characters are * required to be given and are never modified. The * remaining four, the algorithm code, are completely * determined by, and must be consistent with, ctypeS1 * and the first four characters of ctypeS2. A non-zero * status value will be returned if they are inconsistent * (see below). However, if the final three characters * are specified as "???", or if just the eighth * character is specified as '?', the correct algorithm * code will be substituted (applies for grism axes as * well as non-grism). * * Returned: * crvalS2 double* Value of the new S-type spectral variable at the * reference point, i.e. the new CRVALia keyvalue, SI * units. * * cdeltS2 double* Increment of the new S-type spectral variable at the * reference point, i.e. the new CDELTia keyvalue, SI * units. * * err struct wcserr ** * If enabled, for function return values > 1, this * struct will contain a detailed error message, see * wcserr_enable(). May be NULL if an error message is * not desired. Otherwise, the user is responsible for * deleting the memory allocated for the wcserr struct. * * Function return value: * int Status return value: * 0: Success. * 2: Invalid spectral parameters. * * A status value of 2 will be returned if restfrq or * restwav are not specified when required, or if ctypeS1 * or ctypeS2 are self-inconsistent, or have different * spectral X-type variables. * * * spcaips() - Translate AIPS-convention spectral keywords * ------------------------------------------------------- * spcaips() translates AIPS-convention spectral CTYPEia and VELREF keyvalues. * * Given: * ctypeA const char[9] * CTYPEia keyvalue possibly containing an * AIPS-convention spectral code (eight characters, need * not be null-terminated). * * velref int AIPS-convention VELREF code. It has the following * integer values: * 1: LSR kinematic, originally described simply as * "LSR" without distinction between the kinematic * and dynamic definitions. * 2: Barycentric, originally described as "HEL" * meaning heliocentric. * 3: Topocentric, originally described as "OBS" * meaning geocentric but widely interpreted as * topocentric. * AIPS++ extensions to VELREF are also recognized: * 4: LSR dynamic. * 5: Geocentric. * 6: Source rest frame. * 7: Galactocentric. * * For an AIPS 'VELO' axis, a radio convention velocity * (VRAD) is denoted by adding 256 to VELREF, otherwise * an optical velocity (VOPT) is indicated (this is not * applicable to 'FREQ' or 'FELO' axes). Setting velref * to 0 or 256 chooses between optical and radio velocity * without specifying a Doppler frame, provided that a * frame is encoded in ctypeA. If not, i.e. for * ctypeA = 'VELO', ctype will be returned as 'VELO'. * * VELREF takes precedence over CTYPEia in defining the * Doppler frame, e.g. * = ctypeA = 'VELO-HEL' = velref = 1 * * returns ctype = 'VOPT' with specsys set to 'LSRK'. * * If omitted from the header, the default value of * VELREF is 0. * * Returned: * ctype char[9] Translated CTYPEia keyvalue, or a copy of ctypeA if no * translation was performed (in which case any trailing * blanks in ctypeA will be replaced with nulls). * * specsys char[9] Doppler reference frame indicated by VELREF or else * by CTYPEia with value corresponding to the SPECSYS * keyvalue in the FITS WCS standard. May be returned * blank if neither specifies a Doppler frame, e.g. * ctypeA = 'FELO' and velref%256 == 0. * * Function return value: * int Status return value: * -1: No translation required (not an error). * 0: Success. * 2: Invalid value of VELREF. * * * spcprm struct - Spectral transformation parameters * -------------------------------------------------- * The spcprm struct contains information required to transform spectral * coordinates. It consists of certain members that must be set by the user * ("given") and others that are set by the WCSLIB routines ("returned"). Some * of the latter are supplied for informational purposes while others are for * internal use only. * * int flag * (Given and returned) This flag must be set to zero whenever any of the * following spcprm structure members are set or changed: * * - spcprm::type, * - spcprm::code, * - spcprm::crval, * - spcprm::restfrq, * - spcprm::restwav, * - spcprm::pv[]. * * This signals the initialization routine, spcset(), to recompute the * returned members of the spcprm struct. spcset() will reset flag to * indicate that this has been done. * * char type[8] * (Given) Four-letter spectral variable type, e.g "ZOPT" for * CTYPEia = 'ZOPT-F2W'. (Declared as char[8] for alignment reasons.) * * char code[4] * (Given) Three-letter spectral algorithm code, e.g "F2W" for * CTYPEia = 'ZOPT-F2W'. * * double crval * (Given) Reference value (CRVALia), SI units. * * double restfrq * (Given) The rest frequency [Hz], and ... * * double restwav * (Given) ... the rest wavelength in vacuo [m], only one of which need be * given, the other should be set to zero. Neither are required if the * X and S spectral variables are both wave-characteristic, or both * velocity-characteristic, types. * * double pv[7] * (Given) Grism parameters for 'GRI' and 'GRA' algorithm codes: * - 0: G, grating ruling density. * - 1: m, interference order. * - 2: alpha, angle of incidence [deg]. * - 3: n_r, refractive index at the reference wavelength, lambda_r. * - 4: n'_r, dn/dlambda at the reference wavelength, lambda_r (/m). * - 5: epsilon, grating tilt angle [deg]. * - 6: theta, detector tilt angle [deg]. * * The remaining members of the spcprm struct are maintained by spcset() and * must not be modified elsewhere: * * double w[6] * (Returned) Intermediate values: * - 0: Rest frequency or wavelength (SI). * - 1: The value of the X-type spectral variable at the reference point * (SI units). * - 2: dX/dS at the reference point (SI units). * The remainder are grism intermediates. * * int isGrism * (Returned) Grism coordinates? * - 0: no, * - 1: in vacuum, * - 2: in air. * * int padding1 * (An unused variable inserted for alignment purposes only.) * * struct wcserr *err * (Returned) If enabled, when an error status is returned, this struct * contains detailed information about the error, see wcserr_enable(). * * void *padding2 * (An unused variable inserted for alignment purposes only.) * int (*spxX2P)(SPX_ARGS) * (Returned) The first and ... * int (*spxP2S)(SPX_ARGS) * (Returned) ... the second of the pointers to the transformation * functions in the two-step algorithm chain X -> P -> S in the * pixel-to-spectral direction where the non-linear transformation is from * X to P. The argument list, SPX_ARGS, is defined in spx.h. * * int (*spxS2P)(SPX_ARGS) * (Returned) The first and ... * int (*spxP2X)(SPX_ARGS) * (Returned) ... the second of the pointers to the transformation * functions in the two-step algorithm chain S -> P -> X in the * spectral-to-pixel direction where the non-linear transformation is from * P to X. The argument list, SPX_ARGS, is defined in spx.h. * * * Global variable: const char *spc_errmsg[] - Status return messages * ------------------------------------------------------------------ * Error messages to match the status value returned from each function. * *===========================================================================*/ #ifndef WCSLIB_SPC #define WCSLIB_SPC #include "spx.h" #ifdef __cplusplus extern "C" { #endif extern const char *spc_errmsg[]; enum spc_errmsg_enum { SPCERR_NO_CHANGE = -1, // No change. SPCERR_SUCCESS = 0, // Success. SPCERR_NULL_POINTER = 1, // Null spcprm pointer passed. SPCERR_BAD_SPEC_PARAMS = 2, // Invalid spectral parameters. SPCERR_BAD_X = 3, // One or more of x coordinates were // invalid. SPCERR_BAD_SPEC = 4 // One or more of the spec coordinates were // invalid. }; struct spcprm { // Initialization flag (see the prologue above). //-------------------------------------------------------------------------- int flag; // Set to zero to force initialization. // Parameters to be provided (see the prologue above). //-------------------------------------------------------------------------- char type[8]; // Four-letter spectral variable type. char code[4]; // Three-letter spectral algorithm code. double crval; // Reference value (CRVALia), SI units. double restfrq; // Rest frequency, Hz. double restwav; // Rest wavelength, m. double pv[7]; // Grism parameters: // 0: G, grating ruling density. // 1: m, interference order. // 2: alpha, angle of incidence. // 3: n_r, refractive index at lambda_r. // 4: n'_r, dn/dlambda at lambda_r. // 5: epsilon, grating tilt angle. // 6: theta, detector tilt angle. // Information derived from the parameters supplied. //-------------------------------------------------------------------------- double w[6]; // Intermediate values. // 0: Rest frequency or wavelength (SI). // 1: CRVALX (SI units). // 2: CDELTX/CDELTia = dX/dS (SI units). // The remainder are grism intermediates. int isGrism; // Grism coordinates? 1: vacuum, 2: air. int padding1; // (Dummy inserted for alignment purposes.) // Error handling //-------------------------------------------------------------------------- struct wcserr *err; // Private //-------------------------------------------------------------------------- void *padding2; // (Dummy inserted for alignment purposes.) int (*spxX2P)(SPX_ARGS); // Pointers to the transformation functions int (*spxP2S)(SPX_ARGS); // in the two-step algorithm chain in the // pixel-to-spectral direction. int (*spxS2P)(SPX_ARGS); // Pointers to the transformation functions int (*spxP2X)(SPX_ARGS); // in the two-step algorithm chain in the // spectral-to-pixel direction. }; // Size of the spcprm struct in int units, used by the Fortran wrappers. #define SPCLEN (sizeof(struct spcprm)/sizeof(int)) int spcini(struct spcprm *spc); int spcfree(struct spcprm *spc); int spcsize(const struct spcprm *spc, int sizes[2]); int spcprt(const struct spcprm *spc); int spcperr(const struct spcprm *spc, const char *prefix); int spcset(struct spcprm *spc); int spcx2s(struct spcprm *spc, int nx, int sx, int sspec, const double x[], double spec[], int stat[]); int spcs2x(struct spcprm *spc, int nspec, int sspec, int sx, const double spec[], double x[], int stat[]); int spctype(const char ctype[9], char stype[], char scode[], char sname[], char units[], char *ptype, char *xtype, int *restreq, struct wcserr **err); int spcspxe(const char ctypeS[9], double crvalS, double restfrq, double restwav, char *ptype, char *xtype, int *restreq, double *crvalX, double *dXdS, struct wcserr **err); int spcxpse(const char ctypeS[9], double crvalX, double restfrq, double restwav, char *ptype, char *xtype, int *restreq, double *crvalS, double *dSdX, struct wcserr **err); int spctrne(const char ctypeS1[9], double crvalS1, double cdeltS1, double restfrq, double restwav, char ctypeS2[9], double *crvalS2, double *cdeltS2, struct wcserr **err); int spcaips(const char ctypeA[9], int velref, char ctype[9], char specsys[9]); // Deprecated. #define spcini_errmsg spc_errmsg #define spcprt_errmsg spc_errmsg #define spcset_errmsg spc_errmsg #define spcx2s_errmsg spc_errmsg #define spcs2x_errmsg spc_errmsg int spctyp(const char ctype[9], char stype[], char scode[], char sname[], char units[], char *ptype, char *xtype, int *restreq); int spcspx(const char ctypeS[9], double crvalS, double restfrq, double restwav, char *ptype, char *xtype, int *restreq, double *crvalX, double *dXdS); int spcxps(const char ctypeS[9], double crvalX, double restfrq, double restwav, char *ptype, char *xtype, int *restreq, double *crvalS, double *dSdX); int spctrn(const char ctypeS1[9], double crvalS1, double cdeltS1, double restfrq, double restwav, char ctypeS2[9], double *crvalS2, double *cdeltS2); #ifdef __cplusplus } #endif #endif // WCSLIB_SPC ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921587.0 astropy-5.0.2/astropy/wcs/include/wcslib/spx.h0000644000175100001710000005270400000000000020443 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: spx.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the spx routines * --------------------------- * Routines in this suite implement the spectral coordinate systems recognized * by the FITS World Coordinate System (WCS) standard, as described in * = "Representations of world coordinates in FITS", = Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (WCS Paper I) = = "Representations of spectral coordinates in FITS", = Greisen, E.W., Calabretta, M.R., Valdes, F.G., & Allen, S.L. = 2006, A&A, 446, 747 (WCS Paper III) * * specx() is a scalar routine that, given one spectral variable (e.g. * frequency), computes all the others (e.g. wavelength, velocity, etc.) plus * the required derivatives of each with respect to the others. The results * are returned in the spxprm struct. * * spxperr() prints the error message(s) (if any) stored in a spxprm struct. * * The remaining routines are all vector conversions from one spectral * variable to another. The API of these functions only differ in whether the * rest frequency or wavelength need be supplied. * * Non-linear: * - freqwave() frequency -> vacuum wavelength * - wavefreq() vacuum wavelength -> frequency * * - freqawav() frequency -> air wavelength * - awavfreq() air wavelength -> frequency * * - freqvelo() frequency -> relativistic velocity * - velofreq() relativistic velocity -> frequency * * - waveawav() vacuum wavelength -> air wavelength * - awavwave() air wavelength -> vacuum wavelength * * - wavevelo() vacuum wavelength -> relativistic velocity * - velowave() relativistic velocity -> vacuum wavelength * * - awavvelo() air wavelength -> relativistic velocity * - veloawav() relativistic velocity -> air wavelength * * Linear: * - freqafrq() frequency -> angular frequency * - afrqfreq() angular frequency -> frequency * * - freqener() frequency -> energy * - enerfreq() energy -> frequency * * - freqwavn() frequency -> wave number * - wavnfreq() wave number -> frequency * * - freqvrad() frequency -> radio velocity * - vradfreq() radio velocity -> frequency * * - wavevopt() vacuum wavelength -> optical velocity * - voptwave() optical velocity -> vacuum wavelength * * - wavezopt() vacuum wavelength -> redshift * - zoptwave() redshift -> vacuum wavelength * * - velobeta() relativistic velocity -> beta (= v/c) * - betavelo() beta (= v/c) -> relativistic velocity * * These are the workhorse routines, to be used for fast transformations. * Conversions may be done "in place" by calling the routine with the output * vector set to the input. * * Air-to-vacuum wavelength conversion: * ------------------------------------ * The air-to-vacuum wavelength conversion in early drafts of WCS Paper III * cites Cox (ed., 2000, Allen’s Astrophysical Quantities, AIP Press, * Springer-Verlag, New York), which itself derives from EdlÊn (1953, Journal * of the Optical Society of America, 43, 339). This is the IAU standard, * adopted in 1957 and again in 1991. No more recent IAU resolution replaces * this relation, and it is the one used by WCSLIB. * * However, the Cox relation was replaced in later drafts of Paper III, and as * eventually published, by the IUGG relation (1999, International Union of * Geodesy and Geophysics, comptes rendus of the 22nd General Assembly, * Birmingham UK, p111). There is a nearly constant ratio between the two, * with IUGG/Cox = 1.000015 over most of the range between 200nm and 10,000nm. * * The IUGG relation itself is derived from the work of Ciddor (1996, Applied * Optics, 35, 1566), which is used directly by the Sloan Digital Sky Survey. * It agrees closely with Cox; longwards of 2500nm, the ratio Ciddor/Cox is * fixed at 1.000000021, decreasing only slightly, to 1.000000018, at 1000nm. * * The Cox, IUGG, and Ciddor relations all accurately provide the wavelength * dependence of the air-to-vacuum wavelength conversion. However, for full * accuracy, the atmospheric temperature, pressure, and partial pressure of * water vapour must be taken into account. These will determine a small, * wavelength-independent scale factor and offset, which is not considered by * WCS Paper III. * * WCS Paper III is also silent on the question of the range of validity of the * air-to-vacuum wavelength conversion. Cox's relation would appear to be * valid in the range 200nm to 10,000nm. Both the Cox and the Ciddor relations * have singularities below 200nm, with Cox's at 156nm and 83nm. WCSLIB checks * neither the range of validity, nor for these singularities. * * Argument checking: * ------------------ * The input spectral values are only checked for values that would result * in floating point exceptions. In particular, negative frequencies and * wavelengths are allowed, as are velocities greater than the speed of * light. The same is true for the spectral parameters - rest frequency and * wavelength. * * Accuracy: * --------- * No warranty is given for the accuracy of these routines (refer to the * copyright notice); intending users must satisfy for themselves their * adequacy for the intended purpose. However, closure effectively to within * double precision rounding error was demonstrated by test routine tspec.c * which accompanies this software. * * * specx() - Spectral cross conversions (scalar) * --------------------------------------------- * Given one spectral variable specx() computes all the others, plus the * required derivatives of each with respect to the others. * * Given: * type const char* * The type of spectral variable given by spec, FREQ, * AFRQ, ENER, WAVN, VRAD, WAVE, VOPT, ZOPT, AWAV, VELO, * or BETA (case sensitive). * * spec double The spectral variable given, in SI units. * * restfrq, * restwav double Rest frequency [Hz] or rest wavelength in vacuo [m], * only one of which need be given. The other should be * set to zero. If both are zero, only a subset of the * spectral variables can be computed, the remainder are * set to zero. Specifically, given one of FREQ, AFRQ, * ENER, WAVN, WAVE, or AWAV the others can be computed * without knowledge of the rest frequency. Likewise, * VRAD, VOPT, ZOPT, VELO, and BETA. * * Given and returned: * specs struct spxprm* * Data structure containing all spectral variables and * their derivatives, in SI units. * * Function return value: * int Status return value: * 0: Success. * 1: Null spxprm pointer passed. * 2: Invalid spectral parameters. * 3: Invalid spectral variable. * * For returns > 1, a detailed error message is set in * spxprm::err if enabled, see wcserr_enable(). * * freqafrq(), afrqfreq(), freqener(), enerfreq(), freqwavn(), wavnfreq(), * freqwave(), wavefreq(), freqawav(), awavfreq(), waveawav(), awavwave(), * velobeta(), and betavelo() implement vector conversions between wave-like * or velocity-like spectral types (i.e. conversions that do not need the rest * frequency or wavelength). They all have the same API. * * * spxperr() - Print error messages from a spxprm struct * ----------------------------------------------------- * spxperr() prints the error message(s) (if any) stored in a spxprm struct. * If there are no errors then nothing is printed. It uses wcserr_prt(), q.v. * * Given: * spx const struct spxprm* * Spectral variables and their derivatives. * * prefix const char * * If non-NULL, each output line will be prefixed with * this string. * * Function return value: * int Status return value: * 0: Success. * 1: Null spxprm pointer passed. * * * freqafrq() - Convert frequency to angular frequency (vector) * ------------------------------------------------------------ * freqafrq() converts frequency to angular frequency. * * Given: * param double Ignored. * * nspec int Vector length. * * instep, * outstep int Vector strides. * * inspec const double[] * Input spectral variables, in SI units. * * Returned: * outspec double[] Output spectral variables, in SI units. * * stat int[] Status return value for each vector element: * 0: Success. * 1: Invalid value of inspec. * * Function return value: * int Status return value: * 0: Success. * 2: Invalid spectral parameters. * 4: One or more of the inspec coordinates were * invalid, as indicated by the stat vector. * * * freqvelo(), velofreq(), freqvrad(), and vradfreq() implement vector * conversions between frequency and velocity spectral types. They all have * the same API. * * * freqvelo() - Convert frequency to relativistic velocity (vector) * ---------------------------------------------------------------- * freqvelo() converts frequency to relativistic velocity. * * Given: * param double Rest frequency [Hz]. * * nspec int Vector length. * * instep, * outstep int Vector strides. * * inspec const double[] * Input spectral variables, in SI units. * * Returned: * outspec double[] Output spectral variables, in SI units. * * stat int[] Status return value for each vector element: * 0: Success. * 1: Invalid value of inspec. * * Function return value: * int Status return value: * 0: Success. * 2: Invalid spectral parameters. * 4: One or more of the inspec coordinates were * invalid, as indicated by the stat vector. * * * wavevelo(), velowave(), awavvelo(), veloawav(), wavevopt(), voptwave(), * wavezopt(), and zoptwave() implement vector conversions between wavelength * and velocity spectral types. They all have the same API. * * * wavevelo() - Conversions between wavelength and velocity types (vector) * ----------------------------------------------------------------------- * wavevelo() converts vacuum wavelength to relativistic velocity. * * Given: * param double Rest wavelength in vacuo [m]. * * nspec int Vector length. * * instep, * outstep int Vector strides. * * inspec const double[] * Input spectral variables, in SI units. * * Returned: * outspec double[] Output spectral variables, in SI units. * * stat int[] Status return value for each vector element: * 0: Success. * 1: Invalid value of inspec. * * Function return value: * int Status return value: * 0: Success. * 2: Invalid spectral parameters. * 4: One or more of the inspec coordinates were * invalid, as indicated by the stat vector. * * * spxprm struct - Spectral variables and their derivatives * -------------------------------------------------------- * The spxprm struct contains the value of all spectral variables and their * derivatives. It is used solely by specx() which constructs it from * information provided via its function arguments. * * This struct should be considered read-only, no members need ever be set nor * should ever be modified by the user. * * double restfrq * (Returned) Rest frequency [Hz]. * * double restwav * (Returned) Rest wavelength [m]. * * int wavetype * (Returned) True if wave types have been computed, and ... * * int velotype * (Returned) ... true if velocity types have been computed; types are * defined below. * * If one or other of spxprm::restfrq and spxprm::restwav is given * (non-zero) then all spectral variables may be computed. If both are * given, restfrq is used. If restfrq and restwav are both zero, only wave * characteristic xor velocity type spectral variables may be computed * depending on the variable given. These flags indicate what is * available. * * double freq * (Returned) Frequency [Hz] (wavetype). * * double afrq * (Returned) Angular frequency [rad/s] (wavetype). * * double ener * (Returned) Photon energy [J] (wavetype). * * double wavn * (Returned) Wave number [/m] (wavetype). * * double vrad * (Returned) Radio velocity [m/s] (velotype). * * double wave * (Returned) Vacuum wavelength [m] (wavetype). * * double vopt * (Returned) Optical velocity [m/s] (velotype). * * double zopt * (Returned) Redshift [dimensionless] (velotype). * * double awav * (Returned) Air wavelength [m] (wavetype). * * double velo * (Returned) Relativistic velocity [m/s] (velotype). * * double beta * (Returned) Relativistic beta [dimensionless] (velotype). * * double dfreqafrq * (Returned) Derivative of frequency with respect to angular frequency * [/rad] (constant, = 1 / 2*pi), and ... * double dafrqfreq * (Returned) ... vice versa [rad] (constant, = 2*pi, always available). * * double dfreqener * (Returned) Derivative of frequency with respect to photon energy * [/J/s] (constant, = 1/h), and ... * double denerfreq * (Returned) ... vice versa [Js] (constant, = h, Planck's constant, * always available). * * double dfreqwavn * (Returned) Derivative of frequency with respect to wave number [m/s] * (constant, = c, the speed of light in vacuo), and ... * double dwavnfreq * (Returned) ... vice versa [s/m] (constant, = 1/c, always available). * * double dfreqvrad * (Returned) Derivative of frequency with respect to radio velocity [/m], * and ... * double dvradfreq * (Returned) ... vice versa [m] (wavetype && velotype). * * double dfreqwave * (Returned) Derivative of frequency with respect to vacuum wavelength * [/m/s], and ... * double dwavefreq * (Returned) ... vice versa [m s] (wavetype). * * double dfreqawav * (Returned) Derivative of frequency with respect to air wavelength, * [/m/s], and ... * double dawavfreq * (Returned) ... vice versa [m s] (wavetype). * * double dfreqvelo * (Returned) Derivative of frequency with respect to relativistic * velocity [/m], and ... * double dvelofreq * (Returned) ... vice versa [m] (wavetype && velotype). * * double dwavevopt * (Returned) Derivative of vacuum wavelength with respect to optical * velocity [s], and ... * double dvoptwave * (Returned) ... vice versa [/s] (wavetype && velotype). * * double dwavezopt * (Returned) Derivative of vacuum wavelength with respect to redshift [m], * and ... * double dzoptwave * (Returned) ... vice versa [/m] (wavetype && velotype). * * double dwaveawav * (Returned) Derivative of vacuum wavelength with respect to air * wavelength [dimensionless], and ... * double dawavwave * (Returned) ... vice versa [dimensionless] (wavetype). * * double dwavevelo * (Returned) Derivative of vacuum wavelength with respect to relativistic * velocity [s], and ... * double dvelowave * (Returned) ... vice versa [/s] (wavetype && velotype). * * double dawavvelo * (Returned) Derivative of air wavelength with respect to relativistic * velocity [s], and ... * double dveloawav * (Returned) ... vice versa [/s] (wavetype && velotype). * * double dvelobeta * (Returned) Derivative of relativistic velocity with respect to * relativistic beta [m/s] (constant, = c, the speed of light in vacuo), * and ... * double dbetavelo * (Returned) ... vice versa [s/m] (constant, = 1/c, always available). * * struct wcserr *err * (Returned) If enabled, when an error status is returned, this struct * contains detailed information about the error, see wcserr_enable(). * * void *padding * (An unused variable inserted for alignment purposes only.) * * Global variable: const char *spx_errmsg[] - Status return messages * ------------------------------------------------------------------ * Error messages to match the status value returned from each function. * *===========================================================================*/ #ifndef WCSLIB_SPEC #define WCSLIB_SPEC #ifdef __cplusplus extern "C" { #endif extern const char *spx_errmsg[]; enum spx_errmsg { SPXERR_SUCCESS = 0, // Success. SPXERR_NULL_POINTER = 1, // Null spxprm pointer passed. SPXERR_BAD_SPEC_PARAMS = 2, // Invalid spectral parameters. SPXERR_BAD_SPEC_VAR = 3, // Invalid spectral variable. SPXERR_BAD_INSPEC_COORD = 4 // One or more of the inspec coordinates were // invalid. }; struct spxprm { double restfrq, restwav; // Rest frequency [Hz] and wavelength [m]. int wavetype, velotype; // True if wave/velocity types have been // computed; types are defined below. // Spectral variables computed by specx(). //-------------------------------------------------------------------------- double freq, // wavetype: Frequency [Hz]. afrq, // wavetype: Angular frequency [rad/s]. ener, // wavetype: Photon energy [J]. wavn, // wavetype: Wave number [/m]. vrad, // velotype: Radio velocity [m/s]. wave, // wavetype: Vacuum wavelength [m]. vopt, // velotype: Optical velocity [m/s]. zopt, // velotype: Redshift. awav, // wavetype: Air wavelength [m]. velo, // velotype: Relativistic velocity [m/s]. beta; // velotype: Relativistic beta. // Derivatives of spectral variables computed by specx(). //-------------------------------------------------------------------------- double dfreqafrq, dafrqfreq, // Constant, always available. dfreqener, denerfreq, // Constant, always available. dfreqwavn, dwavnfreq, // Constant, always available. dfreqvrad, dvradfreq, // wavetype && velotype. dfreqwave, dwavefreq, // wavetype. dfreqawav, dawavfreq, // wavetype. dfreqvelo, dvelofreq, // wavetype && velotype. dwavevopt, dvoptwave, // wavetype && velotype. dwavezopt, dzoptwave, // wavetype && velotype. dwaveawav, dawavwave, // wavetype. dwavevelo, dvelowave, // wavetype && velotype. dawavvelo, dveloawav, // wavetype && velotype. dvelobeta, dbetavelo; // Constant, always available. // Error handling //-------------------------------------------------------------------------- struct wcserr *err; // Private //-------------------------------------------------------------------------- void *padding; // (Dummy inserted for alignment purposes.) }; // Size of the spxprm struct in int units, used by the Fortran wrappers. #define SPXLEN (sizeof(struct spxprm)/sizeof(int)) int specx(const char *type, double spec, double restfrq, double restwav, struct spxprm *specs); int spxperr(const struct spxprm *spx, const char *prefix); // For use in declaring function prototypes, e.g. in spcprm. #define SPX_ARGS double param, int nspec, int instep, int outstep, \ const double inspec[], double outspec[], int stat[] int freqafrq(SPX_ARGS); int afrqfreq(SPX_ARGS); int freqener(SPX_ARGS); int enerfreq(SPX_ARGS); int freqwavn(SPX_ARGS); int wavnfreq(SPX_ARGS); int freqwave(SPX_ARGS); int wavefreq(SPX_ARGS); int freqawav(SPX_ARGS); int awavfreq(SPX_ARGS); int waveawav(SPX_ARGS); int awavwave(SPX_ARGS); int velobeta(SPX_ARGS); int betavelo(SPX_ARGS); int freqvelo(SPX_ARGS); int velofreq(SPX_ARGS); int freqvrad(SPX_ARGS); int vradfreq(SPX_ARGS); int wavevelo(SPX_ARGS); int velowave(SPX_ARGS); int awavvelo(SPX_ARGS); int veloawav(SPX_ARGS); int wavevopt(SPX_ARGS); int voptwave(SPX_ARGS); int wavezopt(SPX_ARGS); int zoptwave(SPX_ARGS); #ifdef __cplusplus } #endif #endif // WCSLIB_SPEC ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921587.0 astropy-5.0.2/astropy/wcs/include/wcslib/tab.h0000644000175100001710000006333500000000000020401 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: tab.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the tab routines * --------------------------- * Routines in this suite implement the part of the FITS World Coordinate * System (WCS) standard that deals with tabular coordinates, i.e. coordinates * that are defined via a lookup table, as described in * = "Representations of world coordinates in FITS", = Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (WCS Paper I) = = "Representations of spectral coordinates in FITS", = Greisen, E.W., Calabretta, M.R., Valdes, F.G., & Allen, S.L. = 2006, A&A, 446, 747 (WCS Paper III) * * These routines define methods to be used for computing tabular world * coordinates from intermediate world coordinates (a linear transformation * of image pixel coordinates), and vice versa. They are based on the tabprm * struct which contains all information needed for the computations. The * struct contains some members that must be set by the user, and others that * are maintained by these routines, somewhat like a C++ class but with no * encapsulation. * * tabini(), tabmem(), tabcpy(), and tabfree() are provided to manage the * tabprm struct, tabsize() computes its total size including allocated memory, * and tabprt() prints its contents. * * tabperr() prints the error message(s) (if any) stored in a tabprm struct. * * A setup routine, tabset(), computes intermediate values in the tabprm struct * from parameters in it that were supplied by the user. The struct always * needs to be set up by tabset() but it need not be called explicitly - refer * to the explanation of tabprm::flag. * * tabx2s() and tabs2x() implement the WCS tabular coordinate transformations. * * Accuracy: * --------- * No warranty is given for the accuracy of these routines (refer to the * copyright notice); intending users must satisfy for themselves their * adequacy for the intended purpose. However, closure effectively to within * double precision rounding error was demonstrated by test routine ttab.c * which accompanies this software. * * * tabini() - Default constructor for the tabprm struct * ---------------------------------------------------- * tabini() allocates memory for arrays in a tabprm struct and sets all members * of the struct to default values. * * PLEASE NOTE: every tabprm struct should be initialized by tabini(), possibly * repeatedly. On the first invokation, and only the first invokation, the * flag member of the tabprm struct must be set to -1 to initialize memory * management, regardless of whether tabini() will actually be used to allocate * memory. * * Given: * alloc int If true, allocate memory unconditionally for arrays in * the tabprm struct. * * If false, it is assumed that pointers to these arrays * have been set by the user except if they are null * pointers in which case memory will be allocated for * them regardless. (In other words, setting alloc true * saves having to initalize these pointers to zero.) * * M int The number of tabular coordinate axes. * * K const int[] * Vector of length M whose elements (K_1, K_2,... K_M) * record the lengths of the axes of the coordinate array * and of each indexing vector. M and K[] are used to * determine the length of the various tabprm arrays and * therefore the amount of memory to allocate for them. * Their values are copied into the tabprm struct. * * It is permissible to set K (i.e. the address of the * array) to zero which has the same effect as setting * each element of K[] to zero. In this case no memory * will be allocated for the index vectors or coordinate * array in the tabprm struct. These together with the * K vector must be set separately before calling * tabset(). * * Given and returned: * tab struct tabprm* * Tabular transformation parameters. Note that, in * order to initialize memory management tabprm::flag * should be set to -1 when tab is initialized for the * first time (memory leaks may result if it had already * been initialized). * * Function return value: * int Status return value: * 0: Success. * 1: Null tabprm pointer passed. * 2: Memory allocation failed. * 3: Invalid tabular parameters. * * For returns > 1, a detailed error message is set in * tabprm::err if enabled, see wcserr_enable(). * * * tabmem() - Acquire tabular memory * --------------------------------- * tabmem() takes control of memory allocated by the user for arrays in the * tabprm struct. * * Given and returned: * tab struct tabprm* * Tabular transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null tabprm pointer passed. * 2: Memory allocation failed. * * For returns > 1, a detailed error message is set in * tabprm::err if enabled, see wcserr_enable(). * * * tabcpy() - Copy routine for the tabprm struct * --------------------------------------------- * tabcpy() does a deep copy of one tabprm struct to another, using tabini() to * allocate memory for its arrays if required. Only the "information to be * provided" part of the struct is copied; a call to tabset() is required to * set up the remainder. * * Given: * alloc int If true, allocate memory unconditionally for arrays in * the tabprm struct. * * If false, it is assumed that pointers to these arrays * have been set by the user except if they are null * pointers in which case memory will be allocated for * them regardless. (In other words, setting alloc true * saves having to initalize these pointers to zero.) * * tabsrc const struct tabprm* * Struct to copy from. * * Given and returned: * tabdst struct tabprm* * Struct to copy to. tabprm::flag should be set to -1 * if tabdst was not previously initialized (memory leaks * may result if it was previously initialized). * * Function return value: * int Status return value: * 0: Success. * 1: Null tabprm pointer passed. * 2: Memory allocation failed. * * For returns > 1, a detailed error message is set in * tabprm::err (associated with tabdst) if enabled, see * wcserr_enable(). * * * tabcmp() - Compare two tabprm structs for equality * -------------------------------------------------- * tabcmp() compares two tabprm structs for equality. * * Given: * cmp int A bit field controlling the strictness of the * comparison. At present, this value must always be 0, * indicating a strict comparison. In the future, other * options may be added. * * tol double Tolerance for comparison of floating-point values. * For example, for tol == 1e-6, all floating-point * values in the structs must be equal to the first 6 * decimal places. A value of 0 implies exact equality. * * tab1 const struct tabprm* * The first tabprm struct to compare. * * tab2 const struct tabprm* * The second tabprm struct to compare. * * Returned: * equal int* Non-zero when the given structs are equal. * * Function return value: * int Status return value: * 0: Success. * 1: Null pointer passed. * * * tabfree() - Destructor for the tabprm struct * -------------------------------------------- * tabfree() frees memory allocated for the tabprm arrays by tabini(). * tabini() records the memory it allocates and tabfree() will only attempt to * free this. * * PLEASE NOTE: tabfree() must not be invoked on a tabprm struct that was not * initialized by tabini(). * * Returned: * tab struct tabprm* * Coordinate transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null tabprm pointer passed. * * * tabsize() - Compute the size of a tabprm struct * ----------------------------------------------- * tabsize() computes the full size of a tabprm struct, including allocated * memory. * * Given: * tab const struct tabprm* * Tabular transformation parameters. * * If NULL, the base size of the struct and the allocated * size are both set to zero. * * Returned: * sizes int[2] The first element is the base size of the struct as * returned by sizeof(struct tabprm). The second element * is the total allocated size, in bytes, assuming that * the allocation was done by tabini(). This figure * includes memory allocated for the constituent struct, * tabprm::err. * * It is not an error for the struct not to have been set * up via tabset(), which normally results in additional * memory allocation. * * Function return value: * int Status return value: * 0: Success. * * * tabprt() - Print routine for the tabprm struct * ---------------------------------------------- * tabprt() prints the contents of a tabprm struct using wcsprintf(). Mainly * intended for diagnostic purposes. * * Given: * tab const struct tabprm* * Tabular transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null tabprm pointer passed. * * * tabperr() - Print error messages from a tabprm struct * ----------------------------------------------------- * tabperr() prints the error message(s) (if any) stored in a tabprm struct. * If there are no errors then nothing is printed. It uses wcserr_prt(), q.v. * * Given: * tab const struct tabprm* * Tabular transformation parameters. * * prefix const char * * If non-NULL, each output line will be prefixed with * this string. * * Function return value: * int Status return value: * 0: Success. * 1: Null tabprm pointer passed. * * * tabset() - Setup routine for the tabprm struct * ----------------------------------------------- * tabset() allocates memory for work arrays in the tabprm struct and sets up * the struct according to information supplied within it. * * Note that this routine need not be called directly; it will be invoked by * tabx2s() and tabs2x() if tabprm::flag is anything other than a predefined * magic value. * * Given and returned: * tab struct tabprm* * Tabular transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null tabprm pointer passed. * 3: Invalid tabular parameters. * * For returns > 1, a detailed error message is set in * tabprm::err if enabled, see wcserr_enable(). * * * tabx2s() - Pixel-to-world transformation * ---------------------------------------- * tabx2s() transforms intermediate world coordinates to world coordinates * using coordinate lookup. * * Given and returned: * tab struct tabprm* * Tabular transformation parameters. * * Given: * ncoord, * nelem int The number of coordinates, each of vector length * nelem. * * x const double[ncoord][nelem] * Array of intermediate world coordinates, SI units. * * Returned: * world double[ncoord][nelem] * Array of world coordinates, in SI units. * * stat int[ncoord] * Status return value status for each coordinate: * 0: Success. * 1: Invalid intermediate world coordinate. * * Function return value: * int Status return value: * 0: Success. * 1: Null tabprm pointer passed. * 3: Invalid tabular parameters. * 4: One or more of the x coordinates were invalid, * as indicated by the stat vector. * * For returns > 1, a detailed error message is set in * tabprm::err if enabled, see wcserr_enable(). * * * tabs2x() - World-to-pixel transformation * ---------------------------------------- * tabs2x() transforms world coordinates to intermediate world coordinates. * * Given and returned: * tab struct tabprm* * Tabular transformation parameters. * * Given: * ncoord, * nelem int The number of coordinates, each of vector length * nelem. * world const double[ncoord][nelem] * Array of world coordinates, in SI units. * * Returned: * x double[ncoord][nelem] * Array of intermediate world coordinates, SI units. * stat int[ncoord] * Status return value status for each vector element: * 0: Success. * 1: Invalid world coordinate. * * Function return value: * int Status return value: * 0: Success. * 1: Null tabprm pointer passed. * 3: Invalid tabular parameters. * 5: One or more of the world coordinates were * invalid, as indicated by the stat vector. * * For returns > 1, a detailed error message is set in * tabprm::err if enabled, see wcserr_enable(). * * * tabprm struct - Tabular transformation parameters * ------------------------------------------------- * The tabprm struct contains information required to transform tabular * coordinates. It consists of certain members that must be set by the user * ("given") and others that are set by the WCSLIB routines ("returned"). Some * of the latter are supplied for informational purposes while others are for * internal use only. * * int flag * (Given and returned) This flag must be set to zero whenever any of the * following tabprm structure members are set or changed: * * - tabprm::M (q.v., not normally set by the user), * - tabprm::K (q.v., not normally set by the user), * - tabprm::map, * - tabprm::crval, * - tabprm::index, * - tabprm::coord. * * This signals the initialization routine, tabset(), to recompute the * returned members of the tabprm struct. tabset() will reset flag to * indicate that this has been done. * * PLEASE NOTE: flag should be set to -1 when tabini() is called for the * first time for a particular tabprm struct in order to initialize memory * management. It must ONLY be used on the first initialization otherwise * memory leaks may result. * * int M * (Given or returned) Number of tabular coordinate axes. * * If tabini() is used to initialize the tabprm struct (as would normally * be the case) then it will set M from the value passed to it as a * function argument. The user should not subsequently modify it. * * int *K * (Given or returned) Pointer to the first element of a vector of length * tabprm::M whose elements (K_1, K_2,... K_M) record the lengths of the * axes of the coordinate array and of each indexing vector. * * If tabini() is used to initialize the tabprm struct (as would normally * be the case) then it will set K from the array passed to it as a * function argument. The user should not subsequently modify it. * * int *map * (Given) Pointer to the first element of a vector of length tabprm::M * that defines the association between axis m in the M-dimensional * coordinate array (1 <= m <= M) and the indices of the intermediate world * coordinate and world coordinate arrays, x[] and world[], in the argument * lists for tabx2s() and tabs2x(). * * When x[] and world[] contain the full complement of coordinate elements * in image-order, as will usually be the case, then map[m-1] == i-1 for * axis i in the N-dimensional image (1 <= i <= N). In terms of the FITS * keywords * * map[PVi_3a - 1] == i - 1. * * However, a different association may result if x[], for example, only * contains a (relevant) subset of intermediate world coordinate elements. * For example, if M == 1 for an image with N > 1, it is possible to fill * x[] with the relevant coordinate element with nelem set to 1. In this * case map[0] = 0 regardless of the value of i. * * double *crval * (Given) Pointer to the first element of a vector of length tabprm::M * whose elements contain the index value for the reference pixel for each * of the tabular coordinate axes. * * double **index * (Given) Pointer to the first element of a vector of length tabprm::M of * pointers to vectors of lengths (K_1, K_2,... K_M) of 0-relative indexes * (see tabprm::K). * * The address of any or all of these index vectors may be set to zero, * i.e. * = index[m] == 0; * * this is interpreted as default indexing, i.e. * = index[m][k] = k; * * double *coord * (Given) Pointer to the first element of the tabular coordinate array, * treated as though it were defined as * = double coord[K_M]...[K_2][K_1][M]; * * (see tabprm::K) i.e. with the M dimension varying fastest so that the * M elements of a coordinate vector are stored contiguously in memory. * * int nc * (Returned) Total number of coordinate vectors in the coordinate array * being the product K_1 * K_2 * ... * K_M (see tabprm::K). * * int padding * (An unused variable inserted for alignment purposes only.) * * int *sense * (Returned) Pointer to the first element of a vector of length tabprm::M * whose elements indicate whether the corresponding indexing vector is * monotonic increasing (+1), or decreasing (-1). * * int *p0 * (Returned) Pointer to the first element of a vector of length tabprm::M * of interpolated indices into the coordinate array such that Upsilon_m, * as defined in Paper III, is equal to (p0[m] + 1) + tabprm::delta[m]. * * double *delta * (Returned) Pointer to the first element of a vector of length tabprm::M * of interpolated indices into the coordinate array such that Upsilon_m, * as defined in Paper III, is equal to (tabprm::p0[m] + 1) + delta[m]. * * double *extrema * (Returned) Pointer to the first element of an array that records the * minimum and maximum value of each element of the coordinate vector in * each row of the coordinate array, treated as though it were defined as * = double extrema[K_M]...[K_2][2][M] * * (see tabprm::K). The minimum is recorded in the first element of the * compressed K_1 dimension, then the maximum. This array is used by the * inverse table lookup function, tabs2x(), to speed up table searches. * * struct wcserr *err * (Returned) If enabled, when an error status is returned, this struct * contains detailed information about the error, see wcserr_enable(). * * int m_flag * (For internal use only.) * int m_M * (For internal use only.) * int m_N * (For internal use only.) * int set_M * (For internal use only.) * int m_K * (For internal use only.) * int m_map * (For internal use only.) * int m_crval * (For internal use only.) * int m_index * (For internal use only.) * int m_indxs * (For internal use only.) * int m_coord * (For internal use only.) * * * Global variable: const char *tab_errmsg[] - Status return messages * ------------------------------------------------------------------ * Error messages to match the status value returned from each function. * *===========================================================================*/ #ifndef WCSLIB_TAB #define WCSLIB_TAB #ifdef __cplusplus extern "C" { #endif extern const char *tab_errmsg[]; enum tab_errmsg_enum { TABERR_SUCCESS = 0, // Success. TABERR_NULL_POINTER = 1, // Null tabprm pointer passed. TABERR_MEMORY = 2, // Memory allocation failed. TABERR_BAD_PARAMS = 3, // Invalid tabular parameters. TABERR_BAD_X = 4, // One or more of the x coordinates were // invalid. TABERR_BAD_WORLD = 5 // One or more of the world coordinates were // invalid. }; struct tabprm { // Initialization flag (see the prologue above). //-------------------------------------------------------------------------- int flag; // Set to zero to force initialization. // Parameters to be provided (see the prologue above). //-------------------------------------------------------------------------- int M; // Number of tabular coordinate axes. int *K; // Vector of length M whose elements // (K_1, K_2,... K_M) record the lengths of // the axes of the coordinate array and of // each indexing vector. int *map; // Vector of length M usually such that // map[m-1] == i-1 for coordinate array // axis m and image axis i (see above). double *crval; // Vector of length M containing the index // value for the reference pixel for each // of the tabular coordinate axes. double **index; // Vector of pointers to M indexing vectors // of lengths (K_1, K_2,... K_M). double *coord; // (1+M)-dimensional tabular coordinate // array (see above). // Information derived from the parameters supplied. //-------------------------------------------------------------------------- int nc; // Number of coordinate vectors (of length // M) in the coordinate array. int padding; // (Dummy inserted for alignment purposes.) int *sense; // Vector of M flags that indicate whether // the Mth indexing vector is monotonic // increasing, or else decreasing. int *p0; // Vector of M indices. double *delta; // Vector of M increments. double *extrema; // (1+M)-dimensional array of coordinate // extrema. // Error handling //-------------------------------------------------------------------------- struct wcserr *err; // Private - the remainder are for memory management. //-------------------------------------------------------------------------- int m_flag, m_M, m_N; int set_M; int *m_K, *m_map; double *m_crval, **m_index, **m_indxs, *m_coord; }; // Size of the tabprm struct in int units, used by the Fortran wrappers. #define TABLEN (sizeof(struct tabprm)/sizeof(int)) int tabini(int alloc, int M, const int K[], struct tabprm *tab); int tabmem(struct tabprm *tab); int tabcpy(int alloc, const struct tabprm *tabsrc, struct tabprm *tabdst); int tabcmp(int cmp, double tol, const struct tabprm *tab1, const struct tabprm *tab2, int *equal); int tabfree(struct tabprm *tab); int tabsize(const struct tabprm *tab, int size[2]); int tabprt(const struct tabprm *tab); int tabperr(const struct tabprm *tab, const char *prefix); int tabset(struct tabprm *tab); int tabx2s(struct tabprm *tab, int ncoord, int nelem, const double x[], double world[], int stat[]); int tabs2x(struct tabprm *tab, int ncoord, int nelem, const double world[], double x[], int stat[]); // Deprecated. #define tabini_errmsg tab_errmsg #define tabcpy_errmsg tab_errmsg #define tabfree_errmsg tab_errmsg #define tabprt_errmsg tab_errmsg #define tabset_errmsg tab_errmsg #define tabx2s_errmsg tab_errmsg #define tabs2x_errmsg tab_errmsg #ifdef __cplusplus } #endif #endif // WCSLIB_TAB ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921587.0 astropy-5.0.2/astropy/wcs/include/wcslib/wcs.h0000644000175100001710000026732100000000000020430 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcs.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the wcs routines * --------------------------- * Routines in this suite implement the FITS World Coordinate System (WCS) * standard which defines methods to be used for computing world coordinates * from image pixel coordinates, and vice versa. The standard, and proposed * extensions for handling distortions, are described in * = "Representations of world coordinates in FITS", = Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (WCS Paper I) = = "Representations of celestial coordinates in FITS", = Calabretta, M.R., & Greisen, E.W. 2002, A&A, 395, 1077 (WCS Paper II) = = "Representations of spectral coordinates in FITS", = Greisen, E.W., Calabretta, M.R., Valdes, F.G., & Allen, S.L. = 2006, A&A, 446, 747 (WCS Paper III) = = "Representations of distortions in FITS world coordinate systems", = Calabretta, M.R. et al. (WCS Paper IV, draft dated 2004/04/22), = available from http://www.atnf.csiro.au/people/Mark.Calabretta = = "Mapping on the HEALPix grid", = Calabretta, M.R., & Roukema, B.F. 2007, MNRAS, 381, 865 (WCS Paper V) = = "Representing the 'Butterfly' Projection in FITS -- Projection Code XPH", = Calabretta, M.R., & Lowe, S.R. 2013, PASA, 30, e050 (WCS Paper VI) = = "Representations of time coordinates in FITS - = Time and relative dimension in space", = Rots, A.H., Bunclark, P.S., Calabretta, M.R., Allen, S.L., = Manchester, R.N., & Thompson, W.T. 2015, A&A, 574, A36 (WCS Paper VII) * * These routines are based on the wcsprm struct which contains all information * needed for the computations. The struct contains some members that must be * set by the user, and others that are maintained by these routines, somewhat * like a C++ class but with no encapsulation. * * wcsnpv(), wcsnps(), wcsini(), wcsinit(), wcssub(), wcsfree(), and wcstrim(), * are provided to manage the wcsprm struct, wcssize() computes its total size * including allocated memory, and wcsprt() prints its contents. Refer to the * description of the wcsprm struct for an explanation of the anticipated usage * of these routines. wcscopy(), which does a deep copy of one wcsprm struct * to another, is defined as a preprocessor macro function that invokes * wcssub(). * * wcsperr() prints the error message(s) (if any) stored in a wcsprm struct, * and the linprm, celprm, prjprm, spcprm, and tabprm structs that it contains. * * A setup routine, wcsset(), computes intermediate values in the wcsprm struct * from parameters in it that were supplied by the user. The struct always * needs to be set up by wcsset() but this need not be called explicitly - * refer to the explanation of wcsprm::flag. * * wcsp2s() and wcss2p() implement the WCS world coordinate transformations. * In fact, they are high level driver routines for the WCS linear, * logarithmic, celestial, spectral and tabular transformation routines * described in lin.h, log.h, cel.h, spc.h and tab.h. * * Given either the celestial longitude or latitude plus an element of the * pixel coordinate a hybrid routine, wcsmix(), iteratively solves for the * unknown elements. * * wcsccs() changes the celestial coordinate system of a wcsprm struct, for * example, from equatorial to galactic, and wcssptr() translates the spectral * axis. For example, a 'FREQ' axis may be translated into 'ZOPT-F2W' and vice * versa. * * wcslib_version() returns the WCSLIB version number. * * Quadcube projections: * --------------------- * The quadcube projections (TSC, CSC, QSC) may be represented in FITS in * either of two ways: * * a: The six faces may be laid out in one plane and numbered as follows: * = 0 = = 4 3 2 1 4 3 2 = = 5 * * Faces 2, 3 and 4 may appear on one side or the other (or both). The * world-to-pixel routines map faces 2, 3 and 4 to the left but the * pixel-to-world routines accept them on either side. * * b: The "COBE" convention in which the six faces are stored in a * three-dimensional structure using a CUBEFACE axis indexed from * 0 to 5 as above. * * These routines support both methods; wcsset() determines which is being * used by the presence or absence of a CUBEFACE axis in ctype[]. wcsp2s() * and wcss2p() translate the CUBEFACE axis representation to the single * plane representation understood by the lower-level WCSLIB projection * routines. * * * wcsnpv() - Memory allocation for PVi_ma * --------------------------------------- * wcsnpv() sets or gets the value of NPVMAX (default 64). This global * variable controls the number of pvcard structs, for holding PVi_ma * keyvalues, that wcsini() should allocate space for. It is also used by * wcsinit() as the default value of npvmax. * * PLEASE NOTE: This function is not thread-safe. * * Given: * n int Value of NPVMAX; ignored if < 0. Use a value less * than zero to get the current value. * * Function return value: * int Current value of NPVMAX. * * * wcsnps() - Memory allocation for PSi_ma * --------------------------------------- * wcsnps() sets or gets the value of NPSMAX (default 8). This global variable * controls the number of pscard structs, for holding PSi_ma keyvalues, that * wcsini() should allocate space for. It is also used by wcsinit() as the * default value of npsmax. * * PLEASE NOTE: This function is not thread-safe. * * Given: * n int Value of NPSMAX; ignored if < 0. Use a value less * than zero to get the current value. * * Function return value: * int Current value of NPSMAX. * * * wcsini() - Default constructor for the wcsprm struct * ---------------------------------------------------- * wcsini() is a thin wrapper on wcsinit(). It invokes it with npvmax, * npsmax, and ndpmax set to -1 which causes it to use the values of the * global variables NDPMAX, NPSMAX, and NDPMAX. It is thereby potentially * thread-unsafe if these variables are altered dynamically via wcsnpv(), * wcsnps(), and disndp(). Use wcsinit() for a thread-safe alternative in * this case. * * * wcsinit() - Default constructor for the wcsprm struct * ----------------------------------------------------- * wcsinit() optionally allocates memory for arrays in a wcsprm struct and sets * all members of the struct to default values. * * PLEASE NOTE: every wcsprm struct should be initialized by wcsinit(), * possibly repeatedly. On the first invokation, and only the first * invokation, wcsprm::flag must be set to -1 to initialize memory management, * regardless of whether wcsinit() will actually be used to allocate memory. * * Given: * alloc int If true, allocate memory unconditionally for the * crpix, etc. arrays. Please note that memory is never * allocated by wcsinit() for the auxprm, tabprm, nor * wtbarr structs. * * If false, it is assumed that pointers to these arrays * have been set by the user except if they are null * pointers in which case memory will be allocated for * them regardless. (In other words, setting alloc true * saves having to initalize these pointers to zero.) * * naxis int The number of world coordinate axes. This is used to * determine the length of the various wcsprm vectors and * matrices and therefore the amount of memory to * allocate for them. * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. * * Note that, in order to initialize memory management, * wcsprm::flag should be set to -1 when wcs is * initialized for the first time (memory leaks may * result if it had already been initialized). * * Given: * npvmax int The number of PVi_ma keywords to allocate space for. * If set to -1, the value of the global variable NPVMAX * will be used. This is potentially thread-unsafe if * wcsnpv() is being used dynamically to alter its value. * * npsmax int The number of PSi_ma keywords to allocate space for. * If set to -1, the value of the global variable NPSMAX * will be used. This is potentially thread-unsafe if * wcsnps() is being used dynamically to alter its value. * * ndpmax int The number of DPja or DQia keywords to allocate space * for. If set to -1, the value of the global variable * NDPMAX will be used. This is potentially * thread-unsafe if disndp() is being used dynamically to * alter its value. * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * 2: Memory allocation failed. * * For returns > 1, a detailed error message is set in * wcsprm::err if enabled, see wcserr_enable(). * * * wcsauxi() - Default constructor for the auxprm struct * ----------------------------------------------------- * wcsauxi() optionally allocates memory for an auxprm struct, attaches it to * wcsprm, and sets all members of the struct to default values. * * Given: * alloc int If true, allocate memory unconditionally for the * auxprm struct. * * If false, it is assumed that wcsprm::aux has already * been set to point to an auxprm struct, in which case * the user is responsible for managing that memory. * However, if wcsprm::aux is a null pointer, memory will * be allocated regardless. (In other words, setting * alloc true saves having to initalize the pointer to * zero.) * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * 2: Memory allocation failed. * * * wcssub() - Subimage extraction routine for the wcsprm struct * ------------------------------------------------------------ * wcssub() extracts the coordinate description for a subimage from a wcsprm * struct. It does a deep copy, using wcsinit() to allocate memory for its * arrays if required. Only the "information to be provided" part of the * struct is extracted. Consequently, wcsset() need not have been, and won't * be invoked on the struct from which the subimage is extracted. A call to * wcsset() is required to set up the subimage struct. * * The world coordinate system of the subimage must be separable in the sense * that the world coordinates at any point in the subimage must depend only on * the pixel coordinates of the axes extracted. In practice, this means that * the linear transformation matrix of the original image must not contain * non-zero off-diagonal terms that associate any of the subimage axes with any * of the non-subimage axes. Likewise, if any distortions are associated with * the subimage axes, they must not depend on any of the axes that are not * being extracted. * * Note that while the required elements of the tabprm array are extracted, the * wtbarr array is not. (Thus it is not appropriate to call wcssub() after * wcstab() but before filling the tabprm structs - refer to wcshdr.h.) * * wcssub() can also add axes to a wcsprm struct. The new axes will be created * using the defaults set by wcsinit() which produce a simple, unnamed, linear * axis with world coordinate equal to the pixel coordinate. These default * values can be changed afterwards, before invoking wcsset(). * * Given: * alloc int If true, allocate memory for the crpix, etc. arrays in * the destination. Otherwise, it is assumed that * pointers to these arrays have been set by the user * except if they are null pointers in which case memory * will be allocated for them regardless. * * wcssrc const struct wcsprm* * Struct to extract from. * * Given and returned: * nsub int* * axes int[] Vector of length *nsub containing the image axis * numbers (1-relative) to extract. Order is * significant; axes[0] is the axis number of the input * image that corresponds to the first axis in the * subimage, etc. * * Use an axis number of 0 to create a new axis using * the defaults set by wcsinit(). They can be changed * later. * * nsub (the pointer) may be set to zero, and so also may * *nsub, which is interpreted to mean all axes in the * input image; the number of axes will be returned if * nsub != 0x0. axes itself (the pointer) may be set to * zero to indicate the first *nsub axes in their * original order. * * Set both nsub (or *nsub) and axes to zero to do a deep * copy of one wcsprm struct to another. * * Subimage extraction by coordinate axis type may be * done by setting the elements of axes[] to the * following special preprocessor macro values: * * WCSSUB_LONGITUDE: Celestial longitude. * WCSSUB_LATITUDE: Celestial latitude. * WCSSUB_CUBEFACE: Quadcube CUBEFACE axis. * WCSSUB_SPECTRAL: Spectral axis. * WCSSUB_STOKES: Stokes axis. * * Refer to the notes (below) for further usage examples. * * On return, *nsub will be set to the number of axes in * the subimage; this may be zero if there were no axes * of the required type(s) (in which case no memory will * be allocated). axes[] will contain the axis numbers * that were extracted, or 0 for newly created axes. The * vector length must be sufficient to contain all axis * numbers. No checks are performed to verify that the * coordinate axes are consistent, this is done by * wcsset(). * * wcsdst struct wcsprm* * Struct describing the subimage. wcsprm::flag should * be set to -1 if wcsdst was not previously initialized * (memory leaks may result if it was previously * initialized). * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * 2: Memory allocation failed. * 12: Invalid subimage specification. * 13: Non-separable subimage coordinate system. * * For returns > 1, a detailed error message is set in * wcsprm::err if enabled, see wcserr_enable(). * * Notes: * 1: Combinations of subimage axes of particular types may be extracted in * the same order as they occur in the input image by combining * preprocessor codes, for example * = *nsub = 1; = axes[0] = WCSSUB_LONGITUDE | WCSSUB_LATITUDE | WCSSUB_SPECTRAL; * * would extract the longitude, latitude, and spectral axes in the same * order as the input image. If one of each were present, *nsub = 3 would * be returned. * * For convenience, WCSSUB_CELESTIAL is defined as the combination * WCSSUB_LONGITUDE | WCSSUB_LATITUDE | WCSSUB_CUBEFACE. * * The codes may also be negated to extract all but the types specified, * for example * = *nsub = 4; = axes[0] = WCSSUB_LONGITUDE; = axes[1] = WCSSUB_LATITUDE; = axes[2] = WCSSUB_CUBEFACE; = axes[3] = -(WCSSUB_SPECTRAL | WCSSUB_STOKES); * * The last of these specifies all axis types other than spectral or * Stokes. Extraction is done in the order specified by axes[] a * longitude axis (if present) would be extracted first (via axes[0]) and * not subsequently (via axes[3]). Likewise for the latitude and cubeface * axes in this example. * * From the foregoing, it is apparent that the value of *nsub returned may * be less than or greater than that given. However, it will never exceed * the number of axes in the input image (plus the number of newly-created * axes if any were specified on input). * * * wcscompare() - Compare two wcsprm structs for equality * ------------------------------------------------------ * wcscompare() compares two wcsprm structs for equality. * * Given: * cmp int A bit field controlling the strictness of the * comparison. When 0, all fields must be identical. * * The following constants may be or'ed together to * relax the comparison: * WCSCOMPARE_ANCILLARY: Ignore ancillary keywords * that don't change the WCS transformation, such * as DATE-OBS or EQUINOX. * WCSCOMPARE_TILING: Ignore integral differences in * CRPIXja. This is the 'tiling' condition, where * two WCSes cover different regions of the same * map projection and align on the same map grid. * WCSCOMPARE_CRPIX: Ignore any differences at all in * CRPIXja. The two WCSes cover different regions * of the same map projection but may not align on * the same map grid. Overrides WCSCOMPARE_TILING. * * tol double Tolerance for comparison of floating-point values. * For example, for tol == 1e-6, all floating-point * values in the structs must be equal to the first 6 * decimal places. A value of 0 implies exact equality. * * wcs1 const struct wcsprm* * The first wcsprm struct to compare. * * wcs2 const struct wcsprm* * The second wcsprm struct to compare. * * Returned: * equal int* Non-zero when the given structs are equal. * * Function return value: * int Status return value: * 0: Success. * 1: Null pointer passed. * * * wcscopy() macro - Copy routine for the wcsprm struct * ---------------------------------------------------- * wcscopy() does a deep copy of one wcsprm struct to another. As of * WCSLIB 3.6, it is implemented as a preprocessor macro that invokes * wcssub() with the nsub and axes pointers both set to zero. * * * wcsfree() - Destructor for the wcsprm struct * -------------------------------------------- * wcsfree() frees memory allocated for the wcsprm arrays by wcsinit() and/or * wcsset(). wcsinit() records the memory it allocates and wcsfree() will only * attempt to free this. * * PLEASE NOTE: wcsfree() must not be invoked on a wcsprm struct that was not * initialized by wcsinit(). * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * * * wcstrim() - Free unused arrays in the wcsprm struct * --------------------------------------------------- * wcstrim() frees memory allocated by wcsinit() for arrays in the wcsprm * struct that remains unused after it has been set up by wcsset(). * * The free'd array members are associated with FITS WCS keyrecords that are * rarely used and usually just bloat the struct: wcsprm::crota, wcsprm::colax, * wcsprm::cname, wcsprm::crder, wcsprm::csyer, wcsprm::czphs, and * wcsprm::cperi. If unused, wcsprm::pv, wcsprm::ps, and wcsprm::cd are also * freed. * * Once these arrays have been freed, a test such as = = if (!undefined(wcs->cname[i])) {...} = * must be protected as follows = = if (wcs->cname && !undefined(wcs->cname[i])) {...} = * In addition, if wcsprm::npv is non-zero but less than wcsprm::npvmax, then * the unused space in wcsprm::pv will be recovered (using realloc()). * Likewise for wcsprm::ps. * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * 14: wcsprm struct is unset. * * * wcssize() - Compute the size of a wcsprm struct * ----------------------------------------------- * wcssize() computes the full size of a wcsprm struct, including allocated * memory. * * Given: * wcs const struct wcsprm* * Coordinate transformation parameters. * * If NULL, the base size of the struct and the allocated * size are both set to zero. * * Returned: * sizes int[2] The first element is the base size of the struct as * returned by sizeof(struct wcsprm). The second element * is the total allocated size, in bytes, assuming that * the allocation was done by wcsini(). This figure * includes memory allocated for members of constituent * structs, such as wcsprm::lin. * * It is not an error for the struct not to have been set * up via wcsset(), which normally results in additional * memory allocation. * * Function return value: * int Status return value: * 0: Success. * * * auxsize() - Compute the size of a auxprm struct * ----------------------------------------------- * auxsize() computes the full size of a auxprm struct, including allocated * memory. * * Given: * aux const struct auxprm* * Auxiliary coordinate information. * * If NULL, the base size of the struct and the allocated * size are both set to zero. * * Returned: * sizes int[2] The first element is the base size of the struct as * returned by sizeof(struct auxprm). The second element * is the total allocated size, in bytes, currently zero. * * Function return value: * int Status return value: * 0: Success. * * * wcsprt() - Print routine for the wcsprm struct * ---------------------------------------------- * wcsprt() prints the contents of a wcsprm struct using wcsprintf(). Mainly * intended for diagnostic purposes. * * Given: * wcs const struct wcsprm* * Coordinate transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * * * wcsperr() - Print error messages from a wcsprm struct * ----------------------------------------------------- * wcsperr() prints the error message(s), if any, stored in a wcsprm struct, * and the linprm, celprm, prjprm, spcprm, and tabprm structs that it contains. * If there are no errors then nothing is printed. It uses wcserr_prt(), q.v. * * Given: * wcs const struct wcsprm* * Coordinate transformation parameters. * * prefix const char * * If non-NULL, each output line will be prefixed with * this string. * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * * * wcsbchk() - Enable/disable bounds checking * ------------------------------------------ * wcsbchk() is used to control bounds checking in the projection routines. * Note that wcsset() always enables bounds checking. wcsbchk() will invoke * wcsset() on the wcsprm struct beforehand if necessary. * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. * * Given: * bounds int If bounds&1 then enable strict bounds checking for the * spherical-to-Cartesian (s2x) transformation for the * AZP, SZP, TAN, SIN, ZPN, and COP projections. * * If bounds&2 then enable strict bounds checking for the * Cartesian-to-spherical (x2s) transformation for the * HPX and XPH projections. * * If bounds&4 then enable bounds checking on the native * coordinates returned by the Cartesian-to-spherical * (x2s) transformations using prjchk(). * * Zero it to disable all checking. * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * * * wcsset() - Setup routine for the wcsprm struct * ---------------------------------------------- * wcsset() sets up a wcsprm struct according to information supplied within * it (refer to the description of the wcsprm struct). * * wcsset() recognizes the NCP projection and converts it to the equivalent SIN * projection and likewise translates GLS into SFL. It also translates the * AIPS spectral types ('FREQ-LSR', 'FELO-HEL', etc.), possibly changing the * input header keywords wcsprm::ctype and/or wcsprm::specsys if necessary. * * Note that this routine need not be called directly; it will be invoked by * wcsp2s() and wcss2p() if the wcsprm::flag is anything other than a * predefined magic value. * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * 2: Memory allocation failed. * 3: Linear transformation matrix is singular. * 4: Inconsistent or unrecognized coordinate axis * types. * 5: Invalid parameter value. * 6: Invalid coordinate transformation parameters. * 7: Ill-conditioned coordinate transformation * parameters. * * For returns > 1, a detailed error message is set in * wcsprm::err if enabled, see wcserr_enable(). * * Notes: * 1: wcsset() always enables strict bounds checking in the projection * routines (via a call to prjini()). Use wcsbchk() to modify * bounds-checking after wcsset() is invoked. * * * wcsp2s() - Pixel-to-world transformation * ---------------------------------------- * wcsp2s() transforms pixel coordinates to world coordinates. * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. * * Given: * ncoord, * nelem int The number of coordinates, each of vector length * nelem but containing wcs.naxis coordinate elements. * Thus nelem must equal or exceed the value of the * NAXIS keyword unless ncoord == 1, in which case nelem * is not used. * * pixcrd const double[ncoord][nelem] * Array of pixel coordinates. * * Returned: * imgcrd double[ncoord][nelem] * Array of intermediate world coordinates. For * celestial axes, imgcrd[][wcs.lng] and * imgcrd[][wcs.lat] are the projected x-, and * y-coordinates in pseudo "degrees". For spectral * axes, imgcrd[][wcs.spec] is the intermediate spectral * coordinate, in SI units. * * phi,theta double[ncoord] * Longitude and latitude in the native coordinate system * of the projection [deg]. * * world double[ncoord][nelem] * Array of world coordinates. For celestial axes, * world[][wcs.lng] and world[][wcs.lat] are the * celestial longitude and latitude [deg]. For * spectral axes, imgcrd[][wcs.spec] is the intermediate * spectral coordinate, in SI units. * * stat int[ncoord] * Status return value for each coordinate: * 0: Success. * 1+: A bit mask indicating invalid pixel coordinate * element(s). * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * 2: Memory allocation failed. * 3: Linear transformation matrix is singular. * 4: Inconsistent or unrecognized coordinate axis * types. * 5: Invalid parameter value. * 6: Invalid coordinate transformation parameters. * 7: Ill-conditioned coordinate transformation * parameters. * 8: One or more of the pixel coordinates were * invalid, as indicated by the stat vector. * * For returns > 1, a detailed error message is set in * wcsprm::err if enabled, see wcserr_enable(). * * * wcss2p() - World-to-pixel transformation * ---------------------------------------- * wcss2p() transforms world coordinates to pixel coordinates. * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. * * Given: * ncoord, * nelem int The number of coordinates, each of vector length nelem * but containing wcs.naxis coordinate elements. Thus * nelem must equal or exceed the value of the NAXIS * keyword unless ncoord == 1, in which case nelem is not * used. * * world const double[ncoord][nelem] * Array of world coordinates. For celestial axes, * world[][wcs.lng] and world[][wcs.lat] are the * celestial longitude and latitude [deg]. For spectral * axes, world[][wcs.spec] is the spectral coordinate, in * SI units. * * Returned: * phi,theta double[ncoord] * Longitude and latitude in the native coordinate * system of the projection [deg]. * * imgcrd double[ncoord][nelem] * Array of intermediate world coordinates. For * celestial axes, imgcrd[][wcs.lng] and * imgcrd[][wcs.lat] are the projected x-, and * y-coordinates in pseudo "degrees". For quadcube * projections with a CUBEFACE axis the face number is * also returned in imgcrd[][wcs.cubeface]. For * spectral axes, imgcrd[][wcs.spec] is the intermediate * spectral coordinate, in SI units. * * pixcrd double[ncoord][nelem] * Array of pixel coordinates. * * stat int[ncoord] * Status return value for each coordinate: * 0: Success. * 1+: A bit mask indicating invalid world coordinate * element(s). * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * 2: Memory allocation failed. * 3: Linear transformation matrix is singular. * 4: Inconsistent or unrecognized coordinate axis * types. * 5: Invalid parameter value. * 6: Invalid coordinate transformation parameters. * 7: Ill-conditioned coordinate transformation * parameters. * 9: One or more of the world coordinates were * invalid, as indicated by the stat vector. * * For returns > 1, a detailed error message is set in * wcsprm::err if enabled, see wcserr_enable(). * * * wcsmix() - Hybrid coordinate transformation * ------------------------------------------- * wcsmix(), given either the celestial longitude or latitude plus an element * of the pixel coordinate, solves for the remaining elements by iterating on * the unknown celestial coordinate element using wcss2p(). Refer also to the * notes below. * * Given and returned: * wcs struct wcsprm* * Indices for the celestial coordinates obtained * by parsing the wcsprm::ctype[]. * * Given: * mixpix int Which element of the pixel coordinate is given. * * mixcel int Which element of the celestial coordinate is given: * 1: Celestial longitude is given in * world[wcs.lng], latitude returned in * world[wcs.lat]. * 2: Celestial latitude is given in * world[wcs.lat], longitude returned in * world[wcs.lng]. * * vspan const double[2] * Solution interval for the celestial coordinate [deg]. * The ordering of the two limits is irrelevant. * Longitude ranges may be specified with any convenient * normalization, for example [-120,+120] is the same as * [240,480], except that the solution will be returned * with the same normalization, i.e. lie within the * interval specified. * * vstep const double * Step size for solution search [deg]. If zero, a * sensible, although perhaps non-optimal default will be * used. * * viter int If a solution is not found then the step size will be * halved and the search recommenced. viter controls how * many times the step size is halved. The allowed range * is 5 - 10. * * Given and returned: * world double[naxis] * World coordinate elements. world[wcs.lng] and * world[wcs.lat] are the celestial longitude and * latitude [deg]. Which is given and which returned * depends on the value of mixcel. All other elements * are given. * * Returned: * phi,theta double[naxis] * Longitude and latitude in the native coordinate * system of the projection [deg]. * * imgcrd double[naxis] * Image coordinate elements. imgcrd[wcs.lng] and * imgcrd[wcs.lat] are the projected x-, and * y-coordinates in pseudo "degrees". * * Given and returned: * pixcrd double[naxis] * Pixel coordinate. The element indicated by mixpix is * given and the remaining elements are returned. * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * 2: Memory allocation failed. * 3: Linear transformation matrix is singular. * 4: Inconsistent or unrecognized coordinate axis * types. * 5: Invalid parameter value. * 6: Invalid coordinate transformation parameters. * 7: Ill-conditioned coordinate transformation * parameters. * 10: Invalid world coordinate. * 11: No solution found in the specified interval. * * For returns > 1, a detailed error message is set in * wcsprm::err if enabled, see wcserr_enable(). * * Notes: * 1: Initially the specified solution interval is checked to see if it's a * "crossing" interval. If it isn't, a search is made for a crossing * solution by iterating on the unknown celestial coordinate starting at * the upper limit of the solution interval and decrementing by the * specified step size. A crossing is indicated if the trial value of the * pixel coordinate steps through the value specified. If a crossing * interval is found then the solution is determined by a modified form of * "regula falsi" division of the crossing interval. If no crossing * interval was found within the specified solution interval then a search * is made for a "non-crossing" solution as may arise from a point of * tangency. The process is complicated by having to make allowance for * the discontinuities that occur in all map projections. * * Once one solution has been determined others may be found by subsequent * invokations of wcsmix() with suitably restricted solution intervals. * * Note the circumstance that arises when the solution point lies at a * native pole of a projection in which the pole is represented as a * finite curve, for example the zenithals and conics. In such cases two * or more valid solutions may exist but wcsmix() only ever returns one. * * Because of its generality wcsmix() is very compute-intensive. For * compute-limited applications more efficient special-case solvers could * be written for simple projections, for example non-oblique cylindrical * projections. * * * wcsccs() - Change celestial coordinate system * --------------------------------------------- * wcsccs() changes the celestial coordinate system of a wcsprm struct. For * example, from equatorial to galactic coordinates. * * Parameters that define the spherical coordinate transformation, essentially * being three Euler angles, must be provided. Thereby wcsccs() does not need * prior knowledge of specific celestial coordinate systems. It also has the * advantage of making it completely general. * * Auxiliary members of the wcsprm struct relating to equatorial celestial * coordinate systems may also be changed. * * Only orthodox spherical coordinate systems are supported. That is, they * must be right-handed, with latitude increasing from zero at the equator to * +90 degrees at the pole. This precludes systems such as aziumuth and zenith * distance, which, however, could be handled as negative azimuth and * elevation. * * PLEASE NOTE: Information in the wcsprm struct relating to the original * coordinate system will be overwritten and therefore lost. If this is * undesirable, invoke wcsccs() on a copy of the struct made with wcssub(). * The wcsprm struct is reset on return with an explicit call to wcsset(). * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. Particular * "values to be given" elements of the wcsprm struct * are modified. * * Given: * lng2p1, * lat2p1 double Longitude and latitude in the new celestial coordinate * system of the pole (i.e. latitude +90) of the original * system [deg]. See notes 1 and 2 below. * * lng1p2 double Longitude in the original celestial coordinate system * of the pole (i.e. latitude +90) of the new system * [deg]. See note 1 below. * * clng,clat const char* * Longitude and latitude identifiers of the new CTYPEia * celestial axis codes, without trailing dashes. For * example, "RA" and "DEC" or "GLON" and "GLAT". Up to * four characters are used, longer strings need not be * null-terminated. * * radesys const char* * Used when transforming to equatorial coordinates, * identified by clng == "RA" and clat = "DEC". May be * set to the null pointer to preserve the current value. * Up to 71 characters are used, longer strings need not * be null-terminated. * * If the new coordinate system is anything other than * equatorial, then wcsprm::radesys will be cleared. * * equinox double Used when transforming to equatorial coordinates. May * be set to zero to preserve the current value. * * If the new coordinate system is not equatorial, then * wcsprm::equinox will be marked as undefined. * * alt const char* * Character code for alternate coordinate descriptions * (i.e. the 'a' in keyword names such as CTYPEia). This * is blank for the primary coordinate description, or * one of the 26 upper-case letters, A-Z. May be set to * the null pointer, or null string if no change is * required. * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * 12: Invalid subimage specification (no celestial * axes). * * Notes: * 1: Follows the prescription given in WCS Paper II, Sect. 2.7 for changing * celestial coordinates. * * The implementation takes account of indeterminacies that arise in that * prescription in the particular cases where one of the poles of the new * system is at the fiducial point, or one of them is at the native pole. * * 2: If lat2p1 == +90, i.e. where the poles of the two coordinate systems * coincide, then the spherical coordinate transformation becomes a simple * change in origin of longitude given by * lng2 = lng1 + (lng2p1 - lng1p2 - 180), and lat2 = lat1, where * (lng2,lat2) are coordinates in the new system, and (lng1,lat1) are * coordinates in the original system. * * Likewise, if lat2p1 == -90, then lng2 = -lng1 + (lng2p1 + lng1p2), and * lat2 = -lat1. * * 3: For example, if the original coordinate system is B1950 equatorial and * the desired new coordinate system is galactic, then * * - (lng2p1,lat2p1) are the galactic coordinates of the B1950 celestial * pole, defined by the IAU to be (123.0,+27.4), and lng1p2 is the B1950 * right ascension of the galactic pole, defined as 192.25. Clearly * these coordinates are fixed for a particular coordinate * transformation. * * - (clng,clat) would be 'GLON' and 'GLAT', these being the FITS standard * identifiers for galactic coordinates. * * - Since the new coordinate system is not equatorial, wcsprm::radesys * and wcsprm::equinox will be cleared. * * 4. The coordinates required for some common transformations (obtained from * https://ned.ipac.caltech.edu/coordinate_calculator) are as follows: * = (123.0000,+27.4000) galactic coordinates of B1950 celestial pole, = (192.2500,+27.4000) B1950 equatorial coordinates of galactic pole. * = (122.9319,+27.1283) galactic coordinates of J2000 celestial pole, = (192.8595,+27.1283) J2000 equatorial coordinates of galactic pole. * = (359.6774,+89.7217) B1950 equatorial coordinates of J2000 pole, = (180.3162,+89.7217) J2000 equatorial coordinates of B1950 pole. * = (270.0000,+66.5542) B1950 equatorial coordinates of B1950 ecliptic pole, = ( 90.0000,+66.5542) B1950 ecliptic coordinates of B1950 celestial pole. * = (270.0000,+66.5607) J2000 equatorial coordinates of J2000 ecliptic pole, = ( 90.0000,+66.5607) J2000 ecliptic coordinates of J2000 celestial pole. * = ( 26.7315,+15.6441) supergalactic coordinates of B1950 celestial pole, = (283.1894,+15.6441) B1950 equatorial coordinates of supergalactic pole. * = ( 26.4505,+15.7089) supergalactic coordinates of J2000 celestial pole, = (283.7542,+15.7089) J2000 equatorial coordinates of supergalactic pole. * * * wcssptr() - Spectral axis translation * ------------------------------------- * wcssptr() translates the spectral axis in a wcsprm struct. For example, a * 'FREQ' axis may be translated into 'ZOPT-F2W' and vice versa. * * PLEASE NOTE: Information in the wcsprm struct relating to the original * coordinate system will be overwritten and therefore lost. If this is * undesirable, invoke wcssptr() on a copy of the struct made with wcssub(). * The wcsprm struct is reset on return with an explicit call to wcsset(). * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. * * i int* Index of the spectral axis (0-relative). If given < 0 * it will be set to the first spectral axis identified * from the ctype[] keyvalues in the wcsprm struct. * * ctype char[9] Desired spectral CTYPEia. Wildcarding may be used as * for the ctypeS2 argument to spctrn() as described in * the prologue of spc.h, i.e. if the final three * characters are specified as "???", or if just the * eighth character is specified as '?', the correct * algorithm code will be substituted and returned. * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * 2: Memory allocation failed. * 3: Linear transformation matrix is singular. * 4: Inconsistent or unrecognized coordinate axis * types. * 5: Invalid parameter value. * 6: Invalid coordinate transformation parameters. * 7: Ill-conditioned coordinate transformation * parameters. * 12: Invalid subimage specification (no spectral * axis). * * For returns > 1, a detailed error message is set in * wcsprm::err if enabled, see wcserr_enable(). * * * wcslib_version() - WCSLIB version number * ---------------------------------------- * wcslib_version() returns the WCSLIB version number. * * The major version number changes when the ABI changes or when the license * conditions change. ABI changes typically result from a change to the * contents of one of the structs. The major version number is used to * distinguish between incompatible versions of the sharable library. * * The minor version number changes with new functionality or bug fixes that do * not involve a change in the ABI. * * The auxiliary version number (which is often absent) signals changes to the * documentation, test suite, build procedures, or any other change that does * not affect the compiled library. * * Returned: * vers[3] int[3] The broken-down version number: * 0: Major version number. * 1: Minor version number. * 2: Auxiliary version number (zero if absent). * May be given as a null pointer if not required. * * Function return value: * char* A null-terminated, statically allocated string * containing the version number in the usual form, i.e. * "..". * * * wcsprm struct - Coordinate transformation parameters * ---------------------------------------------------- * The wcsprm struct contains information required to transform world * coordinates. It consists of certain members that must be set by the user * ("given") and others that are set by the WCSLIB routines ("returned"). * While the addresses of the arrays themselves may be set by wcsinit() if it * (optionally) allocates memory, their contents must be set by the user. * * Some parameters that are given are not actually required for transforming * coordinates. These are described as "auxiliary"; the struct simply provides * a place to store them, though they may be used by wcshdo() in constructing a * FITS header from a wcsprm struct. Some of the returned values are supplied * for informational purposes and others are for internal use only as * indicated. * * In practice, it is expected that a WCS parser would scan the FITS header to * determine the number of coordinate axes. It would then use wcsinit() to * allocate memory for arrays in the wcsprm struct and set default values. * Then as it reread the header and identified each WCS keyrecord it would load * the value into the relevant wcsprm array element. This is essentially what * wcspih() does - refer to the prologue of wcshdr.h. As the final step, * wcsset() is invoked, either directly or indirectly, to set the derived * members of the wcsprm struct. wcsset() strips off trailing blanks in all * string members and null-fills the character array. * * int flag * (Given and returned) This flag must be set to zero whenever any of the * following wcsprm struct members are set or changed: * * - wcsprm::naxis (q.v., not normally set by the user), * - wcsprm::crpix, * - wcsprm::pc, * - wcsprm::cdelt, * - wcsprm::crval, * - wcsprm::cunit, * - wcsprm::ctype, * - wcsprm::lonpole, * - wcsprm::latpole, * - wcsprm::restfrq, * - wcsprm::restwav, * - wcsprm::npv, * - wcsprm::pv, * - wcsprm::nps, * - wcsprm::ps, * - wcsprm::cd, * - wcsprm::crota, * - wcsprm::altlin, * - wcsprm::ntab, * - wcsprm::nwtb, * - wcsprm::tab, * - wcsprm::wtb. * * This signals the initialization routine, wcsset(), to recompute the * returned members of the linprm, celprm, spcprm, and tabprm structs. * wcsset() will reset flag to indicate that this has been done. * * PLEASE NOTE: flag should be set to -1 when wcsinit() is called for the * first time for a particular wcsprm struct in order to initialize memory * management. It must ONLY be used on the first initialization otherwise * memory leaks may result. * * int naxis * (Given or returned) Number of pixel and world coordinate elements. * * If wcsinit() is used to initialize the linprm struct (as would normally * be the case) then it will set naxis from the value passed to it as a * function argument. The user should not subsequently modify it. * * double *crpix * (Given) Address of the first element of an array of double containing * the coordinate reference pixel, CRPIXja. * * double *pc * (Given) Address of the first element of the PCi_ja (pixel coordinate) * transformation matrix. The expected order is * = struct wcsprm wcs; = wcs.pc = {PC1_1, PC1_2, PC2_1, PC2_2}; * * This may be constructed conveniently from a 2-D array via * = double m[2][2] = {{PC1_1, PC1_2}, = {PC2_1, PC2_2}}; * * which is equivalent to * = double m[2][2]; = m[0][0] = PC1_1; = m[0][1] = PC1_2; = m[1][0] = PC2_1; = m[1][1] = PC2_2; * * The storage order for this 2-D array is the same as for the 1-D array, * whence * = wcs.pc = *m; * * would be legitimate. * * double *cdelt * (Given) Address of the first element of an array of double containing * the coordinate increments, CDELTia. * * double *crval * (Given) Address of the first element of an array of double containing * the coordinate reference values, CRVALia. * * char (*cunit)[72] * (Given) Address of the first element of an array of char[72] containing * the CUNITia keyvalues which define the units of measurement of the * CRVALia, CDELTia, and CDi_ja keywords. * * As CUNITia is an optional header keyword, cunit[][72] may be left blank * but otherwise is expected to contain a standard units specification as * defined by WCS Paper I. Utility function wcsutrn(), described in * wcsunits.h, is available to translate commonly used non-standard units * specifications but this must be done as a separate step before invoking * wcsset(). * * For celestial axes, if cunit[][72] is not blank, wcsset() uses * wcsunits() to parse it and scale cdelt[], crval[], and cd[][*] to * degrees. It then resets cunit[][72] to "deg". * * For spectral axes, if cunit[][72] is not blank, wcsset() uses wcsunits() * to parse it and scale cdelt[], crval[], and cd[][*] to SI units. It * then resets cunit[][72] accordingly. * * wcsset() ignores cunit[][72] for other coordinate types; cunit[][72] may * be used to label coordinate values. * * These variables accomodate the longest allowed string-valued FITS * keyword, being limited to 68 characters, plus the null-terminating * character. * * char (*ctype)[72] * (Given) Address of the first element of an array of char[72] containing * the coordinate axis types, CTYPEia. * * The ctype[][72] keyword values must be in upper case and there must be * zero or one pair of matched celestial axis types, and zero or one * spectral axis. The ctype[][72] strings should be padded with blanks on * the right and null-terminated so that they are at least eight characters * in length. * * These variables accomodate the longest allowed string-valued FITS * keyword, being limited to 68 characters, plus the null-terminating * character. * * double lonpole * (Given and returned) The native longitude of the celestial pole, phi_p, * given by LONPOLEa [deg] or by PVi_2a [deg] attached to the longitude * axis which takes precedence if defined, and ... * double latpole * (Given and returned) ... the native latitude of the celestial pole, * theta_p, given by LATPOLEa [deg] or by PVi_3a [deg] attached to the * longitude axis which takes precedence if defined. * * lonpole and latpole may be left to default to values set by wcsinit() * (see celprm::ref), but in any case they will be reset by wcsset() to * the values actually used. Note therefore that if the wcsprm struct is * reused without resetting them, whether directly or via wcsinit(), they * will no longer have their default values. * * double restfrq * (Given) The rest frequency [Hz], and/or ... * double restwav * (Given) ... the rest wavelength in vacuo [m], only one of which need be * given, the other should be set to zero. * * int npv * (Given) The number of entries in the wcsprm::pv[] array. * * int npvmax * (Given or returned) The length of the wcsprm::pv[] array. * * npvmax will be set by wcsinit() if it allocates memory for wcsprm::pv[], * otherwise it must be set by the user. See also wcsnpv(). * * struct pvcard *pv * (Given) Address of the first element of an array of length npvmax of * pvcard structs. * * As a FITS header parser encounters each PVi_ma keyword it should load it * into a pvcard struct in the array and increment npv. wcsset() * interprets these as required. * * Note that, if they were not given, wcsset() resets the entries for * PVi_1a, PVi_2a, PVi_3a, and PVi_4a for longitude axis i to match * phi_0 and theta_0 (the native longitude and latitude of the reference * point), LONPOLEa and LATPOLEa respectively. * * int nps * (Given) The number of entries in the wcsprm::ps[] array. * * int npsmax * (Given or returned) The length of the wcsprm::ps[] array. * * npsmax will be set by wcsinit() if it allocates memory for wcsprm::ps[], * otherwise it must be set by the user. See also wcsnps(). * * struct pscard *ps * (Given) Address of the first element of an array of length npsmax of * pscard structs. * * As a FITS header parser encounters each PSi_ma keyword it should load it * into a pscard struct in the array and increment nps. wcsset() * interprets these as required (currently no PSi_ma keyvalues are * recognized). * * double *cd * (Given) For historical compatibility, the wcsprm struct supports two * alternate specifications of the linear transformation matrix, those * associated with the CDi_ja keywords, and ... * double *crota * (Given) ... those associated with the CROTAi keywords. Although these * may not formally co-exist with PCi_ja, the approach taken here is simply * to ignore them if given in conjunction with PCi_ja. * * int altlin * (Given) altlin is a bit flag that denotes which of the PCi_ja, CDi_ja * and CROTAi keywords are present in the header: * * - Bit 0: PCi_ja is present. * * - Bit 1: CDi_ja is present. * * Matrix elements in the IRAF convention are equivalent to the product * CDi_ja = CDELTia * PCi_ja, but the defaults differ from that of the * PCi_ja matrix. If one or more CDi_ja keywords are present then all * unspecified CDi_ja default to zero. If no CDi_ja (or CROTAi) keywords * are present, then the header is assumed to be in PCi_ja form whether * or not any PCi_ja keywords are present since this results in an * interpretation of CDELTia consistent with the original FITS * specification. * * While CDi_ja may not formally co-exist with PCi_ja, it may co-exist * with CDELTia and CROTAi which are to be ignored. * * - Bit 2: CROTAi is present. * * In the AIPS convention, CROTAi may only be associated with the * latitude axis of a celestial axis pair. It specifies a rotation in * the image plane that is applied AFTER the CDELTia; any other CROTAi * keywords are ignored. * * CROTAi may not formally co-exist with PCi_ja. * * CROTAi and CDELTia may formally co-exist with CDi_ja but if so are to * be ignored. * * - Bit 3: PCi_ja + CDELTia was derived from CDi_ja by wcspcx(). * * This bit is set by wcspcx() when it derives PCi_ja and CDELTia from * CDi_ja via an orthonormal decomposition. In particular, it signals * wcsset() not to replace PCi_ja by a copy of CDi_ja with CDELTia set * to unity. * * CDi_ja and CROTAi keywords, if found, are to be stored in the wcsprm::cd * and wcsprm::crota arrays which are dimensioned similarly to wcsprm::pc * and wcsprm::cdelt. FITS header parsers should use the following * procedure: * * - Whenever a PCi_ja keyword is encountered: altlin |= 1; * * - Whenever a CDi_ja keyword is encountered: altlin |= 2; * * - Whenever a CROTAi keyword is encountered: altlin |= 4; * * If none of these bits are set the PCi_ja representation results, i.e. * wcsprm::pc and wcsprm::cdelt will be used as given. * * These alternate specifications of the linear transformation matrix are * translated immediately to PCi_ja by wcsset() and are invisible to the * lower-level WCSLIB routines. In particular, unless bit 3 is also set, * wcsset() resets wcsprm::cdelt to unity if CDi_ja is present (and no * PCi_ja). * * If CROTAi are present but none is associated with the latitude axis * (and no PCi_ja or CDi_ja), then wcsset() reverts to a unity PCi_ja * matrix. * * int velref * (Given) AIPS velocity code VELREF, refer to spcaips(). * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::velref is changed. * * char alt[4] * (Given, auxiliary) Character code for alternate coordinate descriptions * (i.e. the 'a' in keyword names such as CTYPEia). This is blank for the * primary coordinate description, or one of the 26 upper-case letters, * A-Z. * * An array of four characters is provided for alignment purposes, only the * first is used. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::alt is changed. * * int colnum * (Given, auxiliary) Where the coordinate representation is associated * with an image-array column in a FITS binary table, this variable may be * used to record the relevant column number. * * It should be set to zero for an image header or pixel list. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::colnum is changed. * * int *colax * (Given, auxiliary) Address of the first element of an array of int * recording the column numbers for each axis in a pixel list. * * The array elements should be set to zero for an image header or image * array in a binary table. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::colax is changed. * * char (*cname)[72] * (Given, auxiliary) The address of the first element of an array of * char[72] containing the coordinate axis names, CNAMEia. * * These variables accomodate the longest allowed string-valued FITS * keyword, being limited to 68 characters, plus the null-terminating * character. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::cname is changed. * * double *crder * (Given, auxiliary) Address of the first element of an array of double * recording the random error in the coordinate value, CRDERia. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::crder is changed. * * double *csyer * (Given, auxiliary) Address of the first element of an array of double * recording the systematic error in the coordinate value, CSYERia. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::csyer is changed. * * double *czphs * (Given, auxiliary) Address of the first element of an array of double * recording the time at the zero point of a phase axis, CZPHSia. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::czphs is changed. * * double *cperi * (Given, auxiliary) Address of the first element of an array of double * recording the period of a phase axis, CPERIia. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::cperi is changed. * * char wcsname[72] * (Given, auxiliary) The name given to the coordinate representation, * WCSNAMEa. This variable accomodates the longest allowed string-valued * FITS keyword, being limited to 68 characters, plus the null-terminating * character. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::wcsname is changed. * * char timesys[72] * (Given, auxiliary) TIMESYS keyvalue, being the time scale (UTC, TAI, * etc.) in which all other time-related auxiliary header values are * recorded. Also defines the time scale for an image axis with CTYPEia * set to 'TIME'. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::timesys is changed. * * char trefpos[72] * (Given, auxiliary) TREFPOS keyvalue, being the location in space where * the recorded time is valid. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::trefpos is changed. * * char trefdir[72] * (Given, auxiliary) TREFDIR keyvalue, being the reference direction used * in calculating a pathlength delay. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::trefdir is changed. * * char plephem[72] * (Given, auxiliary) PLEPHEM keyvalue, being the Solar System ephemeris * used for calculating a pathlength delay. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::plephem is changed. * * char timeunit[72] * (Given, auxiliary) TIMEUNIT keyvalue, being the time units in which * the following header values are expressed: TSTART, TSTOP, TIMEOFFS, * TIMSYER, TIMRDER, TIMEDEL. It also provides the default value for * CUNITia for time axes. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::timeunit is changed. * * char dateref[72] * (Given, auxiliary) DATEREF keyvalue, being the date of a reference epoch * relative to which other time measurements refer. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::dateref is changed. * * double mjdref[2] * (Given, auxiliary) MJDREF keyvalue, equivalent to DATEREF expressed as * a Modified Julian Date (MJD = JD - 2400000.5). The value is given as * the sum of the two-element vector, allowing increased precision. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::mjdref is changed. * * double timeoffs * (Given, auxiliary) TIMEOFFS keyvalue, being a time offset, which may be * used, for example, to provide a uniform clock correction for times * referenced to DATEREF. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::timeoffs is changed. * * char dateobs[72] * (Given, auxiliary) DATE-OBS keyvalue, being the date at the start of the * observation unless otherwise explained in the DATE-OBS keycomment, in * ISO format, yyyy-mm-ddThh:mm:ss. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::dateobs is changed. * * char datebeg[72] * (Given, auxiliary) DATE-BEG keyvalue, being the date at the start of the * observation in ISO format, yyyy-mm-ddThh:mm:ss. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::datebeg is changed. * * char dateavg[72] * (Given, auxiliary) DATE-AVG keyvalue, being the date at a representative * mid-point of the observation in ISO format, yyyy-mm-ddThh:mm:ss. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::dateavg is changed. * * char dateend[72] * (Given, auxiliary) DATE-END keyvalue, baing the date at the end of the * observation in ISO format, yyyy-mm-ddThh:mm:ss. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::dateend is changed. * * double mjdobs * (Given, auxiliary) MJD-OBS keyvalue, equivalent to DATE-OBS expressed * as a Modified Julian Date (MJD = JD - 2400000.5). * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::mjdobs is changed. * * double mjdbeg * (Given, auxiliary) MJD-BEG keyvalue, equivalent to DATE-BEG expressed * as a Modified Julian Date (MJD = JD - 2400000.5). * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::mjdbeg is changed. * * double mjdavg * (Given, auxiliary) MJD-AVG keyvalue, equivalent to DATE-AVG expressed * as a Modified Julian Date (MJD = JD - 2400000.5). * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::mjdavg is changed. * * double mjdend * (Given, auxiliary) MJD-END keyvalue, equivalent to DATE-END expressed * as a Modified Julian Date (MJD = JD - 2400000.5). * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::mjdend is changed. * * double jepoch * (Given, auxiliary) JEPOCH keyvalue, equivalent to DATE-OBS expressed * as a Julian epoch. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::jepoch is changed. * * double bepoch * (Given, auxiliary) BEPOCH keyvalue, equivalent to DATE-OBS expressed * as a Besselian epoch * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::bepoch is changed. * * double tstart * (Given, auxiliary) TSTART keyvalue, equivalent to DATE-BEG expressed * as a time in units of TIMEUNIT relative to DATEREF+TIMEOFFS. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::tstart is changed. * * double tstop * (Given, auxiliary) TSTOP keyvalue, equivalent to DATE-END expressed * as a time in units of TIMEUNIT relative to DATEREF+TIMEOFFS. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::tstop is changed. * * double xposure * (Given, auxiliary) XPOSURE keyvalue, being the effective exposure time * in units of TIMEUNIT. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::xposure is changed. * * double telapse * (Given, auxiliary) TELAPSE keyvalue, equivalent to the elapsed time * between DATE-BEG and DATE-END, in units of TIMEUNIT. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::telapse is changed. * * double timsyer * (Given, auxiliary) TIMSYER keyvalue, being the absolute error of the * time values, in units of TIMEUNIT. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::timsyer is changed. * * double timrder * (Given, auxiliary) TIMRDER keyvalue, being the accuracy of time stamps * relative to each other, in units of TIMEUNIT. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::timrder is changed. * * double timedel * (Given, auxiliary) TIMEDEL keyvalue, being the resolution of the time * stamps. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::timedel is changed. * * double timepixr * (Given, auxiliary) TIMEPIXR keyvalue, being the relative position of the * time stamps in binned time intervals, a value between 0.0 and 1.0. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::timepixr is changed. * * double obsgeo[6] * (Given, auxiliary) Location of the observer in a standard terrestrial * reference frame. The first three give ITRS Cartesian coordinates * OBSGEO-X [m], OBSGEO-Y [m], OBSGEO-Z [m], and the second three give * OBSGEO-L [deg], OBSGEO-B [deg], OBSGEO-H [m], which are related through * a standard transformation. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::obsgeo is changed. * * char obsorbit[72] * (Given, auxiliary) OBSORBIT keyvalue, being the URI, URL, or name of an * orbit ephemeris file giving spacecraft coordinates relating to TREFPOS. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::obsorbit is changed. * * char radesys[72] * (Given, auxiliary) The equatorial or ecliptic coordinate system type, * RADESYSa. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::radesys is changed. * * double equinox * (Given, auxiliary) The equinox associated with dynamical equatorial or * ecliptic coordinate systems, EQUINOXa (or EPOCH in older headers). Not * applicable to ICRS equatorial or ecliptic coordinates. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::equinox is changed. * * char specsys[72] * (Given, auxiliary) Spectral reference frame (standard of rest), * SPECSYSa. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::specsys is changed. * * char ssysobs[72] * (Given, auxiliary) The spectral reference frame in which there is no * differential variation in the spectral coordinate across the * field-of-view, SSYSOBSa. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::ssysobs is changed. * * double velosys * (Given, auxiliary) The relative radial velocity [m/s] between the * observer and the selected standard of rest in the direction of the * celestial reference coordinate, VELOSYSa. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::velosys is changed. * * double zsource * (Given, auxiliary) The redshift, ZSOURCEa, of the source. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::zsource is changed. * * char ssyssrc[72] * (Given, auxiliary) The spectral reference frame (standard of rest), * SSYSSRCa, in which wcsprm::zsource was measured. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::ssyssrc is changed. * * double velangl * (Given, auxiliary) The angle [deg] that should be used to decompose an * observed velocity into radial and transverse components. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::velangl is changed. * * struct auxprm *aux * (Given, auxiliary) This struct holds auxiliary coordinate system * information of a specialist nature. While these parameters may be * widely recognized within particular fields of astronomy, they differ * from the above auxiliary parameters in not being defined by any of the * FITS WCS standards. Collecting them together in a separate struct that * is allocated only when required helps to control bloat in the size of * the wcsprm struct. * * int ntab * (Given) See wcsprm::tab. * * int nwtb * (Given) See wcsprm::wtb. * * struct tabprm *tab * (Given) Address of the first element of an array of ntab tabprm structs * for which memory has been allocated. These are used to store tabular * transformation parameters. * * Although technically wcsprm::ntab and tab are "given", they will * normally be set by invoking wcstab(), whether directly or indirectly. * * The tabprm structs contain some members that must be supplied and others * that are derived. The information to be supplied comes primarily from * arrays stored in one or more FITS binary table extensions. These * arrays, referred to here as "wcstab arrays", are themselves located by * parameters stored in the FITS image header. * * struct wtbarr *wtb * (Given) Address of the first element of an array of nwtb wtbarr structs * for which memory has been allocated. These are used in extracting * wcstab arrays from a FITS binary table. * * Although technically wcsprm::nwtb and wtb are "given", they will * normally be set by invoking wcstab(), whether directly or indirectly. * * char lngtyp[8] * (Returned) Four-character WCS celestial longitude and ... * char lattyp[8] * (Returned) ... latitude axis types. e.g. "RA", "DEC", "GLON", "GLAT", * etc. extracted from 'RA--', 'DEC-', 'GLON', 'GLAT', etc. in the first * four characters of CTYPEia but with trailing dashes removed. (Declared * as char[8] for alignment reasons.) * * int lng * (Returned) Index for the longitude coordinate, and ... * int lat * (Returned) ... index for the latitude coordinate, and ... * int spec * (Returned) ... index for the spectral coordinate in the imgcrd[][] and * world[][] arrays in the API of wcsp2s(), wcss2p() and wcsmix(). * * These may also serve as indices into the pixcrd[][] array provided that * the PCi_ja matrix does not transpose axes. * * int cubeface * (Returned) Index into the pixcrd[][] array for the CUBEFACE axis. This * is used for quadcube projections where the cube faces are stored on a * separate axis (see wcs.h). * * int *types * (Returned) Address of the first element of an array of int containing a * four-digit type code for each axis. * * - First digit (i.e. 1000s): * - 0: Non-specific coordinate type. * - 1: Stokes coordinate. * - 2: Celestial coordinate (including CUBEFACE). * - 3: Spectral coordinate. * * - Second digit (i.e. 100s): * - 0: Linear axis. * - 1: Quantized axis (STOKES, CUBEFACE). * - 2: Non-linear celestial axis. * - 3: Non-linear spectral axis. * - 4: Logarithmic axis. * - 5: Tabular axis. * * - Third digit (i.e. 10s): * - 0: Group number, e.g. lookup table number, being an index into the * tabprm array (see above). * * - The fourth digit is used as a qualifier depending on the axis type. * * - For celestial axes: * - 0: Longitude coordinate. * - 1: Latitude coordinate. * - 2: CUBEFACE number. * * - For lookup tables: the axis number in a multidimensional table. * * CTYPEia in "4-3" form with unrecognized algorithm code will have its * type set to -1 and generate an error. * * struct linprm lin * (Returned) Linear transformation parameters (usage is described in the * prologue to lin.h). * * struct celprm cel * (Returned) Celestial transformation parameters (usage is described in * the prologue to cel.h). * * struct spcprm spc * (Returned) Spectral transformation parameters (usage is described in the * prologue to spc.h). * * struct wcserr *err * (Returned) If enabled, when an error status is returned, this struct * contains detailed information about the error, see wcserr_enable(). * * int m_flag * (For internal use only.) * int m_naxis * (For internal use only.) * double *m_crpix * (For internal use only.) * double *m_pc * (For internal use only.) * double *m_cdelt * (For internal use only.) * double *m_crval * (For internal use only.) * char (*m_cunit)[72] * (For internal use only.) * char (*m_ctype)[72] * (For internal use only.) * struct pvcard *m_pv * (For internal use only.) * struct pscard *m_ps * (For internal use only.) * double *m_cd * (For internal use only.) * double *m_crota * (For internal use only.) * int *m_colax * (For internal use only.) * char (*m_cname)[72] * (For internal use only.) * double *m_crder * (For internal use only.) * double *m_csyer * (For internal use only.) * double *m_czphs * (For internal use only.) * double *m_cperi * (For internal use only.) * struct tabprm *m_tab * (For internal use only.) * struct wtbarr *m_wtb * (For internal use only.) * * * pvcard struct - Store for PVi_ma keyrecords * ------------------------------------------- * The pvcard struct is used to pass the parsed contents of PVi_ma keyrecords * to wcsset() via the wcsprm struct. * * All members of this struct are to be set by the user. * * int i * (Given) Axis number (1-relative), as in the FITS PVi_ma keyword. If * i == 0, wcsset() will replace it with the latitude axis number. * * int m * (Given) Parameter number (non-negative), as in the FITS PVi_ma keyword. * * double value * (Given) Parameter value. * * * pscard struct - Store for PSi_ma keyrecords * ------------------------------------------- * The pscard struct is used to pass the parsed contents of PSi_ma keyrecords * to wcsset() via the wcsprm struct. * * All members of this struct are to be set by the user. * * int i * (Given) Axis number (1-relative), as in the FITS PSi_ma keyword. * * int m * (Given) Parameter number (non-negative), as in the FITS PSi_ma keyword. * * char value[72] * (Given) Parameter value. * * * auxprm struct - Additional auxiliary parameters * ----------------------------------------------- * The auxprm struct holds auxiliary coordinate system information of a * specialist nature. It is anticipated that this struct will expand in future * to accomodate additional parameters. * * All members of this struct are to be set by the user. * * double rsun_ref * (Given, auxiliary) Reference radius of the Sun used in coordinate * calculations (m). * * double dsun_obs * (Given, auxiliary) Distance between the centre of the Sun and the * observer (m). * * double crln_obs * (Given, auxiliary) Carrington heliographic longitude of the observer * (deg). * * double hgln_obs * (Given, auxiliary) Stonyhurst heliographic longitude of the observer * (deg). * * double hglt_obs * (Given, auxiliary) Heliographic latitude (Carrington or Stonyhurst) of * the observer (deg). * * * Global variable: const char *wcs_errmsg[] - Status return messages * ------------------------------------------------------------------ * Error messages to match the status value returned from each function. * *===========================================================================*/ #ifndef WCSLIB_WCS #define WCSLIB_WCS #include "lin.h" #include "cel.h" #include "spc.h" #ifdef __cplusplus extern "C" { #define wtbarr wtbarr_s // See prologue of wtbarr.h. #endif #define WCSSUB_LONGITUDE 0x1001 #define WCSSUB_LATITUDE 0x1002 #define WCSSUB_CUBEFACE 0x1004 #define WCSSUB_CELESTIAL 0x1007 #define WCSSUB_SPECTRAL 0x1008 #define WCSSUB_STOKES 0x1010 #define WCSCOMPARE_ANCILLARY 0x0001 #define WCSCOMPARE_TILING 0x0002 #define WCSCOMPARE_CRPIX 0x0004 extern const char *wcs_errmsg[]; enum wcs_errmsg_enum { WCSERR_SUCCESS = 0, // Success. WCSERR_NULL_POINTER = 1, // Null wcsprm pointer passed. WCSERR_MEMORY = 2, // Memory allocation failed. WCSERR_SINGULAR_MTX = 3, // Linear transformation matrix is singular. WCSERR_BAD_CTYPE = 4, // Inconsistent or unrecognized coordinate // axis type. WCSERR_BAD_PARAM = 5, // Invalid parameter value. WCSERR_BAD_COORD_TRANS = 6, // Unrecognized coordinate transformation // parameter. WCSERR_ILL_COORD_TRANS = 7, // Ill-conditioned coordinate transformation // parameter. WCSERR_BAD_PIX = 8, // One or more of the pixel coordinates were // invalid. WCSERR_BAD_WORLD = 9, // One or more of the world coordinates were // invalid. WCSERR_BAD_WORLD_COORD = 10, // Invalid world coordinate. WCSERR_NO_SOLUTION = 11, // No solution found in the specified // interval. WCSERR_BAD_SUBIMAGE = 12, // Invalid subimage specification. WCSERR_NON_SEPARABLE = 13, // Non-separable subimage coordinate system. WCSERR_UNSET = 14 // wcsprm struct is unset. }; // Struct used for storing PVi_ma keywords. struct pvcard { int i; // Axis number, as in PVi_ma (1-relative). int m; // Parameter number, ditto (0-relative). double value; // Parameter value. }; // Size of the pvcard struct in int units, used by the Fortran wrappers. #define PVLEN (sizeof(struct pvcard)/sizeof(int)) // Struct used for storing PSi_ma keywords. struct pscard { int i; // Axis number, as in PSi_ma (1-relative). int m; // Parameter number, ditto (0-relative). char value[72]; // Parameter value. }; // Size of the pscard struct in int units, used by the Fortran wrappers. #define PSLEN (sizeof(struct pscard)/sizeof(int)) // Struct used to hold additional auxiliary parameters. struct auxprm { double rsun_ref; // Solar radius. double dsun_obs; // Distance from Sun centre to observer. double crln_obs; // Carrington heliographic lng of observer. double hgln_obs; // Stonyhurst heliographic lng of observer. double hglt_obs; // Heliographic latitude of observer. }; // Size of the auxprm struct in int units, used by the Fortran wrappers. #define AUXLEN (sizeof(struct auxprm)/sizeof(int)) struct wcsprm { // Initialization flag (see the prologue above). //-------------------------------------------------------------------------- int flag; // Set to zero to force initialization. // FITS header keyvalues to be provided (see the prologue above). //-------------------------------------------------------------------------- int naxis; // Number of axes (pixel and coordinate). double *crpix; // CRPIXja keyvalues for each pixel axis. double *pc; // PCi_ja linear transformation matrix. double *cdelt; // CDELTia keyvalues for each coord axis. double *crval; // CRVALia keyvalues for each coord axis. char (*cunit)[72]; // CUNITia keyvalues for each coord axis. char (*ctype)[72]; // CTYPEia keyvalues for each coord axis. double lonpole; // LONPOLEa keyvalue. double latpole; // LATPOLEa keyvalue. double restfrq; // RESTFRQa keyvalue. double restwav; // RESTWAVa keyvalue. int npv; // Number of PVi_ma keywords, and the int npvmax; // number for which space was allocated. struct pvcard *pv; // PVi_ma keywords for each i and m. int nps; // Number of PSi_ma keywords, and the int npsmax; // number for which space was allocated. struct pscard *ps; // PSi_ma keywords for each i and m. // Alternative header keyvalues (see the prologue above). //-------------------------------------------------------------------------- double *cd; // CDi_ja linear transformation matrix. double *crota; // CROTAi keyvalues for each coord axis. int altlin; // Alternative representations // Bit 0: PCi_ja is present, // Bit 1: CDi_ja is present, // Bit 2: CROTAi is present. int velref; // AIPS velocity code, VELREF. // Auxiliary coordinate system information of a general nature. Not // used by WCSLIB. Refer to the prologue comments above for a brief // explanation of these values. char alt[4]; int colnum; int *colax; // Auxiliary coordinate axis information. char (*cname)[72]; double *crder; double *csyer; double *czphs; double *cperi; char wcsname[72]; // Time reference system and measurement. char timesys[72], trefpos[72], trefdir[72], plephem[72]; char timeunit[72]; char dateref[72]; double mjdref[2]; double timeoffs; // Data timestamps and durations. char dateobs[72], datebeg[72], dateavg[72], dateend[72]; double mjdobs, mjdbeg, mjdavg, mjdend; double jepoch, bepoch; double tstart, tstop; double xposure, telapse; // Timing accuracy. double timsyer, timrder; double timedel, timepixr; // Spatial & celestial reference frame. double obsgeo[6]; char obsorbit[72]; char radesys[72]; double equinox; char specsys[72]; char ssysobs[72]; double velosys; double zsource; char ssyssrc[72]; double velangl; // Additional auxiliary coordinate system information of a specialist // nature. Not used by WCSLIB. Refer to the prologue comments above. struct auxprm *aux; // Coordinate lookup tables (see the prologue above). //-------------------------------------------------------------------------- int ntab; // Number of separate tables. int nwtb; // Number of wtbarr structs. struct tabprm *tab; // Tabular transformation parameters. struct wtbarr *wtb; // Array of wtbarr structs. //-------------------------------------------------------------------------- // Information derived from the FITS header keyvalues by wcsset(). //-------------------------------------------------------------------------- char lngtyp[8], lattyp[8]; // Celestial axis types, e.g. RA, DEC. int lng, lat, spec; // Longitude, latitude and spectral axis // indices (0-relative). int cubeface; // True if there is a CUBEFACE axis. int *types; // Coordinate type codes for each axis. struct linprm lin; // Linear transformation parameters. struct celprm cel; // Celestial transformation parameters. struct spcprm spc; // Spectral transformation parameters. //-------------------------------------------------------------------------- // THE REMAINDER OF THE WCSPRM STRUCT IS PRIVATE. //-------------------------------------------------------------------------- // Error handling, if enabled. //-------------------------------------------------------------------------- struct wcserr *err; // Memory management. //-------------------------------------------------------------------------- int m_flag, m_naxis; double *m_crpix, *m_pc, *m_cdelt, *m_crval; char (*m_cunit)[72], (*m_ctype)[72]; struct pvcard *m_pv; struct pscard *m_ps; double *m_cd, *m_crota; int *m_colax; char (*m_cname)[72]; double *m_crder, *m_csyer, *m_czphs, *m_cperi; struct auxprm *m_aux; struct tabprm *m_tab; struct wtbarr *m_wtb; }; // Size of the wcsprm struct in int units, used by the Fortran wrappers. #define WCSLEN (sizeof(struct wcsprm)/sizeof(int)) int wcsnpv(int n); int wcsnps(int n); int wcsini(int alloc, int naxis, struct wcsprm *wcs); int wcsinit(int alloc, int naxis, struct wcsprm *wcs, int npvmax, int npsmax, int ndpmax); int wcsauxi(int alloc, struct wcsprm *wcs); int wcssub(int alloc, const struct wcsprm *wcssrc, int *nsub, int axes[], struct wcsprm *wcsdst); int wcscompare(int cmp, double tol, const struct wcsprm *wcs1, const struct wcsprm *wcs2, int *equal); int wcsfree(struct wcsprm *wcs); int wcstrim(struct wcsprm *wcs); int wcssize(const struct wcsprm *wcs, int sizes[2]); int auxsize(const struct auxprm *aux, int sizes[2]); int wcsprt(const struct wcsprm *wcs); int wcsperr(const struct wcsprm *wcs, const char *prefix); int wcsbchk(struct wcsprm *wcs, int bounds); int wcsset(struct wcsprm *wcs); int wcsp2s(struct wcsprm *wcs, int ncoord, int nelem, const double pixcrd[], double imgcrd[], double phi[], double theta[], double world[], int stat[]); int wcss2p(struct wcsprm *wcs, int ncoord, int nelem, const double world[], double phi[], double theta[], double imgcrd[], double pixcrd[], int stat[]); int wcsmix(struct wcsprm *wcs, int mixpix, int mixcel, const double vspan[2], double vstep, int viter, double world[], double phi[], double theta[], double imgcrd[], double pixcrd[]); int wcsccs(struct wcsprm *wcs, double lng2p1, double lat2p1, double lng1p2, const char *clng, const char *clat, const char *radesys, double equinox, const char *alt); int wcssptr(struct wcsprm *wcs, int *i, char ctype[9]); const char* wcslib_version(int vers[3]); // Defined mainly for backwards compatibility, use wcssub() instead. #define wcscopy(alloc, wcssrc, wcsdst) wcssub(alloc, wcssrc, 0x0, 0x0, wcsdst) // Deprecated. #define wcsini_errmsg wcs_errmsg #define wcssub_errmsg wcs_errmsg #define wcscopy_errmsg wcs_errmsg #define wcsfree_errmsg wcs_errmsg #define wcsprt_errmsg wcs_errmsg #define wcsset_errmsg wcs_errmsg #define wcsp2s_errmsg wcs_errmsg #define wcss2p_errmsg wcs_errmsg #define wcsmix_errmsg wcs_errmsg #ifdef __cplusplus #undef wtbarr } #endif #endif // WCSLIB_WCS ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921587.0 astropy-5.0.2/astropy/wcs/include/wcslib/wcserr.h0000644000175100001710000002312300000000000021127 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. Module author: Michael Droettboom http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcserr.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * Summary of the wcserr routines * ------------------------------ * Most of the structs in WCSLIB contain a pointer to a wcserr struct as a * member. Functions in WCSLIB that return an error status code can also * allocate and set a detailed error message in this struct, which also * identifies the function, source file, and line number where the error * occurred. * * For example: * = struct prjprm prj; = wcserr_enable(1); = if (prjini(&prj)) { = // Print the error message to stderr. = wcsprintf_set(stderr); = wcserr_prt(prj.err, 0x0); = } * * A number of utility functions used in managing the wcserr struct are for * internal use only. They are documented here solely as an aid to * understanding the code. They are not intended for external use - the API * may change without notice! * * * wcserr struct - Error message handling * -------------------------------------- * The wcserr struct contains the numeric error code, a textual description of * the error, and information about the function, source file, and line number * where the error was generated. * * int status * Numeric status code associated with the error, the meaning of which * depends on the function that generated it. See the documentation for * the particular function. * * int line_no * Line number where the error occurred as given by the __LINE__ * preprocessor macro. * * const char *function * Name of the function where the error occurred. * * const char *file * Name of the source file where the error occurred as given by the * __FILE__ preprocessor macro. * * char *msg * Informative error message. * * * wcserr_enable() - Enable/disable error messaging * ------------------------------------------------ * wcserr_enable() enables or disables wcserr error messaging. By default it * is disabled. * * PLEASE NOTE: This function is not thread-safe. * * Given: * enable int If true (non-zero), enable error messaging, else * disable it. * * Function return value: * int Status return value: * 0: Error messaging is disabled. * 1: Error messaging is enabled. * * * wcserr_size() - Compute the size of a wcserr struct * --------------------------------------------------- * wcserr_size() computes the full size of a wcserr struct, including allocated * memory. * * Given: * err const struct wcserr* * The error object. * * If NULL, the base size of the struct and the allocated * size are both set to zero. * * Returned: * sizes int[2] The first element is the base size of the struct as * returned by sizeof(struct wcserr). The second element * is the total allocated size of the message buffer, in * bytes. * * Function return value: * int Status return value: * 0: Success. * * * wcserr_prt() - Print a wcserr struct * ------------------------------------ * wcserr_prt() prints the error message (if any) contained in a wcserr struct. * It uses the wcsprintf() functions. * * Given: * err const struct wcserr* * The error object. If NULL, nothing is printed. * * prefix const char * * If non-NULL, each output line will be prefixed with * this string. * * Function return value: * int Status return value: * 0: Success. * 2: Error messaging is not enabled. * * * wcserr_clear() - Clear a wcserr struct * -------------------------------------- * wcserr_clear() clears (deletes) a wcserr struct. * * Given and returned: * err struct wcserr** * The error object. If NULL, nothing is done. Set to * NULL on return. * * Function return value: * int Status return value: * 0: Success. * * * wcserr_set() - Fill in the contents of an error object * ------------------------------------------------------ * INTERNAL USE ONLY. * * wcserr_set() fills a wcserr struct with information about an error. * * A convenience macro, WCSERR_SET, provides the source file and line number * information automatically. * * Given and returned: * err struct wcserr** * Error object. * * If err is NULL, returns the status code given without * setting an error message. * * If *err is NULL, allocates memory for a wcserr struct * (provided that status is non-zero). * * Given: * status int Numeric status code to set. If 0, then *err will be * deleted and *err will be returned as NULL. * * function const char * * Name of the function generating the error. This * must point to a constant string, i.e. in the * initialized read-only data section ("data") of the * executable. * * file const char * * Name of the source file generating the error. This * must point to a constant string, i.e. in the * initialized read-only data section ("data") of the * executable such as given by the __FILE__ preprocessor * macro. * * line_no int Line number in the source file generating the error * such as given by the __LINE__ preprocessor macro. * * format const char * * Format string of the error message. May contain * printf-style %-formatting codes. * * ... mixed The remaining variable arguments are applied (like * printf) to the format string to generate the error * message. * * Function return value: * int The status return code passed in. * * * wcserr_copy() - Copy an error object * ------------------------------------ * INTERNAL USE ONLY. * * wcserr_copy() copies one error object to another. Use of this function * should be avoided in general since the function, source file, and line * number information copied to the destination may lose its context. * * Given: * src const struct wcserr* * Source error object. If src is NULL, dst is cleared. * * Returned: * dst struct wcserr* * Destination error object. If NULL, no copy is made. * * Function return value: * int Numeric status code of the source error object. * * * WCSERR_SET() macro - Fill in the contents of an error object * ------------------------------------------------------------ * INTERNAL USE ONLY. * * WCSERR_SET() is a preprocessor macro that helps to fill in the argument list * of wcserr_set(). It takes status as an argument of its own and provides the * name of the source file and the line number at the point where invoked. It * assumes that the err and function arguments of wcserr_set() will be provided * by variables of the same names. * *===========================================================================*/ #ifndef WCSLIB_WCSERR #define WCSLIB_WCSERR #ifdef __cplusplus extern "C" { #endif struct wcserr { int status; // Status code for the error. int line_no; // Line number where the error occurred. const char *function; // Function name. const char *file; // Source file name. char *msg; // Informative error message. }; // Size of the wcserr struct in int units, used by the Fortran wrappers. #define ERRLEN (sizeof(struct wcserr)/sizeof(int)) int wcserr_enable(int enable); int wcserr_size(const struct wcserr *err, int sizes[2]); int wcserr_prt(const struct wcserr *err, const char *prefix); int wcserr_clear(struct wcserr **err); // INTERNAL USE ONLY ------------------------------------------------------- int wcserr_set(struct wcserr **err, int status, const char *function, const char *file, int line_no, const char *format, ...); int wcserr_copy(const struct wcserr *src, struct wcserr *dst); // Convenience macro for invoking wcserr_set(). #define WCSERR_SET(status) err, status, function, __FILE__, __LINE__ #ifdef __cplusplus } #endif #endif // WSCLIB_WCSERR ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921587.0 astropy-5.0.2/astropy/wcs/include/wcslib/wcsmath.h0000644000175100001710000000366100000000000021275 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcsmath.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of wcsmath.h * -------------------- * Definition of mathematical constants used by WCSLIB. * *===========================================================================*/ #ifndef WCSLIB_WCSMATH #define WCSLIB_WCSMATH #ifdef PI #undef PI #endif #ifdef D2R #undef D2R #endif #ifdef R2D #undef R2D #endif #ifdef SQRT2 #undef SQRT2 #endif #ifdef SQRT2INV #undef SQRT2INV #endif #define PI 3.141592653589793238462643 #define D2R PI/180.0 #define R2D 180.0/PI #define SQRT2 1.4142135623730950488 #define SQRT2INV 1.0/SQRT2 #ifdef UNDEFINED #undef UNDEFINED #endif #define UNDEFINED 987654321.0e99 #define undefined(value) (value == UNDEFINED) #endif // WCSLIB_WCSMATH ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921587.0 astropy-5.0.2/astropy/wcs/include/wcslib/wcsprintf.h0000644000175100001710000001364600000000000021652 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcsprintf.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the wcsprintf routines * --------------------------------- * Routines in this suite allow diagnostic output from celprt(), linprt(), * prjprt(), spcprt(), tabprt(), wcsprt(), and wcserr_prt() to be redirected to * a file or captured in a string buffer. Those routines all use wcsprintf() * for output. Likewise wcsfprintf() is used by wcsbth() and wcspih(). Both * functions may be used by application programmers to have other output go to * the same place. * * * wcsprintf() - Print function used by WCSLIB diagnostic routines * --------------------------------------------------------------- * wcsprintf() is used by celprt(), linprt(), prjprt(), spcprt(), tabprt(), * wcsprt(), and wcserr_prt() for diagnostic output which by default goes to * stdout. However, it may be redirected to a file or string buffer via * wcsprintf_set(). * * Given: * format char* Format string, passed to one of the printf(3) family * of stdio library functions. * * ... mixed Argument list matching format, as per printf(3). * * Function return value: * int Number of bytes written. * * * wcsfprintf() - Print function used by WCSLIB diagnostic routines * ---------------------------------------------------------------- * wcsfprintf() is used by wcsbth(), and wcspih() for diagnostic output which * they send to stderr. However, it may be redirected to a file or string * buffer via wcsprintf_set(). * * Given: * stream FILE* The output stream if not overridden by a call to * wcsprintf_set(). * * format char* Format string, passed to one of the printf(3) family * of stdio library functions. * * ... mixed Argument list matching format, as per printf(3). * * Function return value: * int Number of bytes written. * * * wcsprintf_set() - Set output disposition for wcsprintf() and wcsfprintf() * ------------------------------------------------------------------------- * wcsprintf_set() sets the output disposition for wcsprintf() which is used by * the celprt(), linprt(), prjprt(), spcprt(), tabprt(), wcsprt(), and * wcserr_prt() routines, and for wcsfprintf() which is used by wcsbth() and * wcspih(). * * Given: * wcsout FILE* Pointer to an output stream that has been opened for * writing, e.g. by the fopen() stdio library function, * or one of the predefined stdio output streams - stdout * and stderr. If zero (NULL), output is written to an * internally-allocated string buffer, the address of * which may be obtained by wcsprintf_buf(). * * Function return value: * int Status return value: * 0: Success. * * * wcsprintf_buf() - Get the address of the internal string buffer * --------------------------------------------------------------- * wcsprintf_buf() returns the address of the internal string buffer created * when wcsprintf_set() is invoked with its FILE* argument set to zero. * * Function return value: * const char * * Address of the internal string buffer. The user may * free this buffer by calling wcsprintf_set() with a * valid FILE*, e.g. stdout. The free() stdlib library * function must NOT be invoked on this const pointer. * * * WCSPRINTF_PTR() macro - Print addresses in a consistent way * ----------------------------------------------------------- * WCSPRINTF_PTR() is a preprocessor macro used to print addresses in a * consistent way. * * On some systems the "%p" format descriptor renders a NULL pointer as the * string "0x0". On others, however, it produces "0" or even "(nil)". On * some systems a non-zero address is prefixed with "0x", on others, not. * * The WCSPRINTF_PTR() macro ensures that a NULL pointer is always rendered as * "0x0" and that non-zero addresses are prefixed with "0x" thus providing * consistency, for example, for comparing the output of test programs. * *===========================================================================*/ #ifndef WCSLIB_WCSPRINTF #define WCSLIB_WCSPRINTF #include #include #ifdef __cplusplus extern "C" { #endif #define WCSPRINTF_PTR(str1, ptr, str2) \ if (ptr) { \ wcsprintf("%s%#" PRIxPTR "%s", (str1), (uintptr_t)(ptr), (str2)); \ } else { \ wcsprintf("%s0x0%s", (str1), (str2)); \ } int wcsprintf_set(FILE *wcsout); int wcsprintf(const char *format, ...); int wcsfprintf(FILE *stream, const char *format, ...); const char *wcsprintf_buf(void); #ifdef __cplusplus } #endif #endif // WCSLIB_WCSPRINTF ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/setup_package.py0000644000175100001710000002264100000000000017734 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import io import os from os.path import join import os.path import shutil import sys from collections import defaultdict from setuptools import Extension from setuptools.dep_util import newer_group import numpy from extension_helpers import import_file, write_if_different, get_compiler, pkg_config WCSROOT = os.path.relpath(os.path.dirname(__file__)) WCSVERSION = "7.7" def b(s): return s.encode('ascii') def string_escape(s): s = s.decode('ascii').encode('ascii', 'backslashreplace') s = s.replace(b'\n', b'\\n') s = s.replace(b'\0', b'\\0') return s.decode('ascii') def determine_64_bit_int(): """ The only configuration parameter needed at compile-time is how to specify a 64-bit signed integer. Python's ctypes module can get us that information. If we can't be absolutely certain, we default to "long long int", which is correct on most platforms (x86, x86_64). If we find platforms where this heuristic doesn't work, we may need to hardcode for them. """ try: try: import ctypes except ImportError: raise ValueError() if ctypes.sizeof(ctypes.c_longlong) == 8: return "long long int" elif ctypes.sizeof(ctypes.c_long) == 8: return "long int" elif ctypes.sizeof(ctypes.c_int) == 8: return "int" else: raise ValueError() except ValueError: return "long long int" def write_wcsconfig_h(paths): """ Writes out the wcsconfig.h header with local configuration. """ h_file = io.StringIO() h_file.write(""" /* The bundled version has WCSLIB_VERSION */ #define HAVE_WCSLIB_VERSION 1 /* WCSLIB library version number. */ #define WCSLIB_VERSION {} /* 64-bit integer data type. */ #define WCSLIB_INT64 {} /* Windows needs some other defines to prevent inclusion of wcsset() which conflicts with wcslib's wcsset(). These need to be set on code that *uses* astropy.wcs, in addition to astropy.wcs itself. */ #if defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) || defined (__MINGW64__) #ifndef YY_NO_UNISTD_H #define YY_NO_UNISTD_H #endif #ifndef _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #endif #ifndef _NO_OLDNAMES #define _NO_OLDNAMES #endif #ifndef NO_OLDNAMES #define NO_OLDNAMES #endif #ifndef __STDC__ #define __STDC__ 1 #endif #endif """.format(WCSVERSION, determine_64_bit_int())) content = h_file.getvalue().encode('ascii') for path in paths: write_if_different(path, content) ###################################################################### # GENERATE DOCSTRINGS IN C def generate_c_docstrings(): docstrings = import_file(os.path.join(WCSROOT, 'docstrings.py')) docstrings = docstrings.__dict__ keys = [ key for key, val in docstrings.items() if not key.startswith('__') and isinstance(val, str)] keys.sort() docs = {} for key in keys: docs[key] = docstrings[key].encode('utf8').lstrip() + b'\0' h_file = io.StringIO() h_file.write("""/* DO NOT EDIT! This file is autogenerated by astropy/wcs/setup_package.py. To edit its contents, edit astropy/wcs/docstrings.py */ #ifndef __DOCSTRINGS_H__ #define __DOCSTRINGS_H__ """) for key in keys: val = docs[key] h_file.write(f'extern char doc_{key}[{len(val)}];\n') h_file.write("\n#endif\n\n") write_if_different( join(WCSROOT, 'include', 'astropy_wcs', 'docstrings.h'), h_file.getvalue().encode('utf-8')) c_file = io.StringIO() c_file.write("""/* DO NOT EDIT! This file is autogenerated by astropy/wcs/setup_package.py. To edit its contents, edit astropy/wcs/docstrings.py The weirdness here with strncpy is because some C compilers, notably MSVC, do not support string literals greater than 256 characters. */ #include #include "astropy_wcs/docstrings.h" """) for key in keys: val = docs[key] c_file.write(f'char doc_{key}[{len(val)}] = {{\n') for i in range(0, len(val), 12): section = val[i:i+12] c_file.write(' ') c_file.write(''.join(f'0x{x:02x}, ' for x in section)) c_file.write('\n') c_file.write(" };\n\n") write_if_different( join(WCSROOT, 'src', 'docstrings.c'), c_file.getvalue().encode('utf-8')) def get_wcslib_cfg(cfg, wcslib_files, include_paths): debug = '--debug' in sys.argv cfg['include_dirs'].append(numpy.get_include()) cfg['define_macros'].extend([ ('ECHO', None), ('WCSTRIG_MACRO', None), ('ASTROPY_WCS_BUILD', None), ('_GNU_SOURCE', None)]) if ((int(os.environ.get('ASTROPY_USE_SYSTEM_WCSLIB', 0)) or int(os.environ.get('ASTROPY_USE_SYSTEM_ALL', 0))) and not sys.platform == 'win32'): wcsconfig_h_path = join(WCSROOT, 'include', 'wcsconfig.h') if os.path.exists(wcsconfig_h_path): os.unlink(wcsconfig_h_path) for k, v in pkg_config(['wcslib'], ['wcs']).items(): cfg[k].extend(v) else: write_wcsconfig_h(include_paths) wcslib_path = join("cextern", "wcslib") # Path to wcslib wcslib_cpath = join(wcslib_path, "C") # Path to wcslib source files cfg['sources'].extend(join(wcslib_cpath, x) for x in wcslib_files) cfg['include_dirs'].append(wcslib_cpath) if debug: cfg['define_macros'].append(('DEBUG', None)) cfg['undef_macros'].append('NDEBUG') if (not sys.platform.startswith('sun') and not sys.platform == 'win32'): cfg['extra_compile_args'].extend(["-fno-inline", "-O0", "-g"]) else: # Define ECHO as nothing to prevent spurious newlines from # printing within the libwcs parser cfg['define_macros'].append(('NDEBUG', None)) cfg['undef_macros'].append('DEBUG') if sys.platform == 'win32': # These are written into wcsconfig.h, but that file is not # used by all parts of wcslib. cfg['define_macros'].extend([ ('YY_NO_UNISTD_H', None), ('_CRT_SECURE_NO_WARNINGS', None), ('_NO_OLDNAMES', None), # for mingw32 ('NO_OLDNAMES', None), # for mingw64 ('__STDC__', None) # for MSVC ]) if sys.platform.startswith('linux'): cfg['define_macros'].append(('HAVE_SINCOS', None)) # For 4.7+ enable C99 syntax in older compilers (need 'gnu99' std for gcc) if get_compiler() == 'unix': cfg['extra_compile_args'].extend(['-std=gnu99']) # Squelch a few compilation warnings in WCSLIB if get_compiler() in ('unix', 'mingw32'): if not debug: cfg['extra_compile_args'].extend([ '-Wno-strict-prototypes', '-Wno-unused-function', '-Wno-unused-value', '-Wno-uninitialized']) def get_extensions(): generate_c_docstrings() ###################################################################### # DISTUTILS SETUP cfg = defaultdict(list) wcslib_files = [ # List of wcslib files to compile 'flexed/wcsbth.c', 'flexed/wcspih.c', 'flexed/wcsulex.c', 'flexed/wcsutrn.c', 'cel.c', 'dis.c', 'lin.c', 'log.c', 'prj.c', 'spc.c', 'sph.c', 'spx.c', 'tab.c', 'wcs.c', 'wcserr.c', 'wcsfix.c', 'wcshdr.c', 'wcsprintf.c', 'wcsunits.c', 'wcsutil.c' ] wcslib_config_paths = [ join(WCSROOT, 'include', 'astropy_wcs', 'wcsconfig.h'), join(WCSROOT, 'include', 'wcsconfig.h') ] get_wcslib_cfg(cfg, wcslib_files, wcslib_config_paths) cfg['include_dirs'].append(join(WCSROOT, "include")) astropy_wcs_files = [ # List of astropy.wcs files to compile 'distortion.c', 'distortion_wrap.c', 'docstrings.c', 'pipeline.c', 'pyutil.c', 'astropy_wcs.c', 'astropy_wcs_api.c', 'sip.c', 'sip_wrap.c', 'str_list_proxy.c', 'unit_list_proxy.c', 'util.c', 'wcslib_wrap.c', 'wcslib_auxprm_wrap.c', 'wcslib_tabprm_wrap.c', 'wcslib_wtbarr_wrap.c' ] cfg['sources'].extend(join(WCSROOT, 'src', x) for x in astropy_wcs_files) cfg['sources'] = [str(x) for x in cfg['sources']] cfg = dict((str(key), val) for key, val in cfg.items()) # Copy over header files from WCSLIB into the installed version of Astropy # so that other Python packages can write extensions that link to it. We # do the copying here then include the data in [options.package_data] in # the setup.cfg file wcslib_headers = [ 'cel.h', 'lin.h', 'prj.h', 'spc.h', 'spx.h', 'tab.h', 'wcs.h', 'wcserr.h', 'wcsmath.h', 'wcsprintf.h', ] if not (int(os.environ.get('ASTROPY_USE_SYSTEM_WCSLIB', 0)) or int(os.environ.get('ASTROPY_USE_SYSTEM_ALL', 0))): for header in wcslib_headers: source = join('cextern', 'wcslib', 'C', header) dest = join('astropy', 'wcs', 'include', 'wcslib', header) if newer_group([source], dest, 'newer'): shutil.copy(source, dest) return [Extension('astropy.wcs._wcs', **cfg)] ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2312572 astropy-5.0.2/astropy/wcs/src/0000755000175100001710000000000000000000000015331 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/src/.gitignore0000644000175100001710000000015400000000000017321 0ustar00vstsdocker# Don't ignore *.c files in this directory tree. We don't have any # Cython files here. !*.c docstrings.c ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/src/astropy_wcs.c0000644000175100001710000005506100000000000020061 0ustar00vstsdocker/* Author: Michael Droettboom mdroe@stsci.edu */ #include "astropy_wcs/astropy_wcs.h" #include "astropy_wcs/wcslib_wrap.h" #include "astropy_wcs/wcslib_tabprm_wrap.h" #include "astropy_wcs/wcslib_auxprm_wrap.h" #include "astropy_wcs/wcslib_units_wrap.h" #include "astropy_wcs/wcslib_wtbarr_wrap.h" #include "astropy_wcs/distortion_wrap.h" #include "astropy_wcs/sip_wrap.h" #include "astropy_wcs/docstrings.h" #include "astropy_wcs/astropy_wcs_api.h" #include "astropy_wcs/unit_list_proxy.h" #include /* from Python */ #include #include #include #include /*************************************************************************** * Wcs type ***************************************************************************/ static PyTypeObject WcsType; static int _setup_wcs_type(PyObject* m); PyObject* PyWcsprm_set_wtbarr_fitsio_callback(PyObject *dummy, PyObject *args) { PyObject *callback; if (PyArg_ParseTuple(args, "O:set_wtbarr_fitsio_callback", &callback)) { if (!PyCallable_Check(callback)) { PyErr_SetString(PyExc_TypeError, "parameter must be callable"); return NULL; } _set_wtbarr_callback(callback); Py_RETURN_NONE; } return NULL; } /*************************************************************************** * PyWcs methods */ static int Wcs_traverse( Wcs* self, visitproc visit, void* arg) { Py_VISIT(self->py_det2im[0]); Py_VISIT(self->py_det2im[1]); Py_VISIT(self->py_sip); Py_VISIT(self->py_distortion_lookup[0]); Py_VISIT(self->py_distortion_lookup[1]); Py_VISIT(self->py_wcsprm); return 0; } static int Wcs_clear( Wcs* self) { Py_CLEAR(self->py_det2im[0]); Py_CLEAR(self->py_det2im[1]); Py_CLEAR(self->py_sip); Py_CLEAR(self->py_distortion_lookup[0]); Py_CLEAR(self->py_distortion_lookup[1]); Py_CLEAR(self->py_wcsprm); return 0; } static void Wcs_dealloc( Wcs* self) { PyObject_GC_UnTrack(self); Wcs_clear(self); pipeline_free(&self->x); Py_TYPE(self)->tp_free((PyObject*)self); } /*@null@*/ static PyObject * Wcs_new( PyTypeObject* type, /*@unused@*/ PyObject* args, /*@unused@*/ PyObject* kwds) { Wcs* self; self = (Wcs*)type->tp_alloc(type, 0); if (self != NULL) { pipeline_clear(&self->x); self->py_det2im[0] = NULL; self->py_det2im[1] = NULL; self->py_sip = NULL; self->py_distortion_lookup[0] = NULL; self->py_distortion_lookup[1] = NULL; self->py_wcsprm = NULL; } return (PyObject*)self; } static int Wcs_init( Wcs* self, PyObject* args, /*@unused@*/ PyObject* kwds) { size_t i; PyObject* py_sip; PyObject* py_wcsprm; PyObject* py_distortion_lookup[2]; PyObject* py_det2im[2]; if (!PyArg_ParseTuple (args, "O(OO)O(OO):Wcs.__init__", &py_sip, &py_distortion_lookup[0], &py_distortion_lookup[1], &py_wcsprm, &py_det2im[0], &py_det2im[1])) { return -1; } /* Check and set Distortion lookup tables */ for (i = 0; i < 2; ++i) { if (py_det2im[i] != NULL && py_det2im[i] != Py_None) { if (!PyObject_TypeCheck(py_det2im[i], &PyDistLookupType)) { PyErr_SetString(PyExc_TypeError, "Arg 4 must be a pair of DistortionLookupTable or None objects"); return -1; } Py_CLEAR(self->py_det2im[i]); self->py_det2im[i] = py_det2im[i]; Py_INCREF(py_det2im[i]); self->x.det2im[i] = &(((PyDistLookup*)py_det2im[i])->x); } } /* Check and set SIP */ if (py_sip != NULL && py_sip != Py_None) { if (!PyObject_TypeCheck(py_sip, &PySipType)) { PyErr_SetString(PyExc_TypeError, "Arg 1 must be Sip object"); return -1; } Py_CLEAR(self->py_sip); self->py_sip = py_sip; Py_INCREF(py_sip); self->x.sip = &(((PySip*)py_sip)->x); } /* Check and set Distortion lookup tables */ for (i = 0; i < 2; ++i) { if (py_distortion_lookup[i] != NULL && py_distortion_lookup[i] != Py_None) { if (!PyObject_TypeCheck(py_distortion_lookup[i], &PyDistLookupType)) { PyErr_SetString(PyExc_TypeError, "Arg 2 must be a pair of DistortionLookupTable or None objects"); return -1; } Py_CLEAR(self->py_distortion_lookup[i]); self->py_distortion_lookup[i] = py_distortion_lookup[i]; Py_INCREF(py_distortion_lookup[i]); self->x.cpdis[i] = &(((PyDistLookup*)py_distortion_lookup[i])->x); } } /* Set and lookup Wcsprm object */ if (py_wcsprm != NULL && py_wcsprm != Py_None) { if (!PyObject_TypeCheck(py_wcsprm, &PyWcsprmType)) { PyErr_SetString(PyExc_TypeError, "Arg 3 must be Wcsprm object"); return -1; } Py_CLEAR(self->py_wcsprm); self->py_wcsprm = py_wcsprm; Py_INCREF(py_wcsprm); self->x.wcs = &(((PyWcsprm*)py_wcsprm)->x); } return 0; } /*@null@*/ static PyObject* Wcs_all_pix2world( Wcs* self, PyObject* args, PyObject* kwds) { int naxis = 2; PyObject* pixcrd_obj = NULL; int origin = 1; PyArrayObject* pixcrd = NULL; PyArrayObject* world = NULL; int status = -1; const char* keywords[] = { "pixcrd", "origin", NULL }; if (!PyArg_ParseTupleAndKeywords( args, kwds, "Oi:all_pix2world", (char **)keywords, &pixcrd_obj, &origin)) { return NULL; } naxis = self->x.wcs->naxis; pixcrd = (PyArrayObject*)PyArray_ContiguousFromAny(pixcrd_obj, NPY_DOUBLE, 2, 2); if (pixcrd == NULL) { return NULL; } if (PyArray_DIM(pixcrd, 1) < naxis) { PyErr_Format( PyExc_RuntimeError, "Input array must be 2-dimensional, where the second dimension >= %d", naxis); goto exit; } world = (PyArrayObject*)PyArray_SimpleNew(2, PyArray_DIMS(pixcrd), NPY_DOUBLE); if (world == NULL) { goto exit; } /* Make the call */ Py_BEGIN_ALLOW_THREADS preoffset_array(pixcrd, origin); wcsprm_python2c(self->x.wcs); status = pipeline_all_pixel2world(&self->x, (unsigned int)PyArray_DIM(pixcrd, 0), (unsigned int)PyArray_DIM(pixcrd, 1), (double*)PyArray_DATA(pixcrd), (double*)PyArray_DATA(world)); wcsprm_c2python(self->x.wcs); unoffset_array(pixcrd, origin); Py_END_ALLOW_THREADS /* unoffset_array(world, origin); */ exit: Py_XDECREF(pixcrd); if (status == 0 || status == 8) { return (PyObject*)world; } else { Py_XDECREF(world); if (status == -1) { PyErr_SetString( PyExc_ValueError, "Wrong number of dimensions in input array. Expected 2."); return NULL; } else { if (status == -1) { /* exception already set */ return NULL; } else { wcserr_to_python_exc(self->x.err); return NULL; } } } } /*@null@*/ static PyObject* Wcs_p4_pix2foc( Wcs* self, PyObject* args, PyObject* kwds) { PyObject* pixcrd_obj = NULL; int origin = 1; PyArrayObject* pixcrd = NULL; PyArrayObject* foccrd = NULL; int status = -1; const char* keywords[] = { "pixcrd", "origin", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oi:p4_pix2foc", (char **)keywords, &pixcrd_obj, &origin)) { return NULL; } if (self->x.cpdis[0] == NULL && self->x.cpdis[1] == NULL) { Py_INCREF(pixcrd_obj); return pixcrd_obj; } pixcrd = (PyArrayObject*)PyArray_ContiguousFromAny(pixcrd_obj, NPY_DOUBLE, 2, 2); if (pixcrd == NULL) { return NULL; } if (PyArray_DIM(pixcrd, 1) != NAXES) { PyErr_SetString(PyExc_ValueError, "Pixel array must be an Nx2 array"); goto exit; } foccrd = (PyArrayObject*)PyArray_SimpleNew(2, PyArray_DIMS(pixcrd), NPY_DOUBLE); if (foccrd == NULL) { status = 2; goto exit; } Py_BEGIN_ALLOW_THREADS preoffset_array(pixcrd, origin); status = p4_pix2foc(2, (void *)self->x.cpdis, (unsigned int)PyArray_DIM(pixcrd, 0), (double*)PyArray_DATA(pixcrd), (double*)PyArray_DATA(foccrd)); unoffset_array(pixcrd, origin); unoffset_array(foccrd, origin); Py_END_ALLOW_THREADS exit: Py_XDECREF(pixcrd); if (status == 0) { return (PyObject*)foccrd; } else { Py_XDECREF(foccrd); if (status == -1) { /* Exception already set */ return NULL; } else { PyErr_SetString(PyExc_MemoryError, "NULL pointer passed"); return NULL; } } } /*@null@*/ static PyObject* Wcs_det2im( Wcs* self, PyObject* args, PyObject* kwds) { PyObject* detcrd_obj = NULL; int origin = 1; PyArrayObject* detcrd = NULL; PyArrayObject* imcrd = NULL; int status = -1; const char* keywords[] = { "detcrd", "origin", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oi:det2im", (char **)keywords, &detcrd_obj, &origin)) { return NULL; } if (self->x.det2im[0] == NULL && self->x.det2im[1] == NULL) { Py_INCREF(detcrd_obj); return detcrd_obj; } detcrd = (PyArrayObject*)PyArray_ContiguousFromAny(detcrd_obj, NPY_DOUBLE, 2, 2); if (detcrd == NULL) { return NULL; } if (PyArray_DIM(detcrd, 1) != NAXES) { PyErr_SetString(PyExc_ValueError, "Pixel array must be an Nx2 array"); goto exit; } imcrd = (PyArrayObject*)PyArray_SimpleNew(2, PyArray_DIMS(detcrd), NPY_DOUBLE); if (imcrd == NULL) { status = 2; goto exit; } Py_BEGIN_ALLOW_THREADS preoffset_array(detcrd, origin); status = p4_pix2foc(2, (void *)self->x.det2im, (unsigned int)PyArray_DIM(detcrd, 0), (double*)PyArray_DATA(detcrd), (double*)PyArray_DATA(imcrd)); unoffset_array(detcrd, origin); unoffset_array(imcrd, origin); Py_END_ALLOW_THREADS exit: Py_XDECREF(detcrd); if (status == 0) { return (PyObject*)imcrd; } else { Py_XDECREF(imcrd); if (status == -1) { /* Exception already set */ return NULL; } else { PyErr_SetString(PyExc_MemoryError, "NULL pointer passed"); return NULL; } } } /*@null@*/ static PyObject* Wcs_pix2foc( Wcs* self, PyObject* args, PyObject* kwds) { PyObject* pixcrd_obj = NULL; int origin = 1; PyArrayObject* pixcrd = NULL; PyArrayObject* foccrd = NULL; int status = -1; const char* keywords[] = { "pixcrd", "origin", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oi:pix2foc", (char **)keywords, &pixcrd_obj, &origin)) { return NULL; } pixcrd = (PyArrayObject*)PyArray_ContiguousFromAny(pixcrd_obj, NPY_DOUBLE, 2, 2); if (pixcrd == NULL) { return NULL; } if (PyArray_DIM(pixcrd, 1) != NAXES) { PyErr_SetString(PyExc_ValueError, "Pixel array must be an Nx2 array"); goto _exit; } foccrd = (PyArrayObject*)PyArray_SimpleNew(2, PyArray_DIMS(pixcrd), NPY_DOUBLE); if (foccrd == NULL) { goto _exit; } Py_BEGIN_ALLOW_THREADS preoffset_array(pixcrd, origin); status = pipeline_pix2foc(&self->x, (unsigned int)PyArray_DIM(pixcrd, 0), (unsigned int)PyArray_DIM(pixcrd, 1), (double*)PyArray_DATA(pixcrd), (double*)PyArray_DATA(foccrd)); unoffset_array(pixcrd, origin); unoffset_array(foccrd, origin); Py_END_ALLOW_THREADS _exit: Py_XDECREF(pixcrd); if (status == 0) { return (PyObject*)foccrd; } else { Py_XDECREF(foccrd); if (status == -1) { /* Exception already set */ return NULL; } else { wcserr_to_python_exc(self->x.err); return NULL; } } } /*@null@*/ static PyObject* Wcs_get_wcs( Wcs* self, /*@unused@*/ void* closure) { if (self->py_wcsprm) { Py_INCREF(self->py_wcsprm); return self->py_wcsprm; } Py_INCREF(Py_None); return Py_None; } static int Wcs_set_wcs( Wcs* self, /*@shared@*/ PyObject* value, /*@unused@*/ void* closure) { Py_CLEAR(self->py_wcsprm); self->x.wcs = NULL; if (value != NULL && value != Py_None) { if (!PyObject_TypeCheck(value, &PyWcsprmType)) { PyErr_SetString(PyExc_TypeError, "wcs must be Wcsprm object"); return -1; } Py_INCREF(value); self->py_wcsprm = value; self->x.wcs = &(((PyWcsprm*)value)->x); } return 0; } static PyObject* Wcs_get_cpdis1( Wcs* self, /*@unused@*/ void* closure) { if (self->py_distortion_lookup[0]) { Py_INCREF(self->py_distortion_lookup[0]); return self->py_distortion_lookup[0]; } Py_INCREF(Py_None); return Py_None; } static int Wcs_set_cpdis1( Wcs* self, /*@shared@*/ PyObject* value, /*@unused@*/ void* closure) { Py_CLEAR(self->py_distortion_lookup[0]); self->x.cpdis[0] = NULL; if (value != NULL && value != Py_None) { if (!PyObject_TypeCheck(value, &PyDistLookupType)) { PyErr_SetString(PyExc_TypeError, "cpdis1 must be DistortionLookupTable object"); return -1; } Py_INCREF(value); self->py_distortion_lookup[0] = value; self->x.cpdis[0] = &(((PyDistLookup*)value)->x); } return 0; } /*@shared@*/ static PyObject* Wcs_get_cpdis2( Wcs* self, /*@unused@*/ void* closure) { if (self->py_distortion_lookup[1]) { Py_INCREF(self->py_distortion_lookup[1]); return self->py_distortion_lookup[1]; } Py_INCREF(Py_None); return Py_None; } static int Wcs_set_cpdis2( Wcs* self, /*@shared@*/ PyObject* value, /*@unused@*/ void* closure) { Py_CLEAR(self->py_distortion_lookup[1]); self->x.cpdis[1] = NULL; if (value != NULL && value != Py_None) { if (!PyObject_TypeCheck(value, &PyDistLookupType)) { PyErr_SetString(PyExc_TypeError, "cpdis2 must be DistortionLookupTable object"); return -1; } Py_INCREF(value); self->py_distortion_lookup[1] = value; self->x.cpdis[1] = &(((PyDistLookup*)value)->x); } return 0; } static PyObject* Wcs_get_det2im1( Wcs* self, /*@unused@*/ void* closure) { if (self->py_det2im[0]) { Py_INCREF(self->py_det2im[0]); return self->py_det2im[0]; } Py_INCREF(Py_None); return Py_None; } static int Wcs_set_det2im1( Wcs* self, /*@shared@*/ PyObject* value, /*@unused@*/ void* closure) { Py_CLEAR(self->py_det2im[0]); self->x.det2im[0] = NULL; if (value != NULL && value != Py_None) { if (!PyObject_TypeCheck(value, &PyDistLookupType)) { PyErr_SetString(PyExc_TypeError, "det2im1 must be DistortionLookupTable object"); return -1; } Py_INCREF(value); self->py_det2im[0] = value; self->x.det2im[0] = &(((PyDistLookup*)value)->x); } return 0; } /*@shared@*/ static PyObject* Wcs_get_det2im2( Wcs* self, /*@unused@*/ void* closure) { if (self->py_det2im[1]) { Py_INCREF(self->py_det2im[1]); return self->py_det2im[1]; } Py_INCREF(Py_None); return Py_None; } static int Wcs_set_det2im2( Wcs* self, /*@shared@*/ PyObject* value, /*@unused@*/ void* closure) { Py_CLEAR(self->py_det2im[1]); self->x.det2im[1] = NULL; if (value != NULL && value != Py_None) { if (!PyObject_TypeCheck(value, &PyDistLookupType)) { PyErr_SetString(PyExc_TypeError, "det2im2 must be DistortionLookupTable object"); return -1; } Py_INCREF(value); self->py_det2im[1] = value; self->x.det2im[1] = &(((PyDistLookup*)value)->x); } return 0; } /*@shared@*/ static PyObject* Wcs_get_sip( Wcs* self, /*@unused@*/ void* closure) { if (self->py_sip) { Py_INCREF(self->py_sip); return self->py_sip; } Py_INCREF(Py_None); return Py_None; } static int Wcs_set_sip( Wcs* self, /*@shared@*/ PyObject* value, /*@unused@*/ void* closure) { Py_CLEAR(self->py_sip); self->x.sip = NULL; if (value != NULL && value != Py_None) { if (!PyObject_TypeCheck(value, &PySipType)) { PyErr_SetString(PyExc_TypeError, "sip must be Sip object"); return -1; } Py_INCREF(value); self->py_sip = value; self->x.sip = &(((PySip*)value)->x); } return 0; } static PyObject* _sanity_check( PyObject* self, PyObject* args, PyObject* kwds) { if (sizeof(WCSLIB_INT64) != 8) { Py_INCREF(Py_False); return Py_False; } Py_INCREF(Py_True); return Py_True; } /*************************************************************************** * Wcs definition structures */ static PyGetSetDef Wcs_getset[] = { {"det2im1", (getter)Wcs_get_det2im1, (setter)Wcs_set_det2im1, (char *)doc_det2im1}, {"det2im2", (getter)Wcs_get_det2im2, (setter)Wcs_set_det2im2, (char *)doc_det2im2}, {"cpdis1", (getter)Wcs_get_cpdis1, (setter)Wcs_set_cpdis1, (char *)doc_cpdis1}, {"cpdis2", (getter)Wcs_get_cpdis2, (setter)Wcs_set_cpdis2, (char *)doc_cpdis2}, {"sip", (getter)Wcs_get_sip, (setter)Wcs_set_sip, (char *)doc_sip}, {"wcs", (getter)Wcs_get_wcs, (setter)Wcs_set_wcs, (char *)doc_wcs}, {NULL} }; static PyMethodDef Wcs_methods[] = { {"_all_pix2world", (PyCFunction)Wcs_all_pix2world, METH_VARARGS|METH_KEYWORDS, doc_all_pix2world}, {"_det2im", (PyCFunction)Wcs_det2im, METH_VARARGS|METH_KEYWORDS, doc_det2im}, {"_p4_pix2foc", (PyCFunction)Wcs_p4_pix2foc, METH_VARARGS|METH_KEYWORDS, doc_p4_pix2foc}, {"_pix2foc", (PyCFunction)Wcs_pix2foc, METH_VARARGS|METH_KEYWORDS, doc_pix2foc}, {NULL} }; static PyMethodDef module_methods[] = { {"_sanity_check", (PyCFunction)_sanity_check, METH_NOARGS, ""}, {"find_all_wcs", (PyCFunction)PyWcsprm_find_all_wcs, METH_VARARGS|METH_KEYWORDS, doc_find_all_wcs}, {"set_wtbarr_fitsio_callback", (PyCFunction)PyWcsprm_set_wtbarr_fitsio_callback, METH_VARARGS, NULL}, {NULL} /* Sentinel */ }; static PyTypeObject WcsType = { PyVarObject_HEAD_INIT(NULL, 0) "astropy.wcs.WCSBase", /*tp_name*/ sizeof(Wcs), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)Wcs_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash */ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ doc_Wcs, /* tp_doc */ (traverseproc)Wcs_traverse, /* tp_traverse */ (inquiry)Wcs_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ Wcs_methods, /* tp_methods */ 0, /* tp_members */ Wcs_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)Wcs_init, /* tp_init */ 0, /* tp_alloc */ Wcs_new, /* tp_new */ }; /*************************************************************************** * Module-level ***************************************************************************/ int _setup_wcs_type( PyObject* m) { if (PyType_Ready(&WcsType) < 0) return -1; Py_INCREF(&WcsType); return PyModule_AddObject(m, "_Wcs", (PyObject *)&WcsType); } struct module_state { /* The Sun compiler can't handle empty structs */ #if defined(__SUNPRO_C) || defined(_MSC_VER) int _dummy; #endif }; static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, "_wcs", NULL, sizeof(struct module_state), module_methods, NULL, NULL, NULL, NULL }; PyMODINIT_FUNC PyInit__wcs(void) { PyObject* m; wcs_errexc[0] = NULL; /* Success */ wcs_errexc[1] = &PyExc_MemoryError; /* Null wcsprm pointer passed */ wcs_errexc[2] = &PyExc_MemoryError; /* Memory allocation failed */ wcs_errexc[3] = &WcsExc_SingularMatrix; /* Linear transformation matrix is singular */ wcs_errexc[4] = &WcsExc_InconsistentAxisTypes; /* Inconsistent or unrecognized coordinate axis types */ wcs_errexc[5] = &PyExc_ValueError; /* Invalid parameter value */ wcs_errexc[6] = &WcsExc_InvalidTransform; /* Invalid coordinate transformation parameters */ wcs_errexc[7] = &WcsExc_InvalidTransform; /* Ill-conditioned coordinate transformation parameters */ wcs_errexc[8] = &WcsExc_InvalidCoordinate; /* One or more of the pixel coordinates were invalid, */ /* as indicated by the stat vector */ wcs_errexc[9] = &WcsExc_InvalidCoordinate; /* One or more of the world coordinates were invalid, */ /* as indicated by the stat vector */ wcs_errexc[10] = &WcsExc_InvalidCoordinate; /* Invalid world coordinate */ wcs_errexc[11] = &WcsExc_NoSolution; /* no solution found in the specified interval */ wcs_errexc[12] = &WcsExc_InvalidSubimageSpecification; /* Invalid subimage specification (no spectral axis) */ wcs_errexc[13] = &WcsExc_NonseparableSubimageCoordinateSystem; /* Non-separable subimage coordinate system */ m = PyModule_Create(&moduledef); if (m == NULL) return NULL; import_array(); if (_setup_api(m) || _setup_str_list_proxy_type(m) || _setup_unit_list_proxy_type(m)|| _setup_wcsprm_type(m) || _setup_auxprm_type(m) || _setup_tabprm_type(m) || _setup_wtbarr_type(m) || _setup_distortion_type(m) || _setup_sip_type(m) || _setup_wcs_type(m) || _define_exceptions(m)) { Py_DECREF(m); return NULL; } #ifdef HAVE_WCSLIB_VERSION if (PyModule_AddStringConstant(m, "__version__", wcslib_version(NULL))) { return NULL; } #else if (PyModule_AddStringConstant(m, "__version__", "4.x")) { return NULL; } #endif return m; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/src/astropy_wcs_api.c0000644000175100001710000000253700000000000020712 0ustar00vstsdocker#define NO_IMPORT_ARRAY #include "astropy_wcs/astropy_wcs_api.h" int AstropyWcs_GetCVersion(void) { return REVISION; } void* AstropyWcs_API[] = { /* 0 */ (void *)AstropyWcs_GetCVersion, /* pyutil.h */ /* 1 */ (void *)wcsprm_python2c, /* 2 */ (void *)wcsprm_c2python, /* distortion.h */ /* 3 */ (void *)distortion_lookup_t_init, /* 4 */ (void *)distortion_lookup_t_free, /* 5 */ (void *)get_distortion_offset, /* 6 */ (void *)p4_pix2foc, /* 7 */ (void *)p4_pix2deltas, /* sip.h */ /* 8 */ (void *)sip_clear, /* 9 */ (void *)sip_init, /* 10 */ (void *)sip_free, /* 11 */ (void *)sip_pix2foc, /* 12 */ (void *)sip_pix2deltas, /* 13 */ (void *)sip_foc2pix, /* 14 */ (void *)sip_foc2deltas, /* pipeline.h */ /* 15 */ (void *)pipeline_clear, /* 16 */ (void *)pipeline_init, /* 17 */ (void *)pipeline_free, /* 18 */ (void *)pipeline_all_pixel2world, /* 19 */ (void *)pipeline_pix2foc, /* wcs.h */ /* 20 */ (void *)wcsp2s, /* 21 */ (void *)wcss2p, /* 22 */ (void *)wcsprt, /* new for api version 2 */ /* 23 */ (void *)wcslib_get_error_message, /* new for api version 3 */ /* 24 */ (void *)wcsprintf_buf }; int _setup_api(PyObject *m) { PyObject* c_api; c_api = PyCapsule_New((void *)AstropyWcs_API, "_wcs._ASTROPY_WCS_API", NULL); PyModule_AddObject(m, "_ASTROPY_WCS_API", c_api); return 0; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/src/distortion.c0000644000175100001710000001317700000000000017704 0ustar00vstsdocker/* Author: Michael Droettboom mdroe@stsci.edu */ #include "astropy_wcs/distortion.h" #include #include #include #include /* TODO: n-dimensional support */ int distortion_lookup_t_init( distortion_lookup_t* lookup) { unsigned int i; for (i = 0; i < NAXES; ++i) { lookup->naxis[i] = 0; lookup->crpix[i] = 0.0; lookup->crval[i] = 0.0; lookup->cdelt[i] = 1.0; } lookup->data = NULL; return 0; } void distortion_lookup_t_free( /*@unused@*/ distortion_lookup_t* lookup) { /*@empty@*/ } /** * Get a value at a specific integral location in the lookup table. * (This is nothing more special than an array lookup with range * checking.) */ static INLINE float get_dist_clamp( const float* const data, const unsigned int* const naxis, const int x, const int y) { return data[ ((naxis[0] * CLAMP(y, 0, (long)naxis[1] - 1)) + CLAMP(x, 0, (long)naxis[0] - 1))]; } static INLINE float get_dist( const float* const data, const unsigned int* const naxis, const int x, const int y) { return data[(naxis[0] * y) + x]; } /** * Converts a pixel coordinate to a fractional coordinate in the * lookup table on a single axis */ static INLINE double image_coord_to_distortion_coord( const distortion_lookup_t * const lookup, const unsigned int axis, const double img) { double result; assert(lookup != NULL); assert(axis < NAXES); /* The "- 1./stepsize" is here because the input coordinates are 1-based, but this is a C-array underneath */ result = ( ((img - lookup->crval[axis]) / lookup->cdelt[axis]) + lookup->crpix[axis]) - 1.0/lookup->cdelt[axis]; return CLAMP(result, 0.0, (double)(lookup->naxis[axis] - 1)); } /** * Converts a pixel coordinate to a fractional coordinate in the * lookup table. */ static INLINE void image_coords_to_distortion_coords( const distortion_lookup_t * const lookup, const double * const img /* [NAXES] */, /* Output parameters */ /*@out@*/ double *dist /* [NAXES] */) { unsigned int i; assert(lookup != NULL); assert(img != NULL); assert(dist != NULL); for (i = 0; i < NAXES; ++i) { dist[i] = image_coord_to_distortion_coord(lookup, i, img[i]); } } INLINE double get_distortion_offset( const distortion_lookup_t * const lookup, const double * const img /*[NAXES]*/) { double dist[NAXES]; double dist_floor[NAXES]; int dist_ifloor[NAXES]; double dist_weight[NAXES]; double dist_iweight[NAXES]; double result; const unsigned int* naxis = lookup->naxis; const float* data = lookup->data; unsigned int i; assert(lookup != NULL); assert(img != NULL); image_coords_to_distortion_coords(lookup, img, dist); for (i = 0; i < NAXES; ++i) { dist_floor[i] = floor(dist[i]); dist_ifloor[i] = (int)dist_floor[i]; dist_weight[i] = dist[i] - dist_floor[i]; dist_iweight[i] = 1.0 - dist_weight[i]; } /* If we may need to clamp the lookups, use this slower approach */ if (dist_ifloor[0] < 0 || dist_ifloor[1] < 0 || dist_ifloor[0] >= (long)lookup->naxis[0] - 1 || dist_ifloor[1] >= (long)lookup->naxis[1] - 1) { result = (double)get_dist_clamp(data, naxis, dist_ifloor[0], dist_ifloor[1]) * dist_iweight[0] * dist_iweight[1] + (double)get_dist_clamp(data, naxis, dist_ifloor[0], dist_ifloor[1] + 1) * dist_iweight[0] * dist_weight[1] + (double)get_dist_clamp(data, naxis, dist_ifloor[0] + 1, dist_ifloor[1]) * dist_weight[0] * dist_iweight[1] + (double)get_dist_clamp(data, naxis, dist_ifloor[0] + 1, dist_ifloor[1] + 1) * dist_weight[0] * dist_weight[1]; /* Else, we don't need to clamp 4 times for each pixel */ } else { result = (double)get_dist(data, naxis, dist_ifloor[0], dist_ifloor[1]) * dist_iweight[0] * dist_iweight[1] + (double)get_dist(data, naxis, dist_ifloor[0], dist_ifloor[1] + 1) * dist_iweight[0] * dist_weight[1] + (double)get_dist(data, naxis, dist_ifloor[0] + 1, dist_ifloor[1]) * dist_weight[0] * dist_iweight[1] + (double)get_dist(data, naxis, dist_ifloor[0] + 1, dist_ifloor[1] + 1) * dist_weight[0] * dist_weight[1]; } return result; } int p4_pix2deltas( const unsigned int naxes, const distortion_lookup_t **lookup, /* [NAXES] */ const unsigned int nelem, const double* pix, /* [NAXES][nelem] */ double *foc /* [NAXES][nelem] */) { int i; double* foc0; const double* pix0; const double* pixend; #ifndef NDEBUG unsigned int k; #endif assert(naxes == NAXES); assert(lookup != NULL); assert(pix != NULL); assert(foc != NULL); #ifndef NDEBUG for (k = 0; k < naxes; ++k) { if (lookup[k] != NULL) { assert(lookup[k]->data != NULL); } } #endif if (pix == NULL || foc == NULL) { return 1; } pixend = pix + nelem * NAXES; /* This can't be parallelized, because pix may be equal to foc */ /* For the same reason, i needs to be in the inner loop */ for (pix0 = pix, foc0 = foc; pix0 < pixend; pix0 += NAXES, foc0 += NAXES) { for (i = 0; i < NAXES; ++i) { if (lookup[i]) { foc0[i] += get_distortion_offset(lookup[i], pix0); } } } return 0; } int p4_pix2foc( const unsigned int naxes, const distortion_lookup_t **lookup, /* [NAXES] */ const unsigned int nelem, const double* pix, /* [NAXES][nelem] */ double *foc /* [NAXES][nelem] */) { assert(pix); assert(foc); if (pix != foc) { memcpy(foc, pix, sizeof(double) * naxes * nelem); } return p4_pix2deltas(naxes, lookup, nelem, pix, foc); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/src/distortion_wrap.c0000644000175100001710000002121200000000000020722 0ustar00vstsdocker/* Author: Michael Droettboom mdroe@stsci.edu */ #define NO_IMPORT_ARRAY #include "astropy_wcs/distortion_wrap.h" #include "astropy_wcs/docstrings.h" #include /* From Python */ static int PyDistLookup_traverse( PyDistLookup* self, visitproc visit, void* arg) { Py_VISIT(self->py_data); return 0; } static int PyDistLookup_clear( PyDistLookup* self) { Py_CLEAR(self->py_data); return 0; } static void PyDistLookup_dealloc( PyDistLookup* self) { PyObject_GC_UnTrack(self); distortion_lookup_t_free(&self->x); Py_XDECREF(self->py_data); Py_TYPE(self)->tp_free((PyObject*)self); } /*@null@*/ static PyObject * PyDistLookup_new( PyTypeObject* type, /*@unused@*/ PyObject* args, /*@unused@*/ PyObject* kwds) { PyDistLookup* self; self = (PyDistLookup*)type->tp_alloc(type, 0); if (self != NULL) { if (distortion_lookup_t_init(&self->x)) { return NULL; } self->py_data = NULL; } return (PyObject*)self; } static int PyDistLookup_init( PyDistLookup* self, PyObject* args, /*@unused@*/ PyObject* kwds) { PyObject* py_array_obj = NULL; PyArrayObject* array_obj = NULL; if (!PyArg_ParseTuple(args, "O(dd)(dd)(dd):DistortionLookupTable.__init__", &py_array_obj, &(self->x.crpix[0]), &(self->x.crpix[1]), &(self->x.crval[0]), &(self->x.crval[1]), &(self->x.cdelt[0]), &(self->x.cdelt[1]))) { return -1; } array_obj = (PyArrayObject*)PyArray_ContiguousFromAny(py_array_obj, NPY_FLOAT32, 2, 2); if (array_obj == NULL) { return -1; } self->py_data = array_obj; self->x.naxis[0] = (unsigned int)PyArray_DIM(array_obj, 1); self->x.naxis[1] = (unsigned int)PyArray_DIM(array_obj, 0); self->x.data = (float *)PyArray_DATA(array_obj); return 0; } static PyObject* PyDistLookup_get_cdelt( PyDistLookup* self, /*@unused@*/ void* closure) { Py_ssize_t naxis = 2; return get_double_array("cdelt", self->x.cdelt, 1, &naxis, (PyObject*)self); } static int PyDistLookup_set_cdelt( PyDistLookup* self, PyObject* value, /*@unused@*/ void* closure) { npy_intp naxis = 2; return set_double_array("cdelt", value, 1, &naxis, self->x.cdelt); } static PyObject* PyDistLookup_get_crpix( PyDistLookup* self, /*@unused@*/ void* closure) { Py_ssize_t naxis = 2; return get_double_array("crpix", self->x.crpix, 1, &naxis, (PyObject*)self); } static int PyDistLookup_set_crpix( PyDistLookup* self, PyObject* value, /*@unused@*/ void* closure) { npy_intp naxis = 2; return set_double_array("crpix", value, 1, &naxis, self->x.crpix); } static PyObject* PyDistLookup_get_crval( PyDistLookup* self, /*@unused@*/ void* closure) { Py_ssize_t naxis = 2; return get_double_array("crval", self->x.crval, 1, &naxis, (PyObject*)self); } static int PyDistLookup_set_crval( PyDistLookup* self, PyObject* value, /*@unused@*/ void* closure) { npy_intp naxis = 2; return set_double_array("crval", value, 1, &naxis, self->x.crval); } /*@shared@*/ static PyObject* PyDistLookup_get_data( PyDistLookup* self, /*@unused@*/ void* closure) { if (self->py_data == NULL) { Py_INCREF(Py_None); return Py_None; } else { Py_INCREF(self->py_data); return (PyObject*)self->py_data; } } static int PyDistLookup_set_data( PyDistLookup* self, PyObject* value, /*@unused@*/ void* closure) { PyArrayObject* value_array = NULL; if (value == NULL) { Py_CLEAR(self->py_data); self->x.data = NULL; return 0; } value_array = (PyArrayObject*)PyArray_ContiguousFromAny(value, NPY_FLOAT32, 2, 2); if (value_array == NULL) { return -1; } Py_XDECREF(self->py_data); self->py_data = value_array; self->x.naxis[0] = (unsigned int)PyArray_DIM(value_array, 1); self->x.naxis[1] = (unsigned int)PyArray_DIM(value_array, 0); self->x.data = (float *)PyArray_DATA(value_array); return 0; } /*@null@*/ static PyObject* PyDistLookup_get_offset( PyDistLookup* self, PyObject* args, /*@unused@*/ PyObject* kwds) { double coord[NAXES]; double result; if (self->x.data == NULL) { PyErr_SetString(PyExc_RuntimeError, "No data has been set for the lookup table"); return NULL; } if (!PyArg_ParseTuple(args, "dd:get_offset", &coord[0], &coord[1])) { return NULL; } result = get_distortion_offset(&self->x, coord); return PyFloat_FromDouble(result); } static PyObject* PyDistLookup___copy__( PyDistLookup* self, /*@unused@*/ PyObject* args, /*@unused@*/ PyObject* kwds) { PyDistLookup* copy = NULL; int i = 0; copy = (PyDistLookup*)PyDistLookup_new(&PyDistLookupType, NULL, NULL); if (copy == NULL) { return NULL; } for (i = 0; i < 2; ++i) { copy->x.naxis[i] = self->x.naxis[i]; copy->x.crpix[i] = self->x.crpix[i]; copy->x.crval[i] = self->x.crval[i]; copy->x.cdelt[i] = self->x.cdelt[i]; } if (self->py_data) { PyDistLookup_set_data(copy, (PyObject*)self->py_data, NULL); } return (PyObject*)copy; } static PyObject* PyDistLookup___deepcopy__( PyDistLookup* self, PyObject* memo, /*@unused@*/ PyObject* kwds) { PyDistLookup* copy; PyObject* obj_copy; int i = 0; copy = (PyDistLookup*)PyDistLookup_new(&PyDistLookupType, NULL, NULL); if (copy == NULL) { return NULL; } for (i = 0; i < 2; ++i) { copy->x.naxis[i] = self->x.naxis[i]; copy->x.crpix[i] = self->x.crpix[i]; copy->x.crval[i] = self->x.crval[i]; copy->x.cdelt[i] = self->x.cdelt[i]; } if (self->py_data) { obj_copy = get_deepcopy((PyObject*)self->py_data, memo); if (obj_copy == NULL) { Py_DECREF(copy); return NULL; } PyDistLookup_set_data(copy, (PyObject*)obj_copy, NULL); Py_DECREF(obj_copy); } return (PyObject*)copy; } static PyGetSetDef PyDistLookup_getset[] = { {"cdelt", (getter)PyDistLookup_get_cdelt, (setter)PyDistLookup_set_cdelt, (char *)doc_cdelt}, {"crpix", (getter)PyDistLookup_get_crpix, (setter)PyDistLookup_set_crpix, (char *)doc_crpix}, {"crval", (getter)PyDistLookup_get_crval, (setter)PyDistLookup_set_crval, (char *)doc_crval}, {"data", (getter)PyDistLookup_get_data, (setter)PyDistLookup_set_data, (char *)doc_data}, {NULL} }; static PyMethodDef PyDistLookup_methods[] = { {"__copy__", (PyCFunction)PyDistLookup___copy__, METH_NOARGS, NULL}, {"__deepcopy__", (PyCFunction)PyDistLookup___deepcopy__, METH_O, NULL}, {"get_offset", (PyCFunction)PyDistLookup_get_offset, METH_VARARGS, doc_get_offset}, {NULL} }; PyTypeObject PyDistLookupType = { PyVarObject_HEAD_INIT(NULL, 0) "astropy.wcs.DistortionLookupTable", /*tp_name*/ sizeof(PyDistLookup), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)PyDistLookup_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash */ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ doc_DistortionLookupTable, /* tp_doc */ (traverseproc)PyDistLookup_traverse, /* tp_traverse */ (inquiry)PyDistLookup_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ PyDistLookup_methods, /* tp_methods */ 0, /* tp_members */ PyDistLookup_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)PyDistLookup_init, /* tp_init */ 0, /* tp_alloc */ PyDistLookup_new, /* tp_new */ }; int _setup_distortion_type( PyObject* m) { if (PyType_Ready(&PyDistLookupType) < 0) { return -1; } Py_INCREF(&PyDistLookupType); return PyModule_AddObject(m, "DistortionLookupTable", (PyObject *)&PyDistLookupType); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921587.0 astropy-5.0.2/astropy/wcs/src/docstrings.c0000644000175100001710000147360100000000000017670 0ustar00vstsdocker/* DO NOT EDIT! This file is autogenerated by astropy/wcs/setup_package.py. To edit its contents, edit astropy/wcs/docstrings.py The weirdness here with strncpy is because some C compilers, notably MSVC, do not support string literals greater than 256 characters. */ #include #include "astropy_wcs/docstrings.h" char doc_Auxprm[198] = { 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x20, 0x61, 0x75, 0x78, 0x69, 0x6c, 0x69, 0x61, 0x72, 0x79, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x69, 0x73, 0x74, 0x0a, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x69, 0x73, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x65, 0x64, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6c, 0x79, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x50, 0x79, 0x74, 0x68, 0x6f, 0x6e, 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x65, 0x61, 0x64, 0x20, 0x69, 0x73, 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x61, 0x75, 0x78, 0x60, 0x2e, 0x0a, 0x00, }; char doc_DistortionLookupTable[371] = { 0x44, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x2a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2a, 0x2c, 0x20, 0x2a, 0x63, 0x72, 0x70, 0x69, 0x78, 0x2a, 0x2c, 0x20, 0x2a, 0x63, 0x72, 0x76, 0x61, 0x6c, 0x2a, 0x2c, 0x20, 0x2a, 0x63, 0x64, 0x65, 0x6c, 0x74, 0x2a, 0x29, 0x0a, 0x0a, 0x52, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x60, 0x64, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x70, 0x65, 0x72, 0x60, 0x5f, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x3a, 0x20, 0x32, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x64, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x0a, 0x0a, 0x63, 0x72, 0x70, 0x69, 0x78, 0x20, 0x3a, 0x20, 0x32, 0x2d, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x64, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x0a, 0x0a, 0x63, 0x72, 0x76, 0x61, 0x6c, 0x20, 0x3a, 0x20, 0x32, 0x2d, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x0a, 0x0a, 0x63, 0x64, 0x65, 0x6c, 0x74, 0x20, 0x3a, 0x20, 0x32, 0x2d, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x67, 0x72, 0x69, 0x64, 0x20, 0x73, 0x74, 0x65, 0x70, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x0a, 0x00, }; char doc_InconsistentAxisTypes[100] = { 0x49, 0x6e, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x41, 0x78, 0x69, 0x73, 0x54, 0x79, 0x70, 0x65, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x29, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x57, 0x43, 0x53, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x75, 0x6e, 0x72, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x74, 0x79, 0x70, 0x65, 0x28, 0x73, 0x29, 0x2e, 0x0a, 0x00, }; char doc_InvalidCoordinate[76] = { 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x29, 0x0a, 0x0a, 0x4f, 0x6e, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x2e, 0x0a, 0x00, }; char doc_InvalidSubimageSpecification[77] = { 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x53, 0x75, 0x62, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x29, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x73, 0x75, 0x62, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x2e, 0x0a, 0x00, }; char doc_InvalidTabularParameters[76] = { 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x61, 0x62, 0x75, 0x6c, 0x61, 0x72, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x29, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x74, 0x61, 0x62, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x2e, 0x0a, 0x00, }; char doc_InvalidTransform[107] = { 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x29, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x57, 0x43, 0x53, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, 0x61, 0x72, 0x65, 0x20, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x2e, 0x0a, 0x00, }; char doc_K[202] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x4d, 0x5d, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x78, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x0a, 0x61, 0x72, 0x72, 0x61, 0x79, 0x2e, 0x0a, 0x0a, 0x41, 0x6e, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x60, 0x4d, 0x60, 0x20, 0x77, 0x68, 0x6f, 0x73, 0x65, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x78, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x0a, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x0a, 0x00, }; char doc_M[56] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x61, 0x62, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x78, 0x65, 0x73, 0x2e, 0x0a, 0x00, }; char doc_NoSolution[68] = { 0x4e, 0x6f, 0x53, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x29, 0x0a, 0x0a, 0x4e, 0x6f, 0x20, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x2e, 0x0a, 0x00, }; char doc_NoWcsKeywordsFound[76] = { 0x4e, 0x6f, 0x57, 0x63, 0x73, 0x4b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x29, 0x0a, 0x0a, 0x4e, 0x6f, 0x20, 0x57, 0x43, 0x53, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x77, 0x65, 0x72, 0x65, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x0a, 0x00, }; char doc_NonseparableSubimageCoordinateSystem[88] = { 0x4e, 0x6f, 0x6e, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x62, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x29, 0x0a, 0x0a, 0x4e, 0x6f, 0x6e, 0x2d, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x75, 0x62, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x0a, 0x00, }; char doc_SingularMatrix[70] = { 0x53, 0x69, 0x6e, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x29, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x69, 0x73, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x2e, 0x0a, 0x00, }; char doc_Sip[1115] = { 0x53, 0x69, 0x70, 0x28, 0x2a, 0x61, 0x2c, 0x20, 0x62, 0x2c, 0x20, 0x61, 0x70, 0x2c, 0x20, 0x62, 0x70, 0x2c, 0x20, 0x63, 0x72, 0x70, 0x69, 0x78, 0x2a, 0x29, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x53, 0x69, 0x70, 0x60, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x20, 0x70, 0x6f, 0x6c, 0x79, 0x6e, 0x6f, 0x6d, 0x69, 0x61, 0x6c, 0x20, 0x64, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x53, 0x49, 0x50, 0x60, 0x5f, 0x20, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x62, 0x6f, 0x74, 0x68, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x20, 0x3a, 0x20, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x60, 0x60, 0x41, 0x5f, 0x69, 0x5f, 0x6a, 0x60, 0x60, 0x20, 0x70, 0x6f, 0x6c, 0x79, 0x6e, 0x6f, 0x6d, 0x69, 0x61, 0x6c, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6d, 0x2b, 0x31, 0x5d, 0x5b, 0x6d, 0x2b, 0x31, 0x5d, 0x60, 0x60, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x74, 0x73, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x28, 0x2a, 0x6d, 0x2a, 0x20, 0x2b, 0x20, 0x31, 0x2c, 0x20, 0x2a, 0x6d, 0x2a, 0x20, 0x2b, 0x20, 0x31, 0x29, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x2a, 0x6d, 0x2a, 0x20, 0x3d, 0x20, 0x60, 0x60, 0x41, 0x5f, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x62, 0x20, 0x3a, 0x20, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x60, 0x60, 0x42, 0x5f, 0x69, 0x5f, 0x6a, 0x60, 0x60, 0x20, 0x70, 0x6f, 0x6c, 0x79, 0x6e, 0x6f, 0x6d, 0x69, 0x61, 0x6c, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6d, 0x2b, 0x31, 0x5d, 0x5b, 0x6d, 0x2b, 0x31, 0x5d, 0x60, 0x60, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x74, 0x73, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x28, 0x2a, 0x6d, 0x2a, 0x20, 0x2b, 0x20, 0x31, 0x2c, 0x20, 0x2a, 0x6d, 0x2a, 0x20, 0x2b, 0x20, 0x31, 0x29, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x2a, 0x6d, 0x2a, 0x20, 0x3d, 0x20, 0x60, 0x60, 0x42, 0x5f, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x61, 0x70, 0x20, 0x3a, 0x20, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x60, 0x60, 0x41, 0x50, 0x5f, 0x69, 0x5f, 0x6a, 0x60, 0x60, 0x20, 0x70, 0x6f, 0x6c, 0x79, 0x6e, 0x6f, 0x6d, 0x69, 0x61, 0x6c, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6d, 0x2b, 0x31, 0x5d, 0x5b, 0x6d, 0x2b, 0x31, 0x5d, 0x60, 0x60, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x74, 0x73, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x28, 0x2a, 0x6d, 0x2a, 0x20, 0x2b, 0x20, 0x31, 0x2c, 0x20, 0x2a, 0x6d, 0x2a, 0x20, 0x2b, 0x20, 0x31, 0x29, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x2a, 0x6d, 0x2a, 0x20, 0x3d, 0x20, 0x60, 0x60, 0x41, 0x50, 0x5f, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x62, 0x70, 0x20, 0x3a, 0x20, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x60, 0x60, 0x42, 0x50, 0x5f, 0x69, 0x5f, 0x6a, 0x60, 0x60, 0x20, 0x70, 0x6f, 0x6c, 0x79, 0x6e, 0x6f, 0x6d, 0x69, 0x61, 0x6c, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6d, 0x2b, 0x31, 0x5d, 0x5b, 0x6d, 0x2b, 0x31, 0x5d, 0x60, 0x60, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x74, 0x73, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x28, 0x2a, 0x6d, 0x2a, 0x20, 0x2b, 0x20, 0x31, 0x2c, 0x20, 0x2a, 0x6d, 0x2a, 0x20, 0x2b, 0x20, 0x31, 0x29, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x2a, 0x6d, 0x2a, 0x20, 0x3d, 0x20, 0x60, 0x60, 0x42, 0x50, 0x5f, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x63, 0x72, 0x70, 0x69, 0x78, 0x20, 0x3a, 0x20, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x32, 0x5d, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x53, 0x68, 0x75, 0x70, 0x65, 0x2c, 0x20, 0x44, 0x2e, 0x20, 0x4c, 0x2e, 0x2c, 0x20, 0x4d, 0x2e, 0x20, 0x4d, 0x6f, 0x73, 0x68, 0x69, 0x72, 0x2c, 0x20, 0x4a, 0x2e, 0x20, 0x4c, 0x69, 0x2c, 0x20, 0x44, 0x2e, 0x20, 0x4d, 0x61, 0x6b, 0x6f, 0x76, 0x6f, 0x7a, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x52, 0x2e, 0x20, 0x4e, 0x61, 0x72, 0x72, 0x6f, 0x6e, 0x2e, 0x20, 0x20, 0x32, 0x30, 0x30, 0x35, 0x2e, 0x0a, 0x22, 0x54, 0x68, 0x65, 0x20, 0x53, 0x49, 0x50, 0x20, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x52, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x44, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x46, 0x49, 0x54, 0x53, 0x20, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x0a, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x2e, 0x22, 0x20, 0x20, 0x41, 0x44, 0x41, 0x53, 0x53, 0x20, 0x58, 0x49, 0x56, 0x2e, 0x0a, 0x00, }; char doc_Tabprm[234] = { 0x41, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x61, 0x62, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x2c, 0x0a, 0x69, 0x2e, 0x65, 0x2e, 0x2c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x61, 0x72, 0x65, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x76, 0x69, 0x61, 0x20, 0x61, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x69, 0x73, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x65, 0x64, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6c, 0x79, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x50, 0x79, 0x74, 0x68, 0x6f, 0x6e, 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x65, 0x61, 0x64, 0x20, 0x69, 0x73, 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x74, 0x61, 0x62, 0x60, 0x2e, 0x0a, 0x00, }; char doc_Wcs[463] = { 0x57, 0x63, 0x73, 0x28, 0x2a, 0x73, 0x69, 0x70, 0x2c, 0x20, 0x63, 0x70, 0x64, 0x69, 0x73, 0x2c, 0x20, 0x77, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2c, 0x20, 0x64, 0x65, 0x74, 0x32, 0x69, 0x6d, 0x2a, 0x29, 0x0a, 0x0a, 0x57, 0x63, 0x73, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x20, 0x61, 0x6d, 0x61, 0x6c, 0x67, 0x61, 0x6d, 0x61, 0x74, 0x65, 0x20, 0x62, 0x61, 0x73, 0x69, 0x63, 0x20, 0x57, 0x43, 0x53, 0x20, 0x28, 0x61, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x60, 0x77, 0x63, 0x73, 0x6c, 0x69, 0x62, 0x60, 0x5f, 0x29, 0x2c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x0a, 0x60, 0x53, 0x49, 0x50, 0x60, 0x5f, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x60, 0x64, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x70, 0x65, 0x72, 0x60, 0x5f, 0x20, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x0a, 0x0a, 0x54, 0x6f, 0x20, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x64, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x57, 0x43, 0x53, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x75, 0x73, 0x65, 0x0a, 0x60, 0x60, 0x61, 0x6c, 0x6c, 0x5f, 0x70, 0x69, 0x78, 0x32, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x73, 0x69, 0x70, 0x20, 0x3a, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x53, 0x69, 0x70, 0x60, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x4e, 0x6f, 0x6e, 0x65, 0x0a, 0x0a, 0x63, 0x70, 0x64, 0x69, 0x73, 0x20, 0x3a, 0x20, 0x28, 0x32, 0x2c, 0x29, 0x20, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x44, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x60, 0x20, 0x6f, 0x72, 0x20, 0x4e, 0x6f, 0x6e, 0x65, 0x0a, 0x0a, 0x77, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x20, 0x3a, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x60, 0x0a, 0x0a, 0x64, 0x65, 0x74, 0x32, 0x69, 0x6d, 0x20, 0x3a, 0x20, 0x28, 0x32, 0x2c, 0x29, 0x20, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x44, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x60, 0x20, 0x6f, 0x72, 0x20, 0x4e, 0x6f, 0x6e, 0x65, 0x0a, 0x00, }; char doc_WcsError[39] = { 0x42, 0x61, 0x73, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x57, 0x43, 0x53, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x0a, 0x00, }; char doc_Wcsprm[3022] = { 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x28, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x3d, 0x4e, 0x6f, 0x6e, 0x65, 0x2c, 0x20, 0x6b, 0x65, 0x79, 0x3d, 0x27, 0x20, 0x27, 0x2c, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x78, 0x3d, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x20, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x3d, 0x32, 0x2c, 0x20, 0x6b, 0x65, 0x79, 0x73, 0x65, 0x6c, 0x3d, 0x30, 0x2c, 0x20, 0x63, 0x6f, 0x6c, 0x73, 0x65, 0x6c, 0x3d, 0x4e, 0x6f, 0x6e, 0x65, 0x29, 0x0a, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x60, 0x20, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x72, 0x65, 0x20, 0x57, 0x43, 0x53, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x0a, 0x0a, 0x2e, 0x2e, 0x20, 0x6e, 0x6f, 0x74, 0x65, 0x3a, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x20, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x6c, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x69, 0x72, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, 0x49, 0x54, 0x53, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x20, 0x20, 0x48, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x79, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, 0x64, 0x6a, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x77, 0x61, 0x79, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x6d, 0x61, 0x6b, 0x65, 0x20, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x57, 0x43, 0x53, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x61, 0x73, 0x69, 0x65, 0x72, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x79, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x65, 0x6c, 0x69, 0x65, 0x64, 0x20, 0x75, 0x70, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x67, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x20, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x61, 0x74, 0x2c, 0x20, 0x75, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x60, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x66, 0x69, 0x74, 0x73, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x60, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6c, 0x79, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x46, 0x49, 0x54, 0x53, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x70, 0x61, 0x72, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x73, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20, 0x46, 0x49, 0x54, 0x53, 0x20, 0x22, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x20, 0x3d, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x20, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x0a, 0x77, 0x69, 0x74, 0x68, 0x20, 0x72, 0x65, 0x67, 0x61, 0x72, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x73, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x20, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x20, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x20, 0x39, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x31, 0x30, 0x2e, 0x0a, 0x48, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6f, 0x65, 0x73, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, 0x7a, 0x65, 0x20, 0x66, 0x72, 0x65, 0x65, 0x2d, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x20, 0x28, 0x4e, 0x4f, 0x53, 0x54, 0x20, 0x31, 0x30, 0x30, 0x2d, 0x32, 0x2e, 0x30, 0x2c, 0x0a, 0x53, 0x65, 0x63, 0x74, 0x2e, 0x20, 0x35, 0x2e, 0x32, 0x2e, 0x31, 0x29, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x20, 0x28, 0x53, 0x65, 0x63, 0x74, 0x2e, 0x20, 0x35, 0x2e, 0x32, 0x2e, 0x33, 0x29, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x2d, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x0a, 0x28, 0x53, 0x65, 0x63, 0x74, 0x2e, 0x20, 0x35, 0x2e, 0x32, 0x2e, 0x34, 0x29, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x2e, 0x0a, 0x0a, 0x0a, 0x2e, 0x2e, 0x20, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x61, 0x6e, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x6c, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x2e, 0x20, 0x20, 0x57, 0x68, 0x65, 0x6e, 0x20, 0x6e, 0x65, 0x65, 0x64, 0x65, 0x64, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x73, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x73, 0x65, 0x74, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x2c, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x6d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2c, 0x20, 0x6f, 0x6e, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x61, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x20, 0x73, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x72, 0x61, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x61, 0x20, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x74, 0x73, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x28, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x74, 0x73, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x76, 0x69, 0x64, 0x75, 0x61, 0x6c, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x20, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x6c, 0x65, 0x61, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x6e, 0x20, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x20, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x60, 0x60, 0x63, 0x72, 0x70, 0x69, 0x78, 0x60, 0x60, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x20, 0x32, 0x44, 0x20, 0x57, 0x43, 0x53, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x60, 0x60, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x60, 0x60, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x60, 0x60, 0x77, 0x63, 0x73, 0x60, 0x60, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x73, 0x65, 0x74, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x77, 0x63, 0x73, 0x2e, 0x63, 0x72, 0x70, 0x69, 0x78, 0x20, 0x3d, 0x20, 0x5b, 0x63, 0x72, 0x70, 0x69, 0x78, 0x31, 0x2c, 0x20, 0x63, 0x72, 0x70, 0x69, 0x78, 0x32, 0x5d, 0x60, 0x60, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x65, 0x61, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x60, 0x60, 0x77, 0x63, 0x73, 0x2e, 0x63, 0x72, 0x70, 0x69, 0x78, 0x5b, 0x30, 0x5d, 0x20, 0x3d, 0x20, 0x63, 0x72, 0x70, 0x69, 0x78, 0x31, 0x3b, 0x20, 0x77, 0x63, 0x73, 0x2e, 0x63, 0x72, 0x70, 0x69, 0x78, 0x5b, 0x31, 0x5d, 0x20, 0x3d, 0x20, 0x63, 0x72, 0x70, 0x69, 0x78, 0x32, 0x5d, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x3a, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x66, 0x69, 0x74, 0x73, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x60, 0x2c, 0x20, 0x73, 0x74, 0x72, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x4e, 0x6f, 0x6e, 0x65, 0x2e, 0x0a, 0x20, 0x20, 0x49, 0x66, 0x20, 0x60, 0x60, 0x4e, 0x6f, 0x6e, 0x65, 0x60, 0x60, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x6b, 0x65, 0x79, 0x20, 0x3a, 0x20, 0x73, 0x74, 0x72, 0x2c, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x57, 0x43, 0x53, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x60, 0x60, 0x27, 0x20, 0x27, 0x60, 0x60, 0x20, 0x6f, 0x72, 0x20, 0x60, 0x60, 0x27, 0x41, 0x27, 0x60, 0x60, 0x2d, 0x60, 0x60, 0x27, 0x5a, 0x27, 0x60, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x73, 0x20, 0x74, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x60, 0x22, 0x61, 0x22, 0x60, 0x60, 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x60, 0x60, 0x22, 0x43, 0x54, 0x59, 0x50, 0x45, 0x69, 0x61, 0x22, 0x60, 0x60, 0x2e, 0x20, 0x20, 0x28, 0x2a, 0x6b, 0x65, 0x79, 0x2a, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x62, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x69, 0x66, 0x20, 0x2a, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2a, 0x20, 0x69, 0x73, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x2e, 0x29, 0x0a, 0x0a, 0x72, 0x65, 0x6c, 0x61, 0x78, 0x20, 0x3a, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x20, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x74, 0x2c, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x44, 0x65, 0x67, 0x72, 0x65, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x76, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x60, 0x3a, 0x20, 0x52, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, 0x7a, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x46, 0x49, 0x54, 0x53, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x57, 0x43, 0x53, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x54, 0x72, 0x75, 0x65, 0x60, 0x3a, 0x20, 0x41, 0x64, 0x6d, 0x69, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x57, 0x43, 0x53, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x69, 0x6e, 0x74, 0x60, 0x3a, 0x20, 0x61, 0x20, 0x62, 0x69, 0x74, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2e, 0x20, 0x20, 0x53, 0x65, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3a, 0x72, 0x65, 0x66, 0x3a, 0x60, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x3a, 0x72, 0x65, 0x6c, 0x61, 0x78, 0x72, 0x65, 0x61, 0x64, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x0a, 0x0a, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x20, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x2c, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x78, 0x65, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x20, 0x20, 0x28, 0x2a, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x2a, 0x20, 0x6d, 0x61, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x69, 0x66, 0x20, 0x2a, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2a, 0x20, 0x69, 0x73, 0x20, 0x60, 0x4e, 0x6f, 0x6e, 0x65, 0x60, 0x2e, 0x29, 0x0a, 0x0a, 0x6b, 0x65, 0x79, 0x73, 0x65, 0x6c, 0x20, 0x3a, 0x20, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x20, 0x62, 0x69, 0x74, 0x73, 0x2c, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x20, 0x62, 0x69, 0x74, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x65, 0x64, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 0x48, 0x44, 0x52, 0x5f, 0x49, 0x4d, 0x47, 0x48, 0x45, 0x41, 0x44, 0x60, 0x60, 0x3a, 0x20, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 0x48, 0x44, 0x52, 0x5f, 0x42, 0x49, 0x4d, 0x47, 0x41, 0x52, 0x52, 0x60, 0x60, 0x3a, 0x20, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 0x48, 0x44, 0x52, 0x5f, 0x50, 0x49, 0x58, 0x4c, 0x49, 0x53, 0x54, 0x60, 0x60, 0x3a, 0x20, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x66, 0x20, 0x7a, 0x65, 0x72, 0x6f, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x20, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x20, 0x49, 0x66, 0x20, 0x2d, 0x31, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x6c, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x63, 0x73, 0x6c, 0x69, 0x62, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x60, 0x60, 0x77, 0x63, 0x73, 0x70, 0x69, 0x68, 0x28, 0x29, 0x60, 0x60, 0x20, 0x69, 0x73, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x2c, 0x20, 0x72, 0x61, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x60, 0x60, 0x77, 0x63, 0x73, 0x74, 0x62, 0x68, 0x28, 0x29, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x63, 0x6f, 0x6c, 0x73, 0x65, 0x6c, 0x20, 0x3a, 0x20, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x41, 0x20, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x65, 0x64, 0x2e, 0x20, 0x20, 0x60, 0x4e, 0x6f, 0x6e, 0x65, 0x60, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x20, 0x6e, 0x6f, 0x20, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x0a, 0x52, 0x61, 0x69, 0x73, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x6b, 0x65, 0x79, 0x2e, 0x0a, 0x0a, 0x4b, 0x65, 0x79, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x46, 0x49, 0x54, 0x53, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x0a, 0x00, }; char doc_Wtbarr[202] = { 0x43, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x20, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x42, 0x49, 0x4e, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x29, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x69, 0x73, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x65, 0x64, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6c, 0x79, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x50, 0x79, 0x74, 0x68, 0x6f, 0x6e, 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x65, 0x61, 0x64, 0x20, 0x69, 0x73, 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x77, 0x74, 0x62, 0x60, 0x2e, 0x0a, 0x00, }; char doc_a[264] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x61, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2b, 0x31, 0x5d, 0x5b, 0x61, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2b, 0x31, 0x5d, 0x60, 0x60, 0x20, 0x46, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x60, 0x53, 0x49, 0x50, 0x60, 0x5f, 0x20, 0x60, 0x60, 0x41, 0x5f, 0x69, 0x5f, 0x6a, 0x60, 0x60, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x0a, 0x49, 0x74, 0x73, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x69, 0x74, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x64, 0x2c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x53, 0x69, 0x70, 0x60, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x0a, 0x00, }; char doc_a_order[60] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x6f, 0x6c, 0x79, 0x6e, 0x6f, 0x6d, 0x69, 0x61, 0x6c, 0x20, 0x28, 0x60, 0x60, 0x41, 0x5f, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x60, 0x60, 0x29, 0x2e, 0x0a, 0x00, }; char doc_all_pix2world[1305] = { 0x61, 0x6c, 0x6c, 0x5f, 0x70, 0x69, 0x78, 0x32, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x28, 0x70, 0x69, 0x78, 0x63, 0x72, 0x64, 0x2c, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x5b, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x5d, 0x60, 0x60, 0x0a, 0x0a, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x44, 0x6f, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x69, 0x66, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x53, 0x49, 0x50, 0x20, 0x64, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x69, 0x66, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x46, 0x49, 0x54, 0x53, 0x20, 0x57, 0x43, 0x53, 0x20, 0x64, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x69, 0x66, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x77, 0x63, 0x73, 0x6c, 0x69, 0x62, 0x20, 0x22, 0x63, 0x6f, 0x72, 0x65, 0x22, 0x20, 0x57, 0x43, 0x53, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x74, 0x68, 0x72, 0x65, 0x65, 0x20, 0x28, 0x74, 0x68, 0x65, 0x20, 0x64, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20, 0x61, 0x72, 0x65, 0x20, 0x64, 0x6f, 0x6e, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x2e, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x70, 0x69, 0x78, 0x63, 0x72, 0x64, 0x20, 0x3a, 0x20, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x5b, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x5d, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x0a, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x46, 0x6f, 0x72, 0x74, 0x72, 0x61, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x46, 0x49, 0x54, 0x53, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x73, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x31, 0x2e, 0x20, 0x20, 0x4e, 0x75, 0x6d, 0x70, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x43, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x69, 0x74, 0x68, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x61, 0x74, 0x20, 0x30, 0x2e, 0x0a, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x3a, 0x20, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x5b, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x5d, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x52, 0x61, 0x69, 0x73, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x53, 0x69, 0x6e, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x69, 0x73, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x41, 0x78, 0x69, 0x73, 0x54, 0x79, 0x70, 0x65, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x75, 0x6e, 0x72, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x0a, 0x0a, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x0a, 0x0a, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x78, 0x2d, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x79, 0x2d, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6c, 0x6c, 0x2d, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x0a, 0x00, }; char doc_alt[236] = { 0x60, 0x60, 0x73, 0x74, 0x72, 0x60, 0x60, 0x20, 0x43, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x0a, 0x0a, 0x46, 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x60, 0x22, 0x61, 0x22, 0x60, 0x60, 0x20, 0x69, 0x6e, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x20, 0x73, 0x75, 0x63, 0x68, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x43, 0x54, 0x59, 0x50, 0x45, 0x69, 0x61, 0x60, 0x60, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x69, 0x73, 0x0a, 0x69, 0x73, 0x20, 0x61, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x0a, 0x74, 0x68, 0x65, 0x20, 0x32, 0x36, 0x20, 0x75, 0x70, 0x70, 0x65, 0x72, 0x2d, 0x63, 0x61, 0x73, 0x65, 0x20, 0x6c, 0x65, 0x74, 0x74, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x41, 0x2d, 0x5a, 0x2e, 0x0a, 0x00, }; char doc_ap[276] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x61, 0x70, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2b, 0x31, 0x5d, 0x5b, 0x61, 0x70, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2b, 0x31, 0x5d, 0x60, 0x60, 0x20, 0x46, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x60, 0x53, 0x49, 0x50, 0x60, 0x5f, 0x20, 0x60, 0x60, 0x41, 0x50, 0x5f, 0x69, 0x5f, 0x6a, 0x60, 0x60, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x66, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x20, 0x49, 0x74, 0x73, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x69, 0x74, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x0a, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x64, 0x2c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x53, 0x69, 0x70, 0x60, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x0a, 0x00, }; char doc_ap_order[61] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x6f, 0x6c, 0x79, 0x6e, 0x6f, 0x6d, 0x69, 0x61, 0x6c, 0x20, 0x28, 0x60, 0x60, 0x41, 0x50, 0x5f, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x60, 0x60, 0x29, 0x2e, 0x0a, 0x00, }; char doc_aux[87] = { 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x41, 0x75, 0x78, 0x70, 0x72, 0x6d, 0x60, 0x20, 0x41, 0x75, 0x78, 0x69, 0x6c, 0x69, 0x61, 0x72, 0x79, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x2e, 0x0a, 0x00, }; char doc_axis_types[916] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x60, 0x60, 0x20, 0x41, 0x6e, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x66, 0x6f, 0x75, 0x72, 0x2d, 0x64, 0x69, 0x67, 0x69, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x61, 0x78, 0x69, 0x73, 0x2e, 0x0a, 0x0a, 0x2d, 0x20, 0x46, 0x69, 0x72, 0x73, 0x74, 0x20, 0x64, 0x69, 0x67, 0x69, 0x74, 0x20, 0x28, 0x69, 0x2e, 0x65, 0x2e, 0x20, 0x31, 0x30, 0x30, 0x30, 0x73, 0x29, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x30, 0x3a, 0x20, 0x4e, 0x6f, 0x6e, 0x2d, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x31, 0x3a, 0x20, 0x53, 0x74, 0x6f, 0x6b, 0x65, 0x73, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x32, 0x3a, 0x20, 0x43, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x28, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x60, 0x60, 0x43, 0x55, 0x42, 0x45, 0x46, 0x41, 0x43, 0x45, 0x60, 0x60, 0x29, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x33, 0x3a, 0x20, 0x53, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x2e, 0x0a, 0x0a, 0x2d, 0x20, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x64, 0x69, 0x67, 0x69, 0x74, 0x20, 0x28, 0x69, 0x2e, 0x65, 0x2e, 0x20, 0x31, 0x30, 0x30, 0x73, 0x29, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x30, 0x3a, 0x20, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x61, 0x78, 0x69, 0x73, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x31, 0x3a, 0x20, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x28, 0x60, 0x60, 0x53, 0x54, 0x4f, 0x4b, 0x45, 0x53, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x43, 0x55, 0x42, 0x45, 0x46, 0x41, 0x43, 0x45, 0x60, 0x60, 0x29, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x32, 0x3a, 0x20, 0x4e, 0x6f, 0x6e, 0x2d, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x69, 0x73, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x33, 0x3a, 0x20, 0x4e, 0x6f, 0x6e, 0x2d, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x73, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x69, 0x73, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x34, 0x3a, 0x20, 0x4c, 0x6f, 0x67, 0x61, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x69, 0x63, 0x20, 0x61, 0x78, 0x69, 0x73, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x35, 0x3a, 0x20, 0x54, 0x61, 0x62, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x61, 0x78, 0x69, 0x73, 0x2e, 0x0a, 0x0a, 0x2d, 0x20, 0x54, 0x68, 0x69, 0x72, 0x64, 0x20, 0x64, 0x69, 0x67, 0x69, 0x74, 0x20, 0x28, 0x69, 0x2e, 0x65, 0x2e, 0x20, 0x31, 0x30, 0x73, 0x29, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x30, 0x3a, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2c, 0x20, 0x65, 0x2e, 0x67, 0x2e, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x0a, 0x0a, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x75, 0x72, 0x74, 0x68, 0x20, 0x64, 0x69, 0x67, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x61, 0x20, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x65, 0x73, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x30, 0x3a, 0x20, 0x4c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x31, 0x3a, 0x20, 0x4c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x32, 0x3a, 0x20, 0x60, 0x60, 0x43, 0x55, 0x42, 0x45, 0x46, 0x41, 0x43, 0x45, 0x60, 0x60, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x3a, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x0a, 0x0a, 0x60, 0x60, 0x43, 0x54, 0x59, 0x50, 0x45, 0x69, 0x61, 0x60, 0x60, 0x20, 0x69, 0x6e, 0x20, 0x60, 0x60, 0x22, 0x34, 0x2d, 0x33, 0x22, 0x60, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x75, 0x6e, 0x72, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x0a, 0x68, 0x61, 0x76, 0x65, 0x20, 0x69, 0x74, 0x73, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x73, 0x65, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x2d, 0x31, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x0a, 0x00, }; char doc_b[273] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x62, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2b, 0x31, 0x5d, 0x5b, 0x62, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2b, 0x31, 0x5d, 0x60, 0x60, 0x20, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x60, 0x53, 0x49, 0x50, 0x60, 0x5f, 0x20, 0x60, 0x60, 0x42, 0x5f, 0x69, 0x5f, 0x6a, 0x60, 0x60, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x20, 0x49, 0x74, 0x73, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x69, 0x74, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x0a, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x64, 0x2c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x53, 0x69, 0x70, 0x60, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x0a, 0x00, }; char doc_b_order[60] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x6f, 0x6c, 0x79, 0x6e, 0x6f, 0x6d, 0x69, 0x61, 0x6c, 0x20, 0x28, 0x60, 0x60, 0x42, 0x5f, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x60, 0x60, 0x29, 0x2e, 0x0a, 0x00, }; char doc_bepoch[119] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x45, 0x71, 0x75, 0x69, 0x76, 0x61, 0x6c, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x60, 0x44, 0x41, 0x54, 0x45, 0x2d, 0x4f, 0x42, 0x53, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x61, 0x20, 0x42, 0x65, 0x73, 0x73, 0x65, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x64, 0x61, 0x74, 0x65, 0x6f, 0x62, 0x73, 0x0a, 0x00, }; char doc_bounds_check[469] = { 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x28, 0x70, 0x69, 0x78, 0x32, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x32, 0x70, 0x69, 0x78, 0x29, 0x0a, 0x0a, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x2f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x70, 0x69, 0x78, 0x32, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x3a, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x2c, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x57, 0x68, 0x65, 0x6e, 0x20, 0x60, 0x54, 0x72, 0x75, 0x65, 0x60, 0x2c, 0x20, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x2d, 0x74, 0x6f, 0x2d, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x28, 0x70, 0x32, 0x78, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x20, 0x20, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x69, 0x73, 0x20, 0x60, 0x54, 0x72, 0x75, 0x65, 0x60, 0x2e, 0x0a, 0x0a, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x32, 0x70, 0x69, 0x78, 0x20, 0x3a, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x2c, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x57, 0x68, 0x65, 0x6e, 0x20, 0x60, 0x54, 0x72, 0x75, 0x65, 0x60, 0x2c, 0x20, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2d, 0x74, 0x6f, 0x2d, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x28, 0x73, 0x32, 0x78, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x20, 0x20, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x69, 0x73, 0x20, 0x60, 0x54, 0x72, 0x75, 0x65, 0x60, 0x2e, 0x0a, 0x0a, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4e, 0x6f, 0x74, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x62, 0x79, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x28, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x60, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x60, 0x29, 0x20, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x20, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x0a, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x73, 0x20, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x2e, 0x0a, 0x00, }; char doc_bp[276] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x62, 0x70, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2b, 0x31, 0x5d, 0x5b, 0x62, 0x70, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2b, 0x31, 0x5d, 0x60, 0x60, 0x20, 0x46, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x60, 0x53, 0x49, 0x50, 0x60, 0x5f, 0x20, 0x60, 0x60, 0x42, 0x50, 0x5f, 0x69, 0x5f, 0x6a, 0x60, 0x60, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x66, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x20, 0x49, 0x74, 0x73, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x69, 0x74, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x0a, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x64, 0x2c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x53, 0x69, 0x70, 0x60, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x0a, 0x00, }; char doc_bp_order[61] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x6f, 0x6c, 0x79, 0x6e, 0x6f, 0x6d, 0x69, 0x61, 0x6c, 0x20, 0x28, 0x60, 0x60, 0x42, 0x50, 0x5f, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x60, 0x60, 0x29, 0x2e, 0x0a, 0x00, }; char doc_cd[1059] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x60, 0x60, 0x20, 0x54, 0x68, 0x65, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2e, 0x0a, 0x0a, 0x46, 0x6f, 0x72, 0x20, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x2c, 0x20, 0x74, 0x68, 0x72, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x77, 0x63, 0x73, 0x6c, 0x69, 0x62, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x0a, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x60, 0x60, 0x43, 0x44, 0x45, 0x4c, 0x54, 0x69, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x0a, 0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 0x60, 0x60, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x2e, 0x20, 0x20, 0x41, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x63, 0x6f, 0x2d, 0x65, 0x78, 0x69, 0x73, 0x74, 0x0a, 0x77, 0x69, 0x74, 0x68, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x61, 0x63, 0x68, 0x20, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x20, 0x69, 0x66, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x0a, 0x69, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x6a, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x5f, 0x70, 0x63, 0x60, 0x2c, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x5f, 0x63, 0x64, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x5f, 0x63, 0x72, 0x6f, 0x74, 0x61, 0x60, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x6f, 0x66, 0x0a, 0x74, 0x68, 0x65, 0x73, 0x65, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x73, 0x65, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x61, 0x72, 0x65, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x6c, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x62, 0x79, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x2d, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x20, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x49, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x2c, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x73, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x64, 0x65, 0x6c, 0x74, 0x60, 0x20, 0x74, 0x6f, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x0a, 0x69, 0x66, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x69, 0x73, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x28, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x29, 0x2e, 0x20, 0x20, 0x49, 0x66, 0x20, 0x6e, 0x6f, 0x20, 0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 0x60, 0x60, 0x20, 0x69, 0x73, 0x0a, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x2c, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x73, 0x0a, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2e, 0x0a, 0x00, }; char doc_cdelt[308] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x60, 0x60, 0x20, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x28, 0x60, 0x60, 0x43, 0x44, 0x45, 0x4c, 0x54, 0x69, 0x61, 0x60, 0x60, 0x29, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x61, 0x63, 0x68, 0x0a, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x61, 0x78, 0x69, 0x73, 0x2e, 0x0a, 0x0a, 0x49, 0x66, 0x20, 0x61, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x69, 0x73, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x2c, 0x20, 0x61, 0x20, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x73, 0x0a, 0x72, 0x61, 0x69, 0x73, 0x65, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x64, 0x65, 0x6c, 0x74, 0x60, 0x20, 0x69, 0x73, 0x20, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x64, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x0a, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x3a, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x64, 0x65, 0x6c, 0x20, 0x77, 0x63, 0x73, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x63, 0x64, 0x0a, 0x0a, 0x41, 0x6e, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x4e, 0x61, 0x4e, 0x2e, 0x0a, 0x00, }; char doc_cdfix[480] = { 0x63, 0x64, 0x66, 0x69, 0x78, 0x28, 0x29, 0x0a, 0x0a, 0x46, 0x69, 0x78, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x6e, 0x65, 0x6f, 0x75, 0x73, 0x6c, 0x79, 0x20, 0x6f, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x74, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x69, 0x61, 0x67, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x74, 0x6f, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x20, 0x69, 0x66, 0x20, 0x61, 0x6c, 0x6c, 0x0a, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x77, 0x65, 0x72, 0x65, 0x20, 0x6f, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x2e, 0x0a, 0x41, 0x63, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x50, 0x61, 0x70, 0x65, 0x72, 0x20, 0x49, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x61, 0x72, 0x65, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x0a, 0x46, 0x49, 0x54, 0x53, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x6f, 0x73, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x7a, 0x65, 0x72, 0x6f, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x0a, 0x73, 0x69, 0x6e, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6e, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x72, 0x6f, 0x77, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x7a, 0x65, 0x72, 0x6f, 0x73, 0x2e, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x60, 0x60, 0x30, 0x60, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x3b, 0x20, 0x60, 0x60, 0x2d, 0x31, 0x60, 0x60, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2e, 0x0a, 0x00, }; char doc_cel_offset[176] = { 0x60, 0x60, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x60, 0x60, 0x20, 0x49, 0x73, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x3f, 0x0a, 0x0a, 0x49, 0x66, 0x20, 0x60, 0x54, 0x72, 0x75, 0x65, 0x60, 0x2c, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x60, 0x28, 0x78, 0x2c, 0x20, 0x79, 0x29, 0x60, 0x60, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x20, 0x60, 0x60, 0x28, 0x78, 0x2c, 0x20, 0x79, 0x29, 0x20, 0x3d, 0x0a, 0x28, 0x30, 0x2c, 0x20, 0x30, 0x29, 0x60, 0x60, 0x20, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x64, 0x75, 0x63, 0x69, 0x61, 0x6c, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2c, 0x20, 0x28, 0x70, 0x68, 0x69, 0x5f, 0x30, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x74, 0x61, 0x5f, 0x30, 0x29, 0x2e, 0x20, 0x20, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x69, 0x73, 0x20, 0x60, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x60, 0x2e, 0x0a, 0x00, }; char doc_celfix[171] = { 0x54, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x20, 0x41, 0x49, 0x50, 0x53, 0x2d, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2c, 0x20, 0x60, 0x60, 0x2d, 0x4e, 0x43, 0x50, 0x60, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x60, 0x60, 0x2d, 0x47, 0x4c, 0x53, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x60, 0x60, 0x30, 0x60, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x3b, 0x20, 0x60, 0x60, 0x2d, 0x31, 0x60, 0x60, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2e, 0x0a, 0x00, }; char doc_cname[76] = { 0x60, 0x60, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x60, 0x60, 0x20, 0x41, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x2c, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x0a, 0x60, 0x60, 0x43, 0x4e, 0x41, 0x4d, 0x45, 0x69, 0x61, 0x60, 0x60, 0x2e, 0x0a, 0x00, }; char doc_colax[91] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x60, 0x60, 0x20, 0x41, 0x6e, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x61, 0x63, 0x68, 0x0a, 0x61, 0x78, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x0a, 0x00, }; char doc_colnum[290] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x60, 0x60, 0x20, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x46, 0x49, 0x54, 0x53, 0x20, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x57, 0x43, 0x53, 0x2e, 0x0a, 0x0a, 0x57, 0x68, 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6e, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2d, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x46, 0x49, 0x54, 0x53, 0x20, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x72, 0x65, 0x6c, 0x65, 0x76, 0x61, 0x6e, 0x74, 0x20, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2e, 0x0a, 0x0a, 0x49, 0x74, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x73, 0x65, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x7a, 0x65, 0x72, 0x6f, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6e, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x6f, 0x72, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x0a, 0x00, }; char doc_compare[1412] = { 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x28, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x2c, 0x20, 0x63, 0x6d, 0x70, 0x3d, 0x30, 0x2c, 0x20, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x3d, 0x30, 0x2e, 0x30, 0x29, 0x0a, 0x0a, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x20, 0x74, 0x77, 0x6f, 0x20, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2e, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x3a, 0x20, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x2e, 0x0a, 0x0a, 0x63, 0x6d, 0x70, 0x20, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x2c, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x41, 0x20, 0x62, 0x69, 0x74, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x2e, 0x20, 0x20, 0x57, 0x68, 0x65, 0x6e, 0x20, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x28, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x29, 0x2c, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x73, 0x2c, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x60, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x6f, 0x72, 0x27, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x67, 0x65, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x45, 0x5f, 0x41, 0x4e, 0x43, 0x49, 0x4c, 0x4c, 0x41, 0x52, 0x59, 0x60, 0x60, 0x3a, 0x20, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x63, 0x69, 0x6c, 0x6c, 0x61, 0x72, 0x79, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x6e, 0x27, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x57, 0x43, 0x53, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x73, 0x75, 0x63, 0x68, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x58, 0x50, 0x4f, 0x53, 0x55, 0x52, 0x45, 0x60, 0x60, 0x20, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x60, 0x45, 0x51, 0x55, 0x49, 0x4e, 0x4f, 0x58, 0x60, 0x60, 0x2e, 0x20, 0x4e, 0x6f, 0x74, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x73, 0x20, 0x60, 0x60, 0x44, 0x41, 0x54, 0x45, 0x2d, 0x4f, 0x42, 0x53, 0x60, 0x60, 0x2c, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x64, 0x6f, 0x65, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x57, 0x43, 0x53, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x63, 0x61, 0x73, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x45, 0x5f, 0x54, 0x49, 0x4c, 0x49, 0x4e, 0x47, 0x60, 0x60, 0x3a, 0x20, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x6c, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x60, 0x43, 0x52, 0x50, 0x49, 0x58, 0x6a, 0x61, 0x60, 0x60, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x27, 0x74, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x27, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x74, 0x77, 0x6f, 0x20, 0x57, 0x43, 0x53, 0x65, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x61, 0x70, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x20, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x61, 0x70, 0x20, 0x67, 0x72, 0x69, 0x64, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x45, 0x5f, 0x43, 0x52, 0x50, 0x49, 0x58, 0x60, 0x60, 0x3a, 0x20, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x69, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x60, 0x43, 0x52, 0x50, 0x49, 0x58, 0x6a, 0x61, 0x60, 0x60, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x74, 0x77, 0x6f, 0x20, 0x57, 0x43, 0x53, 0x65, 0x73, 0x20, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61, 0x70, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x67, 0x72, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x70, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x45, 0x5f, 0x54, 0x49, 0x4c, 0x49, 0x4e, 0x47, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x3a, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2c, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2e, 0x20, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x6f, 0x66, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x31, 0x65, 0x2d, 0x36, 0x2c, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x2d, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x20, 0x74, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x36, 0x20, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x30, 0x2e, 0x30, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x65, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x78, 0x61, 0x63, 0x74, 0x20, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2e, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x20, 0x3a, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x0a, 0x00, }; char doc_convert[121] = { 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x28, 0x61, 0x72, 0x72, 0x61, 0x79, 0x29, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x2a, 0x61, 0x72, 0x72, 0x61, 0x79, 0x2a, 0x2c, 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x73, 0x68, 0x61, 0x70, 0x65, 0x2e, 0x0a, 0x00, }; char doc_coord[277] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x4b, 0x5f, 0x4d, 0x5d, 0x2e, 0x2e, 0x2e, 0x5b, 0x4b, 0x5f, 0x32, 0x5d, 0x5b, 0x4b, 0x5f, 0x31, 0x5d, 0x5b, 0x4d, 0x5d, 0x60, 0x60, 0x20, 0x54, 0x68, 0x65, 0x20, 0x74, 0x61, 0x62, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x2e, 0x0a, 0x0a, 0x48, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x28, 0x4b, 0x5f, 0x4d, 0x2c, 0x20, 0x2e, 0x2e, 0x2e, 0x20, 0x4b, 0x5f, 0x32, 0x2c, 0x20, 0x4b, 0x5f, 0x31, 0x2c, 0x20, 0x4d, 0x29, 0x0a, 0x0a, 0x28, 0x73, 0x65, 0x65, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x54, 0x61, 0x62, 0x70, 0x72, 0x6d, 0x2e, 0x4b, 0x60, 0x29, 0x20, 0x69, 0x2e, 0x65, 0x2e, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x4d, 0x60, 0x20, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x61, 0x73, 0x74, 0x65, 0x73, 0x74, 0x20, 0x73, 0x6f, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x4d, 0x60, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x61, 0x72, 0x65, 0x0a, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x67, 0x75, 0x6f, 0x75, 0x73, 0x6c, 0x79, 0x20, 0x69, 0x6e, 0x20, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x2e, 0x0a, 0x00, }; char doc_copy[40] = { 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x64, 0x65, 0x65, 0x70, 0x20, 0x63, 0x6f, 0x70, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x57, 0x43, 0x53, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x0a, 0x00, }; char doc_cpdis1[106] = { 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x44, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x60, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x70, 0x72, 0x65, 0x2d, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2c, 0x20, 0x60, 0x60, 0x43, 0x50, 0x44, 0x49, 0x53, 0x31, 0x60, 0x60, 0x2e, 0x0a, 0x00, }; char doc_cpdis2[106] = { 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x44, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x60, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x70, 0x72, 0x65, 0x2d, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2c, 0x20, 0x60, 0x60, 0x43, 0x50, 0x44, 0x49, 0x53, 0x32, 0x60, 0x60, 0x2e, 0x0a, 0x00, }; char doc_cperi[101] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x60, 0x60, 0x20, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x20, 0x70, 0x68, 0x61, 0x73, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x2c, 0x20, 0x43, 0x50, 0x45, 0x52, 0x49, 0x69, 0x61, 0x2e, 0x0a, 0x0a, 0x41, 0x6e, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x4e, 0x61, 0x4e, 0x2e, 0x0a, 0x00, }; char doc_crder[123] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x60, 0x60, 0x20, 0x54, 0x68, 0x65, 0x20, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x2c, 0x0a, 0x60, 0x60, 0x43, 0x52, 0x44, 0x45, 0x52, 0x69, 0x61, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x41, 0x6e, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x4e, 0x61, 0x4e, 0x2e, 0x0a, 0x00, }; char doc_crln_obs[106] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x43, 0x61, 0x72, 0x72, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x20, 0x68, 0x65, 0x6c, 0x69, 0x6f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x28, 0x64, 0x65, 0x67, 0x29, 0x2e, 0x20, 0x49, 0x66, 0x0a, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x73, 0x65, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x4e, 0x6f, 0x6e, 0x65, 0x60, 0x2e, 0x0a, 0x00, }; char doc_crota[1055] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x60, 0x60, 0x20, 0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 0x60, 0x60, 0x20, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x0a, 0x61, 0x78, 0x69, 0x73, 0x2e, 0x0a, 0x0a, 0x46, 0x6f, 0x72, 0x20, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x2c, 0x20, 0x74, 0x68, 0x72, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x77, 0x63, 0x73, 0x6c, 0x69, 0x62, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x0a, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x60, 0x60, 0x43, 0x44, 0x45, 0x4c, 0x54, 0x69, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x0a, 0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 0x60, 0x60, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x2e, 0x20, 0x20, 0x41, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x63, 0x6f, 0x2d, 0x65, 0x78, 0x69, 0x73, 0x74, 0x0a, 0x77, 0x69, 0x74, 0x68, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x61, 0x63, 0x68, 0x20, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x20, 0x69, 0x66, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x0a, 0x69, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x6a, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x5f, 0x70, 0x63, 0x60, 0x2c, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x5f, 0x63, 0x64, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x5f, 0x63, 0x72, 0x6f, 0x74, 0x61, 0x60, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x6f, 0x66, 0x0a, 0x74, 0x68, 0x65, 0x73, 0x65, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x73, 0x65, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x61, 0x72, 0x65, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x6c, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x62, 0x79, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x2d, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x20, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x49, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x2c, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x73, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x64, 0x65, 0x6c, 0x74, 0x60, 0x20, 0x74, 0x6f, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x0a, 0x69, 0x66, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x69, 0x73, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x28, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x29, 0x2e, 0x20, 0x20, 0x49, 0x66, 0x20, 0x6e, 0x6f, 0x20, 0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 0x60, 0x60, 0x20, 0x69, 0x73, 0x0a, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x2c, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x73, 0x0a, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2e, 0x0a, 0x00, }; char doc_crpix[88] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x60, 0x60, 0x20, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x73, 0x20, 0x28, 0x60, 0x60, 0x43, 0x52, 0x50, 0x49, 0x58, 0x6a, 0x61, 0x60, 0x60, 0x29, 0x20, 0x66, 0x6f, 0x72, 0x0a, 0x65, 0x61, 0x63, 0x68, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x61, 0x78, 0x69, 0x73, 0x2e, 0x0a, 0x00, }; char doc_crval[93] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x60, 0x60, 0x20, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x28, 0x60, 0x60, 0x43, 0x52, 0x56, 0x41, 0x4c, 0x69, 0x61, 0x60, 0x60, 0x29, 0x20, 0x66, 0x6f, 0x72, 0x0a, 0x65, 0x61, 0x63, 0x68, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x2e, 0x0a, 0x00, }; char doc_crval_tabprm[94] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x4d, 0x5d, 0x60, 0x60, 0x20, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x6f, 0x66, 0x0a, 0x74, 0x68, 0x65, 0x20, 0x74, 0x61, 0x62, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x61, 0x78, 0x65, 0x73, 0x2e, 0x0a, 0x00, }; char doc_csyer[132] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x60, 0x60, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x61, 0x78, 0x65, 0x73, 0x2c, 0x20, 0x60, 0x60, 0x43, 0x53, 0x59, 0x45, 0x52, 0x69, 0x61, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x41, 0x6e, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x4e, 0x61, 0x4e, 0x2e, 0x0a, 0x00, }; char doc_ctype[228] = { 0x60, 0x60, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x60, 0x60, 0x20, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x60, 0x60, 0x43, 0x54, 0x59, 0x50, 0x45, 0x69, 0x61, 0x60, 0x60, 0x20, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x74, 0x79, 0x70, 0x65, 0x60, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x75, 0x70, 0x70, 0x65, 0x72, 0x20, 0x63, 0x61, 0x73, 0x65, 0x0a, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x7a, 0x65, 0x72, 0x6f, 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x70, 0x61, 0x69, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x20, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2c, 0x0a, 0x61, 0x6e, 0x64, 0x20, 0x7a, 0x65, 0x72, 0x6f, 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x69, 0x73, 0x2e, 0x0a, 0x00, }; char doc_cubeface[1236] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x60, 0x60, 0x20, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x60, 0x70, 0x69, 0x78, 0x63, 0x72, 0x64, 0x60, 0x60, 0x20, 0x28, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x29, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x60, 0x60, 0x43, 0x55, 0x42, 0x45, 0x46, 0x41, 0x43, 0x45, 0x60, 0x60, 0x20, 0x61, 0x78, 0x69, 0x73, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x71, 0x75, 0x61, 0x64, 0x63, 0x75, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x75, 0x62, 0x65, 0x20, 0x66, 0x61, 0x63, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x0a, 0x6f, 0x6e, 0x20, 0x61, 0x20, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x71, 0x75, 0x61, 0x64, 0x63, 0x75, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x28, 0x60, 0x60, 0x54, 0x53, 0x43, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x43, 0x53, 0x43, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x51, 0x53, 0x43, 0x60, 0x60, 0x29, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x0a, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x46, 0x49, 0x54, 0x53, 0x20, 0x69, 0x6e, 0x20, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x77, 0x6f, 0x20, 0x77, 0x61, 0x79, 0x73, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x69, 0x78, 0x20, 0x66, 0x61, 0x63, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x6c, 0x61, 0x69, 0x64, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x65, 0x64, 0x20, 0x61, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x73, 0x3a, 0x3a, 0x0a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x34, 0x20, 0x20, 0x33, 0x20, 0x20, 0x32, 0x20, 0x20, 0x31, 0x20, 0x20, 0x34, 0x20, 0x20, 0x33, 0x20, 0x20, 0x32, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x35, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x46, 0x61, 0x63, 0x65, 0x73, 0x20, 0x32, 0x2c, 0x20, 0x33, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x34, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x20, 0x6f, 0x6e, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x73, 0x69, 0x64, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x28, 0x6f, 0x72, 0x20, 0x62, 0x6f, 0x74, 0x68, 0x29, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2d, 0x74, 0x6f, 0x2d, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x70, 0x20, 0x66, 0x61, 0x63, 0x65, 0x73, 0x20, 0x32, 0x2c, 0x20, 0x33, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x34, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x62, 0x75, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x2d, 0x74, 0x6f, 0x2d, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x73, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x20, 0x6f, 0x6e, 0x20, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x60, 0x60, 0x43, 0x4f, 0x42, 0x45, 0x60, 0x60, 0x20, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x69, 0x78, 0x20, 0x66, 0x61, 0x63, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x72, 0x65, 0x65, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x60, 0x60, 0x43, 0x55, 0x42, 0x45, 0x46, 0x41, 0x43, 0x45, 0x60, 0x60, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x30, 0x20, 0x74, 0x6f, 0x20, 0x35, 0x20, 0x61, 0x73, 0x20, 0x61, 0x62, 0x6f, 0x76, 0x65, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x73, 0x65, 0x20, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x73, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x62, 0x6f, 0x74, 0x68, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x3b, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x0a, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x73, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x69, 0x73, 0x20, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x62, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x0a, 0x60, 0x60, 0x43, 0x55, 0x42, 0x45, 0x46, 0x41, 0x43, 0x45, 0x60, 0x60, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x74, 0x79, 0x70, 0x65, 0x60, 0x2e, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x70, 0x32, 0x73, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x32, 0x70, 0x60, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x60, 0x60, 0x43, 0x55, 0x42, 0x45, 0x46, 0x41, 0x43, 0x45, 0x60, 0x60, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x74, 0x6f, 0x6f, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x2d, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x73, 0x2e, 0x0a, 0x00, }; char doc_cunit[1323] = { 0x60, 0x60, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x55, 0x6e, 0x69, 0x74, 0x42, 0x61, 0x73, 0x65, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x60, 0x60, 0x20, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x60, 0x60, 0x43, 0x55, 0x4e, 0x49, 0x54, 0x69, 0x61, 0x60, 0x60, 0x20, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x61, 0x73, 0x0a, 0x60, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x2e, 0x55, 0x6e, 0x69, 0x74, 0x42, 0x61, 0x73, 0x65, 0x60, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x73, 0x65, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x60, 0x43, 0x52, 0x56, 0x41, 0x4c, 0x69, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x43, 0x44, 0x45, 0x4c, 0x54, 0x69, 0x61, 0x60, 0x60, 0x0a, 0x61, 0x6e, 0x64, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x2e, 0x0a, 0x0a, 0x41, 0x73, 0x20, 0x60, 0x60, 0x43, 0x55, 0x4e, 0x49, 0x54, 0x69, 0x61, 0x60, 0x60, 0x20, 0x69, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x2c, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x75, 0x6e, 0x69, 0x74, 0x60, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x77, 0x69, 0x73, 0x65, 0x20, 0x69, 0x73, 0x0a, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x73, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x57, 0x43, 0x53, 0x0a, 0x50, 0x61, 0x70, 0x65, 0x72, 0x20, 0x49, 0x2e, 0x20, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x75, 0x6e, 0x69, 0x74, 0x66, 0x69, 0x78, 0x60, 0x20, 0x69, 0x73, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x6e, 0x6f, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x62, 0x75, 0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x64, 0x6f, 0x6e, 0x65, 0x0a, 0x61, 0x73, 0x20, 0x61, 0x20, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x20, 0x73, 0x74, 0x65, 0x70, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x69, 0x6e, 0x76, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x2e, 0x0a, 0x0a, 0x46, 0x6f, 0x72, 0x20, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x65, 0x73, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x75, 0x6e, 0x69, 0x74, 0x60, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x2c, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 0x75, 0x73, 0x65, 0x73, 0x20, 0x60, 0x60, 0x77, 0x63, 0x73, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x60, 0x60, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x20, 0x69, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x64, 0x65, 0x6c, 0x74, 0x60, 0x2c, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x72, 0x76, 0x61, 0x6c, 0x60, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x64, 0x60, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x20, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x49, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x73, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x75, 0x6e, 0x69, 0x74, 0x60, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x60, 0x22, 0x64, 0x65, 0x67, 0x22, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x46, 0x6f, 0x72, 0x20, 0x73, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x65, 0x73, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x75, 0x6e, 0x69, 0x74, 0x60, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x2c, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 0x75, 0x73, 0x65, 0x73, 0x20, 0x60, 0x60, 0x77, 0x63, 0x73, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x60, 0x60, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x20, 0x69, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x64, 0x65, 0x6c, 0x74, 0x60, 0x2c, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x72, 0x76, 0x61, 0x6c, 0x60, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x64, 0x60, 0x20, 0x74, 0x6f, 0x20, 0x53, 0x49, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x2e, 0x20, 0x20, 0x49, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x73, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x75, 0x6e, 0x69, 0x74, 0x60, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x6c, 0x79, 0x2e, 0x0a, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x73, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x75, 0x6e, 0x69, 0x74, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x0a, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x3b, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x75, 0x6e, 0x69, 0x74, 0x60, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x0a, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x0a, 0x00, }; char doc_cylfix[162] = { 0x63, 0x79, 0x6c, 0x66, 0x69, 0x78, 0x28, 0x29, 0x0a, 0x0a, 0x46, 0x69, 0x78, 0x65, 0x73, 0x20, 0x57, 0x43, 0x53, 0x20, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x6d, 0x61, 0x6c, 0x66, 0x6f, 0x72, 0x6d, 0x65, 0x64, 0x20, 0x63, 0x79, 0x6c, 0x69, 0x6e, 0x64, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x60, 0x60, 0x30, 0x60, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x3b, 0x20, 0x60, 0x60, 0x2d, 0x31, 0x60, 0x60, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2e, 0x0a, 0x00, }; char doc_czphs[125] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x60, 0x60, 0x20, 0x54, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x7a, 0x65, 0x72, 0x6f, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x20, 0x70, 0x68, 0x61, 0x73, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x2c, 0x20, 0x60, 0x60, 0x43, 0x53, 0x50, 0x48, 0x53, 0x69, 0x61, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x41, 0x6e, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x4e, 0x61, 0x4e, 0x2e, 0x0a, 0x00, }; char doc_data[78] = { 0x60, 0x60, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x60, 0x60, 0x20, 0x54, 0x68, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x44, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x60, 0x2e, 0x0a, 0x00, }; char doc_data_wtbarr[52] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x60, 0x60, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x42, 0x49, 0x4e, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x2e, 0x0a, 0x00, }; char doc_dateavg[152] = { 0x60, 0x60, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x60, 0x60, 0x20, 0x52, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x6d, 0x69, 0x64, 0x2d, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x61, 0x74, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x20, 0x49, 0x53, 0x4f, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2c, 0x20, 0x60, 0x60, 0x79, 0x79, 0x79, 0x79, 0x2d, 0x6d, 0x6d, 0x2d, 0x64, 0x64, 0x54, 0x68, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x64, 0x61, 0x74, 0x65, 0x6f, 0x62, 0x73, 0x0a, 0x00, }; char doc_datebeg[137] = { 0x60, 0x60, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x60, 0x60, 0x20, 0x44, 0x61, 0x74, 0x65, 0x20, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x20, 0x49, 0x53, 0x4f, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2c, 0x20, 0x60, 0x60, 0x79, 0x79, 0x79, 0x79, 0x2d, 0x6d, 0x6d, 0x2d, 0x64, 0x64, 0x54, 0x68, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x64, 0x61, 0x74, 0x65, 0x62, 0x65, 0x67, 0x0a, 0x00, }; char doc_dateend[135] = { 0x60, 0x60, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x60, 0x60, 0x20, 0x44, 0x61, 0x74, 0x65, 0x20, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x20, 0x49, 0x53, 0x4f, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2c, 0x20, 0x60, 0x60, 0x79, 0x79, 0x79, 0x79, 0x2d, 0x6d, 0x6d, 0x2d, 0x64, 0x64, 0x54, 0x68, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x64, 0x61, 0x74, 0x65, 0x65, 0x6e, 0x64, 0x0a, 0x00, }; char doc_dateobs[133] = { 0x60, 0x60, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x60, 0x60, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x61, 0x74, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x20, 0x49, 0x53, 0x4f, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2c, 0x20, 0x60, 0x60, 0x79, 0x79, 0x79, 0x79, 0x2d, 0x6d, 0x6d, 0x2d, 0x64, 0x64, 0x54, 0x68, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x64, 0x61, 0x74, 0x65, 0x61, 0x76, 0x67, 0x0a, 0x00, }; char doc_dateref[133] = { 0x60, 0x60, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x60, 0x60, 0x20, 0x44, 0x61, 0x74, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x0a, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x64, 0x61, 0x74, 0x65, 0x72, 0x65, 0x66, 0x0a, 0x00, }; char doc_datfix[512] = { 0x64, 0x61, 0x74, 0x66, 0x69, 0x78, 0x28, 0x29, 0x0a, 0x0a, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x6c, 0x64, 0x20, 0x60, 0x60, 0x44, 0x41, 0x54, 0x45, 0x2d, 0x4f, 0x42, 0x53, 0x60, 0x60, 0x20, 0x64, 0x61, 0x74, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x79, 0x65, 0x61, 0x72, 0x2d, 0x32, 0x30, 0x30, 0x30, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x0a, 0x60, 0x60, 0x28, 0x79, 0x79, 0x79, 0x79, 0x2d, 0x6d, 0x6d, 0x2d, 0x64, 0x64, 0x54, 0x68, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x29, 0x60, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x65, 0x72, 0x69, 0x76, 0x65, 0x73, 0x20, 0x60, 0x60, 0x4d, 0x4a, 0x44, 0x2d, 0x4f, 0x42, 0x53, 0x60, 0x60, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x69, 0x74, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x0a, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x20, 0x73, 0x65, 0x74, 0x2e, 0x0a, 0x0a, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x6c, 0x79, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x6d, 0x6a, 0x64, 0x6f, 0x62, 0x73, 0x60, 0x20, 0x69, 0x73, 0x20, 0x73, 0x65, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x64, 0x61, 0x74, 0x65, 0x6f, 0x62, 0x73, 0x60, 0x20, 0x69, 0x73, 0x6e, 0x27, 0x74, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x64, 0x61, 0x74, 0x66, 0x69, 0x78, 0x60, 0x0a, 0x64, 0x65, 0x72, 0x69, 0x76, 0x65, 0x73, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x64, 0x61, 0x74, 0x65, 0x6f, 0x62, 0x73, 0x60, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x69, 0x74, 0x2e, 0x20, 0x20, 0x49, 0x66, 0x20, 0x62, 0x6f, 0x74, 0x68, 0x20, 0x61, 0x72, 0x65, 0x20, 0x73, 0x65, 0x74, 0x20, 0x62, 0x75, 0x74, 0x0a, 0x64, 0x69, 0x73, 0x61, 0x67, 0x72, 0x65, 0x65, 0x20, 0x62, 0x79, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x20, 0x61, 0x20, 0x64, 0x61, 0x79, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x60, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x60, 0x20, 0x69, 0x73, 0x20, 0x72, 0x61, 0x69, 0x73, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x60, 0x60, 0x30, 0x60, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x3b, 0x20, 0x60, 0x60, 0x2d, 0x31, 0x60, 0x60, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2e, 0x0a, 0x00, }; char doc_delta[238] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x4d, 0x5d, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x0a, 0x61, 0x72, 0x72, 0x61, 0x79, 0x2e, 0x0a, 0x0a, 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x73, 0x75, 0x63, 0x68, 0x20, 0x74, 0x68, 0x61, 0x74, 0x0a, 0x55, 0x70, 0x73, 0x69, 0x6c, 0x6f, 0x6e, 0x5f, 0x6d, 0x2c, 0x20, 0x61, 0x73, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x50, 0x61, 0x70, 0x65, 0x72, 0x20, 0x49, 0x49, 0x49, 0x2c, 0x20, 0x69, 0x73, 0x20, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x20, 0x74, 0x6f, 0x0a, 0x28, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x54, 0x61, 0x62, 0x70, 0x72, 0x6d, 0x2e, 0x70, 0x30, 0x60, 0x20, 0x5b, 0x6d, 0x5d, 0x20, 0x2b, 0x20, 0x31, 0x29, 0x20, 0x2b, 0x20, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5b, 0x6d, 0x5d, 0x2e, 0x0a, 0x00, }; char doc_det2im[58] = { 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x20, 0x64, 0x65, 0x74, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x0a, 0x00, }; char doc_det2im1[103] = { 0x41, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x44, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x60, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x64, 0x65, 0x74, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x0a, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x2a, 0x78, 0x2a, 0x2d, 0x61, 0x78, 0x69, 0x73, 0x2e, 0x0a, 0x00, }; char doc_det2im2[103] = { 0x41, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x44, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x60, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x64, 0x65, 0x74, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x0a, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x2a, 0x79, 0x2a, 0x2d, 0x61, 0x78, 0x69, 0x73, 0x2e, 0x0a, 0x00, }; char doc_dims[98] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x64, 0x69, 0x6d, 0x5d, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x61, 0x62, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x74, 0x62, 0x61, 0x72, 0x72, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x60, 0x2e, 0x0a, 0x00, }; char doc_dsun_obs[110] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x53, 0x75, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x28, 0x6d, 0x29, 0x2e, 0x20, 0x49, 0x66, 0x0a, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x73, 0x65, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x4e, 0x6f, 0x6e, 0x65, 0x60, 0x2e, 0x0a, 0x00, }; char doc_equinox[243] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x54, 0x68, 0x65, 0x20, 0x65, 0x71, 0x75, 0x69, 0x6e, 0x6f, 0x78, 0x20, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x65, 0x71, 0x75, 0x61, 0x74, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x20, 0x6f, 0x72, 0x0a, 0x65, 0x63, 0x6c, 0x69, 0x70, 0x74, 0x69, 0x63, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x0a, 0x0a, 0x60, 0x60, 0x45, 0x51, 0x55, 0x49, 0x4e, 0x4f, 0x58, 0x61, 0x60, 0x60, 0x20, 0x28, 0x6f, 0x72, 0x20, 0x60, 0x60, 0x45, 0x50, 0x4f, 0x43, 0x48, 0x60, 0x60, 0x20, 0x69, 0x6e, 0x20, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x29, 0x2e, 0x20, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x49, 0x43, 0x52, 0x53, 0x0a, 0x65, 0x71, 0x75, 0x61, 0x74, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x20, 0x6f, 0x72, 0x20, 0x65, 0x63, 0x6c, 0x69, 0x70, 0x74, 0x69, 0x63, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x41, 0x6e, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x4e, 0x61, 0x4e, 0x2e, 0x0a, 0x00, }; char doc_extlev[72] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x60, 0x60, 0x45, 0x58, 0x54, 0x4c, 0x45, 0x56, 0x60, 0x60, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x00, }; char doc_extnam[73] = { 0x60, 0x60, 0x73, 0x74, 0x72, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x60, 0x60, 0x45, 0x58, 0x54, 0x4e, 0x41, 0x4d, 0x45, 0x60, 0x60, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x00, }; char doc_extrema[439] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x4b, 0x5f, 0x4d, 0x5d, 0x2e, 0x2e, 0x2e, 0x5b, 0x4b, 0x5f, 0x32, 0x5d, 0x5b, 0x32, 0x5d, 0x5b, 0x4d, 0x5d, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x0a, 0x0a, 0x41, 0x6e, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x0a, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x72, 0x6f, 0x77, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x2c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x28, 0x4b, 0x5f, 0x4d, 0x2c, 0x20, 0x2e, 0x2e, 0x2e, 0x20, 0x4b, 0x5f, 0x32, 0x2c, 0x20, 0x32, 0x2c, 0x20, 0x4d, 0x29, 0x0a, 0x0a, 0x28, 0x73, 0x65, 0x65, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x54, 0x61, 0x62, 0x70, 0x72, 0x6d, 0x2e, 0x4b, 0x60, 0x29, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x65, 0x64, 0x0a, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x4b, 0x5f, 0x31, 0x20, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x69, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x65, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x0a, 0x73, 0x70, 0x65, 0x65, 0x64, 0x20, 0x75, 0x70, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x65, 0x73, 0x2e, 0x0a, 0x00, }; char doc_extver[72] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x60, 0x60, 0x45, 0x58, 0x54, 0x56, 0x45, 0x52, 0x60, 0x60, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x00, }; char doc_find_all_wcs[866] = { 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x77, 0x63, 0x73, 0x28, 0x72, 0x65, 0x6c, 0x61, 0x78, 0x3d, 0x30, 0x2c, 0x20, 0x6b, 0x65, 0x79, 0x73, 0x65, 0x6c, 0x3d, 0x30, 0x29, 0x0a, 0x0a, 0x46, 0x69, 0x6e, 0x64, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x57, 0x43, 0x53, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x3a, 0x20, 0x73, 0x74, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x72, 0x61, 0x77, 0x20, 0x46, 0x49, 0x54, 0x53, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x0a, 0x0a, 0x72, 0x65, 0x6c, 0x61, 0x78, 0x20, 0x3a, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x20, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x44, 0x65, 0x67, 0x72, 0x65, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x76, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x60, 0x3a, 0x20, 0x52, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, 0x7a, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x46, 0x49, 0x54, 0x53, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x57, 0x43, 0x53, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x54, 0x72, 0x75, 0x65, 0x60, 0x3a, 0x20, 0x41, 0x64, 0x6d, 0x69, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x57, 0x43, 0x53, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x69, 0x6e, 0x74, 0x60, 0x3a, 0x20, 0x61, 0x20, 0x62, 0x69, 0x74, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2e, 0x20, 0x20, 0x53, 0x65, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3a, 0x72, 0x65, 0x66, 0x3a, 0x60, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x3a, 0x72, 0x65, 0x6c, 0x61, 0x78, 0x72, 0x65, 0x61, 0x64, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x0a, 0x0a, 0x6b, 0x65, 0x79, 0x73, 0x65, 0x6c, 0x20, 0x3a, 0x20, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x55, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x65, 0x64, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 0x48, 0x44, 0x52, 0x5f, 0x49, 0x4d, 0x47, 0x48, 0x45, 0x41, 0x44, 0x60, 0x60, 0x3a, 0x20, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 0x48, 0x44, 0x52, 0x5f, 0x42, 0x49, 0x4d, 0x47, 0x41, 0x52, 0x52, 0x60, 0x60, 0x3a, 0x20, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 0x48, 0x44, 0x52, 0x5f, 0x50, 0x49, 0x58, 0x4c, 0x49, 0x53, 0x54, 0x60, 0x60, 0x3a, 0x20, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x66, 0x20, 0x7a, 0x65, 0x72, 0x6f, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x20, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x20, 0x49, 0x66, 0x20, 0x2d, 0x31, 0x2c, 0x20, 0x60, 0x77, 0x63, 0x73, 0x70, 0x69, 0x68, 0x60, 0x20, 0x69, 0x73, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x61, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x60, 0x77, 0x63, 0x73, 0x74, 0x62, 0x68, 0x60, 0x2e, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x77, 0x63, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x3a, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x60, 0x0a, 0x00, }; char doc_fix[1679] = { 0x66, 0x69, 0x78, 0x28, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x3d, 0x27, 0x27, 0x2c, 0x20, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x3d, 0x30, 0x29, 0x0a, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x64, 0x20, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x79, 0x20, 0x62, 0x79, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x64, 0x61, 0x74, 0x66, 0x69, 0x78, 0x60, 0x2c, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x75, 0x6e, 0x69, 0x74, 0x66, 0x69, 0x78, 0x60, 0x2c, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x65, 0x6c, 0x66, 0x69, 0x78, 0x60, 0x2c, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x70, 0x63, 0x66, 0x69, 0x78, 0x60, 0x2c, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x79, 0x6c, 0x66, 0x69, 0x78, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x64, 0x66, 0x69, 0x78, 0x60, 0x2e, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x20, 0x3a, 0x20, 0x73, 0x74, 0x72, 0x2c, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x79, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x6e, 0x6f, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x20, 0x20, 0x42, 0x79, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x2c, 0x20, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x41, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x60, 0x60, 0x22, 0x53, 0x22, 0x60, 0x60, 0x20, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x2c, 0x20, 0x69, 0x74, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x60, 0x22, 0x73, 0x22, 0x60, 0x60, 0x20, 0x69, 0x73, 0x20, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x20, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, 0x7a, 0x65, 0x73, 0x20, 0x60, 0x60, 0x22, 0x53, 0x22, 0x60, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x61, 0x73, 0x20, 0x53, 0x69, 0x65, 0x6d, 0x65, 0x6e, 0x73, 0x2c, 0x20, 0x68, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x20, 0x72, 0x61, 0x72, 0x65, 0x6c, 0x79, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x75, 0x73, 0x65, 0x64, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x60, 0x22, 0x48, 0x22, 0x60, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x68, 0x6f, 0x75, 0x72, 0x73, 0x20, 0x28, 0x48, 0x65, 0x6e, 0x72, 0x79, 0x29, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x60, 0x60, 0x22, 0x44, 0x22, 0x60, 0x60, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x64, 0x61, 0x79, 0x73, 0x20, 0x28, 0x44, 0x65, 0x62, 0x79, 0x65, 0x29, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x73, 0x20, 0x77, 0x68, 0x61, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x6f, 0x20, 0x69, 0x6e, 0x20, 0x73, 0x75, 0x63, 0x68, 0x20, 0x63, 0x61, 0x73, 0x65, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x69, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x73, 0x65, 0x2d, 0x69, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x49, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x20, 0x60, 0x60, 0x22, 0x73, 0x22, 0x60, 0x60, 0x2c, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x20, 0x60, 0x60, 0x22, 0x53, 0x22, 0x60, 0x60, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x60, 0x22, 0x73, 0x22, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x49, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x20, 0x60, 0x60, 0x22, 0x68, 0x22, 0x60, 0x60, 0x2c, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x20, 0x60, 0x60, 0x22, 0x48, 0x22, 0x60, 0x60, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x60, 0x22, 0x68, 0x22, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x49, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x20, 0x60, 0x60, 0x22, 0x64, 0x22, 0x60, 0x60, 0x2c, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x20, 0x60, 0x60, 0x22, 0x44, 0x22, 0x60, 0x60, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x60, 0x22, 0x64, 0x22, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x75, 0x73, 0x20, 0x60, 0x60, 0x27, 0x27, 0x60, 0x60, 0x20, 0x64, 0x6f, 0x65, 0x73, 0x6e, 0x27, 0x74, 0x20, 0x64, 0x6f, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x61, 0x73, 0x20, 0x60, 0x60, 0x27, 0x73, 0x68, 0x64, 0x27, 0x60, 0x60, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x65, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x2e, 0x0a, 0x0a, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x20, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x2c, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x73, 0x2e, 0x20, 0x20, 0x49, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x69, 0x73, 0x20, 0x73, 0x65, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x7a, 0x65, 0x72, 0x6f, 0x20, 0x6f, 0x72, 0x20, 0x60, 0x60, 0x4e, 0x6f, 0x6e, 0x65, 0x60, 0x60, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x79, 0x6c, 0x66, 0x69, 0x78, 0x60, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x20, 0x69, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x3a, 0x20, 0x64, 0x69, 0x63, 0x74, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, 0x20, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x6b, 0x65, 0x79, 0x73, 0x2c, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x69, 0x6e, 0x67, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x75, 0x62, 0x2d, 0x66, 0x69, 0x78, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x77, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x64, 0x66, 0x69, 0x78, 0x60, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x64, 0x61, 0x74, 0x66, 0x69, 0x78, 0x60, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x75, 0x6e, 0x69, 0x74, 0x66, 0x69, 0x78, 0x60, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x65, 0x6c, 0x66, 0x69, 0x78, 0x60, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x70, 0x63, 0x66, 0x69, 0x78, 0x60, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x79, 0x6c, 0x66, 0x69, 0x78, 0x60, 0x0a, 0x00, }; char doc_get_cdelt[474] = { 0x67, 0x65, 0x74, 0x5f, 0x63, 0x64, 0x65, 0x6c, 0x74, 0x28, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x6e, 0x75, 0x6d, 0x70, 0x79, 0x2e, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x0a, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x28, 0x60, 0x60, 0x43, 0x44, 0x45, 0x4c, 0x54, 0x69, 0x61, 0x60, 0x60, 0x29, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x60, 0x43, 0x44, 0x45, 0x4c, 0x54, 0x60, 0x60, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x20, 0x20, 0x55, 0x6e, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x64, 0x65, 0x6c, 0x74, 0x60, 0x20, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x0a, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x69, 0x6e, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0a, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x6f, 0x72, 0x20, 0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 0x60, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x75, 0x73, 0x65, 0x66, 0x75, 0x6c, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x0a, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x64, 0x6f, 0x6e, 0x27, 0x74, 0x20, 0x63, 0x61, 0x72, 0x65, 0x20, 0x68, 0x6f, 0x77, 0x20, 0x69, 0x74, 0x20, 0x77, 0x61, 0x73, 0x0a, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x0a, 0x00, }; char doc_get_offset[201] = { 0x67, 0x65, 0x74, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x28, 0x78, 0x2c, 0x20, 0x79, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x28, 0x78, 0x2c, 0x20, 0x79, 0x29, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x20, 0x61, 0x73, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x3a, 0x20, 0x28, 0x32, 0x2c, 0x29, 0x20, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x28, 0x2a, 0x78, 0x2a, 0x2c, 0x20, 0x2a, 0x79, 0x2a, 0x29, 0x2e, 0x0a, 0x00, }; char doc_get_pc[413] = { 0x67, 0x65, 0x74, 0x5f, 0x70, 0x63, 0x28, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x6e, 0x75, 0x6d, 0x70, 0x79, 0x2e, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x60, 0x50, 0x43, 0x60, 0x60, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x69, 0x6e, 0x20, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x60, 0x60, 0x2e, 0x20, 0x20, 0x55, 0x6e, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x70, 0x63, 0x60, 0x20, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x0a, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x69, 0x6e, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0a, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x6f, 0x72, 0x20, 0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 0x60, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x75, 0x73, 0x65, 0x66, 0x75, 0x6c, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x0a, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x64, 0x6f, 0x6e, 0x27, 0x74, 0x20, 0x63, 0x61, 0x72, 0x65, 0x20, 0x68, 0x6f, 0x77, 0x20, 0x69, 0x74, 0x20, 0x77, 0x61, 0x73, 0x0a, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x0a, 0x00, }; char doc_get_ps[431] = { 0x67, 0x65, 0x74, 0x5f, 0x70, 0x73, 0x28, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x60, 0x60, 0x50, 0x53, 0x69, 0x5f, 0x6d, 0x61, 0x60, 0x60, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x2a, 0x69, 0x2a, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x2a, 0x6d, 0x2a, 0x20, 0x61, 0x73, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x70, 0x73, 0x20, 0x3a, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x61, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x28, 0x2a, 0x69, 0x2a, 0x2c, 0x20, 0x2a, 0x6d, 0x2a, 0x2c, 0x20, 0x2a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0x29, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x69, 0x2a, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x2e, 0x20, 0x20, 0x41, 0x78, 0x69, 0x73, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2c, 0x20, 0x61, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x60, 0x60, 0x50, 0x53, 0x69, 0x5f, 0x6d, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x28, 0x69, 0x2e, 0x65, 0x2e, 0x20, 0x31, 0x2d, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x6d, 0x2a, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x2e, 0x20, 0x20, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2c, 0x20, 0x61, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x60, 0x60, 0x50, 0x53, 0x69, 0x5f, 0x6d, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x28, 0x69, 0x2e, 0x65, 0x2e, 0x20, 0x30, 0x2d, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0x3a, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x20, 0x20, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x5f, 0x70, 0x73, 0x20, 0x3a, 0x20, 0x53, 0x65, 0x74, 0x20, 0x60, 0x60, 0x50, 0x53, 0x69, 0x5f, 0x6d, 0x61, 0x60, 0x60, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x0a, 0x00, }; char doc_get_pv[741] = { 0x67, 0x65, 0x74, 0x5f, 0x70, 0x76, 0x28, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x60, 0x60, 0x50, 0x56, 0x69, 0x5f, 0x6d, 0x61, 0x60, 0x60, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x2a, 0x69, 0x2a, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x2a, 0x6d, 0x2a, 0x20, 0x61, 0x73, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x61, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x28, 0x2a, 0x69, 0x2a, 0x2c, 0x20, 0x2a, 0x6d, 0x2a, 0x2c, 0x20, 0x2a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0x29, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x69, 0x2a, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x2e, 0x20, 0x20, 0x41, 0x78, 0x69, 0x73, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2c, 0x20, 0x61, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x60, 0x60, 0x50, 0x56, 0x69, 0x5f, 0x6d, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x28, 0x69, 0x2e, 0x65, 0x2e, 0x20, 0x31, 0x2d, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x6d, 0x2a, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x2e, 0x20, 0x20, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2c, 0x20, 0x61, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x60, 0x60, 0x50, 0x56, 0x69, 0x5f, 0x6d, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x28, 0x69, 0x2e, 0x65, 0x2e, 0x20, 0x30, 0x2d, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0x3a, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x20, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x5f, 0x70, 0x76, 0x20, 0x3a, 0x20, 0x53, 0x65, 0x74, 0x20, 0x60, 0x60, 0x50, 0x56, 0x69, 0x5f, 0x6d, 0x61, 0x60, 0x60, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x0a, 0x0a, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x4e, 0x6f, 0x74, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x79, 0x20, 0x77, 0x65, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x2c, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x73, 0x0a, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x60, 0x60, 0x50, 0x56, 0x69, 0x5f, 0x31, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x50, 0x56, 0x69, 0x5f, 0x32, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x50, 0x56, 0x69, 0x5f, 0x33, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x60, 0x60, 0x50, 0x56, 0x69, 0x5f, 0x34, 0x61, 0x60, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x0a, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x2a, 0x69, 0x2a, 0x20, 0x74, 0x6f, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x28, 0x60, 0x60, 0x70, 0x68, 0x69, 0x5f, 0x30, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x74, 0x68, 0x65, 0x74, 0x61, 0x5f, 0x30, 0x60, 0x60, 0x29, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0a, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x62, 0x79, 0x20, 0x60, 0x60, 0x4c, 0x4f, 0x4e, 0x50, 0x4f, 0x4c, 0x45, 0x61, 0x60, 0x60, 0x0a, 0x61, 0x6e, 0x64, 0x20, 0x60, 0x60, 0x4c, 0x41, 0x54, 0x50, 0x4f, 0x4c, 0x45, 0x61, 0x60, 0x60, 0x2e, 0x0a, 0x00, }; char doc_has_cd[911] = { 0x68, 0x61, 0x73, 0x5f, 0x63, 0x64, 0x28, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x60, 0x54, 0x72, 0x75, 0x65, 0x60, 0x20, 0x69, 0x66, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x69, 0x73, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x2e, 0x0a, 0x0a, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x69, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2c, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x2e, 0x0a, 0x0a, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x52, 0x41, 0x46, 0x20, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x72, 0x65, 0x20, 0x65, 0x71, 0x75, 0x69, 0x76, 0x61, 0x6c, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x0a, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x20, 0x3d, 0x20, 0x43, 0x44, 0x45, 0x4c, 0x54, 0x69, 0x61, 0x20, 0x2a, 0x20, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x6f, 0x66, 0x0a, 0x74, 0x68, 0x65, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2e, 0x20, 0x20, 0x49, 0x66, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x0a, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x75, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x7a, 0x65, 0x72, 0x6f, 0x2e, 0x20, 0x20, 0x49, 0x66, 0x20, 0x6e, 0x6f, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x28, 0x6f, 0x72, 0x0a, 0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 0x60, 0x60, 0x29, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x69, 0x73, 0x20, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x69, 0x6e, 0x0a, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x77, 0x68, 0x65, 0x74, 0x68, 0x65, 0x72, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x0a, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x6e, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x60, 0x60, 0x43, 0x44, 0x45, 0x4c, 0x54, 0x69, 0x61, 0x60, 0x60, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x0a, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x20, 0x46, 0x49, 0x54, 0x53, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x0a, 0x57, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x63, 0x6f, 0x2d, 0x65, 0x78, 0x69, 0x73, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x6d, 0x61, 0x79, 0x0a, 0x63, 0x6f, 0x2d, 0x65, 0x78, 0x69, 0x73, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x60, 0x60, 0x43, 0x44, 0x45, 0x4c, 0x54, 0x69, 0x61, 0x60, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 0x60, 0x60, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x64, 0x20, 0x3a, 0x20, 0x47, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x61, 0x77, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x0a, 0x00, }; char doc_has_cdi_ja[103] = { 0x68, 0x61, 0x73, 0x5f, 0x63, 0x64, 0x69, 0x5f, 0x6a, 0x61, 0x28, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x0a, 0x0a, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x5f, 0x63, 0x64, 0x60, 0x2e, 0x20, 0x20, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x77, 0x61, 0x72, 0x64, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x2e, 0x0a, 0x00, }; char doc_has_crota[652] = { 0x68, 0x61, 0x73, 0x5f, 0x63, 0x72, 0x6f, 0x74, 0x61, 0x28, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x60, 0x54, 0x72, 0x75, 0x65, 0x60, 0x20, 0x69, 0x66, 0x20, 0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 0x60, 0x60, 0x20, 0x69, 0x73, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x2e, 0x0a, 0x0a, 0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 0x60, 0x60, 0x20, 0x69, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2c, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x41, 0x49, 0x50, 0x53, 0x20, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 0x60, 0x60, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x62, 0x65, 0x20, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x20, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x70, 0x61, 0x69, 0x72, 0x2e, 0x20, 0x20, 0x49, 0x74, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x73, 0x20, 0x61, 0x20, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x0a, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x69, 0x73, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x20, 0x2a, 0x61, 0x66, 0x74, 0x65, 0x72, 0x2a, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x60, 0x43, 0x44, 0x45, 0x4c, 0x54, 0x69, 0x61, 0x60, 0x60, 0x3b, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x0a, 0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 0x60, 0x60, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 0x60, 0x60, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x63, 0x6f, 0x2d, 0x65, 0x78, 0x69, 0x73, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x2e, 0x20, 0x20, 0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 0x60, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x60, 0x60, 0x43, 0x44, 0x45, 0x4c, 0x54, 0x69, 0x61, 0x60, 0x60, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x63, 0x6f, 0x2d, 0x65, 0x78, 0x69, 0x73, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x62, 0x75, 0x74, 0x20, 0x69, 0x66, 0x20, 0x73, 0x6f, 0x20, 0x61, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x0a, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x72, 0x6f, 0x74, 0x61, 0x20, 0x3a, 0x20, 0x47, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x61, 0x77, 0x20, 0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 0x60, 0x60, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x0a, 0x00, }; char doc_has_crotaia[107] = { 0x68, 0x61, 0x73, 0x5f, 0x63, 0x72, 0x6f, 0x74, 0x61, 0x69, 0x61, 0x28, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x0a, 0x0a, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x5f, 0x63, 0x72, 0x6f, 0x74, 0x61, 0x60, 0x2e, 0x20, 0x20, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x77, 0x61, 0x72, 0x64, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x2e, 0x0a, 0x00, }; char doc_has_pc[213] = { 0x68, 0x61, 0x73, 0x5f, 0x70, 0x63, 0x28, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x60, 0x54, 0x72, 0x75, 0x65, 0x60, 0x20, 0x69, 0x66, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x69, 0x73, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x2e, 0x20, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x77, 0x61, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x70, 0x63, 0x20, 0x3a, 0x20, 0x47, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x61, 0x77, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x0a, 0x00, }; char doc_has_pci_ja[103] = { 0x68, 0x61, 0x73, 0x5f, 0x70, 0x63, 0x69, 0x5f, 0x6a, 0x61, 0x28, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x0a, 0x0a, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x5f, 0x70, 0x63, 0x60, 0x2e, 0x20, 0x20, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x77, 0x61, 0x72, 0x64, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x2e, 0x0a, 0x00, }; char doc_hgln_obs[100] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x53, 0x74, 0x6f, 0x6e, 0x79, 0x68, 0x75, 0x72, 0x73, 0x74, 0x20, 0x68, 0x65, 0x6c, 0x69, 0x6f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x20, 0x49, 0x66, 0x0a, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x73, 0x65, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x4e, 0x6f, 0x6e, 0x65, 0x60, 0x2e, 0x0a, 0x00, }; char doc_hglt_obs[122] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x20, 0x48, 0x65, 0x6c, 0x69, 0x6f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x28, 0x43, 0x61, 0x72, 0x72, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x53, 0x74, 0x6f, 0x6e, 0x79, 0x68, 0x75, 0x72, 0x73, 0x74, 0x29, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x0a, 0x28, 0x64, 0x65, 0x67, 0x29, 0x2e, 0x20, 0x49, 0x66, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x73, 0x65, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x4e, 0x6f, 0x6e, 0x65, 0x60, 0x2e, 0x0a, 0x00, }; char doc_i[40] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2e, 0x0a, 0x00, }; char doc_imgpix_matrix[173] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x32, 0x5d, 0x5b, 0x32, 0x5d, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x49, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x60, 0x43, 0x44, 0x45, 0x4c, 0x54, 0x60, 0x60, 0x20, 0x6f, 0x72, 0x20, 0x60, 0x60, 0x50, 0x43, 0x60, 0x60, 0x0a, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x60, 0x43, 0x44, 0x45, 0x4c, 0x54, 0x69, 0x61, 0x60, 0x60, 0x20, 0x64, 0x69, 0x61, 0x67, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x74, 0x68, 0x65, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2e, 0x0a, 0x00, }; char doc_is_unity[109] = { 0x69, 0x73, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x28, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x60, 0x54, 0x72, 0x75, 0x65, 0x60, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x0a, 0x28, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x64, 0x60, 0x29, 0x20, 0x69, 0x73, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x2e, 0x0a, 0x00, }; char doc_jepoch[116] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x45, 0x71, 0x75, 0x69, 0x76, 0x61, 0x6c, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x60, 0x44, 0x41, 0x54, 0x45, 0x2d, 0x4f, 0x42, 0x53, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x61, 0x20, 0x4a, 0x75, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x64, 0x61, 0x74, 0x65, 0x6f, 0x62, 0x73, 0x0a, 0x00, }; char doc_kind[157] = { 0x60, 0x60, 0x73, 0x74, 0x72, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x60, 0x60, 0x77, 0x63, 0x73, 0x74, 0x61, 0x62, 0x60, 0x60, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x0a, 0x0a, 0x43, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x60, 0x77, 0x63, 0x73, 0x74, 0x61, 0x62, 0x60, 0x60, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x60, 0x27, 0x63, 0x27, 0x60, 0x60, 0x3a, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x60, 0x27, 0x69, 0x27, 0x60, 0x60, 0x3a, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x0a, 0x00, }; char doc_lat[86] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x54, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x0a, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x0a, 0x00, }; char doc_latpole[75] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x70, 0x6f, 0x6c, 0x65, 0x2c, 0x20, 0x60, 0x60, 0x4c, 0x41, 0x54, 0x50, 0x4f, 0x4c, 0x45, 0x61, 0x60, 0x60, 0x20, 0x28, 0x64, 0x65, 0x67, 0x29, 0x2e, 0x0a, 0x00, }; char doc_lattyp[236] = { 0x60, 0x60, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x43, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x2e, 0x0a, 0x0a, 0x46, 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x22, 0x52, 0x41, 0x22, 0x2c, 0x20, 0x22, 0x44, 0x45, 0x43, 0x22, 0x2c, 0x20, 0x22, 0x47, 0x4c, 0x4f, 0x4e, 0x22, 0x2c, 0x20, 0x22, 0x47, 0x4c, 0x41, 0x54, 0x22, 0x2c, 0x20, 0x65, 0x74, 0x63, 0x2e, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x22, 0x52, 0x41, 0x2d, 0x2d, 0x22, 0x2c, 0x0a, 0x22, 0x44, 0x45, 0x43, 0x2d, 0x22, 0x2c, 0x20, 0x22, 0x47, 0x4c, 0x4f, 0x4e, 0x22, 0x2c, 0x20, 0x22, 0x47, 0x4c, 0x41, 0x54, 0x22, 0x2c, 0x20, 0x65, 0x74, 0x63, 0x2e, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x72, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x20, 0x6f, 0x66, 0x0a, 0x60, 0x60, 0x43, 0x54, 0x59, 0x50, 0x45, 0x69, 0x61, 0x60, 0x60, 0x20, 0x62, 0x75, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x64, 0x61, 0x73, 0x68, 0x65, 0x73, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x2e, 0x0a, 0x00, }; char doc_lng[87] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x54, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x0a, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x0a, 0x00, }; char doc_lngtyp[237] = { 0x60, 0x60, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x43, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x2e, 0x0a, 0x0a, 0x46, 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x22, 0x52, 0x41, 0x22, 0x2c, 0x20, 0x22, 0x44, 0x45, 0x43, 0x22, 0x2c, 0x20, 0x22, 0x47, 0x4c, 0x4f, 0x4e, 0x22, 0x2c, 0x20, 0x22, 0x47, 0x4c, 0x41, 0x54, 0x22, 0x2c, 0x20, 0x65, 0x74, 0x63, 0x2e, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x22, 0x52, 0x41, 0x2d, 0x2d, 0x22, 0x2c, 0x0a, 0x22, 0x44, 0x45, 0x43, 0x2d, 0x22, 0x2c, 0x20, 0x22, 0x47, 0x4c, 0x4f, 0x4e, 0x22, 0x2c, 0x20, 0x22, 0x47, 0x4c, 0x41, 0x54, 0x22, 0x2c, 0x20, 0x65, 0x74, 0x63, 0x2e, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x72, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x20, 0x6f, 0x66, 0x0a, 0x60, 0x60, 0x43, 0x54, 0x59, 0x50, 0x45, 0x69, 0x61, 0x60, 0x60, 0x20, 0x62, 0x75, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x64, 0x61, 0x73, 0x68, 0x65, 0x73, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x2e, 0x0a, 0x00, }; char doc_lonpole[77] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x70, 0x6f, 0x6c, 0x65, 0x2e, 0x0a, 0x0a, 0x60, 0x60, 0x4c, 0x4f, 0x4e, 0x50, 0x4f, 0x4c, 0x45, 0x61, 0x60, 0x60, 0x20, 0x28, 0x64, 0x65, 0x67, 0x29, 0x2e, 0x0a, 0x00, }; char doc_m[63] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x60, 0x60, 0x77, 0x63, 0x73, 0x74, 0x61, 0x62, 0x60, 0x60, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x2e, 0x0a, 0x00, }; char doc_map[967] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x4d, 0x5d, 0x60, 0x60, 0x20, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x20, 0x61, 0x78, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x41, 0x20, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x54, 0x61, 0x62, 0x70, 0x72, 0x6d, 0x2e, 0x4d, 0x60, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x73, 0x0a, 0x74, 0x68, 0x65, 0x20, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x2a, 0x6d, 0x2a, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x2a, 0x4d, 0x2a, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x0a, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x28, 0x31, 0x20, 0x3c, 0x3d, 0x20, 0x2a, 0x6d, 0x2a, 0x20, 0x3c, 0x3d, 0x20, 0x2a, 0x4d, 0x2a, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x0a, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x73, 0x2e, 0x0a, 0x0a, 0x57, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2d, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2c, 0x20, 0x61, 0x73, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x75, 0x73, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x62, 0x65, 0x0a, 0x74, 0x68, 0x65, 0x20, 0x63, 0x61, 0x73, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x60, 0x60, 0x6d, 0x61, 0x70, 0x5b, 0x6d, 0x2d, 0x31, 0x5d, 0x20, 0x3d, 0x3d, 0x20, 0x69, 0x2d, 0x31, 0x60, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x2a, 0x69, 0x2a, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x2a, 0x4e, 0x2a, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x0a, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x28, 0x31, 0x20, 0x3c, 0x3d, 0x20, 0x2a, 0x69, 0x2a, 0x20, 0x3c, 0x3d, 0x20, 0x2a, 0x4e, 0x2a, 0x29, 0x2e, 0x20, 0x20, 0x49, 0x6e, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, 0x49, 0x54, 0x53, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x3a, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61, 0x70, 0x5b, 0x50, 0x56, 0x69, 0x5f, 0x33, 0x61, 0x20, 0x2d, 0x20, 0x31, 0x5d, 0x20, 0x3d, 0x3d, 0x20, 0x69, 0x20, 0x2d, 0x20, 0x31, 0x2e, 0x0a, 0x0a, 0x48, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, 0x20, 0x61, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x0a, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x2c, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x20, 0x61, 0x20, 0x28, 0x72, 0x65, 0x6c, 0x65, 0x76, 0x61, 0x6e, 0x74, 0x29, 0x20, 0x73, 0x75, 0x62, 0x73, 0x65, 0x74, 0x20, 0x6f, 0x66, 0x0a, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x20, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x2a, 0x4d, 0x2a, 0x20, 0x3d, 0x3d, 0x20, 0x31, 0x20, 0x66, 0x6f, 0x72, 0x0a, 0x61, 0x6e, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x2a, 0x4e, 0x2a, 0x20, 0x3e, 0x20, 0x31, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x70, 0x6f, 0x73, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x69, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x0a, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x6c, 0x65, 0x76, 0x61, 0x6e, 0x74, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x60, 0x60, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x60, 0x60, 0x20, 0x73, 0x65, 0x74, 0x20, 0x74, 0x6f, 0x0a, 0x31, 0x2e, 0x20, 0x20, 0x49, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x60, 0x60, 0x6d, 0x61, 0x70, 0x5b, 0x30, 0x5d, 0x20, 0x3d, 0x20, 0x30, 0x60, 0x60, 0x20, 0x72, 0x65, 0x67, 0x61, 0x72, 0x64, 0x6c, 0x65, 0x73, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x2a, 0x69, 0x2a, 0x2e, 0x0a, 0x00, }; char doc_mix[4851] = { 0x6d, 0x69, 0x78, 0x28, 0x6d, 0x69, 0x78, 0x70, 0x69, 0x78, 0x2c, 0x20, 0x6d, 0x69, 0x78, 0x63, 0x65, 0x6c, 0x2c, 0x20, 0x76, 0x73, 0x70, 0x61, 0x6e, 0x2c, 0x20, 0x76, 0x73, 0x74, 0x65, 0x70, 0x2c, 0x20, 0x76, 0x69, 0x74, 0x65, 0x72, 0x2c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2c, 0x20, 0x70, 0x69, 0x78, 0x63, 0x72, 0x64, 0x2c, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x29, 0x0a, 0x0a, 0x47, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x70, 0x6c, 0x75, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x0a, 0x74, 0x68, 0x65, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x2c, 0x20, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x62, 0x79, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x0a, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x32, 0x70, 0x60, 0x2e, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x6d, 0x69, 0x78, 0x70, 0x69, 0x78, 0x20, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x57, 0x68, 0x69, 0x63, 0x68, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x69, 0x73, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x2e, 0x0a, 0x0a, 0x6d, 0x69, 0x78, 0x63, 0x65, 0x6c, 0x20, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x57, 0x68, 0x69, 0x63, 0x68, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x69, 0x73, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x2e, 0x20, 0x49, 0x66, 0x20, 0x2a, 0x6d, 0x69, 0x78, 0x63, 0x65, 0x6c, 0x2a, 0x20, 0x3d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x60, 0x60, 0x31, 0x60, 0x60, 0x2c, 0x20, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x69, 0x73, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x60, 0x60, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x67, 0x5d, 0x60, 0x60, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x60, 0x60, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x61, 0x74, 0x5d, 0x60, 0x60, 0x2e, 0x20, 0x20, 0x49, 0x66, 0x20, 0x2a, 0x6d, 0x69, 0x78, 0x63, 0x65, 0x6c, 0x2a, 0x20, 0x3d, 0x20, 0x60, 0x60, 0x32, 0x60, 0x60, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x69, 0x73, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x60, 0x60, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x61, 0x74, 0x5d, 0x60, 0x60, 0x2c, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x60, 0x60, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x67, 0x5d, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x76, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x3a, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x2c, 0x20, 0x69, 0x6e, 0x20, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x77, 0x6f, 0x20, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x20, 0x69, 0x73, 0x20, 0x69, 0x72, 0x72, 0x65, 0x6c, 0x65, 0x76, 0x61, 0x6e, 0x74, 0x2e, 0x20, 0x20, 0x4c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x6e, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x60, 0x60, 0x28, 0x2d, 0x31, 0x32, 0x30, 0x2c, 0x2b, 0x31, 0x32, 0x30, 0x29, 0x60, 0x60, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x28, 0x32, 0x34, 0x30, 0x2c, 0x34, 0x38, 0x30, 0x29, 0x60, 0x60, 0x2c, 0x20, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x69, 0x2e, 0x65, 0x2e, 0x20, 0x6c, 0x69, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x76, 0x73, 0x74, 0x65, 0x70, 0x20, 0x3a, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x74, 0x65, 0x70, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2c, 0x20, 0x69, 0x6e, 0x20, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x49, 0x66, 0x20, 0x60, 0x60, 0x30, 0x60, 0x60, 0x2c, 0x20, 0x61, 0x20, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x70, 0x65, 0x72, 0x68, 0x61, 0x70, 0x73, 0x20, 0x6e, 0x6f, 0x6e, 0x2d, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x61, 0x6c, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x76, 0x69, 0x74, 0x65, 0x72, 0x20, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x66, 0x20, 0x61, 0x20, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x65, 0x70, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x68, 0x61, 0x6c, 0x76, 0x65, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x63, 0x65, 0x64, 0x2e, 0x20, 0x20, 0x2a, 0x76, 0x69, 0x74, 0x65, 0x72, 0x2a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x73, 0x20, 0x68, 0x6f, 0x77, 0x20, 0x6d, 0x61, 0x6e, 0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x65, 0x70, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x69, 0x73, 0x20, 0x68, 0x61, 0x6c, 0x76, 0x65, 0x64, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x69, 0x73, 0x20, 0x35, 0x20, 0x2d, 0x20, 0x31, 0x30, 0x2e, 0x0a, 0x0a, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x3a, 0x20, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x60, 0x60, 0x2e, 0x20, 0x20, 0x60, 0x60, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x67, 0x5d, 0x60, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x60, 0x60, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x61, 0x74, 0x5d, 0x60, 0x60, 0x20, 0x61, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x57, 0x68, 0x69, 0x63, 0x68, 0x20, 0x69, 0x73, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x66, 0x20, 0x2a, 0x6d, 0x69, 0x78, 0x63, 0x65, 0x6c, 0x2a, 0x2e, 0x20, 0x20, 0x41, 0x6c, 0x6c, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x69, 0x6e, 0x2d, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2e, 0x0a, 0x0a, 0x70, 0x69, 0x78, 0x63, 0x72, 0x64, 0x20, 0x3a, 0x20, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x60, 0x60, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x2a, 0x6d, 0x69, 0x78, 0x70, 0x69, 0x78, 0x2a, 0x20, 0x69, 0x73, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, 0x69, 0x6e, 0x2d, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2e, 0x0a, 0x0a, 0x0a, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x46, 0x6f, 0x72, 0x74, 0x72, 0x61, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x46, 0x49, 0x54, 0x53, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x73, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x31, 0x2e, 0x20, 0x20, 0x4e, 0x75, 0x6d, 0x70, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x43, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x69, 0x74, 0x68, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x61, 0x74, 0x20, 0x30, 0x2e, 0x0a, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x20, 0x3a, 0x20, 0x64, 0x69, 0x63, 0x74, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, 0x20, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x6b, 0x65, 0x79, 0x73, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x70, 0x68, 0x69, 0x2a, 0x20, 0x28, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x60, 0x60, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x74, 0x68, 0x65, 0x74, 0x61, 0x2a, 0x20, 0x28, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x60, 0x60, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x4c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x6f, 0x66, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x69, 0x6e, 0x20, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x69, 0x6d, 0x67, 0x63, 0x72, 0x64, 0x2a, 0x20, 0x28, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x60, 0x60, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x20, 0x20, 0x60, 0x60, 0x69, 0x6d, 0x67, 0x63, 0x72, 0x64, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x67, 0x5d, 0x60, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x60, 0x69, 0x6d, 0x67, 0x63, 0x72, 0x64, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x61, 0x74, 0x5d, 0x60, 0x60, 0x20, 0x61, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x2a, 0x78, 0x2a, 0x2d, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2a, 0x79, 0x2a, 0x2d, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x2c, 0x20, 0x69, 0x6e, 0x20, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x20, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2a, 0x20, 0x28, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x60, 0x60, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x41, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x2a, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2a, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x2e, 0x0a, 0x0a, 0x52, 0x61, 0x69, 0x73, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x53, 0x69, 0x6e, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x69, 0x73, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x41, 0x78, 0x69, 0x73, 0x54, 0x79, 0x70, 0x65, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x75, 0x6e, 0x72, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6c, 0x6c, 0x2d, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x2e, 0x0a, 0x0a, 0x4e, 0x6f, 0x53, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4e, 0x6f, 0x20, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x6c, 0x61, 0x74, 0x2c, 0x20, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x6c, 0x6e, 0x67, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x47, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x78, 0x65, 0x73, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x0a, 0x0a, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x20, 0x69, 0x73, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x65, 0x65, 0x20, 0x69, 0x66, 0x20, 0x69, 0x74, 0x27, 0x73, 0x20, 0x61, 0x0a, 0x22, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x22, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x2e, 0x20, 0x20, 0x49, 0x66, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x6e, 0x27, 0x74, 0x2c, 0x20, 0x61, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x69, 0x73, 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x0a, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x79, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x74, 0x0a, 0x74, 0x68, 0x65, 0x20, 0x75, 0x70, 0x70, 0x65, 0x72, 0x20, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x65, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x73, 0x74, 0x65, 0x70, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x2e, 0x20, 0x20, 0x41, 0x20, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x72, 0x69, 0x61, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x6f, 0x66, 0x0a, 0x74, 0x68, 0x65, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x74, 0x65, 0x70, 0x73, 0x20, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2e, 0x20, 0x20, 0x49, 0x66, 0x20, 0x61, 0x20, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x0a, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x20, 0x69, 0x73, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x0a, 0x6f, 0x66, 0x20, 0x22, 0x72, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x69, 0x22, 0x20, 0x64, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x2e, 0x20, 0x20, 0x49, 0x66, 0x20, 0x6e, 0x6f, 0x20, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x0a, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x20, 0x77, 0x61, 0x73, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x0a, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x69, 0x73, 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x22, 0x6e, 0x6f, 0x6e, 0x2d, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x22, 0x20, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x73, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x61, 0x72, 0x69, 0x73, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x0a, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x61, 0x6e, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x20, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x68, 0x61, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x6d, 0x61, 0x6b, 0x65, 0x0a, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x69, 0x74, 0x69, 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6d, 0x61, 0x70, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x0a, 0x0a, 0x4f, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x61, 0x73, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x73, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x62, 0x79, 0x0a, 0x73, 0x75, 0x62, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x6d, 0x69, 0x78, 0x60, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x73, 0x75, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x79, 0x0a, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x20, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x2e, 0x0a, 0x0a, 0x4e, 0x6f, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x69, 0x72, 0x63, 0x75, 0x6d, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x61, 0x72, 0x69, 0x73, 0x65, 0x73, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x6c, 0x69, 0x65, 0x73, 0x20, 0x61, 0x74, 0x20, 0x61, 0x0a, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x70, 0x6f, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x6f, 0x6c, 0x65, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x61, 0x0a, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x65, 0x20, 0x63, 0x75, 0x72, 0x76, 0x65, 0x2c, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x7a, 0x65, 0x6e, 0x69, 0x74, 0x68, 0x61, 0x6c, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x69, 0x63, 0x73, 0x2e, 0x20, 0x20, 0x49, 0x6e, 0x20, 0x73, 0x75, 0x63, 0x68, 0x20, 0x63, 0x61, 0x73, 0x65, 0x73, 0x20, 0x74, 0x77, 0x6f, 0x0a, 0x6f, 0x72, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x20, 0x62, 0x75, 0x74, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x6d, 0x69, 0x78, 0x60, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x0a, 0x65, 0x76, 0x65, 0x72, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x6f, 0x6e, 0x65, 0x2e, 0x0a, 0x0a, 0x42, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x74, 0x73, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2c, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x6d, 0x69, 0x78, 0x60, 0x20, 0x69, 0x73, 0x20, 0x76, 0x65, 0x72, 0x79, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x2d, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x2e, 0x20, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x2d, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x65, 0x66, 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x0a, 0x73, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x2d, 0x63, 0x61, 0x73, 0x65, 0x20, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x73, 0x20, 0x63, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x66, 0x6f, 0x72, 0x0a, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x6e, 0x2d, 0x6f, 0x62, 0x6c, 0x69, 0x71, 0x75, 0x65, 0x20, 0x63, 0x79, 0x6c, 0x69, 0x6e, 0x64, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x0a, 0x00, }; char doc_mjdavg[181] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x4a, 0x75, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x61, 0x74, 0x65, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x60, 0x44, 0x41, 0x54, 0x45, 0x2d, 0x41, 0x56, 0x47, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x60, 0x60, 0x28, 0x4d, 0x4a, 0x44, 0x20, 0x3d, 0x20, 0x4a, 0x44, 0x20, 0x2d, 0x20, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2e, 0x35, 0x29, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x41, 0x6e, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x4e, 0x61, 0x4e, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x6d, 0x6a, 0x64, 0x6f, 0x62, 0x73, 0x0a, 0x00, }; char doc_mjdbeg[181] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x4a, 0x75, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x61, 0x74, 0x65, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x60, 0x44, 0x41, 0x54, 0x45, 0x2d, 0x42, 0x45, 0x47, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x60, 0x60, 0x28, 0x4d, 0x4a, 0x44, 0x20, 0x3d, 0x20, 0x4a, 0x44, 0x20, 0x2d, 0x20, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2e, 0x35, 0x29, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x41, 0x6e, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x4e, 0x61, 0x4e, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x6d, 0x6a, 0x64, 0x62, 0x65, 0x67, 0x0a, 0x00, }; char doc_mjdend[181] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x4a, 0x75, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x61, 0x74, 0x65, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x60, 0x44, 0x41, 0x54, 0x45, 0x2d, 0x45, 0x4e, 0x44, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x60, 0x60, 0x28, 0x4d, 0x4a, 0x44, 0x20, 0x3d, 0x20, 0x4a, 0x44, 0x20, 0x2d, 0x20, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2e, 0x35, 0x29, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x41, 0x6e, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x4e, 0x61, 0x4e, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x6d, 0x6a, 0x64, 0x65, 0x6e, 0x64, 0x0a, 0x00, }; char doc_mjdobs[181] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x4a, 0x75, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x61, 0x74, 0x65, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x60, 0x44, 0x41, 0x54, 0x45, 0x2d, 0x4f, 0x42, 0x53, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x60, 0x60, 0x28, 0x4d, 0x4a, 0x44, 0x20, 0x3d, 0x20, 0x4a, 0x44, 0x20, 0x2d, 0x20, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2e, 0x35, 0x29, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x41, 0x6e, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x4e, 0x61, 0x4e, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x6d, 0x6a, 0x64, 0x61, 0x76, 0x67, 0x0a, 0x00, }; char doc_mjdref[182] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x4a, 0x75, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x61, 0x74, 0x65, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x60, 0x44, 0x41, 0x54, 0x45, 0x2d, 0x52, 0x45, 0x46, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x60, 0x60, 0x28, 0x4d, 0x4a, 0x44, 0x20, 0x3d, 0x20, 0x4a, 0x44, 0x20, 0x2d, 0x20, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2e, 0x35, 0x29, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x41, 0x6e, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x4e, 0x61, 0x4e, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x64, 0x61, 0x74, 0x65, 0x72, 0x65, 0x66, 0x0a, 0x00, }; char doc_name[74] = { 0x60, 0x60, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x60, 0x60, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x60, 0x60, 0x57, 0x43, 0x53, 0x4e, 0x41, 0x4d, 0x45, 0x61, 0x60, 0x60, 0x2e, 0x0a, 0x00, }; char doc_naxis[761] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x78, 0x65, 0x73, 0x20, 0x28, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x29, 0x2e, 0x0a, 0x0a, 0x47, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x60, 0x4e, 0x41, 0x58, 0x49, 0x53, 0x60, 0x60, 0x20, 0x6f, 0x72, 0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 0x41, 0x58, 0x45, 0x53, 0x61, 0x60, 0x60, 0x20, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x78, 0x65, 0x73, 0x20, 0x69, 0x73, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x61, 0x74, 0x20, 0x70, 0x61, 0x72, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x61, 0x6e, 0x0a, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x20, 0x73, 0x75, 0x62, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x49, 0x74, 0x20, 0x69, 0x73, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x31, 0x2e, 0x20, 0x60, 0x60, 0x4e, 0x41, 0x58, 0x49, 0x53, 0x60, 0x60, 0x0a, 0x0a, 0x20, 0x20, 0x32, 0x2e, 0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 0x41, 0x58, 0x45, 0x53, 0x61, 0x60, 0x60, 0x0a, 0x0a, 0x20, 0x20, 0x33, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x57, 0x43, 0x53, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x20, 0x61, 0x73, 0x20, 0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x2c, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x77, 0x69, 0x73, 0x65, 0x20, 0x69, 0x74, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x49, 0x66, 0x20, 0x6e, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x2c, 0x20, 0x69, 0x2e, 0x65, 0x2e, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x20, 0x61, 0x75, 0x78, 0x69, 0x6c, 0x69, 0x61, 0x72, 0x79, 0x20, 0x57, 0x43, 0x53, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x0a, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6e, 0x6f, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x74, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x69, 0x73, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x0a, 0x00, }; char doc_nc[172] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x2e, 0x0a, 0x0a, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x20, 0x4b, 0x5f, 0x31, 0x20, 0x2a, 0x20, 0x4b, 0x5f, 0x32, 0x20, 0x2a, 0x20, 0x2e, 0x2e, 0x2e, 0x20, 0x2a, 0x20, 0x4b, 0x5f, 0x4d, 0x2e, 0x0a, 0x00, }; char doc_ndim[70] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x60, 0x77, 0x63, 0x73, 0x74, 0x61, 0x62, 0x60, 0x60, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x2e, 0x0a, 0x00, }; char doc_obsgeo[187] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x33, 0x5d, 0x60, 0x60, 0x20, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x74, 0x65, 0x72, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x61, 0x6c, 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x2e, 0x0a, 0x0a, 0x60, 0x60, 0x4f, 0x42, 0x53, 0x47, 0x45, 0x4f, 0x2d, 0x58, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x4f, 0x42, 0x53, 0x47, 0x45, 0x4f, 0x2d, 0x59, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x4f, 0x42, 0x53, 0x47, 0x45, 0x4f, 0x2d, 0x5a, 0x60, 0x60, 0x20, 0x28, 0x69, 0x6e, 0x20, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x29, 0x2e, 0x0a, 0x0a, 0x41, 0x6e, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x4e, 0x61, 0x4e, 0x2e, 0x0a, 0x00, }; char doc_obsorbit[155] = { 0x60, 0x60, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x60, 0x60, 0x20, 0x55, 0x52, 0x49, 0x2c, 0x20, 0x55, 0x52, 0x4c, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x72, 0x62, 0x69, 0x74, 0x20, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x69, 0x73, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x67, 0x69, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x63, 0x72, 0x61, 0x66, 0x74, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x54, 0x52, 0x45, 0x46, 0x50, 0x4f, 0x53, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x74, 0x72, 0x65, 0x66, 0x70, 0x6f, 0x73, 0x0a, 0x0a, 0x00, }; char doc_p0[244] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x4d, 0x5d, 0x60, 0x60, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x2e, 0x0a, 0x0a, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x54, 0x61, 0x62, 0x70, 0x72, 0x6d, 0x2e, 0x4d, 0x60, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x0a, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x73, 0x75, 0x63, 0x68, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x55, 0x70, 0x73, 0x69, 0x6c, 0x6f, 0x6e, 0x5f, 0x6d, 0x2c, 0x20, 0x61, 0x73, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x0a, 0x50, 0x61, 0x70, 0x65, 0x72, 0x20, 0x49, 0x49, 0x49, 0x2c, 0x20, 0x69, 0x73, 0x20, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x60, 0x28, 0x70, 0x30, 0x5b, 0x6d, 0x5d, 0x20, 0x2b, 0x20, 0x31, 0x29, 0x20, 0x2b, 0x20, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5b, 0x6d, 0x5d, 0x60, 0x60, 0x2e, 0x0a, 0x00, }; char doc_p2s[2113] = { 0x70, 0x32, 0x73, 0x28, 0x70, 0x69, 0x78, 0x63, 0x72, 0x64, 0x2c, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x29, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x73, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x70, 0x69, 0x78, 0x63, 0x72, 0x64, 0x20, 0x3a, 0x20, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x5b, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x5d, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x0a, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x46, 0x6f, 0x72, 0x74, 0x72, 0x61, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x46, 0x49, 0x54, 0x53, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x73, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x31, 0x2e, 0x20, 0x20, 0x4e, 0x75, 0x6d, 0x70, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x43, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x69, 0x74, 0x68, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x61, 0x74, 0x20, 0x30, 0x2e, 0x0a, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x20, 0x3a, 0x20, 0x64, 0x69, 0x63, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, 0x20, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x6b, 0x65, 0x79, 0x73, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x69, 0x6d, 0x67, 0x63, 0x72, 0x64, 0x2a, 0x3a, 0x20, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x5b, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x5d, 0x60, 0x60, 0x2e, 0x20, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x65, 0x73, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x60, 0x69, 0x6d, 0x67, 0x63, 0x72, 0x64, 0x5b, 0x5d, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x67, 0x5d, 0x60, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x60, 0x60, 0x69, 0x6d, 0x67, 0x63, 0x72, 0x64, 0x5b, 0x5d, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x61, 0x74, 0x5d, 0x60, 0x60, 0x20, 0x61, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x2a, 0x78, 0x2a, 0x2d, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x2a, 0x79, 0x2a, 0x2d, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x2c, 0x20, 0x69, 0x6e, 0x20, 0x70, 0x73, 0x65, 0x75, 0x64, 0x6f, 0x20, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x46, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x65, 0x73, 0x2c, 0x20, 0x60, 0x60, 0x69, 0x6d, 0x67, 0x63, 0x72, 0x64, 0x5b, 0x5d, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x73, 0x70, 0x65, 0x63, 0x5d, 0x60, 0x60, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x2c, 0x20, 0x69, 0x6e, 0x20, 0x53, 0x49, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x70, 0x68, 0x69, 0x2a, 0x3a, 0x20, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x74, 0x68, 0x65, 0x74, 0x61, 0x2a, 0x3a, 0x20, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x4c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x69, 0x6e, 0x20, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2a, 0x3a, 0x20, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x5b, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x5d, 0x60, 0x60, 0x2e, 0x20, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x65, 0x73, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x60, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5b, 0x5d, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x67, 0x5d, 0x60, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x60, 0x60, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5b, 0x5d, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x61, 0x74, 0x5d, 0x60, 0x60, 0x20, 0x61, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x6e, 0x20, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x73, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x78, 0x65, 0x73, 0x2c, 0x20, 0x60, 0x60, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5b, 0x5d, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x73, 0x70, 0x65, 0x63, 0x5d, 0x60, 0x60, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x2c, 0x20, 0x69, 0x6e, 0x20, 0x53, 0x49, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x73, 0x74, 0x61, 0x74, 0x2a, 0x3a, 0x20, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x60, 0x60, 0x2e, 0x20, 0x60, 0x60, 0x30, 0x60, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x60, 0x31, 0x2b, 0x60, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x2e, 0x0a, 0x0a, 0x52, 0x61, 0x69, 0x73, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x53, 0x69, 0x6e, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x69, 0x73, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x41, 0x78, 0x69, 0x73, 0x54, 0x79, 0x70, 0x65, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x75, 0x6e, 0x72, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x0a, 0x0a, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2a, 0x78, 0x2a, 0x2d, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x2a, 0x79, 0x2a, 0x2d, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6c, 0x6c, 0x2d, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x6c, 0x61, 0x74, 0x2c, 0x20, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x6c, 0x6e, 0x67, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 0x78, 0x65, 0x73, 0x0a, 0x00, }; char doc_p4_pix2foc[682] = { 0x70, 0x34, 0x5f, 0x70, 0x69, 0x78, 0x32, 0x66, 0x6f, 0x63, 0x28, 0x2a, 0x70, 0x69, 0x78, 0x63, 0x72, 0x64, 0x2c, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x2a, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x5b, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x5d, 0x60, 0x60, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x60, 0x64, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x70, 0x61, 0x70, 0x65, 0x72, 0x60, 0x5f, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x2d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x70, 0x69, 0x78, 0x63, 0x72, 0x64, 0x20, 0x3a, 0x20, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x5b, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x5d, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x0a, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x46, 0x6f, 0x72, 0x74, 0x72, 0x61, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x46, 0x49, 0x54, 0x53, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x73, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x31, 0x2e, 0x20, 0x20, 0x4e, 0x75, 0x6d, 0x70, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x43, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x69, 0x74, 0x68, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x61, 0x74, 0x20, 0x30, 0x2e, 0x0a, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x66, 0x6f, 0x63, 0x63, 0x72, 0x64, 0x20, 0x3a, 0x20, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x66, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x5b, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x5d, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x52, 0x61, 0x69, 0x73, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x0a, 0x00, }; char doc_pc[1126] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x5b, 0x6e, 0x61, 0x78, 0x69, 0x73, 0x5d, 0x60, 0x60, 0x20, 0x54, 0x68, 0x65, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x28, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x29, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x20, 0x69, 0x73, 0x3a, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x5b, 0x5b, 0x50, 0x43, 0x31, 0x5f, 0x31, 0x2c, 0x20, 0x50, 0x43, 0x31, 0x5f, 0x32, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x5b, 0x50, 0x43, 0x32, 0x5f, 0x31, 0x2c, 0x20, 0x50, 0x43, 0x32, 0x5f, 0x32, 0x5d, 0x5d, 0x0a, 0x0a, 0x46, 0x6f, 0x72, 0x20, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x2c, 0x20, 0x74, 0x68, 0x72, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x77, 0x63, 0x73, 0x6c, 0x69, 0x62, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x0a, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x60, 0x60, 0x43, 0x44, 0x45, 0x4c, 0x54, 0x69, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x0a, 0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 0x60, 0x60, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x2e, 0x20, 0x20, 0x41, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x63, 0x6f, 0x2d, 0x65, 0x78, 0x69, 0x73, 0x74, 0x0a, 0x77, 0x69, 0x74, 0x68, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x61, 0x63, 0x68, 0x20, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x20, 0x69, 0x66, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x0a, 0x69, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x6a, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x5f, 0x70, 0x63, 0x60, 0x2c, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x5f, 0x63, 0x64, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x5f, 0x63, 0x72, 0x6f, 0x74, 0x61, 0x60, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x6f, 0x66, 0x0a, 0x74, 0x68, 0x65, 0x73, 0x65, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x73, 0x65, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x61, 0x72, 0x65, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x6c, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x62, 0x79, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x2d, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x20, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x49, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x2c, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x73, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x64, 0x65, 0x6c, 0x74, 0x60, 0x20, 0x74, 0x6f, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x0a, 0x69, 0x66, 0x20, 0x60, 0x60, 0x43, 0x44, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x69, 0x73, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x28, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x29, 0x2e, 0x20, 0x20, 0x49, 0x66, 0x20, 0x6e, 0x6f, 0x20, 0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x69, 0x61, 0x60, 0x60, 0x20, 0x69, 0x73, 0x0a, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x2c, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x73, 0x0a, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2e, 0x0a, 0x00, }; char doc_phi0[289] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x64, 0x75, 0x63, 0x69, 0x61, 0x6c, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x77, 0x68, 0x6f, 0x73, 0x65, 0x20, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x60, 0x60, 0x72, 0x65, 0x66, 0x5b, 0x31, 0x3a, 0x32, 0x5d, 0x60, 0x60, 0x2e, 0x20, 0x20, 0x49, 0x66, 0x0a, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x28, 0x4e, 0x61, 0x4e, 0x29, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x2c, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x2c, 0x0a, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x73, 0x65, 0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x61, 0x30, 0x0a, 0x00, }; char doc_pix2foc[667] = { 0x70, 0x69, 0x78, 0x32, 0x66, 0x6f, 0x63, 0x28, 0x2a, 0x70, 0x69, 0x78, 0x63, 0x72, 0x64, 0x2c, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x2a, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x5b, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x5d, 0x60, 0x60, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x62, 0x6f, 0x74, 0x68, 0x20, 0x60, 0x53, 0x49, 0x50, 0x60, 0x5f, 0x20, 0x70, 0x6f, 0x6c, 0x79, 0x6e, 0x6f, 0x6d, 0x69, 0x61, 0x6c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x60, 0x64, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x70, 0x65, 0x72, 0x60, 0x5f, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x2d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x0a, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x2e, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x70, 0x69, 0x78, 0x63, 0x72, 0x64, 0x20, 0x3a, 0x20, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x5b, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x5d, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x0a, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x46, 0x6f, 0x72, 0x74, 0x72, 0x61, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x46, 0x49, 0x54, 0x53, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x73, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x31, 0x2e, 0x20, 0x20, 0x4e, 0x75, 0x6d, 0x70, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x43, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x69, 0x74, 0x68, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x61, 0x74, 0x20, 0x30, 0x2e, 0x0a, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x66, 0x6f, 0x63, 0x63, 0x72, 0x64, 0x20, 0x3a, 0x20, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x66, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x5b, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x5d, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x52, 0x61, 0x69, 0x73, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x0a, 0x00, }; char doc_piximg_matrix[128] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x32, 0x5d, 0x5b, 0x32, 0x5d, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x20, 0x6f, 0x66, 0x0a, 0x74, 0x68, 0x65, 0x20, 0x60, 0x60, 0x43, 0x44, 0x45, 0x4c, 0x54, 0x69, 0x61, 0x60, 0x60, 0x20, 0x64, 0x69, 0x61, 0x67, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2e, 0x0a, 0x00, }; char doc_plephem[126] = { 0x60, 0x60, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x60, 0x60, 0x20, 0x54, 0x68, 0x65, 0x20, 0x53, 0x6f, 0x6c, 0x61, 0x72, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x69, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x63, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x70, 0x61, 0x74, 0x68, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x70, 0x6c, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x0a, 0x00, }; char doc_print_contents[210] = { 0x70, 0x72, 0x69, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x28, 0x29, 0x0a, 0x0a, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x60, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x2e, 0x0a, 0x50, 0x72, 0x6f, 0x62, 0x61, 0x62, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x75, 0x73, 0x65, 0x66, 0x75, 0x6c, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x64, 0x65, 0x62, 0x75, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x20, 0x70, 0x75, 0x72, 0x70, 0x6f, 0x73, 0x65, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x2e, 0x0a, 0x0a, 0x54, 0x6f, 0x20, 0x67, 0x65, 0x74, 0x20, 0x61, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2c, 0x20, 0x75, 0x73, 0x65, 0x20, 0x60, 0x72, 0x65, 0x70, 0x72, 0x60, 0x2e, 0x0a, 0x00, }; char doc_print_contents_tabprm[211] = { 0x70, 0x72, 0x69, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x28, 0x29, 0x0a, 0x0a, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x54, 0x61, 0x62, 0x70, 0x72, 0x6d, 0x60, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x0a, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x2e, 0x20, 0x20, 0x50, 0x72, 0x6f, 0x62, 0x61, 0x62, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x75, 0x73, 0x65, 0x66, 0x75, 0x6c, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x64, 0x65, 0x62, 0x75, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x20, 0x70, 0x75, 0x72, 0x70, 0x6f, 0x73, 0x65, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x0a, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x2e, 0x0a, 0x0a, 0x54, 0x6f, 0x20, 0x67, 0x65, 0x74, 0x20, 0x61, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2c, 0x20, 0x75, 0x73, 0x65, 0x20, 0x60, 0x72, 0x65, 0x70, 0x72, 0x60, 0x2e, 0x0a, 0x00, }; char doc_print_contents_wtbarr[210] = { 0x70, 0x72, 0x69, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x28, 0x29, 0x0a, 0x0a, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x74, 0x62, 0x61, 0x72, 0x72, 0x60, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x0a, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x2e, 0x20, 0x50, 0x72, 0x6f, 0x62, 0x61, 0x62, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x75, 0x73, 0x65, 0x66, 0x75, 0x6c, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x64, 0x65, 0x62, 0x75, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x20, 0x70, 0x75, 0x72, 0x70, 0x6f, 0x73, 0x65, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x0a, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x2e, 0x0a, 0x0a, 0x54, 0x6f, 0x20, 0x67, 0x65, 0x74, 0x20, 0x61, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2c, 0x20, 0x75, 0x73, 0x65, 0x20, 0x60, 0x72, 0x65, 0x70, 0x72, 0x60, 0x2e, 0x0a, 0x00, }; char doc_radesys[77] = { 0x60, 0x60, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x60, 0x60, 0x20, 0x54, 0x68, 0x65, 0x20, 0x65, 0x71, 0x75, 0x61, 0x74, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x20, 0x6f, 0x72, 0x20, 0x65, 0x63, 0x6c, 0x69, 0x70, 0x74, 0x69, 0x63, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x0a, 0x60, 0x60, 0x52, 0x41, 0x44, 0x45, 0x53, 0x59, 0x53, 0x61, 0x60, 0x60, 0x2e, 0x0a, 0x00, }; char doc_restfrq[94] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x52, 0x65, 0x73, 0x74, 0x20, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x20, 0x28, 0x48, 0x7a, 0x29, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x60, 0x60, 0x52, 0x45, 0x53, 0x54, 0x46, 0x52, 0x51, 0x61, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x41, 0x6e, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x4e, 0x61, 0x4e, 0x2e, 0x0a, 0x00, }; char doc_restwav[94] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x52, 0x65, 0x73, 0x74, 0x20, 0x77, 0x61, 0x76, 0x65, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x28, 0x6d, 0x29, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x60, 0x60, 0x52, 0x45, 0x53, 0x54, 0x57, 0x41, 0x56, 0x61, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x41, 0x6e, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x4e, 0x61, 0x4e, 0x2e, 0x0a, 0x00, }; char doc_row[39] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x72, 0x6f, 0x77, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2e, 0x0a, 0x00, }; char doc_rsun_ref[114] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x53, 0x75, 0x6e, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x63, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x28, 0x6d, 0x29, 0x2e, 0x0a, 0x49, 0x66, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x73, 0x65, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x4e, 0x6f, 0x6e, 0x65, 0x60, 0x2e, 0x0a, 0x00, }; char doc_s2p[1946] = { 0x73, 0x32, 0x70, 0x28, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2c, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x29, 0x0a, 0x0a, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x3a, 0x20, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x2c, 0x20, 0x69, 0x6e, 0x20, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x20, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x5b, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x5d, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x0a, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x46, 0x6f, 0x72, 0x74, 0x72, 0x61, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x46, 0x49, 0x54, 0x53, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x73, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x31, 0x2e, 0x20, 0x20, 0x4e, 0x75, 0x6d, 0x70, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x43, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x69, 0x74, 0x68, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x61, 0x74, 0x20, 0x30, 0x2e, 0x0a, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x20, 0x3a, 0x20, 0x64, 0x69, 0x63, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, 0x20, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x6b, 0x65, 0x79, 0x73, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x70, 0x68, 0x69, 0x2a, 0x3a, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x60, 0x60, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x74, 0x68, 0x65, 0x74, 0x61, 0x2a, 0x3a, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x60, 0x60, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x4c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x6f, 0x66, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x69, 0x6e, 0x20, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x69, 0x6d, 0x67, 0x63, 0x72, 0x64, 0x2a, 0x3a, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x5b, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x5d, 0x60, 0x60, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x65, 0x73, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x60, 0x69, 0x6d, 0x67, 0x63, 0x72, 0x64, 0x5b, 0x5d, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x67, 0x5d, 0x60, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x60, 0x60, 0x69, 0x6d, 0x67, 0x63, 0x72, 0x64, 0x5b, 0x5d, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x61, 0x74, 0x5d, 0x60, 0x60, 0x20, 0x61, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x2a, 0x78, 0x2a, 0x2d, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x2a, 0x79, 0x2a, 0x2d, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x2c, 0x20, 0x69, 0x6e, 0x20, 0x70, 0x73, 0x65, 0x75, 0x64, 0x6f, 0x20, 0x22, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x73, 0x22, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x71, 0x75, 0x61, 0x64, 0x63, 0x75, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, 0x60, 0x60, 0x43, 0x55, 0x42, 0x45, 0x46, 0x41, 0x43, 0x45, 0x60, 0x60, 0x20, 0x61, 0x78, 0x69, 0x73, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x61, 0x63, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x69, 0x73, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x60, 0x60, 0x69, 0x6d, 0x67, 0x63, 0x72, 0x64, 0x5b, 0x5d, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x75, 0x62, 0x65, 0x66, 0x61, 0x63, 0x65, 0x5d, 0x60, 0x60, 0x2e, 0x20, 0x20, 0x46, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x65, 0x73, 0x2c, 0x20, 0x60, 0x60, 0x69, 0x6d, 0x67, 0x63, 0x72, 0x64, 0x5b, 0x5d, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x73, 0x70, 0x65, 0x63, 0x5d, 0x60, 0x60, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x2c, 0x20, 0x69, 0x6e, 0x20, 0x53, 0x49, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x70, 0x69, 0x78, 0x63, 0x72, 0x64, 0x2a, 0x3a, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x5b, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x5d, 0x60, 0x60, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7a, 0x65, 0x72, 0x6f, 0x2d, 0x62, 0x61, 0x73, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x73, 0x74, 0x61, 0x74, 0x2a, 0x3a, 0x20, 0x60, 0x60, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x60, 0x60, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x2e, 0x20, 0x60, 0x60, 0x30, 0x60, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x60, 0x31, 0x2b, 0x60, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x2e, 0x0a, 0x0a, 0x52, 0x61, 0x69, 0x73, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x53, 0x69, 0x6e, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x69, 0x73, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x41, 0x78, 0x69, 0x73, 0x54, 0x79, 0x70, 0x65, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x75, 0x6e, 0x72, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6c, 0x6c, 0x2d, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x6c, 0x61, 0x74, 0x2c, 0x20, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x6c, 0x6e, 0x67, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 0x78, 0x65, 0x73, 0x0a, 0x00, }; char doc_sense[232] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x4d, 0x5d, 0x60, 0x60, 0x20, 0x2b, 0x31, 0x20, 0x69, 0x66, 0x20, 0x6d, 0x6f, 0x6e, 0x6f, 0x74, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x61, 0x73, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x2d, 0x31, 0x20, 0x69, 0x66, 0x20, 0x64, 0x65, 0x63, 0x72, 0x65, 0x61, 0x73, 0x69, 0x6e, 0x67, 0x2e, 0x0a, 0x0a, 0x41, 0x20, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x54, 0x61, 0x62, 0x70, 0x72, 0x6d, 0x2e, 0x4d, 0x60, 0x20, 0x77, 0x68, 0x6f, 0x73, 0x65, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x0a, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x77, 0x68, 0x65, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x69, 0x73, 0x20, 0x6d, 0x6f, 0x6e, 0x6f, 0x74, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x0a, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x61, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x28, 0x2b, 0x31, 0x29, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x64, 0x65, 0x63, 0x72, 0x65, 0x61, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x28, 0x2d, 0x31, 0x29, 0x2e, 0x0a, 0x00, }; char doc_set[1206] = { 0x73, 0x65, 0x74, 0x28, 0x29, 0x0a, 0x0a, 0x53, 0x65, 0x74, 0x73, 0x20, 0x75, 0x70, 0x20, 0x61, 0x20, 0x57, 0x43, 0x53, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x0a, 0x69, 0x74, 0x2e, 0x0a, 0x0a, 0x4e, 0x6f, 0x74, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x20, 0x6e, 0x65, 0x65, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6c, 0x79, 0x3b, 0x20, 0x69, 0x74, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x69, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x0a, 0x62, 0x79, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x70, 0x32, 0x73, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x32, 0x70, 0x60, 0x20, 0x69, 0x66, 0x0a, 0x6e, 0x65, 0x63, 0x65, 0x73, 0x73, 0x61, 0x72, 0x79, 0x2e, 0x0a, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x61, 0x72, 0x65, 0x20, 0x62, 0x61, 0x73, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x20, 0x28, 0x73, 0x75, 0x63, 0x68, 0x20, 0x61, 0x73, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x6c, 0x61, 0x74, 0x74, 0x79, 0x70, 0x60, 0x20, 0x6f, 0x6e, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x74, 0x79, 0x70, 0x65, 0x60, 0x29, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x6e, 0x6f, 0x74, 0x0a, 0x62, 0x65, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 0x69, 0x73, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x73, 0x20, 0x6f, 0x66, 0x66, 0x20, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x0a, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x2e, 0x0a, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, 0x7a, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x60, 0x4e, 0x43, 0x50, 0x60, 0x60, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x73, 0x20, 0x69, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x71, 0x75, 0x69, 0x76, 0x61, 0x6c, 0x65, 0x6e, 0x74, 0x20, 0x60, 0x60, 0x53, 0x49, 0x4e, 0x60, 0x60, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x69, 0x74, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x72, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, 0x7a, 0x65, 0x73, 0x20, 0x60, 0x60, 0x47, 0x4c, 0x53, 0x60, 0x60, 0x20, 0x61, 0x73, 0x20, 0x61, 0x20, 0x73, 0x79, 0x6e, 0x6f, 0x6e, 0x79, 0x6d, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x60, 0x60, 0x53, 0x46, 0x4c, 0x60, 0x60, 0x2e, 0x20, 0x20, 0x49, 0x74, 0x20, 0x64, 0x6f, 0x65, 0x73, 0x20, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x41, 0x49, 0x50, 0x53, 0x20, 0x73, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x28, 0x60, 0x60, 0x46, 0x52, 0x45, 0x51, 0x2d, 0x4c, 0x53, 0x52, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x46, 0x45, 0x4c, 0x4f, 0x2d, 0x48, 0x45, 0x4c, 0x60, 0x60, 0x2c, 0x0a, 0x65, 0x74, 0x63, 0x2e, 0x29, 0x20, 0x62, 0x75, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x2e, 0x0a, 0x0a, 0x52, 0x61, 0x69, 0x73, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x53, 0x69, 0x6e, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x69, 0x73, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x41, 0x78, 0x69, 0x73, 0x54, 0x79, 0x70, 0x65, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x75, 0x6e, 0x72, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6c, 0x6c, 0x2d, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x0a, 0x00, }; char doc_set_ps[413] = { 0x73, 0x65, 0x74, 0x5f, 0x70, 0x73, 0x28, 0x70, 0x73, 0x29, 0x0a, 0x0a, 0x53, 0x65, 0x74, 0x73, 0x20, 0x60, 0x60, 0x50, 0x53, 0x69, 0x5f, 0x6d, 0x61, 0x60, 0x60, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x2a, 0x69, 0x2a, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x2a, 0x6d, 0x2a, 0x2e, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x70, 0x73, 0x20, 0x3a, 0x20, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x28, 0x2a, 0x69, 0x2a, 0x2c, 0x20, 0x2a, 0x6d, 0x2a, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0x29, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x69, 0x2a, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x2e, 0x20, 0x20, 0x41, 0x78, 0x69, 0x73, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2c, 0x20, 0x61, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x60, 0x60, 0x50, 0x53, 0x69, 0x5f, 0x6d, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x28, 0x69, 0x2e, 0x65, 0x2e, 0x20, 0x31, 0x2d, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x6d, 0x2a, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x2e, 0x20, 0x20, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2c, 0x20, 0x61, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x60, 0x60, 0x50, 0x53, 0x69, 0x5f, 0x6d, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x28, 0x69, 0x2e, 0x65, 0x2e, 0x20, 0x30, 0x2d, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0x3a, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x20, 0x20, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x73, 0x0a, 0x00, }; char doc_set_pv[408] = { 0x73, 0x65, 0x74, 0x5f, 0x70, 0x76, 0x28, 0x70, 0x76, 0x29, 0x0a, 0x0a, 0x53, 0x65, 0x74, 0x73, 0x20, 0x60, 0x60, 0x50, 0x56, 0x69, 0x5f, 0x6d, 0x61, 0x60, 0x60, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x2a, 0x69, 0x2a, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x2a, 0x6d, 0x2a, 0x2e, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x70, 0x76, 0x20, 0x3a, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x28, 0x2a, 0x69, 0x2a, 0x2c, 0x20, 0x2a, 0x6d, 0x2a, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0x29, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x69, 0x2a, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x2e, 0x20, 0x20, 0x41, 0x78, 0x69, 0x73, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2c, 0x20, 0x61, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x60, 0x60, 0x50, 0x56, 0x69, 0x5f, 0x6d, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x28, 0x69, 0x2e, 0x65, 0x2e, 0x20, 0x31, 0x2d, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x6d, 0x2a, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x2e, 0x20, 0x20, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2c, 0x20, 0x61, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x60, 0x60, 0x50, 0x56, 0x69, 0x5f, 0x6d, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x28, 0x69, 0x2e, 0x65, 0x2e, 0x20, 0x30, 0x2d, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0x3a, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2e, 0x20, 0x20, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x76, 0x0a, 0x00, }; char doc_set_tabprm[330] = { 0x73, 0x65, 0x74, 0x28, 0x29, 0x0a, 0x0a, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x73, 0x20, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x73, 0x2e, 0x0a, 0x0a, 0x41, 0x6c, 0x73, 0x6f, 0x20, 0x73, 0x65, 0x74, 0x73, 0x20, 0x75, 0x70, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x20, 0x69, 0x74, 0x2e, 0x0a, 0x0a, 0x4e, 0x6f, 0x74, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x20, 0x6e, 0x65, 0x65, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6c, 0x79, 0x3b, 0x20, 0x69, 0x74, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x69, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x0a, 0x62, 0x79, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x6e, 0x65, 0x65, 0x64, 0x20, 0x69, 0x74, 0x2e, 0x0a, 0x0a, 0x52, 0x61, 0x69, 0x73, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x61, 0x62, 0x75, 0x6c, 0x61, 0x72, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x74, 0x61, 0x62, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x0a, 0x00, }; char doc_sip[84] = { 0x47, 0x65, 0x74, 0x2f, 0x73, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x53, 0x69, 0x70, 0x60, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x60, 0x53, 0x49, 0x50, 0x60, 0x5f, 0x20, 0x64, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x00, }; char doc_sip_foc2pix[683] = { 0x73, 0x69, 0x70, 0x5f, 0x66, 0x6f, 0x63, 0x32, 0x70, 0x69, 0x78, 0x28, 0x2a, 0x66, 0x6f, 0x63, 0x63, 0x72, 0x64, 0x2c, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x2a, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x5b, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x5d, 0x60, 0x60, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x20, 0x66, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x53, 0x49, 0x50, 0x60, 0x5f, 0x0a, 0x70, 0x6f, 0x6c, 0x79, 0x6e, 0x6f, 0x6d, 0x69, 0x61, 0x6c, 0x20, 0x64, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x66, 0x6f, 0x63, 0x63, 0x72, 0x64, 0x20, 0x3a, 0x20, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x66, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x5b, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x5d, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x0a, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x46, 0x6f, 0x72, 0x74, 0x72, 0x61, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x46, 0x49, 0x54, 0x53, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x73, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x31, 0x2e, 0x20, 0x20, 0x4e, 0x75, 0x6d, 0x70, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x43, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x69, 0x74, 0x68, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x61, 0x74, 0x20, 0x30, 0x2e, 0x0a, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x70, 0x69, 0x78, 0x63, 0x72, 0x64, 0x20, 0x3a, 0x20, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x5b, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x5d, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x52, 0x61, 0x69, 0x73, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x0a, 0x00, }; char doc_sip_pix2foc[683] = { 0x73, 0x69, 0x70, 0x5f, 0x70, 0x69, 0x78, 0x32, 0x66, 0x6f, 0x63, 0x28, 0x2a, 0x70, 0x69, 0x78, 0x63, 0x72, 0x64, 0x2c, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x2a, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x5b, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x5d, 0x60, 0x60, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x53, 0x49, 0x50, 0x60, 0x5f, 0x0a, 0x70, 0x6f, 0x6c, 0x79, 0x6e, 0x6f, 0x6d, 0x69, 0x61, 0x6c, 0x20, 0x64, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x70, 0x69, 0x78, 0x63, 0x72, 0x64, 0x20, 0x3a, 0x20, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x5b, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x5d, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x0a, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x46, 0x6f, 0x72, 0x74, 0x72, 0x61, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x46, 0x49, 0x54, 0x53, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x73, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x31, 0x2e, 0x20, 0x20, 0x4e, 0x75, 0x6d, 0x70, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x43, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x69, 0x74, 0x68, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x61, 0x74, 0x20, 0x30, 0x2e, 0x0a, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x66, 0x6f, 0x63, 0x63, 0x72, 0x64, 0x20, 0x3a, 0x20, 0x6e, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x66, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5b, 0x6e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x5d, 0x5b, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x5d, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x52, 0x61, 0x69, 0x73, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x0a, 0x00, }; char doc_spcfix[272] = { 0x73, 0x70, 0x63, 0x66, 0x69, 0x78, 0x28, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x69, 0x6e, 0x74, 0x0a, 0x0a, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x20, 0x41, 0x49, 0x50, 0x53, 0x2d, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x7b, 0x60, 0x60, 0x46, 0x52, 0x45, 0x51, 0x60, 0x60, 0x2c, 0x0a, 0x60, 0x60, 0x56, 0x45, 0x4c, 0x4f, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x46, 0x45, 0x4c, 0x4f, 0x60, 0x60, 0x7d, 0x2d, 0x7b, 0x60, 0x60, 0x4f, 0x42, 0x53, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x48, 0x45, 0x4c, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x4c, 0x53, 0x52, 0x60, 0x60, 0x7d, 0x20, 0x28, 0x65, 0x2e, 0x67, 0x2e, 0x20, 0x60, 0x60, 0x46, 0x52, 0x45, 0x51, 0x2d, 0x4c, 0x53, 0x52, 0x60, 0x60, 0x2c, 0x0a, 0x60, 0x60, 0x56, 0x45, 0x4c, 0x4f, 0x2d, 0x4f, 0x42, 0x53, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x46, 0x45, 0x4c, 0x4f, 0x2d, 0x48, 0x45, 0x4c, 0x60, 0x60, 0x29, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x60, 0x60, 0x30, 0x60, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x3b, 0x20, 0x60, 0x60, 0x2d, 0x31, 0x60, 0x60, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2e, 0x0a, 0x00, }; char doc_spec[68] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x54, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x0a, 0x00, }; char doc_specsys[145] = { 0x60, 0x60, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x60, 0x60, 0x20, 0x53, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x20, 0x28, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x72, 0x65, 0x73, 0x74, 0x29, 0x2c, 0x20, 0x60, 0x60, 0x53, 0x50, 0x45, 0x43, 0x53, 0x59, 0x53, 0x61, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x73, 0x79, 0x73, 0x6f, 0x62, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x76, 0x65, 0x6c, 0x6f, 0x73, 0x79, 0x73, 0x0a, 0x00, }; char doc_sptr[1370] = { 0x73, 0x70, 0x74, 0x72, 0x28, 0x63, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x20, 0x69, 0x3d, 0x2d, 0x31, 0x29, 0x0a, 0x0a, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x57, 0x43, 0x53, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x0a, 0x0a, 0x46, 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x61, 0x20, 0x60, 0x60, 0x46, 0x52, 0x45, 0x51, 0x60, 0x60, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x60, 0x60, 0x5a, 0x4f, 0x50, 0x54, 0x2d, 0x46, 0x32, 0x57, 0x60, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x76, 0x69, 0x63, 0x65, 0x20, 0x76, 0x65, 0x72, 0x73, 0x61, 0x2e, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x63, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3a, 0x20, 0x73, 0x74, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x73, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x60, 0x60, 0x43, 0x54, 0x59, 0x50, 0x45, 0x69, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x20, 0x6f, 0x66, 0x20, 0x38, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x75, 0x72, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x6f, 0x75, 0x72, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x61, 0x72, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x6c, 0x79, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x62, 0x79, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x72, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x57, 0x69, 0x6c, 0x64, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x2c, 0x20, 0x69, 0x2e, 0x65, 0x2e, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x20, 0x74, 0x68, 0x72, 0x65, 0x65, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x20, 0x61, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x22, 0x3f, 0x3f, 0x3f, 0x22, 0x60, 0x60, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x69, 0x66, 0x20, 0x6a, 0x75, 0x73, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x69, 0x67, 0x68, 0x74, 0x68, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x20, 0x69, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x22, 0x3f, 0x22, 0x60, 0x60, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x75, 0x62, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x65, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x69, 0x20, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x28, 0x30, 0x2d, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x29, 0x2e, 0x20, 0x20, 0x49, 0x66, 0x20, 0x60, 0x60, 0x69, 0x20, 0x3c, 0x20, 0x30, 0x60, 0x60, 0x20, 0x28, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x29, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x73, 0x65, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x73, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x60, 0x43, 0x54, 0x59, 0x50, 0x45, 0x60, 0x60, 0x20, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, 0x49, 0x54, 0x53, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x0a, 0x0a, 0x52, 0x61, 0x69, 0x73, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x53, 0x69, 0x6e, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x69, 0x73, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x41, 0x78, 0x69, 0x73, 0x54, 0x79, 0x70, 0x65, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x75, 0x6e, 0x72, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6c, 0x6c, 0x2d, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x53, 0x75, 0x62, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x73, 0x75, 0x62, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6e, 0x6f, 0x20, 0x73, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x69, 0x73, 0x29, 0x2e, 0x0a, 0x00, }; char doc_ssysobs[253] = { 0x60, 0x60, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x60, 0x60, 0x20, 0x53, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x0a, 0x76, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2d, 0x6f, 0x66, 0x2d, 0x76, 0x69, 0x65, 0x77, 0x2c, 0x0a, 0x60, 0x60, 0x53, 0x53, 0x59, 0x53, 0x4f, 0x42, 0x53, 0x61, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x70, 0x65, 0x63, 0x73, 0x79, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x76, 0x65, 0x6c, 0x6f, 0x73, 0x79, 0x73, 0x0a, 0x00, }; char doc_ssyssrc[150] = { 0x60, 0x60, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x60, 0x60, 0x20, 0x53, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x72, 0x65, 0x64, 0x73, 0x68, 0x69, 0x66, 0x74, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x20, 0x28, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x72, 0x65, 0x73, 0x74, 0x29, 0x20, 0x69, 0x6e, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x64, 0x73, 0x68, 0x69, 0x66, 0x74, 0x0a, 0x77, 0x61, 0x73, 0x20, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x64, 0x2c, 0x20, 0x60, 0x60, 0x53, 0x53, 0x59, 0x53, 0x53, 0x52, 0x43, 0x61, 0x60, 0x60, 0x2e, 0x0a, 0x00, }; char doc_sub[3445] = { 0x73, 0x75, 0x62, 0x28, 0x61, 0x78, 0x65, 0x73, 0x29, 0x0a, 0x0a, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x73, 0x75, 0x62, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x43, 0x53, 0x60, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x75, 0x62, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x73, 0x65, 0x6e, 0x73, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x75, 0x62, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x0a, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x78, 0x65, 0x73, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x65, 0x64, 0x2e, 0x20, 0x20, 0x49, 0x6e, 0x0a, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6d, 0x65, 0x61, 0x6e, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x61, 0x60, 0x60, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x0a, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x6e, 0x6f, 0x6e, 0x2d, 0x7a, 0x65, 0x72, 0x6f, 0x20, 0x6f, 0x66, 0x66, 0x2d, 0x64, 0x69, 0x61, 0x67, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x73, 0x75, 0x62, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x61, 0x78, 0x65, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x6f, 0x6e, 0x2d, 0x73, 0x75, 0x62, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x61, 0x78, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x60, 0x73, 0x75, 0x62, 0x60, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x61, 0x64, 0x64, 0x20, 0x61, 0x78, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x77, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x61, 0x78, 0x65, 0x73, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x20, 0x73, 0x65, 0x74, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x0a, 0x61, 0x20, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x75, 0x6e, 0x6e, 0x61, 0x6d, 0x65, 0x64, 0x2c, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x73, 0x65, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x0a, 0x69, 0x6e, 0x76, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x60, 0x73, 0x65, 0x74, 0x60, 0x2e, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x78, 0x65, 0x73, 0x20, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x49, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x69, 0x6e, 0x74, 0x2c, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x2a, 0x4e, 0x2a, 0x20, 0x61, 0x78, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x69, 0x72, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x20, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x49, 0x66, 0x20, 0x61, 0x20, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x2c, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x31, 0x2d, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x20, 0x28, 0x73, 0x65, 0x65, 0x20, 0x62, 0x65, 0x6c, 0x6f, 0x77, 0x29, 0x2e, 0x20, 0x20, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x20, 0x69, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x66, 0x69, 0x63, 0x61, 0x6e, 0x74, 0x3b, 0x20, 0x60, 0x60, 0x61, 0x78, 0x65, 0x73, 0x5b, 0x30, 0x5d, 0x60, 0x60, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x75, 0x62, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2c, 0x20, 0x65, 0x74, 0x63, 0x2e, 0x20, 0x20, 0x55, 0x73, 0x65, 0x20, 0x61, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x30, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x61, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x49, 0x66, 0x20, 0x60, 0x60, 0x30, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x5b, 0x5d, 0x60, 0x60, 0x20, 0x6f, 0x72, 0x20, 0x60, 0x60, 0x4e, 0x6f, 0x6e, 0x65, 0x60, 0x60, 0x2c, 0x20, 0x64, 0x6f, 0x20, 0x61, 0x20, 0x64, 0x65, 0x65, 0x70, 0x20, 0x63, 0x6f, 0x70, 0x79, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x78, 0x65, 0x73, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x73, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x60, 0x27, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x27, 0x60, 0x60, 0x20, 0x2f, 0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 0x53, 0x55, 0x42, 0x5f, 0x4c, 0x4f, 0x4e, 0x47, 0x49, 0x54, 0x55, 0x44, 0x45, 0x60, 0x60, 0x3a, 0x20, 0x43, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x60, 0x27, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x27, 0x60, 0x60, 0x20, 0x2f, 0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 0x53, 0x55, 0x42, 0x5f, 0x4c, 0x41, 0x54, 0x49, 0x54, 0x55, 0x44, 0x45, 0x60, 0x60, 0x3a, 0x20, 0x43, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x60, 0x27, 0x63, 0x75, 0x62, 0x65, 0x66, 0x61, 0x63, 0x65, 0x27, 0x60, 0x60, 0x20, 0x2f, 0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 0x53, 0x55, 0x42, 0x5f, 0x43, 0x55, 0x42, 0x45, 0x46, 0x41, 0x43, 0x45, 0x60, 0x60, 0x3a, 0x20, 0x51, 0x75, 0x61, 0x64, 0x63, 0x75, 0x62, 0x65, 0x20, 0x60, 0x60, 0x43, 0x55, 0x42, 0x45, 0x46, 0x41, 0x43, 0x45, 0x60, 0x60, 0x20, 0x61, 0x78, 0x69, 0x73, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x60, 0x27, 0x73, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x27, 0x60, 0x60, 0x20, 0x2f, 0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 0x53, 0x55, 0x42, 0x5f, 0x53, 0x50, 0x45, 0x43, 0x54, 0x52, 0x41, 0x4c, 0x60, 0x60, 0x3a, 0x20, 0x53, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x69, 0x73, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x60, 0x27, 0x73, 0x74, 0x6f, 0x6b, 0x65, 0x73, 0x27, 0x60, 0x60, 0x20, 0x2f, 0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 0x53, 0x55, 0x42, 0x5f, 0x53, 0x54, 0x4f, 0x4b, 0x45, 0x53, 0x60, 0x60, 0x3a, 0x20, 0x53, 0x74, 0x6f, 0x6b, 0x65, 0x73, 0x20, 0x61, 0x78, 0x69, 0x73, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x60, 0x27, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x27, 0x60, 0x60, 0x20, 0x2f, 0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 0x53, 0x55, 0x42, 0x5f, 0x43, 0x45, 0x4c, 0x45, 0x53, 0x54, 0x49, 0x41, 0x4c, 0x60, 0x60, 0x3a, 0x20, 0x41, 0x6e, 0x20, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x60, 0x60, 0x27, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x27, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x27, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x27, 0x60, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x60, 0x60, 0x27, 0x63, 0x75, 0x62, 0x65, 0x66, 0x61, 0x63, 0x65, 0x27, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x6e, 0x65, 0x77, 0x5f, 0x77, 0x63, 0x73, 0x20, 0x3a, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x43, 0x53, 0x60, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x0a, 0x0a, 0x52, 0x61, 0x69, 0x73, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x53, 0x75, 0x62, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x73, 0x75, 0x62, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6e, 0x6f, 0x20, 0x73, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x69, 0x73, 0x29, 0x2e, 0x0a, 0x0a, 0x4e, 0x6f, 0x6e, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x62, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4e, 0x6f, 0x6e, 0x2d, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x75, 0x62, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x0a, 0x0a, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x75, 0x62, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x61, 0x78, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x0a, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x79, 0x20, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x62, 0x79, 0x20, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x27, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x6f, 0x72, 0x27, 0x20, 0x28, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x29, 0x20, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x20, 0x20, 0x46, 0x6f, 0x72, 0x0a, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3a, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x77, 0x63, 0x73, 0x2e, 0x73, 0x75, 0x62, 0x28, 0x5b, 0x57, 0x43, 0x53, 0x53, 0x55, 0x42, 0x5f, 0x4c, 0x4f, 0x4e, 0x47, 0x49, 0x54, 0x55, 0x44, 0x45, 0x20, 0x7c, 0x20, 0x57, 0x43, 0x53, 0x53, 0x55, 0x42, 0x5f, 0x4c, 0x41, 0x54, 0x49, 0x54, 0x55, 0x44, 0x45, 0x20, 0x7c, 0x20, 0x57, 0x43, 0x53, 0x53, 0x55, 0x42, 0x5f, 0x53, 0x50, 0x45, 0x43, 0x54, 0x52, 0x41, 0x4c, 0x5d, 0x29, 0x0a, 0x0a, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x2c, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x0a, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x20, 0x20, 0x49, 0x66, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x77, 0x65, 0x72, 0x65, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x69, 0x6e, 0x67, 0x0a, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x74, 0x68, 0x72, 0x65, 0x65, 0x20, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x0a, 0x0a, 0x46, 0x6f, 0x72, 0x20, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x6e, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x2c, 0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 0x53, 0x55, 0x42, 0x5f, 0x43, 0x45, 0x4c, 0x45, 0x53, 0x54, 0x49, 0x41, 0x4c, 0x60, 0x60, 0x20, 0x69, 0x73, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x60, 0x60, 0x57, 0x43, 0x53, 0x53, 0x55, 0x42, 0x5f, 0x4c, 0x4f, 0x4e, 0x47, 0x49, 0x54, 0x55, 0x44, 0x45, 0x20, 0x7c, 0x20, 0x57, 0x43, 0x53, 0x53, 0x55, 0x42, 0x5f, 0x4c, 0x41, 0x54, 0x49, 0x54, 0x55, 0x44, 0x45, 0x20, 0x7c, 0x20, 0x57, 0x43, 0x53, 0x53, 0x55, 0x42, 0x5f, 0x43, 0x55, 0x42, 0x45, 0x46, 0x41, 0x43, 0x45, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2c, 0x0a, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3a, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x77, 0x63, 0x73, 0x2e, 0x73, 0x75, 0x62, 0x28, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x57, 0x43, 0x53, 0x53, 0x55, 0x42, 0x5f, 0x4c, 0x4f, 0x4e, 0x47, 0x49, 0x54, 0x55, 0x44, 0x45, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x57, 0x43, 0x53, 0x53, 0x55, 0x42, 0x5f, 0x4c, 0x41, 0x54, 0x49, 0x54, 0x55, 0x44, 0x45, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x57, 0x43, 0x53, 0x53, 0x55, 0x42, 0x5f, 0x43, 0x55, 0x42, 0x45, 0x46, 0x41, 0x43, 0x45, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x28, 0x57, 0x43, 0x53, 0x53, 0x55, 0x42, 0x5f, 0x53, 0x50, 0x45, 0x43, 0x54, 0x52, 0x41, 0x4c, 0x20, 0x7c, 0x20, 0x57, 0x43, 0x53, 0x53, 0x55, 0x42, 0x5f, 0x53, 0x54, 0x4f, 0x4b, 0x45, 0x53, 0x29, 0x5d, 0x29, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x73, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x6f, 0x72, 0x0a, 0x53, 0x74, 0x6f, 0x6b, 0x65, 0x73, 0x2e, 0x20, 0x20, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x64, 0x6f, 0x6e, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x60, 0x60, 0x61, 0x78, 0x65, 0x73, 0x60, 0x60, 0x2c, 0x20, 0x69, 0x2e, 0x65, 0x2e, 0x20, 0x61, 0x0a, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x28, 0x69, 0x66, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x29, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x65, 0x64, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x28, 0x76, 0x69, 0x61, 0x20, 0x60, 0x60, 0x61, 0x78, 0x65, 0x73, 0x5b, 0x30, 0x5d, 0x60, 0x60, 0x29, 0x0a, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x75, 0x62, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x20, 0x28, 0x76, 0x69, 0x61, 0x20, 0x60, 0x60, 0x61, 0x78, 0x65, 0x73, 0x5b, 0x33, 0x5d, 0x60, 0x60, 0x29, 0x2e, 0x20, 0x20, 0x4c, 0x69, 0x6b, 0x65, 0x77, 0x69, 0x73, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x63, 0x75, 0x62, 0x65, 0x66, 0x61, 0x63, 0x65, 0x20, 0x61, 0x78, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x6c, 0x65, 0x73, 0x73, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x6f, 0x72, 0x0a, 0x67, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x6f, 0x66, 0x20, 0x60, 0x60, 0x61, 0x78, 0x65, 0x73, 0x60, 0x60, 0x2e, 0x20, 0x20, 0x48, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x20, 0x65, 0x78, 0x63, 0x65, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x78, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x0a, 0x00, }; char doc_tab[112] = { 0x60, 0x60, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x54, 0x61, 0x62, 0x70, 0x72, 0x6d, 0x60, 0x60, 0x20, 0x54, 0x61, 0x62, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2e, 0x0a, 0x0a, 0x41, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x61, 0x62, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x20, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x57, 0x43, 0x53, 0x2e, 0x0a, 0x00, }; char doc_telapse[141] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x65, 0x71, 0x75, 0x69, 0x76, 0x61, 0x6c, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x64, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x20, 0x44, 0x41, 0x54, 0x45, 0x2d, 0x42, 0x45, 0x47, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x44, 0x41, 0x54, 0x45, 0x2d, 0x45, 0x4e, 0x44, 0x2c, 0x20, 0x69, 0x6e, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x54, 0x49, 0x4d, 0x45, 0x55, 0x4e, 0x49, 0x54, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x74, 0x73, 0x74, 0x61, 0x72, 0x74, 0x0a, 0x00, }; char doc_theta0[289] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x64, 0x75, 0x63, 0x69, 0x61, 0x6c, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x77, 0x68, 0x6f, 0x73, 0x65, 0x20, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x60, 0x60, 0x72, 0x65, 0x66, 0x5b, 0x31, 0x3a, 0x32, 0x5d, 0x60, 0x60, 0x2e, 0x20, 0x20, 0x49, 0x66, 0x0a, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x28, 0x4e, 0x61, 0x4e, 0x29, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x2c, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x60, 0x2c, 0x0a, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x73, 0x65, 0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x70, 0x68, 0x69, 0x30, 0x0a, 0x00, }; char doc_timedel[93] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x73, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x64, 0x65, 0x6c, 0x0a, 0x00, }; char doc_timeoffs[186] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2c, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x2c, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x20, 0x61, 0x20, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x44, 0x41, 0x54, 0x45, 0x52, 0x45, 0x46, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x66, 0x66, 0x73, 0x0a, 0x00, }; char doc_timepixr[151] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x62, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x2c, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x20, 0x30, 0x2e, 0x30, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x31, 0x2e, 0x30, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x70, 0x69, 0x78, 0x72, 0x0a, 0x00, }; char doc_timesys[230] = { 0x60, 0x60, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x60, 0x60, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x20, 0x28, 0x55, 0x54, 0x43, 0x2c, 0x20, 0x54, 0x41, 0x49, 0x2c, 0x20, 0x65, 0x74, 0x63, 0x2e, 0x29, 0x20, 0x69, 0x6e, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x2d, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x0a, 0x61, 0x75, 0x78, 0x69, 0x6c, 0x69, 0x61, 0x72, 0x79, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x65, 0x64, 0x2e, 0x20, 0x41, 0x6c, 0x73, 0x6f, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x0a, 0x61, 0x6e, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x43, 0x54, 0x59, 0x50, 0x45, 0x69, 0x61, 0x20, 0x73, 0x65, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x27, 0x54, 0x49, 0x4d, 0x45, 0x27, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x79, 0x73, 0x0a, 0x00, }; char doc_timeunit[264] = { 0x60, 0x60, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x60, 0x60, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x3a, 0x0a, 0x60, 0x60, 0x54, 0x53, 0x54, 0x41, 0x52, 0x54, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x54, 0x53, 0x54, 0x4f, 0x50, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x46, 0x46, 0x53, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x54, 0x49, 0x4d, 0x53, 0x59, 0x45, 0x52, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x54, 0x49, 0x4d, 0x52, 0x44, 0x45, 0x52, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x54, 0x49, 0x4d, 0x45, 0x44, 0x45, 0x4c, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x49, 0x74, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x60, 0x60, 0x43, 0x55, 0x4e, 0x49, 0x54, 0x69, 0x61, 0x60, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x61, 0x78, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x74, 0x72, 0x65, 0x66, 0x64, 0x69, 0x72, 0x0a, 0x00, }; char doc_timrder[132] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x63, 0x63, 0x75, 0x72, 0x61, 0x63, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x73, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x2c, 0x20, 0x69, 0x6e, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x54, 0x49, 0x4d, 0x45, 0x55, 0x4e, 0x49, 0x54, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x74, 0x69, 0x6d, 0x73, 0x79, 0x65, 0x72, 0x0a, 0x00, }; char doc_timsyer[119] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x62, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2c, 0x20, 0x69, 0x6e, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x54, 0x49, 0x4d, 0x45, 0x55, 0x4e, 0x49, 0x54, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x74, 0x69, 0x6d, 0x72, 0x64, 0x65, 0x72, 0x0a, 0x00, }; char doc_to_header[2232] = { 0x74, 0x6f, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x72, 0x65, 0x6c, 0x61, 0x78, 0x3d, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x29, 0x0a, 0x0a, 0x60, 0x74, 0x6f, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x60, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x57, 0x43, 0x53, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x46, 0x49, 0x54, 0x53, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x49, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x6f, 0x6c, 0x6e, 0x75, 0x6d, 0x60, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x6e, 0x2d, 0x7a, 0x65, 0x72, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x77, 0x69, 0x73, 0x65, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x6f, 0x6c, 0x61, 0x78, 0x60, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x69, 0x73, 0x20, 0x73, 0x65, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x6f, 0x6e, 0x2d, 0x7a, 0x65, 0x72, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x77, 0x69, 0x73, 0x65, 0x2c, 0x20, 0x61, 0x20, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x61, 0x6c, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x63, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6e, 0x6c, 0x79, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x0a, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x72, 0x65, 0x73, 0x70, 0x65, 0x63, 0x74, 0x73, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x31, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x20, 0x57, 0x43, 0x53, 0x2d, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x2e, 0x20, 0x20, 0x49, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6f, 0x65, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x75, 0x63, 0x68, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x53, 0x49, 0x4d, 0x50, 0x4c, 0x45, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x4e, 0x41, 0x58, 0x49, 0x53, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x42, 0x49, 0x54, 0x50, 0x49, 0x58, 0x60, 0x60, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x60, 0x60, 0x45, 0x4e, 0x44, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x32, 0x2e, 0x20, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x20, 0x28, 0x65, 0x2e, 0x67, 0x2e, 0x20, 0x60, 0x60, 0x43, 0x52, 0x4f, 0x54, 0x41, 0x6e, 0x60, 0x60, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x75, 0x73, 0x61, 0x67, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x28, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x6e, 0x20, 0x77, 0x68, 0x65, 0x74, 0x68, 0x65, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x60, 0x66, 0x69, 0x78, 0x60, 0x60, 0x20, 0x77, 0x61, 0x73, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x29, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x33, 0x2e, 0x20, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x53, 0x49, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x34, 0x2e, 0x20, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x2d, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x35, 0x2e, 0x20, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x60, 0x50, 0x43, 0x69, 0x5f, 0x6a, 0x60, 0x60, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, 0x69, 0x66, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x69, 0x66, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x65, 0x79, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x75, 0x73, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x69, 0x73, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6e, 0x6f, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x36, 0x2e, 0x20, 0x41, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x73, 0x75, 0x63, 0x68, 0x20, 0x61, 0x73, 0x20, 0x60, 0x60, 0x57, 0x43, 0x53, 0x41, 0x58, 0x45, 0x53, 0x60, 0x60, 0x2c, 0x20, 0x60, 0x60, 0x43, 0x55, 0x4e, 0x49, 0x54, 0x69, 0x61, 0x60, 0x60, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x60, 0x4c, 0x4f, 0x4e, 0x50, 0x4f, 0x4c, 0x45, 0x61, 0x60, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x60, 0x60, 0x4c, 0x41, 0x54, 0x50, 0x4f, 0x4c, 0x45, 0x61, 0x60, 0x60, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x37, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x20, 0x6b, 0x65, 0x79, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x6c, 0x6f, 0x73, 0x74, 0x2c, 0x20, 0x61, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x74, 0x6f, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x60, 0x20, 0x74, 0x72, 0x69, 0x65, 0x73, 0x20, 0x68, 0x61, 0x72, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x20, 0x6d, 0x65, 0x61, 0x6e, 0x69, 0x6e, 0x67, 0x66, 0x75, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x38, 0x2e, 0x20, 0x4b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x20, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x4b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x2c, 0x20, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x20, 0x62, 0x79, 0x20, 0x6d, 0x61, 0x6e, 0x69, 0x70, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x6f, 0x6c, 0x6e, 0x75, 0x6d, 0x60, 0x20, 0x6f, 0x72, 0x0a, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x63, 0x6f, 0x6c, 0x61, 0x78, 0x60, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x43, 0x53, 0x60, 0x0a, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x72, 0x65, 0x6c, 0x61, 0x78, 0x20, 0x3a, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x20, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x44, 0x65, 0x67, 0x72, 0x65, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x76, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x60, 0x3a, 0x20, 0x52, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, 0x7a, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x46, 0x49, 0x54, 0x53, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x57, 0x43, 0x53, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x54, 0x72, 0x75, 0x65, 0x60, 0x3a, 0x20, 0x41, 0x64, 0x6d, 0x69, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x57, 0x43, 0x53, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x60, 0x69, 0x6e, 0x74, 0x60, 0x3a, 0x20, 0x61, 0x20, 0x62, 0x69, 0x74, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x65, 0x65, 0x20, 0x3a, 0x72, 0x65, 0x66, 0x3a, 0x60, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x3a, 0x72, 0x65, 0x6c, 0x61, 0x78, 0x77, 0x72, 0x69, 0x74, 0x65, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x3a, 0x20, 0x73, 0x74, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x52, 0x61, 0x77, 0x20, 0x46, 0x49, 0x54, 0x53, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x61, 0x73, 0x20, 0x61, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x0a, 0x00, }; char doc_trefdir[118] = { 0x60, 0x60, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x60, 0x60, 0x20, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x63, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x70, 0x61, 0x74, 0x68, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x74, 0x72, 0x65, 0x66, 0x64, 0x69, 0x72, 0x0a, 0x00, }; char doc_trefpos[110] = { 0x60, 0x60, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x60, 0x60, 0x20, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x65, 0x64, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x69, 0x73, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x74, 0x72, 0x65, 0x66, 0x70, 0x6f, 0x73, 0x0a, 0x00, }; char doc_tstart[150] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x65, 0x71, 0x75, 0x69, 0x76, 0x61, 0x6c, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x44, 0x41, 0x54, 0x45, 0x2d, 0x42, 0x45, 0x47, 0x20, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x61, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x54, 0x49, 0x4d, 0x45, 0x55, 0x4e, 0x49, 0x54, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x44, 0x41, 0x54, 0x45, 0x52, 0x45, 0x46, 0x2b, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x46, 0x46, 0x53, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x74, 0x73, 0x74, 0x6f, 0x70, 0x0a, 0x00, }; char doc_tstop[151] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x65, 0x71, 0x75, 0x69, 0x76, 0x61, 0x6c, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x44, 0x41, 0x54, 0x45, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x61, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x54, 0x49, 0x4d, 0x45, 0x55, 0x4e, 0x49, 0x54, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x44, 0x41, 0x54, 0x45, 0x52, 0x45, 0x46, 0x2b, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x46, 0x46, 0x53, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x74, 0x73, 0x74, 0x61, 0x72, 0x74, 0x0a, 0x00, }; char doc_ttype[107] = { 0x60, 0x60, 0x73, 0x74, 0x72, 0x60, 0x60, 0x20, 0x28, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x60, 0x60, 0x54, 0x54, 0x59, 0x50, 0x45, 0x6e, 0x60, 0x60, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x0a, 0x74, 0x68, 0x65, 0x20, 0x77, 0x63, 0x73, 0x74, 0x61, 0x62, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x2e, 0x0a, 0x00, }; char doc_unitfix[1047] = { 0x75, 0x6e, 0x69, 0x74, 0x66, 0x69, 0x78, 0x28, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x3d, 0x27, 0x27, 0x29, 0x0a, 0x0a, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x20, 0x6e, 0x6f, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x60, 0x60, 0x43, 0x55, 0x4e, 0x49, 0x54, 0x69, 0x61, 0x60, 0x60, 0x20, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x46, 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x60, 0x60, 0x44, 0x45, 0x47, 0x60, 0x60, 0x20, 0x2d, 0x3e, 0x20, 0x60, 0x60, 0x64, 0x65, 0x67, 0x60, 0x60, 0x2c, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x66, 0x20, 0x75, 0x6e, 0x6e, 0x65, 0x63, 0x65, 0x73, 0x73, 0x61, 0x72, 0x79, 0x0a, 0x77, 0x68, 0x69, 0x74, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x20, 0x3a, 0x20, 0x73, 0x74, 0x72, 0x2c, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x44, 0x6f, 0x20, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x6e, 0x6f, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x41, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x60, 0x60, 0x22, 0x53, 0x22, 0x60, 0x60, 0x20, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x2c, 0x20, 0x69, 0x74, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, 0x7a, 0x65, 0x73, 0x20, 0x60, 0x60, 0x22, 0x53, 0x22, 0x60, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x61, 0x73, 0x20, 0x53, 0x69, 0x65, 0x6d, 0x65, 0x6e, 0x73, 0x2c, 0x20, 0x68, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x20, 0x72, 0x61, 0x72, 0x65, 0x6c, 0x79, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x6d, 0x61, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x62, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x60, 0x22, 0x73, 0x22, 0x60, 0x60, 0x20, 0x69, 0x73, 0x20, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x20, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x75, 0x73, 0x65, 0x64, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x60, 0x22, 0x48, 0x22, 0x60, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x68, 0x6f, 0x75, 0x72, 0x73, 0x20, 0x28, 0x48, 0x65, 0x6e, 0x72, 0x79, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x60, 0x60, 0x22, 0x44, 0x22, 0x60, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x64, 0x61, 0x79, 0x73, 0x20, 0x28, 0x44, 0x65, 0x62, 0x79, 0x65, 0x29, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x73, 0x20, 0x77, 0x68, 0x61, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x6f, 0x20, 0x69, 0x6e, 0x20, 0x73, 0x75, 0x63, 0x68, 0x20, 0x63, 0x61, 0x73, 0x65, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x69, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x73, 0x65, 0x2d, 0x69, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x49, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x20, 0x60, 0x60, 0x22, 0x73, 0x22, 0x60, 0x60, 0x2c, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x20, 0x60, 0x60, 0x22, 0x53, 0x22, 0x60, 0x60, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x60, 0x22, 0x73, 0x22, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x49, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x20, 0x60, 0x60, 0x22, 0x68, 0x22, 0x60, 0x60, 0x2c, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x20, 0x60, 0x60, 0x22, 0x48, 0x22, 0x60, 0x60, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x60, 0x22, 0x68, 0x22, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x49, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x20, 0x60, 0x60, 0x22, 0x64, 0x22, 0x60, 0x60, 0x2c, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x20, 0x60, 0x60, 0x22, 0x44, 0x22, 0x60, 0x60, 0x20, 0x74, 0x6f, 0x20, 0x60, 0x60, 0x22, 0x64, 0x22, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x75, 0x73, 0x20, 0x60, 0x60, 0x27, 0x27, 0x60, 0x60, 0x20, 0x64, 0x6f, 0x65, 0x73, 0x6e, 0x27, 0x74, 0x20, 0x64, 0x6f, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x61, 0x73, 0x20, 0x60, 0x60, 0x27, 0x73, 0x68, 0x64, 0x27, 0x60, 0x60, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x65, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x2e, 0x0a, 0x0a, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x60, 0x60, 0x30, 0x60, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x3b, 0x20, 0x60, 0x60, 0x2d, 0x31, 0x60, 0x60, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2e, 0x0a, 0x00, }; char doc_velangl[186] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x56, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x74, 0x79, 0x20, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x0a, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x74, 0x79, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x72, 0x61, 0x64, 0x69, 0x61, 0x6c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x76, 0x65, 0x72, 0x73, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x0a, 0x0a, 0x41, 0x6e, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x4e, 0x61, 0x4e, 0x2e, 0x0a, 0x00, }; char doc_velosys[316] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x72, 0x61, 0x64, 0x69, 0x61, 0x6c, 0x20, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x74, 0x79, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x72, 0x61, 0x64, 0x69, 0x61, 0x6c, 0x20, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x74, 0x79, 0x20, 0x28, 0x6d, 0x2f, 0x73, 0x29, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x72, 0x65, 0x73, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x0a, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x2c, 0x20, 0x60, 0x60, 0x56, 0x45, 0x4c, 0x4f, 0x53, 0x59, 0x53, 0x61, 0x60, 0x60, 0x2e, 0x0a, 0x0a, 0x41, 0x6e, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x4e, 0x61, 0x4e, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x70, 0x65, 0x63, 0x73, 0x79, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x73, 0x73, 0x79, 0x73, 0x6f, 0x62, 0x73, 0x0a, 0x00, }; char doc_velref[55] = { 0x60, 0x60, 0x69, 0x6e, 0x74, 0x60, 0x60, 0x20, 0x41, 0x49, 0x50, 0x53, 0x20, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x74, 0x79, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x0a, 0x0a, 0x46, 0x72, 0x6f, 0x6d, 0x20, 0x60, 0x60, 0x56, 0x45, 0x4c, 0x52, 0x45, 0x46, 0x60, 0x60, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x2e, 0x0a, 0x00, }; char doc_wcs[83] = { 0x41, 0x20, 0x60, 0x7e, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x60, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x61, 0x73, 0x69, 0x63, 0x20, 0x60, 0x77, 0x63, 0x73, 0x6c, 0x69, 0x62, 0x60, 0x5f, 0x20, 0x57, 0x43, 0x53, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x00, }; char doc_wtb[82] = { 0x60, 0x60, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x57, 0x74, 0x62, 0x61, 0x72, 0x72, 0x60, 0x60, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x42, 0x49, 0x4e, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x2e, 0x0a, 0x0a, 0x00, }; char doc_xposure[105] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x54, 0x49, 0x4d, 0x45, 0x55, 0x4e, 0x49, 0x54, 0x2e, 0x0a, 0x0a, 0x53, 0x65, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x77, 0x63, 0x73, 0x2e, 0x57, 0x63, 0x73, 0x70, 0x72, 0x6d, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x75, 0x6e, 0x69, 0x74, 0x0a, 0x00, }; char doc_zsource[98] = { 0x60, 0x60, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x60, 0x60, 0x20, 0x54, 0x68, 0x65, 0x20, 0x72, 0x65, 0x64, 0x73, 0x68, 0x69, 0x66, 0x74, 0x2c, 0x20, 0x60, 0x60, 0x5a, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x61, 0x60, 0x60, 0x2c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x0a, 0x0a, 0x41, 0x6e, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x4e, 0x61, 0x4e, 0x2e, 0x0a, 0x00, }; ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/src/pipeline.c0000644000175100001710000001532500000000000017310 0ustar00vstsdocker/* Author: Michael Droettboom mdroe@stsci.edu */ #include "astropy_wcs/pipeline.h" #include "astropy_wcs/util.h" #include "wcserr.h" #include #include #include #define PIP_ERRMSG(status) WCSERR_SET(status) void pipeline_clear( pipeline_t* pipeline) { pipeline->det2im[0] = NULL; pipeline->det2im[1] = NULL; pipeline->sip = NULL; pipeline->cpdis[0] = NULL; pipeline->cpdis[1] = NULL; pipeline->wcs = NULL; pipeline->err = NULL; } void pipeline_init( pipeline_t* pipeline, /*@shared@*/ distortion_lookup_t** det2im /* [2] */, /*@shared@*/ sip_t* sip, /*@shared@*/ distortion_lookup_t** cpdis /* [2] */, /*@shared@*/ struct wcsprm* wcs) { pipeline->det2im[0] = det2im[0]; pipeline->det2im[1] = det2im[1]; pipeline->sip = sip; pipeline->cpdis[0] = cpdis[0]; pipeline->cpdis[1] = cpdis[1]; pipeline->wcs = wcs; pipeline->err = NULL; } void pipeline_free( pipeline_t* pipeline) { free(pipeline->err); pipeline->err = NULL; } int pipeline_all_pixel2world( pipeline_t* pipeline, const unsigned int ncoord, const unsigned int nelem, const double* const pixcrd /* [ncoord][nelem] */, double* world /* [ncoord][nelem] */) { static const char* function = "pipeline_all_pixel2world"; const double* wcs_input = NULL; double* wcs_output = NULL; int has_det2im; int has_sip; int has_p4; int has_wcs; int status = 1; struct wcserr **err; /* Temporary buffer for performing WCS calculations */ unsigned char* buffer = NULL; unsigned char* mem = NULL; /*@null@*/ double* tmp; /*@null@*/ double* imgcrd; /*@null@*/ double* phi; /*@null@*/ double* theta; /*@null@*/ int* stat; if (pipeline == NULL || pixcrd == NULL || world == NULL) { return WCSERR_NULL_POINTER; } err = &(pipeline->err); has_det2im = pipeline->det2im[0] != NULL || pipeline->det2im[1] != NULL; has_sip = pipeline->sip != NULL; has_p4 = pipeline->cpdis[0] != NULL || pipeline->cpdis[1] != NULL; has_wcs = pipeline->wcs != NULL; if (has_det2im || has_sip || has_p4) { if (nelem != 2) { status = wcserr_set( PIP_ERRMSG(WCSERR_BAD_COORD_TRANS), "Data must be 2-dimensional when Paper IV lookup table or SIP transform is present."); goto exit; } } if (has_wcs) { if (ncoord < 1) { status = wcserr_set( PIP_ERRMSG(WCSERR_BAD_PIX), "The number of coordinates must be > 0"); goto exit; } buffer = mem = malloc( ncoord * nelem * sizeof(double) + /* imgcrd */ ncoord * sizeof(double) + /* phi */ ncoord * sizeof(double) + /* theta */ ncoord * nelem * sizeof(double) + /* tmp */ ncoord * nelem * sizeof(int) /* stat */ ); if (buffer == NULL) { status = wcserr_set( PIP_ERRMSG(WCSERR_MEMORY), "Memory allocation failed"); goto exit; } imgcrd = (double *)mem; mem += ncoord * nelem * sizeof(double); phi = (double *)mem; mem += ncoord * sizeof(double); theta = (double *)mem; mem += ncoord * sizeof(double); tmp = (double *)mem; mem += ncoord * nelem * sizeof(double); stat = (int *)mem; /* mem += ncoord * nelem * sizeof(int); */ if (has_det2im || has_sip || has_p4) { status = pipeline_pix2foc(pipeline, ncoord, nelem, pixcrd, tmp); if (status != 0) { goto exit; } wcs_input = tmp; wcs_output = world; } else { wcs_input = pixcrd; wcs_output = world; } if ((status = wcsp2s(pipeline->wcs, (int)ncoord, (int)nelem, wcs_input, imgcrd, phi, theta, wcs_output, stat))) { if (pipeline->err == NULL) { pipeline->err = calloc(1, sizeof(struct wcserr)); } wcserr_copy(pipeline->wcs->err, pipeline->err); } if (status == 8) { set_invalid_to_nan((int)ncoord, (int)nelem, wcs_output, stat); } } else { if (has_det2im || has_sip || has_p4) { status = pipeline_pix2foc(pipeline, ncoord, nelem, pixcrd, world); } } exit: free(buffer); return status; } int pipeline_pix2foc( pipeline_t* pipeline, const unsigned int ncoord, const unsigned int nelem, const double* const pixcrd /* [ncoord][nelem] */, double* foc /* [ncoord][nelem] */) { static const char* function = "pipeline_pix2foc"; int has_det2im; int has_sip; int has_p4; const double * input = NULL; double * tmp = NULL; int status = 1; struct wcserr **err; assert(nelem == 2); assert(pixcrd != foc); if (pipeline == NULL || pixcrd == NULL || foc == NULL) { return WCSERR_NULL_POINTER; } err = &(pipeline->err); if (ncoord < 1) { status = wcserr_set( PIP_ERRMSG(WCSERR_BAD_PIX), "The number of coordinates must be > 0"); goto exit; } has_det2im = pipeline->det2im[0] != NULL || pipeline->det2im[1] != NULL; has_sip = pipeline->sip != NULL; has_p4 = pipeline->cpdis[0] != NULL || pipeline->cpdis[1] != NULL; if (has_det2im) { if (has_sip || has_p4) { tmp = malloc(ncoord * nelem * sizeof(double)); if (tmp == NULL) { status = wcserr_set( PIP_ERRMSG(WCSERR_MEMORY), "Memory allocation failed"); goto exit; } memcpy(tmp, pixcrd, sizeof(double) * ncoord * nelem); status = p4_pix2deltas(2, (void*)pipeline->det2im, ncoord, pixcrd, tmp); if (status) { wcserr_set(PIP_ERRMSG(WCSERR_NULL_POINTER), "NULL pointer passed"); goto exit; } input = tmp; memcpy(foc, input, sizeof(double) * ncoord * nelem); } else { memcpy(foc, pixcrd, sizeof(double) * ncoord * nelem); status = p4_pix2deltas(2, (void*)pipeline->det2im, ncoord, pixcrd, foc); if (status) { wcserr_set(PIP_ERRMSG(WCSERR_NULL_POINTER), "NULL pointer passed"); goto exit; } } } else { /* Copy pixcrd to foc as a starting point. The "deltas" functions below will undistort from there */ memcpy(foc, pixcrd, sizeof(double) * ncoord * nelem); input = pixcrd; } if (has_sip) { status = sip_pix2deltas(pipeline->sip, 2, ncoord, input, foc); if (status) { if (pipeline->err == NULL) { pipeline->err = calloc(1, sizeof(struct wcserr)); } wcserr_copy(pipeline->sip->err, pipeline->err); goto exit; } } if (has_p4) { status = p4_pix2deltas(2, (void*)pipeline->cpdis, ncoord, input, foc); if (status) { wcserr_set(PIP_ERRMSG(WCSERR_NULL_POINTER), "NULL pointer passed"); goto exit; } } status = 0; exit: free(tmp); return status; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/src/pyutil.c0000644000175100001710000005123600000000000017032 0ustar00vstsdocker/* Author: Michael Droettboom mdroe@stsci.edu */ #define NO_IMPORT_ARRAY /* util.h must be imported first */ #include "astropy_wcs/pyutil.h" #include "astropy_wcs/docstrings.h" #include "wcsfix.h" #include "wcshdr.h" #include "wcsprintf.h" #include "wcsunits.h" /*@null@*/ static INLINE PyObject* _PyArrayProxy_New( /*@shared@*/ PyObject* self, int nd, const npy_intp* dims, int typenum, const void* data, const int flags) { PyArray_Descr* type_descr = NULL; PyObject* result = NULL; type_descr = (PyArray_Descr*)PyArray_DescrFromType(typenum); if (type_descr == NULL) { return NULL; } result = (PyObject*)PyArray_NewFromDescr( &PyArray_Type, type_descr, nd, (npy_intp*)dims, NULL, (void*)data, NPY_ARRAY_C_CONTIGUOUS | flags, NULL); if (result == NULL) { return NULL; } Py_INCREF(self); PyArray_SetBaseObject((PyArrayObject *)result, self); return result; } /*@null@*/ PyObject* PyArrayProxy_New( /*@shared@*/ PyObject* self, int nd, const npy_intp* dims, int typenum, const void* data) { return _PyArrayProxy_New(self, nd, dims, typenum, data, NPY_ARRAY_WRITEABLE); } /*@null@*/ PyObject* PyArrayReadOnlyProxy_New( /*@shared@*/ PyObject* self, int nd, const npy_intp* dims, int typenum, const void* data) { return _PyArrayProxy_New(self, nd, dims, typenum, data, 0); } void preoffset_array( PyArrayObject* array, int value) { npy_intp size; double *data; if (value == 1) { return; } size = PyArray_Size((PyObject*)array); data = (double*)PyArray_DATA(array); offset_c_array(data, size, (double)(1 - value)); } void unoffset_array( PyArrayObject* array, int value) { npy_intp size; double *data; if (value == 1) { return; } size = PyArray_Size((PyObject*)array); data = (double*)PyArray_DATA(array); offset_c_array(data, size, (double)-(1 - value)); } void copy_array_to_c_double( PyArrayObject* array, double* dest) { npy_intp size = 1; double* data = NULL; size = PyArray_Size((PyObject*)array); data = (double*)PyArray_DATA(array); memcpy(dest, data, size * sizeof(double)); } void copy_array_to_c_int( PyArrayObject* array, int* dest) { npy_intp size = 1; int* data = NULL; size = PyArray_Size((PyObject*)array); data = (int*)PyArray_DATA(array); memcpy(dest, data, size * sizeof(int)); } int is_null( /*@null@*/ void *p) { if (p == NULL) { PyErr_SetString(PyExc_AssertionError, "Underlying object is NULL."); return 1; } return 0; } /* wcslib represents undefined values using its own special constant, UNDEFINED. To be consistent with the Pythonic way of doing things, it's nicer to represent undefined values using NaN. Unfortunately, in order to get nice mutable arrays in Python, Python must be able to edit the wcsprm values directly. The solution is to store NaNs in the struct "canonically", but convert those NaNs to/from UNDEFINED around every call into a wcslib function. It's not as computationally expensive as it sounds, as all these arrays are quite small. */ static INLINE void wcsprm_fix_values( struct wcsprm* x, value_fixer_t value_fixer) { unsigned int naxis = (unsigned int)x->naxis; value_fixer(x->cd, naxis * naxis); value_fixer(x->cdelt, naxis); value_fixer(x->crder, naxis); value_fixer(x->crota, naxis); value_fixer(x->crpix, naxis); value_fixer(x->crval, naxis); value_fixer(x->csyer, naxis); value_fixer(&x->equinox, 1); value_fixer(&x->latpole, 1); value_fixer(&x->lonpole, 1); value_fixer(&x->mjdavg, 1); value_fixer(&x->mjdobs, 1); value_fixer(x->obsgeo, 6); value_fixer(&x->cel.phi0, 1); value_fixer(&x->restfrq, 1); value_fixer(&x->restwav, 1); value_fixer(&x->cel.theta0, 1); value_fixer(&x->velangl, 1); value_fixer(&x->velosys, 1); value_fixer(&x->zsource, 1); value_fixer(x->czphs, naxis); value_fixer(x->cperi, naxis); value_fixer(x->mjdref, 2); value_fixer(&x->mjdbeg, 1); value_fixer(&x->mjdend, 1); value_fixer(&x->jepoch, 1); value_fixer(&x->bepoch, 1); value_fixer(&x->tstart, 1); value_fixer(&x->tstop, 1); value_fixer(&x->xposure, 1); value_fixer(&x->timsyer, 1); value_fixer(&x->timrder, 1); value_fixer(&x->timedel, 1); value_fixer(&x->timepixr, 1); value_fixer(&x->timeoffs, 1); value_fixer(&x->telapse, 1); } void wcsprm_c2python( /*@null@*/ struct wcsprm* x) { if (x != NULL) { wcsprm_fix_values(x, &undefined2nan); } } void wcsprm_python2c( /*@null@*/ struct wcsprm* x) { if (x != NULL) { wcsprm_fix_values(x, &nan2undefined); } } /*************************************************************************** * Exceptions * ***************************************************************************/ PyObject* WcsExc_Wcs; PyObject* WcsExc_SingularMatrix; PyObject* WcsExc_InconsistentAxisTypes; PyObject* WcsExc_InvalidTransform; PyObject* WcsExc_InvalidCoordinate; PyObject* WcsExc_NoSolution; PyObject* WcsExc_InvalidSubimageSpecification; PyObject* WcsExc_NonseparableSubimageCoordinateSystem; PyObject* WcsExc_NoWcsKeywordsFound; PyObject* WcsExc_InvalidTabularParameters; /* This is an array mapping the wcs status codes to Python exception * types. The exception string is stored as part of wcslib itself in * wcs_errmsg. */ PyObject** wcs_errexc[14]; static PyObject* _new_exception_with_doc(char *name, char *doc, PyObject *base) { return PyErr_NewExceptionWithDoc(name, doc, base, NULL); } #define DEFINE_EXCEPTION(exc) \ WcsExc_##exc = _new_exception_with_doc( \ "astropy.wcs._wcs." #exc "Error", \ doc_##exc, \ WcsExc_Wcs); \ if (WcsExc_##exc == NULL) \ return 1; \ PyModule_AddObject(m, #exc "Error", WcsExc_##exc); \ int _define_exceptions( PyObject* m) { WcsExc_Wcs = _new_exception_with_doc( "astropy.wcs._wcs.WcsError", doc_WcsError, PyExc_ValueError); if (WcsExc_Wcs == NULL) { return 1; } PyModule_AddObject(m, "WcsError", WcsExc_Wcs); DEFINE_EXCEPTION(SingularMatrix); DEFINE_EXCEPTION(InconsistentAxisTypes); DEFINE_EXCEPTION(InvalidTransform); DEFINE_EXCEPTION(InvalidCoordinate); DEFINE_EXCEPTION(NoSolution); DEFINE_EXCEPTION(InvalidSubimageSpecification); DEFINE_EXCEPTION(NonseparableSubimageCoordinateSystem); DEFINE_EXCEPTION(NoWcsKeywordsFound); DEFINE_EXCEPTION(InvalidTabularParameters); return 0; } const char* wcslib_get_error_message(int status) { return wcs_errmsg[status]; } void wcserr_to_python_exc(const struct wcserr *err) { PyObject *exc; if (err == NULL) { PyErr_SetString(PyExc_RuntimeError, "NULL error object in wcslib"); } else { if (err->status > 0 && err->status <= WCS_ERRMSG_MAX) { exc = *wcs_errexc[err->status]; } else { exc = PyExc_RuntimeError; } /* This is technically not thread-safe -- make sure we have the GIL */ wcsprintf_set(NULL); wcserr_prt(err, ""); PyErr_SetString(exc, wcsprintf_buf()); } } void wcs_to_python_exc(const struct wcsprm *wcs) { PyObject* exc; const struct wcserr *err = wcs->err; if (err == NULL) { PyErr_SetString(PyExc_RuntimeError, "NULL error object in wcslib"); } else { if (err->status > 0 && err->status < WCS_ERRMSG_MAX) { exc = *wcs_errexc[err->status]; } else { exc = PyExc_RuntimeError; } /* This is technically not thread-safe -- make sure we have the GIL */ wcsprintf_set(NULL); wcsperr(wcs, ""); PyErr_SetString(exc, wcsprintf_buf()); } } void wcserr_fix_to_python_exc(const struct wcserr *err) { PyObject *exc; if (err == NULL) { PyErr_SetString(PyExc_RuntimeError, "NULL error object in wcslib"); } else { if (err->status > 0 && err->status <= FIXERR_NO_REF_PIX_VAL) { exc = PyExc_ValueError; } else { exc = PyExc_RuntimeError; } /* This is technically not thread-safe -- make sure we have the GIL */ wcsprintf_set(NULL); wcserr_prt(err, ""); PyErr_SetString(exc, wcsprintf_buf()); } } void wcshdr_err_to_python_exc(int status, const struct wcsprm *wcs) { /* Add error to wcslib error buffer */ wcsperr(wcs, NULL); if (status > 0 && status != WCSHDRERR_PARSER) { PyErr_Format( PyExc_MemoryError, "Memory allocation error:\n%s", wcsprintf_buf() ); } else { PyErr_Format( PyExc_ValueError, "Internal error in wcslib header parser:\n %s", wcsprintf_buf() ); } } /*************************************************************************** Property helpers ***************************************************************************/ #define SHAPE_STR_LEN 2048 /* Helper function to display the desired shape of an array as a string, eg. 2x2 */ static void shape_to_string( int ndims, const npy_intp* dims, char* str /* [SHAPE_STR_LEN] */) { int i; char value[32]; /* More than large enough to hold string rep of a 64-bit integer (way overkill) */ if (ndims > 3) { strncpy(str, "ERROR", 6); return; } str[0] = 0; for (i = 0; i < ndims; ++i) { snprintf(value, 32, "%d", (int)dims[i]); strncat(str, value, 32); if (i != ndims - 1) { strncat(str, "x", 2); } } } /* get_string is inlined */ int set_string( const char* propname, PyObject* value, char* dest, Py_ssize_t maxlen) { char* buffer; Py_ssize_t len; PyObject* ascii_obj = NULL; int result = -1; if (check_delete(propname, value)) { return -1; } if (PyUnicode_Check(value)) { ascii_obj = PyUnicode_AsASCIIString(value); if (ascii_obj == NULL) { goto end; } if (PyBytes_AsStringAndSize(ascii_obj, &buffer, &len) == -1) { goto end; } } else if (PyBytes_Check(value)) { if (PyBytes_AsStringAndSize(value, &buffer, &len) == -1) { goto end; } } else { PyErr_SetString(PyExc_TypeError, "value must be bytes or unicode"); goto end; } if (len > maxlen) { PyErr_Format( PyExc_ValueError, "'%s' must be less than %u characters", propname, (unsigned int)maxlen); goto end; } strncpy(dest, buffer, (size_t)maxlen); result = 0; end: Py_XDECREF(ascii_obj); return result; } /* get_bool is inlined */ int set_bool( const char* propname, PyObject* value, int* dest) { if (check_delete(propname, value)) { return -1; } *dest = PyObject_IsTrue(value); return 0; } /* get_int is inlined */ int set_int( const char* propname, PyObject* value, int* dest) { long value_int; if (check_delete(propname, value)) { return -1; } value_int = PyLong_AsLong(value); if (value_int == -1 && PyErr_Occurred()) { return -1; } if ((unsigned long)value_int > 0x7fffffff) { PyErr_SetString(PyExc_OverflowError, "integer value too large"); return -1; } *dest = (int)value_int; return 0; } /* get_double is inlined */ int set_double( const char* propname, PyObject* value, double* dest) { if (check_delete(propname, value)) { return -1; } *dest = PyFloat_AsDouble(value); if (PyErr_Occurred()) { return -1; } else { return 0; } } /* get_double_array is inlined */ int set_double_array( const char* propname, PyObject* value, int ndims, const npy_intp* dims, double* dest) { PyArrayObject* value_array = NULL; npy_int i = 0; char shape_str[SHAPE_STR_LEN]; if (check_delete(propname, value)) { return -1; } value_array = (PyArrayObject*)PyArray_ContiguousFromAny(value, NPY_DOUBLE, ndims, ndims); if (value_array == NULL) { return -1; } if (dims != NULL) { for (i = 0; i < ndims; ++i) { if (PyArray_DIM(value_array, i) != dims[i]) { shape_to_string(ndims, dims, shape_str); PyErr_Format( PyExc_ValueError, "'%s' array is the wrong shape, must be %s", propname, shape_str); Py_DECREF(value_array); return -1; } } } copy_array_to_c_double(value_array, dest); Py_DECREF(value_array); return 0; } int set_int_array( const char* propname, PyObject* value, int ndims, const npy_intp* dims, int* dest) { PyArrayObject* value_array = NULL; npy_int i = 0; char shape_str[SHAPE_STR_LEN]; if (check_delete(propname, value)) { return -1; } value_array = (PyArrayObject*)PyArray_ContiguousFromAny(value, NPY_INT, ndims, ndims); if (value_array == NULL) { return -1; } if (dims != NULL) { for (i = 0; i < ndims; ++i) { if (PyArray_DIM(value_array, i) != dims[i]) { shape_to_string(ndims, dims, shape_str); PyErr_Format( PyExc_ValueError, "'%s' array is the wrong shape, must be %s", propname, shape_str); Py_DECREF(value_array); return -1; } } } copy_array_to_c_int(value_array, dest); Py_DECREF(value_array); return 0; } /* get_str_list is inlined */ int set_str_list( const char* propname, PyObject* value, Py_ssize_t len, Py_ssize_t maxlen, char (*dest)[72]) { PyObject* str = NULL; Py_ssize_t input_len; Py_ssize_t i = 0; if (check_delete(propname, value)) { return -1; } if (maxlen == 0) { maxlen = 68; } if (!PySequence_Check(value)) { PyErr_Format( PyExc_TypeError, "'%s' must be a sequence of strings", propname); return -1; } if (PySequence_Size(value) != len) { PyErr_Format( PyExc_ValueError, "len(%s) must be %u", propname, (unsigned int)len); return -1; } /* We go through the list twice, once to verify that the list is in the correct format, and then again to do the data copy. This way, we won't partially copy the contents and then throw an exception. */ for (i = 0; i < len; ++i) { str = PySequence_GetItem(value, i); if (str == NULL) { return -1; } if (!(PyBytes_CheckExact(str) || PyUnicode_CheckExact(str))) { PyErr_Format( PyExc_TypeError, "'%s' must be a sequence of bytes or strings", propname); Py_DECREF(str); return -1; } input_len = PySequence_Size(str); if (input_len > maxlen) { PyErr_Format( PyExc_ValueError, "Each entry in '%s' must be less than %u characters", propname, (unsigned int)maxlen); Py_DECREF(str); return -1; } else if (input_len == -1) { Py_DECREF(str); return -1; } Py_DECREF(str); } for (i = 0; i < len; ++i) { str = PySequence_GetItem(value, i); if (str == NULL) { /* Theoretically, something has gone really wrong here, since we've already verified the list. */ PyErr_Clear(); PyErr_Format( PyExc_RuntimeError, "Input values have changed underneath us. Something is seriously wrong."); return -1; } if (set_string(propname, str, dest[i], maxlen)) { PyErr_Clear(); PyErr_Format( PyExc_RuntimeError, "Input values have changed underneath us. Something is seriously wrong."); Py_DECREF(str); return -1; } Py_DECREF(str); } return 0; } /*@null@*/ PyObject* get_pscards( /*@unused@*/ const char* propname, struct pscard* ps, int nps) { PyObject* result = NULL; PyObject* subresult = NULL; Py_ssize_t i = 0; if (nps < 0) { nps = 0; } result = PyList_New((Py_ssize_t)nps); if (result == NULL) { return NULL; } if (nps && ps == NULL) { PyErr_SetString(PyExc_MemoryError, "NULL pointer"); return NULL; } for (i = 0; i < (Py_ssize_t)nps; ++i) { subresult = Py_BuildValue("iis", ps[i].i, ps[i].m, ps[i].value); if (subresult == NULL) { Py_DECREF(result); return NULL; } if (PyList_SetItem(result, i, subresult)) { Py_DECREF(subresult); Py_DECREF(result); return NULL; } } return result; } int set_pscards( /*@unused@*/ const char* propname, PyObject* value, struct pscard** ps, int *nps, int *npsmax) { PyObject* subvalue = NULL; Py_ssize_t i = 0; Py_ssize_t size = 0; int ival = 0; int mval = 0; const char* strvalue = 0; void* newmem = NULL; if (!PySequence_Check(value)) return -1; size = PySequence_Size(value); if (size > 0x7fffffff) { /* Must be a 32-bit size */ return -1; } if (size > (Py_ssize_t)*npsmax) { newmem = malloc(sizeof(struct pscard) * size); if (newmem == NULL) { PyErr_SetString(PyExc_MemoryError, "Could not allocate memory."); return -1; } free(*ps); *ps = newmem; *npsmax = (int)size; } /* Verify the entire list for correct types first, so we don't have to undo anything copied into the canonical array. */ for (i = 0; i < size; ++i) { subvalue = PySequence_GetItem(value, i); if (subvalue == NULL) { return -1; } if (!PyArg_ParseTuple(subvalue, "iis", &ival, &mval, &strvalue)) { Py_DECREF(subvalue); return -1; } Py_DECREF(subvalue); } for (i = 0; i < size; ++i) { subvalue = PySequence_GetItem(value, i); if (subvalue == NULL) { return -1; } if (!PyArg_ParseTuple(subvalue, "iis", &ival, &mval, &strvalue)) { Py_DECREF(subvalue); return -1; } Py_DECREF(subvalue); (*ps)[i].i = ival; (*ps)[i].m = mval; strncpy((*ps)[i].value, strvalue, 72); (*ps)[i].value[71] = '\0'; (*nps) = (int)(i + 1); } return 0; } /*@null@*/ PyObject* get_pvcards( /*@unused@*/ const char* propname, struct pvcard* pv, int npv) { PyObject* result = NULL; PyObject* subresult = NULL; Py_ssize_t i = 0; if (npv < 0) { npv = 0; } result = PyList_New((Py_ssize_t)npv); if (result == NULL) { return NULL; } if (npv && pv == NULL) { PyErr_SetString(PyExc_MemoryError, "NULL pointer"); return NULL; } for (i = 0; i < (Py_ssize_t)npv; ++i) { subresult = Py_BuildValue("iid", pv[i].i, pv[i].m, pv[i].value); if (subresult == NULL) { Py_DECREF(result); return NULL; } if (PyList_SetItem(result, i, subresult)) { Py_DECREF(subresult); Py_DECREF(result); return NULL; } } return result; } int set_pvcards( /*@propname@*/ const char* propname, PyObject* value, struct pvcard** pv, int *npv, int *npvmax) { PyObject* fastseq = NULL; struct pvcard* newmem = NULL; Py_ssize_t size; int ret = -1; int i; fastseq = PySequence_Fast(value, "Expected sequence type"); if (!fastseq) goto done; size = PySequence_Fast_GET_SIZE(value); newmem = malloc(sizeof(struct pvcard) * size); /* Raise exception if size is nonzero but newmem * could not be allocated. */ if (size && !newmem) { PyErr_SetString(PyExc_MemoryError, "Could not allocate memory."); return -1; } for (i = 0; i < size; ++i) { if (!PyArg_ParseTuple(PySequence_Fast_GET_ITEM(value, i), "iid", &newmem[i].i, &newmem[i].m, &newmem[i].value)) { goto done; } } if (size <= (Py_ssize_t)*npvmax) { memcpy(*pv, newmem, sizeof(struct pvcard) * size); } else { /* (size > (Py_ssize_t)*npvmax) */ free(*pv); *npv = (int)size; *pv = newmem; newmem = NULL; } *npv = (int)size; ret = 0; done: Py_XDECREF(fastseq); free(newmem); return ret; } PyObject* get_deepcopy( PyObject* obj, PyObject* memo) { if (PyObject_HasAttrString(obj, "__deepcopy__")) { return PyObject_CallMethod(obj, "__deepcopy__", "O", memo); } else { return PyObject_CallMethod(obj, "__copy__", ""); } } /*************************************************************************** * Miscellaneous helper functions * ***************************************************************************/ int parse_unsafe_unit_conversion_spec( const char* arg, int* ctrl) { const char* p = NULL; *ctrl = 0; for (p = arg; *p != '\0'; ++p) { switch (*p) { case 's': case 'S': *ctrl |= 1; break; case 'h': case 'H': *ctrl |= 2; break; case 'd': case 'D': *ctrl |= 4; break; default: PyErr_SetString( PyExc_ValueError, "translate_units may only contain the characters 's', 'h' or 'd'"); return 1; } } return 0; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/src/sip.c0000644000175100001710000001651100000000000016274 0ustar00vstsdocker/* Author: Michael Droettboom mdroe@stsci.edu */ #include "astropy_wcs/sip.h" #include #include #include #include #define SIP_ERRMSG(status) WCSERR_SET(status) void sip_clear( sip_t* sip) { assert(sip != NULL); sip->a_order = 0; sip->a = NULL; sip->b_order = 0; sip->b = NULL; sip->ap_order = 0; sip->ap = NULL; sip->bp_order = 0; sip->bp = NULL; sip->crpix[0] = 0.0; sip->crpix[1] = 0.0; sip->scratch = NULL; sip->err = NULL; } int sip_init( sip_t* sip, const unsigned int a_order, const double* a, const unsigned int b_order, const double* b, const unsigned int ap_order, const double* ap, const unsigned int bp_order, const double* bp, const double* crpix /* [2] */) { unsigned int a_size = 0; unsigned int b_size = 0; unsigned int ap_size = 0; unsigned int bp_size = 0; unsigned int scratch_size = 0; int status = 0; struct wcserr** err = NULL; static const char *function = "sip_init"; assert(sip != NULL); sip_clear(sip); err = &(sip->err); /* We we have one of A/B or AP/BP, we must have both. */ if ((a == NULL) ^ (b == NULL)) { return wcserr_set( SIP_ERRMSG(WCSERR_BAD_COORD_TRANS), "Both A and B SIP transform must be defined"); } if ((ap == NULL) ^ (bp == NULL)) { return wcserr_set( SIP_ERRMSG(WCSERR_BAD_COORD_TRANS), "Both AP and BP SIP transform must be defined"); } if (a != NULL) { sip->a_order = a_order; a_size = (a_order + 1) * (a_order + 1) * sizeof(double); sip->a = malloc(a_size); if (sip->a == NULL) { sip_free(sip); status = wcserr_set( SIP_ERRMSG(WCSERR_MEMORY), "Memory allocation failed"); goto exit; } memcpy(sip->a, a, a_size); if (a_order > scratch_size) { scratch_size = a_order; } sip->b_order = b_order; b_size = (b_order + 1) * (b_order + 1) * sizeof(double); sip->b = malloc(b_size); if (sip->b == NULL) { sip_free(sip); status = wcserr_set( SIP_ERRMSG(WCSERR_MEMORY), "Memory allocation failed"); goto exit; } memcpy(sip->b, b, b_size); if (b_order > scratch_size) { scratch_size = b_order; } } if (ap != NULL) { sip->ap_order = ap_order; ap_size = (ap_order + 1) * (ap_order + 1) * sizeof(double); sip->ap = malloc(ap_size); if (sip->ap == NULL) { sip_free(sip); status = wcserr_set( SIP_ERRMSG(WCSERR_MEMORY), "Memory allocation failed"); goto exit; } memcpy(sip->ap, ap, ap_size); if (ap_order > scratch_size) { scratch_size = ap_order; } sip->bp_order = bp_order; bp_size = (bp_order + 1) * (bp_order + 1) * sizeof(double); sip->bp = malloc(bp_size); if (sip->bp == NULL) { sip_free(sip); status = wcserr_set( SIP_ERRMSG(WCSERR_MEMORY), "Memory allocation failed"); goto exit; } memcpy(sip->bp, bp, bp_size); if (bp_order > scratch_size) { scratch_size = bp_order; } } scratch_size = (scratch_size + 1) * sizeof(double); sip->scratch = malloc(scratch_size); if (sip->scratch == NULL) { sip_free(sip); status = wcserr_set( SIP_ERRMSG(WCSERR_MEMORY), "Memory allocation failed"); goto exit; } sip->crpix[0] = crpix[0]; sip->crpix[1] = crpix[1]; exit: return status; } void sip_free(sip_t* sip) { free(sip->a); sip->a = NULL; free(sip->b); sip->b = NULL; free(sip->ap); sip->ap = NULL; free(sip->bp); sip->bp = NULL; free(sip->scratch); sip->scratch = NULL; free(sip->err); sip->err = NULL; } static INLINE double lu( const unsigned int order, const double* const matrix, const int x, const int y) { int index; assert(x >= 0 && x <= (int)order); assert(y >= 0 && y <= (int)order); index = x * ((int)order + 1) + y; assert(index >= 0 && index < ((int)order + 1) * ((int)order + 1)); return matrix[index]; } static int sip_compute( /*@unused@*/ const unsigned int naxes, const unsigned int nelem, const unsigned int m, /*@null@*/ const double* a, const unsigned int n, /*@null@*/ const double* b, const double* crpix /* [2] */, /*@null@*/ double* tmp, /*@null@*/ const double* input /* [NAXES][nelem] */, /*@null@*/ double* output /* [NAXES][nelem] */) { unsigned int i; int j, k; double x, y; double sum; const double* input_ptr; double* output_ptr; assert(a != NULL); assert(b != NULL); assert(crpix != NULL); assert(tmp != NULL); assert(input != NULL); assert(output != NULL); /* Avoid segfaults */ if (input == NULL || output == NULL || tmp == NULL || crpix == NULL) { return 1; } /* If we have one, we must have both... */ if ((a == NULL) ^ (b == NULL)) { return 6; } /* If no distortion, just return values */ if (a == NULL /* && b == NULL ... implied */) { return 0; } input_ptr = input; output_ptr = output; for (i = 0; i < nelem; ++i) { x = *input_ptr++ - crpix[0]; y = *input_ptr++ - crpix[1]; for (j = 0; j <= (int)m; ++j) { tmp[j] = lu(m, a, (int)m-j, j); for (k = j-1; k >= 0; --k) { tmp[j] = (y * tmp[j]) + lu(m, a, (int)m-j, k); } } sum = tmp[0]; for (j = (int)m; j > 0; --j) { sum = x * sum + tmp[(int)m - j + 1]; } *output_ptr++ += sum; for (j = 0; j <= (int)n; ++j) { tmp[j] = lu(n, b, (int)n-j, j); for (k = j-1; k >= 0; --k) { tmp[j] = (y * tmp[j]) + lu(n, b, (int)n-j, k); } } sum = tmp[0]; for (j = (int)n; j > 0; --j) { sum = x * sum + tmp[n - j + 1]; } *output_ptr++ += sum; } return 0; } int sip_pix2deltas( const sip_t* sip, const unsigned int naxes, const unsigned int nelem, const double* pix /* [NAXES][nelem] */, double* deltas /* [NAXES][nelem] */) { if (sip == NULL) { return 1; } return sip_compute(naxes, nelem, sip->a_order, sip->a, sip->b_order, sip->b, sip->crpix, (double *)sip->scratch, pix, deltas); } int sip_foc2deltas( const sip_t* sip, const unsigned int naxes, const unsigned int nelem, const double* foc /* [NAXES][nelem] */, double* deltas /* [NAXES][nelem] */) { if (sip == NULL) { return 1; } return sip_compute(naxes, nelem, sip->ap_order, sip->ap, sip->bp_order, sip->bp, sip->crpix, (double *)sip->scratch, foc, deltas); } int sip_pix2foc( const sip_t* sip, const unsigned int naxes, const unsigned int nelem, const double* pix /* [NAXES][nelem] */, double* foc /* [NAXES][nelem] */) { assert(pix); assert(foc); if (pix != foc) { memcpy(foc, pix, sizeof(double) * naxes * nelem); } return sip_pix2deltas(sip, naxes, nelem, pix, foc); } int sip_foc2pix( const sip_t* sip, const unsigned int naxes, const unsigned int nelem, const double* foc /* [NAXES][nelem] */, double* pix /* [NAXES][nelem] */) { assert(pix); assert(foc); if (pix != foc) { memcpy(pix, foc, sizeof(double) * naxes * nelem); } return sip_foc2deltas(sip, naxes, nelem, foc, pix); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/src/sip_wrap.c0000644000175100001710000003205000000000000017321 0ustar00vstsdocker/* Author: Michael Droettboom mdroe@stsci.edu */ #define NO_IMPORT_ARRAY #include "astropy_wcs/sip_wrap.h" #include "astropy_wcs/docstrings.h" #include "wcs.h" static void PySip_dealloc( PySip* self) { sip_free(&self->x); Py_TYPE(self)->tp_free((PyObject*)self); } /*@null@*/ static PyObject * PySip_new( PyTypeObject* type, /*@unused@*/ PyObject* args, /*@unused@*/ PyObject* kwds) { PySip* self; self = (PySip*)type->tp_alloc(type, 0); if (self != NULL) { sip_clear(&self->x); } return (PyObject*)self; } static int convert_matrix( /*@null@*/ PyObject* pyobj, PyArrayObject** array, double** data, unsigned int* order) { if (pyobj == Py_None) { *array = NULL; *data = NULL; *order = 0; return 0; } *array = (PyArrayObject*)PyArray_ContiguousFromAny( pyobj, NPY_DOUBLE, 2, 2); if (*array == NULL) { return -1; } if (PyArray_DIM(*array, 0) != PyArray_DIM(*array, 1)) { PyErr_SetString(PyExc_ValueError, "Matrix must be square."); return -1; } *data = (double*)PyArray_DATA(*array); *order = (unsigned int)PyArray_DIM(*array, 0) - 1; return 0; } static int PySip_init( PySip* self, PyObject* args, /*@unused@*/ PyObject* kwds) { PyObject* py_a = NULL; PyObject* py_b = NULL; PyObject* py_ap = NULL; PyObject* py_bp = NULL; PyObject* py_crpix = NULL; PyArrayObject* a = NULL; PyArrayObject* b = NULL; PyArrayObject* ap = NULL; PyArrayObject* bp = NULL; PyArrayObject* crpix = NULL; double* a_data = NULL; double* b_data = NULL; double* ap_data = NULL; double* bp_data = NULL; unsigned int a_order = 0; unsigned int b_order = 0; unsigned int ap_order = 0; unsigned int bp_order = 0; int status = -1; if (!PyArg_ParseTuple(args, "OOOOO:Sip.__init__", &py_a, &py_b, &py_ap, &py_bp, &py_crpix)) { return -1; } if (convert_matrix(py_a, &a, &a_data, &a_order) || convert_matrix(py_b, &b, &b_data, &b_order) || convert_matrix(py_ap, &ap, &ap_data, &ap_order) || convert_matrix(py_bp, &bp, &bp_data, &bp_order)) { goto exit; } crpix = (PyArrayObject*)PyArray_ContiguousFromAny(py_crpix, NPY_DOUBLE, 1, 1); if (crpix == NULL) { goto exit; } if (PyArray_DIM(crpix, 0) != 2) { PyErr_SetString(PyExc_ValueError, "CRPIX wrong length"); goto exit; } status = sip_init(&self->x, a_order, a_data, b_order, b_data, ap_order, ap_data, bp_order, bp_data, PyArray_DATA(crpix)); exit: Py_XDECREF(a); Py_XDECREF(b); Py_XDECREF(ap); Py_XDECREF(bp); Py_XDECREF(crpix); if (status == 0) { return 0; } else if (status == -1) { /* Exception already set */ return -1; } else { wcserr_to_python_exc(self->x.err); return -1; } } /*@null@*/ static PyObject* PySip_pix2foc( PySip* self, PyObject* args, PyObject* kwds) { PyObject* pixcrd_obj = NULL; int origin = 1; PyArrayObject* pixcrd = NULL; PyArrayObject* foccrd = NULL; double* foccrd_data = NULL; unsigned int nelem = 0; unsigned int i, j; int status = -1; const char* keywords[] = { "pixcrd", "origin", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oi:pix2foc", (char **)keywords, &pixcrd_obj, &origin)) { return NULL; } if (self->x.a == NULL || self->x.b == NULL) { PyErr_SetString( PyExc_ValueError, "SIP object does not have coefficients for pix2foc transformation (A and B)"); return NULL; } pixcrd = (PyArrayObject*)PyArray_ContiguousFromAny(pixcrd_obj, NPY_DOUBLE, 2, 2); if (pixcrd == NULL) { goto exit; } if (PyArray_DIM(pixcrd, 1) != 2) { PyErr_SetString(PyExc_ValueError, "Pixel array must be an Nx2 array"); goto exit; } foccrd = (PyArrayObject*)PyArray_SimpleNew(2, PyArray_DIMS(pixcrd), NPY_DOUBLE); if (foccrd == NULL) { goto exit; } Py_BEGIN_ALLOW_THREADS preoffset_array(pixcrd, origin); status = sip_pix2foc(&self->x, (unsigned int)PyArray_DIM(pixcrd, 1), (unsigned int)PyArray_DIM(pixcrd, 0), (const double*)PyArray_DATA(pixcrd), (double*)PyArray_DATA(foccrd)); unoffset_array(pixcrd, origin); /* Adjust for crpix */ foccrd_data = (double *)PyArray_DATA(foccrd); nelem = (unsigned int)PyArray_DIM(foccrd, 0); for (i = 0; i < nelem; ++i) { for (j = 0; j < 2; ++j) { foccrd_data[i*2 + j] -= self->x.crpix[j]; } } unoffset_array(foccrd, origin); Py_END_ALLOW_THREADS exit: Py_XDECREF(pixcrd); if (status == 0) { return (PyObject*)foccrd; } else { Py_XDECREF(foccrd); if (status == -1) { /* Exception already set */ return NULL; } else { wcserr_to_python_exc(self->x.err); return NULL; } } } /*@null@*/ static PyObject* PySip_foc2pix( PySip* self, PyObject* args, PyObject* kwds) { PyObject* foccrd_obj = NULL; int origin = 1; PyArrayObject* foccrd = NULL; PyArrayObject* pixcrd = NULL; int status = -1; double* foccrd_data = NULL; unsigned int nelem = 0; unsigned int i, j; const char* keywords[] = { "foccrd", "origin", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oi:foc2pix", (char **)keywords, &foccrd_obj, &origin)) { return NULL; } if (self->x.ap == NULL || self->x.bp == NULL) { PyErr_SetString( PyExc_ValueError, "SIP object does not have coefficients for foc2pix transformation (AP and BP)"); return NULL; } foccrd = (PyArrayObject*)PyArray_ContiguousFromAny(foccrd_obj, NPY_DOUBLE, 2, 2); if (foccrd == NULL) { goto exit; } if (PyArray_DIM(foccrd, 1) != 2) { PyErr_SetString(PyExc_ValueError, "Pixel array must be an Nx2 array"); goto exit; } pixcrd = (PyArrayObject*)PyArray_SimpleNew(2, PyArray_DIMS(foccrd), NPY_DOUBLE); if (pixcrd == NULL) { status = 2; goto exit; } Py_BEGIN_ALLOW_THREADS preoffset_array(foccrd, origin); /* Adjust for crpix */ foccrd_data = (double *)PyArray_DATA(foccrd); nelem = (unsigned int)PyArray_DIM(foccrd, 0); for (i = 0; i < nelem; ++i) { for (j = 0; j < 2; ++j) { foccrd_data[i*2 + j] += self->x.crpix[j]; } } status = sip_foc2pix(&self->x, (unsigned int)PyArray_DIM(pixcrd, 1), (unsigned int)PyArray_DIM(pixcrd, 0), (double*)PyArray_DATA(foccrd), (double*)PyArray_DATA(pixcrd)); /* Adjust for crpix */ for (i = 0; i < nelem; ++i) { for (j = 0; j < 2; ++j) { foccrd_data[i*2 + j] -= self->x.crpix[j]; } } unoffset_array(foccrd, origin); unoffset_array(pixcrd, origin); Py_END_ALLOW_THREADS exit: Py_XDECREF(foccrd); if (status == 0) { return (PyObject*)pixcrd; } else { Py_XDECREF(pixcrd); if (status == -1) { /* Exception already set */ return NULL; } else { wcserr_to_python_exc(self->x.err); return NULL; } } } /*@null@*/ static PyObject* PySip_get_a( PySip* self, /*@unused@*/ void* closure) { npy_intp dims[2]; if (self->x.a == NULL) { Py_INCREF(Py_None); return Py_None; } dims[0] = (npy_intp)self->x.a_order + 1; dims[1] = (npy_intp)self->x.a_order + 1; return get_double_array("a", self->x.a, 2, dims, (PyObject*)self); } /*@null@*/ static PyObject* PySip_get_b( PySip* self, /*@unused@*/ void* closure) { npy_intp dims[2]; if (self->x.b == NULL) { Py_INCREF(Py_None); return Py_None; } dims[0] = (npy_intp)self->x.b_order + 1; dims[1] = (npy_intp)self->x.b_order + 1; return get_double_array("b", self->x.b, 2, dims, (PyObject*)self); } /*@null@*/ static PyObject* PySip_get_ap( PySip* self, /*@unused@*/ void* closure) { npy_intp dims[2]; if (self->x.ap == NULL) { Py_INCREF(Py_None); return Py_None; } dims[0] = (npy_intp)self->x.ap_order + 1; dims[1] = (npy_intp)self->x.ap_order + 1; return get_double_array("ap", self->x.ap, 2, dims, (PyObject*)self); } /*@null@*/ static PyObject* PySip_get_bp( PySip* self, /*@unused@*/ void* closure) { npy_intp dims[2]; if (self->x.bp == NULL) { Py_INCREF(Py_None); return Py_None; } dims[0] = (npy_intp)self->x.bp_order + 1; dims[1] = (npy_intp)self->x.bp_order + 1; return get_double_array("bp", self->x.bp, 2, dims, (PyObject*)self); } static PyObject* PySip_get_a_order( PySip* self, /*@unused@*/ void* closure) { return get_int("a_order", (long int)self->x.a_order); } static PyObject* PySip_get_b_order( PySip* self, /*@unused@*/ void* closure) { return get_int("b_order", (long int)self->x.b_order); } static PyObject* PySip_get_ap_order( PySip* self, /*@unused@*/ void* closure) { return get_int("ap_order", (long int)self->x.ap_order); } static PyObject* PySip_get_bp_order( PySip* self, /*@unused@*/ void* closure) { return get_int("bp_order", (long int)self->x.bp_order); } static PyObject* PySip_get_crpix( PySip* self, /*@unused@*/ void* closure) { Py_ssize_t naxis = 2; return get_double_array("crpix", self->x.crpix, 1, &naxis, (PyObject*)self); } static PyObject* PySip___copy__( PySip* self, /*@unused@*/ PyObject* args, /*@unused@*/ PyObject* kwds) { PySip* copy = NULL; copy = (PySip*)PySip_new(&PySipType, NULL, NULL); if (copy == NULL) { return NULL; } if (sip_init(©->x, self->x.a_order, self->x.a, self->x.b_order, self->x.b, self->x.ap_order, self->x.ap, self->x.bp_order, self->x.bp, self->x.crpix)) { Py_DECREF(copy); return NULL; } return (PyObject*)copy; } static PyGetSetDef PySip_getset[] = { {"a", (getter)PySip_get_a, NULL, (char *)doc_a}, {"a_order", (getter)PySip_get_a_order, NULL, (char *)doc_a_order}, {"b", (getter)PySip_get_b, NULL, (char *)doc_b}, {"b_order", (getter)PySip_get_b_order, NULL, (char *)doc_b_order}, {"ap", (getter)PySip_get_ap, NULL, (char *)doc_ap}, {"ap_order", (getter)PySip_get_ap_order, NULL, (char *)doc_ap_order}, {"bp", (getter)PySip_get_bp, NULL, (char *)doc_bp}, {"bp_order", (getter)PySip_get_bp_order, NULL, (char *)doc_bp_order}, {"crpix", (getter)PySip_get_crpix, NULL, (char *)doc_crpix}, {NULL} }; static PyMethodDef PySip_methods[] = { {"__copy__", (PyCFunction)PySip___copy__, METH_NOARGS, NULL}, {"__deepcopy__", (PyCFunction)PySip___copy__, METH_O, NULL}, {"pix2foc", (PyCFunction)PySip_pix2foc, METH_VARARGS|METH_KEYWORDS, doc_sip_pix2foc}, {"foc2pix", (PyCFunction)PySip_foc2pix, METH_VARARGS|METH_KEYWORDS, doc_sip_foc2pix}, {NULL} }; PyTypeObject PySipType = { PyVarObject_HEAD_INIT(NULL, 0) "astropy.wcs.Sip", /*tp_name*/ sizeof(PySip), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)PySip_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash */ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ doc_Sip, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ PySip_methods, /* tp_methods */ 0, /* tp_members */ PySip_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)PySip_init, /* tp_init */ 0, /* tp_alloc */ PySip_new, /* tp_new */ }; int _setup_sip_type( PyObject* m) { if (PyType_Ready(&PySipType) < 0) return -1; Py_INCREF(&PySipType); return PyModule_AddObject(m, "Sip", (PyObject *)&PySipType); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/src/str_list_proxy.c0000644000175100001710000001417700000000000020613 0ustar00vstsdocker/* Author: Michael Droettboom mdroe@stsci.edu */ #define NO_IMPORT_ARRAY #include "astropy_wcs/pyutil.h" /*************************************************************************** * List-of-strings proxy object ***************************************************************************/ static PyTypeObject PyStrListProxyType; typedef struct { PyObject_HEAD /*@null@*/ /*@shared@*/ PyObject* pyobject; Py_ssize_t size; Py_ssize_t maxsize; char (*array)[72]; } PyStrListProxy; static void PyStrListProxy_dealloc( PyStrListProxy* self) { PyObject_GC_UnTrack(self); Py_XDECREF(self->pyobject); Py_TYPE(self)->tp_free((PyObject*)self); } /*@null@*/ static PyObject * PyStrListProxy_new( PyTypeObject* type, /*@unused@*/ PyObject* args, /*@unused@*/ PyObject* kwds) { PyStrListProxy* self = NULL; self = (PyStrListProxy*)type->tp_alloc(type, 0); if (self != NULL) { self->pyobject = NULL; } return (PyObject*)self; } static int PyStrListProxy_traverse( PyStrListProxy* self, visitproc visit, void *arg) { Py_VISIT(self->pyobject); return 0; } static int PyStrListProxy_clear( PyStrListProxy *self) { Py_CLEAR(self->pyobject); return 0; } /*@null@*/ PyObject * PyStrListProxy_New( /*@shared@*/ PyObject* owner, Py_ssize_t size, Py_ssize_t maxsize, char (*array)[72]) { PyStrListProxy* self = NULL; if (maxsize == 0) { maxsize = 68; } self = (PyStrListProxy*)PyStrListProxyType.tp_alloc(&PyStrListProxyType, 0); if (self == NULL) { return NULL; } Py_XINCREF(owner); self->pyobject = owner; self->size = size; self->maxsize = maxsize; self->array = array; return (PyObject*)self; } static Py_ssize_t PyStrListProxy_len( PyStrListProxy* self) { return self->size; } /*@null@*/ static PyObject* PyStrListProxy_getitem( PyStrListProxy* self, Py_ssize_t index) { if (index >= self->size || index < 0) { PyErr_SetString(PyExc_IndexError, "index out of range"); return NULL; } return get_string("string", self->array[index]); } static int PyStrListProxy_setitem( PyStrListProxy* self, Py_ssize_t index, PyObject* arg) { if (index >= self->size || index < 0) { PyErr_SetString(PyExc_IndexError, "index out of range"); return -1; } return set_string("string", arg, self->array[index], self->maxsize); } /*@null@*/ PyObject* str_list_proxy_repr( char (*array)[72], Py_ssize_t size, Py_ssize_t maxsize) { char* buffer = NULL; char* wp = NULL; char* rp = NULL; Py_ssize_t i = 0; Py_ssize_t j = 0; PyObject* result = NULL; /* These are in descending order, so we can exit the loop quickly. They are in pairs: (char_to_escape, char_escaped) */ const char* escapes = "\\\\''\rr\ff\vv\nn\tt\bb\aa"; const char* e = NULL; char next_char = '\0'; /* Overallocating to allow for escaped characters */ buffer = malloc((size_t)size*maxsize*2 + 2); if (buffer == NULL) { PyErr_SetString(PyExc_MemoryError, "Could not allocate memory."); return NULL; } wp = buffer; *wp++ = '['; for (i = 0; i < size; ++i) { *wp++ = '\''; rp = array[i]; for (j = 0; j < maxsize && *rp != '\0'; ++j) { /* Check if this character should be escaped */ e = escapes; next_char = *rp++; do { if (next_char > *e) { break; } else if (next_char == *e) { *wp++ = '\\'; next_char = *(++e); break; } else { e += 2; } } while (*e != '\0'); *wp++ = next_char; } *wp++ = '\''; /* Add a comma for all but the last one */ if (i != size - 1) { *wp++ = ','; *wp++ = ' '; } } *wp++ = ']'; *wp++ = '\0'; result = PyUnicode_FromString(buffer); free(buffer); return result; } /*@null@*/ static PyObject* PyStrListProxy_repr( PyStrListProxy* self) { return str_list_proxy_repr(self->array, self->size, self->maxsize); } static PySequenceMethods PyStrListProxy_sequence_methods = { (lenfunc)PyStrListProxy_len, NULL, NULL, (ssizeargfunc)PyStrListProxy_getitem, NULL, (ssizeobjargproc)PyStrListProxy_setitem, NULL, NULL, NULL, NULL }; static PyTypeObject PyStrListProxyType = { PyVarObject_HEAD_INIT(NULL, 0) "astropy.wcs.StrListProxy", /*tp_name*/ sizeof(PyStrListProxy), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)PyStrListProxy_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ (reprfunc)PyStrListProxy_repr, /*tp_repr*/ 0, /*tp_as_number*/ &PyStrListProxy_sequence_methods, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash */ 0, /*tp_call*/ (reprfunc)PyStrListProxy_repr, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ 0, /* tp_doc */ (traverseproc)PyStrListProxy_traverse, /* tp_traverse */ (inquiry)PyStrListProxy_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ PyStrListProxy_new, /* tp_new */ }; int _setup_str_list_proxy_type( /*@unused@*/ PyObject* m) { if (PyType_Ready(&PyStrListProxyType) < 0) { return 1; } return 0; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/src/unit_list_proxy.c0000644000175100001710000002066600000000000020762 0ustar00vstsdocker/* Author: Michael Droettboom mdroe@stsci.edu */ #define NO_IMPORT_ARRAY #include "astropy_wcs/pyutil.h" #include "astropy_wcs/str_list_proxy.h" /*************************************************************************** * List-of-units proxy object ***************************************************************************/ #define MAXSIZE 68 #define ARRAYSIZE 72 static PyTypeObject PyUnitListProxyType; typedef struct { PyObject_HEAD /*@null@*/ /*@shared@*/ PyObject* pyobject; Py_ssize_t size; char (*array)[ARRAYSIZE]; PyObject* unit_class; } PyUnitListProxy; static void PyUnitListProxy_dealloc( PyUnitListProxy* self) { PyObject_GC_UnTrack(self); Py_XDECREF(self->pyobject); Py_TYPE(self)->tp_free((PyObject*)self); } /*@null@*/ static PyObject * PyUnitListProxy_new( PyTypeObject* type, /*@unused@*/ PyObject* args, /*@unused@*/ PyObject* kwds) { PyUnitListProxy* self = NULL; self = (PyUnitListProxy*)type->tp_alloc(type, 0); if (self != NULL) { self->pyobject = NULL; self->unit_class = NULL; } return (PyObject*)self; } static int PyUnitListProxy_traverse( PyUnitListProxy* self, visitproc visit, void *arg) { Py_VISIT(self->pyobject); Py_VISIT(self->unit_class); return 0; } static int PyUnitListProxy_clear( PyUnitListProxy *self) { Py_CLEAR(self->pyobject); Py_CLEAR(self->unit_class); return 0; } /*@null@*/ PyObject * PyUnitListProxy_New( /*@shared@*/ PyObject* owner, Py_ssize_t size, char (*array)[ARRAYSIZE]) { PyUnitListProxy* self = NULL; PyObject *units_module; PyObject *units_dict; PyObject *unit_class; units_module = PyImport_ImportModule("astropy.units"); if (units_module == NULL) { return NULL; } units_dict = PyModule_GetDict(units_module); if (units_dict == NULL) { return NULL; } unit_class = PyDict_GetItemString(units_dict, "Unit"); if (unit_class == NULL) { PyErr_SetString(PyExc_RuntimeError, "Could not import Unit class"); return NULL; } Py_INCREF(unit_class); self = (PyUnitListProxy*)PyUnitListProxyType.tp_alloc( &PyUnitListProxyType, 0); if (self == NULL) { return NULL; } Py_XINCREF(owner); self->pyobject = owner; self->size = size; self->array = array; self->unit_class = unit_class; return (PyObject*)self; } static Py_ssize_t PyUnitListProxy_len( PyUnitListProxy* self) { return self->size; } static PyObject* _get_unit( PyObject *unit_class, PyObject *unit) { PyObject *args; PyObject *kw; PyObject *result; kw = Py_BuildValue("{s:s,s:s}", "format", "fits", "parse_strict", "warn"); if (kw == NULL) { return NULL; } args = PyTuple_New(1); if (args == NULL) { Py_DECREF(kw); return NULL; } PyTuple_SetItem(args, 0, unit); Py_INCREF(unit); result = PyObject_Call(unit_class, args, kw); Py_DECREF(args); Py_DECREF(kw); return result; } /*@null@*/ static PyObject* PyUnitListProxy_getitem( PyUnitListProxy* self, Py_ssize_t index) { PyObject *value; PyObject *result; if (index >= self->size || index < 0) { PyErr_SetString(PyExc_IndexError, "index out of range"); return NULL; } value = PyUnicode_FromString(self->array[index]); result = _get_unit(self->unit_class, value); Py_DECREF(value); return result; } static PyObject* PyUnitListProxy_richcmp( PyObject *a, PyObject *b, int op){ PyUnitListProxy *lhs, *rhs; Py_ssize_t idx; int equal = 1; assert(a != NULL && b != NULL); if (!PyObject_TypeCheck(a, &PyUnitListProxyType) || !PyObject_TypeCheck(b, &PyUnitListProxyType)) { Py_RETURN_NOTIMPLEMENTED; } if (op != Py_EQ && op != Py_NE) { Py_RETURN_NOTIMPLEMENTED; } /* The actual comparison of the two objects. unit_class is ignored because * it's not an essential property of the instances. */ lhs = (PyUnitListProxy *)a; rhs = (PyUnitListProxy *)b; if (lhs->size != rhs->size) { equal = 0; } for (idx = 0; idx < lhs->size && equal == 1; idx++) { if (strncmp(lhs->array[idx], rhs->array[idx], ARRAYSIZE) != 0) { equal = 0; } } if ((op == Py_EQ && equal == 1) || (op == Py_NE && equal == 0)) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static int PyUnitListProxy_setitem( PyUnitListProxy* self, Py_ssize_t index, PyObject* arg) { PyObject* value; PyObject* unicode_value; PyObject* bytes_value; if (index >= self->size || index < 0) { PyErr_SetString(PyExc_IndexError, "index out of range"); return -1; } value = _get_unit(self->unit_class, arg); if (value == NULL) { return -1; } unicode_value = PyObject_CallMethod(value, "to_string", "s", "fits"); if (unicode_value == NULL) { Py_DECREF(value); return -1; } Py_DECREF(value); if (PyUnicode_Check(unicode_value)) { bytes_value = PyUnicode_AsASCIIString(unicode_value); if (bytes_value == NULL) { Py_DECREF(unicode_value); return -1; } Py_DECREF(unicode_value); } else { bytes_value = unicode_value; } strncpy(self->array[index], PyBytes_AsString(bytes_value), MAXSIZE); Py_DECREF(bytes_value); return 0; } /*@null@*/ static PyObject* PyUnitListProxy_repr( PyUnitListProxy* self) { return str_list_proxy_repr(self->array, self->size, MAXSIZE); } static PySequenceMethods PyUnitListProxy_sequence_methods = { (lenfunc)PyUnitListProxy_len, NULL, NULL, (ssizeargfunc)PyUnitListProxy_getitem, NULL, (ssizeobjargproc)PyUnitListProxy_setitem, NULL, NULL, NULL, NULL }; static PyTypeObject PyUnitListProxyType = { PyVarObject_HEAD_INIT(NULL, 0) "astropy.wcs.UnitListProxy", /*tp_name*/ sizeof(PyUnitListProxy), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)PyUnitListProxy_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ (reprfunc)PyUnitListProxy_repr, /*tp_repr*/ 0, /*tp_as_number*/ &PyUnitListProxy_sequence_methods, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash */ 0, /*tp_call*/ (reprfunc)PyUnitListProxy_repr, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ 0, /* tp_doc */ (traverseproc)PyUnitListProxy_traverse, /* tp_traverse */ (inquiry)PyUnitListProxy_clear, /* tp_clear */ (richcmpfunc)PyUnitListProxy_richcmp, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ PyUnitListProxy_new, /* tp_new */ }; int set_unit_list( PyObject* owner, const char* propname, PyObject* value, Py_ssize_t len, char (*dest)[ARRAYSIZE]) { PyObject* unit = NULL; PyObject* proxy = NULL; Py_ssize_t i = 0; if (check_delete(propname, value)) { return -1; } if (!PySequence_Check(value)) { PyErr_Format( PyExc_TypeError, "'%s' must be a sequence of strings", propname); return -1; } if (PySequence_Size(value) != len) { PyErr_Format( PyExc_ValueError, "len(%s) must be %u", propname, (unsigned int)len); return -1; } proxy = PyUnitListProxy_New(owner, len, dest); if (proxy == NULL) { return -1; } for (i = 0; i < len; ++i) { unit = PySequence_GetItem(value, i); if (unit == NULL) { Py_DECREF(proxy); return -1; } if (PySequence_SetItem(proxy, i, unit) == -1) { Py_DECREF(proxy); Py_DECREF(unit); return -1; } Py_DECREF(unit); } Py_DECREF(proxy); return 0; } int _setup_unit_list_proxy_type( /*@unused@*/ PyObject* m) { if (PyType_Ready(&PyUnitListProxyType) < 0) { return 1; } return 0; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/src/util.c0000644000175100001710000000173500000000000016460 0ustar00vstsdocker/* Author: Michael Droettboom mdroe@stsci.edu */ #define NO_IMPORT_ARRAY #include "astropy_wcs/util.h" #include #include void set_invalid_to_nan( const int ncoord, const int nelem, double* const data, const int* const stat) { int i = 0; double* d = data; const int* s = stat; const int* s_end = stat + ncoord; double n; #ifndef NAN #define INF (DBL_MAX+DBL_MAX) #define NAN (INF-INF) #endif // Note that stat is a bit mask, so we need to mask only some of // the coordinates depending on the bit mask values. n = NAN; for ( ; s != s_end; ++s) { if (*s) { int bit = 1; for (i = 0; i < nelem; ++i) { if (*s & bit) { *d = n; } d++; // We don't need to worry about overflow here because the WCS // class cannot be used for naxis > 15 so nelem will always // be <=15. bit <<= 1; } } else { d += nelem; } } } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/src/wcslib_auxprm_wrap.c0000644000175100001710000001672300000000000021416 0ustar00vstsdocker#define NO_IMPORT_ARRAY #include "astropy_wcs/wcslib_auxprm_wrap.h" #include #include #include /* It gets to be really tedious to type long docstrings in ANSI C syntax (since multi-line strings literals are not valid). Therefore, the docstrings are written in doc/docstrings.py, which are then converted by setup.py into docstrings.h, which we include here. */ #include "astropy_wcs/docstrings.h" /*************************************************************************** * PyAuxprm methods * ***************************************************************************/ static PyObject* PyAuxprm_new(PyTypeObject* type, PyObject* args, PyObject* kwds) { PyAuxprm* self; self = (PyAuxprm*)type->tp_alloc(type, 0); return (PyObject*)self; } static int PyAuxprm_traverse(PyAuxprm* self, visitproc visit, void *arg) { Py_VISIT(self->owner); return 0; } static int PyAuxprm_clear(PyAuxprm* self) { Py_CLEAR(self->owner); return 0; } static void PyAuxprm_dealloc(PyAuxprm* self) { PyAuxprm_clear(self); Py_TYPE(self)->tp_free((PyObject*)self); } PyAuxprm* PyAuxprm_cnew(PyObject* wcsprm, struct auxprm* x) { PyAuxprm* self; self = (PyAuxprm*)(&PyAuxprmType)->tp_alloc(&PyAuxprmType, 0); if (self == NULL) return NULL; self->x = x; Py_INCREF(wcsprm); self->owner = wcsprm; return self; } static void auxprmprt(const struct auxprm *aux) { if (aux == 0x0) return; wcsprintf("rsun_ref:"); if (aux->rsun_ref != UNDEFINED) wcsprintf(" %f", aux->rsun_ref); wcsprintf("\ndsun_obs:"); if (aux->dsun_obs != UNDEFINED) wcsprintf(" %f", aux->dsun_obs); wcsprintf("\ncrln_obs:"); if (aux->crln_obs != UNDEFINED) wcsprintf(" %f", aux->crln_obs); wcsprintf("\nhgln_obs:"); if (aux->hgln_obs != UNDEFINED) wcsprintf(" %f", aux->hgln_obs); wcsprintf("\nhglt_obs:"); if (aux->hglt_obs != UNDEFINED) wcsprintf(" %f", aux->hglt_obs); return; } static PyObject* PyAuxprm___str__(PyAuxprm* self) { /* This is not thread-safe, but since we're holding onto the GIL, we can assume we won't have thread conflicts */ wcsprintf_set(NULL); auxprmprt(self->x); return PyUnicode_FromString(wcsprintf_buf()); } /*************************************************************************** * Member getters/setters (properties) */ static PyObject* PyAuxprm_get_rsun_ref(PyAuxprm* self, void* closure) { if(self->x == NULL || self->x->rsun_ref == UNDEFINED) { Py_RETURN_NONE; } else { return get_double("rsun_ref", self->x->rsun_ref); } } static int PyAuxprm_set_rsun_ref(PyAuxprm* self, PyObject* value, void* closure) { if(self->x == NULL) { return -1; } else if (value == Py_None) { self->x->rsun_ref = UNDEFINED; return 0; } else { return set_double("rsun_ref", value, &self->x->rsun_ref); } } static PyObject* PyAuxprm_get_dsun_obs(PyAuxprm* self, void* closure) { if(self->x == NULL || self->x->dsun_obs == UNDEFINED) { Py_RETURN_NONE; } else { return get_double("dsun_obs", self->x->dsun_obs); } } static int PyAuxprm_set_dsun_obs(PyAuxprm* self, PyObject* value, void* closure) { if(self->x == NULL) { return -1; } else if (value == Py_None) { self->x->dsun_obs = UNDEFINED; return 0; } else { return set_double("dsun_obs", value, &self->x->dsun_obs); } } static PyObject* PyAuxprm_get_crln_obs(PyAuxprm* self, void* closure) { if(self->x == NULL || self->x->crln_obs == UNDEFINED) { Py_RETURN_NONE; } else { return get_double("crln_obs", self->x->crln_obs); } } static int PyAuxprm_set_crln_obs(PyAuxprm* self, PyObject* value, void* closure) { if(self->x == NULL) { return -1; } else if (value == Py_None) { self->x->crln_obs = UNDEFINED; return 0; } else { return set_double("crln_obs", value, &self->x->crln_obs); } } static PyObject* PyAuxprm_get_hgln_obs(PyAuxprm* self, void* closure) { if(self->x == NULL || self->x->hgln_obs == UNDEFINED) { Py_RETURN_NONE; } else { return get_double("hgln_obs", self->x->hgln_obs); } } static int PyAuxprm_set_hgln_obs(PyAuxprm* self, PyObject* value, void* closure) { if(self->x == NULL) { return -1; } else if (value == Py_None) { self->x->hgln_obs = UNDEFINED; return 0; } else { return set_double("hgln_obs", value, &self->x->hgln_obs); } } static PyObject* PyAuxprm_get_hglt_obs(PyAuxprm* self, void* closure) { if(self->x == NULL || self->x->hglt_obs == UNDEFINED) { Py_RETURN_NONE; } else { return get_double("hglt_obs", self->x->hglt_obs); } } static int PyAuxprm_set_hglt_obs(PyAuxprm* self, PyObject* value, void* closure) { if(self->x == NULL) { return -1; } else if (value == Py_None) { self->x->hglt_obs = UNDEFINED; return 0; } else { return set_double("hglt_obs", value, &self->x->hglt_obs); } } /*************************************************************************** * PyAuxprm definition structures */ static PyGetSetDef PyAuxprm_getset[] = { {"rsun_ref", (getter)PyAuxprm_get_rsun_ref, (setter)PyAuxprm_set_rsun_ref, (char *)doc_rsun_ref}, {"dsun_obs", (getter)PyAuxprm_get_dsun_obs, (setter)PyAuxprm_set_dsun_obs, (char *)doc_dsun_obs}, {"crln_obs", (getter)PyAuxprm_get_crln_obs, (setter)PyAuxprm_set_crln_obs, (char *)doc_crln_obs}, {"hgln_obs", (getter)PyAuxprm_get_hgln_obs, (setter)PyAuxprm_set_hgln_obs, (char *)doc_hgln_obs}, {"hglt_obs", (getter)PyAuxprm_get_hglt_obs, (setter)PyAuxprm_set_hglt_obs, (char *)doc_hglt_obs}, {NULL} }; PyTypeObject PyAuxprmType = { PyVarObject_HEAD_INIT(NULL, 0) "astropy.wcs.Auxprm", /*tp_name*/ sizeof(PyAuxprm), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)PyAuxprm_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash */ 0, /*tp_call*/ (reprfunc)PyAuxprm___str__, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ doc_Auxprm, /* tp_doc */ (traverseproc)PyAuxprm_traverse, /* tp_traverse */ (inquiry)PyAuxprm_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ PyAuxprm_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ }; int _setup_auxprm_type(PyObject* m) { if (PyType_Ready(&PyAuxprmType) < 0) { return -1; } Py_INCREF(&PyAuxprmType); PyModule_AddObject(m, "Auxprm", (PyObject *)&PyAuxprmType); return 0; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/src/wcslib_tabprm_wrap.c0000755000175100001710000002453400000000000021371 0ustar00vstsdocker/* Author: Michael Droettboom mdroe@stsci.edu */ #define NO_IMPORT_ARRAY #include "astropy_wcs/wcslib_tabprm_wrap.h" #include #include #include /* It gets to be really tedious to type long docstrings in ANSI C syntax (since multi-line strings literals are not valid). Therefore, the docstrings are written in doc/docstrings.py, which are then converted by setup.py into docstrings.h, which we include here. */ #include "astropy_wcs/docstrings.h" /*************************************************************************** * Helper functions * ***************************************************************************/ static INLINE void note_change(PyTabprm* self) { self->x->flag = 0; } static int make_fancy_dims(PyTabprm* self, int* ndims, npy_intp* dims) { int i, M; M = self->x->M; if (M + 1 > NPY_MAXDIMS) { PyErr_SetString(PyExc_ValueError, "Too many dimensions"); return -1; } *ndims = M + 1; for (i = 0; i < M; ++i) { dims[i] = self->x->K[M-1-i]; } dims[M] = M; return 0; } PyObject** tab_errexc[6]; static void wcslib_tab_to_python_exc(int status) { if (status > 0 && status < 6) { PyErr_SetString(*tab_errexc[status], tab_errmsg[status]); } else { PyErr_SetString( PyExc_RuntimeError, "Unknown error occurred. Something is seriously wrong."); } } /*************************************************************************** * PyTabprm methods */ static int PyTabprm_traverse( PyTabprm* self, visitproc visit, void *arg) { Py_VISIT(self->owner); return 0; } static int PyTabprm_clear( PyTabprm* self) { Py_CLEAR(self->owner); return 0; } static void PyTabprm_dealloc( PyTabprm* self) { PyTabprm_clear(self); Py_TYPE(self)->tp_free((PyObject*)self); } PyTabprm* PyTabprm_cnew(PyObject* wcsprm, struct tabprm* x) { PyTabprm* self; self = (PyTabprm*)(&PyTabprmType)->tp_alloc(&PyTabprmType, 0); if (self == NULL) return NULL; self->x = x; Py_INCREF(wcsprm); self->owner = wcsprm; return self; } static int PyTabprm_cset( PyTabprm* self) { int status = 0; status = tabset(self->x); if (status == 0) { return 0; } else { wcslib_tab_to_python_exc(status); return -1; } } /*@null@*/ static PyObject* PyTabprm_set( PyTabprm* self) { if (PyTabprm_cset(self)) { return NULL; } Py_RETURN_NONE; } /*@null@*/ static PyObject* PyTabprm_print_contents( PyTabprm* self) { if (PyTabprm_cset(self)) { return NULL; } /* This is not thread-safe, but since we're holding onto the GIL, we can assume we won't have thread conflicts */ wcsprintf_set(NULL); tabprt(self->x); printf("%s", wcsprintf_buf()); fflush(stdout); Py_RETURN_NONE; } /*@null@*/ static PyObject* PyTabprm___str__( PyTabprm* self) { if (PyTabprm_cset(self)) { return NULL; } /* This is not thread-safe, but since we're holding onto the GIL, we can assume we won't have thread conflicts */ wcsprintf_set(NULL); tabprt(self->x); return PyUnicode_FromString(wcsprintf_buf()); } /*************************************************************************** * Member getters/setters (properties) */ /*@null@*/ static PyObject* PyTabprm_get_coord( PyTabprm* self, /*@unused@*/ void* closure) { int ndims; npy_intp dims[NPY_MAXDIMS]; if (is_null(self->x->coord)) { return NULL; } if (make_fancy_dims(self, &ndims, dims)) { return NULL; } return get_double_array("coord", self->x->coord, ndims, dims, (PyObject*)self); } /*@null@*/ static int PyTabprm_set_coord( PyTabprm* self, PyObject* value, /*@unused@*/ void* closure) { int ndims; npy_intp dims[NPY_MAXDIMS]; if (is_null(self->x->coord)) { return -1; } if (make_fancy_dims(self, &ndims, dims)) { return -1; } return set_double_array("coord", value, ndims, dims, self->x->coord); } /*@null@*/ static PyObject* PyTabprm_get_crval( PyTabprm* self, /*@unused@*/ void* closure) { Py_ssize_t M = 0; if (is_null(self->x->crval)) { return NULL; } M = (Py_ssize_t)self->x->M; return get_double_array("crval", self->x->crval, 1, &M, (PyObject*)self); } static int PyTabprm_set_crval( PyTabprm* self, PyObject* value, /*@unused@*/ void* closure) { npy_intp M = 0; if (is_null(self->x->crval)) { return -1; } M = (Py_ssize_t)self->x->M; note_change(self); return set_double_array("crval", value, 1, &M, self->x->crval); } /*@null@*/ static PyObject* PyTabprm_get_delta( PyTabprm* self, /*@unused@*/ void* closure) { Py_ssize_t M = 0; if (is_null(self->x->delta)) { return NULL; } M = (Py_ssize_t)self->x->M; return get_double_array("delta", self->x->delta, 1, &M, (PyObject*)self); } /*@null@*/ static PyObject* PyTabprm_get_extrema( PyTabprm* self, /*@unused@*/ void* closure) { int ndims; npy_intp dims[NPY_MAXDIMS]; if (is_null(self->x->coord)) { return NULL; } if (make_fancy_dims(self, &ndims, dims)) { return NULL; } dims[ndims-2] = 2; return get_double_array("extrema", self->x->extrema, ndims, dims, (PyObject*)self); } /*@null@*/ static PyObject* PyTabprm_get_K( PyTabprm* self, /*@unused@*/ void* closure) { Py_ssize_t M = 0; if (is_null(self->x->K)) { return NULL; } M = (Py_ssize_t)self->x->M; return get_int_array("K", self->x->K, 1, &M, (PyObject*)self); } /*@null@*/ static PyObject* PyTabprm_get_M( PyTabprm* self, /*@unused@*/ void* closure) { return get_int("M", self->x->M); } /*@null@*/ static PyObject* PyTabprm_get_map( PyTabprm* self, /*@unused@*/ void* closure) { Py_ssize_t M = 0; if (is_null(self->x->map)) { return NULL; } M = (Py_ssize_t)self->x->M; return get_int_array("map", self->x->map, 1, &M, (PyObject*)self); } static int PyTabprm_set_map( PyTabprm* self, PyObject* value, /*@unused@*/ void* closure) { npy_intp M = 0; if (is_null(self->x->map)) { return -1; } M = (Py_ssize_t)self->x->M; note_change(self); return set_int_array("map", value, 1, &M, self->x->map); } /*@null@*/ static PyObject* PyTabprm_get_nc( PyTabprm* self, /*@unused@*/ void* closure) { return get_int("nc", self->x->nc); } /*@null@*/ static PyObject* PyTabprm_get_p0( PyTabprm* self, /*@unused@*/ void* closure) { Py_ssize_t M = 0; if (is_null(self->x->p0)) { return NULL; } M = (Py_ssize_t)self->x->M; return get_int_array("p0", self->x->p0, 1, &M, (PyObject*)self); } /*@null@*/ static PyObject* PyTabprm_get_sense( PyTabprm* self, /*@unused@*/ void* closure) { Py_ssize_t M = 0; if (is_null(self->x->sense)) { return NULL; } M = (Py_ssize_t)self->x->M; return get_int_array("sense", self->x->sense, 1, &M, (PyObject*)self); } /*************************************************************************** * PyTabprm definition structures */ static PyGetSetDef PyTabprm_getset[] = { {"coord", (getter)PyTabprm_get_coord, (setter)PyTabprm_set_coord, (char *)doc_coord}, {"crval", (getter)PyTabprm_get_crval, (setter)PyTabprm_set_crval, (char *)doc_crval_tabprm}, {"delta", (getter)PyTabprm_get_delta, NULL, (char *)doc_delta}, {"extrema", (getter)PyTabprm_get_extrema, NULL, (char *)doc_extrema}, {"K", (getter)PyTabprm_get_K, NULL, (char *)doc_K}, {"M", (getter)PyTabprm_get_M, NULL, (char *)doc_M}, {"map", (getter)PyTabprm_get_map, (setter)PyTabprm_set_map, (char *)doc_map}, {"nc", (getter)PyTabprm_get_nc, NULL, (char *)doc_nc}, {"p0", (getter)PyTabprm_get_p0, NULL, (char *)doc_p0}, {"sense", (getter)PyTabprm_get_sense, NULL, (char *)doc_sense}, {NULL} }; static PyMethodDef PyTabprm_methods[] = { {"print_contents", (PyCFunction)PyTabprm_print_contents, METH_NOARGS, doc_print_contents_tabprm}, {"set", (PyCFunction)PyTabprm_set, METH_NOARGS, doc_set_tabprm}, {NULL} }; PyTypeObject PyTabprmType = { PyVarObject_HEAD_INIT(NULL, 0) "astropy.wcs.Tabprm", /*tp_name*/ sizeof(PyTabprm), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)PyTabprm_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash */ 0, /*tp_call*/ (reprfunc)PyTabprm___str__, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ doc_Tabprm, /* tp_doc */ (traverseproc)PyTabprm_traverse, /* tp_traverse */ (inquiry)PyTabprm_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ PyTabprm_methods, /* tp_methods */ 0, /* tp_members */ PyTabprm_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ }; int _setup_tabprm_type( PyObject* m) { if (PyType_Ready(&PyTabprmType) < 0) { return -1; } Py_INCREF(&PyTabprmType); PyModule_AddObject(m, "Tabprm", (PyObject *)&PyTabprmType); tab_errexc[0] = NULL; /* Success */ tab_errexc[1] = &PyExc_MemoryError; /* Null wcsprm pointer passed */ tab_errexc[2] = &PyExc_MemoryError; /* Memory allocation failed */ tab_errexc[3] = &WcsExc_InvalidTabularParameters; /* Invalid tabular parameters */ tab_errexc[4] = &WcsExc_InvalidCoordinate; /* One or more of the x coordinates were invalid */ tab_errexc[5] = &WcsExc_InvalidCoordinate; /* One or more of the world coordinates were invalid */ return 0; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/src/wcslib_wrap.c0000755000175100001710000027550000000000000020025 0ustar00vstsdocker/* Author: Michael Droettboom mdroe@stsci.edu */ #define NO_IMPORT_ARRAY #include "astropy_wcs/wcslib_wrap.h" #include "astropy_wcs/wcslib_auxprm_wrap.h" #include "astropy_wcs/wcslib_tabprm_wrap.h" #include "astropy_wcs/wcslib_wtbarr_wrap.h" #include "astropy_wcs/wcslib_units_wrap.h" #include "astropy_wcs/unit_list_proxy.h" #include /* from Python */ #include #include #include #include #include #include #include #include #include #include "astropy_wcs/isnan.h" #include "astropy_wcs/distortion.h" /* It gets to be really tedious to type long docstrings in ANSI C syntax (since multi-line strings literals are not valid). Therefore, the docstrings are written in doc/docstrings.py, which are then converted by setup.py into docstrings.h, which we include here. */ #include "astropy_wcs/docstrings.h" /*************************************************************************** * Helper functions * ***************************************************************************/ enum e_altlin { has_pc = 1, has_cd = 2, has_crota = 4 }; static int is_valid_alt_key( const char* key) { if (key[1] != '\0' || !(key[0] == ' ' || (key[0] >= 'A' && key[0] <= 'Z'))) { PyErr_SetString(PyExc_ValueError, "key must be ' ' or 'A'-'Z'"); return 0; } return 1; } static int convert_rejections_to_warnings() { char buf[1024]; const char *src; char *dst; int last_was_space; PyObject *wcs_module = NULL; PyObject *FITSFixedWarning = NULL; int status = -1; char delimiter; #ifdef HAVE_WCSLIB_VERSION delimiter = ','; #else delimiter = ':'; #endif if (wcsprintf_buf()[0] == 0) { return 0; } wcs_module = PyImport_ImportModule("astropy.wcs"); if (wcs_module == NULL) { goto exit; } FITSFixedWarning = PyObject_GetAttrString( wcs_module, "FITSFixedWarning"); if (FITSFixedWarning == NULL) { goto exit; } src = wcsprintf_buf(); while (*src != 0) { dst = buf; /* Read the first line, removing any repeated spaces */ last_was_space = 0; for (; *src != 0; ++src) { if (*src == ' ') { if (!last_was_space) { *(dst++) = *src; last_was_space = 1; } } else if (*src == '\n') { ++src; break; } else { *(dst++) = *src; last_was_space = 0; } } *(dst++) = '\n'; /* For the second line, remove everything up to and including the first colon */ for (; *src != 0; ++src) { if (*src == delimiter) { ++src; break; } } /* Read to the end of the second line, removing any repeated spaces */ last_was_space = 1; for (; *src != 0; ++src) { if (*src == ' ') { if (!last_was_space) { *(dst++) = *src; last_was_space = 1; } } else if (*src == '\n') { ++src; break; } else { *(dst++) = *src; last_was_space = 0; } } /* NULL terminate the string */ *dst = 0; /* Raise the warning. Depending on the user's configuration, this may raise an exception, and PyErr_WarnEx returns -1. */ if (PyErr_WarnEx(FITSFixedWarning, buf, 1)) { goto exit; } } status = 0; exit: Py_XDECREF(wcs_module); Py_XDECREF(FITSFixedWarning); return status; } /*************************************************************************** * wtbarr-related global variables and functions * ***************************************************************************/ static PyObject *get_wtbarr_data = NULL; void _set_wtbarr_callback(PyObject* callback) { Py_XINCREF(callback); /* Add a reference to new callback */ Py_XDECREF(get_wtbarr_data); /* Dispose of previous callback */ get_wtbarr_data = callback; /* Remember new callback */ } int _update_wtbarr_from_hdulist(PyObject *hdulist, struct wtbarr *wtb) { PyArrayObject *arrayp=NULL; PyObject *result=NULL; int i, naxis, nelem, naxes[NPY_MAXDIMS]; npy_intp *npy_naxes; npy_double *appayp_data; if (hdulist == NULL || hdulist == Py_None) { PyErr_SetString(PyExc_ValueError, "HDUList is required to retrieve -TAB coordinates " "and/or indices."); return 0; } if (wtb->ndim < 1) { PyErr_SetString(PyExc_ValueError, "Number of dimensions should be positive."); return 0; } result = PyObject_CallFunction(get_wtbarr_data, "(OsiiCsli)", hdulist, wtb->extnam, wtb->extver, wtb->extlev, wtb->kind, wtb->ttype, wtb->row, wtb->ndim); if (result == NULL) return 0; arrayp = (PyArrayObject *)PyArray_FromAny(result, PyArray_DescrFromType(NPY_DOUBLE), 0, 0, NPY_ARRAY_CARRAY, NULL); Py_DECREF(result); if (arrayp == NULL) { PyErr_SetString(PyExc_TypeError, "Unable to convert wtbarr callback " "result to a numpy.ndarray."); return 0; } if (!PyArray_Check(arrayp)) { PyErr_SetString(PyExc_TypeError, "wtbarr callback must return a numpy.ndarray type " "coordinate or index array."); Py_DECREF(arrayp); return 0; } naxis = PyArray_NDIM(arrayp); if (naxis == 0) { PyErr_SetString(PyExc_ValueError, "-TAB coordinate or index arrays " "cannot be 0-dimensional."); Py_DECREF(arrayp); return 0; } npy_naxes = PyArray_DIMS(arrayp); for (i = 0; i < naxis; i++) { naxes[i] = (int) npy_naxes[i]; } if (naxis != wtb->ndim) { if (wtb->kind == 'c' && wtb->ndim == 2 && naxis == 1) { /* Allow TDIMn to be omitted for degenerate coordinate arrays. */ naxis = 2; naxes[1] = 1; } else { PyErr_Format(PyExc_ValueError, "An array with an unexpected number of axes was " "received from the callback. Expected %d but got %d.", wtb->ndim, (int) naxis); Py_DECREF(arrayp); return 0; } } if (wtb->kind == 'c') { /* Coordinate array; calculate the array size. */ nelem = naxes[naxis-1]; for (i = 0; i < naxis-1; i++) { *(wtb->dimlen + i) = naxes[naxis-2-i]; nelem *= naxes[i]; } } else { /* Index vector; check length. */ if ((nelem = naxes[naxis-1]) != *(wtb->dimlen)) { /* N.B. coordinate array precedes the index vectors. */ PyErr_Format(PyExc_ValueError, "An index array with an unexpected number of dimensions was " "received from the callback. Expected %d but got %d.", *(wtb->dimlen), (int) nelem); Py_DECREF(arrayp); return 0; } } /* Allocate memory for the array. */ if (!((*wtb->arrayp) = calloc((size_t)nelem, sizeof(double)))) { PyErr_SetString(PyExc_MemoryError, "Out of memory: can't allocate " "coordinate or index array."); Py_DECREF(arrayp); return 0; } /* Read the array from the table. */ appayp_data = (npy_double*)PyArray_DATA(arrayp); for (i = 0; i < nelem; i++) { (*wtb->arrayp)[i] = (double)appayp_data[i]; } Py_DECREF(arrayp); return 1; } /*************************************************************************** * PyWcsprm methods */ static int PyWcsprm_cset(PyWcsprm* self, const int convert); static INLINE void note_change(PyWcsprm* self) { self->x.flag = 0; } static void PyWcsprm_dealloc( PyWcsprm* self) { wcsfree(&self->x); Py_TYPE(self)->tp_free((PyObject*)self); } static PyWcsprm* PyWcsprm_cnew(void) { PyWcsprm* self; self = (PyWcsprm*)(&PyWcsprmType)->tp_alloc(&PyWcsprmType, 0); return self; } static PyObject * PyWcsprm_new( PyTypeObject* type, /*@unused@*/ PyObject* args, /*@unused@*/ PyObject* kwds) { PyWcsprm* self; self = (PyWcsprm*)type->tp_alloc(type, 0); return (PyObject*)self; } static int PyWcsprm_init( PyWcsprm* self, PyObject* args, PyObject* kwds) { int status; PyObject* header_obj = NULL; PyObject* hdulist = NULL; char * header = NULL; Py_ssize_t header_length = 0; Py_ssize_t nkeyrec = 0; const char * key = " "; PyObject* relax_obj = NULL; int relax = 0; int naxis = -1; int keysel = -1; PyObject* colsel = Py_None; PyArrayObject* colsel_array = NULL; int* colsel_data = NULL; int* colsel_ints = NULL; int warnings = 1; int nreject = 0; int nwcs = 0; struct wcsprm* wcs = NULL; int i, j; const char* keywords[] = {"header", "key", "relax", "naxis", "keysel", "colsel", "warnings", "hdulist", NULL}; if (!PyArg_ParseTupleAndKeywords( args, kwds, "|OsOiiOiO:WCSBase.__init__", (char **)keywords, &header_obj, &key, &relax_obj, &naxis, &keysel, &colsel, &warnings, &hdulist)) { return -1; } if (header_obj == NULL || header_obj == Py_None) { if (keysel > 0) { PyErr_SetString( PyExc_ValueError, "If no header is provided, keysel may not be provided either."); return -1; } if (colsel != Py_None) { PyErr_SetString( PyExc_ValueError, "If no header is provided, colsel may not be provided either."); return -1; } /* Default number of axes is 2 */ if (naxis < 0) { naxis = 2; } if (naxis < 1 || naxis > 15) { PyErr_SetString( PyExc_ValueError, "naxis must be in range 1-15"); return -1; } self->x.flag = -1; status = wcsini(1, naxis, &self->x); if (status != 0) { PyErr_SetString( PyExc_MemoryError, self->x.err->msg); return -1; } self->x.alt[0] = key[0]; if (PyWcsprm_cset(self, 0)) { return -1; } wcsprm_c2python(&self->x); return 0; } else { /* header != NULL */ if (PyBytes_AsStringAndSize(header_obj, &header, &header_length)) { return -1; } if (relax_obj == Py_True) { relax = WCSHDR_all; } else if (relax_obj == NULL || relax_obj == Py_False) { relax = WCSHDR_none; } else { relax = (int)PyLong_AsLong(relax_obj); if (relax == -1) { PyErr_SetString( PyExc_ValueError, "relax must be True, False or an integer."); return -1; } } if (!is_valid_alt_key(key)) { return -1; } if (naxis >= 0) { PyErr_SetString( PyExc_ValueError, "naxis may not be provided if a header is provided."); return -1; } nkeyrec = header_length / 80; if (nkeyrec > 0x7fffffff) { PyErr_SetString( PyExc_MemoryError, "header is too long"); return -1; } if (colsel != Py_None) { colsel_array = (PyArrayObject*) PyArray_ContiguousFromAny( colsel, NPY_INT, 1, 1); if (colsel_array == NULL) { return -1; } colsel_ints = malloc(sizeof(int) * (PyArray_DIM(colsel_array, 0) + 1)); if (colsel_ints == NULL) { Py_DECREF(colsel_array); PyErr_SetString( PyExc_MemoryError, "Memory allocation error."); return -1; } colsel_ints[0] = (int)PyArray_DIM(colsel_array, 0); colsel_data = (int *)PyArray_DATA(colsel_array); for (i = 0; i < colsel_ints[0]; ++i) { colsel_ints[i+1] = colsel_data[i]; } Py_DECREF(colsel_array); } wcsprintf_set(NULL); /* Call the header parser twice, the first time to get warnings out about "rejected" keywords (which we can then send to Python as warnings), and the second time to get a corrected wcsprm object. */ if (keysel < 0) { status = wcspih( header, (int)nkeyrec, WCSHDR_reject, 2, &nreject, &nwcs, &wcs); } else { status = wcsbth( header, (int)nkeyrec, WCSHDR_reject, 2, keysel, colsel_ints, &nreject, &nwcs, &wcs); } if (status != 0) { free(colsel_ints); wcshdr_err_to_python_exc(status, wcs); return -1; } wcsvfree(&nwcs, &wcs); if (warnings && convert_rejections_to_warnings()) { free(colsel_ints); return -1; } if (keysel < 0) { status = wcspih( header, (int)nkeyrec, relax, 0, &nreject, &nwcs, &wcs); } else { status = wcsbth( header, (int)nkeyrec, relax, 0, keysel, colsel_ints, &nreject, &nwcs, &wcs); } free(colsel_ints); if (status != 0) { wcshdr_err_to_python_exc(status, wcs); return -1; } if (nwcs == 0) { wcsvfree(&nwcs, &wcs); PyErr_SetString( WcsExc_NoWcsKeywordsFound, "No WCS keywords found in the given header"); return -1; } /* Find the desired WCS */ for (i = 0; i < nwcs; ++i) { if (wcs[i].alt[0] == key[0]) { break; } } if (i >= nwcs) { wcsvfree(&nwcs, &wcs); PyErr_Format( PyExc_KeyError, "No WCS with key '%s' was found in the given header", key); return -1; } if (wcscopy(1, wcs + i, &self->x) != 0) { wcsvfree(&nwcs, &wcs); PyErr_SetString( PyExc_MemoryError, self->x.err->msg); return -1; } if (self->x.ntab) { wcstab(&self->x); for (j = 0; j < self->x.nwtb; j++) { if (!_update_wtbarr_from_hdulist(hdulist, &(self->x.wtb[j]))) { wcsfree(&self->x); return -1; } } } note_change(self); wcsprm_c2python(&self->x); wcsvfree(&nwcs, &wcs); return 0; } } /*@null@*/ static PyObject* PyWcsprm_bounds_check( PyWcsprm* self, PyObject* args, PyObject* kwds) { unsigned char pix2sky = 1; unsigned char sky2pix = 1; int bounds = 0; const char* keywords[] = {"pix2world", "world2pix", NULL}; if (!PyArg_ParseTupleAndKeywords( args, kwds, "|bb:bounds_check", (char **)keywords, &pix2sky, &sky2pix)) { return NULL; } if (pix2sky) { bounds |= 2|4; } if (sky2pix) { bounds |= 1; } wcsprm_python2c(&self->x); wcsbchk(&self->x, bounds); Py_RETURN_NONE; } /*@null@*/ static PyObject* PyWcsprm_copy( PyWcsprm* self) { PyWcsprm* copy = NULL; int status, nelem, i, j, ndim; struct wtbarr *wtb, *wtb0; copy = PyWcsprm_cnew(); if (copy == NULL) { return NULL; } wcsini(0, self->x.naxis, ©->x); wcsprm_python2c(&self->x); status = wcscopy(1, &self->x, ©->x); wcsprm_c2python(&self->x); if (status == 0) { if (PyWcsprm_cset(copy, 0)) { Py_XDECREF(copy); return NULL; } if (self->x.ntab) { wcstab(©->x); for (j = 0; j < copy->x.nwtb; j++) { wtb0 = self->x.wtb + j; wtb = copy->x.wtb + j; for (i = 0; i < wtb0->ndim - 1; i++) { wtb->dimlen[i] = wtb0->dimlen[i]; } /* Allocate memory for the array. */ if (wtb->kind == 'c') { nelem = ndim = wtb->ndim - 1; for (i = 0; i < ndim; i++) { nelem *= wtb->dimlen[i]; } } else { nelem = *(wtb->dimlen); } if (!((*wtb->arrayp) = calloc((size_t)nelem, sizeof(double)))) { PyErr_SetString(PyExc_MemoryError, "Out of memory: can't allocate " "coordinate or index array."); Py_DECREF(copy); return NULL; } for (i = 0; i < nelem; i++) { (*wtb->arrayp)[i] = (*wtb0->arrayp)[i]; } } } wcsprm_c2python(©->x); return (PyObject*)copy; } else { Py_XDECREF(copy); wcs_to_python_exc(&(self->x)); return NULL; } } PyObject* PyWcsprm_find_all_wcs( PyObject* __, PyObject* args, PyObject* kwds) { PyObject* header_obj = NULL; char * header = NULL; Py_ssize_t header_length = 0; Py_ssize_t nkeyrec = 0; PyObject* relax_obj = NULL; int relax = 0; int keysel = 0; int warnings = 1; int nreject = 0; int nwcs = 0; struct wcsprm* wcs = NULL; PyObject* result = NULL; PyWcsprm* subresult = NULL; int i = 0; const char* keywords[] = {"header", "relax", "keysel", "warnings", NULL}; int status = -1; if (!PyArg_ParseTupleAndKeywords( args, kwds, "O|Oii:find_all_wcs", (char **)keywords, &header_obj, &relax_obj, &keysel, &warnings)) { return NULL; } if (PyBytes_AsStringAndSize(header_obj, &header, &header_length)) { return NULL; } nkeyrec = header_length / 80; if (nkeyrec > 0x7fffffff) { PyErr_SetString( PyExc_MemoryError, "header is too long"); return NULL; } if (relax_obj == Py_True) { relax = WCSHDR_all; } else if (relax_obj == NULL || relax_obj == Py_False) { relax = WCSHDR_none; } else { relax = (int)PyLong_AsLong(relax_obj); if (relax == -1) { PyErr_SetString( PyExc_ValueError, "relax must be True, False or an integer."); return NULL; } } /* Call the header parser twice, the first time to get warnings out about "rejected" keywords (which we can then send to Python as warnings), and the second time to get a corrected wcsprm object. */ Py_BEGIN_ALLOW_THREADS if (keysel < 0) { status = wcspih( header, (int)nkeyrec, WCSHDR_reject, 2, &nreject, &nwcs, &wcs); } else { status = wcsbth( header, (int)nkeyrec, WCSHDR_reject, 2, keysel, NULL, &nreject, &nwcs, &wcs); } Py_END_ALLOW_THREADS if (status != 0) { wcshdr_err_to_python_exc(status, wcs); return NULL; } wcsvfree(&nwcs, &wcs); if (warnings && convert_rejections_to_warnings()) { return NULL; } Py_BEGIN_ALLOW_THREADS if (keysel < 0) { status = wcspih( header, (int)nkeyrec, relax, 0, &nreject, &nwcs, &wcs); } else { status = wcsbth( header, (int)nkeyrec, relax, 0, keysel, NULL, &nreject, &nwcs, &wcs); } Py_END_ALLOW_THREADS if (status != 0) { wcshdr_err_to_python_exc(status, wcs); return NULL; } result = PyList_New(nwcs); if (result == NULL) { wcsvfree(&nwcs, &wcs); return NULL; } for (i = 0; i < nwcs; ++i) { subresult = PyWcsprm_cnew(); if (wcscopy(1, wcs + i, &subresult->x) != 0) { Py_DECREF(result); wcsvfree(&nwcs, &wcs); PyErr_SetString( PyExc_MemoryError, "Could not initialize wcsprm object"); return NULL; } if (PyList_SetItem(result, i, (PyObject *)subresult) == -1) { Py_DECREF(subresult); Py_DECREF(result); wcsvfree(&nwcs, &wcs); return NULL; } subresult->x.flag = 0; wcsprm_c2python(&subresult->x); } wcsvfree(&nwcs, &wcs); return result; } static PyObject* PyWcsprm_cdfix( PyWcsprm* self) { int status = 0; wcsprm_python2c(&self->x); status = cdfix(&self->x); wcsprm_c2python(&self->x); if (status == -1 || status == 0) { return PyLong_FromLong((long)status); } else { wcserr_fix_to_python_exc(self->x.err); return NULL; } } static PyObject* PyWcsprm_celfix( PyWcsprm* self) { int status = 0; wcsprm_python2c(&self->x); status = celfix(&self->x); wcsprm_c2python(&self->x); if (status == -1 || status == 0) { return PyLong_FromLong((long)status); } else { wcserr_fix_to_python_exc(self->x.err); return NULL; } } static PyObject * PyWcsprm_compare( PyWcsprm* self, PyObject* args, PyObject* kwds) { int cmp = 0; PyWcsprm *other; double tolerance = 0.0; int equal; int status; const char* keywords[] = {"other", "cmp", "tolerance", NULL}; if (!PyArg_ParseTupleAndKeywords( args, kwds, "O!|id:compare", (char **)keywords, &PyWcsprmType, &other, &cmp, &tolerance)) { return NULL; } wcsprm_python2c(&self->x); wcsprm_python2c(&other->x); status = wcscompare(cmp, tolerance, &self->x, &other->x, &equal); wcsprm_c2python(&self->x); wcsprm_c2python(&other->x); if (status) { wcserr_fix_to_python_exc(self->x.err); return NULL; } else { if (equal) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } } /*@null@*/ static PyObject* PyWcsprm_cylfix( PyWcsprm* self, PyObject* args, PyObject* kwds) { PyObject* naxis_obj = NULL; PyArrayObject* naxis_array = NULL; int* naxis = NULL; int status = 0; const char* keywords[] = {"naxis", NULL}; if (!PyArg_ParseTupleAndKeywords( args, kwds, "|O:cylfix", (char **)keywords, &naxis_obj)) { return NULL; } if (naxis_obj != NULL && naxis_obj != Py_None) { naxis_array = (PyArrayObject*)PyArray_ContiguousFromAny( naxis_obj, NPY_INT, 1, 1); if (naxis_array == NULL) { return NULL; } if (PyArray_DIM(naxis_array, 0) != self->x.naxis) { PyErr_Format( PyExc_ValueError, "naxis must be same length as the number of axes of " "the Wcsprm object (%d).", self->x.naxis); Py_DECREF(naxis_array); return NULL; } naxis = (int*)PyArray_DATA(naxis_array); } wcsprm_python2c(&self->x); status = cylfix(naxis, &self->x); wcsprm_c2python(&self->x); Py_XDECREF(naxis_array); if (status == -1 || status == 0) { return PyLong_FromLong((long)status); } else { wcserr_fix_to_python_exc(self->x.err); return NULL; } } static PyObject* PyWcsprm_datfix( PyWcsprm* self) { int status = 0; wcsprm_python2c(&self->x); status = datfix(&self->x); wcsprm_c2python(&self->x); if (status == -1 || status == 0) { return PyLong_FromLong((long)status); } else { wcserr_fix_to_python_exc(self->x.err); return NULL; } } /*@null@*/ static PyObject* PyWcsprm_fix( PyWcsprm* self, PyObject* args, PyObject* kwds) { const char* translate_units = NULL; int ctrl = 0; PyObject* naxis_obj = NULL; PyArrayObject* naxis_array = NULL; int* naxis = NULL; int stat[NWCSFIX]; struct wcserr err[NWCSFIX]; PyObject* subresult; PyObject* result; int i = 0; int msg_index = 0; const char* message; struct message_map_entry { const char* name; const int index; }; const struct message_map_entry message_map[NWCSFIX] = { {"cdfix", CDFIX}, {"datfix", DATFIX}, #if (NWCSFIX > 6) {"obsfix", OBSFIX}, #endif {"unitfix", UNITFIX}, {"celfix", CELFIX}, {"spcfix", SPCFIX}, {"cylfix", CYLFIX} }; const char* keywords[] = {"translate_units", "naxis", NULL}; if (!PyArg_ParseTupleAndKeywords( args, kwds, "|sO:fix", (char **)keywords, &translate_units, &naxis_obj)) { return NULL; } if (translate_units != NULL) { if (parse_unsafe_unit_conversion_spec(translate_units, &ctrl)) { return NULL; } } if (naxis_obj != NULL && naxis_obj != Py_None) { naxis_array = (PyArrayObject*)PyArray_ContiguousFromAny( naxis_obj, NPY_INT, 1, 1); if (naxis_array == NULL) { return NULL; } if (PyArray_DIM(naxis_array, 0) != self->x.naxis) { PyErr_Format( PyExc_ValueError, "naxis must be same length as the number of axes of " "the Wcprm object (%d).", self->x.naxis); Py_DECREF(naxis_array); return NULL; } naxis = (int*)PyArray_DATA(naxis_array); } memset(err, 0, sizeof(struct wcserr) * NWCSFIX); wcsprm_python2c(&self->x); wcsfixi(ctrl, naxis, &self->x, stat, err); wcsprm_c2python(&self->x); /* We're done with this already, so deref now so we don't have to remember later */ Py_XDECREF(naxis_array); result = PyDict_New(); if (result == NULL) { return NULL; } for (i = 0; i < NWCSFIX; ++i) { msg_index = stat[message_map[i].index]; message = err[message_map[i].index].msg; if (message == NULL || message[0] == 0) { if (msg_index == FIXERR_SUCCESS) { message = "Success"; } else { message = "No change"; } } subresult = PyUnicode_FromString(message); if (subresult == NULL || PyDict_SetItemString(result, message_map[i].name, subresult)) { Py_XDECREF(subresult); Py_XDECREF(result); return NULL; } Py_XDECREF(subresult); } return result; } /*@null@*/ static PyObject* PyWcsprm_get_cdelt_func( PyWcsprm* self, /*@unused@*/ PyObject* args, /*@unused@*/ PyObject* kwds) { Py_ssize_t naxis = 0; if (is_null(self->x.cdelt)) { return NULL; } if (PyWcsprm_cset(self, 1)) { return NULL; } naxis = self->x.naxis; return get_double_array_readonly("cdelt", self->x.cdelt, 1, &naxis, (PyObject*)self); } /*@null@*/ static PyObject* PyWcsprm_get_pc_func( PyWcsprm* self, /*@unused@*/ PyObject* args, /*@unused@*/ PyObject* kwds) { npy_intp dims[2]; if (is_null(self->x.pc)) { return NULL; } if (PyWcsprm_cset(self, 1)) { return NULL; } dims[0] = self->x.naxis; dims[1] = self->x.naxis; return get_double_array_readonly("pc", self->x.pc, 2, dims, (PyObject*)self); } /*@null@*/ static PyObject* PyWcsprm_get_ps( PyWcsprm* self, /*@unused@*/ PyObject* args, /*@unused@*/ PyObject* kwds) { return get_pscards("ps", self->x.ps, self->x.nps); } /*@null@*/ static PyObject* PyWcsprm_get_pv( PyWcsprm* self, /*@unused@*/ PyObject* args, /*@unused@*/ PyObject* kwds) { return get_pvcards("pv", self->x.pv, self->x.npv); } static PyObject* PyWcsprm_has_cdi_ja( PyWcsprm* self) { int result = 0; result = self->x.altlin & has_cd; return PyBool_FromLong(result); } static PyObject* PyWcsprm_has_crotaia( PyWcsprm* self) { int result = 0; result = self->x.altlin & has_crota; return PyBool_FromLong(result); } static PyObject* PyWcsprm_has_pci_ja( PyWcsprm* self) { int result = 0; result = (self->x.altlin == 0 || self->x.altlin & has_pc); return PyBool_FromLong(result); } static PyObject* PyWcsprm_is_unity( PyWcsprm* self) { if (PyWcsprm_cset(self, 1)) { return NULL; } return PyBool_FromLong(self->x.lin.unity); } /*@null@*/ static PyObject* PyWcsprm_mix( PyWcsprm* self, PyObject* args, PyObject* kwds) { int mixpix = 0; int mixcel = 0; double vspan[2] = {0, 0}; double vstep = 0; int viter = 0; Py_ssize_t naxis = 0; PyObject* world_obj = NULL; PyObject* pixcrd_obj = NULL; int origin = 1; PyArrayObject* world = NULL; PyArrayObject* phi = NULL; PyArrayObject* theta = NULL; PyArrayObject* imgcrd = NULL; PyArrayObject* pixcrd = NULL; int status = -1; PyObject* result = NULL; const char* keywords[] = { "mixpix", "mixcel", "vspan", "vstep", "viter", "world", "pixcrd", "origin", NULL }; if (!PyArg_ParseTupleAndKeywords( args, kwds, "ii(dd)diOOi:mix", (char **)keywords, &mixpix, &mixcel, &vspan[0], &vspan[1], &vstep, &viter, &world_obj, &pixcrd_obj, &origin)) { return NULL; } if (viter < 5 || viter > 10) { PyErr_SetString( PyExc_ValueError, "viter must be in the range 5 - 10"); goto exit; } world = (PyArrayObject*)PyArray_ContiguousFromAny (world_obj, NPY_DOUBLE, 1, 1); if (world == NULL) { PyErr_SetString( PyExc_TypeError, "Argument 6 (world) must be a 1-dimensional numpy array"); goto exit; } if ((int)PyArray_DIM(world, 0) != self->x.naxis) { PyErr_Format( PyExc_TypeError, "Argument 6 (world) must be the same length as the number " "of axes (%d)", self->x.naxis); goto exit; } pixcrd = (PyArrayObject*)PyArray_ContiguousFromAny (pixcrd_obj, NPY_DOUBLE, 1, 1); if (pixcrd == NULL) { PyErr_SetString( PyExc_TypeError, "Argument 7 (pixcrd) must be a 1-dimensional numpy array"); goto exit; } if ((int)PyArray_DIM(pixcrd, 0) != self->x.naxis) { PyErr_Format( PyExc_TypeError, "Argument 7 (pixcrd) must be the same length as the " "number of axes (%d)", self->x.naxis); goto exit; } if (mixpix < 1 || mixpix > self->x.naxis) { PyErr_SetString( PyExc_ValueError, "Argument 1 (mixpix) must specify a pixel coordinate " "axis number"); goto exit; } if (mixcel < 1 || mixcel > 2) { PyErr_SetString( PyExc_ValueError, "Argument 2 (mixcel) must specify a celestial coordinate " "axis number (1 for latitude, 2 for longitude)"); goto exit; } /* Now we allocate a bunch of numpy arrays to store the * results in. */ naxis = (Py_ssize_t)self->x.naxis; phi = (PyArrayObject*)PyArray_SimpleNew (1, &naxis, NPY_DOUBLE); if (phi == NULL) { goto exit; } theta = (PyArrayObject*)PyArray_SimpleNew (1, &naxis, NPY_DOUBLE); if (theta == NULL) { goto exit; } imgcrd = (PyArrayObject*)PyArray_SimpleNew (1, &naxis, NPY_DOUBLE); if (imgcrd == NULL) { goto exit; } /* Convert pixel coordinates to 1-based */ Py_BEGIN_ALLOW_THREADS preoffset_array(pixcrd, origin); wcsprm_python2c(&self->x); status = wcsmix( &self->x, mixpix, mixcel, vspan, vstep, viter, (double*)PyArray_DATA(world), (double*)PyArray_DATA(phi), (double*)PyArray_DATA(theta), (double*)PyArray_DATA(imgcrd), (double*)PyArray_DATA(pixcrd)); wcsprm_c2python(&self->x); unoffset_array(pixcrd, origin); unoffset_array(imgcrd, origin); Py_END_ALLOW_THREADS if (status == 0) { result = PyDict_New(); if (result == NULL || PyDict_SetItemString(result, "imgcrd", (PyObject*)imgcrd) || PyDict_SetItemString(result, "phi", (PyObject*)phi) || PyDict_SetItemString(result, "theta", (PyObject*)theta) || PyDict_SetItemString(result, "world", (PyObject*)world)) { goto exit; } } exit: Py_XDECREF(world); Py_XDECREF(phi); Py_XDECREF(theta); Py_XDECREF(imgcrd); Py_XDECREF(pixcrd); if (status == 0) { return result; } else { Py_XDECREF(result); if (status == -1) { /* The error message has already been set */ return NULL; } else { wcs_to_python_exc(&(self->x)); return NULL; } } } /*@null@*/ static PyObject* PyWcsprm_p2s( PyWcsprm* self, PyObject* args, PyObject* kwds) { int naxis = 2; int ncoord = 0; int nelem = 0; PyObject* pixcrd_obj = NULL; int origin = 1; PyArrayObject* pixcrd = NULL; PyArrayObject* imgcrd = NULL; PyArrayObject* phi = NULL; PyArrayObject* theta = NULL; PyArrayObject* world = NULL; PyArrayObject* stat = NULL; PyObject* result = NULL; int status = 0; const char* keywords[] = { "pixcrd", "origin", NULL }; if (!PyArg_ParseTupleAndKeywords( args, kwds, "Oi:p2s", (char **)keywords, &pixcrd_obj, &origin)) { return NULL; } naxis = self->x.naxis; pixcrd = (PyArrayObject*)PyArray_ContiguousFromAny (pixcrd_obj, NPY_DOUBLE, 2, 2); if (pixcrd == NULL) { return NULL; } if (PyArray_DIM(pixcrd, 1) < naxis) { PyErr_Format( PyExc_RuntimeError, "Input array must be 2-dimensional, where the second dimension >= %d", naxis); goto exit; } /* Now we allocate a bunch of numpy arrays to store the results in. */ imgcrd = (PyArrayObject*)PyArray_SimpleNew( 2, PyArray_DIMS(pixcrd), NPY_DOUBLE); if (imgcrd == NULL) { goto exit; } phi = (PyArrayObject*)PyArray_SimpleNew( 1, PyArray_DIMS(pixcrd), NPY_DOUBLE); if (phi == NULL) { goto exit; } theta = (PyArrayObject*)PyArray_SimpleNew( 1, PyArray_DIMS(pixcrd), NPY_DOUBLE); if (theta == NULL) { goto exit; } world = (PyArrayObject*)PyArray_SimpleNew( 2, PyArray_DIMS(pixcrd), NPY_DOUBLE); if (world == NULL) { goto exit; } stat = (PyArrayObject*)PyArray_SimpleNew( 1, PyArray_DIMS(pixcrd), NPY_INT); if (stat == NULL) { goto exit; } /* Make the call */ Py_BEGIN_ALLOW_THREADS ncoord = PyArray_DIM(pixcrd, 0); nelem = PyArray_DIM(pixcrd, 1); preoffset_array(pixcrd, origin); wcsprm_python2c(&self->x); status = wcsp2s( &self->x, ncoord, nelem, (double*)PyArray_DATA(pixcrd), (double*)PyArray_DATA(imgcrd), (double*)PyArray_DATA(phi), (double*)PyArray_DATA(theta), (double*)PyArray_DATA(world), (int*)PyArray_DATA(stat)); wcsprm_c2python(&self->x); unoffset_array(pixcrd, origin); /* unoffset_array(world, origin); */ unoffset_array(imgcrd, origin); if (status == 8) { set_invalid_to_nan( ncoord, nelem, (double*)PyArray_DATA(imgcrd), (int*)PyArray_DATA(stat)); set_invalid_to_nan( ncoord, 1, (double*)PyArray_DATA(phi), (int*)PyArray_DATA(stat)); set_invalid_to_nan( ncoord, 1, (double*)PyArray_DATA(theta), (int*)PyArray_DATA(stat)); set_invalid_to_nan( ncoord, nelem, (double*)PyArray_DATA(world), (int*)PyArray_DATA(stat)); } Py_END_ALLOW_THREADS if (status == 0 || status == 8) { result = PyDict_New(); if (result == NULL || PyDict_SetItemString(result, "imgcrd", (PyObject*)imgcrd) || PyDict_SetItemString(result, "phi", (PyObject*)phi) || PyDict_SetItemString(result, "theta", (PyObject*)theta) || PyDict_SetItemString(result, "world", (PyObject*)world) || PyDict_SetItemString(result, "stat", (PyObject*)stat)) { goto exit; } } exit: Py_XDECREF(pixcrd); Py_XDECREF(imgcrd); Py_XDECREF(phi); Py_XDECREF(theta); Py_XDECREF(world); Py_XDECREF(stat); if (status == 0 || status == 8) { return result; } else { Py_XDECREF(result); if (status == -1) { /* Exception already set */ return NULL; } else { wcs_to_python_exc(&(self->x)); return NULL; } } } /*@null@*/ static PyObject* PyWcsprm_s2p( PyWcsprm* self, PyObject* args, PyObject* kwds) { int naxis = 2; int ncoord = 0; int nelem = 0; PyObject* world_obj = NULL; int origin = 1; PyArrayObject* world = NULL; PyArrayObject* phi = NULL; PyArrayObject* theta = NULL; PyArrayObject* imgcrd = NULL; PyArrayObject* pixcrd = NULL; PyArrayObject* stat = NULL; PyObject* result = NULL; int status = -1; const char* keywords[] = { "world", "origin", NULL }; if (!PyArg_ParseTupleAndKeywords( args, kwds, "Oi:s2p", (char **)keywords, &world_obj, &origin)) { return NULL; } naxis = self->x.naxis; world = (PyArrayObject*)PyArray_ContiguousFromAny( world_obj, NPY_DOUBLE, 2, 2); if (world == NULL) { return NULL; } if (PyArray_DIM(world, 1) < naxis) { PyErr_Format( PyExc_RuntimeError, "Input array must be 2-dimensional, where the second dimension >= %d", naxis); goto exit; } /* Now we allocate a bunch of numpy arrays to store the * results in. */ phi = (PyArrayObject*)PyArray_SimpleNew( 1, PyArray_DIMS(world), NPY_DOUBLE); if (phi == NULL) { goto exit; } theta = (PyArrayObject*)PyArray_SimpleNew( 1, PyArray_DIMS(world), NPY_DOUBLE); if (phi == NULL) { goto exit; } imgcrd = (PyArrayObject*)PyArray_SimpleNew( 2, PyArray_DIMS(world), NPY_DOUBLE); if (theta == NULL) { goto exit; } pixcrd = (PyArrayObject*)PyArray_SimpleNew( 2, PyArray_DIMS(world), NPY_DOUBLE); if (pixcrd == NULL) { goto exit; } stat = (PyArrayObject*)PyArray_SimpleNew( 1, PyArray_DIMS(world), NPY_INT); if (stat == NULL) { goto exit; } /* Make the call */ Py_BEGIN_ALLOW_THREADS ncoord = (int)PyArray_DIM(world, 0); nelem = (int)PyArray_DIM(world, 1); /* preoffset_array(world, origin); */ wcsprm_python2c(&self->x); status = wcss2p( &self->x, ncoord, nelem, (double*)PyArray_DATA(world), (double*)PyArray_DATA(phi), (double*)PyArray_DATA(theta), (double*)PyArray_DATA(imgcrd), (double*)PyArray_DATA(pixcrd), (int*)PyArray_DATA(stat)); wcsprm_c2python(&self->x); /* unoffset_array(world, origin); */ unoffset_array(pixcrd, origin); unoffset_array(imgcrd, origin); if (status == 9) { set_invalid_to_nan( ncoord, 1, (double*)PyArray_DATA(phi), (int*)PyArray_DATA(stat)); set_invalid_to_nan( ncoord, 1, (double*)PyArray_DATA(theta), (int*)PyArray_DATA(stat)); set_invalid_to_nan( ncoord, nelem, (double*)PyArray_DATA(imgcrd), (int*)PyArray_DATA(stat)); set_invalid_to_nan( ncoord, nelem, (double*)PyArray_DATA(pixcrd), (int*)PyArray_DATA(stat)); } Py_END_ALLOW_THREADS if (status == 0 || status == 9) { result = PyDict_New(); if (result == NULL || PyDict_SetItemString(result, "phi", (PyObject*)phi) || PyDict_SetItemString(result, "theta", (PyObject*)theta) || PyDict_SetItemString(result, "imgcrd", (PyObject*)imgcrd) || PyDict_SetItemString(result, "pixcrd", (PyObject*)pixcrd) || PyDict_SetItemString(result, "stat", (PyObject*)stat)) { goto exit; } } exit: Py_XDECREF(pixcrd); Py_XDECREF(imgcrd); Py_XDECREF(phi); Py_XDECREF(theta); Py_XDECREF(world); Py_XDECREF(stat); if (status == 0 || status == 9) { return result; } else { Py_XDECREF(result); if (status == -1) { /* Exception already set */ return NULL; } else { wcs_to_python_exc(&(self->x)); return NULL; } } } static int PyWcsprm_cset( PyWcsprm* self, const int convert) { int status = 0; if (convert) wcsprm_python2c(&self->x); status = wcsset(&self->x); if (convert) wcsprm_c2python(&self->x); if (status == 0) { return 0; } else { wcs_to_python_exc(&(self->x)); return 1; } } /*@null@*/ static PyObject* PyWcsprm_set( PyWcsprm* self) { if (PyWcsprm_cset(self, 1)) { return NULL; } Py_INCREF(Py_None); return Py_None; } /*@null@*/ static PyObject* PyWcsprm_set_ps( PyWcsprm* self, PyObject* arg, /*@unused@*/ PyObject* kwds) { if (is_null(self->x.ps)) { return NULL; } if (set_pscards("ps", arg, &self->x.ps, &self->x.nps, &self->x.npsmax)) { self->x.m_ps = self->x.ps; return NULL; } self->x.m_ps = self->x.ps; note_change(self); Py_INCREF(Py_None); return Py_None; } /*@null@*/ static PyObject* PyWcsprm_set_pv( PyWcsprm* self, PyObject* arg, /*@unused@*/ PyObject* kwds) { if (is_null(self->x.pv)) { return NULL; } else if (set_pvcards("pv", arg, &self->x.pv, &self->x.npv, &self->x.npvmax)) { return NULL; } else { self->x.m_pv = self->x.pv; note_change(self); Py_INCREF(Py_None); return Py_None; } } /* TODO: This is convenient for debugging for now -- but it's not very * Pythonic. It should probably be hooked into __str__ or something. */ /*@null@*/ static PyObject* PyWcsprm_print_contents( PyWcsprm* self) { /* This is not thread-safe, but since we're holding onto the GIL, we can assume we won't have thread conflicts */ wcsprintf_set(NULL); wcsprm_python2c(&self->x); if (PyWcsprm_cset(self, 0)) { wcsprm_c2python(&self->x); return NULL; } wcsprt(&self->x); wcsprm_c2python(&self->x); printf("%s", wcsprintf_buf()); Py_INCREF(Py_None); return Py_None; } /*@null@*/ static PyObject* PyWcsprm_spcfix( PyWcsprm* self) { int status = 0; wcsprm_python2c(&self->x); status = spcfix(&self->x); wcsprm_c2python(&self->x); if (status == -1 || status == 0) { return PyLong_FromLong((long)status); } else { wcserr_fix_to_python_exc(self->x.err); return NULL; } } /*@null@*/ static PyObject* PyWcsprm_sptr( PyWcsprm* self, PyObject* args, PyObject* kwds) { int i = -1; const char* py_ctype = NULL; char ctype[9]; int status = 0; const char* keywords[] = {"ctype", "i", NULL}; if (!PyArg_ParseTupleAndKeywords( args, kwds, "s|i:sptr", (char **)keywords, &py_ctype, &i)) { return NULL; } if (strlen(py_ctype) > 8) { PyErr_SetString( PyExc_ValueError, "ctype string has more than 8 characters."); } strncpy(ctype, py_ctype, 9); wcsprm_python2c(&self->x); status = wcssptr(&self->x, &i, ctype); wcsprm_c2python(&self->x); if (status == 0) { Py_INCREF(Py_None); return Py_None; } else { wcs_to_python_exc(&(self->x)); return NULL; } } /*@null@*/ static PyObject* PyWcsprm___str__( PyWcsprm* self) { /* This is not thread-safe, but since we're holding onto the GIL, we can assume we won't have thread conflicts */ wcsprintf_set(NULL); wcsprm_python2c(&self->x); if (PyWcsprm_cset(self, 0)) { wcsprm_c2python(&self->x); return NULL; } wcsprt(&self->x); wcsprm_c2python(&self->x); return PyUnicode_FromString(wcsprintf_buf()); } PyObject *PyWcsprm_richcompare(PyObject *a, PyObject *b, int op) { int equal; int status; struct wcsprm *ax; struct wcsprm *bx; if ((op == Py_EQ || op == Py_NE) && PyObject_TypeCheck(b, &PyWcsprmType)) { ax = &((PyWcsprm *)a)->x; bx = &((PyWcsprm *)b)->x; wcsprm_python2c(ax); wcsprm_python2c(bx); status = wcscompare( WCSCOMPARE_ANCILLARY, 0.0, ax, bx, &equal); wcsprm_c2python(ax); wcsprm_c2python(bx); if (status == 0) { if (op == Py_NE) { equal = !equal; } if (equal) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } else { wcs_to_python_exc(&(((PyWcsprm *)a)->x)); return NULL; } } Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } /*@null@*/ static PyObject* PyWcsprm_sub( PyWcsprm* self, PyObject* args, PyObject* kwds) { int i = -1; Py_ssize_t tmp = 0; PyObject* py_axes = NULL; PyWcsprm* py_dest_wcs = NULL; PyObject* element = NULL; PyObject* element_utf8 = NULL; char* element_str = NULL; int element_val = 0; int nsub = 0; int* axes = NULL; int status = -1; const char* keywords[] = {"axes", NULL}; if (!PyArg_ParseTupleAndKeywords( args, kwds, "|O:sub", (char **)keywords, &py_axes)) { goto exit; } if (py_axes == NULL || py_axes == Py_None) { /* leave all variables as is */ } else if (PyList_Check(py_axes) || PyTuple_Check(py_axes)) { tmp = PySequence_Size(py_axes); if (tmp == -1) { goto exit; } nsub = (int)tmp; axes = malloc(nsub * sizeof(int) * 2); if (axes == NULL) { PyErr_SetString(PyExc_MemoryError, "Out of memory"); goto exit; } for (i = 0; i < nsub; ++i) { element = PySequence_GetItem(py_axes, i); if (element == NULL) { goto exit; } if (PyUnicode_Check(element) || PyBytes_Check(element)) { if (PyUnicode_Check(element)) { element_utf8 = PyUnicode_AsUTF8String(element); if (element_utf8 == NULL) { goto exit; } element_str = PyBytes_AsString(element_utf8); } else if (PyBytes_Check(element)) { element_str = PyBytes_AsString(element); } if (strncmp(element_str, "longitude", 10) == 0) { element_val = WCSSUB_LONGITUDE; } else if (strncmp(element_str, "latitude", 9) == 0) { element_val = WCSSUB_LATITUDE; } else if (strncmp(element_str, "cubeface", 9) == 0) { element_val = WCSSUB_CUBEFACE; } else if (strncmp(element_str, "spectral", 9) == 0) { element_val = WCSSUB_SPECTRAL; } else if (strncmp(element_str, "stokes", 7) == 0) { element_val = WCSSUB_STOKES; } else if (strncmp(element_str, "celestial", 10) == 0) { element_val = WCSSUB_CELESTIAL; } else { PyErr_SetString( PyExc_ValueError, "string values for axis sequence must be one of 'latitude', 'longitude', 'cubeface', 'spectral', 'stokes', or 'celestial'"); goto exit; } Py_CLEAR(element_utf8); } else if (PyLong_Check(element)) { tmp = (Py_ssize_t)PyLong_AsSsize_t(element); if (tmp == -1 && PyErr_Occurred()) { goto exit; } element_val = (int)tmp; } else { PyErr_SetString( PyExc_TypeError, "axes sequence must contain either strings or ints"); goto exit; } axes[i] = element_val; Py_CLEAR(element); } } else if (PyLong_Check(py_axes)) { tmp = (Py_ssize_t)PyLong_AsSsize_t(py_axes); if (tmp == -1 && PyErr_Occurred()) { goto exit; } nsub = (int)tmp; if (nsub < 0 || nsub > self->x.naxis) { PyErr_Format( PyExc_ValueError, "If axes is an int, it must be in the range 0-self.naxis (%d)", self->x.naxis); goto exit; } } else { PyErr_SetString( PyExc_TypeError, "axes must None, a sequence or an integer"); goto exit; } py_dest_wcs = (PyWcsprm*)PyWcsprm_cnew(); py_dest_wcs->x.flag = -1; status = wcsini(0, nsub, &py_dest_wcs->x); if (status != 0) { goto exit; } wcsprm_python2c(&self->x); status = wcssub(1, &self->x, &nsub, axes, &py_dest_wcs->x); wcsprm_c2python(&self->x); if (PyWcsprm_cset(py_dest_wcs, 0)) { status = -1; goto exit; } wcsprm_c2python(&py_dest_wcs->x); if (status != 0) { goto exit; } exit: free(axes); Py_XDECREF(element); Py_XDECREF(element_utf8); if (status == 0) { return (PyObject*)py_dest_wcs; } else if (status == -1) { Py_XDECREF(py_dest_wcs); /* Exception already set */ return NULL; } else { wcs_to_python_exc(&(py_dest_wcs->x)); Py_XDECREF(py_dest_wcs); return NULL; } } /*@null@*/ static PyObject* PyWcsprm_to_header( PyWcsprm* self, PyObject* args, PyObject* kwds) { PyObject* relax_obj = NULL; int relax = 0; int nkeyrec = 0; char* header = NULL; int status = -1; PyObject* result = NULL; const char* keywords[] = {"relax", NULL}; if (!PyArg_ParseTupleAndKeywords( args, kwds, "|O:to_header", (char **)keywords, &relax_obj)) { goto exit; } if (relax_obj == Py_True) { relax = WCSHDO_all; } else if (relax_obj == NULL || relax_obj == Py_False) { relax = WCSHDO_safe; } else { relax = (int)PyLong_AsLong(relax_obj); if (relax == -1) { PyErr_SetString( PyExc_ValueError, "relax must be True, False or an integer."); return NULL; } } wcsprm_python2c(&self->x); status = wcshdo(relax, &self->x, &nkeyrec, &header); wcsprm_c2python(&self->x); if (status != 0) { wcs_to_python_exc(&(self->x)); goto exit; } /* Just return the raw header string. astropy.io.fits on the Python side will help to parse and use this information. */ result = PyUnicode_FromStringAndSize(header, (Py_ssize_t)nkeyrec * 80); exit: free(header); return result; } /*@null@*/ static PyObject* PyWcsprm_unitfix( PyWcsprm* self, PyObject* args, PyObject* kwds) { const char* translate_units = NULL; int ctrl = 0; int status = 0; const char* keywords[] = {"translate_units", NULL}; if (!PyArg_ParseTupleAndKeywords( args, kwds, "|s:unitfix", (char **)keywords, &translate_units)) { return NULL; } if (translate_units != NULL) { if (parse_unsafe_unit_conversion_spec(translate_units, &ctrl)) { return NULL; } } status = unitfix(ctrl, &self->x); if (status == -1 || status == 0) { return PyLong_FromLong((long)status); } else { wcserr_fix_to_python_exc(self->x.err); return NULL; } } /*************************************************************************** * Member getters/setters (properties) */ /*@null@*/ static PyObject* PyWcsprm_get_alt( PyWcsprm* self, /*@unused@*/ void* closure) { if (is_null(self->x.alt)) { return NULL; } /* Force a null-termination of this single-character string */ self->x.alt[1] = '\0'; return get_string("alt", self->x.alt); } static int PyWcsprm_set_alt( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { char value_string[2]; if (is_null(self->x.alt)) { return -1; } if (value == NULL) { /* deletion */ self->x.alt[0] = ' '; self->x.alt[1] = '\0'; note_change(self); return 0; } if (set_string("alt", value, value_string, 2)) { return -1; } if (!is_valid_alt_key(value_string)) { return -1; } strncpy(self->x.alt, value_string, 2); return 0; } /*@null@*/ static PyObject* PyWcsprm_get_axis_types( PyWcsprm* self, /*@unused@*/ void* closure) { Py_ssize_t naxis = 0; if (is_null(self->x.types)) { return NULL; } if (PyWcsprm_cset(self, 1)) { return NULL; } naxis = (Py_ssize_t)self->x.naxis; return get_int_array("axis_types", self->x.types, 1, &naxis, (PyObject*)self); } static PyObject* PyWcsprm_get_bepoch( PyWcsprm* self, /*@unused@*/ void* closure) { return get_double("bepoch", self->x.bepoch); } static int PyWcsprm_set_bepoch( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (value == NULL) { self->x.bepoch = (double)NPY_NAN; return 0; } return set_double("bepoch", value, &self->x.bepoch); } /*@null@*/ static PyObject* PyWcsprm_get_cd( PyWcsprm* self, /*@unused@*/ void* closure) { npy_intp dims[2]; if (is_null(self->x.cd)) { return NULL; } if ((self->x.altlin & has_cd) == 0) { PyErr_SetString(PyExc_AttributeError, "No cd is present."); return NULL; } dims[0] = self->x.naxis; dims[1] = self->x.naxis; return get_double_array("cd", self->x.cd, 2, dims, (PyObject*)self); } static int PyWcsprm_set_cd( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { npy_intp dims[2]; if (is_null(self->x.cd)) { return -1; } if (value == NULL) { self->x.altlin &= ~has_cd; note_change(self); return 0; } dims[0] = self->x.naxis; dims[1] = self->x.naxis; if (set_double_array("cd", value, 2, dims, self->x.cd)) { return -1; } self->x.altlin |= has_cd; note_change(self); return 0; } /*@null@*/ static PyObject* PyWcsprm_get_cdelt( PyWcsprm* self, /*@unused@*/ void* closure) { Py_ssize_t naxis = 0; if (is_null(self->x.cdelt)) { return NULL; } naxis = self->x.naxis; if (self->x.altlin & has_cd) { PyErr_WarnEx(NULL, "cdelt will be ignored since cd is present", 1); } return get_double_array("cdelt", self->x.cdelt, 1, &naxis, (PyObject*)self); } /*@null@*/ static int PyWcsprm_set_cdelt( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { npy_intp dims; if (is_null(self->x.cdelt)) { return -1; } dims = (npy_int)self->x.naxis; if (self->x.altlin & has_cd) { PyErr_WarnEx(NULL, "cdelt will be ignored since cd is present", 1); } note_change(self); return set_double_array("cdelt", value, 1, &dims, self->x.cdelt); } static PyObject* PyWcsprm_get_cel_offset( PyWcsprm* self, /*@unused@*/ void* closure) { return get_bool("cel_offset", self->x.cel.offset); } static int PyWcsprm_set_cel_offset( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { note_change(self); return set_bool("cel_offset", value, &self->x.cel.offset); } /*@null@*/ static PyObject* PyWcsprm_get_cname( PyWcsprm* self, /*@unused@*/ void* closure) { if (is_null(self->x.cname)) { return NULL; } return get_str_list("cname", self->x.cname, (Py_ssize_t)self->x.naxis, 68, (PyObject*)self); } /*@null@*/ static int PyWcsprm_set_cname( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (is_null(self->x.cname)) { return -1; } return set_str_list("cname", value, (Py_ssize_t)self->x.naxis, 0, self->x.cname); } /*@null@*/ static PyObject* PyWcsprm_get_colax( PyWcsprm* self, /*@unused@*/ void* closure) { Py_ssize_t naxis = 0; if (is_null(self->x.colax)) { return NULL; } naxis = (Py_ssize_t)self->x.naxis; return get_int_array("colax", self->x.colax, 1, &naxis, (PyObject*)self); } static int PyWcsprm_set_colax( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { npy_intp naxis = 0; if (is_null(self->x.colax)) { return -1; } naxis = (Py_ssize_t)self->x.naxis; return set_int_array("colax", value, 1, &naxis, self->x.colax); } static PyObject* PyWcsprm_get_colnum( PyWcsprm* self, /*@unused@*/ void* closure) { return get_int("colnum", self->x.colnum); } static int PyWcsprm_set_colnum( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { return set_int("colnum", value, &self->x.colnum); } /*@null@*/ static PyObject* PyWcsprm_get_crder( PyWcsprm* self, /*@unused@*/ void* closure) { Py_ssize_t naxis = 0; if (is_null(self->x.crder)) { return NULL; } naxis = (Py_ssize_t)self->x.naxis; return get_double_array("crder", self->x.crder, 1, &naxis, (PyObject*)self); } static int PyWcsprm_set_crder( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { npy_intp naxis = 0; if (is_null(self->x.crder)) { return -1; } naxis = (Py_ssize_t)self->x.naxis; return set_double_array("crder", value, 1, &naxis, self->x.crder); } /*@null@*/ static PyObject* PyWcsprm_get_crota( PyWcsprm* self, /*@unused@*/ void* closure) { Py_ssize_t naxis = 0; if (is_null(self->x.crota)) { return NULL; } if ((self->x.altlin & has_crota) == 0) { PyErr_SetString(PyExc_AttributeError, "No crota is present."); return NULL; } naxis = (Py_ssize_t)self->x.naxis; return get_double_array("crota", self->x.crota, 1, &naxis, (PyObject*)self); } static int PyWcsprm_set_crota( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { npy_intp naxis = 0; if (is_null(self->x.crota)) { return -1; } if (value == NULL) { /* Deletion */ self->x.altlin &= ~has_crota; note_change(self); return 0; } naxis = (Py_ssize_t)self->x.naxis; if (set_double_array("crota", value, 1, &naxis, self->x.crota)) { return -1; } self->x.altlin |= has_crota; note_change(self); return 0; } /*@null@*/ static PyObject* PyWcsprm_get_crpix( PyWcsprm* self, /*@unused@*/ void* closure) { Py_ssize_t naxis = 0; if (is_null(self->x.crpix)) { return NULL; } naxis = (Py_ssize_t)self->x.naxis; return get_double_array("crpix", self->x.crpix, 1, &naxis, (PyObject*)self); } static int PyWcsprm_set_crpix( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { npy_intp naxis = 0; if (is_null(self->x.crpix)) { return -1; } naxis = (Py_ssize_t)self->x.naxis; note_change(self); return set_double_array("crpix", value, 1, &naxis, self->x.crpix); } /*@null@*/ static PyObject* PyWcsprm_get_crval( PyWcsprm* self, /*@unused@*/ void* closure) { Py_ssize_t naxis = 0; if (is_null(self->x.crval)) { return NULL; } naxis = (Py_ssize_t)self->x.naxis; return get_double_array("crval", self->x.crval, 1, &naxis, (PyObject*)self); } static int PyWcsprm_set_crval( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { npy_intp naxis; if (is_null(self->x.crval)) { return -1; } naxis = (Py_ssize_t)self->x.naxis; note_change(self); return set_double_array("crval", value, 1, &naxis, self->x.crval); } /*@null@*/ static PyObject* PyWcsprm_get_csyer( PyWcsprm* self, /*@unused@*/ void* closure) { Py_ssize_t naxis; if (is_null(self->x.csyer)) { return NULL; } naxis = (Py_ssize_t)self->x.naxis; return get_double_array("csyer", self->x.csyer, 1, &naxis, (PyObject*)self); } static int PyWcsprm_set_csyer( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { npy_intp naxis; if (is_null(self->x.csyer)) { return -1; } naxis = (Py_ssize_t)self->x.naxis; return set_double_array("csyer", value, 1, &naxis, self->x.csyer); } /*@null@*/ static PyObject* PyWcsprm_get_ctype( PyWcsprm* self, /*@unused@*/ void* closure) { if (is_null(self->x.ctype)) { return NULL; } return get_str_list("ctype", self->x.ctype, self->x.naxis, 68, (PyObject*)self); } static int PyWcsprm_set_ctype( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (is_null(self->x.ctype)) { return -1; } note_change(self); return set_str_list("ctype", value, (Py_ssize_t)self->x.naxis, 0, self->x.ctype); } static PyObject* PyWcsprm_get_cubeface( PyWcsprm* self, /*@unused@*/ void* closure) { return get_int("cubeface", self->x.cubeface); } static int PyWcsprm_set_cubeface( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { note_change(self); return set_int("cubeface", value, &self->x.cubeface); } /*@null@*/ static PyObject* PyWcsprm_get_cunit( PyWcsprm* self, /*@unused@*/ void* closure) { if (is_null(self->x.cunit)) { return NULL; } return get_unit_list( "cunit", self->x.cunit, (Py_ssize_t)self->x.naxis, (PyObject*)self); } static int PyWcsprm_set_cunit( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (is_null(self->x.cunit)) { return -1; } note_change(self); return set_unit_list( (PyObject *)self, "cunit", value, (Py_ssize_t)self->x.naxis, self->x.cunit); } /*@null@*/ static PyObject* PyWcsprm_get_czphs( PyWcsprm* self, /*@unused@*/ void* closure) { Py_ssize_t naxis; if (is_null(self->x.czphs)) { return NULL; } naxis = (Py_ssize_t)self->x.naxis; return get_double_array("czphs", self->x.czphs, 1, &naxis, (PyObject*)self); } static int PyWcsprm_set_czphs( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { npy_intp naxis; if (is_null(self->x.czphs)) { return -1; } naxis = (Py_ssize_t)self->x.naxis; return set_double_array("czphs", value, 1, &naxis, self->x.czphs); } /*@null@*/ static PyObject* PyWcsprm_get_cperi( PyWcsprm* self, /*@unused@*/ void* closure) { Py_ssize_t naxis; if (is_null(self->x.cperi)) { return NULL; } naxis = (Py_ssize_t)self->x.naxis; return get_double_array("cperi", self->x.cperi, 1, &naxis, (PyObject*)self); } static int PyWcsprm_set_cperi( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { npy_intp naxis; if (is_null(self->x.cperi)) { return -1; } naxis = (Py_ssize_t)self->x.naxis; return set_double_array("cperi", value, 1, &naxis, self->x.cperi); } /*@null@*/ static PyObject* PyWcsprm_get_dateavg( PyWcsprm* self, /*@unused@*/ void* closure) { if (is_null(self->x.dateavg)) { return NULL; } return get_string("dateavg", self->x.dateavg); } static int PyWcsprm_set_dateavg( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (is_null(self->x.dateavg)) { return -1; } /* TODO: Verify that this looks like a date string */ return set_string("dateavg", value, self->x.dateavg, 72); } /*@null@*/ static PyObject* PyWcsprm_get_datebeg( PyWcsprm* self, /*@unused@*/ void* closure) { if (is_null(self->x.datebeg)) { return NULL; } return get_string("datebeg", self->x.datebeg); } static int PyWcsprm_set_datebeg( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (is_null(self->x.datebeg)) { return -1; } return set_string("datebeg", value, self->x.datebeg, 72); } /*@null@*/ static PyObject* PyWcsprm_get_dateend( PyWcsprm* self, /*@unused@*/ void* closure) { if (is_null(self->x.dateend)) { return NULL; } return get_string("dateend", self->x.dateend); } static int PyWcsprm_set_dateend( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (is_null(self->x.dateend)) { return -1; } return set_string("dateend", value, self->x.dateend, 72); } /*@null@*/ static PyObject* PyWcsprm_get_dateobs( PyWcsprm* self, /*@unused@*/ void* closure) { if (is_null(self->x.dateobs)) { return NULL; } return get_string("dateobs", self->x.dateobs); } static int PyWcsprm_set_dateobs( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (is_null(self->x.dateobs)) { return -1; } return set_string("dateobs", value, self->x.dateobs, 72); } /*@null@*/ static PyObject* PyWcsprm_get_dateref( PyWcsprm* self, /*@unused@*/ void* closure) { if (is_null(self->x.dateref)) { return NULL; } return get_string("dateref", self->x.dateref); } static int PyWcsprm_set_dateref( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (is_null(self->x.dateref)) { return -1; } return set_string("dateref", value, self->x.dateref, 72); } static PyObject* PyWcsprm_get_equinox( PyWcsprm* self, /*@unused@*/ void* closure) { return get_double("equinox", self->x.equinox); } static int PyWcsprm_set_equinox( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (value == NULL) { /* deletion */ self->x.equinox = (double)NPY_NAN; return 0; } return set_double("equinox", value, &self->x.equinox); } /*@null@*/ static PyObject* PyWcsprm_get_imgpix_matrix( PyWcsprm* self, /*@unused@*/ void* closure) { npy_intp dims[2]; if (is_null(self->x.lin.imgpix)) { return NULL; } if (PyWcsprm_cset(self, 1)) { return NULL; } dims[0] = self->x.naxis; dims[1] = self->x.naxis; return get_double_array("imgpix_matrix", self->x.lin.imgpix, 2, dims, (PyObject*)self); } static PyObject* PyWcsprm_get_jepoch( PyWcsprm* self, /*@unused@*/ void* closure) { return get_double("jepoch", self->x.jepoch); } static int PyWcsprm_set_jepoch( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { note_change(self); if (value == NULL) { self->x.jepoch = (double)NPY_NAN; return 0; } return set_double("jepoch", value, &self->x.jepoch); } static PyObject* PyWcsprm_get_lat( PyWcsprm* self, /*@unused@*/ void* closure) { if (PyWcsprm_cset(self, 1)) { return NULL; } return get_int("lat", self->x.lat); } static PyObject* PyWcsprm_get_latpole( PyWcsprm* self, /*@unused@*/ void* closure) { return get_double("latpole", self->x.latpole); } static int PyWcsprm_set_latpole( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { note_change(self); if (value == NULL) { self->x.latpole = 90.0; return 0; } return set_double("latpole", value, &self->x.latpole); } /*@null@*/ static PyObject* PyWcsprm_get_lattyp( PyWcsprm* self, /*@unused@*/ void* closure) { if (is_null(self->x.lattyp)) { return NULL; } if (PyWcsprm_cset(self, 1)) { return NULL; } return get_string("lattyp", self->x.lattyp); } static PyObject* PyWcsprm_get_lng( PyWcsprm* self, /*@unused@*/ void* closure) { if (PyWcsprm_cset(self, 1)) { return NULL; } return get_int("lng", self->x.lng); } /*@null@*/ static PyObject* PyWcsprm_get_lngtyp( PyWcsprm* self, /*@unused@*/ void* closure) { if (is_null(self->x.lngtyp)) { return NULL; } if (PyWcsprm_cset(self, 1)) { return NULL; } return get_string("lngtyp", self->x.lngtyp); } static PyObject* PyWcsprm_get_lonpole( PyWcsprm* self, /*@unused@*/ void* closure) { return get_double("lonpole", self->x.lonpole); } static int PyWcsprm_set_lonpole( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { note_change(self); if (value == NULL) { self->x.lonpole = (double)NPY_NAN; return 0; } return set_double("lonpole", value, &self->x.lonpole); } static PyObject* PyWcsprm_get_mjdavg( PyWcsprm* self, /*@unused@*/ void* closure) { return get_double("mjdavg", self->x.mjdavg); } static int PyWcsprm_set_mjdavg( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (value == NULL) { self->x.mjdavg = (double)NPY_NAN; return 0; } return set_double("mjdavg", value, &self->x.mjdavg); } static PyObject* PyWcsprm_get_mjdbeg( PyWcsprm* self, /*@unused@*/ void* closure) { return get_double("mjdbeg", self->x.mjdbeg); } static int PyWcsprm_set_mjdbeg( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (value == NULL) { self->x.mjdbeg = (double)NPY_NAN; return 0; } return set_double("mjdbeg", value, &self->x.mjdbeg); } static PyObject* PyWcsprm_get_mjdend( PyWcsprm* self, /*@unused@*/ void* closure) { return get_double("mjdend", self->x.mjdend); } static int PyWcsprm_set_mjdend( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (value == NULL) { self->x.mjdend = (double)NPY_NAN; return 0; } return set_double("mjdend", value, &self->x.mjdend); } static PyObject* PyWcsprm_get_mjdobs( PyWcsprm* self, /*@unused@*/ void* closure) { return get_double("mjdobs", self->x.mjdobs); } static int PyWcsprm_set_mjdobs( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { note_change(self); if (value == NULL) { self->x.mjdobs = (double)NPY_NAN; return 0; } return set_double("mjdobs", value, &self->x.mjdobs); } static PyObject* PyWcsprm_get_mjdref( PyWcsprm* self, /*@unused@*/ void* closure) { npy_intp size = 2; return get_double_array("mjdref", self->x.mjdref, 1, &size, (PyObject*)self); } static int PyWcsprm_set_mjdref( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { npy_intp size = 2; if (value == NULL) { self->x.mjdref[0] = NPY_NAN; self->x.mjdref[1] = NPY_NAN; return 0; } return set_double_array("mjdref", value, 1, &size, self->x.mjdref); } /*@null@*/ static PyObject* PyWcsprm_get_timesys( PyWcsprm* self, /*@unused@*/ void* closure) { if (is_null(self->x.timesys)) { return NULL; } return get_string("timesys", self->x.timesys); } static int PyWcsprm_set_timesys( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (is_null(self->x.timesys)) { return -1; } return set_string("timesys", value, self->x.timesys, 72); } /*@null@*/ static PyObject* PyWcsprm_get_trefpos( PyWcsprm* self, /*@unused@*/ void* closure) { if (is_null(self->x.trefpos)) { return NULL; } return get_string("trefpos", self->x.trefpos); } static int PyWcsprm_set_trefpos( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (is_null(self->x.trefpos)) { return -1; } return set_string("trefpos", value, self->x.trefpos, 72); } /*@null@*/ static PyObject* PyWcsprm_get_trefdir( PyWcsprm* self, /*@unused@*/ void* closure) { if (is_null(self->x.trefdir)) { return NULL; } return get_string("trefdir", self->x.trefdir); } static int PyWcsprm_set_trefdir( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (is_null(self->x.trefdir)) { return -1; } return set_string("trefdir", value, self->x.trefdir, 72); } /*@null@*/ static PyObject* PyWcsprm_get_timeunit( PyWcsprm* self, /*@unused@*/ void* closure) { if (is_null(self->x.timeunit)) { return NULL; } return get_string("timeunit", self->x.timeunit); } static int PyWcsprm_set_timeunit( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (is_null(self->x.timeunit)) { return -1; } return set_string("timeunit", value, self->x.timeunit, 72); } /*@null@*/ static PyObject* PyWcsprm_get_plephem( PyWcsprm* self, /*@unused@*/ void* closure) { if (is_null(self->x.plephem)) { return NULL; } return get_string("plephem", self->x.plephem); } static int PyWcsprm_set_plephem( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (is_null(self->x.plephem)) { return -1; } return set_string("plephem", value, self->x.plephem, 72); } static PyObject* PyWcsprm_get_tstart( PyWcsprm* self, /*@unused@*/ void* closure) { return get_double("tstart", self->x.tstart); } static int PyWcsprm_set_tstart( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (value == NULL) { self->x.tstart = (double)NPY_NAN; return 0; } return set_double("tstart", value, &self->x.tstart); } static PyObject* PyWcsprm_get_tstop( PyWcsprm* self, /*@unused@*/ void* closure) { return get_double("tstop", self->x.tstop); } static int PyWcsprm_set_tstop( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (value == NULL) { self->x.tstop = (double)NPY_NAN; return 0; } return set_double("tstop", value, &self->x.tstop); } static PyObject* PyWcsprm_get_telapse( PyWcsprm* self, /*@unused@*/ void* closure) { return get_double("telapse", self->x.telapse); } static int PyWcsprm_set_telapse( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (value == NULL) { self->x.telapse = (double)NPY_NAN; return 0; } return set_double("telapse", value, &self->x.telapse); } static PyObject* PyWcsprm_get_timeoffs( PyWcsprm* self, /*@unused@*/ void* closure) { return get_double("timeoffs", self->x.timeoffs); } static int PyWcsprm_set_timeoffs( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (value == NULL) { self->x.timeoffs = (double)NPY_NAN; return 0; } return set_double("timeoffs", value, &self->x.timeoffs); } static PyObject* PyWcsprm_get_timsyer( PyWcsprm* self, /*@unused@*/ void* closure) { return get_double("timsyer", self->x.timsyer); } static int PyWcsprm_set_timsyer( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (value == NULL) { self->x.timsyer = (double)NPY_NAN; return 0; } return set_double("timsyer", value, &self->x.timsyer); } static PyObject* PyWcsprm_get_timrder( PyWcsprm* self, /*@unused@*/ void* closure) { return get_double("timrder", self->x.timrder); } static int PyWcsprm_set_timrder( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (value == NULL) { self->x.timrder = (double)NPY_NAN; return 0; } return set_double("timrder", value, &self->x.timrder); } static PyObject* PyWcsprm_get_timedel( PyWcsprm* self, /*@unused@*/ void* closure) { return get_double("timedel", self->x.timedel); } static int PyWcsprm_set_timedel( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (value == NULL) { self->x.timedel = (double)NPY_NAN; return 0; } return set_double("timedel", value, &self->x.timedel); } static PyObject* PyWcsprm_get_timepixr( PyWcsprm* self, /*@unused@*/ void* closure) { return get_double("timepixr", self->x.timepixr); } static int PyWcsprm_set_timepixr( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (value == NULL) { self->x.timepixr = (double)NPY_NAN; return 0; } return set_double("timepixr", value, &self->x.timepixr); } /*@null@*/ static PyObject* PyWcsprm_get_obsorbit( PyWcsprm* self, /*@unused@*/ void* closure) { if (is_null(self->x.obsorbit)) { return NULL; } return get_string("obsorbit", self->x.obsorbit); } static int PyWcsprm_set_obsorbit( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (is_null(self->x.obsorbit)) { return -1; } return set_string("obsorbit", value, self->x.obsorbit, 72); } static PyObject* PyWcsprm_get_xposure( PyWcsprm* self, /*@unused@*/ void* closure) { return get_double("xposure", self->x.xposure); } static int PyWcsprm_set_xposure( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (value == NULL) { self->x.xposure = (double)NPY_NAN; return 0; } return set_double("xposure", value, &self->x.xposure); } /*@null@*/ static PyObject* PyWcsprm_get_name( PyWcsprm* self, /*@unused@*/ void* closure) { if (is_null(self->x.wcsname)) { return NULL; } return get_string("name", self->x.wcsname); } static int PyWcsprm_set_name( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (is_null(self->x.wcsname)) { return -1; } return set_string("name", value, self->x.wcsname, 72); } static PyObject* PyWcsprm_get_naxis( PyWcsprm* self, /*@unused@*/ void* closure) { return get_int("naxis", self->x.naxis); } /*@null@*/ static PyObject* PyWcsprm_get_obsgeo( PyWcsprm* self, /*@unused@*/ void* closure) { Py_ssize_t size = 6; if (is_null(self->x.obsgeo)) { return NULL; } return get_double_array("obsgeo", self->x.obsgeo, 1, &size, (PyObject*)self); } static int PyWcsprm_set_obsgeo( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { npy_intp size = 6; if (is_null(self->x.obsgeo)) { return -1; } if (value == NULL) { self->x.obsgeo[0] = NPY_NAN; self->x.obsgeo[1] = NPY_NAN; self->x.obsgeo[2] = NPY_NAN; self->x.obsgeo[3] = NPY_NAN; self->x.obsgeo[4] = NPY_NAN; self->x.obsgeo[5] = NPY_NAN; return 0; } return set_double_array("obsgeo", value, 1, &size, self->x.obsgeo); } /*@null@*/ static PyObject* PyWcsprm_get_pc( PyWcsprm* self, /*@unused@*/ void* closure) { npy_intp dims[2]; if (is_null(self->x.pc)) { return NULL; } if (self->x.altlin != 0 && (self->x.altlin & has_pc) == 0) { PyErr_SetString(PyExc_AttributeError, "No pc is present."); return NULL; } dims[0] = self->x.naxis; dims[1] = self->x.naxis; return get_double_array("pc", self->x.pc, 2, dims, (PyObject*)self); } static int PyWcsprm_set_pc( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { npy_intp dims[2]; int i, j, naxis; double* pc; if (is_null(self->x.pc)) { return -1; } note_change(self); if (value == NULL) { /* deletion */ self->x.altlin &= ~has_pc; /* If this results in deleting all flags, pc is still the default, so we should set the pc matrix itself to default values. */ naxis = self->x.naxis; pc = self->x.pc; for (i = 0; i < naxis; i++) { for (j = 0; j < naxis; j++) { if (j == i) { *pc = 1.0; } else { *pc = 0.0; } pc++; } } note_change(self); return 0; } dims[0] = self->x.naxis; dims[1] = self->x.naxis; if (set_double_array("pc", value, 2, dims, self->x.pc)) { return -1; } self->x.altlin |= has_pc; note_change(self); return 0; } static PyObject* PyWcsprm_get_phi0( PyWcsprm* self, /*@unused@*/ void* closure) { return get_double("phi0", self->x.cel.phi0); } static int PyWcsprm_set_phi0( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { note_change(self); if (value == NULL) { self->x.cel.phi0 = (double)NPY_NAN; return 0; } return set_double("phi0", value, &(self->x.cel.phi0)); } static PyObject* PyWcsprm_get_piximg_matrix( PyWcsprm* self, /*@unused@*/ void* closure) { npy_intp dims[2]; if (is_null(self->x.lin.piximg)) { return NULL; } if (PyWcsprm_cset(self, 1)) { return NULL; } dims[0] = self->x.naxis; dims[1] = self->x.naxis; return get_double_array("piximg_matrix", self->x.lin.piximg, 2, dims, (PyObject*)self); } static PyObject* PyWcsprm_get_radesys( PyWcsprm* self, /*@unused@*/ void* closure) { if (is_null(self->x.radesys)) { return NULL; } return get_string("radesys", self->x.radesys); } static int PyWcsprm_set_radesys( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (is_null(self->x.radesys)) { return -1; } return set_string("radesys", value, self->x.radesys, 72); } static PyObject* PyWcsprm_get_restfrq( PyWcsprm* self, /*@unused@*/ void* closure) { return get_double("restfrq", self->x.restfrq); } static int PyWcsprm_set_restfrq( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (value == NULL) { /* deletion */ self->x.restfrq = (double)NPY_NAN; return 0; } note_change(self); return set_double("restfrq", value, &self->x.restfrq); } static PyObject* PyWcsprm_get_restwav( PyWcsprm* self, /*@unused@*/ void* closure) { return get_double("restwav", self->x.restwav); } static int PyWcsprm_set_restwav( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (value == NULL) { /* deletion */ self->x.restwav = (double)NPY_NAN; return 0; } note_change(self); return set_double("restwav", value, &self->x.restwav); } static PyObject* PyWcsprm_get_spec( PyWcsprm* self, /*@unused@*/ void* closure) { return get_int("spec", self->x.spec); } /*@null@*/ static PyObject* PyWcsprm_get_specsys( PyWcsprm* self, /*@unused@*/ void* closure) { if (is_null(self->x.specsys)) { return NULL; } return get_string("specsys", self->x.specsys); } static int PyWcsprm_set_specsys( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (is_null(self->x.specsys)) { return -1; } return set_string("specsys", value, self->x.specsys, 72); } /*@null@*/ static PyObject* PyWcsprm_get_ssysobs( PyWcsprm* self, /*@unused@*/ void* closure) { if (is_null(self->x.ssysobs)) { return NULL; } return get_string("ssysobs", self->x.ssysobs); } static int PyWcsprm_set_ssysobs( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (is_null(self->x.ssysobs)) { return -1; } note_change(self); return set_string("ssysobs", value, self->x.ssysobs, 72); } /*@null@*/ static PyObject* PyWcsprm_get_ssyssrc( PyWcsprm* self, /*@unused@*/ void* closure) { if (is_null(self->x.ssyssrc)) { return NULL; } return get_string("ssyssrc", self->x.ssyssrc); } static int PyWcsprm_set_ssyssrc( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (is_null(self->x.ssyssrc)) { return -1; } return set_string("ssyssrc", value, self->x.ssyssrc, 72); } static PyObject* PyWcsprm_get_tab( PyWcsprm* self, /*@unused@*/ void* closure) { PyObject* result; PyObject* subresult; int i, ntab; ntab = self->x.ntab; result = PyList_New(ntab); if (result == NULL) { return NULL; } for (i = 0; i < ntab; ++i) { subresult = (PyObject *)PyTabprm_cnew((PyObject *)self, &(self->x.tab[i])); if (subresult == NULL) { Py_DECREF(result); return NULL; } if (PyList_SetItem(result, i, subresult) == -1) { Py_DECREF(subresult); Py_DECREF(result); return NULL; } } return result; } static PyObject* PyWcsprm_get_theta0( PyWcsprm* self, /*@unused@*/ void* closure) { return get_double("theta0", self->x.cel.theta0); } static int PyWcsprm_set_theta0( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { note_change(self); if (value == NULL) { self->x.cel.theta0 = (double)NPY_NAN; return 0; } return set_double("theta0", value, &self->x.cel.theta0); } static PyObject* PyWcsprm_get_velangl( PyWcsprm* self, /*@unused@*/ void* closure) { return get_double("velangl", self->x.velangl); } static int PyWcsprm_set_velangl( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (value == NULL) { /* deletion */ self->x.velangl = (double)NPY_NAN; return 0; } return set_double("velangl", value, &self->x.velangl); } static PyObject* PyWcsprm_get_velosys( PyWcsprm* self, /*@unused@*/ void* closure) { return get_double("velosys", self->x.velosys); } static int PyWcsprm_set_velosys( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (value == NULL) { /* deletion */ self->x.velosys = (double)NPY_NAN; return 0; } return set_double("velosys", value, &self->x.velosys); } static PyObject* PyWcsprm_get_velref( PyWcsprm* self, /*@unused@*/ void* closure) { return get_int("velref", self->x.velref); } static int PyWcsprm_set_velref( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (value == NULL) { /* deletion */ self->x.velref = 0; return 0; } return set_int("velref", value, &self->x.velref); } static PyObject* PyWcsprm_get_wtb(PyWcsprm* self, void* closure) { PyObject* list; PyObject* elem; int i, nwtb; nwtb = self->x.nwtb; list = PyList_New(nwtb); if (list == NULL) return NULL; for (i = 0; i < nwtb; ++i) { elem = (PyObject *)PyWtbarr_cnew((PyObject *)self, &(self->x.wtb[i])); if (elem == NULL) { Py_DECREF(list); return NULL; } PyList_SET_ITEM(list, i, elem); } return list; } static PyObject* PyWcsprm_get_zsource( PyWcsprm* self, /*@unused@*/ void* closure) { return get_double("zsource", self->x.zsource); } static int PyWcsprm_set_zsource( PyWcsprm* self, PyObject* value, /*@unused@*/ void* closure) { if (value == NULL) { /* deletion */ self->x.zsource = (double)NPY_NAN; return 0; } return set_double("zsource", value, &self->x.zsource); } static PyObject* PyWcsprm_get_aux( PyWcsprm* self, /*@unused@*/ void* closure) { PyObject* result; // If wcsprm.aux is not initialized, we should do so here so that users can // set auxiliary parameters on an empty WCS. if (self->x.aux == 0x0) { wcsauxi(1, &self->x); } result = (PyObject *)PyAuxprm_cnew((PyObject *)self, self->x.aux); return result; } /*************************************************************************** * PyWcsprm definition structures */ static PyGetSetDef PyWcsprm_getset[] = { {"alt", (getter)PyWcsprm_get_alt, (setter)PyWcsprm_set_alt, (char *)doc_alt}, {"aux", (getter)PyWcsprm_get_aux, NULL, (char *)doc_aux}, {"axis_types", (getter)PyWcsprm_get_axis_types, NULL, (char *)doc_axis_types}, {"bepoch", (getter)PyWcsprm_get_bepoch, (setter)PyWcsprm_set_bepoch, (char *)doc_bepoch}, {"cd", (getter)PyWcsprm_get_cd, (setter)PyWcsprm_set_cd, (char *)doc_cd}, {"cdelt", (getter)PyWcsprm_get_cdelt, (setter)PyWcsprm_set_cdelt, (char *)doc_cdelt}, {"cel_offset", (getter)PyWcsprm_get_cel_offset, (setter)PyWcsprm_set_cel_offset, (char *)doc_cel_offset}, {"cname", (getter)PyWcsprm_get_cname, (setter)PyWcsprm_set_cname, (char *)doc_cname}, {"colax", (getter)PyWcsprm_get_colax, (setter)PyWcsprm_set_colax, (char *)doc_colax}, {"colnum", (getter)PyWcsprm_get_colnum, (setter)PyWcsprm_set_colnum, (char *)doc_colnum}, {"crder", (getter)PyWcsprm_get_crder, (setter)PyWcsprm_set_crder, (char *)doc_crder}, {"crota", (getter)PyWcsprm_get_crota, (setter)PyWcsprm_set_crota, (char *)doc_crota}, {"crpix", (getter)PyWcsprm_get_crpix, (setter)PyWcsprm_set_crpix, (char *)doc_crpix}, {"crval", (getter)PyWcsprm_get_crval, (setter)PyWcsprm_set_crval, (char *)doc_crval}, {"csyer", (getter)PyWcsprm_get_csyer, (setter)PyWcsprm_set_csyer, (char *)doc_csyer}, {"ctype", (getter)PyWcsprm_get_ctype, (setter)PyWcsprm_set_ctype, (char *)doc_ctype}, {"cubeface", (getter)PyWcsprm_get_cubeface, (setter)PyWcsprm_set_cubeface, (char *)doc_cubeface}, {"cunit", (getter)PyWcsprm_get_cunit, (setter)PyWcsprm_set_cunit, (char *)doc_cunit}, {"czphs", (getter)PyWcsprm_get_czphs, (setter)PyWcsprm_set_czphs, (char *)doc_czphs}, {"cperi", (getter)PyWcsprm_get_cperi, (setter)PyWcsprm_set_cperi, (char *)doc_cperi}, {"dateavg", (getter)PyWcsprm_get_dateavg, (setter)PyWcsprm_set_dateavg, (char *)doc_dateavg}, {"datebeg", (getter)PyWcsprm_get_datebeg, (setter)PyWcsprm_set_datebeg, (char *)doc_datebeg}, {"dateend", (getter)PyWcsprm_get_dateend, (setter)PyWcsprm_set_dateend, (char *)doc_dateend}, {"dateobs", (getter)PyWcsprm_get_dateobs, (setter)PyWcsprm_set_dateobs, (char *)doc_dateobs}, {"dateref", (getter)PyWcsprm_get_dateref, (setter)PyWcsprm_set_dateref, (char *)doc_dateref}, {"equinox", (getter)PyWcsprm_get_equinox, (setter)PyWcsprm_set_equinox, (char *)doc_equinox}, {"imgpix_matrix", (getter)PyWcsprm_get_imgpix_matrix, NULL, (char *)doc_imgpix_matrix}, {"jepoch", (getter)PyWcsprm_get_jepoch, (setter)PyWcsprm_set_jepoch, (char *)doc_jepoch}, {"lat", (getter)PyWcsprm_get_lat, NULL, (char *)doc_lat}, {"latpole", (getter)PyWcsprm_get_latpole, (setter)PyWcsprm_set_latpole, (char *)doc_latpole}, {"lattyp", (getter)PyWcsprm_get_lattyp, NULL, (char *)doc_lattyp}, {"lng", (getter)PyWcsprm_get_lng, NULL, (char *)doc_lng}, {"lngtyp", (getter)PyWcsprm_get_lngtyp, NULL, (char *)doc_lngtyp}, {"lonpole", (getter)PyWcsprm_get_lonpole, (setter)PyWcsprm_set_lonpole, (char *)doc_lonpole}, {"mjdavg", (getter)PyWcsprm_get_mjdavg, (setter)PyWcsprm_set_mjdavg, (char *)doc_mjdavg}, {"mjdbeg", (getter)PyWcsprm_get_mjdbeg, (setter)PyWcsprm_set_mjdbeg, (char *)doc_mjdbeg}, {"mjdend", (getter)PyWcsprm_get_mjdend, (setter)PyWcsprm_set_mjdend, (char *)doc_mjdend}, {"mjdobs", (getter)PyWcsprm_get_mjdobs, (setter)PyWcsprm_set_mjdobs, (char *)doc_mjdobs}, {"mjdref", (getter)PyWcsprm_get_mjdref, (setter)PyWcsprm_set_mjdref, (char *)doc_mjdref}, {"name", (getter)PyWcsprm_get_name, (setter)PyWcsprm_set_name, (char *)doc_name}, {"naxis", (getter)PyWcsprm_get_naxis, NULL, (char *)doc_naxis}, {"obsgeo", (getter)PyWcsprm_get_obsgeo, (setter)PyWcsprm_set_obsgeo, (char *)doc_obsgeo}, {"obsorbit", (getter)PyWcsprm_get_obsorbit, (setter)PyWcsprm_set_obsorbit, (char *)doc_obsorbit}, {"pc", (getter)PyWcsprm_get_pc, (setter)PyWcsprm_set_pc, (char *)doc_pc}, {"phi0", (getter)PyWcsprm_get_phi0, (setter)PyWcsprm_set_phi0, (char *)doc_phi0}, {"piximg_matrix", (getter)PyWcsprm_get_piximg_matrix, NULL, (char *)doc_piximg_matrix}, {"plephem", (getter)PyWcsprm_get_plephem, (setter)PyWcsprm_set_plephem, (char *) doc_plephem}, {"radesys", (getter)PyWcsprm_get_radesys, (setter)PyWcsprm_set_radesys, (char *)doc_radesys}, {"restfrq", (getter)PyWcsprm_get_restfrq, (setter)PyWcsprm_set_restfrq, (char *)doc_restfrq}, {"restwav", (getter)PyWcsprm_get_restwav, (setter)PyWcsprm_set_restwav, (char *)doc_restwav}, {"spec", (getter)PyWcsprm_get_spec, NULL, (char *)doc_spec}, {"specsys", (getter)PyWcsprm_get_specsys, (setter)PyWcsprm_set_specsys, (char *)doc_specsys}, {"ssysobs", (getter)PyWcsprm_get_ssysobs, (setter)PyWcsprm_set_ssysobs, (char *)doc_ssysobs}, {"ssyssrc", (getter)PyWcsprm_get_ssyssrc, (setter)PyWcsprm_set_ssyssrc, (char *)doc_ssyssrc}, {"tab", (getter)PyWcsprm_get_tab, NULL, (char *)doc_tab}, {"theta0", (getter)PyWcsprm_get_theta0, (setter)PyWcsprm_set_theta0, (char *)doc_theta0}, {"timesys", (getter)PyWcsprm_get_timesys, (setter)PyWcsprm_set_timesys, (char *) doc_timesys}, {"trefpos", (getter)PyWcsprm_get_trefpos, (setter)PyWcsprm_set_trefpos, (char *) doc_trefpos}, {"trefdir", (getter)PyWcsprm_get_trefdir, (setter)PyWcsprm_set_trefdir, (char *) doc_trefdir}, {"tstart", (getter)PyWcsprm_get_tstart, (setter)PyWcsprm_set_tstart, (char *) doc_tstart}, {"tstop", (getter)PyWcsprm_get_tstop, (setter)PyWcsprm_set_tstop, (char *) doc_tstop}, {"telapse", (getter)PyWcsprm_get_telapse, (setter)PyWcsprm_set_telapse, (char *) doc_telapse}, {"timeoffs", (getter)PyWcsprm_get_timeoffs, (setter)PyWcsprm_set_timeoffs, (char *) doc_timeoffs}, {"timsyer", (getter)PyWcsprm_get_timsyer, (setter)PyWcsprm_set_timsyer, (char *) doc_timsyer}, {"timrder", (getter)PyWcsprm_get_timrder, (setter)PyWcsprm_set_timrder, (char *) doc_timrder}, {"timedel", (getter)PyWcsprm_get_timedel, (setter)PyWcsprm_set_timedel, (char *) doc_timedel}, {"timepixr", (getter)PyWcsprm_get_timepixr, (setter)PyWcsprm_set_timepixr, (char *) doc_timepixr}, {"timeunit", (getter)PyWcsprm_get_timeunit, (setter)PyWcsprm_set_timeunit, (char *) doc_timeunit}, {"velangl", (getter)PyWcsprm_get_velangl, (setter)PyWcsprm_set_velangl, (char *)doc_velangl}, {"velosys", (getter)PyWcsprm_get_velosys, (setter)PyWcsprm_set_velosys, (char *)doc_velosys}, {"velref", (getter)PyWcsprm_get_velref, (setter)PyWcsprm_set_velref, (char *)doc_velref}, {"xposure", (getter)PyWcsprm_get_xposure, (setter)PyWcsprm_set_xposure, (char *)doc_xposure}, {"wtb", (getter)PyWcsprm_get_wtb, NULL, (char *) doc_wtb}, {"zsource", (getter)PyWcsprm_get_zsource, (setter)PyWcsprm_set_zsource, (char *)doc_zsource}, {NULL} }; static PyMethodDef PyWcsprm_methods[] = { {"bounds_check", (PyCFunction)PyWcsprm_bounds_check, METH_VARARGS|METH_KEYWORDS, doc_bounds_check}, {"cdfix", (PyCFunction)PyWcsprm_cdfix, METH_NOARGS, doc_cdfix}, {"celfix", (PyCFunction)PyWcsprm_celfix, METH_NOARGS, doc_celfix}, {"compare", (PyCFunction)PyWcsprm_compare, METH_VARARGS|METH_KEYWORDS, doc_compare}, {"__copy__", (PyCFunction)PyWcsprm_copy, METH_NOARGS, doc_copy}, {"cylfix", (PyCFunction)PyWcsprm_cylfix, METH_VARARGS|METH_KEYWORDS, doc_cylfix}, {"datfix", (PyCFunction)PyWcsprm_datfix, METH_NOARGS, doc_datfix}, {"__deepcopy__", (PyCFunction)PyWcsprm_copy, METH_O, doc_copy}, {"fix", (PyCFunction)PyWcsprm_fix, METH_VARARGS|METH_KEYWORDS, doc_fix}, {"get_cdelt", (PyCFunction)PyWcsprm_get_cdelt_func, METH_NOARGS, doc_get_cdelt}, {"get_pc", (PyCFunction)PyWcsprm_get_pc_func, METH_NOARGS, doc_get_pc}, {"get_ps", (PyCFunction)PyWcsprm_get_ps, METH_NOARGS, doc_get_ps}, {"get_pv", (PyCFunction)PyWcsprm_get_pv, METH_NOARGS, doc_get_pv}, {"has_cd", (PyCFunction)PyWcsprm_has_cdi_ja, METH_NOARGS, doc_has_cd}, {"has_cdi_ja", (PyCFunction)PyWcsprm_has_cdi_ja, METH_NOARGS, doc_has_cdi_ja}, {"has_crota", (PyCFunction)PyWcsprm_has_crotaia, METH_NOARGS, doc_has_crota}, {"has_crotaia", (PyCFunction)PyWcsprm_has_crotaia, METH_NOARGS, doc_has_crotaia}, {"has_pc", (PyCFunction)PyWcsprm_has_pci_ja, METH_NOARGS, doc_has_pc}, {"has_pci_ja", (PyCFunction)PyWcsprm_has_pci_ja, METH_NOARGS, doc_has_pci_ja}, {"is_unity", (PyCFunction)PyWcsprm_is_unity, METH_NOARGS, doc_is_unity}, {"mix", (PyCFunction)PyWcsprm_mix, METH_VARARGS|METH_KEYWORDS, doc_mix}, {"p2s", (PyCFunction)PyWcsprm_p2s, METH_VARARGS|METH_KEYWORDS, doc_p2s}, {"print_contents", (PyCFunction)PyWcsprm_print_contents, METH_NOARGS, doc_print_contents}, {"s2p", (PyCFunction)PyWcsprm_s2p, METH_VARARGS|METH_KEYWORDS, doc_s2p}, {"set", (PyCFunction)PyWcsprm_set, METH_NOARGS, doc_set}, {"set_ps", (PyCFunction)PyWcsprm_set_ps, METH_O, doc_set_ps}, {"set_pv", (PyCFunction)PyWcsprm_set_pv, METH_O, doc_set_pv}, {"spcfix", (PyCFunction)PyWcsprm_spcfix, METH_NOARGS, doc_spcfix}, {"sptr", (PyCFunction)PyWcsprm_sptr, METH_VARARGS|METH_KEYWORDS, doc_sptr}, {"sub", (PyCFunction)PyWcsprm_sub, METH_VARARGS|METH_KEYWORDS, doc_sub}, {"to_header", (PyCFunction)PyWcsprm_to_header, METH_VARARGS|METH_KEYWORDS, doc_to_header}, {"unitfix", (PyCFunction)PyWcsprm_unitfix, METH_VARARGS|METH_KEYWORDS, doc_unitfix}, {NULL} }; PyTypeObject PyWcsprmType = { PyVarObject_HEAD_INIT(NULL, 0) "astropy.wcs.Wcsprm", /*tp_name*/ sizeof(PyWcsprm), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)PyWcsprm_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ (reprfunc)PyWcsprm___str__, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash */ 0, /*tp_call*/ (reprfunc)PyWcsprm___str__, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ doc_Wcsprm, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ PyWcsprm_richcompare, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ PyWcsprm_methods, /* tp_methods */ 0, /* tp_members */ PyWcsprm_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)PyWcsprm_init, /* tp_init */ 0, /* tp_alloc */ PyWcsprm_new, /* tp_new */ }; #define CONSTANT(a) PyModule_AddIntConstant(m, #a, a) #define XSTRINGIFY(s) STRINGIFY(s) #define STRINGIFY(s) #s int _setup_wcsprm_type( PyObject* m) { if (PyType_Ready(&PyWcsprmType) < 0) { return -1; } Py_INCREF(&PyWcsprmType); wcsprintf_set(NULL); wcserr_enable(1); return ( PyModule_AddObject(m, "Wcsprm", (PyObject *)&PyWcsprmType) || CONSTANT(WCSSUB_LONGITUDE) || CONSTANT(WCSSUB_LATITUDE) || CONSTANT(WCSSUB_CUBEFACE) || CONSTANT(WCSSUB_SPECTRAL) || CONSTANT(WCSSUB_STOKES) || CONSTANT(WCSSUB_CELESTIAL) || CONSTANT(WCSHDR_IMGHEAD) || CONSTANT(WCSHDR_BIMGARR) || CONSTANT(WCSHDR_PIXLIST) || CONSTANT(WCSHDR_none) || CONSTANT(WCSHDR_all) || CONSTANT(WCSHDR_reject) || #ifdef WCSHDR_strict CONSTANT(WCSHDR_strict) || #endif CONSTANT(WCSHDR_CROTAia) || CONSTANT(WCSHDR_EPOCHa) || CONSTANT(WCSHDR_VELREFa) || CONSTANT(WCSHDR_CD00i00j) || CONSTANT(WCSHDR_PC00i00j) || CONSTANT(WCSHDR_PROJPn) || #ifdef WCSHDR_CD0i_0ja CONSTANT(WCSHDR_CD0i_0ja) || #endif #ifdef WCSHDR_PC0i_0ja CONSTANT(WCSHDR_PC0i_0ja) || #endif #ifdef WCSHDR_PV0i_0ma CONSTANT(WCSHDR_PV0i_0ma) || #endif #ifdef WCSHDR_PS0i_0ma CONSTANT(WCSHDR_PS0i_0ma) || #endif CONSTANT(WCSHDR_RADECSYS) || CONSTANT(WCSHDR_VSOURCE) || CONSTANT(WCSHDR_DOBSn) || CONSTANT(WCSHDR_LONGKEY) || CONSTANT(WCSHDR_CNAMn) || CONSTANT(WCSHDR_AUXIMG) || CONSTANT(WCSHDR_ALLIMG) || CONSTANT(WCSHDO_none) || CONSTANT(WCSHDO_all) || CONSTANT(WCSHDO_safe) || CONSTANT(WCSHDO_DOBSn) || CONSTANT(WCSHDO_TPCn_ka) || CONSTANT(WCSHDO_PVn_ma) || CONSTANT(WCSHDO_CRPXna) || CONSTANT(WCSHDO_CNAMna) || CONSTANT(WCSHDO_WCSNna) || CONSTANT(WCSHDO_P12) || CONSTANT(WCSHDO_P13) || CONSTANT(WCSHDO_P14) || CONSTANT(WCSHDO_P15) || CONSTANT(WCSHDO_P16) || CONSTANT(WCSHDO_P17) || CONSTANT(WCSHDO_EFMT) || CONSTANT(WCSCOMPARE_ANCILLARY) || CONSTANT(WCSCOMPARE_TILING) || CONSTANT(WCSCOMPARE_CRPIX)); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/src/wcslib_wtbarr_wrap.c0000644000175100001710000001570100000000000021376 0ustar00vstsdocker#define NO_IMPORT_ARRAY #include "astropy_wcs/wcslib_wtbarr_wrap.h" #include #include #include #include /* It gets to be really tedious to type long docstrings in ANSI C syntax (since multi-line strings literals are not valid). Therefore, the docstrings are written in doc/docstrings.py, which are then converted by setup.py into docstrings.h, which we include here. */ #include "astropy_wcs/docstrings.h" /*************************************************************************** * PyWtbarr methods * ***************************************************************************/ static PyObject* PyWtbarr_new(PyTypeObject* type, PyObject* args, PyObject* kwds) { PyWtbarr* self; self = (PyWtbarr*)type->tp_alloc(type, 0); return (PyObject*)self; } static int PyWtbarr_traverse(PyWtbarr* self, visitproc visit, void *arg) { Py_VISIT(self->owner); return 0; } static int PyWtbarr_clear(PyWtbarr* self) { Py_CLEAR(self->owner); return 0; } static void PyWtbarr_dealloc(PyWtbarr* self) { PyWtbarr_clear(self); Py_TYPE(self)->tp_free((PyObject*)self); } PyWtbarr* PyWtbarr_cnew(PyObject* wcsprm, struct wtbarr* x) { PyWtbarr* self; self = (PyWtbarr*)(&PyWtbarrType)->tp_alloc(&PyWtbarrType, 0); if (self == NULL) return NULL; self->x = x; Py_INCREF(wcsprm); self->owner = wcsprm; return self; } static void wtbarrprt(const struct wtbarr *wtb) { int i, nd, ndim; if (wtb == 0x0) return; wcsprintf(" i: %d\n", wtb->i); wcsprintf(" m: %d\n", wtb->m); wcsprintf(" kind: %c\n", wtb->kind); wcsprintf("extnam: %s\n", wtb->extnam); wcsprintf("extver: %d\n", wtb->extver); wcsprintf("extlev: %d\n", wtb->extlev); wcsprintf(" ttype: %s\n", wtb->ttype); wcsprintf(" row: %ld\n", wtb->row); wcsprintf(" ndim: %d\n", wtb->ndim); wcsprintf("dimlen: %p\n", (void *)wtb->dimlen); ndim = wtb->ndim - (int)(wtb->kind == 'c'); nd = 1 + (int) log10(ndim ? ndim : 1); for (i = 0; i < ndim; i++) { wcsprintf(" %*d: %d\n", nd, i, wtb->dimlen[i]); } wcsprintf("arrayp: %p\n", (void *)wtb->arrayp); return; } static PyObject* PyWtbarr_print_contents(PyWtbarr* self) { /* This is not thread-safe, but since we're holding onto the GIL, we can assume we won't have thread conflicts */ wcsprintf_set(NULL); wtbarrprt(self->x); printf("%s", wcsprintf_buf()); fflush(stdout); Py_RETURN_NONE; } static PyObject* PyWtbarr___str__(PyWtbarr* self) { /* This is not thread-safe, but since we're holding onto the GIL, we can assume we won't have thread conflicts */ wcsprintf_set(NULL); wtbarrprt(self->x); return PyUnicode_FromString(wcsprintf_buf()); } /*************************************************************************** * Member getters/setters (properties) */ static PyObject* PyWtbarr_get_i(PyWtbarr* self, void* closure) { return get_int("i", self->x->i); } static PyObject* PyWtbarr_get_m(PyWtbarr* self, void* closure) { return get_int("m", self->x->m); } static PyObject* PyWtbarr_get_extver(PyWtbarr* self, void* closure) { return get_int("extver", self->x->extver); } static PyObject* PyWtbarr_get_extlev(PyWtbarr* self, void* closure) { return get_int("extlev", self->x->extlev); } static PyObject* PyWtbarr_get_ndim(PyWtbarr* self, void* closure) { return get_int("ndim", self->x->ndim); } static PyObject* PyWtbarr_get_row(PyWtbarr* self, void* closure) { return get_int("row", self->x->row); } static PyObject* PyWtbarr_get_extnam(PyWtbarr* self, void* closure) { if (is_null(self->x->extnam)) return NULL; return get_string("extnam", self->x->extnam); } static PyObject* PyWtbarr_get_ttype(PyWtbarr* self, void* closure) { if (is_null(self->x->ttype)) return NULL; return get_string("ttype", self->x->ttype); } static PyObject* PyWtbarr_get_kind(PyWtbarr* self, void* closure) { return PyUnicode_FromFormat("%c", self->x->kind); } /*************************************************************************** * PyWtbarr definition structures */ static PyGetSetDef PyWtbarr_getset[] = { {"i", (getter)PyWtbarr_get_i, NULL, (char *) doc_i}, {"m", (getter)PyWtbarr_get_m, NULL, (char *) doc_m}, {"kind", (getter)PyWtbarr_get_kind, NULL, (char *) doc_kind}, {"extnam", (getter)PyWtbarr_get_extnam, NULL, (char *) doc_extnam}, {"extver", (getter)PyWtbarr_get_extver, NULL, (char *) doc_extver}, {"extlev", (getter)PyWtbarr_get_extlev, NULL, (char *) doc_extlev}, {"ttype", (getter)PyWtbarr_get_ttype, NULL, (char *) doc_ttype}, {"row", (getter)PyWtbarr_get_row, NULL, (char *) doc_row}, {"ndim", (getter)PyWtbarr_get_ndim, NULL, (char *) doc_ndim}, /* {"dimlen", (getter)PyWtbarr_get_dimlen, NULL, (char *) NULL}, */ /* {"arrayp", (getter)PyWtbarr_get_arrayp, NULL, (char *) NULL}, */ {NULL} }; static PyMethodDef PyWtbarr_methods[] = { {"print_contents", (PyCFunction)PyWtbarr_print_contents, METH_NOARGS, doc_print_contents_wtbarr}, {NULL} }; PyTypeObject PyWtbarrType = { PyVarObject_HEAD_INIT(NULL, 0) "astropy.wcs.Wtbarr", /*tp_name*/ sizeof(PyWtbarr), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)PyWtbarr_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash */ 0, /*tp_call*/ (reprfunc)PyWtbarr___str__, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ doc_Wtbarr, /* tp_doc */ PyWtbarr_traverse, /* tp_traverse */ PyWtbarr_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ PyWtbarr_methods, /* tp_methods */ 0, /* tp_members */ PyWtbarr_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ }; int _setup_wtbarr_type(PyObject* m) { if (PyType_Ready(&PyWtbarrType) < 0) { return -1; } Py_INCREF(&PyWtbarrType); PyModule_AddObject(m, "Wtbarr", (PyObject *)&PyWtbarrType); return 0; } ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2312572 astropy-5.0.2/astropy/wcs/tests/0000755000175100001710000000000000000000000015704 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/__init__.py0000644000175100001710000000010000000000000020004 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/conftest.py0000644000175100001710000000156000000000000020105 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import pytest import numpy as np from astropy import wcs from . helper import SimModelTAB @pytest.fixture(scope='module') def tab_wcs_2di(): model = SimModelTAB(nx=150, ny=200) # generate FITS HDU list: hdulist = model.hdulist # create WCS object: w = wcs.WCS(hdulist[0].header, hdulist) return w @pytest.fixture(scope='module') def tab_wcsh_2di(): model = SimModelTAB(nx=150, ny=200) # generate FITS HDU list: hdulist = model.hdulist # create WCS object: w = wcs.WCS(hdulist[0].header, hdulist) return w, hdulist @pytest.fixture(scope='function') def tab_wcs_2di_f(): model = SimModelTAB(nx=150, ny=200) # generate FITS HDU list: hdulist = model.hdulist # create WCS object: w = wcs.WCS(hdulist[0].header, hdulist) return w ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2352574 astropy-5.0.2/astropy/wcs/tests/data/0000755000175100001710000000000000000000000016615 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/2wcses.hdr0000644000175100001710000002070000000000000020521 0ustar00vstsdockerSIMPLE = T / conforms to FITS standard BITPIX = -32 / array data type NAXIS = 2 / number of array dimensions NAXIS1 = 2048 NAXIS2 = 4096 EXTEND = T RUN = 418552 / Run number OBSERVAT= 'LAPALMA ' / Name of observatory (IRAF style) OBSERVER= 'Drew ' / Name of principal investigator OBJECT = 'intphas_4970 Ha' / Title of observation LATITUDE= 28.761929 / Telescope latitude (degrees), +28:45:42.9 LONGITUD= -17.877577 / Telescope longitude (degrees), -17:52:39.3 HEIGHT = 2348 / [m] Height above sea level. SLATEL = 'LPO2.5 ' / Telescope name known to SLALIB TELESCOP= 'INT ' / 2.5m Isaac Newton Telescope MJD-OBS = 53240.9816151 / Modified Julian Date of midtime of observation JD = 2453241.4816151 / Julian Date of midtime of observation PLATESCA= 6.856013 / [d/m] Platescale ( 24.68arcsec/mm) TELFOCUS= 0.043969 / Telescope focus (metres) AIRMASS = 1.048846 / Effective mean airmass DATE-OBS= '2004-08-23T23:32:32.4' / UTC date start of observation UTSTART = '23:32:32.4' / UTC of start of observation TEMPTUBE= 10.15365 / Truss Temperature (degrees Celsius) INSTRUME= 'WFC ' / INT wide-field camera is in use. WFFPOS = 1 / Position-number of deployed filter WFFBAND = 'Halpha ' / Waveband of filter WFFID = '197 ' / Unique identifier of filter SECPPIX = 0.333 / Arcseconds per pixel DETECTOR= 'WFC ' / Formal name of camera CCDSPEED= 'FAST ' / Readout speed CCDXBIN = 1 / Binning factor in x axis CCDYBIN = 1 / Binning factor in y axis CCDSUM = '1 1 ' / Binning factors (IRAF style) CCDTEMP = 156.114 / [K] Cryostat temperature NWINDOWS= 0 / Number of readout windows CCDNAME = 'A5506-4 ' / Name of detector chip. CCDXPIXE= 1.35E-05 / [m] Size of pixels in x. CCDYPIXE= 1.35E-05 / [m] Size of pixels in y. AMPNAME = 'LH ' / Name of output amplifier. GAIN = 2.8 / Nominal Photo-electrons per ADU. READNOIS= 6.4 / Nominal Readout noise in electrons. NUMBRMS = 257 / Number of standards used STDCRMS = 0.067 / Astrometric fit error (arcsec) PERCORR = 0.0 / Sky calibration correction (mags) EXTINCT = 0.09 / Extinction coefficient (mags) RADESYSA= 'ICRS ' EQUINOX = 2000.0 CTYPE1 = 'RA---ZPN' / Algorithm type for axis 1 CTYPE2 = 'DEC--ZPN' / Algorithm type for axis 2 CRPIX1 = -337.20001 / [pixel] Reference pixel along axis 1 CRPIX2 = 3040.5 / [pixel] Reference pixel along axis 2 CRVAL1 = 292.20508 / [deg] Right ascension at the reference pixel CRVAL2 = 18.582556 / [deg] Declination at the reference pixel CRUNIT1 = 'deg ' / Unit of right ascension coordinates CRUNIT2 = 'deg ' / Unit of declination coordinates CD1_1 = -1.3007094E-06 / Transformation matrix element CD1_2 = -9.2396054E-05 / Transformation matrix element CD2_1 = -9.2389091E-05 / Transformation matrix element CD2_2 = 1.3203634E-06 / Transformation matrix element PV2_1 = 1.0 / Coefficient for r term PV2_2 = 0.0 / Coefficient for r**2 term PV2_3 = 220.0 / Coefficient for r**3 term ORIGZPT = 21.53 / Original nightly ZP; uncorrected for extinctionMAGZPT = 21.40896253966641 / Re-calibrated DR2 zeropoint EXPTIME = 120.02 / [sec] Exposure time assumed by the pipeline CHECKSUM= '7RREBPRB9PRBAPRB' / HDU checksum updated 2014-02-06T12:02:07 DATASUM = '1660673036' / data unit checksum updated 2014-02-06T12:02:07 HISTORY 20041004 14:45:42 HISTORY $Id: cir_create_file.c,v 1.10 2004/09/03 10:48:45 jim Exp $ HISTORY 20041004 14:45:43 HISTORY $Id: cir_ccdproc.c,v 1.9 2004/09/07 14:18:51 jim Exp $ HISTORY 20041004 22:52:54 HISTORY $Id: cir_imcore.c,v 1.11 2004/09/07 14:18:52 jim Exp $ HISTORY 20041004 22:52:56 HISTORY $Id: cir_platesol.c,v 1.9 2004/09/07 14:18:54 jim Exp $ HISTORY 20041005 16:05:06 HISTORY $Id: cir_imcore.c,v 1.11 2004/09/07 14:18:52 jim Exp $ HISTORY 20041006 07:31:07 HISTORY $Id: cir_platesol.c,v 1.9 2004/09/07 14:18:54 jim Exp $ HISTORY 20131220 22:36:15 HISTORY Headers updated by Geert Barentsen as part of DR2. HISTORY This included changes to MAGZPT, EXPTIME and the WCS. COMMENT Calibration info COMMENT ================ COMMENT The MAGZPT keyword in this header has been corrected for atmospheric COMMENT extinction and gain (PERCORR) and has been re-calibrated as part of DR2.COMMENT COMMENT Hence to obtain calibrated magnitudes relative to Vega, use: COMMENT mag(Vega) = MAGZPT - 2.5*log(pixel value / EXPTIME) END ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/3d_cd.hdr0000644000175100001710000000240000000000000020264 0ustar00vstsdockerCD1_2 = -3.72E-05 CD1_3 = 0 CD1_1 = -4.12E-05 CUNIT3 = 'nm ' CUNIT2 = 'deg ' CTYPE1 = 'RA---TAN' NAXIS = 3 CTYPE3 = 'AWAV ' CD2_1 = -3.72E-05 CTYPE2 = 'DEC--TAN' CD2_3 = 0 CD2_2 = 4.12E-05 CUNIT1 = 'deg ' CD3_1 = 0 CD3_2 = 0 CD3_3 = 0.2 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/chandra-pixlist-wcs.hdr0000644000175100001710000001464000000000000023205 0ustar00vstsdockerDATE = '2020-04-25T20:17:34' / Date and time of file creation DATE-OBS= '2000-07-07T09:25:15' / Observation start date DATE-END= '2000-07-07T15:27:29' / Observation end date TTYPE5 = 'chipx ' / Chip coords TFORM5 = '1I ' / format of field TUNIT5 = 'pixel ' TTYPE15 = 'pha_ro ' / total read-out pulse height of event TFORM15 = '1J ' / format of field TUNIT15 = 'adu ' TNULL15 = 0 MTYPE5 = 'CPC ' / DM Keyword: Descriptor name. MFORM5 = 'CPCX,CPCY' / [mm] TCTYP5 = 'CPCX ' TCRVL5 = 0.0000000000000E+00 TCRPX5 = 5.0000000000000E-01 TCDLT5 = 2.3987000000000E-02 TCUNI5 = 'mm ' TTYPE6 = 'chipy ' / Chip coords TFORM6 = '1I ' / format of field TUNIT6 = 'pixel ' TTYPE16 = 'energy ' / nominal energy of event (eV) TFORM16 = '1E ' / format of field TUNIT16 = 'eV ' TCTYP6 = 'CPCY ' TCRVL6 = 0.0000000000000E+00 TCRPX6 = 5.0000000000000E-01 TCDLT6 = 2.3987000000000E-02 TCUNI6 = 'mm ' MTYPE6 = 'MSC ' / DM Keyword: Descriptor name. MFORM6 = 'PHI,THETA' / [deg] TTYPE9 = 'detx ' / ACIS detector coordinates TFORM9 = '1E ' / format of field TUNIT9 = 'pixel ' TTYPE19 = 'grade ' / binned event grade TFORM19 = '1I ' / format of field TCTYP9 = 'LONG-TAN' TCRVL9 = 0.0000000000000E+00 TCRPX9 = 4.0965000000000E+03 TCDLT9 = 1.3666666666667E-04 TCNA9 = 'PHI ' TCUNI9 = 'deg ' LONP9 = 2.7000000000000E+02 LATP9 = 9.0000000000000E+01 TTYPE10 = 'dety ' / ACIS detector coordinates TFORM10 = '1E ' / format of field TUNIT10 = 'pixel ' TCTYP10 = 'NPOL-TAN' TCRVL10 = 0.0000000000000E+00 TCRPX10 = 4.0965000000000E+03 TCDLT10 = 1.3666666666667E-04 TCNA10 = 'THETA ' TCUNI10 = 'deg ' TTYPE11 = 'x ' / sky coordinates TFORM11 = '1E ' / format of field TUNIT11 = 'pixel ' TCTYP11 = 'RA---TAN' TCRVL11 = 2.2938051931869E+02 TCRPX11 = 4.0965000000000E+03 TCDLT11 = -1.3666666666667E-04 TCUNI11 = 'deg ' TTYPE12 = 'y ' / sky coordinates TFORM12 = '1E ' / format of field TUNIT12 = 'pixel ' TCTYP12 = 'DEC--TAN' TCRVL12 = -5.8811080688850E+01 TCRPX12 = 4.0965000000000E+03 TCDLT12 = 1.3666666666667E-04 TCUNI12 = 'deg ' TIMESYS = 'TT ' / Time system TIMEZERO= 0.0000000000000E+00 / [s] Clock correction TIMEUNIT= 's ' / Time unit TIMEREF = 'LOCAL ' / Time reference (barycenter/local) TIMEPIXR= 5.0000000000000E-01 / default TIMEDEL = 9.4104000000000E-01 / [s] timedel Lev1 TIMEDELA= 9.4104000000000E-01 / Inferred duration of primary exposure (s) TIMEDELB= 0.0000000000000E+00 / Inferred duration of secondary exp. (s) TIME_ADJ= 'NONE ' / time adjustment algorithm TSTART = 7.9349115922606E+07 / [s] Observation start time (MET) TSTOP = 7.9370849510907E+07 / [s] Observation end time (MET) MJD-OBS = 5.1732392545401E+04 / Modified Julian date of observation RADESYS = 'ICRS ' / Equatorial coordinate system ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/defunct_keywords.hdr0000644000175100001710000000606300000000000022700 0ustar00vstsdockerSIMPLE = T / Uncompressed file's conforms to FITS BITPIX = 16 / data type of original image NAXIS = 2 / dimension of original image NAXIS1 = 720 / length of original image axis NAXIS2 = 720 / length of original image axis PSLIB_V = '34286 ' MODULE_V= '34287:34288' PHOT_V = '34286:34322' STATS_V = '34286 ' STACK_V = '34286 ' HISTORY ppStack source: 60eb6cdc-a59c-4636-a4e0-dba66a9721fd NINPUTS = 18 / Number of input images STK_TYPE= 'DEEP_STACK' / type of stack STK_ID = '1237984 ' / type of stack SKYCELL = 'skycell.0680.071' / type of stack TESS_ID = 'RINGS.V3' / type of stack AIRM_SLP= 0. / airmass slope PSCAMERA= 'GPC1 ' / Camera name PSFORMAT= 'SKYCELL ' / Camera format IMAGEID = 1237984 / Image identifier SOURCEID= 35 / Source identifier CTYPE1 = 'RA---TAN' CTYPE2 = 'DEC--TAN' CRVAL1 = 205.063293456991 CRVAL2 = -29.9999999999985 CRPIX1 = 17900.5 CRPIX2 = -13877.5 CDELT1 = 6.94444461259981E-05 CDELT2 = 6.94444461259981E-05 PC001001= -1. PC001002= 0. PC002001= 0. PC002002= 1. RA_DEG = 206.45559692 / Right Ascension of stamp center DEC_DEG = -29.00419807 / Declination of stamp center BSCALE = 1.073792648315E+01 / Scaling: TRUE = BZERO + BSCALE * DISK BZERO = 3.501794623489E+05 / Scaling: TRUE = BZERO + BSCALE * DISK BLANK = 32767 / Value for undefined pixels ZBLANK = 32767 / Value for undefined pixels END././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/dist.fits0000644000175100001710000005500000000000000020447 0ustar00vstsdockerSIMPLE = T / conforms to FITS standard BITPIX = 8 / array data type NAXIS = 0 / number of array dimensions EXTEND = T WCSAXES = 2 / Number of coordinate axes CRPIX1 = 0 / Pixel coordinate of reference point CRPIX2 = 0 / Pixel coordinate of reference point CDELT1 = 1 / Coordinate increment at reference point CDELT2 = 1 / Coordinate increment at reference point CRVAL1 = 0 / Coordinate value at reference point CRVAL2 = 0 / Coordinate value at reference point LATPOLE = 90 / [deg] Native latitude of celestial pole RESTFRQ = 0 / [Hz] Line rest frequency RESTWAV = 0 / [Hz] Line rest wavelength AXISCORR= 2 END XTENSION= 'IMAGE ' / Image extension BITPIX = -32 / array data type NAXIS = 1 / number of array dimensions NAXIS1 = 4096 PCOUNT = 0 / number of parameters GCOUNT = 1 / number of groups EXTNAME = 'D2IMARR ' / extension name CRPIX1 = 2048.0 CRPIX2 = 0.0 CRVAL1 = 2048.0 CRVAL2 = 0.0 CDELT1 = 1.0 CDELT2 = 1.0 END š}JšŠ!Žēė?ē\A8ē yŨēČ/jēđÕ¨ģ šbģ 6 ģÃDģžģT9ģ ĸņģ‡;ģ*y^ģEģ]Bwģkģm CģbŖģNØcģ6ģŗ}ģÂģ#:ģ?oģ_īnģxõģƒīģ€Äqģ[Gũģŋ0ēĩŊēHē˜ē(ã˛ēąũ¸ģ#Ÿ:ģEŊģ1*iģn5ĀēŠQ§;4Eī;-wŧ;+Y;(A ;$úÅ;"˜û;R!;+Ã;(Ā; 8ž;(H:ú…õ:ņŊe:íŪā:č6<:åõ:ÛâZ:ĪD3:ˇTÄ:šnÂ:p˜¸:!ŋ9❴9’ =98 zd¸Ķaše­˛šåiŠēCÉáē“ō#ēŋp¸ēãw1ģ ,Pģ õkģÔģžģ‡ģXlģX3ģ$ØYģ=KSģX bģgüģnŦģfYMģTö9ģ= œģ"ÕÉģX+ģū°ģ7ģWŽ>ģsRÄ삎ģƒUģhnûģ-Ö{ēÕąƒēgaøēÕÜē…ēĀ‚ģĪēģE,ģ2í[ģY4ąģ33y;dÍ;.Ļ(;+Ė ;)%Į;%gî;#xŦ; 1Ō;O;uš;Zm;įŠ:ūéČ:ķa :īžA:é:åõ:ßa:Ķ*Ã:ŋ7[:ĸ/T:‚ČĻ:3X”9õ¨F9§Đ97į48|RȸŒŅ.š=”āšžáËē+R‹ē…÷ē´ôo稞kģĻ™ģCžģ´ģ0Ÿģ.×ģ “ģfčģŸģ5āŖģQÁ^ģd}SģnŦģieŠģZ–\ģCąģ)`Įģ4+ģŒģ/ąĘģN‡ģm4îģ€×ļģ„Qģs^ģ?…ũē÷ú:ēˆnwēæ#ē*ÖēkēöAģ>Jqģ:OģD/ģmlÛ:Áé;1jË;,>‘;*s‰;&GŸ;#åÔ;!‚;°; ~;Ī; ’;ĻÎ:ôh:đąÜ:ëS|:åõ:áúĪ:ÖŠ‡:Æ`:ŠNß:ŒÖæ:H˜ą:͏9ģüb9aØZ8ļ–ˇûĢΚvFšĸŽÉēĻüēoøēŠĻĘēĪ0ēûR&ģ°Įģ æzģIJģžģˆģ č$ģΙģ/ÕģJœ ģ`‰^ģl}wģlåģ_\*ģJAđģ0ŒdģÄĖģjxģ(xNģF+>ģeņŖģ|ãĪģ„e­ģ|sTģO­“ģ ûČē ĨUē3ūÖēųē@bģēÍqĄģ0ޝģB8Öģ5üģz˜7gŠĀ;4é;,Īô;*æų;''P;$Ŗ‰;!ņ3;7Đ;Õ;Ų0; Øķ;Øˇ:÷æÔ:ņ–í:ėP:ææ­:äŌH:ŲËC:ËU„:ąß:”ŽŊ:_Eč:ț9Đôö9‚P8îĮ7'烏ũZšƒ$pēŽhēV#ŧēkēÆOēíWģ §ģ ĨÛģ3ģžģägģû7ģoŽģ(ņ˙ģC1Zģ\*ėģjscģmhžģcē0ģP_Äģ7Î_ģ…ģßŲģ!zČģ=u ģ]ĀTģwĨŠģƒ˛Ŋģl+ģ^šCģ UIēŊ*ŠēO1ēø‚ē!æzēŠA2ģâ›ģF ‘ģ1*iģi:õēāZÛ;0W;-¯Ĩ;+Y;(yˆ;%;"Đä;Š ;ŗž;˜’; āX;˜:ûe˜:ō-6:îN˛:č¤L:åõ:ÜÁū:ЋĨ:š :œ. :u֍:%ßī9åí‰9—I9š78(nиÃg5š[2šÚ˙ėē=Ŧhēs–ēŧŅÎēāÉģÜÚģ e=ģeģžģ֞ģ‰ģxŽģ#ˆäģ;q0ģV…ģguģnŦģg8ōģV}šģ>Ëįģ$•ģĮūģ¯9ģ5—ÎģU'=ģqËfģ‚`úģƒW2ģk\/ģ2‘;*Ģr;&ˆ;$ž;!Ik;2;Bf;‰Ą; ‰d; :õGļ:đče:ëS|:åõ:âÚs:׉+:ĮfÔ:ĢQ5:ū:Nļ*: L9Á:79lT8Äˎ§Îmšy)ššZFēi%ēhúöēϘ ēĖŽē÷͘ģ†Oģ VKģü›ģžģПģ ģļ–ģ-ˆwģH¤×ģ_qŌģl Ļģl‹ļģ`sˇģKÉMģ2ƒ“ģDģŪrģ&šģCü!ģcúpģ{”Wģ„Išģ~H‹ģSĶÚģ‘âē§|Õē:MēØĨē8ĸēÃxoģ,ˆgģCĄ^ģ3´*ģw{šŨę&;5ü;-Ũ;+œ;'kē;$Ŗ‰;");[;ņ§;I; HÅ;H‰:øÆx:ņ–í:ė˙!:įV}:åB:Ú;:ˤú:ŗÕË:–ŨÖ:ec_:ÄP9Ö2Ë9‡ŽS9$ē7§ēƒ¸īšz§€šöä‚ēPCēš\bēÃŅ6ē騊ģ >ģ ­ģĸčģžģ~fģS|ģX"ģ'w“ģA:)ģZŪ(ģiģ“ģmؐģd™ŌģQį"ģ9Ļģãģԟģģ~ģ;}Ôģ[ĒąģvV3ģƒ^āģ‚™ģaāčģ$ëcēÅgēVLē —lēRē „ŅģܰģF cģ1-āģcũ ģRŗ;,';-įŽ;+…Ä;(ąr;%;#Í;Áō;#;ÕŪ; z¯;ë:ü°Œ:ō::č¤L:åõ:ŨĄ :ŅkG:ģä:íP:{a:*> 9ë+]9œ†æ9(E8Dc;¸ŽoÜšPļZšĐ„=ē7ŽíēŒõēē2âēŨđŪģdģ ĶŋģÔŌģįĒģžļģĘ ģl6ģ"9nģ9ąęģTũ¤ģf<ŅģnŦģgåžģW÷!ģ@‹,ģ&@ģ7Đģ_Ãģ3 žģRÔPģpDģņ(샟rģn3ģ6Ōeēæ]ēzyÆē(ĩē ũķ炞zģ~ ģB}-ģ6džģNI"ģUAŦ;~ę;/ŅÕ;+ōė;*Ģ;%×Á;#žx; ĄĨ;âķ;U=;:;ļ;„Đ:ķwY:đ}å:ęW:åõ:āi:Ôę :Âĩč:ĨĪå:ˆz:=Ô=:ø9ąx9LŪ…8šиQŊš-íŗš°ĒŠē #âē}ķõē¯ļšēÔũģ( ģD÷ģŨŠģTĶģŋģxgģ § ģmŌģ2AÛģNBÎģb¸šģm]5ģj÷8ģ],ÎģG+ģ,ßXģķsģ͜ģ+÷CģJ‰ņģiĘģG}ģ„mGģx]õģG˜tģ΅ē“ÉÎē(—Šē ČēT%ēዸģ7öjģ>Ļģ;äŸģzĢ:VŒ™;3*;,`;*ã\;&ˇr;$U§;!U;ĸU;ĸ;ųt; ų5;ąZ:ö'Y:ņX6:믒:æí:ãē:ØhÍ:ČļI:­€M:Ėz:T–đ: ĘŠ9Æx 9uĒË8Ō ˇ'âš | š‘āē +Pēb` ēŖ‰QēĘ_ēôU ģNfģ ÆģSXģžģ˜ļģ JÔģŸ ģ,ģFŌĀģ^ZEģkÕģlĶNģa‹DģMPĢģ4OgģcēģnĄģ$ųŊģAÍ ģbAģzDâģ„'†ģ€ęģWŠģ(ēŽyūēA]ē¸Iē0+äēēŧģ(6[ģDđĶģ2d´ģsÖēc$ņ;5!);-?Æ;+P„;'ۋ;$ÂĐ;"a;ī/;ƒã;¸Ö; ¸™;¸Z:ųĻ:ņ–í:ínô:įÆN:åąę:Û€:Íôo:ĩ•:˜¯:kYĸ:"9Ûpž9ŒĖ'9  c7āū†¸á äšp+Ôšî(ēIčÉē—M¤ēÁĸ翆Ĩģ ^wģ …ģ,0ģžģF}ģČXģ@–ģ&(ģ?BųģYŽŗģhÛđģnŦģeyvģSn€ģ;Lîģ!ģ ˆģNtģ9†ĨģYŗ‚ģtÚ~ģƒ ģ‚‘`ģe'“ģ)wGēÍcē^Ŗē 6UēÂ}瘟ģÖÅģEĶzģ2 „ģ^̍ģA3;#˘;.6>;+Ŋ­;(é[;%/ø;#@ˇ;ųÜ;“c; Į; ęƒ;wž:ū:ķ Ų:ī.U:č¤L:åõ:ہD:ŌJë:Ŋ/ü:Ÿ˙ļ:€):.œP9đi19ĄÄē9/B38`W§¸šÎ°šF:­šĮ <ē1qtē‰vx玓÷ēÛQōģ=īģ ¨ģD¤ģ“ģfĖģ{ģTĒģ éųģ7ØIģSvFģe].ģnŦģhXģYF–ģB)Õģ'Ĩžģ§ĄģOģ1ŠoģPĨ7ģnŧ¨ģ—ģƒ×\ģpߨģ;^žēī;Ņē‚ŋē†îē _ ēx+Ķģ@7ģ@Ŋåģ8WmģHū5ģcú:ã’ļ;0Šö;,*Ö;*;“;&Š;#žx; Ų;RÅ;Å;Šä;Ѝ;,:ķį-:đąÜ:ë6Š:åõ:áö:ÕÉ­:Äu/:§-:ŠĨd:C:N+9ļŊL9WZ-8¨¸'Îmš#ršŠ­‹ēæ ēvöÖēŦļ?ēŅēšēūŅ…ģxŅģ vŽģŒŧģžģ@~ģ Įüģ]ģ0—ģLƒˆģaĄ,ģlídģkžōģ^D[ģHē3ģ.žŸģĶģYģ*7ũģHZØģgéHģ~/đģ„mGģz{°ģK†Ôģ dŸēš‡ē-ßķē-%ēJ ē×âģ4wŨģ@y$ģ8cŽģ{Ž 9ܔÂ;4 ¸;,—ū;*æų;&īZ;$;!š>;˙Û;é;iE; i ;Y:÷˙:ņ–í:ėf:ævÁ:äb[:ŲHq:Ęŋ:¯¯e:’‹Á:YÔÄ:I69ËĩŪ9|§å8ā8˛Iš~횊#1ēíyē\BĻē z”ēČ/íēđÖ{ģ š‰ģ 5īģÃ*ģžģTSģ Ŗģ‡|ģ*yšģEyģ]B¸ģkFģm 7ģbĸĐģNØ ģ6­ģŗ/ģĪģ#:wģ?ņģ_īīģxõmģƒīģ€ÄJģ[G ģžēĩģäēHwē—ėē(åBēą˙­ģ# AģEĨģ1*iģn6ÔēŠES;4FĐ;-w¯;+Y;(A“;$ú¸;"˜î;R;+ž;(§; 8x;(.:ú…Ã:ņŊK:íŪÆ:č6":åõ:Ûâ):ĪCã:ˇTY:šnW:p—v:!€˛9āŽr9’ û9 8 s¯¸Ķ¨še°(šåkˇēCËPē“ōöēŋqWēãwčģ ,žģ õQģĶëģžģ”ģX†ģXgģ$اģ=KĮģX ŧģgüNģnŦģfYģTõŪģ= 4ģ"ÕbģXģū˙ģ7vģWŽĖģsS 삎%ģƒAģhn8ģ-ÕwēÕ¯–ēg_ņēÕ@ē…čēÂFģĐÚģEjģ2í(ģY5ęģ3/P;g—;.Ļ;+Ė ;)%¯;%gâ;#xŸ; 1Å;5;u;ZT;į:ūé–:ķa :īž(:éu:åõ:ß`ë:Ķ*’:ŋ6ö:ĸ.Ī:‚Č:3WR9õ§9§Ž97äą8|L¸ŒÔtš=–ƒšžãÖē+Sųē…÷éē´õ 稺 ģ§ģC‘ģ´vģ0Ÿģ.äģ ­ģgģŸ`ģ5áģQÁÆģd}ŠģnŦģieTģZ– ģCą3ģ)`_ģ3÷ģĀŲģ/˛>ģN‡‚ģm5Jģ€×Üģ„Dģs~Ãģ?…ē÷ø3ēˆm%ēåē+BēkBēöÅģ>K!ģ:NœģD02ģmk :ÁđĨ;1j˜;,>‘;*s|;&G’;#åČ;!v;—; q;ļ; z;Ļ´:ôgá:đąÜ:ëS|:åõ:áú:ÖŠT:Æ:ŠN{:ŒÖi:H—::ˏ9ģû 9aÕÖ8ļ;ˇûŋxšwęšĸ°nē¨6ēoų¸ēЧēĪÍēûR÷ģ°ēģ æ_ģÄĨģžģ•ģ čXģÎæģ/1ģJœ}ģ`‰ ģl}“ģlÉģ_[įģJA‘ģ0‹ęģÄģjŸģ(xļģF+Āģeōģ|äģ„e´ģ|rßģOŦœģ ú¸ē ŖĐē3ũjēøÍē@eēÍt ģ0¯ŽģB8jģ5üģz˜ā7mĸ;4é\;,Īč;*æų;''C;$Ŗ‰;!ņ';7Ä;ģ;Ų; ØÛ;؞:÷æŖ:ņ–í:ė7:ææ“:äŌ.:ŲË):ËU9:ąŪˆ:”Ž@:_D‰:ĮŌ9Đķŗ9‚O=8íūl7'’@¸ũĄšƒ&睤ēV%-ēkÖēÆŌēíWëģ Îģ ĨÁģ2üģžģä‚ģû^ģođģ(ō[ģC1Īģ\+,ģjsŠģmhŖģcšûģP_gģ7Íõģ'ģßįģ!{0ģ=u}ģ]ĀÖģwĨ÷샞Ņģlģ^™‚ģ T9ēŊ(ŅēO’ē÷áē!č'ēŠCKģãĐģF vģ1*iģi<7ēāN…;0Xp;-¯˜;+Y;(y|;%;"Đ×;‰ũ;ŗĻ;˜y; ā3;˜:ûef:ō-:îN™:č¤L:åõ:ÜÁË:Ћr:š§:œ-Ĩ:uÕ`:%Ūô9åė[9—Gå9—´8(h¸Ãl š[4|šÛ`ē=­ÕētgēŧŌkēāfģŨ)ģ e"ģdæģžģÖĢģ–ģxÃģ#‰3ģ;q›ģV…^ģgĒģnŦģg8ŊģV}<ģ>Ë{ģ$”ŠģĮãģ¯Šģ5˜GģU'ĖģqËÂģ‚aģƒWģk[‡ģ2;1ēŨü'ēpۆēɀē[ē‰ąBģ Ŋ"ģCöŪģ4Ĩ ģSĀ.ģEŋŸ;ôĀ;/)ņ;+Ė ;)•€;%ŸĘ;#°ˆ; iŽ;s;åS;Ę%;tÖ:˙É8:ķa :đ ų:é€F:åõ:ßų:Ô 4:Āö=:¤;:…fú:8•<9úäî9Ŧ@x9B`„8Œ x¸{ĩĻš6™fšˇŠkē%bķē‚y[ē˛V!ēÖ0›ģįģģD÷ģ5¨ģ0Ÿģöúģ°]ģ‡xģ‡Ôģ4ģP~ģcæģmÍ"ģjD÷ģ[åģEVyģ+§ģšģŗvģ-ģģLSģk‰Âģ€0"ģ„G-ģuö`ģCŠ$ģZJēŽËē#Xēkûē_c+ēë™øģ;‘;*Ģe;&{;$ą;!I^;2i;BZ;‰‡; ‰K;†:õGƒ:đčL:ëS|:åõ:âÚA:׈ø:Įf‰:ĢP¸::N´Ë: KS9Á9 9lQŠ8Ä Šˇ§âšzĖšš\Qēj_ēhü›ēϘÄēĖŽĸē÷Ôjģ†\ģ V1ģüģžģĐŦģ ĩģļ×ģ-ˆĶģHĨNģ_rģl Āģl‹›ģ`stģKČīģ2ƒģôģŪģ&šoģCü¨ģcúéģ{”¨ģ„Iŋģ~H!ģSŌãģŌē§{6ē:âēØpē8 …ēÃz‰ģ,‰fģCĄ ģ3´zģwRšŨ˛];5‘;-Đ;+Ž;'k ;$Ŗ‰;");B;ņ;Hé; HŦ;Hp:øÆG:ņ–í:ė˙:įVd:åA˙:Ú:ú:ˤ¯:ŗÕh:–ŨX:eb:ÃV9Ö19‡'9"a7§§š¸ī ešzŠõšöæēPŗēš]ēÃŅšēéŲ[ģ >Pģ “ģĸÎģžģ~tģS¤ģXdģ'wâģA: ģZŪwģiģĮģmØvģd™žģQæÄģ9;ģ„ģԑģģéģ;~Nģ[Ģ)ģvVƒģƒ^ķģ‚xģaā%ģ$ęSēÅzēV­ē –Ëē”ē †ęģŨäģF qģ1-ĢģcūbģM2;,%;-į;+…ˇ;(ąe;%;#Ā;Áæ;#w;ÕŅ; z–;Ō:ü°A:ōœî:îžj:č¤L:åõ:ŨĄo:Ņk:ģg:ėë:{5:*=&9ë*09œ…š9(Cˆ8D\ø¸ŽtĮšP¸ĪšĐ†´ē7\ēŒõØēē3ēŨņ{ģŗģ ͞ģÔ¸ģįģžÃģĘ­ģlxģ"9Ŋģ9˛SģTūģf=ģnŦģgåvģWöĶģ@ŠÄģ&âģ7ĩģ`ģ3ĄģRÔÖģpDdģņB샟eģn2Yģ6ŅKēæ}Vēzw‹ē'ąē ū”ē‚´'ģMģB}˜ģ6dRģNJpģU>_;č;/ŅŦ;+ōā;*ž;%×ŗ;#žx; Ą—;âŲ;U$;9÷;‘;„Ē:ķw@:đ}Ė:ęVĶ:åõ:āhî:ÔéØ:Âĩ„:ĨĪ‚:ˆä:=Ķ:a9ą~L9LÜ+8šޏQÆõš-đ)š°ŦLē %ē}õ˜ē¯ˇ7ēÔ€ģ(tģD÷ģŨcģTÆģŋģxtģ §Ôģn ģ2BFģNC7ģb¸úģm]Oģj÷ģ],ŽģGÃģ,Ūņģķ@ģĶŌģ+÷¯ģJŠwģiĘ{ģGĀģ„mGģx]bģG—ƒģÍkē“Čqē(–Rē ũēTŪēáŽ"ģ7÷@ģ>Ĩ•ģ;å…ģzM:VĄ’;3)ß;,`;*ãN;&ˇd;$Uš;!G;ĸ;;Ąū;ųY; ų;ą5:ö'':ņX:ë¯y:æÕ:ãšå:Øhœ:Čĩū:­Ī:Ė:T•Ä: Éā9ÆvŪ9uŠ98Ōāˇ( hš }¯š‘Ÿîē ,ŠēbaŽēŖŠēĘ_‰ēôUÚģNtģ ÆģS?ģžģ˜Ãģ JûģŸJģ,tģFĶ(ģ^Z‡ģkīģlĶ@ģa‹ģMPQģ4Oģclģnģģ$ú%ģA͏ģbēģzE2ģ„'“ģ€ĩģWÅģ&ëēŽxQēAŽē¸ē0-Įēēž'ģ(7uģDđ‚ģ2eģsũēc ;5!E;-?š;+Pw;'Ûq;$ÂÃ;"`ø;ī;ƒģ;¸ģ; ¸~;¸B:ųĨę:ņ–í:ínÚ:įÆ5:åąŌ:ÛN:Íô$:ĩ”Ž:˜ŽŦ:kXv:!‡9Ûor9ŒĘû9 ž 7āņ˙¸á*šp.Jšî*)ēIę8ē—N[ēÁĸ ēæ‡\ģ ^Ŧģ …eģ, ģžģFŠģČrģ@×ģ&(lģ?CnģYģhÜ$ģnŦģeyBģSn&ģ;L†ģ!ŗģ {ģNÁģ9‡ģYŗúģtÚÜģƒ ģ‚‘>ģe&Ëģ)v:ēÍa ē^Ąwē 5´ēÃŋ瘠æģ×ųģE͇ģ2 Oģ^Ŧøģ;˛;#Ζ;.6#;+ŊŸ;(éM;%/ë;#@Š;ųĪ;“I; ē; ęh;wŖ:ũ˙´:ķ Ā:ī.<:č¤L:åõ:ہ:ŌJš:Ŋ/~:Ÿ˙8:€(„:.›V9đh9ĄÃ9/@ĸ8`Qd¸šŅöšF=#šĮĸGē1râē‰wI玔”ēÛRģ>>ģ ›ģDŠģ†ģfÚģ{™ģTëģ ęGģ7ØŋģSvĄģe]bģnŦģh1ģYFHģB){ģ'ĨC짇ģœģ1ŠãģPĨšģnŊģŋģƒ×Nģpß7ģ;]Āēī9¸ē‚ž"ē…âē _Ģēx.ųģAyģ@žQģ8VôģH˙\ģcŦ:ãšÉ;0ŠÁ;,*Č;*;†;&œ;#žx; Ų€;RĒ;Äõ;ŠÉ;Ќ;,e:ķį:đąÜ:ë6v:åõ:áÅ:ÕÉ|:ÄtË:§ŽČ:ФÎ:Cä:Mb9ļŧ 9WWÔ8¨ã¸'ØBš#t|šŠ¯/ēįGēvøyēŦļöēŅģVēūŌXģxÃģ vsģŒ¯ģžģ@‹ģ Č0ģĢģ0—ęģLƒīģaĄnģlí~ģkžĖģ^DģHšŲģ.ž7ģŌãģ€ģ*8dģH[YģgéŊģ~02ģ„mGģz{8ģK…âģ c…ēšôē-Ū{ē-[ēJ\ēׂKģ4xŗģ@x¸ģ8d!ģ{Ģ9ÜĮí;4 ƒ;,—ō;*æų;&īM;$ƒ;!š0;˙Ī;Ī;i+; hî;Xī:÷Ę:ņ–í:ėJ:ævĻ:äbB:ŲH?:Ęs:¯Žé:’‹\:Y͘:Hn9Ë´˛9|ĻU8ā˛Iš€‘šŠ$Ôēîŗē\Dē {KēČ0nēđ×Lģ šąģ 5ÔģÃģžģTnģ Ŗ@ģ‡žģ*zģEáģ]Búģklģm )ģbĸģN׎ģ6Eģ˛áģÜģ#:Ūģ?žsģ_đqģxõēģƒīĒģ€Ä#ģ[FCģŊēĩēēHĘē—ˇē(æđ瞯ģ#Ą[ģE‰ģ1*iģn7ûēŠ8;4GÂ;-wĸ;+Y;(A†;$úĢ;"˜á;R;+u;(Œ; 8P;(:ú…Ž:ņŊ1:íŪŦ:č6:åõ:Ûáō:ĪC˜:ˇSõ:šmķ:p–J:!¸9ā­F9’Ī9ą8 mk¸Ķīše˛šåmÃēCĖžē“ķČēŋqôēãxŸģ ,íģ õ6ģĶÃģžģĸģXĄģX›ģ$Øöģ=L>ģX ģgü‚ģnŦģfXåģTõ„ģ= Ėģ"ÔúģW÷ģ˙Mģ7ëģW\ģsSz삎8ģƒ.ģhmvģ-ÔtēÕ­Šēg]×ēԟē†ŋēÄ)ģŌģEŽģ2ėķģY7:ģ3*Ú;j”;.Ĩô;+Ė ;)%“;%gÔ;#x’; 1¸;;uf;Z9;įu:ūéa:ķa :īž :éY:åõ:ß`´:Ķ*[:ŋ6‹:ĸ.Q:‚Įo:3V&9õĨØ9§a97âW8|EиŒ×ģš=˜'šžåäē+Uiē…øŧē´õĒ稺Ļģ§kģC„ģ´[ģ0Ÿģ.ņģ ĮģgQģŸĸģ5áģQÂ/ģd}žģnŦģie!ģZ•ŊģC°Ųģ)_øģ3ÃģÁ'ģ/˛ŗģN‡øģm5¤ģ€Øģ„7ģs~'ģ?„ē÷ö,ēˆkĶēäē+­ēkgēöJģ>KÜģ:N$ģD1Yģmi:Áø¸;1jc;,>‘;*so;&G…;#åē;!h;Â|; d;›; ^;Ϛ:ôgĒ:đąÜ:ëS|:åõ:áúh:ÖŠ:ÆÄ:ŠN:ŒÕâ:H•Û:Ëđ9ģųķ9aĶ{8ļˇûĶ!šyšĸ˛ēŠpēoû\ēŠ¨8ēĪkēûSËģ°­ģ æEģĘģžģĸģ čģĪ6ģ/ŒģJœôģ`‰áģl}­ģl°ģ_[ĻģJA7ģ0‹vģÄ1ģjÆģ(yģF,Aģeōģ|äkģ„eēģ|rkģOĢĨģ ų¨ē ĸJē3û˙ēø—ē@gXēÍvuģ0°­ģB7ūģ5ũ!ģz™ˇ7tx;4é';,ĪÚ;*æų;''6;$Ŗ‰;!ņ;7ļ;Ą;Øü; Øŋ;؃:÷æm:ņ–í:ė:ææy:äŌ:ŲË:ËTé:ąŪ:”­ē:_C:Æû9Đō‡9‚N8íûK7'l̏ũįšƒ'ˇē°ŪēV&›ēlŽēÆUēíXŊģ öģ Ĩ§ģ2âģžģäœģû†ģp2ģ(ōˇģC2Fģ\+mģjs˛ģmh‰ģcšĮģP_ ģ7͍ģĖģßôģ!{˜ģ=uōģ]ÁXģwĻF샞äģkŨģ^˜žģ S(ēŊ'ēOķē÷@ē!éÕēŠEdģåģF [ģ1*iģi=xēāAO;0Yb;-¯‹;+Y;(yn;%;"ĐĘ;‰đ;ŗŠ;˜^; ā ;—å:ûe0:ō-:îN~:č¤L:åõ:ÜÁ–:Ћ=:š;:œ-9:uÔ:%Ũč9åë9—FŖ9•Z8(a׸Ãq š[6ōšÛÔē=¯Fēu9ēŧĶēā‘ģŨwģ eģdĖģžģÖ¸ģŖģxøģ#‰‚ģ;rģV…ģģgŪģnŦģg8‰ģV|âģ>Ëģ$”AģĮÉ읨ģ5˜ŧģU(ZģqĖģ‚a.ģƒW ģkZŪģ2:!ēŨú9ēpŲLēČ}ē2牞īģ žcģC÷!ģ4¤ĄģSÁ~ģEģ*;÷ŧ;/)É;+Ė ;)•e;%ŸŊ;#°z; iĄ;rė;å7;Ę ;tŽ:˙É:ķa :đ ā:é€+:åõ:ßų:Ô ˙:ĀõŌ:¤Ī:…fY:8“û9úãŦ9Ŧ?59B^8Œ¸{ŋzš6› šˇĢē%d-ē‚z-ē˛VžēÖ1ģč$ģD÷ģ5ģ0Ÿģ÷ģ°jģ‡Ŧģˆģ4öģPčģcžģmÍ<ģjDÃģ[å3ģEVģ+?ģfģŗĒģ-ģ„ģLÉģkŠ)ģ€0Iģ„G ģuõŌģC¨;ģYGēŽzē#WGēlfē_eåēëœaģ;= ģ‘;*ĢX;&n;$¤;!IQ;2M;BL;‰m; ‰0;l:õGN:đč1:ëS|:åõ:âÚ :׈Á:Įf8:ĢP1:ú:NŗR: J}9Á7Č9lO$8Ä Nˇ§õŋš|pšš^_ēkšēhū>ēĻ™}ēĖ$ē÷Õ;ģ†iģ Vģü€ģžģĐšģ éģˇģ-‰.ģHĨÄģ_rUģl Ûģl‹ģ`s3ģKȕģ2‚ĨģĻģŪ§ģ&š×ģCũ*ģcû]ģ{”õģ„IÆģ~GēģSŅîģÁē§y—ē:wēØ:ē8 hēÃ|Ąģ,ŠeģC Ŋģ3´Ëģw(šŨz•;5‘1;-Ã;+€;'k„;$Ŗ‰;");';ņs;HÎ; H‘;HU:øÆ:ņ–í:ėūí:įVI:åAå:Ú:á:ˤ^:ŗÔü:–ÜŌ:e`‰:ÂI9Ö0\9‡‹ä9Ũ7§“—¸ī ŦšzŦišöč™ēP "ēš]ĐēÃŌ<ēéÚ/ģ >„ģ xģĸ´ģžģ~ģSËģXĨģ'x0ģA;ģZŪÅģiģũģmØZģd™iģQæjģ9ŒĶģ*ģԄģŧQģ;~Âģ[̟ģvVŅģƒ_ģ‚Xģaßcģ$éBēōēVē –)ēÖē ‰ģßģF ~ģ1-tģc˙¤ģGą;,$;-įt;+…Š;(ąX;%;#ŗ;ÁØ;#\;ÕÄ; z|;ˇ:ü¯đ:ōœÔ:îžP:č¤L:åõ:ŨĄ8:Ņjß:ē˙á:ė€:{ō:*<9ë(î9œ„w9(AÚ8DVB¸Žy°šPģCšĐ‰(ē7‘ĖēŒöĒēē4ēŨōģŽģ ͤģԝģįģžĐģĘēģlšģ": ģ9˛ģģTū[ģf=;ģnŦģgåOģWö‚ģ@ŠYģ&‡ģ7›ģ`bģ3Ą‹ģRÕXģpDžģņ\샟Xģn1ąģ6Đ;ēæ{OēzuPē&Žē ˙6ē‚ĩÔģ€ģB~ģ6cčģNKĀģU;;„å;/Ņ„;+ōŌ;*;%×Ļ;#žx; Ą‰;âž;U ;9Ũ;i;„‚:ķw%:đ}ą:ęV:åõ:āhĶ:Ôéĸ:Âĩ:ĨĪ:ˆC:=ŅĪ:Ā9ą} 9LŲ§8šS¸QĐÉš-ōŸš°­ņē &Xē}÷;睎ÔēÔģ(ÜģD÷ģŨ<ģTšģŋģxģ ¨ ģnoģ2BŽģNCŸģbš;ģm]jģjöéģ],KģGWģ,Ū…ģķ ģÔģ+øģJŠøģiĘãģHģ„mGģx\ĶģG–™ģĖ[ē“Įē(•ē 3ēT ˜ēᐋģ7øģ>Ĩģ;æiģzī:VļŠ;3)Ē;,_û;*ã@;&ˇV;$UŒ;!:;ĸ;Ąâ;ų>; ų;ą :ö&ņ:ņX:ë¯^:æē:㚯:Øhe:ČĩŽ:­I:ËĢ:T”‚: É 9Æuœ9u§8Ō„ˇ(0ģš Rš‘Ąųē -Äēbb˙窊ŋēĘ` ēôVŦģNģ ÅéģS$ģžģ˜Đģ K"ģŸŒģ,ĐģFĶ’ģ^ZČģkž ģlĶ3ģaŠŋģMOķģ4N”ģcģnÕģ$úģAÎģb.ģzE€ģ„' ģ€ģWŽéģ%ÛēŽvąēAēˇŨē0/ĒēēĀAģ(8ģDđ2ģ2eVģs%ēbí);5!`;-?Ģ;+Pj;'ÛV;$Âĩ;"`ę;îų;ƒ“;¸ ; ¸c;¸&:ųĨ´:ņ–í:ínĀ:įÆ:åąļ:Û:ÍķĶ:ĩ”B:˜ŽA:kW4: z9Ûn09ŒÉš9 ›…7ā䔸áršp0žšî,4ēIë§ē—OēÁŖ#翈ģ ^áģ …Jģ+áģžģF—ģȍģAģ&(ģģ?CåģYPģhÜZģnŦģey ģSmČģ;Lģ!Gģ mģOģ9‡“ģY´pģtÛ6ģƒ *ģ‚‘ģe&ģ)u6ēÍ_ē^Ÿpē 5ēÅē˜ĸĘģŲ.ģEĶ”ģ2 ģ^ŽFģ61;#Г;.6;+Ŋ’;(é@;%/Ū;#@œ;ųÁ;“.; ­; ęM;wˆ:ũ˙d:ķ Ĩ:ī.":č¤L:åõ:Ū€Ü:ŌJƒ:Ŋ.ų:Ÿūŗ:€'ã:.šJ9đfÂ9ĄÂK9/>õ8`JޏšÕ=šF?—šĮ¤Tē1tSē‰x玕3ēÛS.ģ>ģ ŽģDoģyģfįģ{ŗģU-ģ ę–ģ7Ų5ģSvũģe]–ģnŦģhģYEøģB)ģ'¤åģ§mģíģ1Ē\ģPĻ@ģnŊ`쁿ģƒ×AģpŪ›ģ;\Éēī7˛ē‚ŧŅē„Ūē `Lēx2ģBģģ@žŊģ8V{ģI‚ģbũ_:ãĸÜ;0ŠŠ;,*ģ;*;y;&;#žx; Ųr;R;ÄÛ;ŠŽ;Šr;,<:ķæø:đąÜ:ë6A:åõ:áŽ:ÕÉF:Ät_:§Ž]:Ф-:Cĸ:LŒ9ļēŨ9WUP8¨‰¸'âš#vōšŠ°ŌēčēvúēŦˇŦēŅģķēūĶ*ģxļģ vYģŒĸģžģ@™ģ Čfģúģ0˜GģL„YģaĄ¯ģlí˜ģkž¤ģ^CÖģHš{ģ.ĖģŌ­ģŠģ*8ĐģH[āģgę5ģ~0uģ„mGģzzÂģK„ųģ buēšoē-Ũē-ŒēJ‚ēׄĩģ4y‹ģ@xMģ8dĩģ{M9Üû;4 L;,—ä;*æų;&ī@;$u;!š#;˙Á;´;i; hÔ;XĮ:÷•:ņ–í:ė1:æv‹:äb':ŲH :Ę#:¯Žb:’Šņ:YŌV:G—9Ëŗp9|¤§8ßũē˛ëíš‚5šŠ&xēīîē\E„ē |ēČ0ōēđØģ šØģ 5ēģÂ÷ģžģTˆģ Ŗhģˆģ*zrģEJģ]C;ģk“ģm ģbĸOģN×Tģ6 Ú작ģéģ#;Iģ?žøģ_đ÷ģxö ģƒī¸ģ€Ãûģ[E_ģģõēĩ¸bēH+ē—„ē(čē˛ģģ#ĸbģEnģ1*iģn9#ēŠ*æ;4Hŗ;-w”;+Y;(Ax;$úž;"˜Ô;Qų;+M;(r; 8(;'ø:ú…W:ņŊ:íŪ‘:č5í:åõ:ÛáŊ:ĪCG:ˇS‰:šm‡:p•:!~Ŧ9āŦ9’Œ9.8 fĩ¸Ķ6šeĩšåoÎēCÎ.ē“ôšēŋr‘ēãyUģ -;ģ õģ͜ģžģ¯ģXģģXĪģ$ŲFģ=L´ģX uģgüļģnŦģfXąģTõ(ģ= eģ"ԒģWŨģ˙ģ7cģWīģsSØģ‚ˇMģƒģhlŦģ-ĶhēÕĢŦēg[ŅēÔ燇ēÅëģĶ.ģEíģ2ėĀģY8Šģ3&f;m‘;.ĨÚ;+Ė ;)%y;%gÆ;#x…; 1Ē;;uK;Z;įZ:ūé*:ķa :īķ:é>:åõ:ß`:Ķ*&:ŋ6 :ĸ-Ë:‚ÆÎ:3Tä9õ¤–9§97ßŌ8|?¸ŒÛš=™Ëšžįđē+V×ē…ųē´öG稴Cģ§ÔģCvģ´Aģ0Ÿģ.ūģ áģg…ģŸãģ5âģQ˜ģd}ōģnŦģidíģZ•pģC°~ģ)_ģ3ģÁuģ/ŗ,ģNˆpģm6쀨,ģ„*ģs}†ģ?ƒē÷ôēˆjwēãē,ēkWēö ĸģ>LŒģ:MŗģD2mģmgL:ÂË;1j.;,>‘;*sa;&Gw;#å­;![;Âa; V;€; D;Ļ:ôgu:đąÜ:ëS|:åõ:áú2:Ö¨ę:Æt:ŠM¤:ŒÕ\:H”c:Ë9ģøą9aĐ÷8ļ žˇûæËš{1šĸŗĩēĒŦēoũēŠ¨ņēĪēûTœģ° ģ æ+ģċģžģ¯ģ čÁģ΃ģ/čģJjģ`Š!ģl}Æģl–ģ_[fģJ@Üģ0‹ģÃãģjíģ(y†ģF,Ãģeķģ|äģģ„eÁģ|qņģOĒ§ģ øŽē  ¸ē3úˆēøeē@iēÍxĩģ0ą›ģB7›ģ5ũĢģzš7y˙ŋ;4čô;,ĪÍ;*æų;''(;$Ŗ‰;!ņ ;7Ē;†;Øá; ØĨ;Øi:÷æ7:ņ–í:ė:ææ^:äŅø:ŲĘô:ËT˜:ąŨ{:”­4:_Aš:Æ%9ĐņE9‚LĪ8í÷đ7'Dh¸ũ /šƒ)[ē˛ēV( ēmE篨ēíYģ ģ ĨŒģ2Čģžģäļģû­ģpsģ(ķģC2ēģ\+¯ģjsØģmhoģcš“ģP^°ģ7Í%ģrģāģ!{˙ģ=vfģ]ÁŲģwĻ–ģƒ˛ųģkĩģ^—öģ RēŊ%OēOEēöŠē!ëfēŠGYģæ%ģF Bģ1*iģi>Ļēā4û;0ZC;-¯~;+Y;(ya;%;"Đŧ;‰â;ŗp;˜C; ßâ;—Ę:ûdû:ō,į:îNd:č¤L:åõ:ÜÁa:Ћ:šĐ:œ,Î:uŌÜ:%ÜÜ9åé×9—Ea9’Ö8([!¸Ãuôš[9fšÛKē=°´ēv ēŧĶĨēā‘ĄģŨÆģ dîģdąģžģÖÆģ°ģy,ģ#‰Đģ;rlģV†ģgģnŦģg8UģV|†ģ>ĘĢģ$“ŲģĮ°ģ°%ģ5™0ģU(éģqĖwģ‚aHģƒV÷ģkZ/ģ29ēŨø<ēpÖüēĮqēú牴€ģ ŋģC÷`ģ4¤<ģSÂļģEˇ;ú†;/)Ŗ;+Ė ;)•L;%Ÿ°;#°m; i“;rŌ;å;Éđ;t†:˙ČÎ:ķa :đ Ä:é€:åõ:ßøæ:Ô É:Āõf:¤d:…e¸:8’š9úâk9Ŧ=ķ9B[{8Œ¸{ÉPš6œŦšˇŦ°ē%eiē‚zūē˛W[ēÖ1 ģčģD÷ģ5Yģ0Ÿģ÷ģ°wģ‡áģˆWģ4]ģPPģcžNģmÍVģjDģ[äåģEUŠģ+×ģ2ģŗŨģ-ģøģL‘=ģkŠ‘ģ€0pģ„GģuõCģC§IģX:ēŽē#VēlĘē_hpē랡ģ;=Đģ‘;*ĢL;&a;$—;!IE;23;B?;‰R; ‰;P:õG:đč:ëS|:åõ:âŲÕ:׈Œ:Įeč:ĢOĢ:t:NąÛ: IĻ9Á6†9lL 8Äôˇ¨ hš~šš`jēlÕēh˙āēϚ3ēĖ§ē÷Ö ģ†wģ UũģüsģžģĐĮģ ģˇZģ-‰ŠģHĻ:ģ_r–ģl õģl‹gģ`rōģKČ:ģ2‚1ģXģŪÁģ&ē?ģCũĢģcûĶģ{•Cģ„IĖģ~GRģSĐöģŽąē§wéē:˙ēØē8+ēÃ~–ģ,‹SģC qģ3ĩģwņšŨFƒ;5‘K;-ļ;+t;'kl;$Ŗ‰;"(õ;;ņZ;Hŗ; Hw;H::øÅÛ:ņ–í:ėūĶ:įV/:åAĘ:Ú:Å:ˤ :ŗÔ‘:–ÜL:e_:Á=9Ö/9‡Šĸ9X7§u¸īōšzŽßšöę§ēP ēš^‰ēÃŌŋēéÚ˙ģ >¸ģ ^ģĸšģžģ~ŽģSōģXįģ'xģA;‹ģZßģiŧ1ģmØ@ģd™5ģQæģ9ŒlģŒĪģÔwģŧšģ;7ģ[ŦģvWģƒ_ģ‚7ģaŪ ģ$č2ēÅŸēV nē •“ē砊øģā:ģF Šģ1-CģdŅģB;,˙;-įg;+…;(ąK;%;#Ļ;ÁĖ;#C;Õˇ; zb;œ:ü¯Ÿ:ōœ¸:îž5:č¤L:åõ:ŨĄ:ŅjĒ:ē˙Z:ė:{°:*; 9ë'Ŧ9œƒ49(@,8DOŒ¸Ž~œšPŊššĐ‹œē7“;ēŒ÷{ēē4ēēŨōˇģŽPģ Ķ—ģԃģį‚ģžŨģĘČģlûģ":Zģ9ŗ%ģTūˇģf=oģnŦģgå'ģWö5ģ@‰ōģ&,ģ7‚ģ`¯ģ3ĸģRÕÚģpEģņv샟Kģn1ģ6Ī*ēæyIēzsē%Ēē ˙Ė炎eģŧģB~gģ6cƒģNLúģU7ũ;‡¯;/Ņ^;+ōÆ;*„;%י;#žx; Ą};âĨ;Tđ;9Ä;C;„Z:ķw :đ}•:ęVh:åõ:āhš:Ôél:´­:ĨÎĢ:ˆĸ:=Ќ:9ą{Į9L×"8šø¸Qڞš-õ𰝓ē '’ē}øŨ睏qēÔ†ģ)FģD÷ģŨģTŦģŋ,ģxŽģ ¨=ģnžģ2CģND ģbš~ģm]„ģjöÁģ], ģGđģ,ŪģōÖģÔ:ģ+øģJ‹zģiËKģHBģ„mGģx\EģG•°ģËKē“ÅÎē(“äē eēT %ēá’Ëģ7øáģ>¤‘ģ;į>ģz˜:VĘ;3)w;,_î;*ã4;&ˇJ;$U€;!-;ĸ;ĄĘ;ų%; øé;°į:ö&Ā:ņWč:ë¯D:æž:ãšy:Øh0:Čĩ]:­~Ã:Ë?:T“@: Č39ÆtZ9uĨß8Ō)ˇ(X š €õš‘¤ē .˙ēbdmēŖ‹vēĘ`ŽēôW}ģNģ ÅĪģS ģžģ˜Ũģ KIģŸÎģ,,ģFĶûģ^[ ģkž#ģlĶ'ģaŠģMO˜ģ4N,ģbÍģnīģ$úøģAΒģb¤ģzEÎģ„'­ģ€MģWŽ ģ$ËēŽuēApēˇĢē01mēēÂ6ģ(9•ģDīįģ2eĄģs8ēbĶ;5!y;-?Ÿ;+P];'Û=;$Š;"`Ū;îā;ƒm;¸‡; ¸J;¸:ųĨ‚:ņ–í:ínĻ:įÆ:åąœ:Ûã:Íķƒ:ĩ“Ø:˜­Õ:kUō:n9Ûlí9ŒČw9 ™7ā×(¸á¸šp33šî.@ēIíē—OĖēÁŖĻ翈Ęģ _ģ …0ģ+ēģžģF¤ģȧģAZģ&) ģ?D\ģYŸģh܍ģnŦģexØģSmlģ;K˛ģ!āģ `ģO`ģ9ˆģY´äģtÛ‘ģƒ =삐ũģe%Eģ)t3ēÍ].ē^iē 4}ēÆ.瘤ģÚNģEĶ ģ2 įģ^¯€ģ1 ;#Ōo;.5ī;+Ŋ†;(é3;%/Ņ;#@;ųĩ;“;  ; ę4;wo:ũ˙:ķ Œ:ī.:č¤L:åõ:Ū€Ļ:ŌJM:Ŋ.s:Ÿū,:€'B:.™=9đe€9ĄÁ 9/=G8`C÷¸šØƒšFB šĮĻaē1uÁē‰xí玕ĐēÛSËģ>Ûģ ģDUģlģfôģ{ÍģUnģ ęäģ7ŲŠģSwYģe]ËģnŦģhŒâģYEĒģB(Âģ'¤Šģ§Sģ;ģ1ĒĐģPĻÂģnŊģ쁀 ģƒ×4ģpŪģ;[Ōēī5Ģē‚ģ€ēƒÛē `âēx5ģCčģ@ŋ!ģ8V ģI–ģbúJ:ãĒe;0ŠY;,*Ž;*;m;&‚;#žx; Ųf;Rv;ÄÁ;Š•;ŠX;,:ķæŪ:đąÜ:ë6:åõ:á]:ÕÉ:Äsõ:§ņ:ŠŖŒ:C`:Kĩ9ļš›9WRË8¨-¸'ëëš#yfšŠ˛tēéŊēvûžēŦ¸eēŅŧ‘ēūĶüģxŠģ v?ģŒ•ģžģ@Ļģ șģHģ0˜ĄģL„ĀģaĄđģlí˛ģkž}ģ^C–ģHš ģ.dģŌyģĪģ*98ģH\bģgęĢģ~0ĩģ„mGģzzNģK„ģ adēšęē-ÛĨē-ÂēJŌē׆õģ4zRģ@wčģ8e?ģ{Œõ9Ũ*Û;4 ;,—Ø;*æų;&ī3;$i;!š;˙ĩ;›;h÷; hē;XĄ:÷b:ņ–í:ė:ævr:äb:ŲG×:ĘØ:¯­ä:’І:YŅ:FÁ9˲-9|ĸú8ßú_ŗI././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/dist_lookup.fits.gz0000644000175100001710000020560300000000000022465 0ustar00vstsdocker‹‡žUdist_lookup.fitsė›{xSežĮõYoĢûŦãuĮãXMzî'e5ß$…hÚÄ$@ëekڜļ4ŠšUÅa]o⅛Ü-7ËM šĒ(ƒEÅûz{|æQםugöŲß{’´i›BĒūąŧ˙ĀSÎųô÷žŋûīŧø]Ĩ^ˇ“ã†qyV€+æĒcҚXŧ>Á%c\‰+āįÉ`4Œ‡ōŊĀqpŧŽōxâãņ`# &ƒ\˛ąAĪOéXeļr—ŸëĮ/šĒ¯Ōã\Ŧ&K×ëŅD8Mäå9ËÎ2Gûíķ2`§ÖŠujZ§ÖŠujZ§Ö˙›ÅĘIŋËS6Œ+r•Ú†S%Íåüs1įĒÖęœ>!™ŽJOÄ;Nũl’Ä~ŽŸÅž×ĪOČËxūDŌôĀûįĩ{F–zÕ/4ãÁz=ŠĮķī4Ŋ†'tâÕÆcŠ†ãąØĸūŖĖVę$^‘ßî2~ÔŲ^œí–%éN@3xŖœžãČ×ÁG;=Ą:lfÃL>‘į5/šxK@†H–!˛VD@G0Ч;ÁšpDįÆ\­Õãôã<=ĄËg+1ÜĨÄ$%n°Čķ–bâ[Žaę;ĀH0‘äęcĄpM¸:˜Ė/ĒĢl„Ķį ôܯ†Ŗuz<œä’u:××ã\ ‘ŽōŸŸ7Ģ1Vš†WĒjīėú “QŸĐK¤â:éŅ$IØ#Ë\ôų9ŨN{Āį)ķį(¸˜ĢЇkë’Q=‘āRŅpōDöōãŽbnt‰ŗÛœ}„ËËšβ€ĢÄeˇ(¤ũ,‘,†(=Æ+&lu]¸,pą8'^ķSK˜ģčübņHˆŗĮbņP8Ę<ÃߘHęõ\0â|zÄp ooM?­Ņvŋ­ÜéīMŧīQô z‡ vĨŖ<ņ^äe‹™ÅĶ ĻęQãz×ŖÕä}á z¤Ģ/OŧxQ6x}å˛šsåSĖĒÄ+ĒEāUÍ›jÂqŠ*Á á7.Ié\0y<ĻÁËČgŌD3¯ČŠ&XdQŗX­Œ—ĐĢc¤ÛŪí ¯Ķ¯Čg3™L[™ÉīōfCBą§rvläô2löķŲ;ņ ųŠN{yš˛gyĄ’Ä#ž`­ŧĸŠjÕ$•&^!eÉd8aĒČ'į7Œ7ĮÍI37Ąƒ'<ÅlUD…rˆE•5I䉧ö×˜å‰ų3/ŠĒdÉT4Uēķrˇ×“€Œ—–ĪDVeŲ"˂(iŠÖ}ŋĮįĨtF1ņ:ė7ķéåŧ–göĢŠIčIJK\9Ą&RU„5’["IŋĒĢ=Oė%¯ĸwŧRCÁųę+Ãßâzu¸!ĢÎl9Xß Gk9–ÎĶBwãX(¯ĸËK>[ĨÍK ã‘ë* ĪwŪ¯ĪfÔĻ z<ÉŌoާÅáîE9…ÆÜ×,ō™´ąTâązČĄWG˜Ų›Ŋ{säËŨĢ"›I"ž7û´-ZéąÚáÕT3PĐŌGŲJlö€‡ÉĮŒ–`Q-’"™ũŽĶ#ąęp˛‘ R˜Ž§ål`y„KЙ’/Ģ“ąüĩG˙/:~§Íá s-qQeÃƝÍGSĀéķ˙DRä.;U(NŸMčn¤kĻrˆt#ÃÜVȞ|ƒá1ŠhU8ĨŒ"—1ŗXå‰Ũy/)]yâ ypĨ;¤ëņ´XF˙F/s‰đ]zTR74ld’D†—GžžØ{Ūɞ˙ņšÃOĀCÖáĢānrVŒöø?‡•t,&OŠĮá¤|iŗûYš+p%*¯Ž.ĘŖø—öŗę÷įŒWâļ•ļëC3[yUVDĘG"oôŦĪbš6ĘÃ8råë8=^›(ŽŽ‹)HëRH<_ˆw‹ˇŖŸ1‰fAČÆ?Ļ_€ĢÖR§ éÜ]zŸŊ—ķĄ|4‹Hz—yl,:aÕÃpĨޞÜüĢX+ä™üVOŽ_ŸĒĪôú'Ä<[ynžTD‘õÕē ļžōœļ˛vžhæeĢ HŲü[¯ŖŊ…Ņb,‡ÍwS;O0+˛&˲”é?¨0ˆŗMŗ*ŧjá rĄú•3ö,š%Cŧ*ĘŧhØsAį'įÄgÕĸЊdUž— =?ĪŅ}›^É×ŋ<‡č*ĨSfÔ,"KE_ÎŨ•œF8$†ëŠį‰åđĘØ‡Į!œČpeShHoĐŖėĢ9Ցņp°*ĸõšA¨IEĢ; ņsxlîi2ōŲØ‰tĮJĶ1Éēŧtfņ]ybFĀByv/ĶŽ1? Ģŧ•Ō¯ÆĘIāąīúĩ{™û4=č×Ķ Ąp‚tœ~?{dy¯˙8ŧé¤s˛ú¤… åđúĒß<"w’ī$õ›ÆwåŽß4ĪĐ¯˜Õ¯&Q}@šR(hŧĨOúÛõ+ö§~ÅŽúONŋíŧ~Ōo;¯Ÿôۙw˛úáō<ž .Ā>¯Į"‘ØxvÉēx,U[אJrÉô0•ĐCC¸ęx,dc™ĢęÉJú{%5Ž•‰Æ¨š&ÜÎK\GĪĢÆsôg帚ęĘpŊ RyČËŲ§ģ=UŖōęxzBéO¯Ō+I^AŦÉ}%īŖÕÕ!Ą’´,¯ũáî)ĢO+āpØÜŪļ´HTņ Ô*˛ĘžÍkņā ØX}ĀĻUąh‚UT¨mā-šĩī<—ƒ~›;ĪŧđÔCÄ%úœ%OTT3m”–•į%k!ũ%ãIYžÄ‹f:7™ˇR*đÖę âFĐæŠ_hÃ}įųl§ŋ‚Ũ**š)}^E'xåDō•Ķv{ē?T¯"/s¨Ī˨×ĘŲ÷…ĸ¨>ŪpĘô†§´oŠēė>Ą‡xīHc.zRį—šĪåéá>WŸWú>—§ßô‘žĪ՝W¨>ė§;G>.}ŋ¤0^ų æąû†|E!ŊÖøŅIé×ā‰ũČ3î›yzēoV/-_žûf}į÷õrôŅųž^aŧũvēŗWĪíaõœŗģŋ –‚âŠÛčÄ;Yų2ņŲĶ_ņŲyķHW™§ŧÛ~Ež/hŋÆ}BOæûjúJĄJiS2æĪä_ã>a–gÜ)”xJ–’\āŧŨ¸O˜åW yÅ"ˆĒRāŧظO˜áenjš,Čą°ũR=Ti7ęĄĸ“Ōk'^ú™×Īō•÷7¯Ÿ÷č?Ģ×l0úöÁ*Q/W†CÕ']o0Ą+3ĖÂE5ĸ_ēēŗ*%¨˛(ŠŒ6D •đÔ˙?ĩN­ž6-ߏ]Ō1´]|ģŸ*ĮŋW´ĸ-úV?v3fũvŽ( ,Úú6˙G<āĀš×žÅWĖRX}ˇ3n—Ņâ€Y+—aūwgᩅ˙Šië€÷îÁ‚'“xdÕ˙āáÖŨxėĨķąéüĨØxų$č×/Åܙlz÷5Ŧxh š/9m—^Š–3¯Ä|შņĐ.4}õXqÛ§˜5ük4oāđBŗ–īÛo‹Xü›é˜ũõrėRÛ0÷ÎíXĶ|>ūJuØcgâƒŗ&bIđüņņąėŠÛ0yū;8xúŧ¸6„Månl͌—=īböÔ÷ĐV1 M˜}ÆXxs+Ļŋû öVkŽųÛãAĀS§ĩáĐ÷gãOS“øęĘÛŅüÁØyū ėģAÆĖ ð÷Ãe˜ûá­xr~-šĻÄÖ3įáđą"<:īž(ũ–ũų|lŨø<ÖĪoAĶ‚Ũ˜9J@Kô1,—ĸõɘ>hZļŠXdž‚ˇV|ƒ'íįaFŲ4~ã~lÖ>ĮēĄ&^p)ž°/Žüm§`Ķ*ö]v.ļĪ8†O†×áȟÆęžÆ–kŋFĶđ3°ë‡Ĩd'åØVžëÃŞoṋßDëE‹ąJ˙›˙æÅ6˛ĩĮ/›ŒĮūw/֜6 ;ļ^€ŊŖíßļāŲΆbķ{°ö’AËÆLũï°öĄí˜)ÍÃĢSbÁ1OįqäžģđÚ=÷ĄųCņGĐR;ūf žŒõü9ØöÛŖxōˆˆ¯ģ{>܉]æ`™ú:–\63ëĮ’3ŋÄąƒ>L9} ļģ˙†Gf˙Oür!ÍøšLŋƜ§‡ŖĨâ,ē;ŠÕnدô ûŨ‡#Ûļ`Š÷,|i"V\ų4ϧ,žą;^ƒEãGbÁ=w`Ū”AhQžÄĻa‹°mō¯°tŠûæī’ îĮîbî…Wcē?Œš#^Eķ ė?k ¯ēmõ÷bΜĐúׯëâTėŧeö4nFëĀ!Xoŋ›'=†į7\oĢØĪĢ|;/|€ ÷a^ãŖxë‹8ޚˆŠw Å´o7`ŲĶąîðäōK°Ĩmšī-G‹ëž˙‡ÃXbžŽWwŒÄēÔŊØ5€Įá#§ãųÕk1kĀ=xéũQظօĄĮ°úģéx÷ö7°4Z‚×ß|­tV‡†>ŽÃƒ'āķWb×ŅĶą÷?gãĀÎ Ŧ QœX1ĶŦMhųd8žŊâŦûƏ-_œ­ãcîͰūũߥuÉŖXōÖĨX÷åfŦŧn öŋRŽ)Ž÷ąôƒ—1+y[Cįãp=ëg.zĢfÁōëæ`ņáØô7+ĮƒĪtŪ¸øģéŋžÁÔŠ|˛į÷X¯†ņčŌG°eh/ļúq˙šī1yėۘuĮģØkkÂüõoáđ{ևnÅĒ—ųfĖQKąj´Ķæ\ˆ]ŸŒĀâˇvĸi×:<ˆÖŋŋƒÎBGķŠÉØ=lōÆŅ#'Ŗų´CØpÕĩxåŅ6ûšo7Û+¯Ē°;ãˆ}āŽ—đĖļšØų~ ļ~´oŦŠųŖ&`始ąč“/°cÖZLŅâíVĖŨļ›LIÜŖKØ÷Ųt4ŊoĮ~΃8ē`6ļNšë'āŗíoāå&ļW´˙ŨÁËąčļĶņâÖ8^ K˛ŪŽ5;‚XyW n{+ūü:¸ Ëīū'Ŧ>ë/x器1ī"ėžā(6oŪ‹%įY°āŅmhû?’Î2*ÎŦëļqwww׎Û,âîîîî.„āîR8PNQ¸ģkqâîvĪûŨ=čA¤ĪŲ{­9ĶĄ:DMövsķúát˙ ƒDvõš†vļ+˛æ2ⷜÂÄm.#>!ŗXÂŖUbįŦ!äĩ™›{ōbų 2|¤øú=%ĸ¤Ŗ=ŅŋBâr¨Ÿ$ģŽøq]&!˛"ģ¤`SŊGäõ8"ŒÜŅ>Y‚—K(ĄYø°ŽÄxŪEų˜¨|cHž4 MÂd’ĩũpŪˇ‚ŦĮ#ŠL¸A@‹ū8¤Ép8°—^SĐô?G†ë0ÔãŦđú&zĄųadĨ#Đ\OåĮ„[ĮĖņ}OKŦėNJFŊ΃1ÉøMÎ!ķ[J—†¨ņˊ´÷ųÄŽ¯{\äņK7Ÿī"˙ėMÂû_ÁõÍY’Kg kĩƒGÍņ$°ŗ¤aJ_žm¸Ę;wI×A’kx`1›ŋŸđØIKr„ąæõIĘŦ"Ņ  6“˛ i[’ŪģˆôäĀ|°á­Õ ĒšŋÜ ­ūą¯ ŸÛÄũ!Äŋ›HIt•ßšęt ų؞Ü0˙Ev8ū߂đ owû8bej\÷î$đX[ĖÖ‰¨ ėoėlM(ęT‹¤öŸČ{ˇ–ō¤ƒ$7˙üņ12ëĄōÚDډ ˙Õ#ōä”"7Ŗļ§`ošÍ2ŽL#)+ķÃQ$<^NäŒ ¸Ôī‡ßģ䨿‘õė+ú22?ˆhÛ˙'ŠÜŧ šf ԈrRÃŌÚ ˙‹]I]Z)év×Dr`ÍDIBũpÉQąWßí‡S0û9ũģ6÷Ž"ŧošÁJ<žÖĮųx4ļOģP°*Ģ€ŗÜķYO¤į7Ŧæ4Įčšō}Čn7„'owJēUwÔÛņK‚|Šä ŲO‰dMĩdXÄž×´ãUĪ÷<Ũ߄ŒōSxõ؄MĄ%ēĮŋ1]˙äĘgb7đéD‰¤v­Ž’QYS$ccģHLu¤Ęt"_7r÷í bv|ĸ°A(!˙ŽĄŠ~ŒëŦ:ČFå˛ŽĄ†CI}Í;íXî=)ií”HT\ ’}SÉ:Ōˇ'FČ˙Äv´” ™ ȍ #Ėl.…á)„”m§g‚š3y$ęYŊpũā@TÍKÖ&ĄË]MĩOC"NžÃ˙ņlãMņZrŸëupŸˇ…ŦŨfŸ¨!zŅ,!~āÜ7ŋ"lÍŧN<&uyŪYšDŨŠEŸ##öíl|û“ŧlŸ¤Žô—¤ßūļi6¤´īÅ]Ī=xôX‰ŲČ'ØÚ„‘œĩ^b:č§Á’üI|ˆąDzj ņ3ĶɒVáŧõÎoI(؃ßÁTÜ,“­¸KéŠ}¨mĮÂx4¯ß,œ4Œ/ÆdÜ×֊”ņa\ŽLôŒNøÅ¤érUĪք?؏jũQŠú^ÅÚáŌá'H™ļ°ĨSpĢ_OŨ†(?‡aojˆjÃdäe‰ķMlũōĒÛÄ*3đßŪ•ÂeyaDæÆė6ųšæ#Ō;CPÔdŖŋ܏{šbįæ _Įú›h<°&˜‚ŨGđ^zžØė‹(ß<Åm°US†‘×[*iīAr{Ī=ƒQå–ŗĮū5{ĸ]‘fuĄänÄDɔŋÛ$uīeđy×Tt™HlĨúār¤OPÉ~‘û㠉š’ųļõ ēīũfP:ĘÍ`ąŽą$掍¤öYc >› NYKîeŅgVĄOˆ$ĸÁT”ßlšÕõ)–› š0 ;\Wv gĸŒ­“H_€aĄŅwßâķ:›3'l'´EW~WE2žëÖĄķ &{—Yũš(+Æ č>īQ˙nˆGŲÄøEi/ØÛ¤tËųxžMÁâÛ?Ôŋęq§Čë~× 8SŒOr §ŗto 'K•˜~^Œîw}lƒÆĸYŸ'¸ÉŋĪŗ)X‚WāKüSΐøĒ ûWøo™ÅĮņÛSƒnīâû. Lũ•;ũj(’߯ë˛)6õö’™tHė|5ҧ&ŖonOęķÜŦ=7Ÿ|RĢâņ&#ĮœĮ§{IO4“čÚūgā<ŽélÕíŗ ›Ž6pđ.‰Ú éčsœĩßRĩšŲ¯Ķ)ŊČÛŠ<Į6$AäŖWÍd*†O–ėŪ`0Éu–AėY…A×÷g%‡ŊH;˛‹XĢpôûũPZA@ø>RõKŧĶ˛įũ…ß5Dž/ßRÔ哈rüRsį~bnv}C{ÔÎõp ˇĮuž ęÎVD×/š˜HÕŨ6č<įcj6ˇĄ'ņ|5 -wV'Ą^Xˆ‡ĸ>.ũ]0Ķ;ã7ļƒp 7:ūÂŗvÚ~j2ט nƒËäE¨ĻāĢęˆoîs"ĶZãf<û†íHĒŋ“kËĶ H~‡"°”üąŽDŸŦ~'ÖŗĻS’úī [pūĩĮü䛯bĄū@lˇU$wŲ>ĪKÁŪ–vŖëP‡W/WŲŽ=‰'ŗąû|ĨAo¤Ŗ÷ÛGdŊTÔûIɛwü°l" m|ËāęËû¯ūģbĐŋĐ`J…™dŗÆCŌ°ŧ’GMj¸W÷9šEjR=’ŅüģCĻGŌ]ĸÉ40įyJ˜dáõ’’‚]’{÷ŽK‚‡ŋ“tV^&įžÆ_:PāÍžũõ„žÄi_*š,ę%J ęŪ+‘U=āæ0b{ŪĄ"į>I-e„DŋÃÉŋžNJĖJ˙’^4EÅ:ĸŌöyĒO‚ŖO*𞚘HE)3ōˆąąĀËڜĐN‘Ä×o‚ã1?bÕŋąéĸ'mm'ėDJ+o0 ?Qš!ũÔuuĒ/Ö¤<ņĀŖŸ=i—?a”X-b9Á¯ëød2™{`Ūj5î‰Ņ˜N "*r >É÷J™ŨvŌĩũ ™ŧā­Œ6tÂ:b&Æû Iė= ŋwÄ<ÜÄģŨi‚×ūâūĶēü{,öŠö'”I1o"ŧųõLņ:Ũ(ëņ^ŌpWS~Ŋž'Y7aģä×ĸ=ũŪH~]Brū‰ģ¤ƒtļ¤Åč<ÜģUÜWĖßŨÂcČ ōƒPŸ¸BzĢ)„%ôäËĻ*I÷!’‰ĒV’žšķmØģĐo${ė$ĸõVÁ}GÂē_Á˙™žÃ/R˛XôY%îŖ2ŋž)œé˙‹’÷ČØXƒ‹U8zErŨv'Až¤.ĩH›v…™?Ī=ū(îŖÁ-žã-ĮâÆL¤ųÉ<‘ÉÃÁč“' ›1 Į3¯P/Ī'g|ūÉ-ņû¸šāÎ}I—‘iQA”sG+˙ŗá‰ĮŠ7¸ųßCŨ]Jä Úw °/;Ǝŧ߯EũÁÜŋŧžŋ ŦĶGÁō~‹ņ>úųy-ëEFZ]”ˇ\xŊĮŽûįKÚ>{'9P÷•dmÍGɄĢŊ$ĩŽw'Ûõ ™­Û~đ yûE^|tDáŲšqĄwV“ŧĮu é ÷SŲuOĪ>āUæ;ū>('xTÂjŸ#Ā­ļnāļû"Ąëú’˛,ˆˆ1ķ‘jÄ?¯ōņkāņĄU¸ˆķ–.ē.MÄėėäŊĪ~Ō?˙&Áį é_Ž•áÉ}ËxŪØq¯āĮÃJĸ…C¨’: Ø&§līL-?âœđ’ ķÃHr|GZÃaxŊ;I˜˙|´§NĄûø؁ŲxēõGūæ!!Õ* Gô뒁™Ú‡„zbnī-@-Xæz;lG¸aZž’€eĮˆœp†´ų'13õGąģ>ǞFțL'~ÔZcđ ĖæÖ/_b7Cˇ"ۆĐ%ų€Ž¤ÔŅā[ū‡^„tzMˆļ˙°0´k^‘ē gĮh뗠Z8ĨŨ‰ŽŪ„ũė^$žđFĩ7éü’¯‘ܰ†HįÖÂ!ß}ļ6LJ‚_ēÅ{ŽkÍq6Ãîø0ÂîÜĮ#é-ŪK ˙ú˜_?žô­"§äŸœ~K‹{*zŗŒ71ĪšŋqúO ?%%ũå(‚ĨKqđ.FZõ]ėáGęŸ@׊VgÖņėvžˇ÷P=ĸ;:ÃQøÎ˛#)û%‹D?Ŧ#āÃuROeÔ¸‡í§ˆíl„ĸ¸ŊLŽ"ä0ūž˙”‹žŗįĻsąĩڊS™Ú˛CwøKpŌObFépļŠWúJÂõ˙pÍé‡yŅW܃§bģ¨ ÎŠQœp(ž^üęÄÃy6Q ģáuö6z[4ÐŒåΨZ„¤ė'\:¯Ö¨Ž\¤dĐ0 Mj0~.'╏ßņznŪpÂ{đúw‰5įM„3ļÅæLūŋë ôŲEŪöōZīeiõ|*›ūÂŌ|9;wįĒî8Wã‘G7B]kŧÕ ÷˛“X/ICŗg?AĒ+xT˛į‘kpy;>Û=Ȋ?EÉ'’Ë)ģž‚Ī™}$Üi„v¸šđÆ"Wė¸ęö˙ũ>(ߎ ÄošČáVäŪ‹lâĸnzá‘5˙凸1Ս”˜¯Ø\ŠEņb éŌÎTKß p˙ƒzŪ21Įˆš| Ë„öiŽŽT‡_Ô`RŽĩĻčo!Ew^ã°v‚ā bš ¯JŧAŒyŠkE&´ÄĢRÜE]#ėŦį?u0ō6âuĢČČ*ĮjĄpŒ­NÄÅË Ë¯ÁNžD‘aC¤ˇaŸ¸š{pr,ÄŅ͈⍠^ÍĮŅŲįē]ŠwŸÅÂ{ƒ <ģ¯6Š8/&Áž5qĪļ“°ž1Îēár!՝&<RÅĸ@r2bYi€÷˜Ž(úŊĀ÷?ņ,Ļâĸۀy‹`ĖZ\ =^°ģwSâæ=Gĩė6—)ÉüũJŌ5û”äü¸B´ņģY>œčTsÂŖö“ҰĪĮņˇģEäô8LnūÃeH{ĸrqß‡ßcO”ʆĸ3¯–%!Oé†SÁ]|NØĄģ~ •2oŋ>x.oKĀÂ8ũ´$ŲĶÕįsÄLōĀįČ(Bž&wЌYlņzn7_†įúRä­Ū“áŋ ĪēŪØ¯~Wã Ī!ãöZäq9÷O}ÄNÔPēô2!§Ąžā÷Ãũņ™Ņ–đ€XnŪ*#DÖßŲļäMęD`åAÜ۝#ŲŠ6įŽ$%V8ĖĮ\L§Ųãųū ŌÖsđYԇļĩ :UƒzÎVôSzĶX‰c@2f\Hpæ‘:ƒkÜ07?†|‡Q][ā‘cL@ĩÎ1[ũũ€[B!ŌØŲHĶhģŒ$)ū caĩū ÛÛĘxĢā^ ö‡˙ZBäBĸ'NĮË<šęĨŗÄYŦŠu sÉmÜ/ŲQëōŒ+ĕ¯ĮåĘ^ĖķĻäq‚Ėq÷a‚iĸü°ũ0åēĨøŋڋÅŪŽ¤øŽÁûDŦû×q¸5™”…7ÄmÃeĪu´ æ öRa™$8ä×i\/-Äį’7Š œˆ]ˇëÖRüOÂOí‚ĶĐåv?Å\’O`? ˆ\Ũrī{›Ķ×8|և`‘Dā’WhõŪŦŋíJĀÅ"4û§“Ûĩ>A+ |.¸ģ-š˙ô¸ŽčJD¸EņC HlBĖģ˜$?Cg|ĶģûęIÉX7\qĶiĀŋË&üÛhŧ‚‹ņž×gá5Y-IąpÆéZ8ūŲ ÖmÃxF:ņ{Ú!Û*˜Ž÷‘ŲŖĐ ĪÂéwĒ V#ģaâîŋņh÷6!Ī},! ŅĪĪ#ŦNs”ĨɏըÔ钖ŲŲDœšO;ô}ŗˆsÚFĨ3‰ĶČZ8ķzM$Ä| Õč.ô%ŗz<˛×kđ¸€Vr]°Ā@r7×Áš™L’X}YŌë4ŋÂĩ”îh÷Õö‰'{ĢÖ“īéčŖ(‡ŽCx?Ɉ Ė3h' ŲåböߒS5=]Ď]æqÅ9Ât#xd]BėՕ$¨ÎķpĘe¸uūGXf1^N¸Í6ĀkĶXÚė"ZםČC¯]ˆ=ĸ"MpˆØHĖf#Ōk ˛IWˆŊŲˇ÷Ä”c3ā5RÃO8^šˆîÎ*—‰Žčļ ×CĨ8L8HHŠčƒ’Ú¸vī‹EüGœËÕ8_3%îøwŋ%LēĢ<ҝ7lÉú{ŸÂâáņŖđ+‰ŸATūáđcNˇ‚pļ C9ņ4ú/cqō–ĐqČ*ǐļu#­īO G^ aČ24ĢT¤~žŽf_ åwBq¸Œąjp œÆžû‡¤­EĻ\"Áá'Î{ ŋë…æwf›‘Đ)‹ŒgÆˇŨ$[Úí&˙Lôņƒpũ@Ąčĸ´ølî>Õ MzBTĖ”;ÚbûâÖWŽ™ŧųŪvä2Ļæ~ ×Ŗŧj9ķĶ1ÖôCļŊ6ÎžŠ¨o—Œ^Š]ŗdôˇŠ =’LÆ'&ĸ5ž‰‰ėū7ö‘î0ۊņäz"tÜ6Â/9`wąVí4$Š­û’÷%RŧĒ59įßcģp2NĢŅį1Q>īȜ,\ ŲOô ÂQŒÎA1këq:.Åąj.îēžøvi‰{tŽáOPūŗ'iän&m°EČA˛åFÄO;HhøzĖOØākē[g`šrœ˛ĻˇHš?§¤aØEL&ŲV8‹`u¯Íø…9“‡¤įesŽYâ­Q‰đBī˙Į-#ņjéLÁéI¤ˆÄ゠ķÜ*"v^AŨv%;zqZܙ——‚„ū(ęˆ[2RŗņŠ•7í'>ߝŋØĨŦÂ?Ė$jBâG >‚;ĶWr+†üũ†xnŪEÉühÔIAŋXÅę[C¸gZ€ÔIĪWb× :ĸ|ŗ”ŅÛēĨ^dĮ›[§Ša=ąÛr”pˇ1¤~}Ųū.üI<īˍûmĐųüá\u[âG]sW‹Ã¸Û´G]~„kgĖč†ëöPŠŧâ/8Îkø2â3Ļ2Ü ÷äôJ4ƒūï—Ō\)ĄW„¯;lĀ7ŊVŋŋ ;˙’g?â20ŗƒ-Qüˇœ8O Ž…}p-pÅSąķÉą¸ēw&ÚÉĮSO‰Ų,öržCā°ĮŸđ~ŽDõÉÅķîIˇŠ[ Z-;-iųĩŽ>Yn“‰“MÅ/ŖŽČĶ!ÂŨ˙÷ßŨ¤DĖXC褆dĒüļđ(w<—ŨâŌė0üÍOāg÷øąRl—Šņ˜Õ˜,ëˇÄDÆā˛é+Á _ā´h FŨɲ8*>ŸAúÄŨŪ[ōâ×Mä#‹~Žé>ņQ1]¤+ŠcO`ŧģŌvįI™ŨKxē1ŸLŖņŊŪŗ¸_^GËT’Æ­Á÷ķ\b—Ė$ŪĮ_día"—ˆ|ŲõŨūņ„5ÛDȧúėl"Ģ÷lܛ<$ŧŊāŋö•(ÆÆ°ō įm+‘EXîëkĖŽKÎd-Î#ŨvˆØ3ŋŅå8â)Y'<Í §Ûâ^Åž*ÚõAŊ_GÄæ|´ŊQ/x‹ßô‚§*Ņ|ũʑc˙sÅXuŊ‹ęí=|Ėū#â~)V˜ûū$îA6WĨQ E‰í<Éåi‰˙z7ƒđ¨9FJ`Áepž0ƒÔfķqˆ&Ųú*˛¸ĩHNĄ9(rņô2lk¸}…îm°X[Hėɑ˙P’n:Ģđ9¤6‰ÂzÚvÔ[†Đ&×Î 5S›ôʤ_ÉbQÛBU¤$aCc…û[™,ÆFڙĀO¸Æ^Ã}’ž‡Ėū*žmīB"}˙ÃûZ?ÔÅŪ¸ŪÂõTî–›KÄĩæĸCžp7÷ĨSÄį8,߅õĸ4ŠĮL'Éå>ø Ī Ķ Fą­é=?2!‰gÍí0Ŋøƒ}âšmēĀsņ’@Ų“RˇmF˙á"Á+ņ@øÂ­›în…§ëy’î$´ē—û"Ÿūäá ēÂã„î+ÆÚÂã×~ø-Xķ}k|vM#f¤„ĢŸâ=ą[Zķ ÷•éøŧš‰2âAwū"}SHâšÎ„Š.ĸZ4‹ÛfbeĒ'rė[d˙Æ4č:Î¤Ė•rûĩ=×WÜÆuCmnÎ*Ā~˜ČÍcŖ‘Kpí[äJëīöAWéIų‚R v¤8ĀO jēĐHėõyœÚņÆĄˆÂģĨTúÔ!üãY‘ŗ‰d—(ŋÂ9UpĒCm4eŊŅnדū OĶgxî .ßÛŌĨ¨{ģOŽķ‡ÛȎĮã¯ė„ˇü Ųå H|ßäy$÷Í ¯^0A‡Üyļü(Úp\Gī^(:´?öĪüy~õ’pŨ‡¤m7О˛&¸zūŗ žŋ§šåX—=ÆŨׄüQË°Ņ—Ržë>áĩą­EÖ҃ü‚LTÅ3PüļÁYīOôėK5¯ÄŅđ.ÉŪÂ×$D\6!@#ôEü×'Áz^IeDZYĸŽ>Č­ŧ|¤?ˇPxdîi‚­Uhļ7&ÄšĒ6čæ!ŊäĪz] ¯§=Ģ˙á—wÔÛUč‡ú“Ŧ_HÔĘŨ¸Î]DrOs’fdŖk,¸ŋõl‹ûĸ]WFHXSŒ:5Auxqķ×÷JNfØŗÕņo3õ‰¸øBĘáÍĩ›qīū ĸ#ĢpKŧOā_âļ—`6@ėØ6/”ųxzw§NbgĮ_MČíâ߇Õ8ˆčCŊ°oÜ;§0B^æa÷æ3žīâĒ÷"Úc)‰‹Čđ)ÄæŦ ĘŪ%„˙یŠ0,KÖ–ßī˜'<ú´ ›™ŨÍĮz\ Š•KŅ{NÄķVdŦMĒiKŽ~[GčúJîŽhGd‡ RūϐŠ˙ņzÄöšOÖâ§âƒUĀfÜĖ ¸=6 Õ°b÷ũÅÍäĻUJ"W >ZÕ¯Ŗ!øšÕ`ŗ};ķ“ HX(Î]FÆÍtōnęEîÖ&­ÎbĖœCˇ/’gĢ%v^”¤M— yŅBŌqŒ/ŌAQ|PÆ÷["ũˇBüú”ÕķĐoxNlû({Ü%cäeî7 îį<_Įj~8á+]EˆũiLĖŗ&Ü nM¸Čqm§ĩø•^ÍÚŠŌÆ# ܜn“ä~žŦÁíšģõÁ3ūRZŧ—ŲØtG›ŅаaéxīmOđˆŋxĪöAæ¯čÜķ¤…âŊČ oŲ\Bcbû3šåh|ŒÃēĨoÜîcŪô ęe†â 8t˜…G­NŽÅõQ5Rƒ‡ĮÎÅęŋtŪUŽCcuž¨Žkp]ŋ“¨o;°t§˜AxŦžGæ ļĻ 1;Khŋ ÂßPxĨ„ IōG#°Jū˙Wūâwņq#ŪãaōŌõõņopÆ­WGÂwU°p0f­Ü0Ķ'0ė#! WXÚĸXļ÷1›y\öų‰‹yâ{Iå$ÉĒ éT5œXO°Áŗ‡]IÄbĶMâū‹!âÍrŧYčī×!ŋ^)ŖÂƒ!yÖXRœ!Š1^=Ių*˛ģë&‚–Ž<`Œļj?•]ņû´c Ū­ÅyGė&YÛīâg8ėۄ|n ą˙f";ÕĮš5„Ũ˜NáŸy8XÍÃįĨ/E'ˆ|õüߟĮ&F?—ēũpÕ9öá ĘŲÜ{õ“ ĸ;6“uBøZ^4SĮŖxaJNäËĐDÖNÁŋõbΈLüšOÕÔDÔˇz Øá€õ”^˙õ"ė°x~ž1”ÖwÆđcwlŽyØ}ššņõ.~j@Ô^Ņ!gâ°v!~LÉŒ`Ķâ=>}Wg<ųũc PũAc-Îtâ(i‘OQØ‰ŽŅ=”ōĪļXNæR=õÚŌnú#(*‰ģŗEŌyû~ÉÁ¨…’“#ŽHęęä$ ¯$´R°ũĶS(ūÎëŒãM?"”[ø&“ÜtCŌY0wõmáœ%OQZ´{ž ‡"‚BÅ Žh€ou3ü˙ę(=ЧZ!¨äĸË#Txnü@@PŦ„{īTríą%“‰?øˇÆn¸×ģˆÅôG<ØXƒģUĸöĮUģ)}T¸P!¯\uc'Üzŧ!æ_m’å+ČÛ9—ąŅFqcîk<75'Ü"—Ā 7üv\Å÷ëN‘3ëˆúסÜDÂΌ&š V“Žâ¸Ž>Ÿ“č+v“æ`ŽzöLžøUQēščИ ÖŌQŠGˆĪ ĸųsĪW‡™ŸšØÉoąM]LܰMXžN!ēŌHŧV-<ʲpŪÉ õNÁÁM‘¯ ´åjᇰrQSx ū™3)Ø~‡p§+¸<Ę$zŦ™Ŗ×ņŽÎhI§ŊŸ$ î´āõ‘D~.%oâô#"ˆŽ%æĐEÅ;bZMŖ īKIÜ=ŊA“˜HÂN+DG_Á˙˜#øcĩē’ŧWŸDöß úk ~ây B¯ŠOĒI9A=5¨3§-x-˙ĐdR’ˆl9 ㆂĨ […ų­î„LėAĖĀbb\l°ZҚˆĮ:|/¯]Ų×+ĩHœíŨրŠ7?H­īBNņ^<ŋŽÆßdž°É5‚ۊÜđAûæ/^ō—”ŨoNÉW‡ŽĮ{â$~oŒī#w,ĨyČÆ­&x° ëŪ”÷‰”đXÚū@U%øöEBī}Äjg#žŨČÄ!zÎ˙}Fyę0ęíßPŽXƒŋ|%1 í| e¯ņ$N^JÜNlûŨÂōH&eÕ#lMøäh=[ ƘMȞ„ö?„lÅÁG ˆhS@aĘ@îåã㚏uŨŠÄt¯Ąčj8Ų‘øFŪDŋāŖ¸G3âÅ3ķ[‚l3V'öŠ^˛Ãë˜>Ÿâņq9LN‹ŗxOšM΃Θų|"õÜg‚ķúūū7¯ĮÉTđŠҤu Ü/ÎeŽ_\"z"uīl4ķîRh1ičzėÜŊE¤_†ËŅËØ~îÉĄ!ĄDyũã°ŨB_&ßT‰üš!ōcc¸›,úû}&6ŽkŲ›Œ8CÜ_G5Ö ÷q3ũ2ŒāëåhnU—4õŽ"íÂđ:o~Ë$"įĩl%eî̈ôœDÆ,gŦŋ1ô™i‘hë-Fß- ÷Q8­v&ŋ¨w_Ä`­Ž&¤û ŧ‚ŸKˆš+8ûi9&‡–ŖžŅƒ„×ūĸĪō‰ųû§:züūkˆŗä ™í'ĸ)V’]8EƒĨ8‡‘û¤;ž5HkmÆuābģcûî–đē7÷sëiM"  {ąÅË8ÛGIJũ„?>CØH%ÉŽ2ä]cņē”FÔŊ8t#›’ĐŌ mŽ'ŠĄCņM{…÷1[}'^s Īá7Pöėy{<‚ßĸ|#¸qw>oīĸ”^&r‘=_ļ)īˆų~”ŧEāķĢø\Y‰‡b˛hņüᓜCčœ/(ļūÃjûQ˧Ģđ}ņ€uqÄ<š†Ōö ö•Ŗë|NøįPŸT_Öĸlēųá8"UŲÄôëˆTYŽË?;Üĸn#ą•„Ô×čĻwFÚ¯ņēũ˜ôŨ68IÎĸš†›—Te%ũøL|ˇtÄ˙ÛqœmˆqÔälGy€đĶCŌĮâÔ%RÜOm´KlP¸‚´DÜQИ1:ãúæ^ęã<9åžá<„sī$b›ėÁ¯G w^÷žūäũŋHšjÆqÍ*ÂŦBj'zÜ˙ ROoânÚSrz,šÉky1ļ^YÂ÷§žŖĖĻ%æÍ&ļ ‡īûĐHFŖō™Jdö7‡˜+Å|wģķĒ é-või<;>õ&Đ*U?SĸŠSče@fēļŊqZMDŋnčU-Î¨F×w!ąęqŨEzÁĘ^Â-(ĸ YŨpũƒlø2d“ún8 Ŋ\¸_ ĢÃAÜq˙‰ĪßdKCˆĪŠā†ŨZn=œO‘bvސ%ĩĮŅūģ8o"ö[>QŲCÃ6Á“œ$xHo< šāĶšÛ_á˜ĐĨ‹^ôâ ü֜#hm !†uđLJ%¨ēŽŖ °ß”Onŗ+$™ĩãū×Įøß]ÉCë7Ø÷xˆA }:ãŊDđöžxŨ\†´×0åqÆe^q)ĘļEkx…üČ(B;&ĄTl'jC%R§Ëų^C§ 8°1īĖšųL¸Eˇc$66"ĘĖß#pۓ/rJFņx+\_T‰,ģBÚâ…X‰ž+Đ]vÂ9ūRsÔŋ“ô#‹ßņÉ|~¯pƒ—ËЎZŠnîėæũ"ąžéäîŖķX‹zŨІOEm×÷­ņ*nō7žĩ"*āĄĨN7ßDžK W™áŸŋ˙ÜFqųU\ĻGė6 ĮDoûŲŅ8Ō:¨Ū!zų^BŽBūá—ØņĶDũ¨'œŠįK" Z~¤hRNe“ Ģ<€ˇĻŌâTė6ô%¸ūqd×[ĸUL§Ü䇿âö|ņs@:úŲJôe;ČŗíŲéÖ9cq6ŸOhˆ 7>ÆáÛc6v‹5ųLԔWČ3Ī’ŌŦ+÷‡Äēgáøš?†H‰ÎũGhÛ\|:š‘ļ­áŽsn2į0ÆŅm/ŨÔ¤~ŲIHkkS†s§•đŊ(ŅÍ[ëā+,ō-žC(˛CPi/ŧl› îüFæÁķDÖJ¸íbâķįcŅā~‡Û MŧL•Ťe ¸wŪ‡`Ŗaø‡tD龕Ûēķøœ)é­Č_]#čxļõÖãũ~˛EqkkIV— â5ë‘ĐÁ‚ûėđ~sˇËq1ī…›Û’öœĮįŸ”Upč7û€ĄhCžâķ°/ y$Ö]]ČÛ3k×wø_iúF(_ßā1ȅĢ qŨJŽ÷¯?Ģ ^ø4$ÔF|+ë“=°.–ë͉ܖFŌ2ácŊ[0úqOrã\0.o×Ŗn¨C~ņ^Ŋ?#ũŗŽ„Ī÷0i}œkĢĖ‘uÛHR›øoEiA{BĮ†’tũ;y“\1Iۃõåõ<Ēęį%W\R?q{øz,7ÆpKÅbB$ÆÕXPüÜĪŨ ÜžįņûOä{-'Öžēũ˜ĩíJöë)wYšb]d„ØĪ 7ÅãĀacĻR2ÍEQSô63H/Fč#ÜžA7y&ōQÂÛÚß $ũ4ڐM‰nĀ\Î]"ˇņ)Rk= ŽŪbƒ÷ėߘĐ?W æFøúļ„˙ƒęģ ‰M— ĩLėŌËHWM"4q:[Bw>Åįj é1g‘wŪÁÕĘ-Ø=C~ĪŲD‚æÆyŠšævt Ō+b÷ËĻ‘rŋ‚Ũ˙í$,|ÂÖÕŦ‚„OO QÆŖŊڗ°´.ŪũÕLdqË9d Ī­*Êv:˛‘ÃPÚ‹ß;‰Ų9Xvģu¨š;c¸“˛—{î_qÛւ[#ŋuÄīzÂ2 ÷S[DÆĪDąđž˜—Uĸ›ĻālÚŸs1<øŧ—”&mqŧMėÁ_Bæ’tc&E;„˙Ú7ÎŌ§ŽÂĨiPnrDVŋž9ũˆūOæÕŨØxÍÅŠr&ĘߏyTw.1…OĪŧ‹ē‘đøÎÄŪė…÷˛cTŋ~MņĻÖŗ …_šOQācĻBÛ{ū§æ“´Íįõ‚Ī’F"ՂŦGdnå¸&L'JđC|ōub77C^p‘Ä1ŗņ{ŧ‚ŧÍ\Hģ„ŸŽįaâ÷i,rŋĶ^ųJšS ãĩܛ{]â;NŠu<*Āg}ĨČÂĪÄîÅnnÁxYčzēŊĻO.`ņn0ū7bwû?R&ā=4˜0ĪÕøÍ÷&rJ"Y_Ú#+Œĸâ~Cĸ÷OâūúT˛ƒŊĐ?jūÉâH)û˙#Ē´!WággDöUOTģ/ œ= “‹ pÛhËų7áeĒnāx0‡"˙Č,âĐ'UĖáS’LS‘%ž ˛<§Ķ¤ZMF{FKĻ"NüúÕ$ΉG-9žz_ąc­( 4Åî…Č™uÃȤ?^ãcžč†ŧ×|<ĪŽøéŅDnN^iģ]XŸxG„Ŋö÷;LĨ)6“ ^„īÆ4Bšú°ä!öw.skÎP2+Ŋ)<´ã¨ÖÄO%îļmŦ‰žøĪ…ņŽ{Žûá…_ÛáŪÛ]°õuŌ'Ū2—Œ%čڃÔnŊÕyŋCUŪķžWąp×§Čúuo‡ƒ(sŒq)ߊúW5>/ÅšVí#Nˆß›ØچmZ-˛2‰xĨ@Qg˛č՞܎>|ßŧnPŋņÚáøÄī$÷ząÅuHœ›Œ§l"ú™ķ Ië†åØ`ŧúŠŽˆíNôÆČLƒIMqGŪ˛9ÖÚ ‚ĢTØ*^ Üyš"ŖlÁøs{.ŽĩiļE'ō$ū„īMü î›5͏ĸĀš q]BqkđŖĶ'qúlFuP´öÉkz“‚ęyxň>ũo9V‰ČfMD6$ŋq3 ÜīƒQã…XArŽųS%ŪO6}h8Ų~!_Eôž/¸vpÁÍęŒpK#Ô#]p÷;ŽĻîgtnA‚{jđČߎGš”ĀķihæWâY-Ø˛° ™ ŸrĢw ÁīéŸt\†GdoTũaķĒÚ•ß íDä†íØ4#đõ<įĘë*đ–`|ų&U)›Ņu?Öööökq|°õĻAx{gpģŸž¨Ė¨L%iūVÜƒĖ„ˇčņČÜJŌÂ?8JQ¸bȐâŠ-„uŪ†e—bėfoÁrEgœ~Äyu?äFũDOw@ßjúz¸5šJHÔtŠ~ōŖŋÎ„¯1@Uh‹Sž†ÂqøĻg’++Âį§ČÁíx~œ:d='~Cw‚įšā—ĻÃĘŗ5'QÔ2Įųo%šßöŧ]ļ†DŨK.ūÕ2‡Į9¸ u'Đ;ˆÂŋņėۊáGđ6j"~ž7^ƒ<ĸ)Îų¸ĪēŒoÎkŌ<ېĢĮ¸íaBė 8Qō„ÔÎŋņ5߃åJ{Ė7ps’n›Ę¯æöFá€Ö$\ĘkĮæ_Ģp,0ÃūŪ9BbE掰B^î‡Üøß§u ŸÃšĩķ N™j⡡Į,?÷íI đ@Û¤šā%ö(‹MqÖŦ%Æq0>-Nál`NÜĮčSŽˆ<ĀŽˆˇhœ“šÜɂ› p1҉ø–“Hđ’S´dîWŨ ŲŊ§mĢIújN@ę/t˙sč ūÄkVPčs˜ä¸gDúØĸŧ2•ŧÄÄÆ/$Ž… ˙Ē(ŧ_´âĻķâÉđ;ˇŽđ/Ņ%˙#3/ƒ˜=ãH5oDrŧœčVwq™Č-3CōäžŧŽķˆ2íü–•";ã-ŧQôPŖĆåaōĄ‚įm >šZRĢå2bŽ쌏9?ąœŪ ‹”/¤z4Äü|ˇúúGdæÅ!œ˜X˙ũ8Į×r(ĄŊŪ“t6‡@§†ØZ– ),&TũJpÍq¤ŅŸ‰ļŒį‹ieÄpķ\w;…õ:ˆÄ ?)ŧ íßå$×ÚÁũi%¸/,BwņĨgΠŋ°ۙzä Â}Oëņ)ڋīÂÃxęG m ž´ø6“qēÕŨáÄښāëŪŽ¤˛ČBû X{ŗÕK‰›ĐgW;ÂÍļ¸ČЇĻķY۞ō˛.„)ŦqŠ$ļāÚdkܨ¨‹E᝸Í_ׅ^õ‡×Ã[ÄI+‰;ŦÁøÆ4Á Đ7=Jfí$_hGÜ|Á돑ŨûĢČ(CtŊëā>zŅã=ˆ oObĮ6ø:$uæu¤wq?%­= o!ĩŨtljõ"xÃôą†D$–ãŅo5†ëŸ‘6UøKn%vEčŨīķŠ›Čcˆ:9Õ­p"+oāĒ Déú¸-ßø°‰€Á˜–%ĄūPFÅ•ÃøwŠ&lædō=„xuEmŋûØēČ?Ũ%//”ŧĪŽšt#Ed&|šŠŊņģeC˞xÁ]ŖIzŋÄÁÚ €‚#ŸHĩ{€Ú]Npæb‘kxíŲŽƒ­ĻĒÉČX‹š}6ūå“éŊrô4xt÷Ö;Ĩ֖°ÆčÜí))Ū‡e›dÖ_Aŧ*–ė“&Hßĩå~ŗŊDŽ[F˛Ŋs˙áŪĸ;ĶˆžPŸsۏã1â5ēčU‚÷̰ų´U°gĸ‡V‘˛î4í´”<ũĮ̚͟…õĸŋämœLĒam2|pۘäĮžØmŲ \1˜Œ—ãņĢ?Ÿ æčVnE6f>S͉80ÜCģqļu&lÎ Ü5ĪpˇŽSšēk=ņ Œúô;^u›āŌų™Č¤Ž¤(Ф$ÁĀ™(ĢK„$6x~J‰ \EZzWĸĢwĄ{¯MAži¯FEaDMė=%YŠÕ‡øÍŸ#Šĸ3‰b>W]Âú¨úģųØģŒÎb#>ˇą“Ø‘×#—:HhÛíûĨX?š…ģ`›ã‰hšĪ%¨Q7nŪŠOÂô›œß#-ņģp”ŸXÅNįxQ)9‘ŠčŒ!0BN åAdG›ro¤I÷kČZv–ûwį>b,A‡ē“<ĻōÁëeŲ„Ō÷fuņ;xŠŸŌö„ĩų‰îøÁĩ9nĘÂ}F%‘JŅ'ƒ÷ū…hmáĨÎéū(ÁĩĢŅ{‡"ũėŠĶäÚDõHÆÕ.–]Yâü~„“ŋ€Úk&˛—§ąÕ6ĖŅՒ<ûПôË0:Ū€ņž$…õqŋ‚§3J°j‚˛ņ4ĸ›G’4k!žgķqĢs’‹(6~ƒZ{ˇžøŦ>ŒËĨy…õÆ+n U‹o%Üį6InÛšOhØ8’îî“t/Ūd0ŋW4wãûcĩĄ’´:{pœå(öԂô…V„–ĪõƒĨ5D6BČĒ5ČߏBér™€II¯#ķ­‡Ķæ%†bâ:bÛÆ×یˆÅé„F^åķé÷D´.&á[’pŖĩ8_YŽŪLKyŊD䭑43—’ūüMÂqĪwWeRĒę„ĮŅĪ8ŊåėĮ’8Ķô>Ų‹Î 6 áP)žƒHYŪ‡ā-ˇEˇįF8Ō ĩ‰nŋˆDŋĨøŸ­DzZ‰˙aAÅhŨŸâūm7aÅļXdīĻxÖ |nô'mšļaÉč=üąxčƒįÔŲȚ7ĀæÃ4ôƒ Ž5ŽĀZ/0==Ֆ[„}pewķíTîøŽĸ`,?ë•úזƸZNCõĪĶŊ.ȏŦ%|á(BS7" o‡cĘ>Ŋ:ĘŖ섇šĸĢqDžõ* }ģķxĸ éĮ†ë§Ä$LAԈ]¨Û='úÂ2ĸÍwōāŲb¯­#ær,ncW[̓đ­wHęšDØËŸh‹yKZAIv=ŅĨĮä◗‚OÄdâ$ž¨6$ācņŽČčö¤é€öÁ7∞‰Ņ öûJŒŽČS)ŋA2ëÎ,‰mÂÉõĩ$Ã'Ė"cč3âĸEwÆ,$úÎ@´īęđV?ß;Ex~]€"},F§â ;Ģ$šA =ņI|ƒ‹}2Ú #…ÛŦ¤dA† „$TįĄõ؛÷Ũû(-‡cfxƒĖ­ ]ģ›— žĸA­§“âbHÅĄ‹(ĶZæ˙˙ƒØøÍĮ™„íĀ-ø˛-] Žz"ø~=Ú]ŗqīĐ ×ļ{Đ.@„ų Ä>y—`Ę_x/ڄmŠčÄU7ˆŲ/ąØ2\×Ī–ü+Ņ$t ĻT˛Iėĸŋ+(^=!nr–`Œ|’;-ÄŽeG4ˇžÚ`*Q˛Ī¸uę†&bŽQ÷yŗč›ņģžë’Lr,E™ũŲÛzøŋOô™ā‰>”ú5BŅũ1ļ‹"ΰĪũ> Øŗ§9ĪđœųšË›ąņųCyˇ’Ņõc%?ûū6Ø]gœDļĶ[˛īs?úAĸ‹ ×e˙÷^qąRwâÖš]ķ[­Wĸė Æūu'n^‡ēļ†]ŨØŽ]MiÅj<÷&.7€Č‘=p øÍuŗŪHŋųáÕ՚‹aÅdXâ)Ã(}%Aî ˇĶ'*öͧN<ąiÅĸ'ÎâíøĪôĪøz ?9lNÕžŸx§–rcîE ZõAW/˜ĐÉM žøŧØÎØÎîKˆčīs°kc%ã+niūøéŽ‘°ā*Ą=ˆĪ>H\Ę>WØ s˛ĮjQøb,:ËÁ$=ÚFÚ¸4b_nF=ÂT¸úiRĻX _}ë ׹ę…¯đŖđObÎjYŖžeLxŨ÷ØīDVī~DUŒÆiXG|ŸāķĖ‚ō \FôG/ŊŪėžĒ$÷įÂiMOãŲ”[û.āzx:Î^et1^ƒ.‘s!÷N_(ZbBĀS=ęūĪČč+\¤Y_2¯Āw^3ōĻî Į‰û÷ĪR´3—¨÷ĸÛG{’'˜ õ Ân~#T5šģktį´ØņÜLXLę„îŠėļ˙´› [PŪ˙ŠÉ]?lŽ,$VvtŋØM,'įüQƊÂIō—Ôo‚sK7’Vp…¤P w#ŋÁ)d>H‘EšqÚÝđų‡įŊ–Dåô&­t)ĒĖr4O|‰Ū÷ĖygXŌ@ė9!ËãâĶ‹Č(ąk“ውÄfũäu;ŖŲē…$ë,Á,yXĮ ŋŽŽCčõĩ„öÅšô6­ĸ)åįôht‹‘nk…~ŧpʸĢ|ČŌ‰Ô†&8•Ķ“ß(à ũŽíņƄNûKáØŅ<Î"{§&ËUbGbķŖ+3‘{úbŋâ.‚ģÜ6?ĻāDĸÅ3I:†ÄFn‚׏yá#•:áŲļ3ē…‰pƒpá!ICI˙žäÂõIš2s9î¸ÖÂūķqĸEŽĒ‹íqŗŠŠ]CJŗĒ,Į,˙oÛ(ŊŸ”3ÉĐfāÛũ‘eÍqČu&kųrŒDhjDđ6?˛DāR(šo?“¤ĸhÜDœíPZŒáEÁ(œÂrą~Ą0ņ"á.Ō÷9˛ÖŗH9ÛģMˆđ‚m‡Ũ$4Ę$fū˙Ū#7Õˇû8?ĢĄâxG”-f‹9Ÿ@Rîun­øÎƒ×=qß>ŽĘ+ƒHŨûüočûôãĻ­’´…NDŽ:ɍŧ]x¨˙"oy ũU/üEö°ž6aØJËQŨ9FøąK!{2”mcJ'^Fīƒ>|áŨĪ` Šč뛸ī.āúëëØ™ ،ˆķđxú¸ŪŊI´CFķLķ_S 8Bt›’oÆbÜB,ĢšwfÅ5†hk‘gHøŒS¤Ū‹ŗÉjRz ,p”¨ÔŲD5•W!žiNĨķŽĸ¯L"Áũ"Ą‡ˆ~\@ĐÅ~$ôÜÆũˆî×|ŖĐ 3ž=âđԌT‘Ũ9›°w=ļęÜ3mJāÔL3û.>Cęŗ‹Č­ûô /Ą­öa­đÂîô%\§iq›ß‘¸g2Ԋ7w§;ū)kIģQgq—žI^XN'tîĸĮuĄ &€­ų8=Ū‡“´ īŊĩ‰Yé†DԌ2đ¨ė†ōP‚Į撴ˇæ†JĖžzŖ ÍB9§ÎŨsív žCėpJ´&í\G’šm%/é"Ū/ûû|-9&áh›îF÷WGņƒøė=N¸á+ úŒæí5.7§á7ÔOķB´ŋ䘧,"Ãä ifrwE"úĻ‹)œęŒ&ՐœhW”īa~ņ:^!¤¤KIûĄ%#Ĩ>r‡܍ėʃŠ[ņ5úBlž ÉŨ¯’yW×ãÜ(kĸŨrÂ<ģũ$PyÛ ‘{=† ˆ÷(oOĮûščÕĖĪÜņ¸FđAœ\Úcęrģhcræ3÷:ކ‘š]Åßõ4+ŋĻ\ÅŨą2‘/G1ą4ĮŪęÉĶōĐ F’øŒVķqyú_Ī…ŋŒ!­V>E=LHÚ>ˆŠečFĪ&ļy!ŠS⡠Ĩ`ŅR (õDs‚ŦŦu’Úí’pz:IäšųšhRę6Duh(IËē ßyƒČ\7áЅ¸ŧŦĀųįnLK;a‘ڐ0Pũî‚įŒæx”î"ėÜ ÖFŲŽ3^ņĢpãGĘy˛b#úŧ/(J˜ØÍøiÂ}šR=é°äڒú$ S.mMĀĀ(JBgcoŒ¯Õ<ÔGOpwŅ1Ō[aˆ~ĸŞŗÄé…r˛…m{ö$›ø§k yߞč 5ØíjĪc2oĪ{s“¨úRĸtįjęRN=]‡ķ_3šu&Yķ“đ“¨˙ÕÃģaüëî°UFįbëūŨ€ų<¨Ķˆ¨r-Až*2/D}g‰ëO ĩ ˇūBrcj¸ī8YÅ[‰tšDæáUH;Đj ō{ŅLÁļZŠrz&Ji5w^¤ ķ~Méˇ0ü?OĮ’Ø›™đl=”Š˙ęoŠwŋ§Čf $ĮĩĮ†eÄøˇ@ۀšņd lZø`æaCŪ/žÅģĻ q›‡<ī öëPîØˆŗąpļ"š=‰éüYt[ēŸ&w™A§žPŧų!ų‡„oˆŪ‹}Ŋ˙ˇÂgÕãqû6`öč:uȚ˛{yž˙7#¯ĸ1ũĮũ>ÆyŲáØ¸ߋ+¨zہ¤ļFD˙xFZrĄK_“\Ī—PO?|5‡0üī: ‚r3ˆˇäŠĄ'~΅D˙œBė…jRoŒâķ›ĸ7ĻPr˙Oy`Ōyn8Qŧ%ũZ6fīļđPô@ė{‘sMĢ ūâNņāŧNö¤Â8Ÿ’x=ßĘdÜŗ]Ī“Zķ%͚ ŧņtר 7ŅĸwžN˜5žGī‘ĒTY”Hä“@ŧc=IԌ$¨ūY¤žÁd×īGœę<ŠÎņęüˆ¤ĖZøŋlDžt?<ßāŊį2Uļ$­ŪEÁîÄ}s¨’ĄßpyņŌŽ7 æQ#œëTŊĶ3ũĐÕŦĮųøbЇ9ŖífI´{<åņ”ß'rŠO†oán×=ŧėU‹ÔÍQ”åå‘ŌķąĄĶÉą˜”ąŊ%7Ÿ]4pZ‡ÂG›ČęFäž%¤´û—â?ô¤ėŊp’‡ĪĐ҇ßc‰4ĘĨ ŧ!ßË^Pŗ]ø îNŽUŊ”Čæg)8ę…ôZ‰× Ų$˛Ž÷TB.Õ^ÚEãž¨ļ™ ÛgÎŨú]¨ą˙ÁŊŊø—JÆz3Šū5åū°¸yūīûĘ×ĸü´ųëãä4N"/ʟʾQŧ,ßJBß’n‹]ųģf›¤ÉĨE’~ÅŅ’ÚÆ—yanĪßĩ5& u­k’z­×sWū—Üĩõy:ö,OŪ*Čs÷ä͆;’Ú}‚(¨WČģ /ū$ŸåcÃÚT%îæcūOî]8ĘĢōˇ|^hLâˆS|=ÚŅ€˙\ fEž˙‹7}ēQ:鎭„gû.éēJî­íCĻ,IÜacrÎdķâháĻũšÛg2ijoÂ+)ļ5äa´ŖÄįcÁ°Ļ–’A—šQ:j"Aî]I īb@Ōû> &[ÍĢX)ūķŪP8LBø„ŠxQāüēqM2IkŪ÷h/âŸ=‘(ęĢ .žË‹’ÉDXˆškŨ?˙7ØFj)ą* ã÷NŌûmDŗė4ž­%]åJÖö‘Ŧø “ėh*Ų2$F˛¨Ų#‰A?ɘ s%­—DK:§7“4ŲĀã‡1| Η4ÉŲ*ąa˛ÁΈa’Ô…%ŨSS$Ŋˇ‘ôĒ“L÷ʔ4×ū”LčžR2¤ø¨¤éJSIĢC$›Ž’´˜ųXŌ¨b̤V“jIƒŨE<ô*ŖēĄđŠÁé<3o.u÷<Œ‰Š?HĘ^Šc瓎:ˆg3žã×wÕ{›Ÿu“äh-Iģ‘uŪ5!’ĸ~ÆÄ´Oáž~×ķęp*…Ŗ>[9–ílHĻEŋâqË į\Á€]ŋI:Õ)ä•Á ģStĐčŠ*ROɨ!ąŪĐFâwī:/‘hDFŦ )'H|cÚCĪŨ+ÄdžĄ˛“P4^ĒÉZrO~&rC_|"o“z"‡4Uô5zÉ(/sÉÎņŪ<¨¨¤xM0ÁŊŅoŗ!˛ei‰‰öî‰tČ]b^íŧ´Š—ųī%u úHÚtL’Ô.ŠĮãKA’zÛōeÕIÃĒÛ<íĖ‹i2ŧ6´"!aÅķūRÕ-ƒŌĩ$­ļ…KZųKˇļ“Ôuˆ”tô~%iušFŌÖžXŌđJ#I×sí$uÚũ'i=4’üĨÉņhGęĒŽ֌!đO9S•ätxC\=Bžõä{ũŲČú×Ļ2v1euŨˆÜ%˜U¸4ˆ aË#´{ŠŅøØÖģœāuņî.okĐ%\#˙ä"â{vGPEI§.øÎ#qÕY˛— æŨÕŠdD>åIg{Ԝ’mš†Xš‚ė¯ĶQ#/ą59~/yũ‰įÕŨx˛*™¤Ixh€OF'ä¯vā¸Å›œ~ƒPņ”ölGfoōŽ#7xŪCÎĄIīHŒá TĻÂ='g–ŒĪg]š=PƒG‚)ļKĒ ?îŒŋÅ2rPiEĖ/‚ûŧ ­ļūKb›§9ËÅœä÷ÆÛ\×“#„æÍ"éā BÎŦ&6m aV hļ ^rŒŽķnBļļCsg Ų̉ŋ|’Ē­ņü˜síŖų$ŗĀŅ+éL\'ŽD5b ō‹}‰ž´§č‚Ÿ‘} ÍĨÁĖføūø@ĖŦ><:PÛŊ"RŊ)LHĀiU,ŽĢjˆŪֆ€˛ŋč‡Ö#'*ši/Œff ‰B}ËīJĸKE&x]AZ/Š´C^ä­-#Ķ<ŸŠõ{šõä q{S¨ü@yí$9!oŋû†ač‚˙ÃŪŪ–[ ­‘f,āSëŸhĒ7˛w!-ŪķHyœ˜‡‰R/!wKsūzxš/q¯đṫvÛ[áRoŅė-Fîōœ ‡Q˜/Š!÷Ī12—ôôę•=y;ī0ŠŨϏ?ŸAh)ŪÎD^Ô%ëÁΉM.E=WÜÍĄČÍüYo‰ķĀ—ėOßFÂŊø1[bãęĄ+tĀ(Pxđ+#B[ļĨؓ{§Åķũß÷8;ķĖĮ ˇäxŊiŒüŒ?Ļņ¸ŦSā×UÆŖyãQO÷ėūCxš#ĘÜßčŖĪĸ1[6î*?QhP€Ėڐ8ƒÃ‚=r‰\Ŋœ˜7ÂÛæãŊ͗ÄÉ9Čöģ ’¯GŅĖyŋWÄ­Ū€Žų`äĖņˇž÷ŋ„í?†Ķ“oDY‰ųYø—˜9;)üx„&øøn%ûY|ÃÉš‡Ũi”æ6Ę{ ‹Ø'öĢ)3÷Ŗl5¯ûÂ)LŊH˜R†į°5âëũÄ;1ņ{DbŸķDdEĶ/›0Ÿķ~öĮkđ$bÎöĸ<4ģ–')ß{ˆđ Ļ<ÚĐEÜë)ō>EĄđđ#ö”Ũ -/÷ƒiÍeŠĪ&hĢÆûˆlŨ‡č_ŖHūk‹ŨÁ…T~'zų|’fëģŠÔĒ”Ö]‰ų&åDle1ķ_)ˇ@đ%'Ōįī åīX%Üē ˇ~d5Úų$hĢ(3ž_Åĸ(lw×ÁvlBlĮķha5 psŽGú$5 1­ūÉ$åÅ1ÜR:“ēp()')ŦŸ„ŗđžōß=É]ÕyŖlÛØāų'†ĖĩWQK~`Z~…Dų0B;í#_“@FÍ#ü˙&-m"rU*ҧ{cÕ2ŠäõPéNˆõp˛ë\Eņũ“Čį΍ۜĐ ŗÃõ(&ßßp˛ą#ôl}Dn^€j‘-Q§a%æTe6‘Č›íP_ŋŠôzSôšŪ¸>¨Ā˙ņ^nš¨H,īŅ֍ĐH"gĘņ^°ëKbî~Ÿ%-âúÕ8¸TđäŲ~t=„Úë‰ljŝą?q~—he3ŧ$M‘ÆyžŽwwĸûÚĄ¯eûIL}C䰍h§Â?Rgød­Ŗ8=a4]Vrod3’f,%ėŧđą;W ;øcã…ØYŨÆ%XEÂw"ō×ãŗĖUŲbėÄwëcĸYdĻåf-ÁúAcTŨģĄāMĖëE”. & ē1š…Đûl"oD9Ē™—)°_IöÆD,ˇ™"sŊ„g×6Øn Įú÷˛ĪßĮKjOâĨdÂ׍!č×|”-qnü‹ĐŽ­ 3re×ēũxŽČGŊq1Ž7ŊHîlʝ‚ ;œÅCãIÛDâ[Ī%áŪ[ü§×ÁÅ9Žŧ‡3Éíų—€Šëq92ƒ1S>ׯ#5]€LŅ?g1˙oļĄĐˆķWĮ­˛vŊ>âäyGY îĀáû 24Ŗ9SßéĨû¨&}%bô5_ž'æq*;_$ęČXũZãvå.žûĪ‹Ž[…˙Pá×[ĢņhžœÛaũ°ū{ Ÿ‘ŅOÎEЕ9¨îŲ ÁųÎčî÷Á§`7ÖJ‘Öm¸=ņ4a.—¸ßz$‰Ožĸųąm­j;ģ‘´m*•Wž6ä9îIņ[ĩ—ƒF7:GĨƒČ4Rsī“Tw;i{ųMP W,1šb‡c`gFv <|eƒÅŨĩ"ú|4gžZqg•NO#Đŋ¯K›Đˇ[‚ĸŨ@ŦƒļáuĒ5%ĶĀ|oO܆¯F>GB\›Ŗ”ļhÃåíČ~< eÂ,äՃ1;RDÚ1÷™"ķĖĢI’ÄĮ$šc%šīČYv‚ø‚UmŖŧ‰øaCÉiäŠ_c2ēîFU™ƒĮ¸$ ‰#xÂMüƒ7ÚååÂĮ]˙l‚d˙ÚÄŋ¯ƒž¯˙ú^Ä&áŊ¯‰į& Z–A˛ø\bD ~;ö#˜ÃwW3ŌĘa^ĩßŋC8ļ!–ˆ&ŠxË!:ĸ:ŖæøĮĸ›Ķ‰Į‰žxīL°Ų"¤{+Č4‰&ûĪM‚­&dg;Ėæ…ŗ@Ač¨'b/ŨBėįX ÆZqM­1ėx(œdÚĪe¤øŠÍųĨî-cÍŌÎŋEøīŲD\ꀮâ%š˛uØxˇboK”Ī%äėō!Ŗûlĸį‹iUCœv=š7˙ *Ōĸ¨ŽÄĪ΋—+D ŅEŨVp·&¸[ÃĒ~5Q7Ņw`œzŸĀ˙úŖ_9ŠĐĪĩIzВĖ:.Dų@ærMTū‹7{oęŽA„í5&nŽĀļ¨vēãņĩînâŒų¨×x“žã˛ŗ…čįĨđvJæĸÚņíũZxŦ¨@Ũ¸Ō%ļ(gÎÅ-ŗ—KëÕ~ō?#ņ™/îĮÍUj4g—tÍCw-ŠĢ‹PG ~kŅû•x‰Ŧ×įt"čŽ`Š—o Üũ Ĩö)ú·ņ?:‹°%“đ/N‰aęhæ‰|ü ĩĨÆ‰Ųŗ™”ąŽdČ;‘áڟë-ëá[<•qĶķq*ˆ$æũCąĢsđ:˜@đßqD^‰“ņlMũ9ĸ)O]'×Š7ÉģŖ}‰ŪLwr%™Ö%”ǝsģå¨}^ēØ ÷Učîˆģō-Æ%¤†ÕAøũ8Œyĩ𤖋‰•ĩ!biéĪ}Ä>7"+|˜GÖÎ?ÜuÛEMÅr‚’­•†“Öņ Ūž_…oū‡˙üŸ7!/į1šËå8† ÚHiâ'’ û ŸUCz`æÎøŽöA3Ëm÷v$}ūC€õXܲŒņM9Ë}É8\?4ĮææhÜî|<‚¨Ųb&š¸Ũ‰āUƒ0ŋt ÕËß(ÎŽâÅPŽKv’0ę™ö_Ņ>V 1xIö[Ņģeļ"xō<<žĩÄâęŌŪ›’Đŋ>)Ĩ3‰˜*2äÄ{˛Žģ’ŋuA­Ŗ™äMą_].†LĮũöV>ô4 ×í!!ĪËpJ™‰ōũe%ņxū;Nöƒ0,ˇDv¤3ųuŽŧs5qÆWP/z…ūƒŠ­û)rßNr“<¸z“ܡÃČz‰ËĶ›¤ęœČēy‚jÁsæ1Ŗpš“‚G-Kʏ]!GųŊ2uÎ6l,Žá;ĐuĶß\uí‹ÆX—ļ#žŅw*úŦD5lÁ^éäŪĐâŪɉ€]~„÷?,2|,ģ.RØ}ų-gĸŒÆÍp+雋Éoü E­hÂģĮ˙|-ÂĨcWõƒÂÆųØŦ–¨ë‹Æō„ā€7ÜL}ūį44G×23•éMîģ\ Fڏ °qč;ĨöČ#ôīT 9dŊ!čy QŪ9ø@eŸ]8liIė1G4įsfDYV‰ąrŖ°ž1yEą¤ēŒF;1uųԚžĀķæCjĻy = üŖĶWBGZ]:ø¨zQŠŌfō`ąķG> ŽģIi˜RĖōÜ Âđ‹wđ̀Py"Úĸ ”EĻ„ :M`Ī΄ÕzG=WĶä˜{á]Ķ’¨įž„ũ[/Šgۘø‘ßŅú5įyëķx›ĩ'ø-X7Š$)ī6Öķ"ĐÎIōg;bN”bgŗŠč'ŸŖ…dÛÚRÕû;ø…Í]<ī{o˜Žļj҃Ī;ė(™-[ ėŗZt] ÚĀ+ÜjVÍ÷søŽ1A6ū‘VëQī‹%üĮEB‹įĄ]“Hūk9Š&Ák;ņŋ‘„2¸mP7”úDÛā#˛ČFw—ĘŸ†¤uįvFÜēÖ%ûŨ䉡xfˆîų2÷ņėí'b÷îŠÂ‰°ģ´\Ümps‚k#÷×YFÁBWŌ~Öâ‘ŧ-na"Ģf8™įŗI˛?ĻøÖڂYØ|žz\D'Í%îøV\JOR3Ą.ž+šâ?y,Žééūīū Qv˛&ZV„K¯ËTģÛÅm„M|™1NS2ø )úÜŪļ›™8WÛ۔=jOlĮd ˙&8)‚Ā/ŖŲפ åhI™ŌG|}ÜīzˇņęŲ•˛ŗ‰ũ͚ØŌl’‚™īČj8‡čQ.$:ŸBųrĮđ<öī‰Ŋ$ĪÍE“ąŊ7đfģāę…u Ēc‰õĒY=2"Îî:F’“y¯æî„ÎúĪæõ 9WŸ P,žņŗŨgBŋ~EŅ!Uî;bžsmC*ŸÅy÷ċįÚ•č¤Đ5š×â.ē5Ą?]ÉĒ™JĐpŅM˙bzȝû!DŒ?FŲÚmȡQdģ”ôŒ†’Ú’nY@ZZ+, ęs3î=Ž ā´ęöë đAæ=(›‰„Ŧ2Į&'ŸøÔ‹ŲŊj;˜øî“q;°ë:<ö,,Ev!ĀÅ#[ī!kå.<û#ŪrIį&‘ŲžáFŖđĶ­"æēǜ Žî_r í_üßOÄŦÅ;4[Ļ’[?„¸#đ¯-ØdÔ!’Gąx¸'3ĘęŸGoߎŧ/íD>#Ąã”‹ōŦO Ž{KoN%jŖxzcĒ] Îô.ŲW¸iŊFxq_î]€K­Ä'^§âāW˛ė¯…rUŌžzûá †oÁ}]ŪSXV€Cņ>b“T‚…§ķPÜa×N¨‚?ķyÍsū˛G*wãIG/¸'˛Gt™õÂÅ)öúëč>$¨åjôĮ–<`Ēé}đÎXC¸{Ũ.Ōs.~5C}û€ČŪxEvĄjt&6ŗH\ߊéJë†îÍ0Øš÷ÁÔØĒ–ė‘Iäšĩøĩž†ÍŽuø˜åĄ>mæ*üüŠđ:ø Īyxo)Czi!'áģŧļķŌ°ËO'j×,ûĢŦWŒēPôxzĄÛeH|ĀĨîvÂG>|֚ÂZ*Ę"ßōqu"ÁĢĮā}ēš˙{ĪĐŨsIĢ("Ŧ …¨Ų]đKÚJHå@üžø—2‡æļDÕ­Dģ)û5gŸÆņĐTũķy—cs!˙Ū„}ß‘¨ĢÎáiŪ“K Į%°Y&JUâ”JĖ–ČHū>K÷ūâî†*›Œ×Í)[2OxJ/&č%K[˙'™õ™WvЗ5ÅĨõ@ŧˇ _ûŽōH#Ž÷5%Ę.Ũ˙Ŋw‡+ū–3ˆúŲ õ€×˜ŲõÆ)ā+ƯüŅÅ]"ĻãÔF˙đ]ĨĮ{ßPÜĢ ™¸ÛŨqšģ ‹_sŅm€Ėõ0s[“_@N‹å8,oNĘÎMøÚĨáÕ÷.oāđßL¤Ãīc7}<‰ËV’LOÄÂM_lĸí Âl{’›Ty7ąģ–J"'Gđh Úq#¸ŧ˙ lÖÅë‘Î˙ūŌo nģŪ‘XnNØjáĶæä+û°ę )šIøîVPŨéĮ¤54Ånvgb…ŋiO}%ך1!c—Ą?YÅƒčŖ„íW _&¸|ö34§^Ŗ\iBB‹ąd¨BđÖļ'Åŗ’ßíq,­—e6Š=ūƒBņ(ķĩ#ȟ~3ņ,TwĻrų ޞĩdļ6¤˛NÉāų’Fây´í):[’†Ûōw.Žín0áIšų¸unÁí“‘M įá^3Â']Âōųôy=ņĢ÷‹ũy¯)]ĶŲîlâî¯#ųÛtÉf䯞NXGf Ũ°Œ{sÆnyލ :ŦזōnË;Jæcwy‡`ļ\TcÂ0ŲģEî—‘{}ŪFƒ ´‰:Ž)aiŠņŒĀū‚3VÄ#aą­Ū"3ųKÔČē¤ēŸ'øĪoT)j’7uĨtËSŪ†ö•4vžHYŗ ˜%TUrˇÔ ’zw>Sđ7ŸzíŅM åö !¤\؉ŋtžģžūY‰ÃI[ ˇ;ãķû0)[ÄqAmĻíÔK—Ū”†ėÁmp~ĘđuÎÅßĒ™čÉ ‚ĸ,)ÁŖÎB¤^zrö/Gę\E˜Æ¯U‹Ø3¸šõö o6ŗm‚Ë:Ô%ôÂH’ÂIŋÕ“‡ą¨ƒ4đ žÉVhäīp•—$ŗÃÅá Ēåv¤nPqōÂ%t=ŪRémBáÕ‚×8Ņ›u­I zĀÃļ9¨2ŧQm؊ÕF1ë/ûŖÜ•Ž>Éä˙ŪûÛČĄGvßÁõëCqŸWņļëŠ|úg´v)dÎĖ$q¸čöĶČŽ3 ¯Ēf¯$ˇÕFJôäū‚|ũö"g#)ŠÍ5dĨŊ•Lí•(yÕĶQŌ×wúMÜl6õ˙ūŸŋ×ŧOßĒÎö~Jôųix]˙ß÷Áäáôā)ĻGú?¤×ē?'Žīc|GõÄPū˜ä9īI•äsbCĄŸŧ‰jOČø!¨Ä%^!c‚%Ę bŋ–yâöŊ ķÚf¸ļŧA˛ŧ3I‰īHNuGĢ’?ŲXĖžčˇm‰x×8ĸYĩYxûfÜs#ˆo`KđõūxŽIņĄ4"?ž&ë™ā˛ ņ¯•ˆëŸPd­F’ģTí.rî"ŋž7Ņ­Ļh؈°Ã‘Ÿ7Ā!øņEŠØÔ^Cčáģ/ãzž9ņSzãqa c”čAØÁŸÜŒ^Įš^zŌÚĮžh 9˛y^××øúČīv$eîwá`ŊPuˇŒxoĮ­¸ÚGpãé¸e}ĀâđC4 Zb‘q€´ŋ%ĩ>˜šĻQžũ…#ŊÁwr~d(™/ŅĖ_ iņŊĨC}ņ0jŽlŌhLvįks‡wč5Įˆž?‚“0 )ÁęĐVąŸx\žįWJ„Ļ%ÎģŪP\ë3Ž=Ū`vÕOīč×ęíų ‹Â÷ČķĄOŪCFÖG‘ÃĸcnĮąq,Ņ_#ũ9€{ū'Pŧ˛%}~G"ļ š{‰æ„O@Āô;(ŨĒ„Ķ˜$ú]„wŖZqį!-ˆšMĖ"’a7ų7R E˛FŊYL`¤pžĶņĖt$xšØa]qÛV“2ē!éxx¤‚Œ}ŨĐ|ŽÆbÆŧÆdqŗö<ÜAĀ­\"ļY>‰ÄÂ&äļĒÁ›ŋ|zöĀēã\ļ[ļ.›ÔGƒˆMw!ύ.ōUöx9ĪžS°ßá€÷ŲŋÄÅŨA>÷$>ĶEūXlđË˙ŌņnBԊŨD-$):„xįҤühLá*SėÃŗÄŽj ޜƒŦė AķŽāQČŲīpO鎷n†×ƒøēšCëũ¸úE‹ëä^ũŠwV4Y“§"_=Ģ6ƒP˙†ēã<|‡ˆŊŧ8Uä@sōV|ĮkĢp Ŗ—ÄūÜÃŗ"ģfbÛîãM-Dī.ŧwÚ´AJܚŧÅĨw3á OøėũgTÛˇ(ú’• ˆQPPPAr˜Uc* TŒˆ&0 bˆ$3 ( ˆ’$K”Œ¤Ycĸ‚¨ FĖ9g0ōú^‹wÎ˙îŗ÷9íî÷Úš÷Ŋģú7uŌgÕ}ô_ŗZ‘АK¨c>v>•4oôĀ å9¸$ū#ėŠC¸čÚüĒo'Ôp/|nPæ4Nãd؟Mė9|’]€“†9âlŠEW]p§‹+ˇäaŅÉZܨ9įngũl„ķĄįÜ€Ķˇa2sN{ˆÃßĀ OâŒ;6¸zÉ4ÜĒi7úˇ~Ŧ7jq"žã֌Û/ŽÄU/õpT ôWJņéoĪpÉņ8fßgœuô3NüøßxŽ‰ë ˇāS ÎãœãüsĒgqŌX3\Ątķ_Jq”´æMÅŲqÉ!N{\ķ-…yžŽO—ÃU-ßqm'ԏ¸č“NķĪĮå3×âĢ`™<\ũ% _™ˇ_[ĢļÆâ e'pGŪSœøi>{B'ķˇpØDŧ^Ž 7…ķŽz nt0ÁGy0ÚųSЇYá ą¸øˆ1¸ųNkˇá[ũøô x¯Áī_vâúg+qr'ŽIۆÅ•žOņŲ1kp“O Î7\Zφ›Šnā¸ņp•Ĩ3ޤ]˜×ü„‹×žÃ|ĘcĖUŋÃüūL\Šđ§ ’pÍ}Üõō;ÎXŒŗßĪÆg§¯Ä…Š›qRĐ-\í!>˙ wzÅĸɰO¯ÁqPƒOũ‰ß5™žå{ČN¯e&ΒpŰV O9áË 28q×f\ôc3Îŧ™‚‹gŊÅą'“ņũwø¸ŅNœēj‰>N9°wõ–ãĸ“ p-ŗö˜ˆÃ÷ÅãŌcpŦ1?gŽë=ępé×a8yHžđÕliŒĪʔáĖŪ~œĩ1ß9Z‰ķhâD%M|9`.ė5ōūā;F¯`¯,™[bpŅšŸ¸Üĸ ĻĮãĶWÖ⊇é¸îûy\kÉâr§$œ.ҌoÃ57ēpĶēcøō&œ‘Xˆš+ŋpĘĖG¸ÖzNÚN˜ŧ×H†áæé7ņ˸ũ˜6×ô„b‘īÜöéžøč*>ķáN•]‚ĪN1ÅQqbûĖåíÁÍß ÆūÁĨąGņ1Ŗ@œygõĮ9õãņéM‘¸:o>…pÎÜ͸­f!.ɛ+ŋEc˙׸ūģ!Nxց/]îÁŅ›Ā6Ã\€ųm øl Î{Ąˆ[ķ†ãnœ„q¸ÃĪ'XĘã8Ö­˜ŠĶÔ+đŲpSŊŲ:Üöō ކžėrˆ n9|Ÿ|ˆ Ŋ¯ã,ŨßĐ=ĮyĘŌ8ŊŪ_T7ÆÍíw0YĮâS—āęEpØ}U8Ģpåƒøōo]ü`Ģ &ģzņåÉâ8[ŨšŋĮ§gfᘟqwã:ÜQ˙ —/[ŒSėp|'.ęŪ‰OúJá“׿āLi\z1ˇjĮ…ą pęÁh|ļō:ŽĐy†sîgâËnáĐŌ“¸Bn,Nz9ėߋ v/ÂŲ§ããgtqQÂÜÉMøVálÜ 2•xā¸ö$pu+ŪĢ =ÂęÁĐ šâ“/(Ž%ō8ÛX\e;ßüp'lËÁņĪ§âKpí}Š3ôëpÎč¯Đ;ˇā˛Ø5`ą÷XÔ§‡‹æā;ĨOp•Í<œ—tįÚA,=€[Ū]í ƒđiß ¸Úīĩ¨`nÅM\r: +ÄėÅĩŽģ0ˇ{"NnvÆ5Ĩ¯qćH|&SŸz؂;Ę^á‚uđŊ¨ÍXäŗsâp›ÔAoMœ—~Gį:ÁųõāŦÚTœ3ąįˇwāŖëw㙯¸2ô->ž}ō*Ž:…“Áåė2\v/—ļŸÄmåķđ)øĖœav§ZŊÆ'^áëQ9øî•F\Ąm û`6NãRđēŸ“qžŖ.Ē;‰ĢŽÜÆ×āûOëfãÜi˙ö;&âŌÆ\Žr WxŲâfÉY¸Ú6™ā ÅŅ8+úŪīpmĨŽd`7Øp>KˇāÂŧķødŒ.ˆ×Äšõr¸FÖ'ûáĖ]ž¸ô&œ)9įT¤ā3q"\žûN›Úˆ“VáæÚp6wáŽį¯pœ´+NË*‚z›įų |ėëUܑ~§?ĸøŌŒøRčn\—@ņÅ+ĢņÁT\,-¡>¯Äĩî ¸ŽS—ŠĮˇĨ\đ‘Đå¸t3ô•jRøb5ôˆŠA¸rÍ'|Ļm$noPÄéëqšüœøÍ§ß›N‹š!:8,–fžˆķ\㋆āczģp˛ŗ \˙ |lL ž÷iMXƒ÷ļāŦ‹~ø¤ƒÎ_…ËúwāK¯úđ‰ˆ¸ųėœrÄŸŽũ€k“‚1ĮΧģ§ā&‹"\lQģ—¨áJpb%Ԅú§đ3šŽO =Feq‚ôX™˜ŧāJčÅkVčā4é!¸E ÖzŲSÜėīŠĪ~ëŧvßÃM—ĶqæĐ`\ą.ĶË{pĸęZ쉿Īņ•ˆß¸Ä[ ûUŪÄÅá ¸dÜ |ē§įŋۊ‹Yãfõû˜ÚÅßßâ„9•˜ûŗLžŒ/ėrĀWçŊwā„Ÿą8Kō Î…^:⟸âã,Ė÷¯ÆuŊî˜o:„ŗíNāF^œņ~+Nļۍķį­ĮŨŪ:8'ÁmÁˇpÆˇSøÖéf\§€ĢÃ9žßs 'ī’ÁWv↍}øhxüÂ1&8ąeÎQ†+wâÔ3í8!R'†ÉâķՃqް įīŨõsΘ6×ŪČÂĮ`rw ސˆ¯ZBķėۇ+RŸāŧR!Ž„¯éũÂ§ĖĄ‡œŽŽO]…ëFīĮĮí7á|į8ˇ"WÛõⴃ8ø NŦõĮEr8ûË1Ũy 7ˆšāĶ:VøVË\Ŧ1­lĮ—˜Ą¸Võ ÎUQÄMÍM¸ę÷T\Ÿ%†SG<Ā™sÜpĩę7\ūÜ œ,n´ĶFãæQ8×ãÎvãqWįsL‚q]ũ,\Ģs §7¸ãĸ¨`|Íļ_2ļÅŠ7q‚Ä|¯D SĢp.I6ÄõÂL ũčĩR´‡āÂFG^wrÚãÕ!˜–ņ¸Čšįny†îy‰Ręp­Ō||ģŋ_šjE?_brğ´›‹3,žãøUcđɊT؟ú¸iƒ‰tÃ%aŦ7˙Âé5ĒøÂS3|n/ԖwĐ¯OĕõQ¸Ō] ŸžW]+ÃųŠ Đķ¸UG W˜‡ĶŨáüÕļ8w>÷K_(ŅÆg? Ãi–—ņÁ÷QøØ,\⡇&äãėģ0íü‚[Ü"đE'MÜÖ§„¯<ŒÅM]ĪqÎÄŪ۟ā×ZŧS)ęR.ŋfÜöĀeWŸâ§Ëēqõa'\­†ĶGiãæžHÜĸ= —mŲ€/ÄâË×;pžs*.WŸĢæéáÆ÷Ų¸<ũ=Ž,Ÿ€OüŽģŊņd¨ÁZøž”ī~zX›…›ŸÂĄ/ļá’ĸl|rĖå%ú_Sļ™ĢÃđFëN\%vjķ|ö×eœj/‹/lû;¯§ãæû¸2Ę 7(vãĢš3q†<ÂM&†¸kä5\ÕļĶ%F¸‘.ÁWâjūzįčí_ޏ䕎ũíŒkģWãËņ…&¨y0.+Ãqžƒ1žsäNY?Gū†ãŧÖáŒķ°Ž‹¯ã“ŽÅ8†1Á…+GáüW¯p‚4ô„7>âęōŊ¸Ļá}];qdZŽåˆWa]€sîļ'N/ˆÂŨCŊqĒŠN‹{ˆ/ŊŽs¯Åĩ ÃqNÕ1\Ų:‡ŋįpCDΞ÷ί18ūeNĩ˜‡ËŊ^âˇ:*¸Ķe;~°wŽ:ķöøœf&îŽÃ¸%y#>ĩq"ŽšŠĸīã´#wpãš,ׄđĶ:Wˆⴛe8wJžB#qZĮ œ\ũoŋj-}„Ģš8 ~nņ\ûe&ΏwÂÉ~ãņ)Ũx|6@ ŸđøęáéØ+H7,é72øĻV.^9^Ÿ9˙Ķ‘ŋqíéc¸tr,Ž‹oąƒqĘģøŌgxŠãįÂͅY¸fC>wo1žV÷_yk;7Æã*i/œgk‡/ۛáĒ` |MjŽWSĮiŗZqŊlŽV3ÅÕˇáŒüøŧJ+ÎŽ‹Å)K&âÛuo0/ģ Ÿ 2Āyy2øėč͸ijÛî…OĪw‡=˜ gô9XwîzĒÃiîθdô\dđ×ȍÄ]°ČŨ ‹ŠÖâ†PÎLjESváÄŌ|"Ž‹Â3a†e/ŽįˆĪßMĀūũpNžĮš‡îãä SpTĐ|\äû×{TBúįã=35q•[7N[ĶãĀĶiƒĒpIûgœ´z2Ē€ULÃd~6Žp†Ī-™‹ĪOŨŒSvíÁ×dÔqįw?\]|Âe¯ßācŧ-ü>˙8'öÃ1Ŋ¸*į1Nxŗ?kõĮ5YPoš'₎¯pSŒį„ķ8"ÚgjÅ-Ėp‘WÊÁÜæHœ}S _øÔ€¯éāWrš¸=ķ=ė߸ŊĐSß͏%Ž —ŽÂŊ;mņ“č?ÖâG&_đ)—'âKõžøüđå¸}˜ >;~/ÎęÔÄįÅâôO|FkÎßâˆīĪīĀągž@ÍąÃˇĻÛá˜Øû¸¤vN}?{oԁķx>ģŌŸ_°õæāÜ÷kpĸ|?NîRÆÉVē¸îĢzÕk|*A“öV\ŋŸvsÆÁį­đ•ļĶ^ŧÁécĮá|Īøäņ2|§5 ‹Nƒ-‡Ā|[~ÂuƒĖqÄčˇO†žcæĻ?Į'Ü5p۟hÜ4 ^˜ŒŪ)áæU}¸Úy0&'p‰d.ī5•-0ÅÃ11PÅĄ3ûq=?_럸˙(–:ĪppšŊĀA¨­7{ž­ũ mmm=í˙FÚŗˇē¯÷Ôö đņÜļsãömÚ˙‹Āŗg/ÕÖū˙dhf ųÜŊŊŨwi¯u÷q×öŲååųŋĘį`ģtļ“ö˜O[ûßōmķŨēÆĶ[{ûē˙wæ[˙žŌ˙y>“˙(ŸšąĀōu5˙I>Ķ˙äúLūĪįs´[āâāüŸä3ū?ܯ—ģˇûVOOī˙øN˙û˙Y>“˙CžõŪÛ}Ŋūgšū-f,u^cžķœĪäßįÛ¸ÍÃÛv›ļû–íÛÖkģlü–Ī_ųūãûũ/å›á0ũ?šâŸø'ū‰âŸøß"é}sDcrŌoĻqnļÖ\ÆŽŽŲh÷Ą+Ÿ ­!ō–˛DōÜt"^7‚H9 ˆlÖG2â0K&íZIf(#+°?ŲésÖʕÉ2rf‚›sŗĨĮ_ķg ō$ÛVĪÍ­÷.jŽŧ6E$<ū@T÷°•›ŧčÚ;‚Ģü˛ģYą™Hå&‘ĄvidPe ‘0N'Snų8ĸ¸îŅJ×"N‘… +ÉÚ}NĮFΞ<ŪØ•G“‰Ģ/UķÉdD}$1*ŋD%[ÍߑĀÕ$Dq!Ųy`%™ú›ëũÁpaÛüš1Īt¸A“ēšÍC5šoļdęœ„Y0”L7‚ĩˇåĶđR“5ŲÔĘLe'í g'اŗ:O;ŲąJÁŦfcĢ&ˇŸĻŪÆĘĒcÅs¯2_6 g>”ße^;íũk<ūhcē 3FŦf î3‘ŨΘY‰åŒĖ•hųĩFā~sšuĩj|ÍĪÂĢ" ŋ™ĸŦ’N5÷ˇŊO•+ČŊÄĩ2æ~.š@†–]$˛Īv‰ĻŠŋֈôā0"˙B—h\M"FŠ]dNŠ,Yž’lŲįOļŒzJVšM"sl?ãČĩddĶeĸ˛)€č8™“§Ī§ČŪĮm$Äŗ˜ėŨéLĮ‘!?›šŒÎėO7'ņ]‚ŗYC¸+;2‰qI)ÁÖŨÄâ—$Ų8Ōj}A=kū2š5hûÂNzöÕĶsduO…ŗc?šącŦÚŲA]ŦŌ-cVîægVōf ĶûŦ“ų˙–yíČ<{VĖ<é˜ÅÜjĩcZ]B˜ōûRĖņžY5ãŖŌ|RĐūå› Øņ€õ;ņ‹VzÜÁÚßbËEuŊ8ą’ ÜbĘĨnÖâ.ˆ-āŪ.Ņ C”ōˆ|Î"e6âī=ķd=ü͊¨m/!úû‰Érâ6é ش̓lŨPG<8câ¸Ē‰X]]EÆČ„’á÷o‘ąģ›‰ĐW–Ŧ¨w&ū9ä`O‚ļL&+“íˆļËlŽŸÁ-P5ádú‚šąĪvsļĻdĖŖ“dæØŋjČFæ+÷`ųÖxI4kXšķw ŲƎWƎkÂjEČąęgęXåÄcŦƒĨŦtĸ:ķĶ3‘ųdhÉŧs¨`^dĪûkÜmøÃ´ÉaD*ōLĘYÆˇ;Š˙ŊāéÛpAÂėá­d+kũmíĩįÖ[ˆ\MĨEˇûßpÂĸ \ĖÎxŽ^ģĘ=ˆn!ƒīŪ&C<…DÆSė¯ņč†ũ#N†%:aOģØ,• ë5}˙Ú3ë­?‘Åû’ÉÔÖįD÷„ Qžø‡Œ*‹„ĢÄEOHv´Ž#Á̐ƒKLÉf7#bŠ0×ķG…ķęiā”.…pŠ2Ą\xé "Gģo)Ä<'€8ÕŨ#3š”ŲĄYŖI#ūŽ!'’Øņé7X˛ãŦöFŽڊÍĒ<ŨĖŊ4äķ‹éoŲüW ų0T™y¸ęīōŨ’é”[ĪÔËb˛‡Ĩ3Ąëcëø‚ĪF ŠlŗxMu¤NrížÂk"˄sĸšŧ ÜxwÆU¸äēG‰įNdčô^2Øĸũ¯"ūí-‘.[@†žNÆŽ%æâ:ÄQB•x¤–“­WdČĻSˆëĶkdÆâ'd˛öpĸĻÜNÔÎØC.žĖ‹žC6‡/'F?Iˆ=C|ŋ} v§‡1×ųÜQMMNgY5'Ŋ9†[ĩz÷:á(aŲ‚ü%É´“jÄ7(›‰˙bÁšÎņūģ†zŗ„ąēŖëØąŗ7ŗŖMƒX5ŧŽžÉʆ¯e%Ô2˜¯öÕˇž˙­†<ēŊ“š>™š¸Ž“)\hÁDK˙aĒ'1rķ4 Œ•`‹ŗ¸u“âåšŧĢ[EĘģ&Š’—Īä†mĪmøņËMÂ]>:†ëŊžH†Z@äĪ%ŋNū}îļ§ųÁADŊ:ž†ų“YŲ7ČĒdː\˛åH5YŊŗ†Ėm™OLÆ •éDųž7™ ’"vŋƏ^dĪņ%$dļˆėŸu„8]ŋM†Į>âōövqŒæ|Nōfg=8‹;°„­'v™+‰Yå$⯞GÔķjkķ‹5ÔÃN™ÂęmæūĒ!ã&j˛c¸˛#>æąÃgK°ōŗÎŗRŗÂ™ž אūąĖķÅû˜§XšÍĒ0—ŗ0gēZ™øžnÆĶc3˛ÉQĐmÚ*8|ÔI ĻËYåA y/Ŗ%ڝ(úö$˜s”ąã’ŨÖpįŽYr/oF…ŠŖˆ‚j1‘Ęzņw ŲŋŽ vÚKT—Ž#zūqĖ™H–ßĶ'IŲz3†ŦMę Ÿ#‚¨\ĸõ˜ īL'Zd?a÷u×ĶåÄoą9¸ō –N"î^Ũ×ÜyĩõÜâáķ8Ų„-œĻØ".#äQŋ[FfĘ{ÃÄãˇ6ŧč k ŽĮ>?ĘNmbõËŊ˙Ē!:ƒ¯°Z ŸX Všë;dw)+3č5ķĢ,’ų”:˜yWōßjHOfsm3,Ną'Lę[GfŠ;3iĒļāõä‚”CĪú3FZO÷`kKļß9V/ĩ‡9ĢŖošČ¯ƒ8Îô×ķáĩ– š~–ČtvņᧉDZ5‘š”A”ļX’q‚mDPūŠ8˙Î&ëĐĩŋkČĶ4˛¤w,ą9b@&Œą!*VíDcÕ9b–‘Fu:¯é2$čŖ>9˜îMļ™ &–žÜŗ+¸Ũģ.pjúUœüīĪ\pÅn"Ŋ_žā}†Ärmq˜=ޏØąû_ąF×ēØÉŸŪ°“$ Ųņ7XēV;3‡õč3Ģę"d%v°f5+ŌÎ|ö_Æ|Ø÷”yĩDú¯ņx°qĶųJžiŦzÁä´=eÂdv3ÂN!#ĻÔ'(? ˜w/Ô:yt{íB^KdøöŒ¨ėt§­ķˆÛ÷ų+WZĖuŠũ&âúōאž"á|ˆŸ•&Ōëɐŧ 2zk1ĩŊCđU˛ĻVDļŽ° ›z­É ƒĢÄ^m21¸ŋ”¨}ŪIT¯§ÉŊvdNøG˛ņ’9`ŋ„lĩ'+žûD"u5”‹kšĘé'DpR ͜ŗôxîá‘Zbõm™šĢIØ'édˇL!ŗ82‰5›¤ÆŦVc'=vc'Ôxŗē.yėØ vt– Ģ–5’öŨ‡•ũnÁJ”/gžé-c>.ĩd^—cžÉŧes#˜›Ž0ÍÕŗ™âĀųLĖåŨŒsüfČĨÁ…yīéVë9‰ŊGj"…ŊōĸØÔœüdGnÍjmîTøBîŌ*,갎Č]M$–ū]CĢ‰ÜœN22]–ˆ$3;ęÉĘå3ČæÔ.˛åēq?2Ėw,$æ ֓QQŪ–ItŋķÄöŠ,Y#iKvODBô‘@ÉWdILĄ/͕ėúÃŲǝā¤jgsƓŸpJô-]Éô׉éÚJ˛SĒ›ķĐũČZŒČNģĀNv aõîauÛŲqî2ė˜÷FėȃŲáĩŨŦ|m+UģœųžĢųW yģí ķü‚ķ´üsG"šōe;Sub8“X:ŒŲŧ,‹=.HpĮ+MyYO —áaõāĪĄÚ‡ōOD^“;EīôGqŗ_´p ķŗš†ŦŅÜŗC9D~Ĩ?Q=@¤ Œ˙Ž!3÷‘AÍK‰ŠM<™ ?†LÃßɲŖgȆ;ūÚ3žģüˆĶļ@ÂÎ{GÆĒ"Ę adŒƒ@Žeg‚‰Īíũä ŧ Ž]M<õâČD{îŠĮ nåŠhNÁŌ…SkÜĮ%ĻK•îķdÆõŨÄtHYY˜O´lÍXË‰ėËŠėdž˜Õéʎ7ęculjX­īwY8VeČEvČ̃ŦŒķGLšųŦp‹y?ÅåŋՐ{AĶ™Ž9¯Ūč“Ū_ÍNÔ`Ϥ8 >l4d6q#lfŊzI^mōÕ2ŅLĻXt1q&;|¸pŋŽ&Ž—ģŗđ‘ž'CåķÉ éŲDB+ŽHŦģLdö ÜOí—߉ÕÍŲÄÉo&ņ\1å¯ņØĩ”,›OđÄ.ĸ—“FTō2‰ú°Ĥ`;qĖą"Ûh> :@Ūp#^÷ove÷žŊÆŸ=ĀizĮÉŽ’å&_'b6VĆJŦ—l%ŗūXÉĖãcÕŦqÄ7Ö`R7;‰c'(ü]CnEąš‹ÎŗĒį•Xł'ėā‚|VÜ ŠųüÜđīŪŨ˛āīŪ]ãĶÕRĖ4ų1y҆LDÎZÆn¸#é0YPÍĪ,Ynh?RēVÎ]īAĸ‚â#œÆ3yÎī[7WT=ģƉ¸?×BÉЀkDÖī(‘ˆ¤÷î6û‰ÂÅ_DsĖ bœCæ #î™dËÛĩdsÚ'˛rē+™Å™‘)iédÄõDuø22Éę7™ĩü&Y˙rŲoôá¯˛{O™{¨“ČŽMį’Õs†÷?s’†ãš9âC¸s˙bŗK—X{%{ŽĘ îodÍekYƒ„?õîŪ/guŖbØąĸŠėčū;ėĨ—ŦŌÆŦÜFYVrŲHĻWĻ˙īsWkķ˝y˛Æ•š5ksIú,SZęÉ;ŌĀ,ëlb”f[ ZĢî öæ=ĩ~ e]1zļ˜Hz˙[Q„Ž 'ũvį†sšŒŨĮÁ˙ošŨ{Ā˙áDŪâ=øŌ€˙ˆėŠ‘ā˙Ŋāøøŋü?üoEÖdĩƒ˙e‰åĐbđŋøŋ üīū˙ūūß ūO˙Ī˙k“QuZ\yÂÍRķį¤ŪpúO1WŪ_Lt2lÁ˙9û߲“+˜áĚĪl˙—ø?ü_ ūūW˙§˙ķĀ˙ā˙)ā˙sā˙šā˙ ā˙qūŸČ´Ų=˙/˙/aŧü˜ą‚%Ū‚c˛?ǚōÖ ;Kk¯+å‹<ËôEO7×pv­Žā˙oÜŲKĀ˙/Ā˙iā˙…Dúúë˙˙ׯ˙į˙/‚˙)øßaĀ˙ęÄųë=đŋ9ø |N üßū÷˙_&;´Á˙ãÁ˙ļākbØåĪu•ÆsëW}˙ۀ˙_p13‰bûmđ˙&đŋ>YfņŠ˜9˛ŖÖ'€˙‡ øŋü˙üŸū?ūˇ˙˙Á˙1ā˙ø˙ëƒ˙}˙îŨWŋ˙cÎZ~c˛Ļ´˙Ĩŗ%‹_ķ¤yGVOĘ­÷Î^Ųé#ÆÕ=îæ&;}˙ŋä*ŋ*p7ĪČŠđ˙â{ā ˙§üüī ūßū/˙¯˙o˙/˙˙Ī˙˙˙Īû˙Û27ÂúĀ˙áLĄc-ø?ˆq¨leäæ: ˛‚- Ŧ› jō wWŪ}Y”ėļļiˇá×Iđø?‹ëíÜūw˙›€˙Ŗü_ū¯˙ß˙_'ŗrČ*oeđ=ø˙$øß‡Ėm~ūE4”ŋ€˙ŖĀ˙ÛÁ˙ųā˙—ā˙|đ˙Yđ˙XâÔŽéāōöXrŒÆ#đŋg-ʝÛN Âׁ˙‡€˙wEĸžŠŦEėđ;ø˙(ø?cĀ˙Šā ūb‡Īz ū/˙{˙íü?üŋ–yjÛĪÜf~€˙KÁ˙Ā˙KĪ5bĖČs‹Ũ&Š‚ÃQząqîVyyĸÚ÷˛žĸŨ_EߞEqŽƒÎpÉ+ÔÁ˙"îå-Wđŋ#ø?üuĀ˙>ā˙lđ˙Zđ˙#đøßüüīūO# Ÿ5˙Yđø?ü˙’°ûˆkáDđ˙Ađ˙gđø<Ņ}åĝWŲÍ-VĖÉÆˇršâĮšŒC¯ˆzĪđ˙đ!ņøŗ† žoĘŒū˙׀˙=ü_ūū÷˙_˙Įƒ˙;Ā˙ļ˧”wā˙M˙â˙íāUđ˙z&õÍkf˛3I8Ađz’ą %T$С ŗžîÖW[âsQäXÛ&j?TÉYŸ˙orœŲŽįãđ˙đøŋüŸ ū?ū/˙€˙y"¨p"ÎÄČ:Ąô€˙ĄßøvØD4‘ Ŗ˙̈Æjb–9üß ū_ ūĮāO˛Ítąŧ6—{ļo1ˇÛ˙§ĻWÎÉ˙9ÎWęéķÁ˙‰ā˙EÄaŽq™ēŠ•zū/˙?˙§˙Ī ø?ü ü¯Ë* zÁ˙ąā˙Ķāđ˙eæÕâëûÃ;ĻķåMđø?˜ “~¯+˙Ũåûį æŨlŦQRģđÂW‘ᇉĸ˛ĸyœöxMnß×DŽ´ÆŠë˙û øßüü?üīūī$ŖˇiS<“8ØAZûüŋü¯ū?JėUĪƒ{Á˙6ā˙đ)™ëčŌđũ€˙×û„ƒDęĘf.Žy§ŋü˙›st{xtąęĩ!SsNöi(ø>ŗ8ķk6ņ>ø0øßüŋüŸ ūˇ˙ŗŦZæđ˙2đ˙hđŋø_ü?üŋ üßÅ<=˙§0ÍU˜âmā5ÆųD3¤åā‚ß=oĀēCæAžė‘žRQlú;NŪ ‚[ã~”;1üūŋ ū÷˙K‚˙§ ø˙ø˙'øøß‡ĖŧŽū? ūūˇ˙K€˙‚˙ÅĀ˙[Ā˙„čūū˙sd÷ SđøŋŠ,‰>OFLx͕,älG”€˙•9cËW§Gô­|Á˙ÁÄÔSšė”ūÍyČ*€˙g€˙Eāđ˙đ˙9vÜę>đŋ øŸ€˙ ø?ø3ßs^ ø˙6øßüßūw˙ë2UĮK˜Ä’"fķR?fôØÃ‚;ÛŊ‘—~ äŌd­|ė¯}¨8Iä5eŽčŨ¤‰ÜėWÖ\‚ƒ+ø?ƒ{vØ ü_ū÷˙Ëø?üī ūŋūßBĻŲm#ËĸÅȆģēūĮā˙ ā˙CdŦęđ˙đÖ˙˙˙ß˙́˙§Ī ­dĸÃ]q—ãVfús •œÚšŗ\bÆ3ĸrã;øÎå! ČĘĸ>ĸÅV°:WãÁ˙:ā˙tđ˙|đ˙kđøŋ ü?ü΁˙7€˙O1ŋû+Á˙õāô/ūū˙÷ƒ˙­™@ũfĘÉł¤™įĸF6YÖĢŽ­MžöM4S¨#ē˜eĪ™x?âÂũgs5ĮswE™ŠSÁ˙'Á˙ā˙Cā˙Ûā˙$đ˙kĸũĘüüŸ ū_3āđ˙,đ˙đŋø˙0ø?ü˙ü/"Ûx đ˙Yđŋøßа+ęš÷‚Z.¸n§úü_ČLųNÄlw›ē…Äzņ2Ģߍxˆ1“[Ā˙ ā˙fđ˙!đʀ˙Á˙§YÕϝā˙đ$øßü?đw–~ū?ūßË4ų´2yG›™ˆė̌Ũ°'Œäü5‚jĒ-X˛¤Ķ:_åq­ŪM,ŌņŲ+*(5â4žÛs~}ģĀ˙߸kd1÷§c)ø˙ø'øŋtĀ˙GˆBŗ1øŋü˙ ü˙üŋ üŋüü¯Nf‰n˙­Č8WU‡’IÖkÉ,×eāžė›üík27ô‘õå’Užp†÷ö€˙]š9’n܍āšÄ<ā ą ¨%ÖkĮ’=Q…‚ģ߂˙‚˙? ø>ø˙ øßüßūo˙Ofå6ŧc%—ž˙_đ˙đ.øƒ˙§˙w2Ĩ%/Á˙nĖ˛ë‰ŒŌŦm‚ÖĘ ÁŪ\ëâĒŠ˙æ˙ĀXQ„n''ũî į6]•ËØ3—k6ŪÆ}¸1ü_ūī˙đ˙6đŋ øŋŽLÚ­ ūū˙ūßūŸū&7JĀ˙3ˆfÅCđ˙]đ˙=2-m'YõaøŸ˙Ÿ˙ëיvd/ÍUqŖ¸Y*—Ā˙5œūŗ\…øĸ“é ū˙Û˙V?škMÖÜžüŸ5ā˙Cā˙Bđ˙Cđ˙ đŋ/ø?üīūW˙˙›€˙‹Ā˙ƒ˙ö˙ÃOā˙DĻÆé+“ŧõ3ã?‡{ Vđ xĻāØā6ĒzšĩÂÖÍĩ×UŪ‹<+REOˇžãė.×qqŸ›Á˙_¸Įéā˙ˇāKđ˙š˙g˙3Áõ'Á˙߈pŪT˛tˆ:ø?øo˙/} ū!BųËd\įĸŧ¤—höĪ˙ŋ†ęūß ūˇ˙O!ļBÛéÃupëWÜā†vĻsÝåbš&ŎĄā˙búæ3YfÅŗIˇŲQ›ŽŗSrž ø?üß ū?ū¯˙˙¯˙ Ā˙žā÷˙˙/đ%øßüüŋ ž¸1[đ6 ŧ) ūˇ˙ë‘i!Š\ī7.lķunĖMđ1ˇYe=÷mĐđ˙]đŋ.™n˛ŒlŨ8ŠičĢ˙{ ø;ø?ü΁˙7€˙÷‚˙ׂ˙O‚˙W‚˙“Á˙§˙˙7€˙ĩ˜ jMāE&˛ë3ëÄFĻõƒ€|˙,pŋžĮēZqdÍĪëcEģĸDYÃ8Õ/nûO7Ž ßškĶÜĖũtj˙ƒ˙g€˙üŸū"m–ā˙Hđ˙đ˙Cđ1øŋ üŸ ūˇ˙û˙MĀ˙ˆūŽ1dρ-ø? üŋü΁˙7“…9dČ÷|.#kgöŗüŸĀŲŦ_Ę]ņķ%ÆđŊØęąø=–ėNĒąōū×˙ßđŋå€˙ÕÁ˙Õā˙LVéæ/đ˙Yđ˙Ađ˙Ö˙k‚˙w˙UĀ˙ŠLĢķKđŋ8sŧ˜cVŲ)1*~ Ú?;(Yŋũ9×JoKaío™įĸƒz5œXŲ=nņ„“\ę–ŖÜqîíRü˙ üŸū4ā˙đ˙!ĸæe ū¯!vĻ3Á˙[Á˙ā˙pđ˙Eđŋø?ŠŒ‘ž ū˙ūO˙"+–˙ܙā˙'$hsY™XG´ô9^o$ˇ@é3øß†û˛‹+˜ą–Œy* ūwũÛ˙ÂîíÖxŲđ˙‘˙ođ˙%đ˙đø%ø_ž•Nx ū7˙K€˙÷˙‹˙ãÁ˙Bđ? ū0žŖ™ņ=/O_Ģ fžhXn­ī~ŖöÜY‘Ģå'ŅŠNNX:“‹ņpôú`îAŦô¨ūā˙Áā˙Ëū¯˙Ÿ˙÷˙ƒ ë-ū'ā˙{ū'‹÷>˙+ƒ˙mÁ˙-ā˙›āJ\ô—“—5Á˙SĀ˙ōdķō{ĔËõüp^ˇæqJÍû8ÅÁĻ\xÅ{"WįAėzĮķėLâÔ°ŸĖ “ØĄŊüß2ā°L:ūß ūĪdGyŋ˙[˙åÁ˙%āÉ˙?˙OđŋĶ)ÛĪÔí`˛ÛĀ˙Ë븟‚‹EĶ,xĨ˜uäčŅĩ{ÎîYž”Õ寝5ä‚w‚˙ë¸nM"ņBwĀ˙Aûŋwø |¸ˆŒ S˙˙ŋ iāū?ū7˙+˙§˙ׁ˙Oƒ˙CĀ˙-dsÄDđ˙lđŋ6ņũÚAėōY"ļĖž;Ēž›ĶYbĪIoYĮ­ō|ĘŊNq'ŦP› ß^2-åņŨ×Č$Č‚˙ ø)øø?üŋü?ü?üŋüo ūßūw˙›ü‹˙åÁ˙ ākđŋ -õƒq8ŗˆ‘›ŗOĐ`Õ,Ø˛@×ēIÖĄ&īëY‘ō^/QōĘUܰÍÉ܆?SšÜ¤}Üåh]ގ‹˙o˙ÃÚø8āø˙%Q¯Q'†áSĀ˙Māđ˙đøß ü‚˜į€˙sÁ˙yā˙Äî÷$âņsø˙+ø˙ŲoΧkīČđč.oWĮ¨ûƒ˙ÎZawno&1ˆđ$v<øŋ•øŌõė>ū7˙Ÿ˙‚˙Cü/ū×˙ī˙_˙Į‚˙]Ā˙Jא?oÁ˙ŗÁ˙OÁ˙Á˙+™3ŋ˜øģŒįępfdãlAˇą›āđ‘'1­Ģŧ¸„Ú÷ EĸŨEEß^$qޞãĀ˙íÜšÄŊŧmū˙€˙+üūo˙įŊcbËĒ€˙΃˙ƒ˙—ƒ˙7‚˙7Aäuđ˙$đŅĸ Á˙ā˙tđ˙5rpÕ đ˙Râ~߃čžÄÜųáQÜbÅĄā˙‰œĻD7—.IÔīk€˙÷ƒ˙}ˆG6l_ÎŒÖ˙û€˙ Ā˙Küüüīūo˙ī˙×0ŋJ?€˙;Á˙Ž˙âkæÚĻû ×˙üČėQúÄLBę‚×úī)!ū}ÛÛÖĶãڒ]e"Gb'j×įŦb/s‘ßNsœš&×ķi$tTüŸ ūO˙Į€˙ÛÁ˙ø_DÆ1ōāūw˙ŗū_ū˙/˙˙Ÿ˙¯˙!‹ē–‚˙ëĀ˙nā˙Ĩd›I9ąlgšg{pģ}9ĩ %œ|ŋ%\ÕI¤Ŗ Ū/E,=^‡šõąÎJ„<˙‡€˙;Ā˙1ā˙Ü˙‡ƒ˙ëĀ˙˛ā˙đ˙Fđ0ø<øŋüŸ:ā˙ëā˙,đŋ:ø_ üoĮ¯ĩ1bÃęåûäķnåY'pĒ]ØŪ"2ü”.*+ūČiOXĘíëeÁ˙\§„$ø˙î€˙ø_ū×˙‘!ų˛ā˙íā˙đ:Y#bÁ˙›ČĻo/Á˙sÁ˙KĀ˙Ąā9ĸÚ)C&÷˙÷˙“ŗÄ˙öŋÛubŸD¤.ģrqĩ8ũŖ8Š!fœŗ\"÷0æąę ūW$ėŗdˇô{fquø˙4k°ę'øßüŋü ūgĀ˙Zā˙Gā˙Šā đŋķmÂGđŋø%øŸ˙—‚˙=Á˙%ā˙ŲLLk!ã|<ü/'¸ā›"đ͋˛î ŠŅ7&"…‹Dą™ß9yÃ&n͚~đ˙YîŌjyîËâ"đ‘;˙ü¯;ā˙v"7wø?üßū?ūoĮȂ˙͈{ÄY2Ágbîpü? üßū!ļW‡‘5RSĀ˙ā˙ đYrô%1ūWâWÎŲĒ)rR5=œąŦĪz[ĸo ū7˙/&;įÖŧū_ ū/˙o˙Ãx4V˙_ącŪ}˙Į˙3Ā˙ā˙ ā˙Ę˙׃˙5Ā˙ÕāuæĘįëā ūˇe6/1gFkīÜŲf,ˆl äN†Z=xrŧöápo‘—qč97ûu—°@…k8ĨÃ= S˙?˙Ī!Ō“ø?üETlÕÁ˙ü˙üīū_>āâ´ĩü¯ūˇ˙o%c ˙Į‘e•^ÄįŽ%øø ø™čkÉ]Y5Š[™îūWįÔÎKp‰Y—ˆĘ­)ā˙ãā˙‘deÉLĸeiÂę´Į˙ƒ˙˙mĀ˙÷Ā˙)ā˙đ˙đ1ø>ø? üŋüŸū÷ßũxüá§|gŌ˙œaõ3S’į>Ŧkd6ÎMũjŊzNImr—P4sZ‚čbļ3gâãąhp5'ˏ;NSĀ˙Qā˙Ŗā˙íā˙]ā˙įā˙3d˜‹!ø?žXŨ˛˙˙˙Įø0Y6Ŗü?šče?˙o˙ŋ%&§ŨˆcŽ ø5ø˙øß–xŨ;IXˇîŊUL¯q!÷8ŲÕķ¸S-"† øŸ˙ī!ŗÅ‚Éšß̘ĮYwÁ˙āūßūđŋ7ø?üü_ū÷˙#æķŗž˙Ûø˙(ø&øøøßąSĖb$įE ĒšÁGë|ĨđÚ{fFĮ ŦƒĶxÄųũÍՁ˙?sŽO˙Wƒ˙—˙ŗüŸū_ū˙AŒíÉŧeā˙Rđ"ė›l˛ŌŽüŋ‡LIŊ ū/˙€˙ÛÁ˙ČúWāßŋũŋģ‘Ė ųNd×ørÉĘÛ9Þaā˙HnŽt0w#¤Š˜ī:ūŸū¯˙ĪÜũŠūŸū2āđŋ/ø_üßū¯˙˙w‚˙/‚˙O øßüü¯ū—˙ë€˙×0Į">2Ë:3Jö ‚Ö3^‚ŊŲyÖ÷s¯ß‚˙ƒ-D8é÷ī8ˇ!\Æ^ đ˙'îÃÍ1ā˙›āŽH6öø? üŋŒ˙{“*sČ ;üū ū_ūw&–Cnƒ˙cÁ˙/‰;üßūī%ßäÁ˙ĩ$đÜOâ:cEžrUĩk¸YʓÁ˙!œ>ĖI…$!:YkĀ˙Ûūöŋ@‡+˜ôŒ5Ÿuü|Ā˙ā˙4đ'Ģĩđ;ø>øßü¯ĪJëõ˙—€˙ÕĀ˙ąĖ ‹ˇūįÁ˙öā˙pđ˙aÆëÄ fėū"Áƒ"IÁąA‘ÕSŦÖUÕ^i)ōŦR=Ũ~•ŗģ:…‹û’ĖõŽåīr!r†,ø_üŸ2ā˙Rđ?˙ˇŨ[3Á˙•ā_đõ€˙ËÁ˙úāOđ˙1đø?•XÅx€˙߃˙o‚˙įƒ˙5Ȇ-EÄđúŽĢ°ˆ[īz ü/É ?|˜‹9˙š(^‡2ô-øŋž,ŗŽ fÖąŖļƂ˙oøø˙ø?üü/ūŸ ūū_ūŸôˇ˙S?ƒ˙§ø˙øø_›É2le‚/\e˜ŸžfĮ ōÄ´V÷;Ŧ÷NYyGB$LjÕ=˙ĀM^|ƒ ũÅU~ŗįnVځ˙;Á˙~āÛ˙˙˙?˙‡‚˙‹G’ā˙Dđ˙§ŋũŋö-øß üŋüū˙ûŖ3Ä!Ė‹lĩ”˙€˙'‘û‘i•¸Ū/Ú°MūܘĮŠÜ ƒáÜæK¸o˛YdęŧHÂĖ?CĻ›n%[×ĪcÅZÁ˙Süīū÷˙ƒ˙]Á˙îā˙Åā˙@đ˙tđ˙đŋīŋķŋ)Ķ˙ üīÃĖĪ˙ģ1ŗŽ{€˙Õ¤¯\āŪŪk]-_WķķYĢHc‰(ëL§zēˆÛū[ ü˙‘k=˜ûéœūĪ˙O˙đ)øŋüü˙‚ĖIŨDVGŒ˙_˙Įƒ˙ב96wÁ˙âdäšĮā˙ˇā˙Cā˙sÄķŗ øŸ€˙ČŪɂĶydHßQ.#Ŗ–3ûū÷äl6āŽTãō“ā˙“ā˙B˛;ų€ÕŽūŗŦų‹/ā˙+ū×đŋø˙4ø˙ø˙!ø?üŋüo5ā đ˙JæÉĩ>æÖĨ/ā˙DĻŧgøßœYe› ū/h˙8C<¯Íúmī+ŊéjˉNtåÄ*Fr‹õåšÔ­3Ā˙7šˇËĸɐáŖÁ˙‘ā˙æ˙Wƒ˙‹Á˙;‰ūįáāü_ ūŋ ūßū#Ž+ËĀ˙ãÁ˙Ūdøqđ?ú­˙ß˙Įƒ˙ŋƒ˙ĢČʄoD{‘"Į_Ā-6ƒ“ųVĀ}ŊŽ+°_FÆ<ūĮûj.÷Āü'kŧÜüŋĀ˙îū§ā˙Gā/đŋĢp˙ø˙ķsíOæ“Ásđ˙Úņŋ;ø_† ogR Ž2žw™ņwī žžŧ!H˜á.Đ:Öm­ī:ļöœī‘Ģ`čΠšœ°Ŧ’‹ņ“˙į€˙3ĄGŊ@†Ŧ}ū/đ˙đžËüßūßBR%ëGđŋ ø˙™zАčÆŨ˙—‘Qeã‰E’1ø˙%øßü?‹\Ü ū7"Ļާq^Ũŋ8Ĩ‹;Ā˙?¸đĘ@"w6üŋüˆSc5™Q#ÎũqüjĀ˙ķĀ˙eā˙­ā˙8đø4;´åø˙Ķß|uĀ˙MāĨŋkHß3đ øø-ęYËX ~<Ú,(~`×=֑ęĩ{ZE–)Eĸšĸ2nŧįFđ˙Žb‰+ø?ü5ā˙eūW˙ûƒ˙‚˙—s‰ÄQŌüīū_ ū&ŽOž’.dō˜āSđøŋĖ‹‚˙cÁ˙^āeđŋąË›MĖ2ÜŅ‘šœÎbiđ˙%nÕ/îuZ&øŋüŋ‹LK=C|÷|f†cMgw øøßüŸūŸū7˙O˙/˙́˙Á˙#Á˙j˙Ũ˙ˇēĀ˙‘ĖEĪLá‚BđŋãP~‡‘›+h°<$Ø2/ÃēIúKMžė‘ō~eQōęMܰ-]܆ū\n˛ø?ëíū÷'r.ŋÁ˙;ü‘Čˎ˙/˙GYš ø?ü˙üŋžŦöūūgĀ˙&ā˙Ĩā˙2›ū/˙_'{N؁˙/ƒ˙§öodøŅr.Ī˙%ĮŒč˙æŦ‡NæÎí'GœĀ˙;ˆY•ø˙Ŗ¨gæAđ˙\đ5øßüŋåo˙ë˙˙/˙Ÿ˙ûƒ˙Ļīü˙_˙˙/˙΃˙‡€˙cÁ˙ķĪUJĖČĄ ÛHCp8"K 6zŠUŪßÚ÷ŠŸDģKŊĘãåb¸ä•áā˙ŗā˙~đ-ø%ø?yĀ˙GÁ˙ŸĀ˙ĪÁ˙Ā˙GČōû*d#5˙ۀ˙-Ā˙CÁ˙[ˆVdøßü/"ė+âZ¤Lü–h˙5Ā˙VÄũ^Ņ}aʝ–Î-˛“=ĮiJIpā@õ ø?üoG֊]#ƒqk0ĻüŋüŸ ūŸ;ā˙\đ˙eđŋøŋüŋüŸūO˙ׂ˙-ūÅ˙’ā˙Ķā˙åāUfΰ2fĢ x­W$H9h.С1°žž ˛ļdŠČ‘‰Ú¤pVq,Ųģü΁˙kĀ˙Žā˙đ˙Ađ0øŋüß ū˙ ū_Ngƃ˙kĀ˙Ûü¯ūˇ 6áŸĀ˙ā˙`đ)1Ë˙ß&^3ÔÁ˙~ā˙šā˙ÁIJm÷l×ln÷N5Nmüiđ˙e.¸Æ“HQđ˙zđ˙Aâ0īqąúÍJ.˙¯˙_˙‡€˙“üŋüŸÃĒ:˙7˙íĀ˙ËÁ˙ōā˙ā˙ ū˙ˇ0•ÅLÎÕB&L*‹ļG‚˙ĩå{. æŨgŦÜWģđvšČđ̞¨Ŧ4ŽĶÖ;ÆíëëáJkw€˙ņ‰3ü¯ ū/˙€˙‚˙…ā˙:bj7‚8L—˙ī˙‡€˙Ā˙rÄ^åø QûÔ ūgĀ˙Ȝ#ģÉÆÖšā<ā˙ÄūD‘jËŝŋĘéĮ=˙{rÎCÆsĩ‚˙’ŠŲą„}>üŸČ,ž4üīūū7˙Ī˙‚˙ Á˙ƒĀ˙—Ā˙ãYŲž—ŦDŲsđ=ķqÉ đ˙tđøøßüŋ‚)Ūü?qŽŗa†4› .ø,øæÜˇî›XŖŋtˆH!đĢ(6[Š“ŸŌĪ­Yģ•;uÄü”û˛dø? üßū—đø6ø˙*10˙˙$+]åĀ1:ā=đ˙đ"øß€ŒZsü˙üßū?ūĪ˙_˙ƒ˙įƒ˙ČŨVŽÄw8gĢâū/äŒMļr\Ŗ%Ņœ Ķß?˙g’ƒ­š5×ĩĀ˙ģĀ˙éā˙ā!øŋüü˙üŋüü?ü?ü<ā˙\đŋø?…š#ūüŠŠģÉ$w1›]>1Ŗĩļ îly+ˆlöČ%‰Y=¸Ą_ûPĩVäef&z7ņ›ũVüüŸ ūŋDäWŠ€˙Á˙܀˙ŗÁ˙yā˙ådÂD92mēø?üõˇ˙n‚˙ˇvnĢōüŋüŋšÂĀÁ•OĀ˙ąā! Ž#ŸA&ú˜qWVLáVĻnäĖ÷qjĻp‰ŲQDåļø?ƒ˜*<'+K‰–ÉV§c;;Åâ=ø˙øß ü ü ū¯˙Ģ‚˙3Ā˙æā˙íāuđ$øđŋø?ü?üŋüoūĮĖ”$Ąāƒg  ŗAV`$´ˇ^m×[›|ķ h&V]ĖuįL|Ā˙oÁ˙íā˙Vđ˙đøßüŋü˙üüŋ ü˙ü_@œü—˙[˙öä#đ˙i‚õÁ˙ā'ĸŽÄ‚˙ÛÁ˙āB‚‡€˙ÍÁ˙b„uíāŪ[rÁ$Ķ8xü˙ˆ °P$bv/ˆÍŲąā92[<žŦų1‡y|Úüŋ ü_ūß ūđ˙:đŋøŋüüŋü?üoĀ˙Cüŋü¯Ę4íüĘäE}d"NE2vCW3’sĢÕĸ“‚%‹Z­ķ‡ÖęŊ~-ŌŲĩNTPáÃiŧä9ŋŸu\Q­'wÆ‚˙˙ Ā˙ĶĀ˙'üŸ ūO"šZŗĀ˙™ā˙zđ˙đė›}ā˙xđŋ6ø-øøŋLX“YnkĀ˙…ā˙Ē˙;€˙‡Y÷ĩ\˛Ō+ÎđNøŋ‘›3¨ƒģqč+1ßŊˆØøŋ ֞ĶČžČ¯‚žIwĀ˙ŖĀ˙7üoūßūū¯˙Ÿd•6ô‚˙9đ&ø̀˙G€˙ŊÁ˙ŠĖ-ûĖ%Š›Liņđ˙!fŲ5eFifƒ ĩÂP°7ë‡õũĢΌžũõëģū‰â˙ŅņĪûëū{XZü¯Žæ?É÷ŸŧĖĖė˙|ž˙ŋŋn‰ĶôÅļ‹ũ˙Ęûëūŗ|˙Õ÷×ũķũīzĨų˙wß_÷_Ë÷Īûëū‰âŸø'ū‰˙;ũ6ē†ĩü 7Ē‘“øXô$îĒPWiŦĐ0žR¨šËN¨xT$”\÷Õũ™ŒÜYu66ۊŗģ˙…Xŧ?G^FSöã%ę÷šE ×ũĸ•o{hꠍtV” !üLÍ7’;ī1ÃËĖØ´ëŠėåŽtöŦ ˛ہVÛĖ@K'ŨFZ$Ø˛ÕØSIÎėwà 4{Z9ǰ>‚ēöŪBSrP¤*ö×/CN?}‘ĩĮF$?û5;%A—ÔYPK‡uôø-´x}Í=üƒÆœNŖ'ĢbéáˆStWë]:.ņ‘Ŧ;Tåü:g•ĩy§AįúäĶ] …ôø–ƒ´-NŠÎĒIcŸŦBûŠÄPˇD‰pø_ĄtÜÔY'†ø—‡PĖ— H}ķ &9s0šg¨M§†‹SW…ÔOį8MxdCĪlîĻüķ8ÚĻ:š^œ¸„VŸBũo? v×Ѓ™+šôÁž•ORaĢS$9ū 2øÎ ŋ Q˜^Š _‰ŧ'VŖšÖ&ČŧŽ-ȟ‚ĸZ×"î‡=ēZ6 qK-QšüY”ÉėD!‹îĄ}ĶĶĐBądö‰Fˇ<Ķ‘ôÜhĸģ˛hæhUš™ū’Q˧ŠzGhBŪ zđÎ:4$”|úšJTp3Y`ũDHb3= Ų{mĨlí(_vĖ9ę9ۅë!íK×QՇ“¨đî5”å4Ú8°ŠĖI#ˇ˜ôŨ~Oímxš´ĘšöHÔĶį/˛č÷&úĶû$?Ü>‹×PžĮĢúņ AŧĖÛ¯ô‘”͍€Âĸ>БC™ņ¯Ũ҇Û(iA3:uķĘŨ4mÛ[ā"˜D-īė§nŗyēSĨ†Ō@ úõn/‰­xEuO^yÜP~ÂÍûüÄĘ^^wéV^ãŒ'/•hGīFԚ*O§nI÷ ĄŠ…ŋE(†ũ`c€ėôÃŅao Ä/ŗA¯Õ Ål|З[•čÖÔ@Ô-žŨ‘ߊî'ī@w'ųĄûģīŖK¯‡ĄĒ[į‘ˆx!ꩀBģ& 1ĢlŲĖÉjÄ|ĸ3ų’ F­ŧŖž;¨OĶkē6ŋšœš™Ļ(ÚԜŅît֛‹ä'ÎŲgÍöíFŽ.(âĻ&Jģ}qMgPĪK}2ŪĮ˜ÍžOŅT˙ (õŠ8ĸšŅm[5ß°•PĩjŠŸ¤‡’žĐŌējúád6¯ÜÜʏ2åÕ{öķãUoķlįiŪtÄV^_;œß3ŽWÜd@ÖĻ…ÛÛ艝ŋŠãĮ_äyŅ/FŨ. I-LCS¯§ĄŨAč”Ez8/N(i9X(ž!=×ü7Öĸžz3ô{ŌrĄXžũ/AŨĸ.Tđ§UÍŽj˛ĩP oÛljČTā~r4Ũ˜ŧÄK¨‰į&j´¯€n=…îW*§šÍî´Ú9Œ–äŊ ģ6ē“O1Ãí\4[LĻ#Ī_—ĐéqY¨ūĐRôė×áPû^ļ]@sŊûQŒž9jŦ‘DwCšĐĶŦ¨zØ[4æe5 ÜEWČŽŖU­"^fė}^›Ôņ^§ķš/)¯§ú€j7đĖũ^?ŗ‘§Wď2)§īÜĸ™Æ4Îí$]~8Œ$ĒÚ˛õqW‘ÆÕÅČrĖbļXĨeGwí „b™ųB™ĶˇĐwƒEčD–PvūmĄŧķ áÁk…2ŗĄû{8tIW ņ‹–ĸķ2´}į]öIČ5KÂbōÍg8ĩ~x€zfŖAņö4ąY‡Ö4ÛŅ §ÆĐķ2†´RoõPą§âķČ´ž[Ŧlc˛°‹G'Ÿ˙@M‰EčklPãbûiŧ%:¸y*ŖŒî;œFkQÃē•(u?ösįëlĒ4—fŊפŊüčŊĒü¤4^ët6¯Ž*ÎOH¯āÍUjy‹­ø)"K^oW/ų”Ą ĒčąŨûčú ŖÉņą‹ŲSsoĄ!ŽIČZO„vĄR‡=čîŧ1¨oé0ôķczĄkƒŪœ"ÂÁözB9‹ũBÉîBŠwßŅ“ę3čÆČ,t+ŗ]ē9­W„gę‹L‡ÖøšĶ+?×Ņģ+ŅG‚$ÚŦ‹–älĸ‹ŅFōôö RwkŲ¸í5{st1 :„Ũõõįę~z…æĪ3@į=Đõ_ʨĮž]õĘ@j[PjËp„œōØØ)M$î~-Ũ~~2Ŋ횞—Íöã‡|Jæå6„ķƒt-x…Q¯ų‘īŒøqēåŧŪܧŧÎU^Js'mŲ Cĩ‡Ķ%?Αnũ•ÖqŪíė÷Mŋ‘UĮL´Fé;Ęiy‰Ї#^LÕ^ύŠLĩo¨@OØNĄd}<ú‘é†~šĐŗŧ¨=%]Ē›ˆoZĒÂvÜ>ɝgF-"_Ķä%hKT;}ayž~ Qĸŋœ†Ō+VŌ÷¯BiOCMŧe@'gpTú°+ųžėë#üO,@õg…’J„Æĸ…ãŠPžAē;Ŋ‰nFīxĄˇCRQõ4üæ)ŌĮŦîåH:Ōģ—>ôĄͯčĨ=V´CĨŒŪļ—ĨĨJč]Ķ‹ôwĮ'^ņe ¯°ĸŸ>LGšWčÉÃĨtb˙7rrîĻÚhÃ/ė—ūČĮ#úŅ€˛îBÅ]Ū(ąŖĨ˜\CĨļgö]7C/¸dôŠûz˛QuĪIFk‡ĸú~{”ųųrŽ×a[{šļ1TãŌHšēîŊÛmÃKß?ĘģŨČ+ūžÄkTNäÕW‹ņĘŠQôZÎ,ē[ŌjŊ›E.&plĖĩƒ(¸åē–´Q8ėÄFĄĩÔXÖuÁ,4õ›<ĘÚēŨ='&”iJ¨ŦE-/_ĸ˛°2”"+†ŧK$Ļ^t’ÚęĢŦEÞČŌÃëüi´z-UrĻĨĶÚ+iôãˇôĮ‡dz=)šm}G#/ Ŗ3šČÁ¸Ûė„ûŌHęę&´Íæ:ipåÖOG™VËБÕīPTvŠ9ĀĄBæ:ßzĩ D×ėäQ‡×tŽv*Ēėr’ÎĄø‰šČo`‹ŧ·ę^lĄ§§ßĨ¯lķ*áNŧVY(?鰈74ŠäÍL4ųąfđ*hšķCĒå'Nd‚kØÛL Új{õ˛*øÖ ŠFä¤i›sS ­ū$…Ē— A?öŒĘhgĸ'§uЅÉr¨ÉŨUj°I:‹ˆAõŌb¸ ;J™‹ítÑz’sϧ|žSō}í’âéÛ5BzÅGšÆĻtęĘ1TâĀ RâƜX[Į~÷)B32ĸC)cQÁÎltĘÄ4 FnrĢ‘—Z<а"¨đ¨*ĒŨŽr‡čĄęz(īÍ'TĻuÅ,Œŧ"V##šÃĻ\IdėM¨IŦ*ÍHËĻ)đ#^6ķz ]ŧÉŠ<Ū\>”Ÿb~ƒ×W›ÎK…͊ŅötF¸-ÉKīg阴Hū3:3ī)úÃˇ?ū$ĸ'ļ:â T6D"yôavú•g…n´ŧCt‹#j:ĩE­ËBŗ,ļ°Īže3 ם ‰)¨ĖŽÔnVMœ^@ķ,ŽĐŗŖ,čÃ™ô†… -UœNËŠé¸ĢäčpgbĄˇK? ÎChÖmä-‰â´ŖQ\ûO4ëÕ4Jņ2ĖG ,ŋ!÷éČ{Ņp´ŗ6ËíAĮō dŋģ(čí d:ށ­¯õfļŋĩ$ጿP“š!4pŦmßÉ+~YΏûZ1å~œį-GßæZÛyåĒzÚ,“Geדö3ėí™ûP°Â(tūÃGĄøÉÛBãm¤Ûy6ģH¯­ÖČCEûTĐ=—ߨĢÎUâÄ}§¨ä¨?Ę4ŗDÁŗV §Tiö÷VNîš69įÁQTģ”yYIc¯@ŋnāKë_´ŌüQyÔņë Ē3Ŗœ´FN„;\f-æŗ.kö°ßu×ĸ…Ŗį‰ĩČ˙ęj´ÔmySÄ~ž„äôß yq]Äē/Fsn\Gī`ŊBČś(.k ^ ‰Æ‰oc÷Ū^Mä&]§’gR'ûkÔ#؟rÎîüā׹ŧVŅ~ŒŠ*oĀĩō8į6ÄwōŖ¸úĖ+›ĖÖ$iŖ‘ē‹$Jē|ŨÜ*T´ņšžĄëöŋ'AlHŊ%Zh¤RcŽĸ ÁOûg!:õd -mDšãÛPĻzJēöŲž^ÍnûUDļë= ēĨÎtEÂ-jmķZÜÛJ}žëPģûKI‹Ū2škäßb÷t9ąīÚ+Аˇ–Č,)-6úŒ–nûˆ–ÉX#Á¤>e*qÅŠûĸņą.ČŠÉŲŦC†žËĐÜŨb(Ôô#ōk=€EU!Å :Ŧ×įlŽhÂSŌv܄ÎǝĸĄÖ‡č•{üpÛ;ŧöå0^kņ>Ū°âo??œŸ˛’×kV¤_S’hĐÉĸũŽ ŲĘ4dPoÍRáHã ĄõĨM4~L(5zD´›Ž˛‰ŪKģÚ°ĘÅ["žņęė>ŠHMĒ~ U„,FūuėÃ{ë¸\ŸOäģÜ~Ē۝D‡jŪ"7ö Ļ“vūĸ˛ŽķČÆˆbÁÄŗ1ėžK’ėŸtd<øšÁÕ#˙§AhvúV4ĮtbâĒĐl/k4ķō~¤ģ iWŊEŖŸ+ĄY=[‘˛Ģ5›f¨ËŪ*|‰f/ëBfs´Y~Ô v˛'¸gŦÍõŦGîqĸŽ/&ĐŗŊôÃ÷,^ąÔîû…šãĮ8ۏKāc[yM['ú6Z–†Ŋᒕ´ŧ#_IAōÖ U—' Ķms¨ÁŊ äūŧ…DkØ9ÆĶ~ZŽß$ĸ6§‘čæŊ0tÍëj[S‰÷¤Ą¸ÔHĩP‰‰Œl /§ŌåT5î2žÁ“ÚxŸŖŠYĢIæĩ@.ų¸ ģÆâ,ûxŲīÅČõ3šįhŒ Ü$ĐäōˆŲ(‹,ŸĪC:ŽwИ–=ėĮŸ/Ųg—Y.<„].ųZ0v¤{Rrû>RÍˆLe:Ķ?pz6ûIÚŊ]ä‚ŅjĒ6j6 (¤ÅĖ=ÚŖ¤ĮK—čķÃ$ôyņī;ųAõļüØ3 .~åGžôĻ÷6gŌĀÅwĖ lÄPāé7¨Ņ#ũļŌĒ<|"Ô{ Ox ;ƒ43ã3k¸ĮĐķfŠčČĀJzôĄm_WĶį‹žĶ/×čG‡ ôIėdzÕĶûÚĩ´7ī ũĩå m—ųBÃdpSŌôŅ^ƒ ¨u[žPVf°pėėBSŋ0Úąī!ŊؗK˛ču4Oé ų´8€}!7ímnFŠs¨pĘîZ†üU> a&­lÔĄ'lܚQŦļøsî•SQ‰ĩ⎄ņ$Øš…œJ× ĘļŸY%į˃EvfR:ûvŽZbŨ\T [Į•% ÚȰž ŠÜ-D‹ÆŗŧÎ,V%ã%ÛKsÉėeHÍj’3ŊÂū‘¸ĀŽŲÄÜJ8Á$/ü#:j_Lŧ´gSårszüíiäč—ëčĢŗŲôšĶ/úrĩ>å”ͤŪFš4O‹ž0ųD$MĸZŗO°š.(lÕ,ÔføZ(ŲS,ųŠM8yÉ~œU?Jk4¯”íÎKxG9Ë>Ō}w{)QšO~ˆ‚\ĄŒÂ"T4ļEĒ|F*ÍƒŲ›%ˆ}tü5ûđĮ0v‡Í$v¨Ÿ5S2Īûd˗>2íĒ"'UÉõ~Ņg 7b¯yô"ũPdąÚŨ<ƒfo{„°„š-ūFėGÚ_ûŲæ uė1röG¨82^ŋé8̞o{°åQ=ŦYļģ`ęJv{R);Û –ŒŠ1ĨcĖĨi02 ­kĶĮōĢčGĩ;ô­Fm›$FĶ×yŅŊ.ųt–ĸPG‚땈íÜolt§ ŋį‚.ymJŒÜ#”šļN8"(…_™ėČΝ)á™ā/ŧļ-哞‘ģķ°‘r™fŖŲû Ũ´Qrˆ:Žc‡ÖŨČAÚ{{eōfd_<é8`ËãģE‰Û) _mNJŋ ˇž‘°U›¸gļ+ŸîŽa+Z>#ŊŽz„ Î"/d~ßšeh °ũ!ČY!YšŧC# H#p=äԊ‹DÚA>HąŠ”=(ldŠ:jŲũ.¤tcû^R‹Yōn!ЊM*ĐĖoËhÃī z?O>zvŨ¸HsbfSß;ķč˜÷ dVH$sgHYíyQ-­—‹\ŦAŲįöĸö…“ŅųFcTģŽ÷ž6‹wĶßČÛšŊáuægŅßų$Ôې=ítÔ˜ˆĻ&=FvûKPāÂ#čāŪpäom°=ĖáņyhķÎxäyô$[3(†‹K+$e:舉c(ōĨ*ę×HŌÂ›Ė™Œul/@’ hČøWH•… ÂŅŲ—(x×R´nC-˛ˇ?ëD öW ÍUįŅQåL´)â YžŊūŨœ­9:ˆ} }éÖ=G׹(4›lRRĮÖû4ö~íĩĄgczgÍeÚy_…6VQ9ZāČ4UuądßŗÜÅml™ŲR4Rē mģuĨ8=GëŖÜДÁ6|PŽ ŋæŗ&?=ô3?BŨšíC  V´ŧɍž=UJĪyEPę’AŗÎäPƒĢßjŖĪ %­.äT} mz< Ųī‰AĖ‚nä”÷íđTF*KŦ؆īųāá›ø•ļwųŠ3æķōčĻOuĩ=ÚHøØųĪ÷CĮÆĸôĩ7QŊöktÅę9:Ģ1Ĩļڠ؅(čœŌÚšŸUĒĒ"ŸŌŽQÁnęļ™Ō5OsŠĄY?iéF֘SA¨šĨČ}īVbéŖAbúŽĮ/˜ë˙°ĨļėÊl@åö—ü$Ü_ŒŽjûŖĸRčTĪ'”ŧŊyë¯@ĶĻũfߝĀ>Ž6B*Ŋ l\œaŦ§RëžQËĀFęû|͔™L+u—Ōãą48c&õˆcb*Đâų.(ôL% æ —ãųhNčk¤ˇ`1š¸lkŖmN„~åˇö}ág. åĩ+Zč-ķäëĨ$R:pŗôGeĨ5¨>wĒË+Eí+fĸ{ūŅ-Į§¨YÖWŽGË͗!Ũ ;E\ūĒ,×@ņj9âuXMgˇÎ§–ō¨zMé/IGŠP;‹atÁœ^Ęn'Ņm!‚Ž!+93˙7ĖÉSߐøÜ4äyŨiĒ"ģŅå‚áčQæTa(:{1™ŧÉ&ögŅ 6ĪüsKī.ŲtȋÔ^Фō_QO}ŋd%u[Ŋ„Z-§ ÁÚAųhv} ĢmA‡×ĖBî5~H?rÛAĖŲžV$*R’îˆØË/›ú„×;ũ˜>œ8œŽp4`}žîCûuŸĄKģŋ WÕRčķ¯*ôY¨ƒžž FŋŠvĄ3œŅũ÷ˆüTB!מ!•IWˆÚÜx:–fR“ãŖ¨•šõZMUlĨ‡ŠiRC*åĩoĶFËąô"?’6Ũ–§q+_Ķ 3ŨÉ'7Rũå™&:Æôėí`ËĮīGKŸFI–čåî!BÉ7rB‰7Ačú„u(A&fFHrõöĶã$ļŪīē¨äë%ĸyõ;9ũ{ 5öŪA}tĸč¸}jС—sß÷ą ĨŅ™(9Īŋ…âWėĨI<#ŊWœû2ą’nˇ¸EŠ)ņ3CŪņƒ:ŌTģZxŲMé;…DŨĒBɄÂ‘+…ĒÅSâ…#îu •ã넲׏ÅĄ×m;ߊbæi#‡ųÜŊģãÉû_ąT]Ī›:$Ļ͐W…´ČMŸ^y1ģļ“W–<ĪM?͏ŦCßū@´ét-˛MĻ+×#:=ā u=×DMĨŖHë„Ilô „ü„ŨčŌŪŠBŠû„ĘOĶ…2+šŅ%'! š„ˎ_E‚ÚĨhØÁė$Š7ĸ2%?.á¸.ššŨ*†÷$Ŗš\†9fˇn÷FoQJˆ :}e.Ē4Ŋ‚Â2üY^&ŸTv)Rƒ‡Ū´)ĕ×P1æ§.íĄ¯r7ĐšAŲ‹."TxŋH(&Ņ'ÔYv@hĄ‘.´J‰ĸŲ›„Ļ‹ŋ'ø/j>NĘJMEŨ˜ m÷u؛ˆ›ōZDJ<éˆkĄtęĩĪôÄĩ#ôÂS^aÃOų=ŸŸîČ;=_ÎO]pWW1ĻoøPbTEKfŅBí=ôÆãtzWō-éŪFuްÂ1ŗĖL8¨įƒpĖ…›BĨŠčƒĮ-TōģĄ|\ĐÜ`ļøJ0[J‡˛5;G0‰ÃƒZī!8=dģĪįÔĐ1(nŌ=TŸŌ…ō•w 8ī-(čH=~lU >H]ņãe­ōöé#xárzeō"R;š*—Ŗī9ķ„ZŠ6BŗŪ#™tžĐåũĄ“s‰KlNŲ÷Q8vUƒPļ<5{œAΆėų Æ|Æ 2Íx.iÜ"G'-U§EĨOéõfŪāÅ~}˙1ū EhSĮ/ĪIá'&NāÅw˙ĸ] %éÞ/ŧäYŽķ!‡7ÉUæõđú<ΆŽŽīD͇Å^Úĩmf u’…CŠ‹Đ­kĘ(+QĨfŽCIΗЂŲĐę^ųF )Úר;…Đđ§~ČđĢZ‡*iÔøã:uč#ÚąE™Üą|Ö}E­Ev4s] ?Ži“ėŪĩûũķë4Õģ˛9ŨœŠúô4…#ú„†Ķ2…BáUáfÂ%B‡‹^BŗÂÉziBÅ?]¨‡œAŅ]3Âģ3ÜĐ)N\.SIJÆ\ĨîcŌ§øą1üĒĮU|Bäu>ˇÂ›OĘ]ËûēúņhQę(zž~PöAˆĐ°Č_¸„ę wí#ÜĨ0U¸ãē^;#t6ļÚ>Ų.ģh1ęŲv…Ôžes㎠ū8hã1ëéÚŧ6úyô!ŪnŲ>\猝h[Í7 Z˗}z‡‰íįíŒĻđŠ­+čįL-^včwŪ{ōOĖä‰D|Œ¸ŋåÚ[~đjoîų}ôãļ†pžLĐŖå­pq×DĄCqĒĐ>ßXčâW-´ŋm(´ û,4ī^$œæę%d^ '[#œĀŊęŦhNc!vÎęlE¯#Ÿ EŽėåpkē>ö /g7ˆˇūæŋ ā‹‹Vũķüķ?Ī?˙gņŋõųgĶžūįųįw}˙<˙üOü˙Ä?ņOü˙a ķį‰ŦðQäĸŪ9ēĩ6ŒÖųĖKĩ›đã?:ōŖęxÍ[ymŧXÚTz•šĶuũqäTį'îÖĄÁė÷‹‰h[ęvtôå&ttS, ,ëAÎáļȲđ(š‘7éĮÄ#EKöVÁ'ļqŅ!ær’=i/ #ęŠūq *u'‰Ô ŠČ˔áT]zŨžY›ú˙(Ą;Ī> ™XZįv‹6[Ņ,ũW4ėb#u[—G'øO'?Lˆu‰ÍoĪF.íƒŅŽ‚hOËoyEųŸD1Í)čČāīhK™-˛ ėĐŦˆˆņ?‚&l˙ˆô7{°ßT‹ŲĄįX’5æ4•œ@eZ÷“Ëū äĸØ'rûōX*3§SwĪĄL×Wēôģ=ō&‹–_hϧģ†ŅõÛ4~ÆBzüņēüUĩŦk"w ¯rĪ[˛]-ŲHãËM¤a=GĒļ~8Åĩ ‹é΍ 4cŽÍēąæ…ĐS‹gŅ”ŗ…ôPąŨöú3e<ĢHN ˇ õÛ vnōöÖĘyHgæ)´ôqŠuĨüē‚ÂoFn°F˜oo‘LÍ46åä)ļ*r,Ģũā q ›LNôˇ“c&ķ…E+QĒ~4Ž;cĶOĨũĮĶAki´Á"ę#y„*Ũ%cWÍdŽx—# _W=ņ,Ljų„2tîĸĒ ÔļGˆnN CÍR(_M ũŌGžÁž(9v*r<‹ŌŊN í#O!ãĻiHf—›L=8íAB">'–Œ–9I*JĶ‘ÕŠîą2:Nž”šHž +?l¤Ą_NĶŖ“Ũhō\;Zđô=ÛĸB+nŽ ŠÅëiô™ytÛĘtĒŋū i1Ęcļ~{ŎŠ~Åļ­¸6ŒG9mPŦÔ/äˇé)b‚‡ĸĄŠė‘ŗ{™˛ Nĩ4›œō3¤3>ĒЈŪÕ4=ÅV¨Ų߁šžE#î?!C§¸ĶaÎÔeK=]€,Šæã0áĶɎ}ú•­ļąEÖųãŅI=?T¯‘‹JG'ĸܗ§QKZ.ē]'DwzĘЕÍĪŸm‚Ē'&ŖzG#t-œĸ+FoPšķY¨?éĄB$[ŪÎf÷eŨ#T—u’‚ícŠyį,ēÃâ <<”z›xŅØ™*4úQšŅxÆĢ8ŌÂ~J9U7š÷<˜Ë ëė s>6Sš>ž$KM"Â=¯‰¤u7ķĨ¨øßC‡õ8ä}8ÍØõ™¯DfmQėëøũLĪëͤķŽ*]vå,MޏJģž'Ņ~ÛˇBĩķ“QåöA[9ŧŒEÖØQ'ؓŖ&<#Œ–9{ėäc|ųx.@§—8 Ú„S¨´R´ĩŖ:Ũ]čâ|)t‹¯B_‡mDooŖ Ģtąé0ēŊŊ]Y‹PɛQ(lģšņą1ü–ęÄ1ŋ÷ĮrŨë.’ĻDOēčãZļCƒæ‡<§§ēPĸ”M[‡Ķs›&Ō|3qšũQŒoj¤c•¨0g=Ú¨M^ũŽ&y_šūˇ)ĸĖ žŗ¯ė`íĨ‡"-™t¸Í mUGķ]ĘĐĻY!ĩ)™ b†­ĸ˛Ŋ4ŦŅ6ŸĄũq1ü¸ņ+Ņ'š hWĮBĻŪ¯žJE7ĐõmsŠOK ž;“Î9RGJÎeŖ^¸ õŦį(lí^T1ŗ S7t:!ˇ¸ J…šÍĻĄO'ąP~š“Pi7úš=ŨUđFĪC~ ;Ķ|ŅŠZ´ôÉ 4îÉ/öŽÎ$AŪŲn’1ō+•s]IŦ ø'-F¯Ą-ôއ}ĒčCŸÆŽŖ=ąhãB3Zîŗ…&âįô°ĸuJxH>žR Š^w¸¨°;ėŠĮ.ėŊėÕD[öÉÜzäPT‰Bå%Īk´âw ō3yŠŨ/FŖT1ĻŖ×Pĩ$mģ]ŠŪ=0Wœ6“ˇü厎VŪa‹GÔPiãQtĪ+ÍJ~C‹Ę­fŅ(‹™ÔúG.u7˜—ĒŠÆhBgîŖŧ'cQĻ’ʞ‰Î-} 'ĩ G­PN0LŽI1Jî=Š^z† îy(!ē ™m›Įū|=™]ûų*ņĘßNÍ××Ķ={&Ķ +Ú ÉŌvKé÷‰%ŧŒ˛/w4Ž—w„ū‘ŲL?'éŌ×)Cikå|ZĐ5ú¯œDĩjn’‹ž ŒÍŸ:öũŒÜvüFŪŽČõē žšĨY,Aßl‘ëõčڑtiOXĘN?gD.œĨÔšk­_ĒÄÍ å§š ­/BŪ.j=/™&K| tķCzũŠ­1JŖ™˛âô@ītēôŪ>"ēî 8Ũ4=˙yš+Ũ<HĄÃyT×'ƒžd ĨfGÖV 'ŋlĒop@ßdŽ æŪW(Īl1ŠhtDcn|bcĻ`vˆŅ’zĻZ §tWž%͞ĘĶ&˜{ãôĪÂü`¯}‡WŌ{ÄËL?ĪK“F^ÖĨ~ŧkNËūÔ҃-ÍtJŸ4š8ŗĮ.ėF3VžD ōų(ëÔn”Zį†ō?H ÖŊKQI° ʨœ‰2cw#ŸÂl$nļŸ ņmāĒÆÆŅQ¤—ĻŪ,æĨß˙â­6Ŋ@ҝ—°GLŌčdŗ•4üg5ŊdEo$xĶÚしŦēËÍŧȋU­âĨæûņRB3úÂô"å?tĐd“V:÷ĶŌ¨;ŨčÉŖ%Ģ&ĸáMtžŋ]ŋŽģžFŊƒGĄG>I¨é^ "Ä ;´l•gËwå1[ęôHųŽ{tË5ú4Wž×?wEÕ|bWŦˇ§ƒ,–ĐčOŖhũŖ7ôŽä%z{ŨDúJû*}—)FŸžŖåæSčč‡ų‚‚Ul)û ōŪŽf×ŧAÕĮĐIÄ”Bw75 ÷–e¨ģú%Ę=ĪĄŖ#ĐϝīŅŦåÉHēŗa’Ėoô“ ø’€š‹H‡ ĸ’Á‡¨ģE&Nĸ™sVĐKfĶĮ ƒé›Ąé×M˛ŧ„˛&/ŖcEjÚŅ~>ÍũęJ}_ž#7ī*˛ÁƒUĐ´Š,Tŧúz,ž>VA?ÄZ„r"SáČxeá°ã/…b}¨MĪ E?ŌG%‘ėÎķ$&øŨb@īëÚņÔĻĄ“1ĮØÂOÎäÅģ‡ôø4JKĐ÷'Žķ2bYüā\/^nÆS^Ücm:PHŠ÷ĻõĄĄ‘/˛Ø54jČIdīUŒĪ—EQÃÆĸŦ“ķQi>‹2­ÖŖ ˇwÉ& 3mūŧMvígãúns%ƒ‡“—1 Qw'[—h’ ö éÜ,AGΊĨŗ‹ŪĶø'zaģíqč 7üĐ{x)íŸĒEáa´Qp&ĘĪĨëīļ“žÃO˜ĮQKĐāįãĐ]7ÔüpzĒž,”*Qjėęręz?ęÎø&äļ]¨rDÁ#^ A*_ÉŽ$'~_îÆ]ŠA%/،ĸ@Ē&)A“Ũ,iÛ­Cü ŠD~ˆŲ/~øÍ2^1ޘ¯ÚKKž=Ą:S☋%;j”2Ž„FĮŧCSGĢŖeīũĐ;!ōŨŖ€adŠ2HĖESÃ,sëLzj;Z#”dĢZr÷ mHä;Jfp—öę3§dö3O×įO“ēÄCtj˙Nšö,™ō%ŖiЧ¸-ôÆ\OÚy3’œ*Ĩ‡VõRg}ŌÛ­Čå/Ėe‹AÆ7æĸĜ|t%ęRÆPá„ę‹Bķ"UĄIéZĄå°B͜1čö t|´;ŦåEî ^Ԍ7ŠŧŪĮ3į"ęOŅpî<áŧ§'”Ëéũ#ūŧœøg^ŖH‹×s˜×øvœ¯ŋEĢãdŠû“q$Lw#;íeÖTŗO“ēØV…ũėŗ¯1HyFĒÉmėÙ'Ų—1ģŲ†áŅāÖUhÁË_ČĶ*äž&Ξß{žyrąœkē]be+ĻÍĨų°ĨũlÖķKėR÷"ŽĐ´“J}Rƒ^Ą‰Ē+hÆR7š.íBķU÷WŌüû5tˇėęčEŨÚLR?ĪTnÎGRüEtŦŽA-JC…˛—į u]?Ͳ…ÆįBķģEBÍɧĐķ;Ö(ņB'ÛhHŪZōô„F+/cÕÁŖųCPũŗÍČöl‚ -b;õÖzA[|ōķ?fE¯gĮĢų?ĸ}uĐŗŧ;HsméF]5ō(g?gžø•i/ Ēåm‘ČM9ƒ5{$Á6=~ÆÖÉWŗžGŨŲŖËĻ Ĩf;d(ZŒ&,‡†Ī-aSíg=˛ė’ÆīėtŨŸŦ/ëĀŽ?÷šŧqļˆ?M|v Ŗ‡ŖžŽŅÃũ_iÂũ'4úÚßõ†žqYOĶ'mĸÁĐyüŠrúk˛ö­ˇĩa 5Ō皌2ŪōčémĄÂNCĄŽšģĐČĖ[h~Wh1§PŗČõ/ŗAÕŨ_Ø_‡%I[V(Ē›ËKŒØÎ[Ũí@ 6HEšČŠß¤kÆ<¤5k¯ĐGsSø!i°–ÖķÃZĶ×/6Ķ ŗčYÉšŨÖKįošGž>~DŽ}[E{–’ÁÅkšžgßŲŖĄylôƒvYˆÛĒہŒRMæ°×6ždË4‡˛­{oŗī~˙f/>Ę:ĘqĖÚĮ#‰zŧ'Ų0ÍˆÔ ũFŽlQŖcũmŠũ&5ēįOÚēÆĢÅĐBG4įŲ\ëūˆn ëŖ3”Ô¨ÜĘvîû6 Ļ?~'ŌĒëDi&ÆčÖEOĄäÔbĄÆâQB“rOĄų\ĄĀxžpŦX z9w=ʔx†$ČRŌpW‹&ĢÅđ’'jx4­ Ų7J´Î܇ô[LįĀžKī¯ĄŸwŅĪŨô]Ņ[úqy+ŊĶL/mĸį*õiÍÅ34ėķtĒ{ԅ´Z%F?O2râƒŲŨ?ØĢĄÛŲO]æė—ģ̑ܤũIV\fņT V–8°­'Î Ų>Hũq{e_2“>Ŧ—¤ Tü"Ą’ķwԑ҉tJB*õpûLũã;idõNzzú1ZH3œčŽŊč´}†t°˜;IŲYÁŦÛØËV‹$ĐD[otdß T[؉'÷ Uö\NuLˆļ_âņ“…ãŋüDo‡ ”]ۀd[XRĄCã6Ú7vo<û4›Ō4s yEZvĻã÷ҏÎ<Ę+\Ĩ%ŸÖĶü§i%ZIų°ĘĢēŌō°Z´ā=žķ•NŪ=™ėČßRĢũæ}ú&›‡&eÕŖųáhÁnC4eV’§M,ŅģšÎc\e°G6­@Ŗ~ ‘Ãw¤Ų(ɞœŋ(îÚL^Ĩ\#‹ļV tJüSēf5ĻnsŅ(‡ķ4sÆhZ8Ų†ÆSĨį_SŊĖ-p."ЎG°ãK6ą1ŲĒ@ą¨$RŨÖ4J:Õ ĩC3„(¨@8ķĖaáäôuBņ‰ˆ3Ų‡tį&ņîyt™Ŋe´˜̘†ŽŦa+ĘWGŠRsŠyž+]Z5‘Îm3ĸķŪĻĶpƘf]ŧJķ§ĨŌŦBzjĐēq7šˇ>Š;rŦ“š×sŠ-§ ČdL Ú]LЎûO‘ËũeČžx'˛öMfûunŗéA˙?!šė‘ h JANQ÷É!Éu9ŦŠ[“W°KđgībĒž‚īp¤LÂ>ęQWMņ4IbxāKC.QŖėST:ĒÄĒŦä۝aßúNBÖíž(xö”N‡ĄĘÄ­čfÛZôÖkŸpx\…p‚Ívá”iŪBm—BĄÄ‚ Tŧö8{īP!9čCˇũĸˇŋ­äĩÛBQąø äņ´)m]ÎČĶN˛baŲöŅ—KŦ"÷­¤f­éÁÆ´`a=Åh҃÷ļŅŲbōg„—¤šĪ8U=dã^ sĨīČëÆ;´šZ 99Ė@‹Ĩĸš• и—‘ėËķė+ߤ°ĩŲVFĸÅųhé ed0Ŗ)_DCßņHIV’ņ>—ÄžĨ&Ŋ˜úÔ Ŗ‡„įiŒŅ)<ԇŽŋŠB§3TšTŸ,ÎËN:W†Æ¤4#oV %\˛AE~–¨ĄMŨ¨ŗGw$Q˙šŸBšĮēBšīģҝĐĶč:JDŅķLØKƓ3JZ4ļd}]SÆë_´G*›Qūž-h˙ŸLdĖ=`ī9;ąWW°#ŗÕ8éīkIWq"=ŧx­J™Dkĸ6ŌÃģ\é°wt„F6‰ŋžŗ>4š -™ŒĻÜ­G —!WÍ(Øx2r;táŽĢhâ›ãˆ5Ŋ†Ļ–y kJhãΛhŸX":đcÚqār>҆,5Ö#ëʧėUÃd߯j:AM—mˤû}8bh„åzå-ĸīˇĶõkŋQém[DŖNČą÷öØ ķØ§(|Ķ ”?Ë ]ĐOC´W n…UčU{2zßሞŊNAį_頚ÚũčĐ÷Lv­Ã.*YŅB‹ŸēđCRxãP%ôr™=:_t ßVƒ"õëQ˜˜ ØK‘ũ_ļĘęqņb¨Ŋģ[ZAķtÆŅÄ3!tÚ Ē×\JNnyÉm:ĢÆ†TQ$õÙĮˇ …§˙ Cú(˜˙„6îûŠvü’Dą% čX„ŠŦvD1/– ¤ų™Č;¨ŲlHA23ąAbėFãjN~pųę\C…Z§čęų&4¸ĖŠ›:ĐČQ„&–9Ō´ Ũ4Ąu,eĪĮîlÜĪŨh¨éO´Í"%¤.GÕų¨S9ĩ=ŌDįą3jYįŠÎĪFÕ[^ĸ“ŪĢŅŽe›Ø8)Sԟ“B .e͎7ĮņŖĻũAuÍŅYÉÁčD§Ę>Š‹Ēē PĻZō`˛7šęøSä]Â*ē~ür6o=x÷!mQHî/s'Kco ÚVē˛ ;´âĒ‹ČØŪ 9üqD‡RÁkķPrtJ™1ņž{PuvJė|„‚ú둋Žûŧ6I­&Ú!)$˛5›JOūN—‘ôPa1ÔCÃĘ hÁ"ķ)ÆåDĐãM´ĐK…æ|_Ní—K°qVzR û|í94S}ЏâƒÎ˜}G O›ĐY10›Ø#Tåø e;îDGčũS1â~Lœ¤ •\‹iæ'L;– hßũzô.`+ēešŠēUŦŅmÛFt+:åüÔAs[UŲúņYˁU)äânEęšš†ĩ+ĐHžēĩ0tœĖMrt÷MfPí$6ą1یFîˇЎywQÎÃ4$ŌãPYür”xq(*Øā‰ ÚûŅúûšl׏Gĸ÷›HA+՝3‘.Ú¯JÃOŌĶé´ĩ—Đ÷?ĮŌ'ã‹éõČíô ŋ˜šŧĸš:‹iƙzJ,‘æ äéFö7šœ8šHl™Īw }…’ãėQųÛҍšŋ ĩíkD—.n@Eˇ´Đą¨\äĢaØÕ×Ų)Ņ—o—Čû)÷høļ:šøS›g­sš!T¸ēG(é%„jŘ@”ØX€æ÷ˇ˛õ‡ĢČÜ jtdÂ]jÜLŗåĻҌ}:4ŧ]›ÎęBč¯_ܚ66Ėđ˛‚ēęŲZ’ä#Ņy WtaSĘm?‚5LG›~NBS&„˛‡Už'+č :EęFOLŖyŽ9ô"}N_ĪXÁËÉķRŋx­ūsŧJg/§ŠžšN/ˇ]§Uv>´4͎žIũ¤įĐq’Ą$#8“ķįÅ> kGÁŠúč¤ß;$˛ũˆÚũˇĄŽ%;QMÜvˇō˛}Âfõ ŗ~,´!)å=Tęgščp›ī•ĸųŊ‘“ŋ Gœy 6ÛY(ÅÜFįŗļ mŧzĐŽė^-éķã‡ÕōÖR„Ÿjcƛŋėã5oNãĨGŨĻS^ŅK=ĩ´*|ŸëM…q‹H-öã^FŠą9ŋc}oŠ’°Bå­ē¨ũdj×ū…ˆÆt¨* ĩÅ\šŗš¨ˇU“ĮT=ā9 “ēG#ŧ:¨o[ˆPę­˛Pĸŧ}|ō]}=陃äŽOĮ"ĒĨ8‚úO=JĶsP‘O8=7ümũ†)o ÃíÚĮE˛ĮŲ:‰cH“UCkĄ3["Đŗŗ_҇%§ĐUũmčđŗ­hėÁėô „9¤BÎŽÎ%%s’ČĶH'j}x>uģPK]š:iøØ.Úö͎WŲ¯Ę Måį›—ņĶûķ– Nü¤į/xšEöôÍÅlzŅæ+ÍÜ;œÎüu“y*ęíÍ–<ëCŒäG´§ĮEėéF•ŖP‰w JŠŒBSîLgŗžlŲ$š†]Tfo2ÔÜĻ{jЕnĶč¨ÍīŅŗÕčōge”ëi™^6æČÛŧ…šį\¤G˲)õ˜@2ŖĪebé÷irôĶē=´Ĩ/†F{fĶ™˛5äÄ6ž ōuEz5(ÔÔ e‚ЇÅBąr]tsķG”5?9Á9)5ö4›fQÅæ_@˛AĐčįeHõä#d9Iīõe]៧ōj!´Âe¯ė8•˜?âq×;žĸÆ]eų}F´˙}ؒK‹ß¸ŌÕûsIÃčM"§åvlŠR#R7 %;V#w‰h¯žō+´As/:ą7|’Ø}ļ…œlŖÉņŽ\z&GrõWPņ#ŖÉ)VЉŅJŽ;b?’ŧ“=´g=9î2œN-YBÃ$ŪŅŗĖa^L~?˛Đˆąō*¯ēc%¯,Jßĩí¤Å{ŠĶđOdęŦˇlŪŧhúá>¨?f蚔ú¸™ĸöëŅ‹ĒĨ¨‚/ÍD۝´PĐĢ(”$~՟û&_į$T;ąK8ĸčpHž攪ČĻ{(IL Ĩ%Ŋx­õ<’ß͛×yķzŠöŧúHŽ—mą§īžhŅV"IŖw;SmË5$ÖĘēVīĨ3ģÛ"ũ)ąMˆoB6¨i_ĖūšrŒŊĢeĘ.q\AŧÕ[HíRšëâOÚz‘ÜsŸšBM6ōũ áHˇą¨ŠzšY~Îē|ŠšļĶ#'ŋRūúG^Lü.¯ņʉ7Nėâ=gđ“]Ây ŋ ø{kZ>A—šJŠ“°{+ØåōȸĻ;5ôųĄÛęŪč–ōAtŅ7q†PFöÄtŖ÷%Ķ…ŌG7u×bĄë#ĄŪáŨ#ÂåKû…–GĐËí#‘Qđ=Ē‘u€>^]ĖkYņ“úˇņjĩü¸|#~XÔa^îb?/16…ŪN¯ĄŠĢĐu"G°æ rdwÎy +<5…ŊËļēK°Į¤?ą›ˇd’%Žcn9ą=‹ÜŪŨLtēę™ĮŅNhxV.r=´C8ÖŽ•ģ=d[ĸæŅŦA?/W°7āõĻÆđČ9ŽŸUz•Ÿķđ;o'ôæ3"yåßoéĶ˙W)w˙ upœD‰=DļÃ4OwŠ~đpžŸO*ĸ[æa—n%ĄŽX׃elĖéZQcÉCîŒ:TkM¤VßΧ4ô$)IaëAũ Ŧ– ÉŽúú'Ū¯ßŪeƒTĢ=LŌˇnbžtž™e ąÂ0\Ņ_‚Ž˜.hģĨƒG-!0ęu—č5¸ēņ!n´˜EĨ. 6ÎaÁĩ7¨?¸‹  öģ Æu¤Ŗkx4<|/MRŠ MĻ7_ëØVmbōvÕ´ącĢ’ĪÅņʈNļY!§ĪjwjŪRH'ˇ“<쀖˙Ĩ-¨Ē;FđŊ)˜wö 6‹û‚'Jė…ŠļbÁč˜-TįĪ€×ą 8= ]å1hfĄĀ¨œo0e¨…„Ė-čâÄ3[2ĖvžáėŸË i+oÉyģŸžŖCĘxsåk–mōaÛŪSôŠŪSÅäBÚė{B\&Œ9gAæŽz¸úK íūãĐ˙q—VĒ0đ¸#*kü0Ĩ_‡Örŋ{ÎųsĪk¸§o°7ÄķÛø"×0ßvWĪp˜Ÿ4#cfš_ÍÕŅ3<Ø3ROÔøļū¤ŋ#–Íđ)ĀKÅ™ņđúƒ#=a~ û$‚7›2™X2‘Y…}O,Š' ßÖk&&˛“ü9[5ž´"ŪčjņB#ÃĄūŽĨũÁßāÕņd˙šDĄMÛ$qîÍ&ž­+’5ųä8Oü<‹›|4mF˛°›Åņ†zvôôŧÎ`¸ƒ÷ųøđp8Úcá ¤cąD16™0—ŗo°w¸7Øęŧŧ$ŒÂ7o_ÆLˆd“é>Gcã‘}ËDÍ`/îéBûARįŋ x;Âá0?H€āS+_CĄ=”oX”•âxCænXdĘ\?|aô‡Ø&Čmē6oĪ0?–s‰E}I_āŸį-˙ęí˛Ņ.~ˆģBŧ,äâ%WƒčėĻų&úē&dIÖeAŅC-‚ˎ…RÉč$ĸQgŦx‡‚ŨKčÂˇQWDÍDa(¸:ŧžâx˛~ãųAđÂOņk†!О@/ā+–„×ę ÷ƒ?|‹ŪlZĀˇËŒŽ¯Ģ(_M(ÕžžâūJæ‹xĒ? 17ĩĄŨ{zúFOō …ŋĶņX$7nĻÍDÔäĮ͘uæũĶąDōP1=ī žžė J%3Ķi“fÉT,15—ĶéŽ`×`0.ĒĪBN:"‰ąT$“áŖÉ1sÅũÛ1ė Å­x™HGÆĖÕú#ÜėE<ͯK‹øRŧp4JIG3XЧϖ ÷ ‡@RQ_|˛Ø.j풒ˆį^ГėôØ<ÁB­æ—Ãčßx-ĸhävE˛/™˜¸@@ …;oĪ.^1|ąčS8:9ËŪ°73ŅdĘäNBÄäd+šĪ,.‚ũĐží ķm|šN`3ÔLÚ—ĖæåũAđŠöĸ.|ÛhoÕõ<8<:ūmęéí m‘ õex&Eļęzd5x,ũ=};Ŧúv/Mø˙ų{ú5Ŧ¤°Gâ|&I,×ŋ§¸ž`~ôŒôÅÆcdŗ“æŌդ̺{`p0ÔUī.Ā# FÚLEbisŒOĻųčd2•Š%&xs|܌fįgsW¸;ē!ŧ ´ŋéĨņ:ûģ€đ*øŽA š‰ąH";W?É6I#.ĄŪđ^ĸĒd(Š:/Gr]s&öĘU4ŊBÛ;ēŪč â ˆ´ßā…Ez*ūĶ&Ŗ3 ;‹â/2ËāIËáŨp=yĢŅ5MÔ†,ĸŠxjIxĘÛ§Ž1ž6ĮW‡vMÕDQÕ­4žÁž.”?>W?$MT % ‰‚ZX?2Éø4qņ!¯eŒxÁķI~YUD0Ĩ¯”ūņd‹¯ †ČzP•Ōöņ O4d.QV%Uû´ŌđTЧúÁ2´D‚P .OŖû'û E W úT#x%úW_ÃøC<ƒâI~I׈U ŠQ:ß@Ūŋ˛ŦŠš Jā^ÄĶKŒg!gŸ,K ā]ؐĨÛ'Š9û US:–%]ē û¤ĩõ‡(¯1ž˛ÆxęãikŒ§¯1žąÆxĩœ„5Å-¨˛,‹ŨŠÖ™UԏQ)¯/PÖtUŅ5Ĩäú1Jë‡OŊ=UĄŧɊTz=ĨõçC}“u¨†úRēūĒųų 螮Ē&é˛R˛Ūj_ĀŅuYPZĸŌí[ãú1:W?CSEA0 €¨ĨÛ7W?$p­,(%` _ŖÄxļꇨˆ€s ¨ūMØGë‡Oô̆(Ē*)Š(Š7aŸ´Æų+¯1ž˛ÆxęãikŒ§¯1žąÆxk[?Fײ~äįl‘ ŋĄB¤&“ŲäD:’šŒEq4á“û˛‘XŪÎāŠ|xŌä÷ė˛F>|~āãŸ?'ZâSüÁH†‡Į4”Ĩ1~ß ™F %g"ņå§OĄąXbßtzb˛•?ËNōã͉1´f<œ"äËbdDIŒņĄÄØl’9™1#éčäŧ9Qr:Å[ųéD6įE,~įtÂl%ÅŲUdgÆ9ƒ‰‰xŌœÎdĶ2]xŸfÎx؈kxC§Sđ#ƒ—1QĻfāŨÉ,ßŨ\Ā~iŧ9î–m‹­™˙õ¸ų .bH†?HfrédÔĖ ŋc‰l’ÎƒŌ°G‰,X7…OņŊ1 ÃÆ“é)ēį…üQ,ŖĖŠXīæžĩ ˙(öüyøž><>`ΗÃwŽMGá÷‘,ųÂp*-4r.@,/ö$28ę„íWƒ#ö„ųÉf:1…†B„ÂĪūāūn24?˙×ŊzL°gˇ8“Ëā‘Ą#Ĩ Iãëūiø„]%ĸqĢ"ŲČ>0|>^$z_"y0nŽM˜S¤‹%Āģ3|jz_<%ķœĖ_›Ķ˛sÔya m›ÜŠ?•V>˜É$Ŗ1:qJŽķ{1pJŧá…ãģ|ļÅ “$ĄšL$§fZa+ŖĀ,ķä 2<ÆĘØjøâ<ļ/8˛xŪ) ĸ ũA_äPljzŠ*ׁH|Ú\^O‘ųŠ0€KÜŪ@ĮÎPį0š?8–Ɉ’Ļ ĘüûĢûÍhvu÷BsxÃCArŋQ›xUCŲ_ˆ7D\ā'f#ßŧoEl^¯+ԉ÷4‰WD^Pũ‹ņēĖh,ģ,Voņŋ?0ĸā—Õ<Ū)-D —ŸãŧŅExĸŽū€œĮ]-^'īI˙×4ôų|ÃÁūĻ‚ˇÛ†üA?Fj6’˜@]ĖQHüš"wn é˙š`ãÁ/o ohŠû*Ôw°Ī~˜hãąt&ģâ?k xŌjđ2f4 ådĀÎĄŋ öŠų~\1QSE'įK đ‚¨č€Šsm$>fFcSP6ÆĖ‰´šøÖÁ#öų48_*ˇT]…=¯ÂūŨ`įĐĀp0ßßËQRI7ā„IûĄĄdn8ūˆ› öą07Á“n¯p‹æŽģ#éԌvë b¨ø‘ht!~ djebPë"û:sŸy°Čũž]Ąģéüė“ úCÖ5AÆųŗĐŠŋÕĀh5 ‰† ČĩēΌ›Žhî|ØÎŽPī0Ũ?Å¯Ë˛j( ¤ēdČp>Rˆs7,˛fj~ķđ¤Üũ}8EĸjȲŽtЇūŊĀÎ.ņ^:ß ö‰Ē$IÕ ‘âuvaw•ŽZm]<)?V4A h˛aĀ‘Ÿž÷oOĘŲxr@`EA(Béx9ûˆ? įēHÎį%đė8ዀđĒĻ€3 šeÎ_;K“ČũEEg˛ŠĻcŧHĨáIÔ>ÉPMĐu‚šĖ_JĮ“r|uADI‚đKãKūqØ÷×÷×÷×÷×÷×M_V<ʞŗ˙Ž Đåp 0o1oąGØ#ĖítŲģRŽ}m?n?ÎÜÎ}ãūœ>wœqœa7˛™IfŌū•ũ+ĮĮtq6OÖŦcļü Į,sÍžŸÛ_ÄŞt­Û]ueێ9nƒõfnšõĩãkûƒ°>šŋ­ŽVæĖ/đŅöēœ?­šr=]ũ@1Ô^‹GuoCsÅ=…<ŦįåĘ/ŦÄÃ1ËÅō¨ÛŨzŊõzÃvg‚9\ ފ̞xāk&Põg°˙Ž.äaģLōpU÷ļÄę¯Ų#”}dn_čō/ ‹ˇ]Î1!<*ģ=ī3×đ™MaŧŒ×ũ?qįē;×éFõėuæ0sØŪgīsŧYū!r°Ŋa{c![ÔÅĮō;‡í7ČÃō >gÎĻ…<˜ˇœ/ō`TÜSķ¯îĪmĩļZ|UųÍ˙ĐĐĖážážŠŦ/s&h~P°rö[ņe¯ŗ×9N8N°]įÛ™Ũ–íö”=åøVîuՅƃÂ+^v>\$ēō<ęÚ+îÁÜG~žgkgkÖsÛđY1ļœ×÷Ļܯō¨ėŽēŅu™šŒđøŦXZČŖ~cĶ—žˇŊ,Ɩ•įÅ*TÅ=ŽōāļqÛrŋŨæb],ģØ5Âb ũQų|ÍqäÁžcĪaėVvoųظ]jĢŠCŽqæ2õ Éņ\ž.9ĖYȑ{ķ[äĄūÉ×Xũ´ÜŅ琇{oe7Ž•yx˙Ĩéo@ŗ w,åĮæøBčĖŒ+×ĶŽ§-íߨĩĨņ°×ąęŸäuKņ@ŸÛv9›jžĒúō`˙ ŗÕūæ­íÛVœ9_nėöĒYī|ŲķŦģ…ÛfģD~?G˙ tx”Kåķ$ÍĪû~âŪë˜eĪU<ęũŊ÷÷îŽōCeˇÚŽRũ[˜ũøˆ9P¨ŗ¨SĖnüßãĢŋ^Ũ)ÛîļŋgĪņˆãöVöV;—[Œ<œŸŌēązc!ôîųB¨š‹yp‡<—ŅȂ?m_o_oÕ(/ĢüzS*ĩh=‡šˇ uvNĢđwØsĄíČÛŌ]Œ)ˆĻˆ+Ȇذ+ˆØä;ČÄļ‹j.DV.Žō~¸ŠJ\{ĸųM¸ÎĶx*ûęŪ ēØ2ļŒ<{„.ÛŨLˆ}rrʞü\´{đ˛›ÚjLԟ<“#¸ ĖíŋĨ_Åxāį-Ũĩ›s<œŸ‚WŦū­€GaŽPî×'”™ęcVũf/.Å­wũŠ}Í)ãbB\ÜęčcÅ-.Ö˛ÉÅV}‰ÕĪ~ŧėyŒ.w Ío‰ôZ”ÆUžĪ$ĶIwÚ ČüŠÆƒŽ§QO€ÉeT\æ˛ëhÃöú‹N‡Ķ~aOrÃÜ0sšętËŲæ7*ž+ˆ)b?÷÷PŽŅ#å?C}b_ĢūQĶ û< õ˙[ũ#ö5´k­{/eâb+náNq§°ž5>/ŨĶö^];2AS…ēhnē÷BfŪRuĄ8Ēw´3wũ-[Á=Î=ŽLČc§Ŗ“+Ë+ŋh9|Į?uM„>Ųæl؎ū°”ąRājŨēųÅÚ¯š—(ŋCøŽZĄö!˛Įh˙@Î š~;oŽ úbĶŪĪōušÔ]Đ-rNÄå˜õŧŋŲÜđZg y RX\ņīHŋQ1ˇĐ/ČWũEŨ蚨ŲúÎ4QĘãĘŨQSWuēęt…‡ŨJÎW5ÖīwĖņ°?Čîw>E™Xį‹ģŸŨoņ¨ŋ^œ‡Ĩ0Øģ˜Zûēō¨š>lŋr×Ɏ?5Ë9įtT~ŅTŨzŨ{žō‹|˙Ŋ{ŨõZGx\#×XšŽáŨĘu–/ڎšÃcü\žŸČÕ1ZMĐ.övtøãûbRMTlˆ'ĪaœmŽNįÖįÖš'å{Ę÷ØŪĩŊË ×ÔĩmžķuŨ¨ųˆĒ9{cmëSÁ™öÆMĪanX<ÉR‡ö[šą9‡æj—e'úĀâgʕx /sŲųNÃˇũmŸQŊ˛ŋč:ÚTŊõŠĐ'Ũī†>ioôޏŸá^â^O\ˇcžs˜ŗÎ§ÜNŽ‘œC­sŧįūˇú“¨Ä/į÷˜…v“žFë=ymé5đ¨øן yŸđĀčb^e^ĩxԗ Ī4UcTáǘnŊœŲõj˙/wŊzį:P¨Į{Ũqō@ÅĩxāūsšķtīQŅį=Ę]!~š  ũąŒvĢk3ÚJsŨĘ_QŖũ=[zļ´˙Ŗ÷ŧ́^˛ô˜ÆĪÜ<Ãęōsx^y¯wsí›lYų隞‚-s~˖Á‰Č¤ s9?"ŊŒķaRC t–ô19ũĨķ ČũėĮ_ą˙˜.Œ-Š2ąæGøŧÂĶøēūĪÛŌĘ/×U~Aû†|]9Kõ‰ģÂ]!ÚU„÷û~įˇöē9ž?V}čųãr<čt‚yĪ*dޞ‹T˙E<ˆíKō g|v+]öž˙oīĖÃŖĒŌü`ęîK­ŠJeŠėû HÂ"‹†ĨĄ1„@ !B°ŅVT†elĖfitĞvD¤EÛ%âH cĶЊ€€dܰE~į{Î=U•ĸô<=ĪoūČ}r“ēŠ›ķšīzŪÃSGOņ'u÷›ãQ˙@‚õeCˆGö*“"8ø<” įH4ũ)¨-Â9ØČ™pĩÁö0­‘š_ķߡxøø!‚Lˆ.ÃŅf™ãŅWBŋ ÕËņDÂ8ô۔éWĮĄôrK4¯Ė]híÎ6ԕĄ8ŦŒT߲}q9ƒø\ŸÄUD'h„DØŗ´'cŸ×Ø,ÂĻ9튃ķDŗ3Öˇą? Ÿį~lŧāxʞĨŒ ֕– ›û’æ9ÛŦųÄfQü÷Øø ˇō”ĖīŖsč)úĮúĮС'>OˆäpēãĀaĖ ĢJ/áĀ\"œÃņTōĐØ•‘´ˇÁ!Ÿqļi팃ûíí ĒĐÆęÂĶV@ęÖÄĒÔŠčŧJ×ķžY°@b<Ãx‡ņ¸Ēôržë|Wéø3:ėuŪTvAs´Ö úđĪöŪGæ'a~N{-´7/ŸAާ+™[" ›ÍÚĖĪ$ÄaŽOūʗԑÃņPėfd>’3Ŧ>f8‡Ŋ*Nrŧ‚ü€zŗOŒW;ČŠ1ãÉĄ?ĪæØzš^ÎæXާč<+‚õĪņŒÃņTü ß9ûЏmigâĶôÉ!Ûh5‡s JԘh=WXl ų„æ”)!Á šOŪl.CG ¯Ņ)‰Û4oöąúœŦš9ËtNė48/fÂ:Ēdfõ)Đ36ŌĐáÃŦČšÄ)ŠËĪ‹kkĪXhĶZåeΟl•ū¤žĒŊ§Ŋ'*|šĄŦįĘ9¤7čŦéčˆYjXx]Ë*`’ë­\ɁuŽĢáđ5¤'ÄĩŗnãđūG~^NĨģ§‘æ ‡9UkUģyÕxÆņk˙äø…žĮAÂė€d-Ū÷ZAŖí –ɘxGîŒtshŽĄ­ĶցÂüžˆU͘Gâ7 °YÆĄ–bü“KT.¯ÚXļ;} īđ ™]ŅYÆY>ړɷz¯’wWr-ĢaKĘtWžšŒíËĒm\;­Vũc0đuÖ˛üŋņ˙FÛÆúĒŧßĮē°ÂŒ[đ¯tåB8Č×÷Đg‚n͸#ŪĢĩj­ÎŅ9;Œäî_–Uā|ŽĮe—kú_Ņ84ɸ€<č>”?¤ßū’ŗ aúmÎVĖ;r@që2FgŒvíˆäĀƉhôĢÂ8ø:%_ū•ũ(|]^fN÷æ?WrgÆĢÎįāļßĸžŗ?™0}#jÃ×3ĘB×$.Ŧ­úŸīT>¤īøÄƁ<čúĘĐxÅ+æßúĮöũÎ!XmBd7ĮsŋįvÂ,G-åū ›ŌÆhcx˙qįÃÚ6ž\c]†xĨvˇuí1§úrü×ÃĨ&"‡ūŧk,‹sëøĮŒ„u…Œ É+˛žOßåūwĢf'†÷`Ę9$^‹×\×°8FŸél}v4gŽ3—QčŗŅĪRâĮErë„u’f?¸?öZĢ9Õĸhĸ9vz3Ö:"¯Pāão¨[YĩËæ XŸt}åčŽxė%byš×lĶZ gĖ.‹7÷]V°] e5lG9Ļī öļAˇcWîƒŊąõņIŽ}ąĢ6öV˙ķŪ]öĢ>ģ ՉÕ͎ǒŌpi“­­#‡šĶ÷yŌî¤Ũž‹|=X_Yķ)m̈xw1(I菄únŧŋĪęAu‘Ģ6āŠëĮz°1Įgø—žØģËņ™rŒ¯Üąsp}m'ŧ˙á '>ļFDßĩQ_iŪ gÚîˇŨ/ŋ°čņRōĪ—ÃÖā´~đ΁y­6‹UD °Íg}RHėQGwÆah4†qĀŽ }ąĨ;ƁҪ§noIûyâ“úŪP|Šäā9UúqûO/ĮÁ|$~aī_”Íčũ Ī€>,X}Öį!ҟĖ?šÄŗĘŗ*)Į3Ú:ßč¸=†Fcu˜Ÿ‡Ö-Ą{KBFúYī.äQؘŊ…ûš3×Ŧ ë?#ؚJč˙˛ā$ūߨįÂ×%äiČ.Âqģ¸]Ų(ngŅÖžü}ūsŠMöŖq ūsžÆĒŊ­Ŋíl…Ā‘”“Ũ{ôröü¯ž>ë2gÁ?Xוsøļž äöpš_Îu\_ŅÆx|fyīvH¯ŨœÃ3Ā3Ā~Tí.b"~ĀDęÅD9¯œĮYŧ… {M?é¸ÕqĢÚ"-V^Œ“š;GũŗôDŪ oPM)E\+Ž…DĩĘČ÷,Îrõ+ÔŊR+čeŸĸu“Ui=ušēœ~÷ƒzĘUĒ×ČÛåíRÄõ]ė'jĻŧ]؍ŸäqÚ yžš…z›Ø.~ÁD9"~a–ûnôŸsfi#åēh`ĐOę'#9ô“ eīHũ؛ûǏ‰ŽEÆkŒÄü™ų3p(K•Ĩ˛*Ģj•[Ęr•mÔ}ČWCžĒÔ ļÆe_jŨĸqč5âœÃpļ¤ŽwÜ`ŽÔ6Ē™Ž|1E$4€DŲGä‰˙\Ņ]EwųĪÉu >`ŽtŪĢm”ˇk÷zĩæJsĨëģÔõįōnŒ]ĸėĶ1!OžŽ#Gâ ũ-ņ phũ!ŒãuŊøYvUvUŧéÎøYßĪĒū0`Oąæ{R˙­kQė×"õĪ÷ÚpãKĮąRŸ/Ũ1¸•sô˙0ŋįP— R(NËáŲ ĨYiŽŋ9]÷M€V@mh węú>)>ЎQb_œÃģJ<á?g–ãgé1é1EÔ~„(ĸ"Ēŋwߓĩ´ovE¯Š^ũ~›–hw*}ÁK‹ŨZčī?ēßÔôņæ!ĩ… lĘ^Ģrû’n“nĶ^Ņ^!y;ëŨō錪jYQŠ÷EØÆĸės­)(íÛŗä ŽŌ mØG¤rNĮ0܎?&7dĩĨ´ĮρÎUę˙ÂãLĐq{eÉķ”8]T“žļŊl{b˜8~™\Ô7ģęüā“ƒOö_•÷Ĩë:=]éĢôÕO‚$nCęĮŗÎ]ōi1hÃ^d/âūų"ĒņeBlÁÖJmP÷ĒeŊ÷'/ĸ*8ÄvûĻôæ‚ŌŒSî1ŒCiö4ú&8npܐxwī˜ō‘}æĨ´ÛGāuK ã"9”8ˆ˜Į(l/‹qˆqŌcęƒŪ™…Tô|rčģƒOVôʝīž–%Ŋ)/‚ß(įˇĩj‹m5DZė¸Õ?ßņ,ęĘ휃˛¨Z7û”¸ėėũŠķĪÆ×ęķ•ĨˆeLĘ>ķ´yžŽ§ÛR3Ŗœ÷fĩ•˜50ĢHqoSOI?0ŠŽĘũ-]T⤧Ĩ§Ą*ūÛKŪGÕųŠ^ÅŖ|Âöží}p f!æB‡7#'6y8”Ûř‘ú|BōYöФ[ĢEˆCŅãâ4Æ/O:͎Žĸŧĸ.Ė#ūB8<Ŋ27øĶÕŠĪ“˜ˇ!nƒûĮ/ŠgŦUÖjĒĻâ|)‡8S{â̊{Ų#ā‰>ŸäFkJŗ^͇ĸë=q¯¨nJzŋÔį/ŠåfĄĐĀ9äë'8Ā΁Ėaf{Īģoaú@ū€OĪNG¤ŠäDÎBõbqHŲžíur;F/o@D>WMø8īRË( Éã–ŊЧ`/Ō98 ˆĮj&ė‹åDâ-=ōīK<ĸė#yœ0Pģ" Ę=Ę=ō ‘†Ú~Ęķ;8´ūfļ17āŠ„DÚžœƒÛV$Îā€FP—@āPĢÔĒÎ9 Ô#~¸üŪ™`‚ƒû“ú­úm4äķŋÍ˙öôrÆ"ōú ߊ„"ÆÁΜ#Ä#}dŧFžĻ]ŒŲ‹PĖēŒ/|ĩJ{E~‡Y˙LŠ.l[ČsĻņ˜Ä1âČįLc„6XèËõŠÎŧ#$Ü×ÁáyĶķfæ†ÄwÍl­8‡°ŠČUp@l}`_ŒƒÅLJÖÍûbÜg?į€o@'Ņ9RéÄÛ#9đ;Ņ8ŒuqWšŽIŪķŪķŽUŽU°):~K¸MÁË)Sø<ĩŠ ÆŽuc–…zËņg1(äw˜6ôn[ā >žOoķ(f!ę+×wj&~‹’ŦU–°->~ņ—â/qöŧīyšČfļ™­ŋ¨ŋø?á ÁA,éKÎAš^A>dŲ›éŖ#‡kMō[žaļĮô>XŧbB}„œÍÍ‘×á×Ä V­éM&xū\Ī„įî¯lžō_§Ŧ,B}_ØJ|ŸäLQ’/ˆo‹oËũ‰Đų„ĐĖ|ŧej&*ŪP.aņ‰æ|°ļ͍Õ.ZōĩüĩøOâ?á,ŨeûÔąq Qĸūäīå ņwD{ĩd8æC ‰ä°U[qęĮ4ÔȌ"Ćp˚Â}›s€O9ģ5îGŖŊ^ŸE‰ÆÁč9…“āl\cŌ>#įđ(Éoa>ĒK˜Įģ!ōvng!ccš?×ĩ&RŒCē˒N8˜>bˇzEŽe­kŠž4’šĸ3Ē— 9œ žûĻ+sā:׉ąĀ[q%VͲšŋZāŖ6w\øšyˆú߃Χ™ˇ]ËÄČwKđaîĪAŋ˙ˆÕŽÄ’˛ÍXš?¯ķaįĄēä…2&l>NâÆJ¯sŋĀ;7õķŽr%Ė6¨į|-įæËæË‘ė…˙m*ŧžŠāPëÕzJb1đņsa•6‡q0‘3ũ0OY^Ā÷4ĘŪnÍC,áöÄ9XŨ.ļ#ŽR! ļjĖ=ŦZ„æCąsōų,ĩAä2vaĐÕs #Žq.‘”z=TCá9å*9˜>.åP—ģĮ°Y-‹ĶœC.Ô"íŠ{yH,Ŗ WÂęEÆČĪJ†Ø"Ī‘įˆįÅķŧ>į|>ÅúYÄÛ1ö ōĖ숎K¨Q_„ė§cœeVÄ|ZŲ7/Ģ-ÎAsĻÅ+ļ‰mĐÆNcîûLĸsxú¤}čéÉĄū^ũ=į ‹Â9BvÅæ&s¸Į8…8l[l[x|ŠäĀ<>6ÍUڍW¯kCq b=ŸŽJ_ģĶîä` ˛–×´LxŊ%lļ"#2%0yöæŽ(ÜæĪėpnWĖūôļā|+ŒClS6iĮĩãÔĸ.ËĄœ‡KŊląáz:™[Eá€M1Û"ûk´Š˙(œÃnq`|Ąņ‡ō ē ÜÎ x1Ōķ!áöÄ*Â¸ėŒ–Ājįta+›û?šāܕúqâõȆF­Që‹Éy$į˙tÎMũ™Å׎v…8‹yU(.ŗr]>Ä^[,ą´žÖLˇ͇ąÂXĄdYĘ;:âZ}~ WŪ­-˜Ģ͘‹žĪÄžÔwŋ´ü_p/Đ?PtįąŦš‚ŌøßaÖ‡× Áy e@–´ę–MĘ&XVĐĪ=–XļÎĄôu]—ōlüŸŊ3ûRäEā°;]×Atã€>¨ŸŦ ‰˛Ô>ÅõĄq jöhčÛA‘æit;rØļ B 8g}ž&*Gŧ/<#<ƒŗük"ģ͍FĻZĻmwŽLôŪ›ÛÚRĒVËâRĶ˙š30m†ģ]Nˇ‰ÛäO Âw\¤FŠQøN;ĀfGlÎĘkrV"ĪŠ™†›Õ áũT‚°+ęc˜HФ¨1j î˅ūĨĪåÃŌdi˛ė•Ŋâŋ"‘v¨›Ã9´&BÆodÚ& ‡ĩíI7įŸN8WĒeFfāÚžwö?Ü˙pNãŒō„ōDt"lV•ķ<^Kuä`š:’ƒĘUs¨˛~Rŧy§s˛ļ]Ū-UÛ&KÕRĩ‘ûį^ŧbnĖÛīķAÛ+wŋājĐrZ8‡í^Š‘˙ĖĮɁņŖ‡Ëô"•Ą‡ËãŦJĄßīĩ„0k„5á ôL8 ”ˆR,QŠ•âpų×Ú?Ëģ…Ãā€Āž@ņ?Ū[î¸ßįY_Øī–Ķ„ŌHķuĪzįųžˇĸs8nĀZ ãp•ēˇ™ŽžC>ŦíæĘŖDŠĄqKÌ">*>*Û/ÎčE8,ļß—š96mFė8å ø‡:AĀ˙†í^uBü‚!ŊÂ|ŨņGã ÆnÁx˜wĘÛņŊĢ4ĨŨõę[0aĐp‡æß,÷ kä%A›"‚ŋå ĩšØՈđ9tÃ9ØčC$q(÷ëMŽ÷ŒOõ‡q?ũa¯îՍ›Cžõ)câhŒƒ¨†ŒƒŅ9z·á&™átål^GøbˆÃ~wgÂ3ō¯Ĩxũ"lËV`+ĀØ¯løíwčM`€áuå~"OāŠ$š>wĀō="ō'æë”˲#Ū‹æõ8ŧß8čø#_‡ ŠåįXÉt&¤ŊđˆCíÉ⠞˜Ō†ū0Æ?gÄž(…R܇ũŽĀĩYŠKÕļÃ_¤jŽÎŅûTéÁ„Ķę„PÄbö̘>BX›åđųHŗ0ų­Ëqā/Gã€N‚q÷˜tĖvÚvZ,abLÛ]xCF™ą\Ú"mQ×+öē´×vLÚë~ č7eõŠŗíGä%ėoĘKnÜDí™ęB|ĀVmĢFæū˲ĢŠP—Ŗ˙Ėk–åqŽ5qķÜf­šÃqÆqÆėiž.bģ‘öKž^kÉi˙ˆmgÚXO|Žg…ąüRŽĒĘž_güÔ9’Ų3†ŒC¯ Îņ:á`]Ŧúsāp”°øá8“ļ$§ÎßϰôLE |Ŗ|ÉA˛Į­ÄiL0nˆøōWHđįÎ!í5~—\ZV?8¯âŋ “#9ßĀÁûŧĪÁŸy°žmvBöÁƒ•YŗqņÜė™ļ¤ā­„BÛ…ŖÄoŽ•Ę 1z΁üÁ'@Ņ8ÄoÄol¯Û^ĮĪJ€ięK‰#JīĒnjÆÁüūâ ,Ö3Į¸Ã9ŸGÉŋ¯hvÚ f!ĩŠæëšÃŨ;ŽäĒį@PČ ÕÍÆ:ÎAãî1u¯^ĄŒáö%,büAÁØ ^‡€CŠp éOôT<.ū Š€ˆoČKh-AŽ1īVšYž#ûøXŲŧIoĶÛØw–MaÍoyĸ¯øDß˙,8įZŋvœņˇ7C3L7Ą˜HōŦ5vc]rŽī¨žÎĄŒ!z°ęÄÎ8äLčXĮ(vŸī”į=ˇ3üī D¤Hžīø<ŠÕ%î1Ųž‚s‘öMā0{:Îđ,ÎĄĐpwkGŽ =ŅlHė‹ŽŪv-ėJKÆÍ}ƒsYuœRA^"6FjRÄ,Û1øˆ9úā˙O‡×㜉Ėŧ÷ąyĢIœ Xũ Ō“VoiŒÂ¸ŲQĒKäOH=Ŋƒ ė ūÍōĮå9äĎ:á bįāuį`ŲÁqƒGq&„8´Aė{ÖÃÛõ6cû?f!úT„:ŒÃQ’ē7pŒ‘°jNū„s°(eÛĪōņķīī!o#×Ņ|iO6ŲÆs ­Yx^ÛmåeŪ'āņČĘWŗgōšÜ#1Ž3B){Õ~ˇˇY})X›“ø^áYįėŨį8Cs^X4 Œ,>Q´×7­Ũ2;î`"—‡ãĢrŊvÖšßšßŊ3yaāZûqŪP­sęÎ8ümŊŗĘīëķTâ&ÍÃø]üįZÕô4{ Ĩ„7Œ#vIļ'̇§1’ L´›ĀáÛėÛėŧ(ž(Ūûęuá°ŧ ԟˇ°xÎ@ëÆ°&X‚=ūŦ–L[RvãŸVĖΊ3{ōúHĪ…="V°¸Ā3œœ{"큰܍ˇŲ7a 5 ĒJT˜â{ĘNí&FĄė$r=H´ŗîi3Ōf8Ū įĐÆjc˙Žđ<ĒOõ‡ũmĨžŠŲå÷Ĩ-a _Š/9~Ĩį2^s€ƒzFšäHē^Čŧ u˛˛SÎLe$â{D\LbūØ.zäāØoļ˙āáŖĘû­ėđųĪ?iǟ;ˇnļ \1´7vĨΨ¨ĢÍČ)))ôåô.(ę[Ú1ø˛ûwûūû“\i˙îūõŗjšZ}séG _íũĸīßíË%ãŪ2sR]>XxR+6ĀæĻMķ.ŋÜNö'.ŋšËUlā}ˀŖ‡ōuē˙euÍŦɍ3}ŗk°m-ös¨ml™5ˇķû ŧÜũr|Y›[f_é&áûT ŽZ12úũōÃykZf^qOõĘÛF /V‰Īŋ;u¨ĻúZ߀ōĄ–-fUΟk}üŦĢØ{TՈęaėķŅs*ø§Ā‡>z]MCją/yrc ,fvS]m=nŪŲ‡6 }Ū:Ũ/ĩē|TeÅđƒ/JnĖ?‰z˛o@MCũ¤&öYÚˇĩséũFĖ>Ÿ:ĐĐ85'ûvĖm1kô,ėn||žœĢáÍũķ˛û +HÆ:ē"< dŨ2­ĩšžļĻáīâe÷2qXÍÔYtsŪÎys¯†7īĖËî7zø€ĘęQåDÍcCãËņ5×OYã›ÍšCž7šîÎúKvC§ŧyWĪ›w5ŧųŒwHŪÁŗæÖM­kJÍ÷%74ʊPđs§ŸANyŲũ†Öŋ˛zâˆĒ‰l“‡‘°įŅÍlģÉuMõwօ°kÃÔ} /ģÛĘ šãø"yķ¯ôyáåC uÛ(ė'\Y=`âŪpū\|ūŧiõĩĶ: Ŧž[ZÔOîxŋ1•Õt?õœėŦėĸ,$Ž@ØũÂŪN÷ũ¸ÜæöāT]9rĐĐhû˙ā“éGMkĒkžÖØ0ŲÚ$ĨyFĢ5PbGŗØ–93yĖø_<°yMCcã ÜYnÄĶȝ †Ķ™5­žIuž–fžÁËbÔs§Eą3š)ĶĪܟ[ĶÔÜąĸ™îĻCī_‡ü§ú!ŋÅUuü’Ší˛“FŌ‡“‚§ܞ ›¯ÔĐŋ…ęŖšeæLk“šhã›ÛˆŊ}hkļ=W•õ#Ū8ŠĻvÆT’ņfao–*r˙ēų53g7ÔĨ_rŋú)oN¸ɓ#1{˜`7Ŗ+Ų Ū[€ ČŨŲĢ=…‰ā!fŽĶekCƄ͘3éĶeJ†Jé'ąû6Ínl¨ą6đĄé&īHÁ{ęėīÄ@sHã˙?ˇí ūPaaÅ?Nŗ‚W­ÔŌ1ˆE36Č/†L›<€ēâĒ(øŦÅésÍėú<ũŽŖëč:ēŽŽŖëč:ēŽŽŖëøGeʔ)wÄÄĔå$ŅsØŅ­LÍËËĀĩėÄíȹ߉â_g׎-S/^<k™̤×ū:,æ5v­¤LÛŗįM\Ë8ÔJ¯}8q?{_ˇ‘eúęՏāZúü_Ŗ×f|đsz­ûŊeƔ)5¸–úō$vĪģS|ėڊ23//גOŋúsúžĸCÖû*ËĖ‹ŋĮĩ@Ü víWß[īËė{öėÂĩÄįréß;ļžŽ—Œe^™cõęU¸–pK"}ߑWį2†nĨeÎ)S&áš˙3×qz­˛ĖzßmeŽŧŧ,\‹Û1ŪķpQû{ŨōĘ\/ū€kžåã(Ãқ۴žËĘÜ{öėÆ5oō5ô}Į˙5Åzæ7•yV¯~×bÛ{”áZ{éhKļ˜ŽŖëč:ēŽŽŖëč:ēŽŽã˙Ėņ˙˜HVဝ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/header_newlines.fits0000644000175100001710000011110000000000000022632 0ustar00vstsdockerSIMPLE = T / Fits standard BITPIX = -64 / FOUR-BYTE SINGLE PRECISION FLOATING POINT NAXIS = 2 / STANDARD FITS FORMAT NAXIS1 = 1 / STANDARD FITS FORMAT NAXIS2 = 1 / STANDARD FITS FORMAT ORIGIN = 'Palomar Transient Factory' / Origin of these image data CREATOR = 'Infrared Processing and Analysis Center' / Creator of this FITS file DATE = '2011-08-01T15:14:04' / File creation date (YYYY-MM-DDThh:mm:ss UT) / PTF DMASK BIT DEFINITIONS BIT00 = 0 / AIRCRAFT/SATELLITE TRACK BIT01 = 1 / OBJECT (detected by SExtractor) BIT02 = 2 / HIGH DARK-CURRENT BIT03 = 3 / RESERVED FOR FUTURE USE BIT04 = 4 / NOISY BIT05 = 5 / GHOST BIT06 = 6 / CCD BLEED BIT07 = 7 / RAD HIT BIT08 = 8 / SATURATED BIT09 = 9 / DEAD/BAD BIT10 = 10 / NAN (not a number) BIT11 = 11 / DIRTY (10-sigma below coarse local median) BIT12 = 12 / HALO BIT13 = 13 / RESERVED FOR FUTURE USE BIT14 = 14 / RESERVED FOR FUTURE USE BIT15 = 15 / RESERVED FOR FUTURE USE / DATA FLOW PMASKPTH= '/ptf/pos/archive/fallbackcal/pmasks/' / Pixel-mask pathname PMASKFIL= 'bpm_2009060s_c07.v2.fits' / Pixel-mask filename UDMPROC = 'updatemask' / Update bit in dmask UDMVERSN= 1. / Version of updatemask program UDMOP = 0 / Operation type UDMMBT = 4 / Mask bit template UDMIFIL = 'bpm_2009060s_c07.v1.fits' / Program updatemask input file UDMOFIL = 'bpm_2009060s_c07.v2.fits' / Program updatemask output file MCVERSN = 1. / Version of ptfMaskCombine program PTFPPROC= 'ptfPostProc' / Flags proc NaNs, CCD-bleeds and rad hits PPRVERSN= 3. / Version of ptfPostProc program / COPY OF IMAGE HEADER BELOW ORIGIN = 'Palomar Transient Factory' / Origin of these image data CREATOR = 'Infrared Processing and Analysis Center' / Creator of this FITS file TELESCOP= 'P48 ' / Name of telescope INSTRUME= 'PTF/MOSAIC' / Instrument name OBSERVER= 'KulkarniPTF' / Observer name and project CCDID = '7 ' / CCD number (0..11) DATE-OBS= '2009-06-25T08:41:23.970' / UTC shutter time YYYY-MM-DDTHH:MM:SS.SSS DATE = '2011-07-30T15:04:59' / File creation date (YYYY-MM-DDThh:mm:ss UT) REFERENC= 'http://www.astro.caltech.edu/ptf' / URL of PTF website / PROPOSAL INFORMATION PTFPRPI = 'Kulkarni' / PTF Project PI PTFPID = '20000 ' / Project type: 00000-49999 OBJECT = 'PTF_survey' / Fields object PTFFIELD= '2899 ' / PTF unique field ID PTFFLAG = '1 ' / 1 = PTF; 0 = non-PTF category / TIME AND EXPOSURE INFORMATION FILTER = 'R ' / Filter name FILTERID= '2 ' / Filter ID FILTERSL= '2 ' / Filter changer slot position EXPTIME = 60. / [s] Requested exposure time AEXPTIME= 60. / actual exposure time (sec) UTC-OBS = '2009-06-25T08:41:23.970' / UTC time shutter open YYYY-MM-DDTHH:MM:SS.OBSJD = 2455007.86207 / [day] Julian day corresponds to UTC-OBS OBSMJD = 55007.36207 / MJD corresponds to UTC-OBS (day) OBSLST = '19:08:26.70' / Mean LST corresponds to UTC-OBS 'HH:MM:SS.S' HOURANG = '-3:09:09.78' / Mean HA (sHH:MM:SS.S) based on LMST at UTC-OBS HJD = 2455007.86457 / [day] Heliocentric Julian Day OBSTYPE = 'object ' / Image type (dark,science,bias,focus) IMGTYP = 'object ' / Image type (dark,science,bias,focus) / MOON AND SUN MOONRA = 131.676395 / [deg] Moon J2000.0 R.A. MOONDEC = 16.207046 / [deg] Moon J2000.0 Dec. MOONILLF= 0.095389 / [frac] Moon illuminated fraction MOONPHAS= 144.0201 / [deg] Moon phase angle MOONESB = -0. / Moon excess in sky brightness V-band MOONALT = -35.16959 / [deg] Moon altitude SUNAZ = 13.90467 / [deg] Sun azimuth SUNALT = -31.96011 / [deg] Sun altitude / PHOTOMETRY BUNIT = 'DN ' / Data number (analog-to-digital units or ADU) PHTCALEX= 1 / Was phot.-cal. module executed? PHTCALFL= 0 / Flag for image is photometric (0=N, 1=Y) PCALRMSE= 0.030059 / RMSE from (zeropoint, extinction) data fit IMAGEZPT= 22.43948 / Image magnitude zeropoint IZPORIG = 'CALTRANS' / Photometric-calibration origin ZPRULE = 'COMPUTE ' / Photometric-calibration method MAGZPT = 22.73683 / Magnitude zeropoint at airmass=1 EXTINCT = 0.17995 / Extinction APSFILT = 'r ' / SDSS filter used in abs phot cal APSCOL = 'r-i ' / SDSS color used in abs phot cal APRMS = 0.0554857 / RMS in mag of final abs phot cal APBSRMS = 0.03911367 / RMS in mag of final abs phot cal for bright staAPNSTDI1= 69501 / Number of standard stars in first iteration APNSTDIF= 64858 / Number of standard stars in final iteration APCHI2 = 325618.88012443 / Chi2 of final abs phot cal APDOF = 64858. / Dof of chi2 of final abs phot cal APMEDJD = 2455007.84500722 / Median JD used in abs phot cal APPN01 = 'ZeroPoint' / Name of parameter abs phot cal 01 APPAR01 = 22.81878918 / Value of parameter abs phot cal 01 APPARE01= 0.00198923 / Error of parameter abs phot cal 01 APPN02 = 'ColorTerm' / Name of parameter abs phot cal 02 APPAR02 = 0.20481246 / Value of parameter abs phot cal 02 APPARE02= 0.00278076 / Error of parameter abs phot cal 02 APPN03 = 'AirMassTerm' / Name of parameter abs phot cal 03 APPAR03 = -0.12104427 / Value of parameter abs phot cal 03 APPARE03= 0.0011621 / Error of parameter abs phot cal 03 APPN04 = 'AirMassColorTerm' / Name of parameter abs phot cal 04 APPAR04 = 0.00904321 / Value of parameter abs phot cal 04 APPARE04= 0.00176968 / Error of parameter abs phot cal 04 APPN05 = 'TimeTerm' / Name of parameter abs phot cal 05 APPAR05 = 0.03012546 / Value of parameter abs phot cal 05 APPARE05= 0.00459951 / Error of parameter abs phot cal 05 APPN06 = 'Time2Term' / Name of parameter abs phot cal 06 APPAR06 = 1.27460327 / Value of parameter abs phot cal 06 APPARE06= 0.07646497 / Error of parameter abs phot cal 06 APPN07 = 'XTerm ' / Name of parameter abs phot cal 07 APPAR07 = 0.00768843 / Value of parameter abs phot cal 07 APPARE07= 0.00083226 / Error of parameter abs phot cal 07 APPN08 = 'YTerm ' / Name of parameter abs phot cal 08 APPAR08 = 0.06680527 / Value of parameter abs phot cal 08 APPARE08= 0.00203667 / Error of parameter abs phot cal 08 APPN09 = 'Y2Term ' / Name of parameter abs phot cal 09 APPAR09 = 0.31486016 / Value of parameter abs phot cal 09 APPARE09= 0.00318862 / Error of parameter abs phot cal 09 APPN10 = 'Y3Term ' / Name of parameter abs phot cal 10 APPAR10 = 0.69934253 / Value of parameter abs phot cal 10 APPARE10= 0.01257477 / Error of parameter abs phot cal 10 APPN11 = 'XYTerm ' / Name of parameter abs phot cal 11 APPAR11 = -0.04590337 / Value of parameter abs phot cal 11 APPARE11= 0.00286729 / Error of parameter abs phot cal 11 / ASTROMETRY CRVAL1 = 333.443801401309 / [deg] RA of reference point CRVAL2 = 3.08905544069643 / [deg] DEC of reference point CRPIX1 = 1175.019 / [pix] Image reference point CRPIX2 = 945.8826 / [pix] Image reference point CTYPE1 = 'RA---TAN-SIP' / TAN (gnomic) projection + SIP distortions CTYPE2 = 'DEC--TAN-SIP' / TAN (gnomic) projection + SIP distortions CUNIT1 = 'deg ' / Image axis-1 celestial-coordinate units CUNIT2 = 'deg ' / Image axis-2 celestial-coordinate units CRTYPE1 = 'deg ' / Data units of CRVAL1 CRTYPE2 = 'deg ' / Data units of CRVAL2 CD1_1 = 0.000281094342514378 / Transformation matrix CD1_2 = -5.00875320999652E-09 CD2_1 = -2.08930602680508E-07 CD2_2 = -0.000281284158795544 OBJRA = '22:17:08.571' / Requested field J2000.0 Ra. OBJDEC = '+03:22:30.00' / Requested field J2000.0 Dec. OBJRAD = 334.285714 / [deg] Requested field RA (J2000.0) OBJDECD = 3.375 / [deg] Requested field Dec (J2000.0) PIXSCALE= 1.01 / [arcsec/pix] Pixel scale WCSAXES = 2 EQUINOX = 2000. / [yr] Equatorial coordinates definition LONPOLE = 180. LATPOLE = 0. / IMAGE QUALITY SEEING = 2.04 / [pix] Seeing FWHM PEAKDIST= 0.396793397122491 / [pix] Mean dist brightest pixel-centroid pixel ELLIP = 0.063 / Mean image ellipticity A/B ELLIPPA = 48.65 / [deg] Mean image ellipticity PA FBIAS = 1060.884 / [DN] Floating bias of the image SATURVAL= 17000. / [DN] Saturation value of the CCD array FWHMSEX = 2.45 / [arcsec] SExtractor SEEING estimate MDSKYMAG= 20.53072 / [mag/s-arcsec^2] Median sky obsolete MSMAPCZP= 20.70926 / [mag/s-arcsec^2] Median sky abs. phot. cal. LIMITMAG= 20.92587 / [mag/s-arcsec^2] Limiting magnitude obsolete LMGAPCZP= 21.10442 / [mag/s-arcsec^2] Limiting mag. abs. phot. cal. MEDFWHM = 2.931446 / [arcsecond] Median FWHM MEDELONG= 1.132416 / [dimensionless] Median elongation STDELONG= 0.3298569 / [dimensionless] Std. dev. of elongation MEDTHETA= -42.28234 / [deg] Atan(median sin(theta)/median cos(theta))STDTHETA= 66.21399 / [deg] Atan(stddev sin(theta)/stddev cos(theta))MEDDLMAG= 33.85928 / [mag/s-arcsec^2] Median (MU_MAX-MAG_AUTO) STDDLMAG= 0.4367887 / [mag/s-arcsec^2] Stddev of (MU_MAX-MAG_AUTO) / OBSERVATORY AND TCS OCS_TIME= '2009-06-25T08:41:23.978' / UTC Date for OCS calc time-dep params OPERMODE= 'OCS ' / Mode of operation: OCS | Manual | N/A SOFTVER = '1.1.1.1 ' / Softwere version (TCS.Camera.OCS.Sched) OCS_VER = '1 ' / OCS software version and date TCS_VER = '1 ' / TCS software version and date SCH_VER = '1 ' / OCS-Scheduler software version and date MAT_VER = '7.7.0.471' / Matlab version HDR_VER = '1 ' / Header version TRIGGER = 'N/A ' / trigger ID for TOO, e.g. VOEVENT-Nr TCSMODE = 'Star ' / TCS fundamental mode TCSSMODE= 'Active ' / TCS fundamental submode TCSFMODE= 'Pos ' / TCS focus mode TCSFSMOD= 'On-Target' / TCS focus submode TCSDMODE= 'Stop ' / TCS dome mode TCSDSMOD= 'N/A ' / TCS dome submode TCSWMODE= 'Slave ' / TCS windscreen mode TCSWSMOD= 'N/A ' / TCS windscreen submode OBSLAT = 33.3574 / [deg] Telescope geodetic latitude in WGS84 OBSLON = 116.8599 / [deg] Telescope geodetic longitude in WGS84 OBSALT = 1703.2 / [m] Telescope geodetic altitude in WGS84 DEFOCUS = 0. / [mm] Focus position - nominal focus FOCUSPOS= 1.3851 / [mm] Exposures focusPos DOMESTAT= 'open ' / Dome status at begining of exposure TRACKRA = 23.7 / [arcsec/hr] Track speed RA rel to sidereal TRACKDEC= -11.2 / [arcsec/hr] Track speed Dec rel to sidereal AZIMUTH = 113.8682 / [deg] Telescope Azimuth ALTITUDE= 36.81047 / [deg] Telescope altitude AIRMASS = 1.666232 / Telescope airmass TELRA = 334.402 / [deg] Telescope ap equinox of date RA TELDEC = 3.4225 / [deg] Telescope ap equinox of date Dec TELHA = 312.7096 / [deg] Telescope ap equinox of date HA DOMEAZ = 112.8563 / [deg] Dome azimuth WINDSCAL= 10.466 / [deg] Wind screen altitude WINDDIR = 2.2 / [deg] Azimuth of wind direction WINDSPED= 14.6328 / Wind speed (km/hour) OUTTEMP = 20.94444 / [C] Outside temperature OUTRELHU= 0.09 / [frac] Outside relative humidity OUTDEWPT= -12.94444 / [C] Outside dew point / INSTRUMENT TELEMETRY PANID = '_p48s ' / PAN identification DHSID = '_p48s ' / DHS identification ROISTATE= 'ROI ' / ROI State (FULL | ROI) CCDSEC = '[1:2048,1:4096]' / CCD section CCDSIZE = '[1:2048,1:4096]' / CCD size DATASEC = '[1:2048,1:4096]' / Data section DETSEC = '[1:2048,1:4096]' / Detector section ROISEC = '[1:2048,1:4096]' / ROI section FPA = 'P48MOSAIC' / Focal plan array CCDNAME = 'W94C2 ' / Detector mfg serial number CHECKSUM= 'O3aBP1ZBO1aBO1YB' / HDU checksum updated 2010-03-15T13:06:37 DATASUM = '395763289' / Data unit checksum updated 2010-03-15T13:06:37 DHEINF = 'SDSU, Gen-III' / Controller info DHEFIRM = '/usr/src/dsp/tim_m.lod' / DSP software CAM_VER = '20090615.1.3.100000' / Camera server date.rev.cfitsio LV_VER = '8.5 ' / LabVIEW software version PCI_VER = '2.0c ' / Astropci software version DETID = 'PTF/MOSAIC' / Detector ID AUTHOR = 'PTF/OCS/TCS/Camera' / Source for header information DATAMIN = 0. / Minimum value for array ROISTATE= 'ROI ' / ROI State (FULL | ROI) LEDBLUE = 'OFF ' / 470nm LED state (ON | OFF) LEDRED = 'OFF ' / 660nm LED state (ON | OFF) LEDNIR = 'OFF ' / 880nm LED state (ON | OFF) CCD9TEMP= 175.003 / [K] 0x0 servo temp sensor on CCD09 HSTEMP = 148.207 / [K] 0x1 heat spreader temp DHE0TEMP= 295.951 / [K] 0x2 detector head electronics temp, master DHE1TEMP= 298.162 / [K] 0x3 detector head electronics temp, slave DEWWTEMP= 284.71 / [K] 0x4 dewar wall temp HEADTEMP= 138.414 / [K] 0x5 cryo cooler cold head temp CCD5TEMP= 174.91 / [K] 0x6 temp sensor on CCD05 CCD11TEM= 176.061 / [K] 0x7 temp sensor on CCD11 CCD0TEMP= 169.515 / [K] 0x8 temp sensor on CCD00 RSTEMP = 232.61 / [K] 0x9 temp sensor on radiation shield DEWPRESS= 0.82 / [milli-torr] Dewar pressure DETHEAT = 38. / [%] Detector focal plane heater power NAMPSXY = '6 2 ' / Number of amplifiers in x y CCDSUM = '1 1 ' / [pix] Binning in x and y MODELFOC= 'N/A ' / MODELFOC CHECKSUM= '6aLZ8ZKZ6aKZ6YKZ' / HDU checksum updated 2010-03-15T13:06:37 DATASUM = ' 0' / Data unit checksum (2010-03-15T13:06:37) GAIN = 1.7 / [e-/D.N.] Gain of detector. READNOI = 5.1 / [e-] Read noise of detector. DARKCUR = 0.1 / [e-/s] Dark current of detector / SCAMP DISTORTION KEYWORDS RADECSYS= 'ICRS ' / Astrometric system PV1_0 = 0. / Projection distortion parameter PV1_1 = 1. / Projection distortion parameter PV1_2 = 0. / Projection distortion parameter PV1_4 = 0.000811808026654439 / Projection distortion parameter PV1_5 = 0.000610424561546246 / Projection distortion parameter PV1_6 = 0.000247550637436069 / Projection distortion parameter PV1_7 = 0.000103962986153903 / Projection distortion parameter PV1_8 = -0.000463678684598807 / Projection distortion parameter PV1_9 = -0.000431244263972048 / Projection distortion parameter PV1_10 = -0.000152691163850316 / Projection distortion parameter PV1_12 = -0.00204628855915067 / Projection distortion parameter PV1_13 = -0.00173071932398225 / Projection distortion parameter PV1_14 = 0.000212015319199711 / Projection distortion parameter PV1_15 = -0.000489268678679085 / Projection distortion parameter PV1_16 = -0.000182891514774611 / Projection distortion parameter PV2_0 = 0. / Projection distortion parameter PV2_1 = 1. / Projection distortion parameter PV2_2 = 0. / Projection distortion parameter PV2_4 = 0.000273521447624334 / Projection distortion parameter PV2_5 = 0.000876139200581004 / Projection distortion parameter PV2_6 = -0.000122736852992318 / Projection distortion parameter PV2_7 = -0.00115870481394187 / Projection distortion parameter PV2_8 = 0.000744209714565589 / Projection distortion parameter PV2_9 = -0.00031431316953523 / Projection distortion parameter PV2_10 = -0.00025720525696749 / Projection distortion parameter PV2_12 = -0.00074859772103692 / Projection distortion parameter PV2_13 = 0.000838107200656415 / Projection distortion parameter PV2_14 = -0.00012633881376049 / Projection distortion parameter PV2_15 = -0.0020312867769692 / Projection distortion parameter PV2_16 = 0.00524608854745148 / Projection distortion parameter FGROUPNO= 1 / SCAMP field group label ASTIRMS1= 0. / Astrom. dispersion RMS (intern., high S/N) ASTIRMS2= 0. / Astrom. dispersion RMS (intern., high S/N) ASTRRMS1= 3.620458E-05 / Astrom. dispersion RMS (ref., high S/N) ASTRRMS2= 3.332156E-05 / Astrom. dispersion RMS (ref., high S/N) ASTINST = 1 / SCAMP astrometric instrument label FLXSCALE= 0. / SCAMP relative flux scale MAGZEROP= 0. / SCAMP zero-point PHOTIRMS= 0. / mag dispersion RMS (internal, high S/N) RA_RMS = 0.1655724 / [arcsec] RMS of SCAMP fit from 2MASS matching DEC_RMS = 0.1891921 / [arcsec] RMS of SCAMP fit from 2MASS matching ASTROMN = 384 / Number of stars in SCAMP astrometric solution SCAMPPTH= '/ptf/pos/archive/fallbackcal/scamp/7/' / SCAMP catalog path SCAMPFIL= 'PTF_201006174759_c_e_uca3_t112521_u001916251_f02_p002899_c07.fits' / SIP DISTORTION KEYWORDS A_ORDER = 4 / Distortion order for A A_0_2 = 6.96807813586153E-08 / Projection distortion parameter A_0_3 = 1.20881759870351E-11 / Projection distortion parameter A_0_4 = -4.07297345125509E-15 / Projection distortion parameter A_1_1 = -1.71602989085006E-07 / Projection distortion parameter A_1_2 = -3.40958003336147E-11 / Projection distortion parameter A_1_3 = 1.08769435952671E-14 / Projection distortion parameter A_2_0 = 2.28067760155696E-07 / Projection distortion parameter A_2_1 = 3.6610309234789E-11 / Projection distortion parameter A_2_2 = 4.73755078335384E-15 / Projection distortion parameter A_3_0 = 8.24210855193549E-12 / Projection distortion parameter A_3_1 = 3.84753767306115E-14 / Projection distortion parameter A_4_0 = -4.54223812412034E-14 / Projection distortion parameter A_DMAX = 1.53122472683886 / Projection distortion parameter B_ORDER = 4 / Distortion order for B B_0_2 = -7.69933957449607E-08 / Projection distortion parameter B_0_3 = -9.16855566272424E-11 / Projection distortion parameter B_0_4 = 1.66630509620112E-14 / Projection distortion parameter B_1_1 = 2.46289708854316E-07 / Projection distortion parameter B_1_2 = -5.90207917198792E-11 / Projection distortion parameter B_1_3 = 1.86811615261732E-14 / Projection distortion parameter B_2_0 = 3.44908367419592E-08 / Projection distortion parameter B_2_1 = -2.49509936365959E-11 / Projection distortion parameter B_2_2 = 2.84841315780067E-15 / Projection distortion parameter B_3_0 = 2.02845080441181E-11 / Projection distortion parameter B_3_1 = -4.51317603382652E-14 / Projection distortion parameter B_4_0 = -1.16438849571175E-13 / Projection distortion parameter B_DMAX = 2.89468553502114 / Projection distortion parameter AP_ORDER= 4 / Distortion order for AP AP_0_1 = -2.3927681685928E-08 / Projection distortion parameter AP_0_2 = -6.97379868441328E-08 / Projection distortion parameter AP_0_3 = -1.21069584606865E-11 / Projection distortion parameter AP_0_4 = 4.07524721573973E-15 / Projection distortion parameter AP_1_0 = 5.65239128994064E-08 / Projection distortion parameter AP_1_1 = 1.71734217296344E-07 / Projection distortion parameter AP_1_2 = 3.41724875038451E-11 / Projection distortion parameter AP_1_3 = -1.08775499102067E-14 / Projection distortion parameter AP_2_0 = -2.28068482487158E-07 / Projection distortion parameter AP_2_1 = -3.66548961802381E-11 / Projection distortion parameter AP_2_2 = -4.75858241735224E-15 / Projection distortion parameter AP_3_0 = -8.24781966878619E-12 / Projection distortion parameter AP_3_1 = -3.85281201904104E-14 / Projection distortion parameter AP_4_0 = 4.54275049666924E-14 / Projection distortion parameter BP_ORDER= 4 / Distortion order for BP BP_0_1 = -1.50638746640517E-07 / Projection distortion parameter BP_0_2 = 7.70565767927487E-08 / Projection distortion parameter BP_0_3 = 9.18374546897802E-11 / Projection distortion parameter BP_0_4 = -1.66839467627906E-14 / Projection distortion parameter BP_1_0 = -4.87195269294628E-08 / Projection distortion parameter BP_1_1 = -2.46371690411844E-07 / Projection distortion parameter BP_1_2 = 5.9111535979953E-11 / Projection distortion parameter BP_1_3 = -1.87729776729012E-14 / Projection distortion parameter BP_2_0 = -3.46046151217313E-08 / Projection distortion parameter BP_2_1 = 2.51320825919019E-11 / Projection distortion parameter BP_2_2 = -2.85758325791527E-15 / Projection distortion parameter BP_3_0 = -2.04221364218494E-11 / Projection distortion parameter BP_3_1 = 4.51336286236569E-14 / Projection distortion parameter BP_4_0 = 1.16567578965612E-13 / Projection distortion parameter / DATA FLOW ORIGNAME= '/data/PTF_default_38068.fits' / Filename as written by the camera FILENAME= 'PTF200906253621_2_o_38068.fits' / Filename of delivered camera image PROCORIG= 'IPAC-PTF pipelines' / Processing origin PROCDATE= 'Tue Feb 21 03:34:46 2012' / Processing date/time (Pacific time) PTFVERSN= 5. / Version of PTFSCIENCEPIPELINE program PMASKPTH= '/ptf/pos/archive/fallbackcal/pmasks/' / Pathname of pixel mask PMASKFIL= 'bpm_2009060s_c07.v2.fits' / Filename of pixel mask SFLATPTH= '/ptf/pos/sbx1/2009/06/25/f2/c7/cal/p4/cId45986/' / Pathname of super SFLATFIL= 'PTF_200906250000_i_s_flat_t120000_u000045986_f02_p000000_c07.fits' SBIASPTH= '/ptf/pos/sbx1/2009/06/25/f2/c7/cal/p1/cId45922/' / Pathname of super SBIASFIL= 'PTF_200906250000_i_s_bias_t120000_u000045922_f00_p000000_c07.fits' DBNID = 121 / Database night ID DBEXPID = 22920 / Database exposure ID DBRID = 3663141 / Database raw-image ID DBPID = 12052003 / Database processed-image ID DBFID = 2 / Database filter ID DBPIID = 1 / Database P.I. ID DBPRID = 3 / Database project ID DBFIELD = 22920 / Database field ID DBSVID = 50 / Database software-version ID DBCVID = 56 / Database config-data-file ID END ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/header_with_time.fits0000644000175100001710000002070000000000000023004 0ustar00vstsdockerSIMPLE = F / Conforms to FITS standard? NO! BITPIX = -32 / IEEE single precision floating point NAXIS = 0 / No image data CRPIX1A = 513.0 / Pixel coordinate of reference point CRPIX2A = 513.0 / Pixel coordinate of reference point CRPIX3A = 1025.0 / Pixel coordinate of reference point CRPIX4A = 1.0 / Pixel coordinate of reference point PC1_1A = 0.866025404 / Linear transformation matrix element PC1_2A = 0.500000000 / Linear transformation matrix element PC2_1A = -0.500000000 / Linear transformation matrix element PC2_2A = 0.866025404 / Linear transformation matrix element CDELT1A = -0.10 / [deg] x-scale CUNIT1A = 'deg' / Degree units are required CTYPE1A = 'RA---SZP' / Right ascension in slant zenithal projection CRVAL1A = 150.0 / [deg] Right ascension at the reference point CNAME1A = 'Right ascension (J2000)' / Axis name for labelling purposes CDELT2A = 0.10 / [deg] y-scale CUNIT2A = 'deg' / Degree units are required CTYPE2A = 'DEC--SZP' / Declination in a slant zenithal projection CRVAL2A = -30.0 / [deg] Declination at the reference point CNAME2A = 'Declination (J2000)' / Axis name for labelling purposes PV1_1A = 0.0 / [deg] Native longitude of the reference point PV1_2A = 90.0 / [deg] Native latitude of the reference point PV1_3A = 195.0 / [deg] LONPOLEa by another name (precedence) PV1_4A = 999.0 / [deg] LATPOLEa by another name (precedence) PV2_1A = 0.0 / SZP distance, in spherical radii PV2_2A = 180.0 / [deg] SZP P-longitude PV2_3A = 45.0 / [deg] SZP P-latitude LONPOLEA= 195.0 / [deg] Native longitude of the NCP LATPOLEA= 999.0 / [deg] Native latitude of the NCP RADESYSA= 'FK5' / Mean equatorial coordinates, IAU 1984 system EQUINOXA= 2000.0 / [yr] Equinox of equatorial coordinates CDELT3A = -9.635265432E-6 / [m] Wavelength scale CUNIT3A = 'm' / Wavelength units CTYPE3A = 'WAVE-F2W' / Frequency axis expressed as wavelength CRVAL3A = 0.214982042 / [m] Reference wavelength CNAME3A = 'Wavelength' / Axis name for labelling purposes CRDER3A = 1.0E-11 / [m] Wavelength calibration, random error CSYER3A = 1.0E-12 / [m] Wavelength calibration, systematic error RESTFRQA= 1.42040575E9 / [Hz] HI rest frequency RESTWAVA= 0.211061141 / [m] HI rest wavelength SPECSYSA= 'BARYCENT' / Reference frame of spectral coordinates SSYSOBSA= 'TOPOCENT' / Reference frame of observation VELOSYSA= 1500.0 / [m/s] Bary-topo velocity towards the source SSYSSRCA= 'LSRK' / Reference frame of source redshift ZSOURCEA= 0.0025 / Redshift of the source CDELT4A = 1.0 / [s] Time scale CUNIT4A = 's' / Time units CTYPE4A = 'TIME ' / String value and comment containing quotes (') CRVAL4A = -2E3 / [s] Time at the reference point CNAME4A = 'Time offset' / Axis name for labelling purposes PS4_0A = 'UTC' / Time measurement system UNDEF = / Undefined keyvalue TRUE = T / Logical FALSE = F / Logical INT32 = 00000012345 / Not a 64-bit integer INT32 = -000000123456789 / Not a 64-bit integer INT32 = -2147483648 / Not a 64-bit integer (INT_MIN) INT32 = 2147483647 / Not a 64-bit integer (INT_MAX) INT32 = 0000000000000000000000000000000000012345 / Not a very long integer INT32 = -000000000000000000000000000123456789 / Not a very long integer INT64 = -2147483649 / 64-bit integer (INT_MIN - 1) INT64 = +2147483648 / 64-bit integer (INT_MAX + 1) INT64 = +100000000000000000 / 64-bit integer INT64 = -876543210987654321 / 64-bit integer INT64 = -9223372036854775808 / Not a very long integer (LONG_MIN) INT64 = +9223372036854775807 / Not a very long integer (LONG_MAX) INT64 = -000000000000000000000000000000876543210987654321 / 64-bit integer INTVL = -9223372036854775809 / Very long integer (LONG_MIN - 1) INTVL = +9223372036854775808 / Very long integer (LONG_MAX + 1) INTVL = -100000000000000000000000000000876543210987654321 / Very-long integer INTVL = +123456789012345678901234567890123456789012345678901234567890123456789INTVL = 1234567890123456789012345678901234567890123456789012345678901234567890FLOAT = 3.14159265358 / Floating point FLOAT = 1.602176565E-19 / Floating point, lower-case exp allowed FLOAT = 2.99792458E8 / Floating point FLOAT = 6.62606957D-34 / Floating point, lower-case exp allowed FLOAT = 6.02214129D23 / Floating point COMPLEX = (137, -1) / An integer complex keyvalue COMPLEX = (10E5, -0.1) / A floating point complex keyvalue GOODSTR = '"G''DAY" ' / A valid string keyvalue BLANKS = ' ' / An all-blank string equals a single blank LONGSTR = 'The loooooongest possible non-continued string value, 68 characters.'END ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/header_with_time_wcslib71.fits0000644000175100001710000002126000000000000024521 0ustar00vstsdockerSIMPLE = F / Conforms to FITS standard? NO! BITPIX = -32 / IEEE single precision floating point NAXIS = 0 / No image data CRPIX1A = 513.0 / Pixel coordinate of reference point CRPIX2A = 513.0 / Pixel coordinate of reference point CRPIX3A = 1025.0 / Pixel coordinate of reference point CRPIX4A = 1.0 / Pixel coordinate of reference point PC1_1A = 0.866025404 / Linear transformation matrix element PC1_2A = 0.500000000 / Linear transformation matrix element PC2_1A = -0.500000000 / Linear transformation matrix element PC2_2A = 0.866025404 / Linear transformation matrix element CDELT1A = -0.10 / [deg] x-scale CUNIT1A = 'deg' / Degree units are required CTYPE1A = 'RA---SZP' / Right ascension in slant zenithal projection CRVAL1A = 150.0 / [deg] Right ascension at the reference point CNAME1A = 'Right ascension (J2000)' / Axis name for labelling purposes CDELT2A = 0.10 / [deg] y-scale CUNIT2A = 'deg' / Degree units are required CTYPE2A = 'DEC--SZP' / Declination in a slant zenithal projection CRVAL2A = -30.0 / [deg] Declination at the reference point CNAME2A = 'Declination (J2000)' / Axis name for labelling purposes PV1_1A = 0.0 / [deg] Native longitude of the reference point PV1_2A = 90.0 / [deg] Native latitude of the reference point PV1_3A = 195.0 / [deg] LONPOLEa by another name (precedence) PV1_4A = 999.0 / [deg] LATPOLEa by another name (precedence) PV2_1A = 0.0 / SZP distance, in spherical radii PV2_2A = 180.0 / [deg] SZP P-longitude PV2_3A = 45.0 / [deg] SZP P-latitude LONPOLEA= 195.0 / [deg] Native longitude of the NCP LATPOLEA= 999.0 / [deg] Native latitude of the NCP RADESYSA= 'FK5' / Mean equatorial coordinates, IAU 1984 system EQUINOXA= 2000.0 / [yr] Equinox of equatorial coordinates CDELT3A = -9.635265432E-6 / [m] Wavelength scale CUNIT3A = 'm' / Wavelength units CTYPE3A = 'WAVE-F2W' / Frequency axis expressed as wavelength CRVAL3A = 0.214982042 / [m] Reference wavelength CNAME3A = 'Wavelength' / Axis name for labelling purposes CRDER3A = 1.0E-11 / [m] Wavelength calibration, random error CSYER3A = 1.0E-12 / [m] Wavelength calibration, systematic error RESTFRQA= 1.42040575E9 / [Hz] HI rest frequency RESTWAVA= 0.211061141 / [m] HI rest wavelength SPECSYSA= 'BARYCENT' / Reference frame of spectral coordinates SSYSOBSA= 'TOPOCENT' / Reference frame of observation VELOSYSA= 1500.0 / [m/s] Bary-topo velocity towards the source SSYSSRCA= 'LSRK' / Reference frame of source redshift ZSOURCEA= 0.0025 / Redshift of the source CDELT4A = 1.0 / [s] Time scale CUNIT4A = 's' / Time units CTYPE4A = 'TIME ' / String value and comment containing quotes (') CRVAL4A = -2E3 / [s] Time at the reference point CNAME4A = 'Time offset' / Axis name for labelling purposes PS4_0A = 'UTC' / Time measurement system DATEREFA= '1858-11-17' / ISO-8601 fiducial time MJDREFIA= 0.0 / [d] MJD of fiducial time, integer part MJDREFFA= 0.0 / [d] MJD of fiducial time, fractional part UNDEF = / Undefined keyvalue TRUE = T / Logical FALSE = F / Logical INT32 = 00000012345 / Not a 64-bit integer INT32 = -000000123456789 / Not a 64-bit integer INT32 = -2147483648 / Not a 64-bit integer (INT_MIN) INT32 = 2147483647 / Not a 64-bit integer (INT_MAX) INT32 = 0000000000000000000000000000000000012345 / Not a very long integer INT32 = -000000000000000000000000000123456789 / Not a very long integer INT64 = -2147483649 / 64-bit integer (INT_MIN - 1) INT64 = +2147483648 / 64-bit integer (INT_MAX + 1) INT64 = +100000000000000000 / 64-bit integer INT64 = -876543210987654321 / 64-bit integer INT64 = -9223372036854775808 / Not a very long integer (LONG_MIN) INT64 = +9223372036854775807 / Not a very long integer (LONG_MAX) INT64 = -000000000000000000000000000000876543210987654321 / 64-bit integer INTVL = -9223372036854775809 / Very long integer (LONG_MIN - 1) INTVL = +9223372036854775808 / Very long integer (LONG_MAX + 1) INTVL = -100000000000000000000000000000876543210987654321 / Very-long integer INTVL = +123456789012345678901234567890123456789012345678901234567890123456789INTVL = 1234567890123456789012345678901234567890123456789012345678901234567890FLOAT = 3.14159265358 / Floating point FLOAT = 1.602176565E-19 / Floating point, lower-case exp allowed FLOAT = 2.99792458E8 / Floating point FLOAT = 6.62606957D-34 / Floating point, lower-case exp allowed FLOAT = 6.02214129D23 / Floating point COMPLEX = (137, -1) / An integer complex keyvalue COMPLEX = (10E5, -0.1) / A floating point complex keyvalue GOODSTR = '"G''DAY" ' / A valid string keyvalue BLANKS = ' ' / An all-blank string equals a single blank LONGSTR = 'The loooooongest possible non-continued string value, 68 characters.'END ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/ie6d07ujq_wcs.fits0000644000175100001710000007020000000000000022075 0ustar00vstsdockerSIMPLE = T / conforms to FITS standard BITPIX = 8 / array data type NAXIS = 0 / number of array dimensions EXTEND = T WCSAXES = 2 / Number of coordinate axes CRPIX1 = 2048.0 / Pixel coordinate of reference point CRPIX2 = 1026.0 / Pixel coordinate of reference point PC1_1 = 3.920290602516E-06 / Coordinate transformation matrix element PC1_2 = -1.0082434475667E-05 / Coordinate transformation matrix element PC2_1 = -1.0351930440257E-05 / Coordinate transformation matrix element PC2_2 = -4.5644540153863E-06 / Coordinate transformation matrix element CDELT1 = 1.0 / [deg] Coordinate increment at reference point CDELT2 = 1.0 / [deg] Coordinate increment at reference point CUNIT1 = 'deg' / Units of coordinate increment and value CUNIT2 = 'deg' / Units of coordinate increment and value CTYPE1 = 'RA---TAN' / TAN (gnomonic) projection + SIP distortions CTYPE2 = 'DEC--TAN' / TAN (gnomonic) projection + SIP distortions CRVAL1 = 83.19300506082 / [deg] Coordinate value at reference point CRVAL2 = -67.73222548109 / [deg] Coordinate value at reference point LONPOLE = 180.0 / [deg] Native longitude of celestial pole LATPOLE = -67.73222548109 / [deg] Native latitude of celestial pole CRDER1 = 5.1597710370541 / [deg] Random error in coordinate CRDER2 = 4.728058065173 / [deg] Random error in coordinate WCSNAME = 'IDC_2731450pi' / Coordinate system title MJDREF = 0.0 / [d] MJD of fiducial time RADESYS = 'ICRS' / Equatorial coordinate system D2IMDIS1= 'LOOKUP ' / Detector to image correction type D2IM1 = 'EXTVER: 1' / Version number of WCSDVARR extension D2IM1 = 'NAXES: 2' / Number of independent variables in D2IM function D2IM1 = 'AXIS.1: 1' / Axis number of the 1st variable in a D2IM function D2IM1 = 'AXIS.2: 2' / Axis number of the 2nd variable in a D2IM function D2IMDIS2= 'LOOKUP ' / Detector to image correction type D2IM2 = 'EXTVER: 2' / Version number of WCSDVARR extension D2IM2 = 'NAXES: 2' / Number of independent variables in D2IM function D2IM2 = 'AXIS.1: 1' / Axis number of the 1st variable in a D2IM function D2IM2 = 'AXIS.2: 2' / Axis number of the 2nd variable in a D2IM function END XTENSION= 'IMAGE ' / Image extension BITPIX = -32 / array data type NAXIS = 2 / number of array dimensions NAXIS1 = 64 NAXIS2 = 32 PCOUNT = 0 / number of parameters GCOUNT = 1 / number of groups EXTNAME = 'D2IMARR ' / extension name CRPIX1 = 0.0 / Coordinate system reference pixel CRPIX2 = 0.0 / Coordinate system reference pixel CRVAL1 = 0.0 / Coordinate system value at reference pixel CRVAL2 = 0.0 / Coordinate system value at reference pixel CDELT1 = 64.0 / Coordinate increment along axis CDELT2 = 64.0 / Coordinate increment along axis EXTVER = 1 / extension value END :ƒo:ƒo:ƒo;o;ěĻ<o COMMENT EQUINOX = 2000.0000 / Mean equinox RADECSYS= 'ICRS ' / Astrometric system CTYPE1 = 'RA---TAN' / WCS projection type for this axis CTYPE2 = 'DEC--TAN' / WCS projection type for this axis CUNIT1 = 'deg ' / Axis unit CUNIT2 = 'deg ' / Axis unit CRVAL1 = 6.188763218E+01 / World coordinate on this axis CRVAL2 = 4.380823580E+00 / World coordinate on this axis CRPIX1 = 7.894960327E+02 / Reference pixel on this axis CRPIX2 = 3.975587511E+02 / Reference pixel on this axis CD1_1 = 2.804743351E-04 / Linear projection matrix CD1_2 = 1.807931352E-06 / Linear projection matrix CD2_1 = 2.367504576E-06 / Linear projection matrix CD2_2 = -2.808315811E-04 / Linear projection matrix PV1_0 = 1.456397190E-04 / Projection distortion parameter PV1_1 = 9.998189362E-01 / Projection distortion parameter PV1_2 = 3.901789582E-04 / Projection distortion parameter PV1_4 = 2.684396013E-03 / Projection distortion parameter PV1_5 = -7.179465569E-04 / Projection distortion parameter PV1_6 = 5.132011264E-04 / Projection distortion parameter PV1_7 = -1.672242131E-03 / Projection distortion parameter PV1_8 = 5.565322076E-04 / Projection distortion parameter PV1_9 = -8.240132461E-04 / Projection distortion parameter PV1_10 = -3.698351238E-05 / Projection distortion parameter PV1_12 = 3.777486931E-03 / Projection distortion parameter PV1_13 = -1.658254611E-03 / Projection distortion parameter PV1_14 = 2.989635088E-04 / Projection distortion parameter PV1_15 = -4.907197064E-04 / Projection distortion parameter PV1_16 = 2.889486855E-05 / Projection distortion parameter PV2_0 = 1.104553949E-04 / Projection distortion parameter PV2_1 = 1.000001456E+00 / Projection distortion parameter PV2_2 = 5.771870225E-04 / Projection distortion parameter PV2_4 = 2.836854693E-04 / Projection distortion parameter PV2_5 = -1.340251514E-04 / Projection distortion parameter PV2_6 = -7.102989931E-04 / Projection distortion parameter PV2_7 = 1.022790097E-03 / Projection distortion parameter PV2_8 = 2.436846754E-04 / Projection distortion parameter PV2_9 = 9.322698310E-04 / Projection distortion parameter PV2_10 = -7.413484043E-03 / Projection distortion parameter PV2_12 = 5.280834355E-04 / Projection distortion parameter PV2_13 = 4.532076725E-04 / Projection distortion parameter PV2_14 = -1.305400687E-04 / Projection distortion parameter PV2_15 = 6.693583421E-03 / Projection distortion parameter PV2_16 = 2.823700675E-02 / Projection distortion parameter FGROUPNO= 1 / SCAMP field group label ASTIRMS1= 0.000000000E+00 / Astrom. dispersion RMS (intern., high S/N) ASTIRMS2= 0.000000000E+00 / Astrom. dispersion RMS (intern., high S/N) ASTRRMS1= 8.822499895E-06 / Astrom. dispersion RMS (ref., high S/N) ASTRRMS2= 2.438161774E-05 / Astrom. dispersion RMS (ref., high S/N) ASTINST = 1 / SCAMP astrometric instrument label FLXSCALE= 1.666666667E-01 / SCAMP relative flux scale MAGZEROP= 30.0000 / SCAMP zero-point PHOTIRMS= 0.0000 / mag dispersion RMS (internal, high S/N) PHOTINST= 1 / SCAMP photometric instrument label PHOTLINK= ' F' / True if linked to a photometric field END ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/irac_sip.hdr0000644000175100001710000004564000000000000021116 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / FOUR-BYTE SINGLE PRECISION FLOATING POINT NAXIS = 2 / STANDARD FITS FORMAT NAXIS1 = 256 / STANDARD FITS FORMAT NAXIS2 = 256 / STANDARD FITS FORMAT EXTEND = T / TAPE MAY HAVE STANDARD FITS EXTENSIONS ORIGIN = 'SIRTF Science Center' / Organization generating this FITS file CREATOR = 'S8.9.0' / SW version used to create this FITS file TELESCOP= 'SIRTF ' / SIRTF spacecraft INSTRUME= 'IRAC ' / SIRTF instrument ID COMMENT Controlled data files (CDFs) used: COMMENT w_bqd_files_to_copy_to_sandbox.nl, fileID = 2 COMMENT w_bqd_pointrefine.nl, fileID = 120903 CHNLNUM = 1 / 1 digit instrument channel number EXPTYPE = 'sci ' / Exposure Type REQTYPE = 'AOR ' / Request type (AOR, IER, or SER) AOT_TYPE= 'IracMap ' / Observation template type AORLABEL= 'NSMLT-0013 HP' / AOR Label FOVID = 74 / Field of View ID FOVNAME = 'IRAC_Center_of_4.5&8.0umArray' / Field of View Name / PROPOSAL INFORMATION OBSRVR = 'Giovanni Fazio' / Observer Name (Last, First) OBSRVRID= 2 / Observer ID of Principal Investigator PROCYCL = 1 / Proposal Cycle PROGID = 35 / Program ID PROTITLE= 'MULTIPLICTY AND INFRARED COLORS OF NEARBY MLT DWARFS' / Program TitlePROGCAT = 29 / Program Category / TIME AND EXPOSURE INFORMATION DATE_OBS= '2003-12-06T10:46:35.021' / Date & time at DCE start MJD_OBS = 52979.449 / [days] MJD at DCE start (,JD-2400000.05) UTCS_OBS= 123979595.021 / [sec] J2000 ephem. time at DCE start SCLK_OBS= 755174834.035 / [sec] SCLK time (since 1/1/1980) at DCE start SAMPTIME= 0.2 / [sec] Sample integration time FRAMTIME= 30. / [sec] Time spent integrating (whole array) COMMENT Photons in Well = Flux[photons/sec/pixel] * FRAMTIME EXPTIME = 26.8 / [sec] Effective integration time per pixel COMMENT DN per pixel = Flux[photons/sec/pixel] / GAIN * EXPTIME AINTBEG = 43146779. / [Secs since IRAC turn-on] Time of integ. start ATIMEEND= 431497.75 / [Secs since IRAC turn-on] Time of integ. end AFOWLNUM= 16 / Fowler number AWAITPER= 118 / [0.2 sec] Wait period ANUMREPS= 1 / Number of repeat integrations AREADMOD= 0 / Full (0) or subarray (1) ABARREL = 4 / Barrel shift APEDSIG = 0 / 0=Normal, 1=Pedestal, 2=Signal / TARGET AND POINTING INFORMATION OBJECT = 'BRI0021-02' / Target Name OBJTYPE = 'TargetFixedSingle' / Object Type CRVAL1 = 6.15501347619052 / [deg] RA at CRPIX1,CRPIX2 averaged over DCE CRVAL2 = -2.07230798888938 / [deg] DEC at CRPIX1,CRPIX2 averaged over DCE RA_HMS = '00h24m37.2s' / [hh:mm:ss.s] CRVAL1 as sexagesimal DEC_DMS = '-02d04m20s' / [dd:mm:ss] CRVAL2 as sexagesimal RADESYS = 'ICRS ' / International Celestial Reference System EQUINOX = 2000. / Equinox for ICRF celestial coord. system CD1_1 = -0.000147943581033529 CD1_2 = 0.000305150643914974 CD2_1 = 0.000305100010374518 CD2_2 = 0.000147710276207053 CTYPE1 = 'RA---TAN-SIP' / RA---TAN with distortion in pixel space CTYPE2 = 'DEC--TAN-SIP' / DEC--TAN with distortion in pixel space CRPIX1 = 128. / Reference pixel along axis 1 CRPIX2 = 128. / Reference pixel along axis 2 CRDER1 = 0.000630078723280563 / [deg] Uncertainty in CRVAL1 CRDER2 = 0.000630066308654874 / [deg] Uncertainty in CRVAL2 UNCRTPA = 0.00186634833181778 / [deg] Uncertainty in position angle CSDRADEC= 5.27382080384386E-06 / [deg] Costandard deviation in RA and Dec SIGRA = 0.141175326515381 / [arcsec] RMS dispersion of RA over DCE SIGDEC = 0.0260011516228373 / [arcsec] RMS dispersion of DEC over DCE SIGPA = 0.786707814443969 / [arcsec] RMS dispersion of PA over DCE PA = 64.170376337596 / [deg] Position angle of axis 2 (E of N) (was ORRA_RQST = 6.15510111508666 / [deg] Requested RA at CRPIX1, CRPIX2 DEC_RQST= -2.07249338178042 / [deg] Requested Dec at CRPIX1, CRPIX2 PM_RA = -1.4108 / [arcsec/yr] Proper Motion in RA (J2000) PM_DEC = 1.50775 / [arcsec/yr] Proper Motion in Dec (J200) RMS_JIT = 0.00840644136311876 / [arcsec] RMS jitter during DCE RMS_JITY= 0.00544908399993541 / [arcsec] RMS jitter during DCE along Y RMS_JITZ= 0.00640122956573203 / [arcsec] RMS jitter during DCE along Z SIG_JTYZ= 0.00350446005496643 / [arcsec] Costadard deviation of jitter in YZ PTGDIFF = 0.738140521808859 / [arcsec] Offset btwn actual and rqsted pntng RA_REF = 6.10241222222221 / [deg] Commanded RA (J2000) of ref. position DEC_REF = -1.97235500000001 / [deg] Commanded Dec (J2000) of ref. position USEDBPHF= T / T if Boresight Pointing History File was used / DISTORTION KEYWORDS A_ORDER = 2 / polynomial order, axis 1, detector to sky A_0_2 = 6.666E-06 / distortion coefficient A_1_1 = 1.801E-05 / distortion coefficient A_2_0 = -2.353E-05 / distortion coefficient A_DMAX = 0.58 / [pixel] maximum correction B_ORDER = 2 / polynomial order, axis 2, detector to sky B_0_2 = 2.601E-05 / distortion coefficient B_1_1 = -2.944E-05 / distortion coefficient B_2_0 = -1.226E-06 / distortion coefficient B_DMAX = 0.902 / [pixel] maximum correction AP_ORDER= 2 / polynomial order, axis 1, sky to detector AP_0_1 = -5.463E-06 / distortion coefficient AP_0_2 = -6.666E-06 / distortion coefficient AP_1_0 = 1.14E-05 / distortion coefficient AP_1_1 = -1.801E-05 / distortion coefficient AP_2_0 = 2.353E-05 / distortion coefficient BP_ORDER= 2 / polynomial order, axis 2, sky to detector BP_0_1 = 1.975E-05 / distortion coefficient BP_0_2 = -2.601E-05 / distortion coefficient BP_1_0 = -1.495E-05 / distortion coefficient BP_1_1 = 2.944E-05 / distortion coefficient BP_2_0 = 1.225E-06 / distortion coefficient / PHOTOMETRY BUNIT = 'MJy/sr ' / Units of image data FLUXCONV= 0.111 / Flux Conv. factor (MJy/Str per DN/sec) GAIN = 3.3 / e/DN conversion / GENERAL MAPPING KEYWORDS CYCLENUM= 6 / Current cycle number DITHPOS = 1 / Current dither position / IRAC MAPPING KEYWORDS READMODE= 'FULL ' / Readout mode DITHSCAL= 'small ' / Dither scale (small, medium, large) / INSTRUMENT TELEMETRY DATA ASHTCON = 2 / Shutter condition (1:closed, 2: open) AWEASIDE= 0 / WEA side in use (0:B, 1:A) ACTXSTAT= 0 / Cmded transcal status ATXSTAT = 0 / transcal status ACFLSTAT= 0 / Cmded floodcal status AFLSTAT = 0 / floodcal status AVRSTUCC= -3.5 / [Volts] Cmded VRSTUC Bias AVRSTBEG= -3.51078391 / [Volts] VRSTUC Bias at start integration AVDETC = -2.75 / [Volts] Cmded VDET Bias AVDETBEG= -2.75721574 / [Volts] VDET Bias at start of integration AVGG1C = -3.6500001 / [Volts] Cmded VGG1 Bias AVGG1BEG= -3.2065742 / [Volts] VGG1 Bias at start of integration AVDDUCC = -3 / [Volts] Cmded VDDUC Bias AVDDUBEG= -3 / [Volts] VDDUC Bias at start integration AVGGCLC = 1 / [Volts] Cmnded VGGCL clock rail voltage AVGGCBEG= 1 / [Volts] VGGCL clock rail voltage AHTRIBEG= 204.70100403 / [uAmps] Heater current at start of integ AHTRVBEG= 2.39006352 / [Volts] Heater Voltage at start integ. AFPAT2B = 15.02370644 / [Deg_K] FPA Temp sensor #2 at start integ. AFPAT2BT= 431446.8125 / [Sec] FPA Temp sensor #2 time tag AFPAT2E = 15.02312088 / [Deg_K] FPA temp sensor #2, end integ. AFPAT2ET= 431476.9375 / [Sec] FPA temp sensor #2 time tag ACTENDT = 20.46821594 / [Deg_C] C&T board thermistor AFPECTE = 18.34936523 / [Deg_C] FPE control board thermistor AFPEATE = 21.90242577 / [Deg_C] FPE analog board thermistor ASHTEMPE= 21.59600639 / [Deg_C] Shutter board thermistor ATCTEMPE= 22.81523895 / [Deg_C] Temp. controller board thermistor ACETEMPE= 20.49869537 / [Deg_C] Calib. electronics board thermistor APDTEMPE= 21.47408295 / [Deg_C] PDU board thermistor ACATMP1E= 1.31549275 / [Deg_K] CA Temp, end integration for temp1 ACATMP2E= 1.29850066 / [Deg_K] CA Temp, end integration for temp2 ACATMP3E= 1.33064687 / [Deg_K] CA Temp, end integration for temp3 ACATMP4E= 1.3274169 / [Deg_K] CA Temp, end integration for temp4 ACATMP5E= 1.3255291 / [Deg_K] CA Temp, end integration for temp5 ACATMP6E= 1.32403958 / [Deg_K] CA Temp, end integration for temp6 ACATMP7E= 1.32282794 / [Deg_K] CA Temp, end integration for temp7 ACATMP8E= 1.31592035 / [Deg_K] CA Temp, end integration for temp8 / DATA FLOW KEYWORDS ORIGIN0 = 'JPL_FOS ' / Site where RAW FITS file was written CREATOR0= 'J5.1.0 ' / SW system that created RAW FITS DATE = '2003-12-17T00:52:57' / [YYYY-MM-DDThh:mm:ss UTC] file creation date AORKEY = 3937792 / AOR or EIR key. Astrnmy Obs Req/Instr Eng Req EXPID = 11 / Exposure ID (0-9999) DCENUM = 0 / DCE number (0-9999) TLMGRPS = 1 / expected number of groups FILE_VER= 1 / Version of the raw file made by SIS RAWFILE = 'IRAC.1.0003937792.0011.0000.01.mipl.fits' / Raw data file name CPT_VER = '3.0.94 ' / Channel Param Table FOS versioN CTD_VER = '3.0.94S ' / Cmded telemetry data version EXPDFLAG= F / (T/F) expedited DCE MISS_LCT= 0 / Total Missed Line Cnt in this FITS MANCPKT = F / T if this FITS is Missing Ancillary Data MISSDATA= F / T if this FITS is Missing Image Data PAONUM = 206 / PAO Number CAMPAIGN= 'IRAC003500' / Campaign DCEID = 6086781 / Data-Collection-Event ID DCEINSID= 626089 / DCE Instance ID DPID = 2631728 / Data Product Instance ID PIPENUM = 107 / Pipeline Script Number SOS_VER = 2 / Data-Product Version PLVID = 4 / Pipeline Version ID CALID = 6 / CalTrans Version ID SDRKEPID= 28809 / Sky Dark ensemble product ID PMSKFBID= 341 / Pixel mask ID LINCFBID= 357 / Fall-back Linearity correction ID FLATFBID= 718 / Fall-back flat ID FLXCFBID= 349 / Flux conversion ID MBLTFBID= 696 / Muxbleed Lookup Table ID MBCFFBID= 704 / Muxbleed Coefficients ID / PROCESSING HISTORY HISTORY job.c ver: 1.000000 HISTORY TRANHEAD v. 11.9, ran Tue Dec 16 16:52:35 2003 HISTORY CALTRANS v. 2.7, ran Tue Dec 16 16:52:44 2003 HISTORY cvti2r4 v. 1.25 A30501, generated 12/16/03 at 16:52:44 HISTORY FFCORR v. 1.000, ran Tue Dec 16 16:52:46 2003 HISTORY MUXBLEEDCORR v. 1.600, ran Tue Dec 16 16:52:50 2003 HISTORY FOWLINEARIZE v. 4.800000, ran Tue Dec 16 16:52:50 2003 HISTORY DARKSUBNG v. 1.000, ran Tue Dec 16 16:52:51 2003 HISTORY DARKDRIFT v. 3.5, ran Tue Dec 16 16:52:52 2003 HISTORY FLATAP v. 1.300 Tue Dec 16 16:52:53 2003 HISTORY DNTOFLUX v. 3.7, ran Tue Dec 16 16:52:57 2003 HISTORY PREDICTSAT v. 3.500000, ran Tue Dec 16 16:57:59 2003 HISTORY CALTRANS v. 2.7, ran Tue Dec 16 17:07:31 2003 HISTORY PTNTRAN v. 1.2, ran Tue Dec 16 17:07:32 2003 HISTORY FPGen v. 1.22, ran Tue Dec 16 17:07:33 2003 HISTORY CALTRANS v. 2.7, ran Wed Dec 17 06:14:18 2003 SOFTWARE= 'pointingrefine' / Pointing refinement using pnt-src correlation PTGVERSN= 5.3 / Version number of pointingrefine program RARFND = 6.15526023786181 / [deg] Refined RA DECRFND = -2.07244250543341 / [deg] Refined DEC CT2RFND = -64.5569826743286 / [deg] Refined CROTA2 PA_RFND = 64.5569826743286 / [deg] Refined PA (= -CROTA2_refined) ERARFND = 0.000535377007940228 / [deg] Error in refined RA EDECRFND= 0.00123072014833503 / [deg] Error in refined DEC EPA_RFND= 2.28015678741471 / [deg] Error in refined PA or CROTA2 NASTROM = 6 / # Astrometric sources for absolute refinement RARESID = -0.887761029918005 / [arcsec] Residual: Observed-Refined RA DECRESID= 0.484259558515454 / [arcsec] Residual: Observed-Refined DEC PA_RESID= -1391.7828122373 / [arcsec] Residual: Observed-Refined PA CD11RFND= -0.000145881550132727 / [deg/pix] Refined CD matrix element 1_1 CD12RFND= 0.000306140372692502 / [deg/pix] Refined CD matrix element 1_2 CD21RFND= 0.00030609131452955 / [deg/pix] Refined CD matrix element 2_1 CD22RFND= 0.000145647908967425 / [deg/pix] Refined CD matrix element 2_2 END ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/j94f05bgq_flt.fits0000644000175100001710000024310000000000000021764 0ustar00vstsdockerSIMPLE = T / Fits standard BITPIX = 16 / Bits per pixel NAXIS = 0 / Number of axes EXTEND = T / File may contain extensions ORIGIN = 'NOAO-IRAF FITS Image Kernel July 2003' / FITS file originator IRAF-TLM= '10:43:32 (18/12/2008)' / Time of last modification NEXTEND = 6 / Number of standard extensions DATE = '2007-02-08T21:38:46' / date this file was written (yyyy-mm-dd) FILENAME= 'j94f05bgq_flt.fits' / name of file FILETYPE= 'SCI ' / type of data found in data file TELESCOP= 'HST' / telescope used to acquire data INSTRUME= 'ACS ' / identifier for instrument used to acquire data EQUINOX = 2000.0 / equinox of celestial coord. system / DATA DESCRIPTION KEYWORDS ROOTNAME= 'j94f05bgq ' / rootname of the observation setIMAGETYP= 'EXT ' / type of exposure identifier PRIMESI = 'ACS ' / instrument designated as prime / TARGET INFORMATION TARGNAME= 'NGC104 ' / proposer's target name RA_TARG = 5.655000000000E+00 / right ascension of the target (deg) (J2000) DEC_TARG= -7.207055555556E+01 / declination of the target (deg) (J2000) / PROPOSAL INFORMATION PROPOSID= 10368 / PEP proposal identifier LINENUM = '05.004 ' / proposal logsheet line number PR_INV_L= 'Riess ' / last name of principal investigatorPR_INV_F= 'Adam ' / first name of principal investigator PR_INV_M= ' ' / middle name / initial of principal investigat / EXPOSURE INFORMATION SUNANGLE= 67.819656 / angle between sun and V1 axis MOONANGL= 57.400970 / angle between moon and V1 axis SUN_ALT = -5.746915 / altitude of the sun above Earth's limb FGSLOCK = 'FINE ' / commanded FGS lock (FINE,COARSE,GYROS,UNKNOWN) GYROMODE= '3' / observation scheduled with only two gyros (Y/N)REFFRAME= 'GSC1 ' / guide star catalog version DATE-OBS= '2005-03-07' / UT date of start of observation (yyyy-mm-dd) TIME-OBS= '06:51:26' / UT time of start of observation (hh:mm:ss) EXPSTART= 5.343628571938E+04 / exposure start time (Modified Julian Date) EXPEND = 5.343629036114E+04 / exposure end time (Modified Julian Date) EXPTIME = 400.000000 / exposure duration (seconds)--calculated EXPFLAG = 'NORMAL ' / Exposure interruption indicator QUALCOM1= ' 'QUALCOM2= ' 'QUALCOM3= ' 'QUALITY = ' ' / POINTING INFORMATION PA_V3 = 337.125305 / position angle of V3-axis of HST (deg) / TARGET OFFSETS (POSTARGS) POSTARG1= 0.000000 / POSTARG in axis 1 direction POSTARG2= 0.000000 / POSTARG in axis 2 direction / DIAGNOSTIC KEYWORDS OPUS_VER= 'OPUS 2006_6 ' / OPUS software system version number CAL_VER = '4.6.1 (13-Mar-2006)' / CALACS code version PROCTIME= 5.413989813657E+04 / Pipeline processing time (MJD) / SCIENCE INSTRUMENT CONFIGURATION OBSTYPE = 'IMAGING ' / observation type - imaging or spectroscopic OBSMODE = 'ACCUM ' / operating mode CTEIMAGE= 'NONE' / type of Charge Transfer Image, if applicable SCLAMP = 'NONE ' / lamp status, NONE or name of lamp which is on NRPTEXP = 1 / number of repeat exposures in set: default 1 SUBARRAY= F / data from a subarray (T) or full frame (F) DETECTOR= 'WFC' / detector in use: WFC, HRC, or SBC FILTER1 = 'F606W ' / element selected from filter wheel 1 FILTER2 = 'CLEAR2L ' / element selected from filter wheel 2 FWOFFSET= 0 / computed filter wheel offset FWERROR = F / filter wheel position error flag LRFWAVE = 0.000000 / proposed linear ramp filter wavelength APERTURE= 'WFC ' / aperture name PROPAPER= 'WFC ' / proposed aperture name DIRIMAGE= 'NONE ' / direct image for grism or prism exposure CTEDIR = 'NONE ' / CTE measurement direction: serial or parallel CRSPLIT = 1 / number of cosmic ray split exposures / CALIBRATION SWITCHES: PERFORM, OMIT, COMPLETE STATFLAG= F / Calculate statistics? WRTERR = T / write out error array extension DQICORR = 'COMPLETE' / data quality initialization ATODCORR= 'OMIT ' / correct for A to D conversion errors BLEVCORR= 'COMPLETE' / subtract bias level computed from overscan img BIASCORR= 'COMPLETE' / Subtract bias image FLSHCORR= 'OMIT ' / post flash correction CRCORR = 'OMIT ' / combine observations to reject cosmic rays EXPSCORR= 'COMPLETE' / process individual observations after cr-rejectSHADCORR= 'OMIT ' / apply shutter shading correction DARKCORR= 'COMPLETE' / Subtract dark image FLATCORR= 'COMPLETE' / flat field data PHOTCORR= 'COMPLETE' / populate photometric header keywords RPTCORR = 'OMIT ' / add individual repeat observations DRIZCORR= 'COMPLETE' / drizzle processing / CALIBRATION REFERENCE FILES BPIXTAB = 'jref$q860440tj_bpx.fits' / bad pixel table CCDTAB = 'jref$o151506fj_ccd.fits' / CCD calibration parameters ATODTAB = 'jref$kcb1734hj_a2d.fits' / analog to digital correction file OSCNTAB = 'jref$lch1459bj_osc.fits' / CCD overscan table BIASFILE= 'jref$p3v2228mj_bia.fits' / bias image file name FLSHFILE= 'jref$nad14594j_fls.fits' / post flash correction file name CRREJTAB= 'jref$n4e12511j_crr.fits' / cosmic ray rejection parameters SHADFILE= 'jref$kcb17349j_shd.fits' / shutter shading correction file DARKFILE= 'jref$p3v2228qj_drk.fits' / dark image file name PFLTFILE= 'jref$nar1136nj_pfl.fits' / pixel to pixel flat field file name DFLTFILE= 'N/A ' / delta flat field file name LFLTFILE= 'N/A ' / low order flat PHOTTAB = 'N/A ' / Photometric throughput table GRAPHTAB= 'mtab$r1m18595m_tmg.fits' / the HST graph table COMPTAB = 'mtab$r1j2146sm_tmc.fits' / the HST components table IDCTAB = 'jref$qbu1641sj_idc.fits' / image distortion correction table DGEOFILE= 'jref$qbu16424j_dxy.fits' / Distortion correction image MDRIZTAB= 'jref$p3p16511j_mdz.fits' / MultiDrizzle parameter table CFLTFILE= 'N/A ' / Coronagraphic spot image SPOTTAB = 'N/A ' / Coronagraphic spot offset table / COSMIC RAY REJECTION ALGORITHM PARAMETERS MEANEXP = 0.000000 / reference exposure time for parameters SCALENSE= 0.000000 / multiplicative scale factor applied to noise INITGUES= ' ' / initial guess method (MIN or MED) SKYSUB = ' ' / sky value subtracted (MODE or NONE) SKYSUM = 0.0 / sky level from the sum of all constituent imageCRSIGMAS= ' ' / statistical rejection criteria CRRADIUS= 0.000000 / rejection propagation radius (pixels) CRTHRESH= 0.000000 / rejection propagation threshold BADINPDQ= 0 / data quality flag bits to reject REJ_RATE= 0.0 / rate at which pixels are affected by cosmic rayCRMASK = F / flag CR-rejected pixels in input files (T/F) MDRIZSKY= 115.9195664624303 / Sky value computed by MultiDrizzle / OTFR KEYWORDS T_SGSTAR= ' ' / OMS calculated guide star control / PATTERN KEYWORDS PATTERN1= 'NONE ' / primary pattern type P1_SHAPE= ' ' / primary pattern shape P1_PURPS= ' ' / primary pattern purpose P1_NPTS = 0 / number of points in primary pattern P1_PSPAC= 0.000000 / point spacing for primary pattern (arc-sec) P1_LSPAC= 0.000000 / line spacing for primary pattern (arc-sec) P1_ANGLE= 0.000000 / angle between sides of parallelogram patt (deg)P1_FRAME= ' ' / coordinate frame of primary pattern P1_ORINT= 0.000000 / orientation of pattern to coordinate frame (degP1_CENTR= ' ' / center pattern relative to pointing (yes/no) PATTSTEP= 0 / position number of this point in the pattern / POST FLASH PARAMETERS FLASHDUR= 1.0 / Exposure time in seconds: 0.1 to 409.5 FLASHCUR= 'MED ' / Post flash current: OFF, LOW, MED, HIGH FLASHSTA= 'SUCCESSFUL ' / Status: SUCCESSFUL, ABORTED, NOT PERFORMED SHUTRPOS= 'B ' / Shutter position: A or B / ENGINEERING PARAMETERS CCDAMP = 'ABCD' / CCD Amplifier Readout Configuration CCDGAIN = 1 / commanded gain of CCD CCDOFSTA= 3 / commanded CCD bias offset for amplifier A CCDOFSTB= 3 / commanded CCD bias offset for amplifier B CCDOFSTC= 3 / commanded CCD bias offset for amplifier C CCDOFSTD= 3 / commanded CCD bias offset for amplifier D / CALIBRATED ENGINEERING PARAMETERS ATODGNA = 9.9989998E-01 / calibrated gain for amplifier A ATODGNB = 9.7210002E-01 / calibrated gain for amplifier B ATODGNC = 1.0107000E+00 / calibrated gain for amplifier C ATODGND = 1.0180000E+00 / calibrated gain for amplifier D READNSEA= 4.9699998E+00 / calibrated read noise for amplifier A READNSEB= 4.8499999E+00 / calibrated read noise for amplifier B READNSEC= 5.2399998E+00 / calibrated read noise for amplifier C READNSED= 4.8499999E+00 / calibrated read noise for amplifier D BIASLEVA= 2.4281760E+03 / bias level for amplifier A BIASLEVB= 2.5189324E+03 / bias level for amplifier B BIASLEVC= 2.4417756E+03 / bias level for amplifier C BIASLEVD= 2.4699448E+03 / bias level for amplifier D / ASSOCIATION KEYWORDS ASN_ID = 'NONE ' / unique identifier assigned to association ASN_TAB = 'NONE ' / name of the association table ASN_MTYP= ' ' / Role of the Member in the Association UPWCSVER= '1.1.3.dev30781' / Version of STWCS used to updated the WCS PYWCSVER= '1.12.1.dev3982' / Version of PYWCS used to updated the WCS HISTORY CCD parameters table: HISTORY reference table jref$o151506fj_ccd.fits HISTORY inflight HISTORY June 2002 HISTORY Uncertainty array initialized. HISTORY DQICORR complete ... HISTORY values checked for saturation HISTORY DQ array initialized ... HISTORY reference table jref$q860440tj_bpx.fits HISTORY BLEVCORR complete; bias level from overscan was subtracted. HISTORY BLEVCORR does not include correction for drift along lines. HISTORY Overscan region table: HISTORY reference table jref$lch1459bj_osc.fits HISTORY BIASCORR complete ... HISTORY reference image jref$p3v2228mj_bia.fits HISTORY INFLIGHT 05/03/2005 23/03/2005 HISTORY Superbias by Ray Lucas from proposal 10367 or 10370 HISTORY CCD parameters table: HISTORY reference table jref$o151506fj_ccd.fits HISTORY inflight HISTORY June 2002 HISTORY DARKCORR complete ... HISTORY reference image jref$p3v2228qj_drk.fits HISTORY INFLIGHT 05/03/2005 23/03/2005 HISTORY Superdark by Ray Lucas from proposal 10367 or 10370 HISTORY FLATCORR complete ... HISTORY reference image jref$nar1136nj_pfl.fits HISTORY InFlight 18/04/2002 - 09/05/2002 HISTORY F606W step +1 flat w/ mote shifted to -1 step HISTORY PHOTCORR complete ... HISTORY reference table mtab$r1m18595m_tmg.fits HISTORY reference table mtab$r1j2146sm_tmc.fits HISTORY EXPSCORR complete ... TDDCORR = 'PERFORM ' WFCTDD = 'T ' DISTNAME= 'j94f05bgq_qbu1641sj-NOMODEL-NOMODEL' SIPNAME = 'j94f05bgq_qbu1641sj' END XTENSION= 'IMAGE ' / Image extension BITPIX = -32 / Bits per pixel NAXIS = 2 / Number of axes NAXIS1 = 1 / Axis length NAXIS2 = 1 / Axis length PCOUNT = 0 / No 'random' parameters GCOUNT = 1 / Only one group ORIGIN = 'NOAO-IRAF FITS Image Kernel July 2003' / FITS file originator EXTNAME = 'SCI ' / Extension name EXTVER = 1 / Extension version DATE = '2007-02-08T21:38:47' / Date FITS file was generated IRAF-TLM= '13:38:23 (20/08/2008)' / Time of last modification INHERIT = T / inherit the primary header EXPNAME = 'j94f05bgq ' / exposure identifier BUNIT = 'ELECTRONS' / brightness units / WFC CCD CHIP IDENTIFICATION CCDCHIP = 2 / CCD chip (1 or 2) / World Coordinate System and Related Parameters WCSAXES = 2 / number of World Coordinate System axes CRPIX1 = 2048.0 / x-coordinate of reference pixel CRPIX2 = 1024.0 / y-coordinate of reference pixel CRVAL1 = 5.63056810618 / first axis value at reference pixel CRVAL2 = -72.05457184278998 / second axis value at reference pixel CTYPE1 = 'RA---TAN-SIP' / the coordinate type for the first axis CTYPE2 = 'DEC--TAN-SIP' / the coordinate type for the second axis CD1_1 = 1.29056256197165E-05 / partial of first axis coordinate w.r.t. x CD1_2 = 5.95309123310338E-06 / partial of first axis coordinate w.r.t. y CD2_1 = 5.0220581265601E-06 / partial of second axis coordinate w.r.t. x CD2_2 = -1.2644774105568E-05 / partial of second axis coordinate w.r.t. y LTV1 = 0.0000000E+00 / offset in X to subsection start LTV2 = 0.0000000E+00 / offset in Y to subsection start LTM1_1 = 1.0 / reciprocal of sampling rate in X LTM2_2 = 1.0 / reciprocal of sampling rate in Y ORIENTAT= 154.7891975615892 / position angle of image y axis (deg. e of n) RA_APER = 5.655000000000E+00 / RA of aperture reference position DEC_APER= -7.207055555556E+01 / Declination of aperture reference position PA_APER = 154.533 / Position Angle of reference aperture center (deVAFACTOR= 1.000018683511E+00 / velocity aberration plate scale factor / READOUT DEFINITION PARAMETERS CENTERA1= 2073 / subarray axis1 center pt in unbinned dect. pix CENTERA2= 1035 / subarray axis2 center pt in unbinned dect. pix SIZAXIS1= 4096 / subarray axis1 size in unbinned detector pixelsSIZAXIS2= 2048 / subarray axis2 size in unbinned detector pixelsBINAXIS1= 1 / axis1 data bin size in unbinned detector pixelsBINAXIS2= 1 / axis2 data bin size in unbinned detector pixels / PHOTOMETRY KEYWORDS PHOTMODE= 'ACS WFC1 F606W' / observation con PHOTFLAM= 7.9064521E-20 / inverse sensitivity, ergs/cm2/Ang/electron PHOTZPT = -2.1100000E+01 / ST magnitude zero point PHOTPLAM= 5.9176797E+03 / Pivot wavelength (Angstroms) PHOTBW = 6.7231146E+02 / RMS bandwidth of filter plus detector / REPEATED EXPOSURES INFO NCOMBINE= 1 / number of image sets combined during CR rejecti / DATA PACKET INFORMATION FILLCNT = 0 / number of segments containing fill ERRCNT = 0 / number of segments containing errors PODPSFF = F / podps fill present (T/F) STDCFFF = F / ST DDF fill present (T/F) STDCFFP = 'x5569 ' / ST DDF fill pattern (hex) / ON-BOARD COMPRESSION INFORMATION WFCMPRSD= F / was WFC data compressed? (T/F) CBLKSIZ = 0 / size of compression block in 2-byte words LOSTPIX = 0 / #pixels lost due to buffer overflow COMPTYP = 'None ' / compression type performed (Partial/Full/None) / IMAGE STATISTICS AND DATA QUALITY FLAGS NGOODPIX= 7822781 / number of good pixels SDQFLAGS= 31743 / serious data quality flags GOODMIN = -2.5959351E+02 / minimum value of good pixels GOODMAX = 6.5220551E+04 / maximum value of good pixels GOODMEAN= 2.0491536E+02 / mean value of good pixels SOFTERRS= 0 / number of soft error pixels (DQF=1) SNRMIN = -8.0327058E-01 / minimum signal to noise of good pixels SNRMAX = 2.1379723E+02 / maximum signal to noise of good pixels SNRMEAN = 1.0889255E+01 / mean value of signal to noise of good pixels MEANDARK= 1.5474443E+00 / average of the dark values subtracted MEANBLEV= 2.4558604E+03 / average of all bias levels subtracted MEANFLSH= 0.000000 / Mean number of counts in post flash exposure OCRVAL1 = 5.63056810618 / first axis value at reference pixel OCRVAL2 = -72.05457184279 / second axis value at reference pixel OCRPIX2 = 1024.0 / y-coordinate of reference pixel OCRPIX1 = 2048.0 / x-coordinate of reference pixel ONAXIS2 = 2048 / Axis length ONAXIS1 = 4096 / Axis length OCD2_2 = -1.26445E-05 / partial of second axis coordinate w.r.t. y OCD2_1 = 5.02243E-06 / partial of second axis coordinate w.r.t. x OORIENTA= 154.7886863186197 / position angle of image y axis (deg. e of n) OCTYPE1 = 'RA---TAN' / the coordinate type for the first axis OCD1_1 = 1.29046E-05 / partial of first axis coordinate w.r.t. x OCD1_2 = 5.9531E-06 / partial of first axis coordinate w.r.t. y OCTYPE2 = 'DEC--TAN' / the coordinate type for the second axis WCSCDATE= '21:39:44 (08/02/2007)' / Time WCS keywords were copied. A_0_2 = 2.16615952976212E-06 B_0_2 = -7.2168814507744E-06 A_1_1 = -5.1974576466834E-06 B_1_1 = 6.18443235774478E-06 A_2_0 = 8.551277582556502E-06 B_2_0 = -1.7464918770586E-06 A_0_3 = 1.08193519820265E-11 B_0_3 = -4.1754720492749E-10 A_1_2 = -5.234870743692412E-10 B_1_2 = -6.169265268681388E-11 A_2_1 = -3.9771547747287E-11 B_2_1 = -5.085716167386211E-10 A_3_0 = -4.7304448292227E-10 B_3_0 = 8.56763542781631E-11 A_0_4 = 1.49356171166049E-14 B_0_4 = -9.9570490655478E-15 A_1_3 = -2.456997553774615E-14 B_1_3 = 1.21743011568848E-14 A_2_2 = 3.46791267104378E-14 B_2_2 = -3.6614325928657E-14 A_3_1 = 1.971022971660309E-15 B_3_1 = -3.7795068054874E-15 A_4_0 = 2.37430106240231E-14 B_4_0 = -1.7687653826004E-14 A_ORDER = 4 B_ORDER = 4 HISTORY The following throughput tables were used: crotacomp$hst_ota_007_syn.fitHISTORY s, cracscomp$acs_wfc_im123_004_syn.fits, cracscomp$acs_f606w_005_syn.fitHISTORY s, cracscomp$acs_wfc_ebe_win12f_005_syn.fits, cracscomp$acs_wfc_ccd1_017HISTORY _syn.fits TDDALPHA= 0.1195051334702275 TDDBETA = -0.03716837782340918 IDCSCALE= 0.05 IDCV2REF= 256.6222229003906 IDCV3REF= 302.2264099121094 IDCTHETA= 0.0 OCX10 = 0.001961771095643072 OCX11 = 0.0498307741748614 OCY10 = 0.05027452911198226 OCY11 = 0.001490550115269471 SORIENTA= 154.7925383197021 / position angle of image y axis (deg. e of n) SCRVAL1 = 5.63056810618 / first axis value at reference pixel SNAXIS2 = 2048 / Axis length SNAXIS1 = 4096 / Axis length SCRVAL2 = -72.05457184279 / second axis value at reference pixel SCTYPE1 = 'RA---TAN-SIP' / the coordinate type for the first axis SCTYPE2 = 'DEC--TAN-SIP' / the coordinate type for the second axis SCD2_2 = -1.264489181627715E-05 / partial of second axis coordinate w.r.t. y SCD2_1 = 5.022886862247075E-06 / partial of second axis coordinate w.r.t. x SCD1_2 = 5.952245949610081E-06 / partial of first axis coordinate w.r.t. y SCRPIX2 = 1024.0 / y-coordinate of reference pixel SCRPIX1 = 2048.0 / x-coordinate of reference pixel SCD1_1 = 1.290545120875315E-05 / partial of first axis coordinate w.r.t. x IDCXREF = 2048.0 IDCYREF = 1024.0 WCSNAMEO= 'OPUS ' WCSAXESO= 2 CRPIX1O = 2048 CRPIX2O = 1024 CDELT1O = 1 CDELT2O = 1 CUNIT1O = 'deg ' CUNIT2O = 'deg ' CTYPE1O = 'RA---TAN-SIP' CTYPE2O = 'DEC--TAN-SIP' CRVAL1O = 5.63056810618 CRVAL2O = -72.0545718428 LONPOLEO= 180 LATPOLEO= -72.0545718428 RESTFRQO= 0 RESTWAVO= 0 CD1_1O = 1.29056256334E-05 CD1_2O = 5.9530912342E-06 CD2_1O = 5.02205812656E-06 CD2_2O = -1.26447741482E-05 IDCTAB = 'jref$qbu1641sj_idc.fits' WCSNAME = 'IDC_qbu1641sj' END XTENSION= 'IMAGE ' / Image extension BITPIX = -32 / Bits per pixel NAXIS = 0 / Number of axes PCOUNT = 0 / No 'random' parameters GCOUNT = 1 / Only one group ORIGIN = 'NOAO-IRAF FITS Image Kernel July 2003' / FITS file originator EXTNAME = 'ERR ' / Extension name EXTVER = 1 / Extension version DATE = '2007-02-08T21:38:48' / Date FITS file was generated IRAF-TLM= '13:38:31 (20/08/2008)' / Time of last modification INHERIT = T / inherit the primary header EXPNAME = 'j94f05bgq ' / exposure identifier BUNIT = 'ELECTRONS' / brightness units / World Coordinate System and Related Parameters WCSAXES = 2 / number of World Coordinate System axes CRPIX1 = 2048 / x-coordinate of reference pixel CRPIX2 = 1024 / y-coordinate of reference pixel CRVAL1 = 5.63056810618 / first axis value at reference pixel CRVAL2 = -72.0545718428 / second axis value at reference pixel CTYPE1 = 'RA---TAN-SIP' / the coordinate type for the first axis CTYPE2 = 'DEC--TAN-SIP' / the coordinate type for the second axis CD1_1 = 1.29056256197E-05 / partial of first axis coordinate w.r.t. x CD1_2 = 5.9530912331E-06 / partial of first axis coordinate w.r.t. y CD2_1 = 5.02205812656E-06 / partial of second axis coordinate w.r.t. x CD2_2 = -1.26447741056E-05 / partial of second axis coordinate w.r.t. y LTV1 = 0.0000000E+00 / offset in X to subsection start LTV2 = 0.0000000E+00 / offset in Y to subsection start LTM1_1 = 1.0 / reciprocal of sampling rate in X LTM2_2 = 1.0 / reciprocal of sampling rate in Y ORIENTAT= 154.789 / position angle of image y axis (deg. e of n) RA_APER = 5.655000000000E+00 / RA of aperture reference position DEC_APER= -7.207055555556E+01 / Declination of aperture reference position PA_APER = 154.533 / Position Angle of reference aperture center (deVAFACTOR= 1.000018683511E+00 / velocity aberration plate scale factor / IMAGE STATISTICS AND DATA QUALITY FLAGS NGOODPIX= 7822781 / number of good pixels SDQFLAGS= 31743 / serious data quality flags GOODMIN = 5.0154119E+00 / minimum value of good pixels GOODMAX = 4.6192120E+02 / maximum value of good pixels GOODMEAN= 1.3078087E+01 / mean value of good pixels TDDBETA = 0. TDDALPHA= 0. CDELT1 = 1 CDELT2 = 1 CUNIT1 = 'deg ' CUNIT2 = 'deg ' LONPOLE = 180 LATPOLE = -72.0545718428 RESTFRQ = 0 RESTWAV = 0 WCSNAME = 'IDC_qbu1641sj' END XTENSION= 'IMAGE ' / Image extension BITPIX = 16 / Bits per pixel NAXIS = 0 / Number of axes PCOUNT = 0 / No 'random' parameters GCOUNT = 1 / Only one group ORIGIN = 'NOAO-IRAF FITS Image Kernel July 2003' / FITS file originator EXTNAME = 'DQ ' / Extension name EXTVER = 1 / Extension version DATE = '2007-02-08T21:38:48' / Date FITS file was generated IRAF-TLM= '21:38:48 (08/02/2007)' / Time of last modification INHERIT = T / inherit the primary header EXPNAME = 'j94f05bgq ' / exposure identifier BUNIT = 'UNITLESS ' / brightness units / World Coordinate System and Related Parameters WCSAXES = 2 / number of World Coordinate System axes CRPIX1 = 2048 / x-coordinate of reference pixel CRPIX2 = 1024 / y-coordinate of reference pixel CRVAL1 = 5.63056810618 / first axis value at reference pixel CRVAL2 = -72.0545718428 / second axis value at reference pixel CTYPE1 = 'RA---TAN-SIP' / the coordinate type for the first axis CTYPE2 = 'DEC--TAN-SIP' / the coordinate type for the second axis CD1_1 = 1.29056256197E-05 / partial of first axis coordinate w.r.t. x CD1_2 = 5.9530912331E-06 / partial of first axis coordinate w.r.t. y CD2_1 = 5.02205812656E-06 / partial of second axis coordinate w.r.t. x CD2_2 = -1.26447741056E-05 / partial of second axis coordinate w.r.t. y LTV1 = 0.0000000E+00 / offset in X to subsection start LTV2 = 0.0000000E+00 / offset in Y to subsection start LTM1_1 = 1.0 / reciprocal of sampling rate in X LTM2_2 = 1.0 / reciprocal of sampling rate in Y ORIENTAT= 154.789 / position angle of image y axis (deg. e of n) RA_APER = 5.655000000000E+00 / RA of aperture reference position DEC_APER= -7.207055555556E+01 / Declination of aperture reference position PA_APER = 154.533 / Position Angle of reference aperture center (deVAFACTOR= 1.000018683511E+00 / velocity aberration plate scale factor CDELT1 = 1 CDELT2 = 1 CUNIT1 = 'deg ' CUNIT2 = 'deg ' LONPOLE = 180 LATPOLE = -72.0545718428 RESTFRQ = 0 RESTWAV = 0 WCSNAME = 'IDC_qbu1641sj' END XTENSION= 'IMAGE ' / Image extension BITPIX = -32 / Bits per pixel NAXIS = 2 / Number of axes NAXIS1 = 1 / Axis length NAXIS2 = 1 / Axis length PCOUNT = 0 / No 'random' parameters GCOUNT = 1 / Only one group ORIGIN = 'NOAO-IRAF FITS Image Kernel July 2003' / FITS file originator EXTNAME = 'SCI ' / Extension name EXTVER = 2 / Extension version DATE = '2007-02-08T21:39:08' / Date FITS file was generated IRAF-TLM= '21:39:07 (08/02/2007)' / Time of last modification INHERIT = T / inherit the primary header EXPNAME = 'j94f05bgq ' / exposure identifier BUNIT = 'ELECTRONS' / brightness units / WFC CCD CHIP IDENTIFICATION CCDCHIP = 1 / CCD chip (1 or 2) / World Coordinate System and Related Parameters WCSAXES = 2 / number of World Coordinate System axes CRPIX1 = 2048.0 / x-coordinate of reference pixel CRPIX2 = 1024.0 / y-coordinate of reference pixel CRVAL1 = 5.670733269328501 / first axis value at reference pixel CRVAL2 = -72.08067552067514 / second axis value at reference pixel CTYPE1 = 'RA---TAN-SIP' / the coordinate type for the first axis CTYPE2 = 'DEC--TAN-SIP' / the coordinate type for the second axis CD1_1 = 1.28168672384053E-05 / partial of first axis coordinate w.r.t. x CD1_2 = 5.85585924019860E-06 / partial of first axis coordinate w.r.t. y CD2_1 = 4.80078206009106E-06 / partial of second axis coordinate w.r.t. x CD2_2 = -1.2175120783707E-05 / partial of second axis coordinate w.r.t. y LTV1 = 0.0000000E+00 / offset in X to subsection start LTV2 = 0.0000000E+00 / offset in Y to subsection start LTM1_1 = 1.0 / reciprocal of sampling rate in X LTM2_2 = 1.0 / reciprocal of sampling rate in Y ORIENTAT= 154.3138744206447 / position angle of image y axis (deg. e of n) RA_APER = 5.655000000000E+00 / RA of aperture reference position DEC_APER= -7.207055555556E+01 / Declination of aperture reference position PA_APER = 154.533 / Position Angle of reference aperture center (deVAFACTOR= 1.000018683511E+00 / velocity aberration plate scale factor / READOUT DEFINITION PARAMETERS CENTERA1= 2073 / subarray axis1 center pt in unbinned dect. pix CENTERA2= 1035 / subarray axis2 center pt in unbinned dect. pix SIZAXIS1= 4096 / subarray axis1 size in unbinned detector pixelsSIZAXIS2= 2048 / subarray axis2 size in unbinned detector pixelsBINAXIS1= 1 / axis1 data bin size in unbinned detector pixelsBINAXIS2= 1 / axis2 data bin size in unbinned detector pixels / PHOTOMETRY KEYWORDS PHOTMODE= 'ACS WFC1 F606W' / observation con PHOTFLAM= 7.9064521E-20 / inverse sensitivity, ergs/cm2/Ang/electron PHOTZPT = -2.1100000E+01 / ST magnitude zero point PHOTPLAM= 5.9176797E+03 / Pivot wavelength (Angstroms) PHOTBW = 6.7231146E+02 / RMS bandwidth of filter plus detector / REPEATED EXPOSURES INFO NCOMBINE= 1 / number of image sets combined during CR rejecti / DATA PACKET INFORMATION FILLCNT = 0 / number of segments containing fill ERRCNT = 0 / number of segments containing errors PODPSFF = F / podps fill present (T/F) STDCFFF = F / ST DDF fill present (T/F) STDCFFP = '0x5569' / ST DDF fill pattern (hex) / ON-BOARD COMPRESSION INFORMATION WFCMPRSD= F / was WFC data compressed? (T/F) CBLKSIZ = 0 / size of compression block in 2-byte words LOSTPIX = 0 / #pixels lost due to buffer overflow COMPTYP = 'None ' / compression type performed (Partial/Full/None) / IMAGE STATISTICS AND DATA QUALITY FLAGS NGOODPIX= 7842694 / number of good pixels SDQFLAGS= 31743 / serious data quality flags GOODMIN = -7.0795517E+01 / minimum value of good pixels GOODMAX = 6.9170820E+04 / maximum value of good pixels GOODMEAN= 2.3160507E+02 / mean value of good pixels SOFTERRS= 0 / number of soft error pixels (DQF=1) SNRMIN = -2.9959621E+00 / minimum signal to noise of good pixels SNRMAX = 2.1083392E+02 / maximum signal to noise of good pixels SNRMEAN = 1.1493363E+01 / mean value of signal to noise of good pixels MEANDARK= 1.7685415E+00 / average of the dark values subtracted MEANBLEV= 2.4735542E+03 / average of all bias levels subtracted MEANFLSH= 0.000000 / Mean number of counts in post flash exposure OCRVAL1 = 5.670732627827 / first axis value at reference pixel OCRVAL2 = -72.08067512165999 / second axis value at reference pixel OCRPIX2 = 1024.0 / y-coordinate of reference pixel OCRPIX1 = 2048.0 / x-coordinate of reference pixel ONAXIS2 = 2048 / Axis length ONAXIS1 = 4096 / Axis length OCD2_2 = -1.21751E-05 / partial of second axis coordinate w.r.t. y OCD2_1 = 4.80165E-06 / partial of second axis coordinate w.r.t. x OORIENTA= 154.3148269477964 / position angle of image y axis (deg. e of n) OCTYPE1 = 'RA---TAN' / the coordinate type for the first axis OCD1_1 = 1.28162E-05 / partial of first axis coordinate w.r.t. x OCD1_2 = 5.8556E-06 / partial of first axis coordinate w.r.t. y OCTYPE2 = 'DEC--TAN' / the coordinate type for the second axis WCSCDATE= '21:40:01 (08/02/2007)' / Time WCS keywords were copied. A_0_2 = 2.261941311576225E-06 B_0_2 = -9.798580190744584E-06 A_1_1 = -7.5302899956868E-06 B_1_1 = 6.42569978230108E-06 A_2_0 = 8.518868718265025E-06 B_2_0 = -2.965892204849563E-06 A_0_3 = 6.510508887319651E-11 B_0_3 = -4.14215027648948E-10 A_1_2 = -5.253920848284526E-10 B_1_2 = -3.0354268445463E-11 A_2_1 = -1.0714005144979E-10 B_2_1 = -4.4034920544682E-10 A_3_0 = -4.693635321207041E-10 B_3_0 = 9.00334226345491E-11 A_0_4 = 1.35191450637820E-13 B_0_4 = -1.5248976030166E-13 A_1_3 = -1.4269338934146E-14 B_1_3 = 2.75911359120267E-14 A_2_2 = 9.70199525902786E-14 B_2_2 = -1.0403608182763E-13 A_3_1 = 3.800597894287968E-14 B_3_1 = -3.8363936250847E-14 A_4_0 = 1.836278740012908E-14 B_4_0 = -1.6913942401142E-14 A_ORDER = 4 B_ORDER = 4 IDCSCALE= 0.05 IDCV2REF= 260.8870544433594 IDCV3REF= 198.3322296142578 IDCTHETA= 0.0 OCX10 = 0.002267080585457191 OCX11 = 0.0492242502262243 OCY10 = 0.04858284026784934 OCY11 = 0.002132039303452174 TDDALPHA= 0.1195051334702275 TDDBETA = -0.03716837782340918 SORIENTA= 154.3172042452752 / position angle of image y axis (deg. e of n) SCRVAL1 = 5.670727606678185 / first axis value at reference pixel SNAXIS2 = 2048 / Axis length SNAXIS1 = 4096 / Axis length SCRVAL2 = -72.08067576427173 / second axis value at reference pixel SCTYPE1 = 'RA---TAN-SIP' / the coordinate type for the first axis SCTYPE2 = 'DEC--TAN-SIP' / the coordinate type for the second axis SCD2_2 = -1.217522934245482E-05 / partial of second axis coordinate w.r.t. y SCD2_1 = 4.801597437325027E-06 / partial of second axis coordinate w.r.t. x SCD1_2 = 5.855040197035933E-06 / partial of first axis coordinate w.r.t. y SCRPIX2 = 1024.0 / y-coordinate of reference pixel SCRPIX1 = 2048.0 / x-coordinate of reference pixel SCD1_1 = 1.281668382601152E-05 / partial of first axis coordinate w.r.t. x WCSNAMEO= 'OPUS ' WCSAXESO= 2 CRPIX1O = 2048 CRPIX2O = 1024 CDELT1O = 1 CDELT2O = 1 CUNIT1O = 'deg ' CUNIT2O = 'deg ' CTYPE1O = 'RA---TAN-SIP' CTYPE2O = 'DEC--TAN-SIP' CRVAL1O = 5.67073326894 CRVAL2O = -72.0806755207 LONPOLEO= 180 LATPOLEO= -72.0806755207 RESTFRQO= 0 RESTWAVO= 0 CD1_1O = 1.28168672365E-05 CD1_2O = 5.8558592186E-06 CD2_1O = 4.80078206009E-06 CD2_2O = -1.21751207695E-05 IDCXREF = 2048.0 IDCYREF = 1024.0 IDCTAB = 'jref$qbu1641sj_idc.fits' WCSNAME = 'IDC_qbu1641sj' HISTORY The following throughput tables were used: crotacomp$hst_ota_007_syn.fitHISTORY s, cracscomp$acs_wfc_im123_004_syn.fits, cracscomp$acs_f606w_005_syn.fitHISTORY s, cracscomp$acs_wfc_ebe_win12f_005_syn.fits, cracscomp$acs_wfc_ccd1_017HISTORY _syn.fits END XTENSION= 'IMAGE ' / Image extension BITPIX = -32 / Bits per pixel NAXIS = 0 / Number of axes PCOUNT = 0 / No 'random' parameters GCOUNT = 1 / Only one group ORIGIN = 'NOAO-IRAF FITS Image Kernel July 2003' / FITS file originator EXTNAME = 'ERR ' / Extension name EXTVER = 2 / Extension version DATE = '2007-02-08T21:39:09' / Date FITS file was generated IRAF-TLM= '21:39:08 (08/02/2007)' / Time of last modification INHERIT = T / inherit the primary header EXPNAME = 'j94f05bgq ' / exposure identifier BUNIT = 'ELECTRONS' / brightness units / World Coordinate System and Related Parameters WCSAXES = 2 / number of World Coordinate System axes CRPIX1 = 2048 / x-coordinate of reference pixel CRPIX2 = 1024 / y-coordinate of reference pixel CRVAL1 = 5.67073326933 / first axis value at reference pixel CRVAL2 = -72.0806755207 / second axis value at reference pixel CTYPE1 = 'RA---TAN-SIP' / the coordinate type for the first axis CTYPE2 = 'DEC--TAN-SIP' / the coordinate type for the second axis CD1_1 = 1.28168672384E-05 / partial of first axis coordinate w.r.t. x CD1_2 = 5.8558592402E-06 / partial of first axis coordinate w.r.t. y CD2_1 = 4.80078206009E-06 / partial of second axis coordinate w.r.t. x CD2_2 = -1.21751207837E-05 / partial of second axis coordinate w.r.t. y LTV1 = 0.0000000E+00 / offset in X to subsection start LTV2 = 0.0000000E+00 / offset in Y to subsection start LTM1_1 = 1.0 / reciprocal of sampling rate in X LTM2_2 = 1.0 / reciprocal of sampling rate in Y ORIENTAT= 154.315 / position angle of image y axis (deg. e of n) RA_APER = 5.655000000000E+00 / RA of aperture reference position DEC_APER= -7.207055555556E+01 / Declination of aperture reference position PA_APER = 154.533 / Position Angle of reference aperture center (deVAFACTOR= 1.000018683511E+00 / velocity aberration plate scale factor / IMAGE STATISTICS AND DATA QUALITY FLAGS NGOODPIX= 7842694 / number of good pixels SDQFLAGS= 31743 / serious data quality flags GOODMIN = 4.8147907E+00 / minimum value of good pixels GOODMAX = 6.5271405E+02 / maximum value of good pixels GOODMEAN= 1.3935461E+01 / mean value of good pixels CDELT1 = 1 CDELT2 = 1 CUNIT1 = 'deg ' CUNIT2 = 'deg ' LONPOLE = 180 LATPOLE = -72.0806755207 RESTFRQ = 0 RESTWAV = 0 WCSNAME = 'IDC_qbu1641sj' END XTENSION= 'IMAGE ' / Image extension BITPIX = 16 / Bits per pixel NAXIS = 0 / Number of axes PCOUNT = 0 / No 'random' parameters GCOUNT = 1 / Only one group ORIGIN = 'NOAO-IRAF FITS Image Kernel July 2003' / FITS file originator EXTNAME = 'DQ ' / Extension name EXTVER = 2 / Extension version DATE = '2007-02-08T21:39:09' / Date FITS file was generated IRAF-TLM= '21:39:09 (08/02/2007)' / Time of last modification INHERIT = T / inherit the primary header EXPNAME = 'j94f05bgq ' / exposure identifier BUNIT = 'UNITLESS ' / brightness units / World Coordinate System and Related Parameters WCSAXES = 2 / number of World Coordinate System axes CRPIX1 = 2048 / x-coordinate of reference pixel CRPIX2 = 1024 / y-coordinate of reference pixel CRVAL1 = 5.67073326933 / first axis value at reference pixel CRVAL2 = -72.0806755207 / second axis value at reference pixel CTYPE1 = 'RA---TAN-SIP' / the coordinate type for the first axis CTYPE2 = 'DEC--TAN-SIP' / the coordinate type for the second axis CD1_1 = 1.28168672384E-05 / partial of first axis coordinate w.r.t. x CD1_2 = 5.8558592402E-06 / partial of first axis coordinate w.r.t. y CD2_1 = 4.80078206009E-06 / partial of second axis coordinate w.r.t. x CD2_2 = -1.21751207837E-05 / partial of second axis coordinate w.r.t. y LTV1 = 0.0000000E+00 / offset in X to subsection start LTV2 = 0.0000000E+00 / offset in Y to subsection start LTM1_1 = 1.0 / reciprocal of sampling rate in X LTM2_2 = 1.0 / reciprocal of sampling rate in Y ORIENTAT= 154.315 / position angle of image y axis (deg. e of n) RA_APER = 5.655000000000E+00 / RA of aperture reference position DEC_APER= -7.207055555556E+01 / Declination of aperture reference position PA_APER = 154.533 / Position Angle of reference aperture center (deVAFACTOR= 1.000018683511E+00 / velocity aberration plate scale factor CDELT1 = 1 CDELT2 = 1 CUNIT1 = 'deg ' CUNIT2 = 'deg ' LONPOLE = 180 LATPOLE = -72.0806755207 RESTFRQ = 0 RESTWAV = 0 WCSNAME = 'IDC_qbu1641sj' END ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/locale.hdr0000644000175100001710000000550000000000000020553 0ustar00vstsdockerWCSAXES = 2 / Number of coordinate axes CRPIX1 = 1920.5 / Pixel coordinate of reference point CRPIX2 = 1920.5 / Pixel coordinate of reference point CDELT1 = -0.000416666666667 / [deg] Coordinate increment at reference point CDELT2 = 0.000416666666667 / [deg] Coordinate increment at reference point CUNIT1 = 'deg' / Units of coordinate increment and value CUNIT2 = 'deg' / Units of coordinate increment and value CTYPE1 = 'RA---TAN' / Right ascension, gnomonic projection CTYPE2 = 'DEC--TAN' / Declination, gnomonic projection CRVAL1 = 36.661 / [deg] Coordinate value at reference point CRVAL2 = -4.48 / [deg] Coordinate value at reference point LONPOLE = 180 / [deg] Native longitude of celestial pole LATPOLE = -4.48 / [deg] Native latitude of celestial pole RESTFRQ = 0 / [Hz] Line rest frequency RESTWAV = 0 / [Hz] Line rest wavelength EQUINOX = 2000 / [yr] Equinox of equatorial coordinates END ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2392578 astropy-5.0.2/astropy/wcs/tests/data/maps/0000755000175100001710000000000000000000000017555 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_AIR.hdr0000644000175100001710000002210000000000000021570 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---AIR' CRPIX1 = -2.347545010835E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--AIR' CRPIX2 = 8.339330824422E+00 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = -9.000000000000E+01 / Native latitude of celestial pole PV2_1 = 4.500000000000E+01 / Projection parameter 1 EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 01:43:31 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_AIR.continuum.fits". HISTORY Noise level of continuum map: 61 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_AIT.hdr0000644000175100001710000002176000000000000021605 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---AIT' CRPIX1 = -2.462317116277E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--AIT' CRPIX2 = 7.115850027049E+00 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = 0.000000000000E+00 / Native latitude of celestial pole EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 02:04:34 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_AIT.continuum.fits". HISTORY Noise level of continuum map: 61 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_ARC.hdr0000644000175100001710000002176000000000000021575 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---ARC' CRPIX1 = -2.469419019050E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--ARC' CRPIX2 = 5.082274450444E+00 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = -9.000000000000E+01 / Native latitude of celestial pole EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 01:35:43 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_ARC.continuum.fits". HISTORY Noise level of continuum map: 61 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_AZP.hdr0000644000175100001710000002222000000000000021612 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---AZP' CRPIX1 = -2.541100848779E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--AZP' CRPIX2 = -1.134948542534E+01 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = -9.000000000000E+01 / Native latitude of celestial pole PV2_1 = 2.000000000000E+00 / Projection parameter 1 PV2_2 = 3.000000000000E+01 / Projection parameter 2 EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 01:16:54 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_AZP.continuum.fits". HISTORY Noise level of continuum map: 61 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_BON.hdr0000644000175100001710000002210000000000000021573 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---BON' CRPIX1 = -2.431263982441E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--BON' CRPIX2 = -3.307412668190E+01 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = 0.000000000000E+00 / Native latitude of celestial pole PV2_1 = 4.500000000000E+01 / Projection parameter 1 EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 02:17:44 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_BON.continuum.fits". HISTORY Noise level of continuum map: 61 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_CAR.hdr0000644000175100001710000002176000000000000021575 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---CAR' CRPIX1 = -2.482173814412E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--CAR' CRPIX2 = 7.527038199745E+00 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = 0.000000000000E+00 / Native latitude of celestial pole EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 01:51:20 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_CAR.continuum.fits". HISTORY Noise level of continuum map: 61 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_CEA.hdr0000644000175100001710000002210000000000000021545 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---CEA' CRPIX1 = -2.482173814412E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--CEA' CRPIX2 = 7.688571124876E+00 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = 0.000000000000E+00 / Native latitude of celestial pole PV2_1 = 1.000000000000E+00 / Projection parameter 1 EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 01:48:41 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_CEA.continuum.fits". HISTORY Noise level of continuum map: 61 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_COD.hdr0000644000175100001710000002222000000000000021565 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---COD' CRPIX1 = -2.153431714695E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--COD' CRPIX2 = 1.561302682707E+01 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = -4.500000000000E+01 / Native latitude of celestial pole PV2_1 = 4.500000000000E+01 / Projection parameter 1 PV2_2 = 2.500000000000E+01 / Projection parameter 2 EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 02:12:30 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_COD.continuum.fits". HISTORY Noise level of continuum map: 61 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_COE.hdr0000644000175100001710000002222000000000000021566 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---COE' CRPIX1 = -2.230375366798E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--COE' CRPIX2 = -1.435249668783E+01 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = 4.500000000000E+01 / Native latitude of celestial pole PV2_1 = -4.500000000000E+01 / Projection parameter 1 PV2_2 = 2.500000000000E+01 / Projection parameter 2 EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 02:09:50 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_COE.continuum.fits". HISTORY Noise level of continuum map: 62 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_COO.hdr0000644000175100001710000002222000000000000021600 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---COO' CRPIX1 = -2.136486051767E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--COO' CRPIX2 = 1.292640949564E+01 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = -4.500000000000E+01 / Native latitude of celestial pole PV2_1 = 4.500000000000E+01 / Projection parameter 1 PV2_2 = 2.500000000000E+01 / Projection parameter 2 EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 02:15:07 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_COO.continuum.fits". HISTORY Noise level of continuum map: 62 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_COP.hdr0000644000175100001710000002222000000000000021601 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---COP' CRPIX1 = -2.151923139086E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--COP' CRPIX2 = 1.505768272737E+01 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = -4.500000000000E+01 / Native latitude of celestial pole PV2_1 = 4.500000000000E+01 / Projection parameter 1 PV2_2 = 2.500000000000E+01 / Projection parameter 2 EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 02:07:13 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_COP.continuum.fits". HISTORY Noise level of continuum map: 61 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_CSC.hdr0000644000175100001710000002176000000000000021600 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---CSC' CRPIX1 = -2.686531829635E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--CSC' CRPIX2 = -7.043520126533E+00 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = 0.000000000000E+00 / Native latitude of celestial pole EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 02:25:39 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_CSC.continuum.fits". HISTORY Noise level of continuum map: 61 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_CYP.hdr0000644000175100001710000002222000000000000021613 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---CYP' CRPIX1 = -1.471055514007E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--CYP' CRPIX2 = 2.056099939277E+01 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = 0.000000000000E+00 / Native latitude of celestial pole PV2_1 = 1.000000000000E+00 / Projection parameter 1 PV2_2 = 7.071067811870E-01 / Projection parameter 2 EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 01:46:07 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_CYP.continuum.fits". HISTORY Noise level of continuum map: 62 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_HPX.hdr0000644000175100001710000002234000000000000021622 0ustar00vstsdockerSIMPLE = T / file does conform to FITS standard BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 / number of data axes NAXIS1 = 192 / length of data axis 1 NAXIS2 = 192 / length of data axis 2 EXTEND = T / FITS dataset may contain extensions COMMENT FITS (Flexible Image Transport System) format is defined in 'AstronomyCOMMENT and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H BUNIT = 'Jy/beam ' / Pixel value is flux density CTYPE1 = 'RA---HPX' CRPIX1 = -248.217381441188 CDELT1 = -0.0666666666666667 CRVAL1 = 0. CTYPE2 = 'DEC--HPX' CRPIX2 = -8.21754831338666 CDELT2 = 0.0666666666666667 CRVAL2 = -90. LONPOLE = 180. / Native longitude of celestial pole LATPOLE = 0. / Native latitude of celestial pole RADESYS = 'FK5 ' / Equatorial coordinate system EQUINOX = 2000.0 / Equinox of equatorial coordinates BMAJ = 0.24000 / Beam major axis in degrees BMIN = 0.24000 / Beam minor axis in degrees BPA = 0.0 / Beam position angle in degrees HISTORY Single-dish continuum map HISTORY Formed on Mon 2005/03/07 04:03:52 GMT by "pksgridzilla" which was HISTORY compiled on Mar 6 2005 08:00:15 (local time) within HISTORY AIPS++ version 19.986.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_HPX.continuum.fits". HISTORY Noise level of continuum map: 57 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_MER.hdr0000644000175100001710000002176000000000000021613 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---MER' CRPIX1 = -2.482173814412E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--MER' CRPIX2 = 7.364978412864E+00 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = 0.000000000000E+00 / Native latitude of celestial pole EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 01:53:59 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_MER.continuum.fits". HISTORY Noise level of continuum map: 61 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_MOL.hdr0000644000175100001710000002176000000000000021617 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---MOL' CRPIX1 = -2.127655947497E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--MOL' CRPIX2 = -2.310670994515E+00 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = 0.000000000000E+00 / Native latitude of celestial pole EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 02:01:55 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_MOL.continuum.fits". HISTORY Noise level of continuum map: 61 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_NCP.hdr0000644000175100001710000002222000000000000021600 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---SIN' CRPIX1 = -2.371895431541E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--SIN' CRPIX2 = 7.688572009351E+00 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = -9.000000000000E+01 / Native latitude of celestial pole PV2_1 = 0.000000000000E+00 / Projection parameter 1 PV2_2 = -1.216796447506E-08 / Projection parameter 2 EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 01:33:03 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_NCP.continuum.fits". HISTORY Noise level of continuum map: 61 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_PAR.hdr0000644000175100001710000002176000000000000021612 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---PAR' CRPIX1 = -2.465551494284E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--PAR' CRPIX2 = 3.322937769653E+00 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = 0.000000000000E+00 / Native latitude of celestial pole EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 01:59:17 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_PAR.continuum.fits". HISTORY Noise level of continuum map: 61 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_PCO.hdr0000644000175100001710000002176000000000000021611 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---PCO' CRPIX1 = -2.462486098896E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--PCO' CRPIX2 = 3.620782775517E-01 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = 0.000000000000E+00 / Native latitude of celestial pole EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 02:20:22 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_PCO.continuum.fits". HISTORY Noise level of continuum map: 62 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_QSC.hdr0000644000175100001710000002176000000000000021616 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---QSC' CRPIX1 = -2.583408175994E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--QSC' CRPIX2 = -8.258194421088E+00 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = 0.000000000000E+00 / Native latitude of celestial pole EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 02:28:25 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_QSC.continuum.fits". HISTORY Noise level of continuum map: 61 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_SFL.hdr0000644000175100001710000002176000000000000021614 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---SFL' CRPIX1 = -2.463483086237E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--SFL' CRPIX2 = 7.527038199745E+00 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = 0.000000000000E+00 / Native latitude of celestial pole EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 01:56:37 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_SFL.continuum.fits". HISTORY Noise level of continuum map: 61 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_SIN.hdr0000644000175100001710000002222000000000000021611 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---SIN' CRPIX1 = -2.371895431541E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--SIN' CRPIX2 = 7.688571124876E+00 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = -9.000000000000E+01 / Native latitude of celestial pole PV2_1 = 0.000000000000E+00 / Projection parameter 1 PV2_2 = 0.000000000000E+00 / Projection parameter 2 EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 01:30:25 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_SIN.continuum.fits". HISTORY Noise level of continuum map: 61 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_STG.hdr0000644000175100001710000002176000000000000021625 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---STG' CRPIX1 = -2.519459909290E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--STG' CRPIX2 = 3.744942537739E+00 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = -9.000000000000E+01 / Native latitude of celestial pole EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 01:26:55 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_STG.continuum.fits". HISTORY Noise level of continuum map: 61 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_SZP.hdr0000644000175100001710000002234000000000000021637 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---SZP' CRPIX1 = -2.478656972779E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--SZP' CRPIX2 = -2.262051956373E+01 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = -9.000000000000E+01 / Native latitude of celestial pole PV2_1 = 2.000000000000E+00 / Projection parameter 1 PV2_2 = 1.800000000000E+02 / Projection parameter 2 PV2_3 = 6.000000000000E+01 / Projection parameter 3 EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 01:20:19 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_SZP.continuum.fits". HISTORY Noise level of continuum map: 61 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_TAN.hdr0000644000175100001710000002176000000000000021612 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---TAN' CRPIX1 = -2.680658087122E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--TAN' CRPIX2 = -5.630437201085E-01 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = -9.000000000000E+01 / Native latitude of celestial pole EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 01:23:37 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_TAN.continuum.fits". HISTORY Noise level of continuum map: 59 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_TSC.hdr0000644000175100001710000002176000000000000021621 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---TSC' CRPIX1 = -1.897220156818E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--TSC' CRPIX2 = 2.037416464676E+01 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = 0.000000000000E+00 / Native latitude of celestial pole EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 02:23:02 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_TSC.continuum.fits". HISTORY Noise level of continuum map: 61 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_ZEA.hdr0000644000175100001710000002176000000000000021607 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---ZEA' CRPIX1 = -2.444880690361E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--ZEA' CRPIX2 = 5.738055949994E+00 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = -9.000000000000E+01 / Native latitude of celestial pole EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 01:40:52 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_ZEA.continuum.fits". HISTORY Noise level of continuum map: 61 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/maps/1904-66_ZPN.hdr0000644000175100001710000002506000000000000021634 0ustar00vstsdockerSIMPLE = T BITPIX = -32 / IEEE (big-endian) 32-bit floating point data NAXIS = 2 NAXIS1 = 192 NAXIS2 = 192 BUNIT = 'JY/BEAM ' CTYPE1 = 'RA---ZPN' CRPIX1 = -1.832937255632E+02 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--ZPN' CRPIX2 = 2.209211120575E+01 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = -9.000000000000E+01 / Native latitude of celestial pole PV2_0 = 5.000000000000E-02 / Projection parameter 0 PV2_1 = 9.750000000000E-01 / Projection parameter 1 PV2_2 = -8.070000000000E-01 / Projection parameter 2 PV2_3 = 3.370000000000E-01 / Projection parameter 3 PV2_4 = -6.500000000000E-02 / Projection parameter 4 PV2_5 = 1.000000000000E-02 / Projection parameter 5 PV2_6 = 3.000000000000E-03 / Projection parameter 6 PV2_7 = -1.000000000000E-03 / Projection parameter 7 PV2_8 = 0.000000000000E+00 / Projection parameter 8 PV2_9 = 0.000000000000E+00 / Projection parameter 9 PV2_10 = 0.000000000000E+00 / Projection parameter 10 PV2_11 = 0.000000000000E+00 / Projection parameter 11 PV2_12 = 0.000000000000E+00 / Projection parameter 12 PV2_13 = 0.000000000000E+00 / Projection parameter 13 PV2_14 = 0.000000000000E+00 / Projection parameter 14 PV2_15 = 0.000000000000E+00 / Projection parameter 15 PV2_16 = 0.000000000000E+00 / Projection parameter 16 PV2_17 = 0.000000000000E+00 / Projection parameter 17 PV2_18 = 0.000000000000E+00 / Projection parameter 18 PV2_19 = 0.000000000000E+00 / Projection parameter 19 EQUINOX = 2.000000000000E+03 / Equinox of equatorial coordinates BMAJ = 2.399999936422E-01 / Beam major axis in degrees BMIN = 2.399999936422E-01 / Beam minor axis in degrees BPA = 0.000000000000E+00 / Beam position angle in degrees RESTFRQ = 1.420405750000E+09 / Line rest frequency, Hz HISTORY Parkes Multibeam continuum map HISTORY Formed on Mon 2004/02/09 01:38:20 GMT by "pksgridzilla" which was HISTORY compiled on Feb 9 2004 12:08:02 (local time) within HISTORY AIPS++ version 19.405.00 dated . HISTORY Polarization mode: A and B aggregated HISTORY Gridding parameters: HISTORY Method: WGTMED HISTORY Clip fraction: 0.000 HISTORY Tsys weighting: applied HISTORY Beam weight order: 1 HISTORY Beam FWHM: 14.4 arcmin HISTORY Beam normalization: applied HISTORY Smoothing kernel type: TOP-HAT HISTORY Kernel FWHM: 12.0 arcmin HISTORY Cutoff radius: 6.0 arcmin HISTORY Beam RSS cutoff: 0.0 HISTORY Input data sets: HISTORY 97-10-09_0356_193558-66_206a.sdfits HISTORY 97-10-12_0142_182123-66_193a.sdfits HISTORY 97-10-12_0151_182707-66_194a.sdfits HISTORY 97-10-12_0200_183252-66_195a.sdfits HISTORY 97-11-07_0510_183836-66_196a.sdfits HISTORY 97-11-07_0519_184420-66_197a.sdfits HISTORY 97-11-07_0528_185004-66_198a.sdfits HISTORY 97-11-07_0537_185548-66_199a.sdfits HISTORY 97-11-07_0546_190132-66_200a.sdfits HISTORY 97-11-07_0556_190717-66_201a.sdfits HISTORY 97-11-07_0645_191301-66_202a.sdfits HISTORY 97-11-07_0654_191845-66_203a.sdfits HISTORY 97-11-07_0703_192429-66_204a.sdfits HISTORY 97-11-07_0712_193013-66_205a.sdfits HISTORY 97-11-07_0724_194142-66_207a.sdfits HISTORY 97-11-18_0256_193815-66_206c.sdfits HISTORY 97-11-18_0306_194359-66_207c.sdfits HISTORY 97-11-19_0447_182341-66_193c.sdfits HISTORY 97-11-19_0456_182925-66_194c.sdfits HISTORY 97-11-19_0507_190350-66_200c.sdfits HISTORY 97-11-19_0516_190934-66_201c.sdfits HISTORY 97-11-19_0525_191519-66_202c.sdfits HISTORY 97-11-19_0534_192103-66_203c.sdfits HISTORY 97-11-19_0544_192647-66_204c.sdfits HISTORY 97-11-19_0553_193231-66_205c.sdfits HISTORY 97-11-19_0602_183509-66_195c.sdfits HISTORY 97-11-19_0612_184053-66_196c.sdfits HISTORY 97-11-19_0622_184638-66_197c.sdfits HISTORY 97-11-19_0631_185222-66_198c.sdfits HISTORY 97-11-19_0640_185806-66_199c.sdfits HISTORY 98-03-24_2107_193706-66_206b.sdfits HISTORY 98-03-24_2116_194251-66_207b.sdfits HISTORY 98-03-25_2020_190826-66_201b.sdfits HISTORY 98-03-25_2029_191410-66_202b.sdfits HISTORY 98-03-25_2038_191954-66_203b.sdfits HISTORY 98-03-25_2047_192538-66_204b.sdfits HISTORY 98-03-25_2056_193122-66_205b.sdfits HISTORY 98-03-26_2048_190459-66_200d.sdfits HISTORY 98-03-27_2034_191627-66_202d.sdfits HISTORY 98-03-27_2043_192212-66_203d.sdfits HISTORY 98-03-27_2052_192756-66_204d.sdfits HISTORY 98-03-27_2102_193340-66_205d.sdfits HISTORY 98-03-27_2111_193924-66_206d.sdfits HISTORY 98-03-27_2120_194508-66_207d.sdfits HISTORY 98-03-27_2130_191043-66_201d.sdfits HISTORY 98-05-10_2123_182232-66_193b.sdfits HISTORY 98-05-10_2133_182816-66_194b.sdfits HISTORY 98-05-10_2142_183400-66_195b.sdfits HISTORY 98-05-10_2151_183945-66_196b.sdfits HISTORY 98-05-10_2200_184529-66_197b.sdfits HISTORY 98-05-10_2209_185113-66_198b.sdfits HISTORY 98-05-10_2219_185657-66_199b.sdfits HISTORY 98-05-10_2228_190241-66_200b.sdfits HISTORY 98-05-13_2132_182450-66_193d.sdfits HISTORY 98-05-13_2151_183034-66_194d.sdfits HISTORY 98-05-13_2200_183618-66_195d.sdfits HISTORY 98-05-13_2210_184202-66_196d.sdfits HISTORY 98-05-13_2219_184746-66_197d.sdfits HISTORY 98-05-13_2228_185331-66_198d.sdfits HISTORY 98-05-13_2237_185915-66_199d.sdfits HISTORY 98-05-25_1711_182559-66_193e.sdfits HISTORY 98-05-25_1720_183143-66_194e.sdfits HISTORY 98-05-25_1729_183727-66_195e.sdfits HISTORY 98-05-25_1738_184311-66_196e.sdfits HISTORY 98-05-25_1747_184855-66_197e.sdfits HISTORY 98-05-25_1756_185439-66_198e.sdfits HISTORY 98-05-25_1806_190024-66_199e.sdfits HISTORY 98-05-25_1815_190608-66_200e.sdfits HISTORY 98-05-25_1824_191152-66_201e.sdfits HISTORY 98-05-25_1833_191736-66_202e.sdfits HISTORY 98-05-25_1842_192320-66_203e.sdfits HISTORY 98-05-25_1851_192905-66_204e.sdfits HISTORY 98-05-25_1901_193449-66_205e.sdfits HISTORY 98-05-25_1910_194033-66_206e.sdfits HISTORY 98-05-25_1919_194617-66_207e.sdfits HISTORY Original FITS filename "1904-66_ZPN.continuum.fits". HISTORY Noise level of continuum map: 61 mJy (RMS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/nonstandard_units.hdr0000644000175100001710000000240300000000000023050 0ustar00vstsdockerCD1_2 = -3.72E-05 CD1_3 = 0 CD1_1 = -4.12E-05 CUNIT3 = 'HZ ' CUNIT2 = 'M/S ' CTYPE1 = 'RA---TAN' NAXIS = 3 CTYPE3 = 'AWAV ' CD2_1 = -3.72E-05 CTYPE2 = 'DEC--TAN' CD2_3 = 0 CD2_2 = 4.12E-05 CUNIT1 = 'deg ' CD3_1 = 0 CD3_2 = 0 CD3_3 = 0.2 END././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/outside_sky.hdr0000644000175100001710000000267700000000000021672 0ustar00vstsdockerSIMPLE = T / BITPIX = -32 / NAXIS = 2 / NAXIS1 = 2048 / NAXIS2 = 2048 / EXTEND = T / BSCALE = 1.00000000000E+00 / BZERO = 0.00000000000E+00 / CDELT1 = -8.19629704013E-02 / CRPIX1 = 1.02500000000E+03 / CRVAL1 = 79.95701 CTYPE1 = 'RA---SIN' / CDELT2 = 8.19629704013E-02 / CRPIX2 = 1.02500000000E+03 / CRVAL2 = -45.779 CTYPE2 = 'DEC--SIN' / EPOCH = 2.00000000000E+03 / PV2_1 = -0.755124458581295 PV2_2 = 0.209028857410973 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/sip-broken.hdr0000644000175100001710000006250000000000000021370 0ustar00vstsdockerXTENSION= 'IMAGE ' / Image extension BITPIX = -32 / array data type NAXIS = 2 / number of array dimensions NAXIS1 = 10 NAXIS2 = 10 PCOUNT = 0 / number of parameters GCOUNT = 1 / number of groups ORIGIN = 'NOAO-IRAF FITS Image Kernel July 2003' / FITS file originator EXTNAME = 'SCI ' / Extension name EXTVER = 1 / Extension version IRAF-TLM= '2010-01-28T21:42:25' / Time of last modification DATE = '2010-01-15T03:23:55' / Date FITS file was generated INHERIT = T / inherit the primary header EXPNAME = 'ibc301qrq ' / exposure identifier BUNIT = 'electrons' / brightness units / CCD CHIP IDENTIFICATION CCDCHIP = 2 / CCD chip (1 or 2) / World Coordinate System and Related Parameters WCSAXES = 2 / number of World Coordinate System axes CRPIX1 = 2048.0 / x-coordinate of reference pixel CRPIX2 = 1026.0 / y-coordinate of reference pixel CRVAL1 = 201.682062444 / first axis value at reference pixel CRVAL2 = -47.46654604529999 / second axis value at reference pixel CTYPE1 = 'RA---TAN-SIP' / the coordinate type for the first axis CTYPE2 = 'DEC--TAN-SIP' / the coordinate type for the second axis CD1_1 = 9.89532021391661E-06 / partial of first axis coordinate w.r.t. x CD1_2 = 5.57454535620407E-06 / partial of first axis coordinate w.r.t. y CD2_1 = 4.96143358219569E-06 / partial of second axis coordinate w.r.t. x CD2_2 = -9.5612017076973E-06 / partial of second axis coordinate w.r.t. y LTV1 = 0.0000000E+00 / offset in X to subsection start LTV2 = 0.0000000E+00 / offset in Y to subsection start LTM1_1 = 1.0 / reciprocal of sampling rate in X LTM2_2 = 1.0 / reciprocal of sampling rate in Y PA_APER = 149.806 / Position Angle of reference aperture center (deVAFACTOR= 1.0 / velocity aberration plate scale factor ORIENTAT= 149.7956191662691 / position angle of image y axis (deg. e of n) RA_APER = 2.016928333333E+02 / RA of aperture reference position DEC_APER= -4.747905555556E+01 / Declination of aperture reference position / REPEATED EXPOSURES INFORMATION NCOMBINE= 1 / number of image sets combined during CR rejecti / PHOTOMETRY KEYWORDS PHOTMODE= 'WFC3 UVIS2 F606W CAL' / observation con PHOTFLAM= 1.1598989E-19 / inverse sensitivity, ergs/cm2/Ang/electron PHOTFNU = 1.3410633E-07 / inverse sensitivity, Jy*sec/electron PHOTZPT = -2.1100000E+01 / ST magnitude zero point PHOTPLAM= 5.8874194E+03 / Pivot wavelength (Angstroms) PHOTBW = 6.5663947E+02 / RMS bandwidth of filter plus detector / READOUT DEFINITION PARAMETERS CENTERA1= 2104 / subarray axis1 center pt in unbinned dect. pix CENTERA2= 1036 / subarray axis2 center pt in unbinned dect. pix SIZAXIS1= 4096 / subarray axis1 size in unbinned detector pixelsSIZAXIS2= 2051 / subarray axis2 size in unbinned detector pixelsBINAXIS1= 1 / axis1 data bin size in unbinned detector pixelsBINAXIS2= 1 / axis2 data bin size in unbinned detector pixels / DATA PACKET INFORMATION FILLCNT = 0 / number of segments containing fill ERRCNT = 0 / number of segments containing errors PODPSFF = F / podps fill present (T/F) STDCFFF = F / science telemetry fill data present (T=1/F=0) STDCFFP = 'x5569 ' / science telemetry fill pattern (hex) / IMAGE STATISTICS AND DATA QUALITY FLAGS NGOODPIX= 8361737 / number of good pixels SDQFLAGS= 31743 / serious data quality flags GOODMIN = -1.5353586E+10 / minimum value of good pixels GOODMAX = 4.4784176E+08 / maximum value of good pixels GOODMEAN= -1.7965331E+03 / mean value of good pixels SNRMIN = -4.0580401E+00 / minimum signal to noise of good pixels SNRMAX = 2.0669971E+02 / maximum signal to noise of good pixels SNRMEAN = 9.1055450E+00 / mean value of signal to noise of good pixels SOFTERRS= 0 / number of soft error pixels (DQF=1) MEANDARK= -9.8821044E-04 / average of the dark values subtracted MEANBLEV= 2.5543987E+03 / average of all bias levels subtracted MEANFLSH= 0.000000 / Mean number of counts in post flash exposure OCX10 = 0.000175023073097690 OCX11 = 0.03978145867586136 OCY10 = 0.03984303399920464 OCY11 = 0.002337893005460501 IDCSCALE= 0.03962 WCSNAMEO= 'OPUS ' WCSAXESO= 2 CRPIX1O = 2048.0 CRPIX2O = 1026.0 CDELT1O = 1 CDELT2O = 1 CUNIT1O = 'deg ' CUNIT2O = 'deg ' CTYPE1O = 'RA---TAN' CTYPE2O = 'DEC--TAN' CRVAL1O = 201.682062444 CRVAL2O = -47.4665460453 LONPOLEO= 180 LATPOLEO= -47.4665460453 RESTFRQO= 0 RESTWAVO= 0 CD1_1O = 9.90756999999999E-06 CD1_2O = 5.55896E-06 CD2_1O = 4.9244E-06 CD2_2O = -9.54957E-06 IDCTAB = 'iref$v5r1512gi_idc.fits' A_3_1 = -5.1021945200133E-16 A_3_0 = 2.01645819721643E-11 B_3_0 = 1.69320438397225E-12 B_3_1 = 1.63251006567400E-15 B_1_2 = -1.4255424755601E-11 B_1_3 = -2.7323406250153E-15 B_1_1 = 2.81503635244692E-06 B_2_1 = 1.84371537198681E-11 B_2_0 = -4.1200147469028E-08 B_2_2 = 1.39530876683604E-14 A_4_0 = 1.93073916740935E-15 A_ORDER = 4 B_0_4 = 7.44136342655120E-15 B_0_3 = 1.35699782198128E-11 B_0_2 = -3.0813836048843E-06 B_ORDER = 4 B_4_0 = 6.75894948156410E-16 A_1_1 = -2.9689459039407E-06 A_1_3 = -2.5561816554973E-15 A_1_2 = 1.61518535366509E-11 A_0_4 = -1.7441112473874E-14 A_0_2 = 9.41762068657988E-08 A_0_3 = 2.11281723091275E-11 A_2_2 = -1.7127070982784E-14 A_2_0 = 2.87050290904523E-06 A_2_1 = -1.4037704327792E-11 IDCTHETA= 45.0 IDCXREF = 2048.0 IDCYREF = 1026.0 IDCV2REF= -27.56800079345703 IDCV3REF= -33.30899810791016 WCSNAMEA= 'IDC_v5r1512gi' WCSAXESA= 2 CRPIX1A = 2048 CRPIX2A = 1026 CDELT1A = 1 CDELT2A = 1 CUNIT1A = 'deg ' CUNIT2A = 'deg ' CTYPE1A = 'RA---TAN-SIP' CTYPE2A = 'DEC--TAN-SIP' CRVAL1A = 201.682062444 CRVAL2A = -47.4665460453 LONPOLEA= 180 LATPOLEA= -47.4665460453 RESTFRQA= 0 RESTWAVA= 0 CD1_1A = 9.89532021392E-06 CD1_2A = 5.5745453562E-06 CD2_1A = 4.9614335822E-06 CD2_2A = -9.5612017077E-06 A_3_1O = -5.1021945200133E-16 A_3_0O = 2.01645819721643E-11 B_3_0O = 1.69320438397225E-12 B_3_1O = 1.632510065674E-15 B_1_2O = -1.4255424755601E-11 B_1_3O = -2.7323406250153E-15 B_1_1O = 2.81503635244692E-06 B_2_1O = 1.84371537198681E-11 B_2_0O = -4.1200147469028E-08 B_2_2O = 1.39530876683604E-14 B_ORDERO= 4 A_ORDERO= 4 B_0_4O = 7.4413634265512E-15 B_0_3O = 1.35699782198128E-11 B_0_2O = -3.0813836048843E-06 A_4_0O = 1.93073916740935E-15 B_4_0O = 6.7589494815641E-16 A_1_1O = -2.9689459039407E-06 A_1_3O = -2.5561816554973E-15 A_1_2O = 1.61518535366509E-11 A_0_4O = -1.7441112473874E-14 A_0_2O = 9.41762068657988E-08 A_0_3O = 2.11281723091275E-11 A_2_2O = -1.7127070982784E-14 A_2_0O = 2.87050290904523E-06 A_2_1O = -1.4037704327792E-11 WCSNAME = 'IDC_v5r1512gi' WCSNAMEB= 'IDC_v5r1512gi' WCSAXESB= 2 CRPIX1B = 2048.0 CRPIX2B = 1026.0 CDELT1B = 1 CDELT2B = 1 CUNIT1B = 'deg ' CUNIT2B = 'deg ' CTYPE1B = 'RA---TAN-SIP' CTYPE2B = 'DEC--TAN-SIP' CRVAL1B = 201.682062444 CRVAL2B = -47.4665460453 LONPOLEB= 180 LATPOLEB= -47.4665460453 RESTFRQB= 0 RESTWAVB= 0 A_3_1B = -5.1021945200133E-16 A_3_0B = 2.01645819721643E-11 B_3_0B = 1.69320438397225E-12 B_3_1B = 1.632510065674E-15 B_1_2B = -1.4255424755601E-11 B_1_3B = -2.7323406250153E-15 B_1_1B = 2.81503635244692E-06 B_2_1B = 1.84371537198681E-11 B_2_0B = -4.1200147469028E-08 B_2_2B = 1.39530876683604E-14 B_ORDERB= 4 A_ORDERB= 4 B_0_4B = 7.4413634265512E-15 B_0_3B = 1.35699782198128E-11 B_0_2B = -3.0813836048843E-06 A_4_0B = 1.93073916740935E-15 B_4_0B = 6.7589494815641E-16 A_1_1B = -2.9689459039407E-06 A_1_3B = -2.5561816554973E-15 A_1_2B = 1.61518535366509E-11 A_0_4B = -1.7441112473874E-14 A_0_2B = 9.41762068657988E-08 A_0_3B = 2.11281723091275E-11 A_2_2B = -1.7127070982784E-14 A_2_0B = 2.87050290904523E-06 A_2_1B = -1.4037704327792E-11 CD1_1B = 9.89532021392E-06 CD1_2B = 5.5745453562E-06 CD2_1B = 4.9614335822E-06 CD2_2B = -9.5612017077E-06 WCSNAMEC= 'TWEAK_A ' WCSAXESC= 2 CRPIX1C = 2048.0 CRPIX2C = 1026.0 CDELT1C = 1 CDELT2C = 1 CUNIT1C = 'deg ' CUNIT2C = 'deg ' CTYPE1C = 'RA---TAN-SIP' CTYPE2C = 'DEC--TAN-SIP' CRVAL1C = 201.682062444 CRVAL2C = -47.4665460453 LONPOLEC= 180 LATPOLEC= -47.4665460453 RESTFRQC= 0 RESTWAVC= 0 A_3_1C = -5.1021945200133E-16 A_3_0C = 2.01645819721643E-11 B_3_0C = 1.69320438397225E-12 B_3_1C = 1.632510065674E-15 B_1_2C = -1.4255424755601E-11 B_1_3C = -2.7323406250153E-15 B_1_1C = 2.81503635244692E-06 B_2_1C = 1.84371537198681E-11 B_2_0C = -4.1200147469028E-08 B_2_2C = 1.39530876683604E-14 B_ORDERC= 4 A_ORDERC= 4 B_0_4C = 7.4413634265512E-15 B_0_3C = 1.35699782198128E-11 B_0_2C = -3.0813836048843E-06 A_4_0C = 1.93073916740935E-15 B_4_0C = 6.7589494815641E-16 A_1_1C = -2.9689459039407E-06 A_1_3C = -2.5561816554973E-15 A_1_2C = 1.61518535366509E-11 A_0_4C = -1.7441112473874E-14 A_0_2C = 9.41762068657988E-08 A_0_3C = 2.11281723091275E-11 A_2_2C = -1.7127070982784E-14 A_2_0C = 2.87050290904523E-06 A_2_1C = -1.4037704327792E-11 CD1_1C = 9.89532021392E-06 CD1_2C = 5.5745453562E-06 CD2_1C = 4.9614335822E-06 CD2_2C = -9.5612017077E-06 FITNAMEC= 'TWEAK_A ' NMATCHC = 0 RMS_RAC = 0.0 RMS_DECC= 0.0 HISTORY The following throughput tables were used: crotacomp$hst_ota_007_syn.fitHISTORY s, crwfc3comp$wfc3_pom_001_syn.fits, crwfc3comp$wfc3_uvis_mir1_002_syn.fHISTORY its, crwfc3comp$wfc3_uvis_mir2_002_syn.fits, crwfc3comp$wfc3_uvis_f606w_HISTORY 002_syn.fits, crwfc3comp$wfc3_uvis_owin_002_syn.fits, crwfc3comp$wfc3_uvHISTORY is_iwin_002_syn.fits, crwfc3comp$wfc3_uvis_ccd2_003_syn.fits, crwfc3compHISTORY $wfc3_uvis_f606wf2_001_syn.fits, crwfc3comp$wfc3_uvis_cor_003_syn.fits END ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/sip.fits0000644000175100001710000001320000000000000020273 0ustar00vstsdockerSIMPLE = T / conforms to FITS standard BITPIX = 8 / array data type NAXIS = 0 / number of array dimensions WCSAXES = 2 / Number of coordinate axes CRPIX1 = 128.0 / Pixel coordinate of reference point CRPIX2 = 128.0 / Pixel coordinate of reference point PC1_1 = 0.000249756880272 / Coordinate transformation matrix element PC1_2 = 0.000230177809744 / Coordinate transformation matrix element PC2_1 = 0.000230428519265 / Coordinate transformation matrix element PC2_2 = -0.000249965770577 / Coordinate transformation matrix element CDELT1 = 1 / [deg] Coordinate increment at reference point CDELT2 = 1 / [deg] Coordinate increment at reference point CUNIT1 = 'deg' / Units of coordinate increment and value CUNIT2 = 'deg' / Units of coordinate increment and value CTYPE1 = 'RA---TAN-SIP' / Right ascension, gnomonic projection CTYPE2 = 'DEC--TAN-SIP' / Declination, gnomonic projection CRVAL1 = 202.482322805 / [deg] Coordinate value at reference point CRVAL2 = 47.17511893 / [deg] Coordinate value at reference point LONPOLE = 180 / [deg] Native longitude of celestial pole LATPOLE = 47.17511893 / [deg] Native latitude of celestial pole RESTFRQ = 0 / [Hz] Line rest frequency RESTWAV = 0 / [Hz] Line rest wavelength CRDER1 = 4.02509762361E-05 / [deg] Random error in coordinate CRDER2 = 3.42746131953E-05 / [deg] Random error in coordinate RADESYS = 'ICRS' / Equatorial coordinate system EQUINOX = 2000 / [yr] Equinox of equatorial coordinates BP_0_1 = -1.6588E-05 BP_0_2 = -2.3424E-05 A_3_0 = -1.4172E-07 B_3_0 = -2.0249E-08 BP_3_0 = 2.0482E-08 B_1_2 = -5.7813E-09 B_1_1 = -2.4386E-05 B_2_1 = -1.6583E-07 B_2_0 = 2.1197E-06 A_ORDER = 3 B_0_3 = -1.6168E-07 B_0_2 = 2.31E-05 BP_0_3 = 1.651E-07 B_ORDER = 3 BP_ORDER= 3 BP_1_2 = 3.8917E-09 AP_ORDER= 3 AP_3_0 = 1.4492E-07 A_1_1 = 2.1886E-05 BP_2_0 = -2.151E-06 A_1_2 = -1.6847E-07 AP_2_1 = 6.709E-09 AP_2_0 = 2.4146E-05 A_0_2 = 2.9656E-06 A_0_3 = 3.7746E-09 BP_1_1 = 2.4753E-05 BP_1_0 = -2.6783E-06 A_2_0 = -2.3863E-05 A_2_1 = -8.561E-09 AP_1_0 = -1.4897E-05 AP_1_1 = -2.225E-05 AP_1_2 = 1.7195E-07 BP_2_1 = 1.7E-07 AP_0_1 = -6.4275E-07 AP_0_3 = -3.582E-09 AP_0_2 = -2.9425E-06 END ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/sip2.fits0000644000175100001710000001320000000000000020355 0ustar00vstsdockerSIMPLE = T / conforms to FITS standard BITPIX = 8 / array data type NAXIS = 0 / number of array dimensions WCSAXES = 2 / Number of coordinate axes CRPIX1 = 128.0 / Pixel coordinate of reference point CRPIX2 = 128.0 / Pixel coordinate of reference point PC1_1 = 0.000249756880272 / Coordinate transformation matrix element PC1_2 = 0.000230177809744 / Coordinate transformation matrix element PC2_1 = 0.000230428519265 / Coordinate transformation matrix element PC2_2 = -0.000249965770577 / Coordinate transformation matrix element CDELT1 = 1 / [deg] Coordinate increment at reference point CDELT2 = 1 / [deg] Coordinate increment at reference point CUNIT1 = 'deg' / Units of coordinate increment and value CUNIT2 = 'deg' / Units of coordinate increment and value CTYPE1 = 'RA---TAN-SIP' / Right ascension, gnomonic projection CTYPE2 = 'DEC--TAN-SIP' / Declination, gnomonic projection CRVAL1 = 202.482322805 / [deg] Coordinate value at reference point CRVAL2 = 47.17511893 / [deg] Coordinate value at reference point LONPOLE = 180 / [deg] Native longitude of celestial pole LATPOLE = 47.17511893 / [deg] Native latitude of celestial pole RESTFRQ = 0 / [Hz] Line rest frequency RESTWAV = 0 / [Hz] Line rest wavelength CRDER1 = 4.02509762361E-05 / [deg] Random error in coordinate CRDER2 = 3.42746131953E-05 / [deg] Random error in coordinate RADESYS = 'ICRS' / Equatorial coordinate system EQUINOX = 2000 / [yr] Equinox of equatorial coordinates A_3_0 = -1.4172E-07 B_3_0 = -2.0249E-08 B_1_2 = -5.7813E-09 B_1_1 = -2.4386E-05 B_2_1 = -1.6583E-07 B_2_0 = 2.1197E-06 A_ORDER = 3 B_0_3 = -1.6168E-07 B_0_2 = 2.31E-05 B_ORDER = 3 A_1_1 = 2.1886E-05 A_1_2 = -1.6847E-07 A_0_2 = 2.9656E-06 A_0_3 = 3.7746E-09 A_2_0 = -2.3863E-05 A_2_1 = -8.561E-09 END ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/siponly.hdr0000644000175100001710000007020000000000000021010 0ustar00vstsdockerSIMPLE = T / Fits standard BITPIX = -32 / FOUR-BYTE SINGLE PRECISION FLOATING POINT NAXIS = 2 / STANDARD FITS FORMAT NAXIS1 = 2048 / STANDARD FITS FORMAT NAXIS2 = 4096 / STANDARD FITS FORMAT ORIGIN = 'Palomar Transient Factory' / Origin of these image data CREATOR = 'Infrared Processing and Analysis Center' / Creator of this FITS file TELESCOP= 'P48 ' / Name of telescope INSTRUME= 'PTF/MOSAIC' / Instrument name OBSERVER= 'KulkarniPTF' / Observer name and project CCDID = '5 ' / CCD number (0..11) DATE-OBS= '2014-07-31T04:49:58.673' / UTC shutter time YYYY-MM-DDTHH:MM:SS.SSS DATE = '2014-07-31T19:20:32' / File creation date (YYYY-MM-DDThh:mm:ss UT) REFERENC= 'http://www.astro.caltech.edu/ptf' / URL of PTF website / PROPOSAL INFORMATION PTFPRPI = 'Kulkarni' / PTF Project PI PTFPID = '52002 ' / Project type: 00000-49999 OBJECT = 'Galactic_Plane' / Fields object PTFFIELD= '1549 ' / PTF unique field ID PTFFLAG = '1 ' / 1 = PTF; 0 = non-PTF category / TIME AND EXPOSURE INFORMATION FILTER = 'R ' / Filter name FILTERID= '2 ' / Filter ID FILTERSL= '1 ' / Filter changer slot position EXPTIME = 60. / [s] Requested exposure time AEXPTIME= 60. / actual exposure time (sec) UTC-OBS = '2014-07-31T04:49:58.673' / UTC time shutter open YYYY-MM-DDTHH:MM:SS.OBSJD = 2456869.70137 / [day] Julian day corresponds to UTC-OBS OBSMJD = 56869.20137 / MJD corresponds to UTC-OBS (day) OBSLST = '17:37:29.36' / Mean LST corresponds to UTC-OBS 'HH:MM:SS.S' HOURANG = '-0:42:20.82' / Mean HA (sHH:MM:SS.S) based on LMST at UTC-OBS HJD = 2456869.70618 / [day] Heliocentric Julian Day OBSTYPE = 'object ' / Image type (dark,science,bias,focus) IMGTYP = 'object ' / Image type (dark,science,bias,focus) / MOON AND SUN MOONRA = 173.116974 / [deg] Moon J2000.0 R.A. MOONDEC = -0.404999 / [deg] Moon J2000.0 Dec. MOONILLF= 0.155837 / [frac] Moon illuminated fraction MOONPHAS= 133.4978 / [deg] Moon phase angle MOONESB = -0. / Moon excess in sky brightness V-band MOONALT = -1.271649 / [deg] Moon altitude SUNAZ = 312.4731 / [deg] Sun azimuth SUNALT = -22.25475 / [deg] Sun altitude / PHOTOMETRY BUNIT = 'DN ' / Data number (analog-to-digital units or ADU) PHTCALEX= 1 / Was phot.-cal. module executed? PHTCALFL= 0 / Flag for image is photometric (0=N, 1=Y) PCALRMSE= 0.171135 / RMSE from (zeropoint, extinction) data fit IMAGEZPT= 21.22791 / Image magnitude zeropoint IZPORIG = 'CALTRANS' / Photometric-calibration origin ZPRULE = 'COMPUTE ' / Photometric-calibration method MAGZPT = 23.55079 / Magnitude zeropoint at airmass=1 EXTINCT = 1.163014 / Extinction APSFILT = 'r ' / SDSS filter used in abs phot cal APSCOL = 'r-i ' / SDSS color used in abs phot cal APRMS = 0.06677995 / RMS in mag of final abs phot cal APBSRMS = 0.05033556 / RMS in mag of final abs phot cal for bright staAPNSTDI1= 308233 / Number of standard stars in first iteration APNSTDIF= 274569 / Number of standard stars in final iteration APCHI2 = 1861590.34570444 / Chi2 of final abs phot cal APDOF = 274569. / Dof of chi2 of final abs phot cal APMEDJD = 2456869.84882722 / Median JD used in abs phot cal APPN01 = 'ZeroPoint' / Name of parameter abs phot cal 01 APPAR01 = 23.67499643 / Value of parameter abs phot cal 01 APPARE01= 0.00324545 / Error of parameter abs phot cal 01 APPN02 = 'ColorTerm' / Name of parameter abs phot cal 02 APPAR02 = 0.44908632 / Value of parameter abs phot cal 02 APPARE02= 0.00423336 / Error of parameter abs phot cal 02 APPN03 = 'AirMassTerm' / Name of parameter abs phot cal 03 APPAR03 = -0.18342823 / Value of parameter abs phot cal 03 APPARE03= 0.00288243 / Error of parameter abs phot cal 03 APPN04 = 'AirMassColorTerm' / Name of parameter abs phot cal 04 APPAR04 = -0.14534473 / Value of parameter abs phot cal 04 APPARE04= 0.00381178 / Error of parameter abs phot cal 04 APPN05 = 'TimeTerm' / Name of parameter abs phot cal 05 APPAR05 = 0.42239539 / Value of parameter abs phot cal 05 APPARE05= 0.0019644 / Error of parameter abs phot cal 05 APPN06 = 'Time2Term' / Name of parameter abs phot cal 06 APPAR06 = 0.16770061 / Value of parameter abs phot cal 06 APPARE06= 0.01549427 / Error of parameter abs phot cal 06 APPN07 = 'XTerm ' / Name of parameter abs phot cal 07 APPAR07 = 0.02152189 / Value of parameter abs phot cal 07 APPARE07= 0.00047932 / Error of parameter abs phot cal 07 APPN08 = 'YTerm ' / Name of parameter abs phot cal 08 APPAR08 = 0.02739724 / Value of parameter abs phot cal 08 APPARE08= 0.00117248 / Error of parameter abs phot cal 08 APPN09 = 'Y2Term ' / Name of parameter abs phot cal 09 APPAR09 = 0.01522565 / Value of parameter abs phot cal 09 APPARE09= 0.0018581 / Error of parameter abs phot cal 09 APPN10 = 'Y3Term ' / Name of parameter abs phot cal 10 APPAR10 = -0.23390906 / Value of parameter abs phot cal 10 APPARE10= 0.00723349 / Error of parameter abs phot cal 10 APPN11 = 'XYTerm ' / Name of parameter abs phot cal 11 APPAR11 = -0.00677493 / Value of parameter abs phot cal 11 APPARE11= 0.00169149 / Error of parameter abs phot cal 11 / ASTROMETRY CRVAL1 = 274.806945708898 / [deg] RA of reference point CRVAL2 = -25.9746476963393 / [deg] DEC of reference point CRPIX1 = -3925.16 / [pix] Image reference point CRPIX2 = 4360.23 / [pix] Image reference point CTYPE1 = 'RA---TAN-SIP' / TAN (gnomic) projection + SIP distortions CTYPE2 = 'DEC--TAN-SIP' / TAN (gnomic) projection + SIP distortions CUNIT1 = 'deg ' / Image axis-1 celestial-coordinate units CUNIT2 = 'deg ' / Image axis-2 celestial-coordinate units CRTYPE1 = 'deg ' / Data units of CRVAL1 CRTYPE2 = 'deg ' / Data units of CRVAL2 CD1_1 = 0.000286102658601581 / Transformation matrix CD1_2 = -6.28816628331811E-07 CD2_1 = -5.77207018114522E-06 CD2_2 = -0.000281525256171892 OBJRA = '18:18:56.842' / Requested field J2000.0 Ra. OBJDEC = '-25:52:30.00' / Requested field J2000.0 Dec. OBJRAD = 274.73684 / [deg] Requested field RA (J2000.0) OBJDECD = -25.875 / [deg] Requested field Dec (J2000.0) PIXSCALE= 1.01 / [arcsec/pix] Pixel scale EQUINOX = 2000. / [yr] Equatorial coordinates definition / IMAGE QUALITY SEEING = 2.95 / [pix] Seeing FWHM PEAKDIST= 0.481336680505667 / [pix] Mean dist brightest pixel-centroid pixel ELLIP = 0.313 / Mean image ellipticity A/B ELLIPPA = 48.58 / [deg] Mean image ellipticity PA FBIAS = 785.8855 / [DN] Floating bias of the image SATURVAL= 50000. / [DN] Saturation value of the CCD array FWHMSEX = 2.45 / [arcsec] SExtractor SEEING estimate MSMAPCZP= 19.20814 / [mag/s-arcsec^2] Median sky abs. phot. cal. LMGAPCZP= 20.68008 / [mag/s-arcsec^2] Limiting mag. abs. phot. cal. MEDFWHM = 3.417924 / [arcsecond] Median FWHM MEDELONG= 1.406608 / [dimensionless] Median elongation STDELONG= 0.592749 / [dimensionless] Std. dev. of elongation MEDTHETA= -31.22347 / [deg] Atan(median sin(theta)/median cos(theta))STDTHETA= 65.37225 / [deg] Atan(stddev sin(theta)/stddev cos(theta))MEDDLMAG= 2.444709 / [mag/s-arcsec^2] Median (MU_MAX-MAG_AUTO) STDDLMAG= 0.4154117 / [mag/s-arcsec^2] Stddev of (MU_MAX-MAG_AUTO) / OBSERVATORY AND TCS OCS_TIME= '2014-07-31T04:49:58.613' / UTC Date for OCS calc time-dep params OPERMODE= 'OCS ' / Mode of operation: OCS | Manual | N/A SOFTVER = '1.1.1.1 ' / Softwere version (TCS.Camera.OCS.Sched) OCS_VER = '1 ' / OCS software version and date TCS_VER = '1 ' / TCS software version and date SCH_VER = '1 ' / OCS-Scheduler software version and date MAT_VER = '7.7.0.471' / Matlab version HDR_VER = '1 ' / Header version TRIGGER = 'N/A ' / trigger ID for TOO, e.g. VOEVENT-Nr TCSMODE = 'Star ' / TCS fundamental mode TCSSMODE= 'Active ' / TCS fundamental submode TCSFMODE= 'Pos ' / TCS focus mode TCSFSMOD= 'On-Target' / TCS focus submode TCSDMODE= 'Stop ' / TCS dome mode TCSDSMOD= 'N/A ' / TCS dome submode TCSWMODE= 'Slave ' / TCS windscreen mode TCSWSMOD= 'N/A ' / TCS windscreen submode OBSLAT = 33.3574 / [deg] Telescope geodetic latitude in WGS84 OBSLON = -116.8599 / [deg] Telescope geodetic longitude in WGS84 OBSALT = 1703.2 / [m] Telescope geodetic altitude in WGS84 DEFOCUS = 0. / [mm] Focus position - nominal focus FOCUSPOS= 1.3655 / [mm] Exposures focusPos DOMESTAT= 'open ' / Dome status at begining of exposure TRACKRA = 20.4 / [arcsec/hr] Track speed RA rel to sidereal TRACKDEC= -3.9 / [arcsec/hr] Track speed Dec rel to sidereal AZIMUTH = 169.2328 / [deg] Telescope Azimuth ALTITUDE= 29.95342 / [deg] Telescope altitude AIRMASS = 1.997293 / Telescope airmass TELRA = 274.9591 / [deg] Telescope ap equinox of date RA TELDEC = -25.8684 / [deg] Telescope ap equinox of date Dec TELHA = 349.4138 / [deg] Telescope ap equinox of date HA DOMEAZ = 169.4477 / [deg] Dome azimuth WINDSCAL= 12.8995 / [deg] Wind screen altitude WINDDIR = 1.3 / [deg] Azimuth of wind direction WINDSPED= 14.472 / Wind speed (km/hour) OUTTEMP = 22.16667 / [C] Outside temperature OUTRELHU= 0.513 / [frac] Outside relative humidity OUTDEWPT= 11.61111 / [C] Outside dew point / INSTRUMENT TELEMETRY PANID = '_p48m ' / PAN identification DHSID = '_p48m ' / DHS identification CCDSEC = '[1:2048,1:4096]' / CCD section CCDSIZE = '[1:2048,1:4096]' / CCD size DATASEC = '[1:2048,1:4096]' / Data section DETSEC = '[1:2048,1:4096]' / Detector section ROISEC = '[1:2048,1:4096]' / ROI section FPA = 'P48MOSAIC' / Focal plan array CCDNAME = 'W53C2 ' / Detector mfg serial number CHECKSUM= 'fGoXhEmXfEmXfEmX' / Image header unit checksum DATASUM = '2019013917' / Image data unit checksum DHEINF = 'SDSU, Gen-III' / Controller info DHEFIRM = '/usr/src/dsp/20090618/tim_m.lod' / DSP software CAM_VER = '20090615.1.3.100000' / Camera server date.rev.cfitsio LV_VER = '8.5 ' / LabVIEW software version PCI_VER = '2.0c ' / Astropci software version DETID = 'PTF/MOSAIC' / Detector ID AUTHOR = 'PTF/OCS/TCS/Camera' / Source for header information DATAMIN = 0. / Minimum value for array ROISTATE= 'ROI ' / ROI State (FULL | ROI) LEDBLUE = 'OFF ' / 470nm LED state (ON | OFF) LEDRED = 'OFF ' / 660nm LED state (ON | OFF) LEDNIR = 'OFF ' / 880nm LED state (ON | OFF) CCD9TEMP= 174.988 / [K] 0x0 servo temp sensor on CCD09 HSTEMP = 152.111 / [K] 0x1 heat spreader temp DHE0TEMP= 301.098 / [K] 0x2 detector head electronics temp, master DHE1TEMP= 303.178 / [K] 0x3 detector head electronics temp, slave DEWWTEMP= 287.05 / [K] 0x4 dewar wall temp HEADTEMP= 142.103 / [K] 0x5 cryo cooler cold head temp CCD5TEMP= 175.963 / [K] 0x6 temp sensor on CCD05 CCD11TEM= 177.375 / [K] 0x7 temp sensor on CCD11 CCD0TEMP= 170.213 / [K] 0x8 temp sensor on CCD00 RSTEMP = 238.936 / [K] 0x9 temp sensor on radiation shield DEWPRESS= 40. / [milli-torr] Dewar pressure DETHEAT = 1.6 / [%] Detector focal plane heater power NAMPSXY = '6 2 ' / Number of amplifiers in x y CCDSUM = '1 1 ' / [pix] Binning in x and y MODELFOC= 'N/A ' / MODELFOC EXPCKSUM= 'fGoXhEmXfEmXfEmX' / Primary header unit checksum EXPDTSUM= '2019013917' / Primary data unit checksum GAIN = 1.7 / [e-/D.N.] Gain of detector. READNOI = 3.4 / [e-] Read noise of detector. DARKCUR = 0.1 / [e-/s] Dark current of detector / SCAMP DISTORTION KEYWORDS RADECSYS= 'ICRS ' / Astrometric system FGROUPNO= 1 / SCAMP field group label ASTIRMS1= 0. / Astrom. dispersion RMS (intern., high S/N) ASTIRMS2= 0. / Astrom. dispersion RMS (intern., high S/N) ASTRRMS1= 2.362887E-05 / Astrom. dispersion RMS (ref., high S/N) ASTRRMS2= 2.36868E-05 / Astrom. dispersion RMS (ref., high S/N) ASTINST = 1 / SCAMP astrometric instrument label FLXSCALE= 0. / SCAMP relative flux scale MAGZEROP= 0. / SCAMP zero-point PHOTIRMS= 0. / mag dispersion RMS (internal, high S/N) RA_RMS = 0.1040474 / [arcsec] RMS of SCAMP fit from 2MASS matching DEC_RMS = 0.1017731 / [arcsec] RMS of SCAMP fit from 2MASS matching ASTROMN = 2636 / Number of stars in SCAMP astrometric solution SCAMPPTH= 'NotAvailable' / SCAMP catalog path SCAMPFIL= 'NotAvailable' / SCAMP catalog file / SIP DISTORTION KEYWORDS A_ORDER = 4 / Distortion order for A A_0_2 = -6.88320772436348E-08 / Projection distortion parameter A_0_3 = -3.9165520771852E-11 / Projection distortion parameter A_0_4 = -1.37347903340862E-15 / Projection distortion parameter A_1_1 = 1.47451309698268E-06 / Projection distortion parameter A_1_2 = -5.47895978084324E-11 / Projection distortion parameter A_1_3 = 4.32571760220798E-15 / Projection distortion parameter A_2_0 = -4.61014380203131E-06 / Projection distortion parameter A_2_1 = -3.25701227339755E-10 / Projection distortion parameter A_2_2 = 5.87253012315133E-15 / Projection distortion parameter A_3_0 = 5.10801798928538E-10 / Projection distortion parameter A_3_1 = 2.40245891539354E-14 / Projection distortion parameter A_4_0 = -2.24100384816689E-14 / Projection distortion parameter A_DMAX = 96.5018681533569 / Projection distortion parameter B_ORDER = 4 / Distortion order for B B_0_2 = 2.10619568626298E-07 / Projection distortion parameter B_0_3 = -5.06225421390773E-12 / Projection distortion parameter B_0_4 = 5.17539616845577E-16 / Projection distortion parameter B_1_1 = 5.91465601878924E-08 / Projection distortion parameter B_1_2 = -5.12374109506712E-11 / Projection distortion parameter B_1_3 = -1.85594858389364E-15 / Projection distortion parameter B_2_0 = -6.29264904991201E-06 / Projection distortion parameter B_2_1 = -6.77151075883653E-11 / Projection distortion parameter B_2_2 = 3.33079437463431E-15 / Projection distortion parameter B_3_0 = 8.62409953895856E-10 / Projection distortion parameter B_3_1 = 4.00773353822356E-15 / Projection distortion parameter B_4_0 = -4.38536973214709E-14 / Projection distortion parameter B_DMAX = 95.5403565807527 / Projection distortion parameter AP_ORDER= 4 / Distortion order for AP AP_0_1 = -8.35636338195056E-06 / Projection distortion parameter AP_0_2 = 6.41919370738511E-08 / Projection distortion parameter AP_0_3 = 3.82575929801279E-11 / Projection distortion parameter AP_0_4 = 1.34695941598154E-15 / Projection distortion parameter AP_1_0 = 5.96496231342059E-06 / Projection distortion parameter AP_1_1 = -1.47551597085589E-06 / Projection distortion parameter AP_1_2 = 5.9682183111397E-11 / Projection distortion parameter AP_1_3 = -4.07431356348696E-15 / Projection distortion parameter AP_2_0 = 4.63912798241099E-06 / Projection distortion parameter AP_2_1 = 3.2299095062767E-10 / Projection distortion parameter AP_2_2 = -6.30497770263709E-15 / Projection distortion parameter AP_3_0 = -5.03018200403734E-10 / Projection distortion parameter AP_3_1 = -2.35315281608906E-14 / Projection distortion parameter AP_4_0 = 2.13944449467657E-14 / Projection distortion parameter BP_ORDER= 4 / Distortion order for BP BP_0_1 = -5.35341799909328E-06 / Projection distortion parameter BP_0_2 = -2.17548011382368E-07 / Projection distortion parameter BP_0_3 = 3.46141884836402E-12 / Projection distortion parameter BP_0_4 = -5.50225060304376E-16 / Projection distortion parameter BP_1_0 = 2.24406272193445E-05 / Projection distortion parameter BP_1_1 = -5.78663264876419E-08 / Projection distortion parameter BP_1_2 = 5.4445150144274E-11 / Projection distortion parameter BP_1_3 = 2.29942375548271E-15 / Projection distortion parameter BP_2_0 = 6.33813482510013E-06 / Projection distortion parameter BP_2_1 = 5.99623548359284E-11 / Projection distortion parameter BP_2_2 = -3.3053766170687E-15 / Projection distortion parameter BP_3_0 = -8.55094688760831E-10 / Projection distortion parameter BP_3_1 = -2.73327308556661E-15 / Projection distortion parameter BP_4_0 = 4.26704732113368E-14 / Projection distortion parameter / DATA FLOW ORIGNAME= '/data/PTF_default_37806.fits' / Filename as written by the camera FILENAME= 'PTF201407312014_2_o_37806.fits' / Filename of delivered camera image PROCORIG= 'IPAC-PTF pipelines' / Processing origin PROCDATE= 'Fri Sep 26 14:52:55 2014' / Processing date/time (Pacific time) PTFVERSN= 5. / Version of PTFSCIENCEPIPELINE program PMASKPTH= '/ptf/pos/archive/fallbackcal/pmasks/' / Pathname of pixel mask PMASKFIL= '70sOn35s_pixmask_chip5.trimmed.v4.fits' / Filename of pixel mask SFLATPTH= '/ptf/pos/sbx2/2014/07/31/f2/c5/cal/p4/cId112103/' / Pathname of superSFLATFIL= 'PTF_201407310000_i_s_flat_t120000_u000112103_f02_p000000_c05.fits' SBIASPTH= '/ptf/pos/sbx2/2014/07/31/f2/c5/cal/p1/cId112095/' / Pathname of superSBIASFIL= 'PTF_201407310000_i_s_bias_t120000_u000112095_f00_p000000_c05.fits' DBNID = 1938 / Database night ID DBEXPID = 446050 / Database exposure ID DBRID = 6985566 / Database raw-image ID DBPID = 21528832 / Database processed-image ID DBFID = 2 / Database filter ID DBPIID = 1 / Database P.I. ID DBPRID = 31 / Database project ID DBFIELD = 446050 / Database field ID DBSVID = 54 / Database software-version ID DBCVID = 60 / Database config-data-file ID INFOBITS= 0 / Database infobits (2^2 and 2^3 excluded) END ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2392578 astropy-5.0.2/astropy/wcs/tests/data/spectra/0000755000175100001710000000000000000000000020256 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/spectra/orion-freq-1.hdr0000644000175100001710000007330000000000000023177 0ustar00vstsdockerSIMPLE = T / file does conform to FITS standard BITPIX = -32 / number of bits per data pixel NAXIS = 1 / number of data axes NAXIS1 = 4096 / length of data axis 1 EXTEND = T / FITS dataset may contain extensions COMMENT FITS (Flexible Image Transport System) format is defined in 'AstronomyCOMMENT and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H COMMENT COMMENT This FITS file contains an example spectral WCS header constructed by COMMENT Mark Calabretta (ATNF) and Dirk Petry (ESO) based on an observation COMMENT of the Orion Kleinmann-Low nebula made by Andrew Walsh (JCU) and COMMENT Sven Thorwirth (MPIfR) using the Mopra radio telescope. COMMENT COMMENT The 110GHz 13CO 1-0 spectrum in this file is linear in frequency, as COMMENT observed, it being the Fourier transform of a lag spectrum produced COMMENT by a correlating spectrometer. COMMENT COMMENT The reference pixel has been placed deliberately well outside the COMMENT the spectrum in order to test spectral-WCS-interpreting software. COMMENT COMMENT Spectral representations are: COMMENT Frequency (default) ...frequency-like COMMENT E: Photon energy ...frequency-like COMMENT N: Wave number ...frequency-like COMMENT R: Radio velocity ...frequency-like COMMENT W: Wavelength ...wavelength-like COMMENT O: Optical velocity ...wavelength-like COMMENT Z: Redshift ...wavelength-like COMMENT V: Relativistic velocity ...velocity-like COMMENT B: Relativistic beta ...velocity-like COMMENT COMMENT The Mopra radio telescope is operated by the Australia Telescope COMMENT National Facility. COMMENT COMMENT Author: Mark Calabretta, Australia Telescope National Facility COMMENT http://www.atnf.csiro.au/~mcalabre/index.html COMMENT 2009-04-22 COMMENT ---------------------------------------------------------------------- COMMENT OBJECT = 'Orion-KL' / Orion Kleinmann-Low nebula MOLECULE= '13CO ' / Carbon(13) monoxide TRANSITI= '1-0 ' / 1-0 transition DATE-OBS= '2006-07-09T20:29:00' / Date of observation TELESCOP= 'ATNF Mopra' / 22m mm-wave telescope OBSERVER= 'Walsh/Thorwirth' / Observers BUNIT = 'K ' / Brightness units, Kelvin COMMENT COMMENT ------------------------------------------------------------ Frequency COMMENT CRPIX1 = 32768.0 / Pixel coordinate of reference point CTYPE1 = 'FREQ ' / Linear frequency axis (FFT of lag spectrum) CRVAL1 = 102.1189414E+9 / [Hz] Frequency of reference channel CDELT1 = -2.695372970E+5 / [Hz] Channel spacing (lower sideband) CUNIT1 = 'Hz ' / Units of coordinate increment and value COMMENT RESTFRQ = 110201353000.0 / [Hz] 13CO line rest frequency RESTWAV = 0.00272040633 / [m] 13CO line rest wavelength SPECSYS = 'LSRK ' / Reference frame of spectral coordinates SSYSOBS = 'TOPOCENT' / Reference frame of observation VELOSYS = 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRC = 'LSRK ' / Reference frame of source redshift ZSOURCE = 0.0000 / Redshift of the source COMMENT CRPIX2 = 1 CDELT2 = 1.0 CTYPE2 = 'RA ' CRVAL2 = 83.81042 / [deg] (05h35m14.5s) CUNIT2 = 'deg ' COMMENT CRPIX3 = 1 CDELT3 = 1.0 CTYPE3 = 'DEC ' CRVAL3 = -5.375222 / [deg] (-05:22:30.8) CUNIT3 = 'deg ' COMMENT RADESYS = 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOX = 2000.0 / Equinox J2000.0 COMMENT CRPIX4 = 1 CDELT4 = 1.0 CTYPE4 = 'STOKES ' CRVAL4 = 1 / Stokes I (total intensity) COMMENT COMMENT -------------------------------------------------------- Photon energy COMMENT CRPIX1E = 32768.0 / Pixel coordinate of reference point CTYPE1E = 'ENER ' / Photon energy, linear frequency axis CRVAL1E = 4.223303869E-4 / [eV] Photon energy of reference channel CDELT1E = -1.114717695E-9 / [eV] Channel spacing CUNIT1E = 'eV ' / Units of coordinate increment and value COMMENT RESTFRQE= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVE= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSE= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSE= 'TOPOCENT' / Reference frame of observation VELOSYSE= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCE= 'LSRK ' / Reference frame of source redshift ZSOURCEE= 0.0000 / Redshift of the source COMMENT CRPIX2E = 1 CDELT2E = 1.0 CTYPE2E = 'RA ' CRVAL2E = 83.81042 / [deg] (05h35m14.5s) CUNIT2E = 'deg ' COMMENT CRPIX3E = 1 CDELT3E = 1.0 CTYPE3E = 'DEC ' CRVAL3E = -5.375222 / [deg] (-05:22:30.8) CUNIT3E = 'deg ' COMMENT RADESYSE= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXE= 2000.0 / Equinox J2000.0 COMMENT CRPIX4E = 1 CDELT4E = 1.0 CTYPE4E = 'STOKES ' CRVAL4E = 1 / Stokes I (total intensity) COMMENT COMMENT ---------------------------------------------------------- Wave number COMMENT N: Wave number COMMENT CRPIX1N = 32768.0 / Pixel coordinate of reference point CTYPE1N = 'WAVN ' / Wave number, linear frequency axis CRVAL1N = 3.406321229E+2 / [/m] Wave number of reference channel CDELT1N = -8.990796460E-4 / [/m] Channel spacing CUNIT1N = '/m ' / Units of coordinate increment and value COMMENT RESTFRQN= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVN= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSN= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSN= 'TOPOCENT' / Reference frame of observation VELOSYSN= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCN= 'LSRK ' / Reference frame of source redshift ZSOURCEN= 0.0000 / Redshift of the source COMMENT CRPIX2N = 1 CDELT2N = 1.0 CTYPE2N = 'RA ' CRVAL2N = 83.81042 / [deg] (05h35m14.5s) CUNIT2N = 'deg ' COMMENT CRPIX3N = 1 CDELT3N = 1.0 CTYPE3N = 'DEC ' CRVAL3N = -5.375222 / [deg] (-05:22:30.8) CUNIT3N = 'deg ' COMMENT RADESYSN= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXN= 2000.0 / Equinox J2000.0 COMMENT CRPIX4N = 1 CDELT4N = 1.0 CTYPE4N = 'STOKES ' CRVAL4N = 1 / Stokes I (total intensity) COMMENT COMMENT ------------------------------------------------------- Radio velocity COMMENT N: Wave number COMMENT R: Radio velocity COMMENT CRPIX1R = 32768.0 / Pixel coordinate of reference point CTYPE1R = 'VRAD ' / Radio velocity, linear frequency axis CRVAL1R = 2.198744369E+7 / [m/s] Radio velocity of reference channel CDELT1R = 7.332509683E+2 / [m/s] Channel spacing CUNIT1R = 'm/s ' / Units of coordinate increment and value COMMENT RESTFRQR= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVR= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSR= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSR= 'TOPOCENT' / Reference frame of observation VELOSYSR= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCR= 'LSRK ' / Reference frame of source redshift ZSOURCER= 0.0000 / Redshift of the source COMMENT CRPIX2R = 1 CDELT2R = 1.0 CTYPE2R = 'RA ' CRVAL2R = 83.81042 / [deg] (05h35m14.5s) CUNIT2R = 'deg ' COMMENT CRPIX3R = 1 CDELT3R = 1.0 CTYPE3R = 'DEC ' CRVAL3R = -5.375222 / [deg] (-05:22:30.8) CUNIT3R = 'deg ' COMMENT RADESYSR= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXR= 2000.0 / Equinox J2000.0 COMMENT CRPIX4R = 1 CDELT4R = 1.0 CTYPE4R = 'STOKES ' CRVAL4R = 1 / Stokes I (total intensity) COMMENT COMMENT ----------------------------------------------------------- Wavelength COMMENT N: Wave number COMMENT R: Radio velocity COMMENT W: Wavelength COMMENT CRPIX1W = 32768.0 / Pixel coordinate of reference point CTYPE1W = 'WAVE-F2W' / Wavelength in vacuuo, non-linear axis CRVAL1W = 2.935718427E-3 / [m] Wavelength of reference channel CDELT1W = 7.748666397E-9 / [m] Channel spacing CUNIT1W = 'm ' / Units of coordinate increment and value COMMENT SPECSYSW= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSW= 'TOPOCENT' / Reference frame of observation VELOSYSW= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCW= 'LSRK ' / Reference frame of source redshift ZSOURCEW= 0.0000 / Redshift of the source COMMENT CRPIX2W = 1 CDELT2W = 1.0 CTYPE2W = 'RA ' CRVAL2W = 83.81042 / [deg] (05h35m14.5s) CUNIT2W = 'deg ' COMMENT CRPIX3W = 1 CDELT3W = 1.0 CTYPE3W = 'DEC ' CRVAL3W = -5.375222 / [deg] (-05:22:30.8) CUNIT3W = 'deg ' COMMENT RADESYSW= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXW= 2000.0 / Equinox J2000.0 COMMENT CRPIX4W = 1 CDELT4W = 1.0 CTYPE4W = 'STOKES ' CRVAL4W = 1 / Stokes I (total intensity) COMMENT COMMENT ----------------------------------------------------- Optical velocity COMMENT CRPIX1O = 32768.0 / Pixel coordinate of reference point CTYPE1O = 'VOPT-F2W' / Optical velocity, non-linear axis CRVAL1O = 2.372768470E+7 / [m/s] Optical velocity of reference channel CDELT1O = 8.539135209E+2 / [m/s] Channel spacing CUNIT1O = 'm/s ' / Units of coordinate increment and value COMMENT RESTFRQO= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVO= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSO= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSO= 'TOPOCENT' / Reference frame of observation VELOSYSO= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCO= 'LSRK ' / Reference frame of source redshift ZSOURCEO= 0.0000 / Redshift of the source COMMENT CRPIX2O = 1 CDELT2O = 1.0 CTYPE2O = 'RA ' CRVAL2O = 83.81042 / [deg] (05h35m14.5s) CUNIT2O = 'deg ' COMMENT CRPIX3O = 1 CDELT3O = 1.0 CTYPE3O = 'DEC ' CRVAL3O = -5.375222 / [deg] (-05:22:30.8) CUNIT3O = 'deg ' COMMENT RADESYSO= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXO= 2000.0 / Equinox J2000.0 COMMENT CRPIX4O = 1 CDELT4O = 1.0 CTYPE4O = 'STOKES ' CRVAL4O = 1 / Stokes I (total intensity) COMMENT COMMENT ------------------------------------------------------------- Redshift COMMENT N: Wave number COMMENT R: Radio velocity COMMENT W: Wavelength COMMENT O: Optical velocity COMMENT Z: Redshift COMMENT CRPIX1Z = 32768.0 / Pixel coordinate of reference point CTYPE1Z = 'ZOPT-F2W' / Redshift, non-linear axis CRVAL1Z = 7.914703679E-2 / [] Redshift of reference channel CDELT1Z = 2.848348910E-6 / [] Channel spacing COMMENT RESTFRQZ= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVZ= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSZ= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSZ= 'TOPOCENT' / Reference frame of observation VELOSYSZ= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCZ= 'LSRK ' / Reference frame of source redshift ZSOURCEZ= 0.0000 / Redshift of the source COMMENT CRPIX2Z = 1 CDELT2Z = 1.0 CTYPE2Z = 'RA ' CRVAL2Z = 83.81042 / [deg] (05h35m14.5s) CUNIT2Z = 'deg ' COMMENT CRPIX3Z = 1 CDELT3Z = 1.0 CTYPE3Z = 'DEC ' CRVAL3Z = -5.375222 / [deg] (-05:22:30.8) CUNIT3Z = 'deg ' COMMENT RADESYSZ= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXZ= 2000.0 / Equinox J2000.0 COMMENT CRPIX4Z = 1 CDELT4Z = 1.0 CTYPE4Z = 'STOKES ' CRVAL4Z = 1 / Stokes I (total intensity) COMMENT COMMENT ------------------------------------------------ Relativistic velocity COMMENT CRPIX1V = 32768.0 / Pixel coordinate of reference point CTYPE1V = 'VELO-F2V' / Relativistic velocity, non-linear axis CRVAL1V = 2.279141418E+7 / [m/s] Velocity of reference channel CDELT1V = 7.867122599E+2 / [m/s] Channel spacing CUNIT1V = 'm/s ' / Units of coordinate increment and value COMMENT RESTFRQV= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVV= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSV= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSV= 'TOPOCENT' / Reference frame of observation VELOSYSV= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCV= 'LSRK ' / Reference frame of source redshift ZSOURCEV= 0.0000 / Redshift of the source COMMENT CRPIX2V = 1 CDELT2V = 1.0 CTYPE2V = 'RA ' CRVAL2V = 83.81042 / [deg] (05h35m14.5s) CUNIT2V = 'deg ' COMMENT CRPIX3V = 1 CDELT3V = 1.0 CTYPE3V = 'DEC ' CRVAL3V = -5.375222 / [deg] (-05:22:30.8) CUNIT3V = 'deg ' COMMENT RADESYSV= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXV= 2000.0 / Equinox J2000.0 COMMENT CRPIX4V = 1 CDELT4V = 1.0 CTYPE4V = 'STOKES ' CRVAL4V = 1 / Stokes I (total intensity) COMMENT COMMENT ---------------------------------------------- Relativistic beta (v/c) COMMENT CRPIX1B = 32768.0 / Pixel coordinate of reference point CTYPE1B = 'BETA-F2V' / Relativistic beta (v/c), non-linear axis CRVAL1B = 7.602397448E-2 / [] Relativistic beta of reference channel CDELT1B = 2.624189632E-6 / [] Channel spacing COMMENT RESTFRQB= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVB= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSB= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSB= 'TOPOCENT' / Reference frame of observation VELOSYSB= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCB= 'LSRK ' / Reference frame of source redshift ZSOURCEB= 0.0000 / Redshift of the source COMMENT CRPIX2B = 1 CDELT2B = 1.0 CTYPE2B = 'RA ' CRVAL2B = 83.81042 / [deg] (05h35m14.5s) CUNIT2B = 'deg ' COMMENT CRPIX3B = 1 CDELT3B = 1.0 CTYPE3B = 'DEC ' CRVAL3B = -5.375222 / [deg] (-05:22:30.8) CUNIT3B = 'deg ' COMMENT RADESYSB= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXB= 2000.0 / Equinox J2000.0 COMMENT CRPIX4B = 1 CDELT4B = 1.0 CTYPE4B = 'STOKES ' CRVAL4B = 1 / Stokes I (total intensity) COMMENT HISTORY fimgcreate 1.0b at 2009-04-22T04:27:55 DATE = '2009-04-22T04:27:55' / file creation date (YYYY-MM-DDThh:mm:ss UT) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/spectra/orion-freq-4.hdr0000644000175100001710000007366000000000000023213 0ustar00vstsdockerSIMPLE = T / file does conform to FITS standard BITPIX = -32 / number of bits per data pixel NAXIS = 4 / number of data axes NAXIS1 = 4096 / length of data axis 1 NAXIS2 = 1 / length of data axis 2 NAXIS3 = 1 / length of data axis 3 NAXIS4 = 1 / length of data axis 4 EXTEND = T / FITS dataset may contain extensions COMMENT FITS (Flexible Image Transport System) format is defined in 'AstronomyCOMMENT and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H COMMENT COMMENT This FITS file contains an example spectral WCS header constructed by COMMENT Mark Calabretta (ATNF) and Dirk Petry (ESO) based on an observation COMMENT of the Orion Kleinmann-Low nebula made by Andrew Walsh (JCU) and COMMENT Sven Thorwirth (MPIfR) using the Mopra radio telescope. COMMENT COMMENT The 110GHz 13CO 1-0 spectrum in this file is linear in frequency, as COMMENT observed, it being the Fourier transform of a lag spectrum produced COMMENT by a correlating spectrometer. COMMENT COMMENT The reference pixel has been placed deliberately well outside the COMMENT the spectrum in order to test spectral-WCS-interpreting software. COMMENT COMMENT Spectral representations are: COMMENT Frequency (default) ...frequency-like COMMENT E: Photon energy ...frequency-like COMMENT N: Wave number ...frequency-like COMMENT R: Radio velocity ...frequency-like COMMENT W: Wavelength ...wavelength-like COMMENT O: Optical velocity ...wavelength-like COMMENT Z: Redshift ...wavelength-like COMMENT V: Relativistic velocity ...velocity-like COMMENT B: Relativistic beta ...velocity-like COMMENT COMMENT The Mopra radio telescope is operated by the Australia Telescope COMMENT National Facility. COMMENT COMMENT Author: Mark Calabretta, Australia Telescope National Facility COMMENT http://www.atnf.csiro.au/~mcalabre/index.html COMMENT 2009-04-22 COMMENT ---------------------------------------------------------------------- COMMENT OBJECT = 'Orion-KL' / Orion Kleinmann-Low nebula MOLECULE= '13CO ' / Carbon(13) monoxide TRANSITI= '1-0 ' / 1-0 transition DATE-OBS= '2006-07-09T20:29:00' / Date of observation TELESCOP= 'ATNF Mopra' / 22m mm-wave telescope OBSERVER= 'Walsh/Thorwirth' / Observers BUNIT = 'K ' / Brightness units, Kelvin COMMENT COMMENT ------------------------------------------------------------ Frequency COMMENT CRPIX1 = 32768.0 / Pixel coordinate of reference point CTYPE1 = 'FREQ ' / Linear frequency axis (FFT of lag spectrum) CRVAL1 = 102.1189414E+9 / [Hz] Frequency of reference channel CDELT1 = -2.695372970E+5 / [Hz] Channel spacing (lower sideband) CUNIT1 = 'Hz ' / Units of coordinate increment and value COMMENT RESTFRQ = 110201353000.0 / [Hz] 13CO line rest frequency RESTWAV = 0.00272040633 / [m] 13CO line rest wavelength SPECSYS = 'LSRK ' / Reference frame of spectral coordinates SSYSOBS = 'TOPOCENT' / Reference frame of observation VELOSYS = 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRC = 'LSRK ' / Reference frame of source redshift ZSOURCE = 0.0000 / Redshift of the source COMMENT CRPIX2 = 1 CDELT2 = 1.0 CTYPE2 = 'RA ' CRVAL2 = 83.81042 / [deg] (05h35m14.5s) CUNIT2 = 'deg ' COMMENT CRPIX3 = 1 CDELT3 = 1.0 CTYPE3 = 'DEC ' CRVAL3 = -5.375222 / [deg] (-05:22:30.8) CUNIT3 = 'deg ' COMMENT RADESYS = 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOX = 2000.0 / Equinox J2000.0 COMMENT CRPIX4 = 1 CDELT4 = 1.0 CTYPE4 = 'STOKES ' CRVAL4 = 1 / Stokes I (total intensity) COMMENT COMMENT -------------------------------------------------------- Photon energy COMMENT CRPIX1E = 32768.0 / Pixel coordinate of reference point CTYPE1E = 'ENER ' / Photon energy, linear frequency axis CRVAL1E = 4.223303869E-4 / [eV] Photon energy of reference channel CDELT1E = -1.114717695E-9 / [eV] Channel spacing CUNIT1E = 'eV ' / Units of coordinate increment and value COMMENT RESTFRQE= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVE= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSE= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSE= 'TOPOCENT' / Reference frame of observation VELOSYSE= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCE= 'LSRK ' / Reference frame of source redshift ZSOURCEE= 0.0000 / Redshift of the source COMMENT CRPIX2E = 1 CDELT2E = 1.0 CTYPE2E = 'RA ' CRVAL2E = 83.81042 / [deg] (05h35m14.5s) CUNIT2E = 'deg ' COMMENT CRPIX3E = 1 CDELT3E = 1.0 CTYPE3E = 'DEC ' CRVAL3E = -5.375222 / [deg] (-05:22:30.8) CUNIT3E = 'deg ' COMMENT RADESYSE= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXE= 2000.0 / Equinox J2000.0 COMMENT CRPIX4E = 1 CDELT4E = 1.0 CTYPE4E = 'STOKES ' CRVAL4E = 1 / Stokes I (total intensity) COMMENT COMMENT ---------------------------------------------------------- Wave number COMMENT N: Wave number COMMENT CRPIX1N = 32768.0 / Pixel coordinate of reference point CTYPE1N = 'WAVN ' / Wave number, linear frequency axis CRVAL1N = 3.406321229E+2 / [/m] Wave number of reference channel CDELT1N = -8.990796460E-4 / [/m] Channel spacing CUNIT1N = '/m ' / Units of coordinate increment and value COMMENT RESTFRQN= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVN= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSN= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSN= 'TOPOCENT' / Reference frame of observation VELOSYSN= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCN= 'LSRK ' / Reference frame of source redshift ZSOURCEN= 0.0000 / Redshift of the source COMMENT CRPIX2N = 1 CDELT2N = 1.0 CTYPE2N = 'RA ' CRVAL2N = 83.81042 / [deg] (05h35m14.5s) CUNIT2N = 'deg ' COMMENT CRPIX3N = 1 CDELT3N = 1.0 CTYPE3N = 'DEC ' CRVAL3N = -5.375222 / [deg] (-05:22:30.8) CUNIT3N = 'deg ' COMMENT RADESYSN= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXN= 2000.0 / Equinox J2000.0 COMMENT CRPIX4N = 1 CDELT4N = 1.0 CTYPE4N = 'STOKES ' CRVAL4N = 1 / Stokes I (total intensity) COMMENT COMMENT ------------------------------------------------------- Radio velocity COMMENT N: Wave number COMMENT R: Radio velocity COMMENT CRPIX1R = 32768.0 / Pixel coordinate of reference point CTYPE1R = 'VRAD ' / Radio velocity, linear frequency axis CRVAL1R = 2.198744369E+7 / [m/s] Radio velocity of reference channel CDELT1R = 7.332509683E+2 / [m/s] Channel spacing CUNIT1R = 'm/s ' / Units of coordinate increment and value COMMENT RESTFRQR= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVR= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSR= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSR= 'TOPOCENT' / Reference frame of observation VELOSYSR= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCR= 'LSRK ' / Reference frame of source redshift ZSOURCER= 0.0000 / Redshift of the source COMMENT CRPIX2R = 1 CDELT2R = 1.0 CTYPE2R = 'RA ' CRVAL2R = 83.81042 / [deg] (05h35m14.5s) CUNIT2R = 'deg ' COMMENT CRPIX3R = 1 CDELT3R = 1.0 CTYPE3R = 'DEC ' CRVAL3R = -5.375222 / [deg] (-05:22:30.8) CUNIT3R = 'deg ' COMMENT RADESYSR= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXR= 2000.0 / Equinox J2000.0 COMMENT CRPIX4R = 1 CDELT4R = 1.0 CTYPE4R = 'STOKES ' CRVAL4R = 1 / Stokes I (total intensity) COMMENT COMMENT ----------------------------------------------------------- Wavelength COMMENT N: Wave number COMMENT R: Radio velocity COMMENT W: Wavelength COMMENT CRPIX1W = 32768.0 / Pixel coordinate of reference point CTYPE1W = 'WAVE-F2W' / Wavelength in vacuuo, non-linear axis CRVAL1W = 2.935718427E-3 / [m] Wavelength of reference channel CDELT1W = 7.748666397E-9 / [m] Channel spacing CUNIT1W = 'm ' / Units of coordinate increment and value COMMENT SPECSYSW= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSW= 'TOPOCENT' / Reference frame of observation VELOSYSW= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCW= 'LSRK ' / Reference frame of source redshift ZSOURCEW= 0.0000 / Redshift of the source COMMENT CRPIX2W = 1 CDELT2W = 1.0 CTYPE2W = 'RA ' CRVAL2W = 83.81042 / [deg] (05h35m14.5s) CUNIT2W = 'deg ' COMMENT CRPIX3W = 1 CDELT3W = 1.0 CTYPE3W = 'DEC ' CRVAL3W = -5.375222 / [deg] (-05:22:30.8) CUNIT3W = 'deg ' COMMENT RADESYSW= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXW= 2000.0 / Equinox J2000.0 COMMENT CRPIX4W = 1 CDELT4W = 1.0 CTYPE4W = 'STOKES ' CRVAL4W = 1 / Stokes I (total intensity) COMMENT COMMENT ----------------------------------------------------- Optical velocity COMMENT CRPIX1O = 32768.0 / Pixel coordinate of reference point CTYPE1O = 'VOPT-F2W' / Optical velocity, non-linear axis CRVAL1O = 2.372768470E+7 / [m/s] Optical velocity of reference channel CDELT1O = 8.539135209E+2 / [m/s] Channel spacing CUNIT1O = 'm/s ' / Units of coordinate increment and value COMMENT RESTFRQO= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVO= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSO= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSO= 'TOPOCENT' / Reference frame of observation VELOSYSO= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCO= 'LSRK ' / Reference frame of source redshift ZSOURCEO= 0.0000 / Redshift of the source COMMENT CRPIX2O = 1 CDELT2O = 1.0 CTYPE2O = 'RA ' CRVAL2O = 83.81042 / [deg] (05h35m14.5s) CUNIT2O = 'deg ' COMMENT CRPIX3O = 1 CDELT3O = 1.0 CTYPE3O = 'DEC ' CRVAL3O = -5.375222 / [deg] (-05:22:30.8) CUNIT3O = 'deg ' COMMENT RADESYSO= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXO= 2000.0 / Equinox J2000.0 COMMENT CRPIX4O = 1 CDELT4O = 1.0 CTYPE4O = 'STOKES ' CRVAL4O = 1 / Stokes I (total intensity) COMMENT COMMENT ------------------------------------------------------------- Redshift COMMENT N: Wave number COMMENT R: Radio velocity COMMENT W: Wavelength COMMENT O: Optical velocity COMMENT Z: Redshift COMMENT CRPIX1Z = 32768.0 / Pixel coordinate of reference point CTYPE1Z = 'ZOPT-F2W' / Redshift, non-linear axis CRVAL1Z = 7.914703679E-2 / [] Redshift of reference channel CDELT1Z = 2.848348910E-6 / [] Channel spacing COMMENT RESTFRQZ= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVZ= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSZ= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSZ= 'TOPOCENT' / Reference frame of observation VELOSYSZ= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCZ= 'LSRK ' / Reference frame of source redshift ZSOURCEZ= 0.0000 / Redshift of the source COMMENT CRPIX2Z = 1 CDELT2Z = 1.0 CTYPE2Z = 'RA ' CRVAL2Z = 83.81042 / [deg] (05h35m14.5s) CUNIT2Z = 'deg ' COMMENT CRPIX3Z = 1 CDELT3Z = 1.0 CTYPE3Z = 'DEC ' CRVAL3Z = -5.375222 / [deg] (-05:22:30.8) CUNIT3Z = 'deg ' COMMENT RADESYSZ= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXZ= 2000.0 / Equinox J2000.0 COMMENT CRPIX4Z = 1 CDELT4Z = 1.0 CTYPE4Z = 'STOKES ' CRVAL4Z = 1 / Stokes I (total intensity) COMMENT COMMENT ------------------------------------------------ Relativistic velocity COMMENT CRPIX1V = 32768.0 / Pixel coordinate of reference point CTYPE1V = 'VELO-F2V' / Relativistic velocity, non-linear axis CRVAL1V = 2.279141418E+7 / [m/s] Velocity of reference channel CDELT1V = 7.867122599E+2 / [m/s] Channel spacing CUNIT1V = 'm/s ' / Units of coordinate increment and value COMMENT RESTFRQV= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVV= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSV= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSV= 'TOPOCENT' / Reference frame of observation VELOSYSV= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCV= 'LSRK ' / Reference frame of source redshift ZSOURCEV= 0.0000 / Redshift of the source COMMENT CRPIX2V = 1 CDELT2V = 1.0 CTYPE2V = 'RA ' CRVAL2V = 83.81042 / [deg] (05h35m14.5s) CUNIT2V = 'deg ' COMMENT CRPIX3V = 1 CDELT3V = 1.0 CTYPE3V = 'DEC ' CRVAL3V = -5.375222 / [deg] (-05:22:30.8) CUNIT3V = 'deg ' COMMENT RADESYSV= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXV= 2000.0 / Equinox J2000.0 COMMENT CRPIX4V = 1 CDELT4V = 1.0 CTYPE4V = 'STOKES ' CRVAL4V = 1 / Stokes I (total intensity) COMMENT COMMENT ---------------------------------------------- Relativistic beta (v/c) COMMENT CRPIX1B = 32768.0 / Pixel coordinate of reference point CTYPE1B = 'BETA-F2V' / Relativistic beta (v/c), non-linear axis CRVAL1B = 7.602397448E-2 / [] Relativistic beta of reference channel CDELT1B = 2.624189632E-6 / [] Channel spacing COMMENT RESTFRQB= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVB= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSB= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSB= 'TOPOCENT' / Reference frame of observation VELOSYSB= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCB= 'LSRK ' / Reference frame of source redshift ZSOURCEB= 0.0000 / Redshift of the source COMMENT CRPIX2B = 1 CDELT2B = 1.0 CTYPE2B = 'RA ' CRVAL2B = 83.81042 / [deg] (05h35m14.5s) CUNIT2B = 'deg ' COMMENT CRPIX3B = 1 CDELT3B = 1.0 CTYPE3B = 'DEC ' CRVAL3B = -5.375222 / [deg] (-05:22:30.8) CUNIT3B = 'deg ' COMMENT RADESYSB= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXB= 2000.0 / Equinox J2000.0 COMMENT CRPIX4B = 1 CDELT4B = 1.0 CTYPE4B = 'STOKES ' CRVAL4B = 1 / Stokes I (total intensity) COMMENT HISTORY fimgcreate 1.0b at 2009-04-22T04:28:02 DATE = '2009-04-22T04:28:02' / file creation date (YYYY-MM-DDThh:mm:ss UT) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/spectra/orion-velo-1.hdr0000644000175100001710000007176000000000000023217 0ustar00vstsdockerSIMPLE = T / file does conform to FITS standard BITPIX = -32 / number of bits per data pixel NAXIS = 1 / number of data axes NAXIS1 = 4096 / length of data axis 1 EXTEND = T / FITS dataset may contain extensions COMMENT FITS (Flexible Image Transport System) format is defined in 'AstronomyCOMMENT and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H COMMENT COMMENT This FITS file contains an example spectral WCS header constructed by COMMENT Mark Calabretta (ATNF) and Dirk Petry (ESO) based on an observation COMMENT of the Orion Kleinmann-Low nebula made by Andrew Walsh (JCU) and COMMENT Sven Thorwirth (MPIfR) using the Mopra radio telescope. COMMENT COMMENT The 110GHz 13CO 1-0 spectrum in this file is linear in relativistic COMMENT velocity having been regridded from a linear frequency axis, as COMMENT observed. COMMENT COMMENT The reference pixel has been placed deliberately well outside the COMMENT the spectrum in order to test spectral-WCS-interpreting software. COMMENT COMMENT Spectral representations are: COMMENT F: Frequency ...frequency-like COMMENT E: Photon energy ...frequency-like COMMENT N: Wave number ...frequency-like COMMENT R: Radio velocity ...frequency-like COMMENT W: Wavelength ...wavelength-like COMMENT O: Optical velocity ...wavelength-like COMMENT Z: Redshift ...wavelength-like COMMENT Relativistic velocity (default) ...velocity-like COMMENT B: Relativistic beta ...velocity-like COMMENT COMMENT The Mopra radio telescope is operated by the Australia Telescope COMMENT National Facility. COMMENT COMMENT Author: Mark Calabretta, Australia Telescope National Facility COMMENT http://www.atnf.csiro.au/~mcalabre/index.html COMMENT 2009-04-22 COMMENT ---------------------------------------------------------------------- COMMENT OBJECT = 'Orion-KL' / Orion Kleinmann-Low nebula MOLECULE= '13CO ' / Carbon(13) monoxide TRANSITI= '1-0 ' / 1-0 transition DATE-OBS= '2006-07-09T20:29:00' / Date of observation TELESCOP= 'ATNF Mopra' / 22m mm-wave telescope OBSERVER= 'Walsh/Thorwirth' / Observers BUNIT = 'K ' / Brightness units, Kelvin COMMENT COMMENT ------------------------------------------------------------ Frequency COMMENT CRPIX1F = 32768.0 / Pixel coordinate of reference point CTYPE1F = 'FREQ-V2F' / Frequency, non-linear axis CRVAL1F = 102.4071237E+9 / [Hz] Frequency of reference channel CDELT1F = -2.513721996E+5 / [Hz] Channel spacing CUNIT1F = 'Hz ' / Units of coordinate increment and value COMMENT RESTFRQF= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVF= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSF= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSF= 'TOPOCENT' / Reference frame of observation VELOSYSF= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCF= 'LSRK ' / Reference frame of source redshift ZSOURCEF= 0.0000 / Redshift of the source COMMENT CRPIX2F = 1 CDELT2F = 1.0 CTYPE2F = 'RA ' CRVAL2F = 83.81042 / [deg] (05h35m14.5s) CUNIT2F = 'deg ' COMMENT CRPIX3F = 1 CDELT3F = 1.0 CTYPE3F = 'DEC ' CRVAL3F = -5.375222 / [deg] (-05:22:30.8) CUNIT3F = 'deg ' COMMENT RADESYSF= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXF= 2000.0 / Equinox J2000.0 COMMENT CRPIX4F = 1 CDELT4F = 1.0 CTYPE4F = 'STOKES ' CRVAL4F = 1 / Stokes I (total intensity) COMMENT COMMENT -------------------------------------------------------- Photon energy COMMENT CRPIX1E = 32768.0 / Pixel coordinate of reference point CTYPE1E = 'ENER-V2F' / Photon energy, non-linear axis CRVAL1E = 4.235222141E-4 / [eV] Photon energy of reference channel CDELT1E = -1.039592821E-9 / [eV] Channel spacing CUNIT1E = 'eV ' / Units of coordinate increment and value COMMENT RESTFRQE= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVE= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSE= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSE= 'TOPOCENT' / Reference frame of observation VELOSYSE= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCE= 'LSRK ' / Reference frame of source redshift ZSOURCEE= 0.0000 / Redshift of the source COMMENT CRPIX2E = 1 CDELT2E = 1.0 CTYPE2E = 'RA ' CRVAL2E = 83.81042 / [deg] (05h35m14.5s) CUNIT2E = 'deg ' COMMENT CRPIX3E = 1 CDELT3E = 1.0 CTYPE3E = 'DEC ' CRVAL3E = -5.375222 / [deg] (-05:22:30.8) CUNIT3E = 'deg ' COMMENT RADESYSE= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXE= 2000.0 / Equinox J2000.0 COMMENT CRPIX4E = 1 CDELT4E = 1.0 CTYPE4E = 'STOKES ' CRVAL4E = 1 / Stokes I (total intensity) COMMENT COMMENT ---------------------------------------------------------- Wave number COMMENT CRPIX1N = 32768.0 / Pixel coordinate of reference point CTYPE1N = 'WAVN-V2F' / Wave number, non-linear axis CRVAL1N = 3.415933955E+2 / [/m] Wave number of reference channel CDELT1N = -8.384874032E-4 / [/m] Channel spacing CUNIT1N = '/m ' / Units of coordinate increment and value COMMENT RESTFRQN= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVN= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSN= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSN= 'TOPOCENT' / Reference frame of observation VELOSYSN= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCN= 'LSRK ' / Reference frame of source redshift ZSOURCEN= 0.0000 / Redshift of the source COMMENT CRPIX2N = 1 CDELT2N = 1.0 CTYPE2N = 'RA ' CRVAL2N = 83.81042 / [deg] (05h35m14.5s) CUNIT2N = 'deg ' COMMENT CRPIX3N = 1 CDELT3N = 1.0 CTYPE3N = 'DEC ' CRVAL3N = -5.375222 / [deg] (-05:22:30.8) CUNIT3N = 'deg ' COMMENT RADESYSN= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXN= 2000.0 / Equinox J2000.0 COMMENT CRPIX4N = 1 CDELT4N = 1.0 CTYPE4N = 'STOKES ' CRVAL4N = 1 / Stokes I (total intensity) COMMENT COMMENT ------------------------------------------------------- Radio velocity COMMENT CRPIX1R = 32768.0 / Pixel coordinate of reference point CTYPE1R = 'VRAD-V2F' / Radio velocity, non-linear axis CRVAL1R = 2.120347082E+7 / [m/s] Radio velocity of reference channel CDELT1R = 6.838345224E+2 / [m/s] Channel spacing CUNIT1R = 'm/s ' / Units of coordinate increment and value COMMENT RESTFRQR= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVR= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSR= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSR= 'TOPOCENT' / Reference frame of observation VELOSYSR= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCR= 'LSRK ' / Reference frame of source redshift ZSOURCER= 0.0000 / Redshift of the source COMMENT CRPIX2R = 1 CDELT2R = 1.0 CTYPE2R = 'RA ' CRVAL2R = 83.81042 / [deg] (05h35m14.5s) CUNIT2R = 'deg ' COMMENT CRPIX3R = 1 CDELT3R = 1.0 CTYPE3R = 'DEC ' CRVAL3R = -5.375222 / [deg] (-05:22:30.8) CUNIT3R = 'deg ' COMMENT RADESYSR= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXR= 2000.0 / Equinox J2000.0 COMMENT CRPIX4R = 1 CDELT4R = 1.0 CTYPE4R = 'STOKES ' CRVAL4R = 1 / Stokes I (total intensity) COMMENT COMMENT ----------------------------------------------------------- Wavelength COMMENT CRPIX1W = 32768.0 / Pixel coordinate of reference point CTYPE1W = 'WAVE-V2W' / Wavelength in vacuuo, linear axis CRVAL1W = 2.927457068E-3 / [m] Wavelength of reference channel CDELT1W = 7.185841143E-9 / [m] Channel spacing CUNIT1W = 'm ' / Units of coordinate increment and value COMMENT RESTFRQW= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVW= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSW= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSW= 'TOPOCENT' / Reference frame of observation VELOSYSW= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCW= 'LSRK ' / Reference frame of source redshift ZSOURCEW= 0.0000 / Redshift of the source COMMENT CRPIX2W = 1 CDELT2W = 1.0 CTYPE2W = 'RA ' CRVAL2W = 83.81042 / [deg] (05h35m14.5s) CUNIT2W = 'deg ' COMMENT CRPIX3W = 1 CDELT3W = 1.0 CTYPE3W = 'DEC ' CRVAL3W = -5.375222 / [deg] (-05:22:30.8) CUNIT3W = 'deg ' COMMENT RADESYSW= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXW= 2000.0 / Equinox J2000.0 COMMENT CRPIX4W = 1 CDELT4W = 1.0 CTYPE4W = 'STOKES ' CRVAL4W = 1 / Stokes I (total intensity) COMMENT COMMENT ----------------------------------------------------- Optical velocity COMMENT CRPIX1O = 32768.0 / Pixel coordinate of reference point CTYPE1O = 'VOPT-V2W' / Optical velocity, linear axis CRVAL1O = 2.281727178E+7 / [m/s] Optical velocity of reference channel CDELT1O = 7.918894164E+2 / [m/s] Channel spacing CUNIT1O = 'm/s ' / Units of coordinate increment and value COMMENT RESTFRQO= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVO= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSO= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSO= 'TOPOCENT' / Reference frame of observation VELOSYSO= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCO= 'LSRK ' / Reference frame of source redshift ZSOURCEO= 0.0000 / Redshift of the source COMMENT CRPIX2O = 1 CDELT2O = 1.0 CTYPE2O = 'RA ' CRVAL2O = 83.81042 / [deg] (05h35m14.5s) CUNIT2O = 'deg ' COMMENT CRPIX3O = 1 CDELT3O = 1.0 CTYPE3O = 'DEC ' CRVAL3O = -5.375222 / [deg] (-05:22:30.8) CUNIT3O = 'deg ' COMMENT RADESYSO= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXO= 2000.0 / Equinox J2000.0 COMMENT CRPIX4O = 1 CDELT4O = 1.0 CTYPE4O = 'STOKES ' CRVAL4O = 1 / Stokes I (total intensity) COMMENT COMMENT ------------------------------------------------------------- Redshift COMMENT CRPIX1Z = 32768.0 / Pixel coordinate of reference point CTYPE1Z = 'ZOPT-V2W' / Redshift, linear axis CRVAL1Z = 7.611022615E-2 / [] Redshift of reference channel CDELT1Z = 2.641458767E-6 / [] Channel spacing COMMENT RESTFRQZ= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVZ= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSZ= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSZ= 'TOPOCENT' / Reference frame of observation VELOSYSZ= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCZ= 'LSRK ' / Reference frame of source redshift ZSOURCEZ= 0.0000 / Redshift of the source COMMENT CRPIX2Z = 1 CDELT2Z = 1.0 CTYPE2Z = 'RA ' CRVAL2Z = 83.81042 / [deg] (05h35m14.5s) CUNIT2Z = 'deg ' COMMENT CRPIX3Z = 1 CDELT3Z = 1.0 CTYPE3Z = 'DEC ' CRVAL3Z = -5.375222 / [deg] (-05:22:30.8) CUNIT3Z = 'deg ' COMMENT RADESYSZ= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXZ= 2000.0 / Equinox J2000.0 COMMENT CRPIX4Z = 1 CDELT4Z = 1.0 CTYPE4Z = 'STOKES ' CRVAL4Z = 1 / Stokes I (total intensity) COMMENT COMMENT ------------------------------------------------ Relativistic velocity COMMENT CRPIX1 = 32768.0 / Pixel coordinate of reference point CTYPE1 = 'VELO ' / Relativistic velocity, non-linear axis CRVAL1 = 2.195128874E+7 / [m/s] Velocity of reference channel CDELT1 = 7.319359645E+2 / [m/s] Channel spacing CUNIT1 = 'm/s ' / Units of coordinate increment and value COMMENT RESTFRQ = 110201353000.0 / [Hz] 13CO line rest frequency RESTWAV = 0.00272040633 / [m] 13CO line rest wavelength SPECSYS = 'LSRK ' / Reference frame of spectral coordinates SSYSOBS = 'TOPOCENT' / Reference frame of observation VELOSYS = 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRC = 'LSRK ' / Reference frame of source redshift ZSOURCE = 0.0000 / Redshift of the source COMMENT CRPIX2 = 1 CDELT2 = 1.0 CTYPE2 = 'RA ' CRVAL2 = 83.81042 / [deg] (05h35m14.5s) CUNIT2 = 'deg ' COMMENT CRPIX3 = 1 CDELT3 = 1.0 CTYPE3 = 'DEC ' CRVAL3 = -5.375222 / [deg] (-05:22:30.8) CUNIT3 = 'deg ' COMMENT RADESYS = 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOX = 2000.0 / Equinox J2000.0 COMMENT CRPIX4 = 1 CDELT4 = 1.0 CTYPE4 = 'STOKES ' CRVAL4 = 1 / Stokes I (total intensity) COMMENT COMMENT ---------------------------------------------- Relativistic beta (v/c) COMMENT CRPIX1B = 32768.0 / Pixel coordinate of reference point CTYPE1B = 'BETA ' / Relativistic beta (v/c), non-linear axis CRVAL1B = 7.322161766E-2 / [] Relativistic beta of reference channel CDELT1B = 2.441475578E-6 / [] Channel spacing COMMENT RESTFRQB= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVB= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSB= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSB= 'TOPOCENT' / Reference frame of observation VELOSYSB= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCB= 'LSRK ' / Reference frame of source redshift ZSOURCEB= 0.0000 / Redshift of the source COMMENT CRPIX2B = 1 CDELT2B = 1.0 CTYPE2B = 'RA ' CRVAL2B = 83.81042 / [deg] (05h35m14.5s) CUNIT2B = 'deg ' COMMENT CRPIX3B = 1 CDELT3B = 1.0 CTYPE3B = 'DEC ' CRVAL3B = -5.375222 / [deg] (-05:22:30.8) CUNIT3B = 'deg ' COMMENT RADESYSB= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXB= 2000.0 / Equinox J2000.0 COMMENT CRPIX4B = 1 CDELT4B = 1.0 CTYPE4B = 'STOKES ' CRVAL4B = 1 / Stokes I (total intensity) COMMENT HISTORY fimgcreate 1.0b at 2009-04-22T04:28:25 DATE = '2009-04-22T04:28:25' / file creation date (YYYY-MM-DDThh:mm:ss UT) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/spectra/orion-velo-4.hdr0000644000175100001710000007234000000000000023215 0ustar00vstsdockerSIMPLE = T / file does conform to FITS standard BITPIX = -32 / number of bits per data pixel NAXIS = 4 / number of data axes NAXIS1 = 4096 / length of data axis 1 NAXIS2 = 1 / length of data axis 2 NAXIS3 = 1 / length of data axis 3 NAXIS4 = 1 / length of data axis 4 EXTEND = T / FITS dataset may contain extensions COMMENT FITS (Flexible Image Transport System) format is defined in 'AstronomyCOMMENT and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H COMMENT COMMENT This FITS file contains an example spectral WCS header constructed by COMMENT Mark Calabretta (ATNF) and Dirk Petry (ESO) based on an observation COMMENT of the Orion Kleinmann-Low nebula made by Andrew Walsh (JCU) and COMMENT Sven Thorwirth (MPIfR) using the Mopra radio telescope. COMMENT COMMENT The 110GHz 13CO 1-0 spectrum in this file is linear in relativistic COMMENT velocity having been regridded from a linear frequency axis, as COMMENT observed. COMMENT COMMENT The reference pixel has been placed deliberately well outside the COMMENT the spectrum in order to test spectral-WCS-interpreting software. COMMENT COMMENT Spectral representations are: COMMENT F: Frequency ...frequency-like COMMENT E: Photon energy ...frequency-like COMMENT N: Wave number ...frequency-like COMMENT R: Radio velocity ...frequency-like COMMENT W: Wavelength ...wavelength-like COMMENT O: Optical velocity ...wavelength-like COMMENT Z: Redshift ...wavelength-like COMMENT Relativistic velocity (default) ...velocity-like COMMENT B: Relativistic beta ...velocity-like COMMENT COMMENT The Mopra radio telescope is operated by the Australia Telescope COMMENT National Facility. COMMENT COMMENT Author: Mark Calabretta, Australia Telescope National Facility COMMENT http://www.atnf.csiro.au/~mcalabre/index.html COMMENT 2009-04-22 COMMENT ---------------------------------------------------------------------- COMMENT OBJECT = 'Orion-KL' / Orion Kleinmann-Low nebula MOLECULE= '13CO ' / Carbon(13) monoxide TRANSITI= '1-0 ' / 1-0 transition DATE-OBS= '2006-07-09T20:29:00' / Date of observation TELESCOP= 'ATNF Mopra' / 22m mm-wave telescope OBSERVER= 'Walsh/Thorwirth' / Observers BUNIT = 'K ' / Brightness units, Kelvin COMMENT COMMENT ------------------------------------------------------------ Frequency COMMENT CRPIX1F = 32768.0 / Pixel coordinate of reference point CTYPE1F = 'FREQ-V2F' / Frequency, non-linear axis CRVAL1F = 102.4071237E+9 / [Hz] Frequency of reference channel CDELT1F = -2.513721996E+5 / [Hz] Channel spacing CUNIT1F = 'Hz ' / Units of coordinate increment and value COMMENT RESTFRQF= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVF= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSF= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSF= 'TOPOCENT' / Reference frame of observation VELOSYSF= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCF= 'LSRK ' / Reference frame of source redshift ZSOURCEF= 0.0000 / Redshift of the source COMMENT CRPIX2F = 1 CDELT2F = 1.0 CTYPE2F = 'RA ' CRVAL2F = 83.81042 / [deg] (05h35m14.5s) CUNIT2F = 'deg ' COMMENT CRPIX3F = 1 CDELT3F = 1.0 CTYPE3F = 'DEC ' CRVAL3F = -5.375222 / [deg] (-05:22:30.8) CUNIT3F = 'deg ' COMMENT RADESYSF= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXF= 2000.0 / Equinox J2000.0 COMMENT CRPIX4F = 1 CDELT4F = 1.0 CTYPE4F = 'STOKES ' CRVAL4F = 1 / Stokes I (total intensity) COMMENT COMMENT -------------------------------------------------------- Photon energy COMMENT CRPIX1E = 32768.0 / Pixel coordinate of reference point CTYPE1E = 'ENER-V2F' / Photon energy, non-linear axis CRVAL1E = 4.235222141E-4 / [eV] Photon energy of reference channel CDELT1E = -1.039592821E-9 / [eV] Channel spacing CUNIT1E = 'eV ' / Units of coordinate increment and value COMMENT RESTFRQE= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVE= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSE= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSE= 'TOPOCENT' / Reference frame of observation VELOSYSE= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCE= 'LSRK ' / Reference frame of source redshift ZSOURCEE= 0.0000 / Redshift of the source COMMENT CRPIX2E = 1 CDELT2E = 1.0 CTYPE2E = 'RA ' CRVAL2E = 83.81042 / [deg] (05h35m14.5s) CUNIT2E = 'deg ' COMMENT CRPIX3E = 1 CDELT3E = 1.0 CTYPE3E = 'DEC ' CRVAL3E = -5.375222 / [deg] (-05:22:30.8) CUNIT3E = 'deg ' COMMENT RADESYSE= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXE= 2000.0 / Equinox J2000.0 COMMENT CRPIX4E = 1 CDELT4E = 1.0 CTYPE4E = 'STOKES ' CRVAL4E = 1 / Stokes I (total intensity) COMMENT COMMENT ---------------------------------------------------------- Wave number COMMENT CRPIX1N = 32768.0 / Pixel coordinate of reference point CTYPE1N = 'WAVN-V2F' / Wave number, non-linear axis CRVAL1N = 3.415933955E+2 / [/m] Wave number of reference channel CDELT1N = -8.384874032E-4 / [/m] Channel spacing CUNIT1N = '/m ' / Units of coordinate increment and value COMMENT RESTFRQN= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVN= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSN= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSN= 'TOPOCENT' / Reference frame of observation VELOSYSN= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCN= 'LSRK ' / Reference frame of source redshift ZSOURCEN= 0.0000 / Redshift of the source COMMENT CRPIX2N = 1 CDELT2N = 1.0 CTYPE2N = 'RA ' CRVAL2N = 83.81042 / [deg] (05h35m14.5s) CUNIT2N = 'deg ' COMMENT CRPIX3N = 1 CDELT3N = 1.0 CTYPE3N = 'DEC ' CRVAL3N = -5.375222 / [deg] (-05:22:30.8) CUNIT3N = 'deg ' COMMENT RADESYSN= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXN= 2000.0 / Equinox J2000.0 COMMENT CRPIX4N = 1 CDELT4N = 1.0 CTYPE4N = 'STOKES ' CRVAL4N = 1 / Stokes I (total intensity) COMMENT COMMENT ------------------------------------------------------- Radio velocity COMMENT CRPIX1R = 32768.0 / Pixel coordinate of reference point CTYPE1R = 'VRAD-V2F' / Radio velocity, non-linear axis CRVAL1R = 2.120347082E+7 / [m/s] Radio velocity of reference channel CDELT1R = 6.838345224E+2 / [m/s] Channel spacing CUNIT1R = 'm/s ' / Units of coordinate increment and value COMMENT RESTFRQR= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVR= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSR= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSR= 'TOPOCENT' / Reference frame of observation VELOSYSR= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCR= 'LSRK ' / Reference frame of source redshift ZSOURCER= 0.0000 / Redshift of the source COMMENT CRPIX2R = 1 CDELT2R = 1.0 CTYPE2R = 'RA ' CRVAL2R = 83.81042 / [deg] (05h35m14.5s) CUNIT2R = 'deg ' COMMENT CRPIX3R = 1 CDELT3R = 1.0 CTYPE3R = 'DEC ' CRVAL3R = -5.375222 / [deg] (-05:22:30.8) CUNIT3R = 'deg ' COMMENT RADESYSR= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXR= 2000.0 / Equinox J2000.0 COMMENT CRPIX4R = 1 CDELT4R = 1.0 CTYPE4R = 'STOKES ' CRVAL4R = 1 / Stokes I (total intensity) COMMENT COMMENT ----------------------------------------------------------- Wavelength COMMENT CRPIX1W = 32768.0 / Pixel coordinate of reference point CTYPE1W = 'WAVE-V2W' / Wavelength in vacuuo, linear axis CRVAL1W = 2.927457068E-3 / [m] Wavelength of reference channel CDELT1W = 7.185841143E-9 / [m] Channel spacing CUNIT1W = 'm ' / Units of coordinate increment and value COMMENT RESTFRQW= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVW= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSW= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSW= 'TOPOCENT' / Reference frame of observation VELOSYSW= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCW= 'LSRK ' / Reference frame of source redshift ZSOURCEW= 0.0000 / Redshift of the source COMMENT CRPIX2W = 1 CDELT2W = 1.0 CTYPE2W = 'RA ' CRVAL2W = 83.81042 / [deg] (05h35m14.5s) CUNIT2W = 'deg ' COMMENT CRPIX3W = 1 CDELT3W = 1.0 CTYPE3W = 'DEC ' CRVAL3W = -5.375222 / [deg] (-05:22:30.8) CUNIT3W = 'deg ' COMMENT RADESYSW= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXW= 2000.0 / Equinox J2000.0 COMMENT CRPIX4W = 1 CDELT4W = 1.0 CTYPE4W = 'STOKES ' CRVAL4W = 1 / Stokes I (total intensity) COMMENT COMMENT ----------------------------------------------------- Optical velocity COMMENT CRPIX1O = 32768.0 / Pixel coordinate of reference point CTYPE1O = 'VOPT-V2W' / Optical velocity, linear axis CRVAL1O = 2.281727178E+7 / [m/s] Optical velocity of reference channel CDELT1O = 7.918894164E+2 / [m/s] Channel spacing CUNIT1O = 'm/s ' / Units of coordinate increment and value COMMENT RESTFRQO= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVO= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSO= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSO= 'TOPOCENT' / Reference frame of observation VELOSYSO= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCO= 'LSRK ' / Reference frame of source redshift ZSOURCEO= 0.0000 / Redshift of the source COMMENT CRPIX2O = 1 CDELT2O = 1.0 CTYPE2O = 'RA ' CRVAL2O = 83.81042 / [deg] (05h35m14.5s) CUNIT2O = 'deg ' COMMENT CRPIX3O = 1 CDELT3O = 1.0 CTYPE3O = 'DEC ' CRVAL3O = -5.375222 / [deg] (-05:22:30.8) CUNIT3O = 'deg ' COMMENT RADESYSO= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXO= 2000.0 / Equinox J2000.0 COMMENT CRPIX4O = 1 CDELT4O = 1.0 CTYPE4O = 'STOKES ' CRVAL4O = 1 / Stokes I (total intensity) COMMENT COMMENT ------------------------------------------------------------- Redshift COMMENT CRPIX1Z = 32768.0 / Pixel coordinate of reference point CTYPE1Z = 'ZOPT-V2W' / Redshift, linear axis CRVAL1Z = 7.611022615E-2 / [] Redshift of reference channel CDELT1Z = 2.641458767E-6 / [] Channel spacing COMMENT RESTFRQZ= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVZ= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSZ= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSZ= 'TOPOCENT' / Reference frame of observation VELOSYSZ= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCZ= 'LSRK ' / Reference frame of source redshift ZSOURCEZ= 0.0000 / Redshift of the source COMMENT CRPIX2Z = 1 CDELT2Z = 1.0 CTYPE2Z = 'RA ' CRVAL2Z = 83.81042 / [deg] (05h35m14.5s) CUNIT2Z = 'deg ' COMMENT CRPIX3Z = 1 CDELT3Z = 1.0 CTYPE3Z = 'DEC ' CRVAL3Z = -5.375222 / [deg] (-05:22:30.8) CUNIT3Z = 'deg ' COMMENT RADESYSZ= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXZ= 2000.0 / Equinox J2000.0 COMMENT CRPIX4Z = 1 CDELT4Z = 1.0 CTYPE4Z = 'STOKES ' CRVAL4Z = 1 / Stokes I (total intensity) COMMENT COMMENT ------------------------------------------------ Relativistic velocity COMMENT CRPIX1 = 32768.0 / Pixel coordinate of reference point CTYPE1 = 'VELO ' / Relativistic velocity, non-linear axis CRVAL1 = 2.195128874E+7 / [m/s] Velocity of reference channel CDELT1 = 7.319359645E+2 / [m/s] Channel spacing CUNIT1 = 'm/s ' / Units of coordinate increment and value COMMENT RESTFRQ = 110201353000.0 / [Hz] 13CO line rest frequency RESTWAV = 0.00272040633 / [m] 13CO line rest wavelength SPECSYS = 'LSRK ' / Reference frame of spectral coordinates SSYSOBS = 'TOPOCENT' / Reference frame of observation VELOSYS = 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRC = 'LSRK ' / Reference frame of source redshift ZSOURCE = 0.0000 / Redshift of the source COMMENT CRPIX2 = 1 CDELT2 = 1.0 CTYPE2 = 'RA ' CRVAL2 = 83.81042 / [deg] (05h35m14.5s) CUNIT2 = 'deg ' COMMENT CRPIX3 = 1 CDELT3 = 1.0 CTYPE3 = 'DEC ' CRVAL3 = -5.375222 / [deg] (-05:22:30.8) CUNIT3 = 'deg ' COMMENT RADESYS = 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOX = 2000.0 / Equinox J2000.0 COMMENT CRPIX4 = 1 CDELT4 = 1.0 CTYPE4 = 'STOKES ' CRVAL4 = 1 / Stokes I (total intensity) COMMENT COMMENT ---------------------------------------------- Relativistic beta (v/c) COMMENT CRPIX1B = 32768.0 / Pixel coordinate of reference point CTYPE1B = 'BETA ' / Relativistic beta (v/c), non-linear axis CRVAL1B = 7.322161766E-2 / [] Relativistic beta of reference channel CDELT1B = 2.441475578E-6 / [] Channel spacing COMMENT RESTFRQB= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVB= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSB= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSB= 'TOPOCENT' / Reference frame of observation VELOSYSB= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCB= 'LSRK ' / Reference frame of source redshift ZSOURCEB= 0.0000 / Redshift of the source COMMENT CRPIX2B = 1 CDELT2B = 1.0 CTYPE2B = 'RA ' CRVAL2B = 83.81042 / [deg] (05h35m14.5s) CUNIT2B = 'deg ' COMMENT CRPIX3B = 1 CDELT3B = 1.0 CTYPE3B = 'DEC ' CRVAL3B = -5.375222 / [deg] (-05:22:30.8) CUNIT3B = 'deg ' COMMENT RADESYSB= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXB= 2000.0 / Equinox J2000.0 COMMENT CRPIX4B = 1 CDELT4B = 1.0 CTYPE4B = 'STOKES ' CRVAL4B = 1 / Stokes I (total intensity) COMMENT HISTORY fimgcreate 1.0b at 2009-04-22T04:28:33 DATE = '2009-04-22T04:28:33' / file creation date (YYYY-MM-DDThh:mm:ss UT) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/spectra/orion-wave-1.hdr0000644000175100001710000007164000000000000023211 0ustar00vstsdockerSIMPLE = T / file does conform to FITS standard BITPIX = -32 / number of bits per data pixel NAXIS = 1 / number of data axes NAXIS1 = 4096 / length of data axis 1 EXTEND = T / FITS dataset may contain extensions COMMENT FITS (Flexible Image Transport System) format is defined in 'AstronomyCOMMENT and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H COMMENT COMMENT This FITS file contains an example spectral WCS header constructed by COMMENT Mark Calabretta (ATNF) and Dirk Petry (ESO) based on an observation COMMENT of the Orion Kleinmann-Low nebula made by Andrew Walsh (JCU) and COMMENT Sven Thorwirth (MPIfR) using the Mopra radio telescope. COMMENT COMMENT The 110GHz 13CO 1-0 spectrum in this file is linear in wavelength, COMMENT having been regridded from a linear frequency axis, as observed. COMMENT COMMENT The reference pixel has been placed deliberately well outside the COMMENT the spectrum in order to test spectral-WCS-interpreting software. COMMENT COMMENT Spectral representations are: COMMENT F: Frequency ...frequency-like COMMENT E: Photon energy ...frequency-like COMMENT N: Wave number ...frequency-like COMMENT R: Radio velocity ...frequency-like COMMENT Wavelength (default) ...wavelength-like COMMENT O: Optical velocity ...wavelength-like COMMENT Z: Redshift ...wavelength-like COMMENT V: Relativistic velocity ...velocity-like COMMENT B: Relativistic beta ...velocity-like COMMENT COMMENT The Mopra radio telescope is operated by the Australia Telescope COMMENT National Facility. COMMENT COMMENT Author: Mark Calabretta, Australia Telescope National Facility COMMENT http://www.atnf.csiro.au/~mcalabre/index.html COMMENT 2009-04-22 COMMENT ---------------------------------------------------------------------- COMMENT OBJECT = 'Orion-KL' / Orion Kleinmann-Low nebula MOLECULE= '13CO ' / Carbon(13) monoxide TRANSITI= '1-0 ' / 1-0 transition DATE-OBS= '2006-07-09T20:29:00' / Date of observation TELESCOP= 'ATNF Mopra' / 22m mm-wave telescope OBSERVER= 'Walsh/Thorwirth' / Observers BUNIT = 'K ' / Brightness units, Kelvin COMMENT COMMENT ------------------------------------------------------------ Frequency COMMENT CRPIX1F = 32768.0 / Pixel coordinate of reference point CTYPE1F = 'FREQ-W2F' / Frequency, non-linear axis CRVAL1F = 102.6940613E+9 / [Hz] Frequency of reference channel CDELT1F = -2.332330873E+5 / [Hz] Channel spacing CUNIT1F = 'Hz ' / Units of coordinate increment and value COMMENT RESTFRQF= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVF= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSF= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSF= 'TOPOCENT' / Reference frame of observation VELOSYSF= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCF= 'LSRK ' / Reference frame of source redshift ZSOURCEF= 0.0000 / Redshift of the source COMMENT CRPIX2F = 1 CDELT2F = 1.0 CTYPE2F = 'RA ' CRVAL2F = 83.81042 / [deg] (05h35m14.5s) CUNIT2F = 'deg ' COMMENT CRPIX3F = 1 CDELT3F = 1.0 CTYPE3F = 'DEC ' CRVAL3F = -5.375222 / [deg] (-05:22:30.8) CUNIT3F = 'deg ' COMMENT RADESYSF= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXF= 2000.0 / Equinox J2000.0 COMMENT CRPIX4F = 1 CDELT4F = 1.0 CTYPE4F = 'STOKES ' CRVAL4F = 1 / Stokes I (total intensity) COMMENT COMMENT -------------------------------------------------------- Photon energy COMMENT CRPIX1E = 32768.0 / Pixel coordinate of reference point CTYPE1E = 'ENER-W2F' / Photon energy, non-linear axis CRVAL1E = 4.247088937E-4 / [eV] Photon energy of reference channel CDELT1E = -0.9645754124E-9 / [eV] Channel spacing CUNIT1E = 'eV ' / Units of coordinate increment and value COMMENT RESTFRQE= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVE= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSE= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSE= 'TOPOCENT' / Reference frame of observation VELOSYSE= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCE= 'LSRK ' / Reference frame of source redshift ZSOURCEE= 0.0000 / Redshift of the source COMMENT CRPIX2E = 1 CDELT2E = 1.0 CTYPE2E = 'RA ' CRVAL2E = 83.81042 / [deg] (05h35m14.5s) CUNIT2E = 'deg ' COMMENT CRPIX3E = 1 CDELT3E = 1.0 CTYPE3E = 'DEC ' CRVAL3E = -5.375222 / [deg] (-05:22:30.8) CUNIT3E = 'deg ' COMMENT RADESYSE= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXE= 2000.0 / Equinox J2000.0 COMMENT CRPIX4E = 1 CDELT4E = 1.0 CTYPE4E = 'STOKES ' CRVAL4E = 1 / Stokes I (total intensity) COMMENT COMMENT ---------------------------------------------------------- Wave number COMMENT CRPIX1N = 32768.0 / Pixel coordinate of reference point CTYPE1N = 'WAVN-W2F' / Wave number, non-linear axis CRVAL1N = 3.425505162E+2 / [/m] Wave number of reference channel CDELT1N = -7.779818375E-4 / [/m] Channel spacing CUNIT1N = '/m ' / Units of coordinate increment and value COMMENT RESTFRQN= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVN= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSN= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSN= 'TOPOCENT' / Reference frame of observation VELOSYSN= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCN= 'LSRK ' / Reference frame of source redshift ZSOURCEN= 0.0000 / Redshift of the source COMMENT CRPIX2N = 1 CDELT2N = 1.0 CTYPE2N = 'RA ' CRVAL2N = 83.81042 / [deg] (05h35m14.5s) CUNIT2N = 'deg ' COMMENT CRPIX3N = 1 CDELT3N = 1.0 CTYPE3N = 'DEC ' CRVAL3N = -5.375222 / [deg] (-05:22:30.8) CUNIT3N = 'deg ' COMMENT RADESYSN= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXN= 2000.0 / Equinox J2000.0 COMMENT CRPIX4N = 1 CDELT4N = 1.0 CTYPE4N = 'STOKES ' CRVAL4N = 1 / Stokes I (total intensity) COMMENT COMMENT ------------------------------------------------------- Radio velocity COMMENT CRPIX1R = 32768.0 / Pixel coordinate of reference point CTYPE1R = 'VRAD-W2F' / Radio velocity, non-linear axis CRVAL1R = 2.042288396E+7 / [m/s] Radio velocity of reference channel CDELT1R = 6.344887666E+2 / [m/s] Channel spacing CUNIT1R = 'm/s ' / Units of coordinate increment and value COMMENT RESTFRQR= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVR= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSR= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSR= 'TOPOCENT' / Reference frame of observation VELOSYSR= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCR= 'LSRK ' / Reference frame of source redshift ZSOURCER= 0.0000 / Redshift of the source COMMENT CRPIX2R = 1 CDELT2R = 1.0 CTYPE2R = 'RA ' CRVAL2R = 83.81042 / [deg] (05h35m14.5s) CUNIT2R = 'deg ' COMMENT CRPIX3R = 1 CDELT3R = 1.0 CTYPE3R = 'DEC ' CRVAL3R = -5.375222 / [deg] (-05:22:30.8) CUNIT3R = 'deg ' COMMENT RADESYSR= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXR= 2000.0 / Equinox J2000.0 COMMENT CRPIX4R = 1 CDELT4R = 1.0 CTYPE4R = 'STOKES ' CRVAL4R = 1 / Stokes I (total intensity) COMMENT COMMENT ----------------------------------------------------------- Wavelength COMMENT CRPIX1 = 32768.0 / Pixel coordinate of reference point CTYPE1 = 'WAVE ' / Wavelength in vacuuo, linear axis CRVAL1 = 2.919277457E-3 / [m] Wavelength of reference channel CDELT1 = 6.630101933E-9 / [m] Channel spacing CUNIT1 = 'm ' / Units of coordinate increment and value COMMENT RESTFRQ = 110201353000.0 / [Hz] 13CO line rest frequency RESTWAV = 0.00272040633 / [m] 13CO line rest wavelength SPECSYS = 'LSRK ' / Reference frame of spectral coordinates SSYSOBS = 'TOPOCENT' / Reference frame of observation VELOSYS = 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRC = 'LSRK ' / Reference frame of source redshift ZSOURCE = 0.0000 / Redshift of the source COMMENT CRPIX2 = 1 CDELT2 = 1.0 CTYPE2 = 'RA ' CRVAL2 = 83.81042 / [deg] (05h35m14.5s) CUNIT2 = 'deg ' COMMENT CRPIX3 = 1 CDELT3 = 1.0 CTYPE3 = 'DEC ' CRVAL3 = -5.375222 / [deg] (-05:22:30.8) CUNIT3 = 'deg ' COMMENT RADESYS = 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOX = 2000.0 / Equinox J2000.0 COMMENT CRPIX4 = 1 CDELT4 = 1.0 CTYPE4 = 'STOKES ' CRVAL4 = 1 / Stokes I (total intensity) COMMENT COMMENT ----------------------------------------------------- Optical velocity COMMENT CRPIX1O = 32768.0 / Pixel coordinate of reference point CTYPE1O = 'VOPT ' / Optical velocity, linear axis CRVAL1O = 2.191586755E+7 / [m/s] Optical velocity of reference channel CDELT1O = 7.306462036E+2 / [m/s] Channel spacing CUNIT1O = 'm/s ' / Units of coordinate increment and value COMMENT RESTFRQO= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVO= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSO= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSO= 'TOPOCENT' / Reference frame of observation VELOSYSO= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCO= 'LSRK ' / Reference frame of source redshift ZSOURCEO= 0.0000 / Redshift of the source COMMENT CRPIX2O = 1 CDELT2O = 1.0 CTYPE2O = 'RA ' CRVAL2O = 83.81042 / [deg] (05h35m14.5s) CUNIT2O = 'deg ' COMMENT CRPIX3O = 1 CDELT3O = 1.0 CTYPE3O = 'DEC ' CRVAL3O = -5.375222 / [deg] (-05:22:30.8) CUNIT3O = 'deg ' COMMENT RADESYSO= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXO= 2000.0 / Equinox J2000.0 COMMENT CRPIX4O = 1 CDELT4O = 1.0 CTYPE4O = 'STOKES ' CRVAL4O = 1 / Stokes I (total intensity) COMMENT COMMENT ------------------------------------------------------------- Redshift COMMENT CRPIX1Z = 32768.0 / Pixel coordinate of reference point CTYPE1Z = 'ZOPT ' / Redshift, linear axis CRVAL1Z = 7.310346531E-2 / [] Redshift of reference channel CDELT1Z = 2.437173398E-6 / [] Channel spacing COMMENT RESTFRQZ= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVZ= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSZ= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSZ= 'TOPOCENT' / Reference frame of observation VELOSYSZ= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCZ= 'LSRK ' / Reference frame of source redshift ZSOURCEZ= 0.0000 / Redshift of the source COMMENT CRPIX2Z = 1 CDELT2Z = 1.0 CTYPE2Z = 'RA ' CRVAL2Z = 83.81042 / [deg] (05h35m14.5s) CUNIT2Z = 'deg ' COMMENT CRPIX3Z = 1 CDELT3Z = 1.0 CTYPE3Z = 'DEC ' CRVAL3Z = -5.375222 / [deg] (-05:22:30.8) CUNIT3Z = 'deg ' COMMENT RADESYSZ= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXZ= 2000.0 / Equinox J2000.0 COMMENT CRPIX4Z = 1 CDELT4Z = 1.0 CTYPE4Z = 'STOKES ' CRVAL4Z = 1 / Stokes I (total intensity) COMMENT COMMENT ------------------------------------------------ Relativistic velocity COMMENT CRPIX1V = 32768.0 / Pixel coordinate of reference point CTYPE1V = 'VELO-W2V' / Relativistic velocity, non-linear axis CRVAL1V = 2.111679434E+7 / [m/s] Velocity of reference channel CDELT1V = 6.774939349E+2 / [m/s] Channel spacing CUNIT1V = 'm/s ' / Units of coordinate increment and value COMMENT RESTFRQV= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVV= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSV= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSV= 'TOPOCENT' / Reference frame of observation VELOSYSV= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCV= 'LSRK ' / Reference frame of source redshift ZSOURCEV= 0.0000 / Redshift of the source COMMENT CRPIX2V = 1 CDELT2V = 1.0 CTYPE2V = 'RA ' CRVAL2V = 83.81042 / [deg] (05h35m14.5s) CUNIT2V = 'deg ' COMMENT CRPIX3V = 1 CDELT3V = 1.0 CTYPE3V = 'DEC ' CRVAL3V = -5.375222 / [deg] (-05:22:30.8) CUNIT3V = 'deg ' COMMENT RADESYSV= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXV= 2000.0 / Equinox J2000.0 COMMENT CRPIX4V = 1 CDELT4V = 1.0 CTYPE4V = 'STOKES ' CRVAL4V = 1 / Stokes I (total intensity) COMMENT COMMENT ---------------------------------------------- Relativistic beta (v/c) COMMENT CRPIX1B = 32768.0 / Pixel coordinate of reference point CTYPE1B = 'BETA-W2V' / Relativistic beta (v/c), non-linear axis CRVAL1B = 7.043804396E-2 / [] Relativistic beta of reference channel CDELT1B = 2.259876514E-6 / [] Channel spacing COMMENT RESTFRQB= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVB= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSB= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSB= 'TOPOCENT' / Reference frame of observation VELOSYSB= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCB= 'LSRK ' / Reference frame of source redshift ZSOURCEB= 0.0000 / Redshift of the source COMMENT CRPIX2B = 1 CDELT2B = 1.0 CTYPE2B = 'RA ' CRVAL2B = 83.81042 / [deg] (05h35m14.5s) CUNIT2B = 'deg ' COMMENT CRPIX3B = 1 CDELT3B = 1.0 CTYPE3B = 'DEC ' CRVAL3B = -5.375222 / [deg] (-05:22:30.8) CUNIT3B = 'deg ' COMMENT RADESYSB= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXB= 2000.0 / Equinox J2000.0 COMMENT CRPIX4B = 1 CDELT4B = 1.0 CTYPE4B = 'STOKES ' CRVAL4B = 1 / Stokes I (total intensity) COMMENT HISTORY fimgcreate 1.0b at 2009-04-22T04:28:10 DATE = '2009-04-22T04:28:10' / file creation date (YYYY-MM-DDThh:mm:ss UT) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/spectra/orion-wave-4.hdr0000644000175100001710000007222000000000000023207 0ustar00vstsdockerSIMPLE = T / file does conform to FITS standard BITPIX = -32 / number of bits per data pixel NAXIS = 4 / number of data axes NAXIS1 = 4096 / length of data axis 1 NAXIS2 = 1 / length of data axis 2 NAXIS3 = 1 / length of data axis 3 NAXIS4 = 1 / length of data axis 4 EXTEND = T / FITS dataset may contain extensions COMMENT FITS (Flexible Image Transport System) format is defined in 'AstronomyCOMMENT and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H COMMENT COMMENT This FITS file contains an example spectral WCS header constructed by COMMENT Mark Calabretta (ATNF) and Dirk Petry (ESO) based on an observation COMMENT of the Orion Kleinmann-Low nebula made by Andrew Walsh (JCU) and COMMENT Sven Thorwirth (MPIfR) using the Mopra radio telescope. COMMENT COMMENT The 110GHz 13CO 1-0 spectrum in this file is linear in wavelength, COMMENT having been regridded from a linear frequency axis, as observed. COMMENT COMMENT The reference pixel has been placed deliberately well outside the COMMENT the spectrum in order to test spectral-WCS-interpreting software. COMMENT COMMENT Spectral representations are: COMMENT F: Frequency ...frequency-like COMMENT E: Photon energy ...frequency-like COMMENT N: Wave number ...frequency-like COMMENT R: Radio velocity ...frequency-like COMMENT Wavelength (default) ...wavelength-like COMMENT O: Optical velocity ...wavelength-like COMMENT Z: Redshift ...wavelength-like COMMENT V: Relativistic velocity ...velocity-like COMMENT B: Relativistic beta ...velocity-like COMMENT COMMENT The Mopra radio telescope is operated by the Australia Telescope COMMENT National Facility. COMMENT COMMENT Author: Mark Calabretta, Australia Telescope National Facility COMMENT http://www.atnf.csiro.au/~mcalabre/index.html COMMENT 2009-04-22 COMMENT ---------------------------------------------------------------------- COMMENT OBJECT = 'Orion-KL' / Orion Kleinmann-Low nebula MOLECULE= '13CO ' / Carbon(13) monoxide TRANSITI= '1-0 ' / 1-0 transition DATE-OBS= '2006-07-09T20:29:00' / Date of observation TELESCOP= 'ATNF Mopra' / 22m mm-wave telescope OBSERVER= 'Walsh/Thorwirth' / Observers BUNIT = 'K ' / Brightness units, Kelvin COMMENT COMMENT ------------------------------------------------------------ Frequency COMMENT CRPIX1F = 32768.0 / Pixel coordinate of reference point CTYPE1F = 'FREQ-W2F' / Frequency, non-linear axis CRVAL1F = 102.6940613E+9 / [Hz] Frequency of reference channel CDELT1F = -2.332330873E+5 / [Hz] Channel spacing CUNIT1F = 'Hz ' / Units of coordinate increment and value COMMENT RESTFRQF= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVF= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSF= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSF= 'TOPOCENT' / Reference frame of observation VELOSYSF= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCF= 'LSRK ' / Reference frame of source redshift ZSOURCEF= 0.0000 / Redshift of the source COMMENT CRPIX2F = 1 CDELT2F = 1.0 CTYPE2F = 'RA ' CRVAL2F = 83.81042 / [deg] (05h35m14.5s) CUNIT2F = 'deg ' COMMENT CRPIX3F = 1 CDELT3F = 1.0 CTYPE3F = 'DEC ' CRVAL3F = -5.375222 / [deg] (-05:22:30.8) CUNIT3F = 'deg ' COMMENT RADESYSF= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXF= 2000.0 / Equinox J2000.0 COMMENT CRPIX4F = 1 CDELT4F = 1.0 CTYPE4F = 'STOKES ' CRVAL4F = 1 / Stokes I (total intensity) COMMENT COMMENT -------------------------------------------------------- Photon energy COMMENT CRPIX1E = 32768.0 / Pixel coordinate of reference point CTYPE1E = 'ENER-W2F' / Photon energy, non-linear axis CRVAL1E = 4.247088937E-4 / [eV] Photon energy of reference channel CDELT1E = -0.9645754124E-9 / [eV] Channel spacing CUNIT1E = 'eV ' / Units of coordinate increment and value COMMENT RESTFRQE= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVE= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSE= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSE= 'TOPOCENT' / Reference frame of observation VELOSYSE= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCE= 'LSRK ' / Reference frame of source redshift ZSOURCEE= 0.0000 / Redshift of the source COMMENT CRPIX2E = 1 CDELT2E = 1.0 CTYPE2E = 'RA ' CRVAL2E = 83.81042 / [deg] (05h35m14.5s) CUNIT2E = 'deg ' COMMENT CRPIX3E = 1 CDELT3E = 1.0 CTYPE3E = 'DEC ' CRVAL3E = -5.375222 / [deg] (-05:22:30.8) CUNIT3E = 'deg ' COMMENT RADESYSE= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXE= 2000.0 / Equinox J2000.0 COMMENT CRPIX4E = 1 CDELT4E = 1.0 CTYPE4E = 'STOKES ' CRVAL4E = 1 / Stokes I (total intensity) COMMENT COMMENT ---------------------------------------------------------- Wave number COMMENT CRPIX1N = 32768.0 / Pixel coordinate of reference point CTYPE1N = 'WAVN-W2F' / Wave number, non-linear axis CRVAL1N = 3.425505162E+2 / [/m] Wave number of reference channel CDELT1N = -7.779818375E-4 / [/m] Channel spacing CUNIT1N = '/m ' / Units of coordinate increment and value COMMENT RESTFRQN= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVN= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSN= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSN= 'TOPOCENT' / Reference frame of observation VELOSYSN= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCN= 'LSRK ' / Reference frame of source redshift ZSOURCEN= 0.0000 / Redshift of the source COMMENT CRPIX2N = 1 CDELT2N = 1.0 CTYPE2N = 'RA ' CRVAL2N = 83.81042 / [deg] (05h35m14.5s) CUNIT2N = 'deg ' COMMENT CRPIX3N = 1 CDELT3N = 1.0 CTYPE3N = 'DEC ' CRVAL3N = -5.375222 / [deg] (-05:22:30.8) CUNIT3N = 'deg ' COMMENT RADESYSN= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXN= 2000.0 / Equinox J2000.0 COMMENT CRPIX4N = 1 CDELT4N = 1.0 CTYPE4N = 'STOKES ' CRVAL4N = 1 / Stokes I (total intensity) COMMENT COMMENT ------------------------------------------------------- Radio velocity COMMENT CRPIX1R = 32768.0 / Pixel coordinate of reference point CTYPE1R = 'VRAD-W2F' / Radio velocity, non-linear axis CRVAL1R = 2.042288396E+7 / [m/s] Radio velocity of reference channel CDELT1R = 6.344887666E+2 / [m/s] Channel spacing CUNIT1R = 'm/s ' / Units of coordinate increment and value COMMENT RESTFRQR= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVR= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSR= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSR= 'TOPOCENT' / Reference frame of observation VELOSYSR= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCR= 'LSRK ' / Reference frame of source redshift ZSOURCER= 0.0000 / Redshift of the source COMMENT CRPIX2R = 1 CDELT2R = 1.0 CTYPE2R = 'RA ' CRVAL2R = 83.81042 / [deg] (05h35m14.5s) CUNIT2R = 'deg ' COMMENT CRPIX3R = 1 CDELT3R = 1.0 CTYPE3R = 'DEC ' CRVAL3R = -5.375222 / [deg] (-05:22:30.8) CUNIT3R = 'deg ' COMMENT RADESYSR= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXR= 2000.0 / Equinox J2000.0 COMMENT CRPIX4R = 1 CDELT4R = 1.0 CTYPE4R = 'STOKES ' CRVAL4R = 1 / Stokes I (total intensity) COMMENT COMMENT ----------------------------------------------------------- Wavelength COMMENT CRPIX1 = 32768.0 / Pixel coordinate of reference point CTYPE1 = 'WAVE ' / Wavelength in vacuuo, linear axis CRVAL1 = 2.919277457E-3 / [m] Wavelength of reference channel CDELT1 = 6.630101933E-9 / [m] Channel spacing CUNIT1 = 'm ' / Units of coordinate increment and value COMMENT RESTFRQ = 110201353000.0 / [Hz] 13CO line rest frequency RESTWAV = 0.00272040633 / [m] 13CO line rest wavelength SPECSYS = 'LSRK ' / Reference frame of spectral coordinates SSYSOBS = 'TOPOCENT' / Reference frame of observation VELOSYS = 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRC = 'LSRK ' / Reference frame of source redshift ZSOURCE = 0.0000 / Redshift of the source COMMENT CRPIX2 = 1 CDELT2 = 1.0 CTYPE2 = 'RA ' CRVAL2 = 83.81042 / [deg] (05h35m14.5s) CUNIT2 = 'deg ' COMMENT CRPIX3 = 1 CDELT3 = 1.0 CTYPE3 = 'DEC ' CRVAL3 = -5.375222 / [deg] (-05:22:30.8) CUNIT3 = 'deg ' COMMENT RADESYS = 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOX = 2000.0 / Equinox J2000.0 COMMENT CRPIX4 = 1 CDELT4 = 1.0 CTYPE4 = 'STOKES ' CRVAL4 = 1 / Stokes I (total intensity) COMMENT COMMENT ----------------------------------------------------- Optical velocity COMMENT CRPIX1O = 32768.0 / Pixel coordinate of reference point CTYPE1O = 'VOPT ' / Optical velocity, linear axis CRVAL1O = 2.191586755E+7 / [m/s] Optical velocity of reference channel CDELT1O = 7.306462036E+2 / [m/s] Channel spacing CUNIT1O = 'm/s ' / Units of coordinate increment and value COMMENT RESTFRQO= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVO= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSO= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSO= 'TOPOCENT' / Reference frame of observation VELOSYSO= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCO= 'LSRK ' / Reference frame of source redshift ZSOURCEO= 0.0000 / Redshift of the source COMMENT CRPIX2O = 1 CDELT2O = 1.0 CTYPE2O = 'RA ' CRVAL2O = 83.81042 / [deg] (05h35m14.5s) CUNIT2O = 'deg ' COMMENT CRPIX3O = 1 CDELT3O = 1.0 CTYPE3O = 'DEC ' CRVAL3O = -5.375222 / [deg] (-05:22:30.8) CUNIT3O = 'deg ' COMMENT RADESYSO= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXO= 2000.0 / Equinox J2000.0 COMMENT CRPIX4O = 1 CDELT4O = 1.0 CTYPE4O = 'STOKES ' CRVAL4O = 1 / Stokes I (total intensity) COMMENT COMMENT ------------------------------------------------------------- Redshift COMMENT CRPIX1Z = 32768.0 / Pixel coordinate of reference point CTYPE1Z = 'ZOPT ' / Redshift, linear axis CRVAL1Z = 7.310346531E-2 / [] Redshift of reference channel CDELT1Z = 2.437173398E-6 / [] Channel spacing COMMENT RESTFRQZ= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVZ= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSZ= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSZ= 'TOPOCENT' / Reference frame of observation VELOSYSZ= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCZ= 'LSRK ' / Reference frame of source redshift ZSOURCEZ= 0.0000 / Redshift of the source COMMENT CRPIX2Z = 1 CDELT2Z = 1.0 CTYPE2Z = 'RA ' CRVAL2Z = 83.81042 / [deg] (05h35m14.5s) CUNIT2Z = 'deg ' COMMENT CRPIX3Z = 1 CDELT3Z = 1.0 CTYPE3Z = 'DEC ' CRVAL3Z = -5.375222 / [deg] (-05:22:30.8) CUNIT3Z = 'deg ' COMMENT RADESYSZ= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXZ= 2000.0 / Equinox J2000.0 COMMENT CRPIX4Z = 1 CDELT4Z = 1.0 CTYPE4Z = 'STOKES ' CRVAL4Z = 1 / Stokes I (total intensity) COMMENT COMMENT ------------------------------------------------ Relativistic velocity COMMENT CRPIX1V = 32768.0 / Pixel coordinate of reference point CTYPE1V = 'VELO-W2V' / Relativistic velocity, non-linear axis CRVAL1V = 2.111679434E+7 / [m/s] Velocity of reference channel CDELT1V = 6.774939349E+2 / [m/s] Channel spacing CUNIT1V = 'm/s ' / Units of coordinate increment and value COMMENT RESTFRQV= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVV= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSV= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSV= 'TOPOCENT' / Reference frame of observation VELOSYSV= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCV= 'LSRK ' / Reference frame of source redshift ZSOURCEV= 0.0000 / Redshift of the source COMMENT CRPIX2V = 1 CDELT2V = 1.0 CTYPE2V = 'RA ' CRVAL2V = 83.81042 / [deg] (05h35m14.5s) CUNIT2V = 'deg ' COMMENT CRPIX3V = 1 CDELT3V = 1.0 CTYPE3V = 'DEC ' CRVAL3V = -5.375222 / [deg] (-05:22:30.8) CUNIT3V = 'deg ' COMMENT RADESYSV= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXV= 2000.0 / Equinox J2000.0 COMMENT CRPIX4V = 1 CDELT4V = 1.0 CTYPE4V = 'STOKES ' CRVAL4V = 1 / Stokes I (total intensity) COMMENT COMMENT ---------------------------------------------- Relativistic beta (v/c) COMMENT CRPIX1B = 32768.0 / Pixel coordinate of reference point CTYPE1B = 'BETA-W2V' / Relativistic beta (v/c), non-linear axis CRVAL1B = 7.043804396E-2 / [] Relativistic beta of reference channel CDELT1B = 2.259876514E-6 / [] Channel spacing COMMENT RESTFRQB= 110201353000.0 / [Hz] 13CO line rest frequency RESTWAVB= 0.00272040633 / [m] 13CO line rest wavelength SPECSYSB= 'LSRK ' / Reference frame of spectral coordinates SSYSOBSB= 'TOPOCENT' / Reference frame of observation VELOSYSB= 0.0 / [m/s] Bary-topo velocity towards the source SSYSSRCB= 'LSRK ' / Reference frame of source redshift ZSOURCEB= 0.0000 / Redshift of the source COMMENT CRPIX2B = 1 CDELT2B = 1.0 CTYPE2B = 'RA ' CRVAL2B = 83.81042 / [deg] (05h35m14.5s) CUNIT2B = 'deg ' COMMENT CRPIX3B = 1 CDELT3B = 1.0 CTYPE3B = 'DEC ' CRVAL3B = -5.375222 / [deg] (-05:22:30.8) CUNIT3B = 'deg ' COMMENT RADESYSB= 'FK5 ' / FK5 (IAU 1984) equatorial coordinates EQUINOXB= 2000.0 / Equinox J2000.0 COMMENT CRPIX4B = 1 CDELT4B = 1.0 CTYPE4B = 'STOKES ' CRVAL4B = 1 / Stokes I (total intensity) COMMENT HISTORY fimgcreate 1.0b at 2009-04-22T04:28:18 DATE = '2009-04-22T04:28:18' / file creation date (YYYY-MM-DDThh:mm:ss UT) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/sub-segfault.hdr0000644000175100001710000000370200000000000021717 0ustar00vstsdockerWCSAXES = 4 / Number of coordinate axes CRPIX1 = 8193 / Pixel coordinate of reference point CRPIX2 = 8193 / Pixel coordinate of reference point CRPIX3 = 1 / Pixel coordinate of reference point CRPIX4 = 1 / Pixel coordinate of reference point CDELT1 = -0.000555555555556 / [deg] Coordinate increment at reference point CDELT2 = 0.000555555555556 / [deg] Coordinate increment at reference point CDELT3 = 1 / Coordinate increment at reference point CDELT4 = 33333332 / [Hz] Coordinate increment at reference point CUNIT1 = 'deg' / Units of coordinate increment and value CUNIT2 = 'deg' / Units of coordinate increment and value CUNIT4 = 'Hz' / Units of coordinate increment and value CTYPE1 = 'RA---SIN' / Right ascension, orthographic/synthesis project CTYPE2 = 'DEC--SIN' / Declination, orthographic/synthesis projection CTYPE3 = 'STOKES' / Coordinate type code CTYPE4 = 'FREQ' / Frequency (linear) CRVAL1 = 35.3324166667 / [deg] Coordinate value at reference point CRVAL2 = -4.51685555556 / [deg] Coordinate value at reference point CRVAL3 = 1 / Coordinate value at reference point CRVAL4 = 322601561.836 / [Hz] Coordinate value at reference point LONPOLE = 180 / [deg] Native longitude of celestial pole LATPOLE = -4.51685555556 / [deg] Native latitude of celestial pole RESTFRQ = 306000000 / [Hz] Line rest frequency RESTWAV = 0 / [Hz] Line rest wavelength EQUINOX = 2000 / [yr] Equinox of equatorial coordinates SPECSYS = 'TOPOCENT' / Reference frame of spectral coordinates MJD-OBS = 55794 / [d] MJD of observation matching DATE-OBS DATE-OBS= '2011-08-21T00:00:00.000000' / ISO-8601 observation date matching MJD-././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/tab-time-last-axis.fits0000644000175100001710000003410000000000000023107 0ustar00vstsdockerSIMPLE = T / conforms to FITS standard BITPIX = -64 / array data type NAXIS = 3 / number of array dimensions NAXIS1 = 1 NAXIS2 = 1 NAXIS3 = 1 EXTEND = T WCSAXES = 3 / Number of coordinate axes WCSNAME = 'TEST 3D FRAME WITH TIME' CRPIX1 = 32.5 / Pixel coordinate of reference point CRPIX2 = 16.5 / Pixel coordinate of reference point PC1_1 = 5.9533058133115E-06 / Coordinate transformation matrix element PC1_2 = 1.2909957973842E-05 / Coordinate transformation matrix element PC2_1 = -1.2644950182756E-05 / Coordinate transformation matrix element PC2_2 = 5.0222580309289E-06 / Coordinate transformation matrix element CDELT1 = 1.0 / [deg] Coordinate increment at reference point CDELT2 = 1.0 / [deg] Coordinate increment at reference point CUNIT1 = 'deg' / Units of coordinate increment and value CUNIT2 = 'deg' / Units of coordinate increment and value CTYPE1 = 'RA---TAN' / Right ascension, gnomonic projection CTYPE2 = 'DEC--TAN' / Declination, gnomonic projection CRVAL1 = 5.6305039831305 / [deg] Coordinate value at reference point CRVAL2 = -72.050216354325 / [deg] Coordinate value at reference point LONPOLE = 180.0 / [deg] Native longitude of celestial pole LATPOLE = -72.050216354325 / [deg] Native latitude of celestial pole MJDREF = 0.0 / [d] MJD of fiducial time RADESYS = 'ICRS' / Equatorial coordinate system SIPMXERR= 6.55090871151496E-19 / Max diff from GWCS (equiv pix). CTYPE3 = 'TIME-TAB' CUNIT3 = 's ' PS3_0 = 'WCS-TABLE' PV3_1 = 1 PS3_1 = 'coordinates' PV3_3 = 1 CRVAL3 = 1 CRPIX3 = 1.0 PC3_3 = 1.0 CDELT3 = 1.0 COMMENT FITS WCS created by approximating a gWCS END ?đXTENSION= 'BINTABLE' / binary table extension BITPIX = 8 / array data type NAXIS = 2 / number of array dimensions NAXIS1 = 1024 / length of dimension 1 NAXIS2 = 1 / length of dimension 2 PCOUNT = 0 / number of group parameters GCOUNT = 1 / number of groups TFIELDS = 1 / number of table fields TTYPE1 = 'coordinates' TFORM1 = '128D ' TDIM1 = '(1,128) ' EXTNAME = 'WCS-TABLE' / extension name EXTVER = 1 / extension value END ?đ@@@@@@@ @"@$@&@(@*@,@.@0@1@2@3@4@5@6@7@8@9@:@;@<@=@>@?@@@@€@A@A€@B@B€@C@C€@D@D€@E@E€@F@F€@G@G€@H@H€@I@I€@J@J€@K@K€@L@L€@M@M€@N@N€@O@O€@P@P@@P€@PĀ@Q@Q@@Q€@QĀ@R@R@@R€@RĀ@S@S@@S€@SĀ@T@T@@T€@TĀ@U@U@@U€@UĀ@V@V@@V€@VĀ@W@W@@W€@WĀ@X@X@@X€@XĀ@Y@Y@@Y€@YĀ@Z@Z@@Z€@ZĀ@[@[@@[€@[Ā@\@\@@\€@\Ā@]@]@@]€@]Ā@^@^@@^€@^Ā@_@_@@_€@_Ā././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/too_many_pv.hdr0000644000175100001710000010340000000000000021644 0ustar00vstsdockerSIMPLE = T / Fits standard BITPIX = 16 / FOUR-BYTE SINGLE PRECISION FLOATING POINT NAXIS = 2 / STANDARD FITS FORMAT NAXIS1 = 2048 / STANDARD FITS FORMAT NAXIS2 = 4096 / STANDARD FITS FORMAT ORIGIN = 'Palomar Transient Factory' / Origin of these image data CREATOR = 'Infrared Processing and Analysis Center' / Creator of this FITS file DATE = '2011-08-01T15:14:04' / File creation date (YYYY-MM-DDThh:mm:ss UT) / PTF DMASK BIT DEFINITIONS BIT00 = 0 / AIRCRAFT/SATELLITE TRACK BIT01 = 1 / OBJECT (detected by SExtractor) BIT02 = 2 / HIGH DARK-CURRENT BIT03 = 3 / RESERVED FOR FUTURE USE BIT04 = 4 / NOISY BIT05 = 5 / GHOST BIT06 = 6 / CCD BLEED BIT07 = 7 / RAD HIT BIT08 = 8 / SATURATED BIT09 = 9 / DEAD/BAD BIT10 = 10 / NAN (not a number) BIT11 = 11 / DIRTY (10-sigma below coarse local median) BIT12 = 12 / HALO BIT13 = 13 / RESERVED FOR FUTURE USE BIT14 = 14 / RESERVED FOR FUTURE USE BIT15 = 15 / RESERVED FOR FUTURE USE / DATA FLOW PMASKPTH= '/ptf/pos/archive/fallbackcal/pmasks/' / Pixel-mask pathname PMASKFIL= 'bpm_2009060s_c07.v2.fits' / Pixel-mask filename UDMPROC = 'updatemask' / Update bit in dmask UDMVERSN= 1. / Version of updatemask program UDMOP = 0 / Operation type UDMMBT = 4 / Mask bit template UDMIFIL = 'bpm_2009060s_c07.v1.fits' / Program updatemask input file UDMOFIL = 'bpm_2009060s_c07.v2.fits' / Program updatemask output file MCVERSN = 1. / Version of ptfMaskCombine program PTFPPROC= 'ptfPostProc' / Flags proc NaNs, CCD-bleeds and rad hits PPRVERSN= 3. / Version of ptfPostProc program / COPY OF IMAGE HEADER BELOW ORIGIN = 'Palomar Transient Factory' / Origin of these image data CREATOR = 'Infrared Processing and Analysis Center' / Creator of this FITS file TELESCOP= 'P48 ' / Name of telescope INSTRUME= 'PTF/MOSAIC' / Instrument name OBSERVER= 'KulkarniPTF' / Observer name and project CCDID = '7 ' / CCD number (0..11) DATE-OBS= '2009-06-25T08:41:23.970' / UTC shutter time YYYY-MM-DDTHH:MM:SS.SSS DATE = '2011-07-30T15:04:59' / File creation date (YYYY-MM-DDThh:mm:ss UT) REFERENC= 'http://www.astro.caltech.edu/ptf' / URL of PTF website / PROPOSAL INFORMATION PTFPRPI = 'Kulkarni' / PTF Project PI PTFPID = '20000 ' / Project type: 00000-49999 OBJECT = 'PTF_survey' / Fields object PTFFIELD= '2899 ' / PTF unique field ID PTFFLAG = '1 ' / 1 = PTF; 0 = non-PTF category / TIME AND EXPOSURE INFORMATION FILTER = 'R ' / Filter name FILTERID= '2 ' / Filter ID FILTERSL= '2 ' / Filter changer slot position EXPTIME = 60. / [s] Requested exposure time AEXPTIME= 60. / actual exposure time (sec) UTC-OBS = '2009-06-25T08:41:23.970' / UTC time shutter open YYYY-MM-DDTHH:MM:SS.OBSJD = 2455007.86207 / [day] Julian day corresponds to UTC-OBS OBSMJD = 55007.36207 / MJD corresponds to UTC-OBS (day) OBSLST = '19:08:26.70' / Mean LST corresponds to UTC-OBS 'HH:MM:SS.S' HOURANG = '-3:09:09.78' / Mean HA (sHH:MM:SS.S) based on LMST at UTC-OBS HJD = 2455007.86457 / [day] Heliocentric Julian Day OBSTYPE = 'object ' / Image type (dark,science,bias,focus) IMGTYP = 'object ' / Image type (dark,science,bias,focus) / MOON AND SUN MOONRA = 131.676395 / [deg] Moon J2000.0 R.A. MOONDEC = 16.207046 / [deg] Moon J2000.0 Dec. MOONILLF= 0.095389 / [frac] Moon illuminated fraction MOONPHAS= 144.0201 / [deg] Moon phase angle MOONESB = -0. / Moon excess in sky brightness V-band MOONALT = -35.16959 / [deg] Moon altitude SUNAZ = 13.90467 / [deg] Sun azimuth SUNALT = -31.96011 / [deg] Sun altitude / PHOTOMETRY BUNIT = 'DN ' / Data number (analog-to-digital units or ADU) PHTCALEX= 1 / Was phot.-cal. module executed? PHTCALFL= 0 / Flag for image is photometric (0=N, 1=Y) PCALRMSE= 0.030059 / RMSE from (zeropoint, extinction) data fit IMAGEZPT= 22.43948 / Image magnitude zeropoint IZPORIG = 'CALTRANS' / Photometric-calibration origin ZPRULE = 'COMPUTE ' / Photometric-calibration method MAGZPT = 22.73683 / Magnitude zeropoint at airmass=1 EXTINCT = 0.17995 / Extinction APSFILT = 'r ' / SDSS filter used in abs phot cal APSCOL = 'r-i ' / SDSS color used in abs phot cal APRMS = 0.0554857 / RMS in mag of final abs phot cal APBSRMS = 0.03911367 / RMS in mag of final abs phot cal for bright staAPNSTDI1= 69501 / Number of standard stars in first iteration APNSTDIF= 64858 / Number of standard stars in final iteration APCHI2 = 325618.88012443 / Chi2 of final abs phot cal APDOF = 64858. / Dof of chi2 of final abs phot cal APMEDJD = 2455007.84500722 / Median JD used in abs phot cal APPN01 = 'ZeroPoint' / Name of parameter abs phot cal 01 APPAR01 = 22.81878918 / Value of parameter abs phot cal 01 APPARE01= 0.00198923 / Error of parameter abs phot cal 01 APPN02 = 'ColorTerm' / Name of parameter abs phot cal 02 APPAR02 = 0.20481246 / Value of parameter abs phot cal 02 APPARE02= 0.00278076 / Error of parameter abs phot cal 02 APPN03 = 'AirMassTerm' / Name of parameter abs phot cal 03 APPAR03 = -0.12104427 / Value of parameter abs phot cal 03 APPARE03= 0.0011621 / Error of parameter abs phot cal 03 APPN04 = 'AirMassColorTerm' / Name of parameter abs phot cal 04 APPAR04 = 0.00904321 / Value of parameter abs phot cal 04 APPARE04= 0.00176968 / Error of parameter abs phot cal 04 APPN05 = 'TimeTerm' / Name of parameter abs phot cal 05 APPAR05 = 0.03012546 / Value of parameter abs phot cal 05 APPARE05= 0.00459951 / Error of parameter abs phot cal 05 APPN06 = 'Time2Term' / Name of parameter abs phot cal 06 APPAR06 = 1.27460327 / Value of parameter abs phot cal 06 APPARE06= 0.07646497 / Error of parameter abs phot cal 06 APPN07 = 'XTerm ' / Name of parameter abs phot cal 07 APPAR07 = 0.00768843 / Value of parameter abs phot cal 07 APPARE07= 0.00083226 / Error of parameter abs phot cal 07 APPN08 = 'YTerm ' / Name of parameter abs phot cal 08 APPAR08 = 0.06680527 / Value of parameter abs phot cal 08 APPARE08= 0.00203667 / Error of parameter abs phot cal 08 APPN09 = 'Y2Term ' / Name of parameter abs phot cal 09 APPAR09 = 0.31486016 / Value of parameter abs phot cal 09 APPARE09= 0.00318862 / Error of parameter abs phot cal 09 APPN10 = 'Y3Term ' / Name of parameter abs phot cal 10 APPAR10 = 0.69934253 / Value of parameter abs phot cal 10 APPARE10= 0.01257477 / Error of parameter abs phot cal 10 APPN11 = 'XYTerm ' / Name of parameter abs phot cal 11 APPAR11 = -0.04590337 / Value of parameter abs phot cal 11 APPARE11= 0.00286729 / Error of parameter abs phot cal 11 / ASTROMETRY CRVAL1 = 333.443801401309 / [deg] RA of reference point CRVAL2 = 3.08905544069643 / [deg] DEC of reference point CRPIX1 = 1175.019 / [pix] Image reference point CRPIX2 = 945.8826 / [pix] Image reference point CTYPE1 = 'RA---TAN-SIP' / TAN (gnomic) projection + SIP distortions CTYPE2 = 'DEC--TAN-SIP' / TAN (gnomic) projection + SIP distortions CUNIT1 = 'deg ' / Image axis-1 celestial-coordinate units CUNIT2 = 'deg ' / Image axis-2 celestial-coordinate units CRTYPE1 = 'deg ' / Data units of CRVAL1 CRTYPE2 = 'deg ' / Data units of CRVAL2 CD1_1 = 0.000281094342514378 / Transformation matrix CD1_2 = -5.00875320999652E-09 CD2_1 = -2.08930602680508E-07 CD2_2 = -0.000281284158795544 OBJRA = '22:17:08.571' / Requested field J2000.0 Ra. OBJDEC = '+03:22:30.00' / Requested field J2000.0 Dec. OBJRAD = 334.285714 / [deg] Requested field RA (J2000.0) OBJDECD = 3.375 / [deg] Requested field Dec (J2000.0) PIXSCALE= 1.01 / [arcsec/pix] Pixel scale WCSAXES = 2 EQUINOX = 2000. / [yr] Equatorial coordinates definition LONPOLE = 180. LATPOLE = 0. / IMAGE QUALITY SEEING = 2.04 / [pix] Seeing FWHM PEAKDIST= 0.396793397122491 / [pix] Mean dist brightest pixel-centroid pixel ELLIP = 0.063 / Mean image ellipticity A/B ELLIPPA = 48.65 / [deg] Mean image ellipticity PA FBIAS = 1060.884 / [DN] Floating bias of the image SATURVAL= 17000. / [DN] Saturation value of the CCD array FWHMSEX = 2.45 / [arcsec] SExtractor SEEING estimate MDSKYMAG= 20.53072 / [mag/s-arcsec^2] Median sky obsolete MSMAPCZP= 20.70926 / [mag/s-arcsec^2] Median sky abs. phot. cal. LIMITMAG= 20.92587 / [mag/s-arcsec^2] Limiting magnitude obsolete LMGAPCZP= 21.10442 / [mag/s-arcsec^2] Limiting mag. abs. phot. cal. MEDFWHM = 2.931446 / [arcsecond] Median FWHM MEDELONG= 1.132416 / [dimensionless] Median elongation STDELONG= 0.3298569 / [dimensionless] Std. dev. of elongation MEDTHETA= -42.28234 / [deg] Atan(median sin(theta)/median cos(theta))STDTHETA= 66.21399 / [deg] Atan(stddev sin(theta)/stddev cos(theta))MEDDLMAG= 33.85928 / [mag/s-arcsec^2] Median (MU_MAX-MAG_AUTO) STDDLMAG= 0.4367887 / [mag/s-arcsec^2] Stddev of (MU_MAX-MAG_AUTO) / OBSERVATORY AND TCS OCS_TIME= '2009-06-25T08:41:23.978' / UTC Date for OCS calc time-dep params OPERMODE= 'OCS ' / Mode of operation: OCS | Manual | N/A SOFTVER = '1.1.1.1 ' / Softwere version (TCS.Camera.OCS.Sched) OCS_VER = '1 ' / OCS software version and date TCS_VER = '1 ' / TCS software version and date SCH_VER = '1 ' / OCS-Scheduler software version and date MAT_VER = '7.7.0.471' / Matlab version HDR_VER = '1 ' / Header version TRIGGER = 'N/A ' / trigger ID for TOO, e.g. VOEVENT-Nr TCSMODE = 'Star ' / TCS fundamental mode TCSSMODE= 'Active ' / TCS fundamental submode TCSFMODE= 'Pos ' / TCS focus mode TCSFSMOD= 'On-Target' / TCS focus submode TCSDMODE= 'Stop ' / TCS dome mode TCSDSMOD= 'N/A ' / TCS dome submode TCSWMODE= 'Slave ' / TCS windscreen mode TCSWSMOD= 'N/A ' / TCS windscreen submode OBSLAT = 33.3574 / [deg] Telescope geodetic latitude in WGS84 OBSLON = 116.8599 / [deg] Telescope geodetic longitude in WGS84 OBSALT = 1703.2 / [m] Telescope geodetic altitude in WGS84 DEFOCUS = 0. / [mm] Focus position - nominal focus FOCUSPOS= 1.3851 / [mm] Exposures focusPos DOMESTAT= 'open ' / Dome status at begining of exposure TRACKRA = 23.7 / [arcsec/hr] Track speed RA rel to sidereal TRACKDEC= -11.2 / [arcsec/hr] Track speed Dec rel to sidereal AZIMUTH = 113.8682 / [deg] Telescope Azimuth ALTITUDE= 36.81047 / [deg] Telescope altitude AIRMASS = 1.666232 / Telescope airmass TELRA = 334.402 / [deg] Telescope ap equinox of date RA TELDEC = 3.4225 / [deg] Telescope ap equinox of date Dec TELHA = 312.7096 / [deg] Telescope ap equinox of date HA DOMEAZ = 112.8563 / [deg] Dome azimuth WINDSCAL= 10.466 / [deg] Wind screen altitude WINDDIR = 2.2 / [deg] Azimuth of wind direction WINDSPED= 14.6328 / Wind speed (km/hour) OUTTEMP = 20.94444 / [C] Outside temperature OUTRELHU= 0.09 / [frac] Outside relative humidity OUTDEWPT= -12.94444 / [C] Outside dew point / INSTRUMENT TELEMETRY PANID = '_p48s ' / PAN identification DHSID = '_p48s ' / DHS identification ROISTATE= 'ROI ' / ROI State (FULL | ROI) CCDSEC = '[1:2048,1:4096]' / CCD section CCDSIZE = '[1:2048,1:4096]' / CCD size DATASEC = '[1:2048,1:4096]' / Data section DETSEC = '[1:2048,1:4096]' / Detector section ROISEC = '[1:2048,1:4096]' / ROI section FPA = 'P48MOSAIC' / Focal plan array CCDNAME = 'W94C2 ' / Detector mfg serial number CHECKSUM= 'O3aBP1ZBO1aBO1YB' / HDU checksum updated 2010-03-15T13:06:37 DATASUM = '395763289' / Data unit checksum updated 2010-03-15T13:06:37 DHEINF = 'SDSU, Gen-III' / Controller info DHEFIRM = '/usr/src/dsp/tim_m.lod' / DSP software CAM_VER = '20090615.1.3.100000' / Camera server date.rev.cfitsio LV_VER = '8.5 ' / LabVIEW software version PCI_VER = '2.0c ' / Astropci software version DETID = 'PTF/MOSAIC' / Detector ID AUTHOR = 'PTF/OCS/TCS/Camera' / Source for header information DATAMIN = 0. / Minimum value for array ROISTATE= 'ROI ' / ROI State (FULL | ROI) LEDBLUE = 'OFF ' / 470nm LED state (ON | OFF) LEDRED = 'OFF ' / 660nm LED state (ON | OFF) LEDNIR = 'OFF ' / 880nm LED state (ON | OFF) CCD9TEMP= 175.003 / [K] 0x0 servo temp sensor on CCD09 HSTEMP = 148.207 / [K] 0x1 heat spreader temp DHE0TEMP= 295.951 / [K] 0x2 detector head electronics temp, master DHE1TEMP= 298.162 / [K] 0x3 detector head electronics temp, slave DEWWTEMP= 284.71 / [K] 0x4 dewar wall temp HEADTEMP= 138.414 / [K] 0x5 cryo cooler cold head temp CCD5TEMP= 174.91 / [K] 0x6 temp sensor on CCD05 CCD11TEM= 176.061 / [K] 0x7 temp sensor on CCD11 CCD0TEMP= 169.515 / [K] 0x8 temp sensor on CCD00 RSTEMP = 232.61 / [K] 0x9 temp sensor on radiation shield DEWPRESS= 0.82 / [milli-torr] Dewar pressure DETHEAT = 38. / [%] Detector focal plane heater power NAMPSXY = '6 2 ' / Number of amplifiers in x y CCDSUM = '1 1 ' / [pix] Binning in x and y MODELFOC= 'N/A ' / MODELFOC CHECKSUM= '6aLZ8ZKZ6aKZ6YKZ' / HDU checksum updated 2010-03-15T13:06:37 DATASUM = ' 0' / Data unit checksum (2010-03-15T13:06:37) GAIN = 1.7 / [e-/D.N.] Gain of detector. READNOI = 5.1 / [e-] Read noise of detector. DARKCUR = 0.1 / [e-/s] Dark current of detector / SCAMP DISTORTION KEYWORDS RADECSYS= 'ICRS ' / Astrometric system PV1_0 = 0. / Projection distortion parameter PV1_1 = 1. / Projection distortion parameter PV1_2 = 0. / Projection distortion parameter PV1_4 = 0.000811808026654439 / Projection distortion parameter PV1_5 = 0.000610424561546246 / Projection distortion parameter PV1_6 = 0.000247550637436069 / Projection distortion parameter PV1_7 = 0.000103962986153903 / Projection distortion parameter PV1_8 = -0.000463678684598807 / Projection distortion parameter PV1_9 = -0.000431244263972048 / Projection distortion parameter PV1_10 = -0.000152691163850316 / Projection distortion parameter PV1_12 = -0.00204628855915067 / Projection distortion parameter PV1_13 = -0.00173071932398225 / Projection distortion parameter PV1_14 = 0.000212015319199711 / Projection distortion parameter PV1_15 = -0.000489268678679085 / Projection distortion parameter PV1_16 = -0.000182891514774611 / Projection distortion parameter PV2_0 = 0. / Projection distortion parameter PV2_1 = 1. / Projection distortion parameter PV2_2 = 0. / Projection distortion parameter PV2_4 = 0.000273521447624334 / Projection distortion parameter PV2_5 = 0.000876139200581004 / Projection distortion parameter PV2_6 = -0.000122736852992318 / Projection distortion parameter PV2_7 = -0.00115870481394187 / Projection distortion parameter PV2_8 = 0.000744209714565589 / Projection distortion parameter PV2_9 = -0.00031431316953523 / Projection distortion parameter PV2_10 = -0.00025720525696749 / Projection distortion parameter PV2_12 = -0.00074859772103692 / Projection distortion parameter PV2_13 = 0.000838107200656415 / Projection distortion parameter PV2_14 = -0.00012633881376049 / Projection distortion parameter PV2_15 = -0.0020312867769692 / Projection distortion parameter PV2_16 = 0.00524608854745148 / Projection distortion parameter FGROUPNO= 1 / SCAMP field group label ASTIRMS1= 0. / Astrom. dispersion RMS (intern., high S/N) ASTIRMS2= 0. / Astrom. dispersion RMS (intern., high S/N) ASTRRMS1= 3.620458E-05 / Astrom. dispersion RMS (ref., high S/N) ASTRRMS2= 3.332156E-05 / Astrom. dispersion RMS (ref., high S/N) ASTINST = 1 / SCAMP astrometric instrument label FLXSCALE= 0. / SCAMP relative flux scale MAGZEROP= 0. / SCAMP zero-point PHOTIRMS= 0. / mag dispersion RMS (internal, high S/N) RA_RMS = 0.1655724 / [arcsec] RMS of SCAMP fit from 2MASS matching DEC_RMS = 0.1891921 / [arcsec] RMS of SCAMP fit from 2MASS matching ASTROMN = 384 / Number of stars in SCAMP astrometric solution SCAMPPTH= '/ptf/pos/archive/fallbackcal/scamp/7/' / SCAMP catalog path SCAMPFIL= 'PTF_201006174759_c_e_uca3_t112521_u001916251_f02_p002899_c07.fits' / SIP DISTORTION KEYWORDS A_ORDER = 4 / Distortion order for A A_0_2 = 6.96807813586153E-08 / Projection distortion parameter A_0_3 = 1.20881759870351E-11 / Projection distortion parameter A_0_4 = -4.07297345125509E-15 / Projection distortion parameter A_1_1 = -1.71602989085006E-07 / Projection distortion parameter A_1_2 = -3.40958003336147E-11 / Projection distortion parameter A_1_3 = 1.08769435952671E-14 / Projection distortion parameter A_2_0 = 2.28067760155696E-07 / Projection distortion parameter A_2_1 = 3.6610309234789E-11 / Projection distortion parameter A_2_2 = 4.73755078335384E-15 / Projection distortion parameter A_3_0 = 8.24210855193549E-12 / Projection distortion parameter A_3_1 = 3.84753767306115E-14 / Projection distortion parameter A_4_0 = -4.54223812412034E-14 / Projection distortion parameter A_DMAX = 1.53122472683886 / Projection distortion parameter B_ORDER = 4 / Distortion order for B B_0_2 = -7.69933957449607E-08 / Projection distortion parameter B_0_3 = -9.16855566272424E-11 / Projection distortion parameter B_0_4 = 1.66630509620112E-14 / Projection distortion parameter B_1_1 = 2.46289708854316E-07 / Projection distortion parameter B_1_2 = -5.90207917198792E-11 / Projection distortion parameter B_1_3 = 1.86811615261732E-14 / Projection distortion parameter B_2_0 = 3.44908367419592E-08 / Projection distortion parameter B_2_1 = -2.49509936365959E-11 / Projection distortion parameter B_2_2 = 2.84841315780067E-15 / Projection distortion parameter B_3_0 = 2.02845080441181E-11 / Projection distortion parameter B_3_1 = -4.51317603382652E-14 / Projection distortion parameter B_4_0 = -1.16438849571175E-13 / Projection distortion parameter B_DMAX = 2.89468553502114 / Projection distortion parameter AP_ORDER= 4 / Distortion order for AP AP_0_1 = -2.3927681685928E-08 / Projection distortion parameter AP_0_2 = -6.97379868441328E-08 / Projection distortion parameter AP_0_3 = -1.21069584606865E-11 / Projection distortion parameter AP_0_4 = 4.07524721573973E-15 / Projection distortion parameter AP_1_0 = 5.65239128994064E-08 / Projection distortion parameter AP_1_1 = 1.71734217296344E-07 / Projection distortion parameter AP_1_2 = 3.41724875038451E-11 / Projection distortion parameter AP_1_3 = -1.08775499102067E-14 / Projection distortion parameter AP_2_0 = -2.28068482487158E-07 / Projection distortion parameter AP_2_1 = -3.66548961802381E-11 / Projection distortion parameter AP_2_2 = -4.75858241735224E-15 / Projection distortion parameter AP_3_0 = -8.24781966878619E-12 / Projection distortion parameter AP_3_1 = -3.85281201904104E-14 / Projection distortion parameter AP_4_0 = 4.54275049666924E-14 / Projection distortion parameter BP_ORDER= 4 / Distortion order for BP BP_0_1 = -1.50638746640517E-07 / Projection distortion parameter BP_0_2 = 7.70565767927487E-08 / Projection distortion parameter BP_0_3 = 9.18374546897802E-11 / Projection distortion parameter BP_0_4 = -1.66839467627906E-14 / Projection distortion parameter BP_1_0 = -4.87195269294628E-08 / Projection distortion parameter BP_1_1 = -2.46371690411844E-07 / Projection distortion parameter BP_1_2 = 5.9111535979953E-11 / Projection distortion parameter BP_1_3 = -1.87729776729012E-14 / Projection distortion parameter BP_2_0 = -3.46046151217313E-08 / Projection distortion parameter BP_2_1 = 2.51320825919019E-11 / Projection distortion parameter BP_2_2 = -2.85758325791527E-15 / Projection distortion parameter BP_3_0 = -2.04221364218494E-11 / Projection distortion parameter BP_3_1 = 4.51336286236569E-14 / Projection distortion parameter BP_4_0 = 1.16567578965612E-13 / Projection distortion parameter / DATA FLOW ORIGNAME= '/data/PTF_default_38068.fits' / Filename as written by the camera FILENAME= 'PTF200906253621_2_o_38068.fits' / Filename of delivered camera image PROCORIG= 'IPAC-PTF pipelines' / Processing origin PROCDATE= 'Tue Feb 21 03:34:46 2012' / Processing date/time (Pacific time) PTFVERSN= 5. / Version of PTFSCIENCEPIPELINE program PMASKPTH= '/ptf/pos/archive/fallbackcal/pmasks/' / Pathname of pixel mask PMASKFIL= 'bpm_2009060s_c07.v2.fits' / Filename of pixel mask SFLATPTH= '/ptf/pos/sbx1/2009/06/25/f2/c7/cal/p4/cId45986/' / Pathname of super SFLATFIL= 'PTF_200906250000_i_s_flat_t120000_u000045986_f02_p000000_c07.fits' SBIASPTH= '/ptf/pos/sbx1/2009/06/25/f2/c7/cal/p1/cId45922/' / Pathname of super SBIASFIL= 'PTF_200906250000_i_s_bias_t120000_u000045922_f00_p000000_c07.fits' DBNID = 121 / Database night ID DBEXPID = 22920 / Database exposure ID DBRID = 3663141 / Database raw-image ID DBPID = 12052003 / Database processed-image ID DBFID = 2 / Database filter ID DBPIID = 1 / Database P.I. ID DBPRID = 3 / Database project ID DBFIELD = 22920 / Database field ID DBSVID = 50 / Database software-version ID DBCVID = 56 / Database config-data-file ID END ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/tpvonly.hdr0000644000175100001710000006250000000000000021032 0ustar00vstsdockerSIMPLE = T / Fits standard BITPIX = -32 / FOUR-BYTE SINGLE PRECISION FLOATING POINT NAXIS = 2 / STANDARD FITS FORMAT NAXIS1 = 2048 / STANDARD FITS FORMAT NAXIS2 = 4096 / STANDARD FITS FORMAT ORIGIN = 'Palomar Transient Factory' / Origin of these image data CREATOR = 'Infrared Processing and Analysis Center' / Creator of this FITS file TELESCOP= 'P48 ' / Name of telescope INSTRUME= 'PTF/MOSAIC' / Instrument name OBSERVER= 'KulkarniPTF' / Observer name and project CCDID = '5 ' / CCD number (0..11) DATE-OBS= '2014-07-31T04:49:58.673' / UTC shutter time YYYY-MM-DDTHH:MM:SS.SSS DATE = '2014-07-31T19:20:32' / File creation date (YYYY-MM-DDThh:mm:ss UT) REFERENC= 'http://www.astro.caltech.edu/ptf' / URL of PTF website / PROPOSAL INFORMATION PTFPRPI = 'Kulkarni' / PTF Project PI PTFPID = '52002 ' / Project type: 00000-49999 OBJECT = 'Galactic_Plane' / Fields object PTFFIELD= '1549 ' / PTF unique field ID PTFFLAG = '1 ' / 1 = PTF; 0 = non-PTF category / TIME AND EXPOSURE INFORMATION FILTER = 'R ' / Filter name FILTERID= '2 ' / Filter ID FILTERSL= '1 ' / Filter changer slot position EXPTIME = 60. / [s] Requested exposure time AEXPTIME= 60. / actual exposure time (sec) UTC-OBS = '2014-07-31T04:49:58.673' / UTC time shutter open YYYY-MM-DDTHH:MM:SS.OBSJD = 2456869.70137 / [day] Julian day corresponds to UTC-OBS OBSMJD = 56869.20137 / MJD corresponds to UTC-OBS (day) OBSLST = '17:37:29.36' / Mean LST corresponds to UTC-OBS 'HH:MM:SS.S' HOURANG = '-0:42:20.82' / Mean HA (sHH:MM:SS.S) based on LMST at UTC-OBS HJD = 2456869.70618 / [day] Heliocentric Julian Day OBSTYPE = 'object ' / Image type (dark,science,bias,focus) IMGTYP = 'object ' / Image type (dark,science,bias,focus) / MOON AND SUN MOONRA = 173.116974 / [deg] Moon J2000.0 R.A. MOONDEC = -0.404999 / [deg] Moon J2000.0 Dec. MOONILLF= 0.155837 / [frac] Moon illuminated fraction MOONPHAS= 133.4978 / [deg] Moon phase angle MOONESB = -0. / Moon excess in sky brightness V-band MOONALT = -1.271649 / [deg] Moon altitude SUNAZ = 312.4731 / [deg] Sun azimuth SUNALT = -22.25475 / [deg] Sun altitude / PHOTOMETRY BUNIT = 'DN ' / Data number (analog-to-digital units or ADU) PHTCALEX= 1 / Was phot.-cal. module executed? PHTCALFL= 0 / Flag for image is photometric (0=N, 1=Y) PCALRMSE= 0.171135 / RMSE from (zeropoint, extinction) data fit IMAGEZPT= 21.22791 / Image magnitude zeropoint IZPORIG = 'CALTRANS' / Photometric-calibration origin ZPRULE = 'COMPUTE ' / Photometric-calibration method MAGZPT = 23.55079 / Magnitude zeropoint at airmass=1 EXTINCT = 1.163014 / Extinction APSFILT = 'r ' / SDSS filter used in abs phot cal APSCOL = 'r-i ' / SDSS color used in abs phot cal APRMS = 0.06677995 / RMS in mag of final abs phot cal APBSRMS = 0.05033556 / RMS in mag of final abs phot cal for bright staAPNSTDI1= 308233 / Number of standard stars in first iteration APNSTDIF= 274569 / Number of standard stars in final iteration APCHI2 = 1861590.34570444 / Chi2 of final abs phot cal APDOF = 274569. / Dof of chi2 of final abs phot cal APMEDJD = 2456869.84882722 / Median JD used in abs phot cal APPN01 = 'ZeroPoint' / Name of parameter abs phot cal 01 APPAR01 = 23.67499643 / Value of parameter abs phot cal 01 APPARE01= 0.00324545 / Error of parameter abs phot cal 01 APPN02 = 'ColorTerm' / Name of parameter abs phot cal 02 APPAR02 = 0.44908632 / Value of parameter abs phot cal 02 APPARE02= 0.00423336 / Error of parameter abs phot cal 02 APPN03 = 'AirMassTerm' / Name of parameter abs phot cal 03 APPAR03 = -0.18342823 / Value of parameter abs phot cal 03 APPARE03= 0.00288243 / Error of parameter abs phot cal 03 APPN04 = 'AirMassColorTerm' / Name of parameter abs phot cal 04 APPAR04 = -0.14534473 / Value of parameter abs phot cal 04 APPARE04= 0.00381178 / Error of parameter abs phot cal 04 APPN05 = 'TimeTerm' / Name of parameter abs phot cal 05 APPAR05 = 0.42239539 / Value of parameter abs phot cal 05 APPARE05= 0.0019644 / Error of parameter abs phot cal 05 APPN06 = 'Time2Term' / Name of parameter abs phot cal 06 APPAR06 = 0.16770061 / Value of parameter abs phot cal 06 APPARE06= 0.01549427 / Error of parameter abs phot cal 06 APPN07 = 'XTerm ' / Name of parameter abs phot cal 07 APPAR07 = 0.02152189 / Value of parameter abs phot cal 07 APPARE07= 0.00047932 / Error of parameter abs phot cal 07 APPN08 = 'YTerm ' / Name of parameter abs phot cal 08 APPAR08 = 0.02739724 / Value of parameter abs phot cal 08 APPARE08= 0.00117248 / Error of parameter abs phot cal 08 APPN09 = 'Y2Term ' / Name of parameter abs phot cal 09 APPAR09 = 0.01522565 / Value of parameter abs phot cal 09 APPARE09= 0.0018581 / Error of parameter abs phot cal 09 APPN10 = 'Y3Term ' / Name of parameter abs phot cal 10 APPAR10 = -0.23390906 / Value of parameter abs phot cal 10 APPARE10= 0.00723349 / Error of parameter abs phot cal 10 APPN11 = 'XYTerm ' / Name of parameter abs phot cal 11 APPAR11 = -0.00677493 / Value of parameter abs phot cal 11 APPARE11= 0.00169149 / Error of parameter abs phot cal 11 / ASTROMETRY CRVAL1 = 274.806945708898 / [deg] RA of reference point CRVAL2 = -25.9746476963393 / [deg] DEC of reference point CRPIX1 = -3925.16 / [pix] Image reference point CRPIX2 = 4360.23 / [pix] Image reference point CTYPE1 = 'RA---TPV' / TAN (gnomic) projection + SIP distortions CTYPE2 = 'DEC--TPV' / TAN (gnomic) projection + SIP distortions CUNIT1 = 'deg ' / Image axis-1 celestial-coordinate units CUNIT2 = 'deg ' / Image axis-2 celestial-coordinate units CRTYPE1 = 'deg ' / Data units of CRVAL1 CRTYPE2 = 'deg ' / Data units of CRVAL2 CD1_1 = 0.000286102658601581 / Transformation matrix CD1_2 = -6.28816628331811E-07 CD2_1 = -5.77207018114522E-06 CD2_2 = -0.000281525256171892 OBJRA = '18:18:56.842' / Requested field J2000.0 Ra. OBJDEC = '-25:52:30.00' / Requested field J2000.0 Dec. OBJRAD = 274.73684 / [deg] Requested field RA (J2000.0) OBJDECD = -25.875 / [deg] Requested field Dec (J2000.0) PIXSCALE= 1.01 / [arcsec/pix] Pixel scale EQUINOX = 2000. / [yr] Equatorial coordinates definition / IMAGE QUALITY SEEING = 2.95 / [pix] Seeing FWHM PEAKDIST= 0.481336680505667 / [pix] Mean dist brightest pixel-centroid pixel ELLIP = 0.313 / Mean image ellipticity A/B ELLIPPA = 48.58 / [deg] Mean image ellipticity PA FBIAS = 785.8855 / [DN] Floating bias of the image SATURVAL= 50000. / [DN] Saturation value of the CCD array FWHMSEX = 2.45 / [arcsec] SExtractor SEEING estimate MSMAPCZP= 19.20814 / [mag/s-arcsec^2] Median sky abs. phot. cal. LMGAPCZP= 20.68008 / [mag/s-arcsec^2] Limiting mag. abs. phot. cal. MEDFWHM = 3.417924 / [arcsecond] Median FWHM MEDELONG= 1.406608 / [dimensionless] Median elongation STDELONG= 0.592749 / [dimensionless] Std. dev. of elongation MEDTHETA= -31.22347 / [deg] Atan(median sin(theta)/median cos(theta))STDTHETA= 65.37225 / [deg] Atan(stddev sin(theta)/stddev cos(theta))MEDDLMAG= 2.444709 / [mag/s-arcsec^2] Median (MU_MAX-MAG_AUTO) STDDLMAG= 0.4154117 / [mag/s-arcsec^2] Stddev of (MU_MAX-MAG_AUTO) / OBSERVATORY AND TCS OCS_TIME= '2014-07-31T04:49:58.613' / UTC Date for OCS calc time-dep params OPERMODE= 'OCS ' / Mode of operation: OCS | Manual | N/A SOFTVER = '1.1.1.1 ' / Softwere version (TCS.Camera.OCS.Sched) OCS_VER = '1 ' / OCS software version and date TCS_VER = '1 ' / TCS software version and date SCH_VER = '1 ' / OCS-Scheduler software version and date MAT_VER = '7.7.0.471' / Matlab version HDR_VER = '1 ' / Header version TRIGGER = 'N/A ' / trigger ID for TOO, e.g. VOEVENT-Nr TCSMODE = 'Star ' / TCS fundamental mode TCSSMODE= 'Active ' / TCS fundamental submode TCSFMODE= 'Pos ' / TCS focus mode TCSFSMOD= 'On-Target' / TCS focus submode TCSDMODE= 'Stop ' / TCS dome mode TCSDSMOD= 'N/A ' / TCS dome submode TCSWMODE= 'Slave ' / TCS windscreen mode TCSWSMOD= 'N/A ' / TCS windscreen submode OBSLAT = 33.3574 / [deg] Telescope geodetic latitude in WGS84 OBSLON = -116.8599 / [deg] Telescope geodetic longitude in WGS84 OBSALT = 1703.2 / [m] Telescope geodetic altitude in WGS84 DEFOCUS = 0. / [mm] Focus position - nominal focus FOCUSPOS= 1.3655 / [mm] Exposures focusPos DOMESTAT= 'open ' / Dome status at begining of exposure TRACKRA = 20.4 / [arcsec/hr] Track speed RA rel to sidereal TRACKDEC= -3.9 / [arcsec/hr] Track speed Dec rel to sidereal AZIMUTH = 169.2328 / [deg] Telescope Azimuth ALTITUDE= 29.95342 / [deg] Telescope altitude AIRMASS = 1.997293 / Telescope airmass TELRA = 274.9591 / [deg] Telescope ap equinox of date RA TELDEC = -25.8684 / [deg] Telescope ap equinox of date Dec TELHA = 349.4138 / [deg] Telescope ap equinox of date HA DOMEAZ = 169.4477 / [deg] Dome azimuth WINDSCAL= 12.8995 / [deg] Wind screen altitude WINDDIR = 1.3 / [deg] Azimuth of wind direction WINDSPED= 14.472 / Wind speed (km/hour) OUTTEMP = 22.16667 / [C] Outside temperature OUTRELHU= 0.513 / [frac] Outside relative humidity OUTDEWPT= 11.61111 / [C] Outside dew point / INSTRUMENT TELEMETRY PANID = '_p48m ' / PAN identification DHSID = '_p48m ' / DHS identification CCDSEC = '[1:2048,1:4096]' / CCD section CCDSIZE = '[1:2048,1:4096]' / CCD size DATASEC = '[1:2048,1:4096]' / Data section DETSEC = '[1:2048,1:4096]' / Detector section ROISEC = '[1:2048,1:4096]' / ROI section FPA = 'P48MOSAIC' / Focal plan array CCDNAME = 'W53C2 ' / Detector mfg serial number CHECKSUM= 'fGoXhEmXfEmXfEmX' / Image header unit checksum DATASUM = '2019013917' / Image data unit checksum DHEINF = 'SDSU, Gen-III' / Controller info DHEFIRM = '/usr/src/dsp/20090618/tim_m.lod' / DSP software CAM_VER = '20090615.1.3.100000' / Camera server date.rev.cfitsio LV_VER = '8.5 ' / LabVIEW software version PCI_VER = '2.0c ' / Astropci software version DETID = 'PTF/MOSAIC' / Detector ID AUTHOR = 'PTF/OCS/TCS/Camera' / Source for header information DATAMIN = 0. / Minimum value for array ROISTATE= 'ROI ' / ROI State (FULL | ROI) LEDBLUE = 'OFF ' / 470nm LED state (ON | OFF) LEDRED = 'OFF ' / 660nm LED state (ON | OFF) LEDNIR = 'OFF ' / 880nm LED state (ON | OFF) CCD9TEMP= 174.988 / [K] 0x0 servo temp sensor on CCD09 HSTEMP = 152.111 / [K] 0x1 heat spreader temp DHE0TEMP= 301.098 / [K] 0x2 detector head electronics temp, master DHE1TEMP= 303.178 / [K] 0x3 detector head electronics temp, slave DEWWTEMP= 287.05 / [K] 0x4 dewar wall temp HEADTEMP= 142.103 / [K] 0x5 cryo cooler cold head temp CCD5TEMP= 175.963 / [K] 0x6 temp sensor on CCD05 CCD11TEM= 177.375 / [K] 0x7 temp sensor on CCD11 CCD0TEMP= 170.213 / [K] 0x8 temp sensor on CCD00 RSTEMP = 238.936 / [K] 0x9 temp sensor on radiation shield DEWPRESS= 40. / [milli-torr] Dewar pressure DETHEAT = 1.6 / [%] Detector focal plane heater power NAMPSXY = '6 2 ' / Number of amplifiers in x y CCDSUM = '1 1 ' / [pix] Binning in x and y MODELFOC= 'N/A ' / MODELFOC EXPCKSUM= 'fGoXhEmXfEmXfEmX' / Primary header unit checksum EXPDTSUM= '2019013917' / Primary data unit checksum GAIN = 1.7 / [e-/D.N.] Gain of detector. READNOI = 3.4 / [e-] Read noise of detector. DARKCUR = 0.1 / [e-/s] Dark current of detector / SCAMP DISTORTION KEYWORDS RADECSYS= 'ICRS ' / Astrometric system PV1_0 = 0. / Projection distortion parameter PV1_1 = 1. / Projection distortion parameter PV1_2 = 0. / Projection distortion parameter PV1_4 = -0.016169561788921 / Projection distortion parameter PV1_5 = -0.0051747493874632 / Projection distortion parameter PV1_6 = -0.000238504358056776 / Projection distortion parameter PV1_7 = 0.00629760478963159 / Projection distortion parameter PV1_8 = 0.00397207946734115 / Projection distortion parameter PV1_9 = -0.000677296206451849 / Projection distortion parameter PV1_10 = 0.000503546797066621 / Projection distortion parameter PV1_12 = -0.000973553429744082 / Projection distortion parameter PV1_13 = -0.00102312736844768 / Projection distortion parameter PV1_14 = 0.000253623568347818 / Projection distortion parameter PV1_15 = -0.000200211924758127 / Projection distortion parameter PV1_16 = -6.21626607050974E-05 / Projection distortion parameter PV2_0 = 0. / Projection distortion parameter PV2_1 = 1. / Projection distortion parameter PV2_2 = 0. / Projection distortion parameter PV2_4 = -0.000743645656922906 / Projection distortion parameter PV2_5 = 0.000184250025396486 / Projection distortion parameter PV2_6 = 0.0219715919766664 / Projection distortion parameter PV2_7 = -7.54497752637404E-05 / Projection distortion parameter PV2_8 = 0.000649357185110191 / Projection distortion parameter PV2_9 = -0.00081219646536117 / Projection distortion parameter PV2_10 = -0.0105098433615178 / Projection distortion parameter PV2_12 = -2.1755521894303E-05 / Projection distortion parameter PV2_13 = -7.90103717680049E-05 / Projection distortion parameter PV2_14 = -0.000155711703067327 / Projection distortion parameter PV2_15 = 0.000169335617180111 / Projection distortion parameter PV2_16 = 0.00186540574051853 / Projection distortion parameter FGROUPNO= 1 / SCAMP field group label ASTIRMS1= 0. / Astrom. dispersion RMS (intern., high S/N) ASTIRMS2= 0. / Astrom. dispersion RMS (intern., high S/N) ASTRRMS1= 2.362887E-05 / Astrom. dispersion RMS (ref., high S/N) ASTRRMS2= 2.36868E-05 / Astrom. dispersion RMS (ref., high S/N) ASTINST = 1 / SCAMP astrometric instrument label FLXSCALE= 0. / SCAMP relative flux scale MAGZEROP= 0. / SCAMP zero-point PHOTIRMS= 0. / mag dispersion RMS (internal, high S/N) RA_RMS = 0.1040474 / [arcsec] RMS of SCAMP fit from 2MASS matching DEC_RMS = 0.1017731 / [arcsec] RMS of SCAMP fit from 2MASS matching ASTROMN = 2636 / Number of stars in SCAMP astrometric solution SCAMPPTH= 'NotAvailable' / SCAMP catalog path SCAMPFIL= 'NotAvailable' / SCAMP catalog file / SIP DISTORTION KEYWORDS / DATA FLOW ORIGNAME= '/data/PTF_default_37806.fits' / Filename as written by the camera FILENAME= 'PTF201407312014_2_o_37806.fits' / Filename of delivered camera image PROCORIG= 'IPAC-PTF pipelines' / Processing origin PROCDATE= 'Fri Sep 26 14:52:55 2014' / Processing date/time (Pacific time) PTFVERSN= 5. / Version of PTFSCIENCEPIPELINE program PMASKPTH= '/ptf/pos/archive/fallbackcal/pmasks/' / Pathname of pixel mask PMASKFIL= '70sOn35s_pixmask_chip5.trimmed.v4.fits' / Filename of pixel mask SFLATPTH= '/ptf/pos/sbx2/2014/07/31/f2/c5/cal/p4/cId112103/' / Pathname of superSFLATFIL= 'PTF_201407310000_i_s_flat_t120000_u000112103_f02_p000000_c05.fits' SBIASPTH= '/ptf/pos/sbx2/2014/07/31/f2/c5/cal/p1/cId112095/' / Pathname of superSBIASFIL= 'PTF_201407310000_i_s_bias_t120000_u000112095_f00_p000000_c05.fits' DBNID = 1938 / Database night ID DBEXPID = 446050 / Database exposure ID DBRID = 6985566 / Database raw-image ID DBPID = 21528832 / Database processed-image ID DBFID = 2 / Database filter ID DBPIID = 1 / Database P.I. ID DBPRID = 31 / Database project ID DBFIELD = 446050 / Database field ID DBSVID = 54 / Database software-version ID DBCVID = 60 / Database config-data-file ID INFOBITS= 0 / Database infobits (2^2 and 2^3 excluded) END ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/unit.hdr0000644000175100001710000000550000000000000020273 0ustar00vstsdockerSIMPLE = T / conforms to FITS standard BITPIX = -64 / array data type NAXIS = 3 / number of array dimensions NAXIS1 = 400 NAXIS2 = 300 NAXIS3 = 251 EQUINOX = 2000.0 CTYPE1 = 'GLON-CAR' CTYPE2 = 'GLAT-CAR' CTYPE3 = 'VRAD' SPECSYS = 'LSRK' CUNIT3 = 'km/s ' BUNIT = 'K ' CRVAL1 = 49.209553 CRVAL2 = 0.0 CRVAL3 = 50.0 CRPIX1 = 200.0 CRPIX2 = 288.0 CRPIX3 = 125.0 CDELT1 = -0.00333333333333333 CDELT2 = 0.003333333333333333 CDELT3 = 0.5 RESTFREQ= 1000. TELESCOP= 'Arecibo' END ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/validate.5.0.txt0000644000175100001710000000113500000000000021450 0ustar00vstsdockerHDU 1: WCS key ' ': - RADECSYS= 'ICRS ' / Astrometric system the RADECSYS keyword is deprecated, use RADESYSa. - The WCS transformation has more axes (2) than the image it is associated with (0) - Removed redundant SCAMP distortion parameters because SIP parameters are also present HDU 2: WCS key ' ': - The WCS transformation has more axes (3) than the image it is associated with (0) - 'celfix' made the change 'In CUNIT3 : Mismatched units type 'length': have 'Hz', want 'm''. - 'unitfix' made the change 'Changed units: 'HZ ' -> 'Hz''. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/validate.5.13.txt0000644000175100001710000000112700000000000021535 0ustar00vstsdockerHDU 1: WCS key ' ': - RADECSYS= 'ICRS ' / Astrometric system the RADECSYS keyword is deprecated, use RADESYSa. - The WCS transformation has more axes (2) than the image it is associated with (0) - Removed redundant SCAMP distortion parameters because SIP parameters are also present HDU 2: WCS key ' ': - The WCS transformation has more axes (3) than the image it is associated with (0) - 'celfix' made the change 'In CUNIT3 : Mismatched units type 'length': have 'Hz', want 'm''. - 'unitfix' made the change 'Changed units: 'HZ' -> 'Hz''. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/validate.6.txt0000644000175100001710000000113600000000000021314 0ustar00vstsdockerHDU 1: WCS key ' ': - RADECSYS= 'ICRS ' / Astrometric system the RADECSYS keyword is deprecated, use RADESYSa. - The WCS transformation has more axes (2) than the image it is associated with (0) - Removed redundant SCAMP distortion parameters because SIP parameters are also present HDU 2: WCS key ' ': - The WCS transformation has more axes (3) than the image it is associated with (0) - 'unitfix' made the change 'Changed units: 'HZ' -> 'Hz'. - 'celfix' made the change 'In CUNIT3 : Mismatched units type 'length': have 'Hz', want 'm''. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/validate.7.4.txt0000644000175100001710000000133300000000000021456 0ustar00vstsdockerHDU 1: WCS key ' ': - RADECSYS= 'ICRS ' / Astrometric system the RADECSYS keyword is deprecated, use RADESYSa. - The WCS transformation has more axes (2) than the image it is associated with (0) - Removed redundant SCAMP distortion parameters because SIP parameters are also present - 'datfix' made the change 'Set MJD-OBS to 55007.362083 from DATE- OBS'. HDU 2: WCS key ' ': - The WCS transformation has more axes (3) than the image it is associated with (0) - 'datfix' made the change 'Success'. - 'unitfix' made the change 'Changed units: 'HZ' -> 'Hz'. - 'celfix' made the change 'In CUNIT3 : Mismatched units type 'length': have 'Hz', want 'm''. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/validate.7.6.txt0000644000175100001710000000126000000000000021457 0ustar00vstsdockerHDU 1: WCS key ' ': - RADECSYS= 'ICRS ' / Astrometric system the RADECSYS keyword is deprecated, use RADESYSa. - The WCS transformation has more axes (2) than the image it is associated with (0) - Removed redundant SCAMP distortion parameters because SIP parameters are also present - 'datfix' made the change 'Set MJD-OBS to 55007.362083 from DATE- OBS'. HDU 2: WCS key ' ': - The WCS transformation has more axes (3) than the image it is associated with (0) - 'unitfix' made the change 'Changed units: 'HZ' -> 'Hz'. - 'celfix' made the change 'In CUNIT3 : Mismatched units type 'length': have 'Hz', want 'm''.././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/validate.fits0000644000175100001710000011660000000000000021301 0ustar00vstsdockerSIMPLE = T / conforms to FITS standard BITPIX = 8 / array data type NAXIS = 0 / number of array dimensions EXTEND = T END XTENSION= 'IMAGE ' / Image extension BITPIX = 8 / array data type NAXIS = 0 / number of array dimensions PCOUNT = 0 / number of parameters GCOUNT = 1 / number of groups ORIGIN = 'Palomar Transient Factory' / Origin of these image data CREATOR = 'Infrared Processing and Analysis Center' / Creator of this FITS file DATE = '2011-08-01T15:14:04' / File creation date (YYYY-MM-DDThh:mm:ss UT) / PTF DMASK BIT DEFINITIONS BIT00 = 0 / AIRCRAFT/SATELLITE TRACK BIT01 = 1 / OBJECT (detected by SExtractor) BIT02 = 2 / HIGH DARK-CURRENT BIT03 = 3 / RESERVED FOR FUTURE USE BIT04 = 4 / NOISY BIT05 = 5 / GHOST BIT06 = 6 / CCD BLEED BIT07 = 7 / RAD HIT BIT08 = 8 / SATURATED BIT09 = 9 / DEAD/BAD BIT10 = 10 / NAN (not a number) BIT11 = 11 / DIRTY (10-sigma below coarse local median) BIT12 = 12 / HALO BIT13 = 13 / RESERVED FOR FUTURE USE BIT14 = 14 / RESERVED FOR FUTURE USE BIT15 = 15 / RESERVED FOR FUTURE USE / DATA FLOW PMASKPTH= '/ptf/pos/archive/fallbackcal/pmasks/' / Pixel-mask pathname PMASKFIL= 'bpm_2009060s_c07.v2.fits' / Pixel-mask filename UDMPROC = 'updatemask' / Update bit in dmask UDMVERSN= 1. / Version of updatemask program UDMOP = 0 / Operation type UDMMBT = 4 / Mask bit template UDMIFIL = 'bpm_2009060s_c07.v1.fits' / Program updatemask input file UDMOFIL = 'bpm_2009060s_c07.v2.fits' / Program updatemask output file MCVERSN = 1. / Version of ptfMaskCombine program PTFPPROC= 'ptfPostProc' / Flags proc NaNs, CCD-bleeds and rad hits PPRVERSN= 3. / Version of ptfPostProc program / COPY OF IMAGE HEADER BELOW ORIGIN = 'Palomar Transient Factory' / Origin of these image data CREATOR = 'Infrared Processing and Analysis Center' / Creator of this FITS file TELESCOP= 'P48 ' / Name of telescope INSTRUME= 'PTF/MOSAIC' / Instrument name OBSERVER= 'KulkarniPTF' / Observer name and project CCDID = '7 ' / CCD number (0..11) DATE-OBS= '2009-06-25T08:41:23.970' / UTC shutter time YYYY-MM-DDTHH:MM:SS.SSS DATE = '2011-07-30T15:04:59' / File creation date (YYYY-MM-DDThh:mm:ss UT) REFERENC= 'http://www.astro.caltech.edu/ptf' / URL of PTF website / PROPOSAL INFORMATION PTFPRPI = 'Kulkarni' / PTF Project PI PTFPID = '20000 ' / Project type: 00000-49999 OBJECT = 'PTF_survey' / Fields object PTFFIELD= '2899 ' / PTF unique field ID PTFFLAG = '1 ' / 1 = PTF; 0 = non-PTF category / TIME AND EXPOSURE INFORMATION FILTER = 'R ' / Filter name FILTERID= '2 ' / Filter ID FILTERSL= '2 ' / Filter changer slot position EXPTIME = 60. / [s] Requested exposure time AEXPTIME= 60. / actual exposure time (sec) UTC-OBS = '2009-06-25T08:41:23.970' / UTC time shutter open YYYY-MM-DDTHH:MM:SS.OBSJD = 2455007.86207 / [day] Julian day corresponds to UTC-OBS OBSMJD = 55007.36207 / MJD corresponds to UTC-OBS (day) OBSLST = '19:08:26.70' / Mean LST corresponds to UTC-OBS 'HH:MM:SS.S' HOURANG = '-3:09:09.78' / Mean HA (sHH:MM:SS.S) based on LMST at UTC-OBS HJD = 2455007.86457 / [day] Heliocentric Julian Day OBSTYPE = 'object ' / Image type (dark,science,bias,focus) IMGTYP = 'object ' / Image type (dark,science,bias,focus) / MOON AND SUN MOONRA = 131.676395 / [deg] Moon J2000.0 R.A. MOONDEC = 16.207046 / [deg] Moon J2000.0 Dec. MOONILLF= 0.095389 / [frac] Moon illuminated fraction MOONPHAS= 144.0201 / [deg] Moon phase angle MOONESB = -0. / Moon excess in sky brightness V-band MOONALT = -35.16959 / [deg] Moon altitude SUNAZ = 13.90467 / [deg] Sun azimuth SUNALT = -31.96011 / [deg] Sun altitude / PHOTOMETRY BUNIT = 'DN ' / Data number (analog-to-digital units or ADU) PHTCALEX= 1 / Was phot.-cal. module executed? PHTCALFL= 0 / Flag for image is photometric (0=N, 1=Y) PCALRMSE= 0.030059 / RMSE from (zeropoint, extinction) data fit IMAGEZPT= 22.43948 / Image magnitude zeropoint IZPORIG = 'CALTRANS' / Photometric-calibration origin ZPRULE = 'COMPUTE ' / Photometric-calibration method MAGZPT = 22.73683 / Magnitude zeropoint at airmass=1 EXTINCT = 0.17995 / Extinction APSFILT = 'r ' / SDSS filter used in abs phot cal APSCOL = 'r-i ' / SDSS color used in abs phot cal APRMS = 0.0554857 / RMS in mag of final abs phot cal APBSRMS = 0.03911367 / RMS in mag of final abs phot cal for bright staAPNSTDI1= 69501 / Number of standard stars in first iteration APNSTDIF= 64858 / Number of standard stars in final iteration APCHI2 = 325618.88012443 / Chi2 of final abs phot cal APDOF = 64858. / Dof of chi2 of final abs phot cal APMEDJD = 2455007.84500722 / Median JD used in abs phot cal APPN01 = 'ZeroPoint' / Name of parameter abs phot cal 01 APPAR01 = 22.81878918 / Value of parameter abs phot cal 01 APPARE01= 0.00198923 / Error of parameter abs phot cal 01 APPN02 = 'ColorTerm' / Name of parameter abs phot cal 02 APPAR02 = 0.20481246 / Value of parameter abs phot cal 02 APPARE02= 0.00278076 / Error of parameter abs phot cal 02 APPN03 = 'AirMassTerm' / Name of parameter abs phot cal 03 APPAR03 = -0.12104427 / Value of parameter abs phot cal 03 APPARE03= 0.0011621 / Error of parameter abs phot cal 03 APPN04 = 'AirMassColorTerm' / Name of parameter abs phot cal 04 APPAR04 = 0.00904321 / Value of parameter abs phot cal 04 APPARE04= 0.00176968 / Error of parameter abs phot cal 04 APPN05 = 'TimeTerm' / Name of parameter abs phot cal 05 APPAR05 = 0.03012546 / Value of parameter abs phot cal 05 APPARE05= 0.00459951 / Error of parameter abs phot cal 05 APPN06 = 'Time2Term' / Name of parameter abs phot cal 06 APPAR06 = 1.27460327 / Value of parameter abs phot cal 06 APPARE06= 0.07646497 / Error of parameter abs phot cal 06 APPN07 = 'XTerm ' / Name of parameter abs phot cal 07 APPAR07 = 0.00768843 / Value of parameter abs phot cal 07 APPARE07= 0.00083226 / Error of parameter abs phot cal 07 APPN08 = 'YTerm ' / Name of parameter abs phot cal 08 APPAR08 = 0.06680527 / Value of parameter abs phot cal 08 APPARE08= 0.00203667 / Error of parameter abs phot cal 08 APPN09 = 'Y2Term ' / Name of parameter abs phot cal 09 APPAR09 = 0.31486016 / Value of parameter abs phot cal 09 APPARE09= 0.00318862 / Error of parameter abs phot cal 09 APPN10 = 'Y3Term ' / Name of parameter abs phot cal 10 APPAR10 = 0.69934253 / Value of parameter abs phot cal 10 APPARE10= 0.01257477 / Error of parameter abs phot cal 10 APPN11 = 'XYTerm ' / Name of parameter abs phot cal 11 APPAR11 = -0.04590337 / Value of parameter abs phot cal 11 APPARE11= 0.00286729 / Error of parameter abs phot cal 11 / ASTROMETRY CRVAL1 = 333.443801401309 / [deg] RA of reference point CRVAL2 = 3.08905544069643 / [deg] DEC of reference point CRPIX1 = 1175.019 / [pix] Image reference point CRPIX2 = 945.8826 / [pix] Image reference point CTYPE1 = 'RA---TAN-SIP' / TAN (gnomic) projection + SIP distortions CTYPE2 = 'DEC--TAN-SIP' / TAN (gnomic) projection + SIP distortions CUNIT1 = 'deg ' / Image axis-1 celestial-coordinate units CUNIT2 = 'deg ' / Image axis-2 celestial-coordinate units CRTYPE1 = 'deg ' / Data units of CRVAL1 CRTYPE2 = 'deg ' / Data units of CRVAL2 CD1_1 = 0.000281094342514378 / Transformation matrix CD1_2 = -5.00875320999652E-09 CD2_1 = -2.08930602680508E-07 CD2_2 = -0.000281284158795544 OBJRA = '22:17:08.571' / Requested field J2000.0 Ra. OBJDEC = '+03:22:30.00' / Requested field J2000.0 Dec. OBJRAD = 334.285714 / [deg] Requested field RA (J2000.0) OBJDECD = 3.375 / [deg] Requested field Dec (J2000.0) PIXSCALE= 1.01 / [arcsec/pix] Pixel scale WCSAXES = 2 EQUINOX = 2000. / [yr] Equatorial coordinates definition LONPOLE = 180. LATPOLE = 0. / IMAGE QUALITY SEEING = 2.04 / [pix] Seeing FWHM PEAKDIST= 0.396793397122491 / [pix] Mean dist brightest pixel-centroid pixel ELLIP = 0.063 / Mean image ellipticity A/B ELLIPPA = 48.65 / [deg] Mean image ellipticity PA FBIAS = 1060.884 / [DN] Floating bias of the image SATURVAL= 17000. / [DN] Saturation value of the CCD array FWHMSEX = 2.45 / [arcsec] SExtractor SEEING estimate MDSKYMAG= 20.53072 / [mag/s-arcsec^2] Median sky obsolete MSMAPCZP= 20.70926 / [mag/s-arcsec^2] Median sky abs. phot. cal. LIMITMAG= 20.92587 / [mag/s-arcsec^2] Limiting magnitude obsolete LMGAPCZP= 21.10442 / [mag/s-arcsec^2] Limiting mag. abs. phot. cal. MEDFWHM = 2.931446 / [arcsecond] Median FWHM MEDELONG= 1.132416 / [dimensionless] Median elongation STDELONG= 0.3298569 / [dimensionless] Std. dev. of elongation MEDTHETA= -42.28234 / [deg] Atan(median sin(theta)/median cos(theta))STDTHETA= 66.21399 / [deg] Atan(stddev sin(theta)/stddev cos(theta))MEDDLMAG= 33.85928 / [mag/s-arcsec^2] Median (MU_MAX-MAG_AUTO) STDDLMAG= 0.4367887 / [mag/s-arcsec^2] Stddev of (MU_MAX-MAG_AUTO) / OBSERVATORY AND TCS OCS_TIME= '2009-06-25T08:41:23.978' / UTC Date for OCS calc time-dep params OPERMODE= 'OCS ' / Mode of operation: OCS | Manual | N/A SOFTVER = '1.1.1.1 ' / Softwere version (TCS.Camera.OCS.Sched) OCS_VER = '1 ' / OCS software version and date TCS_VER = '1 ' / TCS software version and date SCH_VER = '1 ' / OCS-Scheduler software version and date MAT_VER = '7.7.0.471' / Matlab version HDR_VER = '1 ' / Header version TRIGGER = 'N/A ' / trigger ID for TOO, e.g. VOEVENT-Nr TCSMODE = 'Star ' / TCS fundamental mode TCSSMODE= 'Active ' / TCS fundamental submode TCSFMODE= 'Pos ' / TCS focus mode TCSFSMOD= 'On-Target' / TCS focus submode TCSDMODE= 'Stop ' / TCS dome mode TCSDSMOD= 'N/A ' / TCS dome submode TCSWMODE= 'Slave ' / TCS windscreen mode TCSWSMOD= 'N/A ' / TCS windscreen submode OBSLAT = 33.3574 / [deg] Telescope geodetic latitude in WGS84 OBSLON = 116.8599 / [deg] Telescope geodetic longitude in WGS84 OBSALT = 1703.2 / [m] Telescope geodetic altitude in WGS84 DEFOCUS = 0. / [mm] Focus position - nominal focus FOCUSPOS= 1.3851 / [mm] Exposures focusPos DOMESTAT= 'open ' / Dome status at begining of exposure TRACKRA = 23.7 / [arcsec/hr] Track speed RA rel to sidereal TRACKDEC= -11.2 / [arcsec/hr] Track speed Dec rel to sidereal AZIMUTH = 113.8682 / [deg] Telescope Azimuth ALTITUDE= 36.81047 / [deg] Telescope altitude AIRMASS = 1.666232 / Telescope airmass TELRA = 334.402 / [deg] Telescope ap equinox of date RA TELDEC = 3.4225 / [deg] Telescope ap equinox of date Dec TELHA = 312.7096 / [deg] Telescope ap equinox of date HA DOMEAZ = 112.8563 / [deg] Dome azimuth WINDSCAL= 10.466 / [deg] Wind screen altitude WINDDIR = 2.2 / [deg] Azimuth of wind direction WINDSPED= 14.6328 / Wind speed (km/hour) OUTTEMP = 20.94444 / [C] Outside temperature OUTRELHU= 0.09 / [frac] Outside relative humidity OUTDEWPT= -12.94444 / [C] Outside dew point / INSTRUMENT TELEMETRY PANID = '_p48s ' / PAN identification DHSID = '_p48s ' / DHS identification ROISTATE= 'ROI ' / ROI State (FULL | ROI) CCDSEC = '[1:2048,1:4096]' / CCD section CCDSIZE = '[1:2048,1:4096]' / CCD size DATASEC = '[1:2048,1:4096]' / Data section DETSEC = '[1:2048,1:4096]' / Detector section ROISEC = '[1:2048,1:4096]' / ROI section FPA = 'P48MOSAIC' / Focal plan array CCDNAME = 'W94C2 ' / Detector mfg serial number CHECKSUM= 'O3aBP1ZBO1aBO1YB' / HDU checksum updated 2010-03-15T13:06:37 DATASUM = '395763289' / Data unit checksum updated 2010-03-15T13:06:37 DHEINF = 'SDSU, Gen-III' / Controller info DHEFIRM = '/usr/src/dsp/tim_m.lod' / DSP software CAM_VER = '20090615.1.3.100000' / Camera server date.rev.cfitsio LV_VER = '8.5 ' / LabVIEW software version PCI_VER = '2.0c ' / Astropci software version DETID = 'PTF/MOSAIC' / Detector ID AUTHOR = 'PTF/OCS/TCS/Camera' / Source for header information DATAMIN = 0. / Minimum value for array ROISTATE= 'ROI ' / ROI State (FULL | ROI) LEDBLUE = 'OFF ' / 470nm LED state (ON | OFF) LEDRED = 'OFF ' / 660nm LED state (ON | OFF) LEDNIR = 'OFF ' / 880nm LED state (ON | OFF) CCD9TEMP= 175.003 / [K] 0x0 servo temp sensor on CCD09 HSTEMP = 148.207 / [K] 0x1 heat spreader temp DHE0TEMP= 295.951 / [K] 0x2 detector head electronics temp, master DHE1TEMP= 298.162 / [K] 0x3 detector head electronics temp, slave DEWWTEMP= 284.71 / [K] 0x4 dewar wall temp HEADTEMP= 138.414 / [K] 0x5 cryo cooler cold head temp CCD5TEMP= 174.91 / [K] 0x6 temp sensor on CCD05 CCD11TEM= 176.061 / [K] 0x7 temp sensor on CCD11 CCD0TEMP= 169.515 / [K] 0x8 temp sensor on CCD00 RSTEMP = 232.61 / [K] 0x9 temp sensor on radiation shield DEWPRESS= 0.82 / [milli-torr] Dewar pressure DETHEAT = 38. / [%] Detector focal plane heater power NAMPSXY = '6 2 ' / Number of amplifiers in x y CCDSUM = '1 1 ' / [pix] Binning in x and y MODELFOC= 'N/A ' / MODELFOC CHECKSUM= '6aLZ8ZKZ6aKZ6YKZ' / HDU checksum updated 2010-03-15T13:06:37 DATASUM = ' 0' / Data unit checksum (2010-03-15T13:06:37) GAIN = 1.7 / [e-/D.N.] Gain of detector. READNOI = 5.1 / [e-] Read noise of detector. DARKCUR = 0.1 / [e-/s] Dark current of detector / SCAMP DISTORTION KEYWORDS RADECSYS= 'ICRS ' / Astrometric system PV1_0 = 0. / Projection distortion parameter PV1_1 = 1. / Projection distortion parameter PV1_2 = 0. / Projection distortion parameter PV1_4 = 0.000811808026654439 / Projection distortion parameter PV1_5 = 0.000610424561546246 / Projection distortion parameter PV1_6 = 0.000247550637436069 / Projection distortion parameter PV1_7 = 0.000103962986153903 / Projection distortion parameter PV1_8 = -0.000463678684598807 / Projection distortion parameter PV1_9 = -0.000431244263972048 / Projection distortion parameter PV1_10 = -0.000152691163850316 / Projection distortion parameter PV1_12 = -0.00204628855915067 / Projection distortion parameter PV1_13 = -0.00173071932398225 / Projection distortion parameter PV1_14 = 0.000212015319199711 / Projection distortion parameter PV1_15 = -0.000489268678679085 / Projection distortion parameter PV1_16 = -0.000182891514774611 / Projection distortion parameter PV2_0 = 0. / Projection distortion parameter PV2_1 = 1. / Projection distortion parameter PV2_2 = 0. / Projection distortion parameter PV2_4 = 0.000273521447624334 / Projection distortion parameter PV2_5 = 0.000876139200581004 / Projection distortion parameter PV2_6 = -0.000122736852992318 / Projection distortion parameter PV2_7 = -0.00115870481394187 / Projection distortion parameter PV2_8 = 0.000744209714565589 / Projection distortion parameter PV2_9 = -0.00031431316953523 / Projection distortion parameter PV2_10 = -0.00025720525696749 / Projection distortion parameter PV2_12 = -0.00074859772103692 / Projection distortion parameter PV2_13 = 0.000838107200656415 / Projection distortion parameter PV2_14 = -0.00012633881376049 / Projection distortion parameter PV2_15 = -0.0020312867769692 / Projection distortion parameter PV2_16 = 0.00524608854745148 / Projection distortion parameter FGROUPNO= 1 / SCAMP field group label ASTIRMS1= 0. / Astrom. dispersion RMS (intern., high S/N) ASTIRMS2= 0. / Astrom. dispersion RMS (intern., high S/N) ASTRRMS1= 3.620458E-05 / Astrom. dispersion RMS (ref., high S/N) ASTRRMS2= 3.332156E-05 / Astrom. dispersion RMS (ref., high S/N) ASTINST = 1 / SCAMP astrometric instrument label FLXSCALE= 0. / SCAMP relative flux scale MAGZEROP= 0. / SCAMP zero-point PHOTIRMS= 0. / mag dispersion RMS (internal, high S/N) RA_RMS = 0.1655724 / [arcsec] RMS of SCAMP fit from 2MASS matching DEC_RMS = 0.1891921 / [arcsec] RMS of SCAMP fit from 2MASS matching ASTROMN = 384 / Number of stars in SCAMP astrometric solution SCAMPPTH= '/ptf/pos/archive/fallbackcal/scamp/7/' / SCAMP catalog path SCAMPFIL= 'PTF_201006174759_c_e_uca3_t112521_u001916251_f02_p002899_c07.fits' / SIP DISTORTION KEYWORDS A_ORDER = 4 / Distortion order for A A_0_2 = 6.96807813586153E-08 / Projection distortion parameter A_0_3 = 1.20881759870351E-11 / Projection distortion parameter A_0_4 = -4.07297345125509E-15 / Projection distortion parameter A_1_1 = -1.71602989085006E-07 / Projection distortion parameter A_1_2 = -3.40958003336147E-11 / Projection distortion parameter A_1_3 = 1.08769435952671E-14 / Projection distortion parameter A_2_0 = 2.28067760155696E-07 / Projection distortion parameter A_2_1 = 3.6610309234789E-11 / Projection distortion parameter A_2_2 = 4.73755078335384E-15 / Projection distortion parameter A_3_0 = 8.24210855193549E-12 / Projection distortion parameter A_3_1 = 3.84753767306115E-14 / Projection distortion parameter A_4_0 = -4.54223812412034E-14 / Projection distortion parameter A_DMAX = 1.53122472683886 / Projection distortion parameter B_ORDER = 4 / Distortion order for B B_0_2 = -7.69933957449607E-08 / Projection distortion parameter B_0_3 = -9.16855566272424E-11 / Projection distortion parameter B_0_4 = 1.66630509620112E-14 / Projection distortion parameter B_1_1 = 2.46289708854316E-07 / Projection distortion parameter B_1_2 = -5.90207917198792E-11 / Projection distortion parameter B_1_3 = 1.86811615261732E-14 / Projection distortion parameter B_2_0 = 3.44908367419592E-08 / Projection distortion parameter B_2_1 = -2.49509936365959E-11 / Projection distortion parameter B_2_2 = 2.84841315780067E-15 / Projection distortion parameter B_3_0 = 2.02845080441181E-11 / Projection distortion parameter B_3_1 = -4.51317603382652E-14 / Projection distortion parameter B_4_0 = -1.16438849571175E-13 / Projection distortion parameter B_DMAX = 2.89468553502114 / Projection distortion parameter AP_ORDER= 4 / Distortion order for AP AP_0_1 = -2.3927681685928E-08 / Projection distortion parameter AP_0_2 = -6.97379868441328E-08 / Projection distortion parameter AP_0_3 = -1.21069584606865E-11 / Projection distortion parameter AP_0_4 = 4.07524721573973E-15 / Projection distortion parameter AP_1_0 = 5.65239128994064E-08 / Projection distortion parameter AP_1_1 = 1.71734217296344E-07 / Projection distortion parameter AP_1_2 = 3.41724875038451E-11 / Projection distortion parameter AP_1_3 = -1.08775499102067E-14 / Projection distortion parameter AP_2_0 = -2.28068482487158E-07 / Projection distortion parameter AP_2_1 = -3.66548961802381E-11 / Projection distortion parameter AP_2_2 = -4.75858241735224E-15 / Projection distortion parameter AP_3_0 = -8.24781966878619E-12 / Projection distortion parameter AP_3_1 = -3.85281201904104E-14 / Projection distortion parameter AP_4_0 = 4.54275049666924E-14 / Projection distortion parameter BP_ORDER= 4 / Distortion order for BP BP_0_1 = -1.50638746640517E-07 / Projection distortion parameter BP_0_2 = 7.70565767927487E-08 / Projection distortion parameter BP_0_3 = 9.18374546897802E-11 / Projection distortion parameter BP_0_4 = -1.66839467627906E-14 / Projection distortion parameter BP_1_0 = -4.87195269294628E-08 / Projection distortion parameter BP_1_1 = -2.46371690411844E-07 / Projection distortion parameter BP_1_2 = 5.9111535979953E-11 / Projection distortion parameter BP_1_3 = -1.87729776729012E-14 / Projection distortion parameter BP_2_0 = -3.46046151217313E-08 / Projection distortion parameter BP_2_1 = 2.51320825919019E-11 / Projection distortion parameter BP_2_2 = -2.85758325791527E-15 / Projection distortion parameter BP_3_0 = -2.04221364218494E-11 / Projection distortion parameter BP_3_1 = 4.51336286236569E-14 / Projection distortion parameter BP_4_0 = 1.16567578965612E-13 / Projection distortion parameter / DATA FLOW ORIGNAME= '/data/PTF_default_38068.fits' / Filename as written by the camera FILENAME= 'PTF200906253621_2_o_38068.fits' / Filename of delivered camera image PROCORIG= 'IPAC-PTF pipelines' / Processing origin PROCDATE= 'Tue Feb 21 03:34:46 2012' / Processing date/time (Pacific time) PTFVERSN= 5. / Version of PTFSCIENCEPIPELINE program PMASKPTH= '/ptf/pos/archive/fallbackcal/pmasks/' / Pathname of pixel mask PMASKFIL= 'bpm_2009060s_c07.v2.fits' / Filename of pixel mask SFLATPTH= '/ptf/pos/sbx1/2009/06/25/f2/c7/cal/p4/cId45986/' / Pathname of super SFLATFIL= 'PTF_200906250000_i_s_flat_t120000_u000045986_f02_p000000_c07.fits' SBIASPTH= '/ptf/pos/sbx1/2009/06/25/f2/c7/cal/p1/cId45922/' / Pathname of super SBIASFIL= 'PTF_200906250000_i_s_bias_t120000_u000045922_f00_p000000_c07.fits' DBNID = 121 / Database night ID DBEXPID = 22920 / Database exposure ID DBRID = 3663141 / Database raw-image ID DBPID = 12052003 / Database processed-image ID DBFID = 2 / Database filter ID DBPIID = 1 / Database P.I. ID DBPRID = 3 / Database project ID DBFIELD = 22920 / Database field ID DBSVID = 50 / Database software-version ID DBCVID = 56 / Database config-data-file ID END XTENSION= 'IMAGE ' / Image extension BITPIX = 8 / array data type NAXIS = 0 / number of array dimensions PCOUNT = 0 / number of parameters GCOUNT = 1 / number of groups CD1_2 = -3.72E-05 CD1_3 = 0 CD1_1 = -4.12E-05 CUNIT3 = 'HZ ' CUNIT2 = 'deg ' CTYPE1 = 'RA---TAN' CTYPE3 = 'AWAV ' CD2_1 = -3.72E-05 CTYPE2 = 'DEC--TAN' CD2_3 = 0 CD2_2 = 4.12E-05 CUNIT1 = 'deg ' CD3_1 = 0 CD3_2 = 0 CD3_3 = 0.2 END ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/validate.txt0000644000175100001710000000112300000000000021144 0ustar00vstsdockerHDU 1: WCS key ' ': - RADECSYS= 'ICRS ' / Astrometric system RADECSYS is non-standard, use RADESYSa. - The WCS transformation has more axes (2) than the image it is associated with (0) - Removed redundant SCAMP distortion parameters because SIP parameters are also present HDU 2: WCS key ' ': - The WCS transformation has more axes (3) than the image it is associated with (0) - 'celfix' made the change 'In CUNIT3 : Mismatched units type 'length': have 'Hz', want 'm''. - 'unitfix' made the change 'Changed units: 'HZ ' -> 'Hz''. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/data/zpn-hole.hdr0000644000175100001710000000550000000000000021050 0ustar00vstsdockerNAXIS = 2 NAXIS1 = 200 NAXIS2 = 200 CTYPE1 = 'RA---ZPN' CRPIX1 = 100 CDELT1 = -6.666666666667E-02 CRVAL1 = 0.000000000000E+00 CTYPE2 = 'DEC--ZPN' CRPIX2 = 100 CDELT2 = 6.666666666667E-02 CRVAL2 = -9.000000000000E+01 LONPOLE = 1.800000000000E+02 / Native longitude of celestial pole LATPOLE = -9.000000000000E+01 / Native latitude of celestial pole PV2_0 = 10.000000000000E-02 / Projection parameter 0 PV2_1 = 9.750000000000E-01 / Projection parameter 1 END ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/helper.py0000644000175100001710000000732100000000000017540 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import pytest import numpy as np from astropy import wcs from astropy.io import fits class SimModelTAB: def __init__(self, nx=150, ny=200, crpix=[1, 1], crval = [1, 1], cdelt = [1, 1], pc = {'PC1_1': 1, 'PC2_2': 1}): """ set essential parameters of the model (coord transformations) """ assert nx > 2 and ny > 1 # a limitation of this particular simulation self.nx = nx self.ny = ny self.crpix = crpix self.crval = crval self.cdelt = cdelt self.pc = pc def fwd_eval(self, xy): xb = 1 + self.nx // 3 px = np.array([1, xb, xb, self.nx + 1]) py = np.array([1, self.ny + 1]) xi = self.crval[0] + self.cdelt[0] * (px - self.crpix[0]) yi = self.crval[1] + self.cdelt[1] * (py - self.crpix[1]) cx = np.array([0.0, 0.26, 0.8, 1.0]) cy = np.array([-0.5, 0.5]) xy = np.atleast_2d(xy) x = xy[:, 0] y = xy[:, 1] mbad = (x < px[0]) | (y < py[0]) | (x > px[-1]) | (y > py[-1]) mgood = np.logical_not(mbad) i = 2 * (x > xb).astype(int) psix = self.crval[0] + self.cdelt[0] * (x - self.crpix[0]) psiy = self.crval[1] + self.cdelt[1] * (y - self.crpix[1]) cfx = (psix - xi[i]) / (xi[i + 1] - xi[i]) cfy = (psiy - yi[0]) / (yi[1] - yi[0]) ra = cx[i] + cfx * (cx[i + 1] - cx[i]) dec = cy[0] + cfy * (cy[1] - cy[0]) return np.dstack([ra, dec])[0] @property def hdulist(self): """ Simulates 2D data with a _spatial_ WCS that uses the ``-TAB`` algorithm with indexing. """ # coordinate array (some "arbitrary" numbers with a "jump" along x axis): x = np.array([[0.0, 0.26, 0.8, 1.0], [0.0, 0.26, 0.8, 1.0]]) y = np.array([[-0.5, -0.5, -0.5, -0.5], [0.5, 0.5, 0.5, 0.5]]) c = np.dstack([x, y]) # index arrays (skip PC matrix for simplicity - assume it is an # identity matrix): xb = 1 + self.nx // 3 px = np.array([1, xb, xb, self.nx + 1]) py = np.array([1, self.ny + 1]) xi = self.crval[0] + self.cdelt[0] * (px - self.crpix[0]) yi = self.crval[1] + self.cdelt[1] * (py - self.crpix[1]) # structured array (data) for binary table HDU: arr = np.array( [(c, xi, yi)], dtype=[ ('wavelength', np.float64, c.shape), ('xi', np.double, (xi.size,)), ('yi', np.double, (yi.size,)) ] ) # create binary table HDU: bt = fits.BinTableHDU(arr); bt.header['EXTNAME'] = 'WCS-TABLE' # create primary header: image_data = np.ones((self.ny, self.nx), dtype=np.float32) pu = fits.PrimaryHDU(image_data) pu.header['ctype1'] = 'RA---TAB' pu.header['ctype2'] = 'DEC--TAB' pu.header['naxis1'] = self.nx pu.header['naxis2'] = self.ny pu.header['PS1_0'] = 'WCS-TABLE' pu.header['PS2_0'] = 'WCS-TABLE' pu.header['PS1_1'] = 'wavelength' pu.header['PS2_1'] = 'wavelength' pu.header['PV1_3'] = 1 pu.header['PV2_3'] = 2 pu.header['CUNIT1'] = 'deg' pu.header['CUNIT2'] = 'deg' pu.header['CDELT1'] = self.cdelt[0] pu.header['CDELT2'] = self.cdelt[1] pu.header['CRPIX1'] = self.crpix[0] pu.header['CRPIX2'] = self.crpix[1] pu.header['CRVAL1'] = self.crval[0] pu.header['CRVAL2'] = self.crval[1] pu.header['PS1_2'] = 'xi' pu.header['PS2_2'] = 'yi' for k, v in self.pc.items(): pu.header[k] = v hdulist = fits.HDUList([pu, bt]) return hdulist ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/test_auxprm.py0000644000175100001710000001273400000000000020640 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst # Tests for the auxiliary parameters contained in wcsaux from numpy.testing import assert_allclose from astropy.io import fits from astropy.wcs import WCS STR_EXPECTED_EMPTY = """ rsun_ref: dsun_obs: crln_obs: hgln_obs: hglt_obs:""".lstrip() def test_empty(): w = WCS(naxis=1) assert w.wcs.aux.rsun_ref is None assert w.wcs.aux.dsun_obs is None assert w.wcs.aux.crln_obs is None assert w.wcs.aux.hgln_obs is None assert w.wcs.aux.hglt_obs is None assert str(w.wcs.aux) == STR_EXPECTED_EMPTY HEADER_SOLAR = fits.Header.fromstring(""" WCSAXES = 2 / Number of coordinate axes CRPIX1 = 64.5 / Pixel coordinate of reference point CRPIX2 = 64.5 / Pixel coordinate of reference point PC1_1 = 0.99999994260024 / Coordinate transformation matrix element PC1_2 = -0.00033882076120692 / Coordinate transformation matrix element PC2_1 = 0.00033882076120692 / Coordinate transformation matrix element PC2_2 = 0.99999994260024 / Coordinate transformation matrix element CDELT1 = 0.0053287911111111 / [deg] Coordinate increment at reference point CDELT2 = 0.0053287911111111 / [deg] Coordinate increment at reference point CUNIT1 = 'deg' / Units of coordinate increment and value CUNIT2 = 'deg' / Units of coordinate increment and value CTYPE1 = 'HPLN-TAN' / Coordinate type codegnomonic projection CTYPE2 = 'HPLT-TAN' / Coordinate type codegnomonic projection CRVAL1 = -0.0012589367249586 / [deg] Coordinate value at reference point CRVAL2 = 0.00079599300143911 / [deg] Coordinate value at reference point LONPOLE = 180.0 / [deg] Native longitude of celestial pole LATPOLE = 0.00079599300143911 / [deg] Native latitude of celestial pole DATE-OBS= '2011-02-15T00:00:00.34' / ISO-8601 time of observation MJD-OBS = 55607.000003935 / [d] MJD at start of observation RSUN_REF= 696000000.0 / [m] Solar radius DSUN_OBS= 147724815128.0 / [m] Distance from centre of Sun to observer CRLN_OBS= 22.814522 / [deg] Carrington heliographic lng of observer CRLT_OBS= -6.820544 / [deg] Heliographic latitude of observer HGLN_OBS= 8.431123 / [deg] Stonyhurst heliographic lng of observer HGLT_OBS= -6.820544 / [deg] Heliographic latitude of observer """.lstrip(), sep='\n') STR_EXPECTED_GET = """ rsun_ref: 696000000.000000 dsun_obs: 147724815128.000000 crln_obs: 22.814522 hgln_obs: 8.431123 hglt_obs: -6.820544""".lstrip() def test_solar_aux_get(): w = WCS(HEADER_SOLAR) assert_allclose(w.wcs.aux.rsun_ref, 696000000) assert_allclose(w.wcs.aux.dsun_obs, 147724815128) assert_allclose(w.wcs.aux.crln_obs, 22.814522) assert_allclose(w.wcs.aux.hgln_obs, 8.431123) assert_allclose(w.wcs.aux.hglt_obs, -6.820544) assert str(w.wcs.aux) == STR_EXPECTED_GET STR_EXPECTED_SET = """ rsun_ref: 698000000.000000 dsun_obs: 140000000000.000000 crln_obs: 10.000000 hgln_obs: 30.000000 hglt_obs: 40.000000""".lstrip() def test_solar_aux_set(): w = WCS(HEADER_SOLAR) w.wcs.aux.rsun_ref = 698000000 assert_allclose(w.wcs.aux.rsun_ref, 698000000) w.wcs.aux.dsun_obs = 140000000000 assert_allclose(w.wcs.aux.dsun_obs, 140000000000) w.wcs.aux.crln_obs = 10. assert_allclose(w.wcs.aux.crln_obs, 10.) w.wcs.aux.hgln_obs = 30. assert_allclose(w.wcs.aux.hgln_obs, 30.) w.wcs.aux.hglt_obs = 40. assert_allclose(w.wcs.aux.hglt_obs, 40.) assert str(w.wcs.aux) == STR_EXPECTED_SET header = w.to_header() assert_allclose(header['RSUN_REF'], 698000000) assert_allclose(header['DSUN_OBS'], 140000000000) assert_allclose(header['CRLN_OBS'], 10.) assert_allclose(header['HGLN_OBS'], 30.) assert_allclose(header['HGLT_OBS'], 40.) def test_set_aux_on_empty(): w = WCS(naxis=2) w.wcs.aux.rsun_ref = 698000000 assert_allclose(w.wcs.aux.rsun_ref, 698000000) w.wcs.aux.dsun_obs = 140000000000 assert_allclose(w.wcs.aux.dsun_obs, 140000000000) w.wcs.aux.crln_obs = 10. assert_allclose(w.wcs.aux.crln_obs, 10.) w.wcs.aux.hgln_obs = 30. assert_allclose(w.wcs.aux.hgln_obs, 30.) w.wcs.aux.hglt_obs = 40. assert_allclose(w.wcs.aux.hglt_obs, 40.) assert str(w.wcs.aux) == STR_EXPECTED_SET header = w.to_header() assert_allclose(header['RSUN_REF'], 698000000) assert_allclose(header['DSUN_OBS'], 140000000000) assert_allclose(header['CRLN_OBS'], 10.) assert_allclose(header['HGLN_OBS'], 30.) assert_allclose(header['HGLT_OBS'], 40.) def test_unset_aux(): w = WCS(HEADER_SOLAR) assert w.wcs.aux.rsun_ref is not None w.wcs.aux.rsun_ref = None assert w.wcs.aux.rsun_ref is None assert w.wcs.aux.dsun_obs is not None w.wcs.aux.dsun_obs = None assert w.wcs.aux.dsun_obs is None assert w.wcs.aux.crln_obs is not None w.wcs.aux.crln_obs = None assert w.wcs.aux.crln_obs is None assert w.wcs.aux.hgln_obs is not None w.wcs.aux.hgln_obs = None assert w.wcs.aux.hgln_obs is None assert w.wcs.aux.hglt_obs is not None w.wcs.aux.hglt_obs = None assert w.wcs.aux.hglt_obs is None assert str(w.wcs.aux) == 'rsun_ref:\ndsun_obs:\ncrln_obs:\nhgln_obs:\nhglt_obs:' header = w.to_header() assert 'RSUN_REF' not in header assert 'DSUN_OBS' not in header assert 'CRLN_OBS' not in header assert 'HGLN_OBS' not in header assert 'HGLT_OBS' not in header ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/test_pickle.py0000644000175100001710000001136000000000000020565 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import os import pickle import numpy as np import pytest from numpy.testing import assert_array_almost_equal from astropy.utils.data import (get_pkg_data_contents, get_pkg_data_fileobj, get_pkg_data_filename) from astropy.utils.exceptions import AstropyDeprecationWarning from astropy.utils.misc import NumpyRNGContext from astropy.io import fits from astropy.io.fits.verify import VerifyWarning from astropy import wcs from astropy.wcs.wcs import FITSFixedWarning def test_basic(): wcs1 = wcs.WCS() s = pickle.dumps(wcs1) pickle.loads(s) def test_dist(): with get_pkg_data_fileobj( os.path.join("data", "dist.fits"), encoding='binary') as test_file: hdulist = fits.open(test_file) # The use of ``AXISCORR`` for D2IM correction has been deprecated with pytest.warns(AstropyDeprecationWarning): wcs1 = wcs.WCS(hdulist[0].header, hdulist) assert wcs1.det2im2 is not None s = pickle.dumps(wcs1) wcs2 = pickle.loads(s) with NumpyRNGContext(123456789): x = np.random.rand(2 ** 16, wcs1.wcs.naxis) world1 = wcs1.all_pix2world(x, 1) world2 = wcs2.all_pix2world(x, 1) assert_array_almost_equal(world1, world2) def test_sip(): with get_pkg_data_fileobj( os.path.join("data", "sip.fits"), encoding='binary') as test_file: hdulist = fits.open(test_file, ignore_missing_end=True) with pytest.warns(FITSFixedWarning): wcs1 = wcs.WCS(hdulist[0].header) assert wcs1.sip is not None s = pickle.dumps(wcs1) wcs2 = pickle.loads(s) with NumpyRNGContext(123456789): x = np.random.rand(2 ** 16, wcs1.wcs.naxis) world1 = wcs1.all_pix2world(x, 1) world2 = wcs2.all_pix2world(x, 1) assert_array_almost_equal(world1, world2) def test_sip2(): with get_pkg_data_fileobj( os.path.join("data", "sip2.fits"), encoding='binary') as test_file: hdulist = fits.open(test_file, ignore_missing_end=True) with pytest.warns(FITSFixedWarning): wcs1 = wcs.WCS(hdulist[0].header) assert wcs1.sip is not None s = pickle.dumps(wcs1) wcs2 = pickle.loads(s) with NumpyRNGContext(123456789): x = np.random.rand(2 ** 16, wcs1.wcs.naxis) world1 = wcs1.all_pix2world(x, 1) world2 = wcs2.all_pix2world(x, 1) assert_array_almost_equal(world1, world2) # Ignore "PV2_2 = 0.209028857410973 invalid keyvalue" warning seen on Windows. @pytest.mark.filterwarnings(r'ignore:PV2_2') def test_wcs(): header = get_pkg_data_contents( os.path.join("data", "outside_sky.hdr"), encoding='binary') wcs1 = wcs.WCS(header) s = pickle.dumps(wcs1) wcs2 = pickle.loads(s) with NumpyRNGContext(123456789): x = np.random.rand(2 ** 16, wcs1.wcs.naxis) world1 = wcs1.all_pix2world(x, 1) world2 = wcs2.all_pix2world(x, 1) assert_array_almost_equal(world1, world2) class Sub(wcs.WCS): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.foo = 42 def test_subclass(): wcs1 = Sub() wcs1.foo = 45 s = pickle.dumps(wcs1) wcs2 = pickle.loads(s) assert isinstance(wcs2, Sub) assert wcs1.foo == 45 assert wcs2.foo == 45 assert wcs2.wcs is not None def test_axes_info(): w = wcs.WCS(naxis=3) w.pixel_shape = [100, 200, 300] w.pixel_bounds = ((11, 22), (33, 45), (55, 67)) w.extra = 111 w2 = pickle.loads(pickle.dumps(w)) # explicitly test naxis-related info assert w.naxis == w2.naxis assert w.pixel_shape == w2.pixel_shape assert w.pixel_bounds == w2.pixel_bounds # test all attributes for k, v in w.__dict__.items(): assert getattr(w2, k) == v def test_pixlist_wcs_colsel(): """ Test selection of a specific pixel list WCS using ``colsel``. See #11412. """ hdr_file = get_pkg_data_filename('data/chandra-pixlist-wcs.hdr') hdr = fits.Header.fromtextfile(hdr_file) with pytest.warns(wcs.FITSFixedWarning): w0 = wcs.WCS(hdr, keysel=['image', 'pixel'], colsel=[11, 12]) with pytest.warns(wcs.FITSFixedWarning): w = pickle.loads(pickle.dumps(w0)) assert w.naxis == 2 assert list(w.wcs.ctype) == ['RA---TAN', 'DEC--TAN'] assert np.allclose(w.wcs.crval, [229.38051931869, -58.81108068885]) assert np.allclose(w.wcs.pc, [[1, 0], [0, 1]]) assert np.allclose(w.wcs.cdelt, [-0.00013666666666666, 0.00013666666666666]) assert np.allclose(w.wcs.lonpole, 180.) def test_alt_wcskey(): w = wcs.WCS(key='A') w2 = pickle.loads(pickle.dumps(w)) assert w2.wcs.alt == 'A' ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/test_profiling.py0000644000175100001710000000502600000000000021311 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import os import pytest import numpy as np from astropy.utils.data import get_pkg_data_filenames, get_pkg_data_contents from astropy.utils.misc import NumpyRNGContext from astropy import wcs from astropy.wcs.wcs import FITSFixedWarning # use the base name of the file, because everything we yield # will show up in the test name in the pandokia report hdr_map_file_list = [ os.path.basename(fname) for fname in get_pkg_data_filenames("data/maps", pattern="*.hdr")] # Checking the number of files before reading them in. # OLD COMMENTS: # AFTER we tested with every file that we found, check to see that we # actually have the list we expect. If N=0, we will not have performed # any tests at all. If N < n_data_files, we are missing some files, # so we will have skipped some tests. Without this check, both cases # happen silently! def test_read_map_files(): # how many map files we expect to see n_map_files = 28 assert len(hdr_map_file_list) == n_map_files, ( "test_read_map_files has wrong number data files: found {}, expected " " {}".format(len(hdr_map_file_list), n_map_files)) @pytest.mark.parametrize("filename", hdr_map_file_list) def test_map(filename): header = get_pkg_data_contents(os.path.join("data/maps", filename)) wcsobj = wcs.WCS(header) with NumpyRNGContext(123456789): x = np.random.rand(2 ** 12, wcsobj.wcs.naxis) wcsobj.wcs_pix2world(x, 1) wcsobj.wcs_world2pix(x, 1) hdr_spec_file_list = [ os.path.basename(fname) for fname in get_pkg_data_filenames("data/spectra", pattern="*.hdr")] def test_read_spec_files(): # how many spec files expected n_spec_files = 6 assert len(hdr_spec_file_list) == n_spec_files, ( "test_spectra has wrong number data files: found {}, expected " " {}".format(len(hdr_spec_file_list), n_spec_files)) # b.t.w. If this assert happens, pytest reports one more test # than it would have otherwise. @pytest.mark.parametrize("filename", hdr_spec_file_list) def test_spectrum(filename): header = get_pkg_data_contents(os.path.join("data", "spectra", filename)) # Warning only pops up for one of the inputs. with pytest.warns() as warning_lines: wcsobj = wcs.WCS(header) for w in warning_lines: assert issubclass(w.category, FITSFixedWarning) with NumpyRNGContext(123456789): x = np.random.rand(2 ** 16, wcsobj.wcs.naxis) wcsobj.wcs_pix2world(x, 1) wcsobj.wcs_world2pix(x, 1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/test_tab.py0000644000175100001710000000356000000000000020067 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import numpy as np import pytest from packaging.version import Version from astropy import wcs from astropy.wcs import _wcs # noqa from astropy.io import fits from astropy.utils.data import get_pkg_data_filename from . helper import SimModelTAB _WCSLIB_VER = Version(_wcs.__version__) def test_2d_spatial_tab_roundtrip(tab_wcs_2di): nx, ny = tab_wcs_2di.pixel_shape # generate "random" test coordinates: np.random.seed(1) xy = 0.51 + [nx + 0.99, ny + 0.99] * np.random.random((100, 2)) rd = tab_wcs_2di.wcs_pix2world(xy, 1) xy_roundtripped = tab_wcs_2di.wcs_world2pix(rd, 1) m = np.logical_and(*(np.isfinite(xy_roundtripped).T)) assert np.allclose(xy[m], xy_roundtripped[m], rtol=0, atol=1e-7) def test_2d_spatial_tab_vs_model(): nx = 150 ny = 200 model = SimModelTAB(nx=nx, ny=ny) # generate FITS HDU list: hdulist = model.hdulist # create WCS object: w = wcs.WCS(hdulist[0].header, hdulist) # generate "random" test coordinates: np.random.seed(1) xy = 0.51 + [nx + 0.99, ny + 0.99] * np.random.random((100, 2)) rd = w.wcs_pix2world(xy, 1) rd_model = model.fwd_eval(xy) assert np.allclose(rd, rd_model, rtol=0, atol=1e-7) @pytest.mark.skipif( _WCSLIB_VER < Version('7.6'), reason="Only in WCSLIB 7.6 a 1D -TAB axis roundtrips unless first axis" ) def test_mixed_celest_and_1d_tab_roundtrip(): # Tests WCS roundtripping for the case when there is one -TAB axis and # this axis is not the first axis. This tests a bug fixed in WCSLIB 7.6. filename = get_pkg_data_filename('data/tab-time-last-axis.fits') hdul = fits.open(filename) w = wcs.WCS(hdul[0].header, hdul) hdul.close() pts = np.random.random((10, 3)) * [[2047, 2047, 127]] assert np.allclose(pts, w.wcs_world2pix(w.wcs_pix2world(pts, 0), 0)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/test_tabprm.py0000755000175100001710000000605100000000000020607 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst from copy import deepcopy import pytest import numpy as np from astropy import wcs from . helper import SimModelTAB def test_wcsprm_tab_basic(tab_wcs_2di): assert len(tab_wcs_2di.wcs.tab) == 1 t = tab_wcs_2di.wcs.tab[0] assert tab_wcs_2di.wcs.tab[0] is not t def test_tabprm_coord(tab_wcs_2di_f): t = tab_wcs_2di_f.wcs.tab[0] c0 = t.coord c1 = np.ones_like(c0) t.coord = c1 assert np.allclose(tab_wcs_2di_f.wcs.tab[0].coord, c1) def test_tabprm_crval_and_deepcopy(tab_wcs_2di_f): w = deepcopy(tab_wcs_2di_f) t = tab_wcs_2di_f.wcs.tab[0] pix = np.array([[2, 3]], dtype=np.float32) rd1 = tab_wcs_2di_f.wcs_pix2world(pix, 1) c = t.crval.copy() d = 0.5 * np.ones_like(c) t.crval += d assert np.allclose(tab_wcs_2di_f.wcs.tab[0].crval, c + d) rd2 = tab_wcs_2di_f.wcs_pix2world(pix - d, 1) assert np.allclose(rd1, rd2) rd3 = w.wcs_pix2world(pix, 1) assert np.allclose(rd1, rd3) def test_tabprm_delta(tab_wcs_2di): t = tab_wcs_2di.wcs.tab[0] assert np.allclose([0.0, 0.0], t.delta) def test_tabprm_K(tab_wcs_2di): t = tab_wcs_2di.wcs.tab[0] assert np.all(t.K == [4, 2]) def test_tabprm_M(tab_wcs_2di): t = tab_wcs_2di.wcs.tab[0] assert t.M == 2 def test_tabprm_nc(tab_wcs_2di): t = tab_wcs_2di.wcs.tab[0] assert t.nc == 8 def test_tabprm_extrema(tab_wcs_2di): t = tab_wcs_2di.wcs.tab[0] extrema = np.array( [[[-0.0026, -0.5], [1.001, -0.5]], [[-0.0026, 0.5], [1.001, 0.5]]] ) assert np.allclose(t.extrema, extrema) def test_tabprm_map(tab_wcs_2di_f): t = tab_wcs_2di_f.wcs.tab[0] assert np.allclose(t.map, [0, 1]) t.map[1] = 5 assert np.all(tab_wcs_2di_f.wcs.tab[0].map == [0, 5]) t.map = [1, 4] assert np.all(tab_wcs_2di_f.wcs.tab[0].map == [1, 4]) def test_tabprm_sense(tab_wcs_2di): t = tab_wcs_2di.wcs.tab[0] assert np.all(t.sense == [1, 1]) def test_tabprm_p0(tab_wcs_2di): t = tab_wcs_2di.wcs.tab[0] assert np.all(t.p0 == [0, 0]) def test_tabprm_print(tab_wcs_2di_f, capfd): tab_wcs_2di_f.wcs.tab[0].print_contents() captured = capfd.readouterr() s = str(tab_wcs_2di_f.wcs.tab[0]) out = str(captured.out) lout= out.split('\n') assert out == s assert lout[0] == ' flag: 137' assert lout[1] == ' M: 2' def test_wcstab_copy(tab_wcs_2di_f): t = tab_wcs_2di_f.wcs.tab[0] c0 = t.coord c1 = np.ones_like(c0) t.coord = c1 assert np.allclose(tab_wcs_2di_f.wcs.tab[0].coord, c1) def test_tabprm_crval(tab_wcs_2di_f): w = deepcopy(tab_wcs_2di_f) t = tab_wcs_2di_f.wcs.tab[0] pix = np.array([[2, 3]], dtype=np.float32) rd1 = tab_wcs_2di_f.wcs_pix2world(pix, 1) c = t.crval.copy() d = 0.5 * np.ones_like(c) t.crval += d assert np.allclose(tab_wcs_2di_f.wcs.tab[0].crval, c + d) rd2 = tab_wcs_2di_f.wcs_pix2world(pix - d, 1) assert np.allclose(rd1, rd2) rd3 = w.wcs_pix2world(pix, 1) assert np.allclose(rd1, rd3) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/test_utils.py0000644000175100001710000013620100000000000020460 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import warnings from contextlib import nullcontext import pytest from packaging.version import Version import numpy as np from numpy.testing import assert_almost_equal, assert_equal, assert_allclose from astropy.utils.data import get_pkg_data_contents, get_pkg_data_filename from astropy.utils.exceptions import AstropyUserWarning from astropy.time import Time from astropy import units as u from astropy.utils import unbroadcast from astropy.coordinates import SkyCoord, EarthLocation, ITRS from astropy.units import Quantity from astropy.io import fits from astropy.wcs import _wcs # noqa from astropy.wcs.wcs import (WCS, Sip, WCSSUB_LONGITUDE, WCSSUB_LATITUDE, FITSFixedWarning) from astropy.wcs.wcsapi.fitswcs import SlicedFITSWCS from astropy.wcs.utils import (proj_plane_pixel_scales, is_proj_plane_distorted, non_celestial_pixel_scales, wcs_to_celestial_frame, celestial_frame_to_wcs, skycoord_to_pixel, pixel_to_skycoord, custom_wcs_to_frame_mappings, custom_frame_to_wcs_mappings, add_stokes_axis_to_wcs, pixel_to_pixel, _split_matrix, _pixel_to_pixel_correlation_matrix, _pixel_to_world_correlation_matrix, local_partial_pixel_derivatives, fit_wcs_from_points, obsgeo_to_frame) from astropy.utils.compat.optional_deps import HAS_SCIPY # noqa def test_wcs_dropping(): wcs = WCS(naxis=4) wcs.wcs.pc = np.zeros([4, 4]) np.fill_diagonal(wcs.wcs.pc, np.arange(1, 5)) pc = wcs.wcs.pc # for later use below dropped = wcs.dropaxis(0) assert np.all(dropped.wcs.get_pc().diagonal() == np.array([2, 3, 4])) dropped = wcs.dropaxis(1) assert np.all(dropped.wcs.get_pc().diagonal() == np.array([1, 3, 4])) dropped = wcs.dropaxis(2) assert np.all(dropped.wcs.get_pc().diagonal() == np.array([1, 2, 4])) dropped = wcs.dropaxis(3) assert np.all(dropped.wcs.get_pc().diagonal() == np.array([1, 2, 3])) wcs = WCS(naxis=4) wcs.wcs.cd = pc dropped = wcs.dropaxis(0) assert np.all(dropped.wcs.get_pc().diagonal() == np.array([2, 3, 4])) dropped = wcs.dropaxis(1) assert np.all(dropped.wcs.get_pc().diagonal() == np.array([1, 3, 4])) dropped = wcs.dropaxis(2) assert np.all(dropped.wcs.get_pc().diagonal() == np.array([1, 2, 4])) dropped = wcs.dropaxis(3) assert np.all(dropped.wcs.get_pc().diagonal() == np.array([1, 2, 3])) def test_wcs_swapping(): wcs = WCS(naxis=4) wcs.wcs.pc = np.zeros([4, 4]) np.fill_diagonal(wcs.wcs.pc, np.arange(1, 5)) pc = wcs.wcs.pc # for later use below swapped = wcs.swapaxes(0, 1) assert np.all(swapped.wcs.get_pc().diagonal() == np.array([2, 1, 3, 4])) swapped = wcs.swapaxes(0, 3) assert np.all(swapped.wcs.get_pc().diagonal() == np.array([4, 2, 3, 1])) swapped = wcs.swapaxes(2, 3) assert np.all(swapped.wcs.get_pc().diagonal() == np.array([1, 2, 4, 3])) wcs = WCS(naxis=4) wcs.wcs.cd = pc swapped = wcs.swapaxes(0, 1) assert np.all(swapped.wcs.get_pc().diagonal() == np.array([2, 1, 3, 4])) swapped = wcs.swapaxes(0, 3) assert np.all(swapped.wcs.get_pc().diagonal() == np.array([4, 2, 3, 1])) swapped = wcs.swapaxes(2, 3) assert np.all(swapped.wcs.get_pc().diagonal() == np.array([1, 2, 4, 3])) @pytest.mark.parametrize('ndim', (2, 3)) def test_add_stokes(ndim): wcs = WCS(naxis=ndim) for ii in range(ndim + 1): outwcs = add_stokes_axis_to_wcs(wcs, ii) assert outwcs.wcs.naxis == ndim + 1 assert outwcs.wcs.ctype[ii] == 'STOKES' assert outwcs.wcs.cname[ii] == 'STOKES' def test_slice(): mywcs = WCS(naxis=2) mywcs.wcs.crval = [1, 1] mywcs.wcs.cdelt = [0.1, 0.1] mywcs.wcs.crpix = [1, 1] mywcs._naxis = [1000, 500] pscale = 0.1 # from cdelt slice_wcs = mywcs.slice([slice(1, None), slice(0, None)]) assert np.all(slice_wcs.wcs.crpix == np.array([1, 0])) assert slice_wcs._naxis == [1000, 499] # test that CRPIX maps to CRVAL: assert_allclose( slice_wcs.wcs_pix2world(*slice_wcs.wcs.crpix, 1), slice_wcs.wcs.crval, rtol=0.0, atol=1e-6 * pscale ) slice_wcs = mywcs.slice([slice(1, None, 2), slice(0, None, 4)]) assert np.all(slice_wcs.wcs.crpix == np.array([0.625, 0.25])) assert np.all(slice_wcs.wcs.cdelt == np.array([0.4, 0.2])) assert slice_wcs._naxis == [250, 250] slice_wcs = mywcs.slice([slice(None, None, 2), slice(0, None, 2)]) assert np.all(slice_wcs.wcs.cdelt == np.array([0.2, 0.2])) assert slice_wcs._naxis == [500, 250] # Non-integral values do not alter the naxis attribute with pytest.warns(AstropyUserWarning): slice_wcs = mywcs.slice([slice(50.), slice(20.)]) assert slice_wcs._naxis == [1000, 500] with pytest.warns(AstropyUserWarning): slice_wcs = mywcs.slice([slice(50.), slice(20)]) assert slice_wcs._naxis == [20, 500] with pytest.warns(AstropyUserWarning): slice_wcs = mywcs.slice([slice(50), slice(20.5)]) assert slice_wcs._naxis == [1000, 50] def test_slice_with_sip(): mywcs = WCS(naxis=2) mywcs.wcs.crval = [1, 1] mywcs.wcs.cdelt = [0.1, 0.1] mywcs.wcs.crpix = [1, 1] mywcs._naxis = [1000, 500] mywcs.wcs.ctype = ['RA---TAN-SIP', 'DEC--TAN-SIP'] a = np.array( [[0, 0, 5.33092692e-08, 3.73753773e-11, -2.02111473e-13], [0, 2.44084308e-05, 2.81394789e-11, 5.17856895e-13, 0.0], [-2.41334657e-07, 1.29289255e-10, 2.35753629e-14, 0.0, 0.0], [-2.37162007e-10, 5.43714947e-13, 0.0, 0.0, 0.0], [-2.81029767e-13, 0.0, 0.0, 0.0, 0.0]] ) b = np.array( [[0, 0, 2.99270374e-05, -2.38136074e-10, 7.23205168e-13], [0, -1.71073858e-07, 6.31243431e-11, -5.16744347e-14, 0.0], [6.95458963e-06, -3.08278961e-10, -1.75800917e-13, 0.0, 0.0], [3.51974159e-11, 5.60993016e-14, 0.0, 0.0, 0.0], [-5.92438525e-13, 0.0, 0.0, 0.0, 0.0]] ) mywcs.sip = Sip(a, b, None, None, mywcs.wcs.crpix) mywcs.wcs.set() pscale = 0.1 # from cdelt slice_wcs = mywcs.slice([slice(1, None), slice(0, None)]) # test that CRPIX maps to CRVAL: assert_allclose( slice_wcs.all_pix2world(*slice_wcs.wcs.crpix, 1), slice_wcs.wcs.crval, rtol=0.0, atol=1e-6 * pscale ) slice_wcs = mywcs.slice([slice(1, None, 2), slice(0, None, 4)]) # test that CRPIX maps to CRVAL: assert_allclose( slice_wcs.all_pix2world(*slice_wcs.wcs.crpix, 1), slice_wcs.wcs.crval, rtol=0.0, atol=1e-6 * pscale ) def test_slice_getitem(): mywcs = WCS(naxis=2) mywcs.wcs.crval = [1, 1] mywcs.wcs.cdelt = [0.1, 0.1] mywcs.wcs.crpix = [1, 1] slice_wcs = mywcs[1::2, 0::4] assert np.all(slice_wcs.wcs.crpix == np.array([0.625, 0.25])) assert np.all(slice_wcs.wcs.cdelt == np.array([0.4, 0.2])) mywcs.wcs.crpix = [2, 2] slice_wcs = mywcs[1::2, 0::4] assert np.all(slice_wcs.wcs.crpix == np.array([0.875, 0.75])) assert np.all(slice_wcs.wcs.cdelt == np.array([0.4, 0.2])) # Default: numpy order slice_wcs = mywcs[1::2] assert np.all(slice_wcs.wcs.crpix == np.array([2, 0.75])) assert np.all(slice_wcs.wcs.cdelt == np.array([0.1, 0.2])) def test_slice_fitsorder(): mywcs = WCS(naxis=2) mywcs.wcs.crval = [1, 1] mywcs.wcs.cdelt = [0.1, 0.1] mywcs.wcs.crpix = [1, 1] slice_wcs = mywcs.slice([slice(1, None), slice(0, None)], numpy_order=False) assert np.all(slice_wcs.wcs.crpix == np.array([0, 1])) slice_wcs = mywcs.slice([slice(1, None, 2), slice(0, None, 4)], numpy_order=False) assert np.all(slice_wcs.wcs.crpix == np.array([0.25, 0.625])) assert np.all(slice_wcs.wcs.cdelt == np.array([0.2, 0.4])) slice_wcs = mywcs.slice([slice(1, None, 2)], numpy_order=False) assert np.all(slice_wcs.wcs.crpix == np.array([0.25, 1])) assert np.all(slice_wcs.wcs.cdelt == np.array([0.2, 0.1])) def test_slice_wcs(): mywcs = WCS(naxis=2) sub = mywcs[0] assert isinstance(sub, SlicedFITSWCS) with pytest.raises(IndexError) as exc: mywcs[0, ::2] assert exc.value.args[0] == "Slicing WCS with a step is not supported." def test_axis_names(): mywcs = WCS(naxis=4) mywcs.wcs.ctype = ['RA---TAN', 'DEC--TAN', 'VOPT-LSR', 'STOKES'] assert mywcs.axis_type_names == ['RA', 'DEC', 'VOPT', 'STOKES'] mywcs.wcs.cname = ['RA', 'DEC', 'VOPT', 'STOKES'] assert mywcs.axis_type_names == ['RA', 'DEC', 'VOPT', 'STOKES'] def test_celestial(): mywcs = WCS(naxis=4) mywcs.wcs.ctype = ['RA---TAN', 'DEC--TAN', 'VOPT', 'STOKES'] cel = mywcs.celestial assert tuple(cel.wcs.ctype) == ('RA---TAN', 'DEC--TAN') assert cel.axis_type_names == ['RA', 'DEC'] def test_wcs_to_celestial_frame(): # Import astropy.coordinates here to avoid circular imports from astropy.coordinates.builtin_frames import ICRS, ITRS, FK5, FK4, Galactic mywcs = WCS(naxis=2) mywcs.wcs.set() with pytest.raises(ValueError, match="Could not determine celestial frame " "corresponding to the specified WCS object"): assert wcs_to_celestial_frame(mywcs) is None mywcs = WCS(naxis=2) mywcs.wcs.ctype = ['XOFFSET', 'YOFFSET'] mywcs.wcs.set() with pytest.raises(ValueError): assert wcs_to_celestial_frame(mywcs) is None mywcs = WCS(naxis=2) mywcs.wcs.ctype = ['RA---TAN', 'DEC--TAN'] mywcs.wcs.set() frame = wcs_to_celestial_frame(mywcs) assert isinstance(frame, ICRS) mywcs = WCS(naxis=2) mywcs.wcs.ctype = ['RA---TAN', 'DEC--TAN'] mywcs.wcs.equinox = 1987. mywcs.wcs.set() print(mywcs.to_header()) frame = wcs_to_celestial_frame(mywcs) assert isinstance(frame, FK5) assert frame.equinox == Time(1987., format='jyear') mywcs = WCS(naxis=2) mywcs.wcs.ctype = ['RA---TAN', 'DEC--TAN'] mywcs.wcs.equinox = 1982 mywcs.wcs.set() frame = wcs_to_celestial_frame(mywcs) assert isinstance(frame, FK4) assert frame.equinox == Time(1982., format='byear') mywcs = WCS(naxis=2) mywcs.wcs.ctype = ['GLON-SIN', 'GLAT-SIN'] mywcs.wcs.set() frame = wcs_to_celestial_frame(mywcs) assert isinstance(frame, Galactic) mywcs = WCS(naxis=2) mywcs.wcs.ctype = ['TLON-CAR', 'TLAT-CAR'] mywcs.wcs.dateobs = '2017-08-17T12:41:04.430' mywcs.wcs.set() frame = wcs_to_celestial_frame(mywcs) assert isinstance(frame, ITRS) assert frame.obstime == Time('2017-08-17T12:41:04.430') for equinox in [np.nan, 1987, 1982]: mywcs = WCS(naxis=2) mywcs.wcs.ctype = ['RA---TAN', 'DEC--TAN'] mywcs.wcs.radesys = 'ICRS' mywcs.wcs.equinox = equinox mywcs.wcs.set() frame = wcs_to_celestial_frame(mywcs) assert isinstance(frame, ICRS) # Flipped order mywcs = WCS(naxis=2) mywcs.wcs.ctype = ['DEC--TAN', 'RA---TAN'] mywcs.wcs.set() frame = wcs_to_celestial_frame(mywcs) assert isinstance(frame, ICRS) # More than two dimensions mywcs = WCS(naxis=3) mywcs.wcs.ctype = ['DEC--TAN', 'VELOCITY', 'RA---TAN'] mywcs.wcs.set() frame = wcs_to_celestial_frame(mywcs) assert isinstance(frame, ICRS) mywcs = WCS(naxis=3) mywcs.wcs.ctype = ['GLAT-CAR', 'VELOCITY', 'GLON-CAR'] mywcs.wcs.set() frame = wcs_to_celestial_frame(mywcs) assert isinstance(frame, Galactic) def test_wcs_to_celestial_frame_correlated(): # Regression test for a bug that caused wcs_to_celestial_frame to fail when # the celestial axes were correlated with other axes. # Import astropy.coordinates here to avoid circular imports from astropy.coordinates.builtin_frames import ICRS mywcs = WCS(naxis=3) mywcs.wcs.ctype = 'RA---TAN', 'DEC--TAN', 'FREQ' mywcs.wcs.cd = np.ones((3, 3)) mywcs.wcs.set() frame = wcs_to_celestial_frame(mywcs) assert isinstance(frame, ICRS) def test_wcs_to_celestial_frame_extend(): mywcs = WCS(naxis=2) mywcs.wcs.ctype = ['XOFFSET', 'YOFFSET'] mywcs.wcs.set() with pytest.raises(ValueError): wcs_to_celestial_frame(mywcs) class OffsetFrame: pass def identify_offset(wcs): if wcs.wcs.ctype[0].endswith('OFFSET') and wcs.wcs.ctype[1].endswith('OFFSET'): return OffsetFrame() with custom_wcs_to_frame_mappings(identify_offset): frame = wcs_to_celestial_frame(mywcs) assert isinstance(frame, OffsetFrame) # Check that things are back to normal after the context manager with pytest.raises(ValueError): wcs_to_celestial_frame(mywcs) def test_celestial_frame_to_wcs(): # Import astropy.coordinates here to avoid circular imports from astropy.coordinates import ICRS, ITRS, FK5, FK4, FK4NoETerms, Galactic, BaseCoordinateFrame class FakeFrame(BaseCoordinateFrame): pass frame = FakeFrame() with pytest.raises(ValueError) as exc: celestial_frame_to_wcs(frame) assert exc.value.args[0] == ("Could not determine WCS corresponding to " "the specified coordinate frame.") frame = ICRS() mywcs = celestial_frame_to_wcs(frame) mywcs.wcs.set() assert tuple(mywcs.wcs.ctype) == ('RA---TAN', 'DEC--TAN') assert mywcs.wcs.radesys == 'ICRS' assert np.isnan(mywcs.wcs.equinox) assert mywcs.wcs.lonpole == 180 assert mywcs.wcs.latpole == 0 frame = FK5(equinox='J1987') mywcs = celestial_frame_to_wcs(frame) assert tuple(mywcs.wcs.ctype) == ('RA---TAN', 'DEC--TAN') assert mywcs.wcs.radesys == 'FK5' assert mywcs.wcs.equinox == 1987. frame = FK4(equinox='B1982') mywcs = celestial_frame_to_wcs(frame) assert tuple(mywcs.wcs.ctype) == ('RA---TAN', 'DEC--TAN') assert mywcs.wcs.radesys == 'FK4' assert mywcs.wcs.equinox == 1982. frame = FK4NoETerms(equinox='B1982') mywcs = celestial_frame_to_wcs(frame) assert tuple(mywcs.wcs.ctype) == ('RA---TAN', 'DEC--TAN') assert mywcs.wcs.radesys == 'FK4-NO-E' assert mywcs.wcs.equinox == 1982. frame = Galactic() mywcs = celestial_frame_to_wcs(frame) assert tuple(mywcs.wcs.ctype) == ('GLON-TAN', 'GLAT-TAN') assert mywcs.wcs.radesys == '' assert np.isnan(mywcs.wcs.equinox) frame = Galactic() mywcs = celestial_frame_to_wcs(frame, projection='CAR') assert tuple(mywcs.wcs.ctype) == ('GLON-CAR', 'GLAT-CAR') assert mywcs.wcs.radesys == '' assert np.isnan(mywcs.wcs.equinox) frame = Galactic() mywcs = celestial_frame_to_wcs(frame, projection='CAR') mywcs.wcs.crval = [100, -30] mywcs.wcs.set() assert_allclose((mywcs.wcs.lonpole, mywcs.wcs.latpole), (180, 60)) frame = ITRS(obstime=Time('2017-08-17T12:41:04.43')) mywcs = celestial_frame_to_wcs(frame, projection='CAR') assert tuple(mywcs.wcs.ctype) == ('TLON-CAR', 'TLAT-CAR') assert mywcs.wcs.radesys == 'ITRS' assert mywcs.wcs.dateobs == '2017-08-17T12:41:04.430' frame = ITRS() mywcs = celestial_frame_to_wcs(frame, projection='CAR') assert tuple(mywcs.wcs.ctype) == ('TLON-CAR', 'TLAT-CAR') assert mywcs.wcs.radesys == 'ITRS' assert mywcs.wcs.dateobs == Time('J2000').utc.fits def test_celestial_frame_to_wcs_extend(): class OffsetFrame: pass frame = OffsetFrame() with pytest.raises(ValueError): celestial_frame_to_wcs(frame) def identify_offset(frame, projection=None): if isinstance(frame, OffsetFrame): wcs = WCS(naxis=2) wcs.wcs.ctype = ['XOFFSET', 'YOFFSET'] return wcs with custom_frame_to_wcs_mappings(identify_offset): mywcs = celestial_frame_to_wcs(frame) assert tuple(mywcs.wcs.ctype) == ('XOFFSET', 'YOFFSET') # Check that things are back to normal after the context manager with pytest.raises(ValueError): celestial_frame_to_wcs(frame) def test_pixscale_nodrop(): mywcs = WCS(naxis=2) mywcs.wcs.cdelt = [0.1, 0.2] mywcs.wcs.ctype = ['RA---TAN', 'DEC--TAN'] assert_almost_equal(proj_plane_pixel_scales(mywcs), (0.1, 0.2)) mywcs.wcs.cdelt = [-0.1, 0.2] assert_almost_equal(proj_plane_pixel_scales(mywcs), (0.1, 0.2)) def test_pixscale_withdrop(): mywcs = WCS(naxis=3) mywcs.wcs.cdelt = [0.1, 0.2, 1] mywcs.wcs.ctype = ['RA---TAN', 'DEC--TAN', 'VOPT'] assert_almost_equal(proj_plane_pixel_scales(mywcs.celestial), (0.1, 0.2)) mywcs.wcs.cdelt = [-0.1, 0.2, 1] assert_almost_equal(proj_plane_pixel_scales(mywcs.celestial), (0.1, 0.2)) def test_pixscale_cd(): mywcs = WCS(naxis=2) mywcs.wcs.cd = [[-0.1, 0], [0, 0.2]] mywcs.wcs.ctype = ['RA---TAN', 'DEC--TAN'] assert_almost_equal(proj_plane_pixel_scales(mywcs), (0.1, 0.2)) @pytest.mark.parametrize('angle', (30, 45, 60, 75)) def test_pixscale_cd_rotated(angle): mywcs = WCS(naxis=2) rho = np.radians(angle) scale = 0.1 mywcs.wcs.cd = [[scale * np.cos(rho), -scale * np.sin(rho)], [scale * np.sin(rho), scale * np.cos(rho)]] mywcs.wcs.ctype = ['RA---TAN', 'DEC--TAN'] assert_almost_equal(proj_plane_pixel_scales(mywcs), (0.1, 0.1)) @pytest.mark.parametrize('angle', (30, 45, 60, 75)) def test_pixscale_pc_rotated(angle): mywcs = WCS(naxis=2) rho = np.radians(angle) scale = 0.1 mywcs.wcs.cdelt = [-scale, scale] mywcs.wcs.pc = [[np.cos(rho), -np.sin(rho)], [np.sin(rho), np.cos(rho)]] mywcs.wcs.ctype = ['RA---TAN', 'DEC--TAN'] assert_almost_equal(proj_plane_pixel_scales(mywcs), (0.1, 0.1)) @pytest.mark.parametrize(('cdelt', 'pc', 'pccd'), (([0.1, 0.2], np.eye(2), np.diag([0.1, 0.2])), ([0.1, 0.2, 0.3], np.eye(3), np.diag([0.1, 0.2, 0.3])), ([1, 1, 1], np.diag([0.1, 0.2, 0.3]), np.diag([0.1, 0.2, 0.3])))) def test_pixel_scale_matrix(cdelt, pc, pccd): mywcs = WCS(naxis=(len(cdelt))) mywcs.wcs.cdelt = cdelt mywcs.wcs.pc = pc assert_almost_equal(mywcs.pixel_scale_matrix, pccd) @pytest.mark.parametrize(('ctype', 'cel'), ((['RA---TAN', 'DEC--TAN'], True), (['RA---TAN', 'DEC--TAN', 'FREQ'], False), (['RA---TAN', 'FREQ'], False),)) def test_is_celestial(ctype, cel): mywcs = WCS(naxis=len(ctype)) mywcs.wcs.ctype = ctype assert mywcs.is_celestial == cel @pytest.mark.parametrize(('ctype', 'cel'), ((['RA---TAN', 'DEC--TAN'], True), (['RA---TAN', 'DEC--TAN', 'FREQ'], True), (['RA---TAN', 'FREQ'], False),)) def test_has_celestial(ctype, cel): mywcs = WCS(naxis=len(ctype)) mywcs.wcs.ctype = ctype assert mywcs.has_celestial == cel def test_has_celestial_correlated(): # Regression test for astropy/astropy#8416 - has_celestial failed when # celestial axes were correlated with other axes. mywcs = WCS(naxis=3) mywcs.wcs.ctype = 'RA---TAN', 'DEC--TAN', 'FREQ' mywcs.wcs.cd = np.ones((3, 3)) mywcs.wcs.set() assert mywcs.has_celestial @pytest.mark.parametrize(('cdelt', 'pc', 'cd', 'check_warning'), ((np.array([0.1, 0.2]), np.eye(2), np.eye(2), True), (np.array([1, 1]), np.diag([0.1, 0.2]), np.eye(2), True), (np.array([0.1, 0.2]), np.eye(2), None, False), (np.array([0.1, 0.2]), None, np.eye(2), True), )) def test_noncelestial_scale(cdelt, pc, cd, check_warning): mywcs = WCS(naxis=2) if cd is not None: mywcs.wcs.cd = cd if pc is not None: mywcs.wcs.pc = pc # TODO: Some inputs emit RuntimeWarning from here onwards. # Fix the test data. See @nden's comment in PR 9010. if check_warning: ctx = pytest.warns() else: ctx = nullcontext() with ctx as warning_lines: mywcs.wcs.cdelt = cdelt if check_warning: for w in warning_lines: assert issubclass(w.category, RuntimeWarning) assert 'cdelt will be ignored since cd is present' in str(w.message) mywcs.wcs.ctype = ['RA---TAN', 'FREQ'] ps = non_celestial_pixel_scales(mywcs) assert_almost_equal(ps.to_value(u.deg), np.array([0.1, 0.2])) @pytest.mark.parametrize('mode', ['all', 'wcs']) def test_skycoord_to_pixel(mode): # Import astropy.coordinates here to avoid circular imports from astropy.coordinates import SkyCoord header = get_pkg_data_contents('data/maps/1904-66_TAN.hdr', encoding='binary') wcs = WCS(header) ref = SkyCoord(0.1 * u.deg, -89. * u.deg, frame='icrs') xp, yp = skycoord_to_pixel(ref, wcs, mode=mode) # WCS is in FK5 so we need to transform back to ICRS new = pixel_to_skycoord(xp, yp, wcs, mode=mode).transform_to('icrs') assert_allclose(new.ra.degree, ref.ra.degree) assert_allclose(new.dec.degree, ref.dec.degree) # Make sure you can specify a different class using ``cls`` keyword class SkyCoord2(SkyCoord): pass new2 = pixel_to_skycoord(xp, yp, wcs, mode=mode, cls=SkyCoord2).transform_to('icrs') assert new2.__class__ is SkyCoord2 assert_allclose(new2.ra.degree, ref.ra.degree) assert_allclose(new2.dec.degree, ref.dec.degree) def test_skycoord_to_pixel_swapped(): # Regression test for a bug that caused skycoord_to_pixel and # pixel_to_skycoord to not work correctly if the axes were swapped in the # WCS. # Import astropy.coordinates here to avoid circular imports from astropy.coordinates import SkyCoord header = get_pkg_data_contents('data/maps/1904-66_TAN.hdr', encoding='binary') wcs = WCS(header) wcs_swapped = wcs.sub([WCSSUB_LATITUDE, WCSSUB_LONGITUDE]) ref = SkyCoord(0.1 * u.deg, -89. * u.deg, frame='icrs') xp1, yp1 = skycoord_to_pixel(ref, wcs) xp2, yp2 = skycoord_to_pixel(ref, wcs_swapped) assert_allclose(xp1, xp2) assert_allclose(yp1, yp2) # WCS is in FK5 so we need to transform back to ICRS new1 = pixel_to_skycoord(xp1, yp1, wcs).transform_to('icrs') new2 = pixel_to_skycoord(xp1, yp1, wcs_swapped).transform_to('icrs') assert_allclose(new1.ra.degree, new2.ra.degree) assert_allclose(new1.dec.degree, new2.dec.degree) def test_is_proj_plane_distorted(): # non-orthogonal CD: wcs = WCS(naxis=2) wcs.wcs.cd = [[-0.1, 0], [0, 0.2]] wcs.wcs.ctype = ['RA---TAN', 'DEC--TAN'] assert(is_proj_plane_distorted(wcs)) # almost orthogonal CD: wcs.wcs.cd = [[0.1 + 2.0e-7, 1.7e-7], [1.2e-7, 0.1 - 1.3e-7]] assert(not is_proj_plane_distorted(wcs)) # real case: header = get_pkg_data_filename('data/sip.fits') with pytest.warns(FITSFixedWarning): wcs = WCS(header) assert(is_proj_plane_distorted(wcs)) @pytest.mark.parametrize('mode', ['all', 'wcs']) def test_skycoord_to_pixel_distortions(mode): # Import astropy.coordinates here to avoid circular imports from astropy.coordinates import SkyCoord header = get_pkg_data_filename('data/sip.fits') with pytest.warns(FITSFixedWarning): wcs = WCS(header) ref = SkyCoord(202.50 * u.deg, 47.19 * u.deg, frame='icrs') xp, yp = skycoord_to_pixel(ref, wcs, mode=mode) # WCS is in FK5 so we need to transform back to ICRS new = pixel_to_skycoord(xp, yp, wcs, mode=mode).transform_to('icrs') assert_allclose(new.ra.degree, ref.ra.degree) assert_allclose(new.dec.degree, ref.dec.degree) @pytest.fixture def spatial_wcs_2d_small_angle(): """ This WCS has an almost linear correlation between the pixel and world axes close to the reference pixel. """ wcs = WCS(naxis=2) wcs.wcs.ctype = ['HPLN-TAN', 'HPLT-TAN'] wcs.wcs.crpix = [3.0] * 2 wcs.wcs.cdelt = [0.002] * 2 wcs.wcs.crval = [0] * 2 wcs.wcs.set() return wcs def test_local_pixel_derivatives(spatial_wcs_2d_small_angle): not_diag = np.logical_not(np.diag([1, 1])) # At (or close to) the reference pixel this should equal the cdelt derivs = local_partial_pixel_derivatives(spatial_wcs_2d_small_angle, 3, 3) np.testing.assert_allclose(np.diag(derivs), spatial_wcs_2d_small_angle.wcs.cdelt) np.testing.assert_allclose(derivs[not_diag].flat, [0, 0], atol=1e-10) # Far away from the reference pixel this should not equal the cdelt derivs = local_partial_pixel_derivatives(spatial_wcs_2d_small_angle, 3e4, 3e4) assert not np.allclose(np.diag(derivs), spatial_wcs_2d_small_angle.wcs.cdelt) # At (or close to) the reference pixel this should equal the cdelt derivs = local_partial_pixel_derivatives( spatial_wcs_2d_small_angle, 3, 3, normalize_by_world=True) np.testing.assert_allclose(np.diag(derivs), [1, 1]) np.testing.assert_allclose(derivs[not_diag].flat, [0, 0], atol=1e-8) def test_pixel_to_world_correlation_matrix_celestial(): wcs = WCS(naxis=2) wcs.wcs.ctype = 'RA---TAN', 'DEC--TAN' wcs.wcs.set() assert_equal(wcs.axis_correlation_matrix, [[1, 1], [1, 1]]) matrix, classes = _pixel_to_world_correlation_matrix(wcs) assert_equal(matrix, [[1, 1]]) assert classes == [SkyCoord] def test_pixel_to_world_correlation_matrix_spectral_cube_uncorrelated(): wcs = WCS(naxis=3) wcs.wcs.ctype = 'RA---TAN', 'FREQ', 'DEC--TAN' wcs.wcs.set() assert_equal(wcs.axis_correlation_matrix, [[1, 0, 1], [0, 1, 0], [1, 0, 1]]) matrix, classes = _pixel_to_world_correlation_matrix(wcs) assert_equal(matrix, [[1, 0, 1], [0, 1, 0]]) assert classes == [SkyCoord, Quantity] def test_pixel_to_world_correlation_matrix_spectral_cube_correlated(): wcs = WCS(naxis=3) wcs.wcs.ctype = 'RA---TAN', 'FREQ', 'DEC--TAN' wcs.wcs.cd = np.ones((3, 3)) wcs.wcs.set() assert_equal(wcs.axis_correlation_matrix, [[1, 1, 1], [1, 1, 1], [1, 1, 1]]) matrix, classes = _pixel_to_world_correlation_matrix(wcs) assert_equal(matrix, [[1, 1, 1], [1, 1, 1]]) assert classes == [SkyCoord, Quantity] def test_pixel_to_pixel_correlation_matrix_celestial(): wcs_in = WCS(naxis=2) wcs_in.wcs.ctype = 'RA---TAN', 'DEC--TAN' wcs_in.wcs.set() wcs_out = WCS(naxis=2) wcs_out.wcs.ctype = 'DEC--TAN', 'RA---TAN' wcs_out.wcs.set() matrix = _pixel_to_pixel_correlation_matrix(wcs_in, wcs_out) assert_equal(matrix, [[1, 1], [1, 1]]) def test_pixel_to_pixel_correlation_matrix_spectral_cube_uncorrelated(): wcs_in = WCS(naxis=3) wcs_in.wcs.ctype = 'RA---TAN', 'DEC--TAN', 'FREQ' wcs_in.wcs.set() wcs_out = WCS(naxis=3) wcs_out.wcs.ctype = 'DEC--TAN', 'FREQ', 'RA---TAN' wcs_out.wcs.set() matrix = _pixel_to_pixel_correlation_matrix(wcs_in, wcs_out) assert_equal(matrix, [[1, 1, 0], [0, 0, 1], [1, 1, 0]]) def test_pixel_to_pixel_correlation_matrix_spectral_cube_correlated(): # NOTE: only make one of the WCSes have correlated axes to really test this wcs_in = WCS(naxis=3) wcs_in.wcs.ctype = 'RA---TAN', 'DEC--TAN', 'FREQ' wcs_in.wcs.set() wcs_out = WCS(naxis=3) wcs_out.wcs.ctype = 'DEC--TAN', 'FREQ', 'RA---TAN' wcs_out.wcs.cd = np.ones((3, 3)) wcs_out.wcs.set() matrix = _pixel_to_pixel_correlation_matrix(wcs_in, wcs_out) assert_equal(matrix, [[1, 1, 1], [1, 1, 1], [1, 1, 1]]) def test_pixel_to_pixel_correlation_matrix_mismatch(): wcs_in = WCS(naxis=2) wcs_in.wcs.ctype = 'RA---TAN', 'DEC--TAN' wcs_in.wcs.set() wcs_out = WCS(naxis=3) wcs_out.wcs.ctype = 'DEC--TAN', 'FREQ', 'RA---TAN' wcs_out.wcs.set() with pytest.raises(ValueError) as exc: _pixel_to_pixel_correlation_matrix(wcs_in, wcs_out) assert exc.value.args[0] == "The two WCS return a different number of world coordinates" wcs3 = WCS(naxis=2) wcs3.wcs.ctype = 'FREQ', 'PIXEL' wcs3.wcs.set() with pytest.raises(ValueError) as exc: _pixel_to_pixel_correlation_matrix(wcs_out, wcs3) assert exc.value.args[0] == "The world coordinate types of the two WCS do not match" wcs4 = WCS(naxis=4) wcs4.wcs.ctype = 'RA---TAN', 'DEC--TAN', 'Q1', 'Q2' wcs4.wcs.cunit = ['deg', 'deg', 'm/s', 'm/s'] wcs4.wcs.set() wcs5 = WCS(naxis=4) wcs5.wcs.ctype = 'Q1', 'RA---TAN', 'DEC--TAN', 'Q2' wcs5.wcs.cunit = ['m/s', 'deg', 'deg', 'm/s'] wcs5.wcs.set() with pytest.raises(ValueError, match="World coordinate order doesn't match " "and automatic matching is ambiguous"): _pixel_to_pixel_correlation_matrix(wcs4, wcs5) def test_pixel_to_pixel_correlation_matrix_nonsquare(): # Here we set up an input WCS that maps 3 pixel coordinates to 4 world # coordinates - the idea is to make sure that things work fine in cases # where the number of input and output pixel coordinates do not match. class FakeWCS(object): pass wcs_in = FakeWCS() wcs_in.low_level_wcs = wcs_in wcs_in.pixel_n_dim = 3 wcs_in.world_n_dim = 4 wcs_in.axis_correlation_matrix = [[True, True, False], [True, True, False], [True, True, False], [False, False, True]] wcs_in.world_axis_object_components = [('spat', 'ra', 'ra.degree'), ('spat', 'dec', 'dec.degree'), ('spec', 0, 'value'), ('time', 0, 'utc.value')] wcs_in.world_axis_object_classes = {'spat': ('astropy.coordinates.SkyCoord', (), {'frame': 'icrs'}), 'spec': ('astropy.units.Wavelength', (None,), {}), 'time': ('astropy.time.Time', (None,), {'format': 'mjd', 'scale': 'utc'})} wcs_out = FakeWCS() wcs_out.low_level_wcs = wcs_out wcs_out.pixel_n_dim = 4 wcs_out.world_n_dim = 4 wcs_out.axis_correlation_matrix = [[True, False, False, False], [False, True, True, False], [False, True, True, False], [False, False, False, True]] wcs_out.world_axis_object_components = [('spec', 0, 'value'), ('spat', 'ra', 'ra.degree'), ('spat', 'dec', 'dec.degree'), ('time', 0, 'utc.value')] wcs_out.world_axis_object_classes = wcs_in.world_axis_object_classes matrix = _pixel_to_pixel_correlation_matrix(wcs_in, wcs_out) matrix = matrix.astype(int) # The shape should be (n_pixel_out, n_pixel_in) assert matrix.shape == (4, 3) expected = np.array([[1, 1, 0], [1, 1, 0], [1, 1, 0], [0, 0, 1]]) assert_equal(matrix, expected) def test_split_matrix(): assert _split_matrix(np.array([[1]])) == [([0], [0])] assert _split_matrix(np.array([[1, 1], [1, 1]])) == [([0, 1], [0, 1])] assert _split_matrix(np.array([[1, 1, 0], [1, 1, 0], [0, 0, 1]])) == [([0, 1], [0, 1]), ([2], [2])] assert _split_matrix(np.array([[0, 1, 0], [1, 0, 0], [0, 0, 1]])) == [([0], [1]), ([1], [0]), ([2], [2])] assert _split_matrix(np.array([[0, 1, 1], [1, 0, 0], [1, 0, 1]])) == [([0, 1, 2], [0, 1, 2])] def test_pixel_to_pixel(): wcs_in = WCS(naxis=3) wcs_in.wcs.ctype = 'DEC--TAN', 'FREQ', 'RA---TAN' wcs_in.wcs.set() wcs_out = WCS(naxis=3) wcs_out.wcs.ctype = 'GLON-CAR', 'GLAT-CAR', 'FREQ' wcs_out.wcs.set() # First try with scalars with pytest.warns(AstropyUserWarning, match='No observer defined on WCS'): x, y, z = pixel_to_pixel(wcs_in, wcs_out, 1, 2, 3) assert x.shape == () assert y.shape == () assert z.shape == () # Now try with broadcasted arrays x = np.linspace(10, 20, 10) y = np.linspace(10, 20, 20) z = np.linspace(10, 20, 30) Z1, Y1, X1 = np.meshgrid(z, y, x, indexing='ij', copy=False) with pytest.warns(AstropyUserWarning, match='No observer defined on WCS'): X2, Y2, Z2 = pixel_to_pixel(wcs_in, wcs_out, X1, Y1, Z1) # The final arrays should have the correct shape assert X2.shape == (30, 20, 10) assert Y2.shape == (30, 20, 10) assert Z2.shape == (30, 20, 10) # But behind the scenes should also be broadcasted assert unbroadcast(X2).shape == (30, 1, 10) assert unbroadcast(Y2).shape == (30, 1, 10) assert unbroadcast(Z2).shape == (20, 1) # We can put the values back through the function to ensure round-tripping with pytest.warns(AstropyUserWarning, match='No observer defined on WCS'): X3, Y3, Z3 = pixel_to_pixel(wcs_out, wcs_in, X2, Y2, Z2) # The final arrays should have the correct shape assert X2.shape == (30, 20, 10) assert Y2.shape == (30, 20, 10) assert Z2.shape == (30, 20, 10) # But behind the scenes should also be broadcasted assert unbroadcast(X3).shape == (30, 1, 10) assert unbroadcast(Y3).shape == (20, 1) assert unbroadcast(Z3).shape == (30, 1, 10) # And these arrays should match the input assert_allclose(X1, X3) assert_allclose(Y1, Y3) assert_allclose(Z1, Z3) def test_pixel_to_pixel_correlated(): wcs_in = WCS(naxis=2) wcs_in.wcs.ctype = 'DEC--TAN', 'RA---TAN' wcs_in.wcs.set() wcs_out = WCS(naxis=2) wcs_out.wcs.ctype = 'GLON-CAR', 'GLAT-CAR' wcs_out.wcs.set() # First try with scalars x, y = pixel_to_pixel(wcs_in, wcs_out, 1, 2) assert x.shape == () assert y.shape == () # Now try with broadcasted arrays x = np.linspace(10, 20, 10) y = np.linspace(10, 20, 20) Y1, X1 = np.meshgrid(y, x, indexing='ij', copy=False) Y2, X2 = pixel_to_pixel(wcs_in, wcs_out, X1, Y1) # The final arrays should have the correct shape assert X2.shape == (20, 10) assert Y2.shape == (20, 10) # and there are no efficiency gains here since the celestial axes are correlated assert unbroadcast(X2).shape == (20, 10) def test_pixel_to_pixel_1d(): # Simple test to make sure that when WCS only returns one world coordinate # this still works correctly (since this requires special treatment behind # the scenes). wcs_in = WCS(naxis=1) wcs_in.wcs.ctype = 'COORD1', wcs_in.wcs.cunit = 'nm', wcs_in.wcs.set() wcs_out = WCS(naxis=1) wcs_out.wcs.ctype = 'COORD2', wcs_out.wcs.cunit = 'cm', wcs_out.wcs.set() # First try with a scalar x = pixel_to_pixel(wcs_in, wcs_out, 1) assert x.shape == () # Next with a regular array x = np.linspace(10, 20, 10) x = pixel_to_pixel(wcs_in, wcs_out, x) assert x.shape == (10,) # And now try with a broadcasted array x = np.broadcast_to(np.linspace(10, 20, 10), (4, 10)) x = pixel_to_pixel(wcs_in, wcs_out, x) assert x.shape == (4, 10) # The broadcasting of the input should be retained assert unbroadcast(x).shape == (10,) header_str_linear = """ XTENSION= 'IMAGE ' / Image extension BITPIX = -32 / array data type NAXIS = 2 / number of array dimensions NAXIS1 = 50 NAXIS2 = 50 PCOUNT = 0 / number of parameters GCOUNT = 1 / number of groups RADESYS = 'ICRS ' EQUINOX = 2000.0 WCSAXES = 2 CTYPE1 = 'RA---TAN' CTYPE2 = 'DEC--TAN' CRVAL1 = 250.3497414839765 CRVAL2 = 2.280925599609063 CRPIX1 = 1045.0 CRPIX2 = 1001.0 CD1_1 = -0.005564478186178 CD1_2 = -0.001042099258152 CD2_1 = 0.00118144146585 CD2_2 = -0.005590816683583 """ header_str_sip = """ XTENSION= 'IMAGE ' / Image extension BITPIX = -32 / array data type NAXIS = 2 / number of array dimensions NAXIS1 = 50 NAXIS2 = 50 PCOUNT = 0 / number of parameters GCOUNT = 1 / number of groups RADESYS = 'ICRS ' EQUINOX = 2000.0 WCSAXES = 2 CTYPE1 = 'RA---TAN-SIP' CTYPE2 = 'DEC--TAN-SIP' CRVAL1 = 250.3497414839765 CRVAL2 = 2.280925599609063 CRPIX1 = 1045.0 CRPIX2 = 1001.0 CD1_1 = -0.005564478186178 CD1_2 = -0.001042099258152 CD2_1 = 0.00118144146585 CD2_2 = -0.005590816683583 A_ORDER = 2 B_ORDER = 2 A_2_0 = 2.02451189234E-05 A_0_2 = 3.317603337918E-06 A_1_1 = 1.73456334971071E-05 B_2_0 = 3.331330003472E-06 B_0_2 = 2.04247482482589E-05 B_1_1 = 1.71476710804143E-05 AP_ORDER= 2 BP_ORDER= 2 AP_1_0 = 0.000904700296389636 AP_0_1 = 0.000627660715584716 AP_2_0 = -2.023482905861E-05 AP_0_2 = -3.332285841011E-06 AP_1_1 = -1.731636633824E-05 BP_1_0 = 0.000627960882053211 BP_0_1 = 0.000911222886084808 BP_2_0 = -3.343918167224E-06 BP_0_2 = -2.041598249021E-05 BP_1_1 = -1.711876336719E-05 A_DMAX = 44.72893589844534 B_DMAX = 44.62692873032506 """ header_str_prob = """ NAXIS = 2 / number of array dimensions WCSAXES = 2 / Number of coordinate axes CRPIX1 = 1024.5 / Pixel coordinate of reference point CRPIX2 = 1024.5 / Pixel coordinate of reference point CD1_1 = -1.7445934400771E-05 / Coordinate transformation matrix element CD1_2 = -4.9826985362578E-08 / Coordinate transformation matrix element CD2_1 = -5.0068838822312E-08 / Coordinate transformation matrix element CD2_2 = 1.7530614610951E-05 / Coordinate transformation matrix element CTYPE1 = 'RA---TAN' / Right ascension, gnomonic projection CTYPE2 = 'DEC--TAN' / Declination, gnomonic projection CRVAL1 = 5.8689341666667 / [deg] Coordinate value at reference point CRVAL2 = -71.995508583333 / [deg] Coordinate value at reference point """ @pytest.mark.skipif('not HAS_SCIPY') @pytest.mark.parametrize( 'header_str,crval,sip_degree,user_proj_point,exp_max_dist,exp_std_dist', [ # simple testset no distortions (header_str_linear, 250.3497414839765, None, False, 7e-5*u.deg, 2.5e-5*u.deg), # simple testset with distortions (header_str_sip, 250.3497414839765, 2, False, 7e-6*u.deg, 2.5e-6*u.deg), # testset with problematic WCS header that failed before (header_str_prob, 5.8689341666667, None, False, 7e-6*u.deg, 2.5e-6*u.deg), # simple testset no distortions, user defined center (header_str_linear, 250.3497414839765, None, True, 7e-5*u.deg, 2.5e-5*u.deg), # 360->0 degree crossover, simple testset no distortions (header_str_linear, 352.3497414839765, None, False, 7e-5*u.deg, 2.5e-5*u.deg), # 360->0 degree crossover, simple testset with distortions (header_str_sip, 352.3497414839765, 2, False, 7e-6*u.deg, 2.5e-6*u.deg), # 360->0 degree crossover, testset with problematic WCS header that failed before (header_str_prob, 352.3497414839765, None, False, 7e-6*u.deg, 2.5e-6*u.deg), # 360->0 degree crossover, simple testset no distortions, user defined center (header_str_linear, 352.3497414839765, None, True, 7e-5*u.deg, 2.5e-5*u.deg), ]) def test_fit_wcs_from_points(header_str, crval, sip_degree, user_proj_point, exp_max_dist, exp_std_dist): header = fits.Header.fromstring(header_str, sep='\n') header["CRVAL1"] = crval true_wcs = WCS(header, relax=True) # Getting the pixel coordinates x, y = np.meshgrid(list(range(10)), list(range(10))) x = x.flatten() y = y.flatten() # Calculating the true sky positions world_pix = true_wcs.pixel_to_world(x, y) # which projection point to use if user_proj_point: proj_point = world_pix[0] projlon = proj_point.data.lon.deg projlat = proj_point.data.lat.deg else: proj_point = 'center' # Fitting the wcs fit_wcs = fit_wcs_from_points((x, y), world_pix, proj_point=proj_point, sip_degree=sip_degree) # Validate that the true sky coordinates # match sky coordinates calculated from the wcs fit world_pix_new = fit_wcs.pixel_to_world(x, y) dists = world_pix.separation(world_pix_new) assert dists.max() < exp_max_dist assert np.std(dists) < exp_std_dist if user_proj_point: assert (fit_wcs.wcs.crval == [projlon, projlat]).all() @pytest.mark.skipif('not HAS_SCIPY') def test_fit_wcs_from_points_CRPIX_bounds(): # Test CRPIX bounds requirement wcs_str = """ WCSAXES = 2 / Number of coordinate axes CRPIX1 = 1045.0 / Pixel coordinate of reference point CRPIX2 = 1001.0 / Pixel coordinate of reference point PC1_1 = 0.00056205870415378 / Coordinate transformation matrix element PC1_2 = -0.00569181083243 / Coordinate transformation matrix element PC2_1 = 0.0056776810932466 / Coordinate transformation matrix element PC2_2 = 0.0004208048403273 / Coordinate transformation matrix element CDELT1 = 1.0 / [deg] Coordinate increment at reference point CDELT2 = 1.0 / [deg] Coordinate increment at reference point CUNIT1 = 'deg' / Units of coordinate increment and value CUNIT2 = 'deg' / Units of coordinate increment and value CTYPE1 = 'RA---TAN' / Right ascension, gnomonic projection CTYPE2 = 'DEC--TAN' / Declination, gnomonic projection CRVAL1 = 104.57797893504 / [deg] Coordinate value at reference point CRVAL2 = -74.195502593322 / [deg] Coordinate value at reference point LONPOLE = 180.0 / [deg] Native longitude of celestial pole LATPOLE = -74.195502593322 / [deg] Native latitude of celestial pole TIMESYS = 'TDB' / Time scale TIMEUNIT= 'd' / Time units DATEREF = '1858-11-17' / ISO-8601 fiducial time MJDREFI = 0.0 / [d] MJD of fiducial time, integer part MJDREFF = 0.0 / [d] MJD of fiducial time, fractional part DATE-OBS= '2019-03-27T03:30:13.832Z' / ISO-8601 time of observation MJD-OBS = 58569.145993426 / [d] MJD of observation MJD-OBS = 58569.145993426 / [d] MJD at start of observation TSTART = 1569.6467941661 / [d] Time elapsed since fiducial time at start DATE-END= '2019-03-27T04:00:13.831Z' / ISO-8601 time at end of observation MJD-END = 58569.166826748 / [d] MJD at end of observation TSTOP = 1569.6676274905 / [d] Time elapsed since fiducial time at end TELAPSE = 0.02083332443 / [d] Elapsed time (start to stop) TIMEDEL = 0.020833333333333 / [d] Time resolution TIMEPIXR= 0.5 / Reference position of timestamp in binned data RADESYS = 'ICRS' / Equatorial coordinate system """ wcs_header = fits.Header.fromstring(wcs_str, sep='\n') ffi_wcs = WCS(wcs_header) yi, xi = (1000, 1000) y, x = (10, 200) center_coord = SkyCoord(ffi_wcs.all_pix2world([[xi+x//2, yi+y//2]], 0), unit='deg')[0] ypix, xpix = [arr.flatten() for arr in np.mgrid[xi : xi + x, yi : yi + y]] world_pix = SkyCoord(*ffi_wcs.all_pix2world(xpix, ypix, 0), unit='deg') fit_wcs = fit_wcs_from_points((ypix, xpix), world_pix, proj_point='center') assert (fit_wcs.wcs.crpix.astype(int) == [1100, 1005]).all() assert fit_wcs.pixel_shape == (1199, 1009) @pytest.mark.skipif('not HAS_SCIPY') def test_issue10991(): # test issue #10991 (it just needs to run and set the user defined crval) xy = np.array([[1766.88276168, 662.96432257, 171.50212526, 120.70924648], [1706.69832901, 1788.85480559, 1216.98949653, 1307.41843381]]) world_coords = SkyCoord([(66.3542367, 22.20000162), (67.15416174, 19.18042906), (65.73375432, 17.54251555), (66.02400512, 17.44413253)], frame="icrs", unit="deg") proj_point = SkyCoord(64.67514918, 19.63389538, frame="icrs", unit="deg") fit_wcs = fit_wcs_from_points( xy=xy, world_coords=world_coords, proj_point=proj_point, projection='TAN' ) projlon = proj_point.data.lon.deg projlat = proj_point.data.lat.deg assert (fit_wcs.wcs.crval == [projlon, projlat]).all() @pytest.mark.remote_data @pytest.mark.parametrize('x_in,y_in', [[0, 0], [np.arange(5), np.arange(5)]]) def test_pixel_to_world_itrs(x_in, y_in): """Regression test for https://github.com/astropy/astropy/pull/9609""" if Version(_wcs.__version__) >= Version('7.4'): ctx = pytest.warns( FITSFixedWarning, match=r"'datfix' made the change 'Set MJD-OBS to 57982\.528524 from DATE-OBS'\.") else: ctx = nullcontext() with ctx: wcs = WCS({'NAXIS': 2, 'CTYPE1': 'TLON-CAR', 'CTYPE2': 'TLAT-CAR', 'RADESYS': 'ITRS ', 'DATE-OBS': '2017-08-17T12:41:04.444'}) # This shouldn't raise an exception. coord = wcs.pixel_to_world(x_in, y_in) # Check round trip transformation. x, y = wcs.world_to_pixel(coord) np.testing.assert_almost_equal(x, x_in) np.testing.assert_almost_equal(y, y_in) @pytest.fixture def dkist_location(): return EarthLocation(*(-5466045.25695494, -2404388.73741278, 2242133.88769004) * u.m) def test_obsgeo_cartesian(dkist_location): obstime = Time("2021-05-21T03:00:00") wcs = WCS(naxis=2) wcs.wcs.obsgeo = list(dkist_location.to_value(u.m).tolist()) + [0, 0, 0] wcs.wcs.dateobs = obstime.isot frame = obsgeo_to_frame(wcs.wcs.obsgeo, obstime) assert isinstance(frame, ITRS) assert frame.x == dkist_location.x assert frame.y == dkist_location.y assert frame.z == dkist_location.z def test_obsgeo_spherical(dkist_location): obstime = Time("2021-05-21T03:00:00") dkist_location = dkist_location.get_itrs(obstime) loc_sph = dkist_location.spherical wcs = WCS(naxis=2) wcs.wcs.obsgeo = [0, 0, 0] + [loc_sph.lon.value, loc_sph.lat.value, loc_sph.distance.value] wcs.wcs.dateobs = obstime.isot frame = obsgeo_to_frame(wcs.wcs.obsgeo, obstime) assert isinstance(frame, ITRS) assert u.allclose(frame.x, dkist_location.x) assert u.allclose(frame.y, dkist_location.y) assert u.allclose(frame.z, dkist_location.z) def test_obsgeo_infinite(dkist_location): obstime = Time("2021-05-21T03:00:00") dkist_location = dkist_location.get_itrs(obstime) loc_sph = dkist_location.spherical wcs = WCS(naxis=2) wcs.wcs.obsgeo = [1, 1, np.nan] + [loc_sph.lon.value, loc_sph.lat.value, loc_sph.distance.value] wcs.wcs.dateobs = obstime.isot wcs.wcs.set() frame = obsgeo_to_frame(wcs.wcs.obsgeo, obstime) assert isinstance(frame, ITRS) assert u.allclose(frame.x, dkist_location.x) assert u.allclose(frame.y, dkist_location.y) assert u.allclose(frame.z, dkist_location.z) @pytest.mark.parametrize("obsgeo", ([np.nan] * 6, None, [0] * 6, [54] * 5)) def test_obsgeo_invalid(obsgeo): with pytest.raises(ValueError): obsgeo_to_frame(obsgeo, None) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/test_wcs.py0000644000175100001710000014720700000000000020124 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import io import os from contextlib import nullcontext from datetime import datetime from packaging.version import Version import pytest import numpy as np from numpy.testing import ( assert_allclose, assert_array_almost_equal, assert_array_almost_equal_nulp, assert_array_equal) from astropy import wcs from astropy.wcs import _wcs # noqa from astropy import units as u from astropy.utils.data import ( get_pkg_data_filenames, get_pkg_data_contents, get_pkg_data_filename) from astropy.utils.misc import NumpyRNGContext from astropy.utils.exceptions import ( AstropyUserWarning, AstropyWarning, AstropyDeprecationWarning) from astropy.tests.helper import assert_quantity_allclose from astropy.io import fits from astropy.coordinates import SkyCoord from astropy.nddata import Cutout2D _WCSLIB_VER = Version(_wcs.__version__) # NOTE: User can choose to use system wcslib instead of bundled. def ctx_for_v71_dateref_warnings(): if _WCSLIB_VER >= Version('7.1') and _WCSLIB_VER < Version('7.3'): ctx = pytest.warns( wcs.FITSFixedWarning, match=r"'datfix' made the change 'Set DATE-REF to '1858-11-17' from MJD-REF'\.") else: ctx = nullcontext() return ctx class TestMaps: def setup(self): # get the list of the hdr files that we want to test self._file_list = list(get_pkg_data_filenames( "data/maps", pattern="*.hdr")) def test_consistency(self): # Check to see that we actually have the list we expect, so that we # do not get in a situation where the list is empty or incomplete and # the tests still seem to pass correctly. # how many do we expect to see? n_data_files = 28 assert len(self._file_list) == n_data_files, ( "test_spectra has wrong number data files: found {}, expected " " {}".format(len(self._file_list), n_data_files)) def test_maps(self): for filename in self._file_list: # use the base name of the file, so we get more useful messages # for failing tests. filename = os.path.basename(filename) # Now find the associated file in the installed wcs test directory. header = get_pkg_data_contents( os.path.join("data", "maps", filename), encoding='binary') # finally run the test. wcsobj = wcs.WCS(header) world = wcsobj.wcs_pix2world([[97, 97]], 1) assert_array_almost_equal(world, [[285.0, -66.25]], decimal=1) pix = wcsobj.wcs_world2pix([[285.0, -66.25]], 1) assert_array_almost_equal(pix, [[97, 97]], decimal=0) class TestSpectra: def setup(self): self._file_list = list(get_pkg_data_filenames("data/spectra", pattern="*.hdr")) def test_consistency(self): # Check to see that we actually have the list we expect, so that we # do not get in a situation where the list is empty or incomplete and # the tests still seem to pass correctly. # how many do we expect to see? n_data_files = 6 assert len(self._file_list) == n_data_files, ( "test_spectra has wrong number data files: found {}, expected " " {}".format(len(self._file_list), n_data_files)) def test_spectra(self): for filename in self._file_list: # use the base name of the file, so we get more useful messages # for failing tests. filename = os.path.basename(filename) # Now find the associated file in the installed wcs test directory. header = get_pkg_data_contents( os.path.join("data", "spectra", filename), encoding='binary') # finally run the test. if _WCSLIB_VER >= Version('7.4'): ctx = pytest.warns( wcs.FITSFixedWarning, match=r"'datfix' made the change 'Set MJD-OBS to 53925\.853472 from DATE-OBS'\.") # noqa else: ctx = nullcontext() with ctx: all_wcs = wcs.find_all_wcs(header) assert len(all_wcs) == 9 def test_fixes(): """ From github issue #36 """ header = get_pkg_data_contents('data/nonstandard_units.hdr', encoding='binary') with pytest.raises(wcs.InvalidTransformError), pytest.warns(wcs.FITSFixedWarning) as w: wcs.WCS(header, translate_units='dhs') if Version('7.4') <= _WCSLIB_VER < Version('7.6'): assert len(w) == 3 assert "'datfix' made the change 'Success'." in str(w.pop().message) else: assert len(w) == 2 first_wmsg = str(w[0].message) assert 'unitfix' in first_wmsg and 'Hz' in first_wmsg and 'M/S' in first_wmsg assert 'plane angle' in str(w[1].message) and 'm/s' in str(w[1].message) # Ignore "PV2_2 = 0.209028857410973 invalid keyvalue" warning seen on Windows. @pytest.mark.filterwarnings(r'ignore:PV2_2') def test_outside_sky(): """ From github issue #107 """ header = get_pkg_data_contents( 'data/outside_sky.hdr', encoding='binary') w = wcs.WCS(header) assert np.all(np.isnan(w.wcs_pix2world([[100., 500.]], 0))) # outside sky assert np.all(np.isnan(w.wcs_pix2world([[200., 200.]], 0))) # outside sky assert not np.any(np.isnan(w.wcs_pix2world([[1000., 1000.]], 0))) def test_pix2world(): """ From github issue #1463 """ # TODO: write this to test the expected output behavior of pix2world, # currently this just makes sure it doesn't error out in unexpected ways # (and compares `wcs.pc` and `result` values?) filename = get_pkg_data_filename('data/sip2.fits') with pytest.warns(wcs.FITSFixedWarning) as caught_warnings: # this raises a warning unimportant for this testing the pix2world # FITSFixedWarning(u'The WCS transformation has more axes (2) than # the image it is associated with (0)') ww = wcs.WCS(filename) # might as well monitor for changing behavior if Version('7.4') <= _WCSLIB_VER < Version('7.6'): assert len(caught_warnings) == 2 else: assert len(caught_warnings) == 1 n = 3 pixels = (np.arange(n) * np.ones((2, n))).T result = ww.wcs_pix2world(pixels, 0, ra_dec_order=True) # Catch #2791 ww.wcs_pix2world(pixels[..., 0], pixels[..., 1], 0, ra_dec_order=True) # assuming that the data of sip2.fits doesn't change answer = np.array([[0.00024976, 0.00023018], [0.00023043, -0.00024997]]) assert np.allclose(ww.wcs.pc, answer, atol=1.e-8) answer = np.array([[202.39265216, 47.17756518], [202.39335826, 47.17754619], [202.39406436, 47.1775272]]) assert np.allclose(result, answer, atol=1.e-8, rtol=1.e-10) def test_load_fits_path(): fits_name = get_pkg_data_filename('data/sip.fits') with pytest.warns(wcs.FITSFixedWarning): wcs.WCS(fits_name) def test_dict_init(): """ Test that WCS can be initialized with a dict-like object """ # Dictionary with no actual WCS, returns identity transform with ctx_for_v71_dateref_warnings(): w = wcs.WCS({}) xp, yp = w.wcs_world2pix(41., 2., 1) assert_array_almost_equal_nulp(xp, 41., 10) assert_array_almost_equal_nulp(yp, 2., 10) # Valid WCS hdr = { 'CTYPE1': 'GLON-CAR', 'CTYPE2': 'GLAT-CAR', 'CUNIT1': 'deg', 'CUNIT2': 'deg', 'CRPIX1': 1, 'CRPIX2': 1, 'CRVAL1': 40., 'CRVAL2': 0., 'CDELT1': -0.1, 'CDELT2': 0.1 } if _WCSLIB_VER >= Version('7.1'): hdr['DATEREF'] = '1858-11-17' if _WCSLIB_VER >= Version('7.4'): ctx = pytest.warns( wcs.wcs.FITSFixedWarning, match=r"'datfix' made the change 'Set MJDREF to 0\.000000 from DATEREF'\.") else: ctx = nullcontext() with ctx: w = wcs.WCS(hdr) xp, yp = w.wcs_world2pix(41., 2., 0) assert_array_almost_equal_nulp(xp, -10., 10) assert_array_almost_equal_nulp(yp, 20., 10) def test_extra_kwarg(): """ Issue #444 """ w = wcs.WCS() with NumpyRNGContext(123456789): data = np.random.rand(100, 2) with pytest.raises(TypeError): w.wcs_pix2world(data, origin=1) def test_3d_shapes(): """ Issue #444 """ w = wcs.WCS(naxis=3) with NumpyRNGContext(123456789): data = np.random.rand(100, 3) result = w.wcs_pix2world(data, 1) assert result.shape == (100, 3) result = w.wcs_pix2world( data[..., 0], data[..., 1], data[..., 2], 1) assert len(result) == 3 def test_preserve_shape(): w = wcs.WCS(naxis=2) x = np.random.random((2, 3, 4)) y = np.random.random((2, 3, 4)) xw, yw = w.wcs_pix2world(x, y, 1) assert xw.shape == (2, 3, 4) assert yw.shape == (2, 3, 4) xp, yp = w.wcs_world2pix(x, y, 1) assert xp.shape == (2, 3, 4) assert yp.shape == (2, 3, 4) def test_broadcasting(): w = wcs.WCS(naxis=2) x = np.random.random((2, 3, 4)) y = 1 xp, yp = w.wcs_world2pix(x, y, 1) assert xp.shape == (2, 3, 4) assert yp.shape == (2, 3, 4) def test_shape_mismatch(): w = wcs.WCS(naxis=2) x = np.random.random((2, 3, 4)) y = np.random.random((3, 2, 4)) with pytest.raises(ValueError) as exc: xw, yw = w.wcs_pix2world(x, y, 1) assert exc.value.args[0] == "Coordinate arrays are not broadcastable to each other" with pytest.raises(ValueError) as exc: xp, yp = w.wcs_world2pix(x, y, 1) assert exc.value.args[0] == "Coordinate arrays are not broadcastable to each other" # There are some ambiguities that need to be worked around when # naxis == 1 w = wcs.WCS(naxis=1) x = np.random.random((42, 1)) xw = w.wcs_pix2world(x, 1) assert xw.shape == (42, 1) x = np.random.random((42,)) xw, = w.wcs_pix2world(x, 1) assert xw.shape == (42,) def test_invalid_shape(): # Issue #1395 w = wcs.WCS(naxis=2) xy = np.random.random((2, 3)) with pytest.raises(ValueError) as exc: w.wcs_pix2world(xy, 1) assert exc.value.args[0] == 'When providing two arguments, the array must be of shape (N, 2)' xy = np.random.random((2, 1)) with pytest.raises(ValueError) as exc: w.wcs_pix2world(xy, 1) assert exc.value.args[0] == 'When providing two arguments, the array must be of shape (N, 2)' def test_warning_about_defunct_keywords(): header = get_pkg_data_contents('data/defunct_keywords.hdr', encoding='binary') if Version('7.4') <= _WCSLIB_VER < Version('7.6'): n_warn = 5 else: n_warn = 4 # Make sure the warnings come out every time... for _ in range(2): with pytest.warns(wcs.FITSFixedWarning) as w: wcs.WCS(header) assert len(w) == n_warn # 7.4 adds a fifth warning "'datfix' made the change 'Success'." for item in w[:4]: assert 'PCi_ja' in str(item.message) def test_warning_about_defunct_keywords_exception(): header = get_pkg_data_contents('data/defunct_keywords.hdr', encoding='binary') with pytest.warns(wcs.FITSFixedWarning): wcs.WCS(header) def test_to_header_string(): hdrstr = ( "WCSAXES = 2 / Number of coordinate axes ", "CRPIX1 = 0.0 / Pixel coordinate of reference point ", "CRPIX2 = 0.0 / Pixel coordinate of reference point ", "CDELT1 = 1.0 / Coordinate increment at reference point ", "CDELT2 = 1.0 / Coordinate increment at reference point ", "CRVAL1 = 0.0 / Coordinate value at reference point ", "CRVAL2 = 0.0 / Coordinate value at reference point ", "LATPOLE = 90.0 / [deg] Native latitude of celestial pole ", ) if _WCSLIB_VER >= Version('7.3'): hdrstr += ( "MJDREF = 0.0 / [d] MJD of fiducial time ", ) elif _WCSLIB_VER >= Version('7.1'): hdrstr += ( "DATEREF = '1858-11-17' / ISO-8601 fiducial time ", "MJDREFI = 0.0 / [d] MJD of fiducial time, integer part ", "MJDREFF = 0.0 / [d] MJD of fiducial time, fractional part " ) hdrstr += ("END", ) header_string = ''.join(hdrstr) w = wcs.WCS() h0 = fits.Header.fromstring(w.to_header_string().strip()) if 'COMMENT' in h0: del h0['COMMENT'] if '' in h0: del h0[''] h1 = fits.Header.fromstring(header_string.strip()) assert dict(h0) == dict(h1) def test_to_fits(): nrec = 11 if _WCSLIB_VER >= Version('7.1') else 8 if _WCSLIB_VER < Version('7.1'): nrec = 8 elif _WCSLIB_VER < Version('7.3'): nrec = 11 else: nrec = 9 w = wcs.WCS() header_string = w.to_header() wfits = w.to_fits() assert isinstance(wfits, fits.HDUList) assert isinstance(wfits[0], fits.PrimaryHDU) assert header_string == wfits[0].header[-nrec:] def test_to_header_warning(): fits_name = get_pkg_data_filename('data/sip.fits') with pytest.warns(wcs.FITSFixedWarning): x = wcs.WCS(fits_name) with pytest.warns(AstropyWarning, match='A_ORDER') as w: x.to_header() assert len(w) == 1 def test_no_comments_in_header(): w = wcs.WCS() header = w.to_header() assert w.wcs.alt not in header assert 'COMMENT' + w.wcs.alt.strip() not in header assert 'COMMENT' not in header wkey = 'P' header = w.to_header(key=wkey) assert wkey not in header assert 'COMMENT' not in header assert 'COMMENT' + w.wcs.alt.strip() not in header def test_find_all_wcs_crash(): """ Causes a double free without a recent fix in wcslib_wrap.C """ with open(get_pkg_data_filename("data/too_many_pv.hdr")) as fd: header = fd.read() # We have to set fix=False here, because one of the fixing tasks is to # remove redundant SCAMP distortion parameters when SIP distortion # parameters are also present. with pytest.raises(wcs.InvalidTransformError), pytest.warns(wcs.FITSFixedWarning): wcs.find_all_wcs(header, fix=False) # NOTE: Warning bubbles up from C layer during wcs.validate() and # is hard to catch, so we just ignore it. @pytest.mark.filterwarnings("ignore") def test_validate(): results = wcs.validate(get_pkg_data_filename("data/validate.fits")) results_txt = sorted(set([x.strip() for x in repr(results).splitlines()])) if _WCSLIB_VER >= Version('7.6'): filename = 'data/validate.7.6.txt' elif _WCSLIB_VER >= Version('7.4'): filename = 'data/validate.7.4.txt' elif _WCSLIB_VER >= Version('6.0'): filename = 'data/validate.6.txt' elif _WCSLIB_VER >= Version('5.13'): filename = 'data/validate.5.13.txt' elif _WCSLIB_VER >= Version('5.0'): filename = 'data/validate.5.0.txt' else: filename = 'data/validate.txt' with open(get_pkg_data_filename(filename), "r") as fd: lines = fd.readlines() assert sorted(set([x.strip() for x in lines])) == results_txt def test_validate_with_2_wcses(): # From Issue #2053 with pytest.warns(AstropyUserWarning): results = wcs.validate(get_pkg_data_filename("data/2wcses.hdr")) assert "WCS key 'A':" in str(results) def test_crpix_maps_to_crval(): twcs = wcs.WCS(naxis=2) twcs.wcs.crval = [251.29, 57.58] twcs.wcs.cdelt = [1, 1] twcs.wcs.crpix = [507, 507] twcs.wcs.pc = np.array([[7.7e-6, 3.3e-5], [3.7e-5, -6.8e-6]]) twcs._naxis = [1014, 1014] twcs.wcs.ctype = ['RA---TAN-SIP', 'DEC--TAN-SIP'] a = np.array( [[0, 0, 5.33092692e-08, 3.73753773e-11, -2.02111473e-13], [0, 2.44084308e-05, 2.81394789e-11, 5.17856895e-13, 0.0], [-2.41334657e-07, 1.29289255e-10, 2.35753629e-14, 0.0, 0.0], [-2.37162007e-10, 5.43714947e-13, 0.0, 0.0, 0.0], [-2.81029767e-13, 0.0, 0.0, 0.0, 0.0]] ) b = np.array( [[0, 0, 2.99270374e-05, -2.38136074e-10, 7.23205168e-13], [0, -1.71073858e-07, 6.31243431e-11, -5.16744347e-14, 0.0], [6.95458963e-06, -3.08278961e-10, -1.75800917e-13, 0.0, 0.0], [3.51974159e-11, 5.60993016e-14, 0.0, 0.0, 0.0], [-5.92438525e-13, 0.0, 0.0, 0.0, 0.0]] ) twcs.sip = wcs.Sip(a, b, None, None, twcs.wcs.crpix) twcs.wcs.set() pscale = np.sqrt(wcs.utils.proj_plane_pixel_area(twcs)) # test that CRPIX maps to CRVAL: assert_allclose( twcs.wcs_pix2world(*twcs.wcs.crpix, 1), twcs.wcs.crval, rtol=0.0, atol=1e-6 * pscale ) # test that CRPIX maps to CRVAL: assert_allclose( twcs.all_pix2world(*twcs.wcs.crpix, 1), twcs.wcs.crval, rtol=0.0, atol=1e-6 * pscale ) def test_all_world2pix(fname=None, ext=0, tolerance=1.0e-4, origin=0, random_npts=25000, adaptive=False, maxiter=20, detect_divergence=True): """Test all_world2pix, iterative inverse of all_pix2world""" # Open test FITS file: if fname is None: fname = get_pkg_data_filename('data/j94f05bgq_flt.fits') ext = ('SCI', 1) if not os.path.isfile(fname): raise OSError(f"Input file '{fname:s}' to 'test_all_world2pix' not found.") h = fits.open(fname) w = wcs.WCS(h[ext].header, h) h.close() del h crpix = w.wcs.crpix ncoord = crpix.shape[0] # Assume that CRPIX is at the center of the image and that the image has # a power-of-2 number of pixels along each axis. Only use the central # 1/64 for this testing purpose: naxesi_l = list((7. / 16 * crpix).astype(int)) naxesi_u = list((9. / 16 * crpix).astype(int)) # Generate integer indices of pixels (image grid): img_pix = np.dstack([i.flatten() for i in np.meshgrid(*map(range, naxesi_l, naxesi_u))])[0] # Generage random data (in image coordinates): with NumpyRNGContext(123456789): rnd_pix = np.random.rand(random_npts, ncoord) # Scale random data to cover the central part of the image mwidth = 2 * (crpix * 1. / 8) rnd_pix = crpix - 0.5 * mwidth + (mwidth - 1) * rnd_pix # Reference pixel coordinates in image coordinate system (CS): test_pix = np.append(img_pix, rnd_pix, axis=0) # Reference pixel coordinates in sky CS using forward transformation: all_world = w.all_pix2world(test_pix, origin) try: runtime_begin = datetime.now() # Apply the inverse iterative process to pixels in world coordinates # to recover the pixel coordinates in image space. all_pix = w.all_world2pix( all_world, origin, tolerance=tolerance, adaptive=adaptive, maxiter=maxiter, detect_divergence=detect_divergence) runtime_end = datetime.now() except wcs.wcs.NoConvergence as e: runtime_end = datetime.now() ndiv = 0 if e.divergent is not None: ndiv = e.divergent.shape[0] print(f"There are {ndiv} diverging solutions.") print(f"Indices of diverging solutions:\n{e.divergent}") print(f"Diverging solutions:\n{e.best_solution[e.divergent]}\n") print("Mean radius of the diverging solutions: {}" .format(np.mean( np.linalg.norm(e.best_solution[e.divergent], axis=1)))) print("Mean accuracy of the diverging solutions: {}\n" .format(np.mean( np.linalg.norm(e.accuracy[e.divergent], axis=1)))) else: print("There are no diverging solutions.") nslow = 0 if e.slow_conv is not None: nslow = e.slow_conv.shape[0] print(f"There are {nslow} slowly converging solutions.") print(f"Indices of slowly converging solutions:\n{e.slow_conv}") print(f"Slowly converging solutions:\n{e.best_solution[e.slow_conv]}\n") else: print("There are no slowly converging solutions.\n") print("There are {} converged solutions." .format(e.best_solution.shape[0] - ndiv - nslow)) print(f"Best solutions (all points):\n{e.best_solution}") print(f"Accuracy:\n{e.accuracy}\n") print("\nFinished running 'test_all_world2pix' with errors.\n" "ERROR: {}\nRun time: {}\n" .format(e.args[0], runtime_end - runtime_begin)) raise e # Compute differences between reference pixel coordinates and # pixel coordinates (in image space) recovered from reference # pixels in world coordinates: errors = np.sqrt(np.sum(np.power(all_pix - test_pix, 2), axis=1)) meanerr = np.mean(errors) maxerr = np.amax(errors) print("\nFinished running 'test_all_world2pix'.\n" "Mean error = {:e} (Max error = {:e})\n" "Run time: {}\n" .format(meanerr, maxerr, runtime_end - runtime_begin)) assert(maxerr < 2.0 * tolerance) def test_scamp_sip_distortion_parameters(): """ Test parsing of WCS parameters with redundant SIP and SCAMP distortion parameters. """ header = get_pkg_data_contents('data/validate.fits', encoding='binary') with pytest.warns(wcs.FITSFixedWarning): w = wcs.WCS(header) # Just check that this doesn't raise an exception. w.all_pix2world(0, 0, 0) def test_fixes2(): """ From github issue #1854 """ header = get_pkg_data_contents( 'data/nonstandard_units.hdr', encoding='binary') with pytest.raises(wcs.InvalidTransformError): wcs.WCS(header, fix=False) def test_unit_normalization(): """ From github issue #1918 """ header = get_pkg_data_contents( 'data/unit.hdr', encoding='binary') w = wcs.WCS(header) assert w.wcs.cunit[2] == 'm/s' def test_footprint_to_file(tmpdir): """ From github issue #1912 """ # Arbitrary keywords from real data hdr = {'CTYPE1': 'RA---ZPN', 'CRUNIT1': 'deg', 'CRPIX1': -3.3495999e+02, 'CRVAL1': 3.185790700000e+02, 'CTYPE2': 'DEC--ZPN', 'CRUNIT2': 'deg', 'CRPIX2': 3.0453999e+03, 'CRVAL2': 4.388538000000e+01, 'PV2_1': 1., 'PV2_3': 220., 'NAXIS1': 2048, 'NAXIS2': 1024} w = wcs.WCS(hdr) testfile = str(tmpdir.join('test.txt')) w.footprint_to_file(testfile) with open(testfile, 'r') as f: lines = f.readlines() assert len(lines) == 4 assert lines[2] == 'ICRS\n' assert 'color=green' in lines[3] w.footprint_to_file(testfile, coordsys='FK5', color='red') with open(testfile, 'r') as f: lines = f.readlines() assert len(lines) == 4 assert lines[2] == 'FK5\n' assert 'color=red' in lines[3] with pytest.raises(ValueError): w.footprint_to_file(testfile, coordsys='FOO') del hdr['NAXIS1'] del hdr['NAXIS2'] w = wcs.WCS(hdr) with pytest.warns(AstropyUserWarning): w.footprint_to_file(testfile) # Ignore FITSFixedWarning about keyrecords following the END keyrecord were # ignored, which comes from src/astropy_wcs.c . Only a blind catch like this # seems to work when pytest warnings are turned into exceptions. @pytest.mark.filterwarnings('ignore') def test_validate_faulty_wcs(): """ From github issue #2053 """ h = fits.Header() # Illegal WCS: h['RADESYSA'] = 'ICRS' h['PV2_1'] = 1.0 hdu = fits.PrimaryHDU([[0]], header=h) hdulist = fits.HDUList([hdu]) # Check that this doesn't raise a NameError exception wcs.validate(hdulist) def test_error_message(): header = get_pkg_data_contents( 'data/invalid_header.hdr', encoding='binary') with pytest.raises(wcs.InvalidTransformError): # Both lines are in here, because 0.4 calls .set within WCS.__init__, # whereas 0.3 and earlier did not. with pytest.warns(wcs.FITSFixedWarning): w = wcs.WCS(header, _do_set=False) w.all_pix2world([[536.0, 894.0]], 0) def test_out_of_bounds(): # See #2107 header = get_pkg_data_contents('data/zpn-hole.hdr', encoding='binary') w = wcs.WCS(header) ra, dec = w.wcs_pix2world(110, 110, 0) assert np.isnan(ra) assert np.isnan(dec) ra, dec = w.wcs_pix2world(0, 0, 0) assert not np.isnan(ra) assert not np.isnan(dec) def test_calc_footprint_1(): fits = get_pkg_data_filename('data/sip.fits') with pytest.warns(wcs.FITSFixedWarning): w = wcs.WCS(fits) axes = (1000, 1051) ref = np.array([[202.39314493, 47.17753352], [202.71885939, 46.94630488], [202.94631893, 47.15855022], [202.72053428, 47.37893142]]) footprint = w.calc_footprint(axes=axes) assert_allclose(footprint, ref) def test_calc_footprint_2(): """ Test calc_footprint without distortion. """ fits = get_pkg_data_filename('data/sip.fits') with pytest.warns(wcs.FITSFixedWarning): w = wcs.WCS(fits) axes = (1000, 1051) ref = np.array([[202.39265216, 47.17756518], [202.7469062, 46.91483312], [203.11487481, 47.14359319], [202.76092671, 47.40745948]]) footprint = w.calc_footprint(axes=axes, undistort=False) assert_allclose(footprint, ref) def test_calc_footprint_3(): """ Test calc_footprint with corner of the pixel.""" w = wcs.WCS() w.wcs.ctype = ["GLON-CAR", "GLAT-CAR"] w.wcs.crpix = [1.5, 5.5] w.wcs.cdelt = [-0.1, 0.1] axes = (2, 10) ref = np.array([[0.1, -0.5], [0.1, 0.5], [359.9, 0.5], [359.9, -0.5]]) footprint = w.calc_footprint(axes=axes, undistort=False, center=False) assert_allclose(footprint, ref) def test_sip(): # See #2107 header = get_pkg_data_contents('data/irac_sip.hdr', encoding='binary') w = wcs.WCS(header) x0, y0 = w.sip_pix2foc(200, 200, 0) assert_allclose(72, x0, 1e-3) assert_allclose(72, y0, 1e-3) x1, y1 = w.sip_foc2pix(x0, y0, 0) assert_allclose(200, x1, 1e-3) assert_allclose(200, y1, 1e-3) def test_sub_3d_with_sip(): # See #10527 header = get_pkg_data_contents('data/irac_sip.hdr', encoding='binary') header = fits.Header.fromstring(header) header['NAXIS'] = 3 header.set('NAXIS3', 64, after=header.index('NAXIS2')) w = wcs.WCS(header, naxis=2) assert w.naxis == 2 def test_printwcs(capsys): """ Just make sure that it runs """ h = get_pkg_data_contents( 'data/spectra/orion-freq-1.hdr', encoding='binary') with pytest.warns(wcs.FITSFixedWarning): w = wcs.WCS(h) w.printwcs() captured = capsys.readouterr() assert 'WCS Keywords' in captured.out h = get_pkg_data_contents('data/3d_cd.hdr', encoding='binary') w = wcs.WCS(h) w.printwcs() captured = capsys.readouterr() assert 'WCS Keywords' in captured.out def test_invalid_spherical(): header = """ SIMPLE = T / conforms to FITS standard BITPIX = 8 / array data type WCSAXES = 2 / no comment CTYPE1 = 'RA---TAN' / TAN (gnomic) projection CTYPE2 = 'DEC--TAN' / TAN (gnomic) projection EQUINOX = 2000.0 / Equatorial coordinates definition (yr) LONPOLE = 180.0 / no comment LATPOLE = 0.0 / no comment CRVAL1 = 16.0531567459 / RA of reference point CRVAL2 = 23.1148929108 / DEC of reference point CRPIX1 = 2129 / X reference pixel CRPIX2 = 1417 / Y reference pixel CUNIT1 = 'deg ' / X pixel scale units CUNIT2 = 'deg ' / Y pixel scale units CD1_1 = -0.00912247310646 / Transformation matrix CD1_2 = -0.00250608809647 / no comment CD2_1 = 0.00250608809647 / no comment CD2_2 = -0.00912247310646 / no comment IMAGEW = 4256 / Image width, in pixels. IMAGEH = 2832 / Image height, in pixels. """ f = io.StringIO(header) header = fits.Header.fromtextfile(f) w = wcs.WCS(header) x, y = w.wcs_world2pix(211, -26, 0) assert np.isnan(x) and np.isnan(y) def test_no_iteration(): # Regression test for #3066 w = wcs.WCS(naxis=2) with pytest.raises(TypeError) as exc: iter(w) assert exc.value.args[0] == "'WCS' object is not iterable" class NewWCS(wcs.WCS): pass w = NewWCS(naxis=2) with pytest.raises(TypeError) as exc: iter(w) assert exc.value.args[0] == "'NewWCS' object is not iterable" @pytest.mark.skipif('_wcs.__version__[0] < "5"', reason="TPV only works with wcslib 5.x or later") def test_sip_tpv_agreement(): sip_header = get_pkg_data_contents( os.path.join("data", "siponly.hdr"), encoding='binary') tpv_header = get_pkg_data_contents( os.path.join("data", "tpvonly.hdr"), encoding='binary') with pytest.warns(wcs.FITSFixedWarning): w_sip = wcs.WCS(sip_header) w_tpv = wcs.WCS(tpv_header) assert_array_almost_equal( w_sip.all_pix2world([w_sip.wcs.crpix], 1), w_tpv.all_pix2world([w_tpv.wcs.crpix], 1)) w_sip2 = wcs.WCS(w_sip.to_header()) w_tpv2 = wcs.WCS(w_tpv.to_header()) assert_array_almost_equal( w_sip.all_pix2world([w_sip.wcs.crpix], 1), w_sip2.all_pix2world([w_sip.wcs.crpix], 1)) assert_array_almost_equal( w_tpv.all_pix2world([w_sip.wcs.crpix], 1), w_tpv2.all_pix2world([w_sip.wcs.crpix], 1)) assert_array_almost_equal( w_sip2.all_pix2world([w_sip.wcs.crpix], 1), w_tpv2.all_pix2world([w_tpv.wcs.crpix], 1)) @pytest.mark.skipif('_wcs.__version__[0] < "5"', reason="TPV only works with wcslib 5.x or later") def test_tpv_copy(): # See #3904 tpv_header = get_pkg_data_contents( os.path.join("data", "tpvonly.hdr"), encoding='binary') with pytest.warns(wcs.FITSFixedWarning): w_tpv = wcs.WCS(tpv_header) ra, dec = w_tpv.wcs_pix2world([0, 100, 200], [0, -100, 200], 0) assert ra[0] != ra[1] and ra[1] != ra[2] assert dec[0] != dec[1] and dec[1] != dec[2] def test_hst_wcs(): path = get_pkg_data_filename("data/dist_lookup.fits.gz") with fits.open(path) as hdulist: # wcslib will complain about the distortion parameters if they # weren't correctly deleted from the header w = wcs.WCS(hdulist[1].header, hdulist) # Check pixel scale and area assert_quantity_allclose( w.proj_plane_pixel_scales(), [1.38484378e-05, 1.39758488e-05] * u.deg) assert_quantity_allclose( w.proj_plane_pixel_area(), 1.93085492e-10 * (u.deg * u.deg)) # Exercise the main transformation functions, mainly just for # coverage w.p4_pix2foc([0, 100, 200], [0, -100, 200], 0) w.det2im([0, 100, 200], [0, -100, 200], 0) w.cpdis1 = w.cpdis1 w.cpdis2 = w.cpdis2 w.det2im1 = w.det2im1 w.det2im2 = w.det2im2 w.sip = w.sip w.cpdis1.cdelt = w.cpdis1.cdelt w.cpdis1.crpix = w.cpdis1.crpix w.cpdis1.crval = w.cpdis1.crval w.cpdis1.data = w.cpdis1.data assert w.sip.a_order == 4 assert w.sip.b_order == 4 assert w.sip.ap_order == 0 assert w.sip.bp_order == 0 assert_array_equal(w.sip.crpix, [2048., 1024.]) wcs.WCS(hdulist[1].header, hdulist) def test_cpdis_comments(): path = get_pkg_data_filename("data/dist_lookup.fits.gz") f = fits.open(path) w = wcs.WCS(f[1].header, f) hdr = w.to_fits()[0].header f.close() wcscards = list(hdr['CPDIS*'].cards) + list(hdr['DP*'].cards) wcsdict = {k: (v, c) for k, v, c in wcscards} refcards = [ ('CPDIS1', 'LOOKUP', 'Prior distortion function type'), ('DP1.EXTVER', 1.0, 'Version number of WCSDVARR extension'), ('DP1.NAXES', 2.0, 'Number of independent variables in CPDIS function'), ('DP1.AXIS.1', 1.0, 'Axis number of the 1st variable in a CPDIS function'), ('DP1.AXIS.2', 2.0, 'Axis number of the 2nd variable in a CPDIS function'), ('CPDIS2', 'LOOKUP', 'Prior distortion function type'), ('DP2.EXTVER', 2.0, 'Version number of WCSDVARR extension'), ('DP2.NAXES', 2.0, 'Number of independent variables in CPDIS function'), ('DP2.AXIS.1', 1.0, 'Axis number of the 1st variable in a CPDIS function'), ('DP2.AXIS.2', 2.0, 'Axis number of the 2nd variable in a CPDIS function'), ] assert len(wcsdict) == len(refcards) for k, v, c in refcards: assert wcsdict[k] == (v, c) def test_d2im_comments(): path = get_pkg_data_filename("data/ie6d07ujq_wcs.fits") f = fits.open(path) with pytest.warns(wcs.FITSFixedWarning): w = wcs.WCS(f[0].header, f) f.close() wcscards = list(w.to_fits()[0].header['D2IM*'].cards) wcsdict = {k: (v, c) for k, v, c in wcscards} refcards = [ ('D2IMDIS1', 'LOOKUP', 'Detector to image correction type'), ('D2IM1.EXTVER', 1.0, 'Version number of WCSDVARR extension'), ('D2IM1.NAXES', 2.0, 'Number of independent variables in D2IM function'), ('D2IM1.AXIS.1', 1.0, 'Axis number of the 1st variable in a D2IM function'), ('D2IM1.AXIS.2', 2.0, 'Axis number of the 2nd variable in a D2IM function'), ('D2IMDIS2', 'LOOKUP', 'Detector to image correction type'), ('D2IM2.EXTVER', 2.0, 'Version number of WCSDVARR extension'), ('D2IM2.NAXES', 2.0, 'Number of independent variables in D2IM function'), ('D2IM2.AXIS.1', 1.0, 'Axis number of the 1st variable in a D2IM function'), ('D2IM2.AXIS.2', 2.0, 'Axis number of the 2nd variable in a D2IM function'), # ('D2IMERR1', 0.049, 'Maximum error of D2IM correction for axis 1'), # ('D2IMERR2', 0.035, 'Maximum error of D2IM correction for axis 2'), # ('D2IMEXT', 'iref$y7b1516hi_d2i.fits', ''), ] assert len(wcsdict) == len(refcards) for k, v, c in refcards: assert wcsdict[k] == (v, c) def test_sip_broken(): # This header caused wcslib to segfault because it has a SIP # specification in a non-default keyword hdr = get_pkg_data_contents("data/sip-broken.hdr") wcs.WCS(hdr) def test_no_truncate_crval(): """ Regression test for https://github.com/astropy/astropy/issues/4612 """ w = wcs.WCS(naxis=3) w.wcs.crval = [50, 50, 2.12345678e11] w.wcs.cdelt = [1e-3, 1e-3, 1e8] w.wcs.ctype = ['RA---TAN', 'DEC--TAN', 'FREQ'] w.wcs.set() header = w.to_header() for ii in range(3): assert header[f'CRVAL{ii + 1}'] == w.wcs.crval[ii] assert header[f'CDELT{ii + 1}'] == w.wcs.cdelt[ii] def test_no_truncate_crval_try2(): """ Regression test for https://github.com/astropy/astropy/issues/4612 """ w = wcs.WCS(naxis=3) w.wcs.crval = [50, 50, 2.12345678e11] w.wcs.cdelt = [1e-5, 1e-5, 1e5] w.wcs.ctype = ['RA---SIN', 'DEC--SIN', 'FREQ'] w.wcs.cunit = ['deg', 'deg', 'Hz'] w.wcs.crpix = [1, 1, 1] w.wcs.restfrq = 2.34e11 w.wcs.set() header = w.to_header() for ii in range(3): assert header[f'CRVAL{ii + 1}'] == w.wcs.crval[ii] assert header[f'CDELT{ii + 1}'] == w.wcs.cdelt[ii] def test_no_truncate_crval_p17(): """ Regression test for https://github.com/astropy/astropy/issues/5162 """ w = wcs.WCS(naxis=2) w.wcs.crval = [50.1234567890123456, 50.1234567890123456] w.wcs.cdelt = [1e-3, 1e-3] w.wcs.ctype = ['RA---TAN', 'DEC--TAN'] w.wcs.set() header = w.to_header() assert header['CRVAL1'] != w.wcs.crval[0] assert header['CRVAL2'] != w.wcs.crval[1] header = w.to_header(relax=wcs.WCSHDO_P17) assert header['CRVAL1'] == w.wcs.crval[0] assert header['CRVAL2'] == w.wcs.crval[1] def test_no_truncate_using_compare(): """ Regression test for https://github.com/astropy/astropy/issues/4612 This one uses WCS.wcs.compare and some slightly different values """ w = wcs.WCS(naxis=3) w.wcs.crval = [2.409303333333E+02, 50, 2.12345678e11] w.wcs.cdelt = [1e-3, 1e-3, 1e8] w.wcs.ctype = ['RA---TAN', 'DEC--TAN', 'FREQ'] w.wcs.set() w2 = wcs.WCS(w.to_header()) w.wcs.compare(w2.wcs) def test_passing_ImageHDU(): """ Passing ImageHDU or PrimaryHDU and comparing it with wcs initialized from header. For #4493. """ path = get_pkg_data_filename('data/validate.fits') with fits.open(path) as hdulist: with pytest.warns(wcs.FITSFixedWarning): wcs_hdu = wcs.WCS(hdulist[0]) wcs_header = wcs.WCS(hdulist[0].header) assert wcs_hdu.wcs.compare(wcs_header.wcs) wcs_hdu = wcs.WCS(hdulist[1]) wcs_header = wcs.WCS(hdulist[1].header) assert wcs_hdu.wcs.compare(wcs_header.wcs) def test_inconsistent_sip(): """ Test for #4814 """ hdr = get_pkg_data_contents("data/sip-broken.hdr") ctx = ctx_for_v71_dateref_warnings() with ctx: w = wcs.WCS(hdr) with pytest.warns(AstropyWarning): newhdr = w.to_header(relax=None) # CTYPE should not include "-SIP" if relax is None with ctx: wnew = wcs.WCS(newhdr) assert all(not ctyp.endswith('-SIP') for ctyp in wnew.wcs.ctype) newhdr = w.to_header(relax=False) assert 'A_0_2' not in newhdr # CTYPE should not include "-SIP" if relax is False with ctx: wnew = wcs.WCS(newhdr) assert all(not ctyp.endswith('-SIP') for ctyp in wnew.wcs.ctype) with pytest.warns(AstropyWarning): newhdr = w.to_header(key="C") assert 'A_0_2' not in newhdr # Test writing header with a different key with ctx: wnew = wcs.WCS(newhdr, key='C') assert all(not ctyp.endswith('-SIP') for ctyp in wnew.wcs.ctype) with pytest.warns(AstropyWarning): newhdr = w.to_header(key=" ") # Test writing a primary WCS to header with ctx: wnew = wcs.WCS(newhdr) assert all(not ctyp.endswith('-SIP') for ctyp in wnew.wcs.ctype) # Test that "-SIP" is kept into CTYPE if relax=True and # "-SIP" was in the original header newhdr = w.to_header(relax=True) with ctx: wnew = wcs.WCS(newhdr) assert all(ctyp.endswith('-SIP') for ctyp in wnew.wcs.ctype) assert 'A_0_2' in newhdr # Test that SIP coefficients are also written out. assert wnew.sip is not None # ######### broken header ########### # Test that "-SIP" is added to CTYPE if relax=True and # "-SIP" was not in the original header but SIP coefficients # are present. with ctx: w = wcs.WCS(hdr) w.wcs.ctype = ['RA---TAN', 'DEC--TAN'] newhdr = w.to_header(relax=True) with ctx: wnew = wcs.WCS(newhdr) assert all(ctyp.endswith('-SIP') for ctyp in wnew.wcs.ctype) def test_bounds_check(): """Test for #4957""" w = wcs.WCS(naxis=2) w.wcs.ctype = ["RA---CAR", "DEC--CAR"] w.wcs.cdelt = [10, 10] w.wcs.crval = [-90, 90] w.wcs.crpix = [1, 1] w.wcs.bounds_check(False, False) ra, dec = w.wcs_pix2world(300, 0, 0) assert_allclose(ra, -180) assert_allclose(dec, -30) def test_naxis(): w = wcs.WCS(naxis=2) w.wcs.crval = [1, 1] w.wcs.cdelt = [0.1, 0.1] w.wcs.crpix = [1, 1] w._naxis = [1000, 500] assert w.pixel_shape == (1000, 500) assert w.array_shape == (500, 1000) w.pixel_shape = (99, 59) assert w._naxis == [99, 59] w.array_shape = (45, 23) assert w._naxis == [23, 45] assert w.pixel_shape == (23, 45) w.pixel_shape = None assert w.pixel_bounds is None def test_sip_with_altkey(): """ Test that when creating a WCS object using a key, CTYPE with that key is looked at and not the primary CTYPE. fix for #5443. """ with fits.open(get_pkg_data_filename('data/sip.fits')) as f: with pytest.warns(wcs.FITSFixedWarning): w = wcs.WCS(f[0].header) # create a header with two WCSs. h1 = w.to_header(relax=True, key='A') h2 = w.to_header(relax=False) h1['CTYPE1A'] = "RA---SIN-SIP" h1['CTYPE2A'] = "DEC--SIN-SIP" h1.update(h2) with ctx_for_v71_dateref_warnings(): w = wcs.WCS(h1, key='A') assert (w.wcs.ctype == np.array(['RA---SIN-SIP', 'DEC--SIN-SIP'])).all() def test_to_fits_1(): """ Test to_fits() with LookupTable distortion. """ fits_name = get_pkg_data_filename('data/dist.fits') with pytest.warns(AstropyDeprecationWarning): w = wcs.WCS(fits_name) wfits = w.to_fits() assert isinstance(wfits, fits.HDUList) assert isinstance(wfits[0], fits.PrimaryHDU) assert isinstance(wfits[1], fits.ImageHDU) def test_keyedsip(): """ Test sip reading with extra key. """ hdr_name = get_pkg_data_filename('data/sip-broken.hdr') header = fits.Header.fromfile(hdr_name) del header["CRPIX1"] del header["CRPIX2"] w = wcs.WCS(header=header, key="A") assert isinstance(w.sip, wcs.Sip) assert w.sip.crpix[0] == 2048 assert w.sip.crpix[1] == 1026 def test_zero_size_input(): with fits.open(get_pkg_data_filename('data/sip.fits')) as f: with pytest.warns(wcs.FITSFixedWarning): w = wcs.WCS(f[0].header) inp = np.zeros((0, 2)) assert_array_equal(inp, w.all_pix2world(inp, 0)) assert_array_equal(inp, w.all_world2pix(inp, 0)) inp = [], [1] result = w.all_pix2world([], [1], 0) assert_array_equal(inp[0], result[0]) assert_array_equal(inp[1], result[1]) result = w.all_world2pix([], [1], 0) assert_array_equal(inp[0], result[0]) assert_array_equal(inp[1], result[1]) def test_scalar_inputs(): """ Issue #7845 """ wcsobj = wcs.WCS(naxis=1) result = wcsobj.all_pix2world(2, 1) assert_array_equal(result, [np.array(2.)]) assert result[0].shape == () result = wcsobj.all_pix2world([2], 1) assert_array_equal(result, [np.array([2.])]) assert result[0].shape == (1,) # Ignore RuntimeWarning raised on s390. @pytest.mark.filterwarnings('ignore:.*invalid value encountered in.*') def test_footprint_contains(): """ Test WCS.footprint_contains(skycoord) """ header = """ WCSAXES = 2 / Number of coordinate axes CRPIX1 = 1045.0 / Pixel coordinate of reference point CRPIX2 = 1001.0 / Pixel coordinate of reference point PC1_1 = -0.00556448550786 / Coordinate transformation matrix element PC1_2 = -0.001042120133257 / Coordinate transformation matrix element PC2_1 = 0.001181477028705 / Coordinate transformation matrix element PC2_2 = -0.005590809742987 / Coordinate transformation matrix element CDELT1 = 1.0 / [deg] Coordinate increment at reference point CDELT2 = 1.0 / [deg] Coordinate increment at reference point CUNIT1 = 'deg' / Units of coordinate increment and value CUNIT2 = 'deg' / Units of coordinate increment and value CTYPE1 = 'RA---TAN' / TAN (gnomonic) projection + SIP distortions CTYPE2 = 'DEC--TAN' / TAN (gnomonic) projection + SIP distortions CRVAL1 = 250.34971683647 / [deg] Coordinate value at reference point CRVAL2 = 2.2808772582495 / [deg] Coordinate value at reference point LONPOLE = 180.0 / [deg] Native longitude of celestial pole LATPOLE = 2.2808772582495 / [deg] Native latitude of celestial pole RADESYS = 'ICRS' / Equatorial coordinate system MJD-OBS = 58612.339199259 / [d] MJD of observation matching DATE-OBS DATE-OBS= '2019-05-09T08:08:26.816Z' / ISO-8601 observation date matching MJD-OB NAXIS = 2 / NAXIS NAXIS1 = 2136 / length of first array dimension NAXIS2 = 2078 / length of second array dimension """ # noqa header = fits.Header.fromstring(header.strip(), '\n') test_wcs = wcs.WCS(header) hasCoord = test_wcs.footprint_contains(SkyCoord(254, 2, unit='deg')) assert hasCoord hasCoord = test_wcs.footprint_contains(SkyCoord(240, 2, unit='deg')) assert not hasCoord hasCoord = test_wcs.footprint_contains(SkyCoord(24, 2, unit='deg')) assert not hasCoord def test_cunit(): # Initializing WCS w1 = wcs.WCS(naxis=2) w2 = wcs.WCS(naxis=2) w3 = wcs.WCS(naxis=2) w4 = wcs.WCS(naxis=2) # Initializing the values of cunit w1.wcs.cunit = ['deg', 'm/s'] w2.wcs.cunit = ['km/h', 'km/h'] w3.wcs.cunit = ['deg', 'm/s'] w4.wcs.cunit = ['deg', 'deg'] # Equality checking a cunit with itself assert w1.wcs.cunit == w1.wcs.cunit assert not w1.wcs.cunit != w1.wcs.cunit # Equality checking of two different cunit object having same values assert w1.wcs.cunit == w3.wcs.cunit assert not w1.wcs.cunit != w3.wcs.cunit # Equality checking of two different cunit object having the same first unit # but different second unit (see #9154) assert not w1.wcs.cunit == w4.wcs.cunit assert w1.wcs.cunit != w4.wcs.cunit # Inequality checking of two different cunit object having different values assert not w1.wcs.cunit == w2.wcs.cunit assert w1.wcs.cunit != w2.wcs.cunit # Inequality checking of cunit with a list of literals assert not w1.wcs.cunit == [1, 2, 3] assert w1.wcs.cunit != [1, 2, 3] # Inequality checking with some characters assert not w1.wcs.cunit == ['a', 'b', 'c'] assert w1.wcs.cunit != ['a', 'b', 'c'] # Comparison is not implemented TypeError will raise with pytest.raises(TypeError): w1.wcs.cunit < w2.wcs.cunit class TestWcsWithTime: def setup(self): if _WCSLIB_VER >= Version('7.1'): fname = get_pkg_data_filename('data/header_with_time_wcslib71.fits') else: fname = get_pkg_data_filename('data/header_with_time.fits') self.header = fits.Header.fromfile(fname) with pytest.warns(wcs.FITSFixedWarning): self.w = wcs.WCS(self.header, key='A') def test_keywods2wcsprm(self): """ Make sure Wcsprm is populated correctly from the header.""" ctype = [self.header[val] for val in self.header["CTYPE*"]] crval = [self.header[val] for val in self.header["CRVAL*"]] crpix = [self.header[val] for val in self.header["CRPIX*"]] cdelt = [self.header[val] for val in self.header["CDELT*"]] cunit = [self.header[val] for val in self.header["CUNIT*"]] assert list(self.w.wcs.ctype) == ctype assert list(self.w.wcs.axis_types) == [2200, 2201, 3300, 0] assert_allclose(self.w.wcs.crval, crval) assert_allclose(self.w.wcs.crpix, crpix) assert_allclose(self.w.wcs.cdelt, cdelt) assert list(self.w.wcs.cunit) == cunit naxis = self.w.naxis assert naxis == 4 pc = np.zeros((naxis, naxis), dtype=np.float64) for i in range(1, 5): for j in range(1, 5): if i == j: pc[i-1, j-1] = self.header.get(f'PC{i}_{j}A', 1) else: pc[i-1, j-1] = self.header.get(f'PC{i}_{j}A', 0) assert_allclose(self.w.wcs.pc, pc) char_keys = ['timesys', 'trefpos', 'trefdir', 'plephem', 'timeunit', 'dateref', 'dateobs', 'datebeg', 'dateavg', 'dateend'] for key in char_keys: assert getattr(self.w.wcs, key) == self.header.get(key, "") num_keys = ['mjdref', 'mjdobs', 'mjdbeg', 'mjdend', 'jepoch', 'bepoch', 'tstart', 'tstop', 'xposure', 'timsyer', 'timrder', 'timedel', 'timepixr', 'timeoffs', 'telapse', 'czphs', 'cperi'] for key in num_keys: if key.upper() == 'MJDREF': hdrv = [self.header.get('MJDREFIA', np.nan), self.header.get('MJDREFFA', np.nan)] else: hdrv = self.header.get(key, np.nan) assert_allclose(getattr(self.w.wcs, key), hdrv) def test_transforms(self): assert_allclose(self.w.all_pix2world(*self.w.wcs.crpix, 1), self.w.wcs.crval) def test_invalid_coordinate_masking(): # Regression test for an issue which caused all coordinates to be set to NaN # after a transformation rather than just the invalid ones as reported by # WCSLIB. A specific example of this is that when considering an all-sky # spectral cube with a spectral axis that is not correlated with the sky # axes, if transforming pixel coordinates that did not fall 'in' the sky, # the spectral world value was also masked even though that coordinate # was valid. w = wcs.WCS(naxis=3) w.wcs.ctype = 'VELO_LSR', 'GLON-CAR', 'GLAT-CAR' w.wcs.crval = -20, 0, 0 w.wcs.crpix = 1, 1441, 241 w.wcs.cdelt = 1.3, -0.125, 0.125 px = [-10, -10, 20] py = [-10, 10, 20] pz = [-10, 10, 20] wx, wy, wz = w.wcs_pix2world(px, py, pz, 0) # Before fixing this, wx used to return np.nan for the first element assert_allclose(wx, [-33, -33, 6]) assert_allclose(wy, [np.nan, 178.75, 177.5]) assert_allclose(wz, [np.nan, -28.75, -27.5]) def test_no_pixel_area(): w = wcs.WCS(naxis=3) # Pixel area cannot be computed with pytest.raises(ValueError, match='Pixel area is defined only for 2D pixels'): w.proj_plane_pixel_area() # Pixel scales still possible assert_quantity_allclose(w.proj_plane_pixel_scales(), 1) def test_distortion_header(tmpdir): """ Test that plate distortion model is correctly described by `wcs.to_header()` and preserved when creating a Cutout2D from the image, writing it to FITS, and reading it back from the file. """ path = get_pkg_data_filename("data/dss.14.29.56-62.41.05.fits.gz") cen = np.array((50, 50)) siz = np.array((20, 20)) with fits.open(path) as hdulist: with pytest.warns(wcs.FITSFixedWarning): w = wcs.WCS(hdulist[0].header) cut = Cutout2D(hdulist[0].data, position=cen, size=siz, wcs=w) # This converts the DSS plate solution model with AMD[XY]n coefficients into a # Template Polynomial Distortion model (TPD.FWD.n coefficients); # not testing explicitly for the header keywords here. if _WCSLIB_VER < Version("7.4"): with pytest.warns(AstropyWarning, match="WCS contains a TPD distortion model in CQDIS"): w0 = wcs.WCS(w.to_header_string()) with pytest.warns(AstropyWarning, match="WCS contains a TPD distortion model in CQDIS"): w1 = wcs.WCS(cut.wcs.to_header_string()) if _WCSLIB_VER >= Version("7.1"): pytest.xfail("TPD coefficients incomplete with WCSLIB >= 7.1 < 7.4") else: w0 = wcs.WCS(w.to_header_string()) w1 = wcs.WCS(cut.wcs.to_header_string()) assert w.pixel_to_world(0, 0).separation(w0.pixel_to_world(0, 0)) < 1.e-3 * u.mas assert w.pixel_to_world(*cen).separation(w0.pixel_to_world(*cen)) < 1.e-3 * u.mas assert w.pixel_to_world(*cen).separation(w1.pixel_to_world(*(siz / 2))) < 1.e-3 * u.mas cutfile = str(tmpdir.join('cutout.fits')) fits.writeto(cutfile, cut.data, cut.wcs.to_header()) with fits.open(cutfile) as hdulist: w2 = wcs.WCS(hdulist[0].header) assert w.pixel_to_world(*cen).separation(w2.pixel_to_world(*(siz / 2))) < 1.e-3 * u.mas def test_pixlist_wcs_colsel(): """ Test selection of a specific pixel list WCS using ``colsel``. See #11412. """ hdr_file = get_pkg_data_filename('data/chandra-pixlist-wcs.hdr') hdr = fits.Header.fromtextfile(hdr_file) with pytest.warns(wcs.FITSFixedWarning): w = wcs.WCS(hdr, keysel=['image', 'pixel'], colsel=[11, 12]) assert w.naxis == 2 assert list(w.wcs.ctype) == ['RA---TAN', 'DEC--TAN'] assert np.allclose(w.wcs.crval, [229.38051931869, -58.81108068885]) assert np.allclose(w.wcs.pc, [[1, 0], [0, 1]]) assert np.allclose(w.wcs.cdelt, [-0.00013666666666666, 0.00013666666666666]) assert np.allclose(w.wcs.lonpole, 180.) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/test_wcsprm.py0000644000175100001710000006606100000000000020641 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst import gc import locale import re from packaging.version import Version import pytest import numpy as np from numpy.testing import assert_array_equal, assert_array_almost_equal from astropy.io import fits from astropy.wcs import wcs from astropy.wcs import _wcs from astropy.wcs.wcs import FITSFixedWarning from astropy.utils.data import ( get_pkg_data_contents, get_pkg_data_fileobj, get_pkg_data_filename) from astropy.utils.misc import _set_locale from astropy import units as u from astropy.units.core import UnitsWarning ###################################################################### def test_alt(): w = _wcs.Wcsprm() assert w.alt == " " w.alt = "X" assert w.alt == "X" del w.alt assert w.alt == " " def test_alt_invalid1(): w = _wcs.Wcsprm() with pytest.raises(ValueError): w.alt = "$" def test_alt_invalid2(): w = _wcs.Wcsprm() with pytest.raises(ValueError): w.alt = " " def test_axis_types(): w = _wcs.Wcsprm() assert_array_equal(w.axis_types, [0, 0]) def test_cd(): w = _wcs.Wcsprm() w.cd = [[1, 0], [0, 1]] assert w.cd.dtype == float assert w.has_cd() is True assert_array_equal(w.cd, [[1, 0], [0, 1]]) del w.cd assert w.has_cd() is False def test_cd_missing(): w = _wcs.Wcsprm() assert w.has_cd() is False with pytest.raises(AttributeError): w.cd def test_cd_missing2(): w = _wcs.Wcsprm() w.cd = [[1, 0], [0, 1]] assert w.has_cd() is True del w.cd assert w.has_cd() is False with pytest.raises(AttributeError): w.cd def test_cd_invalid(): w = _wcs.Wcsprm() with pytest.raises(ValueError): w.cd = [1, 0, 0, 1] def test_cdfix(): w = _wcs.Wcsprm() w.cdfix() def test_cdelt(): w = _wcs.Wcsprm() assert_array_equal(w.cdelt, [1, 1]) w.cdelt = [42, 54] assert_array_equal(w.cdelt, [42, 54]) def test_cdelt_delete(): w = _wcs.Wcsprm() with pytest.raises(TypeError): del w.cdelt def test_cel_offset(): w = _wcs.Wcsprm() assert w.cel_offset is False w.cel_offset = 'foo' assert w.cel_offset is True w.cel_offset = 0 assert w.cel_offset is False def test_celfix(): # TODO: We need some data with -NCP or -GLS projections to test # with. For now, this is just a smoke test w = _wcs.Wcsprm() assert w.celfix() == -1 def test_cname(): w = _wcs.Wcsprm() # Test that this works as an iterator for x in w.cname: assert x == '' assert list(w.cname) == ['', ''] w.cname = [b'foo', 'bar'] assert list(w.cname) == ['foo', 'bar'] def test_cname_invalid(): w = _wcs.Wcsprm() with pytest.raises(TypeError): w.cname = [42, 54] def test_colax(): w = _wcs.Wcsprm() assert w.colax.dtype == np.intc assert_array_equal(w.colax, [0, 0]) w.colax = [42, 54] assert_array_equal(w.colax, [42, 54]) w.colax[0] = 0 assert_array_equal(w.colax, [0, 54]) with pytest.raises(ValueError): w.colax = [1, 2, 3] def test_colnum(): w = _wcs.Wcsprm() assert w.colnum == 0 w.colnum = 42 assert w.colnum == 42 with pytest.raises(OverflowError): w.colnum = 0xffffffffffffffffffff with pytest.raises(OverflowError): w.colnum = 0xffffffff with pytest.raises(TypeError): del w.colnum def test_colnum_invalid(): w = _wcs.Wcsprm() with pytest.raises(TypeError): w.colnum = 'foo' def test_crder(): w = _wcs.Wcsprm() assert w.crder.dtype == float assert np.all(np.isnan(w.crder)) w.crder[0] = 0 assert np.isnan(w.crder[1]) assert w.crder[0] == 0 w.crder = w.crder def test_crota(): w = _wcs.Wcsprm() w.crota = [1, 0] assert w.crota.dtype == float assert w.has_crota() is True assert_array_equal(w.crota, [1, 0]) del w.crota assert w.has_crota() is False def test_crota_missing(): w = _wcs.Wcsprm() assert w.has_crota() is False with pytest.raises(AttributeError): w.crota def test_crota_missing2(): w = _wcs.Wcsprm() w.crota = [1, 0] assert w.has_crota() is True del w.crota assert w.has_crota() is False with pytest.raises(AttributeError): w.crota def test_crpix(): w = _wcs.Wcsprm() assert w.crpix.dtype == float assert_array_equal(w.crpix, [0, 0]) w.crpix = [42, 54] assert_array_equal(w.crpix, [42, 54]) w.crpix[0] = 0 assert_array_equal(w.crpix, [0, 54]) with pytest.raises(ValueError): w.crpix = [1, 2, 3] def test_crval(): w = _wcs.Wcsprm() assert w.crval.dtype == float assert_array_equal(w.crval, [0, 0]) w.crval = [42, 54] assert_array_equal(w.crval, [42, 54]) w.crval[0] = 0 assert_array_equal(w.crval, [0, 54]) def test_csyer(): w = _wcs.Wcsprm() assert w.csyer.dtype == float assert np.all(np.isnan(w.csyer)) w.csyer[0] = 0 assert np.isnan(w.csyer[1]) assert w.csyer[0] == 0 w.csyer = w.csyer def test_ctype(): w = _wcs.Wcsprm() assert list(w.ctype) == ['', ''] w.ctype = [b'RA---TAN', 'DEC--TAN'] assert_array_equal(w.axis_types, [2200, 2201]) assert w.lat == 1 assert w.lng == 0 assert w.lattyp == 'DEC' assert w.lngtyp == 'RA' assert list(w.ctype) == ['RA---TAN', 'DEC--TAN'] w.ctype = ['foo', 'bar'] assert_array_equal(w.axis_types, [0, 0]) assert list(w.ctype) == ['foo', 'bar'] assert w.lat == -1 assert w.lng == -1 assert w.lattyp == 'DEC' assert w.lngtyp == 'RA' def test_ctype_repr(): w = _wcs.Wcsprm() assert list(w.ctype) == ['', ''] w.ctype = [b'RA-\t--TAN', 'DEC-\n-TAN'] assert repr(w.ctype == '["RA-\t--TAN", "DEC-\n-TAN"]') def test_ctype_index_error(): w = _wcs.Wcsprm() assert list(w.ctype) == ['', ''] for idx in (2, -3): with pytest.raises(IndexError): w.ctype[idx] with pytest.raises(IndexError): w.ctype[idx] = 'FOO' def test_ctype_invalid_error(): w = _wcs.Wcsprm() assert list(w.ctype) == ['', ''] with pytest.raises(ValueError): w.ctype[0] = 'X' * 100 with pytest.raises(TypeError): w.ctype[0] = True with pytest.raises(TypeError): w.ctype = ['a', 0] with pytest.raises(TypeError): w.ctype = None with pytest.raises(ValueError): w.ctype = ['a', 'b', 'c'] with pytest.raises(ValueError): w.ctype = ['FOO', 'A' * 100] def test_cubeface(): w = _wcs.Wcsprm() assert w.cubeface == -1 w.cubeface = 0 with pytest.raises(OverflowError): w.cubeface = -1 def test_cunit(): w = _wcs.Wcsprm() assert list(w.cunit) == [u.Unit(''), u.Unit('')] w.cunit = [u.m, 'km'] assert w.cunit[0] == u.m assert w.cunit[1] == u.km def test_cunit_invalid(): w = _wcs.Wcsprm() with pytest.warns(u.UnitsWarning, match='foo') as warns: w.cunit[0] = 'foo' assert len(warns) == 1 def test_cunit_invalid2(): w = _wcs.Wcsprm() with pytest.warns(u.UnitsWarning) as warns: w.cunit = ['foo', 'bar'] assert len(warns) == 2 assert 'foo' in str(warns[0].message) assert 'bar' in str(warns[1].message) def test_unit(): w = wcs.WCS() w.wcs.cunit[0] = u.erg assert w.wcs.cunit[0] == u.erg assert repr(w.wcs.cunit) == "['erg', '']" def test_unit2(): w = wcs.WCS() with pytest.warns(UnitsWarning): myunit = u.Unit("FOOBAR", parse_strict="warn") w.wcs.cunit[0] = myunit def test_unit3(): w = wcs.WCS() for idx in (2, -3): with pytest.raises(IndexError): w.wcs.cunit[idx] with pytest.raises(IndexError): w.wcs.cunit[idx] = u.m with pytest.raises(ValueError): w.wcs.cunit = [u.m, u.m, u.m] def test_unitfix(): w = _wcs.Wcsprm() w.unitfix() def test_cylfix(): # TODO: We need some data with broken cylindrical projections to # test with. For now, this is just a smoke test. w = _wcs.Wcsprm() assert w.cylfix() == -1 assert w.cylfix([0, 1]) == -1 with pytest.raises(ValueError): w.cylfix([0, 1, 2]) def test_dateavg(): w = _wcs.Wcsprm() assert w.dateavg == '' # TODO: When dateavg is verified, check that it works def test_dateobs(): w = _wcs.Wcsprm() assert w.dateobs == '' # TODO: When dateavg is verified, check that it works def test_datfix(): w = _wcs.Wcsprm() w.dateobs = '31/12/99' assert w.datfix() == 0 assert w.dateobs == '1999-12-31' assert w.mjdobs == 51543.0 def test_equinox(): w = _wcs.Wcsprm() assert np.isnan(w.equinox) w.equinox = 0 assert w.equinox == 0 del w.equinox assert np.isnan(w.equinox) with pytest.raises(TypeError): w.equinox = None def test_fix(): w = _wcs.Wcsprm() fix_ref = { 'cdfix': 'No change', 'cylfix': 'No change', 'obsfix': 'No change', 'datfix': 'No change', 'spcfix': 'No change', 'unitfix': 'No change', 'celfix': 'No change', 'obsfix': 'No change'} version = wcs._wcs.__version__ if Version(version) <= Version('5'): del fix_ref['obsfix'] if Version(version) >= Version('7.1'): w.dateref = '1858-11-17' if Version('7.4') <= Version(version) < Version('7.6'): fix_ref['datfix'] = 'Success' assert w.fix() == fix_ref def test_fix2(): w = _wcs.Wcsprm() w.dateobs = '31/12/99' fix_ref = { 'cdfix': 'No change', 'cylfix': 'No change', 'obsfix': 'No change', 'datfix': "Set MJD-OBS to 51543.000000 from DATE-OBS.\nChanged DATE-OBS from '31/12/99' to '1999-12-31'", # noqa 'spcfix': 'No change', 'unitfix': 'No change', 'celfix': 'No change'} version = wcs._wcs.__version__ if Version(version) <= Version("5"): del fix_ref['obsfix'] fix_ref['datfix'] = "Changed '31/12/99' to '1999-12-31'" if Version(version) >= Version('7.3'): fix_ref['datfix'] = "Set DATEREF to '1858-11-17' from MJDREF.\n" + fix_ref['datfix'] elif Version(version) >= Version('7.1'): fix_ref['datfix'] = "Set DATE-REF to '1858-11-17' from MJD-REF.\n" + fix_ref['datfix'] assert w.fix() == fix_ref assert w.dateobs == '1999-12-31' assert w.mjdobs == 51543.0 def test_fix3(): w = _wcs.Wcsprm() w.dateobs = '31/12/F9' fix_ref = { 'cdfix': 'No change', 'cylfix': 'No change', 'obsfix': 'No change', 'datfix': "Invalid DATE-OBS format '31/12/F9'", 'spcfix': 'No change', 'unitfix': 'No change', 'celfix': 'No change' } version = wcs._wcs.__version__ if Version(version) <= Version("5"): del fix_ref['obsfix'] fix_ref['datfix'] = "Invalid parameter value: invalid date '31/12/F9'" if Version(version) >= Version('7.3'): fix_ref['datfix'] = "Set DATEREF to '1858-11-17' from MJDREF.\n" + fix_ref['datfix'] elif Version(version) >= Version('7.1'): fix_ref['datfix'] = "Set DATE-REF to '1858-11-17' from MJD-REF.\n" + fix_ref['datfix'] assert w.fix() == fix_ref assert w.dateobs == '31/12/F9' assert np.isnan(w.mjdobs) def test_fix4(): w = _wcs.Wcsprm() with pytest.raises(ValueError): w.fix('X') def test_fix5(): w = _wcs.Wcsprm() with pytest.raises(ValueError): w.fix(naxis=[0, 1, 2]) def test_get_ps(): # TODO: We need some data with PSi_ma keywords w = _wcs.Wcsprm() assert len(w.get_ps()) == 0 def test_get_pv(): # TODO: We need some data with PVi_ma keywords w = _wcs.Wcsprm() assert len(w.get_pv()) == 0 def test_imgpix_matrix(): w = _wcs.Wcsprm() with pytest.raises(AssertionError): w.imgpix_matrix def test_imgpix_matrix2(): w = _wcs.Wcsprm() with pytest.raises(AttributeError): w.imgpix_matrix = None def test_isunity(): w = _wcs.Wcsprm() assert(w.is_unity()) def test_lat(): w = _wcs.Wcsprm() assert w.lat == -1 def test_lat_set(): w = _wcs.Wcsprm() with pytest.raises(AttributeError): w.lat = 0 def test_latpole(): w = _wcs.Wcsprm() assert w.latpole == 90.0 w.latpole = 45.0 assert w.latpole == 45.0 del w.latpole assert w.latpole == 90.0 def test_lattyp(): w = _wcs.Wcsprm() print(repr(w.lattyp)) assert w.lattyp == " " def test_lattyp_set(): w = _wcs.Wcsprm() with pytest.raises(AttributeError): w.lattyp = 0 def test_lng(): w = _wcs.Wcsprm() assert w.lng == -1 def test_lng_set(): w = _wcs.Wcsprm() with pytest.raises(AttributeError): w.lng = 0 def test_lngtyp(): w = _wcs.Wcsprm() assert w.lngtyp == " " def test_lngtyp_set(): w = _wcs.Wcsprm() with pytest.raises(AttributeError): w.lngtyp = 0 def test_lonpole(): w = _wcs.Wcsprm() assert np.isnan(w.lonpole) w.lonpole = 45.0 assert w.lonpole == 45.0 del w.lonpole assert np.isnan(w.lonpole) def test_mix(): w = _wcs.Wcsprm() w.ctype = [b'RA---TAN', 'DEC--TAN'] with pytest.raises(_wcs.InvalidCoordinateError): w.mix(1, 1, [240, 480], 1, 5, [0, 2], [54, 32], 1) def test_mjdavg(): w = _wcs.Wcsprm() assert np.isnan(w.mjdavg) w.mjdavg = 45.0 assert w.mjdavg == 45.0 del w.mjdavg assert np.isnan(w.mjdavg) def test_mjdobs(): w = _wcs.Wcsprm() assert np.isnan(w.mjdobs) w.mjdobs = 45.0 assert w.mjdobs == 45.0 del w.mjdobs assert np.isnan(w.mjdobs) def test_name(): w = _wcs.Wcsprm() assert w.name == '' w.name = 'foo' assert w.name == 'foo' def test_naxis(): w = _wcs.Wcsprm() assert w.naxis == 2 def test_naxis_set(): w = _wcs.Wcsprm() with pytest.raises(AttributeError): w.naxis = 4 def test_obsgeo(): w = _wcs.Wcsprm() assert np.all(np.isnan(w.obsgeo)) w.obsgeo = [1, 2, 3, 4, 5, 6] assert_array_equal(w.obsgeo, [1, 2, 3, 4, 5, 6]) del w.obsgeo assert np.all(np.isnan(w.obsgeo)) def test_pc(): w = _wcs.Wcsprm() assert w.has_pc() assert_array_equal(w.pc, [[1, 0], [0, 1]]) w.cd = [[1, 0], [0, 1]] assert not w.has_pc() del w.cd assert w.has_pc() assert_array_equal(w.pc, [[1, 0], [0, 1]]) w.pc = w.pc def test_pc_missing(): w = _wcs.Wcsprm() w.cd = [[1, 0], [0, 1]] assert not w.has_pc() with pytest.raises(AttributeError): w.pc def test_phi0(): w = _wcs.Wcsprm() assert np.isnan(w.phi0) w.phi0 = 42.0 assert w.phi0 == 42.0 del w.phi0 assert np.isnan(w.phi0) def test_piximg_matrix(): w = _wcs.Wcsprm() with pytest.raises(AssertionError): w.piximg_matrix def test_piximg_matrix2(): w = _wcs.Wcsprm() with pytest.raises(AttributeError): w.piximg_matrix = None def test_print_contents(): # In general, this is human-consumable, so we don't care if the # content changes, just check the type w = _wcs.Wcsprm() assert isinstance(str(w), str) def test_radesys(): w = _wcs.Wcsprm() assert w.radesys == '' w.radesys = 'foo' assert w.radesys == 'foo' def test_restfrq(): w = _wcs.Wcsprm() assert w.restfrq == 0.0 w.restfrq = np.nan assert np.isnan(w.restfrq) del w.restfrq def test_restwav(): w = _wcs.Wcsprm() assert w.restwav == 0.0 w.restwav = np.nan assert np.isnan(w.restwav) del w.restwav def test_set_ps(): w = _wcs.Wcsprm() data = [(0, 0, "param1"), (1, 1, "param2")] w.set_ps(data) assert w.get_ps() == data def test_set_ps_realloc(): w = _wcs.Wcsprm() w.set_ps([(0, 0, "param1")] * 16) def test_set_pv(): w = _wcs.Wcsprm() data = [(0, 0, 42.), (1, 1, 54.)] w.set_pv(data) assert w.get_pv() == data def test_set_pv_realloc(): w = _wcs.Wcsprm() w.set_pv([(0, 0, 42.)] * 16) def test_spcfix(): # TODO: We need some data with broken spectral headers here to # really test header = get_pkg_data_contents( 'data/spectra/orion-velo-1.hdr', encoding='binary') w = _wcs.Wcsprm(header) assert w.spcfix() == -1 def test_spec(): w = _wcs.Wcsprm() assert w.spec == -1 def test_spec_set(): w = _wcs.Wcsprm() with pytest.raises(AttributeError): w.spec = 0 def test_specsys(): w = _wcs.Wcsprm() assert w.specsys == '' w.specsys = 'foo' assert w.specsys == 'foo' def test_sptr(): # TODO: Write me pass def test_ssysobs(): w = _wcs.Wcsprm() assert w.ssysobs == '' w.ssysobs = 'foo' assert w.ssysobs == 'foo' def test_ssyssrc(): w = _wcs.Wcsprm() assert w.ssyssrc == '' w.ssyssrc = 'foo' assert w.ssyssrc == 'foo' def test_tab(): w = _wcs.Wcsprm() assert len(w.tab) == 0 # TODO: Inject some headers that have tables and test def test_theta0(): w = _wcs.Wcsprm() assert np.isnan(w.theta0) w.theta0 = 42.0 assert w.theta0 == 42.0 del w.theta0 assert np.isnan(w.theta0) def test_toheader(): w = _wcs.Wcsprm() assert isinstance(w.to_header(), str) def test_velangl(): w = _wcs.Wcsprm() assert np.isnan(w.velangl) w.velangl = 42.0 assert w.velangl == 42.0 del w.velangl assert np.isnan(w.velangl) def test_velosys(): w = _wcs.Wcsprm() assert np.isnan(w.velosys) w.velosys = 42.0 assert w.velosys == 42.0 del w.velosys assert np.isnan(w.velosys) def test_velref(): w = _wcs.Wcsprm() assert w.velref == 0.0 w.velref = 42 assert w.velref == 42.0 del w.velref assert w.velref == 0.0 def test_zsource(): w = _wcs.Wcsprm() assert np.isnan(w.zsource) w.zsource = 42.0 assert w.zsource == 42.0 del w.zsource assert np.isnan(w.zsource) def test_cd_3d(): header = get_pkg_data_contents('data/3d_cd.hdr', encoding='binary') w = _wcs.Wcsprm(header) assert w.cd.shape == (3, 3) assert w.get_pc().shape == (3, 3) assert w.get_cdelt().shape == (3,) def test_get_pc(): header = get_pkg_data_contents('data/3d_cd.hdr', encoding='binary') w = _wcs.Wcsprm(header) pc = w.get_pc() try: pc[0, 0] = 42 except (RuntimeError, ValueError): pass else: raise AssertionError() def test_detailed_err(): w = _wcs.Wcsprm() w.pc = [[0, 0], [0, 0]] with pytest.raises(_wcs.SingularMatrixError): w.set() def test_header_parse(): from astropy.io import fits with get_pkg_data_fileobj( 'data/header_newlines.fits', encoding='binary') as test_file: hdulist = fits.open(test_file) with pytest.warns(FITSFixedWarning): w = wcs.WCS(hdulist[0].header) assert w.wcs.ctype[0] == 'RA---TAN-SIP' def test_locale(): try: with _set_locale('fr_FR'): header = get_pkg_data_contents('data/locale.hdr', encoding='binary') with pytest.warns(FITSFixedWarning): w = _wcs.Wcsprm(header) assert re.search("[0-9]+,[0-9]*", w.to_header()) is None except locale.Error: pytest.xfail( "Can't set to 'fr_FR' locale, perhaps because it is not installed " "on this system") def test_unicode(): w = _wcs.Wcsprm() with pytest.raises(UnicodeEncodeError): w.alt = "‰" def test_sub_segfault(): # Issue #1960 header = fits.Header.fromtextfile( get_pkg_data_filename('data/sub-segfault.hdr')) w = wcs.WCS(header) w.sub([wcs.WCSSUB_CELESTIAL]) gc.collect() def test_bounds_check(): w = _wcs.Wcsprm() w.bounds_check(False) def test_wcs_sub_error_message(): # Issue #1587 w = _wcs.Wcsprm() with pytest.raises(TypeError) as e: w.sub('latitude') assert e.match("axes must None, a sequence or an integer$") def test_wcs_sub(): # Issue #3356 w = _wcs.Wcsprm() w.sub(['latitude']) w = _wcs.Wcsprm() w.sub([b'latitude']) def test_compare(): header = get_pkg_data_contents('data/3d_cd.hdr', encoding='binary') w = _wcs.Wcsprm(header) w2 = _wcs.Wcsprm(header) assert w == w2 w.equinox = 42 assert w == w2 assert not w.compare(w2) assert w.compare(w2, _wcs.WCSCOMPARE_ANCILLARY) w = _wcs.Wcsprm(header) w2 = _wcs.Wcsprm(header) with pytest.warns(RuntimeWarning): w.cdelt[0] = np.float32(0.00416666666666666666666666) w2.cdelt[0] = np.float64(0.00416666666666666666666666) assert not w.compare(w2) assert w.compare(w2, tolerance=1e-6) def test_radesys_defaults(): w = _wcs.Wcsprm() w.ctype = ['RA---TAN', 'DEC--TAN'] w.set() assert w.radesys == "ICRS" def test_radesys_defaults_full(): # As described in Section 3.1 of the FITS standard "Equatorial and ecliptic # coordinates", for those systems the RADESYS keyword can be used to # indicate the equatorial/ecliptic frame to use. From the standard: # "For RADESYSa values of FK4 and FK4-NO-E, any stated equinox is Besselian # and, if neither EQUINOXa nor EPOCH are given, a default of 1950.0 is to # be taken. For FK5, any stated equinox is Julian and, if neither keyword # is given, it defaults to 2000.0. # "If the EQUINOXa keyword is given it should always be accompanied by # RADESYS a. However, if it should happen to ap- pear by itself then # RADESYSa defaults to FK4 if EQUINOXa < 1984.0, or to FK5 if EQUINOXa # 1984.0. Note that these defaults, while probably true of older files # using the EPOCH keyword, are not required of them. # By default RADESYS is empty w = _wcs.Wcsprm(naxis=2) assert w.radesys == '' assert np.isnan(w.equinox) # For non-ecliptic or equatorial systems it is still empty w = _wcs.Wcsprm(naxis=2) for ctype in [('GLON-CAR', 'GLAT-CAR'), ('SLON-SIN', 'SLAT-SIN')]: w.ctype = ctype w.set() assert w.radesys == '' assert np.isnan(w.equinox) for ctype in [('RA---TAN', 'DEC--TAN'), ('ELON-TAN', 'ELAT-TAN'), ('DEC--TAN', 'RA---TAN'), ('ELAT-TAN', 'ELON-TAN')]: # Check defaults for RADESYS w = _wcs.Wcsprm(naxis=2) w.ctype = ctype w.set() assert w.radesys == 'ICRS' w = _wcs.Wcsprm(naxis=2) w.ctype = ctype w.equinox = 1980 w.set() assert w.radesys == 'FK4' w = _wcs.Wcsprm(naxis=2) w.ctype = ctype w.equinox = 1984 w.set() assert w.radesys == 'FK5' w = _wcs.Wcsprm(naxis=2) w.ctype = ctype w.radesys = 'foo' w.set() assert w.radesys == 'foo' # Check defaults for EQUINOX w = _wcs.Wcsprm(naxis=2) w.ctype = ctype w.set() assert np.isnan(w.equinox) # frame is ICRS, no equinox w = _wcs.Wcsprm(naxis=2) w.ctype = ctype w.radesys = 'ICRS' w.set() assert np.isnan(w.equinox) w = _wcs.Wcsprm(naxis=2) w.ctype = ctype w.radesys = 'FK5' w.set() assert w.equinox == 2000. w = _wcs.Wcsprm(naxis=2) w.ctype = ctype w.radesys = 'FK4' w.set() assert w.equinox == 1950 w = _wcs.Wcsprm(naxis=2) w.ctype = ctype w.radesys = 'FK4-NO-E' w.set() assert w.equinox == 1950 def test_iteration(): world = np.array( [[-0.58995335, -0.5], [0.00664326, -0.5], [-0.58995335, -0.25], [0.00664326, -0.25], [-0.58995335, 0.], [0.00664326, 0.], [-0.58995335, 0.25], [0.00664326, 0.25], [-0.58995335, 0.5], [0.00664326, 0.5]], float ) w = wcs.WCS() w.wcs.ctype = ['GLON-CAR', 'GLAT-CAR'] w.wcs.cdelt = [-0.006666666828, 0.006666666828] w.wcs.crpix = [75.907, 74.8485] x = w.wcs_world2pix(world, 1) expected = np.array( [[1.64400000e+02, -1.51498185e-01], [7.49105110e+01, -1.51498185e-01], [1.64400000e+02, 3.73485009e+01], [7.49105110e+01, 3.73485009e+01], [1.64400000e+02, 7.48485000e+01], [7.49105110e+01, 7.48485000e+01], [1.64400000e+02, 1.12348499e+02], [7.49105110e+01, 1.12348499e+02], [1.64400000e+02, 1.49848498e+02], [7.49105110e+01, 1.49848498e+02]], float) assert_array_almost_equal(x, expected) w2 = w.wcs_pix2world(x, 1) world[:, 0] %= 360. assert_array_almost_equal(w2, world) def test_invalid_args(): with pytest.raises(TypeError): _wcs.Wcsprm(keysel='A') with pytest.raises(ValueError): _wcs.Wcsprm(keysel=2) with pytest.raises(ValueError): _wcs.Wcsprm(colsel=2) with pytest.raises(ValueError): _wcs.Wcsprm(naxis=64) header = get_pkg_data_contents( 'data/spectra/orion-velo-1.hdr', encoding='binary') with pytest.raises(ValueError): _wcs.Wcsprm(header, relax='FOO') with pytest.raises(ValueError): _wcs.Wcsprm(header, naxis=3) with pytest.raises(KeyError): _wcs.Wcsprm(header, key='A') # Test keywords in the Time standard def test_datebeg(): w = _wcs.Wcsprm() assert w.datebeg == '' w.datebeg = '2001-02-11' assert w.datebeg == '2001-02-11' w.datebeg = '31/12/99' fix_ref = { 'cdfix': 'No change', 'cylfix': 'No change', 'obsfix': 'No change', 'datfix': "Invalid DATE-BEG format '31/12/99'", 'spcfix': 'No change', 'unitfix': 'No change', 'celfix': 'No change'} if Version(wcs._wcs.__version__) >= Version('7.3'): fix_ref['datfix'] = "Set DATEREF to '1858-11-17' from MJDREF.\n" + fix_ref['datfix'] elif Version(wcs._wcs.__version__) >= Version('7.1'): fix_ref['datfix'] = "Set DATE-REF to '1858-11-17' from MJD-REF.\n" + fix_ref['datfix'] assert w.fix() == fix_ref char_keys = ['timesys', 'trefpos', 'trefdir', 'plephem', 'timeunit', 'dateref', 'dateavg', 'dateend'] @pytest.mark.parametrize('key', char_keys) def test_char_keys(key): w = _wcs.Wcsprm() assert getattr(w, key) == '' setattr(w, key, "foo") assert getattr(w, key) == 'foo' with pytest.raises(TypeError): setattr(w, key, 42) num_keys = ['mjdobs', 'mjdbeg', 'mjdend', 'jepoch', 'bepoch', 'tstart', 'tstop', 'xposure', 'timsyer', 'timrder', 'timedel', 'timepixr', 'timeoffs', 'telapse', 'xposure'] @pytest.mark.parametrize('key', num_keys) def test_num_keys(key): w = _wcs.Wcsprm() assert np.isnan(getattr(w, key)) setattr(w, key, 42.0) assert getattr(w, key) == 42.0 delattr(w, key) assert np.isnan(getattr(w, key)) with pytest.raises(TypeError): setattr(w, key, "foo") @pytest.mark.parametrize('key', ['czphs', 'cperi', 'mjdref']) def test_array_keys(key): w = _wcs.Wcsprm() attr = getattr(w, key) if key == 'mjdref' and Version(_wcs.__version__) >= Version('7.1'): assert np.allclose(attr, [0, 0]) else: assert np.all(np.isnan(attr)) assert attr.dtype == float setattr(w, key, [1., 2.]) assert_array_equal(getattr(w, key), [1., 2.]) with pytest.raises(ValueError): setattr(w, key, ["foo", "bar"]) with pytest.raises(ValueError): setattr(w, key, "foo") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/tests/test_wtbarr.py0000644000175100001710000000306400000000000020621 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import pytest import numpy as np from astropy import wcs def test_wtbarr_i(tab_wcs_2di): assert tab_wcs_2di.wcs.wtb[0].i == 1 def test_wtbarr_m(tab_wcs_2di): assert tab_wcs_2di.wcs.wtb[0].m == 1 def test_wtbarr_m(tab_wcs_2di): assert tab_wcs_2di.wcs.wtb[0].kind == 'c' def test_wtbarr_extnam(tab_wcs_2di): assert tab_wcs_2di.wcs.wtb[0].extnam == 'WCS-TABLE' def test_wtbarr_extver(tab_wcs_2di): assert tab_wcs_2di.wcs.wtb[0].extver == 1 def test_wtbarr_extlev(tab_wcs_2di): assert tab_wcs_2di.wcs.wtb[0].extlev == 1 def test_wtbarr_ttype(tab_wcs_2di): assert tab_wcs_2di.wcs.wtb[0].ttype == 'wavelength' def test_wtbarr_row(tab_wcs_2di): assert tab_wcs_2di.wcs.wtb[0].row == 1 def test_wtbarr_ndim(tab_wcs_2di): assert tab_wcs_2di.wcs.wtb[0].ndim == 3 def test_wtbarr_print(tab_wcs_2di, capfd): tab_wcs_2di.wcs.wtb[0].print_contents() captured = capfd.readouterr() s = str(tab_wcs_2di.wcs.wtb[0]) lines = s.split('\n') assert captured.out == s assert ' i: 1' == lines[0] assert ' m: 1' == lines[1] assert ' kind: c' == lines[2] assert 'extnam: WCS-TABLE' == lines[3] assert 'extver: 1' == lines[4] assert 'extlev: 1' == lines[5] assert ' ttype: wavelength' == lines[6] assert ' row: 1' == lines[7] assert ' ndim: 3' == lines[8] assert lines[9].startswith('dimlen: ') assert ' 0: 4' == lines[10] assert ' 1: 2' == lines[11] assert lines[12].startswith('arrayp: ') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/utils.py0000644000175100001710000012345200000000000016263 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import copy import numpy as np import astropy.units as u from astropy.coordinates import CartesianRepresentation, SphericalRepresentation, ITRS from astropy.utils import unbroadcast from .wcs import WCS, WCSSUB_LATITUDE, WCSSUB_LONGITUDE __doctest_skip__ = ['wcs_to_celestial_frame', 'celestial_frame_to_wcs'] __all__ = ['obsgeo_to_frame', 'add_stokes_axis_to_wcs', 'celestial_frame_to_wcs', 'wcs_to_celestial_frame', 'proj_plane_pixel_scales', 'proj_plane_pixel_area', 'is_proj_plane_distorted', 'non_celestial_pixel_scales', 'skycoord_to_pixel', 'pixel_to_skycoord', 'custom_wcs_to_frame_mappings', 'custom_frame_to_wcs_mappings', 'pixel_to_pixel', 'local_partial_pixel_derivatives', 'fit_wcs_from_points'] def add_stokes_axis_to_wcs(wcs, add_before_ind): """ Add a new Stokes axis that is uncorrelated with any other axes. Parameters ---------- wcs : `~astropy.wcs.WCS` The WCS to add to add_before_ind : int Index of the WCS to insert the new Stokes axis in front of. To add at the end, do add_before_ind = wcs.wcs.naxis The beginning is at position 0. Returns ------- `~astropy.wcs.WCS` A new `~astropy.wcs.WCS` instance with an additional axis """ inds = [i + 1 for i in range(wcs.wcs.naxis)] inds.insert(add_before_ind, 0) newwcs = wcs.sub(inds) newwcs.wcs.ctype[add_before_ind] = 'STOKES' newwcs.wcs.cname[add_before_ind] = 'STOKES' return newwcs def _wcs_to_celestial_frame_builtin(wcs): # Import astropy.coordinates here to avoid circular imports from astropy.coordinates import (FK4, FK5, ICRS, ITRS, FK4NoETerms, Galactic, SphericalRepresentation) # Import astropy.time here otherwise setup.py fails before extensions are compiled from astropy.time import Time if wcs.wcs.lng == -1 or wcs.wcs.lat == -1: return None radesys = wcs.wcs.radesys if np.isnan(wcs.wcs.equinox): equinox = None else: equinox = wcs.wcs.equinox xcoord = wcs.wcs.ctype[wcs.wcs.lng][:4] ycoord = wcs.wcs.ctype[wcs.wcs.lat][:4] # Apply logic from FITS standard to determine the default radesys if radesys == '' and xcoord == 'RA--' and ycoord == 'DEC-': if equinox is None: radesys = "ICRS" elif equinox < 1984.: radesys = "FK4" else: radesys = "FK5" if radesys == 'FK4': if equinox is not None: equinox = Time(equinox, format='byear') frame = FK4(equinox=equinox) elif radesys == 'FK4-NO-E': if equinox is not None: equinox = Time(equinox, format='byear') frame = FK4NoETerms(equinox=equinox) elif radesys == 'FK5': if equinox is not None: equinox = Time(equinox, format='jyear') frame = FK5(equinox=equinox) elif radesys == 'ICRS': frame = ICRS() else: if xcoord == 'GLON' and ycoord == 'GLAT': frame = Galactic() elif xcoord == 'TLON' and ycoord == 'TLAT': # The default representation for ITRS is cartesian, but for WCS # purposes, we need the spherical representation. frame = ITRS(representation_type=SphericalRepresentation, obstime=wcs.wcs.dateobs or None) else: frame = None return frame def _celestial_frame_to_wcs_builtin(frame, projection='TAN'): # Import astropy.coordinates here to avoid circular imports from astropy.coordinates import FK4, FK5, ICRS, ITRS, BaseRADecFrame, FK4NoETerms, Galactic # Create a 2-dimensional WCS wcs = WCS(naxis=2) if isinstance(frame, BaseRADecFrame): xcoord = 'RA--' ycoord = 'DEC-' if isinstance(frame, ICRS): wcs.wcs.radesys = 'ICRS' elif isinstance(frame, FK4NoETerms): wcs.wcs.radesys = 'FK4-NO-E' wcs.wcs.equinox = frame.equinox.byear elif isinstance(frame, FK4): wcs.wcs.radesys = 'FK4' wcs.wcs.equinox = frame.equinox.byear elif isinstance(frame, FK5): wcs.wcs.radesys = 'FK5' wcs.wcs.equinox = frame.equinox.jyear else: return None elif isinstance(frame, Galactic): xcoord = 'GLON' ycoord = 'GLAT' elif isinstance(frame, ITRS): xcoord = 'TLON' ycoord = 'TLAT' wcs.wcs.radesys = 'ITRS' wcs.wcs.dateobs = frame.obstime.utc.isot else: return None wcs.wcs.ctype = [xcoord + '-' + projection, ycoord + '-' + projection] return wcs WCS_FRAME_MAPPINGS = [[_wcs_to_celestial_frame_builtin]] FRAME_WCS_MAPPINGS = [[_celestial_frame_to_wcs_builtin]] class custom_wcs_to_frame_mappings: def __init__(self, mappings=[]): if hasattr(mappings, '__call__'): mappings = [mappings] WCS_FRAME_MAPPINGS.append(mappings) def __enter__(self): pass def __exit__(self, type, value, tb): WCS_FRAME_MAPPINGS.pop() # Backward-compatibility custom_frame_mappings = custom_wcs_to_frame_mappings class custom_frame_to_wcs_mappings: def __init__(self, mappings=[]): if hasattr(mappings, '__call__'): mappings = [mappings] FRAME_WCS_MAPPINGS.append(mappings) def __enter__(self): pass def __exit__(self, type, value, tb): FRAME_WCS_MAPPINGS.pop() def wcs_to_celestial_frame(wcs): """ For a given WCS, return the coordinate frame that matches the celestial component of the WCS. Parameters ---------- wcs : :class:`~astropy.wcs.WCS` instance The WCS to find the frame for Returns ------- frame : :class:`~astropy.coordinates.baseframe.BaseCoordinateFrame` subclass instance An instance of a :class:`~astropy.coordinates.baseframe.BaseCoordinateFrame` subclass instance that best matches the specified WCS. Notes ----- To extend this function to frames not defined in astropy.coordinates, you can write your own function which should take a :class:`~astropy.wcs.WCS` instance and should return either an instance of a frame, or `None` if no matching frame was found. You can register this function temporarily with:: >>> from astropy.wcs.utils import wcs_to_celestial_frame, custom_wcs_to_frame_mappings >>> with custom_wcs_to_frame_mappings(my_function): ... wcs_to_celestial_frame(...) """ for mapping_set in WCS_FRAME_MAPPINGS: for func in mapping_set: frame = func(wcs) if frame is not None: return frame raise ValueError("Could not determine celestial frame corresponding to " "the specified WCS object") def celestial_frame_to_wcs(frame, projection='TAN'): """ For a given coordinate frame, return the corresponding WCS object. Note that the returned WCS object has only the elements corresponding to coordinate frames set (e.g. ctype, equinox, radesys). Parameters ---------- frame : :class:`~astropy.coordinates.baseframe.BaseCoordinateFrame` subclass instance An instance of a :class:`~astropy.coordinates.baseframe.BaseCoordinateFrame` subclass instance for which to find the WCS projection : str Projection code to use in ctype, if applicable Returns ------- wcs : :class:`~astropy.wcs.WCS` instance The corresponding WCS object Examples -------- :: >>> from astropy.wcs.utils import celestial_frame_to_wcs >>> from astropy.coordinates import FK5 >>> frame = FK5(equinox='J2010') >>> wcs = celestial_frame_to_wcs(frame) >>> wcs.to_header() WCSAXES = 2 / Number of coordinate axes CRPIX1 = 0.0 / Pixel coordinate of reference point CRPIX2 = 0.0 / Pixel coordinate of reference point CDELT1 = 1.0 / [deg] Coordinate increment at reference point CDELT2 = 1.0 / [deg] Coordinate increment at reference point CUNIT1 = 'deg' / Units of coordinate increment and value CUNIT2 = 'deg' / Units of coordinate increment and value CTYPE1 = 'RA---TAN' / Right ascension, gnomonic projection CTYPE2 = 'DEC--TAN' / Declination, gnomonic projection CRVAL1 = 0.0 / [deg] Coordinate value at reference point CRVAL2 = 0.0 / [deg] Coordinate value at reference point LONPOLE = 180.0 / [deg] Native longitude of celestial pole LATPOLE = 0.0 / [deg] Native latitude of celestial pole RADESYS = 'FK5' / Equatorial coordinate system EQUINOX = 2010.0 / [yr] Equinox of equatorial coordinates Notes ----- To extend this function to frames not defined in astropy.coordinates, you can write your own function which should take a :class:`~astropy.coordinates.baseframe.BaseCoordinateFrame` subclass instance and a projection (given as a string) and should return either a WCS instance, or `None` if the WCS could not be determined. You can register this function temporarily with:: >>> from astropy.wcs.utils import celestial_frame_to_wcs, custom_frame_to_wcs_mappings >>> with custom_frame_to_wcs_mappings(my_function): ... celestial_frame_to_wcs(...) """ for mapping_set in FRAME_WCS_MAPPINGS: for func in mapping_set: wcs = func(frame, projection=projection) if wcs is not None: return wcs raise ValueError("Could not determine WCS corresponding to the specified " "coordinate frame.") def proj_plane_pixel_scales(wcs): """ For a WCS returns pixel scales along each axis of the image pixel at the ``CRPIX`` location once it is projected onto the "plane of intermediate world coordinates" as defined in `Greisen & Calabretta 2002, A&A, 395, 1061 `_. .. note:: This function is concerned **only** about the transformation "image plane"->"projection plane" and **not** about the transformation "celestial sphere"->"projection plane"->"image plane". Therefore, this function ignores distortions arising due to non-linear nature of most projections. .. note:: In order to compute the scales corresponding to celestial axes only, make sure that the input `~astropy.wcs.WCS` object contains celestial axes only, e.g., by passing in the `~astropy.wcs.WCS.celestial` WCS object. Parameters ---------- wcs : `~astropy.wcs.WCS` A world coordinate system object. Returns ------- scale : ndarray A vector (`~numpy.ndarray`) of projection plane increments corresponding to each pixel side (axis). The units of the returned results are the same as the units of `~astropy.wcs.Wcsprm.cdelt`, `~astropy.wcs.Wcsprm.crval`, and `~astropy.wcs.Wcsprm.cd` for the celestial WCS and can be obtained by inquiring the value of `~astropy.wcs.Wcsprm.cunit` property of the input `~astropy.wcs.WCS` WCS object. See Also -------- astropy.wcs.utils.proj_plane_pixel_area """ return np.sqrt((wcs.pixel_scale_matrix**2).sum(axis=0, dtype=float)) def proj_plane_pixel_area(wcs): """ For a **celestial** WCS (see `astropy.wcs.WCS.celestial`) returns pixel area of the image pixel at the ``CRPIX`` location once it is projected onto the "plane of intermediate world coordinates" as defined in `Greisen & Calabretta 2002, A&A, 395, 1061 `_. .. note:: This function is concerned **only** about the transformation "image plane"->"projection plane" and **not** about the transformation "celestial sphere"->"projection plane"->"image plane". Therefore, this function ignores distortions arising due to non-linear nature of most projections. .. note:: In order to compute the area of pixels corresponding to celestial axes only, this function uses the `~astropy.wcs.WCS.celestial` WCS object of the input ``wcs``. This is different from the `~astropy.wcs.utils.proj_plane_pixel_scales` function that computes the scales for the axes of the input WCS itself. Parameters ---------- wcs : `~astropy.wcs.WCS` A world coordinate system object. Returns ------- area : float Area (in the projection plane) of the pixel at ``CRPIX`` location. The units of the returned result are the same as the units of the `~astropy.wcs.Wcsprm.cdelt`, `~astropy.wcs.Wcsprm.crval`, and `~astropy.wcs.Wcsprm.cd` for the celestial WCS and can be obtained by inquiring the value of `~astropy.wcs.Wcsprm.cunit` property of the `~astropy.wcs.WCS.celestial` WCS object. Raises ------ ValueError Pixel area is defined only for 2D pixels. Most likely the `~astropy.wcs.Wcsprm.cd` matrix of the `~astropy.wcs.WCS.celestial` WCS is not a square matrix of second order. Notes ----- Depending on the application, square root of the pixel area can be used to represent a single pixel scale of an equivalent square pixel whose area is equal to the area of a generally non-square pixel. See Also -------- astropy.wcs.utils.proj_plane_pixel_scales """ psm = wcs.celestial.pixel_scale_matrix if psm.shape != (2, 2): raise ValueError("Pixel area is defined only for 2D pixels.") return np.abs(np.linalg.det(psm)) def is_proj_plane_distorted(wcs, maxerr=1.0e-5): r""" For a WCS returns `False` if square image (detector) pixels stay square when projected onto the "plane of intermediate world coordinates" as defined in `Greisen & Calabretta 2002, A&A, 395, 1061 `_. It will return `True` if transformation from image (detector) coordinates to the focal plane coordinates is non-orthogonal or if WCS contains non-linear (e.g., SIP) distortions. .. note:: Since this function is concerned **only** about the transformation "image plane"->"focal plane" and **not** about the transformation "celestial sphere"->"focal plane"->"image plane", this function ignores distortions arising due to non-linear nature of most projections. Let's denote by *C* either the original or the reconstructed (from ``PC`` and ``CDELT``) CD matrix. `is_proj_plane_distorted` verifies that the transformation from image (detector) coordinates to the focal plane coordinates is orthogonal using the following check: .. math:: \left \| \frac{C \cdot C^{\mathrm{T}}} {| det(C)|} - I \right \|_{\mathrm{max}} < \epsilon . Parameters ---------- wcs : `~astropy.wcs.WCS` World coordinate system object maxerr : float, optional Accuracy to which the CD matrix, **normalized** such that :math:`|det(CD)|=1`, should be close to being an orthogonal matrix as described in the above equation (see :math:`\epsilon`). Returns ------- distorted : bool Returns `True` if focal (projection) plane is distorted and `False` otherwise. """ cwcs = wcs.celestial return (not _is_cd_orthogonal(cwcs.pixel_scale_matrix, maxerr) or _has_distortion(cwcs)) def _is_cd_orthogonal(cd, maxerr): shape = cd.shape if not (len(shape) == 2 and shape[0] == shape[1]): raise ValueError("CD (or PC) matrix must be a 2D square matrix.") pixarea = np.abs(np.linalg.det(cd)) if (pixarea == 0.0): raise ValueError("CD (or PC) matrix is singular.") # NOTE: Technically, below we should use np.dot(cd, np.conjugate(cd.T)) # However, I am not aware of complex CD/PC matrices... I = np.dot(cd, cd.T) / pixarea cd_unitary_err = np.amax(np.abs(I - np.eye(shape[0]))) return (cd_unitary_err < maxerr) def non_celestial_pixel_scales(inwcs): """ Calculate the pixel scale along each axis of a non-celestial WCS, for example one with mixed spectral and spatial axes. Parameters ---------- inwcs : `~astropy.wcs.WCS` The world coordinate system object. Returns ------- scale : `numpy.ndarray` The pixel scale along each axis. """ if inwcs.is_celestial: raise ValueError("WCS is celestial, use celestial_pixel_scales instead") pccd = inwcs.pixel_scale_matrix if np.allclose(np.extract(1-np.eye(*pccd.shape), pccd), 0): return np.abs(np.diagonal(pccd))*u.deg else: raise ValueError("WCS is rotated, cannot determine consistent pixel scales") def _has_distortion(wcs): """ `True` if contains any SIP or image distortion components. """ return any(getattr(wcs, dist_attr) is not None for dist_attr in ['cpdis1', 'cpdis2', 'det2im1', 'det2im2', 'sip']) # TODO: in future, we should think about how the following two functions can be # integrated better into the WCS class. def skycoord_to_pixel(coords, wcs, origin=0, mode='all'): """ Convert a set of SkyCoord coordinates into pixels. Parameters ---------- coords : `~astropy.coordinates.SkyCoord` The coordinates to convert. wcs : `~astropy.wcs.WCS` The WCS transformation to use. origin : int Whether to return 0 or 1-based pixel coordinates. mode : 'all' or 'wcs' Whether to do the transformation including distortions (``'all'``) or only including only the core WCS transformation (``'wcs'``). Returns ------- xp, yp : `numpy.ndarray` The pixel coordinates See Also -------- astropy.coordinates.SkyCoord.from_pixel """ if _has_distortion(wcs) and wcs.naxis != 2: raise ValueError("Can only handle WCS with distortions for 2-dimensional WCS") # Keep only the celestial part of the axes, also re-orders lon/lat wcs = wcs.sub([WCSSUB_LONGITUDE, WCSSUB_LATITUDE]) if wcs.naxis != 2: raise ValueError("WCS should contain celestial component") # Check which frame the WCS uses frame = wcs_to_celestial_frame(wcs) # Check what unit the WCS needs xw_unit = u.Unit(wcs.wcs.cunit[0]) yw_unit = u.Unit(wcs.wcs.cunit[1]) # Convert positions to frame coords = coords.transform_to(frame) # Extract longitude and latitude. We first try and use lon/lat directly, # but if the representation is not spherical or unit spherical this will # fail. We should then force the use of the unit spherical # representation. We don't do that directly to make sure that we preserve # custom lon/lat representations if available. try: lon = coords.data.lon.to(xw_unit) lat = coords.data.lat.to(yw_unit) except AttributeError: lon = coords.spherical.lon.to(xw_unit) lat = coords.spherical.lat.to(yw_unit) # Convert to pixel coordinates if mode == 'all': xp, yp = wcs.all_world2pix(lon.value, lat.value, origin) elif mode == 'wcs': xp, yp = wcs.wcs_world2pix(lon.value, lat.value, origin) else: raise ValueError("mode should be either 'all' or 'wcs'") return xp, yp def pixel_to_skycoord(xp, yp, wcs, origin=0, mode='all', cls=None): """ Convert a set of pixel coordinates into a `~astropy.coordinates.SkyCoord` coordinate. Parameters ---------- xp, yp : float or ndarray The coordinates to convert. wcs : `~astropy.wcs.WCS` The WCS transformation to use. origin : int Whether to return 0 or 1-based pixel coordinates. mode : 'all' or 'wcs' Whether to do the transformation including distortions (``'all'``) or only including only the core WCS transformation (``'wcs'``). cls : class or None The class of object to create. Should be a `~astropy.coordinates.SkyCoord` subclass. If None, defaults to `~astropy.coordinates.SkyCoord`. Returns ------- coords : `~astropy.coordinates.SkyCoord` subclass The celestial coordinates. Whatever ``cls`` type is. See Also -------- astropy.coordinates.SkyCoord.from_pixel """ # Import astropy.coordinates here to avoid circular imports from astropy.coordinates import SkyCoord, UnitSphericalRepresentation # we have to do this instead of actually setting the default to SkyCoord # because importing SkyCoord at the module-level leads to circular # dependencies. if cls is None: cls = SkyCoord if _has_distortion(wcs) and wcs.naxis != 2: raise ValueError("Can only handle WCS with distortions for 2-dimensional WCS") # Keep only the celestial part of the axes, also re-orders lon/lat wcs = wcs.sub([WCSSUB_LONGITUDE, WCSSUB_LATITUDE]) if wcs.naxis != 2: raise ValueError("WCS should contain celestial component") # Check which frame the WCS uses frame = wcs_to_celestial_frame(wcs) # Check what unit the WCS gives lon_unit = u.Unit(wcs.wcs.cunit[0]) lat_unit = u.Unit(wcs.wcs.cunit[1]) # Convert pixel coordinates to celestial coordinates if mode == 'all': lon, lat = wcs.all_pix2world(xp, yp, origin) elif mode == 'wcs': lon, lat = wcs.wcs_pix2world(xp, yp, origin) else: raise ValueError("mode should be either 'all' or 'wcs'") # Add units to longitude/latitude lon = lon * lon_unit lat = lat * lat_unit # Create a SkyCoord-like object data = UnitSphericalRepresentation(lon=lon, lat=lat) coords = cls(frame.realize_frame(data)) return coords def _unique_with_order_preserved(items): """ Return a list of unique items in the list provided, preserving the order in which they are found. """ new_items = [] for item in items: if item not in new_items: new_items.append(item) return new_items def _pixel_to_world_correlation_matrix(wcs): """ Return a correlation matrix between the pixel coordinates and the high level world coordinates, along with the list of high level world coordinate classes. The shape of the matrix is ``(n_world, n_pix)``, where ``n_world`` is the number of high level world coordinates. """ # We basically want to collapse the world dimensions together that are # combined into the same high-level objects. # Get the following in advance as getting these properties can be expensive all_components = wcs.low_level_wcs.world_axis_object_components all_classes = wcs.low_level_wcs.world_axis_object_classes axis_correlation_matrix = wcs.low_level_wcs.axis_correlation_matrix components = _unique_with_order_preserved([c[0] for c in all_components]) matrix = np.zeros((len(components), wcs.pixel_n_dim), dtype=bool) for iworld in range(wcs.world_n_dim): iworld_unique = components.index(all_components[iworld][0]) matrix[iworld_unique] |= axis_correlation_matrix[iworld] classes = [all_classes[component][0] for component in components] return matrix, classes def _pixel_to_pixel_correlation_matrix(wcs_in, wcs_out): """ Correlation matrix between the input and output pixel coordinates for a pixel -> world -> pixel transformation specified by two WCS instances. The first WCS specified is the one used for the pixel -> world transformation and the second WCS specified is the one used for the world -> pixel transformation. The shape of the matrix is ``(n_pixel_out, n_pixel_in)``. """ matrix1, classes1 = _pixel_to_world_correlation_matrix(wcs_in) matrix2, classes2 = _pixel_to_world_correlation_matrix(wcs_out) if len(classes1) != len(classes2): raise ValueError("The two WCS return a different number of world coordinates") # Check if classes match uniquely unique_match = True mapping = [] for class1 in classes1: matches = classes2.count(class1) if matches == 0: raise ValueError("The world coordinate types of the two WCS do not match") elif matches > 1: unique_match = False break else: mapping.append(classes2.index(class1)) if unique_match: # Classes are unique, so we need to re-order matrix2 along the world # axis using the mapping we found above. matrix2 = matrix2[mapping] elif classes1 != classes2: raise ValueError("World coordinate order doesn't match and automatic matching is ambiguous") matrix = np.matmul(matrix2.T, matrix1) return matrix def _split_matrix(matrix): """ Given an axis correlation matrix from a WCS object, return information about the individual WCS that can be split out. The output is a list of tuples, where each tuple contains a list of pixel dimensions and a list of world dimensions that can be extracted to form a new WCS. For example, in the case of a spectral cube with the first two world coordinates being the celestial coordinates and the third coordinate being an uncorrelated spectral axis, the matrix would look like:: array([[ True, True, False], [ True, True, False], [False, False, True]]) and this function will return ``[([0, 1], [0, 1]), ([2], [2])]``. """ pixel_used = [] split_info = [] for ipix in range(matrix.shape[1]): if ipix in pixel_used: continue pixel_include = np.zeros(matrix.shape[1], dtype=bool) pixel_include[ipix] = True n_pix_prev, n_pix = 0, 1 while n_pix > n_pix_prev: world_include = matrix[:, pixel_include].any(axis=1) pixel_include = matrix[world_include, :].any(axis=0) n_pix_prev, n_pix = n_pix, np.sum(pixel_include) pixel_indices = list(np.nonzero(pixel_include)[0]) world_indices = list(np.nonzero(world_include)[0]) pixel_used.extend(pixel_indices) split_info.append((pixel_indices, world_indices)) return split_info def pixel_to_pixel(wcs_in, wcs_out, *inputs): """ Transform pixel coordinates in a dataset with a WCS to pixel coordinates in another dataset with a different WCS. This function is designed to efficiently deal with input pixel arrays that are broadcasted views of smaller arrays, and is compatible with any APE14-compliant WCS. Parameters ---------- wcs_in : `~astropy.wcs.wcsapi.BaseHighLevelWCS` A WCS object for the original dataset which complies with the high-level shared APE 14 WCS API. wcs_out : `~astropy.wcs.wcsapi.BaseHighLevelWCS` A WCS object for the target dataset which complies with the high-level shared APE 14 WCS API. *inputs : Scalars or arrays giving the pixel coordinates to transform. """ # Shortcut for scalars if np.isscalar(inputs[0]): world_outputs = wcs_in.pixel_to_world(*inputs) if not isinstance(world_outputs, (tuple, list)): world_outputs = (world_outputs,) return wcs_out.world_to_pixel(*world_outputs) # Remember original shape original_shape = inputs[0].shape matrix = _pixel_to_pixel_correlation_matrix(wcs_in, wcs_out) split_info = _split_matrix(matrix) outputs = [None] * wcs_out.pixel_n_dim for (pixel_in_indices, pixel_out_indices) in split_info: pixel_inputs = [] for ipix in range(wcs_in.pixel_n_dim): if ipix in pixel_in_indices: pixel_inputs.append(unbroadcast(inputs[ipix])) else: pixel_inputs.append(inputs[ipix].flat[0]) pixel_inputs = np.broadcast_arrays(*pixel_inputs) world_outputs = wcs_in.pixel_to_world(*pixel_inputs) if not isinstance(world_outputs, (tuple, list)): world_outputs = (world_outputs,) pixel_outputs = wcs_out.world_to_pixel(*world_outputs) if wcs_out.pixel_n_dim == 1: pixel_outputs = (pixel_outputs,) for ipix in range(wcs_out.pixel_n_dim): if ipix in pixel_out_indices: outputs[ipix] = np.broadcast_to(pixel_outputs[ipix], original_shape) return outputs[0] if wcs_out.pixel_n_dim == 1 else outputs def local_partial_pixel_derivatives(wcs, *pixel, normalize_by_world=False): """ Return a matrix of shape ``(world_n_dim, pixel_n_dim)`` where each entry ``[i, j]`` is the partial derivative d(world_i)/d(pixel_j) at the requested pixel position. Parameters ---------- wcs : `~astropy.wcs.WCS` The WCS transformation to evaluate the derivatives for. *pixel : float The scalar pixel coordinates at which to evaluate the derivatives. normalize_by_world : bool If `True`, the matrix is normalized so that for each world entry the derivatives add up to 1. """ # Find the world coordinates at the requested pixel pixel_ref = np.array(pixel) world_ref = np.array(wcs.pixel_to_world_values(*pixel_ref)) # Set up the derivative matrix derivatives = np.zeros((wcs.world_n_dim, wcs.pixel_n_dim)) for i in range(wcs.pixel_n_dim): pixel_off = pixel_ref.copy() pixel_off[i] += 1 world_off = np.array(wcs.pixel_to_world_values(*pixel_off)) derivatives[:, i] = world_off - world_ref if normalize_by_world: derivatives /= derivatives.sum(axis=0)[:, np.newaxis] return derivatives def _linear_wcs_fit(params, lon, lat, x, y, w_obj): """ Objective function for fitting linear terms. Parameters ---------- params : array 6 element array. First 4 elements are PC matrix, last 2 are CRPIX. lon, lat: array Sky coordinates. x, y: array Pixel coordinates w_obj: `~astropy.wcs.WCS` WCS object """ cd = params[0:4] crpix = params[4:6] w_obj.wcs.cd = ((cd[0], cd[1]), (cd[2], cd[3])) w_obj.wcs.crpix = crpix lon2, lat2 = w_obj.wcs_pix2world(x, y, 0) lat_resids = lat - lat2 lon_resids = lon - lon2 # In case the longitude has wrapped around lon_resids = np.mod(lon_resids - 180.0, 360.0) - 180.0 resids = np.concatenate((lon_resids * np.cos(np.radians(lat)), lat_resids)) return resids def _sip_fit(params, lon, lat, u, v, w_obj, order, coeff_names): """ Objective function for fitting SIP. Parameters ---------- params : array Fittable parameters. First 4 elements are PC matrix, last 2 are CRPIX. lon, lat: array Sky coordinates. u, v: array Pixel coordinates w_obj: `~astropy.wcs.WCS` WCS object """ from ..modeling.models import SIP # here to avoid circular import # unpack params crpix = params[0:2] cdx = params[2:6].reshape((2, 2)) a_params = params[6:6+len(coeff_names)] b_params = params[6+len(coeff_names):] # assign to wcs, used for transfomations in this function w_obj.wcs.cd = cdx w_obj.wcs.crpix = crpix a_coeff, b_coeff = {}, {} for i in range(len(coeff_names)): a_coeff['A_' + coeff_names[i]] = a_params[i] b_coeff['B_' + coeff_names[i]] = b_params[i] sip = SIP(crpix=crpix, a_order=order, b_order=order, a_coeff=a_coeff, b_coeff=b_coeff) fuv, guv = sip(u, v) xo, yo = np.dot(cdx, np.array([u+fuv-crpix[0], v+guv-crpix[1]])) # use all pix2world in case `projection` contains distortion table x, y = w_obj.all_world2pix(lon, lat, 0) x, y = np.dot(w_obj.wcs.cd, (x-w_obj.wcs.crpix[0], y-w_obj.wcs.crpix[1])) resids = np.concatenate((x-xo, y-yo)) return resids def fit_wcs_from_points(xy, world_coords, proj_point='center', projection='TAN', sip_degree=None): """ Given two matching sets of coordinates on detector and sky, compute the WCS. Fits a WCS object to matched set of input detector and sky coordinates. Optionally, a SIP can be fit to account for geometric distortion. Returns an `~astropy.wcs.WCS` object with the best fit parameters for mapping between input pixel and sky coordinates. The projection type (default 'TAN') can passed in as a string, one of the valid three-letter projection codes - or as a WCS object with projection keywords already set. Note that if an input WCS has any non-polynomial distortion, this will be applied and reflected in the fit terms and coefficients. Passing in a WCS object in this way essentially allows it to be refit based on the matched input coordinates and projection point, but take care when using this option as non-projection related keywords in the input might cause unexpected behavior. Notes ----- - The fiducial point for the spherical projection can be set to 'center' to use the mean position of input sky coordinates, or as an `~astropy.coordinates.SkyCoord` object. - Units in all output WCS objects will always be in degrees. - If the coordinate frame differs between `~astropy.coordinates.SkyCoord` objects passed in for ``world_coords`` and ``proj_point``, the frame for ``world_coords`` will override as the frame for the output WCS. - If a WCS object is passed in to ``projection`` the CD/PC matrix will be used as an initial guess for the fit. If this is known to be significantly off and may throw off the fit, set to the identity matrix (for example, by doing wcs.wcs.pc = [(1., 0.,), (0., 1.)]) Parameters ---------- xy : (`numpy.ndarray`, `numpy.ndarray`) tuple x & y pixel coordinates. world_coords : `~astropy.coordinates.SkyCoord` Skycoord object with world coordinates. proj_point : 'center' or ~astropy.coordinates.SkyCoord` Defaults to 'center', in which the geometric center of input world coordinates will be used as the projection point. To specify an exact point for the projection, a Skycoord object with a coordinate pair can be passed in. For consistency, the units and frame of these coordinates will be transformed to match ``world_coords`` if they don't. projection : str or `~astropy.wcs.WCS` Three letter projection code, of any of standard projections defined in the FITS WCS standard. Optionally, a WCS object with projection keywords set may be passed in. sip_degree : None or int If set to a non-zero integer value, will fit SIP of degree ``sip_degree`` to model geometric distortion. Defaults to None, meaning no distortion corrections will be fit. Returns ------- wcs : `~astropy.wcs.WCS` The best-fit WCS to the points given. """ from scipy.optimize import least_squares import astropy.units as u from astropy.coordinates import SkyCoord # here to avoid circular import from .wcs import Sip xp, yp = xy try: lon, lat = world_coords.data.lon.deg, world_coords.data.lat.deg except AttributeError: unit_sph = world_coords.unit_spherical lon, lat = unit_sph.lon.deg, unit_sph.lat.deg # verify input if (type(proj_point) != type(world_coords)) and (proj_point != 'center'): raise ValueError("proj_point must be set to 'center', or an" + "`~astropy.coordinates.SkyCoord` object with " + "a pair of points.") use_center_as_proj_point = (str(proj_point) == 'center') if not use_center_as_proj_point: assert proj_point.size == 1 proj_codes = [ 'AZP', 'SZP', 'TAN', 'STG', 'SIN', 'ARC', 'ZEA', 'AIR', 'CYP', 'CEA', 'CAR', 'MER', 'SFL', 'PAR', 'MOL', 'AIT', 'COP', 'COE', 'COD', 'COO', 'BON', 'PCO', 'TSC', 'CSC', 'QSC', 'HPX', 'XPH' ] if type(projection) == str: if projection not in proj_codes: raise ValueError("Must specify valid projection code from list of " + "supported types: ", ', '.join(proj_codes)) # empty wcs to fill in with fit values wcs = celestial_frame_to_wcs(frame=world_coords.frame, projection=projection) else: #if projection is not string, should be wcs object. use as template. wcs = copy.deepcopy(projection) wcs.cdelt = (1., 1.) # make sure cdelt is 1 wcs.sip = None # Change PC to CD, since cdelt will be set to 1 if wcs.wcs.has_pc(): wcs.wcs.cd = wcs.wcs.pc wcs.wcs.__delattr__('pc') if (type(sip_degree) != type(None)) and (type(sip_degree) != int): raise ValueError("sip_degree must be None, or integer.") # compute bounding box for sources in image coordinates: xpmin, xpmax, ypmin, ypmax = xp.min(), xp.max(), yp.min(), yp.max() # set pixel_shape to span of input points wcs.pixel_shape = (1 if xpmax <= 0.0 else int(np.ceil(xpmax)), 1 if ypmax <= 0.0 else int(np.ceil(ypmax))) # determine CRVAL from input close = lambda l, p: p[np.argmin(np.abs(l))] if use_center_as_proj_point: # use center of input points sc1 = SkyCoord(lon.min()*u.deg, lat.max()*u.deg) sc2 = SkyCoord(lon.max()*u.deg, lat.min()*u.deg) pa = sc1.position_angle(sc2) sep = sc1.separation(sc2) midpoint_sc = sc1.directional_offset_by(pa, sep/2) wcs.wcs.crval = ((midpoint_sc.data.lon.deg, midpoint_sc.data.lat.deg)) wcs.wcs.crpix = ((xpmax + xpmin) / 2., (ypmax + ypmin) / 2.) else: # convert units, initial guess for crpix proj_point.transform_to(world_coords) wcs.wcs.crval = (proj_point.data.lon.deg, proj_point.data.lat.deg) wcs.wcs.crpix = (close(lon - wcs.wcs.crval[0], xp + 1), close(lon - wcs.wcs.crval[1], yp + 1)) # fit linear terms, assign to wcs # use (1, 0, 0, 1) as initial guess, in case input wcs was passed in # and cd terms are way off. # Use bounds to require that the fit center pixel is on the input image if xpmin == xpmax: xpmin, xpmax = xpmin - 0.5, xpmax + 0.5 if ypmin == ypmax: ypmin, ypmax = ypmin - 0.5, ypmax + 0.5 p0 = np.concatenate([wcs.wcs.cd.flatten(), wcs.wcs.crpix.flatten()]) fit = least_squares( _linear_wcs_fit, p0, args=(lon, lat, xp, yp, wcs), bounds=[[-np.inf, -np.inf, -np.inf, -np.inf, xpmin + 1, ypmin + 1], [np.inf, np.inf, np.inf, np.inf, xpmax + 1, ypmax + 1]] ) wcs.wcs.crpix = np.array(fit.x[4:6]) wcs.wcs.cd = np.array(fit.x[0:4].reshape((2, 2))) # fit SIP, if specified. Only fit forward coefficients if sip_degree: degree = sip_degree if '-SIP' not in wcs.wcs.ctype[0]: wcs.wcs.ctype = [x + '-SIP' for x in wcs.wcs.ctype] coef_names = [f'{i}_{j}' for i in range(degree+1) for j in range(degree+1) if (i+j) < (degree+1) and (i+j) > 1] p0 = np.concatenate((np.array(wcs.wcs.crpix), wcs.wcs.cd.flatten(), np.zeros(2*len(coef_names)))) fit = least_squares( _sip_fit, p0, args=(lon, lat, xp, yp, wcs, degree, coef_names), bounds=[[xpmin + 1, ypmin + 1] + [-np.inf]*(4 + 2*len(coef_names)), [xpmax + 1, ypmax + 1] + [np.inf]*(4 + 2*len(coef_names))] ) coef_fit = (list(fit.x[6:6+len(coef_names)]), list(fit.x[6+len(coef_names):])) # put fit values in wcs wcs.wcs.cd = fit.x[2:6].reshape((2, 2)) wcs.wcs.crpix = fit.x[0:2] a_vals = np.zeros((degree+1, degree+1)) b_vals = np.zeros((degree+1, degree+1)) for coef_name in coef_names: a_vals[int(coef_name[0])][int(coef_name[2])] = coef_fit[0].pop(0) b_vals[int(coef_name[0])][int(coef_name[2])] = coef_fit[1].pop(0) wcs.sip = Sip(a_vals, b_vals, np.zeros((degree+1, degree+1)), np.zeros((degree+1, degree+1)), wcs.wcs.crpix) return wcs def obsgeo_to_frame(obsgeo, obstime): """ Convert a WCS obsgeo property into an `~.builtin_frames.ITRS` coordinate frame. Parameters ---------- obsgeo : array-like A shape ``(6, )`` array representing ``OBSGEO-[XYZ], OBSGEO-[BLH]`` as returned by ``WCS.wcs.obsgeo``. obstime : time-like The time associated with the coordinate, will be passed to `~.builtin_frames.ITRS` as the obstime keyword. Returns ------- `~.builtin_frames.ITRS` An `~.builtin_frames.ITRS` coordinate frame representing the coordinates. Notes ----- The obsgeo array as accessed on a `.WCS` object is a length 6 numpy array where the first three elements are the coordinate in a cartesian representation and the second 3 are the coordinate in a spherical representation. This function priorities reading the cartesian coordinates, and will only read the spherical coordinates if the cartesian coordinates are either all zero or any of the cartesian coordinates are non-finite. In the case where both the spherical and cartesian coordinates have some non-finite values the spherical coordinates will be returned with the non-finite values included. """ if (obsgeo is None or len(obsgeo) != 6 or np.all(np.array(obsgeo) == 0) or np.all(~np.isfinite(obsgeo)) ): raise ValueError(f"Can not parse the 'obsgeo' location ({obsgeo}). " "obsgeo should be a length 6 non-zero, finite numpy array") # If the cartesian coords are zero or have NaNs in them use the spherical ones if np.all(obsgeo[:3] == 0) or np.any(~np.isfinite(obsgeo[:3])): data = SphericalRepresentation(*(obsgeo[3:] * (u.deg, u.deg, u.m))) # Otherwise we assume the cartesian ones are valid else: data = CartesianRepresentation(*obsgeo[:3] * u.m) return ITRS(data, obstime=obstime) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/wcs.py0000644000175100001710000040414500000000000015720 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst # Under the hood, there are 3 separate classes that perform different # parts of the transformation: # # - `~astropy.wcs.Wcsprm`: Is a direct wrapper of the core WCS # functionality in `wcslib`_. (This includes TPV and TPD # polynomial distortion, but not SIP distortion). # # - `~astropy.wcs.Sip`: Handles polynomial distortion as defined in the # `SIP`_ convention. # # - `~astropy.wcs.DistortionLookupTable`: Handles `distortion paper`_ # lookup tables. # # Additionally, the class `WCS` aggregates all of these transformations # together in a pipeline: # # - Detector to image plane correction (by a pair of # `~astropy.wcs.DistortionLookupTable` objects). # # - `SIP`_ distortion correction (by an underlying `~astropy.wcs.Sip` # object) # # - `distortion paper`_ table-lookup correction (by a pair of # `~astropy.wcs.DistortionLookupTable` objects). # # - `wcslib`_ WCS transformation (by a `~astropy.wcs.Wcsprm` object) # STDLIB import copy import uuid import io import itertools import os import re import textwrap import warnings import builtins # THIRD-PARTY import numpy as np # LOCAL from astropy import log from astropy.io import fits from . import docstrings from . import _wcs from astropy import units as u from astropy.utils.compat import possible_filename from astropy.utils.exceptions import AstropyWarning, AstropyUserWarning, AstropyDeprecationWarning from astropy.utils.decorators import deprecated_renamed_argument # Mix-in class that provides the APE 14 API from .wcsapi.fitswcs import FITSWCSAPIMixin, SlicedFITSWCS __all__ = ['FITSFixedWarning', 'WCS', 'find_all_wcs', 'DistortionLookupTable', 'Sip', 'Tabprm', 'Wcsprm', 'Auxprm', 'Wtbarr', 'WCSBase', 'validate', 'WcsError', 'SingularMatrixError', 'InconsistentAxisTypesError', 'InvalidTransformError', 'InvalidCoordinateError', 'NoSolutionError', 'InvalidSubimageSpecificationError', 'NoConvergence', 'NonseparableSubimageCoordinateSystemError', 'NoWcsKeywordsFoundError', 'InvalidTabularParametersError'] __doctest_skip__ = ['WCS.all_world2pix'] if _wcs is not None: _parsed_version = _wcs.__version__.split('.') if int(_parsed_version[0]) == 5 and int(_parsed_version[1]) < 8: raise ImportError( "astropy.wcs is built with wcslib {0}, but only versions 5.8 and " "later on the 5.x series are known to work. The version of wcslib " "that ships with astropy may be used.") if not _wcs._sanity_check(): raise RuntimeError( "astropy.wcs did not pass its sanity check for your build " "on your platform.") WCSBase = _wcs._Wcs DistortionLookupTable = _wcs.DistortionLookupTable Sip = _wcs.Sip Wcsprm = _wcs.Wcsprm Auxprm = _wcs.Auxprm Tabprm = _wcs.Tabprm Wtbarr = _wcs.Wtbarr WcsError = _wcs.WcsError SingularMatrixError = _wcs.SingularMatrixError InconsistentAxisTypesError = _wcs.InconsistentAxisTypesError InvalidTransformError = _wcs.InvalidTransformError InvalidCoordinateError = _wcs.InvalidCoordinateError NoSolutionError = _wcs.NoSolutionError InvalidSubimageSpecificationError = _wcs.InvalidSubimageSpecificationError NonseparableSubimageCoordinateSystemError = _wcs.NonseparableSubimageCoordinateSystemError NoWcsKeywordsFoundError = _wcs.NoWcsKeywordsFoundError InvalidTabularParametersError = _wcs.InvalidTabularParametersError # Copy all the constants from the C extension into this module's namespace for key, val in _wcs.__dict__.items(): if key.startswith(('WCSSUB_', 'WCSHDR_', 'WCSHDO_', 'WCSCOMPARE_')): locals()[key] = val __all__.append(key) # Set coordinate extraction callback for WCS -TAB: def _load_tab_bintable(hdulist, extnam, extver, extlev, kind, ttype, row, ndim): arr = hdulist[(extnam, extver)].data[ttype][row - 1] if arr.ndim != ndim: if kind == 'c' and ndim == 2: arr = arr.reshape((arr.size, 1)) else: raise ValueError("Bad TDIM") return np.ascontiguousarray(arr, dtype=np.double) _wcs.set_wtbarr_fitsio_callback(_load_tab_bintable) else: WCSBase = object Wcsprm = object DistortionLookupTable = object Sip = object Tabprm = object Wtbarr = object WcsError = None SingularMatrixError = None InconsistentAxisTypesError = None InvalidTransformError = None InvalidCoordinateError = None NoSolutionError = None InvalidSubimageSpecificationError = None NonseparableSubimageCoordinateSystemError = None NoWcsKeywordsFoundError = None InvalidTabularParametersError = None # Additional relax bit flags WCSHDO_SIP = 0x80000 # Regular expression defining SIP keyword It matches keyword that starts with A # or B, optionally followed by P, followed by an underscore then a number in # range of 0-19, followed by an underscore and another number in range of 0-19. # Keyword optionally ends with a capital letter. SIP_KW = re.compile('''^[AB]P?_1?[0-9]_1?[0-9][A-Z]?$''') def _parse_keysel(keysel): keysel_flags = 0 if keysel is not None: for element in keysel: if element.lower() == 'image': keysel_flags |= _wcs.WCSHDR_IMGHEAD elif element.lower() == 'binary': keysel_flags |= _wcs.WCSHDR_BIMGARR elif element.lower() == 'pixel': keysel_flags |= _wcs.WCSHDR_PIXLIST else: raise ValueError( "keysel must be a list of 'image', 'binary' " + "and/or 'pixel'") else: keysel_flags = -1 return keysel_flags class NoConvergence(Exception): """ An error class used to report non-convergence and/or divergence of numerical methods. It is used to report errors in the iterative solution used by the :py:meth:`~astropy.wcs.WCS.all_world2pix`. Attributes ---------- best_solution : `numpy.ndarray` Best solution achieved by the numerical method. accuracy : `numpy.ndarray` Accuracy of the ``best_solution``. niter : `int` Number of iterations performed by the numerical method to compute ``best_solution``. divergent : None, `numpy.ndarray` Indices of the points in ``best_solution`` array for which the solution appears to be divergent. If the solution does not diverge, ``divergent`` will be set to `None`. slow_conv : None, `numpy.ndarray` Indices of the solutions in ``best_solution`` array for which the solution failed to converge within the specified maximum number of iterations. If there are no non-converging solutions (i.e., if the required accuracy has been achieved for all input data points) then ``slow_conv`` will be set to `None`. """ def __init__(self, *args, best_solution=None, accuracy=None, niter=None, divergent=None, slow_conv=None, **kwargs): super().__init__(*args) self.best_solution = best_solution self.accuracy = accuracy self.niter = niter self.divergent = divergent self.slow_conv = slow_conv if kwargs: warnings.warn("Function received unexpected arguments ({}) these " "are ignored but will raise an Exception in the " "future.".format(list(kwargs)), AstropyDeprecationWarning) class FITSFixedWarning(AstropyWarning): """ The warning raised when the contents of the FITS header have been modified to be standards compliant. """ pass class WCS(FITSWCSAPIMixin, WCSBase): """WCS objects perform standard WCS transformations, and correct for `SIP`_ and `distortion paper`_ table-lookup transformations, based on the WCS keywords and supplementary data read from a FITS file. See also: https://docs.astropy.org/en/stable/wcs/ Parameters ---------- header : `~astropy.io.fits.Header`, `~astropy.io.fits.hdu.image.PrimaryHDU`, `~astropy.io.fits.hdu.image.ImageHDU`, str, dict-like, or None, optional If *header* is not provided or None, the object will be initialized to default values. fobj : `~astropy.io.fits.HDUList`, optional It is needed when header keywords point to a `distortion paper`_ lookup table stored in a different extension. key : str, optional The name of a particular WCS transform to use. This may be either ``' '`` or ``'A'``-``'Z'`` and corresponds to the ``\"a\"`` part of the ``CTYPEia`` cards. *key* may only be provided if *header* is also provided. minerr : float, optional The minimum value a distortion correction must have in order to be applied. If the value of ``CQERRja`` is smaller than *minerr*, the corresponding distortion is not applied. relax : bool or int, optional Degree of permissiveness: - `True` (default): Admit all recognized informal extensions of the WCS standard. - `False`: Recognize only FITS keywords defined by the published WCS standard. - `int`: a bit field selecting specific extensions to accept. See :ref:`astropy:relaxread` for details. naxis : int or sequence, optional Extracts specific coordinate axes using :meth:`~astropy.wcs.Wcsprm.sub`. If a header is provided, and *naxis* is not ``None``, *naxis* will be passed to :meth:`~astropy.wcs.Wcsprm.sub` in order to select specific axes from the header. See :meth:`~astropy.wcs.Wcsprm.sub` for more details about this parameter. keysel : sequence of str, optional A sequence of flags used to select the keyword types considered by wcslib. When ``None``, only the standard image header keywords are considered (and the underlying wcspih() C function is called). To use binary table image array or pixel list keywords, *keysel* must be set. Each element in the list should be one of the following strings: - 'image': Image header keywords - 'binary': Binary table image array keywords - 'pixel': Pixel list keywords Keywords such as ``EQUIna`` or ``RFRQna`` that are common to binary table image arrays and pixel lists (including ``WCSNna`` and ``TWCSna``) are selected by both 'binary' and 'pixel'. colsel : sequence of int, optional A sequence of table column numbers used to restrict the WCS transformations considered to only those pertaining to the specified columns. If `None`, there is no restriction. fix : bool, optional When `True` (default), call `~astropy.wcs.Wcsprm.fix` on the resulting object to fix any non-standard uses in the header. `FITSFixedWarning` Warnings will be emitted if any changes were made. translate_units : str, optional Specify which potentially unsafe translations of non-standard unit strings to perform. By default, performs none. See `WCS.fix` for more information about this parameter. Only effective when ``fix`` is `True`. Raises ------ MemoryError Memory allocation failed. ValueError Invalid key. KeyError Key not found in FITS header. ValueError Lookup table distortion present in the header but *fobj* was not provided. Notes ----- 1. astropy.wcs supports arbitrary *n* dimensions for the core WCS (the transformations handled by WCSLIB). However, the `distortion paper`_ lookup table and `SIP`_ distortions must be two dimensional. Therefore, if you try to create a WCS object where the core WCS has a different number of dimensions than 2 and that object also contains a `distortion paper`_ lookup table or `SIP`_ distortion, a `ValueError` exception will be raised. To avoid this, consider using the *naxis* kwarg to select two dimensions from the core WCS. 2. The number of coordinate axes in the transformation is not determined directly from the ``NAXIS`` keyword but instead from the highest of: - ``NAXIS`` keyword - ``WCSAXESa`` keyword - The highest axis number in any parameterized WCS keyword. The keyvalue, as well as the keyword, must be syntactically valid otherwise it will not be considered. If none of these keyword types is present, i.e. if the header only contains auxiliary WCS keywords for a particular coordinate representation, then no coordinate description is constructed for it. The number of axes, which is set as the ``naxis`` member, may differ for different coordinate representations of the same image. 3. When the header includes duplicate keywords, in most cases the last encountered is used. 4. `~astropy.wcs.Wcsprm.set` is called immediately after construction, so any invalid keywords or transformations will be raised by the constructor, not when subsequently calling a transformation method. """ # noqa: E501 def __init__(self, header=None, fobj=None, key=' ', minerr=0.0, relax=True, naxis=None, keysel=None, colsel=None, fix=True, translate_units='', _do_set=True): close_fds = [] # these parameters are stored to be used when unpickling a WCS object: self._init_kwargs = { 'keysel': copy.copy(keysel), 'colsel': copy.copy(colsel), } if header is None: if naxis is None: naxis = 2 wcsprm = _wcs.Wcsprm(header=None, key=key, relax=relax, naxis=naxis) self.naxis = wcsprm.naxis # Set some reasonable defaults. det2im = (None, None) cpdis = (None, None) sip = None else: keysel_flags = _parse_keysel(keysel) if isinstance(header, (str, bytes)): try: is_path = (possible_filename(header) and os.path.exists(header)) except (OSError, ValueError): is_path = False if is_path: if fobj is not None: raise ValueError( "Can not provide both a FITS filename to " "argument 1 and a FITS file object to argument 2") fobj = fits.open(header) close_fds.append(fobj) header = fobj[0].header elif isinstance(header, fits.hdu.image._ImageBaseHDU): header = header.header elif not isinstance(header, fits.Header): try: # Accept any dict-like object orig_header = header header = fits.Header() for dict_key in orig_header.keys(): header[dict_key] = orig_header[dict_key] except TypeError: raise TypeError( "header must be a string, an astropy.io.fits.Header " "object, or a dict-like object") if isinstance(header, fits.Header): header_string = header.tostring().rstrip() else: header_string = header # Importantly, header is a *copy* of the passed-in header # because we will be modifying it if isinstance(header_string, str): header_bytes = header_string.encode('ascii') header_string = header_string else: header_bytes = header_string header_string = header_string.decode('ascii') if not (fobj is None or isinstance(fobj, fits.HDUList)): raise AssertionError("'fobj' must be either None or an " "astropy.io.fits.HDUList object.") est_naxis = 2 try: tmp_header = fits.Header.fromstring(header_string) self._remove_sip_kw(tmp_header) tmp_header_bytes = tmp_header.tostring().rstrip() if isinstance(tmp_header_bytes, str): tmp_header_bytes = tmp_header_bytes.encode('ascii') tmp_wcsprm = _wcs.Wcsprm(header=tmp_header_bytes, key=key, relax=relax, keysel=keysel_flags, colsel=colsel, warnings=False, hdulist=fobj) if naxis is not None: try: tmp_wcsprm = tmp_wcsprm.sub(naxis) except ValueError: pass est_naxis = tmp_wcsprm.naxis if tmp_wcsprm.naxis else 2 except _wcs.NoWcsKeywordsFoundError: pass self.naxis = est_naxis header = fits.Header.fromstring(header_string) det2im = self._read_det2im_kw(header, fobj, err=minerr) cpdis = self._read_distortion_kw( header, fobj, dist='CPDIS', err=minerr) sip = self._read_sip_kw(header, wcskey=key) self._remove_sip_kw(header) header_string = header.tostring() header_string = header_string.replace('END' + ' ' * 77, '') if isinstance(header_string, str): header_bytes = header_string.encode('ascii') header_string = header_string else: header_bytes = header_string header_string = header_string.decode('ascii') try: wcsprm = _wcs.Wcsprm(header=header_bytes, key=key, relax=relax, keysel=keysel_flags, colsel=colsel, hdulist=fobj) except _wcs.NoWcsKeywordsFoundError: # The header may have SIP or distortions, but no core # WCS. That isn't an error -- we want a "default" # (identity) core Wcs transformation in that case. if colsel is None: wcsprm = _wcs.Wcsprm(header=None, key=key, relax=relax, keysel=keysel_flags, colsel=colsel, hdulist=fobj) else: raise if naxis is not None: wcsprm = wcsprm.sub(naxis) self.naxis = wcsprm.naxis if (wcsprm.naxis != 2 and (det2im[0] or det2im[1] or cpdis[0] or cpdis[1] or sip)): raise ValueError( """ FITS WCS distortion paper lookup tables and SIP distortions only work in 2 dimensions. However, WCSLIB has detected {} dimensions in the core WCS keywords. To use core WCS in conjunction with FITS WCS distortion paper lookup tables or SIP distortion, you must select or reduce these to 2 dimensions using the naxis kwarg. """.format(wcsprm.naxis)) header_naxis = header.get('NAXIS', None) if header_naxis is not None and header_naxis < wcsprm.naxis: warnings.warn( "The WCS transformation has more axes ({:d}) than the " "image it is associated with ({:d})".format( wcsprm.naxis, header_naxis), FITSFixedWarning) self._get_naxis(header) WCSBase.__init__(self, sip, cpdis, wcsprm, det2im) if fix: if header is None: with warnings.catch_warnings(): warnings.simplefilter('ignore', FITSFixedWarning) self.fix(translate_units=translate_units) else: self.fix(translate_units=translate_units) if _do_set: self.wcs.set() for fd in close_fds: fd.close() self._pixel_bounds = None def __copy__(self): new_copy = self.__class__() WCSBase.__init__(new_copy, self.sip, (self.cpdis1, self.cpdis2), self.wcs, (self.det2im1, self.det2im2)) new_copy.__dict__.update(self.__dict__) return new_copy def __deepcopy__(self, memo): from copy import deepcopy new_copy = self.__class__() new_copy.naxis = deepcopy(self.naxis, memo) WCSBase.__init__(new_copy, deepcopy(self.sip, memo), (deepcopy(self.cpdis1, memo), deepcopy(self.cpdis2, memo)), deepcopy(self.wcs, memo), (deepcopy(self.det2im1, memo), deepcopy(self.det2im2, memo))) for key, val in self.__dict__.items(): new_copy.__dict__[key] = deepcopy(val, memo) return new_copy def copy(self): """ Return a shallow copy of the object. Convenience method so user doesn't have to import the :mod:`copy` stdlib module. .. warning:: Use `deepcopy` instead of `copy` unless you know why you need a shallow copy. """ return copy.copy(self) def deepcopy(self): """ Return a deep copy of the object. Convenience method so user doesn't have to import the :mod:`copy` stdlib module. """ return copy.deepcopy(self) def sub(self, axes=None): copy = self.deepcopy() # We need to know which axes have been dropped, but there is no easy # way to do this with the .sub function, so instead we assign UUIDs to # the CNAME parameters in copy.wcs. We can later access the original # CNAME properties from self.wcs. cname_uuid = [str(uuid.uuid4()) for i in range(copy.wcs.naxis)] copy.wcs.cname = cname_uuid # Subset the WCS copy.wcs = copy.wcs.sub(axes) copy.naxis = copy.wcs.naxis # Construct a list of dimensions from the original WCS in the order # in which they appear in the final WCS. keep = [cname_uuid.index(cname) if cname in cname_uuid else None for cname in copy.wcs.cname] # Restore the original CNAMEs copy.wcs.cname = ['' if i is None else self.wcs.cname[i] for i in keep] # Subset pixel_shape and pixel_bounds if self.pixel_shape: copy.pixel_shape = tuple([None if i is None else self.pixel_shape[i] for i in keep]) if self.pixel_bounds: copy.pixel_bounds = [None if i is None else self.pixel_bounds[i] for i in keep] return copy if _wcs is not None: sub.__doc__ = _wcs.Wcsprm.sub.__doc__ def _fix_scamp(self): """ Remove SCAMP's PVi_m distortion parameters if SIP distortion parameters are also present. Some projects (e.g., Palomar Transient Factory) convert SCAMP's distortion parameters (which abuse the PVi_m cards) to SIP. However, wcslib gets confused by the presence of both SCAMP and SIP distortion parameters. See https://github.com/astropy/astropy/issues/299. """ # Nothing to be done if no WCS attached if self.wcs is None: return # Nothing to be done if no PV parameters attached pv = self.wcs.get_pv() if not pv: return # Nothing to be done if axes don't use SIP distortion parameters if self.sip is None: return # Nothing to be done if any radial terms are present... # Loop over list to find any radial terms. # Certain values of the `j' index are used for storing # radial terms; refer to Equation (1) in # . pv = np.asarray(pv) # Loop over distinct values of `i' index for i in set(pv[:, 0]): # Get all values of `j' index for this value of `i' index js = set(pv[:, 1][pv[:, 0] == i]) # Find max value of `j' index max_j = max(js) for j in (3, 11, 23, 39): if j < max_j and j in js: return self.wcs.set_pv([]) warnings.warn("Removed redundant SCAMP distortion parameters " + "because SIP parameters are also present", FITSFixedWarning) def fix(self, translate_units='', naxis=None): """ Perform the fix operations from wcslib, and warn about any changes it has made. Parameters ---------- translate_units : str, optional Specify which potentially unsafe translations of non-standard unit strings to perform. By default, performs none. Although ``"S"`` is commonly used to represent seconds, its translation to ``"s"`` is potentially unsafe since the standard recognizes ``"S"`` formally as Siemens, however rarely that may be used. The same applies to ``"H"`` for hours (Henry), and ``"D"`` for days (Debye). This string controls what to do in such cases, and is case-insensitive. - If the string contains ``"s"``, translate ``"S"`` to ``"s"``. - If the string contains ``"h"``, translate ``"H"`` to ``"h"``. - If the string contains ``"d"``, translate ``"D"`` to ``"d"``. Thus ``''`` doesn't do any unsafe translations, whereas ``'shd'`` does all of them. naxis : int array, optional Image axis lengths. If this array is set to zero or ``None``, then `~astropy.wcs.Wcsprm.cylfix` will not be invoked. """ if self.wcs is not None: self._fix_scamp() fixes = self.wcs.fix(translate_units, naxis) for key, val in fixes.items(): if val != "No change": if (key == 'datfix' and '1858-11-17' in val and not np.count_nonzero(self.wcs.mjdref)): continue warnings.warn( ("'{0}' made the change '{1}'."). format(key, val), FITSFixedWarning) def calc_footprint(self, header=None, undistort=True, axes=None, center=True): """ Calculates the footprint of the image on the sky. A footprint is defined as the positions of the corners of the image on the sky after all available distortions have been applied. Parameters ---------- header : `~astropy.io.fits.Header` object, optional Used to get ``NAXIS1`` and ``NAXIS2`` header and axes are mutually exclusive, alternative ways to provide the same information. undistort : bool, optional If `True`, take SIP and distortion lookup table into account axes : (int, int), optional If provided, use the given sequence as the shape of the image. Otherwise, use the ``NAXIS1`` and ``NAXIS2`` keywords from the header that was used to create this `WCS` object. center : bool, optional If `True` use the center of the pixel, otherwise use the corner. Returns ------- coord : (4, 2) array of (*x*, *y*) coordinates. The order is clockwise starting with the bottom left corner. """ if axes is not None: naxis1, naxis2 = axes else: if header is None: try: # classes that inherit from WCS and define naxis1/2 # do not require a header parameter naxis1, naxis2 = self.pixel_shape except (AttributeError, TypeError): warnings.warn( "Need a valid header in order to calculate footprint\n", AstropyUserWarning) return None else: naxis1 = header.get('NAXIS1', None) naxis2 = header.get('NAXIS2', None) if naxis1 is None or naxis2 is None: raise ValueError( "Image size could not be determined.") if center: corners = np.array([[1, 1], [1, naxis2], [naxis1, naxis2], [naxis1, 1]], dtype=np.float64) else: corners = np.array([[0.5, 0.5], [0.5, naxis2 + 0.5], [naxis1 + 0.5, naxis2 + 0.5], [naxis1 + 0.5, 0.5]], dtype=np.float64) if undistort: return self.all_pix2world(corners, 1) else: return self.wcs_pix2world(corners, 1) def _read_det2im_kw(self, header, fobj, err=0.0): """ Create a `distortion paper`_ type lookup table for detector to image plane correction. """ if fobj is None: return (None, None) if not isinstance(fobj, fits.HDUList): return (None, None) try: axiscorr = header['AXISCORR'] d2imdis = self._read_d2im_old_format(header, fobj, axiscorr) return d2imdis except KeyError: pass dist = 'D2IMDIS' d_kw = 'D2IM' err_kw = 'D2IMERR' tables = {} for i in range(1, self.naxis + 1): d_error = header.get(err_kw + str(i), 0.0) if d_error < err: tables[i] = None continue distortion = dist + str(i) if distortion in header: dis = header[distortion].lower() if dis == 'lookup': del header[distortion] assert isinstance(fobj, fits.HDUList), ( 'An astropy.io.fits.HDUList' 'is required for Lookup table distortion.') dp = (d_kw + str(i)).strip() dp_extver_key = dp + '.EXTVER' if dp_extver_key in header: d_extver = header[dp_extver_key] del header[dp_extver_key] else: d_extver = 1 dp_axis_key = dp + f'.AXIS.{i:d}' if i == header[dp_axis_key]: d_data = fobj['D2IMARR', d_extver].data else: d_data = (fobj['D2IMARR', d_extver].data).transpose() del header[dp_axis_key] d_header = fobj['D2IMARR', d_extver].header d_crpix = (d_header.get('CRPIX1', 0.0), d_header.get('CRPIX2', 0.0)) d_crval = (d_header.get('CRVAL1', 0.0), d_header.get('CRVAL2', 0.0)) d_cdelt = (d_header.get('CDELT1', 1.0), d_header.get('CDELT2', 1.0)) d_lookup = DistortionLookupTable(d_data, d_crpix, d_crval, d_cdelt) tables[i] = d_lookup else: warnings.warn('Polynomial distortion is not implemented.\n', AstropyUserWarning) for key in set(header): if key.startswith(dp + '.'): del header[key] else: tables[i] = None if not tables: return (None, None) else: return (tables.get(1), tables.get(2)) def _read_d2im_old_format(self, header, fobj, axiscorr): warnings.warn( "The use of ``AXISCORR`` for D2IM correction has been deprecated." "`~astropy.wcs` will read in files with ``AXISCORR`` but ``to_fits()`` will write " "out files without it.", AstropyDeprecationWarning) cpdis = [None, None] crpix = [0., 0.] crval = [0., 0.] cdelt = [1., 1.] try: d2im_data = fobj[('D2IMARR', 1)].data except KeyError: return (None, None) except AttributeError: return (None, None) d2im_data = np.array([d2im_data]) d2im_hdr = fobj[('D2IMARR', 1)].header naxis = d2im_hdr['NAXIS'] for i in range(1, naxis + 1): crpix[i - 1] = d2im_hdr.get('CRPIX' + str(i), 0.0) crval[i - 1] = d2im_hdr.get('CRVAL' + str(i), 0.0) cdelt[i - 1] = d2im_hdr.get('CDELT' + str(i), 1.0) cpdis = DistortionLookupTable(d2im_data, crpix, crval, cdelt) if axiscorr == 1: return (cpdis, None) elif axiscorr == 2: return (None, cpdis) else: warnings.warn("Expected AXISCORR to be 1 or 2", AstropyUserWarning) return (None, None) def _write_det2im(self, hdulist): """ Writes a `distortion paper`_ type lookup table to the given `~astropy.io.fits.HDUList`. """ if self.det2im1 is None and self.det2im2 is None: return dist = 'D2IMDIS' d_kw = 'D2IM' def write_d2i(num, det2im): if det2im is None: return hdulist[0].header[f'{dist}{num:d}'] = ( 'LOOKUP', 'Detector to image correction type') hdulist[0].header[f'{d_kw}{num:d}.EXTVER'] = ( num, 'Version number of WCSDVARR extension') hdulist[0].header[f'{d_kw}{num:d}.NAXES'] = ( len(det2im.data.shape), 'Number of independent variables in D2IM function') for i in range(det2im.data.ndim): jth = {1: '1st', 2: '2nd', 3: '3rd'}.get(i + 1, f'{i + 1}th') hdulist[0].header[f'{d_kw}{num:d}.AXIS.{i + 1:d}'] = ( i + 1, f'Axis number of the {jth} variable in a D2IM function') image = fits.ImageHDU(det2im.data, name='D2IMARR') header = image.header header['CRPIX1'] = (det2im.crpix[0], 'Coordinate system reference pixel') header['CRPIX2'] = (det2im.crpix[1], 'Coordinate system reference pixel') header['CRVAL1'] = (det2im.crval[0], 'Coordinate system value at reference pixel') header['CRVAL2'] = (det2im.crval[1], 'Coordinate system value at reference pixel') header['CDELT1'] = (det2im.cdelt[0], 'Coordinate increment along axis') header['CDELT2'] = (det2im.cdelt[1], 'Coordinate increment along axis') image.ver = int(hdulist[0].header[f'{d_kw}{num:d}.EXTVER']) hdulist.append(image) write_d2i(1, self.det2im1) write_d2i(2, self.det2im2) def _read_distortion_kw(self, header, fobj, dist='CPDIS', err=0.0): """ Reads `distortion paper`_ table-lookup keywords and data, and returns a 2-tuple of `~astropy.wcs.DistortionLookupTable` objects. If no `distortion paper`_ keywords are found, ``(None, None)`` is returned. """ if isinstance(header, (str, bytes)): return (None, None) if dist == 'CPDIS': d_kw = 'DP' err_kw = 'CPERR' else: d_kw = 'DQ' err_kw = 'CQERR' tables = {} for i in range(1, self.naxis + 1): d_error_key = err_kw + str(i) if d_error_key in header: d_error = header[d_error_key] del header[d_error_key] else: d_error = 0.0 if d_error < err: tables[i] = None continue distortion = dist + str(i) if distortion in header: dis = header[distortion].lower() del header[distortion] if dis == 'lookup': if not isinstance(fobj, fits.HDUList): raise ValueError('an astropy.io.fits.HDUList is ' 'required for Lookup table distortion.') dp = (d_kw + str(i)).strip() dp_extver_key = dp + '.EXTVER' if dp_extver_key in header: d_extver = header[dp_extver_key] del header[dp_extver_key] else: d_extver = 1 dp_axis_key = dp + f'.AXIS.{i:d}' if i == header[dp_axis_key]: d_data = fobj['WCSDVARR', d_extver].data else: d_data = (fobj['WCSDVARR', d_extver].data).transpose() del header[dp_axis_key] d_header = fobj['WCSDVARR', d_extver].header d_crpix = (d_header.get('CRPIX1', 0.0), d_header.get('CRPIX2', 0.0)) d_crval = (d_header.get('CRVAL1', 0.0), d_header.get('CRVAL2', 0.0)) d_cdelt = (d_header.get('CDELT1', 1.0), d_header.get('CDELT2', 1.0)) d_lookup = DistortionLookupTable(d_data, d_crpix, d_crval, d_cdelt) tables[i] = d_lookup for key in set(header): if key.startswith(dp + '.'): del header[key] else: warnings.warn('Polynomial distortion is not implemented.\n', AstropyUserWarning) else: tables[i] = None if not tables: return (None, None) else: return (tables.get(1), tables.get(2)) def _write_distortion_kw(self, hdulist, dist='CPDIS'): """ Write out `distortion paper`_ keywords to the given `~astropy.io.fits.HDUList`. """ if self.cpdis1 is None and self.cpdis2 is None: return if dist == 'CPDIS': d_kw = 'DP' else: d_kw = 'DQ' def write_dist(num, cpdis): if cpdis is None: return hdulist[0].header[f'{dist}{num:d}'] = ( 'LOOKUP', 'Prior distortion function type') hdulist[0].header[f'{d_kw}{num:d}.EXTVER'] = ( num, 'Version number of WCSDVARR extension') hdulist[0].header[f'{d_kw}{num:d}.NAXES'] = ( len(cpdis.data.shape), f'Number of independent variables in {dist} function') for i in range(cpdis.data.ndim): jth = {1: '1st', 2: '2nd', 3: '3rd'}.get(i + 1, f'{i + 1}th') hdulist[0].header[f'{d_kw}{num:d}.AXIS.{i + 1:d}'] = ( i + 1, f'Axis number of the {jth} variable in a {dist} function') image = fits.ImageHDU(cpdis.data, name='WCSDVARR') header = image.header header['CRPIX1'] = (cpdis.crpix[0], 'Coordinate system reference pixel') header['CRPIX2'] = (cpdis.crpix[1], 'Coordinate system reference pixel') header['CRVAL1'] = (cpdis.crval[0], 'Coordinate system value at reference pixel') header['CRVAL2'] = (cpdis.crval[1], 'Coordinate system value at reference pixel') header['CDELT1'] = (cpdis.cdelt[0], 'Coordinate increment along axis') header['CDELT2'] = (cpdis.cdelt[1], 'Coordinate increment along axis') image.ver = int(hdulist[0].header[f'{d_kw}{num:d}.EXTVER']) hdulist.append(image) write_dist(1, self.cpdis1) write_dist(2, self.cpdis2) def _remove_sip_kw(self, header): """ Remove SIP information from a header. """ # Never pass SIP coefficients to wcslib # CTYPE must be passed with -SIP to wcslib for key in set(m.group() for m in map(SIP_KW.match, list(header)) if m is not None): del header[key] def _read_sip_kw(self, header, wcskey=""): """ Reads `SIP`_ header keywords and returns a `~astropy.wcs.Sip` object. If no `SIP`_ header keywords are found, ``None`` is returned. """ if isinstance(header, (str, bytes)): # TODO: Parse SIP from a string without pyfits around return None if "A_ORDER" in header and header['A_ORDER'] > 1: if "B_ORDER" not in header: raise ValueError( "A_ORDER provided without corresponding B_ORDER " "keyword for SIP distortion") m = int(header["A_ORDER"]) a = np.zeros((m + 1, m + 1), np.double) for i in range(m + 1): for j in range(m - i + 1): key = f"A_{i}_{j}" if key in header: a[i, j] = header[key] del header[key] m = int(header["B_ORDER"]) if m > 1: b = np.zeros((m + 1, m + 1), np.double) for i in range(m + 1): for j in range(m - i + 1): key = f"B_{i}_{j}" if key in header: b[i, j] = header[key] del header[key] else: a = None b = None del header['A_ORDER'] del header['B_ORDER'] ctype = [header[f'CTYPE{nax}{wcskey}'] for nax in range(1, self.naxis + 1)] if any(not ctyp.endswith('-SIP') for ctyp in ctype): message = """ Inconsistent SIP distortion information is present in the FITS header and the WCS object: SIP coefficients were detected, but CTYPE is missing a "-SIP" suffix. astropy.wcs is using the SIP distortion coefficients, therefore the coordinates calculated here might be incorrect. If you do not want to apply the SIP distortion coefficients, please remove the SIP coefficients from the FITS header or the WCS object. As an example, if the image is already distortion-corrected (e.g., drizzled) then distortion components should not apply and the SIP coefficients should be removed. While the SIP distortion coefficients are being applied here, if that was indeed the intent, for consistency please append "-SIP" to the CTYPE in the FITS header or the WCS object. """ # noqa: E501 log.info(message) elif "B_ORDER" in header and header['B_ORDER'] > 1: raise ValueError( "B_ORDER provided without corresponding A_ORDER " + "keyword for SIP distortion") else: a = None b = None if "AP_ORDER" in header and header['AP_ORDER'] > 1: if "BP_ORDER" not in header: raise ValueError( "AP_ORDER provided without corresponding BP_ORDER " "keyword for SIP distortion") m = int(header["AP_ORDER"]) ap = np.zeros((m + 1, m + 1), np.double) for i in range(m + 1): for j in range(m - i + 1): key = f"AP_{i}_{j}" if key in header: ap[i, j] = header[key] del header[key] m = int(header["BP_ORDER"]) if m > 1: bp = np.zeros((m + 1, m + 1), np.double) for i in range(m + 1): for j in range(m - i + 1): key = f"BP_{i}_{j}" if key in header: bp[i, j] = header[key] del header[key] else: ap = None bp = None del header['AP_ORDER'] del header['BP_ORDER'] elif "BP_ORDER" in header and header['BP_ORDER'] > 1: raise ValueError( "BP_ORDER provided without corresponding AP_ORDER " "keyword for SIP distortion") else: ap = None bp = None if a is None and b is None and ap is None and bp is None: return None if f"CRPIX1{wcskey}" not in header or f"CRPIX2{wcskey}" not in header: raise ValueError( "Header has SIP keywords without CRPIX keywords") crpix1 = header.get(f"CRPIX1{wcskey}") crpix2 = header.get(f"CRPIX2{wcskey}") return Sip(a, b, ap, bp, (crpix1, crpix2)) def _write_sip_kw(self): """ Write out SIP keywords. Returns a dictionary of key-value pairs. """ if self.sip is None: return {} keywords = {} def write_array(name, a): if a is None: return size = a.shape[0] trdir = 'sky to detector' if name[-1] == 'P' else 'detector to sky' comment = ('SIP polynomial order, axis {:d}, {:s}' .format(ord(name[0]) - ord('A'), trdir)) keywords[f'{name}_ORDER'] = size - 1, comment comment = 'SIP distortion coefficient' for i in range(size): for j in range(size - i): if a[i, j] != 0.0: keywords[ f'{name}_{i:d}_{j:d}'] = a[i, j], comment write_array('A', self.sip.a) write_array('B', self.sip.b) write_array('AP', self.sip.ap) write_array('BP', self.sip.bp) return keywords def _denormalize_sky(self, sky): if self.wcs.lngtyp != 'RA': raise ValueError( "WCS does not have longitude type of 'RA', therefore " + "(ra, dec) data can not be used as input") if self.wcs.lattyp != 'DEC': raise ValueError( "WCS does not have longitude type of 'DEC', therefore " + "(ra, dec) data can not be used as input") if self.wcs.naxis == 2: if self.wcs.lng == 0 and self.wcs.lat == 1: return sky elif self.wcs.lng == 1 and self.wcs.lat == 0: # Reverse the order of the columns return sky[:, ::-1] else: raise ValueError( "WCS does not have longitude and latitude celestial " + "axes, therefore (ra, dec) data can not be used as input") else: if self.wcs.lng < 0 or self.wcs.lat < 0: raise ValueError( "WCS does not have both longitude and latitude " "celestial axes, therefore (ra, dec) data can not be " + "used as input") out = np.zeros((sky.shape[0], self.wcs.naxis)) out[:, self.wcs.lng] = sky[:, 0] out[:, self.wcs.lat] = sky[:, 1] return out def _normalize_sky(self, sky): if self.wcs.lngtyp != 'RA': raise ValueError( "WCS does not have longitude type of 'RA', therefore " + "(ra, dec) data can not be returned") if self.wcs.lattyp != 'DEC': raise ValueError( "WCS does not have longitude type of 'DEC', therefore " + "(ra, dec) data can not be returned") if self.wcs.naxis == 2: if self.wcs.lng == 0 and self.wcs.lat == 1: return sky elif self.wcs.lng == 1 and self.wcs.lat == 0: # Reverse the order of the columns return sky[:, ::-1] else: raise ValueError( "WCS does not have longitude and latitude celestial " "axes, therefore (ra, dec) data can not be returned") else: if self.wcs.lng < 0 or self.wcs.lat < 0: raise ValueError( "WCS does not have both longitude and latitude celestial " "axes, therefore (ra, dec) data can not be returned") out = np.empty((sky.shape[0], 2)) out[:, 0] = sky[:, self.wcs.lng] out[:, 1] = sky[:, self.wcs.lat] return out def _array_converter(self, func, sky, *args, ra_dec_order=False): """ A helper function to support reading either a pair of arrays or a single Nx2 array. """ def _return_list_of_arrays(axes, origin): if any([x.size == 0 for x in axes]): return axes try: axes = np.broadcast_arrays(*axes) except ValueError: raise ValueError( "Coordinate arrays are not broadcastable to each other") xy = np.hstack([x.reshape((x.size, 1)) for x in axes]) if ra_dec_order and sky == 'input': xy = self._denormalize_sky(xy) output = func(xy, origin) if ra_dec_order and sky == 'output': output = self._normalize_sky(output) return (output[:, 0].reshape(axes[0].shape), output[:, 1].reshape(axes[0].shape)) return [output[:, i].reshape(axes[0].shape) for i in range(output.shape[1])] def _return_single_array(xy, origin): if xy.shape[-1] != self.naxis: raise ValueError( "When providing two arguments, the array must be " "of shape (N, {})".format(self.naxis)) if 0 in xy.shape: return xy if ra_dec_order and sky == 'input': xy = self._denormalize_sky(xy) result = func(xy, origin) if ra_dec_order and sky == 'output': result = self._normalize_sky(result) return result if len(args) == 2: try: xy, origin = args xy = np.asarray(xy) origin = int(origin) except Exception: raise TypeError( "When providing two arguments, they must be " "(coords[N][{}], origin)".format(self.naxis)) if xy.shape == () or len(xy.shape) == 1: return _return_list_of_arrays([xy], origin) return _return_single_array(xy, origin) elif len(args) == self.naxis + 1: axes = args[:-1] origin = args[-1] try: axes = [np.asarray(x) for x in axes] origin = int(origin) except Exception: raise TypeError( "When providing more than two arguments, they must be " + "a 1-D array for each axis, followed by an origin.") return _return_list_of_arrays(axes, origin) raise TypeError( "WCS projection has {0} dimensions, so expected 2 (an Nx{0} array " "and the origin argument) or {1} arguments (the position in each " "dimension, and the origin argument). Instead, {2} arguments were " "given.".format( self.naxis, self.naxis + 1, len(args))) def all_pix2world(self, *args, **kwargs): return self._array_converter( self._all_pix2world, 'output', *args, **kwargs) all_pix2world.__doc__ = """ Transforms pixel coordinates to world coordinates. Performs all of the following in series: - Detector to image plane correction (if present in the FITS file) - `SIP`_ distortion correction (if present in the FITS file) - `distortion paper`_ table-lookup correction (if present in the FITS file) - `wcslib`_ "core" WCS transformation Parameters ---------- {} For a transformation that is not two-dimensional, the two-argument form must be used. {} Returns ------- {} Notes ----- The order of the axes for the result is determined by the ``CTYPEia`` keywords in the FITS header, therefore it may not always be of the form (*ra*, *dec*). The `~astropy.wcs.Wcsprm.lat`, `~astropy.wcs.Wcsprm.lng`, `~astropy.wcs.Wcsprm.lattyp` and `~astropy.wcs.Wcsprm.lngtyp` members can be used to determine the order of the axes. Raises ------ MemoryError Memory allocation failed. SingularMatrixError Linear transformation matrix is singular. InconsistentAxisTypesError Inconsistent or unrecognized coordinate axis types. ValueError Invalid parameter value. ValueError Invalid coordinate transformation parameters. ValueError x- and y-coordinate arrays are not the same size. InvalidTransformError Invalid coordinate transformation parameters. InvalidTransformError Ill-conditioned coordinate transformation parameters. """.format(docstrings.TWO_OR_MORE_ARGS('naxis', 8), docstrings.RA_DEC_ORDER(8), docstrings.RETURNS('sky coordinates, in degrees', 8)) def wcs_pix2world(self, *args, **kwargs): if self.wcs is None: raise ValueError("No basic WCS settings were created.") return self._array_converter( lambda xy, o: self.wcs.p2s(xy, o)['world'], 'output', *args, **kwargs) wcs_pix2world.__doc__ = """ Transforms pixel coordinates to world coordinates by doing only the basic `wcslib`_ transformation. No `SIP`_ or `distortion paper`_ table lookup correction is applied. To perform distortion correction, see `~astropy.wcs.WCS.all_pix2world`, `~astropy.wcs.WCS.sip_pix2foc`, `~astropy.wcs.WCS.p4_pix2foc`, or `~astropy.wcs.WCS.pix2foc`. Parameters ---------- {} For a transformation that is not two-dimensional, the two-argument form must be used. {} Returns ------- {} Raises ------ MemoryError Memory allocation failed. SingularMatrixError Linear transformation matrix is singular. InconsistentAxisTypesError Inconsistent or unrecognized coordinate axis types. ValueError Invalid parameter value. ValueError Invalid coordinate transformation parameters. ValueError x- and y-coordinate arrays are not the same size. InvalidTransformError Invalid coordinate transformation parameters. InvalidTransformError Ill-conditioned coordinate transformation parameters. Notes ----- The order of the axes for the result is determined by the ``CTYPEia`` keywords in the FITS header, therefore it may not always be of the form (*ra*, *dec*). The `~astropy.wcs.Wcsprm.lat`, `~astropy.wcs.Wcsprm.lng`, `~astropy.wcs.Wcsprm.lattyp` and `~astropy.wcs.Wcsprm.lngtyp` members can be used to determine the order of the axes. """.format(docstrings.TWO_OR_MORE_ARGS('naxis', 8), docstrings.RA_DEC_ORDER(8), docstrings.RETURNS('world coordinates, in degrees', 8)) def _all_world2pix(self, world, origin, tolerance, maxiter, adaptive, detect_divergence, quiet): # ############################################################ # # DESCRIPTION OF THE NUMERICAL METHOD ## # ############################################################ # In this section I will outline the method of solving # the inverse problem of converting world coordinates to # pixel coordinates (*inverse* of the direct transformation # `all_pix2world`) and I will summarize some of the aspects # of the method proposed here and some of the issues of the # original `all_world2pix` (in relation to this method) # discussed in https://github.com/astropy/astropy/issues/1977 # A more detailed discussion can be found here: # https://github.com/astropy/astropy/pull/2373 # # # ### Background ### # # # I will refer here to the [SIP Paper] # (http://fits.gsfc.nasa.gov/registry/sip/SIP_distortion_v1_0.pdf). # According to this paper, the effect of distortions as # described in *their* equation (1) is: # # (1) x = CD*(u+f(u)), # # where `x` is a *vector* of "intermediate spherical # coordinates" (equivalent to (x,y) in the paper) and `u` # is a *vector* of "pixel coordinates", and `f` is a vector # function describing geometrical distortions # (see equations 2 and 3 in SIP Paper. # However, I prefer to use `w` for "intermediate world # coordinates", `x` for pixel coordinates, and assume that # transformation `W` performs the **linear** # (CD matrix + projection onto celestial sphere) part of the # conversion from pixel coordinates to world coordinates. # Then we can re-write (1) as: # # (2) w = W*(x+f(x)) = T(x) # # In `astropy.wcs.WCS` transformation `W` is represented by # the `wcs_pix2world` member, while the combined ("total") # transformation (linear part + distortions) is performed by # `all_pix2world`. Below I summarize the notations and their # equivalents in `astropy.wcs.WCS`: # # | Equation term | astropy.WCS/meaning | # | ------------- | ---------------------------- | # | `x` | pixel coordinates | # | `w` | world coordinates | # | `W` | `wcs_pix2world()` | # | `W^{-1}` | `wcs_world2pix()` | # | `T` | `all_pix2world()` | # | `x+f(x)` | `pix2foc()` | # # # ### Direct Solving of Equation (2) ### # # # In order to find the pixel coordinates that correspond to # given world coordinates `w`, it is necessary to invert # equation (2): `x=T^{-1}(w)`, or solve equation `w==T(x)` # for `x`. However, this approach has the following # disadvantages: # 1. It requires unnecessary transformations (see next # section). # 2. It is prone to "RA wrapping" issues as described in # https://github.com/astropy/astropy/issues/1977 # (essentially because `all_pix2world` may return points with # a different phase than user's input `w`). # # # ### Description of the Method Used here ### # # # By applying inverse linear WCS transformation (`W^{-1}`) # to both sides of equation (2) and introducing notation `x'` # (prime) for the pixels coordinates obtained from the world # coordinates by applying inverse *linear* WCS transformation # ("focal plane coordinates"): # # (3) x' = W^{-1}(w) # # we obtain the following equation: # # (4) x' = x+f(x), # # or, # # (5) x = x'-f(x) # # This equation is well suited for solving using the method # of fixed-point iterations # (http://en.wikipedia.org/wiki/Fixed-point_iteration): # # (6) x_{i+1} = x'-f(x_i) # # As an initial value of the pixel coordinate `x_0` we take # "focal plane coordinate" `x'=W^{-1}(w)=wcs_world2pix(w)`. # We stop iterations when `|x_{i+1}-x_i||x_i-x_{i-1}|` # **when** `|x_{i+1}-x_i|>=tolerance` (when current # approximation is close to the true solution, # `|x_{i+1}-x_i|>|x_i-x_{i-1}|` may be due to rounding errors # and we ignore such "divergences" when # `|x_{i+1}-x_i|world transformations). # # As an added benefit, the process converges to the correct # solution in just one iteration when distortions are not # present (compare to # https://github.com/astropy/astropy/issues/1977 and # https://github.com/astropy/astropy/pull/2294): in this case # `pix2foc` is the identical transformation # `x_i=pix2foc(x_i)` and from equation (7) we get: # # x' = x_0 = wcs_world2pix(w) # x_1 = x' - pix2foc(x_0) + x_0 = x' - pix2foc(x') + x' = x' # = wcs_world2pix(w) = x_0 # => # |x_1-x_0| = 0 < tolerance (with tolerance > 0) # # However, for performance reasons, it is still better to # avoid iterations altogether and return the exact linear # solution (`wcs_world2pix`) right-away when non-linear # distortions are not present by checking that attributes # `sip`, `cpdis1`, `cpdis2`, `det2im1`, and `det2im2` are # *all* `None`. # # # ### Outline of the Algorithm ### # # # While the proposed code is relatively long (considering # the simplicity of the algorithm), this is due to: 1) # checking if iterative solution is necessary at all; 2) # checking for divergence; 3) re-implementation of the # completely vectorized algorithm as an "adaptive" vectorized # algorithm (for cases when some points diverge for which we # want to stop iterations). In my tests, the adaptive version # of the algorithm is about 50% slower than non-adaptive # version for all HST images. # # The essential part of the vectorized non-adaptive algorithm # (without divergence and other checks) can be described # as follows: # # pix0 = self.wcs_world2pix(world, origin) # pix = pix0.copy() # 0-order solution # # for k in range(maxiter): # # find correction to the previous solution: # dpix = self.pix2foc(pix, origin) - pix0 # # # compute norm (L2) of the correction: # dn = np.linalg.norm(dpix, axis=1) # # # apply correction: # pix -= dpix # # # check convergence: # if np.max(dn) < tolerance: # break # # return pix # # Here, the input parameter `world` can be a `MxN` array # where `M` is the number of coordinate axes in WCS and `N` # is the number of points to be converted simultaneously to # image coordinates. # # # ### IMPORTANT NOTE: ### # # If, in the future releases of the `~astropy.wcs`, # `pix2foc` will not apply all the required distortion # corrections then in the code below, calls to `pix2foc` will # have to be replaced with # wcs_world2pix(all_pix2world(pix_list, origin), origin) # # ############################################################ # # INITIALIZE ITERATIVE PROCESS: ## # ############################################################ # initial approximation (linear WCS based only) pix0 = self.wcs_world2pix(world, origin) # Check that an iterative solution is required at all # (when any of the non-CD-matrix-based corrections are # present). If not required return the initial # approximation (pix0). if not self.has_distortion: # No non-WCS corrections detected so # simply return initial approximation: return pix0 pix = pix0.copy() # 0-order solution # initial correction: dpix = self.pix2foc(pix, origin) - pix0 # Update initial solution: pix -= dpix # Norm (L2) squared of the correction: dn = np.sum(dpix*dpix, axis=1) dnprev = dn.copy() # if adaptive else dn tol2 = tolerance**2 # Prepare for iterative process k = 1 ind = None inddiv = None # Turn off numpy runtime warnings for 'invalid' and 'over': old_invalid = np.geterr()['invalid'] old_over = np.geterr()['over'] np.seterr(invalid='ignore', over='ignore') # ############################################################ # # NON-ADAPTIVE ITERATIONS: ## # ############################################################ if not adaptive: # Fixed-point iterations: while (np.nanmax(dn) >= tol2 and k < maxiter): # Find correction to the previous solution: dpix = self.pix2foc(pix, origin) - pix0 # Compute norm (L2) squared of the correction: dn = np.sum(dpix*dpix, axis=1) # Check for divergence (we do this in two stages # to optimize performance for the most common # scenario when successive approximations converge): if detect_divergence: divergent = (dn >= dnprev) if np.any(divergent): # Find solutions that have not yet converged: slowconv = (dn >= tol2) inddiv, = np.where(divergent & slowconv) if inddiv.shape[0] > 0: # Update indices of elements that # still need correction: conv = (dn < dnprev) iconv = np.where(conv) # Apply correction: dpixgood = dpix[iconv] pix[iconv] -= dpixgood dpix[iconv] = dpixgood # For the next iteration choose # non-divergent points that have not yet # converged to the requested accuracy: ind, = np.where(slowconv & conv) pix0 = pix0[ind] dnprev[ind] = dn[ind] k += 1 # Switch to adaptive iterations: adaptive = True break # Save current correction magnitudes for later: dnprev = dn # Apply correction: pix -= dpix k += 1 # ############################################################ # # ADAPTIVE ITERATIONS: ## # ############################################################ if adaptive: if ind is None: ind, = np.where(np.isfinite(pix).all(axis=1)) pix0 = pix0[ind] # "Adaptive" fixed-point iterations: while (ind.shape[0] > 0 and k < maxiter): # Find correction to the previous solution: dpixnew = self.pix2foc(pix[ind], origin) - pix0 # Compute norm (L2) of the correction: dnnew = np.sum(np.square(dpixnew), axis=1) # Bookkeeping of corrections: dnprev[ind] = dn[ind].copy() dn[ind] = dnnew if detect_divergence: # Find indices of pixels that are converging: conv = (dnnew < dnprev[ind]) iconv = np.where(conv) iiconv = ind[iconv] # Apply correction: dpixgood = dpixnew[iconv] pix[iiconv] -= dpixgood dpix[iiconv] = dpixgood # Find indices of solutions that have not yet # converged to the requested accuracy # AND that do not diverge: subind, = np.where((dnnew >= tol2) & conv) else: # Apply correction: pix[ind] -= dpixnew dpix[ind] = dpixnew # Find indices of solutions that have not yet # converged to the requested accuracy: subind, = np.where(dnnew >= tol2) # Choose solutions that need more iterations: ind = ind[subind] pix0 = pix0[subind] k += 1 # ############################################################ # # FINAL DETECTION OF INVALID, DIVERGING, ## # # AND FAILED-TO-CONVERGE POINTS ## # ############################################################ # Identify diverging and/or invalid points: invalid = ((~np.all(np.isfinite(pix), axis=1)) & (np.all(np.isfinite(world), axis=1))) # When detect_divergence==False, dnprev is outdated # (it is the norm of the very first correction). # Still better than nothing... inddiv, = np.where(((dn >= tol2) & (dn >= dnprev)) | invalid) if inddiv.shape[0] == 0: inddiv = None # Identify points that did not converge within 'maxiter' # iterations: if k >= maxiter: ind, = np.where((dn >= tol2) & (dn < dnprev) & (~invalid)) if ind.shape[0] == 0: ind = None else: ind = None # Restore previous numpy error settings: np.seterr(invalid=old_invalid, over=old_over) # ############################################################ # # RAISE EXCEPTION IF DIVERGING OR TOO SLOWLY CONVERGING ## # # DATA POINTS HAVE BEEN DETECTED: ## # ############################################################ if (ind is not None or inddiv is not None) and not quiet: if inddiv is None: raise NoConvergence( "'WCS.all_world2pix' failed to " "converge to the requested accuracy after {:d} " "iterations.".format(k), best_solution=pix, accuracy=np.abs(dpix), niter=k, slow_conv=ind, divergent=None) else: raise NoConvergence( "'WCS.all_world2pix' failed to " "converge to the requested accuracy.\n" "After {:d} iterations, the solution is diverging " "at least for one input point." .format(k), best_solution=pix, accuracy=np.abs(dpix), niter=k, slow_conv=ind, divergent=inddiv) return pix @deprecated_renamed_argument('accuracy', 'tolerance', '4.3') def all_world2pix(self, *args, tolerance=1e-4, maxiter=20, adaptive=False, detect_divergence=True, quiet=False, **kwargs): if self.wcs is None: raise ValueError("No basic WCS settings were created.") return self._array_converter( lambda *args, **kwargs: self._all_world2pix( *args, tolerance=tolerance, maxiter=maxiter, adaptive=adaptive, detect_divergence=detect_divergence, quiet=quiet), 'input', *args, **kwargs ) all_world2pix.__doc__ = """ all_world2pix(*arg, tolerance=1.0e-4, maxiter=20, adaptive=False, detect_divergence=True, quiet=False) Transforms world coordinates to pixel coordinates, using numerical iteration to invert the full forward transformation `~astropy.wcs.WCS.all_pix2world` with complete distortion model. Parameters ---------- {0} For a transformation that is not two-dimensional, the two-argument form must be used. {1} tolerance : float, optional (default = 1.0e-4) Tolerance of solution. Iteration terminates when the iterative solver estimates that the "true solution" is within this many pixels current estimate, more specifically, when the correction to the solution found during the previous iteration is smaller (in the sense of the L2 norm) than ``tolerance``. maxiter : int, optional (default = 20) Maximum number of iterations allowed to reach a solution. quiet : bool, optional (default = False) Do not throw :py:class:`NoConvergence` exceptions when the method does not converge to a solution with the required accuracy within a specified number of maximum iterations set by ``maxiter`` parameter. Instead, simply return the found solution. Other Parameters ---------------- adaptive : bool, optional (default = False) Specifies whether to adaptively select only points that did not converge to a solution within the required accuracy for the next iteration. Default is recommended for HST as well as most other instruments. .. note:: The :py:meth:`all_world2pix` uses a vectorized implementation of the method of consecutive approximations (see ``Notes`` section below) in which it iterates over *all* input points *regardless* until the required accuracy has been reached for *all* input points. In some cases it may be possible that *almost all* points have reached the required accuracy but there are only a few of input data points for which additional iterations may be needed (this depends mostly on the characteristics of the geometric distortions for a given instrument). In this situation it may be advantageous to set ``adaptive`` = `True` in which case :py:meth:`all_world2pix` will continue iterating *only* over the points that have not yet converged to the required accuracy. However, for the HST's ACS/WFC detector, which has the strongest distortions of all HST instruments, testing has shown that enabling this option would lead to a about 50-100% penalty in computational time (depending on specifics of the image, geometric distortions, and number of input points to be converted). Therefore, for HST and possibly instruments, it is recommended to set ``adaptive`` = `False`. The only danger in getting this setting wrong will be a performance penalty. .. note:: When ``detect_divergence`` is `True`, :py:meth:`all_world2pix` will automatically switch to the adaptive algorithm once divergence has been detected. detect_divergence : bool, optional (default = True) Specifies whether to perform a more detailed analysis of the convergence to a solution. Normally :py:meth:`all_world2pix` may not achieve the required accuracy if either the ``tolerance`` or ``maxiter`` arguments are too low. However, it may happen that for some geometric distortions the conditions of convergence for the the method of consecutive approximations used by :py:meth:`all_world2pix` may not be satisfied, in which case consecutive approximations to the solution will diverge regardless of the ``tolerance`` or ``maxiter`` settings. When ``detect_divergence`` is `False`, these divergent points will be detected as not having achieved the required accuracy (without further details). In addition, if ``adaptive`` is `False` then the algorithm will not know that the solution (for specific points) is diverging and will continue iterating and trying to "improve" diverging solutions. This may result in ``NaN`` or ``Inf`` values in the return results (in addition to a performance penalties). Even when ``detect_divergence`` is `False`, :py:meth:`all_world2pix`, at the end of the iterative process, will identify invalid results (``NaN`` or ``Inf``) as "diverging" solutions and will raise :py:class:`NoConvergence` unless the ``quiet`` parameter is set to `True`. When ``detect_divergence`` is `True`, :py:meth:`all_world2pix` will detect points for which current correction to the coordinates is larger than the correction applied during the previous iteration **if** the requested accuracy **has not yet been achieved**. In this case, if ``adaptive`` is `True`, these points will be excluded from further iterations and if ``adaptive`` is `False`, :py:meth:`all_world2pix` will automatically switch to the adaptive algorithm. Thus, the reported divergent solution will be the latest converging solution computed immediately *before* divergence has been detected. .. note:: When accuracy has been achieved, small increases in current corrections may be possible due to rounding errors (when ``adaptive`` is `False`) and such increases will be ignored. .. note:: Based on our testing using HST ACS/WFC images, setting ``detect_divergence`` to `True` will incur about 5-20% performance penalty with the larger penalty corresponding to ``adaptive`` set to `True`. Because the benefits of enabling this feature outweigh the small performance penalty, especially when ``adaptive`` = `False`, it is recommended to set ``detect_divergence`` to `True`, unless extensive testing of the distortion models for images from specific instruments show a good stability of the numerical method for a wide range of coordinates (even outside the image itself). .. note:: Indices of the diverging inverse solutions will be reported in the ``divergent`` attribute of the raised :py:class:`NoConvergence` exception object. Returns ------- {2} Notes ----- The order of the axes for the input world array is determined by the ``CTYPEia`` keywords in the FITS header, therefore it may not always be of the form (*ra*, *dec*). The `~astropy.wcs.Wcsprm.lat`, `~astropy.wcs.Wcsprm.lng`, `~astropy.wcs.Wcsprm.lattyp`, and `~astropy.wcs.Wcsprm.lngtyp` members can be used to determine the order of the axes. Using the method of fixed-point iterations approximations we iterate starting with the initial approximation, which is computed using the non-distortion-aware :py:meth:`wcs_world2pix` (or equivalent). The :py:meth:`all_world2pix` function uses a vectorized implementation of the method of consecutive approximations and therefore it is highly efficient (>30x) when *all* data points that need to be converted from sky coordinates to image coordinates are passed at *once*. Therefore, it is advisable, whenever possible, to pass as input a long array of all points that need to be converted to :py:meth:`all_world2pix` instead of calling :py:meth:`all_world2pix` for each data point. Also see the note to the ``adaptive`` parameter. Raises ------ NoConvergence The method did not converge to a solution to the required accuracy within a specified number of maximum iterations set by the ``maxiter`` parameter. To turn off this exception, set ``quiet`` to `True`. Indices of the points for which the requested accuracy was not achieved (if any) will be listed in the ``slow_conv`` attribute of the raised :py:class:`NoConvergence` exception object. See :py:class:`NoConvergence` documentation for more details. MemoryError Memory allocation failed. SingularMatrixError Linear transformation matrix is singular. InconsistentAxisTypesError Inconsistent or unrecognized coordinate axis types. ValueError Invalid parameter value. ValueError Invalid coordinate transformation parameters. ValueError x- and y-coordinate arrays are not the same size. InvalidTransformError Invalid coordinate transformation parameters. InvalidTransformError Ill-conditioned coordinate transformation parameters. Examples -------- >>> import astropy.io.fits as fits >>> import astropy.wcs as wcs >>> import numpy as np >>> import os >>> filename = os.path.join(wcs.__path__[0], 'tests/data/j94f05bgq_flt.fits') >>> hdulist = fits.open(filename) >>> w = wcs.WCS(hdulist[('sci',1)].header, hdulist) >>> hdulist.close() >>> ra, dec = w.all_pix2world([1,2,3], [1,1,1], 1) >>> print(ra) # doctest: +FLOAT_CMP [ 5.52645627 5.52649663 5.52653698] >>> print(dec) # doctest: +FLOAT_CMP [-72.05171757 -72.05171276 -72.05170795] >>> radec = w.all_pix2world([[1,1], [2,1], [3,1]], 1) >>> print(radec) # doctest: +FLOAT_CMP [[ 5.52645627 -72.05171757] [ 5.52649663 -72.05171276] [ 5.52653698 -72.05170795]] >>> x, y = w.all_world2pix(ra, dec, 1) >>> print(x) # doctest: +FLOAT_CMP [ 1.00000238 2.00000237 3.00000236] >>> print(y) # doctest: +FLOAT_CMP [ 0.99999996 0.99999997 0.99999997] >>> xy = w.all_world2pix(radec, 1) >>> print(xy) # doctest: +FLOAT_CMP [[ 1.00000238 0.99999996] [ 2.00000237 0.99999997] [ 3.00000236 0.99999997]] >>> xy = w.all_world2pix(radec, 1, maxiter=3, ... tolerance=1.0e-10, quiet=False) Traceback (most recent call last): ... NoConvergence: 'WCS.all_world2pix' failed to converge to the requested accuracy. After 3 iterations, the solution is diverging at least for one input point. >>> # Now try to use some diverging data: >>> divradec = w.all_pix2world([[1.0, 1.0], ... [10000.0, 50000.0], ... [3.0, 1.0]], 1) >>> print(divradec) # doctest: +FLOAT_CMP [[ 5.52645627 -72.05171757] [ 7.15976932 -70.8140779 ] [ 5.52653698 -72.05170795]] >>> # First, turn detect_divergence on: >>> try: # doctest: +FLOAT_CMP ... xy = w.all_world2pix(divradec, 1, maxiter=20, ... tolerance=1.0e-4, adaptive=False, ... detect_divergence=True, ... quiet=False) ... except wcs.wcs.NoConvergence as e: ... print("Indices of diverging points: {{0}}" ... .format(e.divergent)) ... print("Indices of poorly converging points: {{0}}" ... .format(e.slow_conv)) ... print("Best solution:\\n{{0}}".format(e.best_solution)) ... print("Achieved accuracy:\\n{{0}}".format(e.accuracy)) Indices of diverging points: [1] Indices of poorly converging points: None Best solution: [[ 1.00000238e+00 9.99999965e-01] [ -1.99441636e+06 1.44309097e+06] [ 3.00000236e+00 9.99999966e-01]] Achieved accuracy: [[ 6.13968380e-05 8.59638593e-07] [ 8.59526812e+11 6.61713548e+11] [ 6.09398446e-05 8.38759724e-07]] >>> raise e Traceback (most recent call last): ... NoConvergence: 'WCS.all_world2pix' failed to converge to the requested accuracy. After 5 iterations, the solution is diverging at least for one input point. >>> # This time turn detect_divergence off: >>> try: # doctest: +FLOAT_CMP ... xy = w.all_world2pix(divradec, 1, maxiter=20, ... tolerance=1.0e-4, adaptive=False, ... detect_divergence=False, ... quiet=False) ... except wcs.wcs.NoConvergence as e: ... print("Indices of diverging points: {{0}}" ... .format(e.divergent)) ... print("Indices of poorly converging points: {{0}}" ... .format(e.slow_conv)) ... print("Best solution:\\n{{0}}".format(e.best_solution)) ... print("Achieved accuracy:\\n{{0}}".format(e.accuracy)) Indices of diverging points: [1] Indices of poorly converging points: None Best solution: [[ 1.00000009 1. ] [ nan nan] [ 3.00000009 1. ]] Achieved accuracy: [[ 2.29417358e-06 3.21222995e-08] [ nan nan] [ 2.27407877e-06 3.13005639e-08]] >>> raise e Traceback (most recent call last): ... NoConvergence: 'WCS.all_world2pix' failed to converge to the requested accuracy. After 6 iterations, the solution is diverging at least for one input point. """.format(docstrings.TWO_OR_MORE_ARGS('naxis', 8), docstrings.RA_DEC_ORDER(8), docstrings.RETURNS('pixel coordinates', 8)) def wcs_world2pix(self, *args, **kwargs): if self.wcs is None: raise ValueError("No basic WCS settings were created.") return self._array_converter( lambda xy, o: self.wcs.s2p(xy, o)['pixcrd'], 'input', *args, **kwargs) wcs_world2pix.__doc__ = """ Transforms world coordinates to pixel coordinates, using only the basic `wcslib`_ WCS transformation. No `SIP`_ or `distortion paper`_ table lookup transformation is applied. Parameters ---------- {} For a transformation that is not two-dimensional, the two-argument form must be used. {} Returns ------- {} Notes ----- The order of the axes for the input world array is determined by the ``CTYPEia`` keywords in the FITS header, therefore it may not always be of the form (*ra*, *dec*). The `~astropy.wcs.Wcsprm.lat`, `~astropy.wcs.Wcsprm.lng`, `~astropy.wcs.Wcsprm.lattyp` and `~astropy.wcs.Wcsprm.lngtyp` members can be used to determine the order of the axes. Raises ------ MemoryError Memory allocation failed. SingularMatrixError Linear transformation matrix is singular. InconsistentAxisTypesError Inconsistent or unrecognized coordinate axis types. ValueError Invalid parameter value. ValueError Invalid coordinate transformation parameters. ValueError x- and y-coordinate arrays are not the same size. InvalidTransformError Invalid coordinate transformation parameters. InvalidTransformError Ill-conditioned coordinate transformation parameters. """.format(docstrings.TWO_OR_MORE_ARGS('naxis', 8), docstrings.RA_DEC_ORDER(8), docstrings.RETURNS('pixel coordinates', 8)) def pix2foc(self, *args): return self._array_converter(self._pix2foc, None, *args) pix2foc.__doc__ = """ Convert pixel coordinates to focal plane coordinates using the `SIP`_ polynomial distortion convention and `distortion paper`_ table-lookup correction. The output is in absolute pixel coordinates, not relative to ``CRPIX``. Parameters ---------- {} Returns ------- {} Raises ------ MemoryError Memory allocation failed. ValueError Invalid coordinate transformation parameters. """.format(docstrings.TWO_OR_MORE_ARGS('2', 8), docstrings.RETURNS('focal coordinates', 8)) def p4_pix2foc(self, *args): return self._array_converter(self._p4_pix2foc, None, *args) p4_pix2foc.__doc__ = """ Convert pixel coordinates to focal plane coordinates using `distortion paper`_ table-lookup correction. The output is in absolute pixel coordinates, not relative to ``CRPIX``. Parameters ---------- {} Returns ------- {} Raises ------ MemoryError Memory allocation failed. ValueError Invalid coordinate transformation parameters. """.format(docstrings.TWO_OR_MORE_ARGS('2', 8), docstrings.RETURNS('focal coordinates', 8)) def det2im(self, *args): return self._array_converter(self._det2im, None, *args) det2im.__doc__ = """ Convert detector coordinates to image plane coordinates using `distortion paper`_ table-lookup correction. The output is in absolute pixel coordinates, not relative to ``CRPIX``. Parameters ---------- {} Returns ------- {} Raises ------ MemoryError Memory allocation failed. ValueError Invalid coordinate transformation parameters. """.format(docstrings.TWO_OR_MORE_ARGS('2', 8), docstrings.RETURNS('pixel coordinates', 8)) def sip_pix2foc(self, *args): if self.sip is None: if len(args) == 2: return args[0] elif len(args) == 3: return args[:2] else: raise TypeError("Wrong number of arguments") return self._array_converter(self.sip.pix2foc, None, *args) sip_pix2foc.__doc__ = """ Convert pixel coordinates to focal plane coordinates using the `SIP`_ polynomial distortion convention. The output is in pixel coordinates, relative to ``CRPIX``. FITS WCS `distortion paper`_ table lookup correction is not applied, even if that information existed in the FITS file that initialized this :class:`~astropy.wcs.WCS` object. To correct for that, use `~astropy.wcs.WCS.pix2foc` or `~astropy.wcs.WCS.p4_pix2foc`. Parameters ---------- {} Returns ------- {} Raises ------ MemoryError Memory allocation failed. ValueError Invalid coordinate transformation parameters. """.format(docstrings.TWO_OR_MORE_ARGS('2', 8), docstrings.RETURNS('focal coordinates', 8)) def sip_foc2pix(self, *args): if self.sip is None: if len(args) == 2: return args[0] elif len(args) == 3: return args[:2] else: raise TypeError("Wrong number of arguments") return self._array_converter(self.sip.foc2pix, None, *args) sip_foc2pix.__doc__ = """ Convert focal plane coordinates to pixel coordinates using the `SIP`_ polynomial distortion convention. FITS WCS `distortion paper`_ table lookup distortion correction is not applied, even if that information existed in the FITS file that initialized this `~astropy.wcs.WCS` object. Parameters ---------- {} Returns ------- {} Raises ------ MemoryError Memory allocation failed. ValueError Invalid coordinate transformation parameters. """.format(docstrings.TWO_OR_MORE_ARGS('2', 8), docstrings.RETURNS('pixel coordinates', 8)) def proj_plane_pixel_scales(self): """ Calculate pixel scales along each axis of the image pixel at the ``CRPIX`` location once it is projected onto the "plane of intermediate world coordinates" as defined in `Greisen & Calabretta 2002, A&A, 395, 1061 `_. .. note:: This method is concerned **only** about the transformation "image plane"->"projection plane" and **not** about the transformation "celestial sphere"->"projection plane"->"image plane". Therefore, this function ignores distortions arising due to non-linear nature of most projections. .. note:: This method only returns sensible answers if the WCS contains celestial axes, i.e., the `~astropy.wcs.WCS.celestial` WCS object. Returns ------- scale : list of `~astropy.units.Quantity` A vector of projection plane increments corresponding to each pixel side (axis). See Also -------- astropy.wcs.utils.proj_plane_pixel_scales """ # noqa: E501 from astropy.wcs.utils import proj_plane_pixel_scales # Avoid circular import values = proj_plane_pixel_scales(self) units = [u.Unit(x) for x in self.wcs.cunit] return [value * unit for (value, unit) in zip(values, units)] # Can have different units def proj_plane_pixel_area(self): """ For a **celestial** WCS (see `astropy.wcs.WCS.celestial`), returns pixel area of the image pixel at the ``CRPIX`` location once it is projected onto the "plane of intermediate world coordinates" as defined in `Greisen & Calabretta 2002, A&A, 395, 1061 `_. .. note:: This function is concerned **only** about the transformation "image plane"->"projection plane" and **not** about the transformation "celestial sphere"->"projection plane"->"image plane". Therefore, this function ignores distortions arising due to non-linear nature of most projections. .. note:: This method only returns sensible answers if the WCS contains celestial axes, i.e., the `~astropy.wcs.WCS.celestial` WCS object. Returns ------- area : `~astropy.units.Quantity` Area (in the projection plane) of the pixel at ``CRPIX`` location. Raises ------ ValueError Pixel area is defined only for 2D pixels. Most likely the `~astropy.wcs.Wcsprm.cd` matrix of the `~astropy.wcs.WCS.celestial` WCS is not a square matrix of second order. Notes ----- Depending on the application, square root of the pixel area can be used to represent a single pixel scale of an equivalent square pixel whose area is equal to the area of a generally non-square pixel. See Also -------- astropy.wcs.utils.proj_plane_pixel_area """ # noqa: E501 from astropy.wcs.utils import proj_plane_pixel_area # Avoid circular import value = proj_plane_pixel_area(self) unit = u.Unit(self.wcs.cunit[0]) * u.Unit(self.wcs.cunit[1]) # 2D only return value * unit def to_fits(self, relax=False, key=None): """ Generate an `~astropy.io.fits.HDUList` object with all of the information stored in this object. This should be logically identical to the input FITS file, but it will be normalized in a number of ways. See `to_header` for some warnings about the output produced. Parameters ---------- relax : bool or int, optional Degree of permissiveness: - `False` (default): Write all extensions that are considered to be safe and recommended. - `True`: Write all recognized informal extensions of the WCS standard. - `int`: a bit field selecting specific extensions to write. See :ref:`astropy:relaxwrite` for details. key : str The name of a particular WCS transform to use. This may be either ``' '`` or ``'A'``-``'Z'`` and corresponds to the ``"a"`` part of the ``CTYPEia`` cards. Returns ------- hdulist : `~astropy.io.fits.HDUList` """ header = self.to_header(relax=relax, key=key) hdu = fits.PrimaryHDU(header=header) hdulist = fits.HDUList(hdu) self._write_det2im(hdulist) self._write_distortion_kw(hdulist) return hdulist def to_header(self, relax=None, key=None): """Generate an `astropy.io.fits.Header` object with the basic WCS and SIP information stored in this object. This should be logically identical to the input FITS file, but it will be normalized in a number of ways. .. warning:: This function does not write out FITS WCS `distortion paper`_ information, since that requires multiple FITS header data units. To get a full representation of everything in this object, use `to_fits`. Parameters ---------- relax : bool or int, optional Degree of permissiveness: - `False` (default): Write all extensions that are considered to be safe and recommended. - `True`: Write all recognized informal extensions of the WCS standard. - `int`: a bit field selecting specific extensions to write. See :ref:`astropy:relaxwrite` for details. If the ``relax`` keyword argument is not given and any keywords were omitted from the output, an `~astropy.utils.exceptions.AstropyWarning` is displayed. To override this, explicitly pass a value to ``relax``. key : str The name of a particular WCS transform to use. This may be either ``' '`` or ``'A'``-``'Z'`` and corresponds to the ``"a"`` part of the ``CTYPEia`` cards. Returns ------- header : `astropy.io.fits.Header` Notes ----- The output header will almost certainly differ from the input in a number of respects: 1. The output header only contains WCS-related keywords. In particular, it does not contain syntactically-required keywords such as ``SIMPLE``, ``NAXIS``, ``BITPIX``, or ``END``. 2. Deprecated (e.g. ``CROTAn``) or non-standard usage will be translated to standard (this is partially dependent on whether ``fix`` was applied). 3. Quantities will be converted to the units used internally, basically SI with the addition of degrees. 4. Floating-point quantities may be given to a different decimal precision. 5. Elements of the ``PCi_j`` matrix will be written if and only if they differ from the unit matrix. Thus, if the matrix is unity then no elements will be written. 6. Additional keywords such as ``WCSAXES``, ``CUNITia``, ``LONPOLEa`` and ``LATPOLEa`` may appear. 7. The original keycomments will be lost, although `to_header` tries hard to write meaningful comments. 8. Keyword order may be changed. """ # default precision for numerical WCS keywords precision = WCSHDO_P14 # Defined by C-ext # noqa: F821 display_warning = False if relax is None: display_warning = True relax = False if relax not in (True, False): do_sip = relax & WCSHDO_SIP relax &= ~WCSHDO_SIP else: do_sip = relax relax = WCSHDO_all if relax is True else WCSHDO_safe # Defined by C-ext # noqa: F821 relax = precision | relax if self.wcs is not None: if key is not None: orig_key = self.wcs.alt self.wcs.alt = key header_string = self.wcs.to_header(relax) header = fits.Header.fromstring(header_string) keys_to_remove = ["", " ", "COMMENT"] for kw in keys_to_remove: if kw in header: del header[kw] # Check if we can handle TPD distortion correctly if int(_parsed_version[0]) * 10 + int(_parsed_version[1]) < 71: for kw, val in header.items(): if kw[:5] in ('CPDIS', 'CQDIS') and val == 'TPD': warnings.warn( f"WCS contains a TPD distortion model in {kw}. WCSLIB " f"{_wcs.__version__} is writing this in a format incompatible with " f"current versions - please update to 7.4 or use the bundled WCSLIB.", AstropyWarning) elif int(_parsed_version[0]) * 10 + int(_parsed_version[1]) < 74: for kw, val in header.items(): if kw[:5] in ('CPDIS', 'CQDIS') and val == 'TPD': warnings.warn( f"WCS contains a TPD distortion model in {kw}, which requires WCSLIB " f"7.4 or later to store in a FITS header (having {_wcs.__version__}).", AstropyWarning) else: header = fits.Header() if do_sip and self.sip is not None: if self.wcs is not None and any(not ctyp.endswith('-SIP') for ctyp in self.wcs.ctype): self._fix_ctype(header, add_sip=True) for kw, val in self._write_sip_kw().items(): header[kw] = val if not do_sip and self.wcs is not None and any(self.wcs.ctype) and self.sip is not None: # This is called when relax is not False or WCSHDO_SIP # The default case of ``relax=None`` is handled further in the code. header = self._fix_ctype(header, add_sip=False) if display_warning: full_header = self.to_header(relax=True, key=key) missing_keys = [] for kw, val in full_header.items(): if kw not in header: missing_keys.append(kw) if len(missing_keys): warnings.warn( "Some non-standard WCS keywords were excluded: {} " "Use the ``relax`` kwarg to control this.".format( ', '.join(missing_keys)), AstropyWarning) # called when ``relax=None`` # This is different from the case of ``relax=False``. if any(self.wcs.ctype) and self.sip is not None: header = self._fix_ctype(header, add_sip=False, log_message=False) # Finally reset the key. This must be called after ``_fix_ctype``. if key is not None: self.wcs.alt = orig_key return header def _fix_ctype(self, header, add_sip=True, log_message=True): """ Parameters ---------- header : `~astropy.io.fits.Header` FITS header. add_sip : bool Flag indicating whether "-SIP" should be added or removed from CTYPE keywords. Remove "-SIP" from CTYPE when writing out a header with relax=False. This needs to be done outside ``to_header`` because ``to_header`` runs twice when ``relax=False`` and the second time ``relax`` is set to ``True`` to display the missing keywords. If the user requested SIP distortion to be written out add "-SIP" to CTYPE if it is missing. """ _add_sip_to_ctype = """ Inconsistent SIP distortion information is present in the current WCS: SIP coefficients were detected, but CTYPE is missing "-SIP" suffix, therefore the current WCS is internally inconsistent. Because relax has been set to True, the resulting output WCS will have "-SIP" appended to CTYPE in order to make the header internally consistent. However, this may produce incorrect astrometry in the output WCS, if in fact the current WCS is already distortion-corrected. Therefore, if current WCS is already distortion-corrected (eg, drizzled) then SIP distortion components should not apply. In that case, for a WCS that is already distortion-corrected, please remove the SIP coefficients from the header. """ if log_message: if add_sip: log.info(_add_sip_to_ctype) for i in range(1, self.naxis+1): # strip() must be called here to cover the case of alt key= " " kw = f'CTYPE{i}{self.wcs.alt}'.strip() if kw in header: if add_sip: val = header[kw].strip("-SIP") + "-SIP" else: val = header[kw].strip("-SIP") header[kw] = val else: continue return header def to_header_string(self, relax=None): """ Identical to `to_header`, but returns a string containing the header cards. """ return str(self.to_header(relax)) def footprint_to_file(self, filename='footprint.reg', color='green', width=2, coordsys=None): """ Writes out a `ds9`_ style regions file. It can be loaded directly by `ds9`_. Parameters ---------- filename : str, optional Output file name - default is ``'footprint.reg'`` color : str, optional Color to use when plotting the line. width : int, optional Width of the region line. coordsys : str, optional Coordinate system. If not specified (default), the ``radesys`` value is used. For all possible values, see http://ds9.si.edu/doc/ref/region.html#RegionFileFormat """ comments = ('# Region file format: DS9 version 4.0 \n' '# global color=green font="helvetica 12 bold ' 'select=1 highlite=1 edit=1 move=1 delete=1 ' 'include=1 fixed=0 source\n') coordsys = coordsys or self.wcs.radesys if coordsys not in ('PHYSICAL', 'IMAGE', 'FK4', 'B1950', 'FK5', 'J2000', 'GALACTIC', 'ECLIPTIC', 'ICRS', 'LINEAR', 'AMPLIFIER', 'DETECTOR'): raise ValueError("Coordinate system '{}' is not supported. A valid" " one can be given with the 'coordsys' argument." .format(coordsys)) with open(filename, mode='w') as f: f.write(comments) f.write(f'{coordsys}\n') f.write('polygon(') ftpr = self.calc_footprint() if ftpr is not None: ftpr.tofile(f, sep=',') f.write(f') # color={color}, width={width:d} \n') def _get_naxis(self, header=None): _naxis = [] if (header is not None and not isinstance(header, (str, bytes))): for naxis in itertools.count(1): try: _naxis.append(header[f'NAXIS{naxis}']) except KeyError: break if len(_naxis) == 0: _naxis = [0, 0] elif len(_naxis) == 1: _naxis.append(0) self._naxis = _naxis def printwcs(self): print(repr(self)) def __repr__(self): ''' Return a short description. Simply porting the behavior from the `printwcs()` method. ''' description = ["WCS Keywords\n", f"Number of WCS axes: {self.naxis!r}"] sfmt = ' : ' + "".join(["{"+f"{i}"+"!r} " for i in range(self.naxis)]) keywords = ['CTYPE', 'CRVAL', 'CRPIX'] values = [self.wcs.ctype, self.wcs.crval, self.wcs.crpix] for keyword, value in zip(keywords, values): description.append(keyword+sfmt.format(*value)) if hasattr(self.wcs, 'pc'): for i in range(self.naxis): s = '' for j in range(self.naxis): s += ''.join(['PC', str(i+1), '_', str(j+1), ' ']) s += sfmt description.append(s.format(*self.wcs.pc[i])) s = 'CDELT' + sfmt description.append(s.format(*self.wcs.cdelt)) elif hasattr(self.wcs, 'cd'): for i in range(self.naxis): s = '' for j in range(self.naxis): s += "".join(['CD', str(i+1), '_', str(j+1), ' ']) s += sfmt description.append(s.format(*self.wcs.cd[i])) description.append(f"NAXIS : {' '.join(map(str, self._naxis))}") return '\n'.join(description) def get_axis_types(self): """ Similar to `self.wcsprm.axis_types ` but provides the information in a more Python-friendly format. Returns ------- result : list of dict Returns a list of dictionaries, one for each axis, each containing attributes about the type of that axis. Each dictionary has the following keys: - 'coordinate_type': - None: Non-specific coordinate type. - 'stokes': Stokes coordinate. - 'celestial': Celestial coordinate (including ``CUBEFACE``). - 'spectral': Spectral coordinate. - 'scale': - 'linear': Linear axis. - 'quantized': Quantized axis (``STOKES``, ``CUBEFACE``). - 'non-linear celestial': Non-linear celestial axis. - 'non-linear spectral': Non-linear spectral axis. - 'logarithmic': Logarithmic axis. - 'tabular': Tabular axis. - 'group' - Group number, e.g. lookup table number - 'number' - For celestial axes: - 0: Longitude coordinate. - 1: Latitude coordinate. - 2: ``CUBEFACE`` number. - For lookup tables: - the axis number in a multidimensional table. ``CTYPEia`` in ``"4-3"`` form with unrecognized algorithm code will generate an error. """ if self.wcs is None: raise AttributeError( "This WCS object does not have a wcsprm object.") coordinate_type_map = { 0: None, 1: 'stokes', 2: 'celestial', 3: 'spectral'} scale_map = { 0: 'linear', 1: 'quantized', 2: 'non-linear celestial', 3: 'non-linear spectral', 4: 'logarithmic', 5: 'tabular'} result = [] for axis_type in self.wcs.axis_types: subresult = {} coordinate_type = (axis_type // 1000) % 10 subresult['coordinate_type'] = coordinate_type_map[coordinate_type] scale = (axis_type // 100) % 10 subresult['scale'] = scale_map[scale] group = (axis_type // 10) % 10 subresult['group'] = group number = axis_type % 10 subresult['number'] = number result.append(subresult) return result def __reduce__(self): """ Support pickling of WCS objects. This is done by serializing to an in-memory FITS file and dumping that as a string. """ hdulist = self.to_fits(relax=True) buffer = io.BytesIO() hdulist.writeto(buffer) dct = self.__dict__.copy() dct['_alt_wcskey'] = self.wcs.alt return (__WCS_unpickle__, (self.__class__, dct, buffer.getvalue(),)) def dropaxis(self, dropax): """ Remove an axis from the WCS. Parameters ---------- wcs : `~astropy.wcs.WCS` The WCS with naxis to be chopped to naxis-1 dropax : int The index of the WCS to drop, counting from 0 (i.e., python convention, not FITS convention) Returns ------- `~astropy.wcs.WCS` A new `~astropy.wcs.WCS` instance with one axis fewer """ inds = list(range(self.wcs.naxis)) inds.pop(dropax) # axis 0 has special meaning to sub # if wcs.wcs.ctype == ['RA','DEC','VLSR'], you want # wcs.sub([1,2]) to get 'RA','DEC' back return self.sub([i+1 for i in inds]) def swapaxes(self, ax0, ax1): """ Swap axes in a WCS. Parameters ---------- wcs : `~astropy.wcs.WCS` The WCS to have its axes swapped ax0 : int ax1 : int The indices of the WCS to be swapped, counting from 0 (i.e., python convention, not FITS convention) Returns ------- `~astropy.wcs.WCS` A new `~astropy.wcs.WCS` instance with the same number of axes, but two swapped """ inds = list(range(self.wcs.naxis)) inds[ax0], inds[ax1] = inds[ax1], inds[ax0] return self.sub([i+1 for i in inds]) def reorient_celestial_first(self): """ Reorient the WCS such that the celestial axes are first, followed by the spectral axis, followed by any others. Assumes at least celestial axes are present. """ return self.sub([WCSSUB_CELESTIAL, WCSSUB_SPECTRAL, WCSSUB_STOKES]) # Defined by C-ext # noqa: F821 E501 def slice(self, view, numpy_order=True): """ Slice a WCS instance using a Numpy slice. The order of the slice should be reversed (as for the data) compared to the natural WCS order. Parameters ---------- view : tuple A tuple containing the same number of slices as the WCS system. The ``step`` method, the third argument to a slice, is not presently supported. numpy_order : bool Use numpy order, i.e. slice the WCS so that an identical slice applied to a numpy array will slice the array and WCS in the same way. If set to `False`, the WCS will be sliced in FITS order, meaning the first slice will be applied to the *last* numpy index but the *first* WCS axis. Returns ------- wcs_new : `~astropy.wcs.WCS` A new resampled WCS axis """ if hasattr(view, '__len__') and len(view) > self.wcs.naxis: raise ValueError("Must have # of slices <= # of WCS axes") elif not hasattr(view, '__len__'): # view MUST be an iterable view = [view] if not all(isinstance(x, slice) for x in view): # We need to drop some dimensions, but this may not always be # possible with .sub due to correlated axes, so instead we use the # generalized slicing infrastructure from astropy.wcs.wcsapi. return SlicedFITSWCS(self, view) # NOTE: we could in principle use SlicedFITSWCS as above for all slicing, # but in the simple case where there are no axes dropped, we can just # create a full WCS object with updated WCS parameters which is faster # for this specific case and also backward-compatible. wcs_new = self.deepcopy() if wcs_new.sip is not None: sip_crpix = wcs_new.sip.crpix.tolist() for i, iview in enumerate(view): if iview.step is not None and iview.step < 0: raise NotImplementedError("Reversing an axis is not " "implemented.") if numpy_order: wcs_index = self.wcs.naxis - 1 - i else: wcs_index = i if iview.step is not None and iview.start is None: # Slice from "None" is equivalent to slice from 0 (but one # might want to downsample, so allow slices with # None,None,step or None,stop,step) iview = slice(0, iview.stop, iview.step) if iview.start is not None: if iview.step not in (None, 1): crpix = self.wcs.crpix[wcs_index] cdelt = self.wcs.cdelt[wcs_index] # equivalently (keep this comment so you can compare eqns): # wcs_new.wcs.crpix[wcs_index] = # (crpix - iview.start)*iview.step + 0.5 - iview.step/2. crp = ((crpix - iview.start - 1.)/iview.step + 0.5 + 1./iview.step/2.) wcs_new.wcs.crpix[wcs_index] = crp if wcs_new.sip is not None: sip_crpix[wcs_index] = crp wcs_new.wcs.cdelt[wcs_index] = cdelt * iview.step else: wcs_new.wcs.crpix[wcs_index] -= iview.start if wcs_new.sip is not None: sip_crpix[wcs_index] -= iview.start try: # range requires integers but the other attributes can also # handle arbitrary values, so this needs to be in a try/except. nitems = len(builtins.range(self._naxis[wcs_index])[iview]) except TypeError as exc: if 'indices must be integers' not in str(exc): raise warnings.warn("NAXIS{} attribute is not updated because at " "least one index ('{}') is no integer." "".format(wcs_index, iview), AstropyUserWarning) else: wcs_new._naxis[wcs_index] = nitems if wcs_new.sip is not None: wcs_new.sip = Sip(self.sip.a, self.sip.b, self.sip.ap, self.sip.bp, sip_crpix) return wcs_new def __getitem__(self, item): # "getitem" is a shortcut for self.slice; it is very limited # there is no obvious and unambiguous interpretation of wcs[1,2,3] # We COULD allow wcs[1] to link to wcs.sub([2]) # (wcs[i] -> wcs.sub([i+1]) return self.slice(item) def __iter__(self): # Having __getitem__ makes Python think WCS is iterable. However, # Python first checks whether __iter__ is present, so we can raise an # exception here. raise TypeError(f"'{self.__class__.__name__}' object is not iterable") @property def axis_type_names(self): """ World names for each coordinate axis Returns ------- list of str A list of names along each axis. """ names = list(self.wcs.cname) types = self.wcs.ctype for i in range(len(names)): if len(names[i]) > 0: continue names[i] = types[i].split('-')[0] return names @property def celestial(self): """ A copy of the current WCS with only the celestial axes included """ return self.sub([WCSSUB_CELESTIAL]) # Defined by C-ext # noqa: F821 @property def is_celestial(self): return self.has_celestial and self.naxis == 2 @property def has_celestial(self): try: return self.wcs.lng >= 0 and self.wcs.lat >= 0 except InconsistentAxisTypesError: return False @property def spectral(self): """ A copy of the current WCS with only the spectral axes included """ return self.sub([WCSSUB_SPECTRAL]) # Defined by C-ext # noqa: F821 @property def is_spectral(self): return self.has_spectral and self.naxis == 1 @property def has_spectral(self): try: return self.wcs.spec >= 0 except InconsistentAxisTypesError: return False @property def has_distortion(self): """ Returns `True` if any distortion terms are present. """ return (self.sip is not None or self.cpdis1 is not None or self.cpdis2 is not None or self.det2im1 is not None and self.det2im2 is not None) @property def pixel_scale_matrix(self): try: cdelt = np.diag(self.wcs.get_cdelt()) pc = self.wcs.get_pc() except InconsistentAxisTypesError: try: # for non-celestial axes, get_cdelt doesn't work with warnings.catch_warnings(): warnings.filterwarnings( 'ignore', 'cdelt will be ignored since cd is present', RuntimeWarning) cdelt = np.dot(self.wcs.cd, np.diag(self.wcs.cdelt)) except AttributeError: cdelt = np.diag(self.wcs.cdelt) try: pc = self.wcs.pc except AttributeError: pc = 1 pccd = np.dot(cdelt, pc) return pccd def footprint_contains(self, coord, **kwargs): """ Determines if a given SkyCoord is contained in the wcs footprint. Parameters ---------- coord : `~astropy.coordinates.SkyCoord` The coordinate to check if it is within the wcs coordinate. **kwargs : Additional arguments to pass to `~astropy.coordinates.SkyCoord.to_pixel` Returns ------- response : bool True means the WCS footprint contains the coordinate, False means it does not. """ return coord.contained_by(self, **kwargs) def __WCS_unpickle__(cls, dct, fits_data): """ Unpickles a WCS object from a serialized FITS string. """ self = cls.__new__(cls) buffer = io.BytesIO(fits_data) hdulist = fits.open(buffer) naxis = dct.pop('naxis', None) if naxis: hdulist[0].header['naxis'] = naxis naxes = dct.pop('_naxis', []) for k, na in enumerate(naxes): hdulist[0].header[f'naxis{k + 1:d}'] = na kwargs = dct.pop('_init_kwargs', {}) self.__dict__.update(dct) wcskey = dct.pop('_alt_wcskey', ' ') WCS.__init__(self, hdulist[0].header, hdulist, key=wcskey, **kwargs) self.pixel_bounds = dct.get('_pixel_bounds', None) return self def find_all_wcs(header, relax=True, keysel=None, fix=True, translate_units='', _do_set=True): """ Find all the WCS transformations in the given header. Parameters ---------- header : str or `~astropy.io.fits.Header` object. relax : bool or int, optional Degree of permissiveness: - `True` (default): Admit all recognized informal extensions of the WCS standard. - `False`: Recognize only FITS keywords defined by the published WCS standard. - `int`: a bit field selecting specific extensions to accept. See :ref:`astropy:relaxread` for details. keysel : sequence of str, optional A list of flags used to select the keyword types considered by wcslib. When ``None``, only the standard image header keywords are considered (and the underlying wcspih() C function is called). To use binary table image array or pixel list keywords, *keysel* must be set. Each element in the list should be one of the following strings: - 'image': Image header keywords - 'binary': Binary table image array keywords - 'pixel': Pixel list keywords Keywords such as ``EQUIna`` or ``RFRQna`` that are common to binary table image arrays and pixel lists (including ``WCSNna`` and ``TWCSna``) are selected by both 'binary' and 'pixel'. fix : bool, optional When `True` (default), call `~astropy.wcs.Wcsprm.fix` on the resulting objects to fix any non-standard uses in the header. `FITSFixedWarning` warnings will be emitted if any changes were made. translate_units : str, optional Specify which potentially unsafe translations of non-standard unit strings to perform. By default, performs none. See `WCS.fix` for more information about this parameter. Only effective when ``fix`` is `True`. Returns ------- wcses : list of `WCS` """ if isinstance(header, (str, bytes)): header_string = header elif isinstance(header, fits.Header): header_string = header.tostring() else: raise TypeError( "header must be a string or astropy.io.fits.Header object") keysel_flags = _parse_keysel(keysel) if isinstance(header_string, str): header_bytes = header_string.encode('ascii') else: header_bytes = header_string wcsprms = _wcs.find_all_wcs(header_bytes, relax, keysel_flags) result = [] for wcsprm in wcsprms: subresult = WCS(fix=False, _do_set=False) subresult.wcs = wcsprm result.append(subresult) if fix: subresult.fix(translate_units) if _do_set: subresult.wcs.set() return result def validate(source): """ Prints a WCS validation report for the given FITS file. Parameters ---------- source : str or file-like or `~astropy.io.fits.HDUList` The FITS file to validate. Returns ------- results : list subclass instance The result is returned as nested lists. The first level corresponds to the HDUs in the given file. The next level has an entry for each WCS found in that header. The special subclass of list will pretty-print the results as a table when printed. """ class _WcsValidateWcsResult(list): def __init__(self, key): self._key = key def __repr__(self): result = [f" WCS key '{self._key or ' '}':"] if len(self): for entry in self: for i, line in enumerate(entry.splitlines()): if i == 0: initial_indent = ' - ' else: initial_indent = ' ' result.extend( textwrap.wrap( line, initial_indent=initial_indent, subsequent_indent=' ')) else: result.append(" No issues.") return '\n'.join(result) class _WcsValidateHduResult(list): def __init__(self, hdu_index, hdu_name): self._hdu_index = hdu_index self._hdu_name = hdu_name list.__init__(self) def __repr__(self): if len(self): if self._hdu_name: hdu_name = f' ({self._hdu_name})' else: hdu_name = '' result = [f'HDU {self._hdu_index}{hdu_name}:'] for wcs in self: result.append(repr(wcs)) return '\n'.join(result) return '' class _WcsValidateResults(list): def __repr__(self): result = [] for hdu in self: content = repr(hdu) if len(content): result.append(content) return '\n\n'.join(result) global __warningregistry__ if isinstance(source, fits.HDUList): hdulist = source else: hdulist = fits.open(source) results = _WcsValidateResults() for i, hdu in enumerate(hdulist): hdu_results = _WcsValidateHduResult(i, hdu.name) results.append(hdu_results) with warnings.catch_warnings(record=True) as warning_lines: wcses = find_all_wcs( hdu.header, relax=_wcs.WCSHDR_reject, fix=False, _do_set=False) for wcs in wcses: wcs_results = _WcsValidateWcsResult(wcs.wcs.alt) hdu_results.append(wcs_results) try: del __warningregistry__ except NameError: pass with warnings.catch_warnings(record=True) as warning_lines: warnings.resetwarnings() warnings.simplefilter( "always", FITSFixedWarning, append=True) try: WCS(hdu.header, key=wcs.wcs.alt or ' ', relax=_wcs.WCSHDR_reject, fix=True, _do_set=False) except WcsError as e: wcs_results.append(str(e)) wcs_results.extend([str(x.message) for x in warning_lines]) return results ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2432582 astropy-5.0.2/astropy/wcs/wcsapi/0000755000175100001710000000000000000000000016030 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/wcsapi/__init__.py0000644000175100001710000000026600000000000020145 0ustar00vstsdockerfrom .low_level_api import * # noqa from .high_level_api import * # noqa from .high_level_wcs_wrapper import * # noqa from .utils import * # noqa from .wrappers import * # noqa ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/wcsapi/conftest.py0000644000175100001710000001055600000000000020236 0ustar00vstsdockerimport pytest import numpy as np from astropy.coordinates import SkyCoord from astropy.units import Quantity from astropy.wcs import WCS from astropy.wcs.wcsapi import BaseLowLevelWCS # NOTE: This module is deprecated and is emitting warning. collect_ignore = ['sliced_low_level_wcs.py'] @pytest.fixture def spectral_1d_fitswcs(): wcs = WCS(naxis=1) wcs.wcs.ctype = 'FREQ', wcs.wcs.cunit = 'Hz', wcs.wcs.cdelt = 3.e9, wcs.wcs.crval = 4.e9, wcs.wcs.crpix = 11., wcs.wcs.cname = 'Frequency', return wcs @pytest.fixture def time_1d_fitswcs(): wcs = WCS(naxis=1) wcs.wcs.ctype = 'TIME', wcs.wcs.mjdref = (30042, 0) wcs.wcs.crval = 3., wcs.wcs.crpix = 11., wcs.wcs.cname = 'Time', wcs.wcs.cunit = 's' return wcs @pytest.fixture def celestial_2d_fitswcs(): wcs = WCS(naxis=2) wcs.wcs.ctype = 'RA---CAR', 'DEC--CAR' wcs.wcs.cunit = 'deg', 'deg' wcs.wcs.cdelt = -2., 2. wcs.wcs.crval = 4., 0. wcs.wcs.crpix = 6., 7. wcs.wcs.cname = 'Right Ascension', 'Declination' wcs.pixel_shape = (6, 7) wcs.pixel_bounds = [(-1, 5), (1, 7)] return wcs @pytest.fixture def spectral_cube_3d_fitswcs(): wcs = WCS(naxis=3) wcs.wcs.ctype = 'RA---CAR', 'DEC--CAR', 'FREQ' wcs.wcs.cunit = 'deg', 'deg', 'Hz' wcs.wcs.cdelt = -2., 2., 3.e9 wcs.wcs.crval = 4., 0., 4.e9 wcs.wcs.crpix = 6., 7., 11. wcs.wcs.cname = 'Right Ascension', 'Declination', 'Frequency' wcs.pixel_shape = (6, 7, 3) wcs.pixel_bounds = [(-1, 5), (1, 7), (1, 2.5)] return wcs @pytest.fixture def cube_4d_fitswcs(): wcs = WCS(naxis=4) wcs.wcs.ctype = 'RA---CAR', 'DEC--CAR', 'FREQ', 'TIME' wcs.wcs.cunit = 'deg', 'deg', 'Hz', 's' wcs.wcs.cdelt = -2., 2., 3.e9, 1 wcs.wcs.crval = 4., 0., 4.e9, 3, wcs.wcs.crpix = 6., 7., 11., 11. wcs.wcs.cname = 'Right Ascension', 'Declination', 'Frequency', 'Time' wcs.wcs.mjdref = (30042, 0) return wcs class Spectral1DLowLevelWCS(BaseLowLevelWCS): @property def pixel_n_dim(self): return 1 @property def world_n_dim(self): return 1 @property def world_axis_physical_types(self): return 'em.freq', @property def world_axis_units(self): return 'Hz', @property def world_axis_names(self): return 'Frequency', _pixel_shape = None @property def pixel_shape(self): return self._pixel_shape @pixel_shape.setter def pixel_shape(self, value): self._pixel_shape = value _pixel_bounds = None @property def pixel_bounds(self): return self._pixel_bounds @pixel_bounds.setter def pixel_bounds(self, value): self._pixel_bounds = value def pixel_to_world_values(self, pixel_array): return np.asarray(pixel_array - 10) * 3e9 + 4e9 def world_to_pixel_values(self, world_array): return np.asarray(world_array - 4e9) / 3e9 + 10 @property def world_axis_object_components(self): return ('test', 0, 'value'), @property def world_axis_object_classes(self): return {'test': (Quantity, (), {'unit': 'Hz'})} @pytest.fixture def spectral_1d_ape14_wcs(): return Spectral1DLowLevelWCS() class Celestial2DLowLevelWCS(BaseLowLevelWCS): @property def pixel_n_dim(self): return 2 @property def world_n_dim(self): return 2 @property def world_axis_physical_types(self): return 'pos.eq.ra', 'pos.eq.dec' @property def world_axis_units(self): return 'deg', 'deg' @property def world_axis_names(self): return 'Right Ascension', 'Declination' @property def pixel_shape(self): return (6, 7) @property def pixel_bounds(self): return (-1, 5), (1, 7) def pixel_to_world_values(self, px, py): return (-(np.asarray(px) - 5.) * 2 + 4., (np.asarray(py) - 6.) * 2) def world_to_pixel_values(self, wx, wy): return (-(np.asarray(wx) - 4.) / 2 + 5., np.asarray(wy) / 2 + 6.) @property def world_axis_object_components(self): return [('test', 0, 'spherical.lon.degree'), ('test', 1, 'spherical.lat.degree')] @property def world_axis_object_classes(self): return {'test': (SkyCoord, (), {'unit': 'deg'})} @pytest.fixture def celestial_2d_ape14_wcs(): return Celestial2DLowLevelWCS() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2432582 astropy-5.0.2/astropy/wcs/wcsapi/data/0000755000175100001710000000000000000000000016741 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/wcsapi/data/ucds.txt0000644000175100001710000001561000000000000020443 0ustar00vstsdocker# Copied from UCD1+ v1.23 arith arith.diff arith.factor arith.grad arith.rate arith.ratio arith.zp em em.radio em.radio.20-100MHz em.radio.100-200MHz em.radio.200-400MHz em.radio.400-750MHz em.radio.750-1500MHz em.radio.1500-3000MHz em.radio.3-6GHz em.radio.6-12GHz em.radio.12-30GHz em.mm em.mm.30-50GHz em.mm.50-100GHz em.mm.100-200GHz em.mm.200-400GHz em.mm.400-750GHz em.mm.750-1500GHz em.mm.1500-3000GHz em.IR em.IR.J em.IR.H em.IR.K em.IR.3-4um em.IR.4-8um em.IR.8-15um em.IR.15-30um em.IR.30-60um em.IR.60-100um em.IR.NIR em.IR.MIR em.IR.FIR em.opt em.opt.U em.opt.B em.opt.V em.opt.R em.opt.I em.UV em.UV.10-50nm em.UV.50-100nm em.UV.100-200nm em.UV.200-300nm em.UV.FUV em.X-ray em.X-ray.soft em.X-ray.medium em.X-ray.hard em.gamma em.gamma.soft em.gamma.hard em.line em.line.Brgamma em.line.HI em.line.Halpha em.line.Hbeta em.line.Hgamma em.line.Hdelta em.line.Lyalpha em.line.OIII em.line.CO em.bin em.energy em.freq em.wavenumber em.wl em.wl.central em.wl.effective instr instr.background instr.bandpass instr.bandwidth instr.baseline instr.beam instr.calib instr.det instr.det.noise instr.det.psf instr.det.qe instr.dispersion instr.filter instr.fov instr.obsty instr.obsty.seeing instr.offset instr.order instr.param instr.pixel instr.plate instr.plate.emulsion instr.precision instr.saturation instr.scale instr.sensitivity instr.setup instr.skyLevel instr.skyTemp instr.tel instr.tel.focalLength meta meta.abstract meta.bib meta.bib.author meta.bib.bibcode meta.bib.fig meta.bib.journal meta.bib.page meta.bib.volume meta.code meta.code.class meta.code.error meta.code.member meta.code.mime meta.code.multip meta.code.qual meta.code.status meta.cryptic meta.curation meta.dataset meta.email meta.file meta.fits meta.id meta.id.assoc meta.id.CoI meta.id.cross meta.id.parent meta.id.part meta.id.PI meta.main meta.modelled meta.note meta.number meta.record meta.ref meta.ref.ivorn meta.ref.uri meta.ref.url meta.software meta.table meta.title meta.ucd meta.unit meta.version obs obs.airMass obs.atmos obs.atmos.extinction obs.atmos.refractAngle obs.calib obs.calib.flat obs.exposure obs.field obs.image obs.observer obs.param obs.proposal obs.proposal.cycle obs.sequence phot phot.antennaTemp phot.calib phot.color phot.color.excess phot.color.reddFree phot.count phot.fluence phot.flux phot.flux.bol phot.flux.density phot.flux.density.sb phot.flux.sb phot.limbDark phot.mag phot.mag.bc phot.mag.bol phot.mag.distMod phot.mag.reddFree phot.mag.sb phys phys.SFR phys.absorption phys.absorption.coeff phys.absorption.gal phys.absorption.opticalDepth phys.abund phys.abund.Fe phys.abund.X phys.abund.Y phys.abund.Z phys.acceleration phys.albedo phys.angArea phys.angMomentum phys.angSize phys.angSize.smajAxis phys.angSize.sminAxis phys.area phys.atmol phys.atmol.branchingRatio phys.atmol.collStrength phys.atmol.collisional phys.atmol.configuration phys.atmol.crossSection phys.atmol.element phys.atmol.excitation phys.atmol.final phys.atmol.initial phys.atmol.ionStage phys.atmol.ionization phys.atmol.lande phys.atmol.level phys.atmol.lifetime phys.atmol.lineShift phys.atmol.number phys.atmol.oscStrength phys.atmol.parity phys.atmol.qn phys.atmol.radiationType phys.atmol.symmetry phys.atmol.sWeight phys.atmol.sWeight.nuclear phys.atmol.term phys.atmol.transProb phys.atmol.transition phys.atmol.wOscStrength phys.atmol.weight phys.columnDensity phys.composition phys.composition.massLightRatio phys.composition.yield phys.cosmology phys.damping phys.density phys.dielectric phys.dispMeasure phys.electField phys.electron phys.electron.degen phys.emissMeasure phys.emissivity phys.energy phys.energy.density phys.entropy phys.eos phys.excitParam phys.gauntFactor phys.gravity phys.ionizParam phys.ionizParam.coll phys.ionizParam.rad phys.luminosity phys.luminosity.fun phys.magAbs phys.magAbs.bol phys.magField phys.mass phys.mass.loss phys.mol phys.mol.dipole phys.mol.dipole.electric phys.mol.dipole.magnetic phys.mol.dissociation phys.mol.formationHeat phys.mol.quadrupole phys.mol.quadrupole.electric phys.mol.rotation phys.mol.vibration phys.particle.neutrino phys.polarization phys.polarization.circular phys.polarization.linear phys.polarization.rotMeasure phys.polarization.stokes phys.pressure phys.recombination.coeff phys.refractIndex phys.size phys.size.axisRatio phys.size.diameter phys.size.radius phys.size.smajAxis phys.size.sminAxis phys.temperature phys.temperature.effective phys.temperature.electron phys.transmission phys.veloc phys.veloc.ang phys.veloc.dispersion phys.veloc.escape phys.veloc.expansion phys.veloc.microTurb phys.veloc.orbital phys.veloc.pulsat phys.veloc.rotat phys.veloc.transverse phys.virial pos pos.angDistance pos.angResolution pos.az pos.az.alt pos.az.azi pos.az.zd pos.barycenter pos.bodyrc pos.bodyrc.alt pos.bodyrc.lat pos.bodyrc.lon pos.cartesian pos.cartesian.x pos.cartesian.y pos.cartesian.z pos.cmb pos.dirCos pos.distance pos.earth pos.earth.altitude pos.earth.lat pos.earth.lon pos.ecliptic pos.ecliptic.lat pos.ecliptic.lon pos.eop pos.eop.nutation pos.ephem pos.eq pos.eq.dec pos.eq.ha pos.eq.ra pos.eq.spd pos.errorEllipse pos.frame pos.galactic pos.galactic.lat pos.galactic.lon pos.galactocentric pos.geocentric pos.healpix pos.heliocentric pos.HTM pos.lambert pos.lg pos.lsr pos.lunar pos.lunar.occult pos.parallax pos.parallax.dyn pos.parallax.phot pos.parallax.spect pos.parallax.trig pos.phaseAng pos.pm pos.posAng pos.precess pos.supergalactic pos.supergalactic.lat pos.supergalactic.lon pos.wcs pos.wcs.cdmatrix pos.wcs.crpix pos.wcs.crval pos.wcs.ctype pos.wcs.naxes pos.wcs.naxis pos.wcs.scale spect spect.binSize spect.continuum spect.dopplerParam spect.dopplerVeloc spect.dopplerVeloc.opt spect.dopplerVeloc.radio spect.index spect.line spect.line.asymmetry spect.line.broad spect.line.broad.Stark spect.line.broad.Zeeman spect.line.eqWidth spect.line.intensity spect.line.profile spect.line.strength spect.line.width spect.resolution src src.calib src.calib.guideStar src.class src.class.color src.class.distance src.class.luminosity src.class.richness src.class.starGalaxy src.class.struct src.density src.ellipticity src.impactParam src.morph src.morph.param src.morph.scLength src.morph.type src.net src.orbital src.orbital.eccentricity src.orbital.inclination src.orbital.meanAnomaly src.orbital.meanMotion src.orbital.node src.orbital.periastron src.redshift src.redshift.phot src.sample src.spType src.var src.var.amplitude src.var.index src.var.pulse stat stat.Fourier stat.Fourier.amplitude stat.correlation stat.covariance stat.error stat.error.sys stat.filling stat.fit stat.fit.chi2 stat.fit.dof stat.fit.goodness stat.fit.omc stat.fit.param stat.fit.residual stat.likelihood stat.max stat.mean stat.median stat.min stat.param stat.probability stat.snr stat.stdev stat.uncalib stat.value stat.variance stat.weight time time.age time.creation time.crossing time.duration time.end time.epoch time.equinox time.interval time.lifetime time.period time.phase time.processing time.publiYear time.relax time.release time.resolution time.scale time.start ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/wcsapi/fitswcs.py0000644000175100001710000006404400000000000020074 0ustar00vstsdocker# This file includes the definition of a mix-in class that provides the low- # and high-level WCS API to the astropy.wcs.WCS object. We keep this code # isolated in this mix-in class to avoid making the main wcs.py file too # long. import warnings import numpy as np from astropy import units as u from astropy.coordinates import SpectralCoord, Galactic, ICRS from astropy.coordinates.spectral_coordinate import update_differentials_to_match, attach_zero_velocities from astropy.utils.exceptions import AstropyUserWarning from astropy.constants import c from .low_level_api import BaseLowLevelWCS from .high_level_api import HighLevelWCSMixin from .wrappers import SlicedLowLevelWCS __all__ = ['custom_ctype_to_ucd_mapping', 'SlicedFITSWCS', 'FITSWCSAPIMixin'] C_SI = c.si.value VELOCITY_FRAMES = { 'GEOCENT': 'gcrs', 'BARYCENT': 'icrs', 'HELIOCENT': 'hcrs', 'LSRK': 'lsrk', 'LSRD': 'lsrd' } # The spectra velocity frames below are needed for FITS spectral WCS # (see Greisen 06 table 12) but aren't yet defined as real # astropy.coordinates frames, so we instead define them here as instances # of existing coordinate frames with offset velocities. In future we should # make these real frames so that users can more easily recognize these # velocity frames when used in SpectralCoord. # This frame is defined as a velocity of 220 km/s in the # direction of l=90, b=0. The rotation velocity is defined # in: # # Kerr and Lynden-Bell 1986, Review of galactic constants. # # NOTE: this may differ from the assumptions of galcen_v_sun # in the Galactocentric frame - the value used here is # the one adopted by the WCS standard for spectral # transformations. VELOCITY_FRAMES['GALACTOC'] = Galactic(u=0 * u.km, v=0 * u.km, w=0 * u.km, U=0 * u.km / u.s, V=-220 * u.km / u.s, W=0 * u.km / u.s, representation_type='cartesian', differential_type='cartesian') # This frame is defined as a velocity of 300 km/s in the # direction of l=90, b=0. This is defined in: # # Transactions of the IAU Vol. XVI B Proceedings of the # 16th General Assembly, Reports of Meetings of Commissions: # Comptes Rendus Des SÊances Des Commissions, Commission 28, # p201. # # Note that these values differ from those used by CASA # (308 km/s towards l=105, b=-7) but we use the above values # since these are the ones defined in Greisen et al (2006). VELOCITY_FRAMES['LOCALGRP'] = Galactic(u=0 * u.km, v=0 * u.km, w=0 * u.km, U=0 * u.km / u.s, V=-300 * u.km / u.s, W=0 * u.km / u.s, representation_type='cartesian', differential_type='cartesian') # This frame is defined as a velocity of 368 km/s in the # direction of l=263.85, b=48.25. This is defined in: # # Bennett et al. (2003), First-Year Wilkinson Microwave # Anisotropy Probe (WMAP) Observations: Preliminary Maps # and Basic Results # # Note that in that paper, the dipole is expressed as a # temperature (T=3.346 +/- 0.017mK) VELOCITY_FRAMES['CMBDIPOL'] = Galactic(l=263.85 * u.deg, b=48.25 * u.deg, distance=0 * u.km, radial_velocity=-(3.346e-3 / 2.725 * c).to(u.km/u.s)) # Mapping from CTYPE axis name to UCD1 CTYPE_TO_UCD1 = { # Celestial coordinates 'RA': 'pos.eq.ra', 'DEC': 'pos.eq.dec', 'GLON': 'pos.galactic.lon', 'GLAT': 'pos.galactic.lat', 'ELON': 'pos.ecliptic.lon', 'ELAT': 'pos.ecliptic.lat', 'TLON': 'pos.bodyrc.lon', 'TLAT': 'pos.bodyrc.lat', 'HPLT': 'custom:pos.helioprojective.lat', 'HPLN': 'custom:pos.helioprojective.lon', 'HPRZ': 'custom:pos.helioprojective.z', 'HGLN': 'custom:pos.heliographic.stonyhurst.lon', 'HGLT': 'custom:pos.heliographic.stonyhurst.lat', 'CRLN': 'custom:pos.heliographic.carrington.lon', 'CRLT': 'custom:pos.heliographic.carrington.lat', 'SOLX': 'custom:pos.heliocentric.x', 'SOLY': 'custom:pos.heliocentric.y', 'SOLZ': 'custom:pos.heliocentric.z', # Spectral coordinates (WCS paper 3) 'FREQ': 'em.freq', # Frequency 'ENER': 'em.energy', # Energy 'WAVN': 'em.wavenumber', # Wavenumber 'WAVE': 'em.wl', # Vacuum wavelength 'VRAD': 'spect.dopplerVeloc.radio', # Radio velocity 'VOPT': 'spect.dopplerVeloc.opt', # Optical velocity 'ZOPT': 'src.redshift', # Redshift 'AWAV': 'em.wl', # Air wavelength 'VELO': 'spect.dopplerVeloc', # Apparent radial velocity 'BETA': 'custom:spect.doplerVeloc.beta', # Beta factor (v/c) 'STOKES': 'phys.polarization.stokes', # STOKES parameters # Time coordinates (https://www.aanda.org/articles/aa/pdf/2015/02/aa24653-14.pdf) 'TIME': 'time', 'TAI': 'time', 'TT': 'time', 'TDT': 'time', 'ET': 'time', 'IAT': 'time', 'UT1': 'time', 'UTC': 'time', 'GMT': 'time', 'GPS': 'time', 'TCG': 'time', 'TCB': 'time', 'TDB': 'time', 'LOCAL': 'time', # Distance coordinates 'DIST': 'pos.distance', 'DSUN': 'custom:pos.distance.sunToObserver' # UT() and TT() are handled separately in world_axis_physical_types } # Keep a list of additional custom mappings that have been registered. This # is kept as a list in case nested context managers are used CTYPE_TO_UCD1_CUSTOM = [] class custom_ctype_to_ucd_mapping: """ A context manager that makes it possible to temporarily add new CTYPE to UCD1+ mapping used by :attr:`FITSWCSAPIMixin.world_axis_physical_types`. Parameters ---------- mapping : dict A dictionary mapping a CTYPE value to a UCD1+ value Examples -------- Consider a WCS with the following CTYPE:: >>> from astropy.wcs import WCS >>> wcs = WCS(naxis=1) >>> wcs.wcs.ctype = ['SPAM'] By default, :attr:`FITSWCSAPIMixin.world_axis_physical_types` returns `None`, but this can be overridden:: >>> wcs.world_axis_physical_types [None] >>> with custom_ctype_to_ucd_mapping({'SPAM': 'food.spam'}): ... wcs.world_axis_physical_types ['food.spam'] """ def __init__(self, mapping): CTYPE_TO_UCD1_CUSTOM.insert(0, mapping) self.mapping = mapping def __enter__(self): pass def __exit__(self, type, value, tb): CTYPE_TO_UCD1_CUSTOM.remove(self.mapping) class SlicedFITSWCS(SlicedLowLevelWCS, HighLevelWCSMixin): pass class FITSWCSAPIMixin(BaseLowLevelWCS, HighLevelWCSMixin): """ A mix-in class that is intended to be inherited by the :class:`~astropy.wcs.WCS` class and provides the low- and high-level WCS API """ @property def pixel_n_dim(self): return self.naxis @property def world_n_dim(self): return len(self.wcs.ctype) @property def array_shape(self): if self.pixel_shape is None: return None else: return self.pixel_shape[::-1] @array_shape.setter def array_shape(self, value): if value is None: self.pixel_shape = None else: self.pixel_shape = value[::-1] @property def pixel_shape(self): if self._naxis == [0, 0]: return None else: return tuple(self._naxis) @pixel_shape.setter def pixel_shape(self, value): if value is None: self._naxis = [0, 0] else: if len(value) != self.naxis: raise ValueError("The number of data axes, " "{}, does not equal the " "shape {}.".format(self.naxis, len(value))) self._naxis = list(value) @property def pixel_bounds(self): return self._pixel_bounds @pixel_bounds.setter def pixel_bounds(self, value): if value is None: self._pixel_bounds = value else: if len(value) != self.naxis: raise ValueError("The number of data axes, " "{}, does not equal the number of " "pixel bounds {}.".format(self.naxis, len(value))) self._pixel_bounds = list(value) @property def world_axis_physical_types(self): types = [] # TODO: need to support e.g. TT(TAI) for ctype in self.wcs.ctype: if ctype.upper().startswith(('UT(', 'TT(')): types.append('time') else: ctype_name = ctype.split('-')[0] for custom_mapping in CTYPE_TO_UCD1_CUSTOM: if ctype_name in custom_mapping: types.append(custom_mapping[ctype_name]) break else: types.append(CTYPE_TO_UCD1.get(ctype_name.upper(), None)) return types @property def world_axis_units(self): units = [] for unit in self.wcs.cunit: if unit is None: unit = '' elif isinstance(unit, u.Unit): unit = unit.to_string(format='vounit') else: try: unit = u.Unit(unit).to_string(format='vounit') except u.UnitsError: unit = '' units.append(unit) return units @property def world_axis_names(self): return list(self.wcs.cname) @property def axis_correlation_matrix(self): # If there are any distortions present, we assume that there may be # correlations between all axes. Maybe if some distortions only apply # to the image plane we can improve this? if self.has_distortion: return np.ones((self.world_n_dim, self.pixel_n_dim), dtype=bool) # Assuming linear world coordinates along each axis, the correlation # matrix would be given by whether or not the PC matrix is zero matrix = self.wcs.get_pc() != 0 # We now need to check specifically for celestial coordinates since # these can assume correlations because of spherical distortions. For # each celestial coordinate we copy over the pixel dependencies from # the other celestial coordinates. celestial = (self.wcs.axis_types // 1000) % 10 == 2 celestial_indices = np.nonzero(celestial)[0] for world1 in celestial_indices: for world2 in celestial_indices: if world1 != world2: matrix[world1] |= matrix[world2] matrix[world2] |= matrix[world1] return matrix def pixel_to_world_values(self, *pixel_arrays): world = self.all_pix2world(*pixel_arrays, 0) return world[0] if self.world_n_dim == 1 else tuple(world) def world_to_pixel_values(self, *world_arrays): pixel = self.all_world2pix(*world_arrays, 0) return pixel[0] if self.pixel_n_dim == 1 else tuple(pixel) @property def world_axis_object_components(self): return self._get_components_and_classes()[0] @property def world_axis_object_classes(self): return self._get_components_and_classes()[1] @property def serialized_classes(self): return False def _get_components_and_classes(self): # The aim of this function is to return whatever is needed for # world_axis_object_components and world_axis_object_classes. It's easier # to figure it out in one go and then return the values and let the # properties return part of it. # Since this method might get called quite a few times, we need to cache # it. We start off by defining a hash based on the attributes of the # WCS that matter here (we can't just use the WCS object as a hash since # it is mutable) wcs_hash = (self.naxis, list(self.wcs.ctype), list(self.wcs.cunit), self.wcs.radesys, self.wcs.specsys, self.wcs.equinox, self.wcs.dateobs, self.wcs.lng, self.wcs.lat) # If the cache is present, we need to check that the 'hash' matches. if getattr(self, '_components_and_classes_cache', None) is not None: cache = self._components_and_classes_cache if cache[0] == wcs_hash: return cache[1] else: self._components_and_classes_cache = None # Avoid circular imports by importing here from astropy.wcs.utils import wcs_to_celestial_frame from astropy.coordinates import SkyCoord, EarthLocation from astropy.time.formats import FITS_DEPRECATED_SCALES from astropy.time import Time, TimeDelta components = [None] * self.naxis classes = {} # Let's start off by checking whether the WCS has a pair of celestial # components if self.has_celestial: try: celestial_frame = wcs_to_celestial_frame(self) except ValueError: # Some WCSes, e.g. solar, can be recognized by WCSLIB as being # celestial but we don't necessarily have frames for them. celestial_frame = None else: kwargs = {} kwargs['frame'] = celestial_frame kwargs['unit'] = u.deg classes['celestial'] = (SkyCoord, (), kwargs) components[self.wcs.lng] = ('celestial', 0, 'spherical.lon.degree') components[self.wcs.lat] = ('celestial', 1, 'spherical.lat.degree') # Next, we check for spectral components if self.has_spectral: # Find index of spectral coordinate ispec = self.wcs.spec ctype = self.wcs.ctype[ispec][:4] ctype = ctype.upper() kwargs = {} # Determine observer location and velocity # TODO: determine how WCS standard would deal with observer on a # spacecraft far from earth. For now assume the obsgeo parameters, # if present, give the geocentric observer location. if np.isnan(self.wcs.obsgeo[0]): observer = None else: earth_location = EarthLocation(*self.wcs.obsgeo[:3], unit=u.m) obstime = Time(self.wcs.mjdobs, format='mjd', scale='utc', location=earth_location) observer_location = SkyCoord(earth_location.get_itrs(obstime=obstime)) if self.wcs.specsys in VELOCITY_FRAMES: frame = VELOCITY_FRAMES[self.wcs.specsys] observer = observer_location.transform_to(frame) if isinstance(frame, str): observer = attach_zero_velocities(observer) else: observer = update_differentials_to_match(observer_location, VELOCITY_FRAMES[self.wcs.specsys], preserve_observer_frame=True) elif self.wcs.specsys == 'TOPOCENT': observer = attach_zero_velocities(observer_location) else: raise NotImplementedError(f'SPECSYS={self.wcs.specsys} not yet supported') # Determine target # This is tricker. In principle the target for each pixel is the # celestial coordinates of the pixel, but we then need to be very # careful about SSYSOBS which is tricky. For now, we set the # target using the reference celestial coordinate in the WCS (if # any). if self.has_celestial and celestial_frame is not None: # NOTE: celestial_frame was defined higher up # NOTE: we set the distance explicitly to avoid warnings in SpectralCoord target = SkyCoord(self.wcs.crval[self.wcs.lng] * self.wcs.cunit[self.wcs.lng], self.wcs.crval[self.wcs.lat] * self.wcs.cunit[self.wcs.lat], frame=celestial_frame, distance=1000 * u.kpc) target = attach_zero_velocities(target) else: target = None # SpectralCoord does not work properly if either observer or target # are not convertible to ICRS, so if this is the case, we (for now) # drop the observer and target from the SpectralCoord and warn the # user. if observer is not None: try: observer.transform_to(ICRS()) except Exception: warnings.warn('observer cannot be converted to ICRS, so will ' 'not be set on SpectralCoord', AstropyUserWarning) observer = None if target is not None: try: target.transform_to(ICRS()) except Exception: warnings.warn('target cannot be converted to ICRS, so will ' 'not be set on SpectralCoord', AstropyUserWarning) target = None # NOTE: below we include Quantity in classes['spectral'] instead # of SpectralCoord - this is because we want to also be able to # accept plain quantities. if ctype == 'ZOPT': def spectralcoord_from_redshift(redshift): if isinstance(redshift, SpectralCoord): return redshift return SpectralCoord((redshift + 1) * self.wcs.restwav, unit=u.m, observer=observer, target=target) def redshift_from_spectralcoord(spectralcoord): # TODO: check target is consistent if observer is None: warnings.warn('No observer defined on WCS, SpectralCoord ' 'will be converted without any velocity ' 'frame change', AstropyUserWarning) return spectralcoord.to_value(u.m) / self.wcs.restwav - 1. else: return spectralcoord.with_observer_stationary_relative_to(observer).to_value(u.m) / self.wcs.restwav - 1. classes['spectral'] = (u.Quantity, (), {}, spectralcoord_from_redshift) components[self.wcs.spec] = ('spectral', 0, redshift_from_spectralcoord) elif ctype == 'BETA': def spectralcoord_from_beta(beta): if isinstance(beta, SpectralCoord): return beta return SpectralCoord(beta * C_SI, unit=u.m / u.s, doppler_convention='relativistic', doppler_rest=self.wcs.restwav * u.m, observer=observer, target=target) def beta_from_spectralcoord(spectralcoord): # TODO: check target is consistent doppler_equiv = u.doppler_relativistic(self.wcs.restwav * u.m) if observer is None: warnings.warn('No observer defined on WCS, SpectralCoord ' 'will be converted without any velocity ' 'frame change', AstropyUserWarning) return spectralcoord.to_value(u.m / u.s, doppler_equiv) / C_SI else: return spectralcoord.with_observer_stationary_relative_to(observer).to_value(u.m / u.s, doppler_equiv) / C_SI classes['spectral'] = (u.Quantity, (), {}, spectralcoord_from_beta) components[self.wcs.spec] = ('spectral', 0, beta_from_spectralcoord) else: kwargs['unit'] = self.wcs.cunit[ispec] if self.wcs.restfrq > 0: if ctype == 'VELO': kwargs['doppler_convention'] = 'relativistic' kwargs['doppler_rest'] = self.wcs.restfrq * u.Hz elif ctype == 'VRAD': kwargs['doppler_convention'] = 'radio' kwargs['doppler_rest'] = self.wcs.restfrq * u.Hz elif ctype == 'VOPT': kwargs['doppler_convention'] = 'optical' kwargs['doppler_rest'] = self.wcs.restwav * u.m def spectralcoord_from_value(value): return SpectralCoord(value, observer=observer, target=target, **kwargs) def value_from_spectralcoord(spectralcoord): # TODO: check target is consistent if observer is None: warnings.warn('No observer defined on WCS, SpectralCoord ' 'will be converted without any velocity ' 'frame change', AstropyUserWarning) return spectralcoord.to_value(**kwargs) else: return spectralcoord.with_observer_stationary_relative_to(observer).to_value(**kwargs) classes['spectral'] = (u.Quantity, (), {}, spectralcoord_from_value) components[self.wcs.spec] = ('spectral', 0, value_from_spectralcoord) # We can then make sure we correctly return Time objects where appropriate # (https://www.aanda.org/articles/aa/pdf/2015/02/aa24653-14.pdf) if 'time' in self.world_axis_physical_types: multiple_time = self.world_axis_physical_types.count('time') > 1 for i in range(self.naxis): if self.world_axis_physical_types[i] == 'time': if multiple_time: name = f'time.{i}' else: name = 'time' # Initialize delta reference_time_delta = None # Extract time scale scale = self.wcs.ctype[i].lower() if scale == 'time': if self.wcs.timesys: scale = self.wcs.timesys.lower() else: scale = 'utc' # Drop sub-scales if '(' in scale: pos = scale.index('(') scale, subscale = scale[:pos], scale[pos+1:-1] warnings.warn(f'Dropping unsupported sub-scale ' f'{subscale.upper()} from scale {scale.upper()}', UserWarning) # TODO: consider having GPS as a scale in Time # For now GPS is not a scale, we approximate this by TAI - 19s if scale == 'gps': reference_time_delta = TimeDelta(19, format='sec') scale = 'tai' elif scale.upper() in FITS_DEPRECATED_SCALES: scale = FITS_DEPRECATED_SCALES[scale.upper()] elif scale not in Time.SCALES: raise ValueError(f'Unrecognized time CTYPE={self.wcs.ctype[i]}') # Determine location trefpos = self.wcs.trefpos.lower() if trefpos.startswith('topocent'): # Note that some headers use TOPOCENT instead of TOPOCENTER if np.any(np.isnan(self.wcs.obsgeo[:3])): warnings.warn('Missing or incomplete observer location ' 'information, setting location in Time to None', UserWarning) location = None else: location = EarthLocation(*self.wcs.obsgeo[:3], unit=u.m) elif trefpos == 'geocenter': location = EarthLocation(0, 0, 0, unit=u.m) elif trefpos == '': location = None else: # TODO: implement support for more locations when Time supports it warnings.warn(f"Observation location '{trefpos}' is not " "supported, setting location in Time to None", UserWarning) location = None reference_time = Time(np.nan_to_num(self.wcs.mjdref[0]), np.nan_to_num(self.wcs.mjdref[1]), format='mjd', scale=scale, location=location) if reference_time_delta is not None: reference_time = reference_time + reference_time_delta def time_from_reference_and_offset(offset): if isinstance(offset, Time): return offset return reference_time + TimeDelta(offset, format='sec') def offset_from_time_and_reference(time): return (time - reference_time).sec classes[name] = (Time, (), {}, time_from_reference_and_offset) components[i] = (name, 0, offset_from_time_and_reference) # Fallback: for any remaining components that haven't been identified, just # return Quantity as the class to use for i in range(self.naxis): if components[i] is None: name = self.wcs.ctype[i].split('-')[0].lower() if name == '': name = 'world' while name in classes: name += "_" classes[name] = (u.Quantity, (), {'unit': self.wcs.cunit[i]}) components[i] = (name, 0, 'value') # Keep a cached version of result self._components_and_classes_cache = wcs_hash, (components, classes) return components, classes ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/wcsapi/high_level_api.py0000644000175100001710000002615500000000000021352 0ustar00vstsdockerimport abc from collections import defaultdict, OrderedDict import numpy as np from .utils import deserialize_class __all__ = ['BaseHighLevelWCS', 'HighLevelWCSMixin'] def rec_getattr(obj, att): for a in att.split('.'): obj = getattr(obj, a) return obj def default_order(components): order = [] for key, _, _ in components: if key not in order: order.append(key) return order def _toindex(value): """ Convert value to an int or an int array. Input coordinates converted to integers corresponding to the center of the pixel. The convention is that the center of the pixel is (0, 0), while the lower left corner is (-0.5, -0.5). The outputs are used to index the mask. Examples -------- >>> _toindex(np.array([-0.5, 0.49999])) array([0, 0]) >>> _toindex(np.array([0.5, 1.49999])) array([1, 1]) >>> _toindex(np.array([1.5, 2.49999])) array([2, 2]) """ indx = np.asarray(np.floor(np.asarray(value) + 0.5), dtype=int) return indx class BaseHighLevelWCS(metaclass=abc.ABCMeta): """ Abstract base class for the high-level WCS interface. This is described in `APE 14: A shared Python interface for World Coordinate Systems `_. """ @property @abc.abstractmethod def low_level_wcs(self): """ Returns a reference to the underlying low-level WCS object. """ @abc.abstractmethod def pixel_to_world(self, *pixel_arrays): """ Convert pixel coordinates to world coordinates (represented by high-level objects). If a single high-level object is used to represent the world coordinates (i.e., if ``len(wcs.world_axis_object_classes) == 1``), it is returned as-is (not in a tuple/list), otherwise a tuple of high-level objects is returned. See `~astropy.wcs.wcsapi.BaseLowLevelWCS.pixel_to_world_values` for pixel indexing and ordering conventions. """ def array_index_to_world(self, *index_arrays): """ Convert array indices to world coordinates (represented by Astropy objects). If a single high-level object is used to represent the world coordinates (i.e., if ``len(wcs.world_axis_object_classes) == 1``), it is returned as-is (not in a tuple/list), otherwise a tuple of high-level objects is returned. See `~astropy.wcs.wcsapi.BaseLowLevelWCS.array_index_to_world_values` for pixel indexing and ordering conventions. """ return self.pixel_to_world(*index_arrays[::-1]) @abc.abstractmethod def world_to_pixel(self, *world_objects): """ Convert world coordinates (represented by Astropy objects) to pixel coordinates. If `~astropy.wcs.wcsapi.BaseLowLevelWCS.pixel_n_dim` is ``1``, this method returns a single scalar or array, otherwise a tuple of scalars or arrays is returned. See `~astropy.wcs.wcsapi.BaseLowLevelWCS.world_to_pixel_values` for pixel indexing and ordering conventions. """ def world_to_array_index(self, *world_objects): """ Convert world coordinates (represented by Astropy objects) to array indices. If `~astropy.wcs.wcsapi.BaseLowLevelWCS.pixel_n_dim` is ``1``, this method returns a single scalar or array, otherwise a tuple of scalars or arrays is returned. See `~astropy.wcs.wcsapi.BaseLowLevelWCS.world_to_array_index_values` for pixel indexing and ordering conventions. The indices should be returned as rounded integers. """ if self.pixel_n_dim == 1: return _toindex(self.world_to_pixel(*world_objects)) else: return tuple(_toindex(self.world_to_pixel(*world_objects)[::-1]).tolist()) def high_level_objects_to_values(*world_objects, low_level_wcs): """ Convert the input high level object to low level values. This function uses the information in ``wcs.world_axis_object_classes`` and ``wcs.world_axis_object_components`` to convert the high level objects (such as `~.SkyCoord`) to low level "values" `~.Quantity` objects. This is used in `.HighLevelWCSMixin.world_to_pixel`, but provided as a separate function for use in other places where needed. Parameters ---------- *world_objects: object High level coordinate objects. low_level_wcs: `.BaseLowLevelWCS` The WCS object to use to interpret the coordinates. """ # Cache the classes and components since this may be expensive serialized_classes = low_level_wcs.world_axis_object_classes components = low_level_wcs.world_axis_object_components # Deserialize world_axis_object_classes using the default order classes = OrderedDict() for key in default_order(components): if low_level_wcs.serialized_classes: classes[key] = deserialize_class(serialized_classes[key], construct=False) else: classes[key] = serialized_classes[key] # Check that the number of classes matches the number of inputs if len(world_objects) != len(classes): raise ValueError("Number of world inputs ({}) does not match " "expected ({})".format(len(world_objects), len(classes))) # Determine whether the classes are uniquely matched, that is we check # whether there is only one of each class. world_by_key = {} unique_match = True for w in world_objects: matches = [] for key, (klass, *_) in classes.items(): if isinstance(w, klass): matches.append(key) if len(matches) == 1: world_by_key[matches[0]] = w else: unique_match = False break # If the match is not unique, the order of the classes needs to match, # whereas if all classes are unique, we can still intelligently match # them even if the order is wrong. objects = {} if unique_match: for key, (klass, args, kwargs, *rest) in classes.items(): if len(rest) == 0: klass_gen = klass elif len(rest) == 1: klass_gen = rest[0] else: raise ValueError("Tuples in world_axis_object_classes should have length 3 or 4") # FIXME: For now SkyCoord won't auto-convert upon initialization # https://github.com/astropy/astropy/issues/7689 from astropy.coordinates import SkyCoord if isinstance(world_by_key[key], SkyCoord): if 'frame' in kwargs: objects[key] = world_by_key[key].transform_to(kwargs['frame']) else: objects[key] = world_by_key[key] else: objects[key] = klass_gen(world_by_key[key], *args, **kwargs) else: for ikey, key in enumerate(classes): klass, args, kwargs, *rest = classes[key] if len(rest) == 0: klass_gen = klass elif len(rest) == 1: klass_gen = rest[0] else: raise ValueError("Tuples in world_axis_object_classes should have length 3 or 4") w = world_objects[ikey] if not isinstance(w, klass): raise ValueError("Expected the following order of world " "arguments: {}".format(', '.join([k.__name__ for (k, _, _) in classes.values()]))) # FIXME: For now SkyCoord won't auto-convert upon initialization # https://github.com/astropy/astropy/issues/7689 from astropy.coordinates import SkyCoord if isinstance(w, SkyCoord): if 'frame' in kwargs: objects[key] = w.transform_to(kwargs['frame']) else: objects[key] = w else: objects[key] = klass_gen(w, *args, **kwargs) # We now extract the attributes needed for the world values world = [] for key, _, attr in components: if callable(attr): world.append(attr(objects[key])) else: world.append(rec_getattr(objects[key], attr)) return world def values_to_high_level_objects(*world_values, low_level_wcs): """ Convert low level values into high level objects. This function uses the information in ``wcs.world_axis_object_classes`` and ``wcs.world_axis_object_components`` to convert low level "values" `~.Quantity` objects, to high level objects (such as `~.SkyCoord). This is used in `.HighLevelWCSMixin.pixel_to_world`, but provided as a separate function for use in other places where needed. Parameters ---------- *world_values: object Low level, "values" representations of the world coordinates. low_level_wcs: `.BaseLowLevelWCS` The WCS object to use to interpret the coordinates. """ # Cache the classes and components since this may be expensive components = low_level_wcs.world_axis_object_components classes = low_level_wcs.world_axis_object_classes # Deserialize classes if low_level_wcs.serialized_classes: classes_new = {} for key, value in classes.items(): classes_new[key] = deserialize_class(value, construct=False) classes = classes_new args = defaultdict(list) kwargs = defaultdict(dict) for i, (key, attr, _) in enumerate(components): if isinstance(attr, str): kwargs[key][attr] = world_values[i] else: while attr > len(args[key]) - 1: args[key].append(None) args[key][attr] = world_values[i] result = [] for key in default_order(components): klass, ar, kw, *rest = classes[key] if len(rest) == 0: klass_gen = klass elif len(rest) == 1: klass_gen = rest[0] else: raise ValueError("Tuples in world_axis_object_classes should have length 3 or 4") result.append(klass_gen(*args[key], *ar, **kwargs[key], **kw)) return result class HighLevelWCSMixin(BaseHighLevelWCS): """ Mix-in class that automatically provides the high-level WCS API for the low-level WCS object given by the `~HighLevelWCSMixin.low_level_wcs` property. """ @property def low_level_wcs(self): return self def world_to_pixel(self, *world_objects): world_values = high_level_objects_to_values(*world_objects, low_level_wcs=self.low_level_wcs) # Finally we convert to pixel coordinates pixel_values = self.low_level_wcs.world_to_pixel_values(*world_values) return pixel_values def pixel_to_world(self, *pixel_arrays): # Compute the world coordinate values world_values = self.low_level_wcs.pixel_to_world_values(*pixel_arrays) if self.world_n_dim == 1: world_values = (world_values,) pixel_values = values_to_high_level_objects(*world_values, low_level_wcs=self.low_level_wcs) if len(pixel_values) == 1: return pixel_values[0] else: return pixel_values ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/wcsapi/high_level_wcs_wrapper.py0000644000175100001710000000436600000000000023135 0ustar00vstsdockerfrom .high_level_api import HighLevelWCSMixin from .low_level_api import BaseLowLevelWCS from .utils import wcs_info_str __all__ = ['HighLevelWCSWrapper'] class HighLevelWCSWrapper(HighLevelWCSMixin): """ Wrapper class that can take any :class:`~astropy.wcs.wcsapi.BaseLowLevelWCS` object and expose the high-level WCS API. """ def __init__(self, low_level_wcs): if not isinstance(low_level_wcs, BaseLowLevelWCS): raise TypeError('Input to a HighLevelWCSWrapper must be a low level WCS object') self._low_level_wcs = low_level_wcs @property def low_level_wcs(self): return self._low_level_wcs @property def pixel_n_dim(self): """ See `~astropy.wcs.wcsapi.BaseLowLevelWCS.world_n_dim` """ return self.low_level_wcs.pixel_n_dim @property def world_n_dim(self): """ See `~astropy.wcs.wcsapi.BaseLowLevelWCS.world_n_dim` """ return self.low_level_wcs.world_n_dim @property def world_axis_physical_types(self): """ See `~astropy.wcs.wcsapi.BaseLowLevelWCS.world_axis_physical_types` """ return self.low_level_wcs.world_axis_physical_types @property def world_axis_units(self): """ See `~astropy.wcs.wcsapi.BaseLowLevelWCS.world_axis_units` """ return self.low_level_wcs.world_axis_units @property def array_shape(self): """ See `~astropy.wcs.wcsapi.BaseLowLevelWCS.array_shape` """ return self.low_level_wcs.array_shape @property def pixel_bounds(self): """ See `~astropy.wcs.wcsapi.BaseLowLevelWCS.pixel_bounds` """ return self.low_level_wcs.pixel_bounds @property def axis_correlation_matrix(self): """ See `~astropy.wcs.wcsapi.BaseLowLevelWCS.axis_correlation_matrix` """ return self.low_level_wcs.axis_correlation_matrix def _as_mpl_axes(self): """ See `~astropy.wcs.wcsapi.BaseLowLevelWCS._as_mpl_axes` """ return self.low_level_wcs._as_mpl_axes() def __str__(self): return wcs_info_str(self.low_level_wcs) def __repr__(self): return f"{object.__repr__(self)}\n{str(self)}" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/wcsapi/low_level_api.py0000644000175100001710000003656600000000000021243 0ustar00vstsdockerimport os import abc import numpy as np __all__ = ['BaseLowLevelWCS', 'validate_physical_types'] class BaseLowLevelWCS(metaclass=abc.ABCMeta): """ Abstract base class for the low-level WCS interface. This is described in `APE 14: A shared Python interface for World Coordinate Systems `_. """ @property @abc.abstractmethod def pixel_n_dim(self): """ The number of axes in the pixel coordinate system. """ @property @abc.abstractmethod def world_n_dim(self): """ The number of axes in the world coordinate system. """ @property @abc.abstractmethod def world_axis_physical_types(self): """ An iterable of strings describing the physical type for each world axis. These should be names from the VO UCD1+ controlled Vocabulary (http://www.ivoa.net/documents/latest/UCDlist.html). If no matching UCD type exists, this can instead be ``"custom:xxx"``, where ``xxx`` is an arbitrary string. Alternatively, if the physical type is unknown/undefined, an element can be `None`. """ @property @abc.abstractmethod def world_axis_units(self): """ An iterable of strings given the units of the world coordinates for each axis. The strings should follow the `IVOA VOUnit standard `_ (though as noted in the VOUnit specification document, units that do not follow this standard are still allowed, but just not recommended). """ @abc.abstractmethod def pixel_to_world_values(self, *pixel_arrays): """ Convert pixel coordinates to world coordinates. This method takes `~astropy.wcs.wcsapi.BaseLowLevelWCS.pixel_n_dim` scalars or arrays as input, and pixel coordinates should be zero-based. Returns `~astropy.wcs.wcsapi.BaseLowLevelWCS.world_n_dim` scalars or arrays in units given by `~astropy.wcs.wcsapi.BaseLowLevelWCS.world_axis_units`. Note that pixel coordinates are assumed to be 0 at the center of the first pixel in each dimension. If a pixel is in a region where the WCS is not defined, NaN can be returned. The coordinates should be specified in the ``(x, y)`` order, where for an image, ``x`` is the horizontal coordinate and ``y`` is the vertical coordinate. If `~astropy.wcs.wcsapi.BaseLowLevelWCS.world_n_dim` is ``1``, this method returns a single scalar or array, otherwise a tuple of scalars or arrays is returned. """ def array_index_to_world_values(self, *index_arrays): """ Convert array indices to world coordinates. This is the same as `~astropy.wcs.wcsapi.BaseLowLevelWCS.pixel_to_world_values` except that the indices should be given in ``(i, j)`` order, where for an image ``i`` is the row and ``j`` is the column (i.e. the opposite order to `~astropy.wcs.wcsapi.BaseLowLevelWCS.pixel_to_world_values`). If `~astropy.wcs.wcsapi.BaseLowLevelWCS.world_n_dim` is ``1``, this method returns a single scalar or array, otherwise a tuple of scalars or arrays is returned. """ return self.pixel_to_world_values(*index_arrays[::-1]) @abc.abstractmethod def world_to_pixel_values(self, *world_arrays): """ Convert world coordinates to pixel coordinates. This method takes `~astropy.wcs.wcsapi.BaseLowLevelWCS.world_n_dim` scalars or arrays as input in units given by `~astropy.wcs.wcsapi.BaseLowLevelWCS.world_axis_units`. Returns `~astropy.wcs.wcsapi.BaseLowLevelWCS.pixel_n_dim` scalars or arrays. Note that pixel coordinates are assumed to be 0 at the center of the first pixel in each dimension. If a world coordinate does not have a matching pixel coordinate, NaN can be returned. The coordinates should be returned in the ``(x, y)`` order, where for an image, ``x`` is the horizontal coordinate and ``y`` is the vertical coordinate. If `~astropy.wcs.wcsapi.BaseLowLevelWCS.pixel_n_dim` is ``1``, this method returns a single scalar or array, otherwise a tuple of scalars or arrays is returned. """ def world_to_array_index_values(self, *world_arrays): """ Convert world coordinates to array indices. This is the same as `~astropy.wcs.wcsapi.BaseLowLevelWCS.world_to_pixel_values` except that the indices should be returned in ``(i, j)`` order, where for an image ``i`` is the row and ``j`` is the column (i.e. the opposite order to `~astropy.wcs.wcsapi.BaseLowLevelWCS.pixel_to_world_values`). The indices should be returned as rounded integers. If `~astropy.wcs.wcsapi.BaseLowLevelWCS.pixel_n_dim` is ``1``, this method returns a single scalar or array, otherwise a tuple of scalars or arrays is returned. """ pixel_arrays = self.world_to_pixel_values(*world_arrays) if self.pixel_n_dim == 1: pixel_arrays = (pixel_arrays,) else: pixel_arrays = pixel_arrays[::-1] array_indices = tuple(np.asarray(np.floor(pixel + 0.5), dtype=np.int_) for pixel in pixel_arrays) return array_indices[0] if self.pixel_n_dim == 1 else array_indices @property @abc.abstractmethod def world_axis_object_components(self): """ A list with `~astropy.wcs.wcsapi.BaseLowLevelWCS.world_n_dim` elements giving information on constructing high-level objects for the world coordinates. Each element of the list is a tuple with three items: * The first is a name for the world object this world array corresponds to, which *must* match the string names used in `~astropy.wcs.wcsapi.BaseLowLevelWCS.world_axis_object_classes`. Note that names might appear twice because two world arrays might correspond to a single world object (e.g. a celestial coordinate might have both “ra” and “dec” arrays, which correspond to a single sky coordinate object). * The second element is either a string keyword argument name or a positional index for the corresponding class from `~astropy.wcs.wcsapi.BaseLowLevelWCS.world_axis_object_classes`. * The third argument is a string giving the name of the property to access on the corresponding class from `~astropy.wcs.wcsapi.BaseLowLevelWCS.world_axis_object_classes` in order to get numerical values. Alternatively, this argument can be a callable Python object that takes a high-level coordinate object and returns the numerical values suitable for passing to the low-level WCS transformation methods. See the document `APE 14: A shared Python interface for World Coordinate Systems `_ for examples. """ @property @abc.abstractmethod def world_axis_object_classes(self): """ A dictionary giving information on constructing high-level objects for the world coordinates. Each key of the dictionary is a string key from `~astropy.wcs.wcsapi.BaseLowLevelWCS.world_axis_object_components`, and each value is a tuple with three elements or four elements: * The first element of the tuple must be a class or a string specifying the fully-qualified name of a class, which will specify the actual Python object to be created. * The second element, should be a tuple specifying the positional arguments required to initialize the class. If `~astropy.wcs.wcsapi.BaseLowLevelWCS.world_axis_object_components` specifies that the world coordinates should be passed as a positional argument, this this tuple should include `None` placeholders for the world coordinates. * The third tuple element must be a dictionary with the keyword arguments required to initialize the class. * Optionally, for advanced use cases, the fourth element (if present) should be a callable Python object that gets called instead of the class and gets passed the positional and keyword arguments. It should return an object of the type of the first element in the tuple. Note that we don't require the classes to be Astropy classes since there is no guarantee that Astropy will have all the classes to represent all kinds of world coordinates. Furthermore, we recommend that the output be kept as human-readable as possible. The classes used here should have the ability to do conversions by passing an instance as the first argument to the same class with different arguments (e.g. ``Time(Time(...), scale='tai')``). This is a requirement for the implementation of the high-level interface. The second and third tuple elements for each value of this dictionary can in turn contain either instances of classes, or if necessary can contain serialized versions that should take the same form as the main classes described above (a tuple with three elements with the fully qualified name of the class, then the positional arguments and the keyword arguments). For low-level API objects implemented in Python, we recommend simply returning the actual objects (not the serialized form) for optimal performance. Implementations should either always or never use serialized classes to represent Python objects, and should indicate which of these they follow using the `~astropy.wcs.wcsapi.BaseLowLevelWCS.serialized_classes` attribute. See the document `APE 14: A shared Python interface for World Coordinate Systems `_ for examples . """ # The following three properties have default fallback implementations, so # they are not abstract. @property def array_shape(self): """ The shape of the data that the WCS applies to as a tuple of length `~astropy.wcs.wcsapi.BaseLowLevelWCS.pixel_n_dim` in ``(row, column)`` order (the convention for arrays in Python). If the WCS is valid in the context of a dataset with a particular shape, then this property can be used to store the shape of the data. This can be used for example if implementing slicing of WCS objects. This is an optional property, and it should return `None` if a shape is not known or relevant. """ if self.pixel_shape is None: return None else: return self.pixel_shape[::-1] @property def pixel_shape(self): """ The shape of the data that the WCS applies to as a tuple of length `~astropy.wcs.wcsapi.BaseLowLevelWCS.pixel_n_dim` in ``(x, y)`` order (where for an image, ``x`` is the horizontal coordinate and ``y`` is the vertical coordinate). If the WCS is valid in the context of a dataset with a particular shape, then this property can be used to store the shape of the data. This can be used for example if implementing slicing of WCS objects. This is an optional property, and it should return `None` if a shape is not known or relevant. If you are interested in getting a shape that is comparable to that of a Numpy array, you should use `~astropy.wcs.wcsapi.BaseLowLevelWCS.array_shape` instead. """ return None @property def pixel_bounds(self): """ The bounds (in pixel coordinates) inside which the WCS is defined, as a list with `~astropy.wcs.wcsapi.BaseLowLevelWCS.pixel_n_dim` ``(min, max)`` tuples. The bounds should be given in ``[(xmin, xmax), (ymin, ymax)]`` order. WCS solutions are sometimes only guaranteed to be accurate within a certain range of pixel values, for example when defining a WCS that includes fitted distortions. This is an optional property, and it should return `None` if a shape is not known or relevant. """ return None @property def pixel_axis_names(self): """ An iterable of strings describing the name for each pixel axis. If an axis does not have a name, an empty string should be returned (this is the default behavior for all axes if a subclass does not override this property). Note that these names are just for display purposes and are not standardized. """ return [''] * self.pixel_n_dim @property def world_axis_names(self): """ An iterable of strings describing the name for each world axis. If an axis does not have a name, an empty string should be returned (this is the default behavior for all axes if a subclass does not override this property). Note that these names are just for display purposes and are not standardized. For standardized axis types, see `~astropy.wcs.wcsapi.BaseLowLevelWCS.world_axis_physical_types`. """ return [''] * self.world_n_dim @property def axis_correlation_matrix(self): """ Returns an (`~astropy.wcs.wcsapi.BaseLowLevelWCS.world_n_dim`, `~astropy.wcs.wcsapi.BaseLowLevelWCS.pixel_n_dim`) matrix that indicates using booleans whether a given world coordinate depends on a given pixel coordinate. This defaults to a matrix where all elements are `True` in the absence of any further information. For completely independent axes, the diagonal would be `True` and all other entries `False`. """ return np.ones((self.world_n_dim, self.pixel_n_dim), dtype=bool) @property def serialized_classes(self): """ Indicates whether Python objects are given in serialized form or as actual Python objects. """ return False def _as_mpl_axes(self): """ Compatibility hook for Matplotlib and WCSAxes. With this method, one can do:: from astropy.wcs import WCS import matplotlib.pyplot as plt wcs = WCS('filename.fits') fig = plt.figure() ax = fig.add_axes([0.15, 0.1, 0.8, 0.8], projection=wcs) ... and this will generate a plot with the correct WCS coordinates on the axes. """ from astropy.visualization.wcsaxes import WCSAxes return WCSAxes, {'wcs': self} UCDS_FILE = os.path.join(os.path.dirname(__file__), 'data', 'ucds.txt') with open(UCDS_FILE) as f: VALID_UCDS = set([x.strip() for x in f.read().splitlines()[1:]]) def validate_physical_types(physical_types): """ Validate a list of physical types against the UCD1+ standard """ for physical_type in physical_types: if (physical_type is not None and physical_type not in VALID_UCDS and not physical_type.startswith('custom:')): raise ValueError( f"'{physical_type}' is not a valid IOVA UCD1+ physical type. " "It must be a string specified in the list (http://www.ivoa.net/documents/latest/UCDlist.html) " "or if no matching type exists it can be any string prepended with 'custom:'." ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/wcsapi/sliced_low_level_wcs.py0000644000175100001710000000054200000000000022572 0ustar00vstsdockerimport warnings from .wrappers.sliced_wcs import SlicedLowLevelWCS, sanitize_slices from astropy.utils.exceptions import AstropyDeprecationWarning warnings.warn( "SlicedLowLevelWCS has been moved to" " astropy.wcs.wcsapi.wrappers.sliced_wcs.SlicedLowLevelWCS, or can be" " imported from astropy.wcs.wcsapi.", AstropyDeprecationWarning) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2432582 astropy-5.0.2/astropy/wcs/wcsapi/tests/0000755000175100001710000000000000000000000017172 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/wcsapi/tests/__init__.py0000644000175100001710000000000000000000000021271 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/wcsapi/tests/test_fitswcs.py0000644000175100001710000010743300000000000022275 0ustar00vstsdocker# Note that we test the main astropy.wcs.WCS class directly rather than testing # the mix-in class on its own (since it's not functional without being used as # a mix-in) import warnings from packaging.version import Version import numpy as np import pytest from numpy.testing import assert_equal, assert_allclose from itertools import product from astropy import units as u from astropy.time import Time from astropy.tests.helper import assert_quantity_allclose from astropy.units import Quantity from astropy.coordinates import ICRS, FK5, Galactic, SkyCoord, SpectralCoord, ITRS, EarthLocation from astropy.io.fits import Header from astropy.io.fits.verify import VerifyWarning from astropy.units.core import UnitsWarning from astropy.utils.data import get_pkg_data_filename from astropy.wcs.wcs import WCS, FITSFixedWarning from astropy.wcs.wcsapi.fitswcs import custom_ctype_to_ucd_mapping, VELOCITY_FRAMES from astropy.wcs._wcs import __version__ as wcsver from astropy.utils import iers from astropy.utils.exceptions import AstropyUserWarning ############################################################################### # The following example is the simplest WCS with default values ############################################################################### WCS_EMPTY = WCS(naxis=1) WCS_EMPTY.wcs.crpix = [1] def test_empty(): wcs = WCS_EMPTY # Low-level API assert wcs.pixel_n_dim == 1 assert wcs.world_n_dim == 1 assert wcs.array_shape is None assert wcs.pixel_shape is None assert wcs.world_axis_physical_types == [None] assert wcs.world_axis_units == [''] assert wcs.pixel_axis_names == [''] assert wcs.world_axis_names == [''] assert_equal(wcs.axis_correlation_matrix, True) assert wcs.world_axis_object_components == [('world', 0, 'value')] assert wcs.world_axis_object_classes['world'][0] is Quantity assert wcs.world_axis_object_classes['world'][1] == () assert wcs.world_axis_object_classes['world'][2]['unit'] is u.one assert_allclose(wcs.pixel_to_world_values(29), 29) assert_allclose(wcs.array_index_to_world_values(29), 29) assert np.ndim(wcs.pixel_to_world_values(29)) == 0 assert np.ndim(wcs.array_index_to_world_values(29)) == 0 assert_allclose(wcs.world_to_pixel_values(29), 29) assert_equal(wcs.world_to_array_index_values(29), (29,)) assert np.ndim(wcs.world_to_pixel_values(29)) == 0 assert np.ndim(wcs.world_to_array_index_values(29)) == 0 # High-level API coord = wcs.pixel_to_world(29) assert_quantity_allclose(coord, 29 * u.one) assert np.ndim(coord) == 0 coord = wcs.array_index_to_world(29) assert_quantity_allclose(coord, 29 * u.one) assert np.ndim(coord) == 0 coord = 15 * u.one x = wcs.world_to_pixel(coord) assert_allclose(x, 15.) assert np.ndim(x) == 0 i = wcs.world_to_array_index(coord) assert_equal(i, 15) assert np.ndim(i) == 0 ############################################################################### # The following example is a simple 2D image with celestial coordinates ############################################################################### HEADER_SIMPLE_CELESTIAL = """ WCSAXES = 2 CTYPE1 = RA---TAN CTYPE2 = DEC--TAN CRVAL1 = 10 CRVAL2 = 20 CRPIX1 = 30 CRPIX2 = 40 CDELT1 = -0.1 CDELT2 = 0.1 CROTA2 = 0. CUNIT1 = deg CUNIT2 = deg """ with warnings.catch_warnings(): warnings.simplefilter('ignore', VerifyWarning) WCS_SIMPLE_CELESTIAL = WCS(Header.fromstring( HEADER_SIMPLE_CELESTIAL, sep='\n')) def test_simple_celestial(): wcs = WCS_SIMPLE_CELESTIAL # Low-level API assert wcs.pixel_n_dim == 2 assert wcs.world_n_dim == 2 assert wcs.array_shape is None assert wcs.pixel_shape is None assert wcs.world_axis_physical_types == ['pos.eq.ra', 'pos.eq.dec'] assert wcs.world_axis_units == ['deg', 'deg'] assert wcs.pixel_axis_names == ['', ''] assert wcs.world_axis_names == ['', ''] assert_equal(wcs.axis_correlation_matrix, True) assert wcs.world_axis_object_components == [('celestial', 0, 'spherical.lon.degree'), ('celestial', 1, 'spherical.lat.degree')] assert wcs.world_axis_object_classes['celestial'][0] is SkyCoord assert wcs.world_axis_object_classes['celestial'][1] == () assert isinstance(wcs.world_axis_object_classes['celestial'][2]['frame'], ICRS) assert wcs.world_axis_object_classes['celestial'][2]['unit'] is u.deg assert_allclose(wcs.pixel_to_world_values(29, 39), (10, 20)) assert_allclose(wcs.array_index_to_world_values(39, 29), (10, 20)) assert_allclose(wcs.world_to_pixel_values(10, 20), (29., 39.)) assert_equal(wcs.world_to_array_index_values(10, 20), (39, 29)) # High-level API coord = wcs.pixel_to_world(29, 39) assert isinstance(coord, SkyCoord) assert isinstance(coord.frame, ICRS) assert_allclose(coord.ra.deg, 10) assert_allclose(coord.dec.deg, 20) coord = wcs.array_index_to_world(39, 29) assert isinstance(coord, SkyCoord) assert isinstance(coord.frame, ICRS) assert_allclose(coord.ra.deg, 10) assert_allclose(coord.dec.deg, 20) coord = SkyCoord(10, 20, unit='deg', frame='icrs') x, y = wcs.world_to_pixel(coord) assert_allclose(x, 29.) assert_allclose(y, 39.) i, j = wcs.world_to_array_index(coord) assert_equal(i, 39) assert_equal(j, 29) # Check that if the coordinates are passed in a different frame things still # work properly coord_galactic = coord.galactic x, y = wcs.world_to_pixel(coord_galactic) assert_allclose(x, 29.) assert_allclose(y, 39.) i, j = wcs.world_to_array_index(coord_galactic) assert_equal(i, 39) assert_equal(j, 29) # Check that we can actually index the array data = np.arange(3600).reshape((60, 60)) coord = SkyCoord(10, 20, unit='deg', frame='icrs') index = wcs.world_to_array_index(coord) assert_equal(data[index], 2369) coord = SkyCoord([10, 12], [20, 22], unit='deg', frame='icrs') index = wcs.world_to_array_index(coord) assert_equal(data[index], [2369, 3550]) ############################################################################### # The following example is a spectral cube with axes in an unusual order ############################################################################### HEADER_SPECTRAL_CUBE = """ WCSAXES = 3 CTYPE1 = GLAT-CAR CTYPE2 = FREQ CTYPE3 = GLON-CAR CNAME1 = Latitude CNAME2 = Frequency CNAME3 = Longitude CRVAL1 = 10 CRVAL2 = 20 CRVAL3 = 25 CRPIX1 = 30 CRPIX2 = 40 CRPIX3 = 45 CDELT1 = -0.1 CDELT2 = 0.5 CDELT3 = 0.1 CUNIT1 = deg CUNIT2 = Hz CUNIT3 = deg """ with warnings.catch_warnings(): warnings.simplefilter('ignore', VerifyWarning) WCS_SPECTRAL_CUBE = WCS(Header.fromstring(HEADER_SPECTRAL_CUBE, sep='\n')) def test_spectral_cube(): # Spectral cube with a weird axis ordering wcs = WCS_SPECTRAL_CUBE # Low-level API assert wcs.pixel_n_dim == 3 assert wcs.world_n_dim == 3 assert wcs.array_shape is None assert wcs.pixel_shape is None assert wcs.world_axis_physical_types == ['pos.galactic.lat', 'em.freq', 'pos.galactic.lon'] assert wcs.world_axis_units == ['deg', 'Hz', 'deg'] assert wcs.pixel_axis_names == ['', '', ''] assert wcs.world_axis_names == ['Latitude', 'Frequency', 'Longitude'] assert_equal(wcs.axis_correlation_matrix, [[True, False, True], [False, True, False], [True, False, True]]) assert len(wcs.world_axis_object_components) == 3 assert wcs.world_axis_object_components[0] == ('celestial', 1, 'spherical.lat.degree') assert wcs.world_axis_object_components[1][:2] == ('spectral', 0) assert wcs.world_axis_object_components[2] == ('celestial', 0, 'spherical.lon.degree') assert wcs.world_axis_object_classes['celestial'][0] is SkyCoord assert wcs.world_axis_object_classes['celestial'][1] == () assert isinstance(wcs.world_axis_object_classes['celestial'][2]['frame'], Galactic) assert wcs.world_axis_object_classes['celestial'][2]['unit'] is u.deg assert wcs.world_axis_object_classes['spectral'][0] is Quantity assert wcs.world_axis_object_classes['spectral'][1] == () assert wcs.world_axis_object_classes['spectral'][2] == {} assert_allclose(wcs.pixel_to_world_values(29, 39, 44), (10, 20, 25)) assert_allclose(wcs.array_index_to_world_values(44, 39, 29), (10, 20, 25)) assert_allclose(wcs.world_to_pixel_values(10, 20, 25), (29., 39., 44.)) assert_equal(wcs.world_to_array_index_values(10, 20, 25), (44, 39, 29)) # High-level API coord, spec = wcs.pixel_to_world(29, 39, 44) assert isinstance(coord, SkyCoord) assert isinstance(coord.frame, Galactic) assert_allclose(coord.l.deg, 25) assert_allclose(coord.b.deg, 10) assert isinstance(spec, SpectralCoord) assert_allclose(spec.to_value(u.Hz), 20) coord, spec = wcs.array_index_to_world(44, 39, 29) assert isinstance(coord, SkyCoord) assert isinstance(coord.frame, Galactic) assert_allclose(coord.l.deg, 25) assert_allclose(coord.b.deg, 10) assert isinstance(spec, SpectralCoord) assert_allclose(spec.to_value(u.Hz), 20) coord = SkyCoord(25, 10, unit='deg', frame='galactic') spec = 20 * u.Hz with pytest.warns(AstropyUserWarning, match='No observer defined on WCS'): x, y, z = wcs.world_to_pixel(coord, spec) assert_allclose(x, 29.) assert_allclose(y, 39.) assert_allclose(z, 44.) # Order of world coordinates shouldn't matter with pytest.warns(AstropyUserWarning, match='No observer defined on WCS'): x, y, z = wcs.world_to_pixel(spec, coord) assert_allclose(x, 29.) assert_allclose(y, 39.) assert_allclose(z, 44.) with pytest.warns(AstropyUserWarning, match='No observer defined on WCS'): i, j, k = wcs.world_to_array_index(coord, spec) assert_equal(i, 44) assert_equal(j, 39) assert_equal(k, 29) # Order of world coordinates shouldn't matter with pytest.warns(AstropyUserWarning, match='No observer defined on WCS'): i, j, k = wcs.world_to_array_index(spec, coord) assert_equal(i, 44) assert_equal(j, 39) assert_equal(k, 29) HEADER_SPECTRAL_CUBE_NONALIGNED = HEADER_SPECTRAL_CUBE.strip() + '\n' + """ PC2_3 = -0.5 PC3_2 = +0.5 """ with warnings.catch_warnings(): warnings.simplefilter('ignore', VerifyWarning) WCS_SPECTRAL_CUBE_NONALIGNED = WCS(Header.fromstring( HEADER_SPECTRAL_CUBE_NONALIGNED, sep='\n')) def test_spectral_cube_nonaligned(): # Make sure that correlation matrix gets adjusted if there are non-identity # CD matrix terms. wcs = WCS_SPECTRAL_CUBE_NONALIGNED assert wcs.world_axis_physical_types == ['pos.galactic.lat', 'em.freq', 'pos.galactic.lon'] assert wcs.world_axis_units == ['deg', 'Hz', 'deg'] assert wcs.pixel_axis_names == ['', '', ''] assert wcs.world_axis_names == ['Latitude', 'Frequency', 'Longitude'] assert_equal(wcs.axis_correlation_matrix, [[True, True, True], [False, True, True], [True, True, True]]) # NOTE: we check world_axis_object_components and world_axis_object_classes # again here because in the past this failed when non-aligned axes were # present, so this serves as a regression test. assert len(wcs.world_axis_object_components) == 3 assert wcs.world_axis_object_components[0] == ('celestial', 1, 'spherical.lat.degree') assert wcs.world_axis_object_components[1][:2] == ('spectral', 0) assert wcs.world_axis_object_components[2] == ('celestial', 0, 'spherical.lon.degree') assert wcs.world_axis_object_classes['celestial'][0] is SkyCoord assert wcs.world_axis_object_classes['celestial'][1] == () assert isinstance(wcs.world_axis_object_classes['celestial'][2]['frame'], Galactic) assert wcs.world_axis_object_classes['celestial'][2]['unit'] is u.deg assert wcs.world_axis_object_classes['spectral'][0] is Quantity assert wcs.world_axis_object_classes['spectral'][1] == () assert wcs.world_axis_object_classes['spectral'][2] == {} ############################################################################### # The following example is from Rots et al (2015), Table 5. It represents a # cube with two spatial dimensions and one time dimension ############################################################################### HEADER_TIME_CUBE = """ SIMPLE = T / Fits standard BITPIX = -32 / Bits per pixel NAXIS = 3 / Number of axes NAXIS1 = 2048 / Axis length NAXIS2 = 2048 / Axis length NAXIS3 = 11 / Axis length DATE = '2008-10-28T14:39:06' / Date FITS file was generated OBJECT = '2008 TC3' / Name of the object observed EXPTIME = 1.0011 / Integration time MJD-OBS = 54746.02749237 / Obs start DATE-OBS= '2008-10-07T00:39:35.3342' / Observing date TELESCOP= 'VISTA' / ESO Telescope Name INSTRUME= 'VIRCAM' / Instrument used. TIMESYS = 'UTC' / From Observatory Time System TREFPOS = 'TOPOCENT' / Topocentric MJDREF = 54746.0 / Time reference point in MJD RADESYS = 'ICRS' / Not equinoctal CTYPE2 = 'RA---ZPN' / Zenithal Polynomial Projection CRVAL2 = 2.01824372640628 / RA at ref pixel CUNIT2 = 'deg' / Angles are degrees always CRPIX2 = 2956.6 / Pixel coordinate at ref point CTYPE1 = 'DEC--ZPN' / Zenithal Polynomial Projection CRVAL1 = 14.8289418840003 / Dec at ref pixel CUNIT1 = 'deg' / Angles are degrees always CRPIX1 = -448.2 / Pixel coordinate at ref point CTYPE3 = 'UTC' / linear time (UTC) CRVAL3 = 2375.341 / Relative time of first frame CUNIT3 = 's' / Time unit CRPIX3 = 1.0 / Pixel coordinate at ref point CTYPE3A = 'TT' / alternative linear time (TT) CRVAL3A = 2440.525 / Relative time of first frame CUNIT3A = 's' / Time unit CRPIX3A = 1.0 / Pixel coordinate at ref point OBSGEO-B= -24.6157 / [deg] Tel geodetic latitude (=North)+ OBSGEO-L= -70.3976 / [deg] Tel geodetic longitude (=East)+ OBSGEO-H= 2530.0000 / [m] Tel height above reference ellipsoid CRDER3 = 0.0819 / random error in timings from fit CSYER3 = 0.0100 / absolute time error PC1_1 = 0.999999971570892 / WCS transform matrix element PC1_2 = 0.000238449608932 / WCS transform matrix element PC2_1 = -0.000621542859395 / WCS transform matrix element PC2_2 = 0.999999806842218 / WCS transform matrix element CDELT1 = -9.48575432499806E-5 / Axis scale at reference point CDELT2 = 9.48683176211164E-5 / Axis scale at reference point CDELT3 = 13.3629 / Axis scale at reference point PV1_1 = 1. / ZPN linear term PV1_3 = 42. / ZPN cubic term """ with warnings.catch_warnings(): warnings.simplefilter('ignore', (VerifyWarning, FITSFixedWarning)) WCS_TIME_CUBE = WCS(Header.fromstring(HEADER_TIME_CUBE, sep='\n')) def test_time_cube(): # Spectral cube with a weird axis ordering wcs = WCS_TIME_CUBE assert wcs.pixel_n_dim == 3 assert wcs.world_n_dim == 3 assert wcs.array_shape == (11, 2048, 2048) assert wcs.pixel_shape == (2048, 2048, 11) assert wcs.world_axis_physical_types == ['pos.eq.dec', 'pos.eq.ra', 'time'] assert wcs.world_axis_units == ['deg', 'deg', 's'] assert wcs.pixel_axis_names == ['', '', ''] assert wcs.world_axis_names == ['', '', ''] assert_equal(wcs.axis_correlation_matrix, [[True, True, False], [True, True, False], [False, False, True]]) components = wcs.world_axis_object_components assert components[0] == ('celestial', 1, 'spherical.lat.degree') assert components[1] == ('celestial', 0, 'spherical.lon.degree') assert components[2][:2] == ('time', 0) assert callable(components[2][2]) assert wcs.world_axis_object_classes['celestial'][0] is SkyCoord assert wcs.world_axis_object_classes['celestial'][1] == () assert isinstance(wcs.world_axis_object_classes['celestial'][2]['frame'], ICRS) assert wcs.world_axis_object_classes['celestial'][2]['unit'] is u.deg assert wcs.world_axis_object_classes['time'][0] is Time assert wcs.world_axis_object_classes['time'][1] == () assert wcs.world_axis_object_classes['time'][2] == {} assert callable(wcs.world_axis_object_classes['time'][3]) assert_allclose(wcs.pixel_to_world_values(-449.2, 2955.6, 0), (14.8289418840003, 2.01824372640628, 2375.341)) assert_allclose(wcs.array_index_to_world_values(0, 2955.6, -449.2), (14.8289418840003, 2.01824372640628, 2375.341)) assert_allclose(wcs.world_to_pixel_values(14.8289418840003, 2.01824372640628, 2375.341), (-449.2, 2955.6, 0)) assert_equal(wcs.world_to_array_index_values(14.8289418840003, 2.01824372640628, 2375.341), (0, 2956, -449)) # High-level API coord, time = wcs.pixel_to_world(29, 39, 44) assert isinstance(coord, SkyCoord) assert isinstance(coord.frame, ICRS) assert_allclose(coord.ra.deg, 1.7323356692202325) assert_allclose(coord.dec.deg, 14.783516054817797) assert isinstance(time, Time) assert_allclose(time.mjd, 54746.03429755324) coord, time = wcs.array_index_to_world(44, 39, 29) assert isinstance(coord, SkyCoord) assert isinstance(coord.frame, ICRS) assert_allclose(coord.ra.deg, 1.7323356692202325) assert_allclose(coord.dec.deg, 14.783516054817797) assert isinstance(time, Time) assert_allclose(time.mjd, 54746.03429755324) x, y, z = wcs.world_to_pixel(coord, time) assert_allclose(x, 29.) assert_allclose(y, 39.) assert_allclose(z, 44.) # Order of world coordinates shouldn't matter x, y, z = wcs.world_to_pixel(time, coord) assert_allclose(x, 29.) assert_allclose(y, 39.) assert_allclose(z, 44.) i, j, k = wcs.world_to_array_index(coord, time) assert_equal(i, 44) assert_equal(j, 39) assert_equal(k, 29) # Order of world coordinates shouldn't matter i, j, k = wcs.world_to_array_index(time, coord) assert_equal(i, 44) assert_equal(j, 39) assert_equal(k, 29) ############################################################################### # The following tests are to make sure that Time objects are constructed # correctly for a variety of combinations of WCS keywords ############################################################################### HEADER_TIME_1D = """ SIMPLE = T BITPIX = -32 NAXIS = 1 NAXIS1 = 2048 TIMESYS = 'UTC' TREFPOS = 'TOPOCENT' MJDREF = 50002.6 CTYPE1 = 'UTC' CRVAL1 = 5 CUNIT1 = 's' CRPIX1 = 1.0 CDELT1 = 2 OBSGEO-L= -20 OBSGEO-B= -70 OBSGEO-H= 2530 """ if Version(wcsver) >= Version('7.1'): HEADER_TIME_1D += "DATEREF = '1995-10-12T14:24:00'\n" @pytest.fixture def header_time_1d(): return Header.fromstring(HEADER_TIME_1D, sep='\n') def assert_time_at(header, position, jd1, jd2, scale, format): with warnings.catch_warnings(): warnings.simplefilter('ignore', FITSFixedWarning) wcs = WCS(header) time = wcs.pixel_to_world(position) assert_allclose(time.jd1, jd1, rtol=1e-10) assert_allclose(time.jd2, jd2, rtol=1e-10) assert time.format == format assert time.scale == scale @pytest.mark.parametrize('scale', ('tai', 'tcb', 'tcg', 'tdb', 'tt', 'ut1', 'utc', 'local')) def test_time_1d_values(header_time_1d, scale): # Check that Time objects are instantiated with the correct values, # scales, and formats. header_time_1d['CTYPE1'] = scale.upper() assert_time_at(header_time_1d, 1, 2450003, 0.1 + 7 / 3600 / 24, scale, 'mjd') def test_time_1d_values_gps(header_time_1d): # Special treatment for GPS scale header_time_1d['CTYPE1'] = 'GPS' assert_time_at(header_time_1d, 1, 2450003, 0.1 + (7 + 19) / 3600 / 24, 'tai', 'mjd') def test_time_1d_values_deprecated(header_time_1d): # Deprecated (in FITS) scales header_time_1d['CTYPE1'] = 'TDT' assert_time_at(header_time_1d, 1, 2450003, 0.1 + 7 / 3600 / 24, 'tt', 'mjd') header_time_1d['CTYPE1'] = 'IAT' assert_time_at(header_time_1d, 1, 2450003, 0.1 + 7 / 3600 / 24, 'tai', 'mjd') header_time_1d['CTYPE1'] = 'GMT' assert_time_at(header_time_1d, 1, 2450003, 0.1 + 7 / 3600 / 24, 'utc', 'mjd') header_time_1d['CTYPE1'] = 'ET' assert_time_at(header_time_1d, 1, 2450003, 0.1 + 7 / 3600 / 24, 'tt', 'mjd') def test_time_1d_values_time(header_time_1d): header_time_1d['CTYPE1'] = 'TIME' assert_time_at(header_time_1d, 1, 2450003, 0.1 + 7 / 3600 / 24, 'utc', 'mjd') header_time_1d['TIMESYS'] = 'TAI' assert_time_at(header_time_1d, 1, 2450003, 0.1 + 7 / 3600 / 24, 'tai', 'mjd') @pytest.mark.remote_data @pytest.mark.parametrize('scale', ('tai', 'tcb', 'tcg', 'tdb', 'tt', 'ut1', 'utc')) def test_time_1d_roundtrip(header_time_1d, scale): # Check that coordinates round-trip pixel_in = np.arange(3, 10) header_time_1d['CTYPE1'] = scale.upper() with warnings.catch_warnings(): warnings.simplefilter('ignore', FITSFixedWarning) wcs = WCS(header_time_1d) # Simple test time = wcs.pixel_to_world(pixel_in) pixel_out = wcs.world_to_pixel(time) assert_allclose(pixel_in, pixel_out) # Test with an intermediate change to a different scale/format time = wcs.pixel_to_world(pixel_in).tdb time.format = 'isot' pixel_out = wcs.world_to_pixel(time) assert_allclose(pixel_in, pixel_out) def test_time_1d_high_precision(header_time_1d): # Case where the MJDREF is split into two for high precision del header_time_1d['MJDREF'] header_time_1d['MJDREFI'] = 52000. header_time_1d['MJDREFF'] = 1e-11 with warnings.catch_warnings(): warnings.simplefilter('ignore', FITSFixedWarning) wcs = WCS(header_time_1d) time = wcs.pixel_to_world(10) # Here we have to use a very small rtol to really test that MJDREFF is # taken into account assert_allclose(time.jd1, 2452001.0, rtol=1e-12) assert_allclose(time.jd2, -0.5 + 25 / 3600 / 24 + 1e-11, rtol=1e-13) def test_time_1d_location_geodetic(header_time_1d): # Make sure that the location is correctly returned (geodetic case) with warnings.catch_warnings(): warnings.simplefilter('ignore', FITSFixedWarning) wcs = WCS(header_time_1d) time = wcs.pixel_to_world(10) lon, lat, alt = time.location.to_geodetic() # FIXME: alt won't work for now because ERFA doesn't implement the IAU 1976 # ellipsoid (https://github.com/astropy/astropy/issues/9420) assert_allclose(lon.degree, -20) assert_allclose(lat.degree, -70) # assert_allclose(alt.to_value(u.m), 2530.) @pytest.fixture def header_time_1d_no_obs(): header = Header.fromstring(HEADER_TIME_1D, sep='\n') del header['OBSGEO-L'] del header['OBSGEO-B'] del header['OBSGEO-H'] return header def test_time_1d_location_geocentric(header_time_1d_no_obs): # Make sure that the location is correctly returned (geocentric case) header = header_time_1d_no_obs header['OBSGEO-X'] = 10 header['OBSGEO-Y'] = -20 header['OBSGEO-Z'] = 30 with warnings.catch_warnings(): warnings.simplefilter('ignore', FITSFixedWarning) wcs = WCS(header) time = wcs.pixel_to_world(10) x, y, z = time.location.to_geocentric() assert_allclose(x.to_value(u.m), 10) assert_allclose(y.to_value(u.m), -20) assert_allclose(z.to_value(u.m), 30) def test_time_1d_location_geocenter(header_time_1d_no_obs): header_time_1d_no_obs['TREFPOS'] = 'GEOCENTER' wcs = WCS(header_time_1d_no_obs) time = wcs.pixel_to_world(10) x, y, z = time.location.to_geocentric() assert_allclose(x.to_value(u.m), 0) assert_allclose(y.to_value(u.m), 0) assert_allclose(z.to_value(u.m), 0) def test_time_1d_location_missing(header_time_1d_no_obs): # Check what happens when no location is present wcs = WCS(header_time_1d_no_obs) with pytest.warns(UserWarning, match='Missing or incomplete observer location ' 'information, setting location in Time to None'): time = wcs.pixel_to_world(10) assert time.location is None def test_time_1d_location_incomplete(header_time_1d_no_obs): # Check what happens when location information is incomplete header_time_1d_no_obs['OBSGEO-L'] = 10. with warnings.catch_warnings(): warnings.simplefilter('ignore', FITSFixedWarning) wcs = WCS(header_time_1d_no_obs) with pytest.warns(UserWarning, match='Missing or incomplete observer location ' 'information, setting location in Time to None'): time = wcs.pixel_to_world(10) assert time.location is None def test_time_1d_location_unsupported(header_time_1d_no_obs): # Check what happens when TREFPOS is unsupported header_time_1d_no_obs['TREFPOS'] = 'BARYCENTER' wcs = WCS(header_time_1d_no_obs) with pytest.warns(UserWarning, match="Observation location 'barycenter' is not " "supported, setting location in Time to None"): time = wcs.pixel_to_world(10) assert time.location is None def test_time_1d_unsupported_ctype(header_time_1d_no_obs): # For cases that we don't support yet, e.g. UT(...), use Time and drop sub-scale # Case where the MJDREF is split into two for high precision header_time_1d_no_obs['CTYPE1'] = 'UT(WWV)' wcs = WCS(header_time_1d_no_obs) with pytest.warns(UserWarning, match="Dropping unsupported sub-scale WWV from scale UT"): time = wcs.pixel_to_world(10) assert isinstance(time, Time) ############################################################################### # Extra corner cases ############################################################################### def test_unrecognized_unit(): # TODO: Determine whether the following behavior is desirable wcs = WCS(naxis=1) with pytest.warns(UnitsWarning): wcs.wcs.cunit = ['bananas // sekonds'] assert wcs.world_axis_units == ['bananas // sekonds'] def test_distortion_correlations(): filename = get_pkg_data_filename('../../tests/data/sip.fits') with pytest.warns(FITSFixedWarning): w = WCS(filename) assert_equal(w.axis_correlation_matrix, True) # Changing PC to an identity matrix doesn't change anything since # distortions are still present. w.wcs.pc = [[1, 0], [0, 1]] assert_equal(w.axis_correlation_matrix, True) # Nor does changing the name of the axes to make them non-celestial w.wcs.ctype = ['X', 'Y'] assert_equal(w.axis_correlation_matrix, True) # However once we turn off the distortions the matrix changes w.sip = None assert_equal(w.axis_correlation_matrix, [[True, False], [False, True]]) # If we go back to celestial coordinates then the matrix is all True again w.wcs.ctype = ['RA---TAN', 'DEC--TAN'] assert_equal(w.axis_correlation_matrix, True) # Or if we change to X/Y but have a non-identity PC w.wcs.pc = [[0.9, -0.1], [0.1, 0.9]] w.wcs.ctype = ['X', 'Y'] assert_equal(w.axis_correlation_matrix, True) def test_custom_ctype_to_ucd_mappings(): wcs = WCS(naxis=1) wcs.wcs.ctype = ['SPAM'] assert wcs.world_axis_physical_types == [None] # Check simple behavior with custom_ctype_to_ucd_mapping({'APPLE': 'food.fruit'}): assert wcs.world_axis_physical_types == [None] with custom_ctype_to_ucd_mapping({'APPLE': 'food.fruit', 'SPAM': 'food.spam'}): assert wcs.world_axis_physical_types == ['food.spam'] # Check nesting with custom_ctype_to_ucd_mapping({'SPAM': 'food.spam'}): with custom_ctype_to_ucd_mapping({'APPLE': 'food.fruit'}): assert wcs.world_axis_physical_types == ['food.spam'] with custom_ctype_to_ucd_mapping({'APPLE': 'food.fruit'}): with custom_ctype_to_ucd_mapping({'SPAM': 'food.spam'}): assert wcs.world_axis_physical_types == ['food.spam'] # Check priority in nesting with custom_ctype_to_ucd_mapping({'SPAM': 'notfood'}): with custom_ctype_to_ucd_mapping({'SPAM': 'food.spam'}): assert wcs.world_axis_physical_types == ['food.spam'] with custom_ctype_to_ucd_mapping({'SPAM': 'food.spam'}): with custom_ctype_to_ucd_mapping({'SPAM': 'notfood'}): assert wcs.world_axis_physical_types == ['notfood'] def test_caching_components_and_classes(): # Make sure that when we change the WCS object, the classes and components # are updated (we use a cache internally, so we need to make sure the cache # is invalidated if needed) wcs = WCS_SIMPLE_CELESTIAL.deepcopy() assert wcs.world_axis_object_components == [('celestial', 0, 'spherical.lon.degree'), ('celestial', 1, 'spherical.lat.degree')] assert wcs.world_axis_object_classes['celestial'][0] is SkyCoord assert wcs.world_axis_object_classes['celestial'][1] == () assert isinstance(wcs.world_axis_object_classes['celestial'][2]['frame'], ICRS) assert wcs.world_axis_object_classes['celestial'][2]['unit'] is u.deg wcs.wcs.radesys = 'FK5' frame = wcs.world_axis_object_classes['celestial'][2]['frame'] assert isinstance(frame, FK5) assert frame.equinox.jyear == 2000. wcs.wcs.equinox = 2010 frame = wcs.world_axis_object_classes['celestial'][2]['frame'] assert isinstance(frame, FK5) assert frame.equinox.jyear == 2010. def test_sub_wcsapi_attributes(): # Regression test for a bug that caused some of the WCS attributes to be # incorrect when using WCS.sub or WCS.celestial (which is an alias for sub # with lon/lat types). wcs = WCS_SPECTRAL_CUBE.deepcopy() wcs.pixel_shape = (30, 40, 50) wcs.pixel_bounds = [(-1, 11), (-2, 18), (5, 15)] # Use celestial shortcut wcs_sub1 = wcs.celestial assert wcs_sub1.pixel_n_dim == 2 assert wcs_sub1.world_n_dim == 2 assert wcs_sub1.array_shape == (50, 30) assert wcs_sub1.pixel_shape == (30, 50) assert wcs_sub1.pixel_bounds == [(-1, 11), (5, 15)] assert wcs_sub1.world_axis_physical_types == ['pos.galactic.lat', 'pos.galactic.lon'] assert wcs_sub1.world_axis_units == ['deg', 'deg'] assert wcs_sub1.world_axis_names == ['Latitude', 'Longitude'] # Try adding axes wcs_sub2 = wcs.sub([0, 2, 0]) assert wcs_sub2.pixel_n_dim == 3 assert wcs_sub2.world_n_dim == 3 assert wcs_sub2.array_shape == (None, 40, None) assert wcs_sub2.pixel_shape == (None, 40, None) assert wcs_sub2.pixel_bounds == [None, (-2, 18), None] assert wcs_sub2.world_axis_physical_types == [None, 'em.freq', None] assert wcs_sub2.world_axis_units == ['', 'Hz', ''] assert wcs_sub2.world_axis_names == ['', 'Frequency', ''] # Use strings wcs_sub3 = wcs.sub(['longitude', 'latitude']) assert wcs_sub3.pixel_n_dim == 2 assert wcs_sub3.world_n_dim == 2 assert wcs_sub3.array_shape == (30, 50) assert wcs_sub3.pixel_shape == (50, 30) assert wcs_sub3.pixel_bounds == [(5, 15), (-1, 11)] assert wcs_sub3.world_axis_physical_types == ['pos.galactic.lon', 'pos.galactic.lat'] assert wcs_sub3.world_axis_units == ['deg', 'deg'] assert wcs_sub3.world_axis_names == ['Longitude', 'Latitude'] # Now try without CNAME set wcs.wcs.cname = [''] * wcs.wcs.naxis wcs_sub4 = wcs.sub(['longitude', 'latitude']) assert wcs_sub4.pixel_n_dim == 2 assert wcs_sub4.world_n_dim == 2 assert wcs_sub4.array_shape == (30, 50) assert wcs_sub4.pixel_shape == (50, 30) assert wcs_sub4.pixel_bounds == [(5, 15), (-1, 11)] assert wcs_sub4.world_axis_physical_types == ['pos.galactic.lon', 'pos.galactic.lat'] assert wcs_sub4.world_axis_units == ['deg', 'deg'] assert wcs_sub4.world_axis_names == ['', ''] HEADER_POLARIZED = """ CTYPE1 = 'HPLT-TAN' CTYPE2 = 'HPLN-TAN' CTYPE3 = 'STOKES' """ @pytest.fixture def header_polarized(): return Header.fromstring(HEADER_POLARIZED, sep='\n') def test_phys_type_polarization(header_polarized): w = WCS(header_polarized) assert w.world_axis_physical_types[2] == 'phys.polarization.stokes' ############################################################################### # Spectral transformations ############################################################################### HEADER_SPECTRAL_FRAMES = """ BUNIT = 'Jy/beam' EQUINOX = 2.000000000E+03 CTYPE1 = 'RA---SIN' CRVAL1 = 2.60108333333E+02 CDELT1 = -2.777777845E-04 CRPIX1 = 1.0 CUNIT1 = 'deg' CTYPE2 = 'DEC--SIN' CRVAL2 = -9.75000000000E-01 CDELT2 = 2.777777845E-04 CRPIX2 = 1.0 CUNIT2 = 'deg' CTYPE3 = 'FREQ' CRVAL3 = 1.37835117405E+09 CDELT3 = 9.765625000E+04 CRPIX3 = 32.0 CUNIT3 = 'Hz' SPECSYS = 'TOPOCENT' RESTFRQ = 1.420405752E+09 / [Hz] RADESYS = 'FK5' """ @pytest.fixture def header_spectral_frames(): return Header.fromstring(HEADER_SPECTRAL_FRAMES, sep='\n') def test_spectralcoord_frame(header_spectral_frames): # This is a test to check the numerical results of transformations between # different velocity frames. We simply make sure that the returned # SpectralCoords are in the right frame but don't check the transformations # since this is already done in test_spectralcoord_accuracy # in astropy.coordinates. with iers.conf.set_temp('auto_download', False): obstime = Time(f"2009-05-04T04:44:23", scale='utc') header = header_spectral_frames.copy() header['MJD-OBS'] = obstime.mjd header['CRVAL1'] = 16.33211 header['CRVAL2'] = -34.2221 header['OBSGEO-L'] = 144.2 header['OBSGEO-B'] = -20.2 header['OBSGEO-H'] = 0. # We start off with a WCS defined in topocentric frequency with pytest.warns(FITSFixedWarning): wcs_topo = WCS(header) # We convert a single pixel coordinate to world coordinates and keep only # the second high level object - a SpectralCoord: sc_topo = wcs_topo.pixel_to_world(0, 0, 31)[1] # We check that this is in topocentric frame with zero velocities assert isinstance(sc_topo, SpectralCoord) assert isinstance(sc_topo.observer, ITRS) assert sc_topo.observer.obstime.isot == obstime.isot assert_equal(sc_topo.observer.data.differentials['s'].d_xyz.value, 0) observatory = EarthLocation.from_geodetic(144.2, -20.2).get_itrs(obstime=obstime).transform_to(ICRS()) assert observatory.separation_3d(sc_topo.observer.transform_to(ICRS())) < 1 * u.km for specsys, expected_frame in VELOCITY_FRAMES.items(): header['SPECSYS'] = specsys with pytest.warns(FITSFixedWarning): wcs = WCS(header) sc = wcs.pixel_to_world(0, 0, 31)[1] # Now transform to the expected velocity frame, which should leave # the spectral coordinate unchanged sc_check = sc.with_observer_stationary_relative_to(expected_frame) assert_quantity_allclose(sc.quantity, sc_check.quantity) @pytest.mark.parametrize(('ctype3', 'observer'), product(['ZOPT', 'BETA', 'VELO', 'VRAD', 'VOPT'], [False, True])) def test_different_ctypes(header_spectral_frames, ctype3, observer): header = header_spectral_frames.copy() header['CTYPE3'] = ctype3 header['CRVAL3'] = 0.1 header['CDELT3'] = 0.001 if ctype3[0] == 'V': header['CUNIT3'] = 'm s-1' else: header['CUNIT3'] = '' header['RESTWAV'] = 1.420405752E+09 header['MJD-OBS'] = 55197 if observer: header['OBSGEO-L'] = 144.2 header['OBSGEO-B'] = -20.2 header['OBSGEO-H'] = 0. header['SPECSYS'] = 'BARYCENT' with warnings.catch_warnings(): warnings.simplefilter('ignore', FITSFixedWarning) wcs = WCS(header) skycoord, spectralcoord = wcs.pixel_to_world(0, 0, 31) assert isinstance(spectralcoord, SpectralCoord) if observer: pix = wcs.world_to_pixel(skycoord, spectralcoord) else: with pytest.warns(AstropyUserWarning, match='No observer defined on WCS'): pix = wcs.world_to_pixel(skycoord, spectralcoord) assert_allclose(pix, [0, 0, 31], rtol=1e-6) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/wcsapi/tests/test_high_level_api.py0000644000175100001710000001155600000000000023552 0ustar00vstsdockerimport numpy as np from numpy.testing import assert_allclose from astropy.units import Quantity from astropy.coordinates import SkyCoord from astropy.wcs.wcsapi.low_level_api import BaseLowLevelWCS from astropy.wcs.wcsapi.high_level_api import HighLevelWCSMixin, high_level_objects_to_values, values_to_high_level_objects class DoubleLowLevelWCS(BaseLowLevelWCS): """ Basic dummy transformation that doubles values. """ def pixel_to_world_values(self, *pixel_arrays): return [np.asarray(pix) * 2 for pix in pixel_arrays] def world_to_pixel_values(self, *world_arrays): return [np.asarray(world) / 2 for world in world_arrays] class SimpleDuplicateWCS(DoubleLowLevelWCS, HighLevelWCSMixin): """ This example WCS has two of the world coordinates that use the same class, which triggers a different path in the high level WCS code. """ @property def pixel_n_dim(self): return 2 @property def world_n_dim(self): return 2 @property def world_axis_physical_types(self): return ['pos.eq.ra', 'pos.eq.dec'] @property def world_axis_units(self): return ['deg', 'deg'] @property def world_axis_object_components(self): return [('test1', 0, 'value'), ('test2', 0, 'value')] @property def world_axis_object_classes(self): return {'test1': (Quantity, (), {'unit': 'deg'}), 'test2': (Quantity, (), {'unit': 'deg'})} def test_simple_duplicate(): # Make sure that things work properly when the low-level WCS uses the same # class for two of the coordinates. wcs = SimpleDuplicateWCS() q1, q2 = wcs.pixel_to_world(1, 2) assert isinstance(q1, Quantity) assert isinstance(q2, Quantity) x, y = wcs.world_to_pixel(q1, q2) assert_allclose(x, 1) assert_allclose(y, 2) class SkyCoordDuplicateWCS(DoubleLowLevelWCS, HighLevelWCSMixin): """ This example WCS returns two SkyCoord objects which, which triggers a different path in the high level WCS code. """ @property def pixel_n_dim(self): return 4 @property def world_n_dim(self): return 4 @property def world_axis_physical_types(self): return ['pos.eq.ra', 'pos.eq.dec', 'pos.galactic.lon', 'pos.galactic.lat'] @property def world_axis_units(self): return ['deg', 'deg', 'deg', 'deg'] @property def world_axis_object_components(self): # Deliberately use 'ra'/'dec' here to make sure that string argument # names work properly. return [('test1', 'ra', 'spherical.lon.degree'), ('test1', 'dec', 'spherical.lat.degree'), ('test2', 0, 'spherical.lon.degree'), ('test2', 1, 'spherical.lat.degree')] @property def world_axis_object_classes(self): return {'test1': (SkyCoord, (), {'unit': 'deg'}), 'test2': (SkyCoord, (), {'unit': 'deg', 'frame': 'galactic'})} def test_skycoord_duplicate(): # Make sure that things work properly when the low-level WCS uses the same # class, and specifically a SkyCoord for two of the coordinates. wcs = SkyCoordDuplicateWCS() c1, c2 = wcs.pixel_to_world(1, 2, 3, 4) assert isinstance(c1, SkyCoord) assert isinstance(c2, SkyCoord) x, y, z, a = wcs.world_to_pixel(c1, c2) assert_allclose(x, 1) assert_allclose(y, 2) assert_allclose(z, 3) assert_allclose(a, 4) class SerializedWCS(DoubleLowLevelWCS, HighLevelWCSMixin): """ WCS with serialized classes """ @property def serialized_classes(self): return True @property def pixel_n_dim(self): return 2 @property def world_n_dim(self): return 2 @property def world_axis_physical_types(self): return ['pos.eq.ra', 'pos.eq.dec'] @property def world_axis_units(self): return ['deg', 'deg'] @property def world_axis_object_components(self): return [('test', 0, 'value')] @property def world_axis_object_classes(self): return {'test': ('astropy.units.Quantity', (), {'unit': ('astropy.units.Unit', ('deg',), {})})} def test_serialized_classes(): wcs = SerializedWCS() q = wcs.pixel_to_world(1) assert isinstance(q, Quantity) x = wcs.world_to_pixel(q) assert_allclose(x, 1) def test_objects_to_values(): wcs = SkyCoordDuplicateWCS() c1, c2 = wcs.pixel_to_world(1, 2, 3, 4) values = high_level_objects_to_values(c1, c2, low_level_wcs=wcs) assert np.allclose(values, [2, 4, 6, 8]) def test_values_to_objects(): wcs = SkyCoordDuplicateWCS() c1, c2 = wcs.pixel_to_world(1, 2, 3, 4) c1_out, c2_out = values_to_high_level_objects(*[2,4,6,8], low_level_wcs=wcs) assert c1.ra == c1_out.ra assert c2.l == c2_out.l assert c1.dec == c1_out.dec assert c2.b == c2_out.b ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/wcsapi/tests/test_high_level_wcs_wrapper.py0000644000175100001710000000405300000000000025327 0ustar00vstsdockerimport pytest import numpy as np from numpy.testing import assert_allclose from astropy.coordinates import SkyCoord from astropy.wcs.wcsapi.low_level_api import BaseLowLevelWCS from astropy.wcs.wcsapi.high_level_wcs_wrapper import HighLevelWCSWrapper class CustomLowLevelWCS(BaseLowLevelWCS): @property def pixel_n_dim(self): return 2 @property def world_n_dim(self): return 2 @property def world_axis_physical_types(self): return ['pos.eq.ra', 'pos.eq.dec'] @property def world_axis_units(self): return ['deg', 'deg'] def pixel_to_world_values(self, *pixel_arrays): return [np.asarray(pix) * 2 for pix in pixel_arrays] def world_to_pixel_values(self, *world_arrays): return [np.asarray(world) / 2 for world in world_arrays] @property def world_axis_object_components(self): return [('test', 0, 'spherical.lon.degree'), ('test', 1, 'spherical.lat.degree')] @property def world_axis_object_classes(self): return {'test': (SkyCoord, (), {'unit': 'deg'})} def test_wrapper(): wcs = CustomLowLevelWCS() wrapper = HighLevelWCSWrapper(wcs) coord = wrapper.pixel_to_world(1, 2) assert isinstance(coord, SkyCoord) assert coord.isscalar x, y = wrapper.world_to_pixel(coord) assert_allclose(x, 1) assert_allclose(y, 2) assert wrapper.low_level_wcs is wcs assert wrapper.pixel_n_dim == 2 assert wrapper.world_n_dim == 2 assert wrapper.world_axis_physical_types == ['pos.eq.ra', 'pos.eq.dec'] assert wrapper.world_axis_units == ['deg', 'deg'] assert wrapper.array_shape is None assert wrapper.pixel_bounds is None assert np.all(wrapper.axis_correlation_matrix) def test_wrapper_invalid(): class InvalidCustomLowLevelWCS(CustomLowLevelWCS): @property def world_axis_object_classes(self): return {} wcs = InvalidCustomLowLevelWCS() wrapper = HighLevelWCSWrapper(wcs) with pytest.raises(KeyError): wrapper.pixel_to_world(1, 2) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/wcsapi/tests/test_low_level_api.py0000644000175100001710000000130500000000000023423 0ustar00vstsdockerfrom pytest import raises from astropy.wcs.wcsapi.low_level_api import validate_physical_types def test_validate_physical_types(): # Check valid cases validate_physical_types(['pos.eq.ra', 'pos.eq.ra']) validate_physical_types(['spect.dopplerVeloc.radio', 'custom:spam']) validate_physical_types(['time', None]) # Make sure validation is case sensitive with raises(ValueError, match=r"'Pos\.eq\.dec' is not a valid IOVA UCD1\+ physical type"): validate_physical_types(['pos.eq.ra', 'Pos.eq.dec']) # Make sure nonsense types are picked up with raises(ValueError, match=r"'spam' is not a valid IOVA UCD1\+ physical type"): validate_physical_types(['spam']) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/wcsapi/tests/test_utils.py0000644000175100001710000000301300000000000021740 0ustar00vstsdockerimport numpy as np from numpy.testing import assert_allclose import pytest from pytest import raises from astropy import units as u from astropy.wcs import WCS from astropy.tests.helper import assert_quantity_allclose from astropy.wcs.wcsapi.utils import deserialize_class, wcs_info_str def test_construct(): result = deserialize_class(('astropy.units.Quantity', (10,), {'unit': 'deg'})) assert_quantity_allclose(result, 10 * u.deg) def test_noconstruct(): result = deserialize_class(('astropy.units.Quantity', (), {'unit': 'deg'}), construct=False) assert result == (u.Quantity, (), {'unit': 'deg'}) def test_invalid(): with raises(ValueError) as exc: deserialize_class(('astropy.units.Quantity', (), {'unit': 'deg'}, ())) assert exc.value.args[0] == 'Expected a tuple of three values' DEFAULT_1D_STR = """ WCS Transformation This transformation has 1 pixel and 1 world dimensions Array shape (Numpy order): None Pixel Dim Axis Name Data size Bounds 0 None None None World Dim Axis Name Physical Type Units 0 None None unknown Correlation between pixel and world axes: Pixel Dim World Dim 0 0 yes """ def test_wcs_info_str(): # The tests in test_sliced_low_level_wcs.py exercise wcs_info_str # extensively. This test is to ensure that the function exists and the # API of the function works as expected. wcs_empty = WCS(naxis=1) assert wcs_info_str(wcs_empty).strip() == DEFAULT_1D_STR.strip() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/wcsapi/utils.py0000644000175100001710000001053600000000000017547 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst import importlib import numpy as np __all__ = ['deserialize_class', 'wcs_info_str'] def deserialize_class(tpl, construct=True): """ Deserialize classes recursively. """ if not isinstance(tpl, tuple) or len(tpl) != 3: raise ValueError("Expected a tuple of three values") module, klass = tpl[0].rsplit('.', 1) module = importlib.import_module(module) klass = getattr(module, klass) args = tuple([deserialize_class(arg) if isinstance(arg, tuple) else arg for arg in tpl[1]]) kwargs = dict((key, deserialize_class(val)) if isinstance(val, tuple) else (key, val) for (key, val) in tpl[2].items()) if construct: return klass(*args, **kwargs) else: return klass, args, kwargs def wcs_info_str(wcs): # Overall header s = f'{wcs.__class__.__name__} Transformation\n\n' s += ('This transformation has {} pixel and {} world dimensions\n\n' .format(wcs.pixel_n_dim, wcs.world_n_dim)) s += f'Array shape (Numpy order): {wcs.array_shape}\n\n' # Pixel dimensions table array_shape = wcs.array_shape or (0,) pixel_shape = wcs.pixel_shape or (None,) * wcs.pixel_n_dim # Find largest between header size and value length pixel_dim_width = max(9, len(str(wcs.pixel_n_dim))) pixel_nam_width = max(9, max(len(x) for x in wcs.pixel_axis_names)) pixel_siz_width = max(9, len(str(max(array_shape)))) s += (('{0:' + str(pixel_dim_width) + 's}').format('Pixel Dim') + ' ' + ('{0:' + str(pixel_nam_width) + 's}').format('Axis Name') + ' ' + ('{0:' + str(pixel_siz_width) + 's}').format('Data size') + ' ' + 'Bounds\n') for ipix in range(wcs.pixel_n_dim): s += (('{0:' + str(pixel_dim_width) + 'g}').format(ipix) + ' ' + ('{0:' + str(pixel_nam_width) + 's}').format(wcs.pixel_axis_names[ipix] or 'None') + ' ' + (" " * 5 + str(None) if pixel_shape[ipix] is None else ('{0:' + str(pixel_siz_width) + 'g}').format(pixel_shape[ipix])) + ' ' + '{:s}'.format(str(None if wcs.pixel_bounds is None else wcs.pixel_bounds[ipix]) + '\n')) s += '\n' # World dimensions table # Find largest between header size and value length world_dim_width = max(9, len(str(wcs.world_n_dim))) world_nam_width = max(9, max(len(x) if x is not None else 0 for x in wcs.world_axis_names)) world_typ_width = max(13, max(len(x) if x is not None else 0 for x in wcs.world_axis_physical_types)) s += (('{0:' + str(world_dim_width) + 's}').format('World Dim') + ' ' + ('{0:' + str(world_nam_width) + 's}').format('Axis Name') + ' ' + ('{0:' + str(world_typ_width) + 's}').format('Physical Type') + ' ' + 'Units\n') for iwrl in range(wcs.world_n_dim): name = wcs.world_axis_names[iwrl] or 'None' typ = wcs.world_axis_physical_types[iwrl] or 'None' unit = wcs.world_axis_units[iwrl] or 'unknown' s += (('{0:' + str(world_dim_width) + 'd}').format(iwrl) + ' ' + ('{0:' + str(world_nam_width) + 's}').format(name) + ' ' + ('{0:' + str(world_typ_width) + 's}').format(typ) + ' ' + '{:s}'.format(unit + '\n')) s += '\n' # Axis correlation matrix pixel_dim_width = max(3, len(str(wcs.world_n_dim))) s += 'Correlation between pixel and world axes:\n\n' s += (' ' * world_dim_width + ' ' + ('{0:^' + str(wcs.pixel_n_dim * 5 - 2) + 's}').format('Pixel Dim') + '\n') s += (('{0:' + str(world_dim_width) + 's}').format('World Dim') + ''.join([' ' + ('{0:' + str(pixel_dim_width) + 'd}').format(ipix) for ipix in range(wcs.pixel_n_dim)]) + '\n') matrix = wcs.axis_correlation_matrix matrix_str = np.empty(matrix.shape, dtype='U3') matrix_str[matrix] = 'yes' matrix_str[~matrix] = 'no' for iwrl in range(wcs.world_n_dim): s += (('{0:' + str(world_dim_width) + 'd}').format(iwrl) + ''.join([' ' + ('{0:>' + str(pixel_dim_width) + 's}').format(matrix_str[iwrl, ipix]) for ipix in range(wcs.pixel_n_dim)]) + '\n') # Make sure we get rid of the extra whitespace at the end of some lines return '\n'.join([l.rstrip() for l in s.splitlines()]) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2432582 astropy-5.0.2/astropy/wcs/wcsapi/wrappers/0000755000175100001710000000000000000000000017673 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/wcsapi/wrappers/__init__.py0000644000175100001710000000010300000000000021776 0ustar00vstsdockerfrom .sliced_wcs import * # noqa from .base import BaseWCSWrapper ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/wcsapi/wrappers/base.py0000644000175100001710000000373500000000000021167 0ustar00vstsdockerimport abc from astropy.wcs.wcsapi import BaseLowLevelWCS, wcs_info_str class BaseWCSWrapper(BaseLowLevelWCS, metaclass=abc.ABCMeta): """ A base wrapper class for things that modify Low Level WCSes. This wrapper implements a transparent wrapper to many of the properties, with the idea that not all of them would need to be overridden in your wrapper, but some probably will. Parameters ---------- wcs : `astropy.wcs.wcsapi.BaseLowLevelWCS` The WCS object to wrap """ def __init__(self, wcs, *args, **kwargs): self._wcs = wcs @property def pixel_n_dim(self): return self._wcs.pixel_n_dim @property def world_n_dim(self): return self._wcs.world_n_dim @property def world_axis_physical_types(self): return self._wcs.world_axis_physical_types @property def world_axis_units(self): return self._wcs.world_axis_units @property def world_axis_object_components(self): return self._wcs.world_axis_object_components @property def world_axis_object_classes(self): return self._wcs.world_axis_object_classes @property def pixel_shape(self): return self._wcs.pixel_shape @property def pixel_bounds(self): return self._wcs.pixel_bounds @property def pixel_axis_names(self): return self._wcs.pixel_axis_names @property def world_axis_names(self): return self._wcs.world_axis_names @property def axis_correlation_matrix(self): return self._wcs.axis_correlation_matrix @property def serialized_classes(self): return self._wcs.serialized_classes @abc.abstractmethod def pixel_to_world_values(self, *pixel_arrays): pass @abc.abstractmethod def world_to_pixel_values(self, *world_arrays): pass def __repr__(self): return f"{object.__repr__(self)}\n{str(self)}" def __str__(self): return wcs_info_str(self) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/wcsapi/wrappers/sliced_wcs.py0000644000175100001710000002633300000000000022373 0ustar00vstsdockerimport numbers from collections import defaultdict import numpy as np from astropy.utils import isiterable from astropy.utils.decorators import lazyproperty from ..low_level_api import BaseLowLevelWCS from .base import BaseWCSWrapper __all__ = ['sanitize_slices', 'SlicedLowLevelWCS'] def sanitize_slices(slices, ndim): """ Given a slice as input sanitise it to an easier to parse format.format This function returns a list ``ndim`` long containing slice objects (or ints). """ if not isinstance(slices, (tuple, list)): # We just have a single int slices = (slices,) if len(slices) > ndim: raise ValueError( f"The dimensionality of the specified slice {slices} can not be greater " f"than the dimensionality ({ndim}) of the wcs.") if any((isiterable(s) for s in slices)): raise IndexError("This slice is invalid, only integer or range slices are supported.") slices = list(slices) if Ellipsis in slices: if slices.count(Ellipsis) > 1: raise IndexError("an index can only have a single ellipsis ('...')") # Replace the Ellipsis with the correct number of slice(None)s e_ind = slices.index(Ellipsis) slices.remove(Ellipsis) n_e = ndim - len(slices) for i in range(n_e): ind = e_ind + i slices.insert(ind, slice(None)) for i in range(ndim): if i < len(slices): slc = slices[i] if isinstance(slc, slice): if slc.step and slc.step != 1: raise IndexError("Slicing WCS with a step is not supported.") elif not isinstance(slc, numbers.Integral): raise IndexError("Only integer or range slices are accepted.") else: slices.append(slice(None)) return slices def combine_slices(slice1, slice2): """ Given two slices that can be applied to a 1-d array, find the resulting slice that corresponds to the combination of both slices. We assume that slice2 can be an integer, but slice1 cannot. """ if isinstance(slice1, slice) and slice1.step is not None: raise ValueError('Only slices with steps of 1 are supported') if isinstance(slice2, slice) and slice2.step is not None: raise ValueError('Only slices with steps of 1 are supported') if isinstance(slice2, numbers.Integral): if slice1.start is None: return slice2 else: return slice2 + slice1.start if slice1.start is None: if slice1.stop is None: return slice2 else: if slice2.stop is None: return slice(slice2.start, slice1.stop) else: return slice(slice2.start, min(slice1.stop, slice2.stop)) else: if slice2.start is None: start = slice1.start else: start = slice1.start + slice2.start if slice2.stop is None: stop = slice1.stop else: if slice1.start is None: stop = slice2.stop else: stop = slice2.stop + slice1.start if slice1.stop is not None: stop = min(slice1.stop, stop) return slice(start, stop) class SlicedLowLevelWCS(BaseWCSWrapper): """ A Low Level WCS wrapper which applies an array slice to a WCS. This class does not modify the underlying WCS object and can therefore drop coupled dimensions as it stores which pixel and world dimensions have been sliced out (or modified) in the underlying WCS and returns the modified results on all the Low Level WCS methods. Parameters ---------- wcs : `~astropy.wcs.wcsapi.BaseLowLevelWCS` The WCS to slice. slices : `slice` or `tuple` or `int` A valid array slice to apply to the WCS. """ def __init__(self, wcs, slices): slices = sanitize_slices(slices, wcs.pixel_n_dim) if isinstance(wcs, SlicedLowLevelWCS): # Here we combine the current slices with the previous slices # to avoid ending up with many nested WCSes self._wcs = wcs._wcs slices_original = wcs._slices_array.copy() for ipixel in range(wcs.pixel_n_dim): ipixel_orig = wcs._wcs.pixel_n_dim - 1 - wcs._pixel_keep[ipixel] ipixel_new = wcs.pixel_n_dim - 1 - ipixel slices_original[ipixel_orig] = combine_slices(slices_original[ipixel_orig], slices[ipixel_new]) self._slices_array = slices_original else: self._wcs = wcs self._slices_array = slices self._slices_pixel = self._slices_array[::-1] # figure out which pixel dimensions have been kept, then use axis correlation # matrix to figure out which world dims are kept self._pixel_keep = np.nonzero([not isinstance(self._slices_pixel[ip], numbers.Integral) for ip in range(self._wcs.pixel_n_dim)])[0] # axis_correlation_matrix[world, pixel] self._world_keep = np.nonzero( self._wcs.axis_correlation_matrix[:, self._pixel_keep].any(axis=1))[0] if len(self._pixel_keep) == 0 or len(self._world_keep) == 0: raise ValueError("Cannot slice WCS: the resulting WCS should have " "at least one pixel and one world dimension.") @lazyproperty def dropped_world_dimensions(self): """ Information describing the dropped world dimensions. """ world_coords = self._pixel_to_world_values_all(*[0]*len(self._pixel_keep)) dropped_info = defaultdict(list) for i in range(self._wcs.world_n_dim): if i in self._world_keep: continue if "world_axis_object_classes" not in dropped_info: dropped_info["world_axis_object_classes"] = dict() wao_classes = self._wcs.world_axis_object_classes wao_components = self._wcs.world_axis_object_components dropped_info["value"].append(world_coords[i]) dropped_info["world_axis_names"].append(self._wcs.world_axis_names[i]) dropped_info["world_axis_physical_types"].append(self._wcs.world_axis_physical_types[i]) dropped_info["world_axis_units"].append(self._wcs.world_axis_units[i]) dropped_info["world_axis_object_components"].append(wao_components[i]) dropped_info["world_axis_object_classes"].update(dict( filter( lambda x: x[0] == wao_components[i][0], wao_classes.items() ) )) dropped_info["serialized_classes"] = self.serialized_classes return dict(dropped_info) @property def pixel_n_dim(self): return len(self._pixel_keep) @property def world_n_dim(self): return len(self._world_keep) @property def world_axis_physical_types(self): return [self._wcs.world_axis_physical_types[i] for i in self._world_keep] @property def world_axis_units(self): return [self._wcs.world_axis_units[i] for i in self._world_keep] @property def pixel_axis_names(self): return [self._wcs.pixel_axis_names[i] for i in self._pixel_keep] @property def world_axis_names(self): return [self._wcs.world_axis_names[i] for i in self._world_keep] def _pixel_to_world_values_all(self, *pixel_arrays): pixel_arrays = tuple(map(np.asanyarray, pixel_arrays)) pixel_arrays_new = [] ipix_curr = -1 for ipix in range(self._wcs.pixel_n_dim): if isinstance(self._slices_pixel[ipix], numbers.Integral): pixel_arrays_new.append(self._slices_pixel[ipix]) else: ipix_curr += 1 if self._slices_pixel[ipix].start is not None: pixel_arrays_new.append(pixel_arrays[ipix_curr] + self._slices_pixel[ipix].start) else: pixel_arrays_new.append(pixel_arrays[ipix_curr]) pixel_arrays_new = np.broadcast_arrays(*pixel_arrays_new) return self._wcs.pixel_to_world_values(*pixel_arrays_new) def pixel_to_world_values(self, *pixel_arrays): world_arrays = self._pixel_to_world_values_all(*pixel_arrays) # Detect the case of a length 0 array if isinstance(world_arrays, np.ndarray) and not world_arrays.shape: return world_arrays if self._wcs.world_n_dim > 1: # Select the dimensions of the original WCS we are keeping. world_arrays = [world_arrays[iw] for iw in self._world_keep] # If there is only one world dimension (after slicing) we shouldn't return a tuple. if self.world_n_dim == 1: world_arrays = world_arrays[0] return world_arrays def world_to_pixel_values(self, *world_arrays): world_arrays = tuple(map(np.asanyarray, world_arrays)) world_arrays_new = [] iworld_curr = -1 for iworld in range(self._wcs.world_n_dim): if iworld in self._world_keep: iworld_curr += 1 world_arrays_new.append(world_arrays[iworld_curr]) else: world_arrays_new.append(1.) world_arrays_new = np.broadcast_arrays(*world_arrays_new) pixel_arrays = list(self._wcs.world_to_pixel_values(*world_arrays_new)) for ipixel in range(self._wcs.pixel_n_dim): if isinstance(self._slices_pixel[ipixel], slice) and self._slices_pixel[ipixel].start is not None: pixel_arrays[ipixel] -= self._slices_pixel[ipixel].start # Detect the case of a length 0 array if isinstance(pixel_arrays, np.ndarray) and not pixel_arrays.shape: return pixel_arrays pixel = tuple(pixel_arrays[ip] for ip in self._pixel_keep) if self.pixel_n_dim == 1 and self._wcs.pixel_n_dim > 1: pixel = pixel[0] return pixel @property def world_axis_object_components(self): return [self._wcs.world_axis_object_components[idx] for idx in self._world_keep] @property def world_axis_object_classes(self): keys_keep = [item[0] for item in self.world_axis_object_components] return dict([item for item in self._wcs.world_axis_object_classes.items() if item[0] in keys_keep]) @property def array_shape(self): if self._wcs.array_shape: return np.broadcast_to(0, self._wcs.array_shape)[tuple(self._slices_array)].shape @property def pixel_shape(self): if self.array_shape: return tuple(self.array_shape[::-1]) @property def pixel_bounds(self): if self._wcs.pixel_bounds is None: return bounds = [] for idx in self._pixel_keep: if self._slices_pixel[idx].start is None: bounds.append(self._wcs.pixel_bounds[idx]) else: imin, imax = self._wcs.pixel_bounds[idx] start = self._slices_pixel[idx].start bounds.append((imin - start, imax - start)) return tuple(bounds) @property def axis_correlation_matrix(self): return self._wcs.axis_correlation_matrix[self._world_keep][:, self._pixel_keep] ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2432582 astropy-5.0.2/astropy/wcs/wcsapi/wrappers/tests/0000755000175100001710000000000000000000000021035 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/wcsapi/wrappers/tests/__init__.py0000644000175100001710000000000000000000000023134 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/wcsapi/wrappers/tests/test_sliced_wcs.py0000644000175100001710000007720300000000000024576 0ustar00vstsdockerimport warnings import pytest import numpy as np from numpy.testing import assert_equal, assert_allclose from astropy.wcs.wcs import WCS, FITSFixedWarning from astropy.time import Time from astropy.wcs import WCS from astropy.io.fits import Header from astropy.io.fits.verify import VerifyWarning from astropy.coordinates import SkyCoord, Galactic, ICRS from astropy.units import Quantity from astropy.wcs.wcsapi.wrappers.sliced_wcs import SlicedLowLevelWCS, sanitize_slices, combine_slices from astropy.wcs.wcsapi.utils import wcs_info_str import astropy.units as u from astropy.coordinates.spectral_coordinate import SpectralCoord # To test the slicing we start off from standard FITS WCS # objects since those implement the low-level API. We create # a WCS for a spectral cube with axes in non-standard order # and with correlated celestial axes and an uncorrelated # spectral axis. HEADER_SPECTRAL_CUBE = """ NAXIS = 3 NAXIS1 = 10 NAXIS2 = 20 NAXIS3 = 30 CTYPE1 = GLAT-CAR CTYPE2 = FREQ CTYPE3 = GLON-CAR CNAME1 = Latitude CNAME2 = Frequency CNAME3 = Longitude CRVAL1 = 10 CRVAL2 = 20 CRVAL3 = 25 CRPIX1 = 30 CRPIX2 = 40 CRPIX3 = 45 CDELT1 = -0.1 CDELT2 = 0.5 CDELT3 = 0.1 CUNIT1 = deg CUNIT2 = Hz CUNIT3 = deg """ with warnings.catch_warnings(): warnings.simplefilter('ignore', VerifyWarning) WCS_SPECTRAL_CUBE = WCS(Header.fromstring(HEADER_SPECTRAL_CUBE, sep='\n')) WCS_SPECTRAL_CUBE.pixel_bounds = [(-1, 11), (-2, 18), (5, 15)] def test_invalid_slices(): with pytest.raises(IndexError): SlicedLowLevelWCS(WCS_SPECTRAL_CUBE, [None, None, [False, False, False]]) with pytest.raises(IndexError): SlicedLowLevelWCS(WCS_SPECTRAL_CUBE, [None, None, slice(None, None, 2)]) with pytest.raises(IndexError): SlicedLowLevelWCS(WCS_SPECTRAL_CUBE, [None, None, 1000.100]) @pytest.mark.parametrize("item, ndim, expected", ( ([Ellipsis, 10], 4, [slice(None)] * 3 + [10]), ([10, slice(20, 30)], 5, [10, slice(20, 30)] + [slice(None)] * 3), ([10, Ellipsis, 8], 10, [10] + [slice(None)] * 8 + [8]) )) def test_sanitize_slice(item, ndim, expected): new_item = sanitize_slices(item, ndim) # FIXME: do we still need the first two since the third assert # should cover it all? assert len(new_item) == ndim assert all(isinstance(i, (slice, int)) for i in new_item) assert new_item == expected EXPECTED_ELLIPSIS_REPR = """ SlicedLowLevelWCS Transformation This transformation has 3 pixel and 3 world dimensions Array shape (Numpy order): (30, 20, 10) Pixel Dim Axis Name Data size Bounds 0 None 10 (-1, 11) 1 None 20 (-2, 18) 2 None 30 (5, 15) World Dim Axis Name Physical Type Units 0 Latitude pos.galactic.lat deg 1 Frequency em.freq Hz 2 Longitude pos.galactic.lon deg Correlation between pixel and world axes: Pixel Dim World Dim 0 1 2 0 yes no yes 1 no yes no 2 yes no yes """ def test_ellipsis(): wcs = SlicedLowLevelWCS(WCS_SPECTRAL_CUBE, Ellipsis) assert wcs.pixel_n_dim == 3 assert wcs.world_n_dim == 3 assert wcs.array_shape == (30, 20, 10) assert wcs.pixel_shape == (10, 20, 30) assert wcs.world_axis_physical_types == ['pos.galactic.lat', 'em.freq', 'pos.galactic.lon'] assert wcs.world_axis_units == ['deg', 'Hz', 'deg'] assert wcs.pixel_axis_names == ['', '', ''] assert wcs.world_axis_names == ['Latitude', 'Frequency', 'Longitude'] assert_equal(wcs.axis_correlation_matrix, [[True, False, True], [False, True, False], [True, False, True]]) assert len(wcs.world_axis_object_components) == 3 assert wcs.world_axis_object_components[0] == ('celestial', 1, 'spherical.lat.degree') assert wcs.world_axis_object_components[1][:2] == ('spectral', 0) assert wcs.world_axis_object_components[2] == ('celestial', 0, 'spherical.lon.degree') assert wcs.world_axis_object_classes['celestial'][0] is SkyCoord assert wcs.world_axis_object_classes['celestial'][1] == () assert isinstance(wcs.world_axis_object_classes['celestial'][2]['frame'], Galactic) assert wcs.world_axis_object_classes['celestial'][2]['unit'] is u.deg assert wcs.world_axis_object_classes['spectral'][0] is Quantity assert wcs.world_axis_object_classes['spectral'][1] == () assert wcs.world_axis_object_classes['spectral'][2] == {} assert_allclose(wcs.pixel_to_world_values(29, 39, 44), (10, 20, 25)) assert_allclose(wcs.array_index_to_world_values(44, 39, 29), (10, 20, 25)) assert_allclose(wcs.world_to_pixel_values(10, 20, 25), (29., 39., 44.)) assert_equal(wcs.world_to_array_index_values(10, 20, 25), (44, 39, 29)) assert_equal(wcs.pixel_bounds, [(-1, 11), (-2, 18), (5, 15)]) assert str(wcs) == EXPECTED_ELLIPSIS_REPR.strip() assert EXPECTED_ELLIPSIS_REPR.strip() in repr(wcs) def test_pixel_to_world_broadcasting(): wcs = SlicedLowLevelWCS(WCS_SPECTRAL_CUBE, Ellipsis) assert_allclose(wcs.pixel_to_world_values((29, 29), 39, 44), ((10, 10), (20, 20), (25, 25))) def test_world_to_pixel_broadcasting(): wcs = SlicedLowLevelWCS(WCS_SPECTRAL_CUBE, Ellipsis) assert_allclose(wcs.world_to_pixel_values((10, 10), 20, 25), ((29., 29.), (39., 39.), (44., 44.))) EXPECTED_SPECTRAL_SLICE_REPR = """ SlicedLowLevelWCS Transformation This transformation has 2 pixel and 2 world dimensions Array shape (Numpy order): (30, 10) Pixel Dim Axis Name Data size Bounds 0 None 10 (-1, 11) 1 None 30 (5, 15) World Dim Axis Name Physical Type Units 0 Latitude pos.galactic.lat deg 1 Longitude pos.galactic.lon deg Correlation between pixel and world axes: Pixel Dim World Dim 0 1 0 yes yes 1 yes yes """ def test_spectral_slice(): wcs = SlicedLowLevelWCS(WCS_SPECTRAL_CUBE, [slice(None), 10]) assert wcs.pixel_n_dim == 2 assert wcs.world_n_dim == 2 assert wcs.array_shape == (30, 10) assert wcs.pixel_shape == (10, 30) assert wcs.world_axis_physical_types == ['pos.galactic.lat', 'pos.galactic.lon'] assert wcs.world_axis_units == ['deg', 'deg'] assert wcs.pixel_axis_names == ['', ''] assert wcs.world_axis_names == ['Latitude', 'Longitude'] assert_equal(wcs.axis_correlation_matrix, [[True, True], [True, True]]) assert wcs.world_axis_object_components == [('celestial', 1, 'spherical.lat.degree'), ('celestial', 0, 'spherical.lon.degree')] assert wcs.world_axis_object_classes['celestial'][0] is SkyCoord assert wcs.world_axis_object_classes['celestial'][1] == () assert isinstance(wcs.world_axis_object_classes['celestial'][2]['frame'], Galactic) assert wcs.world_axis_object_classes['celestial'][2]['unit'] is u.deg assert_allclose(wcs.pixel_to_world_values(29, 44), (10, 25)) assert_allclose(wcs.array_index_to_world_values(44, 29), (10, 25)) assert_allclose(wcs.world_to_pixel_values(10, 25), (29., 44.)) assert_equal(wcs.world_to_array_index_values(10, 25), (44, 29)) assert_equal(wcs.pixel_bounds, [(-1, 11), (5, 15)]) assert str(wcs) == EXPECTED_SPECTRAL_SLICE_REPR.strip() assert EXPECTED_SPECTRAL_SLICE_REPR.strip() in repr(wcs) EXPECTED_SPECTRAL_RANGE_REPR = """ SlicedLowLevelWCS Transformation This transformation has 3 pixel and 3 world dimensions Array shape (Numpy order): (30, 6, 10) Pixel Dim Axis Name Data size Bounds 0 None 10 (-1, 11) 1 None 6 (-6, 14) 2 None 30 (5, 15) World Dim Axis Name Physical Type Units 0 Latitude pos.galactic.lat deg 1 Frequency em.freq Hz 2 Longitude pos.galactic.lon deg Correlation between pixel and world axes: Pixel Dim World Dim 0 1 2 0 yes no yes 1 no yes no 2 yes no yes """ def test_spectral_range(): wcs = SlicedLowLevelWCS(WCS_SPECTRAL_CUBE, [slice(None), slice(4, 10)]) assert wcs.pixel_n_dim == 3 assert wcs.world_n_dim == 3 assert wcs.array_shape == (30, 6, 10) assert wcs.pixel_shape == (10, 6, 30) assert wcs.world_axis_physical_types == ['pos.galactic.lat', 'em.freq', 'pos.galactic.lon'] assert wcs.world_axis_units == ['deg', 'Hz', 'deg'] assert wcs.pixel_axis_names == ['', '', ''] assert wcs.world_axis_names == ['Latitude', 'Frequency', 'Longitude'] assert_equal(wcs.axis_correlation_matrix, [[True, False, True], [False, True, False], [True, False, True]]) assert len(wcs.world_axis_object_components) == 3 assert wcs.world_axis_object_components[0] == ('celestial', 1, 'spherical.lat.degree') assert wcs.world_axis_object_components[1][:2] == ('spectral', 0) assert wcs.world_axis_object_components[2] == ('celestial', 0, 'spherical.lon.degree') assert wcs.world_axis_object_classes['celestial'][0] is SkyCoord assert wcs.world_axis_object_classes['celestial'][1] == () assert isinstance(wcs.world_axis_object_classes['celestial'][2]['frame'], Galactic) assert wcs.world_axis_object_classes['celestial'][2]['unit'] is u.deg assert wcs.world_axis_object_classes['spectral'][0] is Quantity assert wcs.world_axis_object_classes['spectral'][1] == () assert wcs.world_axis_object_classes['spectral'][2] == {} assert_allclose(wcs.pixel_to_world_values(29, 35, 44), (10, 20, 25)) assert_allclose(wcs.array_index_to_world_values(44, 35, 29), (10, 20, 25)) assert_allclose(wcs.world_to_pixel_values(10, 20, 25), (29., 35., 44.)) assert_equal(wcs.world_to_array_index_values(10, 20, 25), (44, 35, 29)) assert_equal(wcs.pixel_bounds, [(-1, 11), (-6, 14), (5, 15)]) assert str(wcs) == EXPECTED_SPECTRAL_RANGE_REPR.strip() assert EXPECTED_SPECTRAL_RANGE_REPR.strip() in repr(wcs) EXPECTED_CELESTIAL_SLICE_REPR = """ SlicedLowLevelWCS Transformation This transformation has 2 pixel and 3 world dimensions Array shape (Numpy order): (30, 20) Pixel Dim Axis Name Data size Bounds 0 None 20 (-2, 18) 1 None 30 (5, 15) World Dim Axis Name Physical Type Units 0 Latitude pos.galactic.lat deg 1 Frequency em.freq Hz 2 Longitude pos.galactic.lon deg Correlation between pixel and world axes: Pixel Dim World Dim 0 1 0 no yes 1 yes no 2 no yes """ def test_celestial_slice(): wcs = SlicedLowLevelWCS(WCS_SPECTRAL_CUBE, [Ellipsis, 5]) assert wcs.pixel_n_dim == 2 assert wcs.world_n_dim == 3 assert wcs.array_shape == (30, 20) assert wcs.pixel_shape == (20, 30) assert wcs.world_axis_physical_types == ['pos.galactic.lat', 'em.freq', 'pos.galactic.lon'] assert wcs.world_axis_units == ['deg', 'Hz', 'deg'] assert wcs.pixel_axis_names == ['', ''] assert wcs.world_axis_names == ['Latitude', 'Frequency', 'Longitude'] assert_equal(wcs.axis_correlation_matrix, [[False, True], [True, False], [False, True]]) assert len(wcs.world_axis_object_components) == 3 assert wcs.world_axis_object_components[0] == ('celestial', 1, 'spherical.lat.degree') assert wcs.world_axis_object_components[1][:2] == ('spectral', 0) assert wcs.world_axis_object_components[2] == ('celestial', 0, 'spherical.lon.degree') assert wcs.world_axis_object_classes['celestial'][0] is SkyCoord assert wcs.world_axis_object_classes['celestial'][1] == () assert isinstance(wcs.world_axis_object_classes['celestial'][2]['frame'], Galactic) assert wcs.world_axis_object_classes['celestial'][2]['unit'] is u.deg assert wcs.world_axis_object_classes['spectral'][0] is Quantity assert wcs.world_axis_object_classes['spectral'][1] == () assert wcs.world_axis_object_classes['spectral'][2] == {} assert_allclose(wcs.pixel_to_world_values(39, 44), (12.4, 20, 25)) assert_allclose(wcs.array_index_to_world_values(44, 39), (12.4, 20, 25)) assert_allclose(wcs.world_to_pixel_values(12.4, 20, 25), (39., 44.)) assert_equal(wcs.world_to_array_index_values(12.4, 20, 25), (44, 39)) assert_equal(wcs.pixel_bounds, [(-2, 18), (5, 15)]) assert str(wcs) == EXPECTED_CELESTIAL_SLICE_REPR.strip() assert EXPECTED_CELESTIAL_SLICE_REPR.strip() in repr(wcs) EXPECTED_CELESTIAL_RANGE_REPR = """ SlicedLowLevelWCS Transformation This transformation has 3 pixel and 3 world dimensions Array shape (Numpy order): (30, 20, 5) Pixel Dim Axis Name Data size Bounds 0 None 5 (-6, 6) 1 None 20 (-2, 18) 2 None 30 (5, 15) World Dim Axis Name Physical Type Units 0 Latitude pos.galactic.lat deg 1 Frequency em.freq Hz 2 Longitude pos.galactic.lon deg Correlation between pixel and world axes: Pixel Dim World Dim 0 1 2 0 yes no yes 1 no yes no 2 yes no yes """ def test_celestial_range(): wcs = SlicedLowLevelWCS(WCS_SPECTRAL_CUBE, [Ellipsis, slice(5, 10)]) assert wcs.pixel_n_dim == 3 assert wcs.world_n_dim == 3 assert wcs.array_shape == (30, 20, 5) assert wcs.pixel_shape == (5, 20, 30) assert wcs.world_axis_physical_types == ['pos.galactic.lat', 'em.freq', 'pos.galactic.lon'] assert wcs.world_axis_units == ['deg', 'Hz', 'deg'] assert wcs.pixel_axis_names == ['', '', ''] assert wcs.world_axis_names == ['Latitude', 'Frequency', 'Longitude'] assert_equal(wcs.axis_correlation_matrix, [[True, False, True], [False, True, False], [True, False, True]]) assert len(wcs.world_axis_object_components) == 3 assert wcs.world_axis_object_components[0] == ('celestial', 1, 'spherical.lat.degree') assert wcs.world_axis_object_components[1][:2] == ('spectral', 0) assert wcs.world_axis_object_components[2] == ('celestial', 0, 'spherical.lon.degree') assert wcs.world_axis_object_classes['celestial'][0] is SkyCoord assert wcs.world_axis_object_classes['celestial'][1] == () assert isinstance(wcs.world_axis_object_classes['celestial'][2]['frame'], Galactic) assert wcs.world_axis_object_classes['celestial'][2]['unit'] is u.deg assert wcs.world_axis_object_classes['spectral'][0] is Quantity assert wcs.world_axis_object_classes['spectral'][1] == () assert wcs.world_axis_object_classes['spectral'][2] == {} assert_allclose(wcs.pixel_to_world_values(24, 39, 44), (10, 20, 25)) assert_allclose(wcs.array_index_to_world_values(44, 39, 24), (10, 20, 25)) assert_allclose(wcs.world_to_pixel_values(10, 20, 25), (24., 39., 44.)) assert_equal(wcs.world_to_array_index_values(10, 20, 25), (44, 39, 24)) assert_equal(wcs.pixel_bounds, [(-6, 6), (-2, 18), (5, 15)]) assert str(wcs) == EXPECTED_CELESTIAL_RANGE_REPR.strip() assert EXPECTED_CELESTIAL_RANGE_REPR.strip() in repr(wcs) # Now try with a 90 degree rotation with warnings.catch_warnings(): warnings.simplefilter('ignore', VerifyWarning) WCS_SPECTRAL_CUBE_ROT = WCS(Header.fromstring( HEADER_SPECTRAL_CUBE, sep='\n')) WCS_SPECTRAL_CUBE_ROT.wcs.pc = [[0, 0, 1], [0, 1, 0], [1, 0, 0]] WCS_SPECTRAL_CUBE_ROT.wcs.crval[0] = 0 WCS_SPECTRAL_CUBE_ROT.pixel_bounds = [(-1, 11), (-2, 18), (5, 15)] EXPECTED_CELESTIAL_RANGE_ROT_REPR = """ SlicedLowLevelWCS Transformation This transformation has 3 pixel and 3 world dimensions Array shape (Numpy order): (30, 20, 5) Pixel Dim Axis Name Data size Bounds 0 None 5 (-6, 6) 1 None 20 (-2, 18) 2 None 30 (5, 15) World Dim Axis Name Physical Type Units 0 Latitude pos.galactic.lat deg 1 Frequency em.freq Hz 2 Longitude pos.galactic.lon deg Correlation between pixel and world axes: Pixel Dim World Dim 0 1 2 0 yes no yes 1 no yes no 2 yes no yes """ def test_celestial_range_rot(): wcs = SlicedLowLevelWCS(WCS_SPECTRAL_CUBE_ROT, [Ellipsis, slice(5, 10)]) assert wcs.pixel_n_dim == 3 assert wcs.world_n_dim == 3 assert wcs.array_shape == (30, 20, 5) assert wcs.pixel_shape == (5, 20, 30) assert wcs.world_axis_physical_types == ['pos.galactic.lat', 'em.freq', 'pos.galactic.lon'] assert wcs.world_axis_units == ['deg', 'Hz', 'deg'] assert wcs.pixel_axis_names == ['', '', ''] assert wcs.world_axis_names == ['Latitude', 'Frequency', 'Longitude'] assert_equal(wcs.axis_correlation_matrix, [[True, False, True], [False, True, False], [True, False, True]]) assert len(wcs.world_axis_object_components) == 3 assert wcs.world_axis_object_components[0] == ('celestial', 1, 'spherical.lat.degree') assert wcs.world_axis_object_components[1][:2] == ('spectral', 0) assert wcs.world_axis_object_components[2] == ('celestial', 0, 'spherical.lon.degree') assert wcs.world_axis_object_classes['celestial'][0] is SkyCoord assert wcs.world_axis_object_classes['celestial'][1] == () assert isinstance(wcs.world_axis_object_classes['celestial'][2]['frame'], Galactic) assert wcs.world_axis_object_classes['celestial'][2]['unit'] is u.deg assert wcs.world_axis_object_classes['spectral'][0] is Quantity assert wcs.world_axis_object_classes['spectral'][1] == () assert wcs.world_axis_object_classes['spectral'][2] == {} assert_allclose(wcs.pixel_to_world_values(14, 29, 34), (1, 15, 24)) assert_allclose(wcs.array_index_to_world_values(34, 29, 14), (1, 15, 24)) assert_allclose(wcs.world_to_pixel_values(1, 15, 24), (14., 29., 34.)) assert_equal(wcs.world_to_array_index_values(1, 15, 24), (34, 29, 14)) assert_equal(wcs.pixel_bounds, [(-6, 6), (-2, 18), (5, 15)]) assert str(wcs) == EXPECTED_CELESTIAL_RANGE_ROT_REPR.strip() assert EXPECTED_CELESTIAL_RANGE_ROT_REPR.strip() in repr(wcs) HEADER_NO_SHAPE_CUBE = """ NAXIS = 3 CTYPE1 = GLAT-CAR CTYPE2 = FREQ CTYPE3 = GLON-CAR CRVAL1 = 10 CRVAL2 = 20 CRVAL3 = 25 CRPIX1 = 30 CRPIX2 = 40 CRPIX3 = 45 CDELT1 = -0.1 CDELT2 = 0.5 CDELT3 = 0.1 CUNIT1 = deg CUNIT2 = Hz CUNIT3 = deg """ with warnings.catch_warnings(): warnings.simplefilter('ignore', VerifyWarning) WCS_NO_SHAPE_CUBE = WCS(Header.fromstring(HEADER_NO_SHAPE_CUBE, sep='\n')) EXPECTED_NO_SHAPE_REPR = """ SlicedLowLevelWCS Transformation This transformation has 3 pixel and 3 world dimensions Array shape (Numpy order): None Pixel Dim Axis Name Data size Bounds 0 None None None 1 None None None 2 None None None World Dim Axis Name Physical Type Units 0 None pos.galactic.lat deg 1 None em.freq Hz 2 None pos.galactic.lon deg Correlation between pixel and world axes: Pixel Dim World Dim 0 1 2 0 yes no yes 1 no yes no 2 yes no yes """ def test_no_array_shape(): wcs = SlicedLowLevelWCS(WCS_NO_SHAPE_CUBE, Ellipsis) assert wcs.pixel_n_dim == 3 assert wcs.world_n_dim == 3 assert wcs.array_shape is None assert wcs.pixel_shape is None assert wcs.world_axis_physical_types == ['pos.galactic.lat', 'em.freq', 'pos.galactic.lon'] assert wcs.world_axis_units == ['deg', 'Hz', 'deg'] assert_equal(wcs.axis_correlation_matrix, [[True, False, True], [False, True, False], [True, False, True]]) assert len(wcs.world_axis_object_components) == 3 assert wcs.world_axis_object_components[0] == ('celestial', 1, 'spherical.lat.degree') assert wcs.world_axis_object_components[1][:2] == ('spectral', 0) assert wcs.world_axis_object_components[2] == ('celestial', 0, 'spherical.lon.degree') assert wcs.world_axis_object_classes['celestial'][0] is SkyCoord assert wcs.world_axis_object_classes['celestial'][1] == () assert isinstance(wcs.world_axis_object_classes['celestial'][2]['frame'], Galactic) assert wcs.world_axis_object_classes['celestial'][2]['unit'] is u.deg assert wcs.world_axis_object_classes['spectral'][0] is Quantity assert wcs.world_axis_object_classes['spectral'][1] == () assert wcs.world_axis_object_classes['spectral'][2] == {} assert_allclose(wcs.pixel_to_world_values(29, 39, 44), (10, 20, 25)) assert_allclose(wcs.array_index_to_world_values(44, 39, 29), (10, 20, 25)) assert_allclose(wcs.world_to_pixel_values(10, 20, 25), (29., 39., 44.)) assert_equal(wcs.world_to_array_index_values(10, 20, 25), (44, 39, 29)) assert str(wcs) == EXPECTED_NO_SHAPE_REPR.strip() assert EXPECTED_NO_SHAPE_REPR.strip() in repr(wcs) # Testing the WCS object having some physical types as None/Unknown HEADER_SPECTRAL_CUBE_NONE_TYPES = { 'CTYPE1': 'GLAT-CAR', 'CUNIT1': 'deg', 'CDELT1': -0.1, 'CRPIX1': 30, 'CRVAL1': 10, 'NAXIS1': 10, 'CTYPE2': '', 'CUNIT2': 'Hz', 'CDELT2': 0.5, 'CRPIX2': 40, 'CRVAL2': 20, 'NAXIS2': 20, 'CTYPE3': 'GLON-CAR', 'CUNIT3': 'deg', 'CDELT3': 0.1, 'CRPIX3': 45, 'CRVAL3': 25, 'NAXIS3': 30 } WCS_SPECTRAL_CUBE_NONE_TYPES = WCS(header=HEADER_SPECTRAL_CUBE_NONE_TYPES) WCS_SPECTRAL_CUBE_NONE_TYPES.pixel_bounds = [(-1, 11), (-2, 18), (5, 15)] EXPECTED_ELLIPSIS_REPR_NONE_TYPES = """ SlicedLowLevelWCS Transformation This transformation has 3 pixel and 3 world dimensions Array shape (Numpy order): (30, 20, 10) Pixel Dim Axis Name Data size Bounds 0 None 10 (-1, 11) 1 None 20 (-2, 18) 2 None 30 (5, 15) World Dim Axis Name Physical Type Units 0 None pos.galactic.lat deg 1 None None Hz 2 None pos.galactic.lon deg Correlation between pixel and world axes: Pixel Dim World Dim 0 1 2 0 yes no yes 1 no yes no 2 yes no yes """ def test_ellipsis_none_types(): wcs = SlicedLowLevelWCS(WCS_SPECTRAL_CUBE_NONE_TYPES, Ellipsis) assert wcs.pixel_n_dim == 3 assert wcs.world_n_dim == 3 assert wcs.array_shape == (30, 20, 10) assert wcs.pixel_shape == (10, 20, 30) assert wcs.world_axis_physical_types == ['pos.galactic.lat', None, 'pos.galactic.lon'] assert wcs.world_axis_units == ['deg', 'Hz', 'deg'] assert_equal(wcs.axis_correlation_matrix, [[True, False, True], [False, True, False], [True, False, True]]) assert wcs.world_axis_object_components == [('celestial', 1, 'spherical.lat.degree'), ('world', 0, 'value'), ('celestial', 0, 'spherical.lon.degree')] assert wcs.world_axis_object_classes['celestial'][0] is SkyCoord assert wcs.world_axis_object_classes['celestial'][1] == () assert isinstance(wcs.world_axis_object_classes['celestial'][2]['frame'], Galactic) assert wcs.world_axis_object_classes['celestial'][2]['unit'] is u.deg assert_allclose(wcs.pixel_to_world_values(29, 39, 44), (10, 20, 25)) assert_allclose(wcs.array_index_to_world_values(44, 39, 29), (10, 20, 25)) assert_allclose(wcs.world_to_pixel_values(10, 20, 25), (29., 39., 44.)) assert_equal(wcs.world_to_array_index_values(10, 20, 25), (44, 39, 29)) assert_equal(wcs.pixel_bounds, [(-1, 11), (-2, 18), (5, 15)]) assert str(wcs) == EXPECTED_ELLIPSIS_REPR_NONE_TYPES.strip() assert EXPECTED_ELLIPSIS_REPR_NONE_TYPES.strip() in repr(wcs) CASES = [(slice(None), slice(None), slice(None)), (slice(None), slice(3, None), slice(3, None)), (slice(None), slice(None, 16), slice(None, 16)), (slice(None), slice(3, 16), slice(3, 16)), (slice(2, None), slice(None), slice(2, None)), (slice(2, None), slice(3, None), slice(5, None)), (slice(2, None), slice(None, 16), slice(2, 18)), (slice(2, None), slice(3, 16), slice(5, 18)), (slice(None, 10), slice(None), slice(None, 10)), (slice(None, 10), slice(3, None), slice(3, 10)), (slice(None, 10), slice(None, 16), slice(None, 10)), (slice(None, 10), slice(3, 16), slice(3, 10)), (slice(2, 10), slice(None), slice(2, 10)), (slice(2, 10), slice(3, None), slice(5, 10)), (slice(2, 10), slice(None, 16), slice(2, 10)), (slice(2, 10), slice(3, 16), slice(5, 10)), (slice(None), 3, 3), (slice(2, None), 3, 5), (slice(None, 10), 3, 3), (slice(2, 10), 3, 5)] @pytest.mark.parametrize(('slice1', 'slice2', 'expected'), CASES) def test_combine_slices(slice1, slice2, expected): assert combine_slices(slice1, slice2) == expected def test_nested_slicing(): # Make sure that if we call slicing several times, the result is the same # as calling the slicing once with the final slice settings. wcs = WCS_SPECTRAL_CUBE sub1 = SlicedLowLevelWCS( SlicedLowLevelWCS( SlicedLowLevelWCS(wcs, [slice(None), slice(1, 10), slice(None)]), [3, slice(2, None)]), [slice(None), slice(2, 8)]) sub2 = wcs[3, 3:10, 2:8] assert_allclose(sub1.pixel_to_world_values(3, 5), sub2.pixel_to_world_values(3, 5)) assert not isinstance(sub1._wcs, SlicedLowLevelWCS) def test_too_much_slicing(): wcs = WCS_SPECTRAL_CUBE with pytest.raises(ValueError, match='Cannot slice WCS: the resulting WCS ' 'should have at least one pixel and ' 'one world dimension'): wcs[0, 1, 2] HEADER_TIME_1D = """ SIMPLE = T BITPIX = -32 NAXIS = 1 NAXIS1 = 2048 TIMESYS = 'UTC' TREFPOS = 'TOPOCENT' MJDREF = 50002.6 CTYPE1 = 'UTC' CRVAL1 = 5 CUNIT1 = 's' CRPIX1 = 1.0 CDELT1 = 2 OBSGEO-L= -20 OBSGEO-B= -70 OBSGEO-H= 2530 """ @pytest.fixture def header_time_1d(): return Header.fromstring(HEADER_TIME_1D, sep='\n') @pytest.fixture def time_1d_wcs(header_time_1d): with warnings.catch_warnings(): warnings.simplefilter('ignore', FITSFixedWarning) return WCS(header_time_1d) def test_1d_sliced_low_level(time_1d_wcs): sll = SlicedLowLevelWCS(time_1d_wcs, np.s_[10:20]) world = sll.pixel_to_world_values([1, 2]) assert isinstance(world, np.ndarray) assert np.allclose(world, [27, 29]) def validate_info_dict(result, expected): result_value = result.pop("value") expected_value = expected.pop("value") np.testing.assert_allclose(result_value, expected_value) assert result == expected def test_dropped_dimensions(): wcs = WCS_SPECTRAL_CUBE sub = SlicedLowLevelWCS(wcs, np.s_[:, :, :]) assert sub.dropped_world_dimensions == {} sub = SlicedLowLevelWCS(wcs, np.s_[:, 2:5, :]) assert sub.dropped_world_dimensions == {} sub = SlicedLowLevelWCS(wcs, np.s_[:, 0]) waocomp =sub.dropped_world_dimensions.pop("world_axis_object_components") assert len(waocomp) == 1 and waocomp[0][0] == "spectral" and waocomp[0][1] == 0 waocls = sub.dropped_world_dimensions.pop("world_axis_object_classes") assert len(waocls) == 1 and "spectral" in waocls and waocls["spectral"][0] == u.Quantity validate_info_dict(sub.dropped_world_dimensions, { "value": [0.5], "world_axis_physical_types": ["em.freq"], "world_axis_names": ["Frequency"], "world_axis_units": ["Hz"], "serialized_classes": False, }) sub = SlicedLowLevelWCS(wcs, np.s_[:, 0, 0]) waocomp =sub.dropped_world_dimensions.pop("world_axis_object_components") assert len(waocomp) == 1 and waocomp[0][0] == "spectral" and waocomp[0][1] == 0 waocls = sub.dropped_world_dimensions.pop("world_axis_object_classes") assert len(waocls) == 1 and "spectral" in waocls and waocls["spectral"][0] == u.Quantity validate_info_dict(sub.dropped_world_dimensions, { "value": [0.5], "world_axis_physical_types": ["em.freq"], "world_axis_names": ["Frequency"], "world_axis_units": ["Hz"], "serialized_classes": False, }) sub = SlicedLowLevelWCS(wcs, np.s_[0, :, 0]) dwd = sub.dropped_world_dimensions wao_classes = dwd.pop("world_axis_object_classes") validate_info_dict(dwd, { "value": [12.86995801, 20.49217541], "world_axis_physical_types": ["pos.galactic.lat", "pos.galactic.lon"], "world_axis_names": ["Latitude", "Longitude"], "world_axis_units": ["deg", "deg"], "serialized_classes": False, "world_axis_object_components": [('celestial', 1, 'spherical.lat.degree'), ('celestial', 0, 'spherical.lon.degree')], }) assert wao_classes['celestial'][0] is SkyCoord assert wao_classes['celestial'][1] == () assert isinstance(wao_classes['celestial'][2]['frame'], Galactic) assert wao_classes['celestial'][2]['unit'] is u.deg sub = SlicedLowLevelWCS(wcs, np.s_[5, :5, 12]) dwd = sub.dropped_world_dimensions wao_classes = dwd.pop("world_axis_object_classes") validate_info_dict(dwd, { "value": [11.67648267, 21.01921192], "world_axis_physical_types": ["pos.galactic.lat", "pos.galactic.lon"], "world_axis_names": ["Latitude", "Longitude"], "world_axis_units": ["deg", "deg"], "serialized_classes": False, "world_axis_object_components": [('celestial', 1, 'spherical.lat.degree'), ('celestial', 0, 'spherical.lon.degree')], }) assert wao_classes['celestial'][0] is SkyCoord assert wao_classes['celestial'][1] == () assert isinstance(wao_classes['celestial'][2]['frame'], Galactic) assert wao_classes['celestial'][2]['unit'] is u.deg def test_dropped_dimensions_4d(cube_4d_fitswcs): sub = SlicedLowLevelWCS(cube_4d_fitswcs, np.s_[:, 12, 5, 5]) dwd = sub.dropped_world_dimensions wao_classes = dwd.pop("world_axis_object_classes") wao_components = dwd.pop("world_axis_object_components") validate_info_dict(dwd, { "value": [4.e+00, -2.e+00, 1.e+10], "world_axis_physical_types": ["pos.eq.ra", "pos.eq.dec", "em.freq"], "world_axis_names": ['Right Ascension', 'Declination', 'Frequency'], "world_axis_units": ["deg", "deg", "Hz"], "serialized_classes": False, }) assert wao_classes['celestial'][0] is SkyCoord assert wao_classes['celestial'][1] == () assert isinstance(wao_classes['celestial'][2]['frame'], ICRS) assert wao_classes['celestial'][2]['unit'] is u.deg assert wao_classes['spectral'][0:3] == (u.Quantity, (), {}) assert wao_components[0] == ('celestial', 0, 'spherical.lon.degree') assert wao_components[1] == ('celestial', 1, 'spherical.lat.degree') assert wao_components[2][0:2] == ('spectral', 0) sub = SlicedLowLevelWCS(cube_4d_fitswcs, np.s_[12, 12]) dwd = sub.dropped_world_dimensions wao_classes = dwd.pop("world_axis_object_classes") wao_components = dwd.pop("world_axis_object_components") validate_info_dict(dwd, { "value": [1.e+10, 5.e+00], "world_axis_physical_types": ["em.freq", "time"], "world_axis_names": ["Frequency", "Time"], "world_axis_units": ["Hz", "s"], "serialized_classes": False, }) assert wao_components[0][0:2] == ('spectral', 0) assert wao_components[1][0] == 'time' assert wao_components[1][1] == 0 assert wao_classes['spectral'][0:3] == (u.Quantity, (), {}) assert wao_classes['time'][0:3] == (Time, (), {}) def test_pixel_to_world_values_different_int_types(): int_sliced = SlicedLowLevelWCS(WCS_SPECTRAL_CUBE, np.s_[:, 0, :]) np64_sliced = SlicedLowLevelWCS(WCS_SPECTRAL_CUBE, np.s_[:, np.int64(0), :]) pixel_arrays = ([0, 1], [0, 1]) for int_coord, np64_coord in zip(int_sliced.pixel_to_world_values(*pixel_arrays), np64_sliced.pixel_to_world_values(*pixel_arrays)): assert all(int_coord == np64_coord) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/astropy/wcs/wcslint.py0000644000175100001710000000102200000000000016572 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst """ Script support for validating the WCS keywords in a FITS file. """ def main(args=None): from . import wcs import argparse parser = argparse.ArgumentParser( description=("Check the WCS keywords in a FITS file for " "compliance against the standards")) parser.add_argument( 'filename', nargs=1, help='Path to FITS file to check') args = parser.parse_args(args) print(wcs.validate(args.filename[0])) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.0752432 astropy-5.0.2/astropy.egg-info/0000755000175100001710000000000000000000000015440 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921591.0 astropy-5.0.2/astropy.egg-info/PKG-INFO0000644000175100001710000001304100000000000016534 0ustar00vstsdockerMetadata-Version: 2.1 Name: astropy Version: 5.0.2 Summary: Astronomy and astrophysics core library Home-page: http://astropy.org Author: The Astropy Developers Author-email: astropy.team@gmail.com License: BSD 3-Clause License Project-URL: Documentation, https://docs.astropy.org Project-URL: Source, https://github.com/astropy/astropy Keywords: astronomy,astrophysics,cosmology,space,science,units,table,wcs,samp,coordinate,fits,modeling,models,fitting,ascii Platform: UNKNOWN Classifier: Intended Audience :: Science/Research Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Programming Language :: C Classifier: Programming Language :: Cython Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Topic :: Scientific/Engineering :: Astronomy Classifier: Topic :: Scientific/Engineering :: Physics Requires-Python: >=3.8 Provides-Extra: test Provides-Extra: test_all Provides-Extra: recommended Provides-Extra: all Provides-Extra: docs License-File: LICENSE.rst ======= Astropy ======= |Actions Status| |CircleCI Status| |Azure Status| |Coverage Status| |PyPI Status| |Documentation Status| |Zenodo| The Astropy Project (http://astropy.org/) is a community effort to develop a single core package for Astronomy in Python and foster interoperability between Python astronomy packages. This repository contains the core package which is intended to contain much of the core functionality and some common tools needed for performing astronomy and astrophysics with Python. Releases are `registered on PyPI `_, and development is occurring at the `project's GitHub page `_. For installation instructions, see the `online documentation `_ or `docs/install.rst `_ in this source distribution. Contributing Code, Documentation, or Feedback --------------------------------------------- The Astropy Project is made both by and for its users, so we welcome and encourage contributions of many kinds. Our goal is to keep this a positive, inclusive, successful, and growing community by abiding with the `Astropy Community Code of Conduct `_. More detailed information on contributing to the project or submitting feedback can be found on the `contributions `_ page. A `summary of contribution guidelines `_ can also be used as a quick reference when you are ready to start writing or validating code for submission. Supporting the Project ---------------------- |NumFOCUS| |Donate| The Astropy Project is sponsored by NumFOCUS, a 501(c)(3) nonprofit in the United States. You can donate to the project by using the link above, and this donation will support our mission to promote sustainable, high-level code base for the astronomy community, open code development, educational materials, and reproducible scientific research. License ------- Astropy is licensed under a 3-clause BSD style license - see the `LICENSE.rst `_ file. .. |Actions Status| image:: https://github.com/astropy/astropy/workflows/CI/badge.svg :target: https://github.com/astropy/astropy/actions :alt: Astropy's GitHub Actions CI Status .. |CircleCI Status| image:: https://img.shields.io/circleci/build/github/astropy/astropy/main?logo=circleci&label=CircleCI :target: https://circleci.com/gh/astropy/astropy :alt: Astropy's CircleCI Status .. |Azure Status| image:: https://dev.azure.com/astropy-project/astropy/_apis/build/status/astropy.astropy?repoName=astropy%2Fastropy&branchName=main :target: https://dev.azure.com/astropy-project/astropy :alt: Astropy's Azure Pipelines Status .. |Coverage Status| image:: https://codecov.io/gh/astropy/astropy/branch/main/graph/badge.svg :target: https://codecov.io/gh/astropy/astropy :alt: Astropy's Coverage Status .. |PyPI Status| image:: https://img.shields.io/pypi/v/astropy.svg :target: https://pypi.org/project/astropy :alt: Astropy's PyPI Status .. |Zenodo| image:: https://zenodo.org/badge/DOI/10.5281/zenodo.4670728.svg :target: https://doi.org/10.5281/zenodo.4670728 :alt: Zenodo DOI .. |Documentation Status| image:: https://img.shields.io/readthedocs/astropy/latest.svg?logo=read%20the%20docs&logoColor=white&label=Docs&version=stable :target: https://docs.astropy.org/en/stable/?badge=stable :alt: Documentation Status .. |NumFOCUS| image:: https://img.shields.io/badge/powered%20by-NumFOCUS-orange.svg?style=flat&colorA=E1523D&colorB=007D8A :target: http://numfocus.org :alt: Powered by NumFOCUS .. |Donate| image:: https://img.shields.io/badge/Donate-to%20Astropy-brightgreen.svg :target: https://numfocus.salsalabs.org/donate-to-astropy/index.html If you locally cloned this repo before 7 Apr 2021 ------------------------------------------------- The primary branch for this repo has been transitioned from ``master`` to ``main``. If you have a local clone of this repository and want to keep your local branch in sync with this repo, you'll need to do the following in your local clone from your terminal:: git fetch --all --prune # you can stop here if you don't use your local "master"/"main" branch git branch -m master main git branch -u origin/main main If you are using a GUI to manage your repos you'll have to find the equivalent commands as it's different for different programs. Alternatively, you can just delete your local clone and re-clone! ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921593.0 astropy-5.0.2/astropy.egg-info/SOURCES.txt0000644000175100001710000020330400000000000017326 0ustar00vstsdocker.astropy-root .gitattributes .gitignore .mailmap .pep8speaks.yml .pre-commit-config.yaml .readthedocs.yml CHANGES.rst CITATION CODE_OF_CONDUCT.md CONTRIBUTING.md GOVERNANCE.md LICENSE.rst MANIFEST.in README.rst azure-pipelines.yml codecov.yml conftest.py pip-requirements pyproject.toml setup.cfg setup.py tox.ini ./astropy/cosmology/scalar_inv_efuncs.pyx ./astropy/io/fits/_utils.pyx ./astropy/io/fits/src/compressionmodule.c ./astropy/stats/_stats.pyx ./astropy/timeseries/periodograms/lombscargle/implementations/cython_impl.pyx .circleci/config.yml .github/PULL_REQUEST_TEMPLATE.md .github/labeler.yml .github/ISSUE_TEMPLATE/bug_report.md .github/ISSUE_TEMPLATE/feature_request.md .github/workflows/cancel_workflows.yml .github/workflows/check_changelog.yml .github/workflows/ci_cron_daily.yml .github/workflows/ci_cron_weekly.yml .github/workflows/ci_workflows.yml .github/workflows/codeql-analysis.yml .github/workflows/open_actions.yml .github/workflows/stalebot.yml .pyinstaller/run_astropy_tests.py .pyinstaller/hooks/hook-skyfield.py astropy/CITATION astropy/__init__.py astropy/_compiler.c astropy/_version.py astropy/conftest.py astropy/logger.py astropy/version.py astropy.egg-info/PKG-INFO astropy.egg-info/SOURCES.txt astropy.egg-info/dependency_links.txt astropy.egg-info/entry_points.txt astropy.egg-info/not-zip-safe astropy.egg-info/requires.txt astropy.egg-info/top_level.txt astropy/_erfa/__init__.py astropy/config/__init__.py astropy/config/affiliated.py astropy/config/configuration.py astropy/config/paths.py astropy/config/tests/__init__.py astropy/config/tests/test_configs.py astropy/config/tests/data/alias.cfg astropy/config/tests/data/deprecated.cfg astropy/config/tests/data/empty.cfg astropy/config/tests/data/not_empty.cfg astropy/constants/__init__.py astropy/constants/astropyconst13.py astropy/constants/astropyconst20.py astropy/constants/astropyconst40.py astropy/constants/cgs.py astropy/constants/codata2010.py astropy/constants/codata2014.py astropy/constants/codata2018.py astropy/constants/config.py astropy/constants/constant.py astropy/constants/iau2012.py astropy/constants/iau2015.py astropy/constants/si.py astropy/constants/utils.py astropy/constants/tests/__init__.py astropy/constants/tests/test_constant.py astropy/constants/tests/test_pickle.py astropy/constants/tests/test_prior_version.py astropy/constants/tests/test_sciencestate.py astropy/convolution/__init__.py astropy/convolution/convolve.py astropy/convolution/core.py astropy/convolution/kernels.py astropy/convolution/setup_package.py astropy/convolution/utils.py astropy/convolution/src/convolve.c astropy/convolution/src/convolve.h astropy/convolution/tests/__init__.py astropy/convolution/tests/test_convolve.py astropy/convolution/tests/test_convolve_fft.py astropy/convolution/tests/test_convolve_kernels.py astropy/convolution/tests/test_convolve_models.py astropy/convolution/tests/test_convolve_nddata.py astropy/convolution/tests/test_convolve_speeds.py astropy/convolution/tests/test_discretize.py astropy/convolution/tests/test_kernel_class.py astropy/convolution/tests/test_pickle.py astropy/coordinates/__init__.py astropy/coordinates/angle_formats.py astropy/coordinates/angle_lextab.py astropy/coordinates/angle_parsetab.py astropy/coordinates/angle_utilities.py astropy/coordinates/angles.py astropy/coordinates/attributes.py astropy/coordinates/baseframe.py astropy/coordinates/calculation.py astropy/coordinates/distances.py astropy/coordinates/earth.py astropy/coordinates/earth_orientation.py astropy/coordinates/erfa_astrom.py astropy/coordinates/errors.py astropy/coordinates/funcs.py astropy/coordinates/jparser.py astropy/coordinates/matching.py astropy/coordinates/matrix_utilities.py astropy/coordinates/name_resolve.py astropy/coordinates/orbital_elements.py astropy/coordinates/representation.py astropy/coordinates/sites.py astropy/coordinates/sky_coordinate.py astropy/coordinates/sky_coordinate_parsers.py astropy/coordinates/solar_system.py astropy/coordinates/spectral_coordinate.py astropy/coordinates/spectral_quantity.py astropy/coordinates/transformations.py astropy/coordinates/builtin_frames/__init__.py astropy/coordinates/builtin_frames/altaz.py astropy/coordinates/builtin_frames/baseradec.py astropy/coordinates/builtin_frames/cirs.py astropy/coordinates/builtin_frames/cirs_observed_transforms.py astropy/coordinates/builtin_frames/ecliptic.py astropy/coordinates/builtin_frames/ecliptic_transforms.py astropy/coordinates/builtin_frames/equatorial.py astropy/coordinates/builtin_frames/fk4.py astropy/coordinates/builtin_frames/fk4_fk5_transforms.py astropy/coordinates/builtin_frames/fk5.py astropy/coordinates/builtin_frames/galactic.py astropy/coordinates/builtin_frames/galactic_transforms.py astropy/coordinates/builtin_frames/galactocentric.py astropy/coordinates/builtin_frames/gcrs.py astropy/coordinates/builtin_frames/hadec.py astropy/coordinates/builtin_frames/hcrs.py astropy/coordinates/builtin_frames/icrs.py astropy/coordinates/builtin_frames/icrs_cirs_transforms.py astropy/coordinates/builtin_frames/icrs_fk5_transforms.py astropy/coordinates/builtin_frames/icrs_observed_transforms.py astropy/coordinates/builtin_frames/intermediate_rotation_transforms.py astropy/coordinates/builtin_frames/itrs.py astropy/coordinates/builtin_frames/lsr.py astropy/coordinates/builtin_frames/skyoffset.py astropy/coordinates/builtin_frames/supergalactic.py astropy/coordinates/builtin_frames/supergalactic_transforms.py astropy/coordinates/builtin_frames/utils.py astropy/coordinates/data/constellation_data_roman87.dat astropy/coordinates/data/constellation_names.dat astropy/coordinates/data/sites.json astropy/coordinates/tests/__init__.py astropy/coordinates/tests/test_angle_generators.py astropy/coordinates/tests/test_angles.py astropy/coordinates/tests/test_angular_separation.py astropy/coordinates/tests/test_api_ape5.py astropy/coordinates/tests/test_arrays.py astropy/coordinates/tests/test_atc_replacements.py astropy/coordinates/tests/test_celestial_transformations.py astropy/coordinates/tests/test_distance.py astropy/coordinates/tests/test_earth.py astropy/coordinates/tests/test_erfa_astrom.py astropy/coordinates/tests/test_finite_difference_velocities.py astropy/coordinates/tests/test_formatting.py astropy/coordinates/tests/test_frames.py astropy/coordinates/tests/test_frames_with_velocity.py astropy/coordinates/tests/test_funcs.py astropy/coordinates/tests/test_geodetic_representations.py astropy/coordinates/tests/test_iau_fullstack.py astropy/coordinates/tests/test_icrs_observed_transformations.py astropy/coordinates/tests/test_intermediate_transformations.py astropy/coordinates/tests/test_matching.py astropy/coordinates/tests/test_matrix_utilities.py astropy/coordinates/tests/test_name_resolve.py astropy/coordinates/tests/test_pickle.py astropy/coordinates/tests/test_regression.py astropy/coordinates/tests/test_representation.py astropy/coordinates/tests/test_representation_arithmetic.py astropy/coordinates/tests/test_representation_methods.py astropy/coordinates/tests/test_shape_manipulation.py astropy/coordinates/tests/test_sites.py astropy/coordinates/tests/test_sky_coord.py astropy/coordinates/tests/test_sky_coord_velocities.py astropy/coordinates/tests/test_skyoffset_transformations.py astropy/coordinates/tests/test_solar_system.py astropy/coordinates/tests/test_spectral_coordinate.py astropy/coordinates/tests/test_spectral_quantity.py astropy/coordinates/tests/test_transformations.py astropy/coordinates/tests/test_unit_representation.py astropy/coordinates/tests/test_utils.py astropy/coordinates/tests/test_velocity_corrs.py astropy/coordinates/tests/accuracy/__init__.py astropy/coordinates/tests/accuracy/generate_ref_ast.py astropy/coordinates/tests/accuracy/generate_spectralcoord_ref.py astropy/coordinates/tests/accuracy/test_altaz_icrs.py astropy/coordinates/tests/accuracy/test_ecliptic.py astropy/coordinates/tests/accuracy/test_fk4_no_e_fk4.py astropy/coordinates/tests/accuracy/test_fk4_no_e_fk5.py astropy/coordinates/tests/accuracy/test_galactic_fk4.py astropy/coordinates/tests/accuracy/test_icrs_fk5.py astropy/coordinates/tests/accuracy/data/fk4_no_e_fk4.csv astropy/coordinates/tests/accuracy/data/fk4_no_e_fk5.csv astropy/coordinates/tests/accuracy/data/galactic_fk4.csv astropy/coordinates/tests/accuracy/data/icrs_fk5.csv astropy/coordinates/tests/accuracy/data/rv.ecsv astropy/cosmology/__init__.py astropy/cosmology/connect.py astropy/cosmology/core.py astropy/cosmology/flrw.py astropy/cosmology/funcs.py astropy/cosmology/parameter.py astropy/cosmology/parameters.py astropy/cosmology/realizations.py astropy/cosmology/scalar_inv_efuncs.pyx astropy/cosmology/units.py astropy/cosmology/utils.py astropy/cosmology/io/__init__.py astropy/cosmology/io/ecsv.py astropy/cosmology/io/mapping.py astropy/cosmology/io/model.py astropy/cosmology/io/table.py astropy/cosmology/io/tests/__init__.py astropy/cosmology/io/tests/base.py astropy/cosmology/io/tests/test_ecsv.py astropy/cosmology/io/tests/test_mapping.py astropy/cosmology/io/tests/test_model.py astropy/cosmology/io/tests/test_table.py astropy/cosmology/tests/__init__.py astropy/cosmology/tests/conftest.py astropy/cosmology/tests/test_connect.py astropy/cosmology/tests/test_core.py astropy/cosmology/tests/test_cosmology.py astropy/cosmology/tests/test_flrw.py astropy/cosmology/tests/test_funcs.py astropy/cosmology/tests/test_parameter.py astropy/cosmology/tests/test_pickle.py astropy/cosmology/tests/test_realizations.py astropy/cosmology/tests/test_units.py astropy/cosmology/tests/test_utils.py astropy/cosmology/tests/mypackage/__init__.py astropy/cosmology/tests/mypackage/cosmology.py astropy/cosmology/tests/mypackage/io/__init__.py astropy/cosmology/tests/mypackage/io/astropy_convert.py astropy/cosmology/tests/mypackage/io/astropy_io.py astropy/cosmology/tests/mypackage/io/core.py astropy/cosmology/tests/mypackage/io/tests/__init__.py astropy/cosmology/tests/mypackage/io/tests/conftest.py astropy/cosmology/tests/mypackage/io/tests/test_astropy_convert.py astropy/cosmology/tests/mypackage/io/tests/test_astropy_io.py astropy/extern/README.rst astropy/extern/__init__.py astropy/extern/_strptime.py astropy/extern/configobj/__init__.py astropy/extern/configobj/configobj.py astropy/extern/configobj/validate.py astropy/extern/jquery/__init__.py astropy/extern/jquery/data/css/jquery.dataTables.css astropy/extern/jquery/data/js/jquery-3.1.1.js astropy/extern/jquery/data/js/jquery-3.1.1.min.js astropy/extern/jquery/data/js/jquery.dataTables.js astropy/extern/jquery/data/js/jquery.dataTables.min.js astropy/extern/ply/__init__.py astropy/extern/ply/cpp.py astropy/extern/ply/ctokens.py astropy/extern/ply/lex.py astropy/extern/ply/yacc.py astropy/extern/ply/ygen.py astropy/io/__init__.py astropy/io/ascii/__init__.py astropy/io/ascii/basic.py astropy/io/ascii/cds.py astropy/io/ascii/connect.py astropy/io/ascii/core.py astropy/io/ascii/cparser.pyx astropy/io/ascii/daophot.py astropy/io/ascii/docs.py astropy/io/ascii/ecsv.py astropy/io/ascii/fastbasic.py astropy/io/ascii/fixedwidth.py astropy/io/ascii/html.py astropy/io/ascii/ipac.py astropy/io/ascii/latex.py astropy/io/ascii/misc.py astropy/io/ascii/mrt.py astropy/io/ascii/qdp.py astropy/io/ascii/rst.py astropy/io/ascii/setup_package.py astropy/io/ascii/sextractor.py astropy/io/ascii/ui.py astropy/io/ascii/src/tokenizer.c astropy/io/ascii/src/tokenizer.h astropy/io/ascii/tests/__init__.py astropy/io/ascii/tests/common.py astropy/io/ascii/tests/test_c_reader.py astropy/io/ascii/tests/test_cds.py astropy/io/ascii/tests/test_cds_header_from_readme.py astropy/io/ascii/tests/test_compressed.py astropy/io/ascii/tests/test_connect.py astropy/io/ascii/tests/test_ecsv.py astropy/io/ascii/tests/test_fixedwidth.py astropy/io/ascii/tests/test_html.py astropy/io/ascii/tests/test_ipac_definitions.py astropy/io/ascii/tests/test_qdp.py astropy/io/ascii/tests/test_read.py astropy/io/ascii/tests/test_rst.py astropy/io/ascii/tests/test_types.py astropy/io/ascii/tests/test_write.py astropy/io/ascii/tests/data/apostrophe.rdb astropy/io/ascii/tests/data/apostrophe.tab astropy/io/ascii/tests/data/bad.txt astropy/io/ascii/tests/data/bars_at_ends.txt astropy/io/ascii/tests/data/cds.dat astropy/io/ascii/tests/data/cds2.dat astropy/io/ascii/tests/data/cdsFunctional.dat astropy/io/ascii/tests/data/cdsFunctional2.dat astropy/io/ascii/tests/data/cds_malformed.dat astropy/io/ascii/tests/data/commented_header.dat astropy/io/ascii/tests/data/commented_header2.dat astropy/io/ascii/tests/data/conf_py.txt astropy/io/ascii/tests/data/continuation.dat astropy/io/ascii/tests/data/daophot.dat astropy/io/ascii/tests/data/daophot.dat.gz astropy/io/ascii/tests/data/daophot2.dat astropy/io/ascii/tests/data/daophot3.dat astropy/io/ascii/tests/data/daophot4.dat astropy/io/ascii/tests/data/fill_values.txt astropy/io/ascii/tests/data/fixed_width_2_line.txt astropy/io/ascii/tests/data/html.html astropy/io/ascii/tests/data/html2.html astropy/io/ascii/tests/data/ipac.dat astropy/io/ascii/tests/data/ipac.dat.bz2 astropy/io/ascii/tests/data/ipac.dat.xz astropy/io/ascii/tests/data/latex1.tex astropy/io/ascii/tests/data/latex1.tex.gz astropy/io/ascii/tests/data/latex2.tex astropy/io/ascii/tests/data/latex3.tex astropy/io/ascii/tests/data/nls1_stackinfo.dbout astropy/io/ascii/tests/data/no_data_cds.dat astropy/io/ascii/tests/data/no_data_daophot.dat astropy/io/ascii/tests/data/no_data_ipac.dat astropy/io/ascii/tests/data/no_data_sextractor.dat astropy/io/ascii/tests/data/no_data_with_header.dat astropy/io/ascii/tests/data/no_data_without_header.dat astropy/io/ascii/tests/data/sextractor.dat astropy/io/ascii/tests/data/sextractor2.dat astropy/io/ascii/tests/data/sextractor3.dat astropy/io/ascii/tests/data/short.rdb astropy/io/ascii/tests/data/short.rdb.bz2 astropy/io/ascii/tests/data/short.rdb.gz astropy/io/ascii/tests/data/short.rdb.xz astropy/io/ascii/tests/data/short.tab astropy/io/ascii/tests/data/simple.txt astropy/io/ascii/tests/data/simple2.txt astropy/io/ascii/tests/data/simple3.txt astropy/io/ascii/tests/data/simple4.txt astropy/io/ascii/tests/data/simple5.txt astropy/io/ascii/tests/data/simple_csv.csv astropy/io/ascii/tests/data/simple_csv_missing.csv astropy/io/ascii/tests/data/space_delim_blank_lines.txt astropy/io/ascii/tests/data/space_delim_no_header.dat astropy/io/ascii/tests/data/space_delim_no_names.dat astropy/io/ascii/tests/data/subtypes.ecsv astropy/io/ascii/tests/data/test4.dat astropy/io/ascii/tests/data/test5.dat astropy/io/ascii/tests/data/vots_spec.dat astropy/io/ascii/tests/data/whitespace.dat astropy/io/ascii/tests/data/cds/description/ReadMe astropy/io/ascii/tests/data/cds/description/table.dat astropy/io/ascii/tests/data/cds/glob/ReadMe astropy/io/ascii/tests/data/cds/glob/lmxbrefs.dat astropy/io/ascii/tests/data/cds/multi/ReadMe astropy/io/ascii/tests/data/cds/multi/lhs2065.dat astropy/io/ascii/tests/data/cds/multi/lp944-20.dat astropy/io/ascii/tests/data/cds/null/ReadMe astropy/io/ascii/tests/data/cds/null/ReadMe1 astropy/io/ascii/tests/data/cds/null/table.dat astropy/io/ascii/tests/data/vizier/ReadMe astropy/io/ascii/tests/data/vizier/table1.dat astropy/io/ascii/tests/data/vizier/table5.dat astropy/io/fits/__init__.py astropy/io/fits/_utils.pyx astropy/io/fits/card.py astropy/io/fits/column.py astropy/io/fits/connect.py astropy/io/fits/convenience.py astropy/io/fits/diff.py astropy/io/fits/file.py astropy/io/fits/fitsrec.py astropy/io/fits/fitstime.py astropy/io/fits/header.py astropy/io/fits/setup_package.py astropy/io/fits/util.py astropy/io/fits/verify.py astropy/io/fits/hdu/__init__.py astropy/io/fits/hdu/base.py astropy/io/fits/hdu/compressed.py astropy/io/fits/hdu/groups.py astropy/io/fits/hdu/hdulist.py astropy/io/fits/hdu/image.py astropy/io/fits/hdu/nonstandard.py astropy/io/fits/hdu/streaming.py astropy/io/fits/hdu/table.py astropy/io/fits/scripts/__init__.py astropy/io/fits/scripts/fitscheck.py astropy/io/fits/scripts/fitsdiff.py astropy/io/fits/scripts/fitsheader.py astropy/io/fits/scripts/fitsinfo.py astropy/io/fits/src/compressionmodule.c astropy/io/fits/src/compressionmodule.h astropy/io/fits/tests/__init__.py astropy/io/fits/tests/cfitsio_verify.c astropy/io/fits/tests/test_checksum.py astropy/io/fits/tests/test_compression_failures.py astropy/io/fits/tests/test_connect.py astropy/io/fits/tests/test_convenience.py astropy/io/fits/tests/test_core.py astropy/io/fits/tests/test_diff.py astropy/io/fits/tests/test_division.py astropy/io/fits/tests/test_fitscheck.py astropy/io/fits/tests/test_fitsdiff.py astropy/io/fits/tests/test_fitsheader.py astropy/io/fits/tests/test_fitsinfo.py astropy/io/fits/tests/test_fitstime.py astropy/io/fits/tests/test_groups.py astropy/io/fits/tests/test_hdulist.py astropy/io/fits/tests/test_header.py astropy/io/fits/tests/test_image.py astropy/io/fits/tests/test_image_dask.py astropy/io/fits/tests/test_nonstandard.py astropy/io/fits/tests/test_structured.py astropy/io/fits/tests/test_table.py astropy/io/fits/tests/test_uint.py astropy/io/fits/tests/test_util.py astropy/io/fits/tests/data/arange.fits astropy/io/fits/tests/data/ascii.fits astropy/io/fits/tests/data/ascii_i4-i20.fits astropy/io/fits/tests/data/blank.fits astropy/io/fits/tests/data/btable.fits astropy/io/fits/tests/data/chandra_time.fits astropy/io/fits/tests/data/checksum.fits astropy/io/fits/tests/data/checksum_false.fits astropy/io/fits/tests/data/comp.fits astropy/io/fits/tests/data/compressed_float_bzero.fits astropy/io/fits/tests/data/compressed_image.fits astropy/io/fits/tests/data/double_ext.fits astropy/io/fits/tests/data/fixed-1890.fits astropy/io/fits/tests/data/group.fits astropy/io/fits/tests/data/history_header.fits astropy/io/fits/tests/data/memtest.fits astropy/io/fits/tests/data/o4sp040b0_raw.fits astropy/io/fits/tests/data/random_groups.fits astropy/io/fits/tests/data/scale.fits astropy/io/fits/tests/data/stddata.fits astropy/io/fits/tests/data/table.fits astropy/io/fits/tests/data/tb.fits astropy/io/fits/tests/data/tdim.fits astropy/io/fits/tests/data/test0.fits astropy/io/fits/tests/data/test1.fits astropy/io/fits/tests/data/theap-gap.fits astropy/io/fits/tests/data/variable_length_table.fits astropy/io/fits/tests/data/verify.fits astropy/io/fits/tests/data/zerowidth.fits astropy/io/fits/tests/data/invalid/group_invalid.fits astropy/io/misc/__init__.py astropy/io/misc/connect.py astropy/io/misc/hdf5.py astropy/io/misc/parquet.py astropy/io/misc/pickle_helpers.py astropy/io/misc/yaml.py astropy/io/misc/asdf/__init__.py astropy/io/misc/asdf/conftest.py astropy/io/misc/asdf/connect.py astropy/io/misc/asdf/extension.py astropy/io/misc/asdf/types.py astropy/io/misc/asdf/data/schemas/astropy.org/astropy/coordinates/angle-1.0.0.yaml astropy/io/misc/asdf/data/schemas/astropy.org/astropy/coordinates/earthlocation-1.0.0.yaml astropy/io/misc/asdf/data/schemas/astropy.org/astropy/coordinates/latitude-1.0.0.yaml astropy/io/misc/asdf/data/schemas/astropy.org/astropy/coordinates/longitude-1.0.0.yaml astropy/io/misc/asdf/data/schemas/astropy.org/astropy/coordinates/representation-1.0.0.yaml astropy/io/misc/asdf/data/schemas/astropy.org/astropy/coordinates/skycoord-1.0.0.yaml astropy/io/misc/asdf/data/schemas/astropy.org/astropy/coordinates/spectralcoord-1.0.0.yaml astropy/io/misc/asdf/data/schemas/astropy.org/astropy/coordinates/frames/baseframe-1.0.0.yaml astropy/io/misc/asdf/data/schemas/astropy.org/astropy/coordinates/frames/cirs-1.0.0.yaml astropy/io/misc/asdf/data/schemas/astropy.org/astropy/coordinates/frames/fk4-1.0.0.yaml astropy/io/misc/asdf/data/schemas/astropy.org/astropy/coordinates/frames/fk4noeterms-1.0.0.yaml astropy/io/misc/asdf/data/schemas/astropy.org/astropy/coordinates/frames/fk5-1.0.0.yaml astropy/io/misc/asdf/data/schemas/astropy.org/astropy/coordinates/frames/galactic-1.0.0.yaml astropy/io/misc/asdf/data/schemas/astropy.org/astropy/coordinates/frames/galactocentric-1.0.0.yaml astropy/io/misc/asdf/data/schemas/astropy.org/astropy/coordinates/frames/gcrs-1.0.0.yaml astropy/io/misc/asdf/data/schemas/astropy.org/astropy/coordinates/frames/icrs-1.0.0.yaml astropy/io/misc/asdf/data/schemas/astropy.org/astropy/coordinates/frames/icrs-1.1.0.yaml astropy/io/misc/asdf/data/schemas/astropy.org/astropy/coordinates/frames/itrs-1.0.0.yaml astropy/io/misc/asdf/data/schemas/astropy.org/astropy/coordinates/frames/precessedgeocentric-1.0.0.yaml astropy/io/misc/asdf/data/schemas/astropy.org/astropy/fits/fits-1.0.0.yaml astropy/io/misc/asdf/data/schemas/astropy.org/astropy/table/table-1.0.0.yaml astropy/io/misc/asdf/data/schemas/astropy.org/astropy/time/timedelta-1.0.0.yaml astropy/io/misc/asdf/data/schemas/astropy.org/astropy/transform/units_mapping-1.0.0.yaml astropy/io/misc/asdf/data/schemas/astropy.org/astropy/units/equivalency-1.0.0.yaml astropy/io/misc/asdf/tags/__init__.py astropy/io/misc/asdf/tags/helpers.py astropy/io/misc/asdf/tags/coordinates/__init__.py astropy/io/misc/asdf/tags/coordinates/angle.py astropy/io/misc/asdf/tags/coordinates/earthlocation.py astropy/io/misc/asdf/tags/coordinates/frames.py astropy/io/misc/asdf/tags/coordinates/representation.py astropy/io/misc/asdf/tags/coordinates/skycoord.py astropy/io/misc/asdf/tags/coordinates/spectralcoord.py astropy/io/misc/asdf/tags/coordinates/tests/__init__.py astropy/io/misc/asdf/tags/coordinates/tests/test_angle.py astropy/io/misc/asdf/tags/coordinates/tests/test_earthlocation.py astropy/io/misc/asdf/tags/coordinates/tests/test_frames.py astropy/io/misc/asdf/tags/coordinates/tests/test_representation.py astropy/io/misc/asdf/tags/coordinates/tests/test_skycoord.py astropy/io/misc/asdf/tags/coordinates/tests/test_spectralcoord.py astropy/io/misc/asdf/tags/fits/__init__.py astropy/io/misc/asdf/tags/fits/fits.py astropy/io/misc/asdf/tags/fits/tests/__init__.py astropy/io/misc/asdf/tags/fits/tests/test_fits.py astropy/io/misc/asdf/tags/fits/tests/data/complex.fits astropy/io/misc/asdf/tags/table/__init__.py astropy/io/misc/asdf/tags/table/table.py astropy/io/misc/asdf/tags/table/tests/__init__.py astropy/io/misc/asdf/tags/table/tests/test_table.py astropy/io/misc/asdf/tags/tests/__init__.py astropy/io/misc/asdf/tags/tests/helpers.py astropy/io/misc/asdf/tags/time/__init__.py astropy/io/misc/asdf/tags/time/time.py astropy/io/misc/asdf/tags/time/timedelta.py astropy/io/misc/asdf/tags/time/tests/__init__.py astropy/io/misc/asdf/tags/time/tests/test_time.py astropy/io/misc/asdf/tags/time/tests/test_timedelta.py astropy/io/misc/asdf/tags/transform/__init__.py astropy/io/misc/asdf/tags/transform/basic.py astropy/io/misc/asdf/tags/transform/compound.py astropy/io/misc/asdf/tags/transform/functional_models.py astropy/io/misc/asdf/tags/transform/math.py astropy/io/misc/asdf/tags/transform/physical_models.py astropy/io/misc/asdf/tags/transform/polynomial.py astropy/io/misc/asdf/tags/transform/powerlaws.py astropy/io/misc/asdf/tags/transform/projections.py astropy/io/misc/asdf/tags/transform/tabular.py astropy/io/misc/asdf/tags/transform/tests/__init__.py astropy/io/misc/asdf/tags/transform/tests/test_transform.py astropy/io/misc/asdf/tags/transform/tests/test_units_mapping.py astropy/io/misc/asdf/tags/unit/__init__.py astropy/io/misc/asdf/tags/unit/equivalency.py astropy/io/misc/asdf/tags/unit/quantity.py astropy/io/misc/asdf/tags/unit/unit.py astropy/io/misc/asdf/tags/unit/tests/__init__.py astropy/io/misc/asdf/tags/unit/tests/test_equivalency.py astropy/io/misc/asdf/tags/unit/tests/test_quantity.py astropy/io/misc/asdf/tags/unit/tests/test_unit.py astropy/io/misc/asdf/tests/__init__.py astropy/io/misc/asdf/tests/test_io.py astropy/io/misc/pandas/__init__.py astropy/io/misc/pandas/connect.py astropy/io/misc/tests/__init__.py astropy/io/misc/tests/test_hdf5.py astropy/io/misc/tests/test_pandas.py astropy/io/misc/tests/test_parquet.py astropy/io/misc/tests/test_pickle_helpers.py astropy/io/misc/tests/test_yaml.py astropy/io/misc/tests/data/old_meta_example.hdf5 astropy/io/registry/__init__.py astropy/io/registry/base.py astropy/io/registry/compat.py astropy/io/registry/core.py astropy/io/registry/interface.py astropy/io/registry/tests/__init__.py astropy/io/registry/tests/test_registries.py astropy/io/registry/tests/test_registry_help.py astropy/io/tests/__init__.py astropy/io/tests/safeio.py astropy/io/votable/__init__.py astropy/io/votable/connect.py astropy/io/votable/converters.py astropy/io/votable/exceptions.py astropy/io/votable/setup_package.py astropy/io/votable/table.py astropy/io/votable/tree.py astropy/io/votable/ucd.py astropy/io/votable/util.py astropy/io/votable/volint.py astropy/io/votable/xmlutil.py astropy/io/votable/data/VOTable.dtd astropy/io/votable/data/VOTable.v1.1.xsd astropy/io/votable/data/VOTable.v1.2.xsd astropy/io/votable/data/VOTable.v1.3.xsd astropy/io/votable/data/VOTable.v1.4.xsd astropy/io/votable/data/ucd1p-words.txt astropy/io/votable/src/.gitignore astropy/io/votable/src/tablewriter.c astropy/io/votable/tests/__init__.py astropy/io/votable/tests/converter_test.py astropy/io/votable/tests/exception_test.py astropy/io/votable/tests/resource_test.py astropy/io/votable/tests/table_test.py astropy/io/votable/tests/tree_test.py astropy/io/votable/tests/ucd_test.py astropy/io/votable/tests/util_test.py astropy/io/votable/tests/vo_test.py astropy/io/votable/tests/data/binary2_masked_strings.xml astropy/io/votable/tests/data/custom_datatype.xml astropy/io/votable/tests/data/empty_table.xml astropy/io/votable/tests/data/gemini.xml astropy/io/votable/tests/data/irsa-nph-error.xml astropy/io/votable/tests/data/irsa-nph-m31.xml astropy/io/votable/tests/data/names.xml astropy/io/votable/tests/data/no_field_not_empty_table.xml astropy/io/votable/tests/data/no_resource.txt astropy/io/votable/tests/data/no_resource.xml astropy/io/votable/tests/data/nonstandard_units.xml astropy/io/votable/tests/data/regression.bin.tabledata.truth.1.1.xml astropy/io/votable/tests/data/regression.bin.tabledata.truth.1.3.xml astropy/io/votable/tests/data/regression.xml astropy/io/votable/tests/data/resource_groups.xml astropy/io/votable/tests/data/tb.fits astropy/io/votable/tests/data/timesys.xml astropy/io/votable/tests/data/timesys_errors.xml astropy/io/votable/tests/data/too_many_columns.xml.gz astropy/io/votable/tests/data/valid_votable.xml astropy/io/votable/tests/data/validation.txt astropy/io/votable/validator/__init__.py astropy/io/votable/validator/html.py astropy/io/votable/validator/main.py astropy/io/votable/validator/result.py astropy/io/votable/validator/data/urls/cone.big.dat.gz astropy/io/votable/validator/data/urls/cone.broken.dat.gz astropy/io/votable/validator/data/urls/cone.good.dat.gz astropy/io/votable/validator/data/urls/cone.incorrect.dat.gz astropy/modeling/__init__.py astropy/modeling/bounding_box.py astropy/modeling/convolution.py astropy/modeling/core.py astropy/modeling/fitting.py astropy/modeling/functional_models.py astropy/modeling/mappings.py astropy/modeling/math_functions.py astropy/modeling/models.py astropy/modeling/optimizers.py astropy/modeling/parameters.py astropy/modeling/physical_models.py astropy/modeling/polynomial.py astropy/modeling/powerlaws.py astropy/modeling/projections.py astropy/modeling/rotations.py astropy/modeling/separable.py astropy/modeling/setup_package.py astropy/modeling/spline.py astropy/modeling/statistic.py astropy/modeling/tabular.py astropy/modeling/utils.py astropy/modeling/src/.gitignore astropy/modeling/src/projections.c astropy/modeling/src/projections.c.templ astropy/modeling/src/wcsconfig.h astropy/modeling/tests/__init__.py astropy/modeling/tests/example_models.py astropy/modeling/tests/irafutil.py astropy/modeling/tests/test_bounding_box.py astropy/modeling/tests/test_compound.py astropy/modeling/tests/test_constraints.py astropy/modeling/tests/test_convolution.py astropy/modeling/tests/test_core.py astropy/modeling/tests/test_fitters.py astropy/modeling/tests/test_functional_models.py astropy/modeling/tests/test_input.py astropy/modeling/tests/test_mappings.py astropy/modeling/tests/test_math_func.py astropy/modeling/tests/test_model_sets.py astropy/modeling/tests/test_models.py astropy/modeling/tests/test_models_quantities.py astropy/modeling/tests/test_parameters.py astropy/modeling/tests/test_physical_models.py astropy/modeling/tests/test_polynomial.py astropy/modeling/tests/test_projections.py astropy/modeling/tests/test_quantities_evaluation.py astropy/modeling/tests/test_quantities_fitting.py astropy/modeling/tests/test_quantities_model.py astropy/modeling/tests/test_quantities_parameters.py astropy/modeling/tests/test_quantities_rotations.py astropy/modeling/tests/test_rotations.py astropy/modeling/tests/test_separable.py astropy/modeling/tests/test_spline.py astropy/modeling/tests/test_statistics.py astropy/modeling/tests/test_units_mapping.py astropy/modeling/tests/test_utils.py astropy/modeling/tests/data/1904-66_AZP.fits astropy/modeling/tests/data/__init__.py astropy/modeling/tests/data/hst_sip.hdr astropy/modeling/tests/data/idcompspec.fits astropy/modeling/tests/data/irac_sip.hdr astropy/modeling/tests/data/spec.txt astropy/nddata/__init__.py astropy/nddata/_testing.py astropy/nddata/bitmask.py astropy/nddata/blocks.py astropy/nddata/ccddata.py astropy/nddata/compat.py astropy/nddata/decorators.py astropy/nddata/flag_collection.py astropy/nddata/nddata.py astropy/nddata/nddata_base.py astropy/nddata/nddata_withmixins.py astropy/nddata/nduncertainty.py astropy/nddata/utils.py astropy/nddata/mixins/__init__.py astropy/nddata/mixins/ndarithmetic.py astropy/nddata/mixins/ndio.py astropy/nddata/mixins/ndslicing.py astropy/nddata/mixins/tests/__init__.py astropy/nddata/mixins/tests/test_ndarithmetic.py astropy/nddata/mixins/tests/test_ndio.py astropy/nddata/mixins/tests/test_ndslicing.py astropy/nddata/tests/__init__.py astropy/nddata/tests/test_bitmask.py astropy/nddata/tests/test_blocks.py astropy/nddata/tests/test_ccddata.py astropy/nddata/tests/test_compat.py astropy/nddata/tests/test_decorators.py astropy/nddata/tests/test_flag_collection.py astropy/nddata/tests/test_nddata.py astropy/nddata/tests/test_nddata_base.py astropy/nddata/tests/test_nduncertainty.py astropy/nddata/tests/test_utils.py astropy/nddata/tests/data/sip-wcs.fits astropy/samp/__init__.py astropy/samp/client.py astropy/samp/constants.py astropy/samp/errors.py astropy/samp/hub.py astropy/samp/hub_proxy.py astropy/samp/hub_script.py astropy/samp/integrated_client.py astropy/samp/lockfile_helpers.py astropy/samp/setup_package.py astropy/samp/standard_profile.py astropy/samp/utils.py astropy/samp/web_profile.py astropy/samp/data/astropy_icon.png astropy/samp/data/clientaccesspolicy.xml astropy/samp/data/crossdomain.xml astropy/samp/tests/__init__.py astropy/samp/tests/test_client.py astropy/samp/tests/test_errors.py astropy/samp/tests/test_helpers.py astropy/samp/tests/test_hub.py astropy/samp/tests/test_hub_proxy.py astropy/samp/tests/test_hub_script.py astropy/samp/tests/test_standard_profile.py astropy/samp/tests/test_web_profile.py astropy/samp/tests/web_profile_test_helpers.py astropy/stats/__init__.py astropy/stats/_stats.pyx astropy/stats/bayesian_blocks.py astropy/stats/biweight.py astropy/stats/circstats.py astropy/stats/funcs.py astropy/stats/histogram.py astropy/stats/info_theory.py astropy/stats/jackknife.py astropy/stats/setup_package.py astropy/stats/sigma_clipping.py astropy/stats/spatial.py astropy/stats/bls/__init__.py astropy/stats/lombscargle/__init__.py astropy/stats/src/compute_bounds.c astropy/stats/src/compute_bounds.h astropy/stats/src/fast_sigma_clip.c astropy/stats/src/wirth_select.c astropy/stats/src/wirth_select.h astropy/stats/tests/__init__.py astropy/stats/tests/test_bayesian_blocks.py astropy/stats/tests/test_biweight.py astropy/stats/tests/test_circstats.py astropy/stats/tests/test_funcs.py astropy/stats/tests/test_histogram.py astropy/stats/tests/test_info_theory.py astropy/stats/tests/test_jackknife.py astropy/stats/tests/test_sigma_clipping.py astropy/stats/tests/test_spatial.py astropy/table/__init__.py astropy/table/_column_mixins.pyx astropy/table/_np_utils.pyx astropy/table/bst.py astropy/table/column.py astropy/table/connect.py astropy/table/groups.py astropy/table/index.py astropy/table/info.py astropy/table/jsviewer.py astropy/table/meta.py astropy/table/ndarray_mixin.py astropy/table/np_utils.py astropy/table/operations.py astropy/table/pandas.py astropy/table/pprint.py astropy/table/row.py astropy/table/serialize.py astropy/table/setup_package.py astropy/table/soco.py astropy/table/sorted_array.py astropy/table/table.py astropy/table/table_helpers.py astropy/table/mixins/__init__.py astropy/table/mixins/dask.py astropy/table/mixins/registry.py astropy/table/mixins/tests/__init__.py astropy/table/mixins/tests/test_dask.py astropy/table/mixins/tests/test_registry.py astropy/table/scripts/__init__.py astropy/table/scripts/showtable.py astropy/table/tests/__init__.py astropy/table/tests/conftest.py astropy/table/tests/test_array.py astropy/table/tests/test_bst.py astropy/table/tests/test_column.py astropy/table/tests/test_groups.py astropy/table/tests/test_index.py astropy/table/tests/test_info.py astropy/table/tests/test_init_table.py astropy/table/tests/test_item_access.py astropy/table/tests/test_jsviewer.py astropy/table/tests/test_masked.py astropy/table/tests/test_mixin.py astropy/table/tests/test_np_utils.py astropy/table/tests/test_operations.py astropy/table/tests/test_pickle.py astropy/table/tests/test_pprint.py astropy/table/tests/test_row.py astropy/table/tests/test_showtable.py astropy/table/tests/test_subclass.py astropy/table/tests/test_table.py astropy/tests/__init__.py astropy/tests/command.py astropy/tests/disable_internet.py astropy/tests/helper.py astropy/tests/image_tests.py astropy/tests/runner.py astropy/tests/test_logger.py astropy/tests/plugins/__init__.py astropy/tests/plugins/display.py astropy/tests/tests/__init__.py astropy/tests/tests/test_imports.py astropy/tests/tests/test_quantity_helpers.py astropy/tests/tests/test_run_tests.py astropy/tests/tests/test_runner.py astropy/time/__init__.py astropy/time/core.py astropy/time/formats.py astropy/time/setup_package.py astropy/time/utils.py astropy/time/src/parse_times.c astropy/time/tests/__init__.py astropy/time/tests/test_basic.py astropy/time/tests/test_comparisons.py astropy/time/tests/test_corrs.py astropy/time/tests/test_custom_formats.py astropy/time/tests/test_delta.py astropy/time/tests/test_fast_parser.py astropy/time/tests/test_functions.py astropy/time/tests/test_guess.py astropy/time/tests/test_mask.py astropy/time/tests/test_methods.py astropy/time/tests/test_pickle.py astropy/time/tests/test_precision.py astropy/time/tests/test_quantity_interaction.py astropy/time/tests/test_sidereal.py astropy/time/tests/test_update_leap_seconds.py astropy/time/tests/test_ut1.py astropy/timeseries/__init__.py astropy/timeseries/binned.py astropy/timeseries/core.py astropy/timeseries/downsample.py astropy/timeseries/sampled.py astropy/timeseries/io/__init__.py astropy/timeseries/io/kepler.py astropy/timeseries/io/tests/__init__.py astropy/timeseries/io/tests/test_kepler.py astropy/timeseries/periodograms/__init__.py astropy/timeseries/periodograms/base.py astropy/timeseries/periodograms/bls/__init__.py astropy/timeseries/periodograms/bls/_impl.pyx astropy/timeseries/periodograms/bls/bls.c astropy/timeseries/periodograms/bls/core.py astropy/timeseries/periodograms/bls/methods.py astropy/timeseries/periodograms/bls/setup_package.py astropy/timeseries/periodograms/bls/tests/__init__.py astropy/timeseries/periodograms/bls/tests/test_bls.py astropy/timeseries/periodograms/lombscargle/__init__.py astropy/timeseries/periodograms/lombscargle/_statistics.py astropy/timeseries/periodograms/lombscargle/core.py astropy/timeseries/periodograms/lombscargle/utils.py astropy/timeseries/periodograms/lombscargle/implementations/__init__.py astropy/timeseries/periodograms/lombscargle/implementations/chi2_impl.py astropy/timeseries/periodograms/lombscargle/implementations/cython_impl.pyx astropy/timeseries/periodograms/lombscargle/implementations/fast_impl.py astropy/timeseries/periodograms/lombscargle/implementations/fastchi2_impl.py astropy/timeseries/periodograms/lombscargle/implementations/main.py astropy/timeseries/periodograms/lombscargle/implementations/mle.py astropy/timeseries/periodograms/lombscargle/implementations/scipy_impl.py astropy/timeseries/periodograms/lombscargle/implementations/slow_impl.py astropy/timeseries/periodograms/lombscargle/implementations/utils.py astropy/timeseries/periodograms/lombscargle/implementations/tests/__init__.py astropy/timeseries/periodograms/lombscargle/implementations/tests/test_mle.py astropy/timeseries/periodograms/lombscargle/implementations/tests/test_utils.py astropy/timeseries/periodograms/lombscargle/tests/__init__.py astropy/timeseries/periodograms/lombscargle/tests/test_lombscargle.py astropy/timeseries/periodograms/lombscargle/tests/test_statistics.py astropy/timeseries/periodograms/lombscargle/tests/test_utils.py astropy/timeseries/tests/__init__.py astropy/timeseries/tests/test_binned.py astropy/timeseries/tests/test_common.py astropy/timeseries/tests/test_downsample.py astropy/timeseries/tests/test_sampled.py astropy/timeseries/tests/data/binned.csv astropy/timeseries/tests/data/sampled.csv astropy/uncertainty/__init__.py astropy/uncertainty/core.py astropy/uncertainty/distributions.py astropy/uncertainty/tests/__init__.py astropy/uncertainty/tests/test_distribution.py astropy/units/__init__.py astropy/units/_typing.py astropy/units/astrophys.py astropy/units/cds.py astropy/units/cgs.py astropy/units/core.py astropy/units/decorators.py astropy/units/deprecated.py astropy/units/equivalencies.py astropy/units/imperial.py astropy/units/misc.py astropy/units/photometric.py astropy/units/physical.py astropy/units/quantity.py astropy/units/required_by_vounit.py astropy/units/si.py astropy/units/structured.py astropy/units/utils.py astropy/units/format/__init__.py astropy/units/format/base.py astropy/units/format/cds.py astropy/units/format/cds_lextab.py astropy/units/format/cds_parsetab.py astropy/units/format/console.py astropy/units/format/fits.py astropy/units/format/generic.py astropy/units/format/generic_lextab.py astropy/units/format/generic_parsetab.py astropy/units/format/latex.py astropy/units/format/ogip.py astropy/units/format/ogip_lextab.py astropy/units/format/ogip_parsetab.py astropy/units/format/unicode_format.py astropy/units/format/utils.py astropy/units/format/vounit.py astropy/units/function/__init__.py astropy/units/function/core.py astropy/units/function/logarithmic.py astropy/units/function/mixin.py astropy/units/function/units.py astropy/units/quantity_helper/__init__.py astropy/units/quantity_helper/converters.py astropy/units/quantity_helper/erfa.py astropy/units/quantity_helper/function_helpers.py astropy/units/quantity_helper/helpers.py astropy/units/quantity_helper/scipy_special.py astropy/units/tests/__init__.py astropy/units/tests/test_aliases.py astropy/units/tests/test_deprecated.py astropy/units/tests/test_equivalencies.py astropy/units/tests/test_format.py astropy/units/tests/test_logarithmic.py astropy/units/tests/test_photometric.py astropy/units/tests/test_physical.py astropy/units/tests/test_quantity.py astropy/units/tests/test_quantity_annotations.py astropy/units/tests/test_quantity_array_methods.py astropy/units/tests/test_quantity_decorator.py astropy/units/tests/test_quantity_helpers.py astropy/units/tests/test_quantity_non_ufuncs.py astropy/units/tests/test_quantity_typing.py astropy/units/tests/test_quantity_ufuncs.py astropy/units/tests/test_structured.py astropy/units/tests/test_structured_erfa_ufuncs.py astropy/units/tests/test_units.py astropy/units/tests/test_utils.py astropy/utils/__init__.py astropy/utils/argparse.py astropy/utils/codegen.py astropy/utils/collections.py astropy/utils/console.py astropy/utils/data.py astropy/utils/data_info.py astropy/utils/decorators.py astropy/utils/diff.py astropy/utils/exceptions.py astropy/utils/introspection.py astropy/utils/metadata.py astropy/utils/misc.py astropy/utils/parsing.py astropy/utils/setup_package.py astropy/utils/shapes.py astropy/utils/state.py astropy/utils/compat/__init__.py astropy/utils/compat/misc.py astropy/utils/compat/numpycompat.py astropy/utils/compat/optional_deps.py astropy/utils/iers/__init__.py astropy/utils/iers/iers.py astropy/utils/iers/data/Leap_Second.dat astropy/utils/iers/data/ReadMe.eopc04_IAU2000 astropy/utils/iers/data/ReadMe.finals2000A astropy/utils/iers/data/eopc04_IAU2000.62-now astropy/utils/iers/data/update_builtin_iers.sh astropy/utils/iers/tests/__init__.py astropy/utils/iers/tests/test_iers.py astropy/utils/iers/tests/test_leap_second.py astropy/utils/iers/tests/data/finals2000A-2016-02-30-test astropy/utils/iers/tests/data/finals2000A-2016-04-30-test astropy/utils/iers/tests/data/iers_a_excerpt astropy/utils/iers/tests/data/leap-seconds.list astropy/utils/masked/__init__.py astropy/utils/masked/core.py astropy/utils/masked/function_helpers.py astropy/utils/masked/tests/__init__.py astropy/utils/masked/tests/test_containers.py astropy/utils/masked/tests/test_function_helpers.py astropy/utils/masked/tests/test_functions.py astropy/utils/masked/tests/test_masked.py astropy/utils/masked/tests/test_table.py astropy/utils/src/compiler.c astropy/utils/tests/__init__.py astropy/utils/tests/test_codegen.py astropy/utils/tests/test_collections.py astropy/utils/tests/test_console.py astropy/utils/tests/test_data.py astropy/utils/tests/test_data_info.py astropy/utils/tests/test_decorators.py astropy/utils/tests/test_diff.py astropy/utils/tests/test_introspection.py astropy/utils/tests/test_metadata.py astropy/utils/tests/test_misc.py astropy/utils/tests/test_parsing.py astropy/utils/tests/test_progress_bar_func.py astropy/utils/tests/test_shapes.py astropy/utils/tests/test_state.py astropy/utils/tests/test_xml.py astropy/utils/tests/data/.hidden_file.txt astropy/utils/tests/data/alias.cfg astropy/utils/tests/data/local.dat astropy/utils/tests/data/local.dat.bz2 astropy/utils/tests/data/local.dat.gz astropy/utils/tests/data/local.dat.xz astropy/utils/tests/data/unicode.txt astropy/utils/tests/data/unicode.txt.bz2 astropy/utils/tests/data/unicode.txt.gz astropy/utils/tests/data/unicode.txt.xz astropy/utils/tests/data/dataurl/index.html astropy/utils/tests/data/dataurl_mirror/index.html astropy/utils/tests/data/test_package/__init__.py astropy/utils/tests/data/test_package/data/foo.txt astropy/utils/xml/__init__.py astropy/utils/xml/check.py astropy/utils/xml/iterparser.py astropy/utils/xml/setup_package.py astropy/utils/xml/unescaper.py astropy/utils/xml/validate.py astropy/utils/xml/writer.py astropy/utils/xml/src/.gitignore astropy/utils/xml/src/expat_config.h astropy/utils/xml/src/iterparse.c astropy/utils/xml/src/iterparse.map astropy/utils/xml/tests/__init__.py astropy/utils/xml/tests/test_iterparse.py astropy/visualization/__init__.py astropy/visualization/hist.py astropy/visualization/interval.py astropy/visualization/lupton_rgb.py astropy/visualization/mpl_normalize.py astropy/visualization/mpl_style.py astropy/visualization/stretch.py astropy/visualization/time.py astropy/visualization/transform.py astropy/visualization/units.py astropy/visualization/scripts/__init__.py astropy/visualization/scripts/fits2bitmap.py astropy/visualization/scripts/tests/__init__.py astropy/visualization/scripts/tests/test_fits2bitmap.py astropy/visualization/tests/__init__.py astropy/visualization/tests/test_histogram.py astropy/visualization/tests/test_interval.py astropy/visualization/tests/test_lupton_rgb.py astropy/visualization/tests/test_norm.py astropy/visualization/tests/test_stretch.py astropy/visualization/tests/test_time.py astropy/visualization/tests/test_units.py astropy/visualization/wcsaxes/__init__.py astropy/visualization/wcsaxes/axislabels.py astropy/visualization/wcsaxes/coordinate_helpers.py astropy/visualization/wcsaxes/coordinate_range.py astropy/visualization/wcsaxes/coordinates_map.py astropy/visualization/wcsaxes/core.py astropy/visualization/wcsaxes/formatter_locator.py astropy/visualization/wcsaxes/frame.py astropy/visualization/wcsaxes/grid_paths.py astropy/visualization/wcsaxes/patches.py astropy/visualization/wcsaxes/ticklabels.py astropy/visualization/wcsaxes/ticks.py astropy/visualization/wcsaxes/transforms.py astropy/visualization/wcsaxes/utils.py astropy/visualization/wcsaxes/wcsapi.py astropy/visualization/wcsaxes/tests/__init__.py astropy/visualization/wcsaxes/tests/test_coordinate_helpers.py astropy/visualization/wcsaxes/tests/test_display_world_coordinates.py astropy/visualization/wcsaxes/tests/test_formatter_locator.py astropy/visualization/wcsaxes/tests/test_frame.py astropy/visualization/wcsaxes/tests/test_grid_paths.py astropy/visualization/wcsaxes/tests/test_images.py astropy/visualization/wcsaxes/tests/test_misc.py astropy/visualization/wcsaxes/tests/test_transform_coord_meta.py astropy/visualization/wcsaxes/tests/test_transforms.py astropy/visualization/wcsaxes/tests/test_utils.py astropy/visualization/wcsaxes/tests/test_wcsapi.py astropy/visualization/wcsaxes/tests/data/2MASS_k_header astropy/visualization/wcsaxes/tests/data/cube_header astropy/visualization/wcsaxes/tests/data/msx_header astropy/visualization/wcsaxes/tests/data/rosat_header astropy/visualization/wcsaxes/tests/data/slice_header astropy/wcs/__init__.py astropy/wcs/docstrings.py astropy/wcs/setup_package.py astropy/wcs/utils.py astropy/wcs/wcs.py astropy/wcs/wcslint.py astropy/wcs/include/.gitignore astropy/wcs/include/astropy_wcs_api.h astropy/wcs/include/wcsconfig.h astropy/wcs/include/astropy_wcs/astropy_wcs.h astropy/wcs/include/astropy_wcs/astropy_wcs_api.h astropy/wcs/include/astropy_wcs/distortion.h astropy/wcs/include/astropy_wcs/distortion_wrap.h astropy/wcs/include/astropy_wcs/docstrings.h astropy/wcs/include/astropy_wcs/isnan.h astropy/wcs/include/astropy_wcs/pipeline.h astropy/wcs/include/astropy_wcs/pyutil.h astropy/wcs/include/astropy_wcs/sip.h astropy/wcs/include/astropy_wcs/sip_wrap.h astropy/wcs/include/astropy_wcs/str_list_proxy.h astropy/wcs/include/astropy_wcs/unit_list_proxy.h astropy/wcs/include/astropy_wcs/util.h astropy/wcs/include/astropy_wcs/wcsconfig.h astropy/wcs/include/astropy_wcs/wcslib_auxprm_wrap.h astropy/wcs/include/astropy_wcs/wcslib_tabprm_wrap.h astropy/wcs/include/astropy_wcs/wcslib_units_wrap.h astropy/wcs/include/astropy_wcs/wcslib_wrap.h astropy/wcs/include/astropy_wcs/wcslib_wtbarr_wrap.h astropy/wcs/include/wcslib/.empty astropy/wcs/include/wcslib/.gitignore astropy/wcs/include/wcslib/cel.h astropy/wcs/include/wcslib/lin.h astropy/wcs/include/wcslib/prj.h astropy/wcs/include/wcslib/spc.h astropy/wcs/include/wcslib/spx.h astropy/wcs/include/wcslib/tab.h astropy/wcs/include/wcslib/wcs.h astropy/wcs/include/wcslib/wcserr.h astropy/wcs/include/wcslib/wcsmath.h astropy/wcs/include/wcslib/wcsprintf.h astropy/wcs/src/.gitignore astropy/wcs/src/astropy_wcs.c astropy/wcs/src/astropy_wcs_api.c astropy/wcs/src/distortion.c astropy/wcs/src/distortion_wrap.c astropy/wcs/src/docstrings.c astropy/wcs/src/pipeline.c astropy/wcs/src/pyutil.c astropy/wcs/src/sip.c astropy/wcs/src/sip_wrap.c astropy/wcs/src/str_list_proxy.c astropy/wcs/src/unit_list_proxy.c astropy/wcs/src/util.c astropy/wcs/src/wcslib_auxprm_wrap.c astropy/wcs/src/wcslib_tabprm_wrap.c astropy/wcs/src/wcslib_wrap.c astropy/wcs/src/wcslib_wtbarr_wrap.c astropy/wcs/tests/__init__.py astropy/wcs/tests/conftest.py astropy/wcs/tests/helper.py astropy/wcs/tests/test_auxprm.py astropy/wcs/tests/test_pickle.py astropy/wcs/tests/test_profiling.py astropy/wcs/tests/test_tab.py astropy/wcs/tests/test_tabprm.py astropy/wcs/tests/test_utils.py astropy/wcs/tests/test_wcs.py astropy/wcs/tests/test_wcsprm.py astropy/wcs/tests/test_wtbarr.py astropy/wcs/tests/data/2wcses.hdr astropy/wcs/tests/data/3d_cd.hdr astropy/wcs/tests/data/chandra-pixlist-wcs.hdr astropy/wcs/tests/data/defunct_keywords.hdr astropy/wcs/tests/data/dist.fits astropy/wcs/tests/data/dist_lookup.fits.gz astropy/wcs/tests/data/dss.14.29.56-62.41.05.fits.gz astropy/wcs/tests/data/header_newlines.fits astropy/wcs/tests/data/header_with_time.fits astropy/wcs/tests/data/header_with_time_wcslib71.fits astropy/wcs/tests/data/ie6d07ujq_wcs.fits astropy/wcs/tests/data/invalid_header.hdr astropy/wcs/tests/data/irac_sip.hdr astropy/wcs/tests/data/j94f05bgq_flt.fits astropy/wcs/tests/data/locale.hdr astropy/wcs/tests/data/nonstandard_units.hdr astropy/wcs/tests/data/outside_sky.hdr astropy/wcs/tests/data/sip-broken.hdr astropy/wcs/tests/data/sip.fits astropy/wcs/tests/data/sip2.fits astropy/wcs/tests/data/siponly.hdr astropy/wcs/tests/data/sub-segfault.hdr astropy/wcs/tests/data/tab-time-last-axis.fits astropy/wcs/tests/data/too_many_pv.hdr astropy/wcs/tests/data/tpvonly.hdr astropy/wcs/tests/data/unit.hdr astropy/wcs/tests/data/validate.5.0.txt astropy/wcs/tests/data/validate.5.13.txt astropy/wcs/tests/data/validate.6.txt astropy/wcs/tests/data/validate.7.4.txt astropy/wcs/tests/data/validate.7.6.txt astropy/wcs/tests/data/validate.fits astropy/wcs/tests/data/validate.txt astropy/wcs/tests/data/zpn-hole.hdr astropy/wcs/tests/data/maps/1904-66_AIR.hdr astropy/wcs/tests/data/maps/1904-66_AIT.hdr astropy/wcs/tests/data/maps/1904-66_ARC.hdr astropy/wcs/tests/data/maps/1904-66_AZP.hdr astropy/wcs/tests/data/maps/1904-66_BON.hdr astropy/wcs/tests/data/maps/1904-66_CAR.hdr astropy/wcs/tests/data/maps/1904-66_CEA.hdr astropy/wcs/tests/data/maps/1904-66_COD.hdr astropy/wcs/tests/data/maps/1904-66_COE.hdr astropy/wcs/tests/data/maps/1904-66_COO.hdr astropy/wcs/tests/data/maps/1904-66_COP.hdr astropy/wcs/tests/data/maps/1904-66_CSC.hdr astropy/wcs/tests/data/maps/1904-66_CYP.hdr astropy/wcs/tests/data/maps/1904-66_HPX.hdr astropy/wcs/tests/data/maps/1904-66_MER.hdr astropy/wcs/tests/data/maps/1904-66_MOL.hdr astropy/wcs/tests/data/maps/1904-66_NCP.hdr astropy/wcs/tests/data/maps/1904-66_PAR.hdr astropy/wcs/tests/data/maps/1904-66_PCO.hdr astropy/wcs/tests/data/maps/1904-66_QSC.hdr astropy/wcs/tests/data/maps/1904-66_SFL.hdr astropy/wcs/tests/data/maps/1904-66_SIN.hdr astropy/wcs/tests/data/maps/1904-66_STG.hdr astropy/wcs/tests/data/maps/1904-66_SZP.hdr astropy/wcs/tests/data/maps/1904-66_TAN.hdr astropy/wcs/tests/data/maps/1904-66_TSC.hdr astropy/wcs/tests/data/maps/1904-66_ZEA.hdr astropy/wcs/tests/data/maps/1904-66_ZPN.hdr astropy/wcs/tests/data/spectra/orion-freq-1.hdr astropy/wcs/tests/data/spectra/orion-freq-4.hdr astropy/wcs/tests/data/spectra/orion-velo-1.hdr astropy/wcs/tests/data/spectra/orion-velo-4.hdr astropy/wcs/tests/data/spectra/orion-wave-1.hdr astropy/wcs/tests/data/spectra/orion-wave-4.hdr astropy/wcs/wcsapi/__init__.py astropy/wcs/wcsapi/conftest.py astropy/wcs/wcsapi/fitswcs.py astropy/wcs/wcsapi/high_level_api.py astropy/wcs/wcsapi/high_level_wcs_wrapper.py astropy/wcs/wcsapi/low_level_api.py astropy/wcs/wcsapi/sliced_low_level_wcs.py astropy/wcs/wcsapi/utils.py astropy/wcs/wcsapi/data/ucds.txt astropy/wcs/wcsapi/tests/__init__.py astropy/wcs/wcsapi/tests/test_fitswcs.py astropy/wcs/wcsapi/tests/test_high_level_api.py astropy/wcs/wcsapi/tests/test_high_level_wcs_wrapper.py astropy/wcs/wcsapi/tests/test_low_level_api.py astropy/wcs/wcsapi/tests/test_utils.py astropy/wcs/wcsapi/wrappers/__init__.py astropy/wcs/wcsapi/wrappers/base.py astropy/wcs/wcsapi/wrappers/sliced_wcs.py astropy/wcs/wcsapi/wrappers/tests/__init__.py astropy/wcs/wcsapi/wrappers/tests/test_sliced_wcs.py cextern/.gitignore cextern/README.rst cextern/trim_cfitsio.sh cextern/trim_expat.sh cextern/trim_wcslib.sh cextern/cfitsio/License.txt cextern/cfitsio/README.txt cextern/cfitsio/docs/changes.txt cextern/cfitsio/lib/buffers.c cextern/cfitsio/lib/cfileio.c cextern/cfitsio/lib/checksum.c cextern/cfitsio/lib/drvrfile.c cextern/cfitsio/lib/drvrmem.c cextern/cfitsio/lib/drvrnet.c cextern/cfitsio/lib/drvrsmem.c cextern/cfitsio/lib/drvrsmem.h cextern/cfitsio/lib/editcol.c cextern/cfitsio/lib/edithdu.c cextern/cfitsio/lib/eval_defs.h cextern/cfitsio/lib/eval_f.c cextern/cfitsio/lib/eval_l.c cextern/cfitsio/lib/eval_tab.h cextern/cfitsio/lib/eval_y.c cextern/cfitsio/lib/fits_hcompress.c cextern/cfitsio/lib/fits_hdecompress.c cextern/cfitsio/lib/fitscore.c cextern/cfitsio/lib/fitsio.h cextern/cfitsio/lib/fitsio2.h cextern/cfitsio/lib/getcol.c cextern/cfitsio/lib/getcolb.c cextern/cfitsio/lib/getcold.c cextern/cfitsio/lib/getcole.c cextern/cfitsio/lib/getcoli.c cextern/cfitsio/lib/getcolj.c cextern/cfitsio/lib/getcolk.c cextern/cfitsio/lib/getcoll.c cextern/cfitsio/lib/getcols.c cextern/cfitsio/lib/getcolsb.c cextern/cfitsio/lib/getcolui.c cextern/cfitsio/lib/getcoluj.c cextern/cfitsio/lib/getcoluk.c cextern/cfitsio/lib/getkey.c cextern/cfitsio/lib/group.c cextern/cfitsio/lib/group.h cextern/cfitsio/lib/grparser.c cextern/cfitsio/lib/grparser.h cextern/cfitsio/lib/histo.c cextern/cfitsio/lib/imcompress.c cextern/cfitsio/lib/iraffits.c cextern/cfitsio/lib/longnam.h cextern/cfitsio/lib/modkey.c cextern/cfitsio/lib/pliocomp.c cextern/cfitsio/lib/putcol.c cextern/cfitsio/lib/putcolb.c cextern/cfitsio/lib/putcold.c cextern/cfitsio/lib/putcole.c cextern/cfitsio/lib/putcoli.c cextern/cfitsio/lib/putcolj.c cextern/cfitsio/lib/putcolk.c cextern/cfitsio/lib/putcoll.c cextern/cfitsio/lib/putcols.c cextern/cfitsio/lib/putcolsb.c cextern/cfitsio/lib/putcolu.c cextern/cfitsio/lib/putcolui.c cextern/cfitsio/lib/putcoluj.c cextern/cfitsio/lib/putcoluk.c cextern/cfitsio/lib/putkey.c cextern/cfitsio/lib/quantize.c cextern/cfitsio/lib/region.c cextern/cfitsio/lib/region.h cextern/cfitsio/lib/ricecomp.c cextern/cfitsio/lib/scalnull.c cextern/cfitsio/lib/simplerng.c cextern/cfitsio/lib/simplerng.h cextern/cfitsio/lib/swapproc.c cextern/cfitsio/lib/wcssub.c cextern/cfitsio/lib/wcsutil.c cextern/cfitsio/lib/zcompress.c cextern/cfitsio/lib/zuncompress.c cextern/cfitsio/zlib/adler32.c cextern/cfitsio/zlib/crc32.c cextern/cfitsio/zlib/crc32.h cextern/cfitsio/zlib/deflate.c cextern/cfitsio/zlib/deflate.h cextern/cfitsio/zlib/infback.c cextern/cfitsio/zlib/inffast.c cextern/cfitsio/zlib/inffast.h cextern/cfitsio/zlib/inffixed.h cextern/cfitsio/zlib/inflate.c cextern/cfitsio/zlib/inflate.h cextern/cfitsio/zlib/inftrees.c cextern/cfitsio/zlib/inftrees.h cextern/cfitsio/zlib/trees.c cextern/cfitsio/zlib/trees.h cextern/cfitsio/zlib/uncompr.c cextern/cfitsio/zlib/zconf.h cextern/cfitsio/zlib/zlib.h cextern/cfitsio/zlib/zutil.c cextern/cfitsio/zlib/zutil.h cextern/expat/.gitignore cextern/expat/AUTHORS cextern/expat/COPYING cextern/expat/Changes cextern/expat/README.md cextern/expat/README.txt cextern/expat/expat_config.h cextern/expat/expat_config.h.in cextern/expat/lib/.gitignore cextern/expat/lib/Makefile.am cextern/expat/lib/Makefile.in cextern/expat/lib/ascii.h cextern/expat/lib/asciitab.h cextern/expat/lib/expat.h cextern/expat/lib/expat_external.h cextern/expat/lib/iasciitab.h cextern/expat/lib/internal.h cextern/expat/lib/latin1tab.h cextern/expat/lib/libexpat.def cextern/expat/lib/libexpatw.def cextern/expat/lib/nametab.h cextern/expat/lib/siphash.h cextern/expat/lib/utf8tab.h cextern/expat/lib/winconfig.h cextern/expat/lib/xmlparse.c cextern/expat/lib/xmlrole.c cextern/expat/lib/xmlrole.h cextern/expat/lib/xmltok.c cextern/expat/lib/xmltok.h cextern/expat/lib/xmltok_impl.c cextern/expat/lib/xmltok_impl.h cextern/expat/lib/xmltok_ns.c cextern/wcslib/CHANGES cextern/wcslib/COPYING cextern/wcslib/COPYING.LESSER cextern/wcslib/GNUmakefile cextern/wcslib/INSTALL cextern/wcslib/README cextern/wcslib/THANKS cextern/wcslib/VALIDATION cextern/wcslib/configure cextern/wcslib/configure.ac cextern/wcslib/flavours cextern/wcslib/makedefs.in cextern/wcslib/wcsconfig.h.in cextern/wcslib/wcsconfig_f77.h.in cextern/wcslib/wcsconfig_tests.h.in cextern/wcslib/wcsconfig_utils.h.in cextern/wcslib/wcslib.pc.in cextern/wcslib/C/GNUmakefile cextern/wcslib/C/cel.c cextern/wcslib/C/cel.h cextern/wcslib/C/dis.c cextern/wcslib/C/dis.h cextern/wcslib/C/fitshdr.h cextern/wcslib/C/fitshdr.l cextern/wcslib/C/getwcstab.c cextern/wcslib/C/getwcstab.h cextern/wcslib/C/lin.c cextern/wcslib/C/lin.h cextern/wcslib/C/log.c cextern/wcslib/C/log.h cextern/wcslib/C/prj.c cextern/wcslib/C/prj.h cextern/wcslib/C/spc.c cextern/wcslib/C/spc.h cextern/wcslib/C/sph.c cextern/wcslib/C/sph.h cextern/wcslib/C/spx.c cextern/wcslib/C/spx.h cextern/wcslib/C/tab.c cextern/wcslib/C/tab.h cextern/wcslib/C/wcs.c cextern/wcslib/C/wcs.h cextern/wcslib/C/wcsbth.l cextern/wcslib/C/wcserr.c cextern/wcslib/C/wcserr.h cextern/wcslib/C/wcsfix.c cextern/wcslib/C/wcsfix.h cextern/wcslib/C/wcshdr.c cextern/wcslib/C/wcshdr.h cextern/wcslib/C/wcslib.h cextern/wcslib/C/wcsmath.h cextern/wcslib/C/wcspih.l cextern/wcslib/C/wcsprintf.c cextern/wcslib/C/wcsprintf.h cextern/wcslib/C/wcstrig.c cextern/wcslib/C/wcstrig.h cextern/wcslib/C/wcsulex.l cextern/wcslib/C/wcsunits.c cextern/wcslib/C/wcsunits.h cextern/wcslib/C/wcsutil.c cextern/wcslib/C/wcsutil.h cextern/wcslib/C/wcsutrn.l cextern/wcslib/C/wtbarr.h cextern/wcslib/C/flexed/README cextern/wcslib/C/flexed/fitshdr.c cextern/wcslib/C/flexed/wcsbth.c cextern/wcslib/C/flexed/wcspih.c cextern/wcslib/C/flexed/wcsulex.c cextern/wcslib/C/flexed/wcsutrn.c cextern/wcslib/config/config.guess cextern/wcslib/config/config.sub cextern/wcslib/config/install-sh docs/Makefile docs/_pkgtemplate.rst docs/changelog.rst docs/common_links.txt docs/conf.py docs/conftest.py docs/credits.rst docs/getting_started.rst docs/glossary.rst docs/importing_astropy.rst docs/index.rst docs/install.rst docs/known_issues.rst docs/license.rst docs/logging.rst docs/lts_policy.rst docs/make.bat docs/nitpick-exceptions docs/overview.rst docs/robots.txt docs/testhelpers.rst docs/warnings.rst docs/_static/astropy_banner.svg docs/_static/astropy_banner_96.png docs/_static/astropy_logo.pdf docs/_templates/layout.html docs/changes/README.rst docs/changes/template.rst docs/changes/config/.gitkeep docs/changes/constants/.gitkeep docs/changes/convolution/.gitkeep docs/changes/coordinates/.gitkeep docs/changes/cosmology/.gitkeep docs/changes/extern/.gitkeep docs/changes/io.ascii/.gitkeep docs/changes/io.fits/.gitkeep docs/changes/io.misc/.gitkeep docs/changes/io.registry/.gitkeep docs/changes/io.votable/.gitkeep docs/changes/modeling/.gitkeep docs/changes/nddata/.gitkeep docs/changes/samp/.gitkeep docs/changes/stats/.gitkeep docs/changes/table/.gitkeep docs/changes/tests/.gitkeep docs/changes/time/.gitkeep docs/changes/timeseries/.gitkeep docs/changes/uncertainty/.gitkeep docs/changes/units/.gitkeep docs/changes/utils/.gitkeep docs/changes/visualization/.gitkeep docs/changes/wcs/.gitkeep docs/config/astropy_config.rst docs/config/index.rst docs/constants/index.rst docs/constants/performance.inc.rst docs/convolution/index.rst docs/convolution/kernels.rst docs/convolution/non_normalized_kernels.rst docs/convolution/performance.inc.rst docs/convolution/using.rst docs/convolution/images/astropy.png docs/convolution/images/original.png docs/convolution/images/scipy.png docs/coordinates/angles.rst docs/coordinates/apply_space_motion.rst docs/coordinates/common_errors.rst docs/coordinates/definitions.rst docs/coordinates/formatting.rst docs/coordinates/frames.rst docs/coordinates/galactocentric.rst docs/coordinates/index.rst docs/coordinates/inplace.rst docs/coordinates/matchsep.rst docs/coordinates/performance.inc.rst docs/coordinates/remote_methods.rst docs/coordinates/representations.rst docs/coordinates/satellites.rst docs/coordinates/skycoord.rst docs/coordinates/solarsystem.rst docs/coordinates/spectralcoord.rst docs/coordinates/transforming.rst docs/coordinates/velocities.rst docs/cosmology/dev.rst docs/cosmology/index.rst docs/cosmology/io.rst docs/cosmology/units.rst docs/development/astropy-package-template.rst docs/development/building.rst docs/development/ccython.rst docs/development/codeguide.rst docs/development/codeguide_emacs.rst docs/development/docguide.rst docs/development/docrules.rst docs/development/releasing.rst docs/development/scripts.rst docs/development/style-guide.rst docs/development/testguide.rst docs/development/vision.rst docs/development/when_to_rebase.rst docs/development/workflow/additional_git_topics.rst docs/development/workflow/branch_dropdown.png docs/development/workflow/development_workflow.rst docs/development/workflow/forking_button.png docs/development/workflow/get_devel_version.rst docs/development/workflow/git_edit_workflow_examples.rst docs/development/workflow/git_install.rst docs/development/workflow/git_links.inc docs/development/workflow/git_resources.rst docs/development/workflow/links.inc docs/development/workflow/maintainer_workflow.rst docs/development/workflow/patches.rst docs/development/workflow/pull_button.png docs/development/workflow/this_project.inc docs/development/workflow/virtual_pythons.rst docs/development/workflow/worked_example_switch_branch.png docs/io/asdf-schemas.rst docs/io/misc.rst docs/io/registry.rst docs/io/unified.rst docs/io/ascii/base_classes.rst docs/io/ascii/ecsv.rst docs/io/ascii/extension_classes.rst docs/io/ascii/fast_ascii_io.rst docs/io/ascii/fixed_width_gallery.rst docs/io/ascii/index.rst docs/io/ascii/performance.inc.rst docs/io/ascii/read.rst docs/io/ascii/references.txt docs/io/ascii/toc.txt docs/io/ascii/write.rst docs/io/fits/index.rst docs/io/fits/performance.inc.rst docs/io/fits/api/cards.rst docs/io/fits/api/diff.rst docs/io/fits/api/files.rst docs/io/fits/api/hdulists.rst docs/io/fits/api/hdus.rst docs/io/fits/api/headers.rst docs/io/fits/api/images.rst docs/io/fits/api/tables.rst docs/io/fits/api/verification.rst docs/io/fits/appendix/faq.rst docs/io/fits/appendix/header_transition.rst docs/io/fits/appendix/history.rst docs/io/fits/usage/headers.rst docs/io/fits/usage/image.rst docs/io/fits/usage/misc.rst docs/io/fits/usage/scripts.rst docs/io/fits/usage/table.rst docs/io/fits/usage/unfamiliar.rst docs/io/fits/usage/verification.rst docs/io/votable/.gitignore docs/io/votable/api_exceptions.rst docs/io/votable/index.rst docs/io/votable/performance.inc.rst docs/io/votable/references.txt docs/modeling/add-units.rst docs/modeling/compound-models.rst docs/modeling/example-fitting-constraints.rst docs/modeling/example-fitting-line.rst docs/modeling/example-fitting-model-sets.rst docs/modeling/fitting.rst docs/modeling/index.rst docs/modeling/links.inc docs/modeling/models.rst docs/modeling/new-fitter.rst docs/modeling/new-model.rst docs/modeling/parameters.rst docs/modeling/performance.rst docs/modeling/physical_models.rst docs/modeling/polynomial_models.rst docs/modeling/predef_models1D.rst docs/modeling/predef_models2D.rst docs/modeling/reference_api.rst docs/modeling/spline_models.rst docs/modeling/units.rst docs/nddata/bitmask.rst docs/nddata/ccddata.rst docs/nddata/decorator.rst docs/nddata/index.rst docs/nddata/nddata.rst docs/nddata/performance.inc.rst docs/nddata/subclassing.rst docs/nddata/utils.rst docs/nddata/examples/cutout2d_tofits.py docs/nddata/mixins/index.rst docs/nddata/mixins/ndarithmetic.rst docs/nddata/mixins/ndio.rst docs/nddata/mixins/ndslicing.rst docs/samp/advanced_embed_samp_hub.rst docs/samp/example_clients.rst docs/samp/example_hub.rst docs/samp/example_table_image.rst docs/samp/index.rst docs/samp/performance.inc.rst docs/stats/circ.rst docs/stats/index.rst docs/stats/performance.inc.rst docs/stats/ripley.rst docs/stats/robust.rst docs/table/access_table.rst docs/table/construct_table.rst docs/table/implementation_details.rst docs/table/index.rst docs/table/indexing.rst docs/table/io.rst docs/table/masking.rst docs/table/mixin_columns.rst docs/table/modify_table.rst docs/table/operations.rst docs/table/pandas.rst docs/table/performance.inc.rst docs/table/table_architecture.png docs/table/table_repr_html.png docs/table/table_row.png docs/table/table_show_in_nb.png docs/time/index.rst docs/time/performance.inc.rst docs/time/time_scale_conversion.odg docs/time/time_scale_conversion.png docs/timeseries/analysis.rst docs/timeseries/binned.csv docs/timeseries/bls.rst docs/timeseries/data_access.rst docs/timeseries/index.rst docs/timeseries/initializing.rst docs/timeseries/io.rst docs/timeseries/lombscargle.rst docs/timeseries/masking.rst docs/timeseries/pandas.rst docs/timeseries/sampled.csv docs/timeseries/times.rst docs/uncertainty/index.rst docs/uncertainty/performance.inc.rst docs/units/combining_and_defining.rst docs/units/constants_versions.rst docs/units/conversion.rst docs/units/decomposing_and_composing.rst docs/units/equivalencies.rst docs/units/format.rst docs/units/index.rst docs/units/logarithmic_units.rst docs/units/performance.inc.rst docs/units/physical_types.rst docs/units/quantity.rst docs/units/standard_units.rst docs/units/structured_units.rst docs/units/type_hints.rst docs/utils/data.rst docs/utils/iers.rst docs/utils/index.rst docs/utils/masked/index.rst docs/visualization/histogram.rst docs/visualization/index.rst docs/visualization/matplotlib_integration.rst docs/visualization/normalization.rst docs/visualization/performance.inc.rst docs/visualization/rgb.rst docs/visualization/wcsaxes/controlling_axes.rst docs/visualization/wcsaxes/custom_frames.rst docs/visualization/wcsaxes/generic_transforms.rst docs/visualization/wcsaxes/images_contours.rst docs/visualization/wcsaxes/index.rst docs/visualization/wcsaxes/initializing_axes.rst docs/visualization/wcsaxes/overlaying_coordinate_systems.rst docs/visualization/wcsaxes/overlays.rst docs/visualization/wcsaxes/slicing_datacubes.rst docs/visualization/wcsaxes/ticks_labels_grid.rst docs/wcs/example_create_imaging.rst docs/wcs/example_cube_wcs.rst docs/wcs/history.rst docs/wcs/index.rst docs/wcs/legacy_interface.rst docs/wcs/loading_from_fits.rst docs/wcs/note_sip.rst docs/wcs/performance.inc.rst docs/wcs/reference_api.rst docs/wcs/references.rst docs/wcs/references.txt docs/wcs/relax.rst docs/wcs/supported_projections.rst docs/wcs/validation.rst docs/wcs/wcsapi.rst docs/wcs/wcstools.rst docs/wcs/examples/cube_wcs.py docs/wcs/examples/from_file.py docs/wcs/examples/programmatic.py docs/whatsnew/0.1.rst docs/whatsnew/0.2.rst docs/whatsnew/0.3.rst docs/whatsnew/0.4.rst docs/whatsnew/1.0.rst docs/whatsnew/1.1.rst docs/whatsnew/1.2.rst docs/whatsnew/1.3.rst docs/whatsnew/2.0.rst docs/whatsnew/3.0.rst docs/whatsnew/3.1.rst docs/whatsnew/3.2.rst docs/whatsnew/4.0.rst docs/whatsnew/4.1.rst docs/whatsnew/4.2.rst docs/whatsnew/4.3.rst docs/whatsnew/5.0.rst docs/whatsnew/index.rst examples/README.rst examples/coordinates/README.txt examples/coordinates/plot_galactocentric-frame.py examples/coordinates/plot_obs-planning.py examples/coordinates/plot_sgr-coordinate-frame.py examples/coordinates/rv-to-gsr.py examples/io/Hs-2009-14-a-web.jpg examples/io/README.txt examples/io/create-mef.py examples/io/fits-tables.py examples/io/modify-fits-header.py examples/io/plot_fits-image.py examples/io/skip_create-large-fits.py examples/io/split-jpeg-to-fits.py examples/template/example-template.py licenses/AURA_LICENSE.rst licenses/CONFIGOBJ_LICENSE.rst licenses/DATATABLES_LICENSE.rst licenses/ERFA.rst licenses/EXPAT_LICENSE.rst licenses/JQUERY_LICENSE.rst licenses/NUMPY_LICENSE.rst licenses/PLY_LICENSE.rst licenses/PYFITS.rst licenses/PYTHON.rst licenses/README.rst licenses/WCSLIB_LICENSE.rst././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921591.0 astropy-5.0.2/astropy.egg-info/dependency_links.txt0000644000175100001710000000000100000000000021506 0ustar00vstsdocker ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921592.0 astropy-5.0.2/astropy.egg-info/entry_points.txt0000644000175100001710000000112300000000000020733 0ustar00vstsdocker[asdf_extensions] astropy = astropy.io.misc.asdf.extension:AstropyExtension astropy-asdf = astropy.io.misc.asdf.extension:AstropyAsdfExtension [console_scripts] fits2bitmap = astropy.visualization.scripts.fits2bitmap:main fitscheck = astropy.io.fits.scripts.fitscheck:main fitsdiff = astropy.io.fits.scripts.fitsdiff:main fitsheader = astropy.io.fits.scripts.fitsheader:main fitsinfo = astropy.io.fits.scripts.fitsinfo:main samp_hub = astropy.samp.hub_script:hub_script showtable = astropy.table.scripts.showtable:main volint = astropy.io.votable.volint:main wcslint = astropy.wcs.wcslint:main ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921588.0 astropy-5.0.2/astropy.egg-info/not-zip-safe0000644000175100001710000000000100000000000017666 0ustar00vstsdocker ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921592.0 astropy-5.0.2/astropy.egg-info/requires.txt0000644000175100001710000000126200000000000020041 0ustar00vstsdockernumpy>=1.18 pyerfa>=2.0 PyYAML>=3.13 packaging>=19.0 [all] scipy>=1.3 matplotlib!=3.4.0,>=3.1 certifi dask[array] h5py pyarrow>=5.0.0 beautifulsoup4 html5lib bleach pandas sortedcontainers pytz jplephem mpmath asdf>=2.9.2 bottleneck ipython>=4.2 pytest>=7.0 typing_extensions>=3.10.0.1 [docs] sphinx<4 sphinx-astropy>=1.6 pytest>=7.0 scipy>=1.3 matplotlib!=3.4.0,>=3.1 sphinx-changelog>=1.1.0 [recommended] scipy>=1.3 matplotlib!=3.4.0,>=3.1 [test] pytest>=7.0 pytest-doctestplus>=0.12 pytest-astropy>=0.9 pytest-astropy-header!=0.2.0 pytest-xdist [test_all] pytest>=7.0 pytest-doctestplus>=0.12 pytest-astropy>=0.9 pytest-xdist objgraph ipython>=4.2 coverage skyfield>=1.20 sgp4>=2.3 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921592.0 astropy-5.0.2/astropy.egg-info/top_level.txt0000644000175100001710000000001000000000000020161 0ustar00vstsdockerastropy ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/azure-pipelines.yml0000644000175100001710000001005400000000000016104 0ustar00vstsdocker# NOTE: this Azure configuration is used only for building the sdist and wheels. # It uses the OpenAstronomy azure template described in detail at # https://openastronomy-azure-pipelines.readthedocs.io/en/latest/ resources: repositories: - repository: OpenAstronomy type: github endpoint: astropy name: OpenAstronomy/azure-pipelines-templates ref: master # NOTE: for now we only use Azure Pipelines on v* branches, tags, and main # only on a cron for building the source and wheel distributions. If you want to # make changes to this configuration via a pull request, you can *temporarily* # change the pr branches include trigger to just '*' trigger: branches: include: - 'v*' - main tags: include: - 'v*' pr: branches: include: - '*' schedules: - cron: "0 0 * * *" displayName: Daily Build for Nightly Wheels branches: include: - main always: true # Build Linux wheels using manylinux1 for compatibility with old versions # of pip and old platforms. variables: CIBW_MANYLINUX_X86_64_IMAGE: manylinux2010 CIBW_MANYLINUX_I686_IMAGE: manylinux2010 CIBW_ARCHS_LINUX: "auto, aarch64" CIBW_ARCHS_MACOS: "x86_64 arm64" # Numpy 1.22 doesn't have wheels for i386, so we pin Numpy to an older version # that does - this pin can be removed once we drop support for 32-bit wheels. CIBW_TEST_REQUIRES: "numpy==1.21.*" CI: true jobs: - template: publish.yml@OpenAstronomy parameters: # FIXME: we exclude the test_data_out_of_range test since it # currently fails, see https://github.com/astropy/astropy/issues/10409 test_command: pytest -p no:warnings --astropy-header -m "not hypothesis" -k "not test_data_out_of_range and not test_wcsapi_extension" --pyargs astropy test_extras: test # NOTE: for v* tags, we auto-release to PyPI. See # https://openastronomy-azure-pipelines.readthedocs.io/en/latest/publish.html # for information on how to configure things on the Azure Pipelines side ${{ if startsWith(variables['Build.SourceBranch'], 'refs/tags/v') }}: pypi_connection_name : 'pypi_endpoint' # If the build has run on main then upload the artifacts to the nightly feed ${{ if eq(variables['Build.SourceBranchName'], 'main') }}: artifact_project : 'astropy' artifact_feed : 'nightly' remove_local_scheme: true targets: # These builds are run always, to test PRs # Only run one job on PRs, so exclude musllinux here - wheels_cp39-manylinux_x86_64 - ${{ if ne(variables['Build.Reason'], 'PullRequest') }}: - sdist # Linux wheels - wheels_cp38-manylinux_i686 - wheels_cp39-manylinux_i686 # - wheels_cp310*linux_i686 # We can't build this as PyYAML doesn't have i686 wheels for 3.10 yet so the build takes too long - wheels_cp38-manylinux_x86_64 - wheels_cp310-manylinux_x86_64 # MacOS X wheels - as noted in https://github.com/astropy/astropy/pull/12379 we deliberately # do not build universal2 wheels. Note that the arm64 wheels are not actually tested so we # rely on local manual testing of these to make sure they are ok. - wheels_cp38*macosx_x86_64 - wheels_cp39*macosx_x86_64 - wheels_cp310*macosx_x86_64 - wheels_cp38*macosx_arm64 - wheels_cp39*macosx_arm64 - wheels_cp310*macosx_arm64 # Windows wheels - wheels_cp38*win32 - wheels_cp38*win_amd64 - wheels_cp39*win32 - wheels_cp39*win_amd64 - wheels_cp310*win32 - wheels_cp310*win_amd64 # TODO: Add support for musllinux here (which seems to be new in cibuildwheel 2.2) # This seems to introduce real numerical issues # - wheels_cp38-musllinux_x86_64 # - wheels_cp39-musllinux_x86_64 # - wheels_cp310-musllinux_x86_64 # TODO: The aarch64 builds take longer than an hour to complete so get killed # - wheels_cp38-manylinux_aarch64 # - wheels_cp39-manylinux_aarch64 # - wheels_cp310-manylinux_aarch64 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2432582 astropy-5.0.2/cextern/0000755000175100001710000000000000000000000013715 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/.gitignore0000644000175100001710000000000500000000000015700 0ustar00vstsdocker!*.c ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/README.rst0000644000175100001710000000047100000000000015406 0ustar00vstsdockerExternal Packages/Libraries =========================== This directory contains C libraries included with Astropy. Note that only C libraries without python-specific code should be included in this directory. Cython or C code intended for use with Astropy or wrapper code should be in the Astropy source tree. ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2432582 astropy-5.0.2/cextern/cfitsio/0000755000175100001710000000000000000000000015355 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/License.txt0000644000175100001710000000260200000000000017500 0ustar00vstsdockerCopyright (Unpublished--all rights reserved under the copyright laws of the United States), U.S. Government as represented by the Administrator of the National Aeronautics and Space Administration. No copyright is claimed in the United States under Title 17, U.S. Code. Permission to freely use, copy, modify, and distribute this software and its documentation without fee is hereby granted, provided that this copyright notice and disclaimer of warranty appears in all copies. DISCLAIMER: THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT SHALL NASA BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, CONTRACT, TORT , OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/README.txt0000644000175100001710000000033100000000000017050 0ustar00vstsdockerNote: astropy only requires the CFITSIO library, and hence in this bundled version, we removed all other files except the required license (License.txt) and changelog (docs/changes.txt, which has the version number). ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2432582 astropy-5.0.2/cextern/cfitsio/docs/0000755000175100001710000000000000000000000016305 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/docs/changes.txt0000644000175100001710000064455600000000000020502 0ustar00vstsdocker Log of Changes Made to CFITSIO Version 4.0.0 - May 2021 - Removed separate directory for zlib/gzip code, and updated configuration to check for zlib on the user's system (required). When use of cURL is enabled, it may also pull in zlib such that user applications may not need to link with it separately. - Changed version numbering to 3-field format. - Added new calculator functions SETNULL(x,y) to allow substitution of NULL values into tables, and GTIOVERLAP() for calculating the amount of GTI overlap exposure for a time bin. - Fix added for proper handling of string columns with zero repeat count. - Fix to column filtering expressions which write #NULL values to columns of type (J) format. - Fix to memory clearing when using polygon shapes in region files. - Fix to fits_str2time function so that it now flags a particular case of bad syntax which was previously getting through. - In ffgclb and ffpclb (read/write byte columns), the "undocumented" feature of being able to transfer columns 'A' string columnss as byte arrays is now handled correctly, with improved error checking via updates to ffgcprll. More documentation on string handling is in cfitsio.tex. - Fix bug in 'colfilter' functionality. When performing a column deletion of the form -COLNAM*, and multiple matches existed, then none of the matches got deleted. Now the first is deleted as expected. - Improved handling of corner case in ffpkn functions. - In ffgky, modified TULONG case to allow it to read unsigned values greater than the 8-byte signed limit. - Fix to parsing of corner case of extended file syntax. - Major updates to CMake configuration. Version 3.49 - Aug 2020 - Fix to imcompress.c. It now turns off quantization if ZSCALE and ZZERO columns are missing. Treatment will be the same as if ZQUANTIZ were set to 'NONE', even if ZQUANTIZ is present and set to something else. - Added mutex to fits_execute_template() function so that the creation of files using ASCII templates will be thread safe. - In fpack when using -table flag, replaced warning message with a more detailed description mentioning FITS format update. - Added flag to CMake builds to disable curl dependency. Also only add CURL_LIBRARIES to CMake link target if curl is found. - Minor adjustment to download progress output. Version 3.48 - Mar 2020 - Now can handle parentheses in path names rather than automatically interpreting them as output file specifiers. - Fixed bug in imcompress.c that wasn't properly handling conversion between float and double types when reading from a gzip compressed float or double image. - Fixed bug that was preventing use of bracket and parentheses symbols in pathnames when opening multiple READWRITE files, even when requesting no-extended-syntax usage. *This fix necessitates a library interface version number change. - Fixed bug in ffmnhd / fits_movnam_hdu to properly handle wildcard syntax. - Fixed bug in fits_open_extlist to handle filename[EXT] syntax properly. The hdutype parameter may now be null. More documentaion for this function is in cfitsio.tex. - Added new function fits_copy_hdutab to create a new table with the same structure as an existing table. - fits_copy_col / ffcpcl handles long long integer data types more natively to prevent precision loss. - histo.c routines now recognize integer columns that have been scaled by TSCALn keywords and may be closer to floating point type. - Added backward compatibility for very old Rice compressed files which were not using the ZVAL2 keyword in the way that later became standard. - Change made to cfitsio.pc.in to prevent forcing downstream libraries to link against cfitsio's dependencies when using pkgconfig. Version 3.47 - May 2019 - Added set of drivers for performing ftps file transfers. - Tile sizes for compression may now be specified for any pair of axes, where previously 2D tiles where limited to just X and y. - Fix to ffgsky and ffgkls functions for case of keyword with long string values where the final CONTINUE statement ended with '&'. If the final CONTINUE also contained a comment, it was being repeated twice when passed back through the 'comm' argument. - Fix made to ffedit_columns() for case of multiple col filters containing wildcards. Only the first filter was being searched. - fits_copy_rows (ffcprw) can now handle 'P'-type variable-length columns. - Fix made to an obscure case in fits_modify_vector_len, where a wrongly issued EOF error may occur. - Added internal fffvcl() function. Version 3.46 - Oct 2018 (Ftools release) - Improved the algorithm for ensuring no tile dimensions are smaller than 4 pixels for HCOMPRESS compression. - Added new functions intended to assist in diagnosing (primarily https) download issues: fits_show_download_progress, fits_get_timeout, fits_set_timeout. - Added the '-O ' option to fpack, which previously existed only for funpack. Also added fpack/funpack auto-removal of .bz2 suffix equivalent to what existed for .gz. - For the fpack '-table' cases, warning message is now sent to stderr instead of stdout. This is to allow users to pipe the results from stdout in valid FITS format. (The warning message is otherwise placed at the start of the FITS file and therefore corrupts it.) - Fix made to the '-P' file prefix option in funpack. - Added wildcard deletion syntax for columns, i.e. -COLNAM* will delete the first matching column as always; -COLNAM*+ will delete all matching columns (or none); exact symmetry with the keyword deletion syntax. Version 3.45 - May 2018 - New support for reading and writing unsigned long long datatypes. This includes 'implicit datatype conversion' between the unsigned long long datatype and all the other datatypes. - Increased the hardcoded NMAXFILES setting for maximum number of open files from 1000 to 10000. - Bug fix to fits_calc_binning wrapper function, which wasn't filling in the returned float variables. - Fixed a parsing bug for image subsection and column binning range specifiers that was introduced in v3.44. Version 3.44 - April 2018 - This release primarily patches security vulnerabilities. We strongly encourage this upgrade, particularly for those running CFITSIO in web accessible applications. In addition, the following enhancements and fixes were made: - Enhancement to 'template' and 'colfilter' functionality. It is now possible to delete multiple keywords using wildcard syntax. See "Column and Keyword Filtering Specification" section of manual for details. - histo.c uses double precision internally for all floating point binning; new double-precision subroutines fits_calc_binningd(), fits_rebin_wcsd(), and fits_make_histd(); existing single-precision histogram functions still work but convert values to double-precision internally. - new subroutine fits_copy_cols() / ffccls() to copy multiple columns - Fix in imcompress.c for HCOMPRESS and PLIO compression of unsigned short integers. - Fix to fits_insert_card(ffikey). It had wrongly been capitalizing letters that appeared before an '=' sign on a CONTINUE line. Version 3.43 - March 2018 The NASA security team requires the following warning to all users of CFITSIO: ===== The CFITSIO open source software project contains vulnerabilities that could allow a remote, unauthenticated attacker to take control of a server running the CFITSIO software. These vulnerabilities affect all servers and products running the CFITSIO software. The CFITSIO team has released software updates to address these vulnerabilities. There are no workarounds to address these vulnerabilities. In all cases, the CFITSIO team is recommending an immediate update to resolve the issues. ===== - Fixed security vulnerabilities. - Calls to https driver functions in cfileio.c need to be macro- protected by the HAVE_NET_SERVICES variable (as are the http and ftp driver function calls). Otherwise CMake builds on native Windows will fail since drvrnet.o is left empty. - Bug fix to ffmvec function. Should be resetting a local colptr variable after making a call to ffiblk (which can reallocate Ftpr-> tableptr). Originally reported by Willem van Straten. - Ignore any attempted request to not quantize an image before compressing it if the image has integer datatype pixels. - Improved error message construction throughout CFITSIO. Version 3.42 - August 2017 (Stand-alone release) - added https support to the collection of drivers handled in cfileio.c and drvrnet.c. This also handles the case where http transfers are rerouted to https. Note that this enhancement introduces a dependency on the libcurl development package. If this package is absent, CFITSIO will still build but will not have https capability. - made fix to imcomp_init_table function in imcompress.c. It now writes ZSIMPLE keyword only to a compressed image that will be placed in the primary header. - fix made to fits_get_col_display_width for case of a vector column of strings. Version 3.42 - March 2017 (Ftools release only) - in ftp_open_network and in ftp_file_exist, added code to repeatedly attempt to make a ftp connection if the ftp server does not respond to the first request. (some ftp servers don't appear to be 100% reliable). - in drvrnet.c added many calls to 'fclose' to close unneeded files, to avoid exceeding the maximum allowed number of files that can be open at once. - made substantial changes to the ftp_checkfile and http_checkfile routines to streamline the process of checking for the existence of a .gz or .Z compressed version of the file before opening the uncompressed file (when using http or ftp to open the file). - modified the code in ftp_open_network to send "\r\n" as end-of-line characters instead of just "\n". Some ftp servers (in particular, at heasarc.gsfc.nasa.gov) now require both characters, otherwise the network connection simply hangs. - modified the http_open_network routine to handle HTTP 301 or 302 redirects to a FTP url. This is needed to support the new configuration on the heasarc HTTP server which sometimes redirects http URLS to a ftp URL. Version 3.41 - November 2016 - The change made in version 3.40 to include strings.h caused problems on Windows (and other) platforms, so this change was backed out. The reason for including it was to define the strcasecmp and strcasencmp functions, so as an alternative, new equivalent functions called fits_strcasecmp and fits_strncasecmp have been added to CFITSIO.as a substitute. All the previous calls to the str[n]casecmp functions have been changed to now call fits_str[n]casecmp. In addition, the previously defined ngp_strcasecmp function (in grparser.c) has been removed and the calls to it have been changed to fits_strcasecmp. - The speed.c utility program was changed to correctly call the gettimeofday function with a NULL second arguement. Version 3.40 - October 2016 - fixed a bug when writing long string keywords with the CONTINUE convention which caused the CONTINUE'd strings to only be 16 characters long, instead of using up all the available space in the 80-character header record. - fixed a missing 'defined' keyword in fitsio.h. - replaced all calls to strtok (which is not threadsafe) with a new ffstrtok function which internally calls the threadsafe strtok_r function. One byproduct of this change is that must also be included in several of the C source code files. - modified the ffphbn function in putkey.c to support TFORM specifiers that use lowercase 'p' (instead of uppercase) when referring to a variable-length array column. - modified the lexical parser in eval.y and eval_y.c to support bit array columns (with TFORMn = 'X') with greater than 256 elements. Fix to bitcmp function: The internal 'stream' array is now allocated dynamically rather than statically fixed at size 256. This was failing when users attempted a row filtering of a bitcol that was wider than 256X. In bitlgte, bitand, and bitor functions, replaced static stream[256] array allocation with dynamic allocation. - modified the ffiter function in putcol.c to fix a problem which could cause the iterator function to incorrectly deal with null values. This only affected TLONG type columns in cases where sizeof(long) = 8, as well as for TLONGLONG type columns. - Fix made to uncompress2mem function in zcomprss.c for case where output uncompressed file expands to over the 2^32 (4Gb) limit. It now checks for this case at the start, and implements a 4Gb paging system through the output buffer. The problem was specifically caused by the d_stream.avail_out member being of 4-byte type uInt, and thus unable to handle any memory position values above 4Gb. - fixed a bug in fpackutil.c when using the -i2f (integer to float) option in fpack to compress an integer image that is scaled with non-default values for BSCALE and BZERO. This required an additional call to ffrhdu to reset the internal structures that describe the input FITS file. - modified fits_uncompress_table in imcompress.c to silently ignore the ZTILELEN keyword value if it larger than the number of rows in the table - Tweak strcasecmp/strncasecmp ifdefs to exclude 64-bit MINGW environment, as it does not lack those functions. (eval_l.c, fitsio2.h) - CMakeLists.txt: Set M_LIB to "" for MINGW build environment (in addition to MSVC). - Makefile.in: Add *.dSYM (non-XCode gcc leftovers on Macs) to clean list. Install libs by name rather than using a wildcard. - configure: Fix rpath token usage for XCode vs. non-XCode gcc on Macs. Version 3.39 - April 2016 - added 2 new routines suggested by Eric Mandel: ffhisto3 is similar to ffhisto2, except that it does not close the original file. fits_open_extlist is similar to fits_open_data except that it opens the FITS file and then moves to the first extension in the user-input list of 'interesting' extensions. - in ffpsvc and ffprec, it is necessary to treat CONTINUE, COMMENT, HISTORY, and blank name keywords as a special case which must be treated differently from other keywords because they have no value field and, by definition, have keyword names that are strictly limited in length. - added the Fortran wrapper routines for the 2 new string keyword reading routines (FTGSKY and FTGKSL), and documented all the routines in the FITSIO and CFITSIO users guides. - in ffinttyp, added explicit initialization of the input 'negative' argument to 0. - added new routine to return the length of the keyword value string: fits_get_key_strlen / ffgksl. This is primarily intended for use with string keywords that use the CONTINUE convention to continue the value over multiple header records, but this routine can be used to get the length of the value string for any type keyword. - added new routine to read string-valued keywords: fits_read_string_key / ffgsky This routine supports normal string keywords as well as long string keywords that use the CONTINUE convention. In many cases this routine may be more convenient to use then the older fits_read_key_longstr routine. - changed the prototype of fits_register_driver in fitsio2.h so that the pointer definition argument does not have the same name as the pointer itself (to work around a bug in the pgcc compiler). - added the missing FTDTDM fortran wrapper definition to f77_wrap3.c. - modified Makefile.in and configure.in to add LDFLAGS_BIN for task linker flages, which will be the same as LDFLAGS except on newer Mac OS X where an rpath flag is added. - modified Makefile.in to add a new "make utils" command which will build fpack, funpack, cookbook, fitscopy, imcopy, smem, speed, and testprog. These programs will be installed into $prfix/bin. - fixed a bug when attempting to modify the values in a variable-length bit ("X") column in a binary table. - reinstated the ability to write HIERARCH keywords that contain characters that would not be allowed in a normal 8-character keyword name, which had been disabled in the previous release. Version 3.38 - February 2016 - CRITICAL BUG FIX: The Intel 15 and 16 compilers (and potentially other compilers) may silently produce incorrect assembly code when compiling CFITSIO with the -O2 (or higher) optimization flag. In particular, this problem could cause CFITSIO to incorrectly read the values of arrays of 32-bit integers in a FITS file (i.e., images with BITPIX = 32 or table columns with TFORM = 'J') when the array is being read into a 'long' integer array in cases where the long array elements are 8 bytes long. One way to test if a particular system is affected by this problem is to compile CFITSIO V3.37 (or earlier) with optimization enabled, and then compare the output of the testprog.c program with the testprog.out file that is distributed with CFITSIO. If there are any differences in the files, then this system might be affected by this bug. Further tests should be performed to determine the exact cause. The root cause of this problem was traced to the fact that CFITSIO was aliasing an array of 32-bit integers and an array of 64-bit integers to the same memory location in order to obtain better data I/O efficiency when reading FITS files. When CFITSIO modified the values in these arrays, it was essential that the processing be done in strict sequential order from one end of the array to the other end, as was implicit in the C code algorithm. In this case, however, the compiler adopted certain loop optimization techniques that produced assembly code that violated this assumption. Technically, the CFITSIO code violates the "strict aliasing" assumption in ANSI C99, therefore the affected CFITSIO routines have been modified so that the aliasing of different data types to the same memory location no longer occurs. - fixed problem in configure and configure.in which caused the programs that are distributed with CFITSIO (most notably, fack and funpack) to be build without using any compiler optimization options, which could make them run more slowly than expected. - in imcompress.c, fixed bug where the rowspertile variable (declared as 'long') was mistakenly declared as a TLONGLONG variable in a call to fits_write_key. This could have caused the ZTILELEN keyword to be written incorrectly in the header of tile-compressed FITS tables on systems where sizeof(long) = 4. - in imcompress.c, implemented a new set of routines that safely convert shorter integer arrays into a longer integer arrays (e.g. short to int) where both arrays are aliased to the same memory location. These special routines were needed to guard against certain compiler optimization techniques that could produce incorrect code. - modified the 4 FnNoise5_(type) routines in quantize.c to correctly count the number of non-null pixels in the input array. Previously the count could be inaccurate if the image mainly consisted of null pixels. This could have caused certain floating point image tiles to be quantized during the image compression process, when in fact the tile did not satisfy all the criteria to be safely quantized. - in imcomp_copy_comp2img, added THEAP to the list of binary table keywords that may be present in the header of a compressed image and should not be copied to the uncompressed image header. - modified fits_copy_col to check that when copying a vector column, the vector length in the output column is the same as in the input column. Also modified the code to support the case where a column is being copied to an earlier position in the same table (which shifts the input column over 1 space). - added configure option (--with-bzip2) to support reading bzip2 compressed FITS files. This also required modifications to drvrmem.c and drvrfile.c This depends on having the bzlib library installed on the local machine. This patch was submitted by Dustin Lang. - replaced calls to 'memcpy' by 'memmove' in getcolb.c, getcold.c, getcole.c, and getcoli.c to support cases where the 2 memory areas overlap. (submitted by Aurelien Jarno) - modified the FITS keyword reading and writing routines to potentially support keywords with names longer than 8-characters. This was implemented in anticipation of a new experimental FITS convention which allows longer keyword names. - in fits_quantize_double in quantize.c, test if iseed == N_RANDOM, to avoid the (unlikely) possibility of overflowing the random number array bounds. (The corresponding fits_quantize_float routine already performed this test). - in the FnNoise5_short routine in quantize.c, change the first 'if' statement from "if (nx < 5)" to "if )nx < 9)", in order to support the (very rare) case where the tile is from 5 to 8 pixels wide. Also make the same change in the 3 other similar FnNoise5_* routines. - in the qtree_bitins64 routine in fits_hdecompress.c, must declare the plane_val variable as 'LONGLONG' instead of int. This bug could have caused integer overflow errors when uncompressing integer*4 images that had been compressed with the Hcompress algorithm, but only in cases where the image contains large regions of pixels whose values are close to the maximum integer*4 value of 2**31. - in fits_hcompress.c, call the calloc function instead of malloc when allocating the signbits array, to eliminate the need to individually set each byte to zero. - in the ffinit routine, and in a couple other routines that call ffinit, initialize the *fptr input parameter to NULL, even if the input status parameter value is greater than zero. This helps prevent errors later on if that fptr value is passed to ffclos. - modified ftcopy, in edithdu.c, to only abort if status > 0 rather than if status != 0. This had caused a problem in funpack in rare circumstances. - in imcompress.c changed all the calls to ffgdes to ffgdesll, to support compressed files greater than 2.1 GB in size. - fixed bug in ffeqtyll when it is called with 4th and 5th arguments set to NULL. - in fitsio.h, added the standard C++ guard around the declaration of the function fits_read_wcstab. (reported by Tammo Jan Dijkema, Astron.) - in fitsio.h, changed the prototype variable name "zero" to "zeroval" to avoid conflict in code that uses a literal definition of 'zero' to mean 0. - tweaked Makefile.in and configure.in to use LDFLAGS instead of CFLAGS for linking, use Macros for library name, and let fpack and funpack link with shared library. - modified an 'ifdef' statement in cfileio.c to test for '__GLIBC__' instead of 'linux' when initializing support for multi-threading. - modified ffeqtyll to return an effective column data type of TDOUBLE in the case of a 'K' (64-bit integer) column that has non-integer TSCALn or TZEROn keywords. - modified ffgcls (which returns the value in a column as a formatted string) so that when reading a 'K' (TLONGLONG) column it returns a long long integer value if the column is not scaled, but returns a double floating point value if the column has non-integer TSCALn or TZEROn values. - modified fitsio.h to correctly define "OFF_T long long" when using the Borland compiler - converted the 'end of line' characters in simplerng.c file to the unix style, instead of PC DOS. - updated CMakeLists.txt CMake build file which is primarily used to build CFITSIO on Windows machines. - modified fits_get_keyclass to recognize ZQUANTIZ and ZDITHER0 as TYP_CMPRS_KEY type keywords, i.e., keywords used in tile compressed image files. - added test to see if HAVE_UNISTD_H is defined, as a condition for including unistd.h in drvrfile.c drvrnet.c, drvrsmem.c, and group.c. - modified the CMakelist.txt file to fix several issues (primarily for building CFITSIO on Windows machines).. - fixed bug when reading tile-compressed images that were compressed with the IRAF PLIO algorithm. This bug did not affect fpack or funpack, but other software that reads the compressed image could be affected. The bug would cause the data values to be offset by 32768 from the actual pixel values. Version 3.37 - 3 June 2014 - replaced the random Gaussian and Poissonian distribution functions with new code written by Craig Markwardt derived from public domain C++ functions written by John D Cook. - patched fitsio2.h to support CFITSIO on AArch64 (64-bit ARM) architecture (both big and little endian). Supplied by Marcin Juszkiewicz and Sergio Pascual Ramirez, with further update by Michel Normand. - fixed bug in fpackutil.c that caused fpack to exit prematurely if the FZALGOR directive keyword was present in the HDU header. Version 3.36 - 6 December 2013 - added 9 Dec: small change to the fileseek function in drvrfile.c to support large files > 2 GB when building CFITSIO with MinGW on Windows - reorganized the CFITSIO code directory structure; added a 'docs' subdirectory for all the documentation, and a 'zlib' directory for the zlib/gzip file compression code. - made major changes to the compression code for FITS binary table to support all types of columns, including variable-length arrays. This code is mainly used via the fpack and funpack programs. - increased the number of FITS files that can be opened as one time to 1000, as defined by NMAXFILES in fitsio2.h. - made small configuration changes to configure.in, configure, fitsio.h, and drvrfile.c to support large files (64-bit file offsets} when using the mingw-w64 compiler (provided by Benjamin Gilbert). - made small change to fits_delete_file to more completely ignore any non-zero input status value. - fixed a logic error in a 'if' test when parsing a keyword name in the ngp_keyword_is_write function in grparser.c (provided by David Binderman). - when specifying the image compression parameters as part of the compressed image file name (using the "[compress]" qualifier after the name of the file), the quantization level value, if specified, was not being recognized by the CFITSIO compression routines. The image would always be compressed with the default quantization level of 4.0, regardless of what was specified. This affected the imcopy program, and potentially other user-generated application programs that used this method to specify the compression parameters. This bug did not affect fpack or funpack. This was fixed in the imcomp_get_compressed_image_par routine in the imcompress.c file. (reported by Sean Peters) - defined a new CFITS_API macro in fitsio.h which is used to export the public symbols when building CFITSIO on Windows systems with CMake. This works in conjunction with the new Windows CMake build procedure that is described in the README.win32 file. This complete revamping of the way CFITSIO is built under Windows now supports building 64-bit versions of the library. Thanks to Daniel Kaneider (Luminance HDR Team) for providing these new CMake build procedures. - modified the way that the low-level file_create routine works when running in the Hera environment to ensure that the FITS file that is created is within the allow user data disk area. - modified fits_get_compression_type so that it does not return an error if the HDU is a normal FITS IMAGE extension, and is not a tile-compressed image. - modified the low-level ffgcl* and ffpcl* routines to ensure that they never try ro read or write more than 2**31 bytes from disk at one time, as might happen with very large images, to avoid integer overflow errors. Fix kindly provided by Fred Gutsche at NanoFocus AG (www.nanofocus.de). - modified Makefile.in so that doing 'make distclean' does not delete new config.sub and config.guess files that were recently added. - adopted a patch from Debian in zcompress.c to "define" the values of GZBUFSIZE and BUFFINCR, instead of exporting the symbols as 'int's. Version 3.35 - 26 June 2013 (1st beta release was on 24 May) - fixed problem with the default tile size when compressing images with fpack using the Hcompress algorithm. - fixed returned value ("status" instead of "*status") - in imcompress.c, declared some arrays that are used to store the dimensions of the image from 'int' to 'long', to support very large images (at least on systems where sizeof(long) = 8), - modified the routines that convert a string value to a float or double to prevent them from returning a NaN or Inf value if the string is "NaN" or "Inf" (as can happen with gcc implementation of the strtod function). - removed/replaced the use of the assert() functions when locking or unlocking threads because they did not work correctly if NDEBUG is defined. - made modifications to the way the command-line file filters are parsed to 1) remove the 1024-character limit when specifying a column filter, 2) fixed a potential character buffer-overflow risk in fits_get_token, and 3) improved the parsing logic to remove any possible of confusing 2 slash characters ("//") in the string as the beginning of a comment string. - modified configure and Makefile.in so that when building CFITSIO as a shared library on linux or Mac platforms, it will use the SONAME convention to indicate whether each new release of the CFITSIO library is binary-compatible with the previous version. Application programs that link with the shared library will not need to be recompiled as long as the versions are compatible. In practice, this means that the shared library binary file that is created (on Linux systems) will have a name like 'libcfitsio.so.I.J.K', where I is the SONAME version number, J is the major CFITSIO version number (e.g. 3), and K is the minor CFITSIO version number (e.g., 34). Two link files will also be created such that libcfitsio.so -> libcfitsio.so.I, and libcfitsio.so.I -> libcfitsio.I.J.K Application programs will still run correctly with the new version of CFITSIO as long as the 'I' version number remains the same, but the applications will fail to run if the 'I' number changes, thus alerting the user that the application must be rebuilt. - fixed bug in fits_insert_col when computing the new table row width when inserting a '1Q' variable length array column. - modified the image compression routines so that the output compressed image (stored in a FITS binary table) uses the '1Q' variable length array format (instead of '1P') when the input file is larger than 4 GB. - added support for "compression directive" keywords which indicate how that HDU should be compressed (e.g., which compression algorithm to use, what tiling pattern to use, etc.). The values of these keywords will override the compression parameters that were specified on the command line when running the fpack FITS file compression program. - globally changed the variable and/or subroutine name "dither_offset" to "dither_seed" and "quantize_dither" to "quantize_method" so that the names more accurately reflects their purpose. - added support for a new SUBTRACTIVE_DITHER_2 method when compressing floating point images. The only difference with the previous method is that pixels with a value exactly equal to 0.0 will not be dithered, and instead will be exactly preserved when the image is compressed. - added support for an alias of "RICE_ONE" for "RICE_1" as the value of the ZCMPTYPE keyword, which gives the name of the image compression algorithm. This alias is used if the new SUBTRACTIVE_DITHER_2 option is used, to prevent old versions of funpack from creating a corrupted uncompressed image file. Only newer versions of funpack will recognize this alias and be able to uncompress the image. - made performance improvement to fits_read_compressed_img so that when reading a section of an compressed image that includes only every nth pixel in some dimension, it will only uncompressed a tile if there are actually any pixels of interest in that tile. - fixed several issues with the beta FITS binary table compression code that is used by fpack: added support for zero-length vector columns, made improvements to the output report when using the -T option in fpack, changed the default table compression method to 'Rice' instead of 'Best', and now writes the 'ZTILELEN' keyword to document the number of table rows in each tile. - fixed error in ffbinit in calculating the total length of the binary table extension if the THEAP keyword was used to override the default starting location of the heap. Version 3.34 - 20 March 2013 - modified configure and configure.in to support cross-compiled cfitsio as a static library for Windows on a Linux platform using MXE (http://mxe.cc) - a build environment for mingw32. (contributed by Niels Kristian Bech Jensen) - added conditional compilation statementsfor the mingw32 environment in drvrfile.c because mingw32 does not include the ftello and fseeko functions. (contributed by Niels Kristian Bech Jensen) - fixed a potential bug in ffcpcl (routine to copy a column from one table to another table) when dealing with the rare case of a '0X' column (zero length bit column). - fixed an issue in the routines that update or modify string-valued keyword values, as a result of the change to ffc2s in the previous release. These routines would exit with a 204 error status if the current value of the keyword to be updated or modified is null. - fixed typo in the previous modification that was intended to ignore numerical overflows in Hcompress when decompressing an image. - moved the 'startcol' static variable out of the ffgcnn routine and instead added it as a member of the 'FITSfile' structure that is defined in fitsio.h. This removes a possible race condition in ffgcnn in multi-threaded environments. Version 3.33 - 14 Feb 2013 - modified the imcomp_decompress_tile routine to ignore any numerical overflows that might occur when using Hcompress to decompress the image. If Hcompress is used in its 'lossy' mode, the uncompressed image pixel values may slightly exceed the range of an integer*2 variable. This is generally of no consequence, so we can safely ignore any overflows in this case and just clip the values to the legal range. - the default tiling pattern when writing a tile-compressed image has been changed. The old behavior was to compress the whole image as one single large tile. This is often not optimal when dealing with large images, so the new default behavior is to treat each row of the image as one tile. This is the same default behavior as in the standalone fpack program. The default tile size can be overridden by calling fits_set_tile_dim. - fixed bug that resulted in a corrupted output FITS image when attempting to write a float or double array of values to a tile-compressed integer data type image. CFITSIO does not support implicit data type conversion in this case and now correctly returns an appropriate error status. - modified ricecomp.c to define the nonzero_count lookup table as an external variable, rather then dynamically allocating it within the 3 routines that use it. This simplifies the code and eliminates the need for special thread locking and unlocking statements. (Thanks to Lars Kr. Lundin for this suggestion). - modified how the uncompressed size of a gzipped file is computed in the mem_compress_open routine in drvrmem.c. Since gzip only uses 4 bytes in the compressed file header to store the original file size, one may need to apply a modulo 2^32 byte correction in some cases. The logic here was modified to allow for corner cases (e.g., very small files, and when running on 32-bit platforms that do not support files larger than 2^31 bytes in size). - added new public routine to construct a 80 keyword record from the 3 input component strings, i.e, the keyword name string, the value string, and the comment string: fits_make_key/ffmkky. (This was already an undocumented internal routine in previous versions of CFITSIO). - modified ffc2s so that if the input keyword value string is a null string, then it will return a VALUE_UNDEFINED (204) status value. This makes it consistent with the behavior when attempting to read a null keyword (which has no value) as a logical or as a number (which also returns the 204 error). This should only affect cases where the header keyword does not have an equal sign followed by a space character in columns 9 and 10 of the header record. - Changed the "char *" parameter declarations to "const char *" in many of the routines (mainly the routines that modify or update keywords) to avoid compiler warnings or errors from C++ programs that tend to be more rigorous about using "const char *" when appropriate. - added support for caching uncompressed image tiles, so that the tile does not need to be uncompressed again if the application program wants to read more data from the same tile. This required changes to the main FITS file structure that is defined in fitsio.h, as well as changes to imcompress.c. - enhanced the previous modification to drvrfile.c to handle additional user cases when running in the HEASARC's Hera environment. Version 3.32 - Oct 2012 - fixed flaw in the way logical columns (TFORM = 'L') in binary tables were read which caused an illegal value of 1 in the column to be interpreted as a 'T' (TRUE) value. - extended the column filtering syntax in the CFITSIO file name parser to enable users and scripts to append new COMMENT or HISTORY keyword into the header of the filtered file (provided by Craig Markwardt). For example, fcopy "infile.fits[col #HISTORY='Processed on 2012-10-05']" outfile.fits will append this header keyword: "HISTORY Processed on 2012-10-05" - small change to the code that opens and reads an ASCII region file to return an error if the file is empty. - fixed obscure sign propagation error when attempting to read the uncompressed size of a gzipped FITS file. This resulted in a memory allocation error if the gzipped file had an uncompressed file size between 2^31 and 2^32 bytes. Fix supplied by Gudlaugur Johannesson (Stanford). Version 3.31 - 18 July 2012 - enhanced the CFITSIO column filtering syntax to allow the comma, in addition to the semi-colon, to be used to separate clauses, for example: [col X,Y;Z = max(X,Y)]. This was done because users are not allowed to enter the semi-colon character in the on-line Hera data processing system due to computer security concerns. - enhanced the CFITSIO extended filename syntax to allow specifying image compression parameters (e.g. '[compress Rice]') when opening an existing FITS file with write access. The specified compression parameters will be used by default if more images are appended to the existing file. - modified drvrfile.c to do additional file security checks when CFITSIO is running within the HEASARC's Hera software system. In this case CFITSIO will not allow FITS files to be created outside of the user's individual Hera data directory area. - fixed an issue in fpack and funpack on Windows machines, caused by the fact that the 'rename' function behaves differently on Windows in that it does not clobber an existing file, as it does on Unix platforms. - fixed bug in the way byte-swapping was being performed when writing integer*8 null values to an image or binary table column. - added the missing macro definition for fffree to fitsio.h. - modified the low level table read and write functions in getcol*.c and putcol*.c to remove the 32-bit limitation on the number of elements. These routines now support reading and writing more than 2**31 elements at one time. Thanks to Keh-Cheng Chu (Stanford U.) for the patch. - modified Makefile.in so that the shared libcfitsio.so is linked against pthreads and libm. Version 3.30 - 11 April 2012 Enhancements - Added new routine called fits_is_reentrant which returns 1 or 0 depending on whether or not CFITSIO was compiled with the -D_REENTRANT directive. This can be used to determine if it is safe to use CFITSIO in multi-threaded programs. - Implemented much faster byte-swapping algorithms in swapproc.c based on code provided by Julian Taylor at ESO, Garching. These routines significantly improve the FITS image read and write speed (by more than a factor of 2 in some cases) on little-endian machines (e.g., Linux and Microsoft Windows and Macs running on x86 CPUs) where byte-swapping is required when reading and writing data in FITS files. This has no effect on big-endian machines (e.g. Motorola CPUs and some IBM systems). Even faster byte-swapping performance can be achieved in some cases by invoking the new "--enable-sse2" or "--enable-ssse3" configure options when building CFITSIO on machines that have CPUs and compilers that support the SSE2 and SSSE3 machine instructions. - added additional support for implicit data type conversion in cases where the floating point image has been losslessly compressed with gzip. The pixels in these compressed images can now be read back as arrays of short, int, and long integers as well as single and double precision floating-point. - modified fitsio2.h and f77_wrap.h to recognize IBM System z mainframes by testing if __s390x__ or __s390__ is defined. - small change to ffgcrd in getkey.c so that it supports reading a blank keyword (e.g., a keyword whose name simply contains 8 space characters). Bug Fixes - fixed a bug in imcomp_decompress_tile that caused the tile-compressed image to be uncompressed incorrectly (even though the tile-compressed image itself was written correctly) under the following specific conditions: - the original FITS image has a "float" datatype (R*4) - one or more of the image tiles cannot be compressed using the standard quantization method and instead are losslessly compressed with gzip - the pixels in these tiles are not all equal to zero (this bug does affect tiles where all the pixels are equal to zero) - the program that is reading the compressed image uses CFITSIO's "implicit datatype conversion" feature to read the "float" image back into an array of "double" pixel values. If all these conditions are met, then the returned pixel values in the affected image tiles will be garbage, with values often ranging up to 10**34. Note that this bug does not affect the fpack/funpack programs, because funpack does not use CFITSIO's implicit datatype conversion feature when uncompressing the image. Version 3.29 - 2 December 2011 Enhancements - modified Makefile.in to allow configure to override the lib and include destination directories. - added (or restored actually) support for tile compression of 1-byte integer images in imcomp_compress_tile. Support for that data type was overlooked during recent updates to this routine. - modified the fits_get_token command-line parsing routine to perform more rigorous checks to determine if the token can be interpreted as a number or not. - made small modification to fpack.c to not allow the -i2f option (convert image from integer to floating point) with the "-g -q 0" option (do lossless gzip compression). It is more efficient to simply use the -g option alone. - made modifications to fitsio.h and drvrfile.c to support reading and writing large FITS files (> 2.1 GB) when building CFITSIO using Microsoft Visual C++ on Windows platforms. - added new WCS routine (ffgicsa) which returns the WCS keyword values for a particular WCS version ('A' - 'Z'). Bug Fixes - fixed a problem with multi-threaded apps that open/close FITS files simultaneously by putting mutex locks around the call to fits_already_open and in fits_clear_Fptr. - fixed a bug when using the 'regfilter' function to select a subset of the rows in a FITS table that have coordinates that lie within a specified spatial region on the sky. This bug only affects the rarely used panda (and epanda and bpanda) region shapes in which the region is defined by the intersection of an annulus and a pie-shaped wedge. The previous code (starting with version 3.181 of CFITSIO where support for the panda region was first introduced) only worked correctly if the 2 angles that define the wedge have values between -180 and +180. If not, then fewer rows than expected may have been selected from the table. - fixed the extended filename parser so that when creating a histogram by binning 2 table columns, if a keyword or column name is given as the weighting factor, then the output histogram image will have a floating point datatype, not the default integer datatype as is the case when no weight is specified (e.g. with a filename like "myfile.fits[bin x,y; weight_column]" - added fix to the code in imcompress.c to work around a problem with dereferencing the value of a pointer, in cases where the address of that pointer has not been defined (e.g., the nulval variable). - modified the byte shuffling algorithm in fits_shuffle_8bytes to work around a strange bug in the proprietary SunStudioExpress C compiler under OpenSolaris. - removed spurious messages on the CFITSIO error stack when opening a FITS file with FTP (in drvrnet.c); Version 3.28 - 12 May 2011 - added an enhancement to the tiled-image compression method when compressing floating-point image using the standard (lossy) quantization method. In cases where an image tile cannot be quantized, The floating-point pixel values will be losslessly compressed with gzip before writing them to the tile- compressed file. Previously, the uncompressed pixel values would have been written to the file, which obviously requires more disk space. - made significant internal changes to the structure of the tile compression and uncompression routines in imcompress.c to make them more modular and easier to maintain. - modified configure.in and configure to force it to build a Universal binary on Mac OS X. - modified the ffiter function in putcol.c to properly clean up allocated memory if an error occurs. - in quantize.c, when searching for the min and max values in a float array, initialize the max value to -FLT_MAX instead of FLT_MIN (and similarly for double array). Version 3.27 - 3 March 2011 Enhancements - added new routines fits_read_str and fits_delete_str which read or delete, respectively, a header keyword record that contains a specified character string. - added a new routine called fits_free_memory which frees the memory that fits_read_key_longstr allocated for the long string keyword value. - enhanced the ffmkky routine in fitscore.c to not put a space before the equals sign when writing long string-valued keywords using the ESO HIERARCH keyword convention, if that extra character is needed to fit the length of the keyword name + value string within the 80-character FITS keyword record. - made small change to fits_translate_keyword to support translation of blank keywords (where the name = 8 blank characters) - modified fpack so that it uses the minimum of the 2nd, 3rd, and 5th order MAD noise values when quantizing and compressing a floating point image. This is more conservative than just using the 3rd order MAD value alone. - added new routine imcomp_copy_prime2img to imcompress.c that is used by funpack to copy any keywords that may have been added to the primary array of the compressed image file (a null image) back into the header of the uncompressed image. - enhanced the fits_quantize_float and fits_quantize_double routines in quantize.c to also compress the tile if it is completely filled with null values. Previously, this type of tile would have been written to the output compressed image without any compression. - enhanced imcomp_decompress_tile to support implicit datatype conversion when reading a losslessly compressed (with gzip) real*4 image into an array of real*8 values. - in imcompress.c, removed possible attempt to free memory that had not been allocated. Version 3.26 - 30 December 2010 Enhancements - defined 2 new macros in fitsio.h: #define CFITSIO_MAJOR 3 #define CFITSIO_MINOR 26 These may be used within other macros to detect the CFITSIO version number at compile time. - modified group.c to initialize the output URL to a null string in fits_url2relurl. Also added more robust tests to see if 2 file pointers point to the same file. - enhanced the template keyword parsing code in grparser.c to support the 'D' exponent character in the ASCII representation of floating point keyword values (as in TVAL = 1.23D03). Previously, the parser would have written this keyword with a string value (TVAL = '1.23D03'). - modified the low-level routines that write a keyword record to a FITS header so that they silently replace any illegal characters (ASCII values less than 32 or greater than 126) with an ASCII space character. Previously, these routines would have returned with an error when encountering these illegal characters in the keyword record (most commonly tab, carriage return, and line feed characters). - made substantial internal changes to imcompress.c in preparation for possible future support for compression methods for FITS tables analogous to the tiled image compression method. - replaced all the source code in CFITSIO that was distributed under the GNU General Public License with freely available code. In particular, the gzip file compression and uncompression code was replaced by the zlib compression library. Thus, beginning with this version 3.26 of CFITSIO, other software applications may freely use CFITSIO without necessarily incurring any GNU licensing requirement. See the License.txt file for the CFITSIO licensing requirements. - added support for using cfitsio in different 'locales' which use a comma, not a period, as the decimal point character in ASCII representation of a floating point number (e.g., France). This affects how floating point keyword values and floating point numbers in ASCII tables are read and written with the 'printf' and 'strtod' functions. - added a new utility routine called fits_copy_rows/ffcprw that copies a specified range of rows from one table to another. - enhanced the test for illegal ASCII characters in a header (fftrec) to print out the name of the offending character (e.g TAB or Line Feed) as well as the Hex value of the character. - modified ffgtbc (in fitscore.c) to support nonstandard vector variable length array columns in binary tables (e.g. with TFORMn = 2000PE(500)'). - modified the configure file to add "-lm" when linking CFITSIO on Solaris machines. - added new routine, fits_get_inttype, to parse an integer keyword value string and return the minimum integer datatype (TBYTE, TSHORT, TLONG, TLONGLONG) required to store the integer value. - added new routine, fits_convert_hdr2str, which is similar to fits_hdr2str except that if the input HDU is a tile compressed image (stored in a binary table) then it will first convert that header back to that of a normal uncompressed FITS image before concatenating the header keyword records. - modified the file template reading routine (ngp_line_from_file in grparser.c) so that it ignores any carriage return characters (\r) in the line, that might be present, e.g. if the file was created on a Windows machine that uses \r\n as end of line characters. - modified the ffoptplt routine in cfileio.c to check if the PCOUNT keyword in the template file has a non-zero value, and if so, resets it to zero in the newly created file. Bug Fixes - fixed a bug when uncompressing floating-point images that contain Nan values on some 64-bit platforms. - fixed a bug when updating the value of the CRPIXn world coordinate system keywords when extracting a subimage from larger FITS image, using the extended CFITSIO syntax (e.g. myimage[1:500:2, 1:500:2]). This bug only affects cases where the pixel increment value is not equal to 1, and caused the coordinate grid to be shifted by between 0.25 pixels (in the case of a pixel increment of 2) and 0.5 pixels (for large pixel increment values). - fixed a potential string buffer overflow error in the ffmkls routine that modifies the value and comment strings in a keyword that uses the HEASARC long string keyword convention. - fixed a bug in imcompress.c that could cause programs to abort on 64-bit machines when using gzip to tile-compress images. Changed the declaration of clen in imcomp_compress_tile from int to size_t. Version 3.25 - 9 June 2010 - fixed bug that was introduced in version 3.13 that broke the ability to reverse an image section along the y-axis with an image section specifier like this: myimage.fits[*,-*]. This bug caused the output image to be filled with zeros. - fixed typo in the definition of the ftgprh Fortran wrapper routine in f77_wrap3.c. - modified the cfitsio.pc.in configuration file to make the lib path a variable instead of hard coding the path. The provides more flexibility for projects such as suse and fedora when building CFITSIO. - fixed bug in imcomp_compress_tile in imcompress.c which caused null pixel values to be written incorrectly in the rare case where the floating-point tile of pixels could not be quantized into integers. - modified imcompress.c to add a new specialized routine to uncompress an input image and then write it to a output image on a tile by tile basis. This appears to be faster than the old method of uncompressing the whole image into memory before writing it out. It also supports large images with more than 2**31 pixels. - made trivial changes to 2 statements in drvrfile.c to suppress nuisance compiler warnings. - some compilers define CLOCKS_PER_SEC as a double instead of an integer, so added an explicit integer type conversion to 2 statements in imcompress.c that used this macro. - removed debugging printf statements in drvrnet.c (15 July) Version 3.24 - 26 January 2010 - modified fits_translate_keywords so that it silently ignores any illegal ASCII characters in the value or comment fields of the input FITS file. Otherwise, fpack would abort without compressing input files that contained this minor violation of the FITS rules. - added support for Super H cpu in fitsio2.h - updated funpack to correctly handle the -S option, and to use a more robust algorithm for creating temporary output files. - modified the imcomp_compress_tile routine to support the NOCOMPRESS debugging option for real*4 images. Version 3.23 - 7 January 2010 - reduced the default value for the floating point image quantization parameter (q) from 16 to 4. This parameter is used when tile compressing floating point images. This change will increase the average compression ratio for floating point images from about 4.6 to about 6.5 without losing any significant information in the image. - enhanced the template keyword parsing routine to reject a header template string that only contains a sequence of dashes. - enhanced the ASCII region file reading routine to allow tabs as well as spaces between fields in the file. - got rid of bogus error message when calling fits_update_key_longstr - Made the error message more explicit when CFITSIO tries to write to a GZIP compressed file. Instead of just stating "cannot write to a READONLY file", it will say "cannot write to a GZIP compressed file". Version 3.22 - 28 October 2009 - added an option (in imcompress.c) to losslessly compress floating point images, rather than using the default integer scaling method. This option is almost never useful in practice for astronomical images (because the amount of compression is so poor), but it has been added for test comparison purposes. - enhanced the dithering option when quantizing and compressing floating point images so that a random dithering starting point is used, so that the same dithering pattern does not get used for every image. - modified the architecture setup section of fitsio2.h to support the 64-core 8x8-architecture Tile64 platform (thanks to Ken Mighell, NOAO) Fixes - fixed a problem that was introduced in version 3.13 of CFITSIO in cases where a program writes it own END keyword to the header instead of letting CFITSIO do it, as is strongly recommended. In one case this caused CFITSIO to rewrite the END keyword and any blank fill keywords in the header many times, causing a noticeable slow-down in the FITS file writing speed. Version 3.21 - 24 September 2009 - fixed bug in cfileio.c that caused CFITSIO to crash with a bus error on Mac OS X if CFITSIO was compiled with multi-threaded support (with the --enable-reentrant configure option). The Mac requires an additional thread initialization step that is not required on Linux machines. Even with this fix, occasional bus errors have been seen on some Mac platforms, The bus errors are seen when running the thread_test.c program. The bus errors are very intermittent, and occur less than about 1% of the time, on the affected platforms. These bus errors have not been seen on Linux platforms. - fixed invalid C comment delimiter ("//*" should have been "/*") in imcompress.c. - Increased the CFITSIO version number string length in fpackutil.c, to fix problem on some platforms when running fpack -V or funpack -V. Also modified the output format of the fpack -L command. Version 3.20 - 31 August 2009 - modified configure.in and configure so that it will build the Fortran interface routines by default, even if no Fortran compiler is found in the user's path. Building the interface routines may be disabled by specifying FC="none". This was done at the request of users who obtained CFITSIO from some other standard linux distributions, where CFITSIO was apparently built in an environment that had no Fortran compiler and hence did not build the Fortran wrappers. - modified ffchdu (close HDU) so that it calls the routine to update the maximum length of variable length table columns in the TFORM values in all cases where the values may have changed. Previously it would not update the values if a value was already specified in the TFORM value. - added 2 new string manipulation functions to the CFITSIO parser (contributed by Craig Markwardt): strmid extracts a substring from a string, and strstr searches for a substring within a string. - removed the code in quantize.c that treated "floating-point integer" images as a special case (it would just do a datatype conversion from float to int, and not otherwise quantize the pixel values). This caused complications with the new subtractive dithering feature. - enhanced the code for converting floating point images to quantized scaled integer prior to tile-compressing them, to apply a random subtractive dithering, which improves the photometric accuracy of the compressed images. - added new internal routine, iraf_delete_file, for use by fpack to delete a pair of IRAF format header and pixel files. - small change in cfileio.c in the way it recognizes an IRAF format .imh file. Instead of just requiring that the filename contain the ".imh" string, that string must occur at the end of the file name. - fixed bug in the code that is used when tile-compressing real*4 FITS images, which quantizes the floating point pixel values into integer levels. The bug would only appear in the fairly rare circumstance of tile compressing a floating point image that contains null pixels (NaNs) and only when using the lossy Hcompress algorithm (with the s parameter not equal to 1). This could cause underflow of low valued pixels, causing them to appear as very large pixel values (e.g., > 10**30) in the compressed image - changed the "if defined" blocks in fitsio.h, fitsio2.h and f77_wrap.h to correctly set the length of long variables on sparc64 machines. Patch contributed by Matthew Truch (U. Penn). - modified the HTTP file access code in drvrnet.c to support basic HTTP authentication, where the user supplies a user name and password. The CFITSIO filename format in this case is: "http://username:password@hostname/..." Thanks to Jochen Liske (ESO) for the suggestion and the code. Version 3.181 (BETA) - 12 May 2009 - modified region.c and region.h to add support for additional types of region shapes that are supported by ds9: panda, epanda, and bpanda. - fixed compiler error when using the new _REENTRANT flag, having to do with the an attempted static definition of Fitsio_Lock in several source files, after declaring it to be non-static in fitsio2.h. Version 3.18 (BETA) - 10 April 2009 - Made extensive changes to make CFITSIO thread safe. Previously, all opened FITS files shared a common pool of memory to store the most recently read or written FITS records in the files. In a multi-threaded environment different threads could simultaneously read or write to this common area causing unpredictable results. This was changed so that every opened FITS file has its own private memory area for buffering the file. Most of the changes were in buffers.c, fitsio.h, and fitsio2.h. Additional changes were made to cfileio.c, mainly to put locks around small sections of code when setting up the low-level drivers to read or write the FITS file. Also, locks were needed around the GZIP compression and uncompression code in compress.c., the error message stack access routine in fitscore.c, the encode and decode routines in fits_hcompress.c and fits_hdecompress.c, in ricecomp.c, and the table row selection and table calculator functions. Also, removed the 'static' declaration of the local variables in pliocomp.c which did not appeared to be required and prevented the routines from being thread safe. As a consequence of having a separate memory buffer for every FITS file (by default, about 115 kB per file), CFITSIO may now allocate more memory than previously when an application program opens multiple FITS files at once. The read and write speed may also be slightly faster, since the buffers are not shared between files. - Added new families of Fortran wrapper routines to read and write values to large tables that have more than 2**31 rows. The arguments that define the first row and first element to read or write must be I*8 integers, not ordinary I*4 integers. The names of these new routines have 'LL' appended to them, so for example, ftgcvb becomes ftgcvbll. Fixes - Corrected an obscure bug in imcompress.c that would have incorrectly written the null values only in the rare case of writing a signed byte array that is then tile compressed using the Hcompress or PLIO algorithm. Version 3.14 - 18 March 2009 Enhancements - modified the tiled-image compression and uncompression code to support compressing unsigned 16-bit integer images with PLIO. FITS unsigned integer arrays are offset by -32768, but the PLIO algorithm does not work with negative integer values. In this case, an offset of 32768 is added to the array before compression, and then subtracted again when reading the compressed array. IMPORTANT NOTE: This change is not backward compatible, so these PLIO compressed unsigned 16-bit integer images will not be read correctly by previous versions of CFITSIO; the pixel values will have an offset of +32768. - minor changes to the fpack utility to print out more complete version information with the -V option, and format the report produced by the -T option more compactly. Fixes - Modified imcomp_compress_image (which is called by fpack) so that it will preserve any null values (NaNs) if the input image has a floating point datatype (BITPIX = -32 or -64). Null values in integer datatype images are handled correctly. - Modified imcomp_copy_comp2img so that it does not copy the ZBLANK keyword, if present, from the compressed image header when uncompressing the image. - Fixed typo in the Fortran wrapper macro for the ftexist function. Version 3.13 - 5 January 2009 Enhancements - updated the typedef of LONGLONG in fitsio.h and cfortran.h to support the Borland compiler which uses the __int64 data type. - added new feature to the extended filename syntax so that when performing a filtering operation on specified HDU, if you add a '#' character after the name or number of the HDU, then ONLY that HDU (and the primary array if the HDU is a table) will be copied into the filtered version of the file in memory. Otherwise, by default CFITSIO copies all the HDUs from the input file into memory. - when specifying a section, if the specified number of dimensions is less than the number of dimensions in the image, then CFITSIO will use the entire dimension, as if a '*' had been specified. Thus [1:100] is equivalent to [1:100,*] when specifying a section of 2 dimensional image. - modified fits_copy_image_section to read/write the section 1 row at a time, instead of the whole section, to reduce memory usage. - added new stream:// drivers for reading/writing to stdin/stdout. This driver is somewhat fragile, but for simple FITS read and write operations this driver streams the FITS file on stdin or stdout without first copying the entire file in memory, as is done when specifying the file name as "-". - slight modification to ffcopy to make sure that the END keyword is correctly written before copying the data. This is required by the new stream driver. - modified ffgcprll, so that when writing data to an HDU, it first checks that the END keyword has been written to the correct place. This is required by the new stream driver. Fixes - fixed bug in ffgcls2 when reading an ASCII string column in binary tables in cases where the width of the column is greater than 2880 characters and when reading more than 1 row at a time. Similar change was made to ffpcls to fix same problem with writing to columns wider than 2880 characters. - updated the source files listed in makepc.bat so that it can be used to build CFITSIO with the Borland C++ compiler. - fixed overflow error in ffiblk that could cause writing to Large Files (> 2.1 GB) to fail with an error status. - fixed a bug in the spatial region code (region.c) with the annulus region. This bug only affected specialized applications which directly use the internal region structure; it does not affect any CFITSIO functions directly. - fixed memory corruption bug in region.c that was triggered if the region file contained a large number of excluded regions. - got rid of a harmless error message that would appear if filtering a FITS table with a GTI file that has zero rows. (eval_f.c) - modified fits_read_rgnfile so that it removes the error messages from the error stack if it is unable to open the region file as a FITS file. (region.c) Version 3.12 - 8 October 2008 - modified the histogramming code so that the first pixel in the binned array is chosen as the reference pixel by default, if no other value is previously defined. - modified ffitab and ffibin to allow a null pointer to the EXTNAME string, when inserting a table with no name. Version 3.11 - 19 September 2008 - optimized the code when tile compressing real*4 images (which get scaled to integers). This produced a modest speed increase. For best performance, one must specify the absolute q quantization parameter, rather than relative to the noise in the tile (which is expensive to compute). - modified the FITS region file reading code to check for NaN values, which signify the end of the array of points in a polygon region. - removed the test for LONGSIZE == 64 from fitsio.h, since it may not be defined. - modified imcompress.c to support unconventional floating point FITS images that also have BSCALE and BZERO keywords. The compressed floating point images are linearly scaled twice in this case. Version 3.10 - 20 August 2008 - fixed a number of cases, mainly dealing with long input file names (> 1024 char), where unsafe usage of strcat and strcpy could have caused buffer overflows. These buffer overflows could cause the application to crash, and at least theoretically, could be exploited by a malicious user to execute arbitrary code. There are no known instances of this type of malicious attack on CFITSIO applications, and the likelihood of such an attack seems remote. None the less, it would be prudent for CFITSIO users to upgrade to this new version to guard against this possibility. - modified some of the routines to define input character string parameters as "const char *" rather than just "char *" to eliminate some compiler warnings when the calling routine passes a constant string to the CFITSIO routine. Most of the changes were to the keyword name argument in the many routines that read or write keywords. - fixed bug when tile-compressing a FITS image which caused all the completely blank keywords in the input header to be deleted from the output compressed image. Also added a feature to preserve any empty FITS blocks in the header (reserved space for future keywords) when compressing or uncompressing an image. - fixed small bug in the way the default tile size is set in imcompress.c. (Fix sent in by Paul Price). - added support for reading FITS format region files (in addition to the ASCII format that was previously supported). Thanks to Keith Arnaud for modifying region.c to do this. Version 3.09 - 12 June 2008 - fixed bug in the calculator function, parse_data, that evaluates expressions then selecting rows or modifying values in table columns. This bug only appeared in unusual circumstances where the calculated value has a null value (= TNULLn). The bug could cause elements to not be flagged as having a null value, or in rare cases could cause valid elements to be flagged as null. This only appears to have affected 64-bit platforms (where size(long) = 8). - fixed typo in imcomp_decompress_tile: call to fffi2r8 should have been to fffi4r8. - in the imcopy_copy_comp2img routine, moved the call to fits_translate_keywords outside of the 'if' statement. This could affect reading compressed images that did not have a EXTNAME keyword in the header. - fixed imcomp_compress_tile in imcompress.c to properly support writing unsigned integers, in place, to tile compressed images. - modified fits_read_compressed_img so that if the calling routine specifies nullval = 0, then it will not check for null-valued pixels in the compressed FITS image. This mimics the same behavior when reading normal uncompressed FITS images. Version 3.08 - 15 April 2008 - fixed backwards compatibility issue when uncompressing a Rice compressed image that was created with previous versions of CFITSIO (this late fix was added on May 18). - small change to cfortran.h to add "extern" to the common block definition. This was done for compatibility with the version of cfortran.h that is distributed by the Debian project. - relaxed the requirement that a string valued keyword must have a closing quote character. If the quote is missing, CFITSIO will silently append a quote at the end of the keyword record. This change was made because otherwise it is very difficult to correct the keyword because CFITSIO would exit with an error before making the fix. - added a new BYTEPIX compression parameter when tile-compressing images with the Rice algorithm. - cached the NAXIS and NAXISn keyword values in the fitsio structure for efficiency, to eliminate duplicates reads of these keywords. - added variants of the Rice compression and uncompression routines to support short int images (in addition to the routines that support int). - moved the definition of LONGLONG_MIN and LONGLONG_MAX from fitsio2.h to fitsio.h, to make it accessible to application programs. - make efficiency improvements to fitscore.c, to avoid needless searches through the entire header when reading the required keywords that must be near the beginning of the header. - made several improvements to getcol.c to optimize reading of compressed and uncompressed images. - changed the compression level in the gzip code from 6 to 1. In most cases this will provide nearly the same amount of compression, but is significantly faster in some cases. - added new "helper routines' to imcompress.c to allow applications to specified the "quantize level" and Hcompress scaling and smoothing parameters - modified the extended filename syntax to support the "quantize level" and Hcompress scaling and smoothing parameters. The parser in cfileio.c was extensively modified. - extensive changes to quantize.c: - replace the "nbits" parameter with "quantize level" - the quantize level is now relative to the RMS noise in the image - the HCOMPRESS scale factor is now relative to the RMS noise - added routines to calculate RMS noise in image (these changes require a change to the main file structure in fitsio.h) - initialize errno = 0 before the call to strtol in ffext, in case errno has previously been set by an unrelated error condition. - added the corresponding long name for the ffgkyjj routine to longnam.h. - changed imcomp_copy_comp2img (in imcompress.c) to not require the presence of the EXTNAME keyword in the input compressed image header. - modified imcompress.c to only write the UNCOMPRESSED_DATA column in tile-compressed images if it is actually needed. This eliminates the need to subsequently delete the column if it is not used (which is almost always the case). - found that it is necessary to seek to the EOF of a file after truncating the size of the file, to reestablish a definite current location in the file. The required small changes to 3 routines: file_truncate (to seek to EOF) and fftrun (to set io_pos) and the truncation routine in drvrmem.c. - improved the efficiency when compressing integer images with gzip. Previously, the image was always represented using integer*4 pixels, which were then compressed. Now, if the range of pixel values can be represented with integer*2 pixels or integer*1 pixels, then that is used. This change is backward compatible with any compressed images that used the previous method. - changed the default tiling pattern when using Hcompress from large squares (200 to 600 pixels wide) to 16 rows of the image. This generally requires less memory, compresses faster, and is more consistent with the default row by row tiling when using the other compression methods. - modified imcomp_init_table in imcompress.c to enforce a restriction when using the Hcompress algorithm that the 1st 2 dimensions of sll image tiles must be at least 4 pixels long. Hcompress becomes very inefficient for smaller dimensions, and does not work at all with 1D images. - fixed bug in the Hcompress compression algorithm that could affect compression of I*4 images, using non-square compression tiles (in the encode64 routine). Version 3.07 - 6 December 2007 (internal release) - fixed bug with the PLIO image compression routine which silently produced a corrupted compressed image if the uncompressed image pixels were not all in the range 0 to 2**24. (fixed in November) - fixed several 'for' loops in imcompress.c which were exceeding the bounds of an array by 1. (fixed in November) - fixed a possible, but unlikely, memory overflow issue in iraffits.c. - added a clarification to the cfortran.doc file that cfortran.h may be used and distributed under the terms of the GNU Library General Public License. - fixed bug in the fits_modify_vector_len routine when modifying the vector length of a 'X' bit column. Version 3.06 - 27 August 2007 - modified the imcopy.c utility program (to tile-compress images) so that it writes the default EXTNAME = 'COMPRESSED_IMAGE' keyword in the compressed images, to preserve the behavior of earlier versions of imcopy. - modified the angsep function in the FITS calculator (in eval.y) to use haversines, instead of the 'law of cosines', to provide more precision at small angles (< 0.1 arcsec). Version 3.05 - July 2007 (internal release only) - extensive changes to imcompress.c to fully support implicit data type conversion when reading and writing arrays of data to FITS images, where the data type of the array is not the same as the data type of the FITS image. This includes support for null pixels, and data scaling via the BSCALE and BZERO keywords. - rewrote the fits_read_tbl_coord routine in wcssub.c, that gets the standard set of WCS keywords appropriate to a pair of columns in a table, to better support the full set of officially approved WCS keywords. - made significant changes to histo.c, which creates an image by binning columns of a table, to better translate the WCS keywords in the table header into the WCS keywords that are appropriate for an image HDU. - modified imcompress.c so that when pixels are written to a tile-compressed image, the appropriate BSCALE and BZERO values of that image are applied. This fixes a bug in which writing to an unsigned integer datatype image (with BZERO = 32768) was not done correctly. Version 3.04 - 3 April 2007 - The various table calculator routines (fits_select_rows, etc.) implicitly assumed that the input table has not been modified immediately prior to the call. To cover cases where the table has been modified a call to ffrdef has been added to ffprs. IN UNUSUAL CASES THIS CHANGE COULD CAUSE CFITSIO TO BEHAVE DIFFERENTLY THAN IN PREVIOUS VERSIONS. For example, opening a FITS table with this column-editing virtual file expression: myfile.fits[3][col A==X; B = sqrt(X)] no longer works, because the X column does not exist when the sqrt expression is evaluated. The correct expression in this case is myfile.fits[3][col A==X; B = sqrt(A)] - modified putkey.c to support USHORT_IMG when calling fits_create_img to create a signed byte datatype image. - enhanced the column histogramming function to propagate any TCn_k and TPn_k keywords in the table header to the corresponding CDi_j and PCi_j keywords in the image header. - enhanced the random, randomn, and randomp functions in the lexical parser to take a vector column name argument to specify the length of the vector of random numbers that should be generated (provided by Craig Markwardt, GSFC) - enhanced the ffmcrd routine (to modify an existing header card) to support long string keywords so that any CONTINUE keywords associated with the previous keyword will be deleted. - modified the ffgtbp routine to recognize the TDIMn keyword for ASCII string columns in a binary table. The first dimension is taken to be the size of a unit string. (The TFORMn = 'rAw' syntax may also be used to specify the unit string size). - in fits_img_decompress, the fits_get_img_param function was called with an invalid dimension size, which caused a fatal error on at least 1 platform. - in ffopentest, set the status value before returning in case of error. - in the drvrnet.c file, the string terminators needed to be changed from "\n" to "\r\n" to support the strict interpretation of the http and ftp standard that is enforced by some newer web servers. Version 3.03 - 11 December 2006 New Routine - fits_write_hdu writes the current HDU to a FILE stream (e.g. stdout). Changes - modified the region parsing code to support region files where the keyword "physical" is on a separate line preceding the region shape token. (However, "physical" coordinates are not fully supported, and are treated identically to "image" coordinates). - enhanced the iterator routines to support calculations on 64-bit integer columns and images. Currently, the values are cast to double precision when doing the calculations, which can cause a loss of precision for integer values greater than about 2**52. - added support for accessing FITS files on the computational grid. Giuliano Taffoni and Andrea Barisani, at INAF, University of Trieste, Italy, implemented the necessary I/O driver routines in drvrgsiftp.c. - modified the tiled image compression/uncompression routines to preserve/restore the original CHECKSUM and DATASUM keywords if they exist. (saved as ZHECKSUM and ZDATASUM in the compressed image) - split fits_select_image_section into 2 routines: a higher level routine that creates the output file and copies other HDUs from the input file to the output file, and a lower level routine that extracts the image section from the input image into an output image HDU. - Improved the error messages that get generated if one tries to use the lexical parser to perform calculations on variable-length array columns. - added "#define MACHINE NATIVE" in fitsio2.h for all machines where BYTESWAPPED == FALSE. This may improve the file writing performance by eliminating the need to allocate a temporary buffer in some cases. - modified the configure.in and configure script to fix problems with testing if network services are available, which affects the definition of the HAVE_NET_SERVICES flag. - added explicit type casting to all malloc statements, and deleted declarations of unreferenced variables in the image compression code to suppress compiler warnings. - fixed incorrect logic in fitsio2.h in the way it determined if numerical values are byteswapped or not on MIPS and ARM architectures. - added __BORLANDC__ to the list of environments in fitsio.h that don't use %lld in printf for longlong integers - added "#if defined(unix)" around "#include " statements in several C source files, to make them compatible with Windows. Version 3.02 - 18 Sept 2006 - applied the security patch to the gzip code, available at http://security.FreeBSD.org/patches/SA-06:21/gzip.patch The insufficient bounds checks in buffer use can cause gzip to crash, and may permit the execution of arbitrary code. The NULL pointer deference can cause gzip to crash. The infinite loop can cause a Denial-of-Service situation where gzip uses all available CPU time. - added HCOMPRESS as one of the compression algorithm options in the tiled image compression code. (code provided by Richard White (STScI)) Made other improvements to preserve the exact header structure in the compressed image file so that the compressed-and-then-uncompressed FITS image will be as identical as possible to the original FITS image file. New Routines - the following new routines were added to support reading and writing non-standard extension types: fits_write_exthdr - write required keywords for a conforming extension fits_write_ext - write data to the extension fits_read_ext - read data from the extension - added new routines to compute the RMS noise in the background pixels of an image: fits_rms_float and fits_rms_short (take an input array of floats or shorts, respectively). Fixes - added the missing 64-bit integer case to set of "if (datatype)" statements in the routine that returns information about a particular column (ffgbclll). - fixed a parsing error in ffexts in cases where an extension number is followed by a semi-colon and then the column and row number of an array in a binary table. Also removed an extraneous HISTORY keyword that was being written when specifying an input image in a table cel. - modified the routine that reads a table column returning a string value (ffgcls) so that if the displayed numerical value is too wide to fit in the specified length string, then it will return a string of "*" characters instead of the number string. - small change to fitsio.h to support a particular Fortran and C compiler combination on a SGI Altix system - added a test in the gunzip code to prevent seg. fault when trying to uncompress a corrupted file (at least in some cases). - fixed a rarely-occurring bug in the routine that copies a table cell into an image; had to call the ffflsh call a few lines earlier. Version 3.01 - (in FTOOLS 6.1 release) - modified fits_copy_image2cell to correctly copy all the appropriate header keywords when copying an image into a table cell - in eval.y, explicitly included the code for the lgamma function instead of assuming it is available in a system library (e.g., the lgamma function is currently not included in MS Visual++ libraries) - modified the logic in fits_pixel_filter so that the default data type of the output image will be promoted to at least BITPIX = -32 (a single precision floating point) if the expression that is being evaluated resolves to a floating point result. If the expression resolves to an integer result, the output image will have the same BITPIX as the input image. - in fits_copy_cell2image, added 5 more WCS keywords to the list of keywords related to other columns that should be deleted in the output image header. - disabled code in cfileio.c that would write HISTORY keywords to the output file in fits_copy_image2cell and cell2image, because some tasks would not want these extraneous HISTORY keywords. - added 2 new random number functions to the CFITSIO parser RANDOMN() - produces a normal deviate (mean=0, stddev=1) RANDOMP(X) - produces a Poisson deviate for an expected # of counts X - in f77_wrap.h, removed the restriction that "g77Fortran" must be defined on 64-bit Itanium machines before assuming that sizeof(long) = 8. It appears that "long"s are always 8 bytes long on this machine, regardless of what compilers are used. - added test in fitsio.h so that LONGLONG cannot be multiply defined - modified longnam.h so that both "fits_write_nulrows" and "fits_write_nullrows" get replace by the string "ffprwu". This fixes a documentation error regarding the long name of this routine. Bug fixes - fixed a potential null character string dereferencing error in the the ffphtb and ffphbn routines that write the FITS table keywords. This concerned the optional TUNITn keywords. - fixed a few issues in fits_copy_cell2image and fits_copy_image2cell related to converting some WCS keyword between the image extension form and the table cell form of the keyword. (cfileio.c) - fixed bug in fits_translate_keyword (fitscore.c) that, e.g., caused 'EQUINOX' to be translated to EQUINOXA' if the pattern is 'EQUINOXa' - fixed 2 bugs that could affect 'tile compressed' floating point images that contain NaN pixels (null pixels). First, the ZBLANK keyword was not being written, and second, an integer overflow could occur when computing the BZERO offset in the compressed array. (quantize.c and imcompress.c) Version 3.006 - 20 February 2006 -(first full release of v3) - enhanced the 'col' extended filename syntax to support keyword name expressions like [col error=sqrt(rate); #TUNIT# = 'counts/s'], in which the trailing '#' will be replaced by the column number of the most recently referenced column. - fixed bug in the parse_data iterator work function that caused it to fail to return a value of -1 in cases where only a selected set of rows were to be processed. (affected Fv) - added code to fitsio.h and cfortran.h to typedef LONGLONG to the appropriate 8-byte integer data type. Most compilers now support the 'long long' data type, but older MS Visual C++ compilers used '__int64' instead. - made several small changes based on testing by Martin Reinecke: o in eval.y, change 'int undef' to 'long undef' o in getcold.c and getcole.c, fixed a couple format conversion specifiers when displaying the value of long long variables. o in fitsio.h, modified the definition of USE_LL_SUFFIX in the case of Athon64 machines. o in fitsio2.h, defined BYTESWAPPED in the case of SGI machines. o in group.c, added 'include unistd.h' to get rid of compiler warning. Version 3.005 - 20 December 2005 (beta) - cfortran.h has been enhanced to support 64-bit integer parameters when calling C routines from Fortran. This modification was kindly provided by Martin Reinecke (MPE, Garching). - Many new Fortran wrapper routines have been added to support reading and writing 64-bit integer values in FITS files. These new routines are documented in the updated version of the 'FITSIO User's Guide' for Fortran programmers. - fixed a problem in the fits_get_keyclass routine that caused it to not recognize the special COMMENT keywords at the beginning of most FITS files that defines the FITS format. - added a new check to the ffifile routine that parses the input extended file name, to distinguish between a FITS extension name that begins with 'pix', and a pixel filtering operator that begins with the 'pix' keyword. - small change to the WCSLIB interface routine, fits_read_wcstab, to be more permissive in allowing the TDIMn keyword to be omitted for degenerate coordinate array. Version 3.004 - 16 September 2005 (3rd public beta release) - a major enhancement to the CFITSIO virtual file parser was provided by Robert Wiegand (GSFC). One can now specify filtering operations that will be applied on the fly to the pixel values in a FITS image. For example [pix sqrt(X)] will create a virtual FITS image where the pixel values are the square root of the input image pixels. - modified region.c so that it interprets the position angles of regions in a SAO style region file in the same way as DS9. In particular, if the region parameters are given in WCS units, then the position angle should be relative to the WCS coordinates of the image (increasing CCW from West) instead of relative to the X/Y pixel coordinate system. This only affects rotated images (e.g. with non-zero CROTA2 keyword) with elliptical or rectangular regions. - cleaned up fitsio.h and fitsio2.h to make the definition of LONGLONG and BYTESWAPPED and MACHINE more logical. - removed HAVE_LONGLONG everywhere since it is no longer needed (the compiler now must have an 8-byte integer datatype to build CFITSIO). - added support for the 64-bit IBM AIX platform - modified eval.y so that the circle, ellipse, box, and near functions can operate on vectors as well as scalars. This allows region filtering on images that are stored in a vector cell in a binary table. (provided by Craig Markwardt, GSFC) New Routines - added new fits_read_wcstab routine that serves as an interface to Mark Calabretta's wcslib library for reading WCS information when the -TAB table lookup convention is used in the FITS file. - added new fits_write_nullrows routine, which writes null values into every column of a specified range of rows in a FITS table. - added the fits_translate_keyword and fits_translate_keywords utility routines for converting the names of keywords when moving columns and images around. - added fits_copy_cell2image and fits_copy_image2cell routines for copying an image extension (or primary array) to or from a cell in a binary table vector column. Bug fixes - fixed a memory leak in eval.y; was fixed by changing a call to malloc to cmalloc instead. - changed the definition of several global variables at the beginning of buffers.c to make them 'static' and thus invisible to applications programs. - in fits_copy_image_cell, added a call to flush the internal buffers before reading from the file, in case any records had been modified. Version 3.003 - 28 July 2005 - 2nd public beta release (used in HEASOFT) Enhancements - enhanced the string column reading routing fits_get_col_str to support cases where the user enters a null pointer (rather than a null string) as the nulval parameter. - modified the low level ffread and ffwrite routines that physically read and write data from the FITS file so that they write the name of the file to the CFITSIO error stack if an error occurs. - changed the definition of fits_open_file into a macro that will test that the version of the fitsio.h include file that was used to build the CFITSIO library is the same version as included when compiling the application program. - made a simple modification to region.c to support regions files of type "linear", for compatibility with ds9 and fv. - modified the internal ffgpr routine (and renamed it ffgprll) so that it returns the TNULL value as a LONGLONG parameter instead of 'long'. - in fits_get_col_display_width, added support for TFORM = 'k' - modified fitsio.h, fitsio2.h, and f77_wrap.h to add test for (_SX) to identify NEC SX supercomputers. - modified eval_f.c to treat table columns of TULONG (unsigned long) as a double. Also added support for TLONGLONG (8-byte integers) as a double, which is only a temporary fix, since doubles only have about 52 bits of precision. - changed the 'blank' parameter in the internal ffgphd function to to type LONGLONG to support integer*8 FITS images. - when reading the TNULL keyword value, now use ffc2jj instead of ffc2ii, to support integer*8 values. Bug fixes - fixed a significant bug when writing character strings to a variable length array column of a binary table. This bug would result in some unused space in the variable length heap, making the heap somewhat larger than necessary. This in itself is usually a minor issue, since the FITS files are perfectly valid, and other software should have no problems reading back the characters strings. In some cases, however, this problem could cause the program that is writing the table to exit with a status = 108 disk read error. - modified the standalone imcopy.c utility program to fix a memory allocation bug when running on 64-bit platforms where sizeof(long) = 8 bytes. - added an immediate 'return' statement to ffgtcl if the input status >0, to prevent a segfault on some platforms. Version 3.002 - 15 April 2005 - first public beta release - in drvrfile.c, if it fails to open the file for some reason, then it should reset file_outfile to a null string, to avoid errors on a subsequent call to open a file. - updated fits_get_keyclass to recognize most of the WCS keywords defined in the WCS Papers I and II. Version 3.001 - 15 March 2005 - released with HEASOFT 6.0 - numerous minor changes to the code to get rid of compiler warning messages, mainly dealing with numerical data type casting and the subsequent possible loss of precision in the result. Version 3.000 - 1 March 2005 (internal beta release) Enhancements: - Made major changes to many of the CFITSIO routines to more generally support Large Files (> 2.1 GB). These changes are intended to be 100% backward compatible with software that used the previous versions of CFITSIO. The datatype of many of the integer parameters in the CFITSIO functions has been changed from 'long' to 'LONGLONG', which is typedef'ed to be equivalent to an 8-byte integer datatype on each platform. With these changes, CFITSIO supports the following: - integer FITS keywords with absolute values > 2**31 - FITS files with total sizes > 2**31 bytes - FITS tables in which the number of rows, the row width, or the size of the heap is > 2**31 bytes - FITS images with dimensions > 2**31 bytes (support is still somewhat limited, with full support to be added later). - added another lexical parser function (thanks to Craig Markwardt, GSFC): angsep computes the angular separation between 2 positions on the celestial sphere. - modified the image subset extraction code (e.g., when specifying an image subregion when opening the file, such as 'myimage.fits[21:40, 81:90]') so that in addition to updating the values of the primary WCS keywords CRPIXk, CDELTi, and CDj_i in the extracted/binned image, it also looks for and updates any secondary WCS keywords (e.g., 'CRPIX1P'). - made cosmetic change to group.c, so that when a group table is copied, any extra columns will be appended after the last existing column, instead of being inserted before the last column. - modified the routines that read tile compressed images to support NULL as the input value for the 'anynul' parameter (meaning the calling program does not want the value of 'anynul' returned to it). - when constructing or parsing a year/month/day character string, (e.g, when writing the DATE keyword) the routines now rigorously verify that the input day value is valid for the given month (including leap years). - added some checks in cfileio.c to detect if some vital parameters that are stored in memory have been corrupted. This can occur if a user's program writes to areas of memory that it did not allocate. - added the wcsutil_alternate.c source code file which contains non-working stubs for the 2 Classic AIPS world coordinate conversion routines that are distributed under the GNU General Public License. Users who are unwilling or unable to distribute their software under the General Public License may use this alternate source file which has no GPL restrictions, instead of wcsutil.c. This will have no effect on programs that use CFITSIO as long as they do not call the fits_pix_to_world/ffwldp or fits_world_to_pix/ffxypx routines. Bug Fixes - in ffdtdm (which parses the TDIMn keyword value), the check for consistency between the length of the array defined by TDIMn and the size of the TFORMn repeat value, is now not performed for variable length array columns (which always have repeat = 1). - fixed byteswapping problem when writing null values to non-standard long integer FITS images with BITPIX = 64 and FITS table columns with TFORMn = 'K'. - fixed buffer overflow problem in fits_parse_template/ffgthd that occurred only if the input template keyword value string was much longer than can fit in an 80-char header record. Version 2.510 - 2 December 2004 New Routines: - added fits_open_diskfile and fits_create_diskfile routines that simply open or create a FITS file with a specified name. CFITSIO does not try to parse the name using the extended filename syntax. - 2 new C functions, CFITS2Unit and CUnit2FITS, were added to convert between the C fitsfile pointer value and the Fortran unit number. These functions may be useful in mixed language C and Fortran programs. Enhancements: - added the ability to recognize and open a compressed FITS file (compressed with gzip or unix compress) on the stdin standard input stream. - Craig Markwardt (GSFC) provided 2 more lexical parser functions: accum(x) and seqdiff(x) that compute the cumulative sum and the sequential difference of the values of x. - modified putcole.c and putcold.c so that when writing arrays of pixels to the FITS image or column that contain null values, and there are also numerical overflows when converting some of the non-null values to the FITS values, CFITSIO will now ignore the overflow error until after all the data have been written. Previously, in some circumstances CFITSIO would have simply stopped writing any data after the first overflow error. - modified fitsio2.h to try to eliminate compiler warning messages on some platforms about the use of 'long long' constants when defining the value of LONGLONG_MAX (whether to use L or LL suffix). - modified region.c to support 'physical' regions in addition to 'image', 'fk4', etc. - modified ffiurl (input filename parsing routine) to increase the maximum allowed extension number that can be specified from 9999 to 99999 (e.g. 'myfile.fits+99999') Bug Fixes: - added check to fits_create_template to force it to start with the primary array in the template file, in case an extension number was specified as part of the template FITS file name. Version 2.500 - 28 & 30 July 2004 New Routine: - fits_file_exists tests whether the specified input file, or a compressed version of the file, exists on disk. Enhancements: - modified the way CFITSIO reads and writes data in COMPLEX ('C') and DBLCOMPLEX 'M' columns. Now, in all cases, when referring to the number of elements in the vector, or the value of the offset to a particular element within the vector, CFITSIO considers each pair of numbers (the imaginary and real parts) as a single element instead of treating each single number as an element. In particular, this changes the behavior of fits_write_col_null when writing to complex columns. It also changes the length of the 'nullarray' vector in the fits_read_colnull routine; it is now only 1/2 as long as before. Each element of the nullarray is set = 1 if either the real or imaginary parts of the corresponding complex value have a null value.(this change was added to version 2.500 on 30 July). - Craig Markwardt, at GSFC, provided a number of significant enhancements to the CFITSIO lexical parser that is used to evaluate expressions: - the parser now can operate on bit columns ('X') in a similar way as for other numeric columns (e.g., 'B' or 'I' columns) - range checking has been implemented, so that the following conditions return a Null value, rather than returning an error: divide by zero, sqrt(negative), arccos(>1), arcsin(>1), log(negative), log10(negative) - new vector functions: MEDIAN, AVERAGE, STDDEV, and NVALID (returns the number of non-null values in the vector) - all the new functions (and SUM, MIN and MAX) ignore null values - modified the iterator to support variable-length array columns - modified configure to support AIX systems that have flock in a non- standard location. - modified configure to remove the -D_FILE_OFFSET_BITS flag when running on Mac Darwin systems. This caused conflicts with the Fortran wrappers, and should only be needed in any case when using CFITSIO to read/write FITS files greater than 2.1 GB in size. - modified fitsio2.h to support compilers that define LONG_LONG_MAX. - modified ffrsim (resize an existing image) so that it supports changing the datatype to an unsigned integer image using the USHORT_IMG and ULONG_IMG definitions. - modified the disk file driver (drvrfile.c) so that if an output file is specified when opening an ordinary file (e.g. with the syntax 'myfile.fits(outputfile.fits)' then it will make a copy of the file, close the original file and open the copy. Previously, the specified output file would be ignored unless the file was compressed. - modified f77_wrap.h and f77_wrap3.c to support the Fortran wrappers on 64-bit AMD Opteron machines Bug fixes: - made small change to ffsrow in eval_f.c to avoid potential array bounds overflow. - made small change to group.c to fix problem where an 'int' was incorrectly being cast to a 'long'. - corrected a memory allocation error in the new fits_hdr2str routine that was added in version 2.48 - The on-the-fly row-selection filtering would fail with a segfault if the length of a table row (NAXIS1 value) was greater than 500000 bytes. A small change to eval_f.c was required to fix this. Version 2.490 - 11 February 2004 Bug fixes: - fixed a bug that was introduced in the previous release, which caused the CFITSIO parser to no longer move to a named extension when opening a FITS file, e.g., when opening myfile.fit[events] CFITSIO would just open the primary array instead of moving to the EVENTS extension. - new group.c file from the INTEGRAL Science Data Center. It fixes a problem when you attach a child to a parent and they are both is the same file, but, that parent contains groups in other files. In certain cases the attach would not happen because it seemed that the new child was already in the parent group. - fixed bug in fits_calculator_rng when performing a calculation on a range of rows in a table, so that it does not reset the value in all the other rows that are not in the range = 0. - modified fits_write_chksum so that it updates the TFORMn keywords for any variable length vector table columns BEFORE calculating the CHECKSUM values. Otherwise the CHECKSUM value is invalidated when the HDU is subsequently closed. Version 2.480 - 28 January 2004 New Routines: - fits_get_img_equivtype - just like fits_get_img_type, except in the case of scaled integer images, it returns the 'equivalent' data type that is necessary to store the scaled data values. - fits_hdr2str copies all the header keywords in the current HDU into a single long character string. This is a convenient method of passing the header information to other subroutines. The user may exclude any specified keywords from the list. Enhancements: - modified the filename parser so that it accepts extension names that begin with digits, as in 'myfile.fits[123TEST]'. In this case CFITSIO will try to open the extension with EXTNAME = '123TEST' instead of trying to move to the 123rd extension in the file. - the template keyword parser now preserves the comments on the the mandatory FITS keywords if present, otherwise a standard default comment is provided. - modified the ftp driver file (drvrnet.c) to overcome a timeout or hangup problem caused by some firewall software at the user's end (Thanks to Bruce O'Neel for this fix). - modified iraffits.c to incorporate Doug Mink's latest changes to his wcstools library routines. The biggest change is that now the actual image dimensions, rather than the physically stored dimensions, are used when converting an IRAF file to FITS. Bug fixes: - when writing to ASCII FITS tables, the 'elemnum' parameter was supposed to be ignored if it did not have the default value of 1. In some cases however setting elemnum to a value other than 1 could cause the wrong number of rows to be produced in the output table. - If a cfitsio calculator expression was imported from a text file (e.g. using the extended filename syntax 'file.fits[col @file.calc]') and if any individual lines in that text file were greater than 255 characters long, then a space character would be inserted after the 255th character. This could corrupt the line if the space was inserted within a column name or keyword name token. Version 2.480beta (used in the FTOOLS 5.3 release, 1 Nov 2003) New Routines: - fits_get_eqcoltype - just like fits_get_coltype, except in the case of scaled integer columns, it returns the 'equivalent' data type that is necessary to store the scaled data values. - fits_split_names - splits an input string containing a comma or space delimited list of names (typically file names or column names) into individual name tokens. Enhancements: - changed fhist in histo.c so that it can make histograms of ASCII table columns as well as binary table columns (as long as they contain numeric data). Bug fixes: - removed an erroneous reference to listhead.c in makefile.vcc, that is used to build the cfitsio dll under Windows. This caused a 'main' routine to be added to the library, which causes problems when linking fortran programs to cfitsio under windows. - if an error occurs when opening for a 2nd time (with ffopen) a file that is already open (e.g., the specified extension doesn't exist), and if the file had been modified before attempting to reopen it, then the modified buffers may not get written to disk and the internal state of the file may become corrupted. ffclos was modified to always set status=0 before calling ffflsh if the file has been concurrently opened more than once. Version 2.470 - 18 August 2003 Enhancements: - defined 'TSBYTE' to represent the 'signed char' datatype (similar to 'TBYTE' that represents the 'unsigned char' datatype) and added support for this datatype to all the routines that read or write data to a FITS image or table. This was implemented by adding 2 new C source code files to the package: getcolsb.c and putcolsb.c. - Defined a new '1S' shorthand data code for a signed byte column in a binary table. CFITSIO will write TFORMn = '1B' and TZEROn = -128 in this case, which is the convention used to store signed byte values in a 'B' type column. - in fitsio2.h, added test of whether `__x86_64__` is defined, to support the new AMD Opteron 64-bit processor - modified configure to not use the -fast compiler flag on Solaris platforms when using the proprietary Solaris cc compiler. This flag causes compilation problems in eval_y.c (compiler just hangs forever). Bug fixes: - In the special case of writing 0 elements to a vector table column that contains 0 rows, ffgcpr no longer adds a blank row to the table. - added error checking code for cases where a ASCII string column in a binary table is greater than 28800 characters wide, to avoid going into an infinite loop. - the fits_get_col_display_width routine was incorrectly returning width = 0 for a 'A' binary table column that did not have an explicit vector length character. Version 2.460 - 20 May 2003 Enhancements: - modified the HTTP driver in drvrnet.c so that CFITSIO can read FITS files via a proxy HTTP server. (This code was contributed by Philippe Prugniel, Obs. de Lyon). To use this feature, the 'http_proxy' environment variable must be defined with the address (URL) and port number of the proxy server, i.e., > setenv http_proxy http://heasarc.gsfc.nasa.gov:3128 will use port 3128 on heasarc.gsfc.nasa.gov - suppressed some compiler warnings by casting a variable of type 'size_t' to type 'int' in fftkey (in fitscore.c) and iraftofits and irafrdimge (in iraffits.c). Version 2.450 - 30 April 2003 Enhancements: - modified the WCS keyword reading routine (ffgics) to support cases where some of the CDi_j keywords are omitted (with an assumed value = 0). - Made a change to http_open_network in drvrnet.c to add a 'Host: ' string to the open request. This is required by newer HTTP 1.1 servers (so-called virtual servers). - modified ffgcll (read logical table column) to return the illegal character value itself if the FITS file contains a logical value that is not equal to T, F or zero. Previously it treated this case the same as if the FITS file value was = 0. - modified fits_movnam_hdu (ffmnhd) so that it will move to a tile- compressed image (that is stored in a binary table) if the input desired HDU type is BINARY_TBL as well as if the HDU type = IMAGE_HDU. Bug fixes: - in the routine that checks the data fill bytes (ffcdfl), the call to ffmbyt should not ignore an EOF error when trying to read the bytes. This is a little-used routine that is not called by any other CFITSIO routine. - fits_copy_file was not reporting an error if it hit the End Of File while copying the last extension in the input file to the output file. - fixed inconsistencies in the virtual file column filter parser (ffedit_columns) to properly support expressions which create or modify a keyword, instead of a column. Previously it was only possible to modify keywords in a table extension (not an image), and the keyword filtering could cause some of the table columns to not get propagated into the virtual file. Also, spaces are now allowed within the specified keyword comment field. - ffdtyp was incorrectly returning the data type of FITS keyword values of the form '1E-09' (i.e., an exponential value without a decimal point) as integer rather than floating point. - The enhancement in the previous 2.440 release to allow more files to be opened at one time introduced a bug: if ffclos is called with a non-zero status value, then any subsequent call to ffopen will likely cause a segmentation fault. The fits_clear_Fptr routine was modified to fix this. - rearranged the order of some computations in fits_resize_img so as to not exceed the range of a 32-bit integer when dealing with large images. - the template parser routine, ngp_read_xtension, was testing for "ASCIITABLE" instead of "TABLE" as the XTENSION value of an ASCII table, and it did not allow for optional trailing spaces in the IMAGE" or "TABLE" string value. Version 2.440 - 8 January 2003 Enhancements: - modified the iterator function, ffiter, to operate on random groups files. - decoupled the NIOBUF (= 40) parameter from the limit on the number FITS files that can be opened, so that more files may be opened without the overhead of having to increase the number of NIOBUF buffers. A new NMAXFILES parameter is defined in fitsio2.h which sets the maximum number of opened FITS files. It is set = 300 by default. Note however, that the underlying compiler or operating system may not allow this many files to be opened at one time. - updated the version of cfortran.h that is distributed with CFITSIO from version 3.9 to version 4.4. This required changes to f77_wrap.h and f77_wrap3.c. The original cfortran.h v4.4 file was modified slightly to support CFITSIO and ftools (see comments in the header of cfortran.h). - modified ffhist so that it copies all the non-structural keywords from the original binary table header to the binned image header. - modified fits_get_keyclass so that it recognizes EXTNAME = COMPRESSED_IMAGE as a special tile compression keyword. - modified Makefile.in to support the standard --prefix convention for specifying the install target directory. Bug fixes: - in fits_decompress_img, needed to add a call to ffpscl to turn off the BZERO and BSCALE scaling when reading the compressed image. Version 2.430 - 4 November 2002 Enhancements: - modified fits_create_hdu/ffcrhd so that it returns without doing anything and does not generate an error if the current HDU is already an empty HDU. There is no need in this case to append a new empty HDU to the file. - new version of group.c (supplied by B. O'Neel at the ISDC) fixes 2 limitations: 1 - Groups now have 256 characters rather than 160 for the path lengths in the group tables. - ISDC SPR 1720. 2 - Groups now can have backpointers longer than 68 chars using the long string convention. - ISDC SPR 1738. - small change to f77_wrap.h and f77_wrap3.c to support the fortran wrappers on SUN solaris 64-bit sparc systems (see also change to v2.033) - small change to find_column in eval_f.c to support unsigned long columns in binary tables (with TZEROn = 2147483648.0) - small modification to cfortran.h to support Mac OS-X, (Darwin) Bug fixes: - When reading tile-compress images, the BSCALE and BZERO scaling keywords were not being applied, if present. - Previous changes to the error message stack code caused the tile compressed image routines to not clean up spurious error messages properly. - fits_open_image was not skipping over null primary arrays. Version 2.420 - 19 July 2002 Enhancements: - modified the virtual filename parser to support exponential notation when specifying the min, max or binsize in a binning specifier, as in: myfile.fits[binr X=1:10:1.0E-01, Y=1:10:1.0E-01] - removed the limitation on the maximum number of HDUs in a FITS file (limit used to be 1000 HDUs per file). Now any number of HDUs can be written/read in a FITS file. (BUT files that have huge numbers of HDUs can be difficult to manage and are not recommended); - modified grparser.c to support HIERARCH keywords, based on code supplied by Richard Mathar (Max-Planck) - moved the ffflsh (fits_flush_buffer) from the private to the public interface, since this routine may be useful for some applications. It is much faster than ffflus. - small change to the definition of OFF_T in fitsio.h to support large files on IBM AIX operating systems. Bug fixes: - fixed potential problem reading beyond array bounds in ffpkls. This would not have affected the content of any previously generated FITS files. - in the net driver code in drvrnet.c, the requested protocol string was changed from "http/1.0" to "HTTP/1.0" to support apache 1.3.26. - When using the virtual file syntax to open a vector cell in a binary table as if it were a primary array image, there was a bug in fits_copy_image_cell which garbled the data if the vector was more than 30000 bytes long. - fixed problem that caused fits_report_error to crash under Visual C++ on Windows systems. The fix is to use the '/MD' switch on the cl command line, or, in Visual Studio, under project settings / C++ select use runtime library multithreaded DLL - modified ffpscl so it does not attempt to reset the scaling values in the internal structure if the image is tile-compressed. - fixed multiple bugs in mem_rawfile_open which affected the case where a raw binary file is read and converted on the fly into a FITS file. - several small changes to group.c to suppress compiler warnings. Version 2.410 - 22 April 2002 (used in the FTOOLS 5.2 release) New Routines: - fits_open_data behaves similarly to fits_open_file except that it also will move to the first HDU containing significant data if and an explicit HDU name or number to open was not specified. This is useful for automatically skipping over a null primary array when opening the file. - fits_open_table and fits_open_image behaves similarly to fits_open_data, except they move to the first table or image HDU in the file, respectively. - fits_write_errmark and fits_clear_errmark routines can be use to write an invisible marker to the CFITSIO error stack, and then clear any more recent messages on the stack, back to that mark. This preserves any older messages on the stack. - fits_parse_range utility routine parses a row list string and returns integer arrays giving the min and max row in each range. - fits_delete_rowrange deletes a specified list of rows or row ranges. - fits_copy_file copies all or part of the HDUs in the input file to the output file. - added fits_insert_card/ffikey to the publicly defined set of routines (previously, it was a private routine). Enhancements: - changed the default numeric display format in ffgkys from 'E' format to 'G' format, and changed the format for 'X' columns to a string of 8 1s or 0s representing each bit value. - modified ffflsh so the system 'fflush' call is not made in cases where the file was opened with 'READONLY' access. - modified the output filename parser so the "-.gz", and "stdout.gz" now cause the output file to be initially created in memory, and then compressed and written out to the stdout stream when the file is closed. - modified the routines that delete rows from a table to also update the variable length array heap, to remove any orphaned data from the heap. - modified ffedit_columns so that wild card characters may be used when specifying column names in the 'col' file filter specifier (e.g., file.fits[col TIME; *RAW] will create a virtual table contain only the TIME column and any other columns whose name ends with 'RAW'). - modified the keyword classifier utility, fits_get_keyclass, to support cases where the input string is just the keyword name, not the entire 80-character card. - modified configure.in and configure to see if a proprietary C compiler is available (e.g. 'cc'), and only use 'gcc' if not. - modified ffcpcl (copy columns from one table to another) so that it also copies any WCS keywords related to that column. - included an alternate source file that can be used to replace compress.c, which is distributed under the GNU General Public License. The alternate file contains non-functional stubs for the compression routines, which can be used to make a version of CFITSIO that does not have the GPL restrictions (and is also less functional since it cannot read or write compressed FITS files). - modifications to the iterator routine (ffiter) to support writing tile compressed output images. - modified ffourl to support the [compress] qualifier when specifying the optional output file name. E.g., file.fit(out.file[compress])[3] - modified imcomp_compress_tile to fully support implicit data type conversion when writing to tile-compressed images. Previously, one could not write a floating point array to an integer compressed image. - increased the number of internal 2880-byte I/O buffers allocated by CFITSIO from 25 to 40, in recognition of the larger amount of memory available on typical machines today compared with a few years ago. The number of buffers can be set by the user with the NIOBUF parameter in fitsio2.h. (Setting this too large can actually hurt performance). - modified the #if statements in fitsio2.h, f77_wrap.h and f77_wrap1.c to support the new Itanium 64-bit Intel PC. - a couple minor modifications to fitsio.h needed to support the off_t datatype on Debian linux systems. - increased internal buffer sizes in ffshft and ffsrow to improve the I/O performance. Bug fixes: - fits_get_keyclass could sometimes try to append to an unterminated string, causing an overflow of a string array. - fits_create_template no longer worked because of improvements made to other routines. Had to modify ffghdt to not try to rescan the header keywords if the file is still empty and contains no keywords yet. - ffrtnm, which returns the root filename, sometimes did not work properly when testing if the 'filename+n' convention was used for specifying an extension number. - fixed minor problem in the keyword template parsing routine, ffgthd which in rare cases could cause an improperly terminated string to be returned. - the routine to compare 2 strings, ffcmps, failed to find a match in comparing strings like "*R" and "ERROR" where the match occurs on the last character, but where the same matching character occurs previously in the 2nd string. - the region file reading routine (ffrrgn) did not work correctly if the region file (created by POW and perhaps other programs) had an 'exclude' region (beginning with a '-' sign) as the first region in the file. In this case all points outside the excluded region should be accepted, but in fact no points were being accepted in this case. Version 2.401 - 28 Jan 2002 - added the imcopy example program to the release (and Makefile) Bug fixes: - fixed typo in the imcompress code which affected compression of 3D datacubes. - made small change to fficls (insert column) to allow colums with TFORMn = '1PU' and '1PV' to be inserted in a binary table. The 'U' and 'V' are codes only used within CFITSIO to represent unsigned 16-bit and 32-bit integers; They get replaced by '1PI' and '1PJ' respectively in the FITS table header, along with the appropriate TZEROn keyword. Version 2.400 - 18 Jan 2002 (N.B.: Application programs must be recompiled, not just relinked with the new CFITSIO library because of changes made to fitsio.h) New Routines: - fits_write_subset/ffpss writes a rectangular subset (or the whole image) to a FITS image. - added a whole new family of routines to read and write arrays of 'long long' integers (64-bit) to FITS images or table columns. The new routine names all end in 'jj': ffpprjj, ffppnjj, ffp2djj, ffp3djj, ffppssjj, ffpgpjj, ffpcljj, ffpcnjj. ffgpvjj, ffgpfjj, ffg2djj, ffg3djj, ffgsvjj, ffgsfjj, ffggpjj, ffgcvjj, and ffgcfjj. - added a set of helper routines that are used in conjunction with the new support for tiled image compression. 3 routines set the parameters that should be used when CFITSIO compresses an image: fits_set_compression_type fits_set_tile_dim fits_set_noise_bits 3 corresponding routines report back the current settings: fits_get_compression_type fits_get_tile_dim fits_get_noise_bits Enhancements: - major enhancement was made to support writing to tile-compressed images. In this format, the image is divided up into a rectangular grid of tiles, and each tile of pixels is compressed individually and stored in a row of a variable-length array column in a binary table. CFITSIO has been able to transparently read this compressed image format ever since version 2.1. Now all the CFITSIO image writing routines also transparently support this format. There are 2 ways to force CFITSIO to write compressed images: 1) call the fits_set_compression_type routine before writing the image header keywords, or 2), specify that the image should be compressed when entering the name of the output FITS file, using a new extended filename syntax. (examples: "myfile.fits[compress]" will use the default compression parameters, and "myfile.fits[compress GZIP 100,100] will use the GZIP compression algorithm with 100 x 100 pixel tiles. - added new driver to support creating output .gz compressed fits files. If the name of the output FITS file to be created ends with '.gz' then CFITSIO will initially write the FITS file in memory and then, when the FITS file is closed, CFITSIO will gzip the entire file before writing it out to disk. - when over-writing vectors in a variable length array in a binary table, if the new vector to be written is less than or equal to the length of the previously written vector, then CFITSIO will now reuse the existing space in the heap, rather than always appending the new array to the end of the heap. - modified configure.in to support building cfitsio as a dynamic library on Mac OS X. Use 'make shared' like on other UNIX platforms, but a .dylib file will be created instead of .so. If installed in a nonstandard location, add its location to the DYLD_LIBRARY_PATH environment variable so that the library can be found at run time. - made various modifications to better support the 8-byte long integer datatype on more platforms. The 'LONGLONG' datatype is typedef'ed to equal 'long long' on most Unix platforms and MacOS, and equal to '__int64' on Windows machines. - modified configure.in and makefile.in to better support cases where the system has no Fortran compiler and thus the f77 wrapper routines should not be compiled. - made small modification to eval.y and eval_y.f to get rid of warning on some platforms about redefinition of the 'alloca'. Bug fixes: - other recent bug fixes in ffdblk (delete blocks) caused ffdhdu (delete HDU) to fail when trying to replace the primary array with a null primary array. - fixed bug that prevented inserting a new variable length column into a table that already contained variable length data. - modified fits_delete_file so that it will delete the file even if the input status value is not equal to zero. - in fits_resize_image, it was sometimes necessary to call ffrdef to force the image structure to be defined. - modified the filename parser to support input files with names like: "myfile.fits.gz(mem://tmp)" in which the url type is specified for the output file but not for the input file itself. This required modifications to ffiurl and ffrtnm. Version 2.301 - 7 Dec 2001 Enhancements: - modified the http file driver so that if the filename to be opened contains a '?' character (most likely a cgi related string) then it will not attempt to append a .gz or .Z as it would normally do. - added support for the '!' clobber character when specifying the output disk file name in CFITSIO's extended filename syntax, e.g., 'http://a.b.c.d/myfile.fits.gz(!outfile.fits)' - added new device driver which is used when opening a compressed FITS file on disk by uncompressing it into memory with READWRITE access. This happens when specifying an output filename 'mem://'. - added 2 other device drivers to open http and ftp files in memory with write access. - improved the error trapping and reporting in cases where program attempts to write to a READONLY file (especially in cases where the 'file' resides in memory, as is the case when opening an ftp or http file. - modified the extended filename parser so that it is does not confuse the bracket character '[' which is sometimes used in the root name of files of type 'http://', as the start of an extname or row filter expression. If the file is of type 'http://', the parser now checks to see if the last character in the extended file name is a ')' or ']'. If not, it does not try to parse the file name any further. - improved the efficiency when writing FITS files in memory, by initially allocating enough memory for the entire HDU when it is created, rather than incrementally reallocing memory 2880 bytes at a time (modified ffrhdu and mem_truncate). This change also means that the program will fail much sooner if it cannot allocate enough memory to hold the entire FITS HDU. Bug fixes: - There was an error in the definition of the Fortran ftphtb wrapper routine (writes required ASCII table header keywords) that caused it to fail on DEC OSF and other platforms where sizeof(long) = 8. Version 2.300 - 23 Oct 2001 New Routines: - fits_comp_img and fits_decomp_img are now fully supported and documented. These routine compress and decompress, respective, a FITS image using a new algorithm in which the image is first divided into a grid of rectangular tiles, then the compressed byte stream from each tile is stored in a row of a binary table. CFITSIO can transparently read FITS images stored in this compressed format. Compression ratios of 3 - 6 are typically achieved. Large compression ratios are achieved for floating point images by throwing away non-significant noise bits in the pixel values. - fits_test_heap tests the integrity of the binary table heap and returns statistics on the amount of unused space in the heap and the amount of space that is pointed to by more than 1 descriptor. - fits_compress_heap which will reorder the arrays in the binary table heap, recovering any unused space. Enhancements: - made substantial internal changes to the code to support FITS files containing 64-bit integer data values. These files have BITPIX = 64 or TFORMn = 'K'. This new feature in CFITSIO is currently only enabled if SUPPORT_64BIT_INTEGERS is defined = 1 in the beginning of the fitsio2.h file. By default support for 64-bit integers is not enabled. - improved the ability to read and return a table column value as a formatted string by supporting quasi-legal TDISPn values which have a lowercase format code letter, and by completely ignoring other unrecognizable TDISPn values. Previously, unrecognized TDISPn values could cause zero length strings to be returned. - made fits_write_key_longstr more efficient when writing keywords using the long string CONTINUE convention. It previously did not use all the available space on each card when the string to be written contained many single quote characters. - added a new "CFITSIO Quick Start Guide" which provides all the basic information needed to write C programs using CFITSIO. - updated the standard COMMENT keywords that are written at the beginning of every primary array to refer to the newly published FITS Standard document in Astronomy and Astrophysics. Note: because of this change, any FITS file created with this version of CFITSIO will not be identical to the same file written with a previous version of CFITSIO. - replaced the 2 routines in pliocomp.c with new versions provided by D Tody and N Zarate. These routines compress/uncompress image pixels using the IRAF pixel list compression algorithm. - modified fits_copy_hdu so that when copying a Primary Array to an Image extension, the COMMENT cards which give the reference to the A&A journal article about FITS are not copied. In the inverse case the COMMENT keywords are inserted in the header. - modified configure and Makefile.in to add capability to build a shared version of the CFITSIO library. Type 'make shared' or 'make libcfitsio.so' to invoke this option. - disabled some uninformative error messages on the error stack: 1) when calling ffclos (and then ffchdu) with input status > 0 2) when ffmahd tries to move beyond the end of file. The returned status value remains the same as before, but the annoying error messages no longer get written to the error stack. - The syntax for column filtering has been modified so that if one only specifies a list of column names, then only those columns will be copied into the output file. This provides a simple way to make a copy of a table containing only a specified list of columns. If the column specifier explicitly deletes a column, however, than all the other columns will be copied to the filtered input file, regardless of whether the columns were listed or not. Similarly, if the expression specifies only a column to be modified or created, then all the other columns in the table will be copied. mytable.fit[1][col Time;Rate] - only the Time and Rate columns will be copied to the filtered input file. mytable.fit[1][col -Time ] - all but the Time column are copied to the filtered input file. mytable.fit[1][col Rate;-Time] - same as above. - changed a '#if defined' statement in f77_wrap.h and f77_wrap1.c to support the fortran wrappers on 64-bit IBM/RS6000 systems - modified group.c so that when attaching one group (the child) to another (the parent), check in each file for the existence of a pointer to the other before adding the link. This is to prevent multiple links from forming under all circumstances. - modified the filename parser to accept 'STDIN', 'stdin', 'STDOUT' and 'stdout' in addition to '-' to mean read the file from standard input or write to standard output. - Added support for reversing an axis when reading a subsection of a compressed image using the extended filename syntax, as in myfile.fits+1[-*, *] or myfile.fits+1[600:501,501:600] - When copying a compressed image to a uncompressed image, the EXTNAME keyword is no longer copied if the value is equal to 'COMPRESSED_IMAGE'. - slight change to the comment field of the DATE keyword to reflect the fact that the Unix system date and time is not true UTC time. Bug fixes: - fits_write_key_longstr was not writing the keyword if a null input string value was given. - writing data to a variable length column, if that binary table is not the last HDU in the FITS file, might overwrite the following HDU. Fixed this by changing the order of a couple operations in ffgcpr. - deleting a column from a table containing variable length columns could cause the last few FITS blocks of the file to be reset = 0. This bug occurred as a result of modifications to ffdblk in v2.202. This mainly affects users of the 'compress_fits' utility program. - fixed obscure problem when writing bits to a variable length 'B' column. - when reading a subsection of an image, the BSCALE and BZERO pixel scaling may not have been applied when reading image pixel values (even though the scaling keywords were properly written in the header). - fits_get_keyclass was not returning 'TYP_STRUCT_KEY' for the END keyword. Version 2.204 - 26 July 2001 Bug fixes: - Re-write of fits_clean_url in group.c to solve various problems with invalid bounds checking. Version 2.203 - 19 July 2001 (version in FTOOLS v5.1) Enhancements: - When a row selection or calculator expression is written in an external file (and read by CFITSIO with the '@filename' syntax) the file can now contain comment lines. The comment line must begin with 2 slash characters as the first 2 characters on the line. CFITSIO will ignore the entire line when reading the expression. Bug fixes: - With previous versions of CFITSIO, the pixel values in a FITS image could be read incorrectly in the following case: when opening a subset of a FITS image (using the 'filename.fits[Xmin:Xmax,Ymin:Ymax]' notation) on a PC linux, PC Windows, or DEC OSF machine (but not on a SUN or Mac). This problem only occurs when reading more than 8640 bytes of data (2160 4-byte integers) at a time, and usually only occurs if the reading program reads the pixel data immediately after opening the file, without first reading any header keywords. This error would cause strips of zero valued pixels to appear at semi-random positions in the image, where each strip usually would be 2880 bytes long. This problem does not affect cases where the input subsetted image is simply copied to a new output FITS file. Version 2.202 - 22 May 2001 Enhancements: - revised the logic in the routine that tests if a point is within a region: if the first region is an excluded region, then it implicitly assumes a prior include region covering the entire detector. It also now supports cases where a smaller include region is within a prior exclude region. - made enhancement to ffgclb (read bytes) so that it can also read values from a logical column, returning an array of 1s and 0s. - defined 2 new grouping error status values (349, 350) in cfitsio.h and made minor changes to group.c to use these new status values. - modified fits_open_file so that if it encounters an error while trying to move to a user-specified extension (or select a subset of the rows in an input table, or make a histogram of the column values) it will close the input file instead of leaving it open. - when using the extended filename syntax to filter the rows in an input table, or create a histogram image from the values in a table column, CFITSIO now writes HISTORY keywords in the output file to document the filtering expression that was used. Bug fixes: - ffdblk (called by ffdrow) could overwrite the last FITS block(s) in the file in some cases where one writes data to a variable length column and then calls ffdrow to delete rows in the table. This bug was similar to the ffiblk bug that was fixed in v2.033. - modified fits_write_col_null to fix a problem which under unusual circumstances would cause a End-of-File error when trying to read back the value in an ASCII string column, after initializing if by writing a null value to it. - fixed obscure bug in the calculator function that caused an error when trying to modify the value of a keyword in a HDU that does not have a NAXIS2 keyword (e.g., a null primary array). - the iterator function (in putcol.c) had a bug when calculating the optimum number rows to process in the case where the table has very wide rows (>33120 bytes) and the calculator expression involves columns from more than one FITS table. This could cause an infinite loop in calls to the ffcalc calculator function. - fixed bug in ffmvec, which modifies the length of an existing vector column in a binary table. If the vector was reduced in length, the FITS file could sometimes be left in a corrupted state, and in all cases the values in the remaining vector elements of that column would be altered. - in drvrfile.c, replaced calls to fsetpos and fgetpos with fseek and ftell (or fseeko and ftello) because the fpos_t filetype used in fsetpos is incompatible with the off_t filetype used in fseek, at least on some platforms (Linux 7.0). (This fix was inserted into the V2.201 release on April 4). - added "#define fits_write_pixnull ffppxn" to longnam.h Version 2.201 - 15 March 2001 Enhancements - enhanced the keyword reading routines so that they will do implicit datatype conversion from a string keyword value to a numeric keyword value, if the string consist of a valid number enclosed in quotes. For example, the keyword mykey = '37.5' can be read by ffgkye. - modified ffiimg so that it is possible to insert a new primary array at the beginning of the file. The original primary array is then converted into an IMAGE extension. - modified ffcpdt (copy data unit) to support the case where the data unit is being copied between 2 HDUs in the same file. - enhanced the fits_read_pix and fits_read_pixnull routines so that they support the tiled image compression format that the other image reading routines also support. - modified the Extended File Name syntax to also accept a minus sign (-) as well as an exclamation point (!) as the leading character when specifying a column or or keyword to be deleted, as in [col -time] will delete the TIME column. - now completely support reading subimages, including pixel increments in each dimension, for tile-compressed images (where the compressed image tiles are stored in a binary table). Bug fixes: - fixed confusion in the use of the fpos_t and off_t datatypes in the fgetpos and fsetpos routines in drvrfile.c which caused problems with the Windows VC++ compiler. (fpos_t is not necessarily identical to off_t) - fixed a typo in the fits_get_url function in group.c which caused problems when determining the relative URL to a compressed FITS file. - included fitsio.h in the shared memory utility program, smem.c, in order to define OFF_T. - fixed typo in the datatype of 'nullvalue' in ffgsvi, which caused attempts to read subsections of a short integer tiled compressed image to fail with a bus error. - fixed bug in ffdkey which sometimes worked incorrectly if one tried to delete a nonexistent keyword beyond the end of the header. - fixed problem in fits_select_image_section when it writes a dummy value to the last pixel of the section. If the image contains scaled integer pixels, then in some cases the pixel value could end up out of range. - fixed obscure bug in the ffpcn_ family of routines which gave a floating exception when trying to write zero number of pixels to a zero length array (why would anyone do this?) Version 2.200 - 26 Jan 2001 Enhancements - updated the region filtering code to support the latest region file formats that are generated by the POW, SAOtng and ds9 programs. Region positions may now be given in HH:MM:SS.s, DD:MM:SS.s format, and region sizes may be given arcsec or arcmin instead of only in pixel units. Also changed the logic so that if multiple 'include' regions are specified in the region file, they are ORed together, instead of ANDed, so that the filtering keeps points that are located within any of the 'include' regions, not just the intersection of the regions. - added support for reading raw binary data arrays by converting them on the fly into virtual FITS files. - modified ffpmsg, which writes error messages to CFITSIO's internal error stack, so that messages > 80 characters long will be wrapped around into multiple 80 character messages, instead of just being truncated at 80 characters. - modified the CFITSIO parser so that expression which involve scaled integer columns get cast to double rather than int. - Modified the keyword template parsing routine, ffgthd, to support the HIERARCH keyword. - modified ffainit and ffbinit so that they don't unnecessarily allocate 0 bytes of memory if there are no columns (TFIELDS = 0) in the table that is being opened. - modified fitsio2.h to support NetBSD on Alpha OSF platforms (NetBSD does not define the '__unix__' symbol). - changed the way OFF_T is defined in fitsio.h for greater portability. - changed drvrsmem.c so it is compiled only when HAVE_SHMEM_SERVICES is defined in order to removed the conditional logic from the Makefile - reorganized the CFITSIO User's guide to make it clearer and easier for new users to learn the basic routines. - fixed ffhdef (which reserves space for more header keywords) so that is also updates the start position of the next HDU. This affected the offset values returned by ffghof. Version 2.100 - 18 Oct 2000 Enhancements - made substantial modification to the code to support Large files, i.e., files larger than 2**31 bytes = 2.1GB. FITS files up to 6 terabytes in size may now be read and written on platforms that support Large files (currently only Solaris). - modified ffpcom and ffphis, which write COMMENT and HISTORY keywords, respectively, so that they now use columns 9 - 80, instead of only columns 11 - 80. Previously, these routines avoided using columns 9 and 10, but this is was unnecessarily restrictive. - modified ffdhdu so that instead of refusing to delete the primary array, it will replace the current primary array with a null primary array containing the bare minimum of required keywords and no data. New Routines - fits_read_pix, fits_read_pixnull, fits_read_subset, and fits_write_pix routines were added to enable reading and writing of Large images, with more than 2.1e9 pixels. These new routines are now recommended as the basic routines for reading and writing all images. - fits_get_hduoff returns the byte offset in the file to the start and end of the current HDU. This routine replaces the now obsolete fits_get_hduaddr routine; it uses 'off_t' instead of 'long' as the datatype of the arguments and can support offsets in files greater than 2.1GB in size. Bug fixes: - fixed bug in fits_select_image_section that caused an integer overflow when reading very large image sections (bigger than 8192 x 8192 4-byte pixels). - improved ffptbb, the low-level table writing routine, so that it will insert additional rows in the table if the table is not already big enough. Previously it would have just over- written any HDUs following the table in the FITS file. - fixed a bug in the fits_write_col_bit/ffpclx routine which could not write to a bit 'X' column if that was the first column in the table to be written to. This bug would not appear if any other datatype column was written to first. - non-sensible (but still formally legal) binary table TFORM values such as '8A15', or '1A8' or 'A8' would confuse CFITSIO and cause it to return a 308 error. When parsing the TFORMn = 'rAw' value, the ffbnfm routine has been modified to ignore the 'w' value in cases where w > r. - fixed bug in the blsearch routine in iraffits.c which sometimes caused an out-of-bounds string pointer to be returned when searching for blank space in the header just before the 'END' keyword. - fixed minor problem in ffgtcr in group.c, which sometimes failed while trying to move to the end of file before appending a grouping table. - on Solaris, with Sun CC 5.0, one must check for '__unix' rather than '__unix__' or 'unix' as it's symbol. Needed to modify this in drvrfile.c in 3 places. - in ffextn, the FITS file would be left open if the named extension doesn't exist, thus preventing the file from being opened again later with write access. - fixed bug in ffiimg that would cause attempts to insert a new image extension following a table extension, and in front of any other type of extension, to fail. Version 2.037 - 6 July 2000 Enhancements - added support in the extended filename syntax for flipping an image along any axis either by specifying a starting section pixel number greater than the ending pixel number, or by using '-*' to flip the whole axis. Examples: "myfile.fits[1:100, 50:10]" or "myfile.fits[-*,*]". - when reading a section of an image with the extended filename syntax (e.g. image.fits[1:100:2, 1:100:2), any CDi_j WCS keywords will be updated if necessary to transfer the world coordinate system from the input image to the output image section. - on UNIX platforms, added support for filenames that begin with "~/" or "~user/". The "~" symbol will get expanded into a string that gives the user's home directory. - changed the filename parser to support disk file names that begin with a minus sign. Previously, the leading minus sign would cause CFITSIO to try to read/write the file from/to stdin/stdout. - modified the general fits_update_key routine, which writes or updates a keyword value, to use the 'G' display format instead of the 'E' format for floating point keyword values. This will eliminate trailing zeros from appearing in the value. - added support for the "-CAR" celestial coordinate projection in the ffwldp and ffxypx routines. The "-CAR" projection is the default simplest possible linear projection. - added new fits_create_memfile/ffimem routine to create a new fits file at a designated memory location. - ported f77_wrap.h and f77_wrap1.c so that the Fortran interface wrappers work correctly on 64-bit SGI operating systems. In this environment, C 'long's are 8-bytes long, but Fortran 'integers' are still only 4-bytes long, so the words have to be converted by the wrappers. - minor modification to cfortran.h to automatically detect when it is running on a linux platform, and then define f2cFortran in that case. This eliminates the need to define -Df2cFortran on the command line. - modified group.c to support multiple "/" characters in the path name of the file to be opened/created. - minor modifications to the parser (eval.y, eval_f.c, eval_y.c) to a) add the unary '+' operator, and b) support copying the TDIMn keyword from the input to the output image under certain circumstances. - modified the lexical parser in eval_l.y and eval_l.c to support #NULL and #SNULL constants which act to set the value to Null. Support was also added for the C-conditional expression: 'Boolean ? trueVal : falseVal'. - small modification to eval_f.c to write an error message to the error stack if numerical overflow occurs when evaluating an expression. - configure and configure.in now support the egcs g77 compiler on Linux platforms. Bug fixes: - fixed a significant bug when using the extended filename binning syntax to generate a 2-dimensional image from a histogram of the values in 2 table columns. This bug would cause table events that should have been located in the row just below the bottom row of the image (and thus should have been excluded from the histogram) to be instead added into the first row of the image. Similarly, the first plane of a 3-D or 4-D data cube would include the events that should have been excluded as falling in the previous plane of the cube. - fixed minor bug when parsing an extended filename that contains nested pairs of square brackets (e.g., '[col newcol=oldcol[9]]'). - fixed bug when reading unsigned integer values from a table or image with fits_read_col_uint/ffgcvuk. This bug only occurred on systems like Digital Unix (now Tru64 Unix) in which 'long' integers are 8 bytes long, and only when reading more than 7200 elements at a time. This bug would generally cause the program to crash with a segmentation fault. - modified ffgcpr to update 'heapstart' as well as 'numrows' when writing more rows beyond the end of the table. heapstart is needed to calculate if more space needs to be inserted in the table when inserting columns into the table. - modified fficls (insert column), ffmvec, ffdrow and ffdcol to not use the value of the NAXIS2 keyword as the number of rows in the table, and instead use the value that is stored in an internal structure, because the keyword value may not be up to date. - Fixed bug in the iterator function that affected the handling of null values in string columns in ASCII and binary tables. - Reading a subsample of pixels in very large images, (e.g., file = myfile.fits[1:10000:10,1:10000:10], could cause a long integer overflow (value > 2**31) in the computation of the starting byte offset in the file, and cause a return error status = 304 (negative byte address). This was fixed by changing the order of the arithmetic operations in calculating the value of 'readptr' in the ffgcli, ffgclj, ffgcle, ffgcld, etc. routines. - In version 2.031, a fix to prevent compressed files from being opened with write privilege was implemented incorrectly. The fix was intended to not allow a compressed FITS file to be opened except when a local uncompressed copy of the file is being produced (then the copy is opened with write access), but in fact the opposite behavior occurred: Compressed files could be opened with write access, EXCEPT when a local copy is produced. This has been fixed in the mem_compress_open and file_compress_open routines. - in iraffits.c, a global variable called 'val' caused multiply defined symbols warning when linking cfitsio and IRAF libraries. This was fixed by making 'val' a local variable within the routine. Version 2.036 - 1 Feb 2000 - added 2 new generic routines, ffgpf and ffgcf which are analogous to ffgpv and ffgcv but return an array of null flag values instead of setting null pixels to a reserved value. - minor change to eval_y.c and eval.y to "define alloca malloc" on all platforms, not just VMS. - added support for the unsigned int datatype (TUINT) in the generic ffuky routine and changed ffpky so that unsigned ints are cast to double instead of long before being written to the header. - modified ffs2c so that if a null string is given as input then a null FITS string (2 successive single quotes) will be returned. Previously this routine would just return a string with a single quote, which could cause an illegal keyword record to be written. - The file flush operation on Windows platforms apparently changes the internal file position pointer (!) in violation of the C standard. Put a patch into the file_flush routine to explicitly seek back to the original file position. - changed the name of imcomp_get_compressed_image_parms to imcomp_get_compressed_image_par to not exceed the 31 character limit on some compilers. - modified the filename parser (which is used when moving to a named HDU) to support EXTNAME values which contain embedded blanks. - modified drvrnet.c to deal with ftp compressed files better so that even fits files returned from cgi queries which have the wrong mime types and/or wrong types of file names should still decompress. - modified ffgics to reduce the tolerance for acceptable skewness between the axes, and added a new warning return status = APPROX_WCS_KEY in cases where there is significant skewness between the axes. - fixed bug in ffgics that affected cases where the first coordinate axis was DEC, not RA, and the image was a mirror image of the sky. - fixed bug in ffhist when trying to read the default binning factor keyword, TDBIN. - modified ffhist so that is correctly computes the rotation angle in a 2-D image if the first histogram column has a CROTA type keyword but the 2nd column does not. - modified ffcpcl so that it preserves the comment fields on the TTYPE and TFORM keywords when the column is copied to a new file. - make small change to configure.in to support FreeBSD Linux by setting CFLAGS = -Df2cFortran instead of -Dg77Fortran. Then regenerated configure with autoconf 2.13 instead of 2.12. Version 2.035 - 7 Dec 1999 (internal release only, FTOOLS 5.0.2) - added new routine called fits_get_keyclass/ffgkcl that returns the general class of the keyword, e.g., required structural keyword, WCS keyword, Comment keyword, etc. 15 classes of keywords have been defined in fitsio.h - added new routine called fits_get_img_parm/ffgipr that is similar to ffgphd but it only return the bitpix, naxis, and naxisn values. - added 3 new routines that support the long string keyword convention: fits_insert_key_longstr, fits_modify_key_longstr fits_update_key_longstr. - modified ffgphd which reads image header keywords to support the new experimental compressed image format. - when opening a .Z compressed file, CFITSIO tries to allocate memory equal to 3 times the file size, which may be excessive in some cases. This was changed so that if the allocation fails, then CFITSIO will try again to allocate only enough memory equal to 1 times the file size. More memory will be allocated later if this turns out to be too small. - improved the error checking in the fits_insert_key routine to check for illegal characters in the keyword. Version 2.034 - 23 Nov 1999 - enhanced support for the new 'CD' matrix world coordinate system keywords in the ffigics routine. This routine has been enhanced to look for the new 'CD' keywords, if present, and convert them back to the old CDELTn and CROTAn values, which are then returned. The routine will also swap the WCS parameters for the 2 axes if the declination-like axis is the first WCS axis. - modified ffphbn in putkey.c to support the 'U' and 'V" TFORM characters (which represent unsigned short and unsigned int columns) in variable length array columns. (previously only supported these types in fixed length columns). - added checks when reading gzipped files to detect unexpected EOF. Previously, the 'inflate_codes' routine would just sit in an infinite loop if the file ended unexpectedly. - modified fits_verify_chksum/ffvcks so that checksum keywords with a blank value string are treated as undefined, the same as if the keyword did not exist at all. - fixed ffghtb and ffghbn so that they return the extname value in cases where there are no columns in the table. - fixed bug in the ffgtwcs routine (this is a little utility routine to aid in interfacing to Doug Mink's WCS routines); it was not correctly padding the length of string-valued keywords in the returned string. - fixed bug in 'iraffits.c' that prevented Type-2 IRAF images from being correctly byte-swapped on PCs and DEC-OSF machines. - fixed tiny memory leak in irafncmp in iraffits.c. Only relevant when reading IRAF .imh files. - fixed a bug (introduced in version 2.027) that caused the keyword reading routines to sometimes not find a matching keyword if the input name template used the '*' wildcard as the last character. (e.g., if input name = 'COMMENT*' then it would not find the 'COMMENT' keywords. (It would have found longer keywords like 'COMMENTX' correctly). The fix required a minor change to ffgcrd in getkey.c - modified the routine (ffswap8) that does byteswapping of double precision numbers. Some linux systems have reported floating point exceptions because they were trying to interpret the bytes as a double before the bytes had been swapped. - fixed bug in the calculation of the position of the last byte in the string of bits to be read in ffgcxuk and ffgcxui. This bug generally caused no harm, but could cause the routine to exit with an invalid error message about trying to read beyond the size of the field. - If a unix machine did not have '__unix__', 'unix', or '__unix' C preprocessor symbols defined, then CFITSIO would correctly open one FITS file, but would not correctly open subsequent files. Instead it would think that the same file was being opened multiple times. This problem has only been seen on an IBM/AIX machine. The fits_path2url and fits_url2path routines in group.c were modified to fix the problem. - fixed bug in group.c, which affected WINDOWS platforms only, that caused programs to go into infinite loop when trying to open certain files. - the ftrsim Fortran wrapper routine to ffrsim was not defined correctly, which caused the naxis(2) value to be passed incorrectly on Dec OSF machines, where sizeof(long) != sizeof(int). Version 2.033 - 17 Sept 1999 - New Feature: enhanced the row selection parser so that comparisons between values in different rows of the table are allowed, and the string comparisons with <, >, <=, and >= are supported. - added new routine the returns the name of the keyword in the input keyword record string. The name is usually the first 8 characters of the record, except if the HIERARCH convention is being used in which case the name may be up to 67 characters long. - added new routine called fits_null_check/ffnchk that checks to see if the current header contains any null (ASCII 0) characters. These characters are illegal in FITS headers, but they go undetected by the other CFITSIO routines that read the header keywords. - the group.c file has been replaced with a new version as supplied by the ISDC. The changes are mainly to support partial URLs and absolute URLs more robustly. Host dependent directory paths are now converted to true URLs before being read from/written to grouping tables. - modified ffnmhd slightly so that it will move to the first extension in which either the EXTNAME or the HDUNAME keyword is equal to the user-specified name. Previously, it only checked for HDUNAME if the EXTNAME keyword did not exist. - made small change to drvrnet.c so that it uncompress files which end in .Z and .gz just as for ftp files. - rewrote ffcphd (copy header) to handle the case where the input and output HDU are in the same physical FITS file. - fixed bug in how long string keyword values (using the CONTINUE convention) were read. If the string keyword value ended in an '&' character, then fits_read_key_longstr, fits_modify_key_str, and fits_delete_key would interpret the following keyword as a continuation, regardless of whether that keyword name was 'CONTINUE' as required by this convention. There was also a bug in that if the string keyword value was all blanks, then fits_modify_key_str could in certain unusual cases think that the keyword ended in an '&' and go into an infinite loop. - modified ffgpv so that it calls the higher level ffgpv_ routine rather than directly calling the lower level ffgcl_ routine. This change is needed to eventually support reading compressed images. - added 3 new routines to get the image datatype, image dimensions, and image axes length. These support the case where the image is compressed and stored in a binary table. - fixed bug in ffiblk that could sometimes cause it to insert a new block in a file somewhere in the middle of the data, instead of at the end of the HDU. This fortunately is a rare problem, mainly only occurring in certain cases when inserting rows in a binary table that contains variable length array data (i.e., has a heap). - modified fits_write_tdim so that it double checks the TFORMn value directly if the column repeat count stored in the internal structure is not equal to the product of all the dimensions. - fixed bug that prevented ffitab or ffibin from inserting a new table after a null primary array (can't read NAXIS2 keyword). Required a small change to ffrdef. - modified testprog.c so that it will continue to run even if it cannot open or process the template file testprog.tpt. - modified the logic in lines 1182-1185 of grparser.c so that it returns the correct status value in case of an error. - added test in fitsio2.h to see if __sparcv9 is defined; this identifies a machine running Solaris 7 in 64-bit mode where long integers are 64 bits long. Version 2.032 - 25 May 1999 - the distribution .tar file was changed so that all the files will be untarred into a subdirectory by default instead of into the current directory. - modified ffclos so that it always frees the space allocated by the fptr pointer, even when another fptr points to the same file. - plugged a potential (but rare in practice) memory leak in ffpinit - fixed bug in all the ffp3d_ and ffg3d_ routines in cases where the data cube that has been allocated in memory has more planes than the data cube in the FITS file. - modified drvrsmem.c so that it allocates a small shared memory segment only if CFITSIO tries to read or write a FITS file in shared memory. Previously it always allocated the segment whether it was needed or not. Also, this small segment is removed if 0 shared memory segments remain in the system. - put "static" in front of 7 DECLARE macros in compress.c because these global variables were causing conflicts with other applications programs that had variables with the same names. - modified ffasfm to return datatype = TDOUBLE instead of TFLOAT if the ASCII table column has TFORMn = 'Ew.d' with d > 6. - modified the column reading routines to a) print out the offending entry if an error occurs when trying to read a numeric ASCII table column, and b) print out the column number that had the error (the messages are written to CFITSIOs error stack) - major updates to the Fortran FITSIO User's Guide to include many new functions that have been added to CFITSIO in the past year. - modified fitsio2.h so that the test for __D_FLOAT etc. is only made on Alpha VMS machines, to avoid syntax errors on some other platforms. - modified ffgthd so that it recognizes a floating point value that uses the 'd' or 'D' exponent character. - removed the range check in fftm2s that returned an error if 'decimals' was less than zero. A negative value is OK and is used to return only the date and not the time in the string. Version 2.031 - 31 Mar 1999 - moved the code that updates the NAXIS2 and PCOUNT keywords from ffchdu into the lower lever ffrdef routine. This ensures that other routines which call ffrdef will correctly update these 2 keywords if required. Otherwise, for instance, calling fits_write_checksum before closing the HDU could cause the NAXIS2 keyword (number of rows in the table) to not be updated. - fixed bug (introduced in version 2.030) when writing null values to a primary array or image extension. If trying to set more than 1 pixel to null at a time, then typically only 1 null would be written. Also fixed related bug when writing null values to rows in a table that are beyond the currently defined size of the table (the size of the table was not being expanded properly). - enhanced the extended filename parser to support '*' in image section specifiers, to mean use the whole range of the axis. myfile.fits[*,1:100] means use the whole range of the first axis and pixels 1 to 100 in the second axis. Also supports an increment, as in myfile.fits[*:2, *:2] to use just the odd numbered rows and columns. - modified fitscore.c to set the initial max size of the header, when first reading it, to the current size of the file, rather than to 2 x 10**9 to avoid rare cases where CFITSIO ends up writing a huge file to disk. - modified file_compress_open so that it will not allow a compressed FITS file to be opened with write access. Otherwise, a program could write to the temporary copy of the uncompressed file, but the modification would be lost when the program exits. Version 2.030 - 24 Feb 1999 - fixed bug in ffpclu when trying to write a null value to a row beyond the current size of the table (wouldn't append new rows like it should). - major new feature: enhanced the routines that read ASCII string columns in tables so that they can read any table column, including logical and numeric valued columns. The column values are returned as a formatted string. The format is determined by the TDISPn keyword if present, otherwise a default format based on the datatype of the column is used. - new routine: fits_get_col_display_width/ffgcdw returns the length of the formatted strings that will be returned by the routines that read table columns as strings. - major new feature: added support for specifying an 'image section' when opening an image: e.g, myfile.fits[1:512:2,2:512:2] to open a 256x256 pixel image consisting of the odd columns and the even numbered rows of the input image. - added supporting project files and instructions for building CFITSIO under Windows NT with the Microsoft Visual C++ compiler. - changed the variable 'template' to 'templt' in testprog.c since it conflicted with a reserved word on some compilers. - modified group.c to conditionally include sys/stat.h only on unix platforms - fixed bug in the ffiter iterator function that caused it to always pass 'firstn' = 1 to the work function when reading from the primary array or IMAGE extension. It worked correctly for tables. - fixed bug in the template header keyword parser (ffgthd) in cases where the input template line contains a logical valued keyword (T or F) without any following comment string. It was previously interpreting this as a string-valued keyword. - modified ffrhdu that reads and opens a new HDU, so that it ignores any leading blank characters in the XTENSION name, e.g., XTENSION= ' BINTABLE' will not cause any errors, even though this technically violates the FITS Standard. - modified ffgtbp that reads the required table keywords to make it more lenient and not exit with an error if the THEAP keyword in binary tables cannot be read as an integer. Now it will simply ignore this keyword if it cannot be read. - added test for 'WIN32' as well as '__WIN32__' in fitsio2.h, eval.l and eval_l.c in a preprocessor statement. - changed definition of strcasecmp and strncasecmp in fitsio2.h, eval.l and eval_l.c to conform to the function prototypes under the Alpha VMS v7.1 compiler. - corrected the long function names in longnam.h for the new WCS utility functions in wcssubs.c Version 2.029 - 11 Feb 1999 - fixed bug in the way NANs and underflows were being detected on VAX and Alpha VMS machines. - enhanced the filename parser to distinguish between a VMS-style directory name (e.g. disk:[directory]myfile.fits) and a CFITSIO filter specifier at the end of the name. - modified ffgthd to support the HIERARCH convention for keyword names that are longer than 8 characters or contain characters that would be illegal in standard FITS keyword names. - modified the include statements in grparser.c so that malloc.h and memory.h are only included on the few platforms that really need them. - modified the file_read routine in drvrfile.c to ignore the last record in the FITS file it it only contains a single character that is equal to 0, 10 or 32. Text editors sometimes append a character like this to the end of the file, so CFITSIO will ignore it and treat it as if it had reached the end of file. - minor modifications to fitsio.h to help support the ROOT environment. - installed new version of group.c and group.h; the main change is to support relative paths (e.g. "../filename") in the URLs - modified the histogramming routines so that it looks for the default preferred column axes in a keyword of the form CPREF = 'Xcol, Ycol' instead of separate keywords of the form CPREF1 = 'Xcol' CPREF2 = 'Ycol' - fixed bug so that if the binning spec is just a single integer, as in [bin 4] then this will be interpreted as meaning to make a 2D histogram using the preferred or default axes, with the integer taken as the binning factor in both axes. Version 2.028 - 27 Jan 1999 - if the TNULLn keyword value was outside the range of a 'I' or 'B' column, an overflow would occur when setting the short or char to the TNULLn value, leading to incorrect values being flagged as being undefined. This has been fixed so that CFITSIO will ignore TNULLn values that are beyond the range of the column data type. - changed a few instances of the string {"\0"} to {'\0'} in the file groups.c - installed new version of the grparser.c file from the ISDC - added new WCS support routines (in wcssub.c) which make it easier to call Doug Mink's WCSlib routines for converting between plate and sky coordinates. The CFITSIO routines themselves never call a WCSlib routine, so CFITSIO is not dependent on WCSlib. - modified ffopen so that if you use the extended filename syntax to both select rows in a table and then bin columns into a histogram, then CFITSIO will simply construct an array listing the good row numbers to be used when making the histogram, instead of making a whole new temporary FITS file containing the selected rows. - modified ffgphd which parses the primary array header keywords when opening a file, to not choke on minor format errors in optional keywords. Otherwise, this prevents CFITSIO from even opening the file. - changed a few more variable declarations in compress.c from global to static. Version 2.027 - 12 Jan 1999 - modified the usage of the output filename specifier so that it, a) gives the name of the binned image, if specified, else, b) gives the name of column filtered and/or row filtered table, if specified, else c) is the name for a local copy of the ftp or http file, else, d) is the name for the local uncompressed version of the compressed FITS file, else, e) the output filename is ignored. - fixed minor bug in ffcmps, when comparing 2 strings while using a '*' wild card character. - fixed bug in ftgthd that affected cases where the template string started with a minus sign and contained 2 tokens (to rename a keyword). - added support for the HIERARCH keyword convention for reading and writing keywords longer than 8 characters or that contain ASCII characters not allowed in normal FITS keywords. - modified the extended filename syntax to support opening images that are contained in a single cell of a binary table with syntax: filename.fits[extname; col_name(row_expression)] Version 2.026 - 23 Dec 1998 - modified the group parser to: a) support CFITSIO_INCLUDE_FILES environment variable, which can point to the location of template files, and, b) the FITS file parameter passed to the parser no longer has to point to an empty file. If there are already HDUs in the file, then the parser appends new HDUs to the end of the file. - make a small change to the drvrnet.c file to accommodate creating a static version of the CFITSIO library. - added 2 new routines to read consecutive bits as an unsigned integer from a Bit 'X' or Byte 'B' column (ffgcxui and ffgcxuk). - modified the logic for determining histogram boundaries in ffhisto to add one more bin by default, to catch values that are right on the upper boundary of the histogram, or are in the last partial bin. - modified cfitsio2.h to support the new Solaris 7 64-bit mode operating system. - Add utility routine, CFits2Unit, to the Fortran wrappers which searches the gFitsFiles array for a fptr, returning its element (Fortran unit number), or allocating a new element if one doesn't already exists... for C calling Fortran calling CFITSIO. - modified configure so that it does not use the compiler optimizer when using gcc 2.8.x on Linux - (re)added the fitsio.* documentation files that describe the Fortran-callable FITSIO interface to the C routines. - modified the lexical parser in eval_f.c to fix bug in null detections and bug in ffsrow when nrows = 0. - modified ffcalc so that it creates a TNULLn keyword if appropriate when a new column is created. Also fixed detection of OVERFLOWs so that it ignores null values. - added hyperbolic trig and rounding functions to the lexical parser in the eval* files. - improved error message that gets written when the group number is out of range when reading a 'random groups' array. - added description of shared memory, grouping, and template parsing error messages to ffgerr and to the User's Guide. Moved the error code definitions from drvsmem.h to fitsio.h. - modified grparser.c to compile correctly on Alpha/OSF machines - modified drvrnet.c to eliminate compiler warnings - Modified Makefile.in to include targets for building all the sample programs that are included with CFITSIO. Version 2.025 - 1 Dec 1998 - modified ffgphd and ffgtbp so that they ignores BLANK and TNULLn keywords that do not have a valid integer value. Also, any error while reading the BSCALE, BZERO, TSCALn, or TZEROn keywords will be ignored. Previously, CFITSIO would have simply refused to read an HDU that had such an invalid keyword. - modified the parser in eval_f.c to accept out of order times in GTIs - updated cfitsio_mac.sit.hqx to fix bad target parameters for Mac's speed test program - modified template parser in grparser.c to: 1) not write GRPNAME keyword twice, and 2) assign correct value for EXTVERS keyword. - fixed minor bugs in group.c; mainly would only affect users of the INTEGRAL Data Access Layer. - temporarily removed the prototype for ffiwcs from fitsio.h until full WCS support is added to CFITSIO in the near future. - modified the HTTP driver to send a User-Agent string: HEASARC/CFITSIO/ - declared local variables in compress.c as 'static' to avoid conflicts with other libraries. Version 2.024 - 9 Nov 1998 - added new function fits_url_type which returns the driver prefix string associated with a particular FITS file pointer. Version 2.023 - 1 Nov 1998 - first full release of CFITSIO 2.0 - slightly modified the way real keyword values are formatted, to ensure that it includes a decimal point. E.g., '1.0E-09' instead of '1E-09' - added new function to support template files when creating new FITS files. - support the TCROTn WCS keyword in tables, when reading the WCS keywords. - modified the iterator to support null values in logical columns in binary tables. - fixed bug in iterator to support null values in integer columns in ASCII tables. - changed the values for FLOATNULLVALUE and DOUBLENULLVALUE to make them less likely to duplicate actual values in the data. - fixed major bug when freeing memory in the iterator function. It caused mysterious crashes on a few platforms, but had no effect on most others. - added support for reading IRAF format image (.imh files) - added more error checking to return an error if the size of the FITS file exceeds the largest value of a long integer (2.1 GB on 32-bit platforms). - CFITSIO now will automatically insert space for additional table rows or add space to the data heap, if one writes beyond the current end of the table or heap. This prevents any HDUs which might follow the current HDU from being overwritten. It is thus no longer necessary to explicitly call fits_insert_rows before writing new rows of data to the FITS file. - CFITSIO now automatically keeps track of the number of rows that have been written to a FITS table, and updates the NAXIS2 keyword accordingly when the table is closed. It is no longer necessary for the application program to updated NAXIS2. - When reading from a FITS table, CFITSIO will now return an error if the application tries to read beyond the end of the table. - added 2 routines to get the number of rows or columns in a table. - improved the undocumented feature that allows a '20A' column to be read as though it were a '20B' column by fits_read_col_byt. - added overflow error checking when reading keywords. Previously, the returned value could be silently truncated to the maximum allowed value for that data type. Now an error status is returned whenever an overflow occurs. - added new set of routines dealing with hierarchical groups of files. These were provided by Don Jennings of the INTEGRAL Science Data Center. - added new URL parsing routines. - changed the calling sequence to ffghad (get HDU address) from ffghad(fitsfile *fptr, > long *headstart, long *dataend) to ffghad(fitsfile *fptr, > long *headstart, long datastart, long *dataend, int *status) - major modification to support opening the same FITS file more than once. Now one can open the same file multiple times and read and write simultaneously to different HDUs within the file. fits_open_file automatically detects if the file is already opened. - added the ability to clobber/overwrite an existing file with the same name when creating a new output file. Just precede the output file name with '!' (an exclamation mark) - changed the ffpdat routine which writes the DATE keyword to use the new 'YYYY-MM-DDThh:mm:ss' format. - added several new routines to create or parse the new date/time format string. - changed ifdef for DECFortran in f77_wrap.h and f77_wrap1.c: expanded to recognize Linux/Alpha - added new lexical parsing routines (from Peter Wilson): eval_l.c, eval_y.c, eval_f.c, eval_defs.h, and eval_tab.h. These are used when doing on-the-fly table row selections. - added new family of routines to support reading and writing 'unsigned int' data type values in keywords, images or tables. - restructured all the putcol and getcol routines to provide simpler and more robust support for machines which have sizeof(long) = 8. Defined a new datatype INT32BIT which is always 32 bits long (platform independent) and is used internally in CFITSIO when reading or writing BITPIX = 32 images or 'J' columns. This eliminated the need for specialize routines like ffswaplong, ffunswaplong, and ffpacklong. - overhauled cfileio.c (and other files) to use loadable drivers for doing data I/O to different devices. Now CFITSIO support network access to ftp:// and http:// files, and to shared memory files. - removed the ffsmem routine and replaced it with ffomem. This will only affect software that reads an existing file in core memory. (written there by some other process). - modified all the ffgkn[] routines (get an array of keywords) so that the 'nfound' parameter is = the number of keywords returned, not the highest index value on the returned keywords. This makes no difference if the starting index value to look for = 1. This change is not backward compatible with previous versions of CFITSIO, but is the way that FITSIO behaved. - added new error code = 1 for any application error external to CFITSIO. Also reports "unknown error status" if the value doesn't match a known CFITSIO error. Version 1.42 - 30 April 1998 (included in FTOOLS 4.1 release) - modified the routines which read a FITS float values into a float array, or read FITS double values into a double array, so that the array value is also explicitly set in addition to setting the array of flag values, if the FITS value is a NaN. This ensures that no NaN values get passed back to the calling program, which can cause serious problems on some platforms (OSF). - added calls to ffrdef at the beginning of the insert or delete rows or columns routines in editcol.c to make sure that CFITSIO has correctly initialized the HDU information. - added new routine ffdrws to delete a list of rows in a table - added ffcphd to copy the header keywords from one hdu to another - made the anynul parameter in the ffgcl* routines optional by first checking to see if the pointer is not null before initializing it. - modified ffbinit and ffainit to ignore minor format errors in header keywords so that cfitsio can at least move to an extension that contains illegal keywords. - modified all the ffgcl* routines to simply return without error if nelem = 0. - added check to ffclose to check the validity of the fitsfile pointer before closing it. This should prevent program crashes when someone tries to close the same file more than once. - replaced calls to strcmp and strncmp with macros FSTRCMP and FSTRNCMP in a few places to improve performance when reading header keywords (suggested by Mike Noble) Bug Fixes: - fixed typo in macro definition of error 504 in the file fitsio.h. - in ffopen, reserved space for 4 more characters in the input file name in case a '.zip' suffix needs to be added. - small changes to ffpclx to fix problems when writing bit (X) data columns beyond the current end of file. - fixed small bug in ffcrhd where a dummy pointer was not initialized - initialized the dummy variable in ffgcfe and ffgcfd which was causing crashes under OSF in some cases. - increased the length of the allocated string ffgkls by 2 to support the case of reading a numeric keyword as a string which doesn't have the enclosing quote characters. Version 1.4 - 6 Feb 1998 - major restructuring of the CFITSIO User's Guide - added the new 'iterator' function. The fortran wrapper is in f77_iter.c for now. - enhanced ffcrtb so that it writes a dummy primary array if none currently exists before appending the table. - removed the ffgcl routine and replaced it with ffgcvl - modified ffpcnl to just take a single input null value instead of an entire array of null value flags. - modified ffcmps and ffgnxk so that, for example, the string 'rate' is not considered a match to the string 'rate2', and 'rate*' is a match to the string 'rate'. - modified ffgrsz to also work with images, in which case it returns the optimum number of pixels to process at one time. - modified ffgthd to support null valued keywords - added a new source file 'f77_wrap.c' that includes all the Fortran77 wrapper routines for calling CFITSIO. This will eventually replace the Fortran FITSIO library. - added new routines: ffppn - generic write primary array with null values ffpprn - write null values to primary array ffuky - 'update' a keyword value, with any specified datatype. ffrprt - write out report of error status and error messages ffiter - apply a user function iteratively to all the rows of a table ffpkyc - write complex-valued keyword ffpkym - write double complex-valued keyword ffpkfc - write complex-valued keyword in fixed format ffpkfm - write double complex-valued keyword in fixed format ffgkyc - read complex-valued keyword ffgkym - read double complex-valued keyword ffmkyc - modify complex-valued keyword ffmkym - modify double complex-valued keyword ffmkfc - modify complex-valued keyword in fixed format ffmkfm - modify double complex-valued keyword in fixed format ffukyc - update complex-valued keyword ffukym - update double complex-valued keyword ffukfc - update complex-valued keyword in fixed format ffukfm - update double complex-valued keyword in fixed format ffikyc - insert complex-valued keyword ffikym - insert double complex-valued keyword ffikfc - insert complex-valued keyword in fixed format ffikfm - insert double complex-valued keyword in fixed format ffpktp - write or modify keywords using ASCII template file ffcpcl - copy a column from one table to another ffcpky - copy an indexed keyword from one HDU to another ffpcnl - write logical values, including nulls, to binary table ffpcns - write string values, including nulls, to table ffmnhd - move to HDU with given exttype, EXTNAME and EXTVERS values ffthdu - return the total number of HDUs in the file ffghdt - return the type of the CHDU ffflnm - return the name of the open FITS file ffflmd - return the mode of the file (READONLY or READWRITE) - modified ffmahd and ffmrhd (to move to a new extension) so that a null pointer may be given for the returned HDUTYPE argument. - worked around a bug in the Mac CWpro2 compiler by changing all the statements like "#if BYTESWAPPED == TRUE" to "if BYTESWAPPED". - modified ffitab (insert new ASCII table) to allow tables with zero number of columns - modified Makefile.in and configure to define the -Dg77Fortran CFLAGS variable on Linux platforms. This is needed to compile the new f77_wrap.c file (which includes cfortran.h) Bug Fixes: - fixed small bug in ffgrz (get optimum row size) which sometimes caused it to return slightly less than the maximum optimum size. This bug would have done no harm to application programs. - fixed bug in ffpclk and ffgclk to add an 'else' case if size of int is not equal to size of short or size of long. - added test to ffgkls to check if the input string is not null before allocating memory for it. Version 1.32 - 21 November 1997 (internal release only) - fixed bug in the memory deallocation (free) statements in the ffopen routine in the cfileio.c file. - modified ffgphd to tolerate minor violations of the FITS standard in the format of the XTENSION = 'IMAGE ' keyword when reading FITS files. Extra trailing spaces are now allowed in the keyword value. (FITS standard will be changed so that this is not a violation). Version 1.31 - 4 November 1997 (internal release only) Enhancements: - added support for directly reading compressed FITS files by copying the algorithms from the gzip program. This supports the Unix compress, gzip and pkzip algorithms. - modified ffiimg, ffitab, and ffibin (insert HDUs into a FITS file) so that if the inserted HDU is at the end of the FITS file, then it simply appends a new empty HDU and writes the required keywords. This allows space to be reserved for additional keywords in the header if desired. - added the ffchfl and ffcdfl routines to check the header and data fill values, for compatibility with the Fortran FITSIO library. - added the ffgsdt routine to return the system date for compatibility with the Fortran FITSIO library. - added a diagnostic error message (written to the error stack) if the routines that read data from image or column fail. - modified ffgclb so that it simply copies the bytes from an ASCII 'nA' or 'An' format column into the user's byte array. Previously, CFITSIO would return an error when trying to read an 'A' column with ffgclb. - modified ffpclb so that it simply copies the input array of bytes to an ASCII 'nA' or 'An' format column. Previously, CFITSIO would return an error when trying to write to an 'A' column with ffpclb. Bug Fixes: - ffgkls was allocating one too few bytes when reading continued string keyword values. - in testprog.c added code to properly free the memory that had been allocated for string arrays. - corrected typographical errors in the User's Guide. Version 1.30 - 11 September 1997 - major overhaul to support reading and writing FITS files in memory. The new routines fits_set_mem_buff and fits_write_mem_buff have been added to initialize and copy out the memory buffer, respectively. - added support for reading FITS files piped in on 'stdin' and piped out on 'stdout'. Just specify the file name as '-' when opening or creating the FITS file. - added support for 64-bit SGI IRIX machines. This required adding routines to pack and unpack 32-bit integers into 64-bit integers. - cleaned up the code that supports G_FLOAT and IEEE_FLOAT on Alpha VMS systems. Now, the type of float is determined at compile time, not run time. Bug Fixes: - replaced the malloc calls in the error message stack routines with a static fixed size array. The malloc's cause more problems than they solved, and were prone to cause memory leaks if users don't clear the error message stack when closing the FITS file. - when writing float or double keywords, test that the value is not a special IEEE value such as a NaN. Some compilers would write the string 'NaN' in this case into the output value string. - fixed bug in ffiblk, to ignore EOF status return if it is inserting blocks at the end of the file. - removed the 'l' from printf format string that is constructed in the ffcfmt routine. This 'l' is non-standard and causes problems with the Metrowerks compiler on a Mac. - the default null value in images was mistakenly being set equal to NO_NULL = 314, rather than NULL_UNDEFINED = 1234554321 in the ffgphd routine. - check status value in ffgkls to make sure the keyword exists before allocating memory for the value string. - fixed the support for writing and reading unsigned long integer keyword values in ffpky and ffgky by internally treating the values as doubles. This required changes to ffc2r and ffc2d as well. - added explicit cast to 'double' in one place in putcolb.c and 6 places in pubcolui.c, to get rid of warning messages issued by one compiler. - in ffbinit and ffainit, it is necessary to test that tfield > 0 before trying to allocate memory with calloc. Otherwise, some compilers return a null pointer which CFITSIO interprets to mean the memory allocation failed. - had to explicitly cast the null buffer pointer to a char pointer (cptr = (char *)buffer;) in 4 places in the buffers.c file to satisfy a picky C++ compiler. - changed the test for an ALPHA VMS system to see if '__VMS' is defined, rather than 'VMS'. The latter is not defined by at least one C++ compiler. - modified ffpcls so that it can write a null string to a variable length string column, without going into an infinite loop. - fixed bug in ffgcfl that caused the 'next' variable to be incremented twice. - fixed bug in ffgcpr that caused it write 2x the number of complex elements into the descriptor when writing to a complex or double complex variable length array column. - added call to ffrdef at the end of ffrsim to ensure that the internal structures are updated to correspond to the modified header keywords Version 1.25 - 7 July 1997 - improved the efficiency of the ffiblk routine, when inserting more than one block into the file. - fixed bug in ffwend that in rare instances caused the beginning of the following extension to be overwritten by blank fill. - added new routine to modify the size of an existing primary array or image extension: fits_resize_img/ffrsim. - added support for null-valued keywords, e.g., keywords that have no defined value. These keywords have an equal sign and space in columns 9-10, but have not value string. Example: KEYNAME = / null-valued keyword Support for this feature required the following changes: - modified ffpsvc to return a null value string without error - modified ffc2[ilrd] to return error VALUE_UNDEFINED in this case - modified ffgkn[sljed] to continue reading additional keywords even if one or more keywords have undefined values. - added 4 new routines: ffpkyu, ffikyu, ffmkyu, ffukyu to write, insert, modify, or update an undefined keyword - a new makefile.os2 file was added, for building CFITSIO on OS/2 systems. - modified ffgtkn so that if it finds an unexpected keyword name, the returned error status = BAD_ORDER instead of NOT_POS_INT. - added 2 new routines, fits_write_key_unit/ffpunt and fits_read_key_unit/ffgunt to write/read the physical units of a keyword value. These routines use a local FITS convention for storing the units in square brackets following the '/' comment field separator, as in: VELOCITY= 12 / [km/s] orbit speed The testprog.c program was modified to test these new routines. - in the test of Alpha OSF/1 machines in fitsio2.h, change 'defined(unix)' to 'defined(__unix__)' which appears to be a more robust test. - remove test for linux environment variable from fitsio2.h Version 1.24 - 2 May 1997 - fixed bug in ffpbyt that incorrectly computed the current location in the FITS file when writing > 10000 bytes. - changed the datatype of the 'nbytes' parameter in ffpbyt from 'int' to 'long'. Made corresponding datatype change to some internal variables in ffshft. - changed '(unsigned short *)' to '(short *)' in getcolui.c, and changed '(unsigned long *)' to '(long *)' in getcoluj.c, to work around problem with the VAX/VMS cc compiler. Version 1.23 - 24 April 1997 - modified ffcins and ffdins (in editcol.c) to simply return without error if there are no (zero) rows in the table. Version 1.22 - 18 April 1997 - fixed bug in ffgcpr that caused it to think that all values were undefined in ASCII tables columns that have TNULLn = ' ' (i.e., the TNULLn keyword value is a string of blanks. - fixed bug in the ffgcl[bdeijk,ui,uj] family of routines when parsing a numeric value in an ASCII table. The returned values would have the decimal place shifted to the left if the table field contained an explicit decimal point followed by blanks. Example: in an F5.2 column, the value '16. ' would be returned as 0.16. If the trailing zeros were present, then cfitsio returned the correct value (e.g., '16.00' returns 16.). - fixed another bug in the ffgcl[bdeijk,ui,uj] family of routines that caused them to misread values in an ASCII table in rows following an undefined value when all the values were read at once in a single call to the routine. Version 1.21 - 26 March 1997 - added general support for reading and writing unsigned integer keywords, images, and binary table column values. - fixed bug in the way the column number was used in ffgsve and similar routines. This bug caused cfitsio to read (colnum - 1) rather than the desired column. - fixed a bug in ftgkls that prevented it from reading more than one continuation line of a long string keyword value. - fixed the definition of fits_write_longwarn in longnam.h Version 1.20 - 29 Jan 1997 - when creating a binary table with variable length vector columns, if the calling routine does not specify a value for the maximum length of the vector (e.g., TFORMn = '1PE(400)') then cfitsio will automatically calculate the maximum value and append it to the TFORM value when the binary table is first closed. - added the set of routines to do coordinate system transformations - added support for wildcards ('*', '?', and '#') in the input keyword name when reading, modifying, or deleting keywords. - added new general keyword reading routine, ffgnxk, to return the next keyword whose name matches a list of template names, but does not match any names on a second template list. - modified ftgrec so that it simply moves to the beginning of the header if the input keyword number = 0 - added check in ffdelt to make sure the input fits file pointer is not already null - added check in ffcopy to make sure the output HDU does not already contain any keywords (it must be empty). - modified ffgcls so that it does not test if each string column value equals the null string value if the null string value is longer than the width of the column. - fixed bug in ftgtdm that caused it to fail if the TDIMn keyword did not exist in the FITS file - modified testprog.c to include tests of keyword wildcards and the WCS coordinate transformation routines. - added a test for 'EMX' in fitsio2.h so that cfitsio builds correctly on a PC running OS/2. Version 1.11 - 04 Dec 1996 - modified the testprog.c program that is included with the distribution, so that the output FITS file is identical to that produced by the Fortran FITSIO test program. - changed all instances of the 'extname' variable to 'extnm' to avoid a conflict with the -Dextname switch in cfortran.h on HP machines. - in all the routines like ffi4fi1, which convert an array of values to integers just prior to writing them to the FITS file, the integer value is now rounded to the nearest integer rather than truncated. (ffi4fi1, ffi4fi2, ffi4fi4, etc) - changed ffgcfl (and hence ffgcl) so that the input value of the logical array element is not changed if the corresponding FITS value is undefined. - in ffgacl, the returned value of TBCOL was off by 1 (too small) - fixed the comment of EXTNAME keyword to read 'binary table' instead of 'ASCII table' in the header of binary tables. Version 1.101 - 17 Nov 1996 - Made major I/O efficiency improvements by adding internal buffers rather than directly reading or writing to disk. Access to columns in binary tables is now 50 - 150 times faster. Access to FITS image is also slightly faster. - made significant speed improvements when reading numerical data in FITS ASCII tables by writing my own number parsing routines rather than using the sscanf C library routine. This change requires that the -lm argument now be included when linking a program that calls cfitsio (under UNIX). - regrouped the source files into logically related sets of routines. The Makefile now runs much faster since every single routine is not split into a separate file. - now use the memcpy function, rather than a 'for' loop in several places for added efficiency - redesigned the low-level binary table read and write routines (ffpbytoff and ffgbytoff) for greater efficiency. - added a new error status: 103 = too many open FITS files. - added a 'extern "C"' statement around the function prototypes in fitsio.h, to support use of cfitsio by C++ compilers. - fixed routines for writing or reading fixed-length substrings within a binary table ASCII column, with TFORM values of of the form 'rAw' where 'r' is the total width of the ASCII column and 'w' is the width of a substring within the column. - no longer automatically rewrite the END card and following fill values if they are already correct. - all the 'get keyword value and comment' routines have been changed so that the comment is not returned if the input pointer is NULL. - added new routine to return the optimum number of tables rows that should be read or written at one time for optimum efficiency. - modified the way numerical values in ASCII tables are parsed so that embedded spaces in the value are ignored, and implicit decimal points are now supported. (e.g, the string '123E 12' in a 'E10.2' format column will be interpreted as 1.23 * 10**12). - modified ffpcl and ffgcl to support binary table columns of all datatype (added logical, bit, complex, and double complex) - when writing numerical data to ASCII table columns, the ffpcl_ routines now return an overflow error if a value is too large to be expressed in the column format. - closed small memory leak in ffpcls. - initialized the 'incre' variable in ffgcpr to eliminate compiler warning. Version 1.04 - 17 Sept 1996 - added README.MacOS and cfitsio_mac.sit.hqx to the distribution to support the Mac platforms. - fixed bug in ffpdfl that caused an EOF error (107) when a program creates a new extension that is an exact multiple of 2880 bytes long, AND the program does not write a value to the last element in the table or image. - fixed bug in all the ffgsf* and ffgcv* routines which caused core dumps when reading null values in a table. Version 1.03 - 20 August 1996 - added full support for reading and writing the C 'int' data type. This was a problem on Alpha/OSF where short, int, and long datatypes are 2, 4, and 8 bytes long, respectively. - cleaned up the code in the byte-swapping routines. - renamed the file 'longname.h' to 'longnam.h' to avoid conflict with a file with the same name in another unrelated package. Version 1.02 - 15 August 1996 - ffgtbp was not correctly reading the THEAP keyword, hence would not correctly read variable length data in binary tables if the heap was not at the default starting location (i.e., starting immediately after the fixed length table). - now force the cbuff variable in ffpcl_ and ffgcl_ to be aligned on a double word boundary. Non-alignment can cause program to crash on some systems. Version 1.01 - 12 August 1996 - initial public release ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2552593 astropy-5.0.2/cextern/cfitsio/lib/0000755000175100001710000000000000000000000016123 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/buffers.c0000644000175100001710000014775500000000000017746 0ustar00vstsdocker/* This file, buffers.c, contains the core set of FITSIO routines */ /* that use or manage the internal set of IO buffers. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffmbyt(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG bytepos, /* I - byte position in file to move to */ int err_mode, /* I - 1=ignore error, 0 = return error */ int *status) /* IO - error status */ { /* Move to the input byte location in the file. When writing to a file, a move may sometimes be made to a position beyond the current EOF. The err_mode parameter determines whether such conditions should be returned as an error or simply ignored. */ long record; if (*status > 0) return(*status); if (bytepos < 0) return(*status = NEG_FILE_POS); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); record = (long) (bytepos / IOBUFLEN); /* zero-indexed record number */ /* if this is not the current record, then load it */ if ( ((fptr->Fptr)->curbuf < 0) || (record != (fptr->Fptr)->bufrecnum[(fptr->Fptr)->curbuf])) ffldrc(fptr, record, err_mode, status); if (*status <= 0) (fptr->Fptr)->bytepos = bytepos; /* save new file position */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpbyt(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG nbytes, /* I - number of bytes to write */ void *buffer, /* I - buffer containing the bytes to write */ int *status) /* IO - error status */ /* put (write) the buffer of bytes to the output FITS file, starting at the current file position. Write large blocks of data directly to disk; write smaller segments to intermediate IO buffers to improve efficiency. */ { int ii, nbuff; LONGLONG filepos; long recstart, recend; long ntodo, bufpos, nspace, nwrite; char *cptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (nbytes > LONG_MAX) { ffpmsg("Number of bytes to write is greater than LONG_MAX (ffpbyt)."); *status = WRITE_ERROR; return(*status); } ntodo = (long) nbytes; cptr = (char *)buffer; if ((fptr->Fptr)->curbuf < 0) /* no current data buffer for this file */ { /* so reload the last one that was used */ ffldrc(fptr, (long) (((fptr->Fptr)->bytepos) / IOBUFLEN), REPORT_EOF, status); } if (nbytes >= MINDIRECT) { /* write large blocks of data directly to disk instead of via buffers */ /* first, fill up the current IO buffer before flushing it to disk */ nbuff = (fptr->Fptr)->curbuf; /* current IO buffer number */ filepos = (fptr->Fptr)->bytepos; /* save the write starting position */ recstart = (fptr->Fptr)->bufrecnum[nbuff]; /* starting record */ recend = (long) ((filepos + nbytes - 1) / IOBUFLEN); /* ending record */ /* bufpos is the starting position within the IO buffer */ bufpos = (long) (filepos - ((LONGLONG)recstart * IOBUFLEN)); nspace = IOBUFLEN - bufpos; /* amount of space left in the buffer */ if (nspace) { /* fill up the IO buffer */ memcpy((fptr->Fptr)->iobuffer + (nbuff * IOBUFLEN) + bufpos, cptr, nspace); ntodo -= nspace; /* decrement remaining number of bytes */ cptr += nspace; /* increment user buffer pointer */ filepos += nspace; /* increment file position pointer */ (fptr->Fptr)->dirty[nbuff] = TRUE; /* mark record as having been modified */ } for (ii = 0; ii < NIOBUF; ii++) /* flush any affected buffers to disk */ { if ((fptr->Fptr)->bufrecnum[ii] >= recstart && (fptr->Fptr)->bufrecnum[ii] <= recend ) { if ((fptr->Fptr)->dirty[ii]) /* flush modified buffer to disk */ ffbfwt(fptr->Fptr, ii, status); (fptr->Fptr)->bufrecnum[ii] = -1; /* disassociate buffer from the file */ } } /* move to the correct write position */ if ((fptr->Fptr)->io_pos != filepos) ffseek(fptr->Fptr, filepos); nwrite = ((ntodo - 1) / IOBUFLEN) * IOBUFLEN; /* don't write last buff */ ffwrite(fptr->Fptr, nwrite, cptr, status); /* write the data */ ntodo -= nwrite; /* decrement remaining number of bytes */ cptr += nwrite; /* increment user buffer pointer */ (fptr->Fptr)->io_pos = filepos + nwrite; /* update the file position */ if ((fptr->Fptr)->io_pos >= (fptr->Fptr)->filesize) /* at the EOF? */ { (fptr->Fptr)->filesize = (fptr->Fptr)->io_pos; /* increment file size */ /* initialize the current buffer with the correct fill value */ if ((fptr->Fptr)->hdutype == ASCII_TBL) memset((fptr->Fptr)->iobuffer + (nbuff * IOBUFLEN), 32, IOBUFLEN); /* blank fill */ else memset((fptr->Fptr)->iobuffer + (nbuff * IOBUFLEN), 0, IOBUFLEN); /* zero fill */ } else { /* read next record */ ffread(fptr->Fptr, IOBUFLEN, (fptr->Fptr)->iobuffer + (nbuff * IOBUFLEN), status); (fptr->Fptr)->io_pos += IOBUFLEN; } /* copy remaining bytes from user buffer into current IO buffer */ memcpy((fptr->Fptr)->iobuffer + (nbuff * IOBUFLEN), cptr, ntodo); (fptr->Fptr)->dirty[nbuff] = TRUE; /* mark record as having been modified */ (fptr->Fptr)->bufrecnum[nbuff] = recend; /* record number */ (fptr->Fptr)->logfilesize = maxvalue((fptr->Fptr)->logfilesize, (LONGLONG)(recend + 1) * IOBUFLEN); (fptr->Fptr)->bytepos = filepos + nwrite + ntodo; } else { /* bufpos is the starting position in IO buffer */ bufpos = (long) ((fptr->Fptr)->bytepos - ((LONGLONG)(fptr->Fptr)->bufrecnum[(fptr->Fptr)->curbuf] * IOBUFLEN)); nspace = IOBUFLEN - bufpos; /* amount of space left in the buffer */ while (ntodo) { nwrite = minvalue(ntodo, nspace); /* copy bytes from user's buffer to the IO buffer */ memcpy((fptr->Fptr)->iobuffer + ((fptr->Fptr)->curbuf * IOBUFLEN) + bufpos, cptr, nwrite); ntodo -= nwrite; /* decrement remaining number of bytes */ cptr += nwrite; (fptr->Fptr)->bytepos += nwrite; /* increment file position pointer */ (fptr->Fptr)->dirty[(fptr->Fptr)->curbuf] = TRUE; /* mark record as modified */ if (ntodo) /* load next record into a buffer */ { ffldrc(fptr, (long) ((fptr->Fptr)->bytepos / IOBUFLEN), IGNORE_EOF, status); bufpos = 0; nspace = IOBUFLEN; } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffpbytoff(fitsfile *fptr, /* I - FITS file pointer */ long gsize, /* I - size of each group of bytes */ long ngroups, /* I - number of groups to write */ long offset, /* I - size of gap between groups */ void *buffer, /* I - buffer to be written */ int *status) /* IO - error status */ /* put (write) the buffer of bytes to the output FITS file, with an offset between each group of bytes. This function combines ffmbyt and ffpbyt for increased efficiency. */ { int bcurrent; long ii, bufpos, nspace, nwrite, record; char *cptr, *ioptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if ((fptr->Fptr)->curbuf < 0) /* no current data buffer for this file */ { /* so reload the last one that was used */ ffldrc(fptr, (long) (((fptr->Fptr)->bytepos) / IOBUFLEN), REPORT_EOF, status); } cptr = (char *)buffer; bcurrent = (fptr->Fptr)->curbuf; /* number of the current IO buffer */ record = (fptr->Fptr)->bufrecnum[bcurrent]; /* zero-indexed record number */ bufpos = (long) ((fptr->Fptr)->bytepos - ((LONGLONG)record * IOBUFLEN)); /* start pos */ nspace = IOBUFLEN - bufpos; /* amount of space left in buffer */ ioptr = (fptr->Fptr)->iobuffer + (bcurrent * IOBUFLEN) + bufpos; for (ii = 1; ii < ngroups; ii++) /* write all but the last group */ { /* copy bytes from user's buffer to the IO buffer */ nwrite = minvalue(gsize, nspace); memcpy(ioptr, cptr, nwrite); cptr += nwrite; /* increment buffer pointer */ if (nwrite < gsize) /* entire group did not fit */ { (fptr->Fptr)->dirty[bcurrent] = TRUE; /* mark record as having been modified */ record++; ffldrc(fptr, record, IGNORE_EOF, status); /* load next record */ bcurrent = (fptr->Fptr)->curbuf; ioptr = (fptr->Fptr)->iobuffer + (bcurrent * IOBUFLEN); nwrite = gsize - nwrite; memcpy(ioptr, cptr, nwrite); cptr += nwrite; /* increment buffer pointer */ ioptr += (offset + nwrite); /* increment IO buffer pointer */ nspace = IOBUFLEN - offset - nwrite; /* amount of space left */ } else { ioptr += (offset + nwrite); /* increment IO bufer pointer */ nspace -= (offset + nwrite); } if (nspace <= 0) /* beyond current record? */ { (fptr->Fptr)->dirty[bcurrent] = TRUE; record += ((IOBUFLEN - nspace) / IOBUFLEN); /* new record number */ ffldrc(fptr, record, IGNORE_EOF, status); bcurrent = (fptr->Fptr)->curbuf; bufpos = (-nspace) % IOBUFLEN; /* starting buffer pos */ nspace = IOBUFLEN - bufpos; ioptr = (fptr->Fptr)->iobuffer + (bcurrent * IOBUFLEN) + bufpos; } } /* now write the last group */ nwrite = minvalue(gsize, nspace); memcpy(ioptr, cptr, nwrite); cptr += nwrite; /* increment buffer pointer */ if (nwrite < gsize) /* entire group did not fit */ { (fptr->Fptr)->dirty[bcurrent] = TRUE; /* mark record as having been modified */ record++; ffldrc(fptr, record, IGNORE_EOF, status); /* load next record */ bcurrent = (fptr->Fptr)->curbuf; ioptr = (fptr->Fptr)->iobuffer + (bcurrent * IOBUFLEN); nwrite = gsize - nwrite; memcpy(ioptr, cptr, nwrite); } (fptr->Fptr)->dirty[bcurrent] = TRUE; /* mark record as having been modified */ (fptr->Fptr)->bytepos = (fptr->Fptr)->bytepos + (ngroups * gsize) + (ngroups - 1) * offset; return(*status); } /*--------------------------------------------------------------------------*/ int ffgbyt(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG nbytes, /* I - number of bytes to read */ void *buffer, /* O - buffer to read into */ int *status) /* IO - error status */ /* get (read) the requested number of bytes from the file, starting at the current file position. Read large blocks of data directly from disk; read smaller segments via intermediate IO buffers to improve efficiency. */ { int ii; LONGLONG filepos; long recstart, recend, ntodo, bufpos, nspace, nread; char *cptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); cptr = (char *)buffer; if (nbytes >= MINDIRECT) { /* read large blocks of data directly from disk instead of via buffers */ filepos = (fptr->Fptr)->bytepos; /* save the read starting position */ /* note that in this case, ffmbyt has not been called, and so */ /* bufrecnum[(fptr->Fptr)->curbuf] does not point to the intended */ /* output buffer */ recstart = (long) (filepos / IOBUFLEN); /* starting record */ recend = (long) ((filepos + nbytes - 1) / IOBUFLEN); /* ending record */ for (ii = 0; ii < NIOBUF; ii++) /* flush any affected buffers to disk */ { if ((fptr->Fptr)->dirty[ii] && (fptr->Fptr)->bufrecnum[ii] >= recstart && (fptr->Fptr)->bufrecnum[ii] <= recend) { ffbfwt(fptr->Fptr, ii, status); /* flush modified buffer to disk */ } } /* move to the correct read position */ if ((fptr->Fptr)->io_pos != filepos) ffseek(fptr->Fptr, filepos); ffread(fptr->Fptr, (long) nbytes, cptr, status); /* read the data */ (fptr->Fptr)->io_pos = filepos + nbytes; /* update the file position */ } else { /* read small chucks of data using the IO buffers for efficiency */ if ((fptr->Fptr)->curbuf < 0) /* no current data buffer for this file */ { /* so reload the last one that was used */ ffldrc(fptr, (long) (((fptr->Fptr)->bytepos) / IOBUFLEN), REPORT_EOF, status); } /* bufpos is the starting position in IO buffer */ bufpos = (long) ((fptr->Fptr)->bytepos - ((LONGLONG)(fptr->Fptr)->bufrecnum[(fptr->Fptr)->curbuf] * IOBUFLEN)); nspace = IOBUFLEN - bufpos; /* amount of space left in the buffer */ ntodo = (long) nbytes; while (ntodo) { nread = minvalue(ntodo, nspace); /* copy bytes from IO buffer to user's buffer */ memcpy(cptr, (fptr->Fptr)->iobuffer + ((fptr->Fptr)->curbuf * IOBUFLEN) + bufpos, nread); ntodo -= nread; /* decrement remaining number of bytes */ cptr += nread; (fptr->Fptr)->bytepos += nread; /* increment file position pointer */ if (ntodo) /* load next record into a buffer */ { ffldrc(fptr, (long) ((fptr->Fptr)->bytepos / IOBUFLEN), REPORT_EOF, status); bufpos = 0; nspace = IOBUFLEN; } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgbytoff(fitsfile *fptr, /* I - FITS file pointer */ long gsize, /* I - size of each group of bytes */ long ngroups, /* I - number of groups to read */ long offset, /* I - size of gap between groups (may be < 0) */ void *buffer, /* I - buffer to be filled */ int *status) /* IO - error status */ /* get (read) the requested number of bytes from the file, starting at the current file position. This function combines ffmbyt and ffgbyt for increased efficiency. */ { int bcurrent; long ii, bufpos, nspace, nread, record; char *cptr, *ioptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if ((fptr->Fptr)->curbuf < 0) /* no current data buffer for this file */ { /* so reload the last one that was used */ ffldrc(fptr, (long) (((fptr->Fptr)->bytepos) / IOBUFLEN), REPORT_EOF, status); } cptr = (char *)buffer; bcurrent = (fptr->Fptr)->curbuf; /* number of the current IO buffer */ record = (fptr->Fptr)->bufrecnum[bcurrent]; /* zero-indexed record number */ bufpos = (long) ((fptr->Fptr)->bytepos - ((LONGLONG)record * IOBUFLEN)); /* start pos */ nspace = IOBUFLEN - bufpos; /* amount of space left in buffer */ ioptr = (fptr->Fptr)->iobuffer + (bcurrent * IOBUFLEN) + bufpos; for (ii = 1; ii < ngroups; ii++) /* read all but the last group */ { /* copy bytes from IO buffer to the user's buffer */ nread = minvalue(gsize, nspace); memcpy(cptr, ioptr, nread); cptr += nread; /* increment buffer pointer */ if (nread < gsize) /* entire group did not fit */ { record++; ffldrc(fptr, record, REPORT_EOF, status); /* load next record */ bcurrent = (fptr->Fptr)->curbuf; ioptr = (fptr->Fptr)->iobuffer + (bcurrent * IOBUFLEN); nread = gsize - nread; memcpy(cptr, ioptr, nread); cptr += nread; /* increment buffer pointer */ ioptr += (offset + nread); /* increment IO buffer pointer */ nspace = IOBUFLEN - offset - nread; /* amount of space left */ } else { ioptr += (offset + nread); /* increment IO bufer pointer */ nspace -= (offset + nread); } if (nspace <= 0 || nspace > IOBUFLEN) /* beyond current record? */ { if (nspace <= 0) { record += ((IOBUFLEN - nspace) / IOBUFLEN); /* new record number */ bufpos = (-nspace) % IOBUFLEN; /* starting buffer pos */ } else { record -= ((nspace - 1 ) / IOBUFLEN); /* new record number */ bufpos = IOBUFLEN - (nspace % IOBUFLEN); /* starting buffer pos */ } ffldrc(fptr, record, REPORT_EOF, status); bcurrent = (fptr->Fptr)->curbuf; nspace = IOBUFLEN - bufpos; ioptr = (fptr->Fptr)->iobuffer + (bcurrent * IOBUFLEN) + bufpos; } } /* now read the last group */ nread = minvalue(gsize, nspace); memcpy(cptr, ioptr, nread); cptr += nread; /* increment buffer pointer */ if (nread < gsize) /* entire group did not fit */ { record++; ffldrc(fptr, record, REPORT_EOF, status); /* load next record */ bcurrent = (fptr->Fptr)->curbuf; ioptr = (fptr->Fptr)->iobuffer + (bcurrent * IOBUFLEN); nread = gsize - nread; memcpy(cptr, ioptr, nread); } (fptr->Fptr)->bytepos = (fptr->Fptr)->bytepos + (ngroups * gsize) + (ngroups - 1) * offset; return(*status); } /*--------------------------------------------------------------------------*/ int ffldrc(fitsfile *fptr, /* I - FITS file pointer */ long record, /* I - record number to be loaded */ int err_mode, /* I - 1=ignore EOF, 0 = return EOF error */ int *status) /* IO - error status */ { /* low-level routine to load a specified record from a file into a physical buffer, if it is not already loaded. Reset all pointers to make this the new current record for that file. Update ages of all the physical buffers. */ int ibuff, nbuff; LONGLONG rstart; /* check if record is already loaded in one of the buffers */ /* search from youngest to oldest buffer for efficiency */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); for (ibuff = NIOBUF - 1; ibuff >= 0; ibuff--) { nbuff = (fptr->Fptr)->ageindex[ibuff]; if (record == (fptr->Fptr)->bufrecnum[nbuff]) { goto updatebuf; /* use 'goto' for efficiency */ } } /* record is not already loaded */ rstart = (LONGLONG)record * IOBUFLEN; if ( !err_mode && (rstart >= (fptr->Fptr)->logfilesize) ) /* EOF? */ return(*status = END_OF_FILE); if (ffwhbf(fptr, &nbuff) < 0) /* which buffer should we reuse? */ return(*status = TOO_MANY_FILES); if ((fptr->Fptr)->dirty[nbuff]) ffbfwt(fptr->Fptr, nbuff, status); /* write dirty buffer to disk */ if (rstart >= (fptr->Fptr)->filesize) /* EOF? */ { /* initialize an empty buffer with the correct fill value */ if ((fptr->Fptr)->hdutype == ASCII_TBL) memset((fptr->Fptr)->iobuffer + (nbuff * IOBUFLEN), 32, IOBUFLEN); /* blank fill */ else memset((fptr->Fptr)->iobuffer + (nbuff * IOBUFLEN), 0, IOBUFLEN); /* zero fill */ (fptr->Fptr)->logfilesize = maxvalue((fptr->Fptr)->logfilesize, rstart + IOBUFLEN); (fptr->Fptr)->dirty[nbuff] = TRUE; /* mark record as having been modified */ } else /* not EOF, so read record from disk */ { if ((fptr->Fptr)->io_pos != rstart) ffseek(fptr->Fptr, rstart); ffread(fptr->Fptr, IOBUFLEN, (fptr->Fptr)->iobuffer + (nbuff * IOBUFLEN), status); (fptr->Fptr)->io_pos = rstart + IOBUFLEN; /* set new IO position */ } (fptr->Fptr)->bufrecnum[nbuff] = record; /* record number contained in buffer */ updatebuf: (fptr->Fptr)->curbuf = nbuff; /* this is the current buffer for this file */ if (ibuff < 0) { /* find the current position of the buffer in the age index */ for (ibuff = 0; ibuff < NIOBUF; ibuff++) if ((fptr->Fptr)->ageindex[ibuff] == nbuff) break; } /* increment the age of all the buffers that were younger than it */ for (ibuff++; ibuff < NIOBUF; ibuff++) (fptr->Fptr)->ageindex[ibuff - 1] = (fptr->Fptr)->ageindex[ibuff]; (fptr->Fptr)->ageindex[NIOBUF - 1] = nbuff; /* this is now the youngest buffer */ return(*status); } /*--------------------------------------------------------------------------*/ int ffwhbf(fitsfile *fptr, /* I - FITS file pointer */ int *nbuff) /* O - which buffer to use */ { /* decide which buffer to (re)use to hold a new file record */ return(*nbuff = (fptr->Fptr)->ageindex[0]); /* return oldest buffer */ } /*--------------------------------------------------------------------------*/ int ffflus(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* Flush all the data in the current FITS file to disk. This ensures that if the program subsequently dies, the disk FITS file will be closed correctly. */ { int hdunum, hdutype; if (*status > 0) return(*status); ffghdn(fptr, &hdunum); /* get the current HDU number */ if (ffchdu(fptr,status) > 0) /* close out the current HDU */ ffpmsg("ffflus could not close the current HDU."); ffflsh(fptr, FALSE, status); /* flush any modified IO buffers to disk */ if (ffgext(fptr, hdunum - 1, &hdutype, status) > 0) /* reopen HDU */ ffpmsg("ffflus could not reopen the current HDU."); return(*status); } /*--------------------------------------------------------------------------*/ int ffflsh(fitsfile *fptr, /* I - FITS file pointer */ int clearbuf, /* I - also clear buffer contents? */ int *status) /* IO - error status */ { /* flush all dirty IO buffers associated with the file to disk */ int ii; /* no need to move to a different HDU if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); */ for (ii = 0; ii < NIOBUF; ii++) { /* flush modified buffer to disk */ if ((fptr->Fptr)->bufrecnum[ii] >= 0 &&(fptr->Fptr)->dirty[ii]) ffbfwt(fptr->Fptr, ii, status); if (clearbuf) (fptr->Fptr)->bufrecnum[ii] = -1; /* set contents of buffer as undefined */ } if (*status != READONLY_FILE) ffflushx(fptr->Fptr); /* flush system buffers to disk */ return(*status); } /*--------------------------------------------------------------------------*/ int ffbfeof(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ { /* clear any buffers beyond the end of file */ int ii; for (ii = 0; ii < NIOBUF; ii++) { if ( (LONGLONG) (fptr->Fptr)->bufrecnum[ii] * IOBUFLEN >= fptr->Fptr->filesize) { (fptr->Fptr)->bufrecnum[ii] = -1; /* set contents of buffer as undefined */ } } return(*status); } /*--------------------------------------------------------------------------*/ int ffbfwt(FITSfile *Fptr, /* I - FITS file pointer */ int nbuff, /* I - which buffer to write */ int *status) /* IO - error status */ { /* write contents of buffer to file; If the position of the buffer is beyond the current EOF, then the file may need to be extended with fill values, and/or with the contents of some of the other i/o buffers. */ int ii,ibuff; long jj, irec, minrec, nloop; LONGLONG filepos; static char zeros[IOBUFLEN]; /* initialized to zero by default */ if (!(Fptr->writemode) ) { ffpmsg("Error: trying to write to READONLY file."); if (Fptr->driver == 8) { /* gzip compressed file */ ffpmsg("Cannot write to a GZIP or COMPRESS compressed file."); } Fptr->dirty[nbuff] = FALSE; /* reset buffer status to prevent later probs */ *status = READONLY_FILE; return(*status); } filepos = (LONGLONG)Fptr->bufrecnum[nbuff] * IOBUFLEN; if (filepos <= Fptr->filesize) { /* record is located within current file, so just write it */ /* move to the correct write position */ if (Fptr->io_pos != filepos) ffseek(Fptr, filepos); ffwrite(Fptr, IOBUFLEN, Fptr->iobuffer + (nbuff * IOBUFLEN), status); Fptr->io_pos = filepos + IOBUFLEN; if (filepos == Fptr->filesize) /* appended new record? */ Fptr->filesize += IOBUFLEN; /* increment the file size */ Fptr->dirty[nbuff] = FALSE; } else /* if record is beyond the EOF, append any other records */ /* and/or insert fill values if necessary */ { /* move to EOF */ if (Fptr->io_pos != Fptr->filesize) ffseek(Fptr, Fptr->filesize); ibuff = NIOBUF; /* initialize to impossible value */ while(ibuff != nbuff) /* repeat until requested buffer is written */ { minrec = (long) (Fptr->filesize / IOBUFLEN); /* write lowest record beyond the EOF first */ irec = Fptr->bufrecnum[nbuff]; /* initially point to the requested buffer */ ibuff = nbuff; for (ii = 0; ii < NIOBUF; ii++) { if (Fptr->bufrecnum[ii] >= minrec && Fptr->bufrecnum[ii] < irec) { irec = Fptr->bufrecnum[ii]; /* found a lower record */ ibuff = ii; } } filepos = (LONGLONG)irec * IOBUFLEN; /* byte offset of record in file */ /* append 1 or more fill records if necessary */ if (filepos > Fptr->filesize) { nloop = (long) ((filepos - (Fptr->filesize)) / IOBUFLEN); for (jj = 0; jj < nloop && !(*status); jj++) ffwrite(Fptr, IOBUFLEN, zeros, status); /* ffseek(Fptr, filepos); */ Fptr->filesize = filepos; /* increment the file size */ } /* write the buffer itself */ ffwrite(Fptr, IOBUFLEN, Fptr->iobuffer + (ibuff * IOBUFLEN), status); Fptr->dirty[ibuff] = FALSE; Fptr->filesize += IOBUFLEN; /* increment the file size */ } /* loop back if more buffers need to be written */ Fptr->io_pos = Fptr->filesize; /* currently positioned at EOF */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffgrsz( fitsfile *fptr, /* I - FITS file pionter */ long *ndata, /* O - optimal amount of data to access */ int *status) /* IO - error status */ /* Returns an optimal value for the number of rows in a binary table or the number of pixels in an image that should be read or written at one time for maximum efficiency. Accessing more data than this may cause excessive flushing and rereading of buffers to/from disk. */ { int typecode, bytesperpixel; /* There are NIOBUF internal buffers available each IOBUFLEN bytes long. */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header to get hdu struct */ return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU ) /* calc pixels per buffer size */ { /* image pixels are in column 2 of the 'table' */ ffgtcl(fptr, 2, &typecode, NULL, NULL, status); bytesperpixel = typecode / 10; *ndata = ((NIOBUF - 1) * IOBUFLEN) / bytesperpixel; } else /* calc number of rows that fit in buffers */ { *ndata = (long) (((NIOBUF - 1) * IOBUFLEN) / maxvalue(1, (fptr->Fptr)->rowlength)); *ndata = maxvalue(1, *ndata); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgtbb(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG firstrow, /* I - starting row (1 = first row) */ LONGLONG firstchar, /* I - starting byte in row (1=first) */ LONGLONG nchars, /* I - number of bytes to read */ unsigned char *values, /* I - array of bytes to read */ int *status) /* IO - error status */ /* read a consecutive string of bytes from an ascii or binary table. This will span multiple rows of the table if nchars + firstchar is greater than the length of a row. */ { LONGLONG bytepos, endrow; if (*status > 0 || nchars <= 0) return(*status); else if (firstrow < 1) return(*status=BAD_ROW_NUM); else if (firstchar < 1) return(*status=BAD_ELEM_NUM); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* check that we do not exceed number of rows in the table */ endrow = ((firstchar + nchars - 2) / (fptr->Fptr)->rowlength) + firstrow; if (endrow > (fptr->Fptr)->numrows) { ffpmsg("attempt to read past end of table (ffgtbb)"); return(*status=BAD_ROW_NUM); } /* move the i/o pointer to the start of the sequence of characters */ bytepos = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * (firstrow - 1)) + firstchar - 1; ffmbyt(fptr, bytepos, REPORT_EOF, status); ffgbyt(fptr, nchars, values, status); /* read the bytes */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgi1b(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG byteloc, /* I - position within file to start reading */ long nvals, /* I - number of pixels to read */ long incre, /* I - byte increment between pixels */ unsigned char *values, /* O - returned array of values */ int *status) /* IO - error status */ /* get (read) the array of values from the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { LONGLONG postemp; if (incre == 1) /* read all the values at once (contiguous bytes) */ { if (nvals < MINDIRECT) /* read normally via IO buffers */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbyt(fptr, nvals, values, status); } else /* read directly from disk, bypassing IO buffers */ { postemp = (fptr->Fptr)->bytepos; /* store current file position */ (fptr->Fptr)->bytepos = byteloc; /* set to the desired position */ ffgbyt(fptr, nvals, values, status); (fptr->Fptr)->bytepos = postemp; /* reset to original position */ } } else /* have to read each value individually (not contiguous ) */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbytoff(fptr, 1, nvals, incre - 1, values, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgi2b(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG byteloc, /* I - position within file to start reading */ long nvals, /* I - number of pixels to read */ long incre, /* I - byte increment between pixels */ short *values, /* O - returned array of values */ int *status) /* IO - error status */ /* get (read) the array of values from the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { LONGLONG postemp; if (incre == 2) /* read all the values at once (contiguous bytes) */ { if (nvals * 2 < MINDIRECT) /* read normally via IO buffers */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbyt(fptr, nvals * 2, values, status); } else /* read directly from disk, bypassing IO buffers */ { postemp = (fptr->Fptr)->bytepos; /* store current file position */ (fptr->Fptr)->bytepos = byteloc; /* set to the desired position */ ffgbyt(fptr, nvals * 2, values, status); (fptr->Fptr)->bytepos = postemp; /* reset to original position */ } } else /* have to read each value individually (not contiguous ) */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbytoff(fptr, 2, nvals, incre - 2, values, status); } #if BYTESWAPPED ffswap2(values, nvals); /* reverse order of bytes in each value */ #endif return(*status); } /*--------------------------------------------------------------------------*/ int ffgi4b(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG byteloc, /* I - position within file to start reading */ long nvals, /* I - number of pixels to read */ long incre, /* I - byte increment between pixels */ INT32BIT *values, /* O - returned array of values */ int *status) /* IO - error status */ /* get (read) the array of values from the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { LONGLONG postemp; if (incre == 4) /* read all the values at once (contiguous bytes) */ { if (nvals * 4 < MINDIRECT) /* read normally via IO buffers */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbyt(fptr, nvals * 4, values, status); } else /* read directly from disk, bypassing IO buffers */ { postemp = (fptr->Fptr)->bytepos; /* store current file position */ (fptr->Fptr)->bytepos = byteloc; /* set to the desired position */ ffgbyt(fptr, nvals * 4, values, status); (fptr->Fptr)->bytepos = postemp; /* reset to original position */ } } else /* have to read each value individually (not contiguous ) */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbytoff(fptr, 4, nvals, incre - 4, values, status); } #if BYTESWAPPED ffswap4(values, nvals); /* reverse order of bytes in each value */ #endif return(*status); } /*--------------------------------------------------------------------------*/ int ffgi8b(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG byteloc, /* I - position within file to start reading */ long nvals, /* I - number of pixels to read */ long incre, /* I - byte increment between pixels */ long *values, /* O - returned array of values */ int *status) /* IO - error status */ /* get (read) the array of values from the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! This routine reads 'nvals' 8-byte integers into 'values'. This works both on platforms that have sizeof(long) = 64, and 32, as long as 'values' has been allocated to large enough to hold 8 * nvals bytes of data. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ { LONGLONG postemp; if (incre == 8) /* read all the values at once (contiguous bytes) */ { if (nvals * 8 < MINDIRECT) /* read normally via IO buffers */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbyt(fptr, nvals * 8, values, status); } else /* read directly from disk, bypassing IO buffers */ { postemp = (fptr->Fptr)->bytepos; /* store current file position */ (fptr->Fptr)->bytepos = byteloc; /* set to the desired position */ ffgbyt(fptr, nvals * 8, values, status); (fptr->Fptr)->bytepos = postemp; /* reset to original position */ } } else /* have to read each value individually (not contiguous ) */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbytoff(fptr, 8, nvals, incre - 8, values, status); } #if BYTESWAPPED ffswap8((double *) values, nvals); /* reverse bytes in each value */ #endif return(*status); } /*--------------------------------------------------------------------------*/ int ffgr4b(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG byteloc, /* I - position within file to start reading */ long nvals, /* I - number of pixels to read */ long incre, /* I - byte increment between pixels */ float *values, /* O - returned array of values */ int *status) /* IO - error status */ /* get (read) the array of values from the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { LONGLONG postemp; #if MACHINE == VAXVMS long ii; #elif (MACHINE == ALPHAVMS) && (FLOATTYPE == GFLOAT) short *sptr; long ii; #endif if (incre == 4) /* read all the values at once (contiguous bytes) */ { if (nvals * 4 < MINDIRECT) /* read normally via IO buffers */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbyt(fptr, nvals * 4, values, status); } else /* read directly from disk, bypassing IO buffers */ { postemp = (fptr->Fptr)->bytepos; /* store current file position */ (fptr->Fptr)->bytepos = byteloc; /* set to the desired position */ ffgbyt(fptr, nvals * 4, values, status); (fptr->Fptr)->bytepos = postemp; /* reset to original position */ } } else /* have to read each value individually (not contiguous ) */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbytoff(fptr, 4, nvals, incre - 4, values, status); } #if MACHINE == VAXVMS ii = nvals; /* call VAX macro routine to convert */ ieevur(values, values, &ii); /* from IEEE float -> F float */ #elif (MACHINE == ALPHAVMS) && (FLOATTYPE == GFLOAT) ffswap2( (short *) values, nvals * 2); /* swap pairs of bytes */ /* convert from IEEE float format to VMS GFLOAT float format */ sptr = (short *) values; for (ii = 0; ii < nvals; ii++, sptr += 2) { if (!fnan(*sptr) ) /* test for NaN or underflow */ values[ii] *= 4.0; } #elif BYTESWAPPED ffswap4((INT32BIT *)values, nvals); /* reverse order of bytes in values */ #endif return(*status); } /*--------------------------------------------------------------------------*/ int ffgr8b(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG byteloc, /* I - position within file to start reading */ long nvals, /* I - number of pixels to read */ long incre, /* I - byte increment between pixels */ double *values, /* O - returned array of values */ int *status) /* IO - error status */ /* get (read) the array of values from the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { LONGLONG postemp; #if MACHINE == VAXVMS long ii; #elif (MACHINE == ALPHAVMS) && (FLOATTYPE == GFLOAT) short *sptr; long ii; #endif if (incre == 8) /* read all the values at once (contiguous bytes) */ { if (nvals * 8 < MINDIRECT) /* read normally via IO buffers */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbyt(fptr, nvals * 8, values, status); } else /* read directly from disk, bypassing IO buffers */ { postemp = (fptr->Fptr)->bytepos; /* store current file position */ (fptr->Fptr)->bytepos = byteloc; /* set to the desired position */ ffgbyt(fptr, nvals * 8, values, status); (fptr->Fptr)->bytepos = postemp; /* reset to original position */ } } else /* have to read each value individually (not contiguous ) */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbytoff(fptr, 8, nvals, incre - 8, values, status); } #if MACHINE == VAXVMS ii = nvals; /* call VAX macro routine to convert */ ieevud(values, values, &ii); /* from IEEE float -> D float */ #elif (MACHINE == ALPHAVMS) && (FLOATTYPE == GFLOAT) ffswap2( (short *) values, nvals * 4); /* swap pairs of bytes */ /* convert from IEEE float format to VMS GFLOAT float format */ sptr = (short *) values; for (ii = 0; ii < nvals; ii++, sptr += 4) { if (!dnan(*sptr) ) /* test for NaN or underflow */ values[ii] *= 4.0; } #elif BYTESWAPPED ffswap8(values, nvals); /* reverse order of bytes in each value */ #endif return(*status); } /*--------------------------------------------------------------------------*/ int ffptbb(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG firstrow, /* I - starting row (1 = first row) */ LONGLONG firstchar, /* I - starting byte in row (1=first) */ LONGLONG nchars, /* I - number of bytes to write */ unsigned char *values, /* I - array of bytes to write */ int *status) /* IO - error status */ /* write a consecutive string of bytes to an ascii or binary table. This will span multiple rows of the table if nchars + firstchar is greater than the length of a row. */ { LONGLONG bytepos, endrow, nrows; char message[FLEN_ERRMSG]; if (*status > 0 || nchars <= 0) return(*status); else if (firstrow < 1) return(*status=BAD_ROW_NUM); else if (firstchar < 1) return(*status=BAD_ELEM_NUM); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart < 0) /* rescan header if data undefined */ ffrdef(fptr, status); endrow = ((firstchar + nchars - 2) / (fptr->Fptr)->rowlength) + firstrow; /* check if we are writing beyond the current end of table */ if (endrow > (fptr->Fptr)->numrows) { /* if there are more HDUs following the current one, or */ /* if there is a data heap, then we must insert space */ /* for the new rows. */ if ( !((fptr->Fptr)->lasthdu) || (fptr->Fptr)->heapsize > 0) { nrows = endrow - ((fptr->Fptr)->numrows); /* ffirow also updates the heap address and numrows */ if (ffirow(fptr, (fptr->Fptr)->numrows, nrows, status) > 0) { snprintf(message, FLEN_ERRMSG, "ffptbb failed to add space for %.0f new rows in table.", (double) nrows); ffpmsg(message); return(*status); } } else { /* manally update heap starting address */ (fptr->Fptr)->heapstart += ((LONGLONG)(endrow - (fptr->Fptr)->numrows) * (fptr->Fptr)->rowlength ); (fptr->Fptr)->numrows = endrow; /* update number of rows */ } } /* move the i/o pointer to the start of the sequence of characters */ bytepos = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * (firstrow - 1)) + firstchar - 1; ffmbyt(fptr, bytepos, IGNORE_EOF, status); ffpbyt(fptr, nchars, values, status); /* write the bytes */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpi1b(fitsfile *fptr, /* I - FITS file pointer */ long nvals, /* I - number of pixels in the values array */ long incre, /* I - byte increment between pixels */ unsigned char *values, /* I - array of values to write */ int *status) /* IO - error status */ /* put (write) the array of values to the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { if (incre == 1) /* write all the values at once (contiguous bytes) */ ffpbyt(fptr, nvals, values, status); else /* have to write each value individually (not contiguous ) */ ffpbytoff(fptr, 1, nvals, incre - 1, values, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpi2b(fitsfile *fptr, /* I - FITS file pointer */ long nvals, /* I - number of pixels in the values array */ long incre, /* I - byte increment between pixels */ short *values, /* I - array of values to write */ int *status) /* IO - error status */ /* put (write) the array of values to the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { #if BYTESWAPPED ffswap2(values, nvals); /* reverse order of bytes in each value */ #endif if (incre == 2) /* write all the values at once (contiguous bytes) */ ffpbyt(fptr, nvals * 2, values, status); else /* have to write each value individually (not contiguous ) */ ffpbytoff(fptr, 2, nvals, incre - 2, values, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpi4b(fitsfile *fptr, /* I - FITS file pointer */ long nvals, /* I - number of pixels in the values array */ long incre, /* I - byte increment between pixels */ INT32BIT *values, /* I - array of values to write */ int *status) /* IO - error status */ /* put (write) the array of values to the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { #if BYTESWAPPED ffswap4(values, nvals); /* reverse order of bytes in each value */ #endif if (incre == 4) /* write all the values at once (contiguous bytes) */ ffpbyt(fptr, nvals * 4, values, status); else /* have to write each value individually (not contiguous ) */ ffpbytoff(fptr, 4, nvals, incre - 4, values, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpi8b(fitsfile *fptr, /* I - FITS file pointer */ long nvals, /* I - number of pixels in the values array */ long incre, /* I - byte increment between pixels */ long *values, /* I - array of values to write */ int *status) /* IO - error status */ /* put (write) the array of values to the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! This routine writes 'nvals' 8-byte integers from 'values'. This works both on platforms that have sizeof(long) = 64, and 32, as long as 'values' has been allocated to large enough to hold 8 * nvals bytes of data. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ { #if BYTESWAPPED ffswap8((double *) values, nvals); /* reverse bytes in each value */ #endif if (incre == 8) /* write all the values at once (contiguous bytes) */ ffpbyt(fptr, nvals * 8, values, status); else /* have to write each value individually (not contiguous ) */ ffpbytoff(fptr, 8, nvals, incre - 8, values, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpr4b(fitsfile *fptr, /* I - FITS file pointer */ long nvals, /* I - number of pixels in the values array */ long incre, /* I - byte increment between pixels */ float *values, /* I - array of values to write */ int *status) /* IO - error status */ /* put (write) the array of values to the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { #if MACHINE == VAXVMS long ii; ii = nvals; /* call VAX macro routine to convert */ ieevpr(values, values, &ii); /* from F float -> IEEE float */ #elif (MACHINE == ALPHAVMS) && (FLOATTYPE == GFLOAT) long ii; /* convert from VMS FFLOAT float format to IEEE float format */ for (ii = 0; ii < nvals; ii++) values[ii] *= 0.25; ffswap2( (short *) values, nvals * 2); /* swap pairs of bytes */ #elif BYTESWAPPED ffswap4((INT32BIT *) values, nvals); /* reverse order of bytes in values */ #endif if (incre == 4) /* write all the values at once (contiguous bytes) */ ffpbyt(fptr, nvals * 4, values, status); else /* have to write each value individually (not contiguous ) */ ffpbytoff(fptr, 4, nvals, incre - 4, values, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpr8b(fitsfile *fptr, /* I - FITS file pointer */ long nvals, /* I - number of pixels in the values array */ long incre, /* I - byte increment between pixels */ double *values, /* I - array of values to write */ int *status) /* IO - error status */ /* put (write) the array of values to the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { #if MACHINE == VAXVMS long ii; ii = nvals; /* call VAX macro routine to convert */ ieevpd(values, values, &ii); /* from D float -> IEEE float */ #elif (MACHINE == ALPHAVMS) && (FLOATTYPE == GFLOAT) long ii; /* convert from VMS GFLOAT float format to IEEE float format */ for (ii = 0; ii < nvals; ii++) values[ii] *= 0.25; ffswap2( (short *) values, nvals * 4); /* swap pairs of bytes */ #elif BYTESWAPPED ffswap8(values, nvals); /* reverse order of bytes in each value */ #endif if (incre == 8) /* write all the values at once (contiguous bytes) */ ffpbyt(fptr, nvals * 8, values, status); else /* have to write each value individually (not contiguous ) */ ffpbytoff(fptr, 8, nvals, incre - 8, values, status); return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/cfileio.c0000644000175100001710000100303700000000000017705 0ustar00vstsdocker/* This file, cfileio.c, contains the low-level file access routines. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include #include /* apparently needed to define size_t */ #include "fitsio2.h" #include "group.h" #ifdef CFITSIO_HAVE_CURL #include #endif #define MAX_PREFIX_LEN 20 /* max length of file type prefix (e.g. 'http://') */ #define MAX_DRIVERS 31 /* max number of file I/O drivers */ typedef struct /* structure containing pointers to I/O driver functions */ { char prefix[MAX_PREFIX_LEN]; int (*init)(void); int (*shutdown)(void); int (*setoptions)(int option); int (*getoptions)(int *options); int (*getversion)(int *version); int (*checkfile)(char *urltype, char *infile, char *outfile); int (*open)(char *filename, int rwmode, int *driverhandle); int (*create)(char *filename, int *drivehandle); int (*truncate)(int drivehandle, LONGLONG size); int (*close)(int drivehandle); int (*remove)(char *filename); int (*size)(int drivehandle, LONGLONG *size); int (*flush)(int drivehandle); int (*seek)(int drivehandle, LONGLONG offset); int (*read)(int drivehandle, void *buffer, long nbytes); int (*write)(int drivehandle, void *buffer, long nbytes); } fitsdriver; fitsdriver driverTable[MAX_DRIVERS]; /* allocate driver tables */ FITSfile *FptrTable[NMAXFILES]; /* this table of Fptr pointers is */ /* used by fits_already_open */ int need_to_initialize = 1; /* true if CFITSIO has not been initialized */ int no_of_drivers = 0; /* number of currently defined I/O drivers */ static int pixel_filter_helper(fitsfile **fptr, char *outfile, char *expr, int *status); static int find_quote(char **string); static int find_doublequote(char **string); static int find_paren(char **string); static int find_bracket(char **string); static int find_curlybracket(char **string); static int standardize_path(char *fullpath, int *status); int comma2semicolon(char *string); #ifdef _REENTRANT pthread_mutex_t Fitsio_InitLock = PTHREAD_MUTEX_INITIALIZER; #endif /*--------------------------------------------------------------------------*/ int fitsio_init_lock(void) { int status = 0; #ifdef _REENTRANT static int need_to_init = 1; pthread_mutexattr_t mutex_init; FFLOCK1(Fitsio_InitLock); if (need_to_init) { /* Init the main fitsio lock here since we need a a recursive lock */ status = pthread_mutexattr_init(&mutex_init); if (status) { ffpmsg("pthread_mutexattr_init failed (fitsio_init_lock)"); return(status); } #ifdef __GLIBC__ status = pthread_mutexattr_settype(&mutex_init, PTHREAD_MUTEX_RECURSIVE_NP); #else status = pthread_mutexattr_settype(&mutex_init, PTHREAD_MUTEX_RECURSIVE); #endif if (status) { ffpmsg("pthread_mutexattr_settype failed (fitsio_init_lock)"); return(status); } status = pthread_mutex_init(&Fitsio_Lock,&mutex_init); if (status) { ffpmsg("pthread_mutex_init failed (fitsio_init_lock)"); return(status); } need_to_init = 0; } FFUNLOCK1(Fitsio_InitLock); #endif return(status); } /*--------------------------------------------------------------------------*/ int ffomem(fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - name of file to open */ int mode, /* I - 0 = open readonly; 1 = read/write */ void **buffptr, /* I - address of memory pointer */ size_t *buffsize, /* I - size of buffer, in bytes */ size_t deltasize, /* I - increment for future realloc's */ void *(*mem_realloc)(void *p, size_t newsize), /* function */ int *status) /* IO - error status */ /* Open an existing FITS file in core memory. This is a specialized version of ffopen. */ { int ii, driver, handle, hdutyp, slen, movetotype, extvers, extnum; char extname[FLEN_VALUE]; LONGLONG filesize; char urltype[MAX_PREFIX_LEN], infile[FLEN_FILENAME], outfile[FLEN_FILENAME]; char extspec[FLEN_FILENAME], rowfilter[FLEN_FILENAME]; char binspec[FLEN_FILENAME], colspec[FLEN_FILENAME]; char imagecolname[FLEN_VALUE], rowexpress[FLEN_FILENAME]; char *url, errmsg[FLEN_ERRMSG]; char *hdtype[3] = {"IMAGE", "TABLE", "BINTABLE"}; if (*status > 0) return(*status); *fptr = 0; /* initialize null file pointer */ if (need_to_initialize) /* this is called only once */ { *status = fits_init_cfitsio(); if (*status > 0) return(*status); } url = (char *) name; while (*url == ' ') /* ignore leading spaces in the file spec */ url++; /* parse the input file specification */ fits_parse_input_url(url, urltype, infile, outfile, extspec, rowfilter, binspec, colspec, status); strcpy(urltype, "memkeep://"); /* URL type for pre-existing memory file */ *status = urltype2driver(urltype, &driver); if (*status > 0) { ffpmsg("could not find driver for pre-existing memory file: (ffomem)"); return(*status); } /* call driver routine to open the memory file */ FFLOCK; /* lock this while searching for vacant handle */ *status = mem_openmem( buffptr, buffsize,deltasize, mem_realloc, &handle); FFUNLOCK; if (*status > 0) { ffpmsg("failed to open pre-existing memory file: (ffomem)"); return(*status); } /* get initial file size */ *status = (*driverTable[driver].size)(handle, &filesize); if (*status > 0) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed get the size of the memory file: (ffomem)"); return(*status); } /* allocate fitsfile structure and initialize = 0 */ *fptr = (fitsfile *) calloc(1, sizeof(fitsfile)); if (!(*fptr)) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate structure for following file: (ffomem)"); ffpmsg(url); return(*status = MEMORY_ALLOCATION); } /* allocate FITSfile structure and initialize = 0 */ (*fptr)->Fptr = (FITSfile *) calloc(1, sizeof(FITSfile)); if (!((*fptr)->Fptr)) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate structure for following file: (ffomem)"); ffpmsg(url); free(*fptr); *fptr = 0; return(*status = MEMORY_ALLOCATION); } slen = strlen(url) + 1; slen = maxvalue(slen, 32); /* reserve at least 32 chars */ ((*fptr)->Fptr)->filename = (char *) malloc(slen); /* mem for file name */ if ( !(((*fptr)->Fptr)->filename) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for filename: (ffomem)"); ffpmsg(url); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } /* mem for headstart array */ ((*fptr)->Fptr)->headstart = (LONGLONG *) calloc(1001, sizeof(LONGLONG)); if ( !(((*fptr)->Fptr)->headstart) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for headstart array: (ffomem)"); ffpmsg(url); free( ((*fptr)->Fptr)->filename); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } /* mem for file I/O buffers */ ((*fptr)->Fptr)->iobuffer = (char *) calloc(NIOBUF, IOBUFLEN); if ( !(((*fptr)->Fptr)->iobuffer) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for iobuffer array: (ffomem)"); ffpmsg(url); free( ((*fptr)->Fptr)->headstart); /* free memory for headstart array */ free( ((*fptr)->Fptr)->filename); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } /* initialize the ageindex array (relative age of the I/O buffers) */ /* and initialize the bufrecnum array as being empty */ for (ii = 0; ii < NIOBUF; ii++) { ((*fptr)->Fptr)->ageindex[ii] = ii; ((*fptr)->Fptr)->bufrecnum[ii] = -1; } /* store the parameters describing the file */ ((*fptr)->Fptr)->MAXHDU = 1000; /* initial size of headstart */ ((*fptr)->Fptr)->filehandle = handle; /* file handle */ ((*fptr)->Fptr)->driver = driver; /* driver number */ strcpy(((*fptr)->Fptr)->filename, url); /* full input filename */ ((*fptr)->Fptr)->filesize = filesize; /* physical file size */ ((*fptr)->Fptr)->logfilesize = filesize; /* logical file size */ ((*fptr)->Fptr)->writemode = mode; /* read-write mode */ ((*fptr)->Fptr)->datastart = DATA_UNDEFINED; /* unknown start of data */ ((*fptr)->Fptr)->curbuf = -1; /* undefined current IO buffer */ ((*fptr)->Fptr)->open_count = 1; /* structure is currently used once */ ((*fptr)->Fptr)->validcode = VALIDSTRUC; /* flag denoting valid structure */ ((*fptr)->Fptr)->noextsyntax = 0; /* extended syntax can be used in filename */ ffldrc(*fptr, 0, REPORT_EOF, status); /* load first record */ fits_store_Fptr( (*fptr)->Fptr, status); /* store Fptr address */ if (ffrhdu(*fptr, &hdutyp, status) > 0) /* determine HDU structure */ { ffpmsg( "ffomem could not interpret primary array header of file: (ffomem)"); ffpmsg(url); if (*status == UNKNOWN_REC) ffpmsg("This does not look like a FITS file."); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ } /* ---------------------------------------------------------- */ /* move to desired extension, if specified as part of the URL */ /* ---------------------------------------------------------- */ imagecolname[0] = '\0'; rowexpress[0] = '\0'; if (*extspec) { /* parse the extension specifier into individual parameters */ ffexts(extspec, &extnum, extname, &extvers, &movetotype, imagecolname, rowexpress, status); if (*status > 0) return(*status); if (extnum) { ffmahd(*fptr, extnum + 1, &hdutyp, status); } else if (*extname) /* move to named extension, if specified */ { ffmnhd(*fptr, movetotype, extname, extvers, status); } if (*status > 0) { ffpmsg("ffomem could not move to the specified extension:"); if (extnum > 0) { snprintf(errmsg, FLEN_ERRMSG, " extension number %d doesn't exist or couldn't be opened.",extnum); ffpmsg(errmsg); } else { snprintf(errmsg, FLEN_ERRMSG, " extension with EXTNAME = %s,", extname); ffpmsg(errmsg); if (extvers) { snprintf(errmsg, FLEN_ERRMSG, " and with EXTVERS = %d,", extvers); ffpmsg(errmsg); } if (movetotype != ANY_HDU) { snprintf(errmsg, FLEN_ERRMSG, " and with XTENSION = %s,", hdtype[movetotype]); ffpmsg(errmsg); } ffpmsg(" doesn't exist or couldn't be opened."); } return(*status); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffdkopn(fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - full name of file to open */ int mode, /* I - 0 = open readonly; 1 = read/write */ int *status) /* IO - error status */ /* Open an existing FITS file on magnetic disk with either readonly or read/write access. The routine does not support CFITSIO's extended filename syntax and simply uses the entire input 'name' string as the name of the file. */ { if (*status > 0) return(*status); *status = OPEN_DISK_FILE; ffopen(fptr, name, mode, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffdopn(fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - full name of file to open */ int mode, /* I - 0 = open readonly; 1 = read/write */ int *status) /* IO - error status */ /* Open an existing FITS file with either readonly or read/write access. and move to the first HDU that contains 'interesting' data, if the primary array contains a null image (i.e., NAXIS = 0). */ { if (*status > 0) return(*status); *status = SKIP_NULL_PRIMARY; ffopen(fptr, name, mode, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffeopn(fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - full name of file to open */ int mode, /* I - 0 = open readonly; 1 = read/write */ char *extlist, /* I - list of 'good' extensions to move to */ int *hdutype, /* O - type of extension that is moved to */ int *status) /* IO - error status */ /* Open an existing FITS file with either readonly or read/write access. and if the primary array contains a null image (i.e., NAXIS = 0) then attempt to move to the first extension named in the extlist of extension names. If none are found, then simply move to the 2nd extension. */ { int hdunum, naxis = 0, thdutype, gotext=0; char *ext, *textlist; char *saveptr; if (*status > 0) return(*status); if (ffopen(fptr, name, mode, status) > 0) return(*status); fits_get_hdu_num(*fptr, &hdunum); fits_get_hdu_type(*fptr, &thdutype, status); if (hdunum == 1 && thdutype == IMAGE_HDU) { fits_get_img_dim(*fptr, &naxis, status); } /* We are in the "default" primary extension */ /* look through the extension list */ if( (hdunum == 1) && (naxis == 0) ){ if( extlist ){ gotext = 0; textlist = malloc(strlen(extlist) + 1); if (!textlist) { *status = MEMORY_ALLOCATION; return(*status); } strcpy(textlist, extlist); for(ext=(char *)ffstrtok(textlist, " ",&saveptr); ext != NULL; ext=(char *)ffstrtok(NULL," ",&saveptr)){ fits_movnam_hdu(*fptr, ANY_HDU, ext, 0, status); if( *status == 0 ){ gotext = 1; break; } else { *status = 0; } } free(textlist); } if( !gotext ){ /* if all else fails, move to extension #2 and hope for the best */ fits_movabs_hdu(*fptr, 2, &thdutype, status); } } if (hdutype) { fits_get_hdu_type(*fptr, hdutype, status); } return(*status); } /*--------------------------------------------------------------------------*/ int fftopn(fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - full name of file to open */ int mode, /* I - 0 = open readonly; 1 = read/write */ int *status) /* IO - error status */ /* Open an existing FITS file with either readonly or read/write access. and move to the first HDU that contains 'interesting' table (not an image). */ { int hdutype; if (*status > 0) return(*status); *status = SKIP_IMAGE; ffopen(fptr, name, mode, status); if (ffghdt(*fptr, &hdutype, status) <= 0) { if (hdutype == IMAGE_HDU) *status = NOT_TABLE; } return(*status); } /*--------------------------------------------------------------------------*/ int ffiopn(fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - full name of file to open */ int mode, /* I - 0 = open readonly; 1 = read/write */ int *status) /* IO - error status */ /* Open an existing FITS file with either readonly or read/write access. and move to the first HDU that contains 'interesting' image (not an table). */ { int hdutype; if (*status > 0) return(*status); *status = SKIP_TABLE; ffopen(fptr, name, mode, status); if (ffghdt(*fptr, &hdutype, status) <= 0) { if (hdutype != IMAGE_HDU) *status = NOT_IMAGE; } return(*status); } /*--------------------------------------------------------------------------*/ int ffopentest(int soname, /* I - CFITSIO shared library version */ /* application program (fitsio.h file) */ fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - full name of file to open */ int mode, /* I - 0 = open readonly; 1 = read/write */ int *status) /* IO - error status */ /* Open an existing FITS file with either readonly or read/write access. First test that the SONAME of fitsio.h used to build the CFITSIO library is the same as was used in compiling the application program that links to the library. */ { if (soname != CFITSIO_SONAME) { printf("\nERROR: Mismatch in the CFITSIO_SONAME value in the fitsio.h include file\n"); printf("that was used to build the CFITSIO library, and the value in the include file\n"); printf("that was used when compiling the application program:\n"); printf(" Version used to build the CFITSIO library = %d\n",CFITSIO_SONAME); printf(" Version included by the application program = %d\n",soname); printf("\nFix this by recompiling and then relinking this application program \n"); printf("with the CFITSIO library.\n"); *status = FILE_NOT_OPENED; return(*status); } /* now call the normal file open routine */ ffopen(fptr, name, mode, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffopen(fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - full name of file to open */ int mode, /* I - 0 = open readonly; 1 = read/write */ int *status) /* IO - error status */ /* Open an existing FITS file with either readonly or read/write access. */ { fitsfile *newptr; int ii, driver, hdutyp, hdunum, slen, writecopy, isopen; LONGLONG filesize; long rownum, nrows, goodrows; int extnum, extvers, handle, movetotype, tstatus = 0, only_one = 0; char urltype[MAX_PREFIX_LEN], infile[FLEN_FILENAME], outfile[FLEN_FILENAME]; char origurltype[MAX_PREFIX_LEN], extspec[FLEN_FILENAME]; char extname[FLEN_VALUE], rowfilter[FLEN_FILENAME], tblname[FLEN_VALUE]; char imagecolname[FLEN_VALUE], rowexpress[FLEN_FILENAME]; char binspec[FLEN_FILENAME], colspec[FLEN_FILENAME], pixfilter[FLEN_FILENAME]; char histfilename[FLEN_FILENAME]; char filtfilename[FLEN_FILENAME], compspec[FLEN_FILENAME]; char wtcol[FLEN_VALUE]; char minname[4][FLEN_VALUE], maxname[4][FLEN_VALUE]; char binname[4][FLEN_VALUE]; char *url; double minin[4], maxin[4], binsizein[4], weight; int imagetype, naxis = 1, haxis, recip; int skip_null = 0, skip_image = 0, skip_table = 0, open_disk_file = 0; char colname[4][FLEN_VALUE]; char errmsg[FLEN_ERRMSG]; char *hdtype[3] = {"IMAGE", "TABLE", "BINTABLE"}; char *rowselect = 0; if (*status > 0) return(*status); if (*status == SKIP_NULL_PRIMARY) { /* this special status value is used as a flag by ffdopn to tell */ /* ffopen to skip over a null primary array when opening the file. */ skip_null = 1; *status = 0; } else if (*status == SKIP_IMAGE) { /* this special status value is used as a flag by fftopn to tell */ /* ffopen to move to 1st significant table when opening the file. */ skip_image = 1; *status = 0; } else if (*status == SKIP_TABLE) { /* this special status value is used as a flag by ffiopn to tell */ /* ffopen to move to 1st significant image when opening the file. */ skip_table = 1; *status = 0; } else if (*status == OPEN_DISK_FILE) { /* this special status value is used as a flag by ffdkopn to tell */ /* ffopen to not interpret the input filename using CFITSIO's */ /* extended filename syntax, and simply open the specified disk file */ open_disk_file = 1; *status = 0; } *fptr = 0; /* initialize null file pointer */ writecopy = 0; /* have we made a write-able copy of the input file? */ if (need_to_initialize) { /* this is called only once */ *status = fits_init_cfitsio(); } if (*status > 0) return(*status); url = (char *) name; while (*url == ' ') /* ignore leading spaces in the filename */ url++; if (*url == '\0') { ffpmsg("Name of file to open is blank. (ffopen)"); return(*status = FILE_NOT_OPENED); } if (open_disk_file) { /* treat the input URL literally as the name of the file to open */ /* and don't try to parse the URL using the extended filename syntax */ if (strlen(url) > FLEN_FILENAME - 1) { ffpmsg("Name of file to open is too long. (ffopen)"); return(*status = FILE_NOT_OPENED); } strcpy(infile,url); strcpy(urltype, "file://"); outfile[0] = '\0'; extspec[0] = '\0'; binspec[0] = '\0'; colspec[0] = '\0'; rowfilter[0] = '\0'; pixfilter[0] = '\0'; compspec[0] = '\0'; } else { /* parse the input file specification */ /* NOTE: This routine tests that all the strings do not */ /* overflow the standard buffer sizes (FLEN_FILENAME, etc.) */ /* therefore in general we do not have to worry about buffer */ /* overflow of any of the returned strings. */ /* call the newer version of this parsing routine that supports 'compspec' */ ffifile2(url, urltype, infile, outfile, extspec, rowfilter, binspec, colspec, pixfilter, compspec, status); } if (*status > 0) { ffpmsg("could not parse the input filename: (ffopen)"); ffpmsg(url); return(*status); } imagecolname[0] = '\0'; rowexpress[0] = '\0'; if (*extspec) { slen = strlen(extspec); if (extspec[slen - 1] == '#') { /* special symbol to mean only copy this extension */ extspec[slen - 1] = '\0'; only_one = 1; } /* parse the extension specifier into individual parameters */ ffexts(extspec, &extnum, extname, &extvers, &movetotype, imagecolname, rowexpress, status); if (*status > 0) return(*status); } /*-------------------------------------------------------------------*/ /* special cases: */ /*-------------------------------------------------------------------*/ histfilename[0] = '\0'; filtfilename[0] = '\0'; if (*outfile && (*binspec || *imagecolname || *pixfilter)) { /* if binspec or imagecolumn are specified, then the */ /* output file name is intended for the final image, */ /* and not a copy of the input file. */ strcpy(histfilename, outfile); outfile[0] = '\0'; } else if (*outfile && (*rowfilter || *colspec)) { /* if rowfilter or colspece are specified, then the */ /* output file name is intended for the filtered file */ /* and not a copy of the input file. */ strcpy(filtfilename, outfile); outfile[0] = '\0'; } /*-------------------------------------------------------------------*/ /* check if this same file is already open, and if so, attach to it */ /*-------------------------------------------------------------------*/ FFLOCK; if (fits_already_open(fptr, url, urltype, infile, extspec, rowfilter, binspec, colspec, mode, open_disk_file, &isopen, status) > 0) { FFUNLOCK; return(*status); } FFUNLOCK; if (isopen) { goto move2hdu; } /* get the driver number corresponding to this urltype */ *status = urltype2driver(urltype, &driver); if (*status > 0) { ffpmsg("could not find driver for this file: (ffopen)"); ffpmsg(urltype); ffpmsg(url); return(*status); } /*------------------------------------------------------------------- deal with all those messy special cases which may require that a different driver be used: - is disk file compressed? - are ftp:, gsiftp:, or http: files compressed? - has user requested that a local copy be made of the ftp or http file? -------------------------------------------------------------------*/ if (driverTable[driver].checkfile) { strcpy(origurltype,urltype); /* Save the urltype */ /* 'checkfile' may modify the urltype, infile and outfile strings */ *status = (*driverTable[driver].checkfile)(urltype, infile, outfile); if (*status) { ffpmsg("checkfile failed for this file: (ffopen)"); ffpmsg(url); return(*status); } if (strcmp(origurltype, urltype)) /* did driver changed on us? */ { *status = urltype2driver(urltype, &driver); if (*status > 0) { ffpmsg("could not change driver for this file: (ffopen)"); ffpmsg(url); ffpmsg(urltype); return(*status); } } } /* call appropriate driver to open the file */ if (driverTable[driver].open) { FFLOCK; /* lock this while searching for vacant handle */ *status = (*driverTable[driver].open)(infile, mode, &handle); FFUNLOCK; if (*status > 0) { ffpmsg("failed to find or open the following file: (ffopen)"); ffpmsg(url); return(*status); } } else { ffpmsg("cannot open an existing file of this type: (ffopen)"); ffpmsg(url); return(*status = FILE_NOT_OPENED); } /* get initial file size */ *status = (*driverTable[driver].size)(handle, &filesize); if (*status > 0) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed get the size of the following file: (ffopen)"); ffpmsg(url); return(*status); } /* allocate fitsfile structure and initialize = 0 */ *fptr = (fitsfile *) calloc(1, sizeof(fitsfile)); if (!(*fptr)) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate structure for following file: (ffopen)"); ffpmsg(url); return(*status = MEMORY_ALLOCATION); } /* allocate FITSfile structure and initialize = 0 */ (*fptr)->Fptr = (FITSfile *) calloc(1, sizeof(FITSfile)); if (!((*fptr)->Fptr)) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate structure for following file: (ffopen)"); ffpmsg(url); free(*fptr); *fptr = 0; return(*status = MEMORY_ALLOCATION); } slen = strlen(url) + 1; slen = maxvalue(slen, 32); /* reserve at least 32 chars */ ((*fptr)->Fptr)->filename = (char *) malloc(slen); /* mem for file name */ if ( !(((*fptr)->Fptr)->filename) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for filename: (ffopen)"); ffpmsg(url); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } /* mem for headstart array */ ((*fptr)->Fptr)->headstart = (LONGLONG *) calloc(1001, sizeof(LONGLONG)); if ( !(((*fptr)->Fptr)->headstart) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for headstart array: (ffopen)"); ffpmsg(url); free( ((*fptr)->Fptr)->filename); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } /* mem for file I/O buffers */ ((*fptr)->Fptr)->iobuffer = (char *) calloc(NIOBUF, IOBUFLEN); if ( !(((*fptr)->Fptr)->iobuffer) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for iobuffer array: (ffopen)"); ffpmsg(url); free( ((*fptr)->Fptr)->headstart); /* free memory for headstart array */ free( ((*fptr)->Fptr)->filename); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } /* initialize the ageindex array (relative age of the I/O buffers) */ /* and initialize the bufrecnum array as being empty */ for (ii = 0; ii < NIOBUF; ii++) { ((*fptr)->Fptr)->ageindex[ii] = ii; ((*fptr)->Fptr)->bufrecnum[ii] = -1; } /* store the parameters describing the file */ ((*fptr)->Fptr)->MAXHDU = 1000; /* initial size of headstart */ ((*fptr)->Fptr)->filehandle = handle; /* file handle */ ((*fptr)->Fptr)->driver = driver; /* driver number */ strcpy(((*fptr)->Fptr)->filename, url); /* full input filename */ ((*fptr)->Fptr)->filesize = filesize; /* physical file size */ ((*fptr)->Fptr)->logfilesize = filesize; /* logical file size */ ((*fptr)->Fptr)->writemode = mode; /* read-write mode */ ((*fptr)->Fptr)->datastart = DATA_UNDEFINED; /* unknown start of data */ ((*fptr)->Fptr)->curbuf = -1; /* undefined current IO buffer */ ((*fptr)->Fptr)->open_count = 1; /* structure is currently used once */ ((*fptr)->Fptr)->validcode = VALIDSTRUC; /* flag denoting valid structure */ ((*fptr)->Fptr)->only_one = only_one; /* flag denoting only copy single extension */ ((*fptr)->Fptr)->noextsyntax = open_disk_file; /* true if extended syntax is disabled */ ffldrc(*fptr, 0, REPORT_EOF, status); /* load first record */ fits_store_Fptr( (*fptr)->Fptr, status); /* store Fptr address */ if (ffrhdu(*fptr, &hdutyp, status) > 0) /* determine HDU structure */ { ffpmsg( "ffopen could not interpret primary array header of file: "); ffpmsg(url); if (*status == UNKNOWN_REC) ffpmsg("This does not look like a FITS file."); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } /* ------------------------------------------------------------- */ /* At this point, the input file has been opened. If outfile was */ /* specified, then we have opened a copy of the file, not the */ /* original file so it is safe to modify it if necessary */ /* ------------------------------------------------------------- */ if (*outfile) writecopy = 1; move2hdu: /* ---------------------------------------------------------- */ /* move to desired extension, if specified as part of the URL */ /* ---------------------------------------------------------- */ if (*extspec) { if (extnum) /* extension number was specified */ { ffmahd(*fptr, extnum + 1, &hdutyp, status); } else if (*extname) /* move to named extension, if specified */ { ffmnhd(*fptr, movetotype, extname, extvers, status); } if (*status > 0) /* clean up after error */ { ffpmsg("ffopen could not move to the specified extension:"); if (extnum > 0) { snprintf(errmsg, FLEN_ERRMSG, " extension number %d doesn't exist or couldn't be opened.",extnum); ffpmsg(errmsg); } else { snprintf(errmsg, FLEN_ERRMSG, " extension with EXTNAME = %s,", extname); ffpmsg(errmsg); if (extvers) { snprintf(errmsg, FLEN_ERRMSG, " and with EXTVERS = %d,", extvers); ffpmsg(errmsg); } if (movetotype != ANY_HDU) { snprintf(errmsg, FLEN_ERRMSG, " and with XTENSION = %s,", hdtype[movetotype]); ffpmsg(errmsg); } ffpmsg(" doesn't exist or couldn't be opened."); } ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } } else if (skip_null || skip_image || skip_table || (*imagecolname || *colspec || *rowfilter || *binspec)) { /* ------------------------------------------------------------------ If no explicit extension specifier is given as part of the file name, and, if a) skip_null is true (set if ffopen is called by ffdopn) or b) skip_image or skip_table is true (set if ffopen is called by fftopn or ffdopn) or c) other file filters are specified, then CFITSIO will attempt to move to the first 'interesting' HDU after opening an existing FITS file (or to first interesting table HDU if skip_image is true); An 'interesting' HDU is defined to be either an image with NAXIS > 0 (i.e., not a null array) or a table which has an EXTNAME value which does not contain any of the following strings: 'GTI' - Good Time Interval extension 'OBSTABLE' - used in Beppo SAX data files The main purpose for this is to allow CFITSIO to skip over a null primary and other non-interesting HDUs when opening an existing file, and move directly to the first extension that contains significant data. ------------------------------------------------------------------ */ fits_get_hdu_num(*fptr, &hdunum); if (hdunum == 1) { fits_get_img_dim(*fptr, &naxis, status); if (naxis == 0 || skip_image) /* skip primary array */ { while(1) { /* see if the next HDU is 'interesting' */ if (fits_movrel_hdu(*fptr, 1, &hdutyp, status)) { if (*status == END_OF_FILE) *status = 0; /* reset expected error */ /* didn't find an interesting HDU so move back to beginning */ fits_movabs_hdu(*fptr, 1, &hdutyp, status); break; } if (hdutyp == IMAGE_HDU && skip_image) { continue; /* skip images */ } else if (hdutyp != IMAGE_HDU && skip_table) { continue; /* skip tables */ } else if (hdutyp == IMAGE_HDU) { fits_get_img_dim(*fptr, &naxis, status); if (naxis > 0) break; /* found a non-null image */ } else { tstatus = 0; tblname[0] = '\0'; fits_read_key(*fptr, TSTRING, "EXTNAME", tblname, NULL,&tstatus); if ( (!strstr(tblname, "GTI") && !strstr(tblname, "gti")) && fits_strncasecmp(tblname, "OBSTABLE", 8) ) break; /* found an interesting table */ } } /* end while */ } } /* end if (hdunum==1) */ } if (*imagecolname) { /* ----------------------------------------------------------------- */ /* we need to open an image contained in a single table cell */ /* First, determine which row of the table to use. */ /* ----------------------------------------------------------------- */ if (isdigit((int) *rowexpress)) /* is the row specification a number? */ { sscanf(rowexpress, "%ld", &rownum); if (rownum < 1) { ffpmsg("illegal rownum for image cell:"); ffpmsg(rowexpress); ffpmsg("Could not open the following image in a table cell:"); ffpmsg(extspec); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status = BAD_ROW_NUM); } } else if (fits_find_first_row(*fptr, rowexpress, &rownum, status) > 0) { ffpmsg("Failed to find row matching this expression:"); ffpmsg(rowexpress); ffpmsg("Could not open the following image in a table cell:"); ffpmsg(extspec); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } if (rownum == 0) { ffpmsg("row satisfying this expression doesn't exist::"); ffpmsg(rowexpress); ffpmsg("Could not open the following image in a table cell:"); ffpmsg(extspec); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status = BAD_ROW_NUM); } /* determine the name of the new file to contain copy of the image */ if (*histfilename && !(*pixfilter) ) strcpy(outfile, histfilename); /* the original outfile name */ else strcpy(outfile, "mem://_1"); /* create image file in memory */ /* Copy the image into new primary array and open it as the current */ /* fptr. This will close the table that contains the original image. */ /* create new empty file to hold copy of the image */ if (ffinit(&newptr, outfile, status) > 0) { ffpmsg("failed to create file for copy of image in table cell:"); ffpmsg(outfile); return(*status); } if (fits_copy_cell2image(*fptr, newptr, imagecolname, rownum, status) > 0) { ffpmsg("Failed to copy table cell to new primary array:"); ffpmsg(extspec); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } /* close the original file and set fptr to the new image */ ffclos(*fptr, status); *fptr = newptr; /* reset the pointer to the new table */ writecopy = 1; /* we are now dealing with a copy of the original file */ /* leave it up to calling routine to write any HISTORY keywords */ } /* --------------------------------------------------------------------- */ /* edit columns (and/or keywords) in the table, if specified in the URL */ /* --------------------------------------------------------------------- */ if (*colspec) { /* the column specifier will modify the file, so make sure */ /* we are already dealing with a copy, or else make a new copy */ if (!writecopy) /* Is the current file already a copy? */ writecopy = fits_is_this_a_copy(urltype); if (!writecopy) { if (*filtfilename && *outfile == '\0') strcpy(outfile, filtfilename); /* the original outfile name */ else strcpy(outfile, "mem://_1"); /* will create copy in memory */ writecopy = 1; } else { ((*fptr)->Fptr)->writemode = READWRITE; /* we have write access */ outfile[0] = '\0'; } if (ffedit_columns(fptr, outfile, colspec, status) > 0) { ffpmsg("editing columns in input table failed (ffopen)"); ffpmsg(" while trying to perform the following operation:"); ffpmsg(colspec); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } } /* ------------------------------------------------------------------- */ /* select rows from the table, if specified in the URL */ /* or select a subimage (if this is an image HDU and not a table) */ /* ------------------------------------------------------------------- */ if (*rowfilter) { fits_get_hdu_type(*fptr, &hdutyp, status); /* get type of HDU */ if (hdutyp == IMAGE_HDU) { /* this is an image so 'rowfilter' is an image section specification */ if (*filtfilename && *outfile == '\0') strcpy(outfile, filtfilename); /* the original outfile name */ else if (*outfile == '\0') /* output file name not already defined? */ strcpy(outfile, "mem://_2"); /* will create file in memory */ /* create new file containing the image section, plus a copy of */ /* any other HDUs that exist in the input file. This routine */ /* will close the original image file and return a pointer */ /* to the new file. */ if (fits_select_image_section(fptr, outfile, rowfilter, status) > 0) { ffpmsg("on-the-fly selection of image section failed (ffopen)"); ffpmsg(" while trying to use the following section filter:"); ffpmsg(rowfilter); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } } else { /* this is a table HDU, so the rowfilter is really a row filter */ if (*binspec) { /* since we are going to make a histogram of the selected rows, */ /* it would be a waste of time and memory to make a whole copy of */ /* the selected rows. Instead, just construct an array of TRUE */ /* or FALSE values that indicate which rows are to be included */ /* in the histogram and pass that to the histogram generating */ /* routine */ fits_get_num_rows(*fptr, &nrows, status); /* get no. of rows */ rowselect = (char *) calloc(nrows, 1); if (!rowselect) { ffpmsg( "failed to allocate memory for selected columns array (ffopen)"); ffpmsg(" while trying to select rows with the following filter:"); ffpmsg(rowfilter); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } if (fits_find_rows(*fptr, rowfilter, 1L, nrows, &goodrows, rowselect, status) > 0) { ffpmsg("selection of rows in input table failed (ffopen)"); ffpmsg(" while trying to select rows with the following filter:"); ffpmsg(rowfilter); free(rowselect); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } } else { if (!writecopy) /* Is the current file already a copy? */ writecopy = fits_is_this_a_copy(urltype); if (!writecopy) { if (*filtfilename && *outfile == '\0') strcpy(outfile, filtfilename); /* the original outfile name */ else if (*outfile == '\0') /* output filename not already defined? */ strcpy(outfile, "mem://_2"); /* will create copy in memory */ } else { ((*fptr)->Fptr)->writemode = READWRITE; /* we have write access */ outfile[0] = '\0'; } /* select rows in the table. If a copy of the input file has */ /* not already been made, then this routine will make a copy */ /* and then close the input file, so that the modifications will */ /* only be made on the copy, not the original */ if (ffselect_table(fptr, outfile, rowfilter, status) > 0) { ffpmsg("on-the-fly selection of rows in input table failed (ffopen)"); ffpmsg(" while trying to select rows with the following filter:"); ffpmsg(rowfilter); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } /* write history records */ ffphis(*fptr, "CFITSIO used the following filtering expression to create this table:", status); ffphis(*fptr, name, status); } /* end of no binspec case */ } /* end of table HDU case */ } /* end of rowfilter exists case */ /* ------------------------------------------------------------------- */ /* make an image histogram by binning columns, if specified in the URL */ /* ------------------------------------------------------------------- */ if (*binspec) { if (*histfilename && !(*pixfilter) ) strcpy(outfile, histfilename); /* the original outfile name */ else strcpy(outfile, "mem://_3"); /* create histogram in memory */ /* if not already copied the file */ /* parse the binning specifier into individual parameters */ ffbins(binspec, &imagetype, &haxis, colname, minin, maxin, binsizein, minname, maxname, binname, &weight, wtcol, &recip, status); /* Create the histogram primary array and open it as the current fptr */ /* This will close the table that was used to create the histogram. */ ffhist2(fptr, outfile, imagetype, haxis, colname, minin, maxin, binsizein, minname, maxname, binname, weight, wtcol, recip, rowselect, status); if (rowselect) free(rowselect); if (*status > 0) { ffpmsg("on-the-fly histogramming of input table failed (ffopen)"); ffpmsg(" while trying to execute the following histogram specification:"); ffpmsg(binspec); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } /* write history records */ ffphis(*fptr, "CFITSIO used the following expression to create this histogram:", status); ffphis(*fptr, name, status); } if (*pixfilter) { if (*histfilename) strcpy(outfile, histfilename); /* the original outfile name */ else strcpy(outfile, "mem://_4"); /* create in memory */ /* if not already copied the file */ /* Ensure type of HDU is consistent with pixel filtering */ fits_get_hdu_type(*fptr, &hdutyp, status); /* get type of HDU */ if (hdutyp == IMAGE_HDU) { pixel_filter_helper(fptr, outfile, pixfilter, status); if (*status > 0) { ffpmsg("pixel filtering of input image failed (ffopen)"); ffpmsg(" while trying to execute the following:"); ffpmsg(pixfilter); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } /* write history records */ ffphis(*fptr, "CFITSIO used the following expression to create this image:", status); ffphis(*fptr, name, status); } else { ffpmsg("cannot use pixel filter on non-IMAGE HDU"); ffpmsg(pixfilter); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ *status = NOT_IMAGE; return(*status); } } /* parse and save image compression specification, if given */ if (*compspec) { ffparsecompspec(*fptr, compspec, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffreopen(fitsfile *openfptr, /* I - FITS file pointer to open file */ fitsfile **newfptr, /* O - pointer to new re opened file */ int *status) /* IO - error status */ /* Reopen an existing FITS file with either readonly or read/write access. The reopened file shares the same FITSfile structure but may point to a different HDU within the file. */ { if (*status > 0) return(*status); /* check that the open file pointer is valid */ if (!openfptr) return(*status = NULL_INPUT_PTR); else if ((openfptr->Fptr)->validcode != VALIDSTRUC) /* check magic value */ return(*status = BAD_FILEPTR); /* allocate fitsfile structure and initialize = 0 */ *newfptr = (fitsfile *) calloc(1, sizeof(fitsfile)); (*newfptr)->Fptr = openfptr->Fptr; /* both point to the same structure */ (*newfptr)->HDUposition = 0; /* set initial position to primary array */ (((*newfptr)->Fptr)->open_count)++; /* increment the file usage counter */ return(*status); } /*--------------------------------------------------------------------------*/ int fits_store_Fptr(FITSfile *Fptr, /* O - FITS file pointer */ int *status) /* IO - error status */ /* store the new Fptr address for future use by fits_already_open */ { int ii; if (*status > 0) return(*status); FFLOCK; for (ii = 0; ii < NMAXFILES; ii++) { if (FptrTable[ii] == 0) { FptrTable[ii] = Fptr; break; } } FFUNLOCK; return(*status); } /*--------------------------------------------------------------------------*/ int fits_clear_Fptr(FITSfile *Fptr, /* O - FITS file pointer */ int *status) /* IO - error status */ /* clear the Fptr address from the Fptr Table */ { int ii; FFLOCK; for (ii = 0; ii < NMAXFILES; ii++) { if (FptrTable[ii] == Fptr) { FptrTable[ii] = 0; break; } } FFUNLOCK; return(*status); } /*--------------------------------------------------------------------------*/ int fits_already_open(fitsfile **fptr, /* I/O - FITS file pointer */ char *url, char *urltype, char *infile, char *extspec, char *rowfilter, char *binspec, char *colspec, int mode, /* I - 0 = open readonly; 1 = read/write */ int noextsyn, /* I - 0 = ext syntax may be used; 1 = ext syntax disabled */ int *isopen, /* O - 1 = file is already open */ int *status) /* IO - error status */ /* Check if the file to be opened is already open. If so, then attach to it. */ /* the input strings must not exceed the standard lengths */ /* of FLEN_FILENAME, MAX_PREFIX_LEN, etc. */ /* this function was changed so that for files of access method FILE:// the file paths are compared using standard URL syntax and absolute paths (as opposed to relative paths). This eliminates some instances where a file is already opened but it is not realized because it was opened with another file path. For instance, if the CWD is /a/b/c and I open /a/b/c/foo.fits then open ./foo.fits the previous version of this function would not have reconized that the two files were the same. This version does recognize that the two files are the same. */ { FITSfile *oldFptr; int ii, iMatch=-1; char oldurltype[MAX_PREFIX_LEN], oldinfile[FLEN_FILENAME]; char oldextspec[FLEN_FILENAME], oldoutfile[FLEN_FILENAME]; char oldrowfilter[FLEN_FILENAME]; char oldbinspec[FLEN_FILENAME], oldcolspec[FLEN_FILENAME]; char cwd[FLEN_FILENAME]; char tmpStr[FLEN_FILENAME]; char tmpinfile[FLEN_FILENAME]; *isopen = 0; /* When opening a file with readonly access then we simply let the operating system open the file again, instead of using the CFITSIO trick of attaching to the previously opened file. This is required if CFITSIO is running in a multi-threaded environment, because 2 different threads cannot share the same FITSfile pointer. If the file is opened/reopened with write access, then the file MUST only be physically opened once.. */ if (mode == 0) return(*status); strcpy(tmpinfile, infile); if(fits_strcasecmp(urltype,"FILE://") == 0) { if (standardize_path(tmpinfile, status)) return(*status); } for (ii = 0; ii < NMAXFILES; ii++) /* check every buffer */ { if (FptrTable[ii] != 0) { oldFptr = FptrTable[ii]; if (oldFptr->noextsyntax) { /* old urltype must be "file://" */ if (fits_strcasecmp(urltype,"FILE://") == 0) { /* compare tmpinfile to adjusted oldFptr->filename */ /* This shouldn't be possible, but check anyway */ if (strlen(oldFptr->filename) > FLEN_FILENAME-1) { ffpmsg("Name of old file is too long. (fits_already_open)"); return (*status = FILE_NOT_OPENED); } strcpy(oldinfile, oldFptr->filename); if (standardize_path(oldinfile, status)) return(*status); if (!strcmp(tmpinfile, oldinfile)) { /* if infile is not noextsyn, must check that it is not using filters of any kind */ if (noextsyn || (!rowfilter[0] && !binspec[0] && !colspec[0])) { if (mode == READWRITE && oldFptr->writemode == READONLY) { /* cannot assume that a file previously opened with READONLY can now be written to (e.g., files on CDROM, or over the the network, or STDIN), so return with an error. */ ffpmsg( "cannot reopen file READWRITE when previously opened READONLY"); ffpmsg(url); return(*status = FILE_NOT_OPENED); } iMatch = ii; } } } } /* end if old file has disabled extended syntax */ else { fits_parse_input_url(oldFptr->filename, oldurltype, oldinfile, oldoutfile, oldextspec, oldrowfilter, oldbinspec, oldcolspec, status); if (*status > 0) { ffpmsg("could not parse the previously opened filename: (ffopen)"); ffpmsg(oldFptr->filename); return(*status); } if(fits_strcasecmp(oldurltype,"FILE://") == 0) { if (standardize_path(oldinfile, status)) return(*status); } if (!strcmp(urltype, oldurltype) && !strcmp(tmpinfile, oldinfile) ) { /* identical type of file and root file name */ if ( (!rowfilter[0] && !oldrowfilter[0] && !binspec[0] && !oldbinspec[0] && !colspec[0] && !oldcolspec[0]) /* no filtering or binning specs for either file, so */ /* this is a case where the same file is being reopened. */ /* It doesn't matter if the extensions are different */ || /* or */ (!strcmp(rowfilter, oldrowfilter) && !strcmp(binspec, oldbinspec) && !strcmp(colspec, oldcolspec) && !strcmp(extspec, oldextspec) ) ) /* filtering specs are given and are identical, and */ /* the same extension is specified */ { if (mode == READWRITE && oldFptr->writemode == READONLY) { /* cannot assume that a file previously opened with READONLY can now be written to (e.g., files on CDROM, or over the the network, or STDIN), so return with an error. */ ffpmsg( "cannot reopen file READWRITE when previously opened READONLY"); ffpmsg(url); return(*status = FILE_NOT_OPENED); } iMatch = ii; } } } /* end if old file recognizes extended syntax */ } /* end if old fptr exists */ } /* end loop over NMAXFILES */ if (iMatch >= 0) { oldFptr = FptrTable[iMatch]; *fptr = (fitsfile *) calloc(1, sizeof(fitsfile)); if (!(*fptr)) { ffpmsg( "failed to allocate structure for following file: (ffopen)"); ffpmsg(url); return(*status = MEMORY_ALLOCATION); } (*fptr)->Fptr = oldFptr; /* point to the structure */ (*fptr)->HDUposition = 0; /* set initial position */ (((*fptr)->Fptr)->open_count)++; /* increment usage counter */ if (binspec[0]) /* if binning specified, don't move */ extspec[0] = '\0'; /* all the filtering has already been applied, so ignore */ rowfilter[0] = '\0'; binspec[0] = '\0'; colspec[0] = '\0'; *isopen = 1; } return(*status); } /*--------------------------------------------------------------------------*/ int standardize_path(char *fullpath, int* status) { /* Utility function for common operation in fits_already_open fullpath: I/O string to be standardized. Assume len = FLEN_FILENAME */ char tmpPath[FLEN_FILENAME]; char cwd [FLEN_FILENAME]; if (fits_path2url(fullpath, FLEN_FILENAME, tmpPath, status)) return(*status); if (tmpPath[0] != '/') { fits_get_cwd(cwd,status); if (strlen(cwd) + strlen(tmpPath) + 1 > FLEN_FILENAME-1) { ffpmsg("Tile name is too long. (standardize_path)"); return(*status = FILE_NOT_OPENED); } strcat(cwd,"/"); strcat(cwd,tmpPath); fits_clean_url(cwd,tmpPath,status); } strcpy(fullpath, tmpPath); return (*status); } /*--------------------------------------------------------------------------*/ int fits_is_this_a_copy(char *urltype) /* I - type of file */ /* specialized routine that returns 1 if the file is known to be a temporary copy of the originally opened file. Otherwise it returns 0. */ { int iscopy; if (!strncmp(urltype, "mem", 3) ) iscopy = 1; /* file copy is in memory */ else if (!strncmp(urltype, "compress", 8) ) iscopy = 1; /* compressed diskfile that is uncompressed in memory */ else if (!strncmp(urltype, "http", 4) ) iscopy = 1; /* copied file using http protocol */ else if (!strncmp(urltype, "ftp", 3) ) iscopy = 1; /* copied file using ftp protocol */ else if (!strncmp(urltype, "gsiftp", 6) ) iscopy = 1; /* copied file using gsiftp protocol */ else if (!strncpy(urltype, "stdin", 5) ) iscopy = 1; /* piped stdin has been copied to memory */ else iscopy = 0; /* file is not known to be a copy */ return(iscopy); } /*--------------------------------------------------------------------------*/ static int find_quote(char **string) /* look for the closing single quote character in the input string */ { char *tstr; tstr = *string; while (*tstr) { if (*tstr == '\'') { /* found the closing quote */ *string = tstr + 1; /* set pointer to next char */ return(0); } else { /* skip over any other character */ tstr++; } } return(1); /* opps, didn't find the closing character */ } /*--------------------------------------------------------------------------*/ static int find_doublequote(char **string) /* look for the closing double quote character in the input string */ { char *tstr; tstr = *string; while (*tstr) { if (*tstr == '"') { /* found the closing quote */ *string = tstr + 1; /* set pointer to next char */ return(0); } else { /* skip over any other character */ tstr++; } } return(1); /* opps, didn't find the closing character */ } /*--------------------------------------------------------------------------*/ static int find_paren(char **string) /* look for the closing parenthesis character in the input string */ { char *tstr; tstr = *string; while (*tstr) { if (*tstr == ')') { /* found the closing parens */ *string = tstr + 1; /* set pointer to next char */ return(0); } else if (*tstr == '(') { /* found another level of parens */ tstr++; if (find_paren(&tstr)) return(1); } else if (*tstr == '[') { tstr++; if (find_bracket(&tstr)) return(1); } else if (*tstr == '{') { tstr++; if (find_curlybracket(&tstr)) return(1); } else if (*tstr == '"') { tstr++; if (find_doublequote(&tstr)) return(1); } else if (*tstr == '\'') { tstr++; if (find_quote(&tstr)) return(1); } else { tstr++; } } return(1); /* opps, didn't find the closing character */ } /*--------------------------------------------------------------------------*/ static int find_bracket(char **string) /* look for the closing bracket character in the input string */ { char *tstr; tstr = *string; while (*tstr) { if (*tstr == ']') { /* found the closing bracket */ *string = tstr + 1; /* set pointer to next char */ return(0); } else if (*tstr == '(') { /* found another level of parens */ tstr++; if (find_paren(&tstr)) return(1); } else if (*tstr == '[') { tstr++; if (find_bracket(&tstr)) return(1); } else if (*tstr == '{') { tstr++; if (find_curlybracket(&tstr)) return(1); } else if (*tstr == '"') { tstr++; if (find_doublequote(&tstr)) return(1); } else if (*tstr == '\'') { tstr++; if (find_quote(&tstr)) return(1); } else { tstr++; } } return(1); /* opps, didn't find the closing character */ } /*--------------------------------------------------------------------------*/ static int find_curlybracket(char **string) /* look for the closing curly bracket character in the input string */ { char *tstr; tstr = *string; while (*tstr) { if (*tstr == '}') { /* found the closing curly bracket */ *string = tstr + 1; /* set pointer to next char */ return(0); } else if (*tstr == '(') { /* found another level of parens */ tstr++; if (find_paren(&tstr)) return(1); } else if (*tstr == '[') { tstr++; if (find_bracket(&tstr)) return(1); } else if (*tstr == '{') { tstr++; if (find_curlybracket(&tstr)) return(1); } else if (*tstr == '"') { tstr++; if (find_doublequote(&tstr)) return(1); } else if (*tstr == '\'') { tstr++; if (find_quote(&tstr)) return(1); } else { tstr++; } } return(1); /* opps, didn't find the closing character */ } /*--------------------------------------------------------------------------*/ int comma2semicolon(char *string) /* replace commas with semicolons, unless the comma is within a quoted or bracketed expression */ { char *tstr; tstr = string; while (*tstr) { if (*tstr == ',') { /* found a comma */ *tstr = ';'; tstr++; } else if (*tstr == '(') { /* found another level of parens */ tstr++; if (find_paren(&tstr)) return(1); } else if (*tstr == '[') { tstr++; if (find_bracket(&tstr)) return(1); } else if (*tstr == '{') { tstr++; if (find_curlybracket(&tstr)) return(1); } else if (*tstr == '"') { tstr++; if (find_doublequote(&tstr)) return(1); } else if (*tstr == '\'') { tstr++; if (find_quote(&tstr)) return(1); } else { tstr++; } } return(0); /* reached end of string */ } /*--------------------------------------------------------------------------*/ int ffedit_columns( fitsfile **fptr, /* IO - pointer to input table; on output it */ /* points to the new selected rows table */ char *outfile, /* I - name for output file */ char *expr, /* I - column edit expression */ int *status) /* modify columns in a table and/or header keywords in the HDU */ { fitsfile *newptr; int ii, hdunum, slen, colnum = -1, testnum, deletecol = 0, savecol = 0; int numcols = 0, *colindex = 0, tstatus = 0; char *tstbuff=0, *cptr, *cptr2, *cptr3, *clause = NULL, keyname[FLEN_KEYWORD]; char colname[FLEN_VALUE], oldname[FLEN_VALUE], colformat[FLEN_VALUE]; char *file_expr = NULL, testname[FLEN_VALUE], card[FLEN_CARD]; if (*outfile) { /* create new empty file in to hold the selected rows */ if (ffinit(&newptr, outfile, status) > 0) { ffpmsg("failed to create file for copy (ffedit_columns)"); return(*status); } fits_get_hdu_num(*fptr, &hdunum); /* current HDU number in input file */ /* copy all HDUs to the output copy, if the 'only_one' flag is not set */ if (!((*fptr)->Fptr)->only_one) { for (ii = 1; 1; ii++) { if (fits_movabs_hdu(*fptr, ii, NULL, status) > 0) break; fits_copy_hdu(*fptr, newptr, 0, status); } if (*status == END_OF_FILE) { *status = 0; /* got the expected EOF error; reset = 0 */ } else if (*status > 0) { ffclos(newptr, status); ffpmsg("failed to copy all HDUs from input file (ffedit_columns)"); return(*status); } } else { /* only copy the primary array and the designated table extension */ fits_movabs_hdu(*fptr, 1, NULL, status); fits_copy_hdu(*fptr, newptr, 0, status); fits_movabs_hdu(*fptr, hdunum, NULL, status); fits_copy_hdu(*fptr, newptr, 0, status); if (*status > 0) { ffclos(newptr, status); ffpmsg("failed to copy all HDUs from input file (ffedit_columns)"); return(*status); } hdunum = 2; } /* close the original file and return ptr to the new image */ ffclos(*fptr, status); *fptr = newptr; /* reset the pointer to the new table */ /* move back to the selected table HDU */ if (fits_movabs_hdu(*fptr, hdunum, NULL, status) > 0) { ffpmsg("failed to copy the input file (ffedit_columns)"); return(*status); } } /* remove the "col " from the beginning of the column edit expression */ cptr = expr + 4; while (*cptr == ' ') cptr++; /* skip leading white space */ /* Check if need to import expression from a file */ if( *cptr=='@' ) { if( ffimport_file( cptr+1, &file_expr, status ) ) return(*status); cptr = file_expr; while (*cptr == ' ') cptr++; /* skip leading white space... again */ } tstatus = 0; ffgncl(*fptr, &numcols, &tstatus); /* get initial # of cols */ /* as of July 2012, the CFITSIO column filter syntax was modified */ /* so that commas may be used to separate clauses, as well as semi-colons. */ /* This was done because users cannot enter the semi-colon in the HEASARC's */ /* Hera on-line data processing system for computer security reasons. */ /* Therefore, we must convert those commas back to semi-colons here, but we */ /* must not convert any columns that occur within parenthesies. */ if (comma2semicolon(cptr)) { ffpmsg("parsing error in column filter expression"); ffpmsg(cptr); if( file_expr ) free( file_expr ); *status = PARSE_SYNTAX_ERR; return(*status); } /* parse expression and get first clause, if more than 1 */ while ((slen = fits_get_token2(&cptr, ";", &clause, NULL, status)) > 0 ) { if( *cptr==';' ) cptr++; clause[slen] = '\0'; if (clause[0] == '!' || clause[0] == '-') { char *clause1 = clause+1; int clen = clause1[0] ? strlen(clause1) : 0; /* ===================================== */ /* Case I. delete this column or keyword */ /* ===================================== */ /* Case Ia. delete column names with 0-or-more wildcard -COLNAME+ - delete repeated columns with exact name -COLNAM*+ - delete columns matching patterns */ if (*status == 0 && clen > 1 && clause1[0] != '#' && clause1[clen-1] == '+') { clause1[clen-1] = 0; clen--; /* Note that this is a delete 0 or more specification, which means that no matching columns is not an error. */ do { int status_del = 0; /* Have to set status=0 so we can reset the search at start column. Because we are deleting columns on the fly here, we have to reset the search every time. The only penalty here is execution time because leaving *status == COL_NOT_UNIQUE is merely an optimization for tables assuming the tables do not change from one call to the next. (an assumption broken in this loop) */ *status = 0; ffgcno(*fptr, CASEINSEN, clause1, &colnum, status); /* ffgcno returns COL_NOT_UNIQUE if there are multiple columns, and COL_NOT_FOUND after the last column is found, and COL_NOT_FOUND if no matches were found */ if (*status != 0 && *status != COL_NOT_UNIQUE) break; if (ffdcol(*fptr, colnum, &status_del) > 0) { ffpmsg("failed to delete column in input file:"); ffpmsg(clause); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); if( clause ) free(clause); return (*status = status_del); } deletecol = 1; /* set flag that at least one col was deleted */ numcols--; } while (*status == COL_NOT_UNIQUE); *status = 0; /* No matches are still successful */ colnum = -1; /* Ignore the column we found */ /* Case Ib. delete column names with wildcard or not -COLNAME - deleted exact column -COLNAM* - delete first column that matches pattern Note no leading '#' */ } else if (clause1[0] && clause1[0] != '#' && ((ffgcno(*fptr, CASEINSEN, clause1, &colnum, status) <= 0) || *status == COL_NOT_UNIQUE)) { /* a column with this name exists, so try to delete it */ *status = 0; /* Clear potential status=COL_NOT_UNIQUE */ if (ffdcol(*fptr, colnum, status) > 0) { ffpmsg("failed to delete column in input file:"); ffpmsg(clause); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); if( clause ) free(clause); return(*status); } deletecol = 1; /* set flag that at least one col was deleted */ numcols--; colnum = -1; } /* Case Ic. delete keyword(s) -KEYNAME,#KEYNAME - delete exact keyword (first match) -KEYNAM*,#KEYNAM* - delete first matching keyword -KEYNAME+,-#KEYNAME+ - delete 0-or-more exact matches of exact keyword -KEYNAM*+,-#KEYNAM*+ - delete 0-or-more wildcard matches Note the preceding # is optional if no conflicting column name exists and that wildcard patterns are described in "colfilter" section of documentation. */ else { int delall = 0; int haswild = 0; ffcmsg(); /* clear previous error message from ffgcno */ /* try deleting a keyword with this name */ *status = 0; /* skip past leading '#' if any */ if (clause1[0] == '#') clause1++; clen = strlen(clause1); /* Repeat deletion of keyword if requested with trailing '+' */ if (clen > 1 && clause1[clen-1] == '+') { delall = 1; clause1[clen-1] = 0; } /* Determine if this pattern has wildcards */ if (strchr(clause1,'?') || strchr(clause1,'*') || strchr(clause1,'#')) { haswild = 1; } if (haswild) { /* ffdkey() behaves differently if the pattern has a wildcard: it only checks from the "current" header position to the end, and doesn't check before the "current" header position. Therefore, for the case of wildcards we will have to reset to the beginning. */ ffmaky(*fptr, 1, status); /* reset pointer to beginning of header */ } /* Single or repeated deletions until done */ do { if (ffdkey(*fptr, clause1, status) > 0) { if (delall && *status == KEY_NO_EXIST) { /* Found last wildcard item. Stop deleting */ ffcmsg(); *status = 0; delall = 0; /* Force end of this loop */ } else { /* This was not a wildcard deletion, or it resulted in another kind of error */ ffpmsg("column or keyword to be deleted does not exist:"); ffpmsg(clause1); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); if( clause ) free(clause); return(*status); } } } while(delall); /* end do{} */ } } else { /* ===================================================== */ /* Case II: this is either a column name, (case 1) or a new column name followed by double = ("==") followed by the old name which is to be renamed. (case 2A) or a column or keyword name followed by a single "=" and a calculation expression (case 2B) */ /* ===================================================== */ cptr2 = clause; slen = fits_get_token2(&cptr2, "( =", &tstbuff, NULL, status); if (slen == 0 || *status) { ffpmsg("error: column or keyword name is blank (ffedit_columns):"); ffpmsg(clause); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); if (clause) free(clause); if (*status==0) *status=URL_PARSE_ERROR; return(*status); } if (strlen(tstbuff) > FLEN_VALUE-1) { ffpmsg("error: column or keyword name is too long (ffedit_columns):"); ffpmsg(clause); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); if (clause) free(clause); free(tstbuff); return(*status= URL_PARSE_ERROR); } strcpy(colname, tstbuff); free(tstbuff); tstbuff=0; /* If this is a keyword of the form #KEYWORD# then transform to the form #KEYWORDn where n is the previously used column number */ if (colname[0] == '#' && strstr(colname+1, "#") == (colname + strlen(colname) - 1)) { if (colnum <= 0) { ffpmsg("The keyword name:"); ffpmsg(colname); ffpmsg("is invalid unless a column has been previously"); ffpmsg("created or editted by a calculator command"); if( file_expr ) free( file_expr ); if (clause) free(clause); return(*status = URL_PARSE_ERROR); } colname[strlen(colname)-1] = '\0'; /* Make keyword name and put it in oldname */ ffkeyn(colname+1, colnum, oldname, status); if (*status) return (*status); /* Re-copy back into colname */ strcpy(colname+1,oldname); } else if (strstr(colname, "#") == (colname + strlen(colname) - 1)) { /* colname is of the form "NAME#"; if a) colnum is defined, and b) a column with literal name "NAME#" does not exist, and c) a keyword with name "NAMEn" (where n=colnum) exists, then transfrom the colname string to "NAMEn", otherwise do nothing. */ if (colnum > 0) { /* colnum must be defined */ tstatus = 0; ffgcno(*fptr, CASEINSEN, colname, &testnum, &tstatus); if (tstatus != 0 && tstatus != COL_NOT_UNIQUE) { /* OK, column doesn't exist, now see if keyword exists */ ffcmsg(); /* clear previous error message from ffgcno */ strcpy(testname, colname); testname[strlen(testname)-1] = '\0'; /* Make keyword name and put it in oldname */ ffkeyn(testname, colnum, oldname, status); if (*status) { if( file_expr ) free( file_expr ); if (clause) free(clause); return (*status); } tstatus = 0; if (!fits_read_card(*fptr, oldname, card, &tstatus)) { /* Keyword does exist; copy real name back into colname */ strcpy(colname,oldname); } } } } /* if we encountered an opening parenthesis, then we need to */ /* find the closing parenthesis, and concatinate the 2 strings */ /* This supports expressions like: [col #EXTNAME(Extension name)="GTI"] */ if (*cptr2 == '(') { if (fits_get_token2(&cptr2, ")", &tstbuff, NULL, status)==0) { strcat(colname,")"); } else { if ((strlen(tstbuff) + strlen(colname) + 1) > FLEN_VALUE-1) { ffpmsg("error: column name is too long (ffedit_columns):"); if( file_expr ) free( file_expr ); if (clause) free(clause); free(tstbuff); *status=URL_PARSE_ERROR; return (*status); } strcat(colname, tstbuff); strcat(colname, ")"); free(tstbuff); tstbuff=0; } cptr2++; } while (*cptr2 == ' ') cptr2++; /* skip white space */ if (*cptr2 != '=') { /* ------------------------------------ */ /* case 1 - simply the name of a column */ /* ------------------------------------ */ /* look for matching column */ ffgcno(*fptr, CASEINSEN, colname, &testnum, status); while (*status == COL_NOT_UNIQUE) { /* the column name contained wild cards, and it */ /* matches more than one column in the table. */ colnum = testnum; /* keep this column in the output file */ savecol = 1; if (!colindex) colindex = (int *) calloc(999, sizeof(int)); colindex[colnum - 1] = 1; /* flag this column number */ /* look for other matching column names */ ffgcno(*fptr, CASEINSEN, colname, &testnum, status); if (*status == COL_NOT_FOUND) *status = 999; /* temporary status flag value */ } if (*status <= 0) { colnum = testnum; /* keep this column in the output file */ savecol = 1; if (!colindex) colindex = (int *) calloc(999, sizeof(int)); colindex[colnum - 1] = 1; /* flag this column number */ } else if (*status == 999) { /* this special flag value does not represent an error */ *status = 0; } else { ffpmsg("Syntax error in columns specifier in input URL:"); ffpmsg(cptr2); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); if (clause) free(clause); return(*status = URL_PARSE_ERROR); } } else { /* ----------------------------------------------- */ /* case 2 where the token ends with an equals sign */ /* ----------------------------------------------- */ cptr2++; /* skip over the first '=' */ if (*cptr2 == '=') { /*................................................. */ /* Case A: rename a column or keyword; syntax is "new_name == old_name" */ /*................................................. */ cptr2++; /* skip the 2nd '=' */ while (*cptr2 == ' ') cptr2++; /* skip white space */ if (fits_get_token2(&cptr2, " ", &tstbuff, NULL, status)==0) { oldname[0]=0; } else { if (strlen(tstbuff) > FLEN_VALUE-1) { ffpmsg("error: column name syntax is too long (ffedit_columns):"); if( file_expr ) free( file_expr ); if (clause) free(clause); free(tstbuff); *status=URL_PARSE_ERROR; return (*status); } strcpy(oldname, tstbuff); free(tstbuff); tstbuff=0; } /* get column number of the existing column */ if (ffgcno(*fptr, CASEINSEN, oldname, &colnum, status) <= 0) { /* modify the TTYPEn keyword value with the new name */ ffkeyn("TTYPE", colnum, keyname, status); if (ffmkys(*fptr, keyname, colname, NULL, status) > 0) { ffpmsg("failed to rename column in input file"); ffpmsg(" oldname ="); ffpmsg(oldname); ffpmsg(" newname ="); ffpmsg(colname); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); if (clause) free(clause); return(*status); } /* keep this column in the output file */ savecol = 1; if (!colindex) colindex = (int *) calloc(999, sizeof(int)); colindex[colnum - 1] = 1; /* flag this column number */ } else { /* try renaming a keyword */ ffcmsg(); /* clear error message stack */ *status = 0; if (ffmnam(*fptr, oldname, colname, status) > 0) { ffpmsg("column or keyword to be renamed does not exist:"); ffpmsg(clause); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); if (clause) free(clause); return(*status); } } } else { /*...................................................... */ /* Case B: */ /* this must be a general column/keyword calc expression */ /* "name = expression" or "colname(TFORM) = expression" */ /*...................................................... */ /* parse the name and TFORM values, if present */ colformat[0] = '\0'; cptr3 = colname; if (fits_get_token2(&cptr3, "(", &tstbuff, NULL, status)==0) { oldname[0]=0; } else { if (strlen(tstbuff) > FLEN_VALUE-1) { ffpmsg("column expression is too long (ffedit_columns)"); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); if (clause) free(clause); free(tstbuff); *status=URL_PARSE_ERROR; return(*status); } strcpy(oldname, tstbuff); free(tstbuff); tstbuff=0; } if (cptr3[0] == '(' ) { cptr3++; /* skip the '(' */ if (fits_get_token2(&cptr3, ")", &tstbuff, NULL, status)==0) { colformat[0]=0; } else { if (strlen(tstbuff) > FLEN_VALUE-1) { ffpmsg("column expression is too long (ffedit_columns)"); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); if (clause) free(clause); free(tstbuff); *status=URL_PARSE_ERROR; return(*status); } strcpy(colformat, tstbuff); free(tstbuff); tstbuff=0; } } /* calculate values for the column or keyword */ /* cptr2 = the expression to be calculated */ /* oldname = name of the column or keyword */ /* colformat = column format, or keyword comment string */ if (fits_calculator(*fptr, cptr2, *fptr, oldname, colformat, status) > 0) { ffpmsg("Unable to calculate expression"); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); if (clause) free(clause); return(*status); } /* test if this is a column and not a keyword */ tstatus = 0; ffgcno(*fptr, CASEINSEN, oldname, &testnum, &tstatus); if (tstatus == 0) { /* keep this column in the output file */ colnum = testnum; savecol = 1; if (!colindex) colindex = (int *) calloc(999, sizeof(int)); colindex[colnum - 1] = 1; if (colnum > numcols)numcols++; } else { ffcmsg(); /* clear the error message stack */ } } } } if (clause) free(clause); /* free old clause before getting new one */ clause = NULL; } if (savecol && !deletecol) { /* need to delete all but the specified columns */ for (ii = numcols; ii > 0; ii--) { if (!colindex[ii-1]) /* delete this column */ { if (ffdcol(*fptr, ii, status) > 0) { ffpmsg("failed to delete column in input file:"); ffpmsg(clause); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); if (clause) free(clause); return(*status); } } } } if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); if (clause) free(clause); return(*status); } /*--------------------------------------------------------------------------*/ int fits_copy_cell2image( fitsfile *fptr, /* I - point to input table */ fitsfile *newptr, /* O - existing output file; new image HDU will be appended to it */ char *colname, /* I - column name / number containing the image*/ long rownum, /* I - number of the row containing the image */ int *status) /* IO - error status */ /* Copy a table cell of a given row and column into an image extension. The output file must already have been created. A new image extension will be created in that file. This routine was written by Craig Markwardt, GSFC */ { unsigned char buffer[30000]; int hdutype, colnum, typecode, bitpix, naxis, maxelem, tstatus; LONGLONG naxes[9], nbytes, firstbyte, ntodo; LONGLONG repeat, startpos, elemnum, rowlen, tnull; long twidth, incre; double scale, zero; char tform[20]; char card[FLEN_CARD]; char templt[FLEN_CARD] = ""; /* Table-to-image keyword translation table */ /* INPUT OUTPUT */ /* 01234567 01234567 */ char *patterns[][2] = {{"TSCALn", "BSCALE" }, /* Standard FITS keywords */ {"TZEROn", "BZERO" }, {"TUNITn", "BUNIT" }, {"TNULLn", "BLANK" }, {"TDMINn", "DATAMIN" }, {"TDMAXn", "DATAMAX" }, {"iCTYPn", "CTYPEi" }, /* Coordinate labels */ {"iCTYna", "CTYPEia" }, {"iCUNIn", "CUNITi" }, /* Coordinate units */ {"iCUNna", "CUNITia" }, {"iCRVLn", "CRVALi" }, /* WCS keywords */ {"iCRVna", "CRVALia" }, {"iCDLTn", "CDELTi" }, {"iCDEna", "CDELTia" }, {"iCRPXn", "CRPIXi" }, {"iCRPna", "CRPIXia" }, {"ijPCna", "PCi_ja" }, {"ijCDna", "CDi_ja" }, {"iVn_ma", "PVi_ma" }, {"iSn_ma", "PSi_ma" }, {"iCRDna", "CRDERia" }, {"iCSYna", "CSYERia" }, {"iCROTn", "CROTAi" }, {"WCAXna", "WCSAXESa"}, {"WCSNna", "WCSNAMEa"}, {"LONPna", "LONPOLEa"}, {"LATPna", "LATPOLEa"}, {"EQUIna", "EQUINOXa"}, {"MJDOBn", "MJD-OBS" }, {"MJDAn", "MJD-AVG" }, {"RADEna", "RADESYSa"}, {"iCNAna", "CNAMEia" }, {"DAVGn", "DATE-AVG"}, /* Delete table keywords related to other columns */ {"T????#a", "-" }, {"TC??#a", "-" }, {"TWCS#a", "-" }, {"TDIM#", "-" }, {"iCTYPm", "-" }, {"iCUNIm", "-" }, {"iCRVLm", "-" }, {"iCDLTm", "-" }, {"iCRPXm", "-" }, {"iCTYma", "-" }, {"iCUNma", "-" }, {"iCRVma", "-" }, {"iCDEma", "-" }, {"iCRPma", "-" }, {"ijPCma", "-" }, {"ijCDma", "-" }, {"iVm_ma", "-" }, {"iSm_ma", "-" }, {"iCRDma", "-" }, {"iCSYma", "-" }, {"iCROTm", "-" }, {"WCAXma", "-" }, {"WCSNma", "-" }, {"LONPma", "-" }, {"LATPma", "-" }, {"EQUIma", "-" }, {"MJDOBm", "-" }, {"MJDAm", "-" }, {"RADEma", "-" }, {"iCNAma", "-" }, {"DAVGm", "-" }, {"EXTNAME", "-" }, /* Remove structural keywords*/ {"EXTVER", "-" }, {"EXTLEVEL","-" }, {"CHECKSUM","-" }, {"DATASUM", "-" }, {"*", "+" }}; /* copy all other keywords */ int npat; if (*status > 0) return(*status); /* get column number */ if (ffgcno(fptr, CASEINSEN, colname, &colnum, status) > 0) { ffpmsg("column containing image in table cell does not exist:"); ffpmsg(colname); return(*status); } /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if ( ffgcprll(fptr, colnum, rownum, 1L, 1L, 0, &scale, &zero, tform, &twidth, &typecode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, (char *) buffer, status) > 0 ) return(*status); /* get the actual column name, in case a column number was given */ ffkeyn("", colnum, templt, &tstatus); ffgcnn(fptr, CASEINSEN, templt, colname, &colnum, &tstatus); if (hdutype != BINARY_TBL) { ffpmsg("This extension is not a binary table."); ffpmsg(" Cannot open the image in a binary table cell."); return(*status = NOT_BTABLE); } if (typecode < 0) { /* variable length array */ typecode *= -1; /* variable length arrays are 1-dimensional by default */ naxis = 1; naxes[0] = repeat; } else { /* get the dimensions of the image */ ffgtdmll(fptr, colnum, 9, &naxis, naxes, status); } if (*status > 0) { ffpmsg("Error getting the dimensions of the image"); return(*status); } /* determine BITPIX value for the image */ if (typecode == TBYTE) { bitpix = BYTE_IMG; nbytes = repeat; } else if (typecode == TSHORT) { bitpix = SHORT_IMG; nbytes = repeat * 2; } else if (typecode == TLONG) { bitpix = LONG_IMG; nbytes = repeat * 4; } else if (typecode == TFLOAT) { bitpix = FLOAT_IMG; nbytes = repeat * 4; } else if (typecode == TDOUBLE) { bitpix = DOUBLE_IMG; nbytes = repeat * 8; } else if (typecode == TLONGLONG) { bitpix = LONGLONG_IMG; nbytes = repeat * 8; } else if (typecode == TLOGICAL) { bitpix = BYTE_IMG; nbytes = repeat; } else { ffpmsg("Error: the following image column has invalid datatype:"); ffpmsg(colname); ffpmsg(tform); ffpmsg("Cannot open an image in a single row of this column."); return(*status = BAD_TFORM); } /* create new image in output file */ if (ffcrimll(newptr, bitpix, naxis, naxes, status) > 0) { ffpmsg("failed to write required primary array keywords in the output file"); return(*status); } npat = sizeof(patterns)/sizeof(patterns[0][0])/2; /* skip over the first 8 keywords, starting just after TFIELDS */ fits_translate_keywords(fptr, newptr, 9, patterns, npat, colnum, 0, 0, status); /* add some HISTORY */ snprintf(card,FLEN_CARD,"HISTORY This image was copied from row %ld of column '%s',", rownum, colname); /* disable this; leave it up to the caller to write history if needed. ffprec(newptr, card, status); */ /* the use of ffread routine, below, requires that any 'dirty' */ /* buffers in memory be flushed back to the file first */ ffflsh(fptr, FALSE, status); /* finally, copy the data, one buffer size at a time */ ffmbyt(fptr, startpos, TRUE, status); firstbyte = 1; /* the upper limit on the number of bytes must match the declaration */ /* read up to the first 30000 bytes in the normal way with ffgbyt */ ntodo = minvalue(30000, nbytes); ffgbyt(fptr, ntodo, buffer, status); ffptbb(newptr, 1, firstbyte, ntodo, buffer, status); nbytes -= ntodo; firstbyte += ntodo; /* read any additional bytes with low-level ffread routine, for speed */ while (nbytes && (*status <= 0) ) { ntodo = minvalue(30000, nbytes); ffread((fptr)->Fptr, (long) ntodo, buffer, status); ffptbb(newptr, 1, firstbyte, ntodo, buffer, status); nbytes -= ntodo; firstbyte += ntodo; } /* Re-scan the header so that CFITSIO knows about all the new keywords */ ffrdef(newptr,status); return(*status); } /*--------------------------------------------------------------------------*/ int fits_copy_image2cell( fitsfile *fptr, /* I - pointer to input image extension */ fitsfile *newptr, /* I - pointer to output table */ char *colname, /* I - name of column containing the image */ long rownum, /* I - number of the row containing the image */ int copykeyflag, /* I - controls which keywords to copy */ int *status) /* IO - error status */ /* Copy an image extension into a table cell at a given row and column. The table must have already been created. If the "colname" column exists, it will be used, otherwise a new column will be created in the table. The "copykeyflag" parameter controls which keywords to copy from the input image to the output table header (with any appropriate translation). copykeyflag = 0 -- no keywords will be copied copykeyflag = 1 -- essentially all keywords will be copied copykeyflag = 2 -- copy only the WCS related keywords This routine was written by Craig Markwardt, GSFC */ { tcolumn *colptr; unsigned char buffer[30000]; int ii, hdutype, colnum, typecode, bitpix, naxis, ncols, hdunum; char tformchar, tform[20], card[FLEN_CARD]; LONGLONG imgstart, naxes[9], nbytes, repeat, ntodo,firstbyte; char filename[FLEN_FILENAME+20]; int npat; int naxis1; LONGLONG naxes1[9] = {0,0,0,0,0,0,0,0,0}, repeat1, width1; int typecode1; unsigned char dummy = 0; LONGLONG headstart, datastart, dataend; /* Image-to-table keyword translation table */ /* INPUT OUTPUT */ /* 01234567 01234567 */ char *patterns[][2] = {{"BSCALE", "TSCALn" }, /* Standard FITS keywords */ {"BZERO", "TZEROn" }, {"BUNIT", "TUNITn" }, {"BLANK", "TNULLn" }, {"DATAMIN", "TDMINn" }, {"DATAMAX", "TDMAXn" }, {"CTYPEi", "iCTYPn" }, /* Coordinate labels */ {"CTYPEia", "iCTYna" }, {"CUNITi", "iCUNIn" }, /* Coordinate units */ {"CUNITia", "iCUNna" }, {"CRVALi", "iCRVLn" }, /* WCS keywords */ {"CRVALia", "iCRVna" }, {"CDELTi", "iCDLTn" }, {"CDELTia", "iCDEna" }, {"CRPIXj", "jCRPXn" }, {"CRPIXja", "jCRPna" }, {"PCi_ja", "ijPCna" }, {"CDi_ja", "ijCDna" }, {"PVi_ma", "iVn_ma" }, {"PSi_ma", "iSn_ma" }, {"WCSAXESa","WCAXna" }, {"WCSNAMEa","WCSNna" }, {"CRDERia", "iCRDna" }, {"CSYERia", "iCSYna" }, {"CROTAi", "iCROTn" }, {"LONPOLEa","LONPna"}, {"LATPOLEa","LATPna"}, {"EQUINOXa","EQUIna"}, {"MJD-OBS", "MJDOBn" }, {"MJD-AVG", "MJDAn" }, {"RADESYSa","RADEna"}, {"CNAMEia", "iCNAna" }, {"DATE-AVG","DAVGn"}, {"NAXISi", "-" }, /* Remove structural keywords*/ {"PCOUNT", "-" }, {"GCOUNT", "-" }, {"EXTEND", "-" }, {"EXTNAME", "-" }, {"EXTVER", "-" }, {"EXTLEVEL","-" }, {"CHECKSUM","-" }, {"DATASUM", "-" }, {"*", "+" }}; /* copy all other keywords */ if (*status > 0) return(*status); if (fptr == 0 || newptr == 0) return (*status = NULL_INPUT_PTR); if (ffghdt(fptr, &hdutype, status) > 0) { ffpmsg("could not get input HDU type"); return (*status); } if (hdutype != IMAGE_HDU) { ffpmsg("The input extension is not an image."); ffpmsg(" Cannot open the image."); return(*status = NOT_IMAGE); } if (ffghdt(newptr, &hdutype, status) > 0) { ffpmsg("could not get output HDU type"); return (*status); } if (hdutype != BINARY_TBL) { ffpmsg("The output extension is not a table."); return(*status = NOT_BTABLE); } if (ffgiprll(fptr, 9, &bitpix, &naxis, naxes, status) > 0) { ffpmsg("Could not read image parameters."); return (*status); } /* Determine total number of pixels in the image */ repeat = 1; for (ii = 0; ii < naxis; ii++) repeat *= naxes[ii]; /* Determine the TFORM value for the table cell */ if (bitpix == BYTE_IMG) { typecode = TBYTE; tformchar = 'B'; nbytes = repeat; } else if (bitpix == SHORT_IMG) { typecode = TSHORT; tformchar = 'I'; nbytes = repeat*2; } else if (bitpix == LONG_IMG) { typecode = TLONG; tformchar = 'J'; nbytes = repeat*4; } else if (bitpix == FLOAT_IMG) { typecode = TFLOAT; tformchar = 'E'; nbytes = repeat*4; } else if (bitpix == DOUBLE_IMG) { typecode = TDOUBLE; tformchar = 'D'; nbytes = repeat*8; } else if (bitpix == LONGLONG_IMG) { typecode = TLONGLONG; tformchar = 'K'; nbytes = repeat*8; } else { ffpmsg("Error: the image has an invalid datatype."); return (*status = BAD_BITPIX); } /* get column number */ ffpmrk(); ffgcno(newptr, CASEINSEN, colname, &colnum, status); ffcmrk(); /* Column does not exist; create it */ if (*status) { *status = 0; snprintf(tform, 20, "%.0f%c", (double) repeat, tformchar); ffgncl(newptr, &ncols, status); colnum = ncols+1; fficol(newptr, colnum, colname, tform, status); ffptdmll(newptr, colnum, naxis, naxes, status); if (*status) { ffpmsg("Could not insert new column into output table."); return *status; } } else { ffgtdmll(newptr, colnum, 9, &naxis1, naxes1, status); if (*status > 0 || naxis != naxis1) { ffpmsg("Input image dimensions and output table cell dimensions do not match."); return (*status = BAD_DIMEN); } for (ii=0; ii 0) || (typecode1 != typecode) || (repeat1 != repeat)) { ffpmsg("Input image data type does not match output table cell type."); return (*status = BAD_TFORM); } } /* copy keywords from input image to output table, if required */ if (copykeyflag) { npat = sizeof(patterns)/sizeof(patterns[0][0])/2; if (copykeyflag == 2) { /* copy only the WCS-related keywords */ patterns[npat-1][1] = "-"; } /* The 3rd parameter value = 5 means skip the first 4 keywords in the image */ fits_translate_keywords(fptr, newptr, 5, patterns, npat, colnum, 0, 0, status); } /* Here is all the code to compute offsets: * * byte offset from start of row to column (dest table) * * byte offset from start of file to image data (source image) */ /* Force the writing of the row of the table by writing the last byte of the array, which grows the table, and/or shifts following extensions */ ffpcl(newptr, TBYTE, colnum, rownum, repeat, 1, &dummy, status); /* byte offset within the row to the start of the image column */ colptr = (newptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ firstbyte = colptr->tbcol + 1; /* get starting address of input image to be read */ ffghadll(fptr, &headstart, &datastart, &dataend, status); imgstart = datastart; snprintf(card, FLEN_CARD, "HISTORY Table column '%s' row %ld copied from image", colname, rownum); /* Don't automatically write History keywords; leave this up to the caller. ffprec(newptr, card, status); */ /* write HISTORY keyword with the file name (this is now disabled)*/ filename[0] = '\0'; hdunum = 0; strcpy(filename, "HISTORY "); ffflnm(fptr, filename+strlen(filename), status); ffghdn(fptr, &hdunum); snprintf(filename+strlen(filename),FLEN_FILENAME+20-strlen(filename),"[%d]", hdunum-1); /* ffprec(newptr, filename, status); */ /* the use of ffread routine, below, requires that any 'dirty' */ /* buffers in memory be flushed back to the file first */ ffflsh(fptr, FALSE, status); /* move to the first byte of the input image */ ffmbyt(fptr, imgstart, TRUE, status); ntodo = minvalue(30000L, nbytes); ffgbyt(fptr, ntodo, buffer, status); /* read input image */ ffptbb(newptr, rownum, firstbyte, ntodo, buffer, status); /* write to table */ nbytes -= ntodo; firstbyte += ntodo; /* read any additional bytes with low-level ffread routine, for speed */ while (nbytes && (*status <= 0) ) { ntodo = minvalue(30000L, nbytes); ffread(fptr->Fptr, (long) ntodo, buffer, status); ffptbb(newptr, rownum, firstbyte, ntodo, buffer, status); nbytes -= ntodo; firstbyte += ntodo; } /* Re-scan the header so that CFITSIO knows about all the new keywords */ ffrdef(newptr,status); return(*status); } /*--------------------------------------------------------------------------*/ int fits_select_image_section( fitsfile **fptr, /* IO - pointer to input image; on output it */ /* points to the new subimage */ char *outfile, /* I - name for output file */ char *expr, /* I - Image section expression */ int *status) { /* copies an image section from the input file to a new output file. Any HDUs preceding or following the image are also copied to the output file. */ fitsfile *newptr; int ii, hdunum; /* create new empty file to hold the image section */ if (ffinit(&newptr, outfile, status) > 0) { ffpmsg( "failed to create output file for image section:"); ffpmsg(outfile); return(*status); } fits_get_hdu_num(*fptr, &hdunum); /* current HDU number in input file */ /* copy all preceding extensions to the output file, if 'only_one' flag not set */ if (!(((*fptr)->Fptr)->only_one)) { for (ii = 1; ii < hdunum; ii++) { fits_movabs_hdu(*fptr, ii, NULL, status); if (fits_copy_hdu(*fptr, newptr, 0, status) > 0) { ffclos(newptr, status); return(*status); } } /* move back to the original HDU position */ fits_movabs_hdu(*fptr, hdunum, NULL, status); } if (fits_copy_image_section(*fptr, newptr, expr, status) > 0) { ffclos(newptr, status); return(*status); } /* copy any remaining HDUs to the output file, if 'only_one' flag not set */ if (!(((*fptr)->Fptr)->only_one)) { for (ii = hdunum + 1; 1; ii++) { if (fits_movabs_hdu(*fptr, ii, NULL, status) > 0) break; fits_copy_hdu(*fptr, newptr, 0, status); } if (*status == END_OF_FILE) *status = 0; /* got the expected EOF error; reset = 0 */ else if (*status > 0) { ffclos(newptr, status); return(*status); } } else { ii = hdunum + 1; /* this value of ii is required below */ } /* close the original file and return ptr to the new image */ ffclos(*fptr, status); *fptr = newptr; /* reset the pointer to the new table */ /* move back to the image subsection */ if (ii - 1 != hdunum) fits_movabs_hdu(*fptr, hdunum, NULL, status); else { /* may have to reset BSCALE and BZERO pixel scaling, */ /* since the keywords were previously turned off */ if (ffrdef(*fptr, status) > 0) { ffclos(*fptr, status); return(*status); } } return(*status); } /*--------------------------------------------------------------------------*/ int fits_copy_image_section( fitsfile *fptr, /* I - pointer to input image */ fitsfile *newptr, /* I - pointer to output image */ char *expr, /* I - Image section expression */ int *status) { /* copies an image section from the input file to a new output HDU */ int bitpix, naxis, numkeys, nkey; long naxes[] = {1,1,1,1,1,1,1,1,1}, smin, smax, sinc; long fpixels[] = {1,1,1,1,1,1,1,1,1}; long lpixels[] = {1,1,1,1,1,1,1,1,1}; long incs[] = {1,1,1,1,1,1,1,1,1}; char *cptr, keyname[FLEN_KEYWORD], card[FLEN_CARD]; int ii, tstatus, anynull; long minrow, maxrow, minslice, maxslice, mincube, maxcube; long firstpix; long ncubeiter, nsliceiter, nrowiter, kiter, jiter, iiter; int klen, kk, jj; long outnaxes[9], outsize, buffsize; double *buffer, crpix, cdelt; if (*status > 0) return(*status); /* get the size of the input image */ fits_get_img_type(fptr, &bitpix, status); fits_get_img_dim(fptr, &naxis, status); if (fits_get_img_size(fptr, naxis, naxes, status) > 0) return(*status); if (naxis < 1 || naxis > 4) { ffpmsg( "Input image either had NAXIS = 0 (NULL image) or has > 4 dimensions"); return(*status = BAD_NAXIS); } /* create output image with same size and type as the input image */ /* Will update the size later */ fits_create_img(newptr, bitpix, naxis, naxes, status); /* copy all other non-structural keywords from the input to output file */ fits_get_hdrspace(fptr, &numkeys, NULL, status); for (nkey = 4; nkey <= numkeys; nkey++) /* skip the first few keywords */ { fits_read_record(fptr, nkey, card, status); if (fits_get_keyclass(card) > TYP_CMPRS_KEY) { /* write the record to the output file */ fits_write_record(newptr, card, status); } } if (*status > 0) { ffpmsg("error copying header from input image to output image"); return(*status); } /* parse the section specifier to get min, max, and inc for each axis */ /* and the size of each output image axis */ cptr = expr; for (ii=0; ii < naxis; ii++) { if (fits_get_section_range(&cptr, &smin, &smax, &sinc, status) > 0) { ffpmsg("error parsing the following image section specifier:"); ffpmsg(expr); return(*status); } if (smax == 0) smax = naxes[ii]; /* use whole axis by default */ else if (smin == 0) smin = naxes[ii]; /* use inverted whole axis */ if (smin > naxes[ii] || smax > naxes[ii]) { ffpmsg("image section exceeds dimensions of input image:"); ffpmsg(expr); return(*status = BAD_NAXIS); } fpixels[ii] = smin; lpixels[ii] = smax; incs[ii] = sinc; if (smin <= smax) outnaxes[ii] = (smax - smin + sinc) / sinc; else outnaxes[ii] = (smin - smax + sinc) / sinc; /* modify the NAXISn keyword */ fits_make_keyn("NAXIS", ii + 1, keyname, status); fits_modify_key_lng(newptr, keyname, outnaxes[ii], NULL, status); /* modify the WCS keywords if necessary */ if (fpixels[ii] != 1 || incs[ii] != 1) { for (kk=-1;kk<26; kk++) /* modify any alternate WCS keywords */ { /* read the CRPIXn keyword if it exists in the input file */ fits_make_keyn("CRPIX", ii + 1, keyname, status); if (kk != -1) { klen = strlen(keyname); keyname[klen]='A' + kk; keyname[klen + 1] = '\0'; } tstatus = 0; if (fits_read_key(fptr, TDOUBLE, keyname, &crpix, NULL, &tstatus) == 0) { /* calculate the new CRPIXn value */ if (fpixels[ii] <= lpixels[ii]) { crpix = (crpix - (fpixels[ii])) / incs[ii] + 1.0; /* crpix = (crpix - (fpixels[ii] - 1.0) - .5) / incs[ii] + 0.5; */ } else { crpix = (fpixels[ii] - crpix) / incs[ii] + 1.0; /* crpix = (fpixels[ii] - (crpix - 1.0) - .5) / incs[ii] + 0.5; */ } /* modify the value in the output file */ fits_modify_key_dbl(newptr, keyname, crpix, 15, NULL, status); if (incs[ii] != 1 || fpixels[ii] > lpixels[ii]) { /* read the CDELTn keyword if it exists in the input file */ fits_make_keyn("CDELT", ii + 1, keyname, status); if (kk != -1) { klen = strlen(keyname); keyname[klen]='A' + kk; keyname[klen + 1] = '\0'; } tstatus = 0; if (fits_read_key(fptr, TDOUBLE, keyname, &cdelt, NULL, &tstatus) == 0) { /* calculate the new CDELTn value */ if (fpixels[ii] <= lpixels[ii]) cdelt = cdelt * incs[ii]; else cdelt = cdelt * (-incs[ii]); /* modify the value in the output file */ fits_modify_key_dbl(newptr, keyname, cdelt, 15, NULL, status); } /* modify the CDi_j keywords if they exist in the input file */ fits_make_keyn("CD1_", ii + 1, keyname, status); if (kk != -1) { klen = strlen(keyname); keyname[klen]='A' + kk; keyname[klen + 1] = '\0'; } for (jj=0; jj < 9; jj++) /* look for up to 9 dimensions */ { keyname[2] = '1' + jj; tstatus = 0; if (fits_read_key(fptr, TDOUBLE, keyname, &cdelt, NULL, &tstatus) == 0) { /* calculate the new CDi_j value */ if (fpixels[ii] <= lpixels[ii]) cdelt = cdelt * incs[ii]; else cdelt = cdelt * (-incs[ii]); /* modify the value in the output file */ fits_modify_key_dbl(newptr, keyname, cdelt, 15, NULL, status); } } } /* end of if (incs[ii]... loop */ } /* end of fits_read_key loop */ } /* end of for (kk loop */ } } /* end of main NAXIS loop */ if (ffrdef(newptr, status) > 0) /* force the header to be scanned */ { return(*status); } /* turn off any scaling of the pixel values */ fits_set_bscale(fptr, 1.0, 0.0, status); fits_set_bscale(newptr, 1.0, 0.0, status); /* to reduce memory foot print, just read/write image 1 row at a time */ outsize = outnaxes[0]; buffsize = (abs(bitpix) / 8) * outsize; buffer = (double *) malloc(buffsize); /* allocate memory for the image row */ if (!buffer) { ffpmsg("fits_copy_image_section: no memory for image section"); return(*status = MEMORY_ALLOCATION); } /* read the image section then write it to the output file */ minrow = fpixels[1]; maxrow = lpixels[1]; if (minrow > maxrow) { nrowiter = (minrow - maxrow + incs[1]) / incs[1]; } else { nrowiter = (maxrow - minrow + incs[1]) / incs[1]; } minslice = fpixels[2]; maxslice = lpixels[2]; if (minslice > maxslice) { nsliceiter = (minslice - maxslice + incs[2]) / incs[2]; } else { nsliceiter = (maxslice - minslice + incs[2]) / incs[2]; } mincube = fpixels[3]; maxcube = lpixels[3]; if (mincube > maxcube) { ncubeiter = (mincube - maxcube + incs[3]) / incs[3]; } else { ncubeiter = (maxcube - mincube + incs[3]) / incs[3]; } firstpix = 1; for (kiter = 0; kiter < ncubeiter; kiter++) { if (mincube > maxcube) { fpixels[3] = mincube - (kiter * incs[3]); } else { fpixels[3] = mincube + (kiter * incs[3]); } lpixels[3] = fpixels[3]; for (jiter = 0; jiter < nsliceiter; jiter++) { if (minslice > maxslice) { fpixels[2] = minslice - (jiter * incs[2]); } else { fpixels[2] = minslice + (jiter * incs[2]); } lpixels[2] = fpixels[2]; for (iiter = 0; iiter < nrowiter; iiter++) { if (minrow > maxrow) { fpixels[1] = minrow - (iiter * incs[1]); } else { fpixels[1] = minrow + (iiter * incs[1]); } lpixels[1] = fpixels[1]; if (bitpix == 8) { ffgsvb(fptr, 1, naxis, naxes, fpixels, lpixels, incs, 0, (unsigned char *) buffer, &anynull, status); ffpprb(newptr, 1, firstpix, outsize, (unsigned char *) buffer, status); } else if (bitpix == 16) { ffgsvi(fptr, 1, naxis, naxes, fpixels, lpixels, incs, 0, (short *) buffer, &anynull, status); ffppri(newptr, 1, firstpix, outsize, (short *) buffer, status); } else if (bitpix == 32) { ffgsvk(fptr, 1, naxis, naxes, fpixels, lpixels, incs, 0, (int *) buffer, &anynull, status); ffpprk(newptr, 1, firstpix, outsize, (int *) buffer, status); } else if (bitpix == -32) { ffgsve(fptr, 1, naxis, naxes, fpixels, lpixels, incs, FLOATNULLVALUE, (float *) buffer, &anynull, status); ffppne(newptr, 1, firstpix, outsize, (float *) buffer, FLOATNULLVALUE, status); } else if (bitpix == -64) { ffgsvd(fptr, 1, naxis, naxes, fpixels, lpixels, incs, DOUBLENULLVALUE, buffer, &anynull, status); ffppnd(newptr, 1, firstpix, outsize, buffer, DOUBLENULLVALUE, status); } else if (bitpix == 64) { ffgsvjj(fptr, 1, naxis, naxes, fpixels, lpixels, incs, 0, (LONGLONG *) buffer, &anynull, status); ffpprjj(newptr, 1, firstpix, outsize, (LONGLONG *) buffer, status); } firstpix += outsize; } } } free(buffer); /* finished with the memory */ if (*status > 0) { ffpmsg("fits_copy_image_section: error copying image section"); return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int fits_get_section_range(char **ptr, long *secmin, long *secmax, long *incre, int *status) /* Parse the input image section specification string, returning the min, max and increment values. Typical string = "1:512:2" or "1:512" */ { int slen, isanumber; char token[FLEN_VALUE], *tstbuff=0; if (*status > 0) return(*status); slen = fits_get_token2(ptr, " ,:", &tstbuff, &isanumber, status); /* get 1st token */ if (slen==0) { /* support [:2,:2] type syntax, where the leading * is implied */ strcpy(token,"*"); } else { if (strlen(tstbuff) > FLEN_VALUE-1) { ffpmsg("Error: image section string too long (fits_get_section_range)"); free(tstbuff); *status = URL_PARSE_ERROR; return(*status); } strcpy(token, tstbuff); free(tstbuff); tstbuff=0; } if (*token == '*') /* wild card means to use the whole range */ { *secmin = 1; *secmax = 0; } else if (*token == '-' && *(token+1) == '*' ) /* invert the whole range */ { *secmin = 0; *secmax = 1; } else { if (slen == 0 || !isanumber || **ptr != ':') return(*status = URL_PARSE_ERROR); /* the token contains the min value */ *secmin = atol(token); (*ptr)++; /* skip the colon between the min and max values */ slen = fits_get_token2(ptr, " ,:", &tstbuff, &isanumber, status); /* get token */ if (slen == 0 || !isanumber) { if (tstbuff) free(tstbuff); return(*status = URL_PARSE_ERROR); } if (strlen(tstbuff) > FLEN_VALUE-1) { ffpmsg("Error: image section string too long (fits_get_section_range)"); free(tstbuff); *status = URL_PARSE_ERROR; return(*status); } strcpy(token, tstbuff); free(tstbuff); tstbuff=0; /* the token contains the max value */ *secmax = atol(token); } if (**ptr == ':') { (*ptr)++; /* skip the colon between the max and incre values */ slen = fits_get_token2(ptr, " ,", &tstbuff, &isanumber, status); /* get token */ if (slen == 0 || !isanumber) { if (tstbuff) free(tstbuff); return(*status = URL_PARSE_ERROR); } if (strlen(tstbuff) > FLEN_VALUE-1) { ffpmsg("Error: image section string too long (fits_get_section_range)"); free(tstbuff); *status = URL_PARSE_ERROR; return(*status); } strcpy(token, tstbuff); free(tstbuff); tstbuff=0; *incre = atol(token); } else *incre = 1; /* default increment if none is supplied */ if (**ptr == ',') (*ptr)++; while (**ptr == ' ') /* skip any trailing blanks */ (*ptr)++; if (*secmin < 0 || *secmax < 0 || *incre < 1) *status = URL_PARSE_ERROR; return(*status); } /*--------------------------------------------------------------------------*/ int ffselect_table( fitsfile **fptr, /* IO - pointer to input table; on output it */ /* points to the new selected rows table */ char *outfile, /* I - name for output file */ char *expr, /* I - Boolean expression */ int *status) { fitsfile *newptr; int ii, hdunum; if (*outfile) { /* create new empty file in to hold the selected rows */ if (ffinit(&newptr, outfile, status) > 0) { ffpmsg( "failed to create file for selected rows from input table"); ffpmsg(outfile); return(*status); } fits_get_hdu_num(*fptr, &hdunum); /* current HDU number in input file */ /* copy all preceding extensions to the output file, if the 'only_one' flag is not set */ if (!((*fptr)->Fptr)->only_one) { for (ii = 1; ii < hdunum; ii++) { fits_movabs_hdu(*fptr, ii, NULL, status); if (fits_copy_hdu(*fptr, newptr, 0, status) > 0) { ffclos(newptr, status); return(*status); } } } else { /* just copy the primary array */ fits_movabs_hdu(*fptr, 1, NULL, status); if (fits_copy_hdu(*fptr, newptr, 0, status) > 0) { ffclos(newptr, status); return(*status); } } fits_movabs_hdu(*fptr, hdunum, NULL, status); /* copy all the header keywords from the input to output file */ if (fits_copy_header(*fptr, newptr, status) > 0) { ffclos(newptr, status); return(*status); } /* set number of rows = 0 */ fits_modify_key_lng(newptr, "NAXIS2", 0, NULL,status); (newptr->Fptr)->numrows = 0; (newptr->Fptr)->origrows = 0; if (ffrdef(newptr, status) > 0) /* force the header to be scanned */ { ffclos(newptr, status); return(*status); } } else newptr = *fptr; /* will delete rows in place in the table */ /* copy rows which satisfy the selection expression to the output table */ /* or delete the nonqualifying rows if *fptr = newptr. */ if (fits_select_rows(*fptr, newptr, expr, status) > 0) { if (*outfile) ffclos(newptr, status); return(*status); } if (*outfile) { /* copy any remaining HDUs to the output copy */ if (!((*fptr)->Fptr)->only_one) { for (ii = hdunum + 1; 1; ii++) { if (fits_movabs_hdu(*fptr, ii, NULL, status) > 0) break; fits_copy_hdu(*fptr, newptr, 0, status); } if (*status == END_OF_FILE) *status = 0; /* got the expected EOF error; reset = 0 */ else if (*status > 0) { ffclos(newptr, status); return(*status); } } else { hdunum = 2; } /* close the original file and return ptr to the new image */ ffclos(*fptr, status); *fptr = newptr; /* reset the pointer to the new table */ /* move back to the selected table HDU */ fits_movabs_hdu(*fptr, hdunum, NULL, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffparsecompspec(fitsfile *fptr, /* I - FITS file pointer */ char *compspec, /* I - image compression specification */ int *status) /* IO - error status */ /* Parse the image compression specification that was give in square brackets following the output FITS file name, as in these examples: myfile.fits[compress] - default Rice compression, row by row myfile.fits[compress TYPE] - the first letter of TYPE defines the compression algorithm: R = Rice G = GZIP H = HCOMPRESS HS = HCOMPRESS (with smoothing) B - BZIP2 P = PLIO myfile.fits[compress TYPE 100,100] - the numbers give the dimensions of the compression tiles. Default is NAXIS1, 1, 1, ... other optional parameters may be specified following a semi-colon myfile.fits[compress; q 8.0] q specifies the floating point mufile.fits[compress TYPE; q -.0002] quantization level; myfile.fits[compress TYPE 100,100; q 10, s 25] s specifies the HCOMPRESS integer scaling parameter The compression parameters are saved in the fptr->Fptr structure for use when writing FITS images. */ { char *ptr1; /* initialize with default values */ int ii, compresstype = RICE_1, smooth = 0; int quantize_method = SUBTRACTIVE_DITHER_1; long tilesize[MAX_COMPRESS_DIM] = {0,0,0,0,0,0}; float qlevel = -99., scale = 0.; ptr1 = compspec; while (*ptr1 == ' ') /* ignore leading blanks */ ptr1++; if (strncmp(ptr1, "compress", 8) && strncmp(ptr1, "COMPRESS", 8) ) { /* apparently this string does not specify compression parameters */ return(*status = URL_PARSE_ERROR); } ptr1 += 8; while (*ptr1 == ' ') /* ignore leading blanks */ ptr1++; /* ========================= */ /* look for compression type */ /* ========================= */ if (*ptr1 == 'r' || *ptr1 == 'R') { compresstype = RICE_1; while (*ptr1 != ' ' && *ptr1 != ';' && *ptr1 != '\0') ptr1++; } else if (*ptr1 == 'g' || *ptr1 == 'G') { compresstype = GZIP_1; while (*ptr1 != ' ' && *ptr1 != ';' && *ptr1 != '\0') ptr1++; } /* else if (*ptr1 == 'b' || *ptr1 == 'B') { compresstype = BZIP2_1; while (*ptr1 != ' ' && *ptr1 != ';' && *ptr1 != '\0') ptr1++; } */ else if (*ptr1 == 'p' || *ptr1 == 'P') { compresstype = PLIO_1; while (*ptr1 != ' ' && *ptr1 != ';' && *ptr1 != '\0') ptr1++; } else if (*ptr1 == 'h' || *ptr1 == 'H') { compresstype = HCOMPRESS_1; ptr1++; if (*ptr1 == 's' || *ptr1 == 'S') smooth = 1; /* apply smoothing when uncompressing HCOMPRESSed image */ while (*ptr1 != ' ' && *ptr1 != ';' && *ptr1 != '\0') ptr1++; } /* ======================== */ /* look for tile dimensions */ /* ======================== */ while (*ptr1 == ' ') /* ignore leading blanks */ ptr1++; ii = 0; while (isdigit( (int) *ptr1) && ii < 9) { tilesize[ii] = atol(ptr1); /* read the integer value */ ii++; while (isdigit((int) *ptr1)) /* skip over the integer */ ptr1++; if (*ptr1 == ',') ptr1++; /* skip over the comma */ while (*ptr1 == ' ') /* ignore leading blanks */ ptr1++; } /* ========================================================= */ /* look for semi-colon, followed by other optional parameters */ /* ========================================================= */ if (*ptr1 == ';') { ptr1++; while (*ptr1 == ' ') /* ignore leading blanks */ ptr1++; while (*ptr1 != 0) { /* haven't reached end of string yet */ if (*ptr1 == 's' || *ptr1 == 'S') { /* this should be the HCOMPRESS "scale" parameter; default = 1 */ ptr1++; while (*ptr1 == ' ') /* ignore leading blanks */ ptr1++; scale = (float) strtod(ptr1, &ptr1); while (*ptr1 == ' ' || *ptr1 == ',') /* skip over blanks or comma */ ptr1++; } else if (*ptr1 == 'q' || *ptr1 == 'Q') { /* this should be the floating point quantization parameter */ ptr1++; if (*ptr1 == 'z' || *ptr1 == 'Z') { /* use the subtractive_dither_2 option */ quantize_method = SUBTRACTIVE_DITHER_2; ptr1++; } else if (*ptr1 == '0') { /* do not dither */ quantize_method = NO_DITHER; ptr1++; } while (*ptr1 == ' ') /* ignore leading blanks */ ptr1++; qlevel = (float) strtod(ptr1, &ptr1); while (*ptr1 == ' ' || *ptr1 == ',') /* skip over blanks or comma */ ptr1++; } else { return(*status = URL_PARSE_ERROR); } } } /* ================================= */ /* finished parsing; save the values */ /* ================================= */ fits_set_compression_type(fptr, compresstype, status); fits_set_tile_dim(fptr, MAX_COMPRESS_DIM, tilesize, status); if (compresstype == HCOMPRESS_1) { fits_set_hcomp_scale (fptr, scale, status); fits_set_hcomp_smooth(fptr, smooth, status); } if (qlevel != -99.) { fits_set_quantize_level(fptr, qlevel, status); fits_set_quantize_method(fptr, quantize_method, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffdkinit(fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - name of file to create */ int *status) /* IO - error status */ /* Create and initialize a new FITS file on disk. This routine differs from ffinit in that the input 'name' is literally taken as the name of the disk file to be created, and it does not support CFITSIO's extended filename syntax. */ { *fptr = 0; /* initialize null file pointer, */ /* regardless of the value of *status */ if (*status > 0) return(*status); *status = CREATE_DISK_FILE; ffinit(fptr, name,status); return(*status); } /*--------------------------------------------------------------------------*/ int ffinit(fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - name of file to create */ int *status) /* IO - error status */ /* Create and initialize a new FITS file. */ { int ii, driver, slen, clobber = 0; char *url; char urltype[MAX_PREFIX_LEN], outfile[FLEN_FILENAME]; char tmplfile[FLEN_FILENAME], compspec[80]; int handle, create_disk_file = 0; *fptr = 0; /* initialize null file pointer, */ /* regardless of the value of *status */ if (*status > 0) return(*status); if (*status == CREATE_DISK_FILE) { create_disk_file = 1; *status = 0; } if (need_to_initialize) { /* this is called only once */ *status = fits_init_cfitsio(); } if (*status > 0) return(*status); url = (char *) name; while (*url == ' ') /* ignore leading spaces in the filename */ url++; if (*url == '\0') { ffpmsg("Name of file to create is blank. (ffinit)"); return(*status = FILE_NOT_CREATED); } if (create_disk_file) { if (strlen(url) > FLEN_FILENAME - 1) { ffpmsg("Filename is too long. (ffinit)"); return(*status = FILE_NOT_CREATED); } strcpy(outfile, url); strcpy(urltype, "file://"); tmplfile[0] = '\0'; compspec[0] = '\0'; } else { /* check for clobber symbol, i.e, overwrite existing file */ if (*url == '!') { clobber = TRUE; url++; } else clobber = FALSE; /* parse the output file specification */ /* this routine checks that the strings will not overflow */ ffourl(url, urltype, outfile, tmplfile, compspec, status); if (*status > 0) { ffpmsg("could not parse the output filename: (ffinit)"); ffpmsg(url); return(*status); } } /* find which driver corresponds to the urltype */ *status = urltype2driver(urltype, &driver); if (*status) { ffpmsg("could not find driver for this file: (ffinit)"); ffpmsg(url); return(*status); } /* delete pre-existing file, if asked to do so */ if (clobber) { if (driverTable[driver].remove) (*driverTable[driver].remove)(outfile); } /* call appropriate driver to create the file */ if (driverTable[driver].create) { FFLOCK; /* lock this while searching for vacant handle */ *status = (*driverTable[driver].create)(outfile, &handle); FFUNLOCK; if (*status) { ffpmsg("failed to create new file (already exists?):"); ffpmsg(url); return(*status); } } else { ffpmsg("cannot create a new file of this type: (ffinit)"); ffpmsg(url); return(*status = FILE_NOT_CREATED); } /* allocate fitsfile structure and initialize = 0 */ *fptr = (fitsfile *) calloc(1, sizeof(fitsfile)); if (!(*fptr)) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate structure for following file: (ffopen)"); ffpmsg(url); return(*status = MEMORY_ALLOCATION); } /* allocate FITSfile structure and initialize = 0 */ (*fptr)->Fptr = (FITSfile *) calloc(1, sizeof(FITSfile)); if (!((*fptr)->Fptr)) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate structure for following file: (ffopen)"); ffpmsg(url); free(*fptr); *fptr = 0; return(*status = MEMORY_ALLOCATION); } slen = strlen(url) + 1; slen = maxvalue(slen, 32); /* reserve at least 32 chars */ ((*fptr)->Fptr)->filename = (char *) malloc(slen); /* mem for file name */ if ( !(((*fptr)->Fptr)->filename) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for filename: (ffinit)"); ffpmsg(url); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = FILE_NOT_CREATED); } /* mem for headstart array */ ((*fptr)->Fptr)->headstart = (LONGLONG *) calloc(1001, sizeof(LONGLONG)); if ( !(((*fptr)->Fptr)->headstart) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for headstart array: (ffinit)"); ffpmsg(url); free( ((*fptr)->Fptr)->filename); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } /* mem for file I/O buffers */ ((*fptr)->Fptr)->iobuffer = (char *) calloc(NIOBUF, IOBUFLEN); if ( !(((*fptr)->Fptr)->iobuffer) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for iobuffer array: (ffinit)"); ffpmsg(url); free( ((*fptr)->Fptr)->headstart); /* free memory for headstart array */ free( ((*fptr)->Fptr)->filename); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } /* initialize the ageindex array (relative age of the I/O buffers) */ /* and initialize the bufrecnum array as being empty */ for (ii = 0; ii < NIOBUF; ii++) { ((*fptr)->Fptr)->ageindex[ii] = ii; ((*fptr)->Fptr)->bufrecnum[ii] = -1; } /* store the parameters describing the file */ ((*fptr)->Fptr)->MAXHDU = 1000; /* initial size of headstart */ ((*fptr)->Fptr)->filehandle = handle; /* store the file pointer */ ((*fptr)->Fptr)->driver = driver; /* driver number */ strcpy(((*fptr)->Fptr)->filename, url); /* full input filename */ ((*fptr)->Fptr)->filesize = 0; /* physical file size */ ((*fptr)->Fptr)->logfilesize = 0; /* logical file size */ ((*fptr)->Fptr)->writemode = 1; /* read-write mode */ ((*fptr)->Fptr)->datastart = DATA_UNDEFINED; /* unknown start of data */ ((*fptr)->Fptr)->curbuf = -1; /* undefined current IO buffer */ ((*fptr)->Fptr)->open_count = 1; /* structure is currently used once */ ((*fptr)->Fptr)->validcode = VALIDSTRUC; /* flag denoting valid structure */ ((*fptr)->Fptr)->noextsyntax = create_disk_file; /* true if extended syntax is disabled */ ffldrc(*fptr, 0, IGNORE_EOF, status); /* initialize first record */ fits_store_Fptr( (*fptr)->Fptr, status); /* store Fptr address */ /* if template file was given, use it to define structure of new file */ if (tmplfile[0]) ffoptplt(*fptr, tmplfile, status); /* parse and save image compression specification, if given */ if (compspec[0]) ffparsecompspec(*fptr, compspec, status); return(*status); /* successful return */ } /*--------------------------------------------------------------------------*/ /* ffimem == fits_create_memfile */ int ffimem(fitsfile **fptr, /* O - FITS file pointer */ void **buffptr, /* I - address of memory pointer */ size_t *buffsize, /* I - size of buffer, in bytes */ size_t deltasize, /* I - increment for future realloc's */ void *(*mem_realloc)(void *p, size_t newsize), /* function */ int *status) /* IO - error status */ /* Create and initialize a new FITS file in memory */ { int ii, driver, slen; char urltype[MAX_PREFIX_LEN]; int handle; if (*status > 0) return(*status); *fptr = 0; /* initialize null file pointer */ if (need_to_initialize) { /* this is called only once */ *status = fits_init_cfitsio(); } if (*status > 0) return(*status); strcpy(urltype, "memkeep://"); /* URL type for pre-existing memory file */ *status = urltype2driver(urltype, &driver); if (*status > 0) { ffpmsg("could not find driver for pre-existing memory file: (ffimem)"); return(*status); } /* call driver routine to "open" the memory file */ FFLOCK; /* lock this while searching for vacant handle */ *status = mem_openmem( buffptr, buffsize, deltasize, mem_realloc, &handle); FFUNLOCK; if (*status > 0) { ffpmsg("failed to open pre-existing memory file: (ffimem)"); return(*status); } /* allocate fitsfile structure and initialize = 0 */ *fptr = (fitsfile *) calloc(1, sizeof(fitsfile)); if (!(*fptr)) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate structure for memory file: (ffimem)"); return(*status = MEMORY_ALLOCATION); } /* allocate FITSfile structure and initialize = 0 */ (*fptr)->Fptr = (FITSfile *) calloc(1, sizeof(FITSfile)); if (!((*fptr)->Fptr)) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate structure for memory file: (ffimem)"); free(*fptr); *fptr = 0; return(*status = MEMORY_ALLOCATION); } slen = 32; /* reserve at least 32 chars */ ((*fptr)->Fptr)->filename = (char *) malloc(slen); /* mem for file name */ if ( !(((*fptr)->Fptr)->filename) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for filename: (ffimem)"); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } /* mem for headstart array */ ((*fptr)->Fptr)->headstart = (LONGLONG *) calloc(1001, sizeof(LONGLONG)); if ( !(((*fptr)->Fptr)->headstart) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for headstart array: (ffimem)"); free( ((*fptr)->Fptr)->filename); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } /* mem for file I/O buffers */ ((*fptr)->Fptr)->iobuffer = (char *) calloc(NIOBUF, IOBUFLEN); if ( !(((*fptr)->Fptr)->iobuffer) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for iobuffer array: (ffimem)"); free( ((*fptr)->Fptr)->headstart); /* free memory for headstart array */ free( ((*fptr)->Fptr)->filename); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } /* initialize the ageindex array (relative age of the I/O buffers) */ /* and initialize the bufrecnum array as being empty */ for (ii = 0; ii < NIOBUF; ii++) { ((*fptr)->Fptr)->ageindex[ii] = ii; ((*fptr)->Fptr)->bufrecnum[ii] = -1; } /* store the parameters describing the file */ ((*fptr)->Fptr)->MAXHDU = 1000; /* initial size of headstart */ ((*fptr)->Fptr)->filehandle = handle; /* file handle */ ((*fptr)->Fptr)->driver = driver; /* driver number */ strcpy(((*fptr)->Fptr)->filename, "memfile"); /* dummy filename */ ((*fptr)->Fptr)->filesize = *buffsize; /* physical file size */ ((*fptr)->Fptr)->logfilesize = *buffsize; /* logical file size */ ((*fptr)->Fptr)->writemode = 1; /* read-write mode */ ((*fptr)->Fptr)->datastart = DATA_UNDEFINED; /* unknown start of data */ ((*fptr)->Fptr)->curbuf = -1; /* undefined current IO buffer */ ((*fptr)->Fptr)->open_count = 1; /* structure is currently used once */ ((*fptr)->Fptr)->validcode = VALIDSTRUC; /* flag denoting valid structure */ ((*fptr)->Fptr)->noextsyntax = 0; /* extended syntax can be used in filename */ ffldrc(*fptr, 0, IGNORE_EOF, status); /* initialize first record */ fits_store_Fptr( (*fptr)->Fptr, status); /* store Fptr address */ return(*status); } /*--------------------------------------------------------------------------*/ int fits_init_cfitsio(void) /* initialize anything that is required before using the CFITSIO routines */ { int status; union u_tag { short ival; char cval[2]; } u; fitsio_init_lock(); FFLOCK; /* lockout other threads while executing this critical */ /* section of code */ if (need_to_initialize == 0) { /* already initialized? */ FFUNLOCK; return(0); } /* test for correct byteswapping. */ u.ival = 1; if ((BYTESWAPPED && u.cval[0] != 1) || (BYTESWAPPED == FALSE && u.cval[1] != 1) ) { printf ("\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); printf(" Byteswapping is not being done correctly on this system.\n"); printf(" Check the MACHINE and BYTESWAPPED definitions in fitsio2.h\n"); printf(" Please report this problem to the CFITSIO developers.\n"); printf( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); FFUNLOCK; return(1); } /* test that LONGLONG is an 8 byte integer */ if (sizeof(LONGLONG) != 8) { printf ("\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); printf(" CFITSIO did not find an 8-byte long integer data type.\n"); printf(" sizeof(LONGLONG) = %d\n",(int)sizeof(LONGLONG)); printf(" Please report this problem to the CFITSIO developers.\n"); printf( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); FFUNLOCK; return(1); } /* register the standard I/O drivers that are always available */ /* 1--------------------disk file driver-----------------------*/ status = fits_register_driver("file://", file_init, file_shutdown, file_setoptions, file_getoptions, file_getversion, file_checkfile, file_open, file_create, #ifdef HAVE_FTRUNCATE file_truncate, #else NULL, /* no file truncate function */ #endif file_close, file_remove, file_size, file_flush, file_seek, file_read, file_write); if (status) { ffpmsg("failed to register the file:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* 2------------ output temporary memory file driver ----------------*/ status = fits_register_driver("mem://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ NULL, /* open function not allowed */ mem_create, mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the mem:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* 3--------------input pre-existing memory file driver----------------*/ status = fits_register_driver("memkeep://", NULL, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ NULL, /* file open driver function is not used */ NULL, /* create function not allowed */ mem_truncate, mem_close_keep, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the memkeep:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* 4-------------------stdin stream driver----------------------*/ /* the stdin stream is copied to memory then opened in memory */ status = fits_register_driver("stdin://", NULL, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, stdin_checkfile, stdin_open, NULL, /* create function not allowed */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the stdin:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* 5-------------------stdin file stream driver----------------------*/ /* the stdin stream is copied to a disk file then the disk file is opened */ status = fits_register_driver("stdinfile://", NULL, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ stdin_open, NULL, /* create function not allowed */ #ifdef HAVE_FTRUNCATE file_truncate, #else NULL, /* no file truncate function */ #endif file_close, file_remove, file_size, file_flush, file_seek, file_read, file_write); if (status) { ffpmsg("failed to register the stdinfile:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* 6-----------------------stdout stream driver------------------*/ status = fits_register_driver("stdout://", NULL, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ NULL, /* open function not required */ mem_create, mem_truncate, stdout_close, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the stdout:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* 7------------------iraf disk file to memory driver -----------*/ status = fits_register_driver("irafmem://", NULL, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ mem_iraf_open, NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the irafmem:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* 8------------------raw binary file to memory driver -----------*/ status = fits_register_driver("rawfile://", NULL, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ mem_rawfile_open, NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the rawfile:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* 9------------------compressed disk file to memory driver -----------*/ status = fits_register_driver("compress://", NULL, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ mem_compress_open, NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the compress:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* 10------------------compressed disk file to memory driver -----------*/ /* Identical to compress://, except it allows READWRITE access */ status = fits_register_driver("compressmem://", NULL, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ mem_compress_openrw, NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the compressmem:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* 11------------------compressed disk file to disk file driver -------*/ status = fits_register_driver("compressfile://", NULL, file_shutdown, file_setoptions, file_getoptions, file_getversion, NULL, /* checkfile not needed */ file_compress_open, file_create, #ifdef HAVE_FTRUNCATE file_truncate, #else NULL, /* no file truncate function */ #endif file_close, file_remove, file_size, file_flush, file_seek, file_read, file_write); if (status) { ffpmsg("failed to register the compressfile:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* 12---create file in memory, then compress it to disk file on close--*/ status = fits_register_driver("compressoutfile://", NULL, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ NULL, /* open function not allowed */ mem_create_comp, mem_truncate, mem_close_comp, file_remove, /* delete existing compressed disk file */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg( "failed to register the compressoutfile:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* Register Optional drivers */ #ifdef HAVE_NET_SERVICES /* 13--------------------root driver-----------------------*/ status = fits_register_driver("root://", root_init, root_shutdown, root_setoptions, root_getoptions, root_getversion, NULL, /* checkfile not needed */ root_open, root_create, NULL, /* No truncate possible */ root_close, NULL, /* No remove possible */ root_size, /* no size possible */ root_flush, root_seek, /* Though will always succeed */ root_read, root_write); if (status) { ffpmsg("failed to register the root:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* 14--------------------http driver-----------------------*/ status = fits_register_driver("http://", NULL, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, http_checkfile, http_open, NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the http:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* 15--------------------http file driver-----------------------*/ status = fits_register_driver("httpfile://", NULL, file_shutdown, file_setoptions, file_getoptions, file_getversion, NULL, /* checkfile not needed */ http_file_open, file_create, #ifdef HAVE_FTRUNCATE file_truncate, #else NULL, /* no file truncate function */ #endif file_close, file_remove, file_size, file_flush, file_seek, file_read, file_write); if (status) { ffpmsg("failed to register the httpfile:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* 16--------------------http memory driver-----------------------*/ /* same as http:// driver, except memory file can be opened READWRITE */ status = fits_register_driver("httpmem://", NULL, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, http_checkfile, http_file_open, /* this will simply call http_open */ NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the httpmem:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* 17--------------------httpcompress file driver-----------------------*/ status = fits_register_driver("httpcompress://", NULL, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ http_compress_open, NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the httpcompress:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* 18--------------------ftp driver-----------------------*/ status = fits_register_driver("ftp://", NULL, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, ftp_checkfile, ftp_open, NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the ftp:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* 19--------------------ftp file driver-----------------------*/ status = fits_register_driver("ftpfile://", NULL, file_shutdown, file_setoptions, file_getoptions, file_getversion, NULL, /* checkfile not needed */ ftp_file_open, file_create, #ifdef HAVE_FTRUNCATE file_truncate, #else NULL, /* no file truncate function */ #endif file_close, file_remove, file_size, file_flush, file_seek, file_read, file_write); if (status) { ffpmsg("failed to register the ftpfile:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* 20--------------------ftp mem driver-----------------------*/ /* same as ftp:// driver, except memory file can be opened READWRITE */ status = fits_register_driver("ftpmem://", NULL, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, ftp_checkfile, ftp_file_open, /* this will simply call ftp_open */ NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the ftpmem:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* 21--------------------ftp compressed file driver------------------*/ status = fits_register_driver("ftpcompress://", NULL, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ ftp_compress_open, 0, /* create function not required */ mem_truncate, mem_close_free, 0, /* remove function not required */ mem_size, 0, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the ftpcompress:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* === End of net drivers section === */ #endif /* ==================== SHARED MEMORY DRIVER SECTION ======================= */ #ifdef HAVE_SHMEM_SERVICES /* 22--------------------shared memory driver-----------------------*/ status = fits_register_driver("shmem://", smem_init, smem_shutdown, smem_setoptions, smem_getoptions, smem_getversion, NULL, /* checkfile not needed */ smem_open, smem_create, NULL, /* truncate file not supported yet */ smem_close, smem_remove, smem_size, smem_flush, smem_seek, smem_read, smem_write ); if (status) { ffpmsg("failed to register the shmem:// driver (init_cfitsio)"); FFUNLOCK; return(status); } #endif /* ==================== END OF SHARED MEMORY DRIVER SECTION ================ */ #ifdef HAVE_GSIFTP /* 23--------------------gsiftp driver-----------------------*/ status = fits_register_driver("gsiftp://", gsiftp_init, gsiftp_shutdown, gsiftp_setoptions, gsiftp_getoptions, gsiftp_getversion, gsiftp_checkfile, gsiftp_open, gsiftp_create, #ifdef HAVE_FTRUNCATE gsiftp_truncate, #else NULL, #endif gsiftp_close, NULL, /* remove function not yet implemented */ gsiftp_size, gsiftp_flush, gsiftp_seek, gsiftp_read, gsiftp_write); if (status) { ffpmsg("failed to register the gsiftp:// driver (init_cfitsio)"); FFUNLOCK; return(status); } #endif /* 24---------------stdin and stdout stream driver-------------------*/ status = fits_register_driver("stream://", NULL, NULL, NULL, NULL, NULL, NULL, stream_open, stream_create, NULL, /* no stream truncate function */ stream_close, NULL, /* no stream remove */ stream_size, stream_flush, stream_seek, stream_read, stream_write); if (status) { ffpmsg("failed to register the stream:// driver (init_cfitsio)"); FFUNLOCK; return(status); } #ifdef HAVE_NET_SERVICES /* 25--------------------https driver-----------------------*/ status = fits_register_driver("https://", NULL, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, https_checkfile, https_open, NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the https:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* 26--------------------https file driver-----------------------*/ status = fits_register_driver("httpsfile://", NULL, file_shutdown, file_setoptions, file_getoptions, file_getversion, NULL, /* checkfile not needed */ https_file_open, file_create, #ifdef HAVE_FTRUNCATE file_truncate, #else NULL, /* no file truncate function */ #endif file_close, file_remove, file_size, file_flush, file_seek, file_read, file_write); if (status) { ffpmsg("failed to register the httpsfile:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* 27--------------------https memory driver-----------------------*/ /* same as https:// driver, except memory file can be opened READWRITE */ status = fits_register_driver("httpsmem://", NULL, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, https_checkfile, https_file_open, /* this will simply call https_open */ NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the httpsmem:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* === End of https net drivers section === */ /* 28--------------------ftps driver-----------------------*/ status = fits_register_driver("ftps://", NULL, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, ftps_checkfile, ftps_open, NULL, mem_truncate, mem_close_free, NULL, mem_size, NULL, mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the ftps:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* 29--------------------ftps file driver-----------------------*/ status = fits_register_driver("ftpsfile://", NULL, file_shutdown, file_setoptions, file_getoptions, file_getversion, NULL, ftps_file_open, file_create, #ifdef HAVE_FTRUNCATE file_truncate, #else NULL, #endif file_close, file_remove, file_size, file_flush, file_seek, file_read, file_write); if (status) { ffpmsg("failed to register the ftpsfile:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* 30--------------------ftps memory driver-----------------------*/ /* same as ftps:// driver, except memory file can be opened READWRITE */ status = fits_register_driver("ftpsmem://", NULL, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, ftps_checkfile, ftps_file_open, NULL, mem_truncate, mem_close_free, NULL, mem_size, NULL, mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the ftpsmem:// driver (init_cfitsio)"); FFUNLOCK; return(status); } /* 31--------------------ftps compressed file driver------------------*/ status = fits_register_driver("ftpscompress://", NULL, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ ftps_compress_open, 0, /* create function not required */ mem_truncate, mem_close_free, 0, /* remove function not required */ mem_size, 0, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the ftpscompress:// driver (init_cfitsio)"); FFUNLOCK; return(status); } #endif /* reset flag. Any other threads will now not need to call this routine */ need_to_initialize = 0; FFUNLOCK; return(status); } /*--------------------------------------------------------------------------*/ int fits_register_driver(char *prefix, int (*init)(void), int (*shutdown)(void), int (*setoptions)(int option), int (*getoptions)(int *options), int (*getversion)(int *version), int (*checkfile) (char *urltype, char *infile, char *outfile), int (*open)(char *filename, int rwmode, int *driverhandle), int (*create)(char *filename, int *driverhandle), int (*truncate)(int driverhandle, LONGLONG filesize), int (*close)(int driverhandle), int (*fremove)(char *filename), int (*size)(int driverhandle, LONGLONG *sizex), int (*flush)(int driverhandle), int (*seek)(int driverhandle, LONGLONG offset), int (*read) (int driverhandle, void *buffer, long nbytes), int (*write)(int driverhandle, void *buffer, long nbytes) ) /* register all the functions needed to support an I/O driver */ { int status; if (no_of_drivers < 0 ) { /* This is bad. looks like memory has been corrupted. */ ffpmsg("Vital CFITSIO parameters held in memory have been corrupted!!"); ffpmsg("Fatal condition detected in fits_register_driver."); return(TOO_MANY_DRIVERS); } if (no_of_drivers + 1 > MAX_DRIVERS) return(TOO_MANY_DRIVERS); if (prefix == NULL) return(BAD_URL_PREFIX); if (init != NULL) { status = (*init)(); /* initialize the driver */ if (status) return(status); } /* fill in data in table */ strncpy(driverTable[no_of_drivers].prefix, prefix, MAX_PREFIX_LEN); driverTable[no_of_drivers].prefix[MAX_PREFIX_LEN - 1] = 0; driverTable[no_of_drivers].init = init; driverTable[no_of_drivers].shutdown = shutdown; driverTable[no_of_drivers].setoptions = setoptions; driverTable[no_of_drivers].getoptions = getoptions; driverTable[no_of_drivers].getversion = getversion; driverTable[no_of_drivers].checkfile = checkfile; driverTable[no_of_drivers].open = open; driverTable[no_of_drivers].create = create; driverTable[no_of_drivers].truncate = truncate; driverTable[no_of_drivers].close = close; driverTable[no_of_drivers].remove = fremove; driverTable[no_of_drivers].size = size; driverTable[no_of_drivers].flush = flush; driverTable[no_of_drivers].seek = seek; driverTable[no_of_drivers].read = read; driverTable[no_of_drivers].write = write; no_of_drivers++; /* increment the number of drivers */ return(0); } /*--------------------------------------------------------------------------*/ /* fits_parse_input_url */ int ffiurl(char *url, /* input filename */ char *urltype, /* e.g., 'file://', 'http://', 'mem://' */ char *infilex, /* root filename (may be complete path) */ char *outfile, /* optional output file name */ char *extspec, /* extension spec: +n or [extname, extver] */ char *rowfilterx, /* boolean row filter expression */ char *binspec, /* histogram binning specifier */ char *colspec, /* column or keyword modifier expression */ int *status) /* parse the input URL into its basic components. This routine does not support the pixfilter or compspec components. */ { return ffifile2(url, urltype, infilex, outfile, extspec, rowfilterx, binspec, colspec, 0, 0, status); } /*--------------------------------------------------------------------------*/ /* fits_parse_input_file */ int ffifile(char *url, /* input filename */ char *urltype, /* e.g., 'file://', 'http://', 'mem://' */ char *infilex, /* root filename (may be complete path) */ char *outfile, /* optional output file name */ char *extspec, /* extension spec: +n or [extname, extver] */ char *rowfilterx, /* boolean row filter expression */ char *binspec, /* histogram binning specifier */ char *colspec, /* column or keyword modifier expression */ char *pixfilter, /* pixel filter expression */ int *status) /* fits_parse_input_filename parse the input URL into its basic components. This routine does not support the compspec component. */ { return ffifile2(url, urltype, infilex, outfile, extspec, rowfilterx, binspec, colspec, pixfilter, 0, status); } /*--------------------------------------------------------------------------*/ int ffifile2(char *url, /* input filename */ char *urltype, /* e.g., 'file://', 'http://', 'mem://' */ char *infilex, /* root filename (may be complete path) */ char *outfile, /* optional output file name */ char *extspec, /* extension spec: +n or [extname, extver] */ char *rowfilterx, /* boolean row filter expression */ char *binspec, /* histogram binning specifier */ char *colspec, /* column or keyword modifier expression */ char *pixfilter, /* pixel filter expression */ char *compspec, /* image compression specification */ int *status) /* fits_parse_input_filename parse the input URL into its basic components. This routine is big and ugly and should be redesigned someday! */ { int ii, jj, slen, infilelen, plus_ext = 0, collen; char *ptr1, *ptr2, *ptr3, *ptr4, *tmptr; int hasAt, hasDot, hasOper, followingOper, spaceTerm, rowFilter; int colStart, binStart, pixStart, compStart; /* must have temporary variable for these, in case inputs are NULL */ char *infile; char *rowfilter; char *tmpstr; if (*status > 0) return(*status); /* Initialize null strings */ if (infilex) *infilex = '\0'; if (urltype) *urltype = '\0'; if (outfile) *outfile = '\0'; if (extspec) *extspec = '\0'; if (binspec) *binspec = '\0'; if (colspec) *colspec = '\0'; if (rowfilterx) *rowfilterx = '\0'; if (pixfilter) *pixfilter = '\0'; if (compspec) *compspec = '\0'; slen = strlen(url); if (slen == 0) /* blank filename ?? */ return(*status); /* allocate memory for 3 strings, each as long as the input url */ infile = (char *) calloc(3, slen + 1); if (!infile) return(*status = MEMORY_ALLOCATION); rowfilter = &infile[slen + 1]; tmpstr = &rowfilter[slen + 1]; ptr1 = url; /* -------------------------------------------------------- */ /* get urltype (e.g., file://, ftp://, http://, etc.) */ /* --------------------------------------------------------- */ if (*ptr1 == '-' && ( *(ptr1 +1) == 0 || *(ptr1 +1) == ' ' || *(ptr1 +1) == '[' || *(ptr1 +1) == '(' ) ) { /* "-" means read file from stdin. Also support "- ", */ /* "-[extname]" and '-(outfile.fits)" but exclude disk file */ /* names that begin with a minus sign, e.g., "-55d33m.fits" */ if (urltype) strcat(urltype, "stdin://"); ptr1++; } else if (!fits_strncasecmp(ptr1, "stdin", 5)) { if (urltype) strcat(urltype, "stdin://"); ptr1 = ptr1 + 5; } else { ptr2 = strstr(ptr1, "://"); ptr3 = strstr(ptr1, "(" ); if (ptr3 && (ptr3 < ptr2) ) { /* the urltype follows a '(' character, so it must apply */ /* to the output file, and is not the urltype of the input file */ ptr2 = 0; /* so reset pointer to zero */ } if (ptr2) /* copy the explicit urltype string */ { if (ptr2-ptr1+3 >= MAX_PREFIX_LEN) { ffpmsg("Name of urltype is too long."); return(*status = URL_PARSE_ERROR); } if (urltype) strncat(urltype, ptr1, ptr2 - ptr1 + 3); ptr1 = ptr2 + 3; } else if (!strncmp(ptr1, "ftp:", 4) ) { /* the 2 //'s are optional */ if (urltype) strcat(urltype, "ftp://"); ptr1 += 4; } else if (!strncmp(ptr1, "gsiftp:", 7) ) { /* the 2 //'s are optional */ if (urltype) strcat(urltype, "gsiftp://"); ptr1 += 7; } else if (!strncmp(ptr1, "http:", 5) ) { /* the 2 //'s are optional */ if (urltype) strcat(urltype, "http://"); ptr1 += 5; } else if (!strncmp(ptr1, "mem:", 4) ) { /* the 2 //'s are optional */ if (urltype) strcat(urltype, "mem://"); ptr1 += 4; } else if (!strncmp(ptr1, "shmem:", 6) ) { /* the 2 //'s are optional */ if (urltype) strcat(urltype, "shmem://"); ptr1 += 6; } else if (!strncmp(ptr1, "file:", 5) ) { /* the 2 //'s are optional */ if (urltype) strcat(urltype, "file://"); ptr1 += 5; } else /* assume file driver */ { if (urltype) strcat(urltype, "file://"); } } /* ---------------------------------------------------------- If this is a http:// type file, then the cgi file name could include the '[' character, which should not be interpreted as part of CFITSIO's Extended File Name Syntax. Test for this case by seeing if the last character is a ']' or ')'. If it is not, then just treat the whole input string as the file name and do not attempt to interprete the name using the extended filename syntax. ----------------------------------------------------------- */ if (urltype && !strncmp(urltype, "http://", 7) ) { /* test for opening parenthesis or bracket in the file name */ if( strchr(ptr1, '(' ) || strchr(ptr1, '[' ) ) { slen = strlen(ptr1); ptr3 = ptr1 + slen - 1; while (*ptr3 == ' ') /* ignore trailing blanks */ ptr3--; if (*ptr3 != ']' && *ptr3 != ')' ) { /* name doesn't end with a ']' or ')' so don't try */ /* to parse this unusual string (may be cgi string) */ if (infilex) { if (strlen(ptr1) > FLEN_FILENAME - 1) { ffpmsg("Name of file is too long."); return(*status = URL_PARSE_ERROR); } strcpy(infilex, ptr1); } free(infile); return(*status); } } } /* ---------------------------------------------------------- Look for VMS style filenames like: disk:[directory.subdirectory]filename.ext, or [directory.subdirectory]filename.ext Check if the first character is a '[' and urltype != stdin or if there is a ':[' string in the remaining url string. If so, then need to move past this bracket character before search for the opening bracket of a filter specification. ----------------------------------------------------------- */ tmptr = ptr1; if (*ptr1 == '[') { if (*url != '-') tmptr = ptr1 + 1; /* this bracket encloses a VMS directory name */ } else { tmptr = strstr(ptr1, ":["); if (tmptr) /* these 2 chars are part of the VMS disk and directory */ tmptr += 2; else tmptr = ptr1; } /* ------------------------ */ /* get the input file name */ /* ------------------------ */ ptr2 = strchr(tmptr, '('); /* search for opening parenthesis ( */ ptr3 = strchr(tmptr, '['); /* search for opening bracket [ */ if (ptr2) { ptr4 = strchr(ptr2, ')'); /* search for closing parenthesis ) */ while (ptr4 && ptr2) { do { ++ptr4; } while (*ptr4 == ' '); /* find next non-blank char after ')' */ if (*ptr4 == 0 || *ptr4 == '[') break; ptr2 = strchr(ptr2+1, '('); ptr4 = strchr(ptr4, ')'); } } if (ptr2 == ptr3) /* simple case: no [ or ( in the file name */ { strcat(infile, ptr1); } else if (!ptr3 || /* no bracket, so () enclose output file name */ (ptr2 && (ptr2 < ptr3)) ) /* () enclose output name before bracket */ { strncat(infile, ptr1, ptr2 - ptr1); ptr2++; ptr1 = strchr(ptr2, ')' ); /* search for closing ) */ if (!ptr1) { free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ) */ } if (outfile) { if (ptr1 - ptr2 > FLEN_FILENAME - 1) { free(infile); return(*status = URL_PARSE_ERROR); } strncat(outfile, ptr2, ptr1 - ptr2); } /* the opening [ could have been part of output name, */ /* e.g., file(out[compress])[3][#row > 5] */ /* so search again for opening bracket following the closing ) */ ptr3 = strchr(ptr1, '['); } else /* bracket comes first, so there is no output name */ { strncat(infile, ptr1, ptr3 - ptr1); } /* strip off any trailing blanks in the names */ slen = strlen(infile); while ( (--slen) > 0 && infile[slen] == ' ') infile[slen] = '\0'; if (outfile) { slen = strlen(outfile); while ( (--slen) > 0 && outfile[slen] == ' ') outfile[slen] = '\0'; } /* --------------------------------------------- */ /* check if this is an IRAF file (.imh extension */ /* --------------------------------------------- */ ptr4 = strstr(infile, ".imh"); /* did the infile name end with ".imh" ? */ if (ptr4 && (*(ptr4 + 4) == '\0')) { if (urltype) strcpy(urltype, "irafmem://"); } /* --------------------------------------------- */ /* check if the 'filename+n' convention has been */ /* used to specifiy which HDU number to open */ /* --------------------------------------------- */ jj = strlen(infile); for (ii = jj - 1; ii >= 0; ii--) { if (infile[ii] == '+') /* search backwards for '+' sign */ break; } if (ii > 0 && (jj - ii) < 7) /* limit extension numbers to 5 digits */ { infilelen = ii; ii++; ptr1 = infile+ii; /* pointer to start of sequence */ for (; ii < jj; ii++) { if (!isdigit((int) infile[ii] ) ) /* are all the chars digits? */ break; } if (ii == jj) { /* yes, the '+n' convention was used. Copy */ /* the digits to the output extspec string. */ plus_ext = 1; if (extspec) { if (jj - infilelen > FLEN_FILENAME - 1) { free(infile); return(*status = URL_PARSE_ERROR); } strncpy(extspec, ptr1, jj - infilelen); } infile[infilelen] = '\0'; /* delete the extension number */ } } /* -------------------------------------------------------------------- */ /* if '*' was given for the output name expand it to the root file name */ /* -------------------------------------------------------------------- */ if (outfile && outfile[0] == '*') { /* scan input name backwards to the first '/' character */ for (ii = jj - 1; ii >= 0; ii--) { if (infile[ii] == '/' || ii == 0) { if (strlen(&infile[ii + 1]) > FLEN_FILENAME - 1) { free(infile); return(*status = URL_PARSE_ERROR); } strcpy(outfile, &infile[ii + 1]); break; } } } /* ------------------------------------------ */ /* copy strings from local copy to the output */ /* ------------------------------------------ */ if (infilex) { if (strlen(infile) > FLEN_FILENAME - 1) { free(infile); return(*status = URL_PARSE_ERROR); } strcpy(infilex, infile); } /* ---------------------------------------------------------- */ /* if no '[' character in the input string, then we are done. */ /* ---------------------------------------------------------- */ if (!ptr3) { free(infile); return(*status); } /* ------------------------------------------- */ /* see if [ extension specification ] is given */ /* ------------------------------------------- */ if (!plus_ext) /* extension no. not already specified? Then */ /* first brackets must enclose extension name or # */ /* or it encloses a image subsection specification */ /* or a raw binary image specifier */ /* or a image compression specifier */ /* Or, the extension specification may have been */ /* omitted and we have to guess what the user intended */ { ptr1 = ptr3 + 1; /* pointer to first char after the [ */ ptr2 = strchr(ptr1, ']' ); /* search for closing ] */ if (!ptr2) { ffpmsg("input file URL is missing closing bracket ']'"); free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } /* ---------------------------------------------- */ /* First, test if this is a rawfile specifier */ /* which looks something like: '[ib512,512:2880]' */ /* Test if first character is b,i,j,d,r,f, or u, */ /* and optional second character is b or l, */ /* followed by one or more digits, */ /* finally followed by a ',', ':', or ']' */ /* ---------------------------------------------- */ if (*ptr1 == 'b' || *ptr1 == 'B' || *ptr1 == 'i' || *ptr1 == 'I' || *ptr1 == 'j' || *ptr1 == 'J' || *ptr1 == 'd' || *ptr1 == 'D' || *ptr1 == 'r' || *ptr1 == 'R' || *ptr1 == 'f' || *ptr1 == 'F' || *ptr1 == 'u' || *ptr1 == 'U') { /* next optional character may be a b or l (for Big or Little) */ ptr1++; if (*ptr1 == 'b' || *ptr1 == 'B' || *ptr1 == 'l' || *ptr1 == 'L') ptr1++; if (isdigit((int) *ptr1)) /* must have at least 1 digit */ { while (isdigit((int) *ptr1)) ptr1++; /* skip over digits */ if (*ptr1 == ',' || *ptr1 == ':' || *ptr1 == ']' ) { /* OK, this looks like a rawfile specifier */ if (urltype) { if (strstr(urltype, "stdin") ) strcpy(urltype, "rawstdin://"); else strcpy(urltype, "rawfile://"); } /* append the raw array specifier to infilex */ if (infilex) { if (strlen(infilex) + strlen(ptr3) > FLEN_FILENAME - 1) { free(infile); return(*status = URL_PARSE_ERROR); } strcat(infilex, ptr3); ptr1 = strchr(infilex, ']'); /* find the closing ] char */ if (ptr1) *(ptr1 + 1) = '\0'; /* terminate string after the ] */ } if (extspec) strcpy(extspec, "0"); /* the 0 ext number is implicit */ tmptr = strchr(ptr2 + 1, '[' ); /* search for another [ char */ /* copy any remaining characters into rowfilterx */ if (tmptr && rowfilterx) { if (strlen(rowfilterx) + strlen(tmptr + 1) > FLEN_FILENAME -1) { free(infile); return(*status = URL_PARSE_ERROR); } strcat(rowfilterx, tmptr + 1); tmptr = strchr(rowfilterx, ']' ); /* search for closing ] */ if (tmptr) *tmptr = '\0'; /* overwrite the ] with null terminator */ } free(infile); /* finished parsing, so return */ return(*status); } } } /* end of rawfile specifier test */ /* -------------------------------------------------------- */ /* Not a rawfile, so next, test if this is an image section */ /* i.e., an integer followed by a ':' or a '*' or '-*' */ /* -------------------------------------------------------- */ ptr1 = ptr3 + 1; /* reset pointer to first char after the [ */ tmptr = ptr1; while (*tmptr == ' ') tmptr++; /* skip leading blanks */ while (isdigit((int) *tmptr)) tmptr++; /* skip over leading digits */ if (*tmptr == ':' || *tmptr == '*' || *tmptr == '-') { /* this is an image section specifier */ strcat(rowfilter, ptr3); /* don't want to assume 0 extension any more; may imply an image extension. if (extspec) strcpy(extspec, "0"); */ } else { /* ----------------------------------------------------------------- Not an image section or rawfile spec so may be an extension spec. Examples of valid extension specifiers: [3] - 3rd extension; 0 = primary array [events] - events extension [events, 2] - events extension, with EXTVER = 2 [events,2] - spaces are optional [events, 3, b] - same as above, plus XTENSION = 'BINTABLE' [PICS; colName(12)] - an image in row 12 of the colName column in the PICS table extension [PICS; colName(exposure > 1000)] - as above, but find image in first row with with exposure column value > 1000. [Rate Table] - extension name can contain spaces! [Rate Table;colName(exposure>1000)] Examples of other types of specifiers (Not extension specifiers) [bin] !!! this is ambiguous, and can't be distinguished from a valid extension specifier [bini X=1:512:16] (also binb, binj, binr, and bind are allowed) [binr (X,Y) = 5] [bin @binfilter.txt] [col Time;rate] [col PI=PHA * 1.1] [col -Time; status] [X > 5] [X>5] [@filter.txt] [StatusCol] !!! this is ambiguous, and can't be distinguished from a valid extension specifier [StatusCol==0] [StatusCol || x>6] [gtifilter()] [regfilter("region.reg")] [compress Rice] There will always be some ambiguity between an extension name and a boolean row filtering expression, (as in a couple of the above examples). If there is any doubt, the expression should be treated as an extension specification; The user can always add an explicit expression specifier to override this interpretation. The following decision logic will be used: 1) locate the first token, terminated with a space, comma, semi-colon, or closing bracket. 2) the token is not part of an extension specifier if any of the following is true: - if the token begins with '@' and contains a '.' - if the token contains an operator: = > < || && - if the token begins with "gtifilter(" or "regfilter(" - if the token is terminated by a space and is followed by additional characters (not a ']') AND any of the following: - the token is 'col' - the token is 3 or 4 chars long and begins with 'bin' - the second token begins with an operator: ! = < > | & + - * / % 3) otherwise, the string is assumed to be an extension specifier ----------------------------------------------------------------- */ tmptr = ptr1; while(*tmptr == ' ') tmptr++; hasAt = 0; hasDot = 0; hasOper = 0; followingOper = 0; spaceTerm = 0; rowFilter = 0; colStart = 0; binStart = 0; pixStart = 0; compStart = 0; if (*tmptr == '@') /* test for leading @ symbol */ hasAt = 1; if ( !fits_strncasecmp(tmptr, "col ", 4) ) colStart = 1; if ( !fits_strncasecmp(tmptr, "bin", 3) ) binStart = 1; if ( !fits_strncasecmp(tmptr, "pix", 3) ) pixStart = 1; if ( !fits_strncasecmp(tmptr, "compress ", 9) || !fits_strncasecmp(tmptr, "compress]", 9) ) compStart = 1; if ( !fits_strncasecmp(tmptr, "gtifilter(", 10) || !fits_strncasecmp(tmptr, "regfilter(", 10) ) { rowFilter = 1; } else { /* parse the first token of the expression */ for (ii = 0; ii < ptr2 - ptr1 + 1; ii++, tmptr++) { if (*tmptr == '.') hasDot = 1; else if (*tmptr == '=' || *tmptr == '>' || *tmptr == '<' || (*tmptr == '|' && *(tmptr+1) == '|') || (*tmptr == '&' && *(tmptr+1) == '&') ) hasOper = 1; else if (*tmptr == ',' || *tmptr == ';' || *tmptr == ']') { break; } else if (*tmptr == ' ') /* a space char? */ { while(*tmptr == ' ') /* skip spaces */ tmptr++; if (*tmptr == ']') /* is this the end? */ break; spaceTerm = 1; /* 1st token is terminated by space */ /* test if this is a column or binning specifier */ if (colStart || (ii <= 4 && (binStart || pixStart)) ) rowFilter = 1; else { /* check if next character is an operator */ if (*tmptr == '=' || *tmptr == '>' || *tmptr == '<' || *tmptr == '|' || *tmptr == '&' || *tmptr == '!' || *tmptr == '+' || *tmptr == '-' || *tmptr == '*' || *tmptr == '/' || *tmptr == '%') followingOper = 1; } break; } } } /* test if this is NOT an extension specifier */ if ( rowFilter || (pixStart && spaceTerm) || (hasAt && hasDot) || hasOper || compStart || (spaceTerm && followingOper) ) { /* this is (probably) not an extension specifier */ /* so copy all chars to filter spec string */ strcat(rowfilter, ptr3); } else { /* this appears to be a legit extension specifier */ /* copy the extension specification */ if (extspec) { if (ptr2 - ptr1 > FLEN_FILENAME - 1) { free(infile); return(*status = URL_PARSE_ERROR); } strncat(extspec, ptr1, ptr2 - ptr1); } /* copy any remaining chars to filter spec string */ strcat(rowfilter, ptr2 + 1); } } } /* end of if (!plus_ext) */ else { /* ------------------------------------------------------------------ */ /* already have extension, so this must be a filter spec of some sort */ /* ------------------------------------------------------------------ */ strcat(rowfilter, ptr3); } /* strip off any trailing blanks from filter */ slen = strlen(rowfilter); while ( (--slen) >= 0 && rowfilter[slen] == ' ') rowfilter[slen] = '\0'; if (!rowfilter[0]) { free(infile); return(*status); /* nothing left to parse */ } /* ------------------------------------------------ */ /* does the filter contain a binning specification? */ /* ------------------------------------------------ */ ptr1 = strstr(rowfilter, "[bin"); /* search for "[bin" */ if (!ptr1) ptr1 = strstr(rowfilter, "[BIN"); /* search for "[BIN" */ if (!ptr1) ptr1 = strstr(rowfilter, "[Bin"); /* search for "[Bin" */ if (ptr1) { ptr2 = ptr1 + 4; /* end of the '[bin' string */ if (*ptr2 == 'b' || *ptr2 == 'i' || *ptr2 == 'j' || *ptr2 == 'r' || *ptr2 == 'd') ptr2++; /* skip the datatype code letter */ if ( *ptr2 != ' ' && *ptr2 != ']') ptr1 = NULL; /* bin string must be followed by space or ] */ } if (ptr1) { /* found the binning string */ if (binspec) { if (strlen(ptr1 +1) > FLEN_FILENAME - 1) { free(infile); return(*status = URL_PARSE_ERROR); } strcpy(binspec, ptr1 + 1); ptr2 = strchr(binspec, ']'); if (ptr2) /* terminate the binning filter */ { *ptr2 = '\0'; if ( *(--ptr2) == ' ') /* delete trailing spaces */ *ptr2 = '\0'; } else { ffpmsg("input file URL is missing closing bracket ']'"); ffpmsg(rowfilter); free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } } /* delete the binning spec from the row filter string */ ptr2 = strchr(ptr1, ']'); strcpy(tmpstr, ptr2+1); /* copy any chars after the binspec */ strcpy(ptr1, tmpstr); /* overwrite binspec */ } /* --------------------------------------------------------- */ /* does the filter contain a column selection specification? */ /* --------------------------------------------------------- */ ptr1 = strstr(rowfilter, "[col "); if (!ptr1) { ptr1 = strstr(rowfilter, "[COL "); if (!ptr1) ptr1 = strstr(rowfilter, "[Col "); } hasAt = 0; while (ptr1) { /* find the end of the column specifier */ ptr2 = ptr1 + 5; /* Scan past any whitespace and check for @filename */ while (*ptr2 == ' ') ptr2++; if (*ptr2 == '@') hasAt = 1; while (*ptr2 != ']') { if (*ptr2 == '\0') { ffpmsg("input file URL is missing closing bracket ']'"); free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } if (*ptr2 == '\'') /* start of a literal string */ { ptr2 = strchr(ptr2 + 1, '\''); /* find closing quote */ if (!ptr2) { ffpmsg ("literal string in input file URL is missing closing single quote"); free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } } if (*ptr2 == '[') /* set of nested square brackets */ { ptr2 = strchr(ptr2 + 1, ']'); /* find closing bracket */ if (!ptr2) { ffpmsg ("nested brackets in input file URL is missing closing bracket"); free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } } ptr2++; /* continue search for the closing bracket character */ } collen = ptr2 - ptr1 - 1; if (colspec) { /* copy the column specifier to output string */ if (collen + strlen(colspec) > FLEN_FILENAME - 1) { free(infile); return(*status = URL_PARSE_ERROR); } if (*colspec == 0) { strncpy(colspec, ptr1 + 1, collen); colspec[collen] = '\0'; } else { /* Pre-existing colspec, append with ";" */ strcat(colspec, ";"); strncat(colspec, ptr1 + 5, collen-4); /* Note that strncat always null-terminates the destination string */ /* Special error checking here. We can't allow there to be a col @filename.txt includes if there are multiple col expressions */ if (hasAt) { ffpmsg("input URL multiple column filter cannot use @filename.txt"); free(infile); return(*status = URL_PARSE_ERROR); } } collen = strlen(colspec); while (colspec[--collen] == ' ') colspec[collen] = '\0'; /* strip trailing blanks */ } /* delete the column selection spec from the row filter string */ strcpy(tmpstr, ptr2 + 1); /* copy any chars after the colspec */ strcpy(ptr1, tmpstr); /* overwrite binspec */ /* Check for additional column specifiers */ ptr1 = strstr(rowfilter, "[col "); if (!ptr1) ptr1 = strstr(rowfilter, "[COL "); if (!ptr1) ptr1 = strstr(rowfilter, "[Col "); } /* --------------------------------------------------------- */ /* does the filter contain a pixel filter specification? */ /* --------------------------------------------------------- */ ptr1 = strstr(rowfilter, "[pix"); if (!ptr1) { ptr1 = strstr(rowfilter, "[PIX"); if (!ptr1) ptr1 = strstr(rowfilter, "[Pix"); } if (ptr1) { ptr2 = ptr1 + 4; /* end of the '[pix' string */ if (*ptr2 == 'b' || *ptr2 == 'i' || *ptr2 == 'j' || *ptr2 == 'B' || *ptr2 == 'I' || *ptr2 == 'J' || *ptr2 == 'r' || *ptr2 == 'd' || *ptr2 == 'R' || *ptr2 == 'D') ptr2++; /* skip the datatype code letter */ if (*ptr2 == '1') ptr2++; /* skip the single HDU indicator */ if ( *ptr2 != ' ') ptr1 = NULL; /* pix string must be followed by space */ } if (ptr1) { /* find the end of the pixel filter */ while (*ptr2 != ']') { if (*ptr2 == '\0') { ffpmsg("input file URL is missing closing bracket ']'"); free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } if (*ptr2 == '\'') /* start of a literal string */ { ptr2 = strchr(ptr2 + 1, '\''); /* find closing quote */ if (!ptr2) { ffpmsg ("literal string in input file URL is missing closing single quote"); free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } } if (*ptr2 == '[') /* set of nested square brackets */ { ptr2 = strchr(ptr2 + 1, ']'); /* find closing bracket */ if (!ptr2) { ffpmsg ("nested brackets in input file URL is missing closing bracket"); free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } } ptr2++; /* continue search for the closing bracket character */ } collen = ptr2 - ptr1 - 1; if (pixfilter) /* copy the column specifier to output string */ { if (collen > FLEN_FILENAME - 1) { free(infile); return(*status = URL_PARSE_ERROR); } strncpy(pixfilter, ptr1 + 1, collen); pixfilter[collen] = '\0'; while (pixfilter[--collen] == ' ') pixfilter[collen] = '\0'; /* strip trailing blanks */ } /* delete the pixel filter from the row filter string */ strcpy(tmpstr, ptr2 + 1); /* copy any chars after the pixel filter */ strcpy(ptr1, tmpstr); /* overwrite binspec */ } /* ------------------------------------------------------------ */ /* does the filter contain an image compression specification? */ /* ------------------------------------------------------------ */ ptr1 = strstr(rowfilter, "[compress"); if (ptr1) { ptr2 = ptr1 + 9; /* end of the '[compress' string */ if ( *ptr2 != ' ' && *ptr2 != ']') ptr1 = NULL; /* compress string must be followed by space or ] */ } if (ptr1) { /* found the compress string */ if (compspec) { if (strlen(ptr1 +1) > FLEN_FILENAME - 1) { free(infile); return(*status = URL_PARSE_ERROR); } strcpy(compspec, ptr1 + 1); ptr2 = strchr(compspec, ']'); if (ptr2) /* terminate the binning filter */ { *ptr2 = '\0'; if ( *(--ptr2) == ' ') /* delete trailing spaces */ *ptr2 = '\0'; } else { ffpmsg("input file URL is missing closing bracket ']'"); ffpmsg(rowfilter); free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } } /* delete the compression spec from the row filter string */ ptr2 = strchr(ptr1, ']'); strcpy(tmpstr, ptr2+1); /* copy any chars after the binspec */ strcpy(ptr1, tmpstr); /* overwrite binspec */ } /* copy the remaining string to the rowfilter output... should only */ /* contain a rowfilter expression of the form "[expr]" */ if (rowfilterx && rowfilter[0]) { hasAt = 0; /* Check for multiple expressions, which would appear as "[expr][expr]..." */ ptr1 = rowfilter; while((*ptr1 == '[') && (ptr2 = strstr(rowfilter,"]["))-ptr1 > 2) { /* Advance past any white space */ ptr3 = ptr1+1; while (*ptr3 == ' ') ptr3++; /* Check for @filename.txt */ if (*ptr3 == '@') hasAt = 1; /* Add expression of the form "((expr))&&", note the addition of 6 characters */ if ((strlen(rowfilterx) + (ptr2-ptr1) + 6) > FLEN_FILENAME - 1) { free(infile); return (*status = URL_PARSE_ERROR); } /* Special error checking here. We can't allow there to be a @filename.txt includes if there are multiple row expressions */ if (*rowfilterx && hasAt) { ffpmsg("input URL multiple row filter cannot use @filename.txt"); free(infile); return(*status = URL_PARSE_ERROR); } /* Append the expression */ strcat(rowfilterx, "(("); strncat(rowfilterx, ptr1+1, (ptr2-ptr1-1)); /* Note that strncat always null-terminates the destination string */ strcat(rowfilterx, "))&&"); /* Advance to next expression */ ptr1 = ptr2 + 1; } /* At final iteration, ptr1 points to beginning [ and ptr2 to ending ] */ ptr2 = rowfilter + strlen(rowfilter) - 1; if( *ptr1=='[' && *ptr2==']' ) { /* Check for @include in final position */ ptr3 = ptr1 + 1; while (*ptr3 == ' ') ptr3++; if (*ptr3 == '@') hasAt = 1; /* Check for overflow; add extra 4 characters if we have pre-existing expression */ if (strlen(rowfilterx) + (ptr2-ptr1 + (*rowfilterx)?4:0) > FLEN_FILENAME - 1) { free(infile); return(*status = URL_PARSE_ERROR); } /* Special error checking here. We can't allow there to be a @filename.txt includes if there are multiple row expressions */ if (*rowfilterx && hasAt) { ffpmsg("input URL multiple row filter cannot use @filename.txt"); free(infile); return(*status = URL_PARSE_ERROR); } if (*rowfilterx) { /* A pre-existing row filter: we bracket by ((expr)) to be sure */ strcat(rowfilterx, "(("); strncat(rowfilterx, ptr1+1, (ptr2-ptr1-1)); strcat(rowfilterx, "))"); } else { /* We have only one filter, so just copy the expression alone. This will be the most typical case */ strncat(rowfilterx, ptr1+1, (ptr2-ptr1-1)); } } else { ffpmsg("input file URL lacks valid row filter expression"); *status = URL_PARSE_ERROR; } } free(infile); return(*status); } /*--------------------------------------------------------------------------*/ int ffexist(const char *infile, /* I - input filename or URL */ int *exists, /* O - 2 = a compressed version of file exists */ /* 1 = yes, disk file exists */ /* 0 = no, disk file could not be found */ /* -1 = infile is not a disk file (could */ /* be a http, ftp, gsiftp, smem, or stdin file) */ int *status) /* I/O status */ /* test if the input file specifier is an existing file on disk If the specified file can't be found, it then searches for a compressed version of the file. */ { FILE *diskfile; char rootname[FLEN_FILENAME]; char *ptr1; if (*status > 0) return(*status); /* strip off any extname or filters from the name */ ffrtnm( (char *)infile, rootname, status); ptr1 = strstr(rootname, "://"); if (ptr1 || *rootname == '-') { if (!strncmp(rootname, "file", 4) ) { ptr1 = ptr1 + 3; /* pointer to start of the disk file name */ } else { *exists = -1; /* this is not a disk file */ return (*status); } } else { ptr1 = rootname; } /* see if the disk file exists */ if (file_openfile(ptr1, 0, &diskfile)) { /* no, couldn't open file, so see if there is a compressed version */ if (file_is_compressed(ptr1) ) { *exists = 2; /* a compressed version of the file exists */ } else { *exists = 0; /* neither file nor compressed version exist */ } } else { /* yes, file exists */ *exists = 1; fclose(diskfile); } return(*status); } /*--------------------------------------------------------------------------*/ int ffrtnm(char *url, char *rootname, int *status) /* parse the input URL, returning the root name (filetype://basename). */ { int ii, jj, slen, infilelen; char *ptr1, *ptr2, *ptr3, *ptr4; char urltype[MAX_PREFIX_LEN]; char infile[FLEN_FILENAME]; if (*status > 0) return(*status); ptr1 = url; *rootname = '\0'; *urltype = '\0'; *infile = '\0'; /* get urltype (e.g., file://, ftp://, http://, etc.) */ if (*ptr1 == '-') /* "-" means read file from stdin */ { strcat(urltype, "-"); ptr1++; } else if (!strncmp(ptr1, "stdin", 5) || !strncmp(ptr1, "STDIN", 5)) { strcat(urltype, "-"); ptr1 = ptr1 + 5; } else { ptr2 = strstr(ptr1, "://"); ptr3 = strstr(ptr1, "(" ); if (ptr3 && (ptr3 < ptr2) ) { /* the urltype follows a '(' character, so it must apply */ /* to the output file, and is not the urltype of the input file */ ptr2 = 0; /* so reset pointer to zero */ } if (ptr2) /* copy the explicit urltype string */ { if (ptr2 - ptr1 + 3 > MAX_PREFIX_LEN - 1) { return(*status = URL_PARSE_ERROR); } strncat(urltype, ptr1, ptr2 - ptr1 + 3); ptr1 = ptr2 + 3; } else if (!strncmp(ptr1, "ftp:", 4) ) { /* the 2 //'s are optional */ strcat(urltype, "ftp://"); ptr1 += 4; } else if (!strncmp(ptr1, "gsiftp:", 7) ) { /* the 2 //'s are optional */ strcat(urltype, "gsiftp://"); ptr1 += 7; } else if (!strncmp(ptr1, "http:", 5) ) { /* the 2 //'s are optional */ strcat(urltype, "http://"); ptr1 += 5; } else if (!strncmp(ptr1, "mem:", 4) ) { /* the 2 //'s are optional */ strcat(urltype, "mem://"); ptr1 += 4; } else if (!strncmp(ptr1, "shmem:", 6) ) { /* the 2 //'s are optional */ strcat(urltype, "shmem://"); ptr1 += 6; } else if (!strncmp(ptr1, "file:", 5) ) { /* the 2 //'s are optional */ ptr1 += 5; } /* else assume file driver */ } /* get the input file name */ ptr2 = strchr(ptr1, '('); /* search for opening parenthesis ( */ ptr3 = strchr(ptr1, '['); /* search for opening bracket [ */ if (ptr2) { ptr4 = strchr(ptr2, ')'); while (ptr4 && ptr2) { do { ++ptr4; } while (*ptr4 == ' '); if (*ptr4 == 0 || *ptr4 == '[') break; ptr2 = strchr(ptr2+1, '('); ptr4 = strchr(ptr4, ')'); } } if (ptr2 == ptr3) /* simple case: no [ or ( in the file name */ { if (strlen(ptr1) > FLEN_FILENAME - 1) { return(*status = URL_PARSE_ERROR); } strcat(infile, ptr1); } else if (!ptr3) /* no bracket, so () enclose output file name */ { if (ptr2 - ptr1 > FLEN_FILENAME - 1) { return(*status = URL_PARSE_ERROR); } strncat(infile, ptr1, ptr2 - ptr1); ptr2++; ptr1 = strchr(ptr2, ')' ); /* search for closing ) */ if (!ptr1) return(*status = URL_PARSE_ERROR); /* error, no closing ) */ } else if (ptr2 && (ptr2 < ptr3)) /* () enclose output name before bracket */ { if (ptr2 - ptr1 > FLEN_FILENAME - 1) { return(*status = URL_PARSE_ERROR); } strncat(infile, ptr1, ptr2 - ptr1); ptr2++; ptr1 = strchr(ptr2, ')' ); /* search for closing ) */ if (!ptr1) return(*status = URL_PARSE_ERROR); /* error, no closing ) */ } else /* bracket comes first, so there is no output name */ { if (ptr3 - ptr1 > FLEN_FILENAME - 1) { return(*status = URL_PARSE_ERROR); } strncat(infile, ptr1, ptr3 - ptr1); } /* strip off any trailing blanks in the names */ slen = strlen(infile); for (ii = slen - 1; ii > 0; ii--) { if (infile[ii] == ' ') infile[ii] = '\0'; else break; } /* --------------------------------------------- */ /* check if the 'filename+n' convention has been */ /* used to specifiy which HDU number to open */ /* --------------------------------------------- */ jj = strlen(infile); for (ii = jj - 1; ii >= 0; ii--) { if (infile[ii] == '+') /* search backwards for '+' sign */ break; } if (ii > 0 && (jj - ii) < 5) /* limit extension numbers to 4 digits */ { infilelen = ii; ii++; for (; ii < jj; ii++) { if (!isdigit((int) infile[ii] ) ) /* are all the chars digits? */ break; } if (ii == jj) { /* yes, the '+n' convention was used. */ infile[infilelen] = '\0'; /* delete the extension number */ } } if (strlen(urltype) + strlen(infile) > FLEN_FILENAME - 1) { return(*status = URL_PARSE_ERROR); } strcat(rootname, urltype); /* construct the root name */ strcat(rootname, infile); return(*status); } /*--------------------------------------------------------------------------*/ int ffourl(char *url, /* I - full input URL */ char *urltype, /* O - url type */ char *outfile, /* O - base file name */ char *tpltfile, /* O - template file name, if any */ char *compspec, /* O - compression specification, if any */ int *status) /* parse the output URL into its basic components. */ { char *ptr1, *ptr2, *ptr3; if (*status > 0) return(*status); if (urltype) *urltype = '\0'; if (outfile) *outfile = '\0'; if (tpltfile) *tpltfile = '\0'; if (compspec) *compspec = '\0'; ptr1 = url; while (*ptr1 == ' ') /* ignore leading blanks */ ptr1++; if ( ( (*ptr1 == '-') && ( *(ptr1 +1) == 0 || *(ptr1 +1) == ' ' ) ) || !strcmp(ptr1, "stdout") || !strcmp(ptr1, "STDOUT")) /* "-" means write to stdout; also support "- " */ /* but exclude disk file names that begin with a minus sign */ /* e.g., "-55d33m.fits" */ { if (urltype) strcpy(urltype, "stdout://"); } else { /* not writing to stdout */ /* get urltype (e.g., file://, ftp://, http://, etc.) */ ptr2 = strstr(ptr1, "://"); if (ptr2) /* copy the explicit urltype string */ { if (urltype) { if (ptr2 - ptr1 + 3 > MAX_PREFIX_LEN - 1) { return(*status = URL_PARSE_ERROR); } strncat(urltype, ptr1, ptr2 - ptr1 + 3); } ptr1 = ptr2 + 3; } else /* assume file driver */ { if (urltype) strcat(urltype, "file://"); } /* look for template file name, enclosed in parenthesis */ ptr2 = strchr(ptr1, '('); /* look for image compression parameters, enclosed in sq. brackets */ ptr3 = strchr(ptr1, '['); if (outfile) { if (ptr2) { /* template file was specified */ if (ptr2 - ptr1 > FLEN_FILENAME - 1) { return(*status = URL_PARSE_ERROR); } strncat(outfile, ptr1, ptr2 - ptr1); } else if (ptr3) { /* compression was specified */ if (ptr3 - ptr1 > FLEN_FILENAME - 1) { return(*status = URL_PARSE_ERROR); } strncat(outfile, ptr1, ptr3 - ptr1); } else { /* no template file or compression */ if (strlen(ptr1) > FLEN_FILENAME - 1) { return(*status = URL_PARSE_ERROR); } strcpy(outfile, ptr1); } } if (ptr2) /* template file was specified */ { ptr2++; ptr1 = strchr(ptr2, ')' ); /* search for closing ) */ if (!ptr1) { return(*status = URL_PARSE_ERROR); /* error, no closing ) */ } if (tpltfile) { if (ptr1 - ptr2 > FLEN_FILENAME - 1) { return(*status = URL_PARSE_ERROR); } strncat(tpltfile, ptr2, ptr1 - ptr2); } } if (ptr3) /* compression was specified */ { ptr3++; ptr1 = strchr(ptr3, ']' ); /* search for closing ] */ if (!ptr1) { return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } if (compspec) { if (ptr1 - ptr3 > FLEN_FILENAME - 1) { return(*status = URL_PARSE_ERROR); } strncat(compspec, ptr3, ptr1 - ptr3); } } /* check if a .gz compressed output file is to be created */ /* by seeing if the filename ends in '.gz' */ if (urltype && outfile) { if (!strcmp(urltype, "file://") ) { ptr1 = strstr(outfile, ".gz"); if (ptr1) { /* make sure the ".gz" is at the end of the file name */ ptr1 += 3; if (*ptr1 == 0 || *ptr1 == ' ' ) strcpy(urltype, "compressoutfile://"); } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffexts(char *extspec, int *extnum, char *extname, int *extvers, int *hdutype, char *imagecolname, char *rowexpress, int *status) { /* Parse the input extension specification string, returning either the extension number or the values of the EXTNAME, EXTVERS, and XTENSION keywords in desired extension. Also return the name of the column containing an image, and an expression to be used to determine which row to use, if present. */ char *ptr1, *ptr2; int slen, nvals; int notint = 1; /* initially assume specified extname is not an integer */ char tmpname[FLEN_VALUE], *loc; *extnum = 0; *extname = '\0'; *extvers = 0; *hdutype = ANY_HDU; *imagecolname = '\0'; *rowexpress = '\0'; if (*status > 0) return(*status); ptr1 = extspec; /* pointer to first char */ while (*ptr1 == ' ') /* skip over any leading blanks */ ptr1++; if (isdigit((int) *ptr1)) /* is the extension specification a number? */ { notint = 0; /* looks like extname may actually be the ext. number */ errno = 0; /* reset this prior to calling strtol */ *extnum = strtol(ptr1, &loc, 10); /* read the string as an integer */ while (*loc == ' ') /* skip over trailing blanks */ loc++; /* check for read error, or junk following the integer */ if ((*loc != '\0' && *loc != ';' ) || (errno == ERANGE) ) { *extnum = 0; notint = 1; /* no, extname was not a simple integer after all */ errno = 0; /* reset error condition flag if it was set */ } if ( *extnum < 0 || *extnum > 99999) { *extnum = 0; /* this is not a reasonable extension number */ ffpmsg("specified extension number is out of range:"); ffpmsg(extspec); return(*status = URL_PARSE_ERROR); } } /* This logic was too simple, and failed on extnames like '1000TEMP' where it would try to move to the 1000th extension if (isdigit((int) *ptr1)) { sscanf(ptr1, "%d", extnum); if (*extnum < 0 || *extnum > 9999) { *extnum = 0; ffpmsg("specified extension number is out of range:"); ffpmsg(extspec); return(*status = URL_PARSE_ERROR); } } */ if (notint) { /* not a number, so EXTNAME must be specified, followed by */ /* optional EXTVERS and XTENSION values */ /* don't use space char as end indicator, because there */ /* may be imbedded spaces in the EXTNAME value */ slen = strcspn(ptr1, ",:;"); /* length of EXTNAME */ if (slen > FLEN_VALUE - 1) { return(*status = URL_PARSE_ERROR); } strncat(extname, ptr1, slen); /* EXTNAME value */ /* now remove any trailing blanks */ while (slen > 0 && *(extname + slen -1) == ' ') { *(extname + slen -1) = '\0'; slen--; } ptr1 += slen; slen = strspn(ptr1, " ,:"); /* skip delimiter characters */ ptr1 += slen; slen = strcspn(ptr1, " ,:;"); /* length of EXTVERS */ if (slen) { nvals = sscanf(ptr1, "%d", extvers); /* EXTVERS value */ if (nvals != 1) { ffpmsg("illegal EXTVER value in input URL:"); ffpmsg(extspec); return(*status = URL_PARSE_ERROR); } ptr1 += slen; slen = strspn(ptr1, " ,:"); /* skip delimiter characters */ ptr1 += slen; slen = strcspn(ptr1, ";"); /* length of HDUTYPE */ if (slen) { if (*ptr1 == 'b' || *ptr1 == 'B') *hdutype = BINARY_TBL; else if (*ptr1 == 't' || *ptr1 == 'T' || *ptr1 == 'a' || *ptr1 == 'A') *hdutype = ASCII_TBL; else if (*ptr1 == 'i' || *ptr1 == 'I') *hdutype = IMAGE_HDU; else { ffpmsg("unknown type of HDU in input URL:"); ffpmsg(extspec); return(*status = URL_PARSE_ERROR); } } } else { strcpy(tmpname, extname); ffupch(tmpname); if (!strcmp(tmpname, "PRIMARY") || !strcmp(tmpname, "P") ) *extname = '\0'; /* return extnum = 0 */ } } ptr1 = strchr(ptr1, ';'); if (ptr1) { /* an image is to be opened; the image is contained in a single */ /* cell of a binary table. A column name and an expression to */ /* determine which row to use has been entered. */ ptr1++; /* skip over the ';' delimiter */ while (*ptr1 == ' ') /* skip over any leading blanks */ ptr1++; ptr2 = strchr(ptr1, '('); if (!ptr2) { ffpmsg("illegal specification of image in table cell in input URL:"); ffpmsg(" did not find a row expression enclosed in ( )"); ffpmsg(extspec); return(*status = URL_PARSE_ERROR); } if (ptr2 - ptr1 > FLEN_FILENAME - 1) { return(*status = URL_PARSE_ERROR); } strncat(imagecolname, ptr1, ptr2 - ptr1); /* copy column name */ ptr2++; /* skip over the '(' delimiter */ while (*ptr2 == ' ') /* skip over any leading blanks */ ptr2++; ptr1 = strchr(ptr2, ')'); if (!ptr1) { ffpmsg("illegal specification of image in table cell in input URL:"); ffpmsg(" missing closing ')' character in row expression"); ffpmsg(extspec); return(*status = URL_PARSE_ERROR); } if (ptr1 - ptr2 > FLEN_FILENAME - 1) { return(*status = URL_PARSE_ERROR); } strncat(rowexpress, ptr2, ptr1 - ptr2); /* row expression */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffextn(char *url, /* I - input filename/URL */ int *extension_num, /* O - returned extension number */ int *status) { /* Parse the input url string and return the number of the extension that CFITSIO would automatically move to if CFITSIO were to open this input URL. The extension numbers are one's based, so 1 = the primary array, 2 = the first extension, etc. The extension number that gets returned is determined by the following algorithm: 1. If the input URL includes a binning specification (e.g. 'myfile.fits[3][bin X,Y]') then the returned extension number will always = 1, since CFITSIO would create a temporary primary image on the fly in this case. The same is true if an image within a single cell of a binary table is opened. 2. Else if the input URL specifies an extension number (e.g., 'myfile.fits[3]' or 'myfile.fits+3') then the specified extension number (+ 1) is returned. 3. Else if the extension name is specified in brackets (e.g., this 'myfile.fits[EVENTS]') then the file will be opened and searched for the extension number. If the input URL is '-' (reading from the stdin file stream) this is not possible and an error will be returned. 4. Else if the URL does not specify an extension (e.g. 'myfile.fits') then a special extension number = -99 will be returned to signal that no extension was specified. This feature is mainly for compatibility with existing FTOOLS software. CFITSIO would open the primary array by default (extension_num = 1) in this case. */ fitsfile *fptr; char urltype[20]; char infile[FLEN_FILENAME]; char outfile[FLEN_FILENAME]; char extspec[FLEN_FILENAME]; char extname[FLEN_FILENAME]; char rowfilter[FLEN_FILENAME]; char binspec[FLEN_FILENAME]; char colspec[FLEN_FILENAME]; char imagecolname[FLEN_VALUE], rowexpress[FLEN_FILENAME]; char *cptr; int extnum, extvers, hdutype, tstatus = 0; if (*status > 0) return(*status); /* parse the input URL into its basic components */ fits_parse_input_url(url, urltype, infile, outfile, extspec, rowfilter,binspec, colspec, status); if (*status > 0) return(*status); if (*binspec) /* is there a binning specification? */ { *extension_num = 1; /* a temporary primary array image is created */ return(*status); } if (*extspec) /* is an extension specified? */ { ffexts(extspec, &extnum, extname, &extvers, &hdutype, imagecolname, rowexpress, status); if (*status > 0) return(*status); if (*imagecolname) /* is an image within a table cell being opened? */ { *extension_num = 1; /* a temporary primary array image is created */ return(*status); } if (*extname) { /* have to open the file to search for the extension name (curses!) */ if (!strcmp(urltype, "stdin://")) /* opening stdin would destroying it! */ return(*status = URL_PARSE_ERROR); /* First, strip off any filtering specification */ infile[0] = '\0'; strncat(infile, url, FLEN_FILENAME -1); cptr = strchr(infile, ']'); /* locate the closing bracket */ if (!cptr) { return(*status = URL_PARSE_ERROR); } else { cptr++; *cptr = '\0'; /* terminate URl after the extension spec */ } if (ffopen(&fptr, infile, READONLY, status) > 0) /* open the file */ { ffclos(fptr, &tstatus); return(*status); } ffghdn(fptr, &extnum); /* where am I in the file? */ *extension_num = extnum; ffclos(fptr, status); return(*status); } else { *extension_num = extnum + 1; /* return the specified number (+ 1) */ return(*status); } } else { *extension_num = -99; /* no specific extension was specified */ /* defaults to primary array */ return(*status); } } /*--------------------------------------------------------------------------*/ int ffurlt(fitsfile *fptr, char *urlType, int *status) /* return the prefix string associated with the driver in use by the fitsfile pointer fptr */ { strcpy(urlType, driverTable[fptr->Fptr->driver].prefix); return(*status); } /*--------------------------------------------------------------------------*/ int ffimport_file( char *filename, /* Text file to read */ char **contents, /* Pointer to pointer to hold file */ int *status ) /* CFITSIO error code */ /* Read and concatenate all the lines from the given text file. User must free the pointer returned in contents. Pointer is guaranteed to hold 2 characters more than the length of the text... allows the calling routine to append (or prepend) a newline (or quotes?) without reallocating memory. */ { int allocLen, totalLen, llen, eoline = 1; char *lines,line[256]; FILE *aFile; if( *status > 0 ) return( *status ); totalLen = 0; allocLen = 1024; lines = (char *)malloc( allocLen * sizeof(char) ); if( !lines ) { ffpmsg("Couldn't allocate memory to hold ASCII file contents."); return(*status = MEMORY_ALLOCATION ); } lines[0] = '\0'; if( (aFile = fopen( filename, "r" ))==NULL ) { snprintf(line,256,"Could not open ASCII file %s.",filename); ffpmsg(line); free( lines ); return(*status = FILE_NOT_OPENED); } while( fgets(line,256,aFile)!=NULL ) { llen = strlen(line); if ( eoline && (llen > 1) && (line[0] == '/' && line[1] == '/')) continue; /* skip comment lines begging with // */ eoline = 0; /* replace CR and newline chars at end of line with nulls */ if ((llen > 0) && (line[llen-1]=='\n' || line[llen-1] == '\r')) { line[--llen] = '\0'; eoline = 1; /* found an end of line character */ if ((llen > 0) && (line[llen-1]=='\n' || line[llen-1] == '\r')) { line[--llen] = '\0'; } } if( totalLen + llen + 3 >= allocLen ) { allocLen += 256; lines = (char *)realloc(lines, allocLen * sizeof(char) ); if( ! lines ) { ffpmsg("Couldn't allocate memory to hold ASCII file contents."); *status = MEMORY_ALLOCATION; break; } } strcpy( lines+totalLen, line ); totalLen += llen; if (eoline) { strcpy( lines+totalLen, " "); /* add a space between lines */ totalLen += 1; } } fclose(aFile); *contents = lines; return( *status ); } /*--------------------------------------------------------------------------*/ int fits_get_token(char **ptr, char *delimiter, char *token, int *isanumber) /* O - is this token a number? */ /* parse off the next token, delimited by a character in 'delimiter', from the input ptr string; increment *ptr to the end of the token. Returns the length of the token, not including the delimiter char; */ { char *loc, tval[73]; int slen; double dval; *token = '\0'; while (**ptr == ' ') /* skip over leading blanks */ (*ptr)++; slen = strcspn(*ptr, delimiter); /* length of next token */ if (slen) { strncat(token, *ptr, slen); /* copy token */ (*ptr) += slen; /* skip over the token */ if (isanumber) /* check if token is a number */ { *isanumber = 1; if (strchr(token, 'D')) { strncpy(tval, token, 72); tval[72] = '\0'; /* The C language does not support a 'D'; replace with 'E' */ if ((loc = strchr(tval, 'D'))) *loc = 'E'; dval = strtod(tval, &loc); } else { dval = strtod(token, &loc); } /* check for read error, or junk following the value */ if (*loc != '\0' && *loc != ' ' ) *isanumber = 0; if (errno == ERANGE) *isanumber = 0; } } return(slen); } /*--------------------------------------------------------------------------*/ int fits_get_token2(char **ptr, char *delimiter, char **token, int *isanumber, /* O - is this token a number? */ int *status) /* parse off the next token, delimited by a character in 'delimiter', from the input ptr string; increment *ptr to the end of the token. Returns the length of the token, not including the delimiter char; This routine allocates the *token string; the calling routine must free it */ { char *loc, tval[73]; int slen; double dval; if (*status) return(0); while (**ptr == ' ') /* skip over leading blanks */ (*ptr)++; slen = strcspn(*ptr, delimiter); /* length of next token */ if (slen) { *token = (char *) calloc(slen + 1, 1); if (!(*token)) { ffpmsg("Couldn't allocate memory to hold token string (fits_get_token2)."); *status = MEMORY_ALLOCATION ; return(0); } strncat(*token, *ptr, slen); /* copy token */ (*ptr) += slen; /* skip over the token */ if (isanumber) /* check if token is a number */ { *isanumber = 1; if (strchr(*token, 'D')) { strncpy(tval, *token, 72); tval[72] = '\0'; /* The C language does not support a 'D'; replace with 'E' */ if ((loc = strchr(tval, 'D'))) *loc = 'E'; dval = strtod(tval, &loc); } else { dval = strtod(*token, &loc); } /* check for read error, or junk following the value */ if (*loc != '\0' && *loc != ' ' ) *isanumber = 0; if (errno == ERANGE) *isanumber = 0; } } return(slen); } /*---------------------------------------------------------------------------*/ char *fits_split_names( char *list) /* I - input list of names */ { /* A sequence of calls to fits_split_names will split the input string into name tokens. The string typically contains a list of file or column names. The names must be delimited by a comma and/or spaces. This routine ignores spaces and commas that occur within parentheses, brackets, or curly brackets. It also strips any leading and trailing blanks from the returned name. This routine is similar to the ANSI C 'strtok' function: The first call to fits_split_names has a non-null input string. It finds the first name in the string and terminates it by overwriting the next character of the string with a '\0' and returns a pointer to the name. Each subsequent call, indicated by a NULL value of the input string, returns the next name, searching from just past the end of the previous name. It returns NULL when no further names are found. The following line illustrates how a string would be split into 3 names: myfile[1][bin (x,y)=4], file2.fits file3.fits ^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^ 1st name 2nd name 3rd name NOTE: This routine is not thread-safe. This routine is simply provided as a utility routine for other external software. It is not used by any CFITSIO routine. */ int depth = 0; char *start; static char *ptr; if (list) /* reset ptr if a string is given */ ptr = list; while (*ptr == ' ')ptr++; /* skip leading white space */ if (*ptr == '\0')return(0); /* no remaining file names */ start = ptr; while (*ptr != '\0') { if ((*ptr == '[') || (*ptr == '(') || (*ptr == '{')) depth ++; else if ((*ptr == '}') || (*ptr == ')') || (*ptr == ']')) depth --; else if ((depth == 0) && (*ptr == ',' || *ptr == ' ')) { *ptr = '\0'; /* terminate the filename here */ ptr++; /* save pointer to start of next filename */ break; } ptr++; } return(start); } /*--------------------------------------------------------------------------*/ int urltype2driver(char *urltype, int *driver) /* compare input URL with list of known drivers, returning the matching driver numberL. */ { int ii; /* find matching driver; search most recent drivers first */ for (ii=no_of_drivers - 1; ii >= 0; ii--) { if (0 == strcmp(driverTable[ii].prefix, urltype)) { *driver = ii; return(0); } } return(NO_MATCHING_DRIVER); } /*--------------------------------------------------------------------------*/ int ffclos(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* close the FITS file by completing the current HDU, flushing it to disk, then calling the system dependent routine to physically close the FITS file */ { int tstatus = NO_CLOSE_ERROR, zerostatus = 0; if (!fptr) return(*status = NULL_INPUT_PTR); else if ((fptr->Fptr)->validcode != VALIDSTRUC) /* check for magic value */ return(*status = BAD_FILEPTR); /* close and flush the current HDU */ if (*status > 0) ffchdu(fptr, &tstatus); /* turn off the error message from ffchdu */ else ffchdu(fptr, status); ((fptr->Fptr)->open_count)--; /* decrement usage counter */ if ((fptr->Fptr)->open_count == 0) /* if no other files use structure */ { ffflsh(fptr, TRUE, status); /* flush and disassociate IO buffers */ /* call driver function to actually close the file */ if ((*driverTable[(fptr->Fptr)->driver].close)((fptr->Fptr)->filehandle)) { if (*status <= 0) { *status = FILE_NOT_CLOSED; /* report if no previous error */ ffpmsg("failed to close the following file: (ffclos)"); ffpmsg((fptr->Fptr)->filename); } } fits_clear_Fptr( fptr->Fptr, status); /* clear Fptr address */ free((fptr->Fptr)->iobuffer); /* free memory for I/O buffers */ free((fptr->Fptr)->headstart); /* free memory for headstart array */ free((fptr->Fptr)->filename); /* free memory for the filename */ (fptr->Fptr)->filename = 0; (fptr->Fptr)->validcode = 0; /* magic value to indicate invalid fptr */ free(fptr->Fptr); /* free memory for the FITS file structure */ free(fptr); /* free memory for the FITS file structure */ } else { /* to minimize the fallout from any previous error (e.g., trying to open a non-existent extension in a already opened file), always call ffflsh with status = 0. */ /* just flush the buffers, don't disassociate them */ if (*status > 0) ffflsh(fptr, FALSE, &zerostatus); else ffflsh(fptr, FALSE, status); free(fptr); /* free memory for the FITS file structure */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffdelt(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* close and DELETE the FITS file. */ { char *basename; int slen, tstatus = NO_CLOSE_ERROR, zerostatus = 0; if (!fptr) return(*status = NULL_INPUT_PTR); else if ((fptr->Fptr)->validcode != VALIDSTRUC) /* check for magic value */ return(*status = BAD_FILEPTR); if (*status > 0) ffchdu(fptr, &tstatus); /* turn off the error message from ffchdu */ else ffchdu(fptr, status); ffflsh(fptr, TRUE, status); /* flush and disassociate IO buffers */ /* call driver function to actually close the file */ if ( (*driverTable[(fptr->Fptr)->driver].close)((fptr->Fptr)->filehandle) ) { if (*status <= 0) { *status = FILE_NOT_CLOSED; /* report error if no previous error */ ffpmsg("failed to close the following file: (ffdelt)"); ffpmsg((fptr->Fptr)->filename); } } /* call driver function to actually delete the file */ if ( (driverTable[(fptr->Fptr)->driver].remove) ) { /* parse the input URL to get the base filename */ slen = strlen((fptr->Fptr)->filename); basename = (char *) malloc(slen +1); if (!basename) return(*status = MEMORY_ALLOCATION); fits_parse_input_url((fptr->Fptr)->filename, NULL, basename, NULL, NULL, NULL, NULL, NULL, &zerostatus); if ((*driverTable[(fptr->Fptr)->driver].remove)(basename)) { ffpmsg("failed to delete the following file: (ffdelt)"); ffpmsg((fptr->Fptr)->filename); if (!(*status)) *status = FILE_NOT_CLOSED; } free(basename); } fits_clear_Fptr( fptr->Fptr, status); /* clear Fptr address */ free((fptr->Fptr)->iobuffer); /* free memory for I/O buffers */ free((fptr->Fptr)->headstart); /* free memory for headstart array */ free((fptr->Fptr)->filename); /* free memory for the filename */ (fptr->Fptr)->filename = 0; (fptr->Fptr)->validcode = 0; /* magic value to indicate invalid fptr */ free(fptr->Fptr); /* free memory for the FITS file structure */ free(fptr); /* free memory for the FITS file structure */ return(*status); } /*--------------------------------------------------------------------------*/ int fftrun( fitsfile *fptr, /* I - FITS file pointer */ LONGLONG filesize, /* I - size to truncate the file */ int *status) /* O - error status */ /* low level routine to truncate a file to a new smaller size. */ { if (driverTable[(fptr->Fptr)->driver].truncate) { ffflsh(fptr, FALSE, status); /* flush all the buffers first */ (fptr->Fptr)->filesize = filesize; (fptr->Fptr)->io_pos = filesize; (fptr->Fptr)->logfilesize = filesize; (fptr->Fptr)->bytepos = filesize; ffbfeof(fptr, status); /* eliminate any buffers beyond current EOF */ return (*status = (*driverTable[(fptr->Fptr)->driver].truncate)((fptr->Fptr)->filehandle, filesize) ); } else return(*status); } /*--------------------------------------------------------------------------*/ int ffflushx( FITSfile *fptr) /* I - FITS file pointer */ /* low level routine to flush internal file buffers to the file. */ { if (driverTable[fptr->driver].flush) return ( (*driverTable[fptr->driver].flush)(fptr->filehandle) ); else return(0); /* no flush function defined for this driver */ } /*--------------------------------------------------------------------------*/ int ffseek( FITSfile *fptr, /* I - FITS file pointer */ LONGLONG position) /* I - byte position to seek to */ /* low level routine to seek to a position in a file. */ { return( (*driverTable[fptr->driver].seek)(fptr->filehandle, position) ); } /*--------------------------------------------------------------------------*/ int ffwrite( FITSfile *fptr, /* I - FITS file pointer */ long nbytes, /* I - number of bytes to write */ void *buffer, /* I - buffer to write */ int *status) /* O - error status */ /* low level routine to write bytes to a file. */ { if ( (*driverTable[fptr->driver].write)(fptr->filehandle, buffer, nbytes) ) { ffpmsg("Error writing data buffer to file:"); ffpmsg(fptr->filename); *status = WRITE_ERROR; } return(*status); } /*--------------------------------------------------------------------------*/ int ffread( FITSfile *fptr, /* I - FITS file pointer */ long nbytes, /* I - number of bytes to read */ void *buffer, /* O - buffer to read into */ int *status) /* O - error status */ /* low level routine to read bytes from a file. */ { int readstatus; readstatus = (*driverTable[fptr->driver].read)(fptr->filehandle, buffer, nbytes); if (readstatus == END_OF_FILE) *status = END_OF_FILE; else if (readstatus > 0) { ffpmsg("Error reading data buffer from file:"); ffpmsg(fptr->filename); *status = READ_ERROR; } return(*status); } /*--------------------------------------------------------------------------*/ int fftplt(fitsfile **fptr, /* O - FITS file pointer */ const char *filename, /* I - name of file to create */ const char *tempname, /* I - name of template file */ int *status) /* IO - error status */ /* Create and initialize a new FITS file based on a template file. Uses C fopen and fgets functions. */ { *fptr = 0; /* initialize null file pointer, */ /* regardless of the value of *status */ if (*status > 0) return(*status); if ( ffinit(fptr, filename, status) ) /* create empty file */ return(*status); ffoptplt(*fptr, tempname, status); /* open and use template */ return(*status); } /*--------------------------------------------------------------------------*/ int ffoptplt(fitsfile *fptr, /* O - FITS file pointer */ const char *tempname, /* I - name of template file */ int *status) /* IO - error status */ /* open template file and use it to create new file */ { fitsfile *tptr; int tstatus = 0, nkeys, nadd, ii; char card[FLEN_CARD]; if (*status > 0) return(*status); if (tempname == NULL || *tempname == '\0') /* no template file? */ return(*status); /* try opening template */ ffopen(&tptr, (char *) tempname, READONLY, &tstatus); if (tstatus) /* not a FITS file, so treat it as an ASCII template */ { ffxmsg(2, card); /* clear the error message */ fits_execute_template(fptr, (char *) tempname, status); ffmahd(fptr, 1, 0, status); /* move back to the primary array */ return(*status); } else /* template is a valid FITS file */ { ffmahd(tptr, 1, NULL, status); /* make sure we are at the beginning */ while (*status <= 0) { ffghsp(tptr, &nkeys, &nadd, status); /* get no. of keywords */ for (ii = 1; ii <= nkeys; ii++) /* copy keywords */ { ffgrec(tptr, ii, card, status); /* must reset the PCOUNT keyword to zero in the new output file */ if (strncmp(card, "PCOUNT ",8) == 0) { /* the PCOUNT keyword? */ if (strncmp(card+25, " 0", 5)) { /* non-zero value? */ strncpy(card, "PCOUNT = 0", 30); } } ffprec(fptr, card, status); } ffmrhd(tptr, 1, 0, status); /* move to next HDU until error */ ffcrhd(fptr, status); /* create empty new HDU in output file */ } if (*status == END_OF_FILE) { *status = 0; /* expected error condition */ } ffclos(tptr, status); /* close the template file */ } ffmahd(fptr, 1, 0, status); /* move to the primary array */ return(*status); } /*--------------------------------------------------------------------------*/ void ffrprt( FILE *stream, int status) /* Print out report of cfitsio error status and messages on the error stack. Uses C FILE stream. */ { char status_str[FLEN_STATUS], errmsg[FLEN_ERRMSG]; if (status) { fits_get_errstatus(status, status_str); /* get the error description */ fprintf(stream, "\nFITSIO status = %d: %s\n", status, status_str); while ( fits_read_errmsg(errmsg) ) /* get error stack messages */ fprintf(stream, "%s\n", errmsg); } return; } /*--------------------------------------------------------------------------*/ int pixel_filter_helper( fitsfile **fptr, /* IO - pointer to input image; on output it */ /* points to the new image */ char *outfile, /* I - name for output file */ char *expr, /* I - Image filter expression */ int *status) { PixelFilter filter = { 0 }; char * DEFAULT_TAG = "X"; int ii, hdunum; int singleHDU = 0; filter.count = 1; filter.ifptr = fptr; filter.tag = &DEFAULT_TAG; /* create new empty file for result */ if (ffinit(&filter.ofptr, outfile, status) > 0) { ffpmsg("failed to create output file for pixel filter:"); ffpmsg(outfile); return(*status); } fits_get_hdu_num(*fptr, &hdunum); /* current HDU number in input file */ expr += 3; /* skip 'pix' */ switch (expr[0]) { case 'b': case 'B': filter.bitpix = BYTE_IMG; break; case 'i': case 'I': filter.bitpix = SHORT_IMG; break; case 'j': case 'J': filter.bitpix = LONG_IMG; break; case 'r': case 'R': filter.bitpix = FLOAT_IMG; break; case 'd': case 'D': filter.bitpix = DOUBLE_IMG; break; } if (filter.bitpix) /* skip bitpix indicator */ ++expr; if (*expr == '1') { ++expr; singleHDU = 1; } if (((*fptr)->Fptr)->only_one) singleHDU = 1; if (*expr != ' ') { ffpmsg("pixel filtering expression not space separated:"); ffpmsg(expr); } while (*expr == ' ') ++expr; /* copy all preceding extensions to the output file */ for (ii = 1; !singleHDU && ii < hdunum; ii++) { fits_movabs_hdu(*fptr, ii, NULL, status); if (fits_copy_hdu(*fptr, filter.ofptr, 0, status) > 0) { ffclos(filter.ofptr, status); return(*status); } } /* move back to the original HDU position */ fits_movabs_hdu(*fptr, hdunum, NULL, status); filter.expression = expr; if (fits_pixel_filter(&filter, status)) { ffpmsg("failed to execute image filter:"); ffpmsg(expr); ffclos(filter.ofptr, status); return(*status); } /* copy any remaining HDUs to the output file */ for (ii = hdunum + 1; !singleHDU; ii++) { if (fits_movabs_hdu(*fptr, ii, NULL, status) > 0) break; fits_copy_hdu(*fptr, filter.ofptr, 0, status); } if (*status == END_OF_FILE) *status = 0; /* got the expected EOF error; reset = 0 */ else if (*status > 0) { ffclos(filter.ofptr, status); return(*status); } /* close the original file and return ptr to the new image */ ffclos(*fptr, status); *fptr = filter.ofptr; /* reset the pointer to the new table */ /* move back to the image subsection */ if (ii - 1 != hdunum) fits_movabs_hdu(*fptr, hdunum, NULL, status); return(*status); } /*-------------------------------------------------------------------*/ int ffihtps(void) { /* Wrapper function for global initialization of curl library. This is NOT THREAD-SAFE */ int status=0; #ifdef CFITSIO_HAVE_CURL if (curl_global_init(CURL_GLOBAL_ALL)) /* Do we want to define a new CFITSIO error code for this? */ status = -1; #endif return status; } /*-------------------------------------------------------------------*/ int ffchtps(void) { /* Wrapper function for global cleanup of curl library. This is NOT THREAD-SAFE */ #ifdef CFITSIO_HAVE_CURL curl_global_cleanup(); #endif return 0; } /*-------------------------------------------------------------------*/ void ffvhtps(int flag) { /* Turn libcurl's verbose output on (1) or off (0). This is NOT THREAD-SAFE */ #ifdef HAVE_NET_SERVICES https_set_verbose(flag); #endif } /*-------------------------------------------------------------------*/ void ffshdwn(int flag) { /* Display download status bar (to stderr), where applicable. This is NOT THREAD-SAFE */ #ifdef HAVE_NET_SERVICES fits_dwnld_prog_bar(flag); #endif } /*-------------------------------------------------------------------*/ int ffgtmo(void) { int timeout=0; #ifdef HAVE_NET_SERVICES timeout = fits_net_timeout(-1); #endif return timeout; } /*-------------------------------------------------------------------*/ int ffstmo(int sec, int *status) { if (*status > 0) return (*status); #ifdef HAVE_NET_SERVICES if (sec <= 0) { *status = BAD_NETTIMEOUT; ffpmsg("Bad value for net timeout setting (fits_set_timeout)."); return(*status); } fits_net_timeout(sec); #endif return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/checksum.c0000644000175100001710000004230100000000000020071 0ustar00vstsdocker/* This file, checksum.c, contains the checksum-related routines in the */ /* FITSIO library. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include "fitsio2.h" /*------------------------------------------------------------------------*/ int ffcsum(fitsfile *fptr, /* I - FITS file pointer */ long nrec, /* I - number of 2880-byte blocks to sum */ unsigned long *sum, /* IO - accumulated checksum */ int *status) /* IO - error status */ /* Calculate a 32-bit 1's complement checksum of the FITS 2880-byte blocks. This routine is based on the C algorithm developed by Rob Seaman at NOAO that was presented at the 1994 ADASS conference, published in the Astronomical Society of the Pacific Conference Series. This uses a 32-bit 1's complement checksum in which the overflow bits are permuted back into the sum and therefore all bit positions are sampled evenly. */ { long ii, jj; unsigned short sbuf[1440]; unsigned long hi, lo, hicarry, locarry; if (*status > 0) return(*status); /* Sum the specified number of FITS 2880-byte records. This assumes that the FITSIO file pointer points to the start of the records to be summed. Read each FITS block as 1440 short values (do byte swapping if needed). */ for (jj = 0; jj < nrec; jj++) { ffgbyt(fptr, 2880, sbuf, status); #if BYTESWAPPED ffswap2( (short *)sbuf, 1440); /* reverse order of bytes in each value */ #endif hi = (*sum >> 16); lo = *sum & 0xFFFF; for (ii = 0; ii < 1440; ii += 2) { hi += sbuf[ii]; lo += sbuf[ii+1]; } hicarry = hi >> 16; /* fold carry bits in */ locarry = lo >> 16; while (hicarry | locarry) { hi = (hi & 0xFFFF) + locarry; lo = (lo & 0xFFFF) + hicarry; hicarry = hi >> 16; locarry = lo >> 16; } *sum = (hi << 16) + lo; } return(*status); } /*-------------------------------------------------------------------------*/ void ffesum(unsigned long sum, /* I - accumulated checksum */ int complm, /* I - = 1 to encode complement of the sum */ char *ascii) /* O - 16-char ASCII encoded checksum */ /* encode the 32 bit checksum by converting every 2 bits of each byte into an ASCII character (32 bit word encoded as 16 character string). Only ASCII letters and digits are used to encode the values (no ASCII punctuation characters). If complm=TRUE, then the complement of the sum will be encoded. This routine is based on the C algorithm developed by Rob Seaman at NOAO that was presented at the 1994 ADASS conference, published in the Astronomical Society of the Pacific Conference Series. */ { unsigned int exclude[13] = { 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60 }; unsigned long mask[4] = { 0xff000000, 0xff0000, 0xff00, 0xff }; int offset = 0x30; /* ASCII 0 (zero) */ unsigned long value; int byte, quotient, remainder, ch[4], check, ii, jj, kk; char asc[32]; if (complm) value = 0xFFFFFFFF - sum; /* complement each bit of the value */ else value = sum; for (ii = 0; ii < 4; ii++) { byte = (value & mask[ii]) >> (24 - (8 * ii)); quotient = byte / 4 + offset; remainder = byte % 4; for (jj = 0; jj < 4; jj++) ch[jj] = quotient; ch[0] += remainder; for (check = 1; check;) /* avoid ASCII punctuation */ for (check = 0, kk = 0; kk < 13; kk++) for (jj = 0; jj < 4; jj += 2) if ((unsigned char) ch[jj] == exclude[kk] || (unsigned char) ch[jj+1] == exclude[kk]) { ch[jj]++; ch[jj+1]--; check++; } for (jj = 0; jj < 4; jj++) /* assign the bytes */ asc[4*jj+ii] = ch[jj]; } for (ii = 0; ii < 16; ii++) /* shift the bytes 1 to the right */ ascii[ii] = asc[(ii+15)%16]; ascii[16] = '\0'; } /*-------------------------------------------------------------------------*/ unsigned long ffdsum(char *ascii, /* I - 16-char ASCII encoded checksum */ int complm, /* I - =1 to decode complement of the */ unsigned long *sum) /* O - 32-bit checksum */ /* decode the 16-char ASCII encoded checksum into an unsigned 32-bit long. If complm=TRUE, then the complement of the sum will be decoded. This routine is based on the C algorithm developed by Rob Seaman at NOAO that was presented at the 1994 ADASS conference, published in the Astronomical Society of the Pacific Conference Series. */ { char cbuf[16]; unsigned long hi = 0, lo = 0, hicarry, locarry; int ii; /* remove the permuted FITS byte alignment and the ASCII 0 offset */ for (ii = 0; ii < 16; ii++) { cbuf[ii] = ascii[(ii+1)%16]; cbuf[ii] -= 0x30; } for (ii = 0; ii < 16; ii += 4) { hi += (cbuf[ii] << 8) + cbuf[ii+1]; lo += (cbuf[ii+2] << 8) + cbuf[ii+3]; } hicarry = hi >> 16; locarry = lo >> 16; while (hicarry || locarry) { hi = (hi & 0xFFFF) + locarry; lo = (lo & 0xFFFF) + hicarry; hicarry = hi >> 16; locarry = lo >> 16; } *sum = (hi << 16) + lo; if (complm) *sum = 0xFFFFFFFF - *sum; /* complement each bit of the value */ return(*sum); } /*------------------------------------------------------------------------*/ int ffpcks(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* Create or update the checksum keywords in the CHDU. These keywords provide a checksum verification of the FITS HDU based on the ASCII coded 1's complement checksum algorithm developed by Rob Seaman at NOAO. */ { char datestr[20], checksum[FLEN_VALUE], datasum[FLEN_VALUE]; char comm[FLEN_COMMENT], chkcomm[FLEN_COMMENT], datacomm[FLEN_COMMENT]; int tstatus; long nrec; LONGLONG headstart, datastart, dataend; unsigned long dsum, olddsum, sum; double tdouble; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* generate current date string and construct the keyword comments */ ffgstm(datestr, NULL, status); strcpy(chkcomm, "HDU checksum updated "); strcat(chkcomm, datestr); strcpy(datacomm, "data unit checksum updated "); strcat(datacomm, datestr); /* write the CHECKSUM keyword if it does not exist */ tstatus = *status; if (ffgkys(fptr, "CHECKSUM", checksum, comm, status) == KEY_NO_EXIST) { *status = tstatus; strcpy(checksum, "0000000000000000"); ffpkys(fptr, "CHECKSUM", checksum, chkcomm, status); } /* write the DATASUM keyword if it does not exist */ tstatus = *status; if (ffgkys(fptr, "DATASUM", datasum, comm, status) == KEY_NO_EXIST) { *status = tstatus; olddsum = 0; ffpkys(fptr, "DATASUM", " 0", datacomm, status); /* set the CHECKSUM keyword as undefined, if it isn't already */ if (strcmp(checksum, "0000000000000000") ) { strcpy(checksum, "0000000000000000"); ffmkys(fptr, "CHECKSUM", checksum, chkcomm, status); } } else { /* decode the datasum into an unsigned long variable */ /* olddsum = strtoul(datasum, 0, 10); doesn't work on SUN OS */ tdouble = atof(datasum); olddsum = (unsigned long) tdouble; } /* close header: rewrite END keyword and following blank fill */ /* and re-read the required keywords to determine the structure */ if (ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->heapsize > 0) ffuptf(fptr, status); /* update the variable length TFORM values */ /* write the correct data fill values, if they are not already correct */ if (ffpdfl(fptr, status) > 0) return(*status); /* calc size of data unit, in FITS 2880-byte blocks */ if (ffghadll(fptr, &headstart, &datastart, &dataend, status) > 0) return(*status); nrec = (long) ((dataend - datastart) / 2880); dsum = 0; if (nrec > 0) { /* accumulate the 32-bit 1's complement checksum */ ffmbyt(fptr, datastart, REPORT_EOF, status); if (ffcsum(fptr, nrec, &dsum, status) > 0) return(*status); } if (dsum != olddsum) { /* update the DATASUM keyword with the correct value */ snprintf(datasum, FLEN_VALUE, "%lu", dsum); ffmkys(fptr, "DATASUM", datasum, datacomm, status); /* set the CHECKSUM keyword as undefined, if it isn't already */ if (strcmp(checksum, "0000000000000000") ) { strcpy(checksum, "0000000000000000"); ffmkys(fptr, "CHECKSUM", checksum, chkcomm, status); } } if (strcmp(checksum, "0000000000000000") ) { /* check if CHECKSUM is still OK; move to the start of the header */ ffmbyt(fptr, headstart, REPORT_EOF, status); /* accumulate the header checksum into the previous data checksum */ nrec = (long) ((datastart - headstart) / 2880); sum = dsum; if (ffcsum(fptr, nrec, &sum, status) > 0) return(*status); if (sum == 0 || sum == 0xFFFFFFFF) return(*status); /* CHECKSUM is correct */ /* Zero the CHECKSUM and recompute the new value */ ffmkys(fptr, "CHECKSUM", "0000000000000000", chkcomm, status); } /* move to the start of the header */ ffmbyt(fptr, headstart, REPORT_EOF, status); /* accumulate the header checksum into the previous data checksum */ nrec = (long) ((datastart - headstart) / 2880); sum = dsum; if (ffcsum(fptr, nrec, &sum, status) > 0) return(*status); /* encode the COMPLEMENT of the checksum into a 16-character string */ ffesum(sum, TRUE, checksum); /* update the CHECKSUM keyword value with the new string */ ffmkys(fptr, "CHECKSUM", checksum, "&", status); return(*status); } /*------------------------------------------------------------------------*/ int ffupck(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* Update the CHECKSUM keyword value. This assumes that the DATASUM keyword exists and has the correct value. */ { char datestr[20], chkcomm[FLEN_COMMENT], comm[FLEN_COMMENT]; char checksum[FLEN_VALUE], datasum[FLEN_VALUE]; int tstatus; long nrec; LONGLONG headstart, datastart, dataend; unsigned long sum, dsum; double tdouble; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* generate current date string and construct the keyword comments */ ffgstm(datestr, NULL, status); strcpy(chkcomm, "HDU checksum updated "); strcat(chkcomm, datestr); /* get the DATASUM keyword and convert it to a unsigned long */ if (ffgkys(fptr, "DATASUM", datasum, comm, status) == KEY_NO_EXIST) { ffpmsg("DATASUM keyword not found (ffupck"); return(*status); } tdouble = atof(datasum); /* read as a double as a workaround */ dsum = (unsigned long) tdouble; /* get size of the HDU */ if (ffghadll(fptr, &headstart, &datastart, &dataend, status) > 0) return(*status); /* get the checksum keyword, if it exists */ tstatus = *status; if (ffgkys(fptr, "CHECKSUM", checksum, comm, status) == KEY_NO_EXIST) { *status = tstatus; strcpy(checksum, "0000000000000000"); ffpkys(fptr, "CHECKSUM", checksum, chkcomm, status); } else { /* check if CHECKSUM is still OK */ /* rewrite END keyword and following blank fill */ if (ffwend(fptr, status) > 0) return(*status); /* move to the start of the header */ ffmbyt(fptr, headstart, REPORT_EOF, status); /* accumulate the header checksum into the previous data checksum */ nrec = (long) ((datastart - headstart) / 2880); sum = dsum; if (ffcsum(fptr, nrec, &sum, status) > 0) return(*status); if (sum == 0 || sum == 0xFFFFFFFF) return(*status); /* CHECKSUM is already correct */ /* Zero the CHECKSUM and recompute the new value */ ffmkys(fptr, "CHECKSUM", "0000000000000000", chkcomm, status); } /* move to the start of the header */ ffmbyt(fptr, headstart, REPORT_EOF, status); /* accumulate the header checksum into the previous data checksum */ nrec = (long) ((datastart - headstart) / 2880); sum = dsum; if (ffcsum(fptr, nrec, &sum, status) > 0) return(*status); /* encode the COMPLEMENT of the checksum into a 16-character string */ ffesum(sum, TRUE, checksum); /* update the CHECKSUM keyword value with the new string */ ffmkys(fptr, "CHECKSUM", checksum, "&", status); return(*status); } /*------------------------------------------------------------------------*/ int ffvcks(fitsfile *fptr, /* I - FITS file pointer */ int *datastatus, /* O - data checksum status */ int *hdustatus, /* O - hdu checksum status */ /* 1 verification is correct */ /* 0 checksum keyword is not present */ /* -1 verification not correct */ int *status) /* IO - error status */ /* Verify the HDU by comparing the value of the computed checksums against the values of the DATASUM and CHECKSUM keywords if they are present. */ { int tstatus; double tdouble; unsigned long datasum, hdusum, olddatasum; char chksum[FLEN_VALUE], comm[FLEN_COMMENT]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); *datastatus = -1; *hdustatus = -1; tstatus = *status; if (ffgkys(fptr, "CHECKSUM", chksum, comm, status) == KEY_NO_EXIST) { *hdustatus = 0; /* CHECKSUM keyword does not exist */ *status = tstatus; } if (chksum[0] == '\0') *hdustatus = 0; /* all blank checksum means it is undefined */ if (ffgkys(fptr, "DATASUM", chksum, comm, status) == KEY_NO_EXIST) { *datastatus = 0; /* DATASUM keyword does not exist */ *status = tstatus; } if (chksum[0] == '\0') *datastatus = 0; /* all blank checksum means it is undefined */ if ( *status > 0 || (!(*hdustatus) && !(*datastatus)) ) return(*status); /* return if neither keywords exist */ /* convert string to unsigned long */ /* olddatasum = strtoul(chksum, 0, 10); doesn't work w/ gcc on SUN OS */ /* sscanf(chksum, "%u", &olddatasum); doesn't work w/ cc on VAX/VMS */ tdouble = atof(chksum); /* read as a double as a workaround */ olddatasum = (unsigned long) tdouble; /* calculate the data checksum and the HDU checksum */ if (ffgcks(fptr, &datasum, &hdusum, status) > 0) return(*status); if (*datastatus) if (datasum == olddatasum) *datastatus = 1; if (*hdustatus) if (hdusum == 0 || hdusum == 0xFFFFFFFF) *hdustatus = 1; return(*status); } /*------------------------------------------------------------------------*/ int ffgcks(fitsfile *fptr, /* I - FITS file pointer */ unsigned long *datasum, /* O - data checksum */ unsigned long *hdusum, /* O - hdu checksum */ int *status) /* IO - error status */ /* calculate the checksums of the data unit and the total HDU */ { long nrec; LONGLONG headstart, datastart, dataend; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* get size of the HDU */ if (ffghadll(fptr, &headstart, &datastart, &dataend, status) > 0) return(*status); nrec = (long) ((dataend - datastart) / 2880); *datasum = 0; if (nrec > 0) { /* accumulate the 32-bit 1's complement checksum */ ffmbyt(fptr, datastart, REPORT_EOF, status); if (ffcsum(fptr, nrec, datasum, status) > 0) return(*status); } /* move to the start of the header and calc. size of header */ ffmbyt(fptr, headstart, REPORT_EOF, status); nrec = (long) ((datastart - headstart) / 2880); /* accumulate the header checksum into the previous data checksum */ *hdusum = *datasum; ffcsum(fptr, nrec, hdusum, status); return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/drvrfile.c0000644000175100001710000006753400000000000020123 0ustar00vstsdocker/* This file, drvrfile.c contains driver routines for disk files. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include "fitsio2.h" #include "group.h" /* needed for fits_get_cwd in file_create */ #if defined(unix) || defined(__unix__) || defined(__unix) #include /* needed in file_openfile */ #ifdef REPLACE_LINKS #include #include #endif #endif #ifdef HAVE_FTRUNCATE #if defined(unix) || defined(__unix__) || defined(__unix) || defined(HAVE_UNISTD_H) #include /* needed for getcwd prototype on unix machines */ #endif #endif #define IO_SEEK 0 /* last file I/O operation was a seek */ #define IO_READ 1 /* last file I/O operation was a read */ #define IO_WRITE 2 /* last file I/O operation was a write */ static char file_outfile[FLEN_FILENAME]; typedef struct /* structure containing disk file structure */ { FILE *fileptr; LONGLONG currentpos; int last_io_op; } diskdriver; static diskdriver handleTable[NMAXFILES]; /* allocate diskfile handle tables */ /*--------------------------------------------------------------------------*/ int file_init(void) { int ii; for (ii = 0; ii < NMAXFILES; ii++) /* initialize all empty slots in table */ { handleTable[ii].fileptr = 0; } return(0); } /*--------------------------------------------------------------------------*/ int file_setoptions(int options) { /* do something with the options argument, to stop compiler warning */ options = 0; return(options); } /*--------------------------------------------------------------------------*/ int file_getoptions(int *options) { *options = 0; return(0); } /*--------------------------------------------------------------------------*/ int file_getversion(int *version) { *version = 10; return(0); } /*--------------------------------------------------------------------------*/ int file_shutdown(void) { return(0); } /*--------------------------------------------------------------------------*/ int file_open(char *filename, int rwmode, int *handle) { FILE *diskfile; int copyhandle, ii, status; char recbuf[2880]; size_t nread; /* if an output filename has been specified as part of the input file, as in "inputfile.fits(outputfile.fit)" then we have to create the output file, copy the input to it, then reopen the the new copy. */ if (*file_outfile) { /* open the original file, with readonly access */ status = file_openfile(filename, READONLY, &diskfile); if (status) { file_outfile[0] = '\0'; return(status); } /* create the output file */ status = file_create(file_outfile,handle); if (status) { ffpmsg("Unable to create output file for copy of input file:"); ffpmsg(file_outfile); file_outfile[0] = '\0'; return(status); } /* copy the file from input to output */ while(0 != (nread = fread(recbuf,1,2880, diskfile))) { status = file_write(*handle, recbuf, nread); if (status) { file_outfile[0] = '\0'; return(status); } } /* close both files */ fclose(diskfile); copyhandle = *handle; file_close(*handle); *handle = copyhandle; /* reuse the old file handle */ /* reopen the new copy, with correct rwmode */ status = file_openfile(file_outfile, rwmode, &diskfile); file_outfile[0] = '\0'; } else { *handle = -1; for (ii = 0; ii < NMAXFILES; ii++) /* find empty slot in table */ { if (handleTable[ii].fileptr == 0) { *handle = ii; break; } } if (*handle == -1) return(TOO_MANY_FILES); /* too many files opened */ /*open the file */ status = file_openfile(filename, rwmode, &diskfile); } handleTable[*handle].fileptr = diskfile; handleTable[*handle].currentpos = 0; handleTable[*handle].last_io_op = IO_SEEK; return(status); } /*--------------------------------------------------------------------------*/ int file_openfile(char *filename, int rwmode, FILE **diskfile) /* lowest level routine to physically open a disk file */ { char mode[4]; #if defined(unix) || defined(__unix__) || defined(__unix) char tempname[1024], *cptr, user[80]; struct passwd *pwd; int ii = 0; #if defined(REPLACE_LINKS) struct stat stbuf; int success = 0; size_t n; FILE *f1, *f2; char buf[BUFSIZ]; #endif #endif if (rwmode == READWRITE) { strcpy(mode, "r+b"); /* open existing file with read-write */ } else { strcpy(mode, "rb"); /* open existing file readonly */ } #if MACHINE == ALPHAVMS || MACHINE == VAXVMS /* specify VMS record structure: fixed format, 2880 byte records */ /* but force stream mode access to enable random I/O access */ *diskfile = fopen(filename, mode, "rfm=fix", "mrs=2880", "ctx=stm"); #elif defined(unix) || defined(__unix__) || defined(__unix) /* support the ~user/file.fits or ~/file.fits filenames in UNIX */ if (*filename == '~') { if (filename[1] == '/') { cptr = getenv("HOME"); if (cptr) { if (strlen(cptr) + strlen(filename+1) > 1023) return(FILE_NOT_OPENED); strcpy(tempname, cptr); strcat(tempname, filename+1); } else { if (strlen(filename) > 1023) return(FILE_NOT_OPENED); strcpy(tempname, filename); } } else { /* copy user name */ cptr = filename+1; while (*cptr && (*cptr != '/')) { user[ii] = *cptr; cptr++; ii++; } user[ii] = '\0'; /* get structure that includes name of user's home directory */ pwd = getpwnam(user); /* copy user's home directory */ if (strlen(pwd->pw_dir) + strlen(cptr) > 1023) return(FILE_NOT_OPENED); strcpy(tempname, pwd->pw_dir); strcat(tempname, cptr); } *diskfile = fopen(tempname, mode); } else { /* don't need to expand the input file name */ *diskfile = fopen(filename, mode); #if defined(REPLACE_LINKS) if (!(*diskfile) && (rwmode == READWRITE)) { /* failed to open file with READWRITE privilege. Test if */ /* the file we are trying to open is a soft link to a file that */ /* doesn't have write privilege. */ lstat(filename, &stbuf); if ((stbuf.st_mode & S_IFMT) == S_IFLNK) /* is this a soft link? */ { if ((f1 = fopen(filename, "rb")) != 0) /* try opening READONLY */ { if (strlen(filename) + 7 > 1023) return(FILE_NOT_OPENED); strcpy(tempname, filename); strcat(tempname, ".TmxFil"); if ((f2 = fopen(tempname, "wb")) != 0) /* create temp file */ { success = 1; while ((n = fread(buf, 1, BUFSIZ, f1)) > 0) { /* copy linked file to local temporary file */ if (fwrite(buf, 1, n, f2) != n) { success = 0; break; } } fclose(f2); } fclose(f1); if (success) { /* delete link and rename temp file to previous link name */ remove(filename); rename(tempname, filename); /* try once again to open the file with write access */ *diskfile = fopen(filename, mode); } else remove(tempname); /* clean up the failed copy */ } } } #endif } #else /* other non-UNIX machines */ *diskfile = fopen(filename, mode); #endif if (!(*diskfile)) /* couldn't open file */ { return(FILE_NOT_OPENED); } return(0); } /*--------------------------------------------------------------------------*/ int file_create(char *filename, int *handle) { FILE *diskfile; int ii; char mode[4]; int status = 0, rootlen, rootlen2, slen; char *cptr, *cpos; char cwd[FLEN_FILENAME], absURL[FLEN_FILENAME]; char rootstring[256], rootstring2[256]; char username[FLEN_FILENAME], userroot[FLEN_FILENAME], userroot2[FLEN_FILENAME]; cptr = getenv("HERA_DATA_DIRECTORY"); if (cptr) { /* This environment variable is defined in the Hera data analysis environment. */ /* It specifies the root directory path to the users data directories. */ /* CFITSIO will verify that the path to the file that is to be created */ /* is within this root directory + the user's home directory name. */ /* printf("env = %s\n",cptr); */ if (strlen(cptr) > 200) /* guard against possible string overflows */ return(FILE_NOT_CREATED); /* environment variable has the form "path/one/;/path/two/" where the */ /* second path is optional */ strcpy(rootstring, cptr); cpos = strchr(rootstring, ';'); if (cpos) { *cpos = '\0'; cpos++; strcpy(rootstring2, cpos); } else { *rootstring2 = '\0'; } /* printf("%s, %s\n", rootstring, rootstring2); printf("CWD = %s\n", cwd); printf("rootstring=%s, cwd=%s.\n", rootstring, cwd); */ /* Get the current working directory */ fits_get_cwd(cwd, &status); slen = strlen(cwd); if ((slen < FLEN_FILENAME) && cwd[slen-1] != '/') strcat(cwd,"/"); /* make sure the CWD ends with slash */ /* check that CWD string matches the rootstring */ rootlen = strlen(rootstring); if (strncmp(rootstring, cwd, rootlen)) { ffpmsg("invalid CWD: does not match root data directory"); return(FILE_NOT_CREATED); } else { /* get the user name from CWD (it follows the root string) */ strncpy(username, cwd+rootlen, 50); /* limit length of user name */ username[50]=0; cpos=strchr(username, '/'); if (!cpos) { ffpmsg("invalid CWD: not equal to root data directory + username"); return(FILE_NOT_CREATED); } else { *(cpos+1) = '\0'; /* truncate user name string */ /* construct full user root name */ strcpy(userroot, rootstring); strcat(userroot, username); rootlen = strlen(userroot); /* construct alternate full user root name */ strcpy(userroot2, rootstring2); strcat(userroot2, username); rootlen2 = strlen(userroot2); /* convert the input filename to absolute path relative to the CWD */ fits_relurl2url(cwd, filename, absURL, &status); /* printf("username = %s\n", username); printf("userroot = %s\n", userroot); printf("userroot2 = %s\n", userroot2); printf("filename = %s\n", filename); printf("ABS = %s\n", absURL); */ /* check that CWD string matches the rootstring or alternate root string */ if ( strncmp(userroot, absURL, rootlen) && strncmp(userroot2, absURL, rootlen2) ) { ffpmsg("invalid filename: path not within user directory"); return(FILE_NOT_CREATED); } } } /* if we got here, then the input filename appears to be valid */ } *handle = -1; for (ii = 0; ii < NMAXFILES; ii++) /* find empty slot in table */ { if (handleTable[ii].fileptr == 0) { *handle = ii; break; } } if (*handle == -1) return(TOO_MANY_FILES); /* too many files opened */ strcpy(mode, "w+b"); /* create new file with read-write */ diskfile = fopen(filename, "r"); /* does file already exist? */ if (diskfile) { fclose(diskfile); /* close file and exit with error */ return(FILE_NOT_CREATED); } #if MACHINE == ALPHAVMS || MACHINE == VAXVMS /* specify VMS record structure: fixed format, 2880 byte records */ /* but force stream mode access to enable random I/O access */ diskfile = fopen(filename, mode, "rfm=fix", "mrs=2880", "ctx=stm"); #else diskfile = fopen(filename, mode); #endif if (!(diskfile)) /* couldn't create file */ { return(FILE_NOT_CREATED); } handleTable[ii].fileptr = diskfile; handleTable[ii].currentpos = 0; handleTable[ii].last_io_op = IO_SEEK; return(0); } /*--------------------------------------------------------------------------*/ int file_truncate(int handle, LONGLONG filesize) /* truncate the diskfile to a new smaller size */ { #ifdef HAVE_FTRUNCATE int fdesc; fdesc = fileno(handleTable[handle].fileptr); ftruncate(fdesc, (OFF_T) filesize); file_seek(handle, filesize); handleTable[handle].currentpos = filesize; handleTable[handle].last_io_op = IO_SEEK; #endif return(0); } /*--------------------------------------------------------------------------*/ int file_size(int handle, LONGLONG *filesize) /* return the size of the file in bytes */ { OFF_T position1,position2; FILE *diskfile; diskfile = handleTable[handle].fileptr; #if defined(_MSC_VER) && (_MSC_VER >= 1400) /* call the VISUAL C++ version of the routines which support */ /* Large Files (> 2GB) if they are supported (since VC 8.0) */ position1 = _ftelli64(diskfile); /* save current postion */ if (position1 < 0) return(SEEK_ERROR); if (_fseeki64(diskfile, 0, 2) != 0) /* seek to end of file */ return(SEEK_ERROR); position2 = _ftelli64(diskfile); /* get file size */ if (position2 < 0) return(SEEK_ERROR); if (_fseeki64(diskfile, position1, 0) != 0) /* seek back to original pos */ return(SEEK_ERROR); #elif _FILE_OFFSET_BITS - 0 == 64 /* call the newer ftello and fseeko routines , which support */ /* Large Files (> 2GB) if they are supported. */ position1 = ftello(diskfile); /* save current postion */ if (position1 < 0) return(SEEK_ERROR); if (fseeko(diskfile, 0, 2) != 0) /* seek to end of file */ return(SEEK_ERROR); position2 = ftello(diskfile); /* get file size */ if (position2 < 0) return(SEEK_ERROR); if (fseeko(diskfile, position1, 0) != 0) /* seek back to original pos */ return(SEEK_ERROR); #else position1 = ftell(diskfile); /* save current postion */ if (position1 < 0) return(SEEK_ERROR); if (fseek(diskfile, 0, 2) != 0) /* seek to end of file */ return(SEEK_ERROR); position2 = ftell(diskfile); /* get file size */ if (position2 < 0) return(SEEK_ERROR); if (fseek(diskfile, position1, 0) != 0) /* seek back to original pos */ return(SEEK_ERROR); #endif *filesize = (LONGLONG) position2; return(0); } /*--------------------------------------------------------------------------*/ int file_close(int handle) /* close the file */ { if (fclose(handleTable[handle].fileptr) ) return(FILE_NOT_CLOSED); handleTable[handle].fileptr = 0; return(0); } /*--------------------------------------------------------------------------*/ int file_remove(char *filename) /* delete the file from disk */ { remove(filename); return(0); } /*--------------------------------------------------------------------------*/ int file_flush(int handle) /* flush the file */ { if (fflush(handleTable[handle].fileptr) ) return(WRITE_ERROR); /* The flush operation is not supposed to move the internal */ /* file pointer, but it does on some Windows-95 compilers and */ /* perhaps others, so seek to original position to be sure. */ /* This seek will do no harm on other systems. */ #if MACHINE == IBMPC if (file_seek(handle, handleTable[handle].currentpos)) return(SEEK_ERROR); #endif return(0); } /*--------------------------------------------------------------------------*/ int file_seek(int handle, LONGLONG offset) /* seek to position relative to start of the file */ { #if defined(_MSC_VER) && (_MSC_VER >= 1400) /* Microsoft visual studio C++ */ /* _fseeki64 supported beginning with version 8.0 */ if (_fseeki64(handleTable[handle].fileptr, (OFF_T) offset, 0) != 0) return(SEEK_ERROR); #elif _FILE_OFFSET_BITS - 0 == 64 if (fseeko(handleTable[handle].fileptr, (OFF_T) offset, 0) != 0) return(SEEK_ERROR); #else if (fseek(handleTable[handle].fileptr, (OFF_T) offset, 0) != 0) return(SEEK_ERROR); #endif handleTable[handle].currentpos = offset; return(0); } /*--------------------------------------------------------------------------*/ int file_read(int hdl, void *buffer, long nbytes) /* read bytes from the current position in the file */ { long nread; char *cptr; if (handleTable[hdl].last_io_op == IO_WRITE) { if (file_seek(hdl, handleTable[hdl].currentpos)) return(SEEK_ERROR); } nread = (long) fread(buffer, 1, nbytes, handleTable[hdl].fileptr); if (nread == 1) { cptr = (char *) buffer; /* some editors will add a single end-of-file character to a file */ /* Ignore it if the character is a zero, 10, or 32 */ if (*cptr == 0 || *cptr == 10 || *cptr == 32) return(END_OF_FILE); else return(READ_ERROR); } else if (nread != nbytes) { return(READ_ERROR); } handleTable[hdl].currentpos += nbytes; handleTable[hdl].last_io_op = IO_READ; return(0); } /*--------------------------------------------------------------------------*/ int file_write(int hdl, void *buffer, long nbytes) /* write bytes at the current position in the file */ { if (handleTable[hdl].last_io_op == IO_READ) { if (file_seek(hdl, handleTable[hdl].currentpos)) return(SEEK_ERROR); } if((long) fwrite(buffer, 1, nbytes, handleTable[hdl].fileptr) != nbytes) return(WRITE_ERROR); handleTable[hdl].currentpos += nbytes; handleTable[hdl].last_io_op = IO_WRITE; return(0); } /*--------------------------------------------------------------------------*/ int file_compress_open(char *filename, int rwmode, int *hdl) /* This routine opens the compressed diskfile by creating a new uncompressed file then opening it. The input file name (the name of the compressed file) gets replaced with the name of the uncompressed file, which is initially stored in the global file_outfile string. file_outfile then gets set to a null string. */ { FILE *indiskfile, *outdiskfile; int status; char *cptr; /* open the compressed disk file */ status = file_openfile(filename, READONLY, &indiskfile); if (status) { ffpmsg("failed to open compressed disk file (file_compress_open)"); ffpmsg(filename); return(status); } /* name of the output uncompressed file is stored in the */ /* global variable called 'file_outfile'. */ cptr = file_outfile; if (*cptr == '!') { /* clobber any existing file with the same name */ cptr++; remove(cptr); } else { outdiskfile = fopen(file_outfile, "r"); /* does file already exist? */ if (outdiskfile) { ffpmsg("uncompressed file already exists: (file_compress_open)"); ffpmsg(file_outfile); fclose(outdiskfile); /* close file and exit with error */ file_outfile[0] = '\0'; return(FILE_NOT_CREATED); } } outdiskfile = fopen(cptr, "w+b"); /* create new file */ if (!outdiskfile) { ffpmsg("could not create uncompressed file: (file_compress_open)"); ffpmsg(file_outfile); file_outfile[0] = '\0'; return(FILE_NOT_CREATED); } /* uncompress file into another file */ uncompress2file(filename, indiskfile, outdiskfile, &status); fclose(indiskfile); fclose(outdiskfile); if (status) { ffpmsg("error in file_compress_open: failed to uncompressed file:"); ffpmsg(filename); ffpmsg(" into new output file:"); ffpmsg(file_outfile); file_outfile[0] = '\0'; return(status); } strcpy(filename, cptr); /* switch the names */ file_outfile[0] = '\0'; status = file_open(filename, rwmode, hdl); return(status); } /*--------------------------------------------------------------------------*/ int file_is_compressed(char *filename) /* I - FITS file name */ /* Test if the disk file is compressed. Returns 1 if compressed, 0 if not. This may modify the filename string by appending a compression suffex. */ { FILE *diskfile; unsigned char buffer[2]; char tmpfilename[FLEN_FILENAME]; /* Open file. Try various suffix combinations */ if (file_openfile(filename, 0, &diskfile)) { if (strlen(filename) > FLEN_FILENAME - 5) return(0); strcpy(tmpfilename,filename); strcat(filename,".gz"); if (file_openfile(filename, 0, &diskfile)) { #if HAVE_BZIP2 strcpy(filename,tmpfilename); strcat(filename,".bz2"); if (file_openfile(filename, 0, &diskfile)) { #endif strcpy(filename, tmpfilename); strcat(filename,".Z"); if (file_openfile(filename, 0, &diskfile)) { strcpy(filename, tmpfilename); strcat(filename,".z"); /* it's often lower case on CDROMs */ if (file_openfile(filename, 0, &diskfile)) { strcpy(filename, tmpfilename); strcat(filename,".zip"); if (file_openfile(filename, 0, &diskfile)) { strcpy(filename, tmpfilename); strcat(filename,"-z"); /* VMS suffix */ if (file_openfile(filename, 0, &diskfile)) { strcpy(filename, tmpfilename); strcat(filename,"-gz"); /* VMS suffix */ if (file_openfile(filename, 0, &diskfile)) { strcpy(filename,tmpfilename); /* restore original name */ return(0); /* file not found */ } } } } } #if HAVE_BZIP2 } #endif } } if (fread(buffer, 1, 2, diskfile) != 2) /* read 2 bytes */ { fclose(diskfile); /* error reading file so just return */ return(0); } fclose(diskfile); /* see if the 2 bytes have the magic values for a compressed file */ if ( (memcmp(buffer, "\037\213", 2) == 0) || /* GZIP */ (memcmp(buffer, "\120\113", 2) == 0) || /* PKZIP */ (memcmp(buffer, "\037\036", 2) == 0) || /* PACK */ (memcmp(buffer, "\037\235", 2) == 0) || /* LZW */ #if HAVE_BZIP2 (memcmp(buffer, "BZ", 2) == 0) || /* BZip2 */ #endif (memcmp(buffer, "\037\240", 2) == 0)) /* LZH */ { return(1); /* this is a compressed file */ } else { return(0); /* not a compressed file */ } } /*--------------------------------------------------------------------------*/ int file_checkfile (char *urltype, char *infile, char *outfile) { /* special case: if file:// driver, check if the file is compressed */ if ( file_is_compressed(infile) ) { /* if output file has been specified, save the name for future use: */ /* This is the name of the uncompressed file to be created on disk. */ if (strlen(outfile)) { if (!strncmp(outfile, "mem:", 4) ) { /* uncompress the file in memory, with READ and WRITE access */ strcpy(urltype, "compressmem://"); /* use special driver */ *file_outfile = '\0'; } else { strcpy(urltype, "compressfile://"); /* use special driver */ /* don't copy the "file://" prefix, if present. */ if (!strncmp(outfile, "file://", 7) ) strcpy(file_outfile,outfile+7); else strcpy(file_outfile,outfile); } } else { /* uncompress the file in memory */ strcpy(urltype, "compress://"); /* use special driver */ *file_outfile = '\0'; /* no output file was specified */ } } else /* an ordinary, uncompressed FITS file on disk */ { /* save the output file name for later use when opening the file. */ /* In this case, the file to be opened will be opened READONLY, */ /* and copied to this newly created output file. The original file */ /* will be closed, and the copy will be opened by CFITSIO for */ /* subsequent processing (possibly with READWRITE access). */ if (strlen(outfile)) { file_outfile[0] = '\0'; strncat(file_outfile,outfile,FLEN_FILENAME-1); } } return 0; } /**********************************************************************/ /**********************************************************************/ /**********************************************************************/ /**** driver routines for stream//: device (stdin or stdout) ********/ /*--------------------------------------------------------------------------*/ int stream_open(char *filename, int rwmode, int *handle) { /* read from stdin */ if (filename) rwmode = 1; /* dummy statement to suppress unused parameter compiler warning */ *handle = 1; /* 1 = stdin */ return(0); } /*--------------------------------------------------------------------------*/ int stream_create(char *filename, int *handle) { /* write to stdout */ if (filename) /* dummy statement to suppress unused parameter compiler warning */ *handle = 2; else *handle = 2; /* 2 = stdout */ return(0); } /*--------------------------------------------------------------------------*/ int stream_size(int handle, LONGLONG *filesize) /* return the size of the file in bytes */ { handle = 0; /* suppress unused parameter compiler warning */ /* this operation is not supported in a stream; return large value */ *filesize = LONG_MAX; return(0); } /*--------------------------------------------------------------------------*/ int stream_close(int handle) /* don't have to close stdin or stdout */ { handle = 0; /* suppress unused parameter compiler warning */ return(0); } /*--------------------------------------------------------------------------*/ int stream_flush(int handle) /* flush the file */ { if (handle == 2) fflush(stdout); return(0); } /*--------------------------------------------------------------------------*/ int stream_seek(int handle, LONGLONG offset) /* seeking is not allowed in a stream */ { offset = handle; /* suppress unused parameter compiler warning */ return(1); } /*--------------------------------------------------------------------------*/ int stream_read(int hdl, void *buffer, long nbytes) /* reading from stdin stream */ { long nread; if (hdl != 1) return(1); /* can only read from stdin */ nread = (long) fread(buffer, 1, nbytes, stdin); if (nread != nbytes) { /* return(READ_ERROR); */ return(END_OF_FILE); } return(0); } /*--------------------------------------------------------------------------*/ int stream_write(int hdl, void *buffer, long nbytes) /* write bytes at the current position in the file */ { if (hdl != 2) return(1); /* can only write to stdout */ if((long) fwrite(buffer, 1, nbytes, stdout) != nbytes) return(WRITE_ERROR); return(0); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/drvrmem.c0000644000175100001710000011520100000000000017743 0ustar00vstsdocker/* This file, drvrmem.c, contains driver routines for memory files. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include /* apparently needed to define size_t */ #include "fitsio2.h" #if HAVE_BZIP2 #include "bzlib.h" #endif /* prototype for .Z file uncompression function in zuncompress.c */ int zuncompress2mem(char *filename, FILE *diskfile, char **buffptr, size_t *buffsize, void *(*mem_realloc)(void *p, size_t newsize), size_t *filesize, int *status); #if HAVE_BZIP2 /* prototype for .bz2 uncompression function (in this file) */ void bzip2uncompress2mem(char *filename, FILE *diskfile, int hdl, size_t* filesize, int* status); #endif #define RECBUFLEN 1000 static char stdin_outfile[FLEN_FILENAME]; typedef struct /* structure containing mem file structure */ { char **memaddrptr; /* Pointer to memory address pointer; */ /* This may or may not point to memaddr. */ char *memaddr; /* Pointer to starting memory address; may */ /* not always be used, so use *memaddrptr instead */ size_t *memsizeptr; /* Pointer to the size of the memory allocation. */ /* This may or may not point to memsize. */ size_t memsize; /* Size of the memory allocation; this may not */ /* always be used, so use *memsizeptr instead. */ size_t deltasize; /* Suggested increment for reallocating memory */ void *(*mem_realloc)(void *p, size_t newsize); /* realloc function */ LONGLONG currentpos; /* current file position, relative to start */ LONGLONG fitsfilesize; /* size of the FITS file (always <= *memsizeptr) */ FILE *fileptr; /* pointer to compressed output disk file */ } memdriver; static memdriver memTable[NMAXFILES]; /* allocate mem file handle tables */ /*--------------------------------------------------------------------------*/ int mem_init(void) { int ii; for (ii = 0; ii < NMAXFILES; ii++) /* initialize all empty slots in table */ { memTable[ii].memaddrptr = 0; memTable[ii].memaddr = 0; } return(0); } /*--------------------------------------------------------------------------*/ int mem_setoptions(int options) { /* do something with the options argument, to stop compiler warning */ options = 0; return(options); } /*--------------------------------------------------------------------------*/ int mem_getoptions(int *options) { *options = 0; return(0); } /*--------------------------------------------------------------------------*/ int mem_getversion(int *version) { *version = 10; return(0); } /*--------------------------------------------------------------------------*/ int mem_shutdown(void) { return(0); } /*--------------------------------------------------------------------------*/ int mem_create(char *filename, int *handle) /* Create a new empty memory file for subsequent writes. The file name is ignored in this case. */ { int status; /* initially allocate 1 FITS block = 2880 bytes */ status = mem_createmem(2880L, handle); if (status) { ffpmsg("failed to create empty memory file (mem_create)"); return(status); } return(0); } /*--------------------------------------------------------------------------*/ int mem_create_comp(char *filename, int *handle) /* Create a new empty memory file for subsequent writes. Also create an empty compressed .gz file. The memory file will be compressed and written to the disk file when the file is closed. */ { FILE *diskfile; char mode[4]; int status; /* first, create disk file for the compressed output */ if ( !strcmp(filename, "-.gz") || !strcmp(filename, "stdout.gz") || !strcmp(filename, "STDOUT.gz") ) { /* special case: create uncompressed FITS file in memory, then compress it an write it out to 'stdout' when it is closed. */ diskfile = stdout; } else { /* normal case: create disk file for the compressed output */ strcpy(mode, "w+b"); /* create file with read-write */ diskfile = fopen(filename, "r"); /* does file already exist? */ if (diskfile) { fclose(diskfile); /* close file and exit with error */ return(FILE_NOT_CREATED); } #if MACHINE == ALPHAVMS || MACHINE == VAXVMS /* specify VMS record structure: fixed format, 2880 byte records */ /* but force stream mode access to enable random I/O access */ diskfile = fopen(filename, mode, "rfm=fix", "mrs=2880", "ctx=stm"); #else diskfile = fopen(filename, mode); #endif if (!(diskfile)) /* couldn't create file */ { return(FILE_NOT_CREATED); } } /* now create temporary memory file */ /* initially allocate 1 FITS block = 2880 bytes */ status = mem_createmem(2880L, handle); if (status) { ffpmsg("failed to create empty memory file (mem_create_comp)"); return(status); } memTable[*handle].fileptr = diskfile; return(0); } /*--------------------------------------------------------------------------*/ int mem_openmem(void **buffptr, /* I - address of memory pointer */ size_t *buffsize, /* I - size of buffer, in bytes */ size_t deltasize, /* I - increment for future realloc's */ void *(*memrealloc)(void *p, size_t newsize), /* function */ int *handle) /* lowest level routine to open a pre-existing memory file. */ { int ii; *handle = -1; for (ii = 0; ii < NMAXFILES; ii++) /* find empty slot in handle table */ { if (memTable[ii].memaddrptr == 0) { *handle = ii; break; } } if (*handle == -1) return(TOO_MANY_FILES); /* too many files opened */ memTable[ii].memaddrptr = (char **) buffptr; /* pointer to start addres */ memTable[ii].memsizeptr = buffsize; /* allocated size of memory */ memTable[ii].deltasize = deltasize; /* suggested realloc increment */ memTable[ii].fitsfilesize = *buffsize; /* size of FITS file (upper limit) */ memTable[ii].currentpos = 0; /* at beginning of the file */ memTable[ii].mem_realloc = memrealloc; /* memory realloc function */ return(0); } /*--------------------------------------------------------------------------*/ int mem_createmem(size_t msize, int *handle) /* lowest level routine to allocate a memory file. */ { int ii; *handle = -1; for (ii = 0; ii < NMAXFILES; ii++) /* find empty slot in handle table */ { if (memTable[ii].memaddrptr == 0) { *handle = ii; break; } } if (*handle == -1) return(TOO_MANY_FILES); /* too many files opened */ /* use the internally allocated memaddr and memsize variables */ memTable[ii].memaddrptr = &memTable[ii].memaddr; memTable[ii].memsizeptr = &memTable[ii].memsize; /* allocate initial block of memory for the file */ if (msize > 0) { memTable[ii].memaddr = (char *) malloc(msize); if ( !(memTable[ii].memaddr) ) { ffpmsg("malloc of initial memory failed (mem_createmem)"); return(FILE_NOT_OPENED); } } /* set initial state of the file */ memTable[ii].memsize = msize; memTable[ii].deltasize = 2880; memTable[ii].fitsfilesize = 0; memTable[ii].currentpos = 0; memTable[ii].mem_realloc = realloc; return(0); } /*--------------------------------------------------------------------------*/ int mem_truncate(int handle, LONGLONG filesize) /* truncate the file to a new size */ { char *ptr; /* call the memory reallocation function, if defined */ if ( memTable[handle].mem_realloc ) { /* explicit LONGLONG->size_t cast */ ptr = (memTable[handle].mem_realloc)( *(memTable[handle].memaddrptr), (size_t) filesize); if (!ptr) { ffpmsg("Failed to reallocate memory (mem_truncate)"); return(MEMORY_ALLOCATION); } /* if allocated more memory, initialize it to zero */ if ( filesize > *(memTable[handle].memsizeptr) ) { memset(ptr + *(memTable[handle].memsizeptr), 0, ((size_t) filesize) - *(memTable[handle].memsizeptr) ); } *(memTable[handle].memaddrptr) = ptr; *(memTable[handle].memsizeptr) = (size_t) (filesize); } memTable[handle].currentpos = filesize; memTable[handle].fitsfilesize = filesize; return(0); } /*--------------------------------------------------------------------------*/ int stdin_checkfile(char *urltype, char *infile, char *outfile) /* do any special case checking when opening a file on the stdin stream */ { if (strlen(outfile)) { stdin_outfile[0] = '\0'; strncat(stdin_outfile,outfile,FLEN_FILENAME-1); /* an output file is specified */ strcpy(urltype,"stdinfile://"); } else *stdin_outfile = '\0'; /* no output file was specified */ return(0); } /*--------------------------------------------------------------------------*/ int stdin_open(char *filename, int rwmode, int *handle) /* open a FITS file from the stdin file stream by copying it into memory The file name is ignored in this case. */ { int status; char cbuff; if (*stdin_outfile) { /* copy the stdin stream to the specified disk file then open the file */ /* Create the output file */ status = file_create(stdin_outfile,handle); if (status) { ffpmsg("Unable to create output file to copy stdin (stdin_open):"); ffpmsg(stdin_outfile); return(status); } /* copy the whole stdin stream to the file */ status = stdin2file(*handle); file_close(*handle); if (status) { ffpmsg("failed to copy stdin to file (stdin_open)"); ffpmsg(stdin_outfile); return(status); } /* reopen file with proper rwmode attribute */ status = file_open(stdin_outfile, rwmode, handle); } else { /* get the first character, then put it back */ cbuff = fgetc(stdin); ungetc(cbuff, stdin); /* compressed files begin with 037 or 'P' */ if (cbuff == 31 || cbuff == 75) { /* looks like the input stream is compressed */ status = mem_compress_stdin_open(filename, rwmode, handle); } else { /* copy the stdin stream into memory then open file in memory */ if (rwmode != READONLY) { ffpmsg("cannot open stdin with WRITE access"); return(READONLY_FILE); } status = mem_createmem(2880L, handle); if (status) { ffpmsg("failed to create empty memory file (stdin_open)"); return(status); } /* copy the whole stdin stream into memory */ status = stdin2mem(*handle); if (status) { ffpmsg("failed to copy stdin into memory (stdin_open)"); free(memTable[*handle].memaddr); } } } return(status); } /*--------------------------------------------------------------------------*/ int stdin2mem(int hd) /* handle number */ /* Copy the stdin stream into memory. Fill whatever amount of memory has already been allocated, then realloc more memory if necessary. */ { size_t nread, memsize, delta; LONGLONG filesize; char *memptr; char simple[] = "SIMPLE"; int c, ii, jj; memptr = *memTable[hd].memaddrptr; memsize = *memTable[hd].memsizeptr; delta = memTable[hd].deltasize; filesize = 0; ii = 0; for(jj = 0; (c = fgetc(stdin)) != EOF && jj < 2000; jj++) { /* Skip over any garbage at the beginning of the stdin stream by */ /* reading 1 char at a time, looking for 'S', 'I', 'M', 'P', 'L', 'E' */ /* Give up if not found in the first 2000 characters */ if (c == simple[ii]) { ii++; if (ii == 6) /* found the complete string? */ { memcpy(memptr, simple, 6); /* copy "SIMPLE" to buffer */ filesize = 6; break; } } else ii = 0; /* reset search to beginning of the string */ } if (filesize == 0) { ffpmsg("Couldn't find the string 'SIMPLE' in the stdin stream."); ffpmsg("This does not look like a FITS file."); return(FILE_NOT_OPENED); } /* fill up the remainder of the initial memory allocation */ nread = fread(memptr + 6, 1, memsize - 6, stdin); nread += 6; /* add in the 6 characters in 'SIMPLE' */ if (nread < memsize) /* reached the end? */ { memTable[hd].fitsfilesize = nread; return(0); } filesize = nread; while (1) { /* allocate memory for another FITS block */ memptr = realloc(memptr, memsize + delta); if (!memptr) { ffpmsg("realloc failed while copying stdin (stdin2mem)"); return(MEMORY_ALLOCATION); } memsize += delta; /* read another FITS block */ nread = fread(memptr + filesize, 1, delta, stdin); filesize += nread; if (nread < delta) /* reached the end? */ break; } memTable[hd].fitsfilesize = filesize; *memTable[hd].memaddrptr = memptr; *memTable[hd].memsizeptr = memsize; return(0); } /*--------------------------------------------------------------------------*/ int stdin2file(int handle) /* handle number */ /* Copy the stdin stream to a file. . */ { size_t nread; char simple[] = "SIMPLE"; int c, ii, jj, status; char recbuf[RECBUFLEN]; ii = 0; for(jj = 0; (c = fgetc(stdin)) != EOF && jj < 2000; jj++) { /* Skip over any garbage at the beginning of the stdin stream by */ /* reading 1 char at a time, looking for 'S', 'I', 'M', 'P', 'L', 'E' */ /* Give up if not found in the first 2000 characters */ if (c == simple[ii]) { ii++; if (ii == 6) /* found the complete string? */ { memcpy(recbuf, simple, 6); /* copy "SIMPLE" to buffer */ break; } } else ii = 0; /* reset search to beginning of the string */ } if (ii != 6) { ffpmsg("Couldn't find the string 'SIMPLE' in the stdin stream"); return(FILE_NOT_OPENED); } /* fill up the remainder of the buffer */ nread = fread(recbuf + 6, 1, RECBUFLEN - 6, stdin); nread += 6; /* add in the 6 characters in 'SIMPLE' */ status = file_write(handle, recbuf, nread); if (status) return(status); /* copy the rest of stdin stream */ while(0 != (nread = fread(recbuf,1,RECBUFLEN, stdin))) { status = file_write(handle, recbuf, nread); if (status) return(status); } return(status); } /*--------------------------------------------------------------------------*/ int stdout_close(int handle) /* copy the memory file to stdout, then free the memory */ { int status = 0; /* copy from memory to standard out. explicit LONGLONG->size_t cast */ if(fwrite(memTable[handle].memaddr, 1, ((size_t) memTable[handle].fitsfilesize), stdout) != (size_t) memTable[handle].fitsfilesize ) { ffpmsg("failed to copy memory file to stdout (stdout_close)"); status = WRITE_ERROR; } free( memTable[handle].memaddr ); /* free the memory */ memTable[handle].memaddrptr = 0; memTable[handle].memaddr = 0; return(status); } /*--------------------------------------------------------------------------*/ int mem_compress_openrw(char *filename, int rwmode, int *hdl) /* This routine opens the compressed diskfile and creates an empty memory buffer with an appropriate size, then calls mem_uncompress2mem. It allows the memory 'file' to be opened with READWRITE access. */ { return(mem_compress_open(filename, READONLY, hdl)); } /*--------------------------------------------------------------------------*/ int mem_compress_open(char *filename, int rwmode, int *hdl) /* This routine opens the compressed diskfile and creates an empty memory buffer with an appropriate size, then calls mem_uncompress2mem. */ { FILE *diskfile; int status, estimated = 1; unsigned char buffer[4]; size_t finalsize, filesize; LONGLONG llsize = 0; unsigned int modulosize; char *ptr; if (rwmode != READONLY) { ffpmsg( "cannot open compressed file with WRITE access (mem_compress_open)"); ffpmsg(filename); return(READONLY_FILE); } /* open the compressed disk file */ status = file_openfile(filename, READONLY, &diskfile); if (status) { ffpmsg("failed to open compressed disk file (compress_open)"); ffpmsg(filename); return(status); } if (fread(buffer, 1, 2, diskfile) != 2) /* read 2 bytes */ { fclose(diskfile); return(READ_ERROR); } if (memcmp(buffer, "\037\213", 2) == 0) /* GZIP */ { /* the uncompressed file size is give at the end */ /* of the file in the ISIZE field (modulo 2^32) */ fseek(diskfile, 0, 2); /* move to end of file */ filesize = ftell(diskfile); /* position = size of file */ fseek(diskfile, -4L, 1); /* move back 4 bytes */ fread(buffer, 1, 4L, diskfile); /* read 4 bytes */ /* have to worry about integer byte order */ modulosize = buffer[0]; modulosize |= buffer[1] << 8; modulosize |= buffer[2] << 16; modulosize |= buffer[3] << 24; /* the field ISIZE in the gzipped file header only stores 4 bytes and contains the uncompressed file size modulo 2^32. If the uncompressed file size is less than the compressed file size (filesize), then one probably needs to add 2^32 = 4294967296 to the uncompressed file size, assuming that the gzip produces a compressed file that is smaller than the original file. But one must allow for the case of very small files, where the gzipped file may actually be larger then the original uncompressed file. Therefore, only perform the modulo 2^32 correction test if the compressed file is greater than 10,000 bytes in size. (Note: this threhold would fail only if the original file was greater than 2^32 bytes in size AND gzip was able to compress it by more than a factor of 400,000 (!) which seems highly unlikely.) Also, obviously, this 2^32 modulo correction cannot be performed if the finalsize variable is only 32-bits long. Typically, the 'size_t' integer type must be 8 bytes or larger in size to support data files that are greater than 2 GB (2^31 bytes) in size. */ finalsize = modulosize; if (sizeof(size_t) > 4 && filesize > 10000) { llsize = (LONGLONG) finalsize; /* use LONGLONG variable to suppress compiler warning */ while (llsize < (LONGLONG) filesize) llsize += 4294967296; finalsize = (size_t) llsize; } estimated = 0; /* file size is known, not estimated */ } else if (memcmp(buffer, "\120\113", 2) == 0) /* PKZIP */ { /* the uncompressed file size is give at byte 22 the file */ fseek(diskfile, 22L, 0); /* move to byte 22 */ fread(buffer, 1, 4L, diskfile); /* read 4 bytes */ /* have to worry about integer byte order */ modulosize = buffer[0]; modulosize |= buffer[1] << 8; modulosize |= buffer[2] << 16; modulosize |= buffer[3] << 24; finalsize = modulosize; estimated = 0; /* file size is known, not estimated */ } else if (memcmp(buffer, "\037\036", 2) == 0) /* PACK */ finalsize = 0; /* for most methods we can't determine final size */ else if (memcmp(buffer, "\037\235", 2) == 0) /* LZW */ finalsize = 0; /* for most methods we can't determine final size */ else if (memcmp(buffer, "\037\240", 2) == 0) /* LZH */ finalsize = 0; /* for most methods we can't determine final size */ #if HAVE_BZIP2 else if (memcmp(buffer, "BZ", 2) == 0) /* BZip2 */ finalsize = 0; /* for most methods we can't determine final size */ #endif else { /* not a compressed file; this should never happen */ fclose(diskfile); return(1); } if (finalsize == 0) /* estimate uncompressed file size */ { fseek(diskfile, 0, 2); /* move to end of the compressed file */ finalsize = ftell(diskfile); /* position = size of file */ finalsize = finalsize * 3; /* assume factor of 3 compression */ } fseek(diskfile, 0, 0); /* move back to beginning of file */ /* create a memory file big enough (hopefully) for the uncompressed file */ status = mem_createmem(finalsize, hdl); if (status && estimated) { /* memory allocation failed, so try a smaller estimated size */ finalsize = finalsize / 3; status = mem_createmem(finalsize, hdl); } if (status) { fclose(diskfile); ffpmsg("failed to create empty memory file (compress_open)"); return(status); } /* uncompress file into memory */ status = mem_uncompress2mem(filename, diskfile, *hdl); fclose(diskfile); if (status) { mem_close_free(*hdl); /* free up the memory */ ffpmsg("failed to uncompress file into memory (compress_open)"); return(status); } /* if we allocated too much memory initially, then free it */ if (*(memTable[*hdl].memsizeptr) > (( (size_t) memTable[*hdl].fitsfilesize) + 256L) ) { ptr = realloc(*(memTable[*hdl].memaddrptr), ((size_t) memTable[*hdl].fitsfilesize) ); if (!ptr) { ffpmsg("Failed to reduce size of allocated memory (compress_open)"); return(MEMORY_ALLOCATION); } *(memTable[*hdl].memaddrptr) = ptr; *(memTable[*hdl].memsizeptr) = (size_t) (memTable[*hdl].fitsfilesize); } return(0); } /*--------------------------------------------------------------------------*/ int mem_compress_stdin_open(char *filename, int rwmode, int *hdl) /* This routine reads the compressed input stream and creates an empty memory buffer, then calls mem_uncompress2mem. */ { int status; char *ptr; if (rwmode != READONLY) { ffpmsg( "cannot open compressed input stream with WRITE access (mem_compress_stdin_open)"); return(READONLY_FILE); } /* create a memory file for the uncompressed file */ status = mem_createmem(28800, hdl); if (status) { ffpmsg("failed to create empty memory file (compress_stdin_open)"); return(status); } /* uncompress file into memory */ status = mem_uncompress2mem(filename, stdin, *hdl); if (status) { mem_close_free(*hdl); /* free up the memory */ ffpmsg("failed to uncompress stdin into memory (compress_stdin_open)"); return(status); } /* if we allocated too much memory initially, then free it */ if (*(memTable[*hdl].memsizeptr) > (( (size_t) memTable[*hdl].fitsfilesize) + 256L) ) { ptr = realloc(*(memTable[*hdl].memaddrptr), ((size_t) memTable[*hdl].fitsfilesize) ); if (!ptr) { ffpmsg("Failed to reduce size of allocated memory (compress_stdin_open)"); return(MEMORY_ALLOCATION); } *(memTable[*hdl].memaddrptr) = ptr; *(memTable[*hdl].memsizeptr) = (size_t) (memTable[*hdl].fitsfilesize); } return(0); } /*--------------------------------------------------------------------------*/ int mem_iraf_open(char *filename, int rwmode, int *hdl) /* This routine creates an empty memory buffer, then calls iraf2mem to open the IRAF disk file and convert it to a FITS file in memeory. */ { int status; size_t filesize = 0; /* create a memory file with size = 0 for the FITS converted IRAF file */ status = mem_createmem(filesize, hdl); if (status) { ffpmsg("failed to create empty memory file (mem_iraf_open)"); return(status); } /* convert the iraf file into a FITS file in memory */ status = iraf2mem(filename, memTable[*hdl].memaddrptr, memTable[*hdl].memsizeptr, &filesize, &status); if (status) { mem_close_free(*hdl); /* free up the memory */ ffpmsg("failed to convert IRAF file into memory (mem_iraf_open)"); return(status); } memTable[*hdl].currentpos = 0; /* save starting position */ memTable[*hdl].fitsfilesize=filesize; /* and initial file size */ return(0); } /*--------------------------------------------------------------------------*/ int mem_rawfile_open(char *filename, int rwmode, int *hdl) /* This routine creates an empty memory buffer, writes a minimal image header, then copies the image data from the raw file into memory. It will byteswap the pixel values if the raw array is in little endian byte order. */ { FILE *diskfile; fitsfile *fptr; short *sptr; int status, endian, datatype, bytePerPix, naxis; long dim[5] = {1,1,1,1,1}, ii, nvals, offset = 0; size_t filesize = 0, datasize; char rootfile[FLEN_FILENAME], *cptr = 0, *cptr2 = 0; void *ptr; if (rwmode != READONLY) { ffpmsg( "cannot open raw binary file with WRITE access (mem_rawfile_open)"); ffpmsg(filename); return(READONLY_FILE); } cptr = strchr(filename, '['); /* search for opening bracket [ */ if (!cptr) { ffpmsg("binary file name missing '[' character (mem_rawfile_open)"); ffpmsg(filename); return(URL_PARSE_ERROR); } *rootfile = '\0'; strncat(rootfile, filename, cptr - filename); /* store the rootname */ cptr++; while (*cptr == ' ') cptr++; /* skip leading blanks */ /* Get the Data Type of the Image */ if (*cptr == 'b' || *cptr == 'B') { datatype = BYTE_IMG; bytePerPix = 1; } else if (*cptr == 'i' || *cptr == 'I') { datatype = SHORT_IMG; bytePerPix = 2; } else if (*cptr == 'u' || *cptr == 'U') { datatype = USHORT_IMG; bytePerPix = 2; } else if (*cptr == 'j' || *cptr == 'J') { datatype = LONG_IMG; bytePerPix = 4; } else if (*cptr == 'r' || *cptr == 'R' || *cptr == 'f' || *cptr == 'F') { datatype = FLOAT_IMG; bytePerPix = 4; } else if (*cptr == 'd' || *cptr == 'D') { datatype = DOUBLE_IMG; bytePerPix = 8; } else { ffpmsg("error in raw binary file datatype (mem_rawfile_open)"); ffpmsg(filename); return(URL_PARSE_ERROR); } cptr++; /* get Endian: Big or Little; default is same as the local machine */ if (*cptr == 'b' || *cptr == 'B') { endian = 0; cptr++; } else if (*cptr == 'l' || *cptr == 'L') { endian = 1; cptr++; } else endian = BYTESWAPPED; /* byteswapped machines are little endian */ /* read each dimension (up to 5) */ naxis = 1; dim[0] = strtol(cptr, &cptr2, 10); if (cptr2 && *cptr2 == ',') { naxis = 2; dim[1] = strtol(cptr2+1, &cptr, 10); if (cptr && *cptr == ',') { naxis = 3; dim[2] = strtol(cptr+1, &cptr2, 10); if (cptr2 && *cptr2 == ',') { naxis = 4; dim[3] = strtol(cptr2+1, &cptr, 10); if (cptr && *cptr == ',') naxis = 5; dim[4] = strtol(cptr+1, &cptr2, 10); } } } cptr = maxvalue(cptr, cptr2); if (*cptr == ':') /* read starting offset value */ offset = strtol(cptr+1, 0, 10); nvals = dim[0] * dim[1] * dim[2] * dim[3] * dim[4]; datasize = nvals * bytePerPix; filesize = nvals * bytePerPix + 2880; filesize = ((filesize - 1) / 2880 + 1) * 2880; /* open the raw binary disk file */ status = file_openfile(rootfile, READONLY, &diskfile); if (status) { ffpmsg("failed to open raw binary file (mem_rawfile_open)"); ffpmsg(rootfile); return(status); } /* create a memory file with corrct size for the FITS converted raw file */ status = mem_createmem(filesize, hdl); if (status) { ffpmsg("failed to create memory file (mem_rawfile_open)"); fclose(diskfile); return(status); } /* open this piece of memory as a new FITS file */ ffimem(&fptr, (void **) memTable[*hdl].memaddrptr, &filesize, 0, 0, &status); /* write the required header keywords */ ffcrim(fptr, datatype, naxis, dim, &status); /* close the FITS file, but keep the memory allocated */ ffclos(fptr, &status); if (status > 0) { ffpmsg("failed to write basic image header (mem_rawfile_open)"); fclose(diskfile); mem_close_free(*hdl); /* free up the memory */ return(status); } if (offset > 0) fseek(diskfile, offset, 0); /* offset to start of the data */ /* read the raw data into memory */ ptr = *memTable[*hdl].memaddrptr + 2880; if (fread((char *) ptr, 1, datasize, diskfile) != datasize) status = READ_ERROR; fclose(diskfile); /* close the raw binary disk file */ if (status) { mem_close_free(*hdl); /* free up the memory */ ffpmsg("failed to copy raw file data into memory (mem_rawfile_open)"); return(status); } if (datatype == USHORT_IMG) /* have to subtract 32768 from each unsigned */ { /* value to conform to FITS convention. More */ /* efficient way to do this is to just flip */ /* the most significant bit. */ sptr = (short *) ptr; if (endian == BYTESWAPPED) /* working with native format */ { for (ii = 0; ii < nvals; ii++, sptr++) { *sptr = ( *sptr ) ^ 0x8000; } } else /* pixels are byteswapped WRT the native format */ { for (ii = 0; ii < nvals; ii++, sptr++) { *sptr = ( *sptr ) ^ 0x80; } } } if (endian) /* swap the bytes if array is in little endian byte order */ { if (datatype == SHORT_IMG || datatype == USHORT_IMG) { ffswap2( (short *) ptr, nvals); } else if (datatype == LONG_IMG || datatype == FLOAT_IMG) { ffswap4( (INT32BIT *) ptr, nvals); } else if (datatype == DOUBLE_IMG) { ffswap8( (double *) ptr, nvals); } } memTable[*hdl].currentpos = 0; /* save starting position */ memTable[*hdl].fitsfilesize=filesize; /* and initial file size */ return(0); } /*--------------------------------------------------------------------------*/ int mem_uncompress2mem(char *filename, FILE *diskfile, int hdl) { /* lower level routine to uncompress a file into memory. The file has already been opened and the memory buffer has been allocated. */ size_t finalsize; int status; /* uncompress file into memory */ status = 0; if (strstr(filename, ".Z")) { zuncompress2mem(filename, diskfile, memTable[hdl].memaddrptr, /* pointer to memory address */ memTable[hdl].memsizeptr, /* pointer to size of memory */ realloc, /* reallocation function */ &finalsize, &status); /* returned file size nd status*/ #if HAVE_BZIP2 } else if (strstr(filename, ".bz2")) { bzip2uncompress2mem(filename, diskfile, hdl, &finalsize, &status); #endif } else { uncompress2mem(filename, diskfile, memTable[hdl].memaddrptr, /* pointer to memory address */ memTable[hdl].memsizeptr, /* pointer to size of memory */ realloc, /* reallocation function */ &finalsize, &status); /* returned file size nd status*/ } memTable[hdl].currentpos = 0; /* save starting position */ memTable[hdl].fitsfilesize=finalsize; /* and initial file size */ return status; } /*--------------------------------------------------------------------------*/ int mem_size(int handle, LONGLONG *filesize) /* return the size of the file; only called when the file is first opened */ { *filesize = memTable[handle].fitsfilesize; return(0); } /*--------------------------------------------------------------------------*/ int mem_close_free(int handle) /* close the file and free the memory. */ { free( *(memTable[handle].memaddrptr) ); memTable[handle].memaddrptr = 0; memTable[handle].memaddr = 0; return(0); } /*--------------------------------------------------------------------------*/ int mem_close_keep(int handle) /* close the memory file but do not free the memory. */ { memTable[handle].memaddrptr = 0; memTable[handle].memaddr = 0; return(0); } /*--------------------------------------------------------------------------*/ int mem_close_comp(int handle) /* compress the memory file, writing it out to the fileptr (which might be stdout) */ { int status = 0; size_t compsize; /* compress file in memory to a .gz disk file */ if(compress2file_from_mem(memTable[handle].memaddr, (size_t) (memTable[handle].fitsfilesize), memTable[handle].fileptr, &compsize, &status ) ) { ffpmsg("failed to copy memory file to file (mem_close_comp)"); status = WRITE_ERROR; } free( memTable[handle].memaddr ); /* free the memory */ memTable[handle].memaddrptr = 0; memTable[handle].memaddr = 0; /* close the compressed disk file (except if it is 'stdout' */ if (memTable[handle].fileptr != stdout) fclose(memTable[handle].fileptr); return(status); } /*--------------------------------------------------------------------------*/ int mem_seek(int handle, LONGLONG offset) /* seek to position relative to start of the file. */ { if (offset > memTable[handle].fitsfilesize ) return(END_OF_FILE); memTable[handle].currentpos = offset; return(0); } /*--------------------------------------------------------------------------*/ int mem_read(int hdl, void *buffer, long nbytes) /* read bytes from the current position in the file */ { if (memTable[hdl].currentpos + nbytes > memTable[hdl].fitsfilesize) return(END_OF_FILE); memcpy(buffer, *(memTable[hdl].memaddrptr) + memTable[hdl].currentpos, nbytes); memTable[hdl].currentpos += nbytes; return(0); } /*--------------------------------------------------------------------------*/ int mem_write(int hdl, void *buffer, long nbytes) /* write bytes at the current position in the file */ { size_t newsize; char *ptr; if ((size_t) (memTable[hdl].currentpos + nbytes) > *(memTable[hdl].memsizeptr) ) { if (!(memTable[hdl].mem_realloc)) { ffpmsg("realloc function not defined (mem_write)"); return(WRITE_ERROR); } /* Attempt to reallocate additional memory: the memory buffer size is incremented by the larger of: 1 FITS block (2880 bytes) or the defined 'deltasize' parameter */ newsize = maxvalue( (size_t) (((memTable[hdl].currentpos + nbytes - 1) / 2880) + 1) * 2880, *(memTable[hdl].memsizeptr) + memTable[hdl].deltasize); /* call the realloc function */ ptr = (memTable[hdl].mem_realloc)( *(memTable[hdl].memaddrptr), newsize); if (!ptr) { ffpmsg("Failed to reallocate memory (mem_write)"); return(MEMORY_ALLOCATION); } *(memTable[hdl].memaddrptr) = ptr; *(memTable[hdl].memsizeptr) = newsize; } /* now copy the bytes from the buffer into memory */ memcpy( *(memTable[hdl].memaddrptr) + memTable[hdl].currentpos, buffer, nbytes); memTable[hdl].currentpos += nbytes; memTable[hdl].fitsfilesize = maxvalue(memTable[hdl].fitsfilesize, memTable[hdl].currentpos); return(0); } #if HAVE_BZIP2 void bzip2uncompress2mem(char *filename, FILE *diskfile, int hdl, size_t* filesize, int* status) { BZFILE* b; int bzerror; char buf[8192]; size_t total_read = 0; char* errormsg = NULL; *filesize = 0; *status = 0; b = BZ2_bzReadOpen(&bzerror, diskfile, 0, 0, NULL, 0); if (bzerror != BZ_OK) { BZ2_bzReadClose(&bzerror, b); if (bzerror == BZ_MEM_ERROR) ffpmsg("failed to open a bzip2 file: out of memory\n"); else if (bzerror == BZ_CONFIG_ERROR) ffpmsg("failed to open a bzip2 file: miscompiled bzip2 library\n"); else if (bzerror == BZ_IO_ERROR) ffpmsg("failed to open a bzip2 file: I/O error"); else ffpmsg("failed to open a bzip2 file"); *status = READ_ERROR; return; } bzerror = BZ_OK; while (bzerror == BZ_OK) { int nread; nread = BZ2_bzRead(&bzerror, b, buf, sizeof(buf)); if (bzerror == BZ_OK || bzerror == BZ_STREAM_END) { *status = mem_write(hdl, buf, nread); if (*status) { BZ2_bzReadClose(&bzerror, b); if (*status == MEMORY_ALLOCATION) ffpmsg("Failed to reallocate memory while uncompressing bzip2 file"); return; } total_read += nread; } else { if (bzerror == BZ_IO_ERROR) errormsg = "failed to read bzip2 file: I/O error"; else if (bzerror == BZ_UNEXPECTED_EOF) errormsg = "failed to read bzip2 file: unexpected end-of-file"; else if (bzerror == BZ_DATA_ERROR) errormsg = "failed to read bzip2 file: data integrity error"; else if (bzerror == BZ_MEM_ERROR) errormsg = "failed to read bzip2 file: insufficient memory"; } } BZ2_bzReadClose(&bzerror, b); if (bzerror != BZ_OK) { if (errormsg) ffpmsg(errormsg); else ffpmsg("failure closing bzip2 file after reading\n"); *status = READ_ERROR; return; } *filesize = total_read; } #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/drvrnet.c0000644000175100001710000036552400000000000017772 0ustar00vstsdocker/* This file, drvrhttp.c contains driver routines for http, ftp and root files. */ /* This file was written by Bruce O'Neel at the ISDC, Switzerland */ /* The FITSIO software is maintained by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ /* Notes on the drivers: The ftp driver uses passive mode exclusivly. If your remote system can't deal with passive mode then it'll fail. Since Netscape Navigator uses passive mode as well there shouldn't be too many ftp servers which have problems. The http driver works properly with 301 and 302 redirects. For many more gory details see http://www.w3c.org/Protocols/rfc2068/rfc2068. The only catch to the 301/302 redirects is that they have to redirect to another http:// url. If not, things would have to change a lot in cfitsio and this was thought to be too difficult. Redirects look like 301 Moved Permanently

Moved Permanently

The document has moved
here.

This redirect was from apache 1.2.5 but most of the other servers produce something very similiar. The parser for the redirects finds the first anchor tag in the body and goes there. If that wasn't what was intended by the remote system then hopefully the error stack, which includes notes about the redirect will help the user fix the problem. **************************************************************** Note added in 2017: The redirect format shown above is actually preceded by 2 lines that look like HTTP/1.1 302 Found LOCATION: http://heasarc.gsfc.nasa.gov/FTP/software/ftools/release/other/image.fits.gz The CFITSIO parser now looks for the "Location:" string, not the html tag. **************************************************************** Root protocal doesn't have any real docs, so, the emperical docs are as follows. First, you must use a slightly modified rootd server. The modifications include implimentation of the stat command which returns the size of the remote file. Without that it's impossible for cfitsio to work properly since fitsfiles don't include any information about the size of the files in the headers. The rootd server closes the connections on any errors, including reading beyond the end of the file or seeking beyond the end of the file. The rootd:// driver doesn't reopen a closed connection, if the connection is closed you're pretty much done. The messages are of the form All binary information is transfered in network format, so use htonl and ntohl to convert back and forth. :== 4 byte length, in network format, the len doesn't include the length of :== one of the message opcodes below, 4 bytes, network format :== depends on opcode The response is of the same form with the same opcode sent. Success is indicated by being 0. Root is a NFSish protocol where each read/write includes the byte offset to read or write to. As a result, seeks will always succeed in the driver even if they would cause a fatal error when you try to read because you're beyond the end of the file. There is file locking on the host such that you need to possibly create /usr/tmp/rootdtab on the host system. There is one file per socket connection, though the rootd daemon can support multiple files open at once. The messages are sent in the following order: ROOTD_USER - user name, is the user name, trailing null is sent though it's not required it seems. A ROOTD_AUTH message is returned with any sort of error meaning that the user name is wrong. ROOTD_PASS - password, ones complemented, stored in . Once again the trailing null is sent. Once again a ROOTD_AUTH message is returned ROOTD_OPEN - includes filename and one of {create|update|read} as the file mode. ~ seems to be dealt with as the username's login directory. A ROOTD_OPEN message is returned. Once the file is opened any of the following can be sent: ROOTD_STAT - file status and size returns a message where is the file length in bytes ROOTD_FLUSH - flushes the file, not sure this has any real effect on the daemon since the daemon uses open/read/write/close rather than the buffered fopen/fread/fwrite/fclose. ROOTD_GET - on send includes a text message of offset and length to get. Return is a status message first with a status value, then, the raw bytes for the length that you requested. It's an error to seek or read past the end of the file, and, the rootd daemon exits and won't respond anymore. Ie, don't do this. ROOTD_PUT - on send includes a text message of offset and length to put. Then send the raw bytes you want to write. Then recieve a status message When you are finished then you send the message: ROOTD_CLOSE - closes the file Once the file is closed then the socket is closed. Revision 1.56 2000/01/04 11:58:31 oneel Updates so that compressed network files are dealt with regardless of their file names and/or mime types. Revision 1.55 2000/01/04 10:52:40 oneel cfitsio 2.034 Revision 1.51 1999/08/10 12:13:40 oneel Make the http code a bit less picky about the types of files it uncompresses. Now it also uncompresses files which end in .Z or .gz. Revision 1.50 1999/08/04 12:38:46 oneel Don's 2.0.32 patch with dal 1.3 Revision 1.39 1998/12/02 15:31:33 oneel Updates to drvrnet.c so that less compiler warnings would be generated. Fixes the signal handling. Revision 1.38 1998/11/23 10:03:24 oneel Added in a useragent string, as suggested by: Tim Kimball Data Systems Division kimball@stsci.edu 410-338-4417 Space Telescope Science Institute http://www.stsci.edu/~kimball/ 3700 San Martin Drive http://archive.stsci.edu/ Baltimore MD 21218 USA http://faxafloi.stsci.edu:4547/ */ #ifdef HAVE_NET_SERVICES #include #include #include #include #include #include #include #include #include #include #include #include #ifdef CFITSIO_HAVE_CURL #include #endif #if defined(unix) || defined(__unix__) || defined(__unix) || defined(HAVE_UNISTD_H) #include #endif #include #include #include "fitsio2.h" static jmp_buf env; /* holds the jump buffer for setjmp/longjmp pairs */ static void signal_handler(int sig); /* Network routine error codes */ #define NET_OK 0 #define NOT_INET_ADDRESS -1000 #define UNKNOWN_INET_HOST -1001 #define CONNECTION_ERROR -1002 /* Network routine constants */ #define NET_DEFAULT 0 #define NET_OOB 1 #define NET_PEEK 2 /* local defines and variables */ #define MAXLEN 1200 #define SHORTLEN 100 static char netoutfile[MAXLEN]; #define ROOTD_USER 2000 /*user id follows */ #define ROOTD_PASS 2001 /*passwd follows */ #define ROOTD_AUTH 2002 /*authorization status (to client) */ #define ROOTD_FSTAT 2003 /*filename follows */ #define ROOTD_OPEN 2004 /*filename follows + mode */ #define ROOTD_PUT 2005 /*offset, number of bytes and buffer */ #define ROOTD_GET 2006 /*offset, number of bytes */ #define ROOTD_FLUSH 2007 /*flush file */ #define ROOTD_CLOSE 2008 /*close file */ #define ROOTD_STAT 2009 /*return rootd statistics */ #define ROOTD_ACK 2010 /*acknowledgement (all OK) */ #define ROOTD_ERR 2011 /*error code and message follow */ typedef struct /* structure containing disk file structure */ { int sock; LONGLONG currentpos; } rootdriver; typedef struct /* simple mem struct for receiving files from curl */ { char *memory; size_t size; } curlmembuf; static rootdriver handleTable[NMAXFILES]; /* allocate diskfile handle tables */ /* static prototypes */ static int NET_TcpConnect(char *hostname, int port); static int NET_SendRaw(int sock, const void *buf, int length, int opt); static int NET_RecvRaw(int sock, void *buffer, int length); static int NET_ParseUrl(const char *url, char *proto, char *host, int *port, char *fn); static int CreateSocketAddress(struct sockaddr_in *sockaddrPtr, char *host,int port); static int ftp_status(FILE *ftp, char *statusstr); static int http_open_network(char *url, FILE **httpfile, char *contentencoding, int *contentlength); static int https_open_network(char *filename, curlmembuf* buffer); static int ftp_open_network(char *url, FILE **ftpfile, FILE **command, int *sock); static int ftps_open_network(char *filename, curlmembuf* buffer); static int ftp_file_exist(char *url); static int root_send_buffer(int sock, int op, char *buffer, int buflen); static int root_recv_buffer(int sock, int *op, char *buffer,int buflen); static int root_openfile(char *filename, char *rwmode, int *sock); static int encode64(unsigned s_len, char *src, unsigned d_len, char *dst); static int ssl_get_with_curl(char *url, curlmembuf* buffer, char* username, char* password); static size_t curlToMemCallback(void *buffer, size_t size, size_t nmemb, void *userp); static int curlProgressCallback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow); /***************************/ /* Static variables */ static int closehttpfile; static int closememfile; static int closefdiskfile; static int closediskfile; static int closefile; static int closeoutfile; static int closecommandfile; static int closeftpfile; static FILE *diskfile; static FILE *outfile; static int curl_verbose=0; static int show_fits_download_progress=0; static unsigned int net_timeout = 360; /* in seconds */ /*--------------------------------------------------------------------------*/ /* This creates a memory file handle with a copy of the URL in filename. The file is uncompressed if necessary */ int http_open(char *filename, int rwmode, int *handle) { FILE *httpfile; char contentencoding[SHORTLEN]; char errorstr[MAXLEN]; char recbuf[MAXLEN]; long len; int contentlength; int status; char firstchar; closehttpfile = 0; closememfile = 0; /* don't do r/w files */ if (rwmode != 0) { ffpmsg("Can't open http:// type file with READWRITE access"); ffpmsg(" Specify an outfile for r/w access (http_open)"); goto error; } /* do the signal handler bits */ if (setjmp(env) != 0) { /* feels like the second time */ /* this means something bad happened */ ffpmsg("Timeout (http_open)"); snprintf(errorstr, MAXLEN, "Download timeout exceeded: %d seconds",net_timeout); ffpmsg(errorstr); ffpmsg(" (multiplied x10 for files requiring uncompression)"); ffpmsg(" Timeout may be adjusted with fits_set_timeout"); goto error; } (void) signal(SIGALRM, signal_handler); /* Open the network connection */ if (http_open_network(filename,&httpfile,contentencoding, &contentlength)) { alarm(0); ffpmsg("Unable to open http file (http_open):"); ffpmsg(filename); goto error; } closehttpfile++; /* Create the memory file */ if ((status = mem_create(filename,handle))) { ffpmsg("Unable to create memory file (http_open)"); goto error; } closememfile++; /* Now, what do we do with the file */ /* Check to see what the first character is */ firstchar = fgetc(httpfile); ungetc(firstchar,httpfile); if (!strcmp(contentencoding,"x-gzip") || !strcmp(contentencoding,"x-compress") || strstr(filename,".gz") || strstr(filename,".Z") || ('\037' == firstchar)) { /* do the compress dance, which is the same as the gzip dance */ /* Using the cfitsio routine */ status = 0; /* Ok, this is a tough case, let's be arbritary and say 10*net_timeout, Given the choices for nettimeout above they'll probaby ^C before, but it's always worth a shot*/ alarm(net_timeout*10); status = mem_uncompress2mem(filename, httpfile, *handle); alarm(0); if (status) { ffpmsg("Error writing compressed memory file (http_open)"); ffpmsg(filename); goto error; } } else { /* It's not compressed, bad choice, but we'll copy it anyway */ if (contentlength % 2880) { snprintf(errorstr,MAXLEN,"Content-Length not a multiple of 2880 (http_open) %d", contentlength); ffpmsg(errorstr); } /* write a memory file */ alarm(net_timeout); while(0 != (len = fread(recbuf,1,MAXLEN,httpfile))) { alarm(0); /* cancel alarm */ status = mem_write(*handle,recbuf,len); if (status) { ffpmsg("Error copying http file into memory (http_open)"); ffpmsg(filename); goto error; } alarm(net_timeout); /* rearm the alarm */ } } fclose(httpfile); signal(SIGALRM, SIG_DFL); alarm(0); return mem_seek(*handle,0); error: alarm(0); /* clear it */ if (closehttpfile) { fclose(httpfile); } if (closememfile) { mem_close_free(*handle); } signal(SIGALRM, SIG_DFL); return (FILE_NOT_OPENED); } /*--------------------------------------------------------------------------*/ /* This creates a memory file handle with a copy of the URL in filename. The file must be compressed and is copied (still compressed) to disk first. The compressed disk file is then uncompressed into memory (READONLY). */ int http_compress_open(char *url, int rwmode, int *handle) { FILE *httpfile; char contentencoding[SHORTLEN]; char errorstr[MAXLEN]; char recbuf[MAXLEN]; long len; int contentlength; int ii, flen, status; char firstchar; closehttpfile = 0; closediskfile = 0; closefdiskfile = 0; closememfile = 0; flen = strlen(netoutfile); if (!flen) { /* cfileio made a mistake, should set the netoufile first otherwise we don't know where to write the output file */ ffpmsg ("Output file not set, shouldn't have happened (http_compress_open)"); goto error; } if (rwmode != 0) { ffpmsg("Can't open compressed http:// type file with READWRITE access"); ffpmsg(" Specify an UNCOMPRESSED outfile (http_compress_open)"); goto error; } /* do the signal handler bits */ if (setjmp(env) != 0) { /* feels like the second time */ /* this means something bad happened */ ffpmsg("Timeout (http_open)"); snprintf(errorstr, MAXLEN, "Download timeout exceeded: %d seconds",net_timeout); ffpmsg(errorstr); ffpmsg(" Timeout may be adjusted with fits_set_timeout"); goto error; } signal(SIGALRM, signal_handler); /* Open the http connectin */ alarm(net_timeout); if ((status = http_open_network(url,&httpfile,contentencoding, &contentlength))) { alarm(0); ffpmsg("Unable to open http file (http_compress_open)"); ffpmsg(url); goto error; } closehttpfile++; /* Better be compressed */ firstchar = fgetc(httpfile); ungetc(firstchar,httpfile); if (!strcmp(contentencoding,"x-gzip") || !strcmp(contentencoding,"x-compress") || ('\037' == firstchar)) { if (*netoutfile == '!') { /* user wants to clobber file, if it already exists */ for (ii = 0; ii < flen; ii++) netoutfile[ii] = netoutfile[ii + 1]; /* remove '!' */ status = file_remove(netoutfile); } /* Create the new file */ if ((status = file_create(netoutfile,handle))) { ffpmsg("Unable to create output disk file (http_compress_open):"); ffpmsg(netoutfile); goto error; } closediskfile++; /* write a file */ alarm(net_timeout); while(0 != (len = fread(recbuf,1,MAXLEN,httpfile))) { alarm(0); status = file_write(*handle,recbuf,len); if (status) { ffpmsg("Error writing disk file (http_compres_open)"); ffpmsg(netoutfile); goto error; } alarm(net_timeout); } file_close(*handle); fclose(httpfile); closehttpfile--; closediskfile--; /* File is on disk, let's uncompress it into memory */ if (NULL == (diskfile = fopen(netoutfile,"r"))) { ffpmsg("Unable to reopen disk file (http_compress_open)"); ffpmsg(netoutfile); goto error; } closefdiskfile++; /* Create the memory handle to hold it */ if ((status = mem_create(url,handle))) { ffpmsg("Unable to create memory file (http_compress_open)"); goto error; } closememfile++; /* Uncompress it */ status = 0; status = mem_uncompress2mem(url,diskfile,*handle); fclose(diskfile); closefdiskfile--; if (status) { ffpmsg("Error uncompressing disk file to memory (http_compress_open)"); ffpmsg(netoutfile); goto error; } } else { /* Opps, this should not have happened */ ffpmsg("Can only have compressed files here (http_compress_open)"); goto error; } signal(SIGALRM, SIG_DFL); alarm(0); return mem_seek(*handle,0); error: alarm(0); /* clear it */ if (closehttpfile) { fclose(httpfile); } if (closefdiskfile) { fclose(diskfile); } if (closememfile) { mem_close_free(*handle); } if (closediskfile) { file_close(*handle); } signal(SIGALRM, SIG_DFL); return (FILE_NOT_OPENED); } /*--------------------------------------------------------------------------*/ /* This creates a file handle with a copy of the URL in filename. The http file is copied to disk first. If it's compressed then it is uncompressed when copying to the disk */ int http_file_open(char *url, int rwmode, int *handle) { FILE *httpfile; char contentencoding[SHORTLEN]; char errorstr[MAXLEN]; char recbuf[MAXLEN]; long len; int contentlength; int ii, flen, status; char firstchar; /* Check if output file is actually a memory file */ if (!strncmp(netoutfile, "mem:", 4) ) { /* allow the memory file to be opened with write access */ return( http_open(url, READONLY, handle) ); } closehttpfile = 0; closefile = 0; closeoutfile = 0; flen = strlen(netoutfile); if (!flen) { /* cfileio made a mistake, we need to know where to write the file */ ffpmsg("Output file not set, shouldn't have happened (http_file_open)"); return (FILE_NOT_OPENED); } /* do the signal handler bits */ if (setjmp(env) != 0) { /* feels like the second time */ /* this means something bad happened */ ffpmsg("Timeout (http_open)"); snprintf(errorstr, MAXLEN, "Download timeout exceeded: %d seconds",net_timeout); ffpmsg(errorstr); ffpmsg(" (multiplied x10 for files requiring uncompression)"); ffpmsg(" Timeout may be adjusted with fits_set_timeout"); goto error; } signal(SIGALRM, signal_handler); /* Open the network connection */ alarm(net_timeout); if ((status = http_open_network(url,&httpfile,contentencoding, &contentlength))) { alarm(0); ffpmsg("Unable to open http file (http_file_open)"); ffpmsg(url); goto error; } closehttpfile++; if (*netoutfile == '!') { /* user wants to clobber disk file, if it already exists */ for (ii = 0; ii < flen; ii++) netoutfile[ii] = netoutfile[ii + 1]; /* remove '!' */ status = file_remove(netoutfile); } firstchar = fgetc(httpfile); ungetc(firstchar,httpfile); if (!strcmp(contentencoding,"x-gzip") || !strcmp(contentencoding,"x-compress") || ('\037' == firstchar)) { /* to make this more cfitsioish we use the file driver calls to create the disk file */ /* Create the output file */ if ((status = file_create(netoutfile,handle))) { ffpmsg("Unable to create output file (http_file_open)"); ffpmsg(netoutfile); goto error; } file_close(*handle); if (NULL == (outfile = fopen(netoutfile,"w"))) { ffpmsg("Unable to reopen the output file (http_file_open)"); ffpmsg(netoutfile); goto error; } closeoutfile++; status = 0; /* Ok, this is a tough case, let's be arbritary and say 10*net_timeout, Given the choices for nettimeout above they'll probaby ^C before, but it's always worth a shot*/ alarm(net_timeout*10); status = uncompress2file(url,httpfile,outfile,&status); alarm(0); if (status) { ffpmsg("Error uncompressing http file to disk file (http_file_open)"); ffpmsg(url); ffpmsg(netoutfile); goto error; } fclose(outfile); closeoutfile--; } else { /* Create the output file */ if ((status = file_create(netoutfile,handle))) { ffpmsg("Unable to create output file (http_file_open)"); ffpmsg(netoutfile); goto error; } /* Give a warning message. This could just be bad padding at the end so don't treat it like an error. */ closefile++; if (contentlength % 2880) { snprintf(errorstr, MAXLEN, "Content-Length not a multiple of 2880 (http_file_open) %d", contentlength); ffpmsg(errorstr); } /* write a file */ alarm(net_timeout); while(0 != (len = fread(recbuf,1,MAXLEN,httpfile))) { alarm(0); status = file_write(*handle,recbuf,len); if (status) { ffpmsg("Error copying http file to disk file (http_file_open)"); ffpmsg(url); ffpmsg(netoutfile); goto error; } } file_close(*handle); closefile--; } fclose(httpfile); closehttpfile--; signal(SIGALRM, SIG_DFL); alarm(0); return file_open(netoutfile,rwmode,handle); error: alarm(0); /* clear it */ if (closehttpfile) { fclose(httpfile); } if (closeoutfile) { fclose(outfile); } if (closefile) { file_close(*handle); } signal(SIGALRM, SIG_DFL); return (FILE_NOT_OPENED); } /*--------------------------------------------------------------------------*/ /* This is the guts of the code to get a file via http. url is the input url httpfile is set to be the file connected to the socket which you can read the file from contentencoding is the mime type of the file, returned if the http server returns it contentlength is the length of the file, returned if the http server returns it */ static int http_open_network(char *url, FILE **httpfile, char *contentencoding, int *contentlength) { int status; int sock; int tmpint; char recbuf[MAXLEN]; char tmpstr[MAXLEN]; char tmpstr1[SHORTLEN]; char tmpstr2[MAXLEN]; char errorstr[MAXLEN]; char proto[SHORTLEN]; char host[SHORTLEN]; char userpass[MAXLEN]; char fn[MAXLEN]; char turl[MAXLEN]; char *scratchstr; char *scratchstr2; char *saveptr; int port; float version; char pproto[SHORTLEN]; char phost[SHORTLEN]; /* address of the proxy server */ int pport; /* port number of the proxy server */ char pfn[MAXLEN]; char *proxy; /* URL of the proxy server */ /* Parse the URL apart again */ strcpy(turl,"http://"); strncat(turl,url,MAXLEN - 8); if (NET_ParseUrl(turl,proto,host,&port,fn)) { snprintf(errorstr,MAXLEN,"URL Parse Error (http_open) %s",url); ffpmsg(errorstr); return (FILE_NOT_OPENED); } /* Do we have a user:password combo ? */ strcpy(userpass, url); if ((scratchstr = strchr(userpass, '@')) != NULL) { *scratchstr = '\0'; } else { strcpy(userpass, ""); } /* Ph. Prugniel 2003/04/03 Are we using a proxy? We use a proxy if the environment variable "http_proxy" is set to an address, eg. http://wwwcache.nottingham.ac.uk:3128 ("http_proxy" is also used by wget) */ proxy = getenv("http_proxy"); /* Connect to the remote host */ if (proxy) { if (NET_ParseUrl(proxy,pproto,phost,&pport,pfn)) { snprintf(errorstr,MAXLEN,"URL Parse Error (http_open) %s",proxy); ffpmsg(errorstr); return (FILE_NOT_OPENED); } sock = NET_TcpConnect(phost,pport); } else { sock = NET_TcpConnect(host,port); } if (sock < 0) { if (proxy) { ffpmsg("Couldn't connect to host via proxy server (http_open_network)"); ffpmsg(proxy); } return (FILE_NOT_OPENED); } /* Make the socket a stdio file */ if (NULL == (*httpfile = fdopen(sock,"r"))) { ffpmsg ("fdopen failed to convert socket to file (http_open_network)"); close(sock); return (FILE_NOT_OPENED); } /* Send the GET request to the remote server */ /* Ph. Prugniel 2003/04/03 One must add the Host: command because of HTTP 1.1 servers (ie. virtual hosts) */ if (proxy) { snprintf(tmpstr,MAXLEN,"GET http://%s:%-d%s HTTP/1.0\r\n",host,port,fn); } else { snprintf(tmpstr,MAXLEN,"GET %s HTTP/1.0\r\n",fn); } if (strcmp(userpass, "")) { encode64(strlen(userpass), userpass, MAXLEN, tmpstr2); snprintf(tmpstr1, SHORTLEN,"Authorization: Basic %s\r\n", tmpstr2); if (strlen(tmpstr) + strlen(tmpstr1) > MAXLEN - 1) { fclose(*httpfile); *httpfile=0; return (FILE_NOT_OPENED); } strcat(tmpstr,tmpstr1); } /* snprintf(tmpstr1,SHORTLEN,"User-Agent: HEASARC/CFITSIO/%-8.3f\r\n",ffvers(&version)); */ /* snprintf(tmpstr1,SHORTLEN,"User-Agent: CFITSIO/HEASARC/%-8.3f\r\n",ffvers(&version)); */ snprintf(tmpstr1,SHORTLEN,"User-Agent: FITSIO/HEASARC/%-8.3f\r\n",ffvers(&version)); if (strlen(tmpstr) + strlen(tmpstr1) > MAXLEN - 1) { fclose(*httpfile); *httpfile=0; return (FILE_NOT_OPENED); } strcat(tmpstr,tmpstr1); /* HTTP 1.1 servers require the following 'Host: ' string */ snprintf(tmpstr1,SHORTLEN,"Host: %s:%-d\r\n\r\n",host,port); if (strlen(tmpstr) + strlen(tmpstr1) > MAXLEN - 1) { fclose(*httpfile); *httpfile=0; return (FILE_NOT_OPENED); } strcat(tmpstr,tmpstr1); status = NET_SendRaw(sock,tmpstr,strlen(tmpstr),NET_DEFAULT); /* read the header */ if (!(fgets(recbuf,MAXLEN,*httpfile))) { snprintf (errorstr,MAXLEN,"http header short (http_open_network) %s",recbuf); ffpmsg(errorstr); fclose(*httpfile); *httpfile=0; return (FILE_NOT_OPENED); } *contentlength = 0; contentencoding[0] = '\0'; /* Our choices are 200, ok, 302, temporary redirect, or 301 perm redirect */ sscanf(recbuf,"%s %d",tmpstr,&status); if (status != 200){ if (status == 301 || status == 302) { /* got a redirect */ /* if (status == 302) { ffpmsg("Note: Web server replied with a temporary redirect from"); } else { ffpmsg("Note: Web server replied with a redirect from"); } ffpmsg(turl); */ /* now, let's not write the most sophisticated parser here */ while (fgets(recbuf,MAXLEN,*httpfile)) { scratchstr = strstr(recbuf,"Location: "); if (scratchstr != NULL) { /* Ok, we found the Location line which gives the redirected URL */ /* skip the "Location: " charactrers */ scratchstr += 10; /* strip off any end-of-line characters */ tmpint = strlen(scratchstr); if (scratchstr[tmpint-1] == '\r') scratchstr[tmpint-1] = '\0'; tmpint = strlen(scratchstr); if (scratchstr[tmpint-1] == '\n') scratchstr[tmpint-1] = '\0'; tmpint = strlen(scratchstr); if (scratchstr[tmpint-1] == '\r') scratchstr[tmpint-1] = '\0'; /* ffpmsg("to:"); ffpmsg(scratchstr); ffpmsg(" "); */ scratchstr2 = strstr(scratchstr,"http://"); if (scratchstr2 != NULL) { /* Ok, we found the HTTP redirection is to another HTTP URL. */ /* We can handle this case directly, here */ /* skip the "http://" characters */ scratchstr2 += 7; strcpy(turl, scratchstr2); fclose (*httpfile); *httpfile=0; /* note the recursive call to itself */ return http_open_network(turl,httpfile,contentencoding,contentlength); } /* It was not a HTTP to HTTP redirection, so see if it HTTP to FTP */ scratchstr2 = strstr(scratchstr,"ftp://"); if (scratchstr2 != NULL) { /* Ok, we found the HTTP redirection is to a FTP URL. */ /* skip the "ftp://" characters */ scratchstr2 += 6; /* return the new URL string, and set contentencoding to "ftp" as a flag to the http_checkfile routine */ if (strlen(scratchstr2) > FLEN_FILENAME-1) { ffpmsg("Error: redirected url string too long (http_open_network)"); fclose(*httpfile); *httpfile=0; return URL_PARSE_ERROR; } strcpy(url, scratchstr2); strcpy(contentencoding,"ftp://"); fclose (*httpfile); *httpfile=0; return 0; } /* Now check for HTTP to HTTPS redirection. */ scratchstr2 = strstr(scratchstr,"https://"); if (scratchstr2 != NULL) { /* skip the "https://" characters */ scratchstr2 += 8; /* return the new URL string, and set contentencoding to "https" as a flag to the http_checkfile routine */ if (strlen(scratchstr2) > FLEN_FILENAME-1) { ffpmsg("Error: redirected url string too long (http_open_network)"); fclose(*httpfile); return URL_PARSE_ERROR; } strcpy(url, scratchstr2); strcpy(contentencoding,"https://"); fclose(*httpfile); *httpfile=0; return 0; } } } /* if we get here then we couldnt' decide the redirect */ ffpmsg("but we were unable to find the redirected url in the servers response"); } /* error. could not open the http file */ fclose(*httpfile); *httpfile=0; return (FILE_NOT_OPENED); } /* from here the first word holds the keyword we want */ /* so, read the rest of the header */ while (fgets(recbuf,MAXLEN,*httpfile)) { /* Blank line ends the header */ if (*recbuf == '\r') break; if (strlen(recbuf) > 3) { recbuf[strlen(recbuf)-1] = '\0'; recbuf[strlen(recbuf)-1] = '\0'; } sscanf(recbuf,"%s %d",tmpstr,&tmpint); /* Did we get a content-length header ? */ if (!strcmp(tmpstr,"Content-Length:")) { *contentlength = tmpint; } /* Did we get the content-encoding header ? */ if (!strcmp(tmpstr,"Content-Encoding:")) { if (NULL != (scratchstr = strstr(recbuf,":"))) { /* Found the : */ scratchstr++; /* skip the : */ scratchstr++; /* skip the extra space */ if (strlen(scratchstr) > SHORTLEN-1) { ffpmsg("Error: content-encoding string too long (http_open_network)"); fclose(*httpfile); *httpfile=0; return URL_PARSE_ERROR; } strcpy(contentencoding,scratchstr); } } } /* we're done, so return */ return 0; } /*--------------------------------------------------------------------------*/ /* This creates a memory file handle with a copy of the URL in filename. The curl library called from https_open_network will perform file uncompression if necessary. */ int https_open(char *filename, int rwmode, int *handle) { curlmembuf inmem; char errStr[MAXLEN]; int status=0; /* don't do r/w files */ if (rwmode != 0) { ffpmsg("Can't open https:// type file with READWRITE access"); ffpmsg(" Specify an outfile for r/w access (https_open)"); return (FILE_NOT_OPENED); } inmem.memory=0; inmem.size=0; if (setjmp(env) != 0) { alarm(0); signal(SIGALRM, SIG_DFL); ffpmsg("Timeout (https_open)"); snprintf(errStr, MAXLEN, "Download timeout exceeded: %d seconds",net_timeout); ffpmsg(errStr); ffpmsg(" Timeout may be adjusted with fits_set_timeout"); free(inmem.memory); return (FILE_NOT_OPENED); } signal(SIGALRM, signal_handler); alarm(net_timeout); if (https_open_network(filename, &inmem)) { alarm(0); signal(SIGALRM, SIG_DFL); ffpmsg("Unable to read https file into memory (https_open)"); free(inmem.memory); return (FILE_NOT_OPENED); } alarm(0); signal(SIGALRM, SIG_DFL); /* We now have the file transfered from the https server into the inmem.memory buffer. Now transfer that into a FITS memory file. */ if ((status = mem_create(filename, handle))) { ffpmsg("Unable to create memory file (https_open)"); free(inmem.memory); return (FILE_NOT_OPENED); } if (inmem.size % 2880) { snprintf(errStr,MAXLEN,"Content-Length not a multiple of 2880 (https_open) %u", inmem.size); ffpmsg(errStr); } status = mem_write(*handle, inmem.memory, inmem.size); if (status) { ffpmsg("Error copying https file into memory (https_open)"); ffpmsg(filename); free(inmem.memory); mem_close_free(*handle); return (FILE_NOT_OPENED); } free(inmem.memory); return mem_seek(*handle, 0); } /*--------------------------------------------------------------------------*/ int https_file_open(char *filename, int rwmode, int *handle) { int ii, flen; char errStr[MAXLEN]; curlmembuf inmem; /* Check if output file is actually a memory file */ if (!strncmp(netoutfile, "mem:", 4) ) { /* allow the memory file to be opened with write access */ return( https_open(filename, READONLY, handle) ); } flen = strlen(netoutfile); if (!flen) { /* cfileio made a mistake, we need to know where to write the file */ ffpmsg("Output file not set, shouldn't have happened (https_file_open)"); return (FILE_NOT_OPENED); } inmem.memory=0; inmem.size=0; if (setjmp(env) != 0) { alarm(0); signal(SIGALRM, SIG_DFL); ffpmsg("Timeout (https_file_open)"); snprintf(errStr, MAXLEN, "Download timeout exceeded: %d seconds",net_timeout); ffpmsg(errStr); ffpmsg(" Timeout may be adjusted with fits_set_timeout"); free(inmem.memory); return (FILE_NOT_OPENED); } signal(SIGALRM, signal_handler); alarm(net_timeout); if (https_open_network(filename, &inmem)) { alarm(0); signal(SIGALRM, SIG_DFL); ffpmsg("Unable to read https file into memory (https_file_open)"); free(inmem.memory); return (FILE_NOT_OPENED); } alarm(0); signal(SIGALRM, SIG_DFL); if (*netoutfile == '!') { /* user wants to clobber disk file, if it already exists */ for (ii = 0; ii < flen; ii++) netoutfile[ii] = netoutfile[ii + 1]; /* remove '!' */ file_remove(netoutfile); } /* Create the output file */ if (file_create(netoutfile,handle)) { ffpmsg("Unable to create output file (https_file_open)"); ffpmsg(netoutfile); free(inmem.memory); return (FILE_NOT_OPENED); } if (inmem.size % 2880) { snprintf(errStr, MAXLEN, "Content-Length not a multiple of 2880 (https_file_open) %d", inmem.size); ffpmsg(errStr); } if (file_write(*handle, inmem.memory, inmem.size)) { ffpmsg("Error copying https file to disk file (https_file_open)"); ffpmsg(filename); ffpmsg(netoutfile); free(inmem.memory); file_close(*handle); return (FILE_NOT_OPENED); } free(inmem.memory); file_close(*handle); return file_open(netoutfile, rwmode, handle); } /*--------------------------------------------------------------------------*/ /* Callback function curl library uses during https connection to transfer server file into memory */ size_t curlToMemCallback(void *buffer, size_t size, size_t nmemb, void *userp) { curlmembuf* inmem = (curlmembuf* )userp; size_t transferSize = size*nmemb; if (!inmem->size) { /* First time through - initialize with malloc */ inmem->memory = (char *)malloc(transferSize); } else inmem->memory = realloc(inmem->memory, inmem->size+transferSize); if (inmem->memory == NULL) { ffpmsg("realloc error - not enough memory (curlToMemCallback)\n"); return 0; } memcpy(&(inmem->memory[inmem->size]), buffer, transferSize); inmem->size += transferSize; return transferSize; } /*--------------------------------------------------------------------------*/ /* Callback function for displaying status bar during download */ int curlProgressCallback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) { int i, fullBar = 50, nToDisplay = 0; int percent = 0; double fracCompleted = 0.0; char *urlname=0; static int isComplete = 0; static int isFirst = 1; /* isFirst is true the very first time this is entered. Afterwards it should get reset to true when isComplete is first detected to have toggled from true to false. */ if (dltotal == 0.0) { if (isComplete) isFirst = 1; isComplete = 0; return 0; } fracCompleted = dlnow/dltotal; percent = (int)ceil(fracCompleted*100.0 - 0.5); if (isComplete && percent < 100) isFirst = 1; if (!isComplete || percent < 100) { if (isFirst) { urlname = (char *)clientp; if (urlname) { fprintf(stderr,"Downloading "); fprintf(stderr,"%s",urlname); fprintf(stderr,"...\n"); } isFirst = 0; } isComplete = (percent >= 100) ? 1 : 0; nToDisplay = (int)ceil(fracCompleted*fullBar - 0.5); /* Can dlnow ever be > dltotal? Just in case... */ if (nToDisplay > fullBar) nToDisplay = fullBar; fprintf(stderr,"%3d%% [",percent); for (i=0; i 0) net_timeout = (unsigned int)sec; return (int)net_timeout; } /*--------------------------------------------------------------------------*/ int ftps_open(char *filename, int rwmode, int *handle) { curlmembuf inmem; char errStr[MAXLEN]; char localFilename[MAXLEN]; /* may have .gz or .Z appended in ftps_open_network.*/ unsigned char firstByte=0,secondByte=0; int status=0; FILE *compressedFile=0; strcpy(localFilename,filename); /* don't do r/w files */ if (rwmode != 0) { ffpmsg("Can't open ftps:// type file with READWRITE access"); ffpmsg(" Specify an outfile for r/w access (ftps_open)"); return (FILE_NOT_OPENED); } inmem.memory=0; inmem.size=0; if (setjmp(env) != 0) { alarm(0); signal(SIGALRM, SIG_DFL); ffpmsg("Timeout (ftps_open)"); snprintf(errStr, MAXLEN, "Download timeout exceeded: %d seconds",net_timeout); ffpmsg(errStr); ffpmsg(" Timeout may be adjusted with fits_set_timeout"); free(inmem.memory); return (FILE_NOT_OPENED); } signal(SIGALRM, signal_handler); alarm(net_timeout); if (ftps_open_network(localFilename, &inmem)) { alarm(0); signal(SIGALRM, SIG_DFL); ffpmsg("Unable to read ftps file into memory (ftps_open)"); free(inmem.memory); return (FILE_NOT_OPENED); } alarm(0); signal(SIGALRM, SIG_DFL); if (strcmp(localFilename, filename)) { /* ftps_open_network has already checked that this is safe to copy into string of size FLEN_FILENAME */ strcpy(filename, localFilename); } /* We now have the file transfered from the ftps server into the inmem.memory buffer. Now transfer that into a FITS memory file. */ if ((status = mem_create(filename, handle))) { ffpmsg("Unable to create memory file (ftps_open)"); free(inmem.memory); return (FILE_NOT_OPENED); } if (inmem.size > 1) { firstByte = (unsigned char)inmem.memory[0]; secondByte = (unsigned char)inmem.memory[1]; } if (firstByte == 0x1f && secondByte == 0x8b || strstr(localFilename,".Z")) { #ifdef HAVE_FMEMOPEN compressedFile = fmemopen(inmem.memory, inmem.size, "r"); #endif if (!compressedFile) { ffpmsg("Error creating file in memory (ftps_open)"); free(inmem.memory); return(FILE_NOT_OPENED); } if(mem_uncompress2mem(localFilename,compressedFile,*handle)) { ffpmsg("Error writing compressed memory file (ftps_open)"); ffpmsg(filename); fclose(compressedFile); free(inmem.memory); return(FILE_NOT_OPENED); } fclose(compressedFile); } else { if (inmem.size % 2880) { snprintf(errStr,MAXLEN,"Content-Length not a multiple of 2880 (ftps_open) %u", inmem.size); ffpmsg(errStr); } status = mem_write(*handle, inmem.memory, inmem.size); if (status) { ffpmsg("Error copying https file into memory (ftps_open)"); ffpmsg(filename); free(inmem.memory); mem_close_free(*handle); return (FILE_NOT_OPENED); } } free(inmem.memory); return mem_seek(*handle, 0); } /*--------------------------------------------------------------------------*/ int ftps_file_open(char *filename, int rwmode, int *handle) { int ii, flen, status=0; char errStr[MAXLEN]; char localFilename[MAXLEN]; /* may have .gz or .Z appended */ unsigned char firstByte=0,secondByte=0; curlmembuf inmem; FILE *compressedInFile=0; strcpy(localFilename, filename); /* Check if output file is actually a memory file */ if (!strncmp(netoutfile, "mem:", 4) ) { /* allow the memory file to be opened with write access */ return( ftps_open(filename, READONLY, handle) ); } flen = strlen(netoutfile); if (!flen) { /* cfileio made a mistake, we need to know where to write the file */ ffpmsg("Output file not set, shouldn't have happened (ftps_file_open)"); return (FILE_NOT_OPENED); } inmem.memory=0; inmem.size=0; if (setjmp(env) != 0) { alarm(0); signal(SIGALRM, SIG_DFL); ffpmsg("Timeout (ftps_file_open)"); snprintf(errStr, MAXLEN, "Download timeout exceeded: %d seconds",net_timeout); ffpmsg(errStr); ffpmsg(" Timeout may be adjusted with fits_set_timeout"); free(inmem.memory); return (FILE_NOT_OPENED); } signal(SIGALRM, signal_handler); alarm(net_timeout); if (ftps_open_network(localFilename, &inmem)) { alarm(0); signal(SIGALRM, SIG_DFL); ffpmsg("Unable to read ftps file into memory (ftps_file_open)"); free(inmem.memory); return (FILE_NOT_OPENED); } alarm(0); signal(SIGALRM, SIG_DFL); if (strstr(localFilename, ".Z")) { ffpmsg(".Z decompression not supported for file output (ftps_file_open)"); free(inmem.memory); return (FILE_NOT_OPENED); } if (strcmp(localFilename, filename)) { /* ftps_open_network has already checked that this is safe to copy into string of size FLEN_FILENAME */ strcpy(filename, localFilename); } if (*netoutfile == '!') { /* user wants to clobber disk file, if it already exists */ for (ii = 0; ii < flen; ii++) netoutfile[ii] = netoutfile[ii + 1]; /* remove '!' */ file_remove(netoutfile); } /* Create the output file */ if (file_create(netoutfile,handle)) { ffpmsg("Unable to create output file (ftps_file_open)"); ffpmsg(netoutfile); free(inmem.memory); return (FILE_NOT_OPENED); } if (inmem.size > 1) { firstByte = (unsigned char)inmem.memory[0]; secondByte = (unsigned char)inmem.memory[1]; } if (firstByte == 0x1f && secondByte == 0x8b) { /* Doing a file create/close/reopen to mimic the procedure in ftp_file_open. The earlier call to file_create ensures that checking is performed for the Hera case. */ file_close(*handle); /* Reopen with direct call to fopen to set the outfile pointer */ outfile = fopen(netoutfile,"w"); if (!outfile) { ffpmsg("Unable to reopen the output file (ftps_file_open)"); ffpmsg(netoutfile); free(inmem.memory); return(FILE_NOT_OPENED); } #ifdef HAVE_FMEMOPEN compressedInFile = fmemopen(inmem.memory, inmem.size, "r"); #endif if (!compressedInFile) { ffpmsg("Error creating compressed file in memory (ftps_file_open)"); free(inmem.memory); fclose(outfile); return(FILE_NOT_OPENED); } if (uncompress2file(filename, compressedInFile, outfile, &status)) { ffpmsg("Unable to uncompress the output file (ftps_file_open)"); ffpmsg(filename); ffpmsg(netoutfile); fclose(outfile); fclose(compressedInFile); free(inmem.memory); return(FILE_NOT_OPENED); } fclose(outfile); fclose(compressedInFile); } else { if (inmem.size % 2880) { snprintf(errStr, MAXLEN, "Content-Length not a multiple of 2880 (ftps_file_open) %d", inmem.size); ffpmsg(errStr); } if (file_write(*handle, inmem.memory, inmem.size)) { ffpmsg("Error copying ftps file to disk file (ftps_file_open)"); ffpmsg(filename); ffpmsg(netoutfile); free(inmem.memory); file_close(*handle); return (FILE_NOT_OPENED); } file_close(*handle); } free(inmem.memory); return file_open(netoutfile, rwmode, handle); } /*--------------------------------------------------------------------------*/ int ftps_compress_open(char *filename, int rwmode, int *handle) { int ii, flen, status=0; char errStr[MAXLEN]; char localFilename[MAXLEN]; /* may have .gz or .Z appended */ unsigned char firstByte=0,secondByte=0; curlmembuf inmem; FILE *compressedInFile=0; /* don't do r/w files */ if (rwmode != 0) { ffpmsg("Compressed files must be r/o"); return (FILE_NOT_OPENED); } strcpy(localFilename, filename); flen = strlen(netoutfile); if (!flen) { /* cfileio made a mistake, we need to know where to write the file */ ffpmsg("Output file not set, shouldn't have happened (ftps_compress_open)"); return (FILE_NOT_OPENED); } inmem.memory=0; inmem.size=0; if (setjmp(env) != 0) { alarm(0); signal(SIGALRM, SIG_DFL); ffpmsg("Timeout (ftps_compress_open)"); snprintf(errStr, MAXLEN, "Download timeout exceeded: %d seconds",net_timeout); ffpmsg(errStr); ffpmsg(" Timeout may be adjusted with fits_set_timeout"); free(inmem.memory); return (FILE_NOT_OPENED); } signal(SIGALRM, signal_handler); alarm(net_timeout); if (ftps_open_network(localFilename, &inmem)) { alarm(0); signal(SIGALRM, SIG_DFL); ffpmsg("Unable to read ftps file into memory (ftps_compress_open)"); free(inmem.memory); return (FILE_NOT_OPENED); } alarm(0); signal(SIGALRM, SIG_DFL); if (strcmp(localFilename, filename)) { /* ftps_open_network has already checked that this is safe to copy into string of size FLEN_FILENAME */ strcpy(filename, localFilename); } if (inmem.size > 1) { firstByte = (unsigned char)inmem.memory[0]; secondByte = (unsigned char)inmem.memory[1]; } if ((firstByte == 0x1f && secondByte == 0x8b) || strstr(localFilename,".gz") || strstr(localFilename,".Z")) { if (*netoutfile == '!') { /* user wants to clobber disk file, if it already exists */ for (ii = 0; ii < flen; ii++) netoutfile[ii] = netoutfile[ii + 1]; /* remove '!' */ file_remove(netoutfile); } /* Create the output file */ if (file_create(netoutfile,handle)) { ffpmsg("Unable to create output file (ftps_compress_open)"); ffpmsg(netoutfile); free(inmem.memory); return (FILE_NOT_OPENED); } if (file_write(*handle, inmem.memory, inmem.size)) { ffpmsg("Error copying ftps file to disk file (ftps_file_open)"); ffpmsg(filename); ffpmsg(netoutfile); free(inmem.memory); file_close(*handle); return (FILE_NOT_OPENED); } file_close(*handle); /* File is on disk, let's uncompress it into memory */ if (NULL == (diskfile = fopen(netoutfile,"r"))) { ffpmsg("Unable to reopen disk file (ftps_compress_open)"); ffpmsg(netoutfile); free(inmem.memory); return (FILE_NOT_OPENED); } if ((status = mem_create(localFilename,handle))) { ffpmsg("Unable to create memory file (ftps_compress_open)"); ffpmsg(localFilename); free(inmem.memory); fclose(diskfile); diskfile=0; return (FILE_NOT_OPENED); } status = mem_uncompress2mem(localFilename,diskfile,*handle); fclose(diskfile); diskfile=0; if (status) { ffpmsg("Error writing compressed memory file (ftps_compress_open)"); free(inmem.memory); mem_close_free(*handle); return (FILE_NOT_OPENED); } } else { ffpmsg("Cannot write uncompressed infile to compressed outfile (ftps_compress_open)"); free(inmem.memory); return (FILE_NOT_OPENED); } free(inmem.memory); return mem_seek(*handle,0); } /*--------------------------------------------------------------------------*/ int ftps_open_network(char *filename, curlmembuf* buffer) { char agentStr[SHORTLEN]; char url[MAXLEN]; char tmphost[SHORTLEN]; /* work array for separating user/pass/host names */ char *username=0; char *password=0; char *hostname=0; char *dirpath=0; char *strptr=0; float version=0.0; int iDirpath=0, len=0, origLen=0; int status=0; strcpy(url,"ftp://"); /* The filename may already contain a username and password, as indicated by a '@' within the host part of the name (which we'll define as the substring before the first '/'). If not, we'll set a default username:password */ len = strlen(filename); for (iDirpath=0; iDirpath SHORTLEN-1) { ffpmsg("Host name is too long in URL (ftps_open_network)"); return (FILE_NOT_OPENED); } strncpy(tmphost, filename, iDirpath); dirpath = &filename[iDirpath]; tmphost[iDirpath]='\0'; /* There could be more than one '@' since they can also exist in the username or password. Find the right-most '@' and assume that it delimits the host name. */ hostname = strrchr(tmphost, '@'); if (hostname) { *hostname = '\0'; ++hostname; /* Assume first occurrence of ':' is indicative of password delimiter. */ password = strchr(tmphost, ':'); if (password) { *password = '\0'; ++password; } username = tmphost; } else hostname = tmphost; if (!username || strlen(username)==0) username = "anonymous"; if (!password || strlen(password)==0) { snprintf(agentStr,SHORTLEN,"User-Agent: FITSIO/HEASARC/%-8.3f",ffvers(&version)); password = agentStr; } /* url may eventually have .gz or .Z appended to it */ if (strlen(url) + strlen(hostname) + strlen(dirpath) > MAXLEN-4) { ffpmsg("Full URL name is too long (ftps_open_network)"); return (FILE_NOT_OPENED); } strcat(url, hostname); strcat(url, dirpath); /* printf("url = %s\n",url); printf("username = %s\n",username); printf("password = %s\n",password); printf("hostname = %s\n",hostname); */ origLen = strlen(url); status = ssl_get_with_curl(url, buffer, username, password); /* If original url has .gz or .Z appended, do the same to the original filename. Note that url also differs from original filename at this point, since filename may have included username@password (which url would not). */ len = strlen(url); if ((len-origLen) == 2 || (len-origLen) == 3) { if (strlen(filename) > FLEN_FILENAME - 4) { ffpmsg("Filename is too long to append compression ext (ftps_open_network)"); /* buffer memory must be freed by calling routine */ return (FILE_NOT_OPENED); } strptr = url + origLen; strcat(filename, strptr); } return status; } /*--------------------------------------------------------------------------*/ /* Function to perform common curl interfacing for https or ftps transfers */ int ssl_get_with_curl(char *url, curlmembuf* buffer, char* username, char* password) { /* These settings will force libcurl to perform host and peer authentication. If it fails, this routine will try again without authentication (unless user forbids this via CFITSIO_VERIFY_HTTPS environment variable). */ long verifyPeer = 1; long verifyHost = 2; char errStr[MAXLEN]; char agentStr[MAXLEN]; float version=0.0; char *tmpUrl=0; char *verify=0; int isFtp = (strstr(url,"ftp://") != NULL); int experimentWithCompression = (!strstr(url,".gz") && !strstr(url,".Z") && !strstr(url,"?")); int notFound=1; #ifdef CFITSIO_HAVE_CURL CURL *curl=0; CURLcode res; char curlErrBuf[CURL_ERROR_SIZE]; if (strstr(url,".Z") && !isFtp) { ffpmsg("x-compress .Z format not currently supported with curl https transfers"); return(FILE_NOT_OPENED); } /* Will ASSUME curl_global_init has been called by this point. It is not thread-safe to call it here. */ curl = curl_easy_init(); res = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, verifyPeer); if (res != CURLE_OK) { ffpmsg("ERROR: CFITSIO was built with a libcurl library that "); ffpmsg("does not have SSL support, and therefore can't perform https or ftps transfers."); return (FILE_NOT_OPENED); } curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, verifyHost); curl_easy_setopt(curl, CURLOPT_VERBOSE, (long)curl_verbose); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlToMemCallback); snprintf(agentStr,MAXLEN,"User-Agent: FITSIO/HEASARC/%-8.3f",ffvers(&version)); curl_easy_setopt(curl, CURLOPT_USERAGENT,agentStr); buffer->memory = 0; /* malloc/realloc will grow this in the callback function */ buffer->size = 0; curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)buffer); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curlErrBuf); curlErrBuf[0]=0; /* This is needed for easy_perform to return an error whenever http server returns an error >= 400, ie. if it can't find the requested file. */ curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); /* This turns on automatic decompression for all recognized types. */ curl_easy_setopt(curl, CURLOPT_ENCODING, ""); /* tmpUrl should be large enough to accomodate original url + ".gz" */ tmpUrl = (char *)malloc(strlen(url)+4); strcpy(tmpUrl, url); if (show_fits_download_progress) { curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, curlProgressCallback); curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, tmpUrl); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); } else curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L); /* USESSL only necessary for ftps, though it may not hurt anything if it were also set for https. */ if (isFtp) { curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL); if (username) curl_easy_setopt(curl, CURLOPT_USERNAME, username); if (password) curl_easy_setopt(curl, CURLOPT_PASSWORD, password); } /* Unless url already contains a .gz, .Z or '?' (probably from a cgi script), first try with .gz appended. */ if (experimentWithCompression) strcat(tmpUrl, ".gz"); /* First attempt: verification on */ curl_easy_setopt(curl, CURLOPT_URL, tmpUrl); res = curl_easy_perform(curl); if (res != CURLE_OK && res != CURLE_HTTP_RETURNED_ERROR && res != CURLE_REMOTE_FILE_NOT_FOUND) { /* CURLE_HTTP_RETURNED_ERROR is what gets returned if HTTP server returns an error code >= 400. CURLE_REMOTE_FILE_NOT_FOUND may be returned by an ftp server. If these are not causing this error, assume it is a verification issue. Try again with verification removed, unless user disallowed it via environment variable. */ verify = getenv("CFITSIO_VERIFY_HTTPS"); if (verify) { if (verify[0] == 'T' || verify[0] == 't') { snprintf(errStr,MAXLEN,"libcurl error: %d",res); ffpmsg(errStr); if (strlen(curlErrBuf)) ffpmsg(curlErrBuf); curl_easy_cleanup(curl); free(tmpUrl); return (FILE_NOT_OPENED); } } verifyPeer = 0; verifyHost = 0; curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, verifyPeer); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, verifyHost); /* Second attempt: no verification, .gz appended */ res = curl_easy_perform(curl); if (res != CURLE_OK) { if (isFtp && experimentWithCompression) { strcpy(tmpUrl, url); strcat(tmpUrl, ".Z"); curl_easy_setopt(curl, CURLOPT_URL, tmpUrl); /* For ftps, make another attempt with .Z */ res = curl_easy_perform(curl); if (res == CURLE_OK) { /* Success, but should still warn */ fprintf(stderr, "Warning: Unable to perform SSL verification on https transfer from: %s\n", tmpUrl); notFound=0; } } /* If we've been appending .gz or .Z, try a final time without. */ if (experimentWithCompression && notFound) { strcpy(tmpUrl, url); curl_easy_setopt(curl, CURLOPT_URL, tmpUrl); /* attempt with no verification, no .gz or .Z appended */ res = curl_easy_perform(curl); if (res != CURLE_OK) { snprintf(errStr,MAXLEN,"libcurl error: %d",res); ffpmsg(errStr); if (strlen(curlErrBuf)) ffpmsg(curlErrBuf); curl_easy_cleanup(curl); free(tmpUrl); return (FILE_NOT_OPENED); } else /* Success, but should still warn */ fprintf(stderr, "Warning: Unable to perform SSL verification on https transfer from: %s\n", tmpUrl); } else if (notFound) { snprintf(errStr,MAXLEN,"libcurl error: %d",res); ffpmsg(errStr); if (strlen(curlErrBuf)) ffpmsg(curlErrBuf); curl_easy_cleanup(curl); free(tmpUrl); return (FILE_NOT_OPENED); } } else /* Success, but still issue warning */ fprintf(stderr, "Warning: Unable to perform SSL verification on https transfer from: %s\n", tmpUrl); } else if (res == CURLE_HTTP_RETURNED_ERROR || res == CURLE_REMOTE_FILE_NOT_FOUND) { /* .gz extension failed and verification isn't the problem. No need to relax peer/host checking */ /* Unless url already contained a .gz, .Z or '?' (probably from a cgi script), try again with original url unappended (but first try .Z if this is ftps). */ if (experimentWithCompression) { if (isFtp) { strcpy(tmpUrl, url); strcat(tmpUrl, ".Z"); curl_easy_setopt(curl, CURLOPT_URL, tmpUrl); res = curl_easy_perform(curl); if (res == CURLE_OK) notFound = 0; } if (notFound) { strcpy(tmpUrl, url); curl_easy_setopt(curl, CURLOPT_URL, tmpUrl); res = curl_easy_perform(curl); if (res != CURLE_OK) { snprintf(errStr,MAXLEN,"libcurl error: %d",res); ffpmsg(errStr); if (strlen(curlErrBuf)) ffpmsg(curlErrBuf); curl_easy_cleanup(curl); free(tmpUrl); return (FILE_NOT_OPENED); } } } else { snprintf(errStr,MAXLEN,"libcurl error: %d",res); ffpmsg(errStr); if (strlen(curlErrBuf)) ffpmsg(curlErrBuf); curl_easy_cleanup(curl); free(tmpUrl); return (FILE_NOT_OPENED); } } /* If we made it here, assume tmpUrl was successful. Calling routines must make sure url can hold up to 3 extra chars */ strcpy(url, tmpUrl); free(tmpUrl); curl_easy_cleanup(curl); #else ffpmsg("ERROR: This CFITSIO build was not compiled with the libcurl library package "); ffpmsg("and therefore it cannot perform HTTPS or FTPS connections."); return (FILE_NOT_OPENED); #endif return 0; } /*--------------------------------------------------------------------------*/ /* This creates a memory file handle with a copy of the URL in filename. The file is uncompressed if necessary */ int ftp_open(char *filename, int rwmode, int *handle) { FILE *ftpfile; FILE *command; int sock; char errorstr[MAXLEN]; char recbuf[MAXLEN]; long len; int status; char firstchar; closememfile = 0; closecommandfile = 0; closeftpfile = 0; /* don't do r/w files */ if (rwmode != 0) { ffpmsg("Can't open ftp:// type file with READWRITE access"); ffpmsg("Specify an outfile for r/w access (ftp_open)"); return (FILE_NOT_OPENED); } /* do the signal handler bits */ if (setjmp(env) != 0) { /* feels like the second time */ /* this means something bad happened */ ffpmsg("Timeout (ftp_open)"); snprintf(errorstr, MAXLEN, "Download timeout exceeded: %d seconds",net_timeout); ffpmsg(errorstr); ffpmsg(" (multiplied x10 for files requiring uncompression)"); ffpmsg(" Timeout may be adjusted with fits_set_timeout"); goto error; } signal(SIGALRM, signal_handler); /* Open the ftp connetion. ftpfile is connected to the file port, command is connected to port 21. sock is the socket on port 21 */ if (strlen(filename) > MAXLEN - 4) { ffpmsg("filename too long (ftp_open)"); ffpmsg(filename); goto error; } alarm(net_timeout); if (ftp_open_network(filename,&ftpfile,&command,&sock)) { alarm(0); ffpmsg("Unable to open following ftp file (ftp_open):"); ffpmsg(filename); goto error; } closeftpfile++; closecommandfile++; /* create the memory file */ if ((status = mem_create(filename,handle))) { ffpmsg ("Could not create memory file to passive port (ftp_open)"); ffpmsg(filename); goto error; } closememfile++; /* This isn't quite right, it'll fail if the file has .gzabc at the end for instance */ /* Decide if the file is compressed */ firstchar = fgetc(ftpfile); ungetc(firstchar,ftpfile); if (strstr(filename,".gz") || strstr(filename,".Z") || ('\037' == firstchar)) { status = 0; /* A bit arbritary really, the user will probably hit ^C */ alarm(net_timeout*10); status = mem_uncompress2mem(filename, ftpfile, *handle); alarm(0); if (status) { ffpmsg("Error writing compressed memory file (ftp_open)"); ffpmsg(filename); goto error; } } else { /* write a memory file */ alarm(net_timeout); while(0 != (len = fread(recbuf,1,MAXLEN,ftpfile))) { alarm(0); status = mem_write(*handle,recbuf,len); if (status) { ffpmsg("Error writing memory file (http_open)"); ffpmsg(filename); goto error; } alarm(net_timeout); } } /* close and clean up */ fclose(ftpfile); closeftpfile--; fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); closecommandfile--; signal(SIGALRM, SIG_DFL); alarm(0); return mem_seek(*handle,0); error: alarm(0); /* clear it */ if (closecommandfile) { fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); } if (closeftpfile) { fclose(ftpfile); } if (closememfile) { mem_close_free(*handle); } signal(SIGALRM, SIG_DFL); return (FILE_NOT_OPENED); } /*--------------------------------------------------------------------------*/ /* This creates a file handle with a copy of the URL in filename. The file must be uncompressed and is copied to disk first */ int ftp_file_open(char *url, int rwmode, int *handle) { FILE *ftpfile; FILE *command; char errorstr[MAXLEN]; char recbuf[MAXLEN]; long len; int sock; int ii, flen, status; char firstchar; /* Check if output file is actually a memory file */ if (!strncmp(netoutfile, "mem:", 4) ) { /* allow the memory file to be opened with write access */ return( ftp_open(url, READONLY, handle) ); } closeftpfile = 0; closecommandfile = 0; closefile = 0; closeoutfile = 0; /* cfileio made a mistake, need to know where to write the output file */ flen = strlen(netoutfile); if (!flen) { ffpmsg("Output file not set, shouldn't have happened (ftp_file_open)"); return (FILE_NOT_OPENED); } /* do the signal handler bits */ if (setjmp(env) != 0) { /* feels like the second time */ /* this means something bad happened */ ffpmsg("Timeout (ftp_file_open)"); snprintf(errorstr, MAXLEN, "Download timeout exceeded: %d seconds",net_timeout); ffpmsg(errorstr); ffpmsg(" (multiplied x10 for files requiring uncompression)"); ffpmsg(" Timeout may be adjusted with fits_set_timeout"); goto error; } signal(SIGALRM, signal_handler); /* open the network connection to url. ftpfile holds the connection to the input file, command holds the connection to port 21, and sock is the socket connected to port 21 */ alarm(net_timeout); if ((status = ftp_open_network(url,&ftpfile,&command,&sock))) { alarm(0); ffpmsg("Unable to open http file (ftp_file_open)"); ffpmsg(url); goto error; } closeftpfile++; closecommandfile++; if (*netoutfile == '!') { /* user wants to clobber file, if it already exists */ for (ii = 0; ii < flen; ii++) netoutfile[ii] = netoutfile[ii + 1]; /* remove '!' */ status = file_remove(netoutfile); } /* Now, what do we do with the file */ firstchar = fgetc(ftpfile); ungetc(firstchar,ftpfile); if (strstr(url,".gz") || strstr(url,".Z") || ('\037' == firstchar)) { /* to make this more cfitsioish we use the file driver calls to create the file */ /* Create the output file */ if ((status = file_create(netoutfile,handle))) { ffpmsg("Unable to create output file (ftp_file_open)"); ffpmsg(netoutfile); goto error; } file_close(*handle); if (NULL == (outfile = fopen(netoutfile,"w"))) { ffpmsg("Unable to reopen the output file (ftp_file_open)"); ffpmsg(netoutfile); goto error; } closeoutfile++; status = 0; /* Ok, this is a tough case, let's be arbritary and say 10*net_timeout, Given the choices for nettimeout above they'll probaby ^C before, but it's always worth a shot*/ alarm(net_timeout*10); status = uncompress2file(url,ftpfile,outfile,&status); alarm(0); if (status) { ffpmsg("Unable to uncompress the output file (ftp_file_open)"); ffpmsg(url); ffpmsg(netoutfile); goto error; } fclose(outfile); closeoutfile--; } else { /* Create the output file */ if ((status = file_create(netoutfile,handle))) { ffpmsg("Unable to create output file (ftp_file_open)"); ffpmsg(netoutfile); goto error; } closefile++; /* write a file */ alarm(net_timeout); while(0 != (len = fread(recbuf,1,MAXLEN,ftpfile))) { alarm(0); status = file_write(*handle,recbuf,len); if (status) { ffpmsg("Error writing file (ftp_file_open)"); ffpmsg(url); ffpmsg(netoutfile); goto error; } alarm(net_timeout); } file_close(*handle); } fclose(ftpfile); closeftpfile--; fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); closecommandfile--; signal(SIGALRM, SIG_DFL); alarm(0); return file_open(netoutfile,rwmode,handle); error: alarm(0); /* clear it */ if (closeftpfile) { fclose(ftpfile); } if (closecommandfile) { fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); } if (closeoutfile) { fclose(outfile); } if (closefile) { file_close(*handle); } signal(SIGALRM, SIG_DFL); return (FILE_NOT_OPENED); } /*--------------------------------------------------------------------------*/ /* This creates a memory handle with a copy of the URL in filename. The file must be compressed and is copied to disk first */ int ftp_compress_open(char *url, int rwmode, int *handle) { FILE *ftpfile; FILE *command; char errorstr[MAXLEN]; char recbuf[MAXLEN]; long len; int ii, flen, status; int sock; char firstchar; closeftpfile = 0; closecommandfile = 0; closememfile = 0; closefdiskfile = 0; closediskfile = 0; /* don't do r/w files */ if (rwmode != 0) { ffpmsg("Compressed files must be r/o"); return (FILE_NOT_OPENED); } /* Need to know where to write the output file */ flen = strlen(netoutfile); if (!flen) { ffpmsg( "Output file not set, shouldn't have happened (ftp_compress_open)"); return (FILE_NOT_OPENED); } /* do the signal handler bits */ if (setjmp(env) != 0) { /* feels like the second time */ /* this means something bad happened */ ffpmsg("Timeout (ftp_compress_open)"); snprintf(errorstr, MAXLEN, "Download timeout exceeded: %d seconds",net_timeout); ffpmsg(errorstr); ffpmsg(" Timeout may be adjusted with fits_set_timeout"); goto error; } signal(SIGALRM, signal_handler); /* Open the network connection to url, ftpfile is connected to the file port, command is connected to port 21. sock is for writing to port 21 */ alarm(net_timeout); if ((status = ftp_open_network(url,&ftpfile,&command,&sock))) { alarm(0); ffpmsg("Unable to open ftp file (ftp_compress_open)"); ffpmsg(url); goto error; } closeftpfile++; closecommandfile++; /* Now, what do we do with the file */ firstchar = fgetc(ftpfile); ungetc(firstchar,ftpfile); if (strstr(url,".gz") || strstr(url,".Z") || ('\037' == firstchar)) { if (*netoutfile == '!') { /* user wants to clobber file, if it already exists */ for (ii = 0; ii < flen; ii++) netoutfile[ii] = netoutfile[ii + 1]; /* remove '!' */ status = file_remove(netoutfile); } /* Create the output file */ if ((status = file_create(netoutfile,handle))) { ffpmsg("Unable to create output file (ftp_compress_open)"); ffpmsg(netoutfile); goto error; } closediskfile++; /* write a file */ alarm(net_timeout); while(0 != (len = fread(recbuf,1,MAXLEN,ftpfile))) { alarm(0); status = file_write(*handle,recbuf,len); if (status) { ffpmsg("Error writing file (ftp_compres_open)"); ffpmsg(url); ffpmsg(netoutfile); goto error; } alarm(net_timeout); } file_close(*handle); closediskfile--; fclose(ftpfile); closeftpfile--; /* Close down the ftp connection */ fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); closecommandfile--; /* File is on disk, let's uncompress it into memory */ if (NULL == (diskfile = fopen(netoutfile,"r"))) { ffpmsg("Unable to reopen disk file (ftp_compress_open)"); ffpmsg(netoutfile); return (FILE_NOT_OPENED); } closefdiskfile++; if ((status = mem_create(url,handle))) { ffpmsg("Unable to create memory file (ftp_compress_open)"); ffpmsg(url); goto error; } closememfile++; status = 0; status = mem_uncompress2mem(url,diskfile,*handle); fclose(diskfile); closefdiskfile--; if (status) { ffpmsg("Error writing compressed memory file (ftp_compress_open)"); goto error; } } else { /* Opps, this should not have happened */ ffpmsg("Can only compressed files here (ftp_compress_open)"); goto error; } signal(SIGALRM, SIG_DFL); alarm(0); return mem_seek(*handle,0); error: alarm(0); /* clear it */ if (closeftpfile) { fclose(ftpfile); } if (closecommandfile) { fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); } if (closefdiskfile) { fclose(diskfile); } if (closememfile) { mem_close_free(*handle); } if (closediskfile) { file_close(*handle); } signal(SIGALRM, SIG_DFL); return (FILE_NOT_OPENED); } /*--------------------------------------------------------------------------*/ /* Open a ftp connection to filename (really a URL), return ftpfile set to the file connection, and command set to the control connection, with sock also set to the control connection */ static int ftp_open_network(char *filename, FILE **ftpfile, FILE **command, int *sock) { int status; int sock1; int tmpint; char recbuf[MAXLEN]; char errorstr[MAXLEN]; char tmpstr[MAXLEN]; char proto[SHORTLEN]; char host[SHORTLEN]; char agentStr[SHORTLEN]; char *newhost; char *username; char *password; char fn[MAXLEN]; char *newfn; char *passive; char *tstr; char *saveptr; char ip[SHORTLEN]; char turl[MAXLEN]; int port; int ii,tryingtologin = 1; float version=0.0; /* parse the URL */ if (strlen(filename) > MAXLEN - 7) { ffpmsg("ftp filename is too long (ftp_open_network)"); return (FILE_NOT_OPENED); } strcpy(turl,"ftp://"); strcat(turl,filename); if (NET_ParseUrl(turl,proto,host,&port,fn)) { snprintf(errorstr,MAXLEN,"URL Parse Error (ftp_open) %s",filename); ffpmsg(errorstr); return (FILE_NOT_OPENED); } port = 21; /* We might have a user name. If not, set defaults for username and password */ username = "anonymous"; snprintf(agentStr,SHORTLEN,"User-Agent: FITSIO/HEASARC/%-8.3f",ffvers(&version)); password = agentStr; /* is there an @ sign */ if (NULL != (newhost = strrchr(host,'@'))) { *newhost = '\0'; /* make it a null, */ newhost++; /* Now newhost points to the host name and host points to the user name, password combo */ username = host; /* is there a : for a password */ if (NULL != strchr(username,':')) { password = strchr(username,':'); *password = '\0'; password++; } } else { newhost = host; } for (ii = 0; ii < 10; ii++) { /* make up to 10 attempts to log in */ /* Connect to the host on the required port */ *sock = NET_TcpConnect(newhost,port); /* convert it to a stdio file */ if (NULL == (*command = fdopen(*sock,"r"))) { ffpmsg ("fdopen failed to convert socket to stdio file (ftp_open_netowrk)"); return (FILE_NOT_OPENED); } /* Wait for the 220 response */ if (ftp_status(*command,"220 ")) { fclose(*command); NET_SendRaw(*sock,"QUIT\r\n",6,NET_DEFAULT); /* ffpmsg("sleeping for 5 in ftp_open_network, then try again"); */ sleep (5); /* take a nap and hope ftp server sorts itself out in the meantime */ } else { tryingtologin = 0; break; } } if (tryingtologin) { /* the 10 attempts were not successful */ ffpmsg ("error connecting to remote server, no 220 seen (ftp_open_network)"); return (FILE_NOT_OPENED); } /* Send the user name and wait for the right response */ snprintf(tmpstr,MAXLEN,"USER %s\r\n",username); status = NET_SendRaw(*sock,tmpstr,strlen(tmpstr),NET_DEFAULT); if (ftp_status(*command,"331 ")) { ffpmsg ("USER error no 331 seen (ftp_open_network)"); fclose(*command); NET_SendRaw(*sock,"QUIT\r\n",6,NET_DEFAULT); return (FILE_NOT_OPENED); } /* Send the password and wait for the right response */ snprintf(tmpstr,MAXLEN,"PASS %s\r\n",password); status = NET_SendRaw(*sock,tmpstr,strlen(tmpstr),NET_DEFAULT); if (ftp_status(*command,"230 ")) { ffpmsg ("PASS error, no 230 seen (ftp_open_network)"); fclose(*command); NET_SendRaw(*sock,"QUIT\r\n",6,NET_DEFAULT); return (FILE_NOT_OPENED); } /* now do the cwd command */ newfn = strrchr(fn,'/'); if (newfn == NULL) { strcpy(tmpstr,"CWD /\r\n"); newfn = fn; } else { *newfn = '\0'; newfn++; if (strlen(fn) == 0) { strcpy(tmpstr,"CWD /\r\n"); } else { /* remove the leading slash */ if (fn[0] == '/') { snprintf(tmpstr,MAXLEN,"CWD %s\r\n",&fn[1]); } else { snprintf(tmpstr,MAXLEN,"CWD %s\r\n",fn); } } } status = NET_SendRaw(*sock,tmpstr,strlen(tmpstr),NET_DEFAULT); if (ftp_status(*command,"250 ")) { ffpmsg ("CWD error, no 250 seen (ftp_open_network)"); fclose(*command); NET_SendRaw(*sock,"QUIT\r\n",6,NET_DEFAULT); return (FILE_NOT_OPENED); } if (!strlen(newfn)) { ffpmsg("Null file name (ftp_open)"); fclose(*command); NET_SendRaw(*sock,"QUIT\r\n",6,NET_DEFAULT); return (FILE_NOT_OPENED); } /* Always use binary mode */ snprintf(tmpstr,MAXLEN,"TYPE I\r\n"); status = NET_SendRaw(*sock,tmpstr,strlen(tmpstr),NET_DEFAULT); if (ftp_status(*command,"200 ")) { ffpmsg ("TYPE I error, 200 not seen (ftp_open_network)"); fclose(*command); NET_SendRaw(*sock,"QUIT\r\n",6,NET_DEFAULT); return (FILE_NOT_OPENED); } status = NET_SendRaw(*sock,"PASV\r\n",6,NET_DEFAULT); if (!(fgets(recbuf,MAXLEN,*command))) { ffpmsg ("PASV error (ftp_open)"); fclose(*command); NET_SendRaw(*sock,"QUIT\r\n",6,NET_DEFAULT); return (FILE_NOT_OPENED); } /* Passive mode response looks like 227 Entering Passive Mode (129,194,67,8,210,80) */ if (recbuf[0] == '2' && recbuf[1] == '2' && recbuf[2] == '7') { /* got a good passive mode response, find the opening ( */ if (!(passive = strchr(recbuf,'('))) { ffpmsg ("PASV error (ftp_open_network)"); fclose(*command); NET_SendRaw(*sock,"QUIT\r\n",6,NET_DEFAULT); return (FILE_NOT_OPENED); } *passive = '\0'; passive++; ip[0] = '\0'; /* Messy parsing of response from PASV *command */ if (!(tstr = ffstrtok(passive,",)",&saveptr))) { ffpmsg ("PASV error (ftp_open_network)"); fclose(*command); NET_SendRaw(*sock,"QUIT\r\n",6,NET_DEFAULT); return (FILE_NOT_OPENED); } strcpy(ip,tstr); strcat(ip,"."); if (!(tstr = ffstrtok(NULL,",)",&saveptr))) { ffpmsg ("PASV error (ftp_open_network)"); fclose(*command); NET_SendRaw(*sock,"QUIT\r\n",6,NET_DEFAULT); return (FILE_NOT_OPENED); } strcat(ip,tstr); strcat(ip,"."); if (!(tstr = ffstrtok(NULL,",)",&saveptr))) { ffpmsg ("PASV error (ftp_open_network)"); fclose(*command); NET_SendRaw(*sock,"QUIT\r\n",6,NET_DEFAULT); return (FILE_NOT_OPENED); } strcat(ip,tstr); strcat(ip,"."); if (!(tstr = ffstrtok(NULL,",)",&saveptr))) { ffpmsg ("PASV error (ftp_open_network)"); fclose(*command); NET_SendRaw(*sock,"QUIT\r\n",6,NET_DEFAULT); return (FILE_NOT_OPENED); } strcat(ip,tstr); /* Done the ip number, now do the port # */ if (!(tstr = ffstrtok(NULL,",)",&saveptr))) { ffpmsg ("PASV error (ftp_open_network)"); fclose(*command); NET_SendRaw(*sock,"QUIT\r\n",6,NET_DEFAULT); return (FILE_NOT_OPENED); } sscanf(tstr,"%d",&port); port *= 256; if (!(tstr = ffstrtok(NULL,",)",&saveptr))) { ffpmsg ("PASV error (ftp_open_network)"); fclose(*command); NET_SendRaw(*sock,"QUIT\r\n",6,NET_DEFAULT); return (FILE_NOT_OPENED); } sscanf(tstr,"%d",&tmpint); port += tmpint; if (!strlen(newfn)) { ffpmsg("Null file name (ftp_open_network)"); fclose(*command); NET_SendRaw(*sock,"QUIT\r\n",6,NET_DEFAULT); return (FILE_NOT_OPENED); } /* Connect to the data port */ sock1 = NET_TcpConnect(ip,port); if (NULL == (*ftpfile = fdopen(sock1,"r"))) { ffpmsg ("Could not connect to passive port (ftp_open_network)"); fclose(*command); NET_SendRaw(*sock,"QUIT\r\n",6,NET_DEFAULT); return (FILE_NOT_OPENED); } /* Send the retrieve command */ snprintf(tmpstr,MAXLEN,"RETR %s\r\n",newfn); status = NET_SendRaw(*sock,tmpstr,strlen(tmpstr),NET_DEFAULT); if (ftp_status(*command,"150 ")) { fclose(*ftpfile); NET_SendRaw(sock1,"QUIT\r\n",6,NET_DEFAULT); fclose(*command); NET_SendRaw(*sock,"QUIT\r\n",6,NET_DEFAULT); return (FILE_NOT_OPENED); } return 0; /* successfully opened the ftp file */ } /* no passive mode */ fclose(*command); NET_SendRaw(*sock,"QUIT\r\n",6,NET_DEFAULT); return (FILE_NOT_OPENED); } /*--------------------------------------------------------------------------*/ /* Open a ftp connection to see if the file exists (return 1) or not (return 0) */ int ftp_file_exist(char *filename) { FILE *ftpfile; FILE *command; int sock; int status; int sock1; int tmpint; char recbuf[MAXLEN]; char errorstr[MAXLEN]; char tmpstr[MAXLEN]; char proto[SHORTLEN]; char host[SHORTLEN]; char *newhost; char *username; char *password; char fn[MAXLEN]; char *newfn; char *passive; char *tstr; char *saveptr; char ip[SHORTLEN]; char turl[MAXLEN]; int port; int ii, tryingtologin = 1; /* parse the URL */ if (strlen(filename) > MAXLEN - 7) { ffpmsg("ftp filename is too long (ftp_file_exist)"); return 0; } strcpy(turl,"ftp://"); strcat(turl,filename); if (NET_ParseUrl(turl,proto,host,&port,fn)) { snprintf(errorstr,MAXLEN,"URL Parse Error (ftp_file_exist) %s",filename); ffpmsg(errorstr); return 0; } port = 21; /* we might have a user name */ username = "anonymous"; password = "user@host.com"; /* is there an @ sign */ if (NULL != (newhost = strrchr(host,'@'))) { *newhost = '\0'; /* make it a null, */ newhost++; /* Now newhost points to the host name and host points to the user name, password combo */ username = host; /* is there a : for a password */ if (NULL != strchr(username,':')) { password = strchr(username,':'); *password = '\0'; password++; } } else { newhost = host; } for (ii = 0; ii < 10; ii++) { /* make up to 10 attempts to log in */ /* Connect to the host on the required port */ sock = NET_TcpConnect(newhost,port); /* convert it to a stdio file */ if (NULL == (command = fdopen(sock,"r"))) { ffpmsg ("Failed to convert socket to stdio file (ftp_file_exist)"); return 0; } /* Wait for the 220 response */ if (ftp_status(command,"220")) { ffpmsg ("error connecting to remote server, no 220 seen (ftp_file_exist)"); fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); /* ffpmsg("sleeping for 5 in ftp_file_exist, then try again"); */ sleep (5); /* take a nap and hope ftp server sorts itself out in the meantime */ } else { tryingtologin = 0; break; } } if (tryingtologin) { /* the 10 attempts were not successful */ ffpmsg ("error connecting to remote server, no 220 seen (ftp_open_network)"); return (0); } /* Send the user name and wait for the right response */ snprintf(tmpstr,MAXLEN,"USER %s\r\n",username); status = NET_SendRaw(sock,tmpstr,strlen(tmpstr),NET_DEFAULT); /* If command is refused due to the connection requiring SSL (ie. an fpts connection), this is where it will first be detected by way of a 550 error code. */ status = ftp_status(command,"331 "); if (status == 550) { ffpmsg ("Server is requesting SSL, will switch to ftps (ftp_file_exist)"); fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); return -1; } else if (status) { ffpmsg ("USER error no 331 seen (ftp_file_exist)"); fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); return 0; } /* Send the password and wait for the right response */ snprintf(tmpstr,MAXLEN,"PASS %s\r\n",password); status = NET_SendRaw(sock,tmpstr,strlen(tmpstr),NET_DEFAULT); if (ftp_status(command,"230 ")) { ffpmsg ("PASS error, no 230 seen (ftp_file_exist)"); fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); return 0; } /* now do the cwd command */ newfn = strrchr(fn,'/'); if (newfn == NULL) { strcpy(tmpstr,"CWD /\r\n"); newfn = fn; } else { *newfn = '\0'; newfn++; if (strlen(fn) == 0) { strcpy(tmpstr,"CWD /\r\n"); } else { /* remove the leading slash */ if (fn[0] == '/') { snprintf(tmpstr,MAXLEN,"CWD %s\r\n",&fn[1]); } else { snprintf(tmpstr,MAXLEN,"CWD %s\r\n",fn); } } } status = NET_SendRaw(sock,tmpstr,strlen(tmpstr),NET_DEFAULT); if (ftp_status(command,"250 ")) { ffpmsg ("CWD error, no 250 seen (ftp_file_exist)"); fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); return 0; } if (!strlen(newfn)) { ffpmsg("Null file name (ftp_file_exist)"); fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); return 0; } /* Always use binary mode */ snprintf(tmpstr,MAXLEN,"TYPE I\r\n"); status = NET_SendRaw(sock,tmpstr,strlen(tmpstr),NET_DEFAULT); if (ftp_status(command,"200 ")) { ffpmsg ("TYPE I error, 200 not seen (ftp_file_exist)"); fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); return 0; } status = NET_SendRaw(sock,"PASV\r\n",6,NET_DEFAULT); if (!(fgets(recbuf,MAXLEN,command))) { ffpmsg ("PASV error (ftp_file_exist)"); fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); return 0; } /* Passive mode response looks like 227 Entering Passive Mode (129,194,67,8,210,80) */ if (recbuf[0] == '2' && recbuf[1] == '2' && recbuf[2] == '7') { /* got a good passive mode response, find the opening ( */ if (!(passive = strchr(recbuf,'('))) { ffpmsg ("PASV error (ftp_file_exist)"); fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); return 0; } *passive = '\0'; passive++; ip[0] = '\0'; /* Messy parsing of response from PASV command */ if (!(tstr = ffstrtok(passive,",)",&saveptr))) { ffpmsg ("PASV error (ftp_file_exist)"); fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); return 0; } strcpy(ip,tstr); strcat(ip,"."); if (!(tstr = ffstrtok(NULL,",)",&saveptr))) { ffpmsg ("PASV error (ftp_file_exist)"); fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); return 0; } strcat(ip,tstr); strcat(ip,"."); if (!(tstr = ffstrtok(NULL,",)",&saveptr))) { ffpmsg ("PASV error (ftp_file_exist)"); fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); return 0; } strcat(ip,tstr); strcat(ip,"."); if (!(tstr = ffstrtok(NULL,",)",&saveptr))) { ffpmsg ("PASV error (ftp_file_exist)"); fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); return 0; } strcat(ip,tstr); /* Done the ip number, now do the port # */ if (!(tstr = ffstrtok(NULL,",)",&saveptr))) { ffpmsg ("PASV error (ftp_file_exist)"); fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); return 0; } sscanf(tstr,"%d",&port); port *= 256; if (!(tstr = ffstrtok(NULL,",)",&saveptr))) { ffpmsg ("PASV error (ftp_file_exist)"); fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); return 0; } sscanf(tstr,"%d",&tmpint); port += tmpint; if (!strlen(newfn)) { ffpmsg("Null file name (ftp_file_exist)"); fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); return 0; } /* Connect to the data port */ sock1 = NET_TcpConnect(ip,port); if (NULL == (ftpfile = fdopen(sock1,"r"))) { ffpmsg ("Could not connect to passive port (ftp_file_exist)"); fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); return 0; } /* Send the retrieve command */ snprintf(tmpstr,MAXLEN,"RETR %s\r\n",newfn); status = NET_SendRaw(sock,tmpstr,strlen(tmpstr),NET_DEFAULT); if (ftp_status(command,"150 ")) { fclose(ftpfile); NET_SendRaw(sock1,"QUIT\r\n",6,NET_DEFAULT); fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); return 0; } /* if we got here then the file probably exists */ fclose(ftpfile); NET_SendRaw(sock1,"QUIT\r\n",6,NET_DEFAULT); fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); return 1; } /* no passive mode */ fclose(command); NET_SendRaw(sock,"QUIT\r\n",6,NET_DEFAULT); return 0; } /*--------------------------------------------------------------------------*/ /* return a socket which results from connection to hostname on port port */ int NET_TcpConnect(char *hostname, int port) { /* Connect to hostname on port */ struct sockaddr_in sockaddr; int sock; int stat; int val = 1; CreateSocketAddress(&sockaddr,hostname,port); /* Create socket */ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { ffpmsg("ERROR: NET_TcpConnect can't create socket"); return CONNECTION_ERROR; } if ((stat = connect(sock, (struct sockaddr*) &sockaddr, sizeof(sockaddr))) < 0) { close(sock); /* perror("NET_Tcpconnect - Connection error"); ffpmsg("Can't connect to host, connection error"); */ return CONNECTION_ERROR; } setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val)); setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&val, sizeof(val)); val = 65536; setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&val, sizeof(val)); setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&val, sizeof(val)); return sock; } /*--------------------------------------------------------------------------*/ /* Write len bytes from buffer to socket sock */ static int NET_SendRaw(int sock, const void *buffer, int length, int opt) { char * buf = (char *) buffer; int flag; int n, nsent = 0; switch (opt) { case NET_DEFAULT: flag = 0; break; case NET_OOB: flag = MSG_OOB; break; case NET_PEEK: default: flag = 0; break; } if (sock < 0) return -1; for (n = 0; n < length; n += nsent) { if ((nsent = send(sock, buf+n, length-n, flag)) <= 0) { return nsent; } } return n; } /*--------------------------------------------------------------------------*/ static int NET_RecvRaw(int sock, void *buffer, int length) { /* Receive exactly length bytes into buffer. Returns number of bytes */ /* received. Returns -1 in case of error. */ int nrecv, n; char *buf = (char *)buffer; if (sock < 0) return -1; for (n = 0; n < length; n += nrecv) { while ((nrecv = recv(sock, buf+n, length-n, 0)) == -1 && errno == EINTR) errno = 0; /* probably a SIGCLD that was caught */ if (nrecv < 0) return nrecv; else if (nrecv == 0) break; /*/ EOF */ } return n; } /*--------------------------------------------------------------------------*/ /* Yet Another URL Parser url - input url proto - input protocol host - output host port - output port fn - output filename */ static int NET_ParseUrl(const char *url, char *proto, char *host, int *port, char *fn) { /* parses urls into their bits */ /* returns 1 if error, else 0 */ char *urlcopy, *urlcopyorig; char *ptrstr; char *thost; int isftp = 0; /* figure out if there is a http: or ftp: */ urlcopyorig = urlcopy = (char *) malloc(strlen(url)+1); strcpy(urlcopy,url); /* set some defaults */ *port = 80; strcpy(proto,"http:"); strcpy(host,"localhost"); strcpy(fn,"/"); ptrstr = strstr(urlcopy,"http:"); if (ptrstr == NULL) { /* Nope, not http: */ ptrstr = strstr(urlcopy,"root:"); if (ptrstr == NULL) { /* Nope, not root either */ ptrstr = strstr(urlcopy,"ftp:"); if (ptrstr != NULL) { if (ptrstr == urlcopy) { strcpy(proto,"ftp:"); *port = 21; isftp++; urlcopy += 4; /* move past ftp: */ } else { /* not at the beginning, bad url */ free(urlcopyorig); return 1; } } } else { if (ptrstr == urlcopy) { urlcopy += 5; /* move past root: */ } else { /* not at the beginning, bad url */ free(urlcopyorig); return 1; } } } else { if (ptrstr == urlcopy) { urlcopy += 5; /* move past http: */ } else { free(urlcopyorig); return 1; } } /* got the protocol */ /* get the hostname */ if (urlcopy[0] == '/' && urlcopy[1] == '/') { /* we have a hostname */ urlcopy += 2; /* move past the // */ } /* do this only if http */ if (!strcmp(proto,"http:")) { /* Move past any user:password */ if ((thost = strchr(urlcopy, '@')) != NULL) urlcopy = thost+1; if (strlen(urlcopy) > SHORTLEN-1) { free(urlcopyorig); return 1; } strcpy(host,urlcopy); thost = host; while (*urlcopy != '/' && *urlcopy != ':' && *urlcopy) { thost++; urlcopy++; } /* we should either be at the end of the string, have a /, or have a : */ *thost = '\0'; if (*urlcopy == ':') { /* follows a port number */ urlcopy++; sscanf(urlcopy,"%d",port); while (*urlcopy != '/' && *urlcopy) urlcopy++; /* step to the */ } } else { /* do this for ftp */ if (strlen(urlcopy) > SHORTLEN-1) { free(urlcopyorig); return 1; } strcpy(host,urlcopy); thost = host; while (*urlcopy != '/' && *urlcopy) { thost++; urlcopy++; } *thost = '\0'; /* Now, we should either be at the end of the string, or have a / */ } /* Now the rest is a fn */ if (*urlcopy) { if (strlen(urlcopy) > MAXLEN-1) { free(urlcopyorig); return 1; } strcpy(fn,urlcopy); } free(urlcopyorig); return 0; } /*--------------------------------------------------------------------------*/ int http_checkfile (char *urltype, char *infile, char *outfile1) { /* Small helper functions to set the netoutfile static string */ /* Called by cfileio after parsing the output file off of the input file url */ char newinfile[MAXLEN]; FILE *httpfile=0; char contentencoding[MAXLEN]; int contentlength; int foundfile = 0; int status=0; /* set defaults */ strcpy(urltype,"http://"); if (strlen(outfile1)) { /* don't copy the "file://" prefix, if present. */ if (!strncmp(outfile1, "file://", 7) ) { strcpy(netoutfile,outfile1+7); } else { strcpy(netoutfile,outfile1); } } if (strstr(infile, "?")) { /* Special case where infile name contains a "?". */ /* This is probably a CGI string; no point in testing if it exists */ /* so just set urltype and netoutfile if necessary, then return */ if (strlen(outfile1)) { /* was an outfile specified? */ strcpy(urltype,"httpfile://"); /* don't copy the "file://" prefix, if present. */ if (!strncmp(outfile1, "file://", 7) ) { strcpy(netoutfile,outfile1+7); } else { strcpy(netoutfile,outfile1); } } return 0; /* case where infile name contains "?" */ } /* If the specified infile file name does not contain a .gz or .Z suffix, then first test if a .gz compressed version of the file exists, and if not then test if a .Z version of the file exists. (because it will be much faster to read the compressed file). If the compressed files do not exist, then finally just open the infile name exactly as specified. */ if (!strstr(infile,".gz") && (!strstr(infile,".Z"))) { /* The infile string does not contain the name of a compressed file. */ /* Fisrt, look for a .gz compressed version of the file. */ if (strlen(infile) + 3 > MAXLEN-1) { return URL_PARSE_ERROR; } strcpy(newinfile,infile); strcat(newinfile,".gz"); status = http_open_network(newinfile,&httpfile,contentencoding, &contentlength); if (!status) { if (!strcmp(contentencoding, "ftp://")) { /* this is a signal from http_open_network that indicates that */ /* the http server returned a 301 or 302 redirect to a FTP URL. */ /* Check that the file exists, because redirect many not be reliable */ if (ftp_file_exist(newinfile)>0) { /* The ftp .gz compressed file is there, all is good! */ strcpy(urltype, "ftp://"); if (strlen(newinfile) > FLEN_FILENAME-1) { return URL_PARSE_ERROR; } strcpy(infile,newinfile); if (strlen(outfile1)) { /* there is an output file; might need to modify the urltype */ if (!strncmp(outfile1, "mem:", 4) ) { /* copy the file to memory, with READ and WRITE access In this case, it makes no difference whether the ftp file and or the output file are compressed or not. */ strcpy(urltype, "ftpmem://"); /* use special driver */ } else { /* input file is compressed */ if (strstr(outfile1,".gz") || (strstr(outfile1,".Z"))) { strcpy(urltype,"ftpcompress://"); } else { strcpy(urltype,"ftpfile://"); } } } return 0; /* found the .gz compressed ftp file */ } /* fall through to here if ftp redirect does not exist */ } else if (!strcmp(contentencoding, "https://")) { /* the http server returned a 301 or 302 redirect to an HTTPS URL. */ https_checkfile(urltype, infile, outfile1); /* For https we're not testing for compressed extensions at this stage. It will all be done in https_open_network. Therefore leave infile alone and do immediate return. */ return 0; } else { /* found the http .gz compressed file */ if (httpfile) fclose(httpfile); foundfile = 1; if (strlen(newinfile) > FLEN_FILENAME-1) { return URL_PARSE_ERROR; } strcpy(infile,newinfile); } } else if (status != FILE_NOT_OPENED) { /* Some other error occured aside from not finding file, such as a url parsing error. Don't continue trying with other extensions. */ return status; } if (!foundfile) { /* did not find .gz compressed version of the file, so look for .Z file. */ if (strlen(infile+2) > MAXLEN-1) { return URL_PARSE_ERROR; } strcpy(newinfile,infile); strcat(newinfile,".Z"); if (!http_open_network(newinfile,&httpfile,contentencoding, &contentlength)) { if (!strcmp(contentencoding, "ftp://")) { /* this is a signal from http_open_network that indicates that */ /* the http server returned a 301 or 302 redirect to a FTP URL. */ /* Check that the file exists, because redirect many not be reliable */ if (ftp_file_exist(newinfile)>0) { /* The ftp .Z compressed file is there, all is good! */ strcpy(urltype, "ftp://"); if (strlen(newinfile) > FLEN_FILENAME-1) { return URL_PARSE_ERROR; } strcpy(infile,newinfile); if (strlen(outfile1)) { /* there is an output file; might need to modify the urltype */ if (!strncmp(outfile1, "mem:", 4) ) { /* copy the file to memory, with READ and WRITE access In this case, it makes no difference whether the ftp file and or the output file are compressed or not. */ strcpy(urltype, "ftpmem://"); /* use special driver */ } else { /* input file is compressed */ if (strstr(outfile1,".gz") || (strstr(outfile1,".Z"))) { strcpy(urltype,"ftpcompress://"); } else { strcpy(urltype,"ftpfile://"); } } } return 0; /* found the .Z compressed ftp file */ } /* fall through to here if ftp redirect does not exist */ } else { /* found the http .Z compressed file */ if (httpfile) fclose(httpfile); foundfile = 1; if (strlen(newinfile) > FLEN_FILENAME-1) { return URL_PARSE_ERROR; } strcpy(infile,newinfile); } } } } /* end of case where infile does not contain .gz or .Z */ if (!foundfile) { /* look for the base file.name */ strcpy(newinfile,infile); if (!http_open_network(newinfile,&httpfile,contentencoding, &contentlength)) { if (!strcmp(contentencoding, "ftp://")) { /* this is a signal from http_open_network that indicates that */ /* the http server returned a 301 or 302 redirect to a FTP URL. */ /* Check that the file exists, because redirect many not be reliable */ if (ftp_file_exist(newinfile)>0) { /* The ftp file is there, all is good! */ strcpy(urltype, "ftp://"); if (strlen(newinfile) > FLEN_FILENAME-1) { return URL_PARSE_ERROR; } strcpy(infile,newinfile); if (strlen(outfile1)) { /* there is an output file; might need to modify the urltype */ if (!strncmp(outfile1, "mem:", 4) ) { /* copy the file to memory, with READ and WRITE access In this case, it makes no difference whether the ftp file and or the output file are compressed or not. */ strcpy(urltype, "ftpmem://"); /* use special driver */ return 0; } else { /* input file is not compressed */ strcpy(urltype,"ftpfile://"); } } return 0; /* found the ftp file */ } /* fall through to here if ftp redirect does not exist */ } else if (!strcmp(contentencoding, "https://")) { /* the http server returned a 301 or 302 redirect to an HTTPS URL. */ https_checkfile(urltype, infile, outfile1); /* For https we're not testing for compressed extensions at this stage. It will all be done in https_open_network. Therefore leave infile alone and do immediate return. */ return 0; } else { /* found the base named file */ if (httpfile) fclose(httpfile); foundfile = 1; if (strlen(newinfile) > FLEN_FILENAME-1) { return URL_PARSE_ERROR; } strcpy(infile,newinfile); } } } if (!foundfile) { return (FILE_NOT_OPENED); } if (strlen(outfile1)) { /* there is an output file */ if (!strncmp(outfile1, "mem:", 4) ) { /* copy the file to memory, with READ and WRITE access In this case, it makes no difference whether the http file and or the output file are compressed or not. */ strcpy(urltype, "httpmem://"); /* use special driver */ return 0; } if (strstr(infile, "?")) { /* file name contains a '?' so probably a cgi string; */ strcpy(urltype,"httpfile://"); return 0; } if (strstr(infile,".gz") || (strstr(infile,".Z"))) { /* It's compressed */ if (strstr(outfile1,".gz") || (strstr(outfile1,".Z"))) { strcpy(urltype,"httpcompress://"); } else { strcpy(urltype,"httpfile://"); } } else { strcpy(urltype,"httpfile://"); } } return 0; } /*--------------------------------------------------------------------------*/ int https_checkfile (char *urltype, char *infile, char *outfile1) { /* set default */ strcpy(urltype,"https://"); if (strlen(outfile1)) { /* don't copy the "file://" prefix, if present. */ if (!strncmp(outfile1, "file://", 7) ) { strcpy(netoutfile,outfile1+7); } else { strcpy(netoutfile,outfile1); } if (!strncmp(outfile1, "mem:", 4)) strcpy(urltype,"httpsmem://"); else strcpy(urltype,"httpsfile://"); } return 0; } /*--------------------------------------------------------------------------*/ int ftps_checkfile (char *urltype, char *infile, char *outfile1) { strcpy(urltype,"ftps://"); if (strlen(outfile1)) { /* don't copy the "file://" prefix, if present. */ if (!strncmp(outfile1, "file://", 7) ) { strcpy(netoutfile,outfile1+7); } else { strcpy(netoutfile,outfile1); } if (!strncmp(outfile1, "mem:", 4)) strcpy(urltype,"ftpsmem://"); else { if (strstr(outfile1,".gz") || strstr(outfile1,".Z")) { /* Note that for Curl dependent handlers, we can't check at this point if infile will have a .gz or .Z appended. If it does not, the ftpscompress 'open' handler will fail.*/ strcpy(urltype,"ftpscompress://"); } else strcpy(urltype,"ftpsfile://"); } } return 0; } /*--------------------------------------------------------------------------*/ int ftp_checkfile (char *urltype, char *infile, char *outfile1) { char newinfile[MAXLEN]; FILE *ftpfile; FILE *command; int sock; int foundfile = 0; int status=0; /* Small helper functions to set the netoutfile static string */ /* default to ftp:// if no outfile specified */ strcpy(urltype,"ftp://"); if (!strstr(infile,".gz") && (!strstr(infile,".Z"))) { /* The infile string does not contain the name of a compressed file. */ /* Fisrt, look for a .gz compressed version of the file. */ if (strlen(infile)+3 > MAXLEN-1) { return URL_PARSE_ERROR; } strcpy(newinfile,infile); strcat(newinfile,".gz"); /* look for .gz version of the file */ status = ftp_file_exist(newinfile); if (status > 0) { foundfile = 1; if (strlen(newinfile) > FLEN_FILENAME-1) return URL_PARSE_ERROR; strcpy(infile,newinfile); } else if (status < 0) { /* Server is demanding an SSL connection. Change urltype and exit. */ ftps_checkfile(urltype, infile, outfile1); return 0; } if (!foundfile) { if (strlen(infile)+2 > MAXLEN-1) { return URL_PARSE_ERROR; } strcpy(newinfile,infile); strcat(newinfile,".Z"); /* look for .Z version of the file */ if (ftp_file_exist(newinfile)) { foundfile = 1; if (strlen(newinfile) > FLEN_FILENAME-1) return URL_PARSE_ERROR; strcpy(infile,newinfile); } } } if (!foundfile) { strcpy(newinfile,infile); /* look for the base file */ status = ftp_file_exist(newinfile); if (status > 0) { foundfile = 1; if (strlen(newinfile) > FLEN_FILENAME-1) return URL_PARSE_ERROR; strcpy(infile,newinfile); } else if (status < 0) { /* Server is demanding an SSL connection. Change urltype and exit. */ ftps_checkfile(urltype, infile, outfile1); return 0; } } if (!foundfile) { return (FILE_NOT_OPENED); } if (strlen(outfile1)) { /* there is an output file; might need to modify the urltype */ /* don't copy the "file://" prefix, if present. */ if (!strncmp(outfile1, "file://", 7) ) strcpy(netoutfile,outfile1+7); else strcpy(netoutfile,outfile1); if (!strncmp(outfile1, "mem:", 4) ) { /* copy the file to memory, with READ and WRITE access In this case, it makes no difference whether the ftp file and or the output file are compressed or not. */ strcpy(urltype, "ftpmem://"); /* use special driver */ return 0; } if (strstr(infile,".gz") || (strstr(infile,".Z"))) { /* input file is compressed */ if (strstr(outfile1,".gz") || (strstr(outfile1,".Z"))) { strcpy(urltype,"ftpcompress://"); } else { strcpy(urltype,"ftpfile://"); } } else { strcpy(urltype,"ftpfile://"); } } return 0; } /*--------------------------------------------------------------------------*/ /* A small helper function to wait for a particular status on the ftp connectino */ static int ftp_status(FILE *ftp, char *statusstr) { /* read through until we find a string beginning with statusstr */ /* This needs a timeout */ /* Modified 2/19 to return the numerical value of the returned status when it differs from the requested status. */ char recbuf[MAXLEN], errorstr[SHORTLEN]; int len, ftpcode=0; len = strlen(statusstr); while (1) { if (!(fgets(recbuf,MAXLEN,ftp))) { snprintf(errorstr,SHORTLEN,"ERROR: ftp_status wants %s but fgets returned 0",statusstr); ffpmsg(errorstr); return 1; /* error reading */ } recbuf[len] = '\0'; /* make it short */ if (!strcmp(recbuf,statusstr)) { return 0; /* we're ok */ } if (recbuf[0] > '3') { /* oh well, some sort of error. */ snprintf(errorstr,SHORTLEN,"ERROR ftp_status wants %s but got %s", statusstr, recbuf); ffpmsg(errorstr); /* Return the numerical code, if string can be converted to int. But must not return 0 from here. */ ftpcode = atoi(recbuf); return ftpcode ? ftpcode : 1; } snprintf(errorstr,SHORTLEN,"ERROR ftp_status wants %s but got unexpected %s", statusstr, recbuf); ffpmsg(errorstr); } } /* *---------------------------------------------------------------------- * * CreateSocketAddress -- * * This function initializes a sockaddr structure for a host and port. * * Results: * 1 if the host was valid, 0 if the host could not be converted to * an IP address. * * Side effects: * Fills in the *sockaddrPtr structure. * *---------------------------------------------------------------------- */ static int CreateSocketAddress( struct sockaddr_in *sockaddrPtr, /* Socket address */ char *host, /* Host. NULL implies INADDR_ANY */ int port) /* Port number */ { struct hostent *hostent; /* Host database entry */ struct in_addr addr; /* For 64/32 bit madness */ char localhost[MAXLEN]; strcpy(localhost,host); memset((void *) sockaddrPtr, '\0', sizeof(struct sockaddr_in)); sockaddrPtr->sin_family = AF_INET; sockaddrPtr->sin_port = htons((unsigned short) (port & 0xFFFF)); if (host == NULL) { addr.s_addr = INADDR_ANY; } else { addr.s_addr = inet_addr(localhost); if (addr.s_addr == 0xFFFFFFFF) { hostent = gethostbyname(localhost); if (hostent != NULL) { memcpy((void *) &addr, (void *) hostent->h_addr_list[0], (size_t) hostent->h_length); } else { #ifdef EHOSTUNREACH errno = EHOSTUNREACH; #else #ifdef ENXIO errno = ENXIO; #endif #endif return 0; /* error */ } } } /* * NOTE: On 64 bit machines the assignment below is rumored to not * do the right thing. Please report errors related to this if you * observe incorrect behavior on 64 bit machines such as DEC Alphas. * Should we modify this code to do an explicit memcpy? */ sockaddrPtr->sin_addr.s_addr = addr.s_addr; return 1; /* Success. */ } /* Signal handler for timeouts */ static void signal_handler(int sig) { switch (sig) { case SIGALRM: /* process for alarm */ longjmp(env,sig); default: { /* Hmm, shouldn't have happend */ exit(sig); } } } /**************************************************************/ /* Root driver */ /*--------------------------------------------------------------------------*/ int root_init(void) { int ii; for (ii = 0; ii < NMAXFILES; ii++) /* initialize all empty slots in table */ { handleTable[ii].sock = 0; handleTable[ii].currentpos = 0; } return(0); } /*--------------------------------------------------------------------------*/ int root_setoptions(int options) { /* do something with the options argument, to stop compiler warning */ options = 0; return(options); } /*--------------------------------------------------------------------------*/ int root_getoptions(int *options) { *options = 0; return(0); } /*--------------------------------------------------------------------------*/ int root_getversion(int *version) { *version = 10; return(0); } /*--------------------------------------------------------------------------*/ int root_shutdown(void) { return(0); } /*--------------------------------------------------------------------------*/ int root_open(char *url, int rwmode, int *handle) { int ii, status; int sock; *handle = -1; for (ii = 0; ii < NMAXFILES; ii++) /* find empty slot in table */ { if (handleTable[ii].sock == 0) { *handle = ii; break; } } if (*handle == -1) return(TOO_MANY_FILES); /* too many files opened */ /*open the file */ if (rwmode) { status = root_openfile(url, "update", &sock); } else { status = root_openfile(url, "read", &sock); } if (status) return(status); handleTable[ii].sock = sock; handleTable[ii].currentpos = 0; return(0); } /*--------------------------------------------------------------------------*/ int root_create(char *filename, int *handle) { int ii, status; int sock; *handle = -1; for (ii = 0; ii < NMAXFILES; ii++) /* find empty slot in table */ { if (handleTable[ii].sock == 0) { *handle = ii; break; } } if (*handle == -1) return(TOO_MANY_FILES); /* too many files opened */ /*open the file */ status = root_openfile(filename, "create", &sock); if (status) { ffpmsg("Unable to create file"); return(status); } handleTable[ii].sock = sock; handleTable[ii].currentpos = 0; return(0); } /*--------------------------------------------------------------------------*/ int root_size(int handle, LONGLONG *filesize) /* return the size of the file in bytes */ { int sock; int offset; int status; int op; sock = handleTable[handle].sock; status = root_send_buffer(sock,ROOTD_STAT,NULL,0); status = root_recv_buffer(sock,&op,(char *)&offset, 4); *filesize = (LONGLONG) ntohl(offset); return(0); } /*--------------------------------------------------------------------------*/ int root_close(int handle) /* close the file */ { int status; int sock; sock = handleTable[handle].sock; status = root_send_buffer(sock,ROOTD_CLOSE,NULL,0); close(sock); handleTable[handle].sock = 0; return(0); } /*--------------------------------------------------------------------------*/ int root_flush(int handle) /* flush the file */ { int status; int sock; sock = handleTable[handle].sock; status = root_send_buffer(sock,ROOTD_FLUSH,NULL,0); return(0); } /*--------------------------------------------------------------------------*/ int root_seek(int handle, LONGLONG offset) /* seek to position relative to start of the file */ { handleTable[handle].currentpos = offset; return(0); } /*--------------------------------------------------------------------------*/ int root_read(int hdl, void *buffer, long nbytes) /* read bytes from the current position in the file */ { char msg[SHORTLEN]; int op; int status; int astat; /* we presume here that the file position will never be > 2**31 = 2.1GB */ snprintf(msg,SHORTLEN,"%ld %ld ",(long) handleTable[hdl].currentpos,nbytes); status = root_send_buffer(handleTable[hdl].sock,ROOTD_GET,msg,strlen(msg)); if ((unsigned) status != strlen(msg)) { return (READ_ERROR); } astat = 0; status = root_recv_buffer(handleTable[hdl].sock,&op,(char *) &astat,4); if (astat != 0) { return (READ_ERROR); } status = NET_RecvRaw(handleTable[hdl].sock,buffer,nbytes); if (status != nbytes) { return (READ_ERROR); } handleTable[hdl].currentpos += nbytes; return(0); } /*--------------------------------------------------------------------------*/ int root_write(int hdl, void *buffer, long nbytes) /* write bytes at the current position in the file */ { char msg[SHORTLEN]; int len; int sock; int status; int astat; int op; sock = handleTable[hdl].sock; /* we presume here that the file position will never be > 2**31 = 2.1GB */ snprintf(msg,SHORTLEN,"%ld %ld ",(long) handleTable[hdl].currentpos,nbytes); len = strlen(msg); status = root_send_buffer(sock,ROOTD_PUT,msg,len+1); if (status != len+1) { return (WRITE_ERROR); } status = NET_SendRaw(sock,buffer,nbytes,NET_DEFAULT); if (status != nbytes) { return (WRITE_ERROR); } astat = 0; status = root_recv_buffer(handleTable[hdl].sock,&op,(char *) &astat,4); if (astat != 0) { return (WRITE_ERROR); } handleTable[hdl].currentpos += nbytes; return(0); } /*--------------------------------------------------------------------------*/ int root_openfile(char *url, char *rwmode, int *sock) /* lowest level routine to physically open a root file */ { int status; char recbuf[MAXLEN]; char errorstr[MAXLEN]; char proto[SHORTLEN]; char host[SHORTLEN]; char fn[MAXLEN]; char turl[MAXLEN]; int port; int op; int ii; int authstat; /* Parse the URL apart again */ if (strlen(url)+7 > MAXLEN-1) { ffpmsg("Error: url too long"); return(FILE_NOT_OPENED); } strcpy(turl,"root://"); strcat(turl,url); if (NET_ParseUrl(turl,proto,host,&port,fn)) { snprintf(errorstr,MAXLEN,"URL Parse Error (root_open) %s",url); ffpmsg(errorstr); return (FILE_NOT_OPENED); } /* Connect to the remote host */ *sock = NET_TcpConnect(host,port); if (*sock < 0) { ffpmsg("Couldn't connect to host (root_openfile)"); return (FILE_NOT_OPENED); } /* get the username */ if (NULL != getenv("ROOTUSERNAME")) { if (strlen(getenv("ROOTUSERNAME")) > MAXLEN-1) { ffpmsg("root user name too long (root_openfile)"); return (FILE_NOT_OPENED); } strcpy(recbuf,getenv("ROOTUSERNAME")); } else { printf("Username: "); fgets(recbuf,MAXLEN,stdin); recbuf[strlen(recbuf)-1] = '\0'; } status = root_send_buffer(*sock, ROOTD_USER, recbuf,strlen(recbuf)); if (status < 0) { ffpmsg("error talking to remote system on username "); return (FILE_NOT_OPENED); } status = root_recv_buffer(*sock,&op,(char *)&authstat,4); if (!status) { ffpmsg("error talking to remote system on username"); return (FILE_NOT_OPENED); } if (op != ROOTD_AUTH) { ffpmsg("ERROR on ROOTD_USER"); ffpmsg(recbuf); return (FILE_NOT_OPENED); } /* now the password */ if (NULL != getenv("ROOTPASSWORD")) { if (strlen(getenv("ROOTPASSWORD")) > MAXLEN-1) { ffpmsg("root password too long (root_openfile)"); return (FILE_NOT_OPENED); } strcpy(recbuf,getenv("ROOTPASSWORD")); } else { printf("Password: "); fgets(recbuf,MAXLEN,stdin); recbuf[strlen(recbuf)-1] = '\0'; } /* ones complement the password */ for (ii=0;(unsigned) ii MAXLEN-1) { ffpmsg("root file name too long (root_openfile)"); return (FILE_NOT_OPENED); } strcpy(recbuf,fn); strcat(recbuf," "); strcat(recbuf,rwmode); status = root_send_buffer(*sock, ROOTD_OPEN, recbuf, strlen(recbuf)); if (status < 0) { ffpmsg("error talking to remote system on open "); return (FILE_NOT_OPENED); } status = root_recv_buffer(*sock,&op,(char *)&authstat,4); if (status < 0) { ffpmsg("error talking to remote system on open"); return (FILE_NOT_OPENED); } if ((op != ROOTD_OPEN) && (authstat != 0)) { ffpmsg("ERROR on ROOTD_OPEN"); ffpmsg(recbuf); return (FILE_NOT_OPENED); } return 0; } static int root_send_buffer(int sock, int op, char *buffer, int buflen) { /* send a buffer, the form is includes the 4 bytes for the op, the length bytes (4) are implicit if buffer is null don't send it, not everything needs something sent */ int len; int status; int hdr[2]; len = 4; if (buffer != NULL) { len += buflen; } hdr[0] = htonl(len); hdr[1] = htonl(op); status = NET_SendRaw(sock,hdr,sizeof(hdr),NET_DEFAULT); if (status < 0) { return status; } if (buffer != NULL) { status = NET_SendRaw(sock,buffer,buflen,NET_DEFAULT); } return status; } static int root_recv_buffer(int sock, int *op, char *buffer, int buflen) { /* recv a buffer, the form is */ int recv1 = 0; int len; int status; char recbuf[MAXLEN]; status = NET_RecvRaw(sock,&len,4); if (status < 0) { return status; } recv1 += status; len = ntohl(len); /* ok, have the length, recive the operation */ len -= 4; status = NET_RecvRaw(sock,op,4); if (status < 0) { return status; } recv1 += status; *op = ntohl(*op); if (len > MAXLEN) { len = MAXLEN; } if (len > 0) { /* Get the rest of the message */ status = NET_RecvRaw(sock,recbuf,len); if (len > buflen) { len = buflen; } memcpy(buffer,recbuf,len); if (status < 0) { return status; } } recv1 += status; return recv1; } /*****************************************************************************/ /* Encode a string into MIME Base64 format string */ static int encode64(unsigned s_len, char *src, unsigned d_len, char *dst) { static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789" "+/"; unsigned triad; for (triad = 0; triad < s_len; triad += 3) { unsigned long int sr; unsigned byte; for (byte = 0; (byte<3) && (triad+byte #include #include #include #include #include #include #if defined(unix) || defined(__unix__) || defined(__unix) || defined(HAVE_UNISTD_H) #include #endif static int shared_kbase = 0; /* base for shared memory handles */ static int shared_maxseg = 0; /* max number of shared memory blocks */ static int shared_range = 0; /* max number of tried entries */ static int shared_fd = SHARED_INVALID; /* handle of global access lock file */ static int shared_gt_h = SHARED_INVALID; /* handle of global table segment */ static SHARED_LTAB *shared_lt = NULL; /* local table pointer */ static SHARED_GTAB *shared_gt = NULL; /* global table pointer */ static int shared_create_mode = 0666; /* permission flags for created objects */ static int shared_debug = 1; /* simple debugging tool, set to 0 to disable messages */ static int shared_init_called = 0; /* flag whether shared_init() has been called, used for delayed init */ /* static support routines prototypes */ static int shared_clear_entry(int idx); /* unconditionally clear entry */ static int shared_destroy_entry(int idx); /* unconditionally destroy sema & shseg and clear entry */ static int shared_mux(int idx, int mode); /* obtain exclusive access to specified segment */ static int shared_demux(int idx, int mode); /* free exclusive access to specified segment */ static int shared_process_count(int sem); /* valid only for time of invocation */ static int shared_delta_process(int sem, int delta); /* change number of processes hanging on segment */ static int shared_attach_process(int sem); static int shared_detach_process(int sem); static int shared_get_free_entry(int newhandle); /* get free entry in shared_key, or -1, entry is set rw locked */ static int shared_get_hash(long size, int idx);/* return hash value for malloc */ static long shared_adjust_size(long size); /* size must be >= 0 !!! */ static int shared_check_locked_index(int idx); /* verify that given idx is valid */ static int shared_map(int idx); /* map all tables for given idx, check for validity */ static int shared_validate(int idx, int mode); /* use intrnally inside crit.sect !!! */ /* support routines - initialization */ static int shared_clear_entry(int idx) /* unconditionally clear entry */ { if ((idx < 0) || (idx >= shared_maxseg)) return(SHARED_BADARG); shared_gt[idx].key = SHARED_INVALID; /* clear entries in global table */ shared_gt[idx].handle = SHARED_INVALID; shared_gt[idx].sem = SHARED_INVALID; shared_gt[idx].semkey = SHARED_INVALID; shared_gt[idx].nprocdebug = 0; shared_gt[idx].size = 0; shared_gt[idx].attr = 0; return(SHARED_OK); } static int shared_destroy_entry(int idx) /* unconditionally destroy sema & shseg and clear entry */ { int r, r2; union semun filler; if ((idx < 0) || (idx >= shared_maxseg)) return(SHARED_BADARG); r2 = r = SHARED_OK; filler.val = 0; /* this is to make cc happy (warning otherwise) */ if (SHARED_INVALID != shared_gt[idx].sem) r = semctl(shared_gt[idx].sem, 0, IPC_RMID, filler); /* destroy semaphore */ if (SHARED_INVALID != shared_gt[idx].handle) r2 = shmctl(shared_gt[idx].handle, IPC_RMID, 0); /* destroy shared memory segment */ if (SHARED_OK == r) r = r2; /* accumulate error code in r, free r2 */ r2 = shared_clear_entry(idx); return((SHARED_OK == r) ? r2 : r); } void shared_cleanup(void) /* this must (should) be called during exit/abort */ { int i, j, r, oktodelete, filelocked, segmentspresent; flock_t flk; struct shmid_ds ds; if (shared_debug) printf("shared_cleanup:"); if (NULL != shared_lt) { if (shared_debug) printf(" deleting segments:"); for (i=0; i>\n"); return; } int shared_init(int debug_msgs) /* initialize shared memory stuff, you have to call this routine once */ { int i; char buf[1000], *p; mode_t oldumask; shared_init_called = 1; /* tell everybody no need to call us for the 2nd time */ shared_debug = debug_msgs; /* set required debug mode */ if (shared_debug) printf("shared_init:"); shared_kbase = 0; /* adapt to current env. settings */ if (NULL != (p = getenv(SHARED_ENV_KEYBASE))) shared_kbase = atoi(p); if (0 == shared_kbase) shared_kbase = SHARED_KEYBASE; if (shared_debug) printf(" keybase=%d", shared_kbase); shared_maxseg = 0; if (NULL != (p = getenv(SHARED_ENV_MAXSEG))) shared_maxseg = atoi(p); if (0 == shared_maxseg) shared_maxseg = SHARED_MAXSEG; if (shared_debug) printf(" maxseg=%d", shared_maxseg); shared_range = 3 * shared_maxseg; if (SHARED_INVALID == shared_fd) /* create rw locking file (this file is never deleted) */ { if (shared_debug) printf(" lockfileinit="); snprintf(buf, 1000,"%s.%d.%d", SHARED_FDNAME, shared_kbase, shared_maxseg); oldumask = umask(0); shared_fd = open(buf, O_TRUNC | O_EXCL | O_CREAT | O_RDWR, shared_create_mode); umask(oldumask); if (SHARED_INVALID == shared_fd) /* or just open rw locking file, in case it already exists */ { shared_fd = open(buf, O_TRUNC | O_RDWR, shared_create_mode); if (SHARED_INVALID == shared_fd) return(SHARED_NOFILE); if (shared_debug) printf("slave"); } else { if (shared_debug) printf("master"); } } if (SHARED_INVALID == shared_gt_h) /* global table not attached, try to create it in shared memory */ { if (shared_debug) printf(" globalsharedtableinit="); shared_gt_h = shmget(shared_kbase, shared_maxseg * sizeof(SHARED_GTAB), IPC_CREAT | IPC_EXCL | shared_create_mode); /* try open as a master */ if (SHARED_INVALID == shared_gt_h) /* if failed, try to open as a slave */ { shared_gt_h = shmget(shared_kbase, shared_maxseg * sizeof(SHARED_GTAB), shared_create_mode); if (SHARED_INVALID == shared_gt_h) return(SHARED_IPCERR); /* means deleted ID residing in system, shared mem unusable ... */ shared_gt = (SHARED_GTAB *)shmat(shared_gt_h, 0, 0); /* attach segment */ if (((SHARED_GTAB *)SHARED_INVALID) == shared_gt) return(SHARED_IPCERR); if (shared_debug) printf("slave"); } else { shared_gt = (SHARED_GTAB *)shmat(shared_gt_h, 0, 0); /* attach segment */ if (((SHARED_GTAB *)SHARED_INVALID) == shared_gt) return(SHARED_IPCERR); for (i=0; i>\n"); return(SHARED_OK); } int shared_recover(int id) /* try to recover dormant segments after applic crash */ { int i, r, r2; if (NULL == shared_gt) return(SHARED_NOTINIT); /* not initialized */ if (NULL == shared_lt) return(SHARED_NOTINIT); /* not initialized */ r = SHARED_OK; for (i=0; i r2) || (0 == r2)) { if (shared_debug) printf("Bogus handle=%d nproc=%d sema=%d:", i, shared_gt[i].nprocdebug, r2); r = shared_destroy_entry(i); if (shared_debug) { printf("%s", r ? "error couldn't clear handle" : "handle cleared"); } } shared_demux(i, SHARED_RDWRITE); } return(r); /* table full */ } /* API routines - mutexes and locking */ static int shared_mux(int idx, int mode) /* obtain exclusive access to specified segment */ { flock_t flk; int r; if (0 == shared_init_called) /* delayed initialization */ { if (SHARED_OK != (r = shared_init(0))) return(r); } if (SHARED_INVALID == shared_fd) return(SHARED_NOTINIT); if ((idx < 0) || (idx >= shared_maxseg)) return(SHARED_BADARG); flk.l_type = ((mode & SHARED_RDWRITE) ? F_WRLCK : F_RDLCK); flk.l_whence = 0; flk.l_start = idx; flk.l_len = 1; if (shared_debug) printf(" [mux (%d): ", idx); if (-1 == fcntl(shared_fd, ((mode & SHARED_NOWAIT) ? F_SETLK : F_SETLKW), &flk)) { switch (errno) { case EAGAIN: ; case EACCES: if (shared_debug) printf("again]"); return(SHARED_AGAIN); default: if (shared_debug) printf("err]"); return(SHARED_IPCERR); } } if (shared_debug) printf("ok]"); return(SHARED_OK); } static int shared_demux(int idx, int mode) /* free exclusive access to specified segment */ { flock_t flk; if (SHARED_INVALID == shared_fd) return(SHARED_NOTINIT); if ((idx < 0) || (idx >= shared_maxseg)) return(SHARED_BADARG); flk.l_type = F_UNLCK; flk.l_whence = 0; flk.l_start = idx; flk.l_len = 1; if (shared_debug) printf(" [demux (%d): ", idx); if (-1 == fcntl(shared_fd, F_SETLKW, &flk)) { switch (errno) { case EAGAIN: ; case EACCES: if (shared_debug) printf("again]"); return(SHARED_AGAIN); default: if (shared_debug) printf("err]"); return(SHARED_IPCERR); } } if (shared_debug) printf("mode=%d ok]", mode); return(SHARED_OK); } static int shared_process_count(int sem) /* valid only for time of invocation */ { union semun su; su.val = 0; /* to force compiler not to give warning messages */ return(semctl(sem, 0, GETVAL, su)); /* su is unused here */ } static int shared_delta_process(int sem, int delta) /* change number of processes hanging on segment */ { struct sembuf sb; if (SHARED_INVALID == sem) return(SHARED_BADARG); /* semaphore not attached */ sb.sem_num = 0; sb.sem_op = delta; sb.sem_flg = SEM_UNDO; return((-1 == semop(sem, &sb, 1)) ? SHARED_IPCERR : SHARED_OK); } static int shared_attach_process(int sem) { if (shared_debug) printf(" [attach process]"); return(shared_delta_process(sem, 1)); } static int shared_detach_process(int sem) { if (shared_debug) printf(" [detach process]"); return(shared_delta_process(sem, -1)); } /* API routines - hashing and searching */ static int shared_get_free_entry(int newhandle) /* get newhandle, or -1, entry is set rw locked */ { if (NULL == shared_gt) return(-1); /* not initialized */ if (NULL == shared_lt) return(-1); /* not initialized */ if (newhandle < 0) return(-1); if (newhandle >= shared_maxseg) return(-1); if (shared_lt[newhandle].tcnt) return(-1); /* somebody (we) is using it */ if (shared_mux(newhandle, SHARED_NOWAIT | SHARED_RDWRITE)) return(-1); /* used by others */ if (SHARED_INVALID == shared_gt[newhandle].key) return(newhandle); /* we have found free slot, lock it and return index */ shared_demux(newhandle, SHARED_RDWRITE); if (shared_debug) printf("[free_entry - ERROR - entry unusable]"); return(-1); /* table full */ } static int shared_get_hash(long size, int idx) /* return hash value for malloc */ { static int counter = 0; int hash; hash = (counter + size * idx) % shared_range; counter = (counter + 1) % shared_range; return(hash); } static long shared_adjust_size(long size) /* size must be >= 0 !!! */ { return(((size + sizeof(BLKHEAD) + SHARED_GRANUL - 1) / SHARED_GRANUL) * SHARED_GRANUL); } /* API routines - core : malloc/realloc/free/attach/detach/lock/unlock */ int shared_malloc(long size, int mode, int newhandle) /* return idx or SHARED_INVALID */ { int h, i, r, idx, key; union semun filler; BLKHEAD *bp; if (0 == shared_init_called) /* delayed initialization */ { if (SHARED_OK != (r = shared_init(0))) return(r); } if (shared_debug) printf("malloc (size = %ld, mode = %d):", size, mode); if (size < 0) return(SHARED_INVALID); if (-1 == (idx = shared_get_free_entry(newhandle))) return(SHARED_INVALID); if (shared_debug) printf(" idx=%d", idx); for (i = 0; ; i++) { if (i >= shared_range) /* table full, signal error & exit */ { shared_demux(idx, SHARED_RDWRITE); return(SHARED_INVALID); } key = shared_kbase + ((i + shared_get_hash(size, idx)) % shared_range); if (shared_debug) printf(" key=%d", key); h = shmget(key, shared_adjust_size(size), IPC_CREAT | IPC_EXCL | shared_create_mode); if (shared_debug) printf(" handle=%d", h); if (SHARED_INVALID == h) continue; /* segment already accupied */ bp = (BLKHEAD *)shmat(h, 0, 0); /* try attach */ if (shared_debug) printf(" p=%p", bp); if (((BLKHEAD *)SHARED_INVALID) == bp) /* cannot attach, delete segment, try with another key */ { shmctl(h, IPC_RMID, 0); continue; } /* now create semaphor counting number of processes attached */ if (SHARED_INVALID == (shared_gt[idx].sem = semget(key, 1, IPC_CREAT | IPC_EXCL | shared_create_mode))) { shmdt((void *)bp); /* cannot create segment, delete everything */ shmctl(h, IPC_RMID, 0); continue; /* try with another key */ } if (shared_debug) printf(" sem=%d", shared_gt[idx].sem); if (shared_attach_process(shared_gt[idx].sem)) /* try attach process */ { semctl(shared_gt[idx].sem, 0, IPC_RMID, filler); /* destroy semaphore */ shmdt((char *)bp); /* detach shared mem segment */ shmctl(h, IPC_RMID, 0); /* destroy shared mem segment */ continue; /* try with another key */ } bp->s.tflag = BLOCK_SHARED; /* fill in data in segment's header (this is really not necessary) */ bp->s.ID[0] = SHARED_ID_0; bp->s.ID[1] = SHARED_ID_1; bp->s.handle = idx; /* used in yorick */ if (mode & SHARED_RESIZE) { if (shmdt((char *)bp)) r = SHARED_IPCERR; /* if segment is resizable, then detach segment */ shared_lt[idx].p = NULL; } else { shared_lt[idx].p = bp; } shared_lt[idx].tcnt = 1; /* one thread using segment */ shared_lt[idx].lkcnt = 0; /* no locks at the moment */ shared_lt[idx].seekpos = 0L; /* r/w pointer positioned at beg of block */ shared_gt[idx].handle = h; /* fill in data in global table */ shared_gt[idx].size = size; shared_gt[idx].attr = mode; shared_gt[idx].semkey = key; shared_gt[idx].key = key; shared_gt[idx].nprocdebug = 0; break; } shared_demux(idx, SHARED_RDWRITE); /* hope this will not fail */ return(idx); } int shared_attach(int idx) { int r, r2; if (SHARED_OK != (r = shared_mux(idx, SHARED_RDWRITE | SHARED_WAIT))) return(r); if (SHARED_OK != (r = shared_map(idx))) { shared_demux(idx, SHARED_RDWRITE); return(r); } if (shared_attach_process(shared_gt[idx].sem)) /* try attach process */ { shmdt((char *)(shared_lt[idx].p)); /* cannot attach process, detach everything */ shared_lt[idx].p = NULL; shared_demux(idx, SHARED_RDWRITE); return(SHARED_BADARG); } shared_lt[idx].tcnt++; /* one more thread is using segment */ if (shared_gt[idx].attr & SHARED_RESIZE) /* if resizeable, detach and return special pointer */ { if (shmdt((char *)(shared_lt[idx].p))) r = SHARED_IPCERR; /* if segment is resizable, then detach segment */ shared_lt[idx].p = NULL; } shared_lt[idx].seekpos = 0L; /* r/w pointer positioned at beg of block */ r2 = shared_demux(idx, SHARED_RDWRITE); return(r ? r : r2); } static int shared_check_locked_index(int idx) /* verify that given idx is valid */ { int r; if (0 == shared_init_called) /* delayed initialization */ { if (SHARED_OK != (r = shared_init(0))) return(r); } if ((idx < 0) || (idx >= shared_maxseg)) return(SHARED_BADARG); if (NULL == shared_lt[idx].p) return(SHARED_BADARG); /* NULL pointer, not attached ?? */ if (0 == shared_lt[idx].lkcnt) return(SHARED_BADARG); /* not locked ?? */ if ((SHARED_ID_0 != (shared_lt[idx].p)->s.ID[0]) || (SHARED_ID_1 != (shared_lt[idx].p)->s.ID[1]) || (BLOCK_SHARED != (shared_lt[idx].p)->s.tflag)) /* invalid data in segment */ return(SHARED_BADARG); return(SHARED_OK); } static int shared_map(int idx) /* map all tables for given idx, check for validity */ { int h; /* have to obtain excl. access before calling shared_map */ BLKHEAD *bp; if ((idx < 0) || (idx >= shared_maxseg)) return(SHARED_BADARG); if (SHARED_INVALID == shared_gt[idx].key) return(SHARED_BADARG); if (SHARED_INVALID == (h = shmget(shared_gt[idx].key, 1, shared_create_mode))) return(SHARED_BADARG); if (((BLKHEAD *)SHARED_INVALID) == (bp = (BLKHEAD *)shmat(h, 0, 0))) return(SHARED_BADARG); if ((SHARED_ID_0 != bp->s.ID[0]) || (SHARED_ID_1 != bp->s.ID[1]) || (BLOCK_SHARED != bp->s.tflag) || (h != shared_gt[idx].handle)) { shmdt((char *)bp); /* invalid segment, detach everything */ return(SHARED_BADARG); } if (shared_gt[idx].sem != semget(shared_gt[idx].semkey, 1, shared_create_mode)) /* check if sema is still there */ { shmdt((char *)bp); /* cannot attach semaphore, detach everything */ return(SHARED_BADARG); } shared_lt[idx].p = bp; /* store pointer to shmem data */ return(SHARED_OK); } static int shared_validate(int idx, int mode) /* use intrnally inside crit.sect !!! */ { int r; if (SHARED_OK != (r = shared_mux(idx, mode))) return(r); /* idx checked by shared_mux */ if (NULL == shared_lt[idx].p) if (SHARED_OK != (r = shared_map(idx))) { shared_demux(idx, mode); return(r); } if ((SHARED_ID_0 != (shared_lt[idx].p)->s.ID[0]) || (SHARED_ID_1 != (shared_lt[idx].p)->s.ID[1]) || (BLOCK_SHARED != (shared_lt[idx].p)->s.tflag)) { shared_demux(idx, mode); return(r); } return(SHARED_OK); } SHARED_P shared_realloc(int idx, long newsize) /* realloc shared memory segment */ { int h, key, i, r; BLKHEAD *bp; long transfersize; r = SHARED_OK; if (newsize < 0) return(NULL); if (shared_check_locked_index(idx)) return(NULL); if (0 == (shared_gt[idx].attr & SHARED_RESIZE)) return(NULL); if (-1 != shared_lt[idx].lkcnt) return(NULL); /* check for RW lock */ if (shared_adjust_size(shared_gt[idx].size) == shared_adjust_size(newsize)) { shared_gt[idx].size = newsize; return((SHARED_P)((shared_lt[idx].p) + 1)); } for (i = 0; ; i++) { if (i >= shared_range) return(NULL); /* table full, signal error & exit */ key = shared_kbase + ((i + shared_get_hash(newsize, idx)) % shared_range); h = shmget(key, shared_adjust_size(newsize), IPC_CREAT | IPC_EXCL | shared_create_mode); if (SHARED_INVALID == h) continue; /* segment already accupied */ bp = (BLKHEAD *)shmat(h, 0, 0); /* try attach */ if (((BLKHEAD *)SHARED_INVALID) == bp) /* cannot attach, delete segment, try with another key */ { shmctl(h, IPC_RMID, 0); continue; } *bp = *(shared_lt[idx].p); /* copy header, then data */ transfersize = ((newsize < shared_gt[idx].size) ? newsize : shared_gt[idx].size); if (transfersize > 0) memcpy((void *)(bp + 1), (void *)((shared_lt[idx].p) + 1), transfersize); if (shmdt((char *)(shared_lt[idx].p))) r = SHARED_IPCERR; /* try to detach old segment */ if (shmctl(shared_gt[idx].handle, IPC_RMID, 0)) if (SHARED_OK == r) r = SHARED_IPCERR; /* destroy old shared memory segment */ shared_gt[idx].size = newsize; /* signal new size */ shared_gt[idx].handle = h; /* signal new handle */ shared_gt[idx].key = key; /* signal new key */ shared_lt[idx].p = bp; break; } return((SHARED_P)(bp + 1)); } int shared_free(int idx) /* detach segment, if last process & !PERSIST, destroy segment */ { int cnt, r, r2; if (SHARED_OK != (r = shared_validate(idx, SHARED_RDWRITE | SHARED_WAIT))) return(r); if (SHARED_OK != (r = shared_detach_process(shared_gt[idx].sem))) /* update number of processes using segment */ { shared_demux(idx, SHARED_RDWRITE); return(r); } shared_lt[idx].tcnt--; /* update number of threads using segment */ if (shared_lt[idx].tcnt > 0) return(shared_demux(idx, SHARED_RDWRITE)); /* if more threads are using segment we are done */ if (shmdt((char *)(shared_lt[idx].p))) /* if, we are the last thread, try to detach segment */ { shared_demux(idx, SHARED_RDWRITE); return(SHARED_IPCERR); } shared_lt[idx].p = NULL; /* clear entry in local table */ shared_lt[idx].seekpos = 0L; /* r/w pointer positioned at beg of block */ if (-1 == (cnt = shared_process_count(shared_gt[idx].sem))) /* get number of processes hanging on segment */ { shared_demux(idx, SHARED_RDWRITE); return(SHARED_IPCERR); } if ((0 == cnt) && (0 == (shared_gt[idx].attr & SHARED_PERSIST))) r = shared_destroy_entry(idx); /* no procs on seg, destroy it */ r2 = shared_demux(idx, SHARED_RDWRITE); return(r ? r : r2); } SHARED_P shared_lock(int idx, int mode) /* lock given segment for exclusive access */ { int r; if (shared_mux(idx, mode)) return(NULL); /* idx checked by shared_mux */ if (0 != shared_lt[idx].lkcnt) /* are we already locked ?? */ if (SHARED_OK != (r = shared_map(idx))) { shared_demux(idx, mode); return(NULL); } if (NULL == shared_lt[idx].p) /* stupid pointer ?? */ if (SHARED_OK != (r = shared_map(idx))) { shared_demux(idx, mode); return(NULL); } if ((SHARED_ID_0 != (shared_lt[idx].p)->s.ID[0]) || (SHARED_ID_1 != (shared_lt[idx].p)->s.ID[1]) || (BLOCK_SHARED != (shared_lt[idx].p)->s.tflag)) { shared_demux(idx, mode); return(NULL); } if (mode & SHARED_RDWRITE) { shared_lt[idx].lkcnt = -1; shared_gt[idx].nprocdebug++; } else shared_lt[idx].lkcnt++; shared_lt[idx].seekpos = 0L; /* r/w pointer positioned at beg of block */ return((SHARED_P)((shared_lt[idx].p) + 1)); } int shared_unlock(int idx) /* unlock given segment, assumes seg is locked !! */ { int r, r2, mode; if (SHARED_OK != (r = shared_check_locked_index(idx))) return(r); if (shared_lt[idx].lkcnt > 0) { shared_lt[idx].lkcnt--; /* unlock read lock */ mode = SHARED_RDONLY; } else { shared_lt[idx].lkcnt = 0; /* unlock write lock */ shared_gt[idx].nprocdebug--; mode = SHARED_RDWRITE; } if (0 == shared_lt[idx].lkcnt) if (shared_gt[idx].attr & SHARED_RESIZE) { if (shmdt((char *)(shared_lt[idx].p))) r = SHARED_IPCERR; /* segment is resizable, then detach segment */ shared_lt[idx].p = NULL; /* signal detachment in local table */ } r2 = shared_demux(idx, mode); /* unlock segment, rest is only parameter checking */ return(r ? r : r2); } /* API routines - support and info routines */ int shared_attr(int idx) /* get the attributes of the shared memory segment */ { int r; if (shared_check_locked_index(idx)) return(SHARED_INVALID); r = shared_gt[idx].attr; return(r); } int shared_set_attr(int idx, int newattr) /* get the attributes of the shared memory segment */ { int r; if (shared_check_locked_index(idx)) return(SHARED_INVALID); if (-1 != shared_lt[idx].lkcnt) return(SHARED_INVALID); /* ADDED - check for RW lock */ r = shared_gt[idx].attr; shared_gt[idx].attr = newattr; return(r); } int shared_set_debug(int mode) /* set/reset debug mode */ { int r = shared_debug; shared_debug = mode; return(r); } int shared_set_createmode(int mode) /* set/reset debug mode */ { int r = shared_create_mode; shared_create_mode = mode; return(r); } int shared_list(int id) { int i, r; if (NULL == shared_gt) return(SHARED_NOTINIT); /* not initialized */ if (NULL == shared_lt) return(SHARED_NOTINIT); /* not initialized */ if (shared_debug) printf("shared_list:"); r = SHARED_OK; printf(" Idx Key Nproc Size Flags\n"); printf("==============================================\n"); for (i=0; i= SHARED_ERRBASE) { printf(" cannot clear PERSIST attribute"); } if (shared_free(i)) { printf(" delete failed\n"); } else { printf(" deleted\n"); } } if (shared_debug) printf(" done\n"); return(r); /* table full */ } /************************* CFITSIO DRIVER FUNCTIONS ***************************/ int smem_init(void) { return(0); } int smem_shutdown(void) { if (shared_init_called) shared_cleanup(); return(0); } int smem_setoptions(int option) { option = 0; return(0); } int smem_getoptions(int *options) { if (NULL == options) return(SHARED_NULPTR); *options = 0; return(0); } int smem_getversion(int *version) { if (NULL == version) return(SHARED_NULPTR); *version = 10; return(0); } int smem_open(char *filename, int rwmode, int *driverhandle) { int h, nitems, r; DAL_SHM_SEGHEAD *sp; if (NULL == filename) return(SHARED_NULPTR); if (NULL == driverhandle) return(SHARED_NULPTR); nitems = sscanf(filename, "h%d", &h); if (1 != nitems) return(SHARED_BADARG); if (SHARED_OK != (r = shared_attach(h))) return(r); if (NULL == (sp = (DAL_SHM_SEGHEAD *)shared_lock(h, ((READWRITE == rwmode) ? SHARED_RDWRITE : SHARED_RDONLY)))) { shared_free(h); return(SHARED_BADARG); } if ((h != sp->h) || (DAL_SHM_SEGHEAD_ID != sp->ID)) { shared_unlock(h); shared_free(h); return(SHARED_BADARG); } *driverhandle = h; return(0); } int smem_create(char *filename, int *driverhandle) { DAL_SHM_SEGHEAD *sp; int h, sz, nitems; if (NULL == filename) return(SHARED_NULPTR); /* currently ignored */ if (NULL == driverhandle) return(SHARED_NULPTR); nitems = sscanf(filename, "h%d", &h); if (1 != nitems) return(SHARED_BADARG); if (SHARED_INVALID == (h = shared_malloc(sz = 2880 + sizeof(DAL_SHM_SEGHEAD), SHARED_RESIZE | SHARED_PERSIST, h))) return(SHARED_NOMEM); if (NULL == (sp = (DAL_SHM_SEGHEAD *)shared_lock(h, SHARED_RDWRITE))) { shared_free(h); return(SHARED_BADARG); } sp->ID = DAL_SHM_SEGHEAD_ID; sp->h = h; sp->size = sz; sp->nodeidx = -1; *driverhandle = h; return(0); } int smem_close(int driverhandle) { int r; if (SHARED_OK != (r = shared_unlock(driverhandle))) return(r); return(shared_free(driverhandle)); } int smem_remove(char *filename) { int nitems, h, r; if (NULL == filename) return(SHARED_NULPTR); nitems = sscanf(filename, "h%d", &h); if (1 != nitems) return(SHARED_BADARG); if (0 == shared_check_locked_index(h)) /* are we locked ? */ { if (-1 != shared_lt[h].lkcnt) /* are we locked RO ? */ { if (SHARED_OK != (r = shared_unlock(h))) return(r); /* yes, so relock in RW */ if (NULL == shared_lock(h, SHARED_RDWRITE)) return(SHARED_BADARG); } } else /* not locked */ { if (SHARED_OK != (r = smem_open(filename, READWRITE, &h))) return(r); /* so open in RW mode */ } shared_set_attr(h, SHARED_RESIZE); /* delete PERSIST attribute */ return(smem_close(h)); /* detach segment (this will delete it) */ } int smem_size(int driverhandle, LONGLONG *size) { if (NULL == size) return(SHARED_NULPTR); if (shared_check_locked_index(driverhandle)) return(SHARED_INVALID); *size = (LONGLONG) (shared_gt[driverhandle].size - sizeof(DAL_SHM_SEGHEAD)); return(0); } int smem_flush(int driverhandle) { if (shared_check_locked_index(driverhandle)) return(SHARED_INVALID); return(0); } int smem_seek(int driverhandle, LONGLONG offset) { if (offset < 0) return(SHARED_BADARG); if (shared_check_locked_index(driverhandle)) return(SHARED_INVALID); shared_lt[driverhandle].seekpos = offset; return(0); } int smem_read(int driverhandle, void *buffer, long nbytes) { if (NULL == buffer) return(SHARED_NULPTR); if (shared_check_locked_index(driverhandle)) return(SHARED_INVALID); if (nbytes < 0) return(SHARED_BADARG); if ((shared_lt[driverhandle].seekpos + nbytes) > shared_gt[driverhandle].size) return(SHARED_BADARG); /* read beyond EOF */ memcpy(buffer, ((char *)(((DAL_SHM_SEGHEAD *)(shared_lt[driverhandle].p + 1)) + 1)) + shared_lt[driverhandle].seekpos, nbytes); shared_lt[driverhandle].seekpos += nbytes; return(0); } int smem_write(int driverhandle, void *buffer, long nbytes) { if (NULL == buffer) return(SHARED_NULPTR); if (shared_check_locked_index(driverhandle)) return(SHARED_INVALID); if (-1 != shared_lt[driverhandle].lkcnt) return(SHARED_INVALID); /* are we locked RW ? */ if (nbytes < 0) return(SHARED_BADARG); if ((unsigned long)(shared_lt[driverhandle].seekpos + nbytes) > (unsigned long)(shared_gt[driverhandle].size - sizeof(DAL_SHM_SEGHEAD))) { /* need to realloc shmem */ if (NULL == shared_realloc(driverhandle, shared_lt[driverhandle].seekpos + nbytes + sizeof(DAL_SHM_SEGHEAD))) return(SHARED_NOMEM); } memcpy(((char *)(((DAL_SHM_SEGHEAD *)(shared_lt[driverhandle].p + 1)) + 1)) + shared_lt[driverhandle].seekpos, buffer, nbytes); shared_lt[driverhandle].seekpos += nbytes; return(0); } #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/drvrsmem.h0000644000175100001710000001461000000000000020135 0ustar00vstsdocker/* S H A R E D M E M O R Y D R I V E R ======================================= by Jerzy.Borkowski@obs.unige.ch 09-Mar-98 : initial version 1.0 released 23-Mar-98 : shared_malloc now accepts new handle as an argument */ #include /* this is necessary for Solaris/Linux */ #include #include #ifdef _AIX #include #else #include #endif /* configuration parameters */ #define SHARED_MAXSEG (16) /* maximum number of shared memory blocks */ #define SHARED_KEYBASE (14011963) /* base for shared memory keys, may be overriden by getenv */ #define SHARED_FDNAME ("/tmp/.shmem-lockfile") /* template for lock file name */ #define SHARED_ENV_KEYBASE ("SHMEM_LIB_KEYBASE") /* name of environment variable */ #define SHARED_ENV_MAXSEG ("SHMEM_LIB_MAXSEG") /* name of environment variable */ /* useful constants */ #define SHARED_RDONLY (0) /* flag for shared_(un)lock, lock for read */ #define SHARED_RDWRITE (1) /* flag for shared_(un)lock, lock for write */ #define SHARED_WAIT (0) /* flag for shared_lock, block if cannot lock immediate */ #define SHARED_NOWAIT (2) /* flag for shared_lock, fail if cannot lock immediate */ #define SHARED_NOLOCK (0x100) /* flag for shared_validate function */ #define SHARED_RESIZE (4) /* flag for shared_malloc, object is resizeable */ #define SHARED_PERSIST (8) /* flag for shared_malloc, object is not deleted after last proc detaches */ #define SHARED_INVALID (-1) /* invalid handle for semaphore/shared memory */ #define SHARED_EMPTY (0) /* entries for shared_used table */ #define SHARED_USED (1) #define SHARED_GRANUL (16384) /* granularity of shared_malloc allocation = phys page size, system dependent */ /* checkpoints in shared memory segments - might be omitted */ #define SHARED_ID_0 ('J') /* first byte of identifier in BLKHEAD */ #define SHARED_ID_1 ('B') /* second byte of identifier in BLKHEAD */ #define BLOCK_REG (0) /* value for tflag member of BLKHEAD */ #define BLOCK_SHARED (1) /* value for tflag member of BLKHEAD */ /* generic error codes */ #define SHARED_OK (0) #define SHARED_ERR_MIN_IDX SHARED_BADARG #define SHARED_ERR_MAX_IDX SHARED_NORESIZE #define DAL_SHM_FREE (0) #define DAL_SHM_USED (1) #define DAL_SHM_ID0 ('D') #define DAL_SHM_ID1 ('S') #define DAL_SHM_ID2 ('M') #define DAL_SHM_SEGHEAD_ID (0x19630114) /* data types */ /* BLKHEAD object is placed at the beginning of every memory segment (both shared and regular) to allow automatic recognition of segments type */ typedef union { struct BLKHEADstruct { char ID[2]; /* ID = 'JB', just as a checkpoint */ char tflag; /* is it shared memory or regular one ? */ int handle; /* this is not necessary, used only for non-resizeable objects via ptr */ } s; double d; /* for proper alignment on every machine */ } BLKHEAD; typedef void *SHARED_P; /* generic type of shared memory pointer */ typedef struct SHARED_GTABstruct /* data type used in global table */ { int sem; /* access semaphore (1 field): process count */ int semkey; /* key value used to generate semaphore handle */ int key; /* key value used to generate shared memory handle (realloc changes it) */ int handle; /* handle of shared memory segment */ int size; /* size of shared memory segment */ int nprocdebug; /* attached proc counter, helps remove zombie segments */ char attr; /* attributes of shared memory object */ } SHARED_GTAB; typedef struct SHARED_LTABstruct /* data type used in local table */ { BLKHEAD *p; /* pointer to segment (may be null) */ int tcnt; /* number of threads in this process attached to segment */ int lkcnt; /* >=0 <- number of read locks, -1 - write lock */ long seekpos; /* current pointer position, read/write/seek operations change it */ } SHARED_LTAB; /* system dependent definitions */ #ifndef HAVE_FLOCK_T typedef struct flock flock_t; #define HAVE_FLOCK_T #endif #ifndef HAVE_UNION_SEMUN union semun { int val; struct semid_ds *buf; unsigned short *array; }; #define HAVE_UNION_SEMUN #endif typedef struct DAL_SHM_SEGHEAD_STRUCT DAL_SHM_SEGHEAD; struct DAL_SHM_SEGHEAD_STRUCT { int ID; /* ID for debugging */ int h; /* handle of sh. mem */ int size; /* size of data area */ int nodeidx; /* offset of root object (node struct typically) */ }; /* API routines */ #ifdef __cplusplus extern "C" { #endif void shared_cleanup(void); /* must be called at exit/abort */ int shared_init(int debug_msgs); /* must be called before any other shared memory routine */ int shared_recover(int id); /* try to recover dormant segment(s) after applic crash */ int shared_malloc(long size, int mode, int newhandle); /* allocate n-bytes of shared memory */ int shared_attach(int idx); /* attach to segment given index to table */ int shared_free(int idx); /* release shared memory */ SHARED_P shared_lock(int idx, int mode); /* lock segment for reading */ SHARED_P shared_realloc(int idx, long newsize); /* reallocate n-bytes of shared memory (ON LOCKED SEGMENT ONLY) */ int shared_size(int idx); /* get size of attached shared memory segment (ON LOCKED SEGMENT ONLY) */ int shared_attr(int idx); /* get attributes of attached shared memory segment (ON LOCKED SEGMENT ONLY) */ int shared_set_attr(int idx, int newattr); /* set attributes of attached shared memory segment (ON LOCKED SEGMENT ONLY) */ int shared_unlock(int idx); /* unlock segment (ON LOCKED SEGMENT ONLY) */ int shared_set_debug(int debug_msgs); /* set/reset debug mode */ int shared_set_createmode(int mode); /* set/reset debug mode */ int shared_list(int id); /* list segment(s) */ int shared_uncond_delete(int id); /* uncondintionally delete (NOWAIT operation) segment(s) */ int shared_getaddr(int id, char **address); /* get starting address of FITS file in segment */ int smem_init(void); int smem_shutdown(void); int smem_setoptions(int options); int smem_getoptions(int *options); int smem_getversion(int *version); int smem_open(char *filename, int rwmode, int *driverhandle); int smem_create(char *filename, int *driverhandle); int smem_close(int driverhandle); int smem_remove(char *filename); int smem_size(int driverhandle, LONGLONG *size); int smem_flush(int driverhandle); int smem_seek(int driverhandle, LONGLONG offset); int smem_read(int driverhandle, void *buffer, long nbytes); int smem_write(int driverhandle, void *buffer, long nbytes); #ifdef __cplusplus } #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/editcol.c0000644000175100001710000030665700000000000017733 0ustar00vstsdocker/* This file, editcol.c, contains the set of FITSIO routines that */ /* insert or delete rows or columns in a table or resize an image */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffrsim(fitsfile *fptr, /* I - FITS file pointer */ int bitpix, /* I - bits per pixel */ int naxis, /* I - number of axes in the array */ long *naxes, /* I - size of each axis */ int *status) /* IO - error status */ /* resize an existing primary array or IMAGE extension. */ { LONGLONG tnaxes[99]; int ii; if (*status > 0) return(*status); for (ii = 0; (ii < naxis) && (ii < 99); ii++) tnaxes[ii] = naxes[ii]; ffrsimll(fptr, bitpix, naxis, tnaxes, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffrsimll(fitsfile *fptr, /* I - FITS file pointer */ int bitpix, /* I - bits per pixel */ int naxis, /* I - number of axes in the array */ LONGLONG *naxes, /* I - size of each axis */ int *status) /* IO - error status */ /* resize an existing primary array or IMAGE extension. */ { int ii, simple, obitpix, onaxis, extend, nmodify; long nblocks, longval; long pcount, gcount, longbitpix; LONGLONG onaxes[99], newsize, oldsize; char comment[FLEN_COMMENT], keyname[FLEN_KEYWORD], message[FLEN_ERRMSG]; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); /* get current image size parameters */ if (ffghprll(fptr, 99, &simple, &obitpix, &onaxis, onaxes, &pcount, &gcount, &extend, status) > 0) return(*status); longbitpix = bitpix; /* test for the 2 special cases that represent unsigned integers */ if (longbitpix == USHORT_IMG) longbitpix = SHORT_IMG; else if (longbitpix == ULONG_IMG) longbitpix = LONG_IMG; /* test that the new values are legal */ if (longbitpix != BYTE_IMG && longbitpix != SHORT_IMG && longbitpix != LONG_IMG && longbitpix != LONGLONG_IMG && longbitpix != FLOAT_IMG && longbitpix != DOUBLE_IMG) { snprintf(message, FLEN_ERRMSG, "Illegal value for BITPIX keyword: %d", bitpix); ffpmsg(message); return(*status = BAD_BITPIX); } if (naxis < 0 || naxis > 999) { snprintf(message, FLEN_ERRMSG, "Illegal value for NAXIS keyword: %d", naxis); ffpmsg(message); return(*status = BAD_NAXIS); } if (naxis == 0) newsize = 0; else newsize = 1; for (ii = 0; ii < naxis; ii++) { if (naxes[ii] < 0) { snprintf(message, FLEN_ERRMSG, "Illegal value for NAXIS%d keyword: %.0f", ii + 1, (double) (naxes[ii])); ffpmsg(message); return(*status = BAD_NAXES); } newsize *= naxes[ii]; /* compute new image size, in pixels */ } /* compute size of old image, in bytes */ if (onaxis == 0) oldsize = 0; else { oldsize = 1; for (ii = 0; ii < onaxis; ii++) oldsize *= onaxes[ii]; oldsize = (oldsize + pcount) * gcount * (abs(obitpix) / 8); } oldsize = (oldsize + 2879) / 2880; /* old size, in blocks */ newsize = (newsize + pcount) * gcount * (abs(longbitpix) / 8); newsize = (newsize + 2879) / 2880; /* new size, in blocks */ if (newsize > oldsize) /* have to insert new blocks for image */ { nblocks = (long) (newsize - oldsize); if (ffiblk(fptr, nblocks, 1, status) > 0) return(*status); } else if (oldsize > newsize) /* have to delete blocks from image */ { nblocks = (long) (oldsize - newsize); if (ffdblk(fptr, nblocks, status) > 0) return(*status); } /* now update the header keywords */ strcpy(comment,"&"); /* special value to leave comments unchanged */ if (longbitpix != obitpix) { /* update BITPIX value */ ffmkyj(fptr, "BITPIX", longbitpix, comment, status); } if (naxis != onaxis) { /* update NAXIS value */ longval = naxis; ffmkyj(fptr, "NAXIS", longval, comment, status); } /* modify the existing NAXISn keywords */ nmodify = minvalue(naxis, onaxis); for (ii = 0; ii < nmodify; ii++) { ffkeyn("NAXIS", ii+1, keyname, status); ffmkyj(fptr, keyname, naxes[ii], comment, status); } if (naxis > onaxis) /* insert additional NAXISn keywords */ { strcpy(comment,"length of data axis"); for (ii = onaxis; ii < naxis; ii++) { ffkeyn("NAXIS", ii+1, keyname, status); ffikyj(fptr, keyname, naxes[ii], comment, status); } } else if (onaxis > naxis) /* delete old NAXISn keywords */ { for (ii = naxis; ii < onaxis; ii++) { ffkeyn("NAXIS", ii+1, keyname, status); ffdkey(fptr, keyname, status); } } /* Update the BSCALE and BZERO keywords, if an unsigned integer image */ if (bitpix == USHORT_IMG) { strcpy(comment, "offset data range to that of unsigned short"); ffukyg(fptr, "BZERO", 32768., 0, comment, status); strcpy(comment, "default scaling factor"); ffukyg(fptr, "BSCALE", 1.0, 0, comment, status); } else if (bitpix == ULONG_IMG) { strcpy(comment, "offset data range to that of unsigned long"); ffukyg(fptr, "BZERO", 2147483648., 0, comment, status); strcpy(comment, "default scaling factor"); ffukyg(fptr, "BSCALE", 1.0, 0, comment, status); } /* re-read the header, to make sure structures are updated */ ffrdef(fptr, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffirow(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG firstrow, /* I - insert space AFTER this row */ /* 0 = insert space at beginning of table */ LONGLONG nrows, /* I - number of rows to insert */ int *status) /* IO - error status */ /* insert NROWS blank rows immediated after row firstrow (1 = first row). Set firstrow = 0 to insert space at the beginning of the table. */ { int tstatus; LONGLONG naxis1, naxis2; LONGLONG datasize, firstbyte, nshift, nbytes; LONGLONG freespace; long nblock; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffpmsg("Can only add rows to TABLE or BINTABLE extension (ffirow)"); return(*status = NOT_TABLE); } if (nrows < 0 ) return(*status = NEG_BYTES); else if (nrows == 0) return(*status); /* no op, so just return */ /* get the current size of the table */ /* use internal structure since NAXIS2 keyword may not be up to date */ naxis1 = (fptr->Fptr)->rowlength; naxis2 = (fptr->Fptr)->numrows; if (firstrow > naxis2) { ffpmsg( "Insert position greater than the number of rows in the table (ffirow)"); return(*status = BAD_ROW_NUM); } else if (firstrow < 0) { ffpmsg("Insert position is less than 0 (ffirow)"); return(*status = BAD_ROW_NUM); } /* current data size */ datasize = (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; freespace = ( ( (datasize + 2879) / 2880) * 2880) - datasize; nshift = naxis1 * nrows; /* no. of bytes to add to table */ if ( (freespace - nshift) < 0) /* not enough existing space? */ { nblock = (long) ((nshift - freespace + 2879) / 2880); /* number of blocks */ ffiblk(fptr, nblock, 1, status); /* insert the blocks */ } firstbyte = naxis1 * firstrow; /* relative insert position */ nbytes = datasize - firstbyte; /* no. of bytes to shift down */ firstbyte += ((fptr->Fptr)->datastart); /* absolute insert position */ ffshft(fptr, firstbyte, nbytes, nshift, status); /* shift rows and heap */ /* update the heap starting address */ (fptr->Fptr)->heapstart += nshift; /* update the THEAP keyword if it exists */ tstatus = 0; ffmkyj(fptr, "THEAP", (fptr->Fptr)->heapstart, "&", &tstatus); /* update the NAXIS2 keyword */ ffmkyj(fptr, "NAXIS2", naxis2 + nrows, "&", status); ((fptr->Fptr)->numrows) += nrows; ((fptr->Fptr)->origrows) += nrows; return(*status); } /*--------------------------------------------------------------------------*/ int ffdrow(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG firstrow, /* I - first row to delete (1 = first) */ LONGLONG nrows, /* I - number of rows to delete */ int *status) /* IO - error status */ /* delete NROWS rows from table starting with firstrow (1 = first row of table). */ { int tstatus; LONGLONG naxis1, naxis2; LONGLONG datasize, firstbyte, nbytes, nshift; LONGLONG freespace; long nblock; char comm[FLEN_COMMENT]; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffpmsg("Can only delete rows in TABLE or BINTABLE extension (ffdrow)"); return(*status = NOT_TABLE); } if (nrows < 0 ) return(*status = NEG_BYTES); else if (nrows == 0) return(*status); /* no op, so just return */ ffgkyjj(fptr, "NAXIS1", &naxis1, comm, status); /* get the current */ /* ffgkyj(fptr, "NAXIS2", &naxis2, comm, status);*/ /* size of the table */ /* the NAXIS2 keyword may not be up to date, so use the structure value */ naxis2 = (fptr->Fptr)->numrows; if (firstrow > naxis2) { ffpmsg( "Delete position greater than the number of rows in the table (ffdrow)"); return(*status = BAD_ROW_NUM); } else if (firstrow < 1) { ffpmsg("Delete position is less than 1 (ffdrow)"); return(*status = BAD_ROW_NUM); } else if (firstrow + nrows - 1 > naxis2) { ffpmsg("No. of rows to delete exceeds size of table (ffdrow)"); return(*status = BAD_ROW_NUM); } nshift = naxis1 * nrows; /* no. of bytes to delete from table */ /* cur size of data */ datasize = (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; firstbyte = naxis1 * (firstrow + nrows - 1); /* relative del pos */ nbytes = datasize - firstbyte; /* no. of bytes to shift up */ firstbyte += ((fptr->Fptr)->datastart); /* absolute delete position */ ffshft(fptr, firstbyte, nbytes, nshift * (-1), status); /* shift data */ freespace = ( ( (datasize + 2879) / 2880) * 2880) - datasize; nblock = (long) ((nshift + freespace) / 2880); /* number of blocks */ /* delete integral number blocks */ if (nblock > 0) ffdblk(fptr, nblock, status); /* update the heap starting address */ (fptr->Fptr)->heapstart -= nshift; /* update the THEAP keyword if it exists */ tstatus = 0; ffmkyj(fptr, "THEAP", (long)(fptr->Fptr)->heapstart, "&", &tstatus); /* update the NAXIS2 keyword */ ffmkyj(fptr, "NAXIS2", naxis2 - nrows, "&", status); ((fptr->Fptr)->numrows) -= nrows; ((fptr->Fptr)->origrows) -= nrows; /* Update the heap data, if any. This will remove any orphaned data */ /* that was only pointed to by the rows that have been deleted */ ffcmph(fptr, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffdrrg(fitsfile *fptr, /* I - FITS file pointer to table */ char *ranges, /* I - ranges of rows to delete (1 = first) */ int *status) /* IO - error status */ /* delete the ranges of rows from the table (1 = first row of table). The 'ranges' parameter typically looks like: '10-20, 30 - 40, 55' or '50-' and gives a list of rows or row ranges separated by commas. */ { char *cptr; int nranges, nranges2, ii; long *minrow, *maxrow, nrows, *rowarray, jj, kk; LONGLONG naxis2; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffpmsg("Can only delete rows in TABLE or BINTABLE extension (ffdrrg)"); return(*status = NOT_TABLE); } /* the NAXIS2 keyword may not be up to date, so use the structure value */ naxis2 = (fptr->Fptr)->numrows; /* find how many ranges were specified ( = no. of commas in string + 1) */ cptr = ranges; for (nranges = 1; (cptr = strchr(cptr, ',')); nranges++) cptr++; minrow = calloc(nranges, sizeof(long)); maxrow = calloc(nranges, sizeof(long)); if (!minrow || !maxrow) { *status = MEMORY_ALLOCATION; ffpmsg("failed to allocate memory for row ranges (ffdrrg)"); if (maxrow) free(maxrow); if (minrow) free(minrow); return(*status); } /* parse range list into array of range min and max values */ ffrwrg(ranges, naxis2, nranges, &nranges2, minrow, maxrow, status); if (*status > 0 || nranges2 == 0) { free(maxrow); free(minrow); return(*status); } /* determine total number or rows to delete */ nrows = 0; for (ii = 0; ii < nranges2; ii++) { nrows = nrows + maxrow[ii] - minrow[ii] + 1; } rowarray = calloc(nrows, sizeof(long)); if (!rowarray) { *status = MEMORY_ALLOCATION; ffpmsg("failed to allocate memory for row array (ffdrrg)"); return(*status); } for (kk = 0, ii = 0; ii < nranges2; ii++) { for (jj = minrow[ii]; jj <= maxrow[ii]; jj++) { rowarray[kk] = jj; kk++; } } /* delete the rows */ ffdrws(fptr, rowarray, nrows, status); free(rowarray); free(maxrow); free(minrow); return(*status); } /*--------------------------------------------------------------------------*/ int ffdrws(fitsfile *fptr, /* I - FITS file pointer */ long *rownum, /* I - list of rows to delete (1 = first) */ long nrows, /* I - number of rows to delete */ int *status) /* IO - error status */ /* delete the list of rows from the table (1 = first row of table). */ { LONGLONG naxis1, naxis2, insertpos, nextrowpos; long ii, nextrow; char comm[FLEN_COMMENT]; unsigned char *buffer; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffpmsg("Can only delete rows in TABLE or BINTABLE extension (ffdrws)"); return(*status = NOT_TABLE); } if (nrows < 0 ) return(*status = NEG_BYTES); else if (nrows == 0) return(*status); /* no op, so just return */ ffgkyjj(fptr, "NAXIS1", &naxis1, comm, status); /* row width */ ffgkyjj(fptr, "NAXIS2", &naxis2, comm, status); /* number of rows */ /* check that input row list is in ascending order */ for (ii = 1; ii < nrows; ii++) { if (rownum[ii - 1] >= rownum[ii]) { ffpmsg("row numbers are not in increasing order (ffdrws)"); return(*status = BAD_ROW_NUM); } } if (rownum[0] < 1) { ffpmsg("first row to delete is less than 1 (ffdrws)"); return(*status = BAD_ROW_NUM); } else if (rownum[nrows - 1] > naxis2) { ffpmsg("last row to delete exceeds size of table (ffdrws)"); return(*status = BAD_ROW_NUM); } buffer = (unsigned char *) malloc( (size_t) naxis1); /* buffer for one row */ if (!buffer) { ffpmsg("malloc failed (ffdrws)"); return(*status = MEMORY_ALLOCATION); } /* byte location to start of first row to delete, and the next row */ insertpos = (fptr->Fptr)->datastart + ((rownum[0] - 1) * naxis1); nextrowpos = insertpos + naxis1; nextrow = rownum[0] + 1; /* work through the list of rows to delete */ for (ii = 1; ii < nrows; nextrow++, nextrowpos += naxis1) { if (nextrow < rownum[ii]) { /* keep this row, so copy it to the new position */ ffmbyt(fptr, nextrowpos, REPORT_EOF, status); ffgbyt(fptr, naxis1, buffer, status); /* read the bytes */ ffmbyt(fptr, insertpos, IGNORE_EOF, status); ffpbyt(fptr, naxis1, buffer, status); /* write the bytes */ if (*status > 0) { ffpmsg("error while copying good rows in table (ffdrws)"); free(buffer); return(*status); } insertpos += naxis1; } else { /* skip over this row since it is in the list */ ii++; } } /* finished with all the rows to delete; copy remaining rows */ while(nextrow <= naxis2) { ffmbyt(fptr, nextrowpos, REPORT_EOF, status); ffgbyt(fptr, naxis1, buffer, status); /* read the bytes */ ffmbyt(fptr, insertpos, IGNORE_EOF, status); ffpbyt(fptr, naxis1, buffer, status); /* write the bytes */ if (*status > 0) { ffpmsg("failed to copy remaining rows in table (ffdrws)"); free(buffer); return(*status); } insertpos += naxis1; nextrowpos += naxis1; nextrow++; } free(buffer); /* now delete the empty rows at the end of the table */ ffdrow(fptr, naxis2 - nrows + 1, nrows, status); /* Update the heap data, if any. This will remove any orphaned data */ /* that was only pointed to by the rows that have been deleted */ ffcmph(fptr, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffdrwsll(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG *rownum, /* I - list of rows to delete (1 = first) */ LONGLONG nrows, /* I - number of rows to delete */ int *status) /* IO - error status */ /* delete the list of rows from the table (1 = first row of table). */ { LONGLONG insertpos, nextrowpos; LONGLONG naxis1, naxis2, ii, nextrow; char comm[FLEN_COMMENT]; unsigned char *buffer; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffpmsg("Can only delete rows in TABLE or BINTABLE extension (ffdrws)"); return(*status = NOT_TABLE); } if (nrows < 0 ) return(*status = NEG_BYTES); else if (nrows == 0) return(*status); /* no op, so just return */ ffgkyjj(fptr, "NAXIS1", &naxis1, comm, status); /* row width */ ffgkyjj(fptr, "NAXIS2", &naxis2, comm, status); /* number of rows */ /* check that input row list is in ascending order */ for (ii = 1; ii < nrows; ii++) { if (rownum[ii - 1] >= rownum[ii]) { ffpmsg("row numbers are not in increasing order (ffdrws)"); return(*status = BAD_ROW_NUM); } } if (rownum[0] < 1) { ffpmsg("first row to delete is less than 1 (ffdrws)"); return(*status = BAD_ROW_NUM); } else if (rownum[nrows - 1] > naxis2) { ffpmsg("last row to delete exceeds size of table (ffdrws)"); return(*status = BAD_ROW_NUM); } buffer = (unsigned char *) malloc( (size_t) naxis1); /* buffer for one row */ if (!buffer) { ffpmsg("malloc failed (ffdrwsll)"); return(*status = MEMORY_ALLOCATION); } /* byte location to start of first row to delete, and the next row */ insertpos = (fptr->Fptr)->datastart + ((rownum[0] - 1) * naxis1); nextrowpos = insertpos + naxis1; nextrow = rownum[0] + 1; /* work through the list of rows to delete */ for (ii = 1; ii < nrows; nextrow++, nextrowpos += naxis1) { if (nextrow < rownum[ii]) { /* keep this row, so copy it to the new position */ ffmbyt(fptr, nextrowpos, REPORT_EOF, status); ffgbyt(fptr, naxis1, buffer, status); /* read the bytes */ ffmbyt(fptr, insertpos, IGNORE_EOF, status); ffpbyt(fptr, naxis1, buffer, status); /* write the bytes */ if (*status > 0) { ffpmsg("error while copying good rows in table (ffdrws)"); free(buffer); return(*status); } insertpos += naxis1; } else { /* skip over this row since it is in the list */ ii++; } } /* finished with all the rows to delete; copy remaining rows */ while(nextrow <= naxis2) { ffmbyt(fptr, nextrowpos, REPORT_EOF, status); ffgbyt(fptr, naxis1, buffer, status); /* read the bytes */ ffmbyt(fptr, insertpos, IGNORE_EOF, status); ffpbyt(fptr, naxis1, buffer, status); /* write the bytes */ if (*status > 0) { ffpmsg("failed to copy remaining rows in table (ffdrws)"); free(buffer); return(*status); } insertpos += naxis1; nextrowpos += naxis1; nextrow++; } free(buffer); /* now delete the empty rows at the end of the table */ ffdrow(fptr, naxis2 - nrows + 1, nrows, status); /* Update the heap data, if any. This will remove any orphaned data */ /* that was only pointed to by the rows that have been deleted */ ffcmph(fptr, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffrwrg( char *rowlist, /* I - list of rows and row ranges */ LONGLONG maxrows, /* I - number of rows in the table */ int maxranges, /* I - max number of ranges to be returned */ int *numranges, /* O - number ranges returned */ long *minrow, /* O - first row in each range */ long *maxrow, /* O - last row in each range */ int *status) /* IO - status value */ { /* parse the input list of row ranges, returning the number of ranges, and the min and max row value in each range. The only characters allowed in the input rowlist are decimal digits, minus sign, and comma (and non-significant spaces) Example: list = "10-20, 30-35,50" would return numranges = 3, minrow[] = {10, 30, 50}, maxrow[] = {20, 35, 50} error is returned if min value of range is > max value of range or if the ranges are not monotonically increasing. */ char *next; long minval, maxval; if (*status > 0) return(*status); if (maxrows <= 0 ) { *status = RANGE_PARSE_ERROR; ffpmsg("Input maximum range value is <= 0 (fits_parse_ranges)"); return(*status); } next = rowlist; *numranges = 0; while (*next == ' ')next++; /* skip spaces */ while (*next != '\0') { /* find min value of next range; *next must be '-' or a digit */ if (*next == '-') { minval = 1; /* implied minrow value = 1 */ } else if ( isdigit((int) *next) ) { minval = strtol(next, &next, 10); } else { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list:"); ffpmsg(rowlist); return(*status); } while (*next == ' ')next++; /* skip spaces */ /* find max value of next range; *next must be '-', or ',' */ if (*next == '-') { next++; while (*next == ' ')next++; /* skip spaces */ if ( isdigit((int) *next) ) { maxval = strtol(next, &next, 10); } else if (*next == ',' || *next == '\0') { maxval = (long) maxrows; /* implied max value */ } else { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list:"); ffpmsg(rowlist); return(*status); } } else if (*next == ',' || *next == '\0') { maxval = minval; /* only a single integer in this range */ } else { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list:"); ffpmsg(rowlist); return(*status); } if (*numranges + 1 > maxranges) { *status = RANGE_PARSE_ERROR; ffpmsg("Overflowed maximum number of ranges (fits_parse_ranges)"); return(*status); } if (minval < 1 ) { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list: row number < 1"); ffpmsg(rowlist); return(*status); } if (maxval < minval) { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list: min > max"); ffpmsg(rowlist); return(*status); } if (*numranges > 0) { if (minval <= maxrow[(*numranges) - 1]) { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list. Range minimum is"); ffpmsg(" less than or equal to previous range maximum"); ffpmsg(rowlist); return(*status); } } if (minval <= maxrows) { /* ignore range if greater than maxrows */ if (maxval > maxrows) maxval = (long) maxrows; minrow[*numranges] = minval; maxrow[*numranges] = maxval; (*numranges)++; } while (*next == ' ')next++; /* skip spaces */ if (*next == ',') { next++; while (*next == ' ')next++; /* skip more spaces */ } } if (*numranges == 0) { /* a null string was entered */ minrow[0] = 1; maxrow[0] = (long) maxrows; *numranges = 1; } return(*status); } /*--------------------------------------------------------------------------*/ int ffrwrgll( char *rowlist, /* I - list of rows and row ranges */ LONGLONG maxrows, /* I - number of rows in the list */ int maxranges, /* I - max number of ranges to be returned */ int *numranges, /* O - number ranges returned */ LONGLONG *minrow, /* O - first row in each range */ LONGLONG *maxrow, /* O - last row in each range */ int *status) /* IO - status value */ { /* parse the input list of row ranges, returning the number of ranges, and the min and max row value in each range. The only characters allowed in the input rowlist are decimal digits, minus sign, and comma (and non-significant spaces) Example: list = "10-20, 30-35,50" would return numranges = 3, minrow[] = {10, 30, 50}, maxrow[] = {20, 35, 50} error is returned if min value of range is > max value of range or if the ranges are not monotonically increasing. */ char *next; LONGLONG minval, maxval; double dvalue; if (*status > 0) return(*status); if (maxrows <= 0 ) { *status = RANGE_PARSE_ERROR; ffpmsg("Input maximum range value is <= 0 (fits_parse_ranges)"); return(*status); } next = rowlist; *numranges = 0; while (*next == ' ')next++; /* skip spaces */ while (*next != '\0') { /* find min value of next range; *next must be '-' or a digit */ if (*next == '-') { minval = 1; /* implied minrow value = 1 */ } else if ( isdigit((int) *next) ) { /* read as a double, because the string to LONGLONG function */ /* is platform dependent (strtoll, strtol, _atoI64) */ dvalue = strtod(next, &next); minval = (LONGLONG) (dvalue + 0.1); } else { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list:"); ffpmsg(rowlist); return(*status); } while (*next == ' ')next++; /* skip spaces */ /* find max value of next range; *next must be '-', or ',' */ if (*next == '-') { next++; while (*next == ' ')next++; /* skip spaces */ if ( isdigit((int) *next) ) { /* read as a double, because the string to LONGLONG function */ /* is platform dependent (strtoll, strtol, _atoI64) */ dvalue = strtod(next, &next); maxval = (LONGLONG) (dvalue + 0.1); } else if (*next == ',' || *next == '\0') { maxval = maxrows; /* implied max value */ } else { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list:"); ffpmsg(rowlist); return(*status); } } else if (*next == ',' || *next == '\0') { maxval = minval; /* only a single integer in this range */ } else { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list:"); ffpmsg(rowlist); return(*status); } if (*numranges + 1 > maxranges) { *status = RANGE_PARSE_ERROR; ffpmsg("Overflowed maximum number of ranges (fits_parse_ranges)"); return(*status); } if (minval < 1 ) { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list: row number < 1"); ffpmsg(rowlist); return(*status); } if (maxval < minval) { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list: min > max"); ffpmsg(rowlist); return(*status); } if (*numranges > 0) { if (minval <= maxrow[(*numranges) - 1]) { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list. Range minimum is"); ffpmsg(" less than or equal to previous range maximum"); ffpmsg(rowlist); return(*status); } } if (minval <= maxrows) { /* ignore range if greater than maxrows */ if (maxval > maxrows) maxval = maxrows; minrow[*numranges] = minval; maxrow[*numranges] = maxval; (*numranges)++; } while (*next == ' ')next++; /* skip spaces */ if (*next == ',') { next++; while (*next == ' ')next++; /* skip more spaces */ } } if (*numranges == 0) { /* a null string was entered */ minrow[0] = 1; maxrow[0] = maxrows; *numranges = 1; } return(*status); } /*--------------------------------------------------------------------------*/ int fficol(fitsfile *fptr, /* I - FITS file pointer */ int numcol, /* I - position for new col. (1 = 1st) */ char *ttype, /* I - name of column (TTYPE keyword) */ char *tform, /* I - format of column (TFORM keyword) */ int *status) /* IO - error status */ /* Insert a new column into an existing table at position numcol. If numcol is greater than the number of existing columns in the table then the new column will be appended as the last column in the table. */ { char *name, *format; name = ttype; format = tform; fficls(fptr, numcol, 1, &name, &format, status); return(*status); } /*--------------------------------------------------------------------------*/ int fficls(fitsfile *fptr, /* I - FITS file pointer */ int fstcol, /* I - position for first new col. (1 = 1st) */ int ncols, /* I - number of columns to insert */ char **ttype, /* I - array of column names(TTYPE keywords) */ char **tform, /* I - array of formats of column (TFORM) */ int *status) /* IO - error status */ /* Insert 1 or more new columns into an existing table at position numcol. If fstcol is greater than the number of existing columns in the table then the new column will be appended as the last column in the table. */ { int colnum, datacode, decims, tfields, tstatus, ii; LONGLONG datasize, firstbyte, nbytes, nadd, naxis1, naxis2, freespace; LONGLONG tbcol, firstcol, delbyte; long nblock, width, repeat; char tfm[FLEN_VALUE], keyname[FLEN_KEYWORD], comm[FLEN_COMMENT], *cptr; tcolumn *colptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffpmsg("Can only add columns to TABLE or BINTABLE extension (fficls)"); return(*status = NOT_TABLE); } /* is the column number valid? */ tfields = (fptr->Fptr)->tfield; if (fstcol < 1 ) return(*status = BAD_COL_NUM); else if (fstcol > tfields) colnum = tfields + 1; /* append as last column */ else colnum = fstcol; /* parse the tform value and calc number of bytes to add to each row */ delbyte = 0; for (ii = 0; ii < ncols; ii++) { if (strlen(tform[ii]) > FLEN_VALUE-1) { ffpmsg("Column format string too long (fficls)"); return (*status=BAD_TFORM); } strcpy(tfm, tform[ii]); ffupch(tfm); /* make sure format is in upper case */ if ((fptr->Fptr)->hdutype == ASCII_TBL) { ffasfm(tfm, &datacode, &width, &decims, status); delbyte += width + 1; /* add one space between the columns */ } else { ffbnfm(tfm, &datacode, &repeat, &width, status); if (datacode < 0) { /* variable length array column */ if (strchr(tfm, 'Q')) delbyte += 16; else delbyte += 8; } else if (datacode == 1) /* bit column; round up */ delbyte += (repeat + 7) / 8; /* to multiple of 8 bits */ else if (datacode == 16) /* ASCII string column */ delbyte += repeat; else /* numerical data type */ delbyte += (datacode / 10) * repeat; } } if (*status > 0) return(*status); /* get the current size of the table */ /* use internal structure since NAXIS2 keyword may not be up to date */ naxis1 = (fptr->Fptr)->rowlength; naxis2 = (fptr->Fptr)->numrows; /* current size of data */ datasize = (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; freespace = ( ( (datasize + 2879) / 2880) * 2880) - datasize; nadd = delbyte * naxis2; /* no. of bytes to add to table */ if ( (freespace - nadd) < 0) /* not enough existing space? */ { nblock = (long) ((nadd - freespace + 2879) / 2880); /* number of blocks */ if (ffiblk(fptr, nblock, 1, status) > 0) /* insert the blocks */ return(*status); } /* shift heap down (if it exists) */ if ((fptr->Fptr)->heapsize > 0) { nbytes = (fptr->Fptr)->heapsize; /* no. of bytes to shift down */ /* absolute heap pos */ firstbyte = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart; if (ffshft(fptr, firstbyte, nbytes, nadd, status) > 0) /* move heap */ return(*status); } /* update the heap starting address */ (fptr->Fptr)->heapstart += nadd; /* update the THEAP keyword if it exists */ tstatus = 0; ffmkyj(fptr, "THEAP", (fptr->Fptr)->heapstart, "&", &tstatus); /* calculate byte position in the row where to insert the new column */ if (colnum > tfields) firstcol = naxis1; else { colptr = (fptr->Fptr)->tableptr; colptr += (colnum - 1); firstcol = colptr->tbcol; } /* insert delbyte bytes in every row, at byte position firstcol */ ffcins(fptr, naxis1, naxis2, delbyte, firstcol, status); if ((fptr->Fptr)->hdutype == ASCII_TBL) { /* adjust the TBCOL values of the existing columns */ for(ii = 0; ii < tfields; ii++) { ffkeyn("TBCOL", ii + 1, keyname, status); ffgkyjj(fptr, keyname, &tbcol, comm, status); if (tbcol > firstcol) { tbcol += delbyte; ffmkyj(fptr, keyname, tbcol, "&", status); } } } /* update the mandatory keywords */ ffmkyj(fptr, "TFIELDS", tfields + ncols, "&", status); ffmkyj(fptr, "NAXIS1", naxis1 + delbyte, "&", status); /* increment the index value on any existing column keywords */ if(colnum <= tfields) ffkshf(fptr, colnum, tfields, ncols, status); /* add the required keywords for the new columns */ for (ii = 0; ii < ncols; ii++, colnum++) { strcpy(comm, "label for field"); ffkeyn("TTYPE", colnum, keyname, status); ffpkys(fptr, keyname, ttype[ii], comm, status); strcpy(comm, "format of field"); strcpy(tfm, tform[ii]); ffupch(tfm); /* make sure format is in upper case */ ffkeyn("TFORM", colnum, keyname, status); if (abs(datacode) == TSBYTE) { /* Replace the 'S' with an 'B' in the TFORMn code */ cptr = tfm; while (*cptr != 'S') cptr++; *cptr = 'B'; ffpkys(fptr, keyname, tfm, comm, status); /* write the TZEROn and TSCALn keywords */ ffkeyn("TZERO", colnum, keyname, status); strcpy(comm, "offset for signed bytes"); ffpkyg(fptr, keyname, -128., 0, comm, status); ffkeyn("TSCAL", colnum, keyname, status); strcpy(comm, "data are not scaled"); ffpkyg(fptr, keyname, 1., 0, comm, status); } else if (abs(datacode) == TUSHORT) { /* Replace the 'U' with an 'I' in the TFORMn code */ cptr = tfm; while (*cptr != 'U') cptr++; *cptr = 'I'; ffpkys(fptr, keyname, tfm, comm, status); /* write the TZEROn and TSCALn keywords */ ffkeyn("TZERO", colnum, keyname, status); strcpy(comm, "offset for unsigned integers"); ffpkyg(fptr, keyname, 32768., 0, comm, status); ffkeyn("TSCAL", colnum, keyname, status); strcpy(comm, "data are not scaled"); ffpkyg(fptr, keyname, 1., 0, comm, status); } else if (abs(datacode) == TULONG) { /* Replace the 'V' with an 'J' in the TFORMn code */ cptr = tfm; while (*cptr != 'V') cptr++; *cptr = 'J'; ffpkys(fptr, keyname, tfm, comm, status); /* write the TZEROn and TSCALn keywords */ ffkeyn("TZERO", colnum, keyname, status); strcpy(comm, "offset for unsigned integers"); ffpkyg(fptr, keyname, 2147483648., 0, comm, status); ffkeyn("TSCAL", colnum, keyname, status); strcpy(comm, "data are not scaled"); ffpkyg(fptr, keyname, 1., 0, comm, status); } else { ffpkys(fptr, keyname, tfm, comm, status); } if ((fptr->Fptr)->hdutype == ASCII_TBL) /* write the TBCOL keyword */ { if (colnum == tfields + 1) tbcol = firstcol + 2; /* allow space between preceding col */ else tbcol = firstcol + 1; strcpy(comm, "beginning column of field"); ffkeyn("TBCOL", colnum, keyname, status); ffpkyj(fptr, keyname, tbcol, comm, status); /* increment the column starting position for the next column */ ffasfm(tfm, &datacode, &width, &decims, status); firstcol += width + 1; /* add one space between the columns */ } } ffrdef(fptr, status); /* initialize the new table structure */ return(*status); } /*--------------------------------------------------------------------------*/ int ffmvec(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - position of col to be modified */ LONGLONG newveclen, /* I - new vector length of column (TFORM) */ int *status) /* IO - error status */ /* Modify the vector length of a column in a binary table, larger or smaller. E.g., change a column from TFORMn = '1E' to '20E'. */ { int datacode, tfields, tstatus; LONGLONG datasize, size, firstbyte, nbytes, nadd, ndelete; LONGLONG naxis1, naxis2, firstcol, freespace; LONGLONG width, delbyte, repeat; long nblock; char tfm[FLEN_VALUE], keyname[FLEN_KEYWORD], tcode[2]; tcolumn *colptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype != BINARY_TBL) { ffpmsg( "Can only change vector length of a column in BINTABLE extension (ffmvec)"); return(*status = NOT_TABLE); } /* is the column number valid? */ tfields = (fptr->Fptr)->tfield; if (colnum < 1 || colnum > tfields) return(*status = BAD_COL_NUM); /* look up the current vector length and element width */ colptr = (fptr->Fptr)->tableptr; colptr += (colnum - 1); datacode = colptr->tdatatype; /* datatype of the column */ repeat = colptr->trepeat; /* field repeat count */ width = colptr->twidth; /* width of a single element in chars */ if (datacode < 0) { ffpmsg( "Can't modify vector length of variable length column (ffmvec)"); return(*status = BAD_TFORM); } if (repeat == newveclen) return(*status); /* column already has the desired vector length */ if (datacode == TSTRING) width = 1; /* width was equal to width of unit string */ naxis1 = (fptr->Fptr)->rowlength; /* current width of the table */ naxis2 = (fptr->Fptr)->numrows; delbyte = (newveclen - repeat) * width; /* no. of bytes to insert */ if (datacode == TBIT) /* BIT column is a special case */ delbyte = ((newveclen + 7) / 8) - ((repeat + 7) / 8); if (delbyte > 0) /* insert space for more elements */ { /* current size of data */ datasize = (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; freespace = ( ( (datasize + 2879) / 2880) * 2880) - datasize; nadd = (LONGLONG)delbyte * naxis2; /* no. of bytes to add to table */ if ( (freespace - nadd) < 0) /* not enough existing space? */ { nblock = (long) ((nadd - freespace + 2879) / 2880); /* number of blocks */ if (ffiblk(fptr, nblock, 1, status) > 0) /* insert the blocks */ return(*status); } /* shift heap down (if it exists) */ if ((fptr->Fptr)->heapsize > 0) { nbytes = (fptr->Fptr)->heapsize; /* no. of bytes to shift down */ /* absolute heap pos */ firstbyte = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart; if (ffshft(fptr, firstbyte, nbytes, nadd, status) > 0) /* move heap */ return(*status); } /* update the heap starting address */ (fptr->Fptr)->heapstart += nadd; /* update the THEAP keyword if it exists */ tstatus = 0; ffmkyj(fptr, "THEAP", (fptr->Fptr)->heapstart, "&", &tstatus); /* Must reset colptr before using it again. (fptr->Fptr)->tableptr may have been reallocated down in ffbinit via the call to ffiblk above.*/ colptr = (fptr->Fptr)->tableptr; colptr += (colnum - 1); firstcol = colptr->tbcol + (repeat * width); /* insert position */ /* insert delbyte bytes in every row, at byte position firstcol */ ffcins(fptr, naxis1, naxis2, delbyte, firstcol, status); } else if (delbyte < 0) { /* current size of table */ size = (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; freespace = ((size + 2879) / 2880) * 2880 - size - ((LONGLONG)delbyte * naxis2); nblock = (long) (freespace / 2880); /* number of empty blocks to delete */ firstcol = colptr->tbcol + (newveclen * width); /* delete position */ /* delete elements from the vector */ ffcdel(fptr, naxis1, naxis2, -delbyte, firstcol, status); /* abs heap pos */ firstbyte = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart; ndelete = (LONGLONG)delbyte * naxis2; /* size of shift (negative) */ /* shift heap up (if it exists) */ if ((fptr->Fptr)->heapsize > 0) { nbytes = (fptr->Fptr)->heapsize; /* no. of bytes to shift up */ if (ffshft(fptr, firstbyte, nbytes, ndelete, status) > 0) return(*status); } /* delete the empty blocks at the end of the HDU */ if (nblock > 0) ffdblk(fptr, nblock, status); /* update the heap starting address */ (fptr->Fptr)->heapstart += ndelete; /* ndelete is negative */ /* update the THEAP keyword if it exists */ tstatus = 0; ffmkyj(fptr, "THEAP", (fptr->Fptr)->heapstart, "&", &tstatus); } /* construct the new TFORM keyword for the column */ if (datacode == TBIT) strcpy(tcode,"X"); else if (datacode == TBYTE) strcpy(tcode,"B"); else if (datacode == TLOGICAL) strcpy(tcode,"L"); else if (datacode == TSTRING) strcpy(tcode,"A"); else if (datacode == TSHORT) strcpy(tcode,"I"); else if (datacode == TLONG) strcpy(tcode,"J"); else if (datacode == TLONGLONG) strcpy(tcode,"K"); else if (datacode == TFLOAT) strcpy(tcode,"E"); else if (datacode == TDOUBLE) strcpy(tcode,"D"); else if (datacode == TCOMPLEX) strcpy(tcode,"C"); else if (datacode == TDBLCOMPLEX) strcpy(tcode,"M"); /* write as a double value because the LONGLONG conversion */ /* character in snprintf is platform dependent ( %lld, %ld, %I64d ) */ snprintf(tfm,FLEN_VALUE,"%.0f%s",(double) newveclen, tcode); ffkeyn("TFORM", colnum, keyname, status); /* Keyword name */ ffmkys(fptr, keyname, tfm, "&", status); /* modify TFORM keyword */ ffmkyj(fptr, "NAXIS1", naxis1 + delbyte, "&", status); /* modify NAXIS1 */ ffrdef(fptr, status); /* reinitialize the new table structure */ return(*status); } /*--------------------------------------------------------------------------*/ int ffcpcl(fitsfile *infptr, /* I - FITS file pointer to input file */ fitsfile *outfptr, /* I - FITS file pointer to output file */ int incol, /* I - number of input column */ int outcol, /* I - number for output column */ int create_col, /* I - create new col if TRUE, else overwrite */ int *status) /* IO - error status */ /* copy a column from infptr and insert it in the outfptr table. */ { int tstatus, colnum, typecode, otypecode, etypecode, anynull; int inHduType, outHduType; long tfields, repeat, orepeat, width, owidth, nrows, outrows; long inloop, outloop, maxloop, ndone, ntodo, npixels; long firstrow, firstelem, ii; char keyname[FLEN_KEYWORD], ttype[FLEN_VALUE], tform[FLEN_VALUE]; char ttype_comm[FLEN_COMMENT],tform_comm[FLEN_COMMENT]; char *lvalues = 0, nullflag, **strarray = 0; char nulstr[] = {'\5', '\0'}; /* unique null string value */ double dnull = 0.l, *dvalues = 0; float fnull = 0., *fvalues = 0; long long int *jjvalues = 0; unsigned long long int *ujjvalues = 0; if (*status > 0) return(*status); if (infptr->HDUposition != (infptr->Fptr)->curhdu) { ffmahd(infptr, (infptr->HDUposition) + 1, NULL, status); } else if ((infptr->Fptr)->datastart == DATA_UNDEFINED) ffrdef(infptr, status); /* rescan header */ inHduType = (infptr->Fptr)->hdutype; if (outfptr->HDUposition != (outfptr->Fptr)->curhdu) { ffmahd(outfptr, (outfptr->HDUposition) + 1, NULL, status); } else if ((outfptr->Fptr)->datastart == DATA_UNDEFINED) ffrdef(outfptr, status); /* rescan header */ outHduType = (outfptr->Fptr)->hdutype; if (*status > 0) return(*status); if (inHduType == IMAGE_HDU || outHduType == IMAGE_HDU) { ffpmsg ("Can not copy columns to or from IMAGE HDUs (ffcpcl)"); return(*status = NOT_TABLE); } if ( inHduType == BINARY_TBL && outHduType == ASCII_TBL) { ffpmsg ("Copying from Binary table to ASCII table is not supported (ffcpcl)"); return(*status = NOT_BTABLE); } /* get the datatype and vector repeat length of the column */ ffgtcl(infptr, incol, &typecode, &repeat, &width, status); /* ... and equivalent type code */ ffeqty(infptr, incol, &etypecode, 0, 0, status); if (typecode < 0) { ffpmsg("Variable-length columns are not supported (ffcpcl)"); return(*status = BAD_TFORM); } if (create_col) /* insert new column in output table? */ { tstatus = 0; ffkeyn("TTYPE", incol, keyname, &tstatus); ffgkys(infptr, keyname, ttype, ttype_comm, &tstatus); ffkeyn("TFORM", incol, keyname, &tstatus); if (ffgkys(infptr, keyname, tform, tform_comm, &tstatus) ) { ffpmsg ("Could not find TTYPE and TFORM keywords in input table (ffcpcl)"); return(*status = NO_TFORM); } if (inHduType == ASCII_TBL && outHduType == BINARY_TBL) { /* convert from ASCII table to BINARY table format string */ if (typecode == TSTRING) ffnkey(width, "A", tform, status); else if (typecode == TLONG) strcpy(tform, "1J"); else if (typecode == TSHORT) strcpy(tform, "1I"); else if (typecode == TFLOAT) strcpy(tform,"1E"); else if (typecode == TDOUBLE) strcpy(tform,"1D"); } if (ffgkyj(outfptr, "TFIELDS", &tfields, 0, &tstatus)) { ffpmsg ("Could not read TFIELDS keyword in output table (ffcpcl)"); return(*status = NO_TFIELDS); } colnum = minvalue((int) tfields + 1, outcol); /* output col. number */ /* create the empty column */ if (fficol(outfptr, colnum, ttype, tform, status) > 0) { ffpmsg ("Could not append new column to output file (ffcpcl)"); return(*status); } if ((infptr->Fptr == outfptr->Fptr) && (infptr->HDUposition == outfptr->HDUposition) && (colnum <= incol)) { incol++; /* the input column has been shifted over */ } /* copy the comment strings from the input file for TTYPE and TFORM */ tstatus = 0; ffkeyn("TTYPE", colnum, keyname, &tstatus); ffmcom(outfptr, keyname, ttype_comm, &tstatus); ffkeyn("TFORM", colnum, keyname, &tstatus); ffmcom(outfptr, keyname, tform_comm, &tstatus); /* copy other column-related keywords if they exist */ ffcpky(infptr, outfptr, incol, colnum, "TUNIT", status); ffcpky(infptr, outfptr, incol, colnum, "TSCAL", status); ffcpky(infptr, outfptr, incol, colnum, "TZERO", status); ffcpky(infptr, outfptr, incol, colnum, "TDISP", status); ffcpky(infptr, outfptr, incol, colnum, "TLMIN", status); ffcpky(infptr, outfptr, incol, colnum, "TLMAX", status); ffcpky(infptr, outfptr, incol, colnum, "TDIM", status); /* WCS keywords */ ffcpky(infptr, outfptr, incol, colnum, "TCTYP", status); ffcpky(infptr, outfptr, incol, colnum, "TCUNI", status); ffcpky(infptr, outfptr, incol, colnum, "TCRVL", status); ffcpky(infptr, outfptr, incol, colnum, "TCRPX", status); ffcpky(infptr, outfptr, incol, colnum, "TCDLT", status); ffcpky(infptr, outfptr, incol, colnum, "TCROT", status); if (inHduType == ASCII_TBL && outHduType == BINARY_TBL) { /* binary tables only have TNULLn keyword for integer columns */ if (typecode == TLONG || typecode == TSHORT) { /* check if null string is defined; replace with integer */ ffkeyn("TNULL", incol, keyname, &tstatus); if (ffgkys(infptr, keyname, ttype, 0, &tstatus) <= 0) { ffkeyn("TNULL", colnum, keyname, &tstatus); if (typecode == TLONG) ffpkyj(outfptr, keyname, -9999999L, "Null value", status); else ffpkyj(outfptr, keyname, -32768L, "Null value", status); } } } else { ffcpky(infptr, outfptr, incol, colnum, "TNULL", status); } /* rescan header to recognize the new keywords */ if (ffrdef(outfptr, status) ) return(*status); } else { colnum = outcol; /* get the datatype and vector repeat length of the output column */ ffgtcl(outfptr, outcol, &otypecode, &orepeat, &owidth, status); if (orepeat != repeat) { ffpmsg("Input and output vector columns must have same length (ffcpcl)"); return(*status = BAD_TFORM); } } ffgkyj(infptr, "NAXIS2", &nrows, 0, status); /* no. of input rows */ ffgkyj(outfptr, "NAXIS2", &outrows, 0, status); /* no. of output rows */ nrows = minvalue(nrows, outrows); if (typecode == TBIT) repeat = (repeat + 7) / 8; /* convert from bits to bytes */ else if (typecode == TSTRING && inHduType == BINARY_TBL) repeat = repeat / width; /* convert from chars to unit strings */ /* get optimum number of rows to copy at one time */ ffgrsz(infptr, &inloop, status); ffgrsz(outfptr, &outloop, status); /* adjust optimum number, since 2 tables are open at once */ maxloop = minvalue(inloop, outloop); /* smallest of the 2 tables */ maxloop = maxvalue(1, maxloop / 2); /* at least 1 row */ maxloop = minvalue(maxloop, nrows); /* max = nrows to be copied */ maxloop *= repeat; /* mult by no of elements in a row */ /* allocate memory for arrays */ if (typecode == TLOGICAL) { lvalues = (char *) calloc(maxloop, sizeof(char) ); if (!lvalues) { ffpmsg ("malloc failed to get memory for logicals (ffcpcl)"); return(*status = ARRAY_TOO_BIG); } } else if (typecode == TSTRING) { /* allocate array of pointers */ strarray = (char **) calloc(maxloop, sizeof(strarray)); /* allocate space for each string */ for (ii = 0; ii < maxloop; ii++) strarray[ii] = (char *) calloc(width+1, sizeof(char)); } else if (typecode == TCOMPLEX) { fvalues = (float *) calloc(maxloop * 2, sizeof(float) ); if (!fvalues) { ffpmsg ("malloc failed to get memory for complex (ffcpcl)"); return(*status = ARRAY_TOO_BIG); } fnull = 0.; } else if (typecode == TDBLCOMPLEX) { dvalues = (double *) calloc(maxloop * 2, sizeof(double) ); if (!dvalues) { ffpmsg ("malloc failed to get memory for dbl complex (ffcpcl)"); return(*status = ARRAY_TOO_BIG); } dnull = 0.; } /* These are unsigned long-long ints that are not rescaled to floating point numbers */ else if (typecode == TLONGLONG && etypecode == TULONGLONG) { ujjvalues = (unsigned long long int *) calloc(maxloop, sizeof(unsigned long long int) ); if (!ujjvalues) { ffpmsg ("malloc failed to get memory for unsigned long long int (ffcpcl)"); return(*status = ARRAY_TOO_BIG); } } /* These are long-long ints that are not rescaled to floating point numbers */ else if (typecode == TLONGLONG && etypecode != TDOUBLE) { jjvalues = (long long int *) calloc(maxloop, sizeof(long long int) ); if (!jjvalues) { ffpmsg ("malloc failed to get memory for long long int (ffcpcl)"); return(*status = ARRAY_TOO_BIG); } } else /* other numerical datatype; read them all as doubles */ { dvalues = (double *) calloc(maxloop, sizeof(double) ); if (!dvalues) { ffpmsg ("malloc failed to get memory for doubles (ffcpcl)"); return(*status = ARRAY_TOO_BIG); } dnull = -9.99991999E31; /* use an unlikely value for nulls */ } npixels = nrows * repeat; /* total no. of pixels to copy */ ntodo = minvalue(npixels, maxloop); /* no. to copy per iteration */ ndone = 0; /* total no. of pixels that have been copied */ while (ntodo) /* iterate through the table */ { firstrow = ndone / repeat + 1; firstelem = ndone - ((firstrow - 1) * repeat) + 1; /* read from input table */ if (typecode == TLOGICAL) ffgcl(infptr, incol, firstrow, firstelem, ntodo, lvalues, status); else if (typecode == TSTRING) ffgcvs(infptr, incol, firstrow, firstelem, ntodo, nulstr, strarray, &anynull, status); else if (typecode == TCOMPLEX) ffgcvc(infptr, incol, firstrow, firstelem, ntodo, fnull, fvalues, &anynull, status); else if (typecode == TDBLCOMPLEX) ffgcvm(infptr, incol, firstrow, firstelem, ntodo, dnull, dvalues, &anynull, status); /* Neither TULONGLONG nor TLONGLONG does null checking. Whatever null value is in input table is transferred to output table without checking. Since the TNULL value was copied, this should preserve null values */ else if (typecode == TLONGLONG && etypecode == TULONGLONG) ffgcvujj(infptr, incol, firstrow, firstelem, ntodo, /*nulval*/ 0, ujjvalues, &anynull, status); else if (typecode == TLONGLONG && etypecode != TDOUBLE) ffgcvjj(infptr, incol, firstrow, firstelem, ntodo, /*nulval*/ 0, jjvalues, &anynull, status); else /* all numerical types */ ffgcvd(infptr, incol, firstrow, firstelem, ntodo, dnull, dvalues, &anynull, status); if (*status > 0) { ffpmsg("Error reading input copy of column (ffcpcl)"); break; } /* write to output table */ if (typecode == TLOGICAL) { nullflag = 2; ffpcnl(outfptr, colnum, firstrow, firstelem, ntodo, lvalues, nullflag, status); } else if (typecode == TSTRING) { if (anynull) ffpcns(outfptr, colnum, firstrow, firstelem, ntodo, strarray, nulstr, status); else ffpcls(outfptr, colnum, firstrow, firstelem, ntodo, strarray, status); } else if (typecode == TCOMPLEX) { /* doesn't support writing nulls */ ffpclc(outfptr, colnum, firstrow, firstelem, ntodo, fvalues, status); } else if (typecode == TDBLCOMPLEX) { /* doesn't support writing nulls */ ffpclm(outfptr, colnum, firstrow, firstelem, ntodo, dvalues, status); } else if (typecode == TLONGLONG && etypecode == TULONGLONG) { /* No null checking because we did none to read */ ffpclujj(outfptr, colnum, firstrow, firstelem, ntodo, ujjvalues, status); } else if (typecode == TLONGLONG && etypecode != TDOUBLE) { /* No null checking because we did none to read */ ffpcljj(outfptr, colnum, firstrow, firstelem, ntodo, jjvalues, status); } else /* all other numerical types */ { if (anynull) ffpcnd(outfptr, colnum, firstrow, firstelem, ntodo, dvalues, dnull, status); else ffpcld(outfptr, colnum, firstrow, firstelem, ntodo, dvalues, status); } if (*status > 0) { ffpmsg("Error writing output copy of column (ffcpcl)"); break; } npixels -= ntodo; ndone += ntodo; ntodo = minvalue(npixels, maxloop); } /* free the previously allocated memory */ if (typecode == TLOGICAL) { free(lvalues); } else if (typecode == TSTRING) { for (ii = 0; ii < maxloop; ii++) free(strarray[ii]); free(strarray); } if (ujjvalues) free(ujjvalues); if (jjvalues) free(jjvalues); if (dvalues) free(dvalues); return(*status); } /*--------------------------------------------------------------------------*/ int ffccls(fitsfile *infptr, /* I - FITS file pointer to input file */ fitsfile *outfptr, /* I - FITS file pointer to output file */ int incol, /* I - number of first input column */ int outcol, /* I - number for first output column */ int ncols, /* I - number of columns to copy from input to output */ int create_col, /* I - create new col if TRUE, else overwrite */ int *status) /* IO - error status */ /* copy multiple columns from infptr and insert them in the outfptr table. Optimized for multiple-column case since it only expands the output file once using fits_insert_cols() instead of calling fits_insert_col() multiple times. */ { int tstatus, colnum, typecode, otypecode, anynull; int inHduType, outHduType; long tfields, repeat, orepeat, width, owidth, nrows, outrows; long inloop, outloop, maxloop, ndone, ntodo, npixels; long firstrow, firstelem, ii; char keyname[FLEN_KEYWORD], ttype[FLEN_VALUE], tform[FLEN_VALUE]; char ttype_comm[FLEN_COMMENT],tform_comm[FLEN_COMMENT]; char *lvalues = 0, nullflag, **strarray = 0; char nulstr[] = {'\5', '\0'}; /* unique null string value */ double dnull = 0.l, *dvalues = 0; float fnull = 0., *fvalues = 0; int typecodes[1000]; char *ttypes[1000], *tforms[1000], keyarr[1001][FLEN_CARD]; int ikey = 0; int icol, incol1, outcol1; if (*status > 0) return(*status); /* Do not allow more than internal array limit to be copied */ if (ncols > 1000) return (*status = ARRAY_TOO_BIG); if (infptr->HDUposition != (infptr->Fptr)->curhdu) { ffmahd(infptr, (infptr->HDUposition) + 1, NULL, status); } else if ((infptr->Fptr)->datastart == DATA_UNDEFINED) ffrdef(infptr, status); /* rescan header */ inHduType = (infptr->Fptr)->hdutype; if (outfptr->HDUposition != (outfptr->Fptr)->curhdu) { ffmahd(outfptr, (outfptr->HDUposition) + 1, NULL, status); } else if ((outfptr->Fptr)->datastart == DATA_UNDEFINED) ffrdef(outfptr, status); /* rescan header */ outHduType = (outfptr->Fptr)->hdutype; if (*status > 0) return(*status); if (inHduType == IMAGE_HDU || outHduType == IMAGE_HDU) { ffpmsg ("Can not copy columns to or from IMAGE HDUs (ffccls)"); return(*status = NOT_TABLE); } if ( (inHduType == BINARY_TBL && outHduType == ASCII_TBL) || (inHduType == ASCII_TBL && outHduType == BINARY_TBL) ) { ffpmsg ("Copying between Binary and ASCII tables is not supported (ffccls)"); return(*status = NOT_BTABLE); } /* Do not allow copying multiple columns in the same HDU because the permutations of possible overlapping copies is mind-bending */ if ((infptr->Fptr == outfptr->Fptr) && (infptr->HDUposition == outfptr->HDUposition)) { ffpmsg ("Copying multiple columns in same HDU is not supported (ffccls)"); return(*status = NOT_BTABLE); } /* Retrieve the number of columns in output file */ tstatus=0; if (ffgkyj(outfptr, "TFIELDS", &tfields, 0, &tstatus)) { ffpmsg ("Could not read TFIELDS keyword in output table (ffccls)"); return(*status = NO_TFIELDS); } colnum = minvalue((int) tfields + 1, outcol); /* output col. number */ /* Collect data about input column (type, repeat, etc) */ for (incol1 = incol, outcol1 = colnum, icol = 0; icol < ncols; icol++, incol1++, outcol1++) { ffgtcl(infptr, incol1, &typecode, &repeat, &width, status); if (typecode < 0) { ffpmsg("Variable-length columns are not supported (ffccls)"); return(*status = BAD_TFORM); } typecodes[icol] = typecode; tstatus = 0; ffkeyn("TTYPE", incol1, keyname, &tstatus); ffgkys(infptr, keyname, ttype, ttype_comm, &tstatus); ffkeyn("TFORM", incol1, keyname, &tstatus); if (ffgkys(infptr, keyname, tform, tform_comm, &tstatus) ) { ffpmsg ("Could not find TTYPE and TFORM keywords in input table (ffccls)"); return(*status = NO_TFORM); } /* If creating columns, we need to save these values */ if ( create_col ) { tforms[icol] = keyarr[ikey++]; ttypes[icol] = keyarr[ikey++]; strcpy(tforms[icol], tform); strcpy(ttypes[icol], ttype); } else { /* If not creating columns, then check the datatype and vector repeat length of the output column */ ffgtcl(outfptr, outcol1, &otypecode, &orepeat, &owidth, status); if (orepeat != repeat) { ffpmsg("Input and output vector columns must have same length (ffccls)"); return(*status = BAD_TFORM); } } } /* Insert columns into output file and copy all meta-data keywords, if requested */ if (create_col) { /* create the empty columns */ if (fficls(outfptr, colnum, ncols, ttypes, tforms, status) > 0) { ffpmsg ("Could not append new columns to output file (ffccls)"); return(*status); } /* Copy meta-data strings from input column to output */ for (incol1 = incol, outcol1 = colnum, icol = 0; icol < ncols; icol++, incol1++, outcol1++) { /* copy the comment strings from the input file for TTYPE and TFORM */ ffkeyn("TTYPE", incol1, keyname, status); ffgkys(infptr, keyname, ttype, ttype_comm, status); ffkeyn("TTYPE", outcol1, keyname, status); ffmcom(outfptr, keyname, ttype_comm, status); ffkeyn("TFORM", incol1, keyname, status); ffgkys(infptr, keyname, tform, tform_comm, status); ffkeyn("TFORM", outcol1, keyname, status); ffmcom(outfptr, keyname, tform_comm, status); /* copy other column-related keywords if they exist */ ffcpky(infptr, outfptr, incol1, outcol1, "TUNIT", status); ffcpky(infptr, outfptr, incol1, outcol1, "TSCAL", status); ffcpky(infptr, outfptr, incol1, outcol1, "TZERO", status); ffcpky(infptr, outfptr, incol1, outcol1, "TDISP", status); ffcpky(infptr, outfptr, incol1, outcol1, "TLMIN", status); ffcpky(infptr, outfptr, incol1, outcol1, "TLMAX", status); ffcpky(infptr, outfptr, incol1, outcol1, "TDIM", status); /* WCS keywords */ ffcpky(infptr, outfptr, incol1, outcol1, "TCTYP", status); ffcpky(infptr, outfptr, incol1, outcol1, "TCUNI", status); ffcpky(infptr, outfptr, incol1, outcol1, "TCRVL", status); ffcpky(infptr, outfptr, incol1, outcol1, "TCRPX", status); ffcpky(infptr, outfptr, incol1, outcol1, "TCDLT", status); ffcpky(infptr, outfptr, incol1, outcol1, "TCROT", status); ffcpky(infptr, outfptr, incol1, outcol1, "TNULL", status); } /* rescan header to recognize the new keywords */ if (ffrdef(outfptr, status) ) return(*status); } /* Copy columns using standard ffcpcl(); do this in a loop because the I/O-intensive column expanding is done */ for (incol1 = incol, outcol1 = colnum, icol = 0; icol < ncols; icol++, incol1++, outcol1++) { ffcpcl(infptr, outfptr, incol1, outcol1, 0, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffcprw(fitsfile *infptr, /* I - FITS file pointer to input file */ fitsfile *outfptr, /* I - FITS file pointer to output file */ LONGLONG firstrow, /* I - number of first row to copy (1 based) */ LONGLONG nrows, /* I - number of rows to copy */ int *status) /* IO - error status */ /* copy consecutive set of rows from infptr and append it in the outfptr table. */ { LONGLONG innaxis1, innaxis2, outnaxis1, outnaxis2, ii, jj, icol; LONGLONG iVarCol, inPos, outPos, nVarBytes, nVarAllocBytes = 0; unsigned char *buffer, *varColBuff=0; int nInVarCols=0, nOutVarCols=0, varColDiff=0; int *inVarCols=0, *outVarCols=0; long nNewBlocks; LONGLONG hrepeat=0, hoffset=0; tcolumn *colptr=0; if (*status > 0) return(*status); if (infptr->HDUposition != (infptr->Fptr)->curhdu) { ffmahd(infptr, (infptr->HDUposition) + 1, NULL, status); } else if ((infptr->Fptr)->datastart == DATA_UNDEFINED) ffrdef(infptr, status); /* rescan header */ if (outfptr->HDUposition != (outfptr->Fptr)->curhdu) { ffmahd(outfptr, (outfptr->HDUposition) + 1, NULL, status); } else if ((outfptr->Fptr)->datastart == DATA_UNDEFINED) ffrdef(outfptr, status); /* rescan header */ if (*status > 0) return(*status); if ((infptr->Fptr)->hdutype == IMAGE_HDU || (outfptr->Fptr)->hdutype == IMAGE_HDU) { ffpmsg ("Can not copy rows to or from IMAGE HDUs (ffcprw)"); return(*status = NOT_TABLE); } if ( ((infptr->Fptr)->hdutype == BINARY_TBL && (outfptr->Fptr)->hdutype == ASCII_TBL) || ((infptr->Fptr)->hdutype == ASCII_TBL && (outfptr->Fptr)->hdutype == BINARY_TBL) ) { ffpmsg ("Copying rows between Binary and ASCII tables is not supported (ffcprw)"); return(*status = NOT_BTABLE); } ffgkyjj(infptr, "NAXIS1", &innaxis1, 0, status); /* width of input rows */ ffgkyjj(infptr, "NAXIS2", &innaxis2, 0, status); /* no. of input rows */ ffgkyjj(outfptr, "NAXIS1", &outnaxis1, 0, status); /* width of output rows */ ffgkyjj(outfptr, "NAXIS2", &outnaxis2, 0, status); /* no. of output rows */ if (*status > 0) return(*status); if (outnaxis1 != innaxis1) { ffpmsg ("Input and output tables do not have same width (ffcprw)"); return(*status = BAD_ROW_WIDTH); } if (firstrow + nrows - 1 > innaxis2) { ffpmsg ("Not enough rows in input table to copy (ffcprw)"); return(*status = BAD_ROW_NUM); } if ((infptr->Fptr)->tfield != (outfptr->Fptr)->tfield) { ffpmsg ("Input and output tables do not have same number of columns (ffcprw)"); return(*status = BAD_COL_NUM); } /* allocate buffer to hold 1 row of data */ buffer = malloc( (size_t) innaxis1); if (!buffer) { ffpmsg ("Unable to allocate memory (ffcprw)"); return(*status = MEMORY_ALLOCATION); } inVarCols = malloc(infptr->Fptr->tfield*sizeof(int)); outVarCols = malloc(outfptr->Fptr->tfield*sizeof(int)); fffvcl(infptr, &nInVarCols, inVarCols, status); fffvcl(outfptr, &nOutVarCols, outVarCols, status); if (nInVarCols != nOutVarCols) varColDiff=1; else { for (ii=0; iiFptr)->tableptr; for (icol=0; icol<(infptr->Fptr)->tfield; ++icol) { if (iVarCol < nInVarCols && inVarCols[iVarCol] == icol+1) { /* Copy from a variable length column */ ffgdesll(infptr, icol+1, ii, &hrepeat, &hoffset, status); /* If this is a bit column, hrepeat will be number of bits, not bytes. If it is a string column, hrepeat is the number of bytes, twidth is the max col width and can be ignored.*/ if (colptr->tdatatype == -TBIT) { nVarBytes = (hrepeat+7)/8; } else if (colptr->tdatatype == -TSTRING) { nVarBytes = hrepeat; } else { nVarBytes = hrepeat*colptr->twidth*sizeof(char); } inPos = (infptr->Fptr)->datastart + (infptr->Fptr)->heapstart + hoffset; outPos = (outfptr->Fptr)->datastart + (outfptr->Fptr)->heapstart + (outfptr->Fptr)->heapsize; ffmbyt(infptr, inPos, REPORT_EOF, status); /* If this is not the last HDU in the file, then check if */ /* extending the heap would overwrite the following header. */ /* If so, then have to insert more blocks. */ if ( !((outfptr->Fptr)->lasthdu) ) { if (outPos+nVarBytes > (outfptr->Fptr)->headstart[(outfptr->Fptr)->curhdu+1]) { nNewBlocks = (long)(((outPos+nVarBytes - 1 - (outfptr->Fptr)->headstart[(outfptr->Fptr)-> curhdu+1]) / 2880) + 1); if (ffiblk(outfptr, nNewBlocks, 1, status) > 0) { ffpmsg("Failed to extend the size of the variable length heap (ffcprw)"); goto CLEANUP_RETURN; } } } if (nVarBytes) { if (nVarBytes > nVarAllocBytes) { /* Grow the copy buffer to accomodate the new maximum size. Note it is safe to call realloc() with null input pointer, which is equivalent to malloc(). */ unsigned char *varColBuff1 = (unsigned char *) realloc(varColBuff, nVarBytes); if (! varColBuff1) { *status = MEMORY_ALLOCATION; ffpmsg("failed to allocate memory for variable column copy (ffcprw)"); goto CLEANUP_RETURN; } /* Record the new state */ varColBuff = varColBuff1; nVarAllocBytes = nVarBytes; } /* Copy date from input to output */ ffgbyt(infptr, nVarBytes, varColBuff, status); ffmbyt(outfptr, outPos, IGNORE_EOF, status); ffpbyt(outfptr, nVarBytes, varColBuff, status); } ffpdes(outfptr, icol+1, jj, hrepeat, (outfptr->Fptr)->heapsize, status); (outfptr->Fptr)->heapsize += nVarBytes; ++iVarCol; } ++colptr; } ++jj; } } else { /* copy the rows, 1 at a time */ for (ii = firstrow; ii < firstrow + nrows; ii++) { fits_read_tblbytes (infptr, ii, 1, innaxis1, buffer, status); fits_write_tblbytes(outfptr, jj, 1, innaxis1, buffer, status); jj++; } } outnaxis2 += nrows; fits_update_key(outfptr, TLONGLONG, "NAXIS2", &outnaxis2, 0, status); CLEANUP_RETURN: free(buffer); free(inVarCols); free(outVarCols); if (varColBuff) free(varColBuff); return(*status); } /*--------------------------------------------------------------------------*/ int ffcpky(fitsfile *infptr, /* I - FITS file pointer to input file */ fitsfile *outfptr, /* I - FITS file pointer to output file */ int incol, /* I - input index number */ int outcol, /* I - output index number */ char *rootname, /* I - root name of the keyword to be copied */ int *status) /* IO - error status */ /* copy an indexed keyword from infptr to outfptr. */ { int tstatus = 0; char keyname[FLEN_KEYWORD]; char value[FLEN_VALUE], comment[FLEN_COMMENT], card[FLEN_CARD]; ffkeyn(rootname, incol, keyname, &tstatus); if (ffgkey(infptr, keyname, value, comment, &tstatus) <= 0) { ffkeyn(rootname, outcol, keyname, &tstatus); ffmkky(keyname, value, comment, card, status); ffprec(outfptr, card, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffdcol(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column to delete (1 = 1st) */ int *status) /* IO - error status */ /* Delete a column from a table. */ { int ii, tstatus; LONGLONG firstbyte, size, ndelete, nbytes, naxis1, naxis2, firstcol, delbyte, freespace; LONGLONG tbcol; long nblock, nspace; char keyname[FLEN_KEYWORD], comm[FLEN_COMMENT]; tcolumn *colptr, *nextcol; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffpmsg ("Can only delete column from TABLE or BINTABLE extension (ffdcol)"); return(*status = NOT_TABLE); } if (colnum < 1 || colnum > (fptr->Fptr)->tfield ) return(*status = BAD_COL_NUM); colptr = (fptr->Fptr)->tableptr; colptr += (colnum - 1); firstcol = colptr->tbcol; /* starting byte position of the column */ /* use column width to determine how many bytes to delete in each row */ if ((fptr->Fptr)->hdutype == ASCII_TBL) { delbyte = colptr->twidth; /* width of ASCII column */ if (colnum < (fptr->Fptr)->tfield) /* check for space between next column */ { nextcol = colptr + 1; nspace = (long) ((nextcol->tbcol) - (colptr->tbcol) - delbyte); if (nspace > 0) delbyte++; } else if (colnum > 1) /* check for space between last 2 columns */ { nextcol = colptr - 1; nspace = (long) ((colptr->tbcol) - (nextcol->tbcol) - (nextcol->twidth)); if (nspace > 0) { delbyte++; firstcol--; /* delete the leading space */ } } } else /* a binary table */ { if (colnum < (fptr->Fptr)->tfield) { nextcol = colptr + 1; delbyte = (nextcol->tbcol) - (colptr->tbcol); } else { delbyte = ((fptr->Fptr)->rowlength) - (colptr->tbcol); } } naxis1 = (fptr->Fptr)->rowlength; /* current width of the table */ naxis2 = (fptr->Fptr)->numrows; /* current size of table */ size = (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; freespace = ((LONGLONG)delbyte * naxis2) + ((size + 2879) / 2880) * 2880 - size; nblock = (long) (freespace / 2880); /* number of empty blocks to delete */ ffcdel(fptr, naxis1, naxis2, delbyte, firstcol, status); /* delete col */ /* absolute heap position */ firstbyte = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart; ndelete = (LONGLONG)delbyte * naxis2; /* size of shift */ /* shift heap up (if it exists) */ if ((fptr->Fptr)->heapsize > 0) { nbytes = (fptr->Fptr)->heapsize; /* no. of bytes to shift up */ if (ffshft(fptr, firstbyte, nbytes, -ndelete, status) > 0) /* mv heap */ return(*status); } /* delete the empty blocks at the end of the HDU */ if (nblock > 0) ffdblk(fptr, nblock, status); /* update the heap starting address */ (fptr->Fptr)->heapstart -= ndelete; /* update the THEAP keyword if it exists */ tstatus = 0; ffmkyj(fptr, "THEAP", (long)(fptr->Fptr)->heapstart, "&", &tstatus); if ((fptr->Fptr)->hdutype == ASCII_TBL) { /* adjust the TBCOL values of the remaining columns */ for (ii = 1; ii <= (fptr->Fptr)->tfield; ii++) { ffkeyn("TBCOL", ii, keyname, status); ffgkyjj(fptr, keyname, &tbcol, comm, status); if (tbcol > firstcol) { tbcol = tbcol - delbyte; ffmkyj(fptr, keyname, tbcol, "&", status); } } } /* update the mandatory keywords */ ffmkyj(fptr, "TFIELDS", ((fptr->Fptr)->tfield) - 1, "&", status); ffmkyj(fptr, "NAXIS1", naxis1 - delbyte, "&", status); /* delete the index keywords starting with 'T' associated with the deleted column and subtract 1 from index of all higher keywords */ ffkshf(fptr, colnum, (fptr->Fptr)->tfield, -1, status); ffrdef(fptr, status); /* initialize the new table structure */ return(*status); } /*--------------------------------------------------------------------------*/ int ffcins(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG naxis1, /* I - width of the table, in bytes */ LONGLONG naxis2, /* I - number of rows in the table */ LONGLONG ninsert, /* I - number of bytes to insert in each row */ LONGLONG bytepos, /* I - rel. position in row to insert bytes */ int *status) /* IO - error status */ /* Insert 'ninsert' bytes into each row of the table at position 'bytepos'. */ { unsigned char buffer[10000], cfill; LONGLONG newlen, fbyte, nbytes, irow, nseg, ii; if (*status > 0) return(*status); if (naxis2 == 0) return(*status); /* just return if there are 0 rows in the table */ /* select appropriate fill value */ if ((fptr->Fptr)->hdutype == ASCII_TBL) cfill = 32; /* ASCII tables use blank fill */ else cfill = 0; /* primary array and binary tables use zero fill */ newlen = naxis1 + ninsert; if (newlen <= 10000) { /******************************************************************* CASE #1: optimal case where whole new row fits in the work buffer *******************************************************************/ for (ii = 0; ii < ninsert; ii++) buffer[ii] = cfill; /* initialize buffer with fill value */ /* first move the trailing bytes (if any) in the last row */ fbyte = bytepos + 1; nbytes = naxis1 - bytepos; /* If the last row hasn't yet been accessed in full, it's possible that logfilesize hasn't been updated to account for it (by way of an ffldrc call). This could cause ffgtbb to return with an EOF error. To prevent this, we must increase logfilesize here. */ if ((fptr->Fptr)->logfilesize < (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart) { (fptr->Fptr)->logfilesize = (((fptr->Fptr)->datastart + (fptr->Fptr)->heapstart + 2879)/2880)*2880; } ffgtbb(fptr, naxis2, fbyte, nbytes, &buffer[ninsert], status); (fptr->Fptr)->rowlength = newlen; /* new row length */ /* write the row (with leading fill bytes) in the new place */ nbytes += ninsert; ffptbb(fptr, naxis2, fbyte, nbytes, buffer, status); (fptr->Fptr)->rowlength = naxis1; /* reset to orig. value */ /* now move the rest of the rows */ for (irow = naxis2 - 1; irow > 0; irow--) { /* read the row to be shifted (work backwards thru the table) */ ffgtbb(fptr, irow, fbyte, naxis1, &buffer[ninsert], status); (fptr->Fptr)->rowlength = newlen; /* new row length */ /* write the row (with the leading fill bytes) in the new place */ ffptbb(fptr, irow, fbyte, newlen, buffer, status); (fptr->Fptr)->rowlength = naxis1; /* reset to orig value */ } } else { /***************************************************************** CASE #2: whole row doesn't fit in work buffer; move row in pieces ****************************************************************** first copy the data, then go back and write fill into the new column start by copying the trailing bytes (if any) in the last row. */ nbytes = naxis1 - bytepos; nseg = (nbytes + 9999) / 10000; fbyte = (nseg - 1) * 10000 + bytepos + 1; nbytes = naxis1 - fbyte + 1; for (ii = 0; ii < nseg; ii++) { ffgtbb(fptr, naxis2, fbyte, nbytes, buffer, status); (fptr->Fptr)->rowlength = newlen; /* new row length */ ffptbb(fptr, naxis2, fbyte + ninsert, nbytes, buffer, status); (fptr->Fptr)->rowlength = naxis1; /* reset to orig value */ fbyte -= 10000; nbytes = 10000; } /* now move the rest of the rows */ nseg = (naxis1 + 9999) / 10000; for (irow = naxis2 - 1; irow > 0; irow--) { fbyte = (nseg - 1) * 10000 + bytepos + 1; nbytes = naxis1 - (nseg - 1) * 10000; for (ii = 0; ii < nseg; ii++) { /* read the row to be shifted (work backwards thru the table) */ ffgtbb(fptr, irow, fbyte, nbytes, buffer, status); (fptr->Fptr)->rowlength = newlen; /* new row length */ /* write the row in the new place */ ffptbb(fptr, irow, fbyte + ninsert, nbytes, buffer, status); (fptr->Fptr)->rowlength = naxis1; /* reset to orig value */ fbyte -= 10000; nbytes = 10000; } } /* now write the fill values into the new column */ nbytes = minvalue(ninsert, 10000); memset(buffer, cfill, (size_t) nbytes); /* initialize with fill value */ nseg = (ninsert + 9999) / 10000; (fptr->Fptr)->rowlength = newlen; /* new row length */ for (irow = 1; irow <= naxis2; irow++) { fbyte = bytepos + 1; nbytes = ninsert - ((nseg - 1) * 10000); for (ii = 0; ii < nseg; ii++) { ffptbb(fptr, irow, fbyte, nbytes, buffer, status); fbyte += nbytes; nbytes = 10000; } } (fptr->Fptr)->rowlength = naxis1; /* reset to orig value */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffcdel(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG naxis1, /* I - width of the table, in bytes */ LONGLONG naxis2, /* I - number of rows in the table */ LONGLONG ndelete, /* I - number of bytes to delete in each row */ LONGLONG bytepos, /* I - rel. position in row to delete bytes */ int *status) /* IO - error status */ /* delete 'ndelete' bytes from each row of the table at position 'bytepos'. */ { unsigned char buffer[10000]; LONGLONG i1, i2, ii, irow, nseg; LONGLONG newlen, remain, nbytes; if (*status > 0) return(*status); if (naxis2 == 0) return(*status); /* just return if there are 0 rows in the table */ newlen = naxis1 - ndelete; if (newlen <= 10000) { /******************************************************************* CASE #1: optimal case where whole new row fits in the work buffer *******************************************************************/ i1 = bytepos + 1; i2 = i1 + ndelete; for (irow = 1; irow < naxis2; irow++) { ffgtbb(fptr, irow, i2, newlen, buffer, status); /* read row */ (fptr->Fptr)->rowlength = newlen; /* new row length */ ffptbb(fptr, irow, i1, newlen, buffer, status); /* write row */ (fptr->Fptr)->rowlength = naxis1; /* reset to orig value */ } /* now do the last row */ remain = naxis1 - (bytepos + ndelete); if (remain > 0) { ffgtbb(fptr, naxis2, i2, remain, buffer, status); /* read row */ (fptr->Fptr)->rowlength = newlen; /* new row length */ ffptbb(fptr, naxis2, i1, remain, buffer, status); /* write row */ (fptr->Fptr)->rowlength = naxis1; /* reset to orig value */ } } else { /***************************************************************** CASE #2: whole row doesn't fit in work buffer; move row in pieces ******************************************************************/ nseg = (newlen + 9999) / 10000; for (irow = 1; irow < naxis2; irow++) { i1 = bytepos + 1; i2 = i1 + ndelete; nbytes = newlen - (nseg - 1) * 10000; for (ii = 0; ii < nseg; ii++) { ffgtbb(fptr, irow, i2, nbytes, buffer, status); /* read bytes */ (fptr->Fptr)->rowlength = newlen; /* new row length */ ffptbb(fptr, irow, i1, nbytes, buffer, status); /* rewrite bytes */ (fptr->Fptr)->rowlength = naxis1; /* reset to orig value */ i1 += nbytes; i2 += nbytes; nbytes = 10000; } } /* now do the last row */ remain = naxis1 - (bytepos + ndelete); if (remain > 0) { nseg = (remain + 9999) / 10000; i1 = bytepos + 1; i2 = i1 + ndelete; nbytes = remain - (nseg - 1) * 10000; for (ii = 0; ii < nseg; ii++) { ffgtbb(fptr, naxis2, i2, nbytes, buffer, status); (fptr->Fptr)->rowlength = newlen; /* new row length */ ffptbb(fptr, naxis2, i1, nbytes, buffer, status); /* write row */ (fptr->Fptr)->rowlength = naxis1; /* reset to orig value */ i1 += nbytes; i2 += nbytes; nbytes = 10000; } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffkshf(fitsfile *fptr, /* I - FITS file pointer */ int colmin, /* I - starting col. to be incremented; 1 = 1st */ int colmax, /* I - last column to be incremented */ int incre, /* I - shift index number by this amount */ int *status) /* IO - error status */ /* shift the index value on any existing column keywords This routine will modify the name of any keyword that begins with 'T' and has an index number in the range COLMIN - COLMAX, inclusive. if incre is positive, then the index values will be incremented. if incre is negative, then the kewords with index = COLMIN will be deleted and the index of higher numbered keywords will be decremented. */ { int nkeys, nmore, nrec, tstatus, i1; long ivalue; char rec[FLEN_CARD], q[FLEN_KEYWORD], newkey[FLEN_KEYWORD]; ffghsp(fptr, &nkeys, &nmore, status); /* get number of keywords */ /* go thru header starting with the 9th keyword looking for 'TxxxxNNN' */ for (nrec = 9; nrec <= nkeys; nrec++) { ffgrec(fptr, nrec, rec, status); if (rec[0] == 'T') { i1 = 0; strncpy(q, &rec[1], 4); if (!strncmp(q, "BCOL", 4) || !strncmp(q, "FORM", 4) || !strncmp(q, "TYPE", 4) || !strncmp(q, "SCAL", 4) || !strncmp(q, "UNIT", 4) || !strncmp(q, "NULL", 4) || !strncmp(q, "ZERO", 4) || !strncmp(q, "DISP", 4) || !strncmp(q, "LMIN", 4) || !strncmp(q, "LMAX", 4) || !strncmp(q, "DMIN", 4) || !strncmp(q, "DMAX", 4) || !strncmp(q, "CTYP", 4) || !strncmp(q, "CRPX", 4) || !strncmp(q, "CRVL", 4) || !strncmp(q, "CDLT", 4) || !strncmp(q, "CROT", 4) || !strncmp(q, "CUNI", 4) ) i1 = 5; else if (!strncmp(rec, "TDIM", 4) ) i1 = 4; if (i1) { /* try reading the index number suffix */ q[0] = '\0'; strncat(q, &rec[i1], 8 - i1); tstatus = 0; ffc2ii(q, &ivalue, &tstatus); if (tstatus == 0 && ivalue >= colmin && ivalue <= colmax) { if (incre <= 0 && ivalue == colmin) { ffdrec(fptr, nrec, status); /* delete keyword */ nkeys = nkeys - 1; nrec = nrec - 1; } else { ivalue = ivalue + incre; q[0] = '\0'; strncat(q, rec, i1); ffkeyn(q, ivalue, newkey, status); /* NOTE: because of null termination, it is not equivalent to use strcpy() for the same calls */ strncpy(rec, " ", 8); /* erase old keyword name */ i1 = strlen(newkey); strncpy(rec, newkey, i1); /* overwrite new keyword name */ ffmrec(fptr, nrec, rec, status); /* modify the record */ } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffvcl(fitsfile *fptr, /* I - FITS file pointer */ int *nvarcols, /* O - Number of variable length columns found */ int *colnums, /* O - 1-based variable column positions */ int *status) /* IO - error status */ { /* Internal function to identify which columns in a binary table are variable length. The colnums array will be filled with nvarcols elements - the 1-based numbers of all variable length columns in the table. This ASSUMES calling function has passed in a colnums array large enough to hold these. */ int tfields=0,icol; tcolumn *colptr=0; *nvarcols = 0; if (*status > 0) return(*status); if ((fptr->Fptr)->hdutype != BINARY_TBL) { ffpmsg("Var-length column search can only be performed on Binary tables (fffvcl)"); return(*status = NOT_BTABLE); } if ((fptr->Fptr)->tableptr) { colptr = (fptr->Fptr)->tableptr; tfields = (fptr->Fptr)->tfield; for (icol=0; icoltdatatype < 0) { colnums[*nvarcols] = icol + 1; *nvarcols += 1; } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffshft(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG firstbyte, /* I - position of first byte in block to shift */ LONGLONG nbytes, /* I - size of block of bytes to shift */ LONGLONG nshift, /* I - size of shift in bytes (+ or -) */ int *status) /* IO - error status */ /* Shift block of bytes by nshift bytes (positive or negative). A positive nshift value moves the block down further in the file, while a negative value shifts the block towards the beginning of the file. */ { #define shftbuffsize 100000 long ntomov; LONGLONG ptr, ntodo; char buffer[shftbuffsize]; if (*status > 0) return(*status); ntodo = nbytes; /* total number of bytes to shift */ if (nshift > 0) /* start at the end of the block and work backwards */ ptr = firstbyte + nbytes; else /* start at the beginning of the block working forwards */ ptr = firstbyte; while (ntodo) { /* number of bytes to move at one time */ ntomov = (long) (minvalue(ntodo, shftbuffsize)); if (nshift > 0) /* if moving block down ... */ ptr -= ntomov; /* move to position and read the bytes to be moved */ ffmbyt(fptr, ptr, REPORT_EOF, status); ffgbyt(fptr, ntomov, buffer, status); /* move by shift amount and write the bytes */ ffmbyt(fptr, ptr + nshift, IGNORE_EOF, status); if (ffpbyt(fptr, ntomov, buffer, status) > 0) { ffpmsg("Error while shifting block (ffshft)"); return(*status); } ntodo -= ntomov; if (nshift < 0) /* if moving block up ... */ ptr += ntomov; } /* now overwrite the old data with fill */ if ((fptr->Fptr)->hdutype == ASCII_TBL) memset(buffer, 32, shftbuffsize); /* fill ASCII tables with spaces */ else memset(buffer, 0, shftbuffsize); /* fill other HDUs with zeros */ if (nshift < 0) { ntodo = -nshift; /* point to the end of the shifted block */ ptr = firstbyte + nbytes + nshift; } else { ntodo = nshift; /* point to original beginning of the block */ ptr = firstbyte; } ffmbyt(fptr, ptr, REPORT_EOF, status); while (ntodo) { ntomov = (long) (minvalue(ntodo, shftbuffsize)); ffpbyt(fptr, ntomov, buffer, status); ntodo -= ntomov; } return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/edithdu.c0000644000175100001710000007772700000000000017741 0ustar00vstsdocker/* This file, edithdu.c, contains the FITSIO routines related to */ /* copying, inserting, or deleting HDUs in a FITS file */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffcopy(fitsfile *infptr, /* I - FITS file pointer to input file */ fitsfile *outfptr, /* I - FITS file pointer to output file */ int morekeys, /* I - reserve space in output header */ int *status) /* IO - error status */ /* copy the CHDU from infptr to the CHDU of outfptr. This will also allocate space in the output header for MOREKY keywords */ { int nspace; if (*status > 0) return(*status); if (infptr == outfptr) return(*status = SAME_FILE); if (ffcphd(infptr, outfptr, status) > 0) /* copy the header keywords */ return(*status); if (morekeys > 0) { ffhdef(outfptr, morekeys, status); /* reserve space for more keywords */ } else { if (ffghsp(infptr, NULL, &nspace, status) > 0) /* get existing space */ return(*status); if (nspace > 0) { ffhdef(outfptr, nspace, status); /* preserve same amount of space */ if (nspace >= 35) { /* There is at least 1 full empty FITS block in the header. */ /* Physically write the END keyword at the beginning of the */ /* last block to preserve this extra space now rather than */ /* later. This is needed by the stream: driver which cannot */ /* seek back to the header to write the END keyword later. */ ffwend(outfptr, status); } } } ffcpdt(infptr, outfptr, status); /* now copy the data unit */ return(*status); } /*--------------------------------------------------------------------------*/ int ffcpfl(fitsfile *infptr, /* I - FITS file pointer to input file */ fitsfile *outfptr, /* I - FITS file pointer to output file */ int previous, /* I - copy any previous HDUs? */ int current, /* I - copy the current HDU? */ int following, /* I - copy any following HDUs? */ int *status) /* IO - error status */ /* copy all or part of the input file to the output file. */ { int hdunum, ii; if (*status > 0) return(*status); if (infptr == outfptr) return(*status = SAME_FILE); ffghdn(infptr, &hdunum); if (previous) { /* copy any previous HDUs */ for (ii=1; ii < hdunum; ii++) { ffmahd(infptr, ii, NULL, status); ffcopy(infptr, outfptr, 0, status); } } if (current && (*status <= 0) ) { /* copy current HDU */ ffmahd(infptr, hdunum, NULL, status); ffcopy(infptr, outfptr, 0, status); } if (following && (*status <= 0) ) { /* copy any remaining HDUs */ ii = hdunum + 1; while (1) { if (ffmahd(infptr, ii, NULL, status) ) { /* reset expected end of file status */ if (*status == END_OF_FILE) *status = 0; break; } if (ffcopy(infptr, outfptr, 0, status)) break; /* quit on unexpected error */ ii++; } } ffmahd(infptr, hdunum, NULL, status); /* restore initial position */ return(*status); } /*--------------------------------------------------------------------------*/ int ffcphd(fitsfile *infptr, /* I - FITS file pointer to input file */ fitsfile *outfptr, /* I - FITS file pointer to output file */ int *status) /* IO - error status */ /* copy the header keywords from infptr to outfptr. */ { int nkeys, ii, inPrim = 0, outPrim = 0; long naxis, naxes[1]; char *card, comm[FLEN_COMMENT]; char *tmpbuff; if (*status > 0) return(*status); if (infptr == outfptr) return(*status = SAME_FILE); /* set the input pointer to the correct HDU */ if (infptr->HDUposition != (infptr->Fptr)->curhdu) ffmahd(infptr, (infptr->HDUposition) + 1, NULL, status); if (ffghsp(infptr, &nkeys, NULL, status) > 0) /* get no. of keywords */ return(*status); /* create a memory buffer to hold the header records */ tmpbuff = (char*) malloc(nkeys*FLEN_CARD*sizeof(char)); if (!tmpbuff) return(*status = MEMORY_ALLOCATION); /* read all of the header records in the input HDU */ for (ii = 0; ii < nkeys; ii++) ffgrec(infptr, ii+1, tmpbuff + (ii * FLEN_CARD), status); if (infptr->HDUposition == 0) /* set flag if this is the Primary HDU */ inPrim = 1; /* if input is an image hdu, get the number of axes */ naxis = -1; /* negative if HDU is a table */ if ((infptr->Fptr)->hdutype == IMAGE_HDU) ffgkyj(infptr, "NAXIS", &naxis, NULL, status); /* set the output pointer to the correct HDU */ if (outfptr->HDUposition != (outfptr->Fptr)->curhdu) ffmahd(outfptr, (outfptr->HDUposition) + 1, NULL, status); /* check if output header is empty; if not create new empty HDU */ if ((outfptr->Fptr)->headend != (outfptr->Fptr)->headstart[(outfptr->Fptr)->curhdu] ) ffcrhd(outfptr, status); if (outfptr->HDUposition == 0) { if (naxis < 0) { /* the input HDU is a table, so we have to create */ /* a dummy Primary array before copying it to the output */ ffcrim(outfptr, 8, 0, naxes, status); ffcrhd(outfptr, status); /* create new empty HDU */ } else { /* set flag that this is the Primary HDU */ outPrim = 1; } } if (*status > 0) /* check for errors before proceeding */ { free(tmpbuff); return(*status); } if ( inPrim == 1 && outPrim == 0 ) { /* copying from primary array to image extension */ strcpy(comm, "IMAGE extension"); ffpkys(outfptr, "XTENSION", "IMAGE", comm, status); /* copy BITPIX through NAXISn keywords */ for (ii = 1; ii < 3 + naxis; ii++) { card = tmpbuff + (ii * FLEN_CARD); ffprec(outfptr, card, status); } strcpy(comm, "number of random group parameters"); ffpkyj(outfptr, "PCOUNT", 0, comm, status); strcpy(comm, "number of random groups"); ffpkyj(outfptr, "GCOUNT", 1, comm, status); /* copy remaining keywords, excluding EXTEND, and reference COMMENT keywords */ for (ii = 3 + naxis ; ii < nkeys; ii++) { card = tmpbuff+(ii * FLEN_CARD); if (FSTRNCMP(card, "EXTEND ", 8) && FSTRNCMP(card, "COMMENT FITS (Flexible Image Transport System) format is", 58) && FSTRNCMP(card, "COMMENT and Astrophysics', volume 376, page 3", 47) ) { ffprec(outfptr, card, status); } } } else if ( inPrim == 0 && outPrim == 1 ) { /* copying between image extension and primary array */ strcpy(comm, "file does conform to FITS standard"); ffpkyl(outfptr, "SIMPLE", TRUE, comm, status); /* copy BITPIX through NAXISn keywords */ for (ii = 1; ii < 3 + naxis; ii++) { card = tmpbuff + (ii * FLEN_CARD); ffprec(outfptr, card, status); } /* add the EXTEND keyword */ strcpy(comm, "FITS dataset may contain extensions"); ffpkyl(outfptr, "EXTEND", TRUE, comm, status); /* write standard block of self-documentating comments */ ffprec(outfptr, "COMMENT FITS (Flexible Image Transport System) format is defined in 'Astronomy", status); ffprec(outfptr, "COMMENT and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H", status); /* copy remaining keywords, excluding pcount, gcount */ for (ii = 3 + naxis; ii < nkeys; ii++) { card = tmpbuff+(ii * FLEN_CARD); if (FSTRNCMP(card, "PCOUNT ", 8) && FSTRNCMP(card, "GCOUNT ", 8)) { ffprec(outfptr, card, status); } } } else { /* input and output HDUs are same type; simply copy all keywords */ for (ii = 0; ii < nkeys; ii++) { card = tmpbuff+(ii * FLEN_CARD); ffprec(outfptr, card, status); } } free(tmpbuff); return(*status); } /*--------------------------------------------------------------------------*/ int ffcpht(fitsfile *infptr, /* I - FITS file pointer to input file */ fitsfile *outfptr, /* I - FITS file pointer to output file */ LONGLONG firstrow, /* I - number of first row to copy (1 based) */ LONGLONG nrows, /* I - number of rows to copy */ int *status) /* IO - error status */ /* Copy the table structure from an existing table HDU, but only copy a limited row range. All header keywords from the input table are copied directly, but NAXSI2 and PCOUNT are set to their correct values. */ { if (*status > 0) return(*status); /* Copy the header only */ ffcphd(infptr, outfptr, status); /* Note that we now have a copied header that describes the table, and that is the current header, but the original number of table rows and heap area sizes are still there. */ /* Zero out the size-related keywords */ if (! *status ) { ffukyj(outfptr,"NAXIS2",0,0,status); /* NAXIS2 = 0 */ ffukyj(outfptr,"PCOUNT",0,0,status); /* PCOUNT = 0 */ /* Update the internal structure variables within CFITSIO now that we have a valid table header */ ffrdef(outfptr,status); } /* OK now that we have a pristine HDU, copy the requested rows */ if (! *status && nrows > 0) { ffcprw(infptr, outfptr, firstrow, nrows, status); } return (*status); } /*--------------------------------------------------------------------------*/ int ffcpdt(fitsfile *infptr, /* I - FITS file pointer to input file */ fitsfile *outfptr, /* I - FITS file pointer to output file */ int *status) /* IO - error status */ { /* copy the data unit from the CHDU of infptr to the CHDU of outfptr. This will overwrite any data already in the outfptr CHDU. */ long nb, ii; LONGLONG indatastart, indataend, outdatastart; char buffer[2880]; if (*status > 0) return(*status); if (infptr == outfptr) return(*status = SAME_FILE); ffghadll(infptr, NULL, &indatastart, &indataend, status); ffghadll(outfptr, NULL, &outdatastart, NULL, status); /* Calculate the number of blocks to be copied */ nb = (long) ((indataend - indatastart) / 2880); if (nb > 0) { if (infptr->Fptr == outfptr->Fptr) { /* copying between 2 HDUs in the SAME file */ for (ii = 0; ii < nb; ii++) { ffmbyt(infptr, indatastart, REPORT_EOF, status); ffgbyt(infptr, 2880L, buffer, status); /* read input block */ ffmbyt(outfptr, outdatastart, IGNORE_EOF, status); ffpbyt(outfptr, 2880L, buffer, status); /* write output block */ indatastart += 2880; /* move address */ outdatastart += 2880; /* move address */ } } else { /* copying between HDUs in separate files */ /* move to the initial copy position in each of the files */ ffmbyt(infptr, indatastart, REPORT_EOF, status); ffmbyt(outfptr, outdatastart, IGNORE_EOF, status); for (ii = 0; ii < nb; ii++) { ffgbyt(infptr, 2880L, buffer, status); /* read input block */ ffpbyt(outfptr, 2880L, buffer, status); /* write output block */ } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffwrhdu(fitsfile *infptr, /* I - FITS file pointer to input file */ FILE *outstream, /* I - stream to write HDU to */ int *status) /* IO - error status */ { /* write the data unit from the CHDU of infptr to the output file stream */ long nb, ii; LONGLONG hdustart, hduend; char buffer[2880]; if (*status > 0) return(*status); ffghadll(infptr, &hdustart, NULL, &hduend, status); nb = (long) ((hduend - hdustart) / 2880); /* number of blocks to copy */ if (nb > 0) { /* move to the start of the HDU */ ffmbyt(infptr, hdustart, REPORT_EOF, status); for (ii = 0; ii < nb; ii++) { ffgbyt(infptr, 2880L, buffer, status); /* read input block */ fwrite(buffer, 1, 2880, outstream ); /* write to output stream */ } } return(*status); } /*--------------------------------------------------------------------------*/ int ffiimg(fitsfile *fptr, /* I - FITS file pointer */ int bitpix, /* I - bits per pixel */ int naxis, /* I - number of axes in the array */ long *naxes, /* I - size of each axis */ int *status) /* IO - error status */ /* insert an IMAGE extension following the current HDU */ { LONGLONG tnaxes[99]; int ii; if (*status > 0) return(*status); if (naxis > 99) { ffpmsg("NAXIS value is too large (>99) (ffiimg)"); return(*status = 212); } for (ii = 0; (ii < naxis); ii++) tnaxes[ii] = naxes[ii]; ffiimgll(fptr, bitpix, naxis, tnaxes, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffiimgll(fitsfile *fptr, /* I - FITS file pointer */ int bitpix, /* I - bits per pixel */ int naxis, /* I - number of axes in the array */ LONGLONG *naxes, /* I - size of each axis */ int *status) /* IO - error status */ /* insert an IMAGE extension following the current HDU */ { int bytlen, nexthdu, maxhdu, ii, onaxis; long nblocks; LONGLONG npixels, newstart, datasize; char errmsg[FLEN_ERRMSG], card[FLEN_CARD], naxiskey[FLEN_KEYWORD]; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); maxhdu = (fptr->Fptr)->maxhdu; if (*status != PREPEND_PRIMARY) { /* if the current header is completely empty ... */ if (( (fptr->Fptr)->headend == (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu]) /* or, if we are at the end of the file, ... */ || ( (((fptr->Fptr)->curhdu) == maxhdu ) && ((fptr->Fptr)->headstart[maxhdu + 1] >= (fptr->Fptr)->logfilesize ) ) ) { /* then simply append new image extension */ ffcrimll(fptr, bitpix, naxis, naxes, status); return(*status); } } if (bitpix == 8) bytlen = 1; else if (bitpix == 16) bytlen = 2; else if (bitpix == 32 || bitpix == -32) bytlen = 4; else if (bitpix == 64 || bitpix == -64) bytlen = 8; else { snprintf(errmsg, FLEN_ERRMSG, "Illegal value for BITPIX keyword: %d", bitpix); ffpmsg(errmsg); return(*status = BAD_BITPIX); /* illegal bitpix value */ } if (naxis < 0 || naxis > 999) { snprintf(errmsg, FLEN_ERRMSG, "Illegal value for NAXIS keyword: %d", naxis); ffpmsg(errmsg); return(*status = BAD_NAXIS); } for (ii = 0; ii < naxis; ii++) { if (naxes[ii] < 0) { snprintf(errmsg, FLEN_ERRMSG, "Illegal value for NAXIS%d keyword: %ld", ii + 1, (long) naxes[ii]); ffpmsg(errmsg); return(*status = BAD_NAXES); } } /* calculate number of pixels in the image */ if (naxis == 0) npixels = 0; else npixels = naxes[0]; for (ii = 1; ii < naxis; ii++) npixels = npixels * naxes[ii]; datasize = npixels * bytlen; /* size of image in bytes */ nblocks = (long) (((datasize + 2879) / 2880) + 1); /* +1 for the header */ if ((fptr->Fptr)->writemode == READWRITE) /* must have write access */ { /* close the CHDU */ ffrdef(fptr, status); /* scan header to redefine structure */ ffpdfl(fptr, status); /* insure correct data file values */ } else return(*status = READONLY_FILE); if (*status == PREPEND_PRIMARY) { /* inserting a new primary array; the current primary */ /* array must be transformed into an image extension. */ *status = 0; ffmahd(fptr, 1, NULL, status); /* move to the primary array */ ffgidm(fptr, &onaxis, status); if (onaxis > 0) ffkeyn("NAXIS",onaxis, naxiskey, status); else strcpy(naxiskey, "NAXIS"); ffgcrd(fptr, naxiskey, card, status); /* read last NAXIS keyword */ ffikyj(fptr, "PCOUNT", 0, "required keyword", status); /* add PCOUNT and */ ffikyj(fptr, "GCOUNT", 1, "required keyword", status); /* GCOUNT keywords */ if (*status > 0) return(*status); if (ffdkey(fptr, "EXTEND", status) ) /* delete the EXTEND keyword */ *status = 0; /* redefine internal structure for this HDU */ ffrdef(fptr, status); /* insert space for the primary array */ if (ffiblk(fptr, nblocks, -1, status) > 0) /* insert the blocks */ return(*status); nexthdu = 0; /* number of the new hdu */ newstart = 0; /* starting addr of HDU */ } else { nexthdu = ((fptr->Fptr)->curhdu) + 1; /* number of the next (new) hdu */ newstart = (fptr->Fptr)->headstart[nexthdu]; /* save starting addr of HDU */ (fptr->Fptr)->hdutype = IMAGE_HDU; /* so that correct fill value is used */ /* ffiblk also increments headstart for all following HDUs */ if (ffiblk(fptr, nblocks, 1, status) > 0) /* insert the blocks */ return(*status); } ((fptr->Fptr)->maxhdu)++; /* increment known number of HDUs in the file */ for (ii = (fptr->Fptr)->maxhdu; ii > (fptr->Fptr)->curhdu; ii--) (fptr->Fptr)->headstart[ii + 1] = (fptr->Fptr)->headstart[ii]; /* incre start addr */ if (nexthdu == 0) (fptr->Fptr)->headstart[1] = nblocks * 2880; /* start of the old Primary array */ (fptr->Fptr)->headstart[nexthdu] = newstart; /* set starting addr of HDU */ /* set default parameters for this new empty HDU */ (fptr->Fptr)->curhdu = nexthdu; /* we are now located at the next HDU */ fptr->HDUposition = nexthdu; /* we are now located at the next HDU */ (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[nexthdu]; (fptr->Fptr)->headend = (fptr->Fptr)->headstart[nexthdu]; (fptr->Fptr)->datastart = ((fptr->Fptr)->headstart[nexthdu]) + 2880; (fptr->Fptr)->hdutype = IMAGE_HDU; /* might need to be reset... */ /* write the required header keywords */ ffphprll(fptr, TRUE, bitpix, naxis, naxes, 0, 1, TRUE, status); /* redefine internal structure for this HDU */ ffrdef(fptr, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffitab(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG naxis1, /* I - width of row in the table */ LONGLONG naxis2, /* I - number of rows in the table */ int tfields, /* I - number of columns in the table */ char **ttype, /* I - name of each column */ long *tbcol, /* I - byte offset in row to each column */ char **tform, /* I - value of TFORMn keyword for each column */ char **tunit, /* I - value of TUNITn keyword for each column */ const char *extnmx, /* I - value of EXTNAME keyword, if any */ int *status) /* IO - error status */ /* insert an ASCII table extension following the current HDU */ { int nexthdu, maxhdu, ii, nunit, nhead, ncols, gotmem = 0; long nblocks, rowlen; LONGLONG datasize, newstart; char errmsg[FLEN_ERRMSG], extnm[FLEN_VALUE]; if (*status > 0) return(*status); extnm[0] = '\0'; if (extnmx) strncat(extnm, extnmx, FLEN_VALUE-1); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); maxhdu = (fptr->Fptr)->maxhdu; /* if the current header is completely empty ... */ if (( (fptr->Fptr)->headend == (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) /* or, if we are at the end of the file, ... */ || ( (((fptr->Fptr)->curhdu) == maxhdu ) && ((fptr->Fptr)->headstart[maxhdu + 1] >= (fptr->Fptr)->logfilesize ) ) ) { /* then simply append new image extension */ ffcrtb(fptr, ASCII_TBL, naxis2, tfields, ttype, tform, tunit, extnm, status); return(*status); } if (naxis1 < 0) return(*status = NEG_WIDTH); else if (naxis2 < 0) return(*status = NEG_ROWS); else if (tfields < 0 || tfields > 999) { snprintf(errmsg, FLEN_ERRMSG, "Illegal value for TFIELDS keyword: %d", tfields); ffpmsg(errmsg); return(*status = BAD_TFIELDS); } /* count number of optional TUNIT keywords to be written */ nunit = 0; for (ii = 0; ii < tfields; ii++) { if (tunit && *tunit && *tunit[ii]) nunit++; } if (*extnm) nunit++; /* add one for the EXTNAME keyword */ rowlen = (long) naxis1; if (!tbcol || !tbcol[0] || (!naxis1 && tfields)) /* spacing not defined? */ { /* allocate mem for tbcol; malloc may have problems allocating small */ /* arrays, so allocate at least 20 bytes */ ncols = maxvalue(5, tfields); tbcol = (long *) calloc(ncols, sizeof(long)); if (tbcol) { gotmem = 1; /* calculate width of a row and starting position of each column. */ /* Each column will be separated by 1 blank space */ ffgabc(tfields, tform, 1, &rowlen, tbcol, status); } } nhead = (9 + (3 * tfields) + nunit + 35) / 36; /* no. of header blocks */ datasize = (LONGLONG)rowlen * naxis2; /* size of table in bytes */ nblocks = (long) (((datasize + 2879) / 2880) + nhead); /* size of HDU */ if ((fptr->Fptr)->writemode == READWRITE) /* must have write access */ { /* close the CHDU */ ffrdef(fptr, status); /* scan header to redefine structure */ ffpdfl(fptr, status); /* insure correct data file values */ } else return(*status = READONLY_FILE); nexthdu = ((fptr->Fptr)->curhdu) + 1; /* number of the next (new) hdu */ newstart = (fptr->Fptr)->headstart[nexthdu]; /* save starting addr of HDU */ (fptr->Fptr)->hdutype = ASCII_TBL; /* so that correct fill value is used */ /* ffiblk also increments headstart for all following HDUs */ if (ffiblk(fptr, nblocks, 1, status) > 0) /* insert the blocks */ { if (gotmem) free(tbcol); return(*status); } ((fptr->Fptr)->maxhdu)++; /* increment known number of HDUs in the file */ for (ii = (fptr->Fptr)->maxhdu; ii > (fptr->Fptr)->curhdu; ii--) (fptr->Fptr)->headstart[ii + 1] = (fptr->Fptr)->headstart[ii]; /* incre start addr */ (fptr->Fptr)->headstart[nexthdu] = newstart; /* set starting addr of HDU */ /* set default parameters for this new empty HDU */ (fptr->Fptr)->curhdu = nexthdu; /* we are now located at the next HDU */ fptr->HDUposition = nexthdu; /* we are now located at the next HDU */ (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[nexthdu]; (fptr->Fptr)->headend = (fptr->Fptr)->headstart[nexthdu]; (fptr->Fptr)->datastart = ((fptr->Fptr)->headstart[nexthdu]) + (nhead * 2880); (fptr->Fptr)->hdutype = ASCII_TBL; /* might need to be reset... */ /* write the required header keywords */ ffphtb(fptr, rowlen, naxis2, tfields, ttype, tbcol, tform, tunit, extnm, status); if (gotmem) free(tbcol); /* redefine internal structure for this HDU */ ffrdef(fptr, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffibin(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG naxis2, /* I - number of rows in the table */ int tfields, /* I - number of columns in the table */ char **ttype, /* I - name of each column */ char **tform, /* I - value of TFORMn keyword for each column */ char **tunit, /* I - value of TUNITn keyword for each column */ const char *extnmx, /* I - value of EXTNAME keyword, if any */ LONGLONG pcount, /* I - size of special data area (heap) */ int *status) /* IO - error status */ /* insert a Binary table extension following the current HDU */ { int nexthdu, maxhdu, ii, nunit, nhead, datacode; LONGLONG naxis1; long nblocks, repeat, width; LONGLONG datasize, newstart; char errmsg[FLEN_ERRMSG], extnm[FLEN_VALUE]; if (*status > 0) return(*status); extnm[0] = '\0'; if (extnmx) strncat(extnm, extnmx, FLEN_VALUE-1); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); maxhdu = (fptr->Fptr)->maxhdu; /* if the current header is completely empty ... */ if (( (fptr->Fptr)->headend == (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) /* or, if we are at the end of the file, ... */ || ( (((fptr->Fptr)->curhdu) == maxhdu ) && ((fptr->Fptr)->headstart[maxhdu + 1] >= (fptr->Fptr)->logfilesize ) ) ) { /* then simply append new image extension */ ffcrtb(fptr, BINARY_TBL, naxis2, tfields, ttype, tform, tunit, extnm, status); return(*status); } if (naxis2 < 0) return(*status = NEG_ROWS); else if (tfields < 0 || tfields > 999) { snprintf(errmsg, FLEN_ERRMSG, "Illegal value for TFIELDS keyword: %d", tfields); ffpmsg(errmsg); return(*status = BAD_TFIELDS); } /* count number of optional TUNIT keywords to be written */ nunit = 0; for (ii = 0; ii < tfields; ii++) { if (tunit && *tunit && *tunit[ii]) nunit++; } if (*extnm) nunit++; /* add one for the EXTNAME keyword */ nhead = (9 + (2 * tfields) + nunit + 35) / 36; /* no. of header blocks */ /* calculate total width of the table */ naxis1 = 0; for (ii = 0; ii < tfields; ii++) { ffbnfm(tform[ii], &datacode, &repeat, &width, status); if (datacode == TBIT) naxis1 = naxis1 + ((repeat + 7) / 8); else if (datacode == TSTRING) naxis1 += repeat; else naxis1 = naxis1 + (repeat * width); } datasize = ((LONGLONG)naxis1 * naxis2) + pcount; /* size of table in bytes */ nblocks = (long) ((datasize + 2879) / 2880) + nhead; /* size of HDU */ if ((fptr->Fptr)->writemode == READWRITE) /* must have write access */ { /* close the CHDU */ ffrdef(fptr, status); /* scan header to redefine structure */ ffpdfl(fptr, status); /* insure correct data file values */ } else return(*status = READONLY_FILE); nexthdu = ((fptr->Fptr)->curhdu) + 1; /* number of the next (new) hdu */ newstart = (fptr->Fptr)->headstart[nexthdu]; /* save starting addr of HDU */ (fptr->Fptr)->hdutype = BINARY_TBL; /* so that correct fill value is used */ /* ffiblk also increments headstart for all following HDUs */ if (ffiblk(fptr, nblocks, 1, status) > 0) /* insert the blocks */ return(*status); ((fptr->Fptr)->maxhdu)++; /* increment known number of HDUs in the file */ for (ii = (fptr->Fptr)->maxhdu; ii > (fptr->Fptr)->curhdu; ii--) (fptr->Fptr)->headstart[ii + 1] = (fptr->Fptr)->headstart[ii]; /* incre start addr */ (fptr->Fptr)->headstart[nexthdu] = newstart; /* set starting addr of HDU */ /* set default parameters for this new empty HDU */ (fptr->Fptr)->curhdu = nexthdu; /* we are now located at the next HDU */ fptr->HDUposition = nexthdu; /* we are now located at the next HDU */ (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[nexthdu]; (fptr->Fptr)->headend = (fptr->Fptr)->headstart[nexthdu]; (fptr->Fptr)->datastart = ((fptr->Fptr)->headstart[nexthdu]) + (nhead * 2880); (fptr->Fptr)->hdutype = BINARY_TBL; /* might need to be reset... */ /* write the required header keywords. This will write PCOUNT = 0 */ /* so that the variable length data will be written at the right place */ ffphbn(fptr, naxis2, tfields, ttype, tform, tunit, extnm, pcount, status); /* redefine internal structure for this HDU (with PCOUNT = 0) */ ffrdef(fptr, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffdhdu(fitsfile *fptr, /* I - FITS file pointer */ int *hdutype, /* O - type of the new CHDU after deletion */ int *status) /* IO - error status */ /* Delete the CHDU. If the CHDU is the primary array, then replace the HDU with an empty primary array with no data. Return the type of the new CHDU after the old CHDU is deleted. */ { int tmptype = 0; long nblocks, ii, naxes[1]; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if ((fptr->Fptr)->curhdu == 0) /* replace primary array with null image */ { /* ignore any existing keywords */ (fptr->Fptr)->headend = 0; (fptr->Fptr)->nextkey = 0; /* write default primary array header */ ffphpr(fptr,1,8,0,naxes,0,1,1,status); /* calc number of blocks to delete (leave just 1 block) */ nblocks = (long) (( (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu + 1] - 2880 ) / 2880); /* ffdblk also updates the starting address of all following HDUs */ if (nblocks > 0) { if (ffdblk(fptr, nblocks, status) > 0) /* delete the HDU */ return(*status); } /* this might not be necessary, but is doesn't hurt */ (fptr->Fptr)->datastart = DATA_UNDEFINED; ffrdef(fptr, status); /* reinitialize the primary array */ } else { /* calc number of blocks to delete */ nblocks = (long) (( (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu + 1] - (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) / 2880); /* ffdblk also updates the starting address of all following HDUs */ if (ffdblk(fptr, nblocks, status) > 0) /* delete the HDU */ return(*status); /* delete the CHDU from the list of HDUs */ for (ii = (fptr->Fptr)->curhdu + 1; ii <= (fptr->Fptr)->maxhdu; ii++) (fptr->Fptr)->headstart[ii] = (fptr->Fptr)->headstart[ii + 1]; (fptr->Fptr)->headstart[(fptr->Fptr)->maxhdu + 1] = 0; ((fptr->Fptr)->maxhdu)--; /* decrement the known number of HDUs */ if (ffrhdu(fptr, &tmptype, status) > 0) /* initialize next HDU */ { /* failed (end of file?), so move back one HDU */ *status = 0; ffcmsg(); /* clear extraneous error messages */ ffgext(fptr, ((fptr->Fptr)->curhdu) - 1, &tmptype, status); } } if (hdutype) *hdutype = tmptype; return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/eval_defs.h0000644000175100001710000001030000000000000020216 0ustar00vstsdocker#include #include #include #include #if defined(__sgi) || defined(__hpux) #include #endif #ifdef sparc #include #endif #include "fitsio2.h" #define MAXDIMS 5 #define MAXSUBS 10 #define MAXVARNAME 80 #define CONST_OP -1000 #define pERROR -1 #define MAX_STRLEN 256 #define MAX_STRLEN_S "255" #ifndef FFBISON #include "eval_tab.h" #endif typedef struct { char name[MAXVARNAME+1]; int type; long nelem; int naxis; long naxes[MAXDIMS]; char *undef; void *data; } DataInfo; typedef struct { long nelem; int naxis; long naxes[MAXDIMS]; char *undef; union { double dbl; long lng; char log; char str[MAX_STRLEN]; double *dblptr; long *lngptr; char *logptr; char **strptr; void *ptr; } data; } lval; typedef struct Node { int operation; void (*DoOp)(struct Node *this); int nSubNodes; int SubNodes[MAXSUBS]; int type; lval value; } Node; typedef struct { fitsfile *def_fptr; int (*getData)( char *dataName, void *dataValue ); int (*loadData)( int varNum, long fRow, long nRows, void *data, char *undef ); int compressed; int timeCol; int parCol; int valCol; char *expr; int index; int is_eobuf; Node *Nodes; int nNodes; int nNodesAlloc; int resultNode; long firstRow; long nRows; int nCols; iteratorCol *colData; DataInfo *varData; PixelFilter *pixFilter; long firstDataRow; long nDataRows; long totalRows; int datatype; int hdutype; int status; } ParseData; typedef enum { rnd_fct = 1001, sum_fct, nelem_fct, sin_fct, cos_fct, tan_fct, asin_fct, acos_fct, atan_fct, sinh_fct, cosh_fct, tanh_fct, exp_fct, log_fct, log10_fct, sqrt_fct, abs_fct, atan2_fct, ceil_fct, floor_fct, round_fct, min1_fct, min2_fct, max1_fct, max2_fct, near_fct, circle_fct, box_fct, elps_fct, isnull_fct, defnull_fct, gtifilt_fct, regfilt_fct, ifthenelse_fct, row_fct, null_fct, median_fct, average_fct, stddev_fct, nonnull_fct, angsep_fct, gasrnd_fct, poirnd_fct, strmid_fct, strpos_fct, setnull_fct, gtiover_fct } funcOp; extern ParseData gParse; #ifdef __cplusplus extern "C" { #endif int ffparse(void); int fflex(void); void ffrestart(FILE*); void Evaluate_Parser( long firstRow, long nRows ); #ifdef __cplusplus } #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/eval_f.c0000644000175100001710000030141100000000000017523 0ustar00vstsdocker/************************************************************************/ /* */ /* CFITSIO Lexical Parser */ /* */ /* This file is one of 3 files containing code which parses an */ /* arithmetic expression and evaluates it in the context of an input */ /* FITS file table extension. The CFITSIO lexical parser is divided */ /* into the following 3 parts/files: the CFITSIO "front-end", */ /* eval_f.c, contains the interface between the user/CFITSIO and the */ /* real core of the parser; the FLEX interpreter, eval_l.c, takes the */ /* input string and parses it into tokens and identifies the FITS */ /* information required to evaluate the expression (ie, keywords and */ /* columns); and, the BISON grammar and evaluation routines, eval_y.c, */ /* receives the FLEX output and determines and performs the actual */ /* operations. The files eval_l.c and eval_y.c are produced from */ /* running flex and bison on the files eval.l and eval.y, respectively. */ /* (flex and bison are available from any GNU archive: see www.gnu.org) */ /* */ /* The grammar rules, rather than evaluating the expression in situ, */ /* builds a tree, or Nodal, structure mapping out the order of */ /* operations and expression dependencies. This "compilation" process */ /* allows for much faster processing of multiple rows. This technique */ /* was developed by Uwe Lammers of the XMM Science Analysis System, */ /* although the CFITSIO implementation is entirely code original. */ /* */ /* */ /* Modification History: */ /* */ /* Kent Blackburn c1992 Original parser code developed for the */ /* FTOOLS software package, in particular, */ /* the fselect task. */ /* Kent Blackburn c1995 BIT column support added */ /* Peter D Wilson Feb 1998 Vector column support added */ /* Peter D Wilson May 1998 Ported to CFITSIO library. User */ /* interface routines written, in essence */ /* making fselect, fcalc, and maketime */ /* capabilities available to all tools */ /* via single function calls. */ /* Peter D Wilson Jun 1998 Major rewrite of parser core, so as to */ /* create a run-time evaluation tree, */ /* inspired by the work of Uwe Lammers, */ /* resulting in a speed increase of */ /* 10-100 times. */ /* Peter D Wilson Jul 1998 gtifilter(a,b,c,d) function added */ /* Peter D Wilson Aug 1998 regfilter(a,b,c,d) function added */ /* Peter D Wilson Jul 1999 Make parser fitsfile-independent, */ /* allowing a purely vector-based usage */ /* Peter D Wilson Aug 1999 Add row-offset capability */ /* Peter D Wilson Sep 1999 Add row-range capability to ffcalc_rng */ /* */ /************************************************************************/ #include #include #include "eval_defs.h" #include "region.h" typedef struct { int datatype; /* Data type to cast parse results into for user */ void *dataPtr; /* Pointer to array of results, NULL if to use iterCol */ void *nullPtr; /* Pointer to nulval, use zero if NULL */ long maxRows; /* Max No. of rows to process, -1=all, 0=1 iteration */ int anyNull; /* Flag indicating at least 1 undef value encountered */ } parseInfo; /* Internal routines needed to allow the evaluator to operate on FITS data */ static void Setup_DataArrays( int nCols, iteratorCol *cols, long fRow, long nRows ); static int find_column( char *colName, void *itslval ); static int find_keywd ( char *key, void *itslval ); static int allocateCol( int nCol, int *status ); static int load_column( int varNum, long fRow, long nRows, void *data, char *undef ); static int DEBUG_PIXFILTER; #define FREE(x) { if (x) free(x); else printf("invalid free(" #x ") at %s:%d\n", __FILE__, __LINE__); } /*---------------------------------------------------------------------------*/ int fffrow( fitsfile *fptr, /* I - Input FITS file */ char *expr, /* I - Boolean expression */ long firstrow, /* I - First row of table to eval */ long nrows, /* I - Number of rows to evaluate */ long *n_good_rows, /* O - Number of rows eval to True */ char *row_status, /* O - Array of boolean results */ int *status ) /* O - Error status */ /* */ /* Evaluate a boolean expression using the indicated rows, returning an */ /* array of flags indicating which rows evaluated to TRUE/FALSE */ /*---------------------------------------------------------------------------*/ { parseInfo Info; int naxis, constant; long nelem, naxes[MAXDIMS], elem; char result; if( *status ) return( *status ); FFLOCK; if( ffiprs( fptr, 0, expr, MAXDIMS, &Info.datatype, &nelem, &naxis, naxes, status ) ) { ffcprs(); FFUNLOCK; return( *status ); } if( nelem<0 ) { constant = 1; nelem = -nelem; } else constant = 0; if( Info.datatype!=TLOGICAL || nelem!=1 ) { ffcprs(); ffpmsg("Expression does not evaluate to a logical scalar."); FFUNLOCK; return( *status = PARSE_BAD_TYPE ); } if( constant ) { /* No need to call parser... have result from ffiprs */ result = gParse.Nodes[gParse.resultNode].value.data.log; *n_good_rows = nrows; for( elem=0; elem1 ? firstrow : 1); Info.dataPtr = row_status; Info.nullPtr = NULL; Info.maxRows = nrows; if( ffiter( gParse.nCols, gParse.colData, firstrow-1, 0, parse_data, (void*)&Info, status ) == -1 ) *status = 0; /* -1 indicates exitted without error before end... OK */ if( *status ) { /***********************/ /* Error... Do nothing */ /***********************/ } else { /***********************************/ /* Count number of good rows found */ /***********************************/ *n_good_rows = 0L; for( elem=0; elemHDUposition != (infptr->Fptr)->curhdu ) ffmahd( infptr, (infptr->HDUposition) + 1, NULL, status ); if( *status ) { ffcprs(); FFUNLOCK; return( *status ); } inExt.rowLength = (long) (infptr->Fptr)->rowlength; inExt.numRows = (infptr->Fptr)->numrows; inExt.heapSize = (infptr->Fptr)->heapsize; if( inExt.numRows == 0 ) { /* Nothing to copy */ ffcprs(); FFUNLOCK; return( *status ); } if( outfptr->HDUposition != (outfptr->Fptr)->curhdu ) ffmahd( outfptr, (outfptr->HDUposition) + 1, NULL, status ); if( (outfptr->Fptr)->datastart < 0 ) ffrdef( outfptr, status ); if( *status ) { ffcprs(); FFUNLOCK; return( *status ); } outExt.rowLength = (long) (outfptr->Fptr)->rowlength; outExt.numRows = (outfptr->Fptr)->numrows; if( !outExt.numRows ) (outfptr->Fptr)->heapsize = 0L; outExt.heapSize = (outfptr->Fptr)->heapsize; if( inExt.rowLength != outExt.rowLength ) { ffpmsg("Output table has different row length from input"); ffcprs(); FFUNLOCK; return( *status = PARSE_BAD_OUTPUT ); } /***********************************/ /* Fill out Info data for parser */ /***********************************/ Info.dataPtr = (char *)malloc( (size_t) ((inExt.numRows + 1) * sizeof(char)) ); Info.nullPtr = NULL; Info.maxRows = (long) inExt.numRows; if( !Info.dataPtr ) { ffpmsg("Unable to allocate memory for row selection"); ffcprs(); FFUNLOCK; return( *status = MEMORY_ALLOCATION ); } /* make sure array is zero terminated */ ((char*)Info.dataPtr)[inExt.numRows] = 0; if( constant ) { /* Set all rows to the same value from constant result */ result = gParse.Nodes[gParse.resultNode].value.data.log; for( ntodo = 0; ntodo 1) ffirow( outfptr, outExt.numRows, nGood, status ); } do { if( ((char*)Info.dataPtr)[inloc-1] ) { ffgtbb( infptr, inloc, 1L, rdlen, buffer+rdlen*nbuff, status ); nbuff++; if( nbuff==maxrows ) { ffptbb( outfptr, outloc, 1L, rdlen*nbuff, buffer, status ); outloc += nbuff; nbuff = 0; } } inloc++; } while( !*status && inloc<=inExt.numRows ); if( nbuff ) { ffptbb( outfptr, outloc, 1L, rdlen*nbuff, buffer, status ); outloc += nbuff; } if( infptr==outfptr ) { if( outloc<=inExt.numRows ) ffdrow( infptr, outloc, inExt.numRows-outloc+1, status ); } else if( inExt.heapSize && nGood ) { /* Copy heap, if it exists and at least one row copied */ /********************************************************/ /* Get location information from the output extension */ /********************************************************/ if( outfptr->HDUposition != (outfptr->Fptr)->curhdu ) ffmahd( outfptr, (outfptr->HDUposition) + 1, NULL, status ); outExt.dataStart = (outfptr->Fptr)->datastart; outExt.heapStart = (outfptr->Fptr)->heapstart; /*************************************************/ /* Insert more space into outfptr if necessary */ /*************************************************/ hsize = outExt.heapStart + outExt.heapSize; freespace = (long) (( ( (hsize + 2879) / 2880) * 2880) - hsize); ntodo = inExt.heapSize; if ( (freespace - ntodo) < 0) { /* not enough existing space? */ ntodo = (ntodo - freespace + 2879) / 2880; /* number of blocks */ ffiblk(outfptr, (long) ntodo, 1, status); /* insert the blocks */ } ffukyj( outfptr, "PCOUNT", inExt.heapSize+outExt.heapSize, NULL, status ); /*******************************************************/ /* Get location information from the input extension */ /*******************************************************/ if( infptr->HDUposition != (infptr->Fptr)->curhdu ) ffmahd( infptr, (infptr->HDUposition) + 1, NULL, status ); inExt.dataStart = (infptr->Fptr)->datastart; inExt.heapStart = (infptr->Fptr)->heapstart; /**********************************/ /* Finally copy heap to outfptr */ /**********************************/ ntodo = inExt.heapSize; inbyteloc = inExt.heapStart + inExt.dataStart; outbyteloc = outExt.heapStart + outExt.dataStart + outExt.heapSize; while ( ntodo && !*status ) { rdlen = (long) minvalue(ntodo,500000); ffmbyt( infptr, inbyteloc, REPORT_EOF, status ); ffgbyt( infptr, rdlen, buffer, status ); ffmbyt( outfptr, outbyteloc, IGNORE_EOF, status ); ffpbyt( outfptr, rdlen, buffer, status ); inbyteloc += rdlen; outbyteloc += rdlen; ntodo -= rdlen; } /***********************************************************/ /* But must update DES if data is being appended to a */ /* pre-existing heap space. Edit each new entry in file */ /***********************************************************/ if( outExt.heapSize ) { LONGLONG repeat, offset, j; int i; for( i=1; i<=(outfptr->Fptr)->tfield; i++ ) { if( (outfptr->Fptr)->tableptr[i-1].tdatatype<0 ) { for( j=outExt.numRows+1; j<=outExt.numRows+nGood; j++ ) { ffgdesll( outfptr, i, j, &repeat, &offset, status ); offset += outExt.heapSize; ffpdes( outfptr, i, j, repeat, offset, status ); } } } } } /* End of HEAP copy */ FREE(buffer); } FREE(Info.dataPtr); ffcprs(); ffcmph(outfptr, status); /* compress heap, deleting any orphaned data */ FFUNLOCK; return(*status); } /*---------------------------------------------------------------------------*/ int ffcrow( fitsfile *fptr, /* I - Input FITS file */ int datatype, /* I - Datatype to return results as */ char *expr, /* I - Arithmetic expression */ long firstrow, /* I - First row to evaluate */ long nelements, /* I - Number of elements to return */ void *nulval, /* I - Ptr to value to use as UNDEF */ void *array, /* O - Array of results */ int *anynul, /* O - Were any UNDEFs encountered? */ int *status ) /* O - Error status */ /* */ /* Calculate an expression for the indicated rows of a table, returning */ /* the results, cast as datatype (TSHORT, TDOUBLE, etc), in array. If */ /* nulval==NULL, UNDEFs will be zeroed out. For vector results, the number */ /* of elements returned may be less than nelements if nelements is not an */ /* even multiple of the result dimension. Call fftexp to obtain the */ /* dimensions of the results. */ /*---------------------------------------------------------------------------*/ { parseInfo Info; int naxis; long nelem1, naxes[MAXDIMS]; if( *status ) return( *status ); FFLOCK; if( ffiprs( fptr, 0, expr, MAXDIMS, &Info.datatype, &nelem1, &naxis, naxes, status ) ) { ffcprs(); FFUNLOCK; return( *status ); } if( nelem1<0 ) nelem1 = - nelem1; if( nelements1 ? firstrow : 1); if( datatype ) Info.datatype = datatype; Info.dataPtr = array; Info.nullPtr = nulval; Info.maxRows = nelements / nelem1; if( ffiter( gParse.nCols, gParse.colData, firstrow-1, 0, parse_data, (void*)&Info, status ) == -1 ) *status=0; /* -1 indicates exitted without error before end... OK */ *anynul = Info.anyNull; ffcprs(); FFUNLOCK; return( *status ); } /*--------------------------------------------------------------------------*/ int ffcalc( fitsfile *infptr, /* I - Input FITS file */ char *expr, /* I - Arithmetic expression */ fitsfile *outfptr, /* I - Output fits file */ char *parName, /* I - Name of output parameter */ char *parInfo, /* I - Extra information on parameter */ int *status ) /* O - Error status */ /* */ /* Evaluate an expression for all rows of a table. Call ffcalc_rng with */ /* a row range of 1-MAX. */ { long start=1, end=LONG_MAX; return ffcalc_rng( infptr, expr, outfptr, parName, parInfo, 1, &start, &end, status ); } /*--------------------------------------------------------------------------*/ int ffcalc_rng( fitsfile *infptr, /* I - Input FITS file */ char *expr, /* I - Arithmetic expression */ fitsfile *outfptr, /* I - Output fits file */ char *parName, /* I - Name of output parameter */ char *parInfo, /* I - Extra information on parameter */ int nRngs, /* I - Row range info */ long *start, /* I - Row range info */ long *end, /* I - Row range info */ int *status ) /* O - Error status */ /* */ /* Evaluate an expression using the data in the input FITS file and place */ /* the results into either a column or keyword in the output fits file, */ /* depending on the value of parName (keywords normally prefixed with '#') */ /* and whether the expression evaluates to a constant or a table column. */ /* The logic is as follows: */ /* (1) If a column exists with name, parName, put results there. */ /* (2) If parName starts with '#', as in #NAXIS, put result there, */ /* with parInfo used as the comment. If expression does not evaluate */ /* to a constant, flag an error. */ /* (3) If a keyword exists with name, parName, and expression is a */ /* constant, put result there, using parInfo as the new comment. */ /* (4) Else, create a new column with name parName and TFORM parInfo. */ /* If parInfo is NULL, use a default data type for the column. */ /*--------------------------------------------------------------------------*/ { parseInfo Info; int naxis, constant, typecode, newNullKwd=0; long nelem, naxes[MAXDIMS], repeat, width; int col_cnt, colNo; Node *result; char card[81], tform[16], nullKwd[9], tdimKwd[9]; if( *status ) return( *status ); FFLOCK; if( ffiprs( infptr, 0, expr, MAXDIMS, &Info.datatype, &nelem, &naxis, naxes, status ) ) { ffcprs(); FFUNLOCK; return( *status ); } if( nelem<0 ) { constant = 1; nelem = -nelem; } else constant = 0; /* Case (1): If column exists put it there */ colNo = 0; if( ffgcno( outfptr, CASEINSEN, parName, &colNo, status )==COL_NOT_FOUND ) { /* Output column doesn't exist. Test for keyword. */ /* Case (2): Does parName indicate result should be put into keyword */ *status = 0; if( parName[0]=='#' ) { if( ! constant ) { ffcprs(); ffpmsg( "Cannot put tabular result into keyword (ffcalc)" ); FFUNLOCK; return( *status = PARSE_BAD_TYPE ); } parName++; /* Advance past '#' */ if ( (fits_strcasecmp(parName,"HISTORY") == 0 || fits_strcasecmp(parName,"COMMENT") == 0) && Info.datatype != TSTRING ) { ffcprs(); ffpmsg( "HISTORY and COMMENT values must be strings (ffcalc)" ); FFUNLOCK; return( *status = PARSE_BAD_TYPE ); } } else if( constant ) { /* Case (3): Does a keyword named parName already exist */ if( ffgcrd( outfptr, parName, card, status )==KEY_NO_EXIST ) { colNo = -1; } else if( *status ) { ffcprs(); FFUNLOCK; return( *status ); } } else colNo = -1; if( colNo<0 ) { /* Case (4): Create new column */ *status = 0; ffgncl( outfptr, &colNo, status ); colNo++; if( parInfo==NULL || *parInfo=='\0' ) { /* Figure out best default column type */ if( gParse.hdutype==BINARY_TBL ) { snprintf(tform,15,"%ld",nelem); switch( Info.datatype ) { case TLOGICAL: strcat(tform,"L"); break; case TLONG: strcat(tform,"J"); break; case TDOUBLE: strcat(tform,"D"); break; case TSTRING: strcat(tform,"A"); break; case TBIT: strcat(tform,"X"); break; case TLONGLONG: strcat(tform,"K"); break; } } else { switch( Info.datatype ) { case TLOGICAL: ffcprs(); ffpmsg("Cannot create LOGICAL column in ASCII table"); FFUNLOCK; return( *status = NOT_BTABLE ); case TLONG: strcpy(tform,"I11"); break; case TDOUBLE: strcpy(tform,"D23.15"); break; case TSTRING: case TBIT: snprintf(tform,16,"A%ld",nelem); break; } } parInfo = tform; } else if( !(isdigit((int) *parInfo)) && gParse.hdutype==BINARY_TBL ) { if( Info.datatype==TBIT && *parInfo=='B' ) nelem = (nelem+7)/8; snprintf(tform,16,"%ld%s",nelem,parInfo); parInfo = tform; } fficol( outfptr, colNo, parName, parInfo, status ); if( naxis>1 ) ffptdm( outfptr, colNo, naxis, naxes, status ); /* Setup TNULLn keyword in case NULLs are encountered */ ffkeyn("TNULL", colNo, nullKwd, status); if( ffgcrd( outfptr, nullKwd, card, status )==KEY_NO_EXIST ) { *status = 0; if( gParse.hdutype==BINARY_TBL ) { LONGLONG nullVal=0; fits_binary_tform( parInfo, &typecode, &repeat, &width, status ); if( typecode==TBYTE ) nullVal = UCHAR_MAX; else if( typecode==TSHORT ) nullVal = SHRT_MIN; else if( typecode==TINT ) nullVal = INT_MIN; else if( typecode==TLONG ) { if (sizeof(long) == 8 && sizeof(int) == 4) nullVal = INT_MIN; else nullVal = LONG_MIN; } else if( typecode==TLONGLONG ) nullVal = LONGLONG_MIN; if( nullVal ) { ffpkyj( outfptr, nullKwd, nullVal, "Null value", status ); fits_set_btblnull( outfptr, colNo, nullVal, status ); newNullKwd = 1; } } else if( gParse.hdutype==ASCII_TBL ) { ffpkys( outfptr, nullKwd, "NULL", "Null value string", status ); fits_set_atblnull( outfptr, colNo, "NULL", status ); newNullKwd = 1; } } } } else if( *status ) { ffcprs(); FFUNLOCK; return( *status ); } else { /********************************************************/ /* Check if a TDIM keyword should be written/updated. */ /********************************************************/ ffkeyn("TDIM", colNo, tdimKwd, status); ffgcrd( outfptr, tdimKwd, card, status ); if( *status==0 ) { /* TDIM exists, so update it with result's dimension */ ffptdm( outfptr, colNo, naxis, naxes, status ); } else if( *status==KEY_NO_EXIST ) { /* TDIM does not exist, so clear error stack and */ /* write a TDIM only if result is multi-dimensional */ *status = 0; ffcmsg(); if( naxis>1 ) ffptdm( outfptr, colNo, naxis, naxes, status ); } if( *status ) { /* Either some other error happened in ffgcrd */ /* or one happened in ffptdm */ ffcprs(); FFUNLOCK; return( *status ); } } if( colNo>0 ) { /* Output column exists (now)... put results into it */ int anyNull = 0; int nPerLp, i; long totaln; ffgkyj(infptr, "NAXIS2", &totaln, 0, status); /*************************************/ /* Create new iterator Output Column */ /*************************************/ col_cnt = gParse.nCols; if( allocateCol( col_cnt, status ) ) { ffcprs(); FFUNLOCK; return( *status ); } fits_iter_set_by_num( gParse.colData+col_cnt, outfptr, colNo, 0, OutputCol ); gParse.nCols++; for( i=0; i= 10) && (nRngs == 1) && (start[0] == 1) && (end[0] == totaln)) nPerLp = 0; else nPerLp = Info.maxRows; if( ffiter( gParse.nCols, gParse.colData, start[i]-1, nPerLp, parse_data, (void*)&Info, status ) == -1 ) *status = 0; else if( *status ) { ffcprs(); FFUNLOCK; return( *status ); } if( Info.anyNull ) anyNull = 1; } if( newNullKwd && !anyNull ) { ffdkey( outfptr, nullKwd, status ); } } else { /* Put constant result into keyword */ result = gParse.Nodes + gParse.resultNode; switch( Info.datatype ) { case TDOUBLE: ffukyd( outfptr, parName, result->value.data.dbl, 15, parInfo, status ); break; case TLONG: ffukyj( outfptr, parName, result->value.data.lng, parInfo, status ); break; case TLOGICAL: ffukyl( outfptr, parName, result->value.data.log, parInfo, status ); break; case TBIT: case TSTRING: if (fits_strcasecmp(parName,"HISTORY") == 0) { ffphis( outfptr, result->value.data.str, status); } else if (fits_strcasecmp(parName,"COMMENT") == 0) { ffpcom( outfptr, result->value.data.str, status); } else { ffukys( outfptr, parName, result->value.data.str, parInfo, status ); } break; } } ffcprs(); FFUNLOCK; return( *status ); } /*--------------------------------------------------------------------------*/ int fftexp( fitsfile *fptr, /* I - Input FITS file */ char *expr, /* I - Arithmetic expression */ int maxdim, /* I - Max Dimension of naxes */ int *datatype, /* O - Data type of result */ long *nelem, /* O - Vector length of result */ int *naxis, /* O - # of dimensions of result */ long *naxes, /* O - Size of each dimension */ int *status ) /* O - Error status */ /* */ /* Evaluate the given expression and return information on the result. */ /*--------------------------------------------------------------------------*/ { FFLOCK; ffiprs( fptr, 0, expr, maxdim, datatype, nelem, naxis, naxes, status ); ffcprs(); FFUNLOCK; return( *status ); } /*--------------------------------------------------------------------------*/ int ffiprs( fitsfile *fptr, /* I - Input FITS file */ int compressed, /* I - Is FITS file hkunexpanded? */ char *expr, /* I - Arithmetic expression */ int maxdim, /* I - Max Dimension of naxes */ int *datatype, /* O - Data type of result */ long *nelem, /* O - Vector length of result */ int *naxis, /* O - # of dimensions of result */ long *naxes, /* O - Size of each dimension */ int *status ) /* O - Error status */ /* */ /* Initialize the parser and determine what type of result the expression */ /* produces. */ /*--------------------------------------------------------------------------*/ { Node *result; int i,lexpr, tstatus = 0; int xaxis, bitpix; long xaxes[9]; static iteratorCol dmyCol; if( *status ) return( *status ); /* make sure all internal structures for this HDU are current */ if ( ffrdef(fptr, status) ) return(*status); /* Initialize the Parser structure */ gParse.def_fptr = fptr; gParse.compressed = compressed; gParse.nCols = 0; gParse.colData = NULL; gParse.varData = NULL; gParse.getData = find_column; gParse.loadData = load_column; gParse.Nodes = NULL; gParse.nNodesAlloc= 0; gParse.nNodes = 0; gParse.hdutype = 0; gParse.status = 0; fits_get_hdu_type(fptr, &gParse.hdutype, status ); if (gParse.hdutype == IMAGE_HDU) { fits_get_img_param(fptr, 9, &bitpix, &xaxis, xaxes, status); if (*status) { ffpmsg("ffiprs: unable to get image dimensions"); return( *status ); } gParse.totalRows = xaxis > 0 ? 1 : 0; for (i = 0; i < xaxis; ++i) gParse.totalRows *= xaxes[i]; if (DEBUG_PIXFILTER) printf("naxis=%d, gParse.totalRows=%ld\n", xaxis, gParse.totalRows); } else if( ffgkyj(fptr, "NAXIS2", &gParse.totalRows, 0, &tstatus) ) { /* this might be a 1D or null image with no NAXIS2 keyword */ gParse.totalRows = 0; } /* Copy expression into parser... read from file if necessary */ if( expr[0]=='@' ) { if( ffimport_file( expr+1, &gParse.expr, status ) ) return( *status ); lexpr = strlen(gParse.expr); } else { lexpr = strlen(expr); gParse.expr = (char*)malloc( (2+lexpr)*sizeof(char)); strcpy(gParse.expr,expr); } strcat(gParse.expr + lexpr,"\n"); gParse.index = 0; gParse.is_eobuf = 0; /* Parse the expression, building the Nodes and determing */ /* which columns are needed and what data type is returned */ ffrestart(NULL); if( ffparse() ) { return( *status = PARSE_SYNTAX_ERR ); } /* Check results */ *status = gParse.status; if( *status ) return(*status); if( !gParse.nNodes ) { ffpmsg("Blank expression"); return( *status = PARSE_SYNTAX_ERR ); } if( !gParse.nCols ) { dmyCol.fptr = fptr; /* This allows iterator to know value of */ gParse.colData = &dmyCol; /* fptr when no columns are referenced */ } result = gParse.Nodes + gParse.resultNode; *naxis = result->value.naxis; *nelem = result->value.nelem; for( i=0; i<*naxis && ivalue.naxes[i]; switch( result->type ) { case BOOLEAN: *datatype = TLOGICAL; break; case LONG: *datatype = TLONG; break; case DOUBLE: *datatype = TDOUBLE; break; case BITSTR: *datatype = TBIT; break; case STRING: *datatype = TSTRING; break; default: *datatype = 0; ffpmsg("Bad return data type"); *status = gParse.status = PARSE_BAD_TYPE; break; } gParse.datatype = *datatype; FREE(gParse.expr); if( result->operation==CONST_OP ) *nelem = - *nelem; return(*status); } /*--------------------------------------------------------------------------*/ void ffcprs( void ) /* No parameters */ /* */ /* Clear the parser, making it ready to accept a new expression. */ /*--------------------------------------------------------------------------*/ { int col, node, i; if( gParse.nCols > 0 ) { FREE( gParse.colData ); for( col=0; col 0 ) { node = gParse.nNodes; while( node-- ) { if( gParse.Nodes[node].operation==gtifilt_fct ) { i = gParse.Nodes[node].SubNodes[0]; if (gParse.Nodes[ i ].value.data.ptr) FREE( gParse.Nodes[ i ].value.data.ptr ); } else if( gParse.Nodes[node].operation==regfilt_fct ) { i = gParse.Nodes[node].SubNodes[0]; fits_free_region( (SAORegion *)gParse.Nodes[ i ].value.data.ptr ); } } gParse.nNodes = 0; } if( gParse.Nodes ) free( gParse.Nodes ); gParse.Nodes = NULL; gParse.hdutype = ANY_HDU; gParse.pixFilter = 0; } /*---------------------------------------------------------------------------*/ int parse_data( long totalrows, /* I - Total rows to be processed */ long offset, /* I - Number of rows skipped at start*/ long firstrow, /* I - First row of this iteration */ long nrows, /* I - Number of rows in this iter */ int nCols, /* I - Number of columns in use */ iteratorCol *colData, /* IO- Column information/data */ void *userPtr ) /* I - Data handling instructions */ /* */ /* Iterator work function which calls the parser and copies the results */ /* into either an OutputCol or a data pointer supplied in the userPtr */ /* structure. */ /*---------------------------------------------------------------------------*/ { int status, constant=0, anyNullThisTime=0; long jj, kk, idx, remain, ntodo; Node *result; iteratorCol * outcol; /* declare variables static to preserve their values between calls */ static void *Data, *Null; static int datasize; static long lastRow, repeat, resDataSize; static LONGLONG jnull; static parseInfo *userInfo; static long zeros[4] = {0,0,0,0}; if (DEBUG_PIXFILTER) printf("parse_data(total=%ld, offset=%ld, first=%ld, rows=%ld, cols=%d)\n", totalrows, offset, firstrow, nrows, nCols); /*--------------------------------------------------------*/ /* Initialization procedures: execute on the first call */ /*--------------------------------------------------------*/ outcol = colData + (nCols - 1); if (firstrow == offset+1) { userInfo = (parseInfo*)userPtr; userInfo->anyNull = 0; if( userInfo->maxRows>0 ) userInfo->maxRows = minvalue(totalrows,userInfo->maxRows); else if( userInfo->maxRows<0 ) userInfo->maxRows = totalrows; else userInfo->maxRows = nrows; lastRow = firstrow + userInfo->maxRows - 1; if( userInfo->dataPtr==NULL ) { if( outcol->iotype == InputCol ) { ffpmsg("Output column for parser results not found!"); return( PARSE_NO_OUTPUT ); } /* Data gets set later */ Null = outcol->array; userInfo->datatype = outcol->datatype; /* Check for a TNULL/BLANK keyword for output column/image */ status = 0; jnull = 0; if (gParse.hdutype == IMAGE_HDU) { if (gParse.pixFilter->blank) jnull = (LONGLONG) gParse.pixFilter->blank; } else { ffgknjj( outcol->fptr, "TNULL", outcol->colnum, 1, &jnull, (int*)&jj, &status ); if( status==BAD_INTKEY ) { /* Probably ASCII table with text TNULL keyword */ switch( userInfo->datatype ) { case TSHORT: jnull = (LONGLONG) SHRT_MIN; break; case TINT: jnull = (LONGLONG) INT_MIN; break; case TLONG: jnull = (LONGLONG) LONG_MIN; break; } } } repeat = outcol->repeat; /* if (DEBUG_PIXFILTER) printf("parse_data: using null value %ld\n", jnull); */ } else { Data = userInfo->dataPtr; Null = (userInfo->nullPtr ? userInfo->nullPtr : zeros); repeat = gParse.Nodes[gParse.resultNode].value.nelem; } /* Determine the size of each element of the returned result */ switch( userInfo->datatype ) { case TBIT: /* Fall through to TBYTE */ case TLOGICAL: /* Fall through to TBYTE */ case TBYTE: datasize = sizeof(char); break; case TSHORT: datasize = sizeof(short); break; case TINT: datasize = sizeof(int); break; case TLONG: datasize = sizeof(long); break; case TLONGLONG: datasize = sizeof(LONGLONG); break; case TFLOAT: datasize = sizeof(float); break; case TDOUBLE: datasize = sizeof(double); break; case TSTRING: datasize = sizeof(char*); break; } /* Determine the size of each element of the calculated result */ /* (only matters for numeric/logical data) */ switch( gParse.Nodes[gParse.resultNode].type ) { case BOOLEAN: resDataSize = sizeof(char); break; case LONG: resDataSize = sizeof(long); break; case DOUBLE: resDataSize = sizeof(double); break; } } /*-------------------------------------------*/ /* Main loop: process all the rows of data */ /*-------------------------------------------*/ /* If writing to output column, set first element to appropriate */ /* null value. If no NULLs encounter, zero out before returning. */ /* if (DEBUG_PIXFILTER) printf("parse_data: using null value %ld\n", jnull); */ if( userInfo->dataPtr == NULL ) { /* First, reset Data pointer to start of output array */ Data = (char*) outcol->array + datasize; switch( userInfo->datatype ) { case TLOGICAL: *(char *)Null = 'U'; break; case TBYTE: *(char *)Null = (char )jnull; break; case TSHORT: *(short *)Null = (short)jnull; break; case TINT: *(int *)Null = (int )jnull; break; case TLONG: *(long *)Null = (long )jnull; break; case TLONGLONG: *(LONGLONG *)Null = (LONGLONG )jnull; break; case TFLOAT: *(float *)Null = FLOATNULLVALUE; break; case TDOUBLE: *(double*)Null = DOUBLENULLVALUE; break; case TSTRING: (*(char **)Null)[0] = '\1'; (*(char **)Null)[1] = '\0'; break; } } /* Alter nrows in case calling routine didn't want to do all rows */ nrows = minvalue(nrows,lastRow-firstrow+1); Setup_DataArrays( nCols, colData, firstrow, nrows ); /* Parser allocates arrays for each column and calculation it performs. */ /* Limit number of rows processed during each pass to reduce memory */ /* requirements... In most cases, iterator will limit rows to less */ /* than 2500 rows per iteration, so this is really only relevant for */ /* hk-compressed files which must be decompressed in memory and sent */ /* whole to parse_data in a single iteration. */ remain = nrows; while( remain ) { ntodo = minvalue(remain,2500); Evaluate_Parser ( firstrow, ntodo ); if( gParse.status ) break; firstrow += ntodo; remain -= ntodo; /* Copy results into data array */ result = gParse.Nodes + gParse.resultNode; if( result->operation==CONST_OP ) constant = 1; switch( result->type ) { case BOOLEAN: case LONG: case DOUBLE: if( constant ) { char undef=0; for( kk=0; kkvalue.data), &undef, result->value.nelem /* 1 */, userInfo->datatype, Null, (char*)Data + (kk*repeat+jj)*datasize, &anyNullThisTime, &gParse.status ); } else { if ( repeat == result->value.nelem ) { ffcvtn( gParse.datatype, result->value.data.ptr, result->value.undef, result->value.nelem*ntodo, userInfo->datatype, Null, Data, &anyNullThisTime, &gParse.status ); } else if( result->value.nelem == 1 ) { for( kk=0; kkvalue.data.ptr + kk*resDataSize, (char*)result->value.undef + kk, 1, userInfo->datatype, Null, (char*)Data + (kk*repeat+jj)*datasize, &anyNullThisTime, &gParse.status ); } } else { int nCopy; nCopy = minvalue( repeat, result->value.nelem ); for( kk=0; kkvalue.data.ptr + kk*result->value.nelem*resDataSize, (char*)result->value.undef + kk*result->value.nelem, nCopy, userInfo->datatype, Null, (char*)Data + (kk*repeat)*datasize, &anyNullThisTime, &gParse.status ); if( nCopy < repeat ) { memset( (char*)Data + (kk*repeat+nCopy)*datasize, 0, (repeat-nCopy)*datasize); } } } if( result->operation>0 ) { FREE( result->value.data.ptr ); } } if( gParse.status==OVERFLOW_ERR ) { gParse.status = NUM_OVERFLOW; ffpmsg("Numerical overflow while converting expression to necessary datatype"); } break; case BITSTR: switch( userInfo->datatype ) { case TBYTE: idx = -1; for( kk=0; kkvalue.nelem; jj++ ) { if( jj%8 == 0 ) ((char*)Data)[++idx] = 0; if( constant ) { if( result->value.data.str[jj]=='1' ) ((char*)Data)[idx] |= 128>>(jj%8); } else { if( result->value.data.strptr[kk][jj]=='1' ) ((char*)Data)[idx] |= 128>>(jj%8); } } } break; case TBIT: case TLOGICAL: if( constant ) { for( kk=0; kkvalue.nelem; jj++ ) { ((char*)Data)[ jj+kk*result->value.nelem ] = ( result->value.data.str[jj]=='1' ); } } else { for( kk=0; kkvalue.nelem; jj++ ) { ((char*)Data)[ jj+kk*result->value.nelem ] = ( result->value.data.strptr[kk][jj]=='1' ); } } break; case TSTRING: if( constant ) { for( jj=0; jjvalue.data.str ); } } else { for( jj=0; jjvalue.data.strptr[jj] ); } } break; default: ffpmsg("Cannot convert bit expression to desired type."); gParse.status = PARSE_BAD_TYPE; break; } if( result->operation>0 ) { FREE( result->value.data.strptr[0] ); FREE( result->value.data.strptr ); } break; case STRING: if( userInfo->datatype==TSTRING ) { if( constant ) { for( jj=0; jjvalue.data.str ); } else { for( jj=0; jjvalue.undef[jj] ) { anyNullThisTime = 1; strcpy( ((char**)Data)[jj], *(char **)Null ); } else { strcpy( ((char**)Data)[jj], result->value.data.strptr[jj] ); } } } else { ffpmsg("Cannot convert string expression to desired type."); gParse.status = PARSE_BAD_TYPE; } if( result->operation>0 ) { FREE( result->value.data.strptr[0] ); FREE( result->value.data.strptr ); } break; } if( gParse.status ) break; /* Increment Data to point to where the next block should go */ if( result->type==BITSTR && userInfo->datatype==TBYTE ) Data = (char*)Data + datasize * ( (result->value.nelem+7)/8 ) * ntodo; else if( result->type==STRING ) Data = (char*)Data + datasize * ntodo; else Data = (char*)Data + datasize * ntodo * repeat; } /* If no NULLs encountered during this pass, set Null value to */ /* zero to make the writing of the output column data faster */ if( anyNullThisTime ) userInfo->anyNull = 1; else if( userInfo->dataPtr == NULL ) { if( userInfo->datatype == TSTRING ) memcpy( *(char **)Null, zeros, 2 ); else memcpy( Null, zeros, datasize ); } /*-------------------------------------------------------*/ /* Clean up procedures: after processing all the rows */ /*-------------------------------------------------------*/ /* if the calling routine specified that only a limited number */ /* of rows in the table should be processed, return a value of -1 */ /* once all the rows have been done, if no other error occurred. */ if (gParse.hdutype != IMAGE_HDU && firstrow - 1 == lastRow) { if (!gParse.status && userInfo->maxRowsiotype == OutputCol ) continue; nelem = varData->nelem; len = nelem * nRows; switch ( varData->type ) { case BITSTR: /* No need for UNDEF array, but must make string DATA array */ len = (nelem+1)*nRows; /* Count '\0' */ bitStrs = (char**)varData->data; if( bitStrs ) FREE( bitStrs[0] ); free( bitStrs ); bitStrs = (char**)malloc( nRows*sizeof(char*) ); if( bitStrs==NULL ) { varData->data = varData->undef = NULL; gParse.status = MEMORY_ALLOCATION; break; } bitStrs[0] = (char*)malloc( len*sizeof(char) ); if( bitStrs[0]==NULL ) { free( bitStrs ); varData->data = varData->undef = NULL; gParse.status = MEMORY_ALLOCATION; break; } for( row=0; rowarray)[idx] & (1<<(7-len%8)) ) bitStrs[row][len] = '1'; else bitStrs[row][len] = '0'; if( len%8==7 ) idx++; } bitStrs[row][len] = '\0'; } varData->undef = (char*)bitStrs; varData->data = (char*)bitStrs; break; case STRING: sptr = (char**)icol->array; if (varData->undef) free( varData->undef ); varData->undef = (char*)malloc( nRows*sizeof(char) ); if( varData->undef==NULL ) { gParse.status = MEMORY_ALLOCATION; break; } row = nRows; while( row-- ) varData->undef[row] = ( **sptr != '\0' && FSTRCMP( sptr[0], sptr[row+1] )==0 ); varData->data = sptr + 1; break; case BOOLEAN: barray = (char*)icol->array; if (varData->undef) free( varData->undef ); varData->undef = (char*)malloc( len*sizeof(char) ); if( varData->undef==NULL ) { gParse.status = MEMORY_ALLOCATION; break; } while( len-- ) { varData->undef[len] = ( barray[0]!=0 && barray[0]==barray[len+1] ); } varData->data = barray + 1; break; case LONG: iarray = (long*)icol->array; if (varData->undef) free( varData->undef ); varData->undef = (char*)malloc( len*sizeof(char) ); if( varData->undef==NULL ) { gParse.status = MEMORY_ALLOCATION; break; } while( len-- ) { varData->undef[len] = ( iarray[0]!=0L && iarray[0]==iarray[len+1] ); } varData->data = iarray + 1; break; case DOUBLE: rarray = (double*)icol->array; if (varData->undef) free( varData->undef ); varData->undef = (char*)malloc( len*sizeof(char) ); if( varData->undef==NULL ) { gParse.status = MEMORY_ALLOCATION; break; } while( len-- ) { varData->undef[len] = ( rarray[0]!=0.0 && rarray[0]==rarray[len+1]); } varData->data = rarray + 1; break; default: snprintf(msg, 80, "SetupDataArrays, unhandled type %d\n", varData->type); ffpmsg(msg); } if( gParse.status ) { /* Deallocate NULL arrays of previous columns */ while( i-- ) { varData = gParse.varData + i; if( varData->type==BITSTR ) FREE( ((char**)varData->data)[0] ); FREE( varData->undef ); varData->undef = NULL; } return; } } } /*--------------------------------------------------------------------------*/ int ffcvtn( int inputType, /* I - Data type of input array */ void *input, /* I - Input array of type inputType */ char *undef, /* I - Array of flags indicating UNDEF elems */ long ntodo, /* I - Number of elements to process */ int outputType, /* I - Data type of output array */ void *nulval, /* I - Ptr to value to use for UNDEF elements */ void *output, /* O - Output array of type outputType */ int *anynull, /* O - Any nulls flagged? */ int *status ) /* O - Error status */ /* */ /* Convert an array of any input data type to an array of any output */ /* data type, using an array of UNDEF flags to assign nulvals to */ /*--------------------------------------------------------------------------*/ { long i; switch( outputType ) { case TLOGICAL: switch( inputType ) { case TLOGICAL: case TBYTE: for( i=0; i UCHAR_MAX ) { *status = OVERFLOW_ERR; ((unsigned char*)output)[i] = UCHAR_MAX; } else ((unsigned char*)output)[i] = (unsigned char) ((long*)input)[i]; } } return( *status ); case TFLOAT: fffr4i1((float*)input,ntodo,1.,0.,0,0,NULL,NULL, (unsigned char*)output,status); break; case TDOUBLE: fffr8i1((double*)input,ntodo,1.,0.,0,0,NULL,NULL, (unsigned char*)output,status); break; default: *status = BAD_DATATYPE; break; } for(i=0;i SHRT_MAX ) { *status = OVERFLOW_ERR; ((short*)output)[i] = SHRT_MAX; } else ((short*)output)[i] = (short) ((long*)input)[i]; } } return( *status ); case TFLOAT: fffr4i2((float*)input,ntodo,1.,0.,0,0,NULL,NULL, (short*)output,status); break; case TDOUBLE: fffr8i2((double*)input,ntodo,1.,0.,0,0,NULL,NULL, (short*)output,status); break; default: *status = BAD_DATATYPE; break; } for(i=0;i=0 ) { found[parNo] = 1; /* Flag this parameter as found */ switch( gParse.colData[parNo].datatype ) { case TLONG: ffgcvj( fptr, gParse.valCol, row, 1L, 1L, ((long*)gParse.colData[parNo].array)[0], ((long*)gParse.colData[parNo].array)+currelem, &anynul, status ); break; case TDOUBLE: ffgcvd( fptr, gParse.valCol, row, 1L, 1L, ((double*)gParse.colData[parNo].array)[0], ((double*)gParse.colData[parNo].array)+currelem, &anynul, status ); break; case TSTRING: ffgcvs( fptr, gParse.valCol, row, 1L, 1L, ((char**)gParse.colData[parNo].array)[0], ((char**)gParse.colData[parNo].array)+currelem, &anynul, status ); break; } if( *status ) return( *status ); } } if( currelemoperation==CONST_OP ) { if( result->value.data.log ) { *(long*)userPtr = firstrow; return( -1 ); } } else { for( idx=0; idxvalue.data.logptr[idx] && !result->value.undef[idx] ) { *(long*)userPtr = firstrow + idx; return( -1 ); } } } return( gParse.status ); } static int set_image_col_types (fitsfile * fptr, const char * name, int bitpix, DataInfo * varInfo, iteratorCol *colIter) { int istatus; double tscale, tzero; char temp[80]; switch (bitpix) { case BYTE_IMG: case SHORT_IMG: case LONG_IMG: istatus = 0; if (fits_read_key(fptr, TDOUBLE, "BZERO", &tzero, NULL, &istatus)) tzero = 0.0; istatus = 0; if (fits_read_key(fptr, TDOUBLE, "BSCALE", &tscale, NULL, &istatus)) tscale = 1.0; if (tscale == 1.0 && (tzero == 0.0 || tzero == 32768.0 )) { varInfo->type = LONG; colIter->datatype = TLONG; } else { varInfo->type = DOUBLE; colIter->datatype = TDOUBLE; if (DEBUG_PIXFILTER) printf("use DOUBLE for %s with BSCALE=%g/BZERO=%g\n", name, tscale, tzero); } break; case LONGLONG_IMG: case FLOAT_IMG: case DOUBLE_IMG: varInfo->type = DOUBLE; colIter->datatype = TDOUBLE; break; default: snprintf(temp, 80,"set_image_col_types: unrecognized image bitpix [%d]\n", bitpix); ffpmsg(temp); return gParse.status = PARSE_BAD_TYPE; } return 0; } /************************************************************************* Functions used by the evaluator to access FITS data (find_column, find_keywd, allocateCol, load_column) *************************************************************************/ static int find_column( char *colName, void *itslval ) { FFSTYPE *thelval = (FFSTYPE*)itslval; int col_cnt, status; int colnum, typecode, type; long repeat, width; fitsfile *fptr; char temp[80]; double tzero,tscale; int istatus; DataInfo *varInfo; iteratorCol *colIter; if (DEBUG_PIXFILTER) printf("find_column(%s)\n", colName); if( *colName == '#' ) return( find_keywd( colName + 1, itslval ) ); fptr = gParse.def_fptr; status = 0; col_cnt = gParse.nCols; if (gParse.hdutype == IMAGE_HDU) { int i; if (!gParse.pixFilter) { gParse.status = COL_NOT_FOUND; ffpmsg("find_column: IMAGE_HDU but no PixelFilter"); return pERROR; } colnum = -1; for (i = 0; i < gParse.pixFilter->count; ++i) { if (!fits_strcasecmp(colName, gParse.pixFilter->tag[i])) colnum = i; } if (colnum < 0) { snprintf(temp, 80, "find_column: PixelFilter tag %s not found", colName); ffpmsg(temp); gParse.status = COL_NOT_FOUND; return pERROR; } if( allocateCol( col_cnt, &gParse.status ) ) return pERROR; varInfo = gParse.varData + col_cnt; colIter = gParse.colData + col_cnt; fptr = gParse.pixFilter->ifptr[colnum]; fits_get_img_param(fptr, MAXDIMS, &typecode, /* actually bitpix */ &varInfo->naxis, &varInfo->naxes[0], &status); varInfo->nelem = 1; type = COLUMN; if (set_image_col_types(fptr, colName, typecode, varInfo, colIter)) return pERROR; colIter->fptr = fptr; colIter->iotype = InputCol; } else { /* HDU holds a table */ if( gParse.compressed ) colnum = gParse.valCol; else if( fits_get_colnum( fptr, CASEINSEN, colName, &colnum, &status ) ) { if( status == COL_NOT_FOUND ) { type = find_keywd( colName, itslval ); if( type != pERROR ) ffcmsg(); return( type ); } gParse.status = status; return pERROR; } if( fits_get_coltype( fptr, colnum, &typecode, &repeat, &width, &status ) ) { gParse.status = status; return pERROR; } if( allocateCol( col_cnt, &gParse.status ) ) return pERROR; varInfo = gParse.varData + col_cnt; colIter = gParse.colData + col_cnt; fits_iter_set_by_num( colIter, fptr, colnum, 0, InputCol ); } /* Make sure we don't overflow variable name array */ strncpy(varInfo->name,colName,MAXVARNAME); varInfo->name[MAXVARNAME] = '\0'; if (gParse.hdutype != IMAGE_HDU) { switch( typecode ) { case TBIT: varInfo->type = BITSTR; colIter->datatype = TBYTE; type = BITCOL; break; case TBYTE: case TSHORT: case TLONG: /* The datatype of column with TZERO and TSCALE keywords might be float or double. */ snprintf(temp,80,"TZERO%d",colnum); istatus = 0; if(fits_read_key(fptr,TDOUBLE,temp,&tzero,NULL,&istatus)) { tzero = 0.0; } snprintf(temp,80,"TSCAL%d",colnum); istatus = 0; if(fits_read_key(fptr,TDOUBLE,temp,&tscale,NULL,&istatus)) { tscale = 1.0; } if (tscale == 1.0 && (tzero == 0.0 || tzero == 32768.0 )) { varInfo->type = LONG; colIter->datatype = TLONG; /* Reading an unsigned long column as a long can cause overflow errors. Treat the column as a double instead. } else if (tscale == 1.0 && tzero == 2147483648.0 ) { varInfo->type = LONG; colIter->datatype = TULONG; */ } else { varInfo->type = DOUBLE; colIter->datatype = TDOUBLE; } type = COLUMN; break; /* For now, treat 8-byte integer columns as type double. This can lose precision, so the better long term solution will be to add support for TLONGLONG as a separate datatype. */ case TLONGLONG: case TFLOAT: case TDOUBLE: varInfo->type = DOUBLE; colIter->datatype = TDOUBLE; type = COLUMN; break; case TLOGICAL: varInfo->type = BOOLEAN; colIter->datatype = TLOGICAL; type = BCOLUMN; break; case TSTRING: varInfo->type = STRING; colIter->datatype = TSTRING; type = SCOLUMN; if ( width >= MAX_STRLEN ) { snprintf(temp, 80, "column %d is wider than maximum %d characters", colnum, MAX_STRLEN-1); ffpmsg(temp); gParse.status = PARSE_LRG_VECTOR; return pERROR; } if( gParse.hdutype == ASCII_TBL ) repeat = width; break; default: if (typecode < 0) { snprintf(temp, 80,"variable-length array columns are not supported. typecode = %d", typecode); ffpmsg(temp); } gParse.status = PARSE_BAD_TYPE; return pERROR; } varInfo->nelem = repeat; if( repeat>1 && typecode!=TSTRING ) { if( fits_read_tdim( fptr, colnum, MAXDIMS, &varInfo->naxis, &varInfo->naxes[0], &status ) ) { gParse.status = status; return pERROR; } } else { varInfo->naxis = 1; varInfo->naxes[0] = 1; } } gParse.nCols++; thelval->lng = col_cnt; return( type ); } static int find_keywd(char *keyname, void *itslval ) { FFSTYPE *thelval = (FFSTYPE*)itslval; int status, type; char keyvalue[FLEN_VALUE], dtype; fitsfile *fptr; double rval; int bval; long ival; status = 0; fptr = gParse.def_fptr; if( fits_read_keyword( fptr, keyname, keyvalue, NULL, &status ) ) { if( status == KEY_NO_EXIST ) { /* Do this since ffgkey doesn't put an error message on stack */ snprintf(keyvalue,FLEN_VALUE, "ffgkey could not find keyword: %s",keyname); ffpmsg(keyvalue); } gParse.status = status; return( pERROR ); } if( fits_get_keytype( keyvalue, &dtype, &status ) ) { gParse.status = status; return( pERROR ); } switch( dtype ) { case 'C': fits_read_key_str( fptr, keyname, keyvalue, NULL, &status ); type = STRING; strcpy( thelval->str , keyvalue ); break; case 'L': fits_read_key_log( fptr, keyname, &bval, NULL, &status ); type = BOOLEAN; thelval->log = bval; break; case 'I': fits_read_key_lng( fptr, keyname, &ival, NULL, &status ); type = LONG; thelval->lng = ival; break; case 'F': fits_read_key_dbl( fptr, keyname, &rval, NULL, &status ); type = DOUBLE; thelval->dbl = rval; break; default: type = pERROR; break; } if( status ) { gParse.status=status; return pERROR; } return( type ); } static int allocateCol( int nCol, int *status ) { if( (nCol%25)==0 ) { if( nCol ) { gParse.colData = (iteratorCol*) realloc( gParse.colData, (nCol+25)*sizeof(iteratorCol) ); gParse.varData = (DataInfo *) realloc( gParse.varData, (nCol+25)*sizeof(DataInfo) ); } else { gParse.colData = (iteratorCol*) malloc( 25*sizeof(iteratorCol) ); gParse.varData = (DataInfo *) malloc( 25*sizeof(DataInfo) ); } if( gParse.colData == NULL || gParse.varData == NULL ) { if( gParse.colData ) free(gParse.colData); if( gParse.varData ) free(gParse.varData); gParse.colData = NULL; gParse.varData = NULL; return( *status = MEMORY_ALLOCATION ); } } gParse.varData[nCol].data = NULL; gParse.varData[nCol].undef = NULL; return 0; } static int load_column( int varNum, long fRow, long nRows, void *data, char *undef ) { iteratorCol *var = gParse.colData+varNum; long nelem,nbytes,row,len,idx; char **bitStrs, msg[80]; unsigned char *bytes; int status = 0, anynul; if (gParse.hdutype == IMAGE_HDU) { /* This test would need to be on a per varNum basis to support * cross HDU operations */ fits_read_imgnull(var->fptr, var->datatype, fRow, nRows, data, undef, &anynul, &status); if (DEBUG_PIXFILTER) printf("load_column: IMAGE_HDU fRow=%ld, nRows=%ld => %d\n", fRow, nRows, status); } else { nelem = nRows * var->repeat; switch( var->datatype ) { case TBYTE: nbytes = ((var->repeat+7)/8) * nRows; bytes = (unsigned char *)malloc( nbytes * sizeof(char) ); ffgcvb(var->fptr, var->colnum, fRow, 1L, nbytes, 0, bytes, &anynul, &status); nelem = var->repeat; bitStrs = (char **)data; for( row=0; rowfptr, var->colnum, fRow, 1L, nRows, (char **)data, undef, &anynul, &status); break; case TLOGICAL: ffgcfl(var->fptr, var->colnum, fRow, 1L, nelem, (char *)data, undef, &anynul, &status); break; case TLONG: ffgcfj(var->fptr, var->colnum, fRow, 1L, nelem, (long *)data, undef, &anynul, &status); break; case TDOUBLE: ffgcfd(var->fptr, var->colnum, fRow, 1L, nelem, (double *)data, undef, &anynul, &status); break; default: snprintf(msg,80,"load_column: unexpected datatype %d", var->datatype); ffpmsg(msg); } } if( status ) { gParse.status = status; return pERROR; } return 0; } /*--------------------------------------------------------------------------*/ int fits_pixel_filter (PixelFilter * filter, int * status) /* Evaluate an expression using the data in the input FITS file(s) */ /*--------------------------------------------------------------------------*/ { parseInfo Info = { 0 }; int naxis, bitpix; long nelem, naxes[MAXDIMS]; int col_cnt; Node *result; int datatype; fitsfile * infptr; fitsfile * outfptr; char * DEFAULT_TAGS[] = { "X" }; char msg[256]; int writeBlankKwd = 0; /* write BLANK if any output nulls? */ DEBUG_PIXFILTER = getenv("DEBUG_PIXFILTER") ? 1 : 0; if (*status) return (*status); FFLOCK; if (!filter->tag || !filter->tag[0] || !filter->tag[0][0]) { filter->tag = DEFAULT_TAGS; if (DEBUG_PIXFILTER) printf("using default tag '%s'\n", filter->tag[0]); } infptr = filter->ifptr[0]; outfptr = filter->ofptr; gParse.pixFilter = filter; if (ffiprs(infptr, 0, filter->expression, MAXDIMS, &Info.datatype, &nelem, &naxis, naxes, status)) { goto CLEANUP; } if (nelem < 0) { nelem = -nelem; } { /* validate result type */ const char * type = 0; switch (Info.datatype) { case TLOGICAL: type = "LOGICAL"; break; case TLONG: type = "LONG"; break; case TDOUBLE: type = "DOUBLE"; break; case TSTRING: type = "STRING"; *status = pERROR; ffpmsg("pixel_filter: cannot have string image"); case TBIT: type = "BIT"; if (DEBUG_PIXFILTER) printf("hmm, image from bits?\n"); break; default: type = "UNKNOWN?!"; *status = pERROR; ffpmsg("pixel_filter: unexpected result datatype"); } if (DEBUG_PIXFILTER) printf("result type is %s [%d]\n", type, Info.datatype); if (*status) goto CLEANUP; } if (fits_get_img_param(infptr, MAXDIMS, &bitpix, &naxis, &naxes[0], status)) { ffpmsg("pixel_filter: unable to read input image parameters"); goto CLEANUP; } if (DEBUG_PIXFILTER) printf("input bitpix %d\n", bitpix); if (Info.datatype == TDOUBLE) { /* for floating point expressions, set the default output image to bitpix = -32 (float) unless the default is already a double */ if (bitpix != DOUBLE_IMG) bitpix = FLOAT_IMG; } /* override output image bitpix if specified by caller */ if (filter->bitpix) bitpix = filter->bitpix; if (DEBUG_PIXFILTER) printf("output bitpix %d\n", bitpix); if (fits_create_img(outfptr, bitpix, naxis, naxes, status)) { ffpmsg("pixel_filter: unable to create output image"); goto CLEANUP; } /* transfer keycards */ { int i, ncards, more; if (fits_get_hdrspace(infptr, &ncards, &more, status)) { ffpmsg("pixel_filter: unable to determine number of keycards"); goto CLEANUP; } for (i = 1; i <= ncards; ++i) { int keyclass; char card[FLEN_CARD]; if (fits_read_record(infptr, i, card, status)) { snprintf(msg, 256,"pixel_filter: unable to read keycard %d", i); ffpmsg(msg); goto CLEANUP; } keyclass = fits_get_keyclass(card); if (keyclass == TYP_STRUC_KEY) { /* output structure defined by fits_create_img */ } else if (keyclass == TYP_COMM_KEY && i < 12) { /* assume this is one of the FITS standard comments */ } else if (keyclass == TYP_NULL_KEY && bitpix < 0) { /* do not transfer BLANK to real output image */ } else if (keyclass == TYP_SCAL_KEY && bitpix < 0) { /* do not transfer BZERO, BSCALE to real output image */ } else if (fits_write_record(outfptr, card, status)) { snprintf(msg,256, "pixel_filter: unable to write keycard '%s' [%d]\n", card, *status); ffpmsg(msg); goto CLEANUP; } } } switch (bitpix) { case BYTE_IMG: datatype = TLONG; Info.datatype = TBYTE; break; case SHORT_IMG: datatype = TLONG; Info.datatype = TSHORT; break; case LONG_IMG: datatype = TLONG; Info.datatype = TLONG; break; case FLOAT_IMG: datatype = TDOUBLE; Info.datatype = TFLOAT; break; case DOUBLE_IMG: datatype = TDOUBLE; Info.datatype = TDOUBLE; break; default: snprintf(msg, 256,"pixel_filter: unexpected output bitpix %d\n", bitpix); ffpmsg(msg); *status = pERROR; goto CLEANUP; } if (bitpix > 0) { /* arrange for NULLs in output */ long nullVal = filter->blank; if (!filter->blank) { int tstatus = 0; if (fits_read_key_lng(infptr, "BLANK", &nullVal, 0, &tstatus)) { writeBlankKwd = 1; if (bitpix == BYTE_IMG) nullVal = UCHAR_MAX; else if (bitpix == SHORT_IMG) nullVal = SHRT_MIN; else if (bitpix == LONG_IMG) { if (sizeof(long) == 8 && sizeof(int) == 4) nullVal = INT_MIN; else nullVal = LONG_MIN; } else printf("unhandled positive output BITPIX %d\n", bitpix); } filter->blank = nullVal; } fits_set_imgnull(outfptr, filter->blank, status); if (DEBUG_PIXFILTER) printf("using blank %ld\n", nullVal); } if (!filter->keyword[0]) { iteratorCol * colIter; DataInfo * varInfo; /*************************************/ /* Create new iterator Output Column */ /*************************************/ col_cnt = gParse.nCols; if (allocateCol(col_cnt, status)) goto CLEANUP; gParse.nCols++; colIter = &gParse.colData[col_cnt]; colIter->fptr = filter->ofptr; colIter->iotype = OutputCol; varInfo = &gParse.varData[col_cnt]; set_image_col_types(colIter->fptr, "CREATED", bitpix, varInfo, colIter); Info.maxRows = -1; if (ffiter(gParse.nCols, gParse.colData, 0, 0, parse_data, &Info, status) == -1) *status = 0; else if (*status) goto CLEANUP; if (Info.anyNull) { if (writeBlankKwd) { fits_update_key_lng(outfptr, "BLANK", filter->blank, "NULL pixel value", status); if (*status) ffpmsg("pixel_filter: unable to write BLANK keyword"); if (DEBUG_PIXFILTER) { printf("output has NULLs\n"); printf("wrote blank [%d]\n", *status); } } } else if (bitpix > 0) /* never used a null */ if (fits_set_imgnull(outfptr, -1234554321, status)) ffpmsg("pixel_filter: unable to reset imgnull"); } else { /* Put constant result into keyword */ char * parName = filter->keyword; char * parInfo = filter->comment; result = gParse.Nodes + gParse.resultNode; switch (Info.datatype) { case TDOUBLE: ffukyd(outfptr, parName, result->value.data.dbl, 15, parInfo, status); break; case TLONG: ffukyj(outfptr, parName, result->value.data.lng, parInfo, status); break; case TLOGICAL: ffukyl(outfptr, parName, result->value.data.log, parInfo, status); break; case TBIT: case TSTRING: ffukys(outfptr, parName, result->value.data.str, parInfo, status); break; default: snprintf(msg, 256,"pixel_filter: unexpected constant result type [%d]\n", Info.datatype); ffpmsg(msg); } } CLEANUP: ffcprs(); FFUNLOCK; return (*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/eval_l.c0000644000175100001710000021036200000000000017535 0ustar00vstsdocker #line 3 "" #define FF_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define FF_FLEX_MAJOR_VERSION 2 #define FF_FLEX_MINOR_VERSION 5 #define FF_FLEX_SUBMINOR_VERSION 35 #if FF_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; typedef uint64_t flex_uint64_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! FLEXINT_H */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define FF_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define FF_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef FF_USE_CONST #define ffconst const #else #define ffconst #endif /* Returned upon end-of-file. */ #define FF_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define FF_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (ff_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The FFSTATE alias is for lex * compatibility. */ #define FF_START (((ff_start) - 1) / 2) #define FFSTATE FF_START /* Action number for EOF rule of a given start state. */ #define FF_STATE_EOF(state) (FF_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define FF_NEW_FILE ffrestart(ffin ) #define FF_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef FF_BUF_SIZE #define FF_BUF_SIZE 16384 #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define FF_STATE_BUF_SIZE ((FF_BUF_SIZE + 2) * sizeof(ff_state_type)) #ifndef FF_TYPEDEF_FF_BUFFER_STATE #define FF_TYPEDEF_FF_BUFFER_STATE typedef struct ff_buffer_state *FF_BUFFER_STATE; #endif #ifndef FF_TYPEDEF_FF_SIZE_T #define FF_TYPEDEF_FF_SIZE_T typedef size_t ff_size_t; #endif extern ff_size_t ffleng; extern FILE *ffin, *ffout; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define FF_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define ffless(n) \ do \ { \ /* Undo effects of setting up fftext. */ \ int ffless_macro_arg = (n); \ FF_LESS_LINENO(ffless_macro_arg);\ *ff_cp = (ff_hold_char); \ FF_RESTORE_FF_MORE_OFFSET \ (ff_c_buf_p) = ff_cp = ff_bp + ffless_macro_arg - FF_MORE_ADJ; \ FF_DO_BEFORE_ACTION; /* set up fftext again */ \ } \ while ( 0 ) #define unput(c) ffunput( c, (fftext_ptr) ) #ifndef FF_STRUCT_FF_BUFFER_STATE #define FF_STRUCT_FF_BUFFER_STATE struct ff_buffer_state { FILE *ff_input_file; char *ff_ch_buf; /* input buffer */ char *ff_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ ff_size_t ff_buf_size; /* Number of characters read into ff_ch_buf, not including EOB * characters. */ ff_size_t ff_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int ff_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int ff_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int ff_at_bol; int ff_bs_lineno; /**< The line count. */ int ff_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int ff_fill_buffer; int ff_buffer_status; #define FF_BUFFER_NEW 0 #define FF_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as FF_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via ffrestart()), so that the user can continue scanning by * just pointing ffin at a new input file. */ #define FF_BUFFER_EOF_PENDING 2 }; #endif /* !FF_STRUCT_FF_BUFFER_STATE */ /* Stack of input buffers. */ static size_t ff_buffer_stack_top = 0; /**< index of top of stack. */ static size_t ff_buffer_stack_max = 0; /**< capacity of stack. */ static FF_BUFFER_STATE * ff_buffer_stack = 0; /**< Stack as an array. */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define FF_CURRENT_BUFFER ( (ff_buffer_stack) \ ? (ff_buffer_stack)[(ff_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define FF_CURRENT_BUFFER_LVALUE (ff_buffer_stack)[(ff_buffer_stack_top)] /* ff_hold_char holds the character lost when fftext is formed. */ static char ff_hold_char; static ff_size_t ff_n_chars; /* number of characters read into ff_ch_buf */ ff_size_t ffleng; /* Points to current character in buffer. */ static char *ff_c_buf_p = (char *) 0; static int ff_init = 0; /* whether we need to initialize */ static int ff_start = 0; /* start state number */ /* Flag which is used to allow ffwrap()'s to do buffer switches * instead of setting up a fresh ffin. A bit of a hack ... */ static int ff_did_buffer_switch_on_eof; void ffrestart (FILE *input_file ); void ff_switch_to_buffer (FF_BUFFER_STATE new_buffer ); FF_BUFFER_STATE ff_create_buffer (FILE *file,int size ); void ff_delete_buffer (FF_BUFFER_STATE b ); void ff_flush_buffer (FF_BUFFER_STATE b ); void ffpush_buffer_state (FF_BUFFER_STATE new_buffer ); void ffpop_buffer_state (void ); static void ffensure_buffer_stack (void ); static void ff_load_buffer_state (void ); static void ff_init_buffer (FF_BUFFER_STATE b,FILE *file ); #define FF_FLUSH_BUFFER ff_flush_buffer(FF_CURRENT_BUFFER ) FF_BUFFER_STATE ff_scan_buffer (char *base,ff_size_t size ); FF_BUFFER_STATE ff_scan_string (ffconst char *ff_str ); FF_BUFFER_STATE ff_scan_bytes (ffconst char *bytes,ff_size_t len ); void *ffalloc (ff_size_t ); void *ffrealloc (void *,ff_size_t ); void yyfffree (void * ); #define ff_new_buffer ff_create_buffer #define ff_set_interactive(is_interactive) \ { \ if ( ! FF_CURRENT_BUFFER ){ \ ffensure_buffer_stack (); \ FF_CURRENT_BUFFER_LVALUE = \ ff_create_buffer(ffin,FF_BUF_SIZE ); \ } \ FF_CURRENT_BUFFER_LVALUE->ff_is_interactive = is_interactive; \ } #define ff_set_bol(at_bol) \ { \ if ( ! FF_CURRENT_BUFFER ){\ ffensure_buffer_stack (); \ FF_CURRENT_BUFFER_LVALUE = \ ff_create_buffer(ffin,FF_BUF_SIZE ); \ } \ FF_CURRENT_BUFFER_LVALUE->ff_at_bol = at_bol; \ } #define FF_AT_BOL() (FF_CURRENT_BUFFER_LVALUE->ff_at_bol) /* Begin user sect3 */ typedef unsigned char FF_CHAR; FILE *ffin = (FILE *) 0, *ffout = (FILE *) 0; typedef int ff_state_type; extern int fflineno; int fflineno = 1; extern char *fftext; #define fftext_ptr fftext static ff_state_type ff_get_previous_state (void ); static ff_state_type ff_try_NUL_trans (ff_state_type current_state ); static int ff_get_next_buffer (void ); static void ff_fatal_error (ffconst char msg[] ); /* Done after the current pattern has been matched and before the * corresponding action - sets up fftext. */ #define FF_DO_BEFORE_ACTION \ (fftext_ptr) = ff_bp; \ ffleng = (ff_size_t) (ff_cp - ff_bp); \ (ff_hold_char) = *ff_cp; \ *ff_cp = '\0'; \ (ff_c_buf_p) = ff_cp; #define FF_NUM_RULES 30 #define FF_END_OF_BUFFER 31 /* This struct is not used in this scanner, but its presence is necessary. */ struct ff_trans_info { flex_int32_t ff_verify; flex_int32_t ff_nxt; }; static ffconst flex_int16_t ff_accept[174] = { 0, 0, 0, 31, 29, 1, 28, 18, 29, 29, 29, 29, 29, 29, 29, 10, 8, 8, 24, 29, 23, 13, 13, 13, 13, 9, 13, 13, 13, 13, 13, 17, 13, 13, 13, 13, 13, 13, 13, 29, 1, 22, 0, 12, 0, 11, 0, 13, 20, 0, 0, 0, 0, 0, 0, 0, 17, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 8, 0, 0, 0, 0, 26, 21, 25, 13, 13, 13, 2, 13, 13, 13, 4, 13, 13, 13, 13, 3, 13, 27, 13, 13, 13, 13, 13, 13, 13, 13, 13, 19, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5, 6, 7, 14, 13, 23, 24, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0 } ; static ffconst flex_int32_t ff_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 5, 6, 7, 1, 8, 9, 10, 11, 12, 13, 1, 13, 14, 1, 15, 16, 17, 17, 17, 17, 17, 17, 18, 18, 1, 1, 19, 20, 21, 1, 1, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 31, 32, 31, 33, 34, 31, 35, 36, 31, 37, 38, 31, 31, 39, 31, 31, 1, 1, 40, 41, 42, 1, 43, 44, 24, 45, 46, 47, 48, 29, 49, 31, 31, 50, 31, 51, 52, 31, 53, 54, 31, 55, 56, 31, 31, 57, 31, 31, 1, 58, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static ffconst flex_int32_t ff_meta[59] = { 0, 1, 1, 2, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 1, 1, 1, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 5, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1 } ; static ffconst flex_int16_t ff_base[182] = { 0, 0, 0, 412, 413, 409, 413, 390, 404, 401, 400, 398, 396, 34, 392, 70, 114, 16, 383, 46, 382, 29, 84, 359, 28, 358, 52, 157, 64, 91, 128, 358, 0, 40, 27, 69, 92, 100, 171, 340, 395, 413, 391, 413, 388, 387, 386, 413, 413, 383, 357, 358, 356, 336, 337, 335, 413, 139, 190, 352, 349, 71, 111, 135, 347, 348, 330, 327, 59, 64, 116, 325, 323, 175, 0, 59, 120, 326, 0, 413, 413, 413, 153, 184, 0, 202, 209, 210, 219, 351, 220, 228, 229, 211, 230, 240, 413, 221, 246, 254, 263, 264, 265, 266, 239, 275, 413, 346, 342, 310, 313, 309, 289, 292, 288, 275, 317, 327, 326, 325, 324, 323, 322, 298, 320, 297, 287, 317, 315, 314, 312, 311, 310, 249, 289, 243, 294, 298, 134, 246, 0, 413, 285, 413, 413, 288, 308, 309, 261, 261, 256, 221, 215, 246, 241, 223, 218, 213, 208, 197, 413, 166, 160, 413, 128, 122, 150, 154, 105, 101, 96, 413, 84, 413, 351, 354, 359, 364, 366, 368, 373, 89 } ; static ffconst flex_int16_t ff_def[182] = { 0, 173, 1, 173, 173, 173, 173, 173, 174, 175, 176, 173, 177, 173, 173, 173, 173, 16, 173, 173, 173, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 173, 179, 178, 178, 178, 178, 178, 178, 173, 173, 173, 174, 173, 180, 175, 176, 173, 173, 177, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 17, 173, 173, 173, 181, 173, 173, 173, 178, 178, 179, 178, 178, 178, 178, 27, 178, 178, 178, 178, 178, 178, 173, 178, 178, 178, 178, 178, 178, 178, 178, 178, 173, 180, 180, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 181, 173, 178, 173, 173, 178, 178, 178, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 0, 173, 173, 173, 173, 173, 173, 173, 173 } ; static ffconst flex_int16_t ff_nxt[472] = { 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 4, 14, 4, 15, 16, 17, 17, 17, 18, 19, 20, 21, 22, 23, 23, 24, 25, 26, 27, 23, 23, 28, 29, 30, 23, 23, 25, 23, 23, 4, 31, 32, 33, 22, 23, 34, 25, 35, 23, 36, 37, 38, 23, 23, 25, 23, 23, 39, 50, 173, 51, 83, 86, 52, 79, 80, 81, 173, 84, 84, 84, 136, 173, 137, 137, 137, 137, 87, 53, 98, 54, 84, 55, 57, 58, 58, 58, 58, 88, 90, 97, 59, 140, 84, 171, 60, 118, 61, 85, 85, 91, 62, 63, 64, 128, 84, 171, 119, 65, 130, 84, 171, 66, 129, 99, 67, 92, 68, 131, 69, 70, 71, 85, 100, 93, 84, 72, 73, 74, 74, 74, 74, 84, 84, 138, 138, 120, 101, 75, 75, 85, 84, 94, 94, 94, 103, 102, 121, 138, 138, 172, 104, 57, 115, 115, 115, 115, 76, 75, 75, 122, 132, 141, 95, 171, 77, 94, 133, 123, 84, 78, 89, 89, 89, 89, 170, 169, 168, 89, 89, 89, 89, 89, 89, 94, 94, 94, 94, 57, 58, 58, 58, 58, 141, 84, 89, 167, 166, 84, 89, 89, 89, 89, 89, 58, 58, 58, 58, 142, 94, 96, 141, 84, 89, 75, 75, 85, 85, 141, 141, 141, 160, 80, 81, 105, 84, 48, 94, 141, 141, 141, 96, 143, 79, 75, 75, 160, 141, 141, 141, 85, 144, 41, 84, 94, 94, 94, 145, 141, 141, 84, 84, 84, 106, 48, 141, 163, 165, 85, 80, 84, 84, 84, 141, 164, 146, 163, 81, 94, 84, 84, 84, 141, 141, 141, 141, 143, 79, 144, 41, 84, 84, 162, 161, 141, 139, 94, 84, 106, 115, 115, 115, 115, 147, 141, 84, 159, 141, 48, 75, 75, 160, 106, 158, 84, 84, 84, 84, 137, 137, 137, 137, 137, 137, 137, 137, 84, 141, 141, 75, 75, 48, 160, 41, 144, 79, 84, 143, 81, 84, 80, 157, 156, 106, 155, 41, 144, 79, 143, 81, 80, 154, 153, 152, 151, 150, 149, 148, 108, 84, 84, 42, 108, 42, 42, 42, 45, 45, 45, 46, 141, 46, 46, 46, 49, 139, 49, 49, 49, 82, 82, 84, 84, 107, 135, 107, 107, 107, 134, 127, 126, 125, 124, 117, 116, 114, 113, 112, 111, 110, 109, 43, 47, 173, 108, 43, 40, 106, 96, 84, 84, 81, 79, 56, 43, 48, 47, 44, 43, 41, 40, 173, 3, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173 } ; static ffconst flex_int16_t ff_chk[472] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 13, 17, 13, 21, 24, 13, 19, 19, 19, 17, 34, 24, 21, 75, 17, 75, 75, 75, 75, 26, 13, 34, 13, 33, 13, 15, 15, 15, 15, 15, 26, 28, 33, 15, 181, 26, 172, 15, 61, 15, 22, 22, 28, 15, 15, 15, 68, 28, 170, 61, 15, 69, 35, 169, 15, 68, 35, 15, 29, 15, 69, 15, 15, 15, 22, 35, 29, 22, 15, 16, 16, 16, 16, 16, 29, 36, 76, 76, 62, 36, 16, 16, 22, 37, 30, 30, 30, 37, 36, 62, 138, 138, 168, 37, 57, 57, 57, 57, 57, 16, 16, 16, 63, 70, 82, 30, 167, 16, 30, 70, 63, 30, 16, 27, 27, 27, 27, 166, 165, 164, 27, 27, 27, 27, 27, 27, 30, 38, 38, 38, 73, 73, 73, 73, 73, 83, 82, 27, 162, 161, 27, 27, 27, 27, 27, 27, 58, 58, 58, 58, 83, 38, 159, 85, 38, 27, 58, 58, 85, 85, 86, 87, 93, 158, 86, 87, 38, 83, 157, 38, 88, 90, 97, 156, 88, 90, 58, 58, 155, 91, 92, 94, 85, 91, 92, 85, 94, 94, 94, 93, 104, 95, 86, 87, 93, 95, 154, 98, 153, 152, 85, 98, 88, 90, 97, 99, 151, 97, 150, 99, 94, 91, 92, 94, 100, 101, 102, 103, 100, 101, 102, 103, 104, 95, 149, 148, 105, 139, 94, 98, 105, 115, 115, 115, 115, 104, 142, 99, 135, 145, 142, 115, 115, 145, 134, 133, 100, 101, 102, 103, 136, 136, 136, 136, 137, 137, 137, 137, 105, 146, 147, 115, 115, 146, 147, 132, 131, 130, 142, 129, 128, 145, 127, 126, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 114, 113, 112, 111, 110, 109, 108, 146, 147, 174, 107, 174, 174, 174, 175, 175, 175, 176, 89, 176, 176, 176, 177, 77, 177, 177, 177, 178, 178, 179, 179, 180, 72, 180, 180, 180, 71, 67, 66, 65, 64, 60, 59, 55, 54, 53, 52, 51, 50, 49, 46, 45, 44, 42, 40, 39, 31, 25, 23, 20, 18, 14, 12, 11, 10, 9, 8, 7, 5, 3, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173 } ; static ff_state_type ff_last_accepting_state; static char *ff_last_accepting_cpos; extern int ff_flex_debug; int ff_flex_debug = 0; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define ffmore() ffmore_used_but_not_detected #define FF_MORE_ADJ 0 #define FF_RESTORE_FF_MORE_OFFSET char *fftext; #line 1 "eval.l" #line 2 "eval.l" /************************************************************************/ /* */ /* CFITSIO Lexical Parser */ /* */ /* This file is one of 3 files containing code which parses an */ /* arithmetic expression and evaluates it in the context of an input */ /* FITS file table extension. The CFITSIO lexical parser is divided */ /* into the following 3 parts/files: the CFITSIO "front-end", */ /* eval_f.c, contains the interface between the user/CFITSIO and the */ /* real core of the parser; the FLEX interpreter, eval_l.c, takes the */ /* input string and parses it into tokens and identifies the FITS */ /* information required to evaluate the expression (ie, keywords and */ /* columns); and, the BISON grammar and evaluation routines, eval_y.c, */ /* receives the FLEX output and determines and performs the actual */ /* operations. The files eval_l.c and eval_y.c are produced from */ /* running flex and bison on the files eval.l and eval.y, respectively. */ /* (flex and bison are available from any GNU archive: see www.gnu.org) */ /* */ /* The grammar rules, rather than evaluating the expression in situ, */ /* builds a tree, or Nodal, structure mapping out the order of */ /* operations and expression dependencies. This "compilation" process */ /* allows for much faster processing of multiple rows. This technique */ /* was developed by Uwe Lammers of the XMM Science Analysis System, */ /* although the CFITSIO implementation is entirely code original. */ /* */ /* */ /* Modification History: */ /* */ /* Kent Blackburn c1992 Original parser code developed for the */ /* FTOOLS software package, in particular, */ /* the fselect task. */ /* Kent Blackburn c1995 BIT column support added */ /* Peter D Wilson Feb 1998 Vector column support added */ /* Peter D Wilson May 1998 Ported to CFITSIO library. User */ /* interface routines written, in essence */ /* making fselect, fcalc, and maketime */ /* capabilities available to all tools */ /* via single function calls. */ /* Peter D Wilson Jun 1998 Major rewrite of parser core, so as to */ /* create a run-time evaluation tree, */ /* inspired by the work of Uwe Lammers, */ /* resulting in a speed increase of */ /* 10-100 times. */ /* Peter D Wilson Jul 1998 gtifilter(a,b,c,d) function added */ /* Peter D Wilson Aug 1998 regfilter(a,b,c,d) function added */ /* Peter D Wilson Jul 1999 Make parser fitsfile-independent, */ /* allowing a purely vector-based usage */ /* */ /************************************************************************/ #include #include #include #ifdef sparc #include #else #include #endif #include "eval_defs.h" ParseData gParse; /* Global structure holding all parser information */ /***** Internal functions *****/ int ffGetVariable( char *varName, FFSTYPE *varVal ); static int find_variable( char *varName ); static int expr_read( char *buf, int nbytes ); /***** Definitions *****/ #define FF_NO_UNPUT /* Don't include FFUNPUT function */ #define FF_NEVER_INTERACTIVE 1 #define MAXCHR 256 #define MAXBIT 128 #define OCT_0 "000" #define OCT_1 "001" #define OCT_2 "010" #define OCT_3 "011" #define OCT_4 "100" #define OCT_5 "101" #define OCT_6 "110" #define OCT_7 "111" #define OCT_X "xxx" #define HEX_0 "0000" #define HEX_1 "0001" #define HEX_2 "0010" #define HEX_3 "0011" #define HEX_4 "0100" #define HEX_5 "0101" #define HEX_6 "0110" #define HEX_7 "0111" #define HEX_8 "1000" #define HEX_9 "1001" #define HEX_A "1010" #define HEX_B "1011" #define HEX_C "1100" #define HEX_D "1101" #define HEX_E "1110" #define HEX_F "1111" #define HEX_X "xxxx" /* MJT - 13 June 1996 read from buffer instead of stdin (as per old ftools.skel) */ #undef FF_INPUT #define FF_INPUT(buf,result,max_size) \ if ( (result = expr_read( (char *) buf, max_size )) < 0 ) \ FF_FATAL_ERROR( "read() in flex scanner failed" ); #line 729 "" #define INITIAL 0 #ifndef FF_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef FF_EXTRA_TYPE #define FF_EXTRA_TYPE void * #endif static int ff_init_globals (void ); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int fflex_destroy (void ); int ffget_debug (void ); void ffset_debug (int debug_flag ); FF_EXTRA_TYPE ffget_extra (void ); void ffset_extra (FF_EXTRA_TYPE user_defined ); FILE *ffget_in (void ); void ffset_in (FILE * in_str ); FILE *ffget_out (void ); void ffset_out (FILE * out_str ); ff_size_t ffget_leng (void ); char *ffget_text (void ); int ffget_lineno (void ); void ffset_lineno (int line_number ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef FF_SKIP_FFWRAP #ifdef __cplusplus extern "C" int ffwrap (void ); #else extern int ffwrap (void ); #endif #endif static void ffunput (int c,char *buf_ptr ); #ifndef fftext_ptr static void ff_flex_strncpy (char *,ffconst char *,int ); #endif #ifdef FF_NEED_STRLEN static int ff_flex_strlen (ffconst char * ); #endif #ifndef FF_NO_INPUT #ifdef __cplusplus static int ffinput (void ); #else static int input (void ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef FF_READ_BUF_SIZE #define FF_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO fwrite( fftext, ffleng, 1, ffout ) #endif /* Gets input and stuffs it into "buf". number of characters read, or FF_NULL, * is returned in "result". */ #ifndef FF_INPUT #define FF_INPUT(buf,result,max_size) \ if ( FF_CURRENT_BUFFER_LVALUE->ff_is_interactive ) \ { \ int c = '*'; \ ff_size_t n; \ for ( n = 0; n < max_size && \ (c = getc( ffin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( ffin ) ) \ FF_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = fread(buf, 1, max_size, ffin))==0 && ferror(ffin)) \ { \ if( errno != EINTR) \ { \ FF_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(ffin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "ffterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef ffterminate #define ffterminate() return FF_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef FF_START_STACK_INCR #define FF_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef FF_FATAL_ERROR #define FF_FATAL_ERROR(msg) ff_fatal_error( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef FF_DECL #define FF_DECL_IS_OURS 1 extern int fflex (void); #define FF_DECL int fflex (void) #endif /* !FF_DECL */ /* Code executed at the beginning of each rule, after fftext and ffleng * have been set up. */ #ifndef FF_USER_ACTION #define FF_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef FF_BREAK #define FF_BREAK break; #endif #define FF_RULE_SETUP \ FF_USER_ACTION /** The main scanner function which does all the work. */ FF_DECL { register ff_state_type ff_current_state; register char *ff_cp, *ff_bp; register int ff_act; #line 146 "eval.l" #line 914 "" if ( !(ff_init) ) { (ff_init) = 1; #ifdef FF_USER_INIT FF_USER_INIT; #endif if ( ! (ff_start) ) (ff_start) = 1; /* first start state */ if ( ! ffin ) ffin = stdin; if ( ! ffout ) ffout = stdout; if ( ! FF_CURRENT_BUFFER ) { ffensure_buffer_stack (); FF_CURRENT_BUFFER_LVALUE = ff_create_buffer(ffin,FF_BUF_SIZE ); } ff_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { ff_cp = (ff_c_buf_p); /* Support of fftext. */ *ff_cp = (ff_hold_char); /* ff_bp points to the position in ff_ch_buf of the start of * the current run. */ ff_bp = ff_cp; ff_current_state = (ff_start); ff_match: do { register FF_CHAR ff_c = ff_ec[FF_SC_TO_UI(*ff_cp)]; if ( ff_accept[ff_current_state] ) { (ff_last_accepting_state) = ff_current_state; (ff_last_accepting_cpos) = ff_cp; } while ( ff_chk[ff_base[ff_current_state] + ff_c] != ff_current_state ) { ff_current_state = (int) ff_def[ff_current_state]; if ( ff_current_state >= 174 ) ff_c = ff_meta[(unsigned int) ff_c]; } ff_current_state = ff_nxt[ff_base[ff_current_state] + (unsigned int) ff_c]; ++ff_cp; } while ( ff_base[ff_current_state] != 413 ); ff_find_action: ff_act = ff_accept[ff_current_state]; if ( ff_act == 0 ) { /* have to back up */ ff_cp = (ff_last_accepting_cpos); ff_current_state = (ff_last_accepting_state); ff_act = ff_accept[ff_current_state]; } FF_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( ff_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of FF_DO_BEFORE_ACTION */ *ff_cp = (ff_hold_char); ff_cp = (ff_last_accepting_cpos); ff_current_state = (ff_last_accepting_state); goto ff_find_action; case 1: FF_RULE_SETUP #line 148 "eval.l" ; FF_BREAK case 2: FF_RULE_SETUP #line 149 "eval.l" { int len; len = strlen(fftext); while (fftext[len] == ' ') len--; len = len - 1; strncpy(fflval.str,&fftext[1],len); fflval.str[len] = '\0'; return( BITSTR ); } FF_BREAK case 3: FF_RULE_SETUP #line 159 "eval.l" { int len; char tmpstring[256]; char bitstring[256]; len = strlen(fftext); if (len >= 256) { char errMsg[100]; gParse.status = PARSE_SYNTAX_ERR; strcpy (errMsg,"Bit string exceeds maximum length: '"); strncat(errMsg, &(fftext[0]), 20); strcat (errMsg,"...'"); ffpmsg (errMsg); len = 0; } else { while (fftext[len] == ' ') len--; len = len - 1; strncpy(tmpstring,&fftext[1],len); } tmpstring[len] = '\0'; bitstring[0] = '\0'; len = 0; while ( tmpstring[len] != '\0') { switch ( tmpstring[len] ) { case '0': strcat(bitstring,OCT_0); break; case '1': strcat(bitstring,OCT_1); break; case '2': strcat(bitstring,OCT_2); break; case '3': strcat(bitstring,OCT_3); break; case '4': strcat(bitstring,OCT_4); break; case '5': strcat(bitstring,OCT_5); break; case '6': strcat(bitstring,OCT_6); break; case '7': strcat(bitstring,OCT_7); break; case 'x': case 'X': strcat(bitstring,OCT_X); break; } len++; } strcpy( fflval.str, bitstring ); return( BITSTR ); } FF_BREAK case 4: FF_RULE_SETUP #line 219 "eval.l" { int len; char tmpstring[256]; char bitstring[256]; len = strlen(fftext); if (len >= 256) { char errMsg[100]; gParse.status = PARSE_SYNTAX_ERR; strcpy (errMsg,"Hex string exceeds maximum length: '"); strncat(errMsg, &(fftext[0]), 20); strcat (errMsg,"...'"); ffpmsg (errMsg); len = 0; } else { while (fftext[len] == ' ') len--; len = len - 1; strncpy(tmpstring,&fftext[1],len); } tmpstring[len] = '\0'; bitstring[0] = '\0'; len = 0; while ( tmpstring[len] != '\0') { switch ( tmpstring[len] ) { case '0': strcat(bitstring,HEX_0); break; case '1': strcat(bitstring,HEX_1); break; case '2': strcat(bitstring,HEX_2); break; case '3': strcat(bitstring,HEX_3); break; case '4': strcat(bitstring,HEX_4); break; case '5': strcat(bitstring,HEX_5); break; case '6': strcat(bitstring,HEX_6); break; case '7': strcat(bitstring,HEX_7); break; case '8': strcat(bitstring,HEX_8); break; case '9': strcat(bitstring,HEX_9); break; case 'a': case 'A': strcat(bitstring,HEX_A); break; case 'b': case 'B': strcat(bitstring,HEX_B); break; case 'c': case 'C': strcat(bitstring,HEX_C); break; case 'd': case 'D': strcat(bitstring,HEX_D); break; case 'e': case 'E': strcat(bitstring,HEX_E); break; case 'f': case 'F': strcat(bitstring,HEX_F); break; case 'x': case 'X': strcat(bitstring,HEX_X); break; } len++; } strcpy( fflval.str, bitstring ); return( BITSTR ); } FF_BREAK case 5: FF_RULE_SETUP #line 310 "eval.l" { long int constval = 0; char *p; for (p = &(fftext[2]); *p; p++) { constval = (constval << 1) | (*p == '1'); } fflval.lng = constval; return( LONG ); } FF_BREAK case 6: FF_RULE_SETUP #line 319 "eval.l" { long int constval = 0; char *p; for (p = &(fftext[2]); *p; p++) { constval = (constval << 3) | (*p - '0'); } fflval.lng = constval; return( LONG ); } FF_BREAK case 7: FF_RULE_SETUP #line 328 "eval.l" { long int constval = 0; char *p; for (p = &(fftext[2]); *p; p++) { int v = (isdigit(*p) ? (*p - '0') : (*p - 'a' + 10)); constval = (constval << 4) | v; } fflval.lng = constval; return( LONG ); } FF_BREAK case 8: FF_RULE_SETUP #line 340 "eval.l" { fflval.lng = atol(fftext); return( LONG ); } FF_BREAK case 9: FF_RULE_SETUP #line 344 "eval.l" { if ((fftext[0] == 't') || (fftext[0] == 'T')) fflval.log = 1; else fflval.log = 0; return( BOOLEAN ); } FF_BREAK case 10: FF_RULE_SETUP #line 351 "eval.l" { fflval.dbl = atof(fftext); return( DOUBLE ); } FF_BREAK case 11: FF_RULE_SETUP #line 355 "eval.l" { if( !fits_strcasecmp(fftext,"#PI") ) { fflval.dbl = (double)(4) * atan((double)(1)); return( DOUBLE ); } else if( !fits_strcasecmp(fftext,"#E") ) { fflval.dbl = exp((double)(1)); return( DOUBLE ); } else if( !fits_strcasecmp(fftext,"#DEG") ) { fflval.dbl = ((double)4)*atan((double)1)/((double)180); return( DOUBLE ); } else if( !fits_strcasecmp(fftext,"#ROW") ) { return( ROWREF ); } else if( !fits_strcasecmp(fftext,"#NULL") ) { return( NULLREF ); } else if( !fits_strcasecmp(fftext,"#SNULL") ) { return( SNULLREF ); } else { int len; if (fftext[1] == '$') { len = strlen(fftext) - 3; fflval.str[0] = '#'; strncpy(fflval.str+1,&fftext[2],len); fflval.str[len+1] = '\0'; fftext = fflval.str; } return( (*gParse.getData)(fftext, &fflval) ); } } FF_BREAK case 12: FF_RULE_SETUP #line 383 "eval.l" { int len; len = strlen(fftext) - 2; if (len >= MAX_STRLEN) { char errMsg[100]; gParse.status = PARSE_SYNTAX_ERR; strcpy (errMsg,"String exceeds maximum length: '"); strncat(errMsg, &(fftext[1]), 20); strcat (errMsg,"...'"); ffpmsg (errMsg); len = 0; } else { strncpy(fflval.str,&fftext[1],len); } fflval.str[len] = '\0'; return( STRING ); } FF_BREAK case 13: FF_RULE_SETUP #line 400 "eval.l" { int len,type; if (fftext[0] == '$') { len = strlen(fftext) - 2; strncpy(fflval.str,&fftext[1],len); fflval.str[len] = '\0'; fftext = fflval.str; } type = ffGetVariable(fftext, &fflval); return( type ); } FF_BREAK case 14: FF_RULE_SETUP #line 412 "eval.l" { char *fname; int len=0; fname = &fflval.str[0]; while( (fname[len]=toupper(fftext[len])) ) len++; if( FSTRCMP(fname,"BOX(")==0 || FSTRCMP(fname,"CIRCLE(")==0 || FSTRCMP(fname,"ELLIPSE(")==0 || FSTRCMP(fname,"NEAR(")==0 || FSTRCMP(fname,"ISNULL(")==0 ) /* Return type is always boolean */ return( BFUNCTION ); else if( FSTRCMP(fname,"GTIFILTER(")==0 ) return( GTIFILTER ); else if( FSTRCMP(fname,"GTIOVERLAP(")==0 ) return( GTIOVERLAP ); else if( FSTRCMP(fname,"REGFILTER(")==0 ) return( REGFILTER ); else if( FSTRCMP(fname,"STRSTR(")==0 ) return( IFUNCTION ); /* Returns integer */ else return( FUNCTION ); } FF_BREAK case 15: FF_RULE_SETUP #line 442 "eval.l" { return( INTCAST ); } FF_BREAK case 16: FF_RULE_SETUP #line 443 "eval.l" { return( FLTCAST ); } FF_BREAK case 17: FF_RULE_SETUP #line 444 "eval.l" { return( POWER ); } FF_BREAK case 18: FF_RULE_SETUP #line 445 "eval.l" { return( NOT ); } FF_BREAK case 19: FF_RULE_SETUP #line 446 "eval.l" { return( OR ); } FF_BREAK case 20: FF_RULE_SETUP #line 447 "eval.l" { return( AND ); } FF_BREAK case 21: FF_RULE_SETUP #line 448 "eval.l" { return( EQ ); } FF_BREAK case 22: FF_RULE_SETUP #line 449 "eval.l" { return( NE ); } FF_BREAK case 23: FF_RULE_SETUP #line 450 "eval.l" { return( GT ); } FF_BREAK case 24: FF_RULE_SETUP #line 451 "eval.l" { return( LT ); } FF_BREAK case 25: FF_RULE_SETUP #line 452 "eval.l" { return( GTE ); } FF_BREAK case 26: FF_RULE_SETUP #line 453 "eval.l" { return( LTE ); } FF_BREAK case 27: FF_RULE_SETUP #line 454 "eval.l" { return( XOR ); } FF_BREAK case 28: /* rule 28 can match eol */ FF_RULE_SETUP #line 455 "eval.l" { return( '\n' ); } FF_BREAK case 29: FF_RULE_SETUP #line 456 "eval.l" { return( fftext[0] ); } FF_BREAK case 30: FF_RULE_SETUP #line 457 "eval.l" ECHO; FF_BREAK #line 1426 "" case FF_STATE_EOF(INITIAL): ffterminate(); case FF_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int ff_amount_of_matched_text = (int) (ff_cp - (fftext_ptr)) - 1; /* Undo the effects of FF_DO_BEFORE_ACTION. */ *ff_cp = (ff_hold_char); FF_RESTORE_FF_MORE_OFFSET if ( FF_CURRENT_BUFFER_LVALUE->ff_buffer_status == FF_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed ffin at a new source and called * fflex(). If so, then we have to assure * consistency between FF_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (ff_n_chars) = FF_CURRENT_BUFFER_LVALUE->ff_n_chars; FF_CURRENT_BUFFER_LVALUE->ff_input_file = ffin; FF_CURRENT_BUFFER_LVALUE->ff_buffer_status = FF_BUFFER_NORMAL; } /* Note that here we test for ff_c_buf_p "<=" to the position * of the first EOB in the buffer, since ff_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (ff_c_buf_p) <= &FF_CURRENT_BUFFER_LVALUE->ff_ch_buf[(ff_n_chars)] ) { /* This was really a NUL. */ ff_state_type ff_next_state; (ff_c_buf_p) = (fftext_ptr) + ff_amount_of_matched_text; ff_current_state = ff_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * ff_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ ff_next_state = ff_try_NUL_trans( ff_current_state ); ff_bp = (fftext_ptr) + FF_MORE_ADJ; if ( ff_next_state ) { /* Consume the NUL. */ ff_cp = ++(ff_c_buf_p); ff_current_state = ff_next_state; goto ff_match; } else { ff_cp = (ff_c_buf_p); goto ff_find_action; } } else switch ( ff_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (ff_did_buffer_switch_on_eof) = 0; if ( ffwrap( ) ) { /* Note: because we've taken care in * ff_get_next_buffer() to have set up * fftext, we can now set up * ff_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * FF_NULL, it'll still work - another * FF_NULL will get returned. */ (ff_c_buf_p) = (fftext_ptr) + FF_MORE_ADJ; ff_act = FF_STATE_EOF(FF_START); goto do_action; } else { if ( ! (ff_did_buffer_switch_on_eof) ) FF_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (ff_c_buf_p) = (fftext_ptr) + ff_amount_of_matched_text; ff_current_state = ff_get_previous_state( ); ff_cp = (ff_c_buf_p); ff_bp = (fftext_ptr) + FF_MORE_ADJ; goto ff_match; case EOB_ACT_LAST_MATCH: (ff_c_buf_p) = &FF_CURRENT_BUFFER_LVALUE->ff_ch_buf[(ff_n_chars)]; ff_current_state = ff_get_previous_state( ); ff_cp = (ff_c_buf_p); ff_bp = (fftext_ptr) + FF_MORE_ADJ; goto ff_find_action; } break; } default: FF_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of fflex */ /* ff_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int ff_get_next_buffer (void) { register char *dest = FF_CURRENT_BUFFER_LVALUE->ff_ch_buf; register char *source = (fftext_ptr); register int number_to_move, i; int ret_val; if ( (ff_c_buf_p) > &FF_CURRENT_BUFFER_LVALUE->ff_ch_buf[(ff_n_chars) + 1] ) FF_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( FF_CURRENT_BUFFER_LVALUE->ff_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (ff_c_buf_p) - (fftext_ptr) - FF_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((ff_c_buf_p) - (fftext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( FF_CURRENT_BUFFER_LVALUE->ff_buffer_status == FF_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ FF_CURRENT_BUFFER_LVALUE->ff_n_chars = (ff_n_chars) = 0; else { ff_size_t num_to_read = FF_CURRENT_BUFFER_LVALUE->ff_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ FF_BUFFER_STATE b = FF_CURRENT_BUFFER; int ff_c_buf_p_offset = (int) ((ff_c_buf_p) - b->ff_ch_buf); if ( b->ff_is_our_buffer ) { ff_size_t new_size = b->ff_buf_size * 2; if ( new_size <= 0 ) b->ff_buf_size += b->ff_buf_size / 8; else b->ff_buf_size *= 2; b->ff_ch_buf = (char *) /* Include room in for 2 EOB chars. */ ffrealloc((void *) b->ff_ch_buf,b->ff_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->ff_ch_buf = 0; if ( ! b->ff_ch_buf ) FF_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (ff_c_buf_p) = &b->ff_ch_buf[ff_c_buf_p_offset]; num_to_read = FF_CURRENT_BUFFER_LVALUE->ff_buf_size - number_to_move - 1; } if ( num_to_read > FF_READ_BUF_SIZE ) num_to_read = FF_READ_BUF_SIZE; /* Read in more data. */ FF_INPUT( (&FF_CURRENT_BUFFER_LVALUE->ff_ch_buf[number_to_move]), (ff_n_chars), num_to_read ); FF_CURRENT_BUFFER_LVALUE->ff_n_chars = (ff_n_chars); } if ( (ff_n_chars) == 0 ) { if ( number_to_move == FF_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; ffrestart(ffin ); } else { ret_val = EOB_ACT_LAST_MATCH; FF_CURRENT_BUFFER_LVALUE->ff_buffer_status = FF_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((ff_size_t) ((ff_n_chars) + number_to_move) > FF_CURRENT_BUFFER_LVALUE->ff_buf_size) { /* Extend the array by 50%, plus the number we really need. */ ff_size_t new_size = (ff_n_chars) + number_to_move + ((ff_n_chars) >> 1); FF_CURRENT_BUFFER_LVALUE->ff_ch_buf = (char *) ffrealloc((void *) FF_CURRENT_BUFFER_LVALUE->ff_ch_buf,new_size ); if ( ! FF_CURRENT_BUFFER_LVALUE->ff_ch_buf ) FF_FATAL_ERROR( "out of dynamic memory in ff_get_next_buffer()" ); } (ff_n_chars) += number_to_move; FF_CURRENT_BUFFER_LVALUE->ff_ch_buf[(ff_n_chars)] = FF_END_OF_BUFFER_CHAR; FF_CURRENT_BUFFER_LVALUE->ff_ch_buf[(ff_n_chars) + 1] = FF_END_OF_BUFFER_CHAR; (fftext_ptr) = &FF_CURRENT_BUFFER_LVALUE->ff_ch_buf[0]; return ret_val; } /* ff_get_previous_state - get the state just before the EOB char was reached */ static ff_state_type ff_get_previous_state (void) { register ff_state_type ff_current_state; register char *ff_cp; ff_current_state = (ff_start); for ( ff_cp = (fftext_ptr) + FF_MORE_ADJ; ff_cp < (ff_c_buf_p); ++ff_cp ) { register FF_CHAR ff_c = (*ff_cp ? ff_ec[FF_SC_TO_UI(*ff_cp)] : 1); if ( ff_accept[ff_current_state] ) { (ff_last_accepting_state) = ff_current_state; (ff_last_accepting_cpos) = ff_cp; } while ( ff_chk[ff_base[ff_current_state] + ff_c] != ff_current_state ) { ff_current_state = (int) ff_def[ff_current_state]; if ( ff_current_state >= 174 ) ff_c = ff_meta[(unsigned int) ff_c]; } ff_current_state = ff_nxt[ff_base[ff_current_state] + (unsigned int) ff_c]; } return ff_current_state; } /* ff_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = ff_try_NUL_trans( current_state ); */ static ff_state_type ff_try_NUL_trans (ff_state_type ff_current_state ) { register int ff_is_jam; register char *ff_cp = (ff_c_buf_p); register FF_CHAR ff_c = 1; if ( ff_accept[ff_current_state] ) { (ff_last_accepting_state) = ff_current_state; (ff_last_accepting_cpos) = ff_cp; } while ( ff_chk[ff_base[ff_current_state] + ff_c] != ff_current_state ) { ff_current_state = (int) ff_def[ff_current_state]; if ( ff_current_state >= 174 ) ff_c = ff_meta[(unsigned int) ff_c]; } ff_current_state = ff_nxt[ff_base[ff_current_state] + (unsigned int) ff_c]; ff_is_jam = (ff_current_state == 173); return ff_is_jam ? 0 : ff_current_state; } static void ffunput (int c, register char * ff_bp ) { register char *ff_cp; ff_cp = (ff_c_buf_p); /* undo effects of setting up fftext */ *ff_cp = (ff_hold_char); if ( ff_cp < FF_CURRENT_BUFFER_LVALUE->ff_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register ff_size_t number_to_move = (ff_n_chars) + 2; register char *dest = &FF_CURRENT_BUFFER_LVALUE->ff_ch_buf[ FF_CURRENT_BUFFER_LVALUE->ff_buf_size + 2]; register char *source = &FF_CURRENT_BUFFER_LVALUE->ff_ch_buf[number_to_move]; while ( source > FF_CURRENT_BUFFER_LVALUE->ff_ch_buf ) *--dest = *--source; ff_cp += (int) (dest - source); ff_bp += (int) (dest - source); FF_CURRENT_BUFFER_LVALUE->ff_n_chars = (ff_n_chars) = FF_CURRENT_BUFFER_LVALUE->ff_buf_size; if ( ff_cp < FF_CURRENT_BUFFER_LVALUE->ff_ch_buf + 2 ) FF_FATAL_ERROR( "flex scanner push-back overflow" ); } *--ff_cp = (char) c; (fftext_ptr) = ff_bp; (ff_hold_char) = *ff_cp; (ff_c_buf_p) = ff_cp; } #ifndef FF_NO_INPUT #ifdef __cplusplus static int ffinput (void) #else static int input (void) #endif { int c; *(ff_c_buf_p) = (ff_hold_char); if ( *(ff_c_buf_p) == FF_END_OF_BUFFER_CHAR ) { /* ff_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (ff_c_buf_p) < &FF_CURRENT_BUFFER_LVALUE->ff_ch_buf[(ff_n_chars)] ) /* This was really a NUL. */ *(ff_c_buf_p) = '\0'; else { /* need more input */ ff_size_t offset = (ff_c_buf_p) - (fftext_ptr); ++(ff_c_buf_p); switch ( ff_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because ff_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ ffrestart(ffin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( ffwrap( ) ) return 0; if ( ! (ff_did_buffer_switch_on_eof) ) FF_NEW_FILE; #ifdef __cplusplus return ffinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (ff_c_buf_p) = (fftext_ptr) + offset; break; } } } c = *(unsigned char *) (ff_c_buf_p); /* cast for 8-bit char's */ *(ff_c_buf_p) = '\0'; /* preserve fftext */ (ff_hold_char) = *++(ff_c_buf_p); return c; } #endif /* ifndef FF_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void ffrestart (FILE * input_file ) { if ( ! FF_CURRENT_BUFFER ){ ffensure_buffer_stack (); FF_CURRENT_BUFFER_LVALUE = ff_create_buffer(ffin,FF_BUF_SIZE ); } ff_init_buffer(FF_CURRENT_BUFFER,input_file ); ff_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void ff_switch_to_buffer (FF_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * ffpop_buffer_state(); * ffpush_buffer_state(new_buffer); */ ffensure_buffer_stack (); if ( FF_CURRENT_BUFFER == new_buffer ) return; if ( FF_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(ff_c_buf_p) = (ff_hold_char); FF_CURRENT_BUFFER_LVALUE->ff_buf_pos = (ff_c_buf_p); FF_CURRENT_BUFFER_LVALUE->ff_n_chars = (ff_n_chars); } FF_CURRENT_BUFFER_LVALUE = new_buffer; ff_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (ffwrap()) processing, but the only time this flag * is looked at is after ffwrap() is called, so it's safe * to go ahead and always set it. */ (ff_did_buffer_switch_on_eof) = 1; } static void ff_load_buffer_state (void) { (ff_n_chars) = FF_CURRENT_BUFFER_LVALUE->ff_n_chars; (fftext_ptr) = (ff_c_buf_p) = FF_CURRENT_BUFFER_LVALUE->ff_buf_pos; ffin = FF_CURRENT_BUFFER_LVALUE->ff_input_file; (ff_hold_char) = *(ff_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c FF_BUF_SIZE. * * @return the allocated buffer state. */ FF_BUFFER_STATE ff_create_buffer (FILE * file, int size ) { FF_BUFFER_STATE b; b = (FF_BUFFER_STATE) ffalloc(sizeof( struct ff_buffer_state ) ); if ( ! b ) FF_FATAL_ERROR( "out of dynamic memory in ff_create_buffer()" ); b->ff_buf_size = size; /* ff_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->ff_ch_buf = (char *) ffalloc(b->ff_buf_size + 2 ); if ( ! b->ff_ch_buf ) FF_FATAL_ERROR( "out of dynamic memory in ff_create_buffer()" ); b->ff_is_our_buffer = 1; ff_init_buffer(b,file ); return b; } /** Destroy the buffer. * @param b a buffer created with ff_create_buffer() * */ void ff_delete_buffer (FF_BUFFER_STATE b ) { if ( ! b ) return; if ( b == FF_CURRENT_BUFFER ) /* Not sure if we should pop here. */ FF_CURRENT_BUFFER_LVALUE = (FF_BUFFER_STATE) 0; if ( b->ff_is_our_buffer ) yyfffree((void *) b->ff_ch_buf ); yyfffree((void *) b ); } #ifndef __cplusplus extern int isatty (int ); #endif /* __cplusplus */ /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a ffrestart() or at EOF. */ static void ff_init_buffer (FF_BUFFER_STATE b, FILE * file ) { int oerrno = errno; ff_flush_buffer(b ); b->ff_input_file = file; b->ff_fill_buffer = 1; /* If b is the current buffer, then ff_init_buffer was _probably_ * called from ffrestart() or through ff_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != FF_CURRENT_BUFFER){ b->ff_bs_lineno = 1; b->ff_bs_column = 0; } b->ff_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, FF_INPUT will be called. * @param b the buffer state to be flushed, usually @c FF_CURRENT_BUFFER. * */ void ff_flush_buffer (FF_BUFFER_STATE b ) { if ( ! b ) return; b->ff_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->ff_ch_buf[0] = FF_END_OF_BUFFER_CHAR; b->ff_ch_buf[1] = FF_END_OF_BUFFER_CHAR; b->ff_buf_pos = &b->ff_ch_buf[0]; b->ff_at_bol = 1; b->ff_buffer_status = FF_BUFFER_NEW; if ( b == FF_CURRENT_BUFFER ) ff_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void ffpush_buffer_state (FF_BUFFER_STATE new_buffer ) { if (new_buffer == NULL) return; ffensure_buffer_stack(); /* This block is copied from ff_switch_to_buffer. */ if ( FF_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(ff_c_buf_p) = (ff_hold_char); FF_CURRENT_BUFFER_LVALUE->ff_buf_pos = (ff_c_buf_p); FF_CURRENT_BUFFER_LVALUE->ff_n_chars = (ff_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (FF_CURRENT_BUFFER) (ff_buffer_stack_top)++; FF_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from ff_switch_to_buffer. */ ff_load_buffer_state( ); (ff_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void ffpop_buffer_state (void) { if (!FF_CURRENT_BUFFER) return; ff_delete_buffer(FF_CURRENT_BUFFER ); FF_CURRENT_BUFFER_LVALUE = NULL; if ((ff_buffer_stack_top) > 0) --(ff_buffer_stack_top); if (FF_CURRENT_BUFFER) { ff_load_buffer_state( ); (ff_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void ffensure_buffer_stack (void) { ff_size_t num_to_alloc; if (!(ff_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (ff_buffer_stack) = (struct ff_buffer_state**)ffalloc (num_to_alloc * sizeof(struct ff_buffer_state*) ); if ( ! (ff_buffer_stack) ) FF_FATAL_ERROR( "out of dynamic memory in ffensure_buffer_stack()" ); memset((ff_buffer_stack), 0, num_to_alloc * sizeof(struct ff_buffer_state*)); (ff_buffer_stack_max) = num_to_alloc; (ff_buffer_stack_top) = 0; return; } if ((ff_buffer_stack_top) >= ((ff_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (ff_buffer_stack_max) + grow_size; (ff_buffer_stack) = (struct ff_buffer_state**)ffrealloc ((ff_buffer_stack), num_to_alloc * sizeof(struct ff_buffer_state*) ); if ( ! (ff_buffer_stack) ) FF_FATAL_ERROR( "out of dynamic memory in ffensure_buffer_stack()" ); /* zero only the new slots.*/ memset((ff_buffer_stack) + (ff_buffer_stack_max), 0, grow_size * sizeof(struct ff_buffer_state*)); (ff_buffer_stack_max) = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * * @return the newly allocated buffer state object. */ FF_BUFFER_STATE ff_scan_buffer (char * base, ff_size_t size ) { FF_BUFFER_STATE b; if ( size < 2 || base[size-2] != FF_END_OF_BUFFER_CHAR || base[size-1] != FF_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return 0; b = (FF_BUFFER_STATE) ffalloc(sizeof( struct ff_buffer_state ) ); if ( ! b ) FF_FATAL_ERROR( "out of dynamic memory in ff_scan_buffer()" ); b->ff_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->ff_buf_pos = b->ff_ch_buf = base; b->ff_is_our_buffer = 0; b->ff_input_file = 0; b->ff_n_chars = b->ff_buf_size; b->ff_is_interactive = 0; b->ff_at_bol = 1; b->ff_fill_buffer = 0; b->ff_buffer_status = FF_BUFFER_NEW; ff_switch_to_buffer(b ); return b; } /** Setup the input buffer state to scan a string. The next call to fflex() will * scan from a @e copy of @a str. * @param ffstr a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * ff_scan_bytes() instead. */ FF_BUFFER_STATE ff_scan_string (ffconst char * ffstr ) { return ff_scan_bytes(ffstr,strlen(ffstr) ); } /** Setup the input buffer state to scan the given bytes. The next call to fflex() will * scan from a @e copy of @a bytes. * @param bytes the byte buffer to scan * @param len the number of bytes in the buffer pointed to by @a bytes. * * @return the newly allocated buffer state object. */ FF_BUFFER_STATE ff_scan_bytes (ffconst char * ffbytes, ff_size_t _ffbytes_len ) { FF_BUFFER_STATE b; char *buf; ff_size_t n, i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _ffbytes_len + 2; buf = (char *) ffalloc(n ); if ( ! buf ) FF_FATAL_ERROR( "out of dynamic memory in ff_scan_bytes()" ); for ( i = 0; i < _ffbytes_len; ++i ) buf[i] = ffbytes[i]; buf[_ffbytes_len] = buf[_ffbytes_len+1] = FF_END_OF_BUFFER_CHAR; b = ff_scan_buffer(buf,n ); if ( ! b ) FF_FATAL_ERROR( "bad buffer in ff_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->ff_is_our_buffer = 1; return b; } #ifndef FF_EXIT_FAILURE #define FF_EXIT_FAILURE 2 #endif static void ff_fatal_error (ffconst char* msg ) { (void) fprintf( stderr, "%s\n", msg ); exit( FF_EXIT_FAILURE ); } /* Redefine ffless() so it works in section 3 code. */ #undef ffless #define ffless(n) \ do \ { \ /* Undo effects of setting up fftext. */ \ int ffless_macro_arg = (n); \ FF_LESS_LINENO(ffless_macro_arg);\ fftext[ffleng] = (ff_hold_char); \ (ff_c_buf_p) = fftext + ffless_macro_arg; \ (ff_hold_char) = *(ff_c_buf_p); \ *(ff_c_buf_p) = '\0'; \ ffleng = ffless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the current line number. * */ int ffget_lineno (void) { return fflineno; } /** Get the input stream. * */ FILE *ffget_in (void) { return ffin; } /** Get the output stream. * */ FILE *ffget_out (void) { return ffout; } /** Get the length of the current token. * */ ff_size_t ffget_leng (void) { return ffleng; } /** Get the current token. * */ char *ffget_text (void) { return fftext; } /** Set the current line number. * @param line_number * */ void ffset_lineno (int line_number ) { fflineno = line_number; } /** Set the input stream. This does not discard the current * input buffer. * @param in_str A readable stream. * * @see ff_switch_to_buffer */ void ffset_in (FILE * in_str ) { ffin = in_str ; } void ffset_out (FILE * out_str ) { ffout = out_str ; } int ffget_debug (void) { return ff_flex_debug; } void ffset_debug (int bdebug ) { ff_flex_debug = bdebug ; } static int ff_init_globals (void) { /* Initialization is the same as for the non-reentrant scanner. * This function is called from fflex_destroy(), so don't allocate here. */ (ff_buffer_stack) = 0; (ff_buffer_stack_top) = 0; (ff_buffer_stack_max) = 0; (ff_c_buf_p) = (char *) 0; (ff_init) = 0; (ff_start) = 0; /* Defined in main.c */ #ifdef FF_STDINIT ffin = stdin; ffout = stdout; #else ffin = (FILE *) 0; ffout = (FILE *) 0; #endif /* For future reference: Set errno on error, since we are called by * fflex_init() */ return 0; } /* fflex_destroy is for both reentrant and non-reentrant scanners. */ int fflex_destroy (void) { /* Pop the buffer stack, destroying each element. */ while(FF_CURRENT_BUFFER){ ff_delete_buffer(FF_CURRENT_BUFFER ); FF_CURRENT_BUFFER_LVALUE = NULL; ffpop_buffer_state(); } /* Destroy the stack itself. */ yyfffree((ff_buffer_stack) ); (ff_buffer_stack) = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * fflex() is called, initialization will occur. */ ff_init_globals( ); return 0; } /* * Internal utility routines. */ #ifndef fftext_ptr static void ff_flex_strncpy (char* s1, ffconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef FF_NEED_STRLEN static int ff_flex_strlen (ffconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *ffalloc (ff_size_t size ) { return (void *) malloc( size ); } void *ffrealloc (void * ptr, ff_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void yyfffree (void * ptr ) { free( (char *) ptr ); /* see ffrealloc() for (char *) cast */ } #define FFTABLES_NAME "fftables" #line 457 "eval.l" int ffwrap() { /* MJT -- 13 June 1996 Supplied for compatibility with pre-2.5.1 versions of flex which do not recognize %option noffwrap */ return(1); } /* expr_read is lifted from old ftools.skel. Now we can use any version of flex with no .skel file necessary! MJT - 13 June 1996 keep a memory of how many bytes have been read previously, so that an unlimited-sized buffer can be supported. PDW - 28 Feb 1998 */ static int expr_read(char *buf, int nbytes) { int n; n = 0; if( !gParse.is_eobuf ) { do { buf[n++] = gParse.expr[gParse.index++]; } while ((nlng = varNum; } return( type ); } static int find_variable(char *varName) { int i; if( gParse.nCols ) for( i=0; i. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, especially those whose name start with FF_ or ff_. They are private implementation details that can be changed or removed. */ #ifndef FF_FF_Y_TAB_H_INCLUDED # define FF_FF_Y_TAB_H_INCLUDED /* Debug traces. */ #ifndef FFDEBUG # define FFDEBUG 0 #endif #if FFDEBUG extern int ffdebug; #endif /* Token kinds. */ #ifndef FFTOKENTYPE # define FFTOKENTYPE enum fftokentype { FFEMPTY = -2, FFEOF = 0, /* "end of file" */ FFerror = 256, /* error */ FFUNDEF = 257, /* "invalid token" */ BOOLEAN = 258, /* BOOLEAN */ LONG = 259, /* LONG */ DOUBLE = 260, /* DOUBLE */ STRING = 261, /* STRING */ BITSTR = 262, /* BITSTR */ FUNCTION = 263, /* FUNCTION */ BFUNCTION = 264, /* BFUNCTION */ IFUNCTION = 265, /* IFUNCTION */ GTIFILTER = 266, /* GTIFILTER */ GTIOVERLAP = 267, /* GTIOVERLAP */ REGFILTER = 268, /* REGFILTER */ COLUMN = 269, /* COLUMN */ BCOLUMN = 270, /* BCOLUMN */ SCOLUMN = 271, /* SCOLUMN */ BITCOL = 272, /* BITCOL */ ROWREF = 273, /* ROWREF */ NULLREF = 274, /* NULLREF */ SNULLREF = 275, /* SNULLREF */ OR = 276, /* OR */ AND = 277, /* AND */ EQ = 278, /* EQ */ NE = 279, /* NE */ GT = 280, /* GT */ LT = 281, /* LT */ LTE = 282, /* LTE */ GTE = 283, /* GTE */ XOR = 284, /* XOR */ POWER = 285, /* POWER */ NOT = 286, /* NOT */ INTCAST = 287, /* INTCAST */ FLTCAST = 288, /* FLTCAST */ UMINUS = 289, /* UMINUS */ ACCUM = 290, /* ACCUM */ DIFF = 291 /* DIFF */ }; typedef enum fftokentype fftoken_kind_t; #endif /* Token kinds. */ #define FFEMPTY -2 #define FFEOF 0 #define FFerror 256 #define FFUNDEF 257 #define BOOLEAN 258 #define LONG 259 #define DOUBLE 260 #define STRING 261 #define BITSTR 262 #define FUNCTION 263 #define BFUNCTION 264 #define IFUNCTION 265 #define GTIFILTER 266 #define GTIOVERLAP 267 #define REGFILTER 268 #define COLUMN 269 #define BCOLUMN 270 #define SCOLUMN 271 #define BITCOL 272 #define ROWREF 273 #define NULLREF 274 #define SNULLREF 275 #define OR 276 #define AND 277 #define EQ 278 #define NE 279 #define GT 280 #define LT 281 #define LTE 282 #define GTE 283 #define XOR 284 #define POWER 285 #define NOT 286 #define INTCAST 287 #define FLTCAST 288 #define UMINUS 289 #define ACCUM 290 #define DIFF 291 /* Value type. */ #if ! defined FFSTYPE && ! defined FFSTYPE_IS_DECLARED union FFSTYPE { #line 199 "eval.y" int Node; /* Index of Node */ double dbl; /* real value */ long lng; /* integer value */ char log; /* logical value */ char str[MAX_STRLEN]; /* string value */ #line 147 "y.tab.h" }; typedef union FFSTYPE FFSTYPE; # define FFSTYPE_IS_TRIVIAL 1 # define FFSTYPE_IS_DECLARED 1 #endif extern FFSTYPE fflval; int ffparse (void); #endif /* !FF_FF_Y_TAB_H_INCLUDED */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/eval_y.c0000644000175100001710000106230300000000000017553 0ustar00vstsdocker/* A Bison parser, made by GNU Bison 3.7.4. */ /* Bison implementation for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, especially those whose name start with FF_ or ff_. They are private implementation details that can be changed or removed. */ /* All symbols defined below should begin with ff or FF, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output, and Bison version. */ #define FFBISON 30704 /* Bison version string. */ #define FFBISON_VERSION "3.7.4" /* Skeleton name. */ #define FFSKELETON_NAME "yacc.c" /* Pure parsers. */ #define FFPURE 0 /* Push parsers. */ #define FFPUSH 0 /* Pull parsers. */ #define FFPULL 1 /* First part of user prologue. */ #line 1 "eval.y" /************************************************************************/ /* */ /* CFITSIO Lexical Parser */ /* */ /* This file is one of 3 files containing code which parses an */ /* arithmetic expression and evaluates it in the context of an input */ /* FITS file table extension. The CFITSIO lexical parser is divided */ /* into the following 3 parts/files: the CFITSIO "front-end", */ /* eval_f.c, contains the interface between the user/CFITSIO and the */ /* real core of the parser; the FLEX interpreter, eval_l.c, takes the */ /* input string and parses it into tokens and identifies the FITS */ /* information required to evaluate the expression (ie, keywords and */ /* columns); and, the BISON grammar and evaluation routines, eval_y.c, */ /* receives the FLEX output and determines and performs the actual */ /* operations. The files eval_l.c and eval_y.c are produced from */ /* running flex and bison on the files eval.l and eval.y, respectively. */ /* (flex and bison are available from any GNU archive: see www.gnu.org) */ /* */ /* The grammar rules, rather than evaluating the expression in situ, */ /* builds a tree, or Nodal, structure mapping out the order of */ /* operations and expression dependencies. This "compilation" process */ /* allows for much faster processing of multiple rows. This technique */ /* was developed by Uwe Lammers of the XMM Science Analysis System, */ /* although the CFITSIO implementation is entirely code original. */ /* */ /* */ /* Modification History: */ /* */ /* Kent Blackburn c1992 Original parser code developed for the */ /* FTOOLS software package, in particular, */ /* the fselect task. */ /* Kent Blackburn c1995 BIT column support added */ /* Peter D Wilson Feb 1998 Vector column support added */ /* Peter D Wilson May 1998 Ported to CFITSIO library. User */ /* interface routines written, in essence */ /* making fselect, fcalc, and maketime */ /* capabilities available to all tools */ /* via single function calls. */ /* Peter D Wilson Jun 1998 Major rewrite of parser core, so as to */ /* create a run-time evaluation tree, */ /* inspired by the work of Uwe Lammers, */ /* resulting in a speed increase of */ /* 10-100 times. */ /* Peter D Wilson Jul 1998 gtifilter(a,b,c,d) function added */ /* Peter D Wilson Aug 1998 regfilter(a,b,c,d) function added */ /* Peter D Wilson Jul 1999 Make parser fitsfile-independent, */ /* allowing a purely vector-based usage */ /* Craig B Markwardt Jun 2004 Add MEDIAN() function */ /* Craig B Markwardt Jun 2004 Add SUM(), and MIN/MAX() for bit arrays */ /* Craig B Markwardt Jun 2004 Allow subscripting of nX bit arrays */ /* Craig B Markwardt Jun 2004 Implement statistical functions */ /* NVALID(), AVERAGE(), and STDDEV() */ /* for integer and floating point vectors */ /* Craig B Markwardt Jun 2004 Use NULL values for range errors instead*/ /* of throwing a parse error */ /* Craig B Markwardt Oct 2004 Add ACCUM() and SEQDIFF() functions */ /* Craig B Markwardt Feb 2005 Add ANGSEP() function */ /* Craig B Markwardt Aug 2005 CIRCLE, BOX, ELLIPSE, NEAR and REGFILTER*/ /* functions now accept vector arguments */ /* Craig B Markwardt Sum 2006 Add RANDOMN() and RANDOMP() functions */ /* Craig B Markwardt Mar 2007 Allow arguments to RANDOM and RANDOMN to*/ /* determine the output dimensions */ /* Craig B Markwardt Aug 2009 Add substring STRMID() and string search*/ /* STRSTR() functions; more overflow checks*/ /* Craig B Markwardt Dec 2019 Add bit/hex/oct literal strings and */ /* bitwise operatiosn between integers */ /* Craig B Markwardt Mar 2021 Add SETNULL() function */ /* */ /************************************************************************/ #define APPROX 1.0e-7 #include "eval_defs.h" #include "region.h" #include #include #ifndef alloca #define alloca malloc #endif /* Random number generators for various distributions */ #include "simplerng.h" /* Shrink the initial stack depth to keep local data <32K (mac limit) */ /* yacc will allocate more space if needed, though. */ #define FFINITDEPTH 100 /***************************************************************/ /* Replace Bison's BACKUP macro with one that fixes a bug -- */ /* must update state after popping the stack -- and allows */ /* popping multiple terms at one time. */ /***************************************************************/ #define FFNEWBACKUP(token, value) \ do \ if (ffchar == FFEMPTY ) \ { ffchar = (token); \ memcpy( &fflval, &(value), sizeof(value) ); \ ffchar1 = FFTRANSLATE (ffchar); \ while (fflen--) FFPOPSTACK; \ ffstate = *ffssp; \ goto ffbackup; \ } \ else \ { fferror ("syntax error: cannot back up"); FFERROR; } \ while (0) /***************************************************************/ /* Useful macros for accessing/testing Nodes */ /***************************************************************/ #define TEST(a) if( (a)<0 ) FFERROR #define SIZE(a) gParse.Nodes[ a ].value.nelem #define TYPE(a) gParse.Nodes[ a ].type #define OPER(a) gParse.Nodes[ a ].operation #define PROMOTE(a,b) if( TYPE(a) > TYPE(b) ) \ b = New_Unary( TYPE(a), 0, b ); \ else if( TYPE(a) < TYPE(b) ) \ a = New_Unary( TYPE(b), 0, a ); /***** Internal functions *****/ #ifdef __cplusplus extern "C" { #endif static int Alloc_Node ( void ); static void Free_Last_Node( void ); static void Evaluate_Node ( int thisNode ); static int New_Const ( int returnType, void *value, long len ); static int New_Column( int ColNum ); static int New_Offset( int ColNum, int offset ); static int New_Unary ( int returnType, int Op, int Node1 ); static int New_BinOp ( int returnType, int Node1, int Op, int Node2 ); static int New_Func ( int returnType, funcOp Op, int nNodes, int Node1, int Node2, int Node3, int Node4, int Node5, int Node6, int Node7 ); static int New_FuncSize( int returnType, funcOp Op, int nNodes, int Node1, int Node2, int Node3, int Node4, int Node5, int Node6, int Node7, int Size); static int New_Deref ( int Var, int nDim, int Dim1, int Dim2, int Dim3, int Dim4, int Dim5 ); static int New_GTI ( funcOp Op, char *fname, int Node1, int Node2, char *start, char *stop ); static int New_REG ( char *fname, int NodeX, int NodeY, char *colNames ); static int New_Vector( int subNode ); static int Close_Vec ( int vecNode ); static int Locate_Col( Node *this ); static int Test_Dims ( int Node1, int Node2 ); static void Copy_Dims ( int Node1, int Node2 ); static void Allocate_Ptrs( Node *this ); static void Do_Unary ( Node *this ); static void Do_Offset ( Node *this ); static void Do_BinOp_bit ( Node *this ); static void Do_BinOp_str ( Node *this ); static void Do_BinOp_log ( Node *this ); static void Do_BinOp_lng ( Node *this ); static void Do_BinOp_dbl ( Node *this ); static void Do_Func ( Node *this ); static void Do_Deref ( Node *this ); static void Do_GTI ( Node *this ); static void Do_GTI_Over ( Node *this ); static void Do_REG ( Node *this ); static void Do_Vector ( Node *this ); static long Search_GTI ( double evtTime, long nGTI, double *start, double *stop, int ordered, long *nextGTI ); static double GTI_Over(double evtStart, double evtStop, long nGTI, double *start, double *stop, long *gtiout); static char saobox (double xcen, double ycen, double xwid, double ywid, double rot, double xcol, double ycol); static char ellipse(double xcen, double ycen, double xrad, double yrad, double rot, double xcol, double ycol); static char circle (double xcen, double ycen, double rad, double xcol, double ycol); static char bnear (double x, double y, double tolerance); static char bitcmp (char *bitstrm1, char *bitstrm2); static char bitlgte(char *bits1, int oper, char *bits2); static void bitand(char *result, char *bitstrm1, char *bitstrm2); static void bitor (char *result, char *bitstrm1, char *bitstrm2); static void bitnot(char *result, char *bits); static int cstrmid(char *dest_str, int dest_len, char *src_str, int src_len, int pos); static void fferror(char *msg); #ifdef __cplusplus } #endif #line 269 "y.tab.c" # ifndef FF_CAST # ifdef __cplusplus # define FF_CAST(Type, Val) static_cast (Val) # define FF_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) # else # define FF_CAST(Type, Val) ((Type) (Val)) # define FF_REINTERPRET_CAST(Type, Val) ((Type) (Val)) # endif # endif # ifndef FF_NULLPTR # if defined __cplusplus # if 201103L <= __cplusplus # define FF_NULLPTR nullptr # else # define FF_NULLPTR 0 # endif # else # define FF_NULLPTR ((void*)0) # endif # endif /* Use api.header.include to #include this header instead of duplicating it here. */ #ifndef FF_FF_Y_TAB_H_INCLUDED # define FF_FF_Y_TAB_H_INCLUDED /* Debug traces. */ #ifndef FFDEBUG # define FFDEBUG 0 #endif #if FFDEBUG extern int ffdebug; #endif /* Token kinds. */ #ifndef FFTOKENTYPE # define FFTOKENTYPE enum fftokentype { FFEMPTY = -2, FFEOF = 0, /* "end of file" */ FFerror = 256, /* error */ FFUNDEF = 257, /* "invalid token" */ BOOLEAN = 258, /* BOOLEAN */ LONG = 259, /* LONG */ DOUBLE = 260, /* DOUBLE */ STRING = 261, /* STRING */ BITSTR = 262, /* BITSTR */ FUNCTION = 263, /* FUNCTION */ BFUNCTION = 264, /* BFUNCTION */ IFUNCTION = 265, /* IFUNCTION */ GTIFILTER = 266, /* GTIFILTER */ GTIOVERLAP = 267, /* GTIOVERLAP */ REGFILTER = 268, /* REGFILTER */ COLUMN = 269, /* COLUMN */ BCOLUMN = 270, /* BCOLUMN */ SCOLUMN = 271, /* SCOLUMN */ BITCOL = 272, /* BITCOL */ ROWREF = 273, /* ROWREF */ NULLREF = 274, /* NULLREF */ SNULLREF = 275, /* SNULLREF */ OR = 276, /* OR */ AND = 277, /* AND */ EQ = 278, /* EQ */ NE = 279, /* NE */ GT = 280, /* GT */ LT = 281, /* LT */ LTE = 282, /* LTE */ GTE = 283, /* GTE */ XOR = 284, /* XOR */ POWER = 285, /* POWER */ NOT = 286, /* NOT */ INTCAST = 287, /* INTCAST */ FLTCAST = 288, /* FLTCAST */ UMINUS = 289, /* UMINUS */ ACCUM = 290, /* ACCUM */ DIFF = 291 /* DIFF */ }; typedef enum fftokentype fftoken_kind_t; #endif /* Token kinds. */ #define FFEMPTY -2 #define FFEOF 0 #define FFerror 256 #define FFUNDEF 257 #define BOOLEAN 258 #define LONG 259 #define DOUBLE 260 #define STRING 261 #define BITSTR 262 #define FUNCTION 263 #define BFUNCTION 264 #define IFUNCTION 265 #define GTIFILTER 266 #define GTIOVERLAP 267 #define REGFILTER 268 #define COLUMN 269 #define BCOLUMN 270 #define SCOLUMN 271 #define BITCOL 272 #define ROWREF 273 #define NULLREF 274 #define SNULLREF 275 #define OR 276 #define AND 277 #define EQ 278 #define NE 279 #define GT 280 #define LT 281 #define LTE 282 #define GTE 283 #define XOR 284 #define POWER 285 #define NOT 286 #define INTCAST 287 #define FLTCAST 288 #define UMINUS 289 #define ACCUM 290 #define DIFF 291 /* Value type. */ #if ! defined FFSTYPE && ! defined FFSTYPE_IS_DECLARED union FFSTYPE { #line 199 "eval.y" int Node; /* Index of Node */ double dbl; /* real value */ long lng; /* integer value */ char log; /* logical value */ char str[MAX_STRLEN]; /* string value */ #line 402 "y.tab.c" }; typedef union FFSTYPE FFSTYPE; # define FFSTYPE_IS_TRIVIAL 1 # define FFSTYPE_IS_DECLARED 1 #endif extern FFSTYPE fflval; int ffparse (void); #endif /* !FF_FF_Y_TAB_H_INCLUDED */ /* Symbol kind. */ enum ffsymbol_kind_t { FFSYMBOL_FFEMPTY = -2, FFSYMBOL_FFEOF = 0, /* "end of file" */ FFSYMBOL_FFerror = 1, /* error */ FFSYMBOL_FFUNDEF = 2, /* "invalid token" */ FFSYMBOL_BOOLEAN = 3, /* BOOLEAN */ FFSYMBOL_LONG = 4, /* LONG */ FFSYMBOL_DOUBLE = 5, /* DOUBLE */ FFSYMBOL_STRING = 6, /* STRING */ FFSYMBOL_BITSTR = 7, /* BITSTR */ FFSYMBOL_FUNCTION = 8, /* FUNCTION */ FFSYMBOL_BFUNCTION = 9, /* BFUNCTION */ FFSYMBOL_IFUNCTION = 10, /* IFUNCTION */ FFSYMBOL_GTIFILTER = 11, /* GTIFILTER */ FFSYMBOL_GTIOVERLAP = 12, /* GTIOVERLAP */ FFSYMBOL_REGFILTER = 13, /* REGFILTER */ FFSYMBOL_COLUMN = 14, /* COLUMN */ FFSYMBOL_BCOLUMN = 15, /* BCOLUMN */ FFSYMBOL_SCOLUMN = 16, /* SCOLUMN */ FFSYMBOL_BITCOL = 17, /* BITCOL */ FFSYMBOL_ROWREF = 18, /* ROWREF */ FFSYMBOL_NULLREF = 19, /* NULLREF */ FFSYMBOL_SNULLREF = 20, /* SNULLREF */ FFSYMBOL_21_ = 21, /* ',' */ FFSYMBOL_22_ = 22, /* '=' */ FFSYMBOL_23_ = 23, /* ':' */ FFSYMBOL_24_ = 24, /* '{' */ FFSYMBOL_25_ = 25, /* '}' */ FFSYMBOL_26_ = 26, /* '?' */ FFSYMBOL_OR = 27, /* OR */ FFSYMBOL_AND = 28, /* AND */ FFSYMBOL_EQ = 29, /* EQ */ FFSYMBOL_NE = 30, /* NE */ FFSYMBOL_31_ = 31, /* '~' */ FFSYMBOL_GT = 32, /* GT */ FFSYMBOL_LT = 33, /* LT */ FFSYMBOL_LTE = 34, /* LTE */ FFSYMBOL_GTE = 35, /* GTE */ FFSYMBOL_36_ = 36, /* '+' */ FFSYMBOL_37_ = 37, /* '-' */ FFSYMBOL_38_ = 38, /* '%' */ FFSYMBOL_39_ = 39, /* '*' */ FFSYMBOL_40_ = 40, /* '/' */ FFSYMBOL_41_ = 41, /* '|' */ FFSYMBOL_42_ = 42, /* '&' */ FFSYMBOL_XOR = 43, /* XOR */ FFSYMBOL_POWER = 44, /* POWER */ FFSYMBOL_NOT = 45, /* NOT */ FFSYMBOL_INTCAST = 46, /* INTCAST */ FFSYMBOL_FLTCAST = 47, /* FLTCAST */ FFSYMBOL_UMINUS = 48, /* UMINUS */ FFSYMBOL_49_ = 49, /* '[' */ FFSYMBOL_ACCUM = 50, /* ACCUM */ FFSYMBOL_DIFF = 51, /* DIFF */ FFSYMBOL_52_n_ = 52, /* '\n' */ FFSYMBOL_53_ = 53, /* ']' */ FFSYMBOL_54_ = 54, /* '(' */ FFSYMBOL_55_ = 55, /* ')' */ FFSYMBOL_FFACCEPT = 56, /* $accept */ FFSYMBOL_lines = 57, /* lines */ FFSYMBOL_line = 58, /* line */ FFSYMBOL_bvector = 59, /* bvector */ FFSYMBOL_vector = 60, /* vector */ FFSYMBOL_expr = 61, /* expr */ FFSYMBOL_bexpr = 62, /* bexpr */ FFSYMBOL_bits = 63, /* bits */ FFSYMBOL_sexpr = 64 /* sexpr */ }; typedef enum ffsymbol_kind_t ffsymbol_kind_t; #ifdef short # undef short #endif /* On compilers that do not define __PTRDIFF_MAX__ etc., make sure and (if available) are included so that the code can choose integer types of a good width. */ #ifndef __PTRDIFF_MAX__ # include /* INFRINGES ON USER NAME SPACE */ # if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define FF_STDINT_H # endif #endif /* Narrow types that promote to a signed type and that can represent a signed or unsigned integer of at least N bits. In tables they can save space and decrease cache pressure. Promoting to a signed type helps avoid bugs in integer arithmetic. */ #ifdef __INT_LEAST8_MAX__ typedef __INT_LEAST8_TYPE__ fftype_int8; #elif defined FF_STDINT_H typedef int_least8_t fftype_int8; #else typedef signed char fftype_int8; #endif #ifdef __INT_LEAST16_MAX__ typedef __INT_LEAST16_TYPE__ fftype_int16; #elif defined FF_STDINT_H typedef int_least16_t fftype_int16; #else typedef short fftype_int16; #endif #if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ typedef __UINT_LEAST8_TYPE__ fftype_uint8; #elif (!defined __UINT_LEAST8_MAX__ && defined FF_STDINT_H \ && UINT_LEAST8_MAX <= INT_MAX) typedef uint_least8_t fftype_uint8; #elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX typedef unsigned char fftype_uint8; #else typedef short fftype_uint8; #endif #if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ typedef __UINT_LEAST16_TYPE__ fftype_uint16; #elif (!defined __UINT_LEAST16_MAX__ && defined FF_STDINT_H \ && UINT_LEAST16_MAX <= INT_MAX) typedef uint_least16_t fftype_uint16; #elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX typedef unsigned short fftype_uint16; #else typedef int fftype_uint16; #endif #ifndef FFPTRDIFF_T # if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ # define FFPTRDIFF_T __PTRDIFF_TYPE__ # define FFPTRDIFF_MAXIMUM __PTRDIFF_MAX__ # elif defined PTRDIFF_MAX # ifndef ptrdiff_t # include /* INFRINGES ON USER NAME SPACE */ # endif # define FFPTRDIFF_T ptrdiff_t # define FFPTRDIFF_MAXIMUM PTRDIFF_MAX # else # define FFPTRDIFF_T long # define FFPTRDIFF_MAXIMUM LONG_MAX # endif #endif #ifndef FFSIZE_T # ifdef __SIZE_TYPE__ # define FFSIZE_T __SIZE_TYPE__ # elif defined size_t # define FFSIZE_T size_t # elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define FFSIZE_T size_t # else # define FFSIZE_T unsigned # endif #endif #define FFSIZE_MAXIMUM \ FF_CAST (FFPTRDIFF_T, \ (FFPTRDIFF_MAXIMUM < FF_CAST (FFSIZE_T, -1) \ ? FFPTRDIFF_MAXIMUM \ : FF_CAST (FFSIZE_T, -1))) #define FFSIZEOF(X) FF_CAST (FFPTRDIFF_T, sizeof (X)) /* Stored state numbers (used for stacks). */ typedef fftype_int16 ff_state_t; /* State numbers in computations. */ typedef int ff_state_fast_t; #ifndef FF_ # if defined FFENABLE_NLS && FFENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define FF_(Msgid) dgettext ("bison-runtime", Msgid) # endif # endif # ifndef FF_ # define FF_(Msgid) Msgid # endif #endif #ifndef FF_ATTRIBUTE_PURE # if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) # define FF_ATTRIBUTE_PURE __attribute__ ((__pure__)) # else # define FF_ATTRIBUTE_PURE # endif #endif #ifndef FF_ATTRIBUTE_UNUSED # if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) # define FF_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) # else # define FF_ATTRIBUTE_UNUSED # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define FFUSE(E) ((void) (E)) #else # define FFUSE(E) /* empty */ #endif #if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ /* Suppress an incorrect diagnostic about fflval being uninitialized. */ # define FF_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") # define FF_IGNORE_MAYBE_UNINITIALIZED_END \ _Pragma ("GCC diagnostic pop") #else # define FF_INITIAL_VALUE(Value) Value #endif #ifndef FF_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define FF_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define FF_IGNORE_MAYBE_UNINITIALIZED_END #endif #ifndef FF_INITIAL_VALUE # define FF_INITIAL_VALUE(Value) /* Nothing. */ #endif #if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ # define FF_IGNORE_USELESS_CAST_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") # define FF_IGNORE_USELESS_CAST_END \ _Pragma ("GCC diagnostic pop") #endif #ifndef FF_IGNORE_USELESS_CAST_BEGIN # define FF_IGNORE_USELESS_CAST_BEGIN # define FF_IGNORE_USELESS_CAST_END #endif #define FF_ASSERT(E) ((void) (0 && (E))) #if !defined ffoverflow /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef FFSTACK_USE_ALLOCA # if FFSTACK_USE_ALLOCA # ifdef __GNUC__ # define FFSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define FFSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define FFSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS # include /* INFRINGES ON USER NAME SPACE */ /* Use EXIT_SUCCESS as a witness for stdlib.h. */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # endif # endif # endif # ifdef FFSTACK_ALLOC /* Pacify GCC's 'empty if-body' warning. */ # define FFSTACK_FREE(Ptr) do { /* empty */; } while (0) # ifndef FFSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define FFSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define FFSTACK_ALLOC FFMALLOC # define FFSTACK_FREE FFFREE # ifndef FFSTACK_ALLOC_MAXIMUM # define FFSTACK_ALLOC_MAXIMUM FFSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined FFMALLOC || defined malloc) \ && (defined FFFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # ifndef FFMALLOC # define FFMALLOC malloc # if ! defined malloc && ! defined EXIT_SUCCESS void *malloc (FFSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef FFFREE # define FFFREE free # if ! defined free && ! defined EXIT_SUCCESS void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* !defined ffoverflow */ #if (! defined ffoverflow \ && (! defined __cplusplus \ || (defined FFSTYPE_IS_TRIVIAL && FFSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union ffalloc { ff_state_t ffss_alloc; FFSTYPE ffvs_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ # define FFSTACK_GAP_MAXIMUM (FFSIZEOF (union ffalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define FFSTACK_BYTES(N) \ ((N) * (FFSIZEOF (ff_state_t) + FFSIZEOF (FFSTYPE)) \ + FFSTACK_GAP_MAXIMUM) # define FFCOPY_NEEDED 1 /* Relocate STACK from its old location to the new one. The local variables FFSIZE and FFSTACKSIZE give the old and new number of elements in the stack, and FFPTR gives the new location of the stack. Advance FFPTR to a properly aligned location for the next stack. */ # define FFSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ FFPTRDIFF_T ffnewbytes; \ FFCOPY (&ffptr->Stack_alloc, Stack, ffsize); \ Stack = &ffptr->Stack_alloc; \ ffnewbytes = ffstacksize * FFSIZEOF (*Stack) + FFSTACK_GAP_MAXIMUM; \ ffptr += ffnewbytes / FFSIZEOF (*ffptr); \ } \ while (0) #endif #if defined FFCOPY_NEEDED && FFCOPY_NEEDED /* Copy COUNT objects from SRC to DST. The source and destination do not overlap. */ # ifndef FFCOPY # if defined __GNUC__ && 1 < __GNUC__ # define FFCOPY(Dst, Src, Count) \ __builtin_memcpy (Dst, Src, FF_CAST (FFSIZE_T, (Count)) * sizeof (*(Src))) # else # define FFCOPY(Dst, Src, Count) \ do \ { \ FFPTRDIFF_T ffi; \ for (ffi = 0; ffi < (Count); ffi++) \ (Dst)[ffi] = (Src)[ffi]; \ } \ while (0) # endif # endif #endif /* !FFCOPY_NEEDED */ /* FFFINAL -- State number of the termination state. */ #define FFFINAL 2 /* FFLAST -- Last index in FFTABLE. */ #define FFLAST 1725 /* FFNTOKENS -- Number of terminals. */ #define FFNTOKENS 56 /* FFNNTS -- Number of nonterminals. */ #define FFNNTS 9 /* FFNRULES -- Number of rules. */ #define FFNRULES 130 /* FFNSTATES -- Number of states. */ #define FFNSTATES 308 /* FFMAXUTOK -- Last valid token kind. */ #define FFMAXUTOK 291 /* FFTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM as returned by fflex, with out-of-bounds checking. */ #define FFTRANSLATE(FFX) \ (0 <= (FFX) && (FFX) <= FFMAXUTOK \ ? FF_CAST (ffsymbol_kind_t, fftranslate[FFX]) \ : FFSYMBOL_FFUNDEF) /* FFTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM as returned by fflex. */ static const fftype_int8 fftranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 52, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 38, 42, 2, 54, 55, 39, 36, 21, 37, 2, 40, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 23, 2, 2, 22, 2, 26, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 49, 2, 53, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 24, 41, 25, 31, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 27, 28, 29, 30, 32, 33, 34, 35, 43, 44, 45, 46, 47, 48, 50, 51 }; #if FFDEBUG /* FFRLINE[FFN] -- Source line where rule number FFN was defined. */ static const fftype_int16 ffrline[] = { 0, 252, 252, 253, 256, 257, 263, 269, 275, 281, 284, 286, 299, 301, 314, 325, 339, 343, 347, 351, 353, 362, 365, 368, 377, 379, 381, 383, 385, 387, 390, 394, 396, 398, 400, 409, 411, 413, 416, 419, 422, 425, 428, 437, 446, 455, 458, 460, 462, 464, 468, 472, 491, 510, 529, 540, 554, 566, 597, 692, 700, 761, 785, 787, 789, 791, 793, 795, 797, 799, 801, 805, 807, 809, 818, 821, 824, 827, 830, 833, 836, 839, 842, 845, 848, 851, 854, 857, 860, 863, 866, 869, 872, 875, 877, 879, 881, 884, 891, 908, 921, 934, 945, 961, 985, 1013, 1050, 1054, 1058, 1061, 1066, 1069, 1074, 1078, 1081, 1085, 1087, 1089, 1091, 1093, 1095, 1097, 1101, 1104, 1106, 1115, 1117, 1119, 1128, 1147, 1166 }; #endif /** Accessing symbol of state STATE. */ #define FF_ACCESSING_SYMBOL(State) FF_CAST (ffsymbol_kind_t, ffstos[State]) #if FFDEBUG || 0 /* The user-facing name of the symbol whose (internal) number is FFSYMBOL. No bounds checking. */ static const char *ffsymbol_name (ffsymbol_kind_t ffsymbol) FF_ATTRIBUTE_UNUSED; /* FFTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at FFNTOKENS, nonterminals. */ static const char *const fftname[] = { "\"end of file\"", "error", "\"invalid token\"", "BOOLEAN", "LONG", "DOUBLE", "STRING", "BITSTR", "FUNCTION", "BFUNCTION", "IFUNCTION", "GTIFILTER", "GTIOVERLAP", "REGFILTER", "COLUMN", "BCOLUMN", "SCOLUMN", "BITCOL", "ROWREF", "NULLREF", "SNULLREF", "','", "'='", "':'", "'{'", "'}'", "'?'", "OR", "AND", "EQ", "NE", "'~'", "GT", "LT", "LTE", "GTE", "'+'", "'-'", "'%'", "'*'", "'/'", "'|'", "'&'", "XOR", "POWER", "NOT", "INTCAST", "FLTCAST", "UMINUS", "'['", "ACCUM", "DIFF", "'\\n'", "']'", "'('", "')'", "$accept", "lines", "line", "bvector", "vector", "expr", "bexpr", "bits", "sexpr", FF_NULLPTR }; static const char * ffsymbol_name (ffsymbol_kind_t ffsymbol) { return fftname[ffsymbol]; } #endif #ifdef FFPRINT /* FFTOKNUM[NUM] -- (External) token number corresponding to the (internal) symbol number NUM (which must be that of a token). */ static const fftype_int16 fftoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 44, 61, 58, 123, 125, 63, 276, 277, 278, 279, 126, 280, 281, 282, 283, 43, 45, 37, 42, 47, 124, 38, 284, 285, 286, 287, 288, 289, 91, 290, 291, 10, 93, 40, 41 }; #endif #define FFPACT_NINF (-40) #define ffpact_value_is_default(Yyn) \ ((Yyn) == FFPACT_NINF) #define FFTABLE_NINF (-1) #define fftable_value_is_error(Yyn) \ 0 /* FFPACT[STATE-NUM] -- Index in FFTABLE of the portion describing STATE-NUM. */ static const fftype_int16 ffpact[] = { -40, 337, -40, -39, -40, -40, -40, -40, -40, 389, 442, 442, -5, 21, 29, 17, 25, 44, 45, -40, -40, -40, 442, 442, 442, 442, 442, 442, -40, 442, -40, -15, 19, 1159, 443, 1584, 1605, -40, -40, 276, -10, 330, 133, 469, 144, 1647, 248, 1526, 209, 1689, -19, -40, 49, -18, 442, 442, 442, 442, 1526, 209, 294, -6, -6, 24, 26, -6, 24, -6, 24, 671, 1186, 382, 1544, 442, -40, 442, -40, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, -40, 442, 442, 442, 442, 442, 442, 442, -40, -3, -3, -3, -3, -3, -3, -3, -3, -3, 442, -40, 442, 442, 442, 442, 442, 442, 442, -40, 442, -40, 442, -40, -40, 442, -40, 442, -40, -40, -40, 442, 442, -40, 442, 442, -40, 1388, 1411, 1434, 1457, -40, -40, -40, -40, 1526, 209, 1526, 209, 1480, 1665, 1665, 1665, 22, 22, 22, 22, 203, 203, 203, 148, 24, 148, -37, -37, -37, -37, 784, 1503, 1558, 1619, 18, 69, -34, -34, 148, 809, -3, -3, 111, 111, 111, 111, 111, 111, -11, 26, 26, 834, 406, 406, 58, 58, 58, 58, -40, 498, 1191, 1221, 1560, 1245, 1576, 527, 1269, 1293, -40, -40, -40, -40, 442, 442, -40, 442, 442, 442, 442, -40, 26, 68, 442, -40, 442, -40, -40, 442, -40, 442, -40, 90, -40, 442, 442, 1629, 859, 1629, 209, 1629, 209, 294, 884, 909, 1317, 699, 556, 76, 585, 614, 442, -40, 442, -40, 442, -40, 442, -40, 442, -40, 96, 97, -40, 99, -40, 934, 959, 984, 727, 1341, 51, 92, 56, 442, -40, 442, -40, 442, -40, -40, 442, -40, 108, -40, 1009, 1034, 1059, 643, 65, 442, -40, 442, -40, 442, -40, 442, -40, -40, 1084, 1109, 1134, 1365, -40, -40, -40, 442, 755, -40 }; /* FFDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. Performed when FFTABLE does not specify something else to do. Zero means the default is an error. */ static const fftype_uint8 ffdefact[] = { 2, 0, 1, 0, 71, 31, 32, 122, 18, 0, 0, 0, 0, 0, 0, 33, 72, 123, 19, 35, 36, 125, 0, 0, 0, 0, 0, 0, 4, 0, 3, 0, 0, 0, 0, 0, 0, 9, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 0, 0, 0, 0, 0, 0, 12, 10, 0, 46, 47, 120, 29, 67, 68, 69, 70, 0, 0, 0, 0, 0, 17, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 7, 0, 58, 0, 55, 57, 0, 56, 0, 99, 100, 101, 0, 0, 107, 0, 0, 112, 0, 0, 0, 0, 48, 121, 30, 126, 15, 11, 13, 14, 0, 85, 86, 84, 80, 81, 83, 82, 38, 39, 37, 40, 49, 41, 43, 42, 44, 45, 0, 0, 0, 0, 94, 93, 95, 96, 50, 0, 0, 0, 74, 75, 78, 76, 77, 79, 23, 22, 21, 0, 87, 88, 89, 91, 92, 90, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 73, 124, 20, 0, 0, 62, 0, 0, 0, 0, 115, 29, 0, 0, 24, 0, 60, 102, 0, 129, 0, 59, 0, 108, 0, 0, 97, 0, 51, 53, 52, 98, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 116, 0, 25, 0, 130, 0, 103, 0, 0, 110, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 117, 0, 26, 61, 0, 109, 0, 114, 0, 0, 0, 0, 0, 0, 65, 0, 118, 0, 27, 0, 104, 111, 0, 0, 0, 0, 66, 119, 28, 0, 0, 105 }; /* FFPGOTO[NTERM-NUM]. */ static const fftype_int16 ffpgoto[] = { -40, -40, -40, -40, -40, -1, 106, 155, 23 }; /* FFDEFGOTO[NTERM-NUM]. */ static const fftype_int8 ffdefgoto[] = { -1, 1, 30, 31, 32, 47, 48, 45, 60 }; /* FFTABLE[FFPACT[STATE-NUM]] -- What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule whose number is the opposite. If FFTABLE_NINF, syntax error. */ static const fftype_int16 fftable[] = { 33, 50, 135, 138, 8, 101, 73, 93, 39, 43, 74, 125, 94, 37, 18, 102, 96, 97, 98, 99, 100, 58, 61, 62, 36, 65, 67, 52, 69, 101, 111, 112, 42, 46, 49, 53, 136, 139, 113, 102, 75, 54, 180, 94, 76, 126, 98, 99, 100, 55, 51, 181, 72, 140, 141, 142, 143, 101, 85, 86, 87, 88, 89, 90, 91, 92, 93, 102, 56, 57, 137, 94, 148, 102, 150, 113, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 165, 166, 167, 168, 169, 170, 121, 171, 247, 260, 99, 100, 178, 179, 270, 271, 110, 272, 281, 34, 101, 111, 112, 283, 191, 282, 288, 40, 44, 113, 102, 173, 297, 0, 199, 146, 0, 0, 0, 201, 59, 203, 0, 63, 66, 68, 205, 70, 206, 207, 192, 193, 194, 195, 196, 197, 198, 0, 0, 110, 0, 0, 0, 202, 111, 112, 128, 0, 35, 204, 0, 0, 113, 0, 115, 116, 41, 117, 118, 119, 120, 121, 96, 97, 98, 99, 100, 0, 0, 0, 0, 149, 64, 151, 0, 101, 71, 0, 0, 0, 129, 90, 91, 92, 93, 102, 164, 0, 0, 94, 0, 132, 0, 0, 172, 174, 175, 176, 177, 0, 0, 0, 0, 235, 236, 0, 237, 239, 0, 242, 0, 0, 0, 243, 0, 244, 0, 0, 245, 0, 246, 0, 0, 200, 248, 249, 0, 96, 97, 98, 99, 100, 241, 0, 88, 89, 90, 91, 92, 93, 101, 265, 0, 266, 94, 267, 0, 268, 0, 269, 102, 182, 183, 184, 185, 186, 187, 188, 189, 190, 0, 0, 0, 0, 284, 0, 285, 0, 286, 115, 116, 287, 117, 118, 119, 120, 121, 0, 0, 0, 298, 0, 299, 0, 300, 0, 301, 0, 0, 123, 77, 0, 0, 0, 0, 133, 306, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 238, 240, 115, 116, 94, 117, 118, 119, 120, 121, 124, 0, 0, 0, 220, 221, 2, 3, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 0, 104, 105, 22, 106, 107, 108, 109, 110, 0, 0, 0, 0, 111, 112, 23, 24, 0, 0, 0, 0, 113, 0, 0, 25, 26, 27, 127, 0, 0, 0, 28, 0, 29, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 0, 104, 105, 22, 106, 107, 108, 109, 110, 0, 0, 0, 0, 111, 112, 23, 24, 0, 0, 0, 0, 113, 0, 0, 25, 26, 27, 146, 117, 118, 119, 120, 121, 29, 38, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 0, 0, 0, 22, 0, 0, 96, 97, 98, 99, 100, 0, 0, 0, 0, 23, 24, 0, 0, 101, 0, 0, 0, 0, 25, 26, 27, 130, 77, 102, 0, 0, 103, 29, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 0, 0, 0, 94, 224, 77, 0, 0, 0, 131, 0, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 0, 0, 0, 94, 231, 77, 0, 0, 0, 225, 0, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 0, 0, 0, 94, 258, 77, 0, 0, 0, 232, 0, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 0, 0, 0, 94, 261, 77, 0, 0, 0, 259, 0, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 0, 0, 0, 94, 263, 77, 0, 0, 0, 262, 0, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 0, 0, 0, 94, 295, 77, 0, 0, 0, 264, 0, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 0, 0, 0, 94, 77, 0, 0, 0, 0, 296, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 0, 0, 0, 94, 77, 0, 0, 0, 0, 144, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 0, 0, 0, 94, 77, 0, 0, 0, 0, 257, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 0, 0, 0, 94, 77, 0, 0, 0, 0, 279, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 0, 0, 0, 94, 213, 77, 0, 0, 0, 307, 0, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 218, 77, 0, 94, 0, 0, 0, 214, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 222, 77, 0, 94, 0, 0, 0, 219, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 250, 77, 0, 94, 0, 0, 0, 223, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 252, 77, 0, 94, 0, 0, 0, 251, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 254, 77, 0, 94, 0, 0, 0, 253, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 273, 77, 0, 94, 0, 0, 0, 255, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 275, 77, 0, 94, 0, 0, 0, 274, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 277, 77, 0, 94, 0, 0, 0, 276, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 289, 77, 0, 94, 0, 0, 0, 278, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 291, 77, 0, 94, 0, 0, 0, 290, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 293, 77, 0, 94, 0, 0, 0, 292, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 0, 77, 0, 94, 0, 0, 0, 294, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 0, 77, 0, 94, 0, 0, 0, 302, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 0, 77, 0, 94, 0, 0, 0, 303, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 0, 77, 0, 94, 0, 0, 0, 304, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 0, 0, 0, 94, 0, 0, 95, 96, 97, 98, 99, 100, 96, 97, 98, 99, 100, 0, 0, 0, 101, 0, 0, 0, 0, 101, 0, 0, 0, 0, 102, 0, 0, 0, 0, 102, 145, 227, 77, 0, 0, 226, 0, 0, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 229, 77, 0, 0, 94, 0, 0, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 233, 77, 0, 0, 94, 0, 0, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 234, 77, 0, 0, 94, 0, 0, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 256, 77, 0, 0, 94, 0, 0, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 280, 77, 0, 0, 94, 0, 0, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 305, 77, 0, 0, 94, 0, 0, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 77, 0, 0, 208, 94, 0, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 77, 0, 0, 209, 94, 0, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 77, 0, 0, 210, 94, 0, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 77, 0, 0, 211, 94, 0, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 77, 212, 0, 0, 94, 0, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 77, 215, 0, 0, 94, 0, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 77, 0, 0, 0, 94, 0, 0, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 0, 115, 116, 94, 117, 118, 119, 120, 121, 216, 0, 0, 96, 97, 98, 99, 100, 115, 116, 0, 117, 118, 119, 120, 121, 101, 0, 147, 0, 0, 0, 0, 0, 115, 116, 102, 117, 118, 119, 120, 121, 104, 105, 228, 106, 107, 108, 109, 110, 0, 0, 0, 0, 111, 112, 0, 0, 0, 0, 230, 0, 113, 115, 116, 114, 117, 118, 119, 120, 121, 217, 0, 0, 0, 0, 0, 115, 116, 0, 117, 118, 119, 120, 121, 0, 122, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 0, 104, 105, 94, 106, 107, 108, 109, 110, 0, 0, 0, 0, 111, 112, 0, 0, 0, 0, 0, 0, 113, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 134, 0, 0, 0, 94, 0, 0, 0, 115, 116, 0, 117, 118, 119, 120, 121 }; static const fftype_int16 ffcheck[] = { 1, 6, 21, 21, 7, 39, 21, 44, 9, 10, 25, 21, 49, 52, 17, 49, 26, 27, 28, 29, 30, 22, 23, 24, 1, 26, 27, 6, 29, 39, 41, 42, 9, 10, 11, 6, 55, 55, 49, 49, 21, 24, 45, 49, 25, 55, 28, 29, 30, 24, 55, 54, 29, 54, 55, 56, 57, 39, 36, 37, 38, 39, 40, 41, 42, 43, 44, 49, 24, 24, 21, 49, 73, 49, 75, 49, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 36, 96, 6, 21, 29, 30, 101, 102, 6, 6, 36, 6, 55, 1, 39, 41, 42, 55, 113, 21, 6, 9, 10, 49, 49, 96, 55, -1, 123, 55, -1, -1, -1, 128, 22, 130, -1, 25, 26, 27, 135, 29, 137, 138, 115, 116, 117, 118, 119, 120, 121, -1, -1, 36, -1, -1, -1, 128, 41, 42, 21, -1, 1, 134, -1, -1, 49, -1, 29, 30, 9, 32, 33, 34, 35, 36, 26, 27, 28, 29, 30, -1, -1, -1, -1, 73, 25, 75, -1, 39, 29, -1, -1, -1, 55, 41, 42, 43, 44, 49, 88, -1, -1, 49, -1, 55, -1, -1, 96, 97, 98, 99, 100, -1, -1, -1, -1, 212, 213, -1, 215, 216, -1, 218, -1, -1, -1, 222, -1, 224, -1, -1, 227, -1, 229, -1, -1, 125, 233, 234, -1, 26, 27, 28, 29, 30, 217, -1, 39, 40, 41, 42, 43, 44, 39, 250, -1, 252, 49, 254, -1, 256, -1, 258, 49, 104, 105, 106, 107, 108, 109, 110, 111, 112, -1, -1, -1, -1, 273, -1, 275, -1, 277, 29, 30, 280, 32, 33, 34, 35, 36, -1, -1, -1, 289, -1, 291, -1, 293, -1, 295, -1, -1, 21, 22, -1, -1, -1, -1, 55, 305, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 215, 216, 29, 30, 49, 32, 33, 34, 35, 36, 55, -1, -1, -1, 180, 181, 0, 1, -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, -1, 29, 30, 24, 32, 33, 34, 35, 36, -1, -1, -1, -1, 41, 42, 36, 37, -1, -1, -1, -1, 49, -1, -1, 45, 46, 47, 55, -1, -1, -1, 52, -1, 54, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, -1, 29, 30, 24, 32, 33, 34, 35, 36, -1, -1, -1, -1, 41, 42, 36, 37, -1, -1, -1, -1, 49, -1, -1, 45, 46, 47, 55, 32, 33, 34, 35, 36, 54, 55, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, -1, -1, -1, 24, -1, -1, 26, 27, 28, 29, 30, -1, -1, -1, -1, 36, 37, -1, -1, 39, -1, -1, -1, -1, 45, 46, 47, 21, 22, 49, -1, -1, 52, 54, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, -1, -1, -1, 49, 21, 22, -1, -1, -1, 55, -1, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, -1, -1, -1, 49, 21, 22, -1, -1, -1, 55, -1, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, -1, -1, -1, 49, 21, 22, -1, -1, -1, 55, -1, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, -1, -1, -1, 49, 21, 22, -1, -1, -1, 55, -1, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, -1, -1, -1, 49, 21, 22, -1, -1, -1, 55, -1, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, -1, -1, -1, 49, 21, 22, -1, -1, -1, 55, -1, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, -1, -1, -1, 49, 22, -1, -1, -1, -1, 55, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, -1, -1, -1, 49, 22, -1, -1, -1, -1, 55, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, -1, -1, -1, 49, 22, -1, -1, -1, -1, 55, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, -1, -1, -1, 49, 22, -1, -1, -1, -1, 55, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, -1, -1, -1, 49, 21, 22, -1, -1, -1, 55, -1, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, 21, 22, -1, 49, -1, -1, -1, 53, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, 21, 22, -1, 49, -1, -1, -1, 53, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, 21, 22, -1, 49, -1, -1, -1, 53, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, 21, 22, -1, 49, -1, -1, -1, 53, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, 21, 22, -1, 49, -1, -1, -1, 53, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, 21, 22, -1, 49, -1, -1, -1, 53, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, 21, 22, -1, 49, -1, -1, -1, 53, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, 21, 22, -1, 49, -1, -1, -1, 53, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, 21, 22, -1, 49, -1, -1, -1, 53, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, 21, 22, -1, 49, -1, -1, -1, 53, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, 21, 22, -1, 49, -1, -1, -1, 53, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, -1, 22, -1, 49, -1, -1, -1, 53, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, -1, 22, -1, 49, -1, -1, -1, 53, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, -1, 22, -1, 49, -1, -1, -1, 53, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, -1, 22, -1, 49, -1, -1, -1, 53, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, -1, -1, -1, 49, -1, -1, 52, 26, 27, 28, 29, 30, 26, 27, 28, 29, 30, -1, -1, -1, 39, -1, -1, -1, -1, 39, -1, -1, -1, -1, 49, -1, -1, -1, -1, 49, 55, 21, 22, -1, -1, 55, -1, -1, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 21, 22, -1, -1, 49, -1, -1, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 21, 22, -1, -1, 49, -1, -1, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 21, 22, -1, -1, 49, -1, -1, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 21, 22, -1, -1, 49, -1, -1, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 21, 22, -1, -1, 49, -1, -1, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 21, 22, -1, -1, 49, -1, -1, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 22, -1, -1, 25, 49, -1, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 22, -1, -1, 25, 49, -1, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 22, -1, -1, 25, 49, -1, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 22, -1, -1, 25, 49, -1, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 22, 23, -1, -1, 49, -1, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 22, 23, -1, -1, 49, -1, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 22, -1, -1, -1, 49, -1, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, -1, 29, 30, 49, 32, 33, 34, 35, 36, 23, -1, -1, 26, 27, 28, 29, 30, 29, 30, -1, 32, 33, 34, 35, 36, 39, -1, 55, -1, -1, -1, -1, -1, 29, 30, 49, 32, 33, 34, 35, 36, 29, 30, 55, 32, 33, 34, 35, 36, -1, -1, -1, -1, 41, 42, -1, -1, -1, -1, 55, -1, 49, 29, 30, 52, 32, 33, 34, 35, 36, 23, -1, -1, -1, -1, -1, 29, 30, -1, 32, 33, 34, 35, 36, -1, 52, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1, -1, 29, 30, 49, 32, 33, 34, 35, 36, -1, -1, -1, -1, 41, 42, -1, -1, -1, -1, -1, -1, 49, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 21, -1, -1, -1, 49, -1, -1, -1, 29, 30, -1, 32, 33, 34, 35, 36 }; /* FFSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const fftype_int8 ffstos[] = { 0, 57, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 24, 36, 37, 45, 46, 47, 52, 54, 58, 59, 60, 61, 62, 63, 64, 52, 55, 61, 62, 63, 64, 61, 62, 63, 64, 61, 62, 64, 6, 55, 6, 6, 24, 24, 24, 24, 61, 62, 64, 61, 61, 62, 63, 61, 62, 61, 62, 61, 62, 63, 64, 21, 25, 21, 25, 22, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 49, 52, 26, 27, 28, 29, 30, 39, 49, 52, 29, 30, 32, 33, 34, 35, 36, 41, 42, 49, 52, 29, 30, 32, 33, 34, 35, 36, 52, 21, 55, 21, 55, 55, 21, 55, 21, 55, 55, 55, 21, 21, 55, 21, 21, 55, 61, 61, 61, 61, 55, 55, 55, 55, 61, 62, 61, 62, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 62, 61, 61, 61, 61, 61, 61, 61, 62, 64, 62, 62, 62, 62, 61, 61, 45, 54, 63, 63, 63, 63, 63, 63, 63, 63, 63, 61, 64, 64, 64, 64, 64, 64, 64, 61, 62, 61, 64, 61, 64, 61, 61, 61, 25, 25, 25, 25, 23, 21, 53, 23, 23, 23, 21, 53, 63, 63, 21, 53, 21, 55, 55, 21, 55, 21, 55, 21, 55, 21, 21, 61, 61, 61, 62, 61, 62, 64, 61, 61, 61, 61, 61, 6, 61, 61, 21, 53, 21, 53, 21, 53, 21, 55, 21, 55, 21, 21, 55, 21, 55, 61, 61, 61, 61, 61, 6, 6, 6, 21, 53, 21, 53, 21, 53, 55, 21, 55, 21, 55, 61, 61, 61, 61, 6, 21, 53, 21, 53, 21, 53, 21, 55, 55, 61, 61, 61, 61, 53, 53, 53, 21, 61, 55 }; /* FFR1[FFN] -- Symbol number of symbol that rule FFN derives. */ static const fftype_int8 ffr1[] = { 0, 56, 57, 57, 58, 58, 58, 58, 58, 58, 59, 59, 60, 60, 60, 60, 61, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 64, 64, 64, 64, 64, 64, 64, 64, 64 }; /* FFR2[FFN] -- Number of symbols on the right hand side of rule FFN. */ static const fftype_int8 ffr2[] = { 0, 2, 0, 2, 1, 2, 2, 2, 2, 2, 2, 3, 2, 3, 3, 3, 2, 2, 1, 1, 4, 3, 3, 3, 4, 6, 8, 10, 12, 2, 3, 1, 1, 1, 4, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 3, 5, 5, 5, 2, 3, 3, 3, 3, 5, 5, 9, 4, 6, 8, 10, 12, 2, 2, 2, 2, 1, 1, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 3, 3, 3, 5, 7, 11, 15, 2, 3, 5, 9, 7, 11, 3, 7, 9, 4, 6, 8, 10, 12, 2, 3, 1, 1, 4, 1, 3, 3, 5, 5, 7 }; enum { FFENOMEM = -2 }; #define fferrok (fferrstatus = 0) #define ffclearin (ffchar = FFEMPTY) #define FFACCEPT goto ffacceptlab #define FFABORT goto ffabortlab #define FFERROR goto fferrorlab #define FFRECOVERING() (!!fferrstatus) #define FFBACKUP(Token, Value) \ do \ if (ffchar == FFEMPTY) \ { \ ffchar = (Token); \ fflval = (Value); \ FFPOPSTACK (fflen); \ ffstate = *ffssp; \ goto ffbackup; \ } \ else \ { \ fferror (FF_("syntax error: cannot back up")); \ FFERROR; \ } \ while (0) /* Backward compatibility with an undocumented macro. Use FFerror or FFUNDEF. */ #define FFERRCODE FFUNDEF /* Enable debugging if requested. */ #if FFDEBUG # ifndef FFFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define FFFPRINTF fprintf # endif # define FFDPRINTF(Args) \ do { \ if (ffdebug) \ FFFPRINTF Args; \ } while (0) /* This macro is provided for backward compatibility. */ # ifndef FF_LOCATION_PRINT # define FF_LOCATION_PRINT(File, Loc) ((void) 0) # endif # define FF_SYMBOL_PRINT(Title, Kind, Value, Location) \ do { \ if (ffdebug) \ { \ FFFPRINTF (stderr, "%s ", Title); \ ff_symbol_print (stderr, \ Kind, Value); \ FFFPRINTF (stderr, "\n"); \ } \ } while (0) /*-----------------------------------. | Print this symbol's value on FFO. | `-----------------------------------*/ static void ff_symbol_value_print (FILE *ffo, ffsymbol_kind_t ffkind, FFSTYPE const * const ffvaluep) { FILE *ffoutput = ffo; FFUSE (ffoutput); if (!ffvaluep) return; # ifdef FFPRINT if (ffkind < FFNTOKENS) FFPRINT (ffo, fftoknum[ffkind], *ffvaluep); # endif FF_IGNORE_MAYBE_UNINITIALIZED_BEGIN FFUSE (ffkind); FF_IGNORE_MAYBE_UNINITIALIZED_END } /*---------------------------. | Print this symbol on FFO. | `---------------------------*/ static void ff_symbol_print (FILE *ffo, ffsymbol_kind_t ffkind, FFSTYPE const * const ffvaluep) { FFFPRINTF (ffo, "%s %s (", ffkind < FFNTOKENS ? "token" : "nterm", ffsymbol_name (ffkind)); ff_symbol_value_print (ffo, ffkind, ffvaluep); FFFPRINTF (ffo, ")"); } /*------------------------------------------------------------------. | ff_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ static void ff_stack_print (ff_state_t *ffbottom, ff_state_t *fftop) { FFFPRINTF (stderr, "Stack now"); for (; ffbottom <= fftop; ffbottom++) { int ffbot = *ffbottom; FFFPRINTF (stderr, " %d", ffbot); } FFFPRINTF (stderr, "\n"); } # define FF_STACK_PRINT(Bottom, Top) \ do { \ if (ffdebug) \ ff_stack_print ((Bottom), (Top)); \ } while (0) /*------------------------------------------------. | Report that the FFRULE is going to be reduced. | `------------------------------------------------*/ static void ff_reduce_print (ff_state_t *ffssp, FFSTYPE *ffvsp, int ffrule) { int fflno = ffrline[ffrule]; int ffnrhs = ffr2[ffrule]; int ffi; FFFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", ffrule - 1, fflno); /* The symbols being reduced. */ for (ffi = 0; ffi < ffnrhs; ffi++) { FFFPRINTF (stderr, " $%d = ", ffi + 1); ff_symbol_print (stderr, FF_ACCESSING_SYMBOL (+ffssp[ffi + 1 - ffnrhs]), &ffvsp[(ffi + 1) - (ffnrhs)]); FFFPRINTF (stderr, "\n"); } } # define FF_REDUCE_PRINT(Rule) \ do { \ if (ffdebug) \ ff_reduce_print (ffssp, ffvsp, Rule); \ } while (0) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int ffdebug; #else /* !FFDEBUG */ # define FFDPRINTF(Args) ((void) 0) # define FF_SYMBOL_PRINT(Title, Kind, Value, Location) # define FF_STACK_PRINT(Bottom, Top) # define FF_REDUCE_PRINT(Rule) #endif /* !FFDEBUG */ /* FFINITDEPTH -- initial size of the parser's stacks. */ #ifndef FFINITDEPTH # define FFINITDEPTH 200 #endif /* FFMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if FFSTACK_ALLOC_MAXIMUM < FFSTACK_BYTES (FFMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef FFMAXDEPTH # define FFMAXDEPTH 10000 #endif /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ static void ffdestruct (const char *ffmsg, ffsymbol_kind_t ffkind, FFSTYPE *ffvaluep) { FFUSE (ffvaluep); if (!ffmsg) ffmsg = "Deleting"; FF_SYMBOL_PRINT (ffmsg, ffkind, ffvaluep, fflocationp); FF_IGNORE_MAYBE_UNINITIALIZED_BEGIN FFUSE (ffkind); FF_IGNORE_MAYBE_UNINITIALIZED_END } /* Lookahead token kind. */ int ffchar; /* The semantic value of the lookahead symbol. */ FFSTYPE fflval; /* Number of syntax errors so far. */ int ffnerrs; /*----------. | ffparse. | `----------*/ int ffparse (void) { ff_state_fast_t ffstate = 0; /* Number of tokens to shift before error messages enabled. */ int fferrstatus = 0; /* Refer to the stacks through separate pointers, to allow ffoverflow to reallocate them elsewhere. */ /* Their size. */ FFPTRDIFF_T ffstacksize = FFINITDEPTH; /* The state stack: array, bottom, top. */ ff_state_t ffssa[FFINITDEPTH]; ff_state_t *ffss = ffssa; ff_state_t *ffssp = ffss; /* The semantic value stack: array, bottom, top. */ FFSTYPE ffvsa[FFINITDEPTH]; FFSTYPE *ffvs = ffvsa; FFSTYPE *ffvsp = ffvs; int ffn; /* The return value of ffparse. */ int ffresult; /* Lookahead symbol kind. */ ffsymbol_kind_t fftoken = FFSYMBOL_FFEMPTY; /* The variables used to return semantic value and location from the action routines. */ FFSTYPE ffval; #define FFPOPSTACK(N) (ffvsp -= (N), ffssp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int fflen = 0; FFDPRINTF ((stderr, "Starting parse\n")); ffchar = FFEMPTY; /* Cause a token to be read. */ goto ffsetstate; /*------------------------------------------------------------. | ffnewstate -- push a new state, which is found in ffstate. | `------------------------------------------------------------*/ ffnewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ ffssp++; /*--------------------------------------------------------------------. | ffsetstate -- set current state (the top of the stack) to ffstate. | `--------------------------------------------------------------------*/ ffsetstate: FFDPRINTF ((stderr, "Entering state %d\n", ffstate)); FF_ASSERT (0 <= ffstate && ffstate < FFNSTATES); FF_IGNORE_USELESS_CAST_BEGIN *ffssp = FF_CAST (ff_state_t, ffstate); FF_IGNORE_USELESS_CAST_END FF_STACK_PRINT (ffss, ffssp); if (ffss + ffstacksize - 1 <= ffssp) #if !defined ffoverflow && !defined FFSTACK_RELOCATE goto ffexhaustedlab; #else { /* Get the current used size of the three stacks, in elements. */ FFPTRDIFF_T ffsize = ffssp - ffss + 1; # if defined ffoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ ff_state_t *ffss1 = ffss; FFSTYPE *ffvs1 = ffvs; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if ffoverflow is a macro. */ ffoverflow (FF_("memory exhausted"), &ffss1, ffsize * FFSIZEOF (*ffssp), &ffvs1, ffsize * FFSIZEOF (*ffvsp), &ffstacksize); ffss = ffss1; ffvs = ffvs1; } # else /* defined FFSTACK_RELOCATE */ /* Extend the stack our own way. */ if (FFMAXDEPTH <= ffstacksize) goto ffexhaustedlab; ffstacksize *= 2; if (FFMAXDEPTH < ffstacksize) ffstacksize = FFMAXDEPTH; { ff_state_t *ffss1 = ffss; union ffalloc *ffptr = FF_CAST (union ffalloc *, FFSTACK_ALLOC (FF_CAST (FFSIZE_T, FFSTACK_BYTES (ffstacksize)))); if (! ffptr) goto ffexhaustedlab; FFSTACK_RELOCATE (ffss_alloc, ffss); FFSTACK_RELOCATE (ffvs_alloc, ffvs); # undef FFSTACK_RELOCATE if (ffss1 != ffssa) FFSTACK_FREE (ffss1); } # endif ffssp = ffss + ffsize - 1; ffvsp = ffvs + ffsize - 1; FF_IGNORE_USELESS_CAST_BEGIN FFDPRINTF ((stderr, "Stack size increased to %ld\n", FF_CAST (long, ffstacksize))); FF_IGNORE_USELESS_CAST_END if (ffss + ffstacksize - 1 <= ffssp) FFABORT; } #endif /* !defined ffoverflow && !defined FFSTACK_RELOCATE */ if (ffstate == FFFINAL) FFACCEPT; goto ffbackup; /*-----------. | ffbackup. | `-----------*/ ffbackup: /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to lookahead token. */ ffn = ffpact[ffstate]; if (ffpact_value_is_default (ffn)) goto ffdefault; /* Not known => get a lookahead token if don't already have one. */ /* FFCHAR is either empty, or end-of-input, or a valid lookahead. */ if (ffchar == FFEMPTY) { FFDPRINTF ((stderr, "Reading a token\n")); ffchar = fflex (); } if (ffchar <= FFEOF) { ffchar = FFEOF; fftoken = FFSYMBOL_FFEOF; FFDPRINTF ((stderr, "Now at end of input.\n")); } else if (ffchar == FFerror) { /* The scanner already issued an error message, process directly to error recovery. But do not keep the error token as lookahead, it is too special and may lead us to an endless loop in error recovery. */ ffchar = FFUNDEF; fftoken = FFSYMBOL_FFerror; goto fferrlab1; } else { fftoken = FFTRANSLATE (ffchar); FF_SYMBOL_PRINT ("Next token is", fftoken, &fflval, &fflloc); } /* If the proper action on seeing token FFTOKEN is to reduce or to detect an error, take that action. */ ffn += fftoken; if (ffn < 0 || FFLAST < ffn || ffcheck[ffn] != fftoken) goto ffdefault; ffn = fftable[ffn]; if (ffn <= 0) { if (fftable_value_is_error (ffn)) goto fferrlab; ffn = -ffn; goto ffreduce; } /* Count tokens shifted since error; after three, turn off error status. */ if (fferrstatus) fferrstatus--; /* Shift the lookahead token. */ FF_SYMBOL_PRINT ("Shifting", fftoken, &fflval, &fflloc); ffstate = ffn; FF_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++ffvsp = fflval; FF_IGNORE_MAYBE_UNINITIALIZED_END /* Discard the shifted token. */ ffchar = FFEMPTY; goto ffnewstate; /*-----------------------------------------------------------. | ffdefault -- do the default action for the current state. | `-----------------------------------------------------------*/ ffdefault: ffn = ffdefact[ffstate]; if (ffn == 0) goto fferrlab; goto ffreduce; /*-----------------------------. | ffreduce -- do a reduction. | `-----------------------------*/ ffreduce: /* ffn is the number of a rule to reduce with. */ fflen = ffr2[ffn]; /* If FFLEN is nonzero, implement the default value of the action: '$$ = $1'. Otherwise, the following line sets FFVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to FFVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that FFVAL may be used uninitialized. */ ffval = ffvsp[1-fflen]; FF_REDUCE_PRINT (ffn); switch (ffn) { case 4: /* line: '\n' */ #line 256 "eval.y" {} #line 1913 "y.tab.c" break; case 5: /* line: expr '\n' */ #line 258 "eval.y" { if( (ffvsp[-1].Node)<0 ) { fferror("Couldn't build node structure: out of memory?"); FFERROR; } gParse.resultNode = (ffvsp[-1].Node); } #line 1923 "y.tab.c" break; case 6: /* line: bexpr '\n' */ #line 264 "eval.y" { if( (ffvsp[-1].Node)<0 ) { fferror("Couldn't build node structure: out of memory?"); FFERROR; } gParse.resultNode = (ffvsp[-1].Node); } #line 1933 "y.tab.c" break; case 7: /* line: sexpr '\n' */ #line 270 "eval.y" { if( (ffvsp[-1].Node)<0 ) { fferror("Couldn't build node structure: out of memory?"); FFERROR; } gParse.resultNode = (ffvsp[-1].Node); } #line 1943 "y.tab.c" break; case 8: /* line: bits '\n' */ #line 276 "eval.y" { if( (ffvsp[-1].Node)<0 ) { fferror("Couldn't build node structure: out of memory?"); FFERROR; } gParse.resultNode = (ffvsp[-1].Node); } #line 1953 "y.tab.c" break; case 9: /* line: error '\n' */ #line 281 "eval.y" { fferrok; } #line 1959 "y.tab.c" break; case 10: /* bvector: '{' bexpr */ #line 285 "eval.y" { (ffval.Node) = New_Vector( (ffvsp[0].Node) ); TEST((ffval.Node)); } #line 1965 "y.tab.c" break; case 11: /* bvector: bvector ',' bexpr */ #line 287 "eval.y" { if( gParse.Nodes[(ffvsp[-2].Node)].nSubNodes >= MAXSUBS ) { (ffvsp[-2].Node) = Close_Vec( (ffvsp[-2].Node) ); TEST((ffvsp[-2].Node)); (ffval.Node) = New_Vector( (ffvsp[-2].Node) ); TEST((ffval.Node)); } else { (ffval.Node) = (ffvsp[-2].Node); } gParse.Nodes[(ffval.Node)].SubNodes[ gParse.Nodes[(ffval.Node)].nSubNodes++ ] = (ffvsp[0].Node); } #line 1980 "y.tab.c" break; case 12: /* vector: '{' expr */ #line 300 "eval.y" { (ffval.Node) = New_Vector( (ffvsp[0].Node) ); TEST((ffval.Node)); } #line 1986 "y.tab.c" break; case 13: /* vector: vector ',' expr */ #line 302 "eval.y" { if( TYPE((ffvsp[-2].Node)) < TYPE((ffvsp[0].Node)) ) TYPE((ffvsp[-2].Node)) = TYPE((ffvsp[0].Node)); if( gParse.Nodes[(ffvsp[-2].Node)].nSubNodes >= MAXSUBS ) { (ffvsp[-2].Node) = Close_Vec( (ffvsp[-2].Node) ); TEST((ffvsp[-2].Node)); (ffval.Node) = New_Vector( (ffvsp[-2].Node) ); TEST((ffval.Node)); } else { (ffval.Node) = (ffvsp[-2].Node); } gParse.Nodes[(ffval.Node)].SubNodes[ gParse.Nodes[(ffval.Node)].nSubNodes++ ] = (ffvsp[0].Node); } #line 2003 "y.tab.c" break; case 14: /* vector: vector ',' bexpr */ #line 315 "eval.y" { if( gParse.Nodes[(ffvsp[-2].Node)].nSubNodes >= MAXSUBS ) { (ffvsp[-2].Node) = Close_Vec( (ffvsp[-2].Node) ); TEST((ffvsp[-2].Node)); (ffval.Node) = New_Vector( (ffvsp[-2].Node) ); TEST((ffval.Node)); } else { (ffval.Node) = (ffvsp[-2].Node); } gParse.Nodes[(ffval.Node)].SubNodes[ gParse.Nodes[(ffval.Node)].nSubNodes++ ] = (ffvsp[0].Node); } #line 2018 "y.tab.c" break; case 15: /* vector: bvector ',' expr */ #line 326 "eval.y" { TYPE((ffvsp[-2].Node)) = TYPE((ffvsp[0].Node)); if( gParse.Nodes[(ffvsp[-2].Node)].nSubNodes >= MAXSUBS ) { (ffvsp[-2].Node) = Close_Vec( (ffvsp[-2].Node) ); TEST((ffvsp[-2].Node)); (ffval.Node) = New_Vector( (ffvsp[-2].Node) ); TEST((ffval.Node)); } else { (ffval.Node) = (ffvsp[-2].Node); } gParse.Nodes[(ffval.Node)].SubNodes[ gParse.Nodes[(ffval.Node)].nSubNodes++ ] = (ffvsp[0].Node); } #line 2034 "y.tab.c" break; case 16: /* expr: vector '}' */ #line 340 "eval.y" { (ffval.Node) = Close_Vec( (ffvsp[-1].Node) ); TEST((ffval.Node)); } #line 2040 "y.tab.c" break; case 17: /* bexpr: bvector '}' */ #line 344 "eval.y" { (ffval.Node) = Close_Vec( (ffvsp[-1].Node) ); TEST((ffval.Node)); } #line 2046 "y.tab.c" break; case 18: /* bits: BITSTR */ #line 348 "eval.y" { (ffval.Node) = New_Const( BITSTR, (ffvsp[0].str), strlen((ffvsp[0].str))+1 ); TEST((ffval.Node)); SIZE((ffval.Node)) = strlen((ffvsp[0].str)); } #line 2054 "y.tab.c" break; case 19: /* bits: BITCOL */ #line 352 "eval.y" { (ffval.Node) = New_Column( (ffvsp[0].lng) ); TEST((ffval.Node)); } #line 2060 "y.tab.c" break; case 20: /* bits: BITCOL '{' expr '}' */ #line 354 "eval.y" { if( TYPE((ffvsp[-1].Node)) != LONG || OPER((ffvsp[-1].Node)) != CONST_OP ) { fferror("Offset argument must be a constant integer"); FFERROR; } (ffval.Node) = New_Offset( (ffvsp[-3].lng), (ffvsp[-1].Node) ); TEST((ffval.Node)); } #line 2073 "y.tab.c" break; case 21: /* bits: bits '&' bits */ #line 363 "eval.y" { (ffval.Node) = New_BinOp( BITSTR, (ffvsp[-2].Node), '&', (ffvsp[0].Node) ); TEST((ffval.Node)); SIZE((ffval.Node)) = ( SIZE((ffvsp[-2].Node))>SIZE((ffvsp[0].Node)) ? SIZE((ffvsp[-2].Node)) : SIZE((ffvsp[0].Node)) ); } #line 2080 "y.tab.c" break; case 22: /* bits: bits '|' bits */ #line 366 "eval.y" { (ffval.Node) = New_BinOp( BITSTR, (ffvsp[-2].Node), '|', (ffvsp[0].Node) ); TEST((ffval.Node)); SIZE((ffval.Node)) = ( SIZE((ffvsp[-2].Node))>SIZE((ffvsp[0].Node)) ? SIZE((ffvsp[-2].Node)) : SIZE((ffvsp[0].Node)) ); } #line 2087 "y.tab.c" break; case 23: /* bits: bits '+' bits */ #line 369 "eval.y" { if (SIZE((ffvsp[-2].Node))+SIZE((ffvsp[0].Node)) >= MAX_STRLEN) { fferror("Combined bit string size exceeds " MAX_STRLEN_S " bits"); FFERROR; } (ffval.Node) = New_BinOp( BITSTR, (ffvsp[-2].Node), '+', (ffvsp[0].Node) ); TEST((ffval.Node)); SIZE((ffval.Node)) = SIZE((ffvsp[-2].Node)) + SIZE((ffvsp[0].Node)); } #line 2100 "y.tab.c" break; case 24: /* bits: bits '[' expr ']' */ #line 378 "eval.y" { (ffval.Node) = New_Deref( (ffvsp[-3].Node), 1, (ffvsp[-1].Node), 0, 0, 0, 0 ); TEST((ffval.Node)); } #line 2106 "y.tab.c" break; case 25: /* bits: bits '[' expr ',' expr ']' */ #line 380 "eval.y" { (ffval.Node) = New_Deref( (ffvsp[-5].Node), 2, (ffvsp[-3].Node), (ffvsp[-1].Node), 0, 0, 0 ); TEST((ffval.Node)); } #line 2112 "y.tab.c" break; case 26: /* bits: bits '[' expr ',' expr ',' expr ']' */ #line 382 "eval.y" { (ffval.Node) = New_Deref( (ffvsp[-7].Node), 3, (ffvsp[-5].Node), (ffvsp[-3].Node), (ffvsp[-1].Node), 0, 0 ); TEST((ffval.Node)); } #line 2118 "y.tab.c" break; case 27: /* bits: bits '[' expr ',' expr ',' expr ',' expr ']' */ #line 384 "eval.y" { (ffval.Node) = New_Deref( (ffvsp[-9].Node), 4, (ffvsp[-7].Node), (ffvsp[-5].Node), (ffvsp[-3].Node), (ffvsp[-1].Node), 0 ); TEST((ffval.Node)); } #line 2124 "y.tab.c" break; case 28: /* bits: bits '[' expr ',' expr ',' expr ',' expr ',' expr ']' */ #line 386 "eval.y" { (ffval.Node) = New_Deref( (ffvsp[-11].Node), 5, (ffvsp[-9].Node), (ffvsp[-7].Node), (ffvsp[-5].Node), (ffvsp[-3].Node), (ffvsp[-1].Node) ); TEST((ffval.Node)); } #line 2130 "y.tab.c" break; case 29: /* bits: NOT bits */ #line 388 "eval.y" { (ffval.Node) = New_Unary( BITSTR, NOT, (ffvsp[0].Node) ); TEST((ffval.Node)); } #line 2136 "y.tab.c" break; case 30: /* bits: '(' bits ')' */ #line 391 "eval.y" { (ffval.Node) = (ffvsp[-1].Node); } #line 2142 "y.tab.c" break; case 31: /* expr: LONG */ #line 395 "eval.y" { (ffval.Node) = New_Const( LONG, &((ffvsp[0].lng)), sizeof(long) ); TEST((ffval.Node)); } #line 2148 "y.tab.c" break; case 32: /* expr: DOUBLE */ #line 397 "eval.y" { (ffval.Node) = New_Const( DOUBLE, &((ffvsp[0].dbl)), sizeof(double) ); TEST((ffval.Node)); } #line 2154 "y.tab.c" break; case 33: /* expr: COLUMN */ #line 399 "eval.y" { (ffval.Node) = New_Column( (ffvsp[0].lng) ); TEST((ffval.Node)); } #line 2160 "y.tab.c" break; case 34: /* expr: COLUMN '{' expr '}' */ #line 401 "eval.y" { if( TYPE((ffvsp[-1].Node)) != LONG || OPER((ffvsp[-1].Node)) != CONST_OP ) { fferror("Offset argument must be a constant integer"); FFERROR; } (ffval.Node) = New_Offset( (ffvsp[-3].lng), (ffvsp[-1].Node) ); TEST((ffval.Node)); } #line 2173 "y.tab.c" break; case 35: /* expr: ROWREF */ #line 410 "eval.y" { (ffval.Node) = New_Func( LONG, row_fct, 0, 0, 0, 0, 0, 0, 0, 0 ); } #line 2179 "y.tab.c" break; case 36: /* expr: NULLREF */ #line 412 "eval.y" { (ffval.Node) = New_Func( LONG, null_fct, 0, 0, 0, 0, 0, 0, 0, 0 ); } #line 2185 "y.tab.c" break; case 37: /* expr: expr '%' expr */ #line 414 "eval.y" { PROMOTE((ffvsp[-2].Node),(ffvsp[0].Node)); (ffval.Node) = New_BinOp( TYPE((ffvsp[-2].Node)), (ffvsp[-2].Node), '%', (ffvsp[0].Node) ); TEST((ffval.Node)); } #line 2192 "y.tab.c" break; case 38: /* expr: expr '+' expr */ #line 417 "eval.y" { PROMOTE((ffvsp[-2].Node),(ffvsp[0].Node)); (ffval.Node) = New_BinOp( TYPE((ffvsp[-2].Node)), (ffvsp[-2].Node), '+', (ffvsp[0].Node) ); TEST((ffval.Node)); } #line 2199 "y.tab.c" break; case 39: /* expr: expr '-' expr */ #line 420 "eval.y" { PROMOTE((ffvsp[-2].Node),(ffvsp[0].Node)); (ffval.Node) = New_BinOp( TYPE((ffvsp[-2].Node)), (ffvsp[-2].Node), '-', (ffvsp[0].Node) ); TEST((ffval.Node)); } #line 2206 "y.tab.c" break; case 40: /* expr: expr '*' expr */ #line 423 "eval.y" { PROMOTE((ffvsp[-2].Node),(ffvsp[0].Node)); (ffval.Node) = New_BinOp( TYPE((ffvsp[-2].Node)), (ffvsp[-2].Node), '*', (ffvsp[0].Node) ); TEST((ffval.Node)); } #line 2213 "y.tab.c" break; case 41: /* expr: expr '/' expr */ #line 426 "eval.y" { PROMOTE((ffvsp[-2].Node),(ffvsp[0].Node)); (ffval.Node) = New_BinOp( TYPE((ffvsp[-2].Node)), (ffvsp[-2].Node), '/', (ffvsp[0].Node) ); TEST((ffval.Node)); } #line 2220 "y.tab.c" break; case 42: /* expr: expr '&' expr */ #line 429 "eval.y" { if (TYPE((ffvsp[-2].Node)) != LONG || TYPE((ffvsp[0].Node)) != LONG) { fferror("Bitwise operations with incompatible types; only (bit OP bit) and (int OP int) are allowed"); FFERROR; } (ffval.Node) = New_BinOp( TYPE((ffvsp[-2].Node)), (ffvsp[-2].Node), '&', (ffvsp[0].Node) ); } #line 2233 "y.tab.c" break; case 43: /* expr: expr '|' expr */ #line 438 "eval.y" { if (TYPE((ffvsp[-2].Node)) != LONG || TYPE((ffvsp[0].Node)) != LONG) { fferror("Bitwise operations with incompatible types; only (bit OP bit) and (int OP int) are allowed"); FFERROR; } (ffval.Node) = New_BinOp( TYPE((ffvsp[-2].Node)), (ffvsp[-2].Node), '|', (ffvsp[0].Node) ); } #line 2246 "y.tab.c" break; case 44: /* expr: expr XOR expr */ #line 447 "eval.y" { if (TYPE((ffvsp[-2].Node)) != LONG || TYPE((ffvsp[0].Node)) != LONG) { fferror("Bitwise operations with incompatible types; only (bit OP bit) and (int OP int) are allowed"); FFERROR; } (ffval.Node) = New_BinOp( TYPE((ffvsp[-2].Node)), (ffvsp[-2].Node), '^', (ffvsp[0].Node) ); } #line 2259 "y.tab.c" break; case 45: /* expr: expr POWER expr */ #line 456 "eval.y" { PROMOTE((ffvsp[-2].Node),(ffvsp[0].Node)); (ffval.Node) = New_BinOp( TYPE((ffvsp[-2].Node)), (ffvsp[-2].Node), POWER, (ffvsp[0].Node) ); TEST((ffval.Node)); } #line 2266 "y.tab.c" break; case 46: /* expr: '+' expr */ #line 459 "eval.y" { (ffval.Node) = (ffvsp[0].Node); } #line 2272 "y.tab.c" break; case 47: /* expr: '-' expr */ #line 461 "eval.y" { (ffval.Node) = New_Unary( TYPE((ffvsp[0].Node)), UMINUS, (ffvsp[0].Node) ); TEST((ffval.Node)); } #line 2278 "y.tab.c" break; case 48: /* expr: '(' expr ')' */ #line 463 "eval.y" { (ffval.Node) = (ffvsp[-1].Node); } #line 2284 "y.tab.c" break; case 49: /* expr: expr '*' bexpr */ #line 465 "eval.y" { (ffvsp[0].Node) = New_Unary( TYPE((ffvsp[-2].Node)), 0, (ffvsp[0].Node) ); (ffval.Node) = New_BinOp( TYPE((ffvsp[-2].Node)), (ffvsp[-2].Node), '*', (ffvsp[0].Node) ); TEST((ffval.Node)); } #line 2292 "y.tab.c" break; case 50: /* expr: bexpr '*' expr */ #line 469 "eval.y" { (ffvsp[-2].Node) = New_Unary( TYPE((ffvsp[0].Node)), 0, (ffvsp[-2].Node) ); (ffval.Node) = New_BinOp( TYPE((ffvsp[0].Node)), (ffvsp[-2].Node), '*', (ffvsp[0].Node) ); TEST((ffval.Node)); } #line 2300 "y.tab.c" break; case 51: /* expr: bexpr '?' expr ':' expr */ #line 473 "eval.y" { PROMOTE((ffvsp[-2].Node),(ffvsp[0].Node)); if( ! Test_Dims((ffvsp[-2].Node),(ffvsp[0].Node)) ) { fferror("Incompatible dimensions in '?:' arguments"); FFERROR; } (ffval.Node) = New_Func( 0, ifthenelse_fct, 3, (ffvsp[-2].Node), (ffvsp[0].Node), (ffvsp[-4].Node), 0, 0, 0, 0 ); TEST((ffval.Node)); if( SIZE((ffvsp[-2].Node))=SIZE((ffvsp[-1].Node)) && Test_Dims( (ffvsp[-3].Node), (ffvsp[-1].Node) ) ) { PROMOTE((ffvsp[-3].Node),(ffvsp[-1].Node)); (ffval.Node) = New_Func( 0, defnull_fct, 2, (ffvsp[-3].Node), (ffvsp[-1].Node), 0, 0, 0, 0, 0 ); TEST((ffval.Node)); } else { fferror("Dimensions of DEFNULL arguments " "are not compatible"); FFERROR; } } else if (FSTRCMP((ffvsp[-4].str),"ARCTAN2(") == 0) { if( TYPE((ffvsp[-3].Node)) != DOUBLE ) (ffvsp[-3].Node) = New_Unary( DOUBLE, 0, (ffvsp[-3].Node) ); if( TYPE((ffvsp[-1].Node)) != DOUBLE ) (ffvsp[-1].Node) = New_Unary( DOUBLE, 0, (ffvsp[-1].Node) ); if( Test_Dims( (ffvsp[-3].Node), (ffvsp[-1].Node) ) ) { (ffval.Node) = New_Func( 0, atan2_fct, 2, (ffvsp[-3].Node), (ffvsp[-1].Node), 0, 0, 0, 0, 0 ); TEST((ffval.Node)); if( SIZE((ffvsp[-3].Node))=SIZE((ffvsp[-1].Node)) && Test_Dims( (ffvsp[-3].Node), (ffvsp[-1].Node) ) ) { (ffval.Node) = New_Func( 0, defnull_fct, 2, (ffvsp[-3].Node), (ffvsp[-1].Node), 0, 0, 0, 0, 0 ); TEST((ffval.Node)); } else { fferror("Dimensions of DEFNULL arguments are not compatible"); FFERROR; } } else { fferror("Boolean Function(expr,expr) not supported"); FFERROR; } } #line 2992 "y.tab.c" break; case 103: /* bexpr: BFUNCTION expr ',' expr ',' expr ')' */ #line 962 "eval.y" { if( TYPE((ffvsp[-5].Node)) != DOUBLE ) (ffvsp[-5].Node) = New_Unary( DOUBLE, 0, (ffvsp[-5].Node) ); if( TYPE((ffvsp[-3].Node)) != DOUBLE ) (ffvsp[-3].Node) = New_Unary( DOUBLE, 0, (ffvsp[-3].Node) ); if( TYPE((ffvsp[-1].Node)) != DOUBLE ) (ffvsp[-1].Node) = New_Unary( DOUBLE, 0, (ffvsp[-1].Node) ); if( ! (Test_Dims( (ffvsp[-5].Node), (ffvsp[-3].Node) ) && Test_Dims( (ffvsp[-3].Node), (ffvsp[-1].Node) ) ) ) { fferror("Dimensions of NEAR arguments " "are not compatible"); FFERROR; } else { if (FSTRCMP((ffvsp[-6].str),"NEAR(") == 0) { (ffval.Node) = New_Func( BOOLEAN, near_fct, 3, (ffvsp[-5].Node), (ffvsp[-3].Node), (ffvsp[-1].Node), 0, 0, 0, 0 ); } else { fferror("Boolean Function not supported"); FFERROR; } TEST((ffval.Node)); if( SIZE((ffval.Node))= MAX_STRLEN) { fferror("Combined string size exceeds " MAX_STRLEN_S " characters"); FFERROR; } (ffval.Node) = New_BinOp( STRING, (ffvsp[-2].Node), '+', (ffvsp[0].Node) ); TEST((ffval.Node)); SIZE((ffval.Node)) = SIZE((ffvsp[-2].Node)) + SIZE((ffvsp[0].Node)); } #line 3251 "y.tab.c" break; case 128: /* sexpr: bexpr '?' sexpr ':' sexpr */ #line 1129 "eval.y" { int outSize; if( SIZE((ffvsp[-4].Node))!=1 ) { fferror("Cannot have a vector string column"); FFERROR; } /* Since the output can be calculated now, as a constant scalar, we must precalculate the output size, in order to avoid an overflow. */ outSize = SIZE((ffvsp[-2].Node)); if (SIZE((ffvsp[0].Node)) > outSize) outSize = SIZE((ffvsp[0].Node)); (ffval.Node) = New_FuncSize( 0, ifthenelse_fct, 3, (ffvsp[-2].Node), (ffvsp[0].Node), (ffvsp[-4].Node), 0, 0, 0, 0, outSize); TEST((ffval.Node)); if( SIZE((ffvsp[-2].Node)) outSize) outSize = SIZE((ffvsp[-1].Node)); (ffval.Node) = New_FuncSize( 0, defnull_fct, 2, (ffvsp[-3].Node), (ffvsp[-1].Node), 0, 0, 0, 0, 0, outSize ); TEST((ffval.Node)); if( SIZE((ffvsp[-1].Node))>SIZE((ffvsp[-3].Node)) ) SIZE((ffval.Node)) = SIZE((ffvsp[-1].Node)); } else { fferror("Function(string,string) not supported"); FFERROR; } } #line 3296 "y.tab.c" break; case 130: /* sexpr: FUNCTION sexpr ',' expr ',' expr ')' */ #line 1167 "eval.y" { if (FSTRCMP((ffvsp[-6].str),"STRMID(") == 0) { int len; if( TYPE((ffvsp[-3].Node)) != LONG || SIZE((ffvsp[-3].Node)) != 1 || TYPE((ffvsp[-1].Node)) != LONG || SIZE((ffvsp[-1].Node)) != 1) { fferror("When using STRMID(S,P,N), P and N must be integers (and not vector columns)"); FFERROR; } if (OPER((ffvsp[-1].Node)) == CONST_OP) { /* Constant value: use that directly */ len = (gParse.Nodes[(ffvsp[-1].Node)].value.data.lng); } else { /* Variable value: use the maximum possible (from $2) */ len = SIZE((ffvsp[-5].Node)); } if (len <= 0 || len >= MAX_STRLEN) { fferror("STRMID(S,P,N), N must be 1-" MAX_STRLEN_S); FFERROR; } (ffval.Node) = New_FuncSize( 0, strmid_fct, 3, (ffvsp[-5].Node), (ffvsp[-3].Node),(ffvsp[-1].Node),0,0,0,0,len); TEST((ffval.Node)); } else { fferror("Function(string,expr,expr) not supported"); FFERROR; } } #line 3327 "y.tab.c" break; #line 3331 "y.tab.c" default: break; } /* User semantic actions sometimes alter ffchar, and that requires that fftoken be updated with the new translation. We take the approach of translating immediately before every use of fftoken. One alternative is translating here after every semantic action, but that translation would be missed if the semantic action invokes FFABORT, FFACCEPT, or FFERROR immediately after altering ffchar or if it invokes FFBACKUP. In the case of FFABORT or FFACCEPT, an incorrect destructor might then be invoked immediately. In the case of FFERROR or FFBACKUP, subsequent parser actions might lead to an incorrect destructor call or verbose syntax error message before the lookahead is translated. */ FF_SYMBOL_PRINT ("-> $$ =", FF_CAST (ffsymbol_kind_t, ffr1[ffn]), &ffval, &ffloc); FFPOPSTACK (fflen); fflen = 0; *++ffvsp = ffval; /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ { const int fflhs = ffr1[ffn] - FFNTOKENS; const int ffi = ffpgoto[fflhs] + *ffssp; ffstate = (0 <= ffi && ffi <= FFLAST && ffcheck[ffi] == *ffssp ? fftable[ffi] : ffdefgoto[fflhs]); } goto ffnewstate; /*--------------------------------------. | fferrlab -- here on detecting error. | `--------------------------------------*/ fferrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ fftoken = ffchar == FFEMPTY ? FFSYMBOL_FFEMPTY : FFTRANSLATE (ffchar); /* If not already recovering from an error, report this error. */ if (!fferrstatus) { ++ffnerrs; fferror (FF_("syntax error")); } if (fferrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (ffchar <= FFEOF) { /* Return failure if at end of input. */ if (ffchar == FFEOF) FFABORT; } else { ffdestruct ("Error: discarding", fftoken, &fflval); ffchar = FFEMPTY; } } /* Else will try to reuse lookahead token after shifting the error token. */ goto fferrlab1; /*---------------------------------------------------. | fferrorlab -- error raised explicitly by FFERROR. | `---------------------------------------------------*/ fferrorlab: /* Pacify compilers when the user code never invokes FFERROR and the label fferrorlab therefore never appears in user code. */ if (0) FFERROR; /* Do not reclaim the symbols of the rule whose action triggered this FFERROR. */ FFPOPSTACK (fflen); fflen = 0; FF_STACK_PRINT (ffss, ffssp); ffstate = *ffssp; goto fferrlab1; /*-------------------------------------------------------------. | fferrlab1 -- common code for both syntax error and FFERROR. | `-------------------------------------------------------------*/ fferrlab1: fferrstatus = 3; /* Each real token shifted decrements this. */ /* Pop stack until we find a state that shifts the error token. */ for (;;) { ffn = ffpact[ffstate]; if (!ffpact_value_is_default (ffn)) { ffn += FFSYMBOL_FFerror; if (0 <= ffn && ffn <= FFLAST && ffcheck[ffn] == FFSYMBOL_FFerror) { ffn = fftable[ffn]; if (0 < ffn) break; } } /* Pop the current state because it cannot handle the error token. */ if (ffssp == ffss) FFABORT; ffdestruct ("Error: popping", FF_ACCESSING_SYMBOL (ffstate), ffvsp); FFPOPSTACK (1); ffstate = *ffssp; FF_STACK_PRINT (ffss, ffssp); } FF_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++ffvsp = fflval; FF_IGNORE_MAYBE_UNINITIALIZED_END /* Shift the error token. */ FF_SYMBOL_PRINT ("Shifting", FF_ACCESSING_SYMBOL (ffn), ffvsp, fflsp); ffstate = ffn; goto ffnewstate; /*-------------------------------------. | ffacceptlab -- FFACCEPT comes here. | `-------------------------------------*/ ffacceptlab: ffresult = 0; goto ffreturn; /*-----------------------------------. | ffabortlab -- FFABORT comes here. | `-----------------------------------*/ ffabortlab: ffresult = 1; goto ffreturn; #if !defined ffoverflow /*-------------------------------------------------. | ffexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ ffexhaustedlab: fferror (FF_("memory exhausted")); ffresult = 2; goto ffreturn; #endif /*-------------------------------------------------------. | ffreturn -- parsing is finished, clean up and return. | `-------------------------------------------------------*/ ffreturn: if (ffchar != FFEMPTY) { /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ fftoken = FFTRANSLATE (ffchar); ffdestruct ("Cleanup: discarding lookahead", fftoken, &fflval); } /* Do not reclaim the symbols of the rule whose action triggered this FFABORT or FFACCEPT. */ FFPOPSTACK (fflen); FF_STACK_PRINT (ffss, ffssp); while (ffssp != ffss) { ffdestruct ("Cleanup: popping", FF_ACCESSING_SYMBOL (+*ffssp), ffvsp); FFPOPSTACK (1); } #ifndef ffoverflow if (ffss != ffssa) FFSTACK_FREE (ffss); #endif return ffresult; } #line 1196 "eval.y" /*************************************************************************/ /* Start of "New" routines which build the expression Nodal structure */ /*************************************************************************/ static int Alloc_Node( void ) { /* Use this for allocation to guarantee *Nodes */ Node *newNodePtr; /* survives on failure, making it still valid */ /* while working our way out of this error */ if( gParse.nNodes == gParse.nNodesAlloc ) { if( gParse.Nodes ) { gParse.nNodesAlloc += gParse.nNodesAlloc; newNodePtr = (Node *)realloc( gParse.Nodes, sizeof(Node)*gParse.nNodesAlloc ); } else { gParse.nNodesAlloc = 100; newNodePtr = (Node *)malloc ( sizeof(Node)*gParse.nNodesAlloc ); } if( newNodePtr ) { gParse.Nodes = newNodePtr; } else { gParse.status = MEMORY_ALLOCATION; return( -1 ); } } return ( gParse.nNodes++ ); } static void Free_Last_Node( void ) { if( gParse.nNodes ) gParse.nNodes--; } static int New_Const( int returnType, void *value, long len ) { Node *this; int n; n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->operation = CONST_OP; /* Flag a constant */ this->DoOp = NULL; this->nSubNodes = 0; this->type = returnType; memcpy( &(this->value.data), value, len ); this->value.undef = NULL; this->value.nelem = 1; this->value.naxis = 1; this->value.naxes[0] = 1; } return(n); } static int New_Column( int ColNum ) { Node *this; int n, i; n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->operation = -ColNum; this->DoOp = NULL; this->nSubNodes = 0; this->type = gParse.varData[ColNum].type; this->value.nelem = gParse.varData[ColNum].nelem; this->value.naxis = gParse.varData[ColNum].naxis; for( i=0; ivalue.naxes[i] = gParse.varData[ColNum].naxes[i]; } return(n); } static int New_Offset( int ColNum, int offsetNode ) { Node *this; int n, i, colNode; colNode = New_Column( ColNum ); if( colNode<0 ) return(-1); n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->operation = '{'; this->DoOp = Do_Offset; this->nSubNodes = 2; this->SubNodes[0] = colNode; this->SubNodes[1] = offsetNode; this->type = gParse.varData[ColNum].type; this->value.nelem = gParse.varData[ColNum].nelem; this->value.naxis = gParse.varData[ColNum].naxis; for( i=0; ivalue.naxes[i] = gParse.varData[ColNum].naxes[i]; } return(n); } static int New_Unary( int returnType, int Op, int Node1 ) { Node *this, *that; int i,n; if( Node1<0 ) return(-1); that = gParse.Nodes + Node1; if( !Op ) Op = returnType; if( (Op==DOUBLE || Op==FLTCAST) && that->type==DOUBLE ) return( Node1 ); if( (Op==LONG || Op==INTCAST) && that->type==LONG ) return( Node1 ); if( (Op==BOOLEAN ) && that->type==BOOLEAN ) return( Node1 ); n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->operation = Op; this->DoOp = Do_Unary; this->nSubNodes = 1; this->SubNodes[0] = Node1; this->type = returnType; that = gParse.Nodes + Node1; /* Reset in case .Nodes mv'd */ this->value.nelem = that->value.nelem; this->value.naxis = that->value.naxis; for( i=0; ivalue.naxis; i++ ) this->value.naxes[i] = that->value.naxes[i]; if( that->operation==CONST_OP ) this->DoOp( this ); } return( n ); } static int New_BinOp( int returnType, int Node1, int Op, int Node2 ) { Node *this,*that1,*that2; int n,i,constant; if( Node1<0 || Node2<0 ) return(-1); n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->operation = Op; this->nSubNodes = 2; this->SubNodes[0]= Node1; this->SubNodes[1]= Node2; this->type = returnType; that1 = gParse.Nodes + Node1; that2 = gParse.Nodes + Node2; constant = (that1->operation==CONST_OP && that2->operation==CONST_OP); if( that1->type!=STRING && that1->type!=BITSTR ) if( !Test_Dims( Node1, Node2 ) ) { Free_Last_Node(); fferror("Array sizes/dims do not match for binary operator"); return(-1); } if( that1->value.nelem == 1 ) that1 = that2; this->value.nelem = that1->value.nelem; this->value.naxis = that1->value.naxis; for( i=0; ivalue.naxis; i++ ) this->value.naxes[i] = that1->value.naxes[i]; if ( Op == ACCUM && that1->type == BITSTR ) { /* ACCUM is rank-reducing on bit strings */ this->value.nelem = 1; this->value.naxis = 1; this->value.naxes[0] = 1; } /* Both subnodes should be of same time */ switch( that1->type ) { case BITSTR: this->DoOp = Do_BinOp_bit; break; case STRING: this->DoOp = Do_BinOp_str; break; case BOOLEAN: this->DoOp = Do_BinOp_log; break; case LONG: this->DoOp = Do_BinOp_lng; break; case DOUBLE: this->DoOp = Do_BinOp_dbl; break; } if( constant ) this->DoOp( this ); } return( n ); } static int New_Func( int returnType, funcOp Op, int nNodes, int Node1, int Node2, int Node3, int Node4, int Node5, int Node6, int Node7 ) { return New_FuncSize(returnType, Op, nNodes, Node1, Node2, Node3, Node4, Node5, Node6, Node7, 0); } static int New_FuncSize( int returnType, funcOp Op, int nNodes, int Node1, int Node2, int Node3, int Node4, int Node5, int Node6, int Node7, int Size ) /* If returnType==0 , use Node1's type and vector sizes as returnType, */ /* else return a single value of type returnType */ { Node *this, *that; int i,n,constant; if( Node1<0 || Node2<0 || Node3<0 || Node4<0 || Node5<0 || Node6<0 || Node7<0 ) return(-1); n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->operation = (int)Op; this->DoOp = Do_Func; this->nSubNodes = nNodes; this->SubNodes[0] = Node1; this->SubNodes[1] = Node2; this->SubNodes[2] = Node3; this->SubNodes[3] = Node4; this->SubNodes[4] = Node5; this->SubNodes[5] = Node6; this->SubNodes[6] = Node7; i = constant = nNodes; /* Functions with zero params are not const */ if (Op == poirnd_fct) constant = 0; /* Nor is Poisson deviate */ while( i-- ) constant = ( constant && OPER(this->SubNodes[i]) == CONST_OP ); if( returnType ) { this->type = returnType; this->value.nelem = 1; this->value.naxis = 1; this->value.naxes[0] = 1; } else { that = gParse.Nodes + Node1; this->type = that->type; this->value.nelem = that->value.nelem; this->value.naxis = that->value.naxis; for( i=0; ivalue.naxis; i++ ) this->value.naxes[i] = that->value.naxes[i]; } /* Force explicit size before evaluating */ if (Size > 0) this->value.nelem = Size; if( constant ) this->DoOp( this ); } return( n ); } static int New_Deref( int Var, int nDim, int Dim1, int Dim2, int Dim3, int Dim4, int Dim5 ) { int n, idx, constant; long elem=0; Node *this, *theVar, *theDim[MAXDIMS]; if( Var<0 || Dim1<0 || Dim2<0 || Dim3<0 || Dim4<0 || Dim5<0 ) return(-1); theVar = gParse.Nodes + Var; if( theVar->operation==CONST_OP || theVar->value.nelem==1 ) { fferror("Cannot index a scalar value"); return(-1); } n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->nSubNodes = nDim+1; theVar = gParse.Nodes + (this->SubNodes[0]=Var); theDim[0] = gParse.Nodes + (this->SubNodes[1]=Dim1); theDim[1] = gParse.Nodes + (this->SubNodes[2]=Dim2); theDim[2] = gParse.Nodes + (this->SubNodes[3]=Dim3); theDim[3] = gParse.Nodes + (this->SubNodes[4]=Dim4); theDim[4] = gParse.Nodes + (this->SubNodes[5]=Dim5); constant = theVar->operation==CONST_OP; for( idx=0; idxoperation==CONST_OP); for( idx=0; idxvalue.nelem>1 ) { Free_Last_Node(); fferror("Cannot use an array as an index value"); return(-1); } else if( theDim[idx]->type!=LONG ) { Free_Last_Node(); fferror("Index value must be an integer type"); return(-1); } this->operation = '['; this->DoOp = Do_Deref; this->type = theVar->type; if( theVar->value.naxis == nDim ) { /* All dimensions specified */ this->value.nelem = 1; this->value.naxis = 1; this->value.naxes[0] = 1; } else if( nDim==1 ) { /* Dereference only one dimension */ elem=1; this->value.naxis = theVar->value.naxis-1; for( idx=0; idxvalue.naxis; idx++ ) { elem *= ( this->value.naxes[idx] = theVar->value.naxes[idx] ); } this->value.nelem = elem; } else { Free_Last_Node(); fferror("Must specify just one or all indices for vector"); return(-1); } if( constant ) this->DoOp( this ); } return(n); } extern int ffGetVariable( char *varName, FFSTYPE *varVal ); static int New_GTI( funcOp Op, char *fname, int Node1, int Node2, char *start, char *stop ) { fitsfile *fptr; Node *this, *that0, *that1, *that2; int type,i,n, startCol, stopCol, Node0; int hdutype, hdunum, evthdu, samefile, extvers, movetotype, tstat; char extname[100]; long nrows; double timeZeroI[2], timeZeroF[2], dt, timeSpan; char xcol[20], xexpr[20]; FFSTYPE colVal; if( Op == gtifilt_fct && Node1==-99 ) { type = ffGetVariable( "TIME", &colVal ); if( type==COLUMN ) { Node1 = New_Column( (int)colVal.lng ); } else { fferror("Could not build TIME column for GTIFILTER"); return(-1); } } if (Op == gtiover_fct) { if (Node1 == -99 || Node2 == -99) { fferror("startExpr and stopExpr values must be defined for GTIOVERLAP"); return(-1); } /* Also case TIME_STOP to double precision */ Node2 = New_Unary( DOUBLE, 0, Node2 ); if (Node2 < 0) return(-1); } /* Type cast TIME to double precision */ Node1 = New_Unary( DOUBLE, 0, Node1 ); Node0 = Alloc_Node(); /* This will hold the START/STOP times */ if( Node1<0 || Node0<0 ) return(-1); /* Record current HDU number in case we need to move within this file */ fptr = gParse.def_fptr; ffghdn( fptr, &evthdu ); /* Look for TIMEZERO keywords in current extension */ tstat = 0; if( ffgkyd( fptr, "TIMEZERO", timeZeroI, NULL, &tstat ) ) { tstat = 0; if( ffgkyd( fptr, "TIMEZERI", timeZeroI, NULL, &tstat ) ) { timeZeroI[0] = timeZeroF[0] = 0.0; } else if( ffgkyd( fptr, "TIMEZERF", timeZeroF, NULL, &tstat ) ) { timeZeroF[0] = 0.0; } } else { timeZeroF[0] = 0.0; } /* Resolve filename parameter */ switch( fname[0] ) { case '\0': samefile = 1; hdunum = 1; break; case '[': samefile = 1; i = 1; while( fname[i] != '\0' && fname[i] != ']' ) i++; if( fname[i] ) { fname[i] = '\0'; fname++; ffexts( fname, &hdunum, extname, &extvers, &movetotype, xcol, xexpr, &gParse.status ); if( *extname ) { ffmnhd( fptr, movetotype, extname, extvers, &gParse.status ); ffghdn( fptr, &hdunum ); } else if( hdunum ) { ffmahd( fptr, ++hdunum, &hdutype, &gParse.status ); } else if( !gParse.status ) { fferror("Cannot use primary array for GTI filter"); return( -1 ); } } else { fferror("File extension specifier lacks closing ']'"); return( -1 ); } break; case '+': samefile = 1; hdunum = atoi( fname ) + 1; if( hdunum>1 ) ffmahd( fptr, hdunum, &hdutype, &gParse.status ); else { fferror("Cannot use primary array for GTI filter"); return( -1 ); } break; default: samefile = 0; if( ! ffopen( &fptr, fname, READONLY, &gParse.status ) ) ffghdn( fptr, &hdunum ); break; } if( gParse.status ) return(-1); /* If at primary, search for GTI extension */ if( hdunum==1 ) { while( 1 ) { hdunum++; if( ffmahd( fptr, hdunum, &hdutype, &gParse.status ) ) break; if( hdutype==IMAGE_HDU ) continue; tstat = 0; if( ffgkys( fptr, "EXTNAME", extname, NULL, &tstat ) ) continue; ffupch( extname ); if( strstr( extname, "GTI" ) ) break; } if( gParse.status ) { if( gParse.status==END_OF_FILE ) fferror("GTI extension not found in this file"); return(-1); } } /* Locate START/STOP Columns */ ffgcno( fptr, CASEINSEN, start, &startCol, &gParse.status ); ffgcno( fptr, CASEINSEN, stop, &stopCol, &gParse.status ); if( gParse.status ) return(-1); /* Look for TIMEZERO keywords in GTI extension */ tstat = 0; if( ffgkyd( fptr, "TIMEZERO", timeZeroI+1, NULL, &tstat ) ) { tstat = 0; if( ffgkyd( fptr, "TIMEZERI", timeZeroI+1, NULL, &tstat ) ) { timeZeroI[1] = timeZeroF[1] = 0.0; } else if( ffgkyd( fptr, "TIMEZERF", timeZeroF+1, NULL, &tstat ) ) { timeZeroF[1] = 0.0; } } else { timeZeroF[1] = 0.0; } n = Alloc_Node(); if( n >= 0 ) { this = gParse.Nodes + n; this->SubNodes[1] = Node1; this->operation = (int) Op; if (Op == gtifilt_fct) { this->nSubNodes = 2; this->DoOp = Do_GTI; this->type = BOOLEAN; } else { this->nSubNodes = 3; this->DoOp = Do_GTI_Over; this->type = DOUBLE; } that1 = gParse.Nodes + Node1; this->value.nelem = that1->value.nelem; this->value.naxis = that1->value.naxis; for( i=0; i < that1->value.naxis; i++ ) this->value.naxes[i] = that1->value.naxes[i]; if (Op == gtiover_fct) { this->SubNodes[2] = Node2; that2 = gParse.Nodes + Node2; if (that1->value.nelem != that2->value.nelem) { fferror("Dimensions of TIME and TIME_STOP must match for GTIOVERLAP"); return(-1); } } /* Init START/STOP node to be treated as a "constant" */ this->SubNodes[0] = Node0; that0 = gParse.Nodes + Node0; that0->operation = CONST_OP; that0->DoOp = NULL; that0->value.data.ptr= NULL; /* Read in START/STOP times */ if( ffgkyj( fptr, "NAXIS2", &nrows, NULL, &gParse.status ) ) return(-1); that0->value.nelem = nrows; if( nrows ) { that0->value.data.dblptr = (double*)malloc( 2*nrows*sizeof(double) ); if( !that0->value.data.dblptr ) { gParse.status = MEMORY_ALLOCATION; return(-1); } ffgcvd( fptr, startCol, 1L, 1L, nrows, 0.0, that0->value.data.dblptr, &i, &gParse.status ); ffgcvd( fptr, stopCol, 1L, 1L, nrows, 0.0, that0->value.data.dblptr+nrows, &i, &gParse.status ); if( gParse.status ) { free( that0->value.data.dblptr ); return(-1); } /* Test for fully time-ordered GTI... both START && STOP */ that0->type = 1; /* Assume yes */ i = nrows; while( --i ) if( that0->value.data.dblptr[i-1] >= that0->value.data.dblptr[i] || that0->value.data.dblptr[i-1+nrows] >= that0->value.data.dblptr[i+nrows] ) { that0->type = 0; break; } /* GTIOVERLAP() requires ordered GTI */ if (that0->type != 1 && Op == gtiover_fct) { fferror("Input GTI must be time-ordered for GTIOVERLAP"); return(-1); } /* Handle TIMEZERO offset, if any */ dt = (timeZeroI[1] - timeZeroI[0]) + (timeZeroF[1] - timeZeroF[0]); timeSpan = that0->value.data.dblptr[nrows+nrows-1] - that0->value.data.dblptr[0]; if( fabs( dt / timeSpan ) > 1e-12 ) { for( i=0; i<(nrows+nrows); i++ ) that0->value.data.dblptr[i] += dt; } } /* If Node1 is constant (gtifilt_fct) or Node1 and Node2 are constant (gtiover_fct), then evaluate now */ if( OPER(Node1)==CONST_OP && (Op == gtifilt_fct || OPER(Node2)==CONST_OP)) { this->DoOp( this ); } } if( samefile ) ffmahd( fptr, evthdu, &hdutype, &gParse.status ); else ffclos( fptr, &gParse.status ); return( n ); } static int New_REG( char *fname, int NodeX, int NodeY, char *colNames ) { Node *this, *that0; int type, n, Node0; int Xcol, Ycol, tstat; WCSdata wcs; SAORegion *Rgn; char *cX, *cY; FFSTYPE colVal; if( NodeX==-99 ) { type = ffGetVariable( "X", &colVal ); if( type==COLUMN ) { NodeX = New_Column( (int)colVal.lng ); } else { fferror("Could not build X column for REGFILTER"); return(-1); } } if( NodeY==-99 ) { type = ffGetVariable( "Y", &colVal ); if( type==COLUMN ) { NodeY = New_Column( (int)colVal.lng ); } else { fferror("Could not build Y column for REGFILTER"); return(-1); } } NodeX = New_Unary( DOUBLE, 0, NodeX ); NodeY = New_Unary( DOUBLE, 0, NodeY ); Node0 = Alloc_Node(); /* This will hold the Region Data */ if( NodeX<0 || NodeY<0 || Node0<0 ) return(-1); if( ! (Test_Dims( NodeX, NodeY ) ) ) { fferror("Dimensions of REGFILTER arguments are not compatible"); return (-1); } n = Alloc_Node(); if( n >= 0 ) { this = gParse.Nodes + n; this->nSubNodes = 3; this->SubNodes[0] = Node0; this->SubNodes[1] = NodeX; this->SubNodes[2] = NodeY; this->operation = (int)regfilt_fct; this->DoOp = Do_REG; this->type = BOOLEAN; this->value.nelem = 1; this->value.naxis = 1; this->value.naxes[0] = 1; Copy_Dims(n, NodeX); if( SIZE(NodeX)operation = CONST_OP; that0->DoOp = NULL; /* Identify what columns to use for WCS information */ Xcol = Ycol = 0; if( *colNames ) { /* Use the column names in this string for WCS info */ while( *colNames==' ' ) colNames++; cX = cY = colNames; while( *cY && *cY!=' ' && *cY!=',' ) cY++; if( *cY ) *(cY++) = '\0'; while( *cY==' ' ) cY++; if( !*cY ) { fferror("Could not extract valid pair of column names from REGFILTER"); Free_Last_Node(); return( -1 ); } fits_get_colnum( gParse.def_fptr, CASEINSEN, cX, &Xcol, &gParse.status ); fits_get_colnum( gParse.def_fptr, CASEINSEN, cY, &Ycol, &gParse.status ); if( gParse.status ) { fferror("Could not locate columns indicated for WCS info"); Free_Last_Node(); return( -1 ); } } else { /* Try to find columns used in X/Y expressions */ Xcol = Locate_Col( gParse.Nodes + NodeX ); Ycol = Locate_Col( gParse.Nodes + NodeY ); if( Xcol<0 || Ycol<0 ) { fferror("Found multiple X/Y column references in REGFILTER"); Free_Last_Node(); return( -1 ); } } /* Now, get the WCS info, if it exists, from the indicated columns */ wcs.exists = 0; if( Xcol>0 && Ycol>0 ) { tstat = 0; ffgtcs( gParse.def_fptr, Xcol, Ycol, &wcs.xrefval, &wcs.yrefval, &wcs.xrefpix, &wcs.yrefpix, &wcs.xinc, &wcs.yinc, &wcs.rot, wcs.type, &tstat ); if( tstat==NO_WCS_KEY ) { wcs.exists = 0; } else if( tstat ) { gParse.status = tstat; Free_Last_Node(); return( -1 ); } else { wcs.exists = 1; } } /* Read in Region file */ fits_read_rgnfile( fname, &wcs, &Rgn, &gParse.status ); if( gParse.status ) { Free_Last_Node(); return( -1 ); } that0->value.data.ptr = Rgn; if( OPER(NodeX)==CONST_OP && OPER(NodeY)==CONST_OP ) this->DoOp( this ); } return( n ); } static int New_Vector( int subNode ) { Node *this, *that; int n; n = Alloc_Node(); if( n >= 0 ) { this = gParse.Nodes + n; that = gParse.Nodes + subNode; this->type = that->type; this->nSubNodes = 1; this->SubNodes[0] = subNode; this->operation = '{'; this->DoOp = Do_Vector; } return( n ); } static int Close_Vec( int vecNode ) { Node *this; int n, nelem=0; this = gParse.Nodes + vecNode; for( n=0; n < this->nSubNodes; n++ ) { if( TYPE( this->SubNodes[n] ) != this->type ) { this->SubNodes[n] = New_Unary( this->type, 0, this->SubNodes[n] ); if( this->SubNodes[n]<0 ) return(-1); } nelem += SIZE(this->SubNodes[n]); } this->value.naxis = 1; this->value.nelem = nelem; this->value.naxes[0] = nelem; return( vecNode ); } static int Locate_Col( Node *this ) /* Locate the TABLE column number of any columns in "this" calculation. */ /* Return ZERO if none found, or negative if more than 1 found. */ { Node *that; int i, col=0, newCol, nfound=0; if( this->nSubNodes==0 && this->operation<=0 && this->operation!=CONST_OP ) return gParse.colData[ - this->operation].colnum; for( i=0; inSubNodes; i++ ) { that = gParse.Nodes + this->SubNodes[i]; if( that->operation>0 ) { newCol = Locate_Col( that ); if( newCol<=0 ) { nfound += -newCol; } else { if( !nfound ) { col = newCol; nfound++; } else if( col != newCol ) { nfound++; } } } else if( that->operation!=CONST_OP ) { /* Found a Column */ newCol = gParse.colData[- that->operation].colnum; if( !nfound ) { col = newCol; nfound++; } else if( col != newCol ) { nfound++; } } } if( nfound!=1 ) return( - nfound ); else return( col ); } static int Test_Dims( int Node1, int Node2 ) { Node *that1, *that2; int valid, i; if( Node1<0 || Node2<0 ) return(0); that1 = gParse.Nodes + Node1; that2 = gParse.Nodes + Node2; if( that1->value.nelem==1 || that2->value.nelem==1 ) valid = 1; else if( that1->type==that2->type && that1->value.nelem==that2->value.nelem && that1->value.naxis==that2->value.naxis ) { valid = 1; for( i=0; ivalue.naxis; i++ ) { if( that1->value.naxes[i]!=that2->value.naxes[i] ) valid = 0; } } else valid = 0; return( valid ); } static void Copy_Dims( int Node1, int Node2 ) { Node *that1, *that2; int i; if( Node1<0 || Node2<0 ) return; that1 = gParse.Nodes + Node1; that2 = gParse.Nodes + Node2; that1->value.nelem = that2->value.nelem; that1->value.naxis = that2->value.naxis; for( i=0; ivalue.naxis; i++ ) that1->value.naxes[i] = that2->value.naxes[i]; } /********************************************************************/ /* Routines for actually evaluating the expression start here */ /********************************************************************/ void Evaluate_Parser( long firstRow, long nRows ) /***********************************************************************/ /* Reset the parser for processing another batch of data... */ /* firstRow: Row number of the first element to evaluate */ /* nRows: Number of rows to be processed */ /* Initialize each COLUMN node so that its UNDEF and DATA pointers */ /* point to the appropriate column arrays. */ /* Finally, call Evaluate_Node for final node. */ /***********************************************************************/ { int i, column; long offset, rowOffset; static int rand_initialized = 0; /* Initialize the random number generator once and only once */ if (rand_initialized == 0) { simplerng_srand( (unsigned int) time(NULL) ); rand_initialized = 1; } gParse.firstRow = firstRow; gParse.nRows = nRows; /* Reset Column Nodes' pointers to point to right data and UNDEF arrays */ rowOffset = firstRow - gParse.firstDataRow; for( i=0; i 0 || OPER(i) == CONST_OP ) continue; column = -OPER(i); offset = gParse.varData[column].nelem * rowOffset; gParse.Nodes[i].value.undef = gParse.varData[column].undef + offset; switch( gParse.Nodes[i].type ) { case BITSTR: gParse.Nodes[i].value.data.strptr = (char**)gParse.varData[column].data + rowOffset; gParse.Nodes[i].value.undef = NULL; break; case STRING: gParse.Nodes[i].value.data.strptr = (char**)gParse.varData[column].data + rowOffset; gParse.Nodes[i].value.undef = gParse.varData[column].undef + rowOffset; break; case BOOLEAN: gParse.Nodes[i].value.data.logptr = (char*)gParse.varData[column].data + offset; break; case LONG: gParse.Nodes[i].value.data.lngptr = (long*)gParse.varData[column].data + offset; break; case DOUBLE: gParse.Nodes[i].value.data.dblptr = (double*)gParse.varData[column].data + offset; break; } } Evaluate_Node( gParse.resultNode ); } static void Evaluate_Node( int thisNode ) /**********************************************************************/ /* Recursively evaluate thisNode's subNodes, then call one of the */ /* Do_ functions pointed to by thisNode's DoOp element. */ /**********************************************************************/ { Node *this; int i; if( gParse.status ) return; this = gParse.Nodes + thisNode; if( this->operation>0 ) { /* <=0 indicate constants and columns */ i = this->nSubNodes; while( i-- ) { Evaluate_Node( this->SubNodes[i] ); if( gParse.status ) return; } this->DoOp( this ); } } static void Allocate_Ptrs( Node *this ) { long elem, row, size; if( this->type==BITSTR || this->type==STRING ) { this->value.data.strptr = (char**)malloc( gParse.nRows * sizeof(char*) ); if( this->value.data.strptr ) { this->value.data.strptr[0] = (char*)malloc( gParse.nRows * (this->value.nelem+2) * sizeof(char) ); if( this->value.data.strptr[0] ) { row = 0; while( (++row)value.data.strptr[row] = this->value.data.strptr[row-1] + this->value.nelem+1; } if( this->type==STRING ) { this->value.undef = this->value.data.strptr[row-1] + this->value.nelem+1; } else { this->value.undef = NULL; /* BITSTRs don't use undef array */ } } else { gParse.status = MEMORY_ALLOCATION; free( this->value.data.strptr ); } } else { gParse.status = MEMORY_ALLOCATION; } } else { elem = this->value.nelem * gParse.nRows; switch( this->type ) { case DOUBLE: size = sizeof( double ); break; case LONG: size = sizeof( long ); break; case BOOLEAN: size = sizeof( char ); break; default: size = 1; break; } this->value.data.ptr = calloc(size+1, elem); if( this->value.data.ptr==NULL ) { gParse.status = MEMORY_ALLOCATION; } else { this->value.undef = (char *)this->value.data.ptr + elem*size; } } } static void Do_Unary( Node *this ) { Node *that; long elem; that = gParse.Nodes + this->SubNodes[0]; if( that->operation==CONST_OP ) { /* Operating on a constant! */ switch( this->operation ) { case DOUBLE: case FLTCAST: if( that->type==LONG ) this->value.data.dbl = (double)that->value.data.lng; else if( that->type==BOOLEAN ) this->value.data.dbl = ( that->value.data.log ? 1.0 : 0.0 ); break; case LONG: case INTCAST: if( that->type==DOUBLE ) this->value.data.lng = (long)that->value.data.dbl; else if( that->type==BOOLEAN ) this->value.data.lng = ( that->value.data.log ? 1L : 0L ); break; case BOOLEAN: if( that->type==DOUBLE ) this->value.data.log = ( that->value.data.dbl != 0.0 ); else if( that->type==LONG ) this->value.data.log = ( that->value.data.lng != 0L ); break; case UMINUS: if( that->type==DOUBLE ) this->value.data.dbl = - that->value.data.dbl; else if( that->type==LONG ) this->value.data.lng = - that->value.data.lng; break; case NOT: if( that->type==BOOLEAN ) this->value.data.log = ( ! that->value.data.log ); else if( that->type==BITSTR ) bitnot( this->value.data.str, that->value.data.str ); break; } this->operation = CONST_OP; } else { Allocate_Ptrs( this ); if( !gParse.status ) { if( this->type!=BITSTR ) { elem = gParse.nRows; if( this->type!=STRING ) elem *= this->value.nelem; while( elem-- ) this->value.undef[elem] = that->value.undef[elem]; } elem = gParse.nRows * this->value.nelem; switch( this->operation ) { case BOOLEAN: if( that->type==DOUBLE ) while( elem-- ) this->value.data.logptr[elem] = ( that->value.data.dblptr[elem] != 0.0 ); else if( that->type==LONG ) while( elem-- ) this->value.data.logptr[elem] = ( that->value.data.lngptr[elem] != 0L ); break; case DOUBLE: case FLTCAST: if( that->type==LONG ) while( elem-- ) this->value.data.dblptr[elem] = (double)that->value.data.lngptr[elem]; else if( that->type==BOOLEAN ) while( elem-- ) this->value.data.dblptr[elem] = ( that->value.data.logptr[elem] ? 1.0 : 0.0 ); break; case LONG: case INTCAST: if( that->type==DOUBLE ) while( elem-- ) this->value.data.lngptr[elem] = (long)that->value.data.dblptr[elem]; else if( that->type==BOOLEAN ) while( elem-- ) this->value.data.lngptr[elem] = ( that->value.data.logptr[elem] ? 1L : 0L ); break; case UMINUS: if( that->type==DOUBLE ) { while( elem-- ) this->value.data.dblptr[elem] = - that->value.data.dblptr[elem]; } else if( that->type==LONG ) { while( elem-- ) this->value.data.lngptr[elem] = - that->value.data.lngptr[elem]; } break; case NOT: if( that->type==BOOLEAN ) { while( elem-- ) this->value.data.logptr[elem] = ( ! that->value.data.logptr[elem] ); } else if( that->type==BITSTR ) { elem = gParse.nRows; while( elem-- ) bitnot( this->value.data.strptr[elem], that->value.data.strptr[elem] ); } break; } } } if( that->operation>0 ) { free( that->value.data.ptr ); } } static void Do_Offset( Node *this ) { Node *col; long fRow, nRowOverlap, nRowReload, rowOffset; long nelem, elem, offset, nRealElem; int status; col = gParse.Nodes + this->SubNodes[0]; rowOffset = gParse.Nodes[ this->SubNodes[1] ].value.data.lng; Allocate_Ptrs( this ); fRow = gParse.firstRow + rowOffset; if( this->type==STRING || this->type==BITSTR ) nRealElem = 1; else nRealElem = this->value.nelem; nelem = nRealElem; if( fRow < gParse.firstDataRow ) { /* Must fill in data at start of array */ nRowReload = gParse.firstDataRow - fRow; if( nRowReload > gParse.nRows ) nRowReload = gParse.nRows; nRowOverlap = gParse.nRows - nRowReload; offset = 0; /* NULLify any values falling out of bounds */ while( fRow<1 && nRowReload>0 ) { if( this->type == BITSTR ) { nelem = this->value.nelem; this->value.data.strptr[offset][ nelem ] = '\0'; while( nelem-- ) this->value.data.strptr[offset][nelem] = '0'; offset++; } else { while( nelem-- ) this->value.undef[offset++] = 1; } nelem = nRealElem; fRow++; nRowReload--; } } else if( fRow + gParse.nRows > gParse.firstDataRow + gParse.nDataRows ) { /* Must fill in data at end of array */ nRowReload = (fRow+gParse.nRows) - (gParse.firstDataRow+gParse.nDataRows); if( nRowReload>gParse.nRows ) { nRowReload = gParse.nRows; } else { fRow = gParse.firstDataRow + gParse.nDataRows; } nRowOverlap = gParse.nRows - nRowReload; offset = nRowOverlap * nelem; /* NULLify any values falling out of bounds */ elem = gParse.nRows * nelem; while( fRow+nRowReload>gParse.totalRows && nRowReload>0 ) { if( this->type == BITSTR ) { nelem = this->value.nelem; elem--; this->value.data.strptr[elem][ nelem ] = '\0'; while( nelem-- ) this->value.data.strptr[elem][nelem] = '0'; } else { while( nelem-- ) this->value.undef[--elem] = 1; } nelem = nRealElem; nRowReload--; } } else { nRowReload = 0; nRowOverlap = gParse.nRows; offset = 0; } if( nRowReload>0 ) { switch( this->type ) { case BITSTR: case STRING: status = (*gParse.loadData)( -col->operation, fRow, nRowReload, this->value.data.strptr+offset, this->value.undef+offset ); break; case BOOLEAN: status = (*gParse.loadData)( -col->operation, fRow, nRowReload, this->value.data.logptr+offset, this->value.undef+offset ); break; case LONG: status = (*gParse.loadData)( -col->operation, fRow, nRowReload, this->value.data.lngptr+offset, this->value.undef+offset ); break; case DOUBLE: status = (*gParse.loadData)( -col->operation, fRow, nRowReload, this->value.data.dblptr+offset, this->value.undef+offset ); break; } } /* Now copy over the overlapping region, if any */ if( nRowOverlap <= 0 ) return; if( rowOffset>0 ) elem = nRowOverlap * nelem; else elem = gParse.nRows * nelem; offset = nelem * rowOffset; while( nRowOverlap-- && !gParse.status ) { while( nelem-- && !gParse.status ) { elem--; if( this->type != BITSTR ) this->value.undef[elem] = col->value.undef[elem+offset]; switch( this->type ) { case BITSTR: strcpy( this->value.data.strptr[elem ], col->value.data.strptr[elem+offset] ); break; case STRING: strcpy( this->value.data.strptr[elem ], col->value.data.strptr[elem+offset] ); break; case BOOLEAN: this->value.data.logptr[elem] = col->value.data.logptr[elem+offset]; break; case LONG: this->value.data.lngptr[elem] = col->value.data.lngptr[elem+offset]; break; case DOUBLE: this->value.data.dblptr[elem] = col->value.data.dblptr[elem+offset]; break; } } nelem = nRealElem; } } static void Do_BinOp_bit( Node *this ) { Node *that1, *that2; char *sptr1=NULL, *sptr2=NULL; int const1, const2; long rows; that1 = gParse.Nodes + this->SubNodes[0]; that2 = gParse.Nodes + this->SubNodes[1]; const1 = ( that1->operation==CONST_OP ); const2 = ( that2->operation==CONST_OP ); sptr1 = ( const1 ? that1->value.data.str : NULL ); sptr2 = ( const2 ? that2->value.data.str : NULL ); if( const1 && const2 ) { switch( this->operation ) { case NE: this->value.data.log = !bitcmp( sptr1, sptr2 ); break; case EQ: this->value.data.log = bitcmp( sptr1, sptr2 ); break; case GT: case LT: case LTE: case GTE: this->value.data.log = bitlgte( sptr1, this->operation, sptr2 ); break; case '|': bitor( this->value.data.str, sptr1, sptr2 ); break; case '&': bitand( this->value.data.str, sptr1, sptr2 ); break; case '+': strcpy( this->value.data.str, sptr1 ); strcat( this->value.data.str, sptr2 ); break; case ACCUM: this->value.data.lng = 0; while( *sptr1 ) { if ( *sptr1 == '1' ) this->value.data.lng ++; sptr1 ++; } break; } this->operation = CONST_OP; } else { Allocate_Ptrs( this ); if( !gParse.status ) { rows = gParse.nRows; switch( this->operation ) { /* BITSTR comparisons */ case NE: case EQ: case GT: case LT: case LTE: case GTE: while( rows-- ) { if( !const1 ) sptr1 = that1->value.data.strptr[rows]; if( !const2 ) sptr2 = that2->value.data.strptr[rows]; switch( this->operation ) { case NE: this->value.data.logptr[rows] = !bitcmp( sptr1, sptr2 ); break; case EQ: this->value.data.logptr[rows] = bitcmp( sptr1, sptr2 ); break; case GT: case LT: case LTE: case GTE: this->value.data.logptr[rows] = bitlgte( sptr1, this->operation, sptr2 ); break; } this->value.undef[rows] = 0; } break; /* BITSTR AND/ORs ... no UNDEFS in or out */ case '|': case '&': case '+': while( rows-- ) { if( !const1 ) sptr1 = that1->value.data.strptr[rows]; if( !const2 ) sptr2 = that2->value.data.strptr[rows]; if( this->operation=='|' ) bitor( this->value.data.strptr[rows], sptr1, sptr2 ); else if( this->operation=='&' ) bitand( this->value.data.strptr[rows], sptr1, sptr2 ); else { strcpy( this->value.data.strptr[rows], sptr1 ); strcat( this->value.data.strptr[rows], sptr2 ); } } break; /* Accumulate 1 bits */ case ACCUM: { long i, previous, curr; previous = that2->value.data.lng; /* Cumulative sum of this chunk */ for (i=0; ivalue.data.strptr[i]; for (curr = 0; *sptr1; sptr1 ++) { if ( *sptr1 == '1' ) curr ++; } previous += curr; this->value.data.lngptr[i] = previous; this->value.undef[i] = 0; } /* Store final cumulant for next pass */ that2->value.data.lng = previous; } } } } if( that1->operation>0 ) { free( that1->value.data.strptr[0] ); free( that1->value.data.strptr ); } if( that2->operation>0 ) { free( that2->value.data.strptr[0] ); free( that2->value.data.strptr ); } } static void Do_BinOp_str( Node *this ) { Node *that1, *that2; char *sptr1, *sptr2, null1=0, null2=0; int const1, const2, val; long rows; that1 = gParse.Nodes + this->SubNodes[0]; that2 = gParse.Nodes + this->SubNodes[1]; const1 = ( that1->operation==CONST_OP ); const2 = ( that2->operation==CONST_OP ); sptr1 = ( const1 ? that1->value.data.str : NULL ); sptr2 = ( const2 ? that2->value.data.str : NULL ); if( const1 && const2 ) { /* Result is a constant */ switch( this->operation ) { /* Compare Strings */ case NE: case EQ: val = ( FSTRCMP( sptr1, sptr2 ) == 0 ); this->value.data.log = ( this->operation==EQ ? val : !val ); break; case GT: this->value.data.log = ( FSTRCMP( sptr1, sptr2 ) > 0 ); break; case LT: this->value.data.log = ( FSTRCMP( sptr1, sptr2 ) < 0 ); break; case GTE: this->value.data.log = ( FSTRCMP( sptr1, sptr2 ) >= 0 ); break; case LTE: this->value.data.log = ( FSTRCMP( sptr1, sptr2 ) <= 0 ); break; /* Concat Strings */ case '+': strcpy( this->value.data.str, sptr1 ); strcat( this->value.data.str, sptr2 ); break; } this->operation = CONST_OP; } else { /* Not a constant */ Allocate_Ptrs( this ); if( !gParse.status ) { rows = gParse.nRows; switch( this->operation ) { /* Compare Strings */ case NE: case EQ: while( rows-- ) { if( !const1 ) null1 = that1->value.undef[rows]; if( !const2 ) null2 = that2->value.undef[rows]; this->value.undef[rows] = (null1 || null2); if( ! this->value.undef[rows] ) { if( !const1 ) sptr1 = that1->value.data.strptr[rows]; if( !const2 ) sptr2 = that2->value.data.strptr[rows]; val = ( FSTRCMP( sptr1, sptr2 ) == 0 ); this->value.data.logptr[rows] = ( this->operation==EQ ? val : !val ); } } break; case GT: case LT: while( rows-- ) { if( !const1 ) null1 = that1->value.undef[rows]; if( !const2 ) null2 = that2->value.undef[rows]; this->value.undef[rows] = (null1 || null2); if( ! this->value.undef[rows] ) { if( !const1 ) sptr1 = that1->value.data.strptr[rows]; if( !const2 ) sptr2 = that2->value.data.strptr[rows]; val = ( FSTRCMP( sptr1, sptr2 ) ); this->value.data.logptr[rows] = ( this->operation==GT ? val>0 : val<0 ); } } break; case GTE: case LTE: while( rows-- ) { if( !const1 ) null1 = that1->value.undef[rows]; if( !const2 ) null2 = that2->value.undef[rows]; this->value.undef[rows] = (null1 || null2); if( ! this->value.undef[rows] ) { if( !const1 ) sptr1 = that1->value.data.strptr[rows]; if( !const2 ) sptr2 = that2->value.data.strptr[rows]; val = ( FSTRCMP( sptr1, sptr2 ) ); this->value.data.logptr[rows] = ( this->operation==GTE ? val>=0 : val<=0 ); } } break; /* Concat Strings */ case '+': while( rows-- ) { if( !const1 ) null1 = that1->value.undef[rows]; if( !const2 ) null2 = that2->value.undef[rows]; this->value.undef[rows] = (null1 || null2); if( ! this->value.undef[rows] ) { if( !const1 ) sptr1 = that1->value.data.strptr[rows]; if( !const2 ) sptr2 = that2->value.data.strptr[rows]; strcpy( this->value.data.strptr[rows], sptr1 ); strcat( this->value.data.strptr[rows], sptr2 ); } } break; } } } if( that1->operation>0 ) { free( that1->value.data.strptr[0] ); free( that1->value.data.strptr ); } if( that2->operation>0 ) { free( that2->value.data.strptr[0] ); free( that2->value.data.strptr ); } } static void Do_BinOp_log( Node *this ) { Node *that1, *that2; int vector1, vector2; char val1=0, val2=0, null1=0, null2=0; long rows, nelem, elem; that1 = gParse.Nodes + this->SubNodes[0]; that2 = gParse.Nodes + this->SubNodes[1]; vector1 = ( that1->operation!=CONST_OP ); if( vector1 ) vector1 = that1->value.nelem; else { val1 = that1->value.data.log; } vector2 = ( that2->operation!=CONST_OP ); if( vector2 ) vector2 = that2->value.nelem; else { val2 = that2->value.data.log; } if( !vector1 && !vector2 ) { /* Result is a constant */ switch( this->operation ) { case OR: this->value.data.log = (val1 || val2); break; case AND: this->value.data.log = (val1 && val2); break; case EQ: this->value.data.log = ( (val1 && val2) || (!val1 && !val2) ); break; case NE: this->value.data.log = ( (val1 && !val2) || (!val1 && val2) ); break; case ACCUM: this->value.data.lng = val1; break; } this->operation=CONST_OP; } else if (this->operation == ACCUM) { long i, previous, curr; rows = gParse.nRows; nelem = this->value.nelem; elem = this->value.nelem * rows; Allocate_Ptrs( this ); if( !gParse.status ) { previous = that2->value.data.lng; /* Cumulative sum of this chunk */ for (i=0; ivalue.undef[i]) { curr = that1->value.data.logptr[i]; previous += curr; } this->value.data.lngptr[i] = previous; this->value.undef[i] = 0; } /* Store final cumulant for next pass */ that2->value.data.lng = previous; } } else { rows = gParse.nRows; nelem = this->value.nelem; elem = this->value.nelem * rows; Allocate_Ptrs( this ); if( !gParse.status ) { if (this->operation == ACCUM) { long i, previous, curr; previous = that2->value.data.lng; /* Cumulative sum of this chunk */ for (i=0; ivalue.undef[i]) { curr = that1->value.data.logptr[i]; previous += curr; } this->value.data.lngptr[i] = previous; this->value.undef[i] = 0; } /* Store final cumulant for next pass */ that2->value.data.lng = previous; } while( rows-- ) { while( nelem-- ) { elem--; if( vector1>1 ) { val1 = that1->value.data.logptr[elem]; null1 = that1->value.undef[elem]; } else if( vector1 ) { val1 = that1->value.data.logptr[rows]; null1 = that1->value.undef[rows]; } if( vector2>1 ) { val2 = that2->value.data.logptr[elem]; null2 = that2->value.undef[elem]; } else if( vector2 ) { val2 = that2->value.data.logptr[rows]; null2 = that2->value.undef[rows]; } this->value.undef[elem] = (null1 || null2); switch( this->operation ) { case OR: /* This is more complicated than others to suppress UNDEFs */ /* in those cases where the other argument is DEF && TRUE */ if( !null1 && !null2 ) { this->value.data.logptr[elem] = (val1 || val2); } else if( (null1 && !null2 && val2) || ( !null1 && null2 && val1 ) ) { this->value.data.logptr[elem] = 1; this->value.undef[elem] = 0; } break; case AND: /* This is more complicated than others to suppress UNDEFs */ /* in those cases where the other argument is DEF && FALSE */ if( !null1 && !null2 ) { this->value.data.logptr[elem] = (val1 && val2); } else if( (null1 && !null2 && !val2) || ( !null1 && null2 && !val1 ) ) { this->value.data.logptr[elem] = 0; this->value.undef[elem] = 0; } break; case EQ: this->value.data.logptr[elem] = ( (val1 && val2) || (!val1 && !val2) ); break; case NE: this->value.data.logptr[elem] = ( (val1 && !val2) || (!val1 && val2) ); break; } } nelem = this->value.nelem; } } } if( that1->operation>0 ) { free( that1->value.data.ptr ); } if( that2->operation>0 ) { free( that2->value.data.ptr ); } } static void Do_BinOp_lng( Node *this ) { Node *that1, *that2; int vector1, vector2; long val1=0, val2=0; char null1=0, null2=0; long rows, nelem, elem; that1 = gParse.Nodes + this->SubNodes[0]; that2 = gParse.Nodes + this->SubNodes[1]; vector1 = ( that1->operation!=CONST_OP ); if( vector1 ) vector1 = that1->value.nelem; else { val1 = that1->value.data.lng; } vector2 = ( that2->operation!=CONST_OP ); if( vector2 ) vector2 = that2->value.nelem; else { val2 = that2->value.data.lng; } if( !vector1 && !vector2 ) { /* Result is a constant */ switch( this->operation ) { case '~': /* Treat as == for LONGS */ case EQ: this->value.data.log = (val1 == val2); break; case NE: this->value.data.log = (val1 != val2); break; case GT: this->value.data.log = (val1 > val2); break; case LT: this->value.data.log = (val1 < val2); break; case LTE: this->value.data.log = (val1 <= val2); break; case GTE: this->value.data.log = (val1 >= val2); break; case '+': this->value.data.lng = (val1 + val2); break; case '-': this->value.data.lng = (val1 - val2); break; case '*': this->value.data.lng = (val1 * val2); break; case '&': this->value.data.lng = (val1 & val2); break; case '|': this->value.data.lng = (val1 | val2); break; case '^': this->value.data.lng = (val1 ^ val2); break; case '%': if( val2 ) this->value.data.lng = (val1 % val2); else fferror("Divide by Zero"); break; case '/': if( val2 ) this->value.data.lng = (val1 / val2); else fferror("Divide by Zero"); break; case POWER: this->value.data.lng = (long)pow((double)val1,(double)val2); break; case ACCUM: this->value.data.lng = val1; break; case DIFF: this->value.data.lng = 0; break; } this->operation=CONST_OP; } else if ((this->operation == ACCUM) || (this->operation == DIFF)) { long i, previous, curr; long undef; rows = gParse.nRows; nelem = this->value.nelem; elem = this->value.nelem * rows; Allocate_Ptrs( this ); if( !gParse.status ) { previous = that2->value.data.lng; undef = (long) that2->value.undef; if (this->operation == ACCUM) { /* Cumulative sum of this chunk */ for (i=0; ivalue.undef[i]) { curr = that1->value.data.lngptr[i]; previous += curr; } this->value.data.lngptr[i] = previous; this->value.undef[i] = 0; } } else { /* Sequential difference for this chunk */ for (i=0; ivalue.data.lngptr[i]; if (that1->value.undef[i] || undef) { /* Either this, or previous, value was undefined */ this->value.data.lngptr[i] = 0; this->value.undef[i] = 1; } else { /* Both defined, we are okay! */ this->value.data.lngptr[i] = curr - previous; this->value.undef[i] = 0; } previous = curr; undef = that1->value.undef[i]; } } /* Store final cumulant for next pass */ that2->value.data.lng = previous; that2->value.undef = (char *) undef; /* XXX evil, but no harm here */ } } else { rows = gParse.nRows; nelem = this->value.nelem; elem = this->value.nelem * rows; Allocate_Ptrs( this ); while( rows-- && !gParse.status ) { while( nelem-- && !gParse.status ) { elem--; if( vector1>1 ) { val1 = that1->value.data.lngptr[elem]; null1 = that1->value.undef[elem]; } else if( vector1 ) { val1 = that1->value.data.lngptr[rows]; null1 = that1->value.undef[rows]; } if( vector2>1 ) { val2 = that2->value.data.lngptr[elem]; null2 = that2->value.undef[elem]; } else if( vector2 ) { val2 = that2->value.data.lngptr[rows]; null2 = that2->value.undef[rows]; } this->value.undef[elem] = (null1 || null2); switch( this->operation ) { case '~': /* Treat as == for LONGS */ case EQ: this->value.data.logptr[elem] = (val1 == val2); break; case NE: this->value.data.logptr[elem] = (val1 != val2); break; case GT: this->value.data.logptr[elem] = (val1 > val2); break; case LT: this->value.data.logptr[elem] = (val1 < val2); break; case LTE: this->value.data.logptr[elem] = (val1 <= val2); break; case GTE: this->value.data.logptr[elem] = (val1 >= val2); break; case '+': this->value.data.lngptr[elem] = (val1 + val2); break; case '-': this->value.data.lngptr[elem] = (val1 - val2); break; case '*': this->value.data.lngptr[elem] = (val1 * val2); break; case '&': this->value.data.lngptr[elem] = (val1 & val2); break; case '|': this->value.data.lngptr[elem] = (val1 | val2); break; case '^': this->value.data.lngptr[elem] = (val1 ^ val2); break; case '%': if( val2 ) this->value.data.lngptr[elem] = (val1 % val2); else { this->value.data.lngptr[elem] = 0; this->value.undef[elem] = 1; } break; case '/': if( val2 ) this->value.data.lngptr[elem] = (val1 / val2); else { this->value.data.lngptr[elem] = 0; this->value.undef[elem] = 1; } break; case POWER: this->value.data.lngptr[elem] = (long)pow((double)val1,(double)val2); break; } } nelem = this->value.nelem; } } if( that1->operation>0 ) { free( that1->value.data.ptr ); } if( that2->operation>0 ) { free( that2->value.data.ptr ); } } static void Do_BinOp_dbl( Node *this ) { Node *that1, *that2; int vector1, vector2; double val1=0.0, val2=0.0; char null1=0, null2=0; long rows, nelem, elem; that1 = gParse.Nodes + this->SubNodes[0]; that2 = gParse.Nodes + this->SubNodes[1]; vector1 = ( that1->operation!=CONST_OP ); if( vector1 ) vector1 = that1->value.nelem; else { val1 = that1->value.data.dbl; } vector2 = ( that2->operation!=CONST_OP ); if( vector2 ) vector2 = that2->value.nelem; else { val2 = that2->value.data.dbl; } if( !vector1 && !vector2 ) { /* Result is a constant */ switch( this->operation ) { case '~': this->value.data.log = ( fabs(val1-val2) < APPROX ); break; case EQ: this->value.data.log = (val1 == val2); break; case NE: this->value.data.log = (val1 != val2); break; case GT: this->value.data.log = (val1 > val2); break; case LT: this->value.data.log = (val1 < val2); break; case LTE: this->value.data.log = (val1 <= val2); break; case GTE: this->value.data.log = (val1 >= val2); break; case '+': this->value.data.dbl = (val1 + val2); break; case '-': this->value.data.dbl = (val1 - val2); break; case '*': this->value.data.dbl = (val1 * val2); break; case '%': if( val2 ) this->value.data.dbl = val1 - val2*((int)(val1/val2)); else fferror("Divide by Zero"); break; case '/': if( val2 ) this->value.data.dbl = (val1 / val2); else fferror("Divide by Zero"); break; case POWER: this->value.data.dbl = (double)pow(val1,val2); break; case ACCUM: this->value.data.dbl = val1; break; case DIFF: this->value.data.dbl = 0; break; } this->operation=CONST_OP; } else if ((this->operation == ACCUM) || (this->operation == DIFF)) { long i; long undef; double previous, curr; rows = gParse.nRows; nelem = this->value.nelem; elem = this->value.nelem * rows; Allocate_Ptrs( this ); if( !gParse.status ) { previous = that2->value.data.dbl; undef = (long) that2->value.undef; if (this->operation == ACCUM) { /* Cumulative sum of this chunk */ for (i=0; ivalue.undef[i]) { curr = that1->value.data.dblptr[i]; previous += curr; } this->value.data.dblptr[i] = previous; this->value.undef[i] = 0; } } else { /* Sequential difference for this chunk */ for (i=0; ivalue.data.dblptr[i]; if (that1->value.undef[i] || undef) { /* Either this, or previous, value was undefined */ this->value.data.dblptr[i] = 0; this->value.undef[i] = 1; } else { /* Both defined, we are okay! */ this->value.data.dblptr[i] = curr - previous; this->value.undef[i] = 0; } previous = curr; undef = that1->value.undef[i]; } } /* Store final cumulant for next pass */ that2->value.data.dbl = previous; that2->value.undef = (char *) undef; /* XXX evil, but no harm here */ } } else { rows = gParse.nRows; nelem = this->value.nelem; elem = this->value.nelem * rows; Allocate_Ptrs( this ); while( rows-- && !gParse.status ) { while( nelem-- && !gParse.status ) { elem--; if( vector1>1 ) { val1 = that1->value.data.dblptr[elem]; null1 = that1->value.undef[elem]; } else if( vector1 ) { val1 = that1->value.data.dblptr[rows]; null1 = that1->value.undef[rows]; } if( vector2>1 ) { val2 = that2->value.data.dblptr[elem]; null2 = that2->value.undef[elem]; } else if( vector2 ) { val2 = that2->value.data.dblptr[rows]; null2 = that2->value.undef[rows]; } this->value.undef[elem] = (null1 || null2); switch( this->operation ) { case '~': this->value.data.logptr[elem] = ( fabs(val1-val2) < APPROX ); break; case EQ: this->value.data.logptr[elem] = (val1 == val2); break; case NE: this->value.data.logptr[elem] = (val1 != val2); break; case GT: this->value.data.logptr[elem] = (val1 > val2); break; case LT: this->value.data.logptr[elem] = (val1 < val2); break; case LTE: this->value.data.logptr[elem] = (val1 <= val2); break; case GTE: this->value.data.logptr[elem] = (val1 >= val2); break; case '+': this->value.data.dblptr[elem] = (val1 + val2); break; case '-': this->value.data.dblptr[elem] = (val1 - val2); break; case '*': this->value.data.dblptr[elem] = (val1 * val2); break; case '%': if( val2 ) this->value.data.dblptr[elem] = val1 - val2*((int)(val1/val2)); else { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } break; case '/': if( val2 ) this->value.data.dblptr[elem] = (val1 / val2); else { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } break; case POWER: this->value.data.dblptr[elem] = (double)pow(val1,val2); break; } } nelem = this->value.nelem; } } if( that1->operation>0 ) { free( that1->value.data.ptr ); } if( that2->operation>0 ) { free( that2->value.data.ptr ); } } /* * This Quickselect routine is based on the algorithm described in * "Numerical recipes in C", Second Edition, * Cambridge University Press, 1992, Section 8.5, ISBN 0-521-43108-5 * This code by Nicolas Devillard - 1998. Public domain. * http://ndevilla.free.fr/median/median/src/quickselect.c */ #define ELEM_SWAP(a,b) { register long t=(a);(a)=(b);(b)=t; } /* * qselect_median_lng - select the median value of a long array * * This routine selects the median value of the long integer array * arr[]. If there are an even number of elements, the "lower median" * is selected. * * The array arr[] is scrambled, so users must operate on a scratch * array if they wish the values to be preserved. * * long arr[] - array of values * int n - number of elements in arr * * RETURNS: the lower median value of arr[] * */ long qselect_median_lng(long arr[], int n) { int low, high ; int median; int middle, ll, hh; low = 0 ; high = n-1 ; median = (low + high) / 2; for (;;) { if (high <= low) { /* One element only */ return arr[median]; } if (high == low + 1) { /* Two elements only */ if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; return arr[median]; } /* Find median of low, middle and high items; swap into position low */ middle = (low + high) / 2; if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]) ; if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]) ; /* Swap low item (now in position middle) into position (low+1) */ ELEM_SWAP(arr[middle], arr[low+1]) ; /* Nibble from each end towards middle, swapping items when stuck */ ll = low + 1; hh = high; for (;;) { do ll++; while (arr[low] > arr[ll]) ; do hh--; while (arr[hh] > arr[low]) ; if (hh < ll) break; ELEM_SWAP(arr[ll], arr[hh]) ; } /* Swap middle item (in position low) back into correct position */ ELEM_SWAP(arr[low], arr[hh]) ; /* Re-set active partition */ if (hh <= median) low = ll; if (hh >= median) high = hh - 1; } } #undef ELEM_SWAP #define ELEM_SWAP(a,b) { register double t=(a);(a)=(b);(b)=t; } /* * qselect_median_dbl - select the median value of a double array * * This routine selects the median value of the double array * arr[]. If there are an even number of elements, the "lower median" * is selected. * * The array arr[] is scrambled, so users must operate on a scratch * array if they wish the values to be preserved. * * double arr[] - array of values * int n - number of elements in arr * * RETURNS: the lower median value of arr[] * */ double qselect_median_dbl(double arr[], int n) { int low, high ; int median; int middle, ll, hh; low = 0 ; high = n-1 ; median = (low + high) / 2; for (;;) { if (high <= low) { /* One element only */ return arr[median] ; } if (high == low + 1) { /* Two elements only */ if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; return arr[median] ; } /* Find median of low, middle and high items; swap into position low */ middle = (low + high) / 2; if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]) ; if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]) ; /* Swap low item (now in position middle) into position (low+1) */ ELEM_SWAP(arr[middle], arr[low+1]) ; /* Nibble from each end towards middle, swapping items when stuck */ ll = low + 1; hh = high; for (;;) { do ll++; while (arr[low] > arr[ll]) ; do hh--; while (arr[hh] > arr[low]) ; if (hh < ll) break; ELEM_SWAP(arr[ll], arr[hh]) ; } /* Swap middle item (in position low) back into correct position */ ELEM_SWAP(arr[low], arr[hh]) ; /* Re-set active partition */ if (hh <= median) low = ll; if (hh >= median) high = hh - 1; } } #undef ELEM_SWAP /* * angsep_calc - compute angular separation between celestial coordinates * * This routine computes the angular separation between to coordinates * on the celestial sphere (i.e. RA and Dec). Note that all units are * in DEGREES, unlike the other trig functions in the calculator. * * double ra1, dec1 - RA and Dec of the first position in degrees * double ra2, dec2 - RA and Dec of the second position in degrees * * RETURNS: (double) angular separation in degrees * */ double angsep_calc(double ra1, double dec1, double ra2, double dec2) { /* double cd; */ static double deg = 0; double a, sdec, sra; if (deg == 0) deg = ((double)4)*atan((double)1)/((double)180); /* deg = 1.0; **** UNCOMMENT IF YOU WANT RADIANS */ /* The algorithm is the law of Haversines. This algorithm is stable even when the points are close together. The normal Law of Cosines fails for angles around 0.1 arcsec. */ sra = sin( (ra2 - ra1)*deg / 2 ); sdec = sin( (dec2 - dec1)*deg / 2); a = sdec*sdec + cos(dec1*deg)*cos(dec2*deg)*sra*sra; /* Sanity checking to avoid a range error in the sqrt()'s below */ if (a < 0) { a = 0; } if (a > 1) { a = 1; } return 2.0*atan2(sqrt(a), sqrt(1.0 - a)) / deg; } static void Do_Func( Node *this ) { Node *theParams[MAXSUBS]; int vector[MAXSUBS], allConst; lval pVals[MAXSUBS]; char pNull[MAXSUBS]; long ival; double dval; int i, valInit; long row, elem, nelem; i = this->nSubNodes; allConst = 1; while( i-- ) { theParams[i] = gParse.Nodes + this->SubNodes[i]; vector[i] = ( theParams[i]->operation!=CONST_OP ); if( vector[i] ) { allConst = 0; vector[i] = theParams[i]->value.nelem; } else { if( theParams[i]->type==DOUBLE ) { pVals[i].data.dbl = theParams[i]->value.data.dbl; } else if( theParams[i]->type==LONG ) { pVals[i].data.lng = theParams[i]->value.data.lng; } else if( theParams[i]->type==BOOLEAN ) { pVals[i].data.log = theParams[i]->value.data.log; } else strcpy(pVals[i].data.str, theParams[i]->value.data.str); pNull[i] = 0; } } if( this->nSubNodes==0 ) allConst = 0; /* These do produce scalars */ /* Random numbers are *never* constant !! */ if( this->operation == poirnd_fct ) allConst = 0; if( this->operation == gasrnd_fct ) allConst = 0; if( this->operation == rnd_fct ) allConst = 0; if( allConst ) { switch( this->operation ) { /* Non-Trig single-argument functions */ case sum_fct: if( theParams[0]->type==BOOLEAN ) this->value.data.lng = ( pVals[0].data.log ? 1 : 0 ); else if( theParams[0]->type==LONG ) this->value.data.lng = pVals[0].data.lng; else if( theParams[0]->type==DOUBLE ) this->value.data.dbl = pVals[0].data.dbl; else if( theParams[0]->type==BITSTR ) strcpy(this->value.data.str, pVals[0].data.str); break; case average_fct: if( theParams[0]->type==LONG ) this->value.data.dbl = pVals[0].data.lng; else if( theParams[0]->type==DOUBLE ) this->value.data.dbl = pVals[0].data.dbl; break; case stddev_fct: this->value.data.dbl = 0; /* Standard deviation of a constant = 0 */ break; case median_fct: if( theParams[0]->type==BOOLEAN ) this->value.data.lng = ( pVals[0].data.log ? 1 : 0 ); else if( theParams[0]->type==LONG ) this->value.data.lng = pVals[0].data.lng; else this->value.data.dbl = pVals[0].data.dbl; break; case poirnd_fct: if( theParams[0]->type==DOUBLE ) this->value.data.lng = simplerng_getpoisson(pVals[0].data.dbl); else this->value.data.lng = simplerng_getpoisson(pVals[0].data.lng); break; case abs_fct: if( theParams[0]->type==DOUBLE ) { dval = pVals[0].data.dbl; this->value.data.dbl = (dval>0.0 ? dval : -dval); } else { ival = pVals[0].data.lng; this->value.data.lng = (ival> 0 ? ival : -ival); } break; /* Special Null-Handling Functions */ case nonnull_fct: this->value.data.lng = 1; /* Constants are always 1-element and defined */ break; case isnull_fct: /* Constants are always defined */ this->value.data.log = 0; break; case defnull_fct: if( this->type==BOOLEAN ) this->value.data.log = pVals[0].data.log; else if( this->type==LONG ) this->value.data.lng = pVals[0].data.lng; else if( this->type==DOUBLE ) this->value.data.dbl = pVals[0].data.dbl; else if( this->type==STRING ) strcpy(this->value.data.str,pVals[0].data.str); break; case setnull_fct: /* Only defined for numeric expressions */ if( this->type==LONG ) this->value.data.lng = pVals[0].data.lng; else if( this->type==DOUBLE ) this->value.data.dbl = pVals[0].data.dbl; break; /* Math functions with 1 double argument */ case sin_fct: this->value.data.dbl = sin( pVals[0].data.dbl ); break; case cos_fct: this->value.data.dbl = cos( pVals[0].data.dbl ); break; case tan_fct: this->value.data.dbl = tan( pVals[0].data.dbl ); break; case asin_fct: dval = pVals[0].data.dbl; if( dval<-1.0 || dval>1.0 ) fferror("Out of range argument to arcsin"); else this->value.data.dbl = asin( dval ); break; case acos_fct: dval = pVals[0].data.dbl; if( dval<-1.0 || dval>1.0 ) fferror("Out of range argument to arccos"); else this->value.data.dbl = acos( dval ); break; case atan_fct: this->value.data.dbl = atan( pVals[0].data.dbl ); break; case sinh_fct: this->value.data.dbl = sinh( pVals[0].data.dbl ); break; case cosh_fct: this->value.data.dbl = cosh( pVals[0].data.dbl ); break; case tanh_fct: this->value.data.dbl = tanh( pVals[0].data.dbl ); break; case exp_fct: this->value.data.dbl = exp( pVals[0].data.dbl ); break; case log_fct: dval = pVals[0].data.dbl; if( dval<=0.0 ) fferror("Out of range argument to log"); else this->value.data.dbl = log( dval ); break; case log10_fct: dval = pVals[0].data.dbl; if( dval<=0.0 ) fferror("Out of range argument to log10"); else this->value.data.dbl = log10( dval ); break; case sqrt_fct: dval = pVals[0].data.dbl; if( dval<0.0 ) fferror("Out of range argument to sqrt"); else this->value.data.dbl = sqrt( dval ); break; case ceil_fct: this->value.data.dbl = ceil( pVals[0].data.dbl ); break; case floor_fct: this->value.data.dbl = floor( pVals[0].data.dbl ); break; case round_fct: this->value.data.dbl = floor( pVals[0].data.dbl + 0.5 ); break; /* Two-argument Trig Functions */ case atan2_fct: this->value.data.dbl = atan2( pVals[0].data.dbl, pVals[1].data.dbl ); break; /* Four-argument ANGSEP function */ case angsep_fct: this->value.data.dbl = angsep_calc(pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl); /* Min/Max functions taking 1 or 2 arguments */ case min1_fct: /* No constant vectors! */ if( this->type == DOUBLE ) this->value.data.dbl = pVals[0].data.dbl; else if( this->type == LONG ) this->value.data.lng = pVals[0].data.lng; else if( this->type == BITSTR ) strcpy(this->value.data.str, pVals[0].data.str); break; case min2_fct: if( this->type == DOUBLE ) this->value.data.dbl = minvalue( pVals[0].data.dbl, pVals[1].data.dbl ); else if( this->type == LONG ) this->value.data.lng = minvalue( pVals[0].data.lng, pVals[1].data.lng ); break; case max1_fct: /* No constant vectors! */ if( this->type == DOUBLE ) this->value.data.dbl = pVals[0].data.dbl; else if( this->type == LONG ) this->value.data.lng = pVals[0].data.lng; else if( this->type == BITSTR ) strcpy(this->value.data.str, pVals[0].data.str); break; case max2_fct: if( this->type == DOUBLE ) this->value.data.dbl = maxvalue( pVals[0].data.dbl, pVals[1].data.dbl ); else if( this->type == LONG ) this->value.data.lng = maxvalue( pVals[0].data.lng, pVals[1].data.lng ); break; /* Boolean SAO region Functions... scalar or vector dbls */ case near_fct: this->value.data.log = bnear( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl ); break; case circle_fct: this->value.data.log = circle( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl, pVals[4].data.dbl ); break; case box_fct: this->value.data.log = saobox( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl, pVals[4].data.dbl, pVals[5].data.dbl, pVals[6].data.dbl ); break; case elps_fct: this->value.data.log = ellipse( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl, pVals[4].data.dbl, pVals[5].data.dbl, pVals[6].data.dbl ); break; /* C Conditional expression: bool ? expr : expr */ case ifthenelse_fct: switch( this->type ) { case BOOLEAN: this->value.data.log = ( pVals[2].data.log ? pVals[0].data.log : pVals[1].data.log ); break; case LONG: this->value.data.lng = ( pVals[2].data.log ? pVals[0].data.lng : pVals[1].data.lng ); break; case DOUBLE: this->value.data.dbl = ( pVals[2].data.log ? pVals[0].data.dbl : pVals[1].data.dbl ); break; case STRING: strcpy(this->value.data.str, ( pVals[2].data.log ? pVals[0].data.str : pVals[1].data.str ) ); break; } break; /* String functions */ case strmid_fct: cstrmid(this->value.data.str, this->value.nelem, pVals[0].data.str, pVals[0].nelem, pVals[1].data.lng); break; case strpos_fct: { char *res = strstr(pVals[0].data.str, pVals[1].data.str); if (res == NULL) { this->value.data.lng = 0; } else { this->value.data.lng = (res - pVals[0].data.str) + 1; } break; } } this->operation = CONST_OP; } else { Allocate_Ptrs( this ); row = gParse.nRows; elem = row * this->value.nelem; if( !gParse.status ) { switch( this->operation ) { /* Special functions with no arguments */ case row_fct: while( row-- ) { this->value.data.lngptr[row] = gParse.firstRow + row; this->value.undef[row] = 0; } break; case null_fct: if( this->type==LONG ) { while( row-- ) { this->value.data.lngptr[row] = 0; this->value.undef[row] = 1; } } else if( this->type==STRING ) { while( row-- ) { this->value.data.strptr[row][0] = '\0'; this->value.undef[row] = 1; } } break; case rnd_fct: while( elem-- ) { this->value.data.dblptr[elem] = simplerng_getuniform(); this->value.undef[elem] = 0; } break; case gasrnd_fct: while( elem-- ) { this->value.data.dblptr[elem] = simplerng_getnorm(); this->value.undef[elem] = 0; } break; case poirnd_fct: if( theParams[0]->type==DOUBLE ) { if (theParams[0]->operation == CONST_OP) { while( elem-- ) { this->value.undef[elem] = (pVals[0].data.dbl < 0); if (! this->value.undef[elem]) { this->value.data.lngptr[elem] = simplerng_getpoisson(pVals[0].data.dbl); } } } else { while( elem-- ) { this->value.undef[elem] = theParams[0]->value.undef[elem]; if (theParams[0]->value.data.dblptr[elem] < 0) this->value.undef[elem] = 1; if (! this->value.undef[elem]) { this->value.data.lngptr[elem] = simplerng_getpoisson(theParams[0]->value.data.dblptr[elem]); } } /* while */ } /* ! CONST_OP */ } else { /* LONG */ if (theParams[0]->operation == CONST_OP) { while( elem-- ) { this->value.undef[elem] = (pVals[0].data.lng < 0); if (! this->value.undef[elem]) { this->value.data.lngptr[elem] = simplerng_getpoisson(pVals[0].data.lng); } } } else { while( elem-- ) { this->value.undef[elem] = theParams[0]->value.undef[elem]; if (theParams[0]->value.data.lngptr[elem] < 0) this->value.undef[elem] = 1; if (! this->value.undef[elem]) { this->value.data.lngptr[elem] = simplerng_getpoisson(theParams[0]->value.data.lngptr[elem]); } } /* while */ } /* ! CONST_OP */ } /* END LONG */ break; /* Non-Trig single-argument functions */ case sum_fct: elem = row * theParams[0]->value.nelem; if( theParams[0]->type==BOOLEAN ) { while( row-- ) { this->value.data.lngptr[row] = 0; /* Default is UNDEF until a defined value is found */ this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( ! theParams[0]->value.undef[elem] ) { this->value.data.lngptr[row] += ( theParams[0]->value.data.logptr[elem] ? 1 : 0 ); this->value.undef[row] = 0; } } } } else if( theParams[0]->type==LONG ) { while( row-- ) { this->value.data.lngptr[row] = 0; /* Default is UNDEF until a defined value is found */ this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( ! theParams[0]->value.undef[elem] ) { this->value.data.lngptr[row] += theParams[0]->value.data.lngptr[elem]; this->value.undef[row] = 0; } } } } else if( theParams[0]->type==DOUBLE ){ while( row-- ) { this->value.data.dblptr[row] = 0.0; /* Default is UNDEF until a defined value is found */ this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( ! theParams[0]->value.undef[elem] ) { this->value.data.dblptr[row] += theParams[0]->value.data.dblptr[elem]; this->value.undef[row] = 0; } } } } else { /* BITSTR */ nelem = theParams[0]->value.nelem; while( row-- ) { char *sptr1 = theParams[0]->value.data.strptr[row]; this->value.data.lngptr[row] = 0; this->value.undef[row] = 0; while (*sptr1) { if (*sptr1 == '1') this->value.data.lngptr[row] ++; sptr1++; } } } break; case average_fct: elem = row * theParams[0]->value.nelem; if( theParams[0]->type==LONG ) { while( row-- ) { int count = 0; this->value.data.dblptr[row] = 0; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if (theParams[0]->value.undef[elem] == 0) { this->value.data.dblptr[row] += theParams[0]->value.data.lngptr[elem]; count ++; } } if (count == 0) { this->value.undef[row] = 1; } else { this->value.undef[row] = 0; this->value.data.dblptr[row] /= count; } } } else if( theParams[0]->type==DOUBLE ){ while( row-- ) { int count = 0; this->value.data.dblptr[row] = 0; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if (theParams[0]->value.undef[elem] == 0) { this->value.data.dblptr[row] += theParams[0]->value.data.dblptr[elem]; count ++; } } if (count == 0) { this->value.undef[row] = 1; } else { this->value.undef[row] = 0; this->value.data.dblptr[row] /= count; } } } break; case stddev_fct: elem = row * theParams[0]->value.nelem; if( theParams[0]->type==LONG ) { /* Compute the mean value */ while( row-- ) { int count = 0; double sum = 0, sum2 = 0; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if (theParams[0]->value.undef[elem] == 0) { sum += theParams[0]->value.data.lngptr[elem]; count ++; } } if (count > 1) { sum /= count; /* Compute the sum of squared deviations */ nelem = theParams[0]->value.nelem; elem += nelem; /* Reset elem for second pass */ while( nelem-- ) { elem--; if (theParams[0]->value.undef[elem] == 0) { double dx = (theParams[0]->value.data.lngptr[elem] - sum); sum2 += (dx*dx); } } sum2 /= (double)count-1; this->value.undef[row] = 0; this->value.data.dblptr[row] = sqrt(sum2); } else { this->value.undef[row] = 0; /* STDDEV => 0 */ this->value.data.dblptr[row] = 0; } } } else if( theParams[0]->type==DOUBLE ){ /* Compute the mean value */ while( row-- ) { int count = 0; double sum = 0, sum2 = 0; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if (theParams[0]->value.undef[elem] == 0) { sum += theParams[0]->value.data.dblptr[elem]; count ++; } } if (count > 1) { sum /= count; /* Compute the sum of squared deviations */ nelem = theParams[0]->value.nelem; elem += nelem; /* Reset elem for second pass */ while( nelem-- ) { elem--; if (theParams[0]->value.undef[elem] == 0) { double dx = (theParams[0]->value.data.dblptr[elem] - sum); sum2 += (dx*dx); } } sum2 /= (double)count-1; this->value.undef[row] = 0; this->value.data.dblptr[row] = sqrt(sum2); } else { this->value.undef[row] = 0; /* STDDEV => 0 */ this->value.data.dblptr[row] = 0; } } } break; case median_fct: elem = row * theParams[0]->value.nelem; nelem = theParams[0]->value.nelem; if( theParams[0]->type==LONG ) { long *dptr = theParams[0]->value.data.lngptr; char *uptr = theParams[0]->value.undef; long *mptr = (long *) malloc(sizeof(long)*nelem); int irow; /* Allocate temporary storage for this row, since the quickselect function will scramble the contents */ if (mptr == 0) { fferror("Could not allocate temporary memory in median function"); free( this->value.data.ptr ); break; } for (irow=0; irow 0) { this->value.undef[irow] = 0; this->value.data.lngptr[irow] = qselect_median_lng(mptr, nelem1); } else { this->value.undef[irow] = 1; this->value.data.lngptr[irow] = 0; } } free(mptr); } else { double *dptr = theParams[0]->value.data.dblptr; char *uptr = theParams[0]->value.undef; double *mptr = (double *) malloc(sizeof(double)*nelem); int irow; /* Allocate temporary storage for this row, since the quickselect function will scramble the contents */ if (mptr == 0) { fferror("Could not allocate temporary memory in median function"); free( this->value.data.ptr ); break; } for (irow=0; irow 0) { this->value.undef[irow] = 0; this->value.data.dblptr[irow] = qselect_median_dbl(mptr, nelem1); } else { this->value.undef[irow] = 1; this->value.data.dblptr[irow] = 0; } } free(mptr); } break; case abs_fct: if( theParams[0]->type==DOUBLE ) while( elem-- ) { dval = theParams[0]->value.data.dblptr[elem]; this->value.data.dblptr[elem] = (dval>0.0 ? dval : -dval); this->value.undef[elem] = theParams[0]->value.undef[elem]; } else while( elem-- ) { ival = theParams[0]->value.data.lngptr[elem]; this->value.data.lngptr[elem] = (ival> 0 ? ival : -ival); this->value.undef[elem] = theParams[0]->value.undef[elem]; } break; /* Special Null-Handling Functions */ case nonnull_fct: nelem = theParams[0]->value.nelem; if ( theParams[0]->type==STRING ) nelem = 1; elem = row * nelem; while( row-- ) { int nelem1 = nelem; this->value.undef[row] = 0; /* Initialize to 0 (defined) */ this->value.data.lngptr[row] = 0; while( nelem1-- ) { elem --; if ( theParams[0]->value.undef[elem] == 0 ) this->value.data.lngptr[row] ++; } } break; case isnull_fct: if( theParams[0]->type==STRING ) elem = row; while( elem-- ) { this->value.data.logptr[elem] = theParams[0]->value.undef[elem]; this->value.undef[elem] = 0; } break; case defnull_fct: switch( this->type ) { case BOOLEAN: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pNull[i] = theParams[i]->value.undef[elem]; pVals[i].data.log = theParams[i]->value.data.logptr[elem]; } else if( vector[i] ) { pNull[i] = theParams[i]->value.undef[row]; pVals[i].data.log = theParams[i]->value.data.logptr[row]; } if( pNull[0] ) { this->value.undef[elem] = pNull[1]; this->value.data.logptr[elem] = pVals[1].data.log; } else { this->value.undef[elem] = 0; this->value.data.logptr[elem] = pVals[0].data.log; } } } break; case LONG: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pNull[i] = theParams[i]->value.undef[elem]; pVals[i].data.lng = theParams[i]->value.data.lngptr[elem]; } else if( vector[i] ) { pNull[i] = theParams[i]->value.undef[row]; pVals[i].data.lng = theParams[i]->value.data.lngptr[row]; } if( pNull[0] ) { this->value.undef[elem] = pNull[1]; this->value.data.lngptr[elem] = pVals[1].data.lng; } else { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = pVals[0].data.lng; } } } break; case DOUBLE: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pNull[i] = theParams[i]->value.undef[elem]; pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; } else if( vector[i] ) { pNull[i] = theParams[i]->value.undef[row]; pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; } if( pNull[0] ) { this->value.undef[elem] = pNull[1]; this->value.data.dblptr[elem] = pVals[1].data.dbl; } else { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = pVals[0].data.dbl; } } } break; case STRING: while( row-- ) { i=2; while( i-- ) if( vector[i] ) { pNull[i] = theParams[i]->value.undef[row]; strcpy(pVals[i].data.str, theParams[i]->value.data.strptr[row]); } if( pNull[0] ) { this->value.undef[row] = pNull[1]; strcpy(this->value.data.strptr[row],pVals[1].data.str); } else { this->value.undef[elem] = 0; strcpy(this->value.data.strptr[row],pVals[0].data.str); } } } break; case setnull_fct: switch( this->type ) { case LONG: while( elem-- ) { if ( theParams[1]->value.data.lng == theParams[0]->value.data.lngptr[elem] ) { this->value.data.lngptr[elem] = 0; this->value.undef[elem] = 1; } else { this->value.data.lngptr[elem] = theParams[0]->value.data.lngptr[elem]; this->value.undef[elem] = theParams[0]->value.undef[elem]; } } break; case DOUBLE: while( elem-- ) { if ( theParams[1]->value.data.dbl == theParams[0]->value.data.dblptr[elem] ) { this->value.data.dblptr[elem] = 0; this->value.undef[elem] = 1; } else { this->value.data.dblptr[elem] = theParams[0]->value.data.dblptr[elem]; this->value.undef[elem] = theParams[0]->value.undef[elem]; } } break; } break; /* Math functions with 1 double argument */ case sin_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = sin( theParams[0]->value.data.dblptr[elem] ); } break; case cos_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = cos( theParams[0]->value.data.dblptr[elem] ); } break; case tan_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = tan( theParams[0]->value.data.dblptr[elem] ); } break; case asin_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; if( dval<-1.0 || dval>1.0 ) { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } else this->value.data.dblptr[elem] = asin( dval ); } break; case acos_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; if( dval<-1.0 || dval>1.0 ) { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } else this->value.data.dblptr[elem] = acos( dval ); } break; case atan_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; this->value.data.dblptr[elem] = atan( dval ); } break; case sinh_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = sinh( theParams[0]->value.data.dblptr[elem] ); } break; case cosh_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = cosh( theParams[0]->value.data.dblptr[elem] ); } break; case tanh_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = tanh( theParams[0]->value.data.dblptr[elem] ); } break; case exp_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; this->value.data.dblptr[elem] = exp( dval ); } break; case log_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; if( dval<=0.0 ) { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } else this->value.data.dblptr[elem] = log( dval ); } break; case log10_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; if( dval<=0.0 ) { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } else this->value.data.dblptr[elem] = log10( dval ); } break; case sqrt_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; if( dval<0.0 ) { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } else this->value.data.dblptr[elem] = sqrt( dval ); } break; case ceil_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = ceil( theParams[0]->value.data.dblptr[elem] ); } break; case floor_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = floor( theParams[0]->value.data.dblptr[elem] ); } break; case round_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = floor( theParams[0]->value.data.dblptr[elem] + 0.5); } break; /* Two-argument Trig Functions */ case atan2_fct: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = (pNull[0] || pNull[1]) ) ) this->value.data.dblptr[elem] = atan2( pVals[0].data.dbl, pVals[1].data.dbl ); } } break; /* Four-argument ANGSEP Function */ case angsep_fct: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=4; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = (pNull[0] || pNull[1] || pNull[2] || pNull[3]) ) ) this->value.data.dblptr[elem] = angsep_calc(pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl); } } break; /* Min/Max functions taking 1 or 2 arguments */ case min1_fct: elem = row * theParams[0]->value.nelem; if( this->type==LONG ) { long minVal=0; while( row-- ) { valInit = 1; this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( !theParams[0]->value.undef[elem] ) { if ( valInit ) { valInit = 0; minVal = theParams[0]->value.data.lngptr[elem]; } else { minVal = minvalue( minVal, theParams[0]->value.data.lngptr[elem] ); } this->value.undef[row] = 0; } } this->value.data.lngptr[row] = minVal; } } else if( this->type==DOUBLE ) { double minVal=0.0; while( row-- ) { valInit = 1; this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( !theParams[0]->value.undef[elem] ) { if ( valInit ) { valInit = 0; minVal = theParams[0]->value.data.dblptr[elem]; } else { minVal = minvalue( minVal, theParams[0]->value.data.dblptr[elem] ); } this->value.undef[row] = 0; } } this->value.data.dblptr[row] = minVal; } } else if( this->type==BITSTR ) { char minVal; while( row-- ) { char *sptr1 = theParams[0]->value.data.strptr[row]; minVal = '1'; while (*sptr1) { if (*sptr1 == '0') minVal = '0'; sptr1++; } this->value.data.strptr[row][0] = minVal; this->value.data.strptr[row][1] = 0; /* Null terminate */ } } break; case min2_fct: if( this->type==LONG ) { while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.lng = theParams[i]->value.data.lngptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.lng = theParams[i]->value.data.lngptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( pNull[0] && pNull[1] ) { this->value.undef[elem] = 1; this->value.data.lngptr[elem] = 0; } else if (pNull[0]) { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = pVals[1].data.lng; } else if (pNull[1]) { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = pVals[0].data.lng; } else { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = minvalue( pVals[0].data.lng, pVals[1].data.lng ); } } } } else if( this->type==DOUBLE ) { while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( pNull[0] && pNull[1] ) { this->value.undef[elem] = 1; this->value.data.dblptr[elem] = 0; } else if (pNull[0]) { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = pVals[1].data.dbl; } else if (pNull[1]) { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = pVals[0].data.dbl; } else { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = minvalue( pVals[0].data.dbl, pVals[1].data.dbl ); } } } } break; case max1_fct: elem = row * theParams[0]->value.nelem; if( this->type==LONG ) { long maxVal=0; while( row-- ) { valInit = 1; this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( !theParams[0]->value.undef[elem] ) { if ( valInit ) { valInit = 0; maxVal = theParams[0]->value.data.lngptr[elem]; } else { maxVal = maxvalue( maxVal, theParams[0]->value.data.lngptr[elem] ); } this->value.undef[row] = 0; } } this->value.data.lngptr[row] = maxVal; } } else if( this->type==DOUBLE ) { double maxVal=0.0; while( row-- ) { valInit = 1; this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( !theParams[0]->value.undef[elem] ) { if ( valInit ) { valInit = 0; maxVal = theParams[0]->value.data.dblptr[elem]; } else { maxVal = maxvalue( maxVal, theParams[0]->value.data.dblptr[elem] ); } this->value.undef[row] = 0; } } this->value.data.dblptr[row] = maxVal; } } else if( this->type==BITSTR ) { char maxVal; while( row-- ) { char *sptr1 = theParams[0]->value.data.strptr[row]; maxVal = '0'; while (*sptr1) { if (*sptr1 == '1') maxVal = '1'; sptr1++; } this->value.data.strptr[row][0] = maxVal; this->value.data.strptr[row][1] = 0; /* Null terminate */ } } break; case max2_fct: if( this->type==LONG ) { while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.lng = theParams[i]->value.data.lngptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.lng = theParams[i]->value.data.lngptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( pNull[0] && pNull[1] ) { this->value.undef[elem] = 1; this->value.data.lngptr[elem] = 0; } else if (pNull[0]) { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = pVals[1].data.lng; } else if (pNull[1]) { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = pVals[0].data.lng; } else { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = maxvalue( pVals[0].data.lng, pVals[1].data.lng ); } } } } else if( this->type==DOUBLE ) { while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( pNull[0] && pNull[1] ) { this->value.undef[elem] = 1; this->value.data.dblptr[elem] = 0; } else if (pNull[0]) { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = pVals[1].data.dbl; } else if (pNull[1]) { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = pVals[0].data.dbl; } else { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = maxvalue( pVals[0].data.dbl, pVals[1].data.dbl ); } } } } break; /* Boolean SAO region Functions... scalar or vector dbls */ case near_fct: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=3; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = (pNull[0] || pNull[1] || pNull[2]) ) ) this->value.data.logptr[elem] = bnear( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl ); } } break; case circle_fct: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=5; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = (pNull[0] || pNull[1] || pNull[2] || pNull[3] || pNull[4]) ) ) this->value.data.logptr[elem] = circle( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl, pVals[4].data.dbl ); } } break; case box_fct: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=7; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = (pNull[0] || pNull[1] || pNull[2] || pNull[3] || pNull[4] || pNull[5] || pNull[6] ) ) ) this->value.data.logptr[elem] = saobox( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl, pVals[4].data.dbl, pVals[5].data.dbl, pVals[6].data.dbl ); } } break; case elps_fct: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=7; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = (pNull[0] || pNull[1] || pNull[2] || pNull[3] || pNull[4] || pNull[5] || pNull[6] ) ) ) this->value.data.logptr[elem] = ellipse( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl, pVals[4].data.dbl, pVals[5].data.dbl, pVals[6].data.dbl ); } } break; /* C Conditional expression: bool ? expr : expr */ case ifthenelse_fct: switch( this->type ) { case BOOLEAN: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; if( vector[2]>1 ) { pVals[2].data.log = theParams[2]->value.data.logptr[elem]; pNull[2] = theParams[2]->value.undef[elem]; } else if( vector[2] ) { pVals[2].data.log = theParams[2]->value.data.logptr[row]; pNull[2] = theParams[2]->value.undef[row]; } i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.log = theParams[i]->value.data.logptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.log = theParams[i]->value.data.logptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = pNull[2]) ) { if( pVals[2].data.log ) { this->value.data.logptr[elem] = pVals[0].data.log; this->value.undef[elem] = pNull[0]; } else { this->value.data.logptr[elem] = pVals[1].data.log; this->value.undef[elem] = pNull[1]; } } } } break; case LONG: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; if( vector[2]>1 ) { pVals[2].data.log = theParams[2]->value.data.logptr[elem]; pNull[2] = theParams[2]->value.undef[elem]; } else if( vector[2] ) { pVals[2].data.log = theParams[2]->value.data.logptr[row]; pNull[2] = theParams[2]->value.undef[row]; } i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.lng = theParams[i]->value.data.lngptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.lng = theParams[i]->value.data.lngptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = pNull[2]) ) { if( pVals[2].data.log ) { this->value.data.lngptr[elem] = pVals[0].data.lng; this->value.undef[elem] = pNull[0]; } else { this->value.data.lngptr[elem] = pVals[1].data.lng; this->value.undef[elem] = pNull[1]; } } } } break; case DOUBLE: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; if( vector[2]>1 ) { pVals[2].data.log = theParams[2]->value.data.logptr[elem]; pNull[2] = theParams[2]->value.undef[elem]; } else if( vector[2] ) { pVals[2].data.log = theParams[2]->value.data.logptr[row]; pNull[2] = theParams[2]->value.undef[row]; } i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = pNull[2]) ) { if( pVals[2].data.log ) { this->value.data.dblptr[elem] = pVals[0].data.dbl; this->value.undef[elem] = pNull[0]; } else { this->value.data.dblptr[elem] = pVals[1].data.dbl; this->value.undef[elem] = pNull[1]; } } } } break; case STRING: while( row-- ) { if( vector[2] ) { pVals[2].data.log = theParams[2]->value.data.logptr[row]; pNull[2] = theParams[2]->value.undef[row]; } i=2; while( i-- ) if( vector[i] ) { strcpy( pVals[i].data.str, theParams[i]->value.data.strptr[row] ); pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[row] = pNull[2]) ) { if( pVals[2].data.log ) { strcpy( this->value.data.strptr[row], pVals[0].data.str ); this->value.undef[row] = pNull[0]; } else { strcpy( this->value.data.strptr[row], pVals[1].data.str ); this->value.undef[row] = pNull[1]; } } else { this->value.data.strptr[row][0] = '\0'; } } break; } break; /* String functions */ case strmid_fct: { int strconst = theParams[0]->operation == CONST_OP; int posconst = theParams[1]->operation == CONST_OP; int lenconst = theParams[2]->operation == CONST_OP; int dest_len = this->value.nelem; int src_len = theParams[0]->value.nelem; while (row--) { int pos; int len; char *str; int undef = 0; if (posconst) { pos = theParams[1]->value.data.lng; } else { pos = theParams[1]->value.data.lngptr[row]; if (theParams[1]->value.undef[row]) undef = 1; } if (strconst) { str = theParams[0]->value.data.str; if (src_len == 0) src_len = strlen(str); } else { str = theParams[0]->value.data.strptr[row]; if (theParams[0]->value.undef[row]) undef = 1; } if (lenconst) { len = dest_len; } else { len = theParams[2]->value.data.lngptr[row]; if (theParams[2]->value.undef[row]) undef = 1; } this->value.data.strptr[row][0] = '\0'; if (pos == 0) undef = 1; if (! undef ) { if (cstrmid(this->value.data.strptr[row], len, str, src_len, pos) < 0) break; } this->value.undef[row] = undef; } } break; /* String functions */ case strpos_fct: { int const1 = theParams[0]->operation == CONST_OP; int const2 = theParams[1]->operation == CONST_OP; while (row--) { char *str1, *str2; int undef = 0; if (const1) { str1 = theParams[0]->value.data.str; } else { str1 = theParams[0]->value.data.strptr[row]; if (theParams[0]->value.undef[row]) undef = 1; } if (const2) { str2 = theParams[1]->value.data.str; } else { str2 = theParams[1]->value.data.strptr[row]; if (theParams[1]->value.undef[row]) undef = 1; } this->value.data.lngptr[row] = 0; if (! undef ) { char *res = strstr(str1, str2); if (res == NULL) { undef = 1; this->value.data.lngptr[row] = 0; } else { this->value.data.lngptr[row] = (res - str1) + 1; } } this->value.undef[row] = undef; } } break; } /* End switch(this->operation) */ } /* End if (!gParse.status) */ } /* End non-constant operations */ i = this->nSubNodes; while( i-- ) { if( theParams[i]->operation>0 ) { /* Currently only numeric params allowed */ free( theParams[i]->value.data.ptr ); } } } static void Do_Deref( Node *this ) { Node *theVar, *theDims[MAXDIMS]; int isConst[MAXDIMS], allConst; long dimVals[MAXDIMS]; int i, nDims; long row, elem, dsize; theVar = gParse.Nodes + this->SubNodes[0]; i = nDims = this->nSubNodes-1; allConst = 1; while( i-- ) { theDims[i] = gParse.Nodes + this->SubNodes[i+1]; isConst[i] = ( theDims[i]->operation==CONST_OP ); if( isConst[i] ) dimVals[i] = theDims[i]->value.data.lng; else allConst = 0; } if( this->type==DOUBLE ) { dsize = sizeof( double ); } else if( this->type==LONG ) { dsize = sizeof( long ); } else if( this->type==BOOLEAN ) { dsize = sizeof( char ); } else dsize = 0; Allocate_Ptrs( this ); if( !gParse.status ) { if( allConst && theVar->value.naxis==nDims ) { /* Dereference completely using constant indices */ elem = 0; i = nDims; while( i-- ) { if( dimVals[i]<1 || dimVals[i]>theVar->value.naxes[i] ) break; elem = theVar->value.naxes[i]*elem + dimVals[i]-1; } if( i<0 ) { for( row=0; rowtype==STRING ) this->value.undef[row] = theVar->value.undef[row]; else if( this->type==BITSTR ) this->value.undef; /* Dummy - BITSTRs do not have undefs */ else this->value.undef[row] = theVar->value.undef[elem]; if( this->type==DOUBLE ) this->value.data.dblptr[row] = theVar->value.data.dblptr[elem]; else if( this->type==LONG ) this->value.data.lngptr[row] = theVar->value.data.lngptr[elem]; else if( this->type==BOOLEAN ) this->value.data.logptr[row] = theVar->value.data.logptr[elem]; else { /* XXX Note, the below expression uses knowledge of the layout of the string format, namely (nelem+1) characters per string, followed by (nelem+1) "undef" values. */ this->value.data.strptr[row][0] = theVar->value.data.strptr[0][elem+row]; this->value.data.strptr[row][1] = 0; /* Null terminate */ } elem += theVar->value.nelem; } } else { fferror("Index out of range"); free( this->value.data.ptr ); } } else if( allConst && nDims==1 ) { /* Reduce dimensions by 1, using a constant index */ if( dimVals[0] < 1 || dimVals[0] > theVar->value.naxes[ theVar->value.naxis-1 ] ) { fferror("Index out of range"); free( this->value.data.ptr ); } else if ( this->type == BITSTR || this->type == STRING ) { elem = this->value.nelem * (dimVals[0]-1); for( row=0; rowvalue.undef) this->value.undef[row] = theVar->value.undef[row]; memcpy( (char*)this->value.data.strptr[0] + row*sizeof(char)*(this->value.nelem+1), (char*)theVar->value.data.strptr[0] + elem*sizeof(char), this->value.nelem * sizeof(char) ); /* Null terminate */ this->value.data.strptr[row][this->value.nelem] = 0; elem += theVar->value.nelem+1; } } else { elem = this->value.nelem * (dimVals[0]-1); for( row=0; rowvalue.undef + row*this->value.nelem, theVar->value.undef + elem, this->value.nelem * sizeof(char) ); memcpy( (char*)this->value.data.ptr + row*dsize*this->value.nelem, (char*)theVar->value.data.ptr + elem*dsize, this->value.nelem * dsize ); elem += theVar->value.nelem; } } } else if( theVar->value.naxis==nDims ) { /* Dereference completely using an expression for the indices */ for( row=0; rowvalue.undef[row] ) { fferror("Null encountered as vector index"); free( this->value.data.ptr ); break; } else dimVals[i] = theDims[i]->value.data.lngptr[row]; } } if( gParse.status ) break; elem = 0; i = nDims; while( i-- ) { if( dimVals[i]<1 || dimVals[i]>theVar->value.naxes[i] ) break; elem = theVar->value.naxes[i]*elem + dimVals[i]-1; } if( i<0 ) { elem += row*theVar->value.nelem; if( this->type==STRING ) this->value.undef[row] = theVar->value.undef[row]; else if( this->type==BITSTR ) this->value.undef; /* Dummy - BITSTRs do not have undefs */ else this->value.undef[row] = theVar->value.undef[elem]; if( this->type==DOUBLE ) this->value.data.dblptr[row] = theVar->value.data.dblptr[elem]; else if( this->type==LONG ) this->value.data.lngptr[row] = theVar->value.data.lngptr[elem]; else if( this->type==BOOLEAN ) this->value.data.logptr[row] = theVar->value.data.logptr[elem]; else { /* XXX Note, the below expression uses knowledge of the layout of the string format, namely (nelem+1) characters per string, followed by (nelem+1) "undef" values. */ this->value.data.strptr[row][0] = theVar->value.data.strptr[0][elem+row]; this->value.data.strptr[row][1] = 0; /* Null terminate */ } } else { fferror("Index out of range"); free( this->value.data.ptr ); } } } else { /* Reduce dimensions by 1, using a nonconstant expression */ for( row=0; rowvalue.undef[row] ) { fferror("Null encountered as vector index"); free( this->value.data.ptr ); break; } else dimVals[0] = theDims[0]->value.data.lngptr[row]; if( dimVals[0] < 1 || dimVals[0] > theVar->value.naxes[ theVar->value.naxis-1 ] ) { fferror("Index out of range"); free( this->value.data.ptr ); } else if ( this->type == BITSTR || this->type == STRING ) { elem = this->value.nelem * (dimVals[0]-1); elem += row*(theVar->value.nelem+1); if (this->value.undef) this->value.undef[row] = theVar->value.undef[row]; memcpy( (char*)this->value.data.strptr[0] + row*sizeof(char)*(this->value.nelem+1), (char*)theVar->value.data.strptr[0] + elem*sizeof(char), this->value.nelem * sizeof(char) ); /* Null terminate */ this->value.data.strptr[row][this->value.nelem] = 0; } else { elem = this->value.nelem * (dimVals[0]-1); elem += row*theVar->value.nelem; memcpy( this->value.undef + row*this->value.nelem, theVar->value.undef + elem, this->value.nelem * sizeof(char) ); memcpy( (char*)this->value.data.ptr + row*dsize*this->value.nelem, (char*)theVar->value.data.ptr + elem*dsize, this->value.nelem * dsize ); } } } } if( theVar->operation>0 ) { if (theVar->type == STRING || theVar->type == BITSTR) free(theVar->value.data.strptr[0] ); else free( theVar->value.data.ptr ); } for( i=0; ioperation>0 ) { free( theDims[i]->value.data.ptr ); } } static void Do_GTI( Node *this ) { Node *theExpr, *theTimes; double *start, *stop, *times; long elem, nGTI, gti; int ordered; theTimes = gParse.Nodes + this->SubNodes[0]; theExpr = gParse.Nodes + this->SubNodes[1]; nGTI = theTimes->value.nelem; start = theTimes->value.data.dblptr; stop = theTimes->value.data.dblptr + nGTI; ordered = theTimes->type; if( theExpr->operation==CONST_OP ) { this->value.data.log = (Search_GTI( theExpr->value.data.dbl, nGTI, start, stop, ordered, 0 )>=0); this->operation = CONST_OP; } else { Allocate_Ptrs( this ); times = theExpr->value.data.dblptr; if( !gParse.status ) { elem = gParse.nRows * this->value.nelem; if( nGTI ) { gti = -1; while( elem-- ) { if( (this->value.undef[elem] = theExpr->value.undef[elem]) ) continue; /* Before searching entire GTI, check the GTI found last time */ if( gti<0 || times[elem]stop[gti] ) { gti = Search_GTI( times[elem], nGTI, start, stop, ordered, 0 ); } this->value.data.logptr[elem] = ( gti>=0 ); } } else while( elem-- ) { this->value.data.logptr[elem] = 0; this->value.undef[elem] = 0; } } } if( theExpr->operation>0 ) free( theExpr->value.data.ptr ); } static void Do_GTI_Over( Node *this ) { Node *theTimes, *theStart, *theStop; double *gtiStart, *gtiStop; double *evtStart, *evtStop; long elem, nGTI, gti, nextGTI; int ordered; theTimes = gParse.Nodes + this->SubNodes[0]; /* GTI times */ theStop = gParse.Nodes + this->SubNodes[2]; /* User start time */ theStart = gParse.Nodes + this->SubNodes[1]; /* User stop time */ nGTI = theTimes->value.nelem; gtiStart = theTimes->value.data.dblptr; /* GTI start */ gtiStop = theTimes->value.data.dblptr + nGTI; /* GTI stop */ if( theStart->operation==CONST_OP && theStop->operation==CONST_OP) { this->value.data.dbl = (GTI_Over( theStart->value.data.dbl, theStop->value.data.dbl, nGTI, gtiStart, gtiStop, >i)); this->operation = CONST_OP; } else { char undefStart = 0, undefStop = 0; /* Input values are undef? */ double uStart, uStop; /* User start/stop values */ if (theStart->operation==CONST_OP) uStart = theStart->value.data.dbl; if (theStop ->operation==CONST_OP) uStop = theStop ->value.data.dbl; Allocate_Ptrs( this ); evtStart = theStart->value.data.dblptr; evtStop = theStop ->value.data.dblptr; if( !gParse.status ) { elem = gParse.nRows * this->value.nelem; if( nGTI ) { double toverlap = 0.0; gti = -1; while( elem-- ) { if (theStart->operation!=CONST_OP) { undefStart = theStart->value.undef[elem]; uStart = evtStart[elem]; } if (theStop->operation!=CONST_OP) { undefStop = theStop ->value.undef[elem]; uStop = evtStop[elem]; } /* This works because at least one of the values is not const */ if( (this->value.undef[elem] = (undefStart||undefStop)) ) continue; /* Before searching entire GTI, check the GTI found last time */ if( gti<0 || uStartgtiStop[gti] || uStop gtiStop[gti]) { /* Nope, need to recalculate */ toverlap = GTI_Over(uStart, uStop, nGTI, gtiStart, gtiStop, >i); } else { /* We are in same GTI, the overlap is just stop-start of user range */ toverlap = (uStop-uStart); } /* This works because at least one of the values is not const */ this->value.data.dblptr[elem] = toverlap; } } else /* nGTI == 0; there is no overlap so set all values to 0.0 */ while( elem-- ) { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 0; } } } if( theStart->operation>0 ) { free( theStart->value.data.ptr ); } if( theStop->operation>0 ) { free( theStop->value.data.ptr ); } } static double GTI_Over(double evtStart, double evtStop, long nGTI, double *start, double *stop, long *gtiout) { long gti1, gti2, nextGTI1, nextGTI2; long gti, nMax; double overlap = 0.0; *gtiout = -1L; /* Zero or negative bin size */ if (evtStop <= evtStart) return 0.0; /* Locate adjacent GTIs for evtStart and evtStop */ gti1 = Search_GTI(evtStart, nGTI, start, stop, 1, &nextGTI1); gti2 = Search_GTI(evtStop, nGTI, start, stop, 1, &nextGTI2); /* evtStart is in gti1, we return that for future processing */ if (gti1 >= 0) *gtiout = gti1; /* Both evtStart/evtStop are beyond the last GTI */ if (nextGTI1 < 0 && nextGTI2 < 0) return 0.0; /* Both evtStart/evtStop are in the same gap between GTIs */ if (gti1 < 0 && gti2 < 0 && nextGTI1 == nextGTI2) return 0.0; /* Both evtStart/evtStop are in the same GTI */ if (gti1 >= 0 && gti1 == gti2) return (evtStop-evtStart); /* Count through the remaining GTIs; there will be at least one */ /* The largest GTI to consider is either nextGTI2-1, if it exists, or nGTI-1 */ if (nextGTI2 < 0) nMax = nGTI-1; else if (gti2 >= 0) nMax = nextGTI2; else nMax = nextGTI2-1; for (gti = nextGTI1; gti <= nMax; gti++) { double starti = start[gti], stopi = stop[gti]; /* Trim the GTI by actual evtStart/Stop times */ if (evtStart > starti) starti = evtStart; if (evtStop < stopi ) stopi = evtStop; overlap += (stopi - starti); } return overlap; } /* * Search_GTI - search GTI for requested evtTime * * double evtTime - requested event time * long nGTI - number of entries in start[] and stop[] * double start[], stop[] - start and stop of each GTI * int ordered - set to 1 if time-ordered * long *nextGTI0 - upon return, *nextGTI0 is either * the GTI evtTime is inside * the next GTI if evtTime is not inside * -1L if there is no next GTI * not set if nextGTI0 is a null pointer * * NOTE: for *nextGTI to be well-defined, the GTI must * be ordered. This is true when called by Do_GTI. * * RETURNS: gti index that evtTime is located inside, or -1L */ static long Search_GTI( double evtTime, long nGTI, double *start, double *stop, int ordered, long *nextGTI0 ) { long gti, nextGTI = -1L, step; if( ordered && nGTI>15 ) { /* If time-ordered and lots of GTIs, */ /* use "FAST" Binary search algorithm */ if( evtTime>=start[0] && evtTime<=stop[nGTI-1] ) { gti = step = (nGTI >> 1); while(1) { if( step>1L ) step >>= 1; if( evtTime>stop[gti] ) { if( evtTime>=start[gti+1] ) gti += step; else { nextGTI = gti+1; gti = -1L; break; } } else if( evtTime evtTime) nextGTI = 0; gti = -1L; } } else { /* Use "SLOW" linear search. Not required to be ordered, so we have to search the whole table no matter what. */ gti = nGTI; while( gti-- ) { if( stop[gti] >= evtTime ) nextGTI = gti; if( evtTime>=start[gti] && evtTime<=stop[gti] ) break; } } if (nextGTI >= nGTI) nextGTI = -1; if (nextGTI0) *nextGTI0 = nextGTI; return( gti ); } static void Do_REG( Node *this ) { Node *theRegion, *theX, *theY; double Xval=0.0, Yval=0.0; char Xnull=0, Ynull=0; int Xvector, Yvector; long nelem, elem, rows; theRegion = gParse.Nodes + this->SubNodes[0]; theX = gParse.Nodes + this->SubNodes[1]; theY = gParse.Nodes + this->SubNodes[2]; Xvector = ( theX->operation!=CONST_OP ); if( Xvector ) Xvector = theX->value.nelem; else { Xval = theX->value.data.dbl; } Yvector = ( theY->operation!=CONST_OP ); if( Yvector ) Yvector = theY->value.nelem; else { Yval = theY->value.data.dbl; } if( !Xvector && !Yvector ) { this->value.data.log = ( fits_in_region( Xval, Yval, (SAORegion *)theRegion->value.data.ptr ) != 0 ); this->operation = CONST_OP; } else { Allocate_Ptrs( this ); if( !gParse.status ) { rows = gParse.nRows; nelem = this->value.nelem; elem = rows*nelem; while( rows-- ) { while( nelem-- ) { elem--; if( Xvector>1 ) { Xval = theX->value.data.dblptr[elem]; Xnull = theX->value.undef[elem]; } else if( Xvector ) { Xval = theX->value.data.dblptr[rows]; Xnull = theX->value.undef[rows]; } if( Yvector>1 ) { Yval = theY->value.data.dblptr[elem]; Ynull = theY->value.undef[elem]; } else if( Yvector ) { Yval = theY->value.data.dblptr[rows]; Ynull = theY->value.undef[rows]; } this->value.undef[elem] = ( Xnull || Ynull ); if( this->value.undef[elem] ) continue; this->value.data.logptr[elem] = ( fits_in_region( Xval, Yval, (SAORegion *)theRegion->value.data.ptr ) != 0 ); } nelem = this->value.nelem; } } } if( theX->operation>0 ) free( theX->value.data.ptr ); if( theY->operation>0 ) free( theY->value.data.ptr ); } static void Do_Vector( Node *this ) { Node *that; long row, elem, idx, jdx, offset=0; int node; Allocate_Ptrs( this ); if( !gParse.status ) { for( node=0; nodenSubNodes; node++ ) { that = gParse.Nodes + this->SubNodes[node]; if( that->operation == CONST_OP ) { idx = gParse.nRows*this->value.nelem + offset; while( (idx-=this->value.nelem)>=0 ) { this->value.undef[idx] = 0; switch( this->type ) { case BOOLEAN: this->value.data.logptr[idx] = that->value.data.log; break; case LONG: this->value.data.lngptr[idx] = that->value.data.lng; break; case DOUBLE: this->value.data.dblptr[idx] = that->value.data.dbl; break; } } } else { row = gParse.nRows; idx = row * that->value.nelem; while( row-- ) { elem = that->value.nelem; jdx = row*this->value.nelem + offset; while( elem-- ) { this->value.undef[jdx+elem] = that->value.undef[--idx]; switch( this->type ) { case BOOLEAN: this->value.data.logptr[jdx+elem] = that->value.data.logptr[idx]; break; case LONG: this->value.data.lngptr[jdx+elem] = that->value.data.lngptr[idx]; break; case DOUBLE: this->value.data.dblptr[jdx+elem] = that->value.data.dblptr[idx]; break; } } } } offset += that->value.nelem; } } for( node=0; node < this->nSubNodes; node++ ) if( OPER(this->SubNodes[node])>0 ) free( gParse.Nodes[this->SubNodes[node]].value.data.ptr ); } /*****************************************************************************/ /* Utility routines which perform the calculations on bits and SAO regions */ /*****************************************************************************/ static char bitlgte(char *bits1, int oper, char *bits2) { int val1, val2, nextbit; char result; int i, l1, l2, length, ldiff; char *stream=0; char chr1, chr2; l1 = strlen(bits1); l2 = strlen(bits2); length = (l1 > l2) ? l1 : l2; stream = (char *)malloc(sizeof(char)*(length+1)); if (l1 < l2) { ldiff = l2 - l1; i=0; while( ldiff-- ) stream[i++] = '0'; while( l1-- ) stream[i++] = *(bits1++); stream[i] = '\0'; bits1 = stream; } else if (l2 < l1) { ldiff = l1 - l2; i=0; while( ldiff-- ) stream[i++] = '0'; while( l2-- ) stream[i++] = *(bits2++); stream[i] = '\0'; bits2 = stream; } val1 = val2 = 0; nextbit = 1; while( length-- ) { chr1 = bits1[length]; chr2 = bits2[length]; if ((chr1 != 'x')&&(chr1 != 'X')&&(chr2 != 'x')&&(chr2 != 'X')) { if (chr1 == '1') val1 += nextbit; if (chr2 == '1') val2 += nextbit; nextbit *= 2; } } result = 0; switch (oper) { case LT: if (val1 < val2) result = 1; break; case LTE: if (val1 <= val2) result = 1; break; case GT: if (val1 > val2) result = 1; break; case GTE: if (val1 >= val2) result = 1; break; } free(stream); return (result); } static void bitand(char *result,char *bitstrm1,char *bitstrm2) { int i, l1, l2, ldiff, largestStream; char *stream=0; char chr1, chr2; l1 = strlen(bitstrm1); l2 = strlen(bitstrm2); largestStream = (l1 > l2) ? l1 : l2; stream = (char *)malloc(sizeof(char)*(largestStream+1)); if (l1 < l2) { ldiff = l2 - l1; i=0; while( ldiff-- ) stream[i++] = '0'; while( l1-- ) stream[i++] = *(bitstrm1++); stream[i] = '\0'; bitstrm1 = stream; } else if (l2 < l1) { ldiff = l1 - l2; i=0; while( ldiff-- ) stream[i++] = '0'; while( l2-- ) stream[i++] = *(bitstrm2++); stream[i] = '\0'; bitstrm2 = stream; } while ( (chr1 = *(bitstrm1++)) ) { chr2 = *(bitstrm2++); if ((chr1 == 'x') || (chr2 == 'x')) *result = 'x'; else if ((chr1 == '1') && (chr2 == '1')) *result = '1'; else *result = '0'; result++; } free(stream); *result = '\0'; } static void bitor(char *result,char *bitstrm1,char *bitstrm2) { int i, l1, l2, ldiff, largestStream; char *stream=0; char chr1, chr2; l1 = strlen(bitstrm1); l2 = strlen(bitstrm2); largestStream = (l1 > l2) ? l1 : l2; stream = (char *)malloc(sizeof(char)*(largestStream+1)); if (l1 < l2) { ldiff = l2 - l1; i=0; while( ldiff-- ) stream[i++] = '0'; while( l1-- ) stream[i++] = *(bitstrm1++); stream[i] = '\0'; bitstrm1 = stream; } else if (l2 < l1) { ldiff = l1 - l2; i=0; while( ldiff-- ) stream[i++] = '0'; while( l2-- ) stream[i++] = *(bitstrm2++); stream[i] = '\0'; bitstrm2 = stream; } while ( (chr1 = *(bitstrm1++)) ) { chr2 = *(bitstrm2++); if ((chr1 == '1') || (chr2 == '1')) *result = '1'; else if ((chr1 == '0') || (chr2 == '0')) *result = '0'; else *result = 'x'; result++; } free(stream); *result = '\0'; } static void bitnot(char *result,char *bits) { int length; char chr; length = strlen(bits); while( length-- ) { chr = *(bits++); *(result++) = ( chr=='1' ? '0' : ( chr=='0' ? '1' : chr ) ); } *result = '\0'; } static char bitcmp(char *bitstrm1, char *bitstrm2) { int i, l1, l2, ldiff, largestStream; char *stream=0; char chr1, chr2; l1 = strlen(bitstrm1); l2 = strlen(bitstrm2); largestStream = (l1 > l2) ? l1 : l2; stream = (char *)malloc(sizeof(char)*(largestStream+1)); if (l1 < l2) { ldiff = l2 - l1; i=0; while( ldiff-- ) stream[i++] = '0'; while( l1-- ) stream[i++] = *(bitstrm1++); stream[i] = '\0'; bitstrm1 = stream; } else if (l2 < l1) { ldiff = l1 - l2; i=0; while( ldiff-- ) stream[i++] = '0'; while( l2-- ) stream[i++] = *(bitstrm2++); stream[i] = '\0'; bitstrm2 = stream; } while( (chr1 = *(bitstrm1++)) ) { chr2 = *(bitstrm2++); if ( ((chr1 == '0') && (chr2 == '1')) || ((chr1 == '1') && (chr2 == '0')) ) { free(stream); return( 0 ); } } free(stream); return( 1 ); } static char bnear(double x, double y, double tolerance) { if (fabs(x - y) < tolerance) return ( 1 ); else return ( 0 ); } static char saobox(double xcen, double ycen, double xwid, double ywid, double rot, double xcol, double ycol) { double x,y,xprime,yprime,xmin,xmax,ymin,ymax,theta; theta = (rot / 180.0) * myPI; xprime = xcol - xcen; yprime = ycol - ycen; x = xprime * cos(theta) + yprime * sin(theta); y = -xprime * sin(theta) + yprime * cos(theta); xmin = - 0.5 * xwid; xmax = 0.5 * xwid; ymin = - 0.5 * ywid; ymax = 0.5 * ywid; if ((x >= xmin) && (x <= xmax) && (y >= ymin) && (y <= ymax)) return ( 1 ); else return ( 0 ); } static char circle(double xcen, double ycen, double rad, double xcol, double ycol) { double r2,dx,dy,dlen; dx = xcol - xcen; dy = ycol - ycen; dx *= dx; dy *= dy; dlen = dx + dy; r2 = rad * rad; if (dlen <= r2) return ( 1 ); else return ( 0 ); } static char ellipse(double xcen, double ycen, double xrad, double yrad, double rot, double xcol, double ycol) { double x,y,xprime,yprime,dx,dy,dlen,theta; theta = (rot / 180.0) * myPI; xprime = xcol - xcen; yprime = ycol - ycen; x = xprime * cos(theta) + yprime * sin(theta); y = -xprime * sin(theta) + yprime * cos(theta); dx = x / xrad; dy = y / yrad; dx *= dx; dy *= dy; dlen = dx + dy; if (dlen <= 1.0) return ( 1 ); else return ( 0 ); } /* * Extract substring */ int cstrmid(char *dest_str, int dest_len, char *src_str, int src_len, int pos) { /* char fill_char = ' '; */ char fill_char = '\0'; if (src_len == 0) { src_len = strlen(src_str); } /* .. if constant */ /* Fill destination with blanks */ if (pos < 0) { fferror("STRMID(S,P,N) P must be 0 or greater"); return -1; } if (pos > src_len || pos == 0) { /* pos==0: blank string requested */ memset(dest_str, fill_char, dest_len); } else if (pos+dest_len > src_len) { /* Copy a subset */ int nsub = src_len-pos+1; int npad = dest_len - nsub; memcpy(dest_str, src_str+pos-1, nsub); /* Fill remaining string with blanks */ memset(dest_str+nsub, fill_char, npad); } else { /* Full string copy */ memcpy(dest_str, src_str+pos-1, dest_len); } dest_str[dest_len] = '\0'; /* Null-terminate */ return 0; } static void fferror(char *s) { char msg[80]; if( !gParse.status ) gParse.status = PARSE_SYNTAX_ERR; strncpy(msg, s, 80); msg[79] = '\0'; ffpmsg(msg); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/fits_hcompress.c0000644000175100001710000013375200000000000021332 0ustar00vstsdocker/* ######################################################################### These routines to apply the H-compress compression algorithm to a 2-D Fits image were written by R. White at the STScI and were obtained from the STScI at http://www.stsci.edu/software/hcompress.html This source file is a concatination of the following sources files in the original distribution htrans.c digitize.c encode.c qwrite.c doencode.c bit_output.c qtree_encode.c The following modifications have been made to the original code: - commented out redundant "include" statements - added the noutchar global variable - changed all the 'extern' declarations to 'static', since all the routines are in the same source file - changed the first parameter in encode (and in lower level routines from a file stream to a char array - modifid the encode routine to return the size of the compressed array of bytes - changed calls to printf and perror to call the CFITSIO ffpmsg routine - modified the mywrite routine, and lower level byte writing routines, to copy the output bytes to a char array, instead of writing them to a file stream - replace "exit" statements with "return" statements - changed the function declarations to the more modern ANSI C style ############################################################################ */ #include #include #include #include #include "fitsio2.h" static long noutchar; static long noutmax; static int htrans(int a[],int nx,int ny); static void digitize(int a[], int nx, int ny, int scale); static int encode(char *outfile, long *nlen, int a[], int nx, int ny, int scale); static void shuffle(int a[], int n, int n2, int tmp[]); static int htrans64(LONGLONG a[],int nx,int ny); static void digitize64(LONGLONG a[], int nx, int ny, int scale); static int encode64(char *outfile, long *nlen, LONGLONG a[], int nx, int ny, int scale); static void shuffle64(LONGLONG a[], int n, int n2, LONGLONG tmp[]); static void writeint(char *outfile, int a); static void writelonglong(char *outfile, LONGLONG a); static int doencode(char *outfile, int a[], int nx, int ny, unsigned char nbitplanes[3]); static int doencode64(char *outfile, LONGLONG a[], int nx, int ny, unsigned char nbitplanes[3]); static int qwrite(char *file, char buffer[], int n); static int qtree_encode(char *outfile, int a[], int n, int nqx, int nqy, int nbitplanes); static int qtree_encode64(char *outfile, LONGLONG a[], int n, int nqx, int nqy, int nbitplanes); static void start_outputing_bits(void); static void done_outputing_bits(char *outfile); static void output_nbits(char *outfile, int bits, int n); static void qtree_onebit(int a[], int n, int nx, int ny, unsigned char b[], int bit); static void qtree_onebit64(LONGLONG a[], int n, int nx, int ny, unsigned char b[], int bit); static void qtree_reduce(unsigned char a[], int n, int nx, int ny, unsigned char b[]); static int bufcopy(unsigned char a[], int n, unsigned char buffer[], int *b, int bmax); static void write_bdirect(char *outfile, int a[], int n,int nqx, int nqy, unsigned char scratch[], int bit); static void write_bdirect64(char *outfile, LONGLONG a[], int n,int nqx, int nqy, unsigned char scratch[], int bit); /* #define output_nybble(outfile,c) output_nbits(outfile,c,4) */ static void output_nybble(char *outfile, int bits); static void output_nnybble(char *outfile, int n, unsigned char array[]); #define output_huffman(outfile,c) output_nbits(outfile,code[c],ncode[c]) /* ---------------------------------------------------------------------- */ int fits_hcompress(int *a, int ny, int nx, int scale, char *output, long *nbytes, int *status) { /* compress the input image using the H-compress algorithm a - input image array nx - size of X axis of image ny - size of Y axis of image scale - quantization scale factor. Larger values results in more (lossy) compression scale = 0 does lossless compression output - pre-allocated array to hold the output compressed stream of bytes nbyts - input value = size of the output buffer; returned value = size of the compressed byte stream, in bytes NOTE: the nx and ny dimensions as defined within this code are reversed from the usual FITS notation. ny is the fastest varying dimension, which is usually considered the X axis in the FITS image display */ int stat; if (*status > 0) return(*status); /* H-transform */ stat = htrans(a, nx, ny); if (stat) { *status = stat; return(*status); } /* digitize */ digitize(a, nx, ny, scale); /* encode and write to output array */ FFLOCK; noutmax = *nbytes; /* input value is the allocated size of the array */ *nbytes = 0; /* reset */ stat = encode(output, nbytes, a, nx, ny, scale); FFUNLOCK; *status = stat; return(*status); } /* ---------------------------------------------------------------------- */ int fits_hcompress64(LONGLONG *a, int ny, int nx, int scale, char *output, long *nbytes, int *status) { /* compress the input image using the H-compress algorithm a - input image array nx - size of X axis of image ny - size of Y axis of image scale - quantization scale factor. Larger values results in more (lossy) compression scale = 0 does lossless compression output - pre-allocated array to hold the output compressed stream of bytes nbyts - size of the compressed byte stream, in bytes NOTE: the nx and ny dimensions as defined within this code are reversed from the usual FITS notation. ny is the fastest varying dimension, which is usually considered the X axis in the FITS image display */ int stat; if (*status > 0) return(*status); /* H-transform */ stat = htrans64(a, nx, ny); if (stat) { *status = stat; return(*status); } /* digitize */ digitize64(a, nx, ny, scale); /* encode and write to output array */ FFLOCK; noutmax = *nbytes; /* input value is the allocated size of the array */ *nbytes = 0; /* reset */ stat = encode64(output, nbytes, a, nx, ny, scale); FFUNLOCK; *status = stat; return(*status); } /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* htrans.c H-transform of NX x NY integer image * * Programmer: R. White Date: 11 May 1992 */ /* ######################################################################### */ static int htrans(int a[],int nx,int ny) { int nmax, log2n, h0, hx, hy, hc, nxtop, nytop, i, j, k; int oddx, oddy; int shift, mask, mask2, prnd, prnd2, nrnd2; int s10, s00; int *tmp; /* * log2n is log2 of max(nx,ny) rounded up to next power of 2 */ nmax = (nx>ny) ? nx : ny; log2n = (int) (log((float) nmax)/log(2.0)+0.5); if ( nmax > (1<> shift; hx = (a[s10+1] + a[s10] - a[s00+1] - a[s00]) >> shift; hy = (a[s10+1] - a[s10] + a[s00+1] - a[s00]) >> shift; hc = (a[s10+1] - a[s10] - a[s00+1] + a[s00]) >> shift; /* * Throw away the 2 bottom bits of h0, bottom bit of hx,hy. * To get rounding to be same for positive and negative * numbers, nrnd2 = prnd2 - 1. */ a[s10+1] = hc; a[s10 ] = ( (hx>=0) ? (hx+prnd) : hx ) & mask ; a[s00+1] = ( (hy>=0) ? (hy+prnd) : hy ) & mask ; a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; s00 += 2; s10 += 2; } if (oddy) { /* * do last element in row if row length is odd * s00+1, s10+1 are off edge */ h0 = (a[s10] + a[s00]) << (1-shift); hx = (a[s10] - a[s00]) << (1-shift); a[s10 ] = ( (hx>=0) ? (hx+prnd) : hx ) & mask ; a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; s00 += 1; s10 += 1; } } if (oddx) { /* * do last row if column length is odd * s10, s10+1 are off edge */ s00 = i*ny; for (j = 0; j=0) ? (hy+prnd) : hy ) & mask ; a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; s00 += 2; } if (oddy) { /* * do corner element if both row and column lengths are odd * s00+1, s10, s10+1 are off edge */ h0 = a[s00] << (2-shift); a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; } } /* * now shuffle in each dimension to group coefficients by order */ for (i = 0; i>1; nytop = (nytop+1)>>1; /* * divisor doubles after first reduction */ shift = 1; /* * masks, rounding values double after each iteration */ mask = mask2; prnd = prnd2; mask2 = mask2 << 1; prnd2 = prnd2 << 1; nrnd2 = prnd2 - 1; } free(tmp); return(0); } /* ######################################################################### */ static int htrans64(LONGLONG a[],int nx,int ny) { int nmax, log2n, nxtop, nytop, i, j, k; int oddx, oddy; int shift; int s10, s00; LONGLONG h0, hx, hy, hc, prnd, prnd2, nrnd2, mask, mask2; LONGLONG *tmp; /* * log2n is log2 of max(nx,ny) rounded up to next power of 2 */ nmax = (nx>ny) ? nx : ny; log2n = (int) (log((float) nmax)/log(2.0)+0.5); if ( nmax > (1<> shift; hx = (a[s10+1] + a[s10] - a[s00+1] - a[s00]) >> shift; hy = (a[s10+1] - a[s10] + a[s00+1] - a[s00]) >> shift; hc = (a[s10+1] - a[s10] - a[s00+1] + a[s00]) >> shift; /* * Throw away the 2 bottom bits of h0, bottom bit of hx,hy. * To get rounding to be same for positive and negative * numbers, nrnd2 = prnd2 - 1. */ a[s10+1] = hc; a[s10 ] = ( (hx>=0) ? (hx+prnd) : hx ) & mask ; a[s00+1] = ( (hy>=0) ? (hy+prnd) : hy ) & mask ; a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; s00 += 2; s10 += 2; } if (oddy) { /* * do last element in row if row length is odd * s00+1, s10+1 are off edge */ h0 = (a[s10] + a[s00]) << (1-shift); hx = (a[s10] - a[s00]) << (1-shift); a[s10 ] = ( (hx>=0) ? (hx+prnd) : hx ) & mask ; a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; s00 += 1; s10 += 1; } } if (oddx) { /* * do last row if column length is odd * s10, s10+1 are off edge */ s00 = i*ny; for (j = 0; j=0) ? (hy+prnd) : hy ) & mask ; a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; s00 += 2; } if (oddy) { /* * do corner element if both row and column lengths are odd * s00+1, s10, s10+1 are off edge */ h0 = a[s00] << (2-shift); a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; } } /* * now shuffle in each dimension to group coefficients by order */ for (i = 0; i>1; nytop = (nytop+1)>>1; /* * divisor doubles after first reduction */ shift = 1; /* * masks, rounding values double after each iteration */ mask = mask2; prnd = prnd2; mask2 = mask2 << 1; prnd2 = prnd2 << 1; nrnd2 = prnd2 - 1; } free(tmp); return(0); } /* ######################################################################### */ static void shuffle(int a[], int n, int n2, int tmp[]) { /* int a[]; array to shuffle int n; number of elements to shuffle int n2; second dimension int tmp[]; scratch storage */ int i; int *p1, *p2, *pt; /* * copy odd elements to tmp */ pt = tmp; p1 = &a[n2]; for (i=1; i < n; i += 2) { *pt = *p1; pt += 1; p1 += (n2+n2); } /* * compress even elements into first half of A */ p1 = &a[n2]; p2 = &a[n2+n2]; for (i=2; i0) ? (*p+d) : (*p-d))/scale; } /* ######################################################################### */ static void digitize64(LONGLONG a[], int nx, int ny, int scale) { LONGLONG d, *p, scale64; /* * round to multiple of scale */ if (scale <= 1) return; d=(scale+1)/2-1; scale64 = scale; /* use a 64-bit int for efficiency in the big loop */ for (p=a; p <= &a[nx*ny-1]; p++) *p = ((*p>0) ? (*p+d) : (*p-d))/scale64; } /* ######################################################################### */ /* ######################################################################### */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* encode.c encode H-transform and write to outfile * * Programmer: R. White Date: 2 February 1994 */ static char code_magic[2] = { (char)0xDD, (char)0x99 }; /* ######################################################################### */ static int encode(char *outfile, long *nlength, int a[], int nx, int ny, int scale) { /* FILE *outfile; - change outfile to a char array */ /* long * nlength returned length (in bytes) of the encoded array) int a[]; input H-transform array (nx,ny) int nx,ny; size of H-transform array int scale; scale factor for digitization */ int nel, nx2, ny2, i, j, k, q, vmax[3], nsign, bits_to_go; unsigned char nbitplanes[3]; unsigned char *signbits; int stat; noutchar = 0; /* initialize the number of compressed bytes that have been written */ nel = nx*ny; /* * write magic value */ qwrite(outfile, code_magic, sizeof(code_magic)); writeint(outfile, nx); /* size of image */ writeint(outfile, ny); writeint(outfile, scale); /* scale factor for digitization */ /* * write first value of A (sum of all pixels -- the only value * which does not compress well) */ writelonglong(outfile, (LONGLONG) a[0]); a[0] = 0; /* * allocate array for sign bits and save values, 8 per byte (initialize to all zeros) */ signbits = (unsigned char *) calloc(1, (nel+7)/8); if (signbits == (unsigned char *) NULL) { ffpmsg("encode: insufficient memory"); return(DATA_COMPRESSION_ERR); } nsign = 0; bits_to_go = 8; /* signbits[0] = 0; */ for (i=0; i 0) { /* * positive element, put zero at end of buffer */ signbits[nsign] <<= 1; bits_to_go -= 1; } else if (a[i] < 0) { /* * negative element, shift in a one */ signbits[nsign] <<= 1; signbits[nsign] |= 1; bits_to_go -= 1; /* * replace a by absolute value */ a[i] = -a[i]; } if (bits_to_go == 0) { /* * filled up this byte, go to the next one */ bits_to_go = 8; nsign += 1; /* signbits[nsign] = 0; */ } } if (bits_to_go != 8) { /* * some bits in last element * move bits in last byte to bottom and increment nsign */ signbits[nsign] <<= bits_to_go; nsign += 1; } /* * calculate number of bit planes for 3 quadrants * * quadrant 0=bottom left, 1=bottom right or top left, 2=top right, */ for (q=0; q<3; q++) { vmax[q] = 0; } /* * get maximum absolute value in each quadrant */ nx2 = (nx+1)/2; ny2 = (ny+1)/2; j=0; /* column counter */ k=0; /* row counter */ for (i=0; i=ny2) + (k>=nx2); if (vmax[q] < a[i]) vmax[q] = a[i]; if (++j >= ny) { j = 0; k += 1; } } /* * now calculate number of bits for each quadrant */ /* this is a more efficient way to do this, */ for (q = 0; q < 3; q++) { for (nbitplanes[q] = 0; vmax[q]>0; vmax[q] = vmax[q]>>1, nbitplanes[q]++) ; } /* for (q = 0; q < 3; q++) { nbitplanes[q] = (int) (log((float) (vmax[q]+1))/log(2.0)+0.5); if ( (vmax[q]+1) > (1< 0) { if ( 0 == qwrite(outfile, (char *) signbits, nsign)) { free(signbits); *nlength = noutchar; ffpmsg("encode: output buffer too small"); return(DATA_COMPRESSION_ERR); } } free(signbits); *nlength = noutchar; if (noutchar >= noutmax) { ffpmsg("encode: output buffer too small"); return(DATA_COMPRESSION_ERR); } return(stat); } /* ######################################################################### */ static int encode64(char *outfile, long *nlength, LONGLONG a[], int nx, int ny, int scale) { /* FILE *outfile; - change outfile to a char array */ /* long * nlength returned length (in bytes) of the encoded array) LONGLONG a[]; input H-transform array (nx,ny) int nx,ny; size of H-transform array int scale; scale factor for digitization */ int nel, nx2, ny2, i, j, k, q, nsign, bits_to_go; LONGLONG vmax[3]; unsigned char nbitplanes[3]; unsigned char *signbits; int stat; noutchar = 0; /* initialize the number of compressed bytes that have been written */ nel = nx*ny; /* * write magic value */ qwrite(outfile, code_magic, sizeof(code_magic)); writeint(outfile, nx); /* size of image */ writeint(outfile, ny); writeint(outfile, scale); /* scale factor for digitization */ /* * write first value of A (sum of all pixels -- the only value * which does not compress well) */ writelonglong(outfile, a[0]); a[0] = 0; /* * allocate array for sign bits and save values, 8 per byte */ signbits = (unsigned char *) calloc(1, (nel+7)/8); if (signbits == (unsigned char *) NULL) { ffpmsg("encode64: insufficient memory"); return(DATA_COMPRESSION_ERR); } nsign = 0; bits_to_go = 8; /* signbits[0] = 0; */ for (i=0; i 0) { /* * positive element, put zero at end of buffer */ signbits[nsign] <<= 1; bits_to_go -= 1; } else if (a[i] < 0) { /* * negative element, shift in a one */ signbits[nsign] <<= 1; signbits[nsign] |= 1; bits_to_go -= 1; /* * replace a by absolute value */ a[i] = -a[i]; } if (bits_to_go == 0) { /* * filled up this byte, go to the next one */ bits_to_go = 8; nsign += 1; /* signbits[nsign] = 0; */ } } if (bits_to_go != 8) { /* * some bits in last element * move bits in last byte to bottom and increment nsign */ signbits[nsign] <<= bits_to_go; nsign += 1; } /* * calculate number of bit planes for 3 quadrants * * quadrant 0=bottom left, 1=bottom right or top left, 2=top right, */ for (q=0; q<3; q++) { vmax[q] = 0; } /* * get maximum absolute value in each quadrant */ nx2 = (nx+1)/2; ny2 = (ny+1)/2; j=0; /* column counter */ k=0; /* row counter */ for (i=0; i=ny2) + (k>=nx2); if (vmax[q] < a[i]) vmax[q] = a[i]; if (++j >= ny) { j = 0; k += 1; } } /* * now calculate number of bits for each quadrant */ /* this is a more efficient way to do this, */ for (q = 0; q < 3; q++) { for (nbitplanes[q] = 0; vmax[q]>0; vmax[q] = vmax[q]>>1, nbitplanes[q]++) ; } /* for (q = 0; q < 3; q++) { nbitplanes[q] = log((float) (vmax[q]+1))/log(2.0)+0.5; if ( (vmax[q]+1) > (((LONGLONG) 1)< 0) { if ( 0 == qwrite(outfile, (char *) signbits, nsign)) { free(signbits); *nlength = noutchar; ffpmsg("encode: output buffer too small"); return(DATA_COMPRESSION_ERR); } } free(signbits); *nlength = noutchar; if (noutchar >= noutmax) { ffpmsg("encode64: output buffer too small"); return(DATA_COMPRESSION_ERR); } return(stat); } /* ######################################################################### */ /* ######################################################################### */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* qwrite.c Write binary data * * Programmer: R. White Date: 11 March 1991 */ /* ######################################################################### */ static void writeint(char *outfile, int a) { int i; unsigned char b[4]; /* Write integer A one byte at a time to outfile. * * This is portable from Vax to Sun since it eliminates the * need for byte-swapping. */ for (i=3; i>=0; i--) { b[i] = a & 0x000000ff; a >>= 8; } for (i=0; i<4; i++) qwrite(outfile, (char *) &b[i],1); } /* ######################################################################### */ static void writelonglong(char *outfile, LONGLONG a) { int i; unsigned char b[8]; /* Write integer A one byte at a time to outfile. * * This is portable from Vax to Sun since it eliminates the * need for byte-swapping. */ for (i=7; i>=0; i--) { b[i] = (unsigned char) (a & 0x000000ff); a >>= 8; } for (i=0; i<8; i++) qwrite(outfile, (char *) &b[i],1); } /* ######################################################################### */ static int qwrite(char *file, char buffer[], int n){ /* * write n bytes from buffer into file * returns number of bytes read (=n) if successful, <=0 if not */ if (noutchar + n > noutmax) return(0); /* buffer overflow */ memcpy(&file[noutchar], buffer, n); noutchar += n; return(n); } /* ######################################################################### */ /* ######################################################################### */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* doencode.c Encode 2-D array and write stream of characters on outfile * * This version assumes that A is positive. * * Programmer: R. White Date: 7 May 1991 */ /* ######################################################################### */ static int doencode(char *outfile, int a[], int nx, int ny, unsigned char nbitplanes[3]) { /* char *outfile; output data stream int a[]; Array of values to encode int nx,ny; Array dimensions [nx][ny] unsigned char nbitplanes[3]; Number of bit planes in quadrants */ int nx2, ny2, stat; nx2 = (nx+1)/2; ny2 = (ny+1)/2; /* * Initialize bit output */ start_outputing_bits(); /* * write out the bit planes for each quadrant */ stat = qtree_encode(outfile, &a[0], ny, nx2, ny2, nbitplanes[0]); if (!stat) stat = qtree_encode(outfile, &a[ny2], ny, nx2, ny/2, nbitplanes[1]); if (!stat) stat = qtree_encode(outfile, &a[ny*nx2], ny, nx/2, ny2, nbitplanes[1]); if (!stat) stat = qtree_encode(outfile, &a[ny*nx2+ny2], ny, nx/2, ny/2, nbitplanes[2]); /* * Add zero as an EOF symbol */ output_nybble(outfile, 0); done_outputing_bits(outfile); return(stat); } /* ######################################################################### */ static int doencode64(char *outfile, LONGLONG a[], int nx, int ny, unsigned char nbitplanes[3]) { /* char *outfile; output data stream LONGLONG a[]; Array of values to encode int nx,ny; Array dimensions [nx][ny] unsigned char nbitplanes[3]; Number of bit planes in quadrants */ int nx2, ny2, stat; nx2 = (nx+1)/2; ny2 = (ny+1)/2; /* * Initialize bit output */ start_outputing_bits(); /* * write out the bit planes for each quadrant */ stat = qtree_encode64(outfile, &a[0], ny, nx2, ny2, nbitplanes[0]); if (!stat) stat = qtree_encode64(outfile, &a[ny2], ny, nx2, ny/2, nbitplanes[1]); if (!stat) stat = qtree_encode64(outfile, &a[ny*nx2], ny, nx/2, ny2, nbitplanes[1]); if (!stat) stat = qtree_encode64(outfile, &a[ny*nx2+ny2], ny, nx/2, ny/2, nbitplanes[2]); /* * Add zero as an EOF symbol */ output_nybble(outfile, 0); done_outputing_bits(outfile); return(stat); } /* ######################################################################### */ /* ######################################################################### */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* BIT OUTPUT ROUTINES */ static LONGLONG bitcount; /* THE BIT BUFFER */ static int buffer2; /* Bits buffered for output */ static int bits_to_go2; /* Number of bits free in buffer */ /* ######################################################################### */ /* INITIALIZE FOR BIT OUTPUT */ static void start_outputing_bits(void) { buffer2 = 0; /* Buffer is empty to start */ bits_to_go2 = 8; /* with */ bitcount = 0; } /* ######################################################################### */ /* OUTPUT N BITS (N must be <= 8) */ static void output_nbits(char *outfile, int bits, int n) { /* AND mask for the right-most n bits */ static int mask[9] = {0, 1, 3, 7, 15, 31, 63, 127, 255}; /* * insert bits at end of buffer */ buffer2 <<= n; /* buffer2 |= ( bits & ((1<>(-bits_to_go2)) & 0xff); if (noutchar < noutmax) noutchar++; bits_to_go2 += 8; } bitcount += n; } /* ######################################################################### */ /* OUTPUT a 4 bit nybble */ static void output_nybble(char *outfile, int bits) { /* * insert 4 bits at end of buffer */ buffer2 = (buffer2<<4) | ( bits & 15 ); bits_to_go2 -= 4; if (bits_to_go2 <= 0) { /* * buffer2 full, put out top 8 bits */ outfile[noutchar] = ((buffer2>>(-bits_to_go2)) & 0xff); if (noutchar < noutmax) noutchar++; bits_to_go2 += 8; } bitcount += 4; } /* ############################################################################ */ /* OUTPUT array of 4 BITS */ static void output_nnybble(char *outfile, int n, unsigned char array[]) { /* pack the 4 lower bits in each element of the array into the outfile array */ int ii, jj, kk = 0, shift; if (n == 1) { output_nybble(outfile, (int) array[0]); return; } /* forcing byte alignment doesn;t help, and even makes it go slightly slower if (bits_to_go2 != 8) output_nbits(outfile, kk, bits_to_go2); */ if (bits_to_go2 <= 4) { /* just room for 1 nybble; write it out separately */ output_nybble(outfile, array[0]); kk++; /* index to next array element */ if (n == 2) /* only 1 more nybble to write out */ { output_nybble(outfile, (int) array[1]); return; } } /* bits_to_go2 is now in the range 5 - 8 */ shift = 8 - bits_to_go2; /* now write out pairs of nybbles; this does not affect value of bits_to_go2 */ jj = (n - kk) / 2; if (bits_to_go2 == 8) { /* special case if nybbles are aligned on byte boundary */ /* this actually seems to make very little differnece in speed */ buffer2 = 0; for (ii = 0; ii < jj; ii++) { outfile[noutchar] = ((array[kk] & 15)<<4) | (array[kk+1] & 15); kk += 2; noutchar++; } } else { for (ii = 0; ii < jj; ii++) { buffer2 = (buffer2<<8) | ((array[kk] & 15)<<4) | (array[kk+1] & 15); kk += 2; /* buffer2 full, put out top 8 bits */ outfile[noutchar] = ((buffer2>>shift) & 0xff); noutchar++; } } bitcount += (8 * (ii - 1)); /* write out last odd nybble, if present */ if (kk != n) output_nybble(outfile, (int) array[n - 1]); return; } /* ######################################################################### */ /* FLUSH OUT THE LAST BITS */ static void done_outputing_bits(char *outfile) { if(bits_to_go2 < 8) { /* putc(buffer2<nqy) ? nqx : nqy; log2n = (int) (log((float) nqmax)/log(2.0)+0.5); if (nqmax > (1<= 0; bit--) { /* * initial bit buffer */ b = 0; bitbuffer = 0; bits_to_go3 = 0; /* * on first pass copy A to scratch array */ qtree_onebit(a,n,nqx,nqy,scratch,bit); nx = (nqx+1)>>1; ny = (nqy+1)>>1; /* * copy non-zero values to output buffer, which will be written * in reverse order */ if (bufcopy(scratch,nx*ny,buffer,&b,bmax)) { /* * quadtree is expanding data, * change warning code and just fill buffer with bit-map */ write_bdirect(outfile,a,n,nqx,nqy,scratch,bit); goto bitplane_done; } /* * do log2n reductions */ for (k = 1; k>1; ny = (ny+1)>>1; if (bufcopy(scratch,nx*ny,buffer,&b,bmax)) { write_bdirect(outfile,a,n,nqx,nqy,scratch,bit); goto bitplane_done; } } /* * OK, we've got the code in buffer * Write quadtree warning code, then write buffer in reverse order */ output_nybble(outfile,0xF); if (b==0) { if (bits_to_go3>0) { /* * put out the last few bits */ output_nbits(outfile, bitbuffer & ((1<0) { /* * put out the last few bits */ output_nbits(outfile, bitbuffer & ((1<=0; i--) { output_nbits(outfile,buffer[i],8); } } bitplane_done: ; } free(buffer); free(scratch); return(0); } /* ######################################################################### */ static int qtree_encode64(char *outfile, LONGLONG a[], int n, int nqx, int nqy, int nbitplanes) { /* LONGLONG a[]; int n; physical dimension of row in a int nqx; length of row int nqy; length of column (<=n) int nbitplanes; number of bit planes to output */ int log2n, i, k, bit, b, nqmax, nqx2, nqy2, nx, ny; int bmax; /* this potentially needs to be made a 64-bit int to support large arrays */ unsigned char *scratch, *buffer; /* * log2n is log2 of max(nqx,nqy) rounded up to next power of 2 */ nqmax = (nqx>nqy) ? nqx : nqy; log2n = (int) (log((float) nqmax)/log(2.0)+0.5); if (nqmax > (1<= 0; bit--) { /* * initial bit buffer */ b = 0; bitbuffer = 0; bits_to_go3 = 0; /* * on first pass copy A to scratch array */ qtree_onebit64(a,n,nqx,nqy,scratch,bit); nx = (nqx+1)>>1; ny = (nqy+1)>>1; /* * copy non-zero values to output buffer, which will be written * in reverse order */ if (bufcopy(scratch,nx*ny,buffer,&b,bmax)) { /* * quadtree is expanding data, * change warning code and just fill buffer with bit-map */ write_bdirect64(outfile,a,n,nqx,nqy,scratch,bit); goto bitplane_done; } /* * do log2n reductions */ for (k = 1; k>1; ny = (ny+1)>>1; if (bufcopy(scratch,nx*ny,buffer,&b,bmax)) { write_bdirect64(outfile,a,n,nqx,nqy,scratch,bit); goto bitplane_done; } } /* * OK, we've got the code in buffer * Write quadtree warning code, then write buffer in reverse order */ output_nybble(outfile,0xF); if (b==0) { if (bits_to_go3>0) { /* * put out the last few bits */ output_nbits(outfile, bitbuffer & ((1<0) { /* * put out the last few bits */ output_nbits(outfile, bitbuffer & ((1<=0; i--) { output_nbits(outfile,buffer[i],8); } } bitplane_done: ; } free(buffer); free(scratch); return(0); } /* ######################################################################### */ /* * copy non-zero codes from array to buffer */ static int bufcopy(unsigned char a[], int n, unsigned char buffer[], int *b, int bmax) { int i; for (i = 0; i < n; i++) { if (a[i] != 0) { /* * add Huffman code for a[i] to buffer */ bitbuffer |= code[a[i]] << bits_to_go3; bits_to_go3 += ncode[a[i]]; if (bits_to_go3 >= 8) { buffer[*b] = bitbuffer & 0xFF; *b += 1; /* * return warning code if we fill buffer */ if (*b >= bmax) return(1); bitbuffer >>= 8; bits_to_go3 -= 8; } } } return(0); } /* ######################################################################### */ /* * Do first quadtree reduction step on bit BIT of array A. * Results put into B. * */ static void qtree_onebit(int a[], int n, int nx, int ny, unsigned char b[], int bit) { int i, j, k; int b0, b1, b2, b3; int s10, s00; /* * use selected bit to get amount to shift */ b0 = 1<> bit; k += 1; s00 += 2; s10 += 2; } if (j < ny) { /* * row size is odd, do last element in row * s00+1,s10+1 are off edge */ b[k] = ( ((a[s10 ]<<1) & b1) | ((a[s00 ]<<3) & b3) ) >> bit; k += 1; } } if (i < nx) { /* * column size is odd, do last row * s10,s10+1 are off edge */ s00 = n*i; for (j = 0; j> bit; k += 1; s00 += 2; } if (j < ny) { /* * both row and column size are odd, do corner element * s00+1, s10, s10+1 are off edge */ b[k] = ( ((a[s00 ]<<3) & b3) ) >> bit; k += 1; } } } /* ######################################################################### */ /* * Do first quadtree reduction step on bit BIT of array A. * Results put into B. * */ static void qtree_onebit64(LONGLONG a[], int n, int nx, int ny, unsigned char b[], int bit) { int i, j, k; LONGLONG b0, b1, b2, b3; int s10, s00; /* * use selected bit to get amount to shift */ b0 = ((LONGLONG) 1)<> bit); k += 1; s00 += 2; s10 += 2; } if (j < ny) { /* * row size is odd, do last element in row * s00+1,s10+1 are off edge */ b[k] = (unsigned char) (( ((a[s10 ]<<1) & b1) | ((a[s00 ]<<3) & b3) ) >> bit); k += 1; } } if (i < nx) { /* * column size is odd, do last row * s10,s10+1 are off edge */ s00 = n*i; for (j = 0; j> bit); k += 1; s00 += 2; } if (j < ny) { /* * both row and column size are odd, do corner element * s00+1, s10, s10+1 are off edge */ b[k] = (unsigned char) (( ((a[s00 ]<<3) & b3) ) >> bit); k += 1; } } } /* ######################################################################### */ /* * do one quadtree reduction step on array a * results put into b (which may be the same as a) */ static void qtree_reduce(unsigned char a[], int n, int nx, int ny, unsigned char b[]) { int i, j, k; int s10, s00; k = 0; /* k is index of b[i/2,j/2] */ for (i = 0; i #include #include #include #include "fitsio2.h" /* WDP added test to see if min and max are already defined */ #ifndef min #define min(a,b) (((a)<(b))?(a):(b)) #endif #ifndef max #define max(a,b) (((a)>(b))?(a):(b)) #endif static long nextchar; static int decode(unsigned char *infile, int *a, int *nx, int *ny, int *scale); static int decode64(unsigned char *infile, LONGLONG *a, int *nx, int *ny, int *scale); static int hinv(int a[], int nx, int ny, int smooth ,int scale); static int hinv64(LONGLONG a[], int nx, int ny, int smooth ,int scale); static void undigitize(int a[], int nx, int ny, int scale); static void undigitize64(LONGLONG a[], int nx, int ny, int scale); static void unshuffle(int a[], int n, int n2, int tmp[]); static void unshuffle64(LONGLONG a[], int n, int n2, LONGLONG tmp[]); static void hsmooth(int a[], int nxtop, int nytop, int ny, int scale); static void hsmooth64(LONGLONG a[], int nxtop, int nytop, int ny, int scale); static void qread(unsigned char *infile,char *a, int n); static int readint(unsigned char *infile); static LONGLONG readlonglong(unsigned char *infile); static int dodecode(unsigned char *infile, int a[], int nx, int ny, unsigned char nbitplanes[3]); static int dodecode64(unsigned char *infile, LONGLONG a[], int nx, int ny, unsigned char nbitplanes[3]); static int qtree_decode(unsigned char *infile, int a[], int n, int nqx, int nqy, int nbitplanes); static int qtree_decode64(unsigned char *infile, LONGLONG a[], int n, int nqx, int nqy, int nbitplanes); static void start_inputing_bits(void); static int input_bit(unsigned char *infile); static int input_nbits(unsigned char *infile, int n); /* make input_nybble a separate routine, for added effiency */ /* #define input_nybble(infile) input_nbits(infile,4) */ static int input_nybble(unsigned char *infile); static int input_nnybble(unsigned char *infile, int n, unsigned char *array); static void qtree_expand(unsigned char *infile, unsigned char a[], int nx, int ny, unsigned char b[]); static void qtree_bitins(unsigned char a[], int nx, int ny, int b[], int n, int bit); static void qtree_bitins64(unsigned char a[], int nx, int ny, LONGLONG b[], int n, int bit); static void qtree_copy(unsigned char a[], int nx, int ny, unsigned char b[], int n); static void read_bdirect(unsigned char *infile, int a[], int n, int nqx, int nqy, unsigned char scratch[], int bit); static void read_bdirect64(unsigned char *infile, LONGLONG a[], int n, int nqx, int nqy, unsigned char scratch[], int bit); static int input_huffman(unsigned char *infile); /* ---------------------------------------------------------------------- */ int fits_hdecompress(unsigned char *input, int smooth, int *a, int *ny, int *nx, int *scale, int *status) { /* decompress the input byte stream using the H-compress algorithm input - input array of compressed bytes a - pre-allocated array to hold the output uncompressed image nx - returned X axis size ny - returned Y axis size NOTE: the nx and ny dimensions as defined within this code are reversed from the usual FITS notation. ny is the fastest varying dimension, which is usually considered the X axis in the FITS image display */ int stat; if (*status > 0) return(*status); /* decode the input array */ FFLOCK; /* decode uses the nextchar global variable */ stat = decode(input, a, nx, ny, scale); FFUNLOCK; *status = stat; if (stat) return(*status); /* * Un-Digitize */ undigitize(a, *nx, *ny, *scale); /* * Inverse H-transform */ stat = hinv(a, *nx, *ny, smooth, *scale); *status = stat; return(*status); } /* ---------------------------------------------------------------------- */ int fits_hdecompress64(unsigned char *input, int smooth, LONGLONG *a, int *ny, int *nx, int *scale, int *status) { /* decompress the input byte stream using the H-compress algorithm input - input array of compressed bytes a - pre-allocated array to hold the output uncompressed image nx - returned X axis size ny - returned Y axis size NOTE: the nx and ny dimensions as defined within this code are reversed from the usual FITS notation. ny is the fastest varying dimension, which is usually considered the X axis in the FITS image display */ int stat, *iarray, ii, nval; if (*status > 0) return(*status); /* decode the input array */ FFLOCK; /* decode uses the nextchar global variable */ stat = decode64(input, a, nx, ny, scale); FFUNLOCK; *status = stat; if (stat) return(*status); /* * Un-Digitize */ undigitize64(a, *nx, *ny, *scale); /* * Inverse H-transform */ stat = hinv64(a, *nx, *ny, smooth, *scale); *status = stat; /* pack the I*8 values back into an I*4 array */ iarray = (int *) a; nval = (*nx) * (*ny); for (ii = 0; ii < nval; ii++) iarray[ii] = (int) a[ii]; return(*status); } /* ############################################################################ */ /* ############################################################################ */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* hinv.c Inverse H-transform of NX x NY integer image * * Programmer: R. White Date: 23 July 1993 */ /* ############################################################################ */ static int hinv(int a[], int nx, int ny, int smooth ,int scale) /* int smooth; 0 for no smoothing, else smooth during inversion int scale; used if smoothing is specified */ { int nmax, log2n, i, j, k; int nxtop,nytop,nxf,nyf,c; int oddx,oddy; int shift, bit0, bit1, bit2, mask0, mask1, mask2, prnd0, prnd1, prnd2, nrnd0, nrnd1, nrnd2, lowbit0, lowbit1; int h0, hx, hy, hc; int s10, s00; int *tmp; /* * log2n is log2 of max(nx,ny) rounded up to next power of 2 */ nmax = (nx>ny) ? nx : ny; log2n = (int) (log((float) nmax)/log(2.0)+0.5); if ( nmax > (1<> 1; prnd1 = bit1 >> 1; prnd2 = bit2 >> 1; nrnd0 = prnd0 - 1; nrnd1 = prnd1 - 1; nrnd2 = prnd2 - 1; /* * round h0 to multiple of bit2 */ a[0] = (a[0] + ((a[0] >= 0) ? prnd2 : nrnd2)) & mask2; /* * do log2n expansions * * We're indexing a as a 2-D array with dimensions (nx,ny). */ nxtop = 1; nytop = 1; nxf = nx; nyf = ny; c = 1<=0; k--) { /* * this somewhat cryptic code generates the sequence * ntop[k-1] = (ntop[k]+1)/2, where ntop[log2n] = n */ c = c>>1; nxtop = nxtop<<1; nytop = nytop<<1; if (nxf <= c) { nxtop -= 1; } else { nxf -= c; } if (nyf <= c) { nytop -= 1; } else { nyf -= c; } /* * double shift and fix nrnd0 (because prnd0=0) on last pass */ if (k == 0) { nrnd0 = 0; shift = 2; } /* * unshuffle in each dimension to interleave coefficients */ for (i = 0; i= 0) ? prnd1 : nrnd1)) & mask1; hy = (hy + ((hy >= 0) ? prnd1 : nrnd1)) & mask1; hc = (hc + ((hc >= 0) ? prnd0 : nrnd0)) & mask0; /* * propagate bit0 of hc to hx,hy */ lowbit0 = hc & bit0; hx = (hx >= 0) ? (hx - lowbit0) : (hx + lowbit0); hy = (hy >= 0) ? (hy - lowbit0) : (hy + lowbit0); /* * Propagate bits 0 and 1 of hc,hx,hy to h0. * This could be simplified if we assume h0>0, but then * the inversion would not be lossless for images with * negative pixels. */ lowbit1 = (hc ^ hx ^ hy) & bit1; h0 = (h0 >= 0) ? (h0 + lowbit0 - lowbit1) : (h0 + ((lowbit0 == 0) ? lowbit1 : (lowbit0-lowbit1))); /* * Divide sums by 2 (4 last time) */ a[s10+1] = (h0 + hx + hy + hc) >> shift; a[s10 ] = (h0 + hx - hy - hc) >> shift; a[s00+1] = (h0 - hx + hy - hc) >> shift; a[s00 ] = (h0 - hx - hy + hc) >> shift; s00 += 2; s10 += 2; } if (oddy) { /* * do last element in row if row length is odd * s00+1, s10+1 are off edge */ h0 = a[s00 ]; hx = a[s10 ]; hx = ((hx >= 0) ? (hx+prnd1) : (hx+nrnd1)) & mask1; lowbit1 = hx & bit1; h0 = (h0 >= 0) ? (h0 - lowbit1) : (h0 + lowbit1); a[s10 ] = (h0 + hx) >> shift; a[s00 ] = (h0 - hx) >> shift; } } if (oddx) { /* * do last row if column length is odd * s10, s10+1 are off edge */ s00 = ny*i; for (j = 0; j= 0) ? (hy+prnd1) : (hy+nrnd1)) & mask1; lowbit1 = hy & bit1; h0 = (h0 >= 0) ? (h0 - lowbit1) : (h0 + lowbit1); a[s00+1] = (h0 + hy) >> shift; a[s00 ] = (h0 - hy) >> shift; s00 += 2; } if (oddy) { /* * do corner element if both row and column lengths are odd * s00+1, s10, s10+1 are off edge */ h0 = a[s00 ]; a[s00 ] = h0 >> shift; } } /* * divide all the masks and rounding values by 2 */ bit2 = bit1; bit1 = bit0; bit0 = bit0 >> 1; mask1 = mask0; mask0 = mask0 >> 1; prnd1 = prnd0; prnd0 = prnd0 >> 1; nrnd1 = nrnd0; nrnd0 = prnd0 - 1; } free(tmp); return(0); } /* ############################################################################ */ static int hinv64(LONGLONG a[], int nx, int ny, int smooth ,int scale) /* int smooth; 0 for no smoothing, else smooth during inversion int scale; used if smoothing is specified */ { int nmax, log2n, i, j, k; int nxtop,nytop,nxf,nyf,c; int oddx,oddy; int shift; LONGLONG mask0, mask1, mask2, prnd0, prnd1, prnd2, bit0, bit1, bit2; LONGLONG nrnd0, nrnd1, nrnd2, lowbit0, lowbit1; LONGLONG h0, hx, hy, hc; int s10, s00; LONGLONG *tmp; /* * log2n is log2 of max(nx,ny) rounded up to next power of 2 */ nmax = (nx>ny) ? nx : ny; log2n = (int) (log((float) nmax)/log(2.0)+0.5); if ( nmax > (1<> 1; prnd1 = bit1 >> 1; prnd2 = bit2 >> 1; nrnd0 = prnd0 - 1; nrnd1 = prnd1 - 1; nrnd2 = prnd2 - 1; /* * round h0 to multiple of bit2 */ a[0] = (a[0] + ((a[0] >= 0) ? prnd2 : nrnd2)) & mask2; /* * do log2n expansions * * We're indexing a as a 2-D array with dimensions (nx,ny). */ nxtop = 1; nytop = 1; nxf = nx; nyf = ny; c = 1<=0; k--) { /* * this somewhat cryptic code generates the sequence * ntop[k-1] = (ntop[k]+1)/2, where ntop[log2n] = n */ c = c>>1; nxtop = nxtop<<1; nytop = nytop<<1; if (nxf <= c) { nxtop -= 1; } else { nxf -= c; } if (nyf <= c) { nytop -= 1; } else { nyf -= c; } /* * double shift and fix nrnd0 (because prnd0=0) on last pass */ if (k == 0) { nrnd0 = 0; shift = 2; } /* * unshuffle in each dimension to interleave coefficients */ for (i = 0; i= 0) ? prnd1 : nrnd1)) & mask1; hy = (hy + ((hy >= 0) ? prnd1 : nrnd1)) & mask1; hc = (hc + ((hc >= 0) ? prnd0 : nrnd0)) & mask0; /* * propagate bit0 of hc to hx,hy */ lowbit0 = hc & bit0; hx = (hx >= 0) ? (hx - lowbit0) : (hx + lowbit0); hy = (hy >= 0) ? (hy - lowbit0) : (hy + lowbit0); /* * Propagate bits 0 and 1 of hc,hx,hy to h0. * This could be simplified if we assume h0>0, but then * the inversion would not be lossless for images with * negative pixels. */ lowbit1 = (hc ^ hx ^ hy) & bit1; h0 = (h0 >= 0) ? (h0 + lowbit0 - lowbit1) : (h0 + ((lowbit0 == 0) ? lowbit1 : (lowbit0-lowbit1))); /* * Divide sums by 2 (4 last time) */ a[s10+1] = (h0 + hx + hy + hc) >> shift; a[s10 ] = (h0 + hx - hy - hc) >> shift; a[s00+1] = (h0 - hx + hy - hc) >> shift; a[s00 ] = (h0 - hx - hy + hc) >> shift; s00 += 2; s10 += 2; } if (oddy) { /* * do last element in row if row length is odd * s00+1, s10+1 are off edge */ h0 = a[s00 ]; hx = a[s10 ]; hx = ((hx >= 0) ? (hx+prnd1) : (hx+nrnd1)) & mask1; lowbit1 = hx & bit1; h0 = (h0 >= 0) ? (h0 - lowbit1) : (h0 + lowbit1); a[s10 ] = (h0 + hx) >> shift; a[s00 ] = (h0 - hx) >> shift; } } if (oddx) { /* * do last row if column length is odd * s10, s10+1 are off edge */ s00 = ny*i; for (j = 0; j= 0) ? (hy+prnd1) : (hy+nrnd1)) & mask1; lowbit1 = hy & bit1; h0 = (h0 >= 0) ? (h0 - lowbit1) : (h0 + lowbit1); a[s00+1] = (h0 + hy) >> shift; a[s00 ] = (h0 - hy) >> shift; s00 += 2; } if (oddy) { /* * do corner element if both row and column lengths are odd * s00+1, s10, s10+1 are off edge */ h0 = a[s00 ]; a[s00 ] = h0 >> shift; } } /* * divide all the masks and rounding values by 2 */ bit2 = bit1; bit1 = bit0; bit0 = bit0 >> 1; mask1 = mask0; mask0 = mask0 >> 1; prnd1 = prnd0; prnd0 = prnd0 >> 1; nrnd1 = nrnd0; nrnd0 = prnd0 - 1; } free(tmp); return(0); } /* ############################################################################ */ static void unshuffle(int a[], int n, int n2, int tmp[]) /* int a[]; array to shuffle int n; number of elements to shuffle int n2; second dimension int tmp[]; scratch storage */ { int i; int nhalf; int *p1, *p2, *pt; /* * copy 2nd half of array to tmp */ nhalf = (n+1)>>1; pt = tmp; p1 = &a[n2*nhalf]; /* pointer to a[i] */ for (i=nhalf; i= 0; i--) { *p1 = *p2; p2 -= n2; p1 -= (n2+n2); } /* * now distribute 2nd half of array (in tmp) to odd elements */ pt = tmp; p1 = &a[n2]; /* pointer to a[i] */ for (i=1; i>1; pt = tmp; p1 = &a[n2*nhalf]; /* pointer to a[i] */ for (i=nhalf; i= 0; i--) { *p1 = *p2; p2 -= n2; p1 -= (n2+n2); } /* * now distribute 2nd half of array (in tmp) to odd elements */ pt = tmp; p1 = &a[n2]; /* pointer to a[i] */ for (i=1; i> 1); if (smax <= 0) return; ny2 = ny << 1; /* * We're indexing a as a 2-D array with dimensions (nxtop,ny) of which * only (nxtop,nytop) are used. The coefficients on the edge of the * array are not adjusted (which is why the loops below start at 2 * instead of 0 and end at nxtop-2 instead of nxtop.) */ /* * Adjust x difference hx */ for (i = 2; i=0, dmin<=0. */ if (dmin < dmax) { diff = max( min(diff, dmax), dmin); /* * Compute change in slope limited to range +/- smax. * Careful with rounding negative numbers when using * shift for divide by 8. */ s = diff-(a[s10]<<3); s = (s>=0) ? (s>>3) : ((s+7)>>3) ; s = max( min(s, smax), -smax); a[s10] = a[s10]+s; } s00 += 2; s10 += 2; } } /* * Adjust y difference hy */ for (i = 0; i=0) ? (s>>3) : ((s+7)>>3) ; s = max( min(s, smax), -smax); a[s00+1] = a[s00+1]+s; } s00 += 2; s10 += 2; } } /* * Adjust curvature difference hc */ for (i = 2; i=0, dmin<=0. */ if (dmin < dmax) { diff = max( min(diff, dmax), dmin); /* * Compute change in slope limited to range +/- smax. * Careful with rounding negative numbers when using * shift for divide by 64. */ s = diff-(a[s10+1]<<6); s = (s>=0) ? (s>>6) : ((s+63)>>6) ; s = max( min(s, smax), -smax); a[s10+1] = a[s10+1]+s; } s00 += 2; s10 += 2; } } } /* ############################################################################ */ static void hsmooth64(LONGLONG a[], int nxtop, int nytop, int ny, int scale) /* LONGLONG a[]; array of H-transform coefficients int nxtop,nytop; size of coefficient block to use int ny; actual 1st dimension of array int scale; truncation scale factor that was used */ { int i, j; int ny2, s10, s00; LONGLONG hm, h0, hp, hmm, hpm, hmp, hpp, hx2, hy2, diff, dmax, dmin, s, smax, m1, m2; /* * Maximum change in coefficients is determined by scale factor. * Since we rounded during division (see digitize.c), the biggest * permitted change is scale/2. */ smax = (scale >> 1); if (smax <= 0) return; ny2 = ny << 1; /* * We're indexing a as a 2-D array with dimensions (nxtop,ny) of which * only (nxtop,nytop) are used. The coefficients on the edge of the * array are not adjusted (which is why the loops below start at 2 * instead of 0 and end at nxtop-2 instead of nxtop.) */ /* * Adjust x difference hx */ for (i = 2; i=0, dmin<=0. */ if (dmin < dmax) { diff = max( min(diff, dmax), dmin); /* * Compute change in slope limited to range +/- smax. * Careful with rounding negative numbers when using * shift for divide by 8. */ s = diff-(a[s10]<<3); s = (s>=0) ? (s>>3) : ((s+7)>>3) ; s = max( min(s, smax), -smax); a[s10] = a[s10]+s; } s00 += 2; s10 += 2; } } /* * Adjust y difference hy */ for (i = 0; i=0) ? (s>>3) : ((s+7)>>3) ; s = max( min(s, smax), -smax); a[s00+1] = a[s00+1]+s; } s00 += 2; s10 += 2; } } /* * Adjust curvature difference hc */ for (i = 2; i=0, dmin<=0. */ if (dmin < dmax) { diff = max( min(diff, dmax), dmin); /* * Compute change in slope limited to range +/- smax. * Careful with rounding negative numbers when using * shift for divide by 64. */ s = diff-(a[s10+1]<<6); s = (s>=0) ? (s>>6) : ((s+63)>>6) ; s = max( min(s, smax), -smax); a[s10+1] = a[s10+1]+s; } s00 += 2; s10 += 2; } } } /* ############################################################################ */ /* ############################################################################ */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* undigitize.c undigitize H-transform * * Programmer: R. White Date: 9 May 1991 */ /* ############################################################################ */ static void undigitize(int a[], int nx, int ny, int scale) { int *p; /* * multiply by scale */ if (scale <= 1) return; for (p=a; p <= &a[nx*ny-1]; p++) *p = (*p)*scale; } /* ############################################################################ */ static void undigitize64(LONGLONG a[], int nx, int ny, int scale) { LONGLONG *p, scale64; /* * multiply by scale */ if (scale <= 1) return; scale64 = (LONGLONG) scale; /* use a 64-bit int for efficiency in the big loop */ for (p=a; p <= &a[nx*ny-1]; p++) *p = (*p)*scale64; } /* ############################################################################ */ /* ############################################################################ */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* decode.c read codes from infile and construct array * * Programmer: R. White Date: 2 February 1994 */ static char code_magic[2] = { (char)0xDD, (char)0x99 }; /* ############################################################################ */ static int decode(unsigned char *infile, int *a, int *nx, int *ny, int *scale) /* char *infile; input file int *a; address of output array [nx][ny] int *nx,*ny; size of output array int *scale; scale factor for digitization */ { LONGLONG sumall; int stat; unsigned char nbitplanes[3]; char tmagic[2]; /* initialize the byte read position to the beginning of the array */; nextchar = 0; /* * File starts either with special 2-byte magic code or with * FITS keyword "SIMPLE =" */ qread(infile, tmagic, sizeof(tmagic)); /* * check for correct magic code value */ if (memcmp(tmagic,code_magic,sizeof(code_magic)) != 0) { ffpmsg("bad file format"); return(DATA_DECOMPRESSION_ERR); } *nx =readint(infile); /* x size of image */ *ny =readint(infile); /* y size of image */ *scale=readint(infile); /* scale factor for digitization */ /* sum of all pixels */ sumall=readlonglong(infile); /* # bits in quadrants */ qread(infile, (char *) nbitplanes, sizeof(nbitplanes)); stat = dodecode(infile, a, *nx, *ny, nbitplanes); /* * put sum of all pixels back into pixel 0 */ a[0] = (int) sumall; return(stat); } /* ############################################################################ */ static int decode64(unsigned char *infile, LONGLONG *a, int *nx, int *ny, int *scale) /* char *infile; input file LONGLONG *a; address of output array [nx][ny] int *nx,*ny; size of output array int *scale; scale factor for digitization */ { int stat; LONGLONG sumall; unsigned char nbitplanes[3]; char tmagic[2]; /* initialize the byte read position to the beginning of the array */; nextchar = 0; /* * File starts either with special 2-byte magic code or with * FITS keyword "SIMPLE =" */ qread(infile, tmagic, sizeof(tmagic)); /* * check for correct magic code value */ if (memcmp(tmagic,code_magic,sizeof(code_magic)) != 0) { ffpmsg("bad file format"); return(DATA_DECOMPRESSION_ERR); } *nx =readint(infile); /* x size of image */ *ny =readint(infile); /* y size of image */ *scale=readint(infile); /* scale factor for digitization */ /* sum of all pixels */ sumall=readlonglong(infile); /* # bits in quadrants */ qread(infile, (char *) nbitplanes, sizeof(nbitplanes)); stat = dodecode64(infile, a, *nx, *ny, nbitplanes); /* * put sum of all pixels back into pixel 0 */ a[0] = sumall; return(stat); } /* ############################################################################ */ /* ############################################################################ */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* dodecode.c Decode stream of characters on infile and return array * * This version encodes the different quadrants separately * * Programmer: R. White Date: 9 May 1991 */ /* ############################################################################ */ static int dodecode(unsigned char *infile, int a[], int nx, int ny, unsigned char nbitplanes[3]) /* int a[]; int nx,ny; Array dimensions are [nx][ny] unsigned char nbitplanes[3]; Number of bit planes in quadrants */ { int i, nel, nx2, ny2, stat; nel = nx*ny; nx2 = (nx+1)/2; ny2 = (ny+1)/2; /* * initialize a to zero */ for (i=0; inqy) ? nqx : nqy; log2n = (int) (log((float) nqmax)/log(2.0)+0.5); if (nqmax > (1<= 0; bit--) { /* * Was bitplane was quadtree-coded or written directly? */ b = input_nybble(infile); if(b == 0) { /* * bit map was written directly */ read_bdirect(infile,a,n,nqx,nqy,scratch,bit); } else if (b != 0xf) { ffpmsg("qtree_decode: bad format code"); return(DATA_DECOMPRESSION_ERR); } else { /* * bitmap was quadtree-coded, do log2n expansions * * read first code */ scratch[0] = input_huffman(infile); /* * now do log2n expansions, reading codes from file as necessary */ nx = 1; ny = 1; nfx = nqx; nfy = nqy; c = 1<>1; nx = nx<<1; ny = ny<<1; if (nfx <= c) { nx -= 1; } else { nfx -= c; } if (nfy <= c) { ny -= 1; } else { nfy -= c; } qtree_expand(infile,scratch,nx,ny,scratch); } /* * now copy last set of 4-bit codes to bitplane bit of array a */ qtree_bitins(scratch,nqx,nqy,a,n,bit); } } free(scratch); return(0); } /* ############################################################################ */ static int qtree_decode64(unsigned char *infile, LONGLONG a[], int n, int nqx, int nqy, int nbitplanes) /* char *infile; LONGLONG a[]; a is 2-D array with dimensions (n,n) int n; length of full row in a int nqx; partial length of row to decode int nqy; partial length of column (<=n) int nbitplanes; number of bitplanes to decode */ { int log2n, k, bit, b, nqmax; int nx,ny,nfx,nfy,c; int nqx2, nqy2; unsigned char *scratch; /* * log2n is log2 of max(nqx,nqy) rounded up to next power of 2 */ nqmax = (nqx>nqy) ? nqx : nqy; log2n = (int) (log((float) nqmax)/log(2.0)+0.5); if (nqmax > (1<= 0; bit--) { /* * Was bitplane was quadtree-coded or written directly? */ b = input_nybble(infile); if(b == 0) { /* * bit map was written directly */ read_bdirect64(infile,a,n,nqx,nqy,scratch,bit); } else if (b != 0xf) { ffpmsg("qtree_decode64: bad format code"); return(DATA_DECOMPRESSION_ERR); } else { /* * bitmap was quadtree-coded, do log2n expansions * * read first code */ scratch[0] = input_huffman(infile); /* * now do log2n expansions, reading codes from file as necessary */ nx = 1; ny = 1; nfx = nqx; nfy = nqy; c = 1<>1; nx = nx<<1; ny = ny<<1; if (nfx <= c) { nx -= 1; } else { nfx -= c; } if (nfy <= c) { ny -= 1; } else { nfy -= c; } qtree_expand(infile,scratch,nx,ny,scratch); } /* * now copy last set of 4-bit codes to bitplane bit of array a */ qtree_bitins64(scratch,nqx,nqy,a,n,bit); } } free(scratch); return(0); } /* ############################################################################ */ /* * do one quadtree expansion step on array a[(nqx+1)/2,(nqy+1)/2] * results put into b[nqx,nqy] (which may be the same as a) */ static void qtree_expand(unsigned char *infile, unsigned char a[], int nx, int ny, unsigned char b[]) { int i; /* * first copy a to b, expanding each 4-bit value */ qtree_copy(a,nx,ny,b,ny); /* * now read new 4-bit values into b for each non-zero element */ for (i = nx*ny-1; i >= 0; i--) { if (b[i]) b[i] = input_huffman(infile); } } /* ############################################################################ */ /* * copy 4-bit values from a[(nx+1)/2,(ny+1)/2] to b[nx,ny], expanding * each value to 2x2 pixels * a,b may be same array */ static void qtree_copy(unsigned char a[], int nx, int ny, unsigned char b[], int n) /* int n; declared y dimension of b */ { int i, j, k, nx2, ny2; int s00, s10; /* * first copy 4-bit values to b * start at end in case a,b are same array */ nx2 = (nx+1)/2; ny2 = (ny+1)/2; k = ny2*(nx2-1)+ny2-1; /* k is index of a[i,j] */ for (i = nx2-1; i >= 0; i--) { s00 = 2*(n*i+ny2-1); /* s00 is index of b[2*i,2*j] */ for (j = ny2-1; j >= 0; j--) { b[s00] = a[k]; k -= 1; s00 -= 2; } } /* * now expand each 2x2 block */ for (i = 0; i>1) & 1; b[s00+1] = (b[s00]>>2) & 1; b[s00 ] = (b[s00]>>3) & 1; */ s00 += 2; s10 += 2; } if (j < ny) { /* * row size is odd, do last element in row * s00+1, s10+1 are off edge */ /* not worth converting this to use 16 case statements */ b[s10 ] = (b[s00]>>1) & 1; b[s00 ] = (b[s00]>>3) & 1; } } if (i < nx) { /* * column size is odd, do last row * s10, s10+1 are off edge */ s00 = n*i; for (j = 0; j>2) & 1; b[s00 ] = (b[s00]>>3) & 1; s00 += 2; } if (j < ny) { /* * both row and column size are odd, do corner element * s00+1, s10, s10+1 are off edge */ /* not worth converting this to use 16 case statements */ b[s00 ] = (b[s00]>>3) & 1; } } } /* ############################################################################ */ /* * Copy 4-bit values from a[(nx+1)/2,(ny+1)/2] to b[nx,ny], expanding * each value to 2x2 pixels and inserting into bitplane BIT of B. * A,B may NOT be same array (it wouldn't make sense to be inserting * bits into the same array anyway.) */ static void qtree_bitins(unsigned char a[], int nx, int ny, int b[], int n, int bit) /* int n; declared y dimension of b */ { int i, j, k; int s00; int plane_val; plane_val = 1 << bit; /* * expand each 2x2 block */ k = 0; /* k is index of a[i/2,j/2] */ for (i = 0; i>1) & 1) << bit; b[s00+1] |= ((a[k]>>2) & 1) << bit; b[s00 ] |= ((a[k]>>3) & 1) << bit; */ s00 += 2; /* s10 += 2; */ k += 1; } if (j < ny) { /* * row size is odd, do last element in row * s00+1, s10+1 are off edge */ switch (a[k]) { case(0): break; case(1): break; case(2): b[s00+n ] |= plane_val; break; case(3): b[s00+n ] |= plane_val; break; case(4): break; case(5): break; case(6): b[s00+n ] |= plane_val; break; case(7): b[s00+n ] |= plane_val; break; case(8): b[s00 ] |= plane_val; break; case(9): b[s00 ] |= plane_val; break; case(10): b[s00+n ] |= plane_val; b[s00 ] |= plane_val; break; case(11): b[s00+n ] |= plane_val; b[s00 ] |= plane_val; break; case(12): b[s00 ] |= plane_val; break; case(13): b[s00 ] |= plane_val; break; case(14): b[s00+n ] |= plane_val; b[s00 ] |= plane_val; break; case(15): b[s00+n ] |= plane_val; b[s00 ] |= plane_val; break; } /* b[s10 ] |= ((a[k]>>1) & 1) << bit; b[s00 ] |= ((a[k]>>3) & 1) << bit; */ k += 1; } } if (i < nx) { /* * column size is odd, do last row * s10, s10+1 are off edge */ s00 = n*i; for (j = 0; j>2) & 1) << bit; b[s00 ] |= ((a[k]>>3) & 1) << bit; */ s00 += 2; k += 1; } if (j < ny) { /* * both row and column size are odd, do corner element * s00+1, s10, s10+1 are off edge */ switch (a[k]) { case(0): break; case(1): break; case(2): break; case(3): break; case(4): break; case(5): break; case(6): break; case(7): break; case(8): b[s00 ] |= plane_val; break; case(9): b[s00 ] |= plane_val; break; case(10): b[s00 ] |= plane_val; break; case(11): b[s00 ] |= plane_val; break; case(12): b[s00 ] |= plane_val; break; case(13): b[s00 ] |= plane_val; break; case(14): b[s00 ] |= plane_val; break; case(15): b[s00 ] |= plane_val; break; } /* b[s00 ] |= ((a[k]>>3) & 1) << bit; */ k += 1; } } } /* ############################################################################ */ /* * Copy 4-bit values from a[(nx+1)/2,(ny+1)/2] to b[nx,ny], expanding * each value to 2x2 pixels and inserting into bitplane BIT of B. * A,B may NOT be same array (it wouldn't make sense to be inserting * bits into the same array anyway.) */ static void qtree_bitins64(unsigned char a[], int nx, int ny, LONGLONG b[], int n, int bit) /* int n; declared y dimension of b */ { int i, j, k; int s00; LONGLONG plane_val; plane_val = ((LONGLONG) 1) << bit; /* * expand each 2x2 block */ k = 0; /* k is index of a[i/2,j/2] */ for (i = 0; i>1) & 1) << bit; b[s00+1] |= ((((LONGLONG)a[k])>>2) & 1) << bit; b[s00 ] |= ((((LONGLONG)a[k])>>3) & 1) << bit; */ s00 += 2; /* s10 += 2; */ k += 1; } if (j < ny) { /* * row size is odd, do last element in row * s00+1, s10+1 are off edge */ switch (a[k]) { case(0): break; case(1): break; case(2): b[s00+n ] |= plane_val; break; case(3): b[s00+n ] |= plane_val; break; case(4): break; case(5): break; case(6): b[s00+n ] |= plane_val; break; case(7): b[s00+n ] |= plane_val; break; case(8): b[s00 ] |= plane_val; break; case(9): b[s00 ] |= plane_val; break; case(10): b[s00+n ] |= plane_val; b[s00 ] |= plane_val; break; case(11): b[s00+n ] |= plane_val; b[s00 ] |= plane_val; break; case(12): b[s00 ] |= plane_val; break; case(13): b[s00 ] |= plane_val; break; case(14): b[s00+n ] |= plane_val; b[s00 ] |= plane_val; break; case(15): b[s00+n ] |= plane_val; b[s00 ] |= plane_val; break; } /* b[s10 ] |= ((((LONGLONG)a[k])>>1) & 1) << bit; b[s00 ] |= ((((LONGLONG)a[k])>>3) & 1) << bit; */ k += 1; } } if (i < nx) { /* * column size is odd, do last row * s10, s10+1 are off edge */ s00 = n*i; for (j = 0; j>2) & 1) << bit; b[s00 ] |= ((((LONGLONG)a[k])>>3) & 1) << bit; */ s00 += 2; k += 1; } if (j < ny) { /* * both row and column size are odd, do corner element * s00+1, s10, s10+1 are off edge */ switch (a[k]) { case(0): break; case(1): break; case(2): break; case(3): break; case(4): break; case(5): break; case(6): break; case(7): break; case(8): b[s00 ] |= plane_val; break; case(9): b[s00 ] |= plane_val; break; case(10): b[s00 ] |= plane_val; break; case(11): b[s00 ] |= plane_val; break; case(12): b[s00 ] |= plane_val; break; case(13): b[s00 ] |= plane_val; break; case(14): b[s00 ] |= plane_val; break; case(15): b[s00 ] |= plane_val; break; } /* b[s00 ] |= ((((LONGLONG)a[k])>>3) & 1) << bit; */ k += 1; } } } /* ############################################################################ */ static void read_bdirect(unsigned char *infile, int a[], int n, int nqx, int nqy, unsigned char scratch[], int bit) { /* * read bit image packed 4 pixels/nybble */ /* int i; for (i = 0; i < ((nqx+1)/2) * ((nqy+1)/2); i++) { scratch[i] = input_nybble(infile); } */ input_nnybble(infile, ((nqx+1)/2) * ((nqy+1)/2), scratch); /* * insert in bitplane BIT of image A */ qtree_bitins(scratch,nqx,nqy,a,n,bit); } /* ############################################################################ */ static void read_bdirect64(unsigned char *infile, LONGLONG a[], int n, int nqx, int nqy, unsigned char scratch[], int bit) { /* * read bit image packed 4 pixels/nybble */ /* int i; for (i = 0; i < ((nqx+1)/2) * ((nqy+1)/2); i++) { scratch[i] = input_nybble(infile); } */ input_nnybble(infile, ((nqx+1)/2) * ((nqy+1)/2), scratch); /* * insert in bitplane BIT of image A */ qtree_bitins64(scratch,nqx,nqy,a,n,bit); } /* ############################################################################ */ /* * Huffman decoding for fixed codes * * Coded values range from 0-15 * * Huffman code values (hex): * * 3e, 00, 01, 08, 02, 09, 1a, 1b, * 03, 1c, 0a, 1d, 0b, 1e, 3f, 0c * * and number of bits in each code: * * 6, 3, 3, 4, 3, 4, 5, 5, * 3, 5, 4, 5, 4, 5, 6, 4 */ static int input_huffman(unsigned char *infile) { int c; /* * get first 3 bits to start */ c = input_nbits(infile,3); if (c < 4) { /* * this is all we need * return 1,2,4,8 for c=0,1,2,3 */ return(1<>bits_to_go) & 1); } /* ############################################################################ */ /* INPUT N BITS (N must be <= 8) */ static int input_nbits(unsigned char *infile, int n) { /* AND mask for retreiving the right-most n bits */ static int mask[9] = {0, 1, 3, 7, 15, 31, 63, 127, 255}; if (bits_to_go < n) { /* * need another byte's worth of bits */ buffer2 = (buffer2<<8) | (int) infile[nextchar]; nextchar++; bits_to_go += 8; } /* * now pick off the first n bits */ bits_to_go -= n; /* there was a slight gain in speed by replacing the following line */ /* return( (buffer2>>bits_to_go) & ((1<>bits_to_go) & (*(mask+n)) ); } /* ############################################################################ */ /* INPUT 4 BITS */ static int input_nybble(unsigned char *infile) { if (bits_to_go < 4) { /* * need another byte's worth of bits */ buffer2 = (buffer2<<8) | (int) infile[nextchar]; nextchar++; bits_to_go += 8; } /* * now pick off the first 4 bits */ bits_to_go -= 4; return( (buffer2>>bits_to_go) & 15 ); } /* ############################################################################ */ /* INPUT array of 4 BITS */ static int input_nnybble(unsigned char *infile, int n, unsigned char array[]) { /* copy n 4-bit nybbles from infile to the lower 4 bits of array */ int ii, kk, shift1, shift2; /* forcing byte alignment doesn;t help, and even makes it go slightly slower if (bits_to_go != 8) input_nbits(infile, bits_to_go); */ if (n == 1) { array[0] = input_nybble(infile); return(0); } if (bits_to_go == 8) { /* already have 2 full nybbles in buffer2, so backspace the infile array to reuse last char */ nextchar--; bits_to_go = 0; } /* bits_to_go now has a value in the range 0 - 7. After adding */ /* another byte, bits_to_go effectively will be in range 8 - 15 */ shift1 = bits_to_go + 4; /* shift1 will be in range 4 - 11 */ shift2 = bits_to_go; /* shift2 will be in range 0 - 7 */ kk = 0; /* special case */ if (bits_to_go == 0) { for (ii = 0; ii < n/2; ii++) { /* * refill the buffer with next byte */ buffer2 = (buffer2<<8) | (int) infile[nextchar]; nextchar++; array[kk] = (int) ((buffer2>>4) & 15); array[kk + 1] = (int) ((buffer2) & 15); /* no shift required */ kk += 2; } } else { for (ii = 0; ii < n/2; ii++) { /* * refill the buffer with next byte */ buffer2 = (buffer2<<8) | (int) infile[nextchar]; nextchar++; array[kk] = (int) ((buffer2>>shift1) & 15); array[kk + 1] = (int) ((buffer2>>shift2) & 15); kk += 2; } } if (ii * 2 != n) { /* have to read last odd byte */ array[n-1] = input_nybble(infile); } return( (buffer2>>bits_to_go) & 15 ); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/fitscore.c0000644000175100001710000116054100000000000020115 0ustar00vstsdocker/* This file, fitscore.c, contains the core set of FITSIO routines. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ /* Copyright (Unpublished--all rights reserved under the copyright laws of the United States), U.S. Government as represented by the Administrator of the National Aeronautics and Space Administration. No copyright is claimed in the United States under Title 17, U.S. Code. Permission to freely use, copy, modify, and distribute this software and its documentation without fee is hereby granted, provided that this copyright notice and disclaimer of warranty appears in all copies. DISCLAIMER: THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT SHALL NASA BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, CONTRACT, TORT , OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER." */ #include #include #include #include #include #include /* stddef.h is apparently needed to define size_t with some compilers ?? */ #include #include #include "fitsio2.h" #define errmsgsiz 25 #define ESMARKER 27 /* Escape character is used as error stack marker */ #define DelAll 1 /* delete all messages on the error stack */ #define DelMark 2 /* delete newest messages back to and including marker */ #define DelNewest 3 /* delete the newest message from the stack */ #define GetMesg 4 /* pop and return oldest message, ignoring marks */ #define PutMesg 5 /* add a new message to the stack */ #define PutMark 6 /* add a marker to the stack */ #ifdef _REENTRANT /* Fitsio_Lock and Fitsio_Pthread_Status are declared in fitsio2.h. */ pthread_mutex_t Fitsio_Lock; int Fitsio_Pthread_Status = 0; #endif int STREAM_DRIVER = 0; struct lconv *lcxxx; /*--------------------------------------------------------------------------*/ float ffvers(float *version) /* IO - version number */ /* return the current version number of the FITSIO software */ { *version = (float) 4.0; /* May 2021 Previous releases: *version = 3.49 Aug 2020 *version = 3.48 Apr 2020 *version = 3.47 May 2019 *version = 3.46 Oct 2018 *version = 3.45 May 2018 *version = 3.44 Apr 2018 *version = 3.43 Mar 2018 *version = 3.42 Mar 2017 *version = 3.41 Nov 2016 *version = 3.40 Oct 2016 *version = 3.39 Apr 2016 *version = 3.38 Feb 2016 *version = 3.37 3 Jun 2014 *version = 3.36 6 Dec 2013 *version = 3.35 23 May 2013 *version = 3.34 20 Mar 2013 *version = 3.33 14 Feb 2013 *version = 3.32 Oct 2012 *version = 3.31 18 Jul 2012 *version = 3.30 11 Apr 2012 *version = 3.29 22 Sep 2011 *version = 3.28 12 May 2011 *version = 3.27 3 Mar 2011 *version = 3.26 30 Dec 2010 *version = 3.25 9 June 2010 *version = 3.24 26 Jan 2010 *version = 3.23 7 Jan 2010 *version = 3.22 28 Oct 2009 *version = 3.21 24 Sep 2009 *version = 3.20 31 Aug 2009 *version = 3.18 12 May 2009 (beta version) *version = 3.14 18 Mar 2009 *version = 3.13 5 Jan 2009 *version = 3.12 8 Oct 2008 *version = 3.11 19 Sep 2008 *version = 3.10 20 Aug 2008 *version = 3.09 3 Jun 2008 *version = 3.08 15 Apr 2007 (internal release) *version = 3.07 5 Nov 2007 (internal release) *version = 3.06 27 Aug 2007 *version = 3.05 12 Jul 2007 (internal release) *version = 3.03 11 Dec 2006 *version = 3.02 18 Sep 2006 *version = 3.01 May 2006 included in FTOOLS 6.1 release *version = 3.006 20 Feb 2006 *version = 3.005 20 Dec 2005 (beta, in heasoft swift release *version = 3.004 16 Sep 2005 (beta, in heasoft swift release *version = 3.003 28 Jul 2005 (beta, in heasoft swift release *version = 3.002 15 Apr 2005 (beta) *version = 3.001 15 Mar 2005 (beta) released with heasoft 6.0 *version = 3.000 1 Mar 2005 (internal release only) *version = 2.51 2 Dec 2004 *version = 2.50 28 Jul 2004 *version = 2.49 11 Feb 2004 *version = 2.48 28 Jan 2004 *version = 2.470 18 Aug 2003 *version = 2.460 20 May 2003 *version = 2.450 30 Apr 2003 (internal release only) *version = 2.440 8 Jan 2003 *version = 2.430; 4 Nov 2002 *version = 2.420; 19 Jul 2002 *version = 2.410; 22 Apr 2002 used in ftools v5.2 *version = 2.401; 28 Jan 2002 *version = 2.400; 18 Jan 2002 *version = 2.301; 7 Dec 2001 *version = 2.300; 23 Oct 2001 *version = 2.204; 26 Jul 2001 *version = 2.203; 19 Jul 2001 used in ftools v5.1 *version = 2.202; 22 May 2001 *version = 2.201; 15 Mar 2001 *version = 2.200; 26 Jan 2001 *version = 2.100; 26 Sep 2000 *version = 2.037; 6 Jul 2000 *version = 2.036; 1 Feb 2000 *version = 2.035; 7 Dec 1999 (internal release only) *version = 2.034; 23 Nov 1999 *version = 2.033; 17 Sep 1999 *version = 2.032; 25 May 1999 *version = 2.031; 31 Mar 1999 *version = 2.030; 24 Feb 1999 *version = 2.029; 11 Feb 1999 *version = 2.028; 26 Jan 1999 *version = 2.027; 12 Jan 1999 *version = 2.026; 23 Dec 1998 *version = 2.025; 1 Dec 1998 *version = 2.024; 9 Nov 1998 *version = 2.023; 1 Nov 1998 first full release of V2.0 *version = 1.42; 30 Apr 1998 *version = 1.40; 6 Feb 1998 *version = 1.33; 16 Dec 1997 (internal release only) *version = 1.32; 21 Nov 1997 (internal release only) *version = 1.31; 4 Nov 1997 (internal release only) *version = 1.30; 11 Sep 1997 *version = 1.27; 3 Sep 1997 (internal release only) *version = 1.25; 2 Jul 1997 *version = 1.24; 2 May 1997 *version = 1.23; 24 Apr 1997 *version = 1.22; 18 Apr 1997 *version = 1.21; 26 Mar 1997 *version = 1.2; 29 Jan 1997 *version = 1.11; 04 Dec 1996 *version = 1.101; 13 Nov 1996 *version = 1.1; 6 Nov 1996 *version = 1.04; 17 Sep 1996 *version = 1.03; 20 Aug 1996 *version = 1.02; 15 Aug 1996 *version = 1.01; 12 Aug 1996 */ return(*version); } /*--------------------------------------------------------------------------*/ int ffflnm(fitsfile *fptr, /* I - FITS file pointer */ char *filename, /* O - name of the file */ int *status) /* IO - error status */ /* return the name of the FITS file */ { strcpy(filename,(fptr->Fptr)->filename); return(*status); } /*--------------------------------------------------------------------------*/ int ffflmd(fitsfile *fptr, /* I - FITS file pointer */ int *filemode, /* O - open mode of the file */ int *status) /* IO - error status */ /* return the access mode of the FITS file */ { *filemode = (fptr->Fptr)->writemode; return(*status); } /*--------------------------------------------------------------------------*/ void ffgerr(int status, /* I - error status value */ char *errtext) /* O - error message (max 30 char long + null) */ /* Return a short descriptive error message that corresponds to the input error status value. The message may be up to 30 characters long, plus the terminating null character. */ { errtext[0] = '\0'; if (status >= 0 && status < 300) { switch (status) { case 0: strcpy(errtext, "OK - no error"); break; case 1: strcpy(errtext, "non-CFITSIO program error"); break; case 101: strcpy(errtext, "same input and output files"); break; case 103: strcpy(errtext, "attempt to open too many files"); break; case 104: strcpy(errtext, "could not open the named file"); break; case 105: strcpy(errtext, "couldn't create the named file"); break; case 106: strcpy(errtext, "error writing to FITS file"); break; case 107: strcpy(errtext, "tried to move past end of file"); break; case 108: strcpy(errtext, "error reading from FITS file"); break; case 110: strcpy(errtext, "could not close the file"); break; case 111: strcpy(errtext, "array dimensions too big"); break; case 112: strcpy(errtext, "cannot write to readonly file"); break; case 113: strcpy(errtext, "could not allocate memory"); break; case 114: strcpy(errtext, "invalid fitsfile pointer"); break; case 115: strcpy(errtext, "NULL input pointer"); break; case 116: strcpy(errtext, "error seeking file position"); break; case 117: strcpy(errtext, "bad value for file download timeout setting"); break; case 121: strcpy(errtext, "invalid URL prefix"); break; case 122: strcpy(errtext, "too many I/O drivers"); break; case 123: strcpy(errtext, "I/O driver init failed"); break; case 124: strcpy(errtext, "no I/O driver for this URLtype"); break; case 125: strcpy(errtext, "parse error in input file URL"); break; case 126: strcpy(errtext, "parse error in range list"); break; case 151: strcpy(errtext, "bad argument (shared mem drvr)"); break; case 152: strcpy(errtext, "null ptr arg (shared mem drvr)"); break; case 153: strcpy(errtext, "no free shared memory handles"); break; case 154: strcpy(errtext, "share mem drvr not initialized"); break; case 155: strcpy(errtext, "IPC system error (shared mem)"); break; case 156: strcpy(errtext, "no memory (shared mem drvr)"); break; case 157: strcpy(errtext, "share mem resource deadlock"); break; case 158: strcpy(errtext, "lock file open/create failed"); break; case 159: strcpy(errtext, "can't resize share mem block"); break; case 201: strcpy(errtext, "header already has keywords"); break; case 202: strcpy(errtext, "keyword not found in header"); break; case 203: strcpy(errtext, "keyword number out of bounds"); break; case 204: strcpy(errtext, "keyword value is undefined"); break; case 205: strcpy(errtext, "string missing closing quote"); break; case 206: strcpy(errtext, "error in indexed keyword name"); break; case 207: strcpy(errtext, "illegal character in keyword"); break; case 208: strcpy(errtext, "required keywords out of order"); break; case 209: strcpy(errtext, "keyword value not positive int"); break; case 210: strcpy(errtext, "END keyword not found"); break; case 211: strcpy(errtext, "illegal BITPIX keyword value"); break; case 212: strcpy(errtext, "illegal NAXIS keyword value"); break; case 213: strcpy(errtext, "illegal NAXISn keyword value"); break; case 214: strcpy(errtext, "illegal PCOUNT keyword value"); break; case 215: strcpy(errtext, "illegal GCOUNT keyword value"); break; case 216: strcpy(errtext, "illegal TFIELDS keyword value"); break; case 217: strcpy(errtext, "negative table row size"); break; case 218: strcpy(errtext, "negative number of rows"); break; case 219: strcpy(errtext, "named column not found"); break; case 220: strcpy(errtext, "illegal SIMPLE keyword value"); break; case 221: strcpy(errtext, "first keyword not SIMPLE"); break; case 222: strcpy(errtext, "second keyword not BITPIX"); break; case 223: strcpy(errtext, "third keyword not NAXIS"); break; case 224: strcpy(errtext, "missing NAXISn keywords"); break; case 225: strcpy(errtext, "first keyword not XTENSION"); break; case 226: strcpy(errtext, "CHDU not an ASCII table"); break; case 227: strcpy(errtext, "CHDU not a binary table"); break; case 228: strcpy(errtext, "PCOUNT keyword not found"); break; case 229: strcpy(errtext, "GCOUNT keyword not found"); break; case 230: strcpy(errtext, "TFIELDS keyword not found"); break; case 231: strcpy(errtext, "missing TBCOLn keyword"); break; case 232: strcpy(errtext, "missing TFORMn keyword"); break; case 233: strcpy(errtext, "CHDU not an IMAGE extension"); break; case 234: strcpy(errtext, "illegal TBCOLn keyword value"); break; case 235: strcpy(errtext, "CHDU not a table extension"); break; case 236: strcpy(errtext, "column exceeds width of table"); break; case 237: strcpy(errtext, "more than 1 matching col. name"); break; case 241: strcpy(errtext, "row width not = field widths"); break; case 251: strcpy(errtext, "unknown FITS extension type"); break; case 252: strcpy(errtext, "1st key not SIMPLE or XTENSION"); break; case 253: strcpy(errtext, "END keyword is not blank"); break; case 254: strcpy(errtext, "Header fill area not blank"); break; case 255: strcpy(errtext, "Data fill area invalid"); break; case 261: strcpy(errtext, "illegal TFORM format code"); break; case 262: strcpy(errtext, "unknown TFORM datatype code"); break; case 263: strcpy(errtext, "illegal TDIMn keyword value"); break; case 264: strcpy(errtext, "invalid BINTABLE heap pointer"); break; default: strcpy(errtext, "unknown error status"); break; } } else if (status < 600) { switch(status) { case 301: strcpy(errtext, "illegal HDU number"); break; case 302: strcpy(errtext, "column number < 1 or > tfields"); break; case 304: strcpy(errtext, "negative byte address"); break; case 306: strcpy(errtext, "negative number of elements"); break; case 307: strcpy(errtext, "bad first row number"); break; case 308: strcpy(errtext, "bad first element number"); break; case 309: strcpy(errtext, "not an ASCII (A) column"); break; case 310: strcpy(errtext, "not a logical (L) column"); break; case 311: strcpy(errtext, "bad ASCII table datatype"); break; case 312: strcpy(errtext, "bad binary table datatype"); break; case 314: strcpy(errtext, "null value not defined"); break; case 317: strcpy(errtext, "not a variable length column"); break; case 320: strcpy(errtext, "illegal number of dimensions"); break; case 321: strcpy(errtext, "1st pixel no. > last pixel no."); break; case 322: strcpy(errtext, "BSCALE or TSCALn = 0."); break; case 323: strcpy(errtext, "illegal axis length < 1"); break; case 340: strcpy(errtext, "not group table"); break; case 341: strcpy(errtext, "HDU already member of group"); break; case 342: strcpy(errtext, "group member not found"); break; case 343: strcpy(errtext, "group not found"); break; case 344: strcpy(errtext, "bad group id"); break; case 345: strcpy(errtext, "too many HDUs tracked"); break; case 346: strcpy(errtext, "HDU alread tracked"); break; case 347: strcpy(errtext, "bad Grouping option"); break; case 348: strcpy(errtext, "identical pointers (groups)"); break; case 360: strcpy(errtext, "malloc failed in parser"); break; case 361: strcpy(errtext, "file read error in parser"); break; case 362: strcpy(errtext, "null pointer arg (parser)"); break; case 363: strcpy(errtext, "empty line (parser)"); break; case 364: strcpy(errtext, "cannot unread > 1 line"); break; case 365: strcpy(errtext, "parser too deeply nested"); break; case 366: strcpy(errtext, "file open failed (parser)"); break; case 367: strcpy(errtext, "hit EOF (parser)"); break; case 368: strcpy(errtext, "bad argument (parser)"); break; case 369: strcpy(errtext, "unexpected token (parser)"); break; case 401: strcpy(errtext, "bad int to string conversion"); break; case 402: strcpy(errtext, "bad float to string conversion"); break; case 403: strcpy(errtext, "keyword value not integer"); break; case 404: strcpy(errtext, "keyword value not logical"); break; case 405: strcpy(errtext, "keyword value not floating pt"); break; case 406: strcpy(errtext, "keyword value not double"); break; case 407: strcpy(errtext, "bad string to int conversion"); break; case 408: strcpy(errtext, "bad string to float conversion"); break; case 409: strcpy(errtext, "bad string to double convert"); break; case 410: strcpy(errtext, "illegal datatype code value"); break; case 411: strcpy(errtext, "illegal no. of decimals"); break; case 412: strcpy(errtext, "datatype conversion overflow"); break; case 413: strcpy(errtext, "error compressing image"); break; case 414: strcpy(errtext, "error uncompressing image"); break; case 420: strcpy(errtext, "bad date or time conversion"); break; case 431: strcpy(errtext, "syntax error in expression"); break; case 432: strcpy(errtext, "expression result wrong type"); break; case 433: strcpy(errtext, "vector result too large"); break; case 434: strcpy(errtext, "missing output column"); break; case 435: strcpy(errtext, "bad data in parsed column"); break; case 436: strcpy(errtext, "output extension of wrong type"); break; case 501: strcpy(errtext, "WCS angle too large"); break; case 502: strcpy(errtext, "bad WCS coordinate"); break; case 503: strcpy(errtext, "error in WCS calculation"); break; case 504: strcpy(errtext, "bad WCS projection type"); break; case 505: strcpy(errtext, "WCS keywords not found"); break; default: strcpy(errtext, "unknown error status"); break; } } else { strcpy(errtext, "unknown error status"); } return; } /*--------------------------------------------------------------------------*/ void ffpmsg(const char *err_message) /* put message on to error stack */ { ffxmsg(PutMesg, (char *)err_message); return; } /*--------------------------------------------------------------------------*/ void ffpmrk(void) /* write a marker to the stack. It is then possible to pop only those messages following the marker off of the stack, leaving the previous messages unaffected. The marker is ignored by the ffgmsg routine. */ { char *dummy = 0; ffxmsg(PutMark, dummy); return; } /*--------------------------------------------------------------------------*/ int ffgmsg(char *err_message) /* get oldest message from error stack, ignoring markers */ { ffxmsg(GetMesg, err_message); return(*err_message); } /*--------------------------------------------------------------------------*/ void ffcmsg(void) /* erase all messages in the error stack */ { char *dummy = 0; ffxmsg(DelAll, dummy); return; } /*--------------------------------------------------------------------------*/ void ffcmrk(void) /* erase newest messages in the error stack, stopping if a marker is found. The marker is also erased in this case. */ { char *dummy = 0; ffxmsg(DelMark, dummy); return; } /*--------------------------------------------------------------------------*/ void ffxmsg( int action, char *errmsg) /* general routine to get, put, or clear the error message stack. Use a static array rather than allocating memory as needed for the error messages because it is likely to be more efficient and simpler to implement. Action Code: DelAll 1 delete all messages on the error stack DelMark 2 delete messages back to and including the 1st marker DelNewest 3 delete the newest message from the stack GetMesg 4 pop and return oldest message, ignoring marks PutMesg 5 add a new message to the stack PutMark 6 add a marker to the stack */ { int ii; char markflag; static char *txtbuff[errmsgsiz], *tmpbuff, *msgptr; static char errbuff[errmsgsiz][81]; /* initialize all = \0 */ static int nummsg = 0; FFLOCK; if (action == DelAll) /* clear the whole message stack */ { for (ii = 0; ii < nummsg; ii ++) *txtbuff[ii] = '\0'; nummsg = 0; } else if (action == DelMark) /* clear up to and including first marker */ { while (nummsg > 0) { nummsg--; markflag = *txtbuff[nummsg]; /* store possible marker character */ *txtbuff[nummsg] = '\0'; /* clear the buffer for this msg */ if (markflag == ESMARKER) break; /* found a marker, so quit */ } } else if (action == DelNewest) /* remove newest message from stack */ { if (nummsg > 0) { nummsg--; *txtbuff[nummsg] = '\0'; /* clear the buffer for this msg */ } } else if (action == GetMesg) /* pop and return oldest message from stack */ { /* ignoring markers */ while (nummsg > 0) { strcpy(errmsg, txtbuff[0]); /* copy oldest message to output */ *txtbuff[0] = '\0'; /* clear the buffer for this msg */ nummsg--; for (ii = 0; ii < nummsg; ii++) txtbuff[ii] = txtbuff[ii + 1]; /* shift remaining pointers */ if (errmsg[0] != ESMARKER) { /* quit if this is not a marker */ FFUNLOCK; return; } } errmsg[0] = '\0'; /* no messages in the stack */ } else if (action == PutMesg) /* add new message to stack */ { msgptr = errmsg; while (strlen(msgptr)) { if (nummsg == errmsgsiz) { tmpbuff = txtbuff[0]; /* buffers full; reuse oldest buffer */ *txtbuff[0] = '\0'; /* clear the buffer for this msg */ nummsg--; for (ii = 0; ii < nummsg; ii++) txtbuff[ii] = txtbuff[ii + 1]; /* shift remaining pointers */ txtbuff[nummsg] = tmpbuff; /* set pointer for the new message */ } else { for (ii = 0; ii < errmsgsiz; ii++) { if (*errbuff[ii] == '\0') /* find first empty buffer */ { txtbuff[nummsg] = errbuff[ii]; break; } } } strncat(txtbuff[nummsg], msgptr, 80); nummsg++; msgptr += minvalue(80, strlen(msgptr)); } } else if (action == PutMark) /* put a marker on the stack */ { if (nummsg == errmsgsiz) { tmpbuff = txtbuff[0]; /* buffers full; reuse oldest buffer */ *txtbuff[0] = '\0'; /* clear the buffer for this msg */ nummsg--; for (ii = 0; ii < nummsg; ii++) txtbuff[ii] = txtbuff[ii + 1]; /* shift remaining pointers */ txtbuff[nummsg] = tmpbuff; /* set pointer for the new message */ } else { for (ii = 0; ii < errmsgsiz; ii++) { if (*errbuff[ii] == '\0') /* find first empty buffer */ { txtbuff[nummsg] = errbuff[ii]; break; } } } *txtbuff[nummsg] = ESMARKER; /* write the marker */ *(txtbuff[nummsg] + 1) = '\0'; nummsg++; } FFUNLOCK; return; } /*--------------------------------------------------------------------------*/ int ffpxsz(int datatype) /* return the number of bytes per pixel associated with the datatype */ { if (datatype == TBYTE) return(sizeof(char)); else if (datatype == TUSHORT) return(sizeof(short)); else if (datatype == TSHORT) return(sizeof(short)); else if (datatype == TULONG) return(sizeof(long)); else if (datatype == TLONG) return(sizeof(long)); else if (datatype == TINT) return(sizeof(int)); else if (datatype == TUINT) return(sizeof(int)); else if (datatype == TFLOAT) return(sizeof(float)); else if (datatype == TDOUBLE) return(sizeof(double)); else if (datatype == TLOGICAL) return(sizeof(char)); else return(0); } /*--------------------------------------------------------------------------*/ int fftkey(const char *keyword, /* I - keyword name */ int *status) /* IO - error status */ /* Test that the keyword name conforms to the FITS standard. Must contain only capital letters, digits, minus or underscore chars. Trailing spaces are allowed. If the input status value is less than zero, then the test is modified so that upper or lower case letters are allowed, and no error messages are printed if the keyword is not legal. */ { size_t maxchr, ii; int spaces=0; char msg[FLEN_ERRMSG], testchar; if (*status > 0) /* inherit input status value if > 0 */ return(*status); maxchr=strlen(keyword); if (maxchr > 8) maxchr = 8; for (ii = 0; ii < maxchr; ii++) { if (*status == 0) testchar = keyword[ii]; else testchar = toupper(keyword[ii]); if ( (testchar >= 'A' && testchar <= 'Z') || (testchar >= '0' && testchar <= '9') || testchar == '-' || testchar == '_' ) { if (spaces) { if (*status == 0) { /* don't print error message if status < 0 */ snprintf(msg, FLEN_ERRMSG, "Keyword name contains embedded space(s): %.8s", keyword); ffpmsg(msg); } return(*status = BAD_KEYCHAR); } } else if (keyword[ii] == ' ') spaces = 1; else { if (*status == 0) { /* don't print error message if status < 0 */ snprintf(msg, FLEN_ERRMSG,"Character %d in this keyword is illegal: %.8s", (int) (ii+1), keyword); ffpmsg(msg); /* explicitly flag the 2 most common cases */ if (keyword[ii] == 0) ffpmsg(" (This a NULL (0) character)."); else if (keyword[ii] == 9) ffpmsg(" (This an ASCII TAB (9) character)."); } return(*status = BAD_KEYCHAR); } } return(*status); } /*--------------------------------------------------------------------------*/ int fftrec(char *card, /* I - keyword card to test */ int *status) /* IO - error status */ /* Test that the keyword card conforms to the FITS standard. Must contain only printable ASCII characters; */ { size_t ii, maxchr; char msg[FLEN_ERRMSG]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); maxchr = strlen(card); for (ii = 8; ii < maxchr; ii++) { if (card[ii] < 32 || card[ii] > 126) { snprintf(msg, FLEN_ERRMSG, "Character %d in this keyword is illegal. Hex Value = %X", (int) (ii+1), (int) card[ii] ); if (card[ii] == 0) strncat(msg, " (NULL char.)",FLEN_ERRMSG-strlen(msg)-1); else if (card[ii] == 9) strncat(msg, " (TAB char.)",FLEN_ERRMSG-strlen(msg)-1); else if (card[ii] == 10) strncat(msg, " (Line Feed char.)",FLEN_ERRMSG-strlen(msg)-1); else if (card[ii] == 11) strncat(msg, " (Vertical Tab)",FLEN_ERRMSG-strlen(msg)-1); else if (card[ii] == 12) strncat(msg, " (Form Feed char.)",FLEN_ERRMSG-strlen(msg)-1); else if (card[ii] == 13) strncat(msg, " (Carriage Return)",FLEN_ERRMSG-strlen(msg)-1); else if (card[ii] == 27) strncat(msg, " (Escape char.)",FLEN_ERRMSG-strlen(msg)-1); else if (card[ii] == 127) strncat(msg, " (Delete char.)",FLEN_ERRMSG-strlen(msg)-1); ffpmsg(msg); strncpy(msg, card, 80); msg[80] = '\0'; ffpmsg(msg); return(*status = BAD_KEYCHAR); } } return(*status); } /*--------------------------------------------------------------------------*/ void ffupch(char *string) /* convert string to upper case, in place. */ { size_t len, ii; len = strlen(string); for (ii = 0; ii < len; ii++) string[ii] = toupper(string[ii]); return; } /*--------------------------------------------------------------------------*/ int ffmkky(const char *keyname, /* I - keyword name */ char *value, /* I - keyword value */ const char *comm, /* I - keyword comment */ char *card, /* O - constructed keyword card */ int *status) /* IO - status value */ /* Make a complete FITS 80-byte keyword card from the input name, value and comment strings. Output card is null terminated without any trailing blanks. */ { size_t namelen, len, ii; char tmpname[FLEN_KEYWORD], tmpname2[FLEN_KEYWORD],*cptr; char *saveptr; int tstatus = -1, nblank = 0, ntoken = 0, maxlen = 0, specialchar = 0; if (*status > 0) return(*status); *tmpname = '\0'; *tmpname2 = '\0'; *card = '\0'; /* skip leading blanks in the name */ while(*(keyname + nblank) == ' ') nblank++; strncat(tmpname, keyname + nblank, FLEN_KEYWORD - 1); len = strlen(value); namelen = strlen(tmpname); /* delete non-significant trailing blanks in the name */ if (namelen) { cptr = tmpname + namelen - 1; while(*cptr == ' ') { *cptr = '\0'; cptr--; } namelen = cptr - tmpname + 1; } /* check that the name does not contain an '=' (equals sign) */ if (strchr(tmpname, '=') ) { ffpmsg("Illegal keyword name; contains an equals sign (=)"); ffpmsg(tmpname); return(*status = BAD_KEYCHAR); } if (namelen <= 8 && fftkey(tmpname, &tstatus) <= 0 ) { /* a normal 8-char (or less) FITS keyword. */ strcat(card, tmpname); /* copy keyword name to buffer */ for (ii = namelen; ii < 8; ii++) card[ii] = ' '; /* pad keyword name with spaces */ card[8] = '='; /* append '= ' in columns 9-10 */ card[9] = ' '; card[10] = '\0'; /* terminate the partial string */ namelen = 10; } else if ((FSTRNCMP(tmpname, "HIERARCH ", 9) == 0) || (FSTRNCMP(tmpname, "hierarch ", 9) == 0) ) { /* this is an explicit ESO HIERARCH keyword */ strcat(card, tmpname); /* copy keyword name to buffer */ if (namelen + 3 + len > 80) { /* save 1 char by not putting a space before the equals sign */ strcat(card, "= "); namelen += 2; } else { strcat(card, " = "); namelen += 3; } } else { /* scan the keyword name to determine the number and max length of the tokens */ /* and test if any of the tokens contain nonstandard characters */ strncat(tmpname2, tmpname, FLEN_KEYWORD - 1); cptr = ffstrtok(tmpname2, " ",&saveptr); while (cptr) { if (strlen(cptr) > maxlen) maxlen = strlen(cptr); /* find longest token */ /* name contains special characters? */ tstatus = -1; /* suppress any error message */ if (fftkey(cptr, &tstatus) > 0) specialchar = 1; cptr = ffstrtok(NULL, " ",&saveptr); ntoken++; } tstatus = -1; /* suppress any error message */ /* if (ntoken > 1) { */ if (ntoken > 0) { /* temporarily change so that this case should always be true */ /* for now at least, treat all cases as an implicit ESO HIERARCH keyword. */ /* This could change if FITS is ever expanded to directly support longer keywords. */ if (namelen + 11 > FLEN_CARD-1) { ffpmsg( "The following keyword is too long to fit on a card:"); ffpmsg(keyname); return(*status = BAD_KEYCHAR); } strcat(card, "HIERARCH "); strcat(card, tmpname); namelen += 9; if (namelen + 3 + len > 80) { /* save 1 char by not putting a space before the equals sign */ strcat(card, "= "); namelen += 2; } else { strcat(card, " = "); namelen += 3; } } else if ((fftkey(tmpname, &tstatus) <= 0)) { /* should never get here (at least for now) */ /* allow keyword names longer than 8 characters */ strncat(card, tmpname, FLEN_KEYWORD - 1); strcat(card, "= "); namelen += 2; } else { /* should never get here (at least for now) */ ffpmsg("Illegal keyword name:"); ffpmsg(tmpname); return(*status = BAD_KEYCHAR); } } if (len > 0) /* now process the value string */ { if (value[0] == '\'') /* is this a quoted string value? */ { if (namelen > 77) { ffpmsg( "The following keyword + value is too long to fit on a card:"); ffpmsg(keyname); ffpmsg(value); return(*status = BAD_KEYCHAR); } strncat(card, value, 80 - namelen); /* append the value string */ len = minvalue(80, namelen + len); /* restore the closing quote if it got truncated */ if (len == 80) { card[79] = '\''; } if (comm) { if (comm[0] != 0) { if (len < 30) { for (ii = len; ii < 30; ii++) card[ii] = ' '; /* fill with spaces to col 30 */ card[30] = '\0'; len = 30; } } } } else { if (namelen + len > 80) { ffpmsg( "The following keyword + value is too long to fit on a card:"); ffpmsg(keyname); ffpmsg(value); return(*status = BAD_KEYCHAR); } else if (namelen + len < 30) { /* add spaces so field ends at least in col 30 */ strncat(card, " ", 30 - (namelen + len)); } strncat(card, value, 80 - namelen); /* append the value string */ len = minvalue(80, namelen + len); len = maxvalue(30, len); } if (comm) { if ((len < 77) && ( strlen(comm) > 0) ) /* room for a comment? */ { strcat(card, " / "); /* append comment separator */ strncat(card, comm, 77 - len); /* append comment (what fits) */ } } } else { if (namelen == 10) /* This case applies to normal keywords only */ { card[8] = ' '; /* keywords with no value have no '=' */ if (comm) { strncat(card, comm, 80 - namelen); /* append comment (what fits) */ } } } /* issue a warning if this keyword does not strictly conform to the standard HIERARCH convention, which requires, 1) at least 2 tokens in the name, 2) no tokens longer than 8 characters, and 3) no special characters in any of the tokens */ if (ntoken == 1 || specialchar == 1) { ffpmsg("Warning: the following keyword does not conform to the HIERARCH convention"); /* ffpmsg(" (e.g., name is not hierarchical or contains non-standard characters)."); */ ffpmsg(card); } return(*status); } /*--------------------------------------------------------------------------*/ int ffmkey(fitsfile *fptr, /* I - FITS file pointer */ const char *card, /* I - card string value */ int *status) /* IO - error status */ /* replace the previously read card (i.e. starting 80 bytes before the (fptr->Fptr)->nextkey position) with the contents of the input card. */ { char tcard[81]; size_t len, ii; int keylength = 8; /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); strncpy(tcard,card,80); tcard[80] = '\0'; len = strlen(tcard); /* silently replace any illegal characters with a space */ for (ii=0; ii < len; ii++) if (tcard[ii] < ' ' || tcard[ii] > 126) tcard[ii] = ' '; for (ii=len; ii < 80; ii++) /* fill card with spaces if necessary */ tcard[ii] = ' '; keylength = strcspn(tcard, "="); if (keylength == 80) keylength = 8; for (ii=0; ii < keylength; ii++) /* make sure keyword name is uppercase */ tcard[ii] = toupper(tcard[ii]); fftkey(tcard, status); /* test keyword name contains legal chars */ /* no need to do this any more, since any illegal characters have been removed fftrec(tcard, status); */ /* test rest of keyword for legal chars */ /* move position of keyword to be over written */ ffmbyt(fptr, ((fptr->Fptr)->nextkey) - 80, REPORT_EOF, status); ffpbyt(fptr, 80, tcard, status); /* write the 80 byte card */ return(*status); } /*--------------------------------------------------------------------------*/ int ffkeyn(const char *keyroot, /* I - root string for keyword name */ int value, /* I - index number to be appended to root name */ char *keyname, /* O - output root + index keyword name */ int *status) /* IO - error status */ /* Construct a keyword name string by appending the index number to the root. e.g., if root = "TTYPE" and value = 12 then keyname = "TTYPE12". */ { char suffix[16]; size_t rootlen; keyname[0] = '\0'; /* initialize output name to null */ rootlen = strlen(keyroot); if (rootlen == 0 || value < 0 ) return(*status = 206); snprintf(suffix, 16, "%d", value); /* construct keyword suffix */ strcpy(keyname, keyroot); /* copy root string to name string */ while (rootlen > 0 && keyname[rootlen - 1] == ' ') { rootlen--; /* remove trailing spaces in root name */ keyname[rootlen] = '\0'; } if (strlen(suffix) + strlen(keyname) > 8) return (*status=206); strcat(keyname, suffix); /* append suffix to the root */ return(*status); } /*--------------------------------------------------------------------------*/ int ffnkey(int value, /* I - index number to be appended to root name */ const char *keyroot, /* I - root string for keyword name */ char *keyname, /* O - output root + index keyword name */ int *status) /* IO - error status */ /* Construct a keyword name string by appending the root string to the index number. e.g., if root = "TTYPE" and value = 12 then keyname = "12TTYPE". */ { size_t rootlen; keyname[0] = '\0'; /* initialize output name to null */ rootlen = strlen(keyroot); if (rootlen == 0 || rootlen > 7 || value < 0 ) return(*status = 206); snprintf(keyname, FLEN_VALUE,"%d", value); /* construct keyword prefix */ if (rootlen + strlen(keyname) > 8) return(*status = 206); strcat(keyname, keyroot); /* append root to the prefix */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpsvc(char *card, /* I - FITS header card (nominally 80 bytes long) */ char *value, /* O - value string parsed from the card */ char *comm, /* O - comment string parsed from the card */ int *status) /* IO - error status */ /* ParSe the Value and Comment strings from the input header card string. If the card contains a quoted string value, the returned value string includes the enclosing quote characters. If comm = NULL, don't return the comment string. */ { int jj; size_t ii, cardlen, nblank, valpos; if (*status > 0) return(*status); value[0] = '\0'; if (comm) comm[0] = '\0'; cardlen = strlen(card); /* support for ESO HIERARCH keywords; find the '=' */ if (FSTRNCMP(card, "HIERARCH ", 9) == 0) { valpos = strcspn(card, "="); if (valpos == cardlen) /* no value indicator ??? */ { if (comm != NULL) { if (cardlen > 8) { strcpy(comm, &card[8]); jj=cardlen - 8; for (jj--; jj >= 0; jj--) /* replace trailing blanks with nulls */ { if (comm[jj] == ' ') comm[jj] = '\0'; else break; } } } return(*status); /* no value indicator */ } valpos++; /* point to the position after the '=' */ } else if (cardlen < 9 || FSTRNCMP(card, "COMMENT ", 8) == 0 || /* keywords with no value */ FSTRNCMP(card, "HISTORY ", 8) == 0 || FSTRNCMP(card, "END ", 8) == 0 || FSTRNCMP(card, "CONTINUE", 8) == 0 || FSTRNCMP(card, " ", 8) == 0 ) { /* no value, so the comment extends from cols 9 - 80 */ if (comm != NULL) { if (cardlen > 8) { strcpy(comm, &card[8]); jj=cardlen - 8; for (jj--; jj >= 0; jj--) /* replace trailing blanks with nulls */ { if (comm[jj] == ' ') comm[jj] = '\0'; else break; } } } return(*status); } else if (FSTRNCMP(&card[8], "= ", 2) == 0 ) { /* normal keyword with '= ' in cols 9-10 */ valpos = 10; /* starting position of the value field */ } else { valpos = strcspn(card, "="); if (valpos == cardlen) /* no value indicator ??? */ { if (comm != NULL) { if (cardlen > 8) { strcpy(comm, &card[8]); jj=cardlen - 8; for (jj--; jj >= 0; jj--) /* replace trailing blanks with nulls */ { if (comm[jj] == ' ') comm[jj] = '\0'; else break; } } } return(*status); /* no value indicator */ } valpos++; /* point to the position after the '=' */ } nblank = strspn(&card[valpos], " "); /* find number of leading blanks */ if (nblank + valpos == cardlen) { /* the absence of a value string is legal, and simply indicates that the keyword value is undefined. Don't write an error message in this case. */ return(*status); } ii = valpos + nblank; if (card[ii] == '/' ) /* slash indicates start of the comment */ { ii++; } else if (card[ii] == '\'' ) /* is this a quoted string value? */ { value[0] = card[ii]; for (jj=1, ii++; ii < cardlen; ii++, jj++) { if (card[ii] == '\'') /* is this the closing quote? */ { if (card[ii+1] == '\'') /* 2 successive quotes? */ { value[jj] = card[ii]; ii++; jj++; } else { value[jj] = card[ii]; break; /* found the closing quote, so exit this loop */ } } value[jj] = card[ii]; /* copy the next character to the output */ } if (ii == cardlen) { jj = minvalue(jj, 69); /* don't exceed 70 char string length */ value[jj] = '\''; /* close the bad value string */ value[jj+1] = '\0'; /* terminate the bad value string */ ffpmsg("This keyword string value has no closing quote:"); ffpmsg(card); /* May 2008 - modified to not fail on this minor error */ /* return(*status = NO_QUOTE); */ } else { value[jj+1] = '\0'; /* terminate the good value string */ ii++; /* point to the character following the value */ } } else if (card[ii] == '(' ) /* is this a complex value? */ { nblank = strcspn(&card[ii], ")" ); /* find closing ) */ if (nblank == strlen( &card[ii] ) ) { ffpmsg("This complex keyword value has no closing ')':"); ffpmsg(card); return(*status = NO_QUOTE); } nblank++; strncpy(value, &card[ii], nblank); value[nblank] = '\0'; ii = ii + nblank; } else /* an integer, floating point, or logical FITS value string */ { nblank = strcspn(&card[ii], " /"); /* find the end of the token */ strncpy(value, &card[ii], nblank); value[nblank] = '\0'; ii = ii + nblank; } /* now find the comment string, if any */ if (comm) { nblank = strspn(&card[ii], " "); /* find next non-space character */ ii = ii + nblank; if (ii < 80) { if (card[ii] == '/') /* ignore the slash separator */ { ii++; if (card[ii] == ' ') /* also ignore the following space */ ii++; } strcat(comm, &card[ii]); /* copy the remaining characters */ jj=strlen(comm); for (jj--; jj >= 0; jj--) /* replace trailing blanks with nulls */ { if (comm[jj] == ' ') comm[jj] = '\0'; else break; } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgthd(char *tmplt, /* I - input header template string */ char *card, /* O - returned FITS header record */ int *hdtype, /* O - how to interpreter the returned card string */ /* -2 = modify the name of a keyword; the old keyword name is returned starting at address chars[0]; the new name is returned starting at address char[40] (to be consistent with the Fortran version). Both names are null terminated. -1 = card contains the name of a keyword that is to be deleted 0 = append this keyword if it doesn't already exist, or modify the value if the keyword already exists. 1 = append this comment keyword ('HISTORY', 'COMMENT', or blank keyword name) 2 = this is the END keyword; do not write it to the header */ int *status) /* IO - error status */ /* 'Get Template HeaDer' parse a template header line and create a formated character string which is suitable for appending to a FITS header */ { char keyname[FLEN_KEYWORD], value[140], comment[140]; char *tok, *suffix, *loc, tvalue[140]; int len, vlen, more, tstatus, lentok1=0, remainlen=0; double dval; if (*status > 0) return(*status); card[0] = '\0'; *hdtype = 0; if (!FSTRNCMP(tmplt, " ", 8) ) { /* if first 8 chars of template are blank, then this is a comment */ strncat(card, tmplt, 80); *hdtype = 1; return(*status); } tok = tmplt; /* point to start of template string */ keyname[0] = '\0'; value[0] = '\0'; comment[0] = '\0'; len = strspn(tok, " "); /* no. of spaces before keyword */ tok += len; /* test for pecular case where token is a string of dashes */ if (strncmp(tok, "--------------------", 20) == 0) return(*status = BAD_KEYCHAR); if (tok[0] == '-') /* is there a leading minus sign? */ { /* first token is name of keyword to be deleted or renamed */ *hdtype = -1; tok++; len = strspn(tok, " "); /* no. of spaces before keyword */ tok += len; len = strcspn(tok, " =+"); /* length of name */ if (len >= FLEN_KEYWORD) return(*status = BAD_KEYCHAR); lentok1 = len; strncat(card, tok, len); /* The HIERARCH convention supports non-standard characters in the keyword name, so don't always convert to upper case or abort if there are illegal characters in the name or if the name is greater than 8 characters long. */ if (len < 9) /* this is possibly a normal FITS keyword name */ { ffupch(card); tstatus = 0; if (fftkey(card, &tstatus) > 0) { /* name contained non-standard characters, so reset */ card[0] = '\0'; strncat(card, tok, len); } } tok += len; /* Check optional "+" indicator to delete multiple keywords */ if (tok[0] == '+' && len < FLEN_KEYWORD) { strcat(card, "+"); return (*status); } /* second token, if present, is the new name for the keyword */ len = strspn(tok, " "); /* no. of spaces before next token */ tok += len; if (tok[0] == '\0' || tok[0] == '=') return(*status); /* no second token */ *hdtype = -2; len = strcspn(tok, " "); /* length of new name */ /* this name has to fit on columns 41-80 of card, and first name must now fit in 1-40 */ if (lentok1 > 40) { card[0] = '\0'; return (*status = BAD_KEYCHAR); } if (len > 40) { card[0] = '\0'; return(*status = BAD_KEYCHAR); } /* copy the new name to card + 40; This is awkward, */ /* but is consistent with the way the Fortran FITSIO works */ strcat(card," "); strncpy(&card[40], tok, len); card[80] = '\0'; /* necessary to add terminator in case len = 40 */ /* The HIERARCH convention supports non-standard characters in the keyword name, so don't always convert to upper case or abort if there are illegal characters in the name or if the name is greater than 8 characters long. */ if (len < 9) /* this is possibly a normal FITS keyword name */ { ffupch(&card[40]); tstatus = 0; if (fftkey(&card[40], &tstatus) > 0) { /* name contained non-standard characters, so reset */ strncpy(&card[40], tok, len); } } } else /* no negative sign at beginning of template */ { /* get the keyword name token */ len = strcspn(tok, " ="); /* length of keyword name */ if (len >= FLEN_KEYWORD) return(*status = BAD_KEYCHAR); strncat(keyname, tok, len); /* The HIERARCH convention supports non-standard characters in the keyword name, so don't always convert to upper case or abort if there are illegal characters in the name or if the name is greater than 8 characters long. */ if (len < 9) /* this is possibly a normal FITS keyword name */ { ffupch(keyname); tstatus = 0; if (fftkey(keyname, &tstatus) > 0) { /* name contained non-standard characters, so reset */ keyname[0] = '\0'; strncat(keyname, tok, len); } } if (!FSTRCMP(keyname, "END") ) { strcpy(card, "END"); *hdtype = 2; return(*status); } tok += len; /* move token pointer to end of the keyword */ if (!FSTRCMP(keyname, "COMMENT") || !FSTRCMP(keyname, "HISTORY") || !FSTRCMP(keyname, "HIERARCH") ) { *hdtype = 1; /* simply append COMMENT and HISTORY keywords */ strcpy(card, keyname); strncat(card, tok, 72); return(*status); } /* look for the value token */ len = strspn(tok, " ="); /* spaces or = between name and value */ tok += len; if (*tok == '\'') /* is value enclosed in quotes? */ { more = TRUE; remainlen = 139; while (more) { tok++; /* temporarily move past the quote char */ len = strcspn(tok, "'"); /* length of quoted string */ tok--; if (len+2 > remainlen) return (*status=BAD_KEYCHAR); strncat(value, tok, len + 2); remainlen -= (len+2); tok += len + 1; if (tok[0] != '\'') /* check there is a closing quote */ return(*status = NO_QUOTE); tok++; if (tok[0] != '\'') /* 2 quote chars = literal quote */ more = FALSE; } } else if (*tok == '/' || *tok == '\0') /* There is no value */ { strcat(value, " "); } else /* not a quoted string value */ { len = strcspn(tok, " /"); /* length of value string */ if (len > 139) return (*status=BAD_KEYCHAR); strncat(value, tok, len); if (!( (tok[0] == 'T' || tok[0] == 'F') && (tok[1] == ' ' || tok[1] == '/' || tok[1] == '\0') )) { /* not a logical value */ dval = strtod(value, &suffix); /* try to read value as number */ if (*suffix != '\0' && *suffix != ' ' && *suffix != '/') { /* value not recognized as a number; might be because it */ /* contains a 'd' or 'D' exponent character */ strcpy(tvalue, value); if ((loc = strchr(tvalue, 'D'))) { *loc = 'E'; /* replace D's with E's. */ dval = strtod(tvalue, &suffix); /* read value again */ } else if ((loc = strchr(tvalue, 'd'))) { *loc = 'E'; /* replace d's with E's. */ dval = strtod(tvalue, &suffix); /* read value again */ } else if ((loc = strchr(tvalue, '.'))) { *loc = ','; /* replace period with a comma */ dval = strtod(tvalue, &suffix); /* read value again */ } } if (*suffix != '\0' && *suffix != ' ' && *suffix != '/') { /* value is not a number; must enclose it in quotes */ if (len > 137) return (*status=BAD_KEYCHAR); strcpy(value, "'"); strncat(value, tok, len); strcat(value, "'"); /* the following useless statement stops the compiler warning */ /* that dval is not used anywhere */ if (dval == 0.) len += (int) dval; } else { /* value is a number; convert any 'e' to 'E', or 'd' to 'D' */ loc = strchr(value, 'e'); if (loc) { *loc = 'E'; } else { loc = strchr(value, 'd'); if (loc) { *loc = 'D'; } } } } tok += len; } len = strspn(tok, " /"); /* no. of spaces between value and comment */ tok += len; vlen = strlen(value); if (vlen > 0 && vlen < 10 && value[0] == '\'') { /* pad quoted string with blanks so it is at least 8 chars long */ value[vlen-1] = '\0'; strncat(value, " ", 10 - vlen); strcat(&value[9], "'"); } /* get the comment string */ strncat(comment, tok, 70); /* construct the complete FITS header card */ ffmkky(keyname, value, comment, card, status); } return(*status); } /*--------------------------------------------------------------------------*/ int fits_translate_keyword( char *inrec, /* I - input string */ char *outrec, /* O - output converted string, or */ /* a null string if input does not */ /* match any of the patterns */ char *patterns[][2],/* I - pointer to input / output string */ /* templates */ int npat, /* I - number of templates passed */ int n_value, /* I - base 'n' template value of interest */ int n_offset, /* I - offset to be applied to the 'n' */ /* value in the output string */ int n_range, /* I - controls range of 'n' template */ /* values of interest (-1,0, or +1) */ int *pat_num, /* O - matched pattern number (0 based) or -1 */ int *i, /* O - value of i, if any, else 0 */ int *j, /* O - value of j, if any, else 0 */ int *m, /* O - value of m, if any, else 0 */ int *n, /* O - value of n, if any, else 0 */ int *status) /* IO - error status */ /* Translate a keyword name to a new name, based on a set of patterns. The user passes an array of patterns to be matched. Input pattern number i is pattern[i][0], and output pattern number i is pattern[i][1]. Keywords are matched against the input patterns. If a match is found then the keyword is re-written according to the output pattern. Order is important. The first match is accepted. The fastest match will be made when templates with the same first character are grouped together. Several characters have special meanings: i,j - single digits, preserved in output template n - column number of one or more digits, preserved in output template m - generic number of one or more digits, preserved in output template a - coordinate designator, preserved in output template # - number of one or more digits ? - any character * - only allowed in first character position, to match all keywords; only useful as last pattern in the list i, j, n, and m are returned by the routine. For example, the input pattern "iCTYPn" will match "1CTYP5" (if n_value is 5); the output pattern "CTYPEi" will be re-written as "CTYPE1". Notice that "i" is preserved. The following output patterns are special Special output pattern characters: "-" - do not copy a keyword that matches the corresponding input pattern "+" - copy the input unchanged The inrec string could be just the 8-char keyword name, or the entire 80-char header record. Characters 9 = 80 in the input string simply get appended to the translated keyword name. If n_range = 0, then only keywords with 'n' equal to n_value will be considered as a pattern match. If n_range = +1, then all values of 'n' greater than or equal to n_value will be a match, and if -1, then values of 'n' less than or equal to n_value will match. This routine was written by Craig Markwardt, GSFC */ { int i1 = 0, j1 = 0, n1 = 0, m1 = 0; int fac; char a = ' '; char oldp; char c, s; int ip, ic, pat, pass = 0, firstfail; char *spat; if (*status > 0) return(*status); if ((inrec == 0) || (outrec == 0)) return (*status = NULL_INPUT_PTR); *outrec = '\0'; /* if (*inrec == '\0') return 0; */ if (*inrec == '\0') /* expand to full 8 char blank keyword name */ strcpy(inrec, " "); oldp = '\0'; firstfail = 0; /* ===== Pattern match stage */ for (pat=0; pat < npat; pat++) { spat = patterns[pat][0]; i1 = 0; j1 = 0; m1 = -1; n1 = -1; a = ' '; /* Initialize the place-holders */ pass = 0; /* Pass the wildcard pattern */ if (spat[0] == '*') { pass = 1; break; } /* Optimization: if we have seen this initial pattern character before, then it must have failed, and we can skip the pattern */ if (firstfail && spat[0] == oldp) continue; oldp = spat[0]; /* ip = index of pattern character being matched ic = index of keyname character being matched firstfail = 1 if we fail on the first characteor (0=not) */ for (ip=0, ic=0, firstfail=1; (spat[ip]) && (ic < 8); ip++, ic++, firstfail=0) { c = inrec[ic]; s = spat[ip]; if (s == 'i') { /* Special pattern: 'i' placeholder */ if (isdigit(c)) { i1 = c - '0'; pass = 1;} } else if (s == 'j') { /* Special pattern: 'j' placeholder */ if (isdigit(c)) { j1 = c - '0'; pass = 1;} } else if ((s == 'n')||(s == 'm')||(s == '#')) { /* Special patterns: multi-digit number */ int val = 0; pass = 0; if (isdigit(c)) { pass = 1; /* NOTE, could fail below */ /* Parse decimal number */ while (ic<8 && isdigit(c)) { val = val*10 + (c - '0'); ic++; c = inrec[ic]; } ic--; c = inrec[ic]; if (s == 'n') { /* Is it a column number? */ if ( val >= 1 && val <= 999 && /* Row range check */ (((n_range == 0) && (val == n_value)) || /* Strict equality */ ((n_range == -1) && (val <= n_value)) || /* n <= n_value */ ((n_range == +1) && (val >= n_value))) ) { /* n >= n_value */ n1 = val; } else { pass = 0; } } else if (s == 'm') { /* Generic number */ m1 = val; } } } else if (s == 'a') { /* Special pattern: coordinate designator */ if (isupper(c) || c == ' ') { a = c; pass = 1;} } else if (s == '?') { /* Match any individual character */ pass = 1; } else if (c == s) { /* Match a specific character */ pass = 1; } else { /* FAIL */ pass = 0; } if (!pass) break; } /* Must pass to the end of the keyword. No partial matches allowed */ if (pass && (ic >= 8 || inrec[ic] == ' ')) break; } /* Transfer the pattern-matched numbers to the output parameters */ if (i) { *i = i1; } if (j) { *j = j1; } if (n) { *n = n1; } if (m) { *m = m1; } if (pat_num) { *pat_num = pat; } /* ===== Keyword rewriting and output stage */ spat = patterns[pat][1]; /* Return case: explicit deletion, return '-' */ if (pass && strcmp(spat,"--") == 0) { strcpy(outrec, "-"); strncat(outrec, inrec, 8); outrec[9] = 0; for(i1=8; i1>1 && outrec[i1] == ' '; i1--) outrec[i1] = 0; return 0; } /* Return case: no match, or do-not-transfer pattern */ if (pass == 0 || spat[0] == '\0' || strcmp(spat,"-") == 0) return 0; /* A match: we start by copying the input record to the output */ strcpy(outrec, inrec); /* Return case: return the input record unchanged */ if (spat[0] == '+') return 0; /* Final case: a new output pattern */ for (ip=0, ic=0; spat[ip]; ip++, ic++) { s = spat[ip]; if (s == 'i') { outrec[ic] = (i1+'0'); } else if (s == 'j') { outrec[ic] = (j1+'0'); } else if (s == 'n') { if (n1 == -1) { n1 = n_value; } if (n1 > 0) { n1 += n_offset; for (fac = 1; (n1/fac) > 0; fac *= 10); fac /= 10; while(fac > 0) { outrec[ic] = ((n1/fac) % 10) + '0'; fac /= 10; ic ++; } ic--; } } else if (s == 'm' && m1 >= 0) { for (fac = 1; (m1/fac) > 0; fac *= 10); fac /= 10; while(fac > 0) { outrec[ic] = ((m1/fac) % 10) + '0'; fac /= 10; ic ++; } ic --; } else if (s == 'a') { outrec[ic] = a; } else { outrec[ic] = s; } } /* Pad the keyword name with spaces */ for ( ; ic<8; ic++) { outrec[ic] = ' '; } return(*status); } /*--------------------------------------------------------------------------*/ int fits_translate_keywords( fitsfile *infptr, /* I - pointer to input HDU */ fitsfile *outfptr, /* I - pointer to output HDU */ int firstkey, /* I - first HDU record number to start with */ char *patterns[][2],/* I - pointer to input / output keyword templates */ int npat, /* I - number of templates passed */ int n_value, /* I - base 'n' template value of interest */ int n_offset, /* I - offset to be applied to the 'n' */ /* value in the output string */ int n_range, /* I - controls range of 'n' template */ /* values of interest (-1,0, or +1) */ int *status) /* IO - error status */ /* Copy relevant keywords from the table header into the newly created primary array header. Convert names of keywords where appropriate. See fits_translate_keyword() for the definitions. Translation begins at header record number 'firstkey', and continues to the end of the header. This routine was written by Craig Markwardt, GSFC */ { int nrec, nkeys, nmore; char rec[FLEN_CARD]; int i = 0, j = 0, n = 0, m = 0; int pat_num = 0, maxchr, ii; char outrec[FLEN_CARD]; if (*status > 0) return(*status); ffghsp(infptr, &nkeys, &nmore, status); /* get number of keywords */ for (nrec = firstkey; (*status == 0) && (nrec <= nkeys); nrec++) { outrec[0] = '\0'; ffgrec(infptr, nrec, rec, status); /* silently overlook any illegal ASCII characters in the value or */ /* comment fields of the record. It is usually not appropriate to */ /* abort the process because of this minor transgression of the FITS rules. */ /* Set the offending character to a blank */ maxchr = strlen(rec); for (ii = 8; ii < maxchr; ii++) { if (rec[ii] < 32 || rec[ii] > 126) rec[ii] = ' '; } fits_translate_keyword(rec, outrec, patterns, npat, n_value, n_offset, n_range, &pat_num, &i, &j, &m, &n, status); if (*status == 0) { if (outrec[0] == '-') { /* prefix -KEYNAME means delete */ int i1; /* Preserve only the keyword portion of name */ outrec[9] = 0; for(i1=8; i1>1 && outrec[i1] == ' '; i1--) outrec[i1] = 0; ffpmrk(); ffdkey(outfptr, outrec+1, status); /* delete the keyword */ if (*status == 0) { int nkeys1; /* get number of keywords again in case of change*/ ffghsp(infptr, &nkeys1, &nmore, status); if (nkeys1 != nkeys) { nrec --; nkeys = nkeys1; } } *status = 0; ffcmrk(); } else if (outrec[0]) { ffprec(outfptr, outrec, status); /* copy the keyword */ } } rec[8] = 0; outrec[8] = 0; } return(*status); } /*--------------------------------------------------------------------------*/ int fits_copy_pixlist2image( fitsfile *infptr, /* I - pointer to input HDU */ fitsfile *outfptr, /* I - pointer to output HDU */ int firstkey, /* I - first HDU record number to start with */ int naxis, /* I - number of axes in the image */ int *colnum, /* I - numbers of the columns to be binned */ int *status) /* IO - error status */ /* Copy relevant keywords from the pixel list table header into a newly created primary array header. Convert names of keywords where appropriate. See fits_translate_pixkeyword() for the definitions. Translation begins at header record number 'firstkey', and continues to the end of the header. */ { int nrec, nkeys, nmore; char rec[FLEN_CARD], outrec[FLEN_CARD]; int pat_num = 0, npat; int iret, jret, nret, mret, lret; char *patterns[][2] = { {"TCTYPn", "CTYPEn" }, {"TCTYna", "CTYPEna" }, {"TCUNIn", "CUNITn" }, {"TCUNna", "CUNITna" }, {"TCRVLn", "CRVALn" }, {"TCRVna", "CRVALna" }, {"TCDLTn", "CDELTn" }, {"TCDEna", "CDELTna" }, {"TCRPXn", "CRPIXn" }, {"TCRPna", "CRPIXna" }, {"TCROTn", "CROTAn" }, {"TPn_ma", "PCn_ma" }, {"TPCn_m", "PCn_ma" }, {"TCn_ma", "CDn_ma" }, {"TCDn_m", "CDn_ma" }, {"TVn_la", "PVn_la" }, {"TPVn_l", "PVn_la" }, {"TSn_la", "PSn_la" }, {"TPSn_l", "PSn_la" }, {"TWCSna", "WCSNAMEa" }, {"TCNAna", "CNAMEna" }, {"TCRDna", "CRDERna" }, {"TCSYna", "CSYERna" }, {"LONPna", "LONPOLEa" }, {"LATPna", "LATPOLEa" }, {"EQUIna", "EQUINOXa" }, {"MJDOBn", "MJD-OBS" }, {"MJDAn", "MJD-AVG" }, {"DAVGn", "DATE-AVG" }, {"RADEna", "RADESYSa" }, {"RFRQna", "RESTFRQa" }, {"RWAVna", "RESTWAVa" }, {"SPECna", "SPECSYSa" }, {"SOBSna", "SSYSOBSa" }, {"SSRCna", "SSYSSRCa" }, /* preserve common keywords */ {"LONPOLEa", "+" }, {"LATPOLEa", "+" }, {"EQUINOXa", "+" }, {"EPOCH", "+" }, {"MJD-????", "+" }, {"DATE????", "+" }, {"TIME????", "+" }, {"RADESYSa", "+" }, {"RADECSYS", "+" }, {"TELESCOP", "+" }, {"INSTRUME", "+" }, {"OBSERVER", "+" }, {"OBJECT", "+" }, /* Delete general table column keywords */ {"XTENSION", "-" }, {"BITPIX", "-" }, {"NAXIS", "-" }, {"NAXISi", "-" }, {"PCOUNT", "-" }, {"GCOUNT", "-" }, {"TFIELDS", "-" }, {"TDIM#", "-" }, {"THEAP", "-" }, {"EXTNAME", "-" }, {"EXTVER", "-" }, {"EXTLEVEL","-" }, {"CHECKSUM","-" }, {"DATASUM", "-" }, {"NAXLEN", "-" }, {"AXLEN#", "-" }, {"CPREF", "-" }, /* Delete table keywords related to other columns */ {"T????#a", "-" }, {"TC??#a", "-" }, {"T??#_#", "-" }, {"TWCS#a", "-" }, {"LONP#a", "-" }, {"LATP#a", "-" }, {"EQUI#a", "-" }, {"MJDOB#", "-" }, {"MJDA#", "-" }, {"RADE#a", "-" }, {"DAVG#", "-" }, {"iCTYP#", "-" }, {"iCTY#a", "-" }, {"iCUNI#", "-" }, {"iCUN#a", "-" }, {"iCRVL#", "-" }, {"iCDLT#", "-" }, {"iCRPX#", "-" }, {"iCTY#a", "-" }, {"iCUN#a", "-" }, {"iCRV#a", "-" }, {"iCDE#a", "-" }, {"iCRP#a", "-" }, {"ijPC#a", "-" }, {"ijCD#a", "-" }, {"iV#_#a", "-" }, {"iS#_#a", "-" }, {"iCRD#a", "-" }, {"iCSY#a", "-" }, {"iCROT#", "-" }, {"WCAX#a", "-" }, {"WCSN#a", "-" }, {"iCNA#a", "-" }, {"*", "+" }}; /* copy all other keywords */ if (*status > 0) return(*status); npat = sizeof(patterns)/sizeof(patterns[0][0])/2; ffghsp(infptr, &nkeys, &nmore, status); /* get number of keywords */ for (nrec = firstkey; nrec <= nkeys; nrec++) { outrec[0] = '\0'; ffgrec(infptr, nrec, rec, status); fits_translate_pixkeyword(rec, outrec, patterns, npat, naxis, colnum, &pat_num, &iret, &jret, &nret, &mret, &lret, status); if (outrec[0]) { ffprec(outfptr, outrec, status); /* copy the keyword */ } rec[8] = 0; outrec[8] = 0; } return(*status); } /*--------------------------------------------------------------------------*/ int fits_translate_pixkeyword( char *inrec, /* I - input string */ char *outrec, /* O - output converted string, or */ /* a null string if input does not */ /* match any of the patterns */ char *patterns[][2],/* I - pointer to input / output string */ /* templates */ int npat, /* I - number of templates passed */ int naxis, /* I - number of columns to be binned */ int *colnum, /* I - numbers of the columns to be binned */ int *pat_num, /* O - matched pattern number (0 based) or -1 */ int *i, int *j, int *n, int *m, int *l, int *status) /* IO - error status */ /* Translate a keyword name to a new name, based on a set of patterns. The user passes an array of patterns to be matched. Input pattern number i is pattern[i][0], and output pattern number i is pattern[i][1]. Keywords are matched against the input patterns. If a match is found then the keyword is re-written according to the output pattern. Order is important. The first match is accepted. The fastest match will be made when templates with the same first character are grouped together. Several characters have special meanings: i,j - single digits, preserved in output template n, m - column number of one or more digits, preserved in output template k - generic number of one or more digits, preserved in output template a - coordinate designator, preserved in output template # - number of one or more digits ? - any character * - only allowed in first character position, to match all keywords; only useful as last pattern in the list i, j, n, and m are returned by the routine. For example, the input pattern "iCTYPn" will match "1CTYP5" (if n_value is 5); the output pattern "CTYPEi" will be re-written as "CTYPE1". Notice that "i" is preserved. The following output patterns are special Special output pattern characters: "-" - do not copy a keyword that matches the corresponding input pattern "+" - copy the input unchanged The inrec string could be just the 8-char keyword name, or the entire 80-char header record. Characters 9 = 80 in the input string simply get appended to the translated keyword name. If n_range = 0, then only keywords with 'n' equal to n_value will be considered as a pattern match. If n_range = +1, then all values of 'n' greater than or equal to n_value will be a match, and if -1, then values of 'n' less than or equal to n_value will match. */ { int i1 = 0, j1 = 0, val; int fac, nval = 0, mval = 0, lval = 0; char a = ' '; char oldp; char c, s; int ip, ic, pat, pass = 0, firstfail; char *spat; if (*status > 0) return(*status); if ((inrec == 0) || (outrec == 0)) return (*status = NULL_INPUT_PTR); *outrec = '\0'; if (*inrec == '\0') return 0; oldp = '\0'; firstfail = 0; /* ===== Pattern match stage */ for (pat=0; pat < npat; pat++) { spat = patterns[pat][0]; i1 = 0; j1 = 0; a = ' '; /* Initialize the place-holders */ pass = 0; /* Pass the wildcard pattern */ if (spat[0] == '*') { pass = 1; break; } /* Optimization: if we have seen this initial pattern character before, then it must have failed, and we can skip the pattern */ if (firstfail && spat[0] == oldp) continue; oldp = spat[0]; /* ip = index of pattern character being matched ic = index of keyname character being matched firstfail = 1 if we fail on the first characteor (0=not) */ for (ip=0, ic=0, firstfail=1; (spat[ip]) && (ic < 8); ip++, ic++, firstfail=0) { c = inrec[ic]; s = spat[ip]; if (s == 'i') { /* Special pattern: 'i' placeholder */ if (isdigit(c)) { i1 = c - '0'; pass = 1;} } else if (s == 'j') { /* Special pattern: 'j' placeholder */ if (isdigit(c)) { j1 = c - '0'; pass = 1;} } else if ((s == 'n')||(s == 'm')||(s == 'l')||(s == '#')) { /* Special patterns: multi-digit number */ val = 0; pass = 0; if (isdigit(c)) { pass = 1; /* NOTE, could fail below */ /* Parse decimal number */ while (ic<8 && isdigit(c)) { val = val*10 + (c - '0'); ic++; c = inrec[ic]; } ic--; c = inrec[ic]; if (s == 'n' || s == 'm') { /* Is it a column number? */ if ( val >= 1 && val <= 999) { if (val == colnum[0]) val = 1; else if (val == colnum[1]) val = 2; else if (val == colnum[2]) val = 3; else if (val == colnum[3]) val = 4; else { pass = 0; val = 0; } if (s == 'n') nval = val; else mval = val; } else { pass = 0; } } else if (s == 'l') { /* Generic number */ lval = val; } } } else if (s == 'a') { /* Special pattern: coordinate designator */ if (isupper(c) || c == ' ') { a = c; pass = 1;} } else if (s == '?') { /* Match any individual character */ pass = 1; } else if (c == s) { /* Match a specific character */ pass = 1; } else { /* FAIL */ pass = 0; } if (!pass) break; } /* Must pass to the end of the keyword. No partial matches allowed */ if (pass && (ic >= 8 || inrec[ic] == ' ')) break; } /* Transfer the pattern-matched numbers to the output parameters */ if (i) { *i = i1; } if (j) { *j = j1; } if (n) { *n = nval; } if (m) { *m = mval; } if (l) { *l = lval; } if (pat_num) { *pat_num = pat; } /* ===== Keyword rewriting and output stage */ spat = patterns[pat][1]; /* Return case: no match, or explicit deletion pattern */ if (pass == 0 || spat[0] == '\0' || spat[0] == '-') return 0; /* A match: we start by copying the input record to the output */ strcpy(outrec, inrec); /* Return case: return the input record unchanged */ if (spat[0] == '+') return 0; /* Final case: a new output pattern */ for (ip=0, ic=0; spat[ip]; ip++, ic++) { s = spat[ip]; if (s == 'i') { outrec[ic] = (i1+'0'); } else if (s == 'j') { outrec[ic] = (j1+'0'); } else if (s == 'n' && nval > 0) { for (fac = 1; (nval/fac) > 0; fac *= 10); fac /= 10; while(fac > 0) { outrec[ic] = ((nval/fac) % 10) + '0'; fac /= 10; ic ++; } ic--; } else if (s == 'm' && mval > 0) { for (fac = 1; (mval/fac) > 0; fac *= 10); fac /= 10; while(fac > 0) { outrec[ic] = ((mval/fac) % 10) + '0'; fac /= 10; ic ++; } ic--; } else if (s == 'l' && lval >= 0) { for (fac = 1; (lval/fac) > 0; fac *= 10); fac /= 10; while(fac > 0) { outrec[ic] = ((lval/fac) % 10) + '0'; fac /= 10; ic ++; } ic --; } else if (s == 'a') { outrec[ic] = a; } else { outrec[ic] = s; } } /* Pad the keyword name with spaces */ for ( ; ic<8; ic++) { outrec[ic] = ' '; } return(*status); } /*--------------------------------------------------------------------------*/ int ffasfm(char *tform, /* I - format code from the TFORMn keyword */ int *dtcode, /* O - numerical datatype code */ long *twidth, /* O - width of the field, in chars */ int *decimals, /* O - number of decimal places (F, E, D format) */ int *status) /* IO - error status */ { /* parse the ASCII table TFORM column format to determine the data type, the field width, and number of decimal places (if relevant) */ int ii, datacode; long longval, width; float fwidth; char *form, temp[FLEN_VALUE], message[FLEN_ERRMSG]; if (*status > 0) return(*status); if (dtcode) *dtcode = 0; if (twidth) *twidth = 0; if (decimals) *decimals = 0; ii = 0; while (tform[ii] != 0 && tform[ii] == ' ') /* find first non-blank char */ ii++; if (strlen(&tform[ii]) > FLEN_VALUE-1) { ffpmsg("Error: ASCII table TFORM code is too long (ffasfm)"); return(*status = BAD_TFORM); } strcpy(temp, &tform[ii]); /* copy format string */ ffupch(temp); /* make sure it is in upper case */ form = temp; /* point to start of format string */ if (form[0] == 0) { ffpmsg("Error: ASCII table TFORM code is blank"); return(*status = BAD_TFORM); } /*-----------------------------------------------*/ /* determine default datatype code */ /*-----------------------------------------------*/ if (form[0] == 'A') datacode = TSTRING; else if (form[0] == 'I') datacode = TLONG; else if (form[0] == 'F') datacode = TFLOAT; else if (form[0] == 'E') datacode = TFLOAT; else if (form[0] == 'D') datacode = TDOUBLE; else { snprintf(message, FLEN_ERRMSG, "Illegal ASCII table TFORMn datatype: \'%s\'", tform); ffpmsg(message); return(*status = BAD_TFORM_DTYPE); } if (dtcode) *dtcode = datacode; form++; /* point to the start of field width */ if (datacode == TSTRING || datacode == TLONG) { /*-----------------------------------------------*/ /* A or I data formats: */ /*-----------------------------------------------*/ if (ffc2ii(form, &width, status) <= 0) /* read the width field */ { if (width <= 0) { width = 0; *status = BAD_TFORM; } else { /* set to shorter precision if I4 or less */ if (width <= 4 && datacode == TLONG) datacode = TSHORT; } } } else { /*-----------------------------------------------*/ /* F, E or D data formats: */ /*-----------------------------------------------*/ if (ffc2rr(form, &fwidth, status) <= 0) /* read ww.dd width field */ { if (fwidth <= 0.) *status = BAD_TFORM; else { width = (long) fwidth; /* convert from float to long */ if (width > 7 && *temp == 'F') datacode = TDOUBLE; /* type double if >7 digits */ if (width < 10) form = form + 1; /* skip 1 digit */ else form = form + 2; /* skip 2 digits */ if (form[0] == '.') /* should be a decimal point here */ { form++; /* point to start of decimals field */ if (ffc2ii(form, &longval, status) <= 0) /* read decimals */ { if (decimals) *decimals = longval; /* long to short convertion */ if (longval >= width) /* width < no. of decimals */ *status = BAD_TFORM; if (longval > 6 && *temp == 'E') datacode = TDOUBLE; /* type double if >6 digits */ } } } } } if (*status > 0) { *status = BAD_TFORM; snprintf(message,FLEN_ERRMSG,"Illegal ASCII table TFORMn code: \'%s\'", tform); ffpmsg(message); } if (dtcode) *dtcode = datacode; if (twidth) *twidth = width; return(*status); } /*--------------------------------------------------------------------------*/ int ffbnfm(char *tform, /* I - format code from the TFORMn keyword */ int *dtcode, /* O - numerical datatype code */ long *trepeat, /* O - repeat count of the field */ long *twidth, /* O - width of the field, in chars */ int *status) /* IO - error status */ { /* parse the binary table TFORM column format to determine the data type, repeat count, and the field width (if it is an ASCII (A) field) */ size_t ii, nchar; int datacode, variable, iread; long width, repeat; char *form, temp[FLEN_VALUE], message[FLEN_ERRMSG]; if (*status > 0) return(*status); if (dtcode) *dtcode = 0; if (trepeat) *trepeat = 0; if (twidth) *twidth = 0; nchar = strlen(tform); for (ii = 0; ii < nchar; ii++) { if (tform[ii] != ' ') /* find first non-space char */ break; } if (ii == nchar) { ffpmsg("Error: binary table TFORM code is blank (ffbnfm)."); return(*status = BAD_TFORM); } if (nchar-ii > FLEN_VALUE-1) { ffpmsg("Error: binary table TFORM code is too long (ffbnfm)."); return (*status = BAD_TFORM); } strcpy(temp, &tform[ii]); /* copy format string */ ffupch(temp); /* make sure it is in upper case */ form = temp; /* point to start of format string */ /*-----------------------------------------------*/ /* get the repeat count */ /*-----------------------------------------------*/ ii = 0; while(isdigit((int) form[ii])) ii++; /* look for leading digits in the field */ if (ii == 0) repeat = 1; /* no explicit repeat count */ else { if (sscanf(form,"%ld", &repeat) != 1) /* read repeat count */ { ffpmsg("Error: Bad repeat format in TFORM (ffbnfm)."); return(*status = BAD_TFORM); } } /*-----------------------------------------------*/ /* determine datatype code */ /*-----------------------------------------------*/ form = form + ii; /* skip over the repeat field */ if (form[0] == 'P' || form[0] == 'Q') { variable = 1; /* this is a variable length column */ /* repeat = 1; */ /* disregard any other repeat value */ form++; /* move to the next data type code char */ } else variable = 0; if (form[0] == 'U') /* internal code to signify unsigned short integer */ { datacode = TUSHORT; width = 2; } else if (form[0] == 'I') { datacode = TSHORT; width = 2; } else if (form[0] == 'V') /* internal code to signify unsigned integer */ { datacode = TULONG; width = 4; } else if (form[0] == 'W') /* internal code to signify unsigned long long integer */ { datacode = TULONGLONG; width = 8; } else if (form[0] == 'J') { datacode = TLONG; width = 4; } else if (form[0] == 'K') { datacode = TLONGLONG; width = 8; } else if (form[0] == 'E') { datacode = TFLOAT; width = 4; } else if (form[0] == 'D') { datacode = TDOUBLE; width = 8; } else if (form[0] == 'A') { datacode = TSTRING; /* the following code is used to support the non-standard datatype of the form rAw where r = total width of the field and w = width of fixed-length substrings within the field. */ iread = 0; if (form[1] != 0) { if (form[1] == '(' ) /* skip parenthesis around */ form++; /* variable length column width */ iread = sscanf(&form[1],"%ld", &width); } if (iread != 1 || (!variable && (width > repeat)) ) width = repeat; } else if (form[0] == 'L') { datacode = TLOGICAL; width = 1; } else if (form[0] == 'X') { datacode = TBIT; width = 1; } else if (form[0] == 'B') { datacode = TBYTE; width = 1; } else if (form[0] == 'S') /* internal code to signify signed byte */ { datacode = TSBYTE; width = 1; } else if (form[0] == 'C') { datacode = TCOMPLEX; width = 8; } else if (form[0] == 'M') { datacode = TDBLCOMPLEX; width = 16; } else { snprintf(message, FLEN_ERRMSG, "Illegal binary table TFORMn datatype: \'%s\' ", tform); ffpmsg(message); return(*status = BAD_TFORM_DTYPE); } if (variable) datacode = datacode * (-1); /* flag variable cols w/ neg type code */ if (dtcode) *dtcode = datacode; if (trepeat) *trepeat = repeat; if (twidth) *twidth = width; return(*status); } /*--------------------------------------------------------------------------*/ int ffbnfmll(char *tform, /* I - format code from the TFORMn keyword */ int *dtcode, /* O - numerical datatype code */ LONGLONG *trepeat, /* O - repeat count of the field */ long *twidth, /* O - width of the field, in chars */ int *status) /* IO - error status */ { /* parse the binary table TFORM column format to determine the data type, repeat count, and the field width (if it is an ASCII (A) field) */ size_t ii, nchar; int datacode, variable, iread; long width; LONGLONG repeat; char *form, temp[FLEN_VALUE], message[FLEN_ERRMSG]; double drepeat; if (*status > 0) return(*status); if (dtcode) *dtcode = 0; if (trepeat) *trepeat = 0; if (twidth) *twidth = 0; nchar = strlen(tform); for (ii = 0; ii < nchar; ii++) { if (tform[ii] != ' ') /* find first non-space char */ break; } if (ii == nchar) { ffpmsg("Error: binary table TFORM code is blank (ffbnfmll)."); return(*status = BAD_TFORM); } if (strlen(&tform[ii]) > FLEN_VALUE-1) { ffpmsg("Error: binary table TFORM code is too long (ffbnfmll)."); return(*status = BAD_TFORM); } strcpy(temp, &tform[ii]); /* copy format string */ ffupch(temp); /* make sure it is in upper case */ form = temp; /* point to start of format string */ /*-----------------------------------------------*/ /* get the repeat count */ /*-----------------------------------------------*/ ii = 0; while(isdigit((int) form[ii])) ii++; /* look for leading digits in the field */ if (ii == 0) repeat = 1; /* no explicit repeat count */ else { /* read repeat count */ /* print as double, because the string-to-64-bit int conversion */ /* character is platform dependent (%lld, %ld, %I64d) */ sscanf(form,"%lf", &drepeat); repeat = (LONGLONG) (drepeat + 0.1); } /*-----------------------------------------------*/ /* determine datatype code */ /*-----------------------------------------------*/ form = form + ii; /* skip over the repeat field */ if (form[0] == 'P' || form[0] == 'Q') { variable = 1; /* this is a variable length column */ /* repeat = 1; */ /* disregard any other repeat value */ form++; /* move to the next data type code char */ } else variable = 0; if (form[0] == 'U') /* internal code to signify unsigned integer */ { datacode = TUSHORT; width = 2; } else if (form[0] == 'I') { datacode = TSHORT; width = 2; } else if (form[0] == 'V') /* internal code to signify unsigned integer */ { datacode = TULONG; width = 4; } else if (form[0] == 'W') /* internal code to signify unsigned long long integer */ { datacode = TULONGLONG; width = 8; } else if (form[0] == 'J') { datacode = TLONG; width = 4; } else if (form[0] == 'K') { datacode = TLONGLONG; width = 8; } else if (form[0] == 'E') { datacode = TFLOAT; width = 4; } else if (form[0] == 'D') { datacode = TDOUBLE; width = 8; } else if (form[0] == 'A') { datacode = TSTRING; /* the following code is used to support the non-standard datatype of the form rAw where r = total width of the field and w = width of fixed-length substrings within the field. */ iread = 0; if (form[1] != 0) { if (form[1] == '(' ) /* skip parenthesis around */ form++; /* variable length column width */ iread = sscanf(&form[1],"%ld", &width); } if (iread != 1 || (!variable && (width > repeat)) ) width = (long) repeat; } else if (form[0] == 'L') { datacode = TLOGICAL; width = 1; } else if (form[0] == 'X') { datacode = TBIT; width = 1; } else if (form[0] == 'B') { datacode = TBYTE; width = 1; } else if (form[0] == 'S') /* internal code to signify signed byte */ { datacode = TSBYTE; width = 1; } else if (form[0] == 'C') { datacode = TCOMPLEX; width = 8; } else if (form[0] == 'M') { datacode = TDBLCOMPLEX; width = 16; } else { snprintf(message, FLEN_ERRMSG, "Illegal binary table TFORMn datatype: \'%s\' ", tform); ffpmsg(message); return(*status = BAD_TFORM_DTYPE); } if (variable) datacode = datacode * (-1); /* flag variable cols w/ neg type code */ if (dtcode) *dtcode = datacode; if (trepeat) *trepeat = repeat; if (twidth) *twidth = width; return(*status); } /*--------------------------------------------------------------------------*/ void ffcfmt(char *tform, /* value of an ASCII table TFORMn keyword */ char *cform) /* equivalent format code in C language syntax */ /* convert the FITS format string for an ASCII Table extension column into the equivalent C format string that can be used in a printf statement, after the values have been read as a double. */ { int ii; cform[0] = '\0'; ii = 0; while (tform[ii] != 0 && tform[ii] == ' ') /* find first non-blank char */ ii++; if (tform[ii] == 0) return; /* input format string was blank */ cform[0] = '%'; /* start the format string */ strcpy(&cform[1], &tform[ii + 1]); /* append the width and decimal code */ if (tform[ii] == 'A') strcat(cform, "s"); else if (tform[ii] == 'I') strcat(cform, ".0f"); /* 0 precision to suppress decimal point */ if (tform[ii] == 'F') strcat(cform, "f"); if (tform[ii] == 'E') strcat(cform, "E"); if (tform[ii] == 'D') strcat(cform, "E"); return; } /*--------------------------------------------------------------------------*/ void ffcdsp(char *tform, /* value of an ASCII table TFORMn keyword */ char *cform) /* equivalent format code in C language syntax */ /* convert the FITS TDISPn display format into the equivalent C format suitable for use in a printf statement. */ { int ii; cform[0] = '\0'; ii = 0; while (tform[ii] != 0 && tform[ii] == ' ') /* find first non-blank char */ ii++; if (tform[ii] == 0) { cform[0] = '\0'; return; /* input format string was blank */ } if (strchr(tform+ii, '%')) /* is there a % character in the string?? */ { cform[0] = '\0'; return; /* illegal TFORM string (possibly even harmful) */ } cform[0] = '%'; /* start the format string */ strcpy(&cform[1], &tform[ii + 1]); /* append the width and decimal code */ if (tform[ii] == 'A' || tform[ii] == 'a') strcat(cform, "s"); else if (tform[ii] == 'I' || tform[ii] == 'i') strcat(cform, "d"); else if (tform[ii] == 'O' || tform[ii] == 'o') strcat(cform, "o"); else if (tform[ii] == 'Z' || tform[ii] == 'z') strcat(cform, "X"); else if (tform[ii] == 'F' || tform[ii] == 'f') strcat(cform, "f"); else if (tform[ii] == 'E' || tform[ii] == 'e') strcat(cform, "E"); else if (tform[ii] == 'D' || tform[ii] == 'd') strcat(cform, "E"); else if (tform[ii] == 'G' || tform[ii] == 'g') strcat(cform, "G"); else cform[0] = '\0'; /* unrecognized tform code */ return; } /*--------------------------------------------------------------------------*/ int ffgcno( fitsfile *fptr, /* I - FITS file pionter */ int casesen, /* I - case sensitive string comparison? 0=no */ char *templt, /* I - input name of column (w/wildcards) */ int *colnum, /* O - number of the named column; 1=first col */ int *status) /* IO - error status */ /* Determine the column number corresponding to an input column name. The first column of the table = column 1; This supports the * and ? wild cards in the input template. */ { char colname[FLEN_VALUE]; /* temporary string to hold column name */ ffgcnn(fptr, casesen, templt, colname, colnum, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcnn( fitsfile *fptr, /* I - FITS file pointer */ int casesen, /* I - case sensitive string comparison? 0=no */ char *templt, /* I - input name of column (w/wildcards) */ char *colname, /* O - full column name up to 68 + 1 chars long*/ int *colnum, /* O - number of the named column; 1=first col */ int *status) /* IO - error status */ /* Return the full column name and column number of the next column whose TTYPEn keyword value matches the input template string. The template may contain the * and ? wildcards. Status = 237 is returned if the match is not unique. If so, one may call this routine again with input status=237 to get the next match. A status value of 219 is returned when there are no more matching columns. */ { char errmsg[FLEN_ERRMSG]; int tstatus, ii, founde, foundw, match, exact, unique; long ivalue; tcolumn *colptr; if (*status <= 0) { (fptr->Fptr)->startcol = 0; /* start search with first column */ tstatus = 0; } else if (*status == COL_NOT_UNIQUE) /* start search from previous spot */ { tstatus = COL_NOT_UNIQUE; *status = 0; } else return(*status); /* bad input status value */ colname[0] = 0; /* initialize null return */ *colnum = 0; /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header to get col struct */ return(*status); colptr = (fptr->Fptr)->tableptr; /* pointer to first column */ colptr += ((fptr->Fptr)->startcol); /* offset to starting column */ founde = FALSE; /* initialize 'found exact match' flag */ foundw = FALSE; /* initialize 'found wildcard match' flag */ unique = FALSE; for (ii = (fptr->Fptr)->startcol; ii < (fptr->Fptr)->tfield; ii++, colptr++) { ffcmps(templt, colptr->ttype, casesen, &match, &exact); if (match) { if (founde && exact) { /* warning: this is the second exact match we've found */ /*reset pointer to first match so next search starts there */ (fptr->Fptr)->startcol = *colnum; return(*status = COL_NOT_UNIQUE); } else if (founde) /* a wildcard match */ { /* already found exact match so ignore this non-exact match */ } else if (exact) { /* this is the first exact match we have found, so save it. */ strcpy(colname, colptr->ttype); *colnum = ii + 1; founde = TRUE; } else if (foundw) { /* we have already found a wild card match, so not unique */ /* continue searching for other matches */ unique = FALSE; } else { /* this is the first wild card match we've found. save it */ strcpy(colname, colptr->ttype); *colnum = ii + 1; (fptr->Fptr)->startcol = *colnum; foundw = TRUE; unique = TRUE; } } } /* OK, we've checked all the names now see if we got any matches */ if (founde) { if (tstatus == COL_NOT_UNIQUE) /* we did find 1 exact match but */ *status = COL_NOT_UNIQUE; /* there was a previous match too */ } else if (foundw) { /* found one or more wildcard matches; report error if not unique */ if (!unique || tstatus == COL_NOT_UNIQUE) *status = COL_NOT_UNIQUE; } else { /* didn't find a match; check if template is a positive integer */ ffc2ii(templt, &ivalue, &tstatus); if (tstatus == 0 && ivalue <= (fptr->Fptr)->tfield && ivalue > 0) { *colnum = ivalue; colptr = (fptr->Fptr)->tableptr; /* pointer to first column */ colptr += (ivalue - 1); /* offset to correct column */ strcpy(colname, colptr->ttype); } else { *status = COL_NOT_FOUND; if (tstatus != COL_NOT_UNIQUE) { snprintf(errmsg, FLEN_ERRMSG, "ffgcnn could not find column: %.45s", templt); ffpmsg(errmsg); } } } (fptr->Fptr)->startcol = *colnum; /* save pointer for next time */ return(*status); } /*--------------------------------------------------------------------------*/ void ffcmps(char *templt, /* I - input template (may have wildcards) */ char *colname, /* I - full column name up to 68 + 1 chars long */ int casesen, /* I - case sensitive string comparison? 1=yes */ int *match, /* O - do template and colname match? 1=yes */ int *exact) /* O - do strings exactly match, or wildcards */ /* compare the template to the string and test if they match. The strings are limited to 68 characters or less (the max. length of a FITS string keyword value. This routine reports whether the two strings match and whether the match is exact or involves wildcards. This algorithm is very similar to the way unix filename wildcards work except that this first treats a wild card as a literal character when looking for a match. If there is no literal match, then it interpretes it as a wild card. So the template 'AB*DE' is considered to be an exact rather than a wild card match to the string 'AB*DE'. The '#' wild card in the template string will match any consecutive string of decimal digits in the colname. */ { int ii, found, t1, s1, wildsearch = 0, tsave = 0, ssave = 0; char temp[FLEN_VALUE], col[FLEN_VALUE]; *match = FALSE; *exact = TRUE; strncpy(temp, templt, FLEN_VALUE); /* copy strings to work area */ strncpy(col, colname, FLEN_VALUE); temp[FLEN_VALUE - 1] = '\0'; /* make sure strings are terminated */ col[FLEN_VALUE - 1] = '\0'; /* truncate trailing non-significant blanks */ for (ii = strlen(temp) - 1; ii >= 0 && temp[ii] == ' '; ii--) temp[ii] = '\0'; for (ii = strlen(col) - 1; ii >= 0 && col[ii] == ' '; ii--) col[ii] = '\0'; if (!casesen) { /* convert both strings to uppercase before comparison */ ffupch(temp); ffupch(col); } if (!FSTRCMP(temp, col) ) { *match = TRUE; /* strings exactly match */ return; } *exact = FALSE; /* strings don't exactly match */ t1 = 0; /* start comparison with 1st char of each string */ s1 = 0; while(1) /* compare corresponding chars in each string */ { if (temp[t1] == '\0' && col[s1] == '\0') { /* completely scanned both strings so they match */ *match = TRUE; return; } else if (temp[t1] == '\0') { if (wildsearch) { /* the previous wildcard search may have been going down a blind alley. Backtrack, and resume the wildcard search with the next character in the string. */ t1 = tsave; s1 = ssave + 1; } else { /* reached end of template string so they don't match */ return; } } else if (col[s1] == '\0') { /* reached end of other string; they match if the next */ /* character in the template string is a '*' wild card */ if (temp[t1] == '*' && temp[t1 + 1] == '\0') { *match = TRUE; } return; } if (temp[t1] == col[s1] || (temp[t1] == '?') ) { s1++; /* corresponding chars in the 2 strings match */ t1++; /* increment both pointers and loop back again */ } else if (temp[t1] == '#' && isdigit((int) col[s1]) ) { s1++; /* corresponding chars in the 2 strings match */ t1++; /* increment both pointers */ /* find the end of the string of digits */ while (isdigit((int) col[s1]) ) s1++; } else if (temp[t1] == '*') { /* save current string locations, in case we need to restart */ wildsearch = 1; tsave = t1; ssave = s1; /* get next char from template and look for it in the col name */ t1++; if (temp[t1] == '\0' || temp[t1] == ' ') { /* reached end of template so strings match */ *match = TRUE; return; } found = FALSE; while (col[s1] && !found) { if (temp[t1] == col[s1]) { t1++; /* found matching characters; incre both pointers */ s1++; /* and loop back to compare next chars */ found = TRUE; } else s1++; /* increment the column name pointer and try again */ } if (!found) { return; /* hit end of column name and failed to find a match */ } } else { if (wildsearch) { /* the previous wildcard search may have been going down a blind alley. Backtrack, and resume the wildcard search with the next character in the string. */ t1 = tsave; s1 = ssave + 1; } else { return; /* strings don't match */ } } } } /*--------------------------------------------------------------------------*/ int ffgtcl( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ int *typecode, /* O - datatype code (21 = short, etc) */ long *repeat, /* O - repeat count of field */ long *width, /* O - if ASCII, width of field or unit string */ int *status) /* IO - error status */ /* Get Type of table column. Returns the datatype code of the column, as well as the vector repeat count and (if it is an ASCII character column) the width of the field or a unit string within the field. This supports the TFORMn = 'rAw' syntax for specifying arrays of substrings, so if TFORMn = '60A12' then repeat = 60 and width = 12. */ { LONGLONG trepeat, twidth; ffgtclll(fptr, colnum, typecode, &trepeat, &twidth, status); if (*status > 0) return(*status); if (repeat) *repeat= (long) trepeat; if (width) *width = (long) twidth; return(*status); } /*--------------------------------------------------------------------------*/ int ffgtclll( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ int *typecode, /* O - datatype code (21 = short, etc) */ LONGLONG *repeat, /* O - repeat count of field */ LONGLONG *width, /* O - if ASCII, width of field or unit string */ int *status) /* IO - error status */ /* Get Type of table column. Returns the datatype code of the column, as well as the vector repeat count and (if it is an ASCII character column) the width of the field or a unit string within the field. This supports the TFORMn = 'rAw' syntax for specifying arrays of substrings, so if TFORMn = '60A12' then repeat = 60 and width = 12. */ { tcolumn *colptr; int hdutype, decims; long tmpwidth; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if (colnum < 1 || colnum > (fptr->Fptr)->tfield) return(*status = BAD_COL_NUM); colptr = (fptr->Fptr)->tableptr; /* pointer to first column */ colptr += (colnum - 1); /* offset to correct column */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == ASCII_TBL) { ffasfm(colptr->tform, typecode, &tmpwidth, &decims, status); *width = tmpwidth; if (repeat) *repeat = 1; } else { if (typecode) *typecode = colptr->tdatatype; if (width) *width = colptr->twidth; if (repeat) *repeat = colptr->trepeat; } return(*status); } /*--------------------------------------------------------------------------*/ int ffeqty( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ int *typecode, /* O - datatype code (21 = short, etc) */ long *repeat, /* O - repeat count of field */ long *width, /* O - if ASCII, width of field or unit string */ int *status) /* IO - error status */ /* Get the 'equivalent' table column type. This routine is similar to the ffgtcl routine (which returns the physical datatype of the column, as stored in the FITS file) except that if the TSCALn and TZEROn keywords are defined for the column, then it returns the 'equivalent' datatype. Thus, if the column is defined as '1I' (short integer) this routine may return the type as 'TUSHORT' or as 'TFLOAT' depending on the TSCALn and TZEROn values. Returns the datatype code of the column, as well as the vector repeat count and (if it is an ASCII character column) the width of the field or a unit string within the field. This supports the TFORMn = 'rAw' syntax for specifying arrays of substrings, so if TFORMn = '60A12' then repeat = 60 and width = 12. */ { LONGLONG trepeat, twidth; ffeqtyll(fptr, colnum, typecode, &trepeat, &twidth, status); if (repeat) *repeat= (long) trepeat; if (width) *width = (long) twidth; return(*status); } /*--------------------------------------------------------------------------*/ int ffeqtyll( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ int *typecode, /* O - datatype code (21 = short, etc) */ LONGLONG *repeat, /* O - repeat count of field */ LONGLONG *width, /* O - if ASCII, width of field or unit string */ int *status) /* IO - error status */ /* Get the 'equivalent' table column type. This routine is similar to the ffgtcl routine (which returns the physical datatype of the column, as stored in the FITS file) except that if the TSCALn and TZEROn keywords are defined for the column, then it returns the 'equivalent' datatype. Thus, if the column is defined as '1I' (short integer) this routine may return the type as 'TUSHORT' or as 'TFLOAT' depending on the TSCALn and TZEROn values. Returns the datatype code of the column, as well as the vector repeat count and (if it is an ASCII character column) the width of the field or a unit string within the field. This supports the TFORMn = 'rAw' syntax for specifying arrays of substrings, so if TFORMn = '60A12' then repeat = 60 and width = 12. */ { tcolumn *colptr; int hdutype, decims, tcode, effcode; double tscale, tzero, min_val, max_val; long lngscale, lngzero = 0, tmpwidth; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if (colnum < 1 || colnum > (fptr->Fptr)->tfield) return(*status = BAD_COL_NUM); colptr = (fptr->Fptr)->tableptr; /* pointer to first column */ colptr += (colnum - 1); /* offset to correct column */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == ASCII_TBL) { ffasfm(colptr->tform, typecode, &tmpwidth, &decims, status); if (width) *width = tmpwidth; if (repeat) *repeat = 1; } else { if (typecode) *typecode = colptr->tdatatype; if (width) *width = colptr->twidth; if (repeat) *repeat = colptr->trepeat; } /* return if caller is not interested in the typecode value */ if (!typecode) return(*status); /* check if the tscale and tzero keywords are defined, which might change the effective datatype of the column */ tscale = colptr->tscale; tzero = colptr->tzero; if (tscale == 1.0 && tzero == 0.0) /* no scaling */ return(*status); tcode = abs(*typecode); switch (tcode) { case TBYTE: /* binary table 'rB' column */ min_val = 0.; max_val = 255.0; break; case TSHORT: min_val = -32768.0; max_val = 32767.0; break; case TLONG: min_val = -2147483648.0; max_val = 2147483647.0; break; case TLONGLONG: min_val = -9.2233720368547755808E18; max_val = 9.2233720368547755807E18; break; default: /* don't have to deal with other data types */ return(*status); } if (tscale >= 0.) { min_val = tzero + tscale * min_val; max_val = tzero + tscale * max_val; } else { max_val = tzero + tscale * min_val; min_val = tzero + tscale * max_val; } if (tzero < 2147483648.) /* don't exceed range of 32-bit integer */ lngzero = (long) tzero; lngscale = (long) tscale; if ((tzero != 2147483648.) && /* special value that exceeds integer range */ (tzero != 9223372036854775808.) && /* indicates unsigned long long */ (lngzero != tzero || lngscale != tscale)) { /* not integers? */ /* floating point scaled values; just decide on required precision */ if (tcode == TBYTE || tcode == TSHORT) effcode = TFLOAT; else effcode = TDOUBLE; /* In all the remaining cases, TSCALn and TZEROn are integers, and not equal to 1 and 0, respectively. */ } else if ((min_val == -128.) && (max_val == 127.)) { effcode = TSBYTE; } else if ((min_val >= -32768.0) && (max_val <= 32767.0)) { effcode = TSHORT; } else if ((min_val >= 0.0) && (max_val <= 65535.0)) { effcode = TUSHORT; } else if ((min_val >= -2147483648.0) && (max_val <= 2147483647.0)) { effcode = TLONG; } else if ((min_val >= 0.0) && (max_val < 4294967296.0)) { effcode = TULONG; } else if ((min_val >= -9.2233720368547755808E18) && (max_val <= 9.2233720368547755807E18)) { effcode = TLONGLONG; } else if ((min_val >= 0.0) && (max_val <= 1.8446744073709551616E19)) { effcode = TULONGLONG; } else { /* exceeds the range of a 64-bit integer */ effcode = TDOUBLE; } /* return the effective datatype code (negative if variable length col.) */ if (*typecode < 0) /* variable length array column */ *typecode = -effcode; else *typecode = effcode; return(*status); } /*--------------------------------------------------------------------------*/ int ffgncl( fitsfile *fptr, /* I - FITS file pointer */ int *ncols, /* O - number of columns in the table */ int *status) /* IO - error status */ /* Get the number of columns in the table (= TFIELDS keyword) */ { if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) return(*status = NOT_TABLE); *ncols = (fptr->Fptr)->tfield; return(*status); } /*--------------------------------------------------------------------------*/ int ffgnrw( fitsfile *fptr, /* I - FITS file pointer */ long *nrows, /* O - number of rows in the table */ int *status) /* IO - error status */ /* Get the number of rows in the table (= NAXIS2 keyword) */ { if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) return(*status = NOT_TABLE); /* the NAXIS2 keyword may not be up to date, so use the structure value */ *nrows = (long) (fptr->Fptr)->numrows; return(*status); } /*--------------------------------------------------------------------------*/ int ffgnrwll( fitsfile *fptr, /* I - FITS file pointer */ LONGLONG *nrows, /* O - number of rows in the table */ int *status) /* IO - error status */ /* Get the number of rows in the table (= NAXIS2 keyword) */ { if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) return(*status = NOT_TABLE); /* the NAXIS2 keyword may not be up to date, so use the structure value */ *nrows = (fptr->Fptr)->numrows; return(*status); } /*--------------------------------------------------------------------------*/ int ffgacl( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ char *ttype, /* O - TTYPEn keyword value */ long *tbcol, /* O - TBCOLn keyword value */ char *tunit, /* O - TUNITn keyword value */ char *tform, /* O - TFORMn keyword value */ double *tscal, /* O - TSCALn keyword value */ double *tzero, /* O - TZEROn keyword value */ char *tnull, /* O - TNULLn keyword value */ char *tdisp, /* O - TDISPn keyword value */ int *status) /* IO - error status */ /* get ASCII column keyword values */ { char name[FLEN_KEYWORD], comm[FLEN_COMMENT]; tcolumn *colptr; int tstatus; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if (colnum < 1 || colnum > (fptr->Fptr)->tfield) return(*status = BAD_COL_NUM); /* get what we can from the column structure */ colptr = (fptr->Fptr)->tableptr; /* pointer to first column */ colptr += (colnum -1); /* offset to correct column */ if (ttype) strcpy(ttype, colptr->ttype); if (tbcol) *tbcol = (long) ((colptr->tbcol) + 1); /* first col is 1, not 0 */ if (tform) strcpy(tform, colptr->tform); if (tscal) *tscal = colptr->tscale; if (tzero) *tzero = colptr->tzero; if (tnull) strcpy(tnull, colptr->strnull); /* read keywords to get additional parameters */ if (tunit) { ffkeyn("TUNIT", colnum, name, status); tstatus = 0; *tunit = '\0'; ffgkys(fptr, name, tunit, comm, &tstatus); } if (tdisp) { ffkeyn("TDISP", colnum, name, status); tstatus = 0; *tdisp = '\0'; ffgkys(fptr, name, tdisp, comm, &tstatus); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgbcl( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ char *ttype, /* O - TTYPEn keyword value */ char *tunit, /* O - TUNITn keyword value */ char *dtype, /* O - datatype char: I, J, E, D, etc. */ long *repeat, /* O - vector column repeat count */ double *tscal, /* O - TSCALn keyword value */ double *tzero, /* O - TZEROn keyword value */ long *tnull, /* O - TNULLn keyword value integer cols only */ char *tdisp, /* O - TDISPn keyword value */ int *status) /* IO - error status */ /* get BINTABLE column keyword values */ { LONGLONG trepeat, ttnull; if (*status > 0) return(*status); ffgbclll(fptr, colnum, ttype, tunit, dtype, &trepeat, tscal, tzero, &ttnull, tdisp, status); if (repeat) *repeat = (long) trepeat; if (tnull) *tnull = (long) ttnull; return(*status); } /*--------------------------------------------------------------------------*/ int ffgbclll( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ char *ttype, /* O - TTYPEn keyword value */ char *tunit, /* O - TUNITn keyword value */ char *dtype, /* O - datatype char: I, J, E, D, etc. */ LONGLONG *repeat, /* O - vector column repeat count */ double *tscal, /* O - TSCALn keyword value */ double *tzero, /* O - TZEROn keyword value */ LONGLONG *tnull, /* O - TNULLn keyword value integer cols only */ char *tdisp, /* O - TDISPn keyword value */ int *status) /* IO - error status */ /* get BINTABLE column keyword values */ { char name[FLEN_KEYWORD], comm[FLEN_COMMENT]; tcolumn *colptr; int tstatus; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if (colnum < 1 || colnum > (fptr->Fptr)->tfield) return(*status = BAD_COL_NUM); /* get what we can from the column structure */ colptr = (fptr->Fptr)->tableptr; /* pointer to first column */ colptr += (colnum -1); /* offset to correct column */ if (ttype) strcpy(ttype, colptr->ttype); if (dtype) { if (colptr->tdatatype < 0) /* add the "P" prefix for */ strcpy(dtype, "P"); /* variable length columns */ else dtype[0] = 0; if (abs(colptr->tdatatype) == TBIT) strcat(dtype, "X"); else if (abs(colptr->tdatatype) == TBYTE) strcat(dtype, "B"); else if (abs(colptr->tdatatype) == TLOGICAL) strcat(dtype, "L"); else if (abs(colptr->tdatatype) == TSTRING) strcat(dtype, "A"); else if (abs(colptr->tdatatype) == TSHORT) strcat(dtype, "I"); else if (abs(colptr->tdatatype) == TLONG) strcat(dtype, "J"); else if (abs(colptr->tdatatype) == TLONGLONG) strcat(dtype, "K"); else if (abs(colptr->tdatatype) == TFLOAT) strcat(dtype, "E"); else if (abs(colptr->tdatatype) == TDOUBLE) strcat(dtype, "D"); else if (abs(colptr->tdatatype) == TCOMPLEX) strcat(dtype, "C"); else if (abs(colptr->tdatatype) == TDBLCOMPLEX) strcat(dtype, "M"); } if (repeat) *repeat = colptr->trepeat; if (tscal) *tscal = colptr->tscale; if (tzero) *tzero = colptr->tzero; if (tnull) *tnull = colptr->tnull; /* read keywords to get additional parameters */ if (tunit) { ffkeyn("TUNIT", colnum, name, status); tstatus = 0; *tunit = '\0'; ffgkys(fptr, name, tunit, comm, &tstatus); } if (tdisp) { ffkeyn("TDISP", colnum, name, status); tstatus = 0; *tdisp = '\0'; ffgkys(fptr, name, tdisp, comm, &tstatus); } return(*status); } /*--------------------------------------------------------------------------*/ int ffghdn(fitsfile *fptr, /* I - FITS file pointer */ int *chdunum) /* O - number of the CHDU; 1 = primary array */ /* Return the number of the Current HDU in the FITS file. The primary array is HDU number 1. Note that this is one of the few cfitsio routines that does not return the error status value as the value of the function. */ { *chdunum = (fptr->HDUposition) + 1; return(*chdunum); } /*--------------------------------------------------------------------------*/ int ffghadll(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG *headstart, /* O - byte offset to beginning of CHDU */ LONGLONG *datastart, /* O - byte offset to beginning of next HDU */ LONGLONG *dataend, /* O - byte offset to beginning of next HDU */ int *status) /* IO - error status */ /* Return the address (= byte offset) in the FITS file to the beginning of the current HDU, the beginning of the data unit, and the end of the data unit. */ { if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { if (ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status) > 0) return(*status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if (ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } if (headstart) *headstart = (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu]; if (datastart) *datastart = (fptr->Fptr)->datastart; if (dataend) *dataend = (fptr->Fptr)->headstart[((fptr->Fptr)->curhdu) + 1]; return(*status); } /*--------------------------------------------------------------------------*/ int ffghof(fitsfile *fptr, /* I - FITS file pointer */ OFF_T *headstart, /* O - byte offset to beginning of CHDU */ OFF_T *datastart, /* O - byte offset to beginning of next HDU */ OFF_T *dataend, /* O - byte offset to beginning of next HDU */ int *status) /* IO - error status */ /* Return the address (= byte offset) in the FITS file to the beginning of the current HDU, the beginning of the data unit, and the end of the data unit. */ { if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { if (ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status) > 0) return(*status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if (ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } if (headstart) *headstart = (OFF_T) (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu]; if (datastart) *datastart = (OFF_T) (fptr->Fptr)->datastart; if (dataend) *dataend = (OFF_T) (fptr->Fptr)->headstart[((fptr->Fptr)->curhdu) + 1]; return(*status); } /*--------------------------------------------------------------------------*/ int ffghad(fitsfile *fptr, /* I - FITS file pointer */ long *headstart, /* O - byte offset to beginning of CHDU */ long *datastart, /* O - byte offset to beginning of next HDU */ long *dataend, /* O - byte offset to beginning of next HDU */ int *status) /* IO - error status */ /* Return the address (= byte offset) in the FITS file to the beginning of the current HDU, the beginning of the data unit, and the end of the data unit. */ { LONGLONG shead, sdata, edata; if (*status > 0) return(*status); ffghadll(fptr, &shead, &sdata, &edata, status); if (headstart) { if (shead > LONG_MAX) *status = NUM_OVERFLOW; else *headstart = (long) shead; } if (datastart) { if (sdata > LONG_MAX) *status = NUM_OVERFLOW; else *datastart = (long) sdata; } if (dataend) { if (edata > LONG_MAX) *status = NUM_OVERFLOW; else *dataend = (long) edata; } return(*status); } /*--------------------------------------------------------------------------*/ int ffrhdu(fitsfile *fptr, /* I - FITS file pointer */ int *hdutype, /* O - type of HDU */ int *status) /* IO - error status */ /* read the required keywords of the CHDU and initialize the corresponding structure elements that describe the format of the HDU */ { int ii, tstatus; char card[FLEN_CARD]; char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT]; char xname[FLEN_VALUE], *xtension, urltype[20]; if (*status > 0) return(*status); if (ffgrec(fptr, 1, card, status) > 0 ) /* get the 80-byte card */ { ffpmsg("Cannot read first keyword in header (ffrhdu)."); return(*status); } strncpy(name,card,8); /* first 8 characters = the keyword name */ name[8] = '\0'; for (ii=7; ii >= 0; ii--) /* replace trailing blanks with nulls */ { if (name[ii] == ' ') name[ii] = '\0'; else break; } if (ffpsvc(card, value, comm, status) > 0) /* parse value and comment */ { ffpmsg("Cannot read value of first keyword in header (ffrhdu):"); ffpmsg(card); return(*status); } if (!strcmp(name, "SIMPLE")) /* this is the primary array */ { ffpinit(fptr, status); /* initialize the primary array */ if (hdutype != NULL) *hdutype = 0; } else if (!strcmp(name, "XTENSION")) /* this is an XTENSION keyword */ { if (ffc2s(value, xname, status) > 0) /* get the value string */ { ffpmsg("Bad value string for XTENSION keyword:"); ffpmsg(value); return(*status); } xtension = xname; while (*xtension == ' ') /* ignore any leading spaces in name */ xtension++; if (!strcmp(xtension, "TABLE")) { ffainit(fptr, status); /* initialize the ASCII table */ if (hdutype != NULL) *hdutype = 1; } else if (!strcmp(xtension, "BINTABLE") || !strcmp(xtension, "A3DTABLE") || !strcmp(xtension, "3DTABLE") ) { ffbinit(fptr, status); /* initialize the binary table */ if (hdutype != NULL) *hdutype = 2; } else { tstatus = 0; ffpinit(fptr, &tstatus); /* probably an IMAGE extension */ if (tstatus == UNKNOWN_EXT && hdutype != NULL) *hdutype = -1; /* don't recognize this extension type */ else { *status = tstatus; if (hdutype != NULL) *hdutype = 0; } } } else /* not the start of a new extension */ { if (card[0] == 0 || card[0] == 10) /* some editors append this character to EOF */ { *status = END_OF_FILE; } else { *status = UNKNOWN_REC; /* found unknown type of record */ ffpmsg ("Extension doesn't start with SIMPLE or XTENSION keyword. (ffrhdu)"); ffpmsg(card); } } /* compare the starting position of the next HDU (if any) with the size */ /* of the whole file to see if this is the last HDU in the file */ if ((fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] < (fptr->Fptr)->logfilesize ) { (fptr->Fptr)->lasthdu = 0; /* no, not the last HDU */ } else { (fptr->Fptr)->lasthdu = 1; /* yes, this is the last HDU */ /* special code for mem:// type files (FITS file in memory) */ /* Allocate enough memory to hold the entire HDU. */ /* Without this code, CFITSIO would repeatedly realloc memory */ /* to incrementally increase the size of the file by 2880 bytes */ /* at a time, until it reached the final size */ ffurlt(fptr, urltype, status); if (!strcmp(urltype,"mem://") || !strcmp(urltype,"memkeep://")) { fftrun(fptr, (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1], status); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffpinit(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* initialize the parameters defining the structure of the primary array or an Image extension */ { int groups, tstatus, simple, bitpix, naxis, extend, nspace; int ttype = 0, bytlen = 0, ii, ntilebins; long pcount, gcount; LONGLONG naxes[999], npix, blank; double bscale, bzero; char comm[FLEN_COMMENT]; tcolumn *colptr; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); (fptr->Fptr)->hdutype = IMAGE_HDU; /* primary array or IMAGE extension */ (fptr->Fptr)->headend = (fptr->Fptr)->logfilesize; /* set max size */ groups = 0; tstatus = *status; /* get all the descriptive info about this HDU */ ffgphd(fptr, 999, &simple, &bitpix, &naxis, naxes, &pcount, &gcount, &extend, &bscale, &bzero, &blank, &nspace, status); if (*status == NOT_IMAGE) *status = tstatus; /* ignore 'unknown extension type' error */ else if (*status > 0) return(*status); /* the logical end of the header is 80 bytes before the current position, minus any trailing blank keywords just before the END keyword. */ (fptr->Fptr)->headend = (fptr->Fptr)->nextkey - (80 * (nspace + 1)); /* the data unit begins at the beginning of the next logical block */ (fptr->Fptr)->datastart = (((fptr->Fptr)->nextkey - 80) / 2880 + 1) * 2880; if (naxis > 0 && naxes[0] == 0) /* test for 'random groups' */ { tstatus = 0; ffmaky(fptr, 2, status); /* reset to beginning of header */ if (ffgkyl(fptr, "GROUPS", &groups, comm, &tstatus)) groups = 0; /* GROUPS keyword not found */ } if (bitpix == BYTE_IMG) /* test bitpix and set the datatype code */ { ttype=TBYTE; bytlen=1; } else if (bitpix == SHORT_IMG) { ttype=TSHORT; bytlen=2; } else if (bitpix == LONG_IMG) { ttype=TLONG; bytlen=4; } else if (bitpix == LONGLONG_IMG) { ttype=TLONGLONG; bytlen=8; } else if (bitpix == FLOAT_IMG) { ttype=TFLOAT; bytlen=4; } else if (bitpix == DOUBLE_IMG) { ttype=TDOUBLE; bytlen=8; } /* calculate the size of the primary array */ (fptr->Fptr)->imgdim = naxis; if (naxis == 0) { npix = 0; } else { if (groups) { npix = 1; /* NAXIS1 = 0 is a special flag for 'random groups' */ } else { npix = naxes[0]; } (fptr->Fptr)->imgnaxis[0] = naxes[0]; for (ii=1; ii < naxis; ii++) { npix = npix*naxes[ii]; /* calc number of pixels in the array */ (fptr->Fptr)->imgnaxis[ii] = naxes[ii]; } } /* now we know everything about the array; just fill in the parameters: the next HDU begins in the next logical block after the data */ (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] = (fptr->Fptr)->datastart + ( ((LONGLONG) pcount + npix) * bytlen * gcount + 2879) / 2880 * 2880; /* initialize the fictitious heap starting address (immediately following the array data) and a zero length heap. This is used to find the end of the data when checking the fill values in the last block. */ (fptr->Fptr)->heapstart = (npix + pcount) * bytlen * gcount; (fptr->Fptr)->heapsize = 0; (fptr->Fptr)->compressimg = 0; /* this is not a compressed image */ if (naxis == 0) { (fptr->Fptr)->rowlength = 0; /* rows have zero length */ (fptr->Fptr)->tfield = 0; /* table has no fields */ /* free the tile-compressed image cache, if it exists */ if ((fptr->Fptr)->tilerow) { ntilebins = (((fptr->Fptr)->znaxis[0] - 1) / ((fptr->Fptr)->tilesize[0])) + 1; for (ii = 0; ii < ntilebins; ii++) { if ((fptr->Fptr)->tiledata[ii]) { free((fptr->Fptr)->tiledata[ii]); } if ((fptr->Fptr)->tilenullarray[ii]) { free((fptr->Fptr)->tilenullarray[ii]); } } free((fptr->Fptr)->tileanynull); free((fptr->Fptr)->tiletype); free((fptr->Fptr)->tiledatasize); free((fptr->Fptr)->tilenullarray); free((fptr->Fptr)->tiledata); free((fptr->Fptr)->tilerow); (fptr->Fptr)->tileanynull = 0; (fptr->Fptr)->tiletype = 0; (fptr->Fptr)->tiledatasize = 0; (fptr->Fptr)->tilenullarray = 0; (fptr->Fptr)->tiledata = 0; (fptr->Fptr)->tilerow = 0; } if ((fptr->Fptr)->tableptr) free((fptr->Fptr)->tableptr); /* free memory for the old CHDU */ (fptr->Fptr)->tableptr = 0; /* set a null table structure pointer */ (fptr->Fptr)->numrows = 0; (fptr->Fptr)->origrows = 0; } else { /* The primary array is actually interpreted as a binary table. There are two columns: the first column contains the group parameters if any. The second column contains the primary array of data as a single vector column element. In the case of 'random grouped' format, each group is stored in a separate row of the table. */ /* the number of rows is equal to the number of groups */ (fptr->Fptr)->numrows = gcount; (fptr->Fptr)->origrows = gcount; (fptr->Fptr)->rowlength = (npix + pcount) * bytlen; /* total size */ (fptr->Fptr)->tfield = 2; /* 2 fields: group params and the image */ /* free the tile-compressed image cache, if it exists */ if ((fptr->Fptr)->tilerow) { ntilebins = (((fptr->Fptr)->znaxis[0] - 1) / ((fptr->Fptr)->tilesize[0])) + 1; for (ii = 0; ii < ntilebins; ii++) { if ((fptr->Fptr)->tiledata[ii]) { free((fptr->Fptr)->tiledata[ii]); } if ((fptr->Fptr)->tilenullarray[ii]) { free((fptr->Fptr)->tilenullarray[ii]); } } free((fptr->Fptr)->tileanynull); free((fptr->Fptr)->tiletype); free((fptr->Fptr)->tiledatasize); free((fptr->Fptr)->tilenullarray); free((fptr->Fptr)->tiledata); free((fptr->Fptr)->tilerow); (fptr->Fptr)->tileanynull = 0; (fptr->Fptr)->tiletype = 0; (fptr->Fptr)->tiledatasize = 0; (fptr->Fptr)->tilenullarray = 0; (fptr->Fptr)->tiledata = 0; (fptr->Fptr)->tilerow = 0; } if ((fptr->Fptr)->tableptr) free((fptr->Fptr)->tableptr); /* free memory for the old CHDU */ colptr = (tcolumn *) calloc(2, sizeof(tcolumn) ) ; if (!colptr) { ffpmsg ("malloc failed to get memory for FITS array descriptors (ffpinit)"); (fptr->Fptr)->tableptr = 0; /* set a null table structure pointer */ return(*status = ARRAY_TOO_BIG); } /* copy the table structure address to the fitsfile structure */ (fptr->Fptr)->tableptr = colptr; /* the first column represents the group parameters, if any */ colptr->tbcol = 0; colptr->tdatatype = ttype; colptr->twidth = bytlen; colptr->trepeat = (LONGLONG) pcount; colptr->tscale = 1.; colptr->tzero = 0.; colptr->tnull = blank; colptr++; /* increment pointer to the second column */ /* the second column represents the image array */ colptr->tbcol = pcount * bytlen; /* col starts after the group parms */ colptr->tdatatype = ttype; colptr->twidth = bytlen; colptr->trepeat = npix; colptr->tscale = bscale; colptr->tzero = bzero; colptr->tnull = blank; } /* reset next keyword pointer to the start of the header */ (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu ]; return(*status); } /*--------------------------------------------------------------------------*/ int ffainit(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ { /* initialize the parameters defining the structure of an ASCII table */ int ii, nspace, ntilebins; long tfield; LONGLONG pcount, rowlen, nrows, tbcoln; tcolumn *colptr = 0; char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT]; char message[FLEN_ERRMSG], errmsg[FLEN_ERRMSG]; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); (fptr->Fptr)->hdutype = ASCII_TBL; /* set that this is an ASCII table */ (fptr->Fptr)->headend = (fptr->Fptr)->logfilesize; /* set max size */ /* get table parameters and test that the header is a valid: */ if (ffgttb(fptr, &rowlen, &nrows, &pcount, &tfield, status) > 0) return(*status); if (pcount != 0) { ffpmsg("PCOUNT keyword not equal to 0 in ASCII table (ffainit)."); snprintf(errmsg, FLEN_ERRMSG," PCOUNT = %ld", (long) pcount); ffpmsg(errmsg); return(*status = BAD_PCOUNT); } (fptr->Fptr)->rowlength = rowlen; /* store length of a row */ (fptr->Fptr)->tfield = tfield; /* store number of table fields in row */ /* free the tile-compressed image cache, if it exists */ if ((fptr->Fptr)->tilerow) { ntilebins = (((fptr->Fptr)->znaxis[0] - 1) / ((fptr->Fptr)->tilesize[0])) + 1; for (ii = 0; ii < ntilebins; ii++) { if ((fptr->Fptr)->tiledata[ii]) { free((fptr->Fptr)->tiledata[ii]); } if ((fptr->Fptr)->tilenullarray[ii]) { free((fptr->Fptr)->tilenullarray[ii]); } } free((fptr->Fptr)->tileanynull); free((fptr->Fptr)->tiletype); free((fptr->Fptr)->tiledatasize); free((fptr->Fptr)->tilenullarray); free((fptr->Fptr)->tiledata); free((fptr->Fptr)->tilerow); (fptr->Fptr)->tileanynull = 0; (fptr->Fptr)->tiletype = 0; (fptr->Fptr)->tiledatasize = 0; (fptr->Fptr)->tilenullarray = 0; (fptr->Fptr)->tiledata = 0; (fptr->Fptr)->tilerow = 0; } if ((fptr->Fptr)->tableptr) free((fptr->Fptr)->tableptr); /* free memory for the old CHDU */ /* mem for column structures ; space is initialized = 0 */ if (tfield > 0) { colptr = (tcolumn *) calloc(tfield, sizeof(tcolumn) ); if (!colptr) { ffpmsg ("malloc failed to get memory for FITS table descriptors (ffainit)"); (fptr->Fptr)->tableptr = 0; /* set a null table structure pointer */ return(*status = ARRAY_TOO_BIG); } } /* copy the table structure address to the fitsfile structure */ (fptr->Fptr)->tableptr = colptr; /* initialize the table field parameters */ for (ii = 0; ii < tfield; ii++, colptr++) { colptr->ttype[0] = '\0'; /* null column name */ colptr->tscale = 1.; colptr->tzero = 0.; colptr->strnull[0] = ASCII_NULL_UNDEFINED; /* null value undefined */ colptr->tbcol = -1; /* initialize to illegal value */ colptr->tdatatype = -9999; /* initialize to illegal value */ } /* Initialize the fictitious heap starting address (immediately following the table data) and a zero length heap. This is used to find the end of the table data when checking the fill values in the last block. There is no special data following an ASCII table. */ (fptr->Fptr)->numrows = nrows; (fptr->Fptr)->origrows = nrows; (fptr->Fptr)->heapstart = rowlen * nrows; (fptr->Fptr)->heapsize = 0; (fptr->Fptr)->compressimg = 0; /* this is not a compressed image */ /* now search for the table column keywords and the END keyword */ for (nspace = 0, ii = 8; 1; ii++) /* infinite loop */ { ffgkyn(fptr, ii, name, value, comm, status); /* try to ignore minor syntax errors */ if (*status == NO_QUOTE) { strcat(value, "'"); *status = 0; } else if (*status == BAD_KEYCHAR) { *status = 0; } if (*status == END_OF_FILE) { ffpmsg("END keyword not found in ASCII table header (ffainit)."); return(*status = NO_END); } else if (*status > 0) return(*status); else if (name[0] == 'T') /* keyword starts with 'T' ? */ ffgtbp(fptr, name, value, status); /* test if column keyword */ else if (!FSTRCMP(name, "END")) /* is this the END keyword? */ break; if (!name[0] && !value[0] && !comm[0]) /* a blank keyword? */ nspace++; else nspace = 0; } /* test that all required keywords were found and have legal values */ colptr = (fptr->Fptr)->tableptr; for (ii = 0; ii < tfield; ii++, colptr++) { tbcoln = colptr->tbcol; /* the starting column number (zero based) */ if (colptr->tdatatype == -9999) { ffkeyn("TFORM", ii+1, name, status); /* construct keyword name */ snprintf(message,FLEN_ERRMSG,"Required %s keyword not found (ffainit).", name); ffpmsg(message); return(*status = NO_TFORM); } else if (tbcoln == -1) { ffkeyn("TBCOL", ii+1, name, status); /* construct keyword name */ snprintf(message,FLEN_ERRMSG,"Required %s keyword not found (ffainit).", name); ffpmsg(message); return(*status = NO_TBCOL); } else if ((fptr->Fptr)->rowlength != 0 && (tbcoln < 0 || tbcoln >= (fptr->Fptr)->rowlength ) ) { ffkeyn("TBCOL", ii+1, name, status); /* construct keyword name */ snprintf(message,FLEN_ERRMSG,"Value of %s keyword out of range: %ld (ffainit).", name, (long) tbcoln); ffpmsg(message); return(*status = BAD_TBCOL); } else if ((fptr->Fptr)->rowlength != 0 && tbcoln + colptr->twidth > (fptr->Fptr)->rowlength ) { snprintf(message,FLEN_ERRMSG,"Column %d is too wide to fit in table (ffainit)", ii+1); ffpmsg(message); snprintf(message, FLEN_ERRMSG," TFORM = %s and NAXIS1 = %ld", colptr->tform, (long) (fptr->Fptr)->rowlength); ffpmsg(message); return(*status = COL_TOO_WIDE); } } /* now we know everything about the table; just fill in the parameters: the 'END' record is 80 bytes before the current position, minus any trailing blank keywords just before the END keyword. */ (fptr->Fptr)->headend = (fptr->Fptr)->nextkey - (80 * (nspace + 1)); /* the data unit begins at the beginning of the next logical block */ (fptr->Fptr)->datastart = (((fptr->Fptr)->nextkey - 80) / 2880 + 1) * 2880; /* the next HDU begins in the next logical block after the data */ (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] = (fptr->Fptr)->datastart + ( ((LONGLONG)rowlen * nrows + 2879) / 2880 * 2880 ); /* reset next keyword pointer to the start of the header */ (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu ]; return(*status); } /*--------------------------------------------------------------------------*/ int ffbinit(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ { /* initialize the parameters defining the structure of a binary table */ int ii, nspace, ntilebins; long tfield; LONGLONG pcount, rowlen, nrows, totalwidth; tcolumn *colptr = 0; char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT]; char message[FLEN_ERRMSG]; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); (fptr->Fptr)->hdutype = BINARY_TBL; /* set that this is a binary table */ (fptr->Fptr)->headend = (fptr->Fptr)->logfilesize; /* set max size */ /* get table parameters and test that the header is valid: */ if (ffgttb(fptr, &rowlen, &nrows, &pcount, &tfield, status) > 0) return(*status); (fptr->Fptr)->rowlength = rowlen; /* store length of a row */ (fptr->Fptr)->tfield = tfield; /* store number of table fields in row */ /* free the tile-compressed image cache, if it exists */ if ((fptr->Fptr)->tilerow) { ntilebins = (((fptr->Fptr)->znaxis[0] - 1) / ((fptr->Fptr)->tilesize[0])) + 1; for (ii = 0; ii < ntilebins; ii++) { if ((fptr->Fptr)->tiledata[ii]) { free((fptr->Fptr)->tiledata[ii]); } if ((fptr->Fptr)->tilenullarray[ii]) { free((fptr->Fptr)->tilenullarray[ii]); } } free((fptr->Fptr)->tileanynull); free((fptr->Fptr)->tiletype); free((fptr->Fptr)->tiledatasize); free((fptr->Fptr)->tilenullarray); free((fptr->Fptr)->tiledata); free((fptr->Fptr)->tilerow); (fptr->Fptr)->tileanynull = 0; (fptr->Fptr)->tiletype = 0; (fptr->Fptr)->tiledatasize = 0; (fptr->Fptr)->tilenullarray = 0; (fptr->Fptr)->tiledata = 0; (fptr->Fptr)->tilerow = 0; } if ((fptr->Fptr)->tableptr) free((fptr->Fptr)->tableptr); /* free memory for the old CHDU */ /* mem for column structures ; space is initialized = 0 */ if (tfield > 0) { colptr = (tcolumn *) calloc(tfield, sizeof(tcolumn) ); if (!colptr) { ffpmsg ("malloc failed to get memory for FITS table descriptors (ffbinit)"); (fptr->Fptr)->tableptr = 0; /* set a null table structure pointer */ return(*status = ARRAY_TOO_BIG); } } /* copy the table structure address to the fitsfile structure */ (fptr->Fptr)->tableptr = colptr; /* initialize the table field parameters */ for (ii = 0; ii < tfield; ii++, colptr++) { colptr->ttype[0] = '\0'; /* null column name */ colptr->tscale = 1.; colptr->tzero = 0.; colptr->tnull = NULL_UNDEFINED; /* (integer) null value undefined */ colptr->tdatatype = -9999; /* initialize to illegal value */ colptr->trepeat = 1; colptr->strnull[0] = '\0'; /* for ASCII string columns (TFORM = rA) */ } /* Initialize the heap starting address (immediately following the table data) and the size of the heap. This is used to find the end of the table data when checking the fill values in the last block. */ (fptr->Fptr)->numrows = nrows; (fptr->Fptr)->origrows = nrows; (fptr->Fptr)->heapstart = rowlen * nrows; (fptr->Fptr)->heapsize = pcount; (fptr->Fptr)->compressimg = 0; /* initialize as not a compressed image */ /* now search for the table column keywords and the END keyword */ for (nspace = 0, ii = 8; 1; ii++) /* infinite loop */ { ffgkyn(fptr, ii, name, value, comm, status); /* try to ignore minor syntax errors */ if (*status == NO_QUOTE) { strcat(value, "'"); *status = 0; } else if (*status == BAD_KEYCHAR) { *status = 0; } if (*status == END_OF_FILE) { ffpmsg("END keyword not found in binary table header (ffbinit)."); return(*status = NO_END); } else if (*status > 0) return(*status); else if (name[0] == 'T') /* keyword starts with 'T' ? */ ffgtbp(fptr, name, value, status); /* test if column keyword */ else if (!FSTRCMP(name, "ZIMAGE")) { if (value[0] == 'T') (fptr->Fptr)->compressimg = 1; /* this is a compressed image */ } else if (!FSTRCMP(name, "END")) /* is this the END keyword? */ break; if (!name[0] && !value[0] && !comm[0]) /* a blank keyword? */ nspace++; else nspace = 0; /* reset number of consecutive spaces before END */ } /* test that all the required keywords were found and have legal values */ colptr = (fptr->Fptr)->tableptr; /* set pointer to first column */ for (ii = 0; ii < tfield; ii++, colptr++) { if (colptr->tdatatype == -9999) { ffkeyn("TFORM", ii+1, name, status); /* construct keyword name */ snprintf(message,FLEN_ERRMSG,"Required %s keyword not found (ffbinit).", name); ffpmsg(message); return(*status = NO_TFORM); } } /* now we know everything about the table; just fill in the parameters: the 'END' record is 80 bytes before the current position, minus any trailing blank keywords just before the END keyword. */ (fptr->Fptr)->headend = (fptr->Fptr)->nextkey - (80 * (nspace + 1)); /* the data unit begins at the beginning of the next logical block */ (fptr->Fptr)->datastart = (((fptr->Fptr)->nextkey - 80) / 2880 + 1) * 2880; /* the next HDU begins in the next logical block after the data */ (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] = (fptr->Fptr)->datastart + ( ((fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize + 2879) / 2880 * 2880 ); /* determine the byte offset to the beginning of each column */ ffgtbc(fptr, &totalwidth, status); if (totalwidth != rowlen) { snprintf(message,FLEN_ERRMSG, "NAXIS1 = %ld is not equal to the sum of column widths: %ld", (long) rowlen, (long) totalwidth); ffpmsg(message); *status = BAD_ROW_WIDTH; } /* reset next keyword pointer to the start of the header */ (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu ]; if ( (fptr->Fptr)->compressimg == 1) /* Is this a compressed image */ imcomp_get_compressed_image_par(fptr, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgabc(int tfields, /* I - number of columns in the table */ char **tform, /* I - value of TFORMn keyword for each column */ int space, /* I - number of spaces to leave between cols */ long *rowlen, /* O - total width of a table row */ long *tbcol, /* O - starting byte in row for each column */ int *status) /* IO - error status */ /* calculate the starting byte offset of each column of an ASCII table and the total length of a row, in bytes. The input space value determines how many blank spaces to leave between each column (1 is recommended). */ { int ii, datacode, decims; long width; if (*status > 0) return(*status); *rowlen=0; if (tfields <= 0) return(*status); tbcol[0] = 1; for (ii = 0; ii < tfields; ii++) { tbcol[ii] = *rowlen + 1; /* starting byte in row of column */ ffasfm(tform[ii], &datacode, &width, &decims, status); *rowlen += (width + space); /* total length of row */ } *rowlen -= space; /* don't add space after the last field */ return (*status); } /*--------------------------------------------------------------------------*/ int ffgtbc(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG *totalwidth, /* O - total width of a table row */ int *status) /* IO - error status */ { /* calculate the starting byte offset of each column of a binary table. Use the values of the datatype code and repeat counts in the column structure. Return the total length of a row, in bytes. */ int tfields, ii; LONGLONG nbytes; tcolumn *colptr; char message[FLEN_ERRMSG], *cptr; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); tfields = (fptr->Fptr)->tfield; colptr = (fptr->Fptr)->tableptr; /* point to first column structure */ *totalwidth = 0; for (ii = 0; ii < tfields; ii++, colptr++) { colptr->tbcol = *totalwidth; /* byte offset in row to this column */ if (colptr->tdatatype == TSTRING) { nbytes = colptr->trepeat; /* one byte per char */ } else if (colptr->tdatatype == TBIT) { nbytes = ( colptr->trepeat + 7) / 8; } else if (colptr->tdatatype > 0) { nbytes = colptr->trepeat * (colptr->tdatatype / 10); } else { cptr = colptr->tform; while (isdigit(*cptr)) cptr++; if (*cptr == 'P') /* this is a 'P' variable length descriptor (neg. tdatatype) */ nbytes = colptr->trepeat * 8; else if (*cptr == 'Q') /* this is a 'Q' variable length descriptor (neg. tdatatype) */ nbytes = colptr->trepeat * 16; else { snprintf(message,FLEN_ERRMSG, "unknown binary table column type: %s", colptr->tform); ffpmsg(message); *status = BAD_TFORM; return(*status); } } *totalwidth = *totalwidth + nbytes; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgtbp(fitsfile *fptr, /* I - FITS file pointer */ char *name, /* I - name of the keyword */ char *value, /* I - value string of the keyword */ int *status) /* IO - error status */ { /* Get TaBle Parameter. The input keyword name begins with the letter T. Test if the keyword is one of the table column definition keywords of an ASCII or binary table. If so, decode it and update the value in the structure. */ int tstatus, datacode, decimals; long width, repeat, nfield, ivalue; LONGLONG jjvalue; double dvalue; char tvalue[FLEN_VALUE], *loc; char message[FLEN_ERRMSG]; tcolumn *colptr; if (*status > 0) return(*status); tstatus = 0; /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if(!FSTRNCMP(name + 1, "TYPE", 4) ) { /* get the index number */ if( ffc2ii(name + 5, &nfield, &tstatus) > 0) /* read index no. */ return(*status); /* must not be an indexed keyword */ if (nfield < 1 || nfield > (fptr->Fptr)->tfield ) /* out of range */ return(*status); colptr = (fptr->Fptr)->tableptr; /* get pointer to columns */ colptr = colptr + nfield - 1; /* point to the correct column */ if (ffc2s(value, tvalue, &tstatus) > 0) /* remove quotes */ return(*status); strcpy(colptr->ttype, tvalue); /* copy col name to structure */ } else if(!FSTRNCMP(name + 1, "FORM", 4) ) { /* get the index number */ if( ffc2ii(name + 5, &nfield, &tstatus) > 0) /* read index no. */ return(*status); /* must not be an indexed keyword */ if (nfield < 1 || nfield > (fptr->Fptr)->tfield ) /* out of range */ return(*status); colptr = (fptr->Fptr)->tableptr; /* get pointer to columns */ colptr = colptr + nfield - 1; /* point to the correct column */ if (ffc2s(value, tvalue, &tstatus) > 0) /* remove quotes */ return(*status); strncpy(colptr->tform, tvalue, 9); /* copy TFORM to structure */ colptr->tform[9] = '\0'; /* make sure it is terminated */ if ((fptr->Fptr)->hdutype == ASCII_TBL) /* ASCII table */ { if (ffasfm(tvalue, &datacode, &width, &decimals, status) > 0) return(*status); /* bad format code */ colptr->tdatatype = TSTRING; /* store datatype code */ colptr->trepeat = 1; /* field repeat count == 1 */ colptr->twidth = width; /* the width of the field, in bytes */ } else /* binary table */ { if (ffbnfm(tvalue, &datacode, &repeat, &width, status) > 0) return(*status); /* bad format code */ colptr->tdatatype = datacode; /* store datatype code */ colptr->trepeat = (LONGLONG) repeat; /* field repeat count */ /* Don't overwrite the unit string width if it was previously */ /* set by a TDIMn keyword and has a legal value */ if (datacode == TSTRING) { if (colptr->twidth == 0 || colptr->twidth > repeat) colptr->twidth = width; /* width of a unit string */ } else { colptr->twidth = width; /* width of a unit value in chars */ } } } else if(!FSTRNCMP(name + 1, "BCOL", 4) ) { /* get the index number */ if( ffc2ii(name + 5, &nfield, &tstatus) > 0) /* read index no. */ return(*status); /* must not be an indexed keyword */ if (nfield < 1 || nfield > (fptr->Fptr)->tfield ) /* out of range */ return(*status); colptr = (fptr->Fptr)->tableptr; /* get pointer to columns */ colptr = colptr + nfield - 1; /* point to the correct column */ if ((fptr->Fptr)->hdutype == BINARY_TBL) return(*status); /* binary tables don't have TBCOL keywords */ if (ffc2ii(value, &ivalue, status) > 0) { snprintf(message, FLEN_ERRMSG, "Error reading value of %s as an integer: %s", name, value); ffpmsg(message); return(*status); } colptr->tbcol = ivalue - 1; /* convert to zero base */ } else if(!FSTRNCMP(name + 1, "SCAL", 4) ) { /* get the index number */ if( ffc2ii(name + 5, &nfield, &tstatus) > 0) /* read index no. */ return(*status); /* must not be an indexed keyword */ if (nfield < 1 || nfield > (fptr->Fptr)->tfield ) /* out of range */ return(*status); colptr = (fptr->Fptr)->tableptr; /* get pointer to columns */ colptr = colptr + nfield - 1; /* point to the correct column */ if (ffc2dd(value, &dvalue, &tstatus) > 0) { snprintf(message,FLEN_ERRMSG, "Error reading value of %s as a double: %s", name, value); ffpmsg(message); /* ignore this error, so don't return error status */ return(*status); } colptr->tscale = dvalue; } else if(!FSTRNCMP(name + 1, "ZERO", 4) ) { /* get the index number */ if( ffc2ii(name + 5, &nfield, &tstatus) > 0) /* read index no. */ return(*status); /* must not be an indexed keyword */ if (nfield < 1 || nfield > (fptr->Fptr)->tfield ) /* out of range */ return(*status); colptr = (fptr->Fptr)->tableptr; /* get pointer to columns */ colptr = colptr + nfield - 1; /* point to the correct column */ if (ffc2dd(value, &dvalue, &tstatus) > 0) { snprintf(message,FLEN_ERRMSG, "Error reading value of %s as a double: %s", name, value); ffpmsg(message); /* ignore this error, so don't return error status */ return(*status); } colptr->tzero = dvalue; } else if(!FSTRNCMP(name + 1, "NULL", 4) ) { /* get the index number */ if( ffc2ii(name + 5, &nfield, &tstatus) > 0) /* read index no. */ return(*status); /* must not be an indexed keyword */ if (nfield < 1 || nfield > (fptr->Fptr)->tfield ) /* out of range */ return(*status); colptr = (fptr->Fptr)->tableptr; /* get pointer to columns */ colptr = colptr + nfield - 1; /* point to the correct column */ if ((fptr->Fptr)->hdutype == ASCII_TBL) /* ASCII table */ { if (ffc2s(value, tvalue, &tstatus) > 0) /* remove quotes */ return(*status); strncpy(colptr->strnull, tvalue, 17); /* copy TNULL string */ colptr->strnull[17] = '\0'; /* terminate the strnull field */ } else /* binary table */ { if (ffc2jj(value, &jjvalue, &tstatus) > 0) { snprintf(message,FLEN_ERRMSG, "Error reading value of %s as an integer: %s", name, value); ffpmsg(message); /* ignore this error, so don't return error status */ return(*status); } colptr->tnull = jjvalue; /* null value for integer column */ } } else if(!FSTRNCMP(name + 1, "DIM", 3) ) { if ((fptr->Fptr)->hdutype == ASCII_TBL) /* ASCII table */ return(*status); /* ASCII tables don't support TDIMn keyword */ /* get the index number */ if( ffc2ii(name + 4, &nfield, &tstatus) > 0) /* read index no. */ return(*status); /* must not be an indexed keyword */ if (nfield < 1 || nfield > (fptr->Fptr)->tfield ) /* out of range */ return(*status); colptr = (fptr->Fptr)->tableptr; /* get pointer to columns */ colptr = colptr + nfield - 1; /* point to the correct column */ /* uninitialized columns have tdatatype set = -9999 */ if (colptr->tdatatype != -9999 && colptr->tdatatype != TSTRING) return(*status); /* this is not an ASCII string column */ loc = strchr(value, '(' ); /* find the opening parenthesis */ if (!loc) return(*status); /* not a proper TDIM keyword */ loc++; width = strtol(loc, &loc, 10); /* read size of first dimension */ if (colptr->trepeat != 1 && colptr->trepeat < width) return(*status); /* string length is greater than column width */ colptr->twidth = width; /* set width of a unit string in chars */ } else if (!FSTRNCMP(name + 1, "HEAP", 4) ) { if ((fptr->Fptr)->hdutype == ASCII_TBL) /* ASCII table */ return(*status); /* ASCII tables don't have a heap */ if (ffc2jj(value, &jjvalue, &tstatus) > 0) { snprintf(message,FLEN_ERRMSG, "Error reading value of %s as an integer: %s", name, value); ffpmsg(message); /* ignore this error, so don't return error status */ return(*status); } (fptr->Fptr)->heapstart = jjvalue; /* starting byte of the heap */ return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgcprll( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number (1 = 1st column of table) */ LONGLONG firstrow, /* I - first row (1 = 1st row of table) */ LONGLONG firstelem, /* I - first element within vector (1 = 1st) */ LONGLONG nelem, /* I - number of elements to read or write */ int writemode, /* I - = 1 if writing data, = 0 if reading data */ /* If = 2, then writing data, but don't modify */ /* the returned values of repeat and incre. */ /* If = -1, then reading data in reverse */ /* direction. */ /* If writemode has 16 added, then treat */ /* TSTRING column as TBYTE vector */ double *scale, /* O - FITS scaling factor (TSCALn keyword value) */ double *zero, /* O - FITS scaling zero pt (TZEROn keyword value) */ char *tform, /* O - ASCII column format: value of TFORMn keyword */ long *twidth, /* O - width of ASCII column (characters) */ int *tcode, /* O - abs(column datatype code): I*4=41, R*4=42, etc */ int *maxelem, /* O - max number of elements that fit in buffer */ LONGLONG *startpos,/* O - offset in file to starting row & column */ LONGLONG *elemnum, /* O - starting element number ( 0 = 1st element) */ long *incre, /* O - byte offset between elements within a row */ LONGLONG *repeat, /* O - number of elements in a row (vector column) */ LONGLONG *rowlen, /* O - length of a row, in bytes */ int *hdutype, /* O - HDU type: 0, 1, 2 = primary, table, bintable */ LONGLONG *tnull, /* O - null value for integer columns */ char *snull, /* O - null value for ASCII table columns */ int *status) /* IO - error status */ /* Get Column PaRameters, and test starting row and element numbers for validity. This is a workhorse routine that is call by nearly every other routine that reads or writes to FITS files. */ { int nulpos, rangecheck = 1, tstatus = 0; LONGLONG datastart, endpos; long nblock; LONGLONG heapoffset, lrepeat, endrow, nrows, tbcol; char message[FLEN_ERRMSG]; tcolumn *colptr; if (fptr->HDUposition != (fptr->Fptr)->curhdu) { /* reset position to the correct HDU if necessary */ ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { /* rescan header if data structure is undefined */ if ( ffrdef(fptr, status) > 0) return(*status); } else if (writemode > 0 && writemode != 15) { /* Only terminate the header with the END card if */ /* writing to the stdout stream (don't have random access). */ /* Initialize STREAM_DRIVER to be the device number for */ /* writing FITS files directly out to the stdout stream. */ /* This only needs to be done once and is thread safe. */ if (STREAM_DRIVER <= 0 || STREAM_DRIVER > 40) { urltype2driver("stream://", &STREAM_DRIVER); } if ((fptr->Fptr)->driver == STREAM_DRIVER) { if ((fptr->Fptr)->ENDpos != maxvalue((fptr->Fptr)->headend , (fptr->Fptr)->datastart -2880)) { ffwend(fptr, status); } } } /* Do sanity check of input parameters */ if (firstrow < 1) { if ((fptr->Fptr)->hdutype == IMAGE_HDU) /* Primary Array or IMAGE */ { snprintf(message,FLEN_ERRMSG, "Image group number is less than 1: %.0f", (double) firstrow); ffpmsg(message); return(*status = BAD_ROW_NUM); } else { snprintf(message, FLEN_ERRMSG,"Starting row number is less than 1: %.0f", (double) firstrow); ffpmsg(message); return(*status = BAD_ROW_NUM); } } else if ((fptr->Fptr)->hdutype != ASCII_TBL && firstelem < 1) { snprintf(message, FLEN_ERRMSG,"Starting element number less than 1: %ld", (long) firstelem); ffpmsg(message); return(*status = BAD_ELEM_NUM); } else if (nelem < 0) { snprintf(message, FLEN_ERRMSG,"Tried to read or write less than 0 elements: %.0f", (double) nelem); ffpmsg(message); return(*status = NEG_BYTES); } else if (colnum < 1 || colnum > (fptr->Fptr)->tfield) { snprintf(message, FLEN_ERRMSG,"Specified column number is out of range: %d", colnum); ffpmsg(message); snprintf(message, FLEN_ERRMSG," There are %d columns in this table.", (fptr->Fptr)->tfield ); ffpmsg(message); return(*status = BAD_COL_NUM); } /* copy relevant parameters from the structure */ *hdutype = (fptr->Fptr)->hdutype; /* image, ASCII table, or BINTABLE */ *rowlen = (fptr->Fptr)->rowlength; /* width of the table, in bytes */ datastart = (fptr->Fptr)->datastart; /* offset in file to start of table */ colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ *scale = colptr->tscale; /* value scaling factor; default = 1.0 */ *zero = colptr->tzero; /* value scaling zeropoint; default = 0.0 */ *tnull = colptr->tnull; /* null value for integer columns */ tbcol = colptr->tbcol; /* offset to start of column within row */ *twidth = colptr->twidth; /* width of a single datum, in bytes */ *incre = colptr->twidth; /* increment between datums, in bytes */ *tcode = colptr->tdatatype; *repeat = colptr->trepeat; strcpy(tform, colptr->tform); /* value of TFORMn keyword */ strcpy(snull, colptr->strnull); /* null value for ASCII table columns */ if (*hdutype == ASCII_TBL && snull[0] == '\0') { /* In ASCII tables, a null value is equivalent to all spaces */ strcpy(snull, " "); /* maximum of 17 spaces */ nulpos = minvalue(17, *twidth); /* truncate to width of column */ snull[nulpos] = '\0'; } /* Special case: use writemode = 15,16,17,18 to interpret TSTRING columns as TBYTE vectors instead (but not for ASCII tables). writemode = 15 equivalent to writemode =-1 writemode = 16 equivalent to writemode = 0 writemode = 17 equivalent to writemode = 1 writemode = 18 equivalent to writemode = 2 */ if (writemode >= 15 && writemode <= 18) { if (abs(*tcode) == TSTRING && *hdutype != ASCII_TBL ) { *incre = 1; /* each element is 1 byte wide */ if (*tcode < 0) *repeat = *twidth; /* variable columns appear to put width in *twidth */ *twidth = 1; /* width of each element */ *scale = 1.0; /* no scaling */ *zero = 0.0; *tnull = NULL_UNDEFINED; /* don't test for nulls */ *maxelem = DBUFFSIZE; if (*tcode < 0) { *tcode = -TBYTE; /* variable-length */ } else { *tcode = TBYTE; } } /* translate to the equivalent as listed above */ writemode -= 16; } /* Special case: interpret writemode = -1 as reading data, but */ /* don't do error check for exceeding the range of pixels */ if (writemode == -1) { writemode = 0; rangecheck = 0; } /* Special case: interprete 'X' column as 'B' */ if (abs(*tcode) == TBIT) { *tcode = *tcode / TBIT * TBYTE; *repeat = (*repeat + 7) / 8; } /* Special case: support the 'rAw' format in BINTABLEs */ if (*hdutype == BINARY_TBL && *tcode == TSTRING) { if (*twidth) *repeat = *repeat / *twidth; /* repeat = # of unit strings in field */ else *repeat = 0; } else if (*hdutype == BINARY_TBL && *tcode == -TSTRING) { /* variable length string */ *incre = 1; *twidth = (long) nelem; } if (*hdutype == ASCII_TBL) *elemnum = 0; /* ASCII tables don't have vector elements */ else *elemnum = firstelem - 1; /* interprete complex and double complex as pairs of floats or doubles */ if (abs(*tcode) >= TCOMPLEX) { if (*tcode > 0) *tcode = (*tcode + 1) / 2; else *tcode = (*tcode - 1) / 2; *repeat = *repeat * 2; *twidth = *twidth / 2; *incre = *incre / 2; } /* calculate no. of pixels that fit in buffer */ /* allow for case where floats are 8 bytes long */ if (abs(*tcode) == TFLOAT) *maxelem = DBUFFSIZE / sizeof(float); else if (abs(*tcode) == TDOUBLE) *maxelem = DBUFFSIZE / sizeof(double); else if (abs(*tcode) == TSTRING) { if (*twidth) *maxelem = (DBUFFSIZE - 1)/ *twidth; /* leave room for final \0 */ else *maxelem = DBUFFSIZE - 1; if (*maxelem == 0) { snprintf(message,FLEN_ERRMSG, "ASCII string column is too wide: %ld; max supported width is %d", *twidth, DBUFFSIZE - 1); ffpmsg(message); return(*status = COL_TOO_WIDE); } } else *maxelem = DBUFFSIZE / *twidth; /* calc starting byte position to 1st element of col */ /* (this does not apply to variable length columns) */ *startpos = datastart + ((LONGLONG)(firstrow - 1) * *rowlen) + tbcol; if (*hdutype == IMAGE_HDU && writemode) /* Primary Array or IMAGE */ { /* For primary arrays, set the repeat count greater than the total number of pixels to be written. This prevents an out-of-range error message in cases where the final image array size is not yet known or defined. */ if (*repeat < *elemnum + nelem) *repeat = *elemnum + nelem; } else if (*tcode > 0) /* Fixed length table column */ { if (*elemnum >= *repeat) { snprintf(message,FLEN_ERRMSG, "First element to write is too large: %ld; max allowed value is %ld", (long) ((*elemnum) + 1), (long) *repeat); ffpmsg(message); return(*status = BAD_ELEM_NUM); } /* last row number to be read or written */ endrow = ((*elemnum + nelem - 1) / *repeat) + firstrow; if (writemode) { /* check if we are writing beyond the current end of table */ if ((endrow > (fptr->Fptr)->numrows) && (nelem > 0) ) { /* if there are more HDUs following the current one, or */ /* if there is a data heap, then we must insert space */ /* for the new rows. */ if ( !((fptr->Fptr)->lasthdu) || (fptr->Fptr)->heapsize > 0) { nrows = endrow - ((fptr->Fptr)->numrows); if (ffirow(fptr, (fptr->Fptr)->numrows, nrows, status) > 0) { snprintf(message,FLEN_ERRMSG, "Failed to add space for %.0f new rows in table.", (double) nrows); ffpmsg(message); return(*status); } } else { /* update heap starting address */ (fptr->Fptr)->heapstart += ((LONGLONG)(endrow - (fptr->Fptr)->numrows) * (fptr->Fptr)->rowlength ); (fptr->Fptr)->numrows = endrow; /* update number of rows */ } } } else /* reading from the file */ { if ( endrow > (fptr->Fptr)->numrows && rangecheck) { if (*hdutype == IMAGE_HDU) /* Primary Array or IMAGE */ { if (firstrow > (fptr->Fptr)->numrows) { snprintf(message, FLEN_ERRMSG, "Attempted to read from group %ld of the HDU,", (long) firstrow); ffpmsg(message); snprintf(message, FLEN_ERRMSG, "however the HDU only contains %ld group(s).", (long) ((fptr->Fptr)->numrows) ); ffpmsg(message); } else { ffpmsg("Attempt to read past end of array:"); snprintf(message, FLEN_ERRMSG, " Image has %ld elements;", (long) *repeat); ffpmsg(message); snprintf(message, FLEN_ERRMSG, " Tried to read %ld elements starting at element %ld.", (long) nelem, (long) firstelem); ffpmsg(message); } } else { ffpmsg("Attempt to read past end of table:"); snprintf(message, FLEN_ERRMSG, " Table has %.0f rows with %.0f elements per row;", (double) ((fptr->Fptr)->numrows), (double) *repeat); ffpmsg(message); snprintf(message, FLEN_ERRMSG, " Tried to read %.0f elements starting at row %.0f, element %.0f.", (double) nelem, (double) firstrow, (double) ((*elemnum) + 1)); ffpmsg(message); } return(*status = BAD_ROW_NUM); } } if (*repeat == 1 && nelem > 1 && writemode != 2) { /* When accessing a scalar column, fool the calling routine into thinking that this is a vector column with very big elements. This allows multiple values (up to the maxelem number of elements that will fit in the buffer) to be read or written with a single routine call, which increases the efficiency. If writemode == 2, then the calling program does not want to have this efficiency trick applied. */ if (*rowlen <= LONG_MAX) { *incre = (long) *rowlen; *repeat = nelem; } } } else /* Variable length Binary Table column */ { *tcode *= (-1); if (writemode) /* return next empty heap address for writing */ { *repeat = nelem + *elemnum; /* total no. of elements in the field */ /* first, check if we are overwriting an existing row, and */ /* if so, if the existing space is big enough for the new vector */ if ( firstrow <= (fptr->Fptr)->numrows ) { ffgdesll(fptr, colnum, firstrow, &lrepeat, &heapoffset, &tstatus); if (!tstatus) { if (colptr->tdatatype <= -TCOMPLEX) lrepeat = lrepeat * 2; /* no. of float or double values */ else if (colptr->tdatatype == -TBIT) lrepeat = (lrepeat + 7) / 8; /* convert from bits to bytes */ if (lrepeat >= *repeat) /* enough existing space? */ { *startpos = datastart + heapoffset + (fptr->Fptr)->heapstart; /* write the descriptor into the fixed length part of table */ if (colptr->tdatatype <= -TCOMPLEX) { /* divide repeat count by 2 to get no. of complex values */ ffpdes(fptr, colnum, firstrow, *repeat / 2, heapoffset, status); } else { ffpdes(fptr, colnum, firstrow, *repeat, heapoffset, status); } return(*status); } } } /* Add more rows to the table, if writing beyond the end. */ /* It is necessary to shift the heap down in this case */ if ( firstrow > (fptr->Fptr)->numrows) { nrows = firstrow - ((fptr->Fptr)->numrows); if (ffirow(fptr, (fptr->Fptr)->numrows, nrows, status) > 0) { snprintf(message,FLEN_ERRMSG, "Failed to add space for %.0f new rows in table.", (double) nrows); ffpmsg(message); return(*status); } } /* calculate starting position (for writing new data) in the heap */ *startpos = datastart + (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; /* write the descriptor into the fixed length part of table */ if (colptr->tdatatype <= -TCOMPLEX) { /* divide repeat count by 2 to get no. of complex values */ ffpdes(fptr, colnum, firstrow, *repeat / 2, (fptr->Fptr)->heapsize, status); } else { ffpdes(fptr, colnum, firstrow, *repeat, (fptr->Fptr)->heapsize, status); } /* If this is not the last HDU in the file, then check if */ /* extending the heap would overwrite the following header. */ /* If so, then have to insert more blocks. */ if ( !((fptr->Fptr)->lasthdu) ) { endpos = datastart + (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize + ( *repeat * (*incre)); if (endpos > (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1]) { /* calc the number of blocks that need to be added */ nblock = (long) (((endpos - 1 - (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] ) / 2880) + 1); if (ffiblk(fptr, nblock, 1, status) > 0) /* insert blocks */ { snprintf(message,FLEN_ERRMSG, "Failed to extend the size of the variable length heap by %ld blocks.", nblock); ffpmsg(message); return(*status); } } } /* increment the address to the next empty heap position */ (fptr->Fptr)->heapsize += ( *repeat * (*incre)); } else /* get the read start position in the heap */ { if ( firstrow > (fptr->Fptr)->numrows) { ffpmsg("Attempt to read past end of table"); snprintf(message,FLEN_ERRMSG, " Table has %.0f rows and tried to read row %.0f.", (double) ((fptr->Fptr)->numrows), (double) firstrow); ffpmsg(message); return(*status = BAD_ROW_NUM); } ffgdesll(fptr, colnum, firstrow, &lrepeat, &heapoffset, status); *repeat = lrepeat; if (colptr->tdatatype <= -TCOMPLEX) *repeat = *repeat * 2; /* no. of float or double values */ else if (colptr->tdatatype == -TBIT) *repeat = (*repeat + 7) / 8; /* convert from bits to bytes */ if (*elemnum >= *repeat) { snprintf(message,FLEN_ERRMSG, "Starting element to read in variable length column is too large: %ld", (long) firstelem); ffpmsg(message); snprintf(message,FLEN_ERRMSG, " This row only contains %ld elements", (long) *repeat); ffpmsg(message); return(*status = BAD_ELEM_NUM); } *startpos = datastart + heapoffset + (fptr->Fptr)->heapstart; } } return(*status); } /*---------------------------------------------------------------------------*/ int fftheap(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG *heapsz, /* O - current size of the heap */ LONGLONG *unused, /* O - no. of unused bytes in the heap */ LONGLONG *overlap, /* O - no. of bytes shared by > 1 descriptors */ int *valid, /* O - are all the heap addresses valid? */ int *status) /* IO - error status */ /* Tests the contents of the binary table variable length array heap. Returns the number of bytes that are currently not pointed to by any of the descriptors, and also the number of bytes that are pointed to by more than one descriptor. It returns valid = FALSE if any of the descriptors point to addresses that are out of the bounds of the heap. */ { int jj, typecode, pixsize; long ii, kk, theapsz, nbytes; LONGLONG repeat, offset, tunused = 0, toverlap = 0; char *buffer, message[FLEN_ERRMSG]; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if ( fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header to make sure everything is up to date */ else if ( ffrdef(fptr, status) > 0) return(*status); if (valid) *valid = TRUE; if (heapsz) *heapsz = (fptr->Fptr)->heapsize; if (unused) *unused = 0; if (overlap) *overlap = 0; /* return if this is not a binary table HDU or if the heap is empty */ if ( (fptr->Fptr)->hdutype != BINARY_TBL || (fptr->Fptr)->heapsize == 0 ) return(*status); if ((fptr->Fptr)->heapsize > LONG_MAX) { ffpmsg("Heap is too big to test ( > 2**31 bytes). (fftheap)"); return(*status = MEMORY_ALLOCATION); } theapsz = (long) (fptr->Fptr)->heapsize; buffer = calloc(1, theapsz); /* allocate temp space */ if (!buffer ) { snprintf(message,FLEN_ERRMSG,"Failed to allocate buffer to test the heap"); ffpmsg(message); return(*status = MEMORY_ALLOCATION); } /* loop over all cols */ for (jj = 1; jj <= (fptr->Fptr)->tfield && *status <= 0; jj++) { ffgtcl(fptr, jj, &typecode, NULL, NULL, status); if (typecode > 0) continue; /* ignore fixed length columns */ pixsize = -typecode / 10; for (ii = 1; ii <= (fptr->Fptr)->numrows; ii++) { ffgdesll(fptr, jj, ii, &repeat, &offset, status); if (typecode == -TBIT) nbytes = (long) (repeat + 7) / 8; else nbytes = (long) repeat * pixsize; if (offset < 0 || offset + nbytes > theapsz) { if (valid) *valid = FALSE; /* address out of bounds */ snprintf(message,FLEN_ERRMSG, "Descriptor in row %ld, column %d has invalid heap address", ii, jj); ffpmsg(message); } else { for (kk = 0; kk < nbytes; kk++) buffer[kk + offset]++; /* increment every used byte */ } } } for (kk = 0; kk < theapsz; kk++) { if (buffer[kk] == 0) tunused++; else if (buffer[kk] > 1) toverlap++; } if (heapsz) *heapsz = theapsz; if (unused) *unused = tunused; if (overlap) *overlap = toverlap; free(buffer); return(*status); } /*--------------------------------------------------------------------------*/ int ffcmph(fitsfile *fptr, /* I -FITS file pointer */ int *status) /* IO - error status */ /* compress the binary table heap by reordering the contents heap and recovering any unused space */ { fitsfile *tptr; int jj, typecode, pixsize, valid; long ii, buffsize = 10000, nblock, nbytes; LONGLONG unused, overlap; LONGLONG repeat, offset; char *buffer, *tbuff, comm[FLEN_COMMENT]; char message[FLEN_ERRMSG]; LONGLONG pcount; LONGLONG readheapstart, writeheapstart, endpos, t1heapsize, t2heapsize; if (*status > 0) return(*status); /* get information about the current heap */ fftheap(fptr, NULL, &unused, &overlap, &valid, status); if (!valid) return(*status = BAD_HEAP_PTR); /* bad heap pointers */ /* return if this is not a binary table HDU or if the heap is OK as is */ if ( (fptr->Fptr)->hdutype != BINARY_TBL || (fptr->Fptr)->heapsize == 0 || (unused == 0 && overlap == 0) || *status > 0 ) return(*status); /* copy the current HDU to a temporary file in memory */ if (ffinit( &tptr, "mem://tempheapfile", status) ) { snprintf(message,FLEN_ERRMSG,"Failed to create temporary file for the heap"); ffpmsg(message); return(*status); } if ( ffcopy(fptr, tptr, 0, status) ) { snprintf(message,FLEN_ERRMSG,"Failed to create copy of the heap"); ffpmsg(message); ffclos(tptr, status); return(*status); } buffer = (char *) malloc(buffsize); /* allocate initial buffer */ if (!buffer) { snprintf(message,FLEN_ERRMSG,"Failed to allocate buffer to copy the heap"); ffpmsg(message); ffclos(tptr, status); return(*status = MEMORY_ALLOCATION); } readheapstart = (tptr->Fptr)->datastart + (tptr->Fptr)->heapstart; writeheapstart = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart; t1heapsize = (fptr->Fptr)->heapsize; /* save original heap size */ (fptr->Fptr)->heapsize = 0; /* reset heap to zero */ /* loop over all cols */ for (jj = 1; jj <= (fptr->Fptr)->tfield && *status <= 0; jj++) { ffgtcl(tptr, jj, &typecode, NULL, NULL, status); if (typecode > 0) continue; /* ignore fixed length columns */ pixsize = -typecode / 10; /* copy heap data, row by row */ for (ii = 1; ii <= (fptr->Fptr)->numrows; ii++) { ffgdesll(tptr, jj, ii, &repeat, &offset, status); if (typecode == -TBIT) nbytes = (long) (repeat + 7) / 8; else nbytes = (long) repeat * pixsize; /* increase size of buffer if necessary to read whole array */ if (nbytes > buffsize) { tbuff = realloc(buffer, nbytes); if (tbuff) { buffer = tbuff; buffsize = nbytes; } else *status = MEMORY_ALLOCATION; } /* If this is not the last HDU in the file, then check if */ /* extending the heap would overwrite the following header. */ /* If so, then have to insert more blocks. */ if ( !((fptr->Fptr)->lasthdu) ) { endpos = writeheapstart + (fptr->Fptr)->heapsize + nbytes; if (endpos > (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1]) { /* calc the number of blocks that need to be added */ nblock = (long) (((endpos - 1 - (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] ) / 2880) + 1); if (ffiblk(fptr, nblock, 1, status) > 0) /* insert blocks */ { snprintf(message,FLEN_ERRMSG, "Failed to extend the size of the variable length heap by %ld blocks.", nblock); ffpmsg(message); } } } /* read arrray of bytes from temporary copy */ ffmbyt(tptr, readheapstart + offset, REPORT_EOF, status); ffgbyt(tptr, nbytes, buffer, status); /* write arrray of bytes back to original file */ ffmbyt(fptr, writeheapstart + (fptr->Fptr)->heapsize, IGNORE_EOF, status); ffpbyt(fptr, nbytes, buffer, status); /* write descriptor */ ffpdes(fptr, jj, ii, repeat, (fptr->Fptr)->heapsize, status); (fptr->Fptr)->heapsize += nbytes; /* update heapsize */ if (*status > 0) { free(buffer); ffclos(tptr, status); return(*status); } } } free(buffer); ffclos(tptr, status); /* delete any empty blocks at the end of the HDU */ nblock = (long) (( (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] - (writeheapstart + (fptr->Fptr)->heapsize) ) / 2880); if (nblock > 0) { t2heapsize = (fptr->Fptr)->heapsize; /* save new heap size */ (fptr->Fptr)->heapsize = t1heapsize; /* restore original heap size */ ffdblk(fptr, nblock, status); (fptr->Fptr)->heapsize = t2heapsize; /* reset correct heap size */ } /* update the PCOUNT value (size of heap) */ ffmaky(fptr, 2, status); /* reset to beginning of header */ ffgkyjj(fptr, "PCOUNT", &pcount, comm, status); if ((fptr->Fptr)->heapsize != pcount) { ffmkyj(fptr, "PCOUNT", (fptr->Fptr)->heapsize, comm, status); } ffrdef(fptr, status); /* rescan new HDU structure */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgdes(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number (1 = 1st column of table) */ LONGLONG rownum, /* I - row number (1 = 1st row of table) */ long *length, /* O - number of elements in the row */ long *heapaddr, /* O - heap pointer to the data */ int *status) /* IO - error status */ /* get (read) the variable length vector descriptor from the table. */ { LONGLONG lengthjj, heapaddrjj; if (ffgdesll(fptr, colnum, rownum, &lengthjj, &heapaddrjj, status) > 0) return(*status); /* convert the temporary 8-byte values to 4-byte values */ /* check for overflow */ if (length) { if (lengthjj > LONG_MAX) *status = NUM_OVERFLOW; else *length = (long) lengthjj; } if (heapaddr) { if (heapaddrjj > LONG_MAX) *status = NUM_OVERFLOW; else *heapaddr = (long) heapaddrjj; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgdesll(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number (1 = 1st column of table) */ LONGLONG rownum, /* I - row number (1 = 1st row of table) */ LONGLONG *length, /* O - number of elements in the row */ LONGLONG *heapaddr, /* O - heap pointer to the data */ int *status) /* IO - error status */ /* get (read) the variable length vector descriptor from the binary table. This is similar to ffgdes, except it supports the full 8-byte range of the length and offset values in 'Q' columns, as well as 'P' columns. */ { LONGLONG bytepos; unsigned int descript4[2] = {0,0}; LONGLONG descript8[2] = {0,0}; tcolumn *colptr; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); colptr = (fptr->Fptr)->tableptr; /* point to first column structure */ colptr += (colnum - 1); /* offset to the correct column */ if (colptr->tdatatype >= 0) { *status = NOT_VARI_LEN; return(*status); } bytepos = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * (rownum - 1)) + colptr->tbcol; if (colptr->tform[0] == 'P' || colptr->tform[1] == 'P') { /* read 4-byte descriptor */ if (ffgi4b(fptr, bytepos, 2, 4, (INT32BIT *) descript4, status) <= 0) { if (length) *length = (LONGLONG) descript4[0]; /* 1st word is the length */ if (heapaddr) *heapaddr = (LONGLONG) descript4[1]; /* 2nd word is the address */ } } else /* this is for 'Q' columns */ { /* read 8 byte descriptor */ if (ffgi8b(fptr, bytepos, 2, 8, (long *) descript8, status) <= 0) { if (length) *length = descript8[0]; /* 1st word is the length */ if (heapaddr) *heapaddr = descript8[1]; /* 2nd word is the address */ } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgdess(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number (1 = 1st column of table) */ LONGLONG firstrow, /* I - first row (1 = 1st row of table) */ LONGLONG nrows, /* I - number or rows to read */ long *length, /* O - number of elements in the row */ long *heapaddr, /* O - heap pointer to the data */ int *status) /* IO - error status */ /* get (read) a range of variable length vector descriptors from the table. */ { LONGLONG rowsize, bytepos; long ii; INT32BIT descript4[2] = {0,0}; LONGLONG descript8[2] = {0,0}; tcolumn *colptr; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); colptr = (fptr->Fptr)->tableptr; /* point to first column structure */ colptr += (colnum - 1); /* offset to the correct column */ if (colptr->tdatatype >= 0) { *status = NOT_VARI_LEN; return(*status); } rowsize = (fptr->Fptr)->rowlength; bytepos = (fptr->Fptr)->datastart + (rowsize * (firstrow - 1)) + colptr->tbcol; if (colptr->tform[0] == 'P' || colptr->tform[1] == 'P') { /* read 4-byte descriptors */ for (ii = 0; ii < nrows; ii++) { /* read descriptors */ if (ffgi4b(fptr, bytepos, 2, 4, descript4, status) <= 0) { if (length) { *length = (long) descript4[0]; /* 1st word is the length */ length++; } if (heapaddr) { *heapaddr = (long) descript4[1]; /* 2nd word is the address */ heapaddr++; } bytepos += rowsize; } else return(*status); } } else /* this is for 'Q' columns */ { /* read 8-byte descriptors */ for (ii = 0; ii < nrows; ii++) { /* read descriptors */ if (ffgi8b(fptr, bytepos, 2, 8, (long *) descript8, status) <= 0) { if (length) { if (descript8[0] > LONG_MAX)*status = NUM_OVERFLOW; *length = (long) descript8[0]; /* 1st word is the length */ length++; } if (heapaddr) { if (descript8[1] > LONG_MAX)*status = NUM_OVERFLOW; *heapaddr = (long) descript8[1]; /* 2nd word is the address */ heapaddr++; } bytepos += rowsize; } else return(*status); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgdessll(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number (1 = 1st column of table) */ LONGLONG firstrow, /* I - first row (1 = 1st row of table) */ LONGLONG nrows, /* I - number or rows to read */ LONGLONG *length, /* O - number of elements in the row */ LONGLONG *heapaddr, /* O - heap pointer to the data */ int *status) /* IO - error status */ /* get (read) a range of variable length vector descriptors from the table. */ { LONGLONG rowsize, bytepos; long ii; unsigned int descript4[2] = {0,0}; LONGLONG descript8[2] = {0,0}; tcolumn *colptr; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); colptr = (fptr->Fptr)->tableptr; /* point to first column structure */ colptr += (colnum - 1); /* offset to the correct column */ if (colptr->tdatatype >= 0) { *status = NOT_VARI_LEN; return(*status); } rowsize = (fptr->Fptr)->rowlength; bytepos = (fptr->Fptr)->datastart + (rowsize * (firstrow - 1)) + colptr->tbcol; if (colptr->tform[0] == 'P' || colptr->tform[1] == 'P') { /* read 4-byte descriptors */ for (ii = 0; ii < nrows; ii++) { /* read descriptors */ if (ffgi4b(fptr, bytepos, 2, 4, (INT32BIT *) descript4, status) <= 0) { if (length) { *length = (LONGLONG) descript4[0]; /* 1st word is the length */ length++; } if (heapaddr) { *heapaddr = (LONGLONG) descript4[1]; /* 2nd word is the address */ heapaddr++; } bytepos += rowsize; } else return(*status); } } else /* this is for 'Q' columns */ { /* read 8-byte descriptors */ for (ii = 0; ii < nrows; ii++) { /* read descriptors */ /* cast to type (long *) even though it is actually (LONGLONG *) */ if (ffgi8b(fptr, bytepos, 2, 8, (long *) descript8, status) <= 0) { if (length) { *length = descript8[0]; /* 1st word is the length */ length++; } if (heapaddr) { *heapaddr = descript8[1]; /* 2nd word is the address */ heapaddr++; } bytepos += rowsize; } else return(*status); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffpdes(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number (1 = 1st column of table) */ LONGLONG rownum, /* I - row number (1 = 1st row of table) */ LONGLONG length, /* I - number of elements in the row */ LONGLONG heapaddr, /* I - heap pointer to the data */ int *status) /* IO - error status */ /* put (write) the variable length vector descriptor to the table. */ { LONGLONG bytepos; unsigned int descript4[2]; LONGLONG descript8[2]; tcolumn *colptr; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); colptr = (fptr->Fptr)->tableptr; /* point to first column structure */ colptr += (colnum - 1); /* offset to the correct column */ if (colptr->tdatatype >= 0) *status = NOT_VARI_LEN; bytepos = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * (rownum - 1)) + colptr->tbcol; ffmbyt(fptr, bytepos, IGNORE_EOF, status); /* move to element */ if (colptr->tform[0] == 'P' || colptr->tform[1] == 'P') { if (length > UINT_MAX || length < 0 || heapaddr > UINT_MAX || heapaddr < 0) { ffpmsg("P variable length column descriptor is out of range"); *status = NUM_OVERFLOW; return(*status); } descript4[0] = (unsigned int) length; /* 1st word is the length */ descript4[1] = (unsigned int) heapaddr; /* 2nd word is the address */ ffpi4b(fptr, 2, 4, (INT32BIT *) descript4, status); /* write the descriptor */ } else /* this is a 'Q' descriptor column */ { descript8[0] = length; /* 1st word is the length */ descript8[1] = heapaddr; /* 2nd word is the address */ ffpi8b(fptr, 2, 8, (long *) descript8, status); /* write the descriptor */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffchdu(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ { /* close the current HDU. If we have write access to the file, then: - write the END keyword and pad header with blanks if necessary - check the data fill values, and rewrite them if not correct */ char message[FLEN_ERRMSG]; int ii, stdriver, ntilebins; /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* no need to do any further updating of the HDU */ } else if ((fptr->Fptr)->writemode == 1) { urltype2driver("stream://", &stdriver); /* don't rescan header in special case of writing to stdout */ if (((fptr->Fptr)->driver != stdriver)) ffrdef(fptr, status); if ((fptr->Fptr)->heapsize > 0) { ffuptf(fptr, status); /* update the variable length TFORM values */ } ffpdfl(fptr, status); /* insure correct data fill values */ } if ((fptr->Fptr)->open_count == 1) { /* free memory for the CHDU structure only if no other files are using it */ if ((fptr->Fptr)->tableptr) { free((fptr->Fptr)->tableptr); (fptr->Fptr)->tableptr = NULL; /* free the tile-compressed image cache, if it exists */ if ((fptr->Fptr)->tilerow) { ntilebins = (((fptr->Fptr)->znaxis[0] - 1) / ((fptr->Fptr)->tilesize[0])) + 1; for (ii = 0; ii < ntilebins; ii++) { if ((fptr->Fptr)->tiledata[ii]) { free((fptr->Fptr)->tiledata[ii]); } if ((fptr->Fptr)->tilenullarray[ii]) { free((fptr->Fptr)->tilenullarray[ii]); } } free((fptr->Fptr)->tileanynull); free((fptr->Fptr)->tiletype); free((fptr->Fptr)->tiledatasize); free((fptr->Fptr)->tilenullarray); free((fptr->Fptr)->tiledata); free((fptr->Fptr)->tilerow); (fptr->Fptr)->tileanynull = 0; (fptr->Fptr)->tiletype = 0; (fptr->Fptr)->tiledatasize = 0; (fptr->Fptr)->tilenullarray = 0; (fptr->Fptr)->tiledata = 0; (fptr->Fptr)->tilerow = 0; } } } if (*status > 0 && *status != NO_CLOSE_ERROR) { snprintf(message,FLEN_ERRMSG, "Error while closing HDU number %d (ffchdu).", (fptr->Fptr)->curhdu); ffpmsg(message); } return(*status); } /*--------------------------------------------------------------------------*/ int ffuptf(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* Update the value of the TFORM keywords for the variable length array columns to make sure they all have the form 1Px(len) or Px(len) where 'len' is the maximum length of the vector in the table (e.g., '1PE(400)') */ { int ii, lenform=0; long tflds; LONGLONG length, addr, maxlen, naxis2, jj; char comment[FLEN_COMMENT], keyname[FLEN_KEYWORD]; char tform[FLEN_VALUE], newform[FLEN_VALUE], lenval[40]; char card[FLEN_CARD]; char message[FLEN_ERRMSG]; char *tmp; ffmaky(fptr, 2, status); /* reset to beginning of header */ ffgkyjj(fptr, "NAXIS2", &naxis2, comment, status); ffgkyj(fptr, "TFIELDS", &tflds, comment, status); for (ii = 1; ii <= tflds; ii++) /* loop over all the columns */ { ffkeyn("TFORM", ii, keyname, status); /* construct name */ if (ffgkys(fptr, keyname, tform, comment, status) > 0) { snprintf(message,FLEN_ERRMSG, "Error while updating variable length vector TFORMn values (ffuptf)."); ffpmsg(message); return(*status); } /* is this a variable array length column ? */ if (tform[0] == 'P' || tform[1] == 'P' || tform[0] == 'Q' || tform[1] == 'Q') { /* get the max length */ maxlen = 0; for (jj=1; jj <= naxis2; jj++) { ffgdesll(fptr, ii, jj, &length, &addr, status); if (length > maxlen) maxlen = length; } /* construct the new keyword value */ strcpy(newform, "'"); tmp = strchr(tform, '('); /* truncate old length, if present */ if (tmp) *tmp = 0; lenform = strlen(tform); /* print as double, because the string-to-64-bit */ /* conversion is platform dependent (%lld, %ld, %I64d) */ snprintf(lenval,40, "(%.0f)", (double) maxlen); if (lenform+strlen(lenval)+2 > FLEN_VALUE-1) { ffpmsg("Error assembling TFORMn string (ffuptf)."); return(*status = BAD_TFORM); } strcat(newform, tform); strcat(newform,lenval); while(strlen(newform) < 9) strcat(newform," "); /* append spaces 'till length = 8 */ strcat(newform,"'" ); /* append closing parenthesis */ /* would be simpler to just call ffmkyj here, but this */ /* would force linking in all the modkey & putkey routines */ ffmkky(keyname, newform, comment, card, status); /* make new card */ ffmkey(fptr, card, status); /* replace last read keyword */ } } return(*status); } /*--------------------------------------------------------------------------*/ int ffrdef(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* ReDEFine the structure of a data unit. This routine re-reads the CHDU header keywords to determine the structure and length of the current data unit. This redefines the start of the next HDU. */ { int dummy, tstatus = 0; LONGLONG naxis2; LONGLONG pcount; char card[FLEN_CARD], comm[FLEN_COMMENT], valstring[FLEN_VALUE]; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->writemode == 1) /* write access to the file? */ { /* don't need to check NAXIS2 and PCOUNT if data hasn't been written */ if ((fptr->Fptr)->datastart != DATA_UNDEFINED) { /* update NAXIS2 keyword if more rows were written to the table */ /* and if the user has not explicitly reset the NAXIS2 value */ if ((fptr->Fptr)->hdutype != IMAGE_HDU) { ffmaky(fptr, 2, status); if (ffgkyjj(fptr, "NAXIS2", &naxis2, comm, &tstatus) > 0) { /* Couldn't read NAXIS2 (odd!); in certain circumstances */ /* this may be normal, so ignore the error. */ naxis2 = (fptr->Fptr)->numrows; } if ((fptr->Fptr)->numrows > naxis2 && (fptr->Fptr)->origrows == naxis2) /* if origrows is not equal to naxis2, then the user must */ /* have manually modified the NAXIS2 keyword value, and */ /* we will assume that the current value is correct. */ { /* would be simpler to just call ffmkyj here, but this */ /* would force linking in all the modkey & putkey routines */ /* print as double because the 64-bit int conversion */ /* is platform dependent (%lld, %ld, %I64 ) */ snprintf(valstring,FLEN_VALUE, "%.0f", (double) ((fptr->Fptr)->numrows)); ffmkky("NAXIS2", valstring, comm, card, status); ffmkey(fptr, card, status); } } /* if data has been written to variable length columns in a */ /* binary table, then we may need to update the PCOUNT value */ if ((fptr->Fptr)->heapsize > 0) { ffmaky(fptr, 2, status); ffgkyjj(fptr, "PCOUNT", &pcount, comm, status); if ((fptr->Fptr)->heapsize != pcount) { ffmkyj(fptr, "PCOUNT", (fptr->Fptr)->heapsize, comm, status); } } } if (ffwend(fptr, status) <= 0) /* rewrite END keyword and fill */ { ffrhdu(fptr, &dummy, status); /* re-scan the header keywords */ } } return(*status); } /*--------------------------------------------------------------------------*/ int ffhdef(fitsfile *fptr, /* I - FITS file pointer */ int morekeys, /* I - reserve space for this many keywords */ int *status) /* IO - error status */ /* based on the number of keywords which have already been written, plus the number of keywords to reserve space for, we then can define where the data unit should start (it must start at the beginning of a 2880-byte logical block). This routine will only have any effect if the starting location of the data unit following the header is not already defined. In any case, it is always possible to add more keywords to the header even if the data has already been written. It is just more efficient to reserve the space in advance. */ { LONGLONG delta; if (*status > 0 || morekeys < 1) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { ffrdef(fptr, status); /* ffrdef defines the offset to datastart and the start of */ /* the next HDU based on the number of existing keywords. */ /* We need to increment both of these values based on */ /* the number of new keywords to be added. */ delta = (((fptr->Fptr)->headend + (morekeys * 80)) / 2880 + 1) * 2880 - (fptr->Fptr)->datastart; (fptr->Fptr)->datastart += delta; (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] += delta; } return(*status); } /*--------------------------------------------------------------------------*/ int ffwend(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* write the END card and following fill (space chars) in the current header */ { int ii, tstatus; LONGLONG endpos; long nspace; char blankkey[FLEN_CARD], endkey[FLEN_CARD], keyrec[FLEN_CARD] = ""; if (*status > 0) return(*status); endpos = (fptr->Fptr)->headend; /* we assume that the HDUposition == curhdu in all cases */ /* calc the data starting position if not currently defined */ if ((fptr->Fptr)->datastart == DATA_UNDEFINED) (fptr->Fptr)->datastart = ( endpos / 2880 + 1 ) * 2880; /* calculate the number of blank keyword slots in the header */ nspace = (long) (( (fptr->Fptr)->datastart - endpos ) / 80); /* construct a blank and END keyword (80 spaces ) */ strcpy(blankkey, " "); strcat(blankkey, " "); strcpy(endkey, "END "); strcat(endkey, " "); /* check if header is already correctly terminated with END and fill */ tstatus=0; ffmbyt(fptr, endpos, REPORT_EOF, &tstatus); /* move to header end */ for (ii=0; ii < nspace; ii++) { ffgbyt(fptr, 80, keyrec, &tstatus); /* get next keyword */ if (tstatus) break; if (strncmp(keyrec, blankkey, 80) && strncmp(keyrec, endkey, 80)) break; } if (ii == nspace && !tstatus) { /* check if the END keyword exists at the correct position */ endpos=maxvalue( endpos, ( (fptr->Fptr)->datastart - 2880 ) ); ffmbyt(fptr, endpos, REPORT_EOF, &tstatus); /* move to END position */ ffgbyt(fptr, 80, keyrec, &tstatus); /* read the END keyword */ if ( !strncmp(keyrec, endkey, 80) && !tstatus) { /* store this position, for later reference */ (fptr->Fptr)->ENDpos = endpos; return(*status); /* END card was already correct */ } } /* header was not correctly terminated, so write the END and blank fill */ endpos = (fptr->Fptr)->headend; ffmbyt(fptr, endpos, IGNORE_EOF, status); /* move to header end */ for (ii=0; ii < nspace; ii++) ffpbyt(fptr, 80, blankkey, status); /* write the blank keywords */ /* The END keyword must either be placed immediately after the last keyword that was written (as indicated by the headend value), or must be in the first 80 bytes of the 2880-byte FITS record immediately preceeding the data unit, whichever is further in the file. The latter will occur if space has been reserved for more header keywords which have not yet been written. */ endpos=maxvalue( endpos, ( (fptr->Fptr)->datastart - 2880 ) ); ffmbyt(fptr, endpos, REPORT_EOF, status); /* move to END position */ ffpbyt(fptr, 80, endkey, status); /* write the END keyword to header */ /* store this position, for later reference */ (fptr->Fptr)->ENDpos = endpos; if (*status > 0) ffpmsg("Error while writing END card (ffwend)."); return(*status); } /*--------------------------------------------------------------------------*/ int ffpdfl(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* Write the Data Unit Fill values if they are not already correct. The fill values are used to fill out the last 2880 byte block of the HDU. Fill the data unit with zeros or blanks depending on the type of HDU from the end of the data to the end of the current FITS 2880 byte block */ { char chfill, fill[2880]; LONGLONG fillstart; int nfill, tstatus, ii; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) return(*status); /* fill has already been correctly written */ if ((fptr->Fptr)->heapstart == 0) return(*status); /* null data unit, so there is no fill */ fillstart = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; nfill = (long) ((fillstart + 2879) / 2880 * 2880 - fillstart); if ((fptr->Fptr)->hdutype == ASCII_TBL) chfill = 32; /* ASCII tables are filled with spaces */ else chfill = 0; /* all other extensions are filled with zeros */ tstatus = 0; if (!nfill) /* no fill bytes; just check that entire table exists */ { fillstart--; nfill = 1; ffmbyt(fptr, fillstart, REPORT_EOF, &tstatus); /* move to last byte */ ffgbyt(fptr, nfill, fill, &tstatus); /* get the last byte */ if (tstatus == 0) return(*status); /* no EOF error, so everything is OK */ } else { ffmbyt(fptr, fillstart, REPORT_EOF, &tstatus); /* move to fill area */ ffgbyt(fptr, nfill, fill, &tstatus); /* get the fill bytes */ if (tstatus == 0) { for (ii = 0; ii < nfill; ii++) { if (fill[ii] != chfill) break; } if (ii == nfill) return(*status); /* all the fill values were correct */ } } /* fill values are incorrect or have not been written, so write them */ memset(fill, chfill, nfill); /* fill the buffer with the fill value */ ffmbyt(fptr, fillstart, IGNORE_EOF, status); /* move to fill area */ ffpbyt(fptr, nfill, fill, status); /* write the fill bytes */ if (*status > 0) ffpmsg("Error writing Data Unit fill bytes (ffpdfl)."); return(*status); } /********************************************************************** ffchfl : Check Header Fill values Check that the header unit is correctly filled with blanks from the END card to the end of the current FITS 2880-byte block Function parameters: fptr Fits file pointer status output error status Translated ftchfl into C by Peter Wilson, Oct. 1997 **********************************************************************/ int ffchfl( fitsfile *fptr, int *status) { int nblank,i,gotend; LONGLONG endpos; char rec[FLEN_CARD]; char *blanks=" "; /* 80 spaces */ if( *status > 0 ) return (*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* calculate the number of blank keyword slots in the header */ endpos=(fptr->Fptr)->headend; nblank=(long) (((fptr->Fptr)->datastart-endpos)/80); /* move the i/o pointer to the end of the header keywords */ ffmbyt(fptr,endpos,TRUE,status); /* find the END card (there may be blank keywords perceeding it) */ gotend=FALSE; for(i=0;i 0 ) { rec[FLEN_CARD - 1] = '\0'; /* make sure string is null terminated */ ffpmsg(rec); return( *status ); } } return( *status ); } /********************************************************************** ffcdfl : Check Data Unit Fill values Check that the data unit is correctly filled with zeros or blanks from the end of the data to the end of the current FITS 2880 byte block Function parameters: fptr Fits file pointer status output error status Translated ftcdfl into C by Peter Wilson, Oct. 1997 **********************************************************************/ int ffcdfl( fitsfile *fptr, int *status) { int nfill,i; LONGLONG filpos; char chfill,chbuff[2880]; if( *status > 0 ) return( *status ); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* check if the data unit is null */ if( (fptr->Fptr)->heapstart==0 ) return( *status ); /* calculate starting position of the fill bytes, if any */ filpos = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; /* calculate the number of fill bytes */ nfill = (long) ((filpos + 2879) / 2880 * 2880 - filpos); if( nfill == 0 ) return( *status ); /* move to the beginning of the fill bytes */ ffmbyt(fptr, filpos, FALSE, status); if( ffgbyt(fptr, nfill, chbuff, status) > 0) { ffpmsg("Error reading data unit fill bytes (ffcdfl)."); return( *status ); } if( (fptr->Fptr)->hdutype==ASCII_TBL ) chfill = 32; /* ASCII tables are filled with spaces */ else chfill = 0; /* all other extensions are filled with zeros */ /* check for all zeros or blanks */ for(i=0;iFptr)->hdutype==ASCII_TBL ) ffpmsg("Warning: remaining bytes following ASCII table data are not filled with blanks."); else ffpmsg("Warning: remaining bytes following data are not filled with zeros."); return( *status ); } } return( *status ); } /*--------------------------------------------------------------------------*/ int ffcrhd(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* CReate Header Data unit: Create, initialize, and move the i/o pointer to a new extension appended to the end of the FITS file. */ { int tstatus = 0; LONGLONG bytepos, *ptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* If the current header is empty, we don't have to do anything */ if ((fptr->Fptr)->headend == (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) return(*status); while (ffmrhd(fptr, 1, 0, &tstatus) == 0); /* move to end of file */ if ((fptr->Fptr)->maxhdu == (fptr->Fptr)->MAXHDU) { /* allocate more space for the headstart array */ ptr = (LONGLONG*) realloc( (fptr->Fptr)->headstart, ((fptr->Fptr)->MAXHDU + 1001) * sizeof(LONGLONG) ); if (ptr == NULL) return (*status = MEMORY_ALLOCATION); else { (fptr->Fptr)->MAXHDU = (fptr->Fptr)->MAXHDU + 1000; (fptr->Fptr)->headstart = ptr; } } if (ffchdu(fptr, status) <= 0) /* close the current HDU */ { bytepos = (fptr->Fptr)->headstart[(fptr->Fptr)->maxhdu + 1]; /* last */ ffmbyt(fptr, bytepos, IGNORE_EOF, status); /* move file ptr to it */ (fptr->Fptr)->maxhdu++; /* increment the known number of HDUs */ (fptr->Fptr)->curhdu = (fptr->Fptr)->maxhdu; /* set current HDU loc */ fptr->HDUposition = (fptr->Fptr)->maxhdu; /* set current HDU loc */ (fptr->Fptr)->nextkey = bytepos; /* next keyword = start of header */ (fptr->Fptr)->headend = bytepos; /* end of header */ (fptr->Fptr)->datastart = DATA_UNDEFINED; /* start data unit undefined */ /* any other needed resets */ /* reset the dithering offset that may have been calculated for the */ /* previous HDU back to the requested default value */ (fptr->Fptr)->dither_seed = (fptr->Fptr)->request_dither_seed; } return(*status); } /*--------------------------------------------------------------------------*/ int ffdblk(fitsfile *fptr, /* I - FITS file pointer */ long nblocks, /* I - number of 2880-byte blocks to delete */ int *status) /* IO - error status */ /* Delete the specified number of 2880-byte blocks from the end of the CHDU by shifting all following extensions up this number of blocks. */ { char buffer[2880]; int tstatus, ii; LONGLONG readpos, writepos; if (*status > 0 || nblocks <= 0) return(*status); tstatus = 0; /* pointers to the read and write positions */ readpos = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; readpos = ((readpos + 2879) / 2880) * 2880; /* start of block */ /* the following formula is wrong because the current data unit may have been extended without updating the headstart value of the following HDU. readpos = (fptr->Fptr)->headstart[((fptr->Fptr)->curhdu) + 1]; */ writepos = readpos - ((LONGLONG)nblocks * 2880); while ( !ffmbyt(fptr, readpos, REPORT_EOF, &tstatus) && !ffgbyt(fptr, 2880L, buffer, &tstatus) ) { ffmbyt(fptr, writepos, REPORT_EOF, status); ffpbyt(fptr, 2880L, buffer, status); if (*status > 0) { ffpmsg("Error deleting FITS blocks (ffdblk)"); return(*status); } readpos += 2880; /* increment to next block to transfer */ writepos += 2880; } /* now fill the last nblock blocks with zeros */ memset(buffer, 0, 2880); ffmbyt(fptr, writepos, REPORT_EOF, status); for (ii = 0; ii < nblocks; ii++) ffpbyt(fptr, 2880L, buffer, status); /* move back before the deleted blocks, since they may be deleted */ /* and we do not want to delete the current active buffer */ ffmbyt(fptr, writepos - 1, REPORT_EOF, status); /* truncate the file to the new size, if supported on this device */ fftrun(fptr, writepos, status); /* recalculate the starting location of all subsequent HDUs */ for (ii = (fptr->Fptr)->curhdu; ii <= (fptr->Fptr)->maxhdu; ii++) (fptr->Fptr)->headstart[ii + 1] -= ((LONGLONG)nblocks * 2880); return(*status); } /*--------------------------------------------------------------------------*/ int ffghdt(fitsfile *fptr, /* I - FITS file pointer */ int *exttype, /* O - type of extension, 0, 1, or 2 */ /* for IMAGE_HDU, ASCII_TBL, or BINARY_TBL */ int *status) /* IO - error status */ /* Return the type of the CHDU. This returns the 'logical' type of the HDU, not necessarily the physical type, so in the case of a compressed image stored in a binary table, this will return the type as an Image, not a binary table. */ { if (*status > 0) return(*status); if (fptr->HDUposition == 0 && (fptr->Fptr)->headend == 0) { /* empty primary array is alway an IMAGE_HDU */ *exttype = IMAGE_HDU; } else { /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { /* rescan header if data structure is undefined */ if ( ffrdef(fptr, status) > 0) return(*status); } *exttype = (fptr->Fptr)->hdutype; /* return the type of HDU */ /* check if this is a compressed image */ if ((fptr->Fptr)->compressimg) *exttype = IMAGE_HDU; } return(*status); } /*--------------------------------------------------------------------------*/ int fits_is_reentrant(void) /* Was CFITSIO compiled with the -D_REENTRANT flag? 1 = yes, 0 = no. Note that specifying the -D_REENTRANT flag is required, but may not be sufficient, to ensure that CFITSIO can be safely used in a multi-threaded environoment. */ { #ifdef _REENTRANT return(1); #else return(0); #endif } /*--------------------------------------------------------------------------*/ int fits_is_compressed_image(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* Returns TRUE if the CHDU is a compressed image, else returns zero. */ { if (*status > 0) return(0); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { /* rescan header if data structure is undefined */ if ( ffrdef(fptr, status) > 0) return(*status); } /* check if this is a compressed image */ if ((fptr->Fptr)->compressimg) return(1); return(0); } /*--------------------------------------------------------------------------*/ int ffgipr(fitsfile *infptr, /* I - FITS file pointer */ int maxaxis, /* I - max number of axes to return */ int *bitpix, /* O - image data type */ int *naxis, /* O - image dimension (NAXIS value) */ long *naxes, /* O - size of image dimensions */ int *status) /* IO - error status */ /* get the datatype and size of the input image */ { if (*status > 0) return(*status); /* don't return the parameter if a null pointer was given */ if (bitpix) fits_get_img_type(infptr, bitpix, status); /* get BITPIX value */ if (naxis) fits_get_img_dim(infptr, naxis, status); /* get NAXIS value */ if (naxes) fits_get_img_size(infptr, maxaxis, naxes, status); /* get NAXISn values */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgiprll(fitsfile *infptr, /* I - FITS file pointer */ int maxaxis, /* I - max number of axes to return */ int *bitpix, /* O - image data type */ int *naxis, /* O - image dimension (NAXIS value) */ LONGLONG *naxes, /* O - size of image dimensions */ int *status) /* IO - error status */ /* get the datatype and size of the input image */ { if (*status > 0) return(*status); /* don't return the parameter if a null pointer was given */ if (bitpix) fits_get_img_type(infptr, bitpix, status); /* get BITPIX value */ if (naxis) fits_get_img_dim(infptr, naxis, status); /* get NAXIS value */ if (naxes) fits_get_img_sizell(infptr, maxaxis, naxes, status); /* get NAXISn values */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgidt( fitsfile *fptr, /* I - FITS file pointer */ int *imgtype, /* O - image data type */ int *status) /* IO - error status */ /* Get the datatype of the image (= BITPIX keyword for normal image, or ZBITPIX for a compressed image) */ { if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); /* reset to beginning of header */ ffmaky(fptr, 1, status); /* simply move to beginning of header */ if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffgky(fptr, TINT, "BITPIX", imgtype, NULL, status); } else if ((fptr->Fptr)->compressimg) { /* this is a binary table containing a compressed image */ ffgky(fptr, TINT, "ZBITPIX", imgtype, NULL, status); } else { *status = NOT_IMAGE; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgiet( fitsfile *fptr, /* I - FITS file pointer */ int *imgtype, /* O - image data type */ int *status) /* IO - error status */ /* Get the effective datatype of the image (= BITPIX keyword for normal image, or ZBITPIX for a compressed image) */ { int tstatus; long lngscale, lngzero = 0; double bscale, bzero, min_val, max_val; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); /* reset to beginning of header */ ffmaky(fptr, 2, status); /* simply move to beginning of header */ if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffgky(fptr, TINT, "BITPIX", imgtype, NULL, status); } else if ((fptr->Fptr)->compressimg) { /* this is a binary table containing a compressed image */ ffgky(fptr, TINT, "ZBITPIX", imgtype, NULL, status); } else { *status = NOT_IMAGE; return(*status); } /* check if the BSCALE and BZERO keywords are defined, which might change the effective datatype of the image */ tstatus = 0; ffgky(fptr, TDOUBLE, "BSCALE", &bscale, NULL, &tstatus); if (tstatus) bscale = 1.0; tstatus = 0; ffgky(fptr, TDOUBLE, "BZERO", &bzero, NULL, &tstatus); if (tstatus) bzero = 0.0; if (bscale == 1.0 && bzero == 0.0) /* no scaling */ return(*status); switch (*imgtype) { case BYTE_IMG: /* 8-bit image */ min_val = 0.; max_val = 255.0; break; case SHORT_IMG: min_val = -32768.0; max_val = 32767.0; break; case LONG_IMG: min_val = -2147483648.0; max_val = 2147483647.0; break; default: /* don't have to deal with other data types */ return(*status); } if (bscale >= 0.) { min_val = bzero + bscale * min_val; max_val = bzero + bscale * max_val; } else { max_val = bzero + bscale * min_val; min_val = bzero + bscale * max_val; } if (bzero < 2147483648.) /* don't exceed range of 32-bit integer */ lngzero = (long) bzero; lngscale = (long) bscale; if ((bzero != 2147483648.) && /* special value that exceeds integer range */ (lngzero != bzero || lngscale != bscale)) { /* not integers? */ /* floating point scaled values; just decide on required precision */ if (*imgtype == BYTE_IMG || *imgtype == SHORT_IMG) *imgtype = FLOAT_IMG; else *imgtype = DOUBLE_IMG; /* In all the remaining cases, BSCALE and BZERO are integers, and not equal to 1 and 0, respectively. */ } else if ((min_val == -128.) && (max_val == 127.)) { *imgtype = SBYTE_IMG; } else if ((min_val >= -32768.0) && (max_val <= 32767.0)) { *imgtype = SHORT_IMG; } else if ((min_val >= 0.0) && (max_val <= 65535.0)) { *imgtype = USHORT_IMG; } else if ((min_val >= -2147483648.0) && (max_val <= 2147483647.0)) { *imgtype = LONG_IMG; } else if ((min_val >= 0.0) && (max_val < 4294967296.0)) { *imgtype = ULONG_IMG; } else { /* exceeds the range of a 32-bit integer */ *imgtype = DOUBLE_IMG; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgidm( fitsfile *fptr, /* I - FITS file pointer */ int *naxis , /* O - image dimension (NAXIS value) */ int *status) /* IO - error status */ /* Get the dimension of the image (= NAXIS keyword for normal image, or ZNAXIS for a compressed image) These values are cached for faster access. */ { if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { *naxis = (fptr->Fptr)->imgdim; } else if ((fptr->Fptr)->compressimg) { *naxis = (fptr->Fptr)->zndim; } else { *status = NOT_IMAGE; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgisz( fitsfile *fptr, /* I - FITS file pointer */ int nlen, /* I - number of axes to return */ long *naxes, /* O - size of image dimensions */ int *status) /* IO - error status */ /* Get the size of the image dimensions (= NAXISn keywords for normal image, or ZNAXISn for a compressed image) These values are cached for faster access. */ { int ii, naxis; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { naxis = minvalue((fptr->Fptr)->imgdim, nlen); for (ii = 0; ii < naxis; ii++) { naxes[ii] = (long) (fptr->Fptr)->imgnaxis[ii]; } } else if ((fptr->Fptr)->compressimg) { naxis = minvalue( (fptr->Fptr)->zndim, nlen); for (ii = 0; ii < naxis; ii++) { naxes[ii] = (long) (fptr->Fptr)->znaxis[ii]; } } else { *status = NOT_IMAGE; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgiszll( fitsfile *fptr, /* I - FITS file pointer */ int nlen, /* I - number of axes to return */ LONGLONG *naxes, /* O - size of image dimensions */ int *status) /* IO - error status */ /* Get the size of the image dimensions (= NAXISn keywords for normal image, or ZNAXISn for a compressed image) */ { int ii, naxis; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { naxis = minvalue((fptr->Fptr)->imgdim, nlen); for (ii = 0; ii < naxis; ii++) { naxes[ii] = (fptr->Fptr)->imgnaxis[ii]; } } else if ((fptr->Fptr)->compressimg) { naxis = minvalue( (fptr->Fptr)->zndim, nlen); for (ii = 0; ii < naxis; ii++) { naxes[ii] = (fptr->Fptr)->znaxis[ii]; } } else { *status = NOT_IMAGE; } return(*status); }/*--------------------------------------------------------------------------*/ int ffmahd(fitsfile *fptr, /* I - FITS file pointer */ int hdunum, /* I - number of the HDU to move to */ int *exttype, /* O - type of extension, 0, 1, or 2 */ int *status) /* IO - error status */ /* Move to Absolute Header Data unit. Move to the specified HDU and read the header to initialize the table structure. Note that extnum is one based, so the primary array is extnum = 1. */ { int moveto, tstatus; char message[FLEN_ERRMSG]; LONGLONG *ptr; if (*status > 0) return(*status); else if (hdunum < 1 ) return(*status = BAD_HDU_NUM); else if (hdunum >= (fptr->Fptr)->MAXHDU ) { /* allocate more space for the headstart array */ ptr = (LONGLONG*) realloc( (fptr->Fptr)->headstart, (hdunum + 1001) * sizeof(LONGLONG) ); if (ptr == NULL) return (*status = MEMORY_ALLOCATION); else { (fptr->Fptr)->MAXHDU = hdunum + 1000; (fptr->Fptr)->headstart = ptr; } } /* set logical HDU position to the actual position, in case they differ */ fptr->HDUposition = (fptr->Fptr)->curhdu; while( ((fptr->Fptr)->curhdu) + 1 != hdunum) /* at the correct HDU? */ { /* move directly to the extension if we know that it exists, otherwise move to the highest known extension. */ moveto = minvalue(hdunum - 1, ((fptr->Fptr)->maxhdu) + 1); /* test if HDU exists */ if ((fptr->Fptr)->headstart[moveto] < (fptr->Fptr)->logfilesize ) { if (ffchdu(fptr, status) <= 0) /* close out the current HDU */ { if (ffgext(fptr, moveto, exttype, status) > 0) { /* failed to get the requested extension */ tstatus = 0; ffrhdu(fptr, exttype, &tstatus); /* restore the CHDU */ } } } else *status = END_OF_FILE; if (*status > 0) { if (*status != END_OF_FILE) { /* don't clutter up the message stack in the common case of */ /* simply hitting the end of file (often an expected error) */ snprintf(message,FLEN_ERRMSG, "Failed to move to HDU number %d (ffmahd).", hdunum); ffpmsg(message); } return(*status); } } /* return the type of HDU; tile compressed images which are stored */ /* in a binary table will return exttype = IMAGE_HDU, not BINARY_TBL */ if (exttype != NULL) ffghdt(fptr, exttype, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmrhd(fitsfile *fptr, /* I - FITS file pointer */ int hdumov, /* I - rel. no. of HDUs to move by (+ or -) */ int *exttype, /* O - type of extension, 0, 1, or 2 */ int *status) /* IO - error status */ /* Move a Relative number of Header Data units. Offset to the specified extension and read the header to initialize the HDU structure. */ { int extnum; if (*status > 0) return(*status); extnum = fptr->HDUposition + 1 + hdumov; /* the absolute HDU number */ ffmahd(fptr, extnum, exttype, status); /* move to the HDU */ return(*status); } /*--------------------------------------------------------------------------*/ int ffmnhd(fitsfile *fptr, /* I - FITS file pointer */ int exttype, /* I - desired extension type */ char *hduname, /* I - desired EXTNAME value for the HDU */ int hduver, /* I - desired EXTVERS value for the HDU */ int *status) /* IO - error status */ /* Move to the next HDU with a given extension type (IMAGE_HDU, ASCII_TBL, BINARY_TBL, or ANY_HDU), extension name (EXTNAME or HDUNAME keyword), and EXTVERS keyword values. If hduvers = 0, then move to the first HDU with the given type and name regardless of EXTVERS value. If no matching HDU is found in the file, then the current open HDU will remain unchanged. */ { char extname[FLEN_VALUE]; int ii, hdutype, alttype, extnum, tstatus, match, exact; int slen, putback = 0, chopped = 0; long extver; if (*status > 0) return(*status); extnum = fptr->HDUposition + 1; /* save the current HDU number */ /* This is a kludge to deal with a special case where the user specified a hduname that ended with a # character, which CFITSIO previously interpreted as a flag to mean "don't copy any other HDUs in the file into the virtual file in memory. If the remaining hduname does not end with a # character (meaning that the user originally entered a hduname ending in 2 # characters) then there is the possibility that the # character should be treated literally, if the actual EXTNAME also ends with a #. Setting putback = 1 means that we need to test for this case later on. */ if ((fptr->Fptr)->only_one) { /* if true, name orignally ended with a # */ slen = strlen(hduname); if (hduname[slen - 1] != '#') /* This will fail if real EXTNAME value */ putback = 1; /* ends with 2 # characters. */ } for (ii=1; 1; ii++) /* loop over all HDUs until EOF */ { tstatus = 0; if (ffmahd(fptr, ii, &hdutype, &tstatus)) /* move to next HDU */ { ffmahd(fptr, extnum, 0, status); /* restore original file position */ return(*status = BAD_HDU_NUM); /* couldn't find desired HDU */ } alttype = -1; if (fits_is_compressed_image(fptr, status)) alttype = BINARY_TBL; /* Does this HDU have a matching type? */ if (exttype == ANY_HDU || hdutype == exttype || hdutype == alttype) { ffmaky(fptr, 2, status); /* reset to the 2nd keyword in the header */ if (ffgkys(fptr, "EXTNAME", extname, 0, &tstatus) <= 0) /* get keyword */ { if (putback) { /* more of the kludge */ /* test if the EXTNAME value ends with a #; if so, chop it */ /* off before comparing the strings */ chopped = 0; slen = strlen(extname); if (extname[slen - 1] == '#') { extname[slen - 1] = '\0'; chopped = 1; } } /* see if the strings are an exact match */ ffcmps(hduname, extname, CASEINSEN, &match, &exact); } /* if EXTNAME keyword doesn't exist, or it does not match, then try HDUNAME */ if (tstatus || !exact) { tstatus = 0; if (ffgkys(fptr, "HDUNAME", extname, 0, &tstatus) <= 0) { if (putback) { /* more of the kludge */ chopped = 0; slen = strlen(extname); if (extname[slen - 1] == '#') { extname[slen - 1] = '\0'; /* chop off the # */ chopped = 1; } } /* see if the strings are an exact match */ ffcmps(hduname, extname, CASEINSEN, &match, &exact); } } if (!tstatus && exact) /* found a matching name */ { if (hduver) /* need to check if version numbers match? */ { if (ffgkyj(fptr, "EXTVER", &extver, 0, &tstatus) > 0) extver = 1; /* assume default EXTVER value */ if ( (int) extver == hduver) { if (chopped) { /* The # was literally part of the name, not a flag */ (fptr->Fptr)->only_one = 0; } return(*status); /* found matching name and vers */ } } else { if (chopped) { /* The # was literally part of the name, not a flag */ (fptr->Fptr)->only_one = 0; } return(*status); /* found matching name */ } } /* end of !tstatus && exact */ } /* end of matching HDU type */ } /* end of loop over HDUs */ } /*--------------------------------------------------------------------------*/ int ffthdu(fitsfile *fptr, /* I - FITS file pointer */ int *nhdu, /* O - number of HDUs in the file */ int *status) /* IO - error status */ /* Return the number of HDUs that currently exist in the file. */ { int ii, extnum, tstatus; if (*status > 0) return(*status); extnum = fptr->HDUposition + 1; /* save the current HDU number */ *nhdu = extnum - 1; /* if the CHDU is empty or not completely defined, just return */ if ((fptr->Fptr)->datastart == DATA_UNDEFINED) return(*status); tstatus = 0; /* loop until EOF */ for (ii=extnum; ffmahd(fptr, ii, 0, &tstatus) <= 0; ii++) { *nhdu = ii; } ffmahd(fptr, extnum, 0, status); /* restore orig file position */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgext(fitsfile *fptr, /* I - FITS file pointer */ int hdunum, /* I - no. of HDU to move get (0 based) */ int *exttype, /* O - type of extension, 0, 1, or 2 */ int *status) /* IO - error status */ /* Get Extension. Move to the specified extension and initialize the HDU structure. */ { int xcurhdu, xmaxhdu; LONGLONG xheadend; if (*status > 0) return(*status); if (ffmbyt(fptr, (fptr->Fptr)->headstart[hdunum], REPORT_EOF, status) <= 0) { /* temporarily save current values, in case of error */ xcurhdu = (fptr->Fptr)->curhdu; xmaxhdu = (fptr->Fptr)->maxhdu; xheadend = (fptr->Fptr)->headend; /* set new parameter values */ (fptr->Fptr)->curhdu = hdunum; fptr->HDUposition = hdunum; (fptr->Fptr)->maxhdu = maxvalue((fptr->Fptr)->maxhdu, hdunum); (fptr->Fptr)->headend = (fptr->Fptr)->logfilesize; /* set max size */ if (ffrhdu(fptr, exttype, status) > 0) { /* failed to get the new HDU, so restore previous values */ (fptr->Fptr)->curhdu = xcurhdu; fptr->HDUposition = xcurhdu; (fptr->Fptr)->maxhdu = xmaxhdu; (fptr->Fptr)->headend = xheadend; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffiblk(fitsfile *fptr, /* I - FITS file pointer */ long nblock, /* I - no. of blocks to insert */ int headdata, /* I - insert where? 0=header, 1=data */ /* -1=beginning of file */ int *status) /* IO - error status */ /* insert 2880-byte blocks at the end of the current header or data unit */ { int tstatus, savehdu, typhdu; LONGLONG insertpt, jpoint; long ii, nshift; char charfill; char buff1[2880], buff2[2880]; char *inbuff, *outbuff, *tmpbuff; char card[FLEN_CARD]; if (*status > 0 || nblock <= 0) return(*status); tstatus = *status; if (headdata == 0 || (fptr->Fptr)->hdutype == ASCII_TBL) charfill = 32; /* headers and ASCII tables have space (32) fill */ else charfill = 0; /* images and binary tables have zero fill */ if (headdata == 0) insertpt = (fptr->Fptr)->datastart; /* insert just before data, or */ else if (headdata == -1) { insertpt = 0; strcpy(card, "XTENSION= 'IMAGE ' / IMAGE extension"); } else /* at end of data, */ { insertpt = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; insertpt = ((insertpt + 2879) / 2880) * 2880; /* start of block */ /* the following formula is wrong because the current data unit may have been extended without updating the headstart value of the following HDU. */ /* insertpt = (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu + 1]; */ } inbuff = buff1; /* set pointers to input and output buffers */ outbuff = buff2; memset(outbuff, charfill, 2880); /* initialize buffer with fill */ if (nblock == 1) /* insert one block */ { if (headdata == -1) ffmrec(fptr, 1, card, status); /* change SIMPLE -> XTENSION */ ffmbyt(fptr, insertpt, REPORT_EOF, status); /* move to 1st point */ ffgbyt(fptr, 2880, inbuff, status); /* read first block of bytes */ while (*status <= 0) { ffmbyt(fptr, insertpt, REPORT_EOF, status); /* insert point */ ffpbyt(fptr, 2880, outbuff, status); /* write the output buffer */ if (*status > 0) return(*status); tmpbuff = inbuff; /* swap input and output pointers */ inbuff = outbuff; outbuff = tmpbuff; insertpt += 2880; /* increment insert point by 1 block */ ffmbyt(fptr, insertpt, REPORT_EOF, status); /* move to next block */ ffgbyt(fptr, 2880, inbuff, status); /* read block of bytes */ } *status = tstatus; /* reset status value */ ffmbyt(fptr, insertpt, IGNORE_EOF, status); /* move back to insert pt */ ffpbyt(fptr, 2880, outbuff, status); /* write the final block */ } else /* inserting more than 1 block */ { savehdu = (fptr->Fptr)->curhdu; /* save the current HDU number */ tstatus = *status; while(*status <= 0) /* find the last HDU in file */ ffmrhd(fptr, 1, &typhdu, status); if (*status == END_OF_FILE) { *status = tstatus; } ffmahd(fptr, savehdu + 1, &typhdu, status); /* move back to CHDU */ if (headdata == -1) ffmrec(fptr, 1, card, status); /* NOW change SIMPLE -> XTENSION */ /* number of 2880-byte blocks that have to be shifted down */ nshift = (long) (((fptr->Fptr)->headstart[(fptr->Fptr)->maxhdu + 1] - insertpt) / 2880); /* position of last block in file to be shifted */ jpoint = (fptr->Fptr)->headstart[(fptr->Fptr)->maxhdu + 1] - 2880; /* move all the blocks starting at end of file working backwards */ for (ii = 0; ii < nshift; ii++) { /* move to the read start position */ if (ffmbyt(fptr, jpoint, REPORT_EOF, status) > 0) return(*status); ffgbyt(fptr, 2880, inbuff,status); /* read one record */ /* move forward to the write postion */ ffmbyt(fptr, jpoint + ((LONGLONG) nblock * 2880), IGNORE_EOF, status); ffpbyt(fptr, 2880, inbuff, status); /* write the record */ jpoint -= 2880; } /* move back to the write start postion (might be EOF) */ ffmbyt(fptr, insertpt, IGNORE_EOF, status); for (ii = 0; ii < nblock; ii++) /* insert correct fill value */ ffpbyt(fptr, 2880, outbuff, status); } if (headdata == 0) /* update data start address */ (fptr->Fptr)->datastart += ((LONGLONG) nblock * 2880); /* update following HDU addresses */ for (ii = (fptr->Fptr)->curhdu; ii <= (fptr->Fptr)->maxhdu; ii++) (fptr->Fptr)->headstart[ii + 1] += ((LONGLONG) nblock * 2880); return(*status); } /*--------------------------------------------------------------------------*/ int ffgkcl(char *tcard) /* Return the type classification of the input header record TYP_STRUC_KEY: SIMPLE, BITPIX, NAXIS, NAXISn, EXTEND, BLOCKED, GROUPS, PCOUNT, GCOUNT, END XTENSION, TFIELDS, TTYPEn, TBCOLn, TFORMn, THEAP, and the first 4 COMMENT keywords in the primary array that define the FITS format. TYP_CMPRS_KEY: The keywords used in the compressed image format ZIMAGE, ZCMPTYPE, ZNAMEn, ZVALn, ZTILEn, ZBITPIX, ZNAXISn, ZSCALE, ZZERO, ZBLANK, EXTNAME = 'COMPRESSED_IMAGE' ZSIMPLE, ZTENSION, ZEXTEND, ZBLOCKED, ZPCOUNT, ZGCOUNT ZQUANTIZ, ZDITHER0 TYP_SCAL_KEY: BSCALE, BZERO, TSCALn, TZEROn TYP_NULL_KEY: BLANK, TNULLn TYP_DIM_KEY: TDIMn TYP_RANG_KEY: TLMINn, TLMAXn, TDMINn, TDMAXn, DATAMIN, DATAMAX TYP_UNIT_KEY: BUNIT, TUNITn TYP_DISP_KEY: TDISPn TYP_HDUID_KEY: EXTNAME, EXTVER, EXTLEVEL, HDUNAME, HDUVER, HDULEVEL TYP_CKSUM_KEY CHECKSUM, DATASUM TYP_WCS_KEY: Primary array: WCAXES, CTYPEn, CUNITn, CRVALn, CRPIXn, CROTAn, CDELTn CDj_is, PVj_ms, LONPOLEs, LATPOLEs Pixel list: TCTYPn, TCTYns, TCUNIn, TCUNns, TCRVLn, TCRVns, TCRPXn, TCRPks, TCDn_k, TCn_ks, TPVn_m, TPn_ms, TCDLTn, TCROTn Bintable vector: jCTYPn, jCTYns, jCUNIn, jCUNns, jCRVLn, jCRVns, iCRPXn, iCRPns, jiCDn, jiCDns, jPVn_m, jPn_ms, jCDLTn, jCROTn TYP_REFSYS_KEY: EQUINOXs, EPOCH, MJD-OBSs, RADECSYS, RADESYSs TYP_COMM_KEY: COMMENT, HISTORY, (blank keyword) TYP_CONT_KEY: CONTINUE TYP_USER_KEY: all other keywords */ { char card[20], *card1, *card5; card[0] = '\0'; strncat(card, tcard, 8); /* copy the keyword name */ strcat(card, " "); /* append blanks to make at least 8 chars long */ ffupch(card); /* make sure it is in upper case */ card1 = card + 1; /* pointer to 2nd character */ card5 = card + 5; /* pointer to 6th character */ /* the strncmp function is slow, so try to be more efficient */ if (*card == 'Z') { if (FSTRNCMP (card1, "IMAGE ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "CMPTYPE", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "NAME", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_CMPRS_KEY); } else if (FSTRNCMP (card1, "VAL", 3) == 0) { if (*(card + 4) >= '0' && *(card + 4) <= '9') return (TYP_CMPRS_KEY); } else if (FSTRNCMP (card1, "TILE", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_CMPRS_KEY); } else if (FSTRNCMP (card1, "BITPIX ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "NAXIS", 5) == 0) { if ( ( *(card + 6) >= '0' && *(card + 6) <= '9' ) || (*(card + 6) == ' ') ) return (TYP_CMPRS_KEY); } else if (FSTRNCMP (card1, "SCALE ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "ZERO ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "BLANK ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "SIMPLE ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "TENSION", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "EXTEND ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "BLOCKED", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "PCOUNT ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "GCOUNT ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "QUANTIZ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "DITHER0", 7) == 0) return (TYP_CMPRS_KEY); } else if (*card == ' ') { return (TYP_COMM_KEY); } else if (*card == 'B') { if (FSTRNCMP (card1, "ITPIX ", 7) == 0) return (TYP_STRUC_KEY); if (FSTRNCMP (card1, "LOCKED ", 7) == 0) return (TYP_STRUC_KEY); if (FSTRNCMP (card1, "LANK ", 7) == 0) return (TYP_NULL_KEY); if (FSTRNCMP (card1, "SCALE ", 7) == 0) return (TYP_SCAL_KEY); if (FSTRNCMP (card1, "ZERO ", 7) == 0) return (TYP_SCAL_KEY); if (FSTRNCMP (card1, "UNIT ", 7) == 0) return (TYP_UNIT_KEY); } else if (*card == 'C') { if (FSTRNCMP (card1, "OMMENT",6) == 0) { /* new comment string starting Oct 2001 */ if (FSTRNCMP (tcard, "COMMENT and Astrophysics', volume 376, page 3", 47) == 0) return (TYP_STRUC_KEY); /* original COMMENT strings from 1993 - 2001 */ if (FSTRNCMP (tcard, "COMMENT FITS (Flexible Image Transport System", 47) == 0) return (TYP_STRUC_KEY); if (FSTRNCMP (tcard, "COMMENT Astrophysics Supplement Series v44/p3", 47) == 0) return (TYP_STRUC_KEY); if (FSTRNCMP (tcard, "COMMENT Contact the NASA Science Office of St", 47) == 0) return (TYP_STRUC_KEY); if (FSTRNCMP (tcard, "COMMENT FITS Definition document #100 and oth", 47) == 0) return (TYP_STRUC_KEY); if (*(card + 7) == ' ') return (TYP_COMM_KEY); else return (TYP_USER_KEY); } if (FSTRNCMP (card1, "HECKSUM", 7) == 0) return (TYP_CKSUM_KEY); if (FSTRNCMP (card1, "ONTINUE", 7) == 0) return (TYP_CONT_KEY); if (FSTRNCMP (card1, "TYPE",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "UNIT",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "RVAL",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "RPIX",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "ROTA",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "RDER",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "SYER",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "DELT",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (*card1 == 'D') { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } } else if (*card == 'D') { if (FSTRNCMP (card1, "ATASUM ", 7) == 0) return (TYP_CKSUM_KEY); if (FSTRNCMP (card1, "ATAMIN ", 7) == 0) return (TYP_RANG_KEY); if (FSTRNCMP (card1, "ATAMAX ", 7) == 0) return (TYP_RANG_KEY); if (FSTRNCMP (card1, "ATE-OBS", 7) == 0) return (TYP_REFSYS_KEY); } else if (*card == 'E') { if (FSTRNCMP (card1, "XTEND ", 7) == 0) return (TYP_STRUC_KEY); if (FSTRNCMP (card1, "ND ", 7) == 0) return (TYP_STRUC_KEY); if (FSTRNCMP (card1, "XTNAME ", 7) == 0) { /* check for special compressed image value */ if (FSTRNCMP(tcard, "EXTNAME = 'COMPRESSED_IMAGE'", 28) == 0) return (TYP_CMPRS_KEY); else return (TYP_HDUID_KEY); } if (FSTRNCMP (card1, "XTVER ", 7) == 0) return (TYP_HDUID_KEY); if (FSTRNCMP (card1, "XTLEVEL", 7) == 0) return (TYP_HDUID_KEY); if (FSTRNCMP (card1, "QUINOX", 6) == 0) return (TYP_REFSYS_KEY); if (FSTRNCMP (card1, "QUI",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_REFSYS_KEY); } if (FSTRNCMP (card1, "POCH ", 7) == 0) return (TYP_REFSYS_KEY); } else if (*card == 'G') { if (FSTRNCMP (card1, "COUNT ", 7) == 0) return (TYP_STRUC_KEY); if (FSTRNCMP (card1, "ROUPS ", 7) == 0) return (TYP_STRUC_KEY); } else if (*card == 'H') { if (FSTRNCMP (card1, "DUNAME ", 7) == 0) return (TYP_HDUID_KEY); if (FSTRNCMP (card1, "DUVER ", 7) == 0) return (TYP_HDUID_KEY); if (FSTRNCMP (card1, "DULEVEL", 7) == 0) return (TYP_HDUID_KEY); if (FSTRNCMP (card1, "ISTORY",6) == 0) { if (*(card + 7) == ' ') return (TYP_COMM_KEY); else return (TYP_USER_KEY); } } else if (*card == 'L') { if (FSTRNCMP (card1, "ONPOLE",6) == 0) return (TYP_WCS_KEY); if (FSTRNCMP (card1, "ATPOLE",6) == 0) return (TYP_WCS_KEY); if (FSTRNCMP (card1, "ONP",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "ATP",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } } else if (*card == 'M') { if (FSTRNCMP (card1, "JD-OBS ", 7) == 0) return (TYP_REFSYS_KEY); if (FSTRNCMP (card1, "JDOB",4) == 0) { if (*(card+5) >= '0' && *(card+5) <= '9') return (TYP_REFSYS_KEY); } } else if (*card == 'N') { if (FSTRNCMP (card1, "AXIS", 4) == 0) { if ((*card5 >= '0' && *card5 <= '9') || (*card5 == ' ')) return (TYP_STRUC_KEY); } } else if (*card == 'P') { if (FSTRNCMP (card1, "COUNT ", 7) == 0) return (TYP_STRUC_KEY); if (*card1 == 'C') { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } else if (*card1 == 'V') { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } else if (*card1 == 'S') { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } } else if (*card == 'R') { if (FSTRNCMP (card1, "ADECSYS", 7) == 0) return (TYP_REFSYS_KEY); if (FSTRNCMP (card1, "ADESYS", 6) == 0) return (TYP_REFSYS_KEY); if (FSTRNCMP (card1, "ADE",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_REFSYS_KEY); } } else if (*card == 'S') { if (FSTRNCMP (card1, "IMPLE ", 7) == 0) return (TYP_STRUC_KEY); } else if (*card == 'T') { if (FSTRNCMP (card1, "TYPE", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_STRUC_KEY); } else if (FSTRNCMP (card1, "FORM", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_STRUC_KEY); } else if (FSTRNCMP (card1, "BCOL", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_STRUC_KEY); } else if (FSTRNCMP (card1, "FIELDS ", 7) == 0) return (TYP_STRUC_KEY); else if (FSTRNCMP (card1, "HEAP ", 7) == 0) return (TYP_STRUC_KEY); else if (FSTRNCMP (card1, "NULL", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_NULL_KEY); } else if (FSTRNCMP (card1, "DIM", 3) == 0) { if (*(card + 4) >= '0' && *(card + 4) <= '9') return (TYP_DIM_KEY); } else if (FSTRNCMP (card1, "UNIT", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_UNIT_KEY); } else if (FSTRNCMP (card1, "DISP", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_DISP_KEY); } else if (FSTRNCMP (card1, "SCAL", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_SCAL_KEY); } else if (FSTRNCMP (card1, "ZERO", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_SCAL_KEY); } else if (FSTRNCMP (card1, "LMIN", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_RANG_KEY); } else if (FSTRNCMP (card1, "LMAX", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_RANG_KEY); } else if (FSTRNCMP (card1, "DMIN", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_RANG_KEY); } else if (FSTRNCMP (card1, "DMAX", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_RANG_KEY); } else if (FSTRNCMP (card1, "CTYP",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CTY",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CUNI",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CUN",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRVL",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRV",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRPX",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRP",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CROT",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CDLT",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CDE",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRD",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CSY",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "WCS",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "C",1) == 0) { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "P",1) == 0) { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "V",1) == 0) { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "S",1) == 0) { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } } else if (*card == 'X') { if (FSTRNCMP (card1, "TENSION", 7) == 0) return (TYP_STRUC_KEY); } else if (*card == 'W') { if (FSTRNCMP (card1, "CSAXES", 6) == 0) return (TYP_WCS_KEY); if (FSTRNCMP (card1, "CSNAME", 6) == 0) return (TYP_WCS_KEY); if (FSTRNCMP (card1, "CAX", 3) == 0) { if (*(card + 4) >= '0' && *(card + 4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CSN", 3) == 0) { if (*(card + 4) >= '0' && *(card + 4) <= '9') return (TYP_WCS_KEY); } } else if (*card >= '0' && *card <= '9') { if (*card1 == 'C') { if (FSTRNCMP (card1, "CTYP",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CTY",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CUNI",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CUN",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRVL",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRV",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRPX",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRP",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CROT",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CDLT",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CDE",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRD",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CSY",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } } else if (FSTRNCMP (card1, "V",1) == 0) { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "S",1) == 0) { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } else if (*card1 >= '0' && *card1 <= '9') { /* 2 digits at beginning of keyword */ if ( (*(card + 2) == 'P') && (*(card + 3) == 'C') ) { if (*(card + 4) >= '0' && *(card + 4) <= '9') return (TYP_WCS_KEY); /* ijPCn keyword */ } else if ( (*(card + 2) == 'C') && (*(card + 3) == 'D') ) { if (*(card + 4) >= '0' && *(card + 4) <= '9') return (TYP_WCS_KEY); /* ijCDn keyword */ } } } return (TYP_USER_KEY); /* by default all others are user keywords */ } /*--------------------------------------------------------------------------*/ int ffdtyp(const char *cval, /* I - formatted string representation of the value */ char *dtype, /* O - datatype code: C, L, F, I, or X */ int *status) /* IO - error status */ /* determine implicit datatype of input string. This assumes that the string conforms to the FITS standard for keyword values, so may not detect all invalid formats. */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (cval[0] == '\0') return(*status = VALUE_UNDEFINED); else if (cval[0] == '\'') *dtype = 'C'; /* character string starts with a quote */ else if (cval[0] == 'T' || cval[0] == 'F') *dtype = 'L'; /* logical = T or F character */ else if (cval[0] == '(') *dtype = 'X'; /* complex datatype "(1.2, -3.4)" */ else if (strchr(cval,'.')) *dtype = 'F'; /* float usualy contains a decimal point */ else if (strchr(cval,'E') || strchr(cval,'D') ) *dtype = 'F'; /* exponential contains a E or D */ else *dtype = 'I'; /* if none of the above assume it is integer */ return(*status); } /*--------------------------------------------------------------------------*/ int ffinttyp(char *cval, /* I - formatted string representation of the integer */ int *dtype, /* O - datatype code: TBYTE, TSHORT, TUSHORT, etc */ int *negative, /* O - is cval negative? */ int *status) /* IO - error status */ /* determine implicit datatype of input integer string. This assumes that the string conforms to the FITS standard for integer keyword value, so may not detect all invalid formats. */ { int ii, len; char *p; if (*status > 0) /* inherit input status value if > 0 */ return(*status); *dtype = 0; /* initialize to NULL */ *negative = 0; p = cval; if (*p == '+') { p++; /* ignore leading + sign */ } else if (*p == '-') { p++; *negative = 1; /* this is a negative number */ } if (*p == '0') { while (*p == '0') p++; /* skip leading zeros */ if (*p == 0) { /* the value is a string of 1 or more zeros */ *dtype = TSBYTE; return(*status); } } len = strlen(p); for (ii = 0; ii < len; ii++) { if (!isdigit(*(p+ii))) { *status = BAD_INTKEY; return(*status); } } /* check for unambiguous cases, based on length of the string */ if (len == 0) { *status = VALUE_UNDEFINED; } else if (len < 3) { *dtype = TSBYTE; } else if (len == 4) { *dtype = TSHORT; } else if (len > 5 && len < 10) { *dtype = TINT; } else if (len > 10 && len < 19) { *dtype = TLONGLONG; } else if (len > 20) { *status = BAD_INTKEY; } else { if (!(*negative)) { /* positive integers */ if (len == 3) { if (strcmp(p,"127") <= 0 ) { *dtype = TSBYTE; } else if (strcmp(p,"255") <= 0 ) { *dtype = TBYTE; } else { *dtype = TSHORT; } } else if (len == 5) { if (strcmp(p,"32767") <= 0 ) { *dtype = TSHORT; } else if (strcmp(p,"65535") <= 0 ) { *dtype = TUSHORT; } else { *dtype = TINT; } } else if (len == 10) { if (strcmp(p,"2147483647") <= 0 ) { *dtype = TINT; } else if (strcmp(p,"4294967295") <= 0 ) { *dtype = TUINT; } else { *dtype = TLONGLONG; } } else if (len == 19) { if (strcmp(p,"9223372036854775807") <= 0 ) { *dtype = TLONGLONG; } else { *dtype = TULONGLONG; } } else if (len == 20) { if (strcmp(p,"18446744073709551615") <= 0 ) { *dtype = TULONGLONG; } else { *status = BAD_INTKEY; } } } else { /* negative integers */ if (len == 3) { if (strcmp(p,"128") <= 0 ) { *dtype = TSBYTE; } else { *dtype = TSHORT; } } else if (len == 5) { if (strcmp(p,"32768") <= 0 ) { *dtype = TSHORT; } else { *dtype = TINT; } } else if (len == 10) { if (strcmp(p,"2147483648") <= 0 ) { *dtype = TINT; } else { *dtype = TLONGLONG; } } else if (len == 19) { if (strcmp(p,"9223372036854775808") <= 0 ) { *dtype = TLONGLONG; } else { *status = BAD_INTKEY; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2x(const char *cval, /* I - formatted string representation of the value */ char *dtype, /* O - datatype code: C, L, F, I or X */ /* Only one of the following will be defined, depending on datatype */ long *ival, /* O - integer value */ int *lval, /* O - logical value */ char *sval, /* O - string value */ double *dval, /* O - double value */ int *status) /* IO - error status */ /* high level routine to convert formatted character string to its intrinsic data type */ { ffdtyp(cval, dtype, status); /* determine the datatype */ if (*dtype == 'I') ffc2ii(cval, ival, status); else if (*dtype == 'F') ffc2dd(cval, dval, status); else if (*dtype == 'L') ffc2ll(cval, lval, status); else ffc2s(cval, sval, status); /* C and X formats */ return(*status); } /*--------------------------------------------------------------------------*/ int ffc2xx(const char *cval, /* I - formatted string representation of the value */ char *dtype, /* O - datatype code: C, L, F, I or X */ /* Only one of the following will be defined, depending on datatype */ LONGLONG *ival, /* O - integer value */ int *lval, /* O - logical value */ char *sval, /* O - string value */ double *dval, /* O - double value */ int *status) /* IO - error status */ /* high level routine to convert formatted character string to its intrinsic data type */ { ffdtyp(cval, dtype, status); /* determine the datatype */ if (*dtype == 'I') ffc2jj(cval, ival, status); else if (*dtype == 'F') ffc2dd(cval, dval, status); else if (*dtype == 'L') ffc2ll(cval, lval, status); else ffc2s(cval, sval, status); /* C and X formats */ return(*status); } /*--------------------------------------------------------------------------*/ int ffc2uxx(const char *cval, /* I - formatted string representation of the value */ char *dtype, /* O - datatype code: C, L, F, I or X */ /* Only one of the following will be defined, depending on datatype */ ULONGLONG *ival, /* O - integer value */ int *lval, /* O - logical value */ char *sval, /* O - string value */ double *dval, /* O - double value */ int *status) /* IO - error status */ /* high level routine to convert formatted character string to its intrinsic data type */ { ffdtyp(cval, dtype, status); /* determine the datatype */ if (*dtype == 'I') ffc2ujj(cval, ival, status); else if (*dtype == 'F') ffc2dd(cval, dval, status); else if (*dtype == 'L') ffc2ll(cval, lval, status); else ffc2s(cval, sval, status); /* C and X formats */ return(*status); } /*--------------------------------------------------------------------------*/ int ffc2i(const char *cval, /* I - string representation of the value */ long *ival, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert formatted string to an integer value, doing implicit datatype conversion if necessary. */ { char dtype, sval[81], msg[81]; int lval; double dval; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (cval[0] == '\0') return(*status = VALUE_UNDEFINED); /* null value string */ /* convert the keyword to its native datatype */ ffc2x(cval, &dtype, ival, &lval, sval, &dval, status); if (dtype == 'X' ) { *status = BAD_INTKEY; } else if (dtype == 'C') { /* try reading the string as a number */ if (ffc2dd(sval, &dval, status) <= 0) { if (dval > (double) LONG_MAX || dval < (double) LONG_MIN) *status = NUM_OVERFLOW; else *ival = (long) dval; } } else if (dtype == 'F') { if (dval > (double) LONG_MAX || dval < (double) LONG_MIN) *status = NUM_OVERFLOW; else *ival = (long) dval; } else if (dtype == 'L') { *ival = (long) lval; } if (*status > 0) { *ival = 0; strcpy(msg,"Error in ffc2i evaluating string as an integer: "); strncat(msg,cval,30); ffpmsg(msg); return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2j(const char *cval, /* I - string representation of the value */ LONGLONG *ival, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert formatted string to a LONGLONG integer value, doing implicit datatype conversion if necessary. */ { char dtype, sval[81], msg[81]; int lval; double dval; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (cval[0] == '\0') return(*status = VALUE_UNDEFINED); /* null value string */ /* convert the keyword to its native datatype */ ffc2xx(cval, &dtype, ival, &lval, sval, &dval, status); if (dtype == 'X' ) { *status = BAD_INTKEY; } else if (dtype == 'C') { /* try reading the string as a number */ if (ffc2dd(sval, &dval, status) <= 0) { if (dval > (double) LONGLONG_MAX || dval < (double) LONGLONG_MIN) *status = NUM_OVERFLOW; else *ival = (LONGLONG) dval; } } else if (dtype == 'F') { if (dval > (double) LONGLONG_MAX || dval < (double) LONGLONG_MIN) *status = NUM_OVERFLOW; else *ival = (LONGLONG) dval; } else if (dtype == 'L') { *ival = (LONGLONG) lval; } if (*status > 0) { *ival = 0; strcpy(msg,"Error in ffc2j evaluating string as a long integer: "); strncat(msg,cval,30); ffpmsg(msg); return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2uj(const char *cval, /* I - string representation of the value */ ULONGLONG *ival, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert formatted string to a ULONGLONG integer value, doing implicit datatype conversion if necessary. */ { char dtype, sval[81], msg[81]; int lval; double dval; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (cval[0] == '\0') return(*status = VALUE_UNDEFINED); /* null value string */ /* convert the keyword to its native datatype */ ffc2uxx(cval, &dtype, ival, &lval, sval, &dval, status); if (dtype == 'X' ) { *status = BAD_INTKEY; } else if (dtype == 'C') { /* try reading the string as a number */ if (ffc2dd(sval, &dval, status) <= 0) { if (dval > (double) DULONGLONG_MAX || dval < -0.49) *status = NUM_OVERFLOW; else *ival = (ULONGLONG) dval; } } else if (dtype == 'F') { if (dval > (double) DULONGLONG_MAX || dval < -0.49) *status = NUM_OVERFLOW; else *ival = (ULONGLONG) dval; } else if (dtype == 'L') { *ival = (ULONGLONG) lval; } if (*status > 0) { *ival = 0; strcpy(msg,"Error in ffc2j evaluating string as a long integer: "); strncat(msg,cval,30); ffpmsg(msg); return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2l(const char *cval, /* I - string representation of the value */ int *lval, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert formatted string to a logical value, doing implicit datatype conversion if necessary */ { char dtype, sval[81], msg[81]; long ival; double dval; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (cval[0] == '\0') return(*status = VALUE_UNDEFINED); /* null value string */ /* convert the keyword to its native datatype */ ffc2x(cval, &dtype, &ival, lval, sval, &dval, status); if (dtype == 'C' || dtype == 'X' ) *status = BAD_LOGICALKEY; if (*status > 0) { *lval = 0; strcpy(msg,"Error in ffc2l evaluating string as a logical: "); strncat(msg,cval,30); ffpmsg(msg); return(*status); } if (dtype == 'I') { if (ival) *lval = 1; else *lval = 0; } else if (dtype == 'F') { if (dval) *lval = 1; else *lval = 0; } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2r(const char *cval, /* I - string representation of the value */ float *fval, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert formatted string to a real float value, doing implicit datatype conversion if necessary */ { char dtype, sval[81], msg[81]; int lval; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (cval[0] == '\0') return(*status = VALUE_UNDEFINED); /* null value string */ ffdtyp(cval, &dtype, status); /* determine the datatype */ if (dtype == 'I' || dtype == 'F') ffc2rr(cval, fval, status); else if (dtype == 'L') { ffc2ll(cval, &lval, status); *fval = (float) lval; } else if (dtype == 'C') { /* try reading the string as a number */ ffc2s(cval, sval, status); ffc2rr(sval, fval, status); } else *status = BAD_FLOATKEY; if (*status > 0) { *fval = 0.; strcpy(msg,"Error in ffc2r evaluating string as a float: "); strncat(msg,cval,30); ffpmsg(msg); return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2d(const char *cval, /* I - string representation of the value */ double *dval, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert formatted string to a double value, doing implicit datatype conversion if necessary */ { char dtype, sval[81], msg[81]; int lval; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (cval[0] == '\0') return(*status = VALUE_UNDEFINED); /* null value string */ ffdtyp(cval, &dtype, status); /* determine the datatype */ if (dtype == 'I' || dtype == 'F') ffc2dd(cval, dval, status); else if (dtype == 'L') { ffc2ll(cval, &lval, status); *dval = (double) lval; } else if (dtype == 'C') { /* try reading the string as a number */ ffc2s(cval, sval, status); ffc2dd(sval, dval, status); } else *status = BAD_DOUBLEKEY; if (*status > 0) { *dval = 0.; strcpy(msg,"Error in ffc2d evaluating string as a double: "); strncat(msg,cval,30); ffpmsg(msg); return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2ii(const char *cval, /* I - string representation of the value */ long *ival, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert null-terminated formatted string to an integer value */ { char *loc, msg[81]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); errno = 0; *ival = 0; *ival = strtol(cval, &loc, 10); /* read the string as an integer */ /* check for read error, or junk following the integer */ if (*loc != '\0' && *loc != ' ' ) *status = BAD_C2I; if (errno == ERANGE) { strcpy(msg,"Range Error in ffc2ii converting string to long int: "); strncat(msg,cval,25); ffpmsg(msg); *status = NUM_OVERFLOW; errno = 0; } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2jj(const char *cval, /* I - string representation of the value */ LONGLONG *ival, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert null-terminated formatted string to an long long integer value */ { char *loc, msg[81]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); errno = 0; *ival = 0; #if defined(_MSC_VER) /* Microsoft Visual C++ 6.0 does not have the strtoll function */ *ival = _atoi64(cval); loc = (char *) cval; while (*loc == ' ') loc++; /* skip spaces */ if (*loc == '-') loc++; /* skip minus sign */ if (*loc == '+') loc++; /* skip plus sign */ while (isdigit(*loc)) loc++; /* skip digits */ #elif (USE_LL_SUFFIX == 1) *ival = strtoll(cval, &loc, 10); /* read the string as an integer */ #else *ival = strtol(cval, &loc, 10); /* read the string as an integer */ #endif /* check for read error, or junk following the integer */ if (*loc != '\0' && *loc != ' ' ) *status = BAD_C2I; if (errno == ERANGE) { strcpy(msg,"Range Error in ffc2jj converting string to longlong int: "); strncat(msg,cval,23); ffpmsg(msg); *status = NUM_OVERFLOW; errno = 0; } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2ujj(const char *cval, /* I - string representation of the value */ ULONGLONG *ival, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert null-terminated formatted string to an unsigned long long integer value */ { char *loc, msg[81]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); errno = 0; *ival = 0; #if defined(_MSC_VER) /* Microsoft Visual C++ 6.0 does not have the strtoll function */ /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ /* !!!!! This needs to be modified to use the unsigned long long version of _atoi64 */ /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ *ival = _atoi64(cval); loc = (char *) cval; while (*loc == ' ') loc++; /* skip spaces */ if (*loc == '-') loc++; /* skip minus sign */ if (*loc == '+') loc++; /* skip plus sign */ while (isdigit(*loc)) loc++; /* skip digits */ #elif (USE_LL_SUFFIX == 1) *ival = strtoull(cval, &loc, 10); /* read the string as an integer */ #else *ival = strtoul(cval, &loc, 10); /* read the string as an integer */ #endif /* check for read error, or junk following the integer */ if (*loc != '\0' && *loc != ' ' ) *status = BAD_C2I; if (errno == ERANGE) { strcpy(msg,"Range Error in ffc2ujj converting string to unsigned longlong int: "); strncat(msg,cval,25); ffpmsg(msg); *status = NUM_OVERFLOW; errno = 0; } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2ll(const char *cval, /* I - string representation of the value: T or F */ int *lval, /* O - numerical value of the input string: 1 or 0 */ int *status) /* IO - error status */ /* convert null-terminated formatted string to a logical value */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (cval[0] == 'T') *lval = 1; else *lval = 0; /* any character besides T is considered false */ return(*status); } /*--------------------------------------------------------------------------*/ int ffc2s(const char *instr, /* I - null terminated quoted input string */ char *outstr, /* O - null terminated output string without quotes */ int *status) /* IO - error status */ /* convert an input quoted string to an unquoted string by removing the leading and trailing quote character. Also, replace any pairs of single quote characters with just a single quote character (FITS used a pair of single quotes to represent a literal quote character within the string). */ { int jj; size_t len, ii; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (instr[0] != '\'') { if (instr[0] == '\0') { outstr[0] = '\0'; return(*status = VALUE_UNDEFINED); /* null value string */ } else { strcpy(outstr, instr); /* no leading quote, so return input string */ return(*status); } } len = strlen(instr); for (ii=1, jj=0; ii < len; ii++, jj++) { if (instr[ii] == '\'') /* is this the closing quote? */ { if (instr[ii+1] == '\'') /* 2 successive quotes? */ ii++; /* copy only one of the quotes */ else break; /* found the closing quote, so exit this loop */ } outstr[jj] = instr[ii]; /* copy the next character to the output */ } outstr[jj] = '\0'; /* terminate the output string */ if (ii == len) { ffpmsg("This string value has no closing quote (ffc2s):"); ffpmsg(instr); return(*status = 205); } for (jj--; jj >= 0; jj--) /* replace trailing blanks with nulls */ { if (outstr[jj] == ' ') outstr[jj] = 0; else break; } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2rr(const char *cval, /* I - string representation of the value */ float *fval, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert null-terminated formatted string to a float value */ { char *loc, msg[81], tval[73]; struct lconv *lcc = 0; static char decimalpt = 0; short *sptr, iret; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (!decimalpt) { /* only do this once for efficiency */ lcc = localeconv(); /* set structure containing local decimal point symbol */ decimalpt = *(lcc->decimal_point); } errno = 0; *fval = 0.; if (strchr(cval, 'D') || decimalpt == ',') { /* strtod expects a comma, not a period, as the decimal point */ if (strlen(cval) > 72) { strcpy(msg,"Error: Invalid string to float in ffc2rr"); ffpmsg(msg); return (*status=BAD_C2F); } strcpy(tval, cval); /* The C language does not support a 'D'; replace with 'E' */ if ((loc = strchr(tval, 'D'))) *loc = 'E'; if (decimalpt == ',') { /* strtod expects a comma, not a period, as the decimal point */ if ((loc = strchr(tval, '.'))) *loc = ','; } *fval = (float) strtod(tval, &loc); /* read the string as an float */ } else { *fval = (float) strtod(cval, &loc); } /* check for read error, or junk following the value */ if (*loc != '\0' && *loc != ' ' ) { strcpy(msg,"Error in ffc2rr converting string to float: "); strncat(msg,cval,30); ffpmsg(msg); *status = BAD_C2F; } sptr = (short *) fval; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif iret = fnan(*sptr); /* if iret == 1, then the float value is a NaN */ if (errno == ERANGE || (iret == 1) ) { strcpy(msg,"Error in ffc2rr converting string to float: "); strncat(msg,cval,30); ffpmsg(msg); *fval = 0.; *status = NUM_OVERFLOW; errno = 0; } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2dd(const char *cval, /* I - string representation of the value */ double *dval, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert null-terminated formatted string to a double value */ { char *loc, msg[81], tval[73]; struct lconv *lcc = 0; static char decimalpt = 0; short *sptr, iret; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (!decimalpt) { /* only do this once for efficiency */ lcc = localeconv(); /* set structure containing local decimal point symbol */ decimalpt = *(lcc->decimal_point); } errno = 0; *dval = 0.; if (strchr(cval, 'D') || decimalpt == ',') { /* need to modify a temporary copy of the string before parsing it */ if (strlen(cval) > 72) { strcpy(msg,"Error: Invalid string to double in ffc2dd"); ffpmsg(msg); return (*status=BAD_C2D); } strcpy(tval, cval); /* The C language does not support a 'D'; replace with 'E' */ if ((loc = strchr(tval, 'D'))) *loc = 'E'; if (decimalpt == ',') { /* strtod expects a comma, not a period, as the decimal point */ if ((loc = strchr(tval, '.'))) *loc = ','; } *dval = strtod(tval, &loc); /* read the string as an double */ } else { *dval = strtod(cval, &loc); } /* check for read error, or junk following the value */ if (*loc != '\0' && *loc != ' ' ) { strcpy(msg,"Error in ffc2dd converting string to double: "); strncat(msg,cval,30); ffpmsg(msg); *status = BAD_C2D; } sptr = (short *) dval; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif iret = dnan(*sptr); /* if iret == 1, then the double value is a NaN */ if (errno == ERANGE || (iret == 1) ) { strcpy(msg,"Error in ffc2dd converting string to double: "); strncat(msg,cval,30); ffpmsg(msg); *dval = 0.; *status = NUM_OVERFLOW; errno = 0; } return(*status); } /* ================================================================== */ /* A hack for nonunix machines, which lack strcasecmp and strncasecmp */ /* ================================================================== */ int fits_strcasecmp(const char *s1, const char *s2) { char c1, c2; for (;;) { c1 = toupper( *s1 ); c2 = toupper( *s2 ); if (c1 < c2) return(-1); if (c1 > c2) return(1); if (c1 == 0) return(0); s1++; s2++; } } int fits_strncasecmp(const char *s1, const char *s2, size_t n) { char c1, c2; for (; n-- ;) { c1 = toupper( *s1 ); c2 = toupper( *s2 ); if (c1 < c2) return(-1); if (c1 > c2) return(1); if (c1 == 0) return(0); s1++; s2++; } return(0); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/fitsio.h0000644000175100001710000035102700000000000017601 0ustar00vstsdocker/* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ /* Copyright (Unpublished--all rights reserved under the copyright laws of the United States), U.S. Government as represented by the Administrator of the National Aeronautics and Space Administration. No copyright is claimed in the United States under Title 17, U.S. Code. Permission to freely use, copy, modify, and distribute this software and its documentation without fee is hereby granted, provided that this copyright notice and disclaimer of warranty appears in all copies. DISCLAIMER: THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT SHALL NASA BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, CONTRACT, TORT , OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER." */ #ifndef _FITSIO_H #define _FITSIO_H #define CFITSIO_VERSION 4.0.0 #define CFITSIO_MICRO 0 #define CFITSIO_MINOR 0 #define CFITSIO_MAJOR 4 #define CFITSIO_SONAME 9 /* the SONAME is incremented in a new release if the binary shared */ /* library (on linux and Mac systems) is not backward compatible */ /* with the previous release of CFITSIO */ /* CFITS_API is defined below for use on Windows systems. */ /* It is used to identify the public functions which should be exported. */ /* This has no effect on non-windows platforms where "WIN32" is not defined */ #if defined (WIN32) #if defined(cfitsio_EXPORTS) #define CFITS_API __declspec(dllexport) #else #define CFITS_API /* __declspec(dllimport) */ #endif /* CFITS_API */ #else /* defined (WIN32) */ #define CFITS_API #endif #include /* the following was provided by Michael Greason (GSFC) to fix a */ /* C/Fortran compatibility problem on an SGI Altix system running */ /* SGI ProPack 4 [this is a Novell SuSE Enterprise 9 derivative] */ /* and using the Intel C++ and Fortran compilers (version 9.1) */ #if defined(__INTEL_COMPILER) && defined(__itanium__) # define mipsFortran 1 # define _MIPS_SZLONG 64 #endif #if defined(linux) || defined(__APPLE__) || defined(__sgi) # include /* apparently needed on debian linux systems */ #endif /* to define off_t */ #include /* apparently needed to define size_t with gcc 2.8.1 */ #include /* needed for LLONG_MAX and INT64_MAX definitions */ /* Define the datatype for variables which store file offset values. */ /* The newer 'off_t' datatype should be used for this purpose, but some */ /* older compilers do not recognize this type, in which case we use 'long' */ /* instead. Note that _OFF_T is defined (or not) in stdio.h depending */ /* on whether _LARGEFILE_SOURCE is defined in sys/feature_tests.h */ /* (at least on Solaris platforms using cc) */ /* Debian systems require: "(defined(linux) && defined(__off_t_defined))" */ /* the mingw-w64 compiler requires: "(defined(__MINGW32__) && defined(_OFF_T_DEFINED))" */ #if defined(_OFF_T) \ || (defined(linux) && defined(__off_t_defined)) \ || (defined(__MINGW32__) && defined(_OFF_T_DEFINED)) \ || defined(_MIPS_SZLONG) || defined(__APPLE__) || defined(_AIX) # define OFF_T off_t #elif defined(__BORLANDC__) || (defined(_MSC_VER) && (_MSC_VER>= 1400)) # define OFF_T long long #else # define OFF_T long #endif /* this block determines if the the string function name is strtol or strtoll, and whether to use %ld or %lld in printf statements */ /* The following 2 cases for that Athon64 were removed on 4 Jan 2006; they appear to be incorrect now that LONGLONG is always typedef'ed to 'long long' || defined(__ia64__) \ || defined(__x86_64__) \ */ #if (defined(__alpha) && ( defined(__unix__) || defined(__NetBSD__) )) \ || defined(__sparcv9) || (defined(__sparc__) && defined(__arch64__)) \ || defined(__powerpc64__) || defined(__64BIT__) \ || (defined(_MIPS_SZLONG) && _MIPS_SZLONG == 64) \ || defined( _MSC_VER)|| defined(__BORLANDC__) # define USE_LL_SUFFIX 0 #else # define USE_LL_SUFFIX 1 #endif /* Determine what 8-byte integer data type is available. 'long long' is now supported by most compilers, but older MS Visual C++ compilers before V7.0 use '__int64' instead. */ #ifndef LONGLONG_TYPE /* this may have been previously defined */ #if defined(_MSC_VER) /* Microsoft Visual C++ */ #if (_MSC_VER < 1300) /* versions earlier than V7.0 do not have 'long long' */ typedef __int64 LONGLONG; typedef unsigned __int64 ULONGLONG; #else /* newer versions do support 'long long' */ typedef long long LONGLONG; typedef unsigned long long ULONGLONG; #endif #elif defined( __BORLANDC__) /* for the Borland 5.5 compiler, in particular */ typedef __int64 LONGLONG; typedef unsigned __int64 ULONGLONG; #else typedef long long LONGLONG; typedef unsigned long long ULONGLONG; #endif #define LONGLONG_TYPE #endif #ifndef LONGLONG_MAX #ifdef LLONG_MAX /* Linux and Solaris definition */ #define LONGLONG_MAX LLONG_MAX #define LONGLONG_MIN LLONG_MIN #elif defined(LONG_LONG_MAX) #define LONGLONG_MAX LONG_LONG_MAX #define LONGLONG_MIN LONG_LONG_MIN #elif defined(__LONG_LONG_MAX__) /* Mac OS X & CYGWIN defintion */ #define LONGLONG_MAX __LONG_LONG_MAX__ #define LONGLONG_MIN (-LONGLONG_MAX -1LL) #elif defined(INT64_MAX) /* windows definition */ #define LONGLONG_MAX INT64_MAX #define LONGLONG_MIN INT64_MIN #elif defined(_I64_MAX) /* windows definition */ #define LONGLONG_MAX _I64_MAX #define LONGLONG_MIN _I64_MIN #elif (defined(__alpha) && ( defined(__unix__) || defined(__NetBSD__) )) \ || defined(__sparcv9) \ || defined(__ia64__) \ || defined(__x86_64__) \ || defined(_SX) \ || defined(__powerpc64__) || defined(__64BIT__) \ || (defined(_MIPS_SZLONG) && _MIPS_SZLONG == 64) /* sizeof(long) = 64 */ #define LONGLONG_MAX 9223372036854775807L /* max 64-bit integer */ #define LONGLONG_MIN (-LONGLONG_MAX -1L) /* min 64-bit integer */ #else /* define a default value, even if it is never used */ #define LONGLONG_MAX 9223372036854775807LL /* max 64-bit integer */ #define LONGLONG_MIN (-LONGLONG_MAX -1LL) /* min 64-bit integer */ #endif #endif /* end of ndef LONGLONG_MAX section */ /* ================================================================= */ /* The following exclusion if __CINT__ is defined is needed for ROOT */ #ifndef __CINT__ #include "longnam.h" #endif #define NIOBUF 40 /* number of IO buffers to create (default = 40) */ /* !! Significantly increasing NIOBUF may degrade performance !! */ #define IOBUFLEN 2880 /* size in bytes of each IO buffer (DONT CHANGE!) */ /* global variables */ #define FLEN_FILENAME 1025 /* max length of a filename */ #define FLEN_KEYWORD 75 /* max length of a keyword (HIERARCH convention) */ #define FLEN_CARD 81 /* length of a FITS header card */ #define FLEN_VALUE 71 /* max length of a keyword value string */ #define FLEN_COMMENT 73 /* max length of a keyword comment string */ #define FLEN_ERRMSG 81 /* max length of a FITSIO error message */ #define FLEN_STATUS 31 /* max length of a FITSIO status text string */ #define TBIT 1 /* codes for FITS table data types */ #define TBYTE 11 #define TSBYTE 12 #define TLOGICAL 14 #define TSTRING 16 #define TUSHORT 20 #define TSHORT 21 #define TUINT 30 #define TINT 31 #define TULONG 40 #define TLONG 41 #define TINT32BIT 41 /* used when returning datatype of a column */ #define TFLOAT 42 #define TULONGLONG 80 #define TLONGLONG 81 #define TDOUBLE 82 #define TCOMPLEX 83 #define TDBLCOMPLEX 163 #define TYP_STRUC_KEY 10 #define TYP_CMPRS_KEY 20 #define TYP_SCAL_KEY 30 #define TYP_NULL_KEY 40 #define TYP_DIM_KEY 50 #define TYP_RANG_KEY 60 #define TYP_UNIT_KEY 70 #define TYP_DISP_KEY 80 #define TYP_HDUID_KEY 90 #define TYP_CKSUM_KEY 100 #define TYP_WCS_KEY 110 #define TYP_REFSYS_KEY 120 #define TYP_COMM_KEY 130 #define TYP_CONT_KEY 140 #define TYP_USER_KEY 150 #define INT32BIT int /* 32-bit integer datatype. Currently this */ /* datatype is an 'int' on all useful platforms */ /* however, it is possible that that are cases */ /* where 'int' is a 2-byte integer, in which case */ /* INT32BIT would need to be defined as 'long'. */ #define BYTE_IMG 8 /* BITPIX code values for FITS image types */ #define SHORT_IMG 16 #define LONG_IMG 32 #define LONGLONG_IMG 64 #define FLOAT_IMG -32 #define DOUBLE_IMG -64 /* The following 2 codes are not true FITS */ /* datatypes; these codes are only used internally */ /* within cfitsio to make it easier for users */ /* to deal with unsigned integers. */ #define SBYTE_IMG 10 #define USHORT_IMG 20 #define ULONG_IMG 40 #define ULONGLONG_IMG 80 #define IMAGE_HDU 0 /* Primary Array or IMAGE HDU */ #define ASCII_TBL 1 /* ASCII table HDU */ #define BINARY_TBL 2 /* Binary table HDU */ #define ANY_HDU -1 /* matches any HDU type */ #define READONLY 0 /* options when opening a file */ #define READWRITE 1 /* adopt a hopefully obscure number to use as a null value flag */ /* could be problems if the FITS files contain data with these values */ #define FLOATNULLVALUE -9.11912E-36F #define DOUBLENULLVALUE -9.1191291391491E-36 /* compression algorithm codes */ #define NO_DITHER -1 #define SUBTRACTIVE_DITHER_1 1 #define SUBTRACTIVE_DITHER_2 2 #define MAX_COMPRESS_DIM 6 #define RICE_1 11 #define GZIP_1 21 #define GZIP_2 22 #define PLIO_1 31 #define HCOMPRESS_1 41 #define BZIP2_1 51 /* not publicly supported; only for test purposes */ #define NOCOMPRESS -1 #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #define CASESEN 1 /* do case-sensitive string match */ #define CASEINSEN 0 /* do case-insensitive string match */ #define GT_ID_ALL_URI 0 /* hierarchical grouping parameters */ #define GT_ID_REF 1 #define GT_ID_POS 2 #define GT_ID_ALL 3 #define GT_ID_REF_URI 11 #define GT_ID_POS_URI 12 #define OPT_RM_GPT 0 #define OPT_RM_ENTRY 1 #define OPT_RM_MBR 2 #define OPT_RM_ALL 3 #define OPT_GCP_GPT 0 #define OPT_GCP_MBR 1 #define OPT_GCP_ALL 2 #define OPT_MCP_ADD 0 #define OPT_MCP_NADD 1 #define OPT_MCP_REPL 2 #define OPT_MCP_MOV 3 #define OPT_MRG_COPY 0 #define OPT_MRG_MOV 1 #define OPT_CMT_MBR 1 #define OPT_CMT_MBR_DEL 11 typedef struct /* structure used to store table column information */ { char ttype[70]; /* column name = FITS TTYPEn keyword; */ LONGLONG tbcol; /* offset in row to first byte of each column */ int tdatatype; /* datatype code of each column */ LONGLONG trepeat; /* repeat count of column; number of elements */ double tscale; /* FITS TSCALn linear scaling factor */ double tzero; /* FITS TZEROn linear scaling zero point */ LONGLONG tnull; /* FITS null value for int image or binary table cols */ char strnull[20]; /* FITS null value string for ASCII table columns */ char tform[10]; /* FITS tform keyword value */ long twidth; /* width of each ASCII table column */ }tcolumn; #define VALIDSTRUC 555 /* magic value used to identify if structure is valid */ typedef struct /* structure used to store basic FITS file information */ { int filehandle; /* handle returned by the file open function */ int driver; /* defines which set of I/O drivers should be used */ int open_count; /* number of opened 'fitsfiles' using this structure */ char *filename; /* file name */ int validcode; /* magic value used to verify that structure is valid */ int only_one; /* flag meaning only copy the specified extension */ int noextsyntax; /* flag for file opened with request to ignore extended syntax*/ LONGLONG filesize; /* current size of the physical disk file in bytes */ LONGLONG logfilesize; /* logical size of file, including unflushed buffers */ int lasthdu; /* is this the last HDU in the file? 0 = no, else yes */ LONGLONG bytepos; /* current logical I/O pointer position in file */ LONGLONG io_pos; /* current I/O pointer position in the physical file */ int curbuf; /* number of I/O buffer currently in use */ int curhdu; /* current HDU number; 0 = primary array */ int hdutype; /* 0 = primary array, 1 = ASCII table, 2 = binary table */ int writemode; /* 0 = readonly, 1 = readwrite */ int maxhdu; /* highest numbered HDU known to exist in the file */ int MAXHDU; /* dynamically allocated dimension of headstart array */ LONGLONG *headstart; /* byte offset in file to start of each HDU */ LONGLONG headend; /* byte offest in file to end of the current HDU header */ LONGLONG ENDpos; /* byte offest to where the END keyword was last written */ LONGLONG nextkey; /* byte offset in file to beginning of next keyword */ LONGLONG datastart; /* byte offset in file to start of the current data unit */ int imgdim; /* dimension of image; cached for fast access */ LONGLONG imgnaxis[99]; /* length of each axis; cached for fast access */ int tfield; /* number of fields in the table (primary array has 2 */ int startcol; /* used by ffgcnn to record starting column number */ LONGLONG origrows; /* original number of rows (value of NAXIS2 keyword) */ LONGLONG numrows; /* number of rows in the table (dynamically updated) */ LONGLONG rowlength; /* length of a table row or image size (bytes) */ tcolumn *tableptr; /* pointer to the table structure */ LONGLONG heapstart; /* heap start byte relative to start of data unit */ LONGLONG heapsize; /* size of the heap, in bytes */ /* the following elements are related to compressed images */ /* these record the 'requested' options to be used when the image is compressed */ int request_compress_type; /* requested image compression algorithm */ long request_tilesize[MAX_COMPRESS_DIM]; /* requested tiling size */ float request_quantize_level; /* requested quantize level */ int request_quantize_method ; /* requested quantizing method */ int request_dither_seed; /* starting offset into the array of random dithering */ int request_lossy_int_compress; /* lossy compress integer image as if float image? */ int request_huge_hdu; /* use '1Q' rather then '1P' variable length arrays */ float request_hcomp_scale; /* requested HCOMPRESS scale factor */ int request_hcomp_smooth; /* requested HCOMPRESS smooth parameter */ /* these record the actual options that were used when the image was compressed */ int compress_type; /* type of compression algorithm */ long tilesize[MAX_COMPRESS_DIM]; /* size of compression tiles */ float quantize_level; /* floating point quantization level */ int quantize_method; /* floating point pixel quantization algorithm */ int dither_seed; /* starting offset into the array of random dithering */ /* other compression parameters */ int compressimg; /* 1 if HDU contains a compressed image, else 0 */ char zcmptype[12]; /* compression type string */ int zbitpix; /* FITS data type of image (BITPIX) */ int zndim; /* dimension of image */ long znaxis[MAX_COMPRESS_DIM]; /* length of each axis */ long maxtilelen; /* max number of pixels in each image tile */ long maxelem; /* maximum byte length of tile compressed arrays */ int cn_compressed; /* column number for COMPRESSED_DATA column */ int cn_uncompressed; /* column number for UNCOMPRESSED_DATA column */ int cn_gzip_data; /* column number for GZIP2 lossless compressed data */ int cn_zscale; /* column number for ZSCALE column */ int cn_zzero; /* column number for ZZERO column */ int cn_zblank; /* column number for the ZBLANK column */ double zscale; /* scaling value, if same for all tiles */ double zzero; /* zero pt, if same for all tiles */ double cn_bscale; /* value of the BSCALE keyword in header */ double cn_bzero; /* value of the BZERO keyword (may be reset) */ double cn_actual_bzero; /* actual value of the BZERO keyword */ int zblank; /* value for null pixels, if not a column */ int rice_blocksize; /* first compression parameter: Rice pixels/block */ int rice_bytepix; /* 2nd compression parameter: Rice bytes/pixel */ float hcomp_scale; /* 1st hcompress compression parameter */ int hcomp_smooth; /* 2nd hcompress compression parameter */ int *tilerow; /* row number of the array of uncompressed tiledata */ long *tiledatasize; /* length of the array of tile data in bytes */ int *tiletype; /* datatype of the array of tile (TINT, TSHORT, etc) */ void **tiledata; /* array of uncompressed tile of data, for row *tilerow */ void **tilenullarray; /* array of optional array of null value flags */ int *tileanynull; /* anynulls in the array of tile? */ char *iobuffer; /* pointer to FITS file I/O buffers */ long bufrecnum[NIOBUF]; /* file record number of each of the buffers */ int dirty[NIOBUF]; /* has the corresponding buffer been modified? */ int ageindex[NIOBUF]; /* relative age of each buffer */ } FITSfile; typedef struct /* structure used to store basic HDU information */ { int HDUposition; /* HDU position in file; 0 = first HDU */ FITSfile *Fptr; /* pointer to FITS file structure */ }fitsfile; typedef struct /* structure for the iterator function column information */ { /* elements required as input to fits_iterate_data: */ fitsfile *fptr; /* pointer to the HDU containing the column */ int colnum; /* column number in the table (use name if < 1) */ char colname[70]; /* name (= TTYPEn value) of the column (optional) */ int datatype; /* output datatype (converted if necessary */ int iotype; /* = InputCol, InputOutputCol, or OutputCol */ /* output elements that may be useful for the work function: */ void *array; /* pointer to the array (and the null value) */ long repeat; /* binary table vector repeat value */ long tlmin; /* legal minimum data value */ long tlmax; /* legal maximum data value */ char tunit[70]; /* physical unit string */ char tdisp[70]; /* suggested display format */ } iteratorCol; #define InputCol 0 /* flag for input only iterator column */ #define InputOutputCol 1 /* flag for input and output iterator column */ #define OutputCol 2 /* flag for output only iterator column */ /*============================================================================= * * The following wtbarr typedef is used in the fits_read_wcstab() routine, * which is intended for use with the WCSLIB library written by Mark * Calabretta, http://www.atnf.csiro.au/~mcalabre/index.html * * In order to maintain WCSLIB and CFITSIO as independent libraries it * was not permissible for any CFITSIO library code to include WCSLIB * header files, or vice versa. However, the CFITSIO function * fits_read_wcstab() accepts an array of structs defined by wcs.h within * WCSLIB. The problem then was to define this struct within fitsio.h * without including wcs.h, especially noting that wcs.h will often (but * not always) be included together with fitsio.h in an applications * program that uses fits_read_wcstab(). * * Of the various possibilities, the solution adopted was for WCSLIB to * define "struct wtbarr" while fitsio.h defines "typedef wtbarr", a * untagged struct with identical members. This allows both wcs.h and * fitsio.h to define a wtbarr data type without conflict by virtue of * the fact that structure tags and typedef names share different * namespaces in C. Therefore, declarations within WCSLIB look like * * struct wtbarr *w; * * while within CFITSIO they are simply * * wtbarr *w; * * but as suggested by the commonality of the names, these are really the * same aggregate data type. However, in passing a (struct wtbarr *) to * fits_read_wcstab() a cast to (wtbarr *) is formally required. *===========================================================================*/ #ifndef WCSLIB_GETWCSTAB #define WCSLIB_GETWCSTAB typedef struct { int i; /* Image axis number. */ int m; /* Array axis number for index vectors. */ int kind; /* Array type, 'c' (coord) or 'i' (index). */ char extnam[72]; /* EXTNAME of binary table extension. */ int extver; /* EXTVER of binary table extension. */ int extlev; /* EXTLEV of binary table extension. */ char ttype[72]; /* TTYPEn of column containing the array. */ long row; /* Table row number. */ int ndim; /* Expected array dimensionality. */ int *dimlen; /* Where to write the array axis lengths. */ double **arrayp; /* Where to write the address of the array */ /* allocated to store the array. */ } wtbarr; /* The following exclusion if __CINT__ is defined is needed for ROOT */ #ifndef __CINT__ /* the following 3 lines are needed to support C++ compilers */ #ifdef __cplusplus extern "C" { #endif #endif int CFITS_API fits_read_wcstab(fitsfile *fptr, int nwtb, wtbarr *wtb, int *status); /* The following exclusion if __CINT__ is defined is needed for ROOT */ #ifndef __CINT__ #ifdef __cplusplus } #endif #endif #endif /* WCSLIB_GETWCSTAB */ /* error status codes */ #define CREATE_DISK_FILE -106 /* create disk file, without extended filename syntax */ #define OPEN_DISK_FILE -105 /* open disk file, without extended filename syntax */ #define SKIP_TABLE -104 /* move to 1st image when opening file */ #define SKIP_IMAGE -103 /* move to 1st table when opening file */ #define SKIP_NULL_PRIMARY -102 /* skip null primary array when opening file */ #define USE_MEM_BUFF -101 /* use memory buffer when opening file */ #define OVERFLOW_ERR -11 /* overflow during datatype conversion */ #define PREPEND_PRIMARY -9 /* used in ffiimg to insert new primary array */ #define SAME_FILE 101 /* input and output files are the same */ #define TOO_MANY_FILES 103 /* tried to open too many FITS files */ #define FILE_NOT_OPENED 104 /* could not open the named file */ #define FILE_NOT_CREATED 105 /* could not create the named file */ #define WRITE_ERROR 106 /* error writing to FITS file */ #define END_OF_FILE 107 /* tried to move past end of file */ #define READ_ERROR 108 /* error reading from FITS file */ #define FILE_NOT_CLOSED 110 /* could not close the file */ #define ARRAY_TOO_BIG 111 /* array dimensions exceed internal limit */ #define READONLY_FILE 112 /* Cannot write to readonly file */ #define MEMORY_ALLOCATION 113 /* Could not allocate memory */ #define BAD_FILEPTR 114 /* invalid fitsfile pointer */ #define NULL_INPUT_PTR 115 /* NULL input pointer to routine */ #define SEEK_ERROR 116 /* error seeking position in file */ #define BAD_NETTIMEOUT 117 /* bad value for file download timeout setting */ #define BAD_URL_PREFIX 121 /* invalid URL prefix on file name */ #define TOO_MANY_DRIVERS 122 /* tried to register too many IO drivers */ #define DRIVER_INIT_FAILED 123 /* driver initialization failed */ #define NO_MATCHING_DRIVER 124 /* matching driver is not registered */ #define URL_PARSE_ERROR 125 /* failed to parse input file URL */ #define RANGE_PARSE_ERROR 126 /* failed to parse input file URL */ #define SHARED_ERRBASE (150) #define SHARED_BADARG (SHARED_ERRBASE + 1) #define SHARED_NULPTR (SHARED_ERRBASE + 2) #define SHARED_TABFULL (SHARED_ERRBASE + 3) #define SHARED_NOTINIT (SHARED_ERRBASE + 4) #define SHARED_IPCERR (SHARED_ERRBASE + 5) #define SHARED_NOMEM (SHARED_ERRBASE + 6) #define SHARED_AGAIN (SHARED_ERRBASE + 7) #define SHARED_NOFILE (SHARED_ERRBASE + 8) #define SHARED_NORESIZE (SHARED_ERRBASE + 9) #define HEADER_NOT_EMPTY 201 /* header already contains keywords */ #define KEY_NO_EXIST 202 /* keyword not found in header */ #define KEY_OUT_BOUNDS 203 /* keyword record number is out of bounds */ #define VALUE_UNDEFINED 204 /* keyword value field is blank */ #define NO_QUOTE 205 /* string is missing the closing quote */ #define BAD_INDEX_KEY 206 /* illegal indexed keyword name */ #define BAD_KEYCHAR 207 /* illegal character in keyword name or card */ #define BAD_ORDER 208 /* required keywords out of order */ #define NOT_POS_INT 209 /* keyword value is not a positive integer */ #define NO_END 210 /* couldn't find END keyword */ #define BAD_BITPIX 211 /* illegal BITPIX keyword value*/ #define BAD_NAXIS 212 /* illegal NAXIS keyword value */ #define BAD_NAXES 213 /* illegal NAXISn keyword value */ #define BAD_PCOUNT 214 /* illegal PCOUNT keyword value */ #define BAD_GCOUNT 215 /* illegal GCOUNT keyword value */ #define BAD_TFIELDS 216 /* illegal TFIELDS keyword value */ #define NEG_WIDTH 217 /* negative table row size */ #define NEG_ROWS 218 /* negative number of rows in table */ #define COL_NOT_FOUND 219 /* column with this name not found in table */ #define BAD_SIMPLE 220 /* illegal value of SIMPLE keyword */ #define NO_SIMPLE 221 /* Primary array doesn't start with SIMPLE */ #define NO_BITPIX 222 /* Second keyword not BITPIX */ #define NO_NAXIS 223 /* Third keyword not NAXIS */ #define NO_NAXES 224 /* Couldn't find all the NAXISn keywords */ #define NO_XTENSION 225 /* HDU doesn't start with XTENSION keyword */ #define NOT_ATABLE 226 /* the CHDU is not an ASCII table extension */ #define NOT_BTABLE 227 /* the CHDU is not a binary table extension */ #define NO_PCOUNT 228 /* couldn't find PCOUNT keyword */ #define NO_GCOUNT 229 /* couldn't find GCOUNT keyword */ #define NO_TFIELDS 230 /* couldn't find TFIELDS keyword */ #define NO_TBCOL 231 /* couldn't find TBCOLn keyword */ #define NO_TFORM 232 /* couldn't find TFORMn keyword */ #define NOT_IMAGE 233 /* the CHDU is not an IMAGE extension */ #define BAD_TBCOL 234 /* TBCOLn keyword value < 0 or > rowlength */ #define NOT_TABLE 235 /* the CHDU is not a table */ #define COL_TOO_WIDE 236 /* column is too wide to fit in table */ #define COL_NOT_UNIQUE 237 /* more than 1 column name matches template */ #define BAD_ROW_WIDTH 241 /* sum of column widths not = NAXIS1 */ #define UNKNOWN_EXT 251 /* unrecognizable FITS extension type */ #define UNKNOWN_REC 252 /* unrecognizable FITS record */ #define END_JUNK 253 /* END keyword is not blank */ #define BAD_HEADER_FILL 254 /* Header fill area not blank */ #define BAD_DATA_FILL 255 /* Data fill area not blank or zero */ #define BAD_TFORM 261 /* illegal TFORM format code */ #define BAD_TFORM_DTYPE 262 /* unrecognizable TFORM datatype code */ #define BAD_TDIM 263 /* illegal TDIMn keyword value */ #define BAD_HEAP_PTR 264 /* invalid BINTABLE heap address */ #define BAD_HDU_NUM 301 /* HDU number < 1 or > MAXHDU */ #define BAD_COL_NUM 302 /* column number < 1 or > tfields */ #define NEG_FILE_POS 304 /* tried to move before beginning of file */ #define NEG_BYTES 306 /* tried to read or write negative bytes */ #define BAD_ROW_NUM 307 /* illegal starting row number in table */ #define BAD_ELEM_NUM 308 /* illegal starting element number in vector */ #define NOT_ASCII_COL 309 /* this is not an ASCII string column */ #define NOT_LOGICAL_COL 310 /* this is not a logical datatype column */ #define BAD_ATABLE_FORMAT 311 /* ASCII table column has wrong format */ #define BAD_BTABLE_FORMAT 312 /* Binary table column has wrong format */ #define NO_NULL 314 /* null value has not been defined */ #define NOT_VARI_LEN 317 /* this is not a variable length column */ #define BAD_DIMEN 320 /* illegal number of dimensions in array */ #define BAD_PIX_NUM 321 /* first pixel number greater than last pixel */ #define ZERO_SCALE 322 /* illegal BSCALE or TSCALn keyword = 0 */ #define NEG_AXIS 323 /* illegal axis length < 1 */ #define NOT_GROUP_TABLE 340 #define HDU_ALREADY_MEMBER 341 #define MEMBER_NOT_FOUND 342 #define GROUP_NOT_FOUND 343 #define BAD_GROUP_ID 344 #define TOO_MANY_HDUS_TRACKED 345 #define HDU_ALREADY_TRACKED 346 #define BAD_OPTION 347 #define IDENTICAL_POINTERS 348 #define BAD_GROUP_ATTACH 349 #define BAD_GROUP_DETACH 350 #define BAD_I2C 401 /* bad int to formatted string conversion */ #define BAD_F2C 402 /* bad float to formatted string conversion */ #define BAD_INTKEY 403 /* can't interprete keyword value as integer */ #define BAD_LOGICALKEY 404 /* can't interprete keyword value as logical */ #define BAD_FLOATKEY 405 /* can't interprete keyword value as float */ #define BAD_DOUBLEKEY 406 /* can't interprete keyword value as double */ #define BAD_C2I 407 /* bad formatted string to int conversion */ #define BAD_C2F 408 /* bad formatted string to float conversion */ #define BAD_C2D 409 /* bad formatted string to double conversion */ #define BAD_DATATYPE 410 /* bad keyword datatype code */ #define BAD_DECIM 411 /* bad number of decimal places specified */ #define NUM_OVERFLOW 412 /* overflow during datatype conversion */ # define DATA_COMPRESSION_ERR 413 /* error in imcompress routines */ # define DATA_DECOMPRESSION_ERR 414 /* error in imcompress routines */ # define NO_COMPRESSED_TILE 415 /* compressed tile doesn't exist */ #define BAD_DATE 420 /* error in date or time conversion */ #define PARSE_SYNTAX_ERR 431 /* syntax error in parser expression */ #define PARSE_BAD_TYPE 432 /* expression did not evaluate to desired type */ #define PARSE_LRG_VECTOR 433 /* vector result too large to return in array */ #define PARSE_NO_OUTPUT 434 /* data parser failed not sent an out column */ #define PARSE_BAD_COL 435 /* bad data encounter while parsing column */ #define PARSE_BAD_OUTPUT 436 /* Output file not of proper type */ #define ANGLE_TOO_BIG 501 /* celestial angle too large for projection */ #define BAD_WCS_VAL 502 /* bad celestial coordinate or pixel value */ #define WCS_ERROR 503 /* error in celestial coordinate calculation */ #define BAD_WCS_PROJ 504 /* unsupported type of celestial projection */ #define NO_WCS_KEY 505 /* celestial coordinate keywords not found */ #define APPROX_WCS_KEY 506 /* approximate WCS keywords were calculated */ #define NO_CLOSE_ERROR 999 /* special value used internally to switch off */ /* the error message from ffclos and ffchdu */ /*------- following error codes are used in the grparser.c file -----------*/ #define NGP_ERRBASE (360) /* base chosen so not to interfere with CFITSIO */ #define NGP_OK (0) #define NGP_NO_MEMORY (NGP_ERRBASE + 0) /* malloc failed */ #define NGP_READ_ERR (NGP_ERRBASE + 1) /* read error from file */ #define NGP_NUL_PTR (NGP_ERRBASE + 2) /* null pointer passed as argument */ #define NGP_EMPTY_CURLINE (NGP_ERRBASE + 3) /* line read seems to be empty */ #define NGP_UNREAD_QUEUE_FULL (NGP_ERRBASE + 4) /* cannot unread more then 1 line (or single line twice) */ #define NGP_INC_NESTING (NGP_ERRBASE + 5) /* too deep include file nesting (inf. loop ?) */ #define NGP_ERR_FOPEN (NGP_ERRBASE + 6) /* fopen() failed, cannot open file */ #define NGP_EOF (NGP_ERRBASE + 7) /* end of file encountered */ #define NGP_BAD_ARG (NGP_ERRBASE + 8) /* bad arguments passed */ #define NGP_TOKEN_NOT_EXPECT (NGP_ERRBASE + 9) /* token not expected here */ /* The following exclusion if __CINT__ is defined is needed for ROOT */ #ifndef __CINT__ /* the following 3 lines are needed to support C++ compilers */ #ifdef __cplusplus extern "C" { #endif #endif int CFITS2Unit( fitsfile *fptr ); CFITS_API fitsfile* CUnit2FITS(int unit); /*---------------- FITS file URL parsing routines -------------*/ int CFITS_API fits_get_token (char **ptr, char *delimiter, char *token, int *isanumber); int CFITS_API fits_get_token2(char **ptr, char *delimiter, char **token, int *isanumber, int *status); char CFITS_API *fits_split_names(char *list); int CFITS_API ffiurl( char *url, char *urltype, char *infile, char *outfile, char *extspec, char *rowfilter, char *binspec, char *colspec, int *status); int CFITS_API ffifile (char *url, char *urltype, char *infile, char *outfile, char *extspec, char *rowfilter, char *binspec, char *colspec, char *pixfilter, int *status); int CFITS_API ffifile2 (char *url, char *urltype, char *infile, char *outfile, char *extspec, char *rowfilter, char *binspec, char *colspec, char *pixfilter, char *compspec, int *status); int CFITS_API ffrtnm(char *url, char *rootname, int *status); int CFITS_API ffexist(const char *infile, int *exists, int *status); int CFITS_API ffexts(char *extspec, int *extnum, char *extname, int *extvers, int *hdutype, char *colname, char *rowexpress, int *status); int CFITS_API ffextn(char *url, int *extension_num, int *status); int CFITS_API ffurlt(fitsfile *fptr, char *urlType, int *status); int CFITS_API ffbins(char *binspec, int *imagetype, int *haxis, char colname[4][FLEN_VALUE], double *minin, double *maxin, double *binsizein, char minname[4][FLEN_VALUE], char maxname[4][FLEN_VALUE], char binname[4][FLEN_VALUE], double *weight, char *wtname, int *recip, int *status); int CFITS_API ffbinr(char **binspec, char *colname, double *minin, double *maxin, double *binsizein, char *minname, char *maxname, char *binname, int *status); int CFITS_API fits_copy_cell2image(fitsfile *fptr, fitsfile *newptr, char *colname, long rownum, int *status); int CFITS_API fits_copy_image2cell(fitsfile *fptr, fitsfile *newptr, char *colname, long rownum, int copykeyflag, int *status); int CFITS_API fits_copy_pixlist2image(fitsfile *infptr, fitsfile *outfptr, int firstkey, /* I - first HDU record number to start with */ int naxis, int *colnum, int *status); int CFITS_API ffimport_file( char *filename, char **contents, int *status ); int CFITS_API ffrwrg( char *rowlist, LONGLONG maxrows, int maxranges, int *numranges, long *minrow, long *maxrow, int *status); int CFITS_API ffrwrgll( char *rowlist, LONGLONG maxrows, int maxranges, int *numranges, LONGLONG *minrow, LONGLONG *maxrow, int *status); /*---------------- FITS file I/O routines -------------*/ int CFITS_API fits_init_cfitsio(void); int CFITS_API ffomem(fitsfile **fptr, const char *name, int mode, void **buffptr, size_t *buffsize, size_t deltasize, void *(*mem_realloc)(void *p, size_t newsize), int *status); int CFITS_API ffopen(fitsfile **fptr, const char *filename, int iomode, int *status); int CFITS_API ffopentest(int soname, fitsfile **fptr, const char *filename, int iomode, int *status); int CFITS_API ffdopn(fitsfile **fptr, const char *filename, int iomode, int *status); int CFITS_API ffeopn(fitsfile **fptr, const char *filename, int iomode, char *extlist, int *hdutype, int *status); int CFITS_API fftopn(fitsfile **fptr, const char *filename, int iomode, int *status); int CFITS_API ffiopn(fitsfile **fptr, const char *filename, int iomode, int *status); int CFITS_API ffdkopn(fitsfile **fptr, const char *filename, int iomode, int *status); int CFITS_API ffreopen(fitsfile *openfptr, fitsfile **newfptr, int *status); int CFITS_API ffinit( fitsfile **fptr, const char *filename, int *status); int CFITS_API ffdkinit(fitsfile **fptr, const char *filename, int *status); int CFITS_API ffimem(fitsfile **fptr, void **buffptr, size_t *buffsize, size_t deltasize, void *(*mem_realloc)(void *p, size_t newsize), int *status); int CFITS_API fftplt(fitsfile **fptr, const char *filename, const char *tempname, int *status); int CFITS_API ffflus(fitsfile *fptr, int *status); int CFITS_API ffflsh(fitsfile *fptr, int clearbuf, int *status); int CFITS_API ffclos(fitsfile *fptr, int *status); int CFITS_API ffdelt(fitsfile *fptr, int *status); int CFITS_API ffflnm(fitsfile *fptr, char *filename, int *status); int CFITS_API ffflmd(fitsfile *fptr, int *filemode, int *status); int CFITS_API fits_delete_iraf_file(const char *filename, int *status); /*---------------- utility routines -------------*/ float CFITS_API ffvers(float *version); void CFITS_API ffupch(char *string); void CFITS_API ffgerr(int status, char *errtext); void CFITS_API ffpmsg(const char *err_message); void CFITS_API ffpmrk(void); int CFITS_API ffgmsg(char *err_message); void CFITS_API ffcmsg(void); void CFITS_API ffcmrk(void); void CFITS_API ffrprt(FILE *stream, int status); void CFITS_API ffcmps(char *templt, char *colname, int casesen, int *match, int *exact); int CFITS_API fftkey(const char *keyword, int *status); int CFITS_API fftrec(char *card, int *status); int CFITS_API ffnchk(fitsfile *fptr, int *status); int CFITS_API ffkeyn(const char *keyroot, int value, char *keyname, int *status); int CFITS_API ffnkey(int value, const char *keyroot, char *keyname, int *status); int CFITS_API ffgkcl(char *card); int CFITS_API ffdtyp(const char *cval, char *dtype, int *status); int CFITS_API ffinttyp(char *cval, int *datatype, int *negative, int *status); int CFITS_API ffpsvc(char *card, char *value, char *comm, int *status); int CFITS_API ffgknm(char *card, char *name, int *length, int *status); int CFITS_API ffgthd(char *tmplt, char *card, int *hdtype, int *status); int CFITS_API ffmkky(const char *keyname, char *keyval, const char *comm, char *card, int *status); int CFITS_API fits_translate_keyword(char *inrec, char *outrec, char *patterns[][2], int npat, int n_value, int n_offset, int n_range, int *pat_num, int *i, int *j, int *m, int *n, int *status); int CFITS_API fits_translate_keywords(fitsfile *infptr, fitsfile *outfptr, int firstkey, char *patterns[][2], int npat, int n_value, int n_offset, int n_range, int *status); int CFITS_API ffasfm(char *tform, int *datacode, long *width, int *decim, int *status); int CFITS_API ffbnfm(char *tform, int *datacode, long *repeat, long *width, int *status); int CFITS_API ffbnfmll(char *tform, int *datacode, LONGLONG *repeat, long *width, int *status); int CFITS_API ffgabc(int tfields, char **tform, int space, long *rowlen, long *tbcol, int *status); int CFITS_API fits_get_section_range(char **ptr,long *secmin,long *secmax,long *incre, int *status); /* ffmbyt should not normally be used in application programs, but it is defined here as a publicly available routine because there are a few rare cases where it is needed */ int CFITS_API ffmbyt(fitsfile *fptr, LONGLONG bytpos, int ignore_err, int *status); /*----------------- write single keywords --------------*/ int CFITS_API ffpky(fitsfile *fptr, int datatype, const char *keyname, void *value, const char *comm, int *status); int CFITS_API ffprec(fitsfile *fptr, const char *card, int *status); int CFITS_API ffpcom(fitsfile *fptr, const char *comm, int *status); int CFITS_API ffpunt(fitsfile *fptr, const char *keyname, const char *unit, int *status); int CFITS_API ffphis(fitsfile *fptr, const char *history, int *status); int CFITS_API ffpdat(fitsfile *fptr, int *status); int CFITS_API ffverifydate(int year, int month, int day, int *status); int CFITS_API ffgstm(char *timestr, int *timeref, int *status); int CFITS_API ffgsdt(int *day, int *month, int *year, int *status); int CFITS_API ffdt2s(int year, int month, int day, char *datestr, int *status); int CFITS_API fftm2s(int year, int month, int day, int hour, int minute, double second, int decimals, char *datestr, int *status); int CFITS_API ffs2dt(char *datestr, int *year, int *month, int *day, int *status); int CFITS_API ffs2tm(char *datestr, int *year, int *month, int *day, int *hour, int *minute, double *second, int *status); int CFITS_API ffpkyu(fitsfile *fptr, const char *keyname, const char *comm, int *status); int CFITS_API ffpkys(fitsfile *fptr, const char *keyname, const char *value, const char *comm,int *status); int CFITS_API ffpkls(fitsfile *fptr, const char *keyname, const char *value, const char *comm,int *status); int CFITS_API ffplsw(fitsfile *fptr, int *status); int CFITS_API ffpkyl(fitsfile *fptr, const char *keyname, int value, const char *comm, int *status); int CFITS_API ffpkyj(fitsfile *fptr, const char *keyname, LONGLONG value, const char *comm, int *status); int CFITS_API ffpkyuj(fitsfile *fptr, const char *keyname, ULONGLONG value, const char *comm, int *status); int CFITS_API ffpkyf(fitsfile *fptr, const char *keyname, float value, int decim, const char *comm, int *status); int CFITS_API ffpkye(fitsfile *fptr, const char *keyname, float value, int decim, const char *comm, int *status); int CFITS_API ffpkyg(fitsfile *fptr, const char *keyname, double value, int decim, const char *comm, int *status); int CFITS_API ffpkyd(fitsfile *fptr, const char *keyname, double value, int decim, const char *comm, int *status); int CFITS_API ffpkyc(fitsfile *fptr, const char *keyname, float *value, int decim, const char *comm, int *status); int CFITS_API ffpkym(fitsfile *fptr, const char *keyname, double *value, int decim, const char *comm, int *status); int CFITS_API ffpkfc(fitsfile *fptr, const char *keyname, float *value, int decim, const char *comm, int *status); int CFITS_API ffpkfm(fitsfile *fptr, const char *keyname, double *value, int decim, const char *comm, int *status); int CFITS_API ffpkyt(fitsfile *fptr, const char *keyname, long intval, double frac, const char *comm, int *status); int CFITS_API ffptdm( fitsfile *fptr, int colnum, int naxis, long naxes[], int *status); int CFITS_API ffptdmll( fitsfile *fptr, int colnum, int naxis, LONGLONG naxes[], int *status); /*----------------- write array of keywords --------------*/ int CFITS_API ffpkns(fitsfile *fptr, const char *keyroot, int nstart, int nkey, char *value[], char *comm[], int *status); int CFITS_API ffpknl(fitsfile *fptr, const char *keyroot, int nstart, int nkey, int *value, char *comm[], int *status); int CFITS_API ffpknj(fitsfile *fptr, const char *keyroot, int nstart, int nkey, long *value, char *comm[], int *status); int CFITS_API ffpknjj(fitsfile *fptr, const char *keyroot, int nstart, int nkey, LONGLONG *value, char *comm[], int *status); int CFITS_API ffpknf(fitsfile *fptr, const char *keyroot, int nstart, int nkey, float *value, int decim, char *comm[], int *status); int CFITS_API ffpkne(fitsfile *fptr, const char *keyroot, int nstart, int nkey, float *value, int decim, char *comm[], int *status); int CFITS_API ffpkng(fitsfile *fptr, const char *keyroot, int nstart, int nkey, double *value, int decim, char *comm[], int *status); int CFITS_API ffpknd(fitsfile *fptr, const char *keyroot, int nstart, int nkey, double *value, int decim, char *comm[], int *status); int CFITS_API ffcpky(fitsfile *infptr,fitsfile *outfptr,int incol,int outcol, char *rootname, int *status); /*----------------- write required header keywords --------------*/ int CFITS_API ffphps( fitsfile *fptr, int bitpix, int naxis, long naxes[], int *status); int CFITS_API ffphpsll( fitsfile *fptr, int bitpix, int naxis, LONGLONG naxes[], int *status); int CFITS_API ffphpr( fitsfile *fptr, int simple, int bitpix, int naxis, long naxes[], LONGLONG pcount, LONGLONG gcount, int extend, int *status); int CFITS_API ffphprll( fitsfile *fptr, int simple, int bitpix, int naxis, LONGLONG naxes[], LONGLONG pcount, LONGLONG gcount, int extend, int *status); int CFITS_API ffphtb(fitsfile *fptr, LONGLONG naxis1, LONGLONG naxis2, int tfields, char **ttype, long *tbcol, char **tform, char **tunit, const char *extname, int *status); int CFITS_API ffphbn(fitsfile *fptr, LONGLONG naxis2, int tfields, char **ttype, char **tform, char **tunit, const char *extname, LONGLONG pcount, int *status); int CFITS_API ffphext( fitsfile *fptr, const char *xtension, int bitpix, int naxis, long naxes[], LONGLONG pcount, LONGLONG gcount, int *status); /*----------------- write template keywords --------------*/ int CFITS_API ffpktp(fitsfile *fptr, const char *filename, int *status); /*------------------ get header information --------------*/ int CFITS_API ffghsp(fitsfile *fptr, int *nexist, int *nmore, int *status); int CFITS_API ffghps(fitsfile *fptr, int *nexist, int *position, int *status); /*------------------ move position in header -------------*/ int CFITS_API ffmaky(fitsfile *fptr, int nrec, int *status); int CFITS_API ffmrky(fitsfile *fptr, int nrec, int *status); /*------------------ read single keywords -----------------*/ int CFITS_API ffgnxk(fitsfile *fptr, char **inclist, int ninc, char **exclist, int nexc, char *card, int *status); int CFITS_API ffgrec(fitsfile *fptr, int nrec, char *card, int *status); int CFITS_API ffgcrd(fitsfile *fptr, const char *keyname, char *card, int *status); int CFITS_API ffgstr(fitsfile *fptr, const char *string, char *card, int *status); int CFITS_API ffgunt(fitsfile *fptr, const char *keyname, char *unit, int *status); int CFITS_API ffgkyn(fitsfile *fptr, int nkey, char *keyname, char *keyval, char *comm, int *status); int CFITS_API ffgkey(fitsfile *fptr, const char *keyname, char *keyval, char *comm, int *status); int CFITS_API ffgky( fitsfile *fptr, int datatype, const char *keyname, void *value, char *comm, int *status); int CFITS_API ffgkys(fitsfile *fptr, const char *keyname, char *value, char *comm, int *status); int CFITS_API ffgksl(fitsfile *fptr, const char *keyname, int *length, int *status); int CFITS_API ffgkls(fitsfile *fptr, const char *keyname, char **value, char *comm, int *status); int CFITS_API ffgsky(fitsfile *fptr, const char *keyname, int firstchar, int maxchar, char *value, int *valuelen, char *comm, int *status); int CFITS_API fffree(void *value, int *status); int CFITS_API fffkls(char *value, int *status); int CFITS_API ffgkyl(fitsfile *fptr, const char *keyname, int *value, char *comm, int *status); int CFITS_API ffgkyj(fitsfile *fptr, const char *keyname, long *value, char *comm, int *status); int CFITS_API ffgkyjj(fitsfile *fptr, const char *keyname, LONGLONG *value, char *comm, int *status); int CFITS_API ffgkyujj(fitsfile *fptr, const char *keyname, ULONGLONG *value, char *comm, int *status); int CFITS_API ffgkye(fitsfile *fptr, const char *keyname, float *value, char *comm,int *status); int CFITS_API ffgkyd(fitsfile *fptr, const char *keyname, double *value,char *comm,int *status); int CFITS_API ffgkyc(fitsfile *fptr, const char *keyname, float *value, char *comm,int *status); int CFITS_API ffgkym(fitsfile *fptr, const char *keyname, double *value,char *comm,int *status); int CFITS_API ffgkyt(fitsfile *fptr, const char *keyname, long *ivalue, double *dvalue, char *comm, int *status); int CFITS_API ffgtdm(fitsfile *fptr, int colnum, int maxdim, int *naxis, long naxes[], int *status); int CFITS_API ffgtdmll(fitsfile *fptr, int colnum, int maxdim, int *naxis, LONGLONG naxes[], int *status); int CFITS_API ffdtdm(fitsfile *fptr, char *tdimstr, int colnum, int maxdim, int *naxis, long naxes[], int *status); int CFITS_API ffdtdmll(fitsfile *fptr, char *tdimstr, int colnum, int maxdim, int *naxis, LONGLONG naxes[], int *status); /*------------------ read array of keywords -----------------*/ int CFITS_API ffgkns(fitsfile *fptr, const char *keyname, int nstart, int nmax, char *value[], int *nfound, int *status); int CFITS_API ffgknl(fitsfile *fptr, const char *keyname, int nstart, int nmax, int *value, int *nfound, int *status); int CFITS_API ffgknj(fitsfile *fptr, const char *keyname, int nstart, int nmax, long *value, int *nfound, int *status); int CFITS_API ffgknjj(fitsfile *fptr, const char *keyname, int nstart, int nmax, LONGLONG *value, int *nfound, int *status); int CFITS_API ffgkne(fitsfile *fptr, const char *keyname, int nstart, int nmax, float *value, int *nfound, int *status); int CFITS_API ffgknd(fitsfile *fptr, const char *keyname, int nstart, int nmax, double *value, int *nfound, int *status); int CFITS_API ffh2st(fitsfile *fptr, char **header, int *status); int CFITS_API ffhdr2str( fitsfile *fptr, int exclude_comm, char **exclist, int nexc, char **header, int *nkeys, int *status); int CFITS_API ffcnvthdr2str( fitsfile *fptr, int exclude_comm, char **exclist, int nexc, char **header, int *nkeys, int *status); /*----------------- read required header keywords --------------*/ int CFITS_API ffghpr(fitsfile *fptr, int maxdim, int *simple, int *bitpix, int *naxis, long naxes[], long *pcount, long *gcount, int *extend, int *status); int CFITS_API ffghprll(fitsfile *fptr, int maxdim, int *simple, int *bitpix, int *naxis, LONGLONG naxes[], long *pcount, long *gcount, int *extend, int *status); int CFITS_API ffghtb(fitsfile *fptr,int maxfield, long *naxis1, long *naxis2, int *tfields, char **ttype, long *tbcol, char **tform, char **tunit, char *extname, int *status); int CFITS_API ffghtbll(fitsfile *fptr,int maxfield, LONGLONG *naxis1, LONGLONG *naxis2, int *tfields, char **ttype, LONGLONG *tbcol, char **tform, char **tunit, char *extname, int *status); int CFITS_API ffghbn(fitsfile *fptr, int maxfield, long *naxis2, int *tfields, char **ttype, char **tform, char **tunit, char *extname, long *pcount, int *status); int CFITS_API ffghbnll(fitsfile *fptr, int maxfield, LONGLONG *naxis2, int *tfields, char **ttype, char **tform, char **tunit, char *extname, LONGLONG *pcount, int *status); /*--------------------- update keywords ---------------*/ int CFITS_API ffuky(fitsfile *fptr, int datatype, const char *keyname, void *value, const char *comm, int *status); int CFITS_API ffucrd(fitsfile *fptr, const char *keyname, const char *card, int *status); int CFITS_API ffukyu(fitsfile *fptr, const char *keyname, const char *comm, int *status); int CFITS_API ffukys(fitsfile *fptr, const char *keyname, const char *value, const char *comm, int *status); int CFITS_API ffukls(fitsfile *fptr, const char *keyname, const char *value, const char *comm, int *status); int CFITS_API ffukyl(fitsfile *fptr, const char *keyname, int value, const char *comm, int *status); int CFITS_API ffukyj(fitsfile *fptr, const char *keyname, LONGLONG value, const char *comm, int *status); int CFITS_API ffukyf(fitsfile *fptr, const char *keyname, float value, int decim, const char *comm, int *status); int CFITS_API ffukye(fitsfile *fptr, const char *keyname, float value, int decim, const char *comm, int *status); int CFITS_API ffukyg(fitsfile *fptr, const char *keyname, double value, int decim, const char *comm, int *status); int CFITS_API ffukyd(fitsfile *fptr, const char *keyname, double value, int decim, const char *comm, int *status); int CFITS_API ffukyc(fitsfile *fptr, const char *keyname, float *value, int decim, const char *comm, int *status); int CFITS_API ffukym(fitsfile *fptr, const char *keyname, double *value, int decim, const char *comm, int *status); int CFITS_API ffukfc(fitsfile *fptr, const char *keyname, float *value, int decim, const char *comm, int *status); int CFITS_API ffukfm(fitsfile *fptr, const char *keyname, double *value, int decim, const char *comm, int *status); /*--------------------- modify keywords ---------------*/ int CFITS_API ffmrec(fitsfile *fptr, int nkey, const char *card, int *status); int CFITS_API ffmcrd(fitsfile *fptr, const char *keyname, const char *card, int *status); int CFITS_API ffmnam(fitsfile *fptr, const char *oldname, const char *newname, int *status); int CFITS_API ffmcom(fitsfile *fptr, const char *keyname, const char *comm, int *status); int CFITS_API ffmkyu(fitsfile *fptr, const char *keyname, const char *comm, int *status); int CFITS_API ffmkys(fitsfile *fptr, const char *keyname, const char *value, const char *comm,int *status); int CFITS_API ffmkls(fitsfile *fptr, const char *keyname, const char *value, const char *comm,int *status); int CFITS_API ffmkyl(fitsfile *fptr, const char *keyname, int value, const char *comm, int *status); int CFITS_API ffmkyj(fitsfile *fptr, const char *keyname, LONGLONG value, const char *comm, int *status); int CFITS_API ffmkyf(fitsfile *fptr, const char *keyname, float value, int decim, const char *comm, int *status); int CFITS_API ffmkye(fitsfile *fptr, const char *keyname, float value, int decim, const char *comm, int *status); int CFITS_API ffmkyg(fitsfile *fptr, const char *keyname, double value, int decim, const char *comm, int *status); int CFITS_API ffmkyd(fitsfile *fptr, const char *keyname, double value, int decim, const char *comm, int *status); int CFITS_API ffmkyc(fitsfile *fptr, const char *keyname, float *value, int decim, const char *comm, int *status); int CFITS_API ffmkym(fitsfile *fptr, const char *keyname, double *value, int decim, const char *comm, int *status); int CFITS_API ffmkfc(fitsfile *fptr, const char *keyname, float *value, int decim, const char *comm, int *status); int CFITS_API ffmkfm(fitsfile *fptr, const char *keyname, double *value, int decim, const char *comm, int *status); /*--------------------- insert keywords ---------------*/ int CFITS_API ffirec(fitsfile *fptr, int nkey, const char *card, int *status); int CFITS_API ffikey(fitsfile *fptr, const char *card, int *status); int CFITS_API ffikyu(fitsfile *fptr, const char *keyname, const char *comm, int *status); int CFITS_API ffikys(fitsfile *fptr, const char *keyname, const char *value, const char *comm,int *status); int CFITS_API ffikls(fitsfile *fptr, const char *keyname, const char *value, const char *comm,int *status); int CFITS_API ffikyl(fitsfile *fptr, const char *keyname, int value, const char *comm, int *status); int CFITS_API ffikyj(fitsfile *fptr, const char *keyname, LONGLONG value, const char *comm, int *status); int CFITS_API ffikyf(fitsfile *fptr, const char *keyname, float value, int decim, const char *comm, int *status); int CFITS_API ffikye(fitsfile *fptr, const char *keyname, float value, int decim, const char *comm, int *status); int CFITS_API ffikyg(fitsfile *fptr, const char *keyname, double value, int decim, const char *comm, int *status); int CFITS_API ffikyd(fitsfile *fptr, const char *keyname, double value, int decim, const char *comm, int *status); int CFITS_API ffikyc(fitsfile *fptr, const char *keyname, float *value, int decim, const char *comm, int *status); int CFITS_API ffikym(fitsfile *fptr, const char *keyname, double *value, int decim, const char *comm, int *status); int CFITS_API ffikfc(fitsfile *fptr, const char *keyname, float *value, int decim, const char *comm, int *status); int CFITS_API ffikfm(fitsfile *fptr, const char *keyname, double *value, int decim, const char *comm, int *status); /*--------------------- delete keywords ---------------*/ int CFITS_API ffdkey(fitsfile *fptr, const char *keyname, int *status); int CFITS_API ffdstr(fitsfile *fptr, const char *string, int *status); int CFITS_API ffdrec(fitsfile *fptr, int keypos, int *status); /*--------------------- get HDU information -------------*/ int CFITS_API ffghdn(fitsfile *fptr, int *chdunum); int CFITS_API ffghdt(fitsfile *fptr, int *exttype, int *status); int CFITS_API ffghad(fitsfile *fptr, long *headstart, long *datastart, long *dataend, int *status); int CFITS_API ffghadll(fitsfile *fptr, LONGLONG *headstart, LONGLONG *datastart, LONGLONG *dataend, int *status); int CFITS_API ffghof(fitsfile *fptr, OFF_T *headstart, OFF_T *datastart, OFF_T *dataend, int *status); int CFITS_API ffgipr(fitsfile *fptr, int maxaxis, int *imgtype, int *naxis, long *naxes, int *status); int CFITS_API ffgiprll(fitsfile *fptr, int maxaxis, int *imgtype, int *naxis, LONGLONG *naxes, int *status); int CFITS_API ffgidt(fitsfile *fptr, int *imgtype, int *status); int CFITS_API ffgiet(fitsfile *fptr, int *imgtype, int *status); int CFITS_API ffgidm(fitsfile *fptr, int *naxis, int *status); int CFITS_API ffgisz(fitsfile *fptr, int nlen, long *naxes, int *status); int CFITS_API ffgiszll(fitsfile *fptr, int nlen, LONGLONG *naxes, int *status); /*--------------------- HDU operations -------------*/ int CFITS_API ffmahd(fitsfile *fptr, int hdunum, int *exttype, int *status); int CFITS_API ffmrhd(fitsfile *fptr, int hdumov, int *exttype, int *status); int CFITS_API ffmnhd(fitsfile *fptr, int exttype, char *hduname, int hduvers, int *status); int CFITS_API ffthdu(fitsfile *fptr, int *nhdu, int *status); int CFITS_API ffcrhd(fitsfile *fptr, int *status); int CFITS_API ffcrim(fitsfile *fptr, int bitpix, int naxis, long *naxes, int *status); int CFITS_API ffcrimll(fitsfile *fptr, int bitpix, int naxis, LONGLONG *naxes, int *status); int CFITS_API ffcrtb(fitsfile *fptr, int tbltype, LONGLONG naxis2, int tfields, char **ttype, char **tform, char **tunit, const char *extname, int *status); int CFITS_API ffiimg(fitsfile *fptr, int bitpix, int naxis, long *naxes, int *status); int CFITS_API ffiimgll(fitsfile *fptr, int bitpix, int naxis, LONGLONG *naxes, int *status); int CFITS_API ffitab(fitsfile *fptr, LONGLONG naxis1, LONGLONG naxis2, int tfields, char **ttype, long *tbcol, char **tform, char **tunit, const char *extname, int *status); int CFITS_API ffibin(fitsfile *fptr, LONGLONG naxis2, int tfields, char **ttype, char **tform, char **tunit, const char *extname, LONGLONG pcount, int *status); int CFITS_API ffrsim(fitsfile *fptr, int bitpix, int naxis, long *naxes, int *status); int CFITS_API ffrsimll(fitsfile *fptr, int bitpix, int naxis, LONGLONG *naxes, int *status); int CFITS_API ffdhdu(fitsfile *fptr, int *hdutype, int *status); int CFITS_API ffcopy(fitsfile *infptr, fitsfile *outfptr, int morekeys, int *status); int CFITS_API ffcpfl(fitsfile *infptr, fitsfile *outfptr, int prev, int cur, int follow, int *status); int CFITS_API ffcphd(fitsfile *infptr, fitsfile *outfptr, int *status); int CFITS_API ffcpdt(fitsfile *infptr, fitsfile *outfptr, int *status); int CFITS_API ffchfl(fitsfile *fptr, int *status); int CFITS_API ffcdfl(fitsfile *fptr, int *status); int CFITS_API ffwrhdu(fitsfile *fptr, FILE *outstream, int *status); int CFITS_API ffrdef(fitsfile *fptr, int *status); int CFITS_API ffrhdu(fitsfile *fptr, int *hdutype, int *status); int CFITS_API ffhdef(fitsfile *fptr, int morekeys, int *status); int CFITS_API ffpthp(fitsfile *fptr, long theap, int *status); int CFITS_API ffcsum(fitsfile *fptr, long nrec, unsigned long *sum, int *status); void CFITS_API ffesum(unsigned long sum, int complm, char *ascii); unsigned long CFITS_API ffdsum(char *ascii, int complm, unsigned long *sum); int CFITS_API ffpcks(fitsfile *fptr, int *status); int CFITS_API ffupck(fitsfile *fptr, int *status); int CFITS_API ffvcks(fitsfile *fptr, int *datastatus, int *hdustatus, int *status); int CFITS_API ffgcks(fitsfile *fptr, unsigned long *datasum, unsigned long *hdusum, int *status); /*--------------------- define scaling or null values -------------*/ int CFITS_API ffpscl(fitsfile *fptr, double scale, double zeroval, int *status); int CFITS_API ffpnul(fitsfile *fptr, LONGLONG nulvalue, int *status); int CFITS_API fftscl(fitsfile *fptr, int colnum, double scale, double zeroval, int *status); int CFITS_API fftnul(fitsfile *fptr, int colnum, LONGLONG nulvalue, int *status); int CFITS_API ffsnul(fitsfile *fptr, int colnum, char *nulstring, int *status); /*--------------------- get column information -------------*/ int CFITS_API ffgcno(fitsfile *fptr, int casesen, char *templt, int *colnum, int *status); int CFITS_API ffgcnn(fitsfile *fptr, int casesen, char *templt, char *colname, int *colnum, int *status); int CFITS_API ffgtcl(fitsfile *fptr, int colnum, int *typecode, long *repeat, long *width, int *status); int CFITS_API ffgtclll(fitsfile *fptr, int colnum, int *typecode, LONGLONG *repeat, LONGLONG *width, int *status); int CFITS_API ffeqty(fitsfile *fptr, int colnum, int *typecode, long *repeat, long *width, int *status); int CFITS_API ffeqtyll(fitsfile *fptr, int colnum, int *typecode, LONGLONG *repeat, LONGLONG *width, int *status); int CFITS_API ffgncl(fitsfile *fptr, int *ncols, int *status); int CFITS_API ffgnrw(fitsfile *fptr, long *nrows, int *status); int CFITS_API ffgnrwll(fitsfile *fptr, LONGLONG *nrows, int *status); int CFITS_API ffgacl(fitsfile *fptr, int colnum, char *ttype, long *tbcol, char *tunit, char *tform, double *tscal, double *tzero, char *tnull, char *tdisp, int *status); int CFITS_API ffgbcl(fitsfile *fptr, int colnum, char *ttype, char *tunit, char *dtype, long *repeat, double *tscal, double *tzero, long *tnull, char *tdisp, int *status); int CFITS_API ffgbclll(fitsfile *fptr, int colnum, char *ttype, char *tunit, char *dtype, LONGLONG *repeat, double *tscal, double *tzero, LONGLONG *tnull, char *tdisp, int *status); int CFITS_API ffgrsz(fitsfile *fptr, long *nrows, int *status); int CFITS_API ffgcdw(fitsfile *fptr, int colnum, int *width, int *status); /*--------------------- read primary array or image elements -------------*/ int CFITS_API ffgpxv(fitsfile *fptr, int datatype, long *firstpix, LONGLONG nelem, void *nulval, void *array, int *anynul, int *status); int CFITS_API ffgpxvll(fitsfile *fptr, int datatype, LONGLONG *firstpix, LONGLONG nelem, void *nulval, void *array, int *anynul, int *status); int CFITS_API ffgpxf(fitsfile *fptr, int datatype, long *firstpix, LONGLONG nelem, void *array, char *nullarray, int *anynul, int *status); int CFITS_API ffgpxfll(fitsfile *fptr, int datatype, LONGLONG *firstpix, LONGLONG nelem, void *array, char *nullarray, int *anynul, int *status); int CFITS_API ffgsv(fitsfile *fptr, int datatype, long *blc, long *trc, long *inc, void *nulval, void *array, int *anynul, int *status); int CFITS_API ffgpv(fitsfile *fptr, int datatype, LONGLONG firstelem, LONGLONG nelem, void *nulval, void *array, int *anynul, int *status); int CFITS_API ffgpf(fitsfile *fptr, int datatype, LONGLONG firstelem, LONGLONG nelem, void *array, char *nullarray, int *anynul, int *status); int CFITS_API ffgpvb(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned char nulval, unsigned char *array, int *anynul, int *status); int CFITS_API ffgpvsb(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, signed char nulval, signed char *array, int *anynul, int *status); int CFITS_API ffgpvui(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned short nulval, unsigned short *array, int *anynul, int *status); int CFITS_API ffgpvi(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, short nulval, short *array, int *anynul, int *status); int CFITS_API ffgpvuj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned long nulval, unsigned long *array, int *anynul, int *status); int CFITS_API ffgpvj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, long nulval, long *array, int *anynul, int *status); int CFITS_API ffgpvujj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, ULONGLONG nulval, ULONGLONG *array, int *anynul, int *status); int CFITS_API ffgpvjj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, LONGLONG nulval, LONGLONG *array, int *anynul, int *status); int CFITS_API ffgpvuk(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned int nulval, unsigned int *array, int *anynul, int *status); int CFITS_API ffgpvk(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, int nulval, int *array, int *anynul, int *status); int CFITS_API ffgpve(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, float nulval, float *array, int *anynul, int *status); int CFITS_API ffgpvd(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, double nulval, double *array, int *anynul, int *status); int CFITS_API ffgpfb(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned char *array, char *nularray, int *anynul, int *status); int CFITS_API ffgpfsb(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, signed char *array, char *nularray, int *anynul, int *status); int CFITS_API ffgpfui(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned short *array, char *nularray, int *anynul, int *status); int CFITS_API ffgpfi(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, short *array, char *nularray, int *anynul, int *status); int CFITS_API ffgpfuj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned long *array, char *nularray, int *anynul, int *status); int CFITS_API ffgpfj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, long *array, char *nularray, int *anynul, int *status); int CFITS_API ffgpfujj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, ULONGLONG *array, char *nularray, int *anynul, int *status); int CFITS_API ffgpfjj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, LONGLONG *array, char *nularray, int *anynul, int *status); int CFITS_API ffgpfuk(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned int *array, char *nularray, int *anynul, int *status); int CFITS_API ffgpfk(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, int *array, char *nularray, int *anynul, int *status); int CFITS_API ffgpfe(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, float *array, char *nularray, int *anynul, int *status); int CFITS_API ffgpfd(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, double *array, char *nularray, int *anynul, int *status); int CFITS_API ffg2db(fitsfile *fptr, long group, unsigned char nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, unsigned char *array, int *anynul, int *status); int CFITS_API ffg2dsb(fitsfile *fptr, long group, signed char nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, signed char *array, int *anynul, int *status); int CFITS_API ffg2dui(fitsfile *fptr, long group, unsigned short nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, unsigned short *array, int *anynul, int *status); int CFITS_API ffg2di(fitsfile *fptr, long group, short nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, short *array, int *anynul, int *status); int CFITS_API ffg2duj(fitsfile *fptr, long group, unsigned long nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, unsigned long *array, int *anynul, int *status); int CFITS_API ffg2dj(fitsfile *fptr, long group, long nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, long *array, int *anynul, int *status); int CFITS_API ffg2dujj(fitsfile *fptr, long group, ULONGLONG nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, ULONGLONG *array, int *anynul, int *status); int CFITS_API ffg2djj(fitsfile *fptr, long group, LONGLONG nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, LONGLONG *array, int *anynul, int *status); int CFITS_API ffg2duk(fitsfile *fptr, long group, unsigned int nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, unsigned int *array, int *anynul, int *status); int CFITS_API ffg2dk(fitsfile *fptr, long group, int nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, int *array, int *anynul, int *status); int CFITS_API ffg2de(fitsfile *fptr, long group, float nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, float *array, int *anynul, int *status); int CFITS_API ffg2dd(fitsfile *fptr, long group, double nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, double *array, int *anynul, int *status); int CFITS_API ffg3db(fitsfile *fptr, long group, unsigned char nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, unsigned char *array, int *anynul, int *status); int CFITS_API ffg3dsb(fitsfile *fptr, long group, signed char nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, signed char *array, int *anynul, int *status); int CFITS_API ffg3dui(fitsfile *fptr, long group, unsigned short nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, unsigned short *array, int *anynul, int *status); int CFITS_API ffg3di(fitsfile *fptr, long group, short nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, short *array, int *anynul, int *status); int CFITS_API ffg3duj(fitsfile *fptr, long group, unsigned long nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, unsigned long *array, int *anynul, int *status); int CFITS_API ffg3dj(fitsfile *fptr, long group, long nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, long *array, int *anynul, int *status); int CFITS_API ffg3dujj(fitsfile *fptr, long group, ULONGLONG nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, ULONGLONG *array, int *anynul, int *status); int CFITS_API ffg3djj(fitsfile *fptr, long group, LONGLONG nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, LONGLONG *array, int *anynul, int *status); int CFITS_API ffg3duk(fitsfile *fptr, long group, unsigned int nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, unsigned int *array, int *anynul, int *status); int CFITS_API ffg3dk(fitsfile *fptr, long group, int nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, int *array, int *anynul, int *status); int CFITS_API ffg3de(fitsfile *fptr, long group, float nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, float *array, int *anynul, int *status); int CFITS_API ffg3dd(fitsfile *fptr, long group, double nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, double *array, int *anynul, int *status); int CFITS_API ffgsvb(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, unsigned char nulval, unsigned char *array, int *anynul, int *status); int CFITS_API ffgsvsb(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, signed char nulval, signed char *array, int *anynul, int *status); int CFITS_API ffgsvui(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, unsigned short nulval, unsigned short *array, int *anynul, int *status); int CFITS_API ffgsvi(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, short nulval, short *array, int *anynul, int *status); int CFITS_API ffgsvuj(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, unsigned long nulval, unsigned long *array, int *anynul, int *status); int CFITS_API ffgsvj(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, long nulval, long *array, int *anynul, int *status); int CFITS_API ffgsvujj(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, ULONGLONG nulval, ULONGLONG *array, int *anynul, int *status); int CFITS_API ffgsvjj(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, LONGLONG nulval, LONGLONG *array, int *anynul, int *status); int CFITS_API ffgsvuk(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, unsigned int nulval, unsigned int *array, int *anynul, int *status); int CFITS_API ffgsvk(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, int nulval, int *array, int *anynul, int *status); int CFITS_API ffgsve(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, float nulval, float *array, int *anynul, int *status); int CFITS_API ffgsvd(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, double nulval, double *array, int *anynul, int *status); int CFITS_API ffgsfb(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, unsigned char *array, char *flagval, int *anynul, int *status); int CFITS_API ffgsfsb(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, signed char *array, char *flagval, int *anynul, int *status); int CFITS_API ffgsfui(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, unsigned short *array, char *flagval, int *anynul, int *status); int CFITS_API ffgsfi(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, short *array, char *flagval, int *anynul, int *status); int CFITS_API ffgsfuj(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, unsigned long *array, char *flagval, int *anynul, int *status); int CFITS_API ffgsfj(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, long *array, char *flagval, int *anynul, int *status); int CFITS_API ffgsfujj(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, ULONGLONG *array, char *flagval, int *anynul, int *status); int CFITS_API ffgsfjj(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, LONGLONG *array, char *flagval, int *anynul, int *status); int CFITS_API ffgsfuk(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, unsigned int *array, char *flagval, int *anynul, int *status); int CFITS_API ffgsfk(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, int *array, char *flagval, int *anynul, int *status); int CFITS_API ffgsfe(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, float *array, char *flagval, int *anynul, int *status); int CFITS_API ffgsfd(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, double *array, char *flagval, int *anynul, int *status); int CFITS_API ffggpb(fitsfile *fptr, long group, long firstelem, long nelem, unsigned char *array, int *status); int CFITS_API ffggpsb(fitsfile *fptr, long group, long firstelem, long nelem, signed char *array, int *status); int CFITS_API ffggpui(fitsfile *fptr, long group, long firstelem, long nelem, unsigned short *array, int *status); int CFITS_API ffggpi(fitsfile *fptr, long group, long firstelem, long nelem, short *array, int *status); int CFITS_API ffggpuj(fitsfile *fptr, long group, long firstelem, long nelem, unsigned long *array, int *status); int CFITS_API ffggpj(fitsfile *fptr, long group, long firstelem, long nelem, long *array, int *status); int CFITS_API ffggpujj(fitsfile *fptr, long group, long firstelem, long nelem, ULONGLONG *array, int *status); int CFITS_API ffggpjj(fitsfile *fptr, long group, long firstelem, long nelem, LONGLONG *array, int *status); int CFITS_API ffggpuk(fitsfile *fptr, long group, long firstelem, long nelem, unsigned int *array, int *status); int CFITS_API ffggpk(fitsfile *fptr, long group, long firstelem, long nelem, int *array, int *status); int CFITS_API ffggpe(fitsfile *fptr, long group, long firstelem, long nelem, float *array, int *status); int CFITS_API ffggpd(fitsfile *fptr, long group, long firstelem, long nelem, double *array, int *status); /*--------------------- read column elements -------------*/ int CFITS_API ffgcv( fitsfile *fptr, int datatype, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, void *nulval, void *array, int *anynul, int *status); int CFITS_API ffgcf( fitsfile *fptr, int datatype, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, void *array, char *nullarray, int *anynul, int *status); int CFITS_API ffgcvs(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char *nulval, char **array, int *anynul, int *status); int CFITS_API ffgcl (fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char *array, int *status); int CFITS_API ffgcvl (fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char nulval, char *array, int *anynul, int *status); int CFITS_API ffgcvb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned char nulval, unsigned char *array, int *anynul, int *status); int CFITS_API ffgcvsb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, signed char nulval, signed char *array, int *anynul, int *status); int CFITS_API ffgcvui(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned short nulval, unsigned short *array, int *anynul, int *status); int CFITS_API ffgcvi(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, short nulval, short *array, int *anynul, int *status); int CFITS_API ffgcvuj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned long nulval, unsigned long *array, int *anynul, int *status); int CFITS_API ffgcvj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long nulval, long *array, int *anynul, int *status); int CFITS_API ffgcvujj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, ULONGLONG nulval, ULONGLONG *array, int *anynul, int *status); int CFITS_API ffgcvjj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, LONGLONG nulval, LONGLONG *array, int *anynul, int *status); int CFITS_API ffgcvuk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned int nulval, unsigned int *array, int *anynul, int *status); int CFITS_API ffgcvk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int nulval, int *array, int *anynul, int *status); int CFITS_API ffgcve(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, float nulval, float *array, int *anynul, int *status); int CFITS_API ffgcvd(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, double nulval, double *array, int *anynul, int *status); int CFITS_API ffgcvc(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, float nulval, float *array, int *anynul, int *status); int CFITS_API ffgcvm(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, double nulval, double *array, int *anynul, int *status); int CFITS_API ffgcx(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstbit, LONGLONG nbits, char *larray, int *status); int CFITS_API ffgcxui(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG nrows, long firstbit, int nbits, unsigned short *array, int *status); int CFITS_API ffgcxuk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG nrows, long firstbit, int nbits, unsigned int *array, int *status); int CFITS_API ffgcfs(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char **array, char *nularray, int *anynul, int *status); int CFITS_API ffgcfl(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char *array, char *nularray, int *anynul, int *status); int CFITS_API ffgcfb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned char *array, char *nularray, int *anynul, int *status); int CFITS_API ffgcfsb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, signed char *array, char *nularray, int *anynul, int *status); int CFITS_API ffgcfui(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned short *array, char *nularray, int *anynul, int *status); int CFITS_API ffgcfi(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, short *array, char *nularray, int *anynul, int *status); int CFITS_API ffgcfuj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned long *array, char *nularray, int *anynul, int *status); int CFITS_API ffgcfj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long *array, char *nularray, int *anynul, int *status); int CFITS_API ffgcfujj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, ULONGLONG *array, char *nularray, int *anynul, int *status); int CFITS_API ffgcfjj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, LONGLONG *array, char *nularray, int *anynul, int *status); int CFITS_API ffgcfuk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned int *array, char *nularray, int *anynul, int *status); int CFITS_API ffgcfk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int *array, char *nularray, int *anynul, int *status); int CFITS_API ffgcfe(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, float *array, char *nularray, int *anynul, int *status); int CFITS_API ffgcfd(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, double *array, char *nularray, int *anynul, int *status); int CFITS_API ffgcfc(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, float *array, char *nularray, int *anynul, int *status); int CFITS_API ffgcfm(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, double *array, char *nularray, int *anynul, int *status); int CFITS_API ffgdes(fitsfile *fptr, int colnum, LONGLONG rownum, long *length, long *heapaddr, int *status); int CFITS_API ffgdesll(fitsfile *fptr, int colnum, LONGLONG rownum, LONGLONG *length, LONGLONG *heapaddr, int *status); int CFITS_API ffgdess(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG nrows, long *length, long *heapaddr, int *status); int CFITS_API ffgdessll(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG nrows, LONGLONG *length, LONGLONG *heapaddr, int *status); int CFITS_API ffpdes(fitsfile *fptr, int colnum, LONGLONG rownum, LONGLONG length, LONGLONG heapaddr, int *status); int CFITS_API fftheap(fitsfile *fptr, LONGLONG *heapsize, LONGLONG *unused, LONGLONG *overlap, int *valid, int *status); int CFITS_API ffcmph(fitsfile *fptr, int *status); int CFITS_API ffgtbb(fitsfile *fptr, LONGLONG firstrow, LONGLONG firstchar, LONGLONG nchars, unsigned char *values, int *status); int CFITS_API ffgextn(fitsfile *fptr, LONGLONG offset, LONGLONG nelem, void *array, int *status); int CFITS_API ffpextn(fitsfile *fptr, LONGLONG offset, LONGLONG nelem, void *array, int *status); /*------------ write primary array or image elements -------------*/ int CFITS_API ffppx(fitsfile *fptr, int datatype, long *firstpix, LONGLONG nelem, void *array, int *status); int CFITS_API ffppxll(fitsfile *fptr, int datatype, LONGLONG *firstpix, LONGLONG nelem, void *array, int *status); int CFITS_API ffppxn(fitsfile *fptr, int datatype, long *firstpix, LONGLONG nelem, void *array, void *nulval, int *status); int CFITS_API ffppxnll(fitsfile *fptr, int datatype, LONGLONG *firstpix, LONGLONG nelem, void *array, void *nulval, int *status); int CFITS_API ffppr(fitsfile *fptr, int datatype, LONGLONG firstelem, LONGLONG nelem, void *array, int *status); int CFITS_API ffpprb(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned char *array, int *status); int CFITS_API ffpprsb(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, signed char *array, int *status); int CFITS_API ffpprui(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned short *array, int *status); int CFITS_API ffppri(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, short *array, int *status); int CFITS_API ffppruj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned long *array, int *status); int CFITS_API ffpprj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, long *array, int *status); int CFITS_API ffppruk(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned int *array, int *status); int CFITS_API ffpprk(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, int *array, int *status); int CFITS_API ffppre(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, float *array, int *status); int CFITS_API ffpprd(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, double *array, int *status); int CFITS_API ffpprjj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, LONGLONG *array, int *status); int CFITS_API ffpprujj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, ULONGLONG *array, int *status); int CFITS_API ffppru(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, int *status); int CFITS_API ffpprn(fitsfile *fptr, LONGLONG firstelem, LONGLONG nelem, int *status); int CFITS_API ffppn(fitsfile *fptr, int datatype, LONGLONG firstelem, LONGLONG nelem, void *array, void *nulval, int *status); int CFITS_API ffppnb(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned char *array, unsigned char nulval, int *status); int CFITS_API ffppnsb(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, signed char *array, signed char nulval, int *status); int CFITS_API ffppnui(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned short *array, unsigned short nulval, int *status); int CFITS_API ffppni(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, short *array, short nulval, int *status); int CFITS_API ffppnj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, long *array, long nulval, int *status); int CFITS_API ffppnuj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned long *array, unsigned long nulval, int *status); int CFITS_API ffppnuk(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned int *array, unsigned int nulval, int *status); int CFITS_API ffppnk(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, int *array, int nulval, int *status); int CFITS_API ffppne(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, float *array, float nulval, int *status); int CFITS_API ffppnd(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, double *array, double nulval, int *status); int CFITS_API ffppnjj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, LONGLONG *array, LONGLONG nulval, int *status); int CFITS_API ffppnujj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, ULONGLONG *array, ULONGLONG nulval, int *status); int CFITS_API ffp2db(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, unsigned char *array, int *status); int CFITS_API ffp2dsb(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, signed char *array, int *status); int CFITS_API ffp2dui(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, unsigned short *array, int *status); int CFITS_API ffp2di(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, short *array, int *status); int CFITS_API ffp2duj(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, unsigned long *array, int *status); int CFITS_API ffp2dj(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, long *array, int *status); int CFITS_API ffp2duk(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, unsigned int *array, int *status); int CFITS_API ffp2dk(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, int *array, int *status); int CFITS_API ffp2de(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, float *array, int *status); int CFITS_API ffp2dd(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, double *array, int *status); int CFITS_API ffp2djj(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, LONGLONG *array, int *status); int CFITS_API ffp2dujj(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, ULONGLONG *array, int *status); int CFITS_API ffp3db(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, unsigned char *array, int *status); int CFITS_API ffp3dsb(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, signed char *array, int *status); int CFITS_API ffp3dui(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, unsigned short *array, int *status); int CFITS_API ffp3di(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, short *array, int *status); int CFITS_API ffp3duj(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, unsigned long *array, int *status); int CFITS_API ffp3dj(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, long *array, int *status); int CFITS_API ffp3duk(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, unsigned int *array, int *status); int CFITS_API ffp3dk(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, int *array, int *status); int CFITS_API ffp3de(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, float *array, int *status); int CFITS_API ffp3dd(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, double *array, int *status); int CFITS_API ffp3djj(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, LONGLONG *array, int *status); int CFITS_API ffp3dujj(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, ULONGLONG *array, int *status); int CFITS_API ffpss(fitsfile *fptr, int datatype, long *fpixel, long *lpixel, void *array, int *status); int CFITS_API ffpssb(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, unsigned char *array, int *status); int CFITS_API ffpsssb(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, signed char *array, int *status); int CFITS_API ffpssui(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, unsigned short *array, int *status); int CFITS_API ffpssi(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, short *array, int *status); int CFITS_API ffpssuj(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, unsigned long *array, int *status); int CFITS_API ffpssj(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, long *array, int *status); int CFITS_API ffpssuk(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, unsigned int *array, int *status); int CFITS_API ffpssk(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, int *array, int *status); int CFITS_API ffpsse(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, float *array, int *status); int CFITS_API ffpssd(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, double *array, int *status); int CFITS_API ffpssjj(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, LONGLONG *array, int *status); int CFITS_API ffpssujj(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, ULONGLONG *array, int *status); int CFITS_API ffpgpb(fitsfile *fptr, long group, long firstelem, long nelem, unsigned char *array, int *status); int CFITS_API ffpgpsb(fitsfile *fptr, long group, long firstelem, long nelem, signed char *array, int *status); int CFITS_API ffpgpui(fitsfile *fptr, long group, long firstelem, long nelem, unsigned short *array, int *status); int CFITS_API ffpgpi(fitsfile *fptr, long group, long firstelem, long nelem, short *array, int *status); int CFITS_API ffpgpuj(fitsfile *fptr, long group, long firstelem, long nelem, unsigned long *array, int *status); int CFITS_API ffpgpj(fitsfile *fptr, long group, long firstelem, long nelem, long *array, int *status); int CFITS_API ffpgpuk(fitsfile *fptr, long group, long firstelem, long nelem, unsigned int *array, int *status); int CFITS_API ffpgpk(fitsfile *fptr, long group, long firstelem, long nelem, int *array, int *status); int CFITS_API ffpgpe(fitsfile *fptr, long group, long firstelem, long nelem, float *array, int *status); int CFITS_API ffpgpd(fitsfile *fptr, long group, long firstelem, long nelem, double *array, int *status); int CFITS_API ffpgpjj(fitsfile *fptr, long group, long firstelem, long nelem, LONGLONG *array, int *status); int CFITS_API ffpgpujj(fitsfile *fptr, long group, long firstelem, long nelem, ULONGLONG *array, int *status); /*--------------------- iterator functions -------------*/ int CFITS_API fits_iter_set_by_name(iteratorCol *col, fitsfile *fptr, char *colname, int datatype, int iotype); int CFITS_API fits_iter_set_by_num(iteratorCol *col, fitsfile *fptr, int colnum, int datatype, int iotype); int CFITS_API fits_iter_set_file(iteratorCol *col, fitsfile *fptr); int CFITS_API fits_iter_set_colname(iteratorCol *col, char *colname); int CFITS_API fits_iter_set_colnum(iteratorCol *col, int colnum); int CFITS_API fits_iter_set_datatype(iteratorCol *col, int datatype); int CFITS_API fits_iter_set_iotype(iteratorCol *col, int iotype); CFITS_API fitsfile * fits_iter_get_file(iteratorCol *col); char CFITS_API * fits_iter_get_colname(iteratorCol *col); int CFITS_API fits_iter_get_colnum(iteratorCol *col); int CFITS_API fits_iter_get_datatype(iteratorCol *col); int CFITS_API fits_iter_get_iotype(iteratorCol *col); void CFITS_API *fits_iter_get_array(iteratorCol *col); long CFITS_API fits_iter_get_tlmin(iteratorCol *col); long CFITS_API fits_iter_get_tlmax(iteratorCol *col); long CFITS_API fits_iter_get_repeat(iteratorCol *col); char CFITS_API *fits_iter_get_tunit(iteratorCol *col); char CFITS_API *fits_iter_get_tdisp(iteratorCol *col); int CFITS_API ffiter(int ncols, iteratorCol *data, long offset, long nPerLoop, int (*workFn)( long totaln, long offset, long firstn, long nvalues, int narrays, iteratorCol *data, void *userPointer), void *userPointer, int *status); /*--------------------- write column elements -------------*/ int CFITS_API ffpcl(fitsfile *fptr, int datatype, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, void *array, int *status); int CFITS_API ffpcls(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char **array, int *status); int CFITS_API ffpcll(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char *array, int *status); int CFITS_API ffpclb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned char *array, int *status); int CFITS_API ffpclsb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, signed char *array, int *status); int CFITS_API ffpclui(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned short *array, int *status); int CFITS_API ffpcli(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, short *array, int *status); int CFITS_API ffpcluj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned long *array, int *status); int CFITS_API ffpclj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long *array, int *status); int CFITS_API ffpcluk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned int *array, int *status); int CFITS_API ffpclk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int *array, int *status); int CFITS_API ffpcle(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, float *array, int *status); int CFITS_API ffpcld(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, double *array, int *status); int CFITS_API ffpclc(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, float *array, int *status); int CFITS_API ffpclm(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, double *array, int *status); int CFITS_API ffpclu(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int *status); int CFITS_API ffprwu(fitsfile *fptr, LONGLONG firstrow, LONGLONG nrows, int *status); int CFITS_API ffpcljj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, LONGLONG *array, int *status); int CFITS_API ffpclujj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, ULONGLONG *array, int *status); int CFITS_API ffpclx(fitsfile *fptr, int colnum, LONGLONG frow, long fbit, long nbit, char *larray, int *status); int CFITS_API ffpcn(fitsfile *fptr, int datatype, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, void *array, void *nulval, int *status); int CFITS_API ffpcns( fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char **array, char *nulvalue, int *status); int CFITS_API ffpcnl( fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char *array, char nulvalue, int *status); int CFITS_API ffpcnb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned char *array, unsigned char nulvalue, int *status); int CFITS_API ffpcnsb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, signed char *array, signed char nulvalue, int *status); int CFITS_API ffpcnui(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned short *array, unsigned short nulvalue, int *status); int CFITS_API ffpcni(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, short *array, short nulvalue, int *status); int CFITS_API ffpcnuj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned long *array, unsigned long nulvalue, int *status); int CFITS_API ffpcnj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long *array, long nulvalue, int *status); int CFITS_API ffpcnuk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned int *array, unsigned int nulvalue, int *status); int CFITS_API ffpcnk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int *array, int nulvalue, int *status); int CFITS_API ffpcne(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, float *array, float nulvalue, int *status); int CFITS_API ffpcnd(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, double *array, double nulvalue, int *status); int CFITS_API ffpcnjj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, LONGLONG *array, LONGLONG nulvalue, int *status); int CFITS_API ffpcnujj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, ULONGLONG *array, ULONGLONG nulvalue, int *status); int CFITS_API ffptbb(fitsfile *fptr, LONGLONG firstrow, LONGLONG firstchar, LONGLONG nchars, unsigned char *values, int *status); int CFITS_API ffirow(fitsfile *fptr, LONGLONG firstrow, LONGLONG nrows, int *status); int CFITS_API ffdrow(fitsfile *fptr, LONGLONG firstrow, LONGLONG nrows, int *status); int CFITS_API ffdrrg(fitsfile *fptr, char *ranges, int *status); int CFITS_API ffdrws(fitsfile *fptr, long *rownum, long nrows, int *status); int CFITS_API ffdrwsll(fitsfile *fptr, LONGLONG *rownum, LONGLONG nrows, int *status); int CFITS_API fficol(fitsfile *fptr, int numcol, char *ttype, char *tform, int *status); int CFITS_API fficls(fitsfile *fptr, int firstcol, int ncols, char **ttype, char **tform, int *status); int CFITS_API ffmvec(fitsfile *fptr, int colnum, LONGLONG newveclen, int *status); int CFITS_API ffdcol(fitsfile *fptr, int numcol, int *status); int CFITS_API ffcpcl(fitsfile *infptr, fitsfile *outfptr, int incol, int outcol, int create_col, int *status); int CFITS_API ffccls(fitsfile *infptr, fitsfile *outfptr, int incol, int outcol, int ncols, int create_col, int *status); int CFITS_API ffcprw(fitsfile *infptr, fitsfile *outfptr, LONGLONG firstrow, LONGLONG nrows, int *status); int CFITS_API ffcpht(fitsfile *infptr, fitsfile *outfptr, LONGLONG firstrow, LONGLONG nrows, int *status); /*--------------------- WCS Utilities ------------------*/ int CFITS_API ffgics(fitsfile *fptr, double *xrval, double *yrval, double *xrpix, double *yrpix, double *xinc, double *yinc, double *rot, char *type, int *status); int CFITS_API ffgicsa(fitsfile *fptr, char version, double *xrval, double *yrval, double *xrpix, double *yrpix, double *xinc, double *yinc, double *rot, char *type, int *status); int CFITS_API ffgtcs(fitsfile *fptr, int xcol, int ycol, double *xrval, double *yrval, double *xrpix, double *yrpix, double *xinc, double *yinc, double *rot, char *type, int *status); int CFITS_API ffwldp(double xpix, double ypix, double xref, double yref, double xrefpix, double yrefpix, double xinc, double yinc, double rot, char *type, double *xpos, double *ypos, int *status); int CFITS_API ffxypx(double xpos, double ypos, double xref, double yref, double xrefpix, double yrefpix, double xinc, double yinc, double rot, char *type, double *xpix, double *ypix, int *status); /* WCS support routines (provide interface to Doug Mink's WCS library */ int CFITS_API ffgiwcs(fitsfile *fptr, char **header, int *status); int CFITS_API ffgtwcs(fitsfile *fptr, int xcol, int ycol, char **header, int *status); /*--------------------- lexical parsing routines ------------------*/ int CFITS_API fftexp( fitsfile *fptr, char *expr, int maxdim, int *datatype, long *nelem, int *naxis, long *naxes, int *status ); int CFITS_API fffrow( fitsfile *infptr, char *expr, long firstrow, long nrows, long *n_good_rows, char *row_status, int *status); int CFITS_API ffffrw( fitsfile *fptr, char *expr, long *rownum, int *status); int CFITS_API fffrwc( fitsfile *fptr, char *expr, char *timeCol, char *parCol, char *valCol, long ntimes, double *times, char *time_status, int *status ); int CFITS_API ffsrow( fitsfile *infptr, fitsfile *outfptr, char *expr, int *status); int CFITS_API ffcrow( fitsfile *fptr, int datatype, char *expr, long firstrow, long nelements, void *nulval, void *array, int *anynul, int *status ); int CFITS_API ffcalc_rng( fitsfile *infptr, char *expr, fitsfile *outfptr, char *parName, char *parInfo, int nRngs, long *start, long *end, int *status ); int CFITS_API ffcalc( fitsfile *infptr, char *expr, fitsfile *outfptr, char *parName, char *parInfo, int *status ); /* ffhist is not really intended as a user-callable routine */ /* but it may be useful for some specialized applications */ /* ffhist2 is a newer version which is strongly recommended instead of ffhist */ int CFITS_API ffhist(fitsfile **fptr, char *outfile, int imagetype, int naxis, char colname[4][FLEN_VALUE], double *minin, double *maxin, double *binsizein, char minname[4][FLEN_VALUE], char maxname[4][FLEN_VALUE], char binname[4][FLEN_VALUE], double weightin, char wtcol[FLEN_VALUE], int recip, char *rowselect, int *status); int CFITS_API ffhist2(fitsfile **fptr, char *outfile, int imagetype, int naxis, char colname[4][FLEN_VALUE], double *minin, double *maxin, double *binsizein, char minname[4][FLEN_VALUE], char maxname[4][FLEN_VALUE], char binname[4][FLEN_VALUE], double weightin, char wtcol[FLEN_VALUE], int recip, char *rowselect, int *status); CFITS_API fitsfile *ffhist3(fitsfile *fptr, char *outfile, int imagetype, int naxis, char colname[4][FLEN_VALUE], double *minin, double *maxin, double *binsizein, char minname[4][FLEN_VALUE], char maxname[4][FLEN_VALUE], char binname[4][FLEN_VALUE], double weightin, char wtcol[FLEN_VALUE], int recip, char *selectrow, int *status); int CFITS_API fits_select_image_section(fitsfile **fptr, char *outfile, char *imagesection, int *status); int CFITS_API fits_copy_image_section(fitsfile *infptr, fitsfile *outfile, char *imagesection, int *status); int CFITS_API fits_calc_binning(fitsfile *fptr, int naxis, char colname[4][FLEN_VALUE], double *minin, double *maxin, double *binsizein, char minname[4][FLEN_VALUE], char maxname[4][FLEN_VALUE], char binname[4][FLEN_VALUE], int *colnum, long *haxes, float *amin, float *amax, float *binsize, int *status); int CFITS_API fits_calc_binningd(fitsfile *fptr, int naxis, char colname[4][FLEN_VALUE], double *minin, double *maxin, double *binsizein, char minname[4][FLEN_VALUE], char maxname[4][FLEN_VALUE], char binname[4][FLEN_VALUE], int *colnum, long *haxes, double *amin, double *amax, double *binsize, int *status); int CFITS_API fits_write_keys_histo(fitsfile *fptr, fitsfile *histptr, int naxis, int *colnum, int *status); int CFITS_API fits_rebin_wcs( fitsfile *fptr, int naxis, float *amin, float *binsize, int *status); int CFITS_API fits_rebin_wcsd( fitsfile *fptr, int naxis, double *amin, double *binsize, int *status); int CFITS_API fits_make_hist(fitsfile *fptr, fitsfile *histptr, int bitpix,int naxis, long *naxes, int *colnum, float *amin, float *amax, float *binsize, float weight, int wtcolnum, int recip, char *selectrow, int *status); int CFITS_API fits_make_histd(fitsfile *fptr, fitsfile *histptr, int bitpix,int naxis, long *naxes, int *colnum, double *amin, double *amax, double *binsize, double weight, int wtcolnum, int recip, char *selectrow, int *status); typedef struct { /* input(s) */ int count; char ** path; char ** tag; fitsfile ** ifptr; char * expression; /* output control */ int bitpix; long blank; fitsfile * ofptr; char keyword[FLEN_KEYWORD]; char comment[FLEN_COMMENT]; } PixelFilter; int CFITS_API fits_pixel_filter (PixelFilter * filter, int * status); /*--------------------- grouping routines ------------------*/ int CFITS_API ffgtcr(fitsfile *fptr, char *grpname, int grouptype, int *status); int CFITS_API ffgtis(fitsfile *fptr, char *grpname, int grouptype, int *status); int CFITS_API ffgtch(fitsfile *gfptr, int grouptype, int *status); int CFITS_API ffgtrm(fitsfile *gfptr, int rmopt, int *status); int CFITS_API ffgtcp(fitsfile *infptr, fitsfile *outfptr, int cpopt, int *status); int CFITS_API ffgtmg(fitsfile *infptr, fitsfile *outfptr, int mgopt, int *status); int CFITS_API ffgtcm(fitsfile *gfptr, int cmopt, int *status); int CFITS_API ffgtvf(fitsfile *gfptr, long *firstfailed, int *status); int CFITS_API ffgtop(fitsfile *mfptr,int group,fitsfile **gfptr,int *status); int CFITS_API ffgtam(fitsfile *gfptr, fitsfile *mfptr, int hdupos, int *status); int CFITS_API ffgtnm(fitsfile *gfptr, long *nmembers, int *status); int CFITS_API ffgmng(fitsfile *mfptr, long *nmembers, int *status); int CFITS_API ffgmop(fitsfile *gfptr, long member, fitsfile **mfptr, int *status); int CFITS_API ffgmcp(fitsfile *gfptr, fitsfile *mfptr, long member, int cpopt, int *status); int CFITS_API ffgmtf(fitsfile *infptr, fitsfile *outfptr, long member, int tfopt, int *status); int CFITS_API ffgmrm(fitsfile *fptr, long member, int rmopt, int *status); /*--------------------- group template parser routines ------------------*/ int CFITS_API fits_execute_template(fitsfile *ff, char *ngp_template, int *status); int CFITS_API fits_img_stats_short(short *array,long nx, long ny, int nullcheck, short nullvalue,long *ngoodpix, short *minvalue, short *maxvalue, double *mean, double *sigma, double *noise1, double *noise2, double *noise3, double *noise5, int *status); int CFITS_API fits_img_stats_int(int *array,long nx, long ny, int nullcheck, int nullvalue,long *ngoodpix, int *minvalue, int *maxvalue, double *mean, double *sigma, double *noise1, double *noise2, double *noise3, double *noise5, int *status); int CFITS_API fits_img_stats_float(float *array, long nx, long ny, int nullcheck, float nullvalue,long *ngoodpix, float *minvalue, float *maxvalue, double *mean, double *sigma, double *noise1, double *noise2, double *noise3, double *noise5, int *status); /*--------------------- image compression routines ------------------*/ int CFITS_API fits_set_compression_type(fitsfile *fptr, int ctype, int *status); int CFITS_API fits_set_tile_dim(fitsfile *fptr, int ndim, long *dims, int *status); int CFITS_API fits_set_noise_bits(fitsfile *fptr, int noisebits, int *status); int CFITS_API fits_set_quantize_level(fitsfile *fptr, float qlevel, int *status); int CFITS_API fits_set_hcomp_scale(fitsfile *fptr, float scale, int *status); int CFITS_API fits_set_hcomp_smooth(fitsfile *fptr, int smooth, int *status); int CFITS_API fits_set_quantize_method(fitsfile *fptr, int method, int *status); int CFITS_API fits_set_quantize_dither(fitsfile *fptr, int dither, int *status); int CFITS_API fits_set_dither_seed(fitsfile *fptr, int seed, int *status); int CFITS_API fits_set_dither_offset(fitsfile *fptr, int offset, int *status); int CFITS_API fits_set_lossy_int(fitsfile *fptr, int lossy_int, int *status); int CFITS_API fits_set_huge_hdu(fitsfile *fptr, int huge, int *status); int CFITS_API fits_set_compression_pref(fitsfile *infptr, fitsfile *outfptr, int *status); int CFITS_API fits_get_compression_type(fitsfile *fptr, int *ctype, int *status); int CFITS_API fits_get_tile_dim(fitsfile *fptr, int ndim, long *dims, int *status); int CFITS_API fits_get_quantize_level(fitsfile *fptr, float *qlevel, int *status); int CFITS_API fits_get_noise_bits(fitsfile *fptr, int *noisebits, int *status); int CFITS_API fits_get_hcomp_scale(fitsfile *fptr, float *scale, int *status); int CFITS_API fits_get_hcomp_smooth(fitsfile *fptr, int *smooth, int *status); int CFITS_API fits_get_dither_seed(fitsfile *fptr, int *seed, int *status); int CFITS_API fits_img_compress(fitsfile *infptr, fitsfile *outfptr, int *status); int CFITS_API fits_compress_img(fitsfile *infptr, fitsfile *outfptr, int compress_type, long *tilesize, int parm1, int parm2, int *status); int CFITS_API fits_is_compressed_image(fitsfile *fptr, int *status); int CFITS_API fits_is_reentrant(void); int CFITS_API fits_decompress_img (fitsfile *infptr, fitsfile *outfptr, int *status); int CFITS_API fits_img_decompress_header(fitsfile *infptr, fitsfile *outfptr, int *status); int CFITS_API fits_img_decompress (fitsfile *infptr, fitsfile *outfptr, int *status); /* H-compress routines */ int CFITS_API fits_hcompress(int *a, int nx, int ny, int scale, char *output, long *nbytes, int *status); int CFITS_API fits_hcompress64(LONGLONG *a, int nx, int ny, int scale, char *output, long *nbytes, int *status); int CFITS_API fits_hdecompress(unsigned char *input, int smooth, int *a, int *nx, int *ny, int *scale, int *status); int CFITS_API fits_hdecompress64(unsigned char *input, int smooth, LONGLONG *a, int *nx, int *ny, int *scale, int *status); int CFITS_API fits_compress_table (fitsfile *infptr, fitsfile *outfptr, int *status); int CFITS_API fits_uncompress_table(fitsfile *infptr, fitsfile *outfptr, int *status); /* curl library wrapper routines (for https access) */ int CFITS_API fits_init_https(void); int CFITS_API fits_cleanup_https(void); void CFITS_API fits_verbose_https(int flag); void CFITS_API ffshdwn(int flag); int CFITS_API ffgtmo(void); int CFITS_API ffstmo(int sec, int *status); /* The following exclusion if __CINT__ is defined is needed for ROOT */ #ifndef __CINT__ #ifdef __cplusplus } #endif #endif #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/fitsio2.h0000644000175100001710000017323300000000000017664 0ustar00vstsdocker#ifndef _FITSIO2_H #define _FITSIO2_H #include "fitsio.h" /* Threading support using POSIX threads programming interface (supplied by Bruce O'Neel) All threaded programs MUST have the -D_REENTRANT on the compile line and must link with -lpthread. This means that when one builds cfitsio for threads you must have -D_REENTRANT on the gcc or cc command line. */ #ifdef _REENTRANT #include /* #include not needed any more */ extern pthread_mutex_t Fitsio_Lock; extern int Fitsio_Pthread_Status; #define FFLOCK1(lockname) (Fitsio_Pthread_Status = pthread_mutex_lock(&lockname)) #define FFUNLOCK1(lockname) (Fitsio_Pthread_Status = pthread_mutex_unlock(&lockname)) #define FFLOCK FFLOCK1(Fitsio_Lock) #define FFUNLOCK FFUNLOCK1(Fitsio_Lock) #define ffstrtok(str, tok, save) strtok_r(str, tok, save) #else #define FFLOCK #define FFUNLOCK #define ffstrtok(str, tok, save) strtok(str, tok) #endif /* If REPLACE_LINKS is defined, then whenever CFITSIO fails to open a file with write access because it is a soft link to a file that only has read access, then CFITSIO will attempt to replace the link with a local copy of the file, with write access. This feature was originally added to support the ftools in the Hera environment, where many of the user's data file are soft links. */ #if defined(BUILD_HERA) #define REPLACE_LINKS 1 #endif #define USE_LARGE_VALUE -99 /* flag used when writing images */ #define DBUFFSIZE 28800 /* size of data buffer in bytes */ #define NMAXFILES 10000 /* maximum number of FITS files that can be opened */ /* CFITSIO will allocate (NMAXFILES * 80) bytes of memory */ /* plus each file that is opened will use NIOBUF * 2880 bytes of memeory */ /* where NIOBUF is defined in fitio.h and has a default value of 40 */ #define MINDIRECT 8640 /* minimum size for direct reads and writes */ /* MINDIRECT must have a value >= 8640 */ /* it is useful to identify certain specific types of machines */ #define NATIVE 0 /* machine that uses non-byteswapped IEEE formats */ #define OTHERTYPE 1 /* any other type of machine */ #define VAXVMS 3 /* uses an odd floating point format */ #define ALPHAVMS 4 /* uses an odd floating point format */ #define IBMPC 5 /* used in drvrfile.c to work around a bug on PCs */ #define CRAY 6 /* requires a special NaN test algorithm */ #define GFLOAT 1 /* used for VMS */ #define IEEEFLOAT 2 /* used for VMS */ /* ======================================================================= */ /* The following logic is used to determine the type machine, */ /* whether the bytes are swapped, and the number of bits in a long value */ /* ======================================================================= */ /* The following platforms have sizeof(long) == 8 */ /* This block of code should match a similar block in fitsio.h */ /* and the block of code at the beginning of f77_wrap.h */ #if defined(__alpha) && ( defined(__unix__) || defined(__NetBSD__) ) /* old Dec Alpha platforms running OSF */ #define BYTESWAPPED TRUE #define LONGSIZE 64 #elif defined(__sparcv9) || (defined(__sparc__) && defined(__arch64__)) /* SUN Solaris7 in 64-bit mode */ #define BYTESWAPPED FALSE #define MACHINE NATIVE #define LONGSIZE 64 /* IBM System z mainframe support */ #elif defined(__s390x__) #define BYTESWAPPED FALSE #define LONGSIZE 64 #elif defined(__s390__) #define BYTESWAPPED FALSE #define LONGSIZE 32 #elif defined(__ia64__) || defined(__x86_64__) || defined(__AARCH64EL__) /* Intel itanium 64-bit PC, or AMD opteron 64-bit PC */ #define BYTESWAPPED TRUE #define LONGSIZE 64 #elif defined(_SX) /* Nec SuperUx */ #define BYTESWAPPED FALSE #define MACHINE NATIVE #define LONGSIZE 64 #elif defined(__powerpc64__) || defined(__64BIT__) || defined(__AARCH64EB__) /* IBM 64-bit AIX powerpc*/ /* could also test for __ppc64__ or __PPC64 */ # if defined(__LITTLE_ENDIAN__) # define BYTESWAPPED TRUE # else # define BYTESWAPPED FALSE # define MACHINE NATIVE # endif # define LONGSIZE 64 #elif defined(_MIPS_SZLONG) # if defined(MIPSEL) # define BYTESWAPPED TRUE # else # define BYTESWAPPED FALSE # define MACHINE NATIVE # endif # if _MIPS_SZLONG == 32 # define LONGSIZE 32 # elif _MIPS_SZLONG == 64 # define LONGSIZE 64 # else # error "can't handle long size given by _MIPS_SZLONG" # endif #elif defined(__riscv) /* RISC-V is always little endian */ #define BYTESWAPPED TRUE # if __riscv_xlen == 32 # define LONGSIZE 32 # elif __riscv_xlen == 64 # define LONGSIZE 64 # else # error "can't handle long size given by __riscv_xlen" # endif /* ============================================================== */ /* the following are all 32-bit byteswapped platforms */ #elif defined(vax) && defined(VMS) #define MACHINE VAXVMS #define BYTESWAPPED TRUE #elif defined(__alpha) && defined(__VMS) #if (__D_FLOAT == TRUE) /* this float option is the same as for VAX/VMS machines. */ #define MACHINE VAXVMS #define BYTESWAPPED TRUE #elif (__G_FLOAT == TRUE) /* G_FLOAT is the default for ALPHA VMS systems */ #define MACHINE ALPHAVMS #define BYTESWAPPED TRUE #define FLOATTYPE GFLOAT #elif (__IEEE_FLOAT == TRUE) #define MACHINE ALPHAVMS #define BYTESWAPPED TRUE #define FLOATTYPE IEEEFLOAT #endif /* end of alpha VMS case */ #elif defined(ultrix) && defined(unix) /* old Dec ultrix machines */ #define BYTESWAPPED TRUE #elif defined(__i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) \ || defined(_MSC_VER) || defined(__BORLANDC__) || defined(__TURBOC__) \ || defined(_NI_mswin_) || defined(__EMX__) /* generic 32-bit IBM PC */ #define MACHINE IBMPC #define BYTESWAPPED TRUE #elif defined(__arm__) /* This assumes all ARM are little endian. In the future, it might be */ /* necessary to use "if defined(__ARMEL__)" to distinguish little from big. */ /* (__ARMEL__ would be defined on little-endian, but not on big-endian). */ #define BYTESWAPPED TRUE #elif defined(__tile__) /* 64-core 8x8-architecture Tile64 platform */ #define BYTESWAPPED TRUE #elif defined(__sh__) /* SuperH CPU can be used in both little and big endian modes */ #if defined(__LITTLE_ENDIAN__) #define BYTESWAPPED TRUE #else #define BYTESWAPPED FALSE #endif #else /* assume all other machine uses the same IEEE formats as used in FITS files */ /* e.g., Macs fall into this category */ #define MACHINE NATIVE #define BYTESWAPPED FALSE #endif #ifndef MACHINE #define MACHINE OTHERTYPE #endif /* assume longs are 4 bytes long, unless previously set otherwise */ #ifndef LONGSIZE #define LONGSIZE 32 #endif /* end of block that determine long size and byte swapping */ /* ==================================================================== */ #define IGNORE_EOF 1 #define REPORT_EOF 0 #define DATA_UNDEFINED -1 #define NULL_UNDEFINED 1234554321 #define ASCII_NULL_UNDEFINED 1 /* indicate no defined null value */ #define maxvalue(A,B) ((A) > (B) ? (A) : (B)) #define minvalue(A,B) ((A) < (B) ? (A) : (B)) /* faster string comparison macros */ #define FSTRCMP(a,b) ((a)[0]<(b)[0]? -1:(a)[0]>(b)[0]?1:strcmp((a),(b))) #define FSTRNCMP(a,b,n) ((a)[0]<(b)[0]?-1:(a)[0]>(b)[0]?1:strncmp((a),(b),(n))) #if defined(__VMS) || defined(VMS) #define FNANMASK 0xFFFF /* mask all bits */ #define DNANMASK 0xFFFF /* mask all bits */ #else #define FNANMASK 0x7F80 /* mask bits 1 - 8; all set on NaNs */ /* all 0 on underflow or 0. */ #define DNANMASK 0x7FF0 /* mask bits 1 - 11; all set on NaNs */ /* all 0 on underflow or 0. */ #endif #if MACHINE == CRAY /* Cray machines: the large negative integer corresponds to the 3 most sig digits set to 1. If these 3 bits are set in a floating point number (64 bits), then it represents a reserved value (i.e., a NaN) */ #define fnan(L) ( (L) >= 0xE000000000000000 ? 1 : 0) ) #else /* these functions work for both big and little endian machines */ /* that use the IEEE floating point format for internal numbers */ /* These functions tests whether the float value is a reserved IEEE */ /* value such as a Not-a-Number (NaN), or underflow, overflow, or */ /* infinity. The functions returns 1 if the value is a NaN, overflow */ /* or infinity; it returns 2 if the value is an denormalized underflow */ /* value; otherwise it returns 0. fnan tests floats, dnan tests doubles */ #define fnan(L) \ ( (L & FNANMASK) == FNANMASK ? 1 : (L & FNANMASK) == 0 ? 2 : 0) #define dnan(L) \ ( (L & DNANMASK) == DNANMASK ? 1 : (L & DNANMASK) == 0 ? 2 : 0) #endif #define DSCHAR_MAX 127.49 /* max double value that fits in an signed char */ #define DSCHAR_MIN -128.49 /* min double value that fits in an signed char */ #define DUCHAR_MAX 255.49 /* max double value that fits in an unsigned char */ #define DUCHAR_MIN -0.49 /* min double value that fits in an unsigned char */ #define DUSHRT_MAX 65535.49 /* max double value that fits in a unsigned short*/ #define DUSHRT_MIN -0.49 /* min double value that fits in an unsigned short */ #define DSHRT_MAX 32767.49 /* max double value that fits in a short */ #define DSHRT_MIN -32768.49 /* min double value that fits in a short */ #if LONGSIZE == 32 # define DLONG_MAX 2147483647.49 /* max double value that fits in a long */ # define DLONG_MIN -2147483648.49 /* min double value that fits in a long */ # define DULONG_MAX 4294967295.49 /* max double that fits in a unsigned long */ #else # define DLONG_MAX 9.2233720368547752E18 /* max double value long */ # define DLONG_MIN -9.2233720368547752E18 /* min double value long */ # define DULONG_MAX 1.84467440737095504E19 /* max double value ulong */ #endif #define DULONG_MIN -0.49 /* min double value that fits in an unsigned long */ #define DULONGLONG_MAX 18446744073709551615. /* max unsigned longlong */ #define DULONGLONG_MIN -0.49 #define DLONGLONG_MAX 9.2233720368547755807E18 /* max double value longlong */ #define DLONGLONG_MIN -9.2233720368547755808E18 /* min double value longlong */ #define DUINT_MAX 4294967295.49 /* max dbl that fits in a unsigned 4-byte int */ #define DUINT_MIN -0.49 /* min dbl that fits in an unsigned 4-byte int */ #define DINT_MAX 2147483647.49 /* max double value that fits in a 4-byte int */ #define DINT_MIN -2147483648.49 /* min double value that fits in a 4-byte int */ #ifndef UINT64_MAX #define UINT64_MAX 18446744073709551615U /* max unsigned 64-bit integer */ #endif #ifndef UINT32_MAX #define UINT32_MAX 4294967295U /* max unsigned 32-bit integer */ #endif #ifndef INT32_MAX #define INT32_MAX 2147483647 /* max 32-bit integer */ #endif #ifndef INT32_MIN #define INT32_MIN (-INT32_MAX -1) /* min 32-bit integer */ #endif #define COMPRESS_NULL_VALUE -2147483647 #define N_RANDOM 10000 /* DO NOT CHANGE THIS; used when quantizing real numbers */ int ffgnky(fitsfile *fptr, char *card, int *status); void ffcfmt(char *tform, char *cform); void ffcdsp(char *tform, char *cform); void ffswap2(short *values, long nvalues); void ffswap4(INT32BIT *values, long nvalues); void ffswap8(double *values, long nvalues); int ffi2c(LONGLONG ival, char *cval, int *status); int ffu2c(ULONGLONG ival, char *cval, int *status); int ffl2c(int lval, char *cval, int *status); int ffs2c(const char *instr, char *outstr, int *status); int ffr2f(float fval, int decim, char *cval, int *status); int ffr2e(float fval, int decim, char *cval, int *status); int ffd2f(double dval, int decim, char *cval, int *status); int ffd2e(double dval, int decim, char *cval, int *status); int ffc2ii(const char *cval, long *ival, int *status); int ffc2jj(const char *cval, LONGLONG *ival, int *status); int ffc2ujj(const char *cval, ULONGLONG *ival, int *status); int ffc2ll(const char *cval, int *lval, int *status); int ffc2rr(const char *cval, float *fval, int *status); int ffc2dd(const char *cval, double *dval, int *status); int ffc2x(const char *cval, char *dtype, long *ival, int *lval, char *sval, double *dval, int *status); int ffc2xx(const char *cval, char *dtype, LONGLONG *ival, int *lval, char *sval, double *dval, int *status); int ffc2uxx(const char *cval, char *dtype, ULONGLONG *ival, int *lval, char *sval, double *dval, int *status); int ffc2s(const char *instr, char *outstr, int *status); int ffc2i(const char *cval, long *ival, int *status); int ffc2j(const char *cval, LONGLONG *ival, int *status); int ffc2uj(const char *cval, ULONGLONG *ival, int *status); int ffc2r(const char *cval, float *fval, int *status); int ffc2d(const char *cval, double *dval, int *status); int ffc2l(const char *cval, int *lval, int *status); void ffxmsg(int action, char *err_message); int ffgcnt(fitsfile *fptr, char *value, char *comm, int *status); int ffgtkn(fitsfile *fptr, int numkey, char *keyname, long *value, int *status); int ffgtknjj(fitsfile *fptr, int numkey, char *keyname, LONGLONG *value, int *status); int fftkyn(fitsfile *fptr, int numkey, char *keyname, char *value, int *status); int ffgphd(fitsfile *fptr, int maxdim, int *simple, int *bitpix, int *naxis, LONGLONG naxes[], long *pcount, long *gcount, int *extend, double *bscale, double *bzero, LONGLONG *blank, int *nspace, int *status); int ffgttb(fitsfile *fptr, LONGLONG *rowlen, LONGLONG *nrows, LONGLONG *pcount, long *tfield, int *status); int ffmkey(fitsfile *fptr, const char *card, int *status); /* ffmbyt has been moved to fitsio.h */ int ffgbyt(fitsfile *fptr, LONGLONG nbytes, void *buffer, int *status); int ffpbyt(fitsfile *fptr, LONGLONG nbytes, void *buffer, int *status); int ffgbytoff(fitsfile *fptr, long gsize, long ngroups, long offset, void *buffer, int *status); int ffpbytoff(fitsfile *fptr, long gsize, long ngroups, long offset, void *buffer, int *status); int ffldrc(fitsfile *fptr, long record, int err_mode, int *status); int ffwhbf(fitsfile *fptr, int *nbuff); int ffbfeof(fitsfile *fptr, int *status); int ffbfwt(FITSfile *Fptr, int nbuff, int *status); int ffpxsz(int datatype); int ffourl(char *url, char *urltype, char *outfile, char *tmplfile, char *compspec, int *status); int ffparsecompspec(fitsfile *fptr, char *compspec, int *status); int ffoptplt(fitsfile *fptr, const char *tempname, int *status); int fits_is_this_a_copy(char *urltype); int fits_store_Fptr(FITSfile *Fptr, int *status); int fits_clear_Fptr(FITSfile *Fptr, int *status); int fits_already_open(fitsfile **fptr, char *url, char *urltype, char *infile, char *extspec, char *rowfilter, char *binspec, char *colspec, int mode, int noextsyn, int *isopen, int *status); int ffedit_columns(fitsfile **fptr, char *outfile, char *expr, int *status); int fits_get_col_minmax(fitsfile *fptr, int colnum, double *datamin, double *datamax, int *status); int ffwritehisto(long totaln, long offset, long firstn, long nvalues, int narrays, iteratorCol *imagepars, void *userPointer); int ffcalchist(long totalrows, long offset, long firstrow, long nrows, int ncols, iteratorCol *colpars, void *userPointer); int ffpinit(fitsfile *fptr, int *status); int ffainit(fitsfile *fptr, int *status); int ffbinit(fitsfile *fptr, int *status); int ffchdu(fitsfile *fptr, int *status); int ffwend(fitsfile *fptr, int *status); int ffpdfl(fitsfile *fptr, int *status); int ffuptf(fitsfile *fptr, int *status); int ffdblk(fitsfile *fptr, long nblocks, int *status); int ffgext(fitsfile *fptr, int moveto, int *exttype, int *status); int ffgtbc(fitsfile *fptr, LONGLONG *totalwidth, int *status); int ffgtbp(fitsfile *fptr, char *name, char *value, int *status); int ffiblk(fitsfile *fptr, long nblock, int headdata, int *status); int ffshft(fitsfile *fptr, LONGLONG firstbyte, LONGLONG nbytes, LONGLONG nshift, int *status); int ffgcprll(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int writemode, double *scale, double *zero, char *tform, long *twidth, int *tcode, int *maxelem, LONGLONG *startpos, LONGLONG *elemnum, long *incre, LONGLONG *repeat, LONGLONG *rowlen, int *hdutype, LONGLONG *tnull, char *snull, int *status); int ffflushx(FITSfile *fptr); int ffseek(FITSfile *fptr, LONGLONG position); int ffread(FITSfile *fptr, long nbytes, void *buffer, int *status); int ffwrite(FITSfile *fptr, long nbytes, void *buffer, int *status); int fftrun(fitsfile *fptr, LONGLONG filesize, int *status); int ffpcluc(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int *status); int ffgcll(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int nultyp, char nulval, char *array, char *nularray, int *anynul, int *status); int ffgcls(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int nultyp, char *nulval, char **array, char *nularray, int *anynul, int *status); int ffgcls2(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int nultyp, char *nulval, char **array, char *nularray, int *anynul, int *status); int ffgclb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, unsigned char nulval, unsigned char *array, char *nularray, int *anynul, int *status); int ffgclsb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, signed char nulval, signed char *array, char *nularray, int *anynul, int *status); int ffgclui(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, unsigned short nulval, unsigned short *array, char *nularray, int *anynul, int *status); int ffgcli(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, short nulval, short *array, char *nularray, int *anynul, int *status); int ffgcluj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, unsigned long nulval, unsigned long *array, char *nularray, int *anynul, int *status); int ffgclujj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, ULONGLONG nulval, ULONGLONG *array, char *nularray, int *anynul, int *status); int ffgcljj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, LONGLONG nulval, LONGLONG *array, char *nularray, int *anynul, int *status); int ffgclj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, long nulval, long *array, char *nularray, int *anynul, int *status); int ffgcluk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, unsigned int nulval, unsigned int *array, char *nularray, int *anynul, int *status); int ffgclk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, int nulval, int *array, char *nularray, int *anynul, int *status); int ffgcle(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, float nulval, float *array, char *nularray, int *anynul, int *status); int ffgcld(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, double nulval, double *array, char *nularray, int *anynul, int *status); int ffpi1b(fitsfile *fptr, long nelem, long incre, unsigned char *buffer, int *status); int ffpi2b(fitsfile *fptr, long nelem, long incre, short *buffer, int *status); int ffpi4b(fitsfile *fptr, long nelem, long incre, INT32BIT *buffer, int *status); int ffpi8b(fitsfile *fptr, long nelem, long incre, long *buffer, int *status); int ffpr4b(fitsfile *fptr, long nelem, long incre, float *buffer, int *status); int ffpr8b(fitsfile *fptr, long nelem, long incre, double *buffer, int *status); int ffgi1b(fitsfile *fptr, LONGLONG pos, long nelem, long incre, unsigned char *buffer, int *status); int ffgi2b(fitsfile *fptr, LONGLONG pos, long nelem, long incre, short *buffer, int *status); int ffgi4b(fitsfile *fptr, LONGLONG pos, long nelem, long incre, INT32BIT *buffer, int *status); int ffgi8b(fitsfile *fptr, LONGLONG pos, long nelem, long incre, long *buffer, int *status); int ffgr4b(fitsfile *fptr, LONGLONG pos, long nelem, long incre, float *buffer, int *status); int ffgr8b(fitsfile *fptr, LONGLONG pos, long nelem, long incre, double *buffer, int *status); int ffcins(fitsfile *fptr, LONGLONG naxis1, LONGLONG naxis2, LONGLONG nbytes, LONGLONG bytepos, int *status); int ffcdel(fitsfile *fptr, LONGLONG naxis1, LONGLONG naxis2, LONGLONG nbytes, LONGLONG bytepos, int *status); int ffkshf(fitsfile *fptr, int firstcol, int tfields, int nshift, int *status); int fffvcl(fitsfile *fptr, int *nvarcols, int *colnums, int *status); int fffi1i1(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, unsigned char nullval, char *nullarray, int *anynull, unsigned char *output, int *status); int fffi2i1(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, unsigned char nullval, char *nullarray, int *anynull, unsigned char *output, int *status); int fffi4i1(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, unsigned char nullval, char *nullarray, int *anynull, unsigned char *output, int *status); int fffi8i1(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, unsigned char nullval, char *nullarray, int *anynull, unsigned char *output, int *status); int fffr4i1(float *input, long ntodo, double scale, double zero, int nullcheck, unsigned char nullval, char *nullarray, int *anynull, unsigned char *output, int *status); int fffr8i1(double *input, long ntodo, double scale, double zero, int nullcheck, unsigned char nullval, char *nullarray, int *anynull, unsigned char *output, int *status); int fffstri1(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, unsigned char nullval, char *nullarray, int *anynull, unsigned char *output, int *status); int fffi1s1(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, signed char nullval, char *nullarray, int *anynull, signed char *output, int *status); int fffi2s1(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, signed char nullval, char *nullarray, int *anynull, signed char *output, int *status); int fffi4s1(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, signed char nullval, char *nullarray, int *anynull, signed char *output, int *status); int fffi8s1(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, signed char nullval, char *nullarray, int *anynull, signed char *output, int *status); int fffr4s1(float *input, long ntodo, double scale, double zero, int nullcheck, signed char nullval, char *nullarray, int *anynull, signed char *output, int *status); int fffr8s1(double *input, long ntodo, double scale, double zero, int nullcheck, signed char nullval, char *nullarray, int *anynull, signed char *output, int *status); int fffstrs1(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, signed char nullval, char *nullarray, int *anynull, signed char *output, int *status); int fffi1u2(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, unsigned short nullval, char *nullarray, int *anynull, unsigned short *output, int *status); int fffi2u2(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, unsigned short nullval, char *nullarray, int *anynull, unsigned short *output, int *status); int fffi4u2(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, unsigned short nullval, char *nullarray, int *anynull, unsigned short *output, int *status); int fffi8u2(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, unsigned short nullval, char *nullarray, int *anynull, unsigned short *output, int *status); int fffr4u2(float *input, long ntodo, double scale, double zero, int nullcheck, unsigned short nullval, char *nullarray, int *anynull, unsigned short *output, int *status); int fffr8u2(double *input, long ntodo, double scale, double zero, int nullcheck, unsigned short nullval, char *nullarray, int *anynull, unsigned short *output, int *status); int fffstru2(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, unsigned short nullval, char *nullarray, int *anynull, unsigned short *output, int *status); int fffi1i2(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, short nullval, char *nullarray, int *anynull, short *output, int *status); int fffi2i2(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, short nullval, char *nullarray, int *anynull, short *output, int *status); int fffi4i2(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, short nullval, char *nullarray, int *anynull, short *output, int *status); int fffi8i2(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, short nullval, char *nullarray, int *anynull, short *output, int *status); int fffr4i2(float *input, long ntodo, double scale, double zero, int nullcheck, short nullval, char *nullarray, int *anynull, short *output, int *status); int fffr8i2(double *input, long ntodo, double scale, double zero, int nullcheck, short nullval, char *nullarray, int *anynull, short *output, int *status); int fffstri2(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, short nullval, char *nullarray, int *anynull, short *output, int *status); int fffi1u4(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, unsigned long nullval, char *nullarray, int *anynull, unsigned long *output, int *status); int fffi2u4(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, unsigned long nullval, char *nullarray, int *anynull, unsigned long *output, int *status); int fffi4u4(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, unsigned long nullval, char *nullarray, int *anynull, unsigned long *output, int *status); int fffi8u4(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, unsigned long nullval, char *nullarray, int *anynull, unsigned long *output, int *status); int fffr4u4(float *input, long ntodo, double scale, double zero, int nullcheck, unsigned long nullval, char *nullarray, int *anynull, unsigned long *output, int *status); int fffr8u4(double *input, long ntodo, double scale, double zero, int nullcheck, unsigned long nullval, char *nullarray, int *anynull, unsigned long *output, int *status); int fffstru4(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, unsigned long nullval, char *nullarray, int *anynull, unsigned long *output, int *status); int fffi1i4(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, long nullval, char *nullarray, int *anynull, long *output, int *status); int fffi2i4(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, long nullval, char *nullarray, int *anynull, long *output, int *status); int fffi4i4(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, long nullval, char *nullarray, int *anynull, long *output, int *status); int fffi8i4(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, long nullval, char *nullarray, int *anynull, long *output, int *status); int fffr4i4(float *input, long ntodo, double scale, double zero, int nullcheck, long nullval, char *nullarray, int *anynull, long *output, int *status); int fffr8i4(double *input, long ntodo, double scale, double zero, int nullcheck, long nullval, char *nullarray, int *anynull, long *output, int *status); int fffstri4(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, long nullval, char *nullarray, int *anynull, long *output, int *status); int fffi1int(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, int nullval, char *nullarray, int *anynull, int *output, int *status); int fffi2int(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, int nullval, char *nullarray, int *anynull, int *output, int *status); int fffi4int(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, int nullval, char *nullarray, int *anynull, int *output, int *status); int fffi8int(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, int nullval, char *nullarray, int *anynull, int *output, int *status); int fffr4int(float *input, long ntodo, double scale, double zero, int nullcheck, int nullval, char *nullarray, int *anynull, int *output, int *status); int fffr8int(double *input, long ntodo, double scale, double zero, int nullcheck, int nullval, char *nullarray, int *anynull, int *output, int *status); int fffstrint(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, int nullval, char *nullarray, int *anynull, int *output, int *status); int fffi1uint(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, unsigned int nullval, char *nullarray, int *anynull, unsigned int *output, int *status); int fffi2uint(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, unsigned int nullval, char *nullarray, int *anynull, unsigned int *output, int *status); int fffi4uint(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, unsigned int nullval, char *nullarray, int *anynull, unsigned int *output, int *status); int fffi8uint(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, unsigned int nullval, char *nullarray, int *anynull, unsigned int *output, int *status); int fffr4uint(float *input, long ntodo, double scale, double zero, int nullcheck, unsigned int nullval, char *nullarray, int *anynull, unsigned int *output, int *status); int fffr8uint(double *input, long ntodo, double scale, double zero, int nullcheck, unsigned int nullval, char *nullarray, int *anynull, unsigned int *output, int *status); int fffstruint(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, unsigned int nullval, char *nullarray, int *anynull, unsigned int *output, int *status); int fffi1i8(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, LONGLONG nullval, char *nullarray, int *anynull, LONGLONG *output, int *status); int fffi2i8(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, LONGLONG nullval, char *nullarray, int *anynull, LONGLONG *output, int *status); int fffi4i8(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, LONGLONG nullval, char *nullarray, int *anynull, LONGLONG *output, int *status); int fffi8i8(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, LONGLONG nullval, char *nullarray, int *anynull, LONGLONG *output, int *status); int fffr4i8(float *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG nullval, char *nullarray, int *anynull, LONGLONG *output, int *status); int fffr8i8(double *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG nullval, char *nullarray, int *anynull, LONGLONG *output, int *status); int fffstri8(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, LONGLONG nullval, char *nullarray, int *anynull, LONGLONG *output, int *status); int fffi1u8(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, ULONGLONG nullval, char *nullarray, int *anynull, ULONGLONG *output, int *status); int fffi2u8(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, ULONGLONG nullval, char *nullarray, int *anynull, ULONGLONG *output, int *status); int fffi4u8(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, ULONGLONG nullval, char *nullarray, int *anynull, ULONGLONG *output, int *status); int fffi8u8(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, ULONGLONG nullval, char *nullarray, int *anynull, ULONGLONG *output, int *status); int fffr4u8(float *input, long ntodo, double scale, double zero, int nullcheck, ULONGLONG nullval, char *nullarray, int *anynull, ULONGLONG *output, int *status); int fffr8u8(double *input, long ntodo, double scale, double zero, int nullcheck, ULONGLONG nullval, char *nullarray, int *anynull, ULONGLONG *output, int *status); int fffstru8(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, ULONGLONG nullval, char *nullarray, int *anynull, ULONGLONG *output, int *status); int fffi1r4(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, float nullval, char *nullarray, int *anynull, float *output, int *status); int fffi2r4(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, float nullval, char *nullarray, int *anynull, float *output, int *status); int fffi4r4(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, float nullval, char *nullarray, int *anynull, float *output, int *status); int fffi8r4(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, float nullval, char *nullarray, int *anynull, float *output, int *status); int fffr4r4(float *input, long ntodo, double scale, double zero, int nullcheck, float nullval, char *nullarray, int *anynull, float *output, int *status); int fffr8r4(double *input, long ntodo, double scale, double zero, int nullcheck, float nullval, char *nullarray, int *anynull, float *output, int *status); int fffstrr4(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, float nullval, char *nullarray, int *anynull, float *output, int *status); int fffi1r8(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, double nullval, char *nullarray, int *anynull, double *output, int *status); int fffi2r8(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, double nullval, char *nullarray, int *anynull, double *output, int *status); int fffi4r8(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, double nullval, char *nullarray, int *anynull, double *output, int *status); int fffi8r8(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, double nullval, char *nullarray, int *anynull, double *output, int *status); int fffr4r8(float *input, long ntodo, double scale, double zero, int nullcheck, double nullval, char *nullarray, int *anynull, double *output, int *status); int fffr8r8(double *input, long ntodo, double scale, double zero, int nullcheck, double nullval, char *nullarray, int *anynull, double *output, int *status); int fffstrr8(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, double nullval, char *nullarray, int *anynull, double *output, int *status); int ffi1fi1(unsigned char *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffs1fi1(signed char *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffu2fi1(unsigned short *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffi2fi1(short *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffu4fi1(unsigned long *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffi4fi1(long *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffu8fi1(ULONGLONG *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffi8fi1(LONGLONG *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffuintfi1(unsigned int *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffintfi1(int *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffr4fi1(float *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffr8fi1(double *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffi1fi2(unsigned char *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffs1fi2(signed char *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffu2fi2(unsigned short *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffi2fi2(short *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffu4fi2(unsigned long *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffi4fi2(long *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffu8fi2(ULONGLONG *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffi8fi2(LONGLONG *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffuintfi2(unsigned int *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffintfi2(int *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffr4fi2(float *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffr8fi2(double *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffi1fi4(unsigned char *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffs1fi4(signed char *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffu2fi4(unsigned short *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffi2fi4(short *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffu4fi4(unsigned long *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffu8fi4(ULONGLONG *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffi4fi4(long *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffi8fi4(LONGLONG *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffuintfi4(unsigned int *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffintfi4(int *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffr4fi4(float *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffr8fi4(double *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffi4fi8(long *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffi8fi8(LONGLONG *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffi2fi8(short *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffi1fi8(unsigned char *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffs1fi8(signed char *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffr4fi8(float *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffr8fi8(double *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffintfi8(int *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffu2fi8(unsigned short *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffu4fi8(unsigned long *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffu8fi8(ULONGLONG *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffuintfi8(unsigned int *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffi1fr4(unsigned char *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffs1fr4(signed char *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffu2fr4(unsigned short *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffi2fr4(short *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffu4fr4(unsigned long *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffi4fr4(long *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffu8fr4(ULONGLONG *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffi8fr4(LONGLONG *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffuintfr4(unsigned int *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffintfr4(int *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffr4fr4(float *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffr8fr4(double *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffi1fr8(unsigned char *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffs1fr8(signed char *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffu2fr8(unsigned short *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffi2fr8(short *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffu4fr8(unsigned long *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffi4fr8(long *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffu8fr8(ULONGLONG *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffi8fr8(LONGLONG *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffuintfr8(unsigned int *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffintfr8(int *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffr4fr8(float *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffr8fr8(double *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffi1fstr(unsigned char *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffs1fstr(signed char *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffu2fstr(unsigned short *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffi2fstr(short *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffu4fstr(unsigned long *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffi4fstr(long *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffu8fstr(ULONGLONG *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffi8fstr(LONGLONG *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffintfstr(int *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffuintfstr(unsigned int *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffr4fstr(float *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffr8fstr(double *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); /* the following 4 routines are VMS macros used on VAX or Alpha VMS */ void ieevpd(double *inarray, double *outarray, long *nvals); void ieevud(double *inarray, double *outarray, long *nvals); void ieevpr(float *inarray, float *outarray, long *nvals); void ieevur(float *inarray, float *outarray, long *nvals); /* routines related to the lexical parser */ int ffselect_table(fitsfile **fptr, char *outfile, char *expr, int *status); int ffiprs( fitsfile *fptr, int compressed, char *expr, int maxdim, int *datatype, long *nelem, int *naxis, long *naxes, int *status ); void ffcprs( void ); int ffcvtn( int inputType, void *input, char *undef, long ntodo, int outputType, void *nulval, void *output, int *anynull, int *status ); int parse_data( long totalrows, long offset, long firstrow, long nrows, int nCols, iteratorCol *colData, void *userPtr ); int uncompress_hkdata( fitsfile *fptr, long ntimes, double *times, int *status ); int ffffrw_work( long totalrows, long offset, long firstrow, long nrows, int nCols, iteratorCol *colData, void *userPtr ); int fits_translate_pixkeyword(char *inrec, char *outrec,char *patterns[][2], int npat, int naxis, int *colnum, int *pat_num, int *i, int *j, int *n, int *m, int *l, int *status); /* image compression routines */ int fits_write_compressed_img(fitsfile *fptr, int datatype, long *fpixel, long *lpixel, int nullcheck, void *array, void *nulval, int *status); int fits_write_compressed_pixels(fitsfile *fptr, int datatype, LONGLONG fpixel, LONGLONG npixels, int nullcheck, void *array, void *nulval, int *status); int fits_write_compressed_img_plane(fitsfile *fptr, int datatype, int bytesperpixel, long nplane, long *firstcoord, long *lastcoord, long *naxes, int nullcheck, void *array, void *nullval, long *nread, int *status); int imcomp_init_table(fitsfile *outfptr, int bitpix, int naxis,long *naxes, int writebitpix, int *status); int imcomp_calc_max_elem (int comptype, int nx, int zbitpix, int blocksize); int imcomp_copy_imheader(fitsfile *infptr, fitsfile *outfptr, int *status); int imcomp_copy_img2comp(fitsfile *infptr, fitsfile *outfptr, int *status); int imcomp_copy_comp2img(fitsfile *infptr, fitsfile *outfptr, int norec, int *status); int imcomp_copy_prime2img(fitsfile *infptr, fitsfile *outfptr, int *status); int imcomp_compress_image (fitsfile *infptr, fitsfile *outfptr, int *status); int imcomp_compress_tile (fitsfile *outfptr, long row, int datatype, void *tiledata, long tilelen, long nx, long ny, int nullcheck, void *nullval, int *status); int imcomp_nullscale(int *idata, long tilelen, int nullflagval, int nullval, double scale, double zero, int * status); int imcomp_nullvalues(int *idata, long tilelen, int nullflagval, int nullval, int * status); int imcomp_scalevalues(int *idata, long tilelen, double scale, double zero, int * status); int imcomp_nullscalefloats(float *fdata, long tilelen, int *idata, double scale, double zero, int nullcheck, float nullflagval, int nullval, int *status); int imcomp_nullfloats(float *fdata, long tilelen, int *idata, int nullcheck, float nullflagval, int nullval, int *status); int imcomp_nullscaledoubles(double *fdata, long tilelen, int *idata, double scale, double zero, int nullcheck, double nullflagval, int nullval, int *status); int imcomp_nulldoubles(double *fdata, long tilelen, int *idata, int nullcheck, double nullflagval, int nullval, int *status); /* image decompression routines */ int fits_read_compressed_img(fitsfile *fptr, int datatype, LONGLONG *fpixel,LONGLONG *lpixel,long *inc, int nullcheck, void *nulval, void *array, char *nullarray, int *anynul, int *status); int fits_read_compressed_pixels(fitsfile *fptr, int datatype, LONGLONG fpixel, LONGLONG npixels, int nullcheck, void *nulval, void *array, char *nullarray, int *anynul, int *status); int fits_read_compressed_img_plane(fitsfile *fptr, int datatype, int bytesperpixel, long nplane, LONGLONG *firstcoord, LONGLONG *lastcoord, long *inc, long *naxes, int nullcheck, void *nullval, void *array, char *nullarray, int *anynul, long *nread, int *status); int imcomp_get_compressed_image_par(fitsfile *infptr, int *status); int imcomp_decompress_tile (fitsfile *infptr, int nrow, int tilesize, int datatype, int nullcheck, void *nulval, void *buffer, char *bnullarray, int *anynul, int *status); int imcomp_copy_overlap (char *tile, int pixlen, int ndim, long *tfpixel, long *tlpixel, char *bnullarray, char *image, long *fpixel, long *lpixel, long *inc, int nullcheck, char *nullarray, int *status); int imcomp_test_overlap (int ndim, long *tfpixel, long *tlpixel, long *fpixel, long *lpixel, long *inc, int *status); int imcomp_merge_overlap (char *tile, int pixlen, int ndim, long *tfpixel, long *tlpixel, char *bnullarray, char *image, long *fpixel, long *lpixel, int nullcheck, int *status); int imcomp_decompress_img(fitsfile *infptr, fitsfile *outfptr, int datatype, int *status); int fits_quantize_float (long row, float fdata[], long nx, long ny, int nullcheck, float in_null_value, float quantize_level, int dither_method, int idata[], double *bscale, double *bzero, int *iminval, int *imaxval); int fits_quantize_double (long row, double fdata[], long nx, long ny, int nullcheck, double in_null_value, float quantize_level, int dither_method, int idata[], double *bscale, double *bzero, int *iminval, int *imaxval); int fits_rcomp(int a[], int nx, unsigned char *c, int clen,int nblock); int fits_rcomp_short(short a[], int nx, unsigned char *c, int clen,int nblock); int fits_rcomp_byte(signed char a[], int nx, unsigned char *c, int clen,int nblock); int fits_rdecomp (unsigned char *c, int clen, unsigned int array[], int nx, int nblock); int fits_rdecomp_short (unsigned char *c, int clen, unsigned short array[], int nx, int nblock); int fits_rdecomp_byte (unsigned char *c, int clen, unsigned char array[], int nx, int nblock); int pl_p2li (int *pxsrc, int xs, short *lldst, int npix); int pl_l2pi (short *ll_src, int xs, int *px_dst, int npix); int fits_init_randoms(void); int fits_unset_compression_param( fitsfile *fptr, int *status); int fits_unset_compression_request( fitsfile *fptr, int *status); int fitsio_init_lock(void); /* general driver routines */ int urltype2driver(char *urltype, int *driver); void fits_dwnld_prog_bar(int flag); int fits_net_timeout(int sec); int fits_register_driver( char *prefix, int (*init)(void), int (*fitsshutdown)(void), int (*setoptions)(int option), int (*getoptions)(int *options), int (*getversion)(int *version), int (*checkfile) (char *urltype, char *infile, char *outfile), int (*fitsopen)(char *filename, int rwmode, int *driverhandle), int (*fitscreate)(char *filename, int *driverhandle), int (*fitstruncate)(int driverhandle, LONGLONG filesize), int (*fitsclose)(int driverhandle), int (*fremove)(char *filename), int (*size)(int driverhandle, LONGLONG *sizex), int (*flush)(int driverhandle), int (*seek)(int driverhandle, LONGLONG offset), int (*fitsread) (int driverhandle, void *buffer, long nbytes), int (*fitswrite)(int driverhandle, void *buffer, long nbytes)); /* file driver I/O routines */ int file_init(void); int file_setoptions(int options); int file_getoptions(int *options); int file_getversion(int *version); int file_shutdown(void); int file_checkfile(char *urltype, char *infile, char *outfile); int file_open(char *filename, int rwmode, int *driverhandle); int file_compress_open(char *filename, int rwmode, int *hdl); int file_openfile(char *filename, int rwmode, FILE **diskfile); int file_create(char *filename, int *driverhandle); int file_truncate(int driverhandle, LONGLONG filesize); int file_size(int driverhandle, LONGLONG *filesize); int file_close(int driverhandle); int file_remove(char *filename); int file_flush(int driverhandle); int file_seek(int driverhandle, LONGLONG offset); int file_read (int driverhandle, void *buffer, long nbytes); int file_write(int driverhandle, void *buffer, long nbytes); int file_is_compressed(char *filename); /* stream driver I/O routines */ int stream_open(char *filename, int rwmode, int *driverhandle); int stream_create(char *filename, int *driverhandle); int stream_size(int driverhandle, LONGLONG *filesize); int stream_close(int driverhandle); int stream_flush(int driverhandle); int stream_seek(int driverhandle, LONGLONG offset); int stream_read (int driverhandle, void *buffer, long nbytes); int stream_write(int driverhandle, void *buffer, long nbytes); /* memory driver I/O routines */ int mem_init(void); int mem_setoptions(int options); int mem_getoptions(int *options); int mem_getversion(int *version); int mem_shutdown(void); int mem_create(char *filename, int *handle); int mem_create_comp(char *filename, int *handle); int mem_openmem(void **buffptr, size_t *buffsize, size_t deltasize, void *(*memrealloc)(void *p, size_t newsize), int *handle); int mem_createmem(size_t memsize, int *handle); int stdin_checkfile(char *urltype, char *infile, char *outfile); int stdin_open(char *filename, int rwmode, int *handle); int stdin2mem(int hd); int stdin2file(int hd); int stdout_close(int handle); int mem_compress_openrw(char *filename, int rwmode, int *hdl); int mem_compress_open(char *filename, int rwmode, int *hdl); int mem_compress_stdin_open(char *filename, int rwmode, int *hdl); int mem_iraf_open(char *filename, int rwmode, int *hdl); int mem_rawfile_open(char *filename, int rwmode, int *hdl); int mem_size(int handle, LONGLONG *filesize); int mem_truncate(int handle, LONGLONG filesize); int mem_close_free(int handle); int mem_close_keep(int handle); int mem_close_comp(int handle); int mem_seek(int handle, LONGLONG offset); int mem_read(int hdl, void *buffer, long nbytes); int mem_write(int hdl, void *buffer, long nbytes); int mem_uncompress2mem(char *filename, FILE *diskfile, int hdl); int iraf2mem(char *filename, char **buffptr, size_t *buffsize, size_t *filesize, int *status); /* root driver I/O routines */ int root_init(void); int root_setoptions(int options); int root_getoptions(int *options); int root_getversion(int *version); int root_shutdown(void); int root_open(char *filename, int rwmode, int *driverhandle); int root_create(char *filename, int *driverhandle); int root_close(int driverhandle); int root_flush(int driverhandle); int root_seek(int driverhandle, LONGLONG offset); int root_read (int driverhandle, void *buffer, long nbytes); int root_write(int driverhandle, void *buffer, long nbytes); int root_size(int handle, LONGLONG *filesize); /* http driver I/O routines */ int http_checkfile(char *urltype, char *infile, char *outfile); int http_open(char *filename, int rwmode, int *driverhandle); int http_file_open(char *filename, int rwmode, int *driverhandle); int http_compress_open(char *filename, int rwmode, int *driverhandle); /* https driver I/O routines */ int https_checkfile(char* urltype, char *infile, char *outfile); int https_open(char *filename, int rwmode, int *driverhandle); int https_file_open(char *filename, int rwmode, int *driverhandle); void https_set_verbose(int flag); /* ftps driver I/O routines */ int ftps_checkfile(char* urltype, char *infile, char *outfile); int ftps_open(char *filename, int rwmode, int *handle); int ftps_file_open(char *filename, int rwmode, int *handle); int ftps_compress_open(char *filename, int rwmode, int *driverhandle); /* ftp driver I/O routines */ int ftp_checkfile(char *urltype, char *infile, char *outfile); int ftp_open(char *filename, int rwmode, int *driverhandle); int ftp_file_open(char *filename, int rwmode, int *driverhandle); int ftp_compress_open(char *filename, int rwmode, int *driverhandle); int uncompress2mem(char *filename, FILE *diskfile, char **buffptr, size_t *buffsize, void *(*mem_realloc)(void *p, size_t newsize), size_t *filesize, int *status); int uncompress2mem_from_mem( char *inmemptr, size_t inmemsize, char **buffptr, size_t *buffsize, void *(*mem_realloc)(void *p, size_t newsize), size_t *filesize, int *status); int uncompress2file(char *filename, FILE *indiskfile, FILE *outdiskfile, int *status); int compress2mem_from_mem( char *inmemptr, size_t inmemsize, char **buffptr, size_t *buffsize, void *(*mem_realloc)(void *p, size_t newsize), size_t *filesize, int *status); int compress2file_from_mem( char *inmemptr, size_t inmemsize, FILE *outdiskfile, size_t *filesize, /* O - size of file, in bytes */ int *status); #ifdef HAVE_GSIFTP /* prototypes for gsiftp driver I/O routines */ #include "drvrgsiftp.h" #endif #ifdef HAVE_SHMEM_SERVICES /* prototypes for shared memory driver I/O routines */ #include "drvrsmem.h" #endif /* A hack for nonunix machines, which lack strcasecmp and strncasecmp */ /* these functions are in fitscore.c */ int fits_strcasecmp (const char *s1, const char *s2 ); int fits_strncasecmp(const char *s1, const char *s2, size_t n); /* end of the entire "ifndef _FITSIO2_H" block */ #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/getcol.c0000644000175100001710000012110600000000000017545 0ustar00vstsdocker /* This file, getcol.c, contains routines that read data elements from */ /* a FITS image or table. There are generic datatype routines. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpxv( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ long *firstpix, /* I - coord of first pixel to read (1s based) */ LONGLONG nelem, /* I - number of values to read */ void *nulval, /* I - value for undefined pixels */ void *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { LONGLONG tfirstpix[99]; int naxis, ii; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* get the size of the image */ ffgidm(fptr, &naxis, status); for (ii=0; ii < naxis; ii++) tfirstpix[ii] = firstpix[ii]; ffgpxvll(fptr, datatype, tfirstpix, nelem, nulval, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpxvll( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ LONGLONG *firstpix, /* I - coord of first pixel to read (1s based) */ LONGLONG nelem, /* I - number of values to read */ void *nulval, /* I - value for undefined pixels */ void *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { int naxis, ii; char cdummy; int nullcheck = 1; LONGLONG naxes[9], trc[9]= {1,1,1,1,1,1,1,1,1}; long inc[9]= {1,1,1,1,1,1,1,1,1}; LONGLONG dimsize = 1, firstelem; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* get the size of the image */ ffgidm(fptr, &naxis, status); ffgiszll(fptr, 9, naxes, status); if (naxis == 0 || naxes[0] == 0) { *status = BAD_DIMEN; return(*status); } /* calculate the position of the first element in the array */ firstelem = 0; for (ii=0; ii < naxis; ii++) { firstelem += ((firstpix[ii] - 1) * dimsize); dimsize *= naxes[ii]; trc[ii] = firstpix[ii]; } firstelem++; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ /* test for special case of reading an integral number of */ /* rows in a 2D or 3D image (which includes reading the whole image */ if (naxis > 1 && naxis < 4 && firstpix[0] == 1 && (nelem / naxes[0]) * naxes[0] == nelem) { /* calculate coordinate of last pixel */ trc[0] = naxes[0]; /* reading whole rows */ trc[1] = firstpix[1] + (nelem / naxes[0] - 1); while (trc[1] > naxes[1]) { trc[1] = trc[1] - naxes[1]; trc[2] = trc[2] + 1; /* increment to next plane of cube */ } fits_read_compressed_img(fptr, datatype, firstpix, trc, inc, 1, nulval, array, NULL, anynul, status); } else { fits_read_compressed_pixels(fptr, datatype, firstelem, nelem, nullcheck, nulval, array, NULL, anynul, status); } return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (datatype == TBYTE) { if (nulval == 0) ffgclb(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (unsigned char *) array, &cdummy, anynul, status); else ffgclb(fptr, 2, 1, firstelem, nelem, 1, 1, *(unsigned char *) nulval, (unsigned char *) array, &cdummy, anynul, status); } else if (datatype == TSBYTE) { if (nulval == 0) ffgclsb(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (signed char *) array, &cdummy, anynul, status); else ffgclsb(fptr, 2, 1, firstelem, nelem, 1, 1, *(signed char *) nulval, (signed char *) array, &cdummy, anynul, status); } else if (datatype == TUSHORT) { if (nulval == 0) ffgclui(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (unsigned short *) array, &cdummy, anynul, status); else ffgclui(fptr, 2, 1, firstelem, nelem, 1, 1, *(unsigned short *) nulval, (unsigned short *) array, &cdummy, anynul, status); } else if (datatype == TSHORT) { if (nulval == 0) ffgcli(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (short *) array, &cdummy, anynul, status); else ffgcli(fptr, 2, 1, firstelem, nelem, 1, 1, *(short *) nulval, (short *) array, &cdummy, anynul, status); } else if (datatype == TUINT) { if (nulval == 0) ffgcluk(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (unsigned int *) array, &cdummy, anynul, status); else ffgcluk(fptr, 2, 1, firstelem, nelem, 1, 1, *(unsigned int *) nulval, (unsigned int *) array, &cdummy, anynul, status); } else if (datatype == TINT) { if (nulval == 0) ffgclk(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (int *) array, &cdummy, anynul, status); else ffgclk(fptr, 2, 1, firstelem, nelem, 1, 1, *(int *) nulval, (int *) array, &cdummy, anynul, status); } else if (datatype == TULONG) { if (nulval == 0) ffgcluj(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (unsigned long *) array, &cdummy, anynul, status); else ffgcluj(fptr, 2, 1, firstelem, nelem, 1, 1, *(unsigned long *) nulval, (unsigned long *) array, &cdummy, anynul, status); } else if (datatype == TLONG) { if (nulval == 0) ffgclj(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (long *) array, &cdummy, anynul, status); else ffgclj(fptr, 2, 1, firstelem, nelem, 1, 1, *(long *) nulval, (long *) array, &cdummy, anynul, status); } else if (datatype == TULONGLONG) { if (nulval == 0) ffgclujj(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (ULONGLONG *) array, &cdummy, anynul, status); else ffgclujj(fptr, 2, 1, firstelem, nelem, 1, 1, *(ULONGLONG *) nulval, (ULONGLONG *) array, &cdummy, anynul, status); } else if (datatype == TLONGLONG) { if (nulval == 0) ffgcljj(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (LONGLONG *) array, &cdummy, anynul, status); else ffgcljj(fptr, 2, 1, firstelem, nelem, 1, 1, *(LONGLONG *) nulval, (LONGLONG *) array, &cdummy, anynul, status); } else if (datatype == TFLOAT) { if (nulval == 0) ffgcle(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (float *) array, &cdummy, anynul, status); else ffgcle(fptr, 2, 1, firstelem, nelem, 1, 1, *(float *) nulval, (float *) array, &cdummy, anynul, status); } else if (datatype == TDOUBLE) { if (nulval == 0) ffgcld(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (double *) array, &cdummy, anynul, status); else ffgcld(fptr, 2, 1, firstelem, nelem, 1, 1, *(double *) nulval, (double *) array, &cdummy, anynul, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffgpxf( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ long *firstpix, /* I - coord of first pixel to read (1s based) */ LONGLONG nelem, /* I - number of values to read */ void *array, /* O - array of values that are returned */ char *nullarray, /* O - returned array of null value flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). The nullarray values will = 1 if the corresponding array value is null. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { LONGLONG tfirstpix[99]; int naxis, ii; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* get the size of the image */ ffgidm(fptr, &naxis, status); for (ii=0; ii < naxis; ii++) tfirstpix[ii] = firstpix[ii]; ffgpxfll(fptr, datatype, tfirstpix, nelem, array, nullarray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpxfll( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ LONGLONG *firstpix, /* I - coord of first pixel to read (1s based) */ LONGLONG nelem, /* I - number of values to read */ void *array, /* O - array of values that are returned */ char *nullarray, /* O - returned array of null value flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). The nullarray values will = 1 if the corresponding array value is null. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { int naxis, ii; int nullcheck = 2; LONGLONG naxes[9]; LONGLONG dimsize = 1, firstelem; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* get the size of the image */ ffgidm(fptr, &naxis, status); ffgiszll(fptr, 9, naxes, status); /* calculate the position of the first element in the array */ firstelem = 0; for (ii=0; ii < naxis; ii++) { firstelem += ((firstpix[ii] - 1) * dimsize); dimsize *= naxes[ii]; } firstelem++; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, datatype, firstelem, nelem, nullcheck, NULL, array, nullarray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (datatype == TBYTE) { ffgclb(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (unsigned char *) array, nullarray, anynul, status); } else if (datatype == TSBYTE) { ffgclsb(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (signed char *) array, nullarray, anynul, status); } else if (datatype == TUSHORT) { ffgclui(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (unsigned short *) array, nullarray, anynul, status); } else if (datatype == TSHORT) { ffgcli(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (short *) array, nullarray, anynul, status); } else if (datatype == TUINT) { ffgcluk(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (unsigned int *) array, nullarray, anynul, status); } else if (datatype == TINT) { ffgclk(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (int *) array, nullarray, anynul, status); } else if (datatype == TULONG) { ffgcluj(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (unsigned long *) array, nullarray, anynul, status); } else if (datatype == TLONG) { ffgclj(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (long *) array, nullarray, anynul, status); } else if (datatype == TULONGLONG) { ffgclujj(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (ULONGLONG *) array, nullarray, anynul, status); } else if (datatype == TLONGLONG) { ffgcljj(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (LONGLONG *) array, nullarray, anynul, status); } else if (datatype == TFLOAT) { ffgcle(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (float *) array, nullarray, anynul, status); } else if (datatype == TDOUBLE) { ffgcld(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (double *) array, nullarray, anynul, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffgsv( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc , /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dim. */ void *nulval, /* I - value for undefined pixels */ void *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an section of values from the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { int naxis, ii; long naxes[9]; LONGLONG nelem = 1; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* get the size of the image */ ffgidm(fptr, &naxis, status); ffgisz(fptr, 9, naxes, status); /* test for the important special case where we are reading the whole image */ /* this is only useful for images that are not tile-compressed */ if (!fits_is_compressed_image(fptr, status)) { for (ii = 0; ii < naxis; ii++) { if (inc[ii] != 1 || blc[ii] !=1 || trc[ii] != naxes[ii]) break; nelem = nelem * naxes[ii]; } if (ii == naxis) { /* read the whole image more efficiently */ ffgpxv(fptr, datatype, blc, nelem, nulval, array, anynul, status); return(*status); } } if (datatype == TBYTE) { if (nulval == 0) ffgsvb(fptr, 1, naxis, naxes, blc, trc, inc, 0, (unsigned char *) array, anynul, status); else ffgsvb(fptr, 1, naxis, naxes, blc, trc, inc, *(unsigned char *) nulval, (unsigned char *) array, anynul, status); } else if (datatype == TSBYTE) { if (nulval == 0) ffgsvsb(fptr, 1, naxis, naxes, blc, trc, inc, 0, (signed char *) array, anynul, status); else ffgsvsb(fptr, 1, naxis, naxes, blc, trc, inc, *(signed char *) nulval, (signed char *) array, anynul, status); } else if (datatype == TUSHORT) { if (nulval == 0) ffgsvui(fptr, 1, naxis, naxes, blc, trc, inc, 0, (unsigned short *) array, anynul, status); else ffgsvui(fptr, 1, naxis, naxes,blc, trc, inc, *(unsigned short *) nulval, (unsigned short *) array, anynul, status); } else if (datatype == TSHORT) { if (nulval == 0) ffgsvi(fptr, 1, naxis, naxes, blc, trc, inc, 0, (short *) array, anynul, status); else ffgsvi(fptr, 1, naxis, naxes, blc, trc, inc, *(short *) nulval, (short *) array, anynul, status); } else if (datatype == TUINT) { if (nulval == 0) ffgsvuk(fptr, 1, naxis, naxes, blc, trc, inc, 0, (unsigned int *) array, anynul, status); else ffgsvuk(fptr, 1, naxis, naxes, blc, trc, inc, *(unsigned int *) nulval, (unsigned int *) array, anynul, status); } else if (datatype == TINT) { if (nulval == 0) ffgsvk(fptr, 1, naxis, naxes, blc, trc, inc, 0, (int *) array, anynul, status); else ffgsvk(fptr, 1, naxis, naxes, blc, trc, inc, *(int *) nulval, (int *) array, anynul, status); } else if (datatype == TULONG) { if (nulval == 0) ffgsvuj(fptr, 1, naxis, naxes, blc, trc, inc, 0, (unsigned long *) array, anynul, status); else ffgsvuj(fptr, 1, naxis, naxes, blc, trc, inc, *(unsigned long *) nulval, (unsigned long *) array, anynul, status); } else if (datatype == TLONG) { if (nulval == 0) ffgsvj(fptr, 1, naxis, naxes, blc, trc, inc, 0, (long *) array, anynul, status); else ffgsvj(fptr, 1, naxis, naxes, blc, trc, inc, *(long *) nulval, (long *) array, anynul, status); } else if (datatype == TULONGLONG) { if (nulval == 0) ffgsvujj(fptr, 1, naxis, naxes, blc, trc, inc, 0, (ULONGLONG *) array, anynul, status); else ffgsvujj(fptr, 1, naxis, naxes, blc, trc, inc, *(ULONGLONG *) nulval, (ULONGLONG *) array, anynul, status); } else if (datatype == TLONGLONG) { if (nulval == 0) ffgsvjj(fptr, 1, naxis, naxes, blc, trc, inc, 0, (LONGLONG *) array, anynul, status); else ffgsvjj(fptr, 1, naxis, naxes, blc, trc, inc, *(LONGLONG *) nulval, (LONGLONG *) array, anynul, status); } else if (datatype == TFLOAT) { if (nulval == 0) ffgsve(fptr, 1, naxis, naxes, blc, trc, inc, 0, (float *) array, anynul, status); else ffgsve(fptr, 1, naxis, naxes, blc, trc, inc, *(float *) nulval, (float *) array, anynul, status); } else if (datatype == TDOUBLE) { if (nulval == 0) ffgsvd(fptr, 1, naxis, naxes, blc, trc, inc, 0, (double *) array, anynul, status); else ffgsvd(fptr, 1, naxis, naxes, blc, trc, inc, *(double *) nulval, (double *) array, anynul, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffgpv( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ void *nulval, /* I - value for undefined pixels */ void *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (datatype == TBYTE) { if (nulval == 0) ffgpvb(fptr, 1, firstelem, nelem, 0, (unsigned char *) array, anynul, status); else ffgpvb(fptr, 1, firstelem, nelem, *(unsigned char *) nulval, (unsigned char *) array, anynul, status); } else if (datatype == TSBYTE) { if (nulval == 0) ffgpvsb(fptr, 1, firstelem, nelem, 0, (signed char *) array, anynul, status); else ffgpvsb(fptr, 1, firstelem, nelem, *(signed char *) nulval, (signed char *) array, anynul, status); } else if (datatype == TUSHORT) { if (nulval == 0) ffgpvui(fptr, 1, firstelem, nelem, 0, (unsigned short *) array, anynul, status); else ffgpvui(fptr, 1, firstelem, nelem, *(unsigned short *) nulval, (unsigned short *) array, anynul, status); } else if (datatype == TSHORT) { if (nulval == 0) ffgpvi(fptr, 1, firstelem, nelem, 0, (short *) array, anynul, status); else ffgpvi(fptr, 1, firstelem, nelem, *(short *) nulval, (short *) array, anynul, status); } else if (datatype == TUINT) { if (nulval == 0) ffgpvuk(fptr, 1, firstelem, nelem, 0, (unsigned int *) array, anynul, status); else ffgpvuk(fptr, 1, firstelem, nelem, *(unsigned int *) nulval, (unsigned int *) array, anynul, status); } else if (datatype == TINT) { if (nulval == 0) ffgpvk(fptr, 1, firstelem, nelem, 0, (int *) array, anynul, status); else ffgpvk(fptr, 1, firstelem, nelem, *(int *) nulval, (int *) array, anynul, status); } else if (datatype == TULONG) { if (nulval == 0) ffgpvuj(fptr, 1, firstelem, nelem, 0, (unsigned long *) array, anynul, status); else ffgpvuj(fptr, 1, firstelem, nelem, *(unsigned long *) nulval, (unsigned long *) array, anynul, status); } else if (datatype == TLONG) { if (nulval == 0) ffgpvj(fptr, 1, firstelem, nelem, 0, (long *) array, anynul, status); else ffgpvj(fptr, 1, firstelem, nelem, *(long *) nulval, (long *) array, anynul, status); } else if (datatype == TULONGLONG) { if (nulval == 0) ffgpvujj(fptr, 1, firstelem, nelem, 0, (ULONGLONG *) array, anynul, status); else ffgpvujj(fptr, 1, firstelem, nelem, *(ULONGLONG *) nulval, (ULONGLONG *) array, anynul, status); } else if (datatype == TLONGLONG) { if (nulval == 0) ffgpvjj(fptr, 1, firstelem, nelem, 0, (LONGLONG *) array, anynul, status); else ffgpvjj(fptr, 1, firstelem, nelem, *(LONGLONG *) nulval, (LONGLONG *) array, anynul, status); } else if (datatype == TFLOAT) { if (nulval == 0) ffgpve(fptr, 1, firstelem, nelem, 0, (float *) array, anynul, status); else ffgpve(fptr, 1, firstelem, nelem, *(float *) nulval, (float *) array, anynul, status); } else if (datatype == TDOUBLE) { if (nulval == 0) ffgpvd(fptr, 1, firstelem, nelem, 0, (double *) array, anynul, status); else { ffgpvd(fptr, 1, firstelem, nelem, *(double *) nulval, (double *) array, anynul, status); } } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffgpf( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ void *array, /* O - array of values that are returned */ char *nullarray, /* O - array of null value flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). The nullarray values will = 1 if the corresponding array value is null. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (datatype == TBYTE) { ffgpfb(fptr, 1, firstelem, nelem, (unsigned char *) array, nullarray, anynul, status); } else if (datatype == TSBYTE) { ffgpfsb(fptr, 1, firstelem, nelem, (signed char *) array, nullarray, anynul, status); } else if (datatype == TUSHORT) { ffgpfui(fptr, 1, firstelem, nelem, (unsigned short *) array, nullarray, anynul, status); } else if (datatype == TSHORT) { ffgpfi(fptr, 1, firstelem, nelem, (short *) array, nullarray, anynul, status); } else if (datatype == TUINT) { ffgpfuk(fptr, 1, firstelem, nelem, (unsigned int *) array, nullarray, anynul, status); } else if (datatype == TINT) { ffgpfk(fptr, 1, firstelem, nelem, (int *) array, nullarray, anynul, status); } else if (datatype == TULONG) { ffgpfuj(fptr, 1, firstelem, nelem, (unsigned long *) array, nullarray, anynul, status); } else if (datatype == TLONG) { ffgpfj(fptr, 1, firstelem, nelem, (long *) array, nullarray, anynul, status); } else if (datatype == TULONGLONG) { ffgpfujj(fptr, 1, firstelem, nelem, (ULONGLONG *) array, nullarray, anynul, status); } else if (datatype == TLONGLONG) { ffgpfjj(fptr, 1, firstelem, nelem, (LONGLONG *) array, nullarray, anynul, status); } else if (datatype == TFLOAT) { ffgpfe(fptr, 1, firstelem, nelem, (float *) array, nullarray, anynul, status); } else if (datatype == TDOUBLE) { ffgpfd(fptr, 1, firstelem, nelem, (double *) array, nullarray, anynul, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffgcv( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ void *nulval, /* I - value for undefined pixels */ void *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a table column. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of true if any pixels are undefined. */ { char cdummy[2]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (datatype == TBIT) { ffgcx(fptr, colnum, firstrow, firstelem, nelem, (char *) array, status); } else if (datatype == TBYTE) { if (nulval == 0) ffgclb(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (unsigned char *) array, cdummy, anynul, status); else ffgclb(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(unsigned char *) nulval, (unsigned char *) array, cdummy, anynul, status); } else if (datatype == TSBYTE) { if (nulval == 0) ffgclsb(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (signed char *) array, cdummy, anynul, status); else ffgclsb(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(signed char *) nulval, (signed char *) array, cdummy, anynul, status); } else if (datatype == TUSHORT) { if (nulval == 0) ffgclui(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (unsigned short *) array, cdummy, anynul, status); else ffgclui(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(unsigned short *) nulval, (unsigned short *) array, cdummy, anynul, status); } else if (datatype == TSHORT) { if (nulval == 0) ffgcli(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (short *) array, cdummy, anynul, status); else ffgcli(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(short *) nulval, (short *) array, cdummy, anynul, status); } else if (datatype == TUINT) { if (nulval == 0) ffgcluk(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (unsigned int *) array, cdummy, anynul, status); else ffgcluk(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(unsigned int *) nulval, (unsigned int *) array, cdummy, anynul, status); } else if (datatype == TINT) { if (nulval == 0) ffgclk(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (int *) array, cdummy, anynul, status); else ffgclk(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(int *) nulval, (int *) array, cdummy, anynul, status); } else if (datatype == TULONG) { if (nulval == 0) ffgcluj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (unsigned long *) array, cdummy, anynul, status); else ffgcluj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(unsigned long *) nulval, (unsigned long *) array, cdummy, anynul, status); } else if (datatype == TLONG) { if (nulval == 0) ffgclj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (long *) array, cdummy, anynul, status); else ffgclj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(long *) nulval, (long *) array, cdummy, anynul, status); } else if (datatype == TULONGLONG) { if (nulval == 0) ffgclujj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (ULONGLONG *) array, cdummy, anynul, status); else ffgclujj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(ULONGLONG *) nulval, (ULONGLONG *) array, cdummy, anynul, status); } else if (datatype == TLONGLONG) { if (nulval == 0) ffgcljj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (LONGLONG *) array, cdummy, anynul, status); else ffgcljj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(LONGLONG *) nulval, (LONGLONG *) array, cdummy, anynul, status); } else if (datatype == TFLOAT) { if (nulval == 0) ffgcle(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0., (float *) array, cdummy, anynul, status); else ffgcle(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(float *) nulval,(float *) array, cdummy, anynul, status); } else if (datatype == TDOUBLE) { if (nulval == 0) ffgcld(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0., (double *) array, cdummy, anynul, status); else ffgcld(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(double *) nulval, (double *) array, cdummy, anynul, status); } else if (datatype == TCOMPLEX) { if (nulval == 0) ffgcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 1, 0., (float *) array, cdummy, anynul, status); else ffgcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 1, *(float *) nulval, (float *) array, cdummy, anynul, status); } else if (datatype == TDBLCOMPLEX) { if (nulval == 0) ffgcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 1, 0., (double *) array, cdummy, anynul, status); else ffgcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 1, *(double *) nulval, (double *) array, cdummy, anynul, status); } else if (datatype == TLOGICAL) { if (nulval == 0) ffgcll(fptr, colnum, firstrow, firstelem, nelem, 1, 0, (char *) array, cdummy, anynul, status); else ffgcll(fptr, colnum, firstrow, firstelem, nelem, 1, *(char *) nulval, (char *) array, cdummy, anynul, status); } else if (datatype == TSTRING) { if (nulval == 0) { cdummy[0] = '\0'; ffgcls(fptr, colnum, firstrow, firstelem, nelem, 1, cdummy, (char **) array, cdummy, anynul, status); } else ffgcls(fptr, colnum, firstrow, firstelem, nelem, 1, (char *) nulval, (char **) array, cdummy, anynul, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffgcf( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ void *array, /* O - array of values that are returned */ char *nullarray, /* O - array of null value flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a table column. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). ANYNUL is returned with a value of true if any pixels are undefined. */ { double nulval = 0.; char cnulval[2]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (datatype == TBIT) { ffgcx(fptr, colnum, firstrow, firstelem, nelem, (char *) array, status); } else if (datatype == TBYTE) { ffgclb(fptr, colnum, firstrow, firstelem, nelem, 1, 2, (unsigned char ) nulval, (unsigned char *) array, nullarray, anynul, status); } else if (datatype == TSBYTE) { ffgclsb(fptr, colnum, firstrow, firstelem, nelem, 1, 2, (signed char ) nulval, (signed char *) array, nullarray, anynul, status); } else if (datatype == TUSHORT) { ffgclui(fptr, colnum, firstrow, firstelem, nelem, 1, 2, (unsigned short ) nulval, (unsigned short *) array, nullarray, anynul, status); } else if (datatype == TSHORT) { ffgcli(fptr, colnum, firstrow, firstelem, nelem, 1, 2, (short ) nulval, (short *) array, nullarray, anynul, status); } else if (datatype == TUINT) { ffgcluk(fptr, colnum, firstrow, firstelem, nelem, 1, 2, (unsigned int ) nulval, (unsigned int *) array, nullarray, anynul, status); } else if (datatype == TINT) { ffgclk(fptr, colnum, firstrow, firstelem, nelem, 1, 2, (int ) nulval, (int *) array, nullarray, anynul, status); } else if (datatype == TULONG) { ffgcluj(fptr, colnum, firstrow, firstelem, nelem, 1, 2, (unsigned long ) nulval, (unsigned long *) array, nullarray, anynul, status); } else if (datatype == TLONG) { ffgclj(fptr, colnum, firstrow, firstelem, nelem, 1, 2, (long ) nulval, (long *) array, nullarray, anynul, status); } else if (datatype == TULONGLONG) { ffgclujj(fptr, colnum, firstrow, firstelem, nelem, 1, 2, (ULONGLONG ) nulval, (ULONGLONG *) array, nullarray, anynul, status); } else if (datatype == TLONGLONG) { ffgcljj(fptr, colnum, firstrow, firstelem, nelem, 1, 2, (LONGLONG ) nulval, (LONGLONG *) array, nullarray, anynul, status); } else if (datatype == TFLOAT) { ffgcle(fptr, colnum, firstrow, firstelem, nelem, 1, 2, (float ) nulval,(float *) array, nullarray, anynul, status); } else if (datatype == TDOUBLE) { ffgcld(fptr, colnum, firstrow, firstelem, nelem, 1, 2, nulval, (double *) array, nullarray, anynul, status); } else if (datatype == TCOMPLEX) { ffgcfc(fptr, colnum, firstrow, firstelem, nelem, (float *) array, nullarray, anynul, status); } else if (datatype == TDBLCOMPLEX) { ffgcfm(fptr, colnum, firstrow, firstelem, nelem, (double *) array, nullarray, anynul, status); } else if (datatype == TLOGICAL) { ffgcll(fptr, colnum, firstrow, firstelem, nelem, 2, (char ) nulval, (char *) array, nullarray, anynul, status); } else if (datatype == TSTRING) { ffgcls(fptr, colnum, firstrow, firstelem, nelem, 2, cnulval, (char **) array, nullarray, anynul, status); } else *status = BAD_DATATYPE; return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/getcolb.c0000644000175100001710000023100200000000000017704 0ustar00vstsdocker/* This file, getcolb.c, contains routines that read data elements from */ /* a FITS image or table, with unsigned char (unsigned byte) data type. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned char nulval, /* I - value for undefined pixels */ unsigned char *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; unsigned char nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TBYTE, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclb(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned char *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TBYTE, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclb(fptr, 2, row, firstelem, nelem, 1, 2, 0, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2db(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ unsigned char nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ unsigned char *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3db(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3db(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ unsigned char nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ unsigned char *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; LONGLONG narray, nfits; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}; LONGLONG lpixel[3]; unsigned char nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TBYTE, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgclb(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgclb(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ unsigned char nulval, /* I - value to set undefined pixels */ unsigned char *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii, i0, i1, i2, i3, i4, i5, i6, i7, i8, row, rstr, rstp, rinc; long str[9], stp[9], incr[9], dir[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; unsigned char nullvalue; if (naxis < 1 || naxis > 9) { snprintf(msg, FLEN_ERRMSG,"NAXIS = %d in call to ffgsvb is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TBYTE, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; dir[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { if (hdutype == IMAGE_HDU) { dir[ii] = -1; } else { snprintf(msg, FLEN_ERRMSG,"ffgsvb: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; dsize[ii] = dsize[ii] * dir[ii]; } dsize[naxis] = dsize[naxis] * dir[naxis]; if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0]*dir[0] - str[0]*dir[0]) / inc[0] + 1; ninc = incr[0] * dir[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]*dir[8]; i8 <= stp[8]*dir[8]; i8 += incr[8]) { for (i7 = str[7]*dir[7]; i7 <= stp[7]*dir[7]; i7 += incr[7]) { for (i6 = str[6]*dir[6]; i6 <= stp[6]*dir[6]; i6 += incr[6]) { for (i5 = str[5]*dir[5]; i5 <= stp[5]*dir[5]; i5 += incr[5]) { for (i4 = str[4]*dir[4]; i4 <= stp[4]*dir[4]; i4 += incr[4]) { for (i3 = str[3]*dir[3]; i3 <= stp[3]*dir[3]; i3 += incr[3]) { for (i2 = str[2]*dir[2]; i2 <= stp[2]*dir[2]; i2 += incr[2]) { for (i1 = str[1]*dir[1]; i1 <= stp[1]*dir[1]; i1 += incr[1]) { felem=str[0] + (i1 - dir[1]) * dsize[1] + (i2 - dir[2]) * dsize[2] + (i3 - dir[3]) * dsize[3] + (i4 - dir[4]) * dsize[4] + (i5 - dir[5]) * dsize[5] + (i6 - dir[6]) * dsize[6] + (i7 - dir[7]) * dsize[7] + (i8 - dir[8]) * dsize[8]; if ( ffgclb(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ unsigned char *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; int hdutype, anyf; unsigned char nulval = 0; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { snprintf(msg, FLEN_ERRMSG,"NAXIS = %d in call to ffgsvb is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TBYTE, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { snprintf(msg, FLEN_ERRMSG,"ffgsvb: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgclb(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ unsigned char *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclb(fptr, 1, row, firstelem, nelem, 1, 1, 0, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned char nulval, /* I - value for null pixels */ unsigned char *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgclb(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned char *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { unsigned char dummy = 0; ffgclb(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgclb( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ unsigned char nulval, /* I - value for null pixels if nultyp = 1 */ unsigned char *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem2, hdutype, xcode, decimals; long twidth, incre, ntodo; long ii, xwidth; int convert, nulcheck, readcheck = 16; /* see note below on readcheck */ LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre, maxelem; char tform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; union u_tag { char charval; unsigned char ucharval; } u; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (elemincre < 0) readcheck -= 1; /* don't do range checking in this case */ /* IMPORTANT NOTE: that the special case of using this subroutine to read bytes from a character column are handled internally by the call to ffgcprll() below. It will adjust the effective *tcode, repeats, etc, to appear as a TBYTE column. */ /* Note that readcheck = 16 is equivalent to readcheck = 0 and readcheck = 15 is equivalent to readcheck = -1, but either of those settings allow TSTRINGS to be treated as TBYTE vectors, but with full error checking */ ffgcprll( fptr, colnum, firstrow, firstelem, nelem, readcheck, &scale, &zero, tform, &twidth, &tcode, &maxelem2, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status); maxelem = maxelem2; /* special case */ if (tcode == TLOGICAL && elemincre == 1) { u.ucharval = nulval; ffgcll(fptr, colnum, firstrow, firstelem, nelem, nultyp, u.charval, (char *) array, nularray, anynul, status); return(*status); } if (*status > 0) return(*status); incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING && hdutype == ASCII_TBL) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default, check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ convert = 1; if (tcode == TBYTE) /* Special Case: */ { /* no type convertion required, so read */ /* data directly into output buffer. */ if (nelem < (LONGLONG)INT32_MAX) { maxelem = nelem; } else { maxelem = INT32_MAX; } if (nulcheck == 0 && scale == 1. && zero == 0.) convert = 0; /* no need to scale data or find nulls */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); if (elemincre >= 0) { ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); } else { ntodo = (long) minvalue(ntodo, (elemnum/(-elemincre) +1)); } readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, &array[next], status); if (convert) fffi1i1(&array[next], ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2i1((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) buffer, status); fffi4i1((INT32BIT *) buffer, ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8i1( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4i1((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8i1((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); /* interpret the string as an ASCII formated number */ fffstri1((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ snprintf(message, FLEN_ERRMSG, "Cannot read bytes from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) snprintf(message,FLEN_ERRMSG, "Error reading elements %.0f thru %.0f from column %d (ffgclb).", dtemp+1., dtemp+ntodo, colnum); else snprintf(message,FLEN_ERRMSG, "Error reading elements %.0f thru %.0f from image (ffgclb).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } else if (elemnum < 0) /* completed a row; start on a previous row */ { rowincre = (-elemnum - 1) / repeat + 1; rownum -= rowincre; elemnum = (rowincre * repeat) + elemnum; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgextn( fitsfile *fptr, /* I - FITS file pointer */ LONGLONG offset, /* I - byte offset from start of extension data */ LONGLONG nelem, /* I - number of elements to read */ void *buffer, /* I - stream of bytes to read */ int *status) /* IO - error status */ /* Read a stream of bytes from the current FITS HDU. This primative routine is mainly for reading non-standard "conforming" extensions and should not be used for standard IMAGE, TABLE or BINTABLE extensions. */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); /* move to write position */ ffmbyt(fptr, (fptr->Fptr)->datastart+ offset, IGNORE_EOF, status); /* read the buffer */ ffgbyt(fptr, nelem, buffer, status); return(*status); } /*--------------------------------------------------------------------------*/ int fffi1i1(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ unsigned char nullval,/* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned char *output,/* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { /* this routine is normally not called in this case */ memmove(output, input, ntodo ); } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2i1(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ unsigned char nullval,/* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned char *output,/* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4i1(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ unsigned char nullval,/* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned char *output,/* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8i1(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ unsigned char nullval,/* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned char *output,/* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; ULONGLONG ulltemp; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 9223372036854775808.) { /* The column we read contains unsigned long long values. */ /* Instead of adding 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { ulltemp = (ULONGLONG) (((LONGLONG) input[ii]) ^ 0x8000000000000000); if (ulltemp > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) ulltemp; } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 9223372036854775808.) { /* The column we read contains unsigned long long values. */ /* Instead of adding 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { ulltemp = (ULONGLONG) (((LONGLONG) input[ii]) ^ 0x8000000000000000); if (ulltemp > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else { output[ii] = (unsigned char) ulltemp; } } } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4i1(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char nullval,/* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned char *output,/* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { /* use redundant boolean logic in following statement */ /* to suppress irritating Borland compiler warning message */ if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8i1(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char nullval,/* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned char *output,/* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstri1(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ unsigned char nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned char *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[FLEN_ERRMSG]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.' || *cptr == ',') /* check for decimal point */ { decpt = 1; cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { snprintf(message, FLEN_ERRMSG,"Cannot read number from ASCII table"); ffpmsg(message); snprintf(message, FLEN_ERRMSG,"Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/getcold.c0000644000175100001710000020633600000000000017722 0ustar00vstsdocker/* This file, getcold.c, contains routines that read data elements from */ /* a FITS image or table, with double datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvd( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ double nulval, /* I - value for undefined pixels */ double *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; double nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TDOUBLE, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcld(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfd( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ double *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TDOUBLE, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcld(fptr, 2, row, firstelem, nelem, 1, 2, 0., array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2dd(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ double nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ double *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3dd(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3dd(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ double nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ double *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { LONGLONG nfits, narray; long tablerow, ii, jj; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}; LONGLONG lpixel[3]; double nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TDOUBLE, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgcld(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgcld(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvd(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ double nulval, /* I - value to set undefined pixels */ double *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dir[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; double nullvalue; if (naxis < 1 || naxis > 9) { snprintf(msg, FLEN_ERRMSG,"NAXIS = %d in call to ffgsvd is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TDOUBLE, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; dir[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { if (hdutype == IMAGE_HDU) { dir[ii] = -1; } else { snprintf(msg, FLEN_ERRMSG,"ffgsvd: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; dsize[ii] = dsize[ii] * dir[ii]; } dsize[naxis] = dsize[naxis] * dir[naxis]; if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0]*dir[0] - str[0]*dir[0]) / inc[0] + 1; ninc = incr[0] * dir[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]*dir[8]; i8 <= stp[8]*dir[8]; i8 += incr[8]) { for (i7 = str[7]*dir[7]; i7 <= stp[7]*dir[7]; i7 += incr[7]) { for (i6 = str[6]*dir[6]; i6 <= stp[6]*dir[6]; i6 += incr[6]) { for (i5 = str[5]*dir[5]; i5 <= stp[5]*dir[5]; i5 += incr[5]) { for (i4 = str[4]*dir[4]; i4 <= stp[4]*dir[4]; i4 += incr[4]) { for (i3 = str[3]*dir[3]; i3 <= stp[3]*dir[3]; i3 += incr[3]) { for (i2 = str[2]*dir[2]; i2 <= stp[2]*dir[2]; i2 += incr[2]) { for (i1 = str[1]*dir[1]; i1 <= stp[1]*dir[1]; i1 += incr[1]) { felem=str[0] + (i1 - dir[1]) * dsize[1] + (i2 - dir[2]) * dsize[2] + (i3 - dir[3]) * dsize[3] + (i4 - dir[4]) * dsize[4] + (i5 - dir[5]) * dsize[5] + (i6 - dir[6]) * dsize[6] + (i7 - dir[7]) * dsize[7] + (i8 - dir[8]) * dsize[8]; if ( ffgcld(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfd(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ double *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; int hdutype, anyf; double nulval = 0; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { snprintf(msg,FLEN_ERRMSG, "NAXIS = %d in call to ffgsvd is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TDOUBLE, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { snprintf(msg, FLEN_ERRMSG,"ffgsvd: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgcld(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpd( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ double *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcld(fptr, 1, row, firstelem, nelem, 1, 1, 0., array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvd(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ double nulval, /* I - value for null pixels */ double *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgcld(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvm(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ double nulval, /* I - value for null pixels */ double *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. TSCAL and ZERO should not be used with complex values. */ { char cdummy; /* a complex double value is interpreted as a pair of double values, */ /* thus need to multiply the first element and number of elements by 2 */ ffgcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfd(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ double *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { double dummy = 0; ffgcld(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfm(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ double *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. TSCAL and ZERO should not be used with complex values. */ { LONGLONG ii, jj; float dummy = 0; char *carray; /* a complex double value is interpreted as a pair of double values, */ /* thus need to multiply the first element and number of elements by 2 */ /* allocate temporary array */ carray = (char *) calloc( (size_t) (nelem * 2), 1); ffgcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 2, dummy, array, carray, anynul, status); for (ii = 0, jj = 0; jj < nelem; ii += 2, jj++) { if (carray[ii] || carray[ii + 1]) nularray[jj] = 1; else nularray[jj] = 0; } free(carray); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcld( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ double nulval, /* I - value for null pixels if nultyp = 1 */ double *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1, dtemp; int tcode, hdutype, xcode, decimals, maxelem2; long twidth, incre; long ii, xwidth, ntodo; int convert, nulcheck, readcheck = 0; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre, maxelem; char tform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (elemincre < 0) readcheck = -1; /* don't do range checking in this case */ if ( ffgcprll( fptr, colnum, firstrow, firstelem, nelem, readcheck, &scale, &zero, tform, &twidth, &tcode, &maxelem2, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); maxelem = maxelem2; incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ convert = 1; if (tcode == TDOUBLE) /* Special Case: */ { /* no type convertion required, so read */ /* data directly into output buffer. */ if (nelem < (LONGLONG)INT32_MAX/8) { maxelem = nelem; } else { maxelem = INT32_MAX/8; } if (nulcheck == 0 && scale == 1. && zero == 0.) convert = 0; /* no need to scale data or find nulls */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); if (elemincre >= 0) { ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); } else { ntodo = (long) minvalue(ntodo, (elemnum/(-elemincre) +1)); } readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, &array[next], status); if (convert) fffr8r8(&array[next], ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1r8((unsigned char *) buffer, ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2r8((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) buffer, status); fffi4r8((INT32BIT *) buffer, ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8r8( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4r8((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstrr8((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ snprintf(message, FLEN_ERRMSG, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) snprintf(message,FLEN_ERRMSG, "Error reading elements %.0f thru %.0f from column %d (ffgcld).", dtemp+1., dtemp+ntodo, colnum); else snprintf(message,FLEN_ERRMSG, "Error reading elements %.0f thru %.0f from image (ffgcld).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = (long) (elemnum / repeat); rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } else if (elemnum < 0) /* completed a row; start on a previous row */ { rowincre = (long) ((-elemnum - 1) / repeat + 1); rownum -= rowincre; elemnum = (rowincre * repeat) + elemnum; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int fffi1r8(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = input[ii] * scale + zero; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (double) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { output[ii] = input[ii] * scale + zero; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2r8(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = input[ii] * scale + zero; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (double) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { output[ii] = input[ii] * scale + zero; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4r8(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = input[ii] * scale + zero; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (double) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { output[ii] = input[ii] * scale + zero; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8r8(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; ULONGLONG ulltemp; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 9223372036854775808.) { /* The column we read contains unsigned long long values. */ /* Instead of adding 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { ulltemp = (ULONGLONG) (((LONGLONG) input[ii]) ^ 0x8000000000000000); output[ii] = (double) ulltemp; } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = (double) input[ii]; /* copy input to output */ } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = input[ii] * scale + zero; } } } else /* must check for null values */ { if (scale == 1. && zero == 9223372036854775808.) { /* The column we read contains unsigned long long values. */ /* Instead of subtracting 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { ulltemp = (ULONGLONG) (((LONGLONG) input[ii]) ^ 0x8000000000000000); output[ii] = (double) ulltemp; } } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (double) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { output[ii] = input[ii] * scale + zero; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4r8(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = input[ii] * scale + zero; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else output[ii] = (double) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = zero; } else output[ii] = input[ii] * scale + zero; } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8r8(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { memmove(output, input, ntodo * sizeof(double) ); } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = input[ii] * scale + zero; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else { nullarray[ii] = 1; /* explicitly set value in case output contains a NaN */ output[ii] = DOUBLENULLVALUE; } } else /* it's an underflow */ output[ii] = 0; } else output[ii] = input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else { nullarray[ii] = 1; /* explicitly set value in case output contains a NaN */ output[ii] = DOUBLENULLVALUE; } } else /* it's an underflow */ output[ii] = zero; } else output[ii] = input[ii] * scale + zero; } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstrr8(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[FLEN_ERRMSG]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.' || *cptr == ',') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { snprintf(message, FLEN_ERRMSG,"Cannot read number from ASCII table"); ffpmsg(message); snprintf(message,FLEN_ERRMSG, "Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); output[ii] = (dvalue * scale + zero); /* apply the scaling */ } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/getcole.c0000644000175100001710000020651400000000000017721 0ustar00vstsdocker/* This file, getcole.c, contains routines that read data elements from */ /* a FITS image or table, with float datatype */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpve( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ float nulval, /* I - value for undefined pixels */ float *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; float nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TFLOAT, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcle(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfe( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ float *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TFLOAT, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcle(fptr, 2, row, firstelem, nelem, 1, 2, 0.F, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2de(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ float nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ float *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3de(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3de(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ float nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ float *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow; LONGLONG narray, nfits, ii, jj; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}; LONGLONG lpixel[3]; float nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TFLOAT, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgcle(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgcle(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsve(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ float nulval, /* I - value to set undefined pixels */ float *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dir[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; float nullvalue; if (naxis < 1 || naxis > 9) { snprintf(msg, FLEN_ERRMSG,"NAXIS = %d in call to ffgsve is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TFLOAT, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; dir[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { if (hdutype == IMAGE_HDU) { dir[ii] = -1; } else { snprintf(msg, FLEN_ERRMSG,"ffgsve: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; dsize[ii] = dsize[ii] * dir[ii]; } dsize[naxis] = dsize[naxis] * dir[naxis]; if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0]*dir[0] - str[0]*dir[0]) / inc[0] + 1; ninc = incr[0] * dir[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]*dir[8]; i8 <= stp[8]*dir[8]; i8 += incr[8]) { for (i7 = str[7]*dir[7]; i7 <= stp[7]*dir[7]; i7 += incr[7]) { for (i6 = str[6]*dir[6]; i6 <= stp[6]*dir[6]; i6 += incr[6]) { for (i5 = str[5]*dir[5]; i5 <= stp[5]*dir[5]; i5 += incr[5]) { for (i4 = str[4]*dir[4]; i4 <= stp[4]*dir[4]; i4 += incr[4]) { for (i3 = str[3]*dir[3]; i3 <= stp[3]*dir[3]; i3 += incr[3]) { for (i2 = str[2]*dir[2]; i2 <= stp[2]*dir[2]; i2 += incr[2]) { for (i1 = str[1]*dir[1]; i1 <= stp[1]*dir[1]; i1 += incr[1]) { felem=str[0] + (i1 - dir[1]) * dsize[1] + (i2 - dir[2]) * dsize[2] + (i3 - dir[3]) * dsize[3] + (i4 - dir[4]) * dsize[4] + (i5 - dir[5]) * dsize[5] + (i6 - dir[6]) * dsize[6] + (i7 - dir[7]) * dsize[7] + (i8 - dir[8]) * dsize[8]; if ( ffgcle(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfe(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ float *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; int hdutype, anyf; float nulval = 0; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { snprintf(msg, FLEN_ERRMSG,"NAXIS = %d in call to ffgsve is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TFLOAT, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { snprintf(msg, FLEN_ERRMSG,"ffgsve: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgcle(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpe( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ float *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcle(fptr, 1, row, firstelem, nelem, 1, 1, 0.F, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcve(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ float nulval, /* I - value for null pixels */ float *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgcle(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvc(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ float nulval, /* I - value for null pixels */ float *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. TSCAL and ZERO should not be used with complex values. */ { char cdummy; /* a complex value is interpreted as a pair of float values, thus */ /* need to multiply the first element and number of elements by 2 */ ffgcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem *2, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfe(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ float *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { float dummy = 0; ffgcle(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfc(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ float *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. TSCAL and ZERO should not be used with complex values. */ { LONGLONG ii, jj; float dummy = 0; char *carray; /* a complex value is interpreted as a pair of float values, thus */ /* need to multiply the first element and number of elements by 2 */ /* allocate temporary array */ carray = (char *) calloc( (size_t) (nelem * 2), 1); ffgcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 2, dummy, array, carray, anynul, status); for (ii = 0, jj = 0; jj < nelem; ii += 2, jj++) { if (carray[ii] || carray[ii + 1]) nularray[jj] = 1; else nularray[jj] = 0; } free(carray); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcle( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ float nulval, /* I - value for null pixels if nultyp = 1 */ float *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem2, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int convert, nulcheck, readcheck = 0; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre, maxelem; char tform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (elemincre < 0) readcheck = -1; /* don't do range checking in this case */ if ( ffgcprll( fptr, colnum, firstrow, firstelem, nelem, readcheck, &scale, &zero, tform, &twidth, &tcode, &maxelem2, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); maxelem = maxelem2; incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ convert = 1; if (tcode == TFLOAT) /* Special Case: */ { /* no type convertion required, so read */ /* data directly into output buffer. */ if (nelem < (LONGLONG)INT32_MAX/4) { maxelem = nelem; } else { maxelem = INT32_MAX/4; } if (nulcheck == 0 && scale == 1. && zero == 0.) convert = 0; /* no need to scale data or find nulls */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); if (elemincre >= 0) { ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); } else { ntodo = (long) minvalue(ntodo, (elemnum/(-elemincre) +1)); } readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, &array[next], status); if (convert) fffr4r4(&array[next], ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1r4((unsigned char *) buffer, ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2r4((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) buffer, status); fffi4r4((INT32BIT *) buffer, ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8r4( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8r4((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstrr4((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ snprintf(message, FLEN_ERRMSG, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) snprintf(message,FLEN_ERRMSG, "Error reading elements %.0f thru %.0f from column %d (ffgcle).", dtemp+1., dtemp+ntodo, colnum); else snprintf(message,FLEN_ERRMSG, "Error reading elements %.0f thru %.0f from image (ffgcle).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } else if (elemnum < 0) /* completed a row; start on a previous row */ { rowincre = (-elemnum - 1) / repeat + 1; rownum -= rowincre; elemnum = (rowincre * repeat) + elemnum; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int fffi1r4(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = (float) (( (double) input[ii] ) * scale + zero); } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (float) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { output[ii] = (float) (( (double) input[ii] ) * scale + zero); } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2r4(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = (float) (input[ii] * scale + zero); } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (float) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { output[ii] = (float) (input[ii] * scale + zero); } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4r4(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = (float) (input[ii] * scale + zero); } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (float) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { output[ii] = (float) (input[ii] * scale + zero); } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8r4(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; ULONGLONG ulltemp; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 9223372036854775808.) { /* The column we read contains unsigned long long values. */ /* Instead of adding 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { ulltemp = (ULONGLONG) (((LONGLONG) input[ii]) ^ 0x8000000000000000); output[ii] = (float) ulltemp; } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = (float) input[ii]; /* copy input to output */ } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = (float) (input[ii] * scale + zero); } } } else /* must check for null values */ { if (scale == 1. && zero == 9223372036854775808.) { /* The column we read contains unsigned long long values. */ /* Instead of subtracting 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { ulltemp = (ULONGLONG) (((LONGLONG) input[ii]) ^ 0x8000000000000000); output[ii] = (float) ulltemp; } } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (float) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { output[ii] = (float) (input[ii] * scale + zero); } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4r4(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { memmove(output, input, ntodo * sizeof(float) ); } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = (float) (input[ii] * scale + zero); } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else { nullarray[ii] = 1; /* explicitly set value in case output contains a NaN */ output[ii] = FLOATNULLVALUE; } } else /* it's an underflow */ output[ii] = 0; } else output[ii] = input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else { nullarray[ii] = 1; /* explicitly set value in case output contains a NaN */ output[ii] = FLOATNULLVALUE; } } else /* it's an underflow */ output[ii] = (float) zero; } else output[ii] = (float) (input[ii] * scale + zero); } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8r4(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = (float) (input[ii] * scale + zero); } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else output[ii] = (float) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = (float) zero; } else output[ii] = (float) (input[ii] * scale + zero); } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstrr4(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[FLEN_ERRMSG]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.' || *cptr == ',') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { snprintf(message, FLEN_ERRMSG,"Cannot read number from ASCII table"); ffpmsg(message); snprintf(message, FLEN_ERRMSG, "Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); output[ii] = (float) (dvalue * scale + zero); /* apply the scaling */ } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/getcoli.c0000644000175100001710000022220500000000000017720 0ustar00vstsdocker/* This file, getcoli.c, contains routines that read data elements from */ /* a FITS image or table, with short datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvi( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ short nulval, /* I - value for undefined pixels */ short *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; short nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TSHORT, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcli(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfi( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ short *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TSHORT, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcli(fptr, 2, row, firstelem, nelem, 1, 2, 0, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2di(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ short nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ short *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3di(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3di(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ short nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ short *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; LONGLONG nfits, narray; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}; LONGLONG lpixel[3]; short nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TSHORT, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgcli(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgcli(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvi(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ short nulval, /* I - value to set undefined pixels */ short *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dir[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; short nullvalue; if (naxis < 1 || naxis > 9) { snprintf(msg,FLEN_ERRMSG, "NAXIS = %d in call to ffgsvi is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TSHORT, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; dir[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { if (hdutype == IMAGE_HDU) { dir[ii] = -1; } else { snprintf(msg, FLEN_ERRMSG,"ffgsvi: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; dsize[ii] = dsize[ii] * dir[ii]; } dsize[naxis] = dsize[naxis] * dir[naxis]; if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0]*dir[0] - str[0]*dir[0]) / inc[0] + 1; ninc = incr[0] * dir[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]*dir[8]; i8 <= stp[8]*dir[8]; i8 += incr[8]) { for (i7 = str[7]*dir[7]; i7 <= stp[7]*dir[7]; i7 += incr[7]) { for (i6 = str[6]*dir[6]; i6 <= stp[6]*dir[6]; i6 += incr[6]) { for (i5 = str[5]*dir[5]; i5 <= stp[5]*dir[5]; i5 += incr[5]) { for (i4 = str[4]*dir[4]; i4 <= stp[4]*dir[4]; i4 += incr[4]) { for (i3 = str[3]*dir[3]; i3 <= stp[3]*dir[3]; i3 += incr[3]) { for (i2 = str[2]*dir[2]; i2 <= stp[2]*dir[2]; i2 += incr[2]) { for (i1 = str[1]*dir[1]; i1 <= stp[1]*dir[1]; i1 += incr[1]) { felem=str[0] + (i1 - dir[1]) * dsize[1] + (i2 - dir[2]) * dsize[2] + (i3 - dir[3]) * dsize[3] + (i4 - dir[4]) * dsize[4] + (i5 - dir[5]) * dsize[5] + (i6 - dir[6]) * dsize[6] + (i7 - dir[7]) * dsize[7] + (i8 - dir[8]) * dsize[8]; if ( ffgcli(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfi(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ short *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; int hdutype, anyf; short nulval = 0; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { snprintf(msg, FLEN_ERRMSG,"NAXIS = %d in call to ffgsvi is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TSHORT, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { snprintf(msg, FLEN_ERRMSG,"ffgsvi: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgcli(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpi( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ short *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcli(fptr, 1, row, firstelem, nelem, 1, 1, 0, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvi(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ short nulval, /* I - value for null pixels */ short *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgcli(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfi(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ short *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { short dummy = 0; ffgcli(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcli( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ short nulval, /* I - value for null pixels if nultyp = 1 */ short *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem2, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int convert, nulcheck, readcheck = 0; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre, maxelem; char tform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (elemincre < 0) readcheck = -1; /* don't do range checking in this case */ if ( ffgcprll( fptr, colnum, firstrow, firstelem, nelem, readcheck, &scale, &zero, tform, &twidth, &tcode, &maxelem2, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); maxelem = maxelem2; incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ convert = 1; if (tcode == TSHORT) /* Special Case: */ { /* no type convertion required, so read */ /* data directly into output buffer. */ if (nelem < (LONGLONG)INT32_MAX/2) { maxelem = nelem; } else { maxelem = INT32_MAX/2; } if (nulcheck == 0 && scale == 1. && zero == 0.) convert = 0; /* no need to scale data or find nulls */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); if (elemincre >= 0) { ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); } else { ntodo = (long) minvalue(ntodo, (elemnum/(-elemincre) +1)); } readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, &array[next], status); if (convert) fffi2i2(&array[next], ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8i2( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1i2((unsigned char *) buffer, ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) buffer, status); fffi4i2((INT32BIT *) buffer, ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4i2((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8i2((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstri2((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ snprintf(message, FLEN_ERRMSG, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) snprintf(message,FLEN_ERRMSG, "Error reading elements %.0f thru %.0f from column %d (ffgcli).", dtemp+1, dtemp+ntodo, colnum); else snprintf(message,FLEN_ERRMSG, "Error reading elements %.0f thru %.0f from image (ffgcli).", dtemp+1, dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } else if (elemnum < 0) /* completed a row; start on a previous row */ { rowincre = (-elemnum - 1) / repeat + 1; rownum -= rowincre; elemnum = (rowincre * repeat) + elemnum; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int fffi1i2(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (short) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2i2(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { memmove(output, input, ntodo * sizeof(short) ); } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4i2(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < SHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < SHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8i2(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; ULONGLONG ulltemp; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 9223372036854775808.) { /* The column we read contains unsigned long long values. */ /* Instead of adding 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { ulltemp = (ULONGLONG) (((LONGLONG) input[ii]) ^ 0x8000000000000000); if (ulltemp > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { output[ii] = (short) ulltemp; } } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < SHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 9223372036854775808.) { /* The column we read contains unsigned long long values. */ /* Instead of subtracting 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { ulltemp = (ULONGLONG) (((LONGLONG) input[ii]) ^ 0x8000000000000000); if (ulltemp > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { output[ii] = (short) ulltemp; } } } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < SHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4i2(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (zero > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8i2(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (zero > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstri2(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[FLEN_ERRMSG]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.' || *cptr == ',') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { snprintf(message, FLEN_ERRMSG,"Cannot read number from ASCII table"); ffpmsg(message); snprintf(message, FLEN_ERRMSG,"Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/getcolj.c0000644000175100001710000044140100000000000017722 0ustar00vstsdocker/* This file, getcolj.c, contains routines that read data elements from */ /* a FITS image or table, with long data type. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long nulval, /* I - value for undefined pixels */ long *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; long nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TLONG, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclj(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TLONG, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclj(fptr, 2, row, firstelem, nelem, 1, 2, 0L, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2dj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ long *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3dj(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3dj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ long *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}, nfits, narray; LONGLONG lpixel[3], nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TLONG, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgclj(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgclj(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ long nulval, /* I - value to set undefined pixels */ long *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dir[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; long nullvalue; if (naxis < 1 || naxis > 9) { snprintf(msg, FLEN_ERRMSG,"NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TLONG, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; dir[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { if (hdutype == IMAGE_HDU) { dir[ii] = -1; } else { snprintf(msg, FLEN_ERRMSG,"ffgsvj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; dsize[ii] = dsize[ii] * dir[ii]; } dsize[naxis] = dsize[naxis] * dir[naxis]; if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0]*dir[0] - str[0]*dir[0]) / inc[0] + 1; ninc = incr[0] * dir[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]*dir[8]; i8 <= stp[8]*dir[8]; i8 += incr[8]) { for (i7 = str[7]*dir[7]; i7 <= stp[7]*dir[7]; i7 += incr[7]) { for (i6 = str[6]*dir[6]; i6 <= stp[6]*dir[6]; i6 += incr[6]) { for (i5 = str[5]*dir[5]; i5 <= stp[5]*dir[5]; i5 += incr[5]) { for (i4 = str[4]*dir[4]; i4 <= stp[4]*dir[4]; i4 += incr[4]) { for (i3 = str[3]*dir[3]; i3 <= stp[3]*dir[3]; i3 += incr[3]) { for (i2 = str[2]*dir[2]; i2 <= stp[2]*dir[2]; i2 += incr[2]) { for (i1 = str[1]*dir[1]; i1 <= stp[1]*dir[1]; i1 += incr[1]) { felem=str[0] + (i1 - dir[1]) * dsize[1] + (i2 - dir[2]) * dsize[2] + (i3 - dir[3]) * dsize[3] + (i4 - dir[4]) * dsize[4] + (i5 - dir[5]) * dsize[5] + (i6 - dir[6]) * dsize[6] + (i7 - dir[7]) * dsize[7] + (i8 - dir[8]) * dsize[8]; if ( ffgclj(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ long *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; long nulval = 0; int hdutype, anyf; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { snprintf(msg, FLEN_ERRMSG,"NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TLONG, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { snprintf(msg, FLEN_ERRMSG,"ffgsvj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgclj(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ long *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclj(fptr, 1, row, firstelem, nelem, 1, 1, 0L, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long nulval, /* I - value for null pixels */ long *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgclj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { long dummy = 0; ffgclj(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgclj( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ long nulval, /* I - value for null pixels if nultyp = 1 */ long *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem2, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int convert, nulcheck, readcheck = 0; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre, maxelem; char tform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (elemincre < 0) readcheck = -1; /* don't do range checking in this case */ if (ffgcprll(fptr, colnum, firstrow, firstelem, nelem, readcheck, &scale, &zero, tform, &twidth, &tcode, &maxelem2, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); maxelem = maxelem2; incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ convert = 1; if ((tcode == TLONG) && (LONGSIZE == 32)) /* Special Case: */ { /* no type convertion required, so read */ /* data directly into output buffer. */ if (nelem < (LONGLONG)INT32_MAX/4) { maxelem = nelem; } else { maxelem = INT32_MAX/4; } if (nulcheck == 0 && scale == 1. && zero == 0. ) convert = 0; /* no need to scale data or find nulls */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); if (elemincre >= 0) { ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); } else { ntodo = (long) minvalue(ntodo, (elemnum/(-elemincre) +1)); } readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TLONG): if (LONGSIZE == 32) { ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) &array[next], status); if (convert) fffi4i4((INT32BIT *) &array[next], ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); } else { /* case where sizeof(long) = 8 */ ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) buffer, status); if (convert) fffi4i4((INT32BIT *) buffer, ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); } break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8i4((LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1i4((unsigned char *) buffer, ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2i4((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4i4((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8i4((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstri4((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ snprintf(message, FLEN_ERRMSG, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) snprintf(message,FLEN_ERRMSG, "Error reading elements %.0f thru %.0f from column %d (ffgclj).", dtemp+1., dtemp+ntodo, colnum); else snprintf(message,FLEN_ERRMSG, "Error reading elements %.0f thru %.0f from image (ffgclj).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } else if (elemnum < 0) /* completed a row; start on a previous row */ { rowincre = (-elemnum - 1) / repeat + 1; rownum -= rowincre; elemnum = (rowincre * repeat) + elemnum; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int fffi1i4(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (long) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2i4(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (long) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4i4(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = (long) input[ii]; /* copy input to output */ } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8i4(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; ULONGLONG ulltemp; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 9223372036854775808.) { /* The column we read contains unsigned long long values. */ /* Instead of adding 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { ulltemp = (ULONGLONG) (((LONGLONG) input[ii]) ^ 0x8000000000000000); if (ulltemp > LONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else { output[ii] = (long) ulltemp; } } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < LONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (input[ii] > LONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 9223372036854775808.) { /* The column we read contains unsigned long long values. */ /* Instead of subtracting 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { ulltemp = (ULONGLONG) (((LONGLONG) input[ii]) ^ 0x8000000000000000); if (ulltemp > LONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else { output[ii] = (long) ulltemp; } } } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < LONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (input[ii] > LONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4i4(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (input[ii] > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (input[ii] > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (zero > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8i4(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (input[ii] > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (input[ii] > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (zero > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstri4(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[FLEN_ERRMSG]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.' || *cptr == ',') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { snprintf(message, FLEN_ERRMSG,"Cannot read number from ASCII table"); ffpmsg(message); snprintf(message, FLEN_ERRMSG,"Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } /* ======================================================================== */ /* the following routines support the 'long long' data type */ /* ======================================================================== */ /*--------------------------------------------------------------------------*/ int ffgpvjj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ LONGLONG nulval, /* I - value for undefined pixels */ LONGLONG *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; LONGLONG nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TLONGLONG, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcljj(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfjj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ LONGLONG *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; LONGLONG dummy = 0; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TLONGLONG, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcljj(fptr, 2, row, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2djj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG nulval ,/* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG *array,/* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3djj(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3djj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ LONGLONG *array,/* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}, nfits, narray; LONGLONG lpixel[3]; LONGLONG nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TLONGLONG, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgcljj(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgcljj(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvjj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ LONGLONG nulval,/* I - value to set undefined pixels */ LONGLONG *array,/* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dir[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; LONGLONG nullvalue; if (naxis < 1 || naxis > 9) { snprintf(msg, FLEN_ERRMSG,"NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TLONGLONG, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; dir[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { if (hdutype == IMAGE_HDU) { dir[ii] = -1; } else { snprintf(msg, FLEN_ERRMSG,"ffgsvj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; dsize[ii] = dsize[ii] * dir[ii]; } dsize[naxis] = dsize[naxis] * dir[naxis]; if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0]*dir[0] - str[0]*dir[0]) / inc[0] + 1; ninc = incr[0] * dir[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]*dir[8]; i8 <= stp[8]*dir[8]; i8 += incr[8]) { for (i7 = str[7]*dir[7]; i7 <= stp[7]*dir[7]; i7 += incr[7]) { for (i6 = str[6]*dir[6]; i6 <= stp[6]*dir[6]; i6 += incr[6]) { for (i5 = str[5]*dir[5]; i5 <= stp[5]*dir[5]; i5 += incr[5]) { for (i4 = str[4]*dir[4]; i4 <= stp[4]*dir[4]; i4 += incr[4]) { for (i3 = str[3]*dir[3]; i3 <= stp[3]*dir[3]; i3 += incr[3]) { for (i2 = str[2]*dir[2]; i2 <= stp[2]*dir[2]; i2 += incr[2]) { for (i1 = str[1]*dir[1]; i1 <= stp[1]*dir[1]; i1 += incr[1]) { felem=str[0] + (i1 - dir[1]) * dsize[1] + (i2 - dir[2]) * dsize[2] + (i3 - dir[3]) * dsize[3] + (i4 - dir[4]) * dsize[4] + (i5 - dir[5]) * dsize[5] + (i6 - dir[6]) * dsize[6] + (i7 - dir[7]) * dsize[7] + (i8 - dir[8]) * dsize[8]; if ( ffgcljj(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfjj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ LONGLONG *array,/* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; LONGLONG nulval = 0; int hdutype, anyf; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { snprintf(msg, FLEN_ERRMSG,"NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TLONGLONG, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { snprintf(msg, FLEN_ERRMSG,"ffgsvj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgcljj(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpjj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ LONGLONG *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; LONGLONG dummy = 0; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcljj(fptr, 1, row, firstelem, nelem, 1, 1, dummy, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvjj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ LONGLONG nulval, /* I - value for null pixels */ LONGLONG *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgcljj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfjj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ LONGLONG *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { LONGLONG dummy = 0; ffgcljj(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcljj( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ LONGLONG nulval, /* I - value for null pixels if nultyp = 1 */ LONGLONG *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem2, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int convert, nulcheck, readcheck = 0; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre, maxelem; char tform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (elemincre < 0) readcheck = -1; /* don't do range checking in this case */ if (ffgcprll(fptr, colnum, firstrow, firstelem, nelem, readcheck, &scale, &zero, tform, &twidth, &tcode, &maxelem2, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); maxelem = maxelem2; incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ convert = 1; if (tcode == TLONGLONG) /* Special Case: */ { /* no type convertion required, so read */ /* data directly into output buffer. */ if (nelem < (LONGLONG)INT32_MAX/8) { maxelem = nelem; } else { maxelem = INT32_MAX/8; } if (nulcheck == 0 && scale == 1. && zero == 0.) convert = 0; /* no need to scale data or find nulls */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); if (elemincre >= 0) { ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); } else { ntodo = (long) minvalue(ntodo, (elemnum/(-elemincre) +1)); } readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) &array[next], status); if (convert) fffi8i8((LONGLONG *) &array[next], ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) buffer, status); fffi4i8((INT32BIT *) buffer, ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1i8((unsigned char *) buffer, ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2i8((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4i8((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8i8((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstri8((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ snprintf(message,FLEN_ERRMSG, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) snprintf(message,FLEN_ERRMSG, "Error reading elements %.0f thru %.0f from column %d (ffgclj).", dtemp+1., dtemp+ntodo, colnum); else snprintf(message,FLEN_ERRMSG, "Error reading elements %.0f thru %.0f from image (ffgclj).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } else if (elemnum < 0) /* completed a row; start on a previous row */ { rowincre = (-elemnum - 1) / repeat + 1; rownum -= rowincre; elemnum = (rowincre * repeat) + elemnum; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int fffi1i8(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ LONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ LONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (LONGLONG) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (LONGLONG) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2i8(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ LONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ LONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (LONGLONG) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (LONGLONG) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4i8(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ LONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ LONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (LONGLONG) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (LONGLONG) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8i8(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ LONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ LONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; ULONGLONG ulltemp; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 9223372036854775808.) { /* The column we read contains unsigned long long values. */ /* Instead of adding 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { ulltemp = (ULONGLONG) (((LONGLONG) input[ii]) ^ 0x8000000000000000); if (ulltemp > LONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { output[ii] = (LONGLONG) ulltemp; } } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = input[ii]; /* copy input to output */ } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 9223372036854775808.) { /* The column we read contains unsigned long long values. */ /* Instead of subtracting 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { ulltemp = (ULONGLONG) (((LONGLONG) input[ii]) ^ 0x8000000000000000); if (ulltemp > LONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { output[ii] = (LONGLONG) ulltemp; } } } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4i8(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ LONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (input[ii] > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (input[ii] > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (zero > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8i8(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ LONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (input[ii] > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (input[ii] > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (zero > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstri8(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ LONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ LONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[FLEN_ERRMSG]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.' || *cptr == ',') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { snprintf(message, FLEN_ERRMSG, "Cannot read number from ASCII table"); ffpmsg(message); snprintf(message, FLEN_ERRMSG,"Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/getcolk.c0000644000175100001710000022177700000000000017737 0ustar00vstsdocker/* This file, getcolk.c, contains routines that read data elements from */ /* a FITS image or table, with 'int' data type. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvk( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ int nulval, /* I - value for undefined pixels */ int *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; int nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TINT, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclk(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfk( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ int *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TINT, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclk(fptr, 2, row, firstelem, nelem, 1, 2, 0L, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2dk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ int nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ int *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3dk(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3dk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ int nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ int *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}, nfits, narray; LONGLONG lpixel[3]; int nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TINT, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgclk(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgclk(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ int nulval, /* I - value to set undefined pixels */ int *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dir[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; int nullvalue; if (naxis < 1 || naxis > 9) { snprintf(msg, FLEN_ERRMSG,"NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TINT, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; dir[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { if (hdutype == IMAGE_HDU) { dir[ii] = -1; } else { snprintf(msg, FLEN_ERRMSG,"ffgsvk: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; dsize[ii] = dsize[ii] * dir[ii]; } dsize[naxis] = dsize[naxis] * dir[naxis]; if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0]*dir[0] - str[0]*dir[0]) / inc[0] + 1; ninc = incr[0] * dir[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]*dir[8]; i8 <= stp[8]*dir[8]; i8 += incr[8]) { for (i7 = str[7]*dir[7]; i7 <= stp[7]*dir[7]; i7 += incr[7]) { for (i6 = str[6]*dir[6]; i6 <= stp[6]*dir[6]; i6 += incr[6]) { for (i5 = str[5]*dir[5]; i5 <= stp[5]*dir[5]; i5 += incr[5]) { for (i4 = str[4]*dir[4]; i4 <= stp[4]*dir[4]; i4 += incr[4]) { for (i3 = str[3]*dir[3]; i3 <= stp[3]*dir[3]; i3 += incr[3]) { for (i2 = str[2]*dir[2]; i2 <= stp[2]*dir[2]; i2 += incr[2]) { for (i1 = str[1]*dir[1]; i1 <= stp[1]*dir[1]; i1 += incr[1]) { felem=str[0] + (i1 - dir[1]) * dsize[1] + (i2 - dir[2]) * dsize[2] + (i3 - dir[3]) * dsize[3] + (i4 - dir[4]) * dsize[4] + (i5 - dir[5]) * dsize[5] + (i6 - dir[6]) * dsize[6] + (i7 - dir[7]) * dsize[7] + (i8 - dir[8]) * dsize[8]; if ( ffgclk(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ int *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; long nulval = 0; int hdutype, anyf; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { snprintf(msg, FLEN_ERRMSG,"NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TINT, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { snprintf(msg, FLEN_ERRMSG,"ffgsvj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgclk(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpk( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ int *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclk(fptr, 1, row, firstelem, nelem, 1, 1, 0L, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ int nulval, /* I - value for null pixels */ int *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgclk(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ int *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { int dummy = 0; ffgclk(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgclk( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ int nulval, /* I - value for null pixels if nultyp = 1 */ int *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power, dtemp; int tcode, maxelem2, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int convert, nulcheck, readcheck = 0; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre, maxelem; char tform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* call the 'short' or 'long' version of this routine, if possible */ if (sizeof(int) == sizeof(short)) ffgcli(fptr, colnum, firstrow, firstelem, nelem, elemincre, nultyp, (short) nulval, (short *) array, nularray, anynul, status); else if (sizeof(int) == sizeof(long)) ffgclj(fptr, colnum, firstrow, firstelem, nelem, elemincre, nultyp, (long) nulval, (long *) array, nularray, anynul, status); else { /* This is a special case: sizeof(int) is not equal to sizeof(short) or sizeof(long). This occurs on Alpha OSF systems where short = 2 bytes, int = 4 bytes, and long = 8 bytes. */ buffer = cbuff; power = 1.; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (elemincre < 0) readcheck = -1; /* don't do range checking in this case */ if ( ffgcprll( fptr, colnum, firstrow, firstelem, nelem, readcheck, &scale, &zero, tform, &twidth, &tcode, &maxelem2, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); maxelem = maxelem2; incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ convert = 1; if (tcode == TLONG) /* Special Case: */ { /* no type convertion required, so read */ /* data directly into output buffer. */ if (nelem < (LONGLONG)INT32_MAX/4) { maxelem = nelem; } else { maxelem = INT32_MAX/4; } if (nulcheck == 0 && scale == 1. && zero == 0.) convert = 0; /* no need to scale data or find nulls */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); if (elemincre >= 0) { ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); } else { ntodo = (long) minvalue(ntodo, (elemnum/(-elemincre) +1)); } readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) &array[next], status); if (convert) fffi4int((INT32BIT *) &array[next], ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8int( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1int((unsigned char *) buffer, ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2int((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4int((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8int((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstrint((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ snprintf(message, FLEN_ERRMSG, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) snprintf(message, FLEN_ERRMSG, "Error reading elements %.0f thru %.0f from column %d (ffgclk).", dtemp+1., dtemp+ntodo, colnum); else snprintf(message, FLEN_ERRMSG, "Error reading elements %.0f thru %.0f from image (ffgclk).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } else if (elemnum < 0) /* completed a row; start on a previous row */ { rowincre = (-elemnum - 1) / repeat + 1; rownum -= rowincre; elemnum = (rowincre * repeat) + elemnum; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } } /* end of DEC Alpha special case */ return(*status); } /*--------------------------------------------------------------------------*/ int fffi1int(unsigned char *input,/* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (int) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2int(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (int) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4int(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (int) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8int(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; ULONGLONG ulltemp; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 9223372036854775808.) { /* The column we read contains unsigned long long values. */ /* Instead of adding 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { ulltemp = (ULONGLONG) (((LONGLONG) input[ii]) ^ 0x8000000000000000); if (ulltemp > INT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else { output[ii] = (int) ulltemp; } } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < INT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (input[ii] > INT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 9223372036854775808.) { /* The column we read contains unsigned long long values. */ /* Instead of subtracting 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { ulltemp = (ULONGLONG) (((LONGLONG) input[ii]) ^ 0x8000000000000000); if (ulltemp > INT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else { output[ii] = (int) ulltemp; } } } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < INT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (input[ii] > INT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4int(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (input[ii] > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (input[ii] > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (zero > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8int(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (input[ii] > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (input[ii] > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (zero > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstrint(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[FLEN_ERRMSG]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.' || *cptr == ',') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { snprintf(message, FLEN_ERRMSG,"Cannot read number from ASCII table"); ffpmsg(message); snprintf(message, FLEN_ERRMSG,"Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (long) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/getcoll.c0000644000175100001710000005540200000000000017726 0ustar00vstsdocker/* This file, getcoll.c, contains routines that read data elements from */ /* a FITS image or table, with logical datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgcvl( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ char nulval, /* I - value for null pixels */ char *array, /* O - array of values */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of logical values from a column in the current FITS HDU. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgcll( fptr, colnum, firstrow, firstelem, nelem, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcl( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ char *array, /* O - array of values */ int *status) /* IO - error status */ /* !!!! THIS ROUTINE IS DEPRECATED AND SHOULD NOT BE USED !!!!!! !!!! USE ffgcvl INSTEAD !!!!!! Read an array of logical values from a column in the current FITS HDU. No checking for null values will be performed. */ { char nulval = 0; int anynul; ffgcvl( fptr, colnum, firstrow, firstelem, nelem, nulval, array, &anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfl( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ char *array, /* O - array of values */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of logical values from a column in the current FITS HDU. */ { char nulval = 0; ffgcll( fptr, colnum, firstrow, firstelem, nelem, 2, nulval, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcll( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ char nulval, /* I - value for null pixels if nultyp = 1 */ char *array, /* O - array of values */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of logical values from a column in the current FITS HDU. */ { double dtemp; int tcode, maxelem, hdutype, ii, nulcheck; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, readptr, tnull, rowlen, rownum, remain, next; double scale, zero; char tform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ unsigned char buffer[DBUFFSIZE], *buffptr; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 0, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode != TLOGICAL) return(*status = NOT_LOGICAL_COL); /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default, check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ /*---------------------------------------------------------------------*/ /* Now read the logical values from the FITS column. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ ntodo = (long) remain; /* max number of elements to read at one time */ while (ntodo) { /* limit the number of pixels to read at one time to the number that remain in the current vector. */ ntodo = (long) minvalue(ntodo, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); readptr = startpos + (rowlen * rownum) + (elemnum * incre); ffgi1b(fptr, readptr, ntodo, incre, buffer, status); /* convert from T or F to 1 or 0 */ buffptr = buffer; for (ii = 0; ii < ntodo; ii++, next++, buffptr++) { if (*buffptr == 'T') array[next] = 1; else if (*buffptr =='F') array[next] = 0; else if (*buffptr == 0) { array[next] = nulval; /* set null values to input nulval */ if (anynul) *anynul = 1; if (nulcheck == 2) { nularray[next] = 1; /* set null flags */ } } else /* some other illegal character; return the char value */ { if (*buffptr == 1) { /* this is an unfortunate case where the illegal value is the same as what we set True values to, so set the value to the character '1' instead, which has ASCII value 49. */ array[next] = 49; } else { array[next] = (char) *buffptr; } } } if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; snprintf(message,FLEN_ERRMSG, "Error reading elements %.0f thruough %.0f of logical array (ffgcl).", dtemp+1., dtemp + ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on later row */ { elemnum = 0; rownum++; } } ntodo = (long) remain; /* this is the maximum number to do in next loop */ } /* End of main while Loop */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgcx( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG frow, /* I - first row to write (1 = 1st row) */ LONGLONG fbit, /* I - first bit to write (1 = 1st) */ LONGLONG nbit, /* I - number of bits to write */ char *larray, /* O - array of logicals corresponding to bits */ int *status) /* IO - error status */ /* read an array of logical values from a specified bit or byte column of the binary table. larray is set = TRUE, if the corresponding bit = 1, otherwise it is set to FALSE. The binary table column being read from must have datatype 'B' or 'X'. */ { LONGLONG bstart; long offset, ndone, ii, repeat, bitloc, fbyte; LONGLONG rstart, estart; int tcode, descrp; unsigned char cbuff; static unsigned char onbit[8] = {128, 64, 32, 16, 8, 4, 2, 1}; tcolumn *colptr; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check input parameters */ if (nbit < 1) return(*status); else if (frow < 1) return(*status = BAD_ROW_NUM); else if (fbit < 1) return(*status = BAD_ELEM_NUM); /* position to the correct HDU */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); fbyte = (long) ((fbit + 7) / 8); bitloc = (long) (fbit - 1 - ((fbit - 1) / 8 * 8)); ndone = 0; rstart = frow - 1; estart = fbyte - 1; colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (abs(tcode) > TBYTE) return(*status = NOT_LOGICAL_COL); /* not correct datatype column */ if (tcode > 0) { descrp = FALSE; /* not a variable length descriptor column */ /* N.B: REPEAT is the number of bytes, not number of bits */ repeat = (long) colptr->trepeat; if (tcode == TBIT) repeat = (repeat + 7) / 8; /* convert from bits to bytes */ if (fbyte > repeat) return(*status = BAD_ELEM_NUM); /* calc the i/o pointer location to start of sequence of pixels */ bstart = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * rstart) + colptr->tbcol + estart; } else { descrp = TRUE; /* a variable length descriptor column */ /* only bit arrays (tform = 'X') are supported for variable */ /* length arrays. REPEAT is the number of BITS in the array. */ ffgdes(fptr, colnum, frow, &repeat, &offset, status); if (tcode == -TBIT) repeat = (repeat + 7) / 8; if ((fbit + nbit + 6) / 8 > repeat) return(*status = BAD_ELEM_NUM); /* calc the i/o pointer location to start of sequence of pixels */ bstart = (fptr->Fptr)->datastart + offset + (fptr->Fptr)->heapstart + estart; } /* move the i/o pointer to the start of the pixel sequence */ if (ffmbyt(fptr, bstart, REPORT_EOF, status) > 0) return(*status); /* read the next byte */ while (1) { if (ffgbyt(fptr, 1, &cbuff, status) > 0) return(*status); for (ii = bitloc; (ii < 8) && (ndone < nbit); ii++, ndone++) { if(cbuff & onbit[ii]) /* test if bit is set */ larray[ndone] = TRUE; else larray[ndone] = FALSE; } if (ndone == nbit) /* finished all the bits */ return(*status); /* not done, so get the next byte */ if (!descrp) { estart++; if (estart == repeat) { /* move the i/o pointer to the next row of pixels */ estart = 0; rstart = rstart + 1; bstart = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * rstart) + colptr->tbcol; ffmbyt(fptr, bstart, REPORT_EOF, status); } } bitloc = 0; } } /*--------------------------------------------------------------------------*/ int ffgcxui(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG nrows, /* I - no. of rows to read */ long input_first_bit, /* I - first bit to read (1 = 1st) */ int input_nbits, /* I - number of bits to read (<= 32) */ unsigned short *array, /* O - array of integer values */ int *status) /* IO - error status */ /* Read a consecutive string of bits from an 'X' or 'B' column and interprete them as an unsigned integer. The number of bits must be less than or equal to 16 or the total number of bits in the column, which ever is less. */ { int ii, firstbit, nbits, bytenum, startbit, numbits, endbit; int firstbyte, lastbyte, nbytes, rshift, lshift; unsigned short colbyte[5]; tcolumn *colptr; char message[FLEN_ERRMSG]; if (*status > 0 || nrows == 0) return(*status); /* check input parameters */ if (firstrow < 1) { snprintf(message,FLEN_ERRMSG, "Starting row number is less than 1: %ld (ffgcxui)", (long) firstrow); ffpmsg(message); return(*status = BAD_ROW_NUM); } else if (input_first_bit < 1) { snprintf(message,FLEN_ERRMSG, "Starting bit number is less than 1: %ld (ffgcxui)", input_first_bit); ffpmsg(message); return(*status = BAD_ELEM_NUM); } else if (input_nbits > 16) { snprintf(message, FLEN_ERRMSG,"Number of bits to read is > 16: %d (ffgcxui)", input_nbits); ffpmsg(message); return(*status = BAD_ELEM_NUM); } /* position to the correct HDU */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype != BINARY_TBL) { ffpmsg("This is not a binary table extension (ffgcxui)"); return(*status = NOT_BTABLE); } if (colnum > (fptr->Fptr)->tfield) { snprintf(message, FLEN_ERRMSG,"Specified column number is out of range: %d (ffgcxui)", colnum); ffpmsg(message); snprintf(message, FLEN_ERRMSG," There are %d columns in this table.", (fptr->Fptr)->tfield ); ffpmsg(message); return(*status = BAD_COL_NUM); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ if (abs(colptr->tdatatype) > TBYTE) { ffpmsg("Can only read bits from X or B type columns. (ffgcxui)"); return(*status = NOT_LOGICAL_COL); /* not correct datatype column */ } firstbyte = (input_first_bit - 1 ) / 8 + 1; lastbyte = (input_first_bit + input_nbits - 2) / 8 + 1; nbytes = lastbyte - firstbyte + 1; if (colptr->tdatatype == TBIT && input_first_bit + input_nbits - 1 > (long) colptr->trepeat) { ffpmsg("Too many bits. Tried to read past width of column (ffgcxui)"); return(*status = BAD_ELEM_NUM); } else if (colptr->tdatatype == TBYTE && lastbyte > (long) colptr->trepeat) { ffpmsg("Too many bits. Tried to read past width of column (ffgcxui)"); return(*status = BAD_ELEM_NUM); } for (ii = 0; ii < nrows; ii++) { /* read the relevant bytes from the row */ if (ffgcvui(fptr, colnum, firstrow+ii, firstbyte, nbytes, 0, colbyte, NULL, status) > 0) { ffpmsg("Error reading bytes from column (ffgcxui)"); return(*status); } firstbit = (input_first_bit - 1) % 8; /* modulus operator */ nbits = input_nbits; array[ii] = 0; /* select and shift the bits from each byte into the output word */ while(nbits) { bytenum = firstbit / 8; startbit = firstbit % 8; numbits = minvalue(nbits, 8 - startbit); endbit = startbit + numbits - 1; rshift = 7 - endbit; lshift = nbits - numbits; array[ii] = ((colbyte[bytenum] >> rshift) << lshift) | array[ii]; nbits -= numbits; firstbit += numbits; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgcxuk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG nrows, /* I - no. of rows to read */ long input_first_bit, /* I - first bit to read (1 = 1st) */ int input_nbits, /* I - number of bits to read (<= 32) */ unsigned int *array, /* O - array of integer values */ int *status) /* IO - error status */ /* Read a consecutive string of bits from an 'X' or 'B' column and interprete them as an unsigned integer. The number of bits must be less than or equal to 32 or the total number of bits in the column, which ever is less. */ { int ii, firstbit, nbits, bytenum, startbit, numbits, endbit; int firstbyte, lastbyte, nbytes, rshift, lshift; unsigned int colbyte[5]; tcolumn *colptr; char message[FLEN_ERRMSG]; if (*status > 0 || nrows == 0) return(*status); /* check input parameters */ if (firstrow < 1) { snprintf(message, FLEN_ERRMSG,"Starting row number is less than 1: %ld (ffgcxuk)", (long) firstrow); ffpmsg(message); return(*status = BAD_ROW_NUM); } else if (input_first_bit < 1) { snprintf(message, FLEN_ERRMSG,"Starting bit number is less than 1: %ld (ffgcxuk)", input_first_bit); ffpmsg(message); return(*status = BAD_ELEM_NUM); } else if (input_nbits > 32) { snprintf(message, FLEN_ERRMSG,"Number of bits to read is > 32: %d (ffgcxuk)", input_nbits); ffpmsg(message); return(*status = BAD_ELEM_NUM); } /* position to the correct HDU */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype != BINARY_TBL) { ffpmsg("This is not a binary table extension (ffgcxuk)"); return(*status = NOT_BTABLE); } if (colnum > (fptr->Fptr)->tfield) { snprintf(message, FLEN_ERRMSG,"Specified column number is out of range: %d (ffgcxuk)", colnum); ffpmsg(message); snprintf(message, FLEN_ERRMSG," There are %d columns in this table.", (fptr->Fptr)->tfield ); ffpmsg(message); return(*status = BAD_COL_NUM); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ if (abs(colptr->tdatatype) > TBYTE) { ffpmsg("Can only read bits from X or B type columns. (ffgcxuk)"); return(*status = NOT_LOGICAL_COL); /* not correct datatype column */ } firstbyte = (input_first_bit - 1 ) / 8 + 1; lastbyte = (input_first_bit + input_nbits - 2) / 8 + 1; nbytes = lastbyte - firstbyte + 1; if (colptr->tdatatype == TBIT && input_first_bit + input_nbits - 1 > (long) colptr->trepeat) { ffpmsg("Too many bits. Tried to read past width of column (ffgcxuk)"); return(*status = BAD_ELEM_NUM); } else if (colptr->tdatatype == TBYTE && lastbyte > (long) colptr->trepeat) { ffpmsg("Too many bits. Tried to read past width of column (ffgcxuk)"); return(*status = BAD_ELEM_NUM); } for (ii = 0; ii < nrows; ii++) { /* read the relevant bytes from the row */ if (ffgcvuk(fptr, colnum, firstrow+ii, firstbyte, nbytes, 0, colbyte, NULL, status) > 0) { ffpmsg("Error reading bytes from column (ffgcxuk)"); return(*status); } firstbit = (input_first_bit - 1) % 8; /* modulus operator */ nbits = input_nbits; array[ii] = 0; /* select and shift the bits from each byte into the output word */ while(nbits) { bytenum = firstbit / 8; startbit = firstbit % 8; numbits = minvalue(nbits, 8 - startbit); endbit = startbit + numbits - 1; rshift = 7 - endbit; lshift = nbits - numbits; array[ii] = ((colbyte[bytenum] >> rshift) << lshift) | array[ii]; nbits -= numbits; firstbit += numbits; } } return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/getcols.c0000644000175100001710000010216300000000000017732 0ustar00vstsdocker/* This file, getcols.c, contains routines that read data elements from */ /* a FITS image or table, with a character string datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include /* stddef.h is apparently needed to define size_t */ #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgcvs( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of strings to read */ char *nulval, /* I - string for null pixels */ char **array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of string values from a column in the current FITS HDU. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = null in which case no checks for undefined pixels will be made. */ { char cdummy[2]; ffgcls(fptr, colnum, firstrow, firstelem, nelem, 1, nulval, array, cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfs( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of strings to read */ char **array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of string values from a column in the current FITS HDU. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { char dummy[2]; ffgcls(fptr, colnum, firstrow, firstelem, nelem, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcls( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of strings to read */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ char *nulval, /* I - value for null pixels if nultyp = 1 */ char **array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of string values from a column in the current FITS HDU. Returns a formated string value, regardless of the datatype of the column */ { int tcode, hdutype, tstatus, scaled, intcol, dwidth, nulwidth, ll, dlen; int equivtype; long ii, jj; tcolumn *colptr; char message[FLEN_ERRMSG], *carray, keyname[FLEN_KEYWORD]; char cform[20], dispfmt[20], tmpstr[400], *flgarray, tmpnull[80]; unsigned char byteval; float *earray; double *darray, tscale = 1.0; LONGLONG *llarray; ULONGLONG *ullarray; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if (colnum < 1 || colnum > (fptr->Fptr)->tfield) { snprintf(message, FLEN_ERRMSG,"Specified column number is out of range: %d", colnum); ffpmsg(message); return(*status = BAD_COL_NUM); } /* get equivalent dataype of column (only needed for TLONGLONG columns) */ ffeqtyll(fptr, colnum, &equivtype, NULL, NULL, status); if (equivtype < 0) equivtype = abs(equivtype); colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = abs(colptr->tdatatype); intcol = 0; if (tcode == TSTRING) { /* simply call the string column reading routine */ ffgcls2(fptr, colnum, firstrow, firstelem, nelem, nultyp, nulval, array, nularray, anynul, status); } else if (tcode == TLOGICAL) { /* allocate memory for the array of logical values */ carray = (char *) malloc((size_t) nelem); /* call the logical column reading routine */ ffgcll(fptr, colnum, firstrow, firstelem, nelem, nultyp, *nulval, carray, nularray, anynul, status); if (*status <= 0) { /* convert logical values to "T", "F", or "N" (Null) */ for (ii = 0; ii < nelem; ii++) { if (carray[ii] == 1) strcpy(array[ii], "T"); else if (carray[ii] == 0) strcpy(array[ii], "F"); else /* undefined values = 2 */ strcpy(array[ii],"N"); } } free(carray); /* free the memory */ } else if (tcode == TCOMPLEX) { /* allocate memory for the array of double values */ earray = (float *) calloc((size_t) (nelem * 2), sizeof(float) ); ffgcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 1, FLOATNULLVALUE, earray, nularray, anynul, status); if (*status <= 0) { /* determine the format for the output strings */ ffgcdw(fptr, colnum, &dwidth, status); dwidth = (dwidth - 3) / 2; /* use the TDISPn keyword if it exists */ ffkeyn("TDISP", colnum, keyname, status); tstatus = 0; cform[0] = '\0'; if (ffgkys(fptr, keyname, dispfmt, NULL, &tstatus) == 0) { /* convert the Fortran style format to a C style format */ ffcdsp(dispfmt, cform); /* Special case: TDISPn='Aw' disallowed for numeric types */ if (dispfmt[0] == 'A') { cform[0] = 0; /* Special case: if the output is intended to be represented as an integer, but we read it as a double, we need to set intcol = 1 so it is printed as an integer */ } else if ((dispfmt[0] == 'I') || (dispfmt[0] == 'i') || (dispfmt[0] == 'O') || (dispfmt[0] == 'o') || (dispfmt[0] == 'Z') || (dispfmt[0] == 'z')) { intcol = 1; } } if (!cform[0]) strcpy(cform, "%14.6E"); /* write the formated string for each value: "(real,imag)" */ jj = 0; for (ii = 0; ii < nelem; ii++) { strcpy(array[ii], "("); /* test for null value */ if (earray[jj] == FLOATNULLVALUE) { strcpy(tmpstr, "NULL"); if (nultyp == 2) nularray[ii] = 1; } else if (intcol) { snprintf(tmpstr, 400,cform, (int) earray[jj]); } else { snprintf(tmpstr, 400,cform, earray[jj]); } strncat(array[ii], tmpstr, dwidth); strcat(array[ii], ","); jj++; /* test for null value */ if (earray[jj] == FLOATNULLVALUE) { strcpy(tmpstr, "NULL"); if (nultyp == 2) nularray[ii] = 1; } else if (intcol) { snprintf(tmpstr, 400,cform, (int) earray[jj]); } else { snprintf(tmpstr, 400,cform, earray[jj]); } strncat(array[ii], tmpstr, dwidth); strcat(array[ii], ")"); jj++; } } free(earray); /* free the memory */ } else if (tcode == TDBLCOMPLEX) { /* allocate memory for the array of double values */ darray = (double *) calloc((size_t) (nelem * 2), sizeof(double) ); ffgcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 1, DOUBLENULLVALUE, darray, nularray, anynul, status); if (*status <= 0) { /* determine the format for the output strings */ ffgcdw(fptr, colnum, &dwidth, status); dwidth = (dwidth - 3) / 2; /* use the TDISPn keyword if it exists */ ffkeyn("TDISP", colnum, keyname, status); tstatus = 0; cform[0] = '\0'; if (ffgkys(fptr, keyname, dispfmt, NULL, &tstatus) == 0) { /* convert the Fortran style format to a C style format */ ffcdsp(dispfmt, cform); /* Special case: TDISPn='Aw' disallowed for numeric types */ if (dispfmt[0] == 'A') { cform[0] = 0; /* Special case: if the output is intended to be represented as an integer, but we read it as a double, we need to set intcol = 1 so it is printed as an integer */ } else if ((dispfmt[0] == 'I') || (dispfmt[0] == 'i') || (dispfmt[0] == 'O') || (dispfmt[0] == 'o') || (dispfmt[0] == 'Z') || (dispfmt[0] == 'z')) { intcol = 1; } } if (!cform[0]) strcpy(cform, "%23.15E"); /* write the formated string for each value: "(real,imag)" */ jj = 0; for (ii = 0; ii < nelem; ii++) { strcpy(array[ii], "("); /* test for null value */ if (darray[jj] == DOUBLENULLVALUE) { strcpy(tmpstr, "NULL"); if (nultyp == 2) nularray[ii] = 1; } else if (intcol) { snprintf(tmpstr, 400,cform, (int) darray[jj]); } else { snprintf(tmpstr, 400,cform, darray[jj]); } strncat(array[ii], tmpstr, dwidth); strcat(array[ii], ","); jj++; /* test for null value */ if (darray[jj] == DOUBLENULLVALUE) { strcpy(tmpstr, "NULL"); if (nultyp == 2) nularray[ii] = 1; } else if (intcol) { snprintf(tmpstr, 400,cform, (int) darray[jj]); } else { snprintf(tmpstr, 400,cform, darray[jj]); } strncat(array[ii], tmpstr, dwidth); strcat(array[ii], ")"); jj++; } } free(darray); /* free the memory */ } else if (tcode == TLONGLONG && equivtype == TLONGLONG) { /* allocate memory for the array of LONGLONG values */ llarray = (LONGLONG *) calloc((size_t) nelem, sizeof(LONGLONG) ); flgarray = (char *) calloc((size_t) nelem, sizeof(char) ); dwidth = 20; /* max width of displayed long long integer value */ if (ffgcfjj(fptr, colnum, firstrow, firstelem, nelem, llarray, flgarray, anynul, status) > 0) { free(flgarray); free(llarray); return(*status); } /* write the formated string for each value */ if (nulval) { strncpy(tmpnull, nulval,79); tmpnull[79]='\0'; /* In case len(nulval) >= 79 */ nulwidth = strlen(tmpnull); } else { strcpy(tmpnull, " "); nulwidth = 1; } for (ii = 0; ii < nelem; ii++) { if ( flgarray[ii] ) { *array[ii] = '\0'; if (dwidth < nulwidth) strncat(array[ii], tmpnull, dwidth); else sprintf(array[ii],"%*s",dwidth,tmpnull); if (nultyp == 2) nularray[ii] = 1; } else { #if defined(_MSC_VER) /* Microsoft Visual C++ 6.0 uses '%I64d' syntax for 8-byte integers */ snprintf(tmpstr, 400,"%20I64d", llarray[ii]); #elif (USE_LL_SUFFIX == 1) snprintf(tmpstr, 400,"%20lld", llarray[ii]); #else snprintf(tmpstr, 400,"%20ld", llarray[ii]); #endif *array[ii] = '\0'; strncat(array[ii], tmpstr, 20); } } free(flgarray); free(llarray); /* free the memory */ } else if (tcode == TLONGLONG && equivtype == TULONGLONG) { /* allocate memory for the array of ULONGLONG values */ ullarray = (ULONGLONG *) calloc((size_t) nelem, sizeof(ULONGLONG) ); flgarray = (char *) calloc((size_t) nelem, sizeof(char) ); dwidth = 20; /* max width of displayed unsigned long long integer value */ if (ffgcfujj(fptr, colnum, firstrow, firstelem, nelem, ullarray, flgarray, anynul, status) > 0) { free(flgarray); free(ullarray); return(*status); } /* write the formated string for each value */ if (nulval) { strncpy(tmpnull, nulval, 79); tmpnull[79]='\0'; /* In case len(nulval) >= 79 */ nulwidth = strlen(tmpnull); } else { strcpy(tmpnull, " "); nulwidth = 1; } for (ii = 0; ii < nelem; ii++) { if ( flgarray[ii] ) { *array[ii] = '\0'; if (dwidth < nulwidth) strncat(array[ii], tmpnull, dwidth); else sprintf(array[ii],"%*s",dwidth,tmpnull); if (nultyp == 2) nularray[ii] = 1; } else { #if defined(_MSC_VER) /* Microsoft Visual C++ 6.0 uses '%I64d' syntax for 8-byte integers */ snprintf(tmpstr, 400, "%20I64u", ullarray[ii]); #elif (USE_LL_SUFFIX == 1) snprintf(tmpstr, 400, "%20llu", ullarray[ii]); #else snprintf(tmpstr, 400, "%20lu", ullarray[ii]); #endif *array[ii] = '\0'; strncat(array[ii], tmpstr, 20); } } free(flgarray); free(ullarray); /* free the memory */ } else { /* allocate memory for the array of double values */ darray = (double *) calloc((size_t) nelem, sizeof(double) ); /* read all other numeric type columns as doubles */ if (ffgcld(fptr, colnum, firstrow, firstelem, nelem, 1, nultyp, DOUBLENULLVALUE, darray, nularray, anynul, status) > 0) { free(darray); return(*status); } /* determine the format for the output strings */ ffgcdw(fptr, colnum, &dwidth, status); /* check if column is scaled */ ffkeyn("TSCAL", colnum, keyname, status); tstatus = 0; scaled = 0; if (ffgkyd(fptr, keyname, &tscale, NULL, &tstatus) == 0) { if (tscale != 1.0) scaled = 1; /* yes, this is a scaled column */ } intcol = 0; if (tcode <= TLONG && !scaled) intcol = 1; /* this is an unscaled integer column */ /* use the TDISPn keyword if it exists */ ffkeyn("TDISP", colnum, keyname, status); tstatus = 0; cform[0] = '\0'; if (ffgkys(fptr, keyname, dispfmt, NULL, &tstatus) == 0) { /* convert the Fortran style TDISPn to a C style format */ ffcdsp(dispfmt, cform); /* Special case: TDISPn='Aw' disallowed for numeric types */ if (dispfmt[0] == 'A') { cform[0] = 0; /* Special case: if the output is intended to be represented as an integer, but we read it as a double, we need to set intcol = 1 so it is printed as an integer */ } else if ((dispfmt[0] == 'I') || (dispfmt[0] == 'i') || (dispfmt[0] == 'O') || (dispfmt[0] == 'o') || (dispfmt[0] == 'Z') || (dispfmt[0] == 'z')) { intcol = 1; } } if (!cform[0]) { /* no TDISPn keyword; use TFORMn instead */ ffkeyn("TFORM", colnum, keyname, status); ffgkys(fptr, keyname, dispfmt, NULL, status); if (scaled && tcode <= TSHORT) { /* scaled short integer column == float */ strcpy(cform, "%#14.6G"); } else if (scaled && tcode == TLONG) { /* scaled long integer column == double */ strcpy(cform, "%#23.15G"); } else if (scaled && tcode == TLONGLONG) { /* scaled long long integer column == double */ strcpy(cform, "%#23.15G"); } else { ffghdt(fptr, &hdutype, status); if (hdutype == ASCII_TBL) { /* convert the Fortran style TFORMn to a C style format */ ffcdsp(dispfmt, cform); } else { /* this is a binary table, need to convert the format */ if (tcode == TBIT) { /* 'X' */ strcpy(cform, "%4d"); } else if (tcode == TBYTE) { /* 'B' */ strcpy(cform, "%4d"); } else if (tcode == TSHORT) { /* 'I' */ strcpy(cform, "%6d"); } else if (tcode == TLONG) { /* 'J' */ strcpy(cform, "%11.0f"); intcol = 0; /* needed to support unsigned int */ } else if (tcode == TFLOAT) { /* 'E' */ strcpy(cform, "%#14.6G"); } else if (tcode == TDOUBLE) { /* 'D' */ strcpy(cform, "%#23.15G"); } } } } if (nulval) { strncpy(tmpnull, nulval,79); tmpnull[79]='\0'; nulwidth = strlen(tmpnull); } else { strcpy(tmpnull, " "); nulwidth = 1; } /* write the formated string for each value */ for (ii = 0; ii < nelem; ii++) { if (tcode == TBIT) { byteval = (char) darray[ii]; for (ll=0; ll < 8; ll++) { if ( ((unsigned char) (byteval << ll)) >> 7 ) *(array[ii] + ll) = '1'; else *(array[ii] + ll) = '0'; } *(array[ii] + 8) = '\0'; } /* test for null value */ else if ( (nultyp == 1 && darray[ii] == DOUBLENULLVALUE) || (nultyp == 2 && nularray[ii]) ) { *array[ii] = '\0'; if (dwidth < nulwidth) strncat(array[ii], tmpnull, dwidth); else sprintf(array[ii],"%*s",dwidth,tmpnull); } else { if (intcol) { snprintf(tmpstr, 400,cform, (int) darray[ii]); } else { snprintf(tmpstr, 400,cform, darray[ii]); } /* fill field with '*' if number is too wide */ dlen = strlen(tmpstr); if (dlen > dwidth) { memset(tmpstr, '*', dwidth); } *array[ii] = '\0'; strncat(array[ii], tmpstr, dwidth); } } free(darray); /* free the memory */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffgcdw( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column (1 = 1st col) */ int *width, /* O - display width */ int *status) /* IO - error status */ /* Get Column Display Width. */ { tcolumn *colptr; char *cptr; char message[FLEN_ERRMSG], keyname[FLEN_KEYWORD], dispfmt[20]; int tcode, hdutype, tstatus, scaled; double tscale; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (colnum < 1 || colnum > (fptr->Fptr)->tfield) { snprintf(message, FLEN_ERRMSG,"Specified column number is out of range: %d", colnum); ffpmsg(message); return(*status = BAD_COL_NUM); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = abs(colptr->tdatatype); /* use the TDISPn keyword if it exists */ ffkeyn("TDISP", colnum, keyname, status); *width = 0; tstatus = 0; if (ffgkys(fptr, keyname, dispfmt, NULL, &tstatus) == 0) { /* parse TDISPn get the display width */ cptr = dispfmt; while(*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == 'A' || *cptr == 'a' || *cptr == 'I' || *cptr == 'i' || *cptr == 'O' || *cptr == 'o' || *cptr == 'Z' || *cptr == 'z' || *cptr == 'F' || *cptr == 'f' || *cptr == 'E' || *cptr == 'e' || *cptr == 'D' || *cptr == 'd' || *cptr == 'G' || *cptr == 'g') { while(!isdigit((int) *cptr) && *cptr != '\0') /* find 1st digit */ cptr++; *width = atoi(cptr); if (tcode >= TCOMPLEX) *width = (2 * (*width)) + 3; } } if (*width == 0) { /* no valid TDISPn keyword; use TFORMn instead */ ffkeyn("TFORM", colnum, keyname, status); ffgkys(fptr, keyname, dispfmt, NULL, status); /* check if column is scaled */ ffkeyn("TSCAL", colnum, keyname, status); tstatus = 0; scaled = 0; if (ffgkyd(fptr, keyname, &tscale, NULL, &tstatus) == 0) { if (tscale != 1.0) scaled = 1; /* yes, this is a scaled column */ } if (scaled && tcode <= TSHORT) { /* scaled short integer col == float; default format is 14.6G */ *width = 14; } else if (scaled && tcode == TLONG) { /* scaled long integer col == double; default format is 23.15G */ *width = 23; } else if (scaled && tcode == TLONGLONG) { /* scaled long long integer col == double; default format is 23.15G */ *width = 23; } else { ffghdt(fptr, &hdutype, status); /* get type of table */ if (hdutype == ASCII_TBL) { /* parse TFORMn get the display width */ cptr = dispfmt; while(!isdigit((int) *cptr) && *cptr != '\0') /* find 1st digit */ cptr++; *width = atoi(cptr); } else { /* this is a binary table */ if (tcode == TBIT) /* 'X' */ *width = 8; else if (tcode == TBYTE) /* 'B' */ *width = 4; else if (tcode == TSHORT) /* 'I' */ *width = 6; else if (tcode == TLONG) /* 'J' */ *width = 11; else if (tcode == TLONGLONG) /* 'K' */ *width = 20; else if (tcode == TFLOAT) /* 'E' */ *width = 14; else if (tcode == TDOUBLE) /* 'D' */ *width = 23; else if (tcode == TCOMPLEX) /* 'C' */ *width = 31; else if (tcode == TDBLCOMPLEX) /* 'M' */ *width = 49; else if (tcode == TLOGICAL) /* 'L' */ *width = 1; else if (tcode == TSTRING) /* 'A' */ { int typecode; long int repeat = 0, rwidth = 0; int gstatus = 0; /* Deal with possible vector string with repeat / width by parsing the TFORM=rAw keyword */ if (ffgtcl(fptr, colnum, &typecode, &repeat, &rwidth, &gstatus) == 0 && rwidth >= 1 && rwidth < repeat) { *width = rwidth; } else { /* Hmmm, we couldn't parse the TFORM keyword by standard, so just do simple parsing */ cptr = dispfmt; while(!isdigit((int) *cptr) && *cptr != '\0') cptr++; *width = atoi(cptr); } if (*width < 1) *width = 1; /* default is at least 1 column */ } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgcls2 ( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of strings to read */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ char *nulval, /* I - value for null pixels if nultyp = 1 */ char **array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of string values from a column in the current FITS HDU. */ { double dtemp; long nullen; int tcode, maxelem, hdutype, nulcheck; long twidth, incre; long ii, jj, ntodo; LONGLONG repeat, startpos, elemnum, readptr, tnull, rowlen, rownum, remain, next; double scale, zero; char tform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ tcolumn *colptr; double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ char *buffer, *arrayptr; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (colnum < 1 || colnum > (fptr->Fptr)->tfield) { snprintf(message, FLEN_ERRMSG,"Specified column number is out of range: %d", colnum); ffpmsg(message); return(*status = BAD_COL_NUM); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode == -TSTRING) /* variable length column in a binary table? */ { /* only read a single string; ignore value of firstelem */ if (ffgcprll( fptr, colnum, firstrow, 1, 1, 0, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); remain = 1; twidth = (long) repeat; } else if (tcode == TSTRING) { if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 0, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); /* if string length is greater than a FITS block (2880 char) then must */ /* only read 1 string at a time, to force reading by ffgbyt instead of */ /* ffgbytoff (ffgbytoff can't handle this case) */ if (twidth > IOBUFLEN) { maxelem = 1; incre = twidth; repeat = 1; } remain = nelem; } else return(*status = NOT_ASCII_COL); nullen = strlen(snull); /* length of the undefined pixel string */ if (nullen == 0) nullen = 1; /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (nultyp == 1 && nulval && nulval[0] == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /* null value string in ASCII table not defined */ else if (nullen > twidth) nulcheck = 0; /* null value string is longer than width of column */ /* thus impossible for any column elements to = null */ /*---------------------------------------------------------------------*/ /* Now read the strings one at a time from the FITS column. */ /*---------------------------------------------------------------------*/ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process at one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, readptr, REPORT_EOF, status); /* move to read position */ /* read the array of strings from the FITS file into the buffer */ if (incre == twidth) ffgbyt(fptr, ntodo * twidth, cbuff, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, cbuff, status); /* copy from the buffer into the user's array of strings */ /* work backwards from last char of last string to 1st char of 1st */ buffer = ((char *) cbuff) + (ntodo * twidth) - 1; for (ii = (long) (next + ntodo - 1); ii >= next; ii--) { arrayptr = array[ii] + twidth - 1; for (jj = twidth - 1; jj > 0; jj--) /* ignore trailing blanks */ { if (*buffer == ' ') { buffer--; arrayptr--; } else break; } *(arrayptr + 1) = 0; /* write the string terminator */ for (; jj >= 0; jj--) /* copy the string itself */ { *arrayptr = *buffer; buffer--; arrayptr--; } /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (nulcheck && !strncmp(snull, array[ii], nullen) ) { *anynul = 1; /* this is a null value */ if (nultyp == 1) { if (nulval) strcpy(array[ii], nulval); else strcpy(array[ii], " "); } else nularray[ii] = 1; } } if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; snprintf(message,FLEN_ERRMSG, "Error reading elements %.0f thru %.0f of data array (ffpcls).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ next += ntodo; remain -= ntodo; if (remain) { elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/getcolsb.c0000644000175100001710000022704300000000000020101 0ustar00vstsdocker/* This file, getcolsb.c, contains routines that read data elements from */ /* a FITS image or table, with signed char (signed byte) data type. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvsb(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ signed char nulval, /* I - value for undefined pixels */ signed char *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; signed char nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TSBYTE, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclsb(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfsb(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ signed char *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TSBYTE, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclsb(fptr, 2, row, firstelem, nelem, 1, 2, 0, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2dsb(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ signed char nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ signed char *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3dsb(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3dsb(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ signed char nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ signed char *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; LONGLONG nfits, narray; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}; LONGLONG lpixel[3]; signed char nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TSBYTE, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgclsb(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgclsb(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvsb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ signed char nulval, /* I - value to set undefined pixels */ signed char *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii, i0, i1, i2, i3, i4, i5, i6, i7, i8, row, rstr, rstp, rinc; long str[9], stp[9], incr[9], dir[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; signed char nullvalue; if (naxis < 1 || naxis > 9) { snprintf(msg, FLEN_ERRMSG,"NAXIS = %d in call to ffgsvsb is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TSBYTE, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; dir[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { if (hdutype == IMAGE_HDU) { dir[ii] = -1; } else { snprintf(msg, FLEN_ERRMSG,"ffgsvsb: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; dsize[ii] = dsize[ii] * dir[ii]; } dsize[naxis] = dsize[naxis] * dir[naxis]; if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0]*dir[0] - str[0]*dir[0]) / inc[0] + 1; ninc = incr[0] * dir[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]*dir[8]; i8 <= stp[8]*dir[8]; i8 += incr[8]) { for (i7 = str[7]*dir[7]; i7 <= stp[7]*dir[7]; i7 += incr[7]) { for (i6 = str[6]*dir[6]; i6 <= stp[6]*dir[6]; i6 += incr[6]) { for (i5 = str[5]*dir[5]; i5 <= stp[5]*dir[5]; i5 += incr[5]) { for (i4 = str[4]*dir[4]; i4 <= stp[4]*dir[4]; i4 += incr[4]) { for (i3 = str[3]*dir[3]; i3 <= stp[3]*dir[3]; i3 += incr[3]) { for (i2 = str[2]*dir[2]; i2 <= stp[2]*dir[2]; i2 += incr[2]) { for (i1 = str[1]*dir[1]; i1 <= stp[1]*dir[1]; i1 += incr[1]) { felem=str[0] + (i1 - dir[1]) * dsize[1] + (i2 - dir[2]) * dsize[2] + (i3 - dir[3]) * dsize[3] + (i4 - dir[4]) * dsize[4] + (i5 - dir[5]) * dsize[5] + (i6 - dir[6]) * dsize[6] + (i7 - dir[7]) * dsize[7] + (i8 - dir[8]) * dsize[8]; if ( ffgclsb(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfsb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ signed char *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; int hdutype, anyf; signed char nulval = 0; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { snprintf(msg, FLEN_ERRMSG,"NAXIS = %d in call to ffgsvsb is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TSBYTE, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { snprintf(msg, FLEN_ERRMSG,"ffgsvsb: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgclsb(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpsb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ signed char *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclsb(fptr, 1, row, firstelem, nelem, 1, 1, 0, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvsb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ signed char nulval, /* I - value for null pixels */ signed char *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgclsb(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfsb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ signed char *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { signed char dummy = 0; ffgclsb(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgclsb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ signed char nulval, /* I - value for null pixels if nultyp = 1 */ signed char *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int nulcheck, readcheck = 0; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre; char tform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; union u_tag { char charval; signed char scharval; } u; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (elemincre < 0) readcheck = -1; /* don't do range checking in this case */ ffgcprll( fptr, colnum, firstrow, firstelem, nelem, readcheck, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status); /* special case: read column of T/F logicals */ if (tcode == TLOGICAL && elemincre == 1) { u.scharval = nulval; ffgcll(fptr, colnum, firstrow, firstelem, nelem, nultyp, u.charval, (char *) array, nularray, anynul, status); return(*status); } if (strchr(tform,'A') != NULL) { if (*status == BAD_ELEM_NUM) { /* ignore this error message */ *status = 0; ffcmsg(); /* clear error stack */ } /* interpret a 'A' ASCII column as a 'B' byte column ('8A' == '8B') */ /* This is an undocumented 'feature' in CFITSIO */ /* we have to reset some of the values returned by ffgcpr */ tcode = TBYTE; incre = 1; /* each element is 1 byte wide */ repeat = twidth; /* total no. of chars in the col */ twidth = 1; /* width of each element */ scale = 1.0; /* no scaling */ zero = 0.0; tnull = NULL_UNDEFINED; /* don't test for nulls */ maxelem = DBUFFSIZE; } if (*status > 0) return(*status); incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING && hdutype == ASCII_TBL) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default, check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); if (elemincre >= 0) { ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); } else { ntodo = (long) minvalue(ntodo, (elemnum/(-elemincre) +1)); } readptr = startpos + (rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) &array[next], status); fffi1s1((unsigned char *)&array[next], ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2s1((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) buffer, status); fffi4s1((INT32BIT *) buffer, ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8s1( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4s1((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8s1((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); /* interpret the string as an ASCII formated number */ fffstrs1((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ snprintf(message, FLEN_ERRMSG, "Cannot read bytes from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) snprintf(message,FLEN_ERRMSG, "Error reading elements %.0f thru %.0f from column %d (ffgclsb).", dtemp+1., dtemp+ntodo, colnum); else snprintf(message,FLEN_ERRMSG, "Error reading elements %.0f thru %.0f from image (ffgclsb).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } else if (elemnum < 0) /* completed a row; start on a previous row */ { rowincre = (-elemnum - 1) / repeat + 1; rownum -= rowincre; elemnum = (rowincre * repeat) + elemnum; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int fffi1s1(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ signed char nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ signed char *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == -128.) { /* Instead of subtracting 128, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) output[ii] = ( *(signed char *) &input[ii] ) ^ 0x80; } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > 127) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; /* copy input */ } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == -128.) { /* Instead of subtracting 128, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = ( *(signed char *) &input[ii] ) ^ 0x80; } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (signed char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2s1(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ signed char nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ signed char *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < -128) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > 127) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < -128) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > 127) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4s1(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ signed char nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ signed char *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < -128) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > 127) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < -128) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > 127) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8s1(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ signed char nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ signed char *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; ULONGLONG ulltemp; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 9223372036854775808.) { /* The column we read contains unsigned long long values. */ /* Instead of adding 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { ulltemp = (ULONGLONG) (((LONGLONG) input[ii]) ^ 0x8000000000000000); if (ulltemp > 127) { *status = OVERFLOW_ERR; output[ii] = 127; } else { output[ii] = (short) ulltemp; } } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < -128) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > 127) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 9223372036854775808.) { /* The column we read contains unsigned long long values. */ /* Instead of subtracting 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { ulltemp = (ULONGLONG) (((LONGLONG) input[ii]) ^ 0x8000000000000000); if (ulltemp > 127) { *status = OVERFLOW_ERR; output[ii] = 127; } else { output[ii] = (short) ulltemp; } } } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < -128) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > 127) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4s1(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ signed char nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ signed char *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { /* use redundant boolean logic in following statement */ /* to suppress irritating Borland compiler warning message */ if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (zero > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8s1(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ signed char nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ signed char *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (zero > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstrs1(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ signed char nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ signed char *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[FLEN_ERRMSG]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.' || *cptr == ',') /* check for decimal point */ { decpt = 1; cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { snprintf(message, FLEN_ERRMSG,"Cannot read number from ASCII table"); ffpmsg(message); snprintf(message, FLEN_ERRMSG,"Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/getcolui.c0000644000175100001710000022302200000000000020103 0ustar00vstsdocker/* This file, getcolui.c, contains routines that read data elements from */ /* a FITS image or table, with unsigned short datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvui( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned short nulval, /* I - value for undefined pixels */ unsigned short *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; unsigned short nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TUSHORT, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclui(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfui( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned short *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TUSHORT, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclui(fptr, 2, row, firstelem, nelem, 1, 2, 0, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2dui(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ unsigned short nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ unsigned short *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3dui(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3dui(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ unsigned short nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ unsigned short *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}, nfits, narray; LONGLONG lpixel[3]; unsigned short nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TUSHORT, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgclui(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgclui(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvui(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ unsigned short nulval, /* I - value to set undefined pixels */ unsigned short *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; unsigned short nullvalue; if (naxis < 1 || naxis > 9) { snprintf(msg, FLEN_ERRMSG,"NAXIS = %d in call to ffgsvui is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TUSHORT, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { snprintf(msg, FLEN_ERRMSG,"ffgsvui: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgclui(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfui(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ unsigned short *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; int hdutype, anyf; unsigned short nulval = 0; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { snprintf(msg, FLEN_ERRMSG,"NAXIS = %d in call to ffgsvi is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TUSHORT, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { snprintf(msg, FLEN_ERRMSG,"ffgsvi: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgclui(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpui( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ unsigned short *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclui(fptr, 1, row, firstelem, nelem, 1, 1, 0, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvui(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned short nulval, /* I - value for null pixels */ unsigned short *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgclui(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfui(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned short *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { unsigned short dummy = 0; ffgclui(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgclui( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ unsigned short nulval, /* I - value for null pixels if nultyp = 1 */ unsigned short *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem2, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int nulcheck; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre, maxelem; char tform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if ( ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 0, &scale, &zero, tform, &twidth, &tcode, &maxelem2, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); maxelem = maxelem2; incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ if (tcode == TSHORT) /* Special Case: */ { /* no type convertion required, so read */ /* data directly into output buffer. */ if (nelem < (LONGLONG)INT32_MAX/2) { maxelem = nelem; } else { maxelem = INT32_MAX/2; } } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) &array[next], status); fffi2u2((short *) &array[next], ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8u2( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1u2((unsigned char *) buffer, ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) buffer, status); fffi4u2((INT32BIT *) buffer, ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4u2((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8u2((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstru2((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ snprintf(message, FLEN_ERRMSG, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) snprintf(message,FLEN_ERRMSG, "Error reading elements %.0f thru %.0f from column %d (ffgclui).", dtemp+1., dtemp+ntodo, colnum); else snprintf(message,FLEN_ERRMSG, "Error reading elements %.0f thru %.0f from image (ffgclui).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int fffi1u2(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ unsigned short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (unsigned short) input[ii]; /* copy input */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (unsigned short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2u2(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ unsigned short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 32768.) { /* Instead of adding 32768, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) output[ii] = ( *(unsigned short *) &input[ii] ) ^ 0x8000; } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned short) input[ii]; /* copy input */ } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 32768.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = ( *(unsigned short *) &input[ii] ) ^ 0x8000; } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned short) input[ii]; /* copy input */ } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4u2(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ unsigned short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > USHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > USHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8u2(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ unsigned short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; ULONGLONG ulltemp; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 9223372036854775808.) { /* The column we read contains unsigned long long values. */ /* Instead of adding 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { ulltemp = (ULONGLONG) (((LONGLONG) input[ii]) ^ 0x8000000000000000); if (ulltemp > USHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) ulltemp; } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > USHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 9223372036854775808.) { /* The column we read contains unsigned long long values. */ /* Instead of adding 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { ulltemp = (ULONGLONG) (((LONGLONG) input[ii]) ^ 0x8000000000000000); if (ulltemp > USHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else { output[ii] = (unsigned short) ulltemp; } } } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > USHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4u2(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8u2(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstru2(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ unsigned short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[FLEN_ERRMSG]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.' || *cptr == ',') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { snprintf(message,FLEN_ERRMSG, "Cannot read number from ASCII table"); ffpmsg(message); snprintf(message, FLEN_ERRMSG,"Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/getcoluj.c0000644000175100001710000044147100000000000020116 0ustar00vstsdocker/* This file, getcoluj.c, contains routines that read data elements from */ /* a FITS image or table, with unsigned long data type. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvuj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned long nulval, /* I - value for undefined pixels */ unsigned long *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; unsigned long nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TULONG, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcluj(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfuj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned long *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TULONG, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcluj(fptr, 2, row, firstelem, nelem, 1, 2, 0L, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2duj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ unsigned long nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ unsigned long *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3duj(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3duj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ unsigned long nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ unsigned long *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}, nfits, narray; LONGLONG lpixel[3]; unsigned long nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TULONG, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgcluj(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgcluj(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvuj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ unsigned long nulval, /* I - value to set undefined pixels */ unsigned long *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; unsigned long nullvalue; if (naxis < 1 || naxis > 9) { snprintf(msg, FLEN_ERRMSG,"NAXIS = %d in call to ffgsvuj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TULONG, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { snprintf(msg, FLEN_ERRMSG,"ffgsvuj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgcluj(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfuj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ unsigned long *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; unsigned long nulval = 0; int hdutype, anyf; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { snprintf(msg, FLEN_ERRMSG,"NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TULONG, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { snprintf(msg, FLEN_ERRMSG,"ffgsvj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgcluj(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpuj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ unsigned long *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcluj(fptr, 1, row, firstelem, nelem, 1, 1, 0L, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvuj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned long nulval, /* I - value for null pixels */ unsigned long *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgcluj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfuj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned long *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { unsigned long dummy = 0; ffgcluj(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcluj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ unsigned long nulval, /* I - value for null pixels if nultyp = 1 */ unsigned long *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem2, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int nulcheck; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre, maxelem; char tform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if ( ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 0, &scale, &zero, tform, &twidth, &tcode, &maxelem2, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); maxelem = maxelem2; incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ if ((tcode == TLONG) && (LONGSIZE == 32)) /* Special Case: */ { /* no type convertion required, so read */ /* data directly into output buffer. */ if (nelem < (LONGLONG)INT32_MAX/4) { maxelem = nelem; } else { maxelem = INT32_MAX/4; } } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TLONG): if (LONGSIZE == 32) { ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) &array[next], status); fffi4u4((INT32BIT *) &array[next], ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); } else { /* case where sizeof(long) = 8 */ ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) buffer, status); fffi4u4((INT32BIT *) buffer, ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); } break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8u4( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1u4((unsigned char *) buffer, ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2u4((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4u4((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8u4((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstru4((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ snprintf(message,FLEN_ERRMSG, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) snprintf(message,FLEN_ERRMSG, "Error reading elements %.0f thru %.0f from column %d (ffgcluj).", dtemp+1., dtemp+ntodo, colnum); else snprintf(message,FLEN_ERRMSG, "Error reading elements %.0f thru %.0f from image (ffgcluj).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int fffi1u4(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ unsigned long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (unsigned long) input[ii]; /* copy input */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (unsigned long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2u4(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ unsigned long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned long) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4u4(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ unsigned long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 2147483648.) { /* Instead of adding 2147483648, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { output[ii] = ( *(unsigned int *) &input[ii] ) ^ 0x80000000; } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned long) input[ii]; /* copy input */ } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 2147483648.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = ( *(unsigned int *) &input[ii] ) ^ 0x80000000; } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned long) input[ii]; /* copy input */ } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8u4(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ unsigned long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; ULONGLONG ulltemp; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 9223372036854775808.) { /* The column we read contains unsigned long long values. */ /* Instead of adding 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { ulltemp = (ULONGLONG) (((LONGLONG) input[ii]) ^ 0x8000000000000000); if (ulltemp > ULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) ulltemp; } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > ULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 9223372036854775808.) { /* The column we read contains unsigned long long values. */ /* Instead of adding 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { ulltemp = (ULONGLONG) (((LONGLONG) input[ii]) ^ 0x8000000000000000); if (ulltemp > ULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else { output[ii] = (unsigned long) ulltemp; } } } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > ULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4u4(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8u4(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstru4(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ unsigned long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[FLEN_ERRMSG]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.' || *cptr == ',') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { snprintf(message, FLEN_ERRMSG,"Cannot read number from ASCII table"); ffpmsg(message); snprintf(message, FLEN_ERRMSG,"Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } /* ======================================================================== */ /* the following routines support the 'long long' data type */ /* ======================================================================== */ /*--------------------------------------------------------------------------*/ int ffgpvujj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ ULONGLONG nulval, /* I - value for undefined pixels */ ULONGLONG *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; ULONGLONG nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TULONGLONG, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclujj(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfujj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ ULONGLONG *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; ULONGLONG dummy = 0; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TULONGLONG, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclujj(fptr, 2, row, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2dujj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ ULONGLONG nulval ,/* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ ULONGLONG *array,/* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3dujj(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3dujj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ ULONGLONG nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ ULONGLONG *array,/* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}, nfits, narray; LONGLONG lpixel[3]; ULONGLONG nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TULONGLONG, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgclujj(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgclujj(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvujj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ ULONGLONG nulval,/* I - value to set undefined pixels */ ULONGLONG *array,/* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dir[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; ULONGLONG nullvalue; if (naxis < 1 || naxis > 9) { snprintf(msg, FLEN_ERRMSG, "NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TULONGLONG, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; dir[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { if (hdutype == IMAGE_HDU) { dir[ii] = -1; } else { snprintf(msg, FLEN_ERRMSG,"ffgsvj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; dsize[ii] = dsize[ii] * dir[ii]; } dsize[naxis] = dsize[naxis] * dir[naxis]; if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0]*dir[0] - str[0]*dir[0]) / inc[0] + 1; ninc = incr[0] * dir[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]*dir[8]; i8 <= stp[8]*dir[8]; i8 += incr[8]) { for (i7 = str[7]*dir[7]; i7 <= stp[7]*dir[7]; i7 += incr[7]) { for (i6 = str[6]*dir[6]; i6 <= stp[6]*dir[6]; i6 += incr[6]) { for (i5 = str[5]*dir[5]; i5 <= stp[5]*dir[5]; i5 += incr[5]) { for (i4 = str[4]*dir[4]; i4 <= stp[4]*dir[4]; i4 += incr[4]) { for (i3 = str[3]*dir[3]; i3 <= stp[3]*dir[3]; i3 += incr[3]) { for (i2 = str[2]*dir[2]; i2 <= stp[2]*dir[2]; i2 += incr[2]) { for (i1 = str[1]*dir[1]; i1 <= stp[1]*dir[1]; i1 += incr[1]) { felem=str[0] + (i1 - dir[1]) * dsize[1] + (i2 - dir[2]) * dsize[2] + (i3 - dir[3]) * dsize[3] + (i4 - dir[4]) * dsize[4] + (i5 - dir[5]) * dsize[5] + (i6 - dir[6]) * dsize[6] + (i7 - dir[7]) * dsize[7] + (i8 - dir[8]) * dsize[8]; if ( ffgclujj(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfujj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ ULONGLONG *array,/* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; ULONGLONG nulval = 0; int hdutype, anyf; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { snprintf(msg, FLEN_ERRMSG,"NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TULONGLONG, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { snprintf(msg, FLEN_ERRMSG,"ffgsvujj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgclujj(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpujj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ ULONGLONG *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; ULONGLONG dummy = 0; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclujj(fptr, 1, row, firstelem, nelem, 1, 1, dummy, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvujj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ ULONGLONG nulval, /* I - value for null pixels */ ULONGLONG *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgclujj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfujj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ ULONGLONG *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { ULONGLONG dummy = 0; ffgclujj(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgclujj( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ ULONGLONG nulval, /* I - value for null pixels if nultyp = 1 */ ULONGLONG *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem2, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int convert, nulcheck, readcheck = 0; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre, maxelem; char tform[20]; char message[81]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (elemincre < 0) readcheck = -1; /* don't do range checking in this case */ if (ffgcprll(fptr, colnum, firstrow, firstelem, nelem, readcheck, &scale, &zero, tform, &twidth, &tcode, &maxelem2, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); maxelem = maxelem2; incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; convert = 1; /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); if (elemincre >= 0) { ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); } else { ntodo = (long) minvalue(ntodo, (elemnum/(-elemincre) +1)); } readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) &array[next], status); fffi8u8((LONGLONG *) &array[next], ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) buffer, status); fffi4u8((INT32BIT *) buffer, ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1u8((unsigned char *) buffer, ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2u8((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4u8((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8u8((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstru8((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ snprintf(message, 81, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) snprintf(message, 81, "Error reading elements %.0f thru %.0f from column %d (ffgclj).", dtemp+1., dtemp+ntodo, colnum); else snprintf(message, 81, "Error reading elements %.0f thru %.0f from image (ffgclj).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } else if (elemnum < 0) /* completed a row; start on a previous row */ { rowincre = (-elemnum - 1) / repeat + 1; rownum -= rowincre; elemnum = (rowincre * repeat) + elemnum; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int fffi1u8(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ ULONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ ULONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else { output[ii] = (ULONGLONG) input[ii]; /* copy input to output */ } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT64_MAX; } else output[ii] = (ULONGLONG) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (ULONGLONG) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT64_MAX; } else output[ii] = (ULONGLONG) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2u8(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ ULONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ ULONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else { output[ii] = (ULONGLONG) input[ii]; /* copy input to output */ } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (LONGLONG) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4u8(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ ULONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ ULONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else { output[ii] = (ULONGLONG) input[ii]; /* copy input to output */ } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT64_MAX; } else output[ii] = (LONGLONG) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else { output[ii] = (ULONGLONG) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT64_MAX; } else output[ii] = (ULONGLONG) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8u8(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ ULONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ ULONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 9223372036854775808.) { /* The column we read contains unsigned long long values. */ /* Instead of adding 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { output[ii] = (ULONGLONG) (((LONGLONG) input[ii]) ^ 0x8000000000000000); } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else { output[ii] = input[ii]; /* copy input to output */ } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT64_MAX; } else output[ii] = (ULONGLONG) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 9223372036854775808.) { /* The column we read contains unsigned long long values. */ /* Instead of adding 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { output[ii] = (ULONGLONG) (((LONGLONG) input[ii]) ^ 0x8000000000000000); } } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else { output[ii] = input[ii]; /* copy input to output */ } } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT64_MAX; } else output[ii] = (ULONGLONG) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4u8(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ ULONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ ULONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DULONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT64_MAX; } else output[ii] = (ULONGLONG) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT64_MAX; } else output[ii] = (ULONGLONG) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DULONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT64_MAX; } else output[ii] = (ULONGLONG) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DULONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT64_MAX; } else output[ii] = (ULONGLONG) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT64_MAX; } else output[ii] = (ULONGLONG) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8u8(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ ULONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ ULONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DULONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT64_MAX; } else output[ii] = (ULONGLONG) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT64_MAX; } else output[ii] = (ULONGLONG) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DULONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT64_MAX; } else output[ii] = (ULONGLONG) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DULONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT64_MAX; } else output[ii] = (ULONGLONG) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT64_MAX; } else output[ii] = (ULONGLONG) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstru8(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ ULONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ ULONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[81]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.' || *cptr == ',') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { sprintf(message, "Cannot read number from ASCII table"); ffpmsg(message); snprintf(message, 81, "Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT64_MAX; } else output[ii] = (ULONGLONG) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/getcoluk.c0000644000175100001710000022334500000000000020115 0ustar00vstsdocker/* This file, getcolk.c, contains routines that read data elements from */ /* a FITS image or table, with 'unsigned int' data type. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvuk( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned int nulval, /* I - value for undefined pixels */ unsigned int *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; unsigned int nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TUINT, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcluk(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfuk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned int *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TUINT, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcluk(fptr, 2, row, firstelem, nelem, 1, 2, 0L, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2duk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ unsigned int nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ unsigned int *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3duk(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3duk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ unsigned int nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ unsigned int *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}, nfits, narray; LONGLONG lpixel[3]; unsigned int nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TUINT, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgcluk(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgcluk(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvuk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ unsigned int nulval, /* I - value to set undefined pixels */ unsigned int *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; unsigned int nullvalue; if (naxis < 1 || naxis > 9) { snprintf(msg, FLEN_ERRMSG,"NAXIS = %d in call to ffgsvuk is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TUINT, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { snprintf(msg, FLEN_ERRMSG,"ffgsvuk: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgcluk(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfuk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ unsigned int *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; long nulval = 0; int hdutype, anyf; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { snprintf(msg, FLEN_ERRMSG,"NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TUINT, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { snprintf(msg, FLEN_ERRMSG,"ffgsvj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgcluk(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpuk( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ unsigned int *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcluk(fptr, 1, row, firstelem, nelem, 1, 1, 0L, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvuk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned int nulval, /* I - value for null pixels */ unsigned int *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgcluk(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfuk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned int *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { int dummy = 0; ffgcluk(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcluk( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ unsigned int nulval, /* I - value for null pixels if nultyp = 1 */ unsigned int *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem2, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int nulcheck; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre, maxelem; char tform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* call the 'short' or 'long' version of this routine, if possible */ if (sizeof(int) == sizeof(short)) ffgclui(fptr, colnum, firstrow, firstelem, nelem, elemincre, nultyp, (unsigned short) nulval, (unsigned short *) array, nularray, anynul, status); else if (sizeof(int) == sizeof(long)) ffgcluj(fptr, colnum, firstrow, firstelem, nelem, elemincre, nultyp, (unsigned long) nulval, (unsigned long *) array, nularray, anynul, status); else { /* This is a special case: sizeof(int) is not equal to sizeof(short) or sizeof(long). This occurs on Alpha OSF systems where short = 2 bytes, int = 4 bytes, and long = 8 bytes. */ buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if ( ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 0, &scale, &zero, tform, &twidth, &tcode, &maxelem2, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); maxelem = maxelem2; incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ if (tcode == TLONG) /* Special Case: */ { /* data are 4-bytes long, so read */ /* data directly into output buffer. */ if (nelem < (LONGLONG)INT32_MAX/4) { maxelem = nelem; } else { maxelem = INT32_MAX/4; } } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) &array[next], status); fffi4uint((INT32BIT *) &array[next], ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8uint( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1uint((unsigned char *) buffer, ntodo, scale, zero,nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2uint((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4uint((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8uint((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstruint((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ snprintf(message, FLEN_ERRMSG, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) snprintf(message,FLEN_ERRMSG, "Error reading elements %.0f thru %.0f from column %d (ffgcluk).", dtemp+1., dtemp+ntodo, colnum); else snprintf(message,FLEN_ERRMSG, "Error reading elements %.0f thru %.0f from image (ffgcluk).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } } /* end of DEC Alpha special case */ return(*status); } /*--------------------------------------------------------------------------*/ int fffi1uint(unsigned char *input,/* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ unsigned int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (unsigned int) input[ii]; /* copy input */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (unsigned int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2uint(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ unsigned int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned int) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4uint(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ unsigned int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 2147483648.) { /* Instead of adding 2147483648, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) output[ii] = ( *(unsigned int *) &input[ii] ) ^ 0x80000000; } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned int) input[ii]; /* copy to output */ } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 2147483648.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = ( *(unsigned int *) &input[ii] ) ^ 0x80000000; } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8uint(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ unsigned int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; ULONGLONG ulltemp; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 9223372036854775808.) { /* The column we read contains unsigned long long values. */ /* Instead of adding 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { ulltemp = (ULONGLONG) (((LONGLONG) input[ii]) ^ 0x8000000000000000); if (ulltemp > UINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) ulltemp; } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 9223372036854775808.) { /* The column we read contains unsigned long long values. */ /* Instead of adding 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { ulltemp = (ULONGLONG) (((LONGLONG) input[ii]) ^ 0x8000000000000000); if (ulltemp > UINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else { output[ii] = (unsigned int) ulltemp; } } } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4uint(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8uint(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstruint(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ unsigned int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[FLEN_ERRMSG]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.' || *cptr == ',') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { snprintf(message, FLEN_ERRMSG,"Cannot read number from ASCII table"); ffpmsg(message); snprintf(message, FLEN_ERRMSG,"Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (long) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/getkey.c0000644000175100001710000036545600000000000017602 0ustar00vstsdocker/* This file, getkey.c, contains routines that read keywords from */ /* a FITS header. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include /* stddef.h is apparently needed to define size_t */ #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffghsp(fitsfile *fptr, /* I - FITS file pointer */ int *nexist, /* O - number of existing keywords in header */ int *nmore, /* O - how many more keywords will fit */ int *status) /* IO - error status */ /* returns the number of existing keywords (not counting the END keyword) and the number of more keyword that will fit in the current header without having to insert more FITS blocks. */ { if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (nexist) *nexist = (int) (( ((fptr->Fptr)->headend) - ((fptr->Fptr)->headstart[(fptr->Fptr)->curhdu]) ) / 80); if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if (nmore) *nmore = -1; /* data not written yet, so room for any keywords */ } else { /* calculate space available between the data and the END card */ if (nmore) *nmore = (int) (((fptr->Fptr)->datastart - (fptr->Fptr)->headend) / 80 - 1); } return(*status); } /*--------------------------------------------------------------------------*/ int ffghps(fitsfile *fptr, /* I - FITS file pointer */ int *nexist, /* O - number of existing keywords in header */ int *position, /* O - position of next keyword to be read */ int *status) /* IO - error status */ /* return the number of existing keywords and the position of the next keyword that will be read. */ { if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (nexist) *nexist = (int) (( ((fptr->Fptr)->headend) - ((fptr->Fptr)->headstart[(fptr->Fptr)->curhdu]) ) / 80); if (position) *position = (int) (( ((fptr->Fptr)->nextkey) - ((fptr->Fptr)->headstart[(fptr->Fptr)->curhdu]) ) / 80 + 1); return(*status); } /*--------------------------------------------------------------------------*/ int ffnchk(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* function returns the position of the first null character (ASCII 0), if any, in the current header. Null characters are illegal, but the other CFITSIO routines that read the header will not detect this error, because the null gets interpreted as a normal end of string character. */ { long ii, nblock; LONGLONG bytepos; int length, nullpos; char block[2881]; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { return(0); /* Don't check a file that is just being created. */ /* It cannot contain nulls since CFITSIO wrote it. */ } else { /* calculate number of blocks in the header */ nblock = (long) (( (fptr->Fptr)->datastart - (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) / 2880); } bytepos = (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu]; ffmbyt(fptr, bytepos, REPORT_EOF, status); /* move to read pos. */ block[2880] = '\0'; for (ii = 0; ii < nblock; ii++) { if (ffgbyt(fptr, 2880, block, status) > 0) return(0); /* read error of some sort */ length = strlen(block); if (length != 2880) { nullpos = (ii * 2880) + length + 1; return(nullpos); } } return(0); } /*--------------------------------------------------------------------------*/ int ffmaky(fitsfile *fptr, /* I - FITS file pointer */ int nrec, /* I - one-based keyword number to move to */ int *status) /* IO - error status */ { /* move pointer to the specified absolute keyword position. E.g. this keyword will then be read by the next call to ffgnky. */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] + ( (nrec - 1) * 80); return(*status); } /*--------------------------------------------------------------------------*/ int ffmrky(fitsfile *fptr, /* I - FITS file pointer */ int nmove, /* I - relative number of keywords to move */ int *status) /* IO - error status */ { /* move pointer to the specified keyword position relative to the current position. E.g. this keyword will then be read by the next call to ffgnky. */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); (fptr->Fptr)->nextkey += (nmove * 80); return(*status); } /*--------------------------------------------------------------------------*/ int ffgnky(fitsfile *fptr, /* I - FITS file pointer */ char *card, /* O - card string */ int *status) /* IO - error status */ /* read the next keyword from the header - used internally by cfitsio */ { int jj, nrec; LONGLONG bytepos, endhead; char message[FLEN_ERRMSG]; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); card[0] = '\0'; /* make sure card is terminated, even affer read error */ /* Check that nextkey points to a legal keyword position. Note that headend is the current end of the header, i.e., the position where a new keyword would be appended, however, if there are more than 1 FITS block worth of blank keywords at the end of the header (36 keywords per 2880 byte block) then the actual physical END card must be located at a starting position which is just 2880 bytes prior to the start of the data unit. */ bytepos = (fptr->Fptr)->nextkey; endhead = maxvalue( ((fptr->Fptr)->headend), ((fptr->Fptr)->datastart - 2880) ); /* nextkey must be < endhead and > than headstart */ if (bytepos > endhead || bytepos < (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) { nrec= (int) ((bytepos - (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu]) / 80 + 1); snprintf(message, FLEN_ERRMSG,"Cannot get keyword number %d. It does not exist.", nrec); ffpmsg(message); return(*status = KEY_OUT_BOUNDS); } ffmbyt(fptr, bytepos, REPORT_EOF, status); /* move to read pos. */ card[80] = '\0'; /* make sure card is terminate, even if ffgbyt fails */ if (ffgbyt(fptr, 80, card, status) <= 0) { (fptr->Fptr)->nextkey += 80; /* increment pointer to next keyword */ /* strip off trailing blanks with terminated string */ jj = 79; while (jj >= 0 && card[jj] == ' ') jj--; card[jj + 1] = '\0'; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgnxk( fitsfile *fptr, /* I - FITS file pointer */ char **inclist, /* I - list of included keyword names */ int ninc, /* I - number of names in inclist */ char **exclist, /* I - list of excluded keyword names */ int nexc, /* I - number of names in exclist */ char *card, /* O - first matching keyword */ int *status) /* IO - error status */ /* Return the next keyword that matches one of the names in inclist but does not match any of the names in exclist. The search goes from the current position to the end of the header, only. Wild card characters may be used in the name lists ('*', '?' and '#'). */ { int casesn, match, exact, namelen; long ii, jj; char keybuf[FLEN_CARD], keyname[FLEN_KEYWORD]; card[0] = '\0'; if (*status > 0) return(*status); casesn = FALSE; /* get next card, and return with an error if hit end of header */ while( ffgcrd(fptr, "*", keybuf, status) <= 0) { ffgknm(keybuf, keyname, &namelen, status); /* get the keyword name */ /* does keyword match any names in the include list? */ for (ii = 0; ii < ninc; ii++) { ffcmps(inclist[ii], keyname, casesn, &match, &exact); if (match) { /* does keyword match any names in the exclusion list? */ jj = -1; while ( ++jj < nexc ) { ffcmps(exclist[jj], keyname, casesn, &match, &exact); if (match) break; } if (jj >= nexc) { /* not in exclusion list, so return this keyword */ strcat(card, keybuf); return(*status); } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgky( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ const char *keyname, /* I - name of keyword to read */ void *value, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the keyword value and comment from the FITS header. Reads a keyword value with the datatype specified by the 2nd argument. */ { LONGLONG longval; ULONGLONG ulongval; double doubleval; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (datatype == TSTRING) { ffgkys(fptr, keyname, (char *) value, comm, status); } else if (datatype == TBYTE) { if (ffgkyjj(fptr, keyname, &longval, comm, status) <= 0) { if (longval > UCHAR_MAX || longval < 0) *status = NUM_OVERFLOW; else *(unsigned char *) value = (unsigned char) longval; } } else if (datatype == TSBYTE) { if (ffgkyjj(fptr, keyname, &longval, comm, status) <= 0) { if (longval > 127 || longval < -128) *status = NUM_OVERFLOW; else *(signed char *) value = (signed char) longval; } } else if (datatype == TUSHORT) { if (ffgkyjj(fptr, keyname, &longval, comm, status) <= 0) { if (longval > (long) USHRT_MAX || longval < 0) *status = NUM_OVERFLOW; else *(unsigned short *) value = (unsigned short) longval; } } else if (datatype == TSHORT) { if (ffgkyjj(fptr, keyname, &longval, comm, status) <= 0) { if (longval > SHRT_MAX || longval < SHRT_MIN) *status = NUM_OVERFLOW; else *(short *) value = (short) longval; } } else if (datatype == TUINT) { if (ffgkyjj(fptr, keyname, &longval, comm, status) <= 0) { if (longval > (long) UINT_MAX || longval < 0) *status = NUM_OVERFLOW; else *(unsigned int *) value = longval; } } else if (datatype == TINT) { if (ffgkyjj(fptr, keyname, &longval, comm, status) <= 0) { if (longval > INT_MAX || longval < INT_MIN) *status = NUM_OVERFLOW; else *(int *) value = longval; } } else if (datatype == TLOGICAL) { ffgkyl(fptr, keyname, (int *) value, comm, status); } else if (datatype == TULONG) { if (ffgkyujj(fptr, keyname, &ulongval, comm, status) <= 0) { if (ulongval > ULONG_MAX) *status = NUM_OVERFLOW; else *(unsigned long *) value = ulongval; } } else if (datatype == TLONG) { if (ffgkyjj(fptr, keyname, &longval, comm, status) <= 0) { if (longval > LONG_MAX || longval < LONG_MIN) *status = NUM_OVERFLOW; else *(int *) value = longval; } ffgkyj(fptr, keyname, (long *) value, comm, status); } else if (datatype == TULONGLONG) { ffgkyujj(fptr, keyname, (ULONGLONG *) value, comm, status); } else if (datatype == TLONGLONG) { ffgkyjj(fptr, keyname, (LONGLONG *) value, comm, status); } else if (datatype == TFLOAT) { ffgkye(fptr, keyname, (float *) value, comm, status); } else if (datatype == TDOUBLE) { ffgkyd(fptr, keyname, (double *) value, comm, status); } else if (datatype == TCOMPLEX) { ffgkyc(fptr, keyname, (float *) value, comm, status); } else if (datatype == TDBLCOMPLEX) { ffgkym(fptr, keyname, (double *) value, comm, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffgkey( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - name of keyword to read */ char *keyval, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the keyword value and comment. The value is just the literal string of characters in the value field of the keyword. In the case of a string valued keyword, the returned value includes the leading and closing quote characters. The value may be up to 70 characters long, and the comment may be up to 72 characters long. If the keyword has no value (no equal sign in column 9) then a null value is returned. */ { char card[FLEN_CARD]; keyval[0] = '\0'; if (comm) comm[0] = '\0'; if (*status > 0) return(*status); if (ffgcrd(fptr, keyname, card, status) > 0) /* get the 80-byte card */ return(*status); ffpsvc(card, keyval, comm, status); /* parse the value and comment */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgrec( fitsfile *fptr, /* I - FITS file pointer */ int nrec, /* I - number of keyword to read */ char *card, /* O - keyword card */ int *status) /* IO - error status */ /* Read (get) the nrec-th keyword, returning the entire keyword card up to 80 characters long. The first keyword in the header has nrec = 1, not 0. The returned card value is null terminated with any trailing blank characters removed. If nrec = 0, then this routine simply moves the current header pointer to the top of the header. */ { if (*status > 0) return(*status); if (nrec == 0) { ffmaky(fptr, 1, status); /* simply move to beginning of header */ if (card) card[0] = '\0'; /* and return null card */ } else if (nrec > 0) { ffmaky(fptr, nrec, status); ffgnky(fptr, card, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgcrd( fitsfile *fptr, /* I - FITS file pointer */ const char *name, /* I - name of keyword to read */ char *card, /* O - keyword card */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the entire keyword card up to 80 characters long. The returned card value is null terminated with any trailing blank characters removed. If the input name contains wild cards ('?' matches any single char and '*' matches any sequence of chars, # matches any string of decimal digits) then the search ends once the end of header is reached and does not automatically resume from the top of the header. */ { int nkeys, nextkey, ntodo, namelen, namelen_limit, namelenminus1, cardlen; int ii = 0, jj, kk, wild, match, exact, hier = 0; char keyname[FLEN_KEYWORD], cardname[FLEN_KEYWORD]; char *ptr1, *ptr2, *gotstar; if (*status > 0) return(*status); *keyname = '\0'; while (name[ii] == ' ') /* skip leading blanks in name */ ii++; strncat(keyname, &name[ii], FLEN_KEYWORD - 1); namelen = strlen(keyname); while (namelen > 0 && keyname[namelen - 1] == ' ') namelen--; /* ignore trailing blanks in name */ keyname[namelen] = '\0'; /* terminate the name */ for (ii=0; ii < namelen; ii++) keyname[ii] = toupper(keyname[ii]); /* make upper case */ if (FSTRNCMP("HIERARCH", keyname, 8) == 0) { if (namelen == 8) { /* special case: just looking for any HIERARCH keyword */ hier = 1; } else { /* ignore the leading HIERARCH and look for the 'real' name */ /* starting with first non-blank character following HIERARCH */ ptr1 = keyname; ptr2 = &keyname[8]; while(*ptr2 == ' ') ptr2++; namelen = 0; while(*ptr2) { *ptr1 = *ptr2; ptr1++; ptr2++; namelen++; } *ptr1 = '\0'; } } /* does input name contain wild card chars? ('?', '*', or '#') */ /* wild cards are currently not supported with HIERARCH keywords */ namelen_limit = namelen; gotstar = 0; if (namelen < 9 && (strchr(keyname,'?') || (gotstar = strchr(keyname,'*')) || strchr(keyname,'#')) ) { wild = 1; /* if we found a '*' wild card in the name, there might be */ /* more than one. Support up to 2 '*' in the template. */ /* Thus we need to compare keywords whose names have at least */ /* namelen - 2 characters. */ if (gotstar) namelen_limit -= 2; } else wild = 0; ffghps(fptr, &nkeys, &nextkey, status); /* get no. keywords and position */ namelenminus1 = maxvalue(namelen - 1, 1); ntodo = nkeys - nextkey + 1; /* first, read from next keyword to end */ for (jj=0; jj < 2; jj++) { for (kk = 0; kk < ntodo; kk++) { ffgnky(fptr, card, status); /* get next keyword */ if (hier) { if (FSTRNCMP("HIERARCH", card, 8) == 0) return(*status); /* found a HIERARCH keyword */ } else { ffgknm(card, cardname, &cardlen, status); /* get the keyword name */ if (cardlen >= namelen_limit) /* can't match if card < name */ { /* if there are no wild cards, lengths must be the same */ if (!( !wild && cardlen != namelen) ) { for (ii=0; ii < cardlen; ii++) { /* make sure keyword is in uppercase */ if (cardname[ii] > 96) { /* This assumes the ASCII character set in which */ /* upper case characters start at ASCII(97) */ /* Timing tests showed that this is 20% faster */ /* than calling the isupper function. */ cardname[ii] = toupper(cardname[ii]); /* make upper case */ } } if (wild) { ffcmps(keyname, cardname, 1, &match, &exact); if (match) return(*status); /* found a matching keyword */ } else if (keyname[namelenminus1] == cardname[namelenminus1]) { /* test the last character of the keyword name first, on */ /* the theory that it is less likely to match then the first */ /* character since many keywords begin with 'T', for example */ if (FSTRNCMP(keyname, cardname, namelenminus1) == 0) { return(*status); /* found the matching keyword */ } } else if (namelen == 0 && cardlen == 0) { /* matched a blank keyword */ return(*status); } } } } } if (wild || jj == 1) break; /* stop at end of header if template contains wildcards */ ffmaky(fptr, 1, status); /* reset pointer to beginning of header */ ntodo = nextkey - 1; /* number of keyword to read */ } return(*status = KEY_NO_EXIST); /* couldn't find the keyword */ } /*--------------------------------------------------------------------------*/ int ffgstr( fitsfile *fptr, /* I - FITS file pointer */ const char *string, /* I - string to match */ char *card, /* O - keyword card */ int *status) /* IO - error status */ /* Read (get) the next keyword record that contains the input character string, returning the entire keyword card up to 80 characters long. The returned card value is null terminated with any trailing blank characters removed. */ { int nkeys, nextkey, ntodo, stringlen; int jj, kk; if (*status > 0) return(*status); stringlen = strlen(string); if (stringlen > 80) { return(*status = KEY_NO_EXIST); /* matching string is too long to exist */ } ffghps(fptr, &nkeys, &nextkey, status); /* get no. keywords and position */ ntodo = nkeys - nextkey + 1; /* first, read from next keyword to end */ for (jj=0; jj < 2; jj++) { for (kk = 0; kk < ntodo; kk++) { ffgnky(fptr, card, status); /* get next keyword */ if (strstr(card, string) != 0) { return(*status); /* found the matching string */ } } ffmaky(fptr, 1, status); /* reset pointer to beginning of header */ ntodo = nextkey - 1; /* number of keyword to read */ } return(*status = KEY_NO_EXIST); /* couldn't find the keyword */ } /*--------------------------------------------------------------------------*/ int ffgknm( char *card, /* I - keyword card */ char *name, /* O - name of the keyword */ int *length, /* O - length of the keyword name */ int *status) /* IO - error status */ /* Return the name of the keyword, and the name length. This supports the ESO HIERARCH convention where keyword names may be > 8 characters long. */ { char *ptr1, *ptr2; int ii, namelength; namelength = FLEN_KEYWORD - 1; *name = '\0'; *length = 0; /* support for ESO HIERARCH keywords; find the '=' */ if (FSTRNCMP(card, "HIERARCH ", 9) == 0) { ptr2 = strchr(card, '='); if (!ptr2) /* no value indicator ??? */ { /* this probably indicates an error, so just return FITS name */ strcat(name, "HIERARCH"); *length = 8; return(*status); } /* find the start and end of the HIERARCH name */ ptr1 = &card[9]; while (*ptr1 == ' ') /* skip spaces */ ptr1++; strncat(name, ptr1, ptr2 - ptr1); ii = ptr2 - ptr1; while (ii > 0 && name[ii - 1] == ' ') /* remove trailing spaces */ ii--; name[ii] = '\0'; *length = ii; } else { for (ii = 0; ii < namelength; ii++) { /* look for string terminator, or a blank */ if (*(card+ii) != ' ' && *(card+ii) != '=' && *(card+ii) !='\0') { *(name+ii) = *(card+ii); } else { name[ii] = '\0'; *length = ii; return(*status); } } /* if we got here, keyword is namelength characters long */ name[namelength] = '\0'; *length = namelength; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgunt( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - name of keyword to read */ char *unit, /* O - keyword units */ int *status) /* IO - error status */ /* Read (get) the units string from the comment field of the existing keyword. This routine uses a local FITS convention (not defined in the official FITS standard) in which the units are enclosed in square brackets following the '/' comment field delimiter, e.g.: KEYWORD = 12 / [kpc] comment string goes here */ { char valstring[FLEN_VALUE]; char comm[FLEN_COMMENT]; char *loc; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ if (comm[0] == '[') { loc = strchr(comm, ']'); /* find the closing bracket */ if (loc) *loc = '\0'; /* terminate the string */ strcpy(unit, &comm[1]); /* copy the string */ } else unit[0] = '\0'; return(*status); } /*--------------------------------------------------------------------------*/ int ffgkys( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - name of keyword to read */ char *value, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Get KeYword with a String value: Read (get) a simple string valued keyword. The returned value may be up to 68 chars long ( + 1 null terminator char). The routine does not support the HEASARC convention for continuing long string values over multiple keywords. The ffgkls routine may be used to read long continued strings. The returned comment string may be up to 69 characters long (including null terminator). */ { char valstring[FLEN_VALUE]; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ value[0] = '\0'; ffc2s(valstring, value, status); /* remove quotes from string */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgksl( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - name of keyword to read */ int *length, /* O - length of the string value */ int *status) /* IO - error status */ /* Get the length of the keyword value string. This routine explicitly supports the CONTINUE convention for long string values. */ { char valstring[FLEN_VALUE], value[FLEN_VALUE]; int position, contin, len; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, NULL, status); /* read the keyword */ if (*status > 0) return(*status); ffghps(fptr, NULL, &position, status); /* save the current header position */ if (!valstring[0]) { /* null value string? */ *length = 0; } else { ffc2s(valstring, value, status); /* in case string contains "/" char */ *length = strlen(value); /* If last character is a & then value may be continued on next keyword */ contin = 1; while (contin) { len = strlen(value); if (len && *(value+len-1) == '&') /* is last char an anpersand? */ { ffgcnt(fptr, value, NULL, status); if (*value) /* a null valstring indicates no continuation */ { *length += strlen(value) - 1; } else { contin = 0; } } else { contin = 0; } } } ffmaky(fptr, position - 1, status); /* reset header pointer to the keyword */ /* since in many cases the program will read */ /* the string value after getting the length */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkls( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - name of keyword to read */ char **value, /* O - pointer to keyword value */ char *comm, /* O - keyword comment (may be NULL) */ int *status) /* IO - error status */ /* This is the original routine for reading long string keywords that use the CONTINUE keyword convention. In 2016 a new routine called ffgsky / fits_read_string_key was added, which may provide a more convenient user interface for most applications. Get Keyword with possible Long String value: Read (get) the named keyword, returning the value and comment. The returned value string may be arbitrarily long (by using the HEASARC convention for continuing long string values over multiple keywords) so this routine allocates the required memory for the returned string value. It is up to the calling routine to free the memory once it is finished with the value string. The returned comment string may be up to 69 characters long. */ { char valstring[FLEN_VALUE], nextcomm[FLEN_COMMENT]; int contin, commspace = 0; size_t len; if (*status > 0) return(*status); *value = NULL; /* initialize a null pointer in case of error */ ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ if (*status > 0) return(*status); if (comm) { /* remaining space in comment string */ commspace = FLEN_COMMENT - strlen(comm) - 2; } if (!valstring[0]) /* null value string? */ { *value = (char *) malloc(1); /* allocate and return a null string */ **value = '\0'; } else { /* allocate space, plus 1 for null */ *value = (char *) malloc(strlen(valstring) + 1); ffc2s(valstring, *value, status); /* convert string to value */ len = strlen(*value); /* If last character is a & then value may be continued on next keyword */ contin = 1; while (contin) { if (len && *(*value+len-1) == '&') /* is last char an ampersand? */ { ffgcnt(fptr, valstring, nextcomm, status); if (*valstring) /* a null valstring indicates no continuation */ { *(*value+len-1) = '\0'; /* erase the trailing & char */ len += strlen(valstring) - 1; *value = (char *) realloc(*value, len + 1); /* increase size */ strcat(*value, valstring); /* append the continued chars */ } else { contin = 0; /* Without this, for case of a last CONTINUE statement ending with a '&', nextcomm would retain the same string from from the previous loop iteration and the comment would get concantenated twice. */ nextcomm[0] = 0; } /* concantenate comment strings (if any) */ if ((commspace > 0) && (*nextcomm != 0)) { strcat(comm, " "); strncat(comm, nextcomm, commspace); commspace = FLEN_COMMENT - strlen(comm) - 2; } } else { contin = 0; } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsky( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - name of keyword to read */ int firstchar, /* I - first character of string to return */ int maxchar, /* I - maximum length of string to return */ /* (string will be null terminated) */ char *value, /* O - pointer to keyword value */ int *valuelen, /* O - total length of the keyword value string */ /* The returned 'value' string may only */ /* contain a piece of the total string, depending */ /* on the value of firstchar and maxchar */ char *comm, /* O - keyword comment (may be NULL) */ int *status) /* IO - error status */ /* Read and return the value of the specified string-valued keyword. This new routine was added in 2016 to provide a more convenient user interface than the older ffgkls routine. Read a string keyword, returning up to 'naxchars' characters of the value starting with the 'firstchar' character. The input 'value' string must be allocated at least 1 char bigger to allow for the terminating null character. This routine may be used to read continued string keywords that use the CONTINUE keyword convention, as well as normal string keywords that are contained within a single header record. This routine differs from the ffkls routine in that it does not internally allocate memory for the returned value string, and consequently the calling routine does not need to call fffree to free the memory. */ { char valstring[FLEN_VALUE], nextcomm[FLEN_COMMENT]; char *tempstring; int contin, commspace = 0; size_t len; if (*status > 0) return(*status); tempstring = NULL; /* initialize in case of error */ *value = '\0'; if (valuelen) *valuelen = 0; ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ if (*status > 0) return(*status); if (comm) { /* remaining space in comment string */ commspace = FLEN_COMMENT - strlen(comm) - 2; } if (!valstring[0]) /* null value string? */ { tempstring = (char *) malloc(1); /* allocate and return a null string */ *tempstring = '\0'; } else { /* allocate space, plus 1 for null */ tempstring = (char *) malloc(strlen(valstring) + 1); ffc2s(valstring, tempstring, status); /* convert string to value */ len = strlen(tempstring); /* If last character is a & then value may be continued on next keyword */ contin = 1; while (contin && *status <= 0) { if (len && *(tempstring+len-1) == '&') /* is last char an anpersand? */ { ffgcnt(fptr, valstring, nextcomm, status); if (*valstring) /* a null valstring indicates no continuation */ { *(tempstring+len-1) = '\0'; /* erase the trailing & char */ len += strlen(valstring) - 1; tempstring = (char *) realloc(tempstring, len + 1); /* increase size */ strcat(tempstring, valstring); /* append the continued chars */ } else { contin = 0; /* Without this, for case of a last CONTINUE statement ending with a '&', nextcomm would retain the same string from from the previous loop iteration and the comment would get concantenated twice. */ nextcomm[0] = 0; } /* concantenate comment strings (if any) */ if ((commspace > 0) && (*nextcomm != 0)) { strcat(comm, " "); strncat(comm, nextcomm, commspace); commspace = FLEN_COMMENT - strlen(comm) - 2; } } else { contin = 0; } } } if (tempstring) { len = strlen(tempstring); if (firstchar <= len) strncat(value, tempstring + (firstchar - 1), maxchar); free(tempstring); if (valuelen) *valuelen = len; /* total length of the keyword value */ } return(*status); } /*--------------------------------------------------------------------------*/ int fffree( void *value, /* I - pointer to keyword value */ int *status) /* IO - error status */ /* Free the memory that was previously allocated by CFITSIO, such as by ffgkls or fits_hdr2str */ { if (*status > 0) return(*status); if (value) free(value); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcnt( fitsfile *fptr, /* I - FITS file pointer */ char *value, /* O - continued string value */ char *comm, /* O - continued comment string */ int *status) /* IO - error status */ /* Attempt to read the next keyword, returning the string value if it is a continuation of the previous string keyword value. This uses the HEASARC convention for continuing long string values over multiple keywords. Each continued string is terminated with a backslash character, and the continuation follows on the next keyword which must have the name CONTINUE without an equal sign in column 9 of the card. If the next card is not a continuation, then the returned value string will be null. */ { int tstatus; char card[FLEN_CARD], strval[FLEN_VALUE]; if (*status > 0) return(*status); tstatus = 0; value[0] = '\0'; if (ffgnky(fptr, card, &tstatus) > 0) /* read next keyword */ return(*status); /* hit end of header */ if (strncmp(card, "CONTINUE ", 10) == 0) /* a continuation card? */ { strncpy(card, "D2345678= ", 10); /* overwrite a dummy keyword name */ ffpsvc(card, strval, comm, &tstatus); /* get the string value & comment */ ffc2s(strval, value, &tstatus); /* remove the surrounding quotes */ if (tstatus) /* return null if error status was returned */ value[0] = '\0'; } else ffmrky(fptr, -1, status); /* reset the keyword pointer */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkyl( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - name of keyword to read */ int *value, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the value and comment. The returned value = 1 if the keyword is true, else = 0 if false. The comment may be up to 69 characters long. */ { char valstring[FLEN_VALUE]; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ ffc2l(valstring, value, status); /* convert string to value */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkyj( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - name of keyword to read */ long *value, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the value and comment. The value will be implicitly converted to a (long) integer if it not already of this datatype. The comment may be up to 69 characters long. */ { char valstring[FLEN_VALUE]; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ ffc2i(valstring, value, status); /* convert string to value */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkyjj( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - name of keyword to read */ LONGLONG *value, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the value and comment. The value will be implicitly converted to a (LONGLONG) integer if it not already of this datatype. The comment may be up to 69 characters long. */ { char valstring[FLEN_VALUE]; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ ffc2j(valstring, value, status); /* convert string to value */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkyujj( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - name of keyword to read */ ULONGLONG *value, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the value and comment. The value will be implicitly converted to a (ULONGLONG) integer if it not already of this datatype. The comment may be up to 69 characters long. */ { char valstring[FLEN_VALUE]; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ ffc2uj(valstring, value, status); /* convert string to value */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkye( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - name of keyword to read */ float *value, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the value and comment. The value will be implicitly converted to a float if it not already of this datatype. The comment may be up to 69 characters long. */ { char valstring[FLEN_VALUE]; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ ffc2r(valstring, value, status); /* convert string to value */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkyd( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - name of keyword to read */ double *value, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the value and comment. The value will be implicitly converted to a double if it not already of this datatype. The comment may be up to 69 characters long. */ { char valstring[FLEN_VALUE]; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ ffc2d(valstring, value, status); /* convert string to value */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkyc( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - name of keyword to read */ float *value, /* O - keyword value (real,imag) */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the value and comment. The keyword must have a complex value. No implicit data conversion will be performed. */ { char valstring[FLEN_VALUE], message[FLEN_ERRMSG]; int len; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ if (valstring[0] != '(' ) /* test that this is a complex keyword */ { snprintf(message, FLEN_ERRMSG, "keyword %s does not have a complex value (ffgkyc):", keyname); ffpmsg(message); ffpmsg(valstring); return(*status = BAD_C2F); } valstring[0] = ' '; /* delete the opening parenthesis */ len = strcspn(valstring, ")" ); valstring[len] = '\0'; /* delete the closing parenthesis */ len = strcspn(valstring, ","); valstring[len] = '\0'; ffc2r(valstring, &value[0], status); /* convert the real part */ ffc2r(&valstring[len + 1], &value[1], status); /* convert imag. part */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkym( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - name of keyword to read */ double *value, /* O - keyword value (real,imag) */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the value and comment. The keyword must have a complex value. No implicit data conversion will be performed. */ { char valstring[FLEN_VALUE], message[FLEN_ERRMSG]; int len; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ if (valstring[0] != '(' ) /* test that this is a complex keyword */ { snprintf(message, FLEN_ERRMSG, "keyword %s does not have a complex value (ffgkym):", keyname); ffpmsg(message); ffpmsg(valstring); return(*status = BAD_C2D); } valstring[0] = ' '; /* delete the opening parenthesis */ len = strcspn(valstring, ")" ); valstring[len] = '\0'; /* delete the closing parenthesis */ len = strcspn(valstring, ","); valstring[len] = '\0'; ffc2d(valstring, &value[0], status); /* convert the real part */ ffc2d(&valstring[len + 1], &value[1], status); /* convert the imag. part */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkyt( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - name of keyword to read */ long *ivalue, /* O - integer part of keyword value */ double *fraction, /* O - fractional part of keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the value and comment. The integer and fractional parts of the value are returned in separate variables, to allow more numerical precision to be passed. This effectively passes a 'triple' precision value, with a 4-byte integer and an 8-byte fraction. The comment may be up to 69 characters long. */ { char valstring[FLEN_VALUE]; char *loc; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ /* read the entire value string as a double, to get the integer part */ ffc2d(valstring, fraction, status); *ivalue = (long) *fraction; *fraction = *fraction - *ivalue; /* see if we need to read the fractional part again with more precision */ /* look for decimal point, without an exponential E or D character */ loc = strchr(valstring, '.'); if (loc) { if (!strchr(valstring, 'E') && !strchr(valstring, 'D')) ffc2d(loc, fraction, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgkyn( fitsfile *fptr, /* I - FITS file pointer */ int nkey, /* I - number of the keyword to read */ char *keyname, /* O - name of the keyword */ char *value, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the nkey-th keyword returning the keyword name, value and comment. The value is just the literal string of characters in the value field of the keyword. In the case of a string valued keyword, the returned value includes the leading and closing quote characters. The value may be up to 70 characters long, and the comment may be up to 72 characters long. If the keyword has no value (no equal sign in column 9) then a null value is returned. If comm = NULL, then do not return the comment string. */ { char card[FLEN_CARD], sbuff[FLEN_CARD]; int namelen; keyname[0] = '\0'; value[0] = '\0'; if (comm) comm[0] = '\0'; if (*status > 0) return(*status); if (ffgrec(fptr, nkey, card, status) > 0 ) /* get the 80-byte card */ return(*status); ffgknm(card, keyname, &namelen, status); /* get the keyword name */ if (ffpsvc(card, value, comm, status) > 0) /* parse value and comment */ return(*status); if (fftrec(keyname, status) > 0) /* test keyword name; catches no END */ { snprintf(sbuff, FLEN_CARD, "Name of keyword no. %d contains illegal character(s): %s", nkey, keyname); ffpmsg(sbuff); if (nkey % 36 == 0) /* test if at beginning of 36-card FITS record */ ffpmsg(" (This may indicate a missing END keyword)."); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgkns( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - root name of keywords to read */ int nstart, /* I - starting index number */ int nmax, /* I - maximum number of keywords to return */ char *value[], /* O - array of pointers to keyword values */ int *nfound, /* O - number of values that were returned */ int *status) /* IO - error status */ /* Read (get) an indexed array of keywords with index numbers between NSTART and (NSTART + NMAX -1) inclusive. This routine does NOT support the HEASARC long string convention. */ { int nend, lenroot, ii, nkeys, mkeys, tstatus, undefinedval; long ival; char keyroot[FLEN_KEYWORD], keyindex[8], card[FLEN_CARD]; char svalue[FLEN_VALUE], comm[FLEN_COMMENT], *equalssign; if (*status > 0) return(*status); *nfound = 0; nend = nstart + nmax - 1; keyroot[0] = '\0'; strncat(keyroot, keyname, FLEN_KEYWORD - 1); lenroot = strlen(keyroot); if (lenroot == 0) /* root must be at least 1 char long */ return(*status); for (ii=0; ii < lenroot; ii++) /* make sure upper case */ keyroot[ii] = toupper(keyroot[ii]); ffghps(fptr, &nkeys, &mkeys, status); /* get the number of keywords */ undefinedval = FALSE; for (ii=3; ii <= nkeys; ii++) { if (ffgrec(fptr, ii, card, status) > 0) /* get next keyword */ return(*status); if (strncmp(keyroot, card, lenroot) == 0) /* see if keyword matches */ { keyindex[0] = '\0'; equalssign = strchr(card, '='); if (equalssign == 0) continue; /* keyword has no value */ if (equalssign - card - lenroot > 7) { return (*status=BAD_KEYCHAR); } strncat(keyindex, &card[lenroot], equalssign - card - lenroot); /* copy suffix */ tstatus = 0; if (ffc2ii(keyindex, &ival, &tstatus) <= 0) /* test suffix */ { if (ival <= nend && ival >= nstart) { ffpsvc(card, svalue, comm, status); /* parse the value */ ffc2s(svalue, value[ival-nstart], status); /* convert */ if (ival - nstart + 1 > *nfound) *nfound = ival - nstart + 1; /* max found */ if (*status == VALUE_UNDEFINED) { undefinedval = TRUE; *status = 0; /* reset status to read remaining values */ } } } } } if (undefinedval && (*status <= 0) ) *status = VALUE_UNDEFINED; /* report at least 1 value undefined */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgknl( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - root name of keywords to read */ int nstart, /* I - starting index number */ int nmax, /* I - maximum number of keywords to return */ int *value, /* O - array of keyword values */ int *nfound, /* O - number of values that were returned */ int *status) /* IO - error status */ /* Read (get) an indexed array of keywords with index numbers between NSTART and (NSTART + NMAX -1) inclusive. The returned value = 1 if the keyword is true, else = 0 if false. */ { int nend, lenroot, ii, nkeys, mkeys, tstatus, undefinedval; long ival; char keyroot[FLEN_KEYWORD], keyindex[8], card[FLEN_CARD]; char svalue[FLEN_VALUE], comm[FLEN_COMMENT], *equalssign; if (*status > 0) return(*status); *nfound = 0; nend = nstart + nmax - 1; keyroot[0] = '\0'; strncat(keyroot, keyname, FLEN_KEYWORD - 1); lenroot = strlen(keyroot); if (lenroot == 0) /* root must be at least 1 char long */ return(*status); for (ii=0; ii < lenroot; ii++) /* make sure upper case */ keyroot[ii] = toupper(keyroot[ii]); ffghps(fptr, &nkeys, &mkeys, status); /* get the number of keywords */ ffmaky(fptr, 3, status); /* move to 3rd keyword (skip 1st 2 keywords) */ undefinedval = FALSE; for (ii=3; ii <= nkeys; ii++) { if (ffgnky(fptr, card, status) > 0) /* get next keyword */ return(*status); if (strncmp(keyroot, card, lenroot) == 0) /* see if keyword matches */ { keyindex[0] = '\0'; equalssign = strchr(card, '='); if (equalssign == 0) continue; /* keyword has no value */ if (equalssign - card - lenroot > 7) { return (*status=BAD_KEYCHAR); } strncat(keyindex, &card[lenroot], equalssign - card - lenroot); /* copy suffix */ tstatus = 0; if (ffc2ii(keyindex, &ival, &tstatus) <= 0) /* test suffix */ { if (ival <= nend && ival >= nstart) { ffpsvc(card, svalue, comm, status); /* parse the value */ ffc2l(svalue, &value[ival-nstart], status); /* convert*/ if (ival - nstart + 1 > *nfound) *nfound = ival - nstart + 1; /* max found */ if (*status == VALUE_UNDEFINED) { undefinedval = TRUE; *status = 0; /* reset status to read remaining values */ } } } } } if (undefinedval && (*status <= 0) ) *status = VALUE_UNDEFINED; /* report at least 1 value undefined */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgknj( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - root name of keywords to read */ int nstart, /* I - starting index number */ int nmax, /* I - maximum number of keywords to return */ long *value, /* O - array of keyword values */ int *nfound, /* O - number of values that were returned */ int *status) /* IO - error status */ /* Read (get) an indexed array of keywords with index numbers between NSTART and (NSTART + NMAX -1) inclusive. */ { int nend, lenroot, ii, nkeys, mkeys, tstatus, undefinedval; long ival; char keyroot[FLEN_KEYWORD], keyindex[8], card[FLEN_CARD]; char svalue[FLEN_VALUE], comm[FLEN_COMMENT], *equalssign; if (*status > 0) return(*status); *nfound = 0; nend = nstart + nmax - 1; keyroot[0] = '\0'; strncat(keyroot, keyname, FLEN_KEYWORD - 1); lenroot = strlen(keyroot); if (lenroot == 0) /* root must be at least 1 char long */ return(*status); for (ii=0; ii < lenroot; ii++) /* make sure upper case */ keyroot[ii] = toupper(keyroot[ii]); ffghps(fptr, &nkeys, &mkeys, status); /* get the number of keywords */ ffmaky(fptr, 3, status); /* move to 3rd keyword (skip 1st 2 keywords) */ undefinedval = FALSE; for (ii=3; ii <= nkeys; ii++) { if (ffgnky(fptr, card, status) > 0) /* get next keyword */ return(*status); if (strncmp(keyroot, card, lenroot) == 0) /* see if keyword matches */ { keyindex[0] = '\0'; equalssign = strchr(card, '='); if (equalssign == 0) continue; /* keyword has no value */ if (equalssign - card - lenroot > 7) { return (*status=BAD_KEYCHAR); } strncat(keyindex, &card[lenroot], equalssign - card - lenroot); /* copy suffix */ tstatus = 0; if (ffc2ii(keyindex, &ival, &tstatus) <= 0) /* test suffix */ { if (ival <= nend && ival >= nstart) { ffpsvc(card, svalue, comm, status); /* parse the value */ ffc2i(svalue, &value[ival-nstart], status); /* convert */ if (ival - nstart + 1 > *nfound) *nfound = ival - nstart + 1; /* max found */ if (*status == VALUE_UNDEFINED) { undefinedval = TRUE; *status = 0; /* reset status to read remaining values */ } } } } } if (undefinedval && (*status <= 0) ) *status = VALUE_UNDEFINED; /* report at least 1 value undefined */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgknjj( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - root name of keywords to read */ int nstart, /* I - starting index number */ int nmax, /* I - maximum number of keywords to return */ LONGLONG *value, /* O - array of keyword values */ int *nfound, /* O - number of values that were returned */ int *status) /* IO - error status */ /* Read (get) an indexed array of keywords with index numbers between NSTART and (NSTART + NMAX -1) inclusive. */ { int nend, lenroot, ii, nkeys, mkeys, tstatus, undefinedval; long ival; char keyroot[FLEN_KEYWORD], keyindex[8], card[FLEN_CARD]; char svalue[FLEN_VALUE], comm[FLEN_COMMENT], *equalssign; if (*status > 0) return(*status); *nfound = 0; nend = nstart + nmax - 1; keyroot[0] = '\0'; strncat(keyroot, keyname, FLEN_KEYWORD - 1); lenroot = strlen(keyroot); if (lenroot == 0) /* root must be at least 1 char long */ return(*status); for (ii=0; ii < lenroot; ii++) /* make sure upper case */ keyroot[ii] = toupper(keyroot[ii]); ffghps(fptr, &nkeys, &mkeys, status); /* get the number of keywords */ ffmaky(fptr, 3, status); /* move to 3rd keyword (skip 1st 2 keywords) */ undefinedval = FALSE; for (ii=3; ii <= nkeys; ii++) { if (ffgnky(fptr, card, status) > 0) /* get next keyword */ return(*status); if (strncmp(keyroot, card, lenroot) == 0) /* see if keyword matches */ { keyindex[0] = '\0'; equalssign = strchr(card, '='); if (equalssign == 0) continue; /* keyword has no value */ if (equalssign - card - lenroot > 7) { return (*status=BAD_KEYCHAR); } strncat(keyindex, &card[lenroot], equalssign - card - lenroot); /* copy suffix */ tstatus = 0; if (ffc2ii(keyindex, &ival, &tstatus) <= 0) /* test suffix */ { if (ival <= nend && ival >= nstart) { ffpsvc(card, svalue, comm, status); /* parse the value */ ffc2j(svalue, &value[ival-nstart], status); /* convert */ if (ival - nstart + 1 > *nfound) *nfound = ival - nstart + 1; /* max found */ if (*status == VALUE_UNDEFINED) { undefinedval = TRUE; *status = 0; /* reset status to read remaining values */ } } } } } if (undefinedval && (*status <= 0) ) *status = VALUE_UNDEFINED; /* report at least 1 value undefined */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkne( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - root name of keywords to read */ int nstart, /* I - starting index number */ int nmax, /* I - maximum number of keywords to return */ float *value, /* O - array of keyword values */ int *nfound, /* O - number of values that were returned */ int *status) /* IO - error status */ /* Read (get) an indexed array of keywords with index numbers between NSTART and (NSTART + NMAX -1) inclusive. */ { int nend, lenroot, ii, nkeys, mkeys, tstatus, undefinedval; long ival; char keyroot[FLEN_KEYWORD], keyindex[8], card[FLEN_CARD]; char svalue[FLEN_VALUE], comm[FLEN_COMMENT], *equalssign; if (*status > 0) return(*status); *nfound = 0; nend = nstart + nmax - 1; keyroot[0] = '\0'; strncat(keyroot, keyname, FLEN_KEYWORD - 1); lenroot = strlen(keyroot); if (lenroot == 0) /* root must be at least 1 char long */ return(*status); for (ii=0; ii < lenroot; ii++) /* make sure upper case */ keyroot[ii] = toupper(keyroot[ii]); ffghps(fptr, &nkeys, &mkeys, status); /* get the number of keywords */ ffmaky(fptr, 3, status); /* move to 3rd keyword (skip 1st 2 keywords) */ undefinedval = FALSE; for (ii=3; ii <= nkeys; ii++) { if (ffgnky(fptr, card, status) > 0) /* get next keyword */ return(*status); if (strncmp(keyroot, card, lenroot) == 0) /* see if keyword matches */ { keyindex[0] = '\0'; equalssign = strchr(card, '='); if (equalssign == 0) continue; /* keyword has no value */ if (equalssign - card - lenroot > 7) { return (*status=BAD_KEYCHAR); } strncat(keyindex, &card[lenroot], equalssign - card - lenroot); /* copy suffix */ tstatus = 0; if (ffc2ii(keyindex, &ival, &tstatus) <= 0) /* test suffix */ { if (ival <= nend && ival >= nstart) { ffpsvc(card, svalue, comm, status); /* parse the value */ ffc2r(svalue, &value[ival-nstart], status); /* convert */ if (ival - nstart + 1 > *nfound) *nfound = ival - nstart + 1; /* max found */ if (*status == VALUE_UNDEFINED) { undefinedval = TRUE; *status = 0; /* reset status to read remaining values */ } } } } } if (undefinedval && (*status <= 0) ) *status = VALUE_UNDEFINED; /* report at least 1 value undefined */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgknd( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - root name of keywords to read */ int nstart, /* I - starting index number */ int nmax, /* I - maximum number of keywords to return */ double *value, /* O - array of keyword values */ int *nfound, /* O - number of values that were returned */ int *status) /* IO - error status */ /* Read (get) an indexed array of keywords with index numbers between NSTART and (NSTART + NMAX -1) inclusive. */ { int nend, lenroot, ii, nkeys, mkeys, tstatus, undefinedval; long ival; char keyroot[FLEN_KEYWORD], keyindex[8], card[FLEN_CARD]; char svalue[FLEN_VALUE], comm[FLEN_COMMENT], *equalssign; if (*status > 0) return(*status); *nfound = 0; nend = nstart + nmax - 1; keyroot[0] = '\0'; strncat(keyroot, keyname, FLEN_KEYWORD - 1); lenroot = strlen(keyroot); if (lenroot == 0) /* root must be at least 1 char long */ return(*status); for (ii=0; ii < lenroot; ii++) /* make sure upper case */ keyroot[ii] = toupper(keyroot[ii]); ffghps(fptr, &nkeys, &mkeys, status); /* get the number of keywords */ ffmaky(fptr, 3, status); /* move to 3rd keyword (skip 1st 2 keywords) */ undefinedval = FALSE; for (ii=3; ii <= nkeys; ii++) { if (ffgnky(fptr, card, status) > 0) /* get next keyword */ return(*status); if (strncmp(keyroot, card, lenroot) == 0) /* see if keyword matches */ { keyindex[0] = '\0'; equalssign = strchr(card, '='); if (equalssign == 0) continue; /* keyword has no value */ if (equalssign - card - lenroot > 7) { return (*status=BAD_KEYCHAR); } strncat(keyindex, &card[lenroot], equalssign - card - lenroot); /* copy suffix */ tstatus = 0; if (ffc2ii(keyindex, &ival, &tstatus) <= 0) /* test suffix */ { if (ival <= nend && ival >= nstart) /* is index within range? */ { ffpsvc(card, svalue, comm, status); /* parse the value */ ffc2d(svalue, &value[ival-nstart], status); /* convert */ if (ival - nstart + 1 > *nfound) *nfound = ival - nstart + 1; /* max found */ if (*status == VALUE_UNDEFINED) { undefinedval = TRUE; *status = 0; /* reset status to read remaining values */ } } } } } if (undefinedval && (*status <= 0) ) *status = VALUE_UNDEFINED; /* report at least 1 value undefined */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgtdm(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read */ int maxdim, /* I - maximum no. of dimensions to read; */ int *naxis, /* O - number of axes in the data array */ long naxes[], /* O - length of each data axis */ int *status) /* IO - error status */ /* read and parse the TDIMnnn keyword to get the dimensionality of a column */ { int tstatus = 0; char keyname[FLEN_KEYWORD], tdimstr[FLEN_VALUE]; if (*status > 0) return(*status); ffkeyn("TDIM", colnum, keyname, status); /* construct keyword name */ ffgkys(fptr, keyname, tdimstr, NULL, &tstatus); /* try reading keyword */ ffdtdm(fptr, tdimstr, colnum, maxdim,naxis, naxes, status); /* decode it */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgtdmll(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read */ int maxdim, /* I - maximum no. of dimensions to read; */ int *naxis, /* O - number of axes in the data array */ LONGLONG naxes[], /* O - length of each data axis */ int *status) /* IO - error status */ /* read and parse the TDIMnnn keyword to get the dimensionality of a column */ { int tstatus = 0; char keyname[FLEN_KEYWORD], tdimstr[FLEN_VALUE]; if (*status > 0) return(*status); ffkeyn("TDIM", colnum, keyname, status); /* construct keyword name */ ffgkys(fptr, keyname, tdimstr, NULL, &tstatus); /* try reading keyword */ ffdtdmll(fptr, tdimstr, colnum, maxdim,naxis, naxes, status); /* decode it */ return(*status); } /*--------------------------------------------------------------------------*/ int ffdtdm(fitsfile *fptr, /* I - FITS file pointer */ char *tdimstr, /* I - TDIMn keyword value string. e.g. (10,10) */ int colnum, /* I - number of the column */ int maxdim, /* I - maximum no. of dimensions to read; */ int *naxis, /* O - number of axes in the data array */ long naxes[], /* O - length of each data axis */ int *status) /* IO - error status */ /* decode the TDIMnnn keyword to get the dimensionality of a column. Check that the value is legal and consistent with the TFORM value. If colnum = 0, then the validity checking is disabled. */ { long dimsize, totalpix = 1; char *loc, *lastloc, message[FLEN_ERRMSG]; tcolumn *colptr = 0; if (*status > 0) return(*status); if (colnum != 0) { if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (colnum < 1 || colnum > (fptr->Fptr)->tfield) return(*status = BAD_COL_NUM); colptr = (fptr->Fptr)->tableptr; /* set pointer to the first column */ colptr += (colnum - 1); /* increment to the correct column */ if (!tdimstr[0]) /* TDIMn keyword doesn't exist? */ { *naxis = 1; /* default = 1 dimensional */ if (maxdim > 0) naxes[0] = (long) colptr->trepeat; /* default length = repeat */ return(*status); } } *naxis = 0; loc = strchr(tdimstr, '(' ); /* find the opening quote */ if (!loc) { snprintf(message, FLEN_ERRMSG, "Illegal dimensions format: %s", tdimstr); return(*status = BAD_TDIM); } while (loc) { loc++; dimsize = strtol(loc, &loc, 10); /* read size of next dimension */ if (*naxis < maxdim) naxes[*naxis] = dimsize; if (dimsize < 0) { ffpmsg("one or more dimension are less than 0 (ffdtdm)"); ffpmsg(tdimstr); return(*status = BAD_TDIM); } totalpix *= dimsize; (*naxis)++; lastloc = loc; loc = strchr(loc, ','); /* look for comma before next dimension */ } loc = strchr(lastloc, ')' ); /* check for the closing quote */ if (!loc) { snprintf(message, FLEN_ERRMSG, "Illegal dimensions format: %s", tdimstr); return(*status = BAD_TDIM); } if (colnum != 0) { if ((colptr->tdatatype > 0) && ((long) colptr->trepeat != totalpix)) { snprintf(message, FLEN_ERRMSG, "column vector length, %ld, does not equal TDIMn array size, %ld", (long) colptr->trepeat, totalpix); ffpmsg(message); ffpmsg(tdimstr); return(*status = BAD_TDIM); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffdtdmll(fitsfile *fptr, /* I - FITS file pointer */ char *tdimstr, /* I - TDIMn keyword value string. e.g. (10,10) */ int colnum, /* I - number of the column */ int maxdim, /* I - maximum no. of dimensions to read; */ int *naxis, /* O - number of axes in the data array */ LONGLONG naxes[], /* O - length of each data axis */ int *status) /* IO - error status */ /* decode the TDIMnnn keyword to get the dimensionality of a column. Check that the value is legal and consistent with the TFORM value. */ { LONGLONG dimsize; LONGLONG totalpix = 1; char *loc, *lastloc, message[FLEN_ERRMSG]; tcolumn *colptr; double doublesize; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (colnum < 1 || colnum > (fptr->Fptr)->tfield) return(*status = BAD_COL_NUM); colptr = (fptr->Fptr)->tableptr; /* set pointer to the first column */ colptr += (colnum - 1); /* increment to the correct column */ if (!tdimstr[0]) /* TDIMn keyword doesn't exist? */ { *naxis = 1; /* default = 1 dimensional */ if (maxdim > 0) naxes[0] = colptr->trepeat; /* default length = repeat */ } else { *naxis = 0; loc = strchr(tdimstr, '(' ); /* find the opening quote */ if (!loc) { snprintf(message, FLEN_ERRMSG, "Illegal TDIM keyword value: %s", tdimstr); return(*status = BAD_TDIM); } while (loc) { loc++; /* Read value as a double because the string to 64-bit int function is */ /* platform dependent (strtoll, strtol, _atoI64). This still gives */ /* about 48 bits of precision, which is plenty for this purpose. */ doublesize = strtod(loc, &loc); dimsize = (LONGLONG) (doublesize + 0.1); if (*naxis < maxdim) naxes[*naxis] = dimsize; if (dimsize < 0) { ffpmsg("one or more TDIM values are less than 0 (ffdtdm)"); ffpmsg(tdimstr); return(*status = BAD_TDIM); } totalpix *= dimsize; (*naxis)++; lastloc = loc; loc = strchr(loc, ','); /* look for comma before next dimension */ } loc = strchr(lastloc, ')' ); /* check for the closing quote */ if (!loc) { snprintf(message, FLEN_ERRMSG, "Illegal TDIM keyword value: %s", tdimstr); return(*status = BAD_TDIM); } if ((colptr->tdatatype > 0) && (colptr->trepeat != totalpix)) { snprintf(message, FLEN_ERRMSG, "column vector length, %.0f, does not equal TDIMn array size, %.0f", (double) (colptr->trepeat), (double) totalpix); ffpmsg(message); ffpmsg(tdimstr); return(*status = BAD_TDIM); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffghpr(fitsfile *fptr, /* I - FITS file pointer */ int maxdim, /* I - maximum no. of dimensions to read; */ int *simple, /* O - does file conform to FITS standard? 1/0 */ int *bitpix, /* O - number of bits per data value pixel */ int *naxis, /* O - number of axes in the data array */ long naxes[], /* O - length of each data axis */ long *pcount, /* O - number of group parameters (usually 0) */ long *gcount, /* O - number of random groups (usually 1 or 0) */ int *extend, /* O - may FITS file haave extensions? */ int *status) /* IO - error status */ /* Get keywords from the Header of the PRimary array: Check that the keywords conform to the FITS standard and return the parameters which determine the size and structure of the primary array or IMAGE extension. */ { int idummy, ii; LONGLONG lldummy; double ddummy; LONGLONG tnaxes[99]; ffgphd(fptr, maxdim, simple, bitpix, naxis, tnaxes, pcount, gcount, extend, &ddummy, &ddummy, &lldummy, &idummy, status); if (naxis && naxes) { for (ii = 0; (ii < *naxis) && (ii < maxdim); ii++) naxes[ii] = (long) tnaxes[ii]; } else if (naxes) { for (ii = 0; ii < maxdim; ii++) naxes[ii] = (long) tnaxes[ii]; } return(*status); } /*--------------------------------------------------------------------------*/ int ffghprll(fitsfile *fptr, /* I - FITS file pointer */ int maxdim, /* I - maximum no. of dimensions to read; */ int *simple, /* O - does file conform to FITS standard? 1/0 */ int *bitpix, /* O - number of bits per data value pixel */ int *naxis, /* O - number of axes in the data array */ LONGLONG naxes[], /* O - length of each data axis */ long *pcount, /* O - number of group parameters (usually 0) */ long *gcount, /* O - number of random groups (usually 1 or 0) */ int *extend, /* O - may FITS file haave extensions? */ int *status) /* IO - error status */ /* Get keywords from the Header of the PRimary array: Check that the keywords conform to the FITS standard and return the parameters which determine the size and structure of the primary array or IMAGE extension. */ { int idummy; LONGLONG lldummy; double ddummy; ffgphd(fptr, maxdim, simple, bitpix, naxis, naxes, pcount, gcount, extend, &ddummy, &ddummy, &lldummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffghtb(fitsfile *fptr, /* I - FITS file pointer */ int maxfield, /* I - maximum no. of columns to read; */ long *naxis1, /* O - length of table row in bytes */ long *naxis2, /* O - number of rows in the table */ int *tfields, /* O - number of columns in the table */ char **ttype, /* O - name of each column */ long *tbcol, /* O - byte offset in row to each column */ char **tform, /* O - value of TFORMn keyword for each column */ char **tunit, /* O - value of TUNITn keyword for each column */ char *extnm, /* O - value of EXTNAME keyword, if any */ int *status) /* IO - error status */ /* Get keywords from the Header of the ASCII TaBle: Check that the keywords conform to the FITS standard and return the parameters which describe the table. */ { int ii, maxf, nfound, tstatus; long fields; char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT]; char xtension[FLEN_VALUE], message[FLEN_ERRMSG]; LONGLONG llnaxis1, llnaxis2, pcount; if (*status > 0) return(*status); /* read the first keyword of the extension */ ffgkyn(fptr, 1, name, value, comm, status); if (!strcmp(name, "XTENSION")) { if (ffc2s(value, xtension, status) > 0) /* get the value string */ { ffpmsg("Bad value string for XTENSION keyword:"); ffpmsg(value); return(*status); } /* allow the quoted string value to begin in any column and */ /* allow any number of trailing blanks before the closing quote */ if ( (value[0] != '\'') || /* first char must be a quote */ ( strcmp(xtension, "TABLE") ) ) { snprintf(message, FLEN_ERRMSG, "This is not a TABLE extension: %s", value); ffpmsg(message); return(*status = NOT_ATABLE); } } else /* error: 1st keyword of extension != XTENSION */ { snprintf(message, FLEN_ERRMSG, "First keyword of the extension is not XTENSION: %s", name); ffpmsg(message); return(*status = NO_XTENSION); } if (ffgttb(fptr, &llnaxis1, &llnaxis2, &pcount, &fields, status) > 0) return(*status); if (naxis1) *naxis1 = (long) llnaxis1; if (naxis2) *naxis2 = (long) llnaxis2; if (pcount != 0) { snprintf(message, FLEN_ERRMSG, "PCOUNT = %.0f is illegal in ASCII table; must = 0", (double) pcount); ffpmsg(message); return(*status = BAD_PCOUNT); } if (tfields) *tfields = fields; if (maxfield < 0) maxf = fields; else maxf = minvalue(maxfield, fields); if (maxf > 0) { for (ii = 0; ii < maxf; ii++) { /* initialize optional keyword values */ if (ttype) *ttype[ii] = '\0'; if (tunit) *tunit[ii] = '\0'; } if (ttype) ffgkns(fptr, "TTYPE", 1, maxf, ttype, &nfound, status); if (tunit) ffgkns(fptr, "TUNIT", 1, maxf, tunit, &nfound, status); if (*status > 0) return(*status); if (tbcol) { ffgknj(fptr, "TBCOL", 1, maxf, tbcol, &nfound, status); if (*status > 0 || nfound != maxf) { ffpmsg( "Required TBCOL keyword(s) not found in ASCII table header (ffghtb)."); return(*status = NO_TBCOL); } } if (tform) { ffgkns(fptr, "TFORM", 1, maxf, tform, &nfound, status); if (*status > 0 || nfound != maxf) { ffpmsg( "Required TFORM keyword(s) not found in ASCII table header (ffghtb)."); return(*status = NO_TFORM); } } } if (extnm) { extnm[0] = '\0'; tstatus = *status; ffgkys(fptr, "EXTNAME", extnm, comm, status); if (*status == KEY_NO_EXIST) *status = tstatus; /* keyword not required, so ignore error */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffghtbll(fitsfile *fptr, /* I - FITS file pointer */ int maxfield, /* I - maximum no. of columns to read; */ LONGLONG *naxis1, /* O - length of table row in bytes */ LONGLONG *naxis2, /* O - number of rows in the table */ int *tfields, /* O - number of columns in the table */ char **ttype, /* O - name of each column */ LONGLONG *tbcol, /* O - byte offset in row to each column */ char **tform, /* O - value of TFORMn keyword for each column */ char **tunit, /* O - value of TUNITn keyword for each column */ char *extnm, /* O - value of EXTNAME keyword, if any */ int *status) /* IO - error status */ /* Get keywords from the Header of the ASCII TaBle: Check that the keywords conform to the FITS standard and return the parameters which describe the table. */ { int ii, maxf, nfound, tstatus; long fields; char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT]; char xtension[FLEN_VALUE], message[FLEN_ERRMSG]; LONGLONG llnaxis1, llnaxis2, pcount; if (*status > 0) return(*status); /* read the first keyword of the extension */ ffgkyn(fptr, 1, name, value, comm, status); if (!strcmp(name, "XTENSION")) { if (ffc2s(value, xtension, status) > 0) /* get the value string */ { ffpmsg("Bad value string for XTENSION keyword:"); ffpmsg(value); return(*status); } /* allow the quoted string value to begin in any column and */ /* allow any number of trailing blanks before the closing quote */ if ( (value[0] != '\'') || /* first char must be a quote */ ( strcmp(xtension, "TABLE") ) ) { snprintf(message, FLEN_ERRMSG, "This is not a TABLE extension: %s", value); ffpmsg(message); return(*status = NOT_ATABLE); } } else /* error: 1st keyword of extension != XTENSION */ { snprintf(message, FLEN_ERRMSG, "First keyword of the extension is not XTENSION: %s", name); ffpmsg(message); return(*status = NO_XTENSION); } if (ffgttb(fptr, &llnaxis1, &llnaxis2, &pcount, &fields, status) > 0) return(*status); if (naxis1) *naxis1 = llnaxis1; if (naxis2) *naxis2 = llnaxis2; if (pcount != 0) { snprintf(message, FLEN_ERRMSG, "PCOUNT = %.0f is illegal in ASCII table; must = 0", (double) pcount); ffpmsg(message); return(*status = BAD_PCOUNT); } if (tfields) *tfields = fields; if (maxfield < 0) maxf = fields; else maxf = minvalue(maxfield, fields); if (maxf > 0) { for (ii = 0; ii < maxf; ii++) { /* initialize optional keyword values */ if (ttype) *ttype[ii] = '\0'; if (tunit) *tunit[ii] = '\0'; } if (ttype) ffgkns(fptr, "TTYPE", 1, maxf, ttype, &nfound, status); if (tunit) ffgkns(fptr, "TUNIT", 1, maxf, tunit, &nfound, status); if (*status > 0) return(*status); if (tbcol) { ffgknjj(fptr, "TBCOL", 1, maxf, tbcol, &nfound, status); if (*status > 0 || nfound != maxf) { ffpmsg( "Required TBCOL keyword(s) not found in ASCII table header (ffghtbll)."); return(*status = NO_TBCOL); } } if (tform) { ffgkns(fptr, "TFORM", 1, maxf, tform, &nfound, status); if (*status > 0 || nfound != maxf) { ffpmsg( "Required TFORM keyword(s) not found in ASCII table header (ffghtbll)."); return(*status = NO_TFORM); } } } if (extnm) { extnm[0] = '\0'; tstatus = *status; ffgkys(fptr, "EXTNAME", extnm, comm, status); if (*status == KEY_NO_EXIST) *status = tstatus; /* keyword not required, so ignore error */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffghbn(fitsfile *fptr, /* I - FITS file pointer */ int maxfield, /* I - maximum no. of columns to read; */ long *naxis2, /* O - number of rows in the table */ int *tfields, /* O - number of columns in the table */ char **ttype, /* O - name of each column */ char **tform, /* O - TFORMn value for each column */ char **tunit, /* O - TUNITn value for each column */ char *extnm, /* O - value of EXTNAME keyword, if any */ long *pcount, /* O - value of PCOUNT keyword */ int *status) /* IO - error status */ /* Get keywords from the Header of the BiNary table: Check that the keywords conform to the FITS standard and return the parameters which describe the table. */ { int ii, maxf, nfound, tstatus; long fields; char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT]; char xtension[FLEN_VALUE], message[FLEN_ERRMSG]; LONGLONG naxis1ll, naxis2ll, pcountll; if (*status > 0) return(*status); /* read the first keyword of the extension */ ffgkyn(fptr, 1, name, value, comm, status); if (!strcmp(name, "XTENSION")) { if (ffc2s(value, xtension, status) > 0) /* get the value string */ { ffpmsg("Bad value string for XTENSION keyword:"); ffpmsg(value); return(*status); } /* allow the quoted string value to begin in any column and */ /* allow any number of trailing blanks before the closing quote */ if ( (value[0] != '\'') || /* first char must be a quote */ ( strcmp(xtension, "BINTABLE") && strcmp(xtension, "A3DTABLE") && strcmp(xtension, "3DTABLE") ) ) { snprintf(message, FLEN_ERRMSG, "This is not a BINTABLE extension: %s", value); ffpmsg(message); return(*status = NOT_BTABLE); } } else /* error: 1st keyword of extension != XTENSION */ { snprintf(message, FLEN_ERRMSG, "First keyword of the extension is not XTENSION: %s", name); ffpmsg(message); return(*status = NO_XTENSION); } if (ffgttb(fptr, &naxis1ll, &naxis2ll, &pcountll, &fields, status) > 0) return(*status); if (naxis2) *naxis2 = (long) naxis2ll; if (pcount) *pcount = (long) pcountll; if (tfields) *tfields = fields; if (maxfield < 0) maxf = fields; else maxf = minvalue(maxfield, fields); if (maxf > 0) { for (ii = 0; ii < maxf; ii++) { /* initialize optional keyword values */ if (ttype) *ttype[ii] = '\0'; if (tunit) *tunit[ii] = '\0'; } if (ttype) ffgkns(fptr, "TTYPE", 1, maxf, ttype, &nfound, status); if (tunit) ffgkns(fptr, "TUNIT", 1, maxf, tunit, &nfound, status); if (*status > 0) return(*status); if (tform) { ffgkns(fptr, "TFORM", 1, maxf, tform, &nfound, status); if (*status > 0 || nfound != maxf) { ffpmsg( "Required TFORM keyword(s) not found in binary table header (ffghbn)."); return(*status = NO_TFORM); } } } if (extnm) { extnm[0] = '\0'; tstatus = *status; ffgkys(fptr, "EXTNAME", extnm, comm, status); if (*status == KEY_NO_EXIST) *status = tstatus; /* keyword not required, so ignore error */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffghbnll(fitsfile *fptr, /* I - FITS file pointer */ int maxfield, /* I - maximum no. of columns to read; */ LONGLONG *naxis2, /* O - number of rows in the table */ int *tfields, /* O - number of columns in the table */ char **ttype, /* O - name of each column */ char **tform, /* O - TFORMn value for each column */ char **tunit, /* O - TUNITn value for each column */ char *extnm, /* O - value of EXTNAME keyword, if any */ LONGLONG *pcount, /* O - value of PCOUNT keyword */ int *status) /* IO - error status */ /* Get keywords from the Header of the BiNary table: Check that the keywords conform to the FITS standard and return the parameters which describe the table. */ { int ii, maxf, nfound, tstatus; long fields; char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT]; char xtension[FLEN_VALUE], message[FLEN_ERRMSG]; LONGLONG naxis1ll, naxis2ll, pcountll; if (*status > 0) return(*status); /* read the first keyword of the extension */ ffgkyn(fptr, 1, name, value, comm, status); if (!strcmp(name, "XTENSION")) { if (ffc2s(value, xtension, status) > 0) /* get the value string */ { ffpmsg("Bad value string for XTENSION keyword:"); ffpmsg(value); return(*status); } /* allow the quoted string value to begin in any column and */ /* allow any number of trailing blanks before the closing quote */ if ( (value[0] != '\'') || /* first char must be a quote */ ( strcmp(xtension, "BINTABLE") && strcmp(xtension, "A3DTABLE") && strcmp(xtension, "3DTABLE") ) ) { snprintf(message, FLEN_ERRMSG, "This is not a BINTABLE extension: %s", value); ffpmsg(message); return(*status = NOT_BTABLE); } } else /* error: 1st keyword of extension != XTENSION */ { snprintf(message, FLEN_ERRMSG, "First keyword of the extension is not XTENSION: %s", name); ffpmsg(message); return(*status = NO_XTENSION); } if (ffgttb(fptr, &naxis1ll, &naxis2ll, &pcountll, &fields, status) > 0) return(*status); if (naxis2) *naxis2 = naxis2ll; if (pcount) *pcount = pcountll; if (tfields) *tfields = fields; if (maxfield < 0) maxf = fields; else maxf = minvalue(maxfield, fields); if (maxf > 0) { for (ii = 0; ii < maxf; ii++) { /* initialize optional keyword values */ if (ttype) *ttype[ii] = '\0'; if (tunit) *tunit[ii] = '\0'; } if (ttype) ffgkns(fptr, "TTYPE", 1, maxf, ttype, &nfound, status); if (tunit) ffgkns(fptr, "TUNIT", 1, maxf, tunit, &nfound, status); if (*status > 0) return(*status); if (tform) { ffgkns(fptr, "TFORM", 1, maxf, tform, &nfound, status); if (*status > 0 || nfound != maxf) { ffpmsg( "Required TFORM keyword(s) not found in binary table header (ffghbn)."); return(*status = NO_TFORM); } } } if (extnm) { extnm[0] = '\0'; tstatus = *status; ffgkys(fptr, "EXTNAME", extnm, comm, status); if (*status == KEY_NO_EXIST) *status = tstatus; /* keyword not required, so ignore error */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffgphd(fitsfile *fptr, /* I - FITS file pointer */ int maxdim, /* I - maximum no. of dimensions to read; */ int *simple, /* O - does file conform to FITS standard? 1/0 */ int *bitpix, /* O - number of bits per data value pixel */ int *naxis, /* O - number of axes in the data array */ LONGLONG naxes[], /* O - length of each data axis */ long *pcount, /* O - number of group parameters (usually 0) */ long *gcount, /* O - number of random groups (usually 1 or 0) */ int *extend, /* O - may FITS file haave extensions? */ double *bscale, /* O - array pixel linear scaling factor */ double *bzero, /* O - array pixel linear scaling zero point */ LONGLONG *blank, /* O - value used to represent undefined pixels */ int *nspace, /* O - number of blank keywords prior to END */ int *status) /* IO - error status */ { /* Get the Primary HeaDer parameters. Check that the keywords conform to the FITS standard and return the parameters which determine the size and structure of the primary array or IMAGE extension. */ int unknown, found_end, tstatus, ii, nextkey, namelen; long longbitpix, longnaxis; LONGLONG axislen; char message[FLEN_ERRMSG], keyword[FLEN_KEYWORD]; char card[FLEN_CARD]; char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT]; char xtension[FLEN_VALUE]; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (simple) *simple = 1; unknown = 0; /*--------------------------------------------------------------------*/ /* Get 1st keyword of HDU and test whether it is SIMPLE or XTENSION */ /*--------------------------------------------------------------------*/ ffgkyn(fptr, 1, name, value, comm, status); if ((fptr->Fptr)->curhdu == 0) /* Is this the beginning of the FITS file? */ { if (!strcmp(name, "SIMPLE")) { if (value[0] == 'F') { if (simple) *simple=0; /* not a simple FITS file */ } else if (value[0] != 'T') return(*status = BAD_SIMPLE); } else { snprintf(message, FLEN_ERRMSG, "First keyword of the file is not SIMPLE: %s", name); ffpmsg(message); return(*status = NO_SIMPLE); } } else /* not beginning of the file, so presumably an IMAGE extension */ { /* or it could be a compressed image in a binary table */ if (!strcmp(name, "XTENSION")) { if (ffc2s(value, xtension, status) > 0) /* get the value string */ { ffpmsg("Bad value string for XTENSION keyword:"); ffpmsg(value); return(*status); } /* allow the quoted string value to begin in any column and */ /* allow any number of trailing blanks before the closing quote */ if ( (value[0] != '\'') || /* first char must be a quote */ ( strcmp(xtension, "IMAGE") && strcmp(xtension, "IUEIMAGE") ) ) { unknown = 1; /* unknown type of extension; press on anyway */ snprintf(message, FLEN_ERRMSG, "This is not an IMAGE extension: %s", value); ffpmsg(message); } } else /* error: 1st keyword of extension != XTENSION */ { snprintf(message, FLEN_ERRMSG, "First keyword of the extension is not XTENSION: %s", name); ffpmsg(message); return(*status = NO_XTENSION); } } if (unknown && (fptr->Fptr)->compressimg) { /* this is a compressed image, so read ZBITPIX, ZNAXIS keywords */ unknown = 0; /* reset flag */ ffxmsg(3, message); /* clear previous spurious error message */ if (bitpix) { ffgidt(fptr, bitpix, status); /* get bitpix value */ if (*status > 0) { ffpmsg("Error reading BITPIX value of compressed image"); return(*status); } } if (naxis) { ffgidm(fptr, naxis, status); /* get NAXIS value */ if (*status > 0) { ffpmsg("Error reading NAXIS value of compressed image"); return(*status); } } if (naxes) { ffgiszll(fptr, maxdim, naxes, status); /* get NAXISn value */ if (*status > 0) { ffpmsg("Error reading NAXISn values of compressed image"); return(*status); } } nextkey = 9; /* skip required table keywords in the following search */ } else { /*----------------------------------------------------------------*/ /* Get 2nd keyword; test whether it is BITPIX with legal value */ /*----------------------------------------------------------------*/ ffgkyn(fptr, 2, name, value, comm, status); /* BITPIX = 2nd keyword */ if (strcmp(name, "BITPIX")) { snprintf(message, FLEN_ERRMSG, "Second keyword of the extension is not BITPIX: %s", name); ffpmsg(message); return(*status = NO_BITPIX); } if (ffc2ii(value, &longbitpix, status) > 0) { snprintf(message, FLEN_ERRMSG, "Value of BITPIX keyword is not an integer: %s", value); ffpmsg(message); return(*status = BAD_BITPIX); } else if (longbitpix != BYTE_IMG && longbitpix != SHORT_IMG && longbitpix != LONG_IMG && longbitpix != LONGLONG_IMG && longbitpix != FLOAT_IMG && longbitpix != DOUBLE_IMG) { snprintf(message, FLEN_ERRMSG, "Illegal value for BITPIX keyword: %s", value); ffpmsg(message); return(*status = BAD_BITPIX); } if (bitpix) *bitpix = longbitpix; /* do explicit type conversion */ /*---------------------------------------------------------------*/ /* Get 3rd keyword; test whether it is NAXIS with legal value */ /*---------------------------------------------------------------*/ ffgtkn(fptr, 3, "NAXIS", &longnaxis, status); if (*status == BAD_ORDER) return(*status = NO_NAXIS); else if (*status == NOT_POS_INT || longnaxis > 999) { snprintf(message,FLEN_ERRMSG,"NAXIS = %ld is illegal", longnaxis); ffpmsg(message); return(*status = BAD_NAXIS); } else if (naxis) *naxis = longnaxis; /* do explicit type conversion */ /*---------------------------------------------------------*/ /* Get the next NAXISn keywords and test for legal values */ /*---------------------------------------------------------*/ for (ii=0, nextkey=4; ii < longnaxis; ii++, nextkey++) { ffkeyn("NAXIS", ii+1, keyword, status); ffgtknjj(fptr, 4+ii, keyword, &axislen, status); if (*status == BAD_ORDER) return(*status = NO_NAXES); else if (*status == NOT_POS_INT) return(*status = BAD_NAXES); else if (ii < maxdim) if (naxes) naxes[ii] = axislen; } } /*---------------------------------------------------------*/ /* now look for other keywords of interest: */ /* BSCALE, BZERO, BLANK, PCOUNT, GCOUNT, EXTEND, and END */ /*---------------------------------------------------------*/ /* initialize default values in case keyword is not present */ if (bscale) *bscale = 1.0; if (bzero) *bzero = 0.0; if (pcount) *pcount = 0; if (gcount) *gcount = 1; if (extend) *extend = 0; if (blank) *blank = NULL_UNDEFINED; /* no default null value for BITPIX=8,16,32 */ *nspace = 0; found_end = 0; tstatus = *status; for (; !found_end; nextkey++) { /* get next keyword */ /* don't use ffgkyn here because it trys to parse the card to read */ /* the value string, thus failing to read the file just because of */ /* minor syntax errors in optional keywords. */ if (ffgrec(fptr, nextkey, card, status) > 0 ) /* get the 80-byte card */ { if (*status == KEY_OUT_BOUNDS) { found_end = 1; /* simply hit the end of the header */ *status = tstatus; /* reset error status */ } else { ffpmsg("Failed to find the END keyword in header (ffgphd)."); } } else /* got the next keyword without error */ { ffgknm(card, name, &namelen, status); /* get the keyword name */ if (fftrec(name, status) > 0) /* test keyword name; catches no END */ { snprintf(message, FLEN_ERRMSG, "Name of keyword no. %d contains illegal character(s): %s", nextkey, name); ffpmsg(message); if (nextkey % 36 == 0) /* test if at beginning of 36-card record */ ffpmsg(" (This may indicate a missing END keyword)."); } if (!strcmp(name, "BSCALE") && bscale) { *nspace = 0; /* reset count of blank keywords */ ffpsvc(card, value, comm, status); /* parse value and comment */ if (ffc2dd(value, bscale, status) > 0) /* convert to double */ { /* reset error status and continue, but still issue warning */ *status = tstatus; *bscale = 1.0; snprintf(message, FLEN_ERRMSG, "Error reading BSCALE keyword value as a double: %s", value); ffpmsg(message); } } else if (!strcmp(name, "BZERO") && bzero) { *nspace = 0; /* reset count of blank keywords */ ffpsvc(card, value, comm, status); /* parse value and comment */ if (ffc2dd(value, bzero, status) > 0) /* convert to double */ { /* reset error status and continue, but still issue warning */ *status = tstatus; *bzero = 0.0; snprintf(message, FLEN_ERRMSG, "Error reading BZERO keyword value as a double: %s", value); ffpmsg(message); } } else if (!strcmp(name, "BLANK") && blank) { *nspace = 0; /* reset count of blank keywords */ ffpsvc(card, value, comm, status); /* parse value and comment */ if (ffc2jj(value, blank, status) > 0) /* convert to LONGLONG */ { /* reset error status and continue, but still issue warning */ *status = tstatus; *blank = NULL_UNDEFINED; snprintf(message, FLEN_ERRMSG, "Error reading BLANK keyword value as an integer: %s", value); ffpmsg(message); } } else if (!strcmp(name, "PCOUNT") && pcount) { *nspace = 0; /* reset count of blank keywords */ ffpsvc(card, value, comm, status); /* parse value and comment */ if (ffc2ii(value, pcount, status) > 0) /* convert to long */ { snprintf(message, FLEN_ERRMSG, "Error reading PCOUNT keyword value as an integer: %s", value); ffpmsg(message); } } else if (!strcmp(name, "GCOUNT") && gcount) { *nspace = 0; /* reset count of blank keywords */ ffpsvc(card, value, comm, status); /* parse value and comment */ if (ffc2ii(value, gcount, status) > 0) /* convert to long */ { snprintf(message, FLEN_ERRMSG, "Error reading GCOUNT keyword value as an integer: %s", value); ffpmsg(message); } } else if (!strcmp(name, "EXTEND") && extend) { *nspace = 0; /* reset count of blank keywords */ ffpsvc(card, value, comm, status); /* parse value and comment */ if (ffc2ll(value, extend, status) > 0) /* convert to logical */ { /* reset error status and continue, but still issue warning */ *status = tstatus; *extend = 0; snprintf(message, FLEN_ERRMSG, "Error reading EXTEND keyword value as a logical: %s", value); ffpmsg(message); } } else if (!strcmp(name, "END")) found_end = 1; else if (!card[0] ) *nspace = *nspace + 1; /* this is a blank card in the header */ else *nspace = 0; /* reset count of blank keywords immediately before the END keyword to zero */ } if (*status > 0) /* exit on error after writing error message */ { if ((fptr->Fptr)->curhdu == 0) ffpmsg( "Failed to read the required primary array header keywords."); else ffpmsg( "Failed to read the required image extension header keywords."); return(*status); } } if (unknown) *status = NOT_IMAGE; return(*status); } /*--------------------------------------------------------------------------*/ int ffgttb(fitsfile *fptr, /* I - FITS file pointer*/ LONGLONG *rowlen, /* O - length of a table row, in bytes */ LONGLONG *nrows, /* O - number of rows in the table */ LONGLONG *pcount, /* O - value of PCOUNT keyword */ long *tfields, /* O - number of fields in the table */ int *status) /* IO - error status */ { /* Get and Test TaBle; Test that this is a legal ASCII or binary table and get some keyword values. We assume that the calling routine has already tested the 1st keyword of the extension to ensure that this is really a table extension. */ if (*status > 0) return(*status); if (fftkyn(fptr, 2, "BITPIX", "8", status) == BAD_ORDER) /* 2nd keyword */ return(*status = NO_BITPIX); /* keyword not BITPIX */ else if (*status == NOT_POS_INT) return(*status = BAD_BITPIX); /* value != 8 */ if (fftkyn(fptr, 3, "NAXIS", "2", status) == BAD_ORDER) /* 3rd keyword */ return(*status = NO_NAXIS); /* keyword not NAXIS */ else if (*status == NOT_POS_INT) return(*status = BAD_NAXIS); /* value != 2 */ if (ffgtknjj(fptr, 4, "NAXIS1", rowlen, status) == BAD_ORDER) /* 4th key */ return(*status = NO_NAXES); /* keyword not NAXIS1 */ else if (*status == NOT_POS_INT) return(*status == BAD_NAXES); /* bad NAXIS1 value */ if (ffgtknjj(fptr, 5, "NAXIS2", nrows, status) == BAD_ORDER) /* 5th key */ return(*status = NO_NAXES); /* keyword not NAXIS2 */ else if (*status == NOT_POS_INT) return(*status == BAD_NAXES); /* bad NAXIS2 value */ if (ffgtknjj(fptr, 6, "PCOUNT", pcount, status) == BAD_ORDER) /* 6th key */ return(*status = NO_PCOUNT); /* keyword not PCOUNT */ else if (*status == NOT_POS_INT) return(*status = BAD_PCOUNT); /* bad PCOUNT value */ if (fftkyn(fptr, 7, "GCOUNT", "1", status) == BAD_ORDER) /* 7th keyword */ return(*status = NO_GCOUNT); /* keyword not GCOUNT */ else if (*status == NOT_POS_INT) return(*status = BAD_GCOUNT); /* value != 1 */ if (ffgtkn(fptr, 8, "TFIELDS", tfields, status) == BAD_ORDER) /* 8th key*/ return(*status = NO_TFIELDS); /* keyword not TFIELDS */ else if (*status == NOT_POS_INT || *tfields > 999) return(*status == BAD_TFIELDS); /* bad TFIELDS value */ if (*status > 0) ffpmsg( "Error reading required keywords in the table header (FTGTTB)."); return(*status); } /*--------------------------------------------------------------------------*/ int ffgtkn(fitsfile *fptr, /* I - FITS file pointer */ int numkey, /* I - number of the keyword to read */ char *name, /* I - expected name of the keyword */ long *value, /* O - integer value of the keyword */ int *status) /* IO - error status */ { /* test that keyword number NUMKEY has the expected name and get the integer value of the keyword. Return an error if the keyword name does not match the input name, or if the value of the keyword is not a positive integer. */ char keyname[FLEN_KEYWORD], valuestring[FLEN_VALUE]; char comm[FLEN_COMMENT], message[FLEN_ERRMSG]; if (*status > 0) return(*status); keyname[0] = '\0'; valuestring[0] = '\0'; if (ffgkyn(fptr, numkey, keyname, valuestring, comm, status) <= 0) { if (strcmp(keyname, name) ) *status = BAD_ORDER; /* incorrect keyword name */ else { ffc2ii(valuestring, value, status); /* convert to integer */ if (*status > 0 || *value < 0 ) *status = NOT_POS_INT; } if (*status > 0) { snprintf(message, FLEN_ERRMSG, "ffgtkn found unexpected keyword or value for keyword no. %d.", numkey); ffpmsg(message); snprintf(message, FLEN_ERRMSG, " Expected positive integer keyword %s, but instead", name); ffpmsg(message); snprintf(message, FLEN_ERRMSG, " found keyword %s with value %s", keyname, valuestring); ffpmsg(message); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgtknjj(fitsfile *fptr, /* I - FITS file pointer */ int numkey, /* I - number of the keyword to read */ char *name, /* I - expected name of the keyword */ LONGLONG *value, /* O - integer value of the keyword */ int *status) /* IO - error status */ { /* test that keyword number NUMKEY has the expected name and get the integer value of the keyword. Return an error if the keyword name does not match the input name, or if the value of the keyword is not a positive integer. */ char keyname[FLEN_KEYWORD], valuestring[FLEN_VALUE]; char comm[FLEN_COMMENT], message[FLEN_ERRMSG]; if (*status > 0) return(*status); keyname[0] = '\0'; valuestring[0] = '\0'; if (ffgkyn(fptr, numkey, keyname, valuestring, comm, status) <= 0) { if (strcmp(keyname, name) ) *status = BAD_ORDER; /* incorrect keyword name */ else { ffc2jj(valuestring, value, status); /* convert to integer */ if (*status > 0 || *value < 0 ) *status = NOT_POS_INT; } if (*status > 0) { snprintf(message, FLEN_ERRMSG, "ffgtknjj found unexpected keyword or value for keyword no. %d.", numkey); ffpmsg(message); snprintf(message, FLEN_ERRMSG, " Expected positive integer keyword %s, but instead", name); ffpmsg(message); snprintf(message, FLEN_ERRMSG, " found keyword %s with value %s", keyname, valuestring); ffpmsg(message); } } return(*status); } /*--------------------------------------------------------------------------*/ int fftkyn(fitsfile *fptr, /* I - FITS file pointer */ int numkey, /* I - number of the keyword to read */ char *name, /* I - expected name of the keyword */ char *value, /* I - expected value of the keyword */ int *status) /* IO - error status */ { /* test that keyword number NUMKEY has the expected name and the expected value string. */ char keyname[FLEN_KEYWORD], valuestring[FLEN_VALUE]; char comm[FLEN_COMMENT], message[FLEN_ERRMSG]; if (*status > 0) return(*status); keyname[0] = '\0'; valuestring[0] = '\0'; if (ffgkyn(fptr, numkey, keyname, valuestring, comm, status) <= 0) { if (strcmp(keyname, name) ) *status = BAD_ORDER; /* incorrect keyword name */ if (strcmp(value, valuestring) ) *status = NOT_POS_INT; /* incorrect keyword value */ } if (*status > 0) { snprintf(message, FLEN_ERRMSG, "fftkyn found unexpected keyword or value for keyword no. %d.", numkey); ffpmsg(message); snprintf(message, FLEN_ERRMSG, " Expected keyword %s with value %s, but", name, value); ffpmsg(message); snprintf(message, FLEN_ERRMSG, " found keyword %s with value %s", keyname, valuestring); ffpmsg(message); } return(*status); } /*--------------------------------------------------------------------------*/ int ffh2st(fitsfile *fptr, /* I - FITS file pointer */ char **header, /* O - returned header string */ int *status) /* IO - error status */ /* read header keywords into a long string of chars. This routine allocates memory for the string, so the calling routine must eventually free the memory when it is not needed any more. */ { int nkeys; long nrec; LONGLONG headstart; if (*status > 0) return(*status); /* get number of keywords in the header (doesn't include END) */ if (ffghsp(fptr, &nkeys, NULL, status) > 0) return(*status); nrec = (nkeys / 36 + 1); /* allocate memory for all the keywords (multiple of 2880 bytes) */ *header = (char *) calloc ( nrec * 2880 + 1, 1); if (!(*header)) { *status = MEMORY_ALLOCATION; ffpmsg("failed to allocate memory to hold all the header keywords"); return(*status); } ffghadll(fptr, &headstart, NULL, NULL, status); /* get header address */ ffmbyt(fptr, headstart, REPORT_EOF, status); /* move to header */ ffgbyt(fptr, nrec * 2880, *header, status); /* copy header */ *(*header + (nrec * 2880)) = '\0'; return(*status); } /*--------------------------------------------------------------------------*/ int ffhdr2str( fitsfile *fptr, /* I - FITS file pointer */ int exclude_comm, /* I - if TRUE, exclude commentary keywords */ char **exclist, /* I - list of excluded keyword names */ int nexc, /* I - number of names in exclist */ char **header, /* O - returned header string */ int *nkeys, /* O - returned number of 80-char keywords */ int *status) /* IO - error status */ /* read header keywords into a long string of chars. This routine allocates memory for the string, so the calling routine must eventually free the memory when it is not needed any more. If exclude_comm is TRUE, then all the COMMENT, HISTORY, and keywords will be excluded from the output string of keywords. Any other list of keywords to be excluded may be specified with the exclist parameter. */ { int casesn, match, exact, totkeys; long ii, jj; char keybuf[162], keyname[FLEN_KEYWORD], *headptr; *nkeys = 0; if (*status > 0) return(*status); /* get number of keywords in the header (doesn't include END) */ if (ffghsp(fptr, &totkeys, NULL, status) > 0) return(*status); /* allocate memory for all the keywords */ /* (will reallocate it later to minimize the memory size) */ *header = (char *) calloc ( (totkeys + 1) * 80 + 1, 1); if (!(*header)) { *status = MEMORY_ALLOCATION; ffpmsg("failed to allocate memory to hold all the header keywords"); return(*status); } headptr = *header; casesn = FALSE; /* read every keyword */ for (ii = 1; ii <= totkeys; ii++) { ffgrec(fptr, ii, keybuf, status); /* pad record with blanks so that it is at least 80 chars long */ strcat(keybuf, " "); keyname[0] = '\0'; strncat(keyname, keybuf, 8); /* copy the keyword name */ if (exclude_comm) { if (!FSTRCMP("COMMENT ", keyname) || !FSTRCMP("HISTORY ", keyname) || !FSTRCMP(" ", keyname) ) continue; /* skip this commentary keyword */ } /* does keyword match any names in the exclusion list? */ for (jj = 0; jj < nexc; jj++ ) { ffcmps(exclist[jj], keyname, casesn, &match, &exact); if (match) break; } if (jj == nexc) { /* not in exclusion list, add this keyword to the string */ strcpy(headptr, keybuf); headptr += 80; (*nkeys)++; } } /* add the END keyword */ strcpy(headptr, "END "); headptr += 80; (*nkeys)++; *headptr = '\0'; /* terminate the header string */ /* minimize the allocated memory */ *header = (char *) realloc(*header, (*nkeys *80) + 1); return(*status); } /*--------------------------------------------------------------------------*/ int ffcnvthdr2str( fitsfile *fptr, /* I - FITS file pointer */ int exclude_comm, /* I - if TRUE, exclude commentary keywords */ char **exclist, /* I - list of excluded keyword names */ int nexc, /* I - number of names in exclist */ char **header, /* O - returned header string */ int *nkeys, /* O - returned number of 80-char keywords */ int *status) /* IO - error status */ /* Same as ffhdr2str, except that if the input HDU is a tile compressed image (stored in a binary table) then it will first convert that header back to that of a normal uncompressed FITS image before concatenating the header keyword records. */ { fitsfile *tempfptr; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status) ) { /* this is a tile compressed image, so need to make an uncompressed */ /* copy of the image header in memory before concatenating the keywords */ if (fits_create_file(&tempfptr, "mem://", status) > 0) { return(*status); } if (fits_img_decompress_header(fptr, tempfptr, status) > 0) { fits_delete_file(tempfptr, status); return(*status); } ffhdr2str(tempfptr, exclude_comm, exclist, nexc, header, nkeys, status); fits_close_file(tempfptr, status); } else { ffhdr2str(fptr, exclude_comm, exclist, nexc, header, nkeys, status); } return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/group.c0000644000175100001710000055233600000000000017441 0ustar00vstsdocker/* This file, group.c, contains the grouping convention suport routines. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ /* */ /* The group.c module of CFITSIO was written by Donald G. Jennings of */ /* the INTEGRAL Science Data Centre (ISDC) under NASA contract task */ /* 66002J6. The above copyright laws apply. Copyright guidelines of The */ /* University of Geneva might also apply. */ /* The following routines are designed to create, read, and manipulate */ /* FITS Grouping Tables as defined in the FITS Grouping Convention paper */ /* by Jennings, Pence, Folk and Schlesinger. The development of the */ /* grouping structure was partially funded under the NASA AISRP Program. */ #include "fitsio2.h" #include "group.h" #include #include #include #if defined(WIN32) || defined(__WIN32__) #include /* defines the getcwd function on Windows PCs */ #endif #if defined(unix) || defined(__unix__) || defined(__unix) || defined(HAVE_UNISTD_H) #include /* needed for getcwd prototype on unix machines */ #endif #define HEX_ESCAPE '%' /*--------------------------------------------------------------------------- Change record: D. Jennings, 18/06/98, version 1.0 of group module delivered to B. Pence for integration into CFITSIO 2.005 D. Jennings, 17/11/98, fixed bug in ffgtcpr(). Now use fits_find_nextkey() correctly and insert auxiliary keyword records directly before the TTYPE1 keyword in the copied group table. D. Jennings, 22/01/99, ffgmop() now looks for relative file paths when the MEMBER_LOCATION information is given in a grouping table. D. Jennings, 01/02/99, ffgtop() now looks for relatve file paths when the GRPLCn keyword value is supplied in the member HDU header. D. Jennings, 01/02/99, ffgtam() now trys to construct relative file paths from the member's file to the group table's file (and visa versa) when both the member's file and group table file are of access type FILE://. D. Jennings, 05/05/99, removed the ffgtcn() function; made obsolete by fits_get_url(). D. Jennings, 05/05/99, updated entire module to handle partial URLs and absolute URLs more robustly. Host dependent directory paths are now converted to true URLs before being read from/written to grouping tables. D. Jennings, 05/05/99, added the following new functions (note, none of these are directly callable by the application) int fits_path2url() int fits_url2path() int fits_get_cwd() int fits_get_url() int fits_clean_url() int fits_relurl2url() int fits_encode_url() int fits_unencode_url() int fits_is_url_absolute() -----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ int ffgtcr(fitsfile *fptr, /* FITS file pointer */ char *grpname, /* name of the grouping table */ int grouptype, /* code specifying the type of grouping table information: GT_ID_ALL_URI 0 ==> defualt (all columns) GT_ID_REF 1 ==> ID by reference GT_ID_POS 2 ==> ID by position GT_ID_ALL 3 ==> ID by ref. and position GT_ID_REF_URI 11 ==> (1) + URI info GT_ID_POS_URI 12 ==> (2) + URI info */ int *status )/* return status code */ /* create a grouping table at the end of the current FITS file. This function makes the last HDU in the file the CHDU, then calls the fits_insert_group() function to actually create the new grouping table. */ { int hdutype; int hdunum; if(*status != 0) return(*status); *status = fits_get_num_hdus(fptr,&hdunum,status); /* If hdunum is 0 then we are at the beginning of the file and we actually haven't closed the first header yet, so don't do anything more */ if (0 != hdunum) { *status = fits_movabs_hdu(fptr,hdunum,&hdutype,status); } /* Now, the whole point of the above two fits_ calls was to get to the end of file. Let's ignore errors at this point and keep going since any error is likely to mean that we are already at the EOF, or the file is fatally corrupted. If we are at the EOF then the next fits_ call will be ok. If it's corrupted then the next call will fail, but that's not big deal at this point. */ if (0 != *status ) *status = 0; *status = fits_insert_group(fptr,grpname,grouptype,status); return(*status); } /*---------------------------------------------------------------------------*/ int ffgtis(fitsfile *fptr, /* FITS file pointer */ char *grpname, /* name of the grouping table */ int grouptype, /* code specifying the type of grouping table information: GT_ID_ALL_URI 0 ==> defualt (all columns) GT_ID_REF 1 ==> ID by reference GT_ID_POS 2 ==> ID by position GT_ID_ALL 3 ==> ID by ref. and position GT_ID_REF_URI 11 ==> (1) + URI info GT_ID_POS_URI 12 ==> (2) + URI info */ int *status) /* return status code */ /* insert a grouping table just after the current HDU of the current FITS file. This is the same as fits_create_group() only it allows the user to select the place within the FITS file to add the grouping table. */ { int tfields = 0; int hdunum = 0; int hdutype = 0; int extver; int i; long pcount = 0; char *ttype[6]; char *tform[6]; char ttypeBuff[102]; char tformBuff[54]; char extname[] = "GROUPING"; char keyword[FLEN_KEYWORD]; char keyvalue[FLEN_VALUE]; char comment[FLEN_COMMENT]; do { /* set up the ttype and tform character buffers */ for(i = 0; i < 6; ++i) { ttype[i] = ttypeBuff+(i*17); tform[i] = tformBuff+(i*9); } /* define the columns required according to the grouptype parameter */ *status = ffgtdc(grouptype,0,0,0,0,0,0,ttype,tform,&tfields,status); /* create the grouping table using the columns defined above */ *status = fits_insert_btbl(fptr,0,tfields,ttype,tform,NULL, NULL,pcount,status); if(*status != 0) continue; /* retrieve the hdu position of the new grouping table for future use */ fits_get_hdu_num(fptr,&hdunum); /* add the EXTNAME and EXTVER keywords to the HDU just after the TFIELDS keyword; for now the EXTVER value is set to 0, it will be set to the correct value later on */ fits_read_keyword(fptr,"TFIELDS",keyvalue,comment,status); fits_insert_key_str(fptr,"EXTNAME",extname, "HDU contains a Grouping Table",status); fits_insert_key_lng(fptr,"EXTVER",0,"Grouping Table vers. (this file)", status); /* if the grpname parameter value was defined (Non NULL and non zero length) then add the GRPNAME keyword and value */ if(grpname != NULL && strlen(grpname) > 0) fits_insert_key_str(fptr,"GRPNAME",grpname,"Grouping Table name", status); /* add the TNULL keywords and values for each integer column defined; integer null values are zero (0) for the MEMBER_POSITION and MEMBER_VERSION columns. */ for(i = 0; i < tfields && *status == 0; ++i) { if(fits_strcasecmp(ttype[i],"MEMBER_POSITION") == 0 || fits_strcasecmp(ttype[i],"MEMBER_VERSION") == 0) { snprintf(keyword,FLEN_KEYWORD,"TFORM%d",i+1); *status = fits_read_key_str(fptr,keyword,keyvalue,comment, status); snprintf(keyword,FLEN_KEYWORD,"TNULL%d",i+1); *status = fits_insert_key_lng(fptr,keyword,0,"Column Null Value", status); } } /* determine the correct EXTVER value for the new grouping table by finding the highest numbered grouping table EXTVER value the currently exists */ for(extver = 1; (fits_movnam_hdu(fptr,ANY_HDU,"GROUPING",extver,status)) == 0; ++extver); if(*status == BAD_HDU_NUM) *status = 0; /* move back to the new grouping table HDU and update the EXTVER keyword value */ fits_movabs_hdu(fptr,hdunum,&hdutype,status); fits_modify_key_lng(fptr,"EXTVER",extver,"&",status); }while(0); return(*status); } /*---------------------------------------------------------------------------*/ int ffgtch(fitsfile *gfptr, /* FITS pointer to group */ int grouptype, /* code specifying the type of grouping table information: GT_ID_ALL_URI 0 ==> defualt (all columns) GT_ID_REF 1 ==> ID by reference GT_ID_POS 2 ==> ID by position GT_ID_ALL 3 ==> ID by ref. and position GT_ID_REF_URI 11 ==> (1) + URI info GT_ID_POS_URI 12 ==> (2) + URI info */ int *status) /* return status code */ /* Change the grouping table structure of the grouping table pointed to by gfptr. The grouptype code specifies the new structure of the table. This operation only adds or removes grouping table columns, it does not add or delete group members (i.e., table rows). If the grouping table already has the desired structure then no operations are performed and function simply returns with a (0) success status code. If the requested structure change creates new grouping table columns, then the column values for all existing members will be filled with the appropriate null values. */ { int xtensionCol, extnameCol, extverCol, positionCol, locationCol, uriCol; int ncols = 0; int colnum = 0; int nrows = 0; int grptype = 0; int i,j; long intNull = 0; long tfields = 0; char *tform[6]; char *ttype[6]; unsigned char charNull[1] = {'\0'}; char ttypeBuff[102]; char tformBuff[54]; char keyword[FLEN_KEYWORD]; char keyvalue[FLEN_VALUE]; char comment[FLEN_COMMENT]; if(*status != 0) return(*status); do { /* set up the ttype and tform character buffers */ for(i = 0; i < 6; ++i) { ttype[i] = ttypeBuff+(i*17); tform[i] = tformBuff+(i*9); } /* retrieve positions of all Grouping table reserved columns */ *status = ffgtgc(gfptr,&xtensionCol,&extnameCol,&extverCol,&positionCol, &locationCol,&uriCol,&grptype,status); if(*status != 0) continue; /* determine the total number of grouping table columns */ *status = fits_read_key_lng(gfptr,"TFIELDS",&tfields,comment,status); /* define grouping table columns to be added to the configuration */ *status = ffgtdc(grouptype,xtensionCol,extnameCol,extverCol,positionCol, locationCol,uriCol,ttype,tform,&ncols,status); /* delete any grouping tables columns that exist but do not belong to new desired configuration; note that we delete before creating new columns for (file size) efficiency reasons */ switch(grouptype) { case GT_ID_ALL_URI: /* no columns to be deleted in this case */ break; case GT_ID_REF: if(positionCol != 0) { *status = fits_delete_col(gfptr,positionCol,status); --tfields; if(uriCol > positionCol) --uriCol; if(locationCol > positionCol) --locationCol; } if(uriCol != 0) { *status = fits_delete_col(gfptr,uriCol,status); --tfields; if(locationCol > uriCol) --locationCol; } if(locationCol != 0) *status = fits_delete_col(gfptr,locationCol,status); break; case GT_ID_POS: if(xtensionCol != 0) { *status = fits_delete_col(gfptr,xtensionCol,status); --tfields; if(extnameCol > xtensionCol) --extnameCol; if(extverCol > xtensionCol) --extverCol; if(uriCol > xtensionCol) --uriCol; if(locationCol > xtensionCol) --locationCol; } if(extnameCol != 0) { *status = fits_delete_col(gfptr,extnameCol,status); --tfields; if(extverCol > extnameCol) --extverCol; if(uriCol > extnameCol) --uriCol; if(locationCol > extnameCol) --locationCol; } if(extverCol != 0) { *status = fits_delete_col(gfptr,extverCol,status); --tfields; if(uriCol > extverCol) --uriCol; if(locationCol > extverCol) --locationCol; } if(uriCol != 0) { *status = fits_delete_col(gfptr,uriCol,status); --tfields; if(locationCol > uriCol) --locationCol; } if(locationCol != 0) { *status = fits_delete_col(gfptr,locationCol,status); --tfields; } break; case GT_ID_ALL: if(uriCol != 0) { *status = fits_delete_col(gfptr,uriCol,status); --tfields; if(locationCol > uriCol) --locationCol; } if(locationCol != 0) { *status = fits_delete_col(gfptr,locationCol,status); --tfields; } break; case GT_ID_REF_URI: if(positionCol != 0) { *status = fits_delete_col(gfptr,positionCol,status); --tfields; } break; case GT_ID_POS_URI: if(xtensionCol != 0) { *status = fits_delete_col(gfptr,xtensionCol,status); --tfields; if(extnameCol > xtensionCol) --extnameCol; if(extverCol > xtensionCol) --extverCol; } if(extnameCol != 0) { *status = fits_delete_col(gfptr,extnameCol,status); --tfields; if(extverCol > extnameCol) --extverCol; } if(extverCol != 0) { *status = fits_delete_col(gfptr,extverCol,status); --tfields; } break; default: *status = BAD_OPTION; ffpmsg("Invalid value for grouptype parameter specified (ffgtch)"); break; } /* add all the new grouping table columns that were not there previously but are called for by the grouptype parameter */ for(i = 0; i < ncols && *status == 0; ++i) *status = fits_insert_col(gfptr,tfields+i+1,ttype[i],tform[i],status); /* add the TNULL keywords and values for each new integer column defined; integer null values are zero (0) for the MEMBER_POSITION and MEMBER_VERSION columns. Insert a null ("/0") into each new string column defined: MEMBER_XTENSION, MEMBER_NAME, MEMBER_URI_TYPE and MEMBER_LOCATION. Note that by convention a null string is the TNULL value for character fields so no TNULL is required. */ for(i = 0; i < ncols && *status == 0; ++i) { if(fits_strcasecmp(ttype[i],"MEMBER_POSITION") == 0 || fits_strcasecmp(ttype[i],"MEMBER_VERSION") == 0) { /* col contains int data; set TNULL and insert 0 for each col */ *status = fits_get_colnum(gfptr,CASESEN,ttype[i],&colnum, status); snprintf(keyword,FLEN_KEYWORD,"TFORM%d",colnum); *status = fits_read_key_str(gfptr,keyword,keyvalue,comment, status); snprintf(keyword,FLEN_KEYWORD,"TNULL%d",colnum); *status = fits_insert_key_lng(gfptr,keyword,0, "Column Null Value",status); for(j = 1; j <= nrows && *status == 0; ++j) *status = fits_write_col_lng(gfptr,colnum,j,1,1,&intNull, status); } else if(fits_strcasecmp(ttype[i],"MEMBER_XTENSION") == 0 || fits_strcasecmp(ttype[i],"MEMBER_NAME") == 0 || fits_strcasecmp(ttype[i],"MEMBER_URI_TYPE") == 0 || fits_strcasecmp(ttype[i],"MEMBER_LOCATION") == 0) { /* new col contains character data; insert NULLs into each col */ *status = fits_get_colnum(gfptr,CASESEN,ttype[i],&colnum, status); for(j = 1; j <= nrows && *status == 0; ++j) /* WILL THIS WORK FOR VAR LENTH CHAR COLS??????*/ *status = fits_write_col_byt(gfptr,colnum,j,1,1,charNull, status); } } }while(0); return(*status); } /*---------------------------------------------------------------------------*/ int ffgtrm(fitsfile *gfptr, /* FITS file pointer to group */ int rmopt, /* code specifying if member elements are to be deleted: OPT_RM_GPT ==> remove only group table OPT_RM_ALL ==> recursively remove members and their members (if groups) */ int *status) /* return status code */ /* remove a grouping table, and optionally all its members. Any groups containing the grouping table are updated, and all members (if not deleted) have their GRPIDn and GRPLCn keywords updated accordingly. If the (deleted) members are members of another grouping table then those tables are also updated. The CHDU of the FITS file pointed to by gfptr must be positioned to the grouping table to be deleted. */ { int hdutype; long i; long nmembers = 0; HDUtracker HDU; if(*status != 0) return(*status); /* remove the grouping table depending upon the rmopt parameter */ switch(rmopt) { case OPT_RM_GPT: /* for this option, the grouping table is deleted, but the member HDUs remain; in this case we only have to remove each member from the grouping table by calling fits_remove_member() with the OPT_RM_ENTRY option */ /* get the number of members contained by this table */ *status = fits_get_num_members(gfptr,&nmembers,status); /* loop over all grouping table members and remove them */ for(i = nmembers; i > 0 && *status == 0; --i) *status = fits_remove_member(gfptr,i,OPT_RM_ENTRY,status); break; case OPT_RM_ALL: /* for this option the entire Group is deleted -- this includes all members and their members (if grouping tables themselves). Call the recursive form of this function to perform the removal. */ /* add the current grouping table to the HDUtracker struct */ HDU.nHDU = 0; *status = fftsad(gfptr,&HDU,NULL,NULL); /* call the recursive group remove function */ *status = ffgtrmr(gfptr,&HDU,status); /* free the memory allocated to the HDUtracker struct */ for(i = 0; i < HDU.nHDU; ++i) { free(HDU.filename[i]); free(HDU.newFilename[i]); } break; default: *status = BAD_OPTION; ffpmsg("Invalid value for the rmopt parameter specified (ffgtrm)"); break; } /* if all went well then unlink and delete the grouping table HDU */ *status = ffgmul(gfptr,0,status); *status = fits_delete_hdu(gfptr,&hdutype,status); return(*status); } /*---------------------------------------------------------------------------*/ int ffgtcp(fitsfile *infptr, /* input FITS file pointer */ fitsfile *outfptr, /* output FITS file pointer */ int cpopt, /* code specifying copy options: OPT_GCP_GPT (0) ==> copy only grouping table OPT_GCP_ALL (2) ==> recusrively copy members and their members (if groups) */ int *status) /* return status code */ /* copy a grouping table, and optionally all its members, to a new FITS file. If the cpopt is set to OPT_GCP_GPT (copy grouping table only) then the existing members have their GRPIDn and GRPLCn keywords updated to reflect the existance of the new group, since they now belong to another group. If cpopt is set to OPT_GCP_ALL (copy grouping table and members recursively) then the original members are not updated; the new grouping table is modified to include only the copied member HDUs and not the original members. Note that the recursive version of this function, ffgtcpr(), is called to perform the group table copy. In the case of cpopt == OPT_GCP_GPT ffgtcpr() does not actually use recursion. */ { int i; HDUtracker HDU; if(*status != 0) return(*status); /* make sure infptr and outfptr are not the same pointer */ if(infptr == outfptr) *status = IDENTICAL_POINTERS; else { /* initialize the HDUtracker struct */ HDU.nHDU = 0; *status = fftsad(infptr,&HDU,NULL,NULL); /* call the recursive form of this function to copy the grouping table. If the cpopt is OPT_GCP_GPT then there is actually no recursion performed */ *status = ffgtcpr(infptr,outfptr,cpopt,&HDU,status); /* free memory allocated for the HDUtracker struct */ for(i = 0; i < HDU.nHDU; ++i) { free(HDU.filename[i]); free(HDU.newFilename[i]); } } return(*status); } /*---------------------------------------------------------------------------*/ int ffgtmg(fitsfile *infptr, /* FITS file ptr to source grouping table */ fitsfile *outfptr, /* FITS file ptr to target grouping table */ int mgopt, /* code specifying merge options: OPT_MRG_COPY (0) ==> copy members to target group, leaving source group in place OPT_MRG_MOV (1) ==> move members to target group, source group is deleted after merge */ int *status) /* return status code */ /* merge two grouping tables by combining their members into a single table. The source grouping table must be the CHDU of the fitsfile pointed to by infptr, and the target grouping table must be the CHDU of the fitsfile to by outfptr. All members of the source grouping table shall be copied to the target grouping table. If the mgopt parameter is OPT_MRG_COPY then the source grouping table continues to exist after the merge. If the mgopt parameter is OPT_MRG_MOV then the source grouping table is deleted after the merge, and all member HDUs are updated accordingly. */ { long i ; long nmembers = 0; fitsfile *tmpfptr = NULL; if(*status != 0) return(*status); do { *status = fits_get_num_members(infptr,&nmembers,status); for(i = 1; i <= nmembers && *status == 0; ++i) { *status = fits_open_member(infptr,i,&tmpfptr,status); *status = fits_add_group_member(outfptr,tmpfptr,0,status); if(*status == HDU_ALREADY_MEMBER) *status = 0; if(tmpfptr != NULL) { fits_close_file(tmpfptr,status); tmpfptr = NULL; } } if(*status != 0) continue; if(mgopt == OPT_MRG_MOV) *status = fits_remove_group(infptr,OPT_RM_GPT,status); }while(0); if(tmpfptr != NULL) { fits_close_file(tmpfptr,status); } return(*status); } /*---------------------------------------------------------------------------*/ int ffgtcm(fitsfile *gfptr, /* FITS file pointer to grouping table */ int cmopt, /* code specifying compact options OPT_CMT_MBR (1) ==> compact only direct members (if groups) OPT_CMT_MBR_DEL (11) ==> (1) + delete all compacted groups */ int *status) /* return status code */ /* "Compact" a group pointed to by the FITS file pointer gfptr. This is achieved by flattening the tree structure of a group and its (grouping table) members. All members HDUs of a grouping table which is itself a member of the grouping table gfptr are added to gfptr. Optionally, the grouping tables which are "compacted" are deleted. If the grouping table contains no members that are themselves grouping tables then this function performs a NOOP. */ { long i; long nmembers = 0; char keyvalue[FLEN_VALUE]; char comment[FLEN_COMMENT]; fitsfile *mfptr = NULL; if(*status != 0) return(*status); do { if(cmopt != OPT_CMT_MBR && cmopt != OPT_CMT_MBR_DEL) { *status = BAD_OPTION; ffpmsg("Invalid value for cmopt parameter specified (ffgtcm)"); continue; } /* reteive the number of grouping table members */ *status = fits_get_num_members(gfptr,&nmembers,status); /* loop over all the grouping table members; if the member is a grouping table then merge its members with the parent grouping table */ for(i = 1; i <= nmembers && *status == 0; ++i) { *status = fits_open_member(gfptr,i,&mfptr,status); if(*status != 0) continue; *status = fits_read_key_str(mfptr,"EXTNAME",keyvalue,comment,status); /* if no EXTNAME keyword then cannot be a grouping table */ if(*status == KEY_NO_EXIST) { *status = 0; continue; } prepare_keyvalue(keyvalue); if(*status != 0) continue; /* if EXTNAME == "GROUPING" then process member as grouping table */ if(fits_strcasecmp(keyvalue,"GROUPING") == 0) { /* merge the member (grouping table) into the grouping table */ *status = fits_merge_groups(mfptr,gfptr,OPT_MRG_COPY,status); *status = fits_close_file(mfptr,status); mfptr = NULL; /* remove the member from the grouping table now that all of its members have been transferred; if cmopt is set to OPT_CMT_MBR_DEL then remove and delete the member */ if(cmopt == OPT_CMT_MBR) *status = fits_remove_member(gfptr,i,OPT_RM_ENTRY,status); else *status = fits_remove_member(gfptr,i,OPT_RM_MBR,status); } else { /* not a grouping table; just close the opened member */ *status = fits_close_file(mfptr,status); mfptr = NULL; } } }while(0); return(*status); } /*--------------------------------------------------------------------------*/ int ffgtvf(fitsfile *gfptr, /* FITS file pointer to group */ long *firstfailed, /* Member ID (if positive) of first failed member HDU verify check or GRPID index (if negitive) of first failed group link verify check. */ int *status) /* return status code */ /* check the integrity of a grouping table to make sure that all group members are accessible and all the links to other grouping tables are valid. The firstfailed parameter returns the member ID of the first member HDU to fail verification if positive or the first group link to fail if negative; otherwise firstfailed contains a return value of 0. */ { long i; long nmembers = 0; long ngroups = 0; char errstr[FLEN_VALUE]; fitsfile *fptr = NULL; if(*status != 0) return(*status); *firstfailed = 0; do { /* attempt to open all the members of the grouping table. We stop at the first member which cannot be opened (which implies that it cannot be located) */ *status = fits_get_num_members(gfptr,&nmembers,status); for(i = 1; i <= nmembers && *status == 0; ++i) { *status = fits_open_member(gfptr,i,&fptr,status); fits_close_file(fptr,status); } /* if the status is non-zero from the above loop then record the member index that caused the error */ if(*status != 0) { *firstfailed = i; snprintf(errstr,FLEN_VALUE,"Group table verify failed for member %ld (ffgtvf)", i); ffpmsg(errstr); continue; } /* attempt to open all the groups linked to this grouping table. We stop at the first group which cannot be opened (which implies that it cannot be located) */ *status = fits_get_num_groups(gfptr,&ngroups,status); for(i = 1; i <= ngroups && *status == 0; ++i) { *status = fits_open_group(gfptr,i,&fptr,status); fits_close_file(fptr,status); } /* if the status from the above loop is non-zero, then record the GRPIDn index of the group that caused the failure */ if(*status != 0) { *firstfailed = -1*i; snprintf(errstr,FLEN_VALUE, "Group table verify failed for GRPID index %ld (ffgtvf)",i); ffpmsg(errstr); continue; } }while(0); return(*status); } /*---------------------------------------------------------------------------*/ int ffgtop(fitsfile *mfptr, /* FITS file pointer to the member HDU */ int grpid, /* group ID (GRPIDn index) within member HDU */ fitsfile **gfptr, /* FITS file pointer to grouping table HDU */ int *status) /* return status code */ /* open the grouping table that contains the member HDU. The member HDU must be the CHDU of the FITS file pointed to by mfptr, and the grouping table is identified by the Nth index number of the GRPIDn keywords specified in the member HDU's header. The fitsfile gfptr pointer is positioned with the appropriate FITS file with the grouping table as the CHDU. If the group grouping table resides in a file other than the member then an attempt is first made to open the file readwrite, and failing that readonly. Note that it is possible for the GRPIDn/GRPLCn keywords in a member header to be non-continuous, e.g., GRPID1, GRPID2, GRPID5, GRPID6. In such cases, the grpid index value specified in the function call shall identify the (grpid)th GRPID value. In the above example, if grpid == 3, then the group specified by GRPID5 would be opened. */ { int i; int found; long ngroups = 0; long grpExtver = 0; char keyword[FLEN_KEYWORD]; char keyvalue[FLEN_FILENAME]; char *tkeyvalue; char location[FLEN_FILENAME]; char location1[FLEN_FILENAME]; char location2[FLEN_FILENAME]; char comment[FLEN_COMMENT]; char *url[2]; if(*status != 0) return(*status); do { /* set the grouping table pointer to NULL for error checking later */ *gfptr = NULL; /* make sure that the group ID requested is valid ==> cannot be larger than the number of GRPIDn keywords in the member HDU header */ *status = fits_get_num_groups(mfptr,&ngroups,status); if(grpid > ngroups) { *status = BAD_GROUP_ID; snprintf(comment,FLEN_COMMENT, "GRPID index %d larger total GRPID keywords %ld (ffgtop)", grpid,ngroups); ffpmsg(comment); continue; } /* find the (grpid)th group that the member HDU belongs to and read the value of the GRPID(grpid) keyword; fits_get_num_groups() automatically re-enumerates the GRPIDn/GRPLCn keywords to fill in any gaps */ snprintf(keyword,FLEN_KEYWORD,"GRPID%d",grpid); *status = fits_read_key_lng(mfptr,keyword,&grpExtver,comment,status); if(*status != 0) continue; /* if the value of the GRPIDn keyword is positive then the member is in the same FITS file as the grouping table and we only have to reopen the current FITS file. Else the member and grouping table HDUs reside in different files and another FITS file must be opened as specified by the corresponding GRPLCn keyword The DO WHILE loop only executes once and is used to control the file opening logic. */ do { if(grpExtver > 0) { /* the member resides in the same file as the grouping table, so just reopen the grouping table file */ *status = fits_reopen_file(mfptr,gfptr,status); continue; } else if(grpExtver == 0) { /* a GRPIDn value of zero (0) is undefined */ *status = BAD_GROUP_ID; snprintf(comment,FLEN_COMMENT,"Invalid value of %ld for GRPID%d (ffgtop)", grpExtver,grpid); ffpmsg(comment); continue; } /* The GRPLCn keyword value is negative, which implies that the grouping table must reside in another FITS file; search for the corresponding GRPLCn keyword */ /* set the grpExtver value positive */ grpExtver = -1*grpExtver; /* read the GRPLCn keyword value */ snprintf(keyword,FLEN_KEYWORD,"GRPLC%d",grpid); /* SPR 1738 */ *status = fits_read_key_longstr(mfptr,keyword,&tkeyvalue,comment, status); if (0 == *status) { strcpy(keyvalue,tkeyvalue); free(tkeyvalue); } /* if the GRPLCn keyword was not found then there is a problem */ if(*status == KEY_NO_EXIST) { *status = BAD_GROUP_ID; snprintf(comment,FLEN_COMMENT,"Cannot find GRPLC%d keyword (ffgtop)", grpid); ffpmsg(comment); continue; } prepare_keyvalue(keyvalue); /* if the GRPLCn keyword value specifies an absolute URL then try to open the file; we cannot attempt any relative URL or host-dependent file path reconstruction */ if(fits_is_url_absolute(keyvalue)) { ffpmsg("Try to open group table file as absolute URL (ffgtop)"); *status = fits_open_file(gfptr,keyvalue,READWRITE,status); /* if the open was successful then continue */ if(*status == 0) continue; /* if READWRITE failed then try opening it READONLY */ ffpmsg("OK, try open group table file as READONLY (ffgtop)"); *status = 0; *status = fits_open_file(gfptr,keyvalue,READONLY,status); /* continue regardless of the outcome */ continue; } /* see if the URL gives a file path that is absolute on the host machine */ *status = fits_url2path(keyvalue,location1,status); *status = fits_open_file(gfptr,location1,READWRITE,status); /* if the file opened then continue */ if(*status == 0) continue; /* if READWRITE failed then try opening it READONLY */ ffpmsg("OK, try open group table file as READONLY (ffgtop)"); *status = 0; *status = fits_open_file(gfptr,location1,READONLY,status); /* if the file opened then continue */ if(*status == 0) continue; /* the grouping table location given by GRPLCn must specify a relative URL. We assume that this URL is relative to the member HDU's FITS file. Try to construct a full URL location for the grouping table's FITS file and then open it */ *status = 0; /* retrieve the URL information for the member HDU's file */ url[0] = location1; url[1] = location2; *status = fits_get_url(mfptr,url[0],url[1],NULL,NULL,NULL,status); /* It is possible that the member HDU file has an initial URL it was opened with and a real URL that the file actually exists at (e.g., an HTTP accessed file copied to a local file). For each possible URL try to construct a */ for(i = 0, found = 0, *gfptr = NULL; i < 2 && !found; ++i) { /* the url string could be empty */ if(*url[i] == 0) continue; /* create a full URL from the partial and the member HDU file URL */ *status = fits_relurl2url(url[i],keyvalue,location,status); /* if an error occured then contniue */ if(*status != 0) { *status = 0; continue; } /* if the location does not specify an access method then turn it into a host dependent path */ if(! fits_is_url_absolute(location)) { *status = fits_url2path(location,url[i],status); strcpy(location,url[i]); } /* try to open the grouping table file READWRITE */ *status = fits_open_file(gfptr,location,READWRITE,status); if(*status != 0) { /* try to open the grouping table file READONLY */ ffpmsg("opening file as READWRITE failed (ffgtop)"); ffpmsg("OK, try to open file as READONLY (ffgtop)"); *status = 0; *status = fits_open_file(gfptr,location,READONLY,status); } /* either set the found flag or reset the status flag */ if(*status == 0) found = 1; else *status = 0; } }while(0); /* end of file opening loop */ /* if an error occured with the file opening then exit */ if(*status != 0) continue; if(*gfptr == NULL) { ffpmsg("Cannot open or find grouping table FITS file (ffgtop)"); *status = GROUP_NOT_FOUND; continue; } /* search for the grouping table in its FITS file */ *status = fits_movnam_hdu(*gfptr,ANY_HDU,"GROUPING",(int)grpExtver, status); if(*status != 0) *status = GROUP_NOT_FOUND; }while(0); if(*status != 0 && *gfptr != NULL) { fits_close_file(*gfptr,status); *gfptr = NULL; } return(*status); } /*---------------------------------------------------------------------------*/ int ffgtam(fitsfile *gfptr, /* FITS file pointer to grouping table HDU */ fitsfile *mfptr, /* FITS file pointer to member HDU */ int hdupos, /* member HDU position IF in the same file as the grouping table AND mfptr == NULL */ int *status) /* return status code */ /* add a member HDU to an existing grouping table. The fitsfile pointer gfptr must be positioned with the grouping table as the CHDU. The member HDU may either be identifed with the fitsfile *mfptr (which must be positioned to the member HDU) or the hdupos parameter (the HDU number of the member HDU) if both reside in the same FITS file. The hdupos value is only used if the mfptr parameter has a value of NULL (0). The new member HDU shall have the appropriate GRPIDn and GRPLCn keywords created in its header. Note that if the member HDU to be added to the grouping table is already a member of the group then it will not be added a sceond time. */ { int xtensionCol,extnameCol,extverCol,positionCol,locationCol,uriCol; int memberPosition = 0; int grptype = 0; int hdutype = 0; int useLocation = 0; int nkeys = 6; int found; int i; int memberIOstate; int groupIOstate; int iomode; long memberExtver = 0; long groupExtver = 0; long memberID = 0; long nmembers = 0; long ngroups = 0; long grpid = 0; char memberAccess1[FLEN_VALUE]; char memberAccess2[FLEN_VALUE]; char memberFileName[FLEN_FILENAME]; char memberLocation[FLEN_FILENAME]; char grplc[FLEN_FILENAME]; char *tgrplc; char memberHDUtype[FLEN_VALUE]; char memberExtname[FLEN_VALUE]; char memberURI[] = "URL"; char groupAccess1[FLEN_VALUE]; char groupAccess2[FLEN_VALUE]; char groupFileName[FLEN_FILENAME]; char groupLocation[FLEN_FILENAME]; char tmprootname[FLEN_FILENAME], grootname[FLEN_FILENAME]; char cwd[FLEN_FILENAME]; char *keys[] = {"GRPNAME","EXTVER","EXTNAME","TFIELDS","GCOUNT","EXTEND"}; char *tmpPtr[1]; char keyword[FLEN_KEYWORD]; char card[FLEN_CARD]; unsigned char charNull[] = {'\0'}; fitsfile *tmpfptr = NULL; int parentStatus = 0; if(*status != 0) return(*status); do { /* make sure the grouping table can be modified before proceeding */ fits_file_mode(gfptr,&iomode,status); if(iomode != READWRITE) { ffpmsg("cannot modify grouping table (ffgtam)"); *status = BAD_GROUP_ATTACH; continue; } /* if the calling function supplied the HDU position of the member HDU instead of fitsfile pointer then get a fitsfile pointer */ if(mfptr == NULL) { *status = fits_reopen_file(gfptr,&tmpfptr,status); *status = fits_movabs_hdu(tmpfptr,hdupos,&hdutype,status); if(*status != 0) continue; } else tmpfptr = mfptr; /* determine all the information about the member HDU that will be needed later; note that we establish the default values for all information values that are not explicitly found */ *status = fits_read_key_str(tmpfptr,"XTENSION",memberHDUtype,card, status); if(*status == KEY_NO_EXIST) { strcpy(memberHDUtype,"PRIMARY"); *status = 0; } prepare_keyvalue(memberHDUtype); *status = fits_read_key_lng(tmpfptr,"EXTVER",&memberExtver,card,status); if(*status == KEY_NO_EXIST) { memberExtver = 1; *status = 0; } *status = fits_read_key_str(tmpfptr,"EXTNAME",memberExtname,card, status); if(*status == KEY_NO_EXIST) { memberExtname[0] = 0; *status = 0; } prepare_keyvalue(memberExtname); fits_get_hdu_num(tmpfptr,&memberPosition); /* Determine if the member HDU's FITS file location needs to be taken into account when building its grouping table reference If the member location needs to be used (==> grouping table and member HDU reside in different files) then create an appropriate URL for the member HDU's file and grouping table's file. Note that the logic for this is rather complicated */ /* SPR 3463, don't do this if(tmpfptr->Fptr == gfptr->Fptr) { */ /* member HDU and grouping table reside in the same file, no need to use the location information */ /* printf ("same file\n"); useLocation = 0; memberIOstate = 1; *memberFileName = 0; } else { */ /* the member HDU and grouping table FITS file location information must be used. First determine the correct driver and file name for the group table and member HDU files. If either are disk files then construct an absolute file path for them. Finally, if both are disk files construct relative file paths from the group(member) file to the member(group) file. */ /* set the USELOCATION flag to true */ useLocation = 1; /* get the location, access type and iostate (RO, RW) of the member HDU file */ *status = fits_get_url(tmpfptr,memberFileName,memberLocation, memberAccess1,memberAccess2,&memberIOstate, status); /* if the memberFileName string is empty then use the values of the memberLocation string. This corresponds to a file where the "real" file is a temporary memory file, and we must assume the the application really wants the original file to be the group member */ if(strlen(memberFileName) == 0) { strcpy(memberFileName,memberLocation); strcpy(memberAccess1,memberAccess2); } /* get the location, access type and iostate (RO, RW) of the grouping table file */ *status = fits_get_url(gfptr,groupFileName,groupLocation, groupAccess1,groupAccess2,&groupIOstate, status); if(*status != 0) continue; /* the grouping table file must be writable to continue */ if(groupIOstate == 0) { ffpmsg("cannot modify grouping table (ffgtam)"); *status = BAD_GROUP_ATTACH; continue; } /* determine how to construct the resulting URLs for the member and group files */ if(fits_strcasecmp(groupAccess1,"file://") && fits_strcasecmp(memberAccess1,"file://")) { *cwd = 0; /* nothing to do in this case; both the member and group files must be of an access type that already gives valid URLs; i.e., URLs that we can pass directly to the file drivers */ } else { /* retrieve the Current Working Directory as a Unix-like URL standard string */ *status = fits_get_cwd(cwd,status); /* create full file path for the member HDU FITS file URL if it is of access type file:// */ if(fits_strcasecmp(memberAccess1,"file://") == 0) { if(*memberFileName == '/') { strcpy(memberLocation,memberFileName); } else { strcpy(memberLocation,cwd); if (strlen(memberLocation)+strlen(memberFileName)+1 > FLEN_FILENAME-1) { ffpmsg("member path and filename is too long (ffgtam)"); *status = URL_PARSE_ERROR; continue; } strcat(memberLocation,"/"); strcat(memberLocation,memberFileName); } *status = fits_clean_url(memberLocation,memberFileName, status); } /* create full file path for the grouping table HDU FITS file URL if it is of access type file:// */ if(fits_strcasecmp(groupAccess1,"file://") == 0) { if(*groupFileName == '/') { strcpy(groupLocation,groupFileName); } else { strcpy(groupLocation,cwd); if (strlen(groupLocation)+strlen(groupFileName)+1 > FLEN_FILENAME-1) { ffpmsg("group path and filename is too long (ffgtam)"); *status = URL_PARSE_ERROR; continue; } strcat(groupLocation,"/"); strcat(groupLocation,groupFileName); } *status = fits_clean_url(groupLocation,groupFileName,status); } /* if both the member and group files are disk files then create a relative path (relative URL) strings with respect to the grouping table's file and the grouping table's file with respect to the member HDU's file */ if(fits_strcasecmp(groupAccess1,"file://") == 0 && fits_strcasecmp(memberAccess1,"file://") == 0) { fits_url2relurl(memberFileName,groupFileName, groupLocation,status); fits_url2relurl(groupFileName,memberFileName, memberLocation,status); /* copy the resulting partial URL strings to the memberFileName and groupFileName variables for latter use in the function */ strcpy(memberFileName,memberLocation); strcpy(groupFileName,groupLocation); } } /* beo done */ /* } */ /* retrieve the grouping table's EXTVER value */ *status = fits_read_key_lng(gfptr,"EXTVER",&groupExtver,card,status); /* if useLocation is true then make the group EXTVER value negative for the subsequent GRPIDn/GRPLCn matching */ /* SPR 3463 change test; WDP added test for same filename */ /* Now, if either the Fptr values are the same, or the root filenames are the same, then assume these refer to the same file. */ fits_parse_rootname(tmpfptr->Fptr->filename, tmprootname, status); fits_parse_rootname(gfptr->Fptr->filename, grootname, status); if((tmpfptr->Fptr != gfptr->Fptr) && strncmp(tmprootname, grootname, FLEN_FILENAME)) groupExtver = -1*groupExtver; /* retrieve the number of group members */ *status = fits_get_num_members(gfptr,&nmembers,status); do { /* make sure the member HDU is not already an entry in the grouping table before adding it */ *status = ffgmf(gfptr,memberHDUtype,memberExtname,memberExtver, memberPosition,memberFileName,&memberID,status); if(*status == MEMBER_NOT_FOUND) *status = 0; else if(*status == 0) { parentStatus = HDU_ALREADY_MEMBER; ffpmsg("Specified HDU is already a member of the Grouping table (ffgtam)"); continue; } else continue; /* if the member HDU is not already recorded in the grouping table then add it */ /* add a new row to the grouping table */ *status = fits_insert_rows(gfptr,nmembers,1,status); ++nmembers; /* retrieve the grouping table column IDs and structure type */ *status = ffgtgc(gfptr,&xtensionCol,&extnameCol,&extverCol,&positionCol, &locationCol,&uriCol,&grptype,status); /* fill in the member HDU data in the new grouping table row */ *tmpPtr = memberHDUtype; if(xtensionCol != 0) fits_write_col_str(gfptr,xtensionCol,nmembers,1,1,tmpPtr,status); *tmpPtr = memberExtname; if(extnameCol != 0) { if(strlen(memberExtname) != 0) fits_write_col_str(gfptr,extnameCol,nmembers,1,1,tmpPtr,status); else /* WILL THIS WORK FOR VAR LENTH CHAR COLS??????*/ fits_write_col_byt(gfptr,extnameCol,nmembers,1,1,charNull,status); } if(extverCol != 0) fits_write_col_lng(gfptr,extverCol,nmembers,1,1,&memberExtver, status); if(positionCol != 0) fits_write_col_int(gfptr,positionCol,nmembers,1,1, &memberPosition,status); *tmpPtr = memberFileName; if(locationCol != 0) { /* Change the test for SPR 3463 */ /* Now, if either the Fptr values are the same, or the root filenames are the same, then assume these refer to the same file. */ fits_parse_rootname(tmpfptr->Fptr->filename, tmprootname, status); fits_parse_rootname(gfptr->Fptr->filename, grootname, status); if((tmpfptr->Fptr != gfptr->Fptr) && strncmp(tmprootname, grootname, FLEN_FILENAME)) fits_write_col_str(gfptr,locationCol,nmembers,1,1,tmpPtr,status); else /* WILL THIS WORK FOR VAR LENTH CHAR COLS??????*/ fits_write_col_byt(gfptr,locationCol,nmembers,1,1,charNull,status); } *tmpPtr = memberURI; if(uriCol != 0) { /* Change the test for SPR 3463 */ /* Now, if either the Fptr values are the same, or the root filenames are the same, then assume these refer to the same file. */ fits_parse_rootname(tmpfptr->Fptr->filename, tmprootname, status); fits_parse_rootname(gfptr->Fptr->filename, grootname, status); if((tmpfptr->Fptr != gfptr->Fptr) && strncmp(tmprootname, grootname, FLEN_FILENAME)) fits_write_col_str(gfptr,uriCol,nmembers,1,1,tmpPtr,status); else /* WILL THIS WORK FOR VAR LENTH CHAR COLS??????*/ fits_write_col_byt(gfptr,uriCol,nmembers,1,1,charNull,status); } } while(0); if(0 != *status) continue; /* add GRPIDn/GRPLCn keywords to the member HDU header to link it to the grouing table if the they do not already exist and the member file is RW */ fits_file_mode(tmpfptr,&iomode,status); if(memberIOstate == 0 || iomode != READWRITE) { ffpmsg("cannot add GRPID/LC keywords to member HDU: (ffgtam)"); ffpmsg(memberFileName); continue; } *status = fits_get_num_groups(tmpfptr,&ngroups,status); /* look for the GRPID/LC keywords in the member HDU; if the keywords for the back-link to the grouping table already exist then no need to add them again */ for(i = 1, found = 0; i <= ngroups && !found && *status == 0; ++i) { snprintf(keyword,FLEN_KEYWORD,"GRPID%d",(int)ngroups); *status = fits_read_key_lng(tmpfptr,keyword,&grpid,card,status); if(grpid == groupExtver) { if(grpid < 0) { /* have to make sure the GRPLCn keyword matches too */ snprintf(keyword,FLEN_KEYWORD,"GRPLC%d",(int)ngroups); /* SPR 1738 */ *status = fits_read_key_longstr(mfptr,keyword,&tgrplc,card, status); if (0 == *status) { strcpy(grplc,tgrplc); free(tgrplc); } /* always compare files using absolute paths the presence of a non-empty cwd indicates that the file names may require conversion to absolute paths */ if(0 < strlen(cwd)) { /* temp buffer for use in assembling abs. path(s) */ char tmp[FLEN_FILENAME]; /* make grplc absolute if necessary */ if(!fits_is_url_absolute(grplc)) { fits_path2url(grplc,FLEN_FILENAME,groupLocation,status); if(groupLocation[0] != '/') { strcpy(tmp, cwd); if (strlen(tmp)+strlen(groupLocation)+1 > FLEN_FILENAME-1) { ffpmsg("path and group location is too long (ffgtam)"); *status = URL_PARSE_ERROR; continue; } strcat(tmp,"/"); strcat(tmp,groupLocation); fits_clean_url(tmp,grplc,status); } } /* make groupFileName absolute if necessary */ if(!fits_is_url_absolute(groupFileName)) { fits_path2url(groupFileName,FLEN_FILENAME,groupLocation,status); if(groupLocation[0] != '/') { strcpy(tmp, cwd); if (strlen(tmp)+strlen(groupLocation)+1 > FLEN_FILENAME-1) { ffpmsg("path and group location is too long (ffgtam)"); *status = URL_PARSE_ERROR; continue; } strcat(tmp,"/"); strcat(tmp,groupLocation); /* note: use groupLocation (which is not used below this block), to store the absolute file name instead of using groupFileName. The latter may be needed unaltered if the GRPLC is written below */ fits_clean_url(tmp,groupLocation,status); } } } /* see if the grplc value and the group file name match */ if(strcmp(grplc,groupLocation) == 0) found = 1; } else { /* the match is found with GRPIDn alone */ found = 1; } } } /* if FOUND is true then no need to continue */ if(found) { ffpmsg("HDU already has GRPID/LC keywords for group table (ffgtam)"); continue; } /* add the GRPID/LC keywords to the member header for this grouping table If NGROUPS == 0 then we must position the header pointer to the record where we want to insert the GRPID/LC keywords (the pointer is already correctly positioned if the above search loop activiated) */ if(ngroups == 0) { /* no GRPIDn/GRPLCn keywords currently exist in header so try to position the header pointer to a desirable position */ for(i = 0, *status = KEY_NO_EXIST; i < nkeys && *status == KEY_NO_EXIST; ++i) { *status = 0; *status = fits_read_card(tmpfptr,keys[i],card,status); } /* all else fails: move write pointer to end of header */ if(*status == KEY_NO_EXIST) { *status = 0; fits_get_hdrspace(tmpfptr,&nkeys,&i,status); ffgrec(tmpfptr,nkeys,card,status); } /* any other error status then abort */ if(*status != 0) continue; } /* now that the header pointer is positioned for the GRPID/LC keyword insertion increment the number of group links counter for the member HDU */ ++ngroups; /* if the member HDU and grouping table reside in the same FITS file then there is no need to add a GRPLCn keyword */ /* SPR 3463 change test */ /* Now, if either the Fptr values are the same, or the root filenames are the same, then assume these refer to the same file. */ fits_parse_rootname(tmpfptr->Fptr->filename, tmprootname, status); fits_parse_rootname(gfptr->Fptr->filename, grootname, status); if((tmpfptr->Fptr == gfptr->Fptr) || strncmp(tmprootname, grootname, FLEN_FILENAME) == 0) { /* add the GRPIDn keyword only */ snprintf(keyword,FLEN_KEYWORD,"GRPID%d",(int)ngroups); fits_insert_key_lng(tmpfptr,keyword,groupExtver, "EXTVER of Group containing this HDU",status); } else { /* add the GRPIDn and GRPLCn keywords */ snprintf(keyword,FLEN_KEYWORD,"GRPID%d",(int)ngroups); fits_insert_key_lng(tmpfptr,keyword,groupExtver, "EXTVER of Group containing this HDU",status); snprintf(keyword,FLEN_KEYWORD,"GRPLC%d",(int)ngroups); /* SPR 1738 */ fits_insert_key_longstr(tmpfptr,keyword,groupFileName, "URL of file containing Group",status); fits_write_key_longwarn(tmpfptr,status); } }while(0); /* close the tmpfptr pointer if it was opened in this function */ if(mfptr == NULL) { *status = fits_close_file(tmpfptr,status); } *status = 0 == *status ? parentStatus : *status; return(*status); } /*---------------------------------------------------------------------------*/ int ffgtnm(fitsfile *gfptr, /* FITS file pointer to grouping table */ long *nmembers, /* member count of the groping table */ int *status) /* return status code */ /* return the number of member HDUs in a grouping table. The fitsfile pointer gfptr must be positioned with the grouping table as the CHDU. The number of grouping table member HDUs is just the NAXIS2 value of the grouping table. */ { char keyvalue[FLEN_VALUE]; char comment[FLEN_COMMENT]; if(*status != 0) return(*status); *status = fits_read_keyword(gfptr,"EXTNAME",keyvalue,comment,status); if(*status == KEY_NO_EXIST) *status = NOT_GROUP_TABLE; else { prepare_keyvalue(keyvalue); if(fits_strcasecmp(keyvalue,"GROUPING") != 0) { *status = NOT_GROUP_TABLE; ffpmsg("Specified HDU is not a Grouping table (ffgtnm)"); } *status = fits_read_key_lng(gfptr,"NAXIS2",nmembers,comment,status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgmng(fitsfile *mfptr, /* FITS file pointer to member HDU */ long *ngroups, /* total number of groups linked to HDU */ int *status) /* return status code */ /* return the number of groups to which a HDU belongs, as defined by the number of GRPIDn/GRPLCn keyword records that appear in the HDU header. The fitsfile pointer mfptr must be positioned with the member HDU as the CHDU. Each time this function is called, the indicies of the GRPIDn/GRPLCn keywords are checked to make sure they are continuous (ie no gaps) and are re-enumerated to eliminate gaps if gaps are found to be present. */ { int offset; int index; int newIndex; int i; long grpid; char *inclist[] = {"GRPID#"}; char keyword[FLEN_KEYWORD]; char newKeyword[FLEN_KEYWORD]; char card[FLEN_CARD]; char comment[FLEN_COMMENT]; char *tkeyvalue; if(*status != 0) return(*status); *ngroups = 0; /* reset the member HDU keyword counter to the beginning */ *status = ffgrec(mfptr,0,card,status); /* search for the number of GRPIDn keywords in the member HDU header and count them with the ngroups variable */ while(*status == 0) { /* read the next GRPIDn keyword in the series */ *status = fits_find_nextkey(mfptr,inclist,1,NULL,0,card,status); if(*status != 0) continue; ++(*ngroups); } if(*status == KEY_NO_EXIST) *status = 0; /* read each GRPIDn/GRPLCn keyword and adjust their index values so that there are no gaps in the index count */ for(index = 1, offset = 0, i = 1; i <= *ngroups && *status == 0; ++index) { snprintf(keyword,FLEN_KEYWORD,"GRPID%d",index); /* try to read the next GRPIDn keyword in the series */ *status = fits_read_key_lng(mfptr,keyword,&grpid,card,status); /* if not found then increment the offset counter and continue */ if(*status == KEY_NO_EXIST) { *status = 0; ++offset; } else { /* increment the number_keys_found counter and see if the index of the keyword needs to be updated */ ++i; if(offset > 0) { /* compute the new index for the GRPIDn/GRPLCn keywords */ newIndex = index - offset; /* update the GRPIDn keyword index */ snprintf(newKeyword,FLEN_KEYWORD,"GRPID%d",newIndex); fits_modify_name(mfptr,keyword,newKeyword,status); /* If present, update the GRPLCn keyword index */ snprintf(keyword,FLEN_KEYWORD,"GRPLC%d",index); snprintf(newKeyword,FLEN_KEYWORD,"GRPLC%d",newIndex); /* SPR 1738 */ *status = fits_read_key_longstr(mfptr,keyword,&tkeyvalue,comment, status); if (0 == *status) { fits_delete_key(mfptr,keyword,status); fits_insert_key_longstr(mfptr,newKeyword,tkeyvalue,comment,status); fits_write_key_longwarn(mfptr,status); free(tkeyvalue); } if(*status == KEY_NO_EXIST) *status = 0; } } } return(*status); } /*---------------------------------------------------------------------------*/ int ffgmop(fitsfile *gfptr, /* FITS file pointer to grouping table */ long member, /* member ID (row num) within grouping table */ fitsfile **mfptr, /* FITS file pointer to member HDU */ int *status) /* return status code */ /* open a grouping table member, returning a pointer to the member's FITS file with the CHDU set to the member HDU. The grouping table must be the CHDU of the FITS file pointed to by gfptr. The member to open is identified by its row number within the grouping table (first row/member == 1). If the member resides in a FITS file different from the grouping table the member file is first opened readwrite and if this fails then it is opened readonly. For access type of FILE:// the member file is searched for assuming (1) an absolute path is given, (2) a path relative to the CWD is given, and (3) a path relative to the grouping table file but not relative to the CWD is given. If all of these fail then the error FILE_NOT_FOUND is returned. */ { int xtensionCol,extnameCol,extverCol,positionCol,locationCol,uriCol; int grptype,hdutype; int dummy; long hdupos = 0; long extver = 0; char xtension[FLEN_VALUE]; char extname[FLEN_VALUE]; char uri[FLEN_VALUE]; char grpLocation1[FLEN_FILENAME]; char grpLocation2[FLEN_FILENAME]; char mbrLocation1[FLEN_FILENAME]; char mbrLocation2[FLEN_FILENAME]; char mbrLocation3[FLEN_FILENAME]; char cwd[FLEN_FILENAME]; char card[FLEN_CARD]; char nstr[] = {'\0'}; char *tmpPtr[1]; if(*status != 0) return(*status); do { /* retrieve the Grouping Convention reserved column positions within the grouping table */ *status = ffgtgc(gfptr,&xtensionCol,&extnameCol,&extverCol,&positionCol, &locationCol,&uriCol,&grptype,status); if(*status != 0) continue; /* verify the column formats */ *status = ffvcfm(gfptr,xtensionCol,extnameCol,extverCol,positionCol, locationCol,uriCol,status); if(*status != 0) continue; /* extract the member information from grouping table */ tmpPtr[0] = xtension; if(xtensionCol != 0) { *status = fits_read_col_str(gfptr,xtensionCol,member,1,1,nstr, tmpPtr,&dummy,status); /* convert the xtension string to a hdutype code */ if(fits_strcasecmp(xtension,"PRIMARY") == 0) hdutype = IMAGE_HDU; else if(fits_strcasecmp(xtension,"IMAGE") == 0) hdutype = IMAGE_HDU; else if(fits_strcasecmp(xtension,"TABLE") == 0) hdutype = ASCII_TBL; else if(fits_strcasecmp(xtension,"BINTABLE") == 0) hdutype = BINARY_TBL; else hdutype = ANY_HDU; } tmpPtr[0] = extname; if(extnameCol != 0) *status = fits_read_col_str(gfptr,extnameCol,member,1,1,nstr, tmpPtr,&dummy,status); if(extverCol != 0) *status = fits_read_col_lng(gfptr,extverCol,member,1,1,0, (long*)&extver,&dummy,status); if(positionCol != 0) *status = fits_read_col_lng(gfptr,positionCol,member,1,1,0, (long*)&hdupos,&dummy,status); tmpPtr[0] = mbrLocation1; if(locationCol != 0) *status = fits_read_col_str(gfptr,locationCol,member,1,1,nstr, tmpPtr,&dummy,status); tmpPtr[0] = uri; if(uriCol != 0) *status = fits_read_col_str(gfptr,uriCol,member,1,1,nstr, tmpPtr,&dummy,status); if(*status != 0) continue; /* decide what FITS file the member HDU resides in and open the file using the fitsfile* pointer mfptr; note that this logic is rather complicated and is based primiarly upon if a URL specifier is given for the member file in the grouping table */ switch(grptype) { case GT_ID_POS: case GT_ID_REF: case GT_ID_ALL: /* no location information is given so we must assume that the member HDU resides in the same FITS file as the grouping table; if the grouping table was incorrectly constructed then this assumption will be false, but there is nothing to be done about it at this point */ *status = fits_reopen_file(gfptr,mfptr,status); break; case GT_ID_REF_URI: case GT_ID_POS_URI: case GT_ID_ALL_URI: /* The member location column exists. Determine if the member resides in the same file as the grouping table or in a separate file; open the member file in either case */ if(strlen(mbrLocation1) == 0) { /* since no location information was given we must assume that the member is in the same FITS file as the grouping table */ *status = fits_reopen_file(gfptr,mfptr,status); } else { /* make sure the location specifiation is "URL"; we cannot decode any other URI types at this time */ if(fits_strcasecmp(uri,"URL") != 0) { *status = FILE_NOT_OPENED; snprintf(card,FLEN_CARD, "Cannot open member HDU file with URI type %s (ffgmop)", uri); ffpmsg(card); continue; } /* The location string for the member is not NULL, so it does not necessially reside in the same FITS file as the grouping table. Three cases are attempted for opening the member's file in the following order: 1. The URL given for the member's file is absolute (i.e., access method supplied); try to open the member 2. The URL given for the member's file is not absolute but is an absolute file path; try to open the member as a file after the file path is converted to a host-dependent form 3. The URL given for the member's file is not absolute and is given as a relative path to the location of the grouping table's file. Create an absolute URL using the grouping table's file URL and try to open the member. If all three cases fail then an error is returned. In each case the file is first opened in read/write mode and failing that readonly mode. The following DO loop is only used as a mechanism to break (continue) when the proper file opening method is found */ do { /* CASE 1: See if the member URL is absolute (i.e., includes a access directive) and if so open the file */ if(fits_is_url_absolute(mbrLocation1)) { /* the URL must specify an access method, which implies that its an absolute reference regardless of the access method, pass the whole URL to the open function for processing */ ffpmsg("member URL is absolute, try open R/W (ffgmop)"); *status = fits_open_file(mfptr,mbrLocation1,READWRITE, status); if(*status == 0) continue; *status = 0; /* now try to open file using full URL specs in readonly mode */ ffpmsg("OK, now try to open read-only (ffgmop)"); *status = fits_open_file(mfptr,mbrLocation1,READONLY, status); /* break from DO loop regardless of status */ continue; } /* CASE 2: If we got this far then the member URL location has no access type ==> FILE:// Try to open the member file using the URL as is, i.e., assume that it is given as absolute, if it starts with a '/' character */ ffpmsg("Member URL is of type FILE (ffgmop)"); if(*mbrLocation1 == '/') { ffpmsg("Member URL specifies abs file path (ffgmop)"); /* convert the URL path to a host dependent path */ *status = fits_url2path(mbrLocation1,mbrLocation2, status); ffpmsg("Try to open member URL in R/W mode (ffgmop)"); *status = fits_open_file(mfptr,mbrLocation2,READWRITE, status); if(*status == 0) continue; *status = 0; /* now try to open file using the URL as an absolute path in readonly mode */ ffpmsg("OK, now try to open read-only (ffgmop)"); *status = fits_open_file(mfptr,mbrLocation2,READONLY, status); /* break from the Do loop regardless of the status */ continue; } /* CASE 3: If we got this far then the URL does not specify an absoulte file path or URL with access method. Since the path to the group table's file is (obviously) valid for the CWD, create a full location string for the member HDU using the grouping table URL as a basis The only problem is that the grouping table file might have two URLs, the original one used to open it and the one that points to the real file being accessed (i.e., a file accessed via HTTP but transferred to a local disk file). Have to attempt to build a URL to the member HDU file using both of these URLs if defined. */ ffpmsg("Try to open member file as relative URL (ffgmop)"); /* get the URL information for the grouping table file */ *status = fits_get_url(gfptr,grpLocation1,grpLocation2, NULL,NULL,NULL,status); /* if the "real" grouping table file URL is defined then build a full url for the member HDU file using it and try to open the member HDU file */ if(*grpLocation1) { /* make sure the group location is absolute */ if(! fits_is_url_absolute(grpLocation1) && *grpLocation1 != '/') { fits_get_cwd(cwd,status); strcat(cwd,"/"); if (strlen(cwd)+strlen(grpLocation1)+1 > FLEN_FILENAME-1) { ffpmsg("cwd and group location1 is too long (ffgmop)"); *status = URL_PARSE_ERROR; continue; } strcat(cwd,grpLocation1); strcpy(grpLocation1,cwd); } /* create a full URL for the member HDU file */ *status = fits_relurl2url(grpLocation1,mbrLocation1, mbrLocation2,status); if(*status != 0) continue; /* if the URL does not have an access method given then translate it into a host dependent file path */ if(! fits_is_url_absolute(mbrLocation2)) { *status = fits_url2path(mbrLocation2,mbrLocation3, status); strcpy(mbrLocation2,mbrLocation3); } /* try to open the member file READWRITE */ *status = fits_open_file(mfptr,mbrLocation2,READWRITE, status); if(*status == 0) continue; *status = 0; /* now try to open in readonly mode */ ffpmsg("now try to open file as READONLY (ffgmop)"); *status = fits_open_file(mfptr,mbrLocation2,READONLY, status); if(*status == 0) continue; *status = 0; } /* if we got this far then either the "real" grouping table file URL was not defined or all attempts to open the resulting member HDU file URL failed. if the "original" grouping table file URL is defined then build a full url for the member HDU file using it and try to open the member HDU file */ if(*grpLocation2) { /* make sure the group location is absolute */ if(! fits_is_url_absolute(grpLocation2) && *grpLocation2 != '/') { fits_get_cwd(cwd,status); if (strlen(cwd)+strlen(grpLocation2)+1 > FLEN_FILENAME-1) { ffpmsg("cwd and group location2 is too long (ffgmop)"); *status = URL_PARSE_ERROR; continue; } strcat(cwd,"/"); strcat(cwd,grpLocation2); strcpy(grpLocation2,cwd); } /* create an absolute URL for the member HDU file */ *status = fits_relurl2url(grpLocation2,mbrLocation1, mbrLocation2,status); if(*status != 0) continue; /* if the URL does not have an access method given then translate it into a host dependent file path */ if(! fits_is_url_absolute(mbrLocation2)) { *status = fits_url2path(mbrLocation2,mbrLocation3, status); strcpy(mbrLocation2,mbrLocation3); } /* try to open the member file READWRITE */ *status = fits_open_file(mfptr,mbrLocation2,READWRITE, status); if(*status == 0) continue; *status = 0; /* now try to open in readonly mode */ ffpmsg("now try to open file as READONLY (ffgmop)"); *status = fits_open_file(mfptr,mbrLocation2,READONLY, status); if(*status == 0) continue; *status = 0; } /* if we got this far then the member HDU file could not be opened using any method. Log the error. */ ffpmsg("Cannot open member HDU FITS file (ffgmop)"); *status = MEMBER_NOT_FOUND; }while(0); } break; default: /* no default action */ break; } if(*status != 0) continue; /* attempt to locate the member HDU within its FITS file as determined and opened above */ switch(grptype) { case GT_ID_POS: case GT_ID_POS_URI: /* try to find the member hdu in the the FITS file pointed to by mfptr based upon its HDU posistion value. Note that is impossible to verify if the HDU is actually the correct HDU due to a lack of information. */ *status = fits_movabs_hdu(*mfptr,(int)hdupos,&hdutype,status); break; case GT_ID_REF: case GT_ID_REF_URI: /* try to find the member hdu in the FITS file pointed to by mfptr based upon its XTENSION, EXTNAME and EXTVER keyword values */ *status = fits_movnam_hdu(*mfptr,hdutype,extname,extver,status); if(*status == BAD_HDU_NUM) { *status = MEMBER_NOT_FOUND; ffpmsg("Cannot find specified member HDU (ffgmop)"); } /* if the above function returned without error then the mfptr is pointed to the member HDU */ break; case GT_ID_ALL: case GT_ID_ALL_URI: /* if the member entry has reference information then use it (ID by reference is safer than ID by position) else use the position information */ if(strlen(xtension) > 0 && strlen(extname) > 0 && extver > 0) { /* valid reference info exists so use it */ /* try to find the member hdu in the grouping table's file */ *status = fits_movnam_hdu(*mfptr,hdutype,extname,extver,status); if(*status == BAD_HDU_NUM) { *status = MEMBER_NOT_FOUND; ffpmsg("Cannot find specified member HDU (ffgmop)"); } } else { *status = fits_movabs_hdu(*mfptr,(int)hdupos,&hdutype, status); if(*status == END_OF_FILE) *status = MEMBER_NOT_FOUND; } /* if the above function returned without error then the mfptr is pointed to the member HDU */ break; default: /* no default action */ break; } }while(0); if(*status != 0 && *mfptr != NULL) { fits_close_file(*mfptr,status); } return(*status); } /*---------------------------------------------------------------------------*/ int ffgmcp(fitsfile *gfptr, /* FITS file pointer to group */ fitsfile *mfptr, /* FITS file pointer to new member FITS file */ long member, /* member ID (row num) within grouping table */ int cpopt, /* code specifying copy options: OPT_MCP_ADD (0) ==> add copied member to the grouping table OPT_MCP_NADD (1) ==> do not add member copy to the grouping table OPT_MCP_REPL (2) ==> replace current member entry with member copy */ int *status) /* return status code */ /* copy a member HDU of a grouping table to a new FITS file. The grouping table must be the CHDU of the FITS file pointed to by gfptr. The copy of the group member shall be appended to the end of the FITS file pointed to by mfptr. If the cpopt parameter is set to OPT_MCP_ADD then the copy of the member is added to the grouping table as a new member, if OPT_MCP_NADD then the copied member is not added to the grouping table, and if OPT_MCP_REPL then the copied member is used to replace the original member. The copied member HDU also has its EXTVER value updated so that its combination of XTENSION, EXTNAME and EXVTER is unique within its new FITS file. */ { int numkeys = 0; int keypos = 0; int hdunum = 0; int hdutype = 0; int i; char *incList[] = {"GRPID#","GRPLC#"}; char extname[FLEN_VALUE]; char card[FLEN_CARD]; char comment[FLEN_COMMENT]; char keyname[FLEN_CARD]; char value[FLEN_CARD]; fitsfile *tmpfptr = NULL; if(*status != 0) return(*status); do { /* open the member HDU to be copied */ *status = fits_open_member(gfptr,member,&tmpfptr,status); if(*status != 0) continue; /* if the member is a grouping table then copy it with a call to fits_copy_group() using the "copy only the grouping table" option if it is not a grouping table then copy the hdu with fits_copy_hdu() remove all GRPIDn and GRPLCn keywords, and update the EXTVER keyword value */ /* get the member HDU's EXTNAME value */ *status = fits_read_key_str(tmpfptr,"EXTNAME",extname,comment,status); /* if no EXTNAME value was found then set the extname to a null string */ if(*status == KEY_NO_EXIST) { extname[0] = 0; *status = 0; } else if(*status != 0) continue; prepare_keyvalue(extname); /* if a grouping table then copy with fits_copy_group() */ if(fits_strcasecmp(extname,"GROUPING") == 0) *status = fits_copy_group(tmpfptr,mfptr,OPT_GCP_GPT,status); else { /* copy the non-grouping table HDU the conventional way */ *status = fits_copy_hdu(tmpfptr,mfptr,0,status); ffgrec(mfptr,0,card,status); /* delete all the GRPIDn and GRPLCn keywords in the copied HDU */ while(*status == 0) { *status = fits_find_nextkey(mfptr,incList,2,NULL,0,card,status); *status = fits_get_hdrpos(mfptr,&numkeys,&keypos,status); /* SPR 1738 */ *status = fits_read_keyn(mfptr,keypos-1,keyname,value, comment,status); *status = fits_read_record(mfptr,keypos-1,card,status); *status = fits_delete_key(mfptr,keyname,status); } if(*status == KEY_NO_EXIST) *status = 0; if(*status != 0) continue; } /* if the member HDU does not have an EXTNAME keyword then add one with a default value */ if(strlen(extname) == 0) { if(fits_get_hdu_num(tmpfptr,&hdunum) == 1) { strcpy(extname,"PRIMARY"); *status = fits_write_key_str(mfptr,"EXTNAME",extname, "HDU was Formerly a Primary Array", status); } else { strcpy(extname,"DEFAULT"); *status = fits_write_key_str(mfptr,"EXTNAME",extname, "default EXTNAME set by CFITSIO", status); } } /* update the member HDU's EXTVER value (add it if not present) */ fits_get_hdu_num(mfptr,&hdunum); fits_get_hdu_type(mfptr,&hdutype,status); /* set the EXTVER value to 0 for now */ *status = fits_modify_key_lng(mfptr,"EXTVER",0,NULL,status); /* if the EXTVER keyword was not found then add it */ if(*status == KEY_NO_EXIST) { *status = 0; *status = fits_read_key_str(mfptr,"EXTNAME",extname,comment, status); *status = fits_insert_key_lng(mfptr,"EXTVER",0, "Extension version ID",status); } if(*status != 0) continue; /* find the first available EXTVER value for the copied HDU */ for(i = 1; fits_movnam_hdu(mfptr,hdutype,extname,i,status) == 0; ++i); *status = 0; fits_movabs_hdu(mfptr,hdunum,&hdutype,status); /* reset the copied member HDUs EXTVER value */ *status = fits_modify_key_lng(mfptr,"EXTVER",(long)i,NULL,status); /* perform member copy operations that are dependent upon the cpopt parameter value */ switch(cpopt) { case OPT_MCP_ADD: /* add the copied member to the grouping table, leaving the entry for the original member in place */ *status = fits_add_group_member(gfptr,mfptr,0,status); break; case OPT_MCP_NADD: /* nothing to do for this copy option */ break; case OPT_MCP_REPL: /* remove the original member from the grouping table and add the copied member in its place */ *status = fits_remove_member(gfptr,member,OPT_RM_ENTRY,status); *status = fits_add_group_member(gfptr,mfptr,0,status); break; default: *status = BAD_OPTION; ffpmsg("Invalid value specified for the cmopt parameter (ffgmcp)"); break; } }while(0); if(tmpfptr != NULL) { fits_close_file(tmpfptr,status); } return(*status); } /*---------------------------------------------------------------------------*/ int ffgmtf(fitsfile *infptr, /* FITS file pointer to source grouping table */ fitsfile *outfptr, /* FITS file pointer to target grouping table */ long member, /* member ID within source grouping table */ int tfopt, /* code specifying transfer opts: OPT_MCP_ADD (0) ==> copy member to dest. OPT_MCP_MOV (3) ==> move member to dest. */ int *status) /* return status code */ /* transfer a group member from one grouping table to another. The source grouping table must be the CHDU of the fitsfile pointed to by infptr, and the destination grouping table must be the CHDU of the fitsfile to by outfptr. If the tfopt parameter is OPT_MCP_ADD then the member is made a member of the target group and remains a member of the source group. If the tfopt parameter is OPT_MCP_MOV then the member is deleted from the source group after the transfer to the destination group. The member to be transfered is identified by its row number within the source grouping table. */ { fitsfile *mfptr = NULL; if(*status != 0) return(*status); if(tfopt != OPT_MCP_MOV && tfopt != OPT_MCP_ADD) { *status = BAD_OPTION; ffpmsg("Invalid value specified for the tfopt parameter (ffgmtf)"); } else { /* open the member of infptr to be transfered */ *status = fits_open_member(infptr,member,&mfptr,status); /* add the member to the outfptr grouping table */ *status = fits_add_group_member(outfptr,mfptr,0,status); /* close the member HDU */ *status = fits_close_file(mfptr,status); /* if the tfopt is "move member" then remove it from the infptr grouping table */ if(tfopt == OPT_MCP_MOV) *status = fits_remove_member(infptr,member,OPT_RM_ENTRY,status); } return(*status); } /*---------------------------------------------------------------------------*/ int ffgmrm(fitsfile *gfptr, /* FITS file pointer to group table */ long member, /* member ID (row num) in the group */ int rmopt, /* code specifying the delete option: OPT_RM_ENTRY ==> delete the member entry OPT_RM_MBR ==> delete entry and member HDU */ int *status) /* return status code */ /* remove a member HDU from a grouping table. The fitsfile pointer gfptr must be positioned with the grouping table as the CHDU, and the member to delete is identified by its row number in the table (first member == 1). The rmopt parameter determines if the member entry is deleted from the grouping table (in which case GRPIDn and GRPLCn keywords in the member HDU's header shall be updated accordingly) or if the member HDU shall itself be removed from its FITS file. */ { int found; int hdutype = 0; int index; int iomode = 0; long i; long ngroups = 0; long nmembers = 0; long groupExtver = 0; long grpid = 0; char grpLocation1[FLEN_FILENAME]; char grpLocation2[FLEN_FILENAME]; char grpLocation3[FLEN_FILENAME]; char cwd[FLEN_FILENAME]; char keyword[FLEN_KEYWORD]; /* SPR 1738 This can now be longer */ char grplc[FLEN_FILENAME]; char *tgrplc; char keyvalue[FLEN_VALUE]; char card[FLEN_CARD]; char *editLocation; char mrootname[FLEN_FILENAME], grootname[FLEN_FILENAME]; fitsfile *mfptr = NULL; if(*status != 0) return(*status); do { /* make sure the grouping table can be modified before proceeding */ fits_file_mode(gfptr,&iomode,status); if(iomode != READWRITE) { ffpmsg("cannot modify grouping table (ffgtam)"); *status = BAD_GROUP_DETACH; continue; } /* open the group member to be deleted and get its IOstatus*/ *status = fits_open_member(gfptr,member,&mfptr,status); *status = fits_file_mode(mfptr,&iomode,status); /* if the member HDU is to be deleted then call fits_unlink_member() to remove it from all groups to which it belongs (including this one) and then delete it. Note that if the member is a grouping table then we have to recursively call fits_remove_member() for each member of the member before we delete the member itself. */ if(rmopt == OPT_RM_MBR) { /* cannot delete a PHDU */ if(fits_get_hdu_num(mfptr,&hdutype) == 1) { *status = BAD_HDU_NUM; continue; } /* determine if the member HDU is itself a grouping table */ *status = fits_read_key_str(mfptr,"EXTNAME",keyvalue,card,status); /* if no EXTNAME is found then the HDU cannot be a grouping table */ if(*status == KEY_NO_EXIST) { keyvalue[0] = 0; *status = 0; } prepare_keyvalue(keyvalue); /* Any other error is a reason to abort */ if(*status != 0) continue; /* if the EXTNAME == GROUPING then the member is a grouping table */ if(fits_strcasecmp(keyvalue,"GROUPING") == 0) { /* remove each of the grouping table members */ *status = fits_get_num_members(mfptr,&nmembers,status); for(i = nmembers; i > 0 && *status == 0; --i) *status = fits_remove_member(mfptr,i,OPT_RM_ENTRY,status); if(*status != 0) continue; } /* unlink the member HDU from all groups that contain it */ *status = ffgmul(mfptr,0,status); if(*status != 0) continue; /* reset the grouping table HDU struct */ fits_set_hdustruc(gfptr,status); /* delete the member HDU */ if(iomode != READONLY) *status = fits_delete_hdu(mfptr,&hdutype,status); } else if(rmopt == OPT_RM_ENTRY) { /* The member HDU is only to be removed as an entry from this grouping table. Actions are (1) find the GRPIDn/GRPLCn keywords that link the member to the grouping table, (2) remove the GRPIDn/GRPLCn keyword from the member HDU header and (3) remove the member entry from the grouping table */ /* there is no need to seach for and remove the GRPIDn/GRPLCn keywords from the member HDU if it has not been opened in READWRITE mode */ if(iomode == READWRITE) { /* determine the group EXTVER value of the grouping table; if the member HDU and grouping table HDU do not reside in the same file then set the groupExtver value to its negative */ *status = fits_read_key_lng(gfptr,"EXTVER",&groupExtver,card, status); /* Now, if either the Fptr values are the same, or the root filenames are the same, then assume these refer to the same file. */ fits_parse_rootname(mfptr->Fptr->filename, mrootname, status); fits_parse_rootname(gfptr->Fptr->filename, grootname, status); if((mfptr->Fptr != gfptr->Fptr) && strncmp(mrootname, grootname, FLEN_FILENAME)) groupExtver = -1*groupExtver; /* retrieve the URLs for the grouping table; note that it is possible that the grouping table file has two URLs, the one used to open it and the "real" one pointing to the actual file being accessed */ *status = fits_get_url(gfptr,grpLocation1,grpLocation2,NULL, NULL,NULL,status); if(*status != 0) continue; /* if either of the group location strings specify a relative file path then convert them into absolute file paths */ *status = fits_get_cwd(cwd,status); if(*grpLocation1 != 0 && *grpLocation1 != '/' && !fits_is_url_absolute(grpLocation1)) { strcpy(grpLocation3,cwd); if (strlen(grpLocation3)+strlen(grpLocation1)+1 > FLEN_FILENAME-1) { ffpmsg("group locations are too long (ffgmrm)"); *status = URL_PARSE_ERROR; continue; } strcat(grpLocation3,"/"); strcat(grpLocation3,grpLocation1); fits_clean_url(grpLocation3,grpLocation1,status); } if(*grpLocation2 != 0 && *grpLocation2 != '/' && !fits_is_url_absolute(grpLocation2)) { strcpy(grpLocation3,cwd); if (strlen(grpLocation3)+strlen(grpLocation2)+1 > FLEN_FILENAME-1) { ffpmsg("group locations are too long (ffgmrm)"); *status = URL_PARSE_ERROR; continue; } strcat(grpLocation3,"/"); strcat(grpLocation3,grpLocation2); fits_clean_url(grpLocation3,grpLocation2,status); } /* determine the number of groups to which the member HDU belongs */ *status = fits_get_num_groups(mfptr,&ngroups,status); /* reset the HDU keyword position counter to the beginning */ *status = ffgrec(mfptr,0,card,status); /* loop over all the GRPIDn keywords in the member HDU header and find the appropriate GRPIDn and GRPLCn keywords that identify it as belonging to the group */ for(index = 1, found = 0; index <= ngroups && *status == 0 && !found; ++index) { /* read the next GRPIDn keyword in the series */ snprintf(keyword,FLEN_KEYWORD,"GRPID%d",index); *status = fits_read_key_lng(mfptr,keyword,&grpid,card, status); if(*status != 0) continue; /* grpid value == group EXTVER value then we could have a match */ if(grpid == groupExtver && grpid > 0) { /* if GRPID is positive then its a match because both the member HDU and grouping table HDU reside in the same FITS file */ found = index; } else if(grpid == groupExtver && grpid < 0) { /* have to look at the GRPLCn value to determine a match because the member HDU and grouping table HDU reside in different FITS files */ snprintf(keyword,FLEN_KEYWORD,"GRPLC%d",index); /* SPR 1738 */ *status = fits_read_key_longstr(mfptr,keyword,&tgrplc, card, status); if (0 == *status) { strcpy(grplc,tgrplc); free(tgrplc); } if(*status == KEY_NO_EXIST) { /* no GRPLCn keyword value found ==> grouping convention not followed; nothing we can do about it, so just continue */ snprintf(card,FLEN_CARD,"No GRPLC%d found for GRPID%d", index,index); ffpmsg(card); *status = 0; continue; } else if (*status != 0) continue; /* construct the URL for the GRPLCn value */ prepare_keyvalue(grplc); /* if the grplc value specifies a relative path then turn it into a absolute file path for comparison purposes */ if(*grplc != 0 && !fits_is_url_absolute(grplc) && *grplc != '/') { /* No, wrong, strcpy(grpLocation3,cwd); should be */ *status = fits_file_name(mfptr,grpLocation3,status); /* Remove everything after the last / */ if (NULL != (editLocation = strrchr(grpLocation3,'/'))) { *editLocation = '\0'; } if (strlen(grpLocation3)+strlen(grplc)+1 > FLEN_FILENAME-1) { ffpmsg("group locations are too long (ffgmrm)"); *status = URL_PARSE_ERROR; continue; } strcat(grpLocation3,"/"); strcat(grpLocation3,grplc); *status = fits_clean_url(grpLocation3,grplc, status); } /* if the absolute value of GRPIDn is equal to the EXTVER value of the grouping table and (one of the possible two) grouping table file URL matches the GRPLCn keyword value then we hava a match */ if(strcmp(grplc,grpLocation1) == 0 || strcmp(grplc,grpLocation2) == 0) found = index; } } /* if found == 0 (false) after the above search then we assume that it is due to an inpromper updating of the GRPIDn and GRPLCn keywords in the member header ==> nothing to delete in the header. Else delete the GRPLCn and GRPIDn keywords that identify the member HDU with the group HDU and re-enumerate the remaining GRPIDn and GRPLCn keywords */ if(found != 0) { snprintf(keyword,FLEN_KEYWORD,"GRPID%d",found); *status = fits_delete_key(mfptr,keyword,status); snprintf(keyword,FLEN_KEYWORD,"GRPLC%d",found); *status = fits_delete_key(mfptr,keyword,status); *status = 0; /* call fits_get_num_groups() to re-enumerate the GRPIDn */ *status = fits_get_num_groups(mfptr,&ngroups,status); } } /* finally, remove the member entry from the current grouping table pointed to by gfptr */ *status = fits_delete_rows(gfptr,member,1,status); } else { *status = BAD_OPTION; ffpmsg("Invalid value specified for the rmopt parameter (ffgmrm)"); } }while(0); if(mfptr != NULL) { fits_close_file(mfptr,status); } return(*status); } /*--------------------------------------------------------------------------- Grouping Table support functions ---------------------------------------------------------------------------*/ int ffgtgc(fitsfile *gfptr, /* pointer to the grouping table */ int *xtensionCol, /* column ID of the MEMBER_XTENSION column */ int *extnameCol, /* column ID of the MEMBER_NAME column */ int *extverCol, /* column ID of the MEMBER_VERSION column */ int *positionCol, /* column ID of the MEMBER_POSITION column */ int *locationCol, /* column ID of the MEMBER_LOCATION column */ int *uriCol, /* column ID of the MEMBER_URI_TYPE column */ int *grptype, /* group structure type code specifying the grouping table columns that are defined: GT_ID_ALL_URI (0) ==> all columns defined GT_ID_REF (1) ==> reference cols only GT_ID_POS (2) ==> position col only GT_ID_ALL (3) ==> ref & pos cols GT_ID_REF_URI (11) ==> ref & loc cols GT_ID_POS_URI (12) ==> pos & loc cols */ int *status) /* return status code */ /* examine the grouping table pointed to by gfptr and determine the column index ID of each possible grouping column. If a column is not found then an index of 0 is returned. the grptype parameter returns the structure of the grouping table ==> what columns are defined. */ { char keyvalue[FLEN_VALUE]; char comment[FLEN_COMMENT]; if(*status != 0) return(*status); do { /* if the HDU does not have an extname of "GROUPING" then it is not a grouping table */ *status = fits_read_key_str(gfptr,"EXTNAME",keyvalue,comment,status); if(*status == KEY_NO_EXIST) { *status = NOT_GROUP_TABLE; ffpmsg("Specified HDU is not a Grouping Table (ffgtgc)"); } if(*status != 0) continue; prepare_keyvalue(keyvalue); if(fits_strcasecmp(keyvalue,"GROUPING") != 0) { *status = NOT_GROUP_TABLE; continue; } /* search for the MEMBER_XTENSION, MEMBER_NAME, MEMBER_VERSION, MEMBER_POSITION, MEMBER_LOCATION and MEMBER_URI_TYPE columns and determine their column index ID */ *status = fits_get_colnum(gfptr,CASESEN,"MEMBER_XTENSION",xtensionCol, status); if(*status == COL_NOT_FOUND) { *status = 0; *xtensionCol = 0; } if(*status != 0) continue; *status = fits_get_colnum(gfptr,CASESEN,"MEMBER_NAME",extnameCol,status); if(*status == COL_NOT_FOUND) { *status = 0; *extnameCol = 0; } if(*status != 0) continue; *status = fits_get_colnum(gfptr,CASESEN,"MEMBER_VERSION",extverCol, status); if(*status == COL_NOT_FOUND) { *status = 0; *extverCol = 0; } if(*status != 0) continue; *status = fits_get_colnum(gfptr,CASESEN,"MEMBER_POSITION",positionCol, status); if(*status == COL_NOT_FOUND) { *status = 0; *positionCol = 0; } if(*status != 0) continue; *status = fits_get_colnum(gfptr,CASESEN,"MEMBER_LOCATION",locationCol, status); if(*status == COL_NOT_FOUND) { *status = 0; *locationCol = 0; } if(*status != 0) continue; *status = fits_get_colnum(gfptr,CASESEN,"MEMBER_URI_TYPE",uriCol, status); if(*status == COL_NOT_FOUND) { *status = 0; *uriCol = 0; } if(*status != 0) continue; /* determine the type of grouping table structure used by this grouping table and record it in the grptype parameter */ if(*xtensionCol && *extnameCol && *extverCol && *positionCol && *locationCol && *uriCol) *grptype = GT_ID_ALL_URI; else if(*xtensionCol && *extnameCol && *extverCol && *locationCol && *uriCol) *grptype = GT_ID_REF_URI; else if(*xtensionCol && *extnameCol && *extverCol && *positionCol) *grptype = GT_ID_ALL; else if(*xtensionCol && *extnameCol && *extverCol) *grptype = GT_ID_REF; else if(*positionCol && *locationCol && *uriCol) *grptype = GT_ID_POS_URI; else if(*positionCol) *grptype = GT_ID_POS; else *status = NOT_GROUP_TABLE; }while(0); /* if the table contained more than one column with a reserved name then this cannot be considered a vailid grouping table */ if(*status == COL_NOT_UNIQUE) { *status = NOT_GROUP_TABLE; ffpmsg("Specified HDU has multipule Group table cols defined (ffgtgc)"); } return(*status); } /*****************************************************************************/ int ffvcfm(fitsfile *gfptr, int xtensionCol, int extnameCol, int extverCol, int positionCol, int locationCol, int uriCol, int *status) { /* Perform validation on column formats to ensure this matches the grouping format the get functions expect. Particularly want to check widths of string columns. */ int typecode=0; long repeat=0, width=0; if (*status != 0) return (*status); do { if (xtensionCol) { fits_get_coltype(gfptr, xtensionCol, &typecode, &repeat, &width, status); if (*status || typecode != TSTRING || repeat != width || repeat > 8) { if (*status==0) *status=NOT_GROUP_TABLE; ffpmsg("Wrong format for Grouping xtension col. (ffvcfm)"); continue; } } if (extnameCol) { fits_get_coltype(gfptr, extnameCol, &typecode, &repeat, &width, status); if (*status || typecode != TSTRING || repeat != width || repeat > 32) { if (*status==0) *status=NOT_GROUP_TABLE; ffpmsg("Wrong format for Grouping name col. (ffvcfm)"); continue; } } if (extverCol) { fits_get_coltype(gfptr, extverCol, &typecode, &repeat, &width, status); if (*status || typecode != TINT32BIT || repeat > 1) { if (*status==0) *status=NOT_GROUP_TABLE; ffpmsg("Wrong format for Grouping version col. (ffvcfm)"); continue; } } if (positionCol) { fits_get_coltype(gfptr, positionCol, &typecode, &repeat, &width, status); if (*status || typecode != TINT32BIT || repeat > 1) { if (*status==0) *status=NOT_GROUP_TABLE; ffpmsg("Wrong format for Grouping position col. (ffvcfm)"); continue; } } if (locationCol) { fits_get_coltype(gfptr, locationCol, &typecode, &repeat, &width, status); if (*status || typecode != TSTRING || repeat != width || repeat > 256) { if (*status==0) *status=NOT_GROUP_TABLE; ffpmsg("Wrong format for Grouping location col. (ffvcfm)"); continue; } } if (uriCol) { fits_get_coltype(gfptr, uriCol, &typecode, &repeat, &width, status); if (*status || typecode != TSTRING || repeat != width || repeat > 3) { if (*status==0) *status=NOT_GROUP_TABLE; ffpmsg("Wrong format for Grouping URI col. (ffvcfm)"); continue; } } } while (0); return (*status); } /*****************************************************************************/ int ffgtdc(int grouptype, /* code specifying the type of grouping table information: GT_ID_ALL_URI 0 ==> defualt (all columns) GT_ID_REF 1 ==> ID by reference GT_ID_POS 2 ==> ID by position GT_ID_ALL 3 ==> ID by ref. and position GT_ID_REF_URI 11 ==> (1) + URI info GT_ID_POS_URI 12 ==> (2) + URI info */ int xtensioncol, /* does MEMBER_XTENSION already exist? */ int extnamecol, /* does MEMBER_NAME aleady exist? */ int extvercol, /* does MEMBER_VERSION already exist? */ int positioncol, /* does MEMBER_POSITION already exist? */ int locationcol, /* does MEMBER_LOCATION already exist? */ int uricol, /* does MEMBER_URI_TYPE aleardy exist? */ char *ttype[], /* array of grouping table column TTYPE names to define (if *col var false) */ char *tform[], /* array of grouping table column TFORM values to define (if*col variable false) */ int *ncols, /* number of TTYPE and TFORM values returned */ int *status) /* return status code */ /* create the TTYPE and TFORM values for the grouping table according to the value of the grouptype parameter and the values of the *col flags. The resulting TTYPE and TFORM are returned in ttype[] and tform[] respectively. The number of TTYPE and TFORMs returned is given by ncols. Both the TTYPE[] and TTFORM[] arrays must contain enough pre-allocated strings to hold the returned information. */ { int i = 0; char xtension[] = "MEMBER_XTENSION"; char xtenTform[] = "8A"; char name[] = "MEMBER_NAME"; char nameTform[] = "32A"; char version[] = "MEMBER_VERSION"; char verTform[] = "1J"; char position[] = "MEMBER_POSITION"; char posTform[] = "1J"; char URI[] = "MEMBER_URI_TYPE"; char URITform[] = "3A"; char location[] = "MEMBER_LOCATION"; /* SPR 01720, move from 160A to 256A */ char locTform[] = "256A"; if(*status != 0) return(*status); switch(grouptype) { case GT_ID_ALL_URI: if(xtensioncol == 0) { strcpy(ttype[i],xtension); strcpy(tform[i],xtenTform); ++i; } if(extnamecol == 0) { strcpy(ttype[i],name); strcpy(tform[i],nameTform); ++i; } if(extvercol == 0) { strcpy(ttype[i],version); strcpy(tform[i],verTform); ++i; } if(positioncol == 0) { strcpy(ttype[i],position); strcpy(tform[i],posTform); ++i; } if(locationcol == 0) { strcpy(ttype[i],location); strcpy(tform[i],locTform); ++i; } if(uricol == 0) { strcpy(ttype[i],URI); strcpy(tform[i],URITform); ++i; } break; case GT_ID_REF: if(xtensioncol == 0) { strcpy(ttype[i],xtension); strcpy(tform[i],xtenTform); ++i; } if(extnamecol == 0) { strcpy(ttype[i],name); strcpy(tform[i],nameTform); ++i; } if(extvercol == 0) { strcpy(ttype[i],version); strcpy(tform[i],verTform); ++i; } break; case GT_ID_POS: if(positioncol == 0) { strcpy(ttype[i],position); strcpy(tform[i],posTform); ++i; } break; case GT_ID_ALL: if(xtensioncol == 0) { strcpy(ttype[i],xtension); strcpy(tform[i],xtenTform); ++i; } if(extnamecol == 0) { strcpy(ttype[i],name); strcpy(tform[i],nameTform); ++i; } if(extvercol == 0) { strcpy(ttype[i],version); strcpy(tform[i],verTform); ++i; } if(positioncol == 0) { strcpy(ttype[i],position); strcpy(tform[i], posTform); ++i; } break; case GT_ID_REF_URI: if(xtensioncol == 0) { strcpy(ttype[i],xtension); strcpy(tform[i],xtenTform); ++i; } if(extnamecol == 0) { strcpy(ttype[i],name); strcpy(tform[i],nameTform); ++i; } if(extvercol == 0) { strcpy(ttype[i],version); strcpy(tform[i],verTform); ++i; } if(locationcol == 0) { strcpy(ttype[i],location); strcpy(tform[i],locTform); ++i; } if(uricol == 0) { strcpy(ttype[i],URI); strcpy(tform[i],URITform); ++i; } break; case GT_ID_POS_URI: if(positioncol == 0) { strcpy(ttype[i],position); strcpy(tform[i],posTform); ++i; } if(locationcol == 0) { strcpy(ttype[i],location); strcpy(tform[i],locTform); ++i; } if(uricol == 0) { strcpy(ttype[i],URI); strcpy(tform[i],URITform); ++i; } break; default: *status = BAD_OPTION; ffpmsg("Invalid value specified for the grouptype parameter (ffgtdc)"); break; } *ncols = i; return(*status); } /*****************************************************************************/ int ffgmul(fitsfile *mfptr, /* pointer to the grouping table member HDU */ int rmopt, /* 0 ==> leave GRPIDn/GRPLCn keywords, 1 ==> remove GRPIDn/GRPLCn keywords */ int *status) /* return status code */ /* examine all the GRPIDn and GRPLCn keywords in the member HDUs header and remove the member from the grouping tables referenced; This effectively "unlinks" the member from all of its groups. The rmopt specifies if the GRPIDn/GRPLCn keywords are to be removed from the member HDUs header after the unlinking. */ { int memberPosition = 0; int iomode; long index; long ngroups = 0; long memberExtver = 0; long memberID = 0; char mbrLocation1[FLEN_FILENAME]; char mbrLocation2[FLEN_FILENAME]; char memberHDUtype[FLEN_VALUE]; char memberExtname[FLEN_VALUE]; char keyword[FLEN_KEYWORD]; char card[FLEN_CARD]; fitsfile *gfptr = NULL; if(*status != 0) return(*status); do { /* determine location parameters of the member HDU; note that default values are supplied if the expected keywords are not found */ *status = fits_read_key_str(mfptr,"XTENSION",memberHDUtype,card,status); if(*status == KEY_NO_EXIST) { strcpy(memberHDUtype,"PRIMARY"); *status = 0; } prepare_keyvalue(memberHDUtype); *status = fits_read_key_lng(mfptr,"EXTVER",&memberExtver,card,status); if(*status == KEY_NO_EXIST) { memberExtver = 1; *status = 0; } *status = fits_read_key_str(mfptr,"EXTNAME",memberExtname,card,status); if(*status == KEY_NO_EXIST) { memberExtname[0] = 0; *status = 0; } prepare_keyvalue(memberExtname); fits_get_hdu_num(mfptr,&memberPosition); *status = fits_get_url(mfptr,mbrLocation1,mbrLocation2,NULL,NULL, NULL,status); if(*status != 0) continue; /* open each grouping table linked to this HDU and remove the member from the grouping tables */ *status = fits_get_num_groups(mfptr,&ngroups,status); /* loop over each group linked to the member HDU */ for(index = 1; index <= ngroups && *status == 0; ++index) { /* open the (index)th group linked to the member HDU */ *status = fits_open_group(mfptr,index,&gfptr,status); /* if the group could not be opened then just skip it */ if(*status != 0) { *status = 0; snprintf(card,FLEN_CARD,"Cannot open the %dth group table (ffgmul)", (int)index); ffpmsg(card); continue; } /* make sure the grouping table can be modified before proceeding */ fits_file_mode(gfptr,&iomode,status); if(iomode != READWRITE) { snprintf(card,FLEN_CARD,"The %dth group cannot be modified (ffgtam)", (int)index); ffpmsg(card); continue; } /* try to find the member's row within the grouping table; first try using the member HDU file's "real" URL string then try using its originally opened URL string if either string exist */ memberID = 0; if(strlen(mbrLocation1) != 0) { *status = ffgmf(gfptr,memberHDUtype,memberExtname,memberExtver, memberPosition,mbrLocation1,&memberID,status); } if(*status == MEMBER_NOT_FOUND && strlen(mbrLocation2) != 0) { *status = 0; *status = ffgmf(gfptr,memberHDUtype,memberExtname,memberExtver, memberPosition,mbrLocation2,&memberID,status); } /* if the member was found then delete it from the grouping table */ if(*status == 0) *status = fits_delete_rows(gfptr,memberID,1,status); /* continue the loop over all member groups even if an error was generated */ if(*status == MEMBER_NOT_FOUND) { ffpmsg("cannot locate member's entry in group table (ffgmul)"); } *status = 0; /* close the file pointed to by gfptr if it is non NULL to prepare for the next loop iterration */ if(gfptr != NULL) { fits_close_file(gfptr,status); gfptr = NULL; } } if(*status != 0) continue; /* if rmopt is non-zero then find and delete the GRPIDn/GRPLCn keywords from the member HDU header */ if(rmopt != 0) { fits_file_mode(mfptr,&iomode,status); if(iomode == READONLY) { ffpmsg("Cannot modify member HDU, opened READONLY (ffgmul)"); continue; } /* delete all the GRPIDn/GRPLCn keywords */ for(index = 1; index <= ngroups && *status == 0; ++index) { snprintf(keyword,FLEN_KEYWORD,"GRPID%d",(int)index); fits_delete_key(mfptr,keyword,status); snprintf(keyword,FLEN_KEYWORD,"GRPLC%d",(int)index); fits_delete_key(mfptr,keyword,status); if(*status == KEY_NO_EXIST) *status = 0; } } }while(0); /* make sure the gfptr has been closed */ if(gfptr != NULL) { fits_close_file(gfptr,status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgmf(fitsfile *gfptr, /* pointer to grouping table HDU to search */ char *xtension, /* XTENSION value for member HDU */ char *extname, /* EXTNAME value for member HDU */ int extver, /* EXTVER value for member HDU */ int position, /* HDU position value for member HDU */ char *location, /* FITS file location value for member HDU */ long *member, /* member HDU ID within group table (if found) */ int *status) /* return status code */ /* try to find the entry for the member HDU defined by the xtension, extname, extver, position, and location parameters within the grouping table pointed to by gfptr. If the member HDU is found then its ID (row number) within the grouping table is returned in the member variable; if not found then member is returned with a value of 0 and the status return code will be set to MEMBER_NOT_FOUND. Note that the member HDU postion information is used to obtain a member match only if the grouping table type is GT_ID_POS_URI or GT_ID_POS. This is because the position information can become invalid much more easily then the reference information for a group member. */ { int xtensionCol,extnameCol,extverCol,positionCol,locationCol,uriCol; int mposition = 0; int grptype; int dummy; int i; long nmembers = 0; long mextver = 0; char charBuff1[FLEN_FILENAME]; char charBuff2[FLEN_FILENAME]; char tmpLocation[FLEN_FILENAME]; char mbrLocation1[FLEN_FILENAME]; char mbrLocation2[FLEN_FILENAME]; char mbrLocation3[FLEN_FILENAME]; char grpLocation1[FLEN_FILENAME]; char grpLocation2[FLEN_FILENAME]; char cwd[FLEN_FILENAME]; char nstr[] = {'\0'}; char *tmpPtr[2]; if(*status != 0) return(*status); *member = 0; tmpPtr[0] = charBuff1; tmpPtr[1] = charBuff2; if(*status != 0) return(*status); /* if the passed LOCATION value is not an absolute URL then turn it into an absolute path */ if(location == NULL) { *tmpLocation = 0; } else if(*location == 0) { *tmpLocation = 0; } else if(!fits_is_url_absolute(location)) { fits_path2url(location,FLEN_FILENAME,tmpLocation,status); if(*tmpLocation != '/') { fits_get_cwd(cwd,status); if (strlen(cwd)+strlen(tmpLocation)+1 > FLEN_FILENAME-1) { ffpmsg("cwd and location are too long (ffgmf)"); return (*status = URL_PARSE_ERROR); } strcat(cwd,"/"); strcat(cwd,tmpLocation); fits_clean_url(cwd,tmpLocation,status); } } else strcpy(tmpLocation,location); /* retrieve the Grouping Convention reserved column positions within the grouping table */ *status = ffgtgc(gfptr,&xtensionCol,&extnameCol,&extverCol,&positionCol, &locationCol,&uriCol,&grptype,status); /* retrieve the number of group members */ *status = fits_get_num_members(gfptr,&nmembers,status); /* loop over all grouping table rows until the member HDU is found */ for(i = 1; i <= nmembers && *member == 0 && *status == 0; ++i) { if(xtensionCol != 0) { fits_read_col_str(gfptr,xtensionCol,i,1,1,nstr,tmpPtr,&dummy,status); if(fits_strcasecmp(tmpPtr[0],xtension) != 0) continue; } if(extnameCol != 0) { fits_read_col_str(gfptr,extnameCol,i,1,1,nstr,tmpPtr,&dummy,status); if(fits_strcasecmp(tmpPtr[0],extname) != 0) continue; } if(extverCol != 0) { fits_read_col_lng(gfptr,extverCol,i,1,1,0, (long*)&mextver,&dummy,status); if(extver != mextver) continue; } /* note we only use postionCol if we have to */ if(positionCol != 0 && (grptype == GT_ID_POS || grptype == GT_ID_POS_URI)) { fits_read_col_int(gfptr,positionCol,i,1,1,0, &mposition,&dummy,status); if(position != mposition) continue; } /* if no location string was passed to the function then assume that the calling application does not wish to use it as a comparision critera ==> if we got this far then we have a match */ if(location == NULL) { ffpmsg("NULL Location string given ==> ignore location (ffgmf)"); *member = i; continue; } /* if the grouping table MEMBER_LOCATION column exists then read the location URL for the member, else set the location string to a zero-length string for subsequent comparisions */ if(locationCol != 0) { fits_read_col_str(gfptr,locationCol,i,1,1,nstr,tmpPtr,&dummy,status); strcpy(mbrLocation1,tmpPtr[0]); *mbrLocation2 = 0; } else *mbrLocation1 = 0; /* if the member location string from the grouping table is zero length (either implicitly or explicitly) then assume that the member HDU is in the same file as the grouping table HDU; retrieve the possible URL values of the grouping table HDU file */ if(*mbrLocation1 == 0) { /* retrieve the possible URLs of the grouping table file */ *status = fits_get_url(gfptr,mbrLocation1,mbrLocation2,NULL,NULL, NULL,status); /* if non-NULL, make sure the first URL is absolute or a full path */ if(*mbrLocation1 != 0 && !fits_is_url_absolute(mbrLocation1) && *mbrLocation1 != '/') { fits_get_cwd(cwd,status); if (strlen(cwd)+strlen(mbrLocation1)+1 > FLEN_FILENAME-1) { ffpmsg("cwd and member locations are too long (ffgmf)"); *status = URL_PARSE_ERROR; continue; } strcat(cwd,"/"); strcat(cwd,mbrLocation1); fits_clean_url(cwd,mbrLocation1,status); } /* if non-NULL, make sure the first URL is absolute or a full path */ if(*mbrLocation2 != 0 && !fits_is_url_absolute(mbrLocation2) && *mbrLocation2 != '/') { fits_get_cwd(cwd,status); if (strlen(cwd)+strlen(mbrLocation2)+1 > FLEN_FILENAME-1) { ffpmsg("cwd and member locations are too long (ffgmf)"); *status = URL_PARSE_ERROR; continue; } strcat(cwd,"/"); strcat(cwd,mbrLocation2); fits_clean_url(cwd,mbrLocation2,status); } } /* if the member location was specified, then make sure that it is either an absolute URL or specifies a full path */ else if(!fits_is_url_absolute(mbrLocation1) && *mbrLocation1 != '/') { strcpy(mbrLocation2,mbrLocation1); /* get the possible URLs for the grouping table file */ *status = fits_get_url(gfptr,grpLocation1,grpLocation2,NULL,NULL, NULL,status); if(*grpLocation1 != 0) { /* make sure the first grouping table URL is absolute */ if(!fits_is_url_absolute(grpLocation1) && *grpLocation1 != '/') { fits_get_cwd(cwd,status); if (strlen(cwd)+strlen(grpLocation1)+1 > FLEN_FILENAME-1) { ffpmsg("cwd and group locations are too long (ffgmf)"); *status = URL_PARSE_ERROR; continue; } strcat(cwd,"/"); strcat(cwd,grpLocation1); fits_clean_url(cwd,grpLocation1,status); } /* create an absoute URL for the member */ fits_relurl2url(grpLocation1,mbrLocation1,mbrLocation3,status); /* if URL construction succeeded then copy it to the first location string; else set the location string to empty */ if(*status == 0) { strcpy(mbrLocation1,mbrLocation3); } else if(*status == URL_PARSE_ERROR) { *status = 0; *mbrLocation1 = 0; } } else *mbrLocation1 = 0; if(*grpLocation2 != 0) { /* make sure the second grouping table URL is absolute */ if(!fits_is_url_absolute(grpLocation2) && *grpLocation2 != '/') { fits_get_cwd(cwd,status); if (strlen(cwd)+strlen(grpLocation2)+1 > FLEN_FILENAME-1) { ffpmsg("cwd and group locations are too long (ffgmf)"); *status = URL_PARSE_ERROR; continue; } strcat(cwd,"/"); strcat(cwd,grpLocation2); fits_clean_url(cwd,grpLocation2,status); } /* create an absolute URL for the member */ fits_relurl2url(grpLocation2,mbrLocation2,mbrLocation3,status); /* if URL construction succeeded then copy it to the second location string; else set the location string to empty */ if(*status == 0) { strcpy(mbrLocation2,mbrLocation3); } else if(*status == URL_PARSE_ERROR) { *status = 0; *mbrLocation2 = 0; } } else *mbrLocation2 = 0; } /* compare the passed member HDU file location string with the (possibly two) member location strings to see if there is a match */ if(strcmp(mbrLocation1,tmpLocation) != 0 && strcmp(mbrLocation2,tmpLocation) != 0 ) continue; /* if we made it this far then a match to the member HDU was found */ *member = i; } /* if a match was not found then set the return status code */ if(*member == 0 && *status == 0) { *status = MEMBER_NOT_FOUND; ffpmsg("Cannot find specified member HDU (ffgmf)"); } return(*status); } /*-------------------------------------------------------------------------- Recursive Group Functions --------------------------------------------------------------------------*/ int ffgtrmr(fitsfile *gfptr, /* FITS file pointer to group */ HDUtracker *HDU, /* list of processed HDUs */ int *status) /* return status code */ /* recursively remove a grouping table and all its members. Each member of the grouping table pointed to by gfptr it processed. If the member is itself a grouping table then ffgtrmr() is recursively called to process all of its members. The HDUtracker struct *HDU is used to make sure a member is not processed twice, thus avoiding an infinite loop (e.g., a grouping table contains itself as a member). */ { int i; int hdutype; long nmembers = 0; char keyvalue[FLEN_VALUE]; char comment[FLEN_COMMENT]; fitsfile *mfptr = NULL; if(*status != 0) return(*status); /* get the number of members contained by this grouping table */ *status = fits_get_num_members(gfptr,&nmembers,status); /* loop over all group members and delete them */ for(i = nmembers; i > 0 && *status == 0; --i) { /* open the member HDU */ *status = fits_open_member(gfptr,i,&mfptr,status); /* if the member cannot be opened then just skip it and continue */ if(*status == MEMBER_NOT_FOUND) { *status = 0; continue; } /* Any other error is a reason to abort */ if(*status != 0) continue; /* add the member HDU to the HDUtracker struct */ *status = fftsad(mfptr,HDU,NULL,NULL); /* status == HDU_ALREADY_TRACKED ==> HDU has already been processed */ if(*status == HDU_ALREADY_TRACKED) { *status = 0; fits_close_file(mfptr,status); continue; } else if(*status != 0) continue; /* determine if the member HDU is itself a grouping table */ *status = fits_read_key_str(mfptr,"EXTNAME",keyvalue,comment,status); /* if no EXTNAME is found then the HDU cannot be a grouping table */ if(*status == KEY_NO_EXIST) { *status = 0; keyvalue[0] = 0; } prepare_keyvalue(keyvalue); /* Any other error is a reason to abort */ if(*status != 0) continue; /* if the EXTNAME == GROUPING then the member is a grouping table and we must call ffgtrmr() to process its members */ if(fits_strcasecmp(keyvalue,"GROUPING") == 0) *status = ffgtrmr(mfptr,HDU,status); /* unlink all the grouping tables that contain this HDU as a member and then delete the HDU (if not a PHDU) */ if(fits_get_hdu_num(mfptr,&hdutype) == 1) *status = ffgmul(mfptr,1,status); else { *status = ffgmul(mfptr,0,status); *status = fits_delete_hdu(mfptr,&hdutype,status); } /* close the fitsfile pointer */ fits_close_file(mfptr,status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgtcpr(fitsfile *infptr, /* input FITS file pointer */ fitsfile *outfptr, /* output FITS file pointer */ int cpopt, /* code specifying copy options: OPT_GCP_GPT (0) ==> cp only grouping table OPT_GCP_ALL (2) ==> recusrively copy members and their members (if groups) */ HDUtracker *HDU, /* list of already copied HDUs */ int *status) /* return status code */ /* copy a Group to a new FITS file. If the cpopt parameter is set to OPT_GCP_GPT (copy grouping table only) then the existing members have their GRPIDn and GRPLCn keywords updated to reflect the existance of the new group, since they now belong to another group. If cpopt is set to OPT_GCP_ALL (copy grouping table and members recursively) then the original members are not updated; the new grouping table is modified to include only the copied member HDUs and not the original members. Note that this function is recursive. When copt is OPT_GCP_ALL it will call itself whenever a member HDU of the current grouping table is itself a grouping table (i.e., EXTNAME = 'GROUPING'). */ { int i; int nexclude = 8; int hdutype = 0; int groupHDUnum = 0; int numkeys = 0; int keypos = 0; int startSearch = 0; int newPosition = 0; long nmembers = 0; long tfields = 0; long newTfields = 0; char keyword[FLEN_KEYWORD]; char keyvalue[FLEN_VALUE]; char card[FLEN_CARD]; char comment[FLEN_CARD]; char *tkeyvalue; char *includeList[] = {"*"}; char *excludeList[] = {"EXTNAME","EXTVER","GRPNAME","GRPID#","GRPLC#", "THEAP","TDIM#","T????#"}; fitsfile *mfptr = NULL; if(*status != 0) return(*status); do { /* create a new grouping table in the FITS file pointed to by outptr */ *status = fits_get_num_members(infptr,&nmembers,status); *status = fits_read_key_str(infptr,"GRPNAME",keyvalue,card,status); if(*status == KEY_NO_EXIST) { keyvalue[0] = 0; *status = 0; } prepare_keyvalue(keyvalue); *status = fits_create_group(outfptr,keyvalue,GT_ID_ALL_URI,status); /* save the new grouping table's HDU position for future use */ fits_get_hdu_num(outfptr,&groupHDUnum); /* update the HDUtracker struct with the grouping table's new position */ *status = fftsud(infptr,HDU,groupHDUnum,NULL); /* Now populate the copied grouping table depending upon the copy option parameter value */ switch(cpopt) { /* for the "copy grouping table only" option we only have to add the members of the original grouping table to the new grouping table */ case OPT_GCP_GPT: for(i = 1; i <= nmembers && *status == 0; ++i) { *status = fits_open_member(infptr,i,&mfptr,status); *status = fits_add_group_member(outfptr,mfptr,0,status); fits_close_file(mfptr,status); mfptr = NULL; } break; case OPT_GCP_ALL: /* for the "copy the entire group" option */ /* loop over all the grouping table members */ for(i = 1; i <= nmembers && *status == 0; ++i) { /* open the ith member */ *status = fits_open_member(infptr,i,&mfptr,status); if(*status != 0) continue; /* add it to the HDUtracker struct */ *status = fftsad(mfptr,HDU,&newPosition,NULL); /* if already copied then just add the member to the group */ if(*status == HDU_ALREADY_TRACKED) { *status = 0; *status = fits_add_group_member(outfptr,NULL,newPosition, status); fits_close_file(mfptr,status); mfptr = NULL; continue; } else if(*status != 0) continue; /* see if the member is a grouping table */ *status = fits_read_key_str(mfptr,"EXTNAME",keyvalue,card, status); if(*status == KEY_NO_EXIST) { keyvalue[0] = 0; *status = 0; } prepare_keyvalue(keyvalue); /* if the member is a grouping table then copy it and all of its members using ffgtcpr(), else copy it using fits_copy_member(); the outptr will point to the newly copied member upon return from both functions */ if(fits_strcasecmp(keyvalue,"GROUPING") == 0) *status = ffgtcpr(mfptr,outfptr,OPT_GCP_ALL,HDU,status); else *status = fits_copy_member(infptr,outfptr,i,OPT_MCP_NADD, status); /* retrieve the position of the newly copied member */ fits_get_hdu_num(outfptr,&newPosition); /* update the HDUtracker struct with member's new position */ if(fits_strcasecmp(keyvalue,"GROUPING") != 0) *status = fftsud(mfptr,HDU,newPosition,NULL); /* move the outfptr back to the copied grouping table HDU */ *status = fits_movabs_hdu(outfptr,groupHDUnum,&hdutype,status); /* add the copied member HDU to the copied grouping table */ *status = fits_add_group_member(outfptr,NULL,newPosition,status); /* close the mfptr pointer */ fits_close_file(mfptr,status); mfptr = NULL; } break; default: *status = BAD_OPTION; ffpmsg("Invalid value specified for cmopt parameter (ffgtcpr)"); break; } if(*status != 0) continue; /* reposition the outfptr to the grouping table so that the grouping table is the CHDU upon return to the calling function */ fits_movabs_hdu(outfptr,groupHDUnum,&hdutype,status); /* copy all auxiliary keyword records from the original grouping table to the new grouping table; they are copied in their original order and inserted just before the TTYPE1 keyword record */ *status = fits_read_card(outfptr,"TTYPE1",card,status); *status = fits_get_hdrpos(outfptr,&numkeys,&keypos,status); --keypos; startSearch = 8; while(*status == 0) { ffgrec(infptr,startSearch,card,status); *status = fits_find_nextkey(infptr,includeList,1,excludeList, nexclude,card,status); *status = fits_get_hdrpos(infptr,&numkeys,&startSearch,status); --startSearch; /* SPR 1738 */ if (strncmp(card,"GRPLC",5)) { /* Not going to be a long string so we're ok */ *status = fits_insert_record(outfptr,keypos,card,status); } else { /* We could have a long string */ *status = fits_read_record(infptr,startSearch,card,status); card[9] = '\0'; *status = fits_read_key_longstr(infptr,card,&tkeyvalue,comment, status); if (0 == *status) { fits_insert_key_longstr(outfptr,card,tkeyvalue,comment,status); fits_write_key_longwarn(outfptr,status); free(tkeyvalue); } } ++keypos; } if(*status == KEY_NO_EXIST) *status = 0; else if(*status != 0) continue; /* search all the columns of the original grouping table and copy those to the new grouping table that were not part of the grouping convention. Note that is legal to have additional columns in a grouping table. Also note that the order of the columns may not be the same in the original and copied grouping table. */ /* retrieve the number of columns in the original and new group tables */ *status = fits_read_key_lng(infptr,"TFIELDS",&tfields,card,status); *status = fits_read_key_lng(outfptr,"TFIELDS",&newTfields,card,status); for(i = 1; i <= tfields; ++i) { snprintf(keyword,FLEN_KEYWORD,"TTYPE%d",i); *status = fits_read_key_str(infptr,keyword,keyvalue,card,status); if(*status == KEY_NO_EXIST) { *status = 0; keyvalue[0] = 0; } prepare_keyvalue(keyvalue); if(fits_strcasecmp(keyvalue,"MEMBER_XTENSION") != 0 && fits_strcasecmp(keyvalue,"MEMBER_NAME") != 0 && fits_strcasecmp(keyvalue,"MEMBER_VERSION") != 0 && fits_strcasecmp(keyvalue,"MEMBER_POSITION") != 0 && fits_strcasecmp(keyvalue,"MEMBER_LOCATION") != 0 && fits_strcasecmp(keyvalue,"MEMBER_URI_TYPE") != 0 ) { /* SPR 3956, add at the end of the table */ *status = fits_copy_col(infptr,outfptr,i,newTfields+1,1,status); ++newTfields; } } }while(0); if(mfptr != NULL) { fits_close_file(mfptr,status); } return(*status); } /*-------------------------------------------------------------------------- HDUtracker struct manipulation functions --------------------------------------------------------------------------*/ int fftsad(fitsfile *mfptr, /* pointer to an member HDU */ HDUtracker *HDU, /* pointer to an HDU tracker struct */ int *newPosition, /* new HDU position of the member HDU */ char *newFileName) /* file containing member HDU */ /* add an HDU to the HDUtracker struct pointed to by HDU. The HDU is only added if it does not already reside in the HDUtracker. If it already resides in the HDUtracker then the new HDU postion and file name are returned in newPosition and newFileName (if != NULL) */ { int i; int hdunum; int status = 0; char filename1[FLEN_FILENAME]; char filename2[FLEN_FILENAME]; do { /* retrieve the HDU's position within the FITS file */ fits_get_hdu_num(mfptr,&hdunum); /* retrieve the HDU's file name */ status = fits_file_name(mfptr,filename1,&status); /* parse the file name and construct the "standard" URL for it */ status = ffrtnm(filename1,filename2,&status); /* examine all the existing HDUs in the HDUtracker an see if this HDU has already been registered */ for(i = 0; i < HDU->nHDU && !(HDU->position[i] == hdunum && strcmp(HDU->filename[i],filename2) == 0); ++i); if(i != HDU->nHDU) { status = HDU_ALREADY_TRACKED; if(newPosition != NULL) *newPosition = HDU->newPosition[i]; if(newFileName != NULL) strcpy(newFileName,HDU->newFilename[i]); continue; } if(HDU->nHDU == MAX_HDU_TRACKER) { status = TOO_MANY_HDUS_TRACKED; continue; } HDU->filename[i] = (char*) malloc(FLEN_FILENAME * sizeof(char)); if(HDU->filename[i] == NULL) { status = MEMORY_ALLOCATION; continue; } HDU->newFilename[i] = (char*) malloc(FLEN_FILENAME * sizeof(char)); if(HDU->newFilename[i] == NULL) { status = MEMORY_ALLOCATION; free(HDU->filename[i]); continue; } HDU->position[i] = hdunum; HDU->newPosition[i] = hdunum; strcpy(HDU->filename[i],filename2); strcpy(HDU->newFilename[i],filename2); ++(HDU->nHDU); }while(0); return(status); } /*--------------------------------------------------------------------------*/ int fftsud(fitsfile *mfptr, /* pointer to an member HDU */ HDUtracker *HDU, /* pointer to an HDU tracker struct */ int newPosition, /* new HDU position of the member HDU */ char *newFileName) /* file containing member HDU */ /* update the HDU information in the HDUtracker struct pointed to by HDU. The HDU to update is pointed to by mfptr. If non-zero, the value of newPosition is used to update the HDU->newPosition[] value for the mfptr, and if non-NULL the newFileName value is used to update the HDU->newFilename[] value for mfptr. */ { int i; int hdunum; int status = 0; char filename1[FLEN_FILENAME]; char filename2[FLEN_FILENAME]; /* retrieve the HDU's position within the FITS file */ fits_get_hdu_num(mfptr,&hdunum); /* retrieve the HDU's file name */ status = fits_file_name(mfptr,filename1,&status); /* parse the file name and construct the "standard" URL for it */ status = ffrtnm(filename1,filename2,&status); /* examine all the existing HDUs in the HDUtracker an see if this HDU has already been registered */ for(i = 0; i < HDU->nHDU && !(HDU->position[i] == hdunum && strcmp(HDU->filename[i],filename2) == 0); ++i); /* if previously registered then change newPosition and newFileName */ if(i != HDU->nHDU) { if(newPosition != 0) HDU->newPosition[i] = newPosition; if(newFileName != NULL) { strcpy(HDU->newFilename[i],newFileName); } } else status = MEMBER_NOT_FOUND; return(status); } /*---------------------------------------------------------------------------*/ void prepare_keyvalue(char *keyvalue) /* string containing keyword value */ /* strip off all single quote characters "'" and blank spaces from a keyword value retrieved via fits_read_key*() routines this is necessary so that a standard comparision of keyword values may be made */ { int i; int length; /* strip off any leading or trailing single quotes (`) and (') from the keyword value */ length = strlen(keyvalue) - 1; if(keyvalue[0] == '\'' && keyvalue[length] == '\'') { for(i = 0; i < length - 1; ++i) keyvalue[i] = keyvalue[i+1]; keyvalue[length-1] = 0; } /* strip off any trailing blanks from the keyword value; note that if the keyvalue consists of nothing but blanks then no blanks are stripped */ length = strlen(keyvalue) - 1; for(i = 0; i < length && keyvalue[i] == ' '; ++i); if(i != length) { for(i = length; i >= 0 && keyvalue[i] == ' '; --i) keyvalue[i] = '\0'; } } /*--------------------------------------------------------------------------- Host dependent directory path to/from URL functions --------------------------------------------------------------------------*/ int fits_path2url(char *inpath, /* input file path string */ int maxlength, /* I max number of chars that can be written to output, including terminating NULL */ char *outpath, /* output file path string */ int *status) /* convert a file path into its Unix-style equivelent for URL purposes. Note that this process is platform dependent. This function supports Unix, MSDOS/WIN32, VMS and Macintosh platforms. The plaform dependant code is conditionally compiled depending upon the setting of the appropriate C preprocessor macros. */ { char buff[FLEN_FILENAME]; #if defined(WINNT) || defined(__WINNT__) /* Microsoft Windows NT case. We assume input file paths of the form: //disk/path/filename All path segments may be null, so that a single file name is the simplist case. The leading "//" becomes a single "/" if present. If no "//" is present, then make sure the resulting URL path is relative, i.e., does not begin with a "/". In other words, the only way that an absolute URL file path may be generated is if the drive specification is given. */ if(*status > 0) return(*status); if(inpath[0] == '/') { strcpy(buff,inpath+1); } else { strcpy(buff,inpath); } #elif defined(MSDOS) || defined(__WIN32__) || defined(WIN32) /* MSDOS or Microsoft windows/NT case. The assumed form of the input path is: disk:\path\filename All path segments may be null, so that a single file name is the simplist case. All back-slashes '\' become slashes '/'; if the path starts with a string of the form "X:" then it is replaced with "/X/" */ int i,j,k; int size; if(*status > 0) return(*status); for(i = 0, j = 0, size = strlen(inpath), buff[0] = 0; i < size; j = strlen(buff)) { switch(inpath[i]) { case ':': /* must be a disk desiginator; add a slash '/' at the start of outpath to designate that the path is absolute, then change the colon ':' to a slash '/' */ for(k = j; k >= 0; --k) buff[k+1] = buff[k]; buff[0] = '/'; strcat(buff,"/"); ++i; break; case '\\': /* just replace the '\' with a '/' IF its not the first character */ if(i != 0 && buff[(j == 0 ? 0 : j-1)] != '/') { buff[j] = '/'; buff[j+1] = 0; } ++i; break; default: /* copy the character from inpath to buff as is */ buff[j] = inpath[i]; buff[j+1] = 0; ++i; break; } } #elif defined(VMS) || defined(vms) || defined(__vms) /* VMS case. Assumed format of the input path is: node::disk:[path]filename.ext;version Any part of the file path may be missing, so that in the simplist case a single file name/extension is given. all brackets "[", "]" and dots "." become "/"; dashes "-" become "..", all single colons ":" become ":/", all double colons "::" become "FILE://" */ int i,j,k; int done; int size; if(*status > 0) return(*status); /* see if inpath contains a directory specification */ if(strchr(inpath,']') == NULL) done = 1; else done = 0; for(i = 0, j = 0, size = strlen(inpath), buff[0] = 0; i < size && j < FLEN_FILENAME - 8; j = strlen(buff)) { switch(inpath[i]) { case ':': /* must be a logical/symbol separator or (in the case of a double colon "::") machine node separator */ if(inpath[i+1] == ':') { /* insert a "FILE://" at the start of buff ==> machine given */ for(k = j; k >= 0; --k) buff[k+7] = buff[k]; strncpy(buff,"FILE://",7); i += 2; } else if(strstr(buff,"FILE://") == NULL) { /* insert a "/" at the start of buff ==> absolute path */ for(k = j; k >= 0; --k) buff[k+1] = buff[k]; buff[0] = '/'; ++i; } else ++i; /* a colon always ==> path separator */ strcat(buff,"/"); break; case ']': /* end of directory spec, file name spec begins after this */ done = 1; buff[j] = '/'; buff[j+1] = 0; ++i; break; case '[': /* begin directory specification; add a '/' only if the last char is not '/' */ if(i != 0 && buff[(j == 0 ? 0 : j-1)] != '/') { buff[j] = '/'; buff[j+1] = 0; } ++i; break; case '.': /* directory segment separator or file name/extension separator; we decide which by looking at the value of done */ if(!done) { /* must be a directory segment separator */ if(inpath[i-1] == '[') { strcat(buff,"./"); ++j; } else buff[j] = '/'; } else /* must be a filename/extension separator */ buff[j] = '.'; buff[j+1] = 0; ++i; break; case '-': /* a dash is the same as ".." in Unix speak, but lets make sure that its not part of the file name first! */ if(!done) /* must be part of the directory path specification */ strcat(buff,".."); else { /* the dash is part of the filename, so just copy it as is */ buff[j] = '-'; buff[j+1] = 0; } ++i; break; default: /* nothing special, just copy the character as is */ buff[j] = inpath[i]; buff[j+1] = 0; ++i; break; } } if(j > FLEN_FILENAME - 8) { *status = URL_PARSE_ERROR; ffpmsg("resulting path to URL conversion too big (fits_path2url)"); } #elif defined(macintosh) /* MacOS case. The assumed form of the input path is: disk:path:filename It is assumed that all paths are absolute with disk and path specified, unless no colons ":" are supplied with the string ==> a single file name only. All colons ":" become slashes "/", and if one or more colon is encountered then the path is specified as absolute. */ int i,j,k; int firstColon; int size; if(*status > 0) return(*status); for(i = 0, j = 0, firstColon = 1, size = strlen(inpath), buff[0] = 0; i < size; j = strlen(buff)) { switch(inpath[i]) { case ':': /* colons imply path separators. If its the first colon encountered then assume that its the disk designator and add a slash to the beginning of the buff string */ if(firstColon) { firstColon = 0; for(k = j; k >= 0; --k) buff[k+1] = buff[k]; buff[0] = '/'; } /* all colons become slashes */ strcat(buff,"/"); ++i; break; default: /* copy the character from inpath to buff as is */ buff[j] = inpath[i]; buff[j+1] = 0; ++i; break; } } #else /* Default Unix case. Nothing special to do here except to remove the double or more // and replace them with single / */ int ii = 0; int jj = 0; if(*status > 0) return(*status); while (inpath[ii]) { if (inpath[ii] == '/' && inpath[ii+1] == '/') { /* do nothing */ } else { buff[jj] = inpath[ii]; jj++; } ii++; } buff[jj] = '\0'; /* printf("buff is %s\ninpath is %s\n",buff,inpath); */ /* strcpy(buff,inpath); */ #endif /* encode all "unsafe" and "reserved" URL characters */ *status = fits_encode_url(buff,maxlength,outpath,status); return(*status); } /*---------------------------------------------------------------------------*/ int fits_url2path(char *inpath, /* input file path string */ char *outpath, /* output file path string */ int *status) /* convert a Unix-style URL into a platform dependent directory path. Note that this process is platform dependent. This function supports Unix, MSDOS/WIN32, VMS and Macintosh platforms. Each platform dependent code segment is conditionally compiled depending upon the setting of the appropriate C preprocesser macros. */ { char buff[FLEN_FILENAME]; int absolute; #if defined(MSDOS) || defined(__WIN32__) || defined(WIN32) char *tmpStr, *saveptr; #elif defined(VMS) || defined(vms) || defined(__vms) int i; char *tmpStr, *saveptr; #elif defined(macintosh) char *tmpStr, *saveptr; #endif if(*status != 0) return(*status); /* make a copy of the inpath so that we can manipulate it */ strcpy(buff,inpath); /* convert any encoded characters to their unencoded values */ *status = fits_unencode_url(inpath,buff,status); /* see if the URL is given as absolute w.r.t. the "local" file system */ if(buff[0] == '/') absolute = 1; else absolute = 0; #if defined(WINNT) || defined(__WINNT__) /* Microsoft Windows NT case. We create output paths of the form //disk/path/filename All path segments but the last may be null, so that a single file name is the simplist case. */ if(absolute) { strcpy(outpath,"/"); strcat(outpath,buff); } else { strcpy(outpath,buff); } #elif defined(MSDOS) || defined(__WIN32__) || defined(WIN32) /* MSDOS or Microsoft windows/NT case. The output path will be of the form disk:\path\filename All path segments but the last may be null, so that a single file name is the simplist case. */ /* separate the URL into tokens at each slash '/' and process until all tokens have been examined */ for(tmpStr = ffstrtok(buff,"/",&saveptr), outpath[0] = 0; tmpStr != NULL; tmpStr = ffstrtok(NULL,"/",&saveptr)) { strcat(outpath,tmpStr); /* if the absolute flag is set then process the token as a disk specification; else just process it as a directory path or filename */ if(absolute) { strcat(outpath,":\\"); absolute = 0; } else strcat(outpath,"\\"); } /* remove the last "\" from the outpath, it does not belong there */ outpath[strlen(outpath)-1] = 0; #elif defined(VMS) || defined(vms) || defined(__vms) /* VMS case. The output path will be of the form: node::disk:[path]filename.ext;version Any part of the file path may be missing execpt filename.ext, so that in the simplist case a single file name/extension is given. if the path is specified as relative starting with "./" then the first part of the VMS path is "[.". If the path is relative and does not start with "./" (e.g., "a/b/c") then the VMS path is constructed as "[a.b.c]" */ /* separate the URL into tokens at each slash '/' and process until all tokens have been examined */ for(tmpStr = ffstrtok(buff,"/",&saveptr), outpath[0] = 0; tmpStr != NULL; tmpStr = ffstrtok(NULL,"/",&saveptr)) { if(fits_strcasecmp(tmpStr,"FILE:") == 0) { /* the next token should contain the DECnet machine name */ tmpStr = ffstrtok(NULL,"/",&saveptr); if(tmpStr == NULL) continue; strcat(outpath,tmpStr); strcat(outpath,"::"); /* set the absolute flag to true for the next token */ absolute = 1; } else if(strcmp(tmpStr,"..") == 0) { /* replace all Unix-like ".." with VMS "-" */ if(strlen(outpath) == 0) strcat(outpath,"["); strcat(outpath,"-."); } else if(strcmp(tmpStr,".") == 0 && strlen(outpath) == 0) { /* must indicate a relative path specifier */ strcat(outpath,"[."); } else if(strchr(tmpStr,'.') != NULL) { /* must be up to the file name; turn the last "." path separator into a "]" and then add the file name to the outpath */ i = strlen(outpath); if(i > 0 && outpath[i-1] == '.') outpath[i-1] = ']'; strcat(outpath,tmpStr); } else { /* process the token as a a directory path segement */ if(absolute) { /* treat the token as a disk specifier */ absolute = 0; strcat(outpath,tmpStr); strcat(outpath,":["); } else if(strlen(outpath) == 0) { /* treat the token as the first directory path specifier */ strcat(outpath,"["); strcat(outpath,tmpStr); strcat(outpath,"."); } else { /* treat the token as an imtermediate path specifier */ strcat(outpath,tmpStr); strcat(outpath,"."); } } } #elif defined(macintosh) /* MacOS case. The output path will be of the form disk:path:filename All path segments but the last may be null, so that a single file name is the simplist case. */ /* separate the URL into tokens at each slash '/' and process until all tokens have been examined */ for(tmpStr = ffstrtok(buff,"/",&saveptr), outpath[0] = 0; tmpStr != NULL; tmpStr = ffstrtok(NULL,"/",&saveptr)) { strcat(outpath,tmpStr); strcat(outpath,":"); } /* remove the last ":" from the outpath, it does not belong there */ outpath[strlen(outpath)-1] = 0; #else /* Default Unix case. Nothing special to do here */ strcpy(outpath,buff); #endif return(*status); } /****************************************************************************/ int fits_get_cwd(char *cwd, /* IO current working directory string */ int *status) /* retrieve the string containing the current working directory absolute path in Unix-like URL standard notation. It is assumed that the CWD string has a size of at least FLEN_FILENAME. Note that this process is platform dependent. This function supports Unix, MSDOS/WIN32, VMS and Macintosh platforms. Each platform dependent code segment is conditionally compiled depending upon the setting of the appropriate C preprocesser macros. */ { char buff[FLEN_FILENAME]; if(*status != 0) return(*status); #if defined(macintosh) /* MacOS case. Currently unknown !!!! */ *buff = 0; #else /* Good old getcwd() seems to work with all other platforms */ if (!getcwd(buff,FLEN_FILENAME)) { cwd[0]=0; ffpmsg("Path and file name too long (fits_get_cwd)"); return (*status=URL_PARSE_ERROR); } #endif /* convert the cwd string to a URL standard path string */ fits_path2url(buff,FLEN_FILENAME,cwd,status); return(*status); } /*---------------------------------------------------------------------------*/ int fits_get_url(fitsfile *fptr, /* I ptr to FITS file to evaluate */ char *realURL, /* O URL of real FITS file */ char *startURL, /* O URL of starting FITS file */ char *realAccess, /* O true access method of FITS file */ char *startAccess,/* O "official" access of FITS file */ int *iostate, /* O can this file be modified? */ int *status) /* For grouping convention purposes, determine the URL of the FITS file associated with the fitsfile pointer fptr. The true access type (file://, mem://, shmem://, root://), starting "official" access type, and iostate (0 ==> readonly, 1 ==> readwrite) are also returned. It is assumed that the url string has enough room to hold the resulting URL, and the the accessType string has enough room to hold the access type. */ { int i; int tmpIOstate = 0; char infile[FLEN_FILENAME]; char outfile[FLEN_FILENAME]; char tmpStr1[FLEN_FILENAME]; char tmpStr2[FLEN_FILENAME]; char tmpStr3[FLEN_FILENAME]; char tmpStr4[FLEN_FILENAME]; char *tmpPtr; if(*status != 0) return(*status); do { /* retrieve the member HDU's file name as opened by ffopen() and parse it into its constitutent pieces; get the currently active driver token too */ *tmpStr1 = *tmpStr2 = *tmpStr3 = *tmpStr4 = 0; *status = fits_file_name(fptr,tmpStr1,status); *status = ffiurl(tmpStr1,NULL,infile,outfile,NULL,tmpStr2,tmpStr3, tmpStr4,status); if((*tmpStr2) || (*tmpStr3) || (*tmpStr4)) tmpIOstate = -1; *status = ffurlt(fptr,tmpStr3,status); strcpy(tmpStr4,tmpStr3); *status = ffrtnm(tmpStr1,tmpStr2,status); strcpy(tmpStr1,tmpStr2); /* for grouping convention purposes (only) determine the URL of the actual FITS file being used for the given fptr, its true access type (file://, mem://, shmem://, root://) and its iostate (0 ==> read only, 1 ==> readwrite) */ /* The first set of access types are "simple" in that they do not use any redirection to temporary memory or outfiles */ /* standard disk file driver is in use */ if(fits_strcasecmp(tmpStr3,"file://") == 0) { tmpIOstate = 1; if(strlen(outfile)) strcpy(tmpStr1,outfile); else *tmpStr2 = 0; /* make sure no FILE:// specifier is given in the tmpStr1 or tmpStr2 strings; the convention calls for local files to have no access specification */ if((tmpPtr = strstr(tmpStr1,"://")) != NULL) { strcpy(infile,tmpPtr+3); strcpy(tmpStr1,infile); } if((tmpPtr = strstr(tmpStr2,"://")) != NULL) { strcpy(infile,tmpPtr+3); strcpy(tmpStr2,infile); } } /* file stored in conventional memory */ else if(fits_strcasecmp(tmpStr3,"mem://") == 0) { if(tmpIOstate < 0) { /* file is a temp mem file only */ ffpmsg("cannot make URL from temp MEM:// file (fits_get_url)"); *status = URL_PARSE_ERROR; } else { /* file is a "perminate" mem file for this process */ tmpIOstate = 1; *tmpStr2 = 0; } } /* file stored in conventional memory */ else if(fits_strcasecmp(tmpStr3,"memkeep://") == 0) { strcpy(tmpStr3,"mem://"); *tmpStr4 = 0; *tmpStr2 = 0; tmpIOstate = 1; } /* file residing in shared memory */ else if(fits_strcasecmp(tmpStr3,"shmem://") == 0) { *tmpStr4 = 0; *tmpStr2 = 0; tmpIOstate = 1; } /* file accessed via the ROOT network protocol */ else if(fits_strcasecmp(tmpStr3,"root://") == 0) { *tmpStr4 = 0; *tmpStr2 = 0; tmpIOstate = 1; } /* the next set of access types redirect the contents of the original file to an special outfile because the original could not be directly modified (i.e., resides on the network, was compressed). In these cases the URL string takes on the value of the OUTFILE, the access type becomes file://, and the iostate is set to 1 (can read/write to the file). */ /* compressed file uncompressed and written to disk */ else if(fits_strcasecmp(tmpStr3,"compressfile://") == 0) { strcpy(tmpStr1,outfile); strcpy(tmpStr2,infile); strcpy(tmpStr3,"file://"); strcpy(tmpStr4,"file://"); tmpIOstate = 1; } /* HTTP accessed file written locally to disk */ else if(fits_strcasecmp(tmpStr3,"httpfile://") == 0) { strcpy(tmpStr1,outfile); strcpy(tmpStr3,"file://"); strcpy(tmpStr4,"http://"); tmpIOstate = 1; } /* FTP accessd file written locally to disk */ else if(fits_strcasecmp(tmpStr3,"ftpfile://") == 0) { strcpy(tmpStr1,outfile); strcpy(tmpStr3,"file://"); strcpy(tmpStr4,"ftp://"); tmpIOstate = 1; } /* file from STDIN written to disk */ else if(fits_strcasecmp(tmpStr3,"stdinfile://") == 0) { strcpy(tmpStr1,outfile); strcpy(tmpStr3,"file://"); strcpy(tmpStr4,"stdin://"); tmpIOstate = 1; } /* the following access types use memory resident files as temporary storage; they cannot be modified or be made group members for grouping conventions purposes, but their original files can be. Thus, their tmpStr3s are reset to mem://, their iostate values are set to 0 (for no-modification), and their URL string values remain set to their original values */ /* compressed disk file uncompressed into memory */ else if(fits_strcasecmp(tmpStr3,"compress://") == 0) { *tmpStr1 = 0; strcpy(tmpStr2,infile); strcpy(tmpStr3,"mem://"); strcpy(tmpStr4,"file://"); tmpIOstate = 0; } /* HTTP accessed file transferred into memory */ else if(fits_strcasecmp(tmpStr3,"http://") == 0) { *tmpStr1 = 0; strcpy(tmpStr3,"mem://"); strcpy(tmpStr4,"http://"); tmpIOstate = 0; } /* HTTP accessed compressed file transferred into memory */ else if(fits_strcasecmp(tmpStr3,"httpcompress://") == 0) { *tmpStr1 = 0; strcpy(tmpStr3,"mem://"); strcpy(tmpStr4,"http://"); tmpIOstate = 0; } /* FTP accessed file transferred into memory */ else if(fits_strcasecmp(tmpStr3,"ftp://") == 0) { *tmpStr1 = 0; strcpy(tmpStr3,"mem://"); strcpy(tmpStr4,"ftp://"); tmpIOstate = 0; } /* FTP accessed compressed file transferred into memory */ else if(fits_strcasecmp(tmpStr3,"ftpcompress://") == 0) { *tmpStr1 = 0; strcpy(tmpStr3,"mem://"); strcpy(tmpStr4,"ftp://"); tmpIOstate = 0; } /* The last set of access types cannot be used to make a meaningful URL strings from; thus an error is generated */ else if(fits_strcasecmp(tmpStr3,"stdin://") == 0) { *status = URL_PARSE_ERROR; ffpmsg("cannot make valid URL from stdin:// (fits_get_url)"); *tmpStr1 = *tmpStr2 = 0; } else if(fits_strcasecmp(tmpStr3,"stdout://") == 0) { *status = URL_PARSE_ERROR; ffpmsg("cannot make valid URL from stdout:// (fits_get_url)"); *tmpStr1 = *tmpStr2 = 0; } else if(fits_strcasecmp(tmpStr3,"irafmem://") == 0) { *status = URL_PARSE_ERROR; ffpmsg("cannot make valid URL from irafmem:// (fits_get_url)"); *tmpStr1 = *tmpStr2 = 0; } if(*status != 0) continue; /* assign values to the calling parameters if they are non-NULL */ if(realURL != NULL) { if(strlen(tmpStr1) == 0) *realURL = 0; else { if((tmpPtr = strstr(tmpStr1,"://")) != NULL) { tmpPtr += 3; i = (long)tmpPtr - (long)tmpStr1; strncpy(realURL,tmpStr1,i); } else { tmpPtr = tmpStr1; i = 0; } *status = fits_path2url(tmpPtr,FLEN_FILENAME-i,realURL+i,status); } } if(startURL != NULL) { if(strlen(tmpStr2) == 0) *startURL = 0; else { if((tmpPtr = strstr(tmpStr2,"://")) != NULL) { tmpPtr += 3; i = (long)tmpPtr - (long)tmpStr2; strncpy(startURL,tmpStr2,i); } else { tmpPtr = tmpStr2; i = 0; } *status = fits_path2url(tmpPtr,FLEN_FILENAME-i,startURL+i,status); } } if(realAccess != NULL) strcpy(realAccess,tmpStr3); if(startAccess != NULL) strcpy(startAccess,tmpStr4); if(iostate != NULL) *iostate = tmpIOstate; }while(0); return(*status); } /*-------------------------------------------------------------------------- URL parse support functions --------------------------------------------------------------------------*/ /* simple push/pop/shift/unshift string stack for use by fits_clean_url */ typedef char* grp_stack_data; /* type of data held by grp_stack */ typedef struct grp_stack_item_struct { grp_stack_data data; /* value of this stack item */ struct grp_stack_item_struct* next; /* next stack item */ struct grp_stack_item_struct* prev; /* previous stack item */ } grp_stack_item; typedef struct grp_stack_struct { size_t stack_size; /* number of items on stack */ grp_stack_item* top; /* top item */ } grp_stack; static char* grp_stack_default = NULL; /* initial value for new instances of grp_stack_data */ /* the following functions implement the group string stack grp_stack */ static void delete_grp_stack(grp_stack** mystack); static grp_stack_item* grp_stack_append( grp_stack_item* last, grp_stack_data data ); static grp_stack_data grp_stack_remove(grp_stack_item* last); static grp_stack* new_grp_stack(void); static grp_stack_data pop_grp_stack(grp_stack* mystack); static void push_grp_stack(grp_stack* mystack, grp_stack_data data); static grp_stack_data shift_grp_stack(grp_stack* mystack); /* static void unshift_grp_stack(grp_stack* mystack, grp_stack_data data); */ int fits_clean_url(char *inURL, /* I input URL string */ char *outURL, /* O output URL string */ int *status) /* clean the URL by eliminating any ".." or "." specifiers in the inURL string, and write the output to the outURL string. Note that this function must have a valid Unix-style URL as input; platform dependent path strings are not allowed. */ { grp_stack* mystack; /* stack to hold pieces of URL */ char* tmp; char *saveptr; if(*status) return *status; mystack = new_grp_stack(); *outURL = 0; do { /* handle URL scheme and domain if they exist */ tmp = strstr(inURL, "://"); if(tmp) { /* there is a URL scheme, so look for the end of the domain too */ tmp = strchr(tmp + 3, '/'); if(tmp) { /* tmp is now the end of the domain, so * copy URL scheme and domain as is, and terminate by hand */ size_t string_size = (size_t) (tmp - inURL); strncpy(outURL, inURL, string_size); outURL[string_size] = 0; /* now advance the input pointer to just after the domain and go on */ inURL = tmp; } else { /* '/' was not found, which means there are no path-like * portions, so copy whole inURL to outURL and we're done */ strcpy(outURL, inURL); continue; /* while(0) */ } } /* explicitly copy a leading / (absolute path) */ if('/' == *inURL) strcat(outURL, "/"); /* now clean the remainder of the inURL. push URL segments onto * stack, dealing with .. and . as we go */ tmp = ffstrtok(inURL, "/",&saveptr); /* finds first / */ while(tmp) { if(!strcmp(tmp, "..")) { /* discard previous URL segment, if there was one. if not, * add the .. to the stack if this is *not* an absolute path * (for absolute paths, leading .. has no effect, so skip it) */ if(0 < mystack->stack_size) pop_grp_stack(mystack); else if('/' != *inURL) push_grp_stack(mystack, tmp); } else { /* always just skip ., but otherwise add segment to stack */ if(strcmp(tmp, ".")) push_grp_stack(mystack, tmp); } tmp = ffstrtok(NULL, "/",&saveptr); /* get the next segment */ } /* stack now has pieces of cleaned URL, so just catenate them * onto output string until stack is empty */ while(0 < mystack->stack_size) { tmp = shift_grp_stack(mystack); if (strlen(outURL) + strlen(tmp) + 1 > FLEN_FILENAME-1) { outURL[0]=0; ffpmsg("outURL is too long (fits_clean_url)"); *status = URL_PARSE_ERROR; delete_grp_stack(&mystack); return *status; } strcat(outURL, tmp); strcat(outURL, "/"); } outURL[strlen(outURL) - 1] = 0; /* blank out trailing / */ } while(0); delete_grp_stack(&mystack); return *status; } /* free all stack contents using pop_grp_stack before freeing the * grp_stack itself */ static void delete_grp_stack(grp_stack** mystack) { if(!mystack || !*mystack) return; while((*mystack)->stack_size) pop_grp_stack(*mystack); free(*mystack); *mystack = NULL; } /* append an item to the stack, handling the special case of the first * item appended */ static grp_stack_item* grp_stack_append( grp_stack_item* last, grp_stack_data data ) { /* first create a new stack item, and copy data to it */ grp_stack_item* new_item = (grp_stack_item*) malloc(sizeof(grp_stack_item)); new_item->data = data; if(last) { /* attach this item between the "last" item and its "next" item */ new_item->next = last->next; new_item->prev = last; last->next->prev = new_item; last->next = new_item; } else { /* stack is empty, so "next" and "previous" both point back to it */ new_item->next = new_item; new_item->prev = new_item; } return new_item; } /* remove an item from the stack, handling the special case of the last * item removed */ static grp_stack_data grp_stack_remove(grp_stack_item* last) { grp_stack_data retval = last->data; last->prev->next = last->next; last->next->prev = last->prev; free(last); return retval; } /* create new stack dynamically, and give it valid initial values */ static grp_stack* new_grp_stack(void) { grp_stack* retval = (grp_stack*) malloc(sizeof(grp_stack)); if(retval) { retval->stack_size = 0; retval->top = NULL; } return retval; } /* return the value at the top of the stack and remove it, updating * stack_size. top->prev becomes the new "top" */ static grp_stack_data pop_grp_stack(grp_stack* mystack) { grp_stack_data retval = grp_stack_default; if(mystack && mystack->top) { grp_stack_item* newtop = mystack->top->prev; retval = grp_stack_remove(mystack->top); mystack->top = newtop; if(0 == --mystack->stack_size) mystack->top = NULL; } return retval; } /* add to the stack after the top element. the added element becomes * the new "top" */ static void push_grp_stack(grp_stack* mystack, grp_stack_data data) { if(!mystack) return; mystack->top = grp_stack_append(mystack->top, data); ++mystack->stack_size; return; } /* return the value at the bottom of the stack and remove it, updating * stack_size. "top" pointer is unaffected */ static grp_stack_data shift_grp_stack(grp_stack* mystack) { grp_stack_data retval = grp_stack_default; if(mystack && mystack->top) { retval = grp_stack_remove(mystack->top->next); /* top->next == bottom */ if(0 == --mystack->stack_size) mystack->top = NULL; } return retval; } /* add to the stack after the top element. "top" is unaffected, except * in the special case of an initially empty stack */ /* static void unshift_grp_stack(grp_stack* mystack, grp_stack_data data) { if(!mystack) return; if(mystack->top) grp_stack_append(mystack->top, data); else mystack->top = grp_stack_append(NULL, data); ++mystack->stack_size; return; } */ /*--------------------------------------------------------------------------*/ int fits_url2relurl(char *refURL, /* I reference URL string */ char *absURL, /* I absoulute URL string to process */ char *relURL, /* O resulting relative URL string */ int *status) /* create a relative URL to the file referenced by absURL with respect to the reference URL refURL. The relative URL is returned in relURL. Both refURL and absURL must be absolute URL strings; i.e. either begin with an access method specification "XXX://" or with a '/' character signifiying that they are absolute file paths. Note that it is possible to make a relative URL from two input URLs (absURL and refURL) that are not compatable. This function does not check to see if the resulting relative URL makes any sence. For instance, it is impossible to make a relative URL from the following two inputs: absURL = ftp://a.b.c.com/x/y/z/foo.fits refURL = /a/b/c/ttt.fits The resulting relURL will be: ../../../ftp://a.b.c.com/x/y/z/foo.fits Which is syntically correct but meaningless. The problem is that a file with an access method of ftp:// cannot be expressed a a relative URL to a local disk file. */ { int i,j; int refcount,abscount; int refsize,abssize; int done; if(*status != 0) return(*status); /* initialize the relative URL string */ relURL[0] = 0; do { /* refURL and absURL must be absolute to process */ if(!(fits_is_url_absolute(refURL) || *refURL == '/') || !(fits_is_url_absolute(absURL) || *absURL == '/')) { *status = URL_PARSE_ERROR; ffpmsg("Cannot make rel. URL from non abs. URLs (fits_url2relurl)"); continue; } /* determine the size of the refURL and absURL strings */ refsize = strlen(refURL); abssize = strlen(absURL); /* process the two URL strings and build the relative URL between them */ for(done = 0, refcount = 0, abscount = 0; !done && refcount < refsize && abscount < abssize; ++refcount, ++abscount) { for(; abscount < abssize && absURL[abscount] == '/'; ++abscount); for(; refcount < refsize && refURL[refcount] == '/'; ++refcount); /* find the next path segment in absURL */ for(i = abscount; absURL[i] != '/' && i < abssize; ++i); /* find the next path segment in refURL */ for(j = refcount; refURL[j] != '/' && j < refsize; ++j); /* do the two path segments match? */ if(i == j && strncmp(absURL+abscount, refURL+refcount,i-refcount) == 0) { /* they match, so ignore them and continue */ abscount = i; refcount = j; continue; } /* We found a difference in the paths in refURL and absURL. For every path segment remaining in the refURL string, append a "../" path segment to the relataive URL relURL. */ for(j = refcount; j < refsize; ++j) if(refURL[j] == '/') { if (strlen(relURL)+3 > FLEN_FILENAME-1) { *status = URL_PARSE_ERROR; ffpmsg("relURL too long (fits_url2relurl)"); return (*status); } strcat(relURL,"../"); } /* copy all remaining characters of absURL to the output relURL */ if (strlen(relURL) + strlen(absURL+abscount) > FLEN_FILENAME-1) { *status = URL_PARSE_ERROR; ffpmsg("relURL too long (fits_url2relurl)"); return (*status); } strcat(relURL,absURL+abscount); /* we are done building the relative URL */ done = 1; } }while(0); return(*status); } /*--------------------------------------------------------------------------*/ int fits_relurl2url(char *refURL, /* I reference URL string */ char *relURL, /* I relative URL string to process */ char *absURL, /* O absolute URL string */ int *status) /* create an absolute URL from a relative url and a reference URL. The reference URL is given by the FITS file pointed to by fptr. The construction of the absolute URL from the partial and reference URl is performed using the rules set forth in: http://www.w3.org/Addressing/URL/URL_TOC.html and http://www.w3.org/Addressing/URL/4_3_Partial.html Note that the relative URL string relURL must conform to the Unix-like URL syntax; host dependent partial URL strings are not allowed. */ { int i; char tmpStr[FLEN_FILENAME]; char *tmpStr1, *tmpStr2; if(*status != 0) return(*status); do { /* make a copy of the reference URL string refURL for parsing purposes */ if (strlen(refURL) > FLEN_FILENAME-1) { absURL[0]=0; ffpmsg("ref URL is too long (fits_relurl2url)"); *status = URL_PARSE_ERROR; continue; } strcpy(tmpStr,refURL); /* if the reference file has an access method of mem:// or shmem:// then we cannot use it as the basis of an absolute URL construction for a partial URL */ if(fits_strncasecmp(tmpStr,"MEM:",4) == 0 || fits_strncasecmp(tmpStr,"SHMEM:",6) == 0) { ffpmsg("ref URL has access mem:// or shmem:// (fits_relurl2url)"); ffpmsg(" cannot construct full URL from a partial URL and "); ffpmsg(" MEM/SHMEM base URL"); *status = URL_PARSE_ERROR; continue; } if(relURL[0] != '/') { /* just append the relative URL string to the reference URL string (minus the reference URL file name) to form the absolute URL string */ tmpStr1 = strrchr(tmpStr,'/'); if(tmpStr1 != NULL) tmpStr1[1] = 0; else tmpStr[0] = 0; if (strlen(tmpStr)+strlen(relURL) > FLEN_FILENAME-1) { absURL[0]=0; ffpmsg("rel + ref URL is too long (fits_relurl2url)"); *status = URL_PARSE_ERROR; continue; } strcat(tmpStr,relURL); } else { /* have to parse the refURL string for the first occurnace of the same number of '/' characters as contained in the beginning of location that is not followed by a greater number of consective '/' charaters (yes, that is a confusing statement); this is the location in the refURL string where the relURL string is to be appended to form the new absolute URL string */ /* first, build up a slash pattern string that has one more slash in it than the starting slash pattern of the relURL string */ strcpy(absURL,"/"); for(i = 0; relURL[i] == '/'; ++i) { if (strlen(absURL) + 1 > FLEN_FILENAME-1) { absURL[0]=0; ffpmsg("abs URL is too long (fits_relurl2url)"); *status = URL_PARSE_ERROR; return (*status); } strcat(absURL,"/"); } /* loop over the refURL string until the slash pattern stored in absURL is no longer found */ for(tmpStr1 = tmpStr, i = strlen(absURL); (tmpStr2 = strstr(tmpStr1,absURL)) != NULL; tmpStr1 = tmpStr2 + i); /* reduce the slash pattern string by one slash */ absURL[i-1] = 0; /* search for the slash pattern in the remaining portion of the refURL string */ tmpStr2 = strstr(tmpStr1,absURL); /* if no slash pattern match was found */ if(tmpStr2 == NULL) { /* just strip off the file name from the refURL */ tmpStr2 = strrchr(tmpStr1,'/'); if(tmpStr2 != NULL) tmpStr2[0] = 0; else tmpStr[0] = 0; } else { /* set a string terminator at the slash pattern match */ *tmpStr2 = 0; } /* conatenate the relURL string to the refURL string to form the absURL */ if (strlen(tmpStr)+strlen(relURL) > FLEN_FILENAME-1) { absURL[0]=0; ffpmsg("rel + ref URL is too long (fits_relurl2url)"); *status = URL_PARSE_ERROR; continue; } strcat(tmpStr,relURL); } /* normalize the absURL by removing any ".." or "." specifiers in the string */ *status = fits_clean_url(tmpStr,absURL,status); }while(0); return(*status); } /*--------------------------------------------------------------------------*/ int fits_encode_url(char *inpath, /* I URL to be encoded */ int maxlength, /* I max number of chars that may be copied to outpath, including terminating NULL. */ char *outpath, /* O output encoded URL */ int *status) /* encode all URL "unsafe" and "reserved" characters using the "%XX" convention, where XX stand for the two hexidecimal digits of the encode character's ASCII code. Note that the outpath length, as specified by the maxlength argument, should be at least as large as inpath and preferably larger (to hold any characters that need encoding). If more than maxlength chars are required for outpath, including the terminating NULL, outpath will be set to size 0 and an error status will be returned. This function was adopted from code in the libwww.a library available via the W3 consortium */ { unsigned char a; char *p; char *q; char *hex = "0123456789ABCDEF"; int iout=0; unsigned const char isAcceptable[96] = {/* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xA 0xB 0xC 0xD 0xE 0xF */ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xF,0xE,0x0,0xF,0xF,0xC, /* 2x !"#$%&'()*+,-./ */ 0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0x8,0x0,0x0,0x0,0x0,0x0, /* 3x 0123456789:;<=>? */ 0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF, /* 4x @ABCDEFGHIJKLMNO */ 0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0x0,0x0,0x0,0x0,0xF, /* 5X PQRSTUVWXYZ[\]^_ */ 0x0,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF, /* 6x `abcdefghijklmno */ 0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0x0,0x0,0x0,0x0,0x0 /* 7X pqrstuvwxyz{\}~DEL */ }; if(*status != 0) return(*status); /* loop over all characters in inpath until '\0' is encountered */ for(q = outpath, p = inpath; *p && (iout < maxlength-1) ; p++) { a = (unsigned char)*p; /* if the charcter requires encoding then process it */ if(!( a>=32 && a<128 && (isAcceptable[a-32]))) { if (iout+2 < maxlength-1) { /* add a '%' character to the outpath */ *q++ = HEX_ESCAPE; /* add the most significant ASCII code hex value */ *q++ = hex[a >> 4]; /* add the least significant ASCII code hex value */ *q++ = hex[a & 15]; iout += 3; } else { ffpmsg("URL input is too long to encode (fits_encode_url)"); *status = URL_PARSE_ERROR; outpath[0] = 0; return (*status); } } /* else just copy the character as is */ else { *q++ = *p; iout++; } } /* null terminate the outpath string */ if (*p && (iout == maxlength-1)) { ffpmsg("URL input is too long to encode (fits_encode_url)"); *status = URL_PARSE_ERROR; outpath[0] = 0; return (*status); } *q++ = 0; return(*status); } /*---------------------------------------------------------------------------*/ int fits_unencode_url(char *inpath, /* I input URL with encoding */ char *outpath, /* O unencoded URL */ int *status) /* unencode all URL "unsafe" and "reserved" characters to their actual ASCII representation. All tokens of the form "%XX" where XX is the hexidecimal code for an ASCII character, are searched for and translated into the actuall ASCII character (so three chars become 1 char). It is assumed that OUTPATH has enough room to hold the unencoded URL. This function was adopted from code in the libwww.a library available via the W3 consortium */ { char *p; char *q; char c; if(*status != 0) return(*status); p = inpath; q = outpath; /* loop over all characters in the inpath looking for the '%' escape character; if found the process the escape sequence */ while(*p != 0) { /* if the character is '%' then unencode the sequence, else just copy the character from inpath to outpath */ if (*p == HEX_ESCAPE) { if((c = *(++p)) != 0) { *q = ( (c >= '0' && c <= '9') ? (c - '0') : ((c >= 'A' && c <= 'F') ? (c - 'A' + 10) : (c - 'a' + 10)) )*16; if((c = *(++p)) != 0) { *q = *q + ( (c >= '0' && c <= '9') ? (c - '0') : ((c >= 'A' && c <= 'F') ? (c - 'A' + 10) : (c - 'a' + 10)) ); p++, q++; } } } else *q++ = *p++; } /* terminate the outpath */ *q = 0; return(*status); } /*---------------------------------------------------------------------------*/ int fits_is_url_absolute(char *url) /* Return a True (1) or False (0) value indicating whether or not the passed URL string contains an access method specifier or not. Note that this is a boolean function and it neither reads nor returns the standard error status parameter */ { char *tmpStr1, *tmpStr2; char reserved[] = {':',';','/','?','@','&','=','+','$',','}; /* The rule for determing if an URL is relative or absolute is that it (1) must have a colon ":" and (2) that the colon must appear before any other reserved URL character in the URL string. We first see if a colon exists, get its position in the string, and then check to see if any of the other reserved characters exists and if their position in the string is greater than that of the colons. */ if( (tmpStr1 = strchr(url,reserved[0])) != NULL && ((tmpStr2 = strchr(url,reserved[1])) == NULL || tmpStr2 > tmpStr1) && ((tmpStr2 = strchr(url,reserved[2])) == NULL || tmpStr2 > tmpStr1) && ((tmpStr2 = strchr(url,reserved[3])) == NULL || tmpStr2 > tmpStr1) && ((tmpStr2 = strchr(url,reserved[4])) == NULL || tmpStr2 > tmpStr1) && ((tmpStr2 = strchr(url,reserved[5])) == NULL || tmpStr2 > tmpStr1) && ((tmpStr2 = strchr(url,reserved[6])) == NULL || tmpStr2 > tmpStr1) && ((tmpStr2 = strchr(url,reserved[7])) == NULL || tmpStr2 > tmpStr1) && ((tmpStr2 = strchr(url,reserved[8])) == NULL || tmpStr2 > tmpStr1) && ((tmpStr2 = strchr(url,reserved[9])) == NULL || tmpStr2 > tmpStr1) ) { return(1); } else { return(0); } } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/group.h0000644000175100001710000000406100000000000017431 0ustar00vstsdocker#define MAX_HDU_TRACKER 1000 typedef struct _HDUtracker HDUtracker; struct _HDUtracker { int nHDU; char *filename[MAX_HDU_TRACKER]; int position[MAX_HDU_TRACKER]; char *newFilename[MAX_HDU_TRACKER]; int newPosition[MAX_HDU_TRACKER]; }; /* functions used internally in the grouping convention module */ int ffgtdc(int grouptype, int xtensioncol, int extnamecol, int extvercol, int positioncol, int locationcol, int uricol, char *ttype[], char *tform[], int *ncols, int *status); int ffgtgc(fitsfile *gfptr, int *xtensionCol, int *extnameCol, int *extverCol, int *positionCol, int *locationCol, int *uriCol, int *grptype, int *status); int ffvcfm(fitsfile *gfptr, int xtensionCol, int extnameCol, int extverCol, int positionCol, int locationCol, int uriCol, int *status); int ffgmul(fitsfile *mfptr, int rmopt, int *status); int ffgmf(fitsfile *gfptr, char *xtension, char *extname, int extver, int position, char *location, long *member, int *status); int ffgtrmr(fitsfile *gfptr, HDUtracker *HDU, int *status); int ffgtcpr(fitsfile *infptr, fitsfile *outfptr, int cpopt, HDUtracker *HDU, int *status); int fftsad(fitsfile *mfptr, HDUtracker *HDU, int *newPosition, char *newFileName); int fftsud(fitsfile *mfptr, HDUtracker *HDU, int newPosition, char *newFileName); void prepare_keyvalue(char *keyvalue); int fits_path2url(char *inpath, int maxlength, char *outpath, int *status); int fits_url2path(char *inpath, char *outpath, int *status); int fits_get_cwd(char *cwd, int *status); int fits_get_url(fitsfile *fptr, char *realURL, char *startURL, char *realAccess, char *startAccess, int *iostate, int *status); int fits_clean_url(char *inURL, char *outURL, int *status); int fits_relurl2url(char *refURL, char *relURL, char *absURL, int *status); int fits_url2relurl(char *refURL, char *absURL, char *relURL, int *status); int fits_encode_url(char *inpath, int maxlength, char *outpath, int *status); int fits_unencode_url(char *inpath, char *outpath, int *status); int fits_is_url_absolute(char *url); ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/grparser.c0000644000175100001710000013236500000000000020126 0ustar00vstsdocker/* T E M P L A T E P A R S E R ============================= by Jerzy.Borkowski@obs.unige.ch Integral Science Data Center ch. d'Ecogia 16 1290 Versoix Switzerland 14-Oct-98: initial release 16-Oct-98: code cleanup, #include included, now gcc -Wall prints no warnings during compilation. Bugfix: now one can specify additional columns in group HDU. Autoindexing also works in this situation (colunms are number from 7 however). 17-Oct-98: bugfix: complex keywords were incorrectly written (was TCOMPLEX should be TDBLCOMPLEX). 20-Oct-98: bugfix: parser was writing EXTNAME twice, when first HDU in template is defined with XTENSION IMAGE then parser creates now dummy PHDU, SIMPLE T is now allowed only at most once and in first HDU only. WARNING: one should not define EXTNAME keyword for GROUP HDUs, as they have them already defined by parser (EXTNAME = GROUPING). Parser accepts EXTNAME oin GROUP HDU definition, but in this case multiple EXTNAME keywords will present in HDU header. 23-Oct-98: bugfix: unnecessary space was written to FITS file for blank keywords. 24-Oct-98: syntax change: empty lines and lines with only whitespaces are written to FITS files as blank keywords (if inside group/hdu definition). Previously lines had to have at least 8 spaces. Please note, that due to pecularities of CFITSIO if the last keyword(s) defined for given HDU are blank keywords consisting of only 80 spaces, then (some of) those keywords may be silently deleted by CFITSIO. 13-Nov-98: bugfix: parser was writing GRPNAME twice. Parser still creates GRPNAME keywords for GROUP HDU's which do not specify them. However, values (of form DEFAULT_GROUP_XXX) are assigned not necessarily in order HDUs appear in template file, but rather in order parser completes their creation in FITS file. Also, when including files, if fopen fails, parser tries to open file with a name = directory_of_top_level file + name of file to be included, as long as name of file to be included does not specify absolute pathname. 16-Nov-98: bugfix to bugfix from 13-Nov-98 19-Nov-98: EXTVER keyword is now automatically assigned value by parser. 17-Dev-98: 2 new things added: 1st: CFITSIO_INCLUDE_FILES environment variable can contain a colon separated list of directories to look for when looking for template include files (and master template also). 2nd: it is now possible to append template to nonempty FITS. file. fitsfile *ff no longer needs to point to an empty FITS file with 0 HDUs in it. All data written by parser will simple be appended at the end of file. 22-Jan-99: changes to parser: when in append mode parser initially scans all existing HDUs to built a list of already used EXTNAME/EXTVERs 22-Jan-99: Bruce O'Neel, bugfix : TLONG should always reference long type variable on OSF/Alpha and on 64-bit archs in general 20-Jun-2002 Wm Pence, added support for the HIERARCH keyword convention in which keyword names can effectively be longer than 8 characters. Example: HIERARCH LongKeywordName = 'value' / comment 30-Jan-2003 Wm Pence, bugfix: ngp_read_xtension was testing for "ASCIITABLE" instead of "TABLE" as the XTENSION value of an ASCII table, and it did not allow for optional trailing spaces in the "IMAGE" or "TABLE" string. 16-Dec-2003 James Peachey: ngp_keyword_all_write was modified to apply comments from the template file to the output file in the case of reserved keywords (e.g. tform#, ttype# etcetera). */ #include #include #ifdef sparc #include #include #endif #include #include "fitsio2.h" #include "grparser.h" NGP_RAW_LINE ngp_curline = { NULL, NULL, NULL, NGP_TTYPE_UNKNOWN, NULL, NGP_FORMAT_OK, 0 }; NGP_RAW_LINE ngp_prevline = { NULL, NULL, NULL, NGP_TTYPE_UNKNOWN, NULL, NGP_FORMAT_OK, 0 }; int ngp_inclevel = 0; /* number of included files, 1 - means mean file */ int ngp_grplevel = 0; /* group nesting level, 0 - means no grouping */ FILE *ngp_fp[NGP_MAX_INCLUDE]; /* stack of included file handles */ int ngp_keyidx = NGP_TOKEN_UNKNOWN; /* index of token in current line */ NGP_TOKEN ngp_linkey; /* keyword after line analyze */ char ngp_master_dir[NGP_MAX_FNAME]; /* directory of top level include file */ NGP_TKDEF ngp_tkdef[] = /* tokens recognized by parser */ { { "\\INCLUDE", NGP_TOKEN_INCLUDE }, { "\\GROUP", NGP_TOKEN_GROUP }, { "\\END", NGP_TOKEN_END }, { "XTENSION", NGP_TOKEN_XTENSION }, { "SIMPLE", NGP_TOKEN_SIMPLE }, { NULL, NGP_TOKEN_UNKNOWN } }; int master_grp_idx = 1; /* current unnamed group in object */ int ngp_extver_tab_size = 0; NGP_EXTVER_TAB *ngp_extver_tab = NULL; int ngp_get_extver(char *extname, int *version) { NGP_EXTVER_TAB *p; char *p2; int i; if ((NULL == extname) || (NULL == version)) return(NGP_BAD_ARG); if ((NULL == ngp_extver_tab) && (ngp_extver_tab_size > 0)) return(NGP_BAD_ARG); if ((NULL != ngp_extver_tab) && (ngp_extver_tab_size <= 0)) return(NGP_BAD_ARG); for (i=0; i 0)) return(NGP_BAD_ARG); if ((NULL != ngp_extver_tab) && (ngp_extver_tab_size <= 0)) return(NGP_BAD_ARG); for (i=0; i ngp_extver_tab[i].version) ngp_extver_tab[i].version = version; return(NGP_OK); } } if (NULL == ngp_extver_tab) { p = (NGP_EXTVER_TAB *)ngp_alloc(sizeof(NGP_EXTVER_TAB)); } else { p = (NGP_EXTVER_TAB *)ngp_realloc(ngp_extver_tab, (ngp_extver_tab_size + 1) * sizeof(NGP_EXTVER_TAB)); } if (NULL == p) return(NGP_NO_MEMORY); p2 = ngp_alloc(strlen(extname) + 1); if (NULL == p2) { ngp_free(p); return(NGP_NO_MEMORY); } strcpy(p2, extname); ngp_extver_tab = p; ngp_extver_tab[ngp_extver_tab_size].extname = p2; ngp_extver_tab[ngp_extver_tab_size].version = version; ngp_extver_tab_size++; return(NGP_OK); } int ngp_delete_extver_tab(void) { int i; if ((NULL == ngp_extver_tab) && (ngp_extver_tab_size > 0)) return(NGP_BAD_ARG); if ((NULL != ngp_extver_tab) && (ngp_extver_tab_size <= 0)) return(NGP_BAD_ARG); if ((NULL == ngp_extver_tab) && (0 == ngp_extver_tab_size)) return(NGP_OK); for (i=0; i allocsize) { p2 = (char *)ngp_realloc(*p, alen); /* realloc buffer, if there is need */ if (NULL == p2) { r = NGP_NO_MEMORY; break; } *p = p2; allocsize = alen; } (*p)[llen - 1] = c; /* copy character to buffer */ } llen++; /* place for terminating \0 */ if (llen != allocsize) { p2 = (char *)ngp_realloc(*p, llen); if (NULL == p2) r = NGP_NO_MEMORY; else { *p = p2; (*p)[llen - 1] = 0; /* copy \0 to buffer */ } } else { (*p)[llen - 1] = 0; /* necessary when line read was empty */ } if ((NGP_EOF != r) && (NGP_OK != r)) /* in case of errors free resources */ { ngp_free(*p); *p = NULL; } return(r); /* return status code */ } /* free current line structure */ int ngp_free_line(void) { if (NULL != ngp_curline.line) { ngp_free(ngp_curline.line); ngp_curline.line = NULL; ngp_curline.name = NULL; ngp_curline.value = NULL; ngp_curline.comment = NULL; ngp_curline.type = NGP_TTYPE_UNKNOWN; ngp_curline.format = NGP_FORMAT_OK; ngp_curline.flags = 0; } return(NGP_OK); } /* free cached line structure */ int ngp_free_prevline(void) { if (NULL != ngp_prevline.line) { ngp_free(ngp_prevline.line); ngp_prevline.line = NULL; ngp_prevline.name = NULL; ngp_prevline.value = NULL; ngp_prevline.comment = NULL; ngp_prevline.type = NGP_TTYPE_UNKNOWN; ngp_prevline.format = NGP_FORMAT_OK; ngp_prevline.flags = 0; } return(NGP_OK); } /* read one line */ int ngp_read_line_buffered(FILE *fp) { ngp_free_line(); /* first free current line (if any) */ if (NULL != ngp_prevline.line) /* if cached, return cached line */ { ngp_curline = ngp_prevline; ngp_prevline.line = NULL; ngp_prevline.name = NULL; ngp_prevline.value = NULL; ngp_prevline.comment = NULL; ngp_prevline.type = NGP_TTYPE_UNKNOWN; ngp_prevline.format = NGP_FORMAT_OK; ngp_prevline.flags = 0; ngp_curline.flags = NGP_LINE_REREAD; return(NGP_OK); } ngp_curline.flags = 0; /* if not cached really read line from file */ return(ngp_line_from_file(fp, &(ngp_curline.line))); } /* unread line */ int ngp_unread_line(void) { if (NULL == ngp_curline.line) /* nothing to unread */ return(NGP_EMPTY_CURLINE); if (NULL != ngp_prevline.line) /* we cannot unread line twice */ return(NGP_UNREAD_QUEUE_FULL); ngp_prevline = ngp_curline; ngp_curline.line = NULL; return(NGP_OK); } /* a first guess line decomposition */ int ngp_extract_tokens(NGP_RAW_LINE *cl) { char *p, *s; int cl_flags, i; p = cl->line; /* start from beginning of line */ if (NULL == p) return(NGP_NUL_PTR); cl->name = cl->value = cl->comment = NULL; cl->type = NGP_TTYPE_UNKNOWN; cl->format = NGP_FORMAT_OK; cl_flags = 0; for (i=0;; i++) /* if 8 spaces at beginning then line is comment */ { if ((0 == *p) || ('\n' == *p)) { /* if line has only blanks -> write blank keyword */ cl->line[0] = 0; /* create empty name (0 length string) */ cl->comment = cl->name = cl->line; cl->type = NGP_TTYPE_RAW; /* signal write unformatted to FITS file */ return(NGP_OK); } if ((' ' != *p) && ('\t' != *p)) break; if (i >= 7) { cl->comment = p + 1; for (s = cl->comment;; s++) /* filter out any EOS characters in comment */ { if ('\n' == *s) *s = 0; if (0 == *s) break; } cl->line[0] = 0; /* create empty name (0 length string) */ cl->name = cl->line; cl->type = NGP_TTYPE_RAW; return(NGP_OK); } p++; } cl->name = p; for (;;) /* we need to find 1st whitespace */ { if ((0 == *p) || ('\n' == *p)) { *p = 0; break; } /* from Richard Mathar, 2002-05-03, add 10 lines: if upper/lowercase HIERARCH followed also by an equal sign... */ if( fits_strncasecmp("HIERARCH",p,strlen("HIERARCH")) == 0 ) { char * const eqsi=strchr(p,'=') ; if( eqsi ) { cl_flags |= NGP_FOUND_EQUAL_SIGN ; p=eqsi ; break ; } } if ((' ' == *p) || ('\t' == *p)) break; if ('=' == *p) { cl_flags |= NGP_FOUND_EQUAL_SIGN; break; } p++; } if (*p) *(p++) = 0; /* found end of keyname so terminate string with zero */ if ((!fits_strcasecmp("HISTORY", cl->name)) || (!fits_strcasecmp("COMMENT", cl->name)) || (!fits_strcasecmp("CONTINUE", cl->name))) { cl->comment = p; for (s = cl->comment;; s++) /* filter out any EOS characters in comment */ { if ('\n' == *s) *s = 0; if (0 == *s) break; } cl->type = NGP_TTYPE_RAW; return(NGP_OK); } if (!fits_strcasecmp("\\INCLUDE", cl->name)) { for (;; p++) if ((' ' != *p) && ('\t' != *p)) break; /* skip whitespace */ cl->value = p; for (s = cl->value;; s++) /* filter out any EOS characters */ { if ('\n' == *s) *s = 0; if (0 == *s) break; } cl->type = NGP_TTYPE_UNKNOWN; return(NGP_OK); } for (;; p++) { if ((0 == *p) || ('\n' == *p)) return(NGP_OK); /* test if at end of string */ if ((' ' == *p) || ('\t' == *p)) continue; /* skip whitespace */ if (cl_flags & NGP_FOUND_EQUAL_SIGN) break; if ('=' != *p) break; /* ignore initial equal sign */ cl_flags |= NGP_FOUND_EQUAL_SIGN; } if ('/' == *p) /* no value specified, comment only */ { p++; if ((' ' == *p) || ('\t' == *p)) p++; cl->comment = p; for (s = cl->comment;; s++) /* filter out any EOS characters in comment */ { if ('\n' == *s) *s = 0; if (0 == *s) break; } return(NGP_OK); } if ('\'' == *p) /* we have found string within quotes */ { cl->value = s = ++p; /* set pointer to beginning of that string */ cl->type = NGP_TTYPE_STRING; /* signal that it is of string type */ for (;;) /* analyze it */ { if ((0 == *p) || ('\n' == *p)) /* end of line -> end of string */ { *s = 0; return(NGP_OK); } if ('\'' == *p) /* we have found doublequote */ { if ((0 == p[1]) || ('\n' == p[1]))/* doublequote is the last character in line */ { *s = 0; return(NGP_OK); } if (('\t' == p[1]) || (' ' == p[1])) /* duoblequote was string terminator */ { *s = 0; p++; break; } if ('\'' == p[1]) p++; /* doublequote is inside string, convert "" -> " */ } *(s++) = *(p++); /* compact string in place, necess. by "" -> " conversion */ } } else /* regular token */ { cl->value = p; /* set pointer to token */ cl->type = NGP_TTYPE_UNKNOWN; /* we dont know type at the moment */ for (;; p++) /* we need to find 1st whitespace */ { if ((0 == *p) || ('\n' == *p)) { *p = 0; return(NGP_OK); } if ((' ' == *p) || ('\t' == *p)) break; } if (*p) *(p++) = 0; /* found so terminate string with zero */ } for (;; p++) { if ((0 == *p) || ('\n' == *p)) return(NGP_OK); /* test if at end of string */ if ((' ' != *p) && ('\t' != *p)) break; /* skip whitespace */ } if ('/' == *p) /* no value specified, comment only */ { p++; if ((' ' == *p) || ('\t' == *p)) p++; cl->comment = p; for (s = cl->comment;; s++) /* filter out any EOS characters in comment */ { if ('\n' == *s) *s = 0; if (0 == *s) break; } return(NGP_OK); } cl->format = NGP_FORMAT_ERROR; return(NGP_OK); /* too many tokens ... */ } /* try to open include file. If open fails and fname does not specify absolute pathname, try to open fname in any directory specified in CFITSIO_INCLUDE_FILES environment variable. Finally try to open fname relative to ngp_master_dir, which is directory of top level include file */ int ngp_include_file(char *fname) /* try to open include file */ { char *p, *p2, *cp, *envar, envfiles[NGP_MAX_ENVFILES]; char *saveptr; if (NULL == fname) return(NGP_NUL_PTR); if (ngp_inclevel >= NGP_MAX_INCLUDE) /* too many include files */ return(NGP_INC_NESTING); if (NULL == (ngp_fp[ngp_inclevel] = fopen(fname, "r"))) { /* if simple open failed .. */ envar = getenv("CFITSIO_INCLUDE_FILES"); /* scan env. variable, and retry to open */ if (NULL != envar) /* is env. variable defined ? */ { strncpy(envfiles, envar, NGP_MAX_ENVFILES - 1); envfiles[NGP_MAX_ENVFILES - 1] = 0; /* copy search path to local variable, env. is fragile */ for (p2 = ffstrtok(envfiles, ":",&saveptr); NULL != p2; p2 = ffstrtok(NULL, ":",&saveptr)) { cp = (char *)ngp_alloc(strlen(fname) + strlen(p2) + 2); if (NULL == cp) return(NGP_NO_MEMORY); strcpy(cp, p2); #ifdef MSDOS strcat(cp, "\\"); /* abs. pathname for MSDOS */ #else strcat(cp, "/"); /* and for unix */ #endif strcat(cp, fname); ngp_fp[ngp_inclevel] = fopen(cp, "r"); ngp_free(cp); if (NULL != ngp_fp[ngp_inclevel]) break; } } if (NULL == ngp_fp[ngp_inclevel]) /* finally try to open relative to top level */ { #ifdef MSDOS if ('\\' == fname[0]) return(NGP_ERR_FOPEN); /* abs. pathname for MSDOS, does not support C:\\PATH */ #else if ('/' == fname[0]) return(NGP_ERR_FOPEN); /* and for unix */ #endif if (0 == ngp_master_dir[0]) return(NGP_ERR_FOPEN); p = ngp_alloc(strlen(fname) + strlen(ngp_master_dir) + 1); if (NULL == p) return(NGP_NO_MEMORY); strcpy(p, ngp_master_dir); /* construct composite pathname */ strcat(p, fname); /* comp = master + fname */ ngp_fp[ngp_inclevel] = fopen(p, "r");/* try to open composite */ ngp_free(p); /* we don't need buffer anymore */ if (NULL == ngp_fp[ngp_inclevel]) return(NGP_ERR_FOPEN); /* fail if error */ } } ngp_inclevel++; return(NGP_OK); } /* read line in the intelligent way. All \INCLUDE directives are handled, empty and comment line skipped. If this function returns NGP_OK, than decomposed line (name, type, value in proper type and comment) are stored in ngp_linkey structure. ignore_blank_lines parameter is zero when parser is inside GROUP or HDU definition. Nonzero otherwise. */ int ngp_read_line(int ignore_blank_lines) { int r, nc, savec; unsigned k; if (ngp_inclevel <= 0) /* do some sanity checking first */ { ngp_keyidx = NGP_TOKEN_EOF; /* no parents, so report error */ return(NGP_OK); } if (ngp_inclevel > NGP_MAX_INCLUDE) return(NGP_INC_NESTING); if (NULL == ngp_fp[ngp_inclevel - 1]) return(NGP_NUL_PTR); for (;;) { switch (r = ngp_read_line_buffered(ngp_fp[ngp_inclevel - 1])) { case NGP_EOF: ngp_inclevel--; /* end of file, revert to parent */ if (ngp_fp[ngp_inclevel]) /* we can close old file */ fclose(ngp_fp[ngp_inclevel]); ngp_fp[ngp_inclevel] = NULL; if (ngp_inclevel <= 0) { ngp_keyidx = NGP_TOKEN_EOF; /* no parents, so report error */ return(NGP_OK); } continue; case NGP_OK: if (ngp_curline.flags & NGP_LINE_REREAD) return(r); break; default: return(r); } switch (ngp_curline.line[0]) { case 0: if (0 == ignore_blank_lines) break; /* ignore empty lines if told so */ case '#': continue; /* ignore comment lines */ } r = ngp_extract_tokens(&ngp_curline); /* analyse line, extract tokens and comment */ if (NGP_OK != r) return(r); if (NULL == ngp_curline.name) continue; /* skip lines consisting only of whitespaces */ for (k = 0; k < strlen(ngp_curline.name); k++) { if ((ngp_curline.name[k] >= 'a') && (ngp_curline.name[k] <= 'z')) ngp_curline.name[k] += 'A' - 'a'; /* force keyword to be upper case */ if (k == 7) break; /* only first 8 chars are required to be upper case */ } for (k=0;; k++) /* find index of keyword in keyword table */ { if (NGP_TOKEN_UNKNOWN == ngp_tkdef[k].code) break; if (0 == strcmp(ngp_curline.name, ngp_tkdef[k].name)) break; } ngp_keyidx = ngp_tkdef[k].code; /* save this index, grammar parser will need this */ if (NGP_TOKEN_INCLUDE == ngp_keyidx) /* if this is \INCLUDE keyword, try to include file */ { if (NGP_OK != (r = ngp_include_file(ngp_curline.value))) return(r); continue; /* and read next line */ } ngp_linkey.type = NGP_TTYPE_UNKNOWN; /* now, get the keyword type, it's a long story ... */ if (NULL != ngp_curline.value) /* if no value given signal it */ { if (NGP_TTYPE_STRING == ngp_curline.type) /* string type test */ { ngp_linkey.type = NGP_TTYPE_STRING; ngp_linkey.value.s = ngp_curline.value; } if (NGP_TTYPE_UNKNOWN == ngp_linkey.type) /* bool type test */ { if ((!fits_strcasecmp("T", ngp_curline.value)) || (!fits_strcasecmp("F", ngp_curline.value))) { ngp_linkey.type = NGP_TTYPE_BOOL; ngp_linkey.value.b = (fits_strcasecmp("T", ngp_curline.value) ? 0 : 1); } } if (NGP_TTYPE_UNKNOWN == ngp_linkey.type) /* complex type test */ { if (2 == sscanf(ngp_curline.value, "(%lg,%lg)%n", &(ngp_linkey.value.c.re), &(ngp_linkey.value.c.im), &nc)) { if ((' ' == ngp_curline.value[nc]) || ('\t' == ngp_curline.value[nc]) || ('\n' == ngp_curline.value[nc]) || (0 == ngp_curline.value[nc])) { ngp_linkey.type = NGP_TTYPE_COMPLEX; } } } if (NGP_TTYPE_UNKNOWN == ngp_linkey.type) /* real type test */ { if (strchr(ngp_curline.value, '.') && (1 == sscanf(ngp_curline.value, "%lg%n", &(ngp_linkey.value.d), &nc))) { if ('D' == ngp_curline.value[nc]) { /* test if template used a 'D' rather than an 'E' as the exponent character (added by WDP in 12/2010) */ savec = nc; ngp_curline.value[nc] = 'E'; sscanf(ngp_curline.value, "%lg%n", &(ngp_linkey.value.d), &nc); if ((' ' == ngp_curline.value[nc]) || ('\t' == ngp_curline.value[nc]) || ('\n' == ngp_curline.value[nc]) || (0 == ngp_curline.value[nc])) { ngp_linkey.type = NGP_TTYPE_REAL; } else { /* no, this is not a real value */ ngp_curline.value[savec] = 'D'; /* restore the original D character */ } } else { if ((' ' == ngp_curline.value[nc]) || ('\t' == ngp_curline.value[nc]) || ('\n' == ngp_curline.value[nc]) || (0 == ngp_curline.value[nc])) { ngp_linkey.type = NGP_TTYPE_REAL; } } } } if (NGP_TTYPE_UNKNOWN == ngp_linkey.type) /* integer type test */ { if (1 == sscanf(ngp_curline.value, "%d%n", &(ngp_linkey.value.i), &nc)) { if ((' ' == ngp_curline.value[nc]) || ('\t' == ngp_curline.value[nc]) || ('\n' == ngp_curline.value[nc]) || (0 == ngp_curline.value[nc])) { ngp_linkey.type = NGP_TTYPE_INT; } } } if (NGP_TTYPE_UNKNOWN == ngp_linkey.type) /* force string type */ { ngp_linkey.type = NGP_TTYPE_STRING; ngp_linkey.value.s = ngp_curline.value; } } else { if (NGP_TTYPE_RAW == ngp_curline.type) ngp_linkey.type = NGP_TTYPE_RAW; else ngp_linkey.type = NGP_TTYPE_NULL; } if (NULL != ngp_curline.comment) { strncpy(ngp_linkey.comment, ngp_curline.comment, NGP_MAX_COMMENT); /* store comment */ ngp_linkey.comment[NGP_MAX_COMMENT - 1] = 0; } else { ngp_linkey.comment[0] = 0; } strncpy(ngp_linkey.name, ngp_curline.name, NGP_MAX_NAME); /* and keyword's name */ ngp_linkey.name[NGP_MAX_NAME - 1] = 0; if (strlen(ngp_linkey.name) > FLEN_KEYWORD) /* WDP: 20-Jun-2002: mod to support HIERARCH */ { return(NGP_BAD_ARG); /* cfitsio does not allow names > 8 chars */ } return(NGP_OK); /* we have valid non empty line, so return success */ } } /* check whether keyword can be written as is */ int ngp_keyword_is_write(NGP_TOKEN *ngp_tok) { int i, j, l, spc; /* indexed variables not to write */ static char *nm[] = { "NAXIS", "TFORM", "TTYPE", NULL } ; /* non indexed variables not allowed to write */ static char *nmni[] = { "SIMPLE", "XTENSION", "BITPIX", "NAXIS", "PCOUNT", "GCOUNT", "TFIELDS", "THEAP", "EXTEND", "EXTVER", NULL } ; if (NULL == ngp_tok) return(NGP_NUL_PTR); for (j = 0; ; j++) /* first check non indexed */ { if (NULL == nmni[j]) break; if (0 == strcmp(nmni[j], ngp_tok->name)) return(NGP_BAD_ARG); } for (j = 0; ; j++) /* now check indexed */ { if (NULL == nm[j]) return(NGP_OK); l = strlen(nm[j]); if ((l < 1) || (l > 5)) continue; if (0 == strncmp(nm[j], ngp_tok->name, l)) break; } if ((ngp_tok->name[l] < '1') || (ngp_tok->name[l] > '9')) return(NGP_OK); spc = 0; for (i = l + 1; i < 8; i++) { if (spc) { if (' ' != ngp_tok->name[i]) return(NGP_OK); } else { if ((ngp_tok->name[i] >= '0') && (ngp_tok->name[i] <= '9')) continue; if (' ' == ngp_tok->name[i]) { spc = 1; continue; } if (0 == ngp_tok->name[i]) break; return(NGP_OK); } } return(NGP_BAD_ARG); } /* write (almost) all keywords from given HDU to disk */ int ngp_keyword_all_write(NGP_HDU *ngph, fitsfile *ffp, int mode) { int i, r, ib; char buf[200]; long l; if (NULL == ngph) return(NGP_NUL_PTR); if (NULL == ffp) return(NGP_NUL_PTR); r = NGP_OK; for (i=0; itokcnt; i++) { r = ngp_keyword_is_write(&(ngph->tok[i])); if ((NGP_REALLY_ALL & mode) || (NGP_OK == r)) { switch (ngph->tok[i].type) { case NGP_TTYPE_BOOL: ib = ngph->tok[i].value.b; fits_write_key(ffp, TLOGICAL, ngph->tok[i].name, &ib, ngph->tok[i].comment, &r); break; case NGP_TTYPE_STRING: fits_write_key_longstr(ffp, ngph->tok[i].name, ngph->tok[i].value.s, ngph->tok[i].comment, &r); break; case NGP_TTYPE_INT: l = ngph->tok[i].value.i; /* bugfix - 22-Jan-99, BO - nonalignment of OSF/Alpha */ fits_write_key(ffp, TLONG, ngph->tok[i].name, &l, ngph->tok[i].comment, &r); break; case NGP_TTYPE_REAL: fits_write_key(ffp, TDOUBLE, ngph->tok[i].name, &(ngph->tok[i].value.d), ngph->tok[i].comment, &r); break; case NGP_TTYPE_COMPLEX: fits_write_key(ffp, TDBLCOMPLEX, ngph->tok[i].name, &(ngph->tok[i].value.c), ngph->tok[i].comment, &r); break; case NGP_TTYPE_NULL: fits_write_key_null(ffp, ngph->tok[i].name, ngph->tok[i].comment, &r); break; case NGP_TTYPE_RAW: if (0 == strcmp("HISTORY", ngph->tok[i].name)) { fits_write_history(ffp, ngph->tok[i].comment, &r); break; } if (0 == strcmp("COMMENT", ngph->tok[i].name)) { fits_write_comment(ffp, ngph->tok[i].comment, &r); break; } snprintf(buf,200, "%-8.8s%s", ngph->tok[i].name, ngph->tok[i].comment); fits_write_record(ffp, buf, &r); break; } } else if (NGP_BAD_ARG == r) /* enhancement 10 dec 2003, James Peachey: template comments replace defaults */ { r = NGP_OK; /* update comments of special keywords like TFORM */ if (ngph->tok[i].comment && *ngph->tok[i].comment) /* do not update with a blank comment */ { fits_modify_comment(ffp, ngph->tok[i].name, ngph->tok[i].comment, &r); } } else /* other problem, typically a blank token */ { r = NGP_OK; /* skip this token, but continue */ } if (r) return(r); } fits_set_hdustruc(ffp, &r); /* resync cfitsio */ return(r); } /* init HDU structure */ int ngp_hdu_init(NGP_HDU *ngph) { if (NULL == ngph) return(NGP_NUL_PTR); ngph->tok = NULL; ngph->tokcnt = 0; return(NGP_OK); } /* clear HDU structure */ int ngp_hdu_clear(NGP_HDU *ngph) { int i; if (NULL == ngph) return(NGP_NUL_PTR); for (i=0; itokcnt; i++) { if (NGP_TTYPE_STRING == ngph->tok[i].type) if (NULL != ngph->tok[i].value.s) { ngp_free(ngph->tok[i].value.s); ngph->tok[i].value.s = NULL; } } if (NULL != ngph->tok) ngp_free(ngph->tok); ngph->tok = NULL; ngph->tokcnt = 0; return(NGP_OK); } /* insert new token to HDU structure */ int ngp_hdu_insert_token(NGP_HDU *ngph, NGP_TOKEN *newtok) { NGP_TOKEN *tkp; if (NULL == ngph) return(NGP_NUL_PTR); if (NULL == newtok) return(NGP_NUL_PTR); if (0 == ngph->tokcnt) tkp = (NGP_TOKEN *)ngp_alloc((ngph->tokcnt + 1) * sizeof(NGP_TOKEN)); else tkp = (NGP_TOKEN *)ngp_realloc(ngph->tok, (ngph->tokcnt + 1) * sizeof(NGP_TOKEN)); if (NULL == tkp) return(NGP_NO_MEMORY); ngph->tok = tkp; ngph->tok[ngph->tokcnt] = *newtok; if (NGP_TTYPE_STRING == newtok->type) { if (NULL != newtok->value.s) { ngph->tok[ngph->tokcnt].value.s = (char *)ngp_alloc(1 + strlen(newtok->value.s)); if (NULL == ngph->tok[ngph->tokcnt].value.s) return(NGP_NO_MEMORY); strcpy(ngph->tok[ngph->tokcnt].value.s, newtok->value.s); } } ngph->tokcnt++; return(NGP_OK); } int ngp_append_columns(fitsfile *ff, NGP_HDU *ngph, int aftercol) { int r, i, j, exitflg, ngph_i; char *my_tform, *my_ttype; char ngph_ctmp; if (NULL == ff) return(NGP_NUL_PTR); if (NULL == ngph) return(NGP_NUL_PTR); if (0 == ngph->tokcnt) return(NGP_OK); /* nothing to do ! */ r = NGP_OK; exitflg = 0; for (j=aftercol; jtok[i].name, "TFORM%d%c", &ngph_i, &ngph_ctmp)) { if ((NGP_TTYPE_STRING == ngph->tok[i].type) && (ngph_i == (j + 1))) { my_tform = ngph->tok[i].value.s; } } else if (1 == sscanf(ngph->tok[i].name, "TTYPE%d%c", &ngph_i, &ngph_ctmp)) { if ((NGP_TTYPE_STRING == ngph->tok[i].type) && (ngph_i == (j + 1))) { my_ttype = ngph->tok[i].value.s; } } if ((NULL != my_tform) && (my_ttype[0])) break; if (i < (ngph->tokcnt - 1)) continue; exitflg = 1; break; } if ((NGP_OK == r) && (NULL != my_tform)) fits_insert_col(ff, j + 1, my_ttype, my_tform, &r); if ((NGP_OK != r) || exitflg) break; } return(r); } /* read complete HDU */ int ngp_read_xtension(fitsfile *ff, int parent_hn, int simple_mode) { int r, exflg, l, my_hn, tmp0, incrementor_index, i, j; int ngph_dim, ngph_bitpix, ngph_node_type, my_version; char incrementor_name[NGP_MAX_STRING], ngph_ctmp; char *ngph_extname = 0; long ngph_size[NGP_MAX_ARRAY_DIM]; NGP_HDU ngph; long lv; incrementor_name[0] = 0; /* signal no keyword+'#' found yet */ incrementor_index = 0; if (NGP_OK != (r = ngp_hdu_init(&ngph))) return(r); if (NGP_OK != (r = ngp_read_line(0))) return(r); /* EOF always means error here */ switch (NGP_XTENSION_SIMPLE & simple_mode) { case 0: if (NGP_TOKEN_XTENSION != ngp_keyidx) return(NGP_TOKEN_NOT_EXPECT); break; default: if (NGP_TOKEN_SIMPLE != ngp_keyidx) return(NGP_TOKEN_NOT_EXPECT); break; } if (NGP_OK != (r = ngp_hdu_insert_token(&ngph, &ngp_linkey))) return(r); for (;;) { if (NGP_OK != (r = ngp_read_line(0))) return(r); /* EOF always means error here */ exflg = 0; switch (ngp_keyidx) { case NGP_TOKEN_SIMPLE: r = NGP_TOKEN_NOT_EXPECT; break; case NGP_TOKEN_END: case NGP_TOKEN_XTENSION: case NGP_TOKEN_GROUP: r = ngp_unread_line(); /* WARNING - not break here .... */ case NGP_TOKEN_EOF: exflg = 1; break; default: l = strlen(ngp_linkey.name); if ((l >= 2) && (l <= 6)) { if ('#' == ngp_linkey.name[l - 1]) { if (0 == incrementor_name[0]) { memcpy(incrementor_name, ngp_linkey.name, l - 1); incrementor_name[l - 1] = 0; } if (((l - 1) == (int)strlen(incrementor_name)) && (0 == memcmp(incrementor_name, ngp_linkey.name, l - 1))) { incrementor_index++; } snprintf(ngp_linkey.name + l - 1, NGP_MAX_NAME-l+1,"%d", incrementor_index); } } r = ngp_hdu_insert_token(&ngph, &ngp_linkey); break; } if ((NGP_OK != r) || exflg) break; } if (NGP_OK == r) { /* we should scan keywords, and calculate HDU's */ /* structure ourselves .... */ ngph_node_type = NGP_NODE_INVALID; /* init variables */ ngph_bitpix = 0; ngph_extname = NULL; for (i=0; i=1) && (j <= NGP_MAX_ARRAY_DIM)) { ngph_size[j - 1] = ngph.tok[i].value.i; } } } switch (ngph_node_type) { case NGP_NODE_IMAGE: if (NGP_XTENSION_FIRST == ((NGP_XTENSION_FIRST | NGP_XTENSION_SIMPLE) & simple_mode)) { /* if caller signals that this is 1st HDU in file */ /* and it is IMAGE defined with XTENSION, then we */ /* need create dummy Primary HDU */ fits_create_img(ff, 16, 0, NULL, &r); } /* create image */ fits_create_img(ff, ngph_bitpix, ngph_dim, ngph_size, &r); /* update keywords */ if (NGP_OK == r) r = ngp_keyword_all_write(&ngph, ff, NGP_NON_SYSTEM_ONLY); break; case NGP_NODE_ATABLE: case NGP_NODE_BTABLE: /* create table, 0 rows and 0 columns for the moment */ fits_create_tbl(ff, ((NGP_NODE_ATABLE == ngph_node_type) ? ASCII_TBL : BINARY_TBL), 0, 0, NULL, NULL, NULL, NULL, &r); if (NGP_OK != r) break; /* add columns ... */ r = ngp_append_columns(ff, &ngph, 0); if (NGP_OK != r) break; /* add remaining keywords */ r = ngp_keyword_all_write(&ngph, ff, NGP_NON_SYSTEM_ONLY); if (NGP_OK != r) break; /* if requested add rows */ if (ngph_size[1] > 0) fits_insert_rows(ff, 0, ngph_size[1], &r); break; default: r = NGP_BAD_ARG; break; } } if ((NGP_OK == r) && (NULL != ngph_extname)) { r = ngp_get_extver(ngph_extname, &my_version); /* write correct ext version number */ lv = my_version; /* bugfix - 22-Jan-99, BO - nonalignment of OSF/Alpha */ fits_write_key(ff, TLONG, "EXTVER", &lv, "auto assigned by template parser", &r); } if (NGP_OK == r) { if (parent_hn > 0) { fits_get_hdu_num(ff, &my_hn); fits_movabs_hdu(ff, parent_hn, &tmp0, &r); /* link us to parent */ fits_add_group_member(ff, NULL, my_hn, &r); fits_movabs_hdu(ff, my_hn, &tmp0, &r); if (NGP_OK != r) return(r); } } if (NGP_OK != r) /* in case of error - delete hdu */ { tmp0 = 0; fits_delete_hdu(ff, NULL, &tmp0); } ngp_hdu_clear(&ngph); return(r); } /* read complete GROUP */ int ngp_read_group(fitsfile *ff, char *grpname, int parent_hn) { int r, exitflg, l, my_hn, tmp0, incrementor_index; char grnm[NGP_MAX_STRING]; /* keyword holding group name */ char incrementor_name[NGP_MAX_STRING]; NGP_HDU ngph; incrementor_name[0] = 0; /* signal no keyword+'#' found yet */ incrementor_index = 6; /* first 6 cols are used by group */ ngp_grplevel++; if (NGP_OK != (r = ngp_hdu_init(&ngph))) return(r); r = NGP_OK; if (NGP_OK != (r = fits_create_group(ff, grpname, GT_ID_ALL_URI, &r))) return(r); fits_get_hdu_num(ff, &my_hn); if (parent_hn > 0) { fits_movabs_hdu(ff, parent_hn, &tmp0, &r); /* link us to parent */ fits_add_group_member(ff, NULL, my_hn, &r); fits_movabs_hdu(ff, my_hn, &tmp0, &r); if (NGP_OK != r) return(r); } for (exitflg = 0; 0 == exitflg;) { if (NGP_OK != (r = ngp_read_line(0))) break; /* EOF always means error here */ switch (ngp_keyidx) { case NGP_TOKEN_SIMPLE: case NGP_TOKEN_EOF: r = NGP_TOKEN_NOT_EXPECT; break; case NGP_TOKEN_END: ngp_grplevel--; exitflg = 1; break; case NGP_TOKEN_GROUP: if (NGP_TTYPE_STRING == ngp_linkey.type) { strncpy(grnm, ngp_linkey.value.s, NGP_MAX_STRING); } else { snprintf(grnm, NGP_MAX_STRING,"DEFAULT_GROUP_%d", master_grp_idx++); } grnm[NGP_MAX_STRING - 1] = 0; r = ngp_read_group(ff, grnm, my_hn); break; /* we can have many subsequent GROUP defs */ case NGP_TOKEN_XTENSION: r = ngp_unread_line(); if (NGP_OK != r) break; r = ngp_read_xtension(ff, my_hn, 0); break; /* we can have many subsequent HDU defs */ default: l = strlen(ngp_linkey.name); if ((l >= 2) && (l <= 6)) { if ('#' == ngp_linkey.name[l - 1]) { if (0 == incrementor_name[0]) { memcpy(incrementor_name, ngp_linkey.name, l - 1); incrementor_name[l - 1] = 0; } if (((l - 1) == (int)strlen(incrementor_name)) && (0 == memcmp(incrementor_name, ngp_linkey.name, l - 1))) { incrementor_index++; } snprintf(ngp_linkey.name + l - 1, NGP_MAX_NAME-l+1,"%d", incrementor_index); } } r = ngp_hdu_insert_token(&ngph, &ngp_linkey); break; /* here we can add keyword */ } if (NGP_OK != r) break; } fits_movabs_hdu(ff, my_hn, &tmp0, &r); /* back to our HDU */ if (NGP_OK == r) /* create additional columns, if requested */ r = ngp_append_columns(ff, &ngph, 6); if (NGP_OK == r) /* and write keywords */ r = ngp_keyword_all_write(&ngph, ff, NGP_NON_SYSTEM_ONLY); if (NGP_OK != r) /* delete group in case of error */ { tmp0 = 0; fits_remove_group(ff, OPT_RM_GPT, &tmp0); } ngp_hdu_clear(&ngph); /* we are done with this HDU, so delete it */ return(r); } /* top level API functions */ /* read whole template. ff should point to the opened empty fits file. */ int fits_execute_template(fitsfile *ff, char *ngp_template, int *status) { int r, exit_flg, first_extension, i, my_hn, tmp0, keys_exist, more_keys, used_ver; char grnm[NGP_MAX_STRING], used_name[NGP_MAX_STRING]; long luv; if (NULL == status) return(NGP_NUL_PTR); if (NGP_OK != *status) return(*status); /* This function uses many global variables (local to this file) and therefore is not thread-safe. */ FFLOCK; if ((NULL == ff) || (NULL == ngp_template)) { *status = NGP_NUL_PTR; FFUNLOCK; return(*status); } ngp_inclevel = 0; /* initialize things, not all should be zero */ ngp_grplevel = 0; master_grp_idx = 1; exit_flg = 0; ngp_master_dir[0] = 0; /* this should be before 1st call to ngp_include_file */ first_extension = 1; /* we need to create PHDU */ if (NGP_OK != (r = ngp_delete_extver_tab())) { *status = r; FFUNLOCK; return(r); } fits_get_hdu_num(ff, &my_hn); /* our HDU position */ if (my_hn <= 1) /* check whether we really need to create PHDU */ { fits_movabs_hdu(ff, 1, &tmp0, status); fits_get_hdrspace(ff, &keys_exist, &more_keys, status); fits_movabs_hdu(ff, my_hn, &tmp0, status); if (NGP_OK != *status) /* error here means file is corrupted */ { FFUNLOCK; return(*status); } if (keys_exist > 0) first_extension = 0; /* if keywords exist assume PHDU already exist */ } else { first_extension = 0; /* PHDU (followed by 1+ extensions) exist */ for (i = 2; i<= my_hn; i++) { *status = NGP_OK; fits_movabs_hdu(ff, 1, &tmp0, status); if (NGP_OK != *status) break; fits_read_key(ff, TSTRING, "EXTNAME", used_name, NULL, status); if (NGP_OK != *status) continue; fits_read_key(ff, TLONG, "EXTVER", &luv, NULL, status); used_ver = luv; /* bugfix - 22-Jan-99, BO - nonalignment of OSF/Alpha */ if (VALUE_UNDEFINED == *status) { used_ver = 1; *status = NGP_OK; } if (NGP_OK == *status) *status = ngp_set_extver(used_name, used_ver); } fits_movabs_hdu(ff, my_hn, &tmp0, status); } if (NGP_OK != *status) { FFUNLOCK; return(*status); } if (NGP_OK != (*status = ngp_include_file(ngp_template))) { FFUNLOCK; return(*status); } for (i = strlen(ngp_template) - 1; i >= 0; i--) /* strlen is > 0, otherwise fopen failed */ { #ifdef MSDOS if ('\\' == ngp_template[i]) break; #else if ('/' == ngp_template[i]) break; #endif } i++; if (i > (NGP_MAX_FNAME - 1)) i = NGP_MAX_FNAME - 1; if (i > 0) { memcpy(ngp_master_dir, ngp_template, i); ngp_master_dir[i] = 0; } for (;;) { if (NGP_OK != (r = ngp_read_line(1))) break; /* EOF always means error here */ switch (ngp_keyidx) { case NGP_TOKEN_SIMPLE: if (0 == first_extension) /* simple only allowed in first HDU */ { r = NGP_TOKEN_NOT_EXPECT; break; } if (NGP_OK != (r = ngp_unread_line())) break; r = ngp_read_xtension(ff, 0, NGP_XTENSION_SIMPLE | NGP_XTENSION_FIRST); first_extension = 0; break; case NGP_TOKEN_XTENSION: if (NGP_OK != (r = ngp_unread_line())) break; r = ngp_read_xtension(ff, 0, (first_extension ? NGP_XTENSION_FIRST : 0)); first_extension = 0; break; case NGP_TOKEN_GROUP: if (NGP_TTYPE_STRING == ngp_linkey.type) { strncpy(grnm, ngp_linkey.value.s, NGP_MAX_STRING); } else { snprintf(grnm,NGP_MAX_STRING, "DEFAULT_GROUP_%d", master_grp_idx++); } grnm[NGP_MAX_STRING - 1] = 0; r = ngp_read_group(ff, grnm, 0); first_extension = 0; break; case NGP_TOKEN_EOF: exit_flg = 1; break; default: r = NGP_TOKEN_NOT_EXPECT; break; } if (exit_flg || (NGP_OK != r)) break; } /* all top level HDUs up to faulty one are left intact in case of i/o error. It is up to the caller to call fits_close_file or fits_delete_file when this function returns error. */ ngp_free_line(); /* deallocate last line (if any) */ ngp_free_prevline(); /* deallocate cached line (if any) */ ngp_delete_extver_tab(); /* delete extver table (if present), error ignored */ *status = r; FFUNLOCK; return(r); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/grparser.h0000644000175100001710000001313500000000000020124 0ustar00vstsdocker/* T E M P L A T E P A R S E R H E A D E R F I L E ===================================================== by Jerzy.Borkowski@obs.unige.ch Integral Science Data Center ch. d'Ecogia 16 1290 Versoix Switzerland 14-Oct-98: initial release 16-Oct-98: reference to fitsio.h removed, also removed strings after #endif directives to make gcc -Wall not to complain 20-Oct-98: added declarations NGP_XTENSION_SIMPLE and NGP_XTENSION_FIRST 24-Oct-98: prototype of ngp_read_line() function updated. 22-Jan-99: prototype for ngp_set_extver() function added. 20-Jun-2002 Wm Pence, added support for the HIERARCH keyword convention (changed NGP_MAX_NAME from (20) to FLEN_KEYWORD) */ #ifndef GRPARSER_H_INCLUDED #define GRPARSER_H_INCLUDED #ifdef __cplusplus extern "C" { #endif /* error codes - now defined in fitsio.h */ /* common constants definitions */ #define NGP_ALLOCCHUNK (1000) #define NGP_MAX_INCLUDE (10) /* include file nesting limit */ #define NGP_MAX_COMMENT (80) /* max size for comment */ #define NGP_MAX_NAME FLEN_KEYWORD /* max size for KEYWORD (FITS limits it to 8 chars) */ /* except HIERARCH can have longer effective keyword names */ #define NGP_MAX_STRING (80) /* max size for various strings */ #define NGP_MAX_ARRAY_DIM (999) /* max. number of dimensions in array */ #define NGP_MAX_FNAME (1000) /* max size of combined path+fname */ #define NGP_MAX_ENVFILES (10000) /* max size of CFITSIO_INCLUDE_FILES env. variable */ #define NGP_TOKEN_UNKNOWN (-1) /* token type unknown */ #define NGP_TOKEN_INCLUDE (0) /* \INCLUDE token */ #define NGP_TOKEN_GROUP (1) /* \GROUP token */ #define NGP_TOKEN_END (2) /* \END token */ #define NGP_TOKEN_XTENSION (3) /* XTENSION token */ #define NGP_TOKEN_SIMPLE (4) /* SIMPLE token */ #define NGP_TOKEN_EOF (5) /* End Of File pseudo token */ #define NGP_TTYPE_UNKNOWN (0) /* undef (yet) token type - invalid to print/write to disk */ #define NGP_TTYPE_BOOL (1) /* boolean, it is 'T' or 'F' */ #define NGP_TTYPE_STRING (2) /* something withing "" or starting with letter */ #define NGP_TTYPE_INT (3) /* starting with digit and not with '.' */ #define NGP_TTYPE_REAL (4) /* digits + '.' */ #define NGP_TTYPE_COMPLEX (5) /* 2 reals, separated with ',' */ #define NGP_TTYPE_NULL (6) /* NULL token, format is : NAME = / comment */ #define NGP_TTYPE_RAW (7) /* HISTORY/COMMENT/8SPACES + comment string without / */ #define NGP_FOUND_EQUAL_SIGN (1) /* line contains '=' after keyword name */ #define NGP_FORMAT_OK (0) /* line format OK */ #define NGP_FORMAT_ERROR (1) /* line format error */ #define NGP_NODE_INVALID (0) /* default node type - invalid (to catch errors) */ #define NGP_NODE_IMAGE (1) /* IMAGE type */ #define NGP_NODE_ATABLE (2) /* ASCII table type */ #define NGP_NODE_BTABLE (3) /* BINARY table type */ #define NGP_NON_SYSTEM_ONLY (0) /* save all keywords except NAXIS,BITPIX,etc.. */ #define NGP_REALLY_ALL (1) /* save really all keywords */ #define NGP_XTENSION_SIMPLE (1) /* HDU defined with SIMPLE T */ #define NGP_XTENSION_FIRST (2) /* this is first extension in template */ #define NGP_LINE_REREAD (1) /* reread line */ #define NGP_BITPIX_INVALID (-12345) /* default BITPIX (to catch errors) */ /* common macro definitions */ #ifdef NGP_PARSER_DEBUG_MALLOC #define ngp_alloc(x) dal_malloc(x) #define ngp_free(x) dal_free(x) #define ngp_realloc(x,y) dal_realloc(x,y) #else #define ngp_alloc(x) malloc(x) #define ngp_free(x) free(x) #define ngp_realloc(x,y) realloc(x,y) #endif /* type definitions */ typedef struct NGP_RAW_LINE_STRUCT { char *line; char *name; char *value; int type; char *comment; int format; int flags; } NGP_RAW_LINE; typedef union NGP_TOKVAL_UNION { char *s; /* space allocated separately, be careful !!! */ char b; int i; double d; struct NGP_COMPLEX_STRUCT { double re; double im; } c; /* complex value */ } NGP_TOKVAL; typedef struct NGP_TOKEN_STRUCT { int type; char name[NGP_MAX_NAME]; NGP_TOKVAL value; char comment[NGP_MAX_COMMENT]; } NGP_TOKEN; typedef struct NGP_HDU_STRUCT { int tokcnt; NGP_TOKEN *tok; } NGP_HDU; typedef struct NGP_TKDEF_STRUCT { char *name; int code; } NGP_TKDEF; typedef struct NGP_EXTVER_TAB_STRUCT { char *extname; int version; } NGP_EXTVER_TAB; /* globally visible variables declarations */ extern NGP_RAW_LINE ngp_curline; extern NGP_RAW_LINE ngp_prevline; extern int ngp_extver_tab_size; extern NGP_EXTVER_TAB *ngp_extver_tab; /* globally visible functions declarations */ int ngp_get_extver(char *extname, int *version); int ngp_set_extver(char *extname, int version); int ngp_delete_extver_tab(void); int ngp_line_from_file(FILE *fp, char **p); int ngp_free_line(void); int ngp_free_prevline(void); int ngp_read_line_buffered(FILE *fp); int ngp_unread_line(void); int ngp_extract_tokens(NGP_RAW_LINE *cl); int ngp_include_file(char *fname); int ngp_read_line(int ignore_blank_lines); int ngp_keyword_is_write(NGP_TOKEN *ngp_tok); int ngp_keyword_all_write(NGP_HDU *ngph, fitsfile *ffp, int mode); int ngp_hdu_init(NGP_HDU *ngph); int ngp_hdu_clear(NGP_HDU *ngph); int ngp_hdu_insert_token(NGP_HDU *ngph, NGP_TOKEN *newtok); int ngp_append_columns(fitsfile *ff, NGP_HDU *ngph, int aftercol); int ngp_read_xtension(fitsfile *ff, int parent_hn, int simple_mode); int ngp_read_group(fitsfile *ff, char *grpname, int parent_hn); /* top level API function - now defined in fitsio.h */ #ifdef __cplusplus } #endif #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/histo.c0000644000175100001710000025144400000000000017427 0ustar00vstsdocker/* Globally defined histogram parameters */ #include #include #include #include #include "fitsio2.h" typedef struct { /* Structure holding all the histogramming information */ union { /* the iterator work functions (ffwritehist, ffcalchist) */ char *b; /* need to do their job... passed via *userPointer. */ short *i; int *j; float *r; double *d; } hist; fitsfile *tblptr; int haxis, hcolnum[4], himagetype; long haxis1, haxis2, haxis3, haxis4; double amin1, amin2, amin3, amin4; double maxbin1, maxbin2, maxbin3, maxbin4; double binsize1, binsize2, binsize3, binsize4; int wtrecip, wtcolnum; double weight; char *rowselector; } histType; /*--------------------------------------------------------------------------*/ int ffbins(char *binspec, /* I - binning specification */ int *imagetype, /* O - image type, TINT or TSHORT */ int *histaxis, /* O - no. of axes in the histogram */ char colname[4][FLEN_VALUE], /* column name for axis */ double *minin, /* minimum value for each axis */ double *maxin, /* maximum value for each axis */ double *binsizein, /* size of bins on each axis */ char minname[4][FLEN_VALUE], /* keyword name for min */ char maxname[4][FLEN_VALUE], /* keyword name for max */ char binname[4][FLEN_VALUE], /* keyword name for binsize */ double *wt, /* weighting factor */ char *wtname, /* keyword or column name for weight */ int *recip, /* the reciprocal of the weight? */ int *status) { /* Parse the input binning specification string, returning the binning parameters. Supports up to 4 dimensions. The binspec string has one of these forms: bin binsize - 2D histogram with binsize on each axis bin xcol - 1D histogram on column xcol bin (xcol, ycol) = binsize - 2D histogram with binsize on each axis bin x=min:max:size, y=min:max:size, z..., t... bin x=:max, y=::size bin x=size, y=min::size most other reasonable combinations are supported. */ int ii, slen, defaulttype; char *ptr, tmpname[FLEN_VALUE], *file_expr = NULL; double dummy; if (*status > 0) return(*status); /* set the default values */ *histaxis = 2; *imagetype = TINT; defaulttype = 1; *wt = 1.; *recip = 0; *wtname = '\0'; /* set default values */ for (ii = 0; ii < 4; ii++) { *colname[ii] = '\0'; *minname[ii] = '\0'; *maxname[ii] = '\0'; *binname[ii] = '\0'; minin[ii] = DOUBLENULLVALUE; /* undefined values */ maxin[ii] = DOUBLENULLVALUE; binsizein[ii] = DOUBLENULLVALUE; } ptr = binspec + 3; /* skip over 'bin' */ if (*ptr == 'i' ) /* bini */ { *imagetype = TSHORT; defaulttype = 0; ptr++; } else if (*ptr == 'j' ) /* binj; same as default */ { defaulttype = 0; ptr ++; } else if (*ptr == 'r' ) /* binr */ { *imagetype = TFLOAT; defaulttype = 0; ptr ++; } else if (*ptr == 'd' ) /* bind */ { *imagetype = TDOUBLE; defaulttype = 0; ptr ++; } else if (*ptr == 'b' ) /* binb */ { *imagetype = TBYTE; defaulttype = 0; ptr ++; } if (*ptr == '\0') /* use all defaults for other parameters */ return(*status); else if (*ptr != ' ') /* must be at least one blank */ { ffpmsg("binning specification syntax error:"); ffpmsg(binspec); return(*status = URL_PARSE_ERROR); } while (*ptr == ' ') /* skip over blanks */ ptr++; if (*ptr == '\0') /* no other parameters; use defaults */ return(*status); /* Check if need to import expression from a file */ if( *ptr=='@' ) { if( ffimport_file( ptr+1, &file_expr, status ) ) return(*status); ptr = file_expr; while (*ptr == ' ') ptr++; /* skip leading white space... again */ } if (*ptr == '(' ) { /* this must be the opening parenthesis around a list of column */ /* names, optionally followed by a '=' and the binning spec. */ for (ii = 0; ii < 4; ii++) { ptr++; /* skip over the '(', ',', or ' ') */ while (*ptr == ' ') /* skip over blanks */ ptr++; slen = strcspn(ptr, " ,)"); strncat(colname[ii], ptr, slen); /* copy 1st column name */ ptr += slen; while (*ptr == ' ') /* skip over blanks */ ptr++; if (*ptr == ')' ) /* end of the list of names */ { *histaxis = ii + 1; break; } } if (ii == 4) /* too many names in the list , or missing ')' */ { ffpmsg( "binning specification has too many column names or is missing closing ')':"); ffpmsg(binspec); if( file_expr ) free( file_expr ); return(*status = URL_PARSE_ERROR); } ptr++; /* skip over the closing parenthesis */ while (*ptr == ' ') /* skip over blanks */ ptr++; if (*ptr == '\0') { if( file_expr ) free( file_expr ); return(*status); /* parsed the entire string */ } else if (*ptr != '=') /* must be an equals sign now*/ { ffpmsg("illegal binning specification in URL:"); ffpmsg(" an equals sign '=' must follow the column names"); ffpmsg(binspec); if( file_expr ) free( file_expr ); return(*status = URL_PARSE_ERROR); } ptr++; /* skip over the equals sign */ while (*ptr == ' ') /* skip over blanks */ ptr++; /* get the single range specification for all the columns */ ffbinr(&ptr, tmpname, minin, maxin, binsizein, minname[0], maxname[0], binname[0], status); if (*status > 0) { ffpmsg("illegal binning specification in URL:"); ffpmsg(binspec); if( file_expr ) free( file_expr ); return(*status); } for (ii = 1; ii < *histaxis; ii++) { minin[ii] = minin[0]; maxin[ii] = maxin[0]; binsizein[ii] = binsizein[0]; strcpy(minname[ii], minname[0]); strcpy(maxname[ii], maxname[0]); strcpy(binname[ii], binname[0]); } while (*ptr == ' ') /* skip over blanks */ ptr++; if (*ptr == ';') goto getweight; /* a weighting factor is specified */ if (*ptr != '\0') /* must have reached end of string */ { ffpmsg("illegal syntax after binning range specification in URL:"); ffpmsg(binspec); if( file_expr ) free( file_expr ); return(*status = URL_PARSE_ERROR); } return(*status); } /* end of case with list of column names in ( ) */ /* if we've reached this point, then the binning specification */ /* must be of the form: XCOL = min:max:binsize, YCOL = ... */ /* where the column name followed by '=' are optional. */ /* If the column name is not specified, then use the default name */ for (ii = 0; ii < 4; ii++) /* allow up to 4 histogram dimensions */ { ffbinr(&ptr, colname[ii], &minin[ii], &maxin[ii], &binsizein[ii], minname[ii], maxname[ii], binname[ii], status); if (*status > 0) { ffpmsg("illegal syntax in binning range specification in URL:"); ffpmsg(binspec); if( file_expr ) free( file_expr ); return(*status); } if (*ptr == '\0' || *ptr == ';') break; /* reached the end of the string */ if (*ptr == ' ') { while (*ptr == ' ') /* skip over blanks */ ptr++; if (*ptr == '\0' || *ptr == ';') break; /* reached the end of the string */ if (*ptr == ',') ptr++; /* comma separates the next column specification */ } else if (*ptr == ',') { ptr++; /* comma separates the next column specification */ } else { ffpmsg("illegal characters following binning specification in URL:"); ffpmsg(binspec); if( file_expr ) free( file_expr ); return(*status = URL_PARSE_ERROR); } } if (ii == 4) { /* there are yet more characters in the string */ ffpmsg("illegal binning specification in URL:"); ffpmsg("apparently greater than 4 histogram dimensions"); ffpmsg(binspec); return(*status = URL_PARSE_ERROR); } else *histaxis = ii + 1; /* special case: if a single number was entered it should be */ /* interpreted as the binning factor for the default X and Y axes */ if (*histaxis == 1 && *colname[0] == '\0' && minin[0] == DOUBLENULLVALUE && maxin[0] == DOUBLENULLVALUE) { *histaxis = 2; binsizein[1] = binsizein[0]; } getweight: if (*ptr == ';') /* looks like a weighting factor is given */ { ptr++; while (*ptr == ' ') /* skip over blanks */ ptr++; recip = 0; if (*ptr == '/') { *recip = 1; /* the reciprocal of the weight is entered */ ptr++; while (*ptr == ' ') /* skip over blanks */ ptr++; } /* parse the weight as though it were a binrange. */ /* either a column name or a numerical value will be returned */ ffbinr(&ptr, wtname, &dummy, &dummy, wt, tmpname, tmpname, tmpname, status); if (*status > 0) { ffpmsg("illegal binning weight specification in URL:"); ffpmsg(binspec); if( file_expr ) free( file_expr ); return(*status); } /* creat a float datatype histogram by default, if weight */ /* factor is not = 1.0 */ if ( (defaulttype && *wt != 1.0) || (defaulttype && *wtname) ) *imagetype = TFLOAT; } while (*ptr == ' ') /* skip over blanks */ ptr++; if (*ptr != '\0') /* should have reached the end of string */ { ffpmsg("illegal syntax after binning weight specification in URL:"); ffpmsg(binspec); *status = URL_PARSE_ERROR; } if( file_expr ) free( file_expr ); return(*status); } /*--------------------------------------------------------------------------*/ int ffbinr(char **ptr, char *colname, double *minin, double *maxin, double *binsizein, char *minname, char *maxname, char *binname, int *status) /* Parse the input binning range specification string, returning the column name, histogram min and max values, and bin size. */ { int slen, isanumber=0; char *token=0; if (*status > 0) return(*status); slen = fits_get_token2(ptr, " ,=:;", &token, &isanumber, status); /* get 1st token */ if ((*status) || (slen == 0 && (**ptr == '\0' || **ptr == ',' || **ptr == ';')) ) return(*status); /* a null range string */ if (!isanumber && **ptr != ':') { /* this looks like the column name */ /* Check for case where col name string is empty but '=' is still there (indicating a following specification string). Musn't enter this block as token would not have been allocated. */ if (token) { if (strlen(token) > FLEN_VALUE-1) { ffpmsg("column name too long (ffbinr)"); free(token); return(*status=PARSE_SYNTAX_ERR); } if (token[0] == '#' && isdigit((int) token[1]) ) { /* omit the leading '#' in the column number */ strcpy(colname, token+1); } else strcpy(colname, token); free(token); token=0; } while (**ptr == ' ') /* skip over blanks */ (*ptr)++; if (**ptr != '=') return(*status); /* reached the end */ (*ptr)++; /* skip over the = sign */ while (**ptr == ' ') /* skip over blanks */ (*ptr)++; /* get specification info */ slen = fits_get_token2(ptr, " ,:;", &token, &isanumber, status); if (*status) return(*status); } if (**ptr != ':') { /* This is the first token, and since it is not followed by a ':' this must be the binsize token. Or it could be empty. */ if (token) { if (!isanumber) { if (strlen(token) > FLEN_VALUE-1) { ffpmsg("binname too long (ffbinr)"); free(token); return(*status=PARSE_SYNTAX_ERR); } strcpy(binname, token); } else *binsizein = strtod(token, NULL); free(token); } return(*status); /* reached the end */ } else { /* the token contains the min value */ if (slen) { if (!isanumber) { if (strlen(token) > FLEN_VALUE-1) { ffpmsg("minname too long (ffbinr)"); free(token); return(*status=PARSE_SYNTAX_ERR); } strcpy(minname, token); } else *minin = strtod(token, NULL); free(token); token=0; } } (*ptr)++; /* skip the colon between the min and max values */ slen = fits_get_token2(ptr, " ,:;", &token, &isanumber, status); /* get token */ if (*status) return(*status); /* the token contains the max value */ if (slen) { if (!isanumber) { if (strlen(token) > FLEN_VALUE-1) { ffpmsg("maxname too long (ffbinr)"); free(token); return(*status=PARSE_SYNTAX_ERR); } strcpy(maxname, token); } else *maxin = strtod(token, NULL); free(token); token=0; } if (**ptr != ':') { free(token); return(*status); /* reached the end; no binsize token */ } (*ptr)++; /* skip the colon between the max and binsize values */ slen = fits_get_token2(ptr, " ,:;", &token, &isanumber, status); /* get token */ if (*status) return(*status); /* the token contains the binsize value */ if (slen) { if (!isanumber) { if (strlen(token) > FLEN_VALUE-1) { ffpmsg("binname too long (ffbinr)"); free(token); return(*status=PARSE_SYNTAX_ERR); } strcpy(binname, token); } else *binsizein = strtod(token, NULL); free(token); } return(*status); } /*--------------------------------------------------------------------------*/ int ffhist2(fitsfile **fptr, /* IO - pointer to table with X and Y cols; */ /* on output, points to histogram image */ char *outfile, /* I - name for the output histogram file */ int imagetype, /* I - datatype for image: TINT, TSHORT, etc */ int naxis, /* I - number of axes in the histogram image */ char colname[4][FLEN_VALUE], /* I - column names */ double *minin, /* I - minimum histogram value, for each axis */ double *maxin, /* I - maximum histogram value, for each axis */ double *binsizein, /* I - bin size along each axis */ char minname[4][FLEN_VALUE], /* I - optional keywords for min */ char maxname[4][FLEN_VALUE], /* I - optional keywords for max */ char binname[4][FLEN_VALUE], /* I - optional keywords for binsize */ double weightin, /* I - binning weighting factor */ char wtcol[FLEN_VALUE], /* I - optional keyword or col for weight*/ int recip, /* I - use reciprocal of the weight? */ char *selectrow, /* I - optional array (length = no. of */ /* rows in the table). If the element is true */ /* then the corresponding row of the table will*/ /* be included in the histogram, otherwise the */ /* row will be skipped. Ingnored if *selectrow*/ /* is equal to NULL. */ int *status) { fitsfile *histptr; int bitpix, colnum[4], wtcolnum; long haxes[4]; double amin[4], amax[4], binsize[4], weight; if (*status > 0) return(*status); if (naxis > 4) { ffpmsg("histogram has more than 4 dimensions"); return(*status = BAD_DIMEN); } /* reset position to the correct HDU if necessary */ if ((*fptr)->HDUposition != ((*fptr)->Fptr)->curhdu) ffmahd(*fptr, ((*fptr)->HDUposition) + 1, NULL, status); if (imagetype == TBYTE) bitpix = BYTE_IMG; else if (imagetype == TSHORT) bitpix = SHORT_IMG; else if (imagetype == TINT) bitpix = LONG_IMG; else if (imagetype == TFLOAT) bitpix = FLOAT_IMG; else if (imagetype == TDOUBLE) bitpix = DOUBLE_IMG; else return(*status = BAD_DATATYPE); /* Calculate the binning parameters: */ /* columm numbers, axes length, min values, max values, and binsizes. */ if (fits_calc_binningd( *fptr, naxis, colname, minin, maxin, binsizein, minname, maxname, binname, colnum, haxes, amin, amax, binsize, status) > 0) { ffpmsg("failed to determine binning parameters"); return(*status); } /* get the histogramming weighting factor, if any */ if (*wtcol) { /* first, look for a keyword with the weight value */ if (ffgky(*fptr, TDOUBLE, wtcol, &weight, NULL, status) ) { /* not a keyword, so look for column with this name */ *status = 0; /* get the column number in the table */ if (ffgcno(*fptr, CASEINSEN, wtcol, &wtcolnum, status) > 0) { ffpmsg( "keyword or column for histogram weights doesn't exist: "); ffpmsg(wtcol); return(*status); } weight = DOUBLENULLVALUE; } } else weight = (double) weightin; if (weight <= 0. && weight != DOUBLENULLVALUE) { ffpmsg("Illegal histogramming weighting factor <= 0."); return(*status = URL_PARSE_ERROR); } if (recip && weight != DOUBLENULLVALUE) /* take reciprocal of weight */ weight = (double) (1.0 / weight); /* size of histogram is now known, so create temp output file */ if (fits_create_file(&histptr, outfile, status) > 0) { ffpmsg("failed to create temp output file for histogram"); return(*status); } /* create output FITS image HDU */ if (ffcrim(histptr, bitpix, naxis, haxes, status) > 0) { ffpmsg("failed to create output histogram FITS image"); return(*status); } /* copy header keywords, converting pixel list WCS keywords to image WCS form */ if (fits_copy_pixlist2image(*fptr, histptr, 9, naxis, colnum, status) > 0) { ffpmsg("failed to copy pixel list keywords to new histogram header"); return(*status); } /* if the table columns have no WCS keywords, then write default keywords */ fits_write_keys_histo(*fptr, histptr, naxis, colnum, status); /* update the WCS keywords for the ref. pixel location, and pixel size */ fits_rebin_wcsd(histptr, naxis, amin, binsize, status); /* now compute the output image by binning the column values */ if (fits_make_histd(*fptr, histptr, bitpix, naxis, haxes, colnum, amin, amax, binsize, weight, wtcolnum, recip, selectrow, status) > 0) { ffpmsg("failed to calculate new histogram values"); return(*status); } /* finally, close the original file and return ptr to the new image */ ffclos(*fptr, status); *fptr = histptr; return(*status); } /*--------------------------------------------------------------------------*/ /* ffhist3: same as ffhist2, but does not close the original file */ /* and/or replace the original file pointer */ fitsfile *ffhist3(fitsfile *fptr, /* I - ptr to table with X and Y cols*/ char *outfile, /* I - name for the output histogram file */ int imagetype, /* I - datatype for image: TINT, TSHORT, etc */ int naxis, /* I - number of axes in the histogram image */ char colname[4][FLEN_VALUE], /* I - column names */ double *minin, /* I - minimum histogram value, for each axis */ double *maxin, /* I - maximum histogram value, for each axis */ double *binsizein, /* I - bin size along each axis */ char minname[4][FLEN_VALUE], /* I - optional keywords for min */ char maxname[4][FLEN_VALUE], /* I - optional keywords for max */ char binname[4][FLEN_VALUE], /* I - optional keywords for binsize */ double weightin, /* I - binning weighting factor */ char wtcol[FLEN_VALUE], /* I - optional keyword or col for weight*/ int recip, /* I - use reciprocal of the weight? */ char *selectrow, /* I - optional array (length = no. of */ /* rows in the table). If the element is true */ /* then the corresponding row of the table will*/ /* be included in the histogram, otherwise the */ /* row will be skipped. Ingnored if *selectrow*/ /* is equal to NULL. */ int *status) { fitsfile *histptr; int bitpix, colnum[4], wtcolnum; long haxes[4]; double amin[4], amax[4], binsize[4], weight; if (*status > 0) return(NULL); if (naxis > 4) { ffpmsg("histogram has more than 4 dimensions"); *status = BAD_DIMEN; return(NULL); } /* reset position to the correct HDU if necessary */ if ((fptr)->HDUposition != ((fptr)->Fptr)->curhdu) ffmahd(fptr, ((fptr)->HDUposition) + 1, NULL, status); if (imagetype == TBYTE) bitpix = BYTE_IMG; else if (imagetype == TSHORT) bitpix = SHORT_IMG; else if (imagetype == TINT) bitpix = LONG_IMG; else if (imagetype == TFLOAT) bitpix = FLOAT_IMG; else if (imagetype == TDOUBLE) bitpix = DOUBLE_IMG; else{ *status = BAD_DATATYPE; return(NULL); } /* Calculate the binning parameters: */ /* columm numbers, axes length, min values, max values, and binsizes. */ if (fits_calc_binningd( fptr, naxis, colname, minin, maxin, binsizein, minname, maxname, binname, colnum, haxes, amin, amax, binsize, status) > 0) { ffpmsg("failed to determine binning parameters"); return(NULL); } /* get the histogramming weighting factor, if any */ if (*wtcol) { /* first, look for a keyword with the weight value */ if (fits_read_key(fptr, TDOUBLE, wtcol, &weight, NULL, status) ) { /* not a keyword, so look for column with this name */ *status = 0; /* get the column number in the table */ if (ffgcno(fptr, CASEINSEN, wtcol, &wtcolnum, status) > 0) { ffpmsg( "keyword or column for histogram weights doesn't exist: "); ffpmsg(wtcol); return(NULL); } weight = DOUBLENULLVALUE; } } else weight = (double) weightin; if (weight <= 0. && weight != DOUBLENULLVALUE) { ffpmsg("Illegal histogramming weighting factor <= 0."); *status = URL_PARSE_ERROR; return(NULL); } if (recip && weight != DOUBLENULLVALUE) /* take reciprocal of weight */ weight = (double) (1.0 / weight); /* size of histogram is now known, so create temp output file */ if (fits_create_file(&histptr, outfile, status) > 0) { ffpmsg("failed to create temp output file for histogram"); return(NULL); } /* create output FITS image HDU */ if (ffcrim(histptr, bitpix, naxis, haxes, status) > 0) { ffpmsg("failed to create output histogram FITS image"); return(NULL); } /* copy header keywords, converting pixel list WCS keywords to image WCS */ if (fits_copy_pixlist2image(fptr, histptr, 9, naxis, colnum, status) > 0) { ffpmsg("failed to copy pixel list keywords to new histogram header"); return(NULL); } /* if the table columns have no WCS keywords, then write default keywords */ fits_write_keys_histo(fptr, histptr, naxis, colnum, status); /* update the WCS keywords for the ref. pixel location, and pixel size */ fits_rebin_wcsd(histptr, naxis, amin, binsize, status); /* now compute the output image by binning the column values */ if (fits_make_histd(fptr, histptr, bitpix, naxis, haxes, colnum, amin, amax, binsize, weight, wtcolnum, recip, selectrow, status) > 0) { ffpmsg("failed to calculate new histogram values"); return(NULL); } return(histptr); } /*--------------------------------------------------------------------------*/ int ffhist(fitsfile **fptr, /* IO - pointer to table with X and Y cols; */ /* on output, points to histogram image */ char *outfile, /* I - name for the output histogram file */ int imagetype, /* I - datatype for image: TINT, TSHORT, etc */ int naxis, /* I - number of axes in the histogram image */ char colname[4][FLEN_VALUE], /* I - column names */ double *minin, /* I - minimum histogram value, for each axis */ double *maxin, /* I - maximum histogram value, for each axis */ double *binsizein, /* I - bin size along each axis */ char minname[4][FLEN_VALUE], /* I - optional keywords for min */ char maxname[4][FLEN_VALUE], /* I - optional keywords for max */ char binname[4][FLEN_VALUE], /* I - optional keywords for binsize */ double weightin, /* I - binning weighting factor */ char wtcol[FLEN_VALUE], /* I - optional keyword or col for weight*/ int recip, /* I - use reciprocal of the weight? */ char *selectrow, /* I - optional array (length = no. of */ /* rows in the table). If the element is true */ /* then the corresponding row of the table will*/ /* be included in the histogram, otherwise the */ /* row will be skipped. Ingnored if *selectrow*/ /* is equal to NULL. */ int *status) { int ii, datatype, repeat, imin, imax, ibin, bitpix, tstatus, use_datamax = 0; long haxes[4]; fitsfile *histptr; char errmsg[FLEN_ERRMSG], keyname[FLEN_KEYWORD], card[FLEN_CARD]; tcolumn *colptr; iteratorCol imagepars[1]; int n_cols = 1, nkeys; long offset = 0; long n_per_loop = -1; /* force whole array to be passed at one time */ histType histData; /* Structure holding histogram info for iterator */ double amin[4], amax[4], binsize[4], maxbin[4]; double datamin = DOUBLENULLVALUE, datamax = DOUBLENULLVALUE; char svalue[FLEN_VALUE]; double dvalue; char cpref[4][FLEN_VALUE]; char *cptr; if (*status > 0) return(*status); if (naxis > 4) { ffpmsg("histogram has more than 4 dimensions"); return(*status = BAD_DIMEN); } /* reset position to the correct HDU if necessary */ if ((*fptr)->HDUposition != ((*fptr)->Fptr)->curhdu) ffmahd(*fptr, ((*fptr)->HDUposition) + 1, NULL, status); histData.tblptr = *fptr; histData.himagetype = imagetype; histData.haxis = naxis; histData.rowselector = selectrow; if (imagetype == TBYTE) bitpix = BYTE_IMG; else if (imagetype == TSHORT) bitpix = SHORT_IMG; else if (imagetype == TINT) bitpix = LONG_IMG; else if (imagetype == TFLOAT) bitpix = FLOAT_IMG; else if (imagetype == TDOUBLE) bitpix = DOUBLE_IMG; else return(*status = BAD_DATATYPE); /* The CPREF keyword, if it exists, gives the preferred columns. */ /* Otherwise, assume "X", "Y", "Z", and "T" */ tstatus = 0; ffgky(*fptr, TSTRING, "CPREF", cpref[0], NULL, &tstatus); if (!tstatus) { /* Preferred column names are given; separate them */ cptr = cpref[0]; /* the first preferred axis... */ while (*cptr != ',' && *cptr != '\0') cptr++; if (*cptr != '\0') { *cptr = '\0'; cptr++; while (*cptr == ' ') cptr++; strcpy(cpref[1], cptr); cptr = cpref[1]; /* the second preferred axis... */ while (*cptr != ',' && *cptr != '\0') cptr++; if (*cptr != '\0') { *cptr = '\0'; cptr++; while (*cptr == ' ') cptr++; strcpy(cpref[2], cptr); cptr = cpref[2]; /* the third preferred axis... */ while (*cptr != ',' && *cptr != '\0') cptr++; if (*cptr != '\0') { *cptr = '\0'; cptr++; while (*cptr == ' ') cptr++; strcpy(cpref[3], cptr); } } } } for (ii = 0; ii < naxis; ii++) { /* get the min, max, and binsize values from keywords, if specified */ if (*minname[ii]) { if (ffgky(*fptr, TDOUBLE, minname[ii], &minin[ii], NULL, status) ) { ffpmsg("error reading histogramming minimum keyword"); ffpmsg(minname[ii]); return(*status); } } if (*maxname[ii]) { if (ffgky(*fptr, TDOUBLE, maxname[ii], &maxin[ii], NULL, status) ) { ffpmsg("error reading histogramming maximum keyword"); ffpmsg(maxname[ii]); return(*status); } } if (*binname[ii]) { if (ffgky(*fptr, TDOUBLE, binname[ii], &binsizein[ii], NULL, status) ) { ffpmsg("error reading histogramming binsize keyword"); ffpmsg(binname[ii]); return(*status); } } if (binsizein[ii] == 0.) { ffpmsg("error: histogram binsize = 0"); return(*status = ZERO_SCALE); } if (*colname[ii] == '\0') { strcpy(colname[ii], cpref[ii]); /* try using the preferred column */ if (*colname[ii] == '\0') { if (ii == 0) strcpy(colname[ii], "X"); else if (ii == 1) strcpy(colname[ii], "Y"); else if (ii == 2) strcpy(colname[ii], "Z"); else if (ii == 3) strcpy(colname[ii], "T"); } } /* get the column number in the table */ if (ffgcno(*fptr, CASEINSEN, colname[ii], histData.hcolnum+ii, status) > 0) { strcpy(errmsg, "column for histogram axis doesn't exist: "); strncat(errmsg, colname[ii], FLEN_ERRMSG-strlen(errmsg)-1); ffpmsg(errmsg); return(*status); } colptr = ((*fptr)->Fptr)->tableptr; colptr += (histData.hcolnum[ii] - 1); repeat = (int) colptr->trepeat; /* vector repeat factor of the column */ if (repeat > 1) { strcpy(errmsg, "Can't bin a vector column: "); strncat(errmsg, colname[ii],FLEN_ERRMSG-strlen(errmsg)-1); ffpmsg(errmsg); return(*status = BAD_DATATYPE); } /* get the datatype of the column */ fits_get_eqcoltype(*fptr, histData.hcolnum[ii], &datatype, NULL, NULL, status); if (datatype < 0 || datatype == TSTRING) { strcpy(errmsg, "Inappropriate datatype; can't bin this column: "); strncat(errmsg, colname[ii],FLEN_ERRMSG-strlen(errmsg)-1); ffpmsg(errmsg); return(*status = BAD_DATATYPE); } /* use TLMINn and TLMAXn keyword values if min and max were not given */ /* else use actual data min and max if TLMINn and TLMAXn don't exist */ if (minin[ii] == DOUBLENULLVALUE) { ffkeyn("TLMIN", histData.hcolnum[ii], keyname, status); if (ffgky(*fptr, TDOUBLE, keyname, amin+ii, NULL, status) > 0) { /* use actual data minimum value for the histogram minimum */ *status = 0; if (fits_get_col_minmax(*fptr, histData.hcolnum[ii], amin+ii, &datamax, status) > 0) { strcpy(errmsg, "Error calculating datamin and datamax for column: "); strncat(errmsg, colname[ii],FLEN_ERRMSG-strlen(errmsg)-1); ffpmsg(errmsg); return(*status); } } } else { amin[ii] = (double) minin[ii]; } if (maxin[ii] == DOUBLENULLVALUE) { ffkeyn("TLMAX", histData.hcolnum[ii], keyname, status); if (ffgky(*fptr, TDOUBLE, keyname, &amax[ii], NULL, status) > 0) { *status = 0; if(datamax != DOUBLENULLVALUE) /* already computed max value */ { amax[ii] = datamax; } else { /* use actual data maximum value for the histogram maximum */ if (fits_get_col_minmax(*fptr, histData.hcolnum[ii], &datamin, &amax[ii], status) > 0) { strcpy(errmsg, "Error calculating datamin and datamax for column: "); strncat(errmsg, colname[ii],FLEN_ERRMSG-strlen(errmsg)-1); ffpmsg(errmsg); return(*status); } } } use_datamax = 1; /* flag that the max was determined by the data values */ /* and not specifically set by the calling program */ } else { amax[ii] = (double) maxin[ii]; } /* use TDBINn keyword or else 1 if bin size is not given */ if (binsizein[ii] == DOUBLENULLVALUE) { tstatus = 0; ffkeyn("TDBIN", histData.hcolnum[ii], keyname, &tstatus); if (ffgky(*fptr, TDOUBLE, keyname, binsizein + ii, NULL, &tstatus) > 0) { /* make at least 10 bins */ binsizein[ii] = (amax[ii] - amin[ii]) / 10. ; if (binsizein[ii] > 1.) binsizein[ii] = 1.; /* use default bin size */ } } if ( (amin[ii] > amax[ii] && binsizein[ii] > 0. ) || (amin[ii] < amax[ii] && binsizein[ii] < 0. ) ) binsize[ii] = (double) -binsizein[ii]; /* reverse the sign of binsize */ else binsize[ii] = (double) binsizein[ii]; /* binsize has the correct sign */ ibin = (int) binsize[ii]; imin = (int) amin[ii]; imax = (int) amax[ii]; /* Determine the range and number of bins in the histogram. This */ /* depends on whether the input columns are integer or floats, so */ /* treat each case separately. */ if (datatype <= TLONG && (double) imin == amin[ii] && (double) imax == amax[ii] && (double) ibin == binsize[ii] ) { /* This is an integer column and integer limits were entered. */ /* Shift the lower and upper histogramming limits by 0.5, so that */ /* the values fall in the center of the bin, not on the edge. */ haxes[ii] = (imax - imin) / ibin + 1; /* last bin may only */ /* be partially full */ maxbin[ii] = (double) (haxes[ii] + 1.); /* add 1. instead of .5 to avoid roundoff */ if (amin[ii] < amax[ii]) { amin[ii] = (double) (amin[ii] - 0.5); amax[ii] = (double) (amax[ii] + 0.5); } else { amin[ii] = (double) (amin[ii] + 0.5); amax[ii] = (double) (amax[ii] - 0.5); } } else if (use_datamax) { /* Either the column datatype and/or the limits are floating point, */ /* and the histogram limits are being defined by the min and max */ /* values of the array. Add 1 to the number of histogram bins to */ /* make sure that pixels that are equal to the maximum or are */ /* in the last partial bin are included. */ maxbin[ii] = (amax[ii] - amin[ii]) / binsize[ii]; haxes[ii] = (long) (maxbin[ii] + 1); } else { /* float datatype column and/or limits, and the maximum value to */ /* include in the histogram is specified by the calling program. */ /* The lower limit is inclusive, but upper limit is exclusive */ maxbin[ii] = (amax[ii] - amin[ii]) / binsize[ii]; haxes[ii] = (long) maxbin[ii]; if (amin[ii] < amax[ii]) { if (amin[ii] + (haxes[ii] * binsize[ii]) < amax[ii]) haxes[ii]++; /* need to include another partial bin */ } else { if (amin[ii] + (haxes[ii] * binsize[ii]) > amax[ii]) haxes[ii]++; /* need to include another partial bin */ } } } /* get the histogramming weighting factor */ if (*wtcol) { /* first, look for a keyword with the weight value */ if (ffgky(*fptr, TDOUBLE, wtcol, &histData.weight, NULL, status) ) { /* not a keyword, so look for column with this name */ *status = 0; /* get the column number in the table */ if (ffgcno(*fptr, CASEINSEN, wtcol, &histData.wtcolnum, status) > 0) { ffpmsg( "keyword or column for histogram weights doesn't exist: "); ffpmsg(wtcol); return(*status); } histData.weight = DOUBLENULLVALUE; } } else histData.weight = (double) weightin; if (histData.weight <= 0. && histData.weight != DOUBLENULLVALUE) { ffpmsg("Illegal histogramming weighting factor <= 0."); return(*status = URL_PARSE_ERROR); } if (recip && histData.weight != DOUBLENULLVALUE) /* take reciprocal of weight */ histData.weight = (double) (1.0 / histData.weight); histData.wtrecip = recip; /* size of histogram is now known, so create temp output file */ if (ffinit(&histptr, outfile, status) > 0) { ffpmsg("failed to create temp output file for histogram"); return(*status); } if (ffcrim(histptr, bitpix, histData.haxis, haxes, status) > 0) { ffpmsg("failed to create primary array histogram in temp file"); ffclos(histptr, status); return(*status); } /* copy all non-structural keywords from the table to the image */ fits_get_hdrspace(*fptr, &nkeys, NULL, status); for (ii = 1; ii <= nkeys; ii++) { fits_read_record(*fptr, ii, card, status); if (fits_get_keyclass(card) >= 120) fits_write_record(histptr, card, status); } /* Set global variables with histogram parameter values. */ /* Use separate scalar variables rather than arrays because */ /* it is more efficient when computing the histogram. */ histData.amin1 = amin[0]; histData.maxbin1 = maxbin[0]; histData.binsize1 = binsize[0]; histData.haxis1 = haxes[0]; if (histData.haxis > 1) { histData.amin2 = amin[1]; histData.maxbin2 = maxbin[1]; histData.binsize2 = binsize[1]; histData.haxis2 = haxes[1]; if (histData.haxis > 2) { histData.amin3 = amin[2]; histData.maxbin3 = maxbin[2]; histData.binsize3 = binsize[2]; histData.haxis3 = haxes[2]; if (histData.haxis > 3) { histData.amin4 = amin[3]; histData.maxbin4 = maxbin[3]; histData.binsize4 = binsize[3]; histData.haxis4 = haxes[3]; } } } /* define parameters of image for the iterator function */ fits_iter_set_file(imagepars, histptr); /* pointer to image */ fits_iter_set_datatype(imagepars, imagetype); /* image datatype */ fits_iter_set_iotype(imagepars, OutputCol); /* image is output */ /* call the iterator function to write out the histogram image */ if (fits_iterate_data(n_cols, imagepars, offset, n_per_loop, ffwritehisto, (void*)&histData, status) ) return(*status); /* write the World Coordinate System (WCS) keywords */ /* create default values if WCS keywords are not present in the table */ for (ii = 0; ii < histData.haxis; ii++) { /* CTYPEn */ tstatus = 0; ffkeyn("TCTYP", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TSTRING, keyname, svalue, NULL, &tstatus); if (tstatus) { /* just use column name as the type */ tstatus = 0; ffkeyn("TTYPE", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TSTRING, keyname, svalue, NULL, &tstatus); } if (!tstatus) { ffkeyn("CTYPE", ii + 1, keyname, &tstatus); ffpky(histptr, TSTRING, keyname, svalue, "Coordinate Type", &tstatus); } else tstatus = 0; /* CUNITn */ ffkeyn("TCUNI", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TSTRING, keyname, svalue, NULL, &tstatus); if (tstatus) { /* use the column units */ tstatus = 0; ffkeyn("TUNIT", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TSTRING, keyname, svalue, NULL, &tstatus); } if (!tstatus) { ffkeyn("CUNIT", ii + 1, keyname, &tstatus); ffpky(histptr, TSTRING, keyname, svalue, "Coordinate Units", &tstatus); } else tstatus = 0; /* CRPIXn - Reference Pixel */ ffkeyn("TCRPX", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus); if (tstatus) { dvalue = 1.0; /* choose first pixel in new image as ref. pix. */ tstatus = 0; } else { /* calculate locate of the ref. pix. in the new image */ dvalue = (dvalue - amin[ii]) / binsize[ii] + .5; } ffkeyn("CRPIX", ii + 1, keyname, &tstatus); ffpky(histptr, TDOUBLE, keyname, &dvalue, "Reference Pixel", &tstatus); /* CRVALn - Value at the location of the reference pixel */ ffkeyn("TCRVL", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus); if (tstatus) { /* calculate value at ref. pix. location (at center of 1st pixel) */ dvalue = amin[ii] + binsize[ii]/2.; tstatus = 0; } ffkeyn("CRVAL", ii + 1, keyname, &tstatus); ffpky(histptr, TDOUBLE, keyname, &dvalue, "Reference Value", &tstatus); /* CDELTn - unit size of pixels */ ffkeyn("TCDLT", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus); if (tstatus) { dvalue = 1.0; /* use default pixel size */ tstatus = 0; } dvalue = dvalue * binsize[ii]; ffkeyn("CDELT", ii + 1, keyname, &tstatus); ffpky(histptr, TDOUBLE, keyname, &dvalue, "Pixel size", &tstatus); /* CROTAn - Rotation angle (degrees CCW) */ /* There should only be a CROTA2 keyword, and only for 2+ D images */ if (ii == 1) { ffkeyn("TCROT", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus); if (!tstatus && dvalue != 0.) /* only write keyword if angle != 0 */ { ffkeyn("CROTA", ii + 1, keyname, &tstatus); ffpky(histptr, TDOUBLE, keyname, &dvalue, "Rotation angle", &tstatus); } else { /* didn't find CROTA for the 2nd axis, so look for one */ /* on the first axis */ tstatus = 0; ffkeyn("TCROT", histData.hcolnum[0], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus); if (!tstatus && dvalue != 0.) /* only write keyword if angle != 0 */ { dvalue *= -1.; /* negate the value, because mirror image */ ffkeyn("CROTA", ii + 1, keyname, &tstatus); ffpky(histptr, TDOUBLE, keyname, &dvalue, "Rotation angle", &tstatus); } } } } /* convert any TPn_k keywords to PCi_j; the value remains unchanged */ /* also convert any TCn_k to CDi_j; the value is modified by n binning size */ /* This is a bit of a kludge, and only works for 2D WCS */ if (histData.haxis == 2) { /* PC1_1 */ tstatus = 0; ffkeyn("TP", histData.hcolnum[0], card, &tstatus); strcat(card,"_"); ffkeyn(card, histData.hcolnum[0], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus); if (!tstatus) ffpky(histptr, TDOUBLE, "PC1_1", &dvalue, card, &tstatus); tstatus = 0; keyname[1] = 'C'; ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus); if (!tstatus) { dvalue *= binsize[0]; ffpky(histptr, TDOUBLE, "CD1_1", &dvalue, card, &tstatus); } /* PC1_2 */ tstatus = 0; ffkeyn("TP", histData.hcolnum[0], card, &tstatus); strcat(card,"_"); ffkeyn(card, histData.hcolnum[1], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus); if (!tstatus) ffpky(histptr, TDOUBLE, "PC1_2", &dvalue, card, &tstatus); tstatus = 0; keyname[1] = 'C'; ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus); if (!tstatus) { dvalue *= binsize[0]; ffpky(histptr, TDOUBLE, "CD1_2", &dvalue, card, &tstatus); } /* PC2_1 */ tstatus = 0; ffkeyn("TP", histData.hcolnum[1], card, &tstatus); strcat(card,"_"); ffkeyn(card, histData.hcolnum[0], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus); if (!tstatus) ffpky(histptr, TDOUBLE, "PC2_1", &dvalue, card, &tstatus); tstatus = 0; keyname[1] = 'C'; ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus); if (!tstatus) { dvalue *= binsize[1]; ffpky(histptr, TDOUBLE, "CD2_1", &dvalue, card, &tstatus); } /* PC2_2 */ tstatus = 0; ffkeyn("TP", histData.hcolnum[1], card, &tstatus); strcat(card,"_"); ffkeyn(card, histData.hcolnum[1], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus); if (!tstatus) ffpky(histptr, TDOUBLE, "PC2_2", &dvalue, card, &tstatus); tstatus = 0; keyname[1] = 'C'; ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus); if (!tstatus) { dvalue *= binsize[1]; ffpky(histptr, TDOUBLE, "CD2_2", &dvalue, card, &tstatus); } } /* finally, close the original file and return ptr to the new image */ ffclos(*fptr, status); *fptr = histptr; return(*status); } /*--------------------------------------------------------------------------*/ /* Single-precision version */ int fits_calc_binning( fitsfile *fptr, /* IO - pointer to table to be binned ; */ int naxis, /* I - number of axes/columns in the binned image */ char colname[4][FLEN_VALUE], /* I - optional column names */ double *minin, /* I - optional lower bound value for each axis */ double *maxin, /* I - optional upper bound value, for each axis */ double *binsizein, /* I - optional bin size along each axis */ char minname[4][FLEN_VALUE], /* I - optional keywords for min */ char maxname[4][FLEN_VALUE], /* I - optional keywords for max */ char binname[4][FLEN_VALUE], /* I - optional keywords for binsize */ /* The returned parameters for each axis of the n-dimensional histogram are */ int *colnum, /* O - column numbers, to be binned */ long *haxes, /* O - number of bins in each histogram axis */ float *amin, /* O - lower bound of the histogram axes */ float *amax, /* O - upper bound of the histogram axes */ float *binsize, /* O - width of histogram bins/pixels on each axis */ int *status) { double amind[4], amaxd[4], binsized[4]; fits_calc_binningd(fptr, naxis, colname, minin, maxin, binsizein, minname, maxname, binname, colnum, haxes, amind, amaxd, binsized, status); /* Copy double precision values into single precision */ if (*status == 0) { int i, naxis1 = 4; if (naxis < naxis1) naxis1 = naxis; for (i=0; i 0) return(*status); if (naxis > 4) { ffpmsg("histograms with more than 4 dimensions are not supported"); return(*status = BAD_DIMEN); } /* reset position to the correct HDU if necessary */ if ((fptr)->HDUposition != ((fptr)->Fptr)->curhdu) ffmahd(fptr, ((fptr)->HDUposition) + 1, NULL, status); /* ============================================================= */ /* The CPREF keyword, if it exists, gives the preferred columns. */ /* Otherwise, assume "X", "Y", "Z", and "T" */ *cpref[0] = '\0'; *cpref[1] = '\0'; *cpref[2] = '\0'; *cpref[3] = '\0'; tstatus = 0; ffgky(fptr, TSTRING, "CPREF", cpref[0], NULL, &tstatus); if (!tstatus) { /* Preferred column names are given; separate them */ cptr = cpref[0]; /* the first preferred axis... */ while (*cptr != ',' && *cptr != '\0') cptr++; if (*cptr != '\0') { *cptr = '\0'; cptr++; while (*cptr == ' ') cptr++; strcpy(cpref[1], cptr); cptr = cpref[1]; /* the second preferred axis... */ while (*cptr != ',' && *cptr != '\0') cptr++; if (*cptr != '\0') { *cptr = '\0'; cptr++; while (*cptr == ' ') cptr++; strcpy(cpref[2], cptr); cptr = cpref[2]; /* the third preferred axis... */ while (*cptr != ',' && *cptr != '\0') cptr++; if (*cptr != '\0') { *cptr = '\0'; cptr++; while (*cptr == ' ') cptr++; strcpy(cpref[3], cptr); } } } } /* ============================================================= */ /* Main Loop for calculating parameters for each column */ for (ii = 0; ii < naxis; ii++) { /* =========================================================== */ /* Determine column Number, based on, in order of priority, 1 input column name, or 2 name given by CPREF keyword, or 3 assume X, Y, Z and T for the name */ if (*colname[ii] == '\0') { strcpy(colname[ii], cpref[ii]); /* try using the preferred column */ if (*colname[ii] == '\0') { if (ii == 0) strcpy(colname[ii], "X"); else if (ii == 1) strcpy(colname[ii], "Y"); else if (ii == 2) strcpy(colname[ii], "Z"); else if (ii == 3) strcpy(colname[ii], "T"); } } /* get the column number in the table */ if (ffgcno(fptr, CASEINSEN, colname[ii], colnum+ii, status) > 0) { strcpy(errmsg, "column for histogram axis doesn't exist: "); strncat(errmsg, colname[ii],FLEN_ERRMSG-strlen(errmsg)-1); ffpmsg(errmsg); return(*status); } /* ================================================================ */ /* check tha column is not a vector or a string */ colptr = ((fptr)->Fptr)->tableptr; colptr += (colnum[ii] - 1); repeat = (int) colptr->trepeat; /* vector repeat factor of the column */ if (repeat > 1) { strcpy(errmsg, "Can't bin a vector column: "); strncat(errmsg, colname[ii],FLEN_ERRMSG-strlen(errmsg)-1); ffpmsg(errmsg); return(*status = BAD_DATATYPE); } /* get the datatype of the column */ fits_get_eqcoltype(fptr, colnum[ii], &datatype, NULL, NULL, status); if (datatype < 0 || datatype == TSTRING) { strcpy(errmsg, "Inappropriate datatype; can't bin this column: "); strncat(errmsg, colname[ii],FLEN_ERRMSG-strlen(errmsg)-1); ffpmsg(errmsg); return(*status = BAD_DATATYPE); } /* ================================================================ */ /* get the minimum value */ datamin = DOUBLENULLVALUE; datamax = DOUBLENULLVALUE; if (*minname[ii]) { if (ffgky(fptr, TDOUBLE, minname[ii], &minin[ii], NULL, status) ) { ffpmsg("error reading histogramming minimum keyword"); ffpmsg(minname[ii]); return(*status); } } if (minin[ii] != DOUBLENULLVALUE) { amin[ii] = (double) minin[ii]; } else { ffkeyn("TLMIN", colnum[ii], keyname, status); if (ffgky(fptr, TDOUBLE, keyname, amin+ii, NULL, status) > 0) { /* use actual data minimum value for the histogram minimum */ *status = 0; if (fits_get_col_minmax(fptr, colnum[ii], amin+ii, &datamax, status) > 0) { strcpy(errmsg, "Error calculating datamin and datamax for column: "); strncat(errmsg, colname[ii],FLEN_ERRMSG-strlen(errmsg)-1); ffpmsg(errmsg); return(*status); } } } /* ================================================================ */ /* get the maximum value */ if (*maxname[ii]) { if (ffgky(fptr, TDOUBLE, maxname[ii], &maxin[ii], NULL, status) ) { ffpmsg("error reading histogramming maximum keyword"); ffpmsg(maxname[ii]); return(*status); } } if (maxin[ii] != DOUBLENULLVALUE) { amax[ii] = (double) maxin[ii]; } else { ffkeyn("TLMAX", colnum[ii], keyname, status); if (ffgky(fptr, TDOUBLE, keyname, &amax[ii], NULL, status) > 0) { *status = 0; if(datamax != DOUBLENULLVALUE) /* already computed max value */ { amax[ii] = datamax; } else { /* use actual data maximum value for the histogram maximum */ if (fits_get_col_minmax(fptr, colnum[ii], &datamin, &amax[ii], status) > 0) { strcpy(errmsg, "Error calculating datamin and datamax for column: "); strncat(errmsg, colname[ii],FLEN_ERRMSG-strlen(errmsg)-1); ffpmsg(errmsg); return(*status); } } } use_datamax = 1; /* flag that the max was determined by the data values */ /* and not specifically set by the calling program */ } /* ================================================================ */ /* determine binning size and range */ if (*binname[ii]) { if (ffgky(fptr, TDOUBLE, binname[ii], &binsizein[ii], NULL, status) ) { ffpmsg("error reading histogramming binsize keyword"); ffpmsg(binname[ii]); return(*status); } } if (binsizein[ii] == 0.) { ffpmsg("error: histogram binsize = 0"); return(*status = ZERO_SCALE); } /* use TDBINn keyword or else 1 if bin size is not given */ if (binsizein[ii] != DOUBLENULLVALUE) { binsize[ii] = (double) binsizein[ii]; } else { tstatus = 0; ffkeyn("TDBIN", colnum[ii], keyname, &tstatus); if (ffgky(fptr, TDOUBLE, keyname, binsizein + ii, NULL, &tstatus) > 0) { /* make at least 10 bins */ binsize[ii] = (amax[ii] - amin[ii]) / 10.F ; if (binsize[ii] > 1.) binsize[ii] = 1.; /* use default bin size */ } } /* ================================================================ */ /* if the min is greater than the max, make the binsize negative */ if ( (amin[ii] > amax[ii] && binsize[ii] > 0. ) || (amin[ii] < amax[ii] && binsize[ii] < 0. ) ) binsize[ii] = -binsize[ii]; /* reverse the sign of binsize */ ibin = (int) binsize[ii]; imin = (int) amin[ii]; imax = (int) amax[ii]; /* Determine the range and number of bins in the histogram. This */ /* depends on whether the input columns are integer or floats, so */ /* treat each case separately. */ if (datatype <= TLONG && (double) imin == amin[ii] && (double) imax == amax[ii] && (double) ibin == binsize[ii] ) { /* This is an integer column and integer limits were entered. */ /* Shift the lower and upper histogramming limits by 0.5, so that */ /* the values fall in the center of the bin, not on the edge. */ haxes[ii] = (imax - imin) / ibin + 1; /* last bin may only */ /* be partially full */ if (amin[ii] < amax[ii]) { amin[ii] = (double) (amin[ii] - 0.5); amax[ii] = (double) (amax[ii] + 0.5); } else { amin[ii] = (double) (amin[ii] + 0.5); amax[ii] = (double) (amax[ii] - 0.5); } } else if (use_datamax) { /* Either the column datatype and/or the limits are floating point, */ /* and the histogram limits are being defined by the min and max */ /* values of the array. Add 1 to the number of histogram bins to */ /* make sure that pixels that are equal to the maximum or are */ /* in the last partial bin are included. */ haxes[ii] = (long) (((amax[ii] - amin[ii]) / binsize[ii]) + 1.); } else { /* float datatype column and/or limits, and the maximum value to */ /* include in the histogram is specified by the calling program. */ /* The lower limit is inclusive, but upper limit is exclusive */ haxes[ii] = (long) ((amax[ii] - amin[ii]) / binsize[ii]); if (amin[ii] < amax[ii]) { if (amin[ii] + (haxes[ii] * binsize[ii]) < amax[ii]) haxes[ii]++; /* need to include another partial bin */ } else { if (amin[ii] + (haxes[ii] * binsize[ii]) > amax[ii]) haxes[ii]++; /* need to include another partial bin */ } } } return(*status); } /*--------------------------------------------------------------------------*/ int fits_write_keys_histo( fitsfile *fptr, /* I - pointer to table to be binned */ fitsfile *histptr, /* I - pointer to output histogram image HDU */ int naxis, /* I - number of axes in the histogram image */ int *colnum, /* I - column numbers (array length = naxis) */ int *status) { /* Write default WCS keywords in the output histogram image header */ /* if the keywords do not already exist. */ int ii, tstatus; char keyname[FLEN_KEYWORD], svalue[FLEN_VALUE]; double dvalue; if (*status > 0) return(*status); for (ii = 0; ii < naxis; ii++) { /* CTYPEn */ tstatus = 0; ffkeyn("CTYPE", ii+1, keyname, &tstatus); ffgky(histptr, TSTRING, keyname, svalue, NULL, &tstatus); if (!tstatus) continue; /* keyword already exists, so skip to next axis */ /* use column name as the axis name */ tstatus = 0; ffkeyn("TTYPE", colnum[ii], keyname, &tstatus); ffgky(fptr, TSTRING, keyname, svalue, NULL, &tstatus); if (!tstatus) { ffkeyn("CTYPE", ii + 1, keyname, &tstatus); ffpky(histptr, TSTRING, keyname, svalue, "Coordinate Type", &tstatus); } /* CUNITn, use the column units */ tstatus = 0; ffkeyn("TUNIT", colnum[ii], keyname, &tstatus); ffgky(fptr, TSTRING, keyname, svalue, NULL, &tstatus); if (!tstatus) { ffkeyn("CUNIT", ii + 1, keyname, &tstatus); ffpky(histptr, TSTRING, keyname, svalue, "Coordinate Units", &tstatus); } /* CRPIXn - Reference Pixel choose first pixel in new image as ref. pix. */ dvalue = 1.0; tstatus = 0; ffkeyn("CRPIX", ii + 1, keyname, &tstatus); ffpky(histptr, TDOUBLE, keyname, &dvalue, "Reference Pixel", &tstatus); /* CRVALn - Value at the location of the reference pixel */ dvalue = 1.0; tstatus = 0; ffkeyn("CRVAL", ii + 1, keyname, &tstatus); ffpky(histptr, TDOUBLE, keyname, &dvalue, "Reference Value", &tstatus); /* CDELTn - unit size of pixels */ dvalue = 1.0; tstatus = 0; dvalue = 1.; ffkeyn("CDELT", ii + 1, keyname, &tstatus); ffpky(histptr, TDOUBLE, keyname, &dvalue, "Pixel size", &tstatus); } return(*status); } /*--------------------------------------------------------------------------*/ int fits_rebin_wcs( fitsfile *fptr, /* I - pointer to table to be binned */ int naxis, /* I - number of axes in the histogram image */ float *amin, /* I - first pixel include in each axis */ float *binsize, /* I - binning factor for each axis */ int *status) { double amind[4], binsized[4]; /* Copy single precision values into double precision */ if (*status == 0) { int i, naxis1 = 4; if (naxis < naxis1) naxis1 = naxis; for (i=0; i 0) return(*status); for (ii = 0; ii < naxis; ii++) { reset = 0; /* flag to reset the reference pixel */ tstatus = 0; ffkeyn("CRVAL", ii + 1, keyname, &tstatus); /* get previous (pre-binning) value */ ffgky(fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus); if (!tstatus && dvalue == 1.0) reset = 1; tstatus = 0; /* CRPIXn - update location of the ref. pix. in the binned image */ ffkeyn("CRPIX", ii + 1, keyname, &tstatus); /* get previous (pre-binning) value */ ffgky(fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus); if (!tstatus) { if (dvalue != 1.0) reset = 0; /* updated value to give pixel location after binning */ dvalue = (dvalue - amin[ii]) / ((double) binsize[ii]) + .5; fits_modify_key_dbl(fptr, keyname, dvalue, -14, NULL, &tstatus); } else { reset = 0; } /* CDELTn - update unit size of pixels */ tstatus = 0; ffkeyn("CDELT", ii + 1, keyname, &tstatus); /* get previous (pre-binning) value */ ffgky(fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus); if (!tstatus) { if (dvalue != 1.0) reset = 0; /* updated to give post-binning value */ dvalue = dvalue * binsize[ii]; fits_modify_key_dbl(fptr, keyname, dvalue, -14, NULL, &tstatus); } else { /* no CDELTn keyword, so look for a CDij keywords */ reset = 0; for (jj = 0; jj < naxis; jj++) { tstatus = 0; ffkeyn("CD", jj + 1, svalue, &tstatus); strcat(svalue,"_"); ffkeyn(svalue, ii + 1, keyname, &tstatus); /* get previous (pre-binning) value */ ffgky(fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus); if (!tstatus) { /* updated to give post-binning value */ dvalue = dvalue * binsize[ii]; fits_modify_key_dbl(fptr, keyname, dvalue, -14, NULL, &tstatus); } } } if (reset) { /* the original CRPIX, CRVAL, and CDELT keywords were all = 1.0 */ /* In this special case, reset the reference pixel to be the */ /* first pixel in the array (instead of possibly far off the array) */ dvalue = 1.0; ffkeyn("CRPIX", ii + 1, keyname, &tstatus); fits_modify_key_dbl(fptr, keyname, dvalue, -14, NULL, &tstatus); ffkeyn("CRVAL", ii + 1, keyname, &tstatus); dvalue = amin[ii] + (binsize[ii] / 2.0); fits_modify_key_dbl(fptr, keyname, dvalue, -14, NULL, &tstatus); } } return(*status); } /*--------------------------------------------------------------------------*/ /* Single-precision version */ int fits_make_hist(fitsfile *fptr, /* IO - pointer to table with X and Y cols; */ fitsfile *histptr, /* I - pointer to output FITS image */ int bitpix, /* I - datatype for image: 16, 32, -32, etc */ int naxis, /* I - number of axes in the histogram image */ long *naxes, /* I - size of axes in the histogram image */ int *colnum, /* I - column numbers (array length = naxis) */ float *amin, /* I - minimum histogram value, for each axis */ float *amax, /* I - maximum histogram value, for each axis */ float *binsize, /* I - bin size along each axis */ float weight, /* I - binning weighting factor */ int wtcolnum, /* I - optional keyword or col for weight*/ int recip, /* I - use reciprocal of the weight? */ char *selectrow, /* I - optional array (length = no. of */ /* rows in the table). If the element is true */ /* then the corresponding row of the table will*/ /* be included in the histogram, otherwise the */ /* row will be skipped. Ingnored if *selectrow*/ /* is equal to NULL. */ int *status) { double amind[4], amaxd[4], binsized[4], weightd; /* Copy single precision values into double precision */ if (*status == 0) { int i, naxis1 = 4; if (naxis < naxis1) naxis1 = naxis; for (i=0; i 0) return(*status); if (naxis > 4) { ffpmsg("histogram has more than 4 dimensions"); return(*status = BAD_DIMEN); } if (bitpix == BYTE_IMG) imagetype = TBYTE; else if (bitpix == SHORT_IMG) imagetype = TSHORT; else if (bitpix == LONG_IMG) imagetype = TINT; else if (bitpix == FLOAT_IMG) imagetype = TFLOAT; else if (bitpix == DOUBLE_IMG) imagetype = TDOUBLE; else return(*status = BAD_DATATYPE); /* reset position to the correct HDU if necessary */ if ((fptr)->HDUposition != ((fptr)->Fptr)->curhdu) ffmahd(fptr, ((fptr)->HDUposition) + 1, NULL, status); histData.weight = weight; histData.wtcolnum = wtcolnum; histData.wtrecip = recip; histData.tblptr = fptr; histData.himagetype = imagetype; histData.haxis = naxis; histData.rowselector = selectrow; for (ii = 0; ii < naxis; ii++) { taxes[ii] = (double) naxes[ii]; tmin[ii] = amin[ii]; tmax[ii] = amax[ii]; if ( (amin[ii] > amax[ii] && binsize[ii] > 0. ) || (amin[ii] < amax[ii] && binsize[ii] < 0. ) ) tbin[ii] = -binsize[ii]; /* reverse the sign of binsize */ else tbin[ii] = binsize[ii]; /* binsize has the correct sign */ imin = (long) tmin[ii]; imax = (long) tmax[ii]; ibin = (long) tbin[ii]; /* get the datatype of the column */ fits_get_eqcoltype(fptr, colnum[ii], &datatype, NULL, NULL, status); if (datatype <= TLONG && (double) imin == tmin[ii] && (double) imax == tmax[ii] && (double) ibin == tbin[ii] ) { /* This is an integer column and integer limits were entered. */ /* Shift the lower and upper histogramming limits by 0.5, so that */ /* the values fall in the center of the bin, not on the edge. */ maxbin[ii] = (taxes[ii] + 1.F); /* add 1. instead of .5 to avoid roundoff */ if (tmin[ii] < tmax[ii]) { tmin[ii] = tmin[ii] - 0.5F; tmax[ii] = tmax[ii] + 0.5F; } else { tmin[ii] = tmin[ii] + 0.5F; tmax[ii] = tmax[ii] - 0.5F; } } else { /* not an integer column with integer limits */ maxbin[ii] = (tmax[ii] - tmin[ii]) / tbin[ii]; } } /* Set global variables with histogram parameter values. */ /* Use separate scalar variables rather than arrays because */ /* it is more efficient when computing the histogram. */ histData.hcolnum[0] = colnum[0]; histData.amin1 = tmin[0]; histData.maxbin1 = maxbin[0]; histData.binsize1 = tbin[0]; histData.haxis1 = (long) taxes[0]; if (histData.haxis > 1) { histData.hcolnum[1] = colnum[1]; histData.amin2 = tmin[1]; histData.maxbin2 = maxbin[1]; histData.binsize2 = tbin[1]; histData.haxis2 = (long) taxes[1]; if (histData.haxis > 2) { histData.hcolnum[2] = colnum[2]; histData.amin3 = tmin[2]; histData.maxbin3 = maxbin[2]; histData.binsize3 = tbin[2]; histData.haxis3 = (long) taxes[2]; if (histData.haxis > 3) { histData.hcolnum[3] = colnum[3]; histData.amin4 = tmin[3]; histData.maxbin4 = maxbin[3]; histData.binsize4 = tbin[3]; histData.haxis4 = (long) taxes[3]; } } } /* define parameters of image for the iterator function */ fits_iter_set_file(imagepars, histptr); /* pointer to image */ fits_iter_set_datatype(imagepars, imagetype); /* image datatype */ fits_iter_set_iotype(imagepars, OutputCol); /* image is output */ /* call the iterator function to write out the histogram image */ fits_iterate_data(n_cols, imagepars, offset, n_per_loop, ffwritehisto, (void*)&histData, status); return(*status); } /*--------------------------------------------------------------------------*/ int fits_get_col_minmax(fitsfile *fptr, int colnum, double *datamin, double *datamax, int *status) /* Simple utility routine to compute the min and max value in a column */ { int anynul; long nrows, ntodo, firstrow, ii; double array[1000], nulval; ffgky(fptr, TLONG, "NAXIS2", &nrows, NULL, status); /* no. of rows */ firstrow = 1; nulval = DOUBLENULLVALUE; *datamin = 9.0E36; *datamax = -9.0E36; while(nrows) { ntodo = minvalue(nrows, 100); ffgcv(fptr, TDOUBLE, colnum, firstrow, 1, ntodo, &nulval, array, &anynul, status); for (ii = 0; ii < ntodo; ii++) { if (array[ii] != nulval) { *datamin = minvalue(*datamin, array[ii]); *datamax = maxvalue(*datamax, array[ii]); } } nrows -= ntodo; firstrow += ntodo; } return(*status); } /*--------------------------------------------------------------------------*/ int ffwritehisto(long totaln, long pixoffset, long firstn, long nvalues, int narrays, iteratorCol *imagepars, void *userPointer) /* Interator work function that writes out the histogram. The histogram values are calculated by another work function, ffcalchisto. This work function only gets called once, and totaln = nvalues. */ { iteratorCol colpars[5]; int ii, status = 0, ncols; long rows_per_loop = 0, offset = 0; histType *histData; histData = (histType *)userPointer; /* store pointer to the histogram array, and initialize to zero */ switch( histData->himagetype ) { case TBYTE: histData->hist.b = (char * ) fits_iter_get_array(imagepars); break; case TSHORT: histData->hist.i = (short * ) fits_iter_get_array(imagepars); break; case TINT: histData->hist.j = (int * ) fits_iter_get_array(imagepars); break; case TFLOAT: histData->hist.r = (float * ) fits_iter_get_array(imagepars); break; case TDOUBLE: histData->hist.d = (double *) fits_iter_get_array(imagepars); break; } /* set the column parameters for the iterator function */ for (ii = 0; ii < histData->haxis; ii++) { fits_iter_set_by_num(&colpars[ii], histData->tblptr, histData->hcolnum[ii], TDOUBLE, InputCol); } ncols = histData->haxis; if (histData->weight == DOUBLENULLVALUE) { fits_iter_set_by_num(&colpars[histData->haxis], histData->tblptr, histData->wtcolnum, TDOUBLE, InputCol); ncols = histData->haxis + 1; } /* call iterator function to calc the histogram pixel values */ /* must lock this call in multithreaded environoments because */ /* the ffcalchist work routine uses static vaiables that would */ /* get clobbered if multiple threads were running at the same time */ FFLOCK; fits_iterate_data(ncols, colpars, offset, rows_per_loop, ffcalchist, (void*)histData, &status); FFUNLOCK; return(status); } /*--------------------------------------------------------------------------*/ int ffcalchist(long totalrows, long offset, long firstrow, long nrows, int ncols, iteratorCol *colpars, void *userPointer) /* Interator work function that calculates values for the 2D histogram. */ { long ii, ipix, iaxisbin; double pix, axisbin; static double *col1, *col2, *col3, *col4; /* static to preserve values */ static double *wtcol; static long incr2, incr3, incr4; static histType histData; static char *rowselect; /* Initialization procedures: execute on the first call */ if (firstrow == 1) { /* Copy input histogram data to static local variable so we */ /* don't have to constantly dereference it. */ histData = *(histType*)userPointer; rowselect = histData.rowselector; /* assign the input array pointers to local pointers */ col1 = (double *) fits_iter_get_array(&colpars[0]); if (histData.haxis > 1) { col2 = (double *) fits_iter_get_array(&colpars[1]); incr2 = histData.haxis1; if (histData.haxis > 2) { col3 = (double *) fits_iter_get_array(&colpars[2]); incr3 = incr2 * histData.haxis2; if (histData.haxis > 3) { col4 = (double *) fits_iter_get_array(&colpars[3]); incr4 = incr3 * histData.haxis3; } } } if (ncols > histData.haxis) /* then weights are give in a column */ { wtcol = (double *) fits_iter_get_array(&colpars[histData.haxis]); } } /* end of Initialization procedures */ /* Main loop: increment the histogram at position of each event */ for (ii = 1; ii <= nrows; ii++) { if (rowselect) /* if a row selector array is supplied... */ { if (*rowselect) { rowselect++; /* this row is included in the histogram */ } else { rowselect++; /* this row is excluded from the histogram */ continue; } } if (col1[ii] == DOUBLENULLVALUE) /* test for null value */ continue; pix = (col1[ii] - histData.amin1) / histData.binsize1; ipix = (long) (pix + 1.); /* add 1 because the 1st pixel is the null value */ /* test if bin is within range */ if (ipix < 1 || ipix > histData.haxis1 || pix > histData.maxbin1) continue; if (histData.haxis > 1) { if (col2[ii] == DOUBLENULLVALUE) continue; axisbin = (col2[ii] - histData.amin2) / histData.binsize2; iaxisbin = (long) axisbin; if (axisbin < 0. || iaxisbin >= histData.haxis2 || axisbin > histData.maxbin2) continue; ipix += (iaxisbin * incr2); if (histData.haxis > 2) { if (col3[ii] == DOUBLENULLVALUE) continue; axisbin = (col3[ii] - histData.amin3) / histData.binsize3; iaxisbin = (long) axisbin; if (axisbin < 0. || iaxisbin >= histData.haxis3 || axisbin > histData.maxbin3) continue; ipix += (iaxisbin * incr3); if (histData.haxis > 3) { if (col4[ii] == DOUBLENULLVALUE) continue; axisbin = (col4[ii] - histData.amin4) / histData.binsize4; iaxisbin = (long) axisbin; if (axisbin < 0. || iaxisbin >= histData.haxis4 || axisbin > histData.maxbin4) continue; ipix += (iaxisbin * incr4); } /* end of haxis > 3 case */ } /* end of haxis > 2 case */ } /* end of haxis > 1 case */ /* increment the histogram pixel */ if (histData.weight != DOUBLENULLVALUE) /* constant weight factor */ { if (histData.himagetype == TINT) histData.hist.j[ipix] += (int) histData.weight; else if (histData.himagetype == TSHORT) histData.hist.i[ipix] += (short) histData.weight; else if (histData.himagetype == TFLOAT) histData.hist.r[ipix] += histData.weight; else if (histData.himagetype == TDOUBLE) histData.hist.d[ipix] += histData.weight; else if (histData.himagetype == TBYTE) histData.hist.b[ipix] += (char) histData.weight; } else if (histData.wtrecip) /* use reciprocal of the weight */ { if (histData.himagetype == TINT) histData.hist.j[ipix] += (int) (1./wtcol[ii]); else if (histData.himagetype == TSHORT) histData.hist.i[ipix] += (short) (1./wtcol[ii]); else if (histData.himagetype == TFLOAT) histData.hist.r[ipix] += (float) (1./wtcol[ii]); else if (histData.himagetype == TDOUBLE) histData.hist.d[ipix] += 1./wtcol[ii]; else if (histData.himagetype == TBYTE) histData.hist.b[ipix] += (char) (1./wtcol[ii]); } else /* no weights */ { if (histData.himagetype == TINT) histData.hist.j[ipix] += (int) wtcol[ii]; else if (histData.himagetype == TSHORT) histData.hist.i[ipix] += (short) wtcol[ii]; else if (histData.himagetype == TFLOAT) histData.hist.r[ipix] += wtcol[ii]; else if (histData.himagetype == TDOUBLE) histData.hist.d[ipix] += wtcol[ii]; else if (histData.himagetype == TBYTE) histData.hist.b[ipix] += (char) wtcol[ii]; } } /* end of main loop over all rows */ return(0); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/imcompress.c0000644000175100001710000134763500000000000020473 0ustar00vstsdocker# include # include # include # include # include # include # include "fitsio2.h" #define NULL_VALUE -2147483647 /* value used to represent undefined pixels */ #define ZERO_VALUE -2147483646 /* value used to represent zero-valued pixels */ /* nearest integer function */ # define NINT(x) ((x >= 0.) ? (int) (x + 0.5) : (int) (x - 0.5)) /* special quantize level value indicates that floating point image pixels */ /* should not be quantized and instead losslessly compressed (with GZIP) */ #define NO_QUANTIZE 9999 /* string array for storing the individual column compression stats */ char results[999][30]; float *fits_rand_value = 0; int imcomp_write_nocompress_tile(fitsfile *outfptr, long row, int datatype, void *tiledata, long tilelen, int nullcheck, void *nullflagval, int *status); int imcomp_convert_tile_tshort(fitsfile *outfptr, void *tiledata, long tilelen, int nullcheck, void *nullflagval, int nullval, int zbitpix, double scale, double zero, double actual_bzero, int *intlength, int *status); int imcomp_convert_tile_tushort(fitsfile *outfptr, void *tiledata, long tilelen, int nullcheck, void *nullflagval, int nullval, int zbitpix, double scale, double zero, int *intlength, int *status); int imcomp_convert_tile_tint(fitsfile *outfptr, void *tiledata, long tilelen, int nullcheck, void *nullflagval, int nullval, int zbitpix, double scale, double zero, int *intlength, int *status); int imcomp_convert_tile_tuint(fitsfile *outfptr, void *tiledata, long tilelen, int nullcheck, void *nullflagval, int nullval, int zbitpix, double scale, double zero, int *intlength, int *status); int imcomp_convert_tile_tbyte(fitsfile *outfptr, void *tiledata, long tilelen, int nullcheck, void *nullflagval, int nullval, int zbitpix, double scale, double zero, int *intlength, int *status); int imcomp_convert_tile_tsbyte(fitsfile *outfptr, void *tiledata, long tilelen, int nullcheck, void *nullflagval, int nullval, int zbitpix, double scale, double zero, int *intlength, int *status); int imcomp_convert_tile_tfloat(fitsfile *outfptr, long row, void *tiledata, long tilelen, long tilenx, long tileny, int nullcheck, void *nullflagval, int nullval, int zbitpix, double scale, double zero, int *intlength, int *flag, double *bscale, double *bzero,int *status); int imcomp_convert_tile_tdouble(fitsfile *outfptr, long row, void *tiledata, long tilelen, long tilenx, long tileny, int nullcheck, void *nullflagval, int nullval, int zbitpix, double scale, double zero, int *intlength, int *flag, double *bscale, double *bzero, int *status); static int unquantize_i1r4(long row, unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int dither_method, /* I - which subtractive dither method to use */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status); /* IO - error status */ static int unquantize_i2r4(long row, short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int dither_method, /* I - which subtractive dither method to use */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status); /* IO - error status */ static int unquantize_i4r4(long row, INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int dither_method, /* I - which subtractive dither method to use */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status); /* IO - error status */ static int unquantize_i1r8(long row, unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int dither_method, /* I - which subtractive dither method to use */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status); /* IO - error status */ static int unquantize_i2r8(long row, short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int dither_method, /* I - which subtractive dither method to use */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status); /* IO - error status */ static int unquantize_i4r8(long row, INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int dither_method, /* I - which subtractive dither method to use */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status); /* IO - error status */ static int imcomp_float2nan(float *indata, long tilelen, int *outdata, float nullflagval, int *status); static int imcomp_double2nan(double *indata, long tilelen, LONGLONG *outdata, double nullflagval, int *status); static int fits_read_write_compressed_img(fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the array to be returned */ LONGLONG *infpixel, /* I - 'bottom left corner' of the subsection */ LONGLONG *inlpixel, /* I - 'top right corner' of the subsection */ long *ininc, /* I - increment to be applied in each dimension */ int nullcheck, /* I - 0 for no null checking */ /* 1: set undefined pixels = nullval */ void *nullval, /* I - value for undefined pixels */ int *anynul, /* O - set to 1 if any values are null; else 0 */ fitsfile *outfptr, /* I - FITS file pointer */ int *status); static int fits_shuffle_8bytes(char *heap, LONGLONG length, int *status); static int fits_shuffle_4bytes(char *heap, LONGLONG length, int *status); static int fits_shuffle_2bytes(char *heap, LONGLONG length, int *status); static int fits_unshuffle_8bytes(char *heap, LONGLONG length, int *status); static int fits_unshuffle_4bytes(char *heap, LONGLONG length, int *status); static int fits_unshuffle_2bytes(char *heap, LONGLONG length, int *status); static int fits_int_to_longlong_inplace(int *intarray, long length, int *status); static int fits_short_to_int_inplace(short *intarray, long length, int shift, int *status); static int fits_ushort_to_int_inplace(unsigned short *intarray, long length, int shift, int *status); static int fits_sbyte_to_int_inplace(signed char *intarray, long length, int *status); static int fits_ubyte_to_int_inplace(unsigned char *intarray, long length, int *status); static int fits_calc_tile_rows(long *tlpixel, long *tfpixel, int ndim, long *trowsize, long *ntrows, int *status); /* only used for diagnoitic purposes */ /* int fits_get_case(int *c1, int*c2, int*c3); */ /*---------------------------------------------------------------------------*/ int fits_init_randoms(void) { /* initialize an array of random numbers */ int ii; double a = 16807.0; double m = 2147483647.0; double temp, seed; FFLOCK; if (fits_rand_value) { FFUNLOCK; return(0); /* array is already initialized */ } /* allocate array for the random number sequence */ /* THIS MEMORY IS NEVER FREED */ fits_rand_value = calloc(N_RANDOM, sizeof(float)); if (!fits_rand_value) { FFUNLOCK; return(MEMORY_ALLOCATION); } /* We need a portable algorithm that anyone can use to generate this exact same sequence of random number. The C 'rand' function is not suitable because it is not available to Fortran or Java programmers. Instead, use a well known simple algorithm published here: "Random number generators: good ones are hard to find", Communications of the ACM, Volume 31 , Issue 10 (October 1988) Pages: 1192 - 1201 */ /* initialize the random numbers */ seed = 1; for (ii = 0; ii < N_RANDOM; ii++) { temp = a * seed; seed = temp -m * ((int) (temp / m) ); fits_rand_value[ii] = (float) (seed / m); } FFUNLOCK; /* IMPORTANT NOTE: the 10000th seed value must have the value 1043618065 if the algorithm has been implemented correctly */ if ( (int) seed != 1043618065) { ffpmsg("fits_init_randoms generated incorrect random number sequence"); return(1); } else { return(0); } } /*--------------------------------------------------------------------------*/ void bz_internal_error(int errcode) { /* external function declared by the bzip2 code in bzlib_private.h */ ffpmsg("bzip2 returned an internal error"); ffpmsg("This should never happen"); return; } /*--------------------------------------------------------------------------*/ int fits_set_compression_type(fitsfile *fptr, /* I - FITS file pointer */ int ctype, /* image compression type code; */ /* allowed values: RICE_1, GZIP_1, GZIP_2, PLIO_1, */ /* HCOMPRESS_1, BZIP2_1, and NOCOMPRESS */ int *status) /* IO - error status */ { /* This routine specifies the image compression algorithm that should be used when writing a FITS image. The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ if (ctype != RICE_1 && ctype != GZIP_1 && ctype != GZIP_2 && ctype != PLIO_1 && ctype != HCOMPRESS_1 && ctype != BZIP2_1 && ctype != NOCOMPRESS && ctype != 0) { ffpmsg("unknown compression algorithm (fits_set_compression_type)"); *status = DATA_COMPRESSION_ERR; } else { (fptr->Fptr)->request_compress_type = ctype; } return(*status); } /*--------------------------------------------------------------------------*/ int fits_set_tile_dim(fitsfile *fptr, /* I - FITS file pointer */ int ndim, /* number of dimensions in the compressed image */ long *dims, /* size of image compression tile in each dimension */ /* default tile size = (NAXIS1, 1, 1, ...) */ int *status) /* IO - error status */ { /* This routine specifies the size (dimension) of the image compression tiles that should be used when writing a FITS image. The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ int ii; if (ndim < 0 || ndim > MAX_COMPRESS_DIM) { *status = BAD_DIMEN; ffpmsg("illegal number of tile dimensions (fits_set_tile_dim)"); return(*status); } for (ii = 0; ii < ndim; ii++) { (fptr->Fptr)->request_tilesize[ii] = dims[ii]; } return(*status); } /*--------------------------------------------------------------------------*/ int fits_set_quantize_level(fitsfile *fptr, /* I - FITS file pointer */ float qlevel, /* floating point quantization level */ int *status) /* IO - error status */ { /* This routine specifies the value of the quantization level, q, that should be used when compressing floating point images. The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ if (qlevel == 0.) { /* this means don't quantize the floating point values. Instead, */ /* the floating point values will be losslessly compressed */ (fptr->Fptr)->request_quantize_level = NO_QUANTIZE; } else { (fptr->Fptr)->request_quantize_level = qlevel; } return(*status); } /*--------------------------------------------------------------------------*/ int fits_set_quantize_method(fitsfile *fptr, /* I - FITS file pointer */ int method, /* quantization method */ int *status) /* IO - error status */ { /* This routine specifies what type of dithering (randomization) should be performed when quantizing floating point images to integer prior to compression. A value of -1 means do no dithering. A value of 0 means use the default SUBTRACTIVE_DITHER_1 (which is equivalent to dither = 1). A value of 2 means use SUBTRACTIVE_DITHER_2. */ if (method < -1 || method > 2) { ffpmsg("illegal dithering value (fits_set_quantize_method)"); *status = DATA_COMPRESSION_ERR; } else { if (method == 0) method = 1; (fptr->Fptr)->request_quantize_method = method; } return(*status); } /*--------------------------------------------------------------------------*/ int fits_set_quantize_dither(fitsfile *fptr, /* I - FITS file pointer */ int dither, /* dither type */ int *status) /* IO - error status */ { /* the name of this routine has changed. This is kept here only for backwards compatibility for any software that may be calling the old routine. */ fits_set_quantize_method(fptr, dither, status); return(*status); } /*--------------------------------------------------------------------------*/ int fits_set_dither_seed(fitsfile *fptr, /* I - FITS file pointer */ int seed, /* random dithering seed value (1 to 10000) */ int *status) /* IO - error status */ { /* This routine specifies the value of the offset that should be applied when calculating the random dithering when quantizing floating point iamges. A random offset should be applied to each image to avoid quantization effects when taking the difference of 2 images, or co-adding a set of images. Without this random offset, the corresponding pixel in every image will have exactly the same dithering. offset = 0 means use the default random dithering based on system time offset = negative means randomly chose dithering based on 1st tile checksum offset = [1 - 10000] means use that particular dithering pattern */ /* if positive, ensure that the value is in the range 1 to 10000 */ if (seed > 10000) { ffpmsg("illegal dithering seed value (fits_set_dither_seed)"); *status = DATA_COMPRESSION_ERR; } else { (fptr->Fptr)->request_dither_seed = seed; } return(*status); } /*--------------------------------------------------------------------------*/ int fits_set_dither_offset(fitsfile *fptr, /* I - FITS file pointer */ int offset, /* random dithering offset value (1 to 10000) */ int *status) /* IO - error status */ { /* The name of this routine has changed. This is kept just for backwards compatibility with any software that calls the old name */ fits_set_dither_seed(fptr, offset, status); return(*status); } /*--------------------------------------------------------------------------*/ int fits_set_noise_bits(fitsfile *fptr, /* I - FITS file pointer */ int noisebits, /* noise_bits parameter value */ /* (default = 4) */ int *status) /* IO - error status */ { /* ******************************************************************** ******************************************************************** THIS ROUTINE IS PROVIDED ONLY FOR BACKWARDS COMPATIBILITY; ALL NEW SOFTWARE SHOULD CALL fits_set_quantize_level INSTEAD ******************************************************************** ******************************************************************** This routine specifies the value of the noice_bits parameter that should be used when compressing floating point images. The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. Feb 2008: the "noisebits" parameter has been replaced with the more general "quantize level" parameter. */ float qlevel; if (noisebits < 1 || noisebits > 16) { *status = DATA_COMPRESSION_ERR; ffpmsg("illegal number of noise bits (fits_set_noise_bits)"); return(*status); } qlevel = (float) pow (2., (double)noisebits); fits_set_quantize_level(fptr, qlevel, status); return(*status); } /*--------------------------------------------------------------------------*/ int fits_set_hcomp_scale(fitsfile *fptr, /* I - FITS file pointer */ float scale, /* hcompress scale parameter value */ /* (default = 0.) */ int *status) /* IO - error status */ { /* This routine specifies the value of the hcompress scale parameter. */ (fptr->Fptr)->request_hcomp_scale = scale; return(*status); } /*--------------------------------------------------------------------------*/ int fits_set_hcomp_smooth(fitsfile *fptr, /* I - FITS file pointer */ int smooth, /* hcompress smooth parameter value */ /* if scale > 1 and smooth != 0, then */ /* the image will be smoothed when it is */ /* decompressed to remove some of the */ /* 'blockiness' in the image produced */ /* by the lossy compression */ int *status) /* IO - error status */ { /* This routine specifies the value of the hcompress scale parameter. */ (fptr->Fptr)->request_hcomp_smooth = smooth; return(*status); } /*--------------------------------------------------------------------------*/ int fits_set_lossy_int(fitsfile *fptr, /* I - FITS file pointer */ int lossy_int, /* I - True (!= 0) or False (0) */ int *status) /* IO - error status */ { /* This routine specifies whether images with integer pixel values should quantized and compressed the same way float images are compressed. The default is to not do this, and instead apply a lossless compression algorithm to integer images. */ (fptr->Fptr)->request_lossy_int_compress = lossy_int; return(*status); } /*--------------------------------------------------------------------------*/ int fits_set_huge_hdu(fitsfile *fptr, /* I - FITS file pointer */ int huge, /* I - True (!= 0) or False (0) */ int *status) /* IO - error status */ { /* This routine specifies whether the HDU that is being compressed is so large (i.e., > 4 GB) that the 'Q' type variable length array columns should be used rather than the normal 'P' type. The allows the heap pointers to be stored as 64-bit quantities, rather than just 32-bits. */ (fptr->Fptr)->request_huge_hdu = huge; return(*status); } /*--------------------------------------------------------------------------*/ int fits_get_compression_type(fitsfile *fptr, /* I - FITS file pointer */ int *ctype, /* image compression type code; */ /* allowed values: */ /* RICE_1, GZIP_1, GZIP_2, PLIO_1, HCOMPRESS_1, BZIP2_1 */ int *status) /* IO - error status */ { /* This routine returns the image compression algorithm that should be used when writing a FITS image. The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ *ctype = (fptr->Fptr)->request_compress_type; if (*ctype != RICE_1 && *ctype != GZIP_1 && *ctype != GZIP_2 && *ctype != PLIO_1 && *ctype != HCOMPRESS_1 && *ctype != BZIP2_1 && *ctype != NOCOMPRESS && *ctype != 0 ) { ffpmsg("unknown compression algorithm (fits_get_compression_type)"); *status = DATA_COMPRESSION_ERR; } return(*status); } /*--------------------------------------------------------------------------*/ int fits_get_tile_dim(fitsfile *fptr, /* I - FITS file pointer */ int ndim, /* number of dimensions in the compressed image */ long *dims, /* size of image compression tile in each dimension */ /* default tile size = (NAXIS1, 1, 1, ...) */ int *status) /* IO - error status */ { /* This routine returns the size (dimension) of the image compression tiles that should be used when writing a FITS image. The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ int ii; if (ndim < 0 || ndim > MAX_COMPRESS_DIM) { *status = BAD_DIMEN; ffpmsg("illegal number of tile dimensions (fits_get_tile_dim)"); return(*status); } for (ii = 0; ii < ndim; ii++) { dims[ii] = (fptr->Fptr)->request_tilesize[ii]; } return(*status); } /*--------------------------------------------------------------------------*/ int fits_unset_compression_param( fitsfile *fptr, int *status) { int ii; (fptr->Fptr)->compress_type = 0; (fptr->Fptr)->quantize_level = 0; (fptr->Fptr)->quantize_method = 0; (fptr->Fptr)->dither_seed = 0; (fptr->Fptr)->hcomp_scale = 0; for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { (fptr->Fptr)->tilesize[ii] = 0; } return(*status); } /*--------------------------------------------------------------------------*/ int fits_unset_compression_request( fitsfile *fptr, int *status) { int ii; (fptr->Fptr)->request_compress_type = 0; (fptr->Fptr)->request_quantize_level = 0; (fptr->Fptr)->request_quantize_method = 0; (fptr->Fptr)->request_dither_seed = 0; (fptr->Fptr)->request_hcomp_scale = 0; (fptr->Fptr)->request_lossy_int_compress = 0; (fptr->Fptr)->request_huge_hdu = 0; for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { (fptr->Fptr)->request_tilesize[ii] = 0; } return(*status); } /*--------------------------------------------------------------------------*/ int fits_set_compression_pref( fitsfile *infptr, fitsfile *outfptr, int *status) { /* Set the preference for various compression options, based on keywords in the input file that provide guidance about how the HDU should be compressed when written to the output file. */ int ii, naxis, nkeys, comptype; int ivalue; long tiledim[6]= {1,1,1,1,1,1}; char card[FLEN_CARD], value[FLEN_VALUE]; double qvalue; float hscale; LONGLONG datastart, dataend; if (*status > 0) return(*status); /* check the size of the HDU that is to be compressed */ fits_get_hduaddrll(infptr, NULL, &datastart, &dataend, status); if ( (LONGLONG)(dataend - datastart) > UINT32_MAX) { /* use 64-bit '1Q' variable length columns instead of '1P' columns */ /* for large files, in case the heap size becomes larger than 2**32 bytes*/ fits_set_huge_hdu(outfptr, 1, status); } fits_get_hdrspace(infptr, &nkeys, NULL, status); /* look for a image compression directive keywords (begin with 'FZ') */ for (ii = 2; ii <= nkeys; ii++) { fits_read_record(infptr, ii, card, status); if (!strncmp(card, "FZ", 2) ){ /* get the keyword value string */ fits_parse_value(card, value, NULL, status); if (!strncmp(card+2, "ALGOR", 5) ) { /* set the desired compression algorithm */ /* allowed values: RICE_1, GZIP_1, GZIP_2, PLIO_1, */ /* HCOMPRESS_1, BZIP2_1, and NOCOMPRESS */ if (!fits_strncasecmp(value, "'RICE_1", 7) ) { comptype = RICE_1; } else if (!fits_strncasecmp(value, "'GZIP_1", 7) ) { comptype = GZIP_1; } else if (!fits_strncasecmp(value, "'GZIP_2", 7) ) { comptype = GZIP_2; } else if (!fits_strncasecmp(value, "'PLIO_1", 7) ) { comptype = PLIO_1; } else if (!fits_strncasecmp(value, "'HCOMPRESS_1", 12) ) { comptype = HCOMPRESS_1; } else if (!fits_strncasecmp(value, "'NONE", 5) ) { comptype = NOCOMPRESS; } else { ffpmsg("Unknown FZALGOR keyword compression algorithm:"); ffpmsg(value); return(*status = DATA_COMPRESSION_ERR); } fits_set_compression_type (outfptr, comptype, status); } else if (!strncmp(card+2, "TILE ", 6) ) { if (!fits_strncasecmp(value, "'row", 4) ) { tiledim[0] = -1; } else if (!fits_strncasecmp(value, "'whole", 6) ) { tiledim[0] = -1; tiledim[1] = -1; tiledim[2] = -1; } else { ffdtdm(infptr, value, 0,6, &naxis, tiledim, status); } /* set the desired tile size */ fits_set_tile_dim (outfptr, 6, tiledim, status); } else if (!strncmp(card+2, "QVALUE", 6) ) { /* set the desired Q quantization value */ qvalue = atof(value); fits_set_quantize_level (outfptr, (float) qvalue, status); } else if (!strncmp(card+2, "QMETHD", 6) ) { if (!fits_strncasecmp(value, "'no_dither", 10) ) { ivalue = -1; /* just quantize, with no dithering */ } else if (!fits_strncasecmp(value, "'subtractive_dither_1", 21) ) { ivalue = SUBTRACTIVE_DITHER_1; /* use subtractive dithering */ } else if (!fits_strncasecmp(value, "'subtractive_dither_2", 21) ) { ivalue = SUBTRACTIVE_DITHER_2; /* dither, except preserve zero-valued pixels */ } else { ffpmsg("Unknown value for FZQUANT keyword: (set_compression_pref)"); ffpmsg(value); return(*status = DATA_COMPRESSION_ERR); } fits_set_quantize_method(outfptr, ivalue, status); } else if (!strncmp(card+2, "DTHRSD", 6) ) { if (!fits_strncasecmp(value, "'checksum", 9) ) { ivalue = -1; /* use checksum of first tile */ } else if (!fits_strncasecmp(value, "'clock", 6) ) { ivalue = 0; /* set dithering seed based on system clock */ } else { /* read integer value */ if (*value == '\'') ivalue = (int) atol(value+1); /* allow for leading quote character */ else ivalue = (int) atol(value); if (ivalue < 1 || ivalue > 10000) { ffpmsg("Invalid value for FZDTHRSD keyword: (set_compression_pref)"); ffpmsg(value); return(*status = DATA_COMPRESSION_ERR); } } /* set the desired dithering */ fits_set_dither_seed(outfptr, ivalue, status); } else if (!strncmp(card+2, "I2F", 3) ) { /* set whether to convert integers to float then use lossy compression */ if (!fits_strcasecmp(value, "t") ) { fits_set_lossy_int (outfptr, 1, status); } else if (!fits_strcasecmp(value, "f") ) { fits_set_lossy_int (outfptr, 0, status); } else { ffpmsg("Unknown value for FZI2F keyword: (set_compression_pref)"); ffpmsg(value); return(*status = DATA_COMPRESSION_ERR); } } else if (!strncmp(card+2, "HSCALE ", 6) ) { /* set the desired Hcompress scale value */ hscale = (float) atof(value); fits_set_hcomp_scale (outfptr, hscale, status); } } } return(*status); } /*--------------------------------------------------------------------------*/ int fits_get_noise_bits(fitsfile *fptr, /* I - FITS file pointer */ int *noisebits, /* noise_bits parameter value */ /* (default = 4) */ int *status) /* IO - error status */ { /* ******************************************************************** ******************************************************************** THIS ROUTINE IS PROVIDED ONLY FOR BACKWARDS COMPATIBILITY; ALL NEW SOFTWARE SHOULD CALL fits_set_quantize_level INSTEAD ******************************************************************** ******************************************************************** This routine returns the value of the noice_bits parameter that should be used when compressing floating point images. The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. Feb 2008: code changed to use the more general "quantize level" parameter rather than the "noise bits" parameter. If quantize level is greater than zero, then the previous noisebits parameter is approximately given by noise bits = natural logarithm (quantize level) / natural log (2) This result is rounded to the nearest integer. */ double qlevel; qlevel = (fptr->Fptr)->request_quantize_level; if (qlevel > 0. && qlevel < 65537. ) *noisebits = (int) ((log(qlevel) / log(2.0)) + 0.5); else *noisebits = 0; return(*status); } /*--------------------------------------------------------------------------*/ int fits_get_quantize_level(fitsfile *fptr, /* I - FITS file pointer */ float *qlevel, /* quantize level parameter value */ int *status) /* IO - error status */ { /* This routine returns the value of the noice_bits parameter that should be used when compressing floating point images. The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ if ((fptr->Fptr)->request_quantize_level == NO_QUANTIZE) { *qlevel = 0; } else { *qlevel = (fptr->Fptr)->request_quantize_level; } return(*status); } /*--------------------------------------------------------------------------*/ int fits_get_dither_seed(fitsfile *fptr, /* I - FITS file pointer */ int *offset, /* dithering offset parameter value */ int *status) /* IO - error status */ { /* This routine returns the value of the dithering offset parameter that is used when compressing floating point images. The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ *offset = (fptr->Fptr)->request_dither_seed; return(*status); }/*--------------------------------------------------------------------------*/ int fits_get_hcomp_scale(fitsfile *fptr, /* I - FITS file pointer */ float *scale, /* Hcompress scale parameter value */ int *status) /* IO - error status */ { /* This routine returns the value of the noice_bits parameter that should be used when compressing floating point images. The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ *scale = (fptr->Fptr)->request_hcomp_scale; return(*status); } /*--------------------------------------------------------------------------*/ int fits_get_hcomp_smooth(fitsfile *fptr, /* I - FITS file pointer */ int *smooth, /* Hcompress smooth parameter value */ int *status) /* IO - error status */ { *smooth = (fptr->Fptr)->request_hcomp_smooth; return(*status); } /*--------------------------------------------------------------------------*/ int fits_img_compress(fitsfile *infptr, /* pointer to image to be compressed */ fitsfile *outfptr, /* empty HDU for output compressed image */ int *status) /* IO - error status */ /* This routine initializes the output table, copies all the keywords, and loops through the input image, compressing the data and writing the compressed tiles to the output table. This is a high level routine that is called by the fpack and funpack FITS compression utilities. */ { int bitpix, naxis; long naxes[MAX_COMPRESS_DIM]; /* int c1, c2, c3; */ if (*status > 0) return(*status); /* get datatype and size of input image */ if (fits_get_img_param(infptr, MAX_COMPRESS_DIM, &bitpix, &naxis, naxes, status) > 0) return(*status); if (naxis < 1 || naxis > MAX_COMPRESS_DIM) { ffpmsg("Image cannot be compressed: NAXIS out of range"); return(*status = BAD_NAXIS); } /* create a new empty HDU in the output file now, before setting the */ /* compression preferences. This HDU will become a binary table that */ /* contains the compressed image. If necessary, create a dummy primary */ /* array, which much precede the binary table extension. */ ffcrhd(outfptr, status); /* this does nothing if the output file is empty */ if ((outfptr->Fptr)->curhdu == 0) /* have to create dummy primary array */ { ffcrim(outfptr, 16, 0, NULL, status); ffcrhd(outfptr, status); } else { /* unset any compress parameter preferences that may have been set when closing the previous HDU in the output file */ fits_unset_compression_param(outfptr, status); } /* set any compress parameter preferences as given in the input file */ fits_set_compression_pref(infptr, outfptr, status); /* special case: the quantization level is not given by a keyword in */ /* the HDU header, so we have to explicitly copy the requested value */ /* to the actual value */ /* do this in imcomp_get_compressed_image_par, instead if ( (outfptr->Fptr)->request_quantize_level != 0.) (outfptr->Fptr)->quantize_level = (outfptr->Fptr)->request_quantize_level; */ /* if requested, treat integer images same as a float image. */ /* Then the pixels will be quantized (lossy algorithm) to achieve */ /* higher amounts of compression than with lossless algorithms */ if ( (outfptr->Fptr)->request_lossy_int_compress != 0 && bitpix > 0) bitpix = FLOAT_IMG; /* compress integer images as if float */ /* initialize output table */ if (imcomp_init_table(outfptr, bitpix, naxis, naxes, 0, status) > 0) return (*status); /* Copy the image header keywords to the table header. */ if (imcomp_copy_img2comp(infptr, outfptr, status) > 0) return (*status); /* turn off any intensity scaling (defined by BSCALE and BZERO */ /* keywords) so that unscaled values will be read by CFITSIO */ /* (except if quantizing an int image, same as a float image) */ if ( (outfptr->Fptr)->request_lossy_int_compress == 0 && bitpix > 0) ffpscl(infptr, 1.0, 0.0, status); /* force a rescan of the output file keywords, so that */ /* the compression parameters will be copied to the internal */ /* fitsfile structure used by CFITSIO */ ffrdef(outfptr, status); /* turn off any intensity scaling (defined by BSCALE and BZERO */ /* keywords) so that unscaled values will be written by CFITSIO */ /* (except if quantizing an int image, same as a float image) */ if ( (outfptr->Fptr)->request_lossy_int_compress == 0 && bitpix > 0) ffpscl(outfptr, 1.0, 0.0, status); /* Read each image tile, compress, and write to a table row. */ imcomp_compress_image (infptr, outfptr, status); /* force another rescan of the output file keywords, to */ /* update PCOUNT and TFORMn = '1PB(iii)' keyword values. */ ffrdef(outfptr, status); /* unset any previously set compress parameter preferences */ fits_unset_compression_request(outfptr, status); /* fits_get_case(&c1, &c2, &c3); printf("c1, c2, c3 = %d, %d, %d\n", c1, c2, c3); */ return (*status); } /*--------------------------------------------------------------------------*/ int imcomp_init_table(fitsfile *outfptr, int inbitpix, int naxis, long *naxes, int writebitpix, /* write the ZBITPIX, ZNAXIS, and ZNAXES keyword? */ int *status) /* create a BINTABLE extension for the output compressed image. */ { char keyname[FLEN_KEYWORD], zcmptype[12]; int ii, remain, ndiv, addToDim, ncols, bitpix; long nrows; char *ttype[] = {"COMPRESSED_DATA", "ZSCALE", "ZZERO"}; char *tform[3]; char tf0[4], tf1[4], tf2[4]; char *tunit[] = {"\0", "\0", "\0" }; char comm[FLEN_COMMENT]; long actual_tilesize[MAX_COMPRESS_DIM]; /* Actual size to use for tiles */ int is_primary=0; /* Is this attempting to write to the primary? */ int nQualifyDims=0; /* For Hcompress, number of image dimensions with required pixels. */ int noHigherDims=1; /* Set to true if all tile dims other than x are size 1. */ int firstDim=-1, secondDim=-1; /* Indices of first and second tiles dimensions with width > 1 */ if (*status > 0) return(*status); /* check for special case of losslessly compressing floating point */ /* images. Only compression algorithm that supports this is GZIP */ if ( (inbitpix < 0) && ((outfptr->Fptr)->request_quantize_level == NO_QUANTIZE) ) { if (((outfptr->Fptr)->request_compress_type != GZIP_1) && ((outfptr->Fptr)->request_compress_type != GZIP_2)) { ffpmsg("Lossless compression of floating point images must use GZIP (imcomp_init_table)"); return(*status = DATA_COMPRESSION_ERR); } } /* set default compression parameter values, if undefined */ if ( (outfptr->Fptr)->request_compress_type == 0) { /* use RICE_1 by default */ (outfptr->Fptr)->request_compress_type = RICE_1; } if (inbitpix < 0 && (outfptr->Fptr)->request_quantize_level != NO_QUANTIZE) { /* set defaults for quantizing floating point images */ if ( (outfptr->Fptr)->request_quantize_method == 0) { /* set default dithering method */ (outfptr->Fptr)->request_quantize_method = SUBTRACTIVE_DITHER_1; } if ( (outfptr->Fptr)->request_quantize_level == 0) { if ((outfptr->Fptr)->request_quantize_method == NO_DITHER) { /* must use finer quantization if no dithering is done */ (outfptr->Fptr)->request_quantize_level = 16; } else { (outfptr->Fptr)->request_quantize_level = 4; } } } /* special case: the quantization level is not given by a keyword in */ /* the HDU header, so we have to explicitly copy the requested value */ /* to the actual value */ /* do this in imcomp_get_compressed_image_par, instead if ( (outfptr->Fptr)->request_quantize_level != 0.) (outfptr->Fptr)->quantize_level = (outfptr->Fptr)->request_quantize_level; */ /* test for the 2 special cases that represent unsigned integers */ if (inbitpix == USHORT_IMG) bitpix = SHORT_IMG; else if (inbitpix == ULONG_IMG) bitpix = LONG_IMG; else if (inbitpix == SBYTE_IMG) bitpix = BYTE_IMG; else bitpix = inbitpix; /* reset default tile dimensions too if required */ memcpy(actual_tilesize, outfptr->Fptr->request_tilesize, MAX_COMPRESS_DIM * sizeof(long)); if ((outfptr->Fptr)->request_compress_type == HCOMPRESS_1) { /* Tiles must ultimately have 2 (and only 2) dimensions, each with at least 4 pixels. First catch the case where the image itself won't allow this. */ if (naxis < 2 ) { ffpmsg("Hcompress cannot be used with 1-dimensional images (imcomp_init_table)"); return(*status = DATA_COMPRESSION_ERR); } for (ii=0; ii= 4) ++nQualifyDims; } if (nQualifyDims < 2) { ffpmsg("Hcompress minimum image dimension is 4 pixels (imcomp_init_table)"); return(*status = DATA_COMPRESSION_ERR); } /* Handle 2 special cases for backwards compatibility. 1) If both X and Y tile dims are set to full size, ignore any other requested dimensions and just set their sizes to 1. 2) If X is full size and all the rest are size 1, attempt to find a reasonable size for Y. All other 1-D tile specifications will be rejected. */ for (ii=1; ii 3) { actual_tilesize[1] = 16; } else if (naxes[1] % 24 == 0 || naxes[1] % 24 > 3) { actual_tilesize[1] = 24; } else if (naxes[1] % 20 == 0 || naxes[1] % 20 > 3) { actual_tilesize[1] = 20; } else if (naxes[1] % 30 == 0 || naxes[1] % 30 > 3) { actual_tilesize[1] = 30; } else if (naxes[1] % 28 == 0 || naxes[1] % 28 > 3) { actual_tilesize[1] = 28; } else if (naxes[1] % 26 == 0 || naxes[1] % 26 > 3) { actual_tilesize[1] = 26; } else if (naxes[1] % 22 == 0 || naxes[1] % 22 > 3) { actual_tilesize[1] = 22; } else if (naxes[1] % 18 == 0 || naxes[1] % 18 > 3) { actual_tilesize[1] = 18; } else if (naxes[1] % 14 == 0 || naxes[1] % 14 > 3) { actual_tilesize[1] = 14; } else { actual_tilesize[1] = 17; } } } else { if (actual_tilesize[0] <= 0) actual_tilesize[0] = naxes[0]; for (ii=1; ii 1) { if (firstDim < 0) firstDim = ii; else if (secondDim < 0) secondDim = ii; else { ffpmsg("Hcompress tiles can only have 2 dimensions (imcomp_init_table)"); return(*status = DATA_COMPRESSION_ERR); } } } if (firstDim < 0 || secondDim < 0) { ffpmsg("Hcompress tiles must have 2 dimensions (imcomp_init_table)"); return(*status = DATA_COMPRESSION_ERR); } if (actual_tilesize[firstDim] < 4 || actual_tilesize[secondDim] < 4) { ffpmsg("Hcompress minimum tile dimension is 4 pixels (imcomp_init_table)"); return (*status = DATA_COMPRESSION_ERR); } /* check if requested tile size causes the last tile to to have less than 4 pixels */ remain = naxes[firstDim] % (actual_tilesize[firstDim]); /* 1st dimension */ if (remain > 0 && remain < 4) { ndiv = naxes[firstDim]/actual_tilesize[firstDim]; /* integer truncation is intentional */ addToDim = ceil((double)remain/ndiv); (actual_tilesize[firstDim]) += addToDim; /* increase tile size */ remain = naxes[firstDim] % (actual_tilesize[firstDim]); if (remain > 0 && remain < 4) { ffpmsg("Last tile along 1st dimension has less than 4 pixels (imcomp_init_table)"); return(*status = DATA_COMPRESSION_ERR); } } remain = naxes[secondDim] % (actual_tilesize[secondDim]); /* 2nd dimension */ if (remain > 0 && remain < 4) { ndiv = naxes[secondDim]/actual_tilesize[secondDim]; /* integer truncation is intentional */ addToDim = ceil((double)remain/ndiv); (actual_tilesize[secondDim]) += addToDim; /* increase tile size */ remain = naxes[secondDim] % (actual_tilesize[secondDim]); if (remain > 0 && remain < 4) { ffpmsg("Last tile along 2nd dimension has less than 4 pixels (imcomp_init_table)"); return(*status = DATA_COMPRESSION_ERR); } } } /* end, if HCOMPRESS_1 */ for (ii = 0; ii < naxis; ii++) { if (ii == 0) { /* first axis is different */ if (actual_tilesize[ii] <= 0) { actual_tilesize[ii] = naxes[ii]; } } else { if (actual_tilesize[ii] < 0) { actual_tilesize[ii] = naxes[ii]; /* negative value maean use whole length */ } else if (actual_tilesize[ii] == 0) { actual_tilesize[ii] = 1; /* zero value means use default value = 1 */ } } } /* ---- set up array of TFORM strings -------------------------------*/ if ( (outfptr->Fptr)->request_huge_hdu != 0) { strcpy(tf0, "1QB"); } else { strcpy(tf0, "1PB"); } strcpy(tf1, "1D"); strcpy(tf2, "1D"); tform[0] = tf0; tform[1] = tf1; tform[2] = tf2; /* calculate number of rows in output table */ nrows = 1; for (ii = 0; ii < naxis; ii++) { nrows = nrows * ((naxes[ii] - 1)/ (actual_tilesize[ii]) + 1); } /* determine the default number of columns in the output table */ if (bitpix < 0 && (outfptr->Fptr)->request_quantize_level != NO_QUANTIZE) ncols = 3; /* quantized and scaled floating point image */ else ncols = 1; /* default table has just one 'COMPRESSED_DATA' column */ if ((outfptr->Fptr)->request_compress_type == RICE_1) { strcpy(zcmptype, "RICE_1"); } else if ((outfptr->Fptr)->request_compress_type == GZIP_1) { strcpy(zcmptype, "GZIP_1"); } else if ((outfptr->Fptr)->request_compress_type == GZIP_2) { strcpy(zcmptype, "GZIP_2"); } else if ((outfptr->Fptr)->request_compress_type == BZIP2_1) { strcpy(zcmptype, "BZIP2_1"); } else if ((outfptr->Fptr)->request_compress_type == PLIO_1) { strcpy(zcmptype, "PLIO_1"); /* the PLIO compression algorithm outputs short integers, not bytes */ if ( (outfptr->Fptr)->request_huge_hdu != 0) { strcpy(tform[0], "1QI"); } else { strcpy(tform[0], "1PI"); } } else if ((outfptr->Fptr)->request_compress_type == HCOMPRESS_1) { strcpy(zcmptype, "HCOMPRESS_1"); } else if ((outfptr->Fptr)->request_compress_type == NOCOMPRESS) { strcpy(zcmptype, "NOCOMPRESS"); } else { ffpmsg("unknown compression type (imcomp_init_table)"); return(*status = DATA_COMPRESSION_ERR); } /* If attempting to write compressed image to primary, the call to ffcrtb will increment Fptr->curhdu to 1. Therefore we need to test now for setting is_primary */ is_primary = (outfptr->Fptr->curhdu == 0); /* create the bintable extension to contain the compressed image */ ffcrtb(outfptr, BINARY_TBL, nrows, ncols, ttype, tform, tunit, 0, status); /* Add standard header keywords. */ ffpkyl (outfptr, "ZIMAGE", 1, "extension contains compressed image", status); if (writebitpix) { /* write the keywords defining the datatype and dimensions of */ /* the uncompressed image. If not, these keywords will be */ /* copied later from the input uncompressed image */ if (is_primary) ffpkyl (outfptr, "ZSIMPLE", 1, "file does conform to FITS standard", status); ffpkyj (outfptr, "ZBITPIX", bitpix, "data type of original image", status); ffpkyj (outfptr, "ZNAXIS", naxis, "dimension of original image", status); for (ii = 0; ii < naxis; ii++) { snprintf (keyname, FLEN_KEYWORD,"ZNAXIS%d", ii+1); ffpkyj (outfptr, keyname, naxes[ii], "length of original image axis", status); } } for (ii = 0; ii < naxis; ii++) { snprintf (keyname, FLEN_KEYWORD,"ZTILE%d", ii+1); ffpkyj (outfptr, keyname, actual_tilesize[ii], "size of tiles to be compressed", status); } if (bitpix < 0) { if ((outfptr->Fptr)->request_quantize_level == NO_QUANTIZE) { ffpkys(outfptr, "ZQUANTIZ", "NONE", "Lossless compression without quantization", status); } else { /* Unless dithering has been specifically turned off by setting */ /* request_quantize_method = -1, use dithering by default */ /* when quantizing floating point images. */ if ( (outfptr->Fptr)->request_quantize_method == 0) (outfptr->Fptr)->request_quantize_method = SUBTRACTIVE_DITHER_1; if ((outfptr->Fptr)->request_quantize_method == SUBTRACTIVE_DITHER_1) { ffpkys(outfptr, "ZQUANTIZ", "SUBTRACTIVE_DITHER_1", "Pixel Quantization Algorithm", status); /* also write the associated ZDITHER0 keyword with a default value */ /* which may get updated later. */ ffpky(outfptr, TINT, "ZDITHER0", &((outfptr->Fptr)->request_dither_seed), "dithering offset when quantizing floats", status); } else if ((outfptr->Fptr)->request_quantize_method == SUBTRACTIVE_DITHER_2) { ffpkys(outfptr, "ZQUANTIZ", "SUBTRACTIVE_DITHER_2", "Pixel Quantization Algorithm", status); /* also write the associated ZDITHER0 keyword with a default value */ /* which may get updated later. */ ffpky(outfptr, TINT, "ZDITHER0", &((outfptr->Fptr)->request_dither_seed), "dithering offset when quantizing floats", status); if (!strcmp(zcmptype, "RICE_1")) { /* when using this new dithering method, change the compression type */ /* to an alias, so that old versions of funpack will not be able to */ /* created a corrupted uncompressed image. */ /* ******* can remove this cludge after about June 2015, after most old versions of fpack are gone */ strcpy(zcmptype, "RICE_ONE"); } } else if ((outfptr->Fptr)->request_quantize_method == NO_DITHER) { ffpkys(outfptr, "ZQUANTIZ", "NO_DITHER", "No dithering during quantization", status); } } } ffpkys (outfptr, "ZCMPTYPE", zcmptype, "compression algorithm", status); /* write any algorithm-specific keywords */ if ((outfptr->Fptr)->request_compress_type == RICE_1) { ffpkys (outfptr, "ZNAME1", "BLOCKSIZE", "compression block size", status); /* for now at least, the block size is always 32 */ ffpkyj (outfptr, "ZVAL1", 32, "pixels per block", status); ffpkys (outfptr, "ZNAME2", "BYTEPIX", "bytes per pixel (1, 2, 4, or 8)", status); if (bitpix == BYTE_IMG) ffpkyj (outfptr, "ZVAL2", 1, "bytes per pixel (1, 2, 4, or 8)", status); else if (bitpix == SHORT_IMG) ffpkyj (outfptr, "ZVAL2", 2, "bytes per pixel (1, 2, 4, or 8)", status); else ffpkyj (outfptr, "ZVAL2", 4, "bytes per pixel (1, 2, 4, or 8)", status); } else if ((outfptr->Fptr)->request_compress_type == HCOMPRESS_1) { ffpkys (outfptr, "ZNAME1", "SCALE", "HCOMPRESS scale factor", status); ffpkye (outfptr, "ZVAL1", (outfptr->Fptr)->request_hcomp_scale, 7, "HCOMPRESS scale factor", status); ffpkys (outfptr, "ZNAME2", "SMOOTH", "HCOMPRESS smooth option", status); ffpkyj (outfptr, "ZVAL2", (long) (outfptr->Fptr)->request_hcomp_smooth, "HCOMPRESS smooth option", status); } /* Write the BSCALE and BZERO keywords, if an unsigned integer image */ if (inbitpix == USHORT_IMG) { strcpy(comm, "offset data range to that of unsigned short"); ffpkyg(outfptr, "BZERO", 32768., 0, comm, status); strcpy(comm, "default scaling factor"); ffpkyg(outfptr, "BSCALE", 1.0, 0, comm, status); } else if (inbitpix == SBYTE_IMG) { strcpy(comm, "offset data range to that of signed byte"); ffpkyg(outfptr, "BZERO", -128., 0, comm, status); strcpy(comm, "default scaling factor"); ffpkyg(outfptr, "BSCALE", 1.0, 0, comm, status); } else if (inbitpix == ULONG_IMG) { strcpy(comm, "offset data range to that of unsigned long"); ffpkyg(outfptr, "BZERO", 2147483648., 0, comm, status); strcpy(comm, "default scaling factor"); ffpkyg(outfptr, "BSCALE", 1.0, 0, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int imcomp_calc_max_elem (int comptype, int nx, int zbitpix, int blocksize) /* This function returns the maximum number of bytes in a compressed image line. nx = maximum number of pixels in a tile blocksize is only relevant for RICE compression */ { if (comptype == RICE_1) { if (zbitpix == 16) return (sizeof(short) * nx + nx / blocksize + 2 + 4); else return (sizeof(float) * nx + nx / blocksize + 2 + 4); } else if ((comptype == GZIP_1) || (comptype == GZIP_2)) { /* gzip usually compressed by at least a factor of 2 for I*4 images */ /* and somewhat less for I*2 images */ /* If this size turns out to be too small, then the gzip */ /* compression routine will allocate more space as required */ /* to be on the safe size, allocate buffer same size as input */ if (zbitpix == 16) return(nx * 2); else if (zbitpix == 8) return(nx); else return(nx * 4); } else if (comptype == BZIP2_1) { /* To guarantee that the compressed data will fit, allocate an output buffer of size 1% larger than the uncompressed data, plus 600 bytes */ return((int) (nx * 1.01 * zbitpix / 8. + 601.)); } else if (comptype == HCOMPRESS_1) { /* Imperical evidence suggests in the worst case, the compressed stream could be up to 10% larger than the original image. Add 26 byte overhead, only significant for very small tiles Possible improvement: may need to allow a larger size for 32-bit images */ if (zbitpix == 16 || zbitpix == 8) return( (int) (nx * 2.2 + 26)); /* will be compressing 16-bit int array */ else return( (int) (nx * 4.4 + 26)); /* will be compressing 32-bit int array */ } else return(nx * sizeof(int)); } /*--------------------------------------------------------------------------*/ int imcomp_compress_image (fitsfile *infptr, fitsfile *outfptr, int *status) /* This routine does the following: - reads an image one tile at a time - if it is a float or double image, then it tries to quantize the pixels into scaled integers. - it then compressess the integer pixels, or if the it was not possible to quantize the floating point pixels, then it losslessly compresses them with gzip - writes the compressed byte stream to the output FITS file */ { double *tiledata; int anynul, gotnulls = 0, datatype; long ii, row; int naxis; double dummy = 0., dblnull = DOUBLENULLVALUE; float fltnull = FLOATNULLVALUE; long maxtilelen, tilelen, incre[] = {1, 1, 1, 1, 1, 1}; long naxes[MAX_COMPRESS_DIM], fpixel[MAX_COMPRESS_DIM]; long lpixel[MAX_COMPRESS_DIM], tile[MAX_COMPRESS_DIM]; long tilesize[MAX_COMPRESS_DIM]; long i0, i1, i2, i3, i4, i5, trowsize, ntrows; char card[FLEN_CARD]; if (*status > 0) return(*status); maxtilelen = (outfptr->Fptr)->maxtilelen; /* Allocate buffer to hold 1 tile of data; size depends on which compression algorithm is used: Rice and GZIP will compress byte, short, or int arrays without conversion. PLIO requires 4-byte int values, so byte and short arrays must be converted to int. HCompress internally converts byte or short values to ints, and converts int values to 8-byte longlong integers. */ if ((outfptr->Fptr)->zbitpix == FLOAT_IMG) { datatype = TFLOAT; if ( (outfptr->Fptr)->compress_type == HCOMPRESS_1) { /* need twice as much scratch space (8 bytes per pixel) */ tiledata = (double*) malloc (maxtilelen * 2 *sizeof (float)); } else { tiledata = (double*) malloc (maxtilelen * sizeof (float)); } } else if ((outfptr->Fptr)->zbitpix == DOUBLE_IMG) { datatype = TDOUBLE; tiledata = (double*) malloc (maxtilelen * sizeof (double)); } else if ((outfptr->Fptr)->zbitpix == SHORT_IMG) { datatype = TSHORT; if ( (outfptr->Fptr)->compress_type == RICE_1 || (outfptr->Fptr)->compress_type == GZIP_1 || (outfptr->Fptr)->compress_type == GZIP_2 || (outfptr->Fptr)->compress_type == BZIP2_1 || (outfptr->Fptr)->compress_type == NOCOMPRESS) { /* only need buffer of I*2 pixels for gzip, bzip2, and Rice */ tiledata = (double*) malloc (maxtilelen * sizeof (short)); } else { /* need buffer of I*4 pixels for Hcompress and PLIO */ tiledata = (double*) malloc (maxtilelen * sizeof (int)); } } else if ((outfptr->Fptr)->zbitpix == BYTE_IMG) { datatype = TBYTE; if ( (outfptr->Fptr)->compress_type == RICE_1 || (outfptr->Fptr)->compress_type == BZIP2_1 || (outfptr->Fptr)->compress_type == GZIP_1 || (outfptr->Fptr)->compress_type == GZIP_2) { /* only need buffer of I*1 pixels for gzip, bzip2, and Rice */ tiledata = (double*) malloc (maxtilelen); } else { /* need buffer of I*4 pixels for Hcompress and PLIO */ tiledata = (double*) malloc (maxtilelen * sizeof (int)); } } else if ((outfptr->Fptr)->zbitpix == LONG_IMG) { datatype = TINT; if ( (outfptr->Fptr)->compress_type == HCOMPRESS_1) { /* need twice as much scratch space (8 bytes per pixel) */ tiledata = (double*) malloc (maxtilelen * 2 * sizeof (int)); } else { /* only need buffer of I*4 pixels for gzip, bzip2, Rice, and PLIO */ tiledata = (double*) malloc (maxtilelen * sizeof (int)); } } else { ffpmsg("Bad image datatype. (imcomp_compress_image)"); return (*status = MEMORY_ALLOCATION); } if (tiledata == NULL) { ffpmsg("Out of memory. (imcomp_compress_image)"); return (*status = MEMORY_ALLOCATION); } /* calculate size of tile in each dimension */ naxis = (outfptr->Fptr)->zndim; for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { if (ii < naxis) { naxes[ii] = (outfptr->Fptr)->znaxis[ii]; tilesize[ii] = (outfptr->Fptr)->tilesize[ii]; } else { naxes[ii] = 1; tilesize[ii] = 1; } } row = 1; /* set up big loop over up to 6 dimensions */ for (i5 = 1; i5 <= naxes[5]; i5 += tilesize[5]) { fpixel[5] = i5; lpixel[5] = minvalue(i5 + tilesize[5] - 1, naxes[5]); tile[5] = lpixel[5] - fpixel[5] + 1; for (i4 = 1; i4 <= naxes[4]; i4 += tilesize[4]) { fpixel[4] = i4; lpixel[4] = minvalue(i4 + tilesize[4] - 1, naxes[4]); tile[4] = lpixel[4] - fpixel[4] + 1; for (i3 = 1; i3 <= naxes[3]; i3 += tilesize[3]) { fpixel[3] = i3; lpixel[3] = minvalue(i3 + tilesize[3] - 1, naxes[3]); tile[3] = lpixel[3] - fpixel[3] + 1; for (i2 = 1; i2 <= naxes[2]; i2 += tilesize[2]) { fpixel[2] = i2; lpixel[2] = minvalue(i2 + tilesize[2] - 1, naxes[2]); tile[2] = lpixel[2] - fpixel[2] + 1; for (i1 = 1; i1 <= naxes[1]; i1 += tilesize[1]) { fpixel[1] = i1; lpixel[1] = minvalue(i1 + tilesize[1] - 1, naxes[1]); tile[1] = lpixel[1] - fpixel[1] + 1; for (i0 = 1; i0 <= naxes[0]; i0 += tilesize[0]) { fpixel[0] = i0; lpixel[0] = minvalue(i0 + tilesize[0] - 1, naxes[0]); tile[0] = lpixel[0] - fpixel[0] + 1; /* number of pixels in this tile */ tilelen = tile[0]; for (ii = 1; ii < naxis; ii++) { tilelen *= tile[ii]; } /* read next tile of data from image */ anynul = 0; if (datatype == TFLOAT) { ffgsve(infptr, 1, naxis, naxes, fpixel, lpixel, incre, FLOATNULLVALUE, (float *) tiledata, &anynul, status); } else if (datatype == TDOUBLE) { ffgsvd(infptr, 1, naxis, naxes, fpixel, lpixel, incre, DOUBLENULLVALUE, tiledata, &anynul, status); } else if (datatype == TINT) { ffgsvk(infptr, 1, naxis, naxes, fpixel, lpixel, incre, 0, (int *) tiledata, &anynul, status); } else if (datatype == TSHORT) { ffgsvi(infptr, 1, naxis, naxes, fpixel, lpixel, incre, 0, (short *) tiledata, &anynul, status); } else if (datatype == TBYTE) { ffgsvb(infptr, 1, naxis, naxes, fpixel, lpixel, incre, 0, (unsigned char *) tiledata, &anynul, status); } else { ffpmsg("Error bad datatype of image tile to compress"); free(tiledata); return (*status); } /* now compress the tile, and write to row of binary table */ /* NOTE: we don't have to worry about the presence of null values in the array if it is an integer array: the null value is simply encoded in the compressed array just like any other pixel value. If it is a floating point array, then we need to check for null only if the anynul parameter returned a true value when reading the tile */ /* Collapse sizes of higher dimension tiles into 2 dimensional equivalents needed by the quantizing algorithms for floating point types */ fits_calc_tile_rows(lpixel, fpixel, naxis, &trowsize, &ntrows, status); if (anynul && datatype == TFLOAT) { imcomp_compress_tile(outfptr, row, datatype, tiledata, tilelen, trowsize, ntrows, 1, &fltnull, status); } else if (anynul && datatype == TDOUBLE) { imcomp_compress_tile(outfptr, row, datatype, tiledata, tilelen, trowsize, ntrows, 1, &dblnull, status); } else { imcomp_compress_tile(outfptr, row, datatype, tiledata, tilelen, trowsize, ntrows, 0, &dummy, status); } /* set flag if we found any null values */ if (anynul) gotnulls = 1; /* check for any error in the previous operations */ if (*status > 0) { ffpmsg("Error writing compressed image to table"); free(tiledata); return (*status); } row++; } } } } } } free (tiledata); /* finished with this buffer */ /* insert ZBLANK keyword if necessary; only for TFLOAT or TDOUBLE images */ if (gotnulls) { ffgcrd(outfptr, "ZCMPTYPE", card, status); ffikyj(outfptr, "ZBLANK", COMPRESS_NULL_VALUE, "null value in the compressed integer array", status); } return (*status); } /*--------------------------------------------------------------------------*/ int imcomp_compress_tile (fitsfile *outfptr, long row, /* tile number = row in the binary table that holds the compressed data */ int datatype, void *tiledata, long tilelen, long tilenx, long tileny, int nullcheck, void *nullflagval, int *status) /* This is the main compression routine. This routine does the following to the input tile of pixels: - if it is a float or double image, then it quantizes the pixels - compresses the integer pixel values - writes the compressed byte stream to the FITS file. If the tile cannot be quantized than the raw float or double values are losslessly compressed with gzip and then written to the output table. This input array may be modified by this routine. If the array is of type TINT or TFLOAT, and the compression type is HCOMPRESS, then it must have been allocated to be twice as large (8 bytes per pixel) to provide scratch space. Note that this routine does not fully support the implicit datatype conversion that is supported when writing to normal FITS images. The datatype of the input array must have the same datatype (either signed or unsigned) as the output (compressed) FITS image in some cases. */ { int *idata; /* quantized integer data */ int cn_zblank, zbitpix, nullval; int flag = 1; /* true by default; only = 0 if float data couldn't be quantized */ int intlength; /* size of integers to be compressed */ double scale, zero, actual_bzero; long ii; size_t clen; /* size of cbuf */ short *cbuf; /* compressed data */ int nelem = 0; /* number of bytes */ int tilecol; size_t gzip_nelem = 0; unsigned int bzlen; int ihcompscale; float hcompscale; double noise2, noise3, noise5; double bscale[1] = {1.}, bzero[1] = {0.}; /* scaling parameters */ long hcomp_len; LONGLONG *lldata; if (*status > 0) return(*status); /* check for special case of losslessly compressing floating point */ /* images. Only compression algorithm that supports this is GZIP */ if ( (outfptr->Fptr)->quantize_level == NO_QUANTIZE) { if (((outfptr->Fptr)->compress_type != GZIP_1) && ((outfptr->Fptr)->compress_type != GZIP_2)) { switch (datatype) { case TFLOAT: case TDOUBLE: case TCOMPLEX: case TDBLCOMPLEX: ffpmsg("Lossless compression of floating point images must use GZIP (imcomp_compress_tile)"); return(*status = DATA_COMPRESSION_ERR); default: break; } } } /* free the previously saved tile if the input tile is for the same row */ if ((outfptr->Fptr)->tilerow) { /* has the tile cache been allocated? */ /* calculate the column bin of the compressed tile */ tilecol = (row - 1) % ((long)(((outfptr->Fptr)->znaxis[0] - 1) / ((outfptr->Fptr)->tilesize[0])) + 1); if ((outfptr->Fptr)->tilerow[tilecol] == row) { if (((outfptr->Fptr)->tiledata)[tilecol]) { free(((outfptr->Fptr)->tiledata)[tilecol]); } if (((outfptr->Fptr)->tilenullarray)[tilecol]) { free(((outfptr->Fptr)->tilenullarray)[tilecol]); } ((outfptr->Fptr)->tiledata)[tilecol] = 0; ((outfptr->Fptr)->tilenullarray)[tilecol] = 0; (outfptr->Fptr)->tilerow[tilecol] = 0; (outfptr->Fptr)->tiledatasize[tilecol] = 0; (outfptr->Fptr)->tiletype[tilecol] = 0; (outfptr->Fptr)->tileanynull[tilecol] = 0; } } if ( (outfptr->Fptr)->compress_type == NOCOMPRESS) { /* Special case when using NOCOMPRESS for diagnostic purposes in fpack */ if (imcomp_write_nocompress_tile(outfptr, row, datatype, tiledata, tilelen, nullcheck, nullflagval, status) > 0) { return(*status); } return(*status); } /* =========================================================================== */ /* initialize various parameters */ idata = (int *) tiledata; /* may overwrite the input tiledata in place */ /* zbitpix is the BITPIX keyword value in the uncompressed FITS image */ zbitpix = (outfptr->Fptr)->zbitpix; /* if the tile/image has an integer datatype, see if a null value has */ /* been defined (with the BLANK keyword in a normal FITS image). */ /* If so, and if the input tile array also contains null pixels, */ /* (represented by pixels that have a value = nullflagval) then */ /* any pixels whose value = nullflagval, must be set to the value = nullval */ /* before the pixel array is compressed. These null pixel values must */ /* not be inverse scaled by the BSCALE/BZERO values, if present. */ cn_zblank = (outfptr->Fptr)->cn_zblank; nullval = (outfptr->Fptr)->zblank; if (zbitpix > 0 && cn_zblank != -1) /* If the integer image has no defined null */ nullcheck = 0; /* value, then don't bother checking input array for nulls. */ /* if the BSCALE and BZERO keywords exist, then the input values must */ /* be inverse scaled by this factor, before the values are compressed. */ /* (The program may have turned off scaling, which over rides the keywords) */ scale = (outfptr->Fptr)->cn_bscale; zero = (outfptr->Fptr)->cn_bzero; actual_bzero = (outfptr->Fptr)->cn_actual_bzero; /* =========================================================================== */ /* prepare the tile of pixel values for compression */ if (datatype == TSHORT) { imcomp_convert_tile_tshort(outfptr, tiledata, tilelen, nullcheck, nullflagval, nullval, zbitpix, scale, zero, actual_bzero, &intlength, status); } else if (datatype == TUSHORT) { imcomp_convert_tile_tushort(outfptr, tiledata, tilelen, nullcheck, nullflagval, nullval, zbitpix, scale, zero, &intlength, status); } else if (datatype == TBYTE) { imcomp_convert_tile_tbyte(outfptr, tiledata, tilelen, nullcheck, nullflagval, nullval, zbitpix, scale, zero, &intlength, status); } else if (datatype == TSBYTE) { imcomp_convert_tile_tsbyte(outfptr, tiledata, tilelen, nullcheck, nullflagval, nullval, zbitpix, scale, zero, &intlength, status); } else if (datatype == TINT) { imcomp_convert_tile_tint(outfptr, tiledata, tilelen, nullcheck, nullflagval, nullval, zbitpix, scale, zero, &intlength, status); } else if (datatype == TUINT) { imcomp_convert_tile_tuint(outfptr, tiledata, tilelen, nullcheck, nullflagval, nullval, zbitpix, scale, zero, &intlength, status); } else if (datatype == TLONG && sizeof(long) == 8) { ffpmsg("Integer*8 Long datatype is not supported when writing to compressed images"); return(*status = BAD_DATATYPE); } else if (datatype == TULONG && sizeof(long) == 8) { ffpmsg("Unsigned integer*8 datatype is not supported when writing to compressed images"); return(*status = BAD_DATATYPE); } else if (datatype == TFLOAT) { imcomp_convert_tile_tfloat(outfptr, row, tiledata, tilelen, tilenx, tileny, nullcheck, nullflagval, nullval, zbitpix, scale, zero, &intlength, &flag, bscale, bzero, status); } else if (datatype == TDOUBLE) { imcomp_convert_tile_tdouble(outfptr, row, tiledata, tilelen, tilenx, tileny, nullcheck, nullflagval, nullval, zbitpix, scale, zero, &intlength, &flag, bscale, bzero, status); } else { ffpmsg("unsupported image datatype (imcomp_compress_tile)"); return(*status = BAD_DATATYPE); } if (*status > 0) return(*status); /* return if error occurs */ /* =========================================================================== */ if (flag) /* now compress the integer data array */ { /* allocate buffer for the compressed tile bytes */ clen = (outfptr->Fptr)->maxelem; cbuf = (short *) calloc (clen, sizeof (unsigned char)); if (cbuf == NULL) { ffpmsg("Memory allocation failure. (imcomp_compress_tile)"); return (*status = MEMORY_ALLOCATION); } /* =========================================================================== */ if ( (outfptr->Fptr)->compress_type == RICE_1) { if (intlength == 2) { nelem = fits_rcomp_short ((short *)idata, tilelen, (unsigned char *) cbuf, clen, (outfptr->Fptr)->rice_blocksize); } else if (intlength == 1) { nelem = fits_rcomp_byte ((signed char *)idata, tilelen, (unsigned char *) cbuf, clen, (outfptr->Fptr)->rice_blocksize); } else { nelem = fits_rcomp (idata, tilelen, (unsigned char *) cbuf, clen, (outfptr->Fptr)->rice_blocksize); } if (nelem < 0) /* data compression error condition */ { free (cbuf); ffpmsg("error Rice compressing image tile (imcomp_compress_tile)"); return (*status = DATA_COMPRESSION_ERR); } /* Write the compressed byte stream. */ ffpclb(outfptr, (outfptr->Fptr)->cn_compressed, row, 1, nelem, (unsigned char *) cbuf, status); } /* =========================================================================== */ else if ( (outfptr->Fptr)->compress_type == PLIO_1) { for (ii = 0; ii < tilelen; ii++) { if (idata[ii] < 0 || idata[ii] > 16777215) { /* plio algorithn only supports positive 24 bit ints */ ffpmsg("data out of range for PLIO compression (0 - 2**24)"); return(*status = DATA_COMPRESSION_ERR); } } nelem = pl_p2li (idata, 1, cbuf, tilelen); if (nelem < 0) /* data compression error condition */ { free (cbuf); ffpmsg("error PLIO compressing image tile (imcomp_compress_tile)"); return (*status = DATA_COMPRESSION_ERR); } /* Write the compressed byte stream. */ ffpcli(outfptr, (outfptr->Fptr)->cn_compressed, row, 1, nelem, cbuf, status); } /* =========================================================================== */ else if ( ((outfptr->Fptr)->compress_type == GZIP_1) || ((outfptr->Fptr)->compress_type == GZIP_2) ) { if ((outfptr->Fptr)->quantize_level == NO_QUANTIZE && datatype == TFLOAT) { /* Special case of losslessly compressing floating point pixels with GZIP */ /* In this case we compress the input tile array directly */ #if BYTESWAPPED ffswap4((int*) tiledata, tilelen); #endif if ( (outfptr->Fptr)->compress_type == GZIP_2 ) fits_shuffle_4bytes((char *) tiledata, tilelen, status); compress2mem_from_mem((char *) tiledata, tilelen * sizeof(float), (char **) &cbuf, &clen, realloc, &gzip_nelem, status); } else if ((outfptr->Fptr)->quantize_level == NO_QUANTIZE && datatype == TDOUBLE) { /* Special case of losslessly compressing double pixels with GZIP */ /* In this case we compress the input tile array directly */ #if BYTESWAPPED ffswap8((double *) tiledata, tilelen); #endif if ( (outfptr->Fptr)->compress_type == GZIP_2 ) fits_shuffle_8bytes((char *) tiledata, tilelen, status); compress2mem_from_mem((char *) tiledata, tilelen * sizeof(double), (char **) &cbuf, &clen, realloc, &gzip_nelem, status); } else { /* compress the integer idata array */ #if BYTESWAPPED if (intlength == 2) ffswap2((short *) idata, tilelen); else if (intlength == 4) ffswap4(idata, tilelen); #endif if (intlength == 2) { if ( (outfptr->Fptr)->compress_type == GZIP_2 ) fits_shuffle_2bytes((char *) tiledata, tilelen, status); compress2mem_from_mem((char *) idata, tilelen * sizeof(short), (char **) &cbuf, &clen, realloc, &gzip_nelem, status); } else if (intlength == 1) { compress2mem_from_mem((char *) idata, tilelen * sizeof(unsigned char), (char **) &cbuf, &clen, realloc, &gzip_nelem, status); } else { if ( (outfptr->Fptr)->compress_type == GZIP_2 ) fits_shuffle_4bytes((char *) tiledata, tilelen, status); compress2mem_from_mem((char *) idata, tilelen * sizeof(int), (char **) &cbuf, &clen, realloc, &gzip_nelem, status); } } /* Write the compressed byte stream. */ ffpclb(outfptr, (outfptr->Fptr)->cn_compressed, row, 1, gzip_nelem, (unsigned char *) cbuf, status); /* =========================================================================== */ } else if ( (outfptr->Fptr)->compress_type == BZIP2_1) { #if BYTESWAPPED if (intlength == 2) ffswap2((short *) idata, tilelen); else if (intlength == 4) ffswap4(idata, tilelen); #endif bzlen = (unsigned int) clen; /* call bzip2 with blocksize = 900K, verbosity = 0, and default workfactor */ /* bzip2 is not supported in the public release. This is only for test purposes. if (BZ2_bzBuffToBuffCompress( (char *) cbuf, &bzlen, (char *) idata, (unsigned int) (tilelen * intlength), 9, 0, 0) ) */ { ffpmsg("bzip2 compression error"); return(*status = DATA_COMPRESSION_ERR); } /* Write the compressed byte stream. */ ffpclb(outfptr, (outfptr->Fptr)->cn_compressed, row, 1, bzlen, (unsigned char *) cbuf, status); /* =========================================================================== */ } else if ( (outfptr->Fptr)->compress_type == HCOMPRESS_1) { /* if hcompscale is positive, then we have to multiply the value by the RMS background noise to get the absolute scale value. If negative, then it gives the absolute scale value directly. */ hcompscale = (outfptr->Fptr)->hcomp_scale; if (hcompscale > 0.) { fits_img_stats_int(idata, tilenx, tileny, nullcheck, nullval, 0,0,0,0,0,0,&noise2,&noise3,&noise5,status); /* use the minimum of the 3 noise estimates */ if (noise2 != 0. && noise2 < noise3) noise3 = noise2; if (noise5 != 0. && noise5 < noise3) noise3 = noise5; hcompscale = (float) (hcompscale * noise3); } else if (hcompscale < 0.) { hcompscale = hcompscale * -1.0F; } ihcompscale = (int) (hcompscale + 0.5); hcomp_len = clen; /* allocated size of the buffer */ if (zbitpix == BYTE_IMG || zbitpix == SHORT_IMG) { fits_hcompress(idata, tilenx, tileny, ihcompscale, (char *) cbuf, &hcomp_len, status); } else { /* have to convert idata to an I*8 array, in place */ /* idata must have been allocated large enough to do this */ fits_int_to_longlong_inplace(idata, tilelen, status); lldata = (LONGLONG *) idata; fits_hcompress64(lldata, tilenx, tileny, ihcompscale, (char *) cbuf, &hcomp_len, status); } /* Write the compressed byte stream. */ ffpclb(outfptr, (outfptr->Fptr)->cn_compressed, row, 1, hcomp_len, (unsigned char *) cbuf, status); } /* =========================================================================== */ if ((outfptr->Fptr)->cn_zscale > 0) { /* write the linear scaling parameters for this tile */ ffpcld (outfptr, (outfptr->Fptr)->cn_zscale, row, 1, 1, bscale, status); ffpcld (outfptr, (outfptr->Fptr)->cn_zzero, row, 1, 1, bzero, status); } free(cbuf); /* finished with this buffer */ /* =========================================================================== */ } else { /* if flag == 0., floating point data couldn't be quantized */ /* losslessly compress the data with gzip. */ /* if gzip2 compressed data column doesn't exist, create it */ if ((outfptr->Fptr)->cn_gzip_data < 1) { if ( (outfptr->Fptr)->request_huge_hdu != 0) { fits_insert_col(outfptr, 999, "GZIP_COMPRESSED_DATA", "1QB", status); } else { fits_insert_col(outfptr, 999, "GZIP_COMPRESSED_DATA", "1PB", status); } if (*status <= 0) /* save the number of this column */ ffgcno(outfptr, CASEINSEN, "GZIP_COMPRESSED_DATA", &(outfptr->Fptr)->cn_gzip_data, status); } if (datatype == TFLOAT) { /* allocate buffer for the compressed tile bytes */ /* make it 10% larger than the original uncompressed data */ clen = (size_t) (tilelen * sizeof(float) * 1.1); cbuf = (short *) calloc (clen, sizeof (unsigned char)); if (cbuf == NULL) { ffpmsg("Memory allocation error. (imcomp_compress_tile)"); return (*status = MEMORY_ALLOCATION); } /* convert null values to NaNs in place, if necessary */ if (nullcheck == 1) { imcomp_float2nan((float *) tiledata, tilelen, (int *) tiledata, *(float *) (nullflagval), status); } #if BYTESWAPPED ffswap4((int*) tiledata, tilelen); #endif compress2mem_from_mem((char *) tiledata, tilelen * sizeof(float), (char **) &cbuf, &clen, realloc, &gzip_nelem, status); } else { /* datatype == TDOUBLE */ /* allocate buffer for the compressed tile bytes */ /* make it 10% larger than the original uncompressed data */ clen = (size_t) (tilelen * sizeof(double) * 1.1); cbuf = (short *) calloc (clen, sizeof (unsigned char)); if (cbuf == NULL) { ffpmsg("Memory allocation error. (imcomp_compress_tile)"); return (*status = MEMORY_ALLOCATION); } /* convert null values to NaNs in place, if necessary */ if (nullcheck == 1) { imcomp_double2nan((double *) tiledata, tilelen, (LONGLONG *) tiledata, *(double *) (nullflagval), status); } #if BYTESWAPPED ffswap8((double*) tiledata, tilelen); #endif compress2mem_from_mem((char *) tiledata, tilelen * sizeof(double), (char **) &cbuf, &clen, realloc, &gzip_nelem, status); } /* Write the compressed byte stream. */ ffpclb(outfptr, (outfptr->Fptr)->cn_gzip_data, row, 1, gzip_nelem, (unsigned char *) cbuf, status); free(cbuf); /* finished with this buffer */ } return(*status); } /*--------------------------------------------------------------------------*/ int imcomp_write_nocompress_tile(fitsfile *outfptr, long row, int datatype, void *tiledata, long tilelen, int nullcheck, void *nullflagval, int *status) { char coltype[4]; /* Write the uncompressed image tile pixels to the tile-compressed image file. */ /* This is a special case when using NOCOMPRESS for diagnostic purposes in fpack. */ /* Currently, this only supports a limited number of data types and */ /* does not fully support null-valued pixels in the image. */ if ((outfptr->Fptr)->cn_uncompressed < 1) { /* uncompressed data column doesn't exist, so append new column to table */ if (datatype == TSHORT) { strcpy(coltype, "1PI"); } else if (datatype == TINT) { strcpy(coltype, "1PJ"); } else if (datatype == TFLOAT) { strcpy(coltype, "1QE"); } else { ffpmsg("NOCOMPRESSION option only supported for int*2, int*4, and float*4 images"); return(*status = DATA_COMPRESSION_ERR); } fits_insert_col(outfptr, 999, "UNCOMPRESSED_DATA", coltype, status); /* create column */ } fits_get_colnum(outfptr, CASEINSEN, "UNCOMPRESSED_DATA", &(outfptr->Fptr)->cn_uncompressed, status); /* save col. num. */ fits_write_col(outfptr, datatype, (outfptr->Fptr)->cn_uncompressed, row, 1, tilelen, tiledata, status); /* write the tile data */ return (*status); } /*--------------------------------------------------------------------------*/ int imcomp_convert_tile_tshort( fitsfile *outfptr, void *tiledata, long tilelen, int nullcheck, void *nullflagval, int nullval, int zbitpix, double scale, double zero, double actual_bzero, int *intlength, int *status) { /* Prepare the input tile array of pixels for compression. */ /* Convert input integer*2 tile array in place to 4 or 8-byte ints for compression, */ /* If needed, convert 4 or 8-byte ints and do null value substitution. */ /* Note that the calling routine must have allocated the input array big enough */ /* to be able to do this. */ short *sbuff; int flagval, *idata; long ii; /* We only support writing this integer*2 tile data to a FITS image with BITPIX = 16 and with BZERO = 0 and BSCALE = 1. */ if (zbitpix != SHORT_IMG || scale != 1.0 || zero != 0.0) { ffpmsg("Datatype conversion/scaling is not supported when writing to compressed images"); return(*status = DATA_COMPRESSION_ERR); } sbuff = (short *) tiledata; idata = (int *) tiledata; if ( (outfptr->Fptr)->compress_type == RICE_1 || (outfptr->Fptr)->compress_type == GZIP_1 || (outfptr->Fptr)->compress_type == GZIP_2 || (outfptr->Fptr)->compress_type == BZIP2_1 ) { /* don't have to convert to int if using gzip, bzip2 or Rice compression */ *intlength = 2; if (nullcheck == 1) { /* reset pixels equal to flagval to the FITS null value, prior to compression */ flagval = *(short *) (nullflagval); if (flagval != nullval) { for (ii = tilelen - 1; ii >= 0; ii--) { if (sbuff[ii] == (short) flagval) sbuff[ii] = (short) nullval; } } } } else if ((outfptr->Fptr)->compress_type == HCOMPRESS_1) { /* have to convert to int if using HCOMPRESS */ *intlength = 4; if (nullcheck == 1) { /* reset pixels equal to flagval to the FITS null value, prior to compression */ flagval = *(short *) (nullflagval); for (ii = tilelen - 1; ii >= 0; ii--) { if (sbuff[ii] == (short) flagval) idata[ii] = nullval; else idata[ii] = (int) sbuff[ii]; } } else { /* just do the data type conversion to int */ /* have to convert sbuff to an I*4 array, in place */ /* sbuff must have been allocated large enough to do this */ fits_short_to_int_inplace(sbuff, tilelen, 0, status); } } else { /* have to convert to int if using PLIO */ *intlength = 4; if (zero == 0. && actual_bzero == 32768.) { /* Here we are compressing unsigned 16-bit integers that have */ /* been offset by -32768 using the standard FITS convention. */ /* Since PLIO cannot deal with negative values, we must apply */ /* the shift of 32786 to the values to make them all positive. */ /* The inverse negative shift will be applied in */ /* imcomp_decompress_tile when reading the compressed tile. */ if (nullcheck == 1) { /* reset pixels equal to flagval to the FITS null value, prior to compression */ flagval = *(short *) (nullflagval); for (ii = tilelen - 1; ii >= 0; ii--) { if (sbuff[ii] == (short) flagval) idata[ii] = nullval; else idata[ii] = (int) sbuff[ii] + 32768; } } else { /* have to convert sbuff to an I*4 array, in place */ /* sbuff must have been allocated large enough to do this */ fits_short_to_int_inplace(sbuff, tilelen, 32768, status); } } else { /* This is not an unsigned 16-bit integer array, so process normally */ if (nullcheck == 1) { /* reset pixels equal to flagval to the FITS null value, prior to compression */ flagval = *(short *) (nullflagval); for (ii = tilelen - 1; ii >= 0; ii--) { if (sbuff[ii] == (short) flagval) idata[ii] = nullval; else idata[ii] = (int) sbuff[ii]; } } else { /* just do the data type conversion to int */ /* have to convert sbuff to an I*4 array, in place */ /* sbuff must have been allocated large enough to do this */ fits_short_to_int_inplace(sbuff, tilelen, 0, status); } } } return(*status); } /*--------------------------------------------------------------------------*/ int imcomp_convert_tile_tushort( fitsfile *outfptr, void *tiledata, long tilelen, int nullcheck, void *nullflagval, int nullval, int zbitpix, double scale, double zero, int *intlength, int *status) { /* Prepare the input tile array of pixels for compression. */ /* Convert input unsigned integer*2 tile array in place to 4 or 8-byte ints for compression, */ /* If needed, convert 4 or 8-byte ints and do null value substitution. */ /* Note that the calling routine must have allocated the input array big enough */ /* to be able to do this. */ unsigned short *usbuff; short *sbuff; int flagval, *idata; long ii; /* datatype of input array is unsigned short. We only support writing this datatype to a FITS image with BITPIX = 16 and with BZERO = 0 and BSCALE = 32768. */ if (zbitpix != SHORT_IMG || scale != 1.0 || zero != 32768.) { ffpmsg("Implicit datatype conversion is not supported when writing to compressed images"); return(*status = DATA_COMPRESSION_ERR); } usbuff = (unsigned short *) tiledata; sbuff = (short *) tiledata; idata = (int *) tiledata; if ((outfptr->Fptr)->compress_type == RICE_1 || (outfptr->Fptr)->compress_type == GZIP_1 || (outfptr->Fptr)->compress_type == GZIP_2 || (outfptr->Fptr)->compress_type == BZIP2_1) { /* don't have to convert to int if using gzip, bzip2, or Rice compression */ *intlength = 2; /* offset the unsigned value by -32768 to a signed short value. */ /* It is more efficient to do this by just flipping the most significant of the 16 bits */ if (nullcheck == 1) { /* reset pixels equal to flagval to the FITS null value, prior to compression */ flagval = *(unsigned short *) (nullflagval); for (ii = tilelen - 1; ii >= 0; ii--) { if (usbuff[ii] == (unsigned short) flagval) sbuff[ii] = (short) nullval; else usbuff[ii] = (usbuff[ii]) ^ 0x8000; } } else { /* just offset the pixel values by 32768 (by flipping the MSB */ for (ii = tilelen - 1; ii >= 0; ii--) usbuff[ii] = (usbuff[ii]) ^ 0x8000; } } else { /* have to convert to int if using HCOMPRESS or PLIO */ *intlength = 4; if (nullcheck == 1) { /* offset the pixel values by 32768, and */ /* reset pixels equal to flagval to nullval */ flagval = *(unsigned short *) (nullflagval); for (ii = tilelen - 1; ii >= 0; ii--) { if (usbuff[ii] == (unsigned short) flagval) idata[ii] = nullval; else idata[ii] = ((int) usbuff[ii]) - 32768; } } else { /* just do the data type conversion to int */ /* for HCOMPRESS we need to simply subtract 32768 */ /* for PLIO, have to convert usbuff to an I*4 array, in place */ /* usbuff must have been allocated large enough to do this */ if ((outfptr->Fptr)->compress_type == HCOMPRESS_1) { fits_ushort_to_int_inplace(usbuff, tilelen, -32768, status); } else { fits_ushort_to_int_inplace(usbuff, tilelen, 0, status); } } } return(*status); } /*--------------------------------------------------------------------------*/ int imcomp_convert_tile_tint( fitsfile *outfptr, void *tiledata, long tilelen, int nullcheck, void *nullflagval, int nullval, int zbitpix, double scale, double zero, int *intlength, int *status) { /* Prepare the input tile array of pixels for compression. */ /* Convert input integer tile array in place to 4 or 8-byte ints for compression, */ /* If needed, do null value substitution. */ int flagval, *idata; long ii; /* datatype of input array is int. We only support writing this datatype to a FITS image with BITPIX = 32 and with BZERO = 0 and BSCALE = 1. */ if (zbitpix != LONG_IMG || scale != 1.0 || zero != 0.) { ffpmsg("Implicit datatype conversion is not supported when writing to compressed images"); return(*status = DATA_COMPRESSION_ERR); } idata = (int *) tiledata; *intlength = 4; if (nullcheck == 1) { /* no datatype conversion is required for any of the compression algorithms, except possibly for HCOMPRESS (to I*8), which is handled later. Just reset pixels equal to flagval to the FITS null value */ flagval = *(int *) (nullflagval); if (flagval != nullval) { for (ii = tilelen - 1; ii >= 0; ii--) { if (idata[ii] == flagval) idata[ii] = nullval; } } } return(*status); } /*--------------------------------------------------------------------------*/ int imcomp_convert_tile_tuint( fitsfile *outfptr, void *tiledata, long tilelen, int nullcheck, void *nullflagval, int nullval, int zbitpix, double scale, double zero, int *intlength, int *status) { /* Prepare the input tile array of pixels for compression. */ /* Convert input unsigned integer tile array in place to 4 or 8-byte ints for compression, */ /* If needed, do null value substitution. */ int *idata; unsigned int *uintbuff, uintflagval; long ii; /* datatype of input array is unsigned int. We only support writing this datatype to a FITS image with BITPIX = 32 and with BZERO = 0 and BSCALE = 2147483648. */ if (zbitpix != LONG_IMG || scale != 1.0 || zero != 2147483648.) { ffpmsg("Implicit datatype conversion is not supported when writing to compressed images"); return(*status = DATA_COMPRESSION_ERR); } *intlength = 4; idata = (int *) tiledata; uintbuff = (unsigned int *) tiledata; /* offset the unsigned value by -2147483648 to a signed int value. */ /* It is more efficient to do this by just flipping the most significant of the 32 bits */ if (nullcheck == 1) { /* reset pixels equal to flagval to nullval and */ /* offset the other pixel values (by flipping the MSB) */ uintflagval = *(unsigned int *) (nullflagval); for (ii = tilelen - 1; ii >= 0; ii--) { if (uintbuff[ii] == uintflagval) idata[ii] = nullval; else uintbuff[ii] = (uintbuff[ii]) ^ 0x80000000; } } else { /* just offset the pixel values (by flipping the MSB) */ for (ii = tilelen - 1; ii >= 0; ii--) uintbuff[ii] = (uintbuff[ii]) ^ 0x80000000; } return(*status); } /*--------------------------------------------------------------------------*/ int imcomp_convert_tile_tbyte( fitsfile *outfptr, void *tiledata, long tilelen, int nullcheck, void *nullflagval, int nullval, int zbitpix, double scale, double zero, int *intlength, int *status) { /* Prepare the input tile array of pixels for compression. */ /* Convert input unsigned integer*1 tile array in place to 4 or 8-byte ints for compression, */ /* If needed, convert 4 or 8-byte ints and do null value substitution. */ /* Note that the calling routine must have allocated the input array big enough */ /* to be able to do this. */ int flagval, *idata; long ii; unsigned char *usbbuff; /* datatype of input array is unsigned byte. We only support writing this datatype to a FITS image with BITPIX = 8 and with BZERO = 0 and BSCALE = 1. */ if (zbitpix != BYTE_IMG || scale != 1.0 || zero != 0.) { ffpmsg("Implicit datatype conversion is not supported when writing to compressed images"); return(*status = DATA_COMPRESSION_ERR); } idata = (int *) tiledata; usbbuff = (unsigned char *) tiledata; if ( (outfptr->Fptr)->compress_type == RICE_1 || (outfptr->Fptr)->compress_type == GZIP_1 || (outfptr->Fptr)->compress_type == GZIP_2 || (outfptr->Fptr)->compress_type == BZIP2_1 ) { /* don't have to convert to int if using gzip, bzip2, or Rice compression */ *intlength = 1; if (nullcheck == 1) { /* reset pixels equal to flagval to the FITS null value, prior to compression */ flagval = *(unsigned char *) (nullflagval); if (flagval != nullval) { for (ii = tilelen - 1; ii >= 0; ii--) { if (usbbuff[ii] == (unsigned char) flagval) usbbuff[ii] = (unsigned char) nullval; } } } } else { /* have to convert to int if using HCOMPRESS or PLIO */ *intlength = 4; if (nullcheck == 1) { /* reset pixels equal to flagval to the FITS null value, prior to compression */ flagval = *(unsigned char *) (nullflagval); for (ii = tilelen - 1; ii >= 0; ii--) { if (usbbuff[ii] == (unsigned char) flagval) idata[ii] = nullval; else idata[ii] = (int) usbbuff[ii]; } } else { /* just do the data type conversion to int */ /* have to convert usbbuff to an I*4 array, in place */ /* usbbuff must have been allocated large enough to do this */ fits_ubyte_to_int_inplace(usbbuff, tilelen, status); } } return(*status); } /*--------------------------------------------------------------------------*/ int imcomp_convert_tile_tsbyte( fitsfile *outfptr, void *tiledata, long tilelen, int nullcheck, void *nullflagval, int nullval, int zbitpix, double scale, double zero, int *intlength, int *status) { /* Prepare the input tile array of pixels for compression. */ /* Convert input integer*1 tile array in place to 4 or 8-byte ints for compression, */ /* If needed, convert 4 or 8-byte ints and do null value substitution. */ /* Note that the calling routine must have allocated the input array big enough */ /* to be able to do this. */ int flagval, *idata; long ii; signed char *sbbuff; /* datatype of input array is signed byte. We only support writing this datatype to a FITS image with BITPIX = 8 and with BZERO = 0 and BSCALE = -128. */ if (zbitpix != BYTE_IMG|| scale != 1.0 || zero != -128.) { ffpmsg("Implicit datatype conversion is not supported when writing to compressed images"); return(*status = DATA_COMPRESSION_ERR); } idata = (int *) tiledata; sbbuff = (signed char *) tiledata; if ( (outfptr->Fptr)->compress_type == RICE_1 || (outfptr->Fptr)->compress_type == GZIP_1 || (outfptr->Fptr)->compress_type == GZIP_2 || (outfptr->Fptr)->compress_type == BZIP2_1 ) { /* don't have to convert to int if using gzip, bzip2 or Rice compression */ *intlength = 1; if (nullcheck == 1) { /* reset pixels equal to flagval to the FITS null value, prior to compression */ /* offset the other pixel values (by flipping the MSB) */ flagval = *(signed char *) (nullflagval); for (ii = tilelen - 1; ii >= 0; ii--) { if (sbbuff[ii] == (signed char) flagval) sbbuff[ii] = (signed char) nullval; else sbbuff[ii] = (sbbuff[ii]) ^ 0x80; } } else { /* just offset the pixel values (by flipping the MSB) */ for (ii = tilelen - 1; ii >= 0; ii--) sbbuff[ii] = (sbbuff[ii]) ^ 0x80; } } else { /* have to convert to int if using HCOMPRESS or PLIO */ *intlength = 4; if (nullcheck == 1) { /* reset pixels equal to flagval to the FITS null value, prior to compression */ flagval = *(signed char *) (nullflagval); for (ii = tilelen - 1; ii >= 0; ii--) { if (sbbuff[ii] == (signed char) flagval) idata[ii] = nullval; else idata[ii] = ((int) sbbuff[ii]) + 128; } } else { /* just do the data type conversion to int */ /* have to convert sbbuff to an I*4 array, in place */ /* sbbuff must have been allocated large enough to do this */ fits_sbyte_to_int_inplace(sbbuff, tilelen, status); } } return(*status); } /*--------------------------------------------------------------------------*/ int imcomp_convert_tile_tfloat( fitsfile *outfptr, long row, void *tiledata, long tilelen, long tilenx, long tileny, int nullcheck, void *nullflagval, int nullval, int zbitpix, double scale, double zero, int *intlength, int *flag, double *bscale, double *bzero, int *status) { /* Prepare the input tile array of pixels for compression. */ /* Convert input float tile array in place to 4 or 8-byte ints for compression, */ /* If needed, convert 4 or 8-byte ints and do null value substitution. */ /* Note that the calling routine must have allocated the input array big enough */ /* to be able to do this. */ int *idata; long irow, ii; float floatnull; unsigned char *usbbuff; unsigned long dithersum; int iminval = 0, imaxval = 0; /* min and max quantized integers */ /* datatype of input array is double. We only support writing this datatype to a FITS image with BITPIX = -64 or -32, except we also support the special case where BITPIX = 32 and BZERO = 0 and BSCALE = 1. */ if ((zbitpix != LONG_IMG && zbitpix != DOUBLE_IMG && zbitpix != FLOAT_IMG) || scale != 1.0 || zero != 0.) { ffpmsg("Implicit datatype conversion is not supported when writing to compressed images"); return(*status = DATA_COMPRESSION_ERR); } *intlength = 4; idata = (int *) tiledata; /* if the tile-compressed table contains zscale and zzero columns */ /* then scale and quantize the input floating point data. */ if ((outfptr->Fptr)->cn_zscale > 0) { /* quantize the float values into integers */ if (nullcheck == 1) floatnull = *(float *) (nullflagval); else floatnull = FLOATNULLVALUE; /* NaNs are represented by this, by default */ if ((outfptr->Fptr)->quantize_method == SUBTRACTIVE_DITHER_1 || (outfptr->Fptr)->quantize_method == SUBTRACTIVE_DITHER_2) { /* see if the dithering offset value needs to be initialized */ if ((outfptr->Fptr)->request_dither_seed == 0 && (outfptr->Fptr)->dither_seed == 0) { /* This means randomly choose the dithering offset based on the system time. */ /* The offset will have a value between 1 and 10000, inclusive. */ /* The time function returns an integer value that is incremented each second. */ /* The clock function returns the elapsed CPU time, in integer CLOCKS_PER_SEC units. */ /* The CPU time returned by clock is typically (on linux PC) only good to 0.01 sec */ /* Summing the 2 quantities may help avoid cases where 2 executions of the program */ /* (perhaps in a multithreaded environoment) end up with exactly the same dither seed */ /* value. The sum is incremented by the current HDU number in the file to provide */ /* further randomization. This randomization is desireable if multiple compressed */ /* images will be summed (or differenced). In such cases, the benefits of dithering */ /* may be lost if all the images use exactly the same sequence of random numbers when */ /* calculating the dithering offsets. */ (outfptr->Fptr)->dither_seed = (( (int)time(NULL) + ( (int) clock() / (int) (CLOCKS_PER_SEC / 100)) + (outfptr->Fptr)->curhdu) % 10000) + 1; /* update the header keyword with this new value */ fits_update_key(outfptr, TINT, "ZDITHER0", &((outfptr->Fptr)->dither_seed), NULL, status); } else if ((outfptr->Fptr)->request_dither_seed < 0 && (outfptr->Fptr)->dither_seed < 0) { /* this means randomly choose the dithering offset based on some hash function */ /* of the first input tile of data to be quantized and compressed. This ensures that */ /* the same offset value is used for a given image every time it is compressed. */ usbbuff = (unsigned char *) tiledata; dithersum = 0; for (ii = 0; ii < 4 * tilelen; ii++) { dithersum += usbbuff[ii]; /* doesn't matter if there is an integer overflow */ } (outfptr->Fptr)->dither_seed = ((int) (dithersum % 10000)) + 1; /* update the header keyword with this new value */ fits_update_key(outfptr, TINT, "ZDITHER0", &((outfptr->Fptr)->dither_seed), NULL, status); } /* subtract 1 to convert from 1-based to 0-based element number */ irow = row + (outfptr->Fptr)->dither_seed - 1; /* dither the quantized values */ } else if ((outfptr->Fptr)->quantize_method == -1) { irow = 0; /* do not dither the quantized values */ } else { ffpmsg("Unknown dithering method."); ffpmsg("May need to install a newer version of CFITSIO."); return(*status = DATA_COMPRESSION_ERR); } *flag = fits_quantize_float (irow, (float *) tiledata, tilenx, tileny, nullcheck, floatnull, (outfptr->Fptr)->quantize_level, (outfptr->Fptr)->quantize_method, idata, bscale, bzero, &iminval, &imaxval); if (*flag > 1) return(*status = *flag); } else if ((outfptr->Fptr)->quantize_level != NO_QUANTIZE) { /* if floating point pixels are not being losslessly compressed, then */ /* input float data is implicitly converted (truncated) to integers */ if ((scale != 1. || zero != 0.)) /* must scale the values */ imcomp_nullscalefloats((float *) tiledata, tilelen, idata, scale, zero, nullcheck, *(float *) (nullflagval), nullval, status); else imcomp_nullfloats((float *) tiledata, tilelen, idata, nullcheck, *(float *) (nullflagval), nullval, status); } else if ((outfptr->Fptr)->quantize_level == NO_QUANTIZE) { /* just convert null values to NaNs in place, if necessary, then do lossless gzip compression */ if (nullcheck == 1) { imcomp_float2nan((float *) tiledata, tilelen, (int *) tiledata, *(float *) (nullflagval), status); } } return(*status); } /*--------------------------------------------------------------------------*/ int imcomp_convert_tile_tdouble( fitsfile *outfptr, long row, void *tiledata, long tilelen, long tilenx, long tileny, int nullcheck, void *nullflagval, int nullval, int zbitpix, double scale, double zero, int *intlength, int *flag, double *bscale, double *bzero, int *status) { /* Prepare the input tile array of pixels for compression. */ /* Convert input double tile array in place to 4-byte ints for compression, */ /* If needed, convert 4 or 8-byte ints and do null value substitution. */ /* Note that the calling routine must have allocated the input array big enough */ /* to be able to do this. */ int *idata; long irow, ii; double doublenull; unsigned char *usbbuff; unsigned long dithersum; int iminval = 0, imaxval = 0; /* min and max quantized integers */ /* datatype of input array is double. We only support writing this datatype to a FITS image with BITPIX = -64 or -32, except we also support the special case where BITPIX = 32 and BZERO = 0 and BSCALE = 1. */ if ((zbitpix != LONG_IMG && zbitpix != DOUBLE_IMG && zbitpix != FLOAT_IMG) || scale != 1.0 || zero != 0.) { ffpmsg("Implicit datatype conversion is not supported when writing to compressed images"); return(*status = DATA_COMPRESSION_ERR); } *intlength = 4; idata = (int *) tiledata; /* if the tile-compressed table contains zscale and zzero columns */ /* then scale and quantize the input floating point data. */ /* Otherwise, just truncate the floats to integers. */ if ((outfptr->Fptr)->cn_zscale > 0) { if (nullcheck == 1) doublenull = *(double *) (nullflagval); else doublenull = DOUBLENULLVALUE; /* quantize the double values into integers */ if ((outfptr->Fptr)->quantize_method == SUBTRACTIVE_DITHER_1 || (outfptr->Fptr)->quantize_method == SUBTRACTIVE_DITHER_2) { /* see if the dithering offset value needs to be initialized (see above) */ if ((outfptr->Fptr)->request_dither_seed == 0 && (outfptr->Fptr)->dither_seed == 0) { (outfptr->Fptr)->dither_seed = (( (int)time(NULL) + ( (int) clock() / (int) (CLOCKS_PER_SEC / 100)) + (outfptr->Fptr)->curhdu) % 10000) + 1; /* update the header keyword with this new value */ fits_update_key(outfptr, TINT, "ZDITHER0", &((outfptr->Fptr)->dither_seed), NULL, status); } else if ((outfptr->Fptr)->request_dither_seed < 0 && (outfptr->Fptr)->dither_seed < 0) { usbbuff = (unsigned char *) tiledata; dithersum = 0; for (ii = 0; ii < 8 * tilelen; ii++) { dithersum += usbbuff[ii]; } (outfptr->Fptr)->dither_seed = ((int) (dithersum % 10000)) + 1; /* update the header keyword with this new value */ fits_update_key(outfptr, TINT, "ZDITHER0", &((outfptr->Fptr)->dither_seed), NULL, status); } irow = row + (outfptr->Fptr)->dither_seed - 1; /* dither the quantized values */ } else if ((outfptr->Fptr)->quantize_method == -1) { irow = 0; /* do not dither the quantized values */ } else { ffpmsg("Unknown subtractive dithering method."); ffpmsg("May need to install a newer version of CFITSIO."); return(*status = DATA_COMPRESSION_ERR); } *flag = fits_quantize_double (irow, (double *) tiledata, tilenx, tileny, nullcheck, doublenull, (outfptr->Fptr)->quantize_level, (outfptr->Fptr)->quantize_method, idata, bscale, bzero, &iminval, &imaxval); if (*flag > 1) return(*status = *flag); } else if ((outfptr->Fptr)->quantize_level != NO_QUANTIZE) { /* if floating point pixels are not being losslessly compressed, then */ /* input float data is implicitly converted (truncated) to integers */ if ((scale != 1. || zero != 0.)) /* must scale the values */ imcomp_nullscaledoubles((double *) tiledata, tilelen, idata, scale, zero, nullcheck, *(double *) (nullflagval), nullval, status); else imcomp_nulldoubles((double *) tiledata, tilelen, idata, nullcheck, *(double *) (nullflagval), nullval, status); } else if ((outfptr->Fptr)->quantize_level == NO_QUANTIZE) { /* just convert null values to NaNs in place, if necessary, then do lossless gzip compression */ if (nullcheck == 1) { imcomp_double2nan((double *) tiledata, tilelen, (LONGLONG *) tiledata, *(double *) (nullflagval), status); } } return(*status); } /*---------------------------------------------------------------------------*/ int imcomp_nullscale( int *idata, long tilelen, int nullflagval, int nullval, double scale, double zero, int *status) /* do null value substitution AND scaling of the integer array. If array value = nullflagval, then set the value to nullval. Otherwise, inverse scale the integer value. */ { long ii; double dvalue; for (ii=0; ii < tilelen; ii++) { if (idata[ii] == nullflagval) idata[ii] = nullval; else { dvalue = (idata[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; idata[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; idata[ii] = INT32_MAX; } else { if (dvalue >= 0) idata[ii] = (int) (dvalue + .5); else idata[ii] = (int) (dvalue - .5); } } } return(*status); } /*---------------------------------------------------------------------------*/ int imcomp_nullvalues( int *idata, long tilelen, int nullflagval, int nullval, int *status) /* do null value substitution. If array value = nullflagval, then set the value to nullval. */ { long ii; for (ii=0; ii < tilelen; ii++) { if (idata[ii] == nullflagval) idata[ii] = nullval; } return(*status); } /*---------------------------------------------------------------------------*/ int imcomp_scalevalues( int *idata, long tilelen, double scale, double zero, int *status) /* do inverse scaling the integer values. */ { long ii; double dvalue; for (ii=0; ii < tilelen; ii++) { dvalue = (idata[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; idata[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; idata[ii] = INT32_MAX; } else { if (dvalue >= 0) idata[ii] = (int) (dvalue + .5); else idata[ii] = (int) (dvalue - .5); } } return(*status); } /*---------------------------------------------------------------------------*/ int imcomp_nullscalei2( short *idata, long tilelen, short nullflagval, short nullval, double scale, double zero, int *status) /* do null value substitution AND scaling of the integer array. If array value = nullflagval, then set the value to nullval. Otherwise, inverse scale the integer value. */ { long ii; double dvalue; for (ii=0; ii < tilelen; ii++) { if (idata[ii] == nullflagval) idata[ii] = nullval; else { dvalue = (idata[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; idata[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; idata[ii] = SHRT_MAX; } else { if (dvalue >= 0) idata[ii] = (int) (dvalue + .5); else idata[ii] = (int) (dvalue - .5); } } } return(*status); } /*---------------------------------------------------------------------------*/ int imcomp_nullvaluesi2( short *idata, long tilelen, short nullflagval, short nullval, int *status) /* do null value substitution. If array value = nullflagval, then set the value to nullval. */ { long ii; for (ii=0; ii < tilelen; ii++) { if (idata[ii] == nullflagval) idata[ii] = nullval; } return(*status); } /*---------------------------------------------------------------------------*/ int imcomp_scalevaluesi2( short *idata, long tilelen, double scale, double zero, int *status) /* do inverse scaling the integer values. */ { long ii; double dvalue; for (ii=0; ii < tilelen; ii++) { dvalue = (idata[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; idata[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; idata[ii] = SHRT_MAX; } else { if (dvalue >= 0) idata[ii] = (int) (dvalue + .5); else idata[ii] = (int) (dvalue - .5); } } return(*status); } /*---------------------------------------------------------------------------*/ int imcomp_nullfloats( float *fdata, long tilelen, int *idata, int nullcheck, float nullflagval, int nullval, int *status) /* do null value substitution of the float array. If array value = nullflagval, then set the output value to FLOATNULLVALUE. */ { long ii; double dvalue; if (nullcheck == 1) /* must check for null values */ { for (ii=0; ii < tilelen; ii++) { if (fdata[ii] == nullflagval) idata[ii] = nullval; else { dvalue = fdata[ii]; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; idata[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; idata[ii] = INT32_MAX; } else { if (dvalue >= 0) idata[ii] = (int) (dvalue + .5); else idata[ii] = (int) (dvalue - .5); } } } } else /* don't have to worry about null values */ { for (ii=0; ii < tilelen; ii++) { dvalue = fdata[ii]; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; idata[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; idata[ii] = INT32_MAX; } else { if (dvalue >= 0) idata[ii] = (int) (dvalue + .5); else idata[ii] = (int) (dvalue - .5); } } } return(*status); } /*---------------------------------------------------------------------------*/ int imcomp_nullscalefloats( float *fdata, long tilelen, int *idata, double scale, double zero, int nullcheck, float nullflagval, int nullval, int *status) /* do null value substitution of the float array. If array value = nullflagval, then set the output value to FLOATNULLVALUE. Otherwise, inverse scale the integer value. */ { long ii; double dvalue; if (nullcheck == 1) /* must check for null values */ { for (ii=0; ii < tilelen; ii++) { if (fdata[ii] == nullflagval) idata[ii] = nullval; else { dvalue = (fdata[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; idata[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; idata[ii] = INT32_MAX; } else { if (dvalue >= 0.) idata[ii] = (int) (dvalue + .5); else idata[ii] = (int) (dvalue - .5); } } } } else /* don't have to worry about null values */ { for (ii=0; ii < tilelen; ii++) { dvalue = (fdata[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; idata[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; idata[ii] = INT32_MAX; } else { if (dvalue >= 0.) idata[ii] = (int) (dvalue + .5); else idata[ii] = (int) (dvalue - .5); } } } return(*status); } /*---------------------------------------------------------------------------*/ int imcomp_nulldoubles( double *fdata, long tilelen, int *idata, int nullcheck, double nullflagval, int nullval, int *status) /* do null value substitution of the float array. If array value = nullflagval, then set the output value to FLOATNULLVALUE. Otherwise, inverse scale the integer value. */ { long ii; double dvalue; if (nullcheck == 1) /* must check for null values */ { for (ii=0; ii < tilelen; ii++) { if (fdata[ii] == nullflagval) idata[ii] = nullval; else { dvalue = fdata[ii]; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; idata[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; idata[ii] = INT32_MAX; } else { if (dvalue >= 0.) idata[ii] = (int) (dvalue + .5); else idata[ii] = (int) (dvalue - .5); } } } } else /* don't have to worry about null values */ { for (ii=0; ii < tilelen; ii++) { dvalue = fdata[ii]; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; idata[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; idata[ii] = INT32_MAX; } else { if (dvalue >= 0.) idata[ii] = (int) (dvalue + .5); else idata[ii] = (int) (dvalue - .5); } } } return(*status); } /*---------------------------------------------------------------------------*/ int imcomp_nullscaledoubles( double *fdata, long tilelen, int *idata, double scale, double zero, int nullcheck, double nullflagval, int nullval, int *status) /* do null value substitution of the float array. If array value = nullflagval, then set the output value to FLOATNULLVALUE. Otherwise, inverse scale the integer value. */ { long ii; double dvalue; if (nullcheck == 1) /* must check for null values */ { for (ii=0; ii < tilelen; ii++) { if (fdata[ii] == nullflagval) idata[ii] = nullval; else { dvalue = (fdata[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; idata[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; idata[ii] = INT32_MAX; } else { if (dvalue >= 0.) idata[ii] = (int) (dvalue + .5); else idata[ii] = (int) (dvalue - .5); } } } } else /* don't have to worry about null values */ { for (ii=0; ii < tilelen; ii++) { dvalue = (fdata[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; idata[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; idata[ii] = INT32_MAX; } else { if (dvalue >= 0.) idata[ii] = (int) (dvalue + .5); else idata[ii] = (int) (dvalue - .5); } } } return(*status); } /*---------------------------------------------------------------------------*/ int fits_write_compressed_img(fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the array to be written */ long *infpixel, /* I - 'bottom left corner' of the subsection */ long *inlpixel, /* I - 'top right corner' of the subsection */ int nullcheck, /* I - 0 for no null checking */ /* 1: pixels that are = nullval will be */ /* written with the FITS null pixel value */ /* (floating point arrays only) */ void *array, /* I - array of values to be written */ void *nullval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write a section of a compressed image. */ { int tiledim[MAX_COMPRESS_DIM]; long naxis[MAX_COMPRESS_DIM]; long tilesize[MAX_COMPRESS_DIM], thistilesize[MAX_COMPRESS_DIM]; long ftile[MAX_COMPRESS_DIM], ltile[MAX_COMPRESS_DIM]; long tfpixel[MAX_COMPRESS_DIM], tlpixel[MAX_COMPRESS_DIM]; long rowdim[MAX_COMPRESS_DIM], offset[MAX_COMPRESS_DIM],ntemp; long fpixel[MAX_COMPRESS_DIM], lpixel[MAX_COMPRESS_DIM]; long i5, i4, i3, i2, i1, i0, irow, trowsize, ntrows; int ii, ndim, pixlen, tilenul; int tstatus, buffpixsiz; void *buffer; char *bnullarray = 0, card[FLEN_CARD]; if (*status > 0) return(*status); if (!fits_is_compressed_image(fptr, status) ) { ffpmsg("CHDU is not a compressed image (fits_write_compressed_img)"); return(*status = DATA_COMPRESSION_ERR); } /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); /* ===================================================================== */ if (datatype == TSHORT || datatype == TUSHORT) { pixlen = sizeof(short); } else if (datatype == TINT || datatype == TUINT) { pixlen = sizeof(int); } else if (datatype == TBYTE || datatype == TSBYTE) { pixlen = 1; } else if (datatype == TLONG || datatype == TULONG) { pixlen = sizeof(long); } else if (datatype == TFLOAT) { pixlen = sizeof(float); } else if (datatype == TDOUBLE) { pixlen = sizeof(double); } else { ffpmsg("unsupported datatype for compressing image"); return(*status = BAD_DATATYPE); } /* ===================================================================== */ /* allocate scratch space for processing one tile of the image */ buffpixsiz = pixlen; /* this is the minimum pixel size */ if ( (fptr->Fptr)->compress_type == HCOMPRESS_1) { /* need 4 or 8 bytes per pixel */ if ((fptr->Fptr)->zbitpix == BYTE_IMG || (fptr->Fptr)->zbitpix == SHORT_IMG ) buffpixsiz = maxvalue(buffpixsiz, 4); else buffpixsiz = 8; } else if ( (fptr->Fptr)->compress_type == PLIO_1) { /* need 4 bytes per pixel */ buffpixsiz = maxvalue(buffpixsiz, 4); } else if ( (fptr->Fptr)->compress_type == RICE_1 || (fptr->Fptr)->compress_type == GZIP_1 || (fptr->Fptr)->compress_type == GZIP_2 || (fptr->Fptr)->compress_type == BZIP2_1) { /* need 1, 2, or 4 bytes per pixel */ if ((fptr->Fptr)->zbitpix == BYTE_IMG) buffpixsiz = maxvalue(buffpixsiz, 1); else if ((fptr->Fptr)->zbitpix == SHORT_IMG) buffpixsiz = maxvalue(buffpixsiz, 2); else buffpixsiz = maxvalue(buffpixsiz, 4); } else { ffpmsg("unsupported image compression algorithm"); return(*status = BAD_DATATYPE); } /* cast to double to force alignment on 8-byte addresses */ buffer = (double *) calloc ((fptr->Fptr)->maxtilelen, buffpixsiz); if (buffer == NULL) { ffpmsg("Out of memory (fits_write_compress_img)"); return (*status = MEMORY_ALLOCATION); } /* ===================================================================== */ /* initialize all the arrays */ for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { naxis[ii] = 1; tiledim[ii] = 1; tilesize[ii] = 1; ftile[ii] = 1; ltile[ii] = 1; rowdim[ii] = 1; } ndim = (fptr->Fptr)->zndim; ntemp = 1; for (ii = 0; ii < ndim; ii++) { fpixel[ii] = infpixel[ii]; lpixel[ii] = inlpixel[ii]; /* calc number of tiles in each dimension, and tile containing */ /* the first and last pixel we want to read in each dimension */ naxis[ii] = (fptr->Fptr)->znaxis[ii]; if (fpixel[ii] < 1) { free(buffer); return(*status = BAD_PIX_NUM); } tilesize[ii] = (fptr->Fptr)->tilesize[ii]; tiledim[ii] = (naxis[ii] - 1) / tilesize[ii] + 1; ftile[ii] = (fpixel[ii] - 1) / tilesize[ii] + 1; ltile[ii] = minvalue((lpixel[ii] - 1) / tilesize[ii] + 1, tiledim[ii]); rowdim[ii] = ntemp; /* total tiles in each dimension */ ntemp *= tiledim[ii]; } /* support up to 6 dimensions for now */ /* tfpixel and tlpixel are the first and last image pixels */ /* along each dimension of the compression tile */ for (i5 = ftile[5]; i5 <= ltile[5]; i5++) { tfpixel[5] = (i5 - 1) * tilesize[5] + 1; tlpixel[5] = minvalue(tfpixel[5] + tilesize[5] - 1, naxis[5]); thistilesize[5] = tlpixel[5] - tfpixel[5] + 1; offset[5] = (i5 - 1) * rowdim[5]; for (i4 = ftile[4]; i4 <= ltile[4]; i4++) { tfpixel[4] = (i4 - 1) * tilesize[4] + 1; tlpixel[4] = minvalue(tfpixel[4] + tilesize[4] - 1, naxis[4]); thistilesize[4] = thistilesize[5] * (tlpixel[4] - tfpixel[4] + 1); offset[4] = (i4 - 1) * rowdim[4] + offset[5]; for (i3 = ftile[3]; i3 <= ltile[3]; i3++) { tfpixel[3] = (i3 - 1) * tilesize[3] + 1; tlpixel[3] = minvalue(tfpixel[3] + tilesize[3] - 1, naxis[3]); thistilesize[3] = thistilesize[4] * (tlpixel[3] - tfpixel[3] + 1); offset[3] = (i3 - 1) * rowdim[3] + offset[4]; for (i2 = ftile[2]; i2 <= ltile[2]; i2++) { tfpixel[2] = (i2 - 1) * tilesize[2] + 1; tlpixel[2] = minvalue(tfpixel[2] + tilesize[2] - 1, naxis[2]); thistilesize[2] = thistilesize[3] * (tlpixel[2] - tfpixel[2] + 1); offset[2] = (i2 - 1) * rowdim[2] + offset[3]; for (i1 = ftile[1]; i1 <= ltile[1]; i1++) { tfpixel[1] = (i1 - 1) * tilesize[1] + 1; tlpixel[1] = minvalue(tfpixel[1] + tilesize[1] - 1, naxis[1]); thistilesize[1] = thistilesize[2] * (tlpixel[1] - tfpixel[1] + 1); offset[1] = (i1 - 1) * rowdim[1] + offset[2]; for (i0 = ftile[0]; i0 <= ltile[0]; i0++) { tfpixel[0] = (i0 - 1) * tilesize[0] + 1; tlpixel[0] = minvalue(tfpixel[0] + tilesize[0] - 1, naxis[0]); thistilesize[0] = thistilesize[1] * (tlpixel[0] - tfpixel[0] + 1); /* calculate row of table containing this tile */ irow = i0 + offset[1]; /* read and uncompress this row (tile) of the table */ /* also do type conversion and undefined pixel substitution */ /* at this point */ imcomp_decompress_tile(fptr, irow, thistilesize[0], datatype, nullcheck, nullval, buffer, bnullarray, &tilenul, status); if (*status == NO_COMPRESSED_TILE) { /* tile doesn't exist, so initialize to zero */ memset(buffer, 0, pixlen * thistilesize[0]); *status = 0; } /* copy the intersecting pixels to this tile from the input */ imcomp_merge_overlap(buffer, pixlen, ndim, tfpixel, tlpixel, bnullarray, array, fpixel, lpixel, nullcheck, status); /* Collapse sizes of higher dimension tiles into 2 dimensional equivalents needed by the quantizing algorithms for floating point types */ fits_calc_tile_rows(tlpixel, tfpixel, ndim, &trowsize, &ntrows, status); /* compress the tile again, and write it back to the FITS file */ imcomp_compress_tile (fptr, irow, datatype, buffer, thistilesize[0], trowsize, ntrows, nullcheck, nullval, status); } } } } } } free(buffer); if ((fptr->Fptr)->zbitpix < 0 && nullcheck != 0) { /* This is a floating point FITS image with possible null values. It is too messy to test if any null values are actually written, so just assume so. We need to make sure that the ZBLANK keyword is present in the compressed image header. If it is not there then we need to insert the keyword. */ tstatus = 0; ffgcrd(fptr, "ZBLANK", card, &tstatus); if (tstatus) { /* have to insert the ZBLANK keyword */ ffgcrd(fptr, "ZCMPTYPE", card, status); ffikyj(fptr, "ZBLANK", COMPRESS_NULL_VALUE, "null value in the compressed integer array", status); /* set this value into the internal structure; it is used if */ /* the program reads back the values from the array */ (fptr->Fptr)->zblank = COMPRESS_NULL_VALUE; (fptr->Fptr)->cn_zblank = -1; /* flag for a constant ZBLANK */ } } return(*status); } /*--------------------------------------------------------------------------*/ int fits_write_compressed_pixels(fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the array to be written */ LONGLONG fpixel, /* I - 'first pixel to write */ LONGLONG npixel, /* I - number of pixels to write */ int nullcheck, /* I - 0 for no null checking */ /* 1: pixels that are = nullval will be */ /* written with the FITS null pixel value */ /* (floating point arrays only) */ void *array, /* I - array of values to write */ void *nullval, /* I - value used to represent undefined pixels*/ int *status) /* IO - error status */ /* Write a consecutive set of pixels to a compressed image. This routine interpretes the n-dimensional image as a long one-dimensional array. This is actually a rather inconvenient way to write compressed images in general, and could be rather inefficient if the requested pixels to be written are located in many different image compression tiles. The general strategy used here is to write the requested pixels in blocks that correspond to rectangular image sections. */ { int naxis, ii, bytesperpixel; long naxes[MAX_COMPRESS_DIM], nread; LONGLONG tfirst, tlast, last0, last1, dimsize[MAX_COMPRESS_DIM]; long nplane, firstcoord[MAX_COMPRESS_DIM], lastcoord[MAX_COMPRESS_DIM]; char *arrayptr; if (*status > 0) return(*status); arrayptr = (char *) array; /* get size of array pixels, in bytes */ bytesperpixel = ffpxsz(datatype); for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { naxes[ii] = 1; firstcoord[ii] = 0; lastcoord[ii] = 0; } /* determine the dimensions of the image to be written */ ffgidm(fptr, &naxis, status); ffgisz(fptr, MAX_COMPRESS_DIM, naxes, status); /* calc the cumulative number of pixels in each successive dimension */ dimsize[0] = 1; for (ii = 1; ii < MAX_COMPRESS_DIM; ii++) dimsize[ii] = dimsize[ii - 1] * naxes[ii - 1]; /* determine the coordinate of the first and last pixel in the image */ /* Use zero based indexes here */ tfirst = fpixel - 1; tlast = tfirst + npixel - 1; for (ii = naxis - 1; ii >= 0; ii--) { firstcoord[ii] = (long) (tfirst / dimsize[ii]); lastcoord[ii] = (long) (tlast / dimsize[ii]); tfirst = tfirst - firstcoord[ii] * dimsize[ii]; tlast = tlast - lastcoord[ii] * dimsize[ii]; } /* to simplify things, treat 1-D, 2-D, and 3-D images as separate cases */ if (naxis == 1) { /* Simple: just write the requested range of pixels */ firstcoord[0] = firstcoord[0] + 1; lastcoord[0] = lastcoord[0] + 1; fits_write_compressed_img(fptr, datatype, firstcoord, lastcoord, nullcheck, array, nullval, status); return(*status); } else if (naxis == 2) { nplane = 0; /* write 1st (and only) plane of the image */ fits_write_compressed_img_plane(fptr, datatype, bytesperpixel, nplane, firstcoord, lastcoord, naxes, nullcheck, array, nullval, &nread, status); } else if (naxis == 3) { /* test for special case: writing an integral number of planes */ if (firstcoord[0] == 0 && firstcoord[1] == 0 && lastcoord[0] == naxes[0] - 1 && lastcoord[1] == naxes[1] - 1) { for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { /* convert from zero base to 1 base */ (firstcoord[ii])++; (lastcoord[ii])++; } /* we can write the contiguous block of pixels in one go */ fits_write_compressed_img(fptr, datatype, firstcoord, lastcoord, nullcheck, array, nullval, status); return(*status); } /* save last coordinate in temporary variables */ last0 = lastcoord[0]; last1 = lastcoord[1]; if (firstcoord[2] < lastcoord[2]) { /* we will write up to the last pixel in all but the last plane */ lastcoord[0] = naxes[0] - 1; lastcoord[1] = naxes[1] - 1; } /* write one plane of the cube at a time, for simplicity */ for (nplane = firstcoord[2]; nplane <= lastcoord[2]; nplane++) { if (nplane == lastcoord[2]) { lastcoord[0] = (long) last0; lastcoord[1] = (long) last1; } fits_write_compressed_img_plane(fptr, datatype, bytesperpixel, nplane, firstcoord, lastcoord, naxes, nullcheck, arrayptr, nullval, &nread, status); /* for all subsequent planes, we start with the first pixel */ firstcoord[0] = 0; firstcoord[1] = 0; /* increment pointers to next elements to be written */ arrayptr = arrayptr + nread * bytesperpixel; } } else { ffpmsg("only 1D, 2D, or 3D images are currently supported"); return(*status = DATA_COMPRESSION_ERR); } return(*status); } /*--------------------------------------------------------------------------*/ int fits_write_compressed_img_plane(fitsfile *fptr, /* I - FITS file */ int datatype, /* I - datatype of the array to be written */ int bytesperpixel, /* I - number of bytes per pixel in array */ long nplane, /* I - which plane of the cube to write */ long *firstcoord, /* I coordinate of first pixel to write */ long *lastcoord, /* I coordinate of last pixel to write */ long *naxes, /* I size of each image dimension */ int nullcheck, /* I - 0 for no null checking */ /* 1: pixels that are = nullval will be */ /* written with the FITS null pixel value */ /* (floating point arrays only) */ void *array, /* I - array of values that are written */ void *nullval, /* I - value for undefined pixels */ long *nread, /* O - total number of pixels written */ int *status) /* IO - error status */ /* in general we have to write the first partial row of the image, followed by the middle complete rows, followed by the last partial row of the image. If the first or last rows are complete, then write them at the same time as all the middle rows. */ { /* bottom left coord. and top right coord. */ long blc[MAX_COMPRESS_DIM], trc[MAX_COMPRESS_DIM]; char *arrayptr; *nread = 0; arrayptr = (char *) array; blc[2] = nplane + 1; trc[2] = nplane + 1; if (firstcoord[0] != 0) { /* have to read a partial first row */ blc[0] = firstcoord[0] + 1; blc[1] = firstcoord[1] + 1; trc[1] = blc[1]; if (lastcoord[1] == firstcoord[1]) trc[0] = lastcoord[0] + 1; /* 1st and last pixels in same row */ else trc[0] = naxes[0]; /* read entire rest of the row */ fits_write_compressed_img(fptr, datatype, blc, trc, nullcheck, arrayptr, nullval, status); *nread = *nread + trc[0] - blc[0] + 1; if (lastcoord[1] == firstcoord[1]) { return(*status); /* finished */ } /* set starting coord to beginning of next line */ firstcoord[0] = 0; firstcoord[1] += 1; arrayptr = arrayptr + (trc[0] - blc[0] + 1) * bytesperpixel; } /* write contiguous complete rows of the image, if any */ blc[0] = 1; blc[1] = firstcoord[1] + 1; trc[0] = naxes[0]; if (lastcoord[0] + 1 == naxes[0]) { /* can write the last complete row, too */ trc[1] = lastcoord[1] + 1; } else { /* last row is incomplete; have to read it separately */ trc[1] = lastcoord[1]; } if (trc[1] >= blc[1]) /* must have at least one whole line to read */ { fits_write_compressed_img(fptr, datatype, blc, trc, nullcheck, arrayptr, nullval, status); *nread = *nread + (trc[1] - blc[1] + 1) * naxes[0]; if (lastcoord[1] + 1 == trc[1]) return(*status); /* finished */ /* increment pointers for the last partial row */ arrayptr = arrayptr + (trc[1] - blc[1] + 1) * naxes[0] * bytesperpixel; } if (trc[1] == lastcoord[1] + 1) return(*status); /* all done */ /* set starting and ending coord to last line */ trc[0] = lastcoord[0] + 1; trc[1] = lastcoord[1] + 1; blc[1] = trc[1]; fits_write_compressed_img(fptr, datatype, blc, trc, nullcheck, arrayptr, nullval, status); *nread = *nread + trc[0] - blc[0] + 1; return(*status); } /* ######################################################################## */ /* ### Image Decompression Routines ### */ /* ######################################################################## */ /*--------------------------------------------------------------------------*/ int fits_img_decompress (fitsfile *infptr, /* image (bintable) to uncompress */ fitsfile *outfptr, /* empty HDU for output uncompressed image */ int *status) /* IO - error status */ /* This routine decompresses the whole image and writes it to the output file. */ { int ii, datatype = 0; int nullcheck, anynul; LONGLONG fpixel[MAX_COMPRESS_DIM], lpixel[MAX_COMPRESS_DIM]; long inc[MAX_COMPRESS_DIM]; long imgsize; float *nulladdr, fnulval; double dnulval; if (fits_img_decompress_header(infptr, outfptr, status) > 0) { return (*status); } /* force a rescan of the output header keywords, then reset the scaling */ /* in case the BSCALE and BZERO keywords are present, so that the */ /* decompressed values won't be scaled when written to the output image */ ffrdef(outfptr, status); ffpscl(outfptr, 1.0, 0.0, status); ffpscl(infptr, 1.0, 0.0, status); /* initialize; no null checking is needed for integer images */ nullcheck = 0; nulladdr = &fnulval; /* determine datatype for image */ if ((infptr->Fptr)->zbitpix == BYTE_IMG) { datatype = TBYTE; } else if ((infptr->Fptr)->zbitpix == SHORT_IMG) { datatype = TSHORT; } else if ((infptr->Fptr)->zbitpix == LONG_IMG) { datatype = TINT; } else if ((infptr->Fptr)->zbitpix == FLOAT_IMG) { /* In the case of float images we must check for NaNs */ nullcheck = 1; fnulval = FLOATNULLVALUE; nulladdr = &fnulval; datatype = TFLOAT; } else if ((infptr->Fptr)->zbitpix == DOUBLE_IMG) { /* In the case of double images we must check for NaNs */ nullcheck = 1; dnulval = DOUBLENULLVALUE; nulladdr = (float *) &dnulval; datatype = TDOUBLE; } /* calculate size of the image (in pixels) */ imgsize = 1; for (ii = 0; ii < (infptr->Fptr)->zndim; ii++) { imgsize *= (infptr->Fptr)->znaxis[ii]; fpixel[ii] = 1; /* Set first and last pixel to */ lpixel[ii] = (infptr->Fptr)->znaxis[ii]; /* include the entire image. */ inc[ii] = 1; } /* uncompress the input image and write to output image, one tile at a time */ fits_read_write_compressed_img(infptr, datatype, fpixel, lpixel, inc, nullcheck, nulladdr, &anynul, outfptr, status); return (*status); } /*--------------------------------------------------------------------------*/ int fits_decompress_img (fitsfile *infptr, /* image (bintable) to uncompress */ fitsfile *outfptr, /* empty HDU for output uncompressed image */ int *status) /* IO - error status */ /* THIS IS AN OBSOLETE ROUTINE. USE fits_img_decompress instead!!! This routine decompresses the whole image and writes it to the output file. */ { double *data; int ii, datatype = 0, byte_per_pix = 0; int nullcheck, anynul; LONGLONG fpixel[MAX_COMPRESS_DIM], lpixel[MAX_COMPRESS_DIM]; long inc[MAX_COMPRESS_DIM]; long imgsize, memsize; float *nulladdr, fnulval; double dnulval; if (*status > 0) return(*status); if (!fits_is_compressed_image(infptr, status) ) { ffpmsg("CHDU is not a compressed image (fits_decompress_img)"); return(*status = DATA_DECOMPRESSION_ERR); } /* create an empty output image with the correct dimensions */ if (ffcrim(outfptr, (infptr->Fptr)->zbitpix, (infptr->Fptr)->zndim, (infptr->Fptr)->znaxis, status) > 0) { ffpmsg("error creating output decompressed image HDU"); return (*status); } /* Copy the table header to the image header. */ if (imcomp_copy_imheader(infptr, outfptr, status) > 0) { ffpmsg("error copying header of compressed image"); return (*status); } /* force a rescan of the output header keywords, then reset the scaling */ /* in case the BSCALE and BZERO keywords are present, so that the */ /* decompressed values won't be scaled when written to the output image */ ffrdef(outfptr, status); ffpscl(outfptr, 1.0, 0.0, status); ffpscl(infptr, 1.0, 0.0, status); /* initialize; no null checking is needed for integer images */ nullcheck = 0; nulladdr = &fnulval; /* determine datatype for image */ if ((infptr->Fptr)->zbitpix == BYTE_IMG) { datatype = TBYTE; byte_per_pix = 1; } else if ((infptr->Fptr)->zbitpix == SHORT_IMG) { datatype = TSHORT; byte_per_pix = sizeof(short); } else if ((infptr->Fptr)->zbitpix == LONG_IMG) { datatype = TINT; byte_per_pix = sizeof(int); } else if ((infptr->Fptr)->zbitpix == FLOAT_IMG) { /* In the case of float images we must check for NaNs */ nullcheck = 1; fnulval = FLOATNULLVALUE; nulladdr = &fnulval; datatype = TFLOAT; byte_per_pix = sizeof(float); } else if ((infptr->Fptr)->zbitpix == DOUBLE_IMG) { /* In the case of double images we must check for NaNs */ nullcheck = 1; dnulval = DOUBLENULLVALUE; nulladdr = (float *) &dnulval; datatype = TDOUBLE; byte_per_pix = sizeof(double); } /* calculate size of the image (in pixels) */ imgsize = 1; for (ii = 0; ii < (infptr->Fptr)->zndim; ii++) { imgsize *= (infptr->Fptr)->znaxis[ii]; fpixel[ii] = 1; /* Set first and last pixel to */ lpixel[ii] = (infptr->Fptr)->znaxis[ii]; /* include the entire image. */ inc[ii] = 1; } /* Calc equivalent number of double pixels same size as whole the image. */ /* We use double datatype to force the memory to be aligned properly */ memsize = ((imgsize * byte_per_pix) - 1) / sizeof(double) + 1; /* allocate memory for the image */ data = (double*) calloc (memsize, sizeof(double)); if (!data) { ffpmsg("Couldn't allocate memory for the uncompressed image"); return(*status = MEMORY_ALLOCATION); } /* uncompress the entire image into memory */ /* This routine should be enhanced sometime to only need enough */ /* memory to uncompress one tile at a time. */ fits_read_compressed_img(infptr, datatype, fpixel, lpixel, inc, nullcheck, nulladdr, data, NULL, &anynul, status); /* write the image to the output file */ if (anynul) fits_write_imgnull(outfptr, datatype, 1, imgsize, data, nulladdr, status); else fits_write_img(outfptr, datatype, 1, imgsize, data, status); free(data); return (*status); } /*--------------------------------------------------------------------------*/ int fits_img_decompress_header(fitsfile *infptr, /* image (bintable) to uncompress */ fitsfile *outfptr, /* empty HDU for output uncompressed image */ int *status) /* IO - error status */ /* This routine reads the header of the input tile compressed image and converts it to that of a standard uncompress FITS image. */ { int writeprime = 0; int hdupos, inhdupos, numkeys; int nullprime = 0, copyprime = 0, norec = 0, tstatus; char card[FLEN_CARD]; int ii, naxis, bitpix; long naxes[MAX_COMPRESS_DIM]; if (*status > 0) return(*status); else if (*status == -1) { *status = 0; writeprime = 1; } if (!fits_is_compressed_image(infptr, status) ) { ffpmsg("CHDU is not a compressed image (fits_img_decompress)"); return(*status = DATA_DECOMPRESSION_ERR); } /* get information about the state of the output file; does it already */ /* contain any keywords and HDUs? */ fits_get_hdu_num(infptr, &inhdupos); /* Get the current output HDU position */ fits_get_hdu_num(outfptr, &hdupos); /* Get the current output HDU position */ fits_get_hdrspace(outfptr, &numkeys, 0, status); /* Was the input compressed HDU originally the primary array image? */ tstatus = 0; if (!fits_read_card(infptr, "ZSIMPLE", card, &tstatus)) { /* yes, input HDU was a primary array (not an IMAGE extension) */ /* Now determine if we can uncompress it into the primary array of */ /* the output file. This is only possible if the output file */ /* currently only contains a null primary array, with no addition */ /* header keywords and with no following extension in the FITS file. */ if (hdupos == 1) { /* are we positioned at the primary array? */ if (numkeys == 0) { /* primary HDU is completely empty */ nullprime = 1; } else { fits_get_img_param(outfptr, MAX_COMPRESS_DIM, &bitpix, &naxis, naxes, status); if (naxis == 0) { /* is this a null image? */ nullprime = 1; if (inhdupos == 2) /* must be at the first extension */ copyprime = 1; } } } } if (nullprime) { /* We will delete the existing keywords in the null primary array and uncompress the input image into the primary array of the output. Some of these keywords may be added back to the uncompressed image header later. */ for (ii = numkeys; ii > 0; ii--) fits_delete_record(outfptr, ii, status); } else { /* if the ZTENSION keyword doesn't exist, then we have to write the required keywords manually */ tstatus = 0; if (fits_read_card(infptr, "ZTENSION", card, &tstatus)) { /* create an empty output image with the correct dimensions */ if (ffcrim(outfptr, (infptr->Fptr)->zbitpix, (infptr->Fptr)->zndim, (infptr->Fptr)->znaxis, status) > 0) { ffpmsg("error creating output decompressed image HDU"); return (*status); } norec = 1; /* the required keywords have already been written */ } else { /* the input compressed image does have ZTENSION keyword */ if (writeprime) { /* convert the image extension to a primary array */ /* have to write the required keywords manually */ /* create an empty output image with the correct dimensions */ if (ffcrim(outfptr, (infptr->Fptr)->zbitpix, (infptr->Fptr)->zndim, (infptr->Fptr)->znaxis, status) > 0) { ffpmsg("error creating output decompressed image HDU"); return (*status); } norec = 1; /* the required keywords have already been written */ } else { /* write the input compressed image to an image extension */ if (numkeys == 0) { /* the output file is currently completely empty */ /* In this case, the input is a compressed IMAGE extension. */ /* Since the uncompressed output file is currently completely empty, */ /* we need to write a null primary array before uncompressing the */ /* image extension */ ffcrim(outfptr, 8, 0, naxes, status); /* naxes is not used */ /* now create the empty extension to uncompress into */ if (fits_create_hdu(outfptr, status) > 0) { ffpmsg("error creating output decompressed image HDU"); return (*status); } } else { /* just create a new empty extension, then copy all the required */ /* keywords into it. */ fits_create_hdu(outfptr, status); } } } } if (*status > 0) { ffpmsg("error creating output decompressed image HDU"); return (*status); } /* Copy the table header to the image header. */ if (imcomp_copy_comp2img(infptr, outfptr, norec, status) > 0) { ffpmsg("error copying header keywords from compressed image"); } if (copyprime) { /* append any unexpected keywords from the primary array. This includes any keywords except SIMPLE, BITPIX, NAXIS, EXTEND, COMMENT, HISTORY, CHECKSUM, and DATASUM. */ fits_movabs_hdu(infptr, 1, NULL, status); /* move to primary array */ /* do this so that any new keywords get written before any blank keywords that may have been appended by imcomp_copy_comp2img */ fits_set_hdustruc(outfptr, status); if (imcomp_copy_prime2img(infptr, outfptr, status) > 0) { ffpmsg("error copying primary keywords from compressed file"); } fits_movabs_hdu(infptr, 2, NULL, status); /* move back to where we were */ } return (*status); } /*---------------------------------------------------------------------------*/ int fits_read_compressed_img(fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the array to be returned */ LONGLONG *infpixel, /* I - 'bottom left corner' of the subsection */ LONGLONG *inlpixel, /* I - 'top right corner' of the subsection */ long *ininc, /* I - increment to be applied in each dimension */ int nullcheck, /* I - 0 for no null checking */ /* 1: set undefined pixels = nullval */ /* 2: set nullarray=1 for undefined pixels */ void *nullval, /* I - value for undefined pixels */ void *array, /* O - array of values that are returned */ char *nullarray, /* O - array of flags = 1 if nullcheck = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a section of a compressed image; Note: lpixel may be larger than the size of the uncompressed image. Only the pixels within the image will be returned. */ { long naxis[MAX_COMPRESS_DIM], tiledim[MAX_COMPRESS_DIM]; long tilesize[MAX_COMPRESS_DIM], thistilesize[MAX_COMPRESS_DIM]; long ftile[MAX_COMPRESS_DIM], ltile[MAX_COMPRESS_DIM]; long tfpixel[MAX_COMPRESS_DIM], tlpixel[MAX_COMPRESS_DIM]; long rowdim[MAX_COMPRESS_DIM], offset[MAX_COMPRESS_DIM],ntemp; long fpixel[MAX_COMPRESS_DIM], lpixel[MAX_COMPRESS_DIM]; long inc[MAX_COMPRESS_DIM]; long i5, i4, i3, i2, i1, i0, irow; int ii, ndim, pixlen, tilenul=0; void *buffer; char *bnullarray = 0; double testnullval = 0.; if (*status > 0) return(*status); if (!fits_is_compressed_image(fptr, status) ) { ffpmsg("CHDU is not a compressed image (fits_read_compressed_img)"); return(*status = DATA_DECOMPRESSION_ERR); } /* get temporary space for uncompressing one image tile */ if (datatype == TSHORT) { buffer = malloc ((fptr->Fptr)->maxtilelen * sizeof (short)); pixlen = sizeof(short); if (nullval) testnullval = *(short *) nullval; } else if (datatype == TINT) { buffer = malloc ((fptr->Fptr)->maxtilelen * sizeof (int)); pixlen = sizeof(int); if (nullval) testnullval = *(int *) nullval; } else if (datatype == TLONG) { buffer = malloc ((fptr->Fptr)->maxtilelen * sizeof (long)); pixlen = sizeof(long); if (nullval) testnullval = *(long *) nullval; } else if (datatype == TFLOAT) { buffer = malloc ((fptr->Fptr)->maxtilelen * sizeof (float)); pixlen = sizeof(float); if (nullval) testnullval = *(float *) nullval; } else if (datatype == TDOUBLE) { buffer = malloc ((fptr->Fptr)->maxtilelen * sizeof (double)); pixlen = sizeof(double); if (nullval) testnullval = *(double *) nullval; } else if (datatype == TUSHORT) { buffer = malloc ((fptr->Fptr)->maxtilelen * sizeof (unsigned short)); pixlen = sizeof(short); if (nullval) testnullval = *(unsigned short *) nullval; } else if (datatype == TUINT) { buffer = malloc ((fptr->Fptr)->maxtilelen * sizeof (unsigned int)); pixlen = sizeof(int); if (nullval) testnullval = *(unsigned int *) nullval; } else if (datatype == TULONG) { buffer = malloc ((fptr->Fptr)->maxtilelen * sizeof (unsigned long)); pixlen = sizeof(long); if (nullval) testnullval = *(unsigned long *) nullval; } else if (datatype == TBYTE || datatype == TSBYTE) { buffer = malloc ((fptr->Fptr)->maxtilelen * sizeof (char)); pixlen = 1; if (nullval) testnullval = *(unsigned char *) nullval; } else { ffpmsg("unsupported datatype for uncompressing image"); return(*status = BAD_DATATYPE); } /* If nullcheck ==1 and nullval == 0, then this means that the */ /* calling routine does not want to check for null pixels in the array */ if (nullcheck == 1 && testnullval == 0.) nullcheck = 0; if (buffer == NULL) { ffpmsg("Out of memory (fits_read_compress_img)"); return (*status = MEMORY_ALLOCATION); } /* allocate memory for a null flag array, if needed */ if (nullcheck == 2) { bnullarray = calloc ((fptr->Fptr)->maxtilelen, sizeof (char)); if (bnullarray == NULL) { ffpmsg("Out of memory (fits_read_compress_img)"); free(buffer); return (*status = MEMORY_ALLOCATION); } } /* initialize all the arrays */ for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { naxis[ii] = 1; tiledim[ii] = 1; tilesize[ii] = 1; ftile[ii] = 1; ltile[ii] = 1; rowdim[ii] = 1; } ndim = (fptr->Fptr)->zndim; ntemp = 1; for (ii = 0; ii < ndim; ii++) { /* support for mirror-reversed image sections */ if (infpixel[ii] <= inlpixel[ii]) { fpixel[ii] = (long) infpixel[ii]; lpixel[ii] = (long) inlpixel[ii]; inc[ii] = ininc[ii]; } else { fpixel[ii] = (long) inlpixel[ii]; lpixel[ii] = (long) infpixel[ii]; inc[ii] = -ininc[ii]; } /* calc number of tiles in each dimension, and tile containing */ /* the first and last pixel we want to read in each dimension */ naxis[ii] = (fptr->Fptr)->znaxis[ii]; if (fpixel[ii] < 1) { if (nullcheck == 2) { free(bnullarray); } free(buffer); return(*status = BAD_PIX_NUM); } tilesize[ii] = (fptr->Fptr)->tilesize[ii]; tiledim[ii] = (naxis[ii] - 1) / tilesize[ii] + 1; ftile[ii] = (fpixel[ii] - 1) / tilesize[ii] + 1; ltile[ii] = minvalue((lpixel[ii] - 1) / tilesize[ii] + 1, tiledim[ii]); rowdim[ii] = ntemp; /* total tiles in each dimension */ ntemp *= tiledim[ii]; } if (anynul) *anynul = 0; /* initialize */ /* support up to 6 dimensions for now */ /* tfpixel and tlpixel are the first and last image pixels */ /* along each dimension of the compression tile */ for (i5 = ftile[5]; i5 <= ltile[5]; i5++) { tfpixel[5] = (i5 - 1) * tilesize[5] + 1; tlpixel[5] = minvalue(tfpixel[5] + tilesize[5] - 1, naxis[5]); thistilesize[5] = tlpixel[5] - tfpixel[5] + 1; offset[5] = (i5 - 1) * rowdim[5]; for (i4 = ftile[4]; i4 <= ltile[4]; i4++) { tfpixel[4] = (i4 - 1) * tilesize[4] + 1; tlpixel[4] = minvalue(tfpixel[4] + tilesize[4] - 1, naxis[4]); thistilesize[4] = thistilesize[5] * (tlpixel[4] - tfpixel[4] + 1); offset[4] = (i4 - 1) * rowdim[4] + offset[5]; for (i3 = ftile[3]; i3 <= ltile[3]; i3++) { tfpixel[3] = (i3 - 1) * tilesize[3] + 1; tlpixel[3] = minvalue(tfpixel[3] + tilesize[3] - 1, naxis[3]); thistilesize[3] = thistilesize[4] * (tlpixel[3] - tfpixel[3] + 1); offset[3] = (i3 - 1) * rowdim[3] + offset[4]; for (i2 = ftile[2]; i2 <= ltile[2]; i2++) { tfpixel[2] = (i2 - 1) * tilesize[2] + 1; tlpixel[2] = minvalue(tfpixel[2] + tilesize[2] - 1, naxis[2]); thistilesize[2] = thistilesize[3] * (tlpixel[2] - tfpixel[2] + 1); offset[2] = (i2 - 1) * rowdim[2] + offset[3]; for (i1 = ftile[1]; i1 <= ltile[1]; i1++) { tfpixel[1] = (i1 - 1) * tilesize[1] + 1; tlpixel[1] = minvalue(tfpixel[1] + tilesize[1] - 1, naxis[1]); thistilesize[1] = thistilesize[2] * (tlpixel[1] - tfpixel[1] + 1); offset[1] = (i1 - 1) * rowdim[1] + offset[2]; for (i0 = ftile[0]; i0 <= ltile[0]; i0++) { tfpixel[0] = (i0 - 1) * tilesize[0] + 1; tlpixel[0] = minvalue(tfpixel[0] + tilesize[0] - 1, naxis[0]); thistilesize[0] = thistilesize[1] * (tlpixel[0] - tfpixel[0] + 1); /* calculate row of table containing this tile */ irow = i0 + offset[1]; /* printf("row %d, %d %d, %d %d, %d %d; %d\n", irow, tfpixel[0],tlpixel[0],tfpixel[1],tlpixel[1],tfpixel[2],tlpixel[2], thistilesize[0]); */ /* test if there are any intersecting pixels in this tile and the output image */ if (imcomp_test_overlap(ndim, tfpixel, tlpixel, fpixel, lpixel, inc, status)) { /* read and uncompress this row (tile) of the table */ /* also do type conversion and undefined pixel substitution */ /* at this point */ imcomp_decompress_tile(fptr, irow, thistilesize[0], datatype, nullcheck, nullval, buffer, bnullarray, &tilenul, status); if (tilenul && anynul) *anynul = 1; /* there are null pixels */ /* printf(" pixlen=%d, ndim=%d, %d %d %d, %d %d %d, %d %d %d\n", pixlen, ndim, fpixel[0],lpixel[0],inc[0],fpixel[1],lpixel[1],inc[1], fpixel[2],lpixel[2],inc[2]); */ /* copy the intersecting pixels from this tile to the output */ imcomp_copy_overlap(buffer, pixlen, ndim, tfpixel, tlpixel, bnullarray, array, fpixel, lpixel, inc, nullcheck, nullarray, status); } } } } } } } if (nullcheck == 2) { free(bnullarray); } free(buffer); return(*status); } /*---------------------------------------------------------------------------*/ int fits_read_write_compressed_img(fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the array to be returned */ LONGLONG *infpixel, /* I - 'bottom left corner' of the subsection */ LONGLONG *inlpixel, /* I - 'top right corner' of the subsection */ long *ininc, /* I - increment to be applied in each dimension */ int nullcheck, /* I - 0 for no null checking */ /* 1: set undefined pixels = nullval */ void *nullval, /* I - value for undefined pixels */ int *anynul, /* O - set to 1 if any values are null; else 0 */ fitsfile *outfptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* This is similar to fits_read_compressed_img, except that it writes the pixels to the output image, on a tile by tile basis instead of returning the array. */ { long naxis[MAX_COMPRESS_DIM], tiledim[MAX_COMPRESS_DIM]; long tilesize[MAX_COMPRESS_DIM], thistilesize[MAX_COMPRESS_DIM]; long ftile[MAX_COMPRESS_DIM], ltile[MAX_COMPRESS_DIM]; long tfpixel[MAX_COMPRESS_DIM], tlpixel[MAX_COMPRESS_DIM]; long rowdim[MAX_COMPRESS_DIM], offset[MAX_COMPRESS_DIM],ntemp; long fpixel[MAX_COMPRESS_DIM], lpixel[MAX_COMPRESS_DIM]; long inc[MAX_COMPRESS_DIM]; long i5, i4, i3, i2, i1, i0, irow; int ii, ndim, tilenul; void *buffer; char *bnullarray = 0, *cnull; LONGLONG firstelem; if (*status > 0) return(*status); if (!fits_is_compressed_image(fptr, status) ) { ffpmsg("CHDU is not a compressed image (fits_read_compressed_img)"); return(*status = DATA_DECOMPRESSION_ERR); } cnull = (char *) nullval; /* used to test if the nullval = 0 */ /* get temporary space for uncompressing one image tile */ /* If nullval == 0, then this means that the */ /* calling routine does not want to check for null pixels in the array */ if (datatype == TSHORT) { buffer = malloc ((fptr->Fptr)->maxtilelen * sizeof (short)); if (cnull) { if (cnull[0] == 0 && cnull[1] == 0 ) { nullcheck = 0; } } } else if (datatype == TINT) { buffer = malloc ((fptr->Fptr)->maxtilelen * sizeof (int)); if (cnull) { if (cnull[0] == 0 && cnull[1] == 0 && cnull[2] == 0 && cnull[3] == 0 ) { nullcheck = 0; } } } else if (datatype == TLONG) { buffer = malloc ((fptr->Fptr)->maxtilelen * sizeof (long)); if (cnull) { if (cnull[0] == 0 && cnull[1] == 0 && cnull[2] == 0 && cnull[3] == 0 ) { nullcheck = 0; } } } else if (datatype == TFLOAT) { buffer = malloc ((fptr->Fptr)->maxtilelen * sizeof (float)); if (cnull) { if (cnull[0] == 0 && cnull[1] == 0 && cnull[2] == 0 && cnull[3] == 0 ) { nullcheck = 0; } } } else if (datatype == TDOUBLE) { buffer = malloc ((fptr->Fptr)->maxtilelen * sizeof (double)); if (cnull) { if (cnull[0] == 0 && cnull[1] == 0 && cnull[2] == 0 && cnull[3] == 0 && cnull[4] == 0 && cnull[5] == 0 && cnull[6] == 0 && cnull[7] == 0 ) { nullcheck = 0; } } } else if (datatype == TUSHORT) { buffer = malloc ((fptr->Fptr)->maxtilelen * sizeof (unsigned short)); if (cnull) { if (cnull[0] == 0 && cnull[1] == 0 ){ nullcheck = 0; } } } else if (datatype == TUINT) { buffer = malloc ((fptr->Fptr)->maxtilelen * sizeof (unsigned int)); if (cnull) { if (cnull[0] == 0 && cnull[1] == 0 && cnull[2] == 0 && cnull[3] == 0 ){ nullcheck = 0; } } } else if (datatype == TULONG) { buffer = malloc ((fptr->Fptr)->maxtilelen * sizeof (unsigned long)); if (cnull) { if (cnull[0] == 0 && cnull[1] == 0 && cnull[2] == 0 && cnull[3] == 0 ){ nullcheck = 0; } } } else if (datatype == TBYTE || datatype == TSBYTE) { buffer = malloc ((fptr->Fptr)->maxtilelen * sizeof (char)); if (cnull) { if (cnull[0] == 0){ nullcheck = 0; } } } else { ffpmsg("unsupported datatype for uncompressing image"); return(*status = BAD_DATATYPE); } if (buffer == NULL) { ffpmsg("Out of memory (fits_read_compress_img)"); return (*status = MEMORY_ALLOCATION); } /* initialize all the arrays */ for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { naxis[ii] = 1; tiledim[ii] = 1; tilesize[ii] = 1; ftile[ii] = 1; ltile[ii] = 1; rowdim[ii] = 1; } ndim = (fptr->Fptr)->zndim; ntemp = 1; for (ii = 0; ii < ndim; ii++) { /* support for mirror-reversed image sections */ if (infpixel[ii] <= inlpixel[ii]) { fpixel[ii] = (long) infpixel[ii]; lpixel[ii] = (long) inlpixel[ii]; inc[ii] = ininc[ii]; } else { fpixel[ii] = (long) inlpixel[ii]; lpixel[ii] = (long) infpixel[ii]; inc[ii] = -ininc[ii]; } /* calc number of tiles in each dimension, and tile containing */ /* the first and last pixel we want to read in each dimension */ naxis[ii] = (fptr->Fptr)->znaxis[ii]; if (fpixel[ii] < 1) { free(buffer); return(*status = BAD_PIX_NUM); } tilesize[ii] = (fptr->Fptr)->tilesize[ii]; tiledim[ii] = (naxis[ii] - 1) / tilesize[ii] + 1; ftile[ii] = (fpixel[ii] - 1) / tilesize[ii] + 1; ltile[ii] = minvalue((lpixel[ii] - 1) / tilesize[ii] + 1, tiledim[ii]); rowdim[ii] = ntemp; /* total tiles in each dimension */ ntemp *= tiledim[ii]; } if (anynul) *anynul = 0; /* initialize */ firstelem = 1; /* support up to 6 dimensions for now */ /* tfpixel and tlpixel are the first and last image pixels */ /* along each dimension of the compression tile */ for (i5 = ftile[5]; i5 <= ltile[5]; i5++) { tfpixel[5] = (i5 - 1) * tilesize[5] + 1; tlpixel[5] = minvalue(tfpixel[5] + tilesize[5] - 1, naxis[5]); thistilesize[5] = tlpixel[5] - tfpixel[5] + 1; offset[5] = (i5 - 1) * rowdim[5]; for (i4 = ftile[4]; i4 <= ltile[4]; i4++) { tfpixel[4] = (i4 - 1) * tilesize[4] + 1; tlpixel[4] = minvalue(tfpixel[4] + tilesize[4] - 1, naxis[4]); thistilesize[4] = thistilesize[5] * (tlpixel[4] - tfpixel[4] + 1); offset[4] = (i4 - 1) * rowdim[4] + offset[5]; for (i3 = ftile[3]; i3 <= ltile[3]; i3++) { tfpixel[3] = (i3 - 1) * tilesize[3] + 1; tlpixel[3] = minvalue(tfpixel[3] + tilesize[3] - 1, naxis[3]); thistilesize[3] = thistilesize[4] * (tlpixel[3] - tfpixel[3] + 1); offset[3] = (i3 - 1) * rowdim[3] + offset[4]; for (i2 = ftile[2]; i2 <= ltile[2]; i2++) { tfpixel[2] = (i2 - 1) * tilesize[2] + 1; tlpixel[2] = minvalue(tfpixel[2] + tilesize[2] - 1, naxis[2]); thistilesize[2] = thistilesize[3] * (tlpixel[2] - tfpixel[2] + 1); offset[2] = (i2 - 1) * rowdim[2] + offset[3]; for (i1 = ftile[1]; i1 <= ltile[1]; i1++) { tfpixel[1] = (i1 - 1) * tilesize[1] + 1; tlpixel[1] = minvalue(tfpixel[1] + tilesize[1] - 1, naxis[1]); thistilesize[1] = thistilesize[2] * (tlpixel[1] - tfpixel[1] + 1); offset[1] = (i1 - 1) * rowdim[1] + offset[2]; for (i0 = ftile[0]; i0 <= ltile[0]; i0++) { tfpixel[0] = (i0 - 1) * tilesize[0] + 1; tlpixel[0] = minvalue(tfpixel[0] + tilesize[0] - 1, naxis[0]); thistilesize[0] = thistilesize[1] * (tlpixel[0] - tfpixel[0] + 1); /* calculate row of table containing this tile */ irow = i0 + offset[1]; /* read and uncompress this row (tile) of the table */ /* also do type conversion and undefined pixel substitution */ /* at this point */ imcomp_decompress_tile(fptr, irow, thistilesize[0], datatype, nullcheck, nullval, buffer, bnullarray, &tilenul, status); /* write the image to the output file */ if (tilenul && anynul) { /* this assumes that the tiled pixels are in the same order as in the uncompressed FITS image. This is not necessarily the case, but it almost alway is in practice. Note that null checking is not performed for integer images, so this could only be a problem for tile compressed floating point images that use an unconventional tiling pattern. */ fits_write_imgnull(outfptr, datatype, firstelem, thistilesize[0], buffer, nullval, status); } else { fits_write_subset(outfptr, datatype, tfpixel, tlpixel, buffer, status); } firstelem += thistilesize[0]; } } } } } } free(buffer); return(*status); } /*--------------------------------------------------------------------------*/ int fits_read_compressed_pixels(fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the array to be returned */ LONGLONG fpixel, /* I - 'first pixel to read */ LONGLONG npixel, /* I - number of pixels to read */ int nullcheck, /* I - 0 for no null checking */ /* 1: set undefined pixels = nullval */ /* 2: set nullarray=1 for undefined pixels */ void *nullval, /* I - value for undefined pixels */ void *array, /* O - array of values that are returned */ char *nullarray, /* O - array of flags = 1 if nullcheck = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a consecutive set of pixels from a compressed image. This routine interpretes the n-dimensional image as a long one-dimensional array. This is actually a rather inconvenient way to read compressed images in general, and could be rather inefficient if the requested pixels to be read are located in many different image compression tiles. The general strategy used here is to read the requested pixels in blocks that correspond to rectangular image sections. */ { int naxis, ii, bytesperpixel, planenul; long naxes[MAX_COMPRESS_DIM], nread; long nplane, inc[MAX_COMPRESS_DIM]; LONGLONG tfirst, tlast, last0, last1, dimsize[MAX_COMPRESS_DIM]; LONGLONG firstcoord[MAX_COMPRESS_DIM], lastcoord[MAX_COMPRESS_DIM]; char *arrayptr, *nullarrayptr; if (*status > 0) return(*status); arrayptr = (char *) array; nullarrayptr = nullarray; /* get size of array pixels, in bytes */ bytesperpixel = ffpxsz(datatype); for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { naxes[ii] = 1; firstcoord[ii] = 0; lastcoord[ii] = 0; inc[ii] = 1; } /* determine the dimensions of the image to be read */ ffgidm(fptr, &naxis, status); ffgisz(fptr, MAX_COMPRESS_DIM, naxes, status); /* calc the cumulative number of pixels in each successive dimension */ dimsize[0] = 1; for (ii = 1; ii < MAX_COMPRESS_DIM; ii++) dimsize[ii] = dimsize[ii - 1] * naxes[ii - 1]; /* determine the coordinate of the first and last pixel in the image */ /* Use zero based indexes here */ tfirst = fpixel - 1; tlast = tfirst + npixel - 1; for (ii = naxis - 1; ii >= 0; ii--) { firstcoord[ii] = tfirst / dimsize[ii]; lastcoord[ii] = tlast / dimsize[ii]; tfirst = tfirst - firstcoord[ii] * dimsize[ii]; tlast = tlast - lastcoord[ii] * dimsize[ii]; } /* to simplify things, treat 1-D, 2-D, and 3-D images as separate cases */ if (naxis == 1) { /* Simple: just read the requested range of pixels */ firstcoord[0] = firstcoord[0] + 1; lastcoord[0] = lastcoord[0] + 1; fits_read_compressed_img(fptr, datatype, firstcoord, lastcoord, inc, nullcheck, nullval, array, nullarray, anynul, status); return(*status); } else if (naxis == 2) { nplane = 0; /* read 1st (and only) plane of the image */ fits_read_compressed_img_plane(fptr, datatype, bytesperpixel, nplane, firstcoord, lastcoord, inc, naxes, nullcheck, nullval, array, nullarray, anynul, &nread, status); } else if (naxis == 3) { /* test for special case: reading an integral number of planes */ if (firstcoord[0] == 0 && firstcoord[1] == 0 && lastcoord[0] == naxes[0] - 1 && lastcoord[1] == naxes[1] - 1) { for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { /* convert from zero base to 1 base */ (firstcoord[ii])++; (lastcoord[ii])++; } /* we can read the contiguous block of pixels in one go */ fits_read_compressed_img(fptr, datatype, firstcoord, lastcoord, inc, nullcheck, nullval, array, nullarray, anynul, status); return(*status); } if (anynul) *anynul = 0; /* initialize */ /* save last coordinate in temporary variables */ last0 = lastcoord[0]; last1 = lastcoord[1]; if (firstcoord[2] < lastcoord[2]) { /* we will read up to the last pixel in all but the last plane */ lastcoord[0] = naxes[0] - 1; lastcoord[1] = naxes[1] - 1; } /* read one plane of the cube at a time, for simplicity */ for (nplane = (long) firstcoord[2]; nplane <= lastcoord[2]; nplane++) { if (nplane == lastcoord[2]) { lastcoord[0] = last0; lastcoord[1] = last1; } fits_read_compressed_img_plane(fptr, datatype, bytesperpixel, nplane, firstcoord, lastcoord, inc, naxes, nullcheck, nullval, arrayptr, nullarrayptr, &planenul, &nread, status); if (planenul && anynul) *anynul = 1; /* there are null pixels */ /* for all subsequent planes, we start with the first pixel */ firstcoord[0] = 0; firstcoord[1] = 0; /* increment pointers to next elements to be read */ arrayptr = arrayptr + nread * bytesperpixel; if (nullarrayptr && (nullcheck == 2) ) nullarrayptr = nullarrayptr + nread; } } else { ffpmsg("only 1D, 2D, or 3D images are currently supported"); return(*status = DATA_DECOMPRESSION_ERR); } return(*status); } /*--------------------------------------------------------------------------*/ int fits_read_compressed_img_plane(fitsfile *fptr, /* I - FITS file */ int datatype, /* I - datatype of the array to be returned */ int bytesperpixel, /* I - number of bytes per pixel in array */ long nplane, /* I - which plane of the cube to read */ LONGLONG *firstcoord, /* coordinate of first pixel to read */ LONGLONG *lastcoord, /* coordinate of last pixel to read */ long *inc, /* increment of pixels to read */ long *naxes, /* size of each image dimension */ int nullcheck, /* I - 0 for no null checking */ /* 1: set undefined pixels = nullval */ /* 2: set nullarray=1 for undefined pixels */ void *nullval, /* I - value for undefined pixels */ void *array, /* O - array of values that are returned */ char *nullarray, /* O - array of flags = 1 if nullcheck = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ long *nread, /* O - total number of pixels read and returned*/ int *status) /* IO - error status */ /* in general we have to read the first partial row of the image, followed by the middle complete rows, followed by the last partial row of the image. If the first or last rows are complete, then read them at the same time as all the middle rows. */ { /* bottom left coord. and top right coord. */ LONGLONG blc[MAX_COMPRESS_DIM], trc[MAX_COMPRESS_DIM]; char *arrayptr, *nullarrayptr; int tnull; if (anynul) *anynul = 0; *nread = 0; arrayptr = (char *) array; nullarrayptr = nullarray; blc[2] = nplane + 1; trc[2] = nplane + 1; if (firstcoord[0] != 0) { /* have to read a partial first row */ blc[0] = firstcoord[0] + 1; blc[1] = firstcoord[1] + 1; trc[1] = blc[1]; if (lastcoord[1] == firstcoord[1]) trc[0] = lastcoord[0] + 1; /* 1st and last pixels in same row */ else trc[0] = naxes[0]; /* read entire rest of the row */ fits_read_compressed_img(fptr, datatype, blc, trc, inc, nullcheck, nullval, arrayptr, nullarrayptr, &tnull, status); *nread = *nread + (long) (trc[0] - blc[0] + 1); if (tnull && anynul) *anynul = 1; /* there are null pixels */ if (lastcoord[1] == firstcoord[1]) { return(*status); /* finished */ } /* set starting coord to beginning of next line */ firstcoord[0] = 0; firstcoord[1] += 1; arrayptr = arrayptr + (trc[0] - blc[0] + 1) * bytesperpixel; if (nullarrayptr && (nullcheck == 2) ) nullarrayptr = nullarrayptr + (trc[0] - blc[0] + 1); } /* read contiguous complete rows of the image, if any */ blc[0] = 1; blc[1] = firstcoord[1] + 1; trc[0] = naxes[0]; if (lastcoord[0] + 1 == naxes[0]) { /* can read the last complete row, too */ trc[1] = lastcoord[1] + 1; } else { /* last row is incomplete; have to read it separately */ trc[1] = lastcoord[1]; } if (trc[1] >= blc[1]) /* must have at least one whole line to read */ { fits_read_compressed_img(fptr, datatype, blc, trc, inc, nullcheck, nullval, arrayptr, nullarrayptr, &tnull, status); *nread = *nread + (long) ((trc[1] - blc[1] + 1) * naxes[0]); if (tnull && anynul) *anynul = 1; if (lastcoord[1] + 1 == trc[1]) return(*status); /* finished */ /* increment pointers for the last partial row */ arrayptr = arrayptr + (trc[1] - blc[1] + 1) * naxes[0] * bytesperpixel; if (nullarrayptr && (nullcheck == 2) ) nullarrayptr = nullarrayptr + (trc[1] - blc[1] + 1) * naxes[0]; } if (trc[1] == lastcoord[1] + 1) return(*status); /* all done */ /* set starting and ending coord to last line */ trc[0] = lastcoord[0] + 1; trc[1] = lastcoord[1] + 1; blc[1] = trc[1]; fits_read_compressed_img(fptr, datatype, blc, trc, inc, nullcheck, nullval, arrayptr, nullarrayptr, &tnull, status); if (tnull && anynul) *anynul = 1; *nread = *nread + (long) (trc[0] - blc[0] + 1); return(*status); } /*--------------------------------------------------------------------------*/ int imcomp_get_compressed_image_par(fitsfile *infptr, int *status) /* This routine reads keywords from a BINTABLE extension containing a compressed image. */ { char keyword[FLEN_KEYWORD]; char value[FLEN_VALUE]; int ii, tstatus, tstatus2, doffset, oldFormat=0, colNum=0; long expect_nrows, maxtilelen; if (*status > 0) return(*status); /* Copy relevant header keyword values to structure */ if (ffgky (infptr, TSTRING, "ZCMPTYPE", value, NULL, status) > 0) { ffpmsg("required ZCMPTYPE compression keyword not found in"); ffpmsg(" imcomp_get_compressed_image_par"); return(*status); } (infptr->Fptr)->zcmptype[0] = '\0'; strncat((infptr->Fptr)->zcmptype, value, 11); if (!FSTRCMP(value, "RICE_1") || !FSTRCMP(value, "RICE_ONE") ) (infptr->Fptr)->compress_type = RICE_1; else if (!FSTRCMP(value, "HCOMPRESS_1") ) (infptr->Fptr)->compress_type = HCOMPRESS_1; else if (!FSTRCMP(value, "GZIP_1") ) (infptr->Fptr)->compress_type = GZIP_1; else if (!FSTRCMP(value, "GZIP_2") ) (infptr->Fptr)->compress_type = GZIP_2; else if (!FSTRCMP(value, "BZIP2_1") ) (infptr->Fptr)->compress_type = BZIP2_1; else if (!FSTRCMP(value, "PLIO_1") ) (infptr->Fptr)->compress_type = PLIO_1; else if (!FSTRCMP(value, "NOCOMPRESS") ) (infptr->Fptr)->compress_type = NOCOMPRESS; else { ffpmsg("Unknown image compression type:"); ffpmsg(value); return (*status = DATA_DECOMPRESSION_ERR); } if (ffgky (infptr, TINT, "ZBITPIX", &(infptr->Fptr)->zbitpix, NULL, status) > 0) { ffpmsg("required ZBITPIX compression keyword not found"); return(*status); } /* If ZZERO and ZSCALE columns don't exist for floating-point types, assume there is NO quantization. Treat exactly as if it had ZQUANTIZ='NONE'. This is true regardless of whether or not file has a ZQUANTIZ keyword. */ tstatus=0; tstatus2=0; if ((infptr->Fptr->zbitpix < 0) && (fits_get_colnum(infptr,CASEINSEN,"ZZERO",&colNum,&tstatus) == COL_NOT_FOUND) && (fits_get_colnum(infptr,CASEINSEN,"ZSCALE",&colNum,&tstatus2) == COL_NOT_FOUND)) { (infptr->Fptr)->quantize_level = NO_QUANTIZE; } else { /* get the floating point to integer quantization type, if present. */ /* FITS files produced before 2009 will not have this keyword */ tstatus = 0; if (ffgky(infptr, TSTRING, "ZQUANTIZ", value, NULL, &tstatus) > 0) { (infptr->Fptr)->quantize_method = 0; (infptr->Fptr)->quantize_level = 0; } else { if (!FSTRCMP(value, "NONE") ) { (infptr->Fptr)->quantize_level = NO_QUANTIZE; } else if (!FSTRCMP(value, "SUBTRACTIVE_DITHER_1") ) (infptr->Fptr)->quantize_method = SUBTRACTIVE_DITHER_1; else if (!FSTRCMP(value, "SUBTRACTIVE_DITHER_2") ) (infptr->Fptr)->quantize_method = SUBTRACTIVE_DITHER_2; else if (!FSTRCMP(value, "NO_DITHER") ) (infptr->Fptr)->quantize_method = NO_DITHER; else (infptr->Fptr)->quantize_method = 0; } } /* get the floating point quantization dithering offset, if present. */ /* FITS files produced before October 2009 will not have this keyword */ tstatus = 0; if (ffgky(infptr, TINT, "ZDITHER0", &doffset, NULL, &tstatus) > 0) { /* by default start with 1st element of random sequence */ (infptr->Fptr)->dither_seed = 1; } else { (infptr->Fptr)->dither_seed = doffset; } if (ffgky (infptr,TINT, "ZNAXIS", &(infptr->Fptr)->zndim, NULL, status) > 0) { ffpmsg("required ZNAXIS compression keyword not found"); return(*status); } if ((infptr->Fptr)->zndim < 1) { ffpmsg("Compressed image has no data (ZNAXIS < 1)"); return (*status = BAD_NAXIS); } if ((infptr->Fptr)->zndim > MAX_COMPRESS_DIM) { ffpmsg("Compressed image has too many dimensions"); return(*status = BAD_NAXIS); } expect_nrows = 1; maxtilelen = 1; for (ii = 0; ii < (infptr->Fptr)->zndim; ii++) { /* get image size */ snprintf (keyword, FLEN_KEYWORD,"ZNAXIS%d", ii+1); ffgky (infptr, TLONG,keyword, &(infptr->Fptr)->znaxis[ii],NULL,status); if (*status > 0) { ffpmsg("required ZNAXISn compression keyword not found"); return(*status); } /* get compression tile size */ snprintf (keyword, FLEN_KEYWORD,"ZTILE%d", ii+1); /* set default tile size in case keywords are not present */ if (ii == 0) (infptr->Fptr)->tilesize[0] = (infptr->Fptr)->znaxis[0]; else (infptr->Fptr)->tilesize[ii] = 1; tstatus = 0; ffgky (infptr, TLONG, keyword, &(infptr->Fptr)->tilesize[ii], NULL, &tstatus); expect_nrows *= (((infptr->Fptr)->znaxis[ii] - 1) / (infptr->Fptr)->tilesize[ii]+ 1); maxtilelen *= (infptr->Fptr)->tilesize[ii]; } /* check number of rows */ if (expect_nrows != (infptr->Fptr)->numrows) { ffpmsg( "number of table rows != the number of tiles in compressed image"); return (*status = DATA_DECOMPRESSION_ERR); } /* read any algorithm specific parameters */ if ((infptr->Fptr)->compress_type == RICE_1 ) { if (ffgky(infptr, TINT,"ZVAL1", &(infptr->Fptr)->rice_blocksize, NULL, status) > 0) { ffpmsg("required ZVAL1 compression keyword not found"); return(*status); } tstatus = 0; /* First check for very old files, where ZVAL2 wasn't yet designated for bytepix */ if (!ffgky(infptr, TSTRING, "ZNAME2", value, NULL, &tstatus) && !FSTRCMP(value, "NOISEBIT")) { oldFormat = 1; } tstatus = 0; if (oldFormat || ffgky(infptr, TINT,"ZVAL2", &(infptr->Fptr)->rice_bytepix, NULL, &tstatus) > 0) { (infptr->Fptr)->rice_bytepix = 4; /* default value */ } if ((infptr->Fptr)->rice_blocksize < 16 && (infptr->Fptr)->rice_bytepix > 8) { /* values are reversed */ tstatus = (infptr->Fptr)->rice_bytepix; (infptr->Fptr)->rice_bytepix = (infptr->Fptr)->rice_blocksize; (infptr->Fptr)->rice_blocksize = tstatus; } } else if ((infptr->Fptr)->compress_type == HCOMPRESS_1 ) { if (ffgky(infptr, TFLOAT,"ZVAL1", &(infptr->Fptr)->hcomp_scale, NULL, status) > 0) { ffpmsg("required ZVAL1 compression keyword not found"); return(*status); } tstatus = 0; ffgky(infptr, TINT,"ZVAL2", &(infptr->Fptr)->hcomp_smooth, NULL, &tstatus); } /* store number of pixels in each compression tile, */ /* and max size of the compressed tile buffer */ (infptr->Fptr)->maxtilelen = maxtilelen; (infptr->Fptr)->maxelem = imcomp_calc_max_elem ((infptr->Fptr)->compress_type, maxtilelen, (infptr->Fptr)->zbitpix, (infptr->Fptr)->rice_blocksize); /* Get Column numbers. */ if (ffgcno(infptr, CASEINSEN, "COMPRESSED_DATA", &(infptr->Fptr)->cn_compressed, status) > 0) { ffpmsg("couldn't find COMPRESSED_DATA column (fits_get_compressed_img_par)"); return(*status = DATA_DECOMPRESSION_ERR); } ffpmrk(); /* put mark on message stack; erase any messages after this */ tstatus = 0; ffgcno(infptr,CASEINSEN, "UNCOMPRESSED_DATA", &(infptr->Fptr)->cn_uncompressed, &tstatus); tstatus = 0; ffgcno(infptr,CASEINSEN, "GZIP_COMPRESSED_DATA", &(infptr->Fptr)->cn_gzip_data, &tstatus); tstatus = 0; if (ffgcno(infptr, CASEINSEN, "ZSCALE", &(infptr->Fptr)->cn_zscale, &tstatus) > 0) { /* CMPSCALE column doesn't exist; see if there is a keyword */ tstatus = 0; if (ffgky(infptr, TDOUBLE, "ZSCALE", &(infptr->Fptr)->zscale, NULL, &tstatus) <= 0) (infptr->Fptr)->cn_zscale = -1; /* flag for a constant ZSCALE */ } tstatus = 0; if (ffgcno(infptr, CASEINSEN, "ZZERO", &(infptr->Fptr)->cn_zzero, &tstatus) > 0) { /* CMPZERO column doesn't exist; see if there is a keyword */ tstatus = 0; if (ffgky(infptr, TDOUBLE, "ZZERO", &(infptr->Fptr)->zzero, NULL, &tstatus) <= 0) (infptr->Fptr)->cn_zzero = -1; /* flag for a constant ZZERO */ } tstatus = 0; if (ffgcno(infptr, CASEINSEN, "ZBLANK", &(infptr->Fptr)->cn_zblank, &tstatus) > 0) { /* ZBLANK column doesn't exist; see if there is a keyword */ tstatus = 0; if (ffgky(infptr, TINT, "ZBLANK", &(infptr->Fptr)->zblank, NULL, &tstatus) <= 0) { (infptr->Fptr)->cn_zblank = -1; /* flag for a constant ZBLANK */ } else { /* ZBLANK keyword doesn't exist; see if there is a BLANK keyword */ tstatus = 0; if (ffgky(infptr, TINT, "BLANK", &(infptr->Fptr)->zblank, NULL, &tstatus) <= 0) (infptr->Fptr)->cn_zblank = -1; /* flag for a constant ZBLANK */ } } /* read the conventional BSCALE and BZERO scaling keywords, if present */ tstatus = 0; if (ffgky (infptr, TDOUBLE, "BSCALE", &(infptr->Fptr)->cn_bscale, NULL, &tstatus) > 0) { (infptr->Fptr)->cn_bscale = 1.0; } tstatus = 0; if (ffgky (infptr, TDOUBLE, "BZERO", &(infptr->Fptr)->cn_bzero, NULL, &tstatus) > 0) { (infptr->Fptr)->cn_bzero = 0.0; (infptr->Fptr)->cn_actual_bzero = 0.0; } else { (infptr->Fptr)->cn_actual_bzero = (infptr->Fptr)->cn_bzero; } /* special case: the quantization level is not given by a keyword in */ /* the HDU header, so we have to explicitly copy the requested value */ /* to the actual value */ if ( (infptr->Fptr)->request_quantize_level != 0.) (infptr->Fptr)->quantize_level = (infptr->Fptr)->request_quantize_level; ffcmrk(); /* clear any spurious error messages, back to the mark */ return (*status); } /*--------------------------------------------------------------------------*/ int imcomp_copy_imheader(fitsfile *infptr, fitsfile *outfptr, int *status) /* This routine reads the header keywords from the input image and copies them to the output image; the manditory structural keywords and the checksum keywords are not copied. If the DATE keyword is copied, then it is updated with the current date and time. */ { int nkeys, ii, keyclass; char card[FLEN_CARD]; /* a header record */ if (*status > 0) return(*status); ffghsp(infptr, &nkeys, NULL, status); /* get number of keywords in image */ for (ii = 5; ii <= nkeys; ii++) /* skip the first 4 keywords */ { ffgrec(infptr, ii, card, status); keyclass = ffgkcl(card); /* Get the type/class of keyword */ /* don't copy structural keywords or checksum keywords */ if ((keyclass <= TYP_CMPRS_KEY) || (keyclass == TYP_CKSUM_KEY)) continue; if (FSTRNCMP(card, "DATE ", 5) == 0) /* write current date */ { ffpdat(outfptr, status); } else if (FSTRNCMP(card, "EXTNAME ", 8) == 0) { /* don't copy default EXTNAME keyword from a compressed image */ if (FSTRNCMP(card, "EXTNAME = 'COMPRESSED_IMAGE'", 28)) { /* if EXTNAME keyword already exists, overwrite it */ /* otherwise append a new EXTNAME keyword */ ffucrd(outfptr, "EXTNAME", card, status); } } else { /* just copy the keyword to the output header */ ffprec (outfptr, card, status); } if (*status > 0) return (*status); } return (*status); } /*--------------------------------------------------------------------------*/ int imcomp_copy_img2comp(fitsfile *infptr, fitsfile *outfptr, int *status) /* This routine copies the header keywords from the uncompressed input image and to the compressed image (in a binary table) */ { char card[FLEN_CARD], card2[FLEN_CARD]; /* a header record */ int nkeys, nmore, ii, jj, tstatus, bitpix; /* tile compressed image keyword translation table */ /* INPUT OUTPUT */ /* 01234567 01234567 */ char *patterns[][2] = {{"SIMPLE", "ZSIMPLE" }, {"XTENSION", "ZTENSION" }, {"BITPIX", "ZBITPIX" }, {"NAXIS", "ZNAXIS" }, {"NAXISm", "ZNAXISm" }, {"EXTEND", "ZEXTEND" }, {"BLOCKED", "ZBLOCKED"}, {"PCOUNT", "ZPCOUNT" }, {"GCOUNT", "ZGCOUNT" }, {"CHECKSUM","ZHECKSUM"}, /* save original checksums */ {"DATASUM", "ZDATASUM"}, {"*", "+" }}; /* copy all other keywords */ int npat; if (*status > 0) return(*status); /* write a default EXTNAME keyword if it doesn't exist in input file*/ fits_read_card(infptr, "EXTNAME", card, status); if (*status) { *status = 0; strcpy(card, "EXTNAME = 'COMPRESSED_IMAGE'"); fits_write_record(outfptr, card, status); } /* copy all the keywords from the input file to the output */ npat = sizeof(patterns)/sizeof(patterns[0][0])/2; fits_translate_keywords(infptr, outfptr, 1, patterns, npat, 0, 0, 0, status); if ( (outfptr->Fptr)->request_lossy_int_compress != 0) { /* request was made to compress integer images as if they had float pixels. */ /* If input image has positive bitpix value, then reset the output ZBITPIX */ /* value to -32. */ fits_read_key(infptr, TINT, "BITPIX", &bitpix, NULL, status); if (*status <= 0 && bitpix > 0) { fits_modify_key_lng(outfptr, "ZBITPIX", -32, NULL, status); /* also delete the BSCALE, BZERO, and BLANK keywords */ tstatus = 0; fits_delete_key(outfptr, "BSCALE", &tstatus); tstatus = 0; fits_delete_key(outfptr, "BZERO", &tstatus); tstatus = 0; fits_delete_key(outfptr, "BLANK", &tstatus); } } /* For compatibility with software that uses an older version of CFITSIO, we must make certain that the new ZQUANTIZ keyword, if it exists, must occur after the other peudo-required keywords (e.g., ZSIMPLE, ZBITPIX, etc.). Do this by trying to delete the keyword. If that succeeds (and thus the keyword did exist) then rewrite the keyword at the end of header. In principle this should not be necessary once all software has upgraded to a newer version of CFITSIO (version number greater than 3.181, newer than August 2009). Do the same for the new ZDITHER0 keyword. */ tstatus = 0; if (fits_read_card(outfptr, "ZQUANTIZ", card, &tstatus) == 0) { fits_delete_key(outfptr, "ZQUANTIZ", status); /* rewrite the deleted keyword at the end of the header */ fits_write_record(outfptr, card, status); /* write some associated HISTORY keywords */ fits_parse_value(card, card2, NULL, status); if (fits_strncasecmp(card2, "'NONE", 5) ) { /* the value is not 'NONE' */ fits_write_history(outfptr, "Image was compressed by CFITSIO using scaled integer quantization:", status); snprintf(card2, FLEN_CARD," q = %f / quantized level scaling parameter", (outfptr->Fptr)->request_quantize_level); fits_write_history(outfptr, card2, status); fits_write_history(outfptr, card+10, status); } } tstatus = 0; if (fits_read_card(outfptr, "ZDITHER0", card, &tstatus) == 0) { fits_delete_key(outfptr, "ZDITHER0", status); /* rewrite the deleted keyword at the end of the header */ fits_write_record(outfptr, card, status); } ffghsp(infptr, &nkeys, &nmore, status); /* get number of keywords in image */ nmore = nmore / 36; /* how many completely empty header blocks are there? */ /* preserve the same number of spare header blocks in the output header */ for (jj = 0; jj < nmore; jj++) for (ii = 0; ii < 36; ii++) fits_write_record(outfptr, " ", status); return (*status); } /*--------------------------------------------------------------------------*/ int imcomp_copy_comp2img(fitsfile *infptr, fitsfile *outfptr, int norec, int *status) /* This routine copies the header keywords from the compressed input image and to the uncompressed image (in a binary table) */ { char card[FLEN_CARD]; /* a header record */ char *patterns[40][2]; char negative[] = "-"; int ii,jj, npat, nreq, nsp, tstatus = 0; int nkeys, nmore; /* tile compressed image keyword translation table */ /* INPUT OUTPUT */ /* 01234567 01234567 */ /* only translate these if required keywords not already written */ char *reqkeys[][2] = { {"ZSIMPLE", "SIMPLE" }, {"ZTENSION", "XTENSION"}, {"ZBITPIX", "BITPIX" }, {"ZNAXIS", "NAXIS" }, {"ZNAXISm", "NAXISm" }, {"ZEXTEND", "EXTEND" }, {"ZBLOCKED", "BLOCKED"}, {"ZPCOUNT", "PCOUNT" }, {"ZGCOUNT", "GCOUNT" }, {"ZHECKSUM", "CHECKSUM"}, /* restore original checksums */ {"ZDATASUM", "DATASUM"}}; /* other special keywords */ char *spkeys[][2] = { {"XTENSION", "-" }, {"BITPIX", "-" }, {"NAXIS", "-" }, {"NAXISm", "-" }, {"PCOUNT", "-" }, {"GCOUNT", "-" }, {"TFIELDS", "-" }, {"TTYPEm", "-" }, {"TFORMm", "-" }, {"THEAP", "-" }, {"ZIMAGE", "-" }, {"ZQUANTIZ", "-" }, {"ZDITHER0", "-" }, {"ZTILEm", "-" }, {"ZCMPTYPE", "-" }, {"ZBLANK", "-" }, {"ZNAMEm", "-" }, {"ZVALm", "-" }, {"CHECKSUM","-" }, /* delete checksums */ {"DATASUM", "-" }, {"EXTNAME", "+" }, /* we may change this, below */ {"*", "+" }}; if (*status > 0) return(*status); nreq = sizeof(reqkeys)/sizeof(reqkeys[0][0])/2; nsp = sizeof(spkeys)/sizeof(spkeys[0][0])/2; /* construct translation patterns */ for (ii = 0; ii < nreq; ii++) { patterns[ii][0] = reqkeys[ii][0]; if (norec) patterns[ii][1] = negative; else patterns[ii][1] = reqkeys[ii][1]; } for (ii = 0; ii < nsp; ii++) { patterns[ii+nreq][0] = spkeys[ii][0]; patterns[ii+nreq][1] = spkeys[ii][1]; } npat = nreq + nsp; /* see if the EXTNAME keyword should be copied or not */ fits_read_card(infptr, "EXTNAME", card, &tstatus); if (tstatus == 0) { if (!strncmp(card, "EXTNAME = 'COMPRESSED_IMAGE'", 28)) patterns[npat-2][1] = negative; } /* translate and copy the keywords from the input file to the output */ fits_translate_keywords(infptr, outfptr, 1, patterns, npat, 0, 0, 0, status); ffghsp(infptr, &nkeys, &nmore, status); /* get number of keywords in image */ nmore = nmore / 36; /* how many completely empty header blocks are there? */ /* preserve the same number of spare header blocks in the output header */ for (jj = 0; jj < nmore; jj++) for (ii = 0; ii < 36; ii++) fits_write_record(outfptr, " ", status); return (*status); } /*--------------------------------------------------------------------------*/ int imcomp_copy_prime2img(fitsfile *infptr, fitsfile *outfptr, int *status) /* This routine copies any unexpected keywords from the primary array of the compressed input image into the header of the uncompressed image (which is the primary array of the output file). */ { int nsp; /* keywords that will not be copied */ char *spkeys[][2] = { {"SIMPLE", "-" }, {"BITPIX", "-" }, {"NAXIS", "-" }, {"NAXISm", "-" }, {"PCOUNT", "-" }, {"EXTEND", "-" }, {"GCOUNT", "-" }, {"CHECKSUM","-" }, {"DATASUM", "-" }, {"EXTNAME", "-" }, {"HISTORY", "-" }, {"COMMENT", "-" }, {"*", "+" }}; if (*status > 0) return(*status); nsp = sizeof(spkeys)/sizeof(spkeys[0][0])/2; /* translate and copy the keywords from the input file to the output */ fits_translate_keywords(infptr, outfptr, 1, spkeys, nsp, 0, 0, 0, status); return (*status); } /*--------------------------------------------------------------------------*/ int imcomp_decompress_tile (fitsfile *infptr, int nrow, /* I - row of table to read and uncompress */ int tilelen, /* I - number of pixels in the tile */ int datatype, /* I - datatype to be returned in 'buffer' */ int nullcheck, /* I - 0 for no null checking */ void *nulval, /* I - value to be used for undefined pixels */ void *buffer, /* O - buffer for returned decompressed values */ char *bnullarray, /* O - buffer for returned null flags */ int *anynul, /* O - any null values returned? */ int *status) /* This routine decompresses one tile of the image */ { int *idata = 0; int tiledatatype, pixlen = 0; /* uncompressed integer data */ size_t idatalen, tilebytesize; int ii, tnull; /* value in the data which represents nulls */ unsigned char *cbuf; /* compressed data */ unsigned char charnull = 0; short snull = 0; int blocksize, ntilebins, tilecol = 0; float fnulval=0; float *tempfloat = 0; double *tempdouble = 0; double dnulval=0; double bscale, bzero, actual_bzero, dummy = 0; /* scaling parameters */ long tilesize; /* number of bytes */ int smooth, nx, ny, scale; /* hcompress parameters */ LONGLONG nelemll = 0, offset = 0; if (*status > 0) return(*status); /* **************************************************************** */ /* allocate pointers to array of cached uncompressed tiles, if not already done */ if ((infptr->Fptr)->tilerow == 0) { /* calculate number of column bins of compressed tile */ ntilebins = (((infptr->Fptr)->znaxis[0] - 1) / ((infptr->Fptr)->tilesize[0])) + 1; if ((infptr->Fptr)->znaxis[0] != (infptr->Fptr)->tilesize[0] || (infptr->Fptr)->tilesize[1] != 1 ) { /* don't cache the tile if only single row of the image */ (infptr->Fptr)->tilerow = (int *) calloc (ntilebins, sizeof(int)); (infptr->Fptr)->tiledata = (void**) calloc (ntilebins, sizeof(void*)); (infptr->Fptr)->tilenullarray = (void **) calloc (ntilebins, sizeof(char*)); (infptr->Fptr)->tiledatasize = (long *) calloc (ntilebins, sizeof(long)); (infptr->Fptr)->tiletype = (int *) calloc (ntilebins, sizeof(int)); (infptr->Fptr)->tileanynull = (int *) calloc (ntilebins, sizeof(int)); } } /* **************************************************************** */ /* check if this tile was cached; if so, just copy it out */ if ((infptr->Fptr)->tilerow) { /* calculate the column bin of the compressed tile */ tilecol = (nrow - 1) % ((long)(((infptr->Fptr)->znaxis[0] - 1) / ((infptr->Fptr)->tilesize[0])) + 1); if (nrow == (infptr->Fptr)->tilerow[tilecol] && datatype == (infptr->Fptr)->tiletype[tilecol] ) { memcpy(buffer, ((infptr->Fptr)->tiledata)[tilecol], (infptr->Fptr)->tiledatasize[tilecol]); if (nullcheck == 2) memcpy(bnullarray, (infptr->Fptr)->tilenullarray[tilecol], tilelen); *anynul = (infptr->Fptr)->tileanynull[tilecol]; return(*status); } } /* **************************************************************** */ /* get length of the compressed byte stream */ ffgdesll (infptr, (infptr->Fptr)->cn_compressed, nrow, &nelemll, &offset, status); /* EOF error here indicates that this tile has not yet been written */ if (*status == END_OF_FILE) return(*status = NO_COMPRESSED_TILE); /* **************************************************************** */ if (nelemll == 0) /* special case: tile was not compressed normally */ { if ((infptr->Fptr)->cn_uncompressed >= 1 ) { /* This option of writing the uncompressed floating point data */ /* to the tile compressed file was used until about May 2011. */ /* This was replaced by the more efficient option of gzipping the */ /* floating point data before writing it to the tile-compressed file */ /* no compressed data, so simply read the uncompressed data */ /* directly from the UNCOMPRESSED_DATA column */ ffgdesll (infptr, (infptr->Fptr)->cn_uncompressed, nrow, &nelemll, &offset, status); if (nelemll == 0 && offset == 0) /* this should never happen */ return (*status = NO_COMPRESSED_TILE); if (nullcheck <= 1) { /* set any null values in the array = nulval */ fits_read_col(infptr, datatype, (infptr->Fptr)->cn_uncompressed, nrow, 1, (long) nelemll, nulval, buffer, anynul, status); } else { /* set the bnullarray = 1 for any null values in the array */ fits_read_colnull(infptr, datatype, (infptr->Fptr)->cn_uncompressed, nrow, 1, (long) nelemll, buffer, bnullarray, anynul, status); } } else if ((infptr->Fptr)->cn_gzip_data >= 1) { /* This is the newer option, that was introduced in May 2011 */ /* floating point data was not quantized, so read the losslessly */ /* compressed data from the GZIP_COMPRESSED_DATA column */ ffgdesll (infptr, (infptr->Fptr)->cn_gzip_data, nrow, &nelemll, &offset, status); if (nelemll == 0 && offset == 0) /* this should never happen */ return (*status = NO_COMPRESSED_TILE); /* allocate memory for the compressed tile of data */ cbuf = (unsigned char *) malloc ((long) nelemll); if (cbuf == NULL) { ffpmsg("error allocating memory for gzipped tile (imcomp_decompress_tile)"); return (*status = MEMORY_ALLOCATION); } /* read array of compressed bytes */ if (fits_read_col(infptr, TBYTE, (infptr->Fptr)->cn_gzip_data, nrow, 1, (long) nelemll, &charnull, cbuf, NULL, status) > 0) { ffpmsg("error reading compressed byte stream from binary table"); free (cbuf); return (*status); } /* size of the returned (uncompressed) data buffer, in bytes */ if ((infptr->Fptr)->zbitpix == FLOAT_IMG) { idatalen = tilelen * sizeof(float); } else if ((infptr->Fptr)->zbitpix == DOUBLE_IMG) { idatalen = tilelen * sizeof(double); } else { /* this should never happen! */ ffpmsg("incompatible data type in gzipped floating-point tile-compressed image"); free (cbuf); return (*status = DATA_DECOMPRESSION_ERR); } /* Do not allow image float/doubles into int arrays */ if (datatype != TFLOAT && datatype != TDOUBLE) { ffpmsg("attempting to read compressed float or double image into incompatible data type"); free(cbuf); return (*status = DATA_DECOMPRESSION_ERR); } if (datatype == TFLOAT && (infptr->Fptr)->zbitpix == DOUBLE_IMG) { tempdouble = (double*)malloc(idatalen); if (tempdouble == NULL) { ffpmsg("Memory allocation failure for tempdouble. (imcomp_decompress_tile)"); free (cbuf); return (*status = MEMORY_ALLOCATION); } /* uncompress the data into temp buffer */ if (uncompress2mem_from_mem ((char *)cbuf, (long) nelemll, (char **) &tempdouble, &idatalen, NULL, &tilebytesize, status)) { ffpmsg("failed to gunzip the image tile"); free (tempdouble); free (cbuf); return (*status); } } else if (datatype == TDOUBLE && (infptr->Fptr)->zbitpix == FLOAT_IMG) { /* have to allocat a temporary buffer for the uncompressed data in the */ /* case where a gzipped "float" tile is returned as a "double" array */ tempfloat = (float*) malloc (idatalen); if (tempfloat == NULL) { ffpmsg("Memory allocation failure for tempfloat. (imcomp_decompress_tile)"); free (cbuf); return (*status = MEMORY_ALLOCATION); } /* uncompress the data into temp buffer */ if (uncompress2mem_from_mem ((char *)cbuf, (long) nelemll, (char **) &tempfloat, &idatalen, NULL, &tilebytesize, status)) { ffpmsg("failed to gunzip the image tile"); free (tempfloat); free (cbuf); return (*status); } } else { /* uncompress the data directly into the output buffer in all other cases */ if (uncompress2mem_from_mem ((char *)cbuf, (long) nelemll, (char **) &buffer, &idatalen, NULL, &tilebytesize, status)) { ffpmsg("failed to gunzip the image tile"); free (cbuf); return (*status); } } free(cbuf); /* do byte swapping and null value substitution for the tile of pixels */ if (tilebytesize == 4 * tilelen) { /* float pixels */ #if BYTESWAPPED if (tempfloat) ffswap4((int *) tempfloat, tilelen); else ffswap4((int *) buffer, tilelen); #endif if (datatype == TFLOAT) { if (nulval) { fnulval = *(float *) nulval; } fffr4r4((float *) buffer, (long) tilelen, 1., 0., nullcheck, fnulval, bnullarray, anynul, (float *) buffer, status); } else if (datatype == TDOUBLE) { if (nulval) { dnulval = *(double *) nulval; } /* note that the R*4 data are in the tempfloat array in this case */ fffr4r8((float *) tempfloat, (long) tilelen, 1., 0., nullcheck, dnulval, bnullarray, anynul, (double *) buffer, status); free(tempfloat); } else { ffpmsg("implicit data type conversion is not supported for gzipped image tiles"); return (*status = DATA_DECOMPRESSION_ERR); } } else if (tilebytesize == 8 * tilelen) { /* double pixels */ #if BYTESWAPPED if (tempdouble) ffswap8((double *) tempdouble, tilelen); else ffswap8((double *) buffer, tilelen); #endif if (datatype == TFLOAT) { if (nulval) { fnulval = *(float *) nulval; } fffr8r4((double *) tempdouble, (long) tilelen, 1., 0., nullcheck, fnulval, bnullarray, anynul, (float *) buffer, status); free(tempdouble); tempdouble=0; } else if (datatype == TDOUBLE) { if (nulval) { dnulval = *(double *) nulval; } fffr8r8((double *) buffer, (long) tilelen, 1., 0., nullcheck, dnulval, bnullarray, anynul, (double *) buffer, status); } else { ffpmsg("implicit data type conversion is not supported in tile-compressed images"); return (*status = DATA_DECOMPRESSION_ERR); } } else { ffpmsg("error: uncompressed tile has wrong size"); return (*status = DATA_DECOMPRESSION_ERR); } /* end of special case of losslessly gzipping a floating-point image tile */ } else { /* this should never happen */ *status = NO_COMPRESSED_TILE; } return(*status); } /* **************************************************************** */ /* deal with the normal case of a compressed tile of pixels */ if (nullcheck == 2) { for (ii = 0; ii < tilelen; ii++) /* initialize the null flage array */ bnullarray[ii] = 0; } if (anynul) *anynul = 0; /* get linear scaling and offset values, if they exist */ actual_bzero = (infptr->Fptr)->cn_actual_bzero; if ((infptr->Fptr)->cn_zscale == 0) { /* set default scaling, if scaling is not defined */ bscale = 1.; bzero = 0.; } else if ((infptr->Fptr)->cn_zscale == -1) { bscale = (infptr->Fptr)->zscale; bzero = (infptr->Fptr)->zzero; } else { /* read the linear scale and offset values for this row */ ffgcvd (infptr, (infptr->Fptr)->cn_zscale, nrow, 1, 1, 0., &bscale, NULL, status); ffgcvd (infptr, (infptr->Fptr)->cn_zzero, nrow, 1, 1, 0., &bzero, NULL, status); if (*status > 0) { ffpmsg("error reading scaling factor and offset for compressed tile"); return (*status); } /* test if floating-point FITS image also has non-default BSCALE and */ /* BZERO keywords. If so, we have to combine the 2 linear scaling factors. */ if ( ((infptr->Fptr)->zbitpix == FLOAT_IMG || (infptr->Fptr)->zbitpix == DOUBLE_IMG ) && ((infptr->Fptr)->cn_bscale != 1.0 || (infptr->Fptr)->cn_bzero != 0.0 ) ) { bscale = bscale * (infptr->Fptr)->cn_bscale; bzero = bzero * (infptr->Fptr)->cn_bscale + (infptr->Fptr)->cn_bzero; } } if (bscale == 1.0 && bzero == 0.0 ) { /* if no other scaling has been specified, try using the values given by the BSCALE and BZERO keywords, if any */ bscale = (infptr->Fptr)->cn_bscale; bzero = (infptr->Fptr)->cn_bzero; } /* ************************************************************* */ /* get the value used to represent nulls in the int array */ if ((infptr->Fptr)->cn_zblank == 0) { nullcheck = 0; /* no null value; don't check for nulls */ } else if ((infptr->Fptr)->cn_zblank == -1) { tnull = (infptr->Fptr)->zblank; /* use the the ZBLANK keyword */ } else { /* read the null value for this row */ ffgcvk (infptr, (infptr->Fptr)->cn_zblank, nrow, 1, 1, 0, &tnull, NULL, status); if (*status > 0) { ffpmsg("error reading null value for compressed tile"); return (*status); } } /* ************************************************************* */ /* allocate memory for the uncompressed array of tile integers */ /* The size depends on the datatype and the compression type. */ if ((infptr->Fptr)->compress_type == HCOMPRESS_1 && ((infptr->Fptr)->zbitpix != BYTE_IMG && (infptr->Fptr)->zbitpix != SHORT_IMG) ) { idatalen = tilelen * sizeof(LONGLONG); /* 8 bytes per pixel */ } else if ( (infptr->Fptr)->compress_type == RICE_1 && (infptr->Fptr)->zbitpix == BYTE_IMG && (infptr->Fptr)->rice_bytepix == 1) { idatalen = tilelen * sizeof(char); /* 1 byte per pixel */ } else if ( ( (infptr->Fptr)->compress_type == GZIP_1 || (infptr->Fptr)->compress_type == GZIP_2 || (infptr->Fptr)->compress_type == BZIP2_1 ) && (infptr->Fptr)->zbitpix == BYTE_IMG ) { idatalen = tilelen * sizeof(char); /* 1 byte per pixel */ } else if ( (infptr->Fptr)->compress_type == RICE_1 && (infptr->Fptr)->zbitpix == SHORT_IMG && (infptr->Fptr)->rice_bytepix == 2) { idatalen = tilelen * sizeof(short); /* 2 bytes per pixel */ } else if ( ( (infptr->Fptr)->compress_type == GZIP_1 || (infptr->Fptr)->compress_type == GZIP_2 || (infptr->Fptr)->compress_type == BZIP2_1 ) && (infptr->Fptr)->zbitpix == SHORT_IMG ) { idatalen = tilelen * sizeof(short); /* 2 bytes per pixel */ } else if ( ( (infptr->Fptr)->compress_type == GZIP_1 || (infptr->Fptr)->compress_type == GZIP_2 || (infptr->Fptr)->compress_type == BZIP2_1 ) && (infptr->Fptr)->zbitpix == DOUBLE_IMG ) { idatalen = tilelen * sizeof(double); /* 8 bytes per pixel */ } else { idatalen = tilelen * sizeof(int); /* all other cases have int pixels */ } idata = (int*) malloc (idatalen); if (idata == NULL) { ffpmsg("Memory allocation failure for idata. (imcomp_decompress_tile)"); return (*status = MEMORY_ALLOCATION); } /* ************************************************************* */ /* allocate memory for the compressed bytes */ if ((infptr->Fptr)->compress_type == PLIO_1) { cbuf = (unsigned char *) malloc ((long) nelemll * sizeof (short)); } else { cbuf = (unsigned char *) malloc ((long) nelemll); } if (cbuf == NULL) { ffpmsg("Out of memory for cbuf. (imcomp_decompress_tile)"); free(idata); return (*status = MEMORY_ALLOCATION); } /* ************************************************************* */ /* read the compressed bytes from the FITS file */ if ((infptr->Fptr)->compress_type == PLIO_1) { fits_read_col(infptr, TSHORT, (infptr->Fptr)->cn_compressed, nrow, 1, (long) nelemll, &snull, (short *) cbuf, NULL, status); } else { fits_read_col(infptr, TBYTE, (infptr->Fptr)->cn_compressed, nrow, 1, (long) nelemll, &charnull, cbuf, NULL, status); } if (*status > 0) { ffpmsg("error reading compressed byte stream from binary table"); free (cbuf); free(idata); return (*status); } /* ************************************************************* */ /* call the algorithm-specific code to uncompress the tile */ if ((infptr->Fptr)->compress_type == RICE_1) { blocksize = (infptr->Fptr)->rice_blocksize; if ((infptr->Fptr)->rice_bytepix == 1 ) { *status = fits_rdecomp_byte (cbuf, (long) nelemll, (unsigned char *)idata, tilelen, blocksize); tiledatatype = TBYTE; } else if ((infptr->Fptr)->rice_bytepix == 2 ) { *status = fits_rdecomp_short (cbuf, (long) nelemll, (unsigned short *)idata, tilelen, blocksize); tiledatatype = TSHORT; } else { *status = fits_rdecomp (cbuf, (long) nelemll, (unsigned int *)idata, tilelen, blocksize); tiledatatype = TINT; } /* ************************************************************* */ } else if ((infptr->Fptr)->compress_type == HCOMPRESS_1) { smooth = (infptr->Fptr)->hcomp_smooth; if ( ((infptr->Fptr)->zbitpix == BYTE_IMG || (infptr->Fptr)->zbitpix == SHORT_IMG)) { *status = fits_hdecompress(cbuf, smooth, idata, &nx, &ny, &scale, status); } else { /* zbitpix = LONG_IMG (32) */ /* idata must have been allocated twice as large for this to work */ *status = fits_hdecompress64(cbuf, smooth, (LONGLONG *) idata, &nx, &ny, &scale, status); } tiledatatype = TINT; /* ************************************************************* */ } else if ((infptr->Fptr)->compress_type == PLIO_1) { pl_l2pi ((short *) cbuf, 1, idata, tilelen); /* uncompress the data */ tiledatatype = TINT; /* ************************************************************* */ } else if ( ((infptr->Fptr)->compress_type == GZIP_1) || ((infptr->Fptr)->compress_type == GZIP_2) ) { uncompress2mem_from_mem ((char *)cbuf, (long) nelemll, (char **) &idata, &idatalen, realloc, &tilebytesize, status); /* determine the data type of the uncompressed array, and */ /* do byte unshuffling and unswapping if needed */ if (tilebytesize == (size_t) (tilelen * 2)) { /* this is a short I*2 array */ tiledatatype = TSHORT; if ( (infptr->Fptr)->compress_type == GZIP_2 ) fits_unshuffle_2bytes((char *) idata, tilelen, status); #if BYTESWAPPED ffswap2((short *) idata, tilelen); #endif } else if (tilebytesize == (size_t) (tilelen * 4)) { /* this is a int I*4 array (or maybe R*4) */ tiledatatype = TINT; if ( (infptr->Fptr)->compress_type == GZIP_2 ) fits_unshuffle_4bytes((char *) idata, tilelen, status); #if BYTESWAPPED ffswap4(idata, tilelen); #endif } else if (tilebytesize == (size_t) (tilelen * 8)) { /* this is a R*8 double array */ tiledatatype = TDOUBLE; if ( (infptr->Fptr)->compress_type == GZIP_2 ) fits_unshuffle_8bytes((char *) idata, tilelen, status); #if BYTESWAPPED ffswap8((double *) idata, tilelen); #endif } else if (tilebytesize == (size_t) tilelen) { /* this is an unsigned char I*1 array */ tiledatatype = TBYTE; } else { ffpmsg("error: uncompressed tile has wrong size"); free(idata); return (*status = DATA_DECOMPRESSION_ERR); } /* ************************************************************* */ } else if ((infptr->Fptr)->compress_type == BZIP2_1) { /* BZIP2 is not supported in the public release; this is only for test purposes if (BZ2_bzBuffToBuffDecompress ((char *) idata, &idatalen, (char *)cbuf, (unsigned int) nelemll, 0, 0) ) */ { ffpmsg("bzip2 decompression error"); free(idata); free (cbuf); return (*status = DATA_DECOMPRESSION_ERR); } if ((infptr->Fptr)->zbitpix == BYTE_IMG) { tiledatatype = TBYTE; } else if ((infptr->Fptr)->zbitpix == SHORT_IMG) { tiledatatype = TSHORT; #if BYTESWAPPED ffswap2((short *) idata, tilelen); #endif } else { tiledatatype = TINT; #if BYTESWAPPED ffswap4(idata, tilelen); #endif } /* ************************************************************* */ } else { ffpmsg("unknown compression algorithm"); free(idata); return (*status = DATA_DECOMPRESSION_ERR); } free(cbuf); if (*status) { /* error uncompressing the tile */ free(idata); return (*status); } /* ************************************************************* */ /* copy the uncompressed tile data to the output buffer, doing */ /* null checking, datatype conversion and linear scaling, if necessary */ if (nulval == 0) nulval = &dummy; /* set address to dummy value */ if (datatype == TSHORT) { pixlen = sizeof(short); if ((infptr->Fptr)->quantize_level == NO_QUANTIZE) { /* the floating point pixels were losselessly compressed with GZIP */ /* Just have to copy the values to the output array */ if (tiledatatype == TINT) { fffr4i2((float *) idata, tilelen, bscale, bzero, nullcheck, *(short *) nulval, bnullarray, anynul, (short *) buffer, status); } else { fffr8i2((double *) idata, tilelen, bscale, bzero, nullcheck, *(short *) nulval, bnullarray, anynul, (short *) buffer, status); } } else if (tiledatatype == TINT) { if ((infptr->Fptr)->compress_type == PLIO_1 && actual_bzero == 32768.) { /* special case where unsigned 16-bit integers have been */ /* offset by +32768 when using PLIO */ fffi4i2(idata, tilelen, bscale, bzero - 32768., nullcheck, tnull, *(short *) nulval, bnullarray, anynul, (short *) buffer, status); } else { fffi4i2(idata, tilelen, bscale, bzero, nullcheck, tnull, *(short *) nulval, bnullarray, anynul, (short *) buffer, status); /* Hcompress is a special case: ignore any numerical overflow errors that may have occurred during the integer*4 to integer*2 convertion. Overflows can happen when a lossy Hcompress algorithm is invoked (with a non-zero scale factor). The fffi4i2 routine clips the returned values to be within the legal I*2 range, so all we need to is to reset the error status to zero. */ if ((infptr->Fptr)->compress_type == HCOMPRESS_1) { if ((*status == NUM_OVERFLOW) || (*status == OVERFLOW_ERR)) *status = 0; } } } else if (tiledatatype == TSHORT) { fffi2i2((short *)idata, tilelen, bscale, bzero, nullcheck, (short) tnull, *(short *) nulval, bnullarray, anynul, (short *) buffer, status); } else if (tiledatatype == TBYTE) { fffi1i2((unsigned char *)idata, tilelen, bscale, bzero, nullcheck, (unsigned char) tnull, *(short *) nulval, bnullarray, anynul, (short *) buffer, status); } } else if (datatype == TINT) { pixlen = sizeof(int); if ((infptr->Fptr)->quantize_level == NO_QUANTIZE) { /* the floating point pixels were losselessly compressed with GZIP */ /* Just have to copy the values to the output array */ if (tiledatatype == TINT) { fffr4int((float *) idata, tilelen, bscale, bzero, nullcheck, *(int *) nulval, bnullarray, anynul, (int *) buffer, status); } else { fffr8int((double *) idata, tilelen, bscale, bzero, nullcheck, *(int *) nulval, bnullarray, anynul, (int *) buffer, status); } } else if (tiledatatype == TINT) if ((infptr->Fptr)->compress_type == PLIO_1 && actual_bzero == 32768.) { /* special case where unsigned 16-bit integers have been */ /* offset by +32768 when using PLIO */ fffi4int(idata, (long) tilelen, bscale, bzero - 32768., nullcheck, tnull, *(int *) nulval, bnullarray, anynul, (int *) buffer, status); } else { fffi4int(idata, (long) tilelen, bscale, bzero, nullcheck, tnull, *(int *) nulval, bnullarray, anynul, (int *) buffer, status); } else if (tiledatatype == TSHORT) fffi2int((short *)idata, tilelen, bscale, bzero, nullcheck, (short) tnull, *(int *) nulval, bnullarray, anynul, (int *) buffer, status); else if (tiledatatype == TBYTE) fffi1int((unsigned char *)idata, tilelen, bscale, bzero, nullcheck, (unsigned char) tnull, *(int *) nulval, bnullarray, anynul, (int *) buffer, status); } else if (datatype == TLONG) { pixlen = sizeof(long); if ((infptr->Fptr)->quantize_level == NO_QUANTIZE) { /* the floating point pixels were losselessly compressed with GZIP */ /* Just have to copy the values to the output array */ if (tiledatatype == TINT) { fffr4i4((float *) idata, tilelen, bscale, bzero, nullcheck, *(long *) nulval, bnullarray, anynul, (long *) buffer, status); } else { fffr8i4((double *) idata, tilelen, bscale, bzero, nullcheck, *(long *) nulval, bnullarray, anynul, (long *) buffer, status); } } else if (tiledatatype == TINT) if ((infptr->Fptr)->compress_type == PLIO_1 && actual_bzero == 32768.) { /* special case where unsigned 16-bit integers have been */ /* offset by +32768 when using PLIO */ fffi4i4(idata, tilelen, bscale, bzero - 32768., nullcheck, tnull, *(long *) nulval, bnullarray, anynul, (long *) buffer, status); } else { fffi4i4(idata, tilelen, bscale, bzero, nullcheck, tnull, *(long *) nulval, bnullarray, anynul, (long *) buffer, status); } else if (tiledatatype == TSHORT) fffi2i4((short *)idata, tilelen, bscale, bzero, nullcheck, (short) tnull, *(long *) nulval, bnullarray, anynul, (long *) buffer, status); else if (tiledatatype == TBYTE) fffi1i4((unsigned char *)idata, tilelen, bscale, bzero, nullcheck, (unsigned char) tnull, *(long *) nulval, bnullarray, anynul, (long *) buffer, status); } else if (datatype == TFLOAT) { pixlen = sizeof(float); if (nulval) { fnulval = *(float *) nulval; } if ((infptr->Fptr)->quantize_level == NO_QUANTIZE) { /* the floating point pixels were losselessly compressed with GZIP */ /* Just have to copy the values to the output array */ if (tiledatatype == TINT) { fffr4r4((float *) idata, tilelen, bscale, bzero, nullcheck, fnulval, bnullarray, anynul, (float *) buffer, status); } else { fffr8r4((double *) idata, tilelen, bscale, bzero, nullcheck, fnulval, bnullarray, anynul, (float *) buffer, status); } } else if ((infptr->Fptr)->quantize_method == SUBTRACTIVE_DITHER_1 || (infptr->Fptr)->quantize_method == SUBTRACTIVE_DITHER_2) { /* use the new dithering algorithm (introduced in July 2009) */ if (tiledatatype == TINT) unquantize_i4r4(nrow + (infptr->Fptr)->dither_seed - 1, idata, tilelen, bscale, bzero, (infptr->Fptr)->quantize_method, nullcheck, tnull, fnulval, bnullarray, anynul, (float *) buffer, status); else if (tiledatatype == TSHORT) unquantize_i2r4(nrow + (infptr->Fptr)->dither_seed - 1, (short *)idata, tilelen, bscale, bzero, (infptr->Fptr)->quantize_method, nullcheck, (short) tnull, fnulval, bnullarray, anynul, (float *) buffer, status); else if (tiledatatype == TBYTE) unquantize_i1r4(nrow + (infptr->Fptr)->dither_seed - 1, (unsigned char *)idata, tilelen, bscale, bzero, (infptr->Fptr)->quantize_method, nullcheck, (unsigned char) tnull, fnulval, bnullarray, anynul, (float *) buffer, status); } else { /* use the old "round to nearest level" quantization algorithm */ if (tiledatatype == TINT) if ((infptr->Fptr)->compress_type == PLIO_1 && actual_bzero == 32768.) { /* special case where unsigned 16-bit integers have been */ /* offset by +32768 when using PLIO */ fffi4r4(idata, tilelen, bscale, bzero - 32768., nullcheck, tnull, fnulval, bnullarray, anynul, (float *) buffer, status); } else { fffi4r4(idata, tilelen, bscale, bzero, nullcheck, tnull, fnulval, bnullarray, anynul, (float *) buffer, status); } else if (tiledatatype == TSHORT) fffi2r4((short *)idata, tilelen, bscale, bzero, nullcheck, (short) tnull, fnulval, bnullarray, anynul, (float *) buffer, status); else if (tiledatatype == TBYTE) fffi1r4((unsigned char *)idata, tilelen, bscale, bzero, nullcheck, (unsigned char) tnull, fnulval, bnullarray, anynul, (float *) buffer, status); } } else if (datatype == TDOUBLE) { pixlen = sizeof(double); if (nulval) { dnulval = *(double *) nulval; } if ((infptr->Fptr)->quantize_level == NO_QUANTIZE) { /* the floating point pixels were losselessly compressed with GZIP */ /* Just have to copy the values to the output array */ if (tiledatatype == TINT) { fffr4r8((float *) idata, tilelen, bscale, bzero, nullcheck, dnulval, bnullarray, anynul, (double *) buffer, status); } else { fffr8r8((double *) idata, tilelen, bscale, bzero, nullcheck, dnulval, bnullarray, anynul, (double *) buffer, status); } } else if ((infptr->Fptr)->quantize_method == SUBTRACTIVE_DITHER_1 || (infptr->Fptr)->quantize_method == SUBTRACTIVE_DITHER_2) { /* use the new dithering algorithm (introduced in July 2009) */ if (tiledatatype == TINT) unquantize_i4r8(nrow + (infptr->Fptr)->dither_seed - 1, idata, tilelen, bscale, bzero, (infptr->Fptr)->quantize_method, nullcheck, tnull, dnulval, bnullarray, anynul, (double *) buffer, status); else if (tiledatatype == TSHORT) unquantize_i2r8(nrow + (infptr->Fptr)->dither_seed - 1, (short *)idata, tilelen, bscale, bzero, (infptr->Fptr)->quantize_method, nullcheck, (short) tnull, dnulval, bnullarray, anynul, (double *) buffer, status); else if (tiledatatype == TBYTE) unquantize_i1r8(nrow + (infptr->Fptr)->dither_seed - 1, (unsigned char *)idata, tilelen, bscale, bzero, (infptr->Fptr)->quantize_method, nullcheck, (unsigned char) tnull, dnulval, bnullarray, anynul, (double *) buffer, status); } else { /* use the old "round to nearest level" quantization algorithm */ if (tiledatatype == TINT) { if ((infptr->Fptr)->compress_type == PLIO_1 && actual_bzero == 32768.) { /* special case where unsigned 16-bit integers have been */ /* offset by +32768 when using PLIO */ fffi4r8(idata, tilelen, bscale, bzero - 32768., nullcheck, tnull, dnulval, bnullarray, anynul, (double *) buffer, status); } else { fffi4r8(idata, tilelen, bscale, bzero, nullcheck, tnull, dnulval, bnullarray, anynul, (double *) buffer, status); } } else if (tiledatatype == TSHORT) { fffi2r8((short *)idata, tilelen, bscale, bzero, nullcheck, (short) tnull, dnulval, bnullarray, anynul, (double *) buffer, status); } else if (tiledatatype == TBYTE) fffi1r8((unsigned char *)idata, tilelen, bscale, bzero, nullcheck, (unsigned char) tnull, dnulval, bnullarray, anynul, (double *) buffer, status); } } else if (datatype == TBYTE) { pixlen = sizeof(char); if (tiledatatype == TINT) fffi4i1(idata, tilelen, bscale, bzero, nullcheck, tnull, *(unsigned char *) nulval, bnullarray, anynul, (unsigned char *) buffer, status); else if (tiledatatype == TSHORT) fffi2i1((short *)idata, tilelen, bscale, bzero, nullcheck, (short) tnull, *(unsigned char *) nulval, bnullarray, anynul, (unsigned char *) buffer, status); else if (tiledatatype == TBYTE) fffi1i1((unsigned char *)idata, tilelen, bscale, bzero, nullcheck, (unsigned char) tnull, *(unsigned char *) nulval, bnullarray, anynul, (unsigned char *) buffer, status); } else if (datatype == TSBYTE) { pixlen = sizeof(char); if (tiledatatype == TINT) fffi4s1(idata, tilelen, bscale, bzero, nullcheck, tnull, *(signed char *) nulval, bnullarray, anynul, (signed char *) buffer, status); else if (tiledatatype == TSHORT) fffi2s1((short *)idata, tilelen, bscale, bzero, nullcheck, (short) tnull, *(signed char *) nulval, bnullarray, anynul, (signed char *) buffer, status); else if (tiledatatype == TBYTE) fffi1s1((unsigned char *)idata, tilelen, bscale, bzero, nullcheck, (unsigned char) tnull, *(signed char *) nulval, bnullarray, anynul, (signed char *) buffer, status); } else if (datatype == TUSHORT) { pixlen = sizeof(short); if ((infptr->Fptr)->quantize_level == NO_QUANTIZE) { /* the floating point pixels were losselessly compressed with GZIP */ /* Just have to copy the values to the output array */ if (tiledatatype == TINT) { fffr4u2((float *) idata, tilelen, bscale, bzero, nullcheck, *(unsigned short *) nulval, bnullarray, anynul, (unsigned short *) buffer, status); } else { fffr8u2((double *) idata, tilelen, bscale, bzero, nullcheck, *(unsigned short *) nulval, bnullarray, anynul, (unsigned short *) buffer, status); } } else if (tiledatatype == TINT) if ((infptr->Fptr)->compress_type == PLIO_1 && actual_bzero == 32768.) { /* special case where unsigned 16-bit integers have been */ /* offset by +32768 when using PLIO */ fffi4u2(idata, tilelen, bscale, bzero - 32768., nullcheck, tnull, *(unsigned short *) nulval, bnullarray, anynul, (unsigned short *) buffer, status); } else { fffi4u2(idata, tilelen, bscale, bzero, nullcheck, tnull, *(unsigned short *) nulval, bnullarray, anynul, (unsigned short *) buffer, status); } else if (tiledatatype == TSHORT) fffi2u2((short *)idata, tilelen, bscale, bzero, nullcheck, (short) tnull, *(unsigned short *) nulval, bnullarray, anynul, (unsigned short *) buffer, status); else if (tiledatatype == TBYTE) fffi1u2((unsigned char *)idata, tilelen, bscale, bzero, nullcheck, (unsigned char) tnull, *(unsigned short *) nulval, bnullarray, anynul, (unsigned short *) buffer, status); } else if (datatype == TUINT) { pixlen = sizeof(int); if ((infptr->Fptr)->quantize_level == NO_QUANTIZE) { /* the floating point pixels were losselessly compressed with GZIP */ /* Just have to copy the values to the output array */ if (tiledatatype == TINT) { fffr4uint((float *) idata, tilelen, bscale, bzero, nullcheck, *(unsigned int *) nulval, bnullarray, anynul, (unsigned int *) buffer, status); } else { fffr8uint((double *) idata, tilelen, bscale, bzero, nullcheck, *(unsigned int *) nulval, bnullarray, anynul, (unsigned int *) buffer, status); } } else if (tiledatatype == TINT) if ((infptr->Fptr)->compress_type == PLIO_1 && actual_bzero == 32768.) { /* special case where unsigned 16-bit integers have been */ /* offset by +32768 when using PLIO */ fffi4uint(idata, tilelen, bscale, bzero - 32768., nullcheck, tnull, *(unsigned int *) nulval, bnullarray, anynul, (unsigned int *) buffer, status); } else { fffi4uint(idata, tilelen, bscale, bzero, nullcheck, tnull, *(unsigned int *) nulval, bnullarray, anynul, (unsigned int *) buffer, status); } else if (tiledatatype == TSHORT) fffi2uint((short *)idata, tilelen, bscale, bzero, nullcheck, (short) tnull, *(unsigned int *) nulval, bnullarray, anynul, (unsigned int *) buffer, status); else if (tiledatatype == TBYTE) fffi1uint((unsigned char *)idata, tilelen, bscale, bzero, nullcheck, (unsigned char) tnull, *(unsigned int *) nulval, bnullarray, anynul, (unsigned int *) buffer, status); } else if (datatype == TULONG) { pixlen = sizeof(long); if ((infptr->Fptr)->quantize_level == NO_QUANTIZE) { /* the floating point pixels were losselessly compressed with GZIP */ /* Just have to copy the values to the output array */ if (tiledatatype == TINT) { fffr4u4((float *) idata, tilelen, bscale, bzero, nullcheck, *(unsigned long *) nulval, bnullarray, anynul, (unsigned long *) buffer, status); } else { fffr8u4((double *) idata, tilelen, bscale, bzero, nullcheck, *(unsigned long *) nulval, bnullarray, anynul, (unsigned long *) buffer, status); } } else if (tiledatatype == TINT) if ((infptr->Fptr)->compress_type == PLIO_1 && actual_bzero == 32768.) { /* special case where unsigned 16-bit integers have been */ /* offset by +32768 when using PLIO */ fffi4u4(idata, tilelen, bscale, bzero - 32768., nullcheck, tnull, *(unsigned long *) nulval, bnullarray, anynul, (unsigned long *) buffer, status); } else { fffi4u4(idata, tilelen, bscale, bzero, nullcheck, tnull, *(unsigned long *) nulval, bnullarray, anynul, (unsigned long *) buffer, status); } else if (tiledatatype == TSHORT) fffi2u4((short *)idata, tilelen, bscale, bzero, nullcheck, (short) tnull, *(unsigned long *) nulval, bnullarray, anynul, (unsigned long *) buffer, status); else if (tiledatatype == TBYTE) fffi1u4((unsigned char *)idata, tilelen, bscale, bzero, nullcheck, (unsigned char) tnull, *(unsigned long *) nulval, bnullarray, anynul, (unsigned long *) buffer, status); } else *status = BAD_DATATYPE; free(idata); /* don't need the uncompressed tile any more */ /* **************************************************************** */ /* cache the tile, in case the application wants it again */ /* Don't cache the tile if tile is a single row of the image; it is less likely that the cache will be used in this cases, so it is not worth the time and the memory overheads. */ if ((infptr->Fptr)->tilerow) { /* make sure cache has been allocated */ if ((infptr->Fptr)->znaxis[0] != (infptr->Fptr)->tilesize[0] || (infptr->Fptr)->tilesize[1] != 1 ) { tilesize = pixlen * tilelen; /* check that tile size/type has not changed */ if (tilesize != (infptr->Fptr)->tiledatasize[tilecol] || datatype != (infptr->Fptr)->tiletype[tilecol] ) { if (((infptr->Fptr)->tiledata)[tilecol]) { free(((infptr->Fptr)->tiledata)[tilecol]); } if (((infptr->Fptr)->tilenullarray)[tilecol]) { free(((infptr->Fptr)->tilenullarray)[tilecol]); } ((infptr->Fptr)->tilenullarray)[tilecol] = 0; ((infptr->Fptr)->tilerow)[tilecol] = 0; ((infptr->Fptr)->tiledatasize)[tilecol] = 0; ((infptr->Fptr)->tiletype)[tilecol] = 0; /* allocate new array(s) */ ((infptr->Fptr)->tiledata)[tilecol] = malloc(tilesize); if (((infptr->Fptr)->tiledata)[tilecol] == 0) return (*status); if (nullcheck == 2) { /* also need array of null pixel flags */ (infptr->Fptr)->tilenullarray[tilecol] = malloc(tilelen); if ((infptr->Fptr)->tilenullarray[tilecol] == 0) return (*status); } (infptr->Fptr)->tiledatasize[tilecol] = tilesize; (infptr->Fptr)->tiletype[tilecol] = datatype; } /* copy the tile array(s) into cache buffer */ memcpy((infptr->Fptr)->tiledata[tilecol], buffer, tilesize); if (nullcheck == 2) { if ((infptr->Fptr)->tilenullarray == 0) { (infptr->Fptr)->tilenullarray[tilecol] = malloc(tilelen); } memcpy((infptr->Fptr)->tilenullarray[tilecol], bnullarray, tilelen); } (infptr->Fptr)->tilerow[tilecol] = nrow; (infptr->Fptr)->tileanynull[tilecol] = *anynul; } } return (*status); } /*--------------------------------------------------------------------------*/ int imcomp_test_overlap ( int ndim, /* I - number of dimension in the tile and image */ long *tfpixel, /* I - first pixel number in each dim. of the tile */ long *tlpixel, /* I - last pixel number in each dim. of the tile */ long *fpixel, /* I - first pixel number in each dim. of the image */ long *lpixel, /* I - last pixel number in each dim. of the image */ long *ininc, /* I - increment to be applied in each image dimen. */ int *status) /* test if there are any intersecting pixels between this tile and the section of the image defined by fixel, lpixel, ininc. */ { long imgdim[MAX_COMPRESS_DIM]; /* product of preceding dimensions in the */ /* output image, allowing for inc factor */ long tiledim[MAX_COMPRESS_DIM]; /* product of preceding dimensions in the */ /* tile, array; inc factor is not relevant */ long imgfpix[MAX_COMPRESS_DIM]; /* 1st img pix overlapping tile: 0 base, */ /* allowing for inc factor */ long imglpix[MAX_COMPRESS_DIM]; /* last img pix overlapping tile 0 base, */ /* allowing for inc factor */ long tilefpix[MAX_COMPRESS_DIM]; /* 1st tile pix overlapping img 0 base, */ /* allowing for inc factor */ long inc[MAX_COMPRESS_DIM]; /* local copy of input ininc */ int ii; long tf, tl; if (*status > 0) return(*status); /* ------------------------------------------------------------ */ /* calc amount of overlap in each dimension; if there is zero */ /* overlap in any dimension then just return */ /* ------------------------------------------------------------ */ for (ii = 0; ii < ndim; ii++) { if (tlpixel[ii] < fpixel[ii] || tfpixel[ii] > lpixel[ii]) return(0); /* there are no overlapping pixels */ inc[ii] = ininc[ii]; /* calc dimensions of the output image section */ imgdim[ii] = (lpixel[ii] - fpixel[ii]) / labs(inc[ii]) + 1; if (imgdim[ii] < 1) { *status = NEG_AXIS; return(0); } /* calc dimensions of the tile */ tiledim[ii] = tlpixel[ii] - tfpixel[ii] + 1; if (tiledim[ii] < 1) { *status = NEG_AXIS; return(0); } if (ii > 0) tiledim[ii] *= tiledim[ii - 1]; /* product of dimensions */ /* first and last pixels in image that overlap with the tile, 0 base */ tf = tfpixel[ii] - 1; tl = tlpixel[ii] - 1; /* skip this plane if it falls in the cracks of the subsampled image */ while ((tf-(fpixel[ii] - 1)) % labs(inc[ii])) { tf++; if (tf > tl) return(0); /* no overlapping pixels */ } while ((tl-(fpixel[ii] - 1)) % labs(inc[ii])) { tl--; if (tf > tl) return(0); /* no overlapping pixels */ } imgfpix[ii] = maxvalue((tf - fpixel[ii] +1) / labs(inc[ii]) , 0); imglpix[ii] = minvalue((tl - fpixel[ii] +1) / labs(inc[ii]) , imgdim[ii] - 1); /* first pixel in the tile that overlaps with the image (0 base) */ tilefpix[ii] = maxvalue(fpixel[ii] - tfpixel[ii], 0); while ((tfpixel[ii] + tilefpix[ii] - fpixel[ii]) % labs(inc[ii])) { (tilefpix[ii])++; if (tilefpix[ii] >= tiledim[ii]) return(0); /* no overlapping pixels */ } if (ii > 0) imgdim[ii] *= imgdim[ii - 1]; /* product of dimensions */ } return(1); /* there appears to be intersecting pixels */ } /*--------------------------------------------------------------------------*/ int imcomp_copy_overlap ( char *tile, /* I - multi dimensional array of tile pixels */ int pixlen, /* I - number of bytes in each tile or image pixel */ int ndim, /* I - number of dimension in the tile and image */ long *tfpixel, /* I - first pixel number in each dim. of the tile */ long *tlpixel, /* I - last pixel number in each dim. of the tile */ char *bnullarray, /* I - array of null flags; used if nullcheck = 2 */ char *image, /* O - multi dimensional output image */ long *fpixel, /* I - first pixel number in each dim. of the image */ long *lpixel, /* I - last pixel number in each dim. of the image */ long *ininc, /* I - increment to be applied in each image dimen. */ int nullcheck, /* I - 0, 1: do nothing; 2: set nullarray for nulls */ char *nullarray, int *status) /* copy the intersecting pixels from a decompressed tile to the output image. Both the tile and the image must have the same number of dimensions. */ { long imgdim[MAX_COMPRESS_DIM]; /* product of preceding dimensions in the */ /* output image, allowing for inc factor */ long tiledim[MAX_COMPRESS_DIM]; /* product of preceding dimensions in the */ /* tile, array; inc factor is not relevant */ long imgfpix[MAX_COMPRESS_DIM]; /* 1st img pix overlapping tile: 0 base, */ /* allowing for inc factor */ long imglpix[MAX_COMPRESS_DIM]; /* last img pix overlapping tile 0 base, */ /* allowing for inc factor */ long tilefpix[MAX_COMPRESS_DIM]; /* 1st tile pix overlapping img 0 base, */ /* allowing for inc factor */ long inc[MAX_COMPRESS_DIM]; /* local copy of input ininc */ long i1, i2, i3, i4; /* offset along each axis of the image */ long it1, it2, it3, it4; long im1, im2, im3, im4; /* offset to image pixel, allowing for inc */ long ipos, tf, tl; long t2, t3, t4; /* offset along each axis of the tile */ long tilepix, imgpix, tilepixbyte, imgpixbyte; int ii, overlap_bytes, overlap_flags; if (*status > 0) return(*status); for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { /* set default values for higher dimensions */ inc[ii] = 1; imgdim[ii] = 1; tiledim[ii] = 1; imgfpix[ii] = 0; imglpix[ii] = 0; tilefpix[ii] = 0; } /* ------------------------------------------------------------ */ /* calc amount of overlap in each dimension; if there is zero */ /* overlap in any dimension then just return */ /* ------------------------------------------------------------ */ for (ii = 0; ii < ndim; ii++) { if (tlpixel[ii] < fpixel[ii] || tfpixel[ii] > lpixel[ii]) return(*status); /* there are no overlapping pixels */ inc[ii] = ininc[ii]; /* calc dimensions of the output image section */ imgdim[ii] = (lpixel[ii] - fpixel[ii]) / labs(inc[ii]) + 1; if (imgdim[ii] < 1) return(*status = NEG_AXIS); /* calc dimensions of the tile */ tiledim[ii] = tlpixel[ii] - tfpixel[ii] + 1; if (tiledim[ii] < 1) return(*status = NEG_AXIS); if (ii > 0) tiledim[ii] *= tiledim[ii - 1]; /* product of dimensions */ /* first and last pixels in image that overlap with the tile, 0 base */ tf = tfpixel[ii] - 1; tl = tlpixel[ii] - 1; /* skip this plane if it falls in the cracks of the subsampled image */ while ((tf-(fpixel[ii] - 1)) % labs(inc[ii])) { tf++; if (tf > tl) return(*status); /* no overlapping pixels */ } while ((tl-(fpixel[ii] - 1)) % labs(inc[ii])) { tl--; if (tf > tl) return(*status); /* no overlapping pixels */ } imgfpix[ii] = maxvalue((tf - fpixel[ii] +1) / labs(inc[ii]) , 0); imglpix[ii] = minvalue((tl - fpixel[ii] +1) / labs(inc[ii]) , imgdim[ii] - 1); /* first pixel in the tile that overlaps with the image (0 base) */ tilefpix[ii] = maxvalue(fpixel[ii] - tfpixel[ii], 0); while ((tfpixel[ii] + tilefpix[ii] - fpixel[ii]) % labs(inc[ii])) { (tilefpix[ii])++; if (tilefpix[ii] >= tiledim[ii]) return(*status); /* no overlapping pixels */ } /* printf("ii tfpixel, tlpixel %d %d %d \n",ii, tfpixel[ii], tlpixel[ii]); printf("ii, tf, tl, imgfpix,imglpix, tilefpix %d %d %d %d %d %d\n",ii, tf,tl,imgfpix[ii], imglpix[ii],tilefpix[ii]); */ if (ii > 0) imgdim[ii] *= imgdim[ii - 1]; /* product of dimensions */ } /* ---------------------------------------------------------------- */ /* calc number of pixels in each row (first dimension) that overlap */ /* multiply by pixlen to get number of bytes to copy in each loop */ /* ---------------------------------------------------------------- */ if (inc[0] != 1) overlap_flags = 1; /* can only copy 1 pixel at a time */ else overlap_flags = imglpix[0] - imgfpix[0] + 1; /* can copy whole row */ overlap_bytes = overlap_flags * pixlen; /* support up to 5 dimensions for now */ for (i4 = 0, it4=0; i4 <= imglpix[4] - imgfpix[4]; i4++, it4++) { /* increment plane if it falls in the cracks of the subsampled image */ while (ndim > 4 && (tfpixel[4] + tilefpix[4] - fpixel[4] + it4) % labs(inc[4]) != 0) it4++; /* offset to start of hypercube */ if (inc[4] > 0) im4 = (i4 + imgfpix[4]) * imgdim[3]; else im4 = imgdim[4] - (i4 + 1 + imgfpix[4]) * imgdim[3]; t4 = (tilefpix[4] + it4) * tiledim[3]; for (i3 = 0, it3=0; i3 <= imglpix[3] - imgfpix[3]; i3++, it3++) { /* increment plane if it falls in the cracks of the subsampled image */ while (ndim > 3 && (tfpixel[3] + tilefpix[3] - fpixel[3] + it3) % labs(inc[3]) != 0) it3++; /* offset to start of cube */ if (inc[3] > 0) im3 = (i3 + imgfpix[3]) * imgdim[2] + im4; else im3 = imgdim[3] - (i3 + 1 + imgfpix[3]) * imgdim[2] + im4; t3 = (tilefpix[3] + it3) * tiledim[2] + t4; /* loop through planes of the image */ for (i2 = 0, it2=0; i2 <= imglpix[2] - imgfpix[2]; i2++, it2++) { /* incre plane if it falls in the cracks of the subsampled image */ while (ndim > 2 && (tfpixel[2] + tilefpix[2] - fpixel[2] + it2) % labs(inc[2]) != 0) it2++; /* offset to start of plane */ if (inc[2] > 0) im2 = (i2 + imgfpix[2]) * imgdim[1] + im3; else im2 = imgdim[2] - (i2 + 1 + imgfpix[2]) * imgdim[1] + im3; t2 = (tilefpix[2] + it2) * tiledim[1] + t3; /* loop through rows of the image */ for (i1 = 0, it1=0; i1 <= imglpix[1] - imgfpix[1]; i1++, it1++) { /* incre row if it falls in the cracks of the subsampled image */ while (ndim > 1 && (tfpixel[1] + tilefpix[1] - fpixel[1] + it1) % labs(inc[1]) != 0) it1++; /* calc position of first pixel in tile to be copied */ tilepix = tilefpix[0] + (tilefpix[1] + it1) * tiledim[0] + t2; /* offset to start of row */ if (inc[1] > 0) im1 = (i1 + imgfpix[1]) * imgdim[0] + im2; else im1 = imgdim[1] - (i1 + 1 + imgfpix[1]) * imgdim[0] + im2; /* printf("inc = %d %d %d %d\n",inc[0],inc[1],inc[2],inc[3]); printf("im1,im2,im3,im4 = %d %d %d %d\n",im1,im2,im3,im4); */ /* offset to byte within the row */ if (inc[0] > 0) imgpix = imgfpix[0] + im1; else imgpix = imgdim[0] - 1 - imgfpix[0] + im1; /* printf("tilefpix0,1, imgfpix1, it1, inc1, t2= %d %d %d %d %d %d\n", tilefpix[0],tilefpix[1],imgfpix[1],it1,inc[1], t2); printf("i1, it1, tilepix, imgpix %d %d %d %d \n", i1, it1, tilepix, imgpix); */ /* loop over pixels along one row of the image */ for (ipos = imgfpix[0]; ipos <= imglpix[0]; ipos += overlap_flags) { if (nullcheck == 2) { /* copy overlapping null flags from tile to image */ memcpy(nullarray + imgpix, bnullarray + tilepix, overlap_flags); } /* convert from image pixel to byte offset */ tilepixbyte = tilepix * pixlen; imgpixbyte = imgpix * pixlen; /* printf(" tilepix, tilepixbyte, imgpix, imgpixbyte= %d %d %d %d\n", tilepix, tilepixbyte, imgpix, imgpixbyte); */ /* copy overlapping row of pixels from tile to image */ memcpy(image + imgpixbyte, tile + tilepixbyte, overlap_bytes); tilepix += (overlap_flags * labs(inc[0])); if (inc[0] > 0) imgpix += overlap_flags; else imgpix -= overlap_flags; } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int imcomp_merge_overlap ( char *tile, /* O - multi dimensional array of tile pixels */ int pixlen, /* I - number of bytes in each tile or image pixel */ int ndim, /* I - number of dimension in the tile and image */ long *tfpixel, /* I - first pixel number in each dim. of the tile */ long *tlpixel, /* I - last pixel number in each dim. of the tile */ char *bnullarray, /* I - array of null flags; used if nullcheck = 2 */ char *image, /* I - multi dimensional output image */ long *fpixel, /* I - first pixel number in each dim. of the image */ long *lpixel, /* I - last pixel number in each dim. of the image */ int nullcheck, /* I - 0, 1: do nothing; 2: set nullarray for nulls */ int *status) /* Similar to imcomp_copy_overlap, except it copies the overlapping pixels from the 'image' to the 'tile'. */ { long imgdim[MAX_COMPRESS_DIM]; /* product of preceding dimensions in the */ /* output image, allowing for inc factor */ long tiledim[MAX_COMPRESS_DIM]; /* product of preceding dimensions in the */ /* tile, array; inc factor is not relevant */ long imgfpix[MAX_COMPRESS_DIM]; /* 1st img pix overlapping tile: 0 base, */ /* allowing for inc factor */ long imglpix[MAX_COMPRESS_DIM]; /* last img pix overlapping tile 0 base, */ /* allowing for inc factor */ long tilefpix[MAX_COMPRESS_DIM]; /* 1st tile pix overlapping img 0 base, */ /* allowing for inc factor */ long inc[MAX_COMPRESS_DIM]; /* local copy of input ininc */ long i1, i2, i3, i4; /* offset along each axis of the image */ long it1, it2, it3, it4; long im1, im2, im3, im4; /* offset to image pixel, allowing for inc */ long ipos, tf, tl; long t2, t3, t4; /* offset along each axis of the tile */ long tilepix, imgpix, tilepixbyte, imgpixbyte; int ii, overlap_bytes, overlap_flags; if (*status > 0) return(*status); for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { /* set default values for higher dimensions */ inc[ii] = 1; imgdim[ii] = 1; tiledim[ii] = 1; imgfpix[ii] = 0; imglpix[ii] = 0; tilefpix[ii] = 0; } /* ------------------------------------------------------------ */ /* calc amount of overlap in each dimension; if there is zero */ /* overlap in any dimension then just return */ /* ------------------------------------------------------------ */ for (ii = 0; ii < ndim; ii++) { if (tlpixel[ii] < fpixel[ii] || tfpixel[ii] > lpixel[ii]) return(*status); /* there are no overlapping pixels */ /* calc dimensions of the output image section */ imgdim[ii] = (lpixel[ii] - fpixel[ii]) / labs(inc[ii]) + 1; if (imgdim[ii] < 1) return(*status = NEG_AXIS); /* calc dimensions of the tile */ tiledim[ii] = tlpixel[ii] - tfpixel[ii] + 1; if (tiledim[ii] < 1) return(*status = NEG_AXIS); if (ii > 0) tiledim[ii] *= tiledim[ii - 1]; /* product of dimensions */ /* first and last pixels in image that overlap with the tile, 0 base */ tf = tfpixel[ii] - 1; tl = tlpixel[ii] - 1; /* skip this plane if it falls in the cracks of the subsampled image */ while ((tf-(fpixel[ii] - 1)) % labs(inc[ii])) { tf++; if (tf > tl) return(*status); /* no overlapping pixels */ } while ((tl-(fpixel[ii] - 1)) % labs(inc[ii])) { tl--; if (tf > tl) return(*status); /* no overlapping pixels */ } imgfpix[ii] = maxvalue((tf - fpixel[ii] +1) / labs(inc[ii]) , 0); imglpix[ii] = minvalue((tl - fpixel[ii] +1) / labs(inc[ii]) , imgdim[ii] - 1); /* first pixel in the tile that overlaps with the image (0 base) */ tilefpix[ii] = maxvalue(fpixel[ii] - tfpixel[ii], 0); while ((tfpixel[ii] + tilefpix[ii] - fpixel[ii]) % labs(inc[ii])) { (tilefpix[ii])++; if (tilefpix[ii] >= tiledim[ii]) return(*status); /* no overlapping pixels */ } /* printf("ii tfpixel, tlpixel %d %d %d \n",ii, tfpixel[ii], tlpixel[ii]); printf("ii, tf, tl, imgfpix,imglpix, tilefpix %d %d %d %d %d %d\n",ii, tf,tl,imgfpix[ii], imglpix[ii],tilefpix[ii]); */ if (ii > 0) imgdim[ii] *= imgdim[ii - 1]; /* product of dimensions */ } /* ---------------------------------------------------------------- */ /* calc number of pixels in each row (first dimension) that overlap */ /* multiply by pixlen to get number of bytes to copy in each loop */ /* ---------------------------------------------------------------- */ if (inc[0] != 1) overlap_flags = 1; /* can only copy 1 pixel at a time */ else overlap_flags = imglpix[0] - imgfpix[0] + 1; /* can copy whole row */ overlap_bytes = overlap_flags * pixlen; /* support up to 5 dimensions for now */ for (i4 = 0, it4=0; i4 <= imglpix[4] - imgfpix[4]; i4++, it4++) { /* increment plane if it falls in the cracks of the subsampled image */ while (ndim > 4 && (tfpixel[4] + tilefpix[4] - fpixel[4] + it4) % labs(inc[4]) != 0) it4++; /* offset to start of hypercube */ if (inc[4] > 0) im4 = (i4 + imgfpix[4]) * imgdim[3]; else im4 = imgdim[4] - (i4 + 1 + imgfpix[4]) * imgdim[3]; t4 = (tilefpix[4] + it4) * tiledim[3]; for (i3 = 0, it3=0; i3 <= imglpix[3] - imgfpix[3]; i3++, it3++) { /* increment plane if it falls in the cracks of the subsampled image */ while (ndim > 3 && (tfpixel[3] + tilefpix[3] - fpixel[3] + it3) % labs(inc[3]) != 0) it3++; /* offset to start of cube */ if (inc[3] > 0) im3 = (i3 + imgfpix[3]) * imgdim[2] + im4; else im3 = imgdim[3] - (i3 + 1 + imgfpix[3]) * imgdim[2] + im4; t3 = (tilefpix[3] + it3) * tiledim[2] + t4; /* loop through planes of the image */ for (i2 = 0, it2=0; i2 <= imglpix[2] - imgfpix[2]; i2++, it2++) { /* incre plane if it falls in the cracks of the subsampled image */ while (ndim > 2 && (tfpixel[2] + tilefpix[2] - fpixel[2] + it2) % labs(inc[2]) != 0) it2++; /* offset to start of plane */ if (inc[2] > 0) im2 = (i2 + imgfpix[2]) * imgdim[1] + im3; else im2 = imgdim[2] - (i2 + 1 + imgfpix[2]) * imgdim[1] + im3; t2 = (tilefpix[2] + it2) * tiledim[1] + t3; /* loop through rows of the image */ for (i1 = 0, it1=0; i1 <= imglpix[1] - imgfpix[1]; i1++, it1++) { /* incre row if it falls in the cracks of the subsampled image */ while (ndim > 1 && (tfpixel[1] + tilefpix[1] - fpixel[1] + it1) % labs(inc[1]) != 0) it1++; /* calc position of first pixel in tile to be copied */ tilepix = tilefpix[0] + (tilefpix[1] + it1) * tiledim[0] + t2; /* offset to start of row */ if (inc[1] > 0) im1 = (i1 + imgfpix[1]) * imgdim[0] + im2; else im1 = imgdim[1] - (i1 + 1 + imgfpix[1]) * imgdim[0] + im2; /* printf("inc = %d %d %d %d\n",inc[0],inc[1],inc[2],inc[3]); printf("im1,im2,im3,im4 = %d %d %d %d\n",im1,im2,im3,im4); */ /* offset to byte within the row */ if (inc[0] > 0) imgpix = imgfpix[0] + im1; else imgpix = imgdim[0] - 1 - imgfpix[0] + im1; /* printf("tilefpix0,1, imgfpix1, it1, inc1, t2= %d %d %d %d %d %d\n", tilefpix[0],tilefpix[1],imgfpix[1],it1,inc[1], t2); printf("i1, it1, tilepix, imgpix %d %d %d %d \n", i1, it1, tilepix, imgpix); */ /* loop over pixels along one row of the image */ for (ipos = imgfpix[0]; ipos <= imglpix[0]; ipos += overlap_flags) { /* convert from image pixel to byte offset */ tilepixbyte = tilepix * pixlen; imgpixbyte = imgpix * pixlen; /* printf(" tilepix, tilepixbyte, imgpix, imgpixbyte= %d %d %d %d\n", tilepix, tilepixbyte, imgpix, imgpixbyte); */ /* copy overlapping row of pixels from image to tile */ memcpy(tile + tilepixbyte, image + imgpixbyte, overlap_bytes); tilepix += (overlap_flags * labs(inc[0])); if (inc[0] > 0) imgpix += overlap_flags; else imgpix -= overlap_flags; } } } } } return(*status); } /*--------------------------------------------------------------------------*/ static int unquantize_i1r4(long row, /* tile number = row number in table */ unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int dither_method, /* I - dithering method to use */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Unquantize byte values into the scaled floating point values */ { long ii; int nextrand, iseed; if (!fits_rand_value) if (fits_init_randoms()) return(MEMORY_ALLOCATION); /* initialize the index to the next random number in the list */ iseed = (int) ((row - 1) % N_RANDOM); nextrand = (int) (fits_rand_value[iseed] * 500); if (nullcheck == 0) /* no null checking required */ { for (ii = 0; ii < ntodo; ii++) { /* if (dither_method == SUBTRACTIVE_DITHER_2 && input[ii] == ZERO_VALUE) output[ii] = 0.0; else */ output[ii] = (float) (((double) input[ii] - fits_rand_value[nextrand] + 0.5) * scale + zero); nextrand++; if (nextrand == N_RANDOM) { iseed++; if (iseed == N_RANDOM) iseed = 0; nextrand = (int) (fits_rand_value[iseed] * 500); } } } else /* must check for null values */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { /* if (dither_method == SUBTRACTIVE_DITHER_2 && input[ii] == ZERO_VALUE) output[ii] = 0.0; else */ output[ii] = (float) (((double) input[ii] - fits_rand_value[nextrand] + 0.5) * scale + zero); } nextrand++; if (nextrand == N_RANDOM) { iseed++; if (iseed == N_RANDOM) iseed = 0; nextrand = (int) (fits_rand_value[iseed] * 500); } } } return(*status); } /*--------------------------------------------------------------------------*/ static int unquantize_i2r4(long row, /* seed for random values */ short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int dither_method, /* I - dithering method to use */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Unquantize short integer values into the scaled floating point values */ { long ii; int nextrand, iseed; if (!fits_rand_value) if (fits_init_randoms()) return(MEMORY_ALLOCATION); /* initialize the index to the next random number in the list */ iseed = (int) ((row - 1) % N_RANDOM); nextrand = (int) (fits_rand_value[iseed] * 500); if (nullcheck == 0) /* no null checking required */ { for (ii = 0; ii < ntodo; ii++) { /* if (dither_method == SUBTRACTIVE_DITHER_2 && input[ii] == ZERO_VALUE) output[ii] = 0.0; else */ output[ii] = (float) (((double) input[ii] - fits_rand_value[nextrand] + 0.5) * scale + zero); nextrand++; if (nextrand == N_RANDOM) { iseed++; if (iseed == N_RANDOM) iseed = 0; nextrand = (int) (fits_rand_value[iseed] * 500); } } } else /* must check for null values */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { /* if (dither_method == SUBTRACTIVE_DITHER_2 && input[ii] == ZERO_VALUE) output[ii] = 0.0; else */ output[ii] = (float) (((double) input[ii] - fits_rand_value[nextrand] + 0.5) * scale + zero); } nextrand++; if (nextrand == N_RANDOM) { iseed++; if (iseed == N_RANDOM) iseed = 0; nextrand = (int) (fits_rand_value[iseed] * 500); } } } return(*status); } /*--------------------------------------------------------------------------*/ static int unquantize_i4r4(long row, /* tile number = row number in table */ INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int dither_method, /* I - dithering method to use */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Unquantize int integer values into the scaled floating point values */ { long ii; int nextrand, iseed; if (fits_rand_value == 0) if (fits_init_randoms()) return(MEMORY_ALLOCATION); /* initialize the index to the next random number in the list */ iseed = (int) ((row - 1) % N_RANDOM); nextrand = (int) (fits_rand_value[iseed] * 500); if (nullcheck == 0) /* no null checking required */ { for (ii = 0; ii < ntodo; ii++) { if (dither_method == SUBTRACTIVE_DITHER_2 && input[ii] == ZERO_VALUE) output[ii] = 0.0; else output[ii] = (float) (((double) input[ii] - fits_rand_value[nextrand] + 0.5) * scale + zero); nextrand++; if (nextrand == N_RANDOM) { iseed++; if (iseed == N_RANDOM) iseed = 0; nextrand = (int) (fits_rand_value[iseed] * 500); } } } else /* must check for null values */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (dither_method == SUBTRACTIVE_DITHER_2 && input[ii] == ZERO_VALUE) output[ii] = 0.0; else output[ii] = (float) (((double) input[ii] - fits_rand_value[nextrand] + 0.5) * scale + zero); } nextrand++; if (nextrand == N_RANDOM) { iseed++; if (iseed == N_RANDOM) iseed = 0; nextrand = (int) (fits_rand_value[iseed] * 500); } } } return(*status); } /*--------------------------------------------------------------------------*/ static int unquantize_i1r8(long row, /* tile number = row number in table */ unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int dither_method, /* I - dithering method to use */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Unquantize byte values into the scaled floating point values */ { long ii; int nextrand, iseed; if (!fits_rand_value) if (fits_init_randoms()) return(MEMORY_ALLOCATION); /* initialize the index to the next random number in the list */ iseed = (int) ((row - 1) % N_RANDOM); nextrand = (int) (fits_rand_value[iseed] * 500); if (nullcheck == 0) /* no null checking required */ { for (ii = 0; ii < ntodo; ii++) { /* if (dither_method == SUBTRACTIVE_DITHER_2 && input[ii] == ZERO_VALUE) output[ii] = 0.0; else */ output[ii] = (double) (((double) input[ii] - fits_rand_value[nextrand] + 0.5) * scale + zero); nextrand++; if (nextrand == N_RANDOM) { iseed++; if (iseed == N_RANDOM) iseed = 0; nextrand = (int) (fits_rand_value[iseed] * 500); } } } else /* must check for null values */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { /* if (dither_method == SUBTRACTIVE_DITHER_2 && input[ii] == ZERO_VALUE) output[ii] = 0.0; else */ output[ii] = (double) (((double) input[ii] - fits_rand_value[nextrand] + 0.5) * scale + zero); } nextrand++; if (nextrand == N_RANDOM) { iseed++; if (iseed == N_RANDOM) iseed = 0; nextrand = (int) (fits_rand_value[iseed] * 500); } } } return(*status); } /*--------------------------------------------------------------------------*/ static int unquantize_i2r8(long row, /* tile number = row number in table */ short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int dither_method, /* I - dithering method to use */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Unquantize short integer values into the scaled floating point values */ { long ii; int nextrand, iseed; if (!fits_rand_value) if (fits_init_randoms()) return(MEMORY_ALLOCATION); /* initialize the index to the next random number in the list */ iseed = (int) ((row - 1) % N_RANDOM); nextrand = (int) (fits_rand_value[iseed] * 500); if (nullcheck == 0) /* no null checking required */ { for (ii = 0; ii < ntodo; ii++) { /* if (dither_method == SUBTRACTIVE_DITHER_2 && input[ii] == ZERO_VALUE) output[ii] = 0.0; else */ output[ii] = (double) (((double) input[ii] - fits_rand_value[nextrand] + 0.5) * scale + zero); nextrand++; if (nextrand == N_RANDOM) { iseed++; if (iseed == N_RANDOM) iseed = 0; nextrand = (int) (fits_rand_value[iseed] * 500); } } } else /* must check for null values */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { /* if (dither_method == SUBTRACTIVE_DITHER_2 && input[ii] == ZERO_VALUE) output[ii] = 0.0; else */ output[ii] = (double) (((double) input[ii] - fits_rand_value[nextrand] + 0.5) * scale + zero); } nextrand++; if (nextrand == N_RANDOM) { iseed++; if (iseed == N_RANDOM) iseed = 0; nextrand = (int) (fits_rand_value[iseed] * 500); } } } return(*status); } /*--------------------------------------------------------------------------*/ static int unquantize_i4r8(long row, /* tile number = row number in table */ INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int dither_method, /* I - dithering method to use */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Unquantize int integer values into the scaled floating point values */ { long ii; int nextrand, iseed; if (fits_rand_value == 0) if (fits_init_randoms()) return(MEMORY_ALLOCATION); /* initialize the index to the next random number in the list */ iseed = (int) ((row - 1) % N_RANDOM); nextrand = (int) (fits_rand_value[iseed] * 500); if (nullcheck == 0) /* no null checking required */ { for (ii = 0; ii < ntodo; ii++) { if (dither_method == SUBTRACTIVE_DITHER_2 && input[ii] == ZERO_VALUE) output[ii] = 0.0; else output[ii] = (double) (((double) input[ii] - fits_rand_value[nextrand] + 0.5) * scale + zero); nextrand++; if (nextrand == N_RANDOM) { iseed++; if (iseed == N_RANDOM) iseed = 0; nextrand = (int) (fits_rand_value[iseed] * 500); } } } else /* must check for null values */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (dither_method == SUBTRACTIVE_DITHER_2 && input[ii] == ZERO_VALUE) output[ii] = 0.0; else output[ii] = (double) (((double) input[ii] - fits_rand_value[nextrand] + 0.5) * scale + zero); } nextrand++; if (nextrand == N_RANDOM) { iseed++; if (iseed == N_RANDOM) iseed = 0; nextrand = (int) (fits_rand_value[iseed] * 500); } } } return(*status); } /*--------------------------------------------------------------------------*/ static int imcomp_float2nan(float *indata, long tilelen, int *outdata, float nullflagval, int *status) /* convert pixels that are equal to nullflag to NaNs. Note that indata and outdata point to the same location. */ { int ii; for (ii = 0; ii < tilelen; ii++) { if (indata[ii] == nullflagval) outdata[ii] = -1; /* integer -1 has the same bit pattern as a real*4 NaN */ } return(*status); } /*--------------------------------------------------------------------------*/ static int imcomp_double2nan(double *indata, long tilelen, LONGLONG *outdata, double nullflagval, int *status) /* convert pixels that are equal to nullflag to NaNs. Note that indata and outdata point to the same location. */ { int ii; for (ii = 0; ii < tilelen; ii++) { if (indata[ii] == nullflagval) outdata[ii] = -1; /* integer -1 has the same bit pattern as a real*8 NaN */ } return(*status); } /* ======================================================================= */ /* TABLE COMPRESSION ROUTINES */ /* =-====================================================================== */ /*--------------------------------------------------------------------------*/ int fits_compress_table(fitsfile *infptr, fitsfile *outfptr, int *status) /* Compress the input FITS Binary Table. First divide the table into equal sized chunks (analogous to image tiles) where all the contain the same number of rows (except perhaps for the last chunk which may contain fewer rows). The chunks should not be too large to copy into memory (currently, about 100 MB max seems a reasonable size). Then, on a chunk by piece basis, do the following: 1. Transpose the table from its original row-major order, into column-major order. All the bytes for each column are then continuous. In addition, the bytes within each table element may be shuffled so that the most significant byte of every element occurs first in the array, followed by the next most significant byte, and so on to the least significant byte. Byte shuffling often improves the gzip compression of floating-point arrays. 2. Compress the contiguous array of bytes in each column using the specified compression method. If no method is specifed, then a default method for that data type is chosen. 3. Store the compressed stream of bytes into a column that has the same name as in the input table, but which has a variable-length array data type (1QB). The output table will contain one row for each piece of the original table. 4. If the input table contain variable-length arrays, then each VLA is compressed individually, and written to the heap in the output table. Note that the output table will contain 2 sets of pointers for each VLA column. The first set contains the pointers to the uncompressed VLAs from the input table and the second is the set of pointers to the compressed VLAs in the output table. The latter set of pointers is used to reconstruct table when it is uncompressed, so that the heap has exactly the same structure as in the original file. The 2 sets of pointers are concatinated together, compressed with gzip, and written to the output table. When reading the compressed table, the only VLA that is directly visible is this compressed array of descriptors. One has to uncompress this array to be able to to read all the descriptors to the individual VLAs in the column. */ { long maxchunksize = 10000000; /* default value for the size of each chunk of the table */ char *cm_buffer; /* memory buffer for the transposed, Column-Major, chunk of the table */ LONGLONG cm_colstart[1000]; /* starting offset of each column in the cm_buffer */ LONGLONG rm_repeat[1000]; /* repeat count of each column in the input row-major table */ LONGLONG rm_colwidth[999]; /* width in bytes of each column in the input row-major table */ LONGLONG cm_repeat[999]; /* total number of elements in each column of the transposed column-major table */ int coltype[999]; /* data type code for each column */ int compalgor[999], default_algor = 0; /* compression algorithm to be applied to each column */ float cratio[999]; /* compression ratio for each column (for diagnostic purposes) */ float compressed_size, uncompressed_size, tot_compressed_size, tot_uncompressed_size; LONGLONG nrows, firstrow; LONGLONG headstart, datastart, dataend, startbyte, jj, kk, naxis1; LONGLONG vlalen, vlamemlen, vlastart, bytepos; long repeat, width, nchunks, rowspertile, lastrows; int ii, ll, ncols, hdutype, ltrue = 1, print_report = 0, tstatus; char *cptr, keyname[9], tform[40], *cdescript; char comm[FLEN_COMMENT], keyvalue[FLEN_VALUE], *cvlamem, tempstring[FLEN_VALUE], card[FLEN_CARD]; LONGLONG *descriptors, *outdescript, *vlamem; int *pdescriptors; size_t dlen, datasize, compmemlen; /* ================================================================================== */ /* perform initial sanity checks */ /* ================================================================================== */ /* special input flag value that means print out diagnostics */ if (*status == -999) { print_report = 1; *status = 0; } if (*status > 0) return(*status); fits_get_hdu_type(infptr, &hdutype, status); if (hdutype != BINARY_TBL) { *status = NOT_BTABLE; return(*status); } if (infptr == outfptr) { ffpmsg("Cannot compress table 'in place' (fits_compress_table)"); ffpmsg(" outfptr cannot be the same as infptr."); *status = DATA_COMPRESSION_ERR; return(*status); } /* get dimensions of the table */ fits_get_num_rowsll(infptr, &nrows, status); fits_get_num_cols(infptr, &ncols, status); fits_read_key(infptr, TLONGLONG, "NAXIS1", &naxis1, NULL, status); /* get offset to the start of the data and total size of the table (including the heap) */ fits_get_hduaddrll(infptr, &headstart, &datastart, &dataend, status); if (*status > 0) return(*status); tstatus = 0; if (!fits_read_key(infptr, TSTRING, "FZALGOR", tempstring, NULL, &tstatus)) { if (!fits_strcasecmp(tempstring, "NONE")) { default_algor = NOCOMPRESS; } else if (!fits_strcasecmp(tempstring, "GZIP") || !fits_strcasecmp(tempstring, "GZIP_1")) { default_algor = GZIP_1; } else if (!fits_strcasecmp(tempstring, "GZIP_2")) { default_algor = GZIP_2; } else if (!fits_strcasecmp(tempstring, "RICE_1")) { default_algor = RICE_1; } else { ffpmsg("FZALGOR specifies unsupported table compression algorithm:"); ffpmsg(tempstring); *status = DATA_COMPRESSION_ERR; return(*status); } } /* just copy the HDU verbatim if the table has 0 columns or rows or if the table */ /* is less than 5760 bytes (2 blocks) in size, or compression directive keyword = "NONE" */ if (nrows < 1 || ncols < 1 || (dataend - datastart) < 5760 || default_algor == NOCOMPRESS) { fits_copy_hdu (infptr, outfptr, 0, status); return(*status); } /* Check if the chunk size has been specified with the FZTILELN keyword. */ /* If not, calculate a default number of rows per chunck, */ tstatus = 0; if (fits_read_key(infptr, TLONG, "FZTILELN", &rowspertile, NULL, &tstatus)) { rowspertile = (long) (maxchunksize / naxis1); } if (rowspertile < 1) rowspertile = 1; if (rowspertile > nrows) rowspertile = (long) nrows; nchunks = (long) ((nrows - 1) / rowspertile + 1); /* total number of chunks */ lastrows = (long) (nrows - ((nchunks - 1) * rowspertile)); /* number of rows in last chunk */ /* allocate space for the transposed, column-major chunk of the table */ cm_buffer = calloc((size_t) naxis1, (size_t) rowspertile); if (!cm_buffer) { ffpmsg("Could not allocate cm_buffer for transposed table"); *status = MEMORY_ALLOCATION; return(*status); } /* ================================================================================== */ /* Construct the header of the output compressed table */ /* ================================================================================== */ fits_copy_header(infptr, outfptr, status); /* start with verbatim copy of the input header */ fits_write_key(outfptr, TLOGICAL, "ZTABLE", <rue, "this is a compressed table", status); fits_write_key(outfptr, TLONG, "ZTILELEN", &rowspertile, "number of rows in each tile", status); fits_read_card(outfptr, "NAXIS1", card, status); /* copy NAXIS1 to ZNAXIS1 */ strncpy(card, "ZNAXIS1", 7); fits_write_record(outfptr, card, status); fits_read_card(outfptr, "NAXIS2", card, status); /* copy NAXIS2 to ZNAXIS2 */ strncpy(card, "ZNAXIS2", 7); fits_write_record(outfptr, card, status); fits_read_card(outfptr, "PCOUNT", card, status); /* copy PCOUNT to ZPCOUNT */ strncpy(card, "ZPCOUNT", 7); fits_write_record(outfptr, card, status); fits_modify_key_lng(outfptr, "NAXIS2", nchunks, "&", status); /* 1 row per chunk */ fits_modify_key_lng(outfptr, "NAXIS1", ncols * 16, "&", status); /* 16 bytes for each 1QB column */ fits_modify_key_lng(outfptr, "PCOUNT", 0L, "&", status); /* reset PCOUNT to 0 */ /* rename the Checksum keywords, if they exist */ tstatus = 0; fits_modify_name(outfptr, "CHECKSUM", "ZHECKSUM", &tstatus); tstatus = 0; fits_modify_name(outfptr, "DATASUM", "ZDATASUM", &tstatus); /* ================================================================================== */ /* Now loop over each column of the input table: write the column-specific keywords */ /* and determine which compression algorithm to use. */ /* Also calculate various offsets to the start of the column data in both the */ /* original row-major table and in the transposed column-major form of the table. */ /* ================================================================================== */ cm_colstart[0] = 0; for (ii = 0; ii < ncols; ii++) { /* get the structural parameters of the original uncompressed column */ fits_make_keyn("TFORM", ii+1, keyname, status); fits_read_key(outfptr, TSTRING, keyname, tform, comm, status); fits_binary_tform(tform, coltype+ii, &repeat, &width, status); /* get the repeat count and the width */ /* preserve the original TFORM value and comment string in a ZFORMn keyword */ fits_read_card(outfptr, keyname, card, status); card[0] = 'Z'; fits_write_record(outfptr, card, status); /* All columns in the compressed table will have a variable-length array type. */ fits_modify_key_str(outfptr, keyname, "1QB", "&", status); /* Use 'Q' pointers (64-bit) */ /* deal with special cases: bit, string, and variable length array columns */ if (coltype[ii] == TBIT) { repeat = (repeat + 7) / 8; /* convert from bits to equivalent number of bytes */ } else if (coltype[ii] == TSTRING) { width = 1; /* ignore the optional 'w' in 'rAw' format */ } else if (coltype[ii] < 0) { /* pointer to variable length array */ if (strchr(tform,'Q') ) { width = 16; /* 'Q' descriptor has 64-bit pointers */ } else { width = 8; /* 'P' descriptor has 32-bit pointers */ } repeat = 1; } rm_repeat[ii] = repeat; rm_colwidth[ii] = repeat * width; /* column width (in bytes)in the input table */ /* starting offset of each field in the OUTPUT transposed column-major table */ cm_colstart[ii + 1] = cm_colstart[ii] + rm_colwidth[ii] * rowspertile; /* total number of elements in each column of the transposed column-major table */ cm_repeat[ii] = rm_repeat[ii] * rowspertile; compalgor[ii] = default_algor; /* initialize the column compression algorithm to the default */ /* check if a compression method has been specified for this column */ fits_make_keyn("FZALG", ii+1, keyname, status); tstatus = 0; if (!fits_read_key(outfptr, TSTRING, keyname, tempstring, NULL, &tstatus)) { if (!fits_strcasecmp(tempstring, "GZIP") || !fits_strcasecmp(tempstring, "GZIP_1")) { compalgor[ii] = GZIP_1; } else if (!fits_strcasecmp(tempstring, "GZIP_2")) { compalgor[ii] = GZIP_2; } else if (!fits_strcasecmp(tempstring, "RICE_1")) { compalgor[ii] = RICE_1; } else { ffpmsg("Unsupported table compression algorithm specification."); ffpmsg(keyname); ffpmsg(tempstring); *status = DATA_COMPRESSION_ERR; free(cm_buffer); return(*status); } } /* do sanity check of the requested algorithm and override if necessary */ if ( abs(coltype[ii]) == TLOGICAL || abs(coltype[ii]) == TBIT || abs(coltype[ii]) == TSTRING) { if (compalgor[ii] != GZIP_1) { compalgor[ii] = GZIP_1; } } else if ( abs(coltype[ii]) == TCOMPLEX || abs(coltype[ii]) == TDBLCOMPLEX || abs(coltype[ii]) == TFLOAT || abs(coltype[ii]) == TDOUBLE || abs(coltype[ii]) == TLONGLONG ) { if (compalgor[ii] != GZIP_1 && compalgor[ii] != GZIP_2) { compalgor[ii] = GZIP_2; /* gzip_2 usually works better gzip_1 */ } } else if ( abs(coltype[ii]) == TSHORT ) { if (compalgor[ii] != GZIP_1 && compalgor[ii] != GZIP_2 && compalgor[ii] != RICE_1) { compalgor[ii] = GZIP_2; /* gzip_2 usually works better rice_1 */ } } else if ( abs(coltype[ii]) == TLONG ) { if (compalgor[ii] != GZIP_1 && compalgor[ii] != GZIP_2 && compalgor[ii] != RICE_1) { compalgor[ii] = RICE_1; } } else if ( abs(coltype[ii]) == TBYTE ) { if (compalgor[ii] != GZIP_1 && compalgor[ii] != RICE_1 ) { compalgor[ii] = GZIP_1; } } } /* end of loop over columns */ /* ================================================================================== */ /* now process each chunk of the table, in turn */ /* ================================================================================== */ tot_uncompressed_size = 0.; tot_compressed_size = 0; firstrow = 1; for (ll = 0; ll < nchunks; ll++) { if (ll == nchunks - 1) { /* the last chunk may have fewer rows */ rowspertile = lastrows; for (ii = 0; ii < ncols; ii++) { cm_colstart[ii + 1] = cm_colstart[ii] + (rm_colwidth[ii] * rowspertile); cm_repeat[ii] = rm_repeat[ii] * rowspertile; } } /* move to the start of the chunk in the input table */ ffmbyt(infptr, datastart, 0, status); /* ================================================================================*/ /* First, transpose this chunck from row-major order to column-major order */ /* At the same time, shuffle the bytes in each datum, if doing GZIP_2 compression */ /* ================================================================================*/ for (jj = 0; jj < rowspertile; jj++) { /* loop over rows */ for (ii = 0; ii < ncols; ii++) { /* loop over columns */ if (rm_repeat[ii] > 0) { /* skip virtual columns that have 0 elements */ kk = 0; /* if the GZIP_2 compression algorithm is used, shuffle the bytes */ if (coltype[ii] == TSHORT && compalgor[ii] == GZIP_2) { while(kk < rm_colwidth[ii]) { cptr = cm_buffer + (cm_colstart[ii] + (jj * rm_repeat[ii]) + kk/2); ffgbyt(infptr, 1, cptr, status); /* get 1st byte */ cptr += cm_repeat[ii]; ffgbyt(infptr, 1, cptr, status); /* get 2nd byte */ kk += 2; } } else if ((coltype[ii] == TFLOAT || coltype[ii] == TLONG) && compalgor[ii] == GZIP_2) { while(kk < rm_colwidth[ii]) { cptr = cm_buffer + (cm_colstart[ii] + (jj * rm_repeat[ii]) + kk/4); ffgbyt(infptr, 1, cptr, status); /* get 1st byte */ cptr += cm_repeat[ii]; ffgbyt(infptr, 1, cptr, status); /* get 2nd byte */ cptr += cm_repeat[ii]; ffgbyt(infptr, 1, cptr, status); /* get 3rd byte */ cptr += cm_repeat[ii]; ffgbyt(infptr, 1, cptr, status); /* get 4th byte */ kk += 4; } } else if ( (coltype[ii] == TDOUBLE || coltype[ii] == TLONGLONG) && compalgor[ii] == GZIP_2) { while(kk < rm_colwidth[ii]) { cptr = cm_buffer + (cm_colstart[ii] + (jj * rm_repeat[ii]) + kk/8); ffgbyt(infptr, 1, cptr, status); /* get 1st byte */ cptr += cm_repeat[ii]; ffgbyt(infptr, 1, cptr, status); /* get 2nd byte */ cptr += cm_repeat[ii]; ffgbyt(infptr, 1, cptr, status); /* get 3rd byte */ cptr += cm_repeat[ii]; ffgbyt(infptr, 1, cptr, status); /* get 4th byte */ cptr += cm_repeat[ii]; ffgbyt(infptr, 1, cptr, status); /* get 5th byte */ cptr += cm_repeat[ii]; ffgbyt(infptr, 1, cptr, status); /* get 6th byte */ cptr += cm_repeat[ii]; ffgbyt(infptr, 1, cptr, status); /* get 7th byte */ cptr += cm_repeat[ii]; ffgbyt(infptr, 1, cptr, status); /* get 8th byte */ kk += 8; } } else { /* all other cases: don't shuffle the bytes; simply transpose the column */ cptr = cm_buffer + (cm_colstart[ii] + (jj * rm_colwidth[ii])); /* addr to copy to */ startbyte = (infptr->Fptr)->bytepos; /* save the starting byte location */ ffgbyt(infptr, rm_colwidth[ii], cptr, status); /* copy all the bytes */ if (rm_colwidth[ii] >= MINDIRECT) { /* have to explicitly move to next byte */ ffmbyt(infptr, startbyte + rm_colwidth[ii], 0, status); } } /* end of test of coltypee */ } /* end of not virtual column */ } /* end of loop over columns */ } /* end of loop over rows */ /* ================================================================================*/ /* now compress each column in the transposed chunk of the table */ /* ================================================================================*/ fits_set_hdustruc(outfptr, status); /* initialize structures in the output table */ for (ii = 0; ii < ncols; ii++) { /* loop over columns */ /* initialize the diagnostic compression results string */ snprintf(results[ii],30,"%3d %3d %3d ", ii+1, coltype[ii], compalgor[ii]); cratio[ii] = 0; if (rm_repeat[ii] > 0) { /* skip virtual columns with zero width */ if (coltype[ii] < 0) { /* this is a variable length array (VLA) column */ /*=========================================================================*/ /* variable-length array columns are a complicated special case */ /*=========================================================================*/ /* allocate memory to hold all the VLA descriptors from the input table, plus */ /* room to hold the descriptors to the compressed VLAs in the output table */ /* In total, there will be 2 descriptors for each row in this chunk */ uncompressed_size = 0.; compressed_size = 0; datasize = (size_t) (cm_colstart[ii + 1] - cm_colstart[ii]); /* size of input descriptors */ cdescript = calloc(datasize + (rowspertile * 16), 1); /* room for both descriptors */ if (!cdescript) { ffpmsg("Could not allocate buffer for descriptors"); *status = MEMORY_ALLOCATION; free(cm_buffer); return(*status); } /* copy the input descriptors to this array */ memcpy(cdescript, &cm_buffer[cm_colstart[ii]], datasize); #if BYTESWAPPED /* byte-swap the integer values into the native machine representation */ if (rm_colwidth[ii] == 16) { ffswap8((double *) cdescript, rowspertile * 2); } else { ffswap4((int *) cdescript, rowspertile * 2); } #endif descriptors = (LONGLONG *) cdescript; /* use this for Q type descriptors */ pdescriptors = (int *) cdescript; /* use this instead for or P type descriptors */ /* pointer to the 2nd set of descriptors */ outdescript = (LONGLONG *) (cdescript + datasize); /* this is a LONGLONG pointer */ for (jj = 0; jj < rowspertile; jj++) { /* loop to compress each VLA in turn */ if (rm_colwidth[ii] == 16) { /* if Q pointers */ vlalen = descriptors[jj * 2]; vlastart = descriptors[(jj * 2) + 1]; } else { /* if P pointers */ vlalen = (LONGLONG) pdescriptors[jj * 2]; vlastart = (LONGLONG) pdescriptors[(jj * 2) + 1]; } if (vlalen > 0) { /* skip zero-length VLAs */ vlamemlen = vlalen * (int) (-coltype[ii] / 10); vlamem = (LONGLONG *) malloc((size_t) vlamemlen); /* memory for the input uncompressed VLA */ if (!vlamem) { ffpmsg("Could not allocate buffer for VLA"); *status = MEMORY_ALLOCATION; free(cdescript); free(cm_buffer); return(*status); } compmemlen = (size_t) (vlalen * ((LONGLONG) (-coltype[ii] / 10)) * 1.5); if (compmemlen < 100) compmemlen = 100; cvlamem = malloc(compmemlen); /* memory for the output compressed VLA */ if (!cvlamem) { ffpmsg("Could not allocate buffer for compressed data"); *status = MEMORY_ALLOCATION; free(vlamem); free(cdescript); free(cm_buffer); return(*status); } /* read the raw bytes directly from the heap, without any byte-swapping or null value detection */ bytepos = (infptr->Fptr)->datastart + (infptr->Fptr)->heapstart + vlastart; ffmbyt(infptr, bytepos, REPORT_EOF, status); ffgbyt(infptr, vlamemlen, vlamem, status); /* read the bytes */ uncompressed_size += vlamemlen; /* total size of the uncompressed VLAs */ tot_uncompressed_size += vlamemlen; /* total size of the uncompressed file */ /* compress the VLA with the appropriate algorithm */ if (compalgor[ii] == RICE_1) { if (-coltype[ii] == TSHORT) { #if BYTESWAPPED ffswap2((short *) (vlamem), (long) vlalen); #endif dlen = fits_rcomp_short ((short *)(vlamem), (int) vlalen, (unsigned char *) cvlamem, (int) compmemlen, 32); } else if (-coltype[ii] == TLONG) { #if BYTESWAPPED ffswap4((int *) (vlamem), (long) vlalen); #endif dlen = fits_rcomp ((int *)(vlamem), (int) vlalen, (unsigned char *) cvlamem, (int) compmemlen, 32); } else if (-coltype[ii] == TBYTE) { dlen = fits_rcomp_byte ((signed char *)(vlamem), (int) vlalen, (unsigned char *) cvlamem, (int) compmemlen, 32); } else { /* this should not happen */ ffpmsg(" Error: cannot compress this column type with the RICE algorithm"); free(vlamem); free(cdescript); free(cm_buffer); free(cvlamem); *status = DATA_COMPRESSION_ERR; return(*status); } } else if (compalgor[ii] == GZIP_1 || compalgor[ii] == GZIP_2){ if (compalgor[ii] == GZIP_2 ) { /* shuffle the bytes before gzipping them */ if ( (int) (-coltype[ii] / 10) == 2) { fits_shuffle_2bytes((char *) vlamem, vlalen, status); } else if ( (int) (-coltype[ii] / 10) == 4) { fits_shuffle_4bytes((char *) vlamem, vlalen, status); } else if ( (int) (-coltype[ii] / 10) == 8) { fits_shuffle_8bytes((char *) vlamem, vlalen, status); } } /*: gzip compress the array of bytes */ compress2mem_from_mem( (char *) vlamem, (size_t) vlamemlen, &cvlamem, &compmemlen, realloc, &dlen, status); } else { /* this should not happen */ ffpmsg(" Error: unknown compression algorithm"); free(vlamem); free(cdescript); free(cm_buffer); free(cvlamem); *status = DATA_COMPRESSION_ERR; return(*status); } /* write the compressed array to the output table, but... */ /* We use a trick of always writing the array to the same row of the output table */ /* and then copy the descriptor into the array of descriptors that we allocated. */ /* First, reset the descriptor */ fits_write_descript(outfptr, ii+1, ll+1, 0, 0, status); /* write the compressed VLA if it is smaller than the original, else write */ /* the uncompressed array */ fits_set_tscale(outfptr, ii + 1, 1.0, 0.0, status); /* turn off any data scaling, first */ if (dlen < vlamemlen) { fits_write_col(outfptr, TBYTE, ii + 1, ll+1, 1, dlen, cvlamem, status); compressed_size += dlen; /* total size of the compressed VLAs */ tot_compressed_size += dlen; /* total size of the compressed file */ } else { if ( -coltype[ii] != TBYTE && compalgor[ii] != GZIP_1) { /* it is probably faster to reread the raw bytes, rather than unshuffle or unswap them */ bytepos = (infptr->Fptr)->datastart + (infptr->Fptr)->heapstart + vlastart; ffmbyt(infptr, bytepos, REPORT_EOF, status); ffgbyt(infptr, vlamemlen, vlamem, status); /* read the bytes */ } fits_write_col(outfptr, TBYTE, ii + 1, ll+1, 1, vlamemlen, vlamem, status); compressed_size += vlamemlen; /* total size of the compressed VLAs */ tot_compressed_size += vlamemlen; /* total size of the compressed file */ } /* read back the descriptor and save it in the array of descriptors */ fits_read_descriptll(outfptr, ii + 1, ll + 1, outdescript+(jj*2), outdescript+(jj*2)+1, status); free(cvlamem); free(vlamem); } /* end of vlalen > 0 */ } /* end of loop over rows */ if (compressed_size != 0) cratio[ii] = uncompressed_size / compressed_size; snprintf(tempstring,FLEN_VALUE," r=%6.2f",cratio[ii]); strncat(results[ii],tempstring, 29-strlen(results[ii])); /* now we just have to compress the array of descriptors (both input and output) */ /* and write them to the output table. */ /* allocate memory for the compressed descriptors */ cvlamem = malloc(datasize + (rowspertile * 16) ); if (!cvlamem) { ffpmsg("Could not allocate buffer for compressed data"); *status = MEMORY_ALLOCATION; free(cdescript); free(cm_buffer); return(*status); } #if BYTESWAPPED /* byte swap the input and output descriptors */ if (rm_colwidth[ii] == 16) { ffswap8((double *) cdescript, rowspertile * 2); } else { ffswap4((int *) cdescript, rowspertile * 2); } ffswap8((double *) outdescript, rowspertile * 2); #endif /* compress the array contain both sets of descriptors */ compress2mem_from_mem((char *) cdescript, datasize + (rowspertile * 16), &cvlamem, &datasize, realloc, &dlen, status); free(cdescript); /* write the compressed descriptors to the output column */ fits_set_tscale(outfptr, ii + 1, 1.0, 0.0, status); /* turn off any data scaling, first */ fits_write_descript(outfptr, ii+1, ll+1, 0, 0, status); /* First, reset the descriptor */ fits_write_col(outfptr, TBYTE, ii + 1, ll+1, 1, dlen, cvlamem, status); free(cvlamem); if (ll == 0) { /* only write the ZCTYPn keyword once, while processing the first column */ fits_make_keyn("ZCTYP", ii+1, keyname, status); if (compalgor[ii] == RICE_1) { strcpy(keyvalue, "RICE_1"); } else if (compalgor[ii] == GZIP_2) { strcpy(keyvalue, "GZIP_2"); } else { strcpy(keyvalue, "GZIP_1"); } fits_write_key(outfptr, TSTRING, keyname, keyvalue, "compression algorithm for column", status); } continue; /* jump to end of loop, to go to next column */ } /* end of VLA case */ /* ================================================================================*/ /* deal with all the normal fixed-length columns here */ /* ================================================================================*/ /* allocate memory for the compressed data */ datasize = (size_t) (cm_colstart[ii + 1] - cm_colstart[ii]); cvlamem = malloc(datasize*2); tot_uncompressed_size += datasize; if (!cvlamem) { ffpmsg("Could not allocate buffer for compressed data"); *status = MEMORY_ALLOCATION; free(cm_buffer); return(*status); } if (compalgor[ii] == RICE_1) { if (coltype[ii] == TSHORT) { #if BYTESWAPPED ffswap2((short *) (cm_buffer + cm_colstart[ii]), datasize / 2); #endif dlen = fits_rcomp_short ((short *)(cm_buffer + cm_colstart[ii]), datasize / 2, (unsigned char *) cvlamem, datasize * 2, 32); } else if (coltype[ii] == TLONG) { #if BYTESWAPPED ffswap4((int *) (cm_buffer + cm_colstart[ii]), datasize / 4); #endif dlen = fits_rcomp ((int *)(cm_buffer + cm_colstart[ii]), datasize / 4, (unsigned char *) cvlamem, datasize * 2, 32); } else if (coltype[ii] == TBYTE) { dlen = fits_rcomp_byte ((signed char *)(cm_buffer + cm_colstart[ii]), datasize, (unsigned char *) cvlamem, datasize * 2, 32); } else { /* this should not happen */ ffpmsg(" Error: cannot compress this column type with the RICE algorthm"); free(cvlamem); free(cm_buffer); *status = DATA_COMPRESSION_ERR; return(*status); } } else { /* all other cases: gzip compress the column (bytes may have been shuffled previously) */ compress2mem_from_mem(cm_buffer + cm_colstart[ii], datasize, &cvlamem, &datasize, realloc, &dlen, status); } if (ll == 0) { /* only write the ZCTYPn keyword once, while processing the first column */ fits_make_keyn("ZCTYP", ii+1, keyname, status); if (compalgor[ii] == RICE_1) { strcpy(keyvalue, "RICE_1"); } else if (compalgor[ii] == GZIP_2) { strcpy(keyvalue, "GZIP_2"); } else { strcpy(keyvalue, "GZIP_1"); } fits_write_key(outfptr, TSTRING, keyname, keyvalue, "compression algorithm for column", status); } /* write the compressed data to the output column */ fits_set_tscale(outfptr, ii + 1, 1.0, 0.0, status); /* turn off any data scaling, first */ fits_write_col(outfptr, TBYTE, ii + 1, ll+1, 1, dlen, cvlamem, status); tot_compressed_size += dlen; free(cvlamem); /* don't need the compressed data any more */ /* create diagnostic messages */ if (dlen != 0) cratio[ii] = (float) datasize / (float) dlen; /* compression ratio of the column */ snprintf(tempstring,FLEN_VALUE," r=%6.2f",cratio[ii]); strncat(results[ii],tempstring,29-strlen(results[ii])); } /* end of not a virtual column */ } /* end of loop over columns */ datastart += (rowspertile * naxis1); /* increment to start of next chunk */ firstrow += rowspertile; /* increment first row in next chunk */ if (print_report) { printf("\nChunk = %d\n",ll+1); for (ii = 0; ii < ncols; ii++) { printf("%s\n", results[ii]); } } } /* end of loop over chunks of the table */ /* =================================================================================*/ /* all done; just clean up and return */ /* ================================================================================*/ free(cm_buffer); fits_set_hdustruc(outfptr, status); /* reset internal structures */ if (print_report) { if (tot_compressed_size != 0) printf("\nTotal data size (MB) %.3f -> %.3f, ratio = %.3f\n", tot_uncompressed_size/1000000., tot_compressed_size/1000000., tot_uncompressed_size/tot_compressed_size); } return(*status); } /*--------------------------------------------------------------------------*/ int fits_uncompress_table(fitsfile *infptr, fitsfile *outfptr, int *status) /* Uncompress the table that was compressed with fits_compress_table */ { char colcode[999]; /* column data type code character */ char coltype[999]; /* column data type numeric code value */ char *cm_buffer; /* memory buffer for the transposed, Column-Major, chunk of the table */ char *rm_buffer; /* memory buffer for the original, Row-Major, chunk of the table */ LONGLONG nrows, rmajor_colwidth[999], rmajor_colstart[1000], cmajor_colstart[1000]; LONGLONG cmajor_repeat[999], rmajor_repeat[999], cmajor_bytespan[999], kk; LONGLONG headstart, datastart = 0, dataend, rowsremain, *descript, *qdescript = 0; LONGLONG rowstart, cvlalen, cvlastart, vlalen, vlastart; long repeat, width, vla_repeat, vla_address, rowspertile, ntile; int ncols, hdutype, inttype, anynull, tstatus, zctype[999], addspace = 0, *pdescript = 0; char *cptr, keyname[9], tform[40]; long pcount, zheapptr, naxis1, naxis2, ii, jj; char *ptr, comm[FLEN_COMMENT], zvalue[FLEN_VALUE], *uncompressed_vla = 0, *compressed_vla; char card[FLEN_CARD]; size_t dlen, fullsize, cm_size, bytepos, vlamemlen; /* ================================================================================== */ /* perform initial sanity checks */ /* ================================================================================== */ if (*status > 0) return(*status); fits_get_hdu_type(infptr, &hdutype, status); if (hdutype != BINARY_TBL) { ffpmsg("This is not a binary table, so cannot uncompress it!"); *status = NOT_BTABLE; return(*status); } if (fits_read_key(infptr, TLOGICAL, "ZTABLE", &tstatus, NULL, status)) { /* just copy the HDU if the table is not compressed */ if (infptr != outfptr) { fits_copy_hdu (infptr, outfptr, 0, status); } return(*status); } fits_get_num_rowsll(infptr, &nrows, status); fits_get_num_cols(infptr, &ncols, status); if ((ncols < 1)) { /* just copy the HDU if the table does not have more than 0 columns */ if (infptr != outfptr) { fits_copy_hdu (infptr, outfptr, 0, status); } return(*status); } fits_read_key(infptr, TLONG, "ZTILELEN", &rowspertile, comm, status); if (*status > 0) { ffpmsg("Could not find the required ZTILELEN keyword"); *status = DATA_DECOMPRESSION_ERR; return(*status); } /**** get size of the uncompressed table */ fits_read_key(infptr, TLONG, "ZNAXIS1", &naxis1, comm, status); if (*status > 0) { ffpmsg("Could not find the required ZNAXIS1 keyword"); *status = DATA_DECOMPRESSION_ERR; return(*status); } fits_read_key(infptr, TLONG, "ZNAXIS2", &naxis2, comm, status); if (*status > 0) { ffpmsg("Could not find the required ZNAXIS2 keyword"); *status = DATA_DECOMPRESSION_ERR; return(*status); } /* silently ignore illegal ZTILELEN value if too large */ if (rowspertile > naxis2) rowspertile = naxis2; fits_read_key(infptr, TLONG, "ZPCOUNT", &pcount, comm, status); if (*status > 0) { ffpmsg("Could not find the required ZPCOUNT keyword"); *status = DATA_DECOMPRESSION_ERR; return(*status); } tstatus = 0; fits_read_key(infptr, TLONG, "ZHEAPPTR", &zheapptr, comm, &tstatus); if (tstatus > 0) { zheapptr = 0; /* uncompressed table has no heap */ } /* ================================================================================== */ /* copy of the input header, then recreate the uncompressed table keywords */ /* ================================================================================== */ fits_copy_header(infptr, outfptr, status); /* reset the NAXIS1, NAXIS2. and PCOUNT keywords to the original */ fits_read_card(outfptr, "ZNAXIS1", card, status); strncpy(card, "NAXIS1 ", 7); fits_update_card(outfptr, "NAXIS1", card, status); fits_read_card(outfptr, "ZNAXIS2", card, status); strncpy(card, "NAXIS2 ", 7); fits_update_card(outfptr, "NAXIS2", card, status); fits_read_card(outfptr, "ZPCOUNT", card, status); strncpy(card, "PCOUNT ", 7); fits_update_card(outfptr, "PCOUNT", card, status); fits_delete_key(outfptr, "ZTABLE", status); fits_delete_key(outfptr, "ZTILELEN", status); fits_delete_key(outfptr, "ZNAXIS1", status); fits_delete_key(outfptr, "ZNAXIS2", status); fits_delete_key(outfptr, "ZPCOUNT", status); tstatus = 0; fits_delete_key(outfptr, "CHECKSUM", &tstatus); tstatus = 0; fits_delete_key(outfptr, "DATASUM", &tstatus); /* restore the Checksum keywords, if they exist */ tstatus = 0; fits_modify_name(outfptr, "ZHECKSUM", "CHECKSUM", &tstatus); tstatus = 0; fits_modify_name(outfptr, "ZDATASUM", "DATASUM", &tstatus); /* ================================================================================== */ /* determine compression paramters for each column and write column-specific keywords */ /* ================================================================================== */ for (ii = 0; ii < ncols; ii++) { /* get the original column type, repeat count, and unit width */ fits_make_keyn("ZFORM", ii+1, keyname, status); fits_read_key(infptr, TSTRING, keyname, tform, comm, status); /* restore the original TFORM value and comment */ fits_read_card(outfptr, keyname, card, status); card[0] = 'T'; keyname[0] = 'T'; fits_update_card(outfptr, keyname, card, status); /* now delete the ZFORM keyword */ keyname[0] = 'Z'; fits_delete_key(outfptr, keyname, status); cptr = tform; while(isdigit(*cptr)) cptr++; colcode[ii] = *cptr; /* save the column type code */ fits_binary_tform(tform, &inttype, &repeat, &width, status); coltype[ii] = inttype; /* deal with special cases */ if (abs(coltype[ii]) == TBIT) { repeat = (repeat + 7) / 8 ; /* convert from bits to bytes */ } else if (abs(coltype[ii]) == TSTRING) { width = 1; } else if (coltype[ii] < 0) { /* pointer to variable length array */ if (colcode[ii] == 'P') width = 8; /* this is a 'P' column */ else width = 16; /* this is a 'Q' not a 'P' column */ addspace += 16; /* need space for a second set of Q pointers for this column */ } rmajor_repeat[ii] = repeat; /* width (in bytes) of each field in the row-major table */ rmajor_colwidth[ii] = rmajor_repeat[ii] * width; /* construct the ZCTYPn keyword name then read the keyword */ fits_make_keyn("ZCTYP", ii+1, keyname, status); tstatus = 0; fits_read_key(infptr, TSTRING, keyname, zvalue, NULL, &tstatus); if (tstatus) { zctype[ii] = GZIP_2; } else { if (!strcmp(zvalue, "GZIP_2")) { zctype[ii] = GZIP_2; } else if (!strcmp(zvalue, "GZIP_1")) { zctype[ii] = GZIP_1; } else if (!strcmp(zvalue, "RICE_1")) { zctype[ii] = RICE_1; } else { ffpmsg("Unrecognized ZCTYPn keyword compression code:"); ffpmsg(zvalue); *status = DATA_DECOMPRESSION_ERR; return(*status); } /* delete this keyword from the uncompressed header */ fits_delete_key(outfptr, keyname, status); } } /* rescan header keywords to reset internal table structure parameters */ fits_set_hdustruc(outfptr, status); /* ================================================================================== */ /* allocate memory for the transposed and untransposed tile of the table */ /* ================================================================================== */ fullsize = naxis1 * rowspertile; cm_size = fullsize + (addspace * rowspertile); cm_buffer = malloc(cm_size); if (!cm_buffer) { ffpmsg("Could not allocate buffer for transformed column-major table"); *status = MEMORY_ALLOCATION; return(*status); } rm_buffer = malloc(fullsize); if (!rm_buffer) { ffpmsg("Could not allocate buffer for untransformed row-major table"); *status = MEMORY_ALLOCATION; free(cm_buffer); return(*status); } /* ================================================================================== */ /* Main loop over all the tiles */ /* ================================================================================== */ rowsremain = naxis2; rowstart = 1; ntile = 0; while(rowsremain) { /* ================================================================================== */ /* loop over each column: read and uncompress the bytes */ /* ================================================================================== */ ntile++; rmajor_colstart[0] = 0; cmajor_colstart[0] = 0; for (ii = 0; ii < ncols; ii++) { cmajor_repeat[ii] = rmajor_repeat[ii] * rowspertile; /* starting offset of each field in the column-major table */ if (coltype[ii] > 0) { /* normal fixed length column */ cmajor_colstart[ii + 1] = cmajor_colstart[ii] + rmajor_colwidth[ii] * rowspertile; } else { /* VLA column: reserve space for the 2nd set of Q pointers */ cmajor_colstart[ii + 1] = cmajor_colstart[ii] + (rmajor_colwidth[ii] + 16) * rowspertile; } /* length of each sequence of bytes, after sorting them in signicant order */ cmajor_bytespan[ii] = (rmajor_repeat[ii] * rowspertile); /* starting offset of each field in the row-major table */ rmajor_colstart[ii + 1] = rmajor_colstart[ii] + rmajor_colwidth[ii]; if (rmajor_repeat[ii] > 0) { /* ignore columns with 0 elements */ /* read compressed bytes from input table */ fits_read_descript(infptr, ii + 1, ntile, &vla_repeat, &vla_address, status); /* allocate memory and read in the compressed bytes */ ptr = malloc(vla_repeat); if (!ptr) { ffpmsg("Could not allocate buffer for uncompressed bytes"); *status = MEMORY_ALLOCATION; free(rm_buffer); free(cm_buffer); return(*status); } fits_set_tscale(infptr, ii + 1, 1.0, 0.0, status); /* turn off any data scaling, first */ fits_read_col_byt(infptr, ii + 1, ntile, 1, vla_repeat, 0, (unsigned char *) ptr, &anynull, status); cptr = cm_buffer + cmajor_colstart[ii]; /* size in bytes of the uncompressed column of bytes */ fullsize = (size_t) (cmajor_colstart[ii+1] - cmajor_colstart[ii]); switch (colcode[ii]) { case 'I': if (zctype[ii] == RICE_1) { dlen = fits_rdecomp_short((unsigned char *)ptr, vla_repeat, (unsigned short *)cptr, fullsize / 2, 32); #if BYTESWAPPED ffswap2((short *) cptr, fullsize / 2); #endif } else { /* gunzip the data into the correct location */ uncompress2mem_from_mem(ptr, vla_repeat, &cptr, &fullsize, realloc, &dlen, status); } break; case 'J': if (zctype[ii] == RICE_1) { dlen = fits_rdecomp ((unsigned char *) ptr, vla_repeat, (unsigned int *)cptr, fullsize / 4, 32); #if BYTESWAPPED ffswap4((int *) cptr, fullsize / 4); #endif } else { /* gunzip the data into the correct location */ uncompress2mem_from_mem(ptr, vla_repeat, &cptr, &fullsize, realloc, &dlen, status); } break; case 'B': if (zctype[ii] == RICE_1) { dlen = fits_rdecomp_byte ((unsigned char *) ptr, vla_repeat, (unsigned char *)cptr, fullsize, 32); } else { /* gunzip the data into the correct location */ uncompress2mem_from_mem(ptr, vla_repeat, &cptr, &fullsize, realloc, &dlen, status); } break; default: /* all variable length array columns are included in this case */ /* gunzip the data into the correct location in the full table buffer */ uncompress2mem_from_mem(ptr, vla_repeat, &cptr, &fullsize, realloc, &dlen, status); } /* end of switch block */ free(ptr); } /* end of rmajor_repeat > 0 */ } /* end of loop over columns */ /* now transpose the rows and columns (from cm_buffer to rm_buffer) */ /* move each byte, in turn, from the cm_buffer to the appropriate place in the rm_buffer */ for (ii = 0; ii < ncols; ii++) { /* loop over columns */ ptr = (char *) (cm_buffer + cmajor_colstart[ii]); /* initialize ptr to start of the column in the cm_buffer */ if (rmajor_repeat[ii] > 0) { /* skip columns with zero elements */ if (coltype[ii] > 0) { /* normal fixed length array columns */ if (zctype[ii] == GZIP_2) { /* need to unshuffle the bytes */ /* recombine the byte planes for the 2-byte, 4-byte, and 8-byte numeric columns */ switch (colcode[ii]) { case 'I': /* get the 1st byte of each I*2 value */ for (jj = 0; jj < rowspertile; jj++) { /* loop over number of rows in the output table */ cptr = rm_buffer + (rmajor_colstart[ii] + (jj * rmajor_colstart[ncols])); for (kk = 0; kk < rmajor_repeat[ii]; kk++) { *cptr = *ptr; /* copy 1 byte */ ptr++; cptr += 2; } } /* get the 2nd byte of each I*2 value */ for (jj = 0; jj < rowspertile; jj++) { /* loop over number of rows in the output table */ cptr = rm_buffer + (rmajor_colstart[ii] + (jj * rmajor_colstart[ncols]) + 1); for (kk = 0; kk < rmajor_repeat[ii]; kk++) { *cptr = *ptr; /* copy 1 byte */ ptr++; cptr += 2; } } break; case 'J': case 'E': /* get the 1st byte of each 4-byte value */ for (jj = 0; jj < rowspertile; jj++) { /* loop over number of rows in the output table */ cptr = rm_buffer + (rmajor_colstart[ii] + (jj * rmajor_colstart[ncols])); for (kk = 0; kk < rmajor_repeat[ii]; kk++) { *cptr = *ptr; /* copy 1 byte */ ptr++; cptr += 4; } } /* get the 2nd byte */ for (jj = 0; jj < rowspertile; jj++) { /* loop over number of rows in the output table */ cptr = rm_buffer + (rmajor_colstart[ii] + (jj * rmajor_colstart[ncols]) + 1); for (kk = 0; kk < rmajor_repeat[ii]; kk++) { *cptr = *ptr; /* copy 1 byte */ ptr++; cptr += 4; } } /* get the 3rd byte */ for (jj = 0; jj < rowspertile; jj++) { /* loop over number of rows in the output table */ cptr = rm_buffer + (rmajor_colstart[ii] + (jj * rmajor_colstart[ncols]) + 2); for (kk = 0; kk < rmajor_repeat[ii]; kk++) { *cptr = *ptr; /* copy 1 byte */ ptr++; cptr += 4; } } /* get the 4th byte */ for (jj = 0; jj < rowspertile; jj++) { /* loop over number of rows in the output table */ cptr = rm_buffer + (rmajor_colstart[ii] + (jj * rmajor_colstart[ncols]) + 3); for (kk = 0; kk < rmajor_repeat[ii]; kk++) { *cptr = *ptr; /* copy 1 byte */ ptr++; cptr += 4; } } break; case 'D': case 'K': /* get the 1st byte of each 8-byte value */ for (jj = 0; jj < rowspertile; jj++) { /* loop over number of rows in the output table */ cptr = rm_buffer + (rmajor_colstart[ii] + (jj * rmajor_colstart[ncols])); for (kk = 0; kk < rmajor_repeat[ii]; kk++) { *cptr = *ptr; /* copy 1 byte */ ptr++; cptr += 8; } } /* get the 2nd byte */ for (jj = 0; jj < rowspertile; jj++) { /* loop over number of rows in the output table */ cptr = rm_buffer + (rmajor_colstart[ii] + (jj * rmajor_colstart[ncols]) + 1); for (kk = 0; kk < rmajor_repeat[ii]; kk++) { *cptr = *ptr; /* copy 1 byte */ ptr++; cptr += 8; } } /* get the 3rd byte */ for (jj = 0; jj < rowspertile; jj++) { /* loop over number of rows in the output table */ cptr = rm_buffer + (rmajor_colstart[ii] + (jj * rmajor_colstart[ncols]) + 2); for (kk = 0; kk < rmajor_repeat[ii]; kk++) { *cptr = *ptr; /* copy 1 byte */ ptr++; cptr += 8; } } /* get the 4th byte */ for (jj = 0; jj < rowspertile; jj++) { /* loop over number of rows in the output table */ cptr = rm_buffer + (rmajor_colstart[ii] + (jj * rmajor_colstart[ncols]) + 3); for (kk = 0; kk < rmajor_repeat[ii]; kk++) { *cptr = *ptr; /* copy 1 byte */ ptr++; cptr += 8; } } /* get the 5th byte */ for (jj = 0; jj < rowspertile; jj++) { /* loop over number of rows in the output table */ cptr = rm_buffer + (rmajor_colstart[ii] + (jj * rmajor_colstart[ncols]) + 4); for (kk = 0; kk < rmajor_repeat[ii]; kk++) { *cptr = *ptr; /* copy 1 byte */ ptr++; cptr += 8; } } /* get the 6th byte */ for (jj = 0; jj < rowspertile; jj++) { /* loop over number of rows in the output table */ cptr = rm_buffer + (rmajor_colstart[ii] + (jj * rmajor_colstart[ncols]) + 5); for (kk = 0; kk < rmajor_repeat[ii]; kk++) { *cptr = *ptr; /* copy 1 byte */ ptr++; cptr += 8; } } /* get the 7th byte */ for (jj = 0; jj < rowspertile; jj++) { /* loop over number of rows in the output table */ cptr = rm_buffer + (rmajor_colstart[ii] + (jj * rmajor_colstart[ncols]) + 6); for (kk = 0; kk < rmajor_repeat[ii]; kk++) { *cptr = *ptr; /* copy 1 byte */ ptr++; cptr += 8; } } /* get the 8th byte */ for (jj = 0; jj < rowspertile; jj++) { /* loop over number of rows in the output table */ cptr = rm_buffer + (rmajor_colstart[ii] + (jj * rmajor_colstart[ncols]) + 7); for (kk = 0; kk < rmajor_repeat[ii]; kk++) { *cptr = *ptr; /* copy 1 byte */ ptr++; cptr += 8; } } break; default: /* should never get here */ ffpmsg("Error: unexpected attempt to use GZIP_2 to compress a column unsuitable data type"); *status = DATA_DECOMPRESSION_ERR; free(rm_buffer); free(cm_buffer); return(*status); } /* end of switch for shuffling the bytes*/ } else { /* not GZIP_2, don't have to shuffle bytes, so just transpose the rows and columns */ for (jj = 0; jj < rowspertile; jj++) { /* loop over number of rows in the output table */ cptr = rm_buffer + (rmajor_colstart[ii] + jj * rmajor_colstart[ncols]); /* addr to copy to */ memcpy(cptr, ptr, (size_t) rmajor_colwidth[ii]); ptr += (rmajor_colwidth[ii]); } } } else { /* transpose the variable length array pointers */ for (jj = 0; jj < rowspertile; jj++) { /* loop over number of rows in the output uncompressed table */ cptr = rm_buffer + (rmajor_colstart[ii] + jj * rmajor_colstart[ncols]); /* addr to copy to */ memcpy(cptr, ptr, (size_t) rmajor_colwidth[ii]); ptr += (rmajor_colwidth[ii]); } if (rmajor_colwidth[ii] == 8 ) { /* these are P-type descriptors */ pdescript = (int *) (cm_buffer + cmajor_colstart[ii]); #if BYTESWAPPED ffswap4((int *) pdescript, rowspertile * 2); /* byte-swap the descriptor */ #endif } else if (rmajor_colwidth[ii] == 16 ) { /* these are Q-type descriptors */ qdescript = (LONGLONG *) (cm_buffer + cmajor_colstart[ii]); #if BYTESWAPPED ffswap8((double *) qdescript, rowspertile * 2); /* byte-swap the descriptor */ #endif } else { /* this should never happen */ ffpmsg("Error: Descriptor column is neither 8 nor 16 bytes wide"); free(rm_buffer); free(cm_buffer); *status = DATA_DECOMPRESSION_ERR; return(*status); } /* First, set pointer to the Q descriptors, and byte-swap them, if needed */ descript = (LONGLONG*) (cm_buffer + cmajor_colstart[ii] + (rmajor_colwidth[ii] * rowspertile)); #if BYTESWAPPED /* byte-swap the descriptor */ ffswap8((double *) descript, rowspertile * 2); #endif /* now uncompress all the individual VLAs, and */ /* write them to their original location in the uncompressed file */ for (jj = 0; jj < rowspertile; jj++) { /* loop over rows */ /* get the size and location of the compressed VLA in the compressed table */ cvlalen = descript[jj * 2]; cvlastart = descript[(jj * 2) + 1]; if (cvlalen > 0 ) { /* get the size and location to write the uncompressed VLA in the uncompressed table */ if (rmajor_colwidth[ii] == 8 ) { vlalen = pdescript[jj * 2]; vlastart = pdescript[(jj * 2) + 1]; } else { vlalen = qdescript[jj * 2]; vlastart = qdescript[(jj * 2) + 1]; } vlamemlen = (size_t) (vlalen * (-coltype[ii] / 10)); /* size of the uncompressed VLA, in bytes */ /* allocate memory for the compressed vla */ compressed_vla = malloc( (size_t) cvlalen); if (!compressed_vla) { ffpmsg("Could not allocate buffer for compressed VLA"); free(rm_buffer); free(cm_buffer); *status = MEMORY_ALLOCATION; return(*status); } /* read the compressed VLA from the heap in the input compressed table */ bytepos = (size_t) ((infptr->Fptr)->datastart + (infptr->Fptr)->heapstart + cvlastart); ffmbyt(infptr, bytepos, REPORT_EOF, status); ffgbyt(infptr, cvlalen, compressed_vla, status); /* read the bytes */ /* if the VLA couldn't be compressed, just copy it directly to the output uncompressed table */ if (cvlalen == vlamemlen ) { bytepos = (size_t) ((outfptr->Fptr)->datastart + (outfptr->Fptr)->heapstart + vlastart); ffmbyt(outfptr, bytepos, IGNORE_EOF, status); ffpbyt(outfptr, cvlalen, compressed_vla, status); /* write the bytes */ } else { /* uncompress the VLA */ /* allocate memory for the uncompressed VLA */ uncompressed_vla = malloc(vlamemlen); if (!uncompressed_vla) { ffpmsg("Could not allocate buffer for uncompressed VLA"); *status = MEMORY_ALLOCATION; free(compressed_vla); free(rm_buffer); free(cm_buffer); return(*status); } /* uncompress the VLA with the appropriate algorithm */ if (zctype[ii] == RICE_1) { if (-coltype[ii] == TSHORT) { dlen = fits_rdecomp_short((unsigned char *) compressed_vla, (int) cvlalen, (unsigned short *)uncompressed_vla, (int) vlalen, 32); #if BYTESWAPPED ffswap2((short *) uncompressed_vla, (long) vlalen); #endif } else if (-coltype[ii] == TLONG) { dlen = fits_rdecomp((unsigned char *) compressed_vla, (int) cvlalen, (unsigned int *)uncompressed_vla, (int) vlalen, 32); #if BYTESWAPPED ffswap4((int *) uncompressed_vla, (long) vlalen); #endif } else if (-coltype[ii] == TBYTE) { dlen = fits_rdecomp_byte((unsigned char *) compressed_vla, (int) cvlalen, (unsigned char *) uncompressed_vla, (int) vlalen, 32); } else { /* this should not happen */ ffpmsg(" Error: cannot uncompress this column type with the RICE algorithm"); *status = DATA_DECOMPRESSION_ERR; free(uncompressed_vla); free(compressed_vla); free(rm_buffer); free(cm_buffer); return(*status); } } else if (zctype[ii] == GZIP_1 || zctype[ii] == GZIP_2){ /*: gzip uncompress the array of bytes */ uncompress2mem_from_mem( compressed_vla, (size_t) cvlalen, &uncompressed_vla, &vlamemlen, realloc, &vlamemlen, status); if (zctype[ii] == GZIP_2 ) { /* unshuffle the bytes after ungzipping them */ if ( (int) (-coltype[ii] / 10) == 2) { fits_unshuffle_2bytes((char *) uncompressed_vla, vlalen, status); } else if ( (int) (-coltype[ii] / 10) == 4) { fits_unshuffle_4bytes((char *) uncompressed_vla, vlalen, status); } else if ( (int) (-coltype[ii] / 10) == 8) { fits_unshuffle_8bytes((char *) uncompressed_vla, vlalen, status); } } } else { /* this should not happen */ ffpmsg(" Error: unknown compression algorithm"); free(uncompressed_vla); free(compressed_vla); free(rm_buffer); free(cm_buffer); *status = DATA_COMPRESSION_ERR; return(*status); } bytepos = (size_t) ((outfptr->Fptr)->datastart + (outfptr->Fptr)->heapstart + vlastart); ffmbyt(outfptr, bytepos, IGNORE_EOF, status); ffpbyt(outfptr, vlamemlen, uncompressed_vla, status); /* write the bytes */ free(uncompressed_vla); } /* end of uncompress VLA */ free(compressed_vla); } /* end of vlalen > 0 */ } /* end of loop over rowspertile */ } /* end of variable length array section*/ } /* end of if column repeat > 0 */ } /* end of ncols loop */ /* copy the buffer of data to the output data unit */ if (datastart == 0) fits_get_hduaddrll(outfptr, &headstart, &datastart, &dataend, status); ffmbyt(outfptr, datastart, 1, status); ffpbyt(outfptr, naxis1 * rowspertile, rm_buffer, status); /* increment pointers for next tile */ rowstart += rowspertile; rowsremain -= rowspertile; datastart += (naxis1 * rowspertile); if (rowspertile > rowsremain) rowspertile = (long) rowsremain; } /* end of while rows still remain */ free(rm_buffer); free(cm_buffer); /* reset internal table structure parameters */ fits_set_hdustruc(outfptr, status); return(*status); } /*--------------------------------------------------------------------------*/ static int fits_shuffle_2bytes(char *heap, LONGLONG length, int *status) /* shuffle the bytes in an array of 2-byte integers in the heap */ { LONGLONG ii; char *ptr, *cptr, *heapptr; ptr = malloc((size_t) (length * 2)); heapptr = heap; cptr = ptr; for (ii = 0; ii < length; ii++) { *cptr = *heapptr; heapptr++; *(cptr + length) = *heapptr; heapptr++; cptr++; } memcpy(heap, ptr, (size_t) (length * 2)); free(ptr); return(*status); } /*--------------------------------------------------------------------------*/ static int fits_shuffle_4bytes(char *heap, LONGLONG length, int *status) /* shuffle the bytes in an array of 4-byte integers or floats */ { LONGLONG ii; char *ptr, *cptr, *heapptr; ptr = malloc((size_t) (length * 4)); if (!ptr) { ffpmsg("malloc failed\n"); return(*status); } heapptr = heap; cptr = ptr; for (ii = 0; ii < length; ii++) { *cptr = *heapptr; heapptr++; *(cptr + length) = *heapptr; heapptr++; *(cptr + (length * 2)) = *heapptr; heapptr++; *(cptr + (length * 3)) = *heapptr; heapptr++; cptr++; } memcpy(heap, ptr, (size_t) (length * 4)); free(ptr); return(*status); } /*--------------------------------------------------------------------------*/ static int fits_shuffle_8bytes(char *heap, LONGLONG length, int *status) /* shuffle the bytes in an array of 8-byte integers or doubles in the heap */ { LONGLONG ii; char *ptr, *cptr, *heapptr; ptr = calloc(1, (size_t) (length * 8)); heapptr = heap; /* for some bizarre reason this loop fails to compile under OpenSolaris using the proprietary SunStudioExpress C compiler; use the following equivalent loop instead. cptr = ptr; for (ii = 0; ii < length; ii++) { *cptr = *heapptr; heapptr++; *(cptr + length) = *heapptr; heapptr++; *(cptr + (length * 2)) = *heapptr; heapptr++; *(cptr + (length * 3)) = *heapptr; heapptr++; *(cptr + (length * 4)) = *heapptr; heapptr++; *(cptr + (length * 5)) = *heapptr; heapptr++; *(cptr + (length * 6)) = *heapptr; heapptr++; *(cptr + (length * 7)) = *heapptr; heapptr++; cptr++; } */ for (ii = 0; ii < length; ii++) { cptr = ptr + ii; *cptr = *heapptr; heapptr++; cptr += length; *cptr = *heapptr; heapptr++; cptr += length; *cptr = *heapptr; heapptr++; cptr += length; *cptr = *heapptr; heapptr++; cptr += length; *cptr = *heapptr; heapptr++; cptr += length; *cptr = *heapptr; heapptr++; cptr += length; *cptr = *heapptr; heapptr++; cptr += length; *cptr = *heapptr; heapptr++; } memcpy(heap, ptr, (size_t) (length * 8)); free(ptr); return(*status); } /*--------------------------------------------------------------------------*/ static int fits_unshuffle_2bytes(char *heap, LONGLONG length, int *status) /* unshuffle the bytes in an array of 2-byte integers */ { LONGLONG ii; char *ptr, *cptr, *heapptr; ptr = malloc((size_t) (length * 2)); heapptr = heap + (2 * length) - 1; cptr = ptr + (2 * length) - 1; for (ii = 0; ii < length; ii++) { *cptr = *heapptr; cptr--; *cptr = *(heapptr - length); cptr--; heapptr--; } memcpy(heap, ptr, (size_t) (length * 2)); free(ptr); return(*status); } /*--------------------------------------------------------------------------*/ static int fits_unshuffle_4bytes(char *heap, LONGLONG length, int *status) /* unshuffle the bytes in an array of 4-byte integers or floats */ { LONGLONG ii; char *ptr, *cptr, *heapptr; ptr = malloc((size_t) (length * 4)); heapptr = heap + (4 * length) -1; cptr = ptr + (4 * length) -1; for (ii = 0; ii < length; ii++) { *cptr = *heapptr; cptr--; *cptr = *(heapptr - length); cptr--; *cptr = *(heapptr - (2 * length)); cptr--; *cptr = *(heapptr - (3 * length)); cptr--; heapptr--; } memcpy(heap, ptr, (size_t) (length * 4)); free(ptr); return(*status); } /*--------------------------------------------------------------------------*/ static int fits_unshuffle_8bytes(char *heap, LONGLONG length, int *status) /* unshuffle the bytes in an array of 8-byte integers or doubles */ { LONGLONG ii; char *ptr, *cptr, *heapptr; ptr = malloc((size_t) (length * 8)); heapptr = heap + (8 * length) - 1; cptr = ptr + (8 * length) -1; for (ii = 0; ii < length; ii++) { *cptr = *heapptr; cptr--; *cptr = *(heapptr - length); cptr--; *cptr = *(heapptr - (2 * length)); cptr--; *cptr = *(heapptr - (3 * length)); cptr--; *cptr = *(heapptr - (4 * length)); cptr--; *cptr = *(heapptr - (5 * length)); cptr--; *cptr = *(heapptr - (6 * length)); cptr--; *cptr = *(heapptr - (7 * length)); cptr--; heapptr--; } memcpy(heap, ptr, (size_t) (length * 8)); free(ptr); return(*status); } /*--------------------------------------------------------------------------*/ static int fits_int_to_longlong_inplace(int *intarray, long length, int *status) /* convert the input array of 32-bit integers into an array of 64-bit integers, in place. This will overwrite the input array with the new longer array starting at the same memory location. Note that aliasing the same memory location with pointers of different datatypes is not allowed in strict ANSI C99, however it is used here for efficency. In principle, one could simply copy the input array in reverse order to the output array, but this only works if the compiler performs the operation in strict order. Certain compiler optimization techniques may vioate this assumption. Therefore, we first copy a section of the input array to a temporary intermediate array, before copying the longer datatype values back to the original array. */ { LONGLONG *longlongarray, *aliasarray; long ii, ntodo, firstelem, nmax = 10000; if (*status > 0) return(*status); ntodo = nmax; if (length < nmax) ntodo = length; firstelem = length - ntodo; /* first element to be converted */ longlongarray = (LONGLONG *) malloc(ntodo * sizeof(LONGLONG)); if (longlongarray == NULL) { ffpmsg("Out of memory. (fits_int_to_longlong_inplace)"); return (*status = MEMORY_ALLOCATION); } aliasarray = (LONGLONG *) intarray; /* alias pointer to the input array */ while (ntodo > 0) { /* do datatype conversion into temp array */ for (ii = 0; ii < ntodo; ii++) { longlongarray[ii] = intarray[ii + firstelem]; } /* copy temp array back to alias */ memcpy(&(aliasarray[firstelem]), longlongarray, ntodo * 8); if (firstelem == 0) { /* we are all done */ ntodo = 0; } else { /* recalculate ntodo and firstelem for next loop */ if (firstelem > nmax) { firstelem -= nmax; } else { ntodo = firstelem; firstelem = 0; } } } free(longlongarray); return(*status); } /*--------------------------------------------------------------------------*/ static int fits_short_to_int_inplace(short *shortarray, long length, int shift, int *status) /* convert the input array of 16-bit integers into an array of 32-bit integers, in place. This will overwrite the input array with the new longer array starting at the same memory location. Note that aliasing the same memory location with pointers of different datatypes is not allowed in strict ANSI C99, however it is used here for efficency. In principle, one could simply copy the input array in reverse order to the output array, but this only works if the compiler performs the operation in strict order. Certain compiler optimization techniques may vioate this assumption. Therefore, we first copy a section of the input array to a temporary intermediate array, before copying the longer datatype values back to the original array. */ { int *intarray, *aliasarray; long ii, ntodo, firstelem, nmax = 10000; if (*status > 0) return(*status); ntodo = nmax; if (length < nmax) ntodo = length; firstelem = length - ntodo; /* first element to be converted */ intarray = (int *) malloc(ntodo * sizeof(int)); if (intarray == NULL) { ffpmsg("Out of memory. (fits_short_to_int_inplace)"); return (*status = MEMORY_ALLOCATION); } aliasarray = (int *) shortarray; /* alias pointer to the input array */ while (ntodo > 0) { /* do datatype conversion into temp array */ for (ii = 0; ii < ntodo; ii++) { intarray[ii] = (int)(shortarray[ii + firstelem]) + shift; } /* copy temp array back to alias */ memcpy(&(aliasarray[firstelem]), intarray, ntodo * 4); if (firstelem == 0) { /* we are all done */ ntodo = 0; } else { /* recalculate ntodo and firstelem for next loop */ if (firstelem > nmax) { firstelem -= nmax; } else { ntodo = firstelem; firstelem = 0; } } } free(intarray); return(*status); } /*--------------------------------------------------------------------------*/ static int fits_ushort_to_int_inplace(unsigned short *ushortarray, long length, int shift, int *status) /* convert the input array of 16-bit unsigned integers into an array of 32-bit integers, in place. This will overwrite the input array with the new longer array starting at the same memory location. Note that aliasing the same memory location with pointers of different datatypes is not allowed in strict ANSI C99, however it is used here for efficency. In principle, one could simply copy the input array in reverse order to the output array, but this only works if the compiler performs the operation in strict order. Certain compiler optimization techniques may vioate this assumption. Therefore, we first copy a section of the input array to a temporary intermediate array, before copying the longer datatype values back to the original array. */ { int *intarray, *aliasarray; long ii, ntodo, firstelem, nmax = 10000; if (*status > 0) return(*status); ntodo = nmax; if (length < nmax) ntodo = length; firstelem = length - ntodo; /* first element to be converted */ intarray = (int *) malloc(ntodo * sizeof(int)); if (intarray == NULL) { ffpmsg("Out of memory. (fits_ushort_to_int_inplace)"); return (*status = MEMORY_ALLOCATION); } aliasarray = (int *) ushortarray; /* alias pointer to the input array */ while (ntodo > 0) { /* do datatype conversion into temp array */ for (ii = 0; ii < ntodo; ii++) { intarray[ii] = (int)(ushortarray[ii + firstelem]) + shift; } /* copy temp array back to alias */ memcpy(&(aliasarray[firstelem]), intarray, ntodo * 4); if (firstelem == 0) { /* we are all done */ ntodo = 0; } else { /* recalculate ntodo and firstelem for next loop */ if (firstelem > nmax) { firstelem -= nmax; } else { ntodo = firstelem; firstelem = 0; } } } free(intarray); return(*status); } /*--------------------------------------------------------------------------*/ static int fits_ubyte_to_int_inplace(unsigned char *ubytearray, long length, int *status) /* convert the input array of 8-bit unsigned integers into an array of 32-bit integers, in place. This will overwrite the input array with the new longer array starting at the same memory location. Note that aliasing the same memory location with pointers of different datatypes is not allowed in strict ANSI C99, however it is used here for efficency. In principle, one could simply copy the input array in reverse order to the output array, but this only works if the compiler performs the operation in strict order. Certain compiler optimization techniques may vioate this assumption. Therefore, we first copy a section of the input array to a temporary intermediate array, before copying the longer datatype values back to the original array. */ { int *intarray, *aliasarray; long ii, ntodo, firstelem, nmax = 10000; if (*status > 0) return(*status); ntodo = nmax; if (length < nmax) ntodo = length; firstelem = length - ntodo; /* first element to be converted */ intarray = (int *) malloc(ntodo * sizeof(int)); if (intarray == NULL) { ffpmsg("Out of memory. (fits_ubyte_to_int_inplace)"); return (*status = MEMORY_ALLOCATION); } aliasarray = (int *) ubytearray; /* alias pointer to the input array */ while (ntodo > 0) { /* do datatype conversion into temp array */ for (ii = 0; ii < ntodo; ii++) { intarray[ii] = ubytearray[ii + firstelem]; } /* copy temp array back to alias */ memcpy(&(aliasarray[firstelem]), intarray, ntodo * 4); if (firstelem == 0) { /* we are all done */ ntodo = 0; } else { /* recalculate ntodo and firstelem for next loop */ if (firstelem > nmax) { firstelem -= nmax; } else { ntodo = firstelem; firstelem = 0; } } } free(intarray); return(*status); } /*--------------------------------------------------------------------------*/ static int fits_sbyte_to_int_inplace(signed char *sbytearray, long length, int *status) /* convert the input array of 8-bit signed integers into an array of 32-bit integers, in place. This will overwrite the input array with the new longer array starting at the same memory location. Note that aliasing the same memory location with pointers of different datatypes is not allowed in strict ANSI C99, however it is used here for efficency. In principle, one could simply copy the input array in reverse order to the output array, but this only works if the compiler performs the operation in strict order. Certain compiler optimization techniques may vioate this assumption. Therefore, we first copy a section of the input array to a temporary intermediate array, before copying the longer datatype values back to the original array. */ /* !!!!!!!!!!!!!!!!! NOTE THAT THIS IS A SPECIALIZED ROUTINE THAT ADDS AN OFFSET OF 128 TO THE ARRAY VALUES !!!!!!!!!!!!!!!!! */ { int *intarray, *aliasarray; long ii, ntodo, firstelem, nmax = 10000; if (*status > 0) return(*status); ntodo = nmax; if (length < nmax) ntodo = length; firstelem = length - ntodo; /* first element to be converted */ intarray = (int *) malloc(ntodo * sizeof(int)); if (intarray == NULL) { ffpmsg("Out of memory. (fits_sbyte_to_int_inplace)"); return (*status = MEMORY_ALLOCATION); } aliasarray = (int *) sbytearray; /* alias pointer to the input array */ while (ntodo > 0) { /* do datatype conversion into temp array */ for (ii = 0; ii < ntodo; ii++) { intarray[ii] = sbytearray[ii + firstelem] + 128; /* !! Note the offset !! */ } /* copy temp array back to alias */ memcpy(&(aliasarray[firstelem]), intarray, ntodo * 4); if (firstelem == 0) { /* we are all done */ ntodo = 0; } else { /* recalculate ntodo and firstelem for next loop */ if (firstelem > nmax) { firstelem -= nmax; } else { ntodo = firstelem; firstelem = 0; } } } free(intarray); return(*status); } int fits_calc_tile_rows(long *tlpixel, long *tfpixel, int ndim, long *trowsize, long *ntrows, int *status) { /* The quantizing algorithms treat all N-dimensional tiles as if they were 2 dimensions (trowsize * ntrows). This sets trowsize to the first dimensional size encountered that's > 1 (typically the X dimension). ntrows will then be the product of the remaining dimensional sizes. Examples: Tile = (5,4,1,3): trowsize=5, ntrows=12 Tile = (1,1,5): trowsize=5, ntrows=1 */ int ii; long np; if (*status) return (*status); *trowsize = 0; *ntrows = 1; for (ii=0; ii 1) { if (!(*trowsize)) *trowsize = np; else *ntrows *= np; } } if (!(*trowsize)) { /* Should only get here for the unusual case of all tile dimensions having size = 1 */ *trowsize = 1; } return (*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/iraffits.c0000644000175100001710000016066100000000000020110 0ustar00vstsdocker/*------------------------------------------------------------------------*/ /* */ /* These routines have been modified by William Pence for use by CFITSIO */ /* The original files were provided by Doug Mink */ /*------------------------------------------------------------------------*/ /* File imhfile.c * August 6, 1998 * By Doug Mink, based on Mike VanHilst's readiraf.c * Module: imhfile.c (IRAF .imh image file reading and writing) * Purpose: Read and write IRAF image files (and translate headers) * Subroutine: irafrhead (filename, lfhead, fitsheader, lihead) * Read IRAF image header * Subroutine: irafrimage (fitsheader) * Read IRAF image pixels (call after irafrhead) * Subroutine: same_path (pixname, hdrname) * Put filename and header path together * Subroutine: iraf2fits (hdrname, irafheader, nbiraf, nbfits) * Convert IRAF image header to FITS image header * Subroutine: irafgeti4 (irafheader, offset) * Get 4-byte integer from arbitrary part of IRAF header * Subroutine: irafgetc2 (irafheader, offset) * Get character string from arbitrary part of IRAF v.1 header * Subroutine: irafgetc (irafheader, offset) * Get character string from arbitrary part of IRAF header * Subroutine: iraf2str (irafstring, nchar) * Convert 2-byte/char IRAF string to 1-byte/char string * Subroutine: irafswap (bitpix,string,nbytes) * Swap bytes in string in place, with FITS bits/pixel code * Subroutine: irafswap2 (string,nbytes) * Swap bytes in string in place * Subroutine irafswap4 (string,nbytes) * Reverse bytes of Integer*4 or Real*4 vector in place * Subroutine irafswap8 (string,nbytes) * Reverse bytes of Real*8 vector in place * Copyright: 2000 Smithsonian Astrophysical Observatory * You may do anything you like with this file except remove * this copyright. The Smithsonian Astrophysical Observatory * makes no representations about the suitability of this * software for any purpose. It is provided "as is" without * express or implied warranty. */ #include "fitsio2.h" #include /* define stderr, FD, and NULL */ #include #include /* stddef.h is apparently needed to define size_t */ #include #define FILE_NOT_OPENED 104 /* Parameters from iraf/lib/imhdr.h for IRAF version 1 images */ #define SZ_IMPIXFILE 79 /* name of pixel storage file */ #define SZ_IMHDRFILE 79 /* length of header storage file */ #define SZ_IMTITLE 79 /* image title string */ #define LEN_IMHDR 2052 /* length of std header */ /* Parameters from iraf/lib/imhdr.h for IRAF version 2 images */ #define SZ_IM2PIXFILE 255 /* name of pixel storage file */ #define SZ_IM2HDRFILE 255 /* name of header storage file */ #define SZ_IM2TITLE 383 /* image title string */ #define LEN_IM2HDR 2046 /* length of std header */ /* Offsets into header in bytes for parameters in IRAF version 1 images */ #define IM_HDRLEN 12 /* Length of header in 4-byte ints */ #define IM_PIXTYPE 16 /* Datatype of the pixels */ #define IM_NDIM 20 /* Number of dimensions */ #define IM_LEN 24 /* Length (as stored) */ #define IM_PHYSLEN 52 /* Physical length (as stored) */ #define IM_PIXOFF 88 /* Offset of the pixels */ #define IM_CTIME 108 /* Time of image creation */ #define IM_MTIME 112 /* Time of last modification */ #define IM_LIMTIME 116 /* Time of min,max computation */ #define IM_MAX 120 /* Maximum pixel value */ #define IM_MIN 124 /* Maximum pixel value */ #define IM_PIXFILE 412 /* Name of pixel storage file */ #define IM_HDRFILE 572 /* Name of header storage file */ #define IM_TITLE 732 /* Image name string */ /* Offsets into header in bytes for parameters in IRAF version 2 images */ #define IM2_HDRLEN 6 /* Length of header in 4-byte ints */ #define IM2_PIXTYPE 10 /* Datatype of the pixels */ #define IM2_SWAPPED 14 /* Pixels are byte swapped */ #define IM2_NDIM 18 /* Number of dimensions */ #define IM2_LEN 22 /* Length (as stored) */ #define IM2_PHYSLEN 50 /* Physical length (as stored) */ #define IM2_PIXOFF 86 /* Offset of the pixels */ #define IM2_CTIME 106 /* Time of image creation */ #define IM2_MTIME 110 /* Time of last modification */ #define IM2_LIMTIME 114 /* Time of min,max computation */ #define IM2_MAX 118 /* Maximum pixel value */ #define IM2_MIN 122 /* Maximum pixel value */ #define IM2_PIXFILE 126 /* Name of pixel storage file */ #define IM2_HDRFILE 382 /* Name of header storage file */ #define IM2_TITLE 638 /* Image name string */ /* Codes from iraf/unix/hlib/iraf.h */ #define TY_CHAR 2 #define TY_SHORT 3 #define TY_INT 4 #define TY_LONG 5 #define TY_REAL 6 #define TY_DOUBLE 7 #define TY_COMPLEX 8 #define TY_POINTER 9 #define TY_STRUCT 10 #define TY_USHORT 11 #define TY_UBYTE 12 #define LEN_PIXHDR 1024 #define MAXINT 2147483647 /* Biggest number that can fit in long */ static int isirafswapped(char *irafheader, int offset); static int irafgeti4(char *irafheader, int offset); static char *irafgetc2(char *irafheader, int offset, int nc); static char *irafgetc(char *irafheader, int offset, int nc); static char *iraf2str(char *irafstring, int nchar); static char *irafrdhead(const char *filename, int *lihead); static int irafrdimage (char **buffptr, size_t *buffsize, size_t *filesize, int *status); static int iraftofits (char *hdrname, char *irafheader, int nbiraf, char **buffptr, size_t *nbfits, size_t *fitssize, int *status); static char *same_path(char *pixname, const char *hdrname); static int swaphead=0; /* =1 to swap data bytes of IRAF header values */ static int swapdata=0; /* =1 to swap bytes in IRAF data pixels */ static void irafswap(int bitpix, char *string, int nbytes); static void irafswap2(char *string, int nbytes); static void irafswap4(char *string, int nbytes); static void irafswap8(char *string, int nbytes); static int pix_version (char *irafheader); static int irafncmp (char *irafheader, char *teststring, int nc); static int machswap(void); static int head_version (char *irafheader); static int hgeti4(char* hstring, char* keyword, int* val); static int hgets(char* hstring, char* keyword, int lstr, char* string); static char* hgetc(char* hstring, char* keyword); static char* ksearch(char* hstring, char* keyword); static char *blsearch (char* hstring, char* keyword); static char *strsrch (char* s1, char* s2); static char *strnsrch ( char* s1,char* s2,int ls1); static void hputi4(char* hstring,char* keyword, int ival); static void hputs(char* hstring,char* keyword,char* cval); static void hputcom(char* hstring,char* keyword,char* comment); static void hputl(char* hstring,char* keyword,int lval); static void hputc(char* hstring,char* keyword,char* cval); static int getirafpixname (const char *hdrname, char *irafheader, char *pixfilename, int *status); int iraf2mem(char *filename, char **buffptr, size_t *buffsize, size_t *filesize, int *status); void ffpmsg(const char *err_message); /* CFITS_API is defined below for use on Windows systems. */ /* It is used to identify the public functions which should be exported. */ /* This has no effect on non-windows platforms where "WIN32" is not defined */ /* this is only needed to export the "fits_delete_iraf_file" symbol, which */ /* is called in fpackutil.c (and perhaps in other applications programs) */ #if defined (WIN32) #if defined(cfitsio_EXPORTS) #define CFITS_API __declspec(dllexport) #else #define CFITS_API //__declspec(dllimport) #endif /* CFITS_API */ #else /* defined (WIN32) */ #define CFITS_API #endif int CFITS_API fits_delete_iraf_file(const char *filename, int *status); /*--------------------------------------------------------------------------*/ int fits_delete_iraf_file(const char *filename, /* name of input file */ int *status) /* IO - error status */ /* Delete the iraf .imh header file and the associated .pix data file */ { char *irafheader; int lenirafhead; char pixfilename[SZ_IM2PIXFILE+1]; /* read IRAF header into dynamically created char array (free it later!) */ irafheader = irafrdhead(filename, &lenirafhead); if (!irafheader) { return(*status = FILE_NOT_OPENED); } getirafpixname (filename, irafheader, pixfilename, status); /* don't need the IRAF header any more */ free(irafheader); if (*status > 0) return(*status); remove(filename); remove(pixfilename); return(*status); } /*--------------------------------------------------------------------------*/ int iraf2mem(char *filename, /* name of input file */ char **buffptr, /* O - memory pointer (initially NULL) */ size_t *buffsize, /* O - size of mem buffer, in bytes */ size_t *filesize, /* O - size of FITS file, in bytes */ int *status) /* IO - error status */ /* Driver routine that reads an IRAF image into memory, also converting it into FITS format. */ { char *irafheader; int lenirafhead; *buffptr = NULL; *buffsize = 0; *filesize = 0; /* read IRAF header into dynamically created char array (free it later!) */ irafheader = irafrdhead(filename, &lenirafhead); if (!irafheader) { return(*status = FILE_NOT_OPENED); } /* convert IRAF header to FITS header in memory */ iraftofits(filename, irafheader, lenirafhead, buffptr, buffsize, filesize, status); /* don't need the IRAF header any more */ free(irafheader); if (*status > 0) return(*status); *filesize = (((*filesize - 1) / 2880 ) + 1 ) * 2880; /* multiple of 2880 */ /* append the image data onto the FITS header */ irafrdimage(buffptr, buffsize, filesize, status); return(*status); } /*--------------------------------------------------------------------------*/ /* Subroutine: irafrdhead (was irafrhead in D. Mink's original code) * Purpose: Open and read the iraf .imh file. * Returns: NULL if failure, else pointer to IRAF .imh image header * Notes: The imhdr format is defined in iraf/lib/imhdr.h, some of * which defines or mimicked, above. */ static char *irafrdhead ( const char *filename, /* Name of IRAF header file */ int *lihead) /* Length of IRAF image header in bytes (returned) */ { FILE *fd; int nbr; char *irafheader; char errmsg[FLEN_ERRMSG]; long nbhead; int nihead; *lihead = 0; /* open the image header file */ fd = fopen (filename, "rb"); if (fd == NULL) { ffpmsg("unable to open IRAF header file:"); ffpmsg(filename); return (NULL); } /* Find size of image header file */ if (fseek(fd, 0, 2) != 0) /* move to end of the file */ { ffpmsg("IRAFRHEAD: cannot seek in file:"); ffpmsg(filename); return(NULL); } nbhead = ftell(fd); /* position = size of file */ if (nbhead < 0) { ffpmsg("IRAFRHEAD: cannot get pos. in file:"); ffpmsg(filename); return(NULL); } if (fseek(fd, 0, 0) != 0) /* move back to beginning */ { ffpmsg("IRAFRHEAD: cannot seek to beginning of file:"); ffpmsg(filename); return(NULL); } /* allocate initial sized buffer */ nihead = nbhead + 5000; irafheader = (char *) calloc (1, nihead); if (irafheader == NULL) { snprintf(errmsg, FLEN_ERRMSG,"IRAFRHEAD Cannot allocate %d-byte header", nihead); ffpmsg(errmsg); ffpmsg(filename); return (NULL); } *lihead = nihead; /* Read IRAF header */ nbr = fread (irafheader, 1, nbhead, fd); fclose (fd); /* Reject if header less than minimum length */ if (nbr < LEN_PIXHDR) { snprintf(errmsg, FLEN_ERRMSG,"IRAFRHEAD header file: %d / %d bytes read.", nbr,LEN_PIXHDR); ffpmsg(errmsg); ffpmsg(filename); free (irafheader); return (NULL); } return (irafheader); } /*--------------------------------------------------------------------------*/ static int irafrdimage ( char **buffptr, /* FITS image header (filled) */ size_t *buffsize, /* allocated size of the buffer */ size_t *filesize, /* actual size of the FITS file */ int *status) { FILE *fd; char *bang; int nax = 1, naxis1 = 1, naxis2 = 1, naxis3 = 1, naxis4 = 1, npaxis1 = 1, npaxis2; int bitpix, bytepix, i; char *fitsheader, *image; int nbr, nbimage, nbaxis, nbl, nbdiff; char *pixheader; char *linebuff; int imhver, lpixhead = 0; char pixname[SZ_IM2PIXFILE+1]; char errmsg[FLEN_ERRMSG]; size_t newfilesize; fitsheader = *buffptr; /* pointer to start of header */ /* Convert pixel file name to character string */ hgets (fitsheader, "PIXFILE", SZ_IM2PIXFILE, pixname); hgeti4 (fitsheader, "PIXOFF", &lpixhead); /* Open pixel file, ignoring machine name if present */ if ((bang = strchr (pixname, '!')) != NULL ) fd = fopen (bang + 1, "rb"); else fd = fopen (pixname, "rb"); /* Print error message and exit if pixel file is not found */ if (!fd) { ffpmsg("IRAFRIMAGE: Cannot open IRAF pixel file:"); ffpmsg(pixname); return (*status = FILE_NOT_OPENED); } /* Read pixel header */ pixheader = (char *) calloc (lpixhead, 1); if (pixheader == NULL) { ffpmsg("IRAFRIMAGE: Cannot alloc memory for pixel header"); ffpmsg(pixname); fclose (fd); return (*status = FILE_NOT_OPENED); } nbr = fread (pixheader, 1, lpixhead, fd); /* Check size of pixel header */ if (nbr < lpixhead) { snprintf(errmsg, FLEN_ERRMSG,"IRAF pixel file: %d / %d bytes read.", nbr,LEN_PIXHDR); ffpmsg(errmsg); free (pixheader); fclose (fd); return (*status = FILE_NOT_OPENED); } /* check pixel header magic word */ imhver = pix_version (pixheader); if (imhver < 1) { ffpmsg("File not valid IRAF pixel file:"); ffpmsg(pixname); free (pixheader); fclose (fd); return (*status = FILE_NOT_OPENED); } free (pixheader); /* Find number of bytes to read */ hgeti4 (fitsheader,"NAXIS",&nax); hgeti4 (fitsheader,"NAXIS1",&naxis1); hgeti4 (fitsheader,"NPAXIS1",&npaxis1); if (nax > 1) { hgeti4 (fitsheader,"NAXIS2",&naxis2); hgeti4 (fitsheader,"NPAXIS2",&npaxis2); } if (nax > 2) hgeti4 (fitsheader,"NAXIS3",&naxis3); if (nax > 3) hgeti4 (fitsheader,"NAXIS4",&naxis4); hgeti4 (fitsheader,"BITPIX",&bitpix); if (bitpix < 0) bytepix = -bitpix / 8; else bytepix = bitpix / 8; nbimage = naxis1 * naxis2 * naxis3 * naxis4 * bytepix; newfilesize = *filesize + nbimage; /* header + data */ newfilesize = (((newfilesize - 1) / 2880 ) + 1 ) * 2880; if (newfilesize > *buffsize) /* need to allocate more memory? */ { fitsheader = (char *) realloc (*buffptr, newfilesize); if (fitsheader == NULL) { snprintf(errmsg, FLEN_ERRMSG,"IRAFRIMAGE Cannot allocate %d-byte image buffer", (int) (*filesize)); ffpmsg(errmsg); ffpmsg(pixname); fclose (fd); return (*status = FILE_NOT_OPENED); } } *buffptr = fitsheader; *buffsize = newfilesize; image = fitsheader + *filesize; *filesize = newfilesize; /* Read IRAF image all at once if physical and image dimensions are the same */ if (npaxis1 == naxis1) nbr = fread (image, 1, nbimage, fd); /* Read IRAF image one line at a time if physical and image dimensions differ */ else { nbdiff = (npaxis1 - naxis1) * bytepix; nbaxis = naxis1 * bytepix; linebuff = image; nbr = 0; if (naxis2 == 1 && naxis3 > 1) naxis2 = naxis3; for (i = 0; i < naxis2; i++) { nbl = fread (linebuff, 1, nbaxis, fd); nbr = nbr + nbl; fseek (fd, nbdiff, 1); linebuff = linebuff + nbaxis; } } fclose (fd); /* Check size of image */ if (nbr < nbimage) { snprintf(errmsg, FLEN_ERRMSG,"IRAF pixel file: %d / %d bytes read.", nbr,nbimage); ffpmsg(errmsg); ffpmsg(pixname); return (*status = FILE_NOT_OPENED); } /* Byte-reverse image, if necessary */ if (swapdata) irafswap (bitpix, image, nbimage); return (*status); } /*--------------------------------------------------------------------------*/ /* Return IRAF image format version number from magic word in IRAF header*/ static int head_version ( char *irafheader) /* IRAF image header from file */ { /* Check header file magic word */ if (irafncmp (irafheader, "imhdr", 5) != 0 ) { if (strncmp (irafheader, "imhv2", 5) != 0) return (0); else return (2); } else return (1); } /*--------------------------------------------------------------------------*/ /* Return IRAF image format version number from magic word in IRAF pixel file */ static int pix_version ( char *irafheader) /* IRAF image header from file */ { /* Check pixel file header magic word */ if (irafncmp (irafheader, "impix", 5) != 0) { if (strncmp (irafheader, "impv2", 5) != 0) return (0); else return (2); } else return (1); } /*--------------------------------------------------------------------------*/ /* Verify that file is valid IRAF imhdr or impix by checking first 5 chars * Returns: 0 on success, 1 on failure */ static int irafncmp ( char *irafheader, /* IRAF image header from file */ char *teststring, /* C character string to compare */ int nc) /* Number of characters to compate */ { char *line; if ((line = iraf2str (irafheader, nc)) == NULL) return (1); if (strncmp (line, teststring, nc) == 0) { free (line); return (0); } else { free (line); return (1); } } /*--------------------------------------------------------------------------*/ /* Convert IRAF image header to FITS image header, returning FITS header */ static int iraftofits ( char *hdrname, /* IRAF header file name (may be path) */ char *irafheader, /* IRAF image header */ int nbiraf, /* Number of bytes in IRAF header */ char **buffptr, /* pointer to the FITS header */ size_t *nbfits, /* allocated size of the FITS header buffer */ size_t *fitssize, /* Number of bytes in FITS header (returned) */ /* = number of bytes to the end of the END keyword */ int *status) { char *objname; /* object name from FITS file */ int lstr, i, j, k, ib, nax, nbits; char *pixname, *newpixname, *bang, *chead; char *fitsheader; int nblock, nlines; char *fhead, *fhead1, *fp, endline[81]; char irafchar; char fitsline[81]; int pixtype; int imhver, n, imu, pixoff, impixoff; /* int immax, immin, imtime; */ int imndim, imlen, imphyslen, impixtype; char errmsg[FLEN_ERRMSG]; /* Set up last line of FITS header */ (void)strncpy (endline,"END", 3); for (i = 3; i < 80; i++) endline[i] = ' '; endline[80] = 0; /* Check header magic word */ imhver = head_version (irafheader); if (imhver < 1) { ffpmsg("File not valid IRAF image header"); ffpmsg(hdrname); return(*status = FILE_NOT_OPENED); } if (imhver == 2) { nlines = 24 + ((nbiraf - LEN_IM2HDR) / 81); imndim = IM2_NDIM; imlen = IM2_LEN; imphyslen = IM2_PHYSLEN; impixtype = IM2_PIXTYPE; impixoff = IM2_PIXOFF; /* imtime = IM2_MTIME; */ /* immax = IM2_MAX; */ /* immin = IM2_MIN; */ } else { nlines = 24 + ((nbiraf - LEN_IMHDR) / 162); imndim = IM_NDIM; imlen = IM_LEN; imphyslen = IM_PHYSLEN; impixtype = IM_PIXTYPE; impixoff = IM_PIXOFF; /* imtime = IM_MTIME; */ /* immax = IM_MAX; */ /* immin = IM_MIN; */ } /* Initialize FITS header */ nblock = (nlines * 80) / 2880; *nbfits = (nblock + 5) * 2880 + 4; fitsheader = (char *) calloc (*nbfits, 1); if (fitsheader == NULL) { snprintf(errmsg, FLEN_ERRMSG,"IRAF2FITS Cannot allocate %d-byte FITS header", (int) (*nbfits)); ffpmsg(hdrname); return (*status = FILE_NOT_OPENED); } fhead = fitsheader; *buffptr = fitsheader; (void)strncpy (fitsheader, endline, 80); hputl (fitsheader, "SIMPLE", 1); fhead = fhead + 80; /* check if the IRAF file is in big endian (sun) format (= 0) or not. */ /* This is done by checking the 4 byte integer in the header that */ /* represents the iraf pixel type. This 4-byte word is guaranteed to */ /* have the least sig byte != 0 and the most sig byte = 0, so if the */ /* first byte of the word != 0, then the file in little endian format */ /* like on an Alpha machine. */ swaphead = isirafswapped(irafheader, impixtype); if (imhver == 1) swapdata = swaphead; /* vers 1 data has same swapness as header */ else swapdata = irafgeti4 (irafheader, IM2_SWAPPED); /* Set pixel size in FITS header */ pixtype = irafgeti4 (irafheader, impixtype); switch (pixtype) { case TY_CHAR: nbits = 8; break; case TY_UBYTE: nbits = 8; break; case TY_SHORT: nbits = 16; break; case TY_USHORT: nbits = -16; break; case TY_INT: case TY_LONG: nbits = 32; break; case TY_REAL: nbits = -32; break; case TY_DOUBLE: nbits = -64; break; default: snprintf(errmsg,FLEN_ERRMSG,"Unsupported IRAF data type: %d", pixtype); ffpmsg(errmsg); ffpmsg(hdrname); return (*status = FILE_NOT_OPENED); } hputi4 (fitsheader,"BITPIX",nbits); hputcom (fitsheader,"BITPIX", "IRAF .imh pixel type"); fhead = fhead + 80; /* Set image dimensions in FITS header */ nax = irafgeti4 (irafheader, imndim); hputi4 (fitsheader,"NAXIS",nax); hputcom (fitsheader,"NAXIS", "IRAF .imh naxis"); fhead = fhead + 80; n = irafgeti4 (irafheader, imlen); hputi4 (fitsheader, "NAXIS1", n); hputcom (fitsheader,"NAXIS1", "IRAF .imh image naxis[1]"); fhead = fhead + 80; if (nax > 1) { n = irafgeti4 (irafheader, imlen+4); hputi4 (fitsheader, "NAXIS2", n); hputcom (fitsheader,"NAXIS2", "IRAF .imh image naxis[2]"); fhead = fhead + 80; } if (nax > 2) { n = irafgeti4 (irafheader, imlen+8); hputi4 (fitsheader, "NAXIS3", n); hputcom (fitsheader,"NAXIS3", "IRAF .imh image naxis[3]"); fhead = fhead + 80; } if (nax > 3) { n = irafgeti4 (irafheader, imlen+12); hputi4 (fitsheader, "NAXIS4", n); hputcom (fitsheader,"NAXIS4", "IRAF .imh image naxis[4]"); fhead = fhead + 80; } /* Set object name in FITS header */ if (imhver == 2) objname = irafgetc (irafheader, IM2_TITLE, SZ_IM2TITLE); else objname = irafgetc2 (irafheader, IM_TITLE, SZ_IMTITLE); if ((lstr = strlen (objname)) < 8) { for (i = lstr; i < 8; i++) objname[i] = ' '; objname[8] = 0; } hputs (fitsheader,"OBJECT",objname); hputcom (fitsheader,"OBJECT", "IRAF .imh title"); free (objname); fhead = fhead + 80; /* Save physical axis lengths so image file can be read */ n = irafgeti4 (irafheader, imphyslen); hputi4 (fitsheader, "NPAXIS1", n); hputcom (fitsheader,"NPAXIS1", "IRAF .imh physical naxis[1]"); fhead = fhead + 80; if (nax > 1) { n = irafgeti4 (irafheader, imphyslen+4); hputi4 (fitsheader, "NPAXIS2", n); hputcom (fitsheader,"NPAXIS2", "IRAF .imh physical naxis[2]"); fhead = fhead + 80; } if (nax > 2) { n = irafgeti4 (irafheader, imphyslen+8); hputi4 (fitsheader, "NPAXIS3", n); hputcom (fitsheader,"NPAXIS3", "IRAF .imh physical naxis[3]"); fhead = fhead + 80; } if (nax > 3) { n = irafgeti4 (irafheader, imphyslen+12); hputi4 (fitsheader, "NPAXIS4", n); hputcom (fitsheader,"NPAXIS4", "IRAF .imh physical naxis[4]"); fhead = fhead + 80; } /* Save image header filename in header */ hputs (fitsheader,"IMHFILE",hdrname); hputcom (fitsheader,"IMHFILE", "IRAF header file name"); fhead = fhead + 80; /* Save image pixel file pathname in header */ if (imhver == 2) pixname = irafgetc (irafheader, IM2_PIXFILE, SZ_IM2PIXFILE); else pixname = irafgetc2 (irafheader, IM_PIXFILE, SZ_IMPIXFILE); if (strncmp(pixname, "HDR", 3) == 0 ) { newpixname = same_path (pixname, hdrname); if (newpixname) { free (pixname); pixname = newpixname; } } if (strchr (pixname, '/') == NULL && strchr (pixname, '$') == NULL) { newpixname = same_path (pixname, hdrname); if (newpixname) { free (pixname); pixname = newpixname; } } if ((bang = strchr (pixname, '!')) != NULL ) hputs (fitsheader,"PIXFILE",bang+1); else hputs (fitsheader,"PIXFILE",pixname); free (pixname); hputcom (fitsheader,"PIXFILE", "IRAF .pix pixel file"); fhead = fhead + 80; /* Save image offset from star of pixel file */ pixoff = irafgeti4 (irafheader, impixoff); pixoff = (pixoff - 1) * 2; hputi4 (fitsheader, "PIXOFF", pixoff); hputcom (fitsheader,"PIXOFF", "IRAF .pix pixel offset (Do not change!)"); fhead = fhead + 80; /* Save IRAF file format version in header */ hputi4 (fitsheader,"IMHVER",imhver); hputcom (fitsheader,"IMHVER", "IRAF .imh format version (1 or 2)"); fhead = fhead + 80; /* Save flag as to whether to swap IRAF data for this file and machine */ if (swapdata) hputl (fitsheader, "PIXSWAP", 1); else hputl (fitsheader, "PIXSWAP", 0); hputcom (fitsheader,"PIXSWAP", "IRAF pixels, FITS byte orders differ if T"); fhead = fhead + 80; /* Add user portion of IRAF header to FITS header */ fitsline[80] = 0; if (imhver == 2) { imu = LEN_IM2HDR; chead = irafheader; j = 0; for (k = 0; k < 80; k++) fitsline[k] = ' '; for (i = imu; i < nbiraf; i++) { irafchar = chead[i]; if (irafchar == 0) break; else if (irafchar == 10) { (void)strncpy (fhead, fitsline, 80); /* fprintf (stderr,"%80s\n",fitsline); */ if (strncmp (fitsline, "OBJECT ", 7) != 0) { fhead = fhead + 80; } for (k = 0; k < 80; k++) fitsline[k] = ' '; j = 0; } else { if (j > 80) { if (strncmp (fitsline, "OBJECT ", 7) != 0) { (void)strncpy (fhead, fitsline, 80); /* fprintf (stderr,"%80s\n",fitsline); */ j = 9; fhead = fhead + 80; } for (k = 0; k < 80; k++) fitsline[k] = ' '; } if (irafchar > 32 && irafchar < 127) fitsline[j] = irafchar; j++; } } } else { imu = LEN_IMHDR; chead = irafheader; if (swaphead == 1) ib = 0; else ib = 1; for (k = 0; k < 80; k++) fitsline[k] = ' '; j = 0; for (i = imu; i < nbiraf; i=i+2) { irafchar = chead[i+ib]; if (irafchar == 0) break; else if (irafchar == 10) { if (strncmp (fitsline, "OBJECT ", 7) != 0) { (void)strncpy (fhead, fitsline, 80); fhead = fhead + 80; } /* fprintf (stderr,"%80s\n",fitsline); */ j = 0; for (k = 0; k < 80; k++) fitsline[k] = ' '; } else { if (j > 80) { if (strncmp (fitsline, "OBJECT ", 7) != 0) { (void)strncpy (fhead, fitsline, 80); j = 9; fhead = fhead + 80; } /* fprintf (stderr,"%80s\n",fitsline); */ for (k = 0; k < 80; k++) fitsline[k] = ' '; } if (irafchar > 32 && irafchar < 127) fitsline[j] = irafchar; j++; } } } /* Add END to last line */ (void)strncpy (fhead, endline, 80); /* Find end of last 2880-byte block of header */ fhead = ksearch (fitsheader, "END") + 80; nblock = *nbfits / 2880; fhead1 = fitsheader + (nblock * 2880); *fitssize = fhead - fitsheader; /* no. of bytes to end of END keyword */ /* Pad rest of header with spaces */ strncpy (endline," ",3); for (fp = fhead; fp < fhead1; fp = fp + 80) { (void)strncpy (fp, endline,80); } return (*status); } /*--------------------------------------------------------------------------*/ /* get the IRAF pixel file name */ static int getirafpixname ( const char *hdrname, /* IRAF header file name (may be path) */ char *irafheader, /* IRAF image header */ char *pixfilename, /* IRAF pixel file name */ int *status) { int imhver; char *pixname, *newpixname, *bang; /* Check header magic word */ imhver = head_version (irafheader); if (imhver < 1) { ffpmsg("File not valid IRAF image header"); ffpmsg(hdrname); return(*status = FILE_NOT_OPENED); } /* get image pixel file pathname in header */ if (imhver == 2) pixname = irafgetc (irafheader, IM2_PIXFILE, SZ_IM2PIXFILE); else pixname = irafgetc2 (irafheader, IM_PIXFILE, SZ_IMPIXFILE); if (strncmp(pixname, "HDR", 3) == 0 ) { newpixname = same_path (pixname, hdrname); if (newpixname) { free (pixname); pixname = newpixname; } } if (strchr (pixname, '/') == NULL && strchr (pixname, '$') == NULL) { newpixname = same_path (pixname, hdrname); if (newpixname) { free (pixname); pixname = newpixname; } } if ((bang = strchr (pixname, '!')) != NULL ) strcpy(pixfilename,bang+1); else strcpy(pixfilename,pixname); free (pixname); return (*status); } /*--------------------------------------------------------------------------*/ /* Put filename and header path together */ static char *same_path ( char *pixname, /* IRAF pixel file pathname */ const char *hdrname) /* IRAF image header file pathname */ { int len; char *newpixname; /* WDP - 10/16/2007 - increased allocation to avoid possible overflow */ /* newpixname = (char *) calloc (SZ_IM2PIXFILE, sizeof (char)); */ newpixname = (char *) calloc (2*SZ_IM2PIXFILE+1, sizeof (char)); if (newpixname == NULL) { ffpmsg("iraffits same_path: Cannot alloc memory for newpixname"); return (NULL); } /* Pixel file is in same directory as header */ if (strncmp(pixname, "HDR$", 4) == 0 ) { (void)strncpy (newpixname, hdrname, SZ_IM2PIXFILE); /* find the end of the pathname */ len = strlen (newpixname); #ifndef VMS while( (len > 0) && (newpixname[len-1] != '/') ) #else while( (len > 0) && (newpixname[len-1] != ']') && (newpixname[len-1] != ':') ) #endif len--; /* add name */ newpixname[len] = '\0'; (void)strncat (newpixname, &pixname[4], SZ_IM2PIXFILE); } /* Bare pixel file with no path is assumed to be same as HDR$filename */ else if (strchr (pixname, '/') == NULL && strchr (pixname, '$') == NULL) { (void)strncpy (newpixname, hdrname, SZ_IM2PIXFILE); /* find the end of the pathname */ len = strlen (newpixname); #ifndef VMS while( (len > 0) && (newpixname[len-1] != '/') ) #else while( (len > 0) && (newpixname[len-1] != ']') && (newpixname[len-1] != ':') ) #endif len--; /* add name */ newpixname[len] = '\0'; (void)strncat (newpixname, pixname, SZ_IM2PIXFILE); } /* Pixel file has same name as header file, but with .pix extension */ else if (strncmp (pixname, "HDR", 3) == 0) { /* load entire header name string into name buffer */ (void)strncpy (newpixname, hdrname, SZ_IM2PIXFILE); len = strlen (newpixname); newpixname[len-3] = 'p'; newpixname[len-2] = 'i'; newpixname[len-1] = 'x'; } return (newpixname); } /*--------------------------------------------------------------------------*/ static int isirafswapped ( char *irafheader, /* IRAF image header */ int offset) /* Number of bytes to skip before number */ /* check if the IRAF file is in big endian (sun) format (= 0) or not */ /* This is done by checking the 4 byte integer in the header that */ /* represents the iraf pixel type. This 4-byte word is guaranteed to */ /* have the least sig byte != 0 and the most sig byte = 0, so if the */ /* first byte of the word != 0, then the file in little endian format */ /* like on an Alpha machine. */ { int swapped; if (irafheader[offset] != 0) swapped = 1; else swapped = 0; return (swapped); } /*--------------------------------------------------------------------------*/ static int irafgeti4 ( char *irafheader, /* IRAF image header */ int offset) /* Number of bytes to skip before number */ { char *ctemp, *cheader; int temp; cheader = irafheader; ctemp = (char *) &temp; if (machswap() != swaphead) { ctemp[3] = cheader[offset]; ctemp[2] = cheader[offset+1]; ctemp[1] = cheader[offset+2]; ctemp[0] = cheader[offset+3]; } else { ctemp[0] = cheader[offset]; ctemp[1] = cheader[offset+1]; ctemp[2] = cheader[offset+2]; ctemp[3] = cheader[offset+3]; } return (temp); } /*--------------------------------------------------------------------------*/ /* IRAFGETC2 -- Get character string from arbitrary part of v.1 IRAF header */ static char *irafgetc2 ( char *irafheader, /* IRAF image header */ int offset, /* Number of bytes to skip before string */ int nc) /* Maximum number of characters in string */ { char *irafstring, *string; irafstring = irafgetc (irafheader, offset, 2*(nc+1)); string = iraf2str (irafstring, nc); free (irafstring); return (string); } /*--------------------------------------------------------------------------*/ /* IRAFGETC -- Get character string from arbitrary part of IRAF header */ static char *irafgetc ( char *irafheader, /* IRAF image header */ int offset, /* Number of bytes to skip before string */ int nc) /* Maximum number of characters in string */ { char *ctemp, *cheader; int i; cheader = irafheader; ctemp = (char *) calloc (nc+1, 1); if (ctemp == NULL) { ffpmsg("IRAFGETC Cannot allocate memory for string variable"); return (NULL); } for (i = 0; i < nc; i++) { ctemp[i] = cheader[offset+i]; if (ctemp[i] > 0 && ctemp[i] < 32) ctemp[i] = ' '; } return (ctemp); } /*--------------------------------------------------------------------------*/ /* Convert IRAF 2-byte/char string to 1-byte/char string */ static char *iraf2str ( char *irafstring, /* IRAF 2-byte/character string */ int nchar) /* Number of characters in string */ { char *string; int i, j; string = (char *) calloc (nchar+1, 1); if (string == NULL) { ffpmsg("IRAF2STR Cannot allocate memory for string variable"); return (NULL); } /* the chars are in bytes 1, 3, 5, ... if bigendian format (SUN) */ /* else in bytes 0, 2, 4, ... if little endian format (Alpha) */ if (irafstring[0] != 0) j = 0; else j = 1; /* Convert appropriate byte of input to output character */ for (i = 0; i < nchar; i++) { string[i] = irafstring[j]; j = j + 2; } return (string); } /*--------------------------------------------------------------------------*/ /* IRAFSWAP -- Reverse bytes of any type of vector in place */ static void irafswap ( int bitpix, /* Number of bits per pixel */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ char *string, /* Address of starting point of bytes to swap */ int nbytes) /* Number of bytes to swap */ { switch (bitpix) { case 16: if (nbytes < 2) return; irafswap2 (string,nbytes); break; case 32: if (nbytes < 4) return; irafswap4 (string,nbytes); break; case -16: if (nbytes < 2) return; irafswap2 (string,nbytes); break; case -32: if (nbytes < 4) return; irafswap4 (string,nbytes); break; case -64: if (nbytes < 8) return; irafswap8 (string,nbytes); break; } return; } /*--------------------------------------------------------------------------*/ /* IRAFSWAP2 -- Swap bytes in string in place */ static void irafswap2 ( char *string, /* Address of starting point of bytes to swap */ int nbytes) /* Number of bytes to swap */ { char *sbyte, temp, *slast; slast = string + nbytes; sbyte = string; while (sbyte < slast) { temp = sbyte[0]; sbyte[0] = sbyte[1]; sbyte[1] = temp; sbyte= sbyte + 2; } return; } /*--------------------------------------------------------------------------*/ /* IRAFSWAP4 -- Reverse bytes of Integer*4 or Real*4 vector in place */ static void irafswap4 ( char *string, /* Address of Integer*4 or Real*4 vector */ int nbytes) /* Number of bytes to reverse */ { char *sbyte, *slast; char temp0, temp1, temp2, temp3; slast = string + nbytes; sbyte = string; while (sbyte < slast) { temp3 = sbyte[0]; temp2 = sbyte[1]; temp1 = sbyte[2]; temp0 = sbyte[3]; sbyte[0] = temp0; sbyte[1] = temp1; sbyte[2] = temp2; sbyte[3] = temp3; sbyte = sbyte + 4; } return; } /*--------------------------------------------------------------------------*/ /* IRAFSWAP8 -- Reverse bytes of Real*8 vector in place */ static void irafswap8 ( char *string, /* Address of Real*8 vector */ int nbytes) /* Number of bytes to reverse */ { char *sbyte, *slast; char temp[8]; slast = string + nbytes; sbyte = string; while (sbyte < slast) { temp[7] = sbyte[0]; temp[6] = sbyte[1]; temp[5] = sbyte[2]; temp[4] = sbyte[3]; temp[3] = sbyte[4]; temp[2] = sbyte[5]; temp[1] = sbyte[6]; temp[0] = sbyte[7]; sbyte[0] = temp[0]; sbyte[1] = temp[1]; sbyte[2] = temp[2]; sbyte[3] = temp[3]; sbyte[4] = temp[4]; sbyte[5] = temp[5]; sbyte[6] = temp[6]; sbyte[7] = temp[7]; sbyte = sbyte + 8; } return; } /*--------------------------------------------------------------------------*/ static int machswap (void) { char *ctest; int itest; itest = 1; ctest = (char *)&itest; if (*ctest) return (1); else return (0); } /*--------------------------------------------------------------------------*/ /* the following routines were originally in hget.c */ /*--------------------------------------------------------------------------*/ static int lhead0 = 0; /*--------------------------------------------------------------------------*/ /* Extract long value for variable from FITS header string */ static int hgeti4 (hstring,keyword,ival) char *hstring; /* character string containing FITS header information in the format = {/ } */ char *keyword; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ int *ival; { char *value; double dval; int minint; char val[30]; /* Get value and comment from header string */ value = hgetc (hstring,keyword); /* Translate value from ASCII to binary */ if (value != NULL) { minint = -MAXINT - 1; if (strlen(value) > 29) return(0); strcpy (val, value); dval = atof (val); if (dval+0.001 > MAXINT) *ival = MAXINT; else if (dval >= 0) *ival = (int) (dval + 0.001); else if (dval-0.001 < minint) *ival = minint; else *ival = (int) (dval - 0.001); return (1); } else { return (0); } } /*-------------------------------------------------------------------*/ /* Extract string value for variable from FITS header string */ static int hgets (hstring, keyword, lstr, str) char *hstring; /* character string containing FITS header information in the format = {/ } */ char *keyword; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ int lstr; /* Size of str in characters */ char *str; /* String (returned) */ { char *value; int lval; /* Get value and comment from header string */ value = hgetc (hstring,keyword); if (value != NULL) { lval = strlen (value); if (lval < lstr) strcpy (str, value); else if (lstr > 1) { strncpy (str, value, lstr-1); str[lstr-1]=0; } else { str[0] = value[0]; } return (1); } else return (0); } /*-------------------------------------------------------------------*/ /* Extract character value for variable from FITS header string */ static char * hgetc (hstring,keyword0) char *hstring; /* character string containing FITS header information in the format = {/ } */ char *keyword0; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ { static char cval[80]; char *value; char cwhite[2]; char squot[2], dquot[2], lbracket[2], rbracket[2], slash[2], comma[2]; char keyword[81]; /* large for ESO hierarchical keywords */ char line[100]; char *vpos, *cpar = NULL; char *q1, *q2 = NULL, *v1, *v2, *c1, *brack1, *brack2; char *saveptr; int ipar, i; squot[0] = 39; squot[1] = 0; dquot[0] = 34; dquot[1] = 0; lbracket[0] = 91; lbracket[1] = 0; comma[0] = 44; comma[1] = 0; rbracket[0] = 93; rbracket[1] = 0; slash[0] = 47; slash[1] = 0; /* Find length of variable name */ strncpy (keyword,keyword0, sizeof(keyword)-1); keyword[80]=0; brack1 = strsrch (keyword,lbracket); if (brack1 == NULL) brack1 = strsrch (keyword,comma); if (brack1 != NULL) { *brack1 = '\0'; brack1++; } /* Search header string for variable name */ vpos = ksearch (hstring,keyword); /* Exit if not found */ if (vpos == NULL) { return (NULL); } /* Initialize line to nulls */ for (i = 0; i < 100; i++) line[i] = 0; /* In standard FITS, data lasts until 80th character */ /* Extract entry for this variable from the header */ strncpy (line,vpos,80); /* check for quoted value */ q1 = strsrch (line,squot); c1 = strsrch (line,slash); if (q1 != NULL) { if (c1 != NULL && q1 < c1) q2 = strsrch (q1+1,squot); else if (c1 == NULL) q2 = strsrch (q1+1,squot); else q1 = NULL; } else { q1 = strsrch (line,dquot); if (q1 != NULL) { if (c1 != NULL && q1 < c1) q2 = strsrch (q1+1,dquot); else if (c1 == NULL) q2 = strsrch (q1+1,dquot); else q1 = NULL; } else { q1 = NULL; q2 = line + 10; } } /* Extract value and remove excess spaces */ if (q1 != NULL) { v1 = q1 + 1; v2 = q2; c1 = strsrch (q2,"/"); } else { v1 = strsrch (line,"=") + 1; c1 = strsrch (line,"/"); if (c1 != NULL) v2 = c1; else v2 = line + 79; } /* Ignore leading spaces */ while (*v1 == ' ' && v1 < v2) { v1++; } /* Drop trailing spaces */ *v2 = '\0'; v2--; while (*v2 == ' ' && v2 > v1) { *v2 = '\0'; v2--; } if (!strcmp (v1, "-0")) v1++; strcpy (cval,v1); value = cval; /* If keyword has brackets, extract appropriate token from value */ if (brack1 != NULL) { brack2 = strsrch (brack1,rbracket); if (brack2 != NULL) *brack2 = '\0'; ipar = atoi (brack1); if (ipar > 0) { cwhite[0] = ' '; cwhite[1] = '\0'; for (i = 1; i <= ipar; i++) { cpar = ffstrtok (v1,cwhite,&saveptr); v1 = NULL; } if (cpar != NULL) { strcpy (cval,cpar); } else value = NULL; } } return (value); } /*-------------------------------------------------------------------*/ /* Find beginning of fillable blank line before FITS header keyword line */ static char * blsearch (hstring,keyword) /* Find entry for keyword keyword in FITS header string hstring. (the keyword may have a maximum of eight letters) NULL is returned if the keyword is not found */ char *hstring; /* character string containing fits-style header information in the format = {/ } the default is that each entry is 80 characters long; however, lines may be of arbitrary length terminated by nulls, carriage returns or linefeeds, if packed is true. */ char *keyword; /* character string containing the name of the variable to be returned. ksearch searches for a line beginning with this string. The string may be a character literal or a character variable terminated by a null or '$'. it is truncated to 8 characters. */ { char *loc, *headnext, *headlast, *pval, *lc, *line; char *bval; int icol, nextchar, lkey, nleft, lhstr; pval = 0; /* Search header string for variable name */ if (lhead0) lhstr = lhead0; else { lhstr = 0; while (lhstr < 57600 && hstring[lhstr] != 0) lhstr++; } headlast = hstring + lhstr; headnext = hstring; pval = NULL; while (headnext < headlast) { nleft = headlast - headnext; loc = strnsrch (headnext, keyword, nleft); /* Exit if keyword is not found */ if (loc == NULL) { break; } icol = (loc - hstring) % 80; lkey = strlen (keyword); nextchar = (int) *(loc + lkey); /* If this is not in the first 8 characters of a line, keep searching */ if (icol > 7) headnext = loc + 1; /* If parameter name in header is longer, keep searching */ else if (nextchar != 61 && nextchar > 32 && nextchar < 127) headnext = loc + 1; /* If preceeding characters in line are not blanks, keep searching */ else { line = loc - icol; for (lc = line; lc < loc; lc++) { if (*lc != ' ') headnext = loc + 1; } /* Return pointer to start of line if match */ if (loc >= headnext) { pval = line; break; } } } /* Return NULL if keyword is found at start of FITS header string */ if (pval == NULL) return (pval); /* Return NULL if found the first keyword in the header */ if (pval == hstring) return (NULL); /* Find last nonblank line before requested keyword */ bval = pval - 80; while (!strncmp (bval," ",8)) bval = bval - 80; bval = bval + 80; /* Return pointer to calling program if blank lines found */ if (bval < pval) return (bval); else return (NULL); } /*-------------------------------------------------------------------*/ /* Find FITS header line containing specified keyword */ static char *ksearch (hstring,keyword) /* Find entry for keyword keyword in FITS header string hstring. (the keyword may have a maximum of eight letters) NULL is returned if the keyword is not found */ char *hstring; /* character string containing fits-style header information in the format = {/ } the default is that each entry is 80 characters long; however, lines may be of arbitrary length terminated by nulls, carriage returns or linefeeds, if packed is true. */ char *keyword; /* character string containing the name of the variable to be returned. ksearch searches for a line beginning with this string. The string may be a character literal or a character variable terminated by a null or '$'. it is truncated to 8 characters. */ { char *loc, *headnext, *headlast, *pval, *lc, *line; int icol, nextchar, lkey, nleft, lhstr; pval = 0; /* Search header string for variable name */ if (lhead0) lhstr = lhead0; else { lhstr = 0; while (lhstr < 57600 && hstring[lhstr] != 0) lhstr++; } headlast = hstring + lhstr; headnext = hstring; pval = NULL; while (headnext < headlast) { nleft = headlast - headnext; loc = strnsrch (headnext, keyword, nleft); /* Exit if keyword is not found */ if (loc == NULL) { break; } icol = (loc - hstring) % 80; lkey = strlen (keyword); nextchar = (int) *(loc + lkey); /* If this is not in the first 8 characters of a line, keep searching */ if (icol > 7) headnext = loc + 1; /* If parameter name in header is longer, keep searching */ else if (nextchar != 61 && nextchar > 32 && nextchar < 127) headnext = loc + 1; /* If preceeding characters in line are not blanks, keep searching */ else { line = loc - icol; for (lc = line; lc < loc; lc++) { if (*lc != ' ') headnext = loc + 1; } /* Return pointer to start of line if match */ if (loc >= headnext) { pval = line; break; } } } /* Return pointer to calling program */ return (pval); } /*-------------------------------------------------------------------*/ /* Find string s2 within null-terminated string s1 */ static char * strsrch (s1, s2) char *s1; /* String to search */ char *s2; /* String to look for */ { int ls1; ls1 = strlen (s1); return (strnsrch (s1, s2, ls1)); } /*-------------------------------------------------------------------*/ /* Find string s2 within string s1 */ static char * strnsrch (s1, s2, ls1) char *s1; /* String to search */ char *s2; /* String to look for */ int ls1; /* Length of string being searched */ { char *s,*s1e; char cfirst,clast; int i,ls2; /* Return null string if either pointer is NULL */ if (s1 == NULL || s2 == NULL) return (NULL); /* A zero-length pattern is found in any string */ ls2 = strlen (s2); if (ls2 ==0) return (s1); /* Only a zero-length string can be found in a zero-length string */ if (ls1 ==0) return (NULL); cfirst = s2[0]; clast = s2[ls2-1]; s1e = s1 + ls1 - ls2 + 1; s = s1; while (s < s1e) { /* Search for first character in pattern string */ if (*s == cfirst) { /* If single character search, return */ if (ls2 == 1) return (s); /* Search for last character in pattern string if first found */ if (s[ls2-1] == clast) { /* If two-character search, return */ if (ls2 == 2) return (s); /* If 3 or more characters, check for rest of search string */ i = 1; while (i < ls2 && s[i] == s2[i]) i++; /* If entire string matches, return */ if (i >= ls2) return (s); } } s++; } return (NULL); } /*-------------------------------------------------------------------*/ /* the following routines were originally in hget.c */ /*-------------------------------------------------------------------*/ /* HPUTI4 - Set int keyword = ival in FITS header string */ static void hputi4 (hstring,keyword,ival) char *hstring; /* character string containing FITS-style header information in the format = {/ } each entry is padded with spaces to 80 characters */ char *keyword; /* character string containing the name of the variable to be returned. hput searches for a line beginning with this string, and if there isn't one, creates one. The first 8 characters of keyword must be unique. */ int ival; /* int number */ { char value[30]; /* Translate value from binary to ASCII */ snprintf (value,30,"%d",ival); /* Put value into header string */ hputc (hstring,keyword,value); /* Return to calling program */ return; } /*-------------------------------------------------------------------*/ /* HPUTL - Set keyword = F if lval=0, else T, in FITS header string */ static void hputl (hstring, keyword,lval) char *hstring; /* FITS header */ char *keyword; /* Keyword name */ int lval; /* logical variable (0=false, else true) */ { char value[8]; /* Translate value from binary to ASCII */ if (lval) strcpy (value, "T"); else strcpy (value, "F"); /* Put value into header string */ hputc (hstring,keyword,value); /* Return to calling program */ return; } /*-------------------------------------------------------------------*/ /* HPUTS - Set character string keyword = 'cval' in FITS header string */ static void hputs (hstring,keyword,cval) char *hstring; /* FITS header */ char *keyword; /* Keyword name */ char *cval; /* character string containing the value for variable keyword. trailing and leading blanks are removed. */ { char squot = 39; char value[70]; int lcval; /* find length of variable string */ lcval = strlen (cval); if (lcval > 67) lcval = 67; /* Put quotes around string */ value[0] = squot; strncpy (&value[1],cval,lcval); value[lcval+1] = squot; value[lcval+2] = 0; /* Put value into header string */ hputc (hstring,keyword,value); /* Return to calling program */ return; } /*---------------------------------------------------------------------*/ /* HPUTC - Set character string keyword = value in FITS header string */ static void hputc (hstring,keyword,value) char *hstring; char *keyword; char *value; /* character string containing the value for variable keyword. trailing and leading blanks are removed. */ { char squot = 39; char line[100]; char newcom[50]; char blank[80]; char *v, *vp, *v1, *v2, *q1, *q2, *c1, *ve; int lkeyword, lcom, lval, lc, i; for (i = 0; i < 80; i++) blank[i] = ' '; /* find length of keyword and value */ lkeyword = strlen (keyword); lval = strlen (value); /* If COMMENT or HISTORY, always add it just before the END */ if (lkeyword == 7 && (strncmp (keyword,"COMMENT",7) == 0 || strncmp (keyword,"HISTORY",7) == 0)) { /* Find end of header */ v1 = ksearch (hstring,"END"); v2 = v1 + 80; /* Move END down one line */ strncpy (v2, v1, 80); /* Insert keyword */ strncpy (v1,keyword,7); /* Pad with spaces */ for (vp = v1+lkeyword; vp < v2; vp++) *vp = ' '; /* Insert comment */ strncpy (v1+9,value,lval); return; } /* Otherwise search for keyword */ else v1 = ksearch (hstring,keyword); /* If parameter is not found, find a place to put it */ if (v1 == NULL) { /* First look for blank lines before END */ v1 = blsearch (hstring, "END"); /* Otherwise, create a space for it at the end of the header */ if (v1 == NULL) { ve = ksearch (hstring,"END"); v1 = ve; v2 = v1 + 80; strncpy (v2, ve, 80); } else v2 = v1 + 80; lcom = 0; newcom[0] = 0; } /* Otherwise, extract the entry for this keyword from the header */ else { strncpy (line, v1, 80); line[80] = 0; v2 = v1 + 80; /* check for quoted value */ q1 = strchr (line, squot); if (q1 != NULL) q2 = strchr (q1+1,squot); else q2 = line; /* extract comment and remove trailing spaces */ c1 = strchr (q2,'/'); if (c1 != NULL) { lcom = 80 - (c1 - line); strncpy (newcom, c1+1, lcom); vp = newcom + lcom - 1; while (vp-- > newcom && *vp == ' ') *vp = 0; lcom = strlen (newcom); } else { newcom[0] = 0; lcom = 0; } } /* Fill new entry with spaces */ for (vp = v1; vp < v2; vp++) *vp = ' '; /* Copy keyword to new entry */ strncpy (v1, keyword, lkeyword); /* Add parameter value in the appropriate place */ vp = v1 + 8; *vp = '='; vp = v1 + 9; *vp = ' '; vp = vp + 1; if (*value == squot) { strncpy (vp, value, lval); if (lval+12 > 31) lc = lval + 12; else lc = 30; } else { vp = v1 + 30 - lval; strncpy (vp, value, lval); lc = 30; } /* Add comment in the appropriate place */ if (lcom > 0) { if (lc+2+lcom > 80) lcom = 78 - lc; vp = v1 + lc + 2; /* Jul 16 1997: was vp = v1 + lc * 2 */ *vp = '/'; vp = vp + 1; strncpy (vp, newcom, lcom); for (v = vp + lcom; v < v2; v++) *v = ' '; } return; } /*-------------------------------------------------------------------*/ /* HPUTCOM - Set comment for keyword or on line in FITS header string */ static void hputcom (hstring,keyword,comment) char *hstring; char *keyword; char *comment; { char squot; char line[100]; int lkeyword, lcom; char *vp, *v1, *v2, *c0 = NULL, *c1, *q1, *q2; squot = 39; /* Find length of variable name */ lkeyword = strlen (keyword); /* If COMMENT or HISTORY, always add it just before the END */ if (lkeyword == 7 && (strncmp (keyword,"COMMENT",7) == 0 || strncmp (keyword,"HISTORY",7) == 0)) { /* Find end of header */ v1 = ksearch (hstring,"END"); v2 = v1 + 80; strncpy (v2, v1, 80); /* blank out new line and insert keyword */ for (vp = v1; vp < v2; vp++) *vp = ' '; strncpy (v1, keyword, lkeyword); } /* search header string for variable name */ else { v1 = ksearch (hstring,keyword); v2 = v1 + 80; /* if parameter is not found, return without doing anything */ if (v1 == NULL) { return; } /* otherwise, extract entry for this variable from the header */ strncpy (line, v1, 80); /* check for quoted value */ q1 = strchr (line,squot); if (q1 != NULL) q2 = strchr (q1+1,squot); else q2 = NULL; if (q2 == NULL || q2-line < 31) c0 = v1 + 31; else c0 = v1 + (q2-line) + 2; /* allan: 1997-09-30, was c0=q2+2 */ strncpy (c0, "/ ",2); } /* create new entry */ lcom = strlen (comment); if (lcom > 0) { c1 = c0 + 2; if (c1+lcom > v2) lcom = v2 - c1; strncpy (c1, comment, lcom); } } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/longnam.h0000644000175100001710000005243000000000000017733 0ustar00vstsdocker#ifndef _LONGNAME_H #define _LONGNAME_H #define fits_parse_input_url ffiurl #define fits_parse_input_filename ffifile #define fits_parse_rootname ffrtnm #define fits_file_exists ffexist #define fits_parse_output_url ffourl #define fits_parse_extspec ffexts #define fits_parse_extnum ffextn #define fits_parse_binspec ffbins #define fits_parse_binrange ffbinr #define fits_parse_range ffrwrg #define fits_parse_rangell ffrwrgll #define fits_open_memfile ffomem /* use the following special macro to test that the fitsio.h include file that was used to build the CFITSIO library is compatible with the version as included when compiling the application program */ #define fits_open_file(A, B, C, D) ffopentest( CFITSIO_SONAME, A, B, C, D) #define fits_open_data ffdopn #define fits_open_extlist ffeopn #define fits_open_table fftopn #define fits_open_image ffiopn #define fits_open_diskfile ffdkopn #define fits_reopen_file ffreopen #define fits_create_file ffinit #define fits_create_diskfile ffdkinit #define fits_create_memfile ffimem #define fits_create_template fftplt #define fits_flush_file ffflus #define fits_flush_buffer ffflsh #define fits_close_file ffclos #define fits_delete_file ffdelt #define fits_file_name ffflnm #define fits_file_mode ffflmd #define fits_url_type ffurlt #define fits_get_version ffvers #define fits_uppercase ffupch #define fits_get_errstatus ffgerr #define fits_write_errmsg ffpmsg #define fits_write_errmark ffpmrk #define fits_read_errmsg ffgmsg #define fits_clear_errmsg ffcmsg #define fits_clear_errmark ffcmrk #define fits_report_error ffrprt #define fits_compare_str ffcmps #define fits_test_keyword fftkey #define fits_test_record fftrec #define fits_null_check ffnchk #define fits_make_keyn ffkeyn #define fits_make_nkey ffnkey #define fits_make_key ffmkky #define fits_get_keyclass ffgkcl #define fits_get_keytype ffdtyp #define fits_get_inttype ffinttyp #define fits_parse_value ffpsvc #define fits_get_keyname ffgknm #define fits_parse_template ffgthd #define fits_ascii_tform ffasfm #define fits_binary_tform ffbnfm #define fits_binary_tformll ffbnfmll #define fits_get_tbcol ffgabc #define fits_get_rowsize ffgrsz #define fits_get_col_display_width ffgcdw #define fits_write_record ffprec #define fits_write_key ffpky #define fits_write_key_unit ffpunt #define fits_write_comment ffpcom #define fits_write_history ffphis #define fits_write_date ffpdat #define fits_get_system_time ffgstm #define fits_get_system_date ffgsdt #define fits_date2str ffdt2s #define fits_time2str fftm2s #define fits_str2date ffs2dt #define fits_str2time ffs2tm #define fits_write_key_longstr ffpkls #define fits_write_key_longwarn ffplsw #define fits_write_key_null ffpkyu #define fits_write_key_str ffpkys #define fits_write_key_log ffpkyl #define fits_write_key_lng ffpkyj #define fits_write_key_ulng ffpkyuj #define fits_write_key_fixflt ffpkyf #define fits_write_key_flt ffpkye #define fits_write_key_fixdbl ffpkyg #define fits_write_key_dbl ffpkyd #define fits_write_key_fixcmp ffpkfc #define fits_write_key_cmp ffpkyc #define fits_write_key_fixdblcmp ffpkfm #define fits_write_key_dblcmp ffpkym #define fits_write_key_triple ffpkyt #define fits_write_tdim ffptdm #define fits_write_tdimll ffptdmll #define fits_write_keys_str ffpkns #define fits_write_keys_log ffpknl #define fits_write_keys_lng ffpknj #define fits_write_keys_fixflt ffpknf #define fits_write_keys_flt ffpkne #define fits_write_keys_fixdbl ffpkng #define fits_write_keys_dbl ffpknd #define fits_copy_key ffcpky #define fits_write_imghdr ffphps #define fits_write_imghdrll ffphpsll #define fits_write_grphdr ffphpr #define fits_write_grphdrll ffphprll #define fits_write_atblhdr ffphtb #define fits_write_btblhdr ffphbn #define fits_write_exthdr ffphext #define fits_write_key_template ffpktp #define fits_get_hdrspace ffghsp #define fits_get_hdrpos ffghps #define fits_movabs_key ffmaky #define fits_movrel_key ffmrky #define fits_find_nextkey ffgnxk #define fits_read_record ffgrec #define fits_read_card ffgcrd #define fits_read_str ffgstr #define fits_read_key_unit ffgunt #define fits_read_keyn ffgkyn #define fits_read_key ffgky #define fits_read_keyword ffgkey #define fits_read_key_str ffgkys #define fits_read_key_log ffgkyl #define fits_read_key_lng ffgkyj #define fits_read_key_lnglng ffgkyjj #define fits_read_key_ulnglng ffgkyujj #define fits_read_key_flt ffgkye #define fits_read_key_dbl ffgkyd #define fits_read_key_cmp ffgkyc #define fits_read_key_dblcmp ffgkym #define fits_read_key_triple ffgkyt #define fits_get_key_strlen ffgksl #define fits_read_key_longstr ffgkls #define fits_read_string_key ffgsky #define fits_free_memory fffree #define fits_read_tdim ffgtdm #define fits_read_tdimll ffgtdmll #define fits_decode_tdim ffdtdm #define fits_decode_tdimll ffdtdmll #define fits_read_keys_str ffgkns #define fits_read_keys_log ffgknl #define fits_read_keys_lng ffgknj #define fits_read_keys_lnglng ffgknjj #define fits_read_keys_flt ffgkne #define fits_read_keys_dbl ffgknd #define fits_read_imghdr ffghpr #define fits_read_imghdrll ffghprll #define fits_read_atblhdr ffghtb #define fits_read_btblhdr ffghbn #define fits_read_atblhdrll ffghtbll #define fits_read_btblhdrll ffghbnll #define fits_hdr2str ffhdr2str #define fits_convert_hdr2str ffcnvthdr2str #define fits_update_card ffucrd #define fits_update_key ffuky #define fits_update_key_null ffukyu #define fits_update_key_str ffukys #define fits_update_key_longstr ffukls #define fits_update_key_log ffukyl #define fits_update_key_lng ffukyj #define fits_update_key_fixflt ffukyf #define fits_update_key_flt ffukye #define fits_update_key_fixdbl ffukyg #define fits_update_key_dbl ffukyd #define fits_update_key_fixcmp ffukfc #define fits_update_key_cmp ffukyc #define fits_update_key_fixdblcmp ffukfm #define fits_update_key_dblcmp ffukym #define fits_modify_record ffmrec #define fits_modify_card ffmcrd #define fits_modify_name ffmnam #define fits_modify_comment ffmcom #define fits_modify_key_null ffmkyu #define fits_modify_key_str ffmkys #define fits_modify_key_longstr ffmkls #define fits_modify_key_log ffmkyl #define fits_modify_key_lng ffmkyj #define fits_modify_key_fixflt ffmkyf #define fits_modify_key_flt ffmkye #define fits_modify_key_fixdbl ffmkyg #define fits_modify_key_dbl ffmkyd #define fits_modify_key_fixcmp ffmkfc #define fits_modify_key_cmp ffmkyc #define fits_modify_key_fixdblcmp ffmkfm #define fits_modify_key_dblcmp ffmkym #define fits_insert_record ffirec #define fits_insert_card ffikey #define fits_insert_key_null ffikyu #define fits_insert_key_str ffikys #define fits_insert_key_longstr ffikls #define fits_insert_key_log ffikyl #define fits_insert_key_lng ffikyj #define fits_insert_key_fixflt ffikyf #define fits_insert_key_flt ffikye #define fits_insert_key_fixdbl ffikyg #define fits_insert_key_dbl ffikyd #define fits_insert_key_fixcmp ffikfc #define fits_insert_key_cmp ffikyc #define fits_insert_key_fixdblcmp ffikfm #define fits_insert_key_dblcmp ffikym #define fits_delete_key ffdkey #define fits_delete_str ffdstr #define fits_delete_record ffdrec #define fits_get_hdu_num ffghdn #define fits_get_hdu_type ffghdt #define fits_get_hduaddr ffghad #define fits_get_hduaddrll ffghadll #define fits_get_hduoff ffghof #define fits_get_img_param ffgipr #define fits_get_img_paramll ffgiprll #define fits_get_img_type ffgidt #define fits_get_img_equivtype ffgiet #define fits_get_img_dim ffgidm #define fits_get_img_size ffgisz #define fits_get_img_sizell ffgiszll #define fits_movabs_hdu ffmahd #define fits_movrel_hdu ffmrhd #define fits_movnam_hdu ffmnhd #define fits_get_num_hdus ffthdu #define fits_create_img ffcrim #define fits_create_imgll ffcrimll #define fits_create_tbl ffcrtb #define fits_create_hdu ffcrhd #define fits_insert_img ffiimg #define fits_insert_imgll ffiimgll #define fits_insert_atbl ffitab #define fits_insert_btbl ffibin #define fits_resize_img ffrsim #define fits_resize_imgll ffrsimll #define fits_delete_hdu ffdhdu #define fits_copy_hdu ffcopy #define fits_copy_file ffcpfl #define fits_copy_header ffcphd #define fits_copy_hdutab ffcpht #define fits_copy_data ffcpdt #define fits_write_hdu ffwrhdu #define fits_set_hdustruc ffrdef #define fits_set_hdrsize ffhdef #define fits_write_theap ffpthp #define fits_encode_chksum ffesum #define fits_decode_chksum ffdsum #define fits_write_chksum ffpcks #define fits_update_chksum ffupck #define fits_verify_chksum ffvcks #define fits_get_chksum ffgcks #define fits_set_bscale ffpscl #define fits_set_tscale fftscl #define fits_set_imgnull ffpnul #define fits_set_btblnull fftnul #define fits_set_atblnull ffsnul #define fits_get_colnum ffgcno #define fits_get_colname ffgcnn #define fits_get_coltype ffgtcl #define fits_get_coltypell ffgtclll #define fits_get_eqcoltype ffeqty #define fits_get_eqcoltypell ffeqtyll #define fits_get_num_rows ffgnrw #define fits_get_num_rowsll ffgnrwll #define fits_get_num_cols ffgncl #define fits_get_acolparms ffgacl #define fits_get_bcolparms ffgbcl #define fits_get_bcolparmsll ffgbclll #define fits_iterate_data ffiter #define fits_read_grppar_byt ffggpb #define fits_read_grppar_sbyt ffggpsb #define fits_read_grppar_usht ffggpui #define fits_read_grppar_ulng ffggpuj #define fits_read_grppar_ulnglng ffggpujj #define fits_read_grppar_sht ffggpi #define fits_read_grppar_lng ffggpj #define fits_read_grppar_lnglng ffggpjj #define fits_read_grppar_int ffggpk #define fits_read_grppar_uint ffggpuk #define fits_read_grppar_flt ffggpe #define fits_read_grppar_dbl ffggpd #define fits_read_pix ffgpxv #define fits_read_pixll ffgpxvll #define fits_read_pixnull ffgpxf #define fits_read_pixnullll ffgpxfll #define fits_read_img ffgpv #define fits_read_imgnull ffgpf #define fits_read_img_byt ffgpvb #define fits_read_img_sbyt ffgpvsb #define fits_read_img_usht ffgpvui #define fits_read_img_ulng ffgpvuj #define fits_read_img_sht ffgpvi #define fits_read_img_lng ffgpvj #define fits_read_img_ulnglng ffgpvujj #define fits_read_img_lnglng ffgpvjj #define fits_read_img_uint ffgpvuk #define fits_read_img_int ffgpvk #define fits_read_img_flt ffgpve #define fits_read_img_dbl ffgpvd #define fits_read_imgnull_byt ffgpfb #define fits_read_imgnull_sbyt ffgpfsb #define fits_read_imgnull_usht ffgpfui #define fits_read_imgnull_ulng ffgpfuj #define fits_read_imgnull_sht ffgpfi #define fits_read_imgnull_lng ffgpfj #define fits_read_imgnull_ulnglng ffgpfujj #define fits_read_imgnull_lnglng ffgpfjj #define fits_read_imgnull_uint ffgpfuk #define fits_read_imgnull_int ffgpfk #define fits_read_imgnull_flt ffgpfe #define fits_read_imgnull_dbl ffgpfd #define fits_read_2d_byt ffg2db #define fits_read_2d_sbyt ffg2dsb #define fits_read_2d_usht ffg2dui #define fits_read_2d_ulng ffg2duj #define fits_read_2d_sht ffg2di #define fits_read_2d_lng ffg2dj #define fits_read_2d_ulnglng ffg2dujj #define fits_read_2d_lnglng ffg2djj #define fits_read_2d_uint ffg2duk #define fits_read_2d_int ffg2dk #define fits_read_2d_flt ffg2de #define fits_read_2d_dbl ffg2dd #define fits_read_3d_byt ffg3db #define fits_read_3d_sbyt ffg3dsb #define fits_read_3d_usht ffg3dui #define fits_read_3d_ulng ffg3duj #define fits_read_3d_sht ffg3di #define fits_read_3d_lng ffg3dj #define fits_read_3d_ulnglng ffg3dujj #define fits_read_3d_lnglng ffg3djj #define fits_read_3d_uint ffg3duk #define fits_read_3d_int ffg3dk #define fits_read_3d_flt ffg3de #define fits_read_3d_dbl ffg3dd #define fits_read_subset ffgsv #define fits_read_subset_byt ffgsvb #define fits_read_subset_sbyt ffgsvsb #define fits_read_subset_usht ffgsvui #define fits_read_subset_ulng ffgsvuj #define fits_read_subset_sht ffgsvi #define fits_read_subset_lng ffgsvj #define fits_read_subset_ulnglng ffgsvujj #define fits_read_subset_lnglng ffgsvjj #define fits_read_subset_uint ffgsvuk #define fits_read_subset_int ffgsvk #define fits_read_subset_flt ffgsve #define fits_read_subset_dbl ffgsvd #define fits_read_subsetnull_byt ffgsfb #define fits_read_subsetnull_sbyt ffgsfsb #define fits_read_subsetnull_usht ffgsfui #define fits_read_subsetnull_ulng ffgsfuj #define fits_read_subsetnull_sht ffgsfi #define fits_read_subsetnull_lng ffgsfj #define fits_read_subsetnull_ulnglng ffgsfujj #define fits_read_subsetnull_lnglng ffgsfjj #define fits_read_subsetnull_uint ffgsfuk #define fits_read_subsetnull_int ffgsfk #define fits_read_subsetnull_flt ffgsfe #define fits_read_subsetnull_dbl ffgsfd #define ffcpimg fits_copy_image_section #define fits_compress_img fits_comp_img #define fits_decompress_img fits_decomp_img #define fits_read_col ffgcv #define fits_read_colnull ffgcf #define fits_read_col_str ffgcvs #define fits_read_col_log ffgcvl #define fits_read_col_byt ffgcvb #define fits_read_col_sbyt ffgcvsb #define fits_read_col_usht ffgcvui #define fits_read_col_ulng ffgcvuj #define fits_read_col_sht ffgcvi #define fits_read_col_lng ffgcvj #define fits_read_col_ulnglng ffgcvujj #define fits_read_col_lnglng ffgcvjj #define fits_read_col_uint ffgcvuk #define fits_read_col_int ffgcvk #define fits_read_col_flt ffgcve #define fits_read_col_dbl ffgcvd #define fits_read_col_cmp ffgcvc #define fits_read_col_dblcmp ffgcvm #define fits_read_col_bit ffgcx #define fits_read_col_bit_usht ffgcxui #define fits_read_col_bit_uint ffgcxuk #define fits_read_colnull_str ffgcfs #define fits_read_colnull_log ffgcfl #define fits_read_colnull_byt ffgcfb #define fits_read_colnull_sbyt ffgcfsb #define fits_read_colnull_usht ffgcfui #define fits_read_colnull_ulng ffgcfuj #define fits_read_colnull_sht ffgcfi #define fits_read_colnull_lng ffgcfj #define fits_read_colnull_ulnglng ffgcfujj #define fits_read_colnull_lnglng ffgcfjj #define fits_read_colnull_uint ffgcfuk #define fits_read_colnull_int ffgcfk #define fits_read_colnull_flt ffgcfe #define fits_read_colnull_dbl ffgcfd #define fits_read_colnull_cmp ffgcfc #define fits_read_colnull_dblcmp ffgcfm #define fits_read_descript ffgdes #define fits_read_descriptll ffgdesll #define fits_read_descripts ffgdess #define fits_read_descriptsll ffgdessll #define fits_read_tblbytes ffgtbb #define fits_write_grppar_byt ffpgpb #define fits_write_grppar_sbyt ffpgpsb #define fits_write_grppar_usht ffpgpui #define fits_write_grppar_ulng ffpgpuj #define fits_write_grppar_sht ffpgpi #define fits_write_grppar_lng ffpgpj #define fits_write_grppar_ulnglng ffpgpujj #define fits_write_grppar_lnglng ffpgpjj #define fits_write_grppar_uint ffpgpuk #define fits_write_grppar_int ffpgpk #define fits_write_grppar_flt ffpgpe #define fits_write_grppar_dbl ffpgpd #define fits_write_pix ffppx #define fits_write_pixll ffppxll #define fits_write_pixnull ffppxn #define fits_write_pixnullll ffppxnll #define fits_write_img ffppr #define fits_write_img_byt ffpprb #define fits_write_img_sbyt ffpprsb #define fits_write_img_usht ffpprui #define fits_write_img_ulng ffppruj #define fits_write_img_sht ffppri #define fits_write_img_lng ffpprj #define fits_write_img_ulnglng ffpprujj #define fits_write_img_lnglng ffpprjj #define fits_write_img_uint ffppruk #define fits_write_img_int ffpprk #define fits_write_img_flt ffppre #define fits_write_img_dbl ffpprd #define fits_write_imgnull ffppn #define fits_write_imgnull_byt ffppnb #define fits_write_imgnull_sbyt ffppnsb #define fits_write_imgnull_usht ffppnui #define fits_write_imgnull_ulng ffppnuj #define fits_write_imgnull_sht ffppni #define fits_write_imgnull_lng ffppnj #define fits_write_imgnull_ulnglng ffppnujj #define fits_write_imgnull_lnglng ffppnjj #define fits_write_imgnull_uint ffppnuk #define fits_write_imgnull_int ffppnk #define fits_write_imgnull_flt ffppne #define fits_write_imgnull_dbl ffppnd #define fits_write_img_null ffppru #define fits_write_null_img ffpprn #define fits_write_2d_byt ffp2db #define fits_write_2d_sbyt ffp2dsb #define fits_write_2d_usht ffp2dui #define fits_write_2d_ulng ffp2duj #define fits_write_2d_sht ffp2di #define fits_write_2d_lng ffp2dj #define fits_write_2d_ulnglng ffp2dujj #define fits_write_2d_lnglng ffp2djj #define fits_write_2d_uint ffp2duk #define fits_write_2d_int ffp2dk #define fits_write_2d_flt ffp2de #define fits_write_2d_dbl ffp2dd #define fits_write_3d_byt ffp3db #define fits_write_3d_sbyt ffp3dsb #define fits_write_3d_usht ffp3dui #define fits_write_3d_ulng ffp3duj #define fits_write_3d_sht ffp3di #define fits_write_3d_lng ffp3dj #define fits_write_3d_ulnglng ffp3dujj #define fits_write_3d_lnglng ffp3djj #define fits_write_3d_uint ffp3duk #define fits_write_3d_int ffp3dk #define fits_write_3d_flt ffp3de #define fits_write_3d_dbl ffp3dd #define fits_write_subset ffpss #define fits_write_subset_byt ffpssb #define fits_write_subset_sbyt ffpsssb #define fits_write_subset_usht ffpssui #define fits_write_subset_ulng ffpssuj #define fits_write_subset_sht ffpssi #define fits_write_subset_lng ffpssj #define fits_write_subset_ulnglng ffpssujj #define fits_write_subset_lnglng ffpssjj #define fits_write_subset_uint ffpssuk #define fits_write_subset_int ffpssk #define fits_write_subset_flt ffpsse #define fits_write_subset_dbl ffpssd #define fits_write_col ffpcl #define fits_write_col_str ffpcls #define fits_write_col_log ffpcll #define fits_write_col_byt ffpclb #define fits_write_col_sbyt ffpclsb #define fits_write_col_usht ffpclui #define fits_write_col_ulng ffpcluj #define fits_write_col_sht ffpcli #define fits_write_col_lng ffpclj #define fits_write_col_ulnglng ffpclujj #define fits_write_col_lnglng ffpcljj #define fits_write_col_uint ffpcluk #define fits_write_col_int ffpclk #define fits_write_col_flt ffpcle #define fits_write_col_dbl ffpcld #define fits_write_col_cmp ffpclc #define fits_write_col_dblcmp ffpclm #define fits_write_col_null ffpclu #define fits_write_col_bit ffpclx #define fits_write_nulrows ffprwu #define fits_write_nullrows ffprwu #define fits_write_colnull ffpcn #define fits_write_colnull_str ffpcns #define fits_write_colnull_log ffpcnl #define fits_write_colnull_byt ffpcnb #define fits_write_colnull_sbyt ffpcnsb #define fits_write_colnull_usht ffpcnui #define fits_write_colnull_ulng ffpcnuj #define fits_write_colnull_sht ffpcni #define fits_write_colnull_lng ffpcnj #define fits_write_colnull_ulnglng ffpcnujj #define fits_write_colnull_lnglng ffpcnjj #define fits_write_colnull_uint ffpcnuk #define fits_write_colnull_int ffpcnk #define fits_write_colnull_flt ffpcne #define fits_write_colnull_dbl ffpcnd #define fits_write_ext ffpextn #define fits_read_ext ffgextn #define fits_write_descript ffpdes #define fits_compress_heap ffcmph #define fits_test_heap fftheap #define fits_write_tblbytes ffptbb #define fits_insert_rows ffirow #define fits_delete_rows ffdrow #define fits_delete_rowrange ffdrrg #define fits_delete_rowlist ffdrws #define fits_delete_rowlistll ffdrwsll #define fits_insert_col fficol #define fits_insert_cols fficls #define fits_delete_col ffdcol #define fits_copy_col ffcpcl #define fits_copy_cols ffccls #define fits_copy_rows ffcprw #define fits_modify_vector_len ffmvec #define fits_read_img_coord ffgics #define fits_read_img_coord_version ffgicsa #define fits_read_tbl_coord ffgtcs #define fits_pix_to_world ffwldp #define fits_world_to_pix ffxypx #define fits_get_image_wcs_keys ffgiwcs #define fits_get_table_wcs_keys ffgtwcs #define fits_find_rows fffrow #define fits_find_first_row ffffrw #define fits_find_rows_cmp fffrwc #define fits_select_rows ffsrow #define fits_calc_rows ffcrow #define fits_calculator ffcalc #define fits_calculator_rng ffcalc_rng #define fits_test_expr fftexp #define fits_create_group ffgtcr #define fits_insert_group ffgtis #define fits_change_group ffgtch #define fits_remove_group ffgtrm #define fits_copy_group ffgtcp #define fits_merge_groups ffgtmg #define fits_compact_group ffgtcm #define fits_verify_group ffgtvf #define fits_open_group ffgtop #define fits_add_group_member ffgtam #define fits_get_num_members ffgtnm #define fits_get_num_groups ffgmng #define fits_open_member ffgmop #define fits_copy_member ffgmcp #define fits_transfer_member ffgmtf #define fits_remove_member ffgmrm #define fits_init_https ffihtps #define fits_cleanup_https ffchtps #define fits_verbose_https ffvhtps #define fits_show_download_progress ffshdwn #define fits_get_timeout ffgtmo #define fits_set_timeout ffstmo #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/modkey.c0000644000175100001710000020324100000000000017561 0ustar00vstsdocker/* This file, modkey.c, contains routines that modify, insert, or update */ /* keywords in a FITS header. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include /* stddef.h is apparently needed to define size_t */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffuky( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ const char *keyname,/* I - name of keyword to write */ void *value, /* I - keyword value */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Update the keyword, value and comment in the FITS header. The datatype is specified by the 2nd argument. */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (datatype == TSTRING) { ffukys(fptr, keyname, (char *) value, comm, status); } else if (datatype == TBYTE) { ffukyj(fptr, keyname, (LONGLONG) *(unsigned char *) value, comm, status); } else if (datatype == TSBYTE) { ffukyj(fptr, keyname, (LONGLONG) *(signed char *) value, comm, status); } else if (datatype == TUSHORT) { ffukyj(fptr, keyname, (LONGLONG) *(unsigned short *) value, comm, status); } else if (datatype == TSHORT) { ffukyj(fptr, keyname, (LONGLONG) *(short *) value, comm, status); } else if (datatype == TINT) { ffukyj(fptr, keyname, (LONGLONG) *(int *) value, comm, status); } else if (datatype == TUINT) { ffukyg(fptr, keyname, (double) *(unsigned int *) value, 0, comm, status); } else if (datatype == TLOGICAL) { ffukyl(fptr, keyname, *(int *) value, comm, status); } else if (datatype == TULONG) { ffukyg(fptr, keyname, (double) *(unsigned long *) value, 0, comm, status); } else if (datatype == TLONG) { ffukyj(fptr, keyname, (LONGLONG) *(long *) value, comm, status); } else if (datatype == TLONGLONG) { ffukyj(fptr, keyname, *(LONGLONG *) value, comm, status); } else if (datatype == TFLOAT) { ffukye(fptr, keyname, *(float *) value, -7, comm, status); } else if (datatype == TDOUBLE) { ffukyd(fptr, keyname, *(double *) value, -15, comm, status); } else if (datatype == TCOMPLEX) { ffukyc(fptr, keyname, (float *) value, -7, comm, status); } else if (datatype == TDBLCOMPLEX) { ffukym(fptr, keyname, (double *) value, -15, comm, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffukyu(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkyu(fptr, keyname, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkyu(fptr, keyname, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukys(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ const char *value, /* I - keyword value */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkys(fptr, keyname, value, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkys(fptr, keyname, value, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukls(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ const char *value, /* I - keyword value */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { /* update a long string keyword */ int tstatus; char junk[FLEN_ERRMSG]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkls(fptr, keyname, value, comm, status) == KEY_NO_EXIST) { /* since the ffmkls call failed, it wrote a bogus error message */ fits_read_errmsg(junk); /* clear the error message */ *status = tstatus; ffpkls(fptr, keyname, value, comm, status); } return(*status); }/*--------------------------------------------------------------------------*/ int ffukyl(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - keyword name */ int value, /* I - keyword value */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkyl(fptr, keyname, value, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkyl(fptr, keyname, value, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukyj(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - keyword name */ LONGLONG value, /* I - keyword value */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkyj(fptr, keyname, value, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkyj(fptr, keyname, value, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukyf(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - keyword name */ float value, /* I - keyword value */ int decim, /* I - no of decimals */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkyf(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkyf(fptr, keyname, value, decim, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukye(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - keyword name */ float value, /* I - keyword value */ int decim, /* I - no of decimals */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkye(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkye(fptr, keyname, value, decim, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukyg(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - keyword name */ double value, /* I - keyword value */ int decim, /* I - no of decimals */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkyg(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkyg(fptr, keyname, value, decim, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukyd(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - keyword name */ double value, /* I - keyword value */ int decim, /* I - no of decimals */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkyd(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkyd(fptr, keyname, value, decim, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukfc(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - keyword name */ float *value, /* I - keyword value */ int decim, /* I - no of decimals */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkfc(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkfc(fptr, keyname, value, decim, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukyc(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - keyword name */ float *value, /* I - keyword value */ int decim, /* I - no of decimals */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkyc(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkyc(fptr, keyname, value, decim, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukfm(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - keyword name */ double *value, /* I - keyword value */ int decim, /* I - no of decimals */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkfm(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkfm(fptr, keyname, value, decim, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukym(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - keyword name */ double *value, /* I - keyword value */ int decim, /* I - no of decimals */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkym(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkym(fptr, keyname, value, decim, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffucrd(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - keyword name */ const char *card, /* I - card string value */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmcrd(fptr, keyname, card, status) == KEY_NO_EXIST) { *status = tstatus; ffprec(fptr, card, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffmrec(fitsfile *fptr, /* I - FITS file pointer */ int nkey, /* I - number of the keyword to modify */ const char *card, /* I - card string value */ int *status) /* IO - error status */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffmaky(fptr, nkey+1, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmcrd(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ const char *card, /* I - card string value */ int *status) /* IO - error status */ { char tcard[FLEN_CARD], valstring[FLEN_CARD], comm[FLEN_CARD], value[FLEN_CARD]; char nextcomm[FLEN_COMMENT]; int keypos, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgcrd(fptr, keyname, tcard, status) > 0) return(*status); ffmkey(fptr, card, status); /* calc position of keyword in header */ keypos = (int) ((((fptr->Fptr)->nextkey) - ((fptr->Fptr)->headstart[(fptr->Fptr)->curhdu])) / 80) + 1; ffpsvc(tcard, valstring, comm, status); if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check for string value which may be continued over multiple keywords */ ffpmrk(); /* put mark on message stack; erase any messages after this */ ffc2s(valstring, value, status); /* remove quotes and trailing spaces */ if (*status == VALUE_UNDEFINED) { ffcmrk(); /* clear any spurious error messages, back to the mark */ *status = 0; } else { len = strlen(value); while (len && value[len - 1] == '&') /* ampersand used as continuation char */ { ffgcnt(fptr, value, nextcomm, status); if (*value) { ffdrec(fptr, keypos, status); /* delete the keyword */ len = strlen(value); } else /* a null valstring indicates no continuation */ len = 0; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffmnam(fitsfile *fptr, /* I - FITS file pointer */ const char *oldname,/* I - existing keyword name */ const char *newname,/* I - new name for keyword */ int *status) /* IO - error status */ { char comm[FLEN_COMMENT]; char value[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, oldname, value, comm, status) > 0) return(*status); ffmkky(newname, value, comm, card, status); /* construct the card */ ffmkey(fptr, card, status); /* rewrite with new name */ return(*status); } /*--------------------------------------------------------------------------*/ int ffmcom(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - keyword name */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char oldcomm[FLEN_COMMENT]; char value[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, value, oldcomm, status) > 0) return(*status); ffmkky(keyname, value, comm, card, status); /* construct the card */ ffmkey(fptr, card, status); /* rewrite with new comment */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpunt(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - keyword name */ const char *unit, /* I - keyword unit string */ int *status) /* IO - error status */ /* Write (put) the units string into the comment field of the existing keyword. This routine uses a FITS convention in which the units are enclosed in square brackets following the '/' comment field delimiter, e.g.: KEYWORD = 12 / [kpc] comment string goes here */ { char oldcomm[FLEN_COMMENT]; char newcomm[FLEN_COMMENT]; char value[FLEN_VALUE]; char card[FLEN_CARD]; char *loc; size_t len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, value, oldcomm, status) > 0) return(*status); /* copy the units string to the new comment string if not null */ if (*unit) { strcpy(newcomm, "["); strncat(newcomm, unit, 45); /* max allowed length is about 45 chars */ strcat(newcomm, "] "); len = strlen(newcomm); len = FLEN_COMMENT - len - 1; /* amount of space left in the field */ } else { newcomm[0] = '\0'; len = FLEN_COMMENT - 1; } if (oldcomm[0] == '[') /* check for existing units field */ { loc = strchr(oldcomm, ']'); /* look for the closing bracket */ if (loc) { loc++; while (*loc == ' ') /* skip any blank spaces */ loc++; strncat(newcomm, loc, len); /* concat remainder of comment */ } else { strncat(newcomm, oldcomm, len); /* append old comment onto new */ } } else { strncat(newcomm, oldcomm, len); } ffmkky(keyname, value, newcomm, card, status); /* construct the card */ ffmkey(fptr, card, status); /* rewrite with new units string */ return(*status); } /*--------------------------------------------------------------------------*/ int ffmkyu(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - keyword name */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ strcpy(valstring," "); /* create a dummy value string */ if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkys(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ const char *value, /* I - keyword value */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { /* NOTE: This routine does not support long continued strings */ /* It will correctly overwrite an existing long continued string, */ /* but it will not write a new long string. */ char oldval[FLEN_VALUE], valstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD], nextcomm[FLEN_COMMENT]; int len, keypos; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, oldval, oldcomm, status) > 0) return(*status); /* get old comment */ ffs2c(value, valstring, status); /* convert value to a string */ if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); /* overwrite the previous keyword */ keypos = (int) (((((fptr->Fptr)->nextkey) - ((fptr->Fptr)->headstart[(fptr->Fptr)->curhdu])) / 80) + 1); if (*status > 0) return(*status); /* check if old string value was continued over multiple keywords */ ffpmrk(); /* put mark on message stack; erase any messages after this */ ffc2s(oldval, valstring, status); /* remove quotes and trailing spaces */ if (*status == VALUE_UNDEFINED) { ffcmrk(); /* clear any spurious error messages, back to the mark */ *status = 0; } else { len = strlen(valstring); while (len && valstring[len - 1] == '&') /* ampersand is continuation char */ { ffgcnt(fptr, valstring, nextcomm, status); if (*valstring) { ffdrec(fptr, keypos, status); /* delete the continuation */ len = strlen(valstring); } else /* a null valstring indicates no continuation */ len = 0; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffmkls( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - name of keyword to write */ const char *value, /* I - keyword value */ const char *incomm, /* I - keyword comment */ int *status) /* IO - error status */ /* Modify the value and optionally the comment of a long string keyword. This routine supports the HEASARC long string convention and can modify arbitrarily long string keyword values. The value is continued over multiple keywords that have the name COMTINUE without an equal sign in column 9 of the card. This routine also supports simple string keywords which are less than 69 characters in length. This routine is not very efficient, so it should be used sparingly. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD], tmpkeyname[FLEN_CARD]; char comm[FLEN_COMMENT]; char tstring[FLEN_VALUE], *cptr; char *longval; int next, remain, vlen, nquote, nchar, namelen, contin, tstatus = -1; int nkeys, keypos; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (!incomm || incomm[0] == '&') /* preserve the old comment string */ { ffghps(fptr, &nkeys, &keypos, status); /* save current position */ if (ffgkls(fptr, keyname, &longval, comm, status) > 0) return(*status); /* keyword doesn't exist */ free(longval); /* don't need the old value */ /* move back to previous position to ensure that we delete */ /* the right keyword in case there are more than one keyword */ /* with this same name. */ ffgrec(fptr, keypos - 1, card, status); } else { /* copy the input comment string */ strncpy(comm, incomm, FLEN_COMMENT-1); comm[FLEN_COMMENT-1] = '\0'; } /* delete the old keyword */ if (ffdkey(fptr, keyname, status) > 0) return(*status); /* keyword doesn't exist */ ffghps(fptr, &nkeys, &keypos, status); /* save current position */ /* now construct the new keyword, and insert into header */ remain = strlen(value); /* number of characters to write out */ next = 0; /* pointer to next character to write */ /* count the number of single quote characters in the string */ nquote = 0; cptr = strchr(value, '\''); /* search for quote character */ while (cptr) /* search for quote character */ { nquote++; /* increment no. of quote characters */ cptr++; /* increment pointer to next character */ cptr = strchr(cptr, '\''); /* search for another quote char */ } strncpy(tmpkeyname, keyname, 80); tmpkeyname[80] = '\0'; cptr = tmpkeyname; while(*cptr == ' ') /* skip over leading spaces in name */ cptr++; /* determine the number of characters that will fit on the line */ /* Note: each quote character is expanded to 2 quotes */ namelen = strlen(cptr); if (namelen <= 8 && (fftkey(cptr, &tstatus) <= 0) ) { /* This a normal 8-character FITS keyword */ nchar = 68 - nquote; /* max of 68 chars fit in a FITS string value */ } else { nchar = 80 - nquote - namelen - 5; } contin = 0; while (remain > 0) { if (nchar > FLEN_VALUE-1) { ffpmsg("longstr keyword value is too long (ffmkls)"); return (*status=BAD_KEYCHAR); } strncpy(tstring, &value[next], nchar); /* copy string to temp buff */ tstring[nchar] = '\0'; ffs2c(tstring, valstring, status); /* put quotes around the string */ if (remain > nchar) /* if string is continued, put & as last char */ { vlen = strlen(valstring); nchar -= 1; /* outputting one less character now */ if (valstring[vlen-2] != '\'') valstring[vlen-2] = '&'; /* over write last char with & */ else { /* last char was a pair of single quotes, so over write both */ valstring[vlen-3] = '&'; valstring[vlen-1] = '\0'; } } if (contin) /* This is a CONTINUEd keyword */ { ffmkky("CONTINUE", valstring, comm, card, status); /* make keyword */ strncpy(&card[8], " ", 2); /* overwrite the '=' */ } else { ffmkky(keyname, valstring, comm, card, status); /* make keyword */ } ffirec(fptr, keypos, card, status); /* insert the keyword */ keypos++; /* next insert position */ contin = 1; remain -= nchar; next += nchar; nchar = 68 - nquote; } return(*status); } /*--------------------------------------------------------------------------*/ int ffmkyl(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ int value, /* I - keyword value */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ ffl2c(value, valstring, status); /* convert value to a string */ if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkyj(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ LONGLONG value, /* I - keyword value */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ ffi2c(value, valstring, status); /* convert value to a string */ if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkyf(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ float value, /* I - keyword value */ int decim, /* I - no of decimals */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ ffr2f(value, decim, valstring, status); /* convert value to a string */ if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkye(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ float value, /* I - keyword value */ int decim, /* I - no of decimals */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ ffr2e(value, decim, valstring, status); /* convert value to a string */ if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkyg(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ double value, /* I - keyword value */ int decim, /* I - no of decimals */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ ffd2f(value, decim, valstring, status); /* convert value to a string */ if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkyd(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ double value, /* I - keyword value */ int decim, /* I - no of decimals */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ ffd2e(value, decim, valstring, status); /* convert value to a string */ if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkfc(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ float *value, /* I - keyword value */ int decim, /* I - no of decimals */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ strcpy(valstring, "(" ); ffr2f(value[0], decim, tmpstring, status); /* convert to string */ if (strlen(tmpstring)+3 > FLEN_VALUE-1) { ffpmsg("complex key value too long (ffmkfc)"); return(*status=BAD_F2C); } strcat(valstring, tmpstring); strcat(valstring, ", "); ffr2f(value[1], decim, tmpstring, status); /* convert to string */ if (strlen(valstring) + strlen(tmpstring)+1 > FLEN_VALUE-1) { ffpmsg("complex key value too long (ffmkfc)"); return(*status=BAD_F2C); } strcat(valstring, tmpstring); strcat(valstring, ")"); if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkyc(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ float *value, /* I - keyword value */ int decim, /* I - no of decimals */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ strcpy(valstring, "(" ); ffr2e(value[0], decim, tmpstring, status); /* convert to string */ if (strlen(tmpstring)+3 > FLEN_VALUE-1) { ffpmsg("complex key value too long (ffmkyc)"); return(*status=BAD_F2C); } strcat(valstring, tmpstring); strcat(valstring, ", "); ffr2e(value[1], decim, tmpstring, status); /* convert to string */ if (strlen(valstring) + strlen(tmpstring)+1 > FLEN_VALUE-1) { ffpmsg("complex key value too long (ffmkyc)"); return(*status=BAD_F2C); } strcat(valstring, tmpstring); strcat(valstring, ")"); if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkfm(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ double *value, /* I - keyword value */ int decim, /* I - no of decimals */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ strcpy(valstring, "(" ); ffd2f(value[0], decim, tmpstring, status); /* convert to string */ if (strlen(tmpstring)+3 > FLEN_VALUE-1) { ffpmsg("complex key value too long (ffmkfm)"); return(*status=BAD_F2C); } strcat(valstring, tmpstring); strcat(valstring, ", "); ffd2f(value[1], decim, tmpstring, status); /* convert to string */ if (strlen(valstring) + strlen(tmpstring)+1 > FLEN_VALUE-1) { ffpmsg("complex key value too long (ffmkfm)"); return(*status=BAD_F2C); } strcat(valstring, tmpstring); strcat(valstring, ")"); if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkym(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ double *value, /* I - keyword value */ int decim, /* I - no of decimals */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ strcpy(valstring, "(" ); ffd2e(value[0], decim, tmpstring, status); /* convert to string */ if (strlen(tmpstring)+3 > FLEN_VALUE-1) { ffpmsg("complex key value too long (ffmkym)"); return(*status=BAD_F2C); } strcat(valstring, tmpstring); strcat(valstring, ", "); ffd2e(value[1], decim, tmpstring, status); /* convert to string */ if (strlen(valstring) + strlen(tmpstring)+1 > FLEN_VALUE-1) { ffpmsg("complex key value too long (ffmkym)"); return(*status=BAD_F2C); } strcat(valstring, tmpstring); strcat(valstring, ")"); if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffikyu(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Insert a null-valued keyword and comment into the FITS header. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring," "); /* create a dummy value string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffikys(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ const char *value, /* I - keyword value */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffs2c(value, valstring, status); /* put quotes around the string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffikls( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - name of keyword to write */ const char *value, /* I - keyword value */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Insert a long string keyword. This routine supports the HEASARC long string convention and can insert arbitrarily long string keyword values. The value is continued over multiple keywords that have the name COMTINUE without an equal sign in column 9 of the card. This routine also supports simple string keywords which are less than 69 characters in length. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD], tmpkeyname[FLEN_CARD]; char tstring[FLEN_VALUE], *cptr; int next, remain, vlen, nquote, nchar, namelen, contin, tstatus = -1; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* construct the new keyword, and insert into header */ remain = strlen(value); /* number of characters to write out */ next = 0; /* pointer to next character to write */ /* count the number of single quote characters in the string */ nquote = 0; cptr = strchr(value, '\''); /* search for quote character */ while (cptr) /* search for quote character */ { nquote++; /* increment no. of quote characters */ cptr++; /* increment pointer to next character */ cptr = strchr(cptr, '\''); /* search for another quote char */ } strncpy(tmpkeyname, keyname, 80); tmpkeyname[80] = '\0'; cptr = tmpkeyname; while(*cptr == ' ') /* skip over leading spaces in name */ cptr++; /* determine the number of characters that will fit on the line */ /* Note: each quote character is expanded to 2 quotes */ namelen = strlen(cptr); if (namelen <= 8 && (fftkey(cptr, &tstatus) <= 0) ) { /* This a normal 8-character FITS keyword */ nchar = 68 - nquote; /* max of 68 chars fit in a FITS string value */ } else { nchar = 80 - nquote - namelen - 5; } contin = 0; while (remain > 0) { if (nchar > FLEN_VALUE-1) { ffpmsg("longstr keyword value is too long (ffikls)"); return (*status=BAD_KEYCHAR); } strncpy(tstring, &value[next], nchar); /* copy string to temp buff */ tstring[nchar] = '\0'; ffs2c(tstring, valstring, status); /* put quotes around the string */ if (remain > nchar) /* if string is continued, put & as last char */ { vlen = strlen(valstring); nchar -= 1; /* outputting one less character now */ if (valstring[vlen-2] != '\'') valstring[vlen-2] = '&'; /* over write last char with & */ else { /* last char was a pair of single quotes, so over write both */ valstring[vlen-3] = '&'; valstring[vlen-1] = '\0'; } } if (contin) /* This is a CONTINUEd keyword */ { ffmkky("CONTINUE", valstring, comm, card, status); /* make keyword */ strncpy(&card[8], " ", 2); /* overwrite the '=' */ } else { ffmkky(keyname, valstring, comm, card, status); /* make keyword */ } ffikey(fptr, card, status); /* insert the keyword */ contin = 1; remain -= nchar; next += nchar; nchar = 68 - nquote; } return(*status); } /*--------------------------------------------------------------------------*/ int ffikyl(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ int value, /* I - keyword value */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffl2c(value, valstring, status); /* convert logical to 'T' or 'F' */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikyj(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ LONGLONG value, /* I - keyword value */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffi2c(value, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikyf(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ float value, /* I - keyword value */ int decim, /* I - no of decimals */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffr2f(value, decim, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikye(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ float value, /* I - keyword value */ int decim, /* I - no of decimals */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffr2e(value, decim, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikyg(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ double value, /* I - keyword value */ int decim, /* I - no of decimals */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffd2f(value, decim, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikyd(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ double value, /* I - keyword value */ int decim, /* I - no of decimals */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffd2e(value, decim, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikfc(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ float *value, /* I - keyword value */ int decim, /* I - no of decimals */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring, "(" ); ffr2f(value[0], decim, tmpstring, status); /* convert to string */ if (strlen(tmpstring)+3 > FLEN_VALUE-1) { ffpmsg("complex key value too long (ffikfc)"); return(*status=BAD_F2C); } strcat(valstring, tmpstring); strcat(valstring, ", "); ffr2f(value[1], decim, tmpstring, status); /* convert to string */ if (strlen(valstring) + strlen(tmpstring)+1 > FLEN_VALUE-1) { ffpmsg("complex key value too long (ffikfc)"); return(*status=BAD_F2C); } strcat(valstring, tmpstring); strcat(valstring, ")"); ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikyc(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ float *value, /* I - keyword value */ int decim, /* I - no of decimals */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring, "(" ); ffr2e(value[0], decim, tmpstring, status); /* convert to string */ if (strlen(tmpstring)+3 > FLEN_VALUE-1) { ffpmsg("complex key value too long (ffikyc)"); return(*status=BAD_F2C); } strcat(valstring, tmpstring); strcat(valstring, ", "); ffr2e(value[1], decim, tmpstring, status); /* convert to string */ if (strlen(valstring) + strlen(tmpstring)+1 > FLEN_VALUE-1) { ffpmsg("complex key value too long (ffikyc)"); return(*status=BAD_F2C); } strcat(valstring, tmpstring); strcat(valstring, ")"); ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikfm(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ double *value, /* I - keyword value */ int decim, /* I - no of decimals */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring, "(" ); ffd2f(value[0], decim, tmpstring, status); /* convert to string */ if (strlen(tmpstring)+3 > FLEN_VALUE-1) { ffpmsg("complex key value too long (ffikfm)"); return(*status=BAD_F2C); } strcat(valstring, tmpstring); strcat(valstring, ", "); ffd2f(value[1], decim, tmpstring, status); /* convert to string */ if (strlen(valstring) + strlen(tmpstring)+1 > FLEN_VALUE-1) { ffpmsg("complex key value too long (ffikfm)"); return(*status=BAD_F2C); } strcat(valstring, tmpstring); strcat(valstring, ")"); ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikym(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ double *value, /* I - keyword value */ int decim, /* I - no of decimals */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring, "(" ); ffd2e(value[0], decim, tmpstring, status); /* convert to string */ if (strlen(tmpstring)+3 > FLEN_VALUE-1) { ffpmsg("complex key value too long (ffikym)"); return(*status=BAD_F2C); } strcat(valstring, tmpstring); strcat(valstring, ", "); ffd2e(value[1], decim, tmpstring, status); /* convert to string */ if (strlen(valstring) + strlen(tmpstring)+1 > FLEN_VALUE-1) { ffpmsg("complex key value too long (ffikym)"); return(*status=BAD_F2C); } strcat(valstring, tmpstring); strcat(valstring, ")"); ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffirec(fitsfile *fptr, /* I - FITS file pointer */ int nkey, /* I - position to insert new keyword */ const char *card, /* I - card string value */ int *status) /* IO - error status */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffmaky(fptr, nkey, status); /* move to insert position */ ffikey(fptr, card, status); /* insert the keyword card */ return(*status); } /*--------------------------------------------------------------------------*/ int ffikey(fitsfile *fptr, /* I - FITS file pointer */ const char *card, /* I - card string value */ int *status) /* IO - error status */ /* insert a keyword at the position of (fptr->Fptr)->nextkey */ { int ii, len, nshift, keylength; long nblocks; LONGLONG bytepos; char *inbuff, *outbuff, *tmpbuff, buff1[FLEN_CARD], buff2[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if ( ((fptr->Fptr)->datastart - (fptr->Fptr)->headend) == 80) /* only room for END card */ { nblocks = 1; if (ffiblk(fptr, nblocks, 0, status) > 0) /* add new 2880-byte block*/ return(*status); } /* no. keywords to shift */ nshift= (int) (( (fptr->Fptr)->headend - (fptr->Fptr)->nextkey ) / 80); strncpy(buff2, card, 80); /* copy card to output buffer */ buff2[80] = '\0'; len = strlen(buff2); /* silently replace any illegal characters with a space */ for (ii=0; ii < len; ii++) if (buff2[ii] < ' ' || buff2[ii] > 126) buff2[ii] = ' '; for (ii=len; ii < 80; ii++) /* fill buffer with spaces if necessary */ buff2[ii] = ' '; keylength = strcspn(buff2, "="); if (keylength == 80) keylength = 8; /* test for the common commentary keywords which by definition have 8-char names */ if ( !fits_strncasecmp( "COMMENT ", buff2, 8) || !fits_strncasecmp( "HISTORY ", buff2, 8) || !fits_strncasecmp( " ", buff2, 8) || !fits_strncasecmp( "CONTINUE", buff2, 8) ) keylength = 8; for (ii=0; ii < keylength; ii++) /* make sure keyword name is uppercase */ buff2[ii] = toupper(buff2[ii]); fftkey(buff2, status); /* test keyword name contains legal chars */ /* no need to do this any more, since any illegal characters have been removed fftrec(buff2, status); */ /* test rest of keyword for legal chars */ inbuff = buff1; outbuff = buff2; bytepos = (fptr->Fptr)->nextkey; /* pointer to next keyword in header */ ffmbyt(fptr, bytepos, REPORT_EOF, status); for (ii = 0; ii < nshift; ii++) /* shift each keyword down one position */ { ffgbyt(fptr, 80, inbuff, status); /* read the current keyword */ ffmbyt(fptr, bytepos, REPORT_EOF, status); /* move back */ ffpbyt(fptr, 80, outbuff, status); /* overwrite with other buffer */ tmpbuff = inbuff; /* swap input and output buffers */ inbuff = outbuff; outbuff = tmpbuff; bytepos += 80; } ffpbyt(fptr, 80, outbuff, status); /* write the final keyword */ (fptr->Fptr)->headend += 80; /* increment the position of the END keyword */ (fptr->Fptr)->nextkey += 80; /* increment the pointer to next keyword */ return(*status); } /*--------------------------------------------------------------------------*/ int ffdkey(fitsfile *fptr, /* I - FITS file pointer */ const char *keyname, /* I - keyword name */ int *status) /* IO - error status */ /* delete a specified header keyword */ { int keypos, len; char valstring[FLEN_VALUE], comm[FLEN_COMMENT], value[FLEN_VALUE]; char message[FLEN_ERRMSG], nextcomm[FLEN_COMMENT]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, comm, status) > 0) /* read keyword */ { snprintf(message, FLEN_ERRMSG,"Could not find the %s keyword to delete (ffdkey)", keyname); ffpmsg(message); return(*status); } /* calc position of keyword in header */ keypos = (int) ((((fptr->Fptr)->nextkey) - ((fptr->Fptr)->headstart[(fptr->Fptr)->curhdu])) / 80); ffdrec(fptr, keypos, status); /* delete the keyword */ if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check for string value which may be continued over multiple keywords */ ffpmrk(); /* put mark on message stack; erase any messages after this */ ffc2s(valstring, value, status); /* remove quotes and trailing spaces */ if (*status == VALUE_UNDEFINED) { ffcmrk(); /* clear any spurious error messages, back to the mark */ *status = 0; } else { len = strlen(value); while (len && value[len - 1] == '&') /* ampersand used as continuation char */ { ffgcnt(fptr, value, nextcomm, status); if (*value) { ffdrec(fptr, keypos, status); /* delete the keyword */ len = strlen(value); } else /* a null valstring indicates no continuation */ len = 0; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffdstr(fitsfile *fptr, /* I - FITS file pointer */ const char *string, /* I - keyword name */ int *status) /* IO - error status */ /* delete a specified header keyword containing the input string */ { int keypos, len; char valstring[FLEN_VALUE], comm[FLEN_COMMENT], value[FLEN_VALUE]; char card[FLEN_CARD], message[FLEN_ERRMSG], nextcomm[FLEN_COMMENT]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgstr(fptr, string, card, status) > 0) /* read keyword */ { snprintf(message, FLEN_ERRMSG,"Could not find the %s keyword to delete (ffdkey)", string); ffpmsg(message); return(*status); } /* calc position of keyword in header */ keypos = (int) ((((fptr->Fptr)->nextkey) - ((fptr->Fptr)->headstart[(fptr->Fptr)->curhdu])) / 80); ffdrec(fptr, keypos, status); /* delete the keyword */ /* check for string value which may be continued over multiple keywords */ ffpsvc(card, valstring, comm, status); if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check for string value which may be continued over multiple keywords */ ffpmrk(); /* put mark on message stack; erase any messages after this */ ffc2s(valstring, value, status); /* remove quotes and trailing spaces */ if (*status == VALUE_UNDEFINED) { ffcmrk(); /* clear any spurious error messages, back to the mark */ *status = 0; } else { len = strlen(value); while (len && value[len - 1] == '&') /* ampersand used as continuation char */ { ffgcnt(fptr, value, nextcomm, status); if (*value) { ffdrec(fptr, keypos, status); /* delete the keyword */ len = strlen(value); } else /* a null valstring indicates no continuation */ len = 0; } } return(*status); }/*--------------------------------------------------------------------------*/ int ffdrec(fitsfile *fptr, /* I - FITS file pointer */ int keypos, /* I - position in header of keyword to delete */ int *status) /* IO - error status */ /* Delete a header keyword at position keypos. The 1st keyword is at keypos=1. */ { int ii, nshift; LONGLONG bytepos; char *inbuff, *outbuff, *tmpbuff, buff1[81], buff2[81]; char message[FLEN_ERRMSG]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (keypos < 1 || keypos > (fptr->Fptr)->headend - (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] / 80 ) return(*status = KEY_OUT_BOUNDS); (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] + (keypos - 1) * 80; nshift=(int) (( (fptr->Fptr)->headend - (fptr->Fptr)->nextkey ) / 80); /* no. keywords to shift */ if (nshift <= 0) { snprintf(message, FLEN_ERRMSG,"Cannot delete keyword number %d. It does not exist.", keypos); ffpmsg(message); return(*status = KEY_OUT_BOUNDS); } bytepos = (fptr->Fptr)->headend - 80; /* last keyword in header */ /* construct a blank keyword */ strcpy(buff2, " "); strcat(buff2, " "); inbuff = buff1; outbuff = buff2; for (ii = 0; ii < nshift; ii++) /* shift each keyword up one position */ { ffmbyt(fptr, bytepos, REPORT_EOF, status); ffgbyt(fptr, 80, inbuff, status); /* read the current keyword */ ffmbyt(fptr, bytepos, REPORT_EOF, status); ffpbyt(fptr, 80, outbuff, status); /* overwrite with next keyword */ tmpbuff = inbuff; /* swap input and output buffers */ inbuff = outbuff; outbuff = tmpbuff; bytepos -= 80; } (fptr->Fptr)->headend -= 80; /* decrement the position of the END keyword */ return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/pliocomp.c0000644000175100001710000001563300000000000020121 0ustar00vstsdocker/* stdlib is needed for the abs function */ #include /* The following prototype code was provided by Doug Tody, NRAO, for performing conversion between pixel arrays and line lists. The compression technique is used in IRAF. */ int pl_p2li (int *pxsrc, int xs, short *lldst, int npix); int pl_l2pi (short *ll_src, int xs, int *px_dst, int npix); /* * PL_P2L -- Convert a pixel array to a line list. The length of the list is * returned as the function value. * * Translated from the SPP version using xc -f, f2c. 8Sep99 DCT. */ #ifndef min #define min(a,b) (((a)<(b))?(a):(b)) #endif #ifndef max #define max(a,b) (((a)>(b))?(a):(b)) #endif int pl_p2li (int *pxsrc, int xs, short *lldst, int npix) /* int *pxsrc; input pixel array */ /* int xs; starting index in pxsrc (?) */ /* short *lldst; encoded line list */ /* int npix; number of pixels to convert */ { /* System generated locals */ int ret_val, i__1, i__2, i__3; /* Local variables */ int zero, v, x1, hi, ip, dv, xe, np, op, iz, nv = 0, pv, nz; /* Parameter adjustments */ --lldst; --pxsrc; /* Function Body */ if (! (npix <= 0)) { goto L110; } ret_val = 0; goto L100; L110: lldst[3] = -100; lldst[2] = 7; lldst[1] = 0; lldst[6] = 0; lldst[7] = 0; xe = xs + npix - 1; op = 8; zero = 0; /* Computing MAX */ i__1 = zero, i__2 = pxsrc[xs]; pv = max(i__1,i__2); x1 = xs; iz = xs; hi = 1; i__1 = xe; for (ip = xs; ip <= i__1; ++ip) { if (! (ip < xe)) { goto L130; } /* Computing MAX */ i__2 = zero, i__3 = pxsrc[ip + 1]; nv = max(i__2,i__3); if (! (nv == pv)) { goto L140; } goto L120; L140: if (! (pv == 0)) { goto L150; } pv = nv; x1 = ip + 1; goto L120; L150: goto L131; L130: if (! (pv == 0)) { goto L160; } x1 = xe + 1; L160: L131: np = ip - x1 + 1; nz = x1 - iz; if (! (pv > 0)) { goto L170; } dv = pv - hi; if (! (dv != 0)) { goto L180; } hi = pv; if (! (abs(dv) > 4095)) { goto L190; } lldst[op] = (short) ((pv & 4095) + 4096); ++op; lldst[op] = (short) (pv / 4096); ++op; goto L191; L190: if (! (dv < 0)) { goto L200; } lldst[op] = (short) (-dv + 12288); goto L201; L200: lldst[op] = (short) (dv + 8192); L201: ++op; if (! (np == 1 && nz == 0)) { goto L210; } v = lldst[op - 1]; lldst[op - 1] = (short) (v | 16384); goto L91; L210: L191: L180: L170: if (! (nz > 0)) { goto L220; } L230: if (! (nz > 0)) { goto L232; } lldst[op] = (short) min(4095,nz); ++op; /* L231: */ nz += -4095; goto L230; L232: if (! (np == 1 && pv > 0)) { goto L240; } lldst[op - 1] = (short) (lldst[op - 1] + 20481); goto L91; L240: L220: L250: if (! (np > 0)) { goto L252; } lldst[op] = (short) (min(4095,np) + 16384); ++op; /* L251: */ np += -4095; goto L250; L252: L91: x1 = ip + 1; iz = x1; pv = nv; L120: ; } /* L121: */ lldst[4] = (short) ((op - 1) % 32768); lldst[5] = (short) ((op - 1) / 32768); ret_val = op - 1; goto L100; L100: return ret_val; } /* plp2li_ */ /* * PL_L2PI -- Translate a PLIO line list into an integer pixel array. * The number of pixels output (always npix) is returned as the function * value. * * Translated from the SPP version using xc -f, f2c. 8Sep99 DCT. */ int pl_l2pi (short *ll_src, int xs, int *px_dst, int npix) /* short *ll_src; encoded line list */ /* int xs; starting index in ll_src */ /* int *px_dst; output pixel array */ /* int npix; number of pixels to convert */ { /* System generated locals */ int ret_val, i__1, i__2; /* Local variables */ int data, sw0001, otop, i__, lllen, i1, i2, x1, x2, ip, xe, np, op, pv, opcode, llfirt; int skipwd; /* Parameter adjustments */ --px_dst; --ll_src; /* Function Body */ if (! (ll_src[3] > 0)) { goto L110; } lllen = ll_src[3]; llfirt = 4; goto L111; L110: lllen = (ll_src[5] << 15) + ll_src[4]; llfirt = ll_src[2] + 1; L111: if (! (npix <= 0 || lllen <= 0)) { goto L120; } ret_val = 0; goto L100; L120: xe = xs + npix - 1; skipwd = 0; op = 1; x1 = 1; pv = 1; i__1 = lllen; for (ip = llfirt; ip <= i__1; ++ip) { if (! skipwd) { goto L140; } skipwd = 0; goto L130; L140: opcode = ll_src[ip] / 4096; data = ll_src[ip] & 4095; sw0001 = opcode; goto L150; L160: x2 = x1 + data - 1; i1 = max(x1,xs); i2 = min(x2,xe); np = i2 - i1 + 1; if (! (np > 0)) { goto L170; } otop = op + np - 1; if (! (opcode == 4)) { goto L180; } i__2 = otop; for (i__ = op; i__ <= i__2; ++i__) { px_dst[i__] = pv; /* L190: */ } /* L191: */ goto L181; L180: i__2 = otop; for (i__ = op; i__ <= i__2; ++i__) { px_dst[i__] = 0; /* L200: */ } /* L201: */ if (! (opcode == 5 && i2 == x2)) { goto L210; } px_dst[otop] = pv; L210: L181: op = otop + 1; L170: x1 = x2 + 1; goto L151; L220: pv = (ll_src[ip + 1] << 12) + data; skipwd = 1; goto L151; L230: pv += data; goto L151; L240: pv -= data; goto L151; L250: pv += data; goto L91; L260: pv -= data; L91: if (! (x1 >= xs && x1 <= xe)) { goto L270; } px_dst[op] = pv; ++op; L270: ++x1; goto L151; L150: ++sw0001; if (sw0001 < 1 || sw0001 > 8) { goto L151; } switch ((int)sw0001) { case 1: goto L160; case 2: goto L220; case 3: goto L230; case 4: goto L240; case 5: goto L160; case 6: goto L160; case 7: goto L250; case 8: goto L260; } L151: if (! (x1 > xe)) { goto L280; } goto L131; L280: L130: ; } L131: i__1 = npix; for (i__ = op; i__ <= i__1; ++i__) { px_dst[i__] = 0; /* L290: */ } /* L291: */ ret_val = npix; goto L100; L100: return ret_val; } /* pll2pi_ */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/putcol.c0000644000175100001710000020462000000000000017601 0ustar00vstsdocker/* This file, putcol.c, contains routines that write data elements to */ /* a FITS image or table. These are the generic routines. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffppx( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ long *firstpix, /* I - coord of first pixel to write(1 based) */ LONGLONG nelem, /* I - number of values to write */ void *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of pixels to the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). This routine is simillar to ffppr, except it supports writing to large images with more than 2**31 pixels. */ { int naxis, ii; long group = 1; LONGLONG firstelem, dimsize = 1, naxes[9]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* get the size of the image */ ffgidm(fptr, &naxis, status); ffgiszll(fptr, 9, naxes, status); firstelem = 0; for (ii=0; ii < naxis; ii++) { firstelem += ((firstpix[ii] - 1) * dimsize); dimsize *= naxes[ii]; } firstelem++; if (datatype == TBYTE) { ffpprb(fptr, group, firstelem, nelem, (unsigned char *) array, status); } else if (datatype == TSBYTE) { ffpprsb(fptr, group, firstelem, nelem, (signed char *) array, status); } else if (datatype == TUSHORT) { ffpprui(fptr, group, firstelem, nelem, (unsigned short *) array, status); } else if (datatype == TSHORT) { ffppri(fptr, group, firstelem, nelem, (short *) array, status); } else if (datatype == TUINT) { ffppruk(fptr, group, firstelem, nelem, (unsigned int *) array, status); } else if (datatype == TINT) { ffpprk(fptr, group, firstelem, nelem, (int *) array, status); } else if (datatype == TULONG) { ffppruj(fptr, group, firstelem, nelem, (unsigned long *) array, status); } else if (datatype == TLONG) { ffpprj(fptr, group, firstelem, nelem, (long *) array, status); } else if (datatype == TULONGLONG) { ffpprujj(fptr, group, firstelem, nelem, (ULONGLONG *) array, status); } else if (datatype == TLONGLONG) { ffpprjj(fptr, group, firstelem, nelem, (LONGLONG *) array, status); } else if (datatype == TFLOAT) { ffppre(fptr, group, firstelem, nelem, (float *) array, status); } else if (datatype == TDOUBLE) { ffpprd(fptr, group, firstelem, nelem, (double *) array, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffppxll( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ LONGLONG *firstpix, /* I - coord of first pixel to write(1 based) */ LONGLONG nelem, /* I - number of values to write */ void *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of pixels to the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). This routine is simillar to ffppr, except it supports writing to large images with more than 2**31 pixels. */ { int naxis, ii; long group = 1; LONGLONG firstelem, dimsize = 1, naxes[9]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* get the size of the image */ ffgidm(fptr, &naxis, status); ffgiszll(fptr, 9, naxes, status); firstelem = 0; for (ii=0; ii < naxis; ii++) { firstelem += ((firstpix[ii] - 1) * dimsize); dimsize *= naxes[ii]; } firstelem++; if (datatype == TBYTE) { ffpprb(fptr, group, firstelem, nelem, (unsigned char *) array, status); } else if (datatype == TSBYTE) { ffpprsb(fptr, group, firstelem, nelem, (signed char *) array, status); } else if (datatype == TUSHORT) { ffpprui(fptr, group, firstelem, nelem, (unsigned short *) array, status); } else if (datatype == TSHORT) { ffppri(fptr, group, firstelem, nelem, (short *) array, status); } else if (datatype == TUINT) { ffppruk(fptr, group, firstelem, nelem, (unsigned int *) array, status); } else if (datatype == TINT) { ffpprk(fptr, group, firstelem, nelem, (int *) array, status); } else if (datatype == TULONG) { ffppruj(fptr, group, firstelem, nelem, (unsigned long *) array, status); } else if (datatype == TLONG) { ffpprj(fptr, group, firstelem, nelem, (long *) array, status); } else if (datatype == TULONGLONG) { ffpprujj(fptr, group, firstelem, nelem, (ULONGLONG *) array, status); } else if (datatype == TLONGLONG) { ffpprjj(fptr, group, firstelem, nelem, (LONGLONG *) array, status); } else if (datatype == TFLOAT) { ffppre(fptr, group, firstelem, nelem, (float *) array, status); } else if (datatype == TDOUBLE) { ffpprd(fptr, group, firstelem, nelem, (double *) array, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffppxn( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ long *firstpix, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ void *array, /* I - array of values that are written */ void *nulval, /* I - pointer to the null value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). This routine supports writing to large images with more than 2**31 pixels. */ { int naxis, ii; long group = 1; LONGLONG firstelem, dimsize = 1, naxes[9]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (nulval == NULL) /* null value not defined? */ { ffppx(fptr, datatype, firstpix, nelem, array, status); return(*status); } /* get the size of the image */ ffgidm(fptr, &naxis, status); ffgiszll(fptr, 9, naxes, status); firstelem = 0; for (ii=0; ii < naxis; ii++) { firstelem += ((firstpix[ii] - 1) * dimsize); dimsize *= naxes[ii]; } firstelem++; if (datatype == TBYTE) { ffppnb(fptr, group, firstelem, nelem, (unsigned char *) array, *(unsigned char *) nulval, status); } else if (datatype == TSBYTE) { ffppnsb(fptr, group, firstelem, nelem, (signed char *) array, *(signed char *) nulval, status); } else if (datatype == TUSHORT) { ffppnui(fptr, group, firstelem, nelem, (unsigned short *) array, *(unsigned short *) nulval,status); } else if (datatype == TSHORT) { ffppni(fptr, group, firstelem, nelem, (short *) array, *(short *) nulval, status); } else if (datatype == TUINT) { ffppnuk(fptr, group, firstelem, nelem, (unsigned int *) array, *(unsigned int *) nulval, status); } else if (datatype == TINT) { ffppnk(fptr, group, firstelem, nelem, (int *) array, *(int *) nulval, status); } else if (datatype == TULONG) { ffppnuj(fptr, group, firstelem, nelem, (unsigned long *) array, *(unsigned long *) nulval,status); } else if (datatype == TLONG) { ffppnj(fptr, group, firstelem, nelem, (long *) array, *(long *) nulval, status); } else if (datatype == TULONGLONG) { ffppnujj(fptr, group, firstelem, nelem, (ULONGLONG *) array, *(ULONGLONG *) nulval, status); } else if (datatype == TLONGLONG) { ffppnjj(fptr, group, firstelem, nelem, (LONGLONG *) array, *(LONGLONG *) nulval, status); } else if (datatype == TFLOAT) { ffppne(fptr, group, firstelem, nelem, (float *) array, *(float *) nulval, status); } else if (datatype == TDOUBLE) { ffppnd(fptr, group, firstelem, nelem, (double *) array, *(double *) nulval, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffppxnll( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ LONGLONG *firstpix, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ void *array, /* I - array of values that are written */ void *nulval, /* I - pointer to the null value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). This routine supports writing to large images with more than 2**31 pixels. */ { int naxis, ii; long group = 1; LONGLONG firstelem, dimsize = 1, naxes[9]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (nulval == NULL) /* null value not defined? */ { ffppxll(fptr, datatype, firstpix, nelem, array, status); return(*status); } /* get the size of the image */ ffgidm(fptr, &naxis, status); ffgiszll(fptr, 9, naxes, status); firstelem = 0; for (ii=0; ii < naxis; ii++) { firstelem += ((firstpix[ii] - 1) * dimsize); dimsize *= naxes[ii]; } firstelem++; if (datatype == TBYTE) { ffppnb(fptr, group, firstelem, nelem, (unsigned char *) array, *(unsigned char *) nulval, status); } else if (datatype == TSBYTE) { ffppnsb(fptr, group, firstelem, nelem, (signed char *) array, *(signed char *) nulval, status); } else if (datatype == TUSHORT) { ffppnui(fptr, group, firstelem, nelem, (unsigned short *) array, *(unsigned short *) nulval,status); } else if (datatype == TSHORT) { ffppni(fptr, group, firstelem, nelem, (short *) array, *(short *) nulval, status); } else if (datatype == TUINT) { ffppnuk(fptr, group, firstelem, nelem, (unsigned int *) array, *(unsigned int *) nulval, status); } else if (datatype == TINT) { ffppnk(fptr, group, firstelem, nelem, (int *) array, *(int *) nulval, status); } else if (datatype == TULONG) { ffppnuj(fptr, group, firstelem, nelem, (unsigned long *) array, *(unsigned long *) nulval,status); } else if (datatype == TLONG) { ffppnj(fptr, group, firstelem, nelem, (long *) array, *(long *) nulval, status); } else if (datatype == TULONGLONG) { ffppnujj(fptr, group, firstelem, nelem, (ULONGLONG *) array, *(ULONGLONG *) nulval, status); } else if (datatype == TLONGLONG) { ffppnjj(fptr, group, firstelem, nelem, (LONGLONG *) array, *(LONGLONG *) nulval, status); } else if (datatype == TFLOAT) { ffppne(fptr, group, firstelem, nelem, (float *) array, *(float *) nulval, status); } else if (datatype == TDOUBLE) { ffppnd(fptr, group, firstelem, nelem, (double *) array, *(double *) nulval, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffppr( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ void *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long group = 1; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (datatype == TBYTE) { ffpprb(fptr, group, firstelem, nelem, (unsigned char *) array, status); } else if (datatype == TSBYTE) { ffpprsb(fptr, group, firstelem, nelem, (signed char *) array, status); } else if (datatype == TUSHORT) { ffpprui(fptr, group, firstelem, nelem, (unsigned short *) array, status); } else if (datatype == TSHORT) { ffppri(fptr, group, firstelem, nelem, (short *) array, status); } else if (datatype == TUINT) { ffppruk(fptr, group, firstelem, nelem, (unsigned int *) array, status); } else if (datatype == TINT) { ffpprk(fptr, group, firstelem, nelem, (int *) array, status); } else if (datatype == TULONG) { ffppruj(fptr, group, firstelem, nelem, (unsigned long *) array, status); } else if (datatype == TLONG) { ffpprj(fptr, group, firstelem, nelem, (long *) array, status); } else if (datatype == TULONGLONG) { ffpprujj(fptr, group, firstelem, nelem, (ULONGLONG *) array, status); } else if (datatype == TLONGLONG) { ffpprjj(fptr, group, firstelem, nelem, (LONGLONG *) array, status); } else if (datatype == TFLOAT) { ffppre(fptr, group, firstelem, nelem, (float *) array, status); } else if (datatype == TDOUBLE) { ffpprd(fptr, group, firstelem, nelem, (double *) array, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffppn( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ void *array, /* I - array of values that are written */ void *nulval, /* I - pointer to the null value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long group = 1; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (nulval == NULL) /* null value not defined? */ { ffppr(fptr, datatype, firstelem, nelem, array, status); return(*status); } if (datatype == TBYTE) { ffppnb(fptr, group, firstelem, nelem, (unsigned char *) array, *(unsigned char *) nulval, status); } else if (datatype == TSBYTE) { ffppnsb(fptr, group, firstelem, nelem, (signed char *) array, *(signed char *) nulval, status); } else if (datatype == TUSHORT) { ffppnui(fptr, group, firstelem, nelem, (unsigned short *) array, *(unsigned short *) nulval,status); } else if (datatype == TSHORT) { ffppni(fptr, group, firstelem, nelem, (short *) array, *(short *) nulval, status); } else if (datatype == TUINT) { ffppnuk(fptr, group, firstelem, nelem, (unsigned int *) array, *(unsigned int *) nulval, status); } else if (datatype == TINT) { ffppnk(fptr, group, firstelem, nelem, (int *) array, *(int *) nulval, status); } else if (datatype == TULONG) { ffppnuj(fptr, group, firstelem, nelem, (unsigned long *) array, *(unsigned long *) nulval,status); } else if (datatype == TLONG) { ffppnj(fptr, group, firstelem, nelem, (long *) array, *(long *) nulval, status); } else if (datatype == TULONGLONG) { ffppnujj(fptr, group, firstelem, nelem, (ULONGLONG *) array, *(ULONGLONG *) nulval, status); } else if (datatype == TLONGLONG) { ffppnjj(fptr, group, firstelem, nelem, (LONGLONG *) array, *(LONGLONG *) nulval, status); } else if (datatype == TFLOAT) { ffppne(fptr, group, firstelem, nelem, (float *) array, *(float *) nulval, status); } else if (datatype == TDOUBLE) { ffppnd(fptr, group, firstelem, nelem, (double *) array, *(double *) nulval, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffpss( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc , /* I - 'top right corner' of the subsection */ void *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write a section of values to the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). This routine supports writing to large images with more than 2**31 pixels. */ { int naxis; long naxes[9]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* get the size of the image */ ffgidm(fptr, &naxis, status); ffgisz(fptr, 9, naxes, status); if (datatype == TBYTE) { ffpssb(fptr, 1, naxis, naxes, blc, trc, (unsigned char *) array, status); } else if (datatype == TSBYTE) { ffpsssb(fptr, 1, naxis, naxes, blc, trc, (signed char *) array, status); } else if (datatype == TUSHORT) { ffpssui(fptr, 1, naxis, naxes, blc, trc, (unsigned short *) array, status); } else if (datatype == TSHORT) { ffpssi(fptr, 1, naxis, naxes, blc, trc, (short *) array, status); } else if (datatype == TUINT) { ffpssuk(fptr, 1, naxis, naxes, blc, trc, (unsigned int *) array, status); } else if (datatype == TINT) { ffpssk(fptr, 1, naxis, naxes, blc, trc, (int *) array, status); } else if (datatype == TULONG) { ffpssuj(fptr, 1, naxis, naxes, blc, trc, (unsigned long *) array, status); } else if (datatype == TLONG) { ffpssj(fptr, 1, naxis, naxes, blc, trc, (long *) array, status); } else if (datatype == TULONGLONG) { ffpssujj(fptr, 1, naxis, naxes, blc, trc, (ULONGLONG *) array, status); } else if (datatype == TLONGLONG) { ffpssjj(fptr, 1, naxis, naxes, blc, trc, (LONGLONG *) array, status); } else if (datatype == TFLOAT) { ffpsse(fptr, 1, naxis, naxes, blc, trc, (float *) array, status); } else if (datatype == TDOUBLE) { ffpssd(fptr, 1, naxis, naxes, blc, trc, (double *) array, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffpcl( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of elements to write */ void *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to a table column. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS column is not the same as the array being written). */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (datatype == TBIT) { ffpclx(fptr, colnum, firstrow, (long) firstelem, (long) nelem, (char *) array, status); } else if (datatype == TBYTE) { ffpclb(fptr, colnum, firstrow, firstelem, nelem, (unsigned char *) array, status); } else if (datatype == TSBYTE) { ffpclsb(fptr, colnum, firstrow, firstelem, nelem, (signed char *) array, status); } else if (datatype == TUSHORT) { ffpclui(fptr, colnum, firstrow, firstelem, nelem, (unsigned short *) array, status); } else if (datatype == TSHORT) { ffpcli(fptr, colnum, firstrow, firstelem, nelem, (short *) array, status); } else if (datatype == TUINT) { ffpcluk(fptr, colnum, firstrow, firstelem, nelem, (unsigned int *) array, status); } else if (datatype == TINT) { ffpclk(fptr, colnum, firstrow, firstelem, nelem, (int *) array, status); } else if (datatype == TULONG) { ffpcluj(fptr, colnum, firstrow, firstelem, nelem, (unsigned long *) array, status); } else if (datatype == TLONG) { ffpclj(fptr, colnum, firstrow, firstelem, nelem, (long *) array, status); } else if (datatype == TULONGLONG) { ffpclujj(fptr, colnum, firstrow, firstelem, nelem, (ULONGLONG *) array, status); } else if (datatype == TLONGLONG) { ffpcljj(fptr, colnum, firstrow, firstelem, nelem, (LONGLONG *) array, status); } else if (datatype == TFLOAT) { ffpcle(fptr, colnum, firstrow, firstelem, nelem, (float *) array, status); } else if (datatype == TDOUBLE) { ffpcld(fptr, colnum, firstrow, firstelem, nelem, (double *) array, status); } else if (datatype == TCOMPLEX) { ffpcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, (float *) array, status); } else if (datatype == TDBLCOMPLEX) { ffpcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, (double *) array, status); } else if (datatype == TLOGICAL) { ffpcll(fptr, colnum, firstrow, firstelem, nelem, (char *) array, status); } else if (datatype == TSTRING) { ffpcls(fptr, colnum, firstrow, firstelem, nelem, (char **) array, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffpcn( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of elements to write */ void *array, /* I - array of values that are written */ void *nulval, /* I - pointer to the null value */ int *status) /* IO - error status */ /* Write an array of values to a table column. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS column is not the same as the array being written). */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (nulval == NULL) /* null value not defined? */ { ffpcl(fptr, datatype, colnum, firstrow, firstelem, nelem, array, status); return(*status); } if (datatype == TBYTE) { ffpcnb(fptr, colnum, firstrow, firstelem, nelem, (unsigned char *) array, *(unsigned char *) nulval, status); } else if (datatype == TSBYTE) { ffpcnsb(fptr, colnum, firstrow, firstelem, nelem, (signed char *) array, *(signed char *) nulval, status); } else if (datatype == TUSHORT) { ffpcnui(fptr, colnum, firstrow, firstelem, nelem, (unsigned short *) array, *(unsigned short *) nulval, status); } else if (datatype == TSHORT) { ffpcni(fptr, colnum, firstrow, firstelem, nelem, (short *) array, *(unsigned short *) nulval, status); } else if (datatype == TUINT) { ffpcnuk(fptr, colnum, firstrow, firstelem, nelem, (unsigned int *) array, *(unsigned int *) nulval, status); } else if (datatype == TINT) { ffpcnk(fptr, colnum, firstrow, firstelem, nelem, (int *) array, *(int *) nulval, status); } else if (datatype == TULONG) { ffpcnuj(fptr, colnum, firstrow, firstelem, nelem, (unsigned long *) array, *(unsigned long *) nulval, status); } else if (datatype == TLONG) { ffpcnj(fptr, colnum, firstrow, firstelem, nelem, (long *) array, *(long *) nulval, status); } else if (datatype == TULONGLONG) { ffpcnujj(fptr, colnum, firstrow, firstelem, nelem, (ULONGLONG *) array, *(ULONGLONG *) nulval, status); } else if (datatype == TLONGLONG) { ffpcnjj(fptr, colnum, firstrow, firstelem, nelem, (LONGLONG *) array, *(LONGLONG *) nulval, status); } else if (datatype == TFLOAT) { ffpcne(fptr, colnum, firstrow, firstelem, nelem, (float *) array, *(float *) nulval, status); } else if (datatype == TDOUBLE) { ffpcnd(fptr, colnum, firstrow, firstelem, nelem, (double *) array, *(double *) nulval, status); } else if (datatype == TCOMPLEX) { ffpcne(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, (float *) array, *(float *) nulval, status); } else if (datatype == TDBLCOMPLEX) { ffpcnd(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, (double *) array, *(double *) nulval, status); } else if (datatype == TLOGICAL) { ffpcnl(fptr, colnum, firstrow, firstelem, nelem, (char *) array, *(char *) nulval, status); } else if (datatype == TSTRING) { ffpcns(fptr, colnum, firstrow, firstelem, nelem, (char **) array, (char *) nulval, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int fits_iter_set_by_name(iteratorCol *col, /* I - iterator col structure */ fitsfile *fptr, /* I - FITS file pointer */ char *colname, /* I - column name */ int datatype, /* I - column datatype */ int iotype) /* I - InputCol, InputOutputCol, or OutputCol */ /* set all the parameters for an iterator column, by column name */ { col->fptr = fptr; strncpy(col->colname, colname,69); col->colname[69]=0; col->colnum = 0; /* set column number undefined since name is given */ col->datatype = datatype; col->iotype = iotype; return(0); } /*--------------------------------------------------------------------------*/ int fits_iter_set_by_num(iteratorCol *col, /* I - iterator column structure */ fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ int datatype, /* I - column datatype */ int iotype) /* I - InputCol, InputOutputCol, or OutputCol */ /* set all the parameters for an iterator column, by column number */ { col->fptr = fptr; col->colnum = colnum; col->datatype = datatype; col->iotype = iotype; return(0); } /*--------------------------------------------------------------------------*/ int fits_iter_set_file(iteratorCol *col, /* I - iterator column structure */ fitsfile *fptr) /* I - FITS file pointer */ /* set iterator column parameter */ { col->fptr = fptr; return(0); } /*--------------------------------------------------------------------------*/ int fits_iter_set_colname(iteratorCol *col, /* I - iterator col structure */ char *colname) /* I - column name */ /* set iterator column parameter */ { strncpy(col->colname, colname,69); col->colname[69]=0; col->colnum = 0; /* set column number undefined since name is given */ return(0); } /*--------------------------------------------------------------------------*/ int fits_iter_set_colnum(iteratorCol *col, /* I - iterator column structure */ int colnum) /* I - column number */ /* set iterator column parameter */ { col->colnum = colnum; return(0); } /*--------------------------------------------------------------------------*/ int fits_iter_set_datatype(iteratorCol *col, /* I - iterator col structure */ int datatype) /* I - column datatype */ /* set iterator column parameter */ { col->datatype = datatype; return(0); } /*--------------------------------------------------------------------------*/ int fits_iter_set_iotype(iteratorCol *col, /* I - iterator column structure */ int iotype) /* I - InputCol, InputOutputCol, or OutputCol */ /* set iterator column parameter */ { col->iotype = iotype; return(0); } /*--------------------------------------------------------------------------*/ fitsfile * fits_iter_get_file(iteratorCol *col) /* I -iterator col structure */ /* get iterator column parameter */ { return(col->fptr); } /*--------------------------------------------------------------------------*/ char * fits_iter_get_colname(iteratorCol *col) /* I -iterator col structure */ /* get iterator column parameter */ { return(col->colname); } /*--------------------------------------------------------------------------*/ int fits_iter_get_colnum(iteratorCol *col) /* I - iterator column structure */ /* get iterator column parameter */ { return(col->colnum); } /*--------------------------------------------------------------------------*/ int fits_iter_get_datatype(iteratorCol *col) /* I - iterator col structure */ /* get iterator column parameter */ { return(col->datatype); } /*--------------------------------------------------------------------------*/ int fits_iter_get_iotype(iteratorCol *col) /* I - iterator column structure */ /* get iterator column parameter */ { return(col->iotype); } /*--------------------------------------------------------------------------*/ void * fits_iter_get_array(iteratorCol *col) /* I - iterator col structure */ /* get iterator column parameter */ { return(col->array); } /*--------------------------------------------------------------------------*/ long fits_iter_get_tlmin(iteratorCol *col) /* I - iterator column structure */ /* get iterator column parameter */ { return(col->tlmin); } /*--------------------------------------------------------------------------*/ long fits_iter_get_tlmax(iteratorCol *col) /* I - iterator column structure */ /* get iterator column parameter */ { return(col->tlmax); } /*--------------------------------------------------------------------------*/ long fits_iter_get_repeat(iteratorCol *col) /* I - iterator col structure */ /* get iterator column parameter */ { return(col->repeat); } /*--------------------------------------------------------------------------*/ char * fits_iter_get_tunit(iteratorCol *col) /* I - iterator col structure */ /* get iterator column parameter */ { return(col->tunit); } /*--------------------------------------------------------------------------*/ char * fits_iter_get_tdisp(iteratorCol *col) /* I -iterator col structure */ /* get iterator column parameter */ { return(col->tdisp); } /*--------------------------------------------------------------------------*/ int ffiter(int n_cols, iteratorCol *cols, long offset, long n_per_loop, int (*work_fn)(long total_n, long offset, long first_n, long n_values, int n_cols, iteratorCol *cols, void *userPointer), void *userPointer, int *status) /* The iterator function. This function will pass the specified columns from a FITS table or pixels from a FITS image to the user-supplied function. Depending on the size of the table or image, only a subset of the rows or pixels may be passed to the function on each call, in which case the function will be called multiple times until all the rows or pixels have been processed. */ { typedef struct /* structure to store the column null value */ { int nullsize; /* length of the null value, in bytes */ union { /* default null value for the column */ char *stringnull; unsigned char charnull; signed char scharnull; int intnull; short shortnull; long longnull; unsigned int uintnull; unsigned short ushortnull; unsigned long ulongnull; float floatnull; double doublenull; LONGLONG longlongnull; } null; } colNulls; void *dataptr, *defaultnull; colNulls *col; int ii, jj, tstatus, naxis, bitpix; int typecode, hdutype, jtype, type, anynul=0, nfiles, nbytes; long totaln, nleft, frow, felement, n_optimum, i_optimum, ntodo; long rept, rowrept, width, tnull, naxes[9] = {1,1,1,1,1,1,1,1,1}, groups; double zeros = 0.; char message[FLEN_ERRMSG], keyname[FLEN_KEYWORD], nullstr[FLEN_VALUE]; char **stringptr, *nullptr, *cptr; if (*status > 0) return(*status); if (n_cols < 0 || n_cols > 999 ) { ffpmsg("Illegal number of columms (ffiter)"); return(*status = BAD_COL_NUM); /* negative number of columns */ } /*------------------------------------------------------------*/ /* Make sure column numbers and datatypes are in legal range */ /* and column numbers and datatypes are legal. */ /* Also fill in other parameters in the column structure. */ /*------------------------------------------------------------*/ ffghdt(cols[0].fptr, &hdutype, status); /* type of first HDU */ for (jj = 0; jj < n_cols; jj++) { /* check that output datatype code value is legal */ type = cols[jj].datatype; /* Allow variable length arrays for InputCol and InputOutputCol columns, but not for OutputCol columns. Variable length arrays have a negative type code value. */ if ((cols[jj].iotype != OutputCol) && (type<0)) { type*=-1; } if (type != 0 && type != TBYTE && type != TSBYTE && type != TLOGICAL && type != TSTRING && type != TSHORT && type != TINT && type != TLONG && type != TFLOAT && type != TDOUBLE && type != TCOMPLEX && type != TULONG && type != TUSHORT && type != TDBLCOMPLEX && type != TLONGLONG ) { if (type < 0) { snprintf(message,FLEN_ERRMSG, "Variable length array not allowed for output column number %d (ffiter)", jj + 1); } else { snprintf(message,FLEN_ERRMSG, "Illegal datatype for column number %d: %d (ffiter)", jj + 1, cols[jj].datatype); } ffpmsg(message); return(*status = BAD_DATATYPE); } /* initialize TLMINn, TLMAXn, column name, and display format */ cols[jj].tlmin = 0; cols[jj].tlmax = 0; cols[jj].tunit[0] = '\0'; cols[jj].tdisp[0] = '\0'; ffghdt(cols[jj].fptr, &jtype, status); /* get HDU type */ if (hdutype == IMAGE_HDU) /* operating on FITS images */ { if (jtype != IMAGE_HDU) { snprintf(message,FLEN_ERRMSG, "File %d not positioned to an image extension (ffiter)", jj + 1); return(*status = NOT_IMAGE); } /* since this is an image, set a dummy column number = 0 */ cols[jj].colnum = 0; strcpy(cols[jj].colname, "IMAGE"); /* dummy name for images */ tstatus = 0; ffgkys(cols[jj].fptr, "BUNIT", cols[jj].tunit, 0, &tstatus); } else /* operating on FITS tables */ { if (jtype == IMAGE_HDU) { snprintf(message,FLEN_ERRMSG, "File %d not positioned to a table extension (ffiter)", jj + 1); return(*status = NOT_TABLE); } if (cols[jj].colnum < 1) { /* find the column number for the named column */ if (ffgcno(cols[jj].fptr, CASEINSEN, cols[jj].colname, &cols[jj].colnum, status) ) { snprintf(message,FLEN_ERRMSG, "Column '%s' not found for column number %d (ffiter)", cols[jj].colname, jj + 1); ffpmsg(message); return(*status); } } /* check that the column number is valid */ if (cols[jj].colnum < 1 || cols[jj].colnum > ((cols[jj].fptr)->Fptr)->tfield) { snprintf(message,FLEN_ERRMSG, "Column %d has illegal table position number: %d (ffiter)", jj + 1, cols[jj].colnum); ffpmsg(message); return(*status = BAD_COL_NUM); } /* look for column description keywords and update structure */ tstatus = 0; ffkeyn("TLMIN", cols[jj].colnum, keyname, &tstatus); ffgkyj(cols[jj].fptr, keyname, &cols[jj].tlmin, 0, &tstatus); tstatus = 0; ffkeyn("TLMAX", cols[jj].colnum, keyname, &tstatus); ffgkyj(cols[jj].fptr, keyname, &cols[jj].tlmax, 0, &tstatus); tstatus = 0; ffkeyn("TTYPE", cols[jj].colnum, keyname, &tstatus); ffgkys(cols[jj].fptr, keyname, cols[jj].colname, 0, &tstatus); if (tstatus) cols[jj].colname[0] = '\0'; tstatus = 0; ffkeyn("TUNIT", cols[jj].colnum, keyname, &tstatus); ffgkys(cols[jj].fptr, keyname, cols[jj].tunit, 0, &tstatus); tstatus = 0; ffkeyn("TDISP", cols[jj].colnum, keyname, &tstatus); ffgkys(cols[jj].fptr, keyname, cols[jj].tdisp, 0, &tstatus); } } /* end of loop over all columns */ /*-----------------------------------------------------------------*/ /* use the first file to set the total number of values to process */ /*-----------------------------------------------------------------*/ offset = maxvalue(offset, 0L); /* make sure offset is legal */ if (hdutype == IMAGE_HDU) /* get total number of pixels in the image */ { fits_get_img_dim(cols[0].fptr, &naxis, status); fits_get_img_size(cols[0].fptr, 9, naxes, status); tstatus = 0; ffgkyj(cols[0].fptr, "GROUPS", &groups, NULL, &tstatus); if (!tstatus && groups && (naxis > 1) && (naxes[0] == 0) ) { /* this is a random groups file, with NAXIS1 = 0 */ /* Use GCOUNT, the number of groups, as the first multiplier */ /* to calculate the total number of pixels in all the groups. */ ffgkyj(cols[0].fptr, "GCOUNT", &totaln, NULL, status); } else { totaln = naxes[0]; } for (ii = 1; ii < naxis; ii++) totaln *= naxes[ii]; frow = 1; felement = 1 + offset; } else /* get total number or rows in the table */ { ffgkyj(cols[0].fptr, "NAXIS2", &totaln, 0, status); frow = 1 + offset; felement = 1; } /* adjust total by the input starting offset value */ totaln -= offset; totaln = maxvalue(totaln, 0L); /* don't allow negative number */ /*------------------------------------------------------------------*/ /* Determine number of values to pass to work function on each loop */ /*------------------------------------------------------------------*/ if (n_per_loop == 0) { /* Determine optimum number of values for each iteration. */ /* Look at all the fitsfile pointers to determine the number */ /* of unique files. */ nfiles = 1; ffgrsz(cols[0].fptr, &n_optimum, status); for (jj = 1; jj < n_cols; jj++) { for (ii = 0; ii < jj; ii++) { if (cols[ii].fptr == cols[jj].fptr) break; } if (ii == jj) /* this is a new file */ { nfiles++; ffgrsz(cols[jj].fptr, &i_optimum, status); n_optimum = minvalue(n_optimum, i_optimum); } } /* divid n_optimum by the number of files that will be processed */ n_optimum = n_optimum / nfiles; n_optimum = maxvalue(n_optimum, 1); } else if (n_per_loop < 0) /* must pass all the values at one time */ { n_optimum = totaln; } else /* calling routine specified how many values to pass at a time */ { n_optimum = minvalue(n_per_loop, totaln); } /*--------------------------------------*/ /* allocate work arrays for each column */ /* and determine the null pixel value */ /*--------------------------------------*/ col = calloc(n_cols, sizeof(colNulls) ); /* memory for the null values */ if (!col) { ffpmsg("ffiter failed to allocate memory for null values"); *status = MEMORY_ALLOCATION; /* memory allocation failed */ return(*status); } for (jj = 0; jj < n_cols; jj++) { /* get image or column datatype and vector length */ if (hdutype == IMAGE_HDU) /* get total number of pixels in the image */ { fits_get_img_type(cols[jj].fptr, &bitpix, status); switch(bitpix) { case BYTE_IMG: typecode = TBYTE; break; case SHORT_IMG: typecode = TSHORT; break; case LONG_IMG: typecode = TLONG; break; case FLOAT_IMG: typecode = TFLOAT; break; case DOUBLE_IMG: typecode = TDOUBLE; break; case LONGLONG_IMG: typecode = TLONGLONG; break; } } else { if (ffgtcl(cols[jj].fptr, cols[jj].colnum, &typecode, &rept, &width, status) > 0) goto cleanup; if (typecode < 0) { /* if any variable length arrays, then the */ n_optimum = 1; /* must process the table 1 row at a time */ /* Allow variable length arrays for InputCol and InputOutputCol columns, but not for OutputCol columns. Variable length arrays have a negative type code value. */ if (cols[jj].iotype == OutputCol) { snprintf(message,FLEN_ERRMSG, "Variable length array not allowed for output column number %d (ffiter)", jj + 1); ffpmsg(message); return(*status = BAD_DATATYPE); } } } /* special case where sizeof(long) = 8: use TINT instead of TLONG */ if (abs(typecode) == TLONG && sizeof(long) == 8 && sizeof(int) == 4) { if(typecode<0) { typecode = -TINT; } else { typecode = TINT; } } /* Special case: interprete 'X' column as 'B' */ if (abs(typecode) == TBIT) { typecode = typecode / TBIT * TBYTE; rept = (rept + 7) / 8; } if (cols[jj].datatype == 0) /* output datatype not specified? */ { /* special case if sizeof(long) = 8: use TINT instead of TLONG */ if (abs(typecode) == TLONG && sizeof(long) == 8 && sizeof(int) == 4) cols[jj].datatype = TINT; else cols[jj].datatype = abs(typecode); } /* calc total number of elements to do on each iteration */ if (hdutype == IMAGE_HDU || cols[jj].datatype == TSTRING) { ntodo = n_optimum; cols[jj].repeat = 1; /* handle special case of a 0-width string column */ if (hdutype == BINARY_TBL && rept == 0) cols[jj].repeat = 0; /* get the BLANK keyword value, if it exists */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG || abs(typecode) == TINT || abs(typecode) == TLONGLONG) { tstatus = 0; ffgkyj(cols[jj].fptr, "BLANK", &tnull, 0, &tstatus); if (tstatus) { tnull = 0L; /* no null values */ } } } else { if (typecode < 0) { /* get max size of the variable length vector; dont't trust the value given by the TFORM keyword */ rept = 1; for (ii = 0; ii < totaln; ii++) { ffgdes(cols[jj].fptr, cols[jj].colnum, frow + ii, &rowrept, NULL, status); rept = maxvalue(rept, rowrept); } } ntodo = n_optimum * rept; /* vector columns */ cols[jj].repeat = rept; /* get the TNULL keyword value, if it exists */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG || abs(typecode) == TINT || abs(typecode) == TLONGLONG) { tstatus = 0; if (hdutype == ASCII_TBL) /* TNULLn value is a string */ { ffkeyn("TNULL", cols[jj].colnum, keyname, &tstatus); ffgkys(cols[jj].fptr, keyname, nullstr, 0, &tstatus); if (tstatus) { tnull = 0L; /* keyword doesn't exist; no null values */ } else { cptr = nullstr; while (*cptr == ' ') /* skip over leading blanks */ cptr++; if (*cptr == '\0') /* TNULLn is all blanks? */ tnull = LONG_MIN; else { /* attempt to read TNULLn string as an integer */ ffc2ii(nullstr, &tnull, &tstatus); if (tstatus) tnull = LONG_MIN; /* choose smallest value */ } /* to represent nulls */ } } else /* Binary table; TNULLn value is an integer */ { ffkeyn("TNULL", cols[jj].colnum, keyname, &tstatus); ffgkyj(cols[jj].fptr, keyname, &tnull, 0, &tstatus); if (tstatus) { tnull = 0L; /* keyword doesn't exist; no null values */ } else if (tnull == 0) { /* worst possible case: a value of 0 is used to */ /* represent nulls in the FITS file. We have to */ /* use a non-zero null value here (zero is used to */ /* mean there are no null values in the array) so we */ /* will use the smallest possible integer instead. */ tnull = LONG_MIN; /* choose smallest possible value */ } } } } /* Note that the data array starts with 2nd element; */ /* 1st element of the array gives the null data value */ switch (cols[jj].datatype) { case TBYTE: cols[jj].array = calloc(ntodo + 1, sizeof(char)); col[jj].nullsize = sizeof(char); /* number of bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG || abs(typecode) == TINT || abs(typecode) == TLONGLONG) { tnull = minvalue(tnull, 255); tnull = maxvalue(tnull, 0); col[jj].null.charnull = (unsigned char) tnull; } else { col[jj].null.charnull = (unsigned char) 255; /* use 255 as null */ } break; case TSBYTE: cols[jj].array = calloc(ntodo + 1, sizeof(char)); col[jj].nullsize = sizeof(char); /* number of bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG || abs(typecode) == TINT || abs(typecode) == TLONGLONG) { tnull = minvalue(tnull, 127); tnull = maxvalue(tnull, -128); col[jj].null.scharnull = (signed char) tnull; } else { col[jj].null.scharnull = (signed char) -128; /* use -128 null */ } break; case TSHORT: cols[jj].array = calloc(ntodo + 1, sizeof(short)); col[jj].nullsize = sizeof(short); /* number of bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG || abs(typecode) == TINT || abs(typecode) == TLONGLONG) { tnull = minvalue(tnull, SHRT_MAX); tnull = maxvalue(tnull, SHRT_MIN); col[jj].null.shortnull = (short) tnull; } else { col[jj].null.shortnull = SHRT_MIN; /* use minimum as null */ } break; case TUSHORT: cols[jj].array = calloc(ntodo + 1, sizeof(unsigned short)); col[jj].nullsize = sizeof(unsigned short); /* bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG || abs(typecode) == TINT || abs(typecode) == TLONGLONG) { tnull = minvalue(tnull, (long) USHRT_MAX); tnull = maxvalue(tnull, 0); /* don't allow negative value */ col[jj].null.ushortnull = (unsigned short) tnull; } else { col[jj].null.ushortnull = USHRT_MAX; /* use maximum null */ } break; case TINT: cols[jj].array = calloc(sizeof(int), ntodo + 1); col[jj].nullsize = sizeof(int); /* number of bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG || abs(typecode) == TINT || abs(typecode) == TLONGLONG) { tnull = minvalue(tnull, INT_MAX); tnull = maxvalue(tnull, INT_MIN); col[jj].null.intnull = (int) tnull; } else { col[jj].null.intnull = INT_MIN; /* use minimum as null */ } break; case TUINT: cols[jj].array = calloc(ntodo + 1, sizeof(unsigned int)); col[jj].nullsize = sizeof(unsigned int); /* bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG || abs(typecode) == TINT || abs(typecode) == TLONGLONG) { tnull = minvalue(tnull, INT32_MAX); tnull = maxvalue(tnull, 0); col[jj].null.uintnull = (unsigned int) tnull; } else { col[jj].null.uintnull = UINT_MAX; /* use maximum as null */ } break; case TLONG: cols[jj].array = calloc(ntodo + 1, sizeof(long)); col[jj].nullsize = sizeof(long); /* number of bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG || abs(typecode) == TINT || abs(typecode) == TLONGLONG) { col[jj].null.longnull = tnull; } else { col[jj].null.longnull = LONG_MIN; /* use minimum as null */ } break; case TULONG: cols[jj].array = calloc(ntodo + 1, sizeof(unsigned long)); col[jj].nullsize = sizeof(unsigned long); /* bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG || abs(typecode) == TINT || abs(typecode) == TLONGLONG) { if (tnull < 0) /* can't use a negative null value */ col[jj].null.ulongnull = LONG_MAX; else col[jj].null.ulongnull = (unsigned long) tnull; } else { col[jj].null.ulongnull = LONG_MAX; /* use maximum as null */ } break; case TFLOAT: cols[jj].array = calloc(ntodo + 1, sizeof(float)); col[jj].nullsize = sizeof(float); /* number of bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG || abs(typecode) == TINT || abs(typecode) == TLONGLONG) { col[jj].null.floatnull = (float) tnull; } else { col[jj].null.floatnull = FLOATNULLVALUE; /* special value */ } break; case TCOMPLEX: cols[jj].array = calloc((ntodo * 2) + 1, sizeof(float)); col[jj].nullsize = sizeof(float); /* number of bytes per value */ col[jj].null.floatnull = FLOATNULLVALUE; /* special value */ break; case TDOUBLE: cols[jj].array = calloc(ntodo + 1, sizeof(double)); col[jj].nullsize = sizeof(double); /* number of bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG || abs(typecode) == TINT || abs(typecode) == TLONGLONG) { col[jj].null.doublenull = (double) tnull; } else { col[jj].null.doublenull = DOUBLENULLVALUE; /* special value */ } break; case TDBLCOMPLEX: cols[jj].array = calloc((ntodo * 2) + 1, sizeof(double)); col[jj].nullsize = sizeof(double); /* number of bytes per value */ col[jj].null.doublenull = DOUBLENULLVALUE; /* special value */ break; case TSTRING: /* allocate array of pointers to all the strings */ if( hdutype==ASCII_TBL ) rept = width; stringptr = calloc((ntodo + 1) , sizeof(stringptr)); cols[jj].array = stringptr; col[jj].nullsize = rept + 1; /* number of bytes per value */ if (stringptr) { /* allocate string to store the null string value */ col[jj].null.stringnull = calloc(rept + 1, sizeof(char) ); if (rept > 0) col[jj].null.stringnull[1] = 1; /* to make sure string != 0 */ /* allocate big block for the array of table column strings */ stringptr[0] = calloc((ntodo + 1) * (rept + 1), sizeof(char) ); if (stringptr[0]) { for (ii = 1; ii <= ntodo; ii++) { /* pointer to each string */ stringptr[ii] = stringptr[ii - 1] + (rept + 1); } /* get the TNULL keyword value, if it exists */ tstatus = 0; ffkeyn("TNULL", cols[jj].colnum, keyname, &tstatus); ffgkys(cols[jj].fptr, keyname, nullstr, 0, &tstatus); if (!tstatus) strncat(col[jj].null.stringnull, nullstr, rept); } else { ffpmsg("ffiter failed to allocate memory arrays"); *status = MEMORY_ALLOCATION; /* memory allocation failed */ goto cleanup; } } break; case TLOGICAL: cols[jj].array = calloc(ntodo + 1, sizeof(char)); col[jj].nullsize = sizeof(char); /* number of bytes per value */ /* use value = 2 to flag null values in logical columns */ col[jj].null.charnull = 2; break; case TLONGLONG: cols[jj].array = calloc(ntodo + 1, sizeof(LONGLONG)); col[jj].nullsize = sizeof(LONGLONG); /* number of bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG || abs(typecode) == TLONGLONG || abs(typecode) == TINT) { col[jj].null.longlongnull = tnull; } else { col[jj].null.longlongnull = LONGLONG_MIN; /* use minimum as null */ } break; default: snprintf(message,FLEN_ERRMSG, "Column %d datatype currently not supported: %d: (ffiter)", jj + 1, cols[jj].datatype); ffpmsg(message); *status = BAD_DATATYPE; goto cleanup; } /* end of switch block */ /* check that all the arrays were allocated successfully */ if (!cols[jj].array) { ffpmsg("ffiter failed to allocate memory arrays"); *status = MEMORY_ALLOCATION; /* memory allocation failed */ goto cleanup; } } /*--------------------------------------------------*/ /* main loop while there are values left to process */ /*--------------------------------------------------*/ nleft = totaln; while (nleft) { ntodo = minvalue(nleft, n_optimum); /* no. of values for this loop */ /* read input columns from FITS file(s) */ for (jj = 0; jj < n_cols; jj++) { if (cols[jj].iotype != OutputCol) { if (cols[jj].datatype == TSTRING) { stringptr = cols[jj].array; dataptr = stringptr + 1; defaultnull = col[jj].null.stringnull; /* ptr to the null value */ } else { dataptr = (char *) cols[jj].array + col[jj].nullsize; defaultnull = &col[jj].null.charnull; /* ptr to the null value */ } if (hdutype == IMAGE_HDU) { if (ffgpv(cols[jj].fptr, cols[jj].datatype, felement, cols[jj].repeat * ntodo, defaultnull, dataptr, &anynul, status) > 0) { break; } } else { if (ffgtcl(cols[jj].fptr, cols[jj].colnum, &typecode, &rept,&width, status) > 0) goto cleanup; if (typecode<0) { /* get size of the variable length vector */ ffgdes(cols[jj].fptr, cols[jj].colnum, frow,&cols[jj].repeat, NULL,status); } if (ffgcv(cols[jj].fptr, cols[jj].datatype, cols[jj].colnum, frow, felement, cols[jj].repeat * ntodo, defaultnull, dataptr, &anynul, status) > 0) { break; } } /* copy the appropriate null value into first array element */ if (anynul) /* are there any nulls in the data? */ { if (cols[jj].datatype == TSTRING) { stringptr = cols[jj].array; memcpy(*stringptr, col[jj].null.stringnull, col[jj].nullsize); } else { memcpy(cols[jj].array, defaultnull, col[jj].nullsize); } } else /* no null values so copy zero into first element */ { if (cols[jj].datatype == TSTRING) { stringptr = cols[jj].array; memset(*stringptr, 0, col[jj].nullsize); } else { memset(cols[jj].array, 0, col[jj].nullsize); } } } } if (*status > 0) break; /* looks like an error occurred; quit immediately */ /* call work function */ if (hdutype == IMAGE_HDU) *status = work_fn(totaln, offset, felement, ntodo, n_cols, cols, userPointer); else *status = work_fn(totaln, offset, frow, ntodo, n_cols, cols, userPointer); if (*status > 0 || *status < -1 ) break; /* looks like an error occurred; quit immediately */ /* write output columns before quiting if status = -1 */ tstatus = 0; for (jj = 0; jj < n_cols; jj++) { if (cols[jj].iotype != InputCol) { if (cols[jj].datatype == TSTRING) { stringptr = cols[jj].array; dataptr = stringptr + 1; nullptr = *stringptr; nbytes = 2; } else { dataptr = (char *) cols[jj].array + col[jj].nullsize; nullptr = (char *) cols[jj].array; nbytes = col[jj].nullsize; } if (memcmp(nullptr, &zeros, nbytes) ) { /* null value flag not zero; must check for and write nulls */ if (hdutype == IMAGE_HDU) { if (ffppn(cols[jj].fptr, cols[jj].datatype, felement, cols[jj].repeat * ntodo, dataptr, nullptr, &tstatus) > 0) break; } else { if (ffgtcl(cols[jj].fptr, cols[jj].colnum, &typecode, &rept,&width, status) > 0) goto cleanup; if (typecode<0) /* variable length array colum */ { ffgdes(cols[jj].fptr, cols[jj].colnum, frow,&cols[jj].repeat, NULL,status); } if (ffpcn(cols[jj].fptr, cols[jj].datatype, cols[jj].colnum, frow, felement, cols[jj].repeat * ntodo, dataptr, nullptr, &tstatus) > 0) break; } } else { /* no null values; just write the array */ if (hdutype == IMAGE_HDU) { if (ffppr(cols[jj].fptr, cols[jj].datatype, felement, cols[jj].repeat * ntodo, dataptr, &tstatus) > 0) break; } else { if (ffgtcl(cols[jj].fptr, cols[jj].colnum, &typecode, &rept,&width, status) > 0) goto cleanup; if (typecode<0) /* variable length array column */ { ffgdes(cols[jj].fptr, cols[jj].colnum, frow,&cols[jj].repeat, NULL,status); } if (ffpcl(cols[jj].fptr, cols[jj].datatype, cols[jj].colnum, frow, felement, cols[jj].repeat * ntodo, dataptr, &tstatus) > 0) break; } } } } if (*status == 0) *status = tstatus; /* propagate any error status from the writes */ if (*status) break; /* exit on any error */ nleft -= ntodo; if (hdutype == IMAGE_HDU) felement += ntodo; else frow += ntodo; } cleanup: /*----------------------------------*/ /* free work arrays for the columns */ /*----------------------------------*/ for (jj = 0; jj < n_cols; jj++) { if (cols[jj].datatype == TSTRING) { if (cols[jj].array) { stringptr = cols[jj].array; free(*stringptr); /* free the block of strings */ free(col[jj].null.stringnull); /* free the null string */ } } if (cols[jj].array) free(cols[jj].array); /* memory for the array of values from the col */ } free(col); /* the structure containing the null values */ return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/putcolb.c0000644000175100001710000011124000000000000017736 0ustar00vstsdocker/* This file, putcolb.c, contains routines that write data elements to */ /* a FITS image or table with char (byte) datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpprb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned char *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; unsigned char nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TBYTE, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpclb(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned char *array, /* I - array of values that are written */ unsigned char nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; unsigned char nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TBYTE, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcnb(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2db(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ unsigned char *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3db(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3db(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ unsigned char *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; LONGLONG nfits, narray; long fpixel[3]= {1,1,1}, lpixel[3]; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TBYTE, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpclb(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpclb(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssb(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ unsigned char *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TBYTE, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpclb(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ unsigned char *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpclb(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpclb( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned char *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int writemode; int tcode, maxelem2, hdutype, writeraw; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull, maxelem; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ /* IMPORTANT NOTE: that the special case of using this subroutine to write bytes to a character column are handled internally by the call to ffgcprll() below. It will adjust the effective *tcode, repeats, etc, to appear as a TBYTE column. */ writemode = 17; /* Equivalent to writemode = 1 but allow TSTRING -> TBYTE */ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, writemode, &scale, &zero, tform, &twidth, &tcode, &maxelem2, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); maxelem = maxelem2; if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /* if there is no scaling then we can simply write the raw data bytes into the FITS file if the datatype of the FITS column is the same as the input values. Otherwise, we must convert the raw values into the scaled and/or machine dependent format in a temporary buffer that has been allocated for this purpose. */ if (scale == 1. && zero == 0. && tcode == TBYTE) { writeraw = 1; if (nelem < (LONGLONG)INT32_MAX) { maxelem = nelem; } else { maxelem = INT32_MAX; } } else writeraw = 0; /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TBYTE): if (writeraw) { /* write raw input bytes without conversion */ ffpi1b(fptr, ntodo, incre, &array[next], status); } else { /* convert the raw data before writing to FITS file */ ffi1fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); } break; case (TLONGLONG): ffi1fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TSHORT): ffi1fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TLONG): ffi1fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TFLOAT): ffi1fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffi1fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (strchr(tform,'A')) { /* write raw input bytes without conversion */ /* This case is a hack to let users write a stream */ /* of bytes directly to the 'A' format column */ if (incre == twidth) { ffpbyt(fptr, ntodo, &array[next], status); } else { ffpbytoff(fptr, twidth, ntodo/twidth, incre - twidth, &array[next], status); } break; } else if (cform[1] != 's') /* "%s" format is a string */ { ffi1fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ snprintf(message, FLEN_ERRMSG, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { snprintf(message,FLEN_ERRMSG, "Error writing elements %.0f thru %.0f of input data array (ffpclb).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnb( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned char *array, /* I - array of values to write */ unsigned char nulvalue, /* I - flag for undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; LONGLONG ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpclb(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood + 1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpclb(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad + 1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpclb(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffpextn( fitsfile *fptr, /* I - FITS file pointer */ LONGLONG offset, /* I - byte offset from start of extension data */ LONGLONG nelem, /* I - number of elements to write */ void *buffer, /* I - stream of bytes to write */ int *status) /* IO - error status */ /* Write a stream of bytes to the current FITS HDU. This primative routine is mainly for writing non-standard "conforming" extensions and should not be used for standard IMAGE, TABLE or BINTABLE extensions. */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); /* move to write position */ ffmbyt(fptr, (fptr->Fptr)->datastart+ offset, IGNORE_EOF, status); /* write the buffer */ ffpbyt(fptr, nelem, buffer, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffi1fi1(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { memcpy(output, input, ntodo); /* just copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) { dvalue = ( ((double) input[ii]) - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi1fi2(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; /* just copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (((double) input[ii]) - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi1fi4(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (INT32BIT) input[ii]; /* copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (((double) input[ii]) - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi1fi8(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 9223372036854775808.) { /* Writing to unsigned long long column. */ /* Instead of subtracting 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ /* no need to check range limits because all unsigned char values */ /* are valid ULONGLONG values. */ for (ii = 0; ii < ntodo; ii++) { output[ii] = ((LONGLONG) input[ii]) ^ 0x8000000000000000; } } else if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi1fr4(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) (( ( (double) input[ii] ) - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffi1fr8(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = ( ( (double) input[ii] ) - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffi1fstr(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; char *cptr; cptr = output; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = ((double) input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } /* replace any commas with periods (e.g., in French locale) */ while ((cptr = strchr(cptr, ','))) *cptr = '.'; return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/putcold.c0000644000175100001710000011350200000000000017743 0ustar00vstsdocker/* This file, putcold.c, contains routines that write data elements to */ /* a FITS image or table, with double datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpprd( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ double *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; double nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TDOUBLE, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcld(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnd( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ double *array, /* I - array of values that are written */ double nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; double nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TDOUBLE, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcnd(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2dd(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ double *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3dd(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3dd(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ double *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TDOUBLE, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpcld(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpcld(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssd(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ double *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TDOUBLE, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpcld(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpd( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ double *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpcld(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcld( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ double *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem2, hdutype, writeraw; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull, maxelem; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem2, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); maxelem = maxelem2; if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /* if there is no scaling and the native machine format is not byteswapped, then we can simply write the raw data bytes into the FITS file if the datatype of the FITS column is the same as the input values. Otherwise, we must convert the raw values into the scaled and/or machine dependent format in a temporary buffer that has been allocated for this purpose. */ if (scale == 1. && zero == 0. && MACHINE == NATIVE && tcode == TDOUBLE) { writeraw = 1; if (nelem < (LONGLONG)INT32_MAX) { maxelem = nelem; } else { maxelem = INT32_MAX/8; } } else writeraw = 0; /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TDOUBLE): if (writeraw) { /* write raw input bytes without conversion */ ffpr8b(fptr, ntodo, incre, &array[next], status); } else { /* convert the raw data before writing to FITS file */ ffr8fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); } break; case (TLONGLONG): ffr8fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TBYTE): ffr8fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TSHORT): ffr8fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TLONG): ffr8fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TFLOAT): ffr8fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffr8fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ snprintf(message, FLEN_ERRMSG, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { snprintf(message,FLEN_ERRMSG, "Error writing elements %.0f thru %.0f of input data array (ffpcld).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpclm( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ double *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of double complex values to a column in the current FITS HDU. Each complex number if interpreted as a pair of float values. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column if necessary, but normally complex values should only be written to a binary table with TFORMn = 'rM' where r is an optional repeat count. The TSCALn and TZERO keywords should not be used with complex numbers because mathmatically the scaling should only be applied to the real (first) component of the complex value. */ { /* simply multiply the number of elements by 2, and call ffpcld */ ffpcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnd( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ double *array, /* I - array of values to write */ double nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; LONGLONG ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ if (abs(tcode) >= TCOMPLEX) { /* treat complex columns as pairs of numbers */ repeat *= 2; } /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpcld(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ /* call ffpcluc, not ffpclu, in case we are writing to a complex ('C') binary table column */ if (ffpcluc(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpcld(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpcld(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpcluc(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr8fi1(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr8fi2(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr8fi4(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (input[ii] > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else output[ii] = (INT32BIT) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr8fi8(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 9223372036854775808.) { /* Writing to unsigned long long column. Input values must not be negative */ /* Instead of subtracting 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { if (input[ii] < -0.49) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (input[ii] > 2.* DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { output[ii] = ((LONGLONG) input[ii]) ^ 0x8000000000000000; } } } else if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (input[ii] > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr8fr4(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) ((input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffr8fr8(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { memcpy(output, input, ntodo * sizeof(double) ); /* copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffr8fstr(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; char *cptr; cptr = output; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } /* replace any commas with periods (e.g., in French locale) */ while ((cptr = strchr(cptr, ','))) *cptr = '.'; return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/putcole.c0000644000175100001710000011457400000000000017756 0ustar00vstsdocker/* This file, putcole.c, contains routines that write data elements to */ /* a FITS image or table, with float datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffppre( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ float *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). This routine cannot be called directly by users to write to large arrays with > 2**31 pixels (although CFITSIO can do so by passing the firstelem thru a LONGLONG sized global variable) */ { long row; float nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TFLOAT, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcle(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppne( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ float *array, /* I - array of values that are written */ float nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. This routine cannot be called directly by users to write to large arrays with > 2**31 pixels (although CFITSIO can do so by passing the firstelem thru a LONGLONG sized global variable) */ { long row; float nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TFLOAT, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcne(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2de(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ float *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). This routine does not support writing to large images with more than 2**31 pixels. */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3de(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3de(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ float *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). This routine does not support writing to large images with more than 2**31 pixels. */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TFLOAT, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpcle(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpcle(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpsse(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ float *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TFLOAT, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpcle(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpe( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ float *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpcle(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcle( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ float *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem2, hdutype, writeraw; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull, maxelem; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem2, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); maxelem = maxelem2; if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /* if there is no scaling and the native machine format is not byteswapped then we can simply write the raw data bytes into the FITS file if the datatype of the FITS column is the same as the input values. Otherwise, we must convert the raw values into the scaled and/or machine dependent format in a temporary buffer that has been allocated for this purpose. */ if (scale == 1. && zero == 0. && MACHINE == NATIVE && tcode == TFLOAT) { writeraw = 1; if (nelem < (LONGLONG)INT32_MAX) { maxelem = nelem; } else { maxelem = INT32_MAX/4; } } else writeraw = 0; /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TFLOAT): if (writeraw) { /* write raw input bytes without conversion */ ffpr4b(fptr, ntodo, incre, &array[next], status); } else { /* convert the raw data before writing to FITS file */ ffr4fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); } break; case (TLONGLONG): ffr4fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TBYTE): ffr4fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TSHORT): ffr4fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TLONG): ffr4fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TDOUBLE): ffr4fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffr4fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ snprintf(message, FLEN_ERRMSG, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { snprintf(message,FLEN_ERRMSG, "Error writing elements %.0f thru %.0f of input data array (ffpcle).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpclc( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ float *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of complex values to a column in the current FITS HDU. Each complex number if interpreted as a pair of float values. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column if necessary, but normally complex values should only be written to a binary table with TFORMn = 'rC' where r is an optional repeat count. The TSCALn and TZERO keywords should not be used with complex numbers because mathmatically the scaling should only be applied to the real (first) component of the complex value. */ { /* simply multiply the number of elements by 2, and call ffpcle */ ffpcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcne( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ float *array, /* I - array of values to write */ float nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; LONGLONG ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ if (abs(tcode) >= TCOMPLEX) { /* treat complex columns as pairs of numbers */ repeat *= 2; } /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpcle(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ /* call ffpcluc, not ffpclu, in case we are writing to a complex ('C') binary table column */ if (ffpcluc(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpcle(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpcle(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpcluc(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr4fi1(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr4fi2(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr4fi4(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (input[ii] > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else output[ii] = (INT32BIT) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr4fi8(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 9223372036854775808.) { /* Writing to unsigned long long column. Input values must not be negative */ /* Instead of subtracting 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { if (input[ii] < -0.49) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (input[ii] > 2.* DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { output[ii] = ((LONGLONG) input[ii]) ^ 0x8000000000000000; } } } else if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (input[ii] > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (long) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr4fr4(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { memcpy(output, input, ntodo * sizeof(float) ); /* copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) ((input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffr4fr8(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffr4fstr(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; char *cptr; cptr = output; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } /* replace any commas with periods (e.g., in French locale) */ while ((cptr = strchr(cptr, ','))) *cptr = '.'; return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/putcoli.c0000644000175100001710000010515700000000000017757 0ustar00vstsdocker/* This file, putcoli.c, contains routines that write data elements to */ /* a FITS image or table, with short datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffppri( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ short *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; short nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TSHORT, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcli(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppni( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ short *array, /* I - array of values that are written */ short nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; short nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TSHORT, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcni(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2di(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ short *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3di(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3di(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ short *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TSHORT, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpcli(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpcli(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssi(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ short *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TSHORT, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpcli(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpi( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ short *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpcli(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcli( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ short *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem2, hdutype, writeraw; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull, maxelem; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem2, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); maxelem = maxelem2; if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /* if there is no scaling and the native machine format is not byteswapped, then we can simply write the raw data bytes into the FITS file if the datatype of the FITS column is the same as the input values. Otherwise, we must convert the raw values into the scaled and/or machine dependent format in a temporary buffer that has been allocated for this purpose. */ if (scale == 1. && zero == 0. && MACHINE == NATIVE && tcode == TSHORT) { writeraw = 1; if (nelem < (LONGLONG)INT32_MAX) { maxelem = nelem; } else { maxelem = INT32_MAX/2; } } else writeraw = 0; /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TSHORT): if (writeraw) { /* write raw input bytes without conversion */ ffpi2b(fptr, ntodo, incre, &array[next], status); } else { /* convert the raw data before writing to FITS file */ ffi2fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); } break; case (TLONGLONG): ffi2fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TBYTE): ffi2fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TLONG): ffi2fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TFLOAT): ffi2fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffi2fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffi2fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ snprintf(message,FLEN_ERRMSG, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { snprintf(message,FLEN_ERRMSG, "Error writing elements %.0f thru %.0f of input data array (ffpcli).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpcni( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ short *array, /* I - array of values to write */ short nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; LONGLONG ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpcli(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpcli(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpcli(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi2fi1(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi2fi2(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { memcpy(output, input, ntodo * sizeof(short) ); } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi2fi4(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (INT32BIT) input[ii]; /* just copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi2fi8(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 9223372036854775808.) { /* Writing to unsigned long long column. Input values must not be negative */ /* Instead of subtracting 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else { output[ii] = ((LONGLONG) input[ii]) ^ 0x8000000000000000; } } } else if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi2fr4(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) ((input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffi2fr8(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffi2fstr(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; char *cptr; cptr = output; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } /* replace any commas with periods (e.g., in French locale) */ while ((cptr = strchr(cptr, ','))) *cptr = '.'; return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/putcolj.c0000644000175100001710000021340500000000000017754 0ustar00vstsdocker/* This file, putcolj.c, contains routines that write data elements to */ /* a FITS image or table, with long datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpprj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ long *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; long nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TLONG, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpclj(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ long *array, /* I - array of values that are written */ long nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; long nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TLONG, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcnj(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2dj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ long *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3dj(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3dj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ long *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TLONG, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpclj(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpclj(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ long *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TLONG, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpclj(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ long *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpclj(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpclj( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ long *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem2, hdutype, writeraw; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull, maxelem; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem2, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); maxelem = maxelem2; if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /* if there is no scaling and the native machine format is not byteswapped then we can simply write the raw data bytes into the FITS file if the datatype of the FITS column is the same as the input values. Otherwise we must convert the raw values into the scaled and/or machine dependent format in a temporary buffer that has been allocated for this purpose. */ if (scale == 1. && zero == 0. && MACHINE == NATIVE && tcode == TLONG && LONGSIZE == 32) { writeraw = 1; if (nelem < (LONGLONG)INT32_MAX) { maxelem = nelem; } else { maxelem = INT32_MAX/8; } } else writeraw = 0; /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TLONG): if (writeraw) { /* write raw input bytes without conversion */ ffpi4b(fptr, ntodo, incre, (INT32BIT *) &array[next], status); } else { /* convert the raw data before writing to FITS file */ ffi4fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); } break; case (TLONGLONG): ffi4fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TBYTE): ffi4fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TSHORT): ffi4fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TFLOAT): ffi4fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffi4fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffi4fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ snprintf(message, FLEN_ERRMSG, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { snprintf(message,FLEN_ERRMSG, "Error writing elements %.0f thru %.0f of input data array (ffpclj).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnj( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ long *array, /* I - array of values to write */ long nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; LONGLONG ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpclj(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood + 1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpclj(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpclj(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi4fi1(long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi4fi2(long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < SHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi4fi4(long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (INT32BIT) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi4fi8(long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 9223372036854775808.) { /* Writing to unsigned long long column. Input values must not be negative */ /* Instead of subtracting 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else { output[ii] = ((LONGLONG) input[ii]) ^ 0x8000000000000000; } } } else if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi4fr4(long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) ((input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffi4fr8(long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffi4fstr(long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; char *cptr; cptr = output; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } /* replace any commas with periods (e.g., in French locale) */ while ((cptr = strchr(cptr, ','))) *cptr = '.'; return(*status); } /* ======================================================================== */ /* the following routines support the 'long long' data type */ /* ======================================================================== */ /*--------------------------------------------------------------------------*/ int ffpprjj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ LONGLONG *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ ffpmsg("writing TLONGLONG to compressed image is not supported"); return(*status = DATA_COMPRESSION_ERR); } row=maxvalue(1,group); ffpcljj(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnjj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ LONGLONG *array, /* I - array of values that are written */ LONGLONG nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ ffpmsg("writing TLONGLONG to compressed image is not supported"); return(*status = DATA_COMPRESSION_ERR); } row=maxvalue(1,group); ffpcnjj(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2djj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3djj(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3djj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ LONGLONG *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ ffpmsg("writing TLONGLONG to compressed image is not supported"); return(*status = DATA_COMPRESSION_ERR); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpcljj(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpcljj(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssjj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ LONGLONG *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ ffpmsg("writing TLONGLONG to compressed image is not supported"); return(*status = DATA_COMPRESSION_ERR); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpcljj(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpjj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ LONGLONG *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpcljj(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcljj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ LONGLONG *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem2, hdutype, writeraw; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull, maxelem; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem2, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); maxelem = maxelem2; if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /* if there is no scaling and the native machine format is not byteswapped then we can simply write the raw data bytes into the FITS file if the datatype of the FITS column is the same as the input values. Otherwise we must convert the raw values into the scaled and/or machine dependent format in a temporary buffer that has been allocated for this purpose. */ if (scale == 1. && zero == 0. && MACHINE == NATIVE && tcode == TLONGLONG) { writeraw = 1; if (nelem < (LONGLONG)INT32_MAX/8) { maxelem = nelem; } else { maxelem = INT32_MAX/8; } } else writeraw = 0; /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TLONGLONG): if (writeraw) { /* write raw input bytes without conversion */ ffpi8b(fptr, ntodo, incre, (long *) &array[next], status); } else { /* convert the raw data before writing to FITS file */ ffi8fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); } break; case (TLONG): ffi8fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TBYTE): ffi8fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TSHORT): ffi8fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TFLOAT): ffi8fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffi8fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffi8fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ snprintf(message, FLEN_ERRMSG, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { snprintf(message,FLEN_ERRMSG, "Error writing elements %.0f thru %.0f of input data array (ffpclj).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnjj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ LONGLONG *array, /* I - array of values to write */ LONGLONG nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; LONGLONG ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpcljj(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpcljj(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpcljj(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi8fi1(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi8fi2(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < SHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi8fi4(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < INT32_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (input[ii] > INT32_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else output[ii] = (INT32BIT) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi8fi8(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 9223372036854775808.) { /* Writing to unsigned long long column. Input values must not be negative */ /* Instead of subtracting 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else { output[ii] = (input[ii]) ^ 0x8000000000000000; } } } else if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi8fr4(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) ((input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffi8fr8(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffi8fstr(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; char *cptr; cptr = output; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } /* replace any commas with periods (e.g., in French locale) */ while ((cptr = strchr(cptr, ','))) *cptr = '.'; return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/putcolk.c0000644000175100001710000010704600000000000017760 0ustar00vstsdocker/* This file, putcolk.c, contains routines that write data elements to */ /* a FITS image or table, with 'int' datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpprk( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ int *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; int nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TINT, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpclk(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnk( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ int *array, /* I - array of values that are written */ int nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; int nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TINT, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcnk(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2dk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ int *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3dk(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3dk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ int *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TINT, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpclk(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpclk(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ int *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TINT, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpclk(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpk( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ int *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpclk(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpclk( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ int *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem2, hdutype, writeraw; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull, maxelem; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* call the 'short' or 'long' version of this routine, if possible */ if (sizeof(int) == sizeof(short)) ffpcli(fptr, colnum, firstrow, firstelem, nelem, (short *) array, status); else if (sizeof(int) == sizeof(long)) ffpclj(fptr, colnum, firstrow, firstelem, nelem, (long *) array, status); else { /* This is a special case: sizeof(int) is not equal to sizeof(short) or sizeof(long). This occurs on Alpha OSF systems where short = 2 bytes, int = 4 bytes, and long = 8 bytes. */ buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem2, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); maxelem = maxelem2; if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /* if there is no scaling and the native machine format is not byteswapped then we can simply write the raw data bytes into the FITS file if the datatype of the FITS column is the same as the input values. Otherwise we must convert the raw values into the scaled and/or machine dependent format in a temporary buffer that has been allocated for this purpose. */ if (scale == 1. && zero == 0. && MACHINE == NATIVE && tcode == TLONG) { writeraw = 1; if (nelem < (LONGLONG)INT32_MAX) { maxelem = nelem; } else { maxelem = INT32_MAX/4; } } else writeraw = 0; /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TLONG): if (writeraw) { /* write raw input bytes without conversion */ ffpi4b(fptr, ntodo, incre, (INT32BIT *) &array[next], status); } else { /* convert the raw data before writing to FITS file */ ffintfi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); } break; case (TLONGLONG): ffintfi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TBYTE): ffintfi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TSHORT): ffintfi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TFLOAT): ffintfr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffintfr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffintfstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ snprintf(message, FLEN_ERRMSG, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { snprintf(message,FLEN_ERRMSG, "Error writing elements %.0f thru %.0f of input data array (ffpclk).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } } /* end of Dec ALPHA special case */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnk( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ int *array, /* I - array of values to write */ int nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; LONGLONG ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpclk(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpclk(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpclk(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffintfi1(int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffintfi2(int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < SHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffintfi4(int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { memcpy(output, input, ntodo * sizeof(int) ); } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffintfi8(int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 9223372036854775808.) { /* Writing to unsigned long long column. Input values must not be negative */ /* Instead of subtracting 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else { output[ii] = ((LONGLONG) input[ii]) ^ 0x8000000000000000; } } } else if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { output[ii] = input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffintfr4(int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) ((input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffintfr8(int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffintfstr(int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; char *cptr; cptr = output; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } /* replace any commas with periods (e.g., in French locale) */ while ((cptr = strchr(cptr, ','))) *cptr = '.'; return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/putcoll.c0000644000175100001710000003315500000000000017760 0ustar00vstsdocker/* This file, putcoll.c, contains routines that write data elements to */ /* a FITS image or table, with logical datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpcll( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ char *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of logical values to a column in the current FITS HDU. */ { int tcode, maxelem, hdutype; long twidth, incre; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], ctrue = 'T', cfalse = 'F'; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ if (*status > 0) /* inherit input status value if > 0 */ return(*status); /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode != TLOGICAL) return(*status = NOT_LOGICAL_COL); /*---------------------------------------------------------------------*/ /* Now write the logical values one at a time to the FITS column. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { wrtptr = startpos + (rowlen * rownum) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ if (array[next]) ffpbyt(fptr, 1, &ctrue, status); else ffpbyt(fptr, 1, &cfalse, status); if (*status > 0) /* test for error during previous write operation */ { snprintf(message,FLEN_ERRMSG, "Error writing element %.0f of input array of logicals (ffpcll).", (double) (next+1)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain--; if (remain) { next++; elemnum++; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnl( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ char *array, /* I - array of values to write */ char nulvalue, /* I - array flagging undefined pixels if true */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels flagged as null will be replaced by the appropriate null value in the output FITS file. */ { tcolumn *colptr; LONGLONG ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* first write the whole input vector, then go back and fill in the nulls */ if (ffpcll(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) return(*status); /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ /* good values have already been written if (ffpcll(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) return(*status); */ ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ /* these have already been written ffpcll(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); */ } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffpclx( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG frow, /* I - first row to write (1 = 1st row) */ long fbit, /* I - first bit to write (1 = 1st) */ long nbit, /* I - number of bits to write */ char *larray, /* I - array of logicals corresponding to bits */ int *status) /* IO - error status */ /* write an array of logical values to a specified bit or byte column of the binary table. If larray is TRUE, then the corresponding bit is set to 1, otherwise it is set to 0. The binary table column being written to must have datatype 'B' or 'X'. */ { LONGLONG offset, bstart, repeat, rowlen, elemnum, rstart, estart, tnull; long fbyte, lbyte, nbyte, bitloc, ndone; long ii, twidth, incre; int tcode, descrp, maxelem, hdutype; double dummyd; char tform[12], snull[12]; unsigned char cbuff; static unsigned char onbit[8] = {128, 64, 32, 16, 8, 4, 2, 1}; static unsigned char offbit[8] = {127, 191, 223, 239, 247, 251, 253, 254}; LONGLONG heapoffset, lrepeat; tcolumn *colptr; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check input parameters */ if (nbit < 1) return(*status); else if (frow < 1) return(*status = BAD_ROW_NUM); else if (fbit < 1) return(*status = BAD_ELEM_NUM); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); fbyte = (fbit + 7) / 8; lbyte = (fbit + nbit + 6) / 8; nbyte = lbyte - fbyte +1; /* Save the current heapsize; ffgcprll will increment the value if */ /* we are writing to a variable length column. */ offset = (fptr->Fptr)->heapsize; /* call ffgcprll in case we are writing beyond the current end of */ /* the table; it will allocate more space and shift any following */ /* HDU's. Otherwise, we have little use for most of the returned */ /* parameters, therefore just use dummy parameters. */ if (ffgcprll( fptr, colnum, frow, fbyte, nbyte, 1, &dummyd, &dummyd, tform, &twidth, &tcode, &maxelem, &bstart, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); bitloc = fbit - 1 - ((fbit - 1) / 8 * 8); ndone = 0; rstart = frow - 1; estart = fbyte - 1; colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (abs(tcode) > TBYTE) return(*status = NOT_LOGICAL_COL); /* not correct datatype column */ if (tcode > 0) { descrp = FALSE; /* not a variable length descriptor column */ repeat = colptr->trepeat; if (tcode == TBIT) repeat = (repeat + 7) / 8; /* convert from bits to bytes */ if (fbyte > repeat) return(*status = BAD_ELEM_NUM); /* calc the i/o pointer location to start of sequence of pixels */ bstart = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * rstart) + colptr->tbcol + estart; } else { descrp = TRUE; /* a variable length descriptor column */ /* only bit arrays (tform = 'X') are supported for variable */ /* length arrays. REPEAT is the number of BITS in the array. */ repeat = fbit + nbit -1; /* write the number of elements and the starting offset. */ /* Note: ffgcprll previous wrote the descripter, but with the */ /* wrong repeat value (gave bytes instead of bits). */ /* Make sure to not change the current heap offset value! */ if (tcode == -TBIT) { ffgdesll(fptr, colnum, frow, &lrepeat, &heapoffset, status); ffpdes( fptr, colnum, frow, (long) repeat, heapoffset, status); } /* Calc the i/o pointer location to start of sequence of pixels. */ /* ffgcprll has already calculated a value for bstart that */ /* points to the first element of the vector; we just have to */ /* increment it to point to the first element we want to write to. */ /* Note: ffgcprll also already updated the size of the heap, so we */ /* don't have to do that again here. */ bstart += estart; } /* move the i/o pointer to the start of the pixel sequence */ ffmbyt(fptr, bstart, IGNORE_EOF, status); /* read the next byte (we may only be modifying some of the bits) */ while (1) { if (ffgbyt(fptr, 1, &cbuff, status) == END_OF_FILE) { /* hit end of file trying to read the byte, so just set byte = 0 */ *status = 0; cbuff = 0; } /* move back, to be able to overwrite the byte */ ffmbyt(fptr, bstart, IGNORE_EOF, status); for (ii = bitloc; (ii < 8) && (ndone < nbit); ii++, ndone++) { if(larray[ndone]) cbuff = cbuff | onbit[ii]; else cbuff = cbuff & offbit[ii]; } ffpbyt(fptr, 1, &cbuff, status); /* write the modified byte */ if (ndone == nbit) /* finished all the bits */ return(*status); /* not done, so get the next byte */ bstart++; if (!descrp) { estart++; if (estart == repeat) { /* move the i/o pointer to the next row of pixels */ estart = 0; rstart = rstart + 1; bstart = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * rstart) + colptr->tbcol; ffmbyt(fptr, bstart, IGNORE_EOF, status); } } bitloc = 0; } } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/putcols.c0000644000175100001710000002530000000000000017760 0ustar00vstsdocker/* This file, putcols.c, contains routines that write data elements to */ /* a FITS image or table, of type character string. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpcls( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of strings to write */ char **array, /* I - array of pointers to strings */ int *status) /* IO - error status */ /* Write an array of string values to a column in the current FITS HDU. */ { int tcode, maxelem, hdutype, nchar; long twidth, incre; long ii, jj, ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], *blanks; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ tcolumn *colptr; double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ char *buffer, *arrayptr; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (colnum < 1 || colnum > (fptr->Fptr)->tfield) { snprintf(message, FLEN_ERRMSG,"Specified column number is out of range: %d", colnum); ffpmsg(message); return(*status = BAD_COL_NUM); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode == -TSTRING) /* variable length column in a binary table? */ { /* only write a single string; ignore value of firstelem */ nchar = maxvalue(1,strlen(array[0])); /* will write at least 1 char */ /* even if input string is null */ if (ffgcprll( fptr, colnum, firstrow, 1, nchar, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); /* simply move to write position, then write the string */ ffmbyt(fptr, startpos, IGNORE_EOF, status); ffpbyt(fptr, nchar, array[0], status); if (*status > 0) /* test for error during previous write operation */ { snprintf(message,FLEN_ERRMSG, "Error writing to variable length string column (ffpcls)."); ffpmsg(message); } return(*status); } else if (tcode == TSTRING) { if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); /* if string length is greater than a FITS block (2880 char) then must */ /* only write 1 string at a time, to force writein by ffpbyt instead of */ /* ffpbytoff (ffpbytoff can't handle this case) */ if (twidth > IOBUFLEN) { maxelem = 1; incre = twidth; repeat = 1; } blanks = (char *) malloc(twidth); /* string for blank fill values */ if (!blanks) { ffpmsg("Could not allocate memory for string (ffpcls)"); return(*status = ARRAY_TOO_BIG); } for (ii = 0; ii < twidth; ii++) blanks[ii] = ' '; /* fill string with blanks */ remain = nelem; /* remaining number of values to write */ } else return(*status = NOT_ASCII_COL); /*-------------------------------------------------------*/ /* Now write the strings to the FITS column. */ /*-------------------------------------------------------*/ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process at one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + (rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ buffer = (char *) cbuff; /* copy the user's strings into the buffer */ for (ii = 0; ii < ntodo; ii++) { arrayptr = array[next]; for (jj = 0; jj < twidth; jj++) /* copy the string, char by char */ { if (*arrayptr) { *buffer = *arrayptr; buffer++; arrayptr++; } else break; } for (;jj < twidth; jj++) /* fill field with blanks, if needed */ { *buffer = ' '; buffer++; } next++; } /* write the buffer full of strings to the FITS file */ if (incre == twidth) ffpbyt(fptr, ntodo * twidth, cbuff, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, cbuff, status); if (*status > 0) /* test for error during previous write operation */ { snprintf(message,FLEN_ERRMSG, "Error writing elements %.0f thru %.0f of input data array (ffpcls).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); if (blanks) free(blanks); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ if (blanks) free(blanks); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcns( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ char **array, /* I - array of values to write */ char *nulvalue, /* I - string representing a null value */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels flagged as null will be replaced by the appropriate null value in the output FITS file. */ { long repeat, width; LONGLONG ngood = 0, nbad = 0, ii; LONGLONG first, fstelm, fstrow; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } /* get the vector repeat length of the column */ ffgtcl(fptr, colnum, NULL, &repeat, &width, status); if ((fptr->Fptr)->hdutype == BINARY_TBL) repeat = repeat / width; /* convert from chars to unit strings */ /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (strcmp(nulvalue, array[ii])) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpcls(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) return(*status); ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpcls(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/putcolsb.c0000644000175100001710000010521200000000000020123 0ustar00vstsdocker/* This file, putcolsb.c, contains routines that write data elements to */ /* a FITS image or table with signed char (signed byte) datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpprsb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ signed char *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; signed char nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TSBYTE, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpclsb(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnsb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ signed char *array, /* I - array of values that are written */ signed char nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; signed char nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TSBYTE, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcnsb(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2dsb(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ signed char *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3dsb(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3dsb(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ signed char *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TSBYTE, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpclsb(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpclsb(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpsssb(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ signed char *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TSBYTE, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpclsb(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpsb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ signed char *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpclsb(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpclsb( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ signed char *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TBYTE): /* convert the raw data before writing to FITS file */ ffs1fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TLONGLONG): ffs1fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TSHORT): ffs1fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TLONG): ffs1fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TFLOAT): ffs1fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffs1fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (strchr(tform,'A')) { /* write raw input bytes without conversion */ /* This case is a hack to let users write a stream */ /* of bytes directly to the 'A' format column */ if (incre == twidth) ffpbyt(fptr, ntodo, &array[next], status); else ffpbytoff(fptr, twidth, ntodo/twidth, incre - twidth, &array[next], status); break; } else if (cform[1] != 's') /* "%s" format is a string */ { ffs1fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ snprintf(message, FLEN_ERRMSG, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { snprintf(message,FLEN_ERRMSG, "Error writing elements %.0f thru %.0f of input data array (ffpclsb).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnsb( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ signed char *array, /* I - array of values to write */ signed char nulvalue, /* I - flag for undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; LONGLONG ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpclsb(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood + 1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpclsb(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad + 1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpclsb(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffs1fi1(signed char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == -128.) { /* Instead of adding 128, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) output[ii] = ( *(unsigned char *) &input[ii] ) ^ 0x80; } else if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned char) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = ( ((double) input[ii]) - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffs1fi2(signed char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; /* just copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (((double) input[ii]) - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffs1fi4(signed char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (INT32BIT) input[ii]; /* copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (((double) input[ii]) - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffs1fi8(signed char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 9223372036854775808.) { /* Writing to unsigned long long column. Input values must not be negative */ /* Instead of subtracting 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else { output[ii] = ((LONGLONG) input[ii]) ^ 0x8000000000000000; } } } else if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffs1fr4(signed char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) (( ( (double) input[ii] ) - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffs1fr8(signed char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = ( ( (double) input[ii] ) - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffs1fstr(signed char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; char *cptr; cptr = output; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = ((double) input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } /* replace any commas with periods (e.g., in French locale) */ while ((cptr = strchr(cptr, ','))) *cptr = '.'; return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/putcolu.c0000644000175100001710000005206300000000000017770 0ustar00vstsdocker/* This file, putcolu.c, contains routines that write data elements to */ /* a FITS image or table. Writes null values. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffppru( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ int *status) /* IO - error status */ /* Write null values to the primary array. */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ ffpmsg("writing to compressed image is not supported"); return(*status = DATA_COMPRESSION_ERR); } row=maxvalue(1,group); ffpclu(fptr, 2, row, firstelem, nelem, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpprn( fitsfile *fptr, /* I - FITS file pointer */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ int *status) /* IO - error status */ /* Write null values to the primary array. (Doesn't support groups). */ { long row = 1; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ ffpmsg("writing to compressed image is not supported"); return(*status = DATA_COMPRESSION_ERR); } ffpclu(fptr, 2, row, firstelem, nelem, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpclu( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelempar, /* I - number of values to write */ int *status) /* IO - error status */ /* Set elements of a table column to the appropriate null value for the column The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. This routine support COMPLEX and DOUBLE COMPLEX binary table columns, and sets both the real and imaginary components of the element to a NaN. */ { int tcode, maxelem, hdutype, writemode = 2, leng; short i2null; INT32BIT i4null; long twidth, incre; LONGLONG ii; LONGLONG largeelem, nelem, tnull, i8null; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, ntodo; double scale, zero; unsigned char i1null, lognul = 0; char tform[20], *cstring = 0; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ long jbuff[2] = { -1, -1}; /* all bits set is equivalent to a NaN */ size_t buffsize; if (*status > 0) /* inherit input status value if > 0 */ return(*status); nelem = nelempar; largeelem = firstelem; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ /* note that writemode = 2 by default (not 1), so that the returned */ /* repeat and incre values will be the actual values for this column. */ /* If writing nulls to a variable length column then dummy data values */ /* must have already been written to the heap. */ /* We just have to overwrite the previous values with null values. */ /* Set writemode = 0 in this case, to test that values have been written */ fits_get_coltype(fptr, colnum, &tcode, NULL, NULL, status); if (tcode < 0) writemode = 0; /* this is a variable length column */ if (abs(tcode) >= TCOMPLEX) { /* treat complex columns as pairs of numbers */ largeelem = (largeelem - 1) * 2 + 1; nelem *= 2; } if (ffgcprll( fptr, colnum, firstrow, largeelem, nelem, writemode, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) { if (snull[0] == ASCII_NULL_UNDEFINED) { ffpmsg( "Null value string for ASCII table column is not defined (FTPCLU)."); return(*status = NO_NULL); } /* allocate buffer to hold the null string. Must write the entire */ /* width of the column (twidth bytes) to avoid possible problems */ /* with uninitialized FITS blocks, in case the field spans blocks */ buffsize = maxvalue(20, twidth); cstring = (char *) malloc(buffsize); if (!cstring) return(*status = MEMORY_ALLOCATION); memset(cstring, ' ', buffsize); /* initialize with blanks */ leng = strlen(snull); if (hdutype == BINARY_TBL) leng++; /* copy the terminator too in binary tables */ strncpy(cstring, snull, leng); /* copy null string to temp buffer */ } else if ( tcode == TBYTE || tcode == TSHORT || tcode == TLONG || tcode == TLONGLONG) { if (tnull == NULL_UNDEFINED) { ffpmsg( "Null value for integer table column is not defined (FTPCLU)."); return(*status = NO_NULL); } if (tcode == TBYTE) i1null = (unsigned char) tnull; else if (tcode == TSHORT) { i2null = (short) tnull; #if BYTESWAPPED ffswap2(&i2null, 1); /* reverse order of bytes */ #endif } else if (tcode == TLONG) { i4null = (INT32BIT) tnull; #if BYTESWAPPED ffswap4(&i4null, 1); /* reverse order of bytes */ #endif } else { i8null = tnull; #if BYTESWAPPED ffswap8((double *)(&i8null), 1); /* reverse order of bytes */ #endif } } /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ ntodo = remain; /* number of elements to write at one time */ while (ntodo) { /* limit the number of pixels to process at one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TBYTE): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 1, &i1null, status); break; case (TSHORT): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 2, &i2null, status); break; case (TLONG): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 4, &i4null, status); break; case (TLONGLONG): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 8, &i8null, status); break; case (TFLOAT): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 4, jbuff, status); break; case (TDOUBLE): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 8, jbuff, status); break; case (TLOGICAL): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 1, &lognul, status); break; case (TSTRING): /* an ASCII table column */ /* repeat always = 1, so ntodo is also guaranteed to = 1 */ ffpbyt(fptr, twidth, cstring, status); break; default: /* error trap */ snprintf(message,FLEN_ERRMSG, "Cannot write null value to column %d which has format %s", colnum,tform); ffpmsg(message); return(*status); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { snprintf(message,FLEN_ERRMSG, "Error writing %.0f thru %.0f of null values (ffpclu).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); if (cstring) free(cstring); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } ntodo = remain; /* this is the maximum number to do in next loop */ } /* End of main while Loop */ if (cstring) free(cstring); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcluc( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ int *status) /* IO - error status */ /* Set elements of a table column to the appropriate null value for the column The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. This routine does not do anything special in the case of COMPLEX table columns (unlike the similar ffpclu routine). This routine is mainly for use by ffpcne which already compensates for the effective doubling of the number of elements in a complex column. */ { int tcode, maxelem, hdutype, writemode = 2, leng; short i2null; INT32BIT i4null; long twidth, incre; LONGLONG ii; LONGLONG tnull, i8null; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, ntodo; double scale, zero; unsigned char i1null, lognul = 0; char tform[20], *cstring = 0; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ long jbuff[2] = { -1, -1}; /* all bits set is equivalent to a NaN */ size_t buffsize; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ /* note that writemode = 2 by default (not 1), so that the returned */ /* repeat and incre values will be the actual values for this column. */ /* If writing nulls to a variable length column then dummy data values */ /* must have already been written to the heap. */ /* We just have to overwrite the previous values with null values. */ /* Set writemode = 0 in this case, to test that values have been written */ fits_get_coltype(fptr, colnum, &tcode, NULL, NULL, status); if (tcode < 0) writemode = 0; /* this is a variable length column */ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, writemode, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) { if (snull[0] == ASCII_NULL_UNDEFINED) { ffpmsg( "Null value string for ASCII table column is not defined (FTPCLU)."); return(*status = NO_NULL); } /* allocate buffer to hold the null string. Must write the entire */ /* width of the column (twidth bytes) to avoid possible problems */ /* with uninitialized FITS blocks, in case the field spans blocks */ buffsize = maxvalue(20, twidth); cstring = (char *) malloc(buffsize); if (!cstring) return(*status = MEMORY_ALLOCATION); memset(cstring, ' ', buffsize); /* initialize with blanks */ leng = strlen(snull); if (hdutype == BINARY_TBL) leng++; /* copy the terminator too in binary tables */ strncpy(cstring, snull, leng); /* copy null string to temp buffer */ } else if ( tcode == TBYTE || tcode == TSHORT || tcode == TLONG || tcode == TLONGLONG) { if (tnull == NULL_UNDEFINED) { ffpmsg( "Null value for integer table column is not defined (FTPCLU)."); return(*status = NO_NULL); } if (tcode == TBYTE) i1null = (unsigned char) tnull; else if (tcode == TSHORT) { i2null = (short) tnull; #if BYTESWAPPED ffswap2(&i2null, 1); /* reverse order of bytes */ #endif } else if (tcode == TLONG) { i4null = (INT32BIT) tnull; #if BYTESWAPPED ffswap4(&i4null, 1); /* reverse order of bytes */ #endif } else { i8null = tnull; #if BYTESWAPPED ffswap8((double *)(&i8null), 1); /* reverse order of bytes */ #endif } } /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ ntodo = remain; /* number of elements to write at one time */ while (ntodo) { /* limit the number of pixels to process at one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TBYTE): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 1, &i1null, status); break; case (TSHORT): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 2, &i2null, status); break; case (TLONG): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 4, &i4null, status); break; case (TLONGLONG): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 8, &i8null, status); break; case (TFLOAT): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 4, jbuff, status); break; case (TDOUBLE): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 8, jbuff, status); break; case (TLOGICAL): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 1, &lognul, status); break; case (TSTRING): /* an ASCII table column */ /* repeat always = 1, so ntodo is also guaranteed to = 1 */ ffpbyt(fptr, twidth, cstring, status); break; default: /* error trap */ snprintf(message, FLEN_ERRMSG, "Cannot write null value to column %d which has format %s", colnum,tform); ffpmsg(message); return(*status); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { snprintf(message,FLEN_ERRMSG, "Error writing %.0f thru %.0f of null values (ffpclu).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); if (cstring) free(cstring); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } ntodo = remain; /* this is the maximum number to do in next loop */ } /* End of main while Loop */ if (cstring) free(cstring); return(*status); } /*--------------------------------------------------------------------------*/ int ffprwu(fitsfile *fptr, LONGLONG firstrow, LONGLONG nrows, int *status) /* * fits_write_nullrows / ffprwu - write TNULLs to all columns in one or more rows * * fitsfile *fptr - pointer to FITS HDU opened for read/write * long int firstrow - first table row to set to null. (firstrow >= 1) * long int nrows - total number or rows to set to null. (nrows >= 1) * int *status - upon return, *status contains CFITSIO status code * * RETURNS: CFITSIO status code * * written by Craig Markwardt, GSFC */ { LONGLONG ntotrows; int ncols, i; int typecode = 0; LONGLONG repeat = 0, width = 0; int nullstatus; if (*status > 0) return *status; if ((firstrow <= 0) || (nrows <= 0)) return (*status = BAD_ROW_NUM); fits_get_num_rowsll(fptr, &ntotrows, status); if (firstrow + nrows - 1 > ntotrows) return (*status = BAD_ROW_NUM); fits_get_num_cols(fptr, &ncols, status); if (*status) return *status; /* Loop through each column and write nulls */ for (i=1; i <= ncols; i++) { repeat = 0; typecode = 0; width = 0; fits_get_coltypell(fptr, i, &typecode, &repeat, &width, status); if (*status) break; /* NOTE: data of TSTRING type must not write the total repeat count, since the repeat count is the *character* count, not the nstring count. Divide by string width to get number of strings. */ if (typecode == TSTRING) repeat /= width; /* Write NULLs */ nullstatus = 0; fits_write_col_null(fptr, i, firstrow, 1, repeat*nrows, &nullstatus); /* ignore error if no null value is defined for the column */ if (nullstatus && nullstatus != NO_NULL) return (*status = nullstatus); } return *status; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/putcolui.c0000644000175100001710000010402500000000000020135 0ustar00vstsdocker/* This file, putcolui.c, contains routines that write data elements to */ /* a FITS image or table, with unsigned short datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpprui(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned short *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; unsigned short nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TUSHORT, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpclui(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnui(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned short *array, /* I - array of values that are written */ unsigned short nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; unsigned short nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TUSHORT, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcnui(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2dui(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ unsigned short *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3dui(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3dui(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ unsigned short *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TUSHORT, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpclui(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpclui(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssui(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ unsigned short *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TUSHORT, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpclui(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpui( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ unsigned short *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpclui(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpclui( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned short *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TSHORT): ffu2fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TLONGLONG): ffu2fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TBYTE): ffu2fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TLONG): ffu2fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TFLOAT): ffu2fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffu2fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffu2fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ snprintf(message,FLEN_ERRMSG, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { snprintf(message,FLEN_ERRMSG, "Error writing elements %.0f thru %.0f of input data array (ffpclui).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnui(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned short *array, /* I - array of values to write */ unsigned short nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; LONGLONG ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpclui(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpclui(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpclui(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu2fi1(unsigned short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = ((double) input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu2fi2(unsigned short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 32768.) { /* Instead of subtracting 32768, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) output[ii] = ( *(short *) &input[ii] ) ^ 0x8000; } else if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = ((double) input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu2fi4(unsigned short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (INT32BIT) input[ii]; /* copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) { dvalue = ((double) input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu2fi8(unsigned short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 9223372036854775808.) { /* Writing to unsigned long long column. */ /* Instead of subtracting 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ /* no need to check range limits because all unsigned short values */ /* are valid ULONGLONG values. */ for (ii = 0; ii < ntodo; ii++) { output[ii] = ((LONGLONG) input[ii]) ^ 0x8000000000000000; } } else if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu2fr4(unsigned short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) (((double) input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffu2fr8(unsigned short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = ((double) input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffu2fstr(unsigned short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; char *cptr; cptr = output; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = ((double) input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } /* replace any commas with periods (e.g., in French locale) */ while ((cptr = strchr(cptr, ','))) *cptr = '.'; return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/putcoluj.c0000644000175100001710000020740200000000000020141 0ustar00vstsdocker/* This file, putcoluj.c, contains routines that write data elements to */ /* a FITS image or table, with unsigned long datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffppruj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned long *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; unsigned long nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TULONG, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcluj(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnuj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned long *array, /* I - array of values that are written */ unsigned long nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; unsigned long nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TULONG, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcnuj(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2duj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ unsigned long *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3duj(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3duj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ unsigned long *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TULONG, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpcluj(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpcluj(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssuj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ unsigned long *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TULONG, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpcluj(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpuj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ unsigned long *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpcluj(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcluj( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned long *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TLONG): ffu4fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TLONGLONG): ffu4fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TBYTE): ffu4fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TSHORT): ffu4fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TFLOAT): ffu4fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffu4fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffu4fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ snprintf(message,FLEN_ERRMSG, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { snprintf(message,FLEN_ERRMSG, "Error writing elements %.0f thru %.0f of input data array (ffpcluj).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnuj( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned long *array, /* I - array of values to write */ unsigned long nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; LONGLONG ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpcluj(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpcluj(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpcluj(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu4fi1(unsigned long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu4fi2(unsigned long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu4fi4(unsigned long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 2147483648. && sizeof(long) == 4) { /* Instead of subtracting 2147483648, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) output[ii] = ( *(long *) &input[ii] ) ^ 0x80000000; } else if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > INT32_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else output[ii] = input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu4fi8(unsigned long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 9223372036854775808.) { /* Writing to unsigned long long column. */ /* Instead of subtracting 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ /* no need to check range limits because all unsigned long values */ /* are valid ULONGLONG values. */ for (ii = 0; ii < ntodo; ii++) { output[ii] = ((LONGLONG) input[ii]) ^ 0x8000000000000000; } } else if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu4fr4(unsigned long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) ((input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffu4fr8(unsigned long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffu4fstr(unsigned long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; char *cptr; cptr = output; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } /* replace any commas with periods (e.g., in French locale) */ while ((cptr = strchr(cptr, ','))) *cptr = '.'; return(*status); } /* ======================================================================== */ /* the following routines support the 'unsigned long long' data type */ /* ======================================================================== */ /*--------------------------------------------------------------------------*/ int ffpprujj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ ULONGLONG *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; unsigned long nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ ffpmsg("writing TULONGLONG to compressed image is not supported"); return(*status = DATA_COMPRESSION_ERR); } row=maxvalue(1,group); ffpclujj(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnujj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ ULONGLONG *array, /* I - array of values that are written */ ULONGLONG nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ ffpmsg("writing TULONGLONG to compressed image is not supported"); return(*status = DATA_COMPRESSION_ERR); } row=maxvalue(1,group); ffpcnujj(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2dujj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ ULONGLONG *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3dujj(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3dujj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ ULONGLONG *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ ffpmsg("writing TULONGLONG to compressed image is not supported"); return(*status = DATA_COMPRESSION_ERR); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpclujj(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpclujj(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssujj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ ULONGLONG *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ ffpmsg("writing TULONGLONG to compressed image is not supported"); return(*status = DATA_COMPRESSION_ERR); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpclujj(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpujj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ ULONGLONG *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpclujj(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpclujj( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ ULONGLONG *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TLONGLONG): ffu8fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TLONG): ffu8fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TBYTE): ffu8fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TSHORT): ffu8fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TFLOAT): ffu8fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffu8fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffu8fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ snprintf(message, FLEN_ERRMSG, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { snprintf(message, FLEN_ERRMSG, "Error writing elements %.0f thru %.0f of input data array (ffpcluj).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnujj( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ ULONGLONG *array, /* I - array of values to write */ ULONGLONG nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; LONGLONG ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpclujj(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpclujj(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpclujj(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu8fi1(ULONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu8fi2(ULONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu8fi4(ULONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > INT32_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else output[ii] = input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu8fi8(ULONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 9223372036854775808.) { /* Writing to unsigned long long column. */ /* Instead of subtracting 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ /* no need to check range limits because all input values */ /* are valid ULONGLONG values. */ for (ii = 0; ii < ntodo; ii++) { output[ii] = ((LONGLONG) input[ii]) ^ 0x8000000000000000; } } else if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > LONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { output[ii] = input[ii]; } } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu8fr4(ULONGLONG *input , /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) ((input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffu8fr8(ULONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffu8fstr(ULONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; char *cptr; cptr = output; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } /* replace any commas with periods (e.g., in French locale) */ while ((cptr = strchr(cptr, ','))) *cptr = '.'; return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/putcoluk.c0000644000175100001710000010550500000000000020143 0ustar00vstsdocker/* This file, putcolk.c, contains routines that write data elements to */ /* a FITS image or table, with 'unsigned int' datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffppruk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned int *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; unsigned int nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TUINT, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcluk(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnuk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned int *array, /* I - array of values that are written */ unsigned int nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; unsigned int nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TUINT, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcnuk(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2duk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ unsigned int *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3duk(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3duk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ unsigned int *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TUINT, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpcluk(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpcluk(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssuk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ unsigned int *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TUINT, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpcluk(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpuk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ unsigned int *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpcluk(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcluk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned int *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* call the 'short' or 'long' version of this routine, if possible */ if (sizeof(int) == sizeof(short)) ffpclui(fptr, colnum, firstrow, firstelem, nelem, (unsigned short *) array, status); else if (sizeof(int) == sizeof(long)) ffpcluj(fptr, colnum, firstrow, firstelem, nelem, (unsigned long *) array, status); else { /* This is a special case: sizeof(int) is not equal to sizeof(short) or sizeof(long). This occurs on Alpha OSF systems where short = 2 bytes, int = 4 bytes, and long = 8 bytes. */ buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TLONG): /* convert the raw data before writing to FITS file */ ffuintfi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TLONGLONG): ffuintfi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TBYTE): ffuintfi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TSHORT): ffuintfi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TFLOAT): ffuintfr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffuintfr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffuintfstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ snprintf(message,FLEN_ERRMSG, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { snprintf(message,FLEN_ERRMSG, "Error writing elements %.0f thru %.0f of input data array (ffpcluk).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } } /* end of Dec ALPHA special case */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnuk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned int *array, /* I - array of values to write */ unsigned int nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; LONGLONG ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpcluk(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpcluk(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpcluk(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffuintfi1(unsigned int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffuintfi2(unsigned int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffuintfi4(unsigned int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 2147483648.) { /* Instead of subtracting 2147483648, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) output[ii] = ( *(int *) &input[ii] ) ^ 0x80000000; } else if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > INT32_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else output[ii] = input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffuintfi8(unsigned int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 9223372036854775808.) { /* Writing to unsigned long long column. */ /* Instead of subtracting 9223372036854775808, it is more efficient */ /* and more precise to just flip the sign bit with the XOR operator */ /* no need to check range limits because all unsigned int values */ /* are valid ULONGLONG values. */ for (ii = 0; ii < ntodo; ii++) { output[ii] = ((LONGLONG) input[ii]) ^ 0x8000000000000000; } } else if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { output[ii] = input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffuintfr4(unsigned int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) ((input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffuintfr8(unsigned int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffuintfstr(unsigned int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; char *cptr; cptr = output; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } /* replace any commas with periods (e.g., in French locale) */ while ((cptr = strchr(cptr, ','))) *cptr = '.'; return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/putkey.c0000644000175100001710000034124000000000000017614 0ustar00vstsdocker/* This file, putkey.c, contains routines that write keywords to */ /* a FITS header. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include /* stddef.h is apparently needed to define size_t */ #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffcrim(fitsfile *fptr, /* I - FITS file pointer */ int bitpix, /* I - bits per pixel */ int naxis, /* I - number of axes in the array */ long *naxes, /* I - size of each axis */ int *status) /* IO - error status */ /* create an IMAGE extension following the current HDU. If the current HDU is empty (contains no header keywords), then simply write the required image (or primary array) keywords to the current HDU. */ { if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* create new extension if current header is not empty */ if ((fptr->Fptr)->headend != (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) ffcrhd(fptr, status); /* write the required header keywords */ ffphpr(fptr, TRUE, bitpix, naxis, naxes, 0, 1, TRUE, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffcrimll(fitsfile *fptr, /* I - FITS file pointer */ int bitpix, /* I - bits per pixel */ int naxis, /* I - number of axes in the array */ LONGLONG *naxes, /* I - size of each axis */ int *status) /* IO - error status */ /* create an IMAGE extension following the current HDU. If the current HDU is empty (contains no header keywords), then simply write the required image (or primary array) keywords to the current HDU. */ { if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* create new extension if current header is not empty */ if ((fptr->Fptr)->headend != (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) ffcrhd(fptr, status); /* write the required header keywords */ ffphprll(fptr, TRUE, bitpix, naxis, naxes, 0, 1, TRUE, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffcrtb(fitsfile *fptr, /* I - FITS file pointer */ int tbltype, /* I - type of table to create */ LONGLONG naxis2, /* I - number of rows in the table */ int tfields, /* I - number of columns in the table */ char **ttype, /* I - name of each column */ char **tform, /* I - value of TFORMn keyword for each column */ char **tunit, /* I - value of TUNITn keyword for each column */ const char *extnm, /* I - value of EXTNAME keyword, if any */ int *status) /* IO - error status */ /* Create a table extension in a FITS file. */ { LONGLONG naxis1 = 0; long *tbcol = 0; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* create new extension if current header is not empty */ if ((fptr->Fptr)->headend != (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) ffcrhd(fptr, status); if ((fptr->Fptr)->curhdu == 0) /* have to create dummy primary array */ { ffcrim(fptr, 16, 0, tbcol, status); ffcrhd(fptr, status); } if (tbltype == BINARY_TBL) { /* write the required header keywords. This will write PCOUNT = 0 */ ffphbn(fptr, naxis2, tfields, ttype, tform, tunit, extnm, 0, status); } else if (tbltype == ASCII_TBL) { /* write the required header keywords */ /* default values for naxis1 and tbcol will be calculated */ ffphtb(fptr, naxis1, naxis2, tfields, ttype, tbcol, tform, tunit, extnm, status); } else *status = NOT_TABLE; return(*status); } /*-------------------------------------------------------------------------*/ int ffpktp(fitsfile *fptr, /* I - FITS file pointer */ const char *filename, /* I - name of template file */ int *status) /* IO - error status */ /* read keywords from template file and append to the FITS file */ { FILE *diskfile; char card[FLEN_CARD], template[161]; char keyname[FLEN_KEYWORD], newname[FLEN_KEYWORD]; int keytype; size_t slen; if (*status > 0) /* inherit input status value if > 0 */ return(*status); diskfile = fopen(filename,"r"); if (!diskfile) /* couldn't open file */ { ffpmsg("ffpktp could not open the following template file:"); ffpmsg(filename); return(*status = FILE_NOT_OPENED); } while (fgets(template, 160, diskfile) ) /* get next template line */ { template[160] = '\0'; /* make sure string is terminated */ slen = strlen(template); /* get string length */ template[slen - 1] = '\0'; /* over write the 'newline' char */ if (ffgthd(template, card, &keytype, status) > 0) /* parse template */ break; strncpy(keyname, card, 8); keyname[8] = '\0'; if (keytype == -2) /* rename the card */ { strncpy(newname, &card[40], 8); newname[8] = '\0'; ffmnam(fptr, keyname, newname, status); } else if (keytype == -1) /* delete the card */ { ffdkey(fptr, keyname, status); } else if (keytype == 0) /* update the card */ { ffucrd(fptr, keyname, card, status); } else if (keytype == 1) /* append the card */ { ffprec(fptr, card, status); } else /* END card; stop here */ { break; } } fclose(diskfile); /* close the template file */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpky( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ const char *keyname,/* I - name of keyword to write */ void *value, /* I - keyword value */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes a keyword value with the datatype specified by the 2nd argument. */ { char errmsg[FLEN_ERRMSG]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (datatype == TSTRING) { ffpkys(fptr, keyname, (char *) value, comm, status); } else if (datatype == TBYTE) { ffpkyj(fptr, keyname, (LONGLONG) *(unsigned char *) value, comm, status); } else if (datatype == TSBYTE) { ffpkyj(fptr, keyname, (LONGLONG) *(signed char *) value, comm, status); } else if (datatype == TUSHORT) { ffpkyj(fptr, keyname, (LONGLONG) *(unsigned short *) value, comm, status); } else if (datatype == TSHORT) { ffpkyj(fptr, keyname, (LONGLONG) *(short *) value, comm, status); } else if (datatype == TUINT) { ffpkyg(fptr, keyname, (double) *(unsigned int *) value, 0, comm, status); } else if (datatype == TINT) { ffpkyj(fptr, keyname, (LONGLONG) *(int *) value, comm, status); } else if (datatype == TLOGICAL) { ffpkyl(fptr, keyname, *(int *) value, comm, status); } else if (datatype == TULONG) { ffpkyuj(fptr, keyname, (ULONGLONG) *(unsigned long *) value, comm, status); } else if (datatype == TULONGLONG) { ffpkyuj(fptr, keyname, (ULONGLONG) *(ULONGLONG *) value, comm, status); } else if (datatype == TLONG) { ffpkyj(fptr, keyname, (LONGLONG) *(long *) value, comm, status); } else if (datatype == TLONGLONG) { ffpkyj(fptr, keyname, *(LONGLONG *) value, comm, status); } else if (datatype == TFLOAT) { ffpkye(fptr, keyname, *(float *) value, -7, comm, status); } else if (datatype == TDOUBLE) { ffpkyd(fptr, keyname, *(double *) value, -15, comm, status); } else if (datatype == TCOMPLEX) { ffpkyc(fptr, keyname, (float *) value, -7, comm, status); } else if (datatype == TDBLCOMPLEX) { ffpkym(fptr, keyname, (double *) value, -15, comm, status); } else { snprintf(errmsg, FLEN_ERRMSG,"Bad keyword datatype code: %d (ffpky)", datatype); ffpmsg(errmsg); *status = BAD_DATATYPE; } return(*status); } /*-------------------------------------------------------------------------*/ int ffprec(fitsfile *fptr, /* I - FITS file pointer */ const char *card, /* I - string to be written */ int *status) /* IO - error status */ /* write a keyword record (80 bytes long) to the end of the header */ { char tcard[FLEN_CARD]; size_t len, ii; long nblocks; int keylength; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if ( ((fptr->Fptr)->datastart - (fptr->Fptr)->headend) == 80) /* no room */ { nblocks = 1; if (ffiblk(fptr, nblocks, 0, status) > 0) /* insert 2880-byte block */ return(*status); } strncpy(tcard,card,80); tcard[80] = '\0'; len = strlen(tcard); /* silently replace any illegal characters with a space */ for (ii=0; ii < len; ii++) if (tcard[ii] < ' ' || tcard[ii] > 126) tcard[ii] = ' '; for (ii=len; ii < 80; ii++) /* fill card with spaces if necessary */ tcard[ii] = ' '; keylength = strcspn(tcard, "="); /* support for free-format keywords */ if (keylength == 80) keylength = 8; /* test for the common commentary keywords which by definition have 8-char names */ if ( !fits_strncasecmp( "COMMENT ", tcard, 8) || !fits_strncasecmp( "HISTORY ", tcard, 8) || !fits_strncasecmp( " ", tcard, 8) || !fits_strncasecmp( "CONTINUE", tcard, 8) ) keylength = 8; for (ii=0; ii < keylength; ii++) /* make sure keyword name is uppercase */ tcard[ii] = toupper(tcard[ii]); fftkey(tcard, status); /* test keyword name contains legal chars */ /* no need to do this any more, since any illegal characters have been removed fftrec(tcard, status); */ /* test rest of keyword for legal chars */ ffmbyt(fptr, (fptr->Fptr)->headend, IGNORE_EOF, status); /* move to end */ ffpbyt(fptr, 80, tcard, status); /* write the 80 byte card */ if (*status <= 0) (fptr->Fptr)->headend += 80; /* update end-of-header position */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkyu( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - name of keyword to write */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) a null-valued keyword and comment into the FITS header. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring," "); /* create a dummy value string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword */ ffprec(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpkys( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - name of keyword to write */ const char *value, /* I - keyword value */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. The value string will be truncated at 68 characters which is the maximum length that will fit on a single FITS keyword. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffs2c(value, valstring, status); /* put quotes around the string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword */ ffprec(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpkls( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - name of keyword to write */ const char *value, /* I - keyword value */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. This routine is a modified version of ffpkys which supports the HEASARC long string convention and can write arbitrarily long string keyword values. The value is continued over multiple keywords that have the name COMTINUE without an equal sign in column 9 of the card. This routine also supports simple string keywords which are less than 69 characters in length. */ { char valstring[FLEN_CARD]; char card[FLEN_CARD], tmpkeyname[FLEN_CARD]; char tstring[FLEN_CARD], *cptr; int next, remain, vlen, nquote, nchar, namelen, contin, tstatus = -1; int commlen=0, nocomment = 0; if (*status > 0) /* inherit input status value if > 0 */ return(*status); remain = maxvalue(strlen(value), 1); /* no. of chars to write (at least 1) */ if (comm) { commlen = strlen(comm); if (commlen > 47) commlen = 47; /* only guarantee preserving the first 47 characters */ } /* count the number of single quote characters are in the string */ tstring[0] = '\0'; strncat(tstring, value, 68); /* copy 1st part of string to temp buff */ nquote = 0; cptr = strchr(tstring, '\''); /* search for quote character */ while (cptr) /* search for quote character */ { nquote++; /* increment no. of quote characters */ cptr++; /* increment pointer to next character */ cptr = strchr(cptr, '\''); /* search for another quote char */ } strncpy(tmpkeyname, keyname, 80); tmpkeyname[80] = '\0'; cptr = tmpkeyname; while(*cptr == ' ') /* skip over leading spaces in name */ cptr++; /* determine the number of characters that will fit on the line */ /* Note: each quote character is expanded to 2 quotes */ namelen = strlen(cptr); if (namelen <= 8 && (fftkey(cptr, &tstatus) <= 0) ) { /* This a normal 8-character FITS keyword */ nchar = 68 - nquote; /* max of 68 chars fit in a FITS string value */ } else { nchar = 80 - nquote - namelen - 5; } contin = 0; next = 0; /* pointer to next character to write */ while (remain > 0) { tstring[0] = '\0'; strncat(tstring, &value[next], nchar); /* copy string to temp buff */ ffs2c(tstring, valstring, status); /* expand quotes, and put quotes around the string */ if (remain > nchar) /* if string is continued, put & as last char */ { vlen = strlen(valstring); nchar -= 1; /* outputting one less character now */ if (valstring[vlen-2] != '\'') valstring[vlen-2] = '&'; /* over write last char with & */ else { /* last char was a pair of single quotes, so over write both */ valstring[vlen-3] = '&'; valstring[vlen-1] = '\0'; } } if (contin) /* This is a CONTINUEd keyword */ { if (nocomment) { ffmkky("CONTINUE", valstring, NULL, card, status); /* make keyword w/o comment */ } else { ffmkky("CONTINUE", valstring, comm, card, status); /* make keyword */ } strncpy(&card[8], " ", 2); /* overwrite the '=' */ } else { ffmkky(keyname, valstring, comm, card, status); /* make keyword */ } ffprec(fptr, card, status); /* write the keyword */ contin = 1; remain -= nchar; next += nchar; nocomment = 0; if (remain > 0) { /* count the number of single quote characters in next section */ tstring[0] = '\0'; strncat(tstring, &value[next], 68); /* copy next part of string */ nquote = 0; cptr = strchr(tstring, '\''); /* search for quote character */ while (cptr) /* search for quote character */ { nquote++; /* increment no. of quote characters */ cptr++; /* increment pointer to next character */ cptr = strchr(cptr, '\''); /* search for another quote char */ } nchar = 68 - nquote; /* max number of chars to write this time */ } /* make adjustment if necessary to allow reasonable room for a comment on last CONTINUE card only need to do this if a) there is a comment string, and b) the remaining value string characters could all fit on the next CONTINUE card, and c) there is not enough room on the next CONTINUE card for both the remaining value characters, and at least 47 characters of the comment string. */ if (commlen > 0 && remain + nquote < 69 && remain + nquote + commlen > 65) { if (nchar > 18) { /* only false if there are a rediculous number of quotes in the string */ nchar = remain - 15; /* force continuation onto another card, so that */ /* there is room for a comment up to 47 chara long */ nocomment = 1; /* don't write the comment string this time */ } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffplsw( fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* Write the LONGSTRN keyword and a series of related COMMENT keywords which document that this FITS header may contain long string keyword values which are continued over multiple keywords using the HEASARC long string keyword convention. If the LONGSTRN keyword already exists then this routine simple returns without doing anything. */ { char valstring[FLEN_VALUE], comm[FLEN_COMMENT]; int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = 0; if (ffgkys(fptr, "LONGSTRN", valstring, comm, &tstatus) == 0) return(*status); /* keyword already exists, so just return */ ffpkys(fptr, "LONGSTRN", "OGIP 1.0", "The HEASARC Long String Convention may be used.", status); ffpcom(fptr, " This FITS file may contain long string keyword values that are", status); ffpcom(fptr, " continued over multiple keywords. The HEASARC convention uses the &", status); ffpcom(fptr, " character at the end of each substring which is then continued", status); ffpcom(fptr, " on the next keyword which has the name CONTINUE.", status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpkyl( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - name of keyword to write */ int value, /* I - keyword value */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Values equal to 0 will result in a False FITS keyword; any other non-zero value will result in a True FITS keyword. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffl2c(value, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkyj( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - name of keyword to write */ LONGLONG value, /* I - keyword value */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes an integer keyword value. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffi2c(value, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkyuj( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - name of keyword to write */ ULONGLONG value, /* I - keyword value */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes an integer keyword value. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffu2c(value, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkyf( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - name of keyword to write */ float value, /* I - keyword value */ int decim, /* I - number of decimal places to display */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes a fixed float keyword value. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffr2f(value, decim, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkye( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - name of keyword to write */ float value, /* I - keyword value */ int decim, /* I - number of decimal places to display */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes an exponential float keyword value. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffr2e(value, decim, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkyg( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - name of keyword to write */ double value, /* I - keyword value */ int decim, /* I - number of decimal places to display */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes a fixed double keyword value.*/ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffd2f(value, decim, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkyd( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - name of keyword to write */ double value, /* I - keyword value */ int decim, /* I - number of decimal places to display */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes an exponential double keyword value.*/ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffd2e(value, decim, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkyc( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - name of keyword to write */ float *value, /* I - keyword value (real, imaginary) */ int decim, /* I - number of decimal places to display */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes an complex float keyword value. Format = (realvalue, imagvalue) */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring, "(" ); ffr2e(value[0], decim, tmpstring, status); /* convert to string */ if (strlen(valstring)+strlen(tmpstring)+2 > FLEN_VALUE-1) { ffpmsg("Error converting complex to string (ffpkyc)"); return(*status=BAD_F2C); } strcat(valstring, tmpstring); strcat(valstring, ", "); ffr2e(value[1], decim, tmpstring, status); /* convert to string */ if (strlen(valstring)+strlen(tmpstring)+1 > FLEN_VALUE-1) { ffpmsg("Error converting complex to string (ffpkyc)"); return(*status=BAD_F2C); } strcat(valstring, tmpstring); strcat(valstring, ")"); ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkym( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - name of keyword to write */ double *value, /* I - keyword value (real, imaginary) */ int decim, /* I - number of decimal places to display */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes an complex double keyword value. Format = (realvalue, imagvalue) */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring, "(" ); ffd2e(value[0], decim, tmpstring, status); /* convert to string */ if (strlen(valstring)+strlen(tmpstring)+2 > FLEN_VALUE-1) { ffpmsg("Error converting complex to string (ffpkym)"); return(*status=BAD_F2C); } strcat(valstring, tmpstring); strcat(valstring, ", "); ffd2e(value[1], decim, tmpstring, status); /* convert to string */ if (strlen(valstring)+strlen(tmpstring)+1 > FLEN_VALUE-1) { ffpmsg("Error converting complex to string (ffpkym)"); return(*status=BAD_F2C); } strcat(valstring, tmpstring); strcat(valstring, ")"); ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkfc( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - name of keyword to write */ float *value, /* I - keyword value (real, imaginary) */ int decim, /* I - number of decimal places to display */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes an complex float keyword value. Format = (realvalue, imagvalue) */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring, "(" ); ffr2f(value[0], decim, tmpstring, status); /* convert to string */ if (strlen(valstring)+strlen(tmpstring)+2 > FLEN_VALUE-1) { ffpmsg("Error converting complex to string (ffpkfc)"); return(*status=BAD_F2C); } strcat(valstring, tmpstring); strcat(valstring, ", "); ffr2f(value[1], decim, tmpstring, status); /* convert to string */ if (strlen(valstring)+strlen(tmpstring)+1 > FLEN_VALUE-1) { ffpmsg("Error converting complex to string (ffpkfc)"); return(*status=BAD_F2C); } strcat(valstring, tmpstring); strcat(valstring, ")"); ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkfm( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - name of keyword to write */ double *value, /* I - keyword value (real, imaginary) */ int decim, /* I - number of decimal places to display */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes an complex double keyword value. Format = (realvalue, imagvalue) */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring, "(" ); ffd2f(value[0], decim, tmpstring, status); /* convert to string */ if (strlen(valstring)+strlen(tmpstring)+2 > FLEN_VALUE-1) { ffpmsg("Error converting complex to string (ffpkfm)"); return(*status=BAD_F2C); } strcat(valstring, tmpstring); strcat(valstring, ", "); ffd2f(value[1], decim, tmpstring, status); /* convert to string */ if (strlen(valstring)+strlen(tmpstring)+1 > FLEN_VALUE-1) { ffpmsg("Error converting complex to string (ffpkfm)"); return(*status=BAD_F2C); } strcat(valstring, tmpstring); strcat(valstring, ")"); ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkyt( fitsfile *fptr, /* I - FITS file pointer */ const char *keyname,/* I - name of keyword to write */ long intval, /* I - integer part of value */ double fraction, /* I - fractional part of value */ const char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) a 'triple' precision keyword where the integer and fractional parts of the value are passed in separate parameters to increase the total amount of numerical precision. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; char fstring[20], *cptr; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (fraction > 1. || fraction < 0.) { ffpmsg("fraction must be between 0. and 1. (ffpkyt)"); return(*status = BAD_F2C); } ffi2c(intval, valstring, status); /* convert integer to string */ ffd2f(fraction, 16, fstring, status); /* convert to 16 decimal string */ cptr = strchr(fstring, '.'); /* find the decimal point */ if (strlen(valstring)+strlen(cptr) > FLEN_VALUE-1) { ffpmsg("converted numerical string too long"); return(*status=BAD_F2C); } strcat(valstring, cptr); /* append the fraction to the integer */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*-----------------------------------------------------------------*/ int ffpcom( fitsfile *fptr, /* I - FITS file pointer */ const char *comm, /* I - comment string */ int *status) /* IO - error status */ /* Write 1 or more COMMENT keywords. If the comment string is too long to fit on a single keyword (72 chars) then it will automatically be continued on multiple CONTINUE keywords. */ { char card[FLEN_CARD]; int len, ii; if (*status > 0) /* inherit input status value if > 0 */ return(*status); len = strlen(comm); ii = 0; for (; len > 0; len -= 72) { strcpy(card, "COMMENT "); strncat(card, &comm[ii], 72); ffprec(fptr, card, status); ii += 72; } return(*status); } /*-----------------------------------------------------------------*/ int ffphis( fitsfile *fptr, /* I - FITS file pointer */ const char *history, /* I - history string */ int *status) /* IO - error status */ /* Write 1 or more HISTORY keywords. If the history string is too long to fit on a single keyword (72 chars) then it will automatically be continued on multiple HISTORY keywords. */ { char card[FLEN_CARD]; int len, ii; if (*status > 0) /* inherit input status value if > 0 */ return(*status); len = strlen(history); ii = 0; for (; len > 0; len -= 72) { strcpy(card, "HISTORY "); strncat(card, &history[ii], 72); ffprec(fptr, card, status); ii += 72; } return(*status); } /*-----------------------------------------------------------------*/ int ffpdat( fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* Write the DATE keyword into the FITS header. If the keyword already exists then the date will simply be updated in the existing keyword. */ { int timeref; char date[30], tmzone[10], card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffgstm(date, &timeref, status); if (timeref) /* GMT not available on this machine */ strcpy(tmzone, " Local"); else strcpy(tmzone, " UT"); strcpy(card, "DATE = '"); strcat(card, date); strcat(card, "' / file creation date (YYYY-MM-DDThh:mm:ss"); strcat(card, tmzone); strcat(card, ")"); ffucrd(fptr, "DATE", card, status); return(*status); } /*-------------------------------------------------------------------*/ int ffverifydate(int year, /* I - year (0 - 9999) */ int month, /* I - month (1 - 12) */ int day, /* I - day (1 - 31) */ int *status) /* IO - error status */ /* Verify that the date is valid */ { int ndays[] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; char errmsg[FLEN_ERRMSG]; if (year < 0 || year > 9999) { snprintf(errmsg, FLEN_ERRMSG, "input year value = %d is out of range 0 - 9999", year); ffpmsg(errmsg); return(*status = BAD_DATE); } else if (month < 1 || month > 12) { snprintf(errmsg, FLEN_ERRMSG, "input month value = %d is out of range 1 - 12", month); ffpmsg(errmsg); return(*status = BAD_DATE); } if (ndays[month] == 31) { if (day < 1 || day > 31) { snprintf(errmsg, FLEN_ERRMSG, "input day value = %d is out of range 1 - 31 for month %d", day, month); ffpmsg(errmsg); return(*status = BAD_DATE); } } else if (ndays[month] == 30) { if (day < 1 || day > 30) { snprintf(errmsg, FLEN_ERRMSG, "input day value = %d is out of range 1 - 30 for month %d", day, month); ffpmsg(errmsg); return(*status = BAD_DATE); } } else { if (day < 1 || day > 28) { if (day == 29) { /* year is a leap year if it is divisible by 4 but not by 100, except years divisible by 400 are leap years */ if ((year % 4 == 0 && year % 100 != 0 ) || year % 400 == 0) return (*status); snprintf(errmsg, FLEN_ERRMSG, "input day value = %d is out of range 1 - 28 for February %d (not leap year)", day, year); ffpmsg(errmsg); } else { snprintf(errmsg, FLEN_ERRMSG, "input day value = %d is out of range 1 - 28 (or 29) for February", day); ffpmsg(errmsg); } return(*status = BAD_DATE); } } return(*status); } /*-----------------------------------------------------------------*/ int ffgstm( char *timestr, /* O - returned system date and time string */ int *timeref, /* O - GMT = 0, Local time = 1 */ int *status) /* IO - error status */ /* Returns the current date and time in format 'yyyy-mm-ddThh:mm:ss'. */ { time_t tp; struct tm *ptr; if (*status > 0) /* inherit input status value if > 0 */ return(*status); time(&tp); ptr = gmtime(&tp); /* get GMT (= UTC) time */ if (timeref) { if (ptr) *timeref = 0; /* returning GMT */ else *timeref = 1; /* returning local time */ } if (!ptr) /* GMT not available on this machine */ ptr = localtime(&tp); strftime(timestr, 25, "%Y-%m-%dT%H:%M:%S", ptr); return(*status); } /*-----------------------------------------------------------------*/ int ffdt2s(int year, /* I - year (0 - 9999) */ int month, /* I - month (1 - 12) */ int day, /* I - day (1 - 31) */ char *datestr, /* O - date string: "YYYY-MM-DD" */ int *status) /* IO - error status */ /* Construct a date character string */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); *datestr = '\0'; if (ffverifydate(year, month, day, status) > 0) { ffpmsg("invalid date (ffdt2s)"); return(*status); } if (year >= 1900 && year <= 1998) /* use old 'dd/mm/yy' format */ sprintf(datestr, "%.2d/%.2d/%.2d", day, month, year - 1900); else /* use the new 'YYYY-MM-DD' format */ sprintf(datestr, "%.4d-%.2d-%.2d", year, month, day); return(*status); } /*-----------------------------------------------------------------*/ int ffs2dt(char *datestr, /* I - date string: "YYYY-MM-DD" or "dd/mm/yy" */ int *year, /* O - year (0 - 9999) */ int *month, /* O - month (1 - 12) */ int *day, /* O - day (1 - 31) */ int *status) /* IO - error status */ /* Parse a date character string into year, month, and day values */ { int slen, lyear, lmonth, lday; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (year) *year = 0; if (month) *month = 0; if (day) *day = 0; if (!datestr) { ffpmsg("error: null input date string (ffs2dt)"); return(*status = BAD_DATE); /* Null datestr pointer ??? */ } slen = strlen(datestr); if (slen == 8 && datestr[2] == '/' && datestr[5] == '/') { if (isdigit((int) datestr[0]) && isdigit((int) datestr[1]) && isdigit((int) datestr[3]) && isdigit((int) datestr[4]) && isdigit((int) datestr[6]) && isdigit((int) datestr[7]) ) { /* this is an old format string: "dd/mm/yy" */ lyear = atoi(&datestr[6]) + 1900; lmonth = atoi(&datestr[3]); lday = atoi(datestr); if (year) *year = lyear; if (month) *month = lmonth; if (day) *day = lday; } else { ffpmsg("input date string has illegal format (ffs2dt):"); ffpmsg(datestr); return(*status = BAD_DATE); } } else if (slen >= 10 && datestr[4] == '-' && datestr[7] == '-') { if (isdigit((int) datestr[0]) && isdigit((int) datestr[1]) && isdigit((int) datestr[2]) && isdigit((int) datestr[3]) && isdigit((int) datestr[5]) && isdigit((int) datestr[6]) && isdigit((int) datestr[8]) && isdigit((int) datestr[9]) ) { if (slen > 10 && datestr[10] != 'T') { ffpmsg("input date string has illegal format (ffs2dt):"); ffpmsg(datestr); return(*status = BAD_DATE); } /* this is a new format string: "yyyy-mm-dd" */ lyear = atoi(datestr); lmonth = atoi(&datestr[5]); lday = atoi(&datestr[8]); if (year) *year = lyear; if (month) *month = lmonth; if (day) *day = lday; } else { ffpmsg("input date string has illegal format (ffs2dt):"); ffpmsg(datestr); return(*status = BAD_DATE); } } else { ffpmsg("input date string has illegal format (ffs2dt):"); ffpmsg(datestr); return(*status = BAD_DATE); } if (ffverifydate(lyear, lmonth, lday, status) > 0) { ffpmsg("invalid date (ffs2dt)"); } return(*status); } /*-----------------------------------------------------------------*/ int fftm2s(int year, /* I - year (0 - 9999) */ int month, /* I - month (1 - 12) */ int day, /* I - day (1 - 31) */ int hour, /* I - hour (0 - 23) */ int minute, /* I - minute (0 - 59) */ double second, /* I - second (0. - 60.9999999) */ int decimals, /* I - number of decimal points to write */ char *datestr, /* O - date string: "YYYY-MM-DDThh:mm:ss.ddd" */ /* or "hh:mm:ss.ddd" if year, month day = 0 */ int *status) /* IO - error status */ /* Construct a date and time character string */ { int width; char errmsg[FLEN_ERRMSG]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); *datestr='\0'; if (year != 0 || month != 0 || day !=0) { if (ffverifydate(year, month, day, status) > 0) { ffpmsg("invalid date (fftm2s)"); return(*status); } } if (hour < 0 || hour > 23) { snprintf(errmsg, FLEN_ERRMSG, "input hour value is out of range 0 - 23: %d (fftm2s)", hour); ffpmsg(errmsg); return(*status = BAD_DATE); } else if (minute < 0 || minute > 59) { snprintf(errmsg, FLEN_ERRMSG, "input minute value is out of range 0 - 59: %d (fftm2s)", minute); ffpmsg(errmsg); return(*status = BAD_DATE); } else if (second < 0. || second >= 61) { snprintf(errmsg, FLEN_ERRMSG, "input second value is out of range 0 - 60.999: %f (fftm2s)", second); ffpmsg(errmsg); return(*status = BAD_DATE); } else if (decimals > 25) { snprintf(errmsg, FLEN_ERRMSG, "input decimals value is out of range 0 - 25: %d (fftm2s)", decimals); ffpmsg(errmsg); return(*status = BAD_DATE); } if (decimals == 0) width = 2; else width = decimals + 3; if (decimals < 0) { /* a negative decimals value means return only the date, not time */ sprintf(datestr, "%.4d-%.2d-%.2d", year, month, day); } else if (year == 0 && month == 0 && day == 0) { /* return only the time, not the date */ sprintf(datestr, "%.2d:%.2d:%0*.*f", hour, minute, width, decimals, second); } else { /* return both the time and date */ sprintf(datestr, "%.4d-%.2d-%.2dT%.2d:%.2d:%0*.*f", year, month, day, hour, minute, width, decimals, second); } return(*status); } /*-----------------------------------------------------------------*/ int ffs2tm(char *datestr, /* I - date string: "YYYY-MM-DD" */ /* or "YYYY-MM-DDThh:mm:ss.ddd" */ /* or "dd/mm/yy" */ int *year, /* O - year (0 - 9999) */ int *month, /* O - month (1 - 12) */ int *day, /* O - day (1 - 31) */ int *hour, /* I - hour (0 - 23) */ int *minute, /* I - minute (0 - 59) */ double *second, /* I - second (0. - 60.9999999) */ int *status) /* IO - error status */ /* Parse a date character string into date and time values */ { int slen; char errmsg[FLEN_ERRMSG]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (year) *year = 0; if (month) *month = 0; if (day) *day = 0; if (hour) *hour = 0; if (minute) *minute = 0; if (second) *second = 0.; if (!datestr) { ffpmsg("error: null input date string (ffs2tm)"); return(*status = BAD_DATE); /* Null datestr pointer ??? */ } if (datestr[2] == '/' || datestr[4] == '-') { /* Parse the year, month, and date */ if (ffs2dt(datestr, year, month, day, status) > 0) return(*status); slen = strlen(datestr); if (slen == 8 || slen == 10) return(*status); /* OK, no time fields */ else if (slen < 19) { ffpmsg("input date string has illegal format:"); ffpmsg(datestr); return(*status = BAD_DATE); } else if (datestr[10] == 'T') { if (datestr[13] == ':' && datestr[16] == ':') { if (isdigit((int) datestr[11]) && isdigit((int) datestr[12]) && isdigit((int) datestr[14]) && isdigit((int) datestr[15]) && isdigit((int) datestr[17]) && isdigit((int) datestr[18]) ) { if (slen > 19 && datestr[19] != '.') { ffpmsg("input date string has illegal format:"); ffpmsg(datestr); return(*status = BAD_DATE); } /* this is a new format string: "yyyy-mm-ddThh:mm:ss.dddd" */ if (hour) *hour = atoi(&datestr[11]); if (minute) *minute = atoi(&datestr[14]); if (second) *second = atof(&datestr[17]); } else { ffpmsg("input date string has illegal format:"); ffpmsg(datestr); return(*status = BAD_DATE); } } else { ffpmsg("input date string has illegal format:"); ffpmsg(datestr); return(*status = BAD_DATE); } } } else /* no date fields */ { if (datestr[2] == ':' && datestr[5] == ':') /* time string */ { if (isdigit((int) datestr[0]) && isdigit((int) datestr[1]) && isdigit((int) datestr[3]) && isdigit((int) datestr[4]) && isdigit((int) datestr[6]) && isdigit((int) datestr[7]) ) { /* this is a time string: "hh:mm:ss.dddd" */ if (hour) *hour = atoi(&datestr[0]); if (minute) *minute = atoi(&datestr[3]); if (second) *second = atof(&datestr[6]); } else { ffpmsg("input date string has illegal format:"); ffpmsg(datestr); return(*status = BAD_DATE); } } else { ffpmsg("input date string has illegal format:"); ffpmsg(datestr); return(*status = BAD_DATE); } } if (hour) if (*hour < 0 || *hour > 23) { snprintf(errmsg,FLEN_ERRMSG, "hour value is out of range 0 - 23: %d (ffs2tm)", *hour); ffpmsg(errmsg); return(*status = BAD_DATE); } if (minute) if (*minute < 0 || *minute > 59) { snprintf(errmsg, FLEN_ERRMSG, "minute value is out of range 0 - 59: %d (ffs2tm)", *minute); ffpmsg(errmsg); return(*status = BAD_DATE); } if (second) if (*second < 0 || *second >= 61.) { snprintf(errmsg, FLEN_ERRMSG, "second value is out of range 0 - 60.9999: %f (ffs2tm)", *second); ffpmsg(errmsg); return(*status = BAD_DATE); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsdt( int *day, int *month, int *year, int *status ) { /* This routine is included for backward compatibility with the Fortran FITSIO library. ffgsdt : Get current System DaTe (GMT if available) Return integer values of the day, month, and year Function parameters: day Day of the month month Numerical month (1=Jan, etc.) year Year (1999, 2000, etc.) status output error status */ time_t now; struct tm *date; now = time( NULL ); date = gmtime(&now); /* get GMT (= UTC) time */ if (!date) /* GMT not available on this machine */ { date = localtime(&now); } *day = date->tm_mday; *month = date->tm_mon + 1; *year = date->tm_year + 1900; /* tm_year is defined as years since 1900 */ return( *status ); } /*--------------------------------------------------------------------------*/ int ffpkns( fitsfile *fptr, /* I - FITS file pointer */ const char *keyroot, /* I - root name of keywords to write */ int nstart, /* I - starting index number */ int nkey, /* I - number of keywords to write */ char *value[], /* I - array of pointers to keyword values */ char *comm[], /* I - array of pointers to keyword comment */ int *status) /* IO - error status */ /* Write (put) an indexed array of keywords with index numbers between NSTART and (NSTART + NKEY -1) inclusive. Writes string keywords. The value strings will be truncated at 68 characters, and the HEASARC long string keyword convention is not supported by this routine. */ { char keyname[FLEN_KEYWORD], tcomment[FLEN_COMMENT]; int ii, jj, repeat, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check if first comment string is to be repeated for all the keywords */ /* by looking to see if the last non-blank character is a '&' char */ repeat = 0; if (comm) { len = strlen(comm[0]); while (len > 0 && comm[0][len - 1] == ' ') len--; /* ignore trailing blanks */ if (len > 0 && comm[0][len - 1] == '&') { len = minvalue(len, FLEN_COMMENT); tcomment[0] = '\0'; strncat(tcomment, comm[0], len-1); /* don't copy the final '&' char */ repeat = 1; } } else { repeat = 1; tcomment[0] = '\0'; } for (ii=0, jj=nstart; ii < nkey; ii++, jj++) { ffkeyn(keyroot, jj, keyname, status); if (repeat) ffpkys(fptr, keyname, value[ii], tcomment, status); else ffpkys(fptr, keyname, value[ii], comm[ii], status); if (*status > 0) return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffpknl( fitsfile *fptr, /* I - FITS file pointer */ const char *keyroot, /* I - root name of keywords to write */ int nstart, /* I - starting index number */ int nkey, /* I - number of keywords to write */ int *value, /* I - array of keyword values */ char *comm[], /* I - array of pointers to keyword comment */ int *status) /* IO - error status */ /* Write (put) an indexed array of keywords with index numbers between NSTART and (NSTART + NKEY -1) inclusive. Writes logical keywords Values equal to zero will be written as a False FITS keyword value; any other non-zero value will result in a True FITS keyword. */ { char keyname[FLEN_KEYWORD], tcomment[FLEN_COMMENT]; int ii, jj, repeat, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check if first comment string is to be repeated for all the keywords */ /* by looking to see if the last non-blank character is a '&' char */ repeat = 0; if (comm) { len = strlen(comm[0]); while (len > 0 && comm[0][len - 1] == ' ') len--; /* ignore trailing blanks */ if (len > 0 && comm[0][len - 1] == '&') { len = minvalue(len, FLEN_COMMENT); tcomment[0] = '\0'; strncat(tcomment, comm[0], len-1); /* don't copy the final '&' char */ repeat = 1; } } else { repeat = 1; tcomment[0] = '\0'; } for (ii=0, jj=nstart; ii < nkey; ii++, jj++) { ffkeyn(keyroot, jj, keyname, status); if (repeat) ffpkyl(fptr, keyname, value[ii], tcomment, status); else ffpkyl(fptr, keyname, value[ii], comm[ii], status); if (*status > 0) return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffpknj( fitsfile *fptr, /* I - FITS file pointer */ const char *keyroot, /* I - root name of keywords to write */ int nstart, /* I - starting index number */ int nkey, /* I - number of keywords to write */ long *value, /* I - array of keyword values */ char *comm[], /* I - array of pointers to keyword comment */ int *status) /* IO - error status */ /* Write (put) an indexed array of keywords with index numbers between NSTART and (NSTART + NKEY -1) inclusive. Write integer keywords */ { char keyname[FLEN_KEYWORD], tcomment[FLEN_COMMENT]; int ii, jj, repeat, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check if first comment string is to be repeated for all the keywords */ /* by looking to see if the last non-blank character is a '&' char */ repeat = 0; if (comm) { len = strlen(comm[0]); while (len > 0 && comm[0][len - 1] == ' ') len--; /* ignore trailing blanks */ if (len > 0 && comm[0][len - 1] == '&') { len = minvalue(len, FLEN_COMMENT); tcomment[0] = '\0'; strncat(tcomment, comm[0], len-1); /* don't copy the final '&' char */ repeat = 1; } } else { repeat = 1; tcomment[0] = '\0'; } for (ii=0, jj=nstart; ii < nkey; ii++, jj++) { ffkeyn(keyroot, jj, keyname, status); if (repeat) ffpkyj(fptr, keyname, value[ii], tcomment, status); else ffpkyj(fptr, keyname, value[ii], comm[ii], status); if (*status > 0) return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffpknjj( fitsfile *fptr, /* I - FITS file pointer */ const char *keyroot, /* I - root name of keywords to write */ int nstart, /* I - starting index number */ int nkey, /* I - number of keywords to write */ LONGLONG *value, /* I - array of keyword values */ char *comm[], /* I - array of pointers to keyword comment */ int *status) /* IO - error status */ /* Write (put) an indexed array of keywords with index numbers between NSTART and (NSTART + NKEY -1) inclusive. Write integer keywords */ { char keyname[FLEN_KEYWORD], tcomment[FLEN_COMMENT]; int ii, jj, repeat, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check if first comment string is to be repeated for all the keywords */ /* by looking to see if the last non-blank character is a '&' char */ repeat = 0; if (comm) { len = strlen(comm[0]); while (len > 0 && comm[0][len - 1] == ' ') len--; /* ignore trailing blanks */ if (len > 0 && comm[0][len - 1] == '&') { len = minvalue(len, FLEN_COMMENT); tcomment[0] = '\0'; strncat(tcomment, comm[0], len-1); /* don't copy the final '&' char */ repeat = 1; } } else { repeat = 1; tcomment[0] = '\0'; } for (ii=0, jj=nstart; ii < nkey; ii++, jj++) { ffkeyn(keyroot, jj, keyname, status); if (repeat) ffpkyj(fptr, keyname, value[ii], tcomment, status); else ffpkyj(fptr, keyname, value[ii], comm[ii], status); if (*status > 0) return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffpknf( fitsfile *fptr, /* I - FITS file pointer */ const char *keyroot, /* I - root name of keywords to write */ int nstart, /* I - starting index number */ int nkey, /* I - number of keywords to write */ float *value, /* I - array of keyword values */ int decim, /* I - number of decimals to display */ char *comm[], /* I - array of pointers to keyword comment */ int *status) /* IO - error status */ /* Write (put) an indexed array of keywords with index numbers between NSTART and (NSTART + NKEY -1) inclusive. Writes fixed float values. */ { char keyname[FLEN_KEYWORD], tcomment[FLEN_COMMENT]; int ii, jj, repeat, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check if first comment string is to be repeated for all the keywords */ /* by looking to see if the last non-blank character is a '&' char */ repeat = 0; if (comm) { len = strlen(comm[0]); while (len > 0 && comm[0][len - 1] == ' ') len--; /* ignore trailing blanks */ if (len > 0 && comm[0][len - 1] == '&') { len = minvalue(len, FLEN_COMMENT); tcomment[0] = '\0'; strncat(tcomment, comm[0], len-1); /* don't copy the final '&' char */ repeat = 1; } } else { repeat = 1; tcomment[0] = '\0'; } for (ii=0, jj=nstart; ii < nkey; ii++, jj++) { ffkeyn(keyroot, jj, keyname, status); if (repeat) ffpkyf(fptr, keyname, value[ii], decim, tcomment, status); else ffpkyf(fptr, keyname, value[ii], decim, comm[ii], status); if (*status > 0) return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffpkne( fitsfile *fptr, /* I - FITS file pointer */ const char *keyroot, /* I - root name of keywords to write */ int nstart, /* I - starting index number */ int nkey, /* I - number of keywords to write */ float *value, /* I - array of keyword values */ int decim, /* I - number of decimals to display */ char *comm[], /* I - array of pointers to keyword comment */ int *status) /* IO - error status */ /* Write (put) an indexed array of keywords with index numbers between NSTART and (NSTART + NKEY -1) inclusive. Writes exponential float values. */ { char keyname[FLEN_KEYWORD], tcomment[FLEN_COMMENT]; int ii, jj, repeat, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check if first comment string is to be repeated for all the keywords */ /* by looking to see if the last non-blank character is a '&' char */ repeat = 0; if (comm) { len = strlen(comm[0]); while (len > 0 && comm[0][len - 1] == ' ') len--; /* ignore trailing blanks */ if (len > 0 && comm[0][len - 1] == '&') { len = minvalue(len, FLEN_COMMENT); tcomment[0] = '\0'; strncat(tcomment, comm[0], len-1); /* don't copy the final '&' char */ repeat = 1; } } else { repeat = 1; tcomment[0] = '\0'; } for (ii=0, jj=nstart; ii < nkey; ii++, jj++) { ffkeyn(keyroot, jj, keyname, status); if (repeat) ffpkye(fptr, keyname, value[ii], decim, tcomment, status); else ffpkye(fptr, keyname, value[ii], decim, comm[ii], status); if (*status > 0) return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffpkng( fitsfile *fptr, /* I - FITS file pointer */ const char *keyroot, /* I - root name of keywords to write */ int nstart, /* I - starting index number */ int nkey, /* I - number of keywords to write */ double *value, /* I - array of keyword values */ int decim, /* I - number of decimals to display */ char *comm[], /* I - array of pointers to keyword comment */ int *status) /* IO - error status */ /* Write (put) an indexed array of keywords with index numbers between NSTART and (NSTART + NKEY -1) inclusive. Writes fixed double values. */ { char keyname[FLEN_KEYWORD], tcomment[FLEN_COMMENT]; int ii, jj, repeat, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check if first comment string is to be repeated for all the keywords */ /* by looking to see if the last non-blank character is a '&' char */ repeat = 0; if (comm) { len = strlen(comm[0]); while (len > 0 && comm[0][len - 1] == ' ') len--; /* ignore trailing blanks */ if (len > 0 && comm[0][len - 1] == '&') { len = minvalue(len, FLEN_COMMENT); tcomment[0] = '\0'; strncat(tcomment, comm[0], len-1); /* don't copy the final '&' char */ repeat = 1; } } else { repeat = 1; tcomment[0] = '\0'; } for (ii=0, jj=nstart; ii < nkey; ii++, jj++) { ffkeyn(keyroot, jj, keyname, status); if (repeat) ffpkyg(fptr, keyname, value[ii], decim, tcomment, status); else ffpkyg(fptr, keyname, value[ii], decim, comm[ii], status); if (*status > 0) return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffpknd( fitsfile *fptr, /* I - FITS file pointer */ const char *keyroot, /* I - root name of keywords to write */ int nstart, /* I - starting index number */ int nkey, /* I - number of keywords to write */ double *value, /* I - array of keyword values */ int decim, /* I - number of decimals to display */ char *comm[], /* I - array of pointers to keyword comment */ int *status) /* IO - error status */ /* Write (put) an indexed array of keywords with index numbers between NSTART and (NSTART + NKEY -1) inclusive. Writes exponential double values. */ { char keyname[FLEN_KEYWORD], tcomment[FLEN_COMMENT]; int ii, jj, repeat, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check if first comment string is to be repeated for all the keywords */ /* by looking to see if the last non-blank character is a '&' char */ repeat = 0; if (comm) { len = strlen(comm[0]); while (len > 0 && comm[0][len - 1] == ' ') len--; /* ignore trailing blanks */ if (len > 0 && comm[0][len - 1] == '&') { len = minvalue(len, FLEN_COMMENT); tcomment[0] = '\0'; strncat(tcomment, comm[0], len-1); /* don't copy the final '&' char */ repeat = 1; } } else { repeat = 1; tcomment[0] = '\0'; } for (ii=0, jj=nstart; ii < nkey; ii++, jj++) { ffkeyn(keyroot, jj, keyname, status); if (repeat) ffpkyd(fptr, keyname, value[ii], decim, tcomment, status); else ffpkyd(fptr, keyname, value[ii], decim, comm[ii], status); if (*status > 0) return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffptdm( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ int naxis, /* I - number of axes in the data array */ long naxes[], /* I - length of each data axis */ int *status) /* IO - error status */ /* write the TDIMnnn keyword describing the dimensionality of a column */ { char keyname[FLEN_KEYWORD], tdimstr[FLEN_VALUE], comm[FLEN_COMMENT]; char value[80], message[FLEN_ERRMSG]; int ii; long totalpix = 1, repeat; tcolumn *colptr; if (*status > 0) return(*status); if (colnum < 1 || colnum > 999) { ffpmsg("column number is out of range 1 - 999 (ffptdm)"); return(*status = BAD_COL_NUM); } if (naxis < 1) { ffpmsg("naxis is less than 1 (ffptdm)"); return(*status = BAD_DIMEN); } /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ( (fptr->Fptr)->hdutype != BINARY_TBL) { ffpmsg( "Error: The TDIMn keyword is only allowed in BINTABLE extensions (ffptdm)"); return(*status = NOT_BTABLE); } strcpy(tdimstr, "("); /* start constructing the TDIM value */ for (ii = 0; ii < naxis; ii++) { if (ii > 0) strcat(tdimstr, ","); /* append the comma separator */ if (naxes[ii] < 0) { ffpmsg("one or more TDIM values are less than 0 (ffptdm)"); return(*status = BAD_TDIM); } snprintf(value, 80,"%ld", naxes[ii]); /* This will either be followed by a ',' or ')'. */ if (strlen(tdimstr)+strlen(value)+1 > FLEN_VALUE-1) { ffpmsg("TDIM string too long (ffptdm)"); return(*status = BAD_TDIM); } strcat(tdimstr, value); /* append the axis size */ totalpix *= naxes[ii]; } colptr = (fptr->Fptr)->tableptr; /* point to first column structure */ colptr += (colnum - 1); /* point to the specified column number */ if ((long) colptr->trepeat != totalpix) { /* There is an apparent inconsistency between TDIMn and TFORMn. */ /* The colptr->trepeat value may be out of date, so re-read */ /* the TFORMn keyword to be sure. */ ffkeyn("TFORM", colnum, keyname, status); /* construct TFORMn name */ ffgkys(fptr, keyname, value, NULL, status); /* read TFORMn keyword */ ffbnfm(value, NULL, &repeat, NULL, status); /* parse the repeat count */ if (*status > 0 || repeat != totalpix) { snprintf(message,FLEN_ERRMSG, "column vector length, %ld, does not equal TDIMn array size, %ld", (long) colptr->trepeat, totalpix); ffpmsg(message); return(*status = BAD_TDIM); } } strcat(tdimstr, ")" ); /* append the closing parenthesis */ strcpy(comm, "size of the multidimensional array"); ffkeyn("TDIM", colnum, keyname, status); /* construct TDIMn name */ ffpkys(fptr, keyname, tdimstr, comm, status); /* write the keyword */ return(*status); } /*--------------------------------------------------------------------------*/ int ffptdmll( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ int naxis, /* I - number of axes in the data array */ LONGLONG naxes[], /* I - length of each data axis */ int *status) /* IO - error status */ /* write the TDIMnnn keyword describing the dimensionality of a column */ { char keyname[FLEN_KEYWORD], tdimstr[FLEN_VALUE], comm[FLEN_COMMENT]; char value[80], message[81]; int ii; LONGLONG totalpix = 1, repeat; tcolumn *colptr; if (*status > 0) return(*status); if (colnum < 1 || colnum > 999) { ffpmsg("column number is out of range 1 - 999 (ffptdm)"); return(*status = BAD_COL_NUM); } if (naxis < 1) { ffpmsg("naxis is less than 1 (ffptdm)"); return(*status = BAD_DIMEN); } /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ( (fptr->Fptr)->hdutype != BINARY_TBL) { ffpmsg( "Error: The TDIMn keyword is only allowed in BINTABLE extensions (ffptdm)"); return(*status = NOT_BTABLE); } strcpy(tdimstr, "("); /* start constructing the TDIM value */ for (ii = 0; ii < naxis; ii++) { if (ii > 0) strcat(tdimstr, ","); /* append the comma separator */ if (naxes[ii] < 0) { ffpmsg("one or more TDIM values are less than 0 (ffptdm)"); return(*status = BAD_TDIM); } /* cast to double because the 64-bit int conversion character in */ /* sprintf is platform dependent ( %lld, %ld, %I64d ) */ snprintf(value, 80, "%.0f", (double) naxes[ii]); if (strlen(tdimstr)+strlen(value)+1 > FLEN_VALUE-1) { ffpmsg("TDIM string too long (ffptdmll)"); return(*status = BAD_TDIM); } strcat(tdimstr, value); /* append the axis size */ totalpix *= naxes[ii]; } colptr = (fptr->Fptr)->tableptr; /* point to first column structure */ colptr += (colnum - 1); /* point to the specified column number */ if ( colptr->trepeat != totalpix) { /* There is an apparent inconsistency between TDIMn and TFORMn. */ /* The colptr->trepeat value may be out of date, so re-read */ /* the TFORMn keyword to be sure. */ ffkeyn("TFORM", colnum, keyname, status); /* construct TFORMn name */ ffgkys(fptr, keyname, value, NULL, status); /* read TFORMn keyword */ ffbnfmll(value, NULL, &repeat, NULL, status); /* parse the repeat count */ if (*status > 0 || repeat != totalpix) { snprintf(message,FLEN_ERRMSG, "column vector length, %.0f, does not equal TDIMn array size, %.0f", (double) (colptr->trepeat), (double) totalpix); ffpmsg(message); return(*status = BAD_TDIM); } } strcat(tdimstr, ")" ); /* append the closing parenthesis */ strcpy(comm, "size of the multidimensional array"); ffkeyn("TDIM", colnum, keyname, status); /* construct TDIMn name */ ffpkys(fptr, keyname, tdimstr, comm, status); /* write the keyword */ return(*status); } /*--------------------------------------------------------------------------*/ int ffphps( fitsfile *fptr, /* I - FITS file pointer */ int bitpix, /* I - number of bits per data value pixel */ int naxis, /* I - number of axes in the data array */ long naxes[], /* I - length of each data axis */ int *status) /* IO - error status */ /* write STANDARD set of required primary header keywords */ { int simple = 1; /* does file conform to FITS standard? 1/0 */ long pcount = 0; /* number of group parameters (usually 0) */ long gcount = 1; /* number of random groups (usually 1 or 0) */ int extend = 1; /* may FITS file have extensions? */ ffphpr(fptr, simple, bitpix, naxis, naxes, pcount, gcount, extend, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffphpsll( fitsfile *fptr, /* I - FITS file pointer */ int bitpix, /* I - number of bits per data value pixel */ int naxis, /* I - number of axes in the data array */ LONGLONG naxes[], /* I - length of each data axis */ int *status) /* IO - error status */ /* write STANDARD set of required primary header keywords */ { int simple = 1; /* does file conform to FITS standard? 1/0 */ LONGLONG pcount = 0; /* number of group parameters (usually 0) */ LONGLONG gcount = 1; /* number of random groups (usually 1 or 0) */ int extend = 1; /* may FITS file have extensions? */ ffphprll(fptr, simple, bitpix, naxis, naxes, pcount, gcount, extend, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffphpr( fitsfile *fptr, /* I - FITS file pointer */ int simple, /* I - does file conform to FITS standard? 1/0 */ int bitpix, /* I - number of bits per data value pixel */ int naxis, /* I - number of axes in the data array */ long naxes[], /* I - length of each data axis */ LONGLONG pcount, /* I - number of group parameters (usually 0) */ LONGLONG gcount, /* I - number of random groups (usually 1 or 0) */ int extend, /* I - may FITS file have extensions? */ int *status) /* IO - error status */ /* write required primary header keywords */ { int ii; LONGLONG naxesll[20]; for (ii = 0; (ii < naxis) && (ii < 20); ii++) naxesll[ii] = naxes[ii]; ffphprll(fptr, simple, bitpix, naxis, naxesll, pcount, gcount, extend, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffphprll( fitsfile *fptr, /* I - FITS file pointer */ int simple, /* I - does file conform to FITS standard? 1/0 */ int bitpix, /* I - number of bits per data value pixel */ int naxis, /* I - number of axes in the data array */ LONGLONG naxes[], /* I - length of each data axis */ LONGLONG pcount, /* I - number of group parameters (usually 0) */ LONGLONG gcount, /* I - number of random groups (usually 1 or 0) */ int extend, /* I - may FITS file have extensions? */ int *status) /* IO - error status */ /* write required primary header keywords */ { int ii; long longbitpix, tnaxes[20]; char name[FLEN_KEYWORD], comm[FLEN_COMMENT], message[FLEN_ERRMSG]; char card[FLEN_CARD]; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if ((fptr->Fptr)->headend != (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) return(*status = HEADER_NOT_EMPTY); if (naxis != 0) /* never try to compress a null image */ { if ( (fptr->Fptr)->request_compress_type ) { for (ii = 0; ii < naxis; ii++) tnaxes[ii] = (long) naxes[ii]; /* write header for a compressed image */ imcomp_init_table(fptr, bitpix, naxis, tnaxes, 1, status); return(*status); } } if ((fptr->Fptr)->curhdu == 0) { /* write primary array header */ if (simple) strcpy(comm, "file does conform to FITS standard"); else strcpy(comm, "file does not conform to FITS standard"); ffpkyl(fptr, "SIMPLE", simple, comm, status); } else { /* write IMAGE extension header */ strcpy(comm, "IMAGE extension"); ffpkys(fptr, "XTENSION", "IMAGE", comm, status); } longbitpix = bitpix; /* test for the 3 special cases that represent unsigned integers */ if (longbitpix == USHORT_IMG) longbitpix = SHORT_IMG; else if (longbitpix == ULONG_IMG) longbitpix = LONG_IMG; else if (longbitpix == ULONGLONG_IMG) longbitpix = LONGLONG_IMG; else if (longbitpix == SBYTE_IMG) longbitpix = BYTE_IMG; if (longbitpix != BYTE_IMG && longbitpix != SHORT_IMG && longbitpix != LONG_IMG && longbitpix != LONGLONG_IMG && longbitpix != FLOAT_IMG && longbitpix != DOUBLE_IMG) { snprintf(message,FLEN_ERRMSG, "Illegal value for BITPIX keyword: %d", bitpix); ffpmsg(message); return(*status = BAD_BITPIX); } strcpy(comm, "number of bits per data pixel"); if (ffpkyj(fptr, "BITPIX", longbitpix, comm, status) > 0) return(*status); if (naxis < 0 || naxis > 999) { snprintf(message,FLEN_ERRMSG, "Illegal value for NAXIS keyword: %d", naxis); ffpmsg(message); return(*status = BAD_NAXIS); } strcpy(comm, "number of data axes"); ffpkyj(fptr, "NAXIS", naxis, comm, status); strcpy(comm, "length of data axis "); for (ii = 0; ii < naxis; ii++) { if (naxes[ii] < 0) { snprintf(message,FLEN_ERRMSG, "Illegal negative value for NAXIS%d keyword: %.0f", ii + 1, (double) (naxes[ii])); ffpmsg(message); return(*status = BAD_NAXES); } snprintf(&comm[20], FLEN_COMMENT-20,"%d", ii + 1); ffkeyn("NAXIS", ii + 1, name, status); ffpkyj(fptr, name, naxes[ii], comm, status); } if ((fptr->Fptr)->curhdu == 0) /* the primary array */ { if (extend) { /* only write EXTEND keyword if value = true */ strcpy(comm, "FITS dataset may contain extensions"); ffpkyl(fptr, "EXTEND", extend, comm, status); } if (pcount < 0) { ffpmsg("pcount value is less than 0"); return(*status = BAD_PCOUNT); } else if (gcount < 1) { ffpmsg("gcount value is less than 1"); return(*status = BAD_GCOUNT); } else if (pcount > 0 || gcount > 1) { /* only write these keyword if non-standard values */ strcpy(comm, "random group records are present"); ffpkyl(fptr, "GROUPS", 1, comm, status); strcpy(comm, "number of random group parameters"); ffpkyj(fptr, "PCOUNT", pcount, comm, status); strcpy(comm, "number of random groups"); ffpkyj(fptr, "GCOUNT", gcount, comm, status); } /* write standard block of self-documentating comments */ ffprec(fptr, "COMMENT FITS (Flexible Image Transport System) format is defined in 'Astronomy", status); ffprec(fptr, "COMMENT and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H", status); } else /* an IMAGE extension */ { /* image extension; cannot have random groups */ if (pcount != 0) { ffpmsg("image extensions must have pcount = 0"); *status = BAD_PCOUNT; } else if (gcount != 1) { ffpmsg("image extensions must have gcount = 1"); *status = BAD_GCOUNT; } else { strcpy(comm, "required keyword; must = 0"); ffpkyj(fptr, "PCOUNT", 0, comm, status); strcpy(comm, "required keyword; must = 1"); ffpkyj(fptr, "GCOUNT", 1, comm, status); } } /* Write the BSCALE and BZERO keywords, if an unsigned integer image */ if (bitpix == USHORT_IMG) { strcpy(comm, "offset data range to that of unsigned short"); ffpkyg(fptr, "BZERO", 32768., 0, comm, status); strcpy(comm, "default scaling factor"); ffpkyg(fptr, "BSCALE", 1.0, 0, comm, status); } else if (bitpix == ULONG_IMG) { strcpy(comm, "offset data range to that of unsigned long"); ffpkyg(fptr, "BZERO", 2147483648., 0, comm, status); strcpy(comm, "default scaling factor"); ffpkyg(fptr, "BSCALE", 1.0, 0, comm, status); } else if (bitpix == ULONGLONG_IMG) { strcpy(card,"BZERO = 9223372036854775808 / offset data range to that of unsigned long long"); ffprec(fptr, card, status); strcpy(comm, "default scaling factor"); ffpkyg(fptr, "BSCALE", 1.0, 0, comm, status); } else if (bitpix == SBYTE_IMG) { strcpy(comm, "offset data range to that of signed byte"); ffpkyg(fptr, "BZERO", -128., 0, comm, status); strcpy(comm, "default scaling factor"); ffpkyg(fptr, "BSCALE", 1.0, 0, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffphtb(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG naxis1, /* I - width of row in the table */ LONGLONG naxis2, /* I - number of rows in the table */ int tfields, /* I - number of columns in the table */ char **ttype, /* I - name of each column */ long *tbcol, /* I - byte offset in row to each column */ char **tform, /* I - value of TFORMn keyword for each column */ char **tunit, /* I - value of TUNITn keyword for each column */ const char *extnmx, /* I - value of EXTNAME keyword, if any */ int *status) /* IO - error status */ /* Put required Header keywords into the ASCII TaBle: */ { int ii, ncols, gotmem = 0; long rowlen; /* must be 'long' because it is passed to ffgabc */ char tfmt[30], name[FLEN_KEYWORD], comm[FLEN_COMMENT], extnm[FLEN_VALUE]; if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (*status > 0) return(*status); else if ((fptr->Fptr)->headend != (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) return(*status = HEADER_NOT_EMPTY); else if (naxis1 < 0) return(*status = NEG_WIDTH); else if (naxis2 < 0) return(*status = NEG_ROWS); else if (tfields < 0 || tfields > 999) return(*status = BAD_TFIELDS); extnm[0] = '\0'; if (extnmx) strncat(extnm, extnmx, FLEN_VALUE-1); rowlen = (long) naxis1; if (!tbcol || !tbcol[0] || (!naxis1 && tfields)) /* spacing not defined? */ { /* allocate mem for tbcol; malloc can have problems allocating small */ /* arrays, so allocate at least 20 bytes */ ncols = maxvalue(5, tfields); tbcol = (long *) calloc(ncols, sizeof(long)); if (tbcol) { gotmem = 1; /* calculate width of a row and starting position of each column. */ /* Each column will be separated by 1 blank space */ ffgabc(tfields, tform, 1, &rowlen, tbcol, status); } } ffpkys(fptr, "XTENSION", "TABLE", "ASCII table extension", status); ffpkyj(fptr, "BITPIX", 8, "8-bit ASCII characters", status); ffpkyj(fptr, "NAXIS", 2, "2-dimensional ASCII table", status); ffpkyj(fptr, "NAXIS1", rowlen, "width of table in characters", status); ffpkyj(fptr, "NAXIS2", naxis2, "number of rows in table", status); ffpkyj(fptr, "PCOUNT", 0, "no group parameters (required keyword)", status); ffpkyj(fptr, "GCOUNT", 1, "one data group (required keyword)", status); ffpkyj(fptr, "TFIELDS", tfields, "number of fields in each row", status); for (ii = 0; ii < tfields; ii++) /* loop over every column */ { if ( *(ttype[ii]) ) /* optional TTYPEn keyword */ { snprintf(comm, FLEN_COMMENT,"label for field %3d", ii + 1); ffkeyn("TTYPE", ii + 1, name, status); ffpkys(fptr, name, ttype[ii], comm, status); } if (tbcol[ii] < 1 || tbcol[ii] > rowlen) *status = BAD_TBCOL; snprintf(comm, FLEN_COMMENT,"beginning column of field %3d", ii + 1); ffkeyn("TBCOL", ii + 1, name, status); ffpkyj(fptr, name, tbcol[ii], comm, status); if (strlen(tform[ii]) > 29) { ffpmsg("Error: ASCII table TFORM code is too long (ffphtb)"); *status = BAD_TFORM; break; } strcpy(tfmt, tform[ii]); /* required TFORMn keyword */ ffupch(tfmt); ffkeyn("TFORM", ii + 1, name, status); ffpkys(fptr, name, tfmt, "Fortran-77 format of field", status); if (tunit) { if (tunit[ii] && *(tunit[ii]) ) /* optional TUNITn keyword */ { ffkeyn("TUNIT", ii + 1, name, status); ffpkys(fptr, name, tunit[ii], "physical unit of field", status) ; } } if (*status > 0) break; /* abort loop on error */ } if (extnm[0]) /* optional EXTNAME keyword */ ffpkys(fptr, "EXTNAME", extnm, "name of this ASCII table extension", status); if (*status > 0) ffpmsg("Failed to write ASCII table header keywords (ffphtb)"); if (gotmem) free(tbcol); return(*status); } /*--------------------------------------------------------------------------*/ int ffphbn(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG naxis2, /* I - number of rows in the table */ int tfields, /* I - number of columns in the table */ char **ttype, /* I - name of each column */ char **tform, /* I - value of TFORMn keyword for each column */ char **tunit, /* I - value of TUNITn keyword for each column */ const char *extnmx, /* I - value of EXTNAME keyword, if any */ LONGLONG pcount, /* I - size of the variable length heap area */ int *status) /* IO - error status */ /* Put required Header keywords into the Binary Table: */ { int ii, datatype, iread = 0; long repeat, width; LONGLONG naxis1; char tfmt[30], name[FLEN_KEYWORD], comm[FLEN_COMMENT], extnm[FLEN_VALUE]; char *cptr, card[FLEN_CARD]; tcolumn *colptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if ((fptr->Fptr)->headend != (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) return(*status = HEADER_NOT_EMPTY); else if (naxis2 < 0) return(*status = NEG_ROWS); else if (pcount < 0) return(*status = BAD_PCOUNT); else if (tfields < 0 || tfields > 999) return(*status = BAD_TFIELDS); extnm[0] = '\0'; if (extnmx) strncat(extnm, extnmx, FLEN_VALUE-1); ffpkys(fptr, "XTENSION", "BINTABLE", "binary table extension", status); ffpkyj(fptr, "BITPIX", 8, "8-bit bytes", status); ffpkyj(fptr, "NAXIS", 2, "2-dimensional binary table", status); naxis1 = 0; for (ii = 0; ii < tfields; ii++) /* sum the width of each field */ { ffbnfm(tform[ii], &datatype, &repeat, &width, status); if (datatype == TSTRING) naxis1 += repeat; /* one byte per char */ else if (datatype == TBIT) naxis1 += (repeat + 7) / 8; else if (datatype > 0) naxis1 += repeat * (datatype / 10); else if (tform[ii][0] == 'P' || tform[ii][1] == 'P'|| tform[ii][0] == 'p' || tform[ii][1] == 'p') /* this is a 'P' variable length descriptor (neg. datatype) */ naxis1 += 8; else /* this is a 'Q' variable length descriptor (neg. datatype) */ naxis1 += 16; if (*status > 0) break; /* abort loop on error */ } ffpkyj(fptr, "NAXIS1", naxis1, "width of table in bytes", status); ffpkyj(fptr, "NAXIS2", naxis2, "number of rows in table", status); /* the initial value of PCOUNT (= size of the variable length array heap) should always be zero. If any variable length data is written, then the value of PCOUNT will be updated when the HDU is closed */ ffpkyj(fptr, "PCOUNT", 0, "size of special data area", status); ffpkyj(fptr, "GCOUNT", 1, "one data group (required keyword)", status); ffpkyj(fptr, "TFIELDS", tfields, "number of fields in each row", status); for (ii = 0; ii < tfields; ii++) /* loop over every column */ { if ( *(ttype[ii]) ) /* optional TTYPEn keyword */ { snprintf(comm, FLEN_COMMENT,"label for field %3d", ii + 1); ffkeyn("TTYPE", ii + 1, name, status); ffpkys(fptr, name, ttype[ii], comm, status); } if (strlen(tform[ii]) > 29) { ffpmsg("Error: BIN table TFORM code is too long (ffphbn)"); *status = BAD_TFORM; break; } strcpy(tfmt, tform[ii]); /* required TFORMn keyword */ ffupch(tfmt); ffkeyn("TFORM", ii + 1, name, status); strcpy(comm, "data format of field"); ffbnfm(tfmt, &datatype, &repeat, &width, status); if (datatype == TSTRING) { strcat(comm, ": ASCII Character"); /* Do sanity check to see if an ASCII table format was used, */ /* e.g., 'A8' instead of '8A', or a bad unit width eg '8A9'. */ /* Don't want to return an error status, so write error into */ /* the keyword comment. */ cptr = strchr(tfmt,'A'); cptr++; if (cptr) iread = sscanf(cptr,"%ld", &width); if (iread == 1 && (width > repeat)) { if (repeat == 1) strcpy(comm, "ERROR?? USING ASCII TABLE SYNTAX BY MISTAKE??"); else strcpy(comm, "rAw FORMAT ERROR! UNIT WIDTH w > COLUMN WIDTH r"); } } else if (datatype == TBIT) strcat(comm, ": BIT"); else if (datatype == TBYTE) strcat(comm, ": BYTE"); else if (datatype == TLOGICAL) strcat(comm, ": 1-byte LOGICAL"); else if (datatype == TSHORT) strcat(comm, ": 2-byte INTEGER"); else if (datatype == TUSHORT) strcat(comm, ": 2-byte INTEGER"); else if (datatype == TLONG) strcat(comm, ": 4-byte INTEGER"); else if (datatype == TLONGLONG) strcat(comm, ": 8-byte INTEGER"); else if (datatype == TULONG) strcat(comm, ": 4-byte INTEGER"); else if (datatype == TULONGLONG) strcat(comm, ": 8-byte INTEGER"); else if (datatype == TFLOAT) strcat(comm, ": 4-byte REAL"); else if (datatype == TDOUBLE) strcat(comm, ": 8-byte DOUBLE"); else if (datatype == TCOMPLEX) strcat(comm, ": COMPLEX"); else if (datatype == TDBLCOMPLEX) strcat(comm, ": DOUBLE COMPLEX"); else if (datatype < 0) strcat(comm, ": variable length array"); if (abs(datatype) == TSBYTE) /* signed bytes */ { /* Replace the 'S' with an 'B' in the TFORMn code */ cptr = tfmt; while (*cptr != 'S') cptr++; *cptr = 'B'; ffpkys(fptr, name, tfmt, comm, status); /* write the TZEROn and TSCALn keywords */ ffkeyn("TZERO", ii + 1, name, status); strcpy(comm, "offset for signed bytes"); ffpkyg(fptr, name, -128., 0, comm, status); ffkeyn("TSCAL", ii + 1, name, status); strcpy(comm, "data are not scaled"); ffpkyg(fptr, name, 1., 0, comm, status); } else if (abs(datatype) == TUSHORT) { /* Replace the 'U' with an 'I' in the TFORMn code */ cptr = tfmt; while (*cptr != 'U') cptr++; *cptr = 'I'; ffpkys(fptr, name, tfmt, comm, status); /* write the TZEROn and TSCALn keywords */ ffkeyn("TZERO", ii + 1, name, status); strcpy(comm, "offset for unsigned integers"); ffpkyg(fptr, name, 32768., 0, comm, status); ffkeyn("TSCAL", ii + 1, name, status); strcpy(comm, "data are not scaled"); ffpkyg(fptr, name, 1., 0, comm, status); } else if (abs(datatype) == TULONG) { /* Replace the 'V' with an 'J' in the TFORMn code */ cptr = tfmt; while (*cptr != 'V') cptr++; *cptr = 'J'; ffpkys(fptr, name, tfmt, comm, status); /* write the TZEROn and TSCALn keywords */ ffkeyn("TZERO", ii + 1, name, status); strcpy(comm, "offset for unsigned integers"); ffpkyg(fptr, name, 2147483648., 0, comm, status); ffkeyn("TSCAL", ii + 1, name, status); strcpy(comm, "data are not scaled"); ffpkyg(fptr, name, 1., 0, comm, status); } else if (abs(datatype) == TULONGLONG) { /* Replace the 'W' with an 'K' in the TFORMn code */ cptr = tfmt; while (*cptr != 'W') cptr++; *cptr = 'K'; ffpkys(fptr, name, tfmt, comm, status); /* write the TZEROn and TSCALn keywords */ ffkeyn("TZERO", ii + 1, card, status); strcat(card, " "); /* make sure name is >= 8 chars long */ *(card+8) = '\0'; strcat(card, "= 9223372036854775808 / offset for unsigned integers"); fits_write_record(fptr, card, status); ffkeyn("TSCAL", ii + 1, name, status); strcpy(comm, "data are not scaled"); ffpkyg(fptr, name, 1., 0, comm, status); } else { ffpkys(fptr, name, tfmt, comm, status); } if (tunit) { if (tunit[ii] && *(tunit[ii]) ) /* optional TUNITn keyword */ { ffkeyn("TUNIT", ii + 1, name, status); ffpkys(fptr, name, tunit[ii], "physical unit of field", status); } } if (*status > 0) break; /* abort loop on error */ } if (extnm[0]) /* optional EXTNAME keyword */ ffpkys(fptr, "EXTNAME", extnm, "name of this binary table extension", status); if (*status > 0) ffpmsg("Failed to write binary table header keywords (ffphbn)"); return(*status); } /*--------------------------------------------------------------------------*/ int ffphext(fitsfile *fptr, /* I - FITS file pointer */ const char *xtensionx, /* I - value for the XTENSION keyword */ int bitpix, /* I - value for the BIXPIX keyword */ int naxis, /* I - value for the NAXIS keyword */ long naxes[], /* I - value for the NAXISn keywords */ LONGLONG pcount, /* I - value for the PCOUNT keyword */ LONGLONG gcount, /* I - value for the GCOUNT keyword */ int *status) /* IO - error status */ /* Put required Header keywords into a conforming extension: */ { char message[FLEN_ERRMSG],comm[81], name[20], xtension[FLEN_VALUE]; int ii; if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (*status > 0) return(*status); else if ((fptr->Fptr)->headend != (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) return(*status = HEADER_NOT_EMPTY); if (naxis < 0 || naxis > 999) { snprintf(message,FLEN_ERRMSG, "Illegal value for NAXIS keyword: %d", naxis); ffpmsg(message); return(*status = BAD_NAXIS); } xtension[0] = '\0'; strncat(xtension, xtensionx, FLEN_VALUE-1); ffpkys(fptr, "XTENSION", xtension, "extension type", status); ffpkyj(fptr, "BITPIX", bitpix, "number of bits per data pixel", status); ffpkyj(fptr, "NAXIS", naxis, "number of data axes", status); strcpy(comm, "length of data axis "); for (ii = 0; ii < naxis; ii++) { if (naxes[ii] < 0) { snprintf(message,FLEN_ERRMSG, "Illegal negative value for NAXIS%d keyword: %.0f", ii + 1, (double) (naxes[ii])); ffpmsg(message); return(*status = BAD_NAXES); } snprintf(&comm[20], 61, "%d", ii + 1); ffkeyn("NAXIS", ii + 1, name, status); ffpkyj(fptr, name, naxes[ii], comm, status); } ffpkyj(fptr, "PCOUNT", pcount, " ", status); ffpkyj(fptr, "GCOUNT", gcount, " ", status); if (*status > 0) ffpmsg("Failed to write extension header keywords (ffphext)"); return(*status); } /*--------------------------------------------------------------------------*/ int ffi2c(LONGLONG ival, /* I - value to be converted to a string */ char *cval, /* O - character string representation of the value */ int *status) /* IO - error status */ /* convert value to a null-terminated formatted string. */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); cval[0] = '\0'; #if defined(_MSC_VER) /* Microsoft Visual C++ 6.0 uses '%I64d' syntax for 8-byte integers */ if (sprintf(cval, "%I64d", ival) < 0) #elif (USE_LL_SUFFIX == 1) if (sprintf(cval, "%lld", ival) < 0) #else if (sprintf(cval, "%ld", ival) < 0) #endif { ffpmsg("Error in ffi2c converting integer to string"); *status = BAD_I2C; } return(*status); } /*--------------------------------------------------------------------------*/ int ffu2c(ULONGLONG ival, /* I - value to be converted to a string */ char *cval, /* O - character string representation of the value */ int *status) /* IO - error status */ /* convert value to a null-terminated formatted string. */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); cval[0] = '\0'; #if defined(_MSC_VER) /* Microsoft Visual C++ 6.0 uses '%I64d' syntax for 8-byte integers */ if (sprintf(cval, "%I64u", ival) < 0) #elif (USE_LL_SUFFIX == 1) if (sprintf(cval, "%llu", ival) < 0) #else if (sprintf(cval, "%lu", ival) < 0) #endif { ffpmsg("Error in ffu2c converting integer to string"); *status = BAD_I2C; } return(*status); } /*--------------------------------------------------------------------------*/ int ffl2c(int lval, /* I - value to be converted to a string */ char *cval, /* O - character string representation of the value */ int *status) /* IO - error status ) */ /* convert logical value to a null-terminated formatted string. If the input value == 0, then the output character is the letter F, else the output character is the letter T. The output string is null terminated. */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (lval) strcpy(cval,"T"); else strcpy(cval,"F"); return(*status); } /*--------------------------------------------------------------------------*/ int ffs2c(const char *instr, /* I - null terminated input string */ char *outstr, /* O - null terminated quoted output string */ int *status) /* IO - error status */ /* convert an input string to a quoted string. Leading spaces are significant. FITS string keyword values must be at least 8 chars long so pad out string with spaces if necessary. Example: km/s ==> 'km/s ' Single quote characters in the input string will be replace by two single quote characters. e.g., o'brian ==> 'o''brian' */ { size_t len, ii, jj; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (!instr) /* a null input pointer?? */ { strcpy(outstr, "''"); /* a null FITS string */ return(*status); } outstr[0] = '\''; /* start output string with a quote */ len = strlen(instr); if (len > 68) len = 68; /* limit input string to 68 chars */ for (ii=0, jj=1; ii < len && jj < 69; ii++, jj++) { outstr[jj] = instr[ii]; /* copy each char from input to output */ if (instr[ii] == '\'') { jj++; outstr[jj]='\''; /* duplicate any apostrophies in the input */ } } for (; jj < 9; jj++) /* pad string so it is at least 8 chars long */ outstr[jj] = ' '; if (jj == 70) /* only occurs if the last char of string was a quote */ outstr[69] = '\0'; else { outstr[jj] = '\''; /* append closing quote character */ outstr[jj+1] = '\0'; /* terminate the string */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffr2f(float fval, /* I - value to be converted to a string */ int decim, /* I - number of decimal places to display */ char *cval, /* O - character string representation of the value */ int *status) /* IO - error status */ /* convert float value to a null-terminated F format string */ { char *cptr; if (*status > 0) /* inherit input status value if > 0 */ return(*status); cval[0] = '\0'; if (decim < 0) { ffpmsg("Error in ffr2f: no. of decimal places < 0"); return(*status = BAD_DECIM); } if (snprintf(cval, FLEN_VALUE,"%.*f", decim, fval) < 0) { ffpmsg("Error in ffr2f converting float to string"); *status = BAD_F2C; } /* replace comma with a period (e.g. in French locale) */ if ( (cptr = strchr(cval, ','))) *cptr = '.'; /* test if output string is 'NaN', 'INDEF', or 'INF' */ if (strchr(cval, 'N')) { ffpmsg("Error in ffr2f: float value is a NaN or INDEF"); *status = BAD_F2C; } return(*status); } /*--------------------------------------------------------------------------*/ int ffr2e(float fval, /* I - value to be converted to a string */ int decim, /* I - number of decimal places to display */ char *cval, /* O - character string representation of the value */ int *status) /* IO - error status */ /* convert float value to a null-terminated exponential format string */ { char *cptr; if (*status > 0) /* inherit input status value if > 0 */ return(*status); cval[0] = '\0'; if (decim < 0) { /* use G format if decim is negative */ if ( snprintf(cval, FLEN_VALUE,"%.*G", -decim, fval) < 0) { ffpmsg("Error in ffr2e converting float to string"); *status = BAD_F2C; } else { /* test if E format was used, and there is no displayed decimal */ if ( !strchr(cval, '.') && strchr(cval,'E') ) { /* reformat value with a decimal point and single zero */ if ( snprintf(cval, FLEN_VALUE,"%.1E", fval) < 0) { ffpmsg("Error in ffr2e converting float to string"); *status = BAD_F2C; } return(*status); } } } else { if ( snprintf(cval, FLEN_VALUE,"%.*E", decim, fval) < 0) { ffpmsg("Error in ffr2e converting float to string"); *status = BAD_F2C; } } if (*status <= 0) { /* replace comma with a period (e.g. in French locale) */ if ( (cptr = strchr(cval, ','))) *cptr = '.'; /* test if output string is 'NaN', 'INDEF', or 'INF' */ if (strchr(cval, 'N')) { ffpmsg("Error in ffr2e: float value is a NaN or INDEF"); *status = BAD_F2C; } else if ( !strchr(cval, '.') && !strchr(cval,'E') && strlen(cval) < FLEN_VALUE-1 ) { /* add decimal point if necessary to distinquish from integer */ strcat(cval, "."); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffd2f(double dval, /* I - value to be converted to a string */ int decim, /* I - number of decimal places to display */ char *cval, /* O - character string representation of the value */ int *status) /* IO - error status */ /* convert double value to a null-terminated F format string */ { char *cptr; if (*status > 0) /* inherit input status value if > 0 */ return(*status); cval[0] = '\0'; if (decim < 0) { ffpmsg("Error in ffd2f: no. of decimal places < 0"); return(*status = BAD_DECIM); } if (snprintf(cval, FLEN_VALUE,"%.*f", decim, dval) < 0) { ffpmsg("Error in ffd2f converting double to string"); *status = BAD_F2C; } /* replace comma with a period (e.g. in French locale) */ if ( (cptr = strchr(cval, ','))) *cptr = '.'; /* test if output string is 'NaN', 'INDEF', or 'INF' */ if (strchr(cval, 'N')) { ffpmsg("Error in ffd2f: double value is a NaN or INDEF"); *status = BAD_F2C; } return(*status); } /*--------------------------------------------------------------------------*/ int ffd2e(double dval, /* I - value to be converted to a string */ int decim, /* I - number of decimal places to display */ char *cval, /* O - character string representation of the value */ int *status) /* IO - error status */ /* convert double value to a null-terminated exponential format string. */ { char *cptr; if (*status > 0) /* inherit input status value if > 0 */ return(*status); cval[0] = '\0'; if (decim < 0) { /* use G format if decim is negative */ if ( snprintf(cval, FLEN_VALUE,"%.*G", -decim, dval) < 0) { ffpmsg("Error in ffd2e converting float to string"); *status = BAD_F2C; } else { /* test if E format was used, and there is no displayed decimal */ if ( !strchr(cval, '.') && strchr(cval,'E') ) { /* reformat value with a decimal point and single zero */ if ( snprintf(cval, FLEN_VALUE,"%.1E", dval) < 0) { ffpmsg("Error in ffd2e converting float to string"); *status = BAD_F2C; } return(*status); } } } else { if ( snprintf(cval, FLEN_VALUE,"%.*E", decim, dval) < 0) { ffpmsg("Error in ffd2e converting float to string"); *status = BAD_F2C; } } if (*status <= 0) { /* replace comma with a period (e.g. in French locale) */ if ( (cptr = strchr(cval, ','))) *cptr = '.'; /* test if output string is 'NaN', 'INDEF', or 'INF' */ if (strchr(cval, 'N')) { ffpmsg("Error in ffd2e: double value is a NaN or INDEF"); *status = BAD_F2C; } else if ( !strchr(cval, '.') && !strchr(cval,'E') && strlen(cval) < FLEN_VALUE-1) { /* add decimal point if necessary to distinquish from integer */ strcat(cval, "."); } } return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/quantize.c0000644000175100001710000035031100000000000020132 0ustar00vstsdocker/* The following code is based on algorithms written by Richard White at STScI and made available for use in CFITSIO in July 1999 and updated in January 2008. */ # include # include # include # include # include #include "fitsio2.h" /* nearest integer function */ # define NINT(x) ((x >= 0.) ? (int) (x + 0.5) : (int) (x - 0.5)) #define NULL_VALUE -2147483647 /* value used to represent undefined pixels */ #define ZERO_VALUE -2147483646 /* value used to represent zero-valued pixels */ #define N_RESERVED_VALUES 10 /* number of reserved values, starting with */ /* and including NULL_VALUE. These values */ /* may not be used to represent the quantized */ /* and scaled floating point pixel values */ /* If lossy Hcompression is used, and the */ /* array contains null values, then it is also */ /* possible for the compressed values to slightly */ /* exceed the range of the actual (lossless) values */ /* so we must reserve a little more space */ /* more than this many standard deviations from the mean is an outlier */ # define SIGMA_CLIP 5. # define NITER 3 /* number of sigma-clipping iterations */ static int FnMeanSigma_short(short *array, long npix, int nullcheck, short nullvalue, long *ngoodpix, double *mean, double *sigma, int *status); static int FnMeanSigma_int(int *array, long npix, int nullcheck, int nullvalue, long *ngoodpix, double *mean, double *sigma, int *status); static int FnMeanSigma_float(float *array, long npix, int nullcheck, float nullvalue, long *ngoodpix, double *mean, double *sigma, int *status); static int FnMeanSigma_double(double *array, long npix, int nullcheck, double nullvalue, long *ngoodpix, double *mean, double *sigma, int *status); static int FnNoise5_short(short *array, long nx, long ny, int nullcheck, short nullvalue, long *ngood, short *minval, short *maxval, double *n2, double *n3, double *n5, int *status); static int FnNoise5_int(int *array, long nx, long ny, int nullcheck, int nullvalue, long *ngood, int *minval, int *maxval, double *n2, double *n3, double *n5, int *status); static int FnNoise5_float(float *array, long nx, long ny, int nullcheck, float nullvalue, long *ngood, float *minval, float *maxval, double *n2, double *n3, double *n5, int *status); static int FnNoise5_double(double *array, long nx, long ny, int nullcheck, double nullvalue, long *ngood, double *minval, double *maxval, double *n2, double *n3, double *n5, int *status); static int FnNoise3_short(short *array, long nx, long ny, int nullcheck, short nullvalue, long *ngood, short *minval, short *maxval, double *noise, int *status); static int FnNoise3_int(int *array, long nx, long ny, int nullcheck, int nullvalue, long *ngood, int *minval, int *maxval, double *noise, int *status); static int FnNoise3_float(float *array, long nx, long ny, int nullcheck, float nullvalue, long *ngood, float *minval, float *maxval, double *noise, int *status); static int FnNoise3_double(double *array, long nx, long ny, int nullcheck, double nullvalue, long *ngood, double *minval, double *maxval, double *noise, int *status); static int FnNoise1_short(short *array, long nx, long ny, int nullcheck, short nullvalue, double *noise, int *status); static int FnNoise1_int(int *array, long nx, long ny, int nullcheck, int nullvalue, double *noise, int *status); static int FnNoise1_float(float *array, long nx, long ny, int nullcheck, float nullvalue, double *noise, int *status); static int FnNoise1_double(double *array, long nx, long ny, int nullcheck, double nullvalue, double *noise, int *status); static int FnCompare_short (const void *, const void *); static int FnCompare_int (const void *, const void *); static int FnCompare_float (const void *, const void *); static int FnCompare_double (const void *, const void *); static float quick_select_float(float arr[], int n); static short quick_select_short(short arr[], int n); static int quick_select_int(int arr[], int n); static LONGLONG quick_select_longlong(LONGLONG arr[], int n); static double quick_select_double(double arr[], int n); /*---------------------------------------------------------------------------*/ int fits_quantize_float (long row, float fdata[], long nxpix, long nypix, int nullcheck, float in_null_value, float qlevel, int dither_method, int idata[], double *bscale, double *bzero, int *iminval, int *imaxval) { /* arguments: long row i: if positive, used to calculate random dithering seed value (this is only used when dithering the quantized values) float fdata[] i: array of image pixels to be compressed long nxpix i: number of pixels in each row of fdata long nypix i: number of rows in fdata nullcheck i: check for nullvalues in fdata? float in_null_value i: value used to represent undefined pixels in fdata float qlevel i: quantization level int dither_method i; which dithering method to use int idata[] o: values of fdata after applying bzero and bscale double bscale o: scale factor double bzero o: zero offset int iminval o: minimum quantized value that is returned int imaxval o: maximum quantized value that is returned The function value will be one if the input fdata were copied to idata; in this case the parameters bscale and bzero can be used to convert back to nearly the original floating point values: fdata ~= idata * bscale + bzero. If the function value is zero, the data were not copied to idata. */ int status, iseed = 0; long i, nx, ngood = 0; double stdev, noise2, noise3, noise5; /* MAD 2nd, 3rd, and 5th order noise values */ float minval = 0., maxval = 0.; /* min & max of fdata */ double delta; /* bscale, 1 in idata = delta in fdata */ double zeropt; /* bzero */ double temp; int nextrand = 0; extern float *fits_rand_value; /* this is defined in imcompress.c */ LONGLONG iqfactor; nx = nxpix * nypix; if (nx <= 1) { *bscale = 1.; *bzero = 0.; return (0); } if (qlevel >= 0.) { /* estimate background noise using MAD pixel differences */ FnNoise5_float(fdata, nxpix, nypix, nullcheck, in_null_value, &ngood, &minval, &maxval, &noise2, &noise3, &noise5, &status); if (nullcheck && ngood == 0) { /* special case of an image filled with Nulls */ /* set parameters to dummy values, which are not used */ minval = 0.; maxval = 1.; stdev = 1; } else { /* use the minimum of noise2, noise3, and noise5 as the best noise value */ stdev = noise3; if (noise2 != 0. && noise2 < stdev) stdev = noise2; if (noise5 != 0. && noise5 < stdev) stdev = noise5; } if (qlevel == 0.) delta = stdev / 4.; /* default quantization */ else delta = stdev / qlevel; if (delta == 0.) return (0); /* don't quantize */ } else { /* negative value represents the absolute quantization level */ delta = -qlevel; /* only nned to calculate the min and max values */ FnNoise3_float(fdata, nxpix, nypix, nullcheck, in_null_value, &ngood, &minval, &maxval, 0, &status); } /* check that the range of quantized levels is not > range of int */ if ((maxval - minval) / delta > 2. * 2147483647. - N_RESERVED_VALUES ) return (0); /* don't quantize */ if (row > 0) { /* we need to dither the quantized values */ if (!fits_rand_value) if (fits_init_randoms()) return(MEMORY_ALLOCATION); /* initialize the index to the next random number in the list */ iseed = (int) ((row - 1) % N_RANDOM); nextrand = (int) (fits_rand_value[iseed] * 500.); } if (ngood == nx) { /* don't have to check for nulls */ /* return all positive values, if possible since some */ /* compression algorithms either only work for positive integers, */ /* or are more efficient. */ if (dither_method == SUBTRACTIVE_DITHER_2) { /* shift the range to be close to the value used to represent zeros */ zeropt = minval - delta * (NULL_VALUE + N_RESERVED_VALUES); } else if ((maxval - minval) / delta < 2147483647. - N_RESERVED_VALUES ) { zeropt = minval; /* fudge the zero point so it is an integer multiple of delta */ /* This helps to ensure the same scaling will be performed if the */ /* file undergoes multiple fpack/funpack cycles */ iqfactor = (LONGLONG) (zeropt/delta + 0.5); zeropt = iqfactor * delta; } else { /* center the quantized levels around zero */ zeropt = (minval + maxval) / 2.; } if (row > 0) { /* dither the values when quantizing */ for (i = 0; i < nx; i++) { if (dither_method == SUBTRACTIVE_DITHER_2 && fdata[i] == 0.0) { idata[i] = ZERO_VALUE; } else { idata[i] = NINT((((double) fdata[i] - zeropt) / delta) + fits_rand_value[nextrand] - 0.5); } nextrand++; if (nextrand == N_RANDOM) { iseed++; if (iseed == N_RANDOM) iseed = 0; nextrand = (int) (fits_rand_value[iseed] * 500); } } } else { /* do not dither the values */ for (i = 0; i < nx; i++) { idata[i] = NINT ((fdata[i] - zeropt) / delta); } } } else { /* data contains null values; shift the range to be */ /* close to the value used to represent null values */ zeropt = minval - delta * (NULL_VALUE + N_RESERVED_VALUES); if (row > 0) { /* dither the values */ for (i = 0; i < nx; i++) { if (fdata[i] != in_null_value) { if (dither_method == SUBTRACTIVE_DITHER_2 && fdata[i] == 0.0) { idata[i] = ZERO_VALUE; } else { idata[i] = NINT((((double) fdata[i] - zeropt) / delta) + fits_rand_value[nextrand] - 0.5); } } else { idata[i] = NULL_VALUE; } /* increment the random number index, regardless */ nextrand++; if (nextrand == N_RANDOM) { iseed++; if (iseed == N_RANDOM) iseed = 0; nextrand = (int) (fits_rand_value[iseed] * 500); } } } else { /* do not dither the values */ for (i = 0; i < nx; i++) { if (fdata[i] != in_null_value) { idata[i] = NINT((fdata[i] - zeropt) / delta); } else { idata[i] = NULL_VALUE; } } } } /* calc min and max values */ temp = (minval - zeropt) / delta; *iminval = NINT (temp); temp = (maxval - zeropt) / delta; *imaxval = NINT (temp); *bscale = delta; *bzero = zeropt; return (1); /* yes, data have been quantized */ } /*---------------------------------------------------------------------------*/ int fits_quantize_double (long row, double fdata[], long nxpix, long nypix, int nullcheck, double in_null_value, float qlevel, int dither_method, int idata[], double *bscale, double *bzero, int *iminval, int *imaxval) { /* arguments: long row i: tile number = row number in the binary table (this is only used when dithering the quantized values) double fdata[] i: array of image pixels to be compressed long nxpix i: number of pixels in each row of fdata long nypix i: number of rows in fdata nullcheck i: check for nullvalues in fdata? double in_null_value i: value used to represent undefined pixels in fdata float qlevel i: quantization level int dither_method i; which dithering method to use int idata[] o: values of fdata after applying bzero and bscale double bscale o: scale factor double bzero o: zero offset int iminval o: minimum quantized value that is returned int imaxval o: maximum quantized value that is returned The function value will be one if the input fdata were copied to idata; in this case the parameters bscale and bzero can be used to convert back to nearly the original floating point values: fdata ~= idata * bscale + bzero. If the function value is zero, the data were not copied to idata. */ int status, iseed = 0; long i, nx, ngood = 0; double stdev, noise2 = 0., noise3 = 0., noise5 = 0.; /* MAD 2nd, 3rd, and 5th order noise values */ double minval = 0., maxval = 0.; /* min & max of fdata */ double delta; /* bscale, 1 in idata = delta in fdata */ double zeropt; /* bzero */ double temp; int nextrand = 0; extern float *fits_rand_value; LONGLONG iqfactor; nx = nxpix * nypix; if (nx <= 1) { *bscale = 1.; *bzero = 0.; return (0); } if (qlevel >= 0.) { /* estimate background noise using MAD pixel differences */ FnNoise5_double(fdata, nxpix, nypix, nullcheck, in_null_value, &ngood, &minval, &maxval, &noise2, &noise3, &noise5, &status); if (nullcheck && ngood == 0) { /* special case of an image filled with Nulls */ /* set parameters to dummy values, which are not used */ minval = 0.; maxval = 1.; stdev = 1; } else { /* use the minimum of noise2, noise3, and noise5 as the best noise value */ stdev = noise3; if (noise2 != 0. && noise2 < stdev) stdev = noise2; if (noise5 != 0. && noise5 < stdev) stdev = noise5; } if (qlevel == 0.) delta = stdev / 4.; /* default quantization */ else delta = stdev / qlevel; if (delta == 0.) return (0); /* don't quantize */ } else { /* negative value represents the absolute quantization level */ delta = -qlevel; /* only nned to calculate the min and max values */ FnNoise3_double(fdata, nxpix, nypix, nullcheck, in_null_value, &ngood, &minval, &maxval, 0, &status); } /* check that the range of quantized levels is not > range of int */ if ((maxval - minval) / delta > 2. * 2147483647. - N_RESERVED_VALUES ) return (0); /* don't quantize */ if (row > 0) { /* we need to dither the quantized values */ if (!fits_rand_value) if (fits_init_randoms()) return(MEMORY_ALLOCATION); /* initialize the index to the next random number in the list */ iseed = (int) ((row - 1) % N_RANDOM); nextrand = (int) (fits_rand_value[iseed] * 500); } if (ngood == nx) { /* don't have to check for nulls */ /* return all positive values, if possible since some */ /* compression algorithms either only work for positive integers, */ /* or are more efficient. */ if (dither_method == SUBTRACTIVE_DITHER_2) { /* shift the range to be close to the value used to represent zeros */ zeropt = minval - delta * (NULL_VALUE + N_RESERVED_VALUES); } else if ((maxval - minval) / delta < 2147483647. - N_RESERVED_VALUES ) { zeropt = minval; /* fudge the zero point so it is an integer multiple of delta */ /* This helps to ensure the same scaling will be performed if the */ /* file undergoes multiple fpack/funpack cycles */ iqfactor = (LONGLONG) (zeropt/delta + 0.5); zeropt = iqfactor * delta; } else { /* center the quantized levels around zero */ zeropt = (minval + maxval) / 2.; } if (row > 0) { /* dither the values when quantizing */ for (i = 0; i < nx; i++) { if (dither_method == SUBTRACTIVE_DITHER_2 && fdata[i] == 0.0) { idata[i] = ZERO_VALUE; } else { idata[i] = NINT((((double) fdata[i] - zeropt) / delta) + fits_rand_value[nextrand] - 0.5); } nextrand++; if (nextrand == N_RANDOM) { iseed++; if (iseed == N_RANDOM) iseed = 0; nextrand = (int) (fits_rand_value[iseed] * 500); } } } else { /* do not dither the values */ for (i = 0; i < nx; i++) { idata[i] = NINT ((fdata[i] - zeropt) / delta); } } } else { /* data contains null values; shift the range to be */ /* close to the value used to represent null values */ zeropt = minval - delta * (NULL_VALUE + N_RESERVED_VALUES); if (row > 0) { /* dither the values */ for (i = 0; i < nx; i++) { if (fdata[i] != in_null_value) { if (dither_method == SUBTRACTIVE_DITHER_2 && fdata[i] == 0.0) { idata[i] = ZERO_VALUE; } else { idata[i] = NINT((((double) fdata[i] - zeropt) / delta) + fits_rand_value[nextrand] - 0.5); } } else { idata[i] = NULL_VALUE; } /* increment the random number index, regardless */ nextrand++; if (nextrand == N_RANDOM) { iseed++; if (iseed == N_RANDOM) iseed = 0; nextrand = (int) (fits_rand_value[iseed] * 500); } } } else { /* do not dither the values */ for (i = 0; i < nx; i++) { if (fdata[i] != in_null_value) idata[i] = NINT((fdata[i] - zeropt) / delta); else idata[i] = NULL_VALUE; } } } /* calc min and max values */ temp = (minval - zeropt) / delta; *iminval = NINT (temp); temp = (maxval - zeropt) / delta; *imaxval = NINT (temp); *bscale = delta; *bzero = zeropt; return (1); /* yes, data have been quantized */ } /*--------------------------------------------------------------------------*/ int fits_img_stats_short(short *array, /* 2 dimensional array of image pixels */ long nx, /* number of pixels in each row of the image */ long ny, /* number of rows in the image */ /* (if this is a 3D image, then ny should be the */ /* product of the no. of rows times the no. of planes) */ int nullcheck, /* check for null values, if true */ short nullvalue, /* value of null pixels, if nullcheck is true */ /* returned parameters (if the pointer is not null) */ long *ngoodpix, /* number of non-null pixels in the image */ short *minvalue, /* returned minimum non-null value in the array */ short *maxvalue, /* returned maximum non-null value in the array */ double *mean, /* returned mean value of all non-null pixels */ double *sigma, /* returned R.M.S. value of all non-null pixels */ double *noise1, /* 1st order estimate of noise in image background level */ double *noise2, /* 2nd order estimate of noise in image background level */ double *noise3, /* 3rd order estimate of noise in image background level */ double *noise5, /* 5th order estimate of noise in image background level */ int *status) /* error status */ /* Compute statistics of the input short integer image. */ { long ngood; short minval = 0, maxval = 0; double xmean = 0., xsigma = 0., xnoise = 0., xnoise2 = 0., xnoise3 = 0., xnoise5 = 0.; /* need to calculate mean and/or sigma and/or limits? */ if (mean || sigma ) { FnMeanSigma_short(array, nx * ny, nullcheck, nullvalue, &ngood, &xmean, &xsigma, status); if (ngoodpix) *ngoodpix = ngood; if (mean) *mean = xmean; if (sigma) *sigma = xsigma; } if (noise1) { FnNoise1_short(array, nx, ny, nullcheck, nullvalue, &xnoise, status); *noise1 = xnoise; } if (minvalue || maxvalue || noise3) { FnNoise5_short(array, nx, ny, nullcheck, nullvalue, &ngood, &minval, &maxval, &xnoise2, &xnoise3, &xnoise5, status); if (ngoodpix) *ngoodpix = ngood; if (minvalue) *minvalue= minval; if (maxvalue) *maxvalue = maxval; if (noise2) *noise2 = xnoise2; if (noise3) *noise3 = xnoise3; if (noise5) *noise5 = xnoise5; } return(*status); } /*--------------------------------------------------------------------------*/ int fits_img_stats_int(int *array, /* 2 dimensional array of image pixels */ long nx, /* number of pixels in each row of the image */ long ny, /* number of rows in the image */ /* (if this is a 3D image, then ny should be the */ /* product of the no. of rows times the no. of planes) */ int nullcheck, /* check for null values, if true */ int nullvalue, /* value of null pixels, if nullcheck is true */ /* returned parameters (if the pointer is not null) */ long *ngoodpix, /* number of non-null pixels in the image */ int *minvalue, /* returned minimum non-null value in the array */ int *maxvalue, /* returned maximum non-null value in the array */ double *mean, /* returned mean value of all non-null pixels */ double *sigma, /* returned R.M.S. value of all non-null pixels */ double *noise1, /* 1st order estimate of noise in image background level */ double *noise2, /* 2nd order estimate of noise in image background level */ double *noise3, /* 3rd order estimate of noise in image background level */ double *noise5, /* 5th order estimate of noise in image background level */ int *status) /* error status */ /* Compute statistics of the input integer image. */ { long ngood; int minval = 0, maxval = 0; double xmean = 0., xsigma = 0., xnoise = 0., xnoise2 = 0., xnoise3 = 0., xnoise5 = 0.; /* need to calculate mean and/or sigma and/or limits? */ if (mean || sigma ) { FnMeanSigma_int(array, nx * ny, nullcheck, nullvalue, &ngood, &xmean, &xsigma, status); if (ngoodpix) *ngoodpix = ngood; if (mean) *mean = xmean; if (sigma) *sigma = xsigma; } if (noise1) { FnNoise1_int(array, nx, ny, nullcheck, nullvalue, &xnoise, status); *noise1 = xnoise; } if (minvalue || maxvalue || noise3) { FnNoise5_int(array, nx, ny, nullcheck, nullvalue, &ngood, &minval, &maxval, &xnoise2, &xnoise3, &xnoise5, status); if (ngoodpix) *ngoodpix = ngood; if (minvalue) *minvalue= minval; if (maxvalue) *maxvalue = maxval; if (noise2) *noise2 = xnoise2; if (noise3) *noise3 = xnoise3; if (noise5) *noise5 = xnoise5; } return(*status); } /*--------------------------------------------------------------------------*/ int fits_img_stats_float(float *array, /* 2 dimensional array of image pixels */ long nx, /* number of pixels in each row of the image */ long ny, /* number of rows in the image */ /* (if this is a 3D image, then ny should be the */ /* product of the no. of rows times the no. of planes) */ int nullcheck, /* check for null values, if true */ float nullvalue, /* value of null pixels, if nullcheck is true */ /* returned parameters (if the pointer is not null) */ long *ngoodpix, /* number of non-null pixels in the image */ float *minvalue, /* returned minimum non-null value in the array */ float *maxvalue, /* returned maximum non-null value in the array */ double *mean, /* returned mean value of all non-null pixels */ double *sigma, /* returned R.M.S. value of all non-null pixels */ double *noise1, /* 1st order estimate of noise in image background level */ double *noise2, /* 2nd order estimate of noise in image background level */ double *noise3, /* 3rd order estimate of noise in image background level */ double *noise5, /* 5th order estimate of noise in image background level */ int *status) /* error status */ /* Compute statistics of the input float image. */ { long ngood; float minval, maxval; double xmean = 0., xsigma = 0., xnoise = 0., xnoise2 = 0., xnoise3 = 0., xnoise5 = 0.; /* need to calculate mean and/or sigma and/or limits? */ if (mean || sigma ) { FnMeanSigma_float(array, nx * ny, nullcheck, nullvalue, &ngood, &xmean, &xsigma, status); if (ngoodpix) *ngoodpix = ngood; if (mean) *mean = xmean; if (sigma) *sigma = xsigma; } if (noise1) { FnNoise1_float(array, nx, ny, nullcheck, nullvalue, &xnoise, status); *noise1 = xnoise; } if (minvalue || maxvalue || noise3) { FnNoise5_float(array, nx, ny, nullcheck, nullvalue, &ngood, &minval, &maxval, &xnoise2, &xnoise3, &xnoise5, status); if (ngoodpix) *ngoodpix = ngood; if (minvalue) *minvalue= minval; if (maxvalue) *maxvalue = maxval; if (noise2) *noise2 = xnoise2; if (noise3) *noise3 = xnoise3; if (noise5) *noise5 = xnoise5; } return(*status); } /*--------------------------------------------------------------------------*/ static int FnMeanSigma_short (short *array, /* 2 dimensional array of image pixels */ long npix, /* number of pixels in the image */ int nullcheck, /* check for null values, if true */ short nullvalue, /* value of null pixels, if nullcheck is true */ /* returned parameters */ long *ngoodpix, /* number of non-null pixels in the image */ double *mean, /* returned mean value of all non-null pixels */ double *sigma, /* returned R.M.S. value of all non-null pixels */ int *status) /* error status */ /* Compute mean and RMS sigma of the non-null pixels in the input array. */ { long ii, ngood = 0; short *value; double sum = 0., sum2 = 0., xtemp; value = array; if (nullcheck) { for (ii = 0; ii < npix; ii++, value++) { if (*value != nullvalue) { ngood++; xtemp = (double) *value; sum += xtemp; sum2 += (xtemp * xtemp); } } } else { ngood = npix; for (ii = 0; ii < npix; ii++, value++) { xtemp = (double) *value; sum += xtemp; sum2 += (xtemp * xtemp); } } if (ngood > 1) { if (ngoodpix) *ngoodpix = ngood; xtemp = sum / ngood; if (mean) *mean = xtemp; if (sigma) *sigma = sqrt((sum2 / ngood) - (xtemp * xtemp)); } else if (ngood == 1){ if (ngoodpix) *ngoodpix = 1; if (mean) *mean = sum; if (sigma) *sigma = 0.0; } else { if (ngoodpix) *ngoodpix = 0; if (mean) *mean = 0.; if (sigma) *sigma = 0.; } return(*status); } /*--------------------------------------------------------------------------*/ static int FnMeanSigma_int (int *array, /* 2 dimensional array of image pixels */ long npix, /* number of pixels in the image */ int nullcheck, /* check for null values, if true */ int nullvalue, /* value of null pixels, if nullcheck is true */ /* returned parameters */ long *ngoodpix, /* number of non-null pixels in the image */ double *mean, /* returned mean value of all non-null pixels */ double *sigma, /* returned R.M.S. value of all non-null pixels */ int *status) /* error status */ /* Compute mean and RMS sigma of the non-null pixels in the input array. */ { long ii, ngood = 0; int *value; double sum = 0., sum2 = 0., xtemp; value = array; if (nullcheck) { for (ii = 0; ii < npix; ii++, value++) { if (*value != nullvalue) { ngood++; xtemp = (double) *value; sum += xtemp; sum2 += (xtemp * xtemp); } } } else { ngood = npix; for (ii = 0; ii < npix; ii++, value++) { xtemp = (double) *value; sum += xtemp; sum2 += (xtemp * xtemp); } } if (ngood > 1) { if (ngoodpix) *ngoodpix = ngood; xtemp = sum / ngood; if (mean) *mean = xtemp; if (sigma) *sigma = sqrt((sum2 / ngood) - (xtemp * xtemp)); } else if (ngood == 1){ if (ngoodpix) *ngoodpix = 1; if (mean) *mean = sum; if (sigma) *sigma = 0.0; } else { if (ngoodpix) *ngoodpix = 0; if (mean) *mean = 0.; if (sigma) *sigma = 0.; } return(*status); } /*--------------------------------------------------------------------------*/ static int FnMeanSigma_float (float *array, /* 2 dimensional array of image pixels */ long npix, /* number of pixels in the image */ int nullcheck, /* check for null values, if true */ float nullvalue, /* value of null pixels, if nullcheck is true */ /* returned parameters */ long *ngoodpix, /* number of non-null pixels in the image */ double *mean, /* returned mean value of all non-null pixels */ double *sigma, /* returned R.M.S. value of all non-null pixels */ int *status) /* error status */ /* Compute mean and RMS sigma of the non-null pixels in the input array. */ { long ii, ngood = 0; float *value; double sum = 0., sum2 = 0., xtemp; value = array; if (nullcheck) { for (ii = 0; ii < npix; ii++, value++) { if (*value != nullvalue) { ngood++; xtemp = (double) *value; sum += xtemp; sum2 += (xtemp * xtemp); } } } else { ngood = npix; for (ii = 0; ii < npix; ii++, value++) { xtemp = (double) *value; sum += xtemp; sum2 += (xtemp * xtemp); } } if (ngood > 1) { if (ngoodpix) *ngoodpix = ngood; xtemp = sum / ngood; if (mean) *mean = xtemp; if (sigma) *sigma = sqrt((sum2 / ngood) - (xtemp * xtemp)); } else if (ngood == 1){ if (ngoodpix) *ngoodpix = 1; if (mean) *mean = sum; if (sigma) *sigma = 0.0; } else { if (ngoodpix) *ngoodpix = 0; if (mean) *mean = 0.; if (sigma) *sigma = 0.; } return(*status); } /*--------------------------------------------------------------------------*/ static int FnMeanSigma_double (double *array, /* 2 dimensional array of image pixels */ long npix, /* number of pixels in the image */ int nullcheck, /* check for null values, if true */ double nullvalue, /* value of null pixels, if nullcheck is true */ /* returned parameters */ long *ngoodpix, /* number of non-null pixels in the image */ double *mean, /* returned mean value of all non-null pixels */ double *sigma, /* returned R.M.S. value of all non-null pixels */ int *status) /* error status */ /* Compute mean and RMS sigma of the non-null pixels in the input array. */ { long ii, ngood = 0; double *value; double sum = 0., sum2 = 0., xtemp; value = array; if (nullcheck) { for (ii = 0; ii < npix; ii++, value++) { if (*value != nullvalue) { ngood++; xtemp = *value; sum += xtemp; sum2 += (xtemp * xtemp); } } } else { ngood = npix; for (ii = 0; ii < npix; ii++, value++) { xtemp = *value; sum += xtemp; sum2 += (xtemp * xtemp); } } if (ngood > 1) { if (ngoodpix) *ngoodpix = ngood; xtemp = sum / ngood; if (mean) *mean = xtemp; if (sigma) *sigma = sqrt((sum2 / ngood) - (xtemp * xtemp)); } else if (ngood == 1){ if (ngoodpix) *ngoodpix = 1; if (mean) *mean = sum; if (sigma) *sigma = 0.0; } else { if (ngoodpix) *ngoodpix = 0; if (mean) *mean = 0.; if (sigma) *sigma = 0.; } return(*status); } /*--------------------------------------------------------------------------*/ static int FnNoise5_short (short *array, /* 2 dimensional array of image pixels */ long nx, /* number of pixels in each row of the image */ long ny, /* number of rows in the image */ int nullcheck, /* check for null values, if true */ short nullvalue, /* value of null pixels, if nullcheck is true */ /* returned parameters */ long *ngood, /* number of good, non-null pixels? */ short *minval, /* minimum non-null value */ short *maxval, /* maximum non-null value */ double *noise2, /* returned 2nd order MAD of all non-null pixels */ double *noise3, /* returned 3rd order MAD of all non-null pixels */ double *noise5, /* returned 5th order MAD of all non-null pixels */ int *status) /* error status */ /* Estimate the median and background noise in the input image using 2nd, 3rd and 5th order Median Absolute Differences. The noise in the background of the image is calculated using the MAD algorithms developed for deriving the signal to noise ratio in spectra (see issue #42 of the ST-ECF newsletter, http://www.stecf.org/documents/newsletter/) 3rd order: noise = 1.482602 / sqrt(6) * median (abs(2*flux(i) - flux(i-2) - flux(i+2))) The returned estimates are the median of the values that are computed for each row of the image. */ { long ii, jj, nrows = 0, nrows2 = 0, nvals, nvals2, ngoodpix = 0; int *differences2, *differences3, *differences5; short *rowpix, v1, v2, v3, v4, v5, v6, v7, v8, v9; short xminval = SHRT_MAX, xmaxval = SHRT_MIN; int do_range = 0; double *diffs2, *diffs3, *diffs5; double xnoise2 = 0, xnoise3 = 0, xnoise5 = 0; if (nx < 9) { /* treat entire array as an image with a single row */ nx = nx * ny; ny = 1; } /* rows must have at least 9 pixels */ if (nx < 9) { for (ii = 0; ii < nx; ii++) { if (nullcheck && array[ii] == nullvalue) continue; else { if (array[ii] < xminval) xminval = array[ii]; if (array[ii] > xmaxval) xmaxval = array[ii]; ngoodpix++; } } if (minval) *minval = xminval; if (maxval) *maxval = xmaxval; if (ngood) *ngood = ngoodpix; if (noise2) *noise2 = 0.; if (noise3) *noise3 = 0.; if (noise5) *noise5 = 0.; return(*status); } /* do we need to compute the min and max value? */ if (minval || maxval) do_range = 1; /* allocate arrays used to compute the median and noise estimates */ differences2 = calloc(nx, sizeof(int)); if (!differences2) { *status = MEMORY_ALLOCATION; return(*status); } differences3 = calloc(nx, sizeof(int)); if (!differences3) { free(differences2); *status = MEMORY_ALLOCATION; return(*status); } differences5 = calloc(nx, sizeof(int)); if (!differences5) { free(differences2); free(differences3); *status = MEMORY_ALLOCATION; return(*status); } diffs2 = calloc(ny, sizeof(double)); if (!diffs2) { free(differences2); free(differences3); free(differences5); *status = MEMORY_ALLOCATION; return(*status); } diffs3 = calloc(ny, sizeof(double)); if (!diffs3) { free(differences2); free(differences3); free(differences5); free(diffs2); *status = MEMORY_ALLOCATION; return(*status); } diffs5 = calloc(ny, sizeof(double)); if (!diffs5) { free(differences2); free(differences3); free(differences5); free(diffs2); free(diffs3); *status = MEMORY_ALLOCATION; return(*status); } /* loop over each row of the image */ for (jj=0; jj < ny; jj++) { rowpix = array + (jj * nx); /* point to first pixel in the row */ /***** find the first valid pixel in row */ ii = 0; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v1 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v1 < xminval) xminval = v1; if (v1 > xmaxval) xmaxval = v1; } /***** find the 2nd valid pixel in row (which we will skip over) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v2 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v2 < xminval) xminval = v2; if (v2 > xmaxval) xmaxval = v2; } /***** find the 3rd valid pixel in row */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v3 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v3 < xminval) xminval = v3; if (v3 > xmaxval) xmaxval = v3; } /* find the 4nd valid pixel in row (to be skipped) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v4 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v4 < xminval) xminval = v4; if (v4 > xmaxval) xmaxval = v4; } /* find the 5th valid pixel in row (to be skipped) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v5 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v5 < xminval) xminval = v5; if (v5 > xmaxval) xmaxval = v5; } /* find the 6th valid pixel in row (to be skipped) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v6 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v6 < xminval) xminval = v6; if (v6 > xmaxval) xmaxval = v6; } /* find the 7th valid pixel in row (to be skipped) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v7 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v7 < xminval) xminval = v7; if (v7 > xmaxval) xmaxval = v7; } /* find the 8th valid pixel in row (to be skipped) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v8 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v8 < xminval) xminval = v8; if (v8 > xmaxval) xmaxval = v8; } /* now populate the differences arrays */ /* for the remaining pixels in the row */ nvals = 0; nvals2 = 0; for (ii++; ii < nx; ii++) { /* find the next valid pixel in row */ if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) break; /* hit end of row */ v9 = rowpix[ii]; /* store the good pixel value */ if (do_range) { if (v9 < xminval) xminval = v9; if (v9 > xmaxval) xmaxval = v9; } /* construct array of absolute differences */ if (!(v5 == v6 && v6 == v7) ) { differences2[nvals2] = abs((int) v5 - (int) v7); nvals2++; } if (!(v3 == v4 && v4 == v5 && v5 == v6 && v6 == v7) ) { differences3[nvals] = abs((2 * (int) v5) - (int) v3 - (int) v7); differences5[nvals] = abs((6 * (int) v5) - (4 * (int) v3) - (4 * (int) v7) + (int) v1 + (int) v9); nvals++; } else { /* ignore constant background regions */ ngoodpix++; } /* shift over 1 pixel */ v1 = v2; v2 = v3; v3 = v4; v4 = v5; v5 = v6; v6 = v7; v7 = v8; v8 = v9; } /* end of loop over pixels in the row */ /* compute the median diffs */ /* Note that there are 8 more pixel values than there are diffs values. */ ngoodpix += nvals; if (nvals == 0) { continue; /* cannot compute medians on this row */ } else if (nvals == 1) { if (nvals2 == 1) { diffs2[nrows2] = differences2[0]; nrows2++; } diffs3[nrows] = differences3[0]; diffs5[nrows] = differences5[0]; } else { /* quick_select returns the median MUCH faster than using qsort */ if (nvals2 > 1) { diffs2[nrows2] = quick_select_int(differences2, nvals); nrows2++; } diffs3[nrows] = quick_select_int(differences3, nvals); diffs5[nrows] = quick_select_int(differences5, nvals); } nrows++; } /* end of loop over rows */ /* compute median of the values for each row */ if (nrows == 0) { xnoise3 = 0; xnoise5 = 0; } else if (nrows == 1) { xnoise3 = diffs3[0]; xnoise5 = diffs5[0]; } else { qsort(diffs3, nrows, sizeof(double), FnCompare_double); qsort(diffs5, nrows, sizeof(double), FnCompare_double); xnoise3 = (diffs3[(nrows - 1)/2] + diffs3[nrows/2]) / 2.; xnoise5 = (diffs5[(nrows - 1)/2] + diffs5[nrows/2]) / 2.; } if (nrows2 == 0) { xnoise2 = 0; } else if (nrows2 == 1) { xnoise2 = diffs2[0]; } else { qsort(diffs2, nrows2, sizeof(double), FnCompare_double); xnoise2 = (diffs2[(nrows2 - 1)/2] + diffs2[nrows2/2]) / 2.; } if (ngood) *ngood = ngoodpix; if (minval) *minval = xminval; if (maxval) *maxval = xmaxval; if (noise2) *noise2 = 1.0483579 * xnoise2; if (noise3) *noise3 = 0.6052697 * xnoise3; if (noise5) *noise5 = 0.1772048 * xnoise5; free(diffs5); free(diffs3); free(diffs2); free(differences5); free(differences3); free(differences2); return(*status); } /*--------------------------------------------------------------------------*/ static int FnNoise5_int (int *array, /* 2 dimensional array of image pixels */ long nx, /* number of pixels in each row of the image */ long ny, /* number of rows in the image */ int nullcheck, /* check for null values, if true */ int nullvalue, /* value of null pixels, if nullcheck is true */ /* returned parameters */ long *ngood, /* number of good, non-null pixels? */ int *minval, /* minimum non-null value */ int *maxval, /* maximum non-null value */ double *noise2, /* returned 2nd order MAD of all non-null pixels */ double *noise3, /* returned 3rd order MAD of all non-null pixels */ double *noise5, /* returned 5th order MAD of all non-null pixels */ int *status) /* error status */ /* Estimate the median and background noise in the input image using 2nd, 3rd and 5th order Median Absolute Differences. The noise in the background of the image is calculated using the MAD algorithms developed for deriving the signal to noise ratio in spectra (see issue #42 of the ST-ECF newsletter, http://www.stecf.org/documents/newsletter/) 3rd order: noise = 1.482602 / sqrt(6) * median (abs(2*flux(i) - flux(i-2) - flux(i+2))) The returned estimates are the median of the values that are computed for each row of the image. */ { long ii, jj, nrows = 0, nrows2 = 0, nvals, nvals2, ngoodpix = 0; LONGLONG *differences2, *differences3, *differences5, tdiff; int *rowpix, v1, v2, v3, v4, v5, v6, v7, v8, v9; int xminval = INT_MAX, xmaxval = INT_MIN; int do_range = 0; double *diffs2, *diffs3, *diffs5; double xnoise2 = 0, xnoise3 = 0, xnoise5 = 0; if (nx < 9) { /* treat entire array as an image with a single row */ nx = nx * ny; ny = 1; } /* rows must have at least 9 pixels */ if (nx < 9) { for (ii = 0; ii < nx; ii++) { if (nullcheck && array[ii] == nullvalue) continue; else { if (array[ii] < xminval) xminval = array[ii]; if (array[ii] > xmaxval) xmaxval = array[ii]; ngoodpix++; } } if (minval) *minval = xminval; if (maxval) *maxval = xmaxval; if (ngood) *ngood = ngoodpix; if (noise2) *noise2 = 0.; if (noise3) *noise3 = 0.; if (noise5) *noise5 = 0.; return(*status); } /* do we need to compute the min and max value? */ if (minval || maxval) do_range = 1; /* allocate arrays used to compute the median and noise estimates */ differences2 = calloc(nx, sizeof(LONGLONG)); if (!differences2) { *status = MEMORY_ALLOCATION; return(*status); } differences3 = calloc(nx, sizeof(LONGLONG)); if (!differences3) { free(differences2); *status = MEMORY_ALLOCATION; return(*status); } differences5 = calloc(nx, sizeof(LONGLONG)); if (!differences5) { free(differences2); free(differences3); *status = MEMORY_ALLOCATION; return(*status); } diffs2 = calloc(ny, sizeof(double)); if (!diffs2) { free(differences2); free(differences3); free(differences5); *status = MEMORY_ALLOCATION; return(*status); } diffs3 = calloc(ny, sizeof(double)); if (!diffs3) { free(differences2); free(differences3); free(differences5); free(diffs2); *status = MEMORY_ALLOCATION; return(*status); } diffs5 = calloc(ny, sizeof(double)); if (!diffs5) { free(differences2); free(differences3); free(differences5); free(diffs2); free(diffs3); *status = MEMORY_ALLOCATION; return(*status); } /* loop over each row of the image */ for (jj=0; jj < ny; jj++) { rowpix = array + (jj * nx); /* point to first pixel in the row */ /***** find the first valid pixel in row */ ii = 0; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v1 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v1 < xminval) xminval = v1; if (v1 > xmaxval) xmaxval = v1; } /***** find the 2nd valid pixel in row (which we will skip over) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v2 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v2 < xminval) xminval = v2; if (v2 > xmaxval) xmaxval = v2; } /***** find the 3rd valid pixel in row */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v3 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v3 < xminval) xminval = v3; if (v3 > xmaxval) xmaxval = v3; } /* find the 4nd valid pixel in row (to be skipped) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v4 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v4 < xminval) xminval = v4; if (v4 > xmaxval) xmaxval = v4; } /* find the 5th valid pixel in row (to be skipped) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v5 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v5 < xminval) xminval = v5; if (v5 > xmaxval) xmaxval = v5; } /* find the 6th valid pixel in row (to be skipped) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v6 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v6 < xminval) xminval = v6; if (v6 > xmaxval) xmaxval = v6; } /* find the 7th valid pixel in row (to be skipped) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v7 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v7 < xminval) xminval = v7; if (v7 > xmaxval) xmaxval = v7; } /* find the 8th valid pixel in row (to be skipped) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v8 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v8 < xminval) xminval = v8; if (v8 > xmaxval) xmaxval = v8; } /* now populate the differences arrays */ /* for the remaining pixels in the row */ nvals = 0; nvals2 = 0; for (ii++; ii < nx; ii++) { /* find the next valid pixel in row */ if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) break; /* hit end of row */ v9 = rowpix[ii]; /* store the good pixel value */ if (do_range) { if (v9 < xminval) xminval = v9; if (v9 > xmaxval) xmaxval = v9; } /* construct array of absolute differences */ if (!(v5 == v6 && v6 == v7) ) { tdiff = (LONGLONG) v5 - (LONGLONG) v7; if (tdiff < 0) differences2[nvals2] = -1 * tdiff; else differences2[nvals2] = tdiff; nvals2++; } if (!(v3 == v4 && v4 == v5 && v5 == v6 && v6 == v7) ) { tdiff = (2 * (LONGLONG) v5) - (LONGLONG) v3 - (LONGLONG) v7; if (tdiff < 0) differences3[nvals] = -1 * tdiff; else differences3[nvals] = tdiff; tdiff = (6 * (LONGLONG) v5) - (4 * (LONGLONG) v3) - (4 * (LONGLONG) v7) + (LONGLONG) v1 + (LONGLONG) v9; if (tdiff < 0) differences5[nvals] = -1 * tdiff; else differences5[nvals] = tdiff; nvals++; } else { /* ignore constant background regions */ ngoodpix++; } /* shift over 1 pixel */ v1 = v2; v2 = v3; v3 = v4; v4 = v5; v5 = v6; v6 = v7; v7 = v8; v8 = v9; } /* end of loop over pixels in the row */ /* compute the median diffs */ /* Note that there are 8 more pixel values than there are diffs values. */ ngoodpix += nvals; if (nvals == 0) { continue; /* cannot compute medians on this row */ } else if (nvals == 1) { if (nvals2 == 1) { diffs2[nrows2] = (double) differences2[0]; nrows2++; } diffs3[nrows] = (double) differences3[0]; diffs5[nrows] = (double) differences5[0]; } else { /* quick_select returns the median MUCH faster than using qsort */ if (nvals2 > 1) { diffs2[nrows2] = (double) quick_select_longlong(differences2, nvals); nrows2++; } diffs3[nrows] = (double) quick_select_longlong(differences3, nvals); diffs5[nrows] = (double) quick_select_longlong(differences5, nvals); } nrows++; } /* end of loop over rows */ /* compute median of the values for each row */ if (nrows == 0) { xnoise3 = 0; xnoise5 = 0; } else if (nrows == 1) { xnoise3 = diffs3[0]; xnoise5 = diffs5[0]; } else { qsort(diffs3, nrows, sizeof(double), FnCompare_double); qsort(diffs5, nrows, sizeof(double), FnCompare_double); xnoise3 = (diffs3[(nrows - 1)/2] + diffs3[nrows/2]) / 2.; xnoise5 = (diffs5[(nrows - 1)/2] + diffs5[nrows/2]) / 2.; } if (nrows2 == 0) { xnoise2 = 0; } else if (nrows2 == 1) { xnoise2 = diffs2[0]; } else { qsort(diffs2, nrows2, sizeof(double), FnCompare_double); xnoise2 = (diffs2[(nrows2 - 1)/2] + diffs2[nrows2/2]) / 2.; } if (ngood) *ngood = ngoodpix; if (minval) *minval = xminval; if (maxval) *maxval = xmaxval; if (noise2) *noise2 = 1.0483579 * xnoise2; if (noise3) *noise3 = 0.6052697 * xnoise3; if (noise5) *noise5 = 0.1772048 * xnoise5; free(diffs5); free(diffs3); free(diffs2); free(differences5); free(differences3); free(differences2); return(*status); } /*--------------------------------------------------------------------------*/ static int FnNoise5_float (float *array, /* 2 dimensional array of image pixels */ long nx, /* number of pixels in each row of the image */ long ny, /* number of rows in the image */ int nullcheck, /* check for null values, if true */ float nullvalue, /* value of null pixels, if nullcheck is true */ /* returned parameters */ long *ngood, /* number of good, non-null pixels? */ float *minval, /* minimum non-null value */ float *maxval, /* maximum non-null value */ double *noise2, /* returned 2nd order MAD of all non-null pixels */ double *noise3, /* returned 3rd order MAD of all non-null pixels */ double *noise5, /* returned 5th order MAD of all non-null pixels */ int *status) /* error status */ /* Estimate the median and background noise in the input image using 2nd, 3rd and 5th order Median Absolute Differences. The noise in the background of the image is calculated using the MAD algorithms developed for deriving the signal to noise ratio in spectra (see issue #42 of the ST-ECF newsletter, http://www.stecf.org/documents/newsletter/) 3rd order: noise = 1.482602 / sqrt(6) * median (abs(2*flux(i) - flux(i-2) - flux(i+2))) The returned estimates are the median of the values that are computed for each row of the image. */ { long ii, jj, nrows = 0, nrows2 = 0, nvals, nvals2, ngoodpix = 0; float *differences2, *differences3, *differences5; float *rowpix, v1, v2, v3, v4, v5, v6, v7, v8, v9; float xminval = FLT_MAX, xmaxval = -FLT_MAX; int do_range = 0; double *diffs2, *diffs3, *diffs5; double xnoise2 = 0, xnoise3 = 0, xnoise5 = 0; if (nx < 9) { /* treat entire array as an image with a single row */ nx = nx * ny; ny = 1; } /* rows must have at least 9 pixels */ if (nx < 9) { for (ii = 0; ii < nx; ii++) { if (nullcheck && array[ii] == nullvalue) continue; else { if (array[ii] < xminval) xminval = array[ii]; if (array[ii] > xmaxval) xmaxval = array[ii]; ngoodpix++; } } if (minval) *minval = xminval; if (maxval) *maxval = xmaxval; if (ngood) *ngood = ngoodpix; if (noise2) *noise2 = 0.; if (noise3) *noise3 = 0.; if (noise5) *noise5 = 0.; return(*status); } /* do we need to compute the min and max value? */ if (minval || maxval) do_range = 1; /* allocate arrays used to compute the median and noise estimates */ differences2 = calloc(nx, sizeof(float)); if (!differences2) { *status = MEMORY_ALLOCATION; return(*status); } differences3 = calloc(nx, sizeof(float)); if (!differences3) { free(differences2); *status = MEMORY_ALLOCATION; return(*status); } differences5 = calloc(nx, sizeof(float)); if (!differences5) { free(differences2); free(differences3); *status = MEMORY_ALLOCATION; return(*status); } diffs2 = calloc(ny, sizeof(double)); if (!diffs2) { free(differences2); free(differences3); free(differences5); *status = MEMORY_ALLOCATION; return(*status); } diffs3 = calloc(ny, sizeof(double)); if (!diffs3) { free(differences2); free(differences3); free(differences5); free(diffs2); *status = MEMORY_ALLOCATION; return(*status); } diffs5 = calloc(ny, sizeof(double)); if (!diffs5) { free(differences2); free(differences3); free(differences5); free(diffs2); free(diffs3); *status = MEMORY_ALLOCATION; return(*status); } /* loop over each row of the image */ for (jj=0; jj < ny; jj++) { rowpix = array + (jj * nx); /* point to first pixel in the row */ /***** find the first valid pixel in row */ ii = 0; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v1 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v1 < xminval) xminval = v1; if (v1 > xmaxval) xmaxval = v1; } /***** find the 2nd valid pixel in row (which we will skip over) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v2 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v2 < xminval) xminval = v2; if (v2 > xmaxval) xmaxval = v2; } /***** find the 3rd valid pixel in row */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v3 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v3 < xminval) xminval = v3; if (v3 > xmaxval) xmaxval = v3; } /* find the 4nd valid pixel in row (to be skipped) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v4 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v4 < xminval) xminval = v4; if (v4 > xmaxval) xmaxval = v4; } /* find the 5th valid pixel in row (to be skipped) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v5 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v5 < xminval) xminval = v5; if (v5 > xmaxval) xmaxval = v5; } /* find the 6th valid pixel in row (to be skipped) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v6 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v6 < xminval) xminval = v6; if (v6 > xmaxval) xmaxval = v6; } /* find the 7th valid pixel in row (to be skipped) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v7 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v7 < xminval) xminval = v7; if (v7 > xmaxval) xmaxval = v7; } /* find the 8th valid pixel in row (to be skipped) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v8 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v8 < xminval) xminval = v8; if (v8 > xmaxval) xmaxval = v8; } /* now populate the differences arrays */ /* for the remaining pixels in the row */ nvals = 0; nvals2 = 0; for (ii++; ii < nx; ii++) { /* find the next valid pixel in row */ if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) break; /* hit end of row */ v9 = rowpix[ii]; /* store the good pixel value */ if (do_range) { if (v9 < xminval) xminval = v9; if (v9 > xmaxval) xmaxval = v9; } /* construct array of absolute differences */ if (!(v5 == v6 && v6 == v7) ) { differences2[nvals2] = (float) fabs(v5 - v7); nvals2++; } if (!(v3 == v4 && v4 == v5 && v5 == v6 && v6 == v7) ) { differences3[nvals] = (float) fabs((2 * v5) - v3 - v7); differences5[nvals] = (float) fabs((6 * v5) - (4 * v3) - (4 * v7) + v1 + v9); nvals++; } else { /* ignore constant background regions */ ngoodpix++; } /* shift over 1 pixel */ v1 = v2; v2 = v3; v3 = v4; v4 = v5; v5 = v6; v6 = v7; v7 = v8; v8 = v9; } /* end of loop over pixels in the row */ /* compute the median diffs */ /* Note that there are 8 more pixel values than there are diffs values. */ ngoodpix += nvals; if (nvals == 0) { continue; /* cannot compute medians on this row */ } else if (nvals == 1) { if (nvals2 == 1) { diffs2[nrows2] = differences2[0]; nrows2++; } diffs3[nrows] = differences3[0]; diffs5[nrows] = differences5[0]; } else { /* quick_select returns the median MUCH faster than using qsort */ if (nvals2 > 1) { diffs2[nrows2] = quick_select_float(differences2, nvals); nrows2++; } diffs3[nrows] = quick_select_float(differences3, nvals); diffs5[nrows] = quick_select_float(differences5, nvals); } nrows++; } /* end of loop over rows */ /* compute median of the values for each row */ if (nrows == 0) { xnoise3 = 0; xnoise5 = 0; } else if (nrows == 1) { xnoise3 = diffs3[0]; xnoise5 = diffs5[0]; } else { qsort(diffs3, nrows, sizeof(double), FnCompare_double); qsort(diffs5, nrows, sizeof(double), FnCompare_double); xnoise3 = (diffs3[(nrows - 1)/2] + diffs3[nrows/2]) / 2.; xnoise5 = (diffs5[(nrows - 1)/2] + diffs5[nrows/2]) / 2.; } if (nrows2 == 0) { xnoise2 = 0; } else if (nrows2 == 1) { xnoise2 = diffs2[0]; } else { qsort(diffs2, nrows2, sizeof(double), FnCompare_double); xnoise2 = (diffs2[(nrows2 - 1)/2] + diffs2[nrows2/2]) / 2.; } if (ngood) *ngood = ngoodpix; if (minval) *minval = xminval; if (maxval) *maxval = xmaxval; if (noise2) *noise2 = 1.0483579 * xnoise2; if (noise3) *noise3 = 0.6052697 * xnoise3; if (noise5) *noise5 = 0.1772048 * xnoise5; free(diffs5); free(diffs3); free(diffs2); free(differences5); free(differences3); free(differences2); return(*status); } /*--------------------------------------------------------------------------*/ static int FnNoise5_double (double *array, /* 2 dimensional array of image pixels */ long nx, /* number of pixels in each row of the image */ long ny, /* number of rows in the image */ int nullcheck, /* check for null values, if true */ double nullvalue, /* value of null pixels, if nullcheck is true */ /* returned parameters */ long *ngood, /* number of good, non-null pixels? */ double *minval, /* minimum non-null value */ double *maxval, /* maximum non-null value */ double *noise2, /* returned 2nd order MAD of all non-null pixels */ double *noise3, /* returned 3rd order MAD of all non-null pixels */ double *noise5, /* returned 5th order MAD of all non-null pixels */ int *status) /* error status */ /* Estimate the median and background noise in the input image using 2nd, 3rd and 5th order Median Absolute Differences. The noise in the background of the image is calculated using the MAD algorithms developed for deriving the signal to noise ratio in spectra (see issue #42 of the ST-ECF newsletter, http://www.stecf.org/documents/newsletter/) 3rd order: noise = 1.482602 / sqrt(6) * median (abs(2*flux(i) - flux(i-2) - flux(i+2))) The returned estimates are the median of the values that are computed for each row of the image. */ { long ii, jj, nrows = 0, nrows2 = 0, nvals, nvals2, ngoodpix = 0; double *differences2, *differences3, *differences5; double *rowpix, v1, v2, v3, v4, v5, v6, v7, v8, v9; double xminval = DBL_MAX, xmaxval = -DBL_MAX; int do_range = 0; double *diffs2, *diffs3, *diffs5; double xnoise2 = 0, xnoise3 = 0, xnoise5 = 0; if (nx < 9) { /* treat entire array as an image with a single row */ nx = nx * ny; ny = 1; } /* rows must have at least 9 pixels */ if (nx < 9) { for (ii = 0; ii < nx; ii++) { if (nullcheck && array[ii] == nullvalue) continue; else { if (array[ii] < xminval) xminval = array[ii]; if (array[ii] > xmaxval) xmaxval = array[ii]; ngoodpix++; } } if (minval) *minval = xminval; if (maxval) *maxval = xmaxval; if (ngood) *ngood = ngoodpix; if (noise2) *noise2 = 0.; if (noise3) *noise3 = 0.; if (noise5) *noise5 = 0.; return(*status); } /* do we need to compute the min and max value? */ if (minval || maxval) do_range = 1; /* allocate arrays used to compute the median and noise estimates */ differences2 = calloc(nx, sizeof(double)); if (!differences2) { *status = MEMORY_ALLOCATION; return(*status); } differences3 = calloc(nx, sizeof(double)); if (!differences3) { free(differences2); *status = MEMORY_ALLOCATION; return(*status); } differences5 = calloc(nx, sizeof(double)); if (!differences5) { free(differences2); free(differences3); *status = MEMORY_ALLOCATION; return(*status); } diffs2 = calloc(ny, sizeof(double)); if (!diffs2) { free(differences2); free(differences3); free(differences5); *status = MEMORY_ALLOCATION; return(*status); } diffs3 = calloc(ny, sizeof(double)); if (!diffs3) { free(differences2); free(differences3); free(differences5); free(diffs2); *status = MEMORY_ALLOCATION; return(*status); } diffs5 = calloc(ny, sizeof(double)); if (!diffs5) { free(differences2); free(differences3); free(differences5); free(diffs2); free(diffs3); *status = MEMORY_ALLOCATION; return(*status); } /* loop over each row of the image */ for (jj=0; jj < ny; jj++) { rowpix = array + (jj * nx); /* point to first pixel in the row */ /***** find the first valid pixel in row */ ii = 0; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v1 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v1 < xminval) xminval = v1; if (v1 > xmaxval) xmaxval = v1; } /***** find the 2nd valid pixel in row (which we will skip over) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v2 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v2 < xminval) xminval = v2; if (v2 > xmaxval) xmaxval = v2; } /***** find the 3rd valid pixel in row */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v3 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v3 < xminval) xminval = v3; if (v3 > xmaxval) xmaxval = v3; } /* find the 4nd valid pixel in row (to be skipped) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v4 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v4 < xminval) xminval = v4; if (v4 > xmaxval) xmaxval = v4; } /* find the 5th valid pixel in row (to be skipped) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v5 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v5 < xminval) xminval = v5; if (v5 > xmaxval) xmaxval = v5; } /* find the 6th valid pixel in row (to be skipped) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v6 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v6 < xminval) xminval = v6; if (v6 > xmaxval) xmaxval = v6; } /* find the 7th valid pixel in row (to be skipped) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v7 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v7 < xminval) xminval = v7; if (v7 > xmaxval) xmaxval = v7; } /* find the 8th valid pixel in row (to be skipped) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v8 = rowpix[ii]; /* store the good pixel value */ ngoodpix++; if (do_range) { if (v8 < xminval) xminval = v8; if (v8 > xmaxval) xmaxval = v8; } /* now populate the differences arrays */ /* for the remaining pixels in the row */ nvals = 0; nvals2 = 0; for (ii++; ii < nx; ii++) { /* find the next valid pixel in row */ if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) break; /* hit end of row */ v9 = rowpix[ii]; /* store the good pixel value */ if (do_range) { if (v9 < xminval) xminval = v9; if (v9 > xmaxval) xmaxval = v9; } /* construct array of absolute differences */ if (!(v5 == v6 && v6 == v7) ) { differences2[nvals2] = fabs(v5 - v7); nvals2++; } if (!(v3 == v4 && v4 == v5 && v5 == v6 && v6 == v7) ) { differences3[nvals] = fabs((2 * v5) - v3 - v7); differences5[nvals] = fabs((6 * v5) - (4 * v3) - (4 * v7) + v1 + v9); nvals++; } else { /* ignore constant background regions */ ngoodpix++; } /* shift over 1 pixel */ v1 = v2; v2 = v3; v3 = v4; v4 = v5; v5 = v6; v6 = v7; v7 = v8; v8 = v9; } /* end of loop over pixels in the row */ /* compute the median diffs */ /* Note that there are 8 more pixel values than there are diffs values. */ ngoodpix += nvals; if (nvals == 0) { continue; /* cannot compute medians on this row */ } else if (nvals == 1) { if (nvals2 == 1) { diffs2[nrows2] = differences2[0]; nrows2++; } diffs3[nrows] = differences3[0]; diffs5[nrows] = differences5[0]; } else { /* quick_select returns the median MUCH faster than using qsort */ if (nvals2 > 1) { diffs2[nrows2] = quick_select_double(differences2, nvals); nrows2++; } diffs3[nrows] = quick_select_double(differences3, nvals); diffs5[nrows] = quick_select_double(differences5, nvals); } nrows++; } /* end of loop over rows */ /* compute median of the values for each row */ if (nrows == 0) { xnoise3 = 0; xnoise5 = 0; } else if (nrows == 1) { xnoise3 = diffs3[0]; xnoise5 = diffs5[0]; } else { qsort(diffs3, nrows, sizeof(double), FnCompare_double); qsort(diffs5, nrows, sizeof(double), FnCompare_double); xnoise3 = (diffs3[(nrows - 1)/2] + diffs3[nrows/2]) / 2.; xnoise5 = (diffs5[(nrows - 1)/2] + diffs5[nrows/2]) / 2.; } if (nrows2 == 0) { xnoise2 = 0; } else if (nrows2 == 1) { xnoise2 = diffs2[0]; } else { qsort(diffs2, nrows2, sizeof(double), FnCompare_double); xnoise2 = (diffs2[(nrows2 - 1)/2] + diffs2[nrows2/2]) / 2.; } if (ngood) *ngood = ngoodpix; if (minval) *minval = xminval; if (maxval) *maxval = xmaxval; if (noise2) *noise2 = 1.0483579 * xnoise2; if (noise3) *noise3 = 0.6052697 * xnoise3; if (noise5) *noise5 = 0.1772048 * xnoise5; free(diffs5); free(diffs3); free(diffs2); free(differences5); free(differences3); free(differences2); return(*status); } /*--------------------------------------------------------------------------*/ static int FnNoise3_short (short *array, /* 2 dimensional array of image pixels */ long nx, /* number of pixels in each row of the image */ long ny, /* number of rows in the image */ int nullcheck, /* check for null values, if true */ short nullvalue, /* value of null pixels, if nullcheck is true */ /* returned parameters */ long *ngood, /* number of good, non-null pixels? */ short *minval, /* minimum non-null value */ short *maxval, /* maximum non-null value */ double *noise, /* returned R.M.S. value of all non-null pixels */ int *status) /* error status */ /* Estimate the median and background noise in the input image using 3rd order differences. The noise in the background of the image is calculated using the 3rd order algorithm developed for deriving the signal to noise ratio in spectra (see issue #42 of the ST-ECF newsletter, http://www.stecf.org/documents/newsletter/) noise = 1.482602 / sqrt(6) * median (abs(2*flux(i) - flux(i-2) - flux(i+2))) The returned estimates are the median of the values that are computed for each row of the image. */ { long ii, jj, nrows = 0, nvals, ngoodpix = 0; short *differences, *rowpix, v1, v2, v3, v4, v5; short xminval = SHRT_MAX, xmaxval = SHRT_MIN, do_range = 0; double *diffs, xnoise = 0, sigma; if (nx < 5) { /* treat entire array as an image with a single row */ nx = nx * ny; ny = 1; } /* rows must have at least 5 pixels */ if (nx < 5) { for (ii = 0; ii < nx; ii++) { if (nullcheck && array[ii] == nullvalue) continue; else { if (array[ii] < xminval) xminval = array[ii]; if (array[ii] > xmaxval) xmaxval = array[ii]; ngoodpix++; } } if (minval) *minval = xminval; if (maxval) *maxval = xmaxval; if (ngood) *ngood = ngoodpix; if (noise) *noise = 0.; return(*status); } /* do we need to compute the min and max value? */ if (minval || maxval) do_range = 1; /* allocate arrays used to compute the median and noise estimates */ differences = calloc(nx, sizeof(short)); if (!differences) { *status = MEMORY_ALLOCATION; return(*status); } diffs = calloc(ny, sizeof(double)); if (!diffs) { free(differences); *status = MEMORY_ALLOCATION; return(*status); } /* loop over each row of the image */ for (jj=0; jj < ny; jj++) { rowpix = array + (jj * nx); /* point to first pixel in the row */ /***** find the first valid pixel in row */ ii = 0; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v1 = rowpix[ii]; /* store the good pixel value */ if (do_range) { if (v1 < xminval) xminval = v1; if (v1 > xmaxval) xmaxval = v1; } /***** find the 2nd valid pixel in row (which we will skip over) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v2 = rowpix[ii]; /* store the good pixel value */ if (do_range) { if (v2 < xminval) xminval = v2; if (v2 > xmaxval) xmaxval = v2; } /***** find the 3rd valid pixel in row */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v3 = rowpix[ii]; /* store the good pixel value */ if (do_range) { if (v3 < xminval) xminval = v3; if (v3 > xmaxval) xmaxval = v3; } /* find the 4nd valid pixel in row (to be skipped) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v4 = rowpix[ii]; /* store the good pixel value */ if (do_range) { if (v4 < xminval) xminval = v4; if (v4 > xmaxval) xmaxval = v4; } /* now populate the differences arrays */ /* for the remaining pixels in the row */ nvals = 0; for (ii++; ii < nx; ii++) { /* find the next valid pixel in row */ if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) break; /* hit end of row */ v5 = rowpix[ii]; /* store the good pixel value */ if (do_range) { if (v5 < xminval) xminval = v5; if (v5 > xmaxval) xmaxval = v5; } /* construct array of 3rd order absolute differences */ if (!(v1 == v2 && v2 == v3 && v3 == v4 && v4 == v5)) { differences[nvals] = abs((2 * v3) - v1 - v5); nvals++; } else { /* ignore constant background regions */ ngoodpix++; } /* shift over 1 pixel */ v1 = v2; v2 = v3; v3 = v4; v4 = v5; } /* end of loop over pixels in the row */ /* compute the 3rd order diffs */ /* Note that there are 4 more pixel values than there are diffs values. */ ngoodpix += (nvals + 4); if (nvals == 0) { continue; /* cannot compute medians on this row */ } else if (nvals == 1) { diffs[nrows] = differences[0]; } else { /* quick_select returns the median MUCH faster than using qsort */ diffs[nrows] = quick_select_short(differences, nvals); } nrows++; } /* end of loop over rows */ /* compute median of the values for each row */ if (nrows == 0) { xnoise = 0; } else if (nrows == 1) { xnoise = diffs[0]; } else { qsort(diffs, nrows, sizeof(double), FnCompare_double); xnoise = (diffs[(nrows - 1)/2] + diffs[nrows/2]) / 2.; FnMeanSigma_double(diffs, nrows, 0, 0.0, 0, &xnoise, &sigma, status); /* do a 4.5 sigma rejection of outliers */ jj = 0; sigma = 4.5 * sigma; for (ii = 0; ii < nrows; ii++) { if ( fabs(diffs[ii] - xnoise) <= sigma) { if (jj != ii) diffs[jj] = diffs[ii]; jj++; } } if (ii != jj) FnMeanSigma_double(diffs, jj, 0, 0.0, 0, &xnoise, &sigma, status); } if (ngood) *ngood = ngoodpix; if (minval) *minval = xminval; if (maxval) *maxval = xmaxval; if (noise) *noise = 0.6052697 * xnoise; free(diffs); free(differences); return(*status); } /*--------------------------------------------------------------------------*/ static int FnNoise3_int (int *array, /* 2 dimensional array of image pixels */ long nx, /* number of pixels in each row of the image */ long ny, /* number of rows in the image */ int nullcheck, /* check for null values, if true */ int nullvalue, /* value of null pixels, if nullcheck is true */ /* returned parameters */ long *ngood, /* number of good, non-null pixels? */ int *minval, /* minimum non-null value */ int *maxval, /* maximum non-null value */ double *noise, /* returned R.M.S. value of all non-null pixels */ int *status) /* error status */ /* Estimate the background noise in the input image using 3rd order differences. The noise in the background of the image is calculated using the 3rd order algorithm developed for deriving the signal to noise ratio in spectra (see issue #42 of the ST-ECF newsletter, http://www.stecf.org/documents/newsletter/) noise = 1.482602 / sqrt(6) * median (abs(2*flux(i) - flux(i-2) - flux(i+2))) The returned estimates are the median of the values that are computed for each row of the image. */ { long ii, jj, nrows = 0, nvals, ngoodpix = 0; int *differences, *rowpix, v1, v2, v3, v4, v5; int xminval = INT_MAX, xmaxval = INT_MIN, do_range = 0; double *diffs, xnoise = 0, sigma; if (nx < 5) { /* treat entire array as an image with a single row */ nx = nx * ny; ny = 1; } /* rows must have at least 5 pixels */ if (nx < 5) { for (ii = 0; ii < nx; ii++) { if (nullcheck && array[ii] == nullvalue) continue; else { if (array[ii] < xminval) xminval = array[ii]; if (array[ii] > xmaxval) xmaxval = array[ii]; ngoodpix++; } } if (minval) *minval = xminval; if (maxval) *maxval = xmaxval; if (ngood) *ngood = ngoodpix; if (noise) *noise = 0.; return(*status); } /* do we need to compute the min and max value? */ if (minval || maxval) do_range = 1; /* allocate arrays used to compute the median and noise estimates */ differences = calloc(nx, sizeof(int)); if (!differences) { *status = MEMORY_ALLOCATION; return(*status); } diffs = calloc(ny, sizeof(double)); if (!diffs) { free(differences); *status = MEMORY_ALLOCATION; return(*status); } /* loop over each row of the image */ for (jj=0; jj < ny; jj++) { rowpix = array + (jj * nx); /* point to first pixel in the row */ /***** find the first valid pixel in row */ ii = 0; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v1 = rowpix[ii]; /* store the good pixel value */ if (do_range) { if (v1 < xminval) xminval = v1; if (v1 > xmaxval) xmaxval = v1; } /***** find the 2nd valid pixel in row (which we will skip over) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v2 = rowpix[ii]; /* store the good pixel value */ if (do_range) { if (v2 < xminval) xminval = v2; if (v2 > xmaxval) xmaxval = v2; } /***** find the 3rd valid pixel in row */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v3 = rowpix[ii]; /* store the good pixel value */ if (do_range) { if (v3 < xminval) xminval = v3; if (v3 > xmaxval) xmaxval = v3; } /* find the 4nd valid pixel in row (to be skipped) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v4 = rowpix[ii]; /* store the good pixel value */ if (do_range) { if (v4 < xminval) xminval = v4; if (v4 > xmaxval) xmaxval = v4; } /* now populate the differences arrays */ /* for the remaining pixels in the row */ nvals = 0; for (ii++; ii < nx; ii++) { /* find the next valid pixel in row */ if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) break; /* hit end of row */ v5 = rowpix[ii]; /* store the good pixel value */ if (do_range) { if (v5 < xminval) xminval = v5; if (v5 > xmaxval) xmaxval = v5; } /* construct array of 3rd order absolute differences */ if (!(v1 == v2 && v2 == v3 && v3 == v4 && v4 == v5)) { differences[nvals] = abs((2 * v3) - v1 - v5); nvals++; } else { /* ignore constant background regions */ ngoodpix++; } /* shift over 1 pixel */ v1 = v2; v2 = v3; v3 = v4; v4 = v5; } /* end of loop over pixels in the row */ /* compute the 3rd order diffs */ /* Note that there are 4 more pixel values than there are diffs values. */ ngoodpix += (nvals + 4); if (nvals == 0) { continue; /* cannot compute medians on this row */ } else if (nvals == 1) { diffs[nrows] = differences[0]; } else { /* quick_select returns the median MUCH faster than using qsort */ diffs[nrows] = quick_select_int(differences, nvals); } nrows++; } /* end of loop over rows */ /* compute median of the values for each row */ if (nrows == 0) { xnoise = 0; } else if (nrows == 1) { xnoise = diffs[0]; } else { qsort(diffs, nrows, sizeof(double), FnCompare_double); xnoise = (diffs[(nrows - 1)/2] + diffs[nrows/2]) / 2.; FnMeanSigma_double(diffs, nrows, 0, 0.0, 0, &xnoise, &sigma, status); /* do a 4.5 sigma rejection of outliers */ jj = 0; sigma = 4.5 * sigma; for (ii = 0; ii < nrows; ii++) { if ( fabs(diffs[ii] - xnoise) <= sigma) { if (jj != ii) diffs[jj] = diffs[ii]; jj++; } } if (ii != jj) FnMeanSigma_double(diffs, jj, 0, 0.0, 0, &xnoise, &sigma, status); } if (ngood) *ngood = ngoodpix; if (minval) *minval = xminval; if (maxval) *maxval = xmaxval; if (noise) *noise = 0.6052697 * xnoise; free(diffs); free(differences); return(*status); } /*--------------------------------------------------------------------------*/ static int FnNoise3_float (float *array, /* 2 dimensional array of image pixels */ long nx, /* number of pixels in each row of the image */ long ny, /* number of rows in the image */ int nullcheck, /* check for null values, if true */ float nullvalue, /* value of null pixels, if nullcheck is true */ /* returned parameters */ long *ngood, /* number of good, non-null pixels? */ float *minval, /* minimum non-null value */ float *maxval, /* maximum non-null value */ double *noise, /* returned R.M.S. value of all non-null pixels */ int *status) /* error status */ /* Estimate the median and background noise in the input image using 3rd order differences. The noise in the background of the image is calculated using the 3rd order algorithm developed for deriving the signal to noise ratio in spectra (see issue #42 of the ST-ECF newsletter, http://www.stecf.org/documents/newsletter/) noise = 1.482602 / sqrt(6) * median (abs(2*flux(i) - flux(i-2) - flux(i+2))) The returned estimates are the median of the values that are computed for each row of the image. */ { long ii, jj, nrows = 0, nvals, ngoodpix = 0; float *differences, *rowpix, v1, v2, v3, v4, v5; float xminval = FLT_MAX, xmaxval = -FLT_MAX; int do_range = 0; double *diffs, xnoise = 0; if (nx < 5) { /* treat entire array as an image with a single row */ nx = nx * ny; ny = 1; } /* rows must have at least 5 pixels to calc noise, so just calc min, max, ngood */ if (nx < 5) { for (ii = 0; ii < nx; ii++) { if (nullcheck && array[ii] == nullvalue) continue; else { if (array[ii] < xminval) xminval = array[ii]; if (array[ii] > xmaxval) xmaxval = array[ii]; ngoodpix++; } } if (minval) *minval = xminval; if (maxval) *maxval = xmaxval; if (ngood) *ngood = ngoodpix; if (noise) *noise = 0.; return(*status); } /* do we need to compute the min and max value? */ if (minval || maxval) do_range = 1; /* allocate arrays used to compute the median and noise estimates */ if (noise) { differences = calloc(nx, sizeof(float)); if (!differences) { *status = MEMORY_ALLOCATION; return(*status); } diffs = calloc(ny, sizeof(double)); if (!diffs) { free(differences); *status = MEMORY_ALLOCATION; return(*status); } } /* loop over each row of the image */ for (jj=0; jj < ny; jj++) { rowpix = array + (jj * nx); /* point to first pixel in the row */ /***** find the first valid pixel in row */ ii = 0; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v1 = rowpix[ii]; /* store the good pixel value */ if (do_range) { if (v1 < xminval) xminval = v1; if (v1 > xmaxval) xmaxval = v1; } /***** find the 2nd valid pixel in row (which we will skip over) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v2 = rowpix[ii]; /* store the good pixel value */ if (do_range) { if (v2 < xminval) xminval = v2; if (v2 > xmaxval) xmaxval = v2; } /***** find the 3rd valid pixel in row */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v3 = rowpix[ii]; /* store the good pixel value */ if (do_range) { if (v3 < xminval) xminval = v3; if (v3 > xmaxval) xmaxval = v3; } /* find the 4nd valid pixel in row (to be skipped) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v4 = rowpix[ii]; /* store the good pixel value */ if (do_range) { if (v4 < xminval) xminval = v4; if (v4 > xmaxval) xmaxval = v4; } /* now populate the differences arrays */ /* for the remaining pixels in the row */ nvals = 0; for (ii++; ii < nx; ii++) { /* find the next valid pixel in row */ if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) { ii++; } if (ii == nx) break; /* hit end of row */ v5 = rowpix[ii]; /* store the good pixel value */ if (do_range) { if (v5 < xminval) xminval = v5; if (v5 > xmaxval) xmaxval = v5; } /* construct array of 3rd order absolute differences */ if (noise) { if (!(v1 == v2 && v2 == v3 && v3 == v4 && v4 == v5)) { differences[nvals] = (float) fabs((2. * v3) - v1 - v5); nvals++; } else { /* ignore constant background regions */ ngoodpix++; } } else { /* just increment the number of non-null pixels */ ngoodpix++; } /* shift over 1 pixel */ v1 = v2; v2 = v3; v3 = v4; v4 = v5; } /* end of loop over pixels in the row */ /* compute the 3rd order diffs */ /* Note that there are 4 more pixel values than there are diffs values. */ ngoodpix += (nvals + 4); if (noise) { if (nvals == 0) { continue; /* cannot compute medians on this row */ } else if (nvals == 1) { diffs[nrows] = differences[0]; } else { /* quick_select returns the median MUCH faster than using qsort */ diffs[nrows] = quick_select_float(differences, nvals); } } nrows++; } /* end of loop over rows */ /* compute median of the values for each row */ if (noise) { if (nrows == 0) { xnoise = 0; } else if (nrows == 1) { xnoise = diffs[0]; } else { qsort(diffs, nrows, sizeof(double), FnCompare_double); xnoise = (diffs[(nrows - 1)/2] + diffs[nrows/2]) / 2.; } } if (ngood) *ngood = ngoodpix; if (minval) *minval = xminval; if (maxval) *maxval = xmaxval; if (noise) { *noise = 0.6052697 * xnoise; free(diffs); free(differences); } return(*status); } /*--------------------------------------------------------------------------*/ static int FnNoise3_double (double *array, /* 2 dimensional array of image pixels */ long nx, /* number of pixels in each row of the image */ long ny, /* number of rows in the image */ int nullcheck, /* check for null values, if true */ double nullvalue, /* value of null pixels, if nullcheck is true */ /* returned parameters */ long *ngood, /* number of good, non-null pixels? */ double *minval, /* minimum non-null value */ double *maxval, /* maximum non-null value */ double *noise, /* returned R.M.S. value of all non-null pixels */ int *status) /* error status */ /* Estimate the median and background noise in the input image using 3rd order differences. The noise in the background of the image is calculated using the 3rd order algorithm developed for deriving the signal to noise ratio in spectra (see issue #42 of the ST-ECF newsletter, http://www.stecf.org/documents/newsletter/) noise = 1.482602 / sqrt(6) * median (abs(2*flux(i) - flux(i-2) - flux(i+2))) The returned estimates are the median of the values that are computed for each row of the image. */ { long ii, jj, nrows = 0, nvals, ngoodpix = 0; double *differences, *rowpix, v1, v2, v3, v4, v5; double xminval = DBL_MAX, xmaxval = -DBL_MAX; int do_range = 0; double *diffs, xnoise = 0; if (nx < 5) { /* treat entire array as an image with a single row */ nx = nx * ny; ny = 1; } /* rows must have at least 5 pixels */ if (nx < 5) { for (ii = 0; ii < nx; ii++) { if (nullcheck && array[ii] == nullvalue) continue; else { if (array[ii] < xminval) xminval = array[ii]; if (array[ii] > xmaxval) xmaxval = array[ii]; ngoodpix++; } } if (minval) *minval = xminval; if (maxval) *maxval = xmaxval; if (ngood) *ngood = ngoodpix; if (noise) *noise = 0.; return(*status); } /* do we need to compute the min and max value? */ if (minval || maxval) do_range = 1; /* allocate arrays used to compute the median and noise estimates */ if (noise) { differences = calloc(nx, sizeof(double)); if (!differences) { *status = MEMORY_ALLOCATION; return(*status); } diffs = calloc(ny, sizeof(double)); if (!diffs) { free(differences); *status = MEMORY_ALLOCATION; return(*status); } } /* loop over each row of the image */ for (jj=0; jj < ny; jj++) { rowpix = array + (jj * nx); /* point to first pixel in the row */ /***** find the first valid pixel in row */ ii = 0; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v1 = rowpix[ii]; /* store the good pixel value */ if (do_range) { if (v1 < xminval) xminval = v1; if (v1 > xmaxval) xmaxval = v1; } /***** find the 2nd valid pixel in row (which we will skip over) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v2 = rowpix[ii]; /* store the good pixel value */ if (do_range) { if (v2 < xminval) xminval = v2; if (v2 > xmaxval) xmaxval = v2; } /***** find the 3rd valid pixel in row */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v3 = rowpix[ii]; /* store the good pixel value */ if (do_range) { if (v3 < xminval) xminval = v3; if (v3 > xmaxval) xmaxval = v3; } /* find the 4nd valid pixel in row (to be skipped) */ ii++; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v4 = rowpix[ii]; /* store the good pixel value */ if (do_range) { if (v4 < xminval) xminval = v4; if (v4 > xmaxval) xmaxval = v4; } /* now populate the differences arrays */ /* for the remaining pixels in the row */ nvals = 0; for (ii++; ii < nx; ii++) { /* find the next valid pixel in row */ if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) break; /* hit end of row */ v5 = rowpix[ii]; /* store the good pixel value */ if (do_range) { if (v5 < xminval) xminval = v5; if (v5 > xmaxval) xmaxval = v5; } /* construct array of 3rd order absolute differences */ if (noise) { if (!(v1 == v2 && v2 == v3 && v3 == v4 && v4 == v5)) { differences[nvals] = fabs((2. * v3) - v1 - v5); nvals++; } else { /* ignore constant background regions */ ngoodpix++; } } else { /* just increment the number of non-null pixels */ ngoodpix++; } /* shift over 1 pixel */ v1 = v2; v2 = v3; v3 = v4; v4 = v5; } /* end of loop over pixels in the row */ /* compute the 3rd order diffs */ /* Note that there are 4 more pixel values than there are diffs values. */ ngoodpix += (nvals + 4); if (noise) { if (nvals == 0) { continue; /* cannot compute medians on this row */ } else if (nvals == 1) { diffs[nrows] = differences[0]; } else { /* quick_select returns the median MUCH faster than using qsort */ diffs[nrows] = quick_select_double(differences, nvals); } } nrows++; } /* end of loop over rows */ /* compute median of the values for each row */ if (noise) { if (nrows == 0) { xnoise = 0; } else if (nrows == 1) { xnoise = diffs[0]; } else { qsort(diffs, nrows, sizeof(double), FnCompare_double); xnoise = (diffs[(nrows - 1)/2] + diffs[nrows/2]) / 2.; } } if (ngood) *ngood = ngoodpix; if (minval) *minval = xminval; if (maxval) *maxval = xmaxval; if (noise) { *noise = 0.6052697 * xnoise; free(diffs); free(differences); } return(*status); } /*--------------------------------------------------------------------------*/ static int FnNoise1_short (short *array, /* 2 dimensional array of image pixels */ long nx, /* number of pixels in each row of the image */ long ny, /* number of rows in the image */ int nullcheck, /* check for null values, if true */ short nullvalue, /* value of null pixels, if nullcheck is true */ /* returned parameters */ double *noise, /* returned R.M.S. value of all non-null pixels */ int *status) /* error status */ /* Estimate the background noise in the input image using sigma of 1st order differences. noise = 1.0 / sqrt(2) * rms of (flux[i] - flux[i-1]) The returned estimate is the median of the values that are computed for each row of the image. */ { int iter; long ii, jj, kk, nrows = 0, nvals; short *differences, *rowpix, v1; double *diffs, xnoise, mean, stdev; /* rows must have at least 3 pixels to estimate noise */ if (nx < 3) { *noise = 0; return(*status); } /* allocate arrays used to compute the median and noise estimates */ differences = calloc(nx, sizeof(short)); if (!differences) { *status = MEMORY_ALLOCATION; return(*status); } diffs = calloc(ny, sizeof(double)); if (!diffs) { free(differences); *status = MEMORY_ALLOCATION; return(*status); } /* loop over each row of the image */ for (jj=0; jj < ny; jj++) { rowpix = array + (jj * nx); /* point to first pixel in the row */ /***** find the first valid pixel in row */ ii = 0; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v1 = rowpix[ii]; /* store the good pixel value */ /* now continue populating the differences arrays */ /* for the remaining pixels in the row */ nvals = 0; for (ii++; ii < nx; ii++) { /* find the next valid pixel in row */ if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) break; /* hit end of row */ /* construct array of 1st order differences */ differences[nvals] = v1 - rowpix[ii]; nvals++; /* shift over 1 pixel */ v1 = rowpix[ii]; } /* end of loop over pixels in the row */ if (nvals < 2) continue; else { FnMeanSigma_short(differences, nvals, 0, 0, 0, &mean, &stdev, status); if (stdev > 0.) { for (iter = 0; iter < NITER; iter++) { kk = 0; for (ii = 0; ii < nvals; ii++) { if (fabs (differences[ii] - mean) < SIGMA_CLIP * stdev) { if (kk < ii) differences[kk] = differences[ii]; kk++; } } if (kk == nvals) break; nvals = kk; FnMeanSigma_short(differences, nvals, 0, 0, 0, &mean, &stdev, status); } } diffs[nrows] = stdev; nrows++; } } /* end of loop over rows */ /* compute median of the values for each row */ if (nrows == 0) { xnoise = 0; } else if (nrows == 1) { xnoise = diffs[0]; } else { qsort(diffs, nrows, sizeof(double), FnCompare_double); xnoise = (diffs[(nrows - 1)/2] + diffs[nrows/2]) / 2.; } *noise = .70710678 * xnoise; free(diffs); free(differences); return(*status); } /*--------------------------------------------------------------------------*/ static int FnNoise1_int (int *array, /* 2 dimensional array of image pixels */ long nx, /* number of pixels in each row of the image */ long ny, /* number of rows in the image */ int nullcheck, /* check for null values, if true */ int nullvalue, /* value of null pixels, if nullcheck is true */ /* returned parameters */ double *noise, /* returned R.M.S. value of all non-null pixels */ int *status) /* error status */ /* Estimate the background noise in the input image using sigma of 1st order differences. noise = 1.0 / sqrt(2) * rms of (flux[i] - flux[i-1]) The returned estimate is the median of the values that are computed for each row of the image. */ { int iter; long ii, jj, kk, nrows = 0, nvals; int *differences, *rowpix, v1; double *diffs, xnoise, mean, stdev; /* rows must have at least 3 pixels to estimate noise */ if (nx < 3) { *noise = 0; return(*status); } /* allocate arrays used to compute the median and noise estimates */ differences = calloc(nx, sizeof(int)); if (!differences) { *status = MEMORY_ALLOCATION; return(*status); } diffs = calloc(ny, sizeof(double)); if (!diffs) { free(differences); *status = MEMORY_ALLOCATION; return(*status); } /* loop over each row of the image */ for (jj=0; jj < ny; jj++) { rowpix = array + (jj * nx); /* point to first pixel in the row */ /***** find the first valid pixel in row */ ii = 0; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v1 = rowpix[ii]; /* store the good pixel value */ /* now continue populating the differences arrays */ /* for the remaining pixels in the row */ nvals = 0; for (ii++; ii < nx; ii++) { /* find the next valid pixel in row */ if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) break; /* hit end of row */ /* construct array of 1st order differences */ differences[nvals] = v1 - rowpix[ii]; nvals++; /* shift over 1 pixel */ v1 = rowpix[ii]; } /* end of loop over pixels in the row */ if (nvals < 2) continue; else { FnMeanSigma_int(differences, nvals, 0, 0, 0, &mean, &stdev, status); if (stdev > 0.) { for (iter = 0; iter < NITER; iter++) { kk = 0; for (ii = 0; ii < nvals; ii++) { if (fabs (differences[ii] - mean) < SIGMA_CLIP * stdev) { if (kk < ii) differences[kk] = differences[ii]; kk++; } } if (kk == nvals) break; nvals = kk; FnMeanSigma_int(differences, nvals, 0, 0, 0, &mean, &stdev, status); } } diffs[nrows] = stdev; nrows++; } } /* end of loop over rows */ /* compute median of the values for each row */ if (nrows == 0) { xnoise = 0; } else if (nrows == 1) { xnoise = diffs[0]; } else { qsort(diffs, nrows, sizeof(double), FnCompare_double); xnoise = (diffs[(nrows - 1)/2] + diffs[nrows/2]) / 2.; } *noise = .70710678 * xnoise; free(diffs); free(differences); return(*status); } /*--------------------------------------------------------------------------*/ static int FnNoise1_float (float *array, /* 2 dimensional array of image pixels */ long nx, /* number of pixels in each row of the image */ long ny, /* number of rows in the image */ int nullcheck, /* check for null values, if true */ float nullvalue, /* value of null pixels, if nullcheck is true */ /* returned parameters */ double *noise, /* returned R.M.S. value of all non-null pixels */ int *status) /* error status */ /* Estimate the background noise in the input image using sigma of 1st order differences. noise = 1.0 / sqrt(2) * rms of (flux[i] - flux[i-1]) The returned estimate is the median of the values that are computed for each row of the image. */ { int iter; long ii, jj, kk, nrows = 0, nvals; float *differences, *rowpix, v1; double *diffs, xnoise, mean, stdev; /* rows must have at least 3 pixels to estimate noise */ if (nx < 3) { *noise = 0; return(*status); } /* allocate arrays used to compute the median and noise estimates */ differences = calloc(nx, sizeof(float)); if (!differences) { *status = MEMORY_ALLOCATION; return(*status); } diffs = calloc(ny, sizeof(double)); if (!diffs) { free(differences); *status = MEMORY_ALLOCATION; return(*status); } /* loop over each row of the image */ for (jj=0; jj < ny; jj++) { rowpix = array + (jj * nx); /* point to first pixel in the row */ /***** find the first valid pixel in row */ ii = 0; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v1 = rowpix[ii]; /* store the good pixel value */ /* now continue populating the differences arrays */ /* for the remaining pixels in the row */ nvals = 0; for (ii++; ii < nx; ii++) { /* find the next valid pixel in row */ if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) break; /* hit end of row */ /* construct array of 1st order differences */ differences[nvals] = v1 - rowpix[ii]; nvals++; /* shift over 1 pixel */ v1 = rowpix[ii]; } /* end of loop over pixels in the row */ if (nvals < 2) continue; else { FnMeanSigma_float(differences, nvals, 0, 0, 0, &mean, &stdev, status); if (stdev > 0.) { for (iter = 0; iter < NITER; iter++) { kk = 0; for (ii = 0; ii < nvals; ii++) { if (fabs (differences[ii] - mean) < SIGMA_CLIP * stdev) { if (kk < ii) differences[kk] = differences[ii]; kk++; } } if (kk == nvals) break; nvals = kk; FnMeanSigma_float(differences, nvals, 0, 0, 0, &mean, &stdev, status); } } diffs[nrows] = stdev; nrows++; } } /* end of loop over rows */ /* compute median of the values for each row */ if (nrows == 0) { xnoise = 0; } else if (nrows == 1) { xnoise = diffs[0]; } else { qsort(diffs, nrows, sizeof(double), FnCompare_double); xnoise = (diffs[(nrows - 1)/2] + diffs[nrows/2]) / 2.; } *noise = .70710678 * xnoise; free(diffs); free(differences); return(*status); } /*--------------------------------------------------------------------------*/ static int FnNoise1_double (double *array, /* 2 dimensional array of image pixels */ long nx, /* number of pixels in each row of the image */ long ny, /* number of rows in the image */ int nullcheck, /* check for null values, if true */ double nullvalue, /* value of null pixels, if nullcheck is true */ /* returned parameters */ double *noise, /* returned R.M.S. value of all non-null pixels */ int *status) /* error status */ /* Estimate the background noise in the input image using sigma of 1st order differences. noise = 1.0 / sqrt(2) * rms of (flux[i] - flux[i-1]) The returned estimate is the median of the values that are computed for each row of the image. */ { int iter; long ii, jj, kk, nrows = 0, nvals; double *differences, *rowpix, v1; double *diffs, xnoise, mean, stdev; /* rows must have at least 3 pixels to estimate noise */ if (nx < 3) { *noise = 0; return(*status); } /* allocate arrays used to compute the median and noise estimates */ differences = calloc(nx, sizeof(double)); if (!differences) { *status = MEMORY_ALLOCATION; return(*status); } diffs = calloc(ny, sizeof(double)); if (!diffs) { free(differences); *status = MEMORY_ALLOCATION; return(*status); } /* loop over each row of the image */ for (jj=0; jj < ny; jj++) { rowpix = array + (jj * nx); /* point to first pixel in the row */ /***** find the first valid pixel in row */ ii = 0; if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) continue; /* hit end of row */ v1 = rowpix[ii]; /* store the good pixel value */ /* now continue populating the differences arrays */ /* for the remaining pixels in the row */ nvals = 0; for (ii++; ii < nx; ii++) { /* find the next valid pixel in row */ if (nullcheck) while (ii < nx && rowpix[ii] == nullvalue) ii++; if (ii == nx) break; /* hit end of row */ /* construct array of 1st order differences */ differences[nvals] = v1 - rowpix[ii]; nvals++; /* shift over 1 pixel */ v1 = rowpix[ii]; } /* end of loop over pixels in the row */ if (nvals < 2) continue; else { FnMeanSigma_double(differences, nvals, 0, 0, 0, &mean, &stdev, status); if (stdev > 0.) { for (iter = 0; iter < NITER; iter++) { kk = 0; for (ii = 0; ii < nvals; ii++) { if (fabs (differences[ii] - mean) < SIGMA_CLIP * stdev) { if (kk < ii) differences[kk] = differences[ii]; kk++; } } if (kk == nvals) break; nvals = kk; FnMeanSigma_double(differences, nvals, 0, 0, 0, &mean, &stdev, status); } } diffs[nrows] = stdev; nrows++; } } /* end of loop over rows */ /* compute median of the values for each row */ if (nrows == 0) { xnoise = 0; } else if (nrows == 1) { xnoise = diffs[0]; } else { qsort(diffs, nrows, sizeof(double), FnCompare_double); xnoise = (diffs[(nrows - 1)/2] + diffs[nrows/2]) / 2.; } *noise = .70710678 * xnoise; free(diffs); free(differences); return(*status); } /*--------------------------------------------------------------------------*/ static int FnCompare_short(const void *v1, const void *v2) { const short *i1 = v1; const short *i2 = v2; if (*i1 < *i2) return(-1); else if (*i1 > *i2) return(1); else return(0); } /*--------------------------------------------------------------------------*/ static int FnCompare_int(const void *v1, const void *v2) { const int *i1 = v1; const int *i2 = v2; if (*i1 < *i2) return(-1); else if (*i1 > *i2) return(1); else return(0); } /*--------------------------------------------------------------------------*/ static int FnCompare_float(const void *v1, const void *v2) { const float *i1 = v1; const float *i2 = v2; if (*i1 < *i2) return(-1); else if (*i1 > *i2) return(1); else return(0); } /*--------------------------------------------------------------------------*/ static int FnCompare_double(const void *v1, const void *v2) { const double *i1 = v1; const double *i2 = v2; if (*i1 < *i2) return(-1); else if (*i1 > *i2) return(1); else return(0); } /*--------------------------------------------------------------------------*/ /* * These Quickselect routines are based on the algorithm described in * "Numerical recipes in C", Second Edition, * Cambridge University Press, 1992, Section 8.5, ISBN 0-521-43108-5 * This code by Nicolas Devillard - 1998. Public domain. */ /*--------------------------------------------------------------------------*/ #define ELEM_SWAP(a,b) { register float t=(a);(a)=(b);(b)=t; } static float quick_select_float(float arr[], int n) { int low, high ; int median; int middle, ll, hh; low = 0 ; high = n-1 ; median = (low + high) / 2; for (;;) { if (high <= low) /* One element only */ return arr[median] ; if (high == low + 1) { /* Two elements only */ if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; return arr[median] ; } /* Find median of low, middle and high items; swap into position low */ middle = (low + high) / 2; if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]) ; if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]) ; /* Swap low item (now in position middle) into position (low+1) */ ELEM_SWAP(arr[middle], arr[low+1]) ; /* Nibble from each end towards middle, swapping items when stuck */ ll = low + 1; hh = high; for (;;) { do ll++; while (arr[low] > arr[ll]) ; do hh--; while (arr[hh] > arr[low]) ; if (hh < ll) break; ELEM_SWAP(arr[ll], arr[hh]) ; } /* Swap middle item (in position low) back into correct position */ ELEM_SWAP(arr[low], arr[hh]) ; /* Re-set active partition */ if (hh <= median) low = ll; if (hh >= median) high = hh - 1; } } #undef ELEM_SWAP /*--------------------------------------------------------------------------*/ #define ELEM_SWAP(a,b) { register short t=(a);(a)=(b);(b)=t; } static short quick_select_short(short arr[], int n) { int low, high ; int median; int middle, ll, hh; low = 0 ; high = n-1 ; median = (low + high) / 2; for (;;) { if (high <= low) /* One element only */ return arr[median] ; if (high == low + 1) { /* Two elements only */ if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; return arr[median] ; } /* Find median of low, middle and high items; swap into position low */ middle = (low + high) / 2; if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]) ; if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]) ; /* Swap low item (now in position middle) into position (low+1) */ ELEM_SWAP(arr[middle], arr[low+1]) ; /* Nibble from each end towards middle, swapping items when stuck */ ll = low + 1; hh = high; for (;;) { do ll++; while (arr[low] > arr[ll]) ; do hh--; while (arr[hh] > arr[low]) ; if (hh < ll) break; ELEM_SWAP(arr[ll], arr[hh]) ; } /* Swap middle item (in position low) back into correct position */ ELEM_SWAP(arr[low], arr[hh]) ; /* Re-set active partition */ if (hh <= median) low = ll; if (hh >= median) high = hh - 1; } } #undef ELEM_SWAP /*--------------------------------------------------------------------------*/ #define ELEM_SWAP(a,b) { register int t=(a);(a)=(b);(b)=t; } static int quick_select_int(int arr[], int n) { int low, high ; int median; int middle, ll, hh; low = 0 ; high = n-1 ; median = (low + high) / 2; for (;;) { if (high <= low) /* One element only */ return arr[median] ; if (high == low + 1) { /* Two elements only */ if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; return arr[median] ; } /* Find median of low, middle and high items; swap into position low */ middle = (low + high) / 2; if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]) ; if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]) ; /* Swap low item (now in position middle) into position (low+1) */ ELEM_SWAP(arr[middle], arr[low+1]) ; /* Nibble from each end towards middle, swapping items when stuck */ ll = low + 1; hh = high; for (;;) { do ll++; while (arr[low] > arr[ll]) ; do hh--; while (arr[hh] > arr[low]) ; if (hh < ll) break; ELEM_SWAP(arr[ll], arr[hh]) ; } /* Swap middle item (in position low) back into correct position */ ELEM_SWAP(arr[low], arr[hh]) ; /* Re-set active partition */ if (hh <= median) low = ll; if (hh >= median) high = hh - 1; } } #undef ELEM_SWAP /*--------------------------------------------------------------------------*/ #define ELEM_SWAP(a,b) { register LONGLONG t=(a);(a)=(b);(b)=t; } static LONGLONG quick_select_longlong(LONGLONG arr[], int n) { int low, high ; int median; int middle, ll, hh; low = 0 ; high = n-1 ; median = (low + high) / 2; for (;;) { if (high <= low) /* One element only */ return arr[median] ; if (high == low + 1) { /* Two elements only */ if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; return arr[median] ; } /* Find median of low, middle and high items; swap into position low */ middle = (low + high) / 2; if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]) ; if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]) ; /* Swap low item (now in position middle) into position (low+1) */ ELEM_SWAP(arr[middle], arr[low+1]) ; /* Nibble from each end towards middle, swapping items when stuck */ ll = low + 1; hh = high; for (;;) { do ll++; while (arr[low] > arr[ll]) ; do hh--; while (arr[hh] > arr[low]) ; if (hh < ll) break; ELEM_SWAP(arr[ll], arr[hh]) ; } /* Swap middle item (in position low) back into correct position */ ELEM_SWAP(arr[low], arr[hh]) ; /* Re-set active partition */ if (hh <= median) low = ll; if (hh >= median) high = hh - 1; } } #undef ELEM_SWAP /*--------------------------------------------------------------------------*/ #define ELEM_SWAP(a,b) { register double t=(a);(a)=(b);(b)=t; } static double quick_select_double(double arr[], int n) { int low, high ; int median; int middle, ll, hh; low = 0 ; high = n-1 ; median = (low + high) / 2; for (;;) { if (high <= low) /* One element only */ return arr[median] ; if (high == low + 1) { /* Two elements only */ if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; return arr[median] ; } /* Find median of low, middle and high items; swap into position low */ middle = (low + high) / 2; if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]) ; if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]) ; /* Swap low item (now in position middle) into position (low+1) */ ELEM_SWAP(arr[middle], arr[low+1]) ; /* Nibble from each end towards middle, swapping items when stuck */ ll = low + 1; hh = high; for (;;) { do ll++; while (arr[low] > arr[ll]) ; do hh--; while (arr[hh] > arr[low]) ; if (hh < ll) break; ELEM_SWAP(arr[ll], arr[hh]) ; } /* Swap middle item (in position low) back into correct position */ ELEM_SWAP(arr[low], arr[hh]) ; /* Re-set active partition */ if (hh <= median) low = ll; if (hh >= median) high = hh - 1; } } #undef ELEM_SWAP ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/region.c0000644000175100001710000016003700000000000017561 0ustar00vstsdocker#include #include #include #include #include #include "fitsio2.h" #include "region.h" static int Pt_in_Poly( double x, double y, int nPts, double *Pts ); /*---------------------------------------------------------------------------*/ int fits_read_rgnfile( const char *filename, WCSdata *wcs, SAORegion **Rgn, int *status ) /* Read regions from either a FITS or ASCII region file and return the information */ /* in the "SAORegion" structure. If it is nonNULL, use wcs to convert the */ /* region coordinates to pixels. Return an error if region is in degrees */ /* but no WCS data is provided. */ /*---------------------------------------------------------------------------*/ { fitsfile *fptr; int tstatus = 0; if( *status ) return( *status ); /* try to open as a FITS file - if that doesn't work treat as an ASCII file */ fits_write_errmark(); if ( ffopen(&fptr, filename, READONLY, &tstatus) ) { fits_clear_errmark(); fits_read_ascii_region(filename, wcs, Rgn, status); } else { fits_read_fits_region(fptr, wcs, Rgn, status); } return(*status); } /*---------------------------------------------------------------------------*/ int fits_read_ascii_region( const char *filename, WCSdata *wcs, SAORegion **Rgn, int *status ) /* Read regions from a SAO-style region file and return the information */ /* in the "SAORegion" structure. If it is nonNULL, use wcs to convert the */ /* region coordinates to pixels. Return an error if region is in degrees */ /* but no WCS data is provided. */ /*---------------------------------------------------------------------------*/ { char *currLine; char *namePtr, *paramPtr, *currLoc; char *pX, *pY, *endp; long allocLen, lineLen, hh, mm, dd; double *coords, X, Y, x, y, ss, div, xsave= 0., ysave= 0.; int nParams, nCoords, negdec; int i, done; FILE *rgnFile; coordFmt cFmt; SAORegion *aRgn; RgnShape *newShape, *tmpShape; if( *status ) return( *status ); aRgn = (SAORegion *)malloc( sizeof(SAORegion) ); if( ! aRgn ) { ffpmsg("Couldn't allocate memory to hold Region file contents."); return(*status = MEMORY_ALLOCATION ); } aRgn->nShapes = 0; aRgn->Shapes = NULL; if( wcs && wcs->exists ) aRgn->wcs = *wcs; else aRgn->wcs.exists = 0; cFmt = pixel_fmt; /* set default format */ /* Allocate Line Buffer */ allocLen = 512; currLine = (char *)malloc( allocLen * sizeof(char) ); if( !currLine ) { free( aRgn ); ffpmsg("Couldn't allocate memory to hold Region file contents."); return(*status = MEMORY_ALLOCATION ); } /* Open Region File */ if( (rgnFile = fopen( filename, "r" ))==NULL ) { snprintf(currLine,allocLen,"Could not open Region file %s.",filename); ffpmsg( currLine ); free( currLine ); free( aRgn ); return( *status = FILE_NOT_OPENED ); } /* Read in file, line by line */ /* First, set error status in case file is empty */ *status = FILE_NOT_OPENED; while( fgets(currLine,allocLen,rgnFile) != NULL ) { /* reset status if we got here */ *status = 0; /* Make sure we have a full line of text */ lineLen = strlen(currLine); while( lineLen==allocLen-1 && currLine[lineLen-1]!='\n' ) { currLoc = (char *)realloc( currLine, 2 * allocLen * sizeof(char) ); if( !currLoc ) { ffpmsg("Couldn't allocate memory to hold Region file contents."); *status = MEMORY_ALLOCATION; goto error; } else { currLine = currLoc; } fgets( currLine+lineLen, allocLen+1, rgnFile ); allocLen += allocLen; lineLen += strlen(currLine+lineLen); } currLoc = currLine; if( *currLoc == '#' ) { /* Look to see if it is followed by a format statement... */ /* if not skip line */ currLoc++; while( isspace(*currLoc) ) currLoc++; if( !fits_strncasecmp( currLoc, "format:", 7 ) ) { if( aRgn->nShapes ) { ffpmsg("Format code encountered after reading 1 or more shapes."); *status = PARSE_SYNTAX_ERR; goto error; } currLoc += 7; while( isspace(*currLoc) ) currLoc++; if( !fits_strncasecmp( currLoc, "pixel", 5 ) ) { cFmt = pixel_fmt; } else if( !fits_strncasecmp( currLoc, "degree", 6 ) ) { cFmt = degree_fmt; } else if( !fits_strncasecmp( currLoc, "hhmmss", 6 ) ) { cFmt = hhmmss_fmt; } else if( !fits_strncasecmp( currLoc, "hms", 3 ) ) { cFmt = hhmmss_fmt; } else { ffpmsg("Unknown format code encountered in region file."); *status = PARSE_SYNTAX_ERR; goto error; } } } else if( !fits_strncasecmp( currLoc, "glob", 4 ) ) { /* skip lines that begin with the word 'global' */ } else { while( *currLoc != '\0' ) { namePtr = currLoc; paramPtr = NULL; nParams = 1; /* Search for closing parenthesis */ done = 0; while( !done && !*status && *currLoc ) { switch (*currLoc) { case '(': *currLoc = '\0'; currLoc++; if( paramPtr ) /* Can't have two '(' in a region! */ *status = 1; else paramPtr = currLoc; break; case ')': *currLoc = '\0'; currLoc++; if( !paramPtr ) /* Can't have a ')' without a '(' first */ *status = 1; else done = 1; break; case '#': case '\n': *currLoc = '\0'; if( !paramPtr ) /* Allow for a blank line */ done = 1; break; case ':': currLoc++; if ( paramPtr ) cFmt = hhmmss_fmt; /* set format if parameter has : */ break; case 'd': currLoc++; if ( paramPtr ) cFmt = degree_fmt; /* set format if parameter has d */ break; case ',': nParams++; /* Fall through to default */ default: currLoc++; break; } } if( *status || !done ) { ffpmsg( "Error reading Region file" ); *status = PARSE_SYNTAX_ERR; goto error; } /* Skip white space in region name */ while( isspace(*namePtr) ) namePtr++; /* Was this a blank line? Or the end of the current one */ if( ! *namePtr && ! paramPtr ) continue; /* Check for format code at beginning of the line */ if( !fits_strncasecmp( namePtr, "image;", 6 ) ) { namePtr += 6; cFmt = pixel_fmt; } else if( !fits_strncasecmp( namePtr, "physical;", 9 ) ) { namePtr += 9; cFmt = pixel_fmt; } else if( !fits_strncasecmp( namePtr, "linear;", 7 ) ) { namePtr += 7; cFmt = pixel_fmt; } else if( !fits_strncasecmp( namePtr, "fk4;", 4 ) ) { namePtr += 4; cFmt = degree_fmt; } else if( !fits_strncasecmp( namePtr, "fk5;", 4 ) ) { namePtr += 4; cFmt = degree_fmt; } else if( !fits_strncasecmp( namePtr, "icrs;", 5 ) ) { namePtr += 5; cFmt = degree_fmt; /* the following 5 cases support region files created by POW (or ds9 Version 4.x) which may have lines containing only a format code, not followed by a ';' (and with no region specifier on the line). We use the 'continue' statement to jump to the end of the loop and then continue reading the next line of the region file. */ } else if( !fits_strncasecmp( namePtr, "fk5", 3 ) ) { cFmt = degree_fmt; continue; /* supports POW region file format */ } else if( !fits_strncasecmp( namePtr, "fk4", 3 ) ) { cFmt = degree_fmt; continue; /* supports POW region file format */ } else if( !fits_strncasecmp( namePtr, "icrs", 4 ) ) { cFmt = degree_fmt; continue; /* supports POW region file format */ } else if( !fits_strncasecmp( namePtr, "image", 5 ) ) { cFmt = pixel_fmt; continue; /* supports POW region file format */ } else if( !fits_strncasecmp( namePtr, "physical", 8 ) ) { cFmt = pixel_fmt; continue; /* supports POW region file format */ } else if( !fits_strncasecmp( namePtr, "galactic;", 9 ) ) { ffpmsg( "Galactic region coordinates not supported" ); ffpmsg( namePtr ); *status = PARSE_SYNTAX_ERR; goto error; } else if( !fits_strncasecmp( namePtr, "ecliptic;", 9 ) ) { ffpmsg( "ecliptic region coordinates not supported" ); ffpmsg( namePtr ); *status = PARSE_SYNTAX_ERR; goto error; } /**************************************************/ /* We've apparently found a region... Set it up */ /**************************************************/ if( !(aRgn->nShapes % 10) ) { if( aRgn->Shapes ) tmpShape = (RgnShape *)realloc( aRgn->Shapes, (10+aRgn->nShapes) * sizeof(RgnShape) ); else tmpShape = (RgnShape *) malloc( 10 * sizeof(RgnShape) ); if( tmpShape ) { aRgn->Shapes = tmpShape; } else { ffpmsg( "Failed to allocate memory for Region data"); *status = MEMORY_ALLOCATION; goto error; } } newShape = &aRgn->Shapes[aRgn->nShapes++]; newShape->sign = 1; newShape->shape = point_rgn; for (i=0; i<8; i++) newShape->param.gen.p[i] = 0.0; newShape->param.gen.a = 0.0; newShape->param.gen.b = 0.0; newShape->param.gen.sinT = 0.0; newShape->param.gen.cosT = 0.0; while( isspace(*namePtr) ) namePtr++; /* Check for the shape's sign */ if( *namePtr=='+' ) { namePtr++; } else if( *namePtr=='-' ) { namePtr++; newShape->sign = 0; } /* Skip white space in region name */ while( isspace(*namePtr) ) namePtr++; if( *namePtr=='\0' ) { ffpmsg( "Error reading Region file" ); *status = PARSE_SYNTAX_ERR; goto error; } lineLen = strlen( namePtr ) - 1; while( isspace(namePtr[lineLen]) ) namePtr[lineLen--] = '\0'; /* Now identify the region */ if( !fits_strcasecmp( namePtr, "circle" ) ) { newShape->shape = circle_rgn; if( nParams != 3 ) *status = PARSE_SYNTAX_ERR; nCoords = 2; } else if( !fits_strcasecmp( namePtr, "annulus" ) ) { newShape->shape = annulus_rgn; if( nParams != 4 ) *status = PARSE_SYNTAX_ERR; nCoords = 2; } else if( !fits_strcasecmp( namePtr, "ellipse" ) ) { if( nParams < 4 || nParams > 8 ) { *status = PARSE_SYNTAX_ERR; } else if ( nParams < 6 ) { newShape->shape = ellipse_rgn; newShape->param.gen.p[4] = 0.0; } else { newShape->shape = elliptannulus_rgn; newShape->param.gen.p[6] = 0.0; newShape->param.gen.p[7] = 0.0; } nCoords = 2; } else if( !fits_strcasecmp( namePtr, "elliptannulus" ) ) { newShape->shape = elliptannulus_rgn; if( !( nParams==8 || nParams==6 ) ) *status = PARSE_SYNTAX_ERR; newShape->param.gen.p[6] = 0.0; newShape->param.gen.p[7] = 0.0; nCoords = 2; } else if( !fits_strcasecmp( namePtr, "box" ) || !fits_strcasecmp( namePtr, "rotbox" ) ) { if( nParams < 4 || nParams > 8 ) { *status = PARSE_SYNTAX_ERR; } else if ( nParams < 6 ) { newShape->shape = box_rgn; newShape->param.gen.p[4] = 0.0; } else { newShape->shape = boxannulus_rgn; newShape->param.gen.p[6] = 0.0; newShape->param.gen.p[7] = 0.0; } nCoords = 2; } else if( !fits_strcasecmp( namePtr, "rectangle" ) || !fits_strcasecmp( namePtr, "rotrectangle" ) ) { newShape->shape = rectangle_rgn; if( nParams < 4 || nParams > 5 ) *status = PARSE_SYNTAX_ERR; newShape->param.gen.p[4] = 0.0; nCoords = 4; } else if( !fits_strcasecmp( namePtr, "diamond" ) || !fits_strcasecmp( namePtr, "rotdiamond" ) || !fits_strcasecmp( namePtr, "rhombus" ) || !fits_strcasecmp( namePtr, "rotrhombus" ) ) { newShape->shape = diamond_rgn; if( nParams < 4 || nParams > 5 ) *status = PARSE_SYNTAX_ERR; newShape->param.gen.p[4] = 0.0; nCoords = 2; } else if( !fits_strcasecmp( namePtr, "sector" ) || !fits_strcasecmp( namePtr, "pie" ) ) { newShape->shape = sector_rgn; if( nParams != 4 ) *status = PARSE_SYNTAX_ERR; nCoords = 2; } else if( !fits_strcasecmp( namePtr, "point" ) ) { newShape->shape = point_rgn; if( nParams != 2 ) *status = PARSE_SYNTAX_ERR; nCoords = 2; } else if( !fits_strcasecmp( namePtr, "line" ) ) { newShape->shape = line_rgn; if( nParams != 4 ) *status = PARSE_SYNTAX_ERR; nCoords = 4; } else if( !fits_strcasecmp( namePtr, "polygon" ) ) { newShape->shape = poly_rgn; if( nParams < 6 || (nParams&1) ) *status = PARSE_SYNTAX_ERR; nCoords = nParams; } else if( !fits_strcasecmp( namePtr, "panda" ) ) { newShape->shape = panda_rgn; if( nParams != 8 ) *status = PARSE_SYNTAX_ERR; nCoords = 2; } else if( !fits_strcasecmp( namePtr, "epanda" ) ) { newShape->shape = epanda_rgn; if( nParams < 10 || nParams > 11 ) *status = PARSE_SYNTAX_ERR; newShape->param.gen.p[10] = 0.0; nCoords = 2; } else if( !fits_strcasecmp( namePtr, "bpanda" ) ) { newShape->shape = bpanda_rgn; if( nParams < 10 || nParams > 11 ) *status = PARSE_SYNTAX_ERR; newShape->param.gen.p[10] = 0.0; nCoords = 2; } else { ffpmsg( "Unrecognized region found in region file:" ); ffpmsg( namePtr ); *status = PARSE_SYNTAX_ERR; goto error; } if( *status ) { ffpmsg( "Wrong number of parameters found for region" ); ffpmsg( namePtr ); goto error; } /* Parse Parameter string... convert to pixels if necessary */ if( newShape->shape==poly_rgn ) { newShape->param.poly.Pts = (double *)malloc( nParams * sizeof(double) ); if( !newShape->param.poly.Pts ) { ffpmsg( "Could not allocate memory to hold polygon parameters" ); *status = MEMORY_ALLOCATION; goto error; } newShape->param.poly.nPts = nParams; coords = newShape->param.poly.Pts; } else coords = newShape->param.gen.p; /* Parse the initial "WCS?" coordinates */ for( i=0; iexists ) { ffpmsg("WCS information needed to convert region coordinates."); *status = NO_WCS_KEY; goto error; } if( ffxypx( X, Y, wcs->xrefval, wcs->yrefval, wcs->xrefpix, wcs->yrefpix, wcs->xinc, wcs->yinc, wcs->rot, wcs->type, &x, &y, status ) ) { ffpmsg("Error converting region to pixel coordinates."); goto error; } X = x; Y = y; } coords[i] = X; coords[i+1] = Y; } /* Read in remaining parameters... */ for( ; ixrefval, wcs->yrefval, wcs->xrefpix, wcs->yrefpix, wcs->xinc, wcs->yinc, wcs->rot, wcs->type, &x, &y, status ) ) { ffpmsg("Error converting region to pixel coordinates."); goto error; } coords[i] = sqrt( pow(x-coords[0],2) + pow(y-coords[1],2) ); } } /* special case for elliptannulus and boxannulus if only one angle was given */ if ( (newShape->shape == elliptannulus_rgn || newShape->shape == boxannulus_rgn ) && nParams == 7 ) { coords[7] = coords[6]; } /* Also, correct the position angle for any WCS rotation: */ /* If regions are specified in WCS coordintes, then the angles */ /* are relative to the WCS system, not the pixel X,Y system */ if( cFmt!=pixel_fmt ) { switch( newShape->shape ) { case sector_rgn: case panda_rgn: coords[2] += (wcs->rot); coords[3] += (wcs->rot); break; case box_rgn: case rectangle_rgn: case diamond_rgn: case ellipse_rgn: coords[4] += (wcs->rot); break; case boxannulus_rgn: case elliptannulus_rgn: coords[6] += (wcs->rot); coords[7] += (wcs->rot); break; case epanda_rgn: case bpanda_rgn: coords[2] += (wcs->rot); coords[3] += (wcs->rot); coords[10] += (wcs->rot); default: break; } } /* do some precalculations to speed up tests */ fits_setup_shape(newShape); } /* End of while( *currLoc ) */ /* if (coords)printf("%.8f %.8f %.8f %.8f %.8f\n", coords[0],coords[1],coords[2],coords[3],coords[4]); */ } /* End of if...else parse line */ } /* End of while( fgets(rgnFile) ) */ /* set up component numbers */ fits_set_region_components( aRgn ); error: if( *status ) { fits_free_region( aRgn ); } else { *Rgn = aRgn; } fclose( rgnFile ); free( currLine ); return( *status ); } /*---------------------------------------------------------------------------*/ int fits_in_region( double X, double Y, SAORegion *Rgn ) /* Test if the given point is within the region described by Rgn. X and */ /* Y are in pixel coordinates. */ /*---------------------------------------------------------------------------*/ { double x, y, dx, dy, xprime, yprime, r, th; RgnShape *Shapes; int i, cur_comp; int result, comp_result; Shapes = Rgn->Shapes; result = 0; comp_result = 0; cur_comp = Rgn->Shapes[0].comp; for( i=0; inShapes; i++, Shapes++ ) { /* if this region has a different component number to the last one */ /* then replace the accumulated selection logical with the union of */ /* the current logical and the total logical. Reinitialize the */ /* temporary logical. */ if ( i==0 || Shapes->comp != cur_comp ) { result = result || comp_result; cur_comp = Shapes->comp; /* if an excluded region is given first, then implicitly */ /* assume a previous shape that includes the entire image. */ comp_result = !Shapes->sign; } /* only need to test if */ /* the point is not already included and this is an include region, */ /* or the point is included and this is an excluded region */ if ( (!comp_result && Shapes->sign) || (comp_result && !Shapes->sign) ) { comp_result = 1; switch( Shapes->shape ) { case box_rgn: /* Shift origin to center of region */ xprime = X - Shapes->param.gen.p[0]; yprime = Y - Shapes->param.gen.p[1]; /* Rotate point to region's orientation */ x = xprime * Shapes->param.gen.cosT + yprime * Shapes->param.gen.sinT; y = -xprime * Shapes->param.gen.sinT + yprime * Shapes->param.gen.cosT; dx = 0.5 * Shapes->param.gen.p[2]; dy = 0.5 * Shapes->param.gen.p[3]; if( (x < -dx) || (x > dx) || (y < -dy) || (y > dy) ) comp_result = 0; break; case boxannulus_rgn: /* Shift origin to center of region */ xprime = X - Shapes->param.gen.p[0]; yprime = Y - Shapes->param.gen.p[1]; /* Rotate point to region's orientation */ x = xprime * Shapes->param.gen.cosT + yprime * Shapes->param.gen.sinT; y = -xprime * Shapes->param.gen.sinT + yprime * Shapes->param.gen.cosT; dx = 0.5 * Shapes->param.gen.p[4]; dy = 0.5 * Shapes->param.gen.p[5]; if( (x < -dx) || (x > dx) || (y < -dy) || (y > dy) ) { comp_result = 0; } else { /* Repeat test for inner box */ x = xprime * Shapes->param.gen.b + yprime * Shapes->param.gen.a; y = -xprime * Shapes->param.gen.a + yprime * Shapes->param.gen.b; dx = 0.5 * Shapes->param.gen.p[2]; dy = 0.5 * Shapes->param.gen.p[3]; if( (x >= -dx) && (x <= dx) && (y >= -dy) && (y <= dy) ) comp_result = 0; } break; case rectangle_rgn: /* Shift origin to center of region */ xprime = X - Shapes->param.gen.p[5]; yprime = Y - Shapes->param.gen.p[6]; /* Rotate point to region's orientation */ x = xprime * Shapes->param.gen.cosT + yprime * Shapes->param.gen.sinT; y = -xprime * Shapes->param.gen.sinT + yprime * Shapes->param.gen.cosT; dx = Shapes->param.gen.a; dy = Shapes->param.gen.b; if( (x < -dx) || (x > dx) || (y < -dy) || (y > dy) ) comp_result = 0; break; case diamond_rgn: /* Shift origin to center of region */ xprime = X - Shapes->param.gen.p[0]; yprime = Y - Shapes->param.gen.p[1]; /* Rotate point to region's orientation */ x = xprime * Shapes->param.gen.cosT + yprime * Shapes->param.gen.sinT; y = -xprime * Shapes->param.gen.sinT + yprime * Shapes->param.gen.cosT; dx = 0.5 * Shapes->param.gen.p[2]; dy = 0.5 * Shapes->param.gen.p[3]; r = fabs(x/dx) + fabs(y/dy); if( r > 1 ) comp_result = 0; break; case circle_rgn: /* Shift origin to center of region */ x = X - Shapes->param.gen.p[0]; y = Y - Shapes->param.gen.p[1]; r = x*x + y*y; if ( r > Shapes->param.gen.a ) comp_result = 0; break; case annulus_rgn: /* Shift origin to center of region */ x = X - Shapes->param.gen.p[0]; y = Y - Shapes->param.gen.p[1]; r = x*x + y*y; if ( r < Shapes->param.gen.a || r > Shapes->param.gen.b ) comp_result = 0; break; case sector_rgn: /* Shift origin to center of region */ x = X - Shapes->param.gen.p[0]; y = Y - Shapes->param.gen.p[1]; if( x || y ) { r = atan2( y, x ) * RadToDeg; if( Shapes->param.gen.p[2] <= Shapes->param.gen.p[3] ) { if( r < Shapes->param.gen.p[2] || r > Shapes->param.gen.p[3] ) comp_result = 0; } else { if( r < Shapes->param.gen.p[2] && r > Shapes->param.gen.p[3] ) comp_result = 0; } } break; case ellipse_rgn: /* Shift origin to center of region */ xprime = X - Shapes->param.gen.p[0]; yprime = Y - Shapes->param.gen.p[1]; /* Rotate point to region's orientation */ x = xprime * Shapes->param.gen.cosT + yprime * Shapes->param.gen.sinT; y = -xprime * Shapes->param.gen.sinT + yprime * Shapes->param.gen.cosT; x /= Shapes->param.gen.p[2]; y /= Shapes->param.gen.p[3]; r = x*x + y*y; if( r>1.0 ) comp_result = 0; break; case elliptannulus_rgn: /* Shift origin to center of region */ xprime = X - Shapes->param.gen.p[0]; yprime = Y - Shapes->param.gen.p[1]; /* Rotate point to outer ellipse's orientation */ x = xprime * Shapes->param.gen.cosT + yprime * Shapes->param.gen.sinT; y = -xprime * Shapes->param.gen.sinT + yprime * Shapes->param.gen.cosT; x /= Shapes->param.gen.p[4]; y /= Shapes->param.gen.p[5]; r = x*x + y*y; if( r>1.0 ) comp_result = 0; else { /* Repeat test for inner ellipse */ x = xprime * Shapes->param.gen.b + yprime * Shapes->param.gen.a; y = -xprime * Shapes->param.gen.a + yprime * Shapes->param.gen.b; x /= Shapes->param.gen.p[2]; y /= Shapes->param.gen.p[3]; r = x*x + y*y; if( r<1.0 ) comp_result = 0; } break; case line_rgn: /* Shift origin to first point of line */ xprime = X - Shapes->param.gen.p[0]; yprime = Y - Shapes->param.gen.p[1]; /* Rotate point to line's orientation */ x = xprime * Shapes->param.gen.cosT + yprime * Shapes->param.gen.sinT; y = -xprime * Shapes->param.gen.sinT + yprime * Shapes->param.gen.cosT; if( (y < -0.5) || (y >= 0.5) || (x < -0.5) || (x >= Shapes->param.gen.a) ) comp_result = 0; break; case point_rgn: /* Shift origin to center of region */ x = X - Shapes->param.gen.p[0]; y = Y - Shapes->param.gen.p[1]; if ( (x<-0.5) || (x>=0.5) || (y<-0.5) || (y>=0.5) ) comp_result = 0; break; case poly_rgn: if( Xxmin || X>Shapes->xmax || Yymin || Y>Shapes->ymax ) comp_result = 0; else comp_result = Pt_in_Poly( X, Y, Shapes->param.poly.nPts, Shapes->param.poly.Pts ); break; case panda_rgn: /* Shift origin to center of region */ x = X - Shapes->param.gen.p[0]; y = Y - Shapes->param.gen.p[1]; r = x*x + y*y; if ( r < Shapes->param.gen.a || r > Shapes->param.gen.b ) { comp_result = 0; } else { if( x || y ) { th = atan2( y, x ) * RadToDeg; if( Shapes->param.gen.p[2] <= Shapes->param.gen.p[3] ) { if( th < Shapes->param.gen.p[2] || th > Shapes->param.gen.p[3] ) comp_result = 0; } else { if( th < Shapes->param.gen.p[2] && th > Shapes->param.gen.p[3] ) comp_result = 0; } } } break; case epanda_rgn: /* Shift origin to center of region */ xprime = X - Shapes->param.gen.p[0]; yprime = Y - Shapes->param.gen.p[1]; /* Rotate point to region's orientation */ x = xprime * Shapes->param.gen.cosT + yprime * Shapes->param.gen.sinT; y = -xprime * Shapes->param.gen.sinT + yprime * Shapes->param.gen.cosT; xprime = x; yprime = y; /* outer region test */ x = xprime/Shapes->param.gen.p[7]; y = yprime/Shapes->param.gen.p[8]; r = x*x + y*y; if ( r>1.0 ) comp_result = 0; else { /* inner region test */ x = xprime/Shapes->param.gen.p[5]; y = yprime/Shapes->param.gen.p[6]; r = x*x + y*y; if ( r<1.0 ) comp_result = 0; else { /* angle test */ if( xprime || yprime ) { th = atan2( yprime, xprime ) * RadToDeg; if( Shapes->param.gen.p[2] <= Shapes->param.gen.p[3] ) { if( th < Shapes->param.gen.p[2] || th > Shapes->param.gen.p[3] ) comp_result = 0; } else { if( th < Shapes->param.gen.p[2] && th > Shapes->param.gen.p[3] ) comp_result = 0; } } } } break; case bpanda_rgn: /* Shift origin to center of region */ xprime = X - Shapes->param.gen.p[0]; yprime = Y - Shapes->param.gen.p[1]; /* Rotate point to region's orientation */ x = xprime * Shapes->param.gen.cosT + yprime * Shapes->param.gen.sinT; y = -xprime * Shapes->param.gen.sinT + yprime * Shapes->param.gen.cosT; /* outer box test */ dx = 0.5 * Shapes->param.gen.p[7]; dy = 0.5 * Shapes->param.gen.p[8]; if( (x < -dx) || (x > dx) || (y < -dy) || (y > dy) ) comp_result = 0; else { /* inner box test */ dx = 0.5 * Shapes->param.gen.p[5]; dy = 0.5 * Shapes->param.gen.p[6]; if( (x >= -dx) && (x <= dx) && (y >= -dy) && (y <= dy) ) comp_result = 0; else { /* angle test */ if( x || y ) { th = atan2( y, x ) * RadToDeg; if( Shapes->param.gen.p[2] <= Shapes->param.gen.p[3] ) { if( th < Shapes->param.gen.p[2] || th > Shapes->param.gen.p[3] ) comp_result = 0; } else { if( th < Shapes->param.gen.p[2] && th > Shapes->param.gen.p[3] ) comp_result = 0; } } } } break; } if( !Shapes->sign ) comp_result = !comp_result; } } result = result || comp_result; return( result ); } /*---------------------------------------------------------------------------*/ void fits_free_region( SAORegion *Rgn ) /* Free up memory allocated to hold the region data. This is more complicated for the case of polygons, which may be sharing points arrays due to shallow copying (in fits_set_region_components) of 'exluded' regions. We must ensure that these arrays are only freed once. /*---------------------------------------------------------------------------*/ { int i,j; int nFreedPoly=0; int nPolyArraySize=10; double **freedPolyPtrs=0; double *ptsToFree=0; int isAlreadyFreed=0; freedPolyPtrs = (double**)malloc(nPolyArraySize*sizeof(double*)); for( i=0; inShapes; i++ ) if( Rgn->Shapes[i].shape == poly_rgn ) { /* No shared arrays for 'include' polygons */ if (Rgn->Shapes[i].sign) free(Rgn->Shapes[i].param.poly.Pts); else { ptsToFree = Rgn->Shapes[i].param.poly.Pts; isAlreadyFreed = 0; for (j=0; jShapes ) free( Rgn->Shapes ); free( Rgn ); free(freedPolyPtrs); } /*---------------------------------------------------------------------------*/ static int Pt_in_Poly( double x, double y, int nPts, double *Pts ) /* Internal routine for testing whether the coordinate x,y is within the */ /* polygon region traced out by the array Pts. */ /*---------------------------------------------------------------------------*/ { int i, j, flag=0; double prevX, prevY; double nextX, nextY; double dx, dy, Dy; nextX = Pts[nPts-2]; nextY = Pts[nPts-1]; for( i=0; iprevY && y>=nextY) || (yprevX && x>=nextX) ) continue; /* Check to see if x,y lies right on the segment */ if( x>=prevX || x>nextX ) { dy = y - prevY; Dy = nextY - prevY; if( fabs(Dy)<1e-10 ) { if( fabs(dy)<1e-10 ) return( 1 ); else continue; } dx = prevX + ( (nextX-prevX)/(Dy) ) * dy - x; if( dx < -1e-10 ) continue; if( dx < 1e-10 ) return( 1 ); } /* There is an intersection! Make sure it isn't a V point. */ if( y != prevY ) { flag = 1 - flag; } else { j = i+1; /* Point to Y component */ do { if( j>1 ) j -= 2; else j = nPts-1; } while( y == Pts[j] ); if( (nextY-y)*(y-Pts[j]) > 0 ) flag = 1-flag; } } return( flag ); } /*---------------------------------------------------------------------------*/ void fits_set_region_components ( SAORegion *aRgn ) { /* Internal routine to turn a collection of regions read from an ascii file into the more complex structure that is allowed by the FITS REGION extension with multiple components. Regions are anded within components and ored between them ie for a pixel to be selected it must be selected by at least one component and to be selected by a component it must be selected by all that component's shapes. The algorithm is to replicate every exclude region after every include region before it in the list. eg reg1, reg2, -reg3, reg4, -reg5 becomes (reg1, -reg3, -reg5), (reg2, -reg5, -reg3), (reg4, -reg5) where the parentheses designate components. */ int i, j, k, icomp; /* loop round shapes */ i = 0; while ( inShapes ) { /* first do the case of an exclude region */ if ( !aRgn->Shapes[i].sign ) { /* we need to run back through the list copying the current shape as required. start by findin the first include shape before this exclude */ j = i-1; while ( j > 0 && !aRgn->Shapes[j].sign ) j--; /* then go back one more shape */ j--; /* and loop back through the regions */ while ( j >= 0 ) { /* if this is an include region then insert a copy of the exclude region immediately after it */ /* Note that this makes shallow copies of a polygon's dynamically allocated Pts array -- the memory is shared. This must be checked when freeing in fits_free_region. */ if ( aRgn->Shapes[j].sign ) { aRgn->Shapes = (RgnShape *) realloc (aRgn->Shapes,(1+aRgn->nShapes)*sizeof(RgnShape)); aRgn->nShapes++; for (k=aRgn->nShapes-1; k>j+1; k--) aRgn->Shapes[k] = aRgn->Shapes[k-1]; i++; aRgn->Shapes[j+1] = aRgn->Shapes[i]; } j--; } } i++; } /* now set the component numbers */ icomp = 0; for ( i=0; inShapes; i++ ) { if ( aRgn->Shapes[i].sign ) icomp++; aRgn->Shapes[i].comp = icomp; /* printf("i = %d, shape = %d, sign = %d, comp = %d\n", i, aRgn->Shapes[i].shape, aRgn->Shapes[i].sign, aRgn->Shapes[i].comp); */ } return; } /*---------------------------------------------------------------------------*/ void fits_setup_shape ( RgnShape *newShape) { /* Perform some useful calculations now to speed up filter later */ double X, Y, R; double *coords; int i; if ( newShape->shape == poly_rgn ) { coords = newShape->param.poly.Pts; } else { coords = newShape->param.gen.p; } switch( newShape->shape ) { case circle_rgn: newShape->param.gen.a = coords[2] * coords[2]; break; case annulus_rgn: newShape->param.gen.a = coords[2] * coords[2]; newShape->param.gen.b = coords[3] * coords[3]; break; case sector_rgn: while( coords[2]> 180.0 ) coords[2] -= 360.0; while( coords[2]<=-180.0 ) coords[2] += 360.0; while( coords[3]> 180.0 ) coords[3] -= 360.0; while( coords[3]<=-180.0 ) coords[3] += 360.0; break; case ellipse_rgn: newShape->param.gen.sinT = sin( myPI * (coords[4] / 180.0) ); newShape->param.gen.cosT = cos( myPI * (coords[4] / 180.0) ); break; case elliptannulus_rgn: newShape->param.gen.a = sin( myPI * (coords[6] / 180.0) ); newShape->param.gen.b = cos( myPI * (coords[6] / 180.0) ); newShape->param.gen.sinT = sin( myPI * (coords[7] / 180.0) ); newShape->param.gen.cosT = cos( myPI * (coords[7] / 180.0) ); break; case box_rgn: newShape->param.gen.sinT = sin( myPI * (coords[4] / 180.0) ); newShape->param.gen.cosT = cos( myPI * (coords[4] / 180.0) ); break; case boxannulus_rgn: newShape->param.gen.a = sin( myPI * (coords[6] / 180.0) ); newShape->param.gen.b = cos( myPI * (coords[6] / 180.0) ); newShape->param.gen.sinT = sin( myPI * (coords[7] / 180.0) ); newShape->param.gen.cosT = cos( myPI * (coords[7] / 180.0) ); break; case rectangle_rgn: newShape->param.gen.sinT = sin( myPI * (coords[4] / 180.0) ); newShape->param.gen.cosT = cos( myPI * (coords[4] / 180.0) ); X = 0.5 * ( coords[2]-coords[0] ); Y = 0.5 * ( coords[3]-coords[1] ); newShape->param.gen.a = fabs( X * newShape->param.gen.cosT + Y * newShape->param.gen.sinT ); newShape->param.gen.b = fabs( Y * newShape->param.gen.cosT - X * newShape->param.gen.sinT ); newShape->param.gen.p[5] = 0.5 * ( coords[2]+coords[0] ); newShape->param.gen.p[6] = 0.5 * ( coords[3]+coords[1] ); break; case diamond_rgn: newShape->param.gen.sinT = sin( myPI * (coords[4] / 180.0) ); newShape->param.gen.cosT = cos( myPI * (coords[4] / 180.0) ); break; case line_rgn: X = coords[2] - coords[0]; Y = coords[3] - coords[1]; R = sqrt( X*X + Y*Y ); newShape->param.gen.sinT = ( R ? Y/R : 0.0 ); newShape->param.gen.cosT = ( R ? X/R : 1.0 ); newShape->param.gen.a = R + 0.5; break; case panda_rgn: while( coords[2]> 180.0 ) coords[2] -= 360.0; while( coords[2]<=-180.0 ) coords[2] += 360.0; while( coords[3]> 180.0 ) coords[3] -= 360.0; while( coords[3]<=-180.0 ) coords[3] += 360.0; newShape->param.gen.a = newShape->param.gen.p[5]*newShape->param.gen.p[5]; newShape->param.gen.b = newShape->param.gen.p[6]*newShape->param.gen.p[6]; break; case epanda_rgn: case bpanda_rgn: while( coords[2]> 180.0 ) coords[2] -= 360.0; while( coords[2]<=-180.0 ) coords[2] += 360.0; while( coords[3]> 180.0 ) coords[3] -= 360.0; while( coords[3]<=-180.0 ) coords[3] += 360.0; newShape->param.gen.sinT = sin( myPI * (coords[10] / 180.0) ); newShape->param.gen.cosT = cos( myPI * (coords[10] / 180.0) ); break; default: break; } /* Set the xmin, xmax, ymin, ymax elements of the RgnShape structure */ /* For everything which has first two parameters as center position just */ /* find a circle that encompasses the region and use it to set the */ /* bounding box */ R = -1.0; switch ( newShape->shape ) { case circle_rgn: R = coords[2]; break; case annulus_rgn: R = coords[3]; break; case ellipse_rgn: if ( coords[2] > coords[3] ) { R = coords[2]; } else { R = coords[3]; } break; case elliptannulus_rgn: if ( coords[4] > coords[5] ) { R = coords[4]; } else { R = coords[5]; } break; case box_rgn: R = sqrt(coords[2]*coords[2]+ coords[3]*coords[3])/2.0; break; case boxannulus_rgn: R = sqrt(coords[4]*coords[5]+ coords[4]*coords[5])/2.0; break; case diamond_rgn: if ( coords[2] > coords[3] ) { R = coords[2]/2.0; } else { R = coords[3]/2.0; } break; case point_rgn: R = 1.0; break; case panda_rgn: R = coords[6]; break; case epanda_rgn: if ( coords[7] > coords[8] ) { R = coords[7]; } else { R = coords[8]; } break; case bpanda_rgn: R = sqrt(coords[7]*coords[8]+ coords[7]*coords[8])/2.0; break; default: break; } if ( R > 0.0 ) { newShape->xmin = coords[0] - R; newShape->xmax = coords[0] + R; newShape->ymin = coords[1] - R; newShape->ymax = coords[1] + R; return; } /* Now do the rest of the shapes that require individual methods */ switch ( newShape->shape ) { case rectangle_rgn: R = sqrt((coords[5]-coords[0])*(coords[5]-coords[0])+ (coords[6]-coords[1])*(coords[6]-coords[1])); newShape->xmin = coords[5] - R; newShape->xmax = coords[5] + R; newShape->ymin = coords[6] - R; newShape->ymax = coords[6] + R; break; case poly_rgn: newShape->xmin = coords[0]; newShape->xmax = coords[0]; newShape->ymin = coords[1]; newShape->ymax = coords[1]; for( i=2; i < newShape->param.poly.nPts; ) { if( newShape->xmin > coords[i] ) /* Min X */ newShape->xmin = coords[i]; if( newShape->xmax < coords[i] ) /* Max X */ newShape->xmax = coords[i]; i++; if( newShape->ymin > coords[i] ) /* Min Y */ newShape->ymin = coords[i]; if( newShape->ymax < coords[i] ) /* Max Y */ newShape->ymax = coords[i]; i++; } break; case line_rgn: if ( coords[0] > coords[2] ) { newShape->xmin = coords[2]; newShape->xmax = coords[0]; } else { newShape->xmin = coords[0]; newShape->xmax = coords[2]; } if ( coords[1] > coords[3] ) { newShape->ymin = coords[3]; newShape->ymax = coords[1]; } else { newShape->ymin = coords[1]; newShape->ymax = coords[3]; } break; /* sector doesn't have min and max so indicate by setting max < min */ case sector_rgn: newShape->xmin = 1.0; newShape->xmax = -1.0; newShape->ymin = 1.0; newShape->ymax = -1.0; break; default: break; } return; } /*---------------------------------------------------------------------------*/ int fits_read_fits_region ( fitsfile *fptr, WCSdata *wcs, SAORegion **Rgn, int *status) /* Read regions from a FITS region extension and return the information */ /* in the "SAORegion" structure. If it is nonNULL, use wcs to convert the */ /* region coordinates to pixels. Return an error if region is in degrees */ /* but no WCS data is provided. */ /*---------------------------------------------------------------------------*/ { int i, j, icol[6], idum, anynul, npos; int dotransform, got_component = 1, tstatus; long icsize[6]; double X, Y, Theta, Xsave = 0, Ysave = 0, Xpos, Ypos; double *coords; char *cvalue, *cvalue2; char comment[FLEN_COMMENT]; char colname[6][FLEN_VALUE] = {"X", "Y", "SHAPE", "R", "ROTANG", "COMPONENT"}; char shapename[17][FLEN_VALUE] = {"POINT","CIRCLE","ELLIPSE","ANNULUS", "ELLIPTANNULUS","BOX","ROTBOX","BOXANNULUS", "RECTANGLE","ROTRECTANGLE","POLYGON","PIE", "SECTOR","DIAMOND","RHOMBUS","ROTDIAMOND", "ROTRHOMBUS"}; int shapetype[17] = {point_rgn, circle_rgn, ellipse_rgn, annulus_rgn, elliptannulus_rgn, box_rgn, box_rgn, boxannulus_rgn, rectangle_rgn, rectangle_rgn, poly_rgn, sector_rgn, sector_rgn, diamond_rgn, diamond_rgn, diamond_rgn, diamond_rgn}; SAORegion *aRgn; RgnShape *newShape; WCSdata *regwcs = 0; if ( *status ) return( *status ); aRgn = (SAORegion *)malloc( sizeof(SAORegion) ); if( ! aRgn ) { ffpmsg("Couldn't allocate memory to hold Region file contents."); return(*status = MEMORY_ALLOCATION ); } aRgn->nShapes = 0; aRgn->Shapes = NULL; if( wcs && wcs->exists ) aRgn->wcs = *wcs; else aRgn->wcs.exists = 0; /* See if we are already positioned to a region extension, else */ /* move to the REGION extension (file is already open). */ tstatus = 0; for (i=0; i<5; i++) { ffgcno(fptr, CASEINSEN, colname[i], &icol[i], &tstatus); } if (tstatus) { /* couldn't find the required columns, so search for "REGION" extension */ if ( ffmnhd(fptr, BINARY_TBL, "REGION", 1, status) ) { ffpmsg("Could not move to REGION extension."); goto error; } } /* get the number of shapes and allocate memory */ if ( ffgky(fptr, TINT, "NAXIS2", &aRgn->nShapes, comment, status) ) { ffpmsg("Could not read NAXIS2 keyword."); goto error; } aRgn->Shapes = (RgnShape *) malloc(aRgn->nShapes * sizeof(RgnShape)); if ( !aRgn->Shapes ) { ffpmsg( "Failed to allocate memory for Region data"); *status = MEMORY_ALLOCATION; goto error; } /* get the required column numbers */ for (i=0; i<5; i++) { if ( ffgcno(fptr, CASEINSEN, colname[i], &icol[i], status) ) { ffpmsg("Could not find column."); goto error; } } /* try to get the optional column numbers */ if ( ffgcno(fptr, CASEINSEN, colname[5], &icol[5], status) ) { got_component = 0; } /* if there was input WCS then read the WCS info for the region in case they */ /* are different and we have to transform */ dotransform = 0; if ( aRgn->wcs.exists ) { regwcs = (WCSdata *) malloc ( sizeof(WCSdata) ); if ( !regwcs ) { ffpmsg( "Failed to allocate memory for Region WCS data"); *status = MEMORY_ALLOCATION; goto error; } regwcs->exists = 1; if ( ffgtcs(fptr, icol[0], icol[1], ®wcs->xrefval, ®wcs->yrefval, ®wcs->xrefpix, ®wcs->yrefpix, ®wcs->xinc, ®wcs->yinc, ®wcs->rot, regwcs->type, status) ) { regwcs->exists = 0; *status = 0; } if ( regwcs->exists && wcs->exists ) { if ( fabs(regwcs->xrefval-wcs->xrefval) > 1.0e-6 || fabs(regwcs->yrefval-wcs->yrefval) > 1.0e-6 || fabs(regwcs->xrefpix-wcs->xrefpix) > 1.0e-6 || fabs(regwcs->yrefpix-wcs->yrefpix) > 1.0e-6 || fabs(regwcs->xinc-wcs->xinc) > 1.0e-6 || fabs(regwcs->yinc-wcs->yinc) > 1.0e-6 || fabs(regwcs->rot-wcs->rot) > 1.0e-6 || !strcmp(regwcs->type,wcs->type) ) dotransform = 1; } } /* get the sizes of the X, Y, R, and ROTANG vectors */ for (i=0; i<6; i++) { if ( ffgtdm(fptr, icol[i], 1, &idum, &icsize[i], status) ) { ffpmsg("Could not find vector size of column."); goto error; } } cvalue = (char *) malloc ((FLEN_VALUE+1)*sizeof(char)); /* loop over the shapes - note 1-based counting for rows in FITS files */ for (i=1; i<=aRgn->nShapes; i++) { newShape = &aRgn->Shapes[i-1]; for (j=0; j<8; j++) newShape->param.gen.p[j] = 0.0; newShape->param.gen.a = 0.0; newShape->param.gen.b = 0.0; newShape->param.gen.sinT = 0.0; newShape->param.gen.cosT = 0.0; /* get the shape */ if ( ffgcvs(fptr, icol[2], i, 1, 1, " ", &cvalue, &anynul, status) ) { ffpmsg("Could not read shape."); goto error; } /* set include or exclude */ newShape->sign = 1; cvalue2 = cvalue; if ( !strncmp(cvalue,"!",1) ) { newShape->sign = 0; cvalue2++; } /* set the shape type */ for (j=0; j<17; j++) { if ( !strcmp(cvalue2, shapename[j]) ) newShape->shape = shapetype[j]; } /* allocate memory for polygon case and set coords pointer */ if ( newShape->shape == poly_rgn ) { newShape->param.poly.Pts = (double *) calloc (2*icsize[0], sizeof(double)); if ( !newShape->param.poly.Pts ) { ffpmsg("Could not allocate memory to hold polygon parameters" ); *status = MEMORY_ALLOCATION; goto error; } newShape->param.poly.nPts = 2*icsize[0]; coords = newShape->param.poly.Pts; } else { coords = newShape->param.gen.p; } /* read X and Y. Polygon and Rectangle require special cases */ npos = 1; if ( newShape->shape == poly_rgn ) npos = newShape->param.poly.nPts/2; if ( newShape->shape == rectangle_rgn ) npos = 2; for (j=0; jparam.poly.nPts = npos * 2; break; } coords++; if ( ffgcvd(fptr, icol[1], i, j+1, 1, DOUBLENULLVALUE, coords, &anynul, status) ) { ffpmsg("Failed to read Y column for polygon region"); goto error; } if (*coords == DOUBLENULLVALUE) { /* check for null value end of array marker */ npos = j; newShape->param.poly.nPts = npos * 2; coords--; break; } coords++; if (j == 0) { /* save the first X and Y coordinate */ Xsave = *(coords - 2); Ysave = *(coords - 1); } else if ((Xsave == *(coords - 2)) && (Ysave == *(coords - 1)) ) { /* if point has same coordinate as first point, this marks the end of the array */ npos = j + 1; newShape->param.poly.nPts = npos * 2; break; } } /* transform positions if the region and input wcs differ */ if ( dotransform ) { coords -= npos*2; Xsave = coords[0]; Ysave = coords[1]; for (j=0; jxrefval, regwcs->yrefval, regwcs->xrefpix, regwcs->yrefpix, regwcs->xinc, regwcs->yinc, regwcs->rot, regwcs->type, &Xpos, &Ypos, status); ffxypx(Xpos, Ypos, wcs->xrefval, wcs->yrefval, wcs->xrefpix, wcs->yrefpix, wcs->xinc, wcs->yinc, wcs->rot, wcs->type, &coords[2*j], &coords[2*j+1], status); if ( *status ) { ffpmsg("Failed to transform coordinates"); goto error; } } coords += npos*2; } /* read R. Circle requires one number; Box, Diamond, Ellipse, Annulus, Sector and Panda two; Boxannulus and Elliptannulus four; Point, Rectangle and Polygon none. */ npos = 0; switch ( newShape->shape ) { case circle_rgn: npos = 1; break; case box_rgn: case diamond_rgn: case ellipse_rgn: case annulus_rgn: case sector_rgn: npos = 2; break; case boxannulus_rgn: case elliptannulus_rgn: npos = 4; break; default: break; } if ( npos > 0 ) { if ( ffgcvd(fptr, icol[3], i, 1, npos, 0.0, coords, &anynul, status) ) { ffpmsg("Failed to read R column for region"); goto error; } /* transform lengths if the region and input wcs differ */ if ( dotransform ) { for (j=0; jxrefval, regwcs->yrefval, regwcs->xrefpix, regwcs->yrefpix, regwcs->xinc, regwcs->yinc, regwcs->rot, regwcs->type, &Xpos, &Ypos, status); ffxypx(Xpos, Ypos, wcs->xrefval, wcs->yrefval, wcs->xrefpix, wcs->yrefpix, wcs->xinc, wcs->yinc, wcs->rot, wcs->type, &X, &Y, status); if ( *status ) { ffpmsg("Failed to transform coordinates"); goto error; } *(coords++) = sqrt(pow(X-newShape->param.gen.p[0],2)+pow(Y-newShape->param.gen.p[1],2)); } } else { coords += npos; } } /* read ROTANG. Requires two values for Boxannulus, Elliptannulus, Sector, Panda; one for Box, Diamond, Ellipse; and none for Circle, Point, Annulus, Rectangle, Polygon */ npos = 0; switch ( newShape->shape ) { case box_rgn: case diamond_rgn: case ellipse_rgn: npos = 1; break; case boxannulus_rgn: case elliptannulus_rgn: case sector_rgn: npos = 2; break; default: break; } if ( npos > 0 ) { if ( ffgcvd(fptr, icol[4], i, 1, npos, 0.0, coords, &anynul, status) ) { ffpmsg("Failed to read ROTANG column for region"); goto error; } /* transform angles if the region and input wcs differ */ if ( dotransform ) { Theta = (wcs->rot) - (regwcs->rot); for (j=0; jcomp, &anynul, status) ) { ffpmsg("Failed to read COMPONENT column for region"); goto error; } } else { newShape->comp = 1; } /* do some precalculations to speed up tests */ fits_setup_shape(newShape); /* end loop over shapes */ } error: if( *status ) fits_free_region( aRgn ); else *Rgn = aRgn; ffclos(fptr, status); return( *status ); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/region.h0000644000175100001710000000415500000000000017564 0ustar00vstsdocker/***************************************************************/ /* REGION STUFF */ /***************************************************************/ #include "fitsio.h" #define myPI 3.1415926535897932385 #define RadToDeg 180.0/myPI typedef struct { int exists; double xrefval, yrefval; double xrefpix, yrefpix; double xinc, yinc; double rot; char type[6]; } WCSdata; typedef enum { point_rgn, line_rgn, circle_rgn, annulus_rgn, ellipse_rgn, elliptannulus_rgn, box_rgn, boxannulus_rgn, rectangle_rgn, diamond_rgn, sector_rgn, poly_rgn, panda_rgn, epanda_rgn, bpanda_rgn } shapeType; typedef enum { pixel_fmt, degree_fmt, hhmmss_fmt } coordFmt; typedef struct { char sign; /* Include or exclude? */ shapeType shape; /* Shape of this region */ int comp; /* Component number for this region */ double xmin,xmax; /* bounding box */ double ymin,ymax; union { /* Parameters - In pixels */ /**** Generic Shape Data ****/ struct { double p[11]; /* Region parameters */ double sinT, cosT; /* For rotated shapes */ double a, b; /* Extra scratch area */ } gen; /**** Polygon Data ****/ struct { int nPts; /* Number of Polygon pts */ double *Pts; /* Polygon points */ } poly; } param; } RgnShape; typedef struct { int nShapes; RgnShape *Shapes; WCSdata wcs; } SAORegion; /* SAO region file routines */ int fits_read_rgnfile( const char *filename, WCSdata *wcs, SAORegion **Rgn, int *status ); int fits_in_region( double X, double Y, SAORegion *Rgn ); void fits_free_region( SAORegion *Rgn ); void fits_set_region_components ( SAORegion *Rgn ); void fits_setup_shape ( RgnShape *shape); int fits_read_fits_region ( fitsfile *fptr, WCSdata * wcs, SAORegion **Rgn, int *status); int fits_read_ascii_region ( const char *filename, WCSdata * wcs, SAORegion **Rgn, int *status); ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/ricecomp.c0000644000175100001710000010542500000000000020077 0ustar00vstsdocker/* The following code was written by Richard White at STScI and made available for use in CFITSIO in July 1999. These routines were originally contained in 2 source files: rcomp.c and rdecomp.c, and the 'include' file now called ricecomp.h was originally called buffer.h. Note that beginning with CFITSIO v3.08, EOB checking was removed to improve speed, and so now the input compressed bytes buffers must have been allocated big enough so that they will never be overflowed. A simple rule of thumb that guarantees the buffer will be large enough is to make it 1% larger than the size of the input array of pixels that are being compressed. */ /*----------------------------------------------------------*/ /* */ /* START OF SOURCE FILE ORIGINALLY CALLED rcomp.c */ /* */ /*----------------------------------------------------------*/ /* @(#) rcomp.c 1.5 99/03/01 12:40:27 */ /* rcomp.c Compress image line using * (1) Difference of adjacent pixels * (2) Rice algorithm coding * * Returns number of bytes written to code buffer or * -1 on failure */ #include #include #include /* * nonzero_count is lookup table giving number of bits in 8-bit values not including * leading zeros used in fits_rdecomp, fits_rdecomp_short and fits_rdecomp_byte */ static const int nonzero_count[256] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}; typedef unsigned char Buffer_t; typedef struct { int bitbuffer; /* bit buffer */ int bits_to_go; /* bits to go in buffer */ Buffer_t *start; /* start of buffer */ Buffer_t *current; /* current position in buffer */ Buffer_t *end; /* end of buffer */ } Buffer; #define putcbuf(c,mf) ((*(mf->current)++ = c), 0) #include "fitsio2.h" static void start_outputing_bits(Buffer *buffer); static int done_outputing_bits(Buffer *buffer); static int output_nbits(Buffer *buffer, int bits, int n); /* only used for diagnoistics static int case1, case2, case3; int fits_get_case(int *c1, int*c2, int*c3) { *c1 = case1; *c2 = case2; *c3 = case3; return(0); } */ /* this routine used to be called 'rcomp' (WDP) */ /*---------------------------------------------------------------------------*/ int fits_rcomp(int a[], /* input array */ int nx, /* number of input pixels */ unsigned char *c, /* output buffer */ int clen, /* max length of output */ int nblock) /* coding block size */ { Buffer bufmem, *buffer = &bufmem; /* int bsize; */ int i, j, thisblock; int lastpix, nextpix, pdiff; int v, fs, fsmask, top, fsmax, fsbits, bbits; int lbitbuffer, lbits_to_go; unsigned int psum; double pixelsum, dpsum; unsigned int *diff; /* * Original size of each pixel (bsize, bytes) and coding block * size (nblock, pixels) * Could make bsize a parameter to allow more efficient * compression of short & byte images. */ /* bsize = 4; */ /* nblock = 32; now an input parameter*/ /* * From bsize derive: * FSBITS = # bits required to store FS * FSMAX = maximum value for FS * BBITS = bits/pixel for direct coding */ /* switch (bsize) { case 1: fsbits = 3; fsmax = 6; break; case 2: fsbits = 4; fsmax = 14; break; case 4: fsbits = 5; fsmax = 25; break; default: ffpmsg("rdecomp: bsize must be 1, 2, or 4 bytes"); return(-1); } */ /* move out of switch block, to tweak performance */ fsbits = 5; fsmax = 25; bbits = 1<start = c; buffer->current = c; buffer->end = c+clen; buffer->bits_to_go = 8; /* * array for differences mapped to non-negative values */ diff = (unsigned int *) malloc(nblock*sizeof(unsigned int)); if (diff == (unsigned int *) NULL) { ffpmsg("fits_rcomp: insufficient memory"); return(-1); } /* * Code in blocks of nblock pixels */ start_outputing_bits(buffer); /* write out first int value to the first 4 bytes of the buffer */ if (output_nbits(buffer, a[0], 32) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } lastpix = a[0]; /* the first difference will always be zero */ thisblock = nblock; for (i=0; i> 1; for (fs = 0; psum>0; fs++) psum >>= 1; /* * write the codes * fsbits ID bits used to indicate split level */ if (fs >= fsmax) { /* Special high entropy case when FS >= fsmax * Just write pixel difference values directly, no Rice coding at all. */ if (output_nbits(buffer, fsmax+1, fsbits) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } for (j=0; jbitbuffer; lbits_to_go = buffer->bits_to_go; for (j=0; j> fs; /* * top is coded by top zeros + 1 */ if (lbits_to_go >= top+1) { lbitbuffer <<= top+1; lbitbuffer |= 1; lbits_to_go -= top+1; } else { lbitbuffer <<= lbits_to_go; putcbuf(lbitbuffer & 0xff,buffer); for (top -= lbits_to_go; top>=8; top -= 8) { putcbuf(0, buffer); } lbitbuffer = 1; lbits_to_go = 7-top; } /* * bottom FS bits are written without coding * code is output_nbits, moved into this routine to reduce overheads * This code potentially breaks if FS>24, so I am limiting * FS to 24 by choice of FSMAX above. */ if (fs > 0) { lbitbuffer <<= fs; lbitbuffer |= v & fsmask; lbits_to_go -= fs; while (lbits_to_go <= 0) { putcbuf((lbitbuffer>>(-lbits_to_go)) & 0xff,buffer); lbits_to_go += 8; } } } /* check if overflowed output buffer */ if (buffer->current > buffer->end) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } buffer->bitbuffer = lbitbuffer; buffer->bits_to_go = lbits_to_go; } } done_outputing_bits(buffer); free(diff); /* * return number of bytes used */ return(buffer->current - buffer->start); } /*---------------------------------------------------------------------------*/ int fits_rcomp_short( short a[], /* input array */ int nx, /* number of input pixels */ unsigned char *c, /* output buffer */ int clen, /* max length of output */ int nblock) /* coding block size */ { Buffer bufmem, *buffer = &bufmem; /* int bsize; */ int i, j, thisblock; /* NOTE: in principle, the following 2 variable could be declared as 'short' but in fact the code runs faster (on 32-bit Linux at least) as 'int' */ int lastpix, nextpix; /* int pdiff; */ short pdiff; int v, fs, fsmask, top, fsmax, fsbits, bbits; int lbitbuffer, lbits_to_go; /* unsigned int psum; */ unsigned short psum; double pixelsum, dpsum; unsigned int *diff; /* * Original size of each pixel (bsize, bytes) and coding block * size (nblock, pixels) * Could make bsize a parameter to allow more efficient * compression of short & byte images. */ /* bsize = 2; */ /* nblock = 32; now an input parameter */ /* * From bsize derive: * FSBITS = # bits required to store FS * FSMAX = maximum value for FS * BBITS = bits/pixel for direct coding */ /* switch (bsize) { case 1: fsbits = 3; fsmax = 6; break; case 2: fsbits = 4; fsmax = 14; break; case 4: fsbits = 5; fsmax = 25; break; default: ffpmsg("rdecomp: bsize must be 1, 2, or 4 bytes"); return(-1); } */ /* move these out of switch block to further tweak performance */ fsbits = 4; fsmax = 14; bbits = 1<start = c; buffer->current = c; buffer->end = c+clen; buffer->bits_to_go = 8; /* * array for differences mapped to non-negative values */ diff = (unsigned int *) malloc(nblock*sizeof(unsigned int)); if (diff == (unsigned int *) NULL) { ffpmsg("fits_rcomp: insufficient memory"); return(-1); } /* * Code in blocks of nblock pixels */ start_outputing_bits(buffer); /* write out first short value to the first 2 bytes of the buffer */ if (output_nbits(buffer, a[0], 16) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } lastpix = a[0]; /* the first difference will always be zero */ thisblock = nblock; for (i=0; i> 1; */ psum = ((unsigned short) dpsum ) >> 1; for (fs = 0; psum>0; fs++) psum >>= 1; /* * write the codes * fsbits ID bits used to indicate split level */ if (fs >= fsmax) { /* case3++; */ /* Special high entropy case when FS >= fsmax * Just write pixel difference values directly, no Rice coding at all. */ if (output_nbits(buffer, fsmax+1, fsbits) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } for (j=0; jbitbuffer; lbits_to_go = buffer->bits_to_go; for (j=0; j> fs; /* * top is coded by top zeros + 1 */ if (lbits_to_go >= top+1) { lbitbuffer <<= top+1; lbitbuffer |= 1; lbits_to_go -= top+1; } else { lbitbuffer <<= lbits_to_go; putcbuf(lbitbuffer & 0xff,buffer); for (top -= lbits_to_go; top>=8; top -= 8) { putcbuf(0, buffer); } lbitbuffer = 1; lbits_to_go = 7-top; } /* * bottom FS bits are written without coding * code is output_nbits, moved into this routine to reduce overheads * This code potentially breaks if FS>24, so I am limiting * FS to 24 by choice of FSMAX above. */ if (fs > 0) { lbitbuffer <<= fs; lbitbuffer |= v & fsmask; lbits_to_go -= fs; while (lbits_to_go <= 0) { putcbuf((lbitbuffer>>(-lbits_to_go)) & 0xff,buffer); lbits_to_go += 8; } } } /* check if overflowed output buffer */ if (buffer->current > buffer->end) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } buffer->bitbuffer = lbitbuffer; buffer->bits_to_go = lbits_to_go; } } done_outputing_bits(buffer); free(diff); /* * return number of bytes used */ return(buffer->current - buffer->start); } /*---------------------------------------------------------------------------*/ int fits_rcomp_byte( signed char a[], /* input array */ int nx, /* number of input pixels */ unsigned char *c, /* output buffer */ int clen, /* max length of output */ int nblock) /* coding block size */ { Buffer bufmem, *buffer = &bufmem; /* int bsize; */ int i, j, thisblock; /* NOTE: in principle, the following 2 variable could be declared as 'short' but in fact the code runs faster (on 32-bit Linux at least) as 'int' */ int lastpix, nextpix; /* int pdiff; */ signed char pdiff; int v, fs, fsmask, top, fsmax, fsbits, bbits; int lbitbuffer, lbits_to_go; /* unsigned int psum; */ unsigned char psum; double pixelsum, dpsum; unsigned int *diff; /* * Original size of each pixel (bsize, bytes) and coding block * size (nblock, pixels) * Could make bsize a parameter to allow more efficient * compression of short & byte images. */ /* bsize = 1; */ /* nblock = 32; now an input parameter */ /* * From bsize derive: * FSBITS = # bits required to store FS * FSMAX = maximum value for FS * BBITS = bits/pixel for direct coding */ /* switch (bsize) { case 1: fsbits = 3; fsmax = 6; break; case 2: fsbits = 4; fsmax = 14; break; case 4: fsbits = 5; fsmax = 25; break; default: ffpmsg("rdecomp: bsize must be 1, 2, or 4 bytes"); return(-1); } */ /* move these out of switch block to further tweak performance */ fsbits = 3; fsmax = 6; bbits = 1<start = c; buffer->current = c; buffer->end = c+clen; buffer->bits_to_go = 8; /* * array for differences mapped to non-negative values */ diff = (unsigned int *) malloc(nblock*sizeof(unsigned int)); if (diff == (unsigned int *) NULL) { ffpmsg("fits_rcomp: insufficient memory"); return(-1); } /* * Code in blocks of nblock pixels */ start_outputing_bits(buffer); /* write out first byte value to the first byte of the buffer */ if (output_nbits(buffer, a[0], 8) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } lastpix = a[0]; /* the first difference will always be zero */ thisblock = nblock; for (i=0; i> 1; */ psum = ((unsigned char) dpsum ) >> 1; for (fs = 0; psum>0; fs++) psum >>= 1; /* * write the codes * fsbits ID bits used to indicate split level */ if (fs >= fsmax) { /* Special high entropy case when FS >= fsmax * Just write pixel difference values directly, no Rice coding at all. */ if (output_nbits(buffer, fsmax+1, fsbits) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } for (j=0; jbitbuffer; lbits_to_go = buffer->bits_to_go; for (j=0; j> fs; /* * top is coded by top zeros + 1 */ if (lbits_to_go >= top+1) { lbitbuffer <<= top+1; lbitbuffer |= 1; lbits_to_go -= top+1; } else { lbitbuffer <<= lbits_to_go; putcbuf(lbitbuffer & 0xff,buffer); for (top -= lbits_to_go; top>=8; top -= 8) { putcbuf(0, buffer); } lbitbuffer = 1; lbits_to_go = 7-top; } /* * bottom FS bits are written without coding * code is output_nbits, moved into this routine to reduce overheads * This code potentially breaks if FS>24, so I am limiting * FS to 24 by choice of FSMAX above. */ if (fs > 0) { lbitbuffer <<= fs; lbitbuffer |= v & fsmask; lbits_to_go -= fs; while (lbits_to_go <= 0) { putcbuf((lbitbuffer>>(-lbits_to_go)) & 0xff,buffer); lbits_to_go += 8; } } } /* check if overflowed output buffer */ if (buffer->current > buffer->end) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } buffer->bitbuffer = lbitbuffer; buffer->bits_to_go = lbits_to_go; } } done_outputing_bits(buffer); free(diff); /* * return number of bytes used */ return(buffer->current - buffer->start); } /*---------------------------------------------------------------------------*/ /* bit_output.c * * Bit output routines * Procedures return zero on success, EOF on end-of-buffer * * Programmer: R. White Date: 20 July 1998 */ /* Initialize for bit output */ static void start_outputing_bits(Buffer *buffer) { /* * Buffer is empty to start with */ buffer->bitbuffer = 0; buffer->bits_to_go = 8; } /*---------------------------------------------------------------------------*/ /* Output N bits (N must be <= 32) */ static int output_nbits(Buffer *buffer, int bits, int n) { /* local copies */ int lbitbuffer; int lbits_to_go; /* AND mask for the right-most n bits */ static unsigned int mask[33] = {0, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff, 0x7ff, 0xfff, 0x1fff, 0x3fff, 0x7fff, 0xffff, 0x1ffff, 0x3ffff, 0x7ffff, 0xfffff, 0x1fffff, 0x3fffff, 0x7fffff, 0xffffff, 0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff}; /* * insert bits at end of bitbuffer */ lbitbuffer = buffer->bitbuffer; lbits_to_go = buffer->bits_to_go; if (lbits_to_go+n > 32) { /* * special case for large n: put out the top lbits_to_go bits first * note that 0 < lbits_to_go <= 8 */ lbitbuffer <<= lbits_to_go; /* lbitbuffer |= (bits>>(n-lbits_to_go)) & ((1<>(n-lbits_to_go)) & *(mask+lbits_to_go); putcbuf(lbitbuffer & 0xff,buffer); n -= lbits_to_go; lbits_to_go = 8; } lbitbuffer <<= n; /* lbitbuffer |= ( bits & ((1<>(-lbits_to_go)) & 0xff,buffer); lbits_to_go += 8; } buffer->bitbuffer = lbitbuffer; buffer->bits_to_go = lbits_to_go; return(0); } /*---------------------------------------------------------------------------*/ /* Flush out the last bits */ static int done_outputing_bits(Buffer *buffer) { if(buffer->bits_to_go < 8) { putcbuf(buffer->bitbuffer<bits_to_go,buffer); /* if (putcbuf(buffer->bitbuffer<bits_to_go,buffer) == EOF) return(EOF); */ } return(0); } /*---------------------------------------------------------------------------*/ /*----------------------------------------------------------*/ /* */ /* START OF SOURCE FILE ORIGINALLY CALLED rdecomp.c */ /* */ /*----------------------------------------------------------*/ /* @(#) rdecomp.c 1.4 99/03/01 12:38:41 */ /* rdecomp.c Decompress image line using * (1) Difference of adjacent pixels * (2) Rice algorithm coding * * Returns 0 on success or 1 on failure */ /* moved these 'includes' to the beginning of the file (WDP) #include #include */ /*---------------------------------------------------------------------------*/ /* this routine used to be called 'rdecomp' (WDP) */ int fits_rdecomp (unsigned char *c, /* input buffer */ int clen, /* length of input */ unsigned int array[], /* output array */ int nx, /* number of output pixels */ int nblock) /* coding block size */ { /* int bsize; */ int i, k, imax; int nbits, nzero, fs; unsigned char *cend, bytevalue; unsigned int b, diff, lastpix; int fsmax, fsbits, bbits; extern const int nonzero_count[]; /* * Original size of each pixel (bsize, bytes) and coding block * size (nblock, pixels) * Could make bsize a parameter to allow more efficient * compression of short & byte images. */ /* bsize = 4; */ /* nblock = 32; now an input parameter */ /* * From bsize derive: * FSBITS = # bits required to store FS * FSMAX = maximum value for FS * BBITS = bits/pixel for direct coding */ /* switch (bsize) { case 1: fsbits = 3; fsmax = 6; break; case 2: fsbits = 4; fsmax = 14; break; case 4: fsbits = 5; fsmax = 25; break; default: ffpmsg("rdecomp: bsize must be 1, 2, or 4 bytes"); return 1; } */ /* move out of switch block, to tweak performance */ fsbits = 5; fsmax = 25; bbits = 1<> nbits) - 1; b &= (1< nx) imax = nx; if (fs<0) { /* low-entropy case, all zero differences */ for ( ; i= 0; k -= 8) { b = *c++; diff |= b<0) { b = *c++; diff |= b>>(-k); b &= (1<>1; } else { diff = ~(diff>>1); } array[i] = diff+lastpix; lastpix = array[i]; } } else { /* normal case, Rice coding */ for ( ; i>nbits); b &= (1<>1; } else { diff = ~(diff>>1); } array[i] = diff+lastpix; lastpix = array[i]; } } if (c > cend) { ffpmsg("decompression error: hit end of compressed byte stream"); return 1; } } if (c < cend) { ffpmsg("decompression warning: unused bytes at end of compressed buffer"); } return 0; } /*---------------------------------------------------------------------------*/ /* this routine used to be called 'rdecomp' (WDP) */ int fits_rdecomp_short (unsigned char *c, /* input buffer */ int clen, /* length of input */ unsigned short array[], /* output array */ int nx, /* number of output pixels */ int nblock) /* coding block size */ { int i, imax; /* int bsize; */ int k; int nbits, nzero, fs; unsigned char *cend, bytevalue; unsigned int b, diff, lastpix; int fsmax, fsbits, bbits; extern const int nonzero_count[]; /* * Original size of each pixel (bsize, bytes) and coding block * size (nblock, pixels) * Could make bsize a parameter to allow more efficient * compression of short & byte images. */ /* bsize = 2; */ /* nblock = 32; now an input parameter */ /* * From bsize derive: * FSBITS = # bits required to store FS * FSMAX = maximum value for FS * BBITS = bits/pixel for direct coding */ /* switch (bsize) { case 1: fsbits = 3; fsmax = 6; break; case 2: fsbits = 4; fsmax = 14; break; case 4: fsbits = 5; fsmax = 25; break; default: ffpmsg("rdecomp: bsize must be 1, 2, or 4 bytes"); return 1; } */ /* move out of switch block, to tweak performance */ fsbits = 4; fsmax = 14; bbits = 1<> nbits) - 1; b &= (1< nx) imax = nx; if (fs<0) { /* low-entropy case, all zero differences */ for ( ; i= 0; k -= 8) { b = *c++; diff |= b<0) { b = *c++; diff |= b>>(-k); b &= (1<>1; } else { diff = ~(diff>>1); } array[i] = diff+lastpix; lastpix = array[i]; } } else { /* normal case, Rice coding */ for ( ; i>nbits); b &= (1<>1; } else { diff = ~(diff>>1); } array[i] = diff+lastpix; lastpix = array[i]; } } if (c > cend) { ffpmsg("decompression error: hit end of compressed byte stream"); return 1; } } if (c < cend) { ffpmsg("decompression warning: unused bytes at end of compressed buffer"); } return 0; } /*---------------------------------------------------------------------------*/ /* this routine used to be called 'rdecomp' (WDP) */ int fits_rdecomp_byte (unsigned char *c, /* input buffer */ int clen, /* length of input */ unsigned char array[], /* output array */ int nx, /* number of output pixels */ int nblock) /* coding block size */ { int i, imax; /* int bsize; */ int k; int nbits, nzero, fs; unsigned char *cend; unsigned int b, diff, lastpix; int fsmax, fsbits, bbits; extern const int nonzero_count[]; /* * Original size of each pixel (bsize, bytes) and coding block * size (nblock, pixels) * Could make bsize a parameter to allow more efficient * compression of short & byte images. */ /* bsize = 1; */ /* nblock = 32; now an input parameter */ /* * From bsize derive: * FSBITS = # bits required to store FS * FSMAX = maximum value for FS * BBITS = bits/pixel for direct coding */ /* switch (bsize) { case 1: fsbits = 3; fsmax = 6; break; case 2: fsbits = 4; fsmax = 14; break; case 4: fsbits = 5; fsmax = 25; break; default: ffpmsg("rdecomp: bsize must be 1, 2, or 4 bytes"); return 1; } */ /* move out of switch block, to tweak performance */ fsbits = 3; fsmax = 6; bbits = 1<> nbits) - 1; b &= (1< nx) imax = nx; if (fs<0) { /* low-entropy case, all zero differences */ for ( ; i= 0; k -= 8) { b = *c++; diff |= b<0) { b = *c++; diff |= b>>(-k); b &= (1<>1; } else { diff = ~(diff>>1); } array[i] = diff+lastpix; lastpix = array[i]; } } else { /* normal case, Rice coding */ for ( ; i>nbits); b &= (1<>1; } else { diff = ~(diff>>1); } array[i] = diff+lastpix; lastpix = array[i]; } } if (c > cend) { ffpmsg("decompression error: hit end of compressed byte stream"); return 1; } } if (c < cend) { ffpmsg("decompression warning: unused bytes at end of compressed buffer"); } return 0; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/scalnull.c0000644000175100001710000002141500000000000020107 0ustar00vstsdocker/* This file, scalnull.c, contains the FITSIO routines used to define */ /* the starting heap address, the value scaling and the null values. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpthp(fitsfile *fptr, /* I - FITS file pointer */ long theap, /* I - starting addrss for the heap */ int *status) /* IO - error status */ /* Define the starting address for the heap for a binary table. The default address is NAXIS1 * NAXIS2. It is in units of bytes relative to the beginning of the regular binary table data. This routine also writes the appropriate THEAP keyword to the FITS header. */ { if (*status > 0 || theap < 1) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); (fptr->Fptr)->heapstart = theap; ffukyj(fptr, "THEAP", theap, "byte offset to heap area", status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpscl(fitsfile *fptr, /* I - FITS file pointer */ double scale, /* I - scaling factor: value of BSCALE */ double zero, /* I - zero point: value of BZERO */ int *status) /* IO - error status */ /* Define the linear scaling factor for the primary array or image extension pixel values. This routine overrides the scaling values given by the BSCALE and BZERO keywords if present. Note that this routine does not write or modify the BSCALE and BZERO keywords, but instead only modifies the values temporarily in the internal buffer. Thus, a subsequent call to the ffrdef routine will reset the scaling back to the BSCALE and BZERO keyword values (or 1. and 0. respectively if the keywords are not present). */ { tcolumn *colptr; int hdutype; if (*status > 0) return(*status); if (scale == 0) return(*status = ZERO_SCALE); /* zero scale value is illegal */ if (ffghdt(fptr, &hdutype, status) > 0) /* get HDU type */ return(*status); if (hdutype != IMAGE_HDU) return(*status = NOT_IMAGE); /* not proper HDU type */ if (fits_is_compressed_image(fptr, status)) /* compressed images */ { (fptr->Fptr)->cn_bscale = scale; (fptr->Fptr)->cn_bzero = zero; return(*status); } /* set pointer to the first 'column' (contains group parameters if any) */ colptr = (fptr->Fptr)->tableptr; colptr++; /* increment to the 2nd 'column' pointer (the image itself) */ colptr->tscale = scale; colptr->tzero = zero; return(*status); } /*--------------------------------------------------------------------------*/ int ffpnul(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG nulvalue, /* I - null pixel value: value of BLANK */ int *status) /* IO - error status */ /* Define the value used to represent undefined pixels in the primary array or image extension. This only applies to integer image pixel (i.e. BITPIX > 0). This routine overrides the null pixel value given by the BLANK keyword if present. Note that this routine does not write or modify the BLANK keyword, but instead only modifies the value temporarily in the internal buffer. Thus, a subsequent call to the ffrdef routine will reset the null value back to the BLANK keyword value (or not defined if the keyword is not present). */ { tcolumn *colptr; int hdutype; if (*status > 0) return(*status); if (ffghdt(fptr, &hdutype, status) > 0) /* get HDU type */ return(*status); if (hdutype != IMAGE_HDU) return(*status = NOT_IMAGE); /* not proper HDU type */ if (fits_is_compressed_image(fptr, status)) /* ignore compressed images */ return(*status); /* set pointer to the first 'column' (contains group parameters if any) */ colptr = (fptr->Fptr)->tableptr; colptr++; /* increment to the 2nd 'column' pointer (the image itself) */ colptr->tnull = nulvalue; return(*status); } /*--------------------------------------------------------------------------*/ int fftscl(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number to apply scaling to */ double scale, /* I - scaling factor: value of TSCALn */ double zero, /* I - zero point: value of TZEROn */ int *status) /* IO - error status */ /* Define the linear scaling factor for the TABLE or BINTABLE extension column values. This routine overrides the scaling values given by the TSCALn and TZEROn keywords if present. Note that this routine does not write or modify the TSCALn and TZEROn keywords, but instead only modifies the values temporarily in the internal buffer. Thus, a subsequent call to the ffrdef routine will reset the scaling back to the TSCALn and TZEROn keyword values (or 1. and 0. respectively if the keywords are not present). */ { tcolumn *colptr; int hdutype; if (*status > 0) return(*status); if (scale == 0) return(*status = ZERO_SCALE); /* zero scale value is illegal */ if (ffghdt(fptr, &hdutype, status) > 0) /* get HDU type */ return(*status); if (hdutype == IMAGE_HDU) return(*status = NOT_TABLE); /* not proper HDU type */ colptr = (fptr->Fptr)->tableptr; /* set pointer to the first column */ colptr += (colnum - 1); /* increment to the correct column */ colptr->tscale = scale; colptr->tzero = zero; return(*status); } /*--------------------------------------------------------------------------*/ int fftnul(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number to apply nulvalue to */ LONGLONG nulvalue, /* I - null pixel value: value of TNULLn */ int *status) /* IO - error status */ /* Define the value used to represent undefined pixels in the BINTABLE column. This only applies to integer datatype columns (TFORM = B, I, or J). This routine overrides the null pixel value given by the TNULLn keyword if present. Note that this routine does not write or modify the TNULLn keyword, but instead only modifies the value temporarily in the internal buffer. Thus, a subsequent call to the ffrdef routine will reset the null value back to the TNULLn keyword value (or not defined if the keyword is not present). */ { tcolumn *colptr; int hdutype; if (*status > 0) return(*status); if (ffghdt(fptr, &hdutype, status) > 0) /* get HDU type */ return(*status); if (hdutype != BINARY_TBL) return(*status = NOT_BTABLE); /* not proper HDU type */ colptr = (fptr->Fptr)->tableptr; /* set pointer to the first column */ colptr += (colnum - 1); /* increment to the correct column */ colptr->tnull = nulvalue; return(*status); } /*--------------------------------------------------------------------------*/ int ffsnul(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number to apply nulvalue to */ char *nulstring, /* I - null pixel value: value of TNULLn */ int *status) /* IO - error status */ /* Define the string used to represent undefined pixels in the ASCII TABLE column. This routine overrides the null value given by the TNULLn keyword if present. Note that this routine does not write or modify the TNULLn keyword, but instead only modifies the value temporarily in the internal buffer. Thus, a subsequent call to the ffrdef routine will reset the null value back to the TNULLn keyword value (or not defined if the keyword is not present). */ { tcolumn *colptr; int hdutype; if (*status > 0) return(*status); if (ffghdt(fptr, &hdutype, status) > 0) /* get HDU type */ return(*status); if (hdutype != ASCII_TBL) return(*status = NOT_ATABLE); /* not proper HDU type */ colptr = (fptr->Fptr)->tableptr; /* set pointer to the first column */ colptr += (colnum - 1); /* increment to the correct column */ colptr->strnull[0] = '\0'; strncat(colptr->strnull, nulstring, 19); /* limit string to 19 chars */ return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/simplerng.c0000644000175100001710000003314500000000000020275 0ustar00vstsdocker/* Simple Random Number Generators - getuniform - uniform deviate [0,1] - getnorm - gaussian (normal) deviate (mean=0, stddev=1) - getpoisson - poisson deviate for given expected mean lambda This code is adapted from SimpleRNG by John D Cook, which is provided in the public domain. The original C++ code is found here: http://www.johndcook.com/cpp_random_number_generation.html This code has been modified in the following ways compared to the original. 1. convert to C from C++ 2. keep only uniform, gaussian and poisson deviates 3. state variables are module static instead of class variables 4. provide an srand() equivalent to initialize the state */ #include #include #define PI 3.1415926535897932384626433832795 /* Use the standard system rand() library routine if it provides enough bits of information, since it probably has better randomness than the toy algorithm in this module. */ #if defined(RAND_MAX) && RAND_MAX > 1000000000 #define USE_SYSTEM_RAND #endif int simplerng_poisson_small(double lambda); int simplerng_poisson_large(double lambda); double simplerng_getuniform_pr(unsigned int *u, unsigned int *v); unsigned int simplerng_getuint_pr(unsigned int *u, unsigned int *v); double simplerng_logfactorial(int n); /* These values are not magical, just the default values Marsaglia used. Any unit should work. */ static unsigned int m_u = 521288629, m_v = 362436069; /* Set u and v state variables */ void simplerng_setstate(unsigned int u, unsigned int v) { m_u = u; m_v = v; } /* Retrieve u and v state variables */ void simplerng_getstate(unsigned int *u, unsigned int *v) { *u = m_u; *v = m_v; } /* srand() equivalent to seed the two state variables */ void simplerng_srand(unsigned int seed) { #ifdef USE_SYSTEM_RAND srand(seed); #else simplerng_setstate(seed ^ 521288629, seed ^ 362436069); #endif } /* Private routine to get uniform deviate */ double simplerng_getuniform_pr(unsigned int *u, unsigned int *v) { /* 0 <= u <= 2^32 */ unsigned int z = simplerng_getuint_pr(u, v); /* The magic number is 1/(2^32) and so result is positive and less than 1. */ return z*2.328306435996595e-10; } /* Private routine to get unsigned integer */ /* Marsaglia multiply-with-carry algorithm (MWC) */ unsigned int simplerng_getuint_pr(unsigned int *u, unsigned int *v) { *v = 36969*((*v) & 65535) + ((*v) >> 16); *u = 18000*((*u) & 65535) + ((*u) >> 16); return ((*v) << 16) + (*u); } /* Get uniform deviate [0,1] */ double simplerng_getuniform(void) { #ifdef USE_SYSTEM_RAND return rand()*(1.0 / ((double)RAND_MAX + 1)); #else return simplerng_getuniform_pr(&m_u, &m_v); #endif } /* Get unsigned integer [0, UINT_MAX] */ unsigned int simplerng_getuint() { /* WARNING: no option for calling rand() here. Will need to provide a scalar to make the uint in the [0,UINT_MAX] range */ return simplerng_getuint_pr(&m_u, &m_v); } /* Get normal (Gaussian) random sample with mean=0, stddev=1 */ double simplerng_getnorm() { double u1, u2, r, theta; static int saved = 0; static double y; /* Since you get two deviates for "free" with each calculation, save one of them for later */ if (saved == 0) { /* Use Box-Muller algorithm */ u1 = simplerng_getuniform(); u2 = simplerng_getuniform(); r = sqrt( -2.0*log(u1) ); theta = 2.0*PI*u2; /* save second value for next call */ y = r*cos(theta); saved = 1; return r*sin(theta); } else { /* We already saved a value from the last call so use it */ saved = 0; return y; } } /* Poisson deviate for expected mean value lambda. lambda should be in the range [0, infinity] For small lambda, a simple rejection method is used For large lambda, an approximation is used */ int simplerng_getpoisson(double lambda) { if (lambda < 0) lambda = 0; return ((lambda < 15.0) ? simplerng_poisson_small(lambda) : simplerng_poisson_large(lambda)); } int simplerng_poisson_small(double lambda) { /* Algorithm due to Donald Knuth, 1969. */ double p = 1.0, L = exp(-lambda); int k = 0; do { k++; p *= simplerng_getuniform(); } while (p > L); return k - 1; } int simplerng_poisson_large(double lambda) { /* "Rejection method PA" from "The Computer Generation of Poisson Random Variables" by A. C. Atkinson Journal of the Royal Statistical Society Series C (Applied Statistics) Vol. 28, No. 1. (1979) The article is on pages 29-35. The algorithm given here is on page 32. */ static double beta, alpha, k; static double old_lambda = -999999.; if (lambda != old_lambda) { double c = 0.767 - 3.36/lambda; beta = PI/sqrt(3.0*lambda); alpha = beta*lambda; k = log(c) - lambda - log(beta); old_lambda = lambda; } for(;;) { /* forever */ double u, x, v, y, temp, lhs, rhs; int n; u = simplerng_getuniform(); x = (alpha - log((1.0 - u)/u))/beta; n = (int) floor(x + 0.5); if (n < 0) continue; v = simplerng_getuniform(); y = alpha - beta*x; temp = 1.0 + exp(y); lhs = y + log(v/(temp*temp)); rhs = k + n*log(lambda) - simplerng_logfactorial(n); if (lhs <= rhs) return n; } } /* Lookup table for log-gamma function */ static double lf[] = { 0.000000000000000, 0.000000000000000, 0.693147180559945, 1.791759469228055, 3.178053830347946, 4.787491742782046, 6.579251212010101, 8.525161361065415, 10.604602902745251, 12.801827480081469, 15.104412573075516, 17.502307845873887, 19.987214495661885, 22.552163853123421, 25.191221182738683, 27.899271383840894, 30.671860106080675, 33.505073450136891, 36.395445208033053, 39.339884187199495, 42.335616460753485, 45.380138898476908, 48.471181351835227, 51.606675567764377, 54.784729398112319, 58.003605222980518, 61.261701761002001, 64.557538627006323, 67.889743137181526, 71.257038967168000, 74.658236348830158, 78.092223553315307, 81.557959456115029, 85.054467017581516, 88.580827542197682, 92.136175603687079, 95.719694542143202, 99.330612454787428, 102.968198614513810, 106.631760260643450, 110.320639714757390, 114.034211781461690, 117.771881399745060, 121.533081515438640, 125.317271149356880, 129.123933639127240, 132.952575035616290, 136.802722637326350, 140.673923648234250, 144.565743946344900, 148.477766951773020, 152.409592584497350, 156.360836303078800, 160.331128216630930, 164.320112263195170, 168.327445448427650, 172.352797139162820, 176.395848406997370, 180.456291417543780, 184.533828861449510, 188.628173423671600, 192.739047287844900, 196.866181672889980, 201.009316399281570, 205.168199482641200, 209.342586752536820, 213.532241494563270, 217.736934113954250, 221.956441819130360, 226.190548323727570, 230.439043565776930, 234.701723442818260, 238.978389561834350, 243.268849002982730, 247.572914096186910, 251.890402209723190, 256.221135550009480, 260.564940971863220, 264.921649798552780, 269.291097651019810, 273.673124285693690, 278.067573440366120, 282.474292687630400, 286.893133295426990, 291.323950094270290, 295.766601350760600, 300.220948647014100, 304.686856765668720, 309.164193580146900, 313.652829949878990, 318.152639620209300, 322.663499126726210, 327.185287703775200, 331.717887196928470, 336.261181979198450, 340.815058870798960, 345.379407062266860, 349.954118040770250, 354.539085519440790, 359.134205369575340, 363.739375555563470, 368.354496072404690, 372.979468885689020, 377.614197873918670, 382.258588773060010, 386.912549123217560, 391.575988217329610, 396.248817051791490, 400.930948278915760, 405.622296161144900, 410.322776526937280, 415.032306728249580, 419.750805599544780, 424.478193418257090, 429.214391866651570, 433.959323995014870, 438.712914186121170, 443.475088120918940, 448.245772745384610, 453.024896238496130, 457.812387981278110, 462.608178526874890, 467.412199571608080, 472.224383926980520, 477.044665492585580, 481.872979229887900, 486.709261136839360, 491.553448223298010, 496.405478487217580, 501.265290891579240, 506.132825342034830, 511.008022665236070, 515.890824587822520, 520.781173716044240, 525.679013515995050, 530.584288294433580, 535.496943180169520, 540.416924105997740, 545.344177791154950, 550.278651724285620, 555.220294146894960, 560.169054037273100, 565.124881094874350, 570.087725725134190, 575.057539024710200, 580.034272767130800, 585.017879388839220, 590.008311975617860, 595.005524249382010, 600.009470555327430, 605.020105849423770, 610.037385686238740, 615.061266207084940, 620.091704128477430, 625.128656730891070, 630.172081847810200, 635.221937855059760, 640.278183660408100, 645.340778693435030, 650.409682895655240, 655.484856710889060, 660.566261075873510, 665.653857411105950, 670.747607611912710, 675.847474039736880, 680.953419513637530, 686.065407301994010, 691.183401114410800, 696.307365093814040, 701.437263808737160, 706.573062245787470, 711.714725802289990, 716.862220279103440, 722.015511873601330, 727.174567172815840, 732.339353146739310, 737.509837141777440, 742.685986874351220, 747.867770424643370, 753.055156230484160, 758.248113081374300, 763.446610112640200, 768.650616799717000, 773.860102952558460, 779.075038710167410, 784.295394535245690, 789.521141208958970, 794.752249825813460, 799.988691788643450, 805.230438803703120, 810.477462875863580, 815.729736303910160, 820.987231675937890, 826.249921864842800, 831.517780023906310, 836.790779582469900, 842.068894241700490, 847.352097970438420, 852.640365001133090, 857.933669825857460, 863.231987192405430, 868.535292100464630, 873.843559797865740, 879.156765776907600, 884.474885770751830, 889.797895749890240, 895.125771918679900, 900.458490711945270, 905.796028791646340, 911.138363043611210, 916.485470574328820, 921.837328707804890, 927.193914982476710, 932.555207148186240, 937.921183163208070, 943.291821191335660, 948.667099599019820, 954.046996952560450, 959.431492015349480, 964.820563745165940, 970.214191291518320, 975.612353993036210, 981.015031374908400, 986.422203146368590, 991.833849198223450, 997.249949600427840, 1002.670484599700300, 1008.095434617181700, 1013.524780246136200, 1018.958502249690200, 1024.396581558613400, 1029.838999269135500, 1035.285736640801600, 1040.736775094367400, 1046.192096209724900, 1051.651681723869200, 1057.115513528895000, 1062.583573670030100, 1068.055844343701400, 1073.532307895632800, 1079.012946818975000, 1084.497743752465600, 1089.986681478622400, 1095.479742921962700, 1100.976911147256000, 1106.478169357800900, 1111.983500893733000, 1117.492889230361000, 1123.006317976526100, 1128.523770872990800, 1134.045231790853000, 1139.570684729984800, 1145.100113817496100, 1150.633503306223700, 1156.170837573242400, }; double simplerng_logfactorial(int n) { if (n < 0) return 0; if (n > 254) { double x = n + 1; return (x - 0.5)*log(x) - x + 0.5*log(2*PI) + 1.0/(12.0*x); } return lf[n]; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/simplerng.h0000644000175100001710000000206600000000000020300 0ustar00vstsdocker/* Simple Random Number Generators - getuniform - uniform deviate [0,1] - getnorm - gaussian (normal) deviate (mean=0, stddev=1) - getpoisson - poisson deviate for given expected mean lambda This code is adapted from SimpleRNG by John D Cook, which is provided in the public domain. The original C++ code is found here: http://www.johndcook.com/cpp_random_number_generation.html This code has been modified in the following ways compared to the original. 1. convert to C from C++ 2. keep only uniform, gaussian and poisson deviates 3. state variables are module static instead of class variables 4. provide an srand() equivalent to initialize the state */ extern void simplerng_setstate(unsigned int u, unsigned int v); extern void simplerng_getstate(unsigned int *u, unsigned int *v); extern void simplerng_srand(unsigned int seed); extern double simplerng_getuniform(void); extern double simplerng_getnorm(void); extern int simplerng_getpoisson(double lambda); extern double simplerng_logfactorial(int n); ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/swapproc.c0000644000175100001710000001702700000000000020134 0ustar00vstsdocker/* This file, swapproc.c, contains general utility routines that are */ /* used by other FITSIO routines to swap bytes. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ /* The fast SSE2 and SSSE3 functions were provided by Julian Taylor, ESO */ #include #include #include "fitsio2.h" /* bswap builtin is available since GCC 4.3 */ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) #define HAVE_BSWAP #endif #ifdef __SSSE3__ #include /* swap 16 bytes according to mask, values must be 16 byte aligned */ static inline void swap_ssse3(char * values, __m128i mask) { __m128i v = _mm_load_si128((__m128i *)values); __m128i s = _mm_shuffle_epi8(v, mask); _mm_store_si128((__m128i*)values, s); } #endif #ifdef __SSE2__ #include /* swap 8 shorts, values must be 16 byte aligned * faster than ssse3 variant for shorts */ static inline void swap2_sse2(char * values) { __m128i r1 = _mm_load_si128((__m128i *)values); __m128i r2 = r1; r1 = _mm_srli_epi16(r1, 8); r2 = _mm_slli_epi16(r2, 8); r1 = _mm_or_si128(r1, r2); _mm_store_si128((__m128i*)values, r1); } /* the three shuffles required for 4 and 8 byte variants make * SSE2 slower than bswap */ /* get number of elements to peel to reach alignment */ static inline size_t get_peel(void * addr, size_t esize, size_t nvals, size_t alignment) { const size_t offset = (size_t)addr % alignment; size_t peel = offset ? (alignment - offset) / esize : 0; peel = nvals < peel ? nvals : peel; return peel; } #endif /*--------------------------------------------------------------------------*/ static void ffswap2_slow(short *svalues, long nvals) { register long ii; unsigned short * usvalues; usvalues = (unsigned short *) svalues; for (ii = 0; ii < nvals; ii++) { usvalues[ii] = (usvalues[ii]>>8) | (usvalues[ii]<<8); } } /*--------------------------------------------------------------------------*/ #if __SSE2__ void ffswap2(short *svalues, /* IO - pointer to shorts to be swapped */ long nvals) /* I - number of shorts to be swapped */ /* swap the bytes in the input short integers: ( 0 1 -> 1 0 ) */ { if ((long)svalues % 2 != 0) { /* should not happen */ ffswap2_slow(svalues, nvals); return; } long ii; size_t peel = get_peel((void*)&svalues[0], sizeof(svalues[0]), nvals, 16); ffswap2_slow(svalues, peel); for (ii = peel; ii < (nvals - peel - (nvals - peel) % 8); ii+=8) { swap2_sse2((char*)&svalues[ii]); } ffswap2_slow(&svalues[ii], nvals - ii); } #else void ffswap2(short *svalues, /* IO - pointer to shorts to be swapped */ long nvals) /* I - number of shorts to be swapped */ /* swap the bytes in the input 4-byte integer: ( 0 1 2 3 -> 3 2 1 0 ) */ { ffswap2_slow(svalues, nvals); } #endif /*--------------------------------------------------------------------------*/ static void ffswap4_slow(INT32BIT *ivalues, long nvals) { register long ii; #if defined(HAVE_BSWAP) for (ii = 0; ii < nvals; ii++) { ivalues[ii] = __builtin_bswap32(ivalues[ii]); } #elif defined(_MSC_VER) && (_MSC_VER >= 1400) /* intrinsic byte swapping function in Microsoft Visual C++ 8.0 and later */ unsigned int* uivalues = (unsigned int *) ivalues; /* intrinsic byte swapping function in Microsoft Visual C++ */ for (ii = 0; ii < nvals; ii++) { uivalues[ii] = _byteswap_ulong(uivalues[ii]); } #else char *cvalues, tmp; for (ii = 0; ii < nvals; ii++) { cvalues = (char *)&ivalues[ii]; tmp = cvalues[0]; cvalues[0] = cvalues[3]; cvalues[3] = tmp; tmp = cvalues[1]; cvalues[1] = cvalues[2]; cvalues[2] = tmp; } #endif } /*--------------------------------------------------------------------------*/ #ifdef __SSSE3__ void ffswap4(INT32BIT *ivalues, /* IO - pointer to INT*4 to be swapped */ long nvals) /* I - number of floats to be swapped */ /* swap the bytes in the input 4-byte integer: ( 0 1 2 3 -> 3 2 1 0 ) */ { if ((long)ivalues % 4 != 0) { /* should not happen */ ffswap4_slow(ivalues, nvals); return; } long ii; const __m128i cmask4 = _mm_set_epi8(12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2 ,3); size_t peel = get_peel((void*)&ivalues[0], sizeof(ivalues[0]), nvals, 16); ffswap4_slow(ivalues, peel); for (ii = peel; ii < (nvals - peel - (nvals - peel) % 4); ii+=4) { swap_ssse3((char*)&ivalues[ii], cmask4); } ffswap4_slow(&ivalues[ii], nvals - ii); } #else void ffswap4(INT32BIT *ivalues, /* IO - pointer to INT*4 to be swapped */ long nvals) /* I - number of floats to be swapped */ /* swap the bytes in the input 4-byte integer: ( 0 1 2 3 -> 3 2 1 0 ) */ { ffswap4_slow(ivalues, nvals); } #endif /*--------------------------------------------------------------------------*/ static void ffswap8_slow(double *dvalues, long nvals) { register long ii; #ifdef HAVE_BSWAP LONGLONG * llvalues = (LONGLONG*)dvalues; for (ii = 0; ii < nvals; ii++) { llvalues[ii] = __builtin_bswap64(llvalues[ii]); } #elif defined(_MSC_VER) && (_MSC_VER >= 1400) /* intrinsic byte swapping function in Microsoft Visual C++ 8.0 and later */ unsigned __int64 * llvalues = (unsigned __int64 *) dvalues; for (ii = 0; ii < nvals; ii++) { llvalues[ii] = _byteswap_uint64(llvalues[ii]); } #else register char *cvalues; register char temp; cvalues = (char *) dvalues; /* copy the pointer value */ for (ii = 0; ii < nvals*8; ii += 8) { temp = cvalues[ii]; cvalues[ii] = cvalues[ii+7]; cvalues[ii+7] = temp; temp = cvalues[ii+1]; cvalues[ii+1] = cvalues[ii+6]; cvalues[ii+6] = temp; temp = cvalues[ii+2]; cvalues[ii+2] = cvalues[ii+5]; cvalues[ii+5] = temp; temp = cvalues[ii+3]; cvalues[ii+3] = cvalues[ii+4]; cvalues[ii+4] = temp; } #endif } /*--------------------------------------------------------------------------*/ #ifdef __SSSE3__ void ffswap8(double *dvalues, /* IO - pointer to doubles to be swapped */ long nvals) /* I - number of doubles to be swapped */ /* swap the bytes in the input doubles: ( 01234567 -> 76543210 ) */ { if ((long)dvalues % 8 != 0) { /* should not happen on amd64 */ ffswap8_slow(dvalues, nvals); return; } long ii; const __m128i cmask8 = _mm_set_epi8(8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2 ,3, 4, 5, 6, 7); size_t peel = get_peel((void*)&dvalues[0], sizeof(dvalues[0]), nvals, 16); ffswap8_slow(dvalues, peel); for (ii = peel; ii < (nvals - peel - (nvals - peel) % 2); ii+=2) { swap_ssse3((char*)&dvalues[ii], cmask8); } ffswap8_slow(&dvalues[ii], nvals - ii); } #else void ffswap8(double *dvalues, /* IO - pointer to doubles to be swapped */ long nvals) /* I - number of doubles to be swapped */ /* swap the bytes in the input doubles: ( 01234567 -> 76543210 ) */ { ffswap8_slow(dvalues, nvals); } #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/wcssub.c0000644000175100001710000010470300000000000017602 0ustar00vstsdocker#include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int fits_read_wcstab( fitsfile *fptr, /* I - FITS file pointer */ int nwtb, /* Number of arrays to be read from the binary table(s) */ wtbarr *wtb, /* Address of the first element of an array of wtbarr typedefs. This wtbarr typedef is defined below to match the wtbarr struct defined in WCSLIB. An array of such structs returned by the WCSLIB function wcstab(). */ int *status) /* * Author: Mark Calabretta, Australia Telescope National Facility * http://www.atnf.csiro.au/~mcalabre/index.html * * fits_read_wcstab() extracts arrays from a binary table required in * constructing -TAB coordinates. This helper routine is intended for * use by routines in the WCSLIB library when dealing with the -TAB table * look up WCS convention. */ { int anynul, colnum, hdunum, iwtb, m, naxis, nostat; long *naxes = 0, nelem; wtbarr *wtbp; if (*status) return *status; if (fptr == 0) { return (*status = NULL_INPUT_PTR); } if (nwtb == 0) return 0; /* Zero the array pointers. */ wtbp = wtb; for (iwtb = 0; iwtb < nwtb; iwtb++, wtbp++) { *wtbp->arrayp = 0x0; } /* Save HDU number so that we can move back to it later. */ fits_get_hdu_num(fptr, &hdunum); wtbp = wtb; for (iwtb = 0; iwtb < nwtb; iwtb++, wtbp++) { /* Move to the required binary table extension. */ if (fits_movnam_hdu(fptr, BINARY_TBL, (char *)(wtbp->extnam), wtbp->extver, status)) { goto cleanup; } /* Locate the table column. */ if (fits_get_colnum(fptr, CASEINSEN, (char *)(wtbp->ttype), &colnum, status)) { goto cleanup; } /* Get the array dimensions and check for consistency. */ if (wtbp->ndim < 1) { *status = NEG_AXIS; goto cleanup; } if (!(naxes = calloc(wtbp->ndim, sizeof(long)))) { *status = MEMORY_ALLOCATION; goto cleanup; } if (fits_read_tdim(fptr, colnum, wtbp->ndim, &naxis, naxes, status)) { goto cleanup; } if (naxis != wtbp->ndim) { if (wtbp->kind == 'c' && wtbp->ndim == 2) { /* Allow TDIMn to be omitted for degenerate coordinate arrays. */ naxis = 2; naxes[1] = naxes[0]; naxes[0] = 1; } else { *status = BAD_TDIM; goto cleanup; } } if (wtbp->kind == 'c') { /* Coordinate array; calculate the array size. */ nelem = naxes[0]; for (m = 0; m < naxis-1; m++) { *(wtbp->dimlen + m) = naxes[m+1]; nelem *= naxes[m+1]; } } else { /* Index vector; check length. */ if ((nelem = naxes[0]) != *(wtbp->dimlen)) { /* N.B. coordinate array precedes the index vectors. */ *status = BAD_TDIM; goto cleanup; } } free(naxes); naxes = 0; /* Allocate memory for the array. */ if (!(*wtbp->arrayp = calloc((size_t)nelem, sizeof(double)))) { *status = MEMORY_ALLOCATION; goto cleanup; } /* Read the array from the table. */ if (fits_read_col_dbl(fptr, colnum, wtbp->row, 1L, nelem, 0.0, *wtbp->arrayp, &anynul, status)) { goto cleanup; } } cleanup: /* Move back to the starting HDU. */ nostat = 0; fits_movabs_hdu(fptr, hdunum, 0, &nostat); /* Release allocated memory. */ if (naxes) free(naxes); if (*status) { wtbp = wtb; for (iwtb = 0; iwtb < nwtb; iwtb++, wtbp++) { if (*wtbp->arrayp) free(*wtbp->arrayp); } } return *status; } /*--------------------------------------------------------------------------*/ int ffgiwcs(fitsfile *fptr, /* I - FITS file pointer */ char **header, /* O - pointer to the WCS related keywords */ int *status) /* IO - error status */ /* int fits_get_image_wcs_keys return a string containing all the image WCS header keywords. This string is then used as input to the wcsinit WCSlib routine. THIS ROUTINE IS DEPRECATED. USE fits_hdr2str INSTEAD */ { int hdutype; if (*status > 0) return(*status); fits_get_hdu_type(fptr, &hdutype, status); if (hdutype != IMAGE_HDU) { ffpmsg( "Error in ffgiwcs. This HDU is not an image. Can't read WCS keywords"); return(*status = NOT_IMAGE); } /* read header keywords into a long string of chars */ if (ffh2st(fptr, header, status) > 0) { ffpmsg("error creating string of image WCS keywords (ffgiwcs)"); return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgics(fitsfile *fptr, /* I - FITS file pointer */ double *xrval, /* O - X reference value */ double *yrval, /* O - Y reference value */ double *xrpix, /* O - X reference pixel */ double *yrpix, /* O - Y reference pixel */ double *xinc, /* O - X increment per pixel */ double *yinc, /* O - Y increment per pixel */ double *rot, /* O - rotation angle (degrees) */ char *type, /* O - type of projection ('-tan') */ int *status) /* IO - error status */ /* read the values of the celestial coordinate system keywords. These values may be used as input to the subroutines that calculate celestial coordinates. (ffxypx, ffwldp) Modified in Nov 1999 to convert the CD matrix keywords back to the old CDELTn form, and to swap the axes if the dec-like axis is given first, and to assume default values if any of the keywords are not present. */ { int tstat = 0, cd_exists = 0, pc_exists = 0; char ctype[FLEN_VALUE]; double cd11 = 0.0, cd21 = 0.0, cd22 = 0.0, cd12 = 0.0; double pc11 = 1.0, pc21 = 0.0, pc22 = 1.0, pc12 = 0.0; double pi = 3.1415926535897932; double phia, phib, temp; double toler = .0002; /* tolerance for angles to agree (radians) */ /* (= approximately 0.01 degrees) */ if (*status > 0) return(*status); tstat = 0; if (ffgkyd(fptr, "CRVAL1", xrval, NULL, &tstat)) *xrval = 0.; tstat = 0; if (ffgkyd(fptr, "CRVAL2", yrval, NULL, &tstat)) *yrval = 0.; tstat = 0; if (ffgkyd(fptr, "CRPIX1", xrpix, NULL, &tstat)) *xrpix = 0.; tstat = 0; if (ffgkyd(fptr, "CRPIX2", yrpix, NULL, &tstat)) *yrpix = 0.; /* look for CDELTn first, then CDi_j keywords */ tstat = 0; if (ffgkyd(fptr, "CDELT1", xinc, NULL, &tstat)) { /* CASE 1: no CDELTn keyword, so look for the CD matrix */ tstat = 0; if (ffgkyd(fptr, "CD1_1", &cd11, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else cd_exists = 1; /* found at least 1 CD_ keyword */ if (ffgkyd(fptr, "CD2_1", &cd21, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else cd_exists = 1; /* found at least 1 CD_ keyword */ if (ffgkyd(fptr, "CD1_2", &cd12, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else cd_exists = 1; /* found at least 1 CD_ keyword */ if (ffgkyd(fptr, "CD2_2", &cd22, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else cd_exists = 1; /* found at least 1 CD_ keyword */ if (cd_exists) /* convert CDi_j back to CDELTn */ { /* there are 2 ways to compute the angle: */ phia = atan2( cd21, cd11); phib = atan2(-cd12, cd22); /* ensure that phia <= phib */ temp = minvalue(phia, phib); phib = maxvalue(phia, phib); phia = temp; /* there is a possible 180 degree ambiguity in the angles */ /* so add 180 degress to the smaller value if the values */ /* differ by more than 90 degrees = pi/2 radians. */ /* (Later, we may decide to take the other solution by */ /* subtracting 180 degrees from the larger value). */ if ((phib - phia) > (pi / 2.)) phia += pi; if (fabs(phia - phib) > toler) { /* angles don't agree, so looks like there is some skewness */ /* between the axes. Return with an error to be safe. */ *status = APPROX_WCS_KEY; } phia = (phia + phib) /2.; /* use the average of the 2 values */ *xinc = cd11 / cos(phia); *yinc = cd22 / cos(phia); *rot = phia * 180. / pi; /* common usage is to have a positive yinc value. If it is */ /* negative, then subtract 180 degrees from rot and negate */ /* both xinc and yinc. */ if (*yinc < 0) { *xinc = -(*xinc); *yinc = -(*yinc); *rot = *rot - 180.; } } else /* no CD matrix keywords either */ { *xinc = 1.; /* there was no CDELT1 keyword, but check for CDELT2 just in case */ tstat = 0; if (ffgkyd(fptr, "CDELT2", yinc, NULL, &tstat)) *yinc = 1.; tstat = 0; if (ffgkyd(fptr, "CROTA2", rot, NULL, &tstat)) *rot=0.; } } else /* Case 2: CDELTn + optional PC matrix */ { if (ffgkyd(fptr, "CDELT2", yinc, NULL, &tstat)) *yinc = 1.; tstat = 0; if (ffgkyd(fptr, "CROTA2", rot, NULL, &tstat)) { *rot=0.; /* no CROTA2 keyword, so look for the PC matrix */ tstat = 0; if (ffgkyd(fptr, "PC1_1", &pc11, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else pc_exists = 1; /* found at least 1 PC_ keyword */ if (ffgkyd(fptr, "PC2_1", &pc21, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else pc_exists = 1; /* found at least 1 PC_ keyword */ if (ffgkyd(fptr, "PC1_2", &pc12, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else pc_exists = 1; /* found at least 1 PC_ keyword */ if (ffgkyd(fptr, "PC2_2", &pc22, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else pc_exists = 1; /* found at least 1 PC_ keyword */ if (pc_exists) /* convert PCi_j back to CDELTn */ { /* there are 2 ways to compute the angle: */ phia = atan2( pc21, pc11); phib = atan2(-pc12, pc22); /* ensure that phia <= phib */ temp = minvalue(phia, phib); phib = maxvalue(phia, phib); phia = temp; /* there is a possible 180 degree ambiguity in the angles */ /* so add 180 degress to the smaller value if the values */ /* differ by more than 90 degrees = pi/2 radians. */ /* (Later, we may decide to take the other solution by */ /* subtracting 180 degrees from the larger value). */ if ((phib - phia) > (pi / 2.)) phia += pi; if (fabs(phia - phib) > toler) { /* angles don't agree, so looks like there is some skewness */ /* between the axes. Return with an error to be safe. */ *status = APPROX_WCS_KEY; } phia = (phia + phib) /2.; /* use the average of the 2 values */ *rot = phia * 180. / pi; } } } /* get the type of projection, if any */ tstat = 0; if (ffgkys(fptr, "CTYPE1", ctype, NULL, &tstat)) type[0] = '\0'; else { /* copy the projection type string */ strncpy(type, &ctype[4], 4); type[4] = '\0'; /* check if RA and DEC are inverted */ if (!strncmp(ctype, "DEC-", 4) || !strncmp(ctype+1, "LAT", 3)) { /* the latitudinal axis is given first, so swap them */ /* this case was removed on 12/9. Apparently not correct. if ((*xinc / *yinc) < 0. ) *rot = -90. - (*rot); else */ *rot = 90. - (*rot); /* Empirical tests with ds9 show the y-axis sign must be negated */ /* and the xinc and yinc values must NOT be swapped. */ *yinc = -(*yinc); temp = *xrval; *xrval = *yrval; *yrval = temp; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgicsa(fitsfile *fptr, /* I - FITS file pointer */ char version, /* I - character code of desired version */ /* A - Z or blank */ double *xrval, /* O - X reference value */ double *yrval, /* O - Y reference value */ double *xrpix, /* O - X reference pixel */ double *yrpix, /* O - Y reference pixel */ double *xinc, /* O - X increment per pixel */ double *yinc, /* O - Y increment per pixel */ double *rot, /* O - rotation angle (degrees) */ char *type, /* O - type of projection ('-tan') */ int *status) /* IO - error status */ /* read the values of the celestial coordinate system keywords. These values may be used as input to the subroutines that calculate celestial coordinates. (ffxypx, ffwldp) Modified in Nov 1999 to convert the CD matrix keywords back to the old CDELTn form, and to swap the axes if the dec-like axis is given first, and to assume default values if any of the keywords are not present. */ { int tstat = 0, cd_exists = 0, pc_exists = 0; char ctype[FLEN_VALUE], keyname[FLEN_VALUE], alt[2]; double cd11 = 0.0, cd21 = 0.0, cd22 = 0.0, cd12 = 0.0; double pc11 = 1.0, pc21 = 0.0, pc22 = 1.0, pc12 = 0.0; double pi = 3.1415926535897932; double phia, phib, temp; double toler = .0002; /* tolerance for angles to agree (radians) */ /* (= approximately 0.01 degrees) */ if (*status > 0) return(*status); if (version == ' ') { ffgics(fptr, xrval, yrval, xrpix, yrpix, xinc, yinc, rot, type, status); return (*status); } if (version > 'Z' || version < 'A') { ffpmsg("ffgicsa: illegal WCS version code (must be A - Z or blank)"); return(*status = WCS_ERROR); } alt[0] = version; alt[1] = '\0'; tstat = 0; strcpy(keyname, "CRVAL1"); strcat(keyname, alt); if (ffgkyd(fptr, keyname, xrval, NULL, &tstat)) *xrval = 0.; tstat = 0; strcpy(keyname, "CRVAL2"); strcat(keyname, alt); if (ffgkyd(fptr, keyname, yrval, NULL, &tstat)) *yrval = 0.; tstat = 0; strcpy(keyname, "CRPIX1"); strcat(keyname, alt); if (ffgkyd(fptr, keyname, xrpix, NULL, &tstat)) *xrpix = 0.; tstat = 0; strcpy(keyname, "CRPIX2"); strcat(keyname, alt); if (ffgkyd(fptr, keyname, yrpix, NULL, &tstat)) *yrpix = 0.; /* look for CDELTn first, then CDi_j keywords */ tstat = 0; strcpy(keyname, "CDELT1"); strcat(keyname, alt); if (ffgkyd(fptr, keyname, xinc, NULL, &tstat)) { /* CASE 1: no CDELTn keyword, so look for the CD matrix */ tstat = 0; strcpy(keyname, "CD1_1"); strcat(keyname, alt); if (ffgkyd(fptr, keyname, &cd11, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else cd_exists = 1; /* found at least 1 CD_ keyword */ strcpy(keyname, "CD2_1"); strcat(keyname, alt); if (ffgkyd(fptr, keyname, &cd21, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else cd_exists = 1; /* found at least 1 CD_ keyword */ strcpy(keyname, "CD1_2"); strcat(keyname, alt); if (ffgkyd(fptr, keyname, &cd12, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else cd_exists = 1; /* found at least 1 CD_ keyword */ strcpy(keyname, "CD2_2"); strcat(keyname, alt); if (ffgkyd(fptr, keyname, &cd22, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else cd_exists = 1; /* found at least 1 CD_ keyword */ if (cd_exists) /* convert CDi_j back to CDELTn */ { /* there are 2 ways to compute the angle: */ phia = atan2( cd21, cd11); phib = atan2(-cd12, cd22); /* ensure that phia <= phib */ temp = minvalue(phia, phib); phib = maxvalue(phia, phib); phia = temp; /* there is a possible 180 degree ambiguity in the angles */ /* so add 180 degress to the smaller value if the values */ /* differ by more than 90 degrees = pi/2 radians. */ /* (Later, we may decide to take the other solution by */ /* subtracting 180 degrees from the larger value). */ if ((phib - phia) > (pi / 2.)) phia += pi; if (fabs(phia - phib) > toler) { /* angles don't agree, so looks like there is some skewness */ /* between the axes. Return with an error to be safe. */ *status = APPROX_WCS_KEY; } phia = (phia + phib) /2.; /* use the average of the 2 values */ *xinc = cd11 / cos(phia); *yinc = cd22 / cos(phia); *rot = phia * 180. / pi; /* common usage is to have a positive yinc value. If it is */ /* negative, then subtract 180 degrees from rot and negate */ /* both xinc and yinc. */ if (*yinc < 0) { *xinc = -(*xinc); *yinc = -(*yinc); *rot = *rot - 180.; } } else /* no CD matrix keywords either */ { *xinc = 1.; /* there was no CDELT1 keyword, but check for CDELT2 just in case */ tstat = 0; strcpy(keyname, "CDELT2"); strcat(keyname, alt); if (ffgkyd(fptr, keyname, yinc, NULL, &tstat)) *yinc = 1.; tstat = 0; strcpy(keyname, "CROTA2"); strcat(keyname, alt); if (ffgkyd(fptr, keyname, rot, NULL, &tstat)) *rot=0.; } } else /* Case 2: CDELTn + optional PC matrix */ { strcpy(keyname, "CDELT2"); strcat(keyname, alt); if (ffgkyd(fptr, keyname, yinc, NULL, &tstat)) *yinc = 1.; tstat = 0; strcpy(keyname, "CROTA2"); strcat(keyname, alt); if (ffgkyd(fptr, keyname, rot, NULL, &tstat)) { *rot=0.; /* no CROTA2 keyword, so look for the PC matrix */ tstat = 0; strcpy(keyname, "PC1_1"); strcat(keyname, alt); if (ffgkyd(fptr, keyname, &pc11, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else pc_exists = 1; /* found at least 1 PC_ keyword */ strcpy(keyname, "PC2_1"); strcat(keyname, alt); if (ffgkyd(fptr, keyname, &pc21, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else pc_exists = 1; /* found at least 1 PC_ keyword */ strcpy(keyname, "PC1_2"); strcat(keyname, alt); if (ffgkyd(fptr, keyname, &pc12, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else pc_exists = 1; /* found at least 1 PC_ keyword */ strcpy(keyname, "PC2_2"); strcat(keyname, alt); if (ffgkyd(fptr, keyname, &pc22, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else pc_exists = 1; /* found at least 1 PC_ keyword */ if (pc_exists) /* convert PCi_j back to CDELTn */ { /* there are 2 ways to compute the angle: */ phia = atan2( pc21, pc11); phib = atan2(-pc12, pc22); /* ensure that phia <= phib */ temp = minvalue(phia, phib); phib = maxvalue(phia, phib); phia = temp; /* there is a possible 180 degree ambiguity in the angles */ /* so add 180 degress to the smaller value if the values */ /* differ by more than 90 degrees = pi/2 radians. */ /* (Later, we may decide to take the other solution by */ /* subtracting 180 degrees from the larger value). */ if ((phib - phia) > (pi / 2.)) phia += pi; if (fabs(phia - phib) > toler) { /* angles don't agree, so looks like there is some skewness */ /* between the axes. Return with an error to be safe. */ *status = APPROX_WCS_KEY; } phia = (phia + phib) /2.; /* use the average of the 2 values */ *rot = phia * 180. / pi; } } } /* get the type of projection, if any */ tstat = 0; strcpy(keyname, "CTYPE1"); strcat(keyname, alt); if (ffgkys(fptr, keyname, ctype, NULL, &tstat)) type[0] = '\0'; else { /* copy the projection type string */ strncpy(type, &ctype[4], 4); type[4] = '\0'; /* check if RA and DEC are inverted */ if (!strncmp(ctype, "DEC-", 4) || !strncmp(ctype+1, "LAT", 3)) { /* the latitudinal axis is given first, so swap them */ *rot = 90. - (*rot); /* Empirical tests with ds9 show the y-axis sign must be negated */ /* and the xinc and yinc values must NOT be swapped. */ *yinc = -(*yinc); temp = *xrval; *xrval = *yrval; *yrval = temp; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgtcs(fitsfile *fptr, /* I - FITS file pointer */ int xcol, /* I - column containing the RA coordinate */ int ycol, /* I - column containing the DEC coordinate */ double *xrval, /* O - X reference value */ double *yrval, /* O - Y reference value */ double *xrpix, /* O - X reference pixel */ double *yrpix, /* O - Y reference pixel */ double *xinc, /* O - X increment per pixel */ double *yinc, /* O - Y increment per pixel */ double *rot, /* O - rotation angle (degrees) */ char *type, /* O - type of projection ('-sin') */ int *status) /* IO - error status */ /* read the values of the celestial coordinate system keywords from a FITS table where the X and Y or RA and DEC coordinates are stored in separate column. Do this by converting the table to a temporary FITS image, then reading the keywords from the image file. These values may be used as input to the subroutines that calculate celestial coordinates. (ffxypx, ffwldp) */ { int colnum[2]; long naxes[2]; fitsfile *tptr; if (*status > 0) return(*status); colnum[0] = xcol; colnum[1] = ycol; naxes[0] = 10; naxes[1] = 10; /* create temporary FITS file, in memory */ ffinit(&tptr, "mem://", status); /* create a temporary image; the datatype and size are not important */ ffcrim(tptr, 32, 2, naxes, status); /* now copy the relevant keywords from the table to the image */ fits_copy_pixlist2image(fptr, tptr, 9, 2, colnum, status); /* write default WCS keywords, if they are not present */ fits_write_keys_histo(fptr, tptr, 2, colnum, status); if (*status > 0) return(*status); /* read the WCS keyword values from the temporary image */ ffgics(tptr, xrval, yrval, xrpix, yrpix, xinc, yinc, rot, type, status); if (*status > 0) { ffpmsg ("ffgtcs could not find all the celestial coordinate keywords"); return(*status = NO_WCS_KEY); } /* delete the temporary file */ fits_delete_file(tptr, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgtwcs(fitsfile *fptr, /* I - FITS file pointer */ int xcol, /* I - column number for the X column */ int ycol, /* I - column number for the Y column */ char **header, /* O - string of all the WCS keywords */ int *status) /* IO - error status */ /* int fits_get_table_wcs_keys Return string containing all the WCS keywords appropriate for the pair of X and Y columns containing the coordinate of each event in an event list table. This string may then be passed to Doug Mink's WCS library wcsinit routine, to create and initialize the WCS structure. The calling routine must free the header character string when it is no longer needed. THIS ROUTINE IS DEPRECATED. USE fits_hdr2str INSTEAD */ { int hdutype, ncols, tstatus, length; int naxis1 = 1, naxis2 = 1; long tlmin, tlmax; char keyname[FLEN_KEYWORD]; char valstring[FLEN_VALUE]; char comm[2]; char *cptr; /* construct a string of 80 blanks, for adding fill to the keywords */ /* 12345678901234567890123456789012345678901234567890123456789012345678901234567890 */ char blanks[] = " "; if (*status > 0) return(*status); fits_get_hdu_type(fptr, &hdutype, status); if (hdutype == IMAGE_HDU) { ffpmsg("Can't read table WSC keywords. This HDU is not a table"); return(*status = NOT_TABLE); } fits_get_num_cols(fptr, &ncols, status); if (xcol < 1 || xcol > ncols) { ffpmsg("illegal X axis column number in fftwcs"); return(*status = BAD_COL_NUM); } if (ycol < 1 || ycol > ncols) { ffpmsg("illegal Y axis column number in fftwcs"); return(*status = BAD_COL_NUM); } /* allocate character string for all the WCS keywords */ *header = calloc(1, 2401); /* room for up to 30 keywords */ if (*header == 0) { ffpmsg("error allocating memory for WCS header keywords (fftwcs)"); return(*status = MEMORY_ALLOCATION); } cptr = *header; comm[0] = '\0'; tstatus = 0; ffkeyn("TLMIN",xcol,keyname,status); ffgkyj(fptr,keyname, &tlmin,NULL,&tstatus); if (!tstatus) { ffkeyn("TLMAX",xcol,keyname,status); ffgkyj(fptr,keyname, &tlmax,NULL,&tstatus); } if (!tstatus) { naxis1 = tlmax - tlmin + 1; } tstatus = 0; ffkeyn("TLMIN",ycol,keyname,status); ffgkyj(fptr,keyname, &tlmin,NULL,&tstatus); if (!tstatus) { ffkeyn("TLMAX",ycol,keyname,status); ffgkyj(fptr,keyname, &tlmax,NULL,&tstatus); } if (!tstatus) { naxis2 = tlmax - tlmin + 1; } /* 123456789012345678901234567890 */ strcat(cptr, "NAXIS = 2"); strncat(cptr, blanks, 50); cptr += 80; ffi2c(naxis1, valstring, status); /* convert to formatted string */ ffmkky("NAXIS1", valstring, comm, cptr, status); /* construct the keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; strcpy(keyname, "NAXIS2"); ffi2c(naxis2, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, cptr, status); /* construct the keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; /* read the required header keywords (use defaults if not found) */ /* CTYPE1 keyword */ tstatus = 0; ffkeyn("TCTYP",xcol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) ) valstring[0] = '\0'; ffmkky("CTYPE1", valstring, comm, cptr, status); /* construct the keyword*/ length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; /* CTYPE2 keyword */ tstatus = 0; ffkeyn("TCTYP",ycol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) ) valstring[0] = '\0'; ffmkky("CTYPE2", valstring, comm, cptr, status); /* construct the keyword*/ length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; /* CRPIX1 keyword */ tstatus = 0; ffkeyn("TCRPX",xcol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) ) strcpy(valstring, "1"); ffmkky("CRPIX1", valstring, comm, cptr, status); /* construct the keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; /* CRPIX2 keyword */ tstatus = 0; ffkeyn("TCRPX",ycol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) ) strcpy(valstring, "1"); ffmkky("CRPIX2", valstring, comm, cptr, status); /* construct the keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; /* CRVAL1 keyword */ tstatus = 0; ffkeyn("TCRVL",xcol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) ) strcpy(valstring, "1"); ffmkky("CRVAL1", valstring, comm, cptr, status); /* construct the keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; /* CRVAL2 keyword */ tstatus = 0; ffkeyn("TCRVL",ycol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) ) strcpy(valstring, "1"); ffmkky("CRVAL2", valstring, comm, cptr, status); /* construct the keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; /* CDELT1 keyword */ tstatus = 0; ffkeyn("TCDLT",xcol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) ) strcpy(valstring, "1"); ffmkky("CDELT1", valstring, comm, cptr, status); /* construct the keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; /* CDELT2 keyword */ tstatus = 0; ffkeyn("TCDLT",ycol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) ) strcpy(valstring, "1"); ffmkky("CDELT2", valstring, comm, cptr, status); /* construct the keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; /* the following keywords may not exist */ /* CROTA2 keyword */ tstatus = 0; ffkeyn("TCROT",ycol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) == 0 ) { ffmkky("CROTA2", valstring, comm, cptr, status); /* construct keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; } /* EPOCH keyword */ tstatus = 0; if (ffgkey(fptr, "EPOCH", valstring, NULL, &tstatus) == 0 ) { ffmkky("EPOCH", valstring, comm, cptr, status); /* construct keyword*/ length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } /* EQUINOX keyword */ tstatus = 0; if (ffgkey(fptr, "EQUINOX", valstring, NULL, &tstatus) == 0 ) { ffmkky("EQUINOX", valstring, comm, cptr, status); /* construct keyword*/ length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } /* RADECSYS keyword */ tstatus = 0; if (ffgkey(fptr, "RADECSYS", valstring, NULL, &tstatus) == 0 ) { ffmkky("RADECSYS", valstring, comm, cptr, status); /*construct keyword*/ length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } /* TELESCOPE keyword */ tstatus = 0; if (ffgkey(fptr, "TELESCOP", valstring, NULL, &tstatus) == 0 ) { ffmkky("TELESCOP", valstring, comm, cptr, status); length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } /* INSTRUME keyword */ tstatus = 0; if (ffgkey(fptr, "INSTRUME", valstring, NULL, &tstatus) == 0 ) { ffmkky("INSTRUME", valstring, comm, cptr, status); length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } /* DETECTOR keyword */ tstatus = 0; if (ffgkey(fptr, "DETECTOR", valstring, NULL, &tstatus) == 0 ) { ffmkky("DETECTOR", valstring, comm, cptr, status); length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } /* MJD-OBS keyword */ tstatus = 0; if (ffgkey(fptr, "MJD-OBS", valstring, NULL, &tstatus) == 0 ) { ffmkky("MJD-OBS", valstring, comm, cptr, status); length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } /* DATE-OBS keyword */ tstatus = 0; if (ffgkey(fptr, "DATE-OBS", valstring, NULL, &tstatus) == 0 ) { ffmkky("DATE-OBS", valstring, comm, cptr, status); length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } /* DATE keyword */ tstatus = 0; if (ffgkey(fptr, "DATE", valstring, NULL, &tstatus) == 0 ) { ffmkky("DATE", valstring, comm, cptr, status); length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } strcat(cptr, "END"); strncat(cptr, blanks, 77); return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/wcsutil.c0000644000175100001710000004060100000000000017762 0ustar00vstsdocker#include #include "fitsio2.h" #define D2R 0.01745329252 #define TWOPI 6.28318530717959 /*--------------------------------------------------------------------------*/ int ffwldp(double xpix, double ypix, double xref, double yref, double xrefpix, double yrefpix, double xinc, double yinc, double rot, char *type, double *xpos, double *ypos, int *status) /* This routine is based on the classic AIPS WCS routine. It converts from pixel location to RA,Dec for 9 projective geometries: "-CAR", "-SIN", "-TAN", "-ARC", "-NCP", "-GLS", "-MER", "-AIT" and "-STG". */ /*-----------------------------------------------------------------------*/ /* routine to determine accurate position for pixel coordinates */ /* returns 0 if successful otherwise: */ /* 501 = angle too large for projection; */ /* does: -CAR, -SIN, -TAN, -ARC, -NCP, -GLS, -MER, -AIT -STG projections*/ /* Input: */ /* f xpix x pixel number (RA or long without rotation) */ /* f ypiy y pixel number (dec or lat without rotation) */ /* d xref x reference coordinate value (deg) */ /* d yref y reference coordinate value (deg) */ /* f xrefpix x reference pixel */ /* f yrefpix y reference pixel */ /* f xinc x coordinate increment (deg) */ /* f yinc y coordinate increment (deg) */ /* f rot rotation (deg) (from N through E) */ /* c *type projection type code e.g. "-SIN"; */ /* Output: */ /* d *xpos x (RA) coordinate (deg) */ /* d *ypos y (dec) coordinate (deg) */ /*-----------------------------------------------------------------------*/ {double cosr, sinr, dx, dy, dz, temp, x, y, z; double sins, coss, dect, rat, dt, l, m, mg, da, dd, cos0, sin0; double dec0, ra0; double geo1, geo2, geo3; double deps = 1.0e-5; char *cptr; if (*status > 0) return(*status); /* Offset from ref pixel */ dx = (xpix-xrefpix) * xinc; dy = (ypix-yrefpix) * yinc; /* Take out rotation */ cosr = cos(rot * D2R); sinr = sin(rot * D2R); if (rot != 0.0) { temp = dx * cosr - dy * sinr; dy = dy * cosr + dx * sinr; dx = temp; } /* convert to radians */ ra0 = xref * D2R; dec0 = yref * D2R; l = dx * D2R; m = dy * D2R; sins = l*l + m*m; cos0 = cos(dec0); sin0 = sin(dec0); if (*type != '-') { /* unrecognized projection code */ return(*status = 504); } cptr = type + 1; if (*cptr == 'C') { /* linear -CAR */ if (*(cptr + 1) != 'A' || *(cptr + 2) != 'R') { return(*status = 504); } rat = ra0 + l; dect = dec0 + m; } else if (*cptr == 'T') { /* -TAN */ if (*(cptr + 1) != 'A' || *(cptr + 2) != 'N') { return(*status = 504); } x = cos0*cos(ra0) - l*sin(ra0) - m*cos(ra0)*sin0; y = cos0*sin(ra0) + l*cos(ra0) - m*sin(ra0)*sin0; z = sin0 + m* cos0; rat = atan2( y, x ); dect = atan ( z / sqrt(x*x+y*y) ); } else if (*cptr == 'S') { if (*(cptr + 1) == 'I' && *(cptr + 2) == 'N') { /* -SIN */ if (sins>1.0) return(*status = 501); coss = sqrt (1.0 - sins); dt = sin0 * coss + cos0 * m; if ((dt>1.0) || (dt<-1.0)) return(*status = 501); dect = asin (dt); rat = cos0 * coss - sin0 * m; if ((rat==0.0) && (l==0.0)) return(*status = 501); rat = atan2 (l, rat) + ra0; } else if (*(cptr + 1) == 'T' && *(cptr + 2) == 'G') { /* -STG Sterographic*/ dz = (4.0 - sins) / (4.0 + sins); if (fabs(dz)>1.0) return(*status = 501); dect = dz * sin0 + m * cos0 * (1.0+dz) / 2.0; if (fabs(dect)>1.0) return(*status = 501); dect = asin (dect); rat = cos(dect); if (fabs(rat)1.0) return(*status = 501); rat = asin (rat); mg = 1.0 + sin(dect) * sin0 + cos(dect) * cos0 * cos(rat); if (fabs(mg)deps) rat = TWOPI /2.0 - rat; rat = ra0 + rat; } else { return(*status = 504); } } else if (*cptr == 'A') { if (*(cptr + 1) == 'R' && *(cptr + 2) == 'C') { /* ARC */ if (sins>=TWOPI*TWOPI/4.0) return(*status = 501); sins = sqrt(sins); coss = cos (sins); if (sins!=0.0) sins = sin (sins) / sins; else sins = 1.0; dt = m * cos0 * sins + sin0 * coss; if ((dt>1.0) || (dt<-1.0)) return(*status = 501); dect = asin (dt); da = coss - dt * sin0; dt = l * sins * cos0; if ((da==0.0) && (dt==0.0)) return(*status = 501); rat = ra0 + atan2 (dt, da); } else if (*(cptr + 1) == 'I' && *(cptr + 2) == 'T') { /* -AIT Aitoff */ dt = yinc*cosr + xinc*sinr; if (dt==0.0) dt = 1.0; dt = dt * D2R; dy = yref * D2R; dx = sin(dy+dt)/sqrt((1.0+cos(dy+dt))/2.0) - sin(dy)/sqrt((1.0+cos(dy))/2.0); if (dx==0.0) dx = 1.0; geo2 = dt / dx; dt = xinc*cosr - yinc* sinr; if (dt==0.0) dt = 1.0; dt = dt * D2R; dx = 2.0 * cos(dy) * sin(dt/2.0); if (dx==0.0) dx = 1.0; geo1 = dt * sqrt((1.0+cos(dy)*cos(dt/2.0))/2.0) / dx; geo3 = geo2 * sin(dy) / sqrt((1.0+cos(dy))/2.0); rat = ra0; dect = dec0; if ((l != 0.0) || (m != 0.0)) { dz = 4.0 - l*l/(4.0*geo1*geo1) - ((m+geo3)/geo2)*((m+geo3)/geo2) ; if ((dz>4.0) || (dz<2.0)) return(*status = 501); dz = 0.5 * sqrt (dz); dd = (m+geo3) * dz / geo2; if (fabs(dd)>1.0) return(*status = 501); dd = asin (dd); if (fabs(cos(dd))1.0) return(*status = 501); da = asin (da); rat = ra0 + 2.0 * da; dect = dd; } } else { return(*status = 504); } } else if (*cptr == 'N') { /* -NCP North celestial pole*/ if (*(cptr + 1) != 'C' || *(cptr + 2) != 'P') { return(*status = 504); } dect = cos0 - m * sin0; if (dect==0.0) return(*status = 501); rat = ra0 + atan2 (l, dect); dt = cos (rat-ra0); if (dt==0.0) return(*status = 501); dect = dect / dt; if ((dect>1.0) || (dect<-1.0)) return(*status = 501); dect = acos (dect); if (dec0<0.0) dect = -dect; } else if (*cptr == 'G') { /* -GLS global sinusoid */ if (*(cptr + 1) != 'L' || *(cptr + 2) != 'S') { return(*status = 504); } dect = dec0 + m; if (fabs(dect)>TWOPI/4.0) return(*status = 501); coss = cos (dect); if (fabs(l)>TWOPI*coss/2.0) return(*status = 501); rat = ra0; if (coss>deps) rat = rat + l / coss; } else if (*cptr == 'M') { /* -MER mercator*/ if (*(cptr + 1) != 'E' || *(cptr + 2) != 'R') { return(*status = 504); } dt = yinc * cosr + xinc * sinr; if (dt==0.0) dt = 1.0; dy = (yref/2.0 + 45.0) * D2R; dx = dy + dt / 2.0 * D2R; dy = log (tan (dy)); dx = log (tan (dx)); geo2 = dt * D2R / (dx - dy); geo3 = geo2 * dy; geo1 = cos (yref*D2R); if (geo1<=0.0) geo1 = 1.0; rat = l / geo1 + ra0; if (fabs(rat - ra0) > TWOPI) return(*status = 501); dt = 0.0; if (geo2!=0.0) dt = (m + geo3) / geo2; dt = exp (dt); dect = 2.0 * atan (dt) - TWOPI / 4.0; } else { return(*status = 504); } /* correct for RA rollover */ if (rat-ra0>TWOPI/2.0) rat = rat - TWOPI; if (rat-ra0<-TWOPI/2.0) rat = rat + TWOPI; if (rat < 0.0) rat += TWOPI; /* convert to degrees */ *xpos = rat / D2R; *ypos = dect / D2R; return(*status); } /*--------------------------------------------------------------------------*/ int ffxypx(double xpos, double ypos, double xref, double yref, double xrefpix, double yrefpix, double xinc, double yinc, double rot, char *type, double *xpix, double *ypix, int *status) /* This routine is based on the classic AIPS WCS routine. It converts from RA,Dec to pixel location to for 9 projective geometries: "-CAR", "-SIN", "-TAN", "-ARC", "-NCP", "-GLS", "-MER", "-AIT" and "-STG". */ /*-----------------------------------------------------------------------*/ /* routine to determine accurate pixel coordinates for an RA and Dec */ /* returns 0 if successful otherwise: */ /* 501 = angle too large for projection; */ /* 502 = bad values */ /* does: -SIN, -TAN, -ARC, -NCP, -GLS, -MER, -AIT projections */ /* anything else is linear */ /* Input: */ /* d xpos x (RA) coordinate (deg) */ /* d ypos y (dec) coordinate (deg) */ /* d xref x reference coordinate value (deg) */ /* d yref y reference coordinate value (deg) */ /* f xrefpix x reference pixel */ /* f yrefpix y reference pixel */ /* f xinc x coordinate increment (deg) */ /* f yinc y coordinate increment (deg) */ /* f rot rotation (deg) (from N through E) */ /* c *type projection type code e.g. "-SIN"; */ /* Output: */ /* f *xpix x pixel number (RA or long without rotation) */ /* f *ypiy y pixel number (dec or lat without rotation) */ /*-----------------------------------------------------------------------*/ { double dx, dy, dz, r, ra0, dec0, ra, dec, coss, sins, dt, da, dd, sint; double l, m, geo1, geo2, geo3, sinr, cosr, cos0, sin0; double deps=1.0e-5; char *cptr; if (*type != '-') { /* unrecognized projection code */ return(*status = 504); } cptr = type + 1; dt = (xpos - xref); if (dt > 180) xpos -= 360; if (dt < -180) xpos += 360; /* NOTE: changing input argument xpos is OK (call-by-value in C!) */ /* default values - linear */ dx = xpos - xref; dy = ypos - yref; /* Correct for rotation */ r = rot * D2R; cosr = cos (r); sinr = sin (r); dz = dx*cosr + dy*sinr; dy = dy*cosr - dx*sinr; dx = dz; /* check axis increments - bail out if either 0 */ if ((xinc==0.0) || (yinc==0.0)) {*xpix=0.0; *ypix=0.0; return(*status = 502);} /* convert to pixels */ *xpix = dx / xinc + xrefpix; *ypix = dy / yinc + yrefpix; if (*cptr == 'C') { /* linear -CAR */ if (*(cptr + 1) != 'A' || *(cptr + 2) != 'R') { return(*status = 504); } return(*status); /* done if linear */ } /* Non linear position */ ra0 = xref * D2R; dec0 = yref * D2R; ra = xpos * D2R; dec = ypos * D2R; /* compute direction cosine */ coss = cos (dec); sins = sin (dec); cos0 = cos (dec0); sin0 = sin (dec0); l = sin(ra-ra0) * coss; sint = sins * sin0 + coss * cos0 * cos(ra-ra0); /* process by case */ if (*cptr == 'T') { /* -TAN tan */ if (*(cptr + 1) != 'A' || *(cptr + 2) != 'N') { return(*status = 504); } if (sint<=0.0) return(*status = 501); if( cos0<0.001 ) { /* Do a first order expansion around pole */ m = (coss * cos(ra-ra0)) / (sins * sin0); m = (-m + cos0 * (1.0 + m*m)) / sin0; } else { m = ( sins/sint - sin0 ) / cos0; } if( fabs(sin(ra0)) < 0.3 ) { l = coss*sin(ra)/sint - cos0*sin(ra0) + m*sin(ra0)*sin0; l /= cos(ra0); } else { l = coss*cos(ra)/sint - cos0*cos(ra0) + m*cos(ra0)*sin0; l /= -sin(ra0); } } else if (*cptr == 'S') { if (*(cptr + 1) == 'I' && *(cptr + 2) == 'N') { /* -SIN */ if (sint<0.0) return(*status = 501); m = sins * cos(dec0) - coss * sin(dec0) * cos(ra-ra0); } else if (*(cptr + 1) == 'T' && *(cptr + 2) == 'G') { /* -STG Sterographic*/ da = ra - ra0; if (fabs(dec)>TWOPI/4.0) return(*status = 501); dd = 1.0 + sins * sin(dec0) + coss * cos(dec0) * cos(da); if (fabs(dd)1.0) m = 1.0; m = acos (m); if (m!=0) m = m / sin(m); else m = 1.0; l = l * m; m = (sins * cos(dec0) - coss * sin(dec0) * cos(ra-ra0)) * m; } else if (*(cptr + 1) == 'I' && *(cptr + 2) == 'T') { /* -AIT Aitoff */ da = (ra - ra0) / 2.0; if (fabs(da)>TWOPI/4.0) return(*status = 501); dt = yinc*cosr + xinc*sinr; if (dt==0.0) dt = 1.0; dt = dt * D2R; dy = yref * D2R; dx = sin(dy+dt)/sqrt((1.0+cos(dy+dt))/2.0) - sin(dy)/sqrt((1.0+cos(dy))/2.0); if (dx==0.0) dx = 1.0; geo2 = dt / dx; dt = xinc*cosr - yinc* sinr; if (dt==0.0) dt = 1.0; dt = dt * D2R; dx = 2.0 * cos(dy) * sin(dt/2.0); if (dx==0.0) dx = 1.0; geo1 = dt * sqrt((1.0+cos(dy)*cos(dt/2.0))/2.0) / dx; geo3 = geo2 * sin(dy) / sqrt((1.0+cos(dy))/2.0); dt = sqrt ((1.0 + cos(dec) * cos(da))/2.0); if (fabs(dt)TWOPI/4.0) return(*status = 501); if (fabs(dec0)>TWOPI/4.0) return(*status = 501); m = dec - dec0; l = dt * coss; } else if (*cptr == 'M') { /* -MER mercator*/ if (*(cptr + 1) != 'E' || *(cptr + 2) != 'R') { return(*status = 504); } dt = yinc * cosr + xinc * sinr; if (dt==0.0) dt = 1.0; dy = (yref/2.0 + 45.0) * D2R; dx = dy + dt / 2.0 * D2R; dy = log (tan (dy)); dx = log (tan (dx)); geo2 = dt * D2R / (dx - dy); geo3 = geo2 * dy; geo1 = cos (yref*D2R); if (geo1<=0.0) geo1 = 1.0; dt = ra - ra0; l = geo1 * dt; dt = dec / 2.0 + TWOPI / 8.0; dt = tan (dt); if (dt #include #include #include #include #include "zlib.h" #define GZBUFSIZE 115200 /* 40 FITS blocks */ #define BUFFINCR 28800 /* 10 FITS blocks */ /* prototype for the following functions */ int uncompress2mem(char *filename, FILE *diskfile, char **buffptr, size_t *buffsize, void *(*mem_realloc)(void *p, size_t newsize), size_t *filesize, int *status); int uncompress2mem_from_mem( char *inmemptr, size_t inmemsize, char **buffptr, size_t *buffsize, void *(*mem_realloc)(void *p, size_t newsize), size_t *filesize, int *status); int uncompress2file(char *filename, FILE *indiskfile, FILE *outdiskfile, int *status); int compress2mem_from_mem( char *inmemptr, size_t inmemsize, char **buffptr, size_t *buffsize, void *(*mem_realloc)(void *p, size_t newsize), size_t *filesize, int *status); int compress2file_from_mem( char *inmemptr, size_t inmemsize, FILE *outdiskfile, size_t *filesize, /* O - size of file, in bytes */ int *status); /*--------------------------------------------------------------------------*/ int uncompress2mem(char *filename, /* name of input file */ FILE *diskfile, /* I - file pointer */ char **buffptr, /* IO - memory pointer */ size_t *buffsize, /* IO - size of buffer, in bytes */ void *(*mem_realloc)(void *p, size_t newsize), /* function */ size_t *filesize, /* O - size of file, in bytes */ int *status) /* IO - error status */ /* Uncompress the disk file into memory. Fill whatever amount of memory has already been allocated, then realloc more memory, using the supplied input function, if necessary. */ { int err, len; char *filebuff; z_stream d_stream; /* decompression stream */ /* Input args buffptr and buffsize may refer to a block of memory larger than the 2^32 4 byte limit. If so, must be broken up into "pages" when assigned to d_stream. (d_stream.avail_out is a uInt type, which might be smaller than buffsize's size_t type.) */ const uLong nPages = (uLong)(*buffsize)/(uLong)UINT_MAX; uLong iPage=0; uInt outbuffsize = (nPages > 0) ? UINT_MAX : (uInt)(*buffsize); if (*status > 0) return(*status); /* Allocate memory to hold compressed bytes read from the file. */ filebuff = (char*)malloc(GZBUFSIZE); if (!filebuff) return(*status = 113); /* memory error */ d_stream.zalloc = (alloc_func)0; d_stream.zfree = (free_func)0; d_stream.opaque = (voidpf)0; d_stream.next_out = (unsigned char*) *buffptr; d_stream.avail_out = outbuffsize; /* Initialize the decompression. The argument (15+16) tells the decompressor that we are to use the gzip algorithm */ err = inflateInit2(&d_stream, (15+16)); if (err != Z_OK) return(*status = 414); /* loop through the file, reading a buffer and uncompressing it */ for (;;) { len = fread(filebuff, 1, GZBUFSIZE, diskfile); if (ferror(diskfile)) { inflateEnd(&d_stream); free(filebuff); return(*status = 414); } if (len == 0) break; /* no more data */ d_stream.next_in = (unsigned char*)filebuff; d_stream.avail_in = len; for (;;) { /* uncompress as much of the input as will fit in the output */ err = inflate(&d_stream, Z_NO_FLUSH); if (err == Z_STREAM_END ) { /* We reached the end of the input */ break; } else if (err == Z_OK ) { if (!d_stream.avail_in) break; /* need more input */ /* need more space in output buffer */ /* First check if more memory is available above the 4Gb limit in the originally input buffptr array */ if (iPage < nPages) { ++iPage; d_stream.next_out = (unsigned char*)(*buffptr + iPage*(uLong)UINT_MAX); if (iPage < nPages) d_stream.avail_out = UINT_MAX; else d_stream.avail_out = (uInt)((uLong)(*buffsize) % (uLong)UINT_MAX); } else if (mem_realloc) { *buffptr = mem_realloc(*buffptr,*buffsize + BUFFINCR); if (*buffptr == NULL){ inflateEnd(&d_stream); free(filebuff); return(*status = 414); /* memory allocation failed */ } d_stream.avail_out = BUFFINCR; d_stream.next_out = (unsigned char*) (*buffptr + *buffsize); *buffsize = *buffsize + BUFFINCR; } else { /* error: no realloc function available */ inflateEnd(&d_stream); free(filebuff); return(*status = 414); } } else { /* some other error */ inflateEnd(&d_stream); free(filebuff); return(*status = 414); } } if (feof(diskfile)) break; /* These settings for next_out and avail_out appear to be redundant, as the inflate() function should already be re-setting these. For case where *buffsize < 4Gb this did not matter, but for > 4Gb it would produce the wrong value in the avail_out assignment. (C. Gordon Jul 2016) d_stream.next_out = (unsigned char*) (*buffptr + d_stream.total_out); d_stream.avail_out = *buffsize - d_stream.total_out; */ } /* Set the output file size to be the total output data */ *filesize = d_stream.total_out; free(filebuff); /* free temporary output data buffer */ err = inflateEnd(&d_stream); /* End the decompression */ if (err != Z_OK) return(*status = 414); return(*status); } /*--------------------------------------------------------------------------*/ int uncompress2mem_from_mem( char *inmemptr, /* I - memory pointer to compressed bytes */ size_t inmemsize, /* I - size of input compressed file */ char **buffptr, /* IO - memory pointer */ size_t *buffsize, /* IO - size of buffer, in bytes */ void *(*mem_realloc)(void *p, size_t newsize), /* function */ size_t *filesize, /* O - size of file, in bytes */ int *status) /* IO - error status */ /* Uncompress the file in memory into memory. Fill whatever amount of memory has already been allocated, then realloc more memory, using the supplied input function, if necessary. */ { int err; z_stream d_stream; /* decompression stream */ if (*status > 0) return(*status); d_stream.zalloc = (alloc_func)0; d_stream.zfree = (free_func)0; d_stream.opaque = (voidpf)0; /* Initialize the decompression. The argument (15+16) tells the decompressor that we are to use the gzip algorithm */ err = inflateInit2(&d_stream, (15+16)); if (err != Z_OK) return(*status = 414); d_stream.next_in = (unsigned char*)inmemptr; d_stream.avail_in = inmemsize; d_stream.next_out = (unsigned char*) *buffptr; d_stream.avail_out = *buffsize; for (;;) { /* uncompress as much of the input as will fit in the output */ err = inflate(&d_stream, Z_NO_FLUSH); if (err == Z_STREAM_END) { /* We reached the end of the input */ break; } else if (err == Z_OK ) { /* need more space in output buffer */ if (mem_realloc) { *buffptr = mem_realloc(*buffptr,*buffsize + BUFFINCR); if (*buffptr == NULL){ inflateEnd(&d_stream); return(*status = 414); /* memory allocation failed */ } d_stream.avail_out = BUFFINCR; d_stream.next_out = (unsigned char*) (*buffptr + *buffsize); *buffsize = *buffsize + BUFFINCR; } else { /* error: no realloc function available */ inflateEnd(&d_stream); return(*status = 414); } } else { /* some other error */ inflateEnd(&d_stream); return(*status = 414); } } /* Set the output file size to be the total output data */ if (filesize) *filesize = d_stream.total_out; /* End the decompression */ err = inflateEnd(&d_stream); if (err != Z_OK) return(*status = 414); return(*status); } /*--------------------------------------------------------------------------*/ int uncompress2file(char *filename, /* name of input file */ FILE *indiskfile, /* I - input file pointer */ FILE *outdiskfile, /* I - output file pointer */ int *status) /* IO - error status */ /* Uncompress the file into another file. */ { int err, len; unsigned long bytes_out = 0; char *infilebuff, *outfilebuff; z_stream d_stream; /* decompression stream */ if (*status > 0) return(*status); /* Allocate buffers to hold compressed and uncompressed */ infilebuff = (char*)malloc(GZBUFSIZE); if (!infilebuff) return(*status = 113); /* memory error */ outfilebuff = (char*)malloc(GZBUFSIZE); if (!outfilebuff) return(*status = 113); /* memory error */ d_stream.zalloc = (alloc_func)0; d_stream.zfree = (free_func)0; d_stream.opaque = (voidpf)0; d_stream.next_out = (unsigned char*) outfilebuff; d_stream.avail_out = GZBUFSIZE; /* Initialize the decompression. The argument (15+16) tells the decompressor that we are to use the gzip algorithm */ err = inflateInit2(&d_stream, (15+16)); if (err != Z_OK) return(*status = 414); /* loop through the file, reading a buffer and uncompressing it */ for (;;) { len = fread(infilebuff, 1, GZBUFSIZE, indiskfile); if (ferror(indiskfile)) { inflateEnd(&d_stream); free(infilebuff); free(outfilebuff); return(*status = 414); } if (len == 0) break; /* no more data */ d_stream.next_in = (unsigned char*)infilebuff; d_stream.avail_in = len; for (;;) { /* uncompress as much of the input as will fit in the output */ err = inflate(&d_stream, Z_NO_FLUSH); if (err == Z_STREAM_END ) { /* We reached the end of the input */ break; } else if (err == Z_OK ) { if (!d_stream.avail_in) break; /* need more input */ /* flush out the full output buffer */ if ((int)fwrite(outfilebuff, 1, GZBUFSIZE, outdiskfile) != GZBUFSIZE) { inflateEnd(&d_stream); free(infilebuff); free(outfilebuff); return(*status = 414); } bytes_out += GZBUFSIZE; d_stream.next_out = (unsigned char*) outfilebuff; d_stream.avail_out = GZBUFSIZE; } else { /* some other error */ inflateEnd(&d_stream); free(infilebuff); free(outfilebuff); return(*status = 414); } } if (feof(indiskfile)) break; } /* write out any remaining bytes in the buffer */ if (d_stream.total_out > bytes_out) { if ((int)fwrite(outfilebuff, 1, (d_stream.total_out - bytes_out), outdiskfile) != (d_stream.total_out - bytes_out)) { inflateEnd(&d_stream); free(infilebuff); free(outfilebuff); return(*status = 414); } } free(infilebuff); /* free temporary output data buffer */ free(outfilebuff); /* free temporary output data buffer */ err = inflateEnd(&d_stream); /* End the decompression */ if (err != Z_OK) return(*status = 414); return(*status); } /*--------------------------------------------------------------------------*/ int compress2mem_from_mem( char *inmemptr, /* I - memory pointer to uncompressed bytes */ size_t inmemsize, /* I - size of input uncompressed file */ char **buffptr, /* IO - memory pointer for compressed file */ size_t *buffsize, /* IO - size of buffer, in bytes */ void *(*mem_realloc)(void *p, size_t newsize), /* function */ size_t *filesize, /* O - size of file, in bytes */ int *status) /* IO - error status */ /* Compress the file into memory. Fill whatever amount of memory has already been allocated, then realloc more memory, using the supplied input function, if necessary. */ { int err; z_stream c_stream; /* compression stream */ if (*status > 0) return(*status); c_stream.zalloc = (alloc_func)0; c_stream.zfree = (free_func)0; c_stream.opaque = (voidpf)0; /* Initialize the compression. The argument (15+16) tells the compressor that we are to use the gzip algorythm. Also use Z_BEST_SPEED for maximum speed with very minor loss in compression factor. */ err = deflateInit2(&c_stream, Z_BEST_SPEED, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY); if (err != Z_OK) return(*status = 413); c_stream.next_in = (unsigned char*)inmemptr; c_stream.avail_in = inmemsize; c_stream.next_out = (unsigned char*) *buffptr; c_stream.avail_out = *buffsize; for (;;) { /* compress as much of the input as will fit in the output */ err = deflate(&c_stream, Z_FINISH); if (err == Z_STREAM_END) { /* We reached the end of the input */ break; } else if (err == Z_OK ) { /* need more space in output buffer */ if (mem_realloc) { *buffptr = mem_realloc(*buffptr,*buffsize + BUFFINCR); if (*buffptr == NULL){ deflateEnd(&c_stream); return(*status = 413); /* memory allocation failed */ } c_stream.avail_out = BUFFINCR; c_stream.next_out = (unsigned char*) (*buffptr + *buffsize); *buffsize = *buffsize + BUFFINCR; } else { /* error: no realloc function available */ deflateEnd(&c_stream); return(*status = 413); } } else { /* some other error */ deflateEnd(&c_stream); return(*status = 413); } } /* Set the output file size to be the total output data */ if (filesize) *filesize = c_stream.total_out; /* End the compression */ err = deflateEnd(&c_stream); if (err != Z_OK) return(*status = 413); return(*status); } /*--------------------------------------------------------------------------*/ int compress2file_from_mem( char *inmemptr, /* I - memory pointer to uncompressed bytes */ size_t inmemsize, /* I - size of input uncompressed file */ FILE *outdiskfile, size_t *filesize, /* O - size of file, in bytes */ int *status) /* Compress the memory file into disk file. */ { int err; unsigned long bytes_out = 0; char *outfilebuff; z_stream c_stream; /* compression stream */ if (*status > 0) return(*status); /* Allocate buffer to hold compressed bytes */ outfilebuff = (char*)malloc(GZBUFSIZE); if (!outfilebuff) return(*status = 113); /* memory error */ c_stream.zalloc = (alloc_func)0; c_stream.zfree = (free_func)0; c_stream.opaque = (voidpf)0; /* Initialize the compression. The argument (15+16) tells the compressor that we are to use the gzip algorythm. Also use Z_BEST_SPEED for maximum speed with very minor loss in compression factor. */ err = deflateInit2(&c_stream, Z_BEST_SPEED, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY); if (err != Z_OK) return(*status = 413); c_stream.next_in = (unsigned char*)inmemptr; c_stream.avail_in = inmemsize; c_stream.next_out = (unsigned char*) outfilebuff; c_stream.avail_out = GZBUFSIZE; for (;;) { /* compress as much of the input as will fit in the output */ err = deflate(&c_stream, Z_FINISH); if (err == Z_STREAM_END) { /* We reached the end of the input */ break; } else if (err == Z_OK ) { /* need more space in output buffer */ /* flush out the full output buffer */ if ((int)fwrite(outfilebuff, 1, GZBUFSIZE, outdiskfile) != GZBUFSIZE) { deflateEnd(&c_stream); free(outfilebuff); return(*status = 413); } bytes_out += GZBUFSIZE; c_stream.next_out = (unsigned char*) outfilebuff; c_stream.avail_out = GZBUFSIZE; } else { /* some other error */ deflateEnd(&c_stream); free(outfilebuff); return(*status = 413); } } /* write out any remaining bytes in the buffer */ if (c_stream.total_out > bytes_out) { if ((int)fwrite(outfilebuff, 1, (c_stream.total_out - bytes_out), outdiskfile) != (c_stream.total_out - bytes_out)) { deflateEnd(&c_stream); free(outfilebuff); return(*status = 413); } } free(outfilebuff); /* free temporary output data buffer */ /* Set the output file size to be the total output data */ if (filesize) *filesize = c_stream.total_out; /* End the compression */ err = deflateEnd(&c_stream); if (err != Z_OK) return(*status = 413); return(*status); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/lib/zuncompress.c0000644000175100001710000004005100000000000020657 0ustar00vstsdocker/* gzcompress.h -- definitions for the .Z decompression routine used in CFITSIO */ #include #include #include #include #define get_char() get_byte() /* gzip.h -- common declarations for all gzip modules */ #define OF(args) args typedef void *voidp; #define memzero(s, n) memset ((voidp)(s), 0, (n)) typedef unsigned char uch; typedef unsigned short ush; typedef unsigned long ulg; /* private version of MIN function */ #define MINZIP(a,b) ((a) <= (b) ? (a) : (b)) /* Return codes from gzip */ #define OK 0 #define ERROR 1 #define COMPRESSED 1 #define DEFLATED 8 #define INBUFSIZ 0x8000 /* input buffer size */ #define INBUF_EXTRA 64 /* required by unlzw() */ #define OUTBUFSIZ 16384 /* output buffer size */ #define OUTBUF_EXTRA 2048 /* required by unlzw() */ #define DIST_BUFSIZE 0x8000 /* buffer for distances, see trees.c */ #define WSIZE 0x8000 /* window size--must be a power of two, and */ #define DECLARE(type, array, size) type array[size] #define tab_suffix window #define tab_prefix prev /* hash link (see deflate.c) */ #define head (prev+WSIZE) /* hash head (see deflate.c) */ #define LZW_MAGIC "\037\235" /* Magic header for lzw files, 1F 9D */ #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf(0)) /* Diagnostic functions */ # define Assert(cond,msg) # define Trace(x) # define Tracev(x) # define Tracevv(x) # define Tracec(c,x) # define Tracecv(c,x) /* lzw.h -- define the lzw functions. */ #ifndef BITS # define BITS 16 #endif #define INIT_BITS 9 /* Initial number of bits per code */ #define BIT_MASK 0x1f /* Mask for 'number of compression bits' */ #define BLOCK_MODE 0x80 #define LZW_RESERVED 0x60 /* reserved bits */ #define CLEAR 256 /* flush the dictionary */ #define FIRST (CLEAR+1) /* first free entry */ /* prototypes */ #define local static void ffpmsg(const char *err_message); local int fill_inbuf OF((int eof_ok)); local void write_buf OF((voidp buf, unsigned cnt)); local void error OF((char *m)); local int unlzw OF((FILE *in, FILE *out)); typedef int file_t; /* Do not use stdio */ int (*work) OF((FILE *infile, FILE *outfile)) = unlzw; /* function to call */ local void error OF((char *m)); /* global buffers */ static DECLARE(uch, inbuf, INBUFSIZ +INBUF_EXTRA); static DECLARE(uch, outbuf, OUTBUFSIZ+OUTBUF_EXTRA); static DECLARE(ush, d_buf, DIST_BUFSIZE); static DECLARE(uch, window, 2L*WSIZE); #ifndef MAXSEG_64K static DECLARE(ush, tab_prefix, 1L< 0) return(*status); /* save input parameters into global variables */ ifname[0] = '\0'; strncat(ifname, filename, 127); ifd = indiskfile; memptr = (void **) buffptr; memsize = buffsize; realloc_fn = mem_realloc; /* clear input and output buffers */ insize = inptr = 0; bytes_in = bytes_out = 0L; magic[0] = (char)get_byte(); magic[1] = (char)get_byte(); if (memcmp(magic, LZW_MAGIC, 2) != 0) { error("ERROR: input .Z file is in unrecognized compression format.\n"); return(-1); } work = unlzw; method = COMPRESSED; last_member = 1; /* do the uncompression */ if ((*work)(ifd, ofd) != OK) { method = -1; /* force cleanup */ *status = 414; /* report some sort of decompression error */ } if (filesize) *filesize = bytes_out; return(*status); } /*=========================================================================*/ /*=========================================================================*/ /* this marks the begining of the original file 'unlzw.c' */ /*=========================================================================*/ /*=========================================================================*/ /* unlzw.c -- decompress files in LZW format. * The code in this file is directly derived from the public domain 'compress' * written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies, * Ken Turkowski, Dave Mack and Peter Jannesen. */ typedef unsigned char char_type; typedef long code_int; typedef unsigned long count_int; typedef unsigned short count_short; typedef unsigned long cmp_code_int; #define MAXCODE(n) (1L << (n)) #ifndef REGISTERS # define REGISTERS 2 #endif #define REG1 #define REG2 #define REG3 #define REG4 #define REG5 #define REG6 #define REG7 #define REG8 #define REG9 #define REG10 #define REG11 #define REG12 #define REG13 #define REG14 #define REG15 #define REG16 #if REGISTERS >= 1 # undef REG1 # define REG1 register #endif #if REGISTERS >= 2 # undef REG2 # define REG2 register #endif #if REGISTERS >= 3 # undef REG3 # define REG3 register #endif #if REGISTERS >= 4 # undef REG4 # define REG4 register #endif #if REGISTERS >= 5 # undef REG5 # define REG5 register #endif #if REGISTERS >= 6 # undef REG6 # define REG6 register #endif #if REGISTERS >= 7 # undef REG7 # define REG7 register #endif #if REGISTERS >= 8 # undef REG8 # define REG8 register #endif #if REGISTERS >= 9 # undef REG9 # define REG9 register #endif #if REGISTERS >= 10 # undef REG10 # define REG10 register #endif #if REGISTERS >= 11 # undef REG11 # define REG11 register #endif #if REGISTERS >= 12 # undef REG12 # define REG12 register #endif #if REGISTERS >= 13 # undef REG13 # define REG13 register #endif #if REGISTERS >= 14 # undef REG14 # define REG14 register #endif #if REGISTERS >= 15 # undef REG15 # define REG15 register #endif #if REGISTERS >= 16 # undef REG16 # define REG16 register #endif #ifndef BYTEORDER # define BYTEORDER 0000 #endif #ifndef NOALLIGN # define NOALLIGN 0 #endif union bytes { long word; struct { #if BYTEORDER == 4321 char_type b1; char_type b2; char_type b3; char_type b4; #else #if BYTEORDER == 1234 char_type b4; char_type b3; char_type b2; char_type b1; #else # undef BYTEORDER int dummy; #endif #endif } bytes; }; #if BYTEORDER == 4321 && NOALLIGN == 1 # define input(b,o,c,n,m){ \ (c) = (*(long *)(&(b)[(o)>>3])>>((o)&0x7))&(m); \ (o) += (n); \ } #else # define input(b,o,c,n,m){ \ REG1 char_type *p = &(b)[(o)>>3]; \ (c) = ((((long)(p[0]))|((long)(p[1])<<8)| \ ((long)(p[2])<<16))>>((o)&0x7))&(m); \ (o) += (n); \ } #endif #ifndef MAXSEG_64K /* DECLARE(ush, tab_prefix, (1<>1] # define clear_tab_prefixof() \ memzero(tab_prefix0, 128), \ memzero(tab_prefix1, 128); #endif #define de_stack ((char_type *)(&d_buf[DIST_BUFSIZE-1])) #define tab_suffixof(i) tab_suffix[i] int block_mode = BLOCK_MODE; /* block compress mode -C compatible with 2.0 */ /* ============================================================================ * Decompress in to out. This routine adapts to the codes in the * file building the "string" table on-the-fly; requiring no table to * be stored in the compressed file. * IN assertions: the buffer inbuf contains already the beginning of * the compressed data, from offsets iptr to insize-1 included. * The magic header has already been checked and skipped. * bytes_in and bytes_out have been initialized. */ local int unlzw(FILE *in, FILE *out) /* input and output file descriptors */ { REG2 char_type *stackp; REG3 code_int code; REG4 int finchar; REG5 code_int oldcode; REG6 code_int incode; REG7 long inbits; REG8 long posbits; REG9 int outpos; /* REG10 int insize; (global) */ REG11 unsigned bitmask; REG12 code_int free_ent; REG13 code_int maxcode; REG14 code_int maxmaxcode; REG15 int n_bits; REG16 int rsize; ofd = out; #ifdef MAXSEG_64K tab_prefix[0] = tab_prefix0; tab_prefix[1] = tab_prefix1; #endif maxbits = get_byte(); block_mode = maxbits & BLOCK_MODE; if ((maxbits & LZW_RESERVED) != 0) { error( "warning, unknown flags in unlzw decompression"); } maxbits &= BIT_MASK; maxmaxcode = MAXCODE(maxbits); if (maxbits > BITS) { error("compressed with too many bits; cannot handle file"); exit_code = ERROR; return ERROR; } rsize = insize; maxcode = MAXCODE(n_bits = INIT_BITS)-1; bitmask = (1<= 0 ; --code) { tab_suffixof(code) = (char_type)code; } do { REG1 int i; int e; int o; resetbuf: e = insize-(o = (posbits>>3)); for (i = 0 ; i < e ; ++i) { inbuf[i] = inbuf[i+o]; } insize = e; posbits = 0; if (insize < INBUF_EXTRA) { /* modified to use fread instead of read - WDP 10/22/97 */ /* if ((rsize = read(in, (char*)inbuf+insize, INBUFSIZ)) == EOF) { */ if ((rsize = fread((char*)inbuf+insize, 1, INBUFSIZ, in)) == EOF) { error("unexpected end of file"); exit_code = ERROR; return ERROR; } insize += rsize; bytes_in += (ulg)rsize; } inbits = ((rsize != 0) ? ((long)insize - insize%n_bits)<<3 : ((long)insize<<3)-(n_bits-1)); while (inbits > posbits) { if (free_ent > maxcode) { posbits = ((posbits-1) + ((n_bits<<3)-(posbits-1+(n_bits<<3))%(n_bits<<3))); ++n_bits; if (n_bits == maxbits) { maxcode = maxmaxcode; } else { maxcode = MAXCODE(n_bits)-1; } bitmask = (1<= 256) { error("corrupt input."); exit_code = ERROR; return ERROR; } outbuf[outpos++] = (char_type)(finchar = (int)(oldcode=code)); continue; } if (code == CLEAR && block_mode) { clear_tab_prefixof(); free_ent = FIRST - 1; posbits = ((posbits-1) + ((n_bits<<3)-(posbits-1+(n_bits<<3))%(n_bits<<3))); maxcode = MAXCODE(n_bits = INIT_BITS)-1; bitmask = (1<= free_ent) { /* Special case for KwKwK string. */ if (code > free_ent) { if (outpos > 0) { write_buf((char*)outbuf, outpos); bytes_out += (ulg)outpos; } error("corrupt input."); exit_code = ERROR; return ERROR; } *--stackp = (char_type)finchar; code = oldcode; } while ((cmp_code_int)code >= (cmp_code_int)256) { /* Generate output characters in reverse order */ *--stackp = tab_suffixof(code); code = tab_prefixof(code); } *--stackp = (char_type)(finchar = tab_suffixof(code)); /* And put them out in forward order */ { /* REG1 int i; already defined above (WDP) */ if (outpos+(i = (de_stack-stackp)) >= OUTBUFSIZ) { do { if (i > OUTBUFSIZ-outpos) i = OUTBUFSIZ-outpos; if (i > 0) { memcpy(outbuf+outpos, stackp, i); outpos += i; } if (outpos >= OUTBUFSIZ) { write_buf((char*)outbuf, outpos); bytes_out += (ulg)outpos; outpos = 0; } stackp+= i; } while ((i = (de_stack-stackp)) > 0); } else { memcpy(outbuf+outpos, stackp, i); outpos += i; } } if ((code = free_ent) < maxmaxcode) { /* Generate the new entry. */ tab_prefixof(code) = (unsigned short)oldcode; tab_suffixof(code) = (char_type)finchar; free_ent = code+1; } oldcode = incode; /* Remember previous code. */ } } while (rsize != 0); if (outpos > 0) { write_buf((char*)outbuf, outpos); bytes_out += (ulg)outpos; } return OK; } /* ========================================================================*/ /* this marks the start of the code from 'util.c' */ local int fill_inbuf(int eof_ok) /* set if EOF acceptable as a result */ { int len; /* Read as much as possible from file */ insize = 0; do { len = fread((char*)inbuf+insize, 1, INBUFSIZ-insize, ifd); if (len == 0 || len == EOF) break; insize += len; } while (insize < INBUFSIZ); if (insize == 0) { if (eof_ok) return EOF; error("unexpected end of file"); exit_code = ERROR; return ERROR; } bytes_in += (ulg)insize; inptr = 1; return inbuf[0]; } /* =========================================================================== */ local void write_buf(voidp buf, unsigned cnt) /* copy buffer into memory; allocate more memory if required*/ { if (!realloc_fn) { /* append buffer to file */ /* added 'unsigned' to get rid of compiler warning (WDP 1/1/99) */ if ((unsigned long) fwrite(buf, 1, cnt, ofd) != cnt) { error ("failed to write buffer to uncompressed output file (write_buf)"); exit_code = ERROR; return; } } else { /* get more memory if current buffer is too small */ if (bytes_out + cnt > *memsize) { *memptr = realloc_fn(*memptr, bytes_out + cnt); *memsize = bytes_out + cnt; /* new memory buffer size */ if (!(*memptr)) { error("malloc failed while uncompressing (write_buf)"); exit_code = ERROR; return; } } /* copy into memory buffer */ memcpy((char *) *memptr + bytes_out, (char *) buf, cnt); } } /* ======================================================================== */ local void error(char *m) /* Error handler */ { ffpmsg(ifname); ffpmsg(m); } ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2592597 astropy-5.0.2/cextern/cfitsio/zlib/0000755000175100001710000000000000000000000016315 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/zlib/adler32.c0000644000175100001710000001164700000000000017726 0ustar00vstsdocker/* adler32.c -- compute the Adler-32 checksum of a data stream * Copyright (C) 1995-2007 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #include "zutil.h" #define local static local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2); #define BASE 65521UL /* largest prime smaller than 65536 */ #define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ #define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); #define DO16(buf) DO8(buf,0); DO8(buf,8); /* use NO_DIVIDE if your processor does not do division in hardware */ #ifdef NO_DIVIDE # define MOD(a) \ do { \ if (a >= (BASE << 16)) a -= (BASE << 16); \ if (a >= (BASE << 15)) a -= (BASE << 15); \ if (a >= (BASE << 14)) a -= (BASE << 14); \ if (a >= (BASE << 13)) a -= (BASE << 13); \ if (a >= (BASE << 12)) a -= (BASE << 12); \ if (a >= (BASE << 11)) a -= (BASE << 11); \ if (a >= (BASE << 10)) a -= (BASE << 10); \ if (a >= (BASE << 9)) a -= (BASE << 9); \ if (a >= (BASE << 8)) a -= (BASE << 8); \ if (a >= (BASE << 7)) a -= (BASE << 7); \ if (a >= (BASE << 6)) a -= (BASE << 6); \ if (a >= (BASE << 5)) a -= (BASE << 5); \ if (a >= (BASE << 4)) a -= (BASE << 4); \ if (a >= (BASE << 3)) a -= (BASE << 3); \ if (a >= (BASE << 2)) a -= (BASE << 2); \ if (a >= (BASE << 1)) a -= (BASE << 1); \ if (a >= BASE) a -= BASE; \ } while (0) # define MOD4(a) \ do { \ if (a >= (BASE << 4)) a -= (BASE << 4); \ if (a >= (BASE << 3)) a -= (BASE << 3); \ if (a >= (BASE << 2)) a -= (BASE << 2); \ if (a >= (BASE << 1)) a -= (BASE << 1); \ if (a >= BASE) a -= BASE; \ } while (0) #else # define MOD(a) a %= BASE # define MOD4(a) a %= BASE #endif /* ========================================================================= */ uLong ZEXPORT adler32(adler, buf, len) uLong adler; const Bytef *buf; uInt len; { unsigned long sum2; unsigned n; /* split Adler-32 into component sums */ sum2 = (adler >> 16) & 0xffff; adler &= 0xffff; /* in case user likes doing a byte at a time, keep it fast */ if (len == 1) { adler += buf[0]; if (adler >= BASE) adler -= BASE; sum2 += adler; if (sum2 >= BASE) sum2 -= BASE; return adler | (sum2 << 16); } /* initial Adler-32 value (deferred check for len == 1 speed) */ if (buf == Z_NULL) return 1L; /* in case short lengths are provided, keep it somewhat fast */ if (len < 16) { while (len--) { adler += *buf++; sum2 += adler; } if (adler >= BASE) adler -= BASE; MOD4(sum2); /* only added so many BASE's */ return adler | (sum2 << 16); } /* do length NMAX blocks -- requires just one modulo operation */ while (len >= NMAX) { len -= NMAX; n = NMAX / 16; /* NMAX is divisible by 16 */ do { DO16(buf); /* 16 sums unrolled */ buf += 16; } while (--n); MOD(adler); MOD(sum2); } /* do remaining bytes (less than NMAX, still just one modulo) */ if (len) { /* avoid modulos if none remaining */ while (len >= 16) { len -= 16; DO16(buf); buf += 16; } while (len--) { adler += *buf++; sum2 += adler; } MOD(adler); MOD(sum2); } /* return recombined sums */ return adler | (sum2 << 16); } /* ========================================================================= */ local uLong adler32_combine_(adler1, adler2, len2) uLong adler1; uLong adler2; z_off64_t len2; { unsigned long sum1; unsigned long sum2; unsigned rem; /* the derivation of this formula is left as an exercise for the reader */ rem = (unsigned)(len2 % BASE); sum1 = adler1 & 0xffff; sum2 = rem * sum1; MOD(sum2); sum1 += (adler2 & 0xffff) + BASE - 1; sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; if (sum1 >= BASE) sum1 -= BASE; if (sum1 >= BASE) sum1 -= BASE; if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); if (sum2 >= BASE) sum2 -= BASE; return sum1 | (sum2 << 16); } /* ========================================================================= */ uLong ZEXPORT adler32_combine(adler1, adler2, len2) uLong adler1; uLong adler2; z_off_t len2; { return adler32_combine_(adler1, adler2, len2); } uLong ZEXPORT adler32_combine64(adler1, adler2, len2) uLong adler1; uLong adler2; z_off64_t len2; { return adler32_combine_(adler1, adler2, len2); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/zlib/crc32.c0000644000175100001710000003254000000000000017401 0ustar00vstsdocker/* crc32.c -- compute the CRC-32 of a data stream * Copyright (C) 1995-2006, 2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h * * Thanks to Rodney Brown for his contribution of faster * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing * tables for updating the shift register in one step with three exclusive-ors * instead of four steps with four exclusive-ors. This results in about a * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. */ /* Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore protection on the static variables used to control the first-use generation of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should first call get_crc_table() to initialize the tables before allowing more than one thread to use crc32(). */ #ifdef MAKECRCH # include # ifndef DYNAMIC_CRC_TABLE # define DYNAMIC_CRC_TABLE # endif /* !DYNAMIC_CRC_TABLE */ #endif /* MAKECRCH */ #include "zutil.h" /* for STDC and FAR definitions */ #define local static /* Find a four-byte integer type for crc32_little() and crc32_big(). */ #ifndef NOBYFOUR # ifdef STDC /* need ANSI C limits.h to determine sizes */ # include # define BYFOUR # if (UINT_MAX == 0xffffffffUL) typedef unsigned int u4; # else # if (ULONG_MAX == 0xffffffffUL) typedef unsigned long u4; # else # if (USHRT_MAX == 0xffffffffUL) typedef unsigned short u4; # else # undef BYFOUR /* can't find a four-byte integer type! */ # endif # endif # endif # endif /* STDC */ #endif /* !NOBYFOUR */ /* Definitions for doing the crc four data bytes at a time. */ #ifdef BYFOUR # define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \ (((w)&0xff00)<<8)+(((w)&0xff)<<24)) local unsigned long crc32_little OF((unsigned long, const unsigned char FAR *, unsigned)); local unsigned long crc32_big OF((unsigned long, const unsigned char FAR *, unsigned)); # define TBLS 8 #else # define TBLS 1 #endif /* BYFOUR */ /* Local functions for crc concatenation */ local unsigned long gf2_matrix_times OF((unsigned long *mat, unsigned long vec)); local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2); #ifdef DYNAMIC_CRC_TABLE local volatile int crc_table_empty = 1; local unsigned long FAR crc_table[TBLS][256]; local void make_crc_table OF((void)); #ifdef MAKECRCH local void write_table OF((FILE *, const unsigned long FAR *)); #endif /* MAKECRCH */ /* Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. Polynomials over GF(2) are represented in binary, one bit per coefficient, with the lowest powers in the most significant bit. Then adding polynomials is just exclusive-or, and multiplying a polynomial by x is a right shift by one. If we call the above polynomial p, and represent a byte as the polynomial q, also with the lowest power in the most significant bit (so the byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, where a mod b means the remainder after dividing a by b. This calculation is done using the shift-register method of multiplying and taking the remainder. The register is initialized to zero, and for each incoming bit, x^32 is added mod p to the register if the bit is a one (where x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x (which is shifting right by one and adding x^32 mod p if the bit shifted out is a one). We start with the highest power (least significant bit) of q and repeat for all eight bits of q. The first table is simply the CRC of all possible eight bit values. This is all the information needed to generate CRCs on data a byte at a time for all combinations of CRC register values and incoming bytes. The remaining tables allow for word-at-a-time CRC calculation for both big-endian and little- endian machines, where a word is four bytes. */ local void make_crc_table() { unsigned long c; int n, k; unsigned long poly; /* polynomial exclusive-or pattern */ /* terms of polynomial defining this crc (except x^32): */ static volatile int first = 1; /* flag to limit concurrent making */ static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; /* See if another task is already doing this (not thread-safe, but better than nothing -- significantly reduces duration of vulnerability in case the advice about DYNAMIC_CRC_TABLE is ignored) */ if (first) { first = 0; /* make exclusive-or pattern from polynomial (0xedb88320UL) */ poly = 0UL; for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) poly |= 1UL << (31 - p[n]); /* generate a crc for every 8-bit value */ for (n = 0; n < 256; n++) { c = (unsigned long)n; for (k = 0; k < 8; k++) c = c & 1 ? poly ^ (c >> 1) : c >> 1; crc_table[0][n] = c; } #ifdef BYFOUR /* generate crc for each value followed by one, two, and three zeros, and then the byte reversal of those as well as the first table */ for (n = 0; n < 256; n++) { c = crc_table[0][n]; crc_table[4][n] = REV(c); for (k = 1; k < 4; k++) { c = crc_table[0][c & 0xff] ^ (c >> 8); crc_table[k][n] = c; crc_table[k + 4][n] = REV(c); } } #endif /* BYFOUR */ crc_table_empty = 0; } else { /* not first */ /* wait for the other guy to finish (not efficient, but rare) */ while (crc_table_empty) ; } #ifdef MAKECRCH /* write out CRC tables to crc32.h */ { FILE *out; out = fopen("crc32.h", "w"); if (out == NULL) return; fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); fprintf(out, "local const unsigned long FAR "); fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); write_table(out, crc_table[0]); # ifdef BYFOUR fprintf(out, "#ifdef BYFOUR\n"); for (k = 1; k < 8; k++) { fprintf(out, " },\n {\n"); write_table(out, crc_table[k]); } fprintf(out, "#endif\n"); # endif /* BYFOUR */ fprintf(out, " }\n};\n"); fclose(out); } #endif /* MAKECRCH */ } #ifdef MAKECRCH local void write_table(out, table) FILE *out; const unsigned long FAR *table; { int n; for (n = 0; n < 256; n++) fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n], n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); } #endif /* MAKECRCH */ #else /* !DYNAMIC_CRC_TABLE */ /* ======================================================================== * Tables of CRC-32s of all single-byte values, made by make_crc_table(). */ #include "crc32.h" #endif /* DYNAMIC_CRC_TABLE */ /* ========================================================================= * This function can be used by asm versions of crc32() */ const unsigned long FAR * ZEXPORT get_crc_table() { #ifdef DYNAMIC_CRC_TABLE if (crc_table_empty) make_crc_table(); #endif /* DYNAMIC_CRC_TABLE */ return (const unsigned long FAR *)crc_table; } /* ========================================================================= */ #define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) #define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 /* ========================================================================= */ unsigned long ZEXPORT crc32(crc, buf, len) unsigned long crc; const unsigned char FAR *buf; uInt len; { if (buf == Z_NULL) return 0UL; #ifdef DYNAMIC_CRC_TABLE if (crc_table_empty) make_crc_table(); #endif /* DYNAMIC_CRC_TABLE */ #ifdef BYFOUR if (sizeof(void *) == sizeof(ptrdiff_t)) { u4 endian; endian = 1; if (*((unsigned char *)(&endian))) return crc32_little(crc, buf, len); else return crc32_big(crc, buf, len); } #endif /* BYFOUR */ crc = crc ^ 0xffffffffUL; while (len >= 8) { DO8; len -= 8; } if (len) do { DO1; } while (--len); return crc ^ 0xffffffffUL; } #ifdef BYFOUR /* ========================================================================= */ #define DOLIT4 c ^= *buf4++; \ c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] #define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 /* ========================================================================= */ local unsigned long crc32_little(crc, buf, len) unsigned long crc; const unsigned char FAR *buf; unsigned len; { register u4 c; register const u4 FAR *buf4; c = (u4)crc; c = ~c; while (len && ((ptrdiff_t)buf & 3)) { c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); len--; } buf4 = (const u4 FAR *)(const void FAR *)buf; while (len >= 32) { DOLIT32; len -= 32; } while (len >= 4) { DOLIT4; len -= 4; } buf = (const unsigned char FAR *)buf4; if (len) do { c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); } while (--len); c = ~c; return (unsigned long)c; } /* ========================================================================= */ #define DOBIG4 c ^= *++buf4; \ c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] #define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 /* ========================================================================= */ local unsigned long crc32_big(crc, buf, len) unsigned long crc; const unsigned char FAR *buf; unsigned len; { register u4 c; register const u4 FAR *buf4; c = REV((u4)crc); c = ~c; while (len && ((ptrdiff_t)buf & 3)) { c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); len--; } buf4 = (const u4 FAR *)(const void FAR *)buf; buf4--; while (len >= 32) { DOBIG32; len -= 32; } while (len >= 4) { DOBIG4; len -= 4; } buf4++; buf = (const unsigned char FAR *)buf4; if (len) do { c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); } while (--len); c = ~c; return (unsigned long)(REV(c)); } #endif /* BYFOUR */ #define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ /* ========================================================================= */ local unsigned long gf2_matrix_times(mat, vec) unsigned long *mat; unsigned long vec; { unsigned long sum; sum = 0; while (vec) { if (vec & 1) sum ^= *mat; vec >>= 1; mat++; } return sum; } /* ========================================================================= */ local void gf2_matrix_square(square, mat) unsigned long *square; unsigned long *mat; { int n; for (n = 0; n < GF2_DIM; n++) square[n] = gf2_matrix_times(mat, mat[n]); } /* ========================================================================= */ local uLong crc32_combine_(crc1, crc2, len2) uLong crc1; uLong crc2; z_off64_t len2; { int n; unsigned long row; unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ /* degenerate case (also disallow negative lengths) */ if (len2 <= 0) return crc1; /* put operator for one zero bit in odd */ odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ row = 1; for (n = 1; n < GF2_DIM; n++) { odd[n] = row; row <<= 1; } /* put operator for two zero bits in even */ gf2_matrix_square(even, odd); /* put operator for four zero bits in odd */ gf2_matrix_square(odd, even); /* apply len2 zeros to crc1 (first square will put the operator for one zero byte, eight zero bits, in even) */ do { /* apply zeros operator for this bit of len2 */ gf2_matrix_square(even, odd); if (len2 & 1) crc1 = gf2_matrix_times(even, crc1); len2 >>= 1; /* if no more bits set, then done */ if (len2 == 0) break; /* another iteration of the loop with odd and even swapped */ gf2_matrix_square(odd, even); if (len2 & 1) crc1 = gf2_matrix_times(odd, crc1); len2 >>= 1; /* if no more bits set, then done */ } while (len2 != 0); /* return combined crc */ crc1 ^= crc2; return crc1; } /* ========================================================================= */ uLong ZEXPORT crc32_combine(crc1, crc2, len2) uLong crc1; uLong crc2; z_off_t len2; { return crc32_combine_(crc1, crc2, len2); } uLong ZEXPORT crc32_combine64(crc1, crc2, len2) uLong crc1; uLong crc2; z_off64_t len2; { return crc32_combine_(crc1, crc2, len2); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/zlib/crc32.h0000644000175100001710000007355000000000000017414 0ustar00vstsdocker/* crc32.h -- tables for rapid CRC calculation * Generated automatically by crc32.c */ local const unsigned long FAR crc_table[TBLS][256] = { { 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, 0x2d02ef8dUL #ifdef BYFOUR }, { 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, 0x9324fd72UL }, { 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, 0xbe9834edUL }, { 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, 0xde0506f1UL }, { 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, 0x8def022dUL }, { 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, 0x72fd2493UL }, { 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, 0xed3498beUL }, { 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, 0xf10605deUL #endif } }; ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/zlib/deflate.c0000644000175100001710000020460700000000000020076 0ustar00vstsdocker/* deflate.c -- compress data using the deflation algorithm * Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* * ALGORITHM * * The "deflation" process depends on being able to identify portions * of the input text which are identical to earlier input (within a * sliding window trailing behind the input currently being processed). * * The most straightforward technique turns out to be the fastest for * most input files: try all possible matches and select the longest. * The key feature of this algorithm is that insertions into the string * dictionary are very simple and thus fast, and deletions are avoided * completely. Insertions are performed at each input character, whereas * string matches are performed only when the previous match ends. So it * is preferable to spend more time in matches to allow very fast string * insertions and avoid deletions. The matching algorithm for small * strings is inspired from that of Rabin & Karp. A brute force approach * is used to find longer strings when a small match has been found. * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze * (by Leonid Broukhis). * A previous version of this file used a more sophisticated algorithm * (by Fiala and Greene) which is guaranteed to run in linear amortized * time, but has a larger average cost, uses more memory and is patented. * However the F&G algorithm may be faster for some highly redundant * files if the parameter max_chain_length (described below) is too large. * * ACKNOWLEDGEMENTS * * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and * I found it in 'freeze' written by Leonid Broukhis. * Thanks to many people for bug reports and testing. * * REFERENCES * * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". * Available in http://www.ietf.org/rfc/rfc1951.txt * * A description of the Rabin and Karp algorithm is given in the book * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. * * Fiala,E.R., and Greene,D.H. * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 * */ #include "deflate.h" const char deflate_copyright[] = " deflate 1.2.5 Copyright 1995-2010 Jean-loup Gailly and Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot include such an acknowledgment, I would appreciate that you keep this copyright string in the executable of your product. */ /* =========================================================================== * Function prototypes. */ typedef enum { need_more, /* block not completed, need more input or more output */ block_done, /* block flush performed */ finish_started, /* finish started, need only more output at next deflate */ finish_done /* finish done, accept no more input or output */ } block_state; typedef block_state (*compress_func) OF((deflate_state *s, int flush)); /* Compression function. Returns the block state after the call. */ local void fill_window OF((deflate_state *s)); local block_state deflate_stored OF((deflate_state *s, int flush)); local block_state deflate_fast OF((deflate_state *s, int flush)); #ifndef FASTEST local block_state deflate_slow OF((deflate_state *s, int flush)); #endif local block_state deflate_rle OF((deflate_state *s, int flush)); local block_state deflate_huff OF((deflate_state *s, int flush)); local void lm_init OF((deflate_state *s)); local void putShortMSB OF((deflate_state *s, uInt b)); local void flush_pending OF((z_streamp strm)); local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); #ifdef ASMV void match_init OF((void)); /* asm code initialization */ uInt longest_match OF((deflate_state *s, IPos cur_match)); #else local uInt longest_match OF((deflate_state *s, IPos cur_match)); #endif #ifdef DEBUG local void check_match OF((deflate_state *s, IPos start, IPos match, int length)); #endif /* =========================================================================== * Local data */ #define NIL 0 /* Tail of hash chains */ #ifndef TOO_FAR # define TOO_FAR 4096 #endif /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ /* Values for max_lazy_match, good_match and max_chain_length, depending on * the desired pack level (0..9). The values given below have been tuned to * exclude worst case performance for pathological files. Better values may be * found for specific files. */ typedef struct config_s { ush good_length; /* reduce lazy search above this match length */ ush max_lazy; /* do not perform lazy search above this match length */ ush nice_length; /* quit search above this match length */ ush max_chain; compress_func func; } config; #ifdef FASTEST local const config configuration_table[2] = { /* good lazy nice chain */ /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ /* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ #else local const config configuration_table[10] = { /* good lazy nice chain */ /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ /* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ /* 2 */ {4, 5, 16, 8, deflate_fast}, /* 3 */ {4, 6, 32, 32, deflate_fast}, /* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ /* 5 */ {8, 16, 32, 32, deflate_slow}, /* 6 */ {8, 16, 128, 128, deflate_slow}, /* 7 */ {8, 32, 128, 256, deflate_slow}, /* 8 */ {32, 128, 258, 1024, deflate_slow}, /* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ #endif /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 * For deflate_fast() (levels <= 3) good is ignored and lazy has a different * meaning. */ #define EQUAL 0 /* result of memcmp for equal strings */ #ifndef NO_DUMMY_DECL struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ #endif /* =========================================================================== * Update a hash value with the given input byte * IN assertion: all calls to to UPDATE_HASH are made with consecutive * input characters, so that a running hash key can be computed from the * previous key instead of complete recalculation each time. */ #define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) /* =========================================================================== * Insert string str in the dictionary and set match_head to the previous head * of the hash chain (the most recent string with same hash key). Return * the previous length of the hash chain. * If this file is compiled with -DFASTEST, the compression level is forced * to 1, and no hash chains are maintained. * IN assertion: all calls to to INSERT_STRING are made with consecutive * input characters and the first MIN_MATCH bytes of str are valid * (except for the last MIN_MATCH-1 bytes of the input file). */ #ifdef FASTEST #define INSERT_STRING(s, str, match_head) \ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ match_head = s->head[s->ins_h], \ s->head[s->ins_h] = (Pos)(str)) #else #define INSERT_STRING(s, str, match_head) \ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ s->head[s->ins_h] = (Pos)(str)) #endif /* =========================================================================== * Initialize the hash table (avoiding 64K overflow for 16 bit systems). * prev[] will be initialized on the fly. */ #define CLEAR_HASH(s) \ s->head[s->hash_size-1] = NIL; \ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); /* ========================================================================= */ int ZEXPORT deflateInit_(strm, level, version, stream_size) z_streamp strm; int level; const char *version; int stream_size; { return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, version, stream_size); /* To do: ignore strm->next_in if we use it as window */ } /* ========================================================================= */ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, version, stream_size) z_streamp strm; int level; int method; int windowBits; int memLevel; int strategy; const char *version; int stream_size; { deflate_state *s; int wrap = 1; static const char my_version[] = ZLIB_VERSION; ushf *overlay; /* We overlay pending_buf and d_buf+l_buf. This works since the average * output size for (length,distance) codes is <= 24 bits. */ if (version == Z_NULL || version[0] != my_version[0] || stream_size != sizeof(z_stream)) { return Z_VERSION_ERROR; } if (strm == Z_NULL) return Z_STREAM_ERROR; strm->msg = Z_NULL; if (strm->zalloc == (alloc_func)0) { strm->zalloc = zcalloc; strm->opaque = (voidpf)0; } if (strm->zfree == (free_func)0) strm->zfree = zcfree; #ifdef FASTEST if (level != 0) level = 1; #else if (level == Z_DEFAULT_COMPRESSION) level = 6; #endif if (windowBits < 0) { /* suppress zlib wrapper */ wrap = 0; windowBits = -windowBits; } #ifdef GZIP else if (windowBits > 15) { wrap = 2; /* write gzip wrapper instead */ windowBits -= 16; } #endif if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { return Z_STREAM_ERROR; } if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); if (s == Z_NULL) return Z_MEM_ERROR; strm->state = (struct internal_state FAR *)s; s->strm = strm; s->wrap = wrap; s->gzhead = Z_NULL; s->w_bits = windowBits; s->w_size = 1 << s->w_bits; s->w_mask = s->w_size - 1; s->hash_bits = memLevel + 7; s->hash_size = 1 << s->hash_bits; s->hash_mask = s->hash_size - 1; s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); s->high_water = 0; /* nothing written to s->window yet */ s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); s->pending_buf = (uchf *) overlay; s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || s->pending_buf == Z_NULL) { s->status = FINISH_STATE; strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); deflateEnd (strm); return Z_MEM_ERROR; } s->d_buf = overlay + s->lit_bufsize/sizeof(ush); s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; s->level = level; s->strategy = strategy; s->method = (Byte)method; return deflateReset(strm); } /* ========================================================================= */ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) z_streamp strm; const Bytef *dictionary; uInt dictLength; { deflate_state *s; uInt length = dictLength; uInt n; IPos hash_head = 0; if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || strm->state->wrap == 2 || (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) return Z_STREAM_ERROR; s = strm->state; if (s->wrap) strm->adler = adler32(strm->adler, dictionary, dictLength); if (length < MIN_MATCH) return Z_OK; if (length > s->w_size) { length = s->w_size; dictionary += dictLength - length; /* use the tail of the dictionary */ } zmemcpy(s->window, dictionary, length); s->strstart = length; s->block_start = (long)length; /* Insert all strings in the hash table (except for the last two bytes). * s->lookahead stays null, so s->ins_h will be recomputed at the next * call of fill_window. */ s->ins_h = s->window[0]; UPDATE_HASH(s, s->ins_h, s->window[1]); for (n = 0; n <= length - MIN_MATCH; n++) { INSERT_STRING(s, n, hash_head); } if (hash_head) hash_head = 0; /* to make compiler happy */ return Z_OK; } /* ========================================================================= */ int ZEXPORT deflateReset (strm) z_streamp strm; { deflate_state *s; if (strm == Z_NULL || strm->state == Z_NULL || strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { return Z_STREAM_ERROR; } strm->total_in = strm->total_out = 0; strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ strm->data_type = Z_UNKNOWN; s = (deflate_state *)strm->state; s->pending = 0; s->pending_out = s->pending_buf; if (s->wrap < 0) { s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ } s->status = s->wrap ? INIT_STATE : BUSY_STATE; strm->adler = #ifdef GZIP s->wrap == 2 ? crc32(0L, Z_NULL, 0) : #endif adler32(0L, Z_NULL, 0); s->last_flush = Z_NO_FLUSH; _tr_init(s); lm_init(s); return Z_OK; } /* ========================================================================= */ int ZEXPORT deflateSetHeader (strm, head) z_streamp strm; gz_headerp head; { if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; if (strm->state->wrap != 2) return Z_STREAM_ERROR; strm->state->gzhead = head; return Z_OK; } /* ========================================================================= */ int ZEXPORT deflatePrime (strm, bits, value) z_streamp strm; int bits; int value; { if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; strm->state->bi_valid = bits; strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); return Z_OK; } /* ========================================================================= */ int ZEXPORT deflateParams(strm, level, strategy) z_streamp strm; int level; int strategy; { deflate_state *s; compress_func func; int err = Z_OK; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; s = strm->state; #ifdef FASTEST if (level != 0) level = 1; #else if (level == Z_DEFAULT_COMPRESSION) level = 6; #endif if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { return Z_STREAM_ERROR; } func = configuration_table[s->level].func; if ((strategy != s->strategy || func != configuration_table[level].func) && strm->total_in != 0) { /* Flush the last buffer: */ err = deflate(strm, Z_BLOCK); } if (s->level != level) { s->level = level; s->max_lazy_match = configuration_table[level].max_lazy; s->good_match = configuration_table[level].good_length; s->nice_match = configuration_table[level].nice_length; s->max_chain_length = configuration_table[level].max_chain; } s->strategy = strategy; return err; } /* ========================================================================= */ int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) z_streamp strm; int good_length; int max_lazy; int nice_length; int max_chain; { deflate_state *s; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; s = strm->state; s->good_match = good_length; s->max_lazy_match = max_lazy; s->nice_match = nice_length; s->max_chain_length = max_chain; return Z_OK; } /* ========================================================================= * For the default windowBits of 15 and memLevel of 8, this function returns * a close to exact, as well as small, upper bound on the compressed size. * They are coded as constants here for a reason--if the #define's are * changed, then this function needs to be changed as well. The return * value for 15 and 8 only works for those exact settings. * * For any setting other than those defaults for windowBits and memLevel, * the value returned is a conservative worst case for the maximum expansion * resulting from using fixed blocks instead of stored blocks, which deflate * can emit on compressed data for some combinations of the parameters. * * This function could be more sophisticated to provide closer upper bounds for * every combination of windowBits and memLevel. But even the conservative * upper bound of about 14% expansion does not seem onerous for output buffer * allocation. */ uLong ZEXPORT deflateBound(strm, sourceLen) z_streamp strm; uLong sourceLen; { deflate_state *s; uLong complen, wraplen; Bytef *str; /* conservative upper bound for compressed data */ complen = sourceLen + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; /* if can't get parameters, return conservative bound plus zlib wrapper */ if (strm == Z_NULL || strm->state == Z_NULL) return complen + 6; /* compute wrapper length */ s = strm->state; switch (s->wrap) { case 0: /* raw deflate */ wraplen = 0; break; case 1: /* zlib wrapper */ wraplen = 6 + (s->strstart ? 4 : 0); break; case 2: /* gzip wrapper */ wraplen = 18; if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ if (s->gzhead->extra != Z_NULL) wraplen += 2 + s->gzhead->extra_len; str = s->gzhead->name; if (str != Z_NULL) do { wraplen++; } while (*str++); str = s->gzhead->comment; if (str != Z_NULL) do { wraplen++; } while (*str++); if (s->gzhead->hcrc) wraplen += 2; } break; default: /* for compiler happiness */ wraplen = 6; } /* if not default parameters, return conservative bound */ if (s->w_bits != 15 || s->hash_bits != 8 + 7) return complen + wraplen; /* default settings: return tight bound for that case */ return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + (sourceLen >> 25) + 13 - 6 + wraplen; } /* ========================================================================= * Put a short in the pending buffer. The 16-bit value is put in MSB order. * IN assertion: the stream state is correct and there is enough room in * pending_buf. */ local void putShortMSB (s, b) deflate_state *s; uInt b; { put_byte(s, (Byte)(b >> 8)); put_byte(s, (Byte)(b & 0xff)); } /* ========================================================================= * Flush as much pending output as possible. All deflate() output goes * through this function so some applications may wish to modify it * to avoid allocating a large strm->next_out buffer and copying into it. * (See also read_buf()). */ local void flush_pending(strm) z_streamp strm; { unsigned len = strm->state->pending; if (len > strm->avail_out) len = strm->avail_out; if (len == 0) return; zmemcpy(strm->next_out, strm->state->pending_out, len); strm->next_out += len; strm->state->pending_out += len; strm->total_out += len; strm->avail_out -= len; strm->state->pending -= len; if (strm->state->pending == 0) { strm->state->pending_out = strm->state->pending_buf; } } /* ========================================================================= */ int ZEXPORT deflate (strm, flush) z_streamp strm; int flush; { int old_flush; /* value of flush param for previous deflate call */ deflate_state *s; if (strm == Z_NULL || strm->state == Z_NULL || flush > Z_BLOCK || flush < 0) { return Z_STREAM_ERROR; } s = strm->state; if (strm->next_out == Z_NULL || (strm->next_in == Z_NULL && strm->avail_in != 0) || (s->status == FINISH_STATE && flush != Z_FINISH)) { ERR_RETURN(strm, Z_STREAM_ERROR); } if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); s->strm = strm; /* just in case */ old_flush = s->last_flush; s->last_flush = flush; /* Write the header */ if (s->status == INIT_STATE) { #ifdef GZIP if (s->wrap == 2) { strm->adler = crc32(0L, Z_NULL, 0); put_byte(s, 31); put_byte(s, 139); put_byte(s, 8); if (s->gzhead == Z_NULL) { put_byte(s, 0); put_byte(s, 0); put_byte(s, 0); put_byte(s, 0); put_byte(s, 0); put_byte(s, s->level == 9 ? 2 : (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? 4 : 0)); put_byte(s, OS_CODE); s->status = BUSY_STATE; } else { put_byte(s, (s->gzhead->text ? 1 : 0) + (s->gzhead->hcrc ? 2 : 0) + (s->gzhead->extra == Z_NULL ? 0 : 4) + (s->gzhead->name == Z_NULL ? 0 : 8) + (s->gzhead->comment == Z_NULL ? 0 : 16) ); put_byte(s, (Byte)(s->gzhead->time & 0xff)); put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); put_byte(s, s->level == 9 ? 2 : (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? 4 : 0)); put_byte(s, s->gzhead->os & 0xff); if (s->gzhead->extra != Z_NULL) { put_byte(s, s->gzhead->extra_len & 0xff); put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); } if (s->gzhead->hcrc) strm->adler = crc32(strm->adler, s->pending_buf, s->pending); s->gzindex = 0; s->status = EXTRA_STATE; } } else #endif { uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; uInt level_flags; if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) level_flags = 0; else if (s->level < 6) level_flags = 1; else if (s->level == 6) level_flags = 2; else level_flags = 3; header |= (level_flags << 6); if (s->strstart != 0) header |= PRESET_DICT; header += 31 - (header % 31); s->status = BUSY_STATE; putShortMSB(s, header); /* Save the adler32 of the preset dictionary: */ if (s->strstart != 0) { putShortMSB(s, (uInt)(strm->adler >> 16)); putShortMSB(s, (uInt)(strm->adler & 0xffff)); } strm->adler = adler32(0L, Z_NULL, 0); } } #ifdef GZIP if (s->status == EXTRA_STATE) { if (s->gzhead->extra != Z_NULL) { uInt beg = s->pending; /* start of bytes to update crc */ while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { if (s->pending == s->pending_buf_size) { if (s->gzhead->hcrc && s->pending > beg) strm->adler = crc32(strm->adler, s->pending_buf + beg, s->pending - beg); flush_pending(strm); beg = s->pending; if (s->pending == s->pending_buf_size) break; } put_byte(s, s->gzhead->extra[s->gzindex]); s->gzindex++; } if (s->gzhead->hcrc && s->pending > beg) strm->adler = crc32(strm->adler, s->pending_buf + beg, s->pending - beg); if (s->gzindex == s->gzhead->extra_len) { s->gzindex = 0; s->status = NAME_STATE; } } else s->status = NAME_STATE; } if (s->status == NAME_STATE) { if (s->gzhead->name != Z_NULL) { uInt beg = s->pending; /* start of bytes to update crc */ int val; do { if (s->pending == s->pending_buf_size) { if (s->gzhead->hcrc && s->pending > beg) strm->adler = crc32(strm->adler, s->pending_buf + beg, s->pending - beg); flush_pending(strm); beg = s->pending; if (s->pending == s->pending_buf_size) { val = 1; break; } } val = s->gzhead->name[s->gzindex++]; put_byte(s, val); } while (val != 0); if (s->gzhead->hcrc && s->pending > beg) strm->adler = crc32(strm->adler, s->pending_buf + beg, s->pending - beg); if (val == 0) { s->gzindex = 0; s->status = COMMENT_STATE; } } else s->status = COMMENT_STATE; } if (s->status == COMMENT_STATE) { if (s->gzhead->comment != Z_NULL) { uInt beg = s->pending; /* start of bytes to update crc */ int val; do { if (s->pending == s->pending_buf_size) { if (s->gzhead->hcrc && s->pending > beg) strm->adler = crc32(strm->adler, s->pending_buf + beg, s->pending - beg); flush_pending(strm); beg = s->pending; if (s->pending == s->pending_buf_size) { val = 1; break; } } val = s->gzhead->comment[s->gzindex++]; put_byte(s, val); } while (val != 0); if (s->gzhead->hcrc && s->pending > beg) strm->adler = crc32(strm->adler, s->pending_buf + beg, s->pending - beg); if (val == 0) s->status = HCRC_STATE; } else s->status = HCRC_STATE; } if (s->status == HCRC_STATE) { if (s->gzhead->hcrc) { if (s->pending + 2 > s->pending_buf_size) flush_pending(strm); if (s->pending + 2 <= s->pending_buf_size) { put_byte(s, (Byte)(strm->adler & 0xff)); put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); strm->adler = crc32(0L, Z_NULL, 0); s->status = BUSY_STATE; } } else s->status = BUSY_STATE; } #endif /* Flush as much pending output as possible */ if (s->pending != 0) { flush_pending(strm); if (strm->avail_out == 0) { /* Since avail_out is 0, deflate will be called again with * more output space, but possibly with both pending and * avail_in equal to zero. There won't be anything to do, * but this is not an error situation so make sure we * return OK instead of BUF_ERROR at next call of deflate: */ s->last_flush = -1; return Z_OK; } /* Make sure there is something to do and avoid duplicate consecutive * flushes. For repeated and useless calls with Z_FINISH, we keep * returning Z_STREAM_END instead of Z_BUF_ERROR. */ } else if (strm->avail_in == 0 && flush <= old_flush && flush != Z_FINISH) { ERR_RETURN(strm, Z_BUF_ERROR); } /* User must not provide more input after the first FINISH: */ if (s->status == FINISH_STATE && strm->avail_in != 0) { ERR_RETURN(strm, Z_BUF_ERROR); } /* Start a new block or continue the current one. */ if (strm->avail_in != 0 || s->lookahead != 0 || (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { block_state bstate; bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : (s->strategy == Z_RLE ? deflate_rle(s, flush) : (*(configuration_table[s->level].func))(s, flush)); if (bstate == finish_started || bstate == finish_done) { s->status = FINISH_STATE; } if (bstate == need_more || bstate == finish_started) { if (strm->avail_out == 0) { s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ } return Z_OK; /* If flush != Z_NO_FLUSH && avail_out == 0, the next call * of deflate should use the same flush parameter to make sure * that the flush is complete. So we don't have to output an * empty block here, this will be done at next call. This also * ensures that for a very small output buffer, we emit at most * one empty block. */ } if (bstate == block_done) { if (flush == Z_PARTIAL_FLUSH) { _tr_align(s); } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ _tr_stored_block(s, (char*)0, 0L, 0); /* For a full flush, this empty block will be recognized * as a special marker by inflate_sync(). */ if (flush == Z_FULL_FLUSH) { CLEAR_HASH(s); /* forget history */ if (s->lookahead == 0) { s->strstart = 0; s->block_start = 0L; } } } flush_pending(strm); if (strm->avail_out == 0) { s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ return Z_OK; } } } Assert(strm->avail_out > 0, "bug2"); if (flush != Z_FINISH) return Z_OK; if (s->wrap <= 0) return Z_STREAM_END; /* Write the trailer */ #ifdef GZIP if (s->wrap == 2) { put_byte(s, (Byte)(strm->adler & 0xff)); put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); put_byte(s, (Byte)(strm->total_in & 0xff)); put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); } else #endif { putShortMSB(s, (uInt)(strm->adler >> 16)); putShortMSB(s, (uInt)(strm->adler & 0xffff)); } flush_pending(strm); /* If avail_out is zero, the application will call deflate again * to flush the rest. */ if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ return s->pending != 0 ? Z_OK : Z_STREAM_END; } /* ========================================================================= */ int ZEXPORT deflateEnd (strm) z_streamp strm; { int status; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; status = strm->state->status; if (status != INIT_STATE && status != EXTRA_STATE && status != NAME_STATE && status != COMMENT_STATE && status != HCRC_STATE && status != BUSY_STATE && status != FINISH_STATE) { return Z_STREAM_ERROR; } /* Deallocate in reverse order of allocations: */ TRY_FREE(strm, strm->state->pending_buf); TRY_FREE(strm, strm->state->head); TRY_FREE(strm, strm->state->prev); TRY_FREE(strm, strm->state->window); ZFREE(strm, strm->state); strm->state = Z_NULL; return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; } /* ========================================================================= * Copy the source state to the destination state. * To simplify the source, this is not supported for 16-bit MSDOS (which * doesn't have enough memory anyway to duplicate compression states). */ int ZEXPORT deflateCopy (dest, source) z_streamp dest; z_streamp source; { #ifdef MAXSEG_64K return Z_STREAM_ERROR; #else deflate_state *ds; deflate_state *ss; ushf *overlay; if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { return Z_STREAM_ERROR; } ss = source->state; zmemcpy(dest, source, sizeof(z_stream)); ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); if (ds == Z_NULL) return Z_MEM_ERROR; dest->state = (struct internal_state FAR *) ds; zmemcpy(ds, ss, sizeof(deflate_state)); ds->strm = dest; ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); ds->pending_buf = (uchf *) overlay; if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || ds->pending_buf == Z_NULL) { deflateEnd (dest); return Z_MEM_ERROR; } /* following zmemcpy do not work for 16-bit MSDOS */ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; ds->l_desc.dyn_tree = ds->dyn_ltree; ds->d_desc.dyn_tree = ds->dyn_dtree; ds->bl_desc.dyn_tree = ds->bl_tree; return Z_OK; #endif /* MAXSEG_64K */ } /* =========================================================================== * Read a new buffer from the current input stream, update the adler32 * and total number of bytes read. All deflate() input goes through * this function so some applications may wish to modify it to avoid * allocating a large strm->next_in buffer and copying from it. * (See also flush_pending()). */ local int read_buf(strm, buf, size) z_streamp strm; Bytef *buf; unsigned size; { unsigned len = strm->avail_in; if (len > size) len = size; if (len == 0) return 0; strm->avail_in -= len; if (strm->state->wrap == 1) { strm->adler = adler32(strm->adler, strm->next_in, len); } #ifdef GZIP else if (strm->state->wrap == 2) { strm->adler = crc32(strm->adler, strm->next_in, len); } #endif zmemcpy(buf, strm->next_in, len); strm->next_in += len; strm->total_in += len; return (int)len; } /* =========================================================================== * Initialize the "longest match" routines for a new zlib stream */ local void lm_init (s) deflate_state *s; { s->window_size = (ulg)2L*s->w_size; CLEAR_HASH(s); /* Set the default configuration parameters: */ s->max_lazy_match = configuration_table[s->level].max_lazy; s->good_match = configuration_table[s->level].good_length; s->nice_match = configuration_table[s->level].nice_length; s->max_chain_length = configuration_table[s->level].max_chain; s->strstart = 0; s->block_start = 0L; s->lookahead = 0; s->match_length = s->prev_length = MIN_MATCH-1; s->match_available = 0; s->ins_h = 0; #ifndef FASTEST #ifdef ASMV match_init(); /* initialize the asm code */ #endif #endif } #ifndef FASTEST /* =========================================================================== * Set match_start to the longest match starting at the given string and * return its length. Matches shorter or equal to prev_length are discarded, * in which case the result is equal to prev_length and match_start is * garbage. * IN assertions: cur_match is the head of the hash chain for the current * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 * OUT assertion: the match length is not greater than s->lookahead. */ #ifndef ASMV /* For 80x86 and 680x0, an optimized version will be provided in match.asm or * match.S. The code will be functionally equivalent. */ local uInt longest_match(s, cur_match) deflate_state *s; IPos cur_match; /* current match */ { unsigned chain_length = s->max_chain_length;/* max hash chain length */ register Bytef *scan = s->window + s->strstart; /* current string */ register Bytef *match; /* matched string */ register int len; /* length of current match */ int best_len = s->prev_length; /* best match length so far */ int nice_match = s->nice_match; /* stop if match long enough */ IPos limit = s->strstart > (IPos)MAX_DIST(s) ? s->strstart - (IPos)MAX_DIST(s) : NIL; /* Stop when cur_match becomes <= limit. To simplify the code, * we prevent matches with the string of window index 0. */ Posf *prev = s->prev; uInt wmask = s->w_mask; #ifdef UNALIGNED_OK /* Compare two bytes at a time. Note: this is not always beneficial. * Try with and without -DUNALIGNED_OK to check. */ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; register ush scan_start = *(ushf*)scan; register ush scan_end = *(ushf*)(scan+best_len-1); #else register Bytef *strend = s->window + s->strstart + MAX_MATCH; register Byte scan_end1 = scan[best_len-1]; register Byte scan_end = scan[best_len]; #endif /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. * It is easy to get rid of this optimization if necessary. */ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); /* Do not waste too much time if we already have a good match: */ if (s->prev_length >= s->good_match) { chain_length >>= 2; } /* Do not look for matches beyond the end of the input. This is necessary * to make deflate deterministic. */ if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); do { Assert(cur_match < s->strstart, "no future"); match = s->window + cur_match; /* Skip to next match if the match length cannot increase * or if the match length is less than 2. Note that the checks below * for insufficient lookahead only occur occasionally for performance * reasons. Therefore uninitialized memory will be accessed, and * conditional jumps will be made that depend on those values. * However the length of the match is limited to the lookahead, so * the output of deflate is not affected by the uninitialized values. */ #if (defined(UNALIGNED_OK) && MAX_MATCH == 258) /* This code assumes sizeof(unsigned short) == 2. Do not use * UNALIGNED_OK if your compiler uses a different size. */ if (*(ushf*)(match+best_len-1) != scan_end || *(ushf*)match != scan_start) continue; /* It is not necessary to compare scan[2] and match[2] since they are * always equal when the other bytes match, given that the hash keys * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at * strstart+3, +5, ... up to strstart+257. We check for insufficient * lookahead only every 4th comparison; the 128th check will be made * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is * necessary to put more guard bytes at the end of the window, or * to check more often for insufficient lookahead. */ Assert(scan[2] == match[2], "scan[2]?"); scan++, match++; do { } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && *(ushf*)(scan+=2) == *(ushf*)(match+=2) && *(ushf*)(scan+=2) == *(ushf*)(match+=2) && *(ushf*)(scan+=2) == *(ushf*)(match+=2) && scan < strend); /* The funny "do {}" generates better code on most compilers */ /* Here, scan <= window+strstart+257 */ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); if (*scan == *match) scan++; len = (MAX_MATCH - 1) - (int)(strend-scan); scan = strend - (MAX_MATCH-1); #else /* UNALIGNED_OK */ if (match[best_len] != scan_end || match[best_len-1] != scan_end1 || *match != *scan || *++match != scan[1]) continue; /* The check at best_len-1 can be removed because it will be made * again later. (This heuristic is not always a win.) * It is not necessary to compare scan[2] and match[2] since they * are always equal when the other bytes match, given that * the hash keys are equal and that HASH_BITS >= 8. */ scan += 2, match++; Assert(*scan == *match, "match[2]?"); /* We check for insufficient lookahead only every 8th comparison; * the 256th check will be made at strstart+258. */ do { } while (*++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && scan < strend); Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); len = MAX_MATCH - (int)(strend - scan); scan = strend - MAX_MATCH; #endif /* UNALIGNED_OK */ if (len > best_len) { s->match_start = cur_match; best_len = len; if (len >= nice_match) break; #ifdef UNALIGNED_OK scan_end = *(ushf*)(scan+best_len-1); #else scan_end1 = scan[best_len-1]; scan_end = scan[best_len]; #endif } } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length != 0); if ((uInt)best_len <= s->lookahead) return (uInt)best_len; return s->lookahead; } #endif /* ASMV */ #else /* FASTEST */ /* --------------------------------------------------------------------------- * Optimized version for FASTEST only */ local uInt longest_match(s, cur_match) deflate_state *s; IPos cur_match; /* current match */ { register Bytef *scan = s->window + s->strstart; /* current string */ register Bytef *match; /* matched string */ register int len; /* length of current match */ register Bytef *strend = s->window + s->strstart + MAX_MATCH; /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. * It is easy to get rid of this optimization if necessary. */ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); Assert(cur_match < s->strstart, "no future"); match = s->window + cur_match; /* Return failure if the match length is less than 2: */ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; /* The check at best_len-1 can be removed because it will be made * again later. (This heuristic is not always a win.) * It is not necessary to compare scan[2] and match[2] since they * are always equal when the other bytes match, given that * the hash keys are equal and that HASH_BITS >= 8. */ scan += 2, match += 2; Assert(*scan == *match, "match[2]?"); /* We check for insufficient lookahead only every 8th comparison; * the 256th check will be made at strstart+258. */ do { } while (*++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && scan < strend); Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); len = MAX_MATCH - (int)(strend - scan); if (len < MIN_MATCH) return MIN_MATCH - 1; s->match_start = cur_match; return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; } #endif /* FASTEST */ #ifdef DEBUG /* =========================================================================== * Check that the match at match_start is indeed a match. */ local void check_match(s, start, match, length) deflate_state *s; IPos start, match; int length; { /* check that the match is indeed a match */ if (zmemcmp(s->window + match, s->window + start, length) != EQUAL) { fprintf(stderr, " start %u, match %u, length %d\n", start, match, length); do { fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); } while (--length != 0); z_error("invalid match"); } if (z_verbose > 1) { fprintf(stderr,"\\[%d,%d]", start-match, length); do { putc(s->window[start++], stderr); } while (--length != 0); } } #else # define check_match(s, start, match, length) #endif /* DEBUG */ /* =========================================================================== * Fill the window when the lookahead becomes insufficient. * Updates strstart and lookahead. * * IN assertion: lookahead < MIN_LOOKAHEAD * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD * At least one byte has been read, or avail_in == 0; reads are * performed for at least two bytes (required for the zip translate_eol * option -- not supported here). */ local void fill_window(s) deflate_state *s; { register unsigned n, m; register Posf *p; unsigned more; /* Amount of free space at the end of the window. */ uInt wsize = s->w_size; do { more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); /* Deal with !@#$% 64K limit: */ if (sizeof(int) <= 2) { if (more == 0 && s->strstart == 0 && s->lookahead == 0) { more = wsize; } else if (more == (unsigned)(-1)) { /* Very unlikely, but possible on 16 bit machine if * strstart == 0 && lookahead == 1 (input done a byte at time) */ more--; } } /* If the window is almost full and there is insufficient lookahead, * move the upper half to the lower one to make room in the upper half. */ if (s->strstart >= wsize+MAX_DIST(s)) { zmemcpy(s->window, s->window+wsize, (unsigned)wsize); s->match_start -= wsize; s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ s->block_start -= (long) wsize; /* Slide the hash table (could be avoided with 32 bit values at the expense of memory usage). We slide even when level == 0 to keep the hash table consistent if we switch back to level > 0 later. (Using level 0 permanently is not an optimal usage of zlib, so we don't care about this pathological case.) */ n = s->hash_size; p = &s->head[n]; do { m = *--p; *p = (Pos)(m >= wsize ? m-wsize : NIL); } while (--n); n = wsize; #ifndef FASTEST p = &s->prev[n]; do { m = *--p; *p = (Pos)(m >= wsize ? m-wsize : NIL); /* If n is not on any hash chain, prev[n] is garbage but * its value will never be used. */ } while (--n); #endif more += wsize; } if (s->strm->avail_in == 0) return; /* If there was no sliding: * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && * more == window_size - lookahead - strstart * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) * => more >= window_size - 2*WSIZE + 2 * In the BIG_MEM or MMAP case (not yet supported), * window_size == input_size + MIN_LOOKAHEAD && * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. * Otherwise, window_size == 2*WSIZE so more >= 2. * If there was sliding, more >= WSIZE. So in all cases, more >= 2. */ Assert(more >= 2, "more < 2"); n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); s->lookahead += n; /* Initialize the hash value now that we have some input: */ if (s->lookahead >= MIN_MATCH) { s->ins_h = s->window[s->strstart]; UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); #if MIN_MATCH != 3 Call UPDATE_HASH() MIN_MATCH-3 more times #endif } /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, * but this is not important since only literal bytes will be emitted. */ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); /* If the WIN_INIT bytes after the end of the current data have never been * written, then zero those bytes in order to avoid memory check reports of * the use of uninitialized (or uninitialised as Julian writes) bytes by * the longest match routines. Update the high water mark for the next * time through here. WIN_INIT is set to MAX_MATCH since the longest match * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. */ if (s->high_water < s->window_size) { ulg curr = s->strstart + (ulg)(s->lookahead); ulg init; if (s->high_water < curr) { /* Previous high water mark below current data -- zero WIN_INIT * bytes or up to end of window, whichever is less. */ init = s->window_size - curr; if (init > WIN_INIT) init = WIN_INIT; zmemzero(s->window + curr, (unsigned)init); s->high_water = curr + init; } else if (s->high_water < (ulg)curr + WIN_INIT) { /* High water mark at or above current data, but below current data * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up * to end of window, whichever is less. */ init = (ulg)curr + WIN_INIT - s->high_water; if (init > s->window_size - s->high_water) init = s->window_size - s->high_water; zmemzero(s->window + s->high_water, (unsigned)init); s->high_water += init; } } } /* =========================================================================== * Flush the current block, with given end-of-file flag. * IN assertion: strstart is set to the end of the current match. */ #define FLUSH_BLOCK_ONLY(s, last) { \ _tr_flush_block(s, (s->block_start >= 0L ? \ (charf *)&s->window[(unsigned)s->block_start] : \ (charf *)Z_NULL), \ (ulg)((long)s->strstart - s->block_start), \ (last)); \ s->block_start = s->strstart; \ flush_pending(s->strm); \ Tracev((stderr,"[FLUSH]")); \ } /* Same but force premature exit if necessary. */ #define FLUSH_BLOCK(s, last) { \ FLUSH_BLOCK_ONLY(s, last); \ if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ } /* =========================================================================== * Copy without compression as much as possible from the input stream, return * the current block state. * This function does not insert new strings in the dictionary since * uncompressible data is probably not useful. This function is used * only for the level=0 compression option. * NOTE: this function should be optimized to avoid extra copying from * window to pending_buf. */ local block_state deflate_stored(s, flush) deflate_state *s; int flush; { /* Stored blocks are limited to 0xffff bytes, pending_buf is limited * to pending_buf_size, and each stored block has a 5 byte header: */ ulg max_block_size = 0xffff; ulg max_start; if (max_block_size > s->pending_buf_size - 5) { max_block_size = s->pending_buf_size - 5; } /* Copy as much as possible from input to output: */ for (;;) { /* Fill the window as much as possible: */ if (s->lookahead <= 1) { Assert(s->strstart < s->w_size+MAX_DIST(s) || s->block_start >= (long)s->w_size, "slide too late"); fill_window(s); if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; if (s->lookahead == 0) break; /* flush the current block */ } Assert(s->block_start >= 0L, "block gone"); s->strstart += s->lookahead; s->lookahead = 0; /* Emit a stored block if pending_buf will be full: */ max_start = s->block_start + max_block_size; if (s->strstart == 0 || (ulg)s->strstart >= max_start) { /* strstart == 0 is possible when wraparound on 16-bit machine */ s->lookahead = (uInt)(s->strstart - max_start); s->strstart = (uInt)max_start; FLUSH_BLOCK(s, 0); } /* Flush if we may have to slide, otherwise block_start may become * negative and the data will be gone: */ if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { FLUSH_BLOCK(s, 0); } } FLUSH_BLOCK(s, flush == Z_FINISH); return flush == Z_FINISH ? finish_done : block_done; } /* =========================================================================== * Compress as much as possible from the input stream, return the current * block state. * This function does not perform lazy evaluation of matches and inserts * new strings in the dictionary only for unmatched strings or for short * matches. It is used only for the fast compression options. */ local block_state deflate_fast(s, flush) deflate_state *s; int flush; { IPos hash_head; /* head of the hash chain */ int bflush; /* set if current block must be flushed */ for (;;) { /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the next match, plus MIN_MATCH bytes to insert the * string following the next match. */ if (s->lookahead < MIN_LOOKAHEAD) { fill_window(s); if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { return need_more; } if (s->lookahead == 0) break; /* flush the current block */ } /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ hash_head = NIL; if (s->lookahead >= MIN_MATCH) { INSERT_STRING(s, s->strstart, hash_head); } /* Find the longest match, discarding those <= prev_length. * At this point we have always match_length < MIN_MATCH */ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ s->match_length = longest_match (s, hash_head); /* longest_match() sets match_start */ } if (s->match_length >= MIN_MATCH) { check_match(s, s->strstart, s->match_start, s->match_length); _tr_tally_dist(s, s->strstart - s->match_start, s->match_length - MIN_MATCH, bflush); s->lookahead -= s->match_length; /* Insert new strings in the hash table only if the match length * is not too large. This saves time but degrades compression. */ #ifndef FASTEST if (s->match_length <= s->max_insert_length && s->lookahead >= MIN_MATCH) { s->match_length--; /* string at strstart already in table */ do { s->strstart++; INSERT_STRING(s, s->strstart, hash_head); /* strstart never exceeds WSIZE-MAX_MATCH, so there are * always MIN_MATCH bytes ahead. */ } while (--s->match_length != 0); s->strstart++; } else #endif { s->strstart += s->match_length; s->match_length = 0; s->ins_h = s->window[s->strstart]; UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); #if MIN_MATCH != 3 Call UPDATE_HASH() MIN_MATCH-3 more times #endif /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not * matter since it will be recomputed at next deflate call. */ } } else { /* No match, output a literal byte */ Tracevv((stderr,"%c", s->window[s->strstart])); _tr_tally_lit (s, s->window[s->strstart], bflush); s->lookahead--; s->strstart++; } if (bflush) FLUSH_BLOCK(s, 0); } FLUSH_BLOCK(s, flush == Z_FINISH); return flush == Z_FINISH ? finish_done : block_done; } #ifndef FASTEST /* =========================================================================== * Same as above, but achieves better compression. We use a lazy * evaluation for matches: a match is finally adopted only if there is * no better match at the next window position. */ local block_state deflate_slow(s, flush) deflate_state *s; int flush; { IPos hash_head; /* head of hash chain */ int bflush; /* set if current block must be flushed */ /* Process the input block. */ for (;;) { /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the next match, plus MIN_MATCH bytes to insert the * string following the next match. */ if (s->lookahead < MIN_LOOKAHEAD) { fill_window(s); if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { return need_more; } if (s->lookahead == 0) break; /* flush the current block */ } /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ hash_head = NIL; if (s->lookahead >= MIN_MATCH) { INSERT_STRING(s, s->strstart, hash_head); } /* Find the longest match, discarding those <= prev_length. */ s->prev_length = s->match_length, s->prev_match = s->match_start; s->match_length = MIN_MATCH-1; if (hash_head != NIL && s->prev_length < s->max_lazy_match && s->strstart - hash_head <= MAX_DIST(s)) { /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ s->match_length = longest_match (s, hash_head); /* longest_match() sets match_start */ if (s->match_length <= 5 && (s->strategy == Z_FILTERED #if TOO_FAR <= 32767 || (s->match_length == MIN_MATCH && s->strstart - s->match_start > TOO_FAR) #endif )) { /* If prev_match is also MIN_MATCH, match_start is garbage * but we will ignore the current match anyway. */ s->match_length = MIN_MATCH-1; } } /* If there was a match at the previous step and the current * match is not better, output the previous match: */ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; /* Do not insert strings in hash table beyond this. */ check_match(s, s->strstart-1, s->prev_match, s->prev_length); _tr_tally_dist(s, s->strstart -1 - s->prev_match, s->prev_length - MIN_MATCH, bflush); /* Insert in hash table all strings up to the end of the match. * strstart-1 and strstart are already inserted. If there is not * enough lookahead, the last two strings are not inserted in * the hash table. */ s->lookahead -= s->prev_length-1; s->prev_length -= 2; do { if (++s->strstart <= max_insert) { INSERT_STRING(s, s->strstart, hash_head); } } while (--s->prev_length != 0); s->match_available = 0; s->match_length = MIN_MATCH-1; s->strstart++; if (bflush) FLUSH_BLOCK(s, 0); } else if (s->match_available) { /* If there was no match at the previous position, output a * single literal. If there was a match but the current match * is longer, truncate the previous match to a single literal. */ Tracevv((stderr,"%c", s->window[s->strstart-1])); _tr_tally_lit(s, s->window[s->strstart-1], bflush); if (bflush) { FLUSH_BLOCK_ONLY(s, 0); } s->strstart++; s->lookahead--; if (s->strm->avail_out == 0) return need_more; } else { /* There is no previous match to compare with, wait for * the next step to decide. */ s->match_available = 1; s->strstart++; s->lookahead--; } } Assert (flush != Z_NO_FLUSH, "no flush?"); if (s->match_available) { Tracevv((stderr,"%c", s->window[s->strstart-1])); _tr_tally_lit(s, s->window[s->strstart-1], bflush); s->match_available = 0; } FLUSH_BLOCK(s, flush == Z_FINISH); return flush == Z_FINISH ? finish_done : block_done; } #endif /* FASTEST */ /* =========================================================================== * For Z_RLE, simply look for runs of bytes, generate matches only of distance * one. Do not maintain a hash table. (It will be regenerated if this run of * deflate switches away from Z_RLE.) */ local block_state deflate_rle(s, flush) deflate_state *s; int flush; { int bflush; /* set if current block must be flushed */ uInt prev; /* byte at distance one to match */ Bytef *scan, *strend; /* scan goes up to strend for length of run */ for (;;) { /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the longest encodable run. */ if (s->lookahead < MAX_MATCH) { fill_window(s); if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) { return need_more; } if (s->lookahead == 0) break; /* flush the current block */ } /* See how many times the previous byte repeats */ s->match_length = 0; if (s->lookahead >= MIN_MATCH && s->strstart > 0) { scan = s->window + s->strstart - 1; prev = *scan; if (prev == *++scan && prev == *++scan && prev == *++scan) { strend = s->window + s->strstart + MAX_MATCH; do { } while (prev == *++scan && prev == *++scan && prev == *++scan && prev == *++scan && prev == *++scan && prev == *++scan && prev == *++scan && prev == *++scan && scan < strend); s->match_length = MAX_MATCH - (int)(strend - scan); if (s->match_length > s->lookahead) s->match_length = s->lookahead; } } /* Emit match if have run of MIN_MATCH or longer, else emit literal */ if (s->match_length >= MIN_MATCH) { check_match(s, s->strstart, s->strstart - 1, s->match_length); _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); s->lookahead -= s->match_length; s->strstart += s->match_length; s->match_length = 0; } else { /* No match, output a literal byte */ Tracevv((stderr,"%c", s->window[s->strstart])); _tr_tally_lit (s, s->window[s->strstart], bflush); s->lookahead--; s->strstart++; } if (bflush) FLUSH_BLOCK(s, 0); } FLUSH_BLOCK(s, flush == Z_FINISH); return flush == Z_FINISH ? finish_done : block_done; } /* =========================================================================== * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. * (It will be regenerated if this run of deflate switches away from Huffman.) */ local block_state deflate_huff(s, flush) deflate_state *s; int flush; { int bflush; /* set if current block must be flushed */ for (;;) { /* Make sure that we have a literal to write. */ if (s->lookahead == 0) { fill_window(s); if (s->lookahead == 0) { if (flush == Z_NO_FLUSH) return need_more; break; /* flush the current block */ } } /* Output a literal byte */ s->match_length = 0; Tracevv((stderr,"%c", s->window[s->strstart])); _tr_tally_lit (s, s->window[s->strstart], bflush); s->lookahead--; s->strstart++; if (bflush) FLUSH_BLOCK(s, 0); } FLUSH_BLOCK(s, flush == Z_FINISH); return flush == Z_FINISH ? finish_done : block_done; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/zlib/deflate.h0000644000175100001710000003055700000000000020104 0ustar00vstsdocker/* deflate.h -- internal compression state * Copyright (C) 1995-2010 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ #ifndef DEFLATE_H #define DEFLATE_H #include "zutil.h" /* define NO_GZIP when compiling if you want to disable gzip header and trailer creation by deflate(). NO_GZIP would be used to avoid linking in the crc code when it is not needed. For shared libraries, gzip encoding should be left enabled. */ #ifndef NO_GZIP # define GZIP #endif /* =========================================================================== * Internal compression state. */ #define LENGTH_CODES 29 /* number of length codes, not counting the special END_BLOCK code */ #define LITERALS 256 /* number of literal bytes 0..255 */ #define L_CODES (LITERALS+1+LENGTH_CODES) /* number of Literal or Length codes, including the END_BLOCK code */ #define D_CODES 30 /* number of distance codes */ #define BL_CODES 19 /* number of codes used to transfer the bit lengths */ #define HEAP_SIZE (2*L_CODES+1) /* maximum heap size */ #define MAX_BITS 15 /* All codes must not exceed MAX_BITS bits */ #define INIT_STATE 42 #define EXTRA_STATE 69 #define NAME_STATE 73 #define COMMENT_STATE 91 #define HCRC_STATE 103 #define BUSY_STATE 113 #define FINISH_STATE 666 /* Stream status */ /* Data structure describing a single value and its code string. */ typedef struct ct_data_s { union { ush freq; /* frequency count */ ush code; /* bit string */ } fc; union { ush dad; /* father node in Huffman tree */ ush len; /* length of bit string */ } dl; } FAR ct_data; #define Freq fc.freq #define Code fc.code #define Dad dl.dad #define Len dl.len typedef struct static_tree_desc_s static_tree_desc; typedef struct tree_desc_s { ct_data *dyn_tree; /* the dynamic tree */ int max_code; /* largest code with non zero frequency */ static_tree_desc *stat_desc; /* the corresponding static tree */ } FAR tree_desc; typedef ush Pos; typedef Pos FAR Posf; typedef unsigned IPos; /* A Pos is an index in the character window. We use short instead of int to * save space in the various tables. IPos is used only for parameter passing. */ typedef struct internal_state { z_streamp strm; /* pointer back to this zlib stream */ int status; /* as the name implies */ Bytef *pending_buf; /* output still pending */ ulg pending_buf_size; /* size of pending_buf */ Bytef *pending_out; /* next pending byte to output to the stream */ uInt pending; /* nb of bytes in the pending buffer */ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ gz_headerp gzhead; /* gzip header information to write */ uInt gzindex; /* where in extra, name, or comment */ Byte method; /* STORED (for zip only) or DEFLATED */ int last_flush; /* value of flush param for previous deflate call */ /* used by deflate.c: */ uInt w_size; /* LZ77 window size (32K by default) */ uInt w_bits; /* log2(w_size) (8..16) */ uInt w_mask; /* w_size - 1 */ Bytef *window; /* Sliding window. Input bytes are read into the second half of the window, * and move to the first half later to keep a dictionary of at least wSize * bytes. With this organization, matches are limited to a distance of * wSize-MAX_MATCH bytes, but this ensures that IO is always * performed with a length multiple of the block size. Also, it limits * the window size to 64K, which is quite useful on MSDOS. * To do: use the user input buffer as sliding window. */ ulg window_size; /* Actual size of window: 2*wSize, except when the user input buffer * is directly used as sliding window. */ Posf *prev; /* Link to older string with same hash index. To limit the size of this * array to 64K, this link is maintained only for the last 32K strings. * An index in this array is thus a window index modulo 32K. */ Posf *head; /* Heads of the hash chains or NIL. */ uInt ins_h; /* hash index of string to be inserted */ uInt hash_size; /* number of elements in hash table */ uInt hash_bits; /* log2(hash_size) */ uInt hash_mask; /* hash_size-1 */ uInt hash_shift; /* Number of bits by which ins_h must be shifted at each input * step. It must be such that after MIN_MATCH steps, the oldest * byte no longer takes part in the hash key, that is: * hash_shift * MIN_MATCH >= hash_bits */ long block_start; /* Window position at the beginning of the current output block. Gets * negative when the window is moved backwards. */ uInt match_length; /* length of best match */ IPos prev_match; /* previous match */ int match_available; /* set if previous match exists */ uInt strstart; /* start of string to insert */ uInt match_start; /* start of matching string */ uInt lookahead; /* number of valid bytes ahead in window */ uInt prev_length; /* Length of the best match at previous step. Matches not greater than this * are discarded. This is used in the lazy match evaluation. */ uInt max_chain_length; /* To speed up deflation, hash chains are never searched beyond this * length. A higher limit improves compression ratio but degrades the * speed. */ uInt max_lazy_match; /* Attempt to find a better match only when the current match is strictly * smaller than this value. This mechanism is used only for compression * levels >= 4. */ # define max_insert_length max_lazy_match /* Insert new strings in the hash table only if the match length is not * greater than this length. This saves time but degrades compression. * max_insert_length is used only for compression levels <= 3. */ int level; /* compression level (1..9) */ int strategy; /* favor or force Huffman coding*/ uInt good_match; /* Use a faster search when the previous match is longer than this */ int nice_match; /* Stop searching when current match exceeds this */ /* used by trees.c: */ /* Didn't use ct_data typedef below to supress compiler warning */ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ struct tree_desc_s l_desc; /* desc. for literal tree */ struct tree_desc_s d_desc; /* desc. for distance tree */ struct tree_desc_s bl_desc; /* desc. for bit length tree */ ush bl_count[MAX_BITS+1]; /* number of codes at each bit length for an optimal tree */ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ int heap_len; /* number of elements in the heap */ int heap_max; /* element of largest frequency */ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. * The same heap array is used to build all trees. */ uch depth[2*L_CODES+1]; /* Depth of each subtree used as tie breaker for trees of equal frequency */ uchf *l_buf; /* buffer for literals or lengths */ uInt lit_bufsize; /* Size of match buffer for literals/lengths. There are 4 reasons for * limiting lit_bufsize to 64K: * - frequencies can be kept in 16 bit counters * - if compression is not successful for the first block, all input * data is still in the window so we can still emit a stored block even * when input comes from standard input. (This can also be done for * all blocks if lit_bufsize is not greater than 32K.) * - if compression is not successful for a file smaller than 64K, we can * even emit a stored file instead of a stored block (saving 5 bytes). * This is applicable only for zip (not gzip or zlib). * - creating new Huffman trees less frequently may not provide fast * adaptation to changes in the input data statistics. (Take for * example a binary file with poorly compressible code followed by * a highly compressible string table.) Smaller buffer sizes give * fast adaptation but have of course the overhead of transmitting * trees more frequently. * - I can't count above 4 */ uInt last_lit; /* running index in l_buf */ ushf *d_buf; /* Buffer for distances. To simplify the code, d_buf and l_buf have * the same number of elements. To use different lengths, an extra flag * array would be necessary. */ ulg opt_len; /* bit length of current block with optimal trees */ ulg static_len; /* bit length of current block with static trees */ uInt matches; /* number of string matches in current block */ int last_eob_len; /* bit length of EOB code for last block */ #ifdef DEBUG ulg compressed_len; /* total bit length of compressed file mod 2^32 */ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ #endif ush bi_buf; /* Output buffer. bits are inserted starting at the bottom (least * significant bits). */ int bi_valid; /* Number of valid bits in bi_buf. All bits above the last valid bit * are always zero. */ ulg high_water; /* High water mark offset in window for initialized bytes -- bytes above * this are set to zero in order to avoid memory check warnings when * longest match routines access bytes past the input. This is then * updated to the new high water mark. */ } FAR deflate_state; /* Output a byte on the stream. * IN assertion: there is enough room in pending_buf. */ #define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) /* Minimum amount of lookahead, except at the end of the input file. * See deflate.c for comments about the MIN_MATCH+1. */ #define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) /* In order to simplify the code, particularly on 16 bit machines, match * distances are limited to MAX_DIST instead of WSIZE. */ #define WIN_INIT MAX_MATCH /* Number of bytes after end of data in window to initialize in order to avoid memory checker errors from longest match routines */ /* in trees.c */ void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, int last)); void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, int last)); #define d_code(dist) \ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) /* Mapping from a distance to a distance code. dist is the distance - 1 and * must not have side effects. _dist_code[256] and _dist_code[257] are never * used. */ #ifndef DEBUG /* Inline versions of _tr_tally for speed: */ #if defined(GEN_TREES_H) || !defined(STDC) extern uch ZLIB_INTERNAL _length_code[]; extern uch ZLIB_INTERNAL _dist_code[]; #else extern const uch ZLIB_INTERNAL _length_code[]; extern const uch ZLIB_INTERNAL _dist_code[]; #endif # define _tr_tally_lit(s, c, flush) \ { uch cc = (c); \ s->d_buf[s->last_lit] = 0; \ s->l_buf[s->last_lit++] = cc; \ s->dyn_ltree[cc].Freq++; \ flush = (s->last_lit == s->lit_bufsize-1); \ } # define _tr_tally_dist(s, distance, length, flush) \ { uch len = (length); \ ush dist = (distance); \ s->d_buf[s->last_lit] = dist; \ s->l_buf[s->last_lit++] = len; \ dist--; \ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ s->dyn_dtree[d_code(dist)].Freq++; \ flush = (s->last_lit == s->lit_bufsize-1); \ } #else # define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) # define _tr_tally_dist(s, distance, length, flush) \ flush = _tr_tally(s, distance, length) #endif #endif /* DEFLATE_H */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/zlib/infback.c0000644000175100001710000005413600000000000020067 0ustar00vstsdocker/* infback.c -- inflate using a call-back interface * Copyright (C) 1995-2009 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* This code is largely copied from inflate.c. Normally either infback.o or inflate.o would be linked into an application--not both. The interface with inffast.c is retained so that optimized assembler-coded versions of inflate_fast() can be used with either inflate.c or infback.c. */ #include "zutil.h" #include "inftrees.h" #include "inflate.h" #include "inffast.h" /* function prototypes */ local void fixedtables OF((struct inflate_state FAR *state)); /* strm provides memory allocation functions in zalloc and zfree, or Z_NULL to use the library memory allocation functions. windowBits is in the range 8..15, and window is a user-supplied window and output buffer that is 2**windowBits bytes. */ int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) z_streamp strm; int windowBits; unsigned char FAR *window; const char *version; int stream_size; { struct inflate_state FAR *state; if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || stream_size != (int)(sizeof(z_stream))) return Z_VERSION_ERROR; if (strm == Z_NULL || window == Z_NULL || windowBits < 8 || windowBits > 15) return Z_STREAM_ERROR; strm->msg = Z_NULL; /* in case we return an error */ if (strm->zalloc == (alloc_func)0) { strm->zalloc = zcalloc; strm->opaque = (voidpf)0; } if (strm->zfree == (free_func)0) strm->zfree = zcfree; state = (struct inflate_state FAR *)ZALLOC(strm, 1, sizeof(struct inflate_state)); if (state == Z_NULL) return Z_MEM_ERROR; Tracev((stderr, "inflate: allocated\n")); strm->state = (struct internal_state FAR *)state; state->dmax = 32768U; state->wbits = windowBits; state->wsize = 1U << windowBits; state->window = window; state->wnext = 0; state->whave = 0; return Z_OK; } /* Return state with length and distance decoding tables and index sizes set to fixed code decoding. Normally this returns fixed tables from inffixed.h. If BUILDFIXED is defined, then instead this routine builds the tables the first time it's called, and returns those tables the first time and thereafter. This reduces the size of the code by about 2K bytes, in exchange for a little execution time. However, BUILDFIXED should not be used for threaded applications, since the rewriting of the tables and virgin may not be thread-safe. */ local void fixedtables(state) struct inflate_state FAR *state; { #ifdef BUILDFIXED static int virgin = 1; static code *lenfix, *distfix; static code fixed[544]; /* build fixed huffman tables if first call (may not be thread safe) */ if (virgin) { unsigned sym, bits; static code *next; /* literal/length table */ sym = 0; while (sym < 144) state->lens[sym++] = 8; while (sym < 256) state->lens[sym++] = 9; while (sym < 280) state->lens[sym++] = 7; while (sym < 288) state->lens[sym++] = 8; next = fixed; lenfix = next; bits = 9; inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); /* distance table */ sym = 0; while (sym < 32) state->lens[sym++] = 5; distfix = next; bits = 5; inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); /* do this just once */ virgin = 0; } #else /* !BUILDFIXED */ # include "inffixed.h" #endif /* BUILDFIXED */ state->lencode = lenfix; state->lenbits = 9; state->distcode = distfix; state->distbits = 5; } /* Macros for inflateBack(): */ /* Load returned state from inflate_fast() */ #define LOAD() \ do { \ put = strm->next_out; \ left = strm->avail_out; \ next = strm->next_in; \ have = strm->avail_in; \ hold = state->hold; \ bits = state->bits; \ } while (0) /* Set state from registers for inflate_fast() */ #define RESTORE() \ do { \ strm->next_out = put; \ strm->avail_out = left; \ strm->next_in = next; \ strm->avail_in = have; \ state->hold = hold; \ state->bits = bits; \ } while (0) /* Clear the input bit accumulator */ #define INITBITS() \ do { \ hold = 0; \ bits = 0; \ } while (0) /* Assure that some input is available. If input is requested, but denied, then return a Z_BUF_ERROR from inflateBack(). */ #define PULL() \ do { \ if (have == 0) { \ have = in(in_desc, &next); \ if (have == 0) { \ next = Z_NULL; \ ret = Z_BUF_ERROR; \ goto inf_leave; \ } \ } \ } while (0) /* Get a byte of input into the bit accumulator, or return from inflateBack() with an error if there is no input available. */ #define PULLBYTE() \ do { \ PULL(); \ have--; \ hold += (unsigned long)(*next++) << bits; \ bits += 8; \ } while (0) /* Assure that there are at least n bits in the bit accumulator. If there is not enough available input to do that, then return from inflateBack() with an error. */ #define NEEDBITS(n) \ do { \ while (bits < (unsigned)(n)) \ PULLBYTE(); \ } while (0) /* Return the low n bits of the bit accumulator (n < 16) */ #define BITS(n) \ ((unsigned)hold & ((1U << (n)) - 1)) /* Remove n bits from the bit accumulator */ #define DROPBITS(n) \ do { \ hold >>= (n); \ bits -= (unsigned)(n); \ } while (0) /* Remove zero to seven bits as needed to go to a byte boundary */ #define BYTEBITS() \ do { \ hold >>= bits & 7; \ bits -= bits & 7; \ } while (0) /* Assure that some output space is available, by writing out the window if it's full. If the write fails, return from inflateBack() with a Z_BUF_ERROR. */ #define ROOM() \ do { \ if (left == 0) { \ put = state->window; \ left = state->wsize; \ state->whave = left; \ if (out(out_desc, put, left)) { \ ret = Z_BUF_ERROR; \ goto inf_leave; \ } \ } \ } while (0) /* strm provides the memory allocation functions and window buffer on input, and provides information on the unused input on return. For Z_DATA_ERROR returns, strm will also provide an error message. in() and out() are the call-back input and output functions. When inflateBack() needs more input, it calls in(). When inflateBack() has filled the window with output, or when it completes with data in the window, it calls out() to write out the data. The application must not change the provided input until in() is called again or inflateBack() returns. The application must not change the window/output buffer until inflateBack() returns. in() and out() are called with a descriptor parameter provided in the inflateBack() call. This parameter can be a structure that provides the information required to do the read or write, as well as accumulated information on the input and output such as totals and check values. in() should return zero on failure. out() should return non-zero on failure. If either in() or out() fails, than inflateBack() returns a Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it was in() or out() that caused in the error. Otherwise, inflateBack() returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format error, or Z_MEM_ERROR if it could not allocate memory for the state. inflateBack() can also return Z_STREAM_ERROR if the input parameters are not correct, i.e. strm is Z_NULL or the state was not initialized. */ int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) z_streamp strm; in_func in; void FAR *in_desc; out_func out; void FAR *out_desc; { struct inflate_state FAR *state; unsigned char FAR *next; /* next input */ unsigned char FAR *put; /* next output */ unsigned have, left; /* available input and output */ unsigned long hold; /* bit buffer */ unsigned bits; /* bits in bit buffer */ unsigned copy; /* number of stored or match bytes to copy */ unsigned char FAR *from; /* where to copy match bytes from */ code here; /* current decoding table entry */ code last; /* parent table entry */ unsigned len; /* length to copy for repeats, bits to drop */ int ret; /* return code */ static const unsigned short order[19] = /* permutation of code lengths */ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; /* Check that the strm exists and that the state was initialized */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; /* Reset the state */ strm->msg = Z_NULL; state->mode = TYPE; state->last = 0; state->whave = 0; next = strm->next_in; have = next != Z_NULL ? strm->avail_in : 0; hold = 0; bits = 0; put = state->window; left = state->wsize; /* Inflate until end of block marked as last */ for (;;) switch (state->mode) { case TYPE: /* determine and dispatch block type */ if (state->last) { BYTEBITS(); state->mode = DONE; break; } NEEDBITS(3); state->last = BITS(1); DROPBITS(1); switch (BITS(2)) { case 0: /* stored block */ Tracev((stderr, "inflate: stored block%s\n", state->last ? " (last)" : "")); state->mode = STORED; break; case 1: /* fixed block */ fixedtables(state); Tracev((stderr, "inflate: fixed codes block%s\n", state->last ? " (last)" : "")); state->mode = LEN; /* decode codes */ break; case 2: /* dynamic block */ Tracev((stderr, "inflate: dynamic codes block%s\n", state->last ? " (last)" : "")); state->mode = TABLE; break; case 3: strm->msg = (char *)"invalid block type"; state->mode = BAD; } DROPBITS(2); break; case STORED: /* get and verify stored block length */ BYTEBITS(); /* go to byte boundary */ NEEDBITS(32); if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { strm->msg = (char *)"invalid stored block lengths"; state->mode = BAD; break; } state->length = (unsigned)hold & 0xffff; Tracev((stderr, "inflate: stored length %u\n", state->length)); INITBITS(); /* copy stored block from input to output */ while (state->length != 0) { copy = state->length; PULL(); ROOM(); if (copy > have) copy = have; if (copy > left) copy = left; zmemcpy(put, next, copy); have -= copy; next += copy; left -= copy; put += copy; state->length -= copy; } Tracev((stderr, "inflate: stored end\n")); state->mode = TYPE; break; case TABLE: /* get dynamic table entries descriptor */ NEEDBITS(14); state->nlen = BITS(5) + 257; DROPBITS(5); state->ndist = BITS(5) + 1; DROPBITS(5); state->ncode = BITS(4) + 4; DROPBITS(4); #ifndef PKZIP_BUG_WORKAROUND if (state->nlen > 286 || state->ndist > 30) { strm->msg = (char *)"too many length or distance symbols"; state->mode = BAD; break; } #endif Tracev((stderr, "inflate: table sizes ok\n")); /* get code length code lengths (not a typo) */ state->have = 0; while (state->have < state->ncode) { NEEDBITS(3); state->lens[order[state->have++]] = (unsigned short)BITS(3); DROPBITS(3); } while (state->have < 19) state->lens[order[state->have++]] = 0; state->next = state->codes; state->lencode = (code const FAR *)(state->next); state->lenbits = 7; ret = inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); if (ret) { strm->msg = (char *)"invalid code lengths set"; state->mode = BAD; break; } Tracev((stderr, "inflate: code lengths ok\n")); /* get length and distance code code lengths */ state->have = 0; while (state->have < state->nlen + state->ndist) { for (;;) { here = state->lencode[BITS(state->lenbits)]; if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } if (here.val < 16) { NEEDBITS(here.bits); DROPBITS(here.bits); state->lens[state->have++] = here.val; } else { if (here.val == 16) { NEEDBITS(here.bits + 2); DROPBITS(here.bits); if (state->have == 0) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; break; } len = (unsigned)(state->lens[state->have - 1]); copy = 3 + BITS(2); DROPBITS(2); } else if (here.val == 17) { NEEDBITS(here.bits + 3); DROPBITS(here.bits); len = 0; copy = 3 + BITS(3); DROPBITS(3); } else { NEEDBITS(here.bits + 7); DROPBITS(here.bits); len = 0; copy = 11 + BITS(7); DROPBITS(7); } if (state->have + copy > state->nlen + state->ndist) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; break; } while (copy--) state->lens[state->have++] = (unsigned short)len; } } /* handle error breaks in while */ if (state->mode == BAD) break; /* check for end-of-block code (better have one) */ if (state->lens[256] == 0) { strm->msg = (char *)"invalid code -- missing end-of-block"; state->mode = BAD; break; } /* build code tables -- note: do not change the lenbits or distbits values here (9 and 6) without reading the comments in inftrees.h concerning the ENOUGH constants, which depend on those values */ state->next = state->codes; state->lencode = (code const FAR *)(state->next); state->lenbits = 9; ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work); if (ret) { strm->msg = (char *)"invalid literal/lengths set"; state->mode = BAD; break; } state->distcode = (code const FAR *)(state->next); state->distbits = 6; ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, &(state->next), &(state->distbits), state->work); if (ret) { strm->msg = (char *)"invalid distances set"; state->mode = BAD; break; } Tracev((stderr, "inflate: codes ok\n")); state->mode = LEN; case LEN: /* use inflate_fast() if we have enough input and output */ if (have >= 6 && left >= 258) { RESTORE(); if (state->whave < state->wsize) state->whave = state->wsize - left; inflate_fast(strm, state->wsize); LOAD(); break; } /* get a literal, length, or end-of-block code */ for (;;) { here = state->lencode[BITS(state->lenbits)]; if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } if (here.op && (here.op & 0xf0) == 0) { last = here; for (;;) { here = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + here.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); } DROPBITS(here.bits); state->length = (unsigned)here.val; /* process literal */ if (here.op == 0) { Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", here.val)); ROOM(); *put++ = (unsigned char)(state->length); left--; state->mode = LEN; break; } /* process end of block */ if (here.op & 32) { Tracevv((stderr, "inflate: end of block\n")); state->mode = TYPE; break; } /* invalid code */ if (here.op & 64) { strm->msg = (char *)"invalid literal/length code"; state->mode = BAD; break; } /* length code -- get extra bits, if any */ state->extra = (unsigned)(here.op) & 15; if (state->extra != 0) { NEEDBITS(state->extra); state->length += BITS(state->extra); DROPBITS(state->extra); } Tracevv((stderr, "inflate: length %u\n", state->length)); /* get distance code */ for (;;) { here = state->distcode[BITS(state->distbits)]; if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } if ((here.op & 0xf0) == 0) { last = here; for (;;) { here = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + here.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); } DROPBITS(here.bits); if (here.op & 64) { strm->msg = (char *)"invalid distance code"; state->mode = BAD; break; } state->offset = (unsigned)here.val; /* get distance extra bits, if any */ state->extra = (unsigned)(here.op) & 15; if (state->extra != 0) { NEEDBITS(state->extra); state->offset += BITS(state->extra); DROPBITS(state->extra); } if (state->offset > state->wsize - (state->whave < state->wsize ? left : 0)) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } Tracevv((stderr, "inflate: distance %u\n", state->offset)); /* copy match from window to output */ do { ROOM(); copy = state->wsize - state->offset; if (copy < left) { from = put + copy; copy = left - copy; } else { from = put - state->offset; copy = left; } if (copy > state->length) copy = state->length; state->length -= copy; left -= copy; do { *put++ = *from++; } while (--copy); } while (state->length != 0); break; case DONE: /* inflate stream terminated properly -- write leftover output */ ret = Z_STREAM_END; if (left < state->wsize) { if (out(out_desc, state->window, state->wsize - left)) ret = Z_BUF_ERROR; } goto inf_leave; case BAD: ret = Z_DATA_ERROR; goto inf_leave; default: /* can't happen, but makes compilers happy */ ret = Z_STREAM_ERROR; goto inf_leave; } /* Return unused input */ inf_leave: strm->next_in = next; strm->avail_in = have; return ret; } int ZEXPORT inflateBackEnd(strm) z_streamp strm; { if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) return Z_STREAM_ERROR; ZFREE(strm, strm->state); strm->state = Z_NULL; Tracev((stderr, "inflate: end\n")); return Z_OK; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/zlib/inffast.c0000644000175100001710000003217700000000000020125 0ustar00vstsdocker/* inffast.c -- fast decoding * Copyright (C) 1995-2008, 2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #include "zutil.h" #include "inftrees.h" #include "inflate.h" #include "inffast.h" #ifndef ASMINF /* Allow machine dependent optimization for post-increment or pre-increment. Based on testing to date, Pre-increment preferred for: - PowerPC G3 (Adler) - MIPS R5000 (Randers-Pehrson) Post-increment preferred for: - none No measurable difference: - Pentium III (Anderson) - M68060 (Nikl) */ #ifdef POSTINC # define OFF 0 # define PUP(a) *(a)++ #else # define OFF 1 # define PUP(a) *++(a) #endif /* Decode literal, length, and distance codes and write out the resulting literal and match bytes until either not enough input or output is available, an end-of-block is encountered, or a data error is encountered. When large enough input and output buffers are supplied to inflate(), for example, a 16K input buffer and a 64K output buffer, more than 95% of the inflate execution time is spent in this routine. Entry assumptions: state->mode == LEN strm->avail_in >= 6 strm->avail_out >= 258 start >= strm->avail_out state->bits < 8 On return, state->mode is one of: LEN -- ran out of enough output space or enough available input TYPE -- reached end of block code, inflate() to interpret next block BAD -- error in block data Notes: - The maximum input bits used by a length/distance pair is 15 bits for the length code, 5 bits for the length extra, 15 bits for the distance code, and 13 bits for the distance extra. This totals 48 bits, or six bytes. Therefore if strm->avail_in >= 6, then there is enough input to avoid checking for available input while decoding. - The maximum bytes that a single length/distance pair can output is 258 bytes, which is the maximum length that can be coded. inflate_fast() requires strm->avail_out >= 258 for each loop to avoid checking for output space. */ void ZLIB_INTERNAL inflate_fast(strm, start) z_streamp strm; unsigned start; /* inflate()'s starting value for strm->avail_out */ { struct inflate_state FAR *state; unsigned char FAR *in; /* local strm->next_in */ unsigned char FAR *last; /* while in < last, enough input available */ unsigned char FAR *out; /* local strm->next_out */ unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ unsigned char FAR *end; /* while out < end, enough space available */ #ifdef INFLATE_STRICT unsigned dmax; /* maximum distance from zlib header */ #endif unsigned wsize; /* window size or zero if not using window */ unsigned whave; /* valid bytes in the window */ unsigned wnext; /* window write index */ unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ unsigned long hold; /* local strm->hold */ unsigned bits; /* local strm->bits */ code const FAR *lcode; /* local strm->lencode */ code const FAR *dcode; /* local strm->distcode */ unsigned lmask; /* mask for first level of length codes */ unsigned dmask; /* mask for first level of distance codes */ code here; /* retrieved table entry */ unsigned op; /* code bits, operation, extra bits, or */ /* window position, window bytes to copy */ unsigned len; /* match length, unused bytes */ unsigned dist; /* match distance */ unsigned char FAR *from; /* where to copy match from */ /* copy state to local variables */ state = (struct inflate_state FAR *)strm->state; in = strm->next_in - OFF; last = in + (strm->avail_in - 5); out = strm->next_out - OFF; beg = out - (start - strm->avail_out); end = out + (strm->avail_out - 257); #ifdef INFLATE_STRICT dmax = state->dmax; #endif wsize = state->wsize; whave = state->whave; wnext = state->wnext; window = state->window; hold = state->hold; bits = state->bits; lcode = state->lencode; dcode = state->distcode; lmask = (1U << state->lenbits) - 1; dmask = (1U << state->distbits) - 1; /* decode literals and length/distances until end-of-block or not enough input data or output space */ do { if (bits < 15) { hold += (unsigned long)(PUP(in)) << bits; bits += 8; hold += (unsigned long)(PUP(in)) << bits; bits += 8; } here = lcode[hold & lmask]; dolen: op = (unsigned)(here.bits); hold >>= op; bits -= op; op = (unsigned)(here.op); if (op == 0) { /* literal */ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", here.val)); PUP(out) = (unsigned char)(here.val); } else if (op & 16) { /* length base */ len = (unsigned)(here.val); op &= 15; /* number of extra bits */ if (op) { if (bits < op) { hold += (unsigned long)(PUP(in)) << bits; bits += 8; } len += (unsigned)hold & ((1U << op) - 1); hold >>= op; bits -= op; } Tracevv((stderr, "inflate: length %u\n", len)); if (bits < 15) { hold += (unsigned long)(PUP(in)) << bits; bits += 8; hold += (unsigned long)(PUP(in)) << bits; bits += 8; } here = dcode[hold & dmask]; dodist: op = (unsigned)(here.bits); hold >>= op; bits -= op; op = (unsigned)(here.op); if (op & 16) { /* distance base */ dist = (unsigned)(here.val); op &= 15; /* number of extra bits */ if (bits < op) { hold += (unsigned long)(PUP(in)) << bits; bits += 8; if (bits < op) { hold += (unsigned long)(PUP(in)) << bits; bits += 8; } } dist += (unsigned)hold & ((1U << op) - 1); #ifdef INFLATE_STRICT if (dist > dmax) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } #endif hold >>= op; bits -= op; Tracevv((stderr, "inflate: distance %u\n", dist)); op = (unsigned)(out - beg); /* max distance in output */ if (dist > op) { /* see if copy from window */ op = dist - op; /* distance back in window */ if (op > whave) { if (state->sane) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR if (len <= op - whave) { do { PUP(out) = 0; } while (--len); continue; } len -= op - whave; do { PUP(out) = 0; } while (--op > whave); if (op == 0) { from = out - dist; do { PUP(out) = PUP(from); } while (--len); continue; } #endif } from = window - OFF; if (wnext == 0) { /* very common case */ from += wsize - op; if (op < len) { /* some from window */ len -= op; do { PUP(out) = PUP(from); } while (--op); from = out - dist; /* rest from output */ } } else if (wnext < op) { /* wrap around window */ from += wsize + wnext - op; op -= wnext; if (op < len) { /* some from end of window */ len -= op; do { PUP(out) = PUP(from); } while (--op); from = window - OFF; if (wnext < len) { /* some from start of window */ op = wnext; len -= op; do { PUP(out) = PUP(from); } while (--op); from = out - dist; /* rest from output */ } } } else { /* contiguous in window */ from += wnext - op; if (op < len) { /* some from window */ len -= op; do { PUP(out) = PUP(from); } while (--op); from = out - dist; /* rest from output */ } } while (len > 2) { PUP(out) = PUP(from); PUP(out) = PUP(from); PUP(out) = PUP(from); len -= 3; } if (len) { PUP(out) = PUP(from); if (len > 1) PUP(out) = PUP(from); } } else { from = out - dist; /* copy direct from output */ do { /* minimum length is three */ PUP(out) = PUP(from); PUP(out) = PUP(from); PUP(out) = PUP(from); len -= 3; } while (len > 2); if (len) { PUP(out) = PUP(from); if (len > 1) PUP(out) = PUP(from); } } } else if ((op & 64) == 0) { /* 2nd level distance code */ here = dcode[here.val + (hold & ((1U << op) - 1))]; goto dodist; } else { strm->msg = (char *)"invalid distance code"; state->mode = BAD; break; } } else if ((op & 64) == 0) { /* 2nd level length code */ here = lcode[here.val + (hold & ((1U << op) - 1))]; goto dolen; } else if (op & 32) { /* end-of-block */ Tracevv((stderr, "inflate: end of block\n")); state->mode = TYPE; break; } else { strm->msg = (char *)"invalid literal/length code"; state->mode = BAD; break; } } while (in < last && out < end); /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ len = bits >> 3; in -= len; bits -= len << 3; hold &= (1U << bits) - 1; /* update state and return */ strm->next_in = in + OFF; strm->next_out = out + OFF; strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); strm->avail_out = (unsigned)(out < end ? 257 + (end - out) : 257 - (out - end)); state->hold = hold; state->bits = bits; return; } /* inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - Using bit fields for code structure - Different op definition to avoid & for extra bits (do & for table bits) - Three separate decoding do-loops for direct, window, and wnext == 0 - Special case for distance > 1 copies to do overlapped load and store copy - Explicit branch predictions (based on measured branch probabilities) - Deferring match copy and interspersed it with decoding subsequent codes - Swapping literal/length else - Swapping window/direct else - Larger unrolled copy loops (three is about right) - Moving len -= 3 statement into middle of loop */ #endif /* !ASMINF */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/zlib/inffast.h0000644000175100001710000000065300000000000020124 0ustar00vstsdocker/* inffast.h -- header to use inffast.c * Copyright (C) 1995-2003, 2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/zlib/inffixed.h0000644000175100001710000001430700000000000020267 0ustar00vstsdocker /* inffixed.h -- table for decoding fixed codes * Generated automatically by makefixed(). */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ static const code lenfix[512] = { {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, {0,9,255} }; static const code distfix[32] = { {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, {22,5,193},{64,5,0} }; ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/zlib/inflate.c0000644000175100001710000014661700000000000020122 0ustar00vstsdocker/* inflate.c -- zlib decompression * Copyright (C) 1995-2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* * Change history: * * 1.2.beta0 24 Nov 2002 * - First version -- complete rewrite of inflate to simplify code, avoid * creation of window when not needed, minimize use of window when it is * needed, make inffast.c even faster, implement gzip decoding, and to * improve code readability and style over the previous zlib inflate code * * 1.2.beta1 25 Nov 2002 * - Use pointers for available input and output checking in inffast.c * - Remove input and output counters in inffast.c * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 * - Remove unnecessary second byte pull from length extra in inffast.c * - Unroll direct copy to three copies per loop in inffast.c * * 1.2.beta2 4 Dec 2002 * - Change external routine names to reduce potential conflicts * - Correct filename to inffixed.h for fixed tables in inflate.c * - Make hbuf[] unsigned char to match parameter type in inflate.c * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) * to avoid negation problem on Alphas (64 bit) in inflate.c * * 1.2.beta3 22 Dec 2002 * - Add comments on state->bits assertion in inffast.c * - Add comments on op field in inftrees.h * - Fix bug in reuse of allocated window after inflateReset() * - Remove bit fields--back to byte structure for speed * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths * - Change post-increments to pre-increments in inflate_fast(), PPC biased? * - Add compile time option, POSTINC, to use post-increments instead (Intel?) * - Make MATCH copy in inflate() much faster for when inflate_fast() not used * - Use local copies of stream next and avail values, as well as local bit * buffer and bit count in inflate()--for speed when inflate_fast() not used * * 1.2.beta4 1 Jan 2003 * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings * - Move a comment on output buffer sizes from inffast.c to inflate.c * - Add comments in inffast.c to introduce the inflate_fast() routine * - Rearrange window copies in inflate_fast() for speed and simplification * - Unroll last copy for window match in inflate_fast() * - Use local copies of window variables in inflate_fast() for speed * - Pull out common wnext == 0 case for speed in inflate_fast() * - Make op and len in inflate_fast() unsigned for consistency * - Add FAR to lcode and dcode declarations in inflate_fast() * - Simplified bad distance check in inflate_fast() * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new * source file infback.c to provide a call-back interface to inflate for * programs like gzip and unzip -- uses window as output buffer to avoid * window copying * * 1.2.beta5 1 Jan 2003 * - Improved inflateBack() interface to allow the caller to provide initial * input in strm. * - Fixed stored blocks bug in inflateBack() * * 1.2.beta6 4 Jan 2003 * - Added comments in inffast.c on effectiveness of POSTINC * - Typecasting all around to reduce compiler warnings * - Changed loops from while (1) or do {} while (1) to for (;;), again to * make compilers happy * - Changed type of window in inflateBackInit() to unsigned char * * * 1.2.beta7 27 Jan 2003 * - Changed many types to unsigned or unsigned short to avoid warnings * - Added inflateCopy() function * * 1.2.0 9 Mar 2003 * - Changed inflateBack() interface to provide separate opaque descriptors * for the in() and out() functions * - Changed inflateBack() argument and in_func typedef to swap the length * and buffer address return values for the input function * - Check next_in and next_out for Z_NULL on entry to inflate() * * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. */ #include "zutil.h" #include "inftrees.h" #include "inflate.h" #include "inffast.h" #ifdef MAKEFIXED # ifndef BUILDFIXED # define BUILDFIXED # endif #endif /* function prototypes */ local void fixedtables OF((struct inflate_state FAR *state)); local int updatewindow OF((z_streamp strm, unsigned out)); #ifdef BUILDFIXED void makefixed OF((void)); #endif local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, unsigned len)); int ZEXPORT inflateReset(strm) z_streamp strm; { struct inflate_state FAR *state; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; strm->total_in = strm->total_out = state->total = 0; strm->msg = Z_NULL; strm->adler = 1; /* to support ill-conceived Java test suite */ state->mode = HEAD; state->last = 0; state->havedict = 0; state->dmax = 32768U; state->head = Z_NULL; state->wsize = 0; state->whave = 0; state->wnext = 0; state->hold = 0; state->bits = 0; state->lencode = state->distcode = state->next = state->codes; state->sane = 1; state->back = -1; Tracev((stderr, "inflate: reset\n")); return Z_OK; } int ZEXPORT inflateReset2(strm, windowBits) z_streamp strm; int windowBits; { int wrap; struct inflate_state FAR *state; /* get the state */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; /* extract wrap request from windowBits parameter */ if (windowBits < 0) { wrap = 0; windowBits = -windowBits; } else { wrap = (windowBits >> 4) + 1; #ifdef GUNZIP if (windowBits < 48) windowBits &= 15; #endif } /* set number of window bits, free window if different */ if (windowBits && (windowBits < 8 || windowBits > 15)) return Z_STREAM_ERROR; if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { ZFREE(strm, state->window); state->window = Z_NULL; } /* update state and reset the rest of it */ state->wrap = wrap; state->wbits = (unsigned)windowBits; return inflateReset(strm); } int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) z_streamp strm; int windowBits; const char *version; int stream_size; { int ret; struct inflate_state FAR *state; if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || stream_size != (int)(sizeof(z_stream))) return Z_VERSION_ERROR; if (strm == Z_NULL) return Z_STREAM_ERROR; strm->msg = Z_NULL; /* in case we return an error */ if (strm->zalloc == (alloc_func)0) { strm->zalloc = zcalloc; strm->opaque = (voidpf)0; } if (strm->zfree == (free_func)0) strm->zfree = zcfree; state = (struct inflate_state FAR *) ZALLOC(strm, 1, sizeof(struct inflate_state)); if (state == Z_NULL) return Z_MEM_ERROR; Tracev((stderr, "inflate: allocated\n")); strm->state = (struct internal_state FAR *)state; state->window = Z_NULL; ret = inflateReset2(strm, windowBits); if (ret != Z_OK) { ZFREE(strm, state); strm->state = Z_NULL; } return ret; } int ZEXPORT inflateInit_(strm, version, stream_size) z_streamp strm; const char *version; int stream_size; { return inflateInit2_(strm, DEF_WBITS, version, stream_size); } int ZEXPORT inflatePrime(strm, bits, value) z_streamp strm; int bits; int value; { struct inflate_state FAR *state; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (bits < 0) { state->hold = 0; state->bits = 0; return Z_OK; } if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; value &= (1L << bits) - 1; state->hold += value << state->bits; state->bits += bits; return Z_OK; } /* Return state with length and distance decoding tables and index sizes set to fixed code decoding. Normally this returns fixed tables from inffixed.h. If BUILDFIXED is defined, then instead this routine builds the tables the first time it's called, and returns those tables the first time and thereafter. This reduces the size of the code by about 2K bytes, in exchange for a little execution time. However, BUILDFIXED should not be used for threaded applications, since the rewriting of the tables and virgin may not be thread-safe. */ local void fixedtables(state) struct inflate_state FAR *state; { #ifdef BUILDFIXED static int virgin = 1; static code *lenfix, *distfix; static code fixed[544]; /* build fixed huffman tables if first call (may not be thread safe) */ if (virgin) { unsigned sym, bits; static code *next; /* literal/length table */ sym = 0; while (sym < 144) state->lens[sym++] = 8; while (sym < 256) state->lens[sym++] = 9; while (sym < 280) state->lens[sym++] = 7; while (sym < 288) state->lens[sym++] = 8; next = fixed; lenfix = next; bits = 9; inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); /* distance table */ sym = 0; while (sym < 32) state->lens[sym++] = 5; distfix = next; bits = 5; inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); /* do this just once */ virgin = 0; } #else /* !BUILDFIXED */ # include "inffixed.h" #endif /* BUILDFIXED */ state->lencode = lenfix; state->lenbits = 9; state->distcode = distfix; state->distbits = 5; } #ifdef MAKEFIXED #include /* Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also defines BUILDFIXED, so the tables are built on the fly. makefixed() writes those tables to stdout, which would be piped to inffixed.h. A small program can simply call makefixed to do this: void makefixed(void); int main(void) { makefixed(); return 0; } Then that can be linked with zlib built with MAKEFIXED defined and run: a.out > inffixed.h */ void makefixed() { unsigned low, size; struct inflate_state state; fixedtables(&state); puts(" /* inffixed.h -- table for decoding fixed codes"); puts(" * Generated automatically by makefixed()."); puts(" */"); puts(""); puts(" /* WARNING: this file should *not* be used by applications."); puts(" It is part of the implementation of this library and is"); puts(" subject to change. Applications should only use zlib.h."); puts(" */"); puts(""); size = 1U << 9; printf(" static const code lenfix[%u] = {", size); low = 0; for (;;) { if ((low % 7) == 0) printf("\n "); printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, state.lencode[low].val); if (++low == size) break; putchar(','); } puts("\n };"); size = 1U << 5; printf("\n static const code distfix[%u] = {", size); low = 0; for (;;) { if ((low % 6) == 0) printf("\n "); printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, state.distcode[low].val); if (++low == size) break; putchar(','); } puts("\n };"); } #endif /* MAKEFIXED */ /* Update the window with the last wsize (normally 32K) bytes written before returning. If window does not exist yet, create it. This is only called when a window is already in use, or when output has been written during this inflate call, but the end of the deflate stream has not been reached yet. It is also called to create a window for dictionary data when a dictionary is loaded. Providing output buffers larger than 32K to inflate() should provide a speed advantage, since only the last 32K of output is copied to the sliding window upon return from inflate(), and since all distances after the first 32K of output will fall in the output data, making match copies simpler and faster. The advantage may be dependent on the size of the processor's data caches. */ local int updatewindow(strm, out) z_streamp strm; unsigned out; { struct inflate_state FAR *state; unsigned copy, dist; state = (struct inflate_state FAR *)strm->state; /* if it hasn't been done already, allocate space for the window */ if (state->window == Z_NULL) { state->window = (unsigned char FAR *) ZALLOC(strm, 1U << state->wbits, sizeof(unsigned char)); if (state->window == Z_NULL) return 1; } /* if window not in use yet, initialize */ if (state->wsize == 0) { state->wsize = 1U << state->wbits; state->wnext = 0; state->whave = 0; } /* copy state->wsize or less output bytes into the circular window */ copy = out - strm->avail_out; if (copy >= state->wsize) { zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); state->wnext = 0; state->whave = state->wsize; } else { dist = state->wsize - state->wnext; if (dist > copy) dist = copy; zmemcpy(state->window + state->wnext, strm->next_out - copy, dist); copy -= dist; if (copy) { zmemcpy(state->window, strm->next_out - copy, copy); state->wnext = copy; state->whave = state->wsize; } else { state->wnext += dist; if (state->wnext == state->wsize) state->wnext = 0; if (state->whave < state->wsize) state->whave += dist; } } return 0; } /* Macros for inflate(): */ /* check function to use adler32() for zlib or crc32() for gzip */ #ifdef GUNZIP # define UPDATE(check, buf, len) \ (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) #else # define UPDATE(check, buf, len) adler32(check, buf, len) #endif /* check macros for header crc */ #ifdef GUNZIP # define CRC2(check, word) \ do { \ hbuf[0] = (unsigned char)(word); \ hbuf[1] = (unsigned char)((word) >> 8); \ check = crc32(check, hbuf, 2); \ } while (0) # define CRC4(check, word) \ do { \ hbuf[0] = (unsigned char)(word); \ hbuf[1] = (unsigned char)((word) >> 8); \ hbuf[2] = (unsigned char)((word) >> 16); \ hbuf[3] = (unsigned char)((word) >> 24); \ check = crc32(check, hbuf, 4); \ } while (0) #endif /* Load registers with state in inflate() for speed */ #define LOAD() \ do { \ put = strm->next_out; \ left = strm->avail_out; \ next = strm->next_in; \ have = strm->avail_in; \ hold = state->hold; \ bits = state->bits; \ } while (0) /* Restore state from registers in inflate() */ #define RESTORE() \ do { \ strm->next_out = put; \ strm->avail_out = left; \ strm->next_in = next; \ strm->avail_in = have; \ state->hold = hold; \ state->bits = bits; \ } while (0) /* Clear the input bit accumulator */ #define INITBITS() \ do { \ hold = 0; \ bits = 0; \ } while (0) /* Get a byte of input into the bit accumulator, or return from inflate() if there is no input available. */ #define PULLBYTE() \ do { \ if (have == 0) goto inf_leave; \ have--; \ hold += (unsigned long)(*next++) << bits; \ bits += 8; \ } while (0) /* Assure that there are at least n bits in the bit accumulator. If there is not enough available input to do that, then return from inflate(). */ #define NEEDBITS(n) \ do { \ while (bits < (unsigned)(n)) \ PULLBYTE(); \ } while (0) /* Return the low n bits of the bit accumulator (n < 16) */ #define BITS(n) \ ((unsigned)hold & ((1U << (n)) - 1)) /* Remove n bits from the bit accumulator */ #define DROPBITS(n) \ do { \ hold >>= (n); \ bits -= (unsigned)(n); \ } while (0) /* Remove zero to seven bits as needed to go to a byte boundary */ #define BYTEBITS() \ do { \ hold >>= bits & 7; \ bits -= bits & 7; \ } while (0) /* Reverse the bytes in a 32-bit value */ #define REVERSE(q) \ ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) /* inflate() uses a state machine to process as much input data and generate as much output data as possible before returning. The state machine is structured roughly as follows: for (;;) switch (state) { ... case STATEn: if (not enough input data or output space to make progress) return; ... make progress ... state = STATEm; break; ... } so when inflate() is called again, the same case is attempted again, and if the appropriate resources are provided, the machine proceeds to the next state. The NEEDBITS() macro is usually the way the state evaluates whether it can proceed or should return. NEEDBITS() does the return if the requested bits are not available. The typical use of the BITS macros is: NEEDBITS(n); ... do something with BITS(n) ... DROPBITS(n); where NEEDBITS(n) either returns from inflate() if there isn't enough input left to load n bits into the accumulator, or it continues. BITS(n) gives the low n bits in the accumulator. When done, DROPBITS(n) drops the low n bits off the accumulator. INITBITS() clears the accumulator and sets the number of available bits to zero. BYTEBITS() discards just enough bits to put the accumulator on a byte boundary. After BYTEBITS() and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return if there is no input available. The decoding of variable length codes uses PULLBYTE() directly in order to pull just enough bytes to decode the next code, and no more. Some states loop until they get enough input, making sure that enough state information is maintained to continue the loop where it left off if NEEDBITS() returns in the loop. For example, want, need, and keep would all have to actually be part of the saved state in case NEEDBITS() returns: case STATEw: while (want < need) { NEEDBITS(n); keep[want++] = BITS(n); DROPBITS(n); } state = STATEx; case STATEx: As shown above, if the next state is also the next case, then the break is omitted. A state may also return if there is not enough output space available to complete that state. Those states are copying stored data, writing a literal byte, and copying a matching string. When returning, a "goto inf_leave" is used to update the total counters, update the check value, and determine whether any progress has been made during that inflate() call in order to return the proper return code. Progress is defined as a change in either strm->avail_in or strm->avail_out. When there is a window, goto inf_leave will update the window with the last output written. If a goto inf_leave occurs in the middle of decompression and there is no window currently, goto inf_leave will create one and copy output to the window for the next call of inflate(). In this implementation, the flush parameter of inflate() only affects the return code (per zlib.h). inflate() always writes as much as possible to strm->next_out, given the space available and the provided input--the effect documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers the allocation of and copying into a sliding window until necessary, which provides the effect documented in zlib.h for Z_FINISH when the entire input stream available. So the only thing the flush parameter actually does is: when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it will return Z_BUF_ERROR if it has not reached the end of the stream. */ int ZEXPORT inflate(strm, flush) z_streamp strm; int flush; { struct inflate_state FAR *state; unsigned char FAR *next; /* next input */ unsigned char FAR *put; /* next output */ unsigned have, left; /* available input and output */ unsigned long hold; /* bit buffer */ unsigned bits; /* bits in bit buffer */ unsigned in, out; /* save starting available input and output */ unsigned copy; /* number of stored or match bytes to copy */ unsigned char FAR *from; /* where to copy match bytes from */ code here; /* current decoding table entry */ code last; /* parent table entry */ unsigned len; /* length to copy for repeats, bits to drop */ int ret; /* return code */ #ifdef GUNZIP unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ #endif static const unsigned short order[19] = /* permutation of code lengths */ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || (strm->next_in == Z_NULL && strm->avail_in != 0)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ LOAD(); in = have; out = left; ret = Z_OK; for (;;) switch (state->mode) { case HEAD: if (state->wrap == 0) { state->mode = TYPEDO; break; } NEEDBITS(16); #ifdef GUNZIP if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ state->check = crc32(0L, Z_NULL, 0); CRC2(state->check, hold); INITBITS(); state->mode = FLAGS; break; } state->flags = 0; /* expect zlib header */ if (state->head != Z_NULL) state->head->done = -1; if (!(state->wrap & 1) || /* check if zlib header allowed */ #else if ( #endif ((BITS(8) << 8) + (hold >> 8)) % 31) { strm->msg = (char *)"incorrect header check"; state->mode = BAD; break; } if (BITS(4) != Z_DEFLATED) { strm->msg = (char *)"unknown compression method"; state->mode = BAD; break; } DROPBITS(4); len = BITS(4) + 8; if (state->wbits == 0) state->wbits = len; else if (len > state->wbits) { strm->msg = (char *)"invalid window size"; state->mode = BAD; break; } state->dmax = 1U << len; Tracev((stderr, "inflate: zlib header ok\n")); strm->adler = state->check = adler32(0L, Z_NULL, 0); state->mode = hold & 0x200 ? DICTID : TYPE; INITBITS(); break; #ifdef GUNZIP case FLAGS: NEEDBITS(16); state->flags = (int)(hold); if ((state->flags & 0xff) != Z_DEFLATED) { strm->msg = (char *)"unknown compression method"; state->mode = BAD; break; } if (state->flags & 0xe000) { strm->msg = (char *)"unknown header flags set"; state->mode = BAD; break; } if (state->head != Z_NULL) state->head->text = (int)((hold >> 8) & 1); if (state->flags & 0x0200) CRC2(state->check, hold); INITBITS(); state->mode = TIME; case TIME: NEEDBITS(32); if (state->head != Z_NULL) state->head->time = hold; if (state->flags & 0x0200) CRC4(state->check, hold); INITBITS(); state->mode = OS; case OS: NEEDBITS(16); if (state->head != Z_NULL) { state->head->xflags = (int)(hold & 0xff); state->head->os = (int)(hold >> 8); } if (state->flags & 0x0200) CRC2(state->check, hold); INITBITS(); state->mode = EXLEN; case EXLEN: if (state->flags & 0x0400) { NEEDBITS(16); state->length = (unsigned)(hold); if (state->head != Z_NULL) state->head->extra_len = (unsigned)hold; if (state->flags & 0x0200) CRC2(state->check, hold); INITBITS(); } else if (state->head != Z_NULL) state->head->extra = Z_NULL; state->mode = EXTRA; case EXTRA: if (state->flags & 0x0400) { copy = state->length; if (copy > have) copy = have; if (copy) { if (state->head != Z_NULL && state->head->extra != Z_NULL) { len = state->head->extra_len - state->length; zmemcpy(state->head->extra + len, next, len + copy > state->head->extra_max ? state->head->extra_max - len : copy); } if (state->flags & 0x0200) state->check = crc32(state->check, next, copy); have -= copy; next += copy; state->length -= copy; } if (state->length) goto inf_leave; } state->length = 0; state->mode = NAME; case NAME: if (state->flags & 0x0800) { if (have == 0) goto inf_leave; copy = 0; do { len = (unsigned)(next[copy++]); if (state->head != Z_NULL && state->head->name != Z_NULL && state->length < state->head->name_max) state->head->name[state->length++] = len; } while (len && copy < have); if (state->flags & 0x0200) state->check = crc32(state->check, next, copy); have -= copy; next += copy; if (len) goto inf_leave; } else if (state->head != Z_NULL) state->head->name = Z_NULL; state->length = 0; state->mode = COMMENT; case COMMENT: if (state->flags & 0x1000) { if (have == 0) goto inf_leave; copy = 0; do { len = (unsigned)(next[copy++]); if (state->head != Z_NULL && state->head->comment != Z_NULL && state->length < state->head->comm_max) state->head->comment[state->length++] = len; } while (len && copy < have); if (state->flags & 0x0200) state->check = crc32(state->check, next, copy); have -= copy; next += copy; if (len) goto inf_leave; } else if (state->head != Z_NULL) state->head->comment = Z_NULL; state->mode = HCRC; case HCRC: if (state->flags & 0x0200) { NEEDBITS(16); if (hold != (state->check & 0xffff)) { strm->msg = (char *)"header crc mismatch"; state->mode = BAD; break; } INITBITS(); } if (state->head != Z_NULL) { state->head->hcrc = (int)((state->flags >> 9) & 1); state->head->done = 1; } strm->adler = state->check = crc32(0L, Z_NULL, 0); state->mode = TYPE; break; #endif case DICTID: NEEDBITS(32); strm->adler = state->check = REVERSE(hold); INITBITS(); state->mode = DICT; case DICT: if (state->havedict == 0) { RESTORE(); return Z_NEED_DICT; } strm->adler = state->check = adler32(0L, Z_NULL, 0); state->mode = TYPE; case TYPE: if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; case TYPEDO: if (state->last) { BYTEBITS(); state->mode = CHECK; break; } NEEDBITS(3); state->last = BITS(1); DROPBITS(1); switch (BITS(2)) { case 0: /* stored block */ Tracev((stderr, "inflate: stored block%s\n", state->last ? " (last)" : "")); state->mode = STORED; break; case 1: /* fixed block */ fixedtables(state); Tracev((stderr, "inflate: fixed codes block%s\n", state->last ? " (last)" : "")); state->mode = LEN_; /* decode codes */ if (flush == Z_TREES) { DROPBITS(2); goto inf_leave; } break; case 2: /* dynamic block */ Tracev((stderr, "inflate: dynamic codes block%s\n", state->last ? " (last)" : "")); state->mode = TABLE; break; case 3: strm->msg = (char *)"invalid block type"; state->mode = BAD; } DROPBITS(2); break; case STORED: BYTEBITS(); /* go to byte boundary */ NEEDBITS(32); if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { strm->msg = (char *)"invalid stored block lengths"; state->mode = BAD; break; } state->length = (unsigned)hold & 0xffff; Tracev((stderr, "inflate: stored length %u\n", state->length)); INITBITS(); state->mode = COPY_; if (flush == Z_TREES) goto inf_leave; case COPY_: state->mode = COPY; case COPY: copy = state->length; if (copy) { if (copy > have) copy = have; if (copy > left) copy = left; if (copy == 0) goto inf_leave; zmemcpy(put, next, copy); have -= copy; next += copy; left -= copy; put += copy; state->length -= copy; break; } Tracev((stderr, "inflate: stored end\n")); state->mode = TYPE; break; case TABLE: NEEDBITS(14); state->nlen = BITS(5) + 257; DROPBITS(5); state->ndist = BITS(5) + 1; DROPBITS(5); state->ncode = BITS(4) + 4; DROPBITS(4); #ifndef PKZIP_BUG_WORKAROUND if (state->nlen > 286 || state->ndist > 30) { strm->msg = (char *)"too many length or distance symbols"; state->mode = BAD; break; } #endif Tracev((stderr, "inflate: table sizes ok\n")); state->have = 0; state->mode = LENLENS; case LENLENS: while (state->have < state->ncode) { NEEDBITS(3); state->lens[order[state->have++]] = (unsigned short)BITS(3); DROPBITS(3); } while (state->have < 19) state->lens[order[state->have++]] = 0; state->next = state->codes; state->lencode = (code const FAR *)(state->next); state->lenbits = 7; ret = inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); if (ret) { strm->msg = (char *)"invalid code lengths set"; state->mode = BAD; break; } Tracev((stderr, "inflate: code lengths ok\n")); state->have = 0; state->mode = CODELENS; case CODELENS: while (state->have < state->nlen + state->ndist) { for (;;) { here = state->lencode[BITS(state->lenbits)]; if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } if (here.val < 16) { NEEDBITS(here.bits); DROPBITS(here.bits); state->lens[state->have++] = here.val; } else { if (here.val == 16) { NEEDBITS(here.bits + 2); DROPBITS(here.bits); if (state->have == 0) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; break; } len = state->lens[state->have - 1]; copy = 3 + BITS(2); DROPBITS(2); } else if (here.val == 17) { NEEDBITS(here.bits + 3); DROPBITS(here.bits); len = 0; copy = 3 + BITS(3); DROPBITS(3); } else { NEEDBITS(here.bits + 7); DROPBITS(here.bits); len = 0; copy = 11 + BITS(7); DROPBITS(7); } if (state->have + copy > state->nlen + state->ndist) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; break; } while (copy--) state->lens[state->have++] = (unsigned short)len; } } /* handle error breaks in while */ if (state->mode == BAD) break; /* check for end-of-block code (better have one) */ if (state->lens[256] == 0) { strm->msg = (char *)"invalid code -- missing end-of-block"; state->mode = BAD; break; } /* build code tables -- note: do not change the lenbits or distbits values here (9 and 6) without reading the comments in inftrees.h concerning the ENOUGH constants, which depend on those values */ state->next = state->codes; state->lencode = (code const FAR *)(state->next); state->lenbits = 9; ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work); if (ret) { strm->msg = (char *)"invalid literal/lengths set"; state->mode = BAD; break; } state->distcode = (code const FAR *)(state->next); state->distbits = 6; ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, &(state->next), &(state->distbits), state->work); if (ret) { strm->msg = (char *)"invalid distances set"; state->mode = BAD; break; } Tracev((stderr, "inflate: codes ok\n")); state->mode = LEN_; if (flush == Z_TREES) goto inf_leave; case LEN_: state->mode = LEN; case LEN: if (have >= 6 && left >= 258) { RESTORE(); inflate_fast(strm, out); LOAD(); if (state->mode == TYPE) state->back = -1; break; } state->back = 0; for (;;) { here = state->lencode[BITS(state->lenbits)]; if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } if (here.op && (here.op & 0xf0) == 0) { last = here; for (;;) { here = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + here.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); state->back += last.bits; } DROPBITS(here.bits); state->back += here.bits; state->length = (unsigned)here.val; if ((int)(here.op) == 0) { Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", here.val)); state->mode = LIT; break; } if (here.op & 32) { Tracevv((stderr, "inflate: end of block\n")); state->back = -1; state->mode = TYPE; break; } if (here.op & 64) { strm->msg = (char *)"invalid literal/length code"; state->mode = BAD; break; } state->extra = (unsigned)(here.op) & 15; state->mode = LENEXT; case LENEXT: if (state->extra) { NEEDBITS(state->extra); state->length += BITS(state->extra); DROPBITS(state->extra); state->back += state->extra; } Tracevv((stderr, "inflate: length %u\n", state->length)); state->was = state->length; state->mode = DIST; case DIST: for (;;) { here = state->distcode[BITS(state->distbits)]; if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } if ((here.op & 0xf0) == 0) { last = here; for (;;) { here = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + here.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); state->back += last.bits; } DROPBITS(here.bits); state->back += here.bits; if (here.op & 64) { strm->msg = (char *)"invalid distance code"; state->mode = BAD; break; } state->offset = (unsigned)here.val; state->extra = (unsigned)(here.op) & 15; state->mode = DISTEXT; case DISTEXT: if (state->extra) { NEEDBITS(state->extra); state->offset += BITS(state->extra); DROPBITS(state->extra); state->back += state->extra; } #ifdef INFLATE_STRICT if (state->offset > state->dmax) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } #endif Tracevv((stderr, "inflate: distance %u\n", state->offset)); state->mode = MATCH; case MATCH: if (left == 0) goto inf_leave; copy = out - left; if (state->offset > copy) { /* copy from window */ copy = state->offset - copy; if (copy > state->whave) { if (state->sane) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR Trace((stderr, "inflate.c too far\n")); copy -= state->whave; if (copy > state->length) copy = state->length; if (copy > left) copy = left; left -= copy; state->length -= copy; do { *put++ = 0; } while (--copy); if (state->length == 0) state->mode = LEN; break; #endif } if (copy > state->wnext) { copy -= state->wnext; from = state->window + (state->wsize - copy); } else from = state->window + (state->wnext - copy); if (copy > state->length) copy = state->length; } else { /* copy from output */ from = put - state->offset; copy = state->length; } if (copy > left) copy = left; left -= copy; state->length -= copy; do { *put++ = *from++; } while (--copy); if (state->length == 0) state->mode = LEN; break; case LIT: if (left == 0) goto inf_leave; *put++ = (unsigned char)(state->length); left--; state->mode = LEN; break; case CHECK: if (state->wrap) { NEEDBITS(32); out -= left; strm->total_out += out; state->total += out; if (out) strm->adler = state->check = UPDATE(state->check, put - out, out); out = left; if (( #ifdef GUNZIP state->flags ? hold : #endif REVERSE(hold)) != state->check) { strm->msg = (char *)"incorrect data check"; state->mode = BAD; break; } INITBITS(); Tracev((stderr, "inflate: check matches trailer\n")); } #ifdef GUNZIP state->mode = LENGTH; case LENGTH: if (state->wrap && state->flags) { NEEDBITS(32); if (hold != (state->total & 0xffffffffUL)) { strm->msg = (char *)"incorrect length check"; state->mode = BAD; break; } INITBITS(); Tracev((stderr, "inflate: length matches trailer\n")); } #endif state->mode = DONE; case DONE: ret = Z_STREAM_END; goto inf_leave; case BAD: ret = Z_DATA_ERROR; goto inf_leave; case MEM: return Z_MEM_ERROR; case SYNC: default: return Z_STREAM_ERROR; } /* Return from inflate(), updating the total counts and the check value. If there was no progress during the inflate() call, return a buffer error. Call updatewindow() to create and/or update the window state. Note: a memory error from inflate() is non-recoverable. */ inf_leave: RESTORE(); if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) if (updatewindow(strm, out)) { state->mode = MEM; return Z_MEM_ERROR; } in -= strm->avail_in; out -= strm->avail_out; strm->total_in += in; strm->total_out += out; state->total += out; if (state->wrap && out) strm->adler = state->check = UPDATE(state->check, strm->next_out - out, out); strm->data_type = state->bits + (state->last ? 64 : 0) + (state->mode == TYPE ? 128 : 0) + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) ret = Z_BUF_ERROR; return ret; } int ZEXPORT inflateEnd(strm) z_streamp strm; { struct inflate_state FAR *state; if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->window != Z_NULL) ZFREE(strm, state->window); ZFREE(strm, strm->state); strm->state = Z_NULL; Tracev((stderr, "inflate: end\n")); return Z_OK; } int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) z_streamp strm; const Bytef *dictionary; uInt dictLength; { struct inflate_state FAR *state; unsigned long id; /* check state */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->wrap != 0 && state->mode != DICT) return Z_STREAM_ERROR; /* check for correct dictionary id */ if (state->mode == DICT) { id = adler32(0L, Z_NULL, 0); id = adler32(id, dictionary, dictLength); if (id != state->check) return Z_DATA_ERROR; } /* copy dictionary to window */ if (updatewindow(strm, strm->avail_out)) { state->mode = MEM; return Z_MEM_ERROR; } if (dictLength > state->wsize) { zmemcpy(state->window, dictionary + dictLength - state->wsize, state->wsize); state->whave = state->wsize; } else { zmemcpy(state->window + state->wsize - dictLength, dictionary, dictLength); state->whave = dictLength; } state->havedict = 1; Tracev((stderr, "inflate: dictionary set\n")); return Z_OK; } int ZEXPORT inflateGetHeader(strm, head) z_streamp strm; gz_headerp head; { struct inflate_state FAR *state; /* check state */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; /* save header structure */ state->head = head; head->done = 0; return Z_OK; } /* Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found or when out of input. When called, *have is the number of pattern bytes found in order so far, in 0..3. On return *have is updated to the new state. If on return *have equals four, then the pattern was found and the return value is how many bytes were read including the last byte of the pattern. If *have is less than four, then the pattern has not been found yet and the return value is len. In the latter case, syncsearch() can be called again with more data and the *have state. *have is initialized to zero for the first call. */ local unsigned syncsearch(have, buf, len) unsigned FAR *have; unsigned char FAR *buf; unsigned len; { unsigned got; unsigned next; got = *have; next = 0; while (next < len && got < 4) { if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) got++; else if (buf[next]) got = 0; else got = 4 - got; next++; } *have = got; return next; } int ZEXPORT inflateSync(strm) z_streamp strm; { unsigned len; /* number of bytes to look at or looked at */ unsigned long in, out; /* temporary to save total_in and total_out */ unsigned char buf[4]; /* to restore bit buffer to byte string */ struct inflate_state FAR *state; /* check parameters */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; /* if first time, start search in bit buffer */ if (state->mode != SYNC) { state->mode = SYNC; state->hold <<= state->bits & 7; state->bits -= state->bits & 7; len = 0; while (state->bits >= 8) { buf[len++] = (unsigned char)(state->hold); state->hold >>= 8; state->bits -= 8; } state->have = 0; syncsearch(&(state->have), buf, len); } /* search available input */ len = syncsearch(&(state->have), strm->next_in, strm->avail_in); strm->avail_in -= len; strm->next_in += len; strm->total_in += len; /* return no joy or set up to restart inflate() on a new block */ if (state->have != 4) return Z_DATA_ERROR; in = strm->total_in; out = strm->total_out; inflateReset(strm); strm->total_in = in; strm->total_out = out; state->mode = TYPE; return Z_OK; } /* Returns true if inflate is currently at the end of a block generated by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored block. When decompressing, PPP checks that at the end of input packet, inflate is waiting for these length bytes. */ int ZEXPORT inflateSyncPoint(strm) z_streamp strm; { struct inflate_state FAR *state; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; return state->mode == STORED && state->bits == 0; } int ZEXPORT inflateCopy(dest, source) z_streamp dest; z_streamp source; { struct inflate_state FAR *state; struct inflate_state FAR *copy; unsigned char FAR *window; unsigned wsize; /* check input */ if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)source->state; /* allocate space */ copy = (struct inflate_state FAR *) ZALLOC(source, 1, sizeof(struct inflate_state)); if (copy == Z_NULL) return Z_MEM_ERROR; window = Z_NULL; if (state->window != Z_NULL) { window = (unsigned char FAR *) ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); if (window == Z_NULL) { ZFREE(source, copy); return Z_MEM_ERROR; } } /* copy state */ zmemcpy(dest, source, sizeof(z_stream)); zmemcpy(copy, state, sizeof(struct inflate_state)); if (state->lencode >= state->codes && state->lencode <= state->codes + ENOUGH - 1) { copy->lencode = copy->codes + (state->lencode - state->codes); copy->distcode = copy->codes + (state->distcode - state->codes); } copy->next = copy->codes + (state->next - state->codes); if (window != Z_NULL) { wsize = 1U << state->wbits; zmemcpy(window, state->window, wsize); } copy->window = window; dest->state = (struct internal_state FAR *)copy; return Z_OK; } int ZEXPORT inflateUndermine(strm, subvert) z_streamp strm; int subvert; { struct inflate_state FAR *state; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; state->sane = !subvert; #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR return Z_OK; #else state->sane = 1; return Z_DATA_ERROR; #endif } long ZEXPORT inflateMark(strm) z_streamp strm; { struct inflate_state FAR *state; if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; state = (struct inflate_state FAR *)strm->state; return ((long)(state->back) << 16) + (state->mode == COPY ? state->length : (state->mode == MATCH ? state->was - state->length : 0)); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/zlib/inflate.h0000644000175100001710000001437700000000000020124 0ustar00vstsdocker/* inflate.h -- internal inflate state definition * Copyright (C) 1995-2009 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ /* define NO_GZIP when compiling if you want to disable gzip header and trailer decoding by inflate(). NO_GZIP would be used to avoid linking in the crc code when it is not needed. For shared libraries, gzip decoding should be left enabled. */ #ifndef NO_GZIP # define GUNZIP #endif /* Possible inflate modes between inflate() calls */ typedef enum { HEAD, /* i: waiting for magic header */ FLAGS, /* i: waiting for method and flags (gzip) */ TIME, /* i: waiting for modification time (gzip) */ OS, /* i: waiting for extra flags and operating system (gzip) */ EXLEN, /* i: waiting for extra length (gzip) */ EXTRA, /* i: waiting for extra bytes (gzip) */ NAME, /* i: waiting for end of file name (gzip) */ COMMENT, /* i: waiting for end of comment (gzip) */ HCRC, /* i: waiting for header crc (gzip) */ DICTID, /* i: waiting for dictionary check value */ DICT, /* waiting for inflateSetDictionary() call */ TYPE, /* i: waiting for type bits, including last-flag bit */ TYPEDO, /* i: same, but skip check to exit inflate on new block */ STORED, /* i: waiting for stored size (length and complement) */ COPY_, /* i/o: same as COPY below, but only first time in */ COPY, /* i/o: waiting for input or output to copy stored block */ TABLE, /* i: waiting for dynamic block table lengths */ LENLENS, /* i: waiting for code length code lengths */ CODELENS, /* i: waiting for length/lit and distance code lengths */ LEN_, /* i: same as LEN below, but only first time in */ LEN, /* i: waiting for length/lit/eob code */ LENEXT, /* i: waiting for length extra bits */ DIST, /* i: waiting for distance code */ DISTEXT, /* i: waiting for distance extra bits */ MATCH, /* o: waiting for output space to copy string */ LIT, /* o: waiting for output space to write literal */ CHECK, /* i: waiting for 32-bit check value */ LENGTH, /* i: waiting for 32-bit length (gzip) */ DONE, /* finished check, done -- remain here until reset */ BAD, /* got a data error -- remain here until reset */ MEM, /* got an inflate() memory error -- remain here until reset */ SYNC /* looking for synchronization bytes to restart inflate() */ } inflate_mode; /* State transitions between above modes - (most modes can go to BAD or MEM on error -- not shown for clarity) Process header: HEAD -> (gzip) or (zlib) or (raw) (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> HCRC -> TYPE (zlib) -> DICTID or TYPE DICTID -> DICT -> TYPE (raw) -> TYPEDO Read deflate blocks: TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK STORED -> COPY_ -> COPY -> TYPE TABLE -> LENLENS -> CODELENS -> LEN_ LEN_ -> LEN Read deflate codes in fixed or dynamic block: LEN -> LENEXT or LIT or TYPE LENEXT -> DIST -> DISTEXT -> MATCH -> LEN LIT -> LEN Process trailer: CHECK -> LENGTH -> DONE */ /* state maintained between inflate() calls. Approximately 10K bytes. */ struct inflate_state { inflate_mode mode; /* current inflate mode */ int last; /* true if processing last block */ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ int havedict; /* true if dictionary provided */ int flags; /* gzip header method and flags (0 if zlib) */ unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ unsigned long check; /* protected copy of check value */ unsigned long total; /* protected copy of output count */ gz_headerp head; /* where to save gzip header information */ /* sliding window */ unsigned wbits; /* log base 2 of requested window size */ unsigned wsize; /* window size or zero if not using window */ unsigned whave; /* valid bytes in the window */ unsigned wnext; /* window write index */ unsigned char FAR *window; /* allocated sliding window, if needed */ /* bit accumulator */ unsigned long hold; /* input bit accumulator */ unsigned bits; /* number of bits in "in" */ /* for string and stored block copying */ unsigned length; /* literal or length of data to copy */ unsigned offset; /* distance back to copy string from */ /* for table and code decoding */ unsigned extra; /* extra bits needed */ /* fixed and dynamic code tables */ code const FAR *lencode; /* starting table for length/literal codes */ code const FAR *distcode; /* starting table for distance codes */ unsigned lenbits; /* index bits for lencode */ unsigned distbits; /* index bits for distcode */ /* dynamic table building */ unsigned ncode; /* number of code length code lengths */ unsigned nlen; /* number of length code lengths */ unsigned ndist; /* number of distance code lengths */ unsigned have; /* number of code lengths in lens[] */ code FAR *next; /* next available space in codes[] */ unsigned short lens[320]; /* temporary storage for code lengths */ unsigned short work[288]; /* work area for code table building */ code codes[ENOUGH]; /* space for code tables */ int sane; /* if false, allow invalid distance too far */ int back; /* bits back of last unprocessed length/lit */ unsigned was; /* initial length of match */ }; ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/zlib/inftrees.c0000644000175100001710000003271100000000000020304 0ustar00vstsdocker/* inftrees.c -- generate Huffman trees for efficient decoding * Copyright (C) 1995-2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #include "zutil.h" #include "inftrees.h" #define MAXBITS 15 const char inflate_copyright[] = " inflate 1.2.5 Copyright 1995-2010 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot include such an acknowledgment, I would appreciate that you keep this copyright string in the executable of your product. */ /* Build a set of tables to decode the provided canonical Huffman code. The code lengths are lens[0..codes-1]. The result starts at *table, whose indices are 0..2^bits-1. work is a writable array of at least lens shorts, which is used as a work area. type is the type of code to be generated, CODES, LENS, or DISTS. On return, zero is success, -1 is an invalid code, and +1 means that ENOUGH isn't enough. table on return points to the next available entry's address. bits is the requested root table index bits, and on return it is the actual root table index bits. It will differ if the request is greater than the longest code or if it is less than the shortest code. */ int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) codetype type; unsigned short FAR *lens; unsigned codes; code FAR * FAR *table; unsigned FAR *bits; unsigned short FAR *work; { unsigned len; /* a code's length in bits */ unsigned sym; /* index of code symbols */ unsigned min, max; /* minimum and maximum code lengths */ unsigned root; /* number of index bits for root table */ unsigned curr; /* number of index bits for current table */ unsigned drop; /* code bits to drop for sub-table */ int left; /* number of prefix codes available */ unsigned used; /* code entries in table used */ unsigned huff; /* Huffman code */ unsigned incr; /* for incrementing code, index */ unsigned fill; /* index for replicating entries */ unsigned low; /* low bits for current root entry */ unsigned mask; /* mask for low root bits */ code here; /* table entry for duplication */ code FAR *next; /* next available space in table */ const unsigned short FAR *base; /* base value table to use */ const unsigned short FAR *extra; /* extra bits table to use */ int end; /* use base and extra for symbol > end */ unsigned short count[MAXBITS+1]; /* number of codes of each length */ unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ static const unsigned short lbase[31] = { /* Length codes 257..285 base */ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 73, 195}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0}; static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 64, 64}; /* Process a set of code lengths to create a canonical Huffman code. The code lengths are lens[0..codes-1]. Each length corresponds to the symbols 0..codes-1. The Huffman code is generated by first sorting the symbols by length from short to long, and retaining the symbol order for codes with equal lengths. Then the code starts with all zero bits for the first code of the shortest length, and the codes are integer increments for the same length, and zeros are appended as the length increases. For the deflate format, these bits are stored backwards from their more natural integer increment ordering, and so when the decoding tables are built in the large loop below, the integer codes are incremented backwards. This routine assumes, but does not check, that all of the entries in lens[] are in the range 0..MAXBITS. The caller must assure this. 1..MAXBITS is interpreted as that code length. zero means that that symbol does not occur in this code. The codes are sorted by computing a count of codes for each length, creating from that a table of starting indices for each length in the sorted table, and then entering the symbols in order in the sorted table. The sorted table is work[], with that space being provided by the caller. The length counts are used for other purposes as well, i.e. finding the minimum and maximum length codes, determining if there are any codes at all, checking for a valid set of lengths, and looking ahead at length counts to determine sub-table sizes when building the decoding tables. */ /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ for (len = 0; len <= MAXBITS; len++) count[len] = 0; for (sym = 0; sym < codes; sym++) count[lens[sym]]++; /* bound code lengths, force root to be within code lengths */ root = *bits; for (max = MAXBITS; max >= 1; max--) if (count[max] != 0) break; if (root > max) root = max; if (max == 0) { /* no symbols to code at all */ here.op = (unsigned char)64; /* invalid code marker */ here.bits = (unsigned char)1; here.val = (unsigned short)0; *(*table)++ = here; /* make a table to force an error */ *(*table)++ = here; *bits = 1; return 0; /* no symbols, but wait for decoding to report error */ } for (min = 1; min < max; min++) if (count[min] != 0) break; if (root < min) root = min; /* check for an over-subscribed or incomplete set of lengths */ left = 1; for (len = 1; len <= MAXBITS; len++) { left <<= 1; left -= count[len]; if (left < 0) return -1; /* over-subscribed */ } if (left > 0 && (type == CODES || max != 1)) return -1; /* incomplete set */ /* generate offsets into symbol table for each length for sorting */ offs[1] = 0; for (len = 1; len < MAXBITS; len++) offs[len + 1] = offs[len] + count[len]; /* sort symbols by length, by symbol order within each length */ for (sym = 0; sym < codes; sym++) if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; /* Create and fill in decoding tables. In this loop, the table being filled is at next and has curr index bits. The code being used is huff with length len. That code is converted to an index by dropping drop bits off of the bottom. For codes where len is less than drop + curr, those top drop + curr - len bits are incremented through all values to fill the table with replicated entries. root is the number of index bits for the root table. When len exceeds root, sub-tables are created pointed to by the root entry with an index of the low root bits of huff. This is saved in low to check for when a new sub-table should be started. drop is zero when the root table is being filled, and drop is root when sub-tables are being filled. When a new sub-table is needed, it is necessary to look ahead in the code lengths to determine what size sub-table is needed. The length counts are used for this, and so count[] is decremented as codes are entered in the tables. used keeps track of how many table entries have been allocated from the provided *table space. It is checked for LENS and DIST tables against the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in the initial root table size constants. See the comments in inftrees.h for more information. sym increments through all symbols, and the loop terminates when all codes of length max, i.e. all codes, have been processed. This routine permits incomplete codes, so another loop after this one fills in the rest of the decoding tables with invalid code markers. */ /* set up for code type */ switch (type) { case CODES: base = extra = work; /* dummy value--not used */ end = 19; break; case LENS: base = lbase; base -= 257; extra = lext; extra -= 257; end = 256; break; default: /* DISTS */ base = dbase; extra = dext; end = -1; } /* initialize state for loop */ huff = 0; /* starting code */ sym = 0; /* starting code symbol */ len = min; /* starting code length */ next = *table; /* current table to fill in */ curr = root; /* current table index bits */ drop = 0; /* current bits to drop from code for index */ low = (unsigned)(-1); /* trigger new sub-table when len > root */ used = 1U << root; /* use root table entries */ mask = used - 1; /* mask for comparing low */ /* check available table space */ if ((type == LENS && used >= ENOUGH_LENS) || (type == DISTS && used >= ENOUGH_DISTS)) return 1; /* process all codes and make table entries */ for (;;) { /* create table entry */ here.bits = (unsigned char)(len - drop); if ((int)(work[sym]) < end) { here.op = (unsigned char)0; here.val = work[sym]; } else if ((int)(work[sym]) > end) { here.op = (unsigned char)(extra[work[sym]]); here.val = base[work[sym]]; } else { here.op = (unsigned char)(32 + 64); /* end of block */ here.val = 0; } /* replicate for those indices with low len bits equal to huff */ incr = 1U << (len - drop); fill = 1U << curr; min = fill; /* save offset to next table */ do { fill -= incr; next[(huff >> drop) + fill] = here; } while (fill != 0); /* backwards increment the len-bit code huff */ incr = 1U << (len - 1); while (huff & incr) incr >>= 1; if (incr != 0) { huff &= incr - 1; huff += incr; } else huff = 0; /* go to next symbol, update count, len */ sym++; if (--(count[len]) == 0) { if (len == max) break; len = lens[work[sym]]; } /* create new sub-table if needed */ if (len > root && (huff & mask) != low) { /* if first time, transition to sub-tables */ if (drop == 0) drop = root; /* increment past last table */ next += min; /* here min is 1 << curr */ /* determine length of next table */ curr = len - drop; left = (int)(1 << curr); while (curr + drop < max) { left -= count[curr + drop]; if (left <= 0) break; curr++; left <<= 1; } /* check for enough space */ used += 1U << curr; if ((type == LENS && used >= ENOUGH_LENS) || (type == DISTS && used >= ENOUGH_DISTS)) return 1; /* point entry in root table to sub-table */ low = huff & mask; (*table)[low].op = (unsigned char)curr; (*table)[low].bits = (unsigned char)root; (*table)[low].val = (unsigned short)(next - *table); } } /* Fill in rest of table for incomplete codes. This loop is similar to the loop above in incrementing huff for table indices. It is assumed that len is equal to curr + drop, so there is no loop needed to increment through high index bits. When the current sub-table is filled, the loop drops back to the root table to fill in any remaining entries there. */ here.op = (unsigned char)64; /* invalid code marker */ here.bits = (unsigned char)(len - drop); here.val = (unsigned short)0; while (huff != 0) { /* when done with sub-table, drop back to root table */ if (drop != 0 && (huff & mask) != low) { drop = 0; len = root; next = *table; here.bits = (unsigned char)len; } /* put invalid code marker in table */ next[huff >> drop] = here; /* backwards increment the len-bit code huff */ incr = 1U << (len - 1); while (huff & incr) incr >>= 1; if (incr != 0) { huff &= incr - 1; huff += incr; } else huff = 0; } /* set return parameters */ *table += used; *bits = root; return 0; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/zlib/inftrees.h0000644000175100001710000000556000000000000020313 0ustar00vstsdocker/* inftrees.h -- header to use inftrees.c * Copyright (C) 1995-2005, 2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ /* Structure for decoding tables. Each entry provides either the information needed to do the operation requested by the code that indexed that table entry, or it provides a pointer to another table that indexes more bits of the code. op indicates whether the entry is a pointer to another table, a literal, a length or distance, an end-of-block, or an invalid code. For a table pointer, the low four bits of op is the number of index bits of that table. For a length or distance, the low four bits of op is the number of extra bits to get after the code. bits is the number of bits in this code or part of the code to drop off of the bit buffer. val is the actual byte to output in the case of a literal, the base length or distance, or the offset from the current table to the next table. Each entry is four bytes. */ typedef struct { unsigned char op; /* operation, extra bits, table bits */ unsigned char bits; /* bits in this part of the code */ unsigned short val; /* offset in table or code value */ } code; /* op values as set by inflate_table(): 00000000 - literal 0000tttt - table link, tttt != 0 is the number of table index bits 0001eeee - length or distance, eeee is the number of extra bits 01100000 - end of block 01000000 - invalid code */ /* Maximum size of the dynamic table. The maximum number of code structures is 1444, which is the sum of 852 for literal/length codes and 592 for distance codes. These values were found by exhaustive searches using the program examples/enough.c found in the zlib distribtution. The arguments to that program are the number of symbols, the initial root table size, and the maximum bit length of a code. "enough 286 9 15" for literal/length codes returns returns 852, and "enough 30 6 15" for distance codes returns 592. The initial root table size (9 or 6) is found in the fifth argument of the inflate_table() calls in inflate.c and infback.c. If the root table size is changed, then these maximum sizes would be need to be recalculated and updated. */ #define ENOUGH_LENS 852 #define ENOUGH_DISTS 592 #define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) /* Type of code to build for inflate_table() */ typedef enum { CODES, LENS, DISTS } codetype; int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, unsigned codes, code FAR * FAR *table, unsigned FAR *bits, unsigned short FAR *work)); ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/zlib/trees.c0000644000175100001710000013025100000000000017605 0ustar00vstsdocker/* trees.c -- output deflated data using Huffman coding * Copyright (C) 1995-2010 Jean-loup Gailly * detect_data_type() function provided freely by Cosmin Truta, 2006 * For conditions of distribution and use, see copyright notice in zlib.h */ /* * ALGORITHM * * The "deflation" process uses several Huffman trees. The more * common source values are represented by shorter bit sequences. * * Each code tree is stored in a compressed form which is itself * a Huffman encoding of the lengths of all the code strings (in * ascending order by source values). The actual code strings are * reconstructed from the lengths in the inflate process, as described * in the deflate specification. * * REFERENCES * * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc * * Storer, James A. * Data Compression: Methods and Theory, pp. 49-50. * Computer Science Press, 1988. ISBN 0-7167-8156-5. * * Sedgewick, R. * Algorithms, p290. * Addison-Wesley, 1983. ISBN 0-201-06672-6. */ /* #define GEN_TREES_H */ #include "deflate.h" #ifdef DEBUG # include #endif /* =========================================================================== * Constants */ #define MAX_BL_BITS 7 /* Bit length codes must not exceed MAX_BL_BITS bits */ #define END_BLOCK 256 /* end of block literal code */ #define REP_3_6 16 /* repeat previous bit length 3-6 times (2 bits of repeat count) */ #define REPZ_3_10 17 /* repeat a zero length 3-10 times (3 bits of repeat count) */ #define REPZ_11_138 18 /* repeat a zero length 11-138 times (7 bits of repeat count) */ local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; local const int extra_dbits[D_CODES] /* extra bits for each distance code */ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; local const uch bl_order[BL_CODES] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; /* The lengths of the bit length codes are sent in order of decreasing * probability, to avoid transmitting the lengths for unused bit length codes. */ #define Buf_size (8 * 2*sizeof(char)) /* Number of bits used within bi_buf. (bi_buf might be implemented on * more than 16 bits on some systems.) */ /* =========================================================================== * Local data. These are initialized only once. */ #define DIST_CODE_LEN 512 /* see definition of array dist_code below */ #if defined(GEN_TREES_H) || !defined(STDC) /* non ANSI compilers may not accept trees.h */ local ct_data static_ltree[L_CODES+2]; /* The static literal tree. Since the bit lengths are imposed, there is no * need for the L_CODES extra codes used during heap construction. However * The codes 286 and 287 are needed to build a canonical tree (see _tr_init * below). */ local ct_data static_dtree[D_CODES]; /* The static distance tree. (Actually a trivial tree since all codes use * 5 bits.) */ uch _dist_code[DIST_CODE_LEN]; /* Distance codes. The first 256 values correspond to the distances * 3 .. 258, the last 256 values correspond to the top 8 bits of * the 15 bit distances. */ uch _length_code[MAX_MATCH-MIN_MATCH+1]; /* length code for each normalized match length (0 == MIN_MATCH) */ local int base_length[LENGTH_CODES]; /* First normalized length for each code (0 = MIN_MATCH) */ local int base_dist[D_CODES]; /* First normalized distance for each code (0 = distance of 1) */ #else # include "trees.h" #endif /* GEN_TREES_H */ struct static_tree_desc_s { const ct_data *static_tree; /* static tree or NULL */ const intf *extra_bits; /* extra bits for each code or NULL */ int extra_base; /* base index for extra_bits */ int elems; /* max number of elements in the tree */ int max_length; /* max bit length for the codes */ }; local static_tree_desc static_l_desc = {static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; local static_tree_desc static_d_desc = {static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; local static_tree_desc static_bl_desc = {(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; /* =========================================================================== * Local (static) routines in this file. */ local void tr_static_init OF((void)); local void init_block OF((deflate_state *s)); local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); local void build_tree OF((deflate_state *s, tree_desc *desc)); local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); local int build_bl_tree OF((deflate_state *s)); local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, int blcodes)); local void compress_block OF((deflate_state *s, ct_data *ltree, ct_data *dtree)); local int detect_data_type OF((deflate_state *s)); local unsigned bi_reverse OF((unsigned value, int length)); local void bi_windup OF((deflate_state *s)); local void bi_flush OF((deflate_state *s)); local void copy_block OF((deflate_state *s, charf *buf, unsigned len, int header)); #ifdef GEN_TREES_H local void gen_trees_header OF((void)); #endif #ifndef DEBUG # define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) /* Send a code of the given tree. c and tree must not have side effects */ #else /* DEBUG */ # define send_code(s, c, tree) \ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ send_bits(s, tree[c].Code, tree[c].Len); } #endif /* =========================================================================== * Output a short LSB first on the stream. * IN assertion: there is enough room in pendingBuf. */ #define put_short(s, w) { \ put_byte(s, (uch)((w) & 0xff)); \ put_byte(s, (uch)((ush)(w) >> 8)); \ } /* =========================================================================== * Send a value on a given number of bits. * IN assertion: length <= 16 and value fits in length bits. */ #ifdef DEBUG local void send_bits OF((deflate_state *s, int value, int length)); local void send_bits(s, value, length) deflate_state *s; int value; /* value to send */ int length; /* number of bits */ { Tracevv((stderr," l %2d v %4x ", length, value)); Assert(length > 0 && length <= 15, "invalid length"); s->bits_sent += (ulg)length; /* If not enough room in bi_buf, use (valid) bits from bi_buf and * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) * unused bits in value. */ if (s->bi_valid > (int)Buf_size - length) { s->bi_buf |= (ush)value << s->bi_valid; put_short(s, s->bi_buf); s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); s->bi_valid += length - Buf_size; } else { s->bi_buf |= (ush)value << s->bi_valid; s->bi_valid += length; } } #else /* !DEBUG */ #define send_bits(s, value, length) \ { int len = length;\ if (s->bi_valid > (int)Buf_size - len) {\ int val = value;\ s->bi_buf |= (ush)val << s->bi_valid;\ put_short(s, s->bi_buf);\ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ s->bi_valid += len - Buf_size;\ } else {\ s->bi_buf |= (ush)(value) << s->bi_valid;\ s->bi_valid += len;\ }\ } #endif /* DEBUG */ /* the arguments must not have side effects */ /* =========================================================================== * Initialize the various 'constant' tables. */ local void tr_static_init() { #if defined(GEN_TREES_H) || !defined(STDC) static int static_init_done = 0; int n; /* iterates over tree elements */ int bits; /* bit counter */ int length; /* length value */ int code; /* code value */ int dist; /* distance index */ ush bl_count[MAX_BITS+1]; /* number of codes at each bit length for an optimal tree */ if (static_init_done) return; /* For some embedded targets, global variables are not initialized: */ #ifdef NO_INIT_GLOBAL_POINTERS static_l_desc.static_tree = static_ltree; static_l_desc.extra_bits = extra_lbits; static_d_desc.static_tree = static_dtree; static_d_desc.extra_bits = extra_dbits; static_bl_desc.extra_bits = extra_blbits; #endif /* Initialize the mapping length (0..255) -> length code (0..28) */ length = 0; for (code = 0; code < LENGTH_CODES-1; code++) { base_length[code] = length; for (n = 0; n < (1< dist code (0..29) */ dist = 0; for (code = 0 ; code < 16; code++) { base_dist[code] = dist; for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ for ( ; code < D_CODES; code++) { base_dist[code] = dist << 7; for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { _dist_code[256 + dist++] = (uch)code; } } Assert (dist == 256, "tr_static_init: 256+dist != 512"); /* Construct the codes of the static literal tree */ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; n = 0; while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; /* Codes 286 and 287 do not exist, but we must include them in the * tree construction to get a canonical Huffman tree (longest code * all ones) */ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); /* The static distance tree is trivial: */ for (n = 0; n < D_CODES; n++) { static_dtree[n].Len = 5; static_dtree[n].Code = bi_reverse((unsigned)n, 5); } static_init_done = 1; # ifdef GEN_TREES_H gen_trees_header(); # endif #endif /* defined(GEN_TREES_H) || !defined(STDC) */ } /* =========================================================================== * Genererate the file trees.h describing the static trees. */ #ifdef GEN_TREES_H # ifndef DEBUG # include # endif # define SEPARATOR(i, last, width) \ ((i) == (last)? "\n};\n\n" : \ ((i) % (width) == (width)-1 ? ",\n" : ", ")) void gen_trees_header() { FILE *header = fopen("trees.h", "w"); int i; Assert (header != NULL, "Can't open trees.h"); fprintf(header, "/* header created automatically with -DGEN_TREES_H */\n\n"); fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); for (i = 0; i < L_CODES+2; i++) { fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); } fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); for (i = 0; i < D_CODES; i++) { fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); } fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); for (i = 0; i < DIST_CODE_LEN; i++) { fprintf(header, "%2u%s", _dist_code[i], SEPARATOR(i, DIST_CODE_LEN-1, 20)); } fprintf(header, "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { fprintf(header, "%2u%s", _length_code[i], SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); } fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); for (i = 0; i < LENGTH_CODES; i++) { fprintf(header, "%1u%s", base_length[i], SEPARATOR(i, LENGTH_CODES-1, 20)); } fprintf(header, "local const int base_dist[D_CODES] = {\n"); for (i = 0; i < D_CODES; i++) { fprintf(header, "%5u%s", base_dist[i], SEPARATOR(i, D_CODES-1, 10)); } fclose(header); } #endif /* GEN_TREES_H */ /* =========================================================================== * Initialize the tree data structures for a new zlib stream. */ void ZLIB_INTERNAL _tr_init(s) deflate_state *s; { tr_static_init(); s->l_desc.dyn_tree = s->dyn_ltree; s->l_desc.stat_desc = &static_l_desc; s->d_desc.dyn_tree = s->dyn_dtree; s->d_desc.stat_desc = &static_d_desc; s->bl_desc.dyn_tree = s->bl_tree; s->bl_desc.stat_desc = &static_bl_desc; s->bi_buf = 0; s->bi_valid = 0; s->last_eob_len = 8; /* enough lookahead for inflate */ #ifdef DEBUG s->compressed_len = 0L; s->bits_sent = 0L; #endif /* Initialize the first block of the first file: */ init_block(s); } /* =========================================================================== * Initialize a new block. */ local void init_block(s) deflate_state *s; { int n; /* iterates over tree elements */ /* Initialize the trees. */ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; s->dyn_ltree[END_BLOCK].Freq = 1; s->opt_len = s->static_len = 0L; s->last_lit = s->matches = 0; } #define SMALLEST 1 /* Index within the heap array of least frequent node in the Huffman tree */ /* =========================================================================== * Remove the smallest element from the heap and recreate the heap with * one less element. Updates heap and heap_len. */ #define pqremove(s, tree, top) \ {\ top = s->heap[SMALLEST]; \ s->heap[SMALLEST] = s->heap[s->heap_len--]; \ pqdownheap(s, tree, SMALLEST); \ } /* =========================================================================== * Compares to subtrees, using the tree depth as tie breaker when * the subtrees have equal frequency. This minimizes the worst case length. */ #define smaller(tree, n, m, depth) \ (tree[n].Freq < tree[m].Freq || \ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) /* =========================================================================== * Restore the heap property by moving down the tree starting at node k, * exchanging a node with the smallest of its two sons if necessary, stopping * when the heap property is re-established (each father smaller than its * two sons). */ local void pqdownheap(s, tree, k) deflate_state *s; ct_data *tree; /* the tree to restore */ int k; /* node to move down */ { int v = s->heap[k]; int j = k << 1; /* left son of k */ while (j <= s->heap_len) { /* Set j to the smallest of the two sons: */ if (j < s->heap_len && smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { j++; } /* Exit if v is smaller than both sons */ if (smaller(tree, v, s->heap[j], s->depth)) break; /* Exchange v with the smallest son */ s->heap[k] = s->heap[j]; k = j; /* And continue down the tree, setting j to the left son of k */ j <<= 1; } s->heap[k] = v; } /* =========================================================================== * Compute the optimal bit lengths for a tree and update the total bit length * for the current block. * IN assertion: the fields freq and dad are set, heap[heap_max] and * above are the tree nodes sorted by increasing frequency. * OUT assertions: the field len is set to the optimal bit length, the * array bl_count contains the frequencies for each bit length. * The length opt_len is updated; static_len is also updated if stree is * not null. */ local void gen_bitlen(s, desc) deflate_state *s; tree_desc *desc; /* the tree descriptor */ { ct_data *tree = desc->dyn_tree; int max_code = desc->max_code; const ct_data *stree = desc->stat_desc->static_tree; const intf *extra = desc->stat_desc->extra_bits; int base = desc->stat_desc->extra_base; int max_length = desc->stat_desc->max_length; int h; /* heap index */ int n, m; /* iterate over the tree elements */ int bits; /* bit length */ int xbits; /* extra bits */ ush f; /* frequency */ int overflow = 0; /* number of elements with bit length too large */ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; /* In a first pass, compute the optimal bit lengths (which may * overflow in the case of the bit length tree). */ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ for (h = s->heap_max+1; h < HEAP_SIZE; h++) { n = s->heap[h]; bits = tree[tree[n].Dad].Len + 1; if (bits > max_length) bits = max_length, overflow++; tree[n].Len = (ush)bits; /* We overwrite tree[n].Dad which is no longer needed */ if (n > max_code) continue; /* not a leaf node */ s->bl_count[bits]++; xbits = 0; if (n >= base) xbits = extra[n-base]; f = tree[n].Freq; s->opt_len += (ulg)f * (bits + xbits); if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); } if (overflow == 0) return; Trace((stderr,"\nbit length overflow\n")); /* This happens for example on obj2 and pic of the Calgary corpus */ /* Find the first bit length which could increase: */ do { bits = max_length-1; while (s->bl_count[bits] == 0) bits--; s->bl_count[bits]--; /* move one leaf down the tree */ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ s->bl_count[max_length]--; /* The brother of the overflow item also moves one step up, * but this does not affect bl_count[max_length] */ overflow -= 2; } while (overflow > 0); /* Now recompute all bit lengths, scanning in increasing frequency. * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all * lengths instead of fixing only the wrong ones. This idea is taken * from 'ar' written by Haruhiko Okumura.) */ for (bits = max_length; bits != 0; bits--) { n = s->bl_count[bits]; while (n != 0) { m = s->heap[--h]; if (m > max_code) continue; if ((unsigned) tree[m].Len != (unsigned) bits) { Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); s->opt_len += ((long)bits - (long)tree[m].Len) *(long)tree[m].Freq; tree[m].Len = (ush)bits; } n--; } } } /* =========================================================================== * Generate the codes for a given tree and bit counts (which need not be * optimal). * IN assertion: the array bl_count contains the bit length statistics for * the given tree and the field len is set for all tree elements. * OUT assertion: the field code is set for all tree elements of non * zero code length. */ local void gen_codes (tree, max_code, bl_count) ct_data *tree; /* the tree to decorate */ int max_code; /* largest code with non zero frequency */ ushf *bl_count; /* number of codes at each bit length */ { ush next_code[MAX_BITS+1]; /* next code value for each bit length */ ush code = 0; /* running code value */ int bits; /* bit index */ int n; /* code index */ /* The distribution counts are first used to generate the code values * without bit reversal. */ for (bits = 1; bits <= MAX_BITS; bits++) { next_code[bits] = code = (code + bl_count[bits-1]) << 1; } /* Check that the bit counts in bl_count are consistent. The last code * must be all ones. */ Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; const ct_data *stree = desc->stat_desc->static_tree; int elems = desc->stat_desc->elems; int n, m; /* iterate over heap elements */ int max_code = -1; /* largest code with non zero frequency */ int node; /* new node being created */ /* Construct the initial heap, with least frequent element in * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. * heap[0] is not used. */ s->heap_len = 0, s->heap_max = HEAP_SIZE; for (n = 0; n < elems; n++) { if (tree[n].Freq != 0) { s->heap[++(s->heap_len)] = max_code = n; s->depth[n] = 0; } else { tree[n].Len = 0; } } /* The pkzip format requires that at least one distance code exists, * and that at least one bit should be sent even if there is only one * possible code. So to avoid special checks later on we force at least * two codes of non zero frequency. */ while (s->heap_len < 2) { node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); tree[node].Freq = 1; s->depth[node] = 0; s->opt_len--; if (stree) s->static_len -= stree[node].Len; /* node is 0 or 1 so it does not have extra bits */ } desc->max_code = max_code; /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, * establish sub-heaps of increasing lengths: */ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); /* Construct the Huffman tree by repeatedly combining the least two * frequent nodes. */ node = elems; /* next internal node of the tree */ do { pqremove(s, tree, n); /* n = node of least frequency */ m = s->heap[SMALLEST]; /* m = node of next least frequency */ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ s->heap[--(s->heap_max)] = m; /* Create a new node father of n and m */ tree[node].Freq = tree[n].Freq + tree[m].Freq; s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? s->depth[n] : s->depth[m]) + 1); tree[n].Dad = tree[m].Dad = (ush)node; #ifdef DUMP_BL_TREE if (tree == s->bl_tree) { fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); } #endif /* and insert the new node in the heap */ s->heap[SMALLEST] = node++; pqdownheap(s, tree, SMALLEST); } while (s->heap_len >= 2); s->heap[--(s->heap_max)] = s->heap[SMALLEST]; /* At this point, the fields freq and dad are set. We can now * generate the bit lengths. */ gen_bitlen(s, (tree_desc *)desc); /* The field len is now set, we can generate the bit codes */ gen_codes ((ct_data *)tree, max_code, s->bl_count); } /* =========================================================================== * Scan a literal or distance tree to determine the frequencies of the codes * in the bit length tree. */ local void scan_tree (s, tree, max_code) deflate_state *s; ct_data *tree; /* the tree to be scanned */ int max_code; /* and its largest code of non zero frequency */ { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ int nextlen = tree[0].Len; /* length of next code */ int count = 0; /* repeat count of the current code */ int max_count = 7; /* max repeat count */ int min_count = 4; /* min repeat count */ if (nextlen == 0) max_count = 138, min_count = 3; tree[max_code+1].Len = (ush)0xffff; /* guard */ for (n = 0; n <= max_code; n++) { curlen = nextlen; nextlen = tree[n+1].Len; if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { s->bl_tree[curlen].Freq += count; } else if (curlen != 0) { if (curlen != prevlen) s->bl_tree[curlen].Freq++; s->bl_tree[REP_3_6].Freq++; } else if (count <= 10) { s->bl_tree[REPZ_3_10].Freq++; } else { s->bl_tree[REPZ_11_138].Freq++; } count = 0; prevlen = curlen; if (nextlen == 0) { max_count = 138, min_count = 3; } else if (curlen == nextlen) { max_count = 6, min_count = 3; } else { max_count = 7, min_count = 4; } } } /* =========================================================================== * Send a literal or distance tree in compressed form, using the codes in * bl_tree. */ local void send_tree (s, tree, max_code) deflate_state *s; ct_data *tree; /* the tree to be scanned */ int max_code; /* and its largest code of non zero frequency */ { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ int nextlen = tree[0].Len; /* length of next code */ int count = 0; /* repeat count of the current code */ int max_count = 7; /* max repeat count */ int min_count = 4; /* min repeat count */ /* tree[max_code+1].Len = -1; */ /* guard already set */ if (nextlen == 0) max_count = 138, min_count = 3; for (n = 0; n <= max_code; n++) { curlen = nextlen; nextlen = tree[n+1].Len; if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { do { send_code(s, curlen, s->bl_tree); } while (--count != 0); } else if (curlen != 0) { if (curlen != prevlen) { send_code(s, curlen, s->bl_tree); count--; } Assert(count >= 3 && count <= 6, " 3_6?"); send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); } else if (count <= 10) { send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); } else { send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); } count = 0; prevlen = curlen; if (nextlen == 0) { max_count = 138, min_count = 3; } else if (curlen == nextlen) { max_count = 6, min_count = 3; } else { max_count = 7, min_count = 4; } } } /* =========================================================================== * Construct the Huffman tree for the bit lengths and return the index in * bl_order of the last bit length code to send. */ local int build_bl_tree(s) deflate_state *s; { int max_blindex; /* index of last bit length code of non zero freq */ /* Determine the bit length frequencies for literal and distance trees */ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); /* Build the bit length tree: */ build_tree(s, (tree_desc *)(&(s->bl_desc))); /* opt_len now includes the length of the tree representations, except * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. */ /* Determine the number of bit length codes to send. The pkzip format * requires that at least 4 bit length codes be sent. (appnote.txt says * 3 but the actual value used is 4.) */ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; } /* Update opt_len to include the bit length tree and counts */ s->opt_len += 3*(max_blindex+1) + 5+5+4; Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", s->opt_len, s->static_len)); return max_blindex; } /* =========================================================================== * Send the header for a block using dynamic Huffman trees: the counts, the * lengths of the bit length codes, the literal tree and the distance tree. * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. */ local void send_all_trees(s, lcodes, dcodes, blcodes) deflate_state *s; int lcodes, dcodes, blcodes; /* number of codes for each tree */ { int rank; /* index in bl_order */ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, "too many codes"); Tracev((stderr, "\nbl counts: ")); send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ send_bits(s, dcodes-1, 5); send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ for (rank = 0; rank < blcodes; rank++) { Tracev((stderr, "\nbl code %2d ", bl_order[rank])); send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); } Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); } /* =========================================================================== * Send a stored block */ void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) deflate_state *s; charf *buf; /* input block */ ulg stored_len; /* length of input block */ int last; /* one if this is the last block for a file */ { send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ #ifdef DEBUG s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; s->compressed_len += (stored_len + 4) << 3; #endif copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ } /* =========================================================================== * Send one empty static block to give enough lookahead for inflate. * This takes 10 bits, of which 7 may remain in the bit buffer. * The current inflate code requires 9 bits of lookahead. If the * last two codes for the previous block (real code plus EOB) were coded * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode * the last real code. In this case we send two empty static blocks instead * of one. (There are no problems if the previous block is stored or fixed.) * To simplify the code, we assume the worst case of last real code encoded * on one bit only. */ void ZLIB_INTERNAL _tr_align(s) deflate_state *s; { send_bits(s, STATIC_TREES<<1, 3); send_code(s, END_BLOCK, static_ltree); #ifdef DEBUG s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ #endif bi_flush(s); /* Of the 10 bits for the empty block, we have already sent * (10 - bi_valid) bits. The lookahead for the last real code (before * the EOB of the previous block) was thus at least one plus the length * of the EOB plus what we have just sent of the empty static block. */ if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { send_bits(s, STATIC_TREES<<1, 3); send_code(s, END_BLOCK, static_ltree); #ifdef DEBUG s->compressed_len += 10L; #endif bi_flush(s); } s->last_eob_len = 7; } /* =========================================================================== * Determine the best encoding for the current block: dynamic trees, static * trees or store, and output the encoded block to the zip file. */ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) deflate_state *s; charf *buf; /* input block, or NULL if too old */ ulg stored_len; /* length of input block */ int last; /* one if this is the last block for a file */ { ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ int max_blindex = 0; /* index of last bit length code of non zero freq */ /* Build the Huffman trees unless a stored block is forced */ if (s->level > 0) { /* Check if the file is binary or text */ if (s->strm->data_type == Z_UNKNOWN) s->strm->data_type = detect_data_type(s); /* Construct the literal and distance trees */ build_tree(s, (tree_desc *)(&(s->l_desc))); Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, s->static_len)); build_tree(s, (tree_desc *)(&(s->d_desc))); Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, s->static_len)); /* At this point, opt_len and static_len are the total bit lengths of * the compressed block data, excluding the tree representations. */ /* Build the bit length tree for the above two trees, and get the index * in bl_order of the last bit length code to send. */ max_blindex = build_bl_tree(s); /* Determine the best encoding. Compute the block lengths in bytes. */ opt_lenb = (s->opt_len+3+7)>>3; static_lenb = (s->static_len+3+7)>>3; Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, s->last_lit)); if (static_lenb <= opt_lenb) opt_lenb = static_lenb; } else { Assert(buf != (char*)0, "lost buf"); opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ } #ifdef FORCE_STORED if (buf != (char*)0) { /* force stored block */ #else if (stored_len+4 <= opt_lenb && buf != (char*)0) { /* 4: two words for the lengths */ #endif /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. * Otherwise we can't have processed more than WSIZE input bytes since * the last block flush, because compression would have been * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to * transform a block into a stored block. */ _tr_stored_block(s, buf, stored_len, last); #ifdef FORCE_STATIC } else if (static_lenb >= 0) { /* force static trees */ #else } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { #endif send_bits(s, (STATIC_TREES<<1)+last, 3); compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); #ifdef DEBUG s->compressed_len += 3 + s->static_len; #endif } else { send_bits(s, (DYN_TREES<<1)+last, 3); send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, max_blindex+1); compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); #ifdef DEBUG s->compressed_len += 3 + s->opt_len; #endif } Assert (s->compressed_len == s->bits_sent, "bad compressed size"); /* The above check is made mod 2^32, for files larger than 512 MB * and uLong implemented on 32 bits. */ init_block(s); if (last) { bi_windup(s); #ifdef DEBUG s->compressed_len += 7; /* align on byte boundary */ #endif } Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, s->compressed_len-7*last)); } /* =========================================================================== * Save the match info and tally the frequency counts. Return true if * the current block must be flushed. */ int ZLIB_INTERNAL _tr_tally (s, dist, lc) deflate_state *s; unsigned dist; /* distance of matched string */ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ { s->d_buf[s->last_lit] = (ush)dist; s->l_buf[s->last_lit++] = (uch)lc; if (dist == 0) { /* lc is the unmatched char */ s->dyn_ltree[lc].Freq++; } else { s->matches++; /* Here, lc is the match length - MIN_MATCH */ dist--; /* dist = match distance - 1 */ Assert((ush)dist < (ush)MAX_DIST(s) && (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; s->dyn_dtree[d_code(dist)].Freq++; } #ifdef TRUNCATE_BLOCK /* Try to guess if it is profitable to stop the current block here */ if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { /* Compute an upper bound for the compressed length */ ulg out_length = (ulg)s->last_lit*8L; ulg in_length = (ulg)((long)s->strstart - s->block_start); int dcode; for (dcode = 0; dcode < D_CODES; dcode++) { out_length += (ulg)s->dyn_dtree[dcode].Freq * (5L+extra_dbits[dcode]); } out_length >>= 3; Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", s->last_lit, in_length, out_length, 100L - out_length*100L/in_length)); if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; } #endif return (s->last_lit == s->lit_bufsize-1); /* We avoid equality with lit_bufsize because of wraparound at 64K * on 16 bit machines and because stored blocks are restricted to * 64K-1 bytes. */ } /* =========================================================================== * Send the block data compressed using the given Huffman trees */ local void compress_block(s, ltree, dtree) deflate_state *s; ct_data *ltree; /* literal tree */ ct_data *dtree; /* distance tree */ { unsigned dist; /* distance of matched string */ int lc; /* match length or unmatched char (if dist == 0) */ unsigned lx = 0; /* running index in l_buf */ unsigned code; /* the code to send */ int extra; /* number of extra bits to send */ if (s->last_lit != 0) do { dist = s->d_buf[lx]; lc = s->l_buf[lx++]; if (dist == 0) { send_code(s, lc, ltree); /* send a literal byte */ Tracecv(isgraph(lc), (stderr," '%c' ", lc)); } else { /* Here, lc is the match length - MIN_MATCH */ code = _length_code[lc]; send_code(s, code+LITERALS+1, ltree); /* send the length code */ extra = extra_lbits[code]; if (extra != 0) { lc -= base_length[code]; send_bits(s, lc, extra); /* send the extra length bits */ } dist--; /* dist is now the match distance - 1 */ code = d_code(dist); Assert (code < D_CODES, "bad d_code"); send_code(s, code, dtree); /* send the distance code */ extra = extra_dbits[code]; if (extra != 0) { dist -= base_dist[code]; send_bits(s, dist, extra); /* send the extra distance bits */ } } /* literal or match pair ? */ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, "pendingBuf overflow"); } while (lx < s->last_lit); send_code(s, END_BLOCK, ltree); s->last_eob_len = ltree[END_BLOCK].Len; } /* =========================================================================== * Check if the data type is TEXT or BINARY, using the following algorithm: * - TEXT if the two conditions below are satisfied: * a) There are no non-portable control characters belonging to the * "black list" (0..6, 14..25, 28..31). * b) There is at least one printable character belonging to the * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). * - BINARY otherwise. * - The following partially-portable control characters form a * "gray list" that is ignored in this detection algorithm: * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). * IN assertion: the fields Freq of dyn_ltree are set. */ local int detect_data_type(s) deflate_state *s; { /* black_mask is the bit mask of black-listed bytes * set bits 0..6, 14..25, and 28..31 * 0xf3ffc07f = binary 11110011111111111100000001111111 */ unsigned long black_mask = 0xf3ffc07fUL; int n; /* Check for non-textual ("black-listed") bytes. */ for (n = 0; n <= 31; n++, black_mask >>= 1) if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) return Z_BINARY; /* Check for textual ("white-listed") bytes. */ if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 || s->dyn_ltree[13].Freq != 0) return Z_TEXT; for (n = 32; n < LITERALS; n++) if (s->dyn_ltree[n].Freq != 0) return Z_TEXT; /* There are no "black-listed" or "white-listed" bytes: * this stream either is empty or has tolerated ("gray-listed") bytes only. */ return Z_BINARY; } /* =========================================================================== * Reverse the first len bits of a code, using straightforward code (a faster * method would use a table) * IN assertion: 1 <= len <= 15 */ local unsigned bi_reverse(code, len) unsigned code; /* the value to invert */ int len; /* its bit length */ { register unsigned res = 0; do { res |= code & 1; code >>= 1, res <<= 1; } while (--len > 0); return res >> 1; } /* =========================================================================== * Flush the bit buffer, keeping at most 7 bits in it. */ local void bi_flush(s) deflate_state *s; { if (s->bi_valid == 16) { put_short(s, s->bi_buf); s->bi_buf = 0; s->bi_valid = 0; } else if (s->bi_valid >= 8) { put_byte(s, (Byte)s->bi_buf); s->bi_buf >>= 8; s->bi_valid -= 8; } } /* =========================================================================== * Flush the bit buffer and align the output on a byte boundary */ local void bi_windup(s) deflate_state *s; { if (s->bi_valid > 8) { put_short(s, s->bi_buf); } else if (s->bi_valid > 0) { put_byte(s, (Byte)s->bi_buf); } s->bi_buf = 0; s->bi_valid = 0; #ifdef DEBUG s->bits_sent = (s->bits_sent+7) & ~7; #endif } /* =========================================================================== * Copy a stored block, storing first the length and its * one's complement if requested. */ local void copy_block(s, buf, len, header) deflate_state *s; charf *buf; /* the input data */ unsigned len; /* its length */ int header; /* true if block header must be written */ { bi_windup(s); /* align on byte boundary */ s->last_eob_len = 8; /* enough lookahead for inflate */ if (header) { put_short(s, (ush)len); put_short(s, (ush)~len); #ifdef DEBUG s->bits_sent += 2*16; #endif } #ifdef DEBUG s->bits_sent += (ulg)len<<3; #endif while (len--) { put_byte(s, *buf++); } } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/zlib/trees.h0000644000175100001710000002043000000000000017607 0ustar00vstsdocker/* header created automatically with -DGEN_TREES_H */ local const ct_data static_ltree[L_CODES+2] = { {{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, {{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, {{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, {{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, {{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, {{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, {{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, {{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, {{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, {{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, {{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, {{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, {{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, {{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, {{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, {{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, {{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, {{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, {{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, {{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, {{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, {{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, {{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, {{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, {{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, {{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, {{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, {{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, {{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, {{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, {{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, {{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, {{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, {{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, {{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, {{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, {{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, {{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, {{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, {{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, {{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, {{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, {{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, {{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, {{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, {{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, {{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, {{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, {{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, {{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, {{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, {{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, {{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, {{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, {{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, {{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, {{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, {{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} }; local const ct_data static_dtree[D_CODES] = { {{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, {{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, {{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, {{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, {{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, {{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} }; const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 }; const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 }; local const int base_length[LENGTH_CODES] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0 }; local const int base_dist[D_CODES] = { 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 }; ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/zlib/uncompr.c0000644000175100001710000000367100000000000020153 0ustar00vstsdocker/* uncompr.c -- decompress a memory buffer * Copyright (C) 1995-2003, 2010 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ #define ZLIB_INTERNAL #include "zlib.h" /* =========================================================================== Decompresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be large enough to hold the entire uncompressed data. (The size of the uncompressed data must have been saved previously by the compressor and transmitted to the decompressor by some mechanism outside the scope of this compression library.) Upon exit, destLen is the actual size of the compressed buffer. uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, or Z_DATA_ERROR if the input data was corrupted. */ int ZEXPORT uncompress (dest, destLen, source, sourceLen) Bytef *dest; uLongf *destLen; const Bytef *source; uLong sourceLen; { z_stream stream; int err; stream.next_in = (Bytef*)source; stream.avail_in = (uInt)sourceLen; /* Check for source > 64K on 16-bit machine: */ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; stream.next_out = dest; stream.avail_out = (uInt)*destLen; if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; stream.zalloc = (alloc_func)0; stream.zfree = (free_func)0; err = inflateInit(&stream); if (err != Z_OK) return err; err = inflate(&stream, Z_FINISH); if (err != Z_STREAM_END) { inflateEnd(&stream); if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) return Z_DATA_ERROR; return err; } *destLen = stream.total_out; err = inflateEnd(&stream); return err; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/zlib/zconf.h0000644000175100001710000003205100000000000017606 0ustar00vstsdocker/* zconf.h -- configuration of the zlib compression library * Copyright (C) 1995-2010 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ #ifndef ZCONF_H #define ZCONF_H /* * If you *really* need a unique prefix for all types and library functions, * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. * Even better than compiling with -DZ_PREFIX would be to use configure to set * this permanently in zconf.h using "./configure --zprefix". */ #ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ /* all linked symbols */ # define _dist_code z__dist_code # define _length_code z__length_code # define _tr_align z__tr_align # define _tr_flush_block z__tr_flush_block # define _tr_init z__tr_init # define _tr_stored_block z__tr_stored_block # define _tr_tally z__tr_tally # define adler32 z_adler32 # define adler32_combine z_adler32_combine # define adler32_combine64 z_adler32_combine64 # define compress z_compress # define compress2 z_compress2 # define compressBound z_compressBound # define crc32 z_crc32 # define crc32_combine z_crc32_combine # define crc32_combine64 z_crc32_combine64 # define deflate z_deflate # define deflateBound z_deflateBound # define deflateCopy z_deflateCopy # define deflateEnd z_deflateEnd # define deflateInit2_ z_deflateInit2_ # define deflateInit_ z_deflateInit_ # define deflateParams z_deflateParams # define deflatePrime z_deflatePrime # define deflateReset z_deflateReset # define deflateSetDictionary z_deflateSetDictionary # define deflateSetHeader z_deflateSetHeader # define deflateTune z_deflateTune # define deflate_copyright z_deflate_copyright # define get_crc_table z_get_crc_table # define gz_error z_gz_error # define gz_intmax z_gz_intmax # define gz_strwinerror z_gz_strwinerror # define gzbuffer z_gzbuffer # define gzclearerr z_gzclearerr # define gzclose z_gzclose # define gzclose_r z_gzclose_r # define gzclose_w z_gzclose_w # define gzdirect z_gzdirect # define gzdopen z_gzdopen # define gzeof z_gzeof # define gzerror z_gzerror # define gzflush z_gzflush # define gzgetc z_gzgetc # define gzgets z_gzgets # define gzoffset z_gzoffset # define gzoffset64 z_gzoffset64 # define gzopen z_gzopen # define gzopen64 z_gzopen64 # define gzprintf z_gzprintf # define gzputc z_gzputc # define gzputs z_gzputs # define gzread z_gzread # define gzrewind z_gzrewind # define gzseek z_gzseek # define gzseek64 z_gzseek64 # define gzsetparams z_gzsetparams # define gztell z_gztell # define gztell64 z_gztell64 # define gzungetc z_gzungetc # define gzwrite z_gzwrite # define inflate z_inflate # define inflateBack z_inflateBack # define inflateBackEnd z_inflateBackEnd # define inflateBackInit_ z_inflateBackInit_ # define inflateCopy z_inflateCopy # define inflateEnd z_inflateEnd # define inflateGetHeader z_inflateGetHeader # define inflateInit2_ z_inflateInit2_ # define inflateInit_ z_inflateInit_ # define inflateMark z_inflateMark # define inflatePrime z_inflatePrime # define inflateReset z_inflateReset # define inflateReset2 z_inflateReset2 # define inflateSetDictionary z_inflateSetDictionary # define inflateSync z_inflateSync # define inflateSyncPoint z_inflateSyncPoint # define inflateUndermine z_inflateUndermine # define inflate_copyright z_inflate_copyright # define inflate_fast z_inflate_fast # define inflate_table z_inflate_table # define uncompress z_uncompress # define zError z_zError # define zcalloc z_zcalloc # define zcfree z_zcfree # define zlibCompileFlags z_zlibCompileFlags # define zlibVersion z_zlibVersion /* all zlib typedefs in zlib.h and zconf.h */ # define Byte z_Byte # define Bytef z_Bytef # define alloc_func z_alloc_func # define charf z_charf # define free_func z_free_func # define gzFile z_gzFile # define gz_header z_gz_header # define gz_headerp z_gz_headerp # define in_func z_in_func # define intf z_intf # define out_func z_out_func # define uInt z_uInt # define uIntf z_uIntf # define uLong z_uLong # define uLongf z_uLongf # define voidp z_voidp # define voidpc z_voidpc # define voidpf z_voidpf /* all zlib structs in zlib.h and zconf.h */ # define gz_header_s z_gz_header_s # define internal_state z_internal_state #endif #if defined(__MSDOS__) && !defined(MSDOS) # define MSDOS #endif #if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) # define OS2 #endif #if defined(_WINDOWS) && !defined(WINDOWS) # define WINDOWS #endif #if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) # ifndef WIN32 # define WIN32 # endif #endif #if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) # if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) # ifndef SYS16BIT # define SYS16BIT # endif # endif #endif /* * Compile with -DMAXSEG_64K if the alloc function cannot allocate more * than 64k bytes at a time (needed on systems with 16-bit int). */ #ifdef SYS16BIT # define MAXSEG_64K #endif #ifdef MSDOS # define UNALIGNED_OK #endif #ifdef __STDC_VERSION__ # ifndef STDC # define STDC # endif # if __STDC_VERSION__ >= 199901L # ifndef STDC99 # define STDC99 # endif # endif #endif #if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) # define STDC #endif #if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) # define STDC #endif #if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) # define STDC #endif #if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) # define STDC #endif #if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ # define STDC #endif #ifndef STDC # ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ # define const /* note: need a more gentle solution here */ # endif #endif /* Some Mac compilers merge all .h files incorrectly: */ #if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) # define NO_DUMMY_DECL #endif /* Maximum value for memLevel in deflateInit2 */ #ifndef MAX_MEM_LEVEL # ifdef MAXSEG_64K # define MAX_MEM_LEVEL 8 # else # define MAX_MEM_LEVEL 9 # endif #endif /* Maximum value for windowBits in deflateInit2 and inflateInit2. * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files * created by gzip. (Files created by minigzip can still be extracted by * gzip.) */ #ifndef MAX_WBITS # define MAX_WBITS 15 /* 32K LZ77 window */ #endif /* The memory requirements for deflate are (in bytes): (1 << (windowBits+2)) + (1 << (memLevel+9)) that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) plus a few kilobytes for small objects. For example, if you want to reduce the default memory requirements from 256K to 128K, compile with make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" Of course this will generally degrade compression (there's no free lunch). The memory requirements for inflate are (in bytes) 1 << windowBits that is, 32K for windowBits=15 (default value) plus a few kilobytes for small objects. */ /* Type declarations */ #ifndef OF /* function prototypes */ # ifdef STDC # define OF(args) args # else # define OF(args) () # endif #endif /* The following definitions for FAR are needed only for MSDOS mixed * model programming (small or medium model with some far allocations). * This was tested only with MSC; for other MSDOS compilers you may have * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, * just define FAR to be empty. */ #ifdef SYS16BIT # if defined(M_I86SM) || defined(M_I86MM) /* MSC small or medium model */ # define SMALL_MEDIUM # ifdef _MSC_VER # define FAR _far # else # define FAR far # endif # endif # if (defined(__SMALL__) || defined(__MEDIUM__)) /* Turbo C small or medium model */ # define SMALL_MEDIUM # ifdef __BORLANDC__ # define FAR _far # else # define FAR far # endif # endif #endif #if defined(WINDOWS) || defined(WIN32) /* If building or using zlib as a DLL, define ZLIB_DLL. * This is not mandatory, but it offers a little performance increase. */ # ifdef ZLIB_DLL # if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) # ifdef ZLIB_INTERNAL # define ZEXTERN extern __declspec(dllexport) # else # define ZEXTERN extern __declspec(dllimport) # endif # endif # endif /* ZLIB_DLL */ /* If building or using zlib with the WINAPI/WINAPIV calling convention, * define ZLIB_WINAPI. * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. */ # ifdef ZLIB_WINAPI # ifdef FAR # undef FAR # endif # include /* No need for _export, use ZLIB.DEF instead. */ /* For complete Windows compatibility, use WINAPI, not __stdcall. */ # define ZEXPORT WINAPI # ifdef WIN32 # define ZEXPORTVA WINAPIV # else # define ZEXPORTVA FAR CDECL # endif # endif #endif #if defined (__BEOS__) # ifdef ZLIB_DLL # ifdef ZLIB_INTERNAL # define ZEXPORT __declspec(dllexport) # define ZEXPORTVA __declspec(dllexport) # else # define ZEXPORT __declspec(dllimport) # define ZEXPORTVA __declspec(dllimport) # endif # endif #endif #ifndef ZEXTERN # define ZEXTERN extern #endif #ifndef ZEXPORT # define ZEXPORT #endif #ifndef ZEXPORTVA # define ZEXPORTVA #endif #ifndef FAR # define FAR #endif #if !defined(__MACTYPES__) typedef unsigned char Byte; /* 8 bits */ #endif typedef unsigned int uInt; /* 16 bits or more */ typedef unsigned long uLong; /* 32 bits or more */ #ifdef SMALL_MEDIUM /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ # define Bytef Byte FAR #else typedef Byte FAR Bytef; #endif typedef char FAR charf; typedef int FAR intf; typedef uInt FAR uIntf; typedef uLong FAR uLongf; #ifdef STDC typedef void const *voidpc; typedef void FAR *voidpf; typedef void *voidp; #else typedef Byte const *voidpc; typedef Byte FAR *voidpf; typedef Byte *voidp; #endif #if !defined(MSDOS) && !defined(WINDOWS) && !defined(WIN32) # define Z_HAVE_UNISTD_H #endif #ifdef STDC # include /* for off_t */ #endif /* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even * though the former does not conform to the LFS document), but considering * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as * equivalently requesting no 64-bit operations */ #if -_LARGEFILE64_SOURCE - -1 == 1 # undef _LARGEFILE64_SOURCE #endif #if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) # include /* for SEEK_* and off_t */ # ifdef VMS # include /* for off_t */ # endif # ifndef z_off_t # define z_off_t off_t # endif #endif #ifndef SEEK_SET # define SEEK_SET 0 /* Seek from beginning of file. */ # define SEEK_CUR 1 /* Seek from current position. */ # define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ #endif #ifndef z_off_t # define z_off_t long #endif #if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 # define z_off64_t off64_t #else # define z_off64_t z_off_t #endif #if defined(__OS400__) # define NO_vsnprintf #endif #if defined(__MVS__) # define NO_vsnprintf #endif /* MVS linker does not support external names larger than 8 bytes */ #if defined(__MVS__) #pragma map(deflateInit_,"DEIN") #pragma map(deflateInit2_,"DEIN2") #pragma map(deflateEnd,"DEEND") #pragma map(deflateBound,"DEBND") #pragma map(inflateInit_,"ININ") #pragma map(inflateInit2_,"ININ2") #pragma map(inflateEnd,"INEND") #pragma map(inflateSync,"INSY") #pragma map(inflateSetDictionary,"INSEDI") #pragma map(compressBound,"CMBND") #pragma map(inflate_table,"INTABL") #pragma map(inflate_fast,"INFA") #pragma map(inflate_copyright,"INCOPY") #endif #endif /* ZCONF_H */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/zlib/zlib.h0000644000175100001710000023331400000000000017434 0ustar00vstsdocker/* zlib.h -- interface of the 'zlib' general purpose compression library version 1.2.5, April 19th, 2010 Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). */ #ifndef ZLIB_H #define ZLIB_H #include "zconf.h" #ifdef __cplusplus extern "C" { #endif #define ZLIB_VERSION "1.2.5" #define ZLIB_VERNUM 0x1250 #define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MINOR 2 #define ZLIB_VER_REVISION 5 #define ZLIB_VER_SUBREVISION 0 /* The 'zlib' compression library provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) but other algorithms will be added later and will have the same stream interface. Compression can be done in a single step if the buffers are large enough, or can be done by repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. The compressed data format used by default by the in-memory functions is the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped around a deflate stream, which is itself documented in RFC 1951. The library also supports reading and writing files in gzip (.gz) format with an interface similar to that of stdio using the functions that start with "gz". The gzip format is different from the zlib format. gzip is a gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. This library can optionally read and write gzip streams in memory as well. The zlib format was designed to be compact and fast for use in memory and on communications channels. The gzip format was designed for single- file compression on file systems, has a larger header than zlib to maintain directory information, and uses a different, slower check method than zlib. The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash even in case of corrupted input. */ typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); typedef void (*free_func) OF((voidpf opaque, voidpf address)); struct internal_state; typedef struct z_stream_s { Bytef *next_in; /* next input byte */ uInt avail_in; /* number of bytes available at next_in */ uLong total_in; /* total nb of input bytes read so far */ Bytef *next_out; /* next output byte should be put there */ uInt avail_out; /* remaining free space at next_out */ uLong total_out; /* total nb of bytes output so far */ char *msg; /* last error message, NULL if no error */ struct internal_state FAR *state; /* not visible by applications */ alloc_func zalloc; /* used to allocate the internal state */ free_func zfree; /* used to free the internal state */ voidpf opaque; /* private data object passed to zalloc and zfree */ int data_type; /* best guess about the data type: binary or text */ uLong adler; /* adler32 value of the uncompressed data */ uLong reserved; /* reserved for future use */ } z_stream; typedef z_stream FAR *z_streamp; /* gzip header information passed to and from zlib routines. See RFC 1952 for more details on the meanings of these fields. */ typedef struct gz_header_s { int text; /* true if compressed data believed to be text */ uLong time; /* modification time */ int xflags; /* extra flags (not used when writing a gzip file) */ int os; /* operating system */ Bytef *extra; /* pointer to extra field or Z_NULL if none */ uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ uInt extra_max; /* space at extra (only when reading header) */ Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ uInt name_max; /* space at name (only when reading header) */ Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ uInt comm_max; /* space at comment (only when reading header) */ int hcrc; /* true if there was or will be a header crc */ int done; /* true when done reading gzip header (not used when writing a gzip file) */ } gz_header; typedef gz_header FAR *gz_headerp; /* The application must update next_in and avail_in when avail_in has dropped to zero. It must update next_out and avail_out when avail_out has dropped to zero. The application must initialize zalloc, zfree and opaque before calling the init function. All other fields are set by the compression library and must not be updated by the application. The opaque value provided by the application will be passed as the first parameter for calls of zalloc and zfree. This can be useful for custom memory management. The compression library attaches no meaning to the opaque value. zalloc must return Z_NULL if there is not enough memory for the object. If zlib is used in a multi-threaded application, zalloc and zfree must be thread safe. On 16-bit systems, the functions zalloc and zfree must be able to allocate exactly 65536 bytes, but will not be required to allocate more than this if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers returned by zalloc for objects of exactly 65536 bytes *must* have their offset normalized to zero. The default allocation function provided by this library ensures this (see zutil.c). To reduce memory requirements and avoid any allocation of 64K objects, at the expense of compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). The fields total_in and total_out can be used for statistics or progress reports. After compression, total_in holds the total size of the uncompressed data and may be saved for use in the decompressor (particularly if the decompressor wants to decompress everything in a single step). */ /* constants */ #define Z_NO_FLUSH 0 #define Z_PARTIAL_FLUSH 1 #define Z_SYNC_FLUSH 2 #define Z_FULL_FLUSH 3 #define Z_FINISH 4 #define Z_BLOCK 5 #define Z_TREES 6 /* Allowed flush values; see deflate() and inflate() below for details */ #define Z_OK 0 #define Z_STREAM_END 1 #define Z_NEED_DICT 2 #define Z_ERRNO (-1) #define Z_STREAM_ERROR (-2) #define Z_DATA_ERROR (-3) #define Z_MEM_ERROR (-4) #define Z_BUF_ERROR (-5) #define Z_VERSION_ERROR (-6) /* Return codes for the compression/decompression functions. Negative values * are errors, positive values are used for special but normal events. */ #define Z_NO_COMPRESSION 0 #define Z_BEST_SPEED 1 #define Z_BEST_COMPRESSION 9 #define Z_DEFAULT_COMPRESSION (-1) /* compression levels */ #define Z_FILTERED 1 #define Z_HUFFMAN_ONLY 2 #define Z_RLE 3 #define Z_FIXED 4 #define Z_DEFAULT_STRATEGY 0 /* compression strategy; see deflateInit2() below for details */ #define Z_BINARY 0 #define Z_TEXT 1 #define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ #define Z_UNKNOWN 2 /* Possible values of the data_type field (though see inflate()) */ #define Z_DEFLATED 8 /* The deflate compression method (the only one supported in this version) */ #define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ #define zlib_version zlibVersion() /* for compatibility with versions < 1.0.2 */ /* basic functions */ ZEXTERN const char * ZEXPORT zlibVersion OF((void)); /* The application can compare zlibVersion and ZLIB_VERSION for consistency. If the first character differs, the library code actually used is not compatible with the zlib.h header file used by the application. This check is automatically made by deflateInit and inflateInit. */ /* ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); Initializes the internal stream state for compression. The fields zalloc, zfree and opaque must be initialized before by the caller. If zalloc and zfree are set to Z_NULL, deflateInit updates them to use default allocation functions. The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: 1 gives best speed, 9 gives best compression, 0 gives no compression at all (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION requests a default compromise between speed and compression (currently equivalent to level 6). deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if level is not a valid compression level, or Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible with the version assumed by the caller (ZLIB_VERSION). msg is set to null if there is no error message. deflateInit does not perform any compression: this will be done by deflate(). */ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); /* deflate compresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce some output latency (reading input without producing any output) except when forced to flush. The detailed semantics are as follows. deflate performs one or both of the following actions: - Compress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in and avail_in are updated and processing will resume at this point for the next call of deflate(). - Provide more output starting at next_out and update next_out and avail_out accordingly. This action is forced if the parameter flush is non zero. Forcing flush frequently degrades the compression ratio, so this parameter should be set only when necessary (in interactive applications). Some output may be provided even if flush is not set. Before the call of deflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more output, and updating avail_in or avail_out accordingly; avail_out should never be zero before the call. The application can consume the compressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK and with zero avail_out, it must be called again after making room in the output buffer because there might be more output pending. Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to decide how much data to accumulate before producing output, in order to maximize compression. If the parameter flush is set to Z_SYNC_FLUSH, all pending output is flushed to the output buffer and the output is aligned on a byte boundary, so that the decompressor can get all input data available so far. (In particular avail_in is zero after the call if enough output space has been provided before the call.) Flushing may degrade compression for some compression algorithms and so it should be used only when necessary. This completes the current deflate block and follows it with an empty stored block that is three bits plus filler bits to the next byte, followed by four bytes (00 00 ff ff). If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the output buffer, but the output is not aligned to a byte boundary. All of the input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. This completes the current deflate block and follows it with an empty fixed codes block that is 10 bits long. This assures that enough bytes are output in order for the decompressor to finish the block before the empty fixed code block. If flush is set to Z_BLOCK, a deflate block is completed and emitted, as for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to seven bits of the current block are held to be written as the next byte after the next deflate block is completed. In this case, the decompressor may not be provided enough bits at this point in order to complete decompression of the data provided so far to the compressor. It may need to wait for the next block to be emitted. This is for advanced applications that need to control the emission of deflate blocks. If flush is set to Z_FULL_FLUSH, all output is flushed as with Z_SYNC_FLUSH, and the compression state is reset so that decompression can restart from this point if previous compressed data has been damaged or if random access is desired. Using Z_FULL_FLUSH too often can seriously degrade compression. If deflate returns with avail_out == 0, this function must be called again with the same value of the flush parameter and more output space (updated avail_out), until the flush is complete (deflate returns with non-zero avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that avail_out is greater than six to avoid repeated flush markers due to avail_out == 0 on return. If the parameter flush is set to Z_FINISH, pending input is processed, pending output is flushed and deflate returns with Z_STREAM_END if there was enough output space; if deflate returns with Z_OK, this function must be called again with Z_FINISH and more output space (updated avail_out) but no more input data, until it returns with Z_STREAM_END or an error. After deflate has returned Z_STREAM_END, the only possible operations on the stream are deflateReset or deflateEnd. Z_FINISH can be used immediately after deflateInit if all the compression is to be done in a single step. In this case, avail_out must be at least the value returned by deflateBound (see below). If deflate does not return Z_STREAM_END, then it must be called again as described above. deflate() sets strm->adler to the adler32 checksum of all input read so far (that is, total_in bytes). deflate() may update strm->data_type if it can make a good guess about the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered binary. This field is only for information purposes and does not affect the compression algorithm in any manner. deflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if all input has been consumed and all output has been produced (only when flush is set to Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and deflate() can be called again with more input and more output space to continue compressing. */ ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output. deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent, Z_DATA_ERROR if the stream was freed prematurely (some input or output was discarded). In the error case, msg may be set but then points to a static string (which must not be deallocated). */ /* ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); Initializes the internal stream state for decompression. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by the caller. If next_in is not Z_NULL and avail_in is large enough (the exact value depends on the compression method), inflateInit determines the compression method from the zlib header and allocates all data structures accordingly; otherwise the allocation will be deferred to the first call of inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to use default allocation functions. inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the version assumed by the caller, or Z_STREAM_ERROR if the parameters are invalid, such as a null pointer to the structure. msg is set to null if there is no error message. inflateInit does not perform any decompression apart from possibly reading the zlib header if present: actual decompression will be done by inflate(). (So next_in and avail_in may be modified, but next_out and avail_out are unused and unchanged.) The current implementation of inflateInit() does not process any header information -- that is deferred until inflate() is called. */ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); /* inflate decompresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce some output latency (reading input without producing any output) except when forced to flush. The detailed semantics are as follows. inflate performs one or both of the following actions: - Decompress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in is updated and processing will resume at this point for the next call of inflate(). - Provide more output starting at next_out and update next_out and avail_out accordingly. inflate() provides as much output as possible, until there is no more input data or no more space in the output buffer (see below about the flush parameter). Before the call of inflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more output, and updating the next_* and avail_* values accordingly. The application can consume the uncompressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of inflate(). If inflate returns Z_OK and with zero avail_out, it must be called again after making room in the output buffer because there might be more output pending. The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much output as possible to the output buffer. Z_BLOCK requests that inflate() stop if and when it gets to the next deflate block boundary. When decoding the zlib or gzip format, this will cause inflate() to return immediately after the header and before the first block. When doing a raw inflate, inflate() will go ahead and process the first block, and will return when it gets to the end of that block, or when it runs out of data. The Z_BLOCK option assists in appending to or combining deflate streams. Also to assist in this, on return inflate() will set strm->data_type to the number of unused bits in the last byte taken from strm->next_in, plus 64 if inflate() is currently decoding the last block in the deflate stream, plus 128 if inflate() returned immediately after decoding an end-of-block code or decoding the complete header up to just before the first byte of the deflate stream. The end-of-block will not be indicated until all of the uncompressed data from that block has been written to strm->next_out. The number of unused bits may in general be greater than seven, except when bit 7 of data_type is set, in which case the number of unused bits will be less than eight. data_type is set as noted here every time inflate() returns for all flush options, and so can be used to determine the amount of currently consumed input in bits. The Z_TREES option behaves as Z_BLOCK does, but it also returns when the end of each deflate block header is reached, before any actual data in that block is decoded. This allows the caller to determine the length of the deflate block header for later use in random access within a deflate block. 256 is added to the value of strm->data_type when inflate() returns immediately after reaching the end of the deflate block header. inflate() should normally be called until it returns Z_STREAM_END or an error. However if all decompression is to be performed in a single step (a single call of inflate), the parameter flush should be set to Z_FINISH. In this case all pending input is processed and all pending output is flushed; avail_out must be large enough to hold all the uncompressed data. (The size of the uncompressed data may have been saved by the compressor for this purpose.) The next operation on this stream must be inflateEnd to deallocate the decompression state. The use of Z_FINISH is never required, but can be used to inform inflate that a faster approach may be used for the single inflate() call. In this implementation, inflate() always flushes as much output as possible to the output buffer, and always uses the faster approach on the first call. So the only effect of the flush parameter in this implementation is on the return value of inflate(), as noted below, or when it returns early because Z_BLOCK or Z_TREES is used. If a preset dictionary is needed after this call (see inflateSetDictionary below), inflate sets strm->adler to the adler32 checksum of the dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise it sets strm->adler to the adler32 checksum of all output produced so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described below. At the end of the stream, inflate() checks that its computed adler32 checksum is equal to that saved by the compressor and returns Z_STREAM_END only if the checksum is correct. inflate() can decompress and check either zlib-wrapped or gzip-wrapped deflate data. The header type is detected automatically, if requested when initializing with inflateInit2(). Any information contained in the gzip header is not retained, so applications that need that information should instead use raw inflate, see inflateInit2() below, or inflateBack() and perform their own processing of the gzip header and trailer. inflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if the end of the compressed data has been reached and all uncompressed output has been produced, Z_NEED_DICT if a preset dictionary is needed at this point, Z_DATA_ERROR if the input data was corrupted (input stream not conforming to the zlib format or incorrect check value), Z_STREAM_ERROR if the stream structure was inconsistent (for example next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no progress is possible or if there was not enough room in the output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and inflate() can be called again with more input and more output space to continue decompressing. If Z_DATA_ERROR is returned, the application may then call inflateSync() to look for a good compression block if a partial recovery of the data is desired. */ ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output. inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent. In the error case, msg may be set but then points to a static string (which must not be deallocated). */ /* Advanced functions */ /* The following functions are needed only in some special applications. */ /* ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy)); This is another version of deflateInit with more compression options. The fields next_in, zalloc, zfree and opaque must be initialized before by the caller. The method parameter is the compression method. It must be Z_DEFLATED in this version of the library. The windowBits parameter is the base two logarithm of the window size (the size of the history buffer). It should be in the range 8..15 for this version of the library. Larger values of this parameter result in better compression at the expense of memory usage. The default value is 15 if deflateInit is used instead. windowBits can also be -8..-15 for raw deflate. In this case, -windowBits determines the window size. deflate() will then generate raw deflate data with no zlib header or trailer, and will not compute an adler32 check value. windowBits can also be greater than 15 for optional gzip encoding. Add 16 to windowBits to write a simple gzip header and trailer around the compressed data instead of a zlib wrapper. The gzip header will have no file name, no extra data, no comment, no modification time (set to zero), no header crc, and the operating system will be set to 255 (unknown). If a gzip stream is being written, strm->adler is a crc32 instead of an adler32. The memLevel parameter specifies how much memory should be allocated for the internal compression state. memLevel=1 uses minimum memory but is slow and reduces compression ratio; memLevel=9 uses maximum memory for optimal speed. The default value is 8. See zconf.h for total memory usage as a function of windowBits and memLevel. The strategy parameter is used to tune the compression algorithm. Use the value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no string match), or Z_RLE to limit match distances to one (run-length encoding). Filtered data consists mostly of small values with a somewhat random distribution. In this case, the compression algorithm is tuned to compress them better. The effect of Z_FILTERED is to force more Huffman coding and less string matching; it is somewhat intermediate between Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy parameter only affects the compression ratio but not the correctness of the compressed output even if it is not set appropriately. Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler decoder for special applications. deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible with the version assumed by the caller (ZLIB_VERSION). msg is set to null if there is no error message. deflateInit2 does not perform any compression: this will be done by deflate(). */ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, const Bytef *dictionary, uInt dictLength)); /* Initializes the compression dictionary from the given byte sequence without producing any compressed output. This function must be called immediately after deflateInit, deflateInit2 or deflateReset, before any call of deflate. The compressor and decompressor must use exactly the same dictionary (see inflateSetDictionary). The dictionary should consist of strings (byte sequences) that are likely to be encountered later in the data to be compressed, with the most commonly used strings preferably put towards the end of the dictionary. Using a dictionary is most useful when the data to be compressed is short and can be predicted with good accuracy; the data can then be compressed better than with the default empty dictionary. Depending on the size of the compression data structures selected by deflateInit or deflateInit2, a part of the dictionary may in effect be discarded, for example if the dictionary is larger than the window size provided in deflateInit or deflateInit2. Thus the strings most likely to be useful should be put at the end of the dictionary, not at the front. In addition, the current implementation of deflate will use at most the window size minus 262 bytes of the provided dictionary. Upon return of this function, strm->adler is set to the adler32 value of the dictionary; the decompressor may later use this value to determine which dictionary has been used by the compressor. (The adler32 value applies to the whole dictionary even if only a subset of the dictionary is actually used by the compressor.) If a raw deflate was requested, then the adler32 value is not computed and strm->adler is not set. deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is inconsistent (for example if deflate has already been called for this stream or if the compression method is bsort). deflateSetDictionary does not perform any compression: this will be done by deflate(). */ ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, z_streamp source)); /* Sets the destination stream as a complete copy of the source stream. This function can be useful when several compression strategies will be tried, for example when there are several ways of pre-processing the input data with a filter. The streams that will be discarded should then be freed by calling deflateEnd. Note that deflateCopy duplicates the internal compression state which can be quite large, so this strategy is slow and can consume lots of memory. deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc being Z_NULL). msg is left unchanged in both source and destination. */ ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); /* This function is equivalent to deflateEnd followed by deflateInit, but does not free and reallocate all the internal compression state. The stream will keep the same compression level and any other attributes that may have been set by deflateInit2. deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being Z_NULL). */ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, int level, int strategy)); /* Dynamically update the compression level and compression strategy. The interpretation of level and strategy is as in deflateInit2. This can be used to switch between compression and straight copy of the input data, or to switch to a different kind of input data requiring a different strategy. If the compression level is changed, the input available so far is compressed with the old level (and may be flushed); the new level will take effect only at the next call of deflate(). Before the call of deflateParams, the stream state must be set as for a call of deflate(), since the currently available input may have to be compressed and flushed. In particular, strm->avail_out must be non-zero. deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if strm->avail_out was zero. */ ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, int good_length, int max_lazy, int nice_length, int max_chain)); /* Fine tune deflate's internal compression parameters. This should only be used by someone who understands the algorithm used by zlib's deflate for searching for the best matching string, and even then only by the most fanatic optimizer trying to squeeze out the last compressed bit for their specific input data. Read the deflate.c source code for the meaning of the max_lazy, good_length, nice_length, and max_chain parameters. deflateTune() can be called after deflateInit() or deflateInit2(), and returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. */ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, uLong sourceLen)); /* deflateBound() returns an upper bound on the compressed size after deflation of sourceLen bytes. It must be called after deflateInit() or deflateInit2(), and after deflateSetHeader(), if used. This would be used to allocate an output buffer for deflation in a single pass, and so would be called before deflate(). */ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, int bits, int value)); /* deflatePrime() inserts bits in the deflate output stream. The intent is that this function is used to start off the deflate output with the bits leftover from a previous deflate stream when appending to it. As such, this function can only be used for raw deflate, and must be used before the first deflate() call after a deflateInit2() or deflateReset(). bits must be less than or equal to 16, and that many of the least significant bits of value will be inserted in the output. deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, gz_headerp head)); /* deflateSetHeader() provides gzip header information for when a gzip stream is requested by deflateInit2(). deflateSetHeader() may be called after deflateInit2() or deflateReset() and before the first call of deflate(). The text, time, os, extra field, name, and comment information in the provided gz_header structure are written to the gzip header (xflag is ignored -- the extra flags are set according to the compression level). The caller must assure that, if not Z_NULL, name and comment are terminated with a zero byte, and that if extra is not Z_NULL, that extra_len bytes are available there. If hcrc is true, a gzip header crc is included. Note that the current versions of the command-line version of gzip (up through version 1.3.x) do not support header crc's, and will report that it is a "multi-part gzip file" and give up. If deflateSetHeader is not used, the default gzip header has text false, the time set to zero, and os set to 255, with no extra, name, or comment fields. The gzip header is returned to the default state by deflateReset(). deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ /* ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, int windowBits)); This is another version of inflateInit with an extra parameter. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by the caller. The windowBits parameter is the base two logarithm of the maximum window size (the size of the history buffer). It should be in the range 8..15 for this version of the library. The default value is 15 if inflateInit is used instead. windowBits must be greater than or equal to the windowBits value provided to deflateInit2() while compressing, or it must be equal to 15 if deflateInit2() was not used. If a compressed stream with a larger window size is given as input, inflate() will return with the error code Z_DATA_ERROR instead of trying to allocate a larger window. windowBits can also be zero to request that inflate use the window size in the zlib header of the compressed stream. windowBits can also be -8..-15 for raw inflate. In this case, -windowBits determines the window size. inflate() will then process raw deflate data, not looking for a zlib or gzip header, not generating a check value, and not looking for any check values for comparison at the end of the stream. This is for use with other formats that use the deflate compressed data format such as zip. Those formats provide their own check values. If a custom format is developed using the raw deflate format for compressed data, it is recommended that a check value such as an adler32 or a crc32 be applied to the uncompressed data as is done in the zlib, gzip, and zip formats. For most applications, the zlib format should be used as is. Note that comments above on the use in deflateInit2() applies to the magnitude of windowBits. windowBits can also be greater than 15 for optional gzip decoding. Add 32 to windowBits to enable zlib and gzip decoding with automatic header detection, or add 16 to decode only the gzip format (the zlib format will return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a crc32 instead of an adler32. inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the version assumed by the caller, or Z_STREAM_ERROR if the parameters are invalid, such as a null pointer to the structure. msg is set to null if there is no error message. inflateInit2 does not perform any decompression apart from possibly reading the zlib header if present: actual decompression will be done by inflate(). (So next_in and avail_in may be modified, but next_out and avail_out are unused and unchanged.) The current implementation of inflateInit2() does not process any header information -- that is deferred until inflate() is called. */ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, const Bytef *dictionary, uInt dictLength)); /* Initializes the decompression dictionary from the given uncompressed byte sequence. This function must be called immediately after a call of inflate, if that call returned Z_NEED_DICT. The dictionary chosen by the compressor can be determined from the adler32 value returned by that call of inflate. The compressor and decompressor must use exactly the same dictionary (see deflateSetDictionary). For raw inflate, this function can be called immediately after inflateInit2() or inflateReset() and before any call of inflate() to set the dictionary. The application must insure that the dictionary that was used for compression is provided. inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the expected one (incorrect adler32 value). inflateSetDictionary does not perform any decompression: this will be done by subsequent calls of inflate(). */ ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); /* Skips invalid compressed data until a full flush point (see above the description of deflate with Z_FULL_FLUSH) can be found, or until all available input is skipped. No output is provided. inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the success case, the application may save the current current value of total_in which indicates where valid compressed data was found. In the error case, the application may repeatedly call inflateSync, providing more input each time, until success or end of the input data. */ ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, z_streamp source)); /* Sets the destination stream as a complete copy of the source stream. This function can be useful when randomly accessing a large stream. The first pass through the stream can periodically record the inflate state, allowing restarting inflate at those points when randomly accessing the stream. inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc being Z_NULL). msg is left unchanged in both source and destination. */ ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); /* This function is equivalent to inflateEnd followed by inflateInit, but does not free and reallocate all the internal decompression state. The stream will keep attributes that may have been set by inflateInit2. inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being Z_NULL). */ ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, int windowBits)); /* This function is the same as inflateReset, but it also permits changing the wrap and window size requests. The windowBits parameter is interpreted the same as it is for inflateInit2. inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being Z_NULL), or if the windowBits parameter is invalid. */ ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, int bits, int value)); /* This function inserts bits in the inflate input stream. The intent is that this function is used to start inflating at a bit position in the middle of a byte. The provided bits will be used before any bytes are used from next_in. This function should only be used with raw inflate, and should be used before the first inflate() call after inflateInit2() or inflateReset(). bits must be less than or equal to 16, and that many of the least significant bits of value will be inserted in the input. If bits is negative, then the input stream bit buffer is emptied. Then inflatePrime() can be called again to put bits in the buffer. This is used to clear out bits leftover after feeding inflate a block description prior to feeding inflate codes. inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); /* This function returns two values, one in the lower 16 bits of the return value, and the other in the remaining upper bits, obtained by shifting the return value down 16 bits. If the upper value is -1 and the lower value is zero, then inflate() is currently decoding information outside of a block. If the upper value is -1 and the lower value is non-zero, then inflate is in the middle of a stored block, with the lower value equaling the number of bytes from the input remaining to copy. If the upper value is not -1, then it is the number of bits back from the current bit position in the input of the code (literal or length/distance pair) currently being processed. In that case the lower value is the number of bytes already emitted for that code. A code is being processed if inflate is waiting for more input to complete decoding of the code, or if it has completed decoding but is waiting for more output space to write the literal or match data. inflateMark() is used to mark locations in the input data for random access, which may be at bit positions, and to note those cases where the output of a code may span boundaries of random access blocks. The current location in the input stream can be determined from avail_in and data_type as noted in the description for the Z_BLOCK flush parameter for inflate. inflateMark returns the value noted above or -1 << 16 if the provided source stream state was inconsistent. */ ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, gz_headerp head)); /* inflateGetHeader() requests that gzip header information be stored in the provided gz_header structure. inflateGetHeader() may be called after inflateInit2() or inflateReset(), and before the first call of inflate(). As inflate() processes the gzip stream, head->done is zero until the header is completed, at which time head->done is set to one. If a zlib stream is being decoded, then head->done is set to -1 to indicate that there will be no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be used to force inflate() to return immediately after header processing is complete and before any actual data is decompressed. The text, time, xflags, and os fields are filled in with the gzip header contents. hcrc is set to true if there is a header CRC. (The header CRC was valid if done is set to one.) If extra is not Z_NULL, then extra_max contains the maximum number of bytes to write to extra. Once done is true, extra_len contains the actual extra field length, and extra contains the extra field, or that field truncated if extra_max is less than extra_len. If name is not Z_NULL, then up to name_max characters are written there, terminated with a zero unless the length is greater than name_max. If comment is not Z_NULL, then up to comm_max characters are written there, terminated with a zero unless the length is greater than comm_max. When any of extra, name, or comment are not Z_NULL and the respective field is not present in the header, then that field is set to Z_NULL to signal its absence. This allows the use of deflateSetHeader() with the returned structure to duplicate the header. However if those fields are set to allocated memory, then the application will need to save those pointers elsewhere so that they can be eventually freed. If inflateGetHeader is not used, then the header information is simply discarded. The header is always checked for validity, including the header CRC if present. inflateReset() will reset the process to discard the header information. The application would need to call inflateGetHeader() again to retrieve the header from the next gzip stream. inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ /* ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, unsigned char FAR *window)); Initialize the internal stream state for decompression using inflateBack() calls. The fields zalloc, zfree and opaque in strm must be initialized before the call. If zalloc and zfree are Z_NULL, then the default library- derived memory allocation routines are used. windowBits is the base two logarithm of the window size, in the range 8..15. window is a caller supplied buffer of that size. Except for special applications where it is assured that deflate was used with small window sizes, windowBits must be 15 and a 32K byte window must be supplied to be able to decompress general deflate streams. See inflateBack() for the usage of these routines. inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of the paramaters are invalid, Z_MEM_ERROR if the internal state could not be allocated, or Z_VERSION_ERROR if the version of the library does not match the version of the header file. */ typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, in_func in, void FAR *in_desc, out_func out, void FAR *out_desc)); /* inflateBack() does a raw inflate with a single call using a call-back interface for input and output. This is more efficient than inflate() for file i/o applications in that it avoids copying between the output and the sliding window by simply making the window itself the output buffer. This function trusts the application to not change the output buffer passed by the output function, at least until inflateBack() returns. inflateBackInit() must be called first to allocate the internal state and to initialize the state with the user-provided window buffer. inflateBack() may then be used multiple times to inflate a complete, raw deflate stream with each call. inflateBackEnd() is then called to free the allocated state. A raw deflate stream is one with no zlib or gzip header or trailer. This routine would normally be used in a utility that reads zip or gzip files and writes out uncompressed files. The utility would decode the header and process the trailer on its own, hence this routine expects only the raw deflate stream to decompress. This is different from the normal behavior of inflate(), which expects either a zlib or gzip header and trailer around the deflate stream. inflateBack() uses two subroutines supplied by the caller that are then called by inflateBack() for input and output. inflateBack() calls those routines until it reads a complete deflate stream and writes out all of the uncompressed data, or until it encounters an error. The function's parameters and return types are defined above in the in_func and out_func typedefs. inflateBack() will call in(in_desc, &buf) which should return the number of bytes of provided input, and a pointer to that input in buf. If there is no input available, in() must return zero--buf is ignored in that case--and inflateBack() will return a buffer error. inflateBack() will call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() should return zero on success, or non-zero on failure. If out() returns non-zero, inflateBack() will return with an error. Neither in() nor out() are permitted to change the contents of the window provided to inflateBackInit(), which is also the buffer that out() uses to write from. The length written by out() will be at most the window size. Any non-zero amount of input may be provided by in(). For convenience, inflateBack() can be provided input on the first call by setting strm->next_in and strm->avail_in. If that input is exhausted, then in() will be called. Therefore strm->next_in must be initialized before calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in must also be initialized, and then if strm->avail_in is not zero, input will initially be taken from strm->next_in[0 .. strm->avail_in - 1]. The in_desc and out_desc parameters of inflateBack() is passed as the first parameter of in() and out() respectively when they are called. These descriptors can be optionally used to pass any information that the caller- supplied in() and out() functions need to do their job. On return, inflateBack() will set strm->next_in and strm->avail_in to pass back any unused input that was provided by the last in() call. The return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR if in() or out() returned an error, Z_DATA_ERROR if there was a format error in the deflate stream (in which case strm->msg is set to indicate the nature of the error), or Z_STREAM_ERROR if the stream was not properly initialized. In the case of Z_BUF_ERROR, an input or output error can be distinguished using strm->next_in which will be Z_NULL only if in() returned an error. If strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning non-zero. (in() will always be called before out(), so strm->next_in is assured to be defined if out() returns non-zero.) Note that inflateBack() cannot return Z_OK. */ ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); /* All memory allocated by inflateBackInit() is freed. inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream state was inconsistent. */ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); /* Return flags indicating compile-time options. Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: 1.0: size of uInt 3.2: size of uLong 5.4: size of voidpf (pointer) 7.6: size of z_off_t Compiler, assembler, and debug options: 8: DEBUG 9: ASMV or ASMINF -- use ASM code 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention 11: 0 (reserved) One-time table building (smaller code, but not thread-safe if true): 12: BUILDFIXED -- build static block decoding tables when needed 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed 14,15: 0 (reserved) Library content (indicates missing functionality): 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking deflate code when not needed) 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect and decode gzip streams (to avoid linking crc code) 18-19: 0 (reserved) Operation variations (changes in library functionality): 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate 21: FASTEST -- deflate algorithm with only one, lowest compression level 22,23: 0 (reserved) The sprintf variant used by gzprintf (zero is best): 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! 26: 0 = returns value, 1 = void -- 1 means inferred string length returned Remainder: 27-31: 0 (reserved) */ /* utility functions */ /* The following utility functions are implemented on top of the basic stream-oriented functions. To simplify the interface, some default options are assumed (compression level and memory usage, standard memory allocation functions). The source code of these utility functions can be modified if you need special options. */ ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)); /* Compresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least the value returned by compressBound(sourceLen). Upon exit, destLen is the actual size of the compressed buffer. compress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer. */ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level)); /* Compresses the source buffer into the destination buffer. The level parameter has the same meaning as in deflateInit. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least the value returned by compressBound(sourceLen). Upon exit, destLen is the actual size of the compressed buffer. compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, Z_STREAM_ERROR if the level parameter is invalid. */ ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); /* compressBound() returns an upper bound on the compressed size after compress() or compress2() on sourceLen bytes. It would be used before a compress() or compress2() call to allocate the destination buffer. */ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)); /* Decompresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be large enough to hold the entire uncompressed data. (The size of the uncompressed data must have been saved previously by the compressor and transmitted to the decompressor by some mechanism outside the scope of this compression library.) Upon exit, destLen is the actual size of the uncompressed buffer. uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. */ /* gzip file access functions */ /* This library supports reading and writing files in gzip (.gz) format with an interface similar to that of stdio, using the functions that start with "gz". The gzip format is different from the zlib format. gzip is a gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. */ typedef voidp gzFile; /* opaque gzip file descriptor */ /* ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); Opens a gzip (.gz) file for reading or writing. The mode parameter is as in fopen ("rb" or "wb") but can also include a compression level ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression as in "wb9F". (See the description of deflateInit2 for more information about the strategy parameter.) Also "a" can be used instead of "w" to request that the gzip stream that will be written be appended to the file. "+" will result in an error, since reading and writing to the same gzip file is not supported. gzopen can be used to read a file which is not in gzip format; in this case gzread will directly read from the file without decompression. gzopen returns NULL if the file could not be opened, if there was insufficient memory to allocate the gzFile state, or if an invalid mode was specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). errno can be checked to determine if the reason gzopen failed was that the file could not be opened. */ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); /* gzdopen associates a gzFile with the file descriptor fd. File descriptors are obtained from calls like open, dup, creat, pipe or fileno (if the file has been previously opened with fopen). The mode parameter is as in gzopen. The next call of gzclose on the returned gzFile will also close the file descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, mode);. The duplicated descriptor should be saved to avoid a leak, since gzdopen does not close fd if it fails. gzdopen returns NULL if there was insufficient memory to allocate the gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not provided, or '+' was provided), or if fd is -1. The file descriptor is not used until the next gz* read, write, seek, or close operation, so gzdopen will not detect if fd is invalid (unless fd is -1). */ ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); /* Set the internal buffer size used by this library's functions. The default buffer size is 8192 bytes. This function must be called after gzopen() or gzdopen(), and before any other calls that read or write the file. The buffer memory allocation is always deferred to the first read or write. Two buffers are allocated, either both of the specified size when writing, or one of the specified size and the other twice that size when reading. A larger buffer size of, for example, 64K or 128K bytes will noticeably increase the speed of decompression (reading). The new buffer size also affects the maximum length for gzprintf(). gzbuffer() returns 0 on success, or -1 on failure, such as being called too late. */ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); /* Dynamically update the compression level or strategy. See the description of deflateInit2 for the meaning of these parameters. gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not opened for writing. */ ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); /* Reads the given number of uncompressed bytes from the compressed file. If the input file was not in gzip format, gzread copies the given number of bytes into the buffer. After reaching the end of a gzip stream in the input, gzread will continue to read, looking for another gzip stream, or failing that, reading the rest of the input file directly without decompression. The entire input file will be read if gzread is called until it returns less than the requested len. gzread returns the number of uncompressed bytes actually read, less than len for end of file, or -1 for error. */ ZEXTERN int ZEXPORT gzwrite OF((gzFile file, voidpc buf, unsigned len)); /* Writes the given number of uncompressed bytes into the compressed file. gzwrite returns the number of uncompressed bytes written or 0 in case of error. */ ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); /* Converts, formats, and writes the arguments to the compressed file under control of the format string, as in fprintf. gzprintf returns the number of uncompressed bytes actually written, or 0 in case of error. The number of uncompressed bytes written is limited to 8191, or one less than the buffer size given to gzbuffer(). The caller should assure that this limit is not exceeded. If it is exceeded, then gzprintf() will return an error (0) with nothing written. In this case, there may also be a buffer overflow with unpredictable consequences, which is possible only if zlib was compiled with the insecure functions sprintf() or vsprintf() because the secure snprintf() or vsnprintf() functions were not available. This can be determined using zlibCompileFlags(). */ ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); /* Writes the given null-terminated string to the compressed file, excluding the terminating null character. gzputs returns the number of characters written, or -1 in case of error. */ ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); /* Reads bytes from the compressed file until len-1 characters are read, or a newline character is read and transferred to buf, or an end-of-file condition is encountered. If any characters are read or if len == 1, the string is terminated with a null character. If no characters are read due to an end-of-file or len < 1, then the buffer is left untouched. gzgets returns buf which is a null-terminated string, or it returns NULL for end-of-file or in case of error. If there was an error, the contents at buf are indeterminate. */ ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); /* Writes c, converted to an unsigned char, into the compressed file. gzputc returns the value that was written, or -1 in case of error. */ ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); /* Reads one byte from the compressed file. gzgetc returns this byte or -1 in case of end of file or error. */ ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); /* Push one character back onto the stream to be read as the first character on the next read. At least one character of push-back is allowed. gzungetc() returns the character pushed, or -1 on failure. gzungetc() will fail if c is -1, and may fail if a character has been pushed but not read yet. If gzungetc is used immediately after gzopen or gzdopen, at least the output buffer size of pushed characters is allowed. (See gzbuffer above.) The pushed character will be discarded if the stream is repositioned with gzseek() or gzrewind(). */ ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); /* Flushes all pending output into the compressed file. The parameter flush is as in the deflate() function. The return value is the zlib error number (see function gzerror below). gzflush is only permitted when writing. If the flush parameter is Z_FINISH, the remaining data is written and the gzip stream is completed in the output. If gzwrite() is called again, a new gzip stream will be started in the output. gzread() is able to read such concatented gzip streams. gzflush should be called only when strictly necessary because it will degrade compression if called too often. */ /* ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, z_off_t offset, int whence)); Sets the starting position for the next gzread or gzwrite on the given compressed file. The offset represents a number of bytes in the uncompressed data stream. The whence parameter is defined as in lseek(2); the value SEEK_END is not supported. If the file is opened for reading, this function is emulated but can be extremely slow. If the file is opened for writing, only forward seeks are supported; gzseek then compresses a sequence of zeroes up to the new starting position. gzseek returns the resulting offset location as measured in bytes from the beginning of the uncompressed stream, or -1 in case of error, in particular if the file is opened for writing and the new starting position would be before the current position. */ ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); /* Rewinds the given file. This function is supported only for reading. gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) */ /* ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); Returns the starting position for the next gzread or gzwrite on the given compressed file. This position represents a number of bytes in the uncompressed data stream, and is zero when starting, even if appending or reading a gzip stream from the middle of a file using gzdopen(). gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) */ /* ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); Returns the current offset in the file being read or written. This offset includes the count of bytes that precede the gzip stream, for example when appending or when using gzdopen() for reading. When reading, the offset does not include as yet unused buffered input. This information can be used for a progress indicator. On error, gzoffset() returns -1. */ ZEXTERN int ZEXPORT gzeof OF((gzFile file)); /* Returns true (1) if the end-of-file indicator has been set while reading, false (0) otherwise. Note that the end-of-file indicator is set only if the read tried to go past the end of the input, but came up short. Therefore, just like feof(), gzeof() may return false even if there is no more data to read, in the event that the last read request was for the exact number of bytes remaining in the input file. This will happen if the input file size is an exact multiple of the buffer size. If gzeof() returns true, then the read functions will return no more data, unless the end-of-file indicator is reset by gzclearerr() and the input file has grown since the previous end of file was detected. */ ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); /* Returns true (1) if file is being copied directly while reading, or false (0) if file is a gzip stream being decompressed. This state can change from false to true while reading the input file if the end of a gzip stream is reached, but is followed by data that is not another gzip stream. If the input file is empty, gzdirect() will return true, since the input does not contain a gzip stream. If gzdirect() is used immediately after gzopen() or gzdopen() it will cause buffers to be allocated to allow reading the file to determine if it is a gzip file. Therefore if gzbuffer() is used, it should be called before gzdirect(). */ ZEXTERN int ZEXPORT gzclose OF((gzFile file)); /* Flushes all pending output if necessary, closes the compressed file and deallocates the (de)compression state. Note that once file is closed, you cannot call gzerror with file, since its structures have been deallocated. gzclose must not be called more than once on the same file, just as free must not be called more than once on the same allocation. gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a file operation error, or Z_OK on success. */ ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); /* Same as gzclose(), but gzclose_r() is only for use when reading, and gzclose_w() is only for use when writing or appending. The advantage to using these instead of gzclose() is that they avoid linking in zlib compression or decompression code that is not used when only reading or only writing respectively. If gzclose() is used, then both compression and decompression code will be included the application when linking to a static zlib library. */ ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); /* Returns the error message for the last error which occurred on the given compressed file. errnum is set to zlib error number. If an error occurred in the file system and not in the compression library, errnum is set to Z_ERRNO and the application may consult errno to get the exact error code. The application must not modify the returned string. Future calls to this function may invalidate the previously returned string. If file is closed, then the string previously returned by gzerror will no longer be available. gzerror() should be used to distinguish errors from end-of-file for those functions above that do not distinguish those cases in their return values. */ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); /* Clears the error and end-of-file flags for file. This is analogous to the clearerr() function in stdio. This is useful for continuing to read a gzip file that is being written concurrently. */ /* checksum functions */ /* These functions are not related to compression but are exported anyway because they might be useful in applications using the compression library. */ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and return the updated checksum. If buf is Z_NULL, this function returns the required initial value for the checksum. An Adler-32 checksum is almost as reliable as a CRC32 but can be computed much faster. Usage example: uLong adler = adler32(0L, Z_NULL, 0); while (read_buffer(buffer, length) != EOF) { adler = adler32(adler, buffer, length); } if (adler != original_adler) error(); */ /* ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, z_off_t len2)); Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. */ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); /* Update a running CRC-32 with the bytes buf[0..len-1] and return the updated CRC-32. If buf is Z_NULL, this function returns the required initial value for the for the crc. Pre- and post-conditioning (one's complement) is performed within this function so it shouldn't be done by the application. Usage example: uLong crc = crc32(0L, Z_NULL, 0); while (read_buffer(buffer, length) != EOF) { crc = crc32(crc, buffer, length); } if (crc != original_crc) error(); */ /* ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); Combine two CRC-32 check values into one. For two sequences of bytes, seq1 and seq2 with lengths len1 and len2, CRC-32 check values were calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and len2. */ /* various hacks, don't look :) */ /* deflateInit and inflateInit are macros to allow checking the zlib version * and the compiler's view of z_stream: */ ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, const char *version, int stream_size)); ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, const char *version, int stream_size)); ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy, const char *version, int stream_size)); ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, const char *version, int stream_size)); ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, unsigned char FAR *window, const char *version, int stream_size)); #define deflateInit(strm, level) \ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) #define inflateInit(strm) \ inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) #define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ (strategy), ZLIB_VERSION, sizeof(z_stream)) #define inflateInit2(strm, windowBits) \ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) #define inflateBackInit(strm, windowBits, window) \ inflateBackInit_((strm), (windowBits), (window), \ ZLIB_VERSION, sizeof(z_stream)) /* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if * both are true, the application gets the *64 functions, and the regular * functions are changed to 64 bits) -- in case these are set on systems * without large file support, _LFS64_LARGEFILE must also be true */ #if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); #endif #if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0 # define gzopen gzopen64 # define gzseek gzseek64 # define gztell gztell64 # define gzoffset gzoffset64 # define adler32_combine adler32_combine64 # define crc32_combine crc32_combine64 # ifdef _LARGEFILE64_SOURCE ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); # endif #else ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); #endif /* hack for buggy compilers */ #if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) struct internal_state {int dummy;}; #endif /* undocumented functions */ ZEXTERN const char * ZEXPORT zError OF((int)); ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); #ifdef __cplusplus } #endif #endif /* ZLIB_H */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/zlib/zutil.c0000644000175100001710000001620000000000000017627 0ustar00vstsdocker/* zutil.c -- target dependent utility functions for the compression library * Copyright (C) 1995-2005, 2010 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ #include "zutil.h" #ifndef NO_DUMMY_DECL struct internal_state {int dummy;}; /* for buggy compilers */ #endif const char * const z_errmsg[10] = { "need dictionary", /* Z_NEED_DICT 2 */ "stream end", /* Z_STREAM_END 1 */ "", /* Z_OK 0 */ "file error", /* Z_ERRNO (-1) */ "stream error", /* Z_STREAM_ERROR (-2) */ "data error", /* Z_DATA_ERROR (-3) */ "insufficient memory", /* Z_MEM_ERROR (-4) */ "buffer error", /* Z_BUF_ERROR (-5) */ "incompatible version",/* Z_VERSION_ERROR (-6) */ ""}; const char * ZEXPORT zlibVersion() { return ZLIB_VERSION; } uLong ZEXPORT zlibCompileFlags() { uLong flags; flags = 0; switch ((int)(sizeof(uInt))) { case 2: break; case 4: flags += 1; break; case 8: flags += 2; break; default: flags += 3; } switch ((int)(sizeof(uLong))) { case 2: break; case 4: flags += 1 << 2; break; case 8: flags += 2 << 2; break; default: flags += 3 << 2; } switch ((int)(sizeof(voidpf))) { case 2: break; case 4: flags += 1 << 4; break; case 8: flags += 2 << 4; break; default: flags += 3 << 4; } switch ((int)(sizeof(z_off_t))) { case 2: break; case 4: flags += 1 << 6; break; case 8: flags += 2 << 6; break; default: flags += 3 << 6; } #ifdef DEBUG flags += 1 << 8; #endif #if defined(ASMV) || defined(ASMINF) flags += 1 << 9; #endif #ifdef ZLIB_WINAPI flags += 1 << 10; #endif #ifdef BUILDFIXED flags += 1 << 12; #endif #ifdef DYNAMIC_CRC_TABLE flags += 1 << 13; #endif #ifdef NO_GZCOMPRESS flags += 1L << 16; #endif #ifdef NO_GZIP flags += 1L << 17; #endif #ifdef PKZIP_BUG_WORKAROUND flags += 1L << 20; #endif #ifdef FASTEST flags += 1L << 21; #endif #ifdef STDC # ifdef NO_vsnprintf flags += 1L << 25; # ifdef HAS_vsprintf_void flags += 1L << 26; # endif # else # ifdef HAS_vsnprintf_void flags += 1L << 26; # endif # endif #else flags += 1L << 24; # ifdef NO_snprintf flags += 1L << 25; # ifdef HAS_sprintf_void flags += 1L << 26; # endif # else # ifdef HAS_snprintf_void flags += 1L << 26; # endif # endif #endif return flags; } #ifdef DEBUG # ifndef verbose # define verbose 0 # endif int ZLIB_INTERNAL z_verbose = verbose; void ZLIB_INTERNAL z_error (m) char *m; { fprintf(stderr, "%s\n", m); exit(1); } #endif /* exported to allow conversion of error code to string for compress() and * uncompress() */ const char * ZEXPORT zError(err) int err; { return ERR_MSG(err); } #if defined(_WIN32_WCE) /* The Microsoft C Run-Time Library for Windows CE doesn't have * errno. We define it as a global variable to simplify porting. * Its value is always 0 and should not be used. */ int errno = 0; #endif #ifndef HAVE_MEMCPY void ZLIB_INTERNAL zmemcpy(dest, source, len) Bytef* dest; const Bytef* source; uInt len; { if (len == 0) return; do { *dest++ = *source++; /* ??? to be unrolled */ } while (--len != 0); } int ZLIB_INTERNAL zmemcmp(s1, s2, len) const Bytef* s1; const Bytef* s2; uInt len; { uInt j; for (j = 0; j < len; j++) { if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; } return 0; } void ZLIB_INTERNAL zmemzero(dest, len) Bytef* dest; uInt len; { if (len == 0) return; do { *dest++ = 0; /* ??? to be unrolled */ } while (--len != 0); } #endif #ifdef SYS16BIT #ifdef __TURBOC__ /* Turbo C in 16-bit mode */ # define MY_ZCALLOC /* Turbo C malloc() does not allow dynamic allocation of 64K bytes * and farmalloc(64K) returns a pointer with an offset of 8, so we * must fix the pointer. Warning: the pointer must be put back to its * original form in order to free it, use zcfree(). */ #define MAX_PTR 10 /* 10*64K = 640K */ local int next_ptr = 0; typedef struct ptr_table_s { voidpf org_ptr; voidpf new_ptr; } ptr_table; local ptr_table table[MAX_PTR]; /* This table is used to remember the original form of pointers * to large buffers (64K). Such pointers are normalized with a zero offset. * Since MSDOS is not a preemptive multitasking OS, this table is not * protected from concurrent access. This hack doesn't work anyway on * a protected system like OS/2. Use Microsoft C instead. */ voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) { voidpf buf = opaque; /* just to make some compilers happy */ ulg bsize = (ulg)items*size; /* If we allocate less than 65520 bytes, we assume that farmalloc * will return a usable pointer which doesn't have to be normalized. */ if (bsize < 65520L) { buf = farmalloc(bsize); if (*(ush*)&buf != 0) return buf; } else { buf = farmalloc(bsize + 16L); } if (buf == NULL || next_ptr >= MAX_PTR) return NULL; table[next_ptr].org_ptr = buf; /* Normalize the pointer to seg:0 */ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; *(ush*)&buf = 0; table[next_ptr++].new_ptr = buf; return buf; } void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) { int n; if (*(ush*)&ptr != 0) { /* object < 64K */ farfree(ptr); return; } /* Find the original pointer */ for (n = 0; n < next_ptr; n++) { if (ptr != table[n].new_ptr) continue; farfree(table[n].org_ptr); while (++n < next_ptr) { table[n-1] = table[n]; } next_ptr--; return; } ptr = opaque; /* just to make some compilers happy */ Assert(0, "zcfree: ptr not found"); } #endif /* __TURBOC__ */ #ifdef M_I86 /* Microsoft C in 16-bit mode */ # define MY_ZCALLOC #if (!defined(_MSC_VER) || (_MSC_VER <= 600)) # define _halloc halloc # define _hfree hfree #endif voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) { if (opaque) opaque = 0; /* to make compiler happy */ return _halloc((long)items, size); } void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) { if (opaque) opaque = 0; /* to make compiler happy */ _hfree(ptr); } #endif /* M_I86 */ #endif /* SYS16BIT */ #ifndef MY_ZCALLOC /* Any system without a special alloc function */ #ifndef STDC extern voidp malloc OF((uInt size)); extern voidp calloc OF((uInt items, uInt size)); extern void free OF((voidpf ptr)); #endif voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) voidpf opaque; unsigned items; unsigned size; { if (opaque) items += size - size; /* make compiler happy */ return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : (voidpf)calloc(items, size); } void ZLIB_INTERNAL zcfree (opaque, ptr) voidpf opaque; voidpf ptr; { free(ptr); if (opaque) return; /* make compiler happy */ } #endif /* MY_ZCALLOC */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/cfitsio/zlib/zutil.h0000644000175100001710000001574000000000000017644 0ustar00vstsdocker/* zutil.h -- internal interface and configuration of the compression library * Copyright (C) 1995-2010 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ #ifndef ZUTIL_H #define ZUTIL_H #if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ) # define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) #else # define ZLIB_INTERNAL #endif #include "zlib.h" #ifdef STDC # if !(defined(_WIN32_WCE) && defined(_MSC_VER)) # include # endif # include # include #endif #ifndef local # define local static #endif /* compile with -Dlocal if your debugger can't find static symbols */ typedef unsigned char uch; typedef uch FAR uchf; typedef unsigned short ush; typedef ush FAR ushf; typedef unsigned long ulg; extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* (size given to avoid silly warnings with Visual C++) */ #define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] #define ERR_RETURN(strm,err) \ return (strm->msg = (char*)ERR_MSG(err), (err)) /* To be used only when the state is known to be valid */ /* common constants */ #ifndef DEF_WBITS # define DEF_WBITS MAX_WBITS #endif /* default windowBits for decompression. MAX_WBITS is for compression only */ #if MAX_MEM_LEVEL >= 8 # define DEF_MEM_LEVEL 8 #else # define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif /* default memLevel */ #define STORED_BLOCK 0 #define STATIC_TREES 1 #define DYN_TREES 2 /* The three kinds of block type */ #define MIN_MATCH 3 #define MAX_MATCH 258 /* The minimum and maximum match lengths */ #define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ /* target dependencies */ #if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) # define OS_CODE 0x00 # if defined(__TURBOC__) || defined(__BORLANDC__) # if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) /* Allow compilation with ANSI keywords only enabled */ void _Cdecl farfree( void *block ); void *_Cdecl farmalloc( unsigned long nbytes ); # else # include # endif # else /* MSC or DJGPP */ # include # endif #endif #ifdef AMIGA # define OS_CODE 0x01 #endif #if defined(VAXC) || defined(VMS) # define OS_CODE 0x02 # define F_OPEN(name, mode) \ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") #endif #if defined(ATARI) || defined(atarist) # define OS_CODE 0x05 #endif #ifdef OS2 # define OS_CODE 0x06 # ifdef M_I86 # include # endif #endif #if defined(MACOS) || defined(TARGET_OS_MAC) # define OS_CODE 0x07 # if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os # include /* for fdopen */ # else # ifndef fdopen # define fdopen(fd,mode) NULL /* No fdopen() */ # endif # endif #endif #ifdef TOPS20 # define OS_CODE 0x0a #endif #ifdef WIN32 # ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ # define OS_CODE 0x0b # endif #endif #ifdef __50SERIES /* Prime/PRIMOS */ # define OS_CODE 0x0f #endif #if defined(_BEOS_) || defined(RISCOS) # define fdopen(fd,mode) NULL /* No fdopen() */ #endif #if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX # if defined(_WIN32_WCE) # define fdopen(fd,mode) NULL /* No fdopen() */ # ifndef _PTRDIFF_T_DEFINED typedef int ptrdiff_t; # define _PTRDIFF_T_DEFINED # endif # else # define fdopen(fd,type) _fdopen(fd,type) # endif #endif #if defined(__BORLANDC__) #pragma warn -8004 #pragma warn -8008 #pragma warn -8066 #endif /* provide prototypes for these when building zlib without LFS */ #if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); #endif /* common defaults */ #ifndef OS_CODE # define OS_CODE 0x03 /* assume Unix */ #endif #ifndef F_OPEN # define F_OPEN(name, mode) fopen((name), (mode)) #endif /* functions */ #if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) # ifndef HAVE_VSNPRINTF # define HAVE_VSNPRINTF # endif #endif #if defined(__CYGWIN__) # ifndef HAVE_VSNPRINTF # define HAVE_VSNPRINTF # endif #endif #ifndef HAVE_VSNPRINTF # ifdef MSDOS /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), but for now we just assume it doesn't. */ # define NO_vsnprintf # endif # ifdef __TURBOC__ # define NO_vsnprintf # endif # ifdef WIN32 /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ # if !defined(vsnprintf) && !defined(NO_vsnprintf) # if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) # define vsnprintf _vsnprintf # endif # endif # endif # ifdef __SASC # define NO_vsnprintf # endif #endif #ifdef VMS # define NO_vsnprintf #endif #if defined(pyr) # define NO_MEMCPY #endif #if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) /* Use our own functions for small and medium model with MSC <= 5.0. * You may have to use the same strategy for Borland C (untested). * The __SC__ check is for Symantec. */ # define NO_MEMCPY #endif #if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) # define HAVE_MEMCPY #endif #ifdef HAVE_MEMCPY # ifdef SMALL_MEDIUM /* MSDOS small or medium model */ # define zmemcpy _fmemcpy # define zmemcmp _fmemcmp # define zmemzero(dest, len) _fmemset(dest, 0, len) # else # define zmemcpy memcpy # define zmemcmp memcmp # define zmemzero(dest, len) memset(dest, 0, len) # endif #else void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); #endif /* Diagnostic functions */ #ifdef DEBUG # include extern int ZLIB_INTERNAL z_verbose; extern void ZLIB_INTERNAL z_error OF((char *m)); # define Assert(cond,msg) {if(!(cond)) z_error(msg);} # define Trace(x) {if (z_verbose>=0) fprintf x ;} # define Tracev(x) {if (z_verbose>0) fprintf x ;} # define Tracevv(x) {if (z_verbose>1) fprintf x ;} # define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} # define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} #else # define Assert(cond,msg) # define Trace(x) # define Tracev(x) # define Tracevv(x) # define Tracec(c,x) # define Tracecv(c,x) #endif voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, unsigned size)); void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); #define ZALLOC(strm, items, size) \ (*((strm)->zalloc))((strm)->opaque, (items), (size)) #define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) #define TRY_FREE(s, p) {if (p) ZFREE(s, p);} #endif /* ZUTIL_H */ ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2592597 astropy-5.0.2/cextern/expat/0000755000175100001710000000000000000000000015036 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/.gitignore0000644000175100001710000000073700000000000017035 0ustar00vstsdocker/autom4te.cache/ m4/ CMakeFiles/ Testing/ aclocal.m4 CMakeCache.txt cmake_install.cmake CTestTestfile.cmake install_manifest.txt Makefile .deps Makefile.in .libs *.la configure config.cache config.log config.status expat_config.h.in expat_config.h libtool expat.ncb expat.opt .project expat.pc *.gcda *.gcno *.gcov *.nccout *.expand /callgraph.svg /libexpat.so.* /run.sh build__R* coverage__R* source__R* /expat-*.tar.bz2 /expat-*.tar.bz2.asc /stamp-h1 /libexpat*.dll /changelog ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/AUTHORS0000644000175100001710000000021600000000000016105 0ustar00vstsdockerExpat is brought to you by: Clark Cooper Fred L. Drake, Jr. Greg Stein James Clark Karl Waclawek Rhodri James Sebastian Pipping Steven Solie ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/COPYING0000644000175100001710000000217000000000000016071 0ustar00vstsdockerCopyright (c) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper Copyright (c) 2001-2017 Expat maintainers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/Changes0000644000175100001710000011325300000000000016336 0ustar00vstsdockerNOTE: We are looking for help with a few things: https://github.com/libexpat/libexpat/labels/help%20wanted If you can help, please get in touch. Thanks! Release 2.2.9 Wed Septemper 25 2019 Other changes: examples: Drop executable bits from elements.c #349 Windows: Change the name of the Windows DLLs from expat*.dll to libexpat*.dll once more (regression from 2.2.8, first fixed in 1.95.3, issue #61 on SourceForge today, was issue #432456 back then); needs a fix due case-insensitive file systems on Windows and the fact that Perl's XML::Parser::Expat compiles into Expat.dll. #347 Windows: Only define _CRT_RAND_S if not defined Version info bumped from 7:10:6 to 7:11:6 Special thanks to: Ben Wagner Release 2.2.8 Fri Septemper 13 2019 Security fixes: #317 #318 CVE-2019-15903 -- Fix heap overflow triggered by XML_GetCurrentLineNumber (or XML_GetCurrentColumnNumber), and deny internal entities closing the doctype; fixed in commit c20b758c332d9a13afbbb276d30db1d183a85d43 Bug fixes: #240 Fix cases where XML_StopParser did not have any effect when called from inside of an end element handler #341 xmlwf: Fix exit code for operation without "-d DIRECTORY"; previously, only "-d DIRECTORY" would give you a proper exit code: # xmlwf -d . <<<'' 2>/dev/null ; echo $? 2 # xmlwf <<<'' 2>/dev/null ; echo $? 0 Now both cases return exit code 2. Other changes: #299 #302 Windows: Replace LoadLibrary hack to access unofficial API function SystemFunction036 (RtlGenRandom) by using official API function rand_s (needs WinXP+) #325 Windows: Drop support for Visual Studio <=7.1/2003 and document supported compilers in README.md #286 Windows: Remove COM code from xmlwf; in case it turns out needed later, there will be a dedicated repository below https://github.com/libexpat/ for that code #322 Windows: Remove explicit MSVC solution and project files. You can generate Visual Studio solution files through CMake, e.g.: cmake -G"Visual Studio 15 2017" . #338 xmlwf: Make "xmlwf -h" help output more friendly #339 examples: Improve elements.c #244 #264 Autotools: Add argument --enable-xml-attr-info #239 #301 Autotools: Add arguments --with-getrandom --without-getrandom --with-sys-getrandom --without-sys-getrandom #312 #343 Autotools: Fix linking issues with "./configure LD=clang" Autotools: Fix "make run-xmltest" for out-of-source builds #329 #336 CMake: Pull all options from Expat <=2.2.7 into namespace prefix EXPAT_ with the exception of DOCBOOK_TO_MAN: - BUILD_doc -> EXPAT_BUILD_DOCS (plural) - BUILD_examples -> EXPAT_BUILD_EXAMPLES - BUILD_shared -> EXPAT_SHARED_LIBS - BUILD_tests -> EXPAT_BUILD_TESTS - BUILD_tools -> EXPAT_BUILD_TOOLS - DOCBOOK_TO_MAN -> DOCBOOK_TO_MAN (unchanged) - INSTALL -> EXPAT_ENABLE_INSTALL - MSVC_USE_STATIC_CRT -> EXPAT_MSVC_STATIC_CRT - USE_libbsd -> EXPAT_WITH_LIBBSD - WARNINGS_AS_ERRORS -> EXPAT_WARNINGS_AS_ERRORS - XML_CONTEXT_BYTES -> EXPAT_CONTEXT_BYTES - XML_DEV_URANDOM -> EXPAT_DEV_URANDOM - XML_DTD -> EXPAT_DTD - XML_NS -> EXPAT_NS - XML_UNICODE -> EXPAT_CHAR_TYPE=ushort (!) - XML_UNICODE_WCHAR_T -> EXPAT_CHAR_TYPE=wchar_t (!) #244 #264 CMake: Add argument -DEXPAT_ATTR_INFO=(ON|OFF), default OFF #326 CMake: Add argument -DEXPAT_LARGE_SIZE=(ON|OFF), default OFF #328 CMake: Add argument -DEXPAT_MIN_SIZE=(ON|OFF), default OFF #239 #277 CMake: Add arguments -DEXPAT_WITH_GETRANDOM=(ON|OFF|AUTO), default AUTO -DEXPAT_WITH_SYS_GETRANDOM=(ON|OFF|AUTO), default AUTO #326 CMake: Install expat_config.h to include directory #326 CMake: Generate and install configuration files for future find_package(expat [..] CONFIG [..]) CMake: Now produces a summary of applied configuration CMake: Require C++ compiler only when tests are enabled #330 CMake: Fix compilation for 16bit character types, i.e. ex -DXML_UNICODE=ON (and ex -DXML_UNICODE_WCHAR_T=ON) #265 CMake: Fix linking with MinGW #330 CMake: Add full support for MinGW; to enable, use -DCMAKE_TOOLCHAIN_FILE=[expat]/cmake/mingw-toolchain.cmake #330 CMake: Port "make run-xmltest" from GNU Autotools to CMake #316 CMake: Windows: Make binary postfix match MSVC Old: expat[d].lib New: expat[w][d][MD|MT].lib CMake: Migrate files from Windows to Unix line endings #308 CMake: Integrate OSS-Fuzz fuzzers, option -DEXPAT_BUILD_FUZZERS=(ON|OFF), default OFF #14 Drop an OpenVMS support leftover #235 #268 .. #270 #310 .. #313 #331 #333 Address compiler warnings #282 #283 .. #284 #285 Address cppcheck warnings #294 #295 Address Clang Static Analyzer warnings #24 #293 Mass-apply clang-format 9 (and ensure conformance during CI) Version info bumped from 7:9:6 to 7:10:6 Special thanks to: David Loffredo Joonun Jang Khajapasha Mohammed Kishore Kunche Marco Maggi Mitch Phillips Rolf Ade xantares Zhongyuan Zhou Release 2.2.7 Wed June 19 2019 Security fixes: #186 #262 CVE-2018-20843 -- Fix extraction of namespace prefixes from XML names; XML names with multiple colons could end up in the wrong namespace, and take a high amount of RAM and CPU resources while processing, opening the door to use for denial-of-service attacks Other changes: #195 #197 Autotools/CMake: Utilize -fvisibility=hidden to stop exporting non-API symbols #227 Autotools: Add --without-examples and --without-tests #228 Autotools: Modernize configure.ac #245 #246 Autotools: Fix check for -fvisibility=hidden for Clang #247 #248 Autotools: Fix compilation for lack of docbook2x-man #236 #258 Autotools: Produce .tar.{gz,lz,xz} release archives #212 CMake: Make libdir of pkgconfig expat.pc support multilib #158 #263 CMake: Build man page in PROJECT_BINARY_DIR not _SOURCE_DIR #219 Remove fallback to bcopy, assume that memmove(3) exists #257 Use portable "/usr/bin/env bash" shebang (e.g. for OpenBSD) #243 Windows: Fix syntax of .def module definition files Version info bumped from 7:8:6 to 7:9:6 Special thanks to: Benjamin Peterson CaolÃĄn McNamara Hanno BÃļck KangLin Kishore Kunche Marco Maggi Rhodri James Sebastian DrÃļge userwithuid Yury Gribov Release 2.2.6 Sun August 12 2018 Bug fixes: #170 #206 Avoid doing arithmetic with NULL pointers in XML_GetBuffer #204 #205 Fix 2.2.5 regression with suspend-resume while parsing a document like '' Other changes: #165 #168 Autotools: Fix docbook-related configure syntax error #166 Autotools: Avoid grep option `-q` for Solaris #167 Autotools: Support ./configure DOCBOOK_TO_MAN="xmlto man --skip-validation" #159 #167 Autotools: Support DOCBOOK_TO_MAN command which produces xmlwf.1 rather than XMLWF.1; also covers case insensitive file systems #181 Autotools: Drop -rpath option passed to libtool #188 Autotools: Detect and deny SGML docbook2man as ours is XML #188 Autotools/CMake: Support command db2x_docbook2man as well #174 CMake: Introduce option WARNINGS_AS_ERRORS, defaults to OFF #184 #185 CMake: Introduce option MSVC_USE_STATIC_CRT, defaults to OFF #207 #208 CMake: Introduce option XML_UNICODE and XML_UNICODE_WCHAR_T, both defaulting to OFF #175 CMake: Prefer check_symbol_exists over check_function_exists #176 CMake: Create the same pkg-config file as with GNU Autotools #178 #179 CMake: Use GNUInstallDirs module to set proper defaults for install directories #208 CMake: Utilize expat_config.h.cmake for XML_DEV_URANDOM #180 Windows: Fix compilation of test suite for Visual Studio 2008 #131 #173 #202 Address compiler warnings #187 #190 #200 Fix miscellaneous typos Version info bumped from 7:7:6 to 7:8:6 Special thanks to: Anton Maklakov Benjamin Peterson Brad King Franek Korta Frank Rast Joe Orton luzpaz Pedro Vicente Rainer Jung Rhodri James Rolf Ade Rolf Eike Beer Thomas Beutlich Tomasz Kłoczko Release 2.2.5 Tue October 31 2017 Bug fixes: #8 If the parser runs out of memory, make sure its internal state reflects the memory it actually has, not the memory it wanted to have. #11 The default handler wasn't being called when it should for a SYSTEM or PUBLIC doctype if an entity declaration handler was registered. #137 #138 Fix a case of mistakenly reported parsing success where XML_StopParser was called from an element handler #162 Function XML_ErrorString was returning NULL rather than a message for code XML_ERROR_INVALID_ARGUMENT introduced with release 2.2.1 Other changes: #106 xmlwf: Add argument -N adding notation declarations #75 #106 Test suite: Resolve expected failure cases where xmlwf output was incomplete #127 Windows: Fix test suite compilation #126 #127 Windows: Fix compilation for Visual Studio 2012 Windows: Upgrade shipped project files to Visual Studio 2017 #33 #132 tests: Mass-fix compilation for XML_UNICODE_WCHAR_T #129 examples: Fix compilation for XML_UNICODE_WCHAR_T #130 benchmark: Fix compilation for XML_UNICODE_WCHAR_T #144 xmlwf: Fix compilation for XML_UNICODE_WCHAR_T; still needs Windows or MinGW for 2-byte wchar_t #9 Address two Clang Static Analyzer false positives #59 Resolve troublesome macros hiding parser struct membership and dereferencing that pointer #6 Resolve superfluous internal malloc/realloc switch #153 #155 Improve docbook2x-man detection #160 Undefine NDEBUG in the test suite (rather than rejecting it) #161 Address compiler warnings Version info bumped from 7:6:6 to 7:7:6 Special thanks to: Benbuck Nason Hans Wennborg JosÊ GutiÊrrez de la Concha Pedro Monreal Gonzalez Rhodri James Rolf Ade Stephen Groat and Core Infrastructure Initiative Release 2.2.4 Sat August 19 2017 Bug fixes: #115 Fix copying of partial characters for UTF-8 input Other changes: #109 Fix "make check" for non-x86 architectures that default to unsigned type char (-128..127 rather than 0..255) #109 coverage.sh: Cover -funsigned-char Autotools: Introduce --without-xmlwf argument #65 Autotools: Replace handwritten Makefile with GNU Automake #43 CMake: Auto-detect high quality entropy extractors, add new option USE_libbsd=ON to use arc4random_buf of libbsd #74 CMake: Add -fno-strict-aliasing only where supported #114 CMake: Always honor manually set BUILD_* options #114 CMake: Compile man page if docbook2x-man is available, only #117 Include file tests/xmltest.log.expected in source tarball (required for "make run-xmltest") #117 Include (existing) Visual Studio 2013 files in source tarball Improve test suite error output #111 Fix some typos in documentation Version info bumped from 7:5:6 to 7:6:6 Special thanks to: Jakub Wilk Joe Orton Lin Tian Rolf Eike Beer Release 2.2.3 Wed August 2 2017 Security fixes: #82 CVE-2017-11742 -- Windows: Fix DLL hijacking vulnerability using Steve Holme's LoadLibrary wrapper for/of cURL Bug fixes: #85 Fix a dangling pointer issue related to realloc Other changes: Increase code coverage #91 Linux: Allow getrandom to fail if nonblocking pool has not yet been initialized and read /dev/urandom then, instead. This is in line with what recent Python does. #81 Pre-10.7/Lion macOS: Support entropy from arc4random #86 Check that a UTF-16 encoding in an XML declaration has the right endianness #4 #5 #7 Recover correctly when some reallocations fail Repair "./configure && make" for systems without any provider of high quality entropy and try reading /dev/urandom on those Ensure that user-defined character encodings have converter functions when they are needed Fix mis-leading description of argument -c in xmlwf.1 Rely on macro HAVE_ARC4RANDOM_BUF (rather than __CloudABI__) for CloudABI #100 Fix use of SIPHASH_MAIN in siphash.h #23 Test suite: Fix memory leaks Version info bumped from 7:4:6 to 7:5:6 Special thanks to: Chanho Park Joe Orton Pascal Cuoq Rhodri James Simon McVittie Vadim Zeitlin Viktor Szakats and Core Infrastructure Initiative Release 2.2.2 Wed July 12 2017 Security fixes: #43 Protect against compilation without any source of high quality entropy enabled, e.g. with CMake build system; commit ff0207e6076e9828e536b8d9cd45c9c92069b895 #60 Windows with _UNICODE: Unintended use of LoadLibraryW with a non-wide string resulted in failure to load advapi32.dll and degradation in quality of used entropy when compiled with _UNICODE for Windows; you can launch existing binaries with EXPAT_ENTROPY_DEBUG=1 in the environment to inspect the quality of entropy used during runtime; commits * 95b95032f907ef1cd17ee7a9a1768010a825d61d * 73a5a2e9c081f49f2d775cf7ced864158b68dc80 [MOX-006] Fix non-NULL parser parameter validation in XML_Parse; resulted in NULL dereference, previously; commit ac256dafdffc9622ab0dc2c62fcecb0dfcfa71fe Bug fixes: #69 Fix improper use of unsigned long long integer literals Other changes: #73 Start requiring a C99 compiler #49 Fix "==" Bashism in configure script #50 Fix too eager getrandom detection for Debian GNU/kFreeBSD #52 and macOS #51 Address lack of stdint.h in Visual Studio 2003 to 2008 #58 Address compile warnings #68 Fix "./buildconf.sh && ./configure" for some versions of Dash for /bin/sh #72 CMake: Ease use of Expat in context of a parent project with multiple CMakeLists.txt files #72 CMake: Resolve mistaken executable permissions #76 Address compile warning with -DNDEBUG (not recommended!) #77 Address compile warning about macro redefinition Special thanks to: Alexander Bluhm Ben Boeckel Cătălin Răceanu Kerin Millar LÃĄszlÃŗ BÃļszÃļrmÊnyi S. P. Zeidler Segev Finer VÃĄclav Slavík Victor Stinner Viktor Szakats and Radically Open Security Release 2.2.1 Sat June 17 2017 Security fixes: CVE-2017-9233 -- External entity infinite loop DoS Details: https://libexpat.github.io/doc/cve-2017-9233/ Commit c4bf96bb51dd2a1b0e185374362ee136fe2c9d7f [MOX-002] CVE-2016-9063 -- Detect integer overflow; commit d4f735b88d9932bd5039df2335eefdd0723dbe20 (Fixed version of existing downstream patches!) (SF.net) #539 Fix regression from fix to CVE-2016-0718 cutting off longer tag names; commits * 896b6c1fd3b842f377d1b62135dccf0a579cf65d * af507cef2c93cb8d40062a0abe43a4f4e9158fb2 #16 * 0dbbf43fdb20f593ddf4fa1ff67288000dd4a7fd #25 More integer overflow detection (function poolGrow); commits * 810b74e4703dcfdd8f404e3cb177d44684775143 * 44178553f3539ce69d34abee77a05e879a7982ac [MOX-002] Detect overflow from len=INT_MAX call to XML_Parse; commits * 4be2cb5afcc018d996f34bbbce6374b7befad47f * 7e5b71b748491b6e459e5c9a1d090820f94544d8 [MOX-005] #30 Use high quality entropy for hash initialization: * arc4random_buf on BSD, systems with libbsd (when configured with --with-libbsd), CloudABI * RtlGenRandom on Windows XP / Server 2003 and later * getrandom on Linux 3.17+ In a way, that's still part of CVE-2016-5300. https://github.com/libexpat/libexpat/pull/30/commits [MOX-005] For the low quality entropy extraction fallback code, the parser instance address can no longer leak, commit 04ad658bd3079dd15cb60fc67087900f0ff4b083 [MOX-003] Prevent use of uninitialised variable; commit [MOX-004] a4dc944f37b664a3ca7199c624a98ee37babdb4b Add missing parameter validation to public API functions and dedicated error code XML_ERROR_INVALID_ARGUMENT: [MOX-006] * NULL checks; commits * d37f74b2b7149a3a95a680c4c4cd2a451a51d60a (merge/many) * 9ed727064b675b7180c98cb3d4f75efba6966681 * 6a747c837c50114dfa413994e07c0ba477be4534 * Negative length (XML_Parse); commit [MOX-002] 70db8d2538a10f4c022655d6895e4c3e78692e7f [MOX-001] #35 Change hash algorithm to William Ahern's version of SipHash to go further with fixing CVE-2012-0876. https://github.com/libexpat/libexpat/pull/39/commits Bug fixes: #32 Fix sharing of hash salt across parsers; relevant where XML_ExternalEntityParserCreate is called prior to XML_Parse, in particular (e.g. FBReader) #28 xmlwf: Auto-disable use of memory-mapping (and parsing as a single chunk) for files larger than ~1 GB (2^30 bytes) rather than failing with error "out of memory" #3 Fix double free after malloc failure in DTD code; commit 7ae9c3d3af433cd4defe95234eae7dc8ed15637f #17 Fix memory leak on parser error for unbound XML attribute prefix with new namespaces defined in the same tag; found by Google's OSS-Fuzz; commits * 16f87daae5a16132e479e4f71862128c7a915c73 * b47dbc9745932c160893d433220e462bd605f8cd xmlwf on Windows: Add missing calls to CloseHandle New features: #30 Introduced environment switch EXPAT_ENTROPY_DEBUG=1 for runtime debugging of entropy extraction Other changes: Increase code coverage #33 Reject use of XML_UNICODE_WCHAR_T with sizeof(wchar_t) != 2; XML_UNICODE_WCHAR_T was never meant to be used outside of Windows; 4-byte wchar_t is common on Linux (SF.net) #538 Start using -fno-strict-aliasing (SF.net) #540 Support compilation against cloudlibc of CloudABI Allow MinGW cross-compilation (SF.net) #534 CMake: Introduce option "BUILD_doc" (enabled by default) to bypass compilation of the xmlwf.1 man page (SF.net) pr2 CMake: Introduce option "INSTALL" (enabled by default) to bypass installation of expat files CMake: Fix ninja support Autotools: Add parameters --enable-xml-context [COUNT] and --disable-xml-context; default of context of 1024 bytes enabled unchanged #14 Drop AmigaOS 4.x code and includes #14 Drop ancient build systems: * Borland C++ Builder * OpenVMS * Open Watcom * Visual Studio 6.0 * Pre-X Mac OS (MPW Makefile) If you happen to rely on some of these, please get in touch for joining with maintenance. #10 Move from WIN32 to _WIN32 #13 Fix "make run-xmltest" order instability Address compile warnings Bump version info from 7:2:6 to 7:3:6 Add AUTHORS file Infrastructure: #1 Migrate from SourceForge to GitHub (except downloads): https://github.com/libexpat/ #1 Re-create http://libexpat.org/ project website Start utilizing Travis CI Special thanks to: Andy Wang Don Lewis Ed Schouten Karl Waclawek Pascal Cuoq Rhodri James Sergei Nikulov Tobias Taschner Viktor Szakats and Core Infrastructure Initiative Mozilla Foundation (MOSS Track 3: Secure Open Source) Radically Open Security Release 2.2.0 Tue June 21 2016 Security fixes: #537 CVE-2016-0718 -- Fix crash on malformed input CVE-2016-4472 -- Improve insufficient fix to CVE-2015-1283 / CVE-2015-2716 introduced with Expat 2.1.1 #499 CVE-2016-5300 -- Use more entropy for hash initialization than the original fix to CVE-2012-0876 #519 CVE-2012-6702 -- Resolve troublesome internal call to srand that was introduced with Expat 2.1.0 when addressing CVE-2012-0876 (issue #496) Bug fixes: Fix uninitialized reads of size 1 (e.g. in little2_updatePosition) Fix detection of UTF-8 character boundaries Other changes: #532 Fix compilation for Visual Studio 2010 (keyword "C99") Autotools: Resolve use of "$<" to better support bmake Autotools: Add QA script "qa.sh" (and make target "qa") Autotools: Respect CXXFLAGS if given Autotools: Fix "make run-xmltest" Autotools: Have "make run-xmltest" check for expected output p90 CMake: Fix static build (BUILD_shared=OFF) on Windows #536 CMake: Add soversion, support -DNO_SONAME=yes to bypass #323 CMake: Add suffix "d" to differentiate debug from release CMake: Define WIN32 with CMake on Windows Annotate memory allocators for GCC Address all currently known compile warnings Make sure that API symbols remain visible despite -fvisibility=hidden Remove executable flag from source files Resolve COMPILED_FROM_DSP in favor of WIN32 Special thanks to: BjÃļrn Lindahl Christian Heimes Cristian Rodríguez Daniel KrÃŧgler Gustavo Grieco Karl Waclawek LÃĄszlÃŗ BÃļszÃļrmÊnyi Marco Grassi Pascal Cuoq Sergei Nikulov Thomas Beutlich Warren Young Yann Droneaud Release 2.1.1 Sat March 12 2016 Security fixes: #582: CVE-2015-1283 - Multiple integer overflows in XML_GetBuffer Bug fixes: #502: Fix potential null pointer dereference #520: Symbol XML_SetHashSalt was not exported Output of "xmlwf -h" was incomplete Other changes: #503: Document behavior of calling XML_SetHashSalt with salt 0 Minor improvements to man page xmlwf(1) Improvements to the experimental CMake build system libtool now invoked with --verbose Release 2.1.0 Sat March 24 2012 - Security fixes: #2958794: CVE-2012-1148 - Memory leak in poolGrow. #2895533: CVE-2012-1147 - Resource leak in readfilemap.c. #3496608: CVE-2012-0876 - Hash DOS attack. #2894085: CVE-2009-3560 - Buffer over-read and crash in big2_toUtf8(). #1990430: CVE-2009-3720 - Parser crash with special UTF-8 sequences. - Bug Fixes: #1742315: Harmful XML_ParserCreateNS suggestion. #1785430: Expat build fails on linux-amd64 with gcc version>=4.1 -O3. #1983953, 2517952, 2517962, 2649838: Build modifications using autoreconf instead of buildconf.sh. #2815947, #2884086: OBJEXT and EXEEXT support while building. #2517938: xmlwf should return non-zero exit status if not well-formed. #2517946: Wrong statement about XMLDecl in xmlwf.1 and xmlwf.sgml. #2855609: Dangling positionPtr after error. #2990652: CMake support. #3010819: UNEXPECTED_STATE with a trailing "%" in entity value. #3206497: Uninitialized memory returned from XML_Parse. #3287849: make check fails on mingw-w64. - Patches: #1749198: pkg-config support. #3010222: Fix for bug #3010819. #3312568: CMake support. #3446384: Report byte offsets for attr names and values. - New Features / API changes: Added new API member XML_SetHashSalt() that allows setting an initial value (salt) for hash calculations. This is part of the fix for bug #3496608 to randomize hash parameters. When compiled with XML_ATTR_INFO defined, adds new API member XML_GetAttributeInfo() that allows retrieving the byte offsets for attribute names and values (patch #3446384). Added CMake build system. See bug #2990652 and patch #3312568. Added run-benchmark target to Makefile.in - relies on testdata module present in the same relative location as in the repository. Release 2.0.1 Tue June 5 2007 - Fixed bugs #1515266, #1515600: The character data handler's calling of XML_StopParser() was not handled properly; if the parser was stopped and the handler set to NULL, the parser would segfault. - Fixed bug #1690883: Expat failed on EBCDIC systems as it assumed some character constants to be ASCII encoded. - Minor cleanups of the test harness. - Fixed xmlwf bug #1513566: "out of memory" error on file size zero. - Fixed outline.c bug #1543233: missing a final XML_ParserFree() call. - Fixes and improvements for Windows platform: bugs #1409451, #1476160, #1548182, #1602769, #1717322. - Build fixes for various platforms: HP-UX, Tru64, Solaris 9: patch #1437840, bug #1196180. All Unix: #1554618 (refreshed config.sub/config.guess). #1490371, #1613457: support both, DESTDIR and INSTALL_ROOT, without relying on GNU-Make specific features. #1647805: Patched configure.in to work better with Intel compiler. - Fixes to Makefile.in to have make check work correctly: bugs #1408143, #1535603, #1536684. - Added Open Watcom support: patch #1523242. Release 2.0.0 Wed Jan 11 2006 - We no longer use the "check" library for C unit testing; we always use the (partial) internal implementation of the API. - Report XML_NS setting via XML_GetFeatureList(). - Fixed headers for use from C++. - XML_GetCurrentLineNumber() and XML_GetCurrentColumnNumber() now return unsigned integers. - Added XML_LARGE_SIZE switch to enable 64-bit integers for byte indexes and line/column numbers. - Updated to use libtool 1.5.22 (the most recent). - Added support for AmigaOS. - Some mostly minor bug fixes. SF issues include: #1006708, #1021776, #1023646, #1114960, #1156398, #1221160, #1271642. Release 1.95.8 Fri Jul 23 2004 - Major new feature: suspend/resume. Handlers can now request that a parse be suspended for later resumption or aborted altogether. See "Temporarily Stopping Parsing" in the documentation for more details. - Some mostly minor bug fixes, but compilation should no longer generate warnings on most platforms. SF issues include: #827319, #840173, #846309, #888329, #896188, #923913, #928113, #961698, #985192. Release 1.95.7 Mon Oct 20 2003 - Fixed enum XML_Status issue (reported on SourceForge many times), so compilers that are properly picky will be happy. - Introduced an XMLCALL macro to control the calling convention used by the Expat API; this macro should be used to annotate prototypes and definitions of callback implementations in code compiled with a calling convention other than the default convention for the host platform. - Improved ability to build without the configure-generated expat_config.h header. This is useful for applications which embed Expat rather than linking in the library. - Fixed a variety of bugs: see SF issues #458907, #609603, #676844, #679754, #692878, #692964, #695401, #699323, #699487, #820946. - Improved hash table lookups. - Added more regression tests and improved documentation. Release 1.95.6 Tue Jan 28 2003 - Added XML_FreeContentModel(). - Added XML_MemMalloc(), XML_MemRealloc(), XML_MemFree(). - Fixed a variety of bugs: see SF issues #615606, #616863, #618199, #653180, #673791. - Enhanced the regression test suite. - Man page improvements: includes SF issue #632146. Release 1.95.5 Fri Sep 6 2002 - Added XML_UseForeignDTD() for improved SAX2 support. - Added XML_GetFeatureList(). - Defined XML_Bool type and the values XML_TRUE and XML_FALSE. - Use an incomplete struct instead of a void* for the parser (may not retain). - Fixed UTF-8 decoding bug that caused legal UTF-8 to be rejected. - Finally fixed bug where default handler would report DTD events that were already handled by another handler. Initial patch contributed by Darryl Miles. - Removed unnecessary DllMain() function that caused static linking into a DLL to be difficult. - Added VC++ projects for building static libraries. - Reduced line-length for all source code and headers to be no longer than 80 characters, to help with AS/400 support. - Reduced memory copying during parsing (SF patch #600964). - Fixed a variety of bugs: see SF issues #580793, #434664, #483514, #580503, #581069, #584041, #584183, #584832, #585537, #596555, #596678, #598352, #598944, #599715, #600479, #600971. Release 1.95.4 Fri Jul 12 2002 - Added support for VMS, contributed by Craig Berry. See vms/README.vms for more information. - Added Mac OS (classic) support, with a makefile for MPW, contributed by Thomas Wegner and Daryle Walker. - Added Borland C++ Builder 5 / BCC 5.5 support, contributed by Patrick McConnell (SF patch #538032). - Fixed a variety of bugs: see SF issues #441449, #563184, #564342, #566334, #566901, #569461, #570263, #575168, #579196. - Made skippedEntityHandler conform to SAX2 (see source comment) - Re-implemented WFC: Entity Declared from XML 1.0 spec and added a new error "entity declared in parameter entity": see SF bug report #569461 and SF patch #578161 - Re-implemented section 5.1 from XML 1.0 spec: see SF bug report #570263 and SF patch #578161 Release 1.95.3 Mon Jun 3 2002 - Added a project to the MSVC workspace to create a wchar_t version of the library; the DLLs are named libexpatw.dll. - Changed the name of the Windows DLLs from expat.dll to libexpat.dll; this fixes SF bug #432456. - Added the XML_ParserReset() API function. - Fixed XML_SetReturnNSTriplet() to work for element names. - Made the XML_UNICODE builds usable (thanks, Karl!). - Allow xmlwf to read from standard input. - Install a man page for xmlwf on Unix systems. - Fixed many bugs; see SF bug reports #231864, #461380, #464837, #466885, #469226, #477667, #484419, #487840, #494749, #496505, #547350. Other bugs which we can't test as easily may also have been fixed, especially in the area of build support. Release 1.95.2 Fri Jul 27 2001 - More changes to make MSVC happy with the build; add a single workspace to support both the library and xmlwf application. - Added a Windows installer for Windows users; includes xmlwf.exe. - Added compile-time constants that can be used to determine the Expat version - Removed a lot of GNU-specific dependencies to aide portability among the various Unix flavors. - Fix the UTF-8 BOM bug. - Cleaned up warning messages for several compilers. - Added the -Wall, -Wstrict-prototypes options for GCC. Release 1.95.1 Sun Oct 22 15:11:36 EDT 2000 - Changes to get expat to build under Microsoft compiler - Removed all aborts and instead return an UNEXPECTED_STATE error. - Fixed a bug where a stray '%' in an entity value would cause an abort. - Defined XML_SetEndNamespaceDeclHandler. Thanks to Darryl Miles for finding this oversight. - Changed default patterns in lib/Makefile.in to fit non-GNU makes Thanks to robin@unrated.net for reporting and providing an account to test on. - The reference had the wrong label for XML_SetStartNamespaceDecl. Reported by an anonymous user. Release 1.95.0 Fri Sep 29 2000 - XML_ParserCreate_MM Allows you to set a memory management suite to replace the standard malloc,realloc, and free. - XML_SetReturnNSTriplet If you turn this feature on when namespace processing is in effect, then qualified, prefixed element and attribute names are returned as "uri|name|prefix" where '|' is whatever separator character is used in namespace processing. - Merged in features from perl-expat o XML_SetElementDeclHandler o XML_SetAttlistDeclHandler o XML_SetXmlDeclHandler o XML_SetEntityDeclHandler o StartDoctypeDeclHandler takes 3 additional parameters: sysid, pubid, has_internal_subset o Many paired handler setters (like XML_SetElementHandler) now have corresponding individual handler setters o XML_GetInputContext for getting the input context of the current parse position. - Added reference material - Packaged into a distribution that builds a sharable library ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/README.md0000644000175100001710000001516100000000000016321 0ustar00vstsdocker[![Travis CI Build Status](https://travis-ci.org/libexpat/libexpat.svg?branch=master)](https://travis-ci.org/libexpat/libexpat) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/libexpat/libexpat?svg=true)](https://ci.appveyor.com/project/libexpat/libexpat) [![Packaging status](https://repology.org/badge/tiny-repos/expat.svg)](https://repology.org/metapackage/expat/versions) # Expat, Release 2.2.9 This is Expat, a C library for parsing XML, started by [James Clark](https://en.wikipedia.org/wiki/James_Clark_(programmer)) in 1997. Expat is a stream-oriented XML parser. This means that you register handlers with the parser before starting the parse. These handlers are called when the parser discovers the associated structures in the document being parsed. A start tag is an example of the kind of structures for which you may register handlers. Expat supports the following compilers: - GNU GCC >=4.5 - LLVM Clang >=3.5 - Microsoft Visual Studio >=8.0/2005 Windows users should use the [`expat_win32` package](https://sourceforge.io/projects/expat/files/expat_win32/), which includes both precompiled libraries and executables, and source code for developers. Expat is [free software](https://www.gnu.org/philosophy/free-sw.en.html). You may copy, distribute, and modify it under the terms of the License contained in the file [`COPYING`](https://github.com/libexpat/libexpat/blob/master/expat/COPYING) distributed with this package. This license is the same as the MIT/X Consortium license. If you are building Expat from a check-out from the [Git repository](https://github.com/libexpat/libexpat/), you need to run a script that generates the configure script using the GNU autoconf and libtool tools. To do this, you need to have autoconf 2.58 or newer. Run the script like this: ```console ./buildconf.sh ``` Once this has been done, follow the same instructions as for building from a source distribution. To build Expat from a source distribution, you first run the configuration shell script in the top level distribution directory: ```console ./configure ``` There are many options which you may provide to configure (which you can discover by running configure with the `--help` option). But the one of most interest is the one that sets the installation directory. By default, the configure script will set things up to install libexpat into `/usr/local/lib`, `expat.h` into `/usr/local/include`, and `xmlwf` into `/usr/local/bin`. If, for example, you'd prefer to install into `/home/me/mystuff/lib`, `/home/me/mystuff/include`, and `/home/me/mystuff/bin`, you can tell `configure` about that with: ```console ./configure --prefix=/home/me/mystuff ``` Another interesting option is to enable 64-bit integer support for line and column numbers and the over-all byte index: ```console ./configure CPPFLAGS=-DXML_LARGE_SIZE ``` However, such a modification would be a breaking change to the ABI and is therefore not recommended for general use — e.g. as part of a Linux distribution — but rather for builds with special requirements. After running the configure script, the `make` command will build things and `make install` will install things into their proper location. Have a look at the `Makefile` to learn about additional `make` options. Note that you need to have write permission into the directories into which things will be installed. If you are interested in building Expat to provide document information in UTF-16 encoding rather than the default UTF-8, follow these instructions (after having run `make distclean`). Please note that we configure with `--without-xmlwf` as xmlwf does not support this mode of compilation (yet): 1. Mass-patch `Makefile.am` files to use `libexpatw.la` for a library name:
`find -name Makefile.am -exec sed -e 's,libexpat\.la,libexpatw.la,' -e 's,libexpat_la,libexpatw_la,' -i {} +` 1. Run `automake` to re-write `Makefile.in` files:
`automake` 1. For UTF-16 output as unsigned short (and version/error strings as char), run:
`./configure CPPFLAGS=-DXML_UNICODE --without-xmlwf`
For UTF-16 output as `wchar_t` (incl. version/error strings), run:
`./configure CFLAGS="-g -O2 -fshort-wchar" CPPFLAGS=-DXML_UNICODE_WCHAR_T --without-xmlwf`
Note: The latter requires libc compiled with `-fshort-wchar`, as well. 1. Run `make` (which excludes xmlwf). 1. Run `make install` (again, excludes xmlwf). Using `DESTDIR` is supported. It works as follows: ```console make install DESTDIR=/path/to/image ``` overrides the in-makefile set `DESTDIR`, because variable-setting priority is 1. commandline 1. in-makefile 1. environment Note: This only applies to the Expat library itself, building UTF-16 versions of xmlwf and the tests is currently not supported. When using Expat with a project using autoconf for configuration, you can use the probing macro in `conftools/expat.m4` to determine how to include Expat. See the comments at the top of that file for more information. A reference manual is available in the file `doc/reference.html` in this distribution. The CMake build system is still *experimental* and will replace the primary build system based on GNU Autotools at some point when it is ready. For an idea of the available (non-advanced) options for building with CMake: ```console # rm -f CMakeCache.txt ; cmake -D_EXPAT_HELP=ON -LH . | grep -B1 ':.*=' | sed 's,^--$,,' // Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel ... CMAKE_BUILD_TYPE:STRING= // Install path prefix, prepended onto install directories. CMAKE_INSTALL_PREFIX:PATH=/usr/local // Path to a program. DOCBOOK_TO_MAN:FILEPATH=/usr/bin/docbook2x-man // build man page for xmlwf EXPAT_BUILD_DOCS:BOOL=ON // build the examples for expat library EXPAT_BUILD_EXAMPLES:BOOL=ON // build fuzzers for the expat library EXPAT_BUILD_FUZZERS:BOOL=OFF // build the tests for expat library EXPAT_BUILD_TESTS:BOOL=ON // build the xmlwf tool for expat library EXPAT_BUILD_TOOLS:BOOL=ON // Character type to use (char|ushort|wchar_t) [default=char] EXPAT_CHAR_TYPE:STRING=char // install expat files in cmake install target EXPAT_ENABLE_INSTALL:BOOL=ON // Use /MT flag (static CRT) when compiling in MSVC EXPAT_MSVC_STATIC_CRT:BOOL=OFF // build a shared expat library EXPAT_SHARED_LIBS:BOOL=ON // Treat all compiler warnings as errors EXPAT_WARNINGS_AS_ERRORS:BOOL=OFF // Make use of getrandom function (ON|OFF|AUTO) [default=AUTO] EXPAT_WITH_GETRANDOM:STRING=AUTO // utilize libbsd (for arc4random_buf) EXPAT_WITH_LIBBSD:BOOL=OFF // Make use of syscall SYS_getrandom (ON|OFF|AUTO) [default=AUTO] EXPAT_WITH_SYS_GETRANDOM:STRING=AUTO ``` ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/README.txt0000644000175100001710000000023000000000000016527 0ustar00vstsdockerNote: astropy only requires the expat library, and hence in this bundled version, we removed all other files except the required license and changelog. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/expat_config.h0000644000175100001710000000737400000000000017670 0ustar00vstsdocker/* expat_config.h. Generated from expat_config.h.in by configure. */ /* expat_config.h.in. Generated from configure.ac by autoheader. */ /* Define if building universal (internal helper macro) */ /* #undef AC_APPLE_UNIVERSAL_BUILD */ /* 1234 = LILENDIAN, 4321 = BIGENDIAN */ #define BYTEORDER 1234 /* Define to 1 if you have the `arc4random' function. */ /* #undef HAVE_ARC4RANDOM */ /* Define to 1 if you have the `arc4random_buf' function. */ /* #undef HAVE_ARC4RANDOM_BUF */ /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 /* Define to 1 if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define to 1 if you have the `getpagesize' function. */ #define HAVE_GETPAGESIZE 1 /* Define to 1 if you have the `getrandom' function. */ /* #undef HAVE_GETRANDOM */ /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the `bsd' library (-lbsd). */ /* #undef HAVE_LIBBSD */ /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have a working `mmap' system call. */ #define HAVE_MMAP 1 /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have `syscall' and `SYS_getrandom'. */ /* #undef HAVE_SYSCALL_GETRANDOM */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_PARAM_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to the sub-directory where libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" /* Name of package */ #define PACKAGE "expat" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "expat-bugs@libexpat.org" /* Define to the full name of this package. */ #define PACKAGE_NAME "expat" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "expat 2.2.9" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "expat" /* Define to the home page for this package. */ #define PACKAGE_URL "" /* Define to the version of this package. */ #define PACKAGE_VERSION "2.2.9" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ #define VERSION "2.2.9" /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN /* # undef WORDS_BIGENDIAN */ # endif #endif /* Define to allow retrieving the byte offsets for attribute names and values. */ /* #undef XML_ATTR_INFO */ /* Define to specify how much context to retain around the current parse point. */ #define XML_CONTEXT_BYTES 1024 /* Define to include code reading entropy from `/dev/urandom'. */ #define XML_DEV_URANDOM 1 /* Define to make parameter entity parsing functionality available. */ #define XML_DTD 1 /* Define to make XML Namespaces functionality available. */ #define XML_NS 1 /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Define to `long int' if does not define. */ /* #undef off_t */ /* Define to `unsigned int' if does not define. */ /* #undef size_t */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/expat_config.h.in0000644000175100001710000000671400000000000020272 0ustar00vstsdocker/* expat_config.h.in. Generated from configure.ac by autoheader. */ /* Define if building universal (internal helper macro) */ #undef AC_APPLE_UNIVERSAL_BUILD /* 1234 = LILENDIAN, 4321 = BIGENDIAN */ #undef BYTEORDER /* Define to 1 if you have the `arc4random' function. */ #undef HAVE_ARC4RANDOM /* Define to 1 if you have the `arc4random_buf' function. */ #undef HAVE_ARC4RANDOM_BUF /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if you have the `getpagesize' function. */ #undef HAVE_GETPAGESIZE /* Define to 1 if you have the `getrandom' function. */ #undef HAVE_GETRANDOM /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `bsd' library (-lbsd). */ #undef HAVE_LIBBSD /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have a working `mmap' system call. */ #undef HAVE_MMAP /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have `syscall' and `SYS_getrandom'. */ #undef HAVE_SYSCALL_GETRANDOM /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PARAM_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN # undef WORDS_BIGENDIAN # endif #endif /* Define to allow retrieving the byte offsets for attribute names and values. */ #undef XML_ATTR_INFO /* Define to specify how much context to retain around the current parse point. */ #undef XML_CONTEXT_BYTES /* Define to include code reading entropy from `/dev/urandom'. */ #undef XML_DEV_URANDOM /* Define to make parameter entity parsing functionality available. */ #undef XML_DTD /* Define to make XML Namespaces functionality available. */ #undef XML_NS /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to `long int' if does not define. */ #undef off_t /* Define to `unsigned int' if does not define. */ #undef size_t ././@PaxHeader0000000000000000000000000000003200000000000010210 xustar0026 mtime=1646921593.26326 astropy-5.0.2/cextern/expat/lib/0000755000175100001710000000000000000000000015604 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/lib/.gitignore0000644000175100001710000000027400000000000017577 0ustar00vstsdockerMakefile .libs *.lo Debug Debug-w Release Release-w expat.ncb expat.opt expat.plg Debug_static Debug-w_static Release_static Release-w_static expat_static.plg expatw.plg expatw_static.plg ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/lib/Makefile.am0000644000175100001710000000435000000000000017642 0ustar00vstsdocker# # __ __ _ # ___\ \/ /_ __ __ _| |_ # / _ \\ /| '_ \ / _` | __| # | __// \| |_) | (_| | |_ # \___/_/\_\ .__/ \__,_|\__| # |_| XML parser # # Copyright (c) 2017 Expat development team # Licensed under the MIT license: # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to permit # persons to whom the Software is furnished to do so, subject to the # following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN # NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE # USE OR OTHER DEALINGS IN THE SOFTWARE. include_HEADERS = \ ../expat_config.h \ expat.h \ expat_external.h lib_LTLIBRARIES = libexpat.la libexpat_la_LDFLAGS = \ -no-undefined \ -version-info @LIBCURRENT@:@LIBREVISION@:@LIBAGE@ libexpat_la_SOURCES = \ xmlparse.c \ xmltok.c \ xmlrole.c doc_DATA = \ ../AUTHORS \ ../Changes install-data-hook: cd "$(DESTDIR)$(docdir)" && $(am__mv) Changes changelog uninstall-local: $(RM) "$(DESTDIR)$(docdir)/changelog" EXTRA_DIST = \ ascii.h \ asciitab.h \ expat_external.h \ expat.h \ iasciitab.h \ internal.h \ latin1tab.h \ libexpat.def \ libexpatw.def \ nametab.h \ siphash.h \ utf8tab.h \ winconfig.h \ xmlrole.h \ xmltok.h \ xmltok_impl.c \ xmltok_impl.h \ xmltok_ns.c ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/lib/Makefile.in0000644000175100001710000006041100000000000017653 0ustar00vstsdocker# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # __ __ _ # ___\ \/ /_ __ __ _| |_ # / _ \\ /| '_ \ / _` | __| # | __// \| |_) | (_| | |_ # \___/_/\_\ .__/ \__,_|\__| # |_| XML parser # # Copyright (c) 2017 Expat development team # Licensed under the MIT license: # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to permit # persons to whom the Software is furnished to do so, subject to the # following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN # NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE # USE OR OTHER DEALINGS IN THE SOFTWARE. VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/conftools/depcomp $(include_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/conftools/ax-require-defined.m4 \ $(top_srcdir)/conftools/ax-check-compile-flag.m4 \ $(top_srcdir)/conftools/ax-check-link-flag.m4 \ $(top_srcdir)/conftools/ax-append-flag.m4 \ $(top_srcdir)/conftools/ax-append-compile-flags.m4 \ $(top_srcdir)/conftools/ax-append-link-flags.m4 \ $(top_srcdir)/conftools/expatcfg-compiler-supports-visibility.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/expat_config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(docdir)" \ "$(DESTDIR)$(includedir)" LTLIBRARIES = $(lib_LTLIBRARIES) libexpat_la_LIBADD = am_libexpat_la_OBJECTS = xmlparse.lo xmltok.lo xmlrole.lo libexpat_la_OBJECTS = $(am_libexpat_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libexpat_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libexpat_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/conftools/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libexpat_la_SOURCES) DIST_SOURCES = $(libexpat_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac DATA = $(doc_DATA) HEADERS = $(include_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOCBOOK_TO_MAN = @DOCBOOK_TO_MAN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILEMAP = @FILEMAP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAGE = @LIBAGE@ LIBCURRENT = @LIBCURRENT@ LIBOBJS = @LIBOBJS@ LIBREVISION = @LIBREVISION@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ include_HEADERS = \ ../expat_config.h \ expat.h \ expat_external.h lib_LTLIBRARIES = libexpat.la libexpat_la_LDFLAGS = \ -no-undefined \ -version-info @LIBCURRENT@:@LIBREVISION@:@LIBAGE@ libexpat_la_SOURCES = \ xmlparse.c \ xmltok.c \ xmlrole.c doc_DATA = \ ../AUTHORS \ ../Changes EXTRA_DIST = \ ascii.h \ asciitab.h \ expat_external.h \ expat.h \ iasciitab.h \ internal.h \ latin1tab.h \ libexpat.def \ libexpatw.def \ nametab.h \ siphash.h \ utf8tab.h \ winconfig.h \ xmlrole.h \ xmltok.h \ xmltok_impl.c \ xmltok_impl.h \ xmltok_ns.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libexpat.la: $(libexpat_la_OBJECTS) $(libexpat_la_DEPENDENCIES) $(EXTRA_libexpat_la_DEPENDENCIES) $(AM_V_CCLD)$(libexpat_la_LINK) -rpath $(libdir) $(libexpat_la_OBJECTS) $(libexpat_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmlparse.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmlrole.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmltok.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-docDATA: $(doc_DATA) @$(NORMAL_INSTALL) @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ done uninstall-docDATA: @$(NORMAL_UNINSTALL) @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ done uninstall-includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-docDATA install-includeHEADERS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-data-hook install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-docDATA uninstall-includeHEADERS \ uninstall-libLTLIBRARIES uninstall-local .MAKE: install-am install-data-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-data-hook install-docDATA install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-includeHEADERS install-info \ install-info-am install-libLTLIBRARIES install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-docDATA \ uninstall-includeHEADERS uninstall-libLTLIBRARIES \ uninstall-local install-data-hook: cd "$(DESTDIR)$(docdir)" && $(am__mv) Changes changelog uninstall-local: $(RM) "$(DESTDIR)$(docdir)/changelog" # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/lib/ascii.h0000644000175100001710000000657400000000000017061 0ustar00vstsdocker/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000-2017 Expat development team Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define ASCII_A 0x41 #define ASCII_B 0x42 #define ASCII_C 0x43 #define ASCII_D 0x44 #define ASCII_E 0x45 #define ASCII_F 0x46 #define ASCII_G 0x47 #define ASCII_H 0x48 #define ASCII_I 0x49 #define ASCII_J 0x4A #define ASCII_K 0x4B #define ASCII_L 0x4C #define ASCII_M 0x4D #define ASCII_N 0x4E #define ASCII_O 0x4F #define ASCII_P 0x50 #define ASCII_Q 0x51 #define ASCII_R 0x52 #define ASCII_S 0x53 #define ASCII_T 0x54 #define ASCII_U 0x55 #define ASCII_V 0x56 #define ASCII_W 0x57 #define ASCII_X 0x58 #define ASCII_Y 0x59 #define ASCII_Z 0x5A #define ASCII_a 0x61 #define ASCII_b 0x62 #define ASCII_c 0x63 #define ASCII_d 0x64 #define ASCII_e 0x65 #define ASCII_f 0x66 #define ASCII_g 0x67 #define ASCII_h 0x68 #define ASCII_i 0x69 #define ASCII_j 0x6A #define ASCII_k 0x6B #define ASCII_l 0x6C #define ASCII_m 0x6D #define ASCII_n 0x6E #define ASCII_o 0x6F #define ASCII_p 0x70 #define ASCII_q 0x71 #define ASCII_r 0x72 #define ASCII_s 0x73 #define ASCII_t 0x74 #define ASCII_u 0x75 #define ASCII_v 0x76 #define ASCII_w 0x77 #define ASCII_x 0x78 #define ASCII_y 0x79 #define ASCII_z 0x7A #define ASCII_0 0x30 #define ASCII_1 0x31 #define ASCII_2 0x32 #define ASCII_3 0x33 #define ASCII_4 0x34 #define ASCII_5 0x35 #define ASCII_6 0x36 #define ASCII_7 0x37 #define ASCII_8 0x38 #define ASCII_9 0x39 #define ASCII_TAB 0x09 #define ASCII_SPACE 0x20 #define ASCII_EXCL 0x21 #define ASCII_QUOT 0x22 #define ASCII_AMP 0x26 #define ASCII_APOS 0x27 #define ASCII_MINUS 0x2D #define ASCII_PERIOD 0x2E #define ASCII_COLON 0x3A #define ASCII_SEMI 0x3B #define ASCII_LT 0x3C #define ASCII_EQUALS 0x3D #define ASCII_GT 0x3E #define ASCII_LSQB 0x5B #define ASCII_RSQB 0x5D #define ASCII_UNDERSCORE 0x5F #define ASCII_LPAREN 0x28 #define ASCII_RPAREN 0x29 #define ASCII_FF 0x0C #define ASCII_SLASH 0x2F #define ASCII_HASH 0x23 #define ASCII_PIPE 0x7C #define ASCII_COMMA 0x2C ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/lib/asciitab.h0000644000175100001710000000642700000000000017545 0ustar00vstsdocker/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000-2017 Expat development team Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, /* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML, /* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, /* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, /* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, /* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, /* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, /* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, /* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI, /* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, /* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, /* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, /* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, /* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, /* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, /* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, /* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, /* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/lib/expat.h0000644000175100001710000012100100000000000017071 0ustar00vstsdocker/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000-2017 Expat development team Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef Expat_INCLUDED #define Expat_INCLUDED 1 #include #include "expat_external.h" #ifdef __cplusplus extern "C" { #endif struct XML_ParserStruct; typedef struct XML_ParserStruct *XML_Parser; typedef unsigned char XML_Bool; #define XML_TRUE ((XML_Bool)1) #define XML_FALSE ((XML_Bool)0) /* The XML_Status enum gives the possible return values for several API functions. The preprocessor #defines are included so this stanza can be added to code that still needs to support older versions of Expat 1.95.x: #ifndef XML_STATUS_OK #define XML_STATUS_OK 1 #define XML_STATUS_ERROR 0 #endif Otherwise, the #define hackery is quite ugly and would have been dropped. */ enum XML_Status { XML_STATUS_ERROR = 0, #define XML_STATUS_ERROR XML_STATUS_ERROR XML_STATUS_OK = 1, #define XML_STATUS_OK XML_STATUS_OK XML_STATUS_SUSPENDED = 2 #define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED }; enum XML_Error { XML_ERROR_NONE, XML_ERROR_NO_MEMORY, XML_ERROR_SYNTAX, XML_ERROR_NO_ELEMENTS, XML_ERROR_INVALID_TOKEN, XML_ERROR_UNCLOSED_TOKEN, XML_ERROR_PARTIAL_CHAR, XML_ERROR_TAG_MISMATCH, XML_ERROR_DUPLICATE_ATTRIBUTE, XML_ERROR_JUNK_AFTER_DOC_ELEMENT, XML_ERROR_PARAM_ENTITY_REF, XML_ERROR_UNDEFINED_ENTITY, XML_ERROR_RECURSIVE_ENTITY_REF, XML_ERROR_ASYNC_ENTITY, XML_ERROR_BAD_CHAR_REF, XML_ERROR_BINARY_ENTITY_REF, XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, XML_ERROR_MISPLACED_XML_PI, XML_ERROR_UNKNOWN_ENCODING, XML_ERROR_INCORRECT_ENCODING, XML_ERROR_UNCLOSED_CDATA_SECTION, XML_ERROR_EXTERNAL_ENTITY_HANDLING, XML_ERROR_NOT_STANDALONE, XML_ERROR_UNEXPECTED_STATE, XML_ERROR_ENTITY_DECLARED_IN_PE, XML_ERROR_FEATURE_REQUIRES_XML_DTD, XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING, /* Added in 1.95.7. */ XML_ERROR_UNBOUND_PREFIX, /* Added in 1.95.8. */ XML_ERROR_UNDECLARING_PREFIX, XML_ERROR_INCOMPLETE_PE, XML_ERROR_XML_DECL, XML_ERROR_TEXT_DECL, XML_ERROR_PUBLICID, XML_ERROR_SUSPENDED, XML_ERROR_NOT_SUSPENDED, XML_ERROR_ABORTED, XML_ERROR_FINISHED, XML_ERROR_SUSPEND_PE, /* Added in 2.0. */ XML_ERROR_RESERVED_PREFIX_XML, XML_ERROR_RESERVED_PREFIX_XMLNS, XML_ERROR_RESERVED_NAMESPACE_URI, /* Added in 2.2.1. */ XML_ERROR_INVALID_ARGUMENT }; enum XML_Content_Type { XML_CTYPE_EMPTY = 1, XML_CTYPE_ANY, XML_CTYPE_MIXED, XML_CTYPE_NAME, XML_CTYPE_CHOICE, XML_CTYPE_SEQ }; enum XML_Content_Quant { XML_CQUANT_NONE, XML_CQUANT_OPT, XML_CQUANT_REP, XML_CQUANT_PLUS }; /* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be XML_CQUANT_NONE, and the other fields will be zero or NULL. If type == XML_CTYPE_MIXED, then quant will be NONE or REP and numchildren will contain number of elements that may be mixed in and children point to an array of XML_Content cells that will be all of XML_CTYPE_NAME type with no quantification. If type == XML_CTYPE_NAME, then the name points to the name, and the numchildren field will be zero and children will be NULL. The quant fields indicates any quantifiers placed on the name. CHOICE and SEQ will have name NULL, the number of children in numchildren and children will point, recursively, to an array of XML_Content cells. The EMPTY, ANY, and MIXED types will only occur at top level. */ typedef struct XML_cp XML_Content; struct XML_cp { enum XML_Content_Type type; enum XML_Content_Quant quant; XML_Char *name; unsigned int numchildren; XML_Content *children; }; /* This is called for an element declaration. See above for description of the model argument. It's the caller's responsibility to free model when finished with it. */ typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData, const XML_Char *name, XML_Content *model); XMLPARSEAPI(void) XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl); /* The Attlist declaration handler is called for *each* attribute. So a single Attlist declaration with multiple attributes declared will generate multiple calls to this handler. The "default" parameter may be NULL in the case of the "#IMPLIED" or "#REQUIRED" keyword. The "isrequired" parameter will be true and the default value will be NULL in the case of "#REQUIRED". If "isrequired" is true and default is non-NULL, then this is a "#FIXED" default. */ typedef void(XMLCALL *XML_AttlistDeclHandler)( void *userData, const XML_Char *elname, const XML_Char *attname, const XML_Char *att_type, const XML_Char *dflt, int isrequired); XMLPARSEAPI(void) XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl); /* The XML declaration handler is called for *both* XML declarations and text declarations. The way to distinguish is that the version parameter will be NULL for text declarations. The encoding parameter may be NULL for XML declarations. The standalone parameter will be -1, 0, or 1 indicating respectively that there was no standalone parameter in the declaration, that it was given as no, or that it was given as yes. */ typedef void(XMLCALL *XML_XmlDeclHandler)(void *userData, const XML_Char *version, const XML_Char *encoding, int standalone); XMLPARSEAPI(void) XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler xmldecl); typedef struct { void *(*malloc_fcn)(size_t size); void *(*realloc_fcn)(void *ptr, size_t size); void (*free_fcn)(void *ptr); } XML_Memory_Handling_Suite; /* Constructs a new parser; encoding is the encoding specified by the external protocol or NULL if there is none specified. */ XMLPARSEAPI(XML_Parser) XML_ParserCreate(const XML_Char *encoding); /* Constructs a new parser and namespace processor. Element type names and attribute names that belong to a namespace will be expanded; unprefixed attribute names are never expanded; unprefixed element type names are expanded only if there is a default namespace. The expanded name is the concatenation of the namespace URI, the namespace separator character, and the local part of the name. If the namespace separator is '\0' then the namespace URI and the local part will be concatenated without any separator. It is a programming error to use the separator '\0' with namespace triplets (see XML_SetReturnNSTriplet). */ XMLPARSEAPI(XML_Parser) XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); /* Constructs a new parser using the memory management suite referred to by memsuite. If memsuite is NULL, then use the standard library memory suite. If namespaceSeparator is non-NULL it creates a parser with namespace processing as described above. The character pointed at will serve as the namespace separator. All further memory operations used for the created parser will come from the given suite. */ XMLPARSEAPI(XML_Parser) XML_ParserCreate_MM(const XML_Char *encoding, const XML_Memory_Handling_Suite *memsuite, const XML_Char *namespaceSeparator); /* Prepare a parser object to be re-used. This is particularly valuable when memory allocation overhead is disproportionately high, such as when a large number of small documnents need to be parsed. All handlers are cleared from the parser, except for the unknownEncodingHandler. The parser's external state is re-initialized except for the values of ns and ns_triplets. Added in Expat 1.95.3. */ XMLPARSEAPI(XML_Bool) XML_ParserReset(XML_Parser parser, const XML_Char *encoding); /* atts is array of name/value pairs, terminated by 0; names and values are 0 terminated. */ typedef void(XMLCALL *XML_StartElementHandler)(void *userData, const XML_Char *name, const XML_Char **atts); typedef void(XMLCALL *XML_EndElementHandler)(void *userData, const XML_Char *name); /* s is not 0 terminated. */ typedef void(XMLCALL *XML_CharacterDataHandler)(void *userData, const XML_Char *s, int len); /* target and data are 0 terminated */ typedef void(XMLCALL *XML_ProcessingInstructionHandler)(void *userData, const XML_Char *target, const XML_Char *data); /* data is 0 terminated */ typedef void(XMLCALL *XML_CommentHandler)(void *userData, const XML_Char *data); typedef void(XMLCALL *XML_StartCdataSectionHandler)(void *userData); typedef void(XMLCALL *XML_EndCdataSectionHandler)(void *userData); /* This is called for any characters in the XML document for which there is no applicable handler. This includes both characters that are part of markup which is of a kind that is not reported (comments, markup declarations), or characters that are part of a construct which could be reported but for which no handler has been supplied. The characters are passed exactly as they were in the XML document except that they will be encoded in UTF-8 or UTF-16. Line boundaries are not normalized. Note that a byte order mark character is not passed to the default handler. There are no guarantees about how characters are divided between calls to the default handler: for example, a comment might be split between multiple calls. */ typedef void(XMLCALL *XML_DefaultHandler)(void *userData, const XML_Char *s, int len); /* This is called for the start of the DOCTYPE declaration, before any DTD or internal subset is parsed. */ typedef void(XMLCALL *XML_StartDoctypeDeclHandler)(void *userData, const XML_Char *doctypeName, const XML_Char *sysid, const XML_Char *pubid, int has_internal_subset); /* This is called for the start of the DOCTYPE declaration when the closing > is encountered, but after processing any external subset. */ typedef void(XMLCALL *XML_EndDoctypeDeclHandler)(void *userData); /* This is called for entity declarations. The is_parameter_entity argument will be non-zero if the entity is a parameter entity, zero otherwise. For internal entities (), value will be non-NULL and systemId, publicID, and notationName will be NULL. The value string is NOT nul-terminated; the length is provided in the value_length argument. Since it is legal to have zero-length values, do not use this argument to test for internal entities. For external entities, value will be NULL and systemId will be non-NULL. The publicId argument will be NULL unless a public identifier was provided. The notationName argument will have a non-NULL value only for unparsed entity declarations. Note that is_parameter_entity can't be changed to XML_Bool, since that would break binary compatibility. */ typedef void(XMLCALL *XML_EntityDeclHandler)( void *userData, const XML_Char *entityName, int is_parameter_entity, const XML_Char *value, int value_length, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId, const XML_Char *notationName); XMLPARSEAPI(void) XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler); /* OBSOLETE -- OBSOLETE -- OBSOLETE This handler has been superseded by the EntityDeclHandler above. It is provided here for backward compatibility. This is called for a declaration of an unparsed (NDATA) entity. The base argument is whatever was set by XML_SetBase. The entityName, systemId and notationName arguments will never be NULL. The other arguments may be. */ typedef void(XMLCALL *XML_UnparsedEntityDeclHandler)( void *userData, const XML_Char *entityName, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId, const XML_Char *notationName); /* This is called for a declaration of notation. The base argument is whatever was set by XML_SetBase. The notationName will never be NULL. The other arguments can be. */ typedef void(XMLCALL *XML_NotationDeclHandler)(void *userData, const XML_Char *notationName, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId); /* When namespace processing is enabled, these are called once for each namespace declaration. The call to the start and end element handlers occur between the calls to the start and end namespace declaration handlers. For an xmlns attribute, prefix will be NULL. For an xmlns="" attribute, uri will be NULL. */ typedef void(XMLCALL *XML_StartNamespaceDeclHandler)(void *userData, const XML_Char *prefix, const XML_Char *uri); typedef void(XMLCALL *XML_EndNamespaceDeclHandler)(void *userData, const XML_Char *prefix); /* This is called if the document is not standalone, that is, it has an external subset or a reference to a parameter entity, but does not have standalone="yes". If this handler returns XML_STATUS_ERROR, then processing will not continue, and the parser will return a XML_ERROR_NOT_STANDALONE error. If parameter entity parsing is enabled, then in addition to the conditions above this handler will only be called if the referenced entity was actually read. */ typedef int(XMLCALL *XML_NotStandaloneHandler)(void *userData); /* This is called for a reference to an external parsed general entity. The referenced entity is not automatically parsed. The application can parse it immediately or later using XML_ExternalEntityParserCreate. The parser argument is the parser parsing the entity containing the reference; it can be passed as the parser argument to XML_ExternalEntityParserCreate. The systemId argument is the system identifier as specified in the entity declaration; it will not be NULL. The base argument is the system identifier that should be used as the base for resolving systemId if systemId was relative; this is set by XML_SetBase; it may be NULL. The publicId argument is the public identifier as specified in the entity declaration, or NULL if none was specified; the whitespace in the public identifier will have been normalized as required by the XML spec. The context argument specifies the parsing context in the format expected by the context argument to XML_ExternalEntityParserCreate; context is valid only until the handler returns, so if the referenced entity is to be parsed later, it must be copied. context is NULL only when the entity is a parameter entity. The handler should return XML_STATUS_ERROR if processing should not continue because of a fatal error in the handling of the external entity. In this case the calling parser will return an XML_ERROR_EXTERNAL_ENTITY_HANDLING error. Note that unlike other handlers the first argument is the parser, not userData. */ typedef int(XMLCALL *XML_ExternalEntityRefHandler)(XML_Parser parser, const XML_Char *context, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId); /* This is called in two situations: 1) An entity reference is encountered for which no declaration has been read *and* this is not an error. 2) An internal entity reference is read, but not expanded, because XML_SetDefaultHandler has been called. Note: skipped parameter entities in declarations and skipped general entities in attribute values cannot be reported, because the event would be out of sync with the reporting of the declarations or attribute values */ typedef void(XMLCALL *XML_SkippedEntityHandler)(void *userData, const XML_Char *entityName, int is_parameter_entity); /* This structure is filled in by the XML_UnknownEncodingHandler to provide information to the parser about encodings that are unknown to the parser. The map[b] member gives information about byte sequences whose first byte is b. If map[b] is c where c is >= 0, then b by itself encodes the Unicode scalar value c. If map[b] is -1, then the byte sequence is malformed. If map[b] is -n, where n >= 2, then b is the first byte of an n-byte sequence that encodes a single Unicode scalar value. The data member will be passed as the first argument to the convert function. The convert function is used to convert multibyte sequences; s will point to a n-byte sequence where map[(unsigned char)*s] == -n. The convert function must return the Unicode scalar value represented by this byte sequence or -1 if the byte sequence is malformed. The convert function may be NULL if the encoding is a single-byte encoding, that is if map[b] >= -1 for all bytes b. When the parser is finished with the encoding, then if release is not NULL, it will call release passing it the data member; once release has been called, the convert function will not be called again. Expat places certain restrictions on the encodings that are supported using this mechanism. 1. Every ASCII character that can appear in a well-formed XML document, other than the characters $@\^`{}~ must be represented by a single byte, and that byte must be the same byte that represents that character in ASCII. 2. No character may require more than 4 bytes to encode. 3. All characters encoded must have Unicode scalar values <= 0xFFFF, (i.e., characters that would be encoded by surrogates in UTF-16 are not allowed). Note that this restriction doesn't apply to the built-in support for UTF-8 and UTF-16. 4. No Unicode character may be encoded by more than one distinct sequence of bytes. */ typedef struct { int map[256]; void *data; int(XMLCALL *convert)(void *data, const char *s); void(XMLCALL *release)(void *data); } XML_Encoding; /* This is called for an encoding that is unknown to the parser. The encodingHandlerData argument is that which was passed as the second argument to XML_SetUnknownEncodingHandler. The name argument gives the name of the encoding as specified in the encoding declaration. If the callback can provide information about the encoding, it must fill in the XML_Encoding structure, and return XML_STATUS_OK. Otherwise it must return XML_STATUS_ERROR. If info does not describe a suitable encoding, then the parser will return an XML_UNKNOWN_ENCODING error. */ typedef int(XMLCALL *XML_UnknownEncodingHandler)(void *encodingHandlerData, const XML_Char *name, XML_Encoding *info); XMLPARSEAPI(void) XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, XML_EndElementHandler end); XMLPARSEAPI(void) XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler handler); XMLPARSEAPI(void) XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler handler); XMLPARSEAPI(void) XML_SetCharacterDataHandler(XML_Parser parser, XML_CharacterDataHandler handler); XMLPARSEAPI(void) XML_SetProcessingInstructionHandler(XML_Parser parser, XML_ProcessingInstructionHandler handler); XMLPARSEAPI(void) XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler); XMLPARSEAPI(void) XML_SetCdataSectionHandler(XML_Parser parser, XML_StartCdataSectionHandler start, XML_EndCdataSectionHandler end); XMLPARSEAPI(void) XML_SetStartCdataSectionHandler(XML_Parser parser, XML_StartCdataSectionHandler start); XMLPARSEAPI(void) XML_SetEndCdataSectionHandler(XML_Parser parser, XML_EndCdataSectionHandler end); /* This sets the default handler and also inhibits expansion of internal entities. These entity references will be passed to the default handler, or to the skipped entity handler, if one is set. */ XMLPARSEAPI(void) XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler); /* This sets the default handler but does not inhibit expansion of internal entities. The entity reference will not be passed to the default handler. */ XMLPARSEAPI(void) XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler); XMLPARSEAPI(void) XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start, XML_EndDoctypeDeclHandler end); XMLPARSEAPI(void) XML_SetStartDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start); XMLPARSEAPI(void) XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end); XMLPARSEAPI(void) XML_SetUnparsedEntityDeclHandler(XML_Parser parser, XML_UnparsedEntityDeclHandler handler); XMLPARSEAPI(void) XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler); XMLPARSEAPI(void) XML_SetNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start, XML_EndNamespaceDeclHandler end); XMLPARSEAPI(void) XML_SetStartNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start); XMLPARSEAPI(void) XML_SetEndNamespaceDeclHandler(XML_Parser parser, XML_EndNamespaceDeclHandler end); XMLPARSEAPI(void) XML_SetNotStandaloneHandler(XML_Parser parser, XML_NotStandaloneHandler handler); XMLPARSEAPI(void) XML_SetExternalEntityRefHandler(XML_Parser parser, XML_ExternalEntityRefHandler handler); /* If a non-NULL value for arg is specified here, then it will be passed as the first argument to the external entity ref handler instead of the parser object. */ XMLPARSEAPI(void) XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg); XMLPARSEAPI(void) XML_SetSkippedEntityHandler(XML_Parser parser, XML_SkippedEntityHandler handler); XMLPARSEAPI(void) XML_SetUnknownEncodingHandler(XML_Parser parser, XML_UnknownEncodingHandler handler, void *encodingHandlerData); /* This can be called within a handler for a start element, end element, processing instruction or character data. It causes the corresponding markup to be passed to the default handler. */ XMLPARSEAPI(void) XML_DefaultCurrent(XML_Parser parser); /* If do_nst is non-zero, and namespace processing is in effect, and a name has a prefix (i.e. an explicit namespace qualifier) then that name is returned as a triplet in a single string separated by the separator character specified when the parser was created: URI + sep + local_name + sep + prefix. If do_nst is zero, then namespace information is returned in the default manner (URI + sep + local_name) whether or not the name has a prefix. Note: Calling XML_SetReturnNSTriplet after XML_Parse or XML_ParseBuffer has no effect. */ XMLPARSEAPI(void) XML_SetReturnNSTriplet(XML_Parser parser, int do_nst); /* This value is passed as the userData argument to callbacks. */ XMLPARSEAPI(void) XML_SetUserData(XML_Parser parser, void *userData); /* Returns the last value set by XML_SetUserData or NULL. */ #define XML_GetUserData(parser) (*(void **)(parser)) /* This is equivalent to supplying an encoding argument to XML_ParserCreate. On success XML_SetEncoding returns non-zero, zero otherwise. Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer has no effect and returns XML_STATUS_ERROR. */ XMLPARSEAPI(enum XML_Status) XML_SetEncoding(XML_Parser parser, const XML_Char *encoding); /* If this function is called, then the parser will be passed as the first argument to callbacks instead of userData. The userData will still be accessible using XML_GetUserData. */ XMLPARSEAPI(void) XML_UseParserAsHandlerArg(XML_Parser parser); /* If useDTD == XML_TRUE is passed to this function, then the parser will assume that there is an external subset, even if none is specified in the document. In such a case the parser will call the externalEntityRefHandler with a value of NULL for the systemId argument (the publicId and context arguments will be NULL as well). Note: For the purpose of checking WFC: Entity Declared, passing useDTD == XML_TRUE will make the parser behave as if the document had a DTD with an external subset. Note: If this function is called, then this must be done before the first call to XML_Parse or XML_ParseBuffer, since it will have no effect after that. Returns XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING. Note: If the document does not have a DOCTYPE declaration at all, then startDoctypeDeclHandler and endDoctypeDeclHandler will not be called, despite an external subset being parsed. Note: If XML_DTD is not defined when Expat is compiled, returns XML_ERROR_FEATURE_REQUIRES_XML_DTD. Note: If parser == NULL, returns XML_ERROR_INVALID_ARGUMENT. */ XMLPARSEAPI(enum XML_Error) XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); /* Sets the base to be used for resolving relative URIs in system identifiers in declarations. Resolving relative identifiers is left to the application: this value will be passed through as the base argument to the XML_ExternalEntityRefHandler, XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base argument will be copied. Returns XML_STATUS_ERROR if out of memory, XML_STATUS_OK otherwise. */ XMLPARSEAPI(enum XML_Status) XML_SetBase(XML_Parser parser, const XML_Char *base); XMLPARSEAPI(const XML_Char *) XML_GetBase(XML_Parser parser); /* Returns the number of the attribute/value pairs passed in last call to the XML_StartElementHandler that were specified in the start-tag rather than defaulted. Each attribute/value pair counts as 2; thus this correspondds to an index into the atts array passed to the XML_StartElementHandler. Returns -1 if parser == NULL. */ XMLPARSEAPI(int) XML_GetSpecifiedAttributeCount(XML_Parser parser); /* Returns the index of the ID attribute passed in the last call to XML_StartElementHandler, or -1 if there is no ID attribute or parser == NULL. Each attribute/value pair counts as 2; thus this correspondds to an index into the atts array passed to the XML_StartElementHandler. */ XMLPARSEAPI(int) XML_GetIdAttributeIndex(XML_Parser parser); #ifdef XML_ATTR_INFO /* Source file byte offsets for the start and end of attribute names and values. The value indices are exclusive of surrounding quotes; thus in a UTF-8 source file an attribute value of "blah" will yield: info->valueEnd - info->valueStart = 4 bytes. */ typedef struct { XML_Index nameStart; /* Offset to beginning of the attribute name. */ XML_Index nameEnd; /* Offset after the attribute name's last byte. */ XML_Index valueStart; /* Offset to beginning of the attribute value. */ XML_Index valueEnd; /* Offset after the attribute value's last byte. */ } XML_AttrInfo; /* Returns an array of XML_AttrInfo structures for the attribute/value pairs passed in last call to the XML_StartElementHandler that were specified in the start-tag rather than defaulted. Each attribute/value pair counts as 1; thus the number of entries in the array is XML_GetSpecifiedAttributeCount(parser) / 2. */ XMLPARSEAPI(const XML_AttrInfo *) XML_GetAttributeInfo(XML_Parser parser); #endif /* Parses some input. Returns XML_STATUS_ERROR if a fatal error is detected. The last call to XML_Parse must have isFinal true; len may be zero for this call (or any other). Though the return values for these functions has always been described as a Boolean value, the implementation, at least for the 1.95.x series, has always returned exactly one of the XML_Status values. */ XMLPARSEAPI(enum XML_Status) XML_Parse(XML_Parser parser, const char *s, int len, int isFinal); XMLPARSEAPI(void *) XML_GetBuffer(XML_Parser parser, int len); XMLPARSEAPI(enum XML_Status) XML_ParseBuffer(XML_Parser parser, int len, int isFinal); /* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return. Must be called from within a call-back handler, except when aborting (resumable = 0) an already suspended parser. Some call-backs may still follow because they would otherwise get lost. Examples: - endElementHandler() for empty elements when stopped in startElementHandler(), - endNameSpaceDeclHandler() when stopped in endElementHandler(), and possibly others. Can be called from most handlers, including DTD related call-backs, except when parsing an external parameter entity and resumable != 0. Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise. Possible error codes: - XML_ERROR_SUSPENDED: when suspending an already suspended parser. - XML_ERROR_FINISHED: when the parser has already finished. - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE. When resumable != 0 (true) then parsing is suspended, that is, XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED. Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer() return XML_STATUS_ERROR with error code XML_ERROR_ABORTED. *Note*: This will be applied to the current parser instance only, that is, if there is a parent parser then it will continue parsing when the externalEntityRefHandler() returns. It is up to the implementation of the externalEntityRefHandler() to call XML_StopParser() on the parent parser (recursively), if one wants to stop parsing altogether. When suspended, parsing can be resumed by calling XML_ResumeParser(). */ XMLPARSEAPI(enum XML_Status) XML_StopParser(XML_Parser parser, XML_Bool resumable); /* Resumes parsing after it has been suspended with XML_StopParser(). Must not be called from within a handler call-back. Returns same status codes as XML_Parse() or XML_ParseBuffer(). Additional error code XML_ERROR_NOT_SUSPENDED possible. *Note*: This must be called on the most deeply nested child parser instance first, and on its parent parser only after the child parser has finished, to be applied recursively until the document entity's parser is restarted. That is, the parent parser will not resume by itself and it is up to the application to call XML_ResumeParser() on it at the appropriate moment. */ XMLPARSEAPI(enum XML_Status) XML_ResumeParser(XML_Parser parser); enum XML_Parsing { XML_INITIALIZED, XML_PARSING, XML_FINISHED, XML_SUSPENDED }; typedef struct { enum XML_Parsing parsing; XML_Bool finalBuffer; } XML_ParsingStatus; /* Returns status of parser with respect to being initialized, parsing, finished, or suspended and processing the final buffer. XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus, XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED */ XMLPARSEAPI(void) XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status); /* Creates an XML_Parser object that can parse an external general entity; context is a '\0'-terminated string specifying the parse context; encoding is a '\0'-terminated string giving the name of the externally specified encoding, or NULL if there is no externally specified encoding. The context string consists of a sequence of tokens separated by formfeeds (\f); a token consisting of a name specifies that the general entity of the name is open; a token of the form prefix=uri specifies the namespace for a particular prefix; a token of the form =uri specifies the default namespace. This can be called at any point after the first call to an ExternalEntityRefHandler so longer as the parser has not yet been freed. The new parser is completely independent and may safely be used in a separate thread. The handlers and userData are initialized from the parser argument. Returns NULL if out of memory. Otherwise returns a new XML_Parser object. */ XMLPARSEAPI(XML_Parser) XML_ExternalEntityParserCreate(XML_Parser parser, const XML_Char *context, const XML_Char *encoding); enum XML_ParamEntityParsing { XML_PARAM_ENTITY_PARSING_NEVER, XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, XML_PARAM_ENTITY_PARSING_ALWAYS }; /* Controls parsing of parameter entities (including the external DTD subset). If parsing of parameter entities is enabled, then references to external parameter entities (including the external DTD subset) will be passed to the handler set with XML_SetExternalEntityRefHandler. The context passed will be 0. Unlike external general entities, external parameter entities can only be parsed synchronously. If the external parameter entity is to be parsed, it must be parsed during the call to the external entity ref handler: the complete sequence of XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and XML_ParserFree calls must be made during this call. After XML_ExternalEntityParserCreate has been called to create the parser for the external parameter entity (context must be 0 for this call), it is illegal to make any calls on the old parser until XML_ParserFree has been called on the newly created parser. If the library has been compiled without support for parameter entity parsing (ie without XML_DTD being defined), then XML_SetParamEntityParsing will return 0 if parsing of parameter entities is requested; otherwise it will return non-zero. Note: If XML_SetParamEntityParsing is called after XML_Parse or XML_ParseBuffer, then it has no effect and will always return 0. Note: If parser == NULL, the function will do nothing and return 0. */ XMLPARSEAPI(int) XML_SetParamEntityParsing(XML_Parser parser, enum XML_ParamEntityParsing parsing); /* Sets the hash salt to use for internal hash calculations. Helps in preventing DoS attacks based on predicting hash function behavior. This must be called before parsing is started. Returns 1 if successful, 0 when called after parsing has started. Note: If parser == NULL, the function will do nothing and return 0. */ XMLPARSEAPI(int) XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt); /* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then XML_GetErrorCode returns information about the error. */ XMLPARSEAPI(enum XML_Error) XML_GetErrorCode(XML_Parser parser); /* These functions return information about the current parse location. They may be called from any callback called to report some parse event; in this case the location is the location of the first of the sequence of characters that generated the event. When called from callbacks generated by declarations in the document prologue, the location identified isn't as neatly defined, but will be within the relevant markup. When called outside of the callback functions, the position indicated will be just past the last parse event (regardless of whether there was an associated callback). They may also be called after returning from a call to XML_Parse or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then the location is the location of the character at which the error was detected; otherwise the location is the location of the last parse event, as described above. Note: XML_GetCurrentLineNumber and XML_GetCurrentColumnNumber return 0 to indicate an error. Note: XML_GetCurrentByteIndex returns -1 to indicate an error. */ XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser); XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser); XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser); /* Return the number of bytes in the current event. Returns 0 if the event is in an internal entity. */ XMLPARSEAPI(int) XML_GetCurrentByteCount(XML_Parser parser); /* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets the integer pointed to by offset to the offset within this buffer of the current parse position, and sets the integer pointed to by size to the size of this buffer (the number of input bytes). Otherwise returns a NULL pointer. Also returns a NULL pointer if a parse isn't active. NOTE: The character pointer returned should not be used outside the handler that makes the call. */ XMLPARSEAPI(const char *) XML_GetInputContext(XML_Parser parser, int *offset, int *size); /* For backwards compatibility with previous versions. */ #define XML_GetErrorLineNumber XML_GetCurrentLineNumber #define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber #define XML_GetErrorByteIndex XML_GetCurrentByteIndex /* Frees the content model passed to the element declaration handler */ XMLPARSEAPI(void) XML_FreeContentModel(XML_Parser parser, XML_Content *model); /* Exposing the memory handling functions used in Expat */ XMLPARSEAPI(void *) XML_ATTR_MALLOC XML_ATTR_ALLOC_SIZE(2) XML_MemMalloc(XML_Parser parser, size_t size); XMLPARSEAPI(void *) XML_ATTR_ALLOC_SIZE(3) XML_MemRealloc(XML_Parser parser, void *ptr, size_t size); XMLPARSEAPI(void) XML_MemFree(XML_Parser parser, void *ptr); /* Frees memory used by the parser. */ XMLPARSEAPI(void) XML_ParserFree(XML_Parser parser); /* Returns a string describing the error. */ XMLPARSEAPI(const XML_LChar *) XML_ErrorString(enum XML_Error code); /* Return a string containing the version number of this expat */ XMLPARSEAPI(const XML_LChar *) XML_ExpatVersion(void); typedef struct { int major; int minor; int micro; } XML_Expat_Version; /* Return an XML_Expat_Version structure containing numeric version number information for this version of expat. */ XMLPARSEAPI(XML_Expat_Version) XML_ExpatVersionInfo(void); /* Added in Expat 1.95.5. */ enum XML_FeatureEnum { XML_FEATURE_END = 0, XML_FEATURE_UNICODE, XML_FEATURE_UNICODE_WCHAR_T, XML_FEATURE_DTD, XML_FEATURE_CONTEXT_BYTES, XML_FEATURE_MIN_SIZE, XML_FEATURE_SIZEOF_XML_CHAR, XML_FEATURE_SIZEOF_XML_LCHAR, XML_FEATURE_NS, XML_FEATURE_LARGE_SIZE, XML_FEATURE_ATTR_INFO /* Additional features must be added to the end of this enum. */ }; typedef struct { enum XML_FeatureEnum feature; const XML_LChar *name; long int value; } XML_Feature; XMLPARSEAPI(const XML_Feature *) XML_GetFeatureList(void); /* Expat follows the semantic versioning convention. See http://semver.org. */ #define XML_MAJOR_VERSION 2 #define XML_MINOR_VERSION 2 #define XML_MICRO_VERSION 9 #ifdef __cplusplus } #endif #endif /* not Expat_INCLUDED */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/lib/expat_external.h0000644000175100001710000001263000000000000021002 0ustar00vstsdocker/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000-2017 Expat development team Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef Expat_External_INCLUDED #define Expat_External_INCLUDED 1 /* External API definitions */ /* Expat tries very hard to make the API boundary very specifically defined. There are two macros defined to control this boundary; each of these can be defined before including this header to achieve some different behavior, but doing so it not recommended or tested frequently. XMLCALL - The calling convention to use for all calls across the "library boundary." This will default to cdecl, and try really hard to tell the compiler that's what we want. XMLIMPORT - Whatever magic is needed to note that a function is to be imported from a dynamically loaded library (.dll, .so, or .sl, depending on your platform). The XMLCALL macro was added in Expat 1.95.7. The only one which is expected to be directly useful in client code is XMLCALL. Note that on at least some Unix versions, the Expat library must be compiled with the cdecl calling convention as the default since system headers may assume the cdecl convention. */ #ifndef XMLCALL # if defined(_MSC_VER) # define XMLCALL __cdecl # elif defined(__GNUC__) && defined(__i386) && ! defined(__INTEL_COMPILER) # define XMLCALL __attribute__((cdecl)) # else /* For any platform which uses this definition and supports more than one calling convention, we need to extend this definition to declare the convention used on that platform, if it's possible to do so. If this is the case for your platform, please file a bug report with information on how to identify your platform via the C pre-processor and how to specify the same calling convention as the platform's malloc() implementation. */ # define XMLCALL # endif #endif /* not defined XMLCALL */ #if ! defined(XML_STATIC) && ! defined(XMLIMPORT) # ifndef XML_BUILDING_EXPAT /* using Expat from an application */ # if defined(_MSC_EXTENSIONS) && ! defined(__BEOS__) && ! defined(__CYGWIN__) # define XMLIMPORT __declspec(dllimport) # endif # endif #endif /* not defined XML_STATIC */ #ifndef XML_ENABLE_VISIBILITY # define XML_ENABLE_VISIBILITY 0 #endif #if ! defined(XMLIMPORT) && XML_ENABLE_VISIBILITY # define XMLIMPORT __attribute__((visibility("default"))) #endif /* If we didn't define it above, define it away: */ #ifndef XMLIMPORT # define XMLIMPORT #endif #if defined(__GNUC__) \ && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)) # define XML_ATTR_MALLOC __attribute__((__malloc__)) #else # define XML_ATTR_MALLOC #endif #if defined(__GNUC__) \ && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) # define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x))) #else # define XML_ATTR_ALLOC_SIZE(x) #endif #define XMLPARSEAPI(type) XMLIMPORT type XMLCALL #ifdef __cplusplus extern "C" { #endif #ifdef XML_UNICODE_WCHAR_T # ifndef XML_UNICODE # define XML_UNICODE # endif # if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2) # error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc" # endif #endif #ifdef XML_UNICODE /* Information is UTF-16 encoded. */ # ifdef XML_UNICODE_WCHAR_T typedef wchar_t XML_Char; typedef wchar_t XML_LChar; # else typedef unsigned short XML_Char; typedef char XML_LChar; # endif /* XML_UNICODE_WCHAR_T */ #else /* Information is UTF-8 encoded. */ typedef char XML_Char; typedef char XML_LChar; #endif /* XML_UNICODE */ #ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */ typedef long long XML_Index; typedef unsigned long long XML_Size; #else typedef long XML_Index; typedef unsigned long XML_Size; #endif /* XML_LARGE_SIZE */ #ifdef __cplusplus } #endif #endif /* not Expat_External_INCLUDED */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/lib/iasciitab.h0000644000175100001710000000653500000000000017716 0ustar00vstsdocker/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000-2017 Expat development team Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */ /* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, /* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML, /* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, /* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, /* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, /* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, /* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, /* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, /* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI, /* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, /* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, /* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, /* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, /* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, /* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, /* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, /* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, /* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/lib/internal.h0000644000175100001710000000766200000000000017604 0ustar00vstsdocker/* internal.h Internal definitions used by Expat. This is not needed to compile client code. The following calling convention macros are defined for frequently called functions: FASTCALL - Used for those internal functions that have a simple body and a low number of arguments and local variables. PTRCALL - Used for functions called though function pointers. PTRFASTCALL - Like PTRCALL, but for low number of arguments. inline - Used for selected internal functions for which inlining may improve performance on some platforms. Note: Use of these macros is based on judgement, not hard rules, and therefore subject to change. __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000-2017 Expat development team Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #if defined(__GNUC__) && defined(__i386__) && ! defined(__MINGW32__) /* We'll use this version by default only where we know it helps. regparm() generates warnings on Solaris boxes. See SF bug #692878. Instability reported with egcs on a RedHat Linux 7.3. Let's comment out: #define FASTCALL __attribute__((stdcall, regparm(3))) and let's try this: */ # define FASTCALL __attribute__((regparm(3))) # define PTRFASTCALL __attribute__((regparm(3))) #endif /* Using __fastcall seems to have an unexpected negative effect under MS VC++, especially for function pointers, so we won't use it for now on that platform. It may be reconsidered for a future release if it can be made more effective. Likely reason: __fastcall on Windows is like stdcall, therefore the compiler cannot perform stack optimizations for call clusters. */ /* Make sure all of these are defined if they aren't already. */ #ifndef FASTCALL # define FASTCALL #endif #ifndef PTRCALL # define PTRCALL #endif #ifndef PTRFASTCALL # define PTRFASTCALL #endif #ifndef XML_MIN_SIZE # if ! defined(__cplusplus) && ! defined(inline) # ifdef __GNUC__ # define inline __inline # endif /* __GNUC__ */ # endif #endif /* XML_MIN_SIZE */ #ifdef __cplusplus # define inline inline #else # ifndef inline # define inline # endif #endif #ifndef UNUSED_P # define UNUSED_P(p) (void)p #endif #ifdef __cplusplus extern "C" { #endif #ifdef XML_ENABLE_VISIBILITY # if XML_ENABLE_VISIBILITY __attribute__((visibility("default"))) # endif #endif void _INTERNAL_trim_to_complete_utf8_characters(const char *from, const char **fromLimRef); #ifdef __cplusplus } #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/lib/latin1tab.h0000644000175100001710000000651400000000000017642 0ustar00vstsdocker/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000-2017 Expat development team Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, /* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME, /* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, /* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, /* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, /* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/lib/libexpat.def0000644000175100001710000000420400000000000020074 0ustar00vstsdocker; DEF file for MS VC++ LIBRARY EXPORTS XML_DefaultCurrent @1 XML_ErrorString @2 XML_ExpatVersion @3 XML_ExpatVersionInfo @4 XML_ExternalEntityParserCreate @5 XML_GetBase @6 XML_GetBuffer @7 XML_GetCurrentByteCount @8 XML_GetCurrentByteIndex @9 XML_GetCurrentColumnNumber @10 XML_GetCurrentLineNumber @11 XML_GetErrorCode @12 XML_GetIdAttributeIndex @13 XML_GetInputContext @14 XML_GetSpecifiedAttributeCount @15 XML_Parse @16 XML_ParseBuffer @17 XML_ParserCreate @18 XML_ParserCreateNS @19 XML_ParserCreate_MM @20 XML_ParserFree @21 XML_SetAttlistDeclHandler @22 XML_SetBase @23 XML_SetCdataSectionHandler @24 XML_SetCharacterDataHandler @25 XML_SetCommentHandler @26 XML_SetDefaultHandler @27 XML_SetDefaultHandlerExpand @28 XML_SetDoctypeDeclHandler @29 XML_SetElementDeclHandler @30 XML_SetElementHandler @31 XML_SetEncoding @32 XML_SetEndCdataSectionHandler @33 XML_SetEndDoctypeDeclHandler @34 XML_SetEndElementHandler @35 XML_SetEndNamespaceDeclHandler @36 XML_SetEntityDeclHandler @37 XML_SetExternalEntityRefHandler @38 XML_SetExternalEntityRefHandlerArg @39 XML_SetNamespaceDeclHandler @40 XML_SetNotStandaloneHandler @41 XML_SetNotationDeclHandler @42 XML_SetParamEntityParsing @43 XML_SetProcessingInstructionHandler @44 XML_SetReturnNSTriplet @45 XML_SetStartCdataSectionHandler @46 XML_SetStartDoctypeDeclHandler @47 XML_SetStartElementHandler @48 XML_SetStartNamespaceDeclHandler @49 XML_SetUnknownEncodingHandler @50 XML_SetUnparsedEntityDeclHandler @51 XML_SetUserData @52 XML_SetXmlDeclHandler @53 XML_UseParserAsHandlerArg @54 ; added with version 1.95.3 XML_ParserReset @55 XML_SetSkippedEntityHandler @56 ; added with version 1.95.5 XML_GetFeatureList @57 XML_UseForeignDTD @58 ; added with version 1.95.6 XML_FreeContentModel @59 XML_MemMalloc @60 XML_MemRealloc @61 XML_MemFree @62 ; added with version 1.95.8 XML_StopParser @63 XML_ResumeParser @64 XML_GetParsingStatus @65 ; added with version 2.1.1 ; XML_GetAttributeInfo @66 XML_SetHashSalt @67 ; added with version 2.2.5 _INTERNAL_trim_to_complete_utf8_characters @68 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/lib/libexpatw.def0000644000175100001710000000420400000000000020263 0ustar00vstsdocker; DEF file for MS VC++ LIBRARY EXPORTS XML_DefaultCurrent @1 XML_ErrorString @2 XML_ExpatVersion @3 XML_ExpatVersionInfo @4 XML_ExternalEntityParserCreate @5 XML_GetBase @6 XML_GetBuffer @7 XML_GetCurrentByteCount @8 XML_GetCurrentByteIndex @9 XML_GetCurrentColumnNumber @10 XML_GetCurrentLineNumber @11 XML_GetErrorCode @12 XML_GetIdAttributeIndex @13 XML_GetInputContext @14 XML_GetSpecifiedAttributeCount @15 XML_Parse @16 XML_ParseBuffer @17 XML_ParserCreate @18 XML_ParserCreateNS @19 XML_ParserCreate_MM @20 XML_ParserFree @21 XML_SetAttlistDeclHandler @22 XML_SetBase @23 XML_SetCdataSectionHandler @24 XML_SetCharacterDataHandler @25 XML_SetCommentHandler @26 XML_SetDefaultHandler @27 XML_SetDefaultHandlerExpand @28 XML_SetDoctypeDeclHandler @29 XML_SetElementDeclHandler @30 XML_SetElementHandler @31 XML_SetEncoding @32 XML_SetEndCdataSectionHandler @33 XML_SetEndDoctypeDeclHandler @34 XML_SetEndElementHandler @35 XML_SetEndNamespaceDeclHandler @36 XML_SetEntityDeclHandler @37 XML_SetExternalEntityRefHandler @38 XML_SetExternalEntityRefHandlerArg @39 XML_SetNamespaceDeclHandler @40 XML_SetNotStandaloneHandler @41 XML_SetNotationDeclHandler @42 XML_SetParamEntityParsing @43 XML_SetProcessingInstructionHandler @44 XML_SetReturnNSTriplet @45 XML_SetStartCdataSectionHandler @46 XML_SetStartDoctypeDeclHandler @47 XML_SetStartElementHandler @48 XML_SetStartNamespaceDeclHandler @49 XML_SetUnknownEncodingHandler @50 XML_SetUnparsedEntityDeclHandler @51 XML_SetUserData @52 XML_SetXmlDeclHandler @53 XML_UseParserAsHandlerArg @54 ; added with version 1.95.3 XML_ParserReset @55 XML_SetSkippedEntityHandler @56 ; added with version 1.95.5 XML_GetFeatureList @57 XML_UseForeignDTD @58 ; added with version 1.95.6 XML_FreeContentModel @59 XML_MemMalloc @60 XML_MemRealloc @61 XML_MemFree @62 ; added with version 1.95.8 XML_StopParser @63 XML_ResumeParser @64 XML_GetParsingStatus @65 ; added with version 2.1.1 ; XML_GetAttributeInfo @66 XML_SetHashSalt @67 ; added with version 2.2.5 _INTERNAL_trim_to_complete_utf8_characters @68 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/lib/nametab.h0000644000175100001710000002150200000000000017364 0ustar00vstsdocker/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000-2017 Expat development team Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ static const unsigned namingBitmap[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE, 0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF, 0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF, 0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD, 0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, 0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF, 0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE, 0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF, 0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000, 0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060, 0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003, 0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003, 0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000, 0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001, 0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003, 0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000, 0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003, 0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003, 0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000, 0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF, 0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB, 0x40000000, 0xF580C900, 0x00000007, 0x02010800, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF, 0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF, 0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF, 0x00000000, 0x00004C40, 0x00000000, 0x00000000, 0x00000007, 0x00000000, 0x00000000, 0x00000000, 0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF, 0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF, 0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000, 0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE, 0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF, 0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003, 0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD, 0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, 0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF, 0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE, 0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF, 0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF, 0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF, 0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF, 0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF, 0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0, 0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1, 0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3, 0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80, 0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3, 0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3, 0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000, 0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000, 0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF, 0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x1FFF0000, 0x00000002, 0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF, 0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF, }; static const unsigned char nmstrtPages[] = { 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; static const unsigned char namePages[] = { 0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00, 0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, 0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/lib/siphash.h0000644000175100001710000003165000000000000017421 0ustar00vstsdocker/* ========================================================================== * siphash.h - SipHash-2-4 in a single header file * -------------------------------------------------------------------------- * Derived by William Ahern from the reference implementation[1] published[2] * by Jean-Philippe Aumasson and Daniel J. Berstein. * Minimal changes by Sebastian Pipping and Victor Stinner on top, see below. * Licensed under the CC0 Public Domain Dedication license. * * 1. https://www.131002.net/siphash/siphash24.c * 2. https://www.131002.net/siphash/ * -------------------------------------------------------------------------- * HISTORY: * * 2019-08-03 (Sebastian Pipping) * - Mark part of sip24_valid as to be excluded from clang-format * - Re-format code using clang-format 9 * * 2018-07-08 (Anton Maklakov) * - Add "fall through" markers for GCC's -Wimplicit-fallthrough * * 2017-11-03 (Sebastian Pipping) * - Hide sip_tobin and sip_binof unless SIPHASH_TOBIN macro is defined * * 2017-07-25 (Vadim Zeitlin) * - Fix use of SIPHASH_MAIN macro * * 2017-07-05 (Sebastian Pipping) * - Use _SIP_ULL macro to not require a C++11 compiler if compiled as C++ * - Add const qualifiers at two places * - Ensure <=80 characters line length (assuming tab width 4) * * 2017-06-23 (Victor Stinner) * - Address Win64 compile warnings * * 2017-06-18 (Sebastian Pipping) * - Clarify license note in the header * - Address C89 issues: * - Stop using inline keyword (and let compiler decide) * - Replace _Bool by int * - Turn macro siphash24 into a function * - Address invalid conversion (void pointer) by explicit cast * - Address lack of stdint.h for Visual Studio 2003 to 2008 * - Always expose sip24_valid (for self-tests) * * 2012-11-04 - Born. (William Ahern) * -------------------------------------------------------------------------- * USAGE: * * SipHash-2-4 takes as input two 64-bit words as the key, some number of * message bytes, and outputs a 64-bit word as the message digest. This * implementation employs two data structures: a struct sipkey for * representing the key, and a struct siphash for representing the hash * state. * * For converting a 16-byte unsigned char array to a key, use either the * macro sip_keyof or the routine sip_tokey. The former instantiates a * compound literal key, while the latter requires a key object as a * parameter. * * unsigned char secret[16]; * arc4random_buf(secret, sizeof secret); * struct sipkey *key = sip_keyof(secret); * * For hashing a message, use either the convenience macro siphash24 or the * routines sip24_init, sip24_update, and sip24_final. * * struct siphash state; * void *msg; * size_t len; * uint64_t hash; * * sip24_init(&state, key); * sip24_update(&state, msg, len); * hash = sip24_final(&state); * * or * * hash = siphash24(msg, len, key); * * To convert the 64-bit hash value to a canonical 8-byte little-endian * binary representation, use either the macro sip_binof or the routine * sip_tobin. The former instantiates and returns a compound literal array, * while the latter requires an array object as a parameter. * -------------------------------------------------------------------------- * NOTES: * * o Neither sip_keyof, sip_binof, nor siphash24 will work with compilers * lacking compound literal support. Instead, you must use the lower-level * interfaces which take as parameters the temporary state objects. * * o Uppercase macros may evaluate parameters more than once. Lowercase * macros should not exhibit any such side effects. * ========================================================================== */ #ifndef SIPHASH_H #define SIPHASH_H #include /* size_t */ #if defined(_WIN32) && defined(_MSC_VER) && (_MSC_VER < 1600) /* For vs2003/7.1 up to vs2008/9.0; _MSC_VER 1600 is vs2010/10.0 */ typedef unsigned __int8 uint8_t; typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; #else # include /* uint64_t uint32_t uint8_t */ #endif /* * Workaround to not require a C++11 compiler for using ULL suffix * if this code is included and compiled as C++; related GCC warning is: * warning: use of C++11 long long integer constant [-Wlong-long] */ #define _SIP_ULL(high, low) (((uint64_t)high << 32) | low) #define SIP_ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b)))) #define SIP_U32TO8_LE(p, v) \ (p)[0] = (uint8_t)((v) >> 0); \ (p)[1] = (uint8_t)((v) >> 8); \ (p)[2] = (uint8_t)((v) >> 16); \ (p)[3] = (uint8_t)((v) >> 24); #define SIP_U64TO8_LE(p, v) \ SIP_U32TO8_LE((p) + 0, (uint32_t)((v) >> 0)); \ SIP_U32TO8_LE((p) + 4, (uint32_t)((v) >> 32)); #define SIP_U8TO64_LE(p) \ (((uint64_t)((p)[0]) << 0) | ((uint64_t)((p)[1]) << 8) \ | ((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) \ | ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) \ | ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56)) #define SIPHASH_INITIALIZER \ { 0, 0, 0, 0, {0}, 0, 0 } struct siphash { uint64_t v0, v1, v2, v3; unsigned char buf[8], *p; uint64_t c; }; /* struct siphash */ #define SIP_KEYLEN 16 struct sipkey { uint64_t k[2]; }; /* struct sipkey */ #define sip_keyof(k) sip_tokey(&(struct sipkey){{0}}, (k)) static struct sipkey * sip_tokey(struct sipkey *key, const void *src) { key->k[0] = SIP_U8TO64_LE((const unsigned char *)src); key->k[1] = SIP_U8TO64_LE((const unsigned char *)src + 8); return key; } /* sip_tokey() */ #ifdef SIPHASH_TOBIN # define sip_binof(v) sip_tobin((unsigned char[8]){0}, (v)) static void * sip_tobin(void *dst, uint64_t u64) { SIP_U64TO8_LE((unsigned char *)dst, u64); return dst; } /* sip_tobin() */ #endif /* SIPHASH_TOBIN */ static void sip_round(struct siphash *H, const int rounds) { int i; for (i = 0; i < rounds; i++) { H->v0 += H->v1; H->v1 = SIP_ROTL(H->v1, 13); H->v1 ^= H->v0; H->v0 = SIP_ROTL(H->v0, 32); H->v2 += H->v3; H->v3 = SIP_ROTL(H->v3, 16); H->v3 ^= H->v2; H->v0 += H->v3; H->v3 = SIP_ROTL(H->v3, 21); H->v3 ^= H->v0; H->v2 += H->v1; H->v1 = SIP_ROTL(H->v1, 17); H->v1 ^= H->v2; H->v2 = SIP_ROTL(H->v2, 32); } } /* sip_round() */ static struct siphash * sip24_init(struct siphash *H, const struct sipkey *key) { H->v0 = _SIP_ULL(0x736f6d65U, 0x70736575U) ^ key->k[0]; H->v1 = _SIP_ULL(0x646f7261U, 0x6e646f6dU) ^ key->k[1]; H->v2 = _SIP_ULL(0x6c796765U, 0x6e657261U) ^ key->k[0]; H->v3 = _SIP_ULL(0x74656462U, 0x79746573U) ^ key->k[1]; H->p = H->buf; H->c = 0; return H; } /* sip24_init() */ #define sip_endof(a) (&(a)[sizeof(a) / sizeof *(a)]) static struct siphash * sip24_update(struct siphash *H, const void *src, size_t len) { const unsigned char *p = (const unsigned char *)src, *pe = p + len; uint64_t m; do { while (p < pe && H->p < sip_endof(H->buf)) *H->p++ = *p++; if (H->p < sip_endof(H->buf)) break; m = SIP_U8TO64_LE(H->buf); H->v3 ^= m; sip_round(H, 2); H->v0 ^= m; H->p = H->buf; H->c += 8; } while (p < pe); return H; } /* sip24_update() */ static uint64_t sip24_final(struct siphash *H) { const char left = (char)(H->p - H->buf); uint64_t b = (H->c + left) << 56; switch (left) { case 7: b |= (uint64_t)H->buf[6] << 48; /* fall through */ case 6: b |= (uint64_t)H->buf[5] << 40; /* fall through */ case 5: b |= (uint64_t)H->buf[4] << 32; /* fall through */ case 4: b |= (uint64_t)H->buf[3] << 24; /* fall through */ case 3: b |= (uint64_t)H->buf[2] << 16; /* fall through */ case 2: b |= (uint64_t)H->buf[1] << 8; /* fall through */ case 1: b |= (uint64_t)H->buf[0] << 0; /* fall through */ case 0: break; } H->v3 ^= b; sip_round(H, 2); H->v0 ^= b; H->v2 ^= 0xff; sip_round(H, 4); return H->v0 ^ H->v1 ^ H->v2 ^ H->v3; } /* sip24_final() */ static uint64_t siphash24(const void *src, size_t len, const struct sipkey *key) { struct siphash state = SIPHASH_INITIALIZER; return sip24_final(sip24_update(sip24_init(&state, key), src, len)); } /* siphash24() */ /* * SipHash-2-4 output with * k = 00 01 02 ... * and * in = (empty string) * in = 00 (1 byte) * in = 00 01 (2 bytes) * in = 00 01 02 (3 bytes) * ... * in = 00 01 02 ... 3e (63 bytes) */ static int sip24_valid(void) { /* clang-format off */ static const unsigned char vectors[64][8] = { { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, }, { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, }, { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, }, { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, }, { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, }, { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, }, { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, }, { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, }, { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, }, { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, }, { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, }, { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, }, { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, }, { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, }, { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, }, { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, }, { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, }, { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, }, { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, }, { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, }, { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, }, { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, }, { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, }, { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, }, { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, }, { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, }, { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, }, { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, }, { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, }, { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, }, { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, }, { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, }, { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, }, { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, }, { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, }, { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, }, { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, }, { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, }, { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, }, { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, }, { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, }, { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, }, { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, }, { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, }, { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, }, { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, }, { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, }, { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, }, { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, }, { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, }, { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, }, { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, }, { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, }, { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, }, { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, }, { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, }, { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, }, { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, }, { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, }, { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, }, { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, }, { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, }, { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, }, { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, } }; /* clang-format on */ unsigned char in[64]; struct sipkey k; size_t i; sip_tokey(&k, "\000\001\002\003\004\005\006\007\010\011" "\012\013\014\015\016\017"); for (i = 0; i < sizeof in; ++i) { in[i] = (unsigned char)i; if (siphash24(in, i, &k) != SIP_U8TO64_LE(vectors[i])) return 0; } return 1; } /* sip24_valid() */ #ifdef SIPHASH_MAIN # include int main(void) { const int ok = sip24_valid(); if (ok) puts("OK"); else puts("FAIL"); return ! ok; } /* main() */ #endif /* SIPHASH_MAIN */ #endif /* SIPHASH_H */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/lib/utf8tab.h0000644000175100001710000000643100000000000017336 0ustar00vstsdocker/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000-2017 Expat development team Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, /* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, /* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, /* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, /* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, /* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, /* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, /* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, /* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, /* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, /* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, /* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, /* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4, /* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML, /* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM, ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/lib/winconfig.h0000644000175100001710000000406200000000000017742 0ustar00vstsdocker/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000-2017 Expat development team Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef WINCONFIG_H #define WINCONFIG_H #define WIN32_LEAN_AND_MEAN #include #undef WIN32_LEAN_AND_MEAN #include #include #if defined(HAVE_EXPAT_CONFIG_H) /* e.g. MinGW */ # include #else /* !defined(HAVE_EXPAT_CONFIG_H) */ # define XML_NS 1 # define XML_DTD 1 # define XML_CONTEXT_BYTES 1024 /* we will assume all Windows platforms are little endian */ # define BYTEORDER 1234 #endif /* !defined(HAVE_EXPAT_CONFIG_H) */ #endif /* ndef WINCONFIG_H */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/lib/xmlparse.c0000644000175100001710000072047400000000000017621 0ustar00vstsdocker/* f519f27c7c3b79fee55aeb8b1e53b7384b079d9118bf3a62eb3a60986a6742f2 (2.2.9+) __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000-2017 Expat development team Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #if ! defined(_GNU_SOURCE) # define _GNU_SOURCE 1 /* syscall prototype */ #endif #ifdef _WIN32 /* force stdlib to define rand_s() */ # if ! defined(_CRT_RAND_S) # define _CRT_RAND_S # endif #endif #include #include /* memset(), memcpy() */ #include #include /* UINT_MAX */ #include /* fprintf */ #include /* getenv, rand_s */ #ifdef _WIN32 # define getpid GetCurrentProcessId #else # include /* gettimeofday() */ # include /* getpid() */ # include /* getpid() */ # include /* O_RDONLY */ # include #endif #define XML_BUILDING_EXPAT 1 #ifdef _WIN32 # include "winconfig.h" #elif defined(HAVE_EXPAT_CONFIG_H) # include #endif /* ndef _WIN32 */ #include "ascii.h" #include "expat.h" #include "siphash.h" #if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) # if defined(HAVE_GETRANDOM) # include /* getrandom */ # else # include /* syscall */ # include /* SYS_getrandom */ # endif # if ! defined(GRND_NONBLOCK) # define GRND_NONBLOCK 0x0001 # endif /* defined(GRND_NONBLOCK) */ #endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */ #if defined(HAVE_LIBBSD) \ && (defined(HAVE_ARC4RANDOM_BUF) || defined(HAVE_ARC4RANDOM)) # include #endif #if defined(_WIN32) && ! defined(LOAD_LIBRARY_SEARCH_SYSTEM32) # define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 #endif #if ! defined(HAVE_GETRANDOM) && ! defined(HAVE_SYSCALL_GETRANDOM) \ && ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) \ && ! defined(XML_DEV_URANDOM) && ! defined(_WIN32) \ && ! defined(XML_POOR_ENTROPY) # error You do not have support for any sources of high quality entropy \ enabled. For end user security, that is probably not what you want. \ \ Your options include: \ * Linux + glibc >=2.25 (getrandom): HAVE_GETRANDOM, \ * Linux + glibc <2.25 (syscall SYS_getrandom): HAVE_SYSCALL_GETRANDOM, \ * BSD / macOS >=10.7 (arc4random_buf): HAVE_ARC4RANDOM_BUF, \ * BSD / macOS <10.7 (arc4random): HAVE_ARC4RANDOM, \ * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \ * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \ * Linux / BSD / macOS (/dev/urandom): XML_DEV_URANDOM \ * Windows (rand_s): _WIN32. \ \ If insist on not using any of these, bypass this error by defining \ XML_POOR_ENTROPY; you have been warned. \ \ If you have reasons to patch this detection code away or need changes \ to the build system, please open a bug. Thank you! #endif #ifdef XML_UNICODE # define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX # define XmlConvert XmlUtf16Convert # define XmlGetInternalEncoding XmlGetUtf16InternalEncoding # define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS # define XmlEncode XmlUtf16Encode /* Using pointer subtraction to convert to integer type. */ # define MUST_CONVERT(enc, s) \ (! (enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1)) typedef unsigned short ICHAR; #else # define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX # define XmlConvert XmlUtf8Convert # define XmlGetInternalEncoding XmlGetUtf8InternalEncoding # define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS # define XmlEncode XmlUtf8Encode # define MUST_CONVERT(enc, s) (! (enc)->isUtf8) typedef char ICHAR; #endif #ifndef XML_NS # define XmlInitEncodingNS XmlInitEncoding # define XmlInitUnknownEncodingNS XmlInitUnknownEncoding # undef XmlGetInternalEncodingNS # define XmlGetInternalEncodingNS XmlGetInternalEncoding # define XmlParseXmlDeclNS XmlParseXmlDecl #endif #ifdef XML_UNICODE # ifdef XML_UNICODE_WCHAR_T # define XML_T(x) (const wchar_t) x # define XML_L(x) L##x # else # define XML_T(x) (const unsigned short)x # define XML_L(x) x # endif #else # define XML_T(x) x # define XML_L(x) x #endif /* Round up n to be a multiple of sz, where sz is a power of 2. */ #define ROUND_UP(n, sz) (((n) + ((sz)-1)) & ~((sz)-1)) /* Do safe (NULL-aware) pointer arithmetic */ #define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)) ? ((p) - (q)) : 0) #include "internal.h" #include "xmltok.h" #include "xmlrole.h" typedef const XML_Char *KEY; typedef struct { KEY name; } NAMED; typedef struct { NAMED **v; unsigned char power; size_t size; size_t used; const XML_Memory_Handling_Suite *mem; } HASH_TABLE; static size_t keylen(KEY s); static void copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key); /* For probing (after a collision) we need a step size relative prime to the hash table size, which is a power of 2. We use double-hashing, since we can calculate a second hash value cheaply by taking those bits of the first hash value that were discarded (masked out) when the table index was calculated: index = hash & mask, where mask = table->size - 1. We limit the maximum step size to table->size / 4 (mask >> 2) and make it odd, since odd numbers are always relative prime to a power of 2. */ #define SECOND_HASH(hash, mask, power) \ ((((hash) & ~(mask)) >> ((power)-1)) & ((mask) >> 2)) #define PROBE_STEP(hash, mask, power) \ ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1)) typedef struct { NAMED **p; NAMED **end; } HASH_TABLE_ITER; #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */ #define INIT_DATA_BUF_SIZE 1024 #define INIT_ATTS_SIZE 16 #define INIT_ATTS_VERSION 0xFFFFFFFF #define INIT_BLOCK_SIZE 1024 #define INIT_BUFFER_SIZE 1024 #define EXPAND_SPARE 24 typedef struct binding { struct prefix *prefix; struct binding *nextTagBinding; struct binding *prevPrefixBinding; const struct attribute_id *attId; XML_Char *uri; int uriLen; int uriAlloc; } BINDING; typedef struct prefix { const XML_Char *name; BINDING *binding; } PREFIX; typedef struct { const XML_Char *str; const XML_Char *localPart; const XML_Char *prefix; int strLen; int uriLen; int prefixLen; } TAG_NAME; /* TAG represents an open element. The name of the element is stored in both the document and API encodings. The memory buffer 'buf' is a separately-allocated memory area which stores the name. During the XML_Parse()/ XMLParseBuffer() when the element is open, the memory for the 'raw' version of the name (in the document encoding) is shared with the document buffer. If the element is open across calls to XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to contain the 'raw' name as well. A parser re-uses these structures, maintaining a list of allocated TAG objects in a free list. */ typedef struct tag { struct tag *parent; /* parent of this element */ const char *rawName; /* tagName in the original encoding */ int rawNameLength; TAG_NAME name; /* tagName in the API encoding */ char *buf; /* buffer for name components */ char *bufEnd; /* end of the buffer */ BINDING *bindings; } TAG; typedef struct { const XML_Char *name; const XML_Char *textPtr; int textLen; /* length in XML_Chars */ int processed; /* # of processed bytes - when suspended */ const XML_Char *systemId; const XML_Char *base; const XML_Char *publicId; const XML_Char *notation; XML_Bool open; XML_Bool is_param; XML_Bool is_internal; /* true if declared in internal subset outside PE */ } ENTITY; typedef struct { enum XML_Content_Type type; enum XML_Content_Quant quant; const XML_Char *name; int firstchild; int lastchild; int childcnt; int nextsib; } CONTENT_SCAFFOLD; #define INIT_SCAFFOLD_ELEMENTS 32 typedef struct block { struct block *next; int size; XML_Char s[1]; } BLOCK; typedef struct { BLOCK *blocks; BLOCK *freeBlocks; const XML_Char *end; XML_Char *ptr; XML_Char *start; const XML_Memory_Handling_Suite *mem; } STRING_POOL; /* The XML_Char before the name is used to determine whether an attribute has been specified. */ typedef struct attribute_id { XML_Char *name; PREFIX *prefix; XML_Bool maybeTokenized; XML_Bool xmlns; } ATTRIBUTE_ID; typedef struct { const ATTRIBUTE_ID *id; XML_Bool isCdata; const XML_Char *value; } DEFAULT_ATTRIBUTE; typedef struct { unsigned long version; unsigned long hash; const XML_Char *uriName; } NS_ATT; typedef struct { const XML_Char *name; PREFIX *prefix; const ATTRIBUTE_ID *idAtt; int nDefaultAtts; int allocDefaultAtts; DEFAULT_ATTRIBUTE *defaultAtts; } ELEMENT_TYPE; typedef struct { HASH_TABLE generalEntities; HASH_TABLE elementTypes; HASH_TABLE attributeIds; HASH_TABLE prefixes; STRING_POOL pool; STRING_POOL entityValuePool; /* false once a parameter entity reference has been skipped */ XML_Bool keepProcessing; /* true once an internal or external PE reference has been encountered; this includes the reference to an external subset */ XML_Bool hasParamEntityRefs; XML_Bool standalone; #ifdef XML_DTD /* indicates if external PE has been read */ XML_Bool paramEntityRead; HASH_TABLE paramEntities; #endif /* XML_DTD */ PREFIX defaultPrefix; /* === scaffolding for building content model === */ XML_Bool in_eldecl; CONTENT_SCAFFOLD *scaffold; unsigned contentStringLen; unsigned scaffSize; unsigned scaffCount; int scaffLevel; int *scaffIndex; } DTD; typedef struct open_internal_entity { const char *internalEventPtr; const char *internalEventEndPtr; struct open_internal_entity *next; ENTITY *entity; int startTagLevel; XML_Bool betweenDecl; /* WFC: PE Between Declarations */ } OPEN_INTERNAL_ENTITY; typedef enum XML_Error PTRCALL Processor(XML_Parser parser, const char *start, const char *end, const char **endPtr); static Processor prologProcessor; static Processor prologInitProcessor; static Processor contentProcessor; static Processor cdataSectionProcessor; #ifdef XML_DTD static Processor ignoreSectionProcessor; static Processor externalParEntProcessor; static Processor externalParEntInitProcessor; static Processor entityValueProcessor; static Processor entityValueInitProcessor; #endif /* XML_DTD */ static Processor epilogProcessor; static Processor errorProcessor; static Processor externalEntityInitProcessor; static Processor externalEntityInitProcessor2; static Processor externalEntityInitProcessor3; static Processor externalEntityContentProcessor; static Processor internalEntityProcessor; static enum XML_Error handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName); static enum XML_Error processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *s, const char *next); static enum XML_Error initializeEncoding(XML_Parser parser); static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, int tok, const char *next, const char **nextPtr, XML_Bool haveMore, XML_Bool allowClosingDoctype); static enum XML_Error processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl); static enum XML_Error doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, const char *start, const char *end, const char **endPtr, XML_Bool haveMore); static enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr, XML_Bool haveMore); #ifdef XML_DTD static enum XML_Error doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr, XML_Bool haveMore); #endif /* XML_DTD */ static void freeBindings(XML_Parser parser, BINDING *bindings); static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const char *s, TAG_NAME *tagNamePtr, BINDING **bindingsPtr); static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr); static int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata, XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser); static enum XML_Error storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata, const char *, const char *, STRING_POOL *); static enum XML_Error appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata, const char *, const char *, STRING_POOL *); static ATTRIBUTE_ID *getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *); static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); static int reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); static void reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); static const XML_Char *getContext(XML_Parser parser); static XML_Bool setContext(XML_Parser parser, const XML_Char *context); static void FASTCALL normalizePublicId(XML_Char *s); static DTD *dtdCreate(const XML_Memory_Handling_Suite *ms); /* do not call if m_parentParser != NULL */ static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms); static void dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms); static int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms); static int copyEntityTable(XML_Parser oldParser, HASH_TABLE *, STRING_POOL *, const HASH_TABLE *); static NAMED *lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize); static void FASTCALL hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms); static void FASTCALL hashTableClear(HASH_TABLE *); static void FASTCALL hashTableDestroy(HASH_TABLE *); static void FASTCALL hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *); static NAMED *FASTCALL hashTableIterNext(HASH_TABLE_ITER *); static void FASTCALL poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms); static void FASTCALL poolClear(STRING_POOL *); static void FASTCALL poolDestroy(STRING_POOL *); static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc, const char *ptr, const char *end); static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc, const char *ptr, const char *end); static XML_Bool FASTCALL poolGrow(STRING_POOL *pool); static const XML_Char *FASTCALL poolCopyString(STRING_POOL *pool, const XML_Char *s); static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n); static const XML_Char *FASTCALL poolAppendString(STRING_POOL *pool, const XML_Char *s); static int FASTCALL nextScaffoldPart(XML_Parser parser); static XML_Content *build_model(XML_Parser parser); static ELEMENT_TYPE *getElementType(XML_Parser parser, const ENCODING *enc, const char *ptr, const char *end); static XML_Char *copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite); static unsigned long generate_hash_secret_salt(XML_Parser parser); static XML_Bool startParsing(XML_Parser parser); static XML_Parser parserCreate(const XML_Char *encodingName, const XML_Memory_Handling_Suite *memsuite, const XML_Char *nameSep, DTD *dtd); static void parserInit(XML_Parser parser, const XML_Char *encodingName); #define poolStart(pool) ((pool)->start) #define poolEnd(pool) ((pool)->ptr) #define poolLength(pool) ((pool)->ptr - (pool)->start) #define poolChop(pool) ((void)--(pool->ptr)) #define poolLastChar(pool) (((pool)->ptr)[-1]) #define poolDiscard(pool) ((pool)->ptr = (pool)->start) #define poolFinish(pool) ((pool)->start = (pool)->ptr) #define poolAppendChar(pool, c) \ (((pool)->ptr == (pool)->end && ! poolGrow(pool)) \ ? 0 \ : ((*((pool)->ptr)++ = c), 1)) struct XML_ParserStruct { /* The first member must be m_userData so that the XML_GetUserData macro works. */ void *m_userData; void *m_handlerArg; char *m_buffer; const XML_Memory_Handling_Suite m_mem; /* first character to be parsed */ const char *m_bufferPtr; /* past last character to be parsed */ char *m_bufferEnd; /* allocated end of m_buffer */ const char *m_bufferLim; XML_Index m_parseEndByteIndex; const char *m_parseEndPtr; XML_Char *m_dataBuf; XML_Char *m_dataBufEnd; XML_StartElementHandler m_startElementHandler; XML_EndElementHandler m_endElementHandler; XML_CharacterDataHandler m_characterDataHandler; XML_ProcessingInstructionHandler m_processingInstructionHandler; XML_CommentHandler m_commentHandler; XML_StartCdataSectionHandler m_startCdataSectionHandler; XML_EndCdataSectionHandler m_endCdataSectionHandler; XML_DefaultHandler m_defaultHandler; XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler; XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler; XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler; XML_NotationDeclHandler m_notationDeclHandler; XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler; XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler; XML_NotStandaloneHandler m_notStandaloneHandler; XML_ExternalEntityRefHandler m_externalEntityRefHandler; XML_Parser m_externalEntityRefHandlerArg; XML_SkippedEntityHandler m_skippedEntityHandler; XML_UnknownEncodingHandler m_unknownEncodingHandler; XML_ElementDeclHandler m_elementDeclHandler; XML_AttlistDeclHandler m_attlistDeclHandler; XML_EntityDeclHandler m_entityDeclHandler; XML_XmlDeclHandler m_xmlDeclHandler; const ENCODING *m_encoding; INIT_ENCODING m_initEncoding; const ENCODING *m_internalEncoding; const XML_Char *m_protocolEncodingName; XML_Bool m_ns; XML_Bool m_ns_triplets; void *m_unknownEncodingMem; void *m_unknownEncodingData; void *m_unknownEncodingHandlerData; void(XMLCALL *m_unknownEncodingRelease)(void *); PROLOG_STATE m_prologState; Processor *m_processor; enum XML_Error m_errorCode; const char *m_eventPtr; const char *m_eventEndPtr; const char *m_positionPtr; OPEN_INTERNAL_ENTITY *m_openInternalEntities; OPEN_INTERNAL_ENTITY *m_freeInternalEntities; XML_Bool m_defaultExpandInternalEntities; int m_tagLevel; ENTITY *m_declEntity; const XML_Char *m_doctypeName; const XML_Char *m_doctypeSysid; const XML_Char *m_doctypePubid; const XML_Char *m_declAttributeType; const XML_Char *m_declNotationName; const XML_Char *m_declNotationPublicId; ELEMENT_TYPE *m_declElementType; ATTRIBUTE_ID *m_declAttributeId; XML_Bool m_declAttributeIsCdata; XML_Bool m_declAttributeIsId; DTD *m_dtd; const XML_Char *m_curBase; TAG *m_tagStack; TAG *m_freeTagList; BINDING *m_inheritedBindings; BINDING *m_freeBindingList; int m_attsSize; int m_nSpecifiedAtts; int m_idAttIndex; ATTRIBUTE *m_atts; NS_ATT *m_nsAtts; unsigned long m_nsAttsVersion; unsigned char m_nsAttsPower; #ifdef XML_ATTR_INFO XML_AttrInfo *m_attInfo; #endif POSITION m_position; STRING_POOL m_tempPool; STRING_POOL m_temp2Pool; char *m_groupConnector; unsigned int m_groupSize; XML_Char m_namespaceSeparator; XML_Parser m_parentParser; XML_ParsingStatus m_parsingStatus; #ifdef XML_DTD XML_Bool m_isParamEntity; XML_Bool m_useForeignDTD; enum XML_ParamEntityParsing m_paramEntityParsing; #endif unsigned long m_hash_secret_salt; }; #define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s))) #define REALLOC(parser, p, s) (parser->m_mem.realloc_fcn((p), (s))) #define FREE(parser, p) (parser->m_mem.free_fcn((p))) XML_Parser XMLCALL XML_ParserCreate(const XML_Char *encodingName) { return XML_ParserCreate_MM(encodingName, NULL, NULL); } XML_Parser XMLCALL XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) { XML_Char tmp[2]; *tmp = nsSep; return XML_ParserCreate_MM(encodingName, NULL, tmp); } static const XML_Char implicitContext[] = {ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'}; /* To avoid warnings about unused functions: */ #if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) # if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) /* Obtain entropy on Linux 3.17+ */ static int writeRandomBytes_getrandom_nonblock(void *target, size_t count) { int success = 0; /* full count bytes written? */ size_t bytesWrittenTotal = 0; const unsigned int getrandomFlags = GRND_NONBLOCK; do { void *const currentTarget = (void *)((char *)target + bytesWrittenTotal); const size_t bytesToWrite = count - bytesWrittenTotal; const int bytesWrittenMore = # if defined(HAVE_GETRANDOM) getrandom(currentTarget, bytesToWrite, getrandomFlags); # else syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags); # endif if (bytesWrittenMore > 0) { bytesWrittenTotal += bytesWrittenMore; if (bytesWrittenTotal >= count) success = 1; } } while (! success && (errno == EINTR)); return success; } # endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */ # if ! defined(_WIN32) && defined(XML_DEV_URANDOM) /* Extract entropy from /dev/urandom */ static int writeRandomBytes_dev_urandom(void *target, size_t count) { int success = 0; /* full count bytes written? */ size_t bytesWrittenTotal = 0; const int fd = open("/dev/urandom", O_RDONLY); if (fd < 0) { return 0; } do { void *const currentTarget = (void *)((char *)target + bytesWrittenTotal); const size_t bytesToWrite = count - bytesWrittenTotal; const ssize_t bytesWrittenMore = read(fd, currentTarget, bytesToWrite); if (bytesWrittenMore > 0) { bytesWrittenTotal += bytesWrittenMore; if (bytesWrittenTotal >= count) success = 1; } } while (! success && (errno == EINTR)); close(fd); return success; } # endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */ #endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */ #if defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF) static void writeRandomBytes_arc4random(void *target, size_t count) { size_t bytesWrittenTotal = 0; while (bytesWrittenTotal < count) { const uint32_t random32 = arc4random(); size_t i = 0; for (; (i < sizeof(random32)) && (bytesWrittenTotal < count); i++, bytesWrittenTotal++) { const uint8_t random8 = (uint8_t)(random32 >> (i * 8)); ((uint8_t *)target)[bytesWrittenTotal] = random8; } } } #endif /* defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF) */ #ifdef _WIN32 /* Obtain entropy on Windows using the rand_s() function which * generates cryptographically secure random numbers. Internally it * uses RtlGenRandom API which is present in Windows XP and later. */ static int writeRandomBytes_rand_s(void *target, size_t count) { size_t bytesWrittenTotal = 0; while (bytesWrittenTotal < count) { unsigned int random32 = 0; size_t i = 0; if (rand_s(&random32)) return 0; /* failure */ for (; (i < sizeof(random32)) && (bytesWrittenTotal < count); i++, bytesWrittenTotal++) { const uint8_t random8 = (uint8_t)(random32 >> (i * 8)); ((uint8_t *)target)[bytesWrittenTotal] = random8; } } return 1; /* success */ } #endif /* _WIN32 */ #if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) static unsigned long gather_time_entropy(void) { # ifdef _WIN32 FILETIME ft; GetSystemTimeAsFileTime(&ft); /* never fails */ return ft.dwHighDateTime ^ ft.dwLowDateTime; # else struct timeval tv; int gettimeofday_res; gettimeofday_res = gettimeofday(&tv, NULL); # if defined(NDEBUG) (void)gettimeofday_res; # else assert(gettimeofday_res == 0); # endif /* defined(NDEBUG) */ /* Microseconds time is <20 bits entropy */ return tv.tv_usec; # endif } #endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */ static unsigned long ENTROPY_DEBUG(const char *label, unsigned long entropy) { const char *const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG"); if (EXPAT_ENTROPY_DEBUG && ! strcmp(EXPAT_ENTROPY_DEBUG, "1")) { fprintf(stderr, "Entropy: %s --> 0x%0*lx (%lu bytes)\n", label, (int)sizeof(entropy) * 2, entropy, (unsigned long)sizeof(entropy)); } return entropy; } static unsigned long generate_hash_secret_salt(XML_Parser parser) { unsigned long entropy; (void)parser; /* "Failproof" high quality providers: */ #if defined(HAVE_ARC4RANDOM_BUF) arc4random_buf(&entropy, sizeof(entropy)); return ENTROPY_DEBUG("arc4random_buf", entropy); #elif defined(HAVE_ARC4RANDOM) writeRandomBytes_arc4random((void *)&entropy, sizeof(entropy)); return ENTROPY_DEBUG("arc4random", entropy); #else /* Try high quality providers first .. */ # ifdef _WIN32 if (writeRandomBytes_rand_s((void *)&entropy, sizeof(entropy))) { return ENTROPY_DEBUG("rand_s", entropy); } # elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) if (writeRandomBytes_getrandom_nonblock((void *)&entropy, sizeof(entropy))) { return ENTROPY_DEBUG("getrandom", entropy); } # endif # if ! defined(_WIN32) && defined(XML_DEV_URANDOM) if (writeRandomBytes_dev_urandom((void *)&entropy, sizeof(entropy))) { return ENTROPY_DEBUG("/dev/urandom", entropy); } # endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */ /* .. and self-made low quality for backup: */ /* Process ID is 0 bits entropy if attacker has local access */ entropy = gather_time_entropy() ^ getpid(); /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */ if (sizeof(unsigned long) == 4) { return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647); } else { return ENTROPY_DEBUG("fallback(8)", entropy * (unsigned long)2305843009213693951ULL); } #endif } static unsigned long get_hash_secret_salt(XML_Parser parser) { if (parser->m_parentParser != NULL) return get_hash_secret_salt(parser->m_parentParser); return parser->m_hash_secret_salt; } static XML_Bool /* only valid for root parser */ startParsing(XML_Parser parser) { /* hash functions must be initialized before setContext() is called */ if (parser->m_hash_secret_salt == 0) parser->m_hash_secret_salt = generate_hash_secret_salt(parser); if (parser->m_ns) { /* implicit context only set for root parser, since child parsers (i.e. external entity parsers) will inherit it */ return setContext(parser, implicitContext); } return XML_TRUE; } XML_Parser XMLCALL XML_ParserCreate_MM(const XML_Char *encodingName, const XML_Memory_Handling_Suite *memsuite, const XML_Char *nameSep) { return parserCreate(encodingName, memsuite, nameSep, NULL); } static XML_Parser parserCreate(const XML_Char *encodingName, const XML_Memory_Handling_Suite *memsuite, const XML_Char *nameSep, DTD *dtd) { XML_Parser parser; if (memsuite) { XML_Memory_Handling_Suite *mtemp; parser = (XML_Parser)memsuite->malloc_fcn(sizeof(struct XML_ParserStruct)); if (parser != NULL) { mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem); mtemp->malloc_fcn = memsuite->malloc_fcn; mtemp->realloc_fcn = memsuite->realloc_fcn; mtemp->free_fcn = memsuite->free_fcn; } } else { XML_Memory_Handling_Suite *mtemp; parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct)); if (parser != NULL) { mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem); mtemp->malloc_fcn = malloc; mtemp->realloc_fcn = realloc; mtemp->free_fcn = free; } } if (! parser) return parser; parser->m_buffer = NULL; parser->m_bufferLim = NULL; parser->m_attsSize = INIT_ATTS_SIZE; parser->m_atts = (ATTRIBUTE *)MALLOC(parser, parser->m_attsSize * sizeof(ATTRIBUTE)); if (parser->m_atts == NULL) { FREE(parser, parser); return NULL; } #ifdef XML_ATTR_INFO parser->m_attInfo = (XML_AttrInfo *)MALLOC( parser, parser->m_attsSize * sizeof(XML_AttrInfo)); if (parser->m_attInfo == NULL) { FREE(parser, parser->m_atts); FREE(parser, parser); return NULL; } #endif parser->m_dataBuf = (XML_Char *)MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char)); if (parser->m_dataBuf == NULL) { FREE(parser, parser->m_atts); #ifdef XML_ATTR_INFO FREE(parser, parser->m_attInfo); #endif FREE(parser, parser); return NULL; } parser->m_dataBufEnd = parser->m_dataBuf + INIT_DATA_BUF_SIZE; if (dtd) parser->m_dtd = dtd; else { parser->m_dtd = dtdCreate(&parser->m_mem); if (parser->m_dtd == NULL) { FREE(parser, parser->m_dataBuf); FREE(parser, parser->m_atts); #ifdef XML_ATTR_INFO FREE(parser, parser->m_attInfo); #endif FREE(parser, parser); return NULL; } } parser->m_freeBindingList = NULL; parser->m_freeTagList = NULL; parser->m_freeInternalEntities = NULL; parser->m_groupSize = 0; parser->m_groupConnector = NULL; parser->m_unknownEncodingHandler = NULL; parser->m_unknownEncodingHandlerData = NULL; parser->m_namespaceSeparator = ASCII_EXCL; parser->m_ns = XML_FALSE; parser->m_ns_triplets = XML_FALSE; parser->m_nsAtts = NULL; parser->m_nsAttsVersion = 0; parser->m_nsAttsPower = 0; parser->m_protocolEncodingName = NULL; poolInit(&parser->m_tempPool, &(parser->m_mem)); poolInit(&parser->m_temp2Pool, &(parser->m_mem)); parserInit(parser, encodingName); if (encodingName && ! parser->m_protocolEncodingName) { XML_ParserFree(parser); return NULL; } if (nameSep) { parser->m_ns = XML_TRUE; parser->m_internalEncoding = XmlGetInternalEncodingNS(); parser->m_namespaceSeparator = *nameSep; } else { parser->m_internalEncoding = XmlGetInternalEncoding(); } return parser; } static void parserInit(XML_Parser parser, const XML_Char *encodingName) { parser->m_processor = prologInitProcessor; XmlPrologStateInit(&parser->m_prologState); if (encodingName != NULL) { parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem)); } parser->m_curBase = NULL; XmlInitEncoding(&parser->m_initEncoding, &parser->m_encoding, 0); parser->m_userData = NULL; parser->m_handlerArg = NULL; parser->m_startElementHandler = NULL; parser->m_endElementHandler = NULL; parser->m_characterDataHandler = NULL; parser->m_processingInstructionHandler = NULL; parser->m_commentHandler = NULL; parser->m_startCdataSectionHandler = NULL; parser->m_endCdataSectionHandler = NULL; parser->m_defaultHandler = NULL; parser->m_startDoctypeDeclHandler = NULL; parser->m_endDoctypeDeclHandler = NULL; parser->m_unparsedEntityDeclHandler = NULL; parser->m_notationDeclHandler = NULL; parser->m_startNamespaceDeclHandler = NULL; parser->m_endNamespaceDeclHandler = NULL; parser->m_notStandaloneHandler = NULL; parser->m_externalEntityRefHandler = NULL; parser->m_externalEntityRefHandlerArg = parser; parser->m_skippedEntityHandler = NULL; parser->m_elementDeclHandler = NULL; parser->m_attlistDeclHandler = NULL; parser->m_entityDeclHandler = NULL; parser->m_xmlDeclHandler = NULL; parser->m_bufferPtr = parser->m_buffer; parser->m_bufferEnd = parser->m_buffer; parser->m_parseEndByteIndex = 0; parser->m_parseEndPtr = NULL; parser->m_declElementType = NULL; parser->m_declAttributeId = NULL; parser->m_declEntity = NULL; parser->m_doctypeName = NULL; parser->m_doctypeSysid = NULL; parser->m_doctypePubid = NULL; parser->m_declAttributeType = NULL; parser->m_declNotationName = NULL; parser->m_declNotationPublicId = NULL; parser->m_declAttributeIsCdata = XML_FALSE; parser->m_declAttributeIsId = XML_FALSE; memset(&parser->m_position, 0, sizeof(POSITION)); parser->m_errorCode = XML_ERROR_NONE; parser->m_eventPtr = NULL; parser->m_eventEndPtr = NULL; parser->m_positionPtr = NULL; parser->m_openInternalEntities = NULL; parser->m_defaultExpandInternalEntities = XML_TRUE; parser->m_tagLevel = 0; parser->m_tagStack = NULL; parser->m_inheritedBindings = NULL; parser->m_nSpecifiedAtts = 0; parser->m_unknownEncodingMem = NULL; parser->m_unknownEncodingRelease = NULL; parser->m_unknownEncodingData = NULL; parser->m_parentParser = NULL; parser->m_parsingStatus.parsing = XML_INITIALIZED; #ifdef XML_DTD parser->m_isParamEntity = XML_FALSE; parser->m_useForeignDTD = XML_FALSE; parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; #endif parser->m_hash_secret_salt = 0; } /* moves list of bindings to m_freeBindingList */ static void FASTCALL moveToFreeBindingList(XML_Parser parser, BINDING *bindings) { while (bindings) { BINDING *b = bindings; bindings = bindings->nextTagBinding; b->nextTagBinding = parser->m_freeBindingList; parser->m_freeBindingList = b; } } XML_Bool XMLCALL XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) { TAG *tStk; OPEN_INTERNAL_ENTITY *openEntityList; if (parser == NULL) return XML_FALSE; if (parser->m_parentParser) return XML_FALSE; /* move m_tagStack to m_freeTagList */ tStk = parser->m_tagStack; while (tStk) { TAG *tag = tStk; tStk = tStk->parent; tag->parent = parser->m_freeTagList; moveToFreeBindingList(parser, tag->bindings); tag->bindings = NULL; parser->m_freeTagList = tag; } /* move m_openInternalEntities to m_freeInternalEntities */ openEntityList = parser->m_openInternalEntities; while (openEntityList) { OPEN_INTERNAL_ENTITY *openEntity = openEntityList; openEntityList = openEntity->next; openEntity->next = parser->m_freeInternalEntities; parser->m_freeInternalEntities = openEntity; } moveToFreeBindingList(parser, parser->m_inheritedBindings); FREE(parser, parser->m_unknownEncodingMem); if (parser->m_unknownEncodingRelease) parser->m_unknownEncodingRelease(parser->m_unknownEncodingData); poolClear(&parser->m_tempPool); poolClear(&parser->m_temp2Pool); FREE(parser, (void *)parser->m_protocolEncodingName); parser->m_protocolEncodingName = NULL; parserInit(parser, encodingName); dtdReset(parser->m_dtd, &parser->m_mem); return XML_TRUE; } enum XML_Status XMLCALL XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) { if (parser == NULL) return XML_STATUS_ERROR; /* Block after XML_Parse()/XML_ParseBuffer() has been called. XXX There's no way for the caller to determine which of the XXX possible error cases caused the XML_STATUS_ERROR return. */ if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED) return XML_STATUS_ERROR; /* Get rid of any previous encoding name */ FREE(parser, (void *)parser->m_protocolEncodingName); if (encodingName == NULL) /* No new encoding name */ parser->m_protocolEncodingName = NULL; else { /* Copy the new encoding name into allocated memory */ parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem)); if (! parser->m_protocolEncodingName) return XML_STATUS_ERROR; } return XML_STATUS_OK; } XML_Parser XMLCALL XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context, const XML_Char *encodingName) { XML_Parser parser = oldParser; DTD *newDtd = NULL; DTD *oldDtd; XML_StartElementHandler oldStartElementHandler; XML_EndElementHandler oldEndElementHandler; XML_CharacterDataHandler oldCharacterDataHandler; XML_ProcessingInstructionHandler oldProcessingInstructionHandler; XML_CommentHandler oldCommentHandler; XML_StartCdataSectionHandler oldStartCdataSectionHandler; XML_EndCdataSectionHandler oldEndCdataSectionHandler; XML_DefaultHandler oldDefaultHandler; XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler; XML_NotationDeclHandler oldNotationDeclHandler; XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler; XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler; XML_NotStandaloneHandler oldNotStandaloneHandler; XML_ExternalEntityRefHandler oldExternalEntityRefHandler; XML_SkippedEntityHandler oldSkippedEntityHandler; XML_UnknownEncodingHandler oldUnknownEncodingHandler; XML_ElementDeclHandler oldElementDeclHandler; XML_AttlistDeclHandler oldAttlistDeclHandler; XML_EntityDeclHandler oldEntityDeclHandler; XML_XmlDeclHandler oldXmlDeclHandler; ELEMENT_TYPE *oldDeclElementType; void *oldUserData; void *oldHandlerArg; XML_Bool oldDefaultExpandInternalEntities; XML_Parser oldExternalEntityRefHandlerArg; #ifdef XML_DTD enum XML_ParamEntityParsing oldParamEntityParsing; int oldInEntityValue; #endif XML_Bool oldns_triplets; /* Note that the new parser shares the same hash secret as the old parser, so that dtdCopy and copyEntityTable can lookup values from hash tables associated with either parser without us having to worry which hash secrets each table has. */ unsigned long oldhash_secret_salt; /* Validate the oldParser parameter before we pull everything out of it */ if (oldParser == NULL) return NULL; /* Stash the original parser contents on the stack */ oldDtd = parser->m_dtd; oldStartElementHandler = parser->m_startElementHandler; oldEndElementHandler = parser->m_endElementHandler; oldCharacterDataHandler = parser->m_characterDataHandler; oldProcessingInstructionHandler = parser->m_processingInstructionHandler; oldCommentHandler = parser->m_commentHandler; oldStartCdataSectionHandler = parser->m_startCdataSectionHandler; oldEndCdataSectionHandler = parser->m_endCdataSectionHandler; oldDefaultHandler = parser->m_defaultHandler; oldUnparsedEntityDeclHandler = parser->m_unparsedEntityDeclHandler; oldNotationDeclHandler = parser->m_notationDeclHandler; oldStartNamespaceDeclHandler = parser->m_startNamespaceDeclHandler; oldEndNamespaceDeclHandler = parser->m_endNamespaceDeclHandler; oldNotStandaloneHandler = parser->m_notStandaloneHandler; oldExternalEntityRefHandler = parser->m_externalEntityRefHandler; oldSkippedEntityHandler = parser->m_skippedEntityHandler; oldUnknownEncodingHandler = parser->m_unknownEncodingHandler; oldElementDeclHandler = parser->m_elementDeclHandler; oldAttlistDeclHandler = parser->m_attlistDeclHandler; oldEntityDeclHandler = parser->m_entityDeclHandler; oldXmlDeclHandler = parser->m_xmlDeclHandler; oldDeclElementType = parser->m_declElementType; oldUserData = parser->m_userData; oldHandlerArg = parser->m_handlerArg; oldDefaultExpandInternalEntities = parser->m_defaultExpandInternalEntities; oldExternalEntityRefHandlerArg = parser->m_externalEntityRefHandlerArg; #ifdef XML_DTD oldParamEntityParsing = parser->m_paramEntityParsing; oldInEntityValue = parser->m_prologState.inEntityValue; #endif oldns_triplets = parser->m_ns_triplets; /* Note that the new parser shares the same hash secret as the old parser, so that dtdCopy and copyEntityTable can lookup values from hash tables associated with either parser without us having to worry which hash secrets each table has. */ oldhash_secret_salt = parser->m_hash_secret_salt; #ifdef XML_DTD if (! context) newDtd = oldDtd; #endif /* XML_DTD */ /* Note that the magical uses of the pre-processor to make field access look more like C++ require that `parser' be overwritten here. This makes this function more painful to follow than it would be otherwise. */ if (parser->m_ns) { XML_Char tmp[2]; *tmp = parser->m_namespaceSeparator; parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd); } else { parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd); } if (! parser) return NULL; parser->m_startElementHandler = oldStartElementHandler; parser->m_endElementHandler = oldEndElementHandler; parser->m_characterDataHandler = oldCharacterDataHandler; parser->m_processingInstructionHandler = oldProcessingInstructionHandler; parser->m_commentHandler = oldCommentHandler; parser->m_startCdataSectionHandler = oldStartCdataSectionHandler; parser->m_endCdataSectionHandler = oldEndCdataSectionHandler; parser->m_defaultHandler = oldDefaultHandler; parser->m_unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler; parser->m_notationDeclHandler = oldNotationDeclHandler; parser->m_startNamespaceDeclHandler = oldStartNamespaceDeclHandler; parser->m_endNamespaceDeclHandler = oldEndNamespaceDeclHandler; parser->m_notStandaloneHandler = oldNotStandaloneHandler; parser->m_externalEntityRefHandler = oldExternalEntityRefHandler; parser->m_skippedEntityHandler = oldSkippedEntityHandler; parser->m_unknownEncodingHandler = oldUnknownEncodingHandler; parser->m_elementDeclHandler = oldElementDeclHandler; parser->m_attlistDeclHandler = oldAttlistDeclHandler; parser->m_entityDeclHandler = oldEntityDeclHandler; parser->m_xmlDeclHandler = oldXmlDeclHandler; parser->m_declElementType = oldDeclElementType; parser->m_userData = oldUserData; if (oldUserData == oldHandlerArg) parser->m_handlerArg = parser->m_userData; else parser->m_handlerArg = parser; if (oldExternalEntityRefHandlerArg != oldParser) parser->m_externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg; parser->m_defaultExpandInternalEntities = oldDefaultExpandInternalEntities; parser->m_ns_triplets = oldns_triplets; parser->m_hash_secret_salt = oldhash_secret_salt; parser->m_parentParser = oldParser; #ifdef XML_DTD parser->m_paramEntityParsing = oldParamEntityParsing; parser->m_prologState.inEntityValue = oldInEntityValue; if (context) { #endif /* XML_DTD */ if (! dtdCopy(oldParser, parser->m_dtd, oldDtd, &parser->m_mem) || ! setContext(parser, context)) { XML_ParserFree(parser); return NULL; } parser->m_processor = externalEntityInitProcessor; #ifdef XML_DTD } else { /* The DTD instance referenced by parser->m_dtd is shared between the document's root parser and external PE parsers, therefore one does not need to call setContext. In addition, one also *must* not call setContext, because this would overwrite existing prefix->binding pointers in parser->m_dtd with ones that get destroyed with the external PE parser. This would leave those prefixes with dangling pointers. */ parser->m_isParamEntity = XML_TRUE; XmlPrologStateInitExternalEntity(&parser->m_prologState); parser->m_processor = externalParEntInitProcessor; } #endif /* XML_DTD */ return parser; } static void FASTCALL destroyBindings(BINDING *bindings, XML_Parser parser) { for (;;) { BINDING *b = bindings; if (! b) break; bindings = b->nextTagBinding; FREE(parser, b->uri); FREE(parser, b); } } void XMLCALL XML_ParserFree(XML_Parser parser) { TAG *tagList; OPEN_INTERNAL_ENTITY *entityList; if (parser == NULL) return; /* free m_tagStack and m_freeTagList */ tagList = parser->m_tagStack; for (;;) { TAG *p; if (tagList == NULL) { if (parser->m_freeTagList == NULL) break; tagList = parser->m_freeTagList; parser->m_freeTagList = NULL; } p = tagList; tagList = tagList->parent; FREE(parser, p->buf); destroyBindings(p->bindings, parser); FREE(parser, p); } /* free m_openInternalEntities and m_freeInternalEntities */ entityList = parser->m_openInternalEntities; for (;;) { OPEN_INTERNAL_ENTITY *openEntity; if (entityList == NULL) { if (parser->m_freeInternalEntities == NULL) break; entityList = parser->m_freeInternalEntities; parser->m_freeInternalEntities = NULL; } openEntity = entityList; entityList = entityList->next; FREE(parser, openEntity); } destroyBindings(parser->m_freeBindingList, parser); destroyBindings(parser->m_inheritedBindings, parser); poolDestroy(&parser->m_tempPool); poolDestroy(&parser->m_temp2Pool); FREE(parser, (void *)parser->m_protocolEncodingName); #ifdef XML_DTD /* external parameter entity parsers share the DTD structure parser->m_dtd with the root parser, so we must not destroy it */ if (! parser->m_isParamEntity && parser->m_dtd) #else if (parser->m_dtd) #endif /* XML_DTD */ dtdDestroy(parser->m_dtd, (XML_Bool)! parser->m_parentParser, &parser->m_mem); FREE(parser, (void *)parser->m_atts); #ifdef XML_ATTR_INFO FREE(parser, (void *)parser->m_attInfo); #endif FREE(parser, parser->m_groupConnector); FREE(parser, parser->m_buffer); FREE(parser, parser->m_dataBuf); FREE(parser, parser->m_nsAtts); FREE(parser, parser->m_unknownEncodingMem); if (parser->m_unknownEncodingRelease) parser->m_unknownEncodingRelease(parser->m_unknownEncodingData); FREE(parser, parser); } void XMLCALL XML_UseParserAsHandlerArg(XML_Parser parser) { if (parser != NULL) parser->m_handlerArg = parser; } enum XML_Error XMLCALL XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) { if (parser == NULL) return XML_ERROR_INVALID_ARGUMENT; #ifdef XML_DTD /* block after XML_Parse()/XML_ParseBuffer() has been called */ if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED) return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING; parser->m_useForeignDTD = useDTD; return XML_ERROR_NONE; #else return XML_ERROR_FEATURE_REQUIRES_XML_DTD; #endif } void XMLCALL XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) { if (parser == NULL) return; /* block after XML_Parse()/XML_ParseBuffer() has been called */ if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED) return; parser->m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE; } void XMLCALL XML_SetUserData(XML_Parser parser, void *p) { if (parser == NULL) return; if (parser->m_handlerArg == parser->m_userData) parser->m_handlerArg = parser->m_userData = p; else parser->m_userData = p; } enum XML_Status XMLCALL XML_SetBase(XML_Parser parser, const XML_Char *p) { if (parser == NULL) return XML_STATUS_ERROR; if (p) { p = poolCopyString(&parser->m_dtd->pool, p); if (! p) return XML_STATUS_ERROR; parser->m_curBase = p; } else parser->m_curBase = NULL; return XML_STATUS_OK; } const XML_Char *XMLCALL XML_GetBase(XML_Parser parser) { if (parser == NULL) return NULL; return parser->m_curBase; } int XMLCALL XML_GetSpecifiedAttributeCount(XML_Parser parser) { if (parser == NULL) return -1; return parser->m_nSpecifiedAtts; } int XMLCALL XML_GetIdAttributeIndex(XML_Parser parser) { if (parser == NULL) return -1; return parser->m_idAttIndex; } #ifdef XML_ATTR_INFO const XML_AttrInfo *XMLCALL XML_GetAttributeInfo(XML_Parser parser) { if (parser == NULL) return NULL; return parser->m_attInfo; } #endif void XMLCALL XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, XML_EndElementHandler end) { if (parser == NULL) return; parser->m_startElementHandler = start; parser->m_endElementHandler = end; } void XMLCALL XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler start) { if (parser != NULL) parser->m_startElementHandler = start; } void XMLCALL XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler end) { if (parser != NULL) parser->m_endElementHandler = end; } void XMLCALL XML_SetCharacterDataHandler(XML_Parser parser, XML_CharacterDataHandler handler) { if (parser != NULL) parser->m_characterDataHandler = handler; } void XMLCALL XML_SetProcessingInstructionHandler(XML_Parser parser, XML_ProcessingInstructionHandler handler) { if (parser != NULL) parser->m_processingInstructionHandler = handler; } void XMLCALL XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler) { if (parser != NULL) parser->m_commentHandler = handler; } void XMLCALL XML_SetCdataSectionHandler(XML_Parser parser, XML_StartCdataSectionHandler start, XML_EndCdataSectionHandler end) { if (parser == NULL) return; parser->m_startCdataSectionHandler = start; parser->m_endCdataSectionHandler = end; } void XMLCALL XML_SetStartCdataSectionHandler(XML_Parser parser, XML_StartCdataSectionHandler start) { if (parser != NULL) parser->m_startCdataSectionHandler = start; } void XMLCALL XML_SetEndCdataSectionHandler(XML_Parser parser, XML_EndCdataSectionHandler end) { if (parser != NULL) parser->m_endCdataSectionHandler = end; } void XMLCALL XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler) { if (parser == NULL) return; parser->m_defaultHandler = handler; parser->m_defaultExpandInternalEntities = XML_FALSE; } void XMLCALL XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler) { if (parser == NULL) return; parser->m_defaultHandler = handler; parser->m_defaultExpandInternalEntities = XML_TRUE; } void XMLCALL XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start, XML_EndDoctypeDeclHandler end) { if (parser == NULL) return; parser->m_startDoctypeDeclHandler = start; parser->m_endDoctypeDeclHandler = end; } void XMLCALL XML_SetStartDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start) { if (parser != NULL) parser->m_startDoctypeDeclHandler = start; } void XMLCALL XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end) { if (parser != NULL) parser->m_endDoctypeDeclHandler = end; } void XMLCALL XML_SetUnparsedEntityDeclHandler(XML_Parser parser, XML_UnparsedEntityDeclHandler handler) { if (parser != NULL) parser->m_unparsedEntityDeclHandler = handler; } void XMLCALL XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler) { if (parser != NULL) parser->m_notationDeclHandler = handler; } void XMLCALL XML_SetNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start, XML_EndNamespaceDeclHandler end) { if (parser == NULL) return; parser->m_startNamespaceDeclHandler = start; parser->m_endNamespaceDeclHandler = end; } void XMLCALL XML_SetStartNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start) { if (parser != NULL) parser->m_startNamespaceDeclHandler = start; } void XMLCALL XML_SetEndNamespaceDeclHandler(XML_Parser parser, XML_EndNamespaceDeclHandler end) { if (parser != NULL) parser->m_endNamespaceDeclHandler = end; } void XMLCALL XML_SetNotStandaloneHandler(XML_Parser parser, XML_NotStandaloneHandler handler) { if (parser != NULL) parser->m_notStandaloneHandler = handler; } void XMLCALL XML_SetExternalEntityRefHandler(XML_Parser parser, XML_ExternalEntityRefHandler handler) { if (parser != NULL) parser->m_externalEntityRefHandler = handler; } void XMLCALL XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) { if (parser == NULL) return; if (arg) parser->m_externalEntityRefHandlerArg = (XML_Parser)arg; else parser->m_externalEntityRefHandlerArg = parser; } void XMLCALL XML_SetSkippedEntityHandler(XML_Parser parser, XML_SkippedEntityHandler handler) { if (parser != NULL) parser->m_skippedEntityHandler = handler; } void XMLCALL XML_SetUnknownEncodingHandler(XML_Parser parser, XML_UnknownEncodingHandler handler, void *data) { if (parser == NULL) return; parser->m_unknownEncodingHandler = handler; parser->m_unknownEncodingHandlerData = data; } void XMLCALL XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl) { if (parser != NULL) parser->m_elementDeclHandler = eldecl; } void XMLCALL XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl) { if (parser != NULL) parser->m_attlistDeclHandler = attdecl; } void XMLCALL XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler) { if (parser != NULL) parser->m_entityDeclHandler = handler; } void XMLCALL XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler handler) { if (parser != NULL) parser->m_xmlDeclHandler = handler; } int XMLCALL XML_SetParamEntityParsing(XML_Parser parser, enum XML_ParamEntityParsing peParsing) { if (parser == NULL) return 0; /* block after XML_Parse()/XML_ParseBuffer() has been called */ if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED) return 0; #ifdef XML_DTD parser->m_paramEntityParsing = peParsing; return 1; #else return peParsing == XML_PARAM_ENTITY_PARSING_NEVER; #endif } int XMLCALL XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) { if (parser == NULL) return 0; if (parser->m_parentParser) return XML_SetHashSalt(parser->m_parentParser, hash_salt); /* block after XML_Parse()/XML_ParseBuffer() has been called */ if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED) return 0; parser->m_hash_secret_salt = hash_salt; return 1; } enum XML_Status XMLCALL XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) { if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) { if (parser != NULL) parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT; return XML_STATUS_ERROR; } switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: parser->m_errorCode = XML_ERROR_SUSPENDED; return XML_STATUS_ERROR; case XML_FINISHED: parser->m_errorCode = XML_ERROR_FINISHED; return XML_STATUS_ERROR; case XML_INITIALIZED: if (parser->m_parentParser == NULL && ! startParsing(parser)) { parser->m_errorCode = XML_ERROR_NO_MEMORY; return XML_STATUS_ERROR; } /* fall through */ default: parser->m_parsingStatus.parsing = XML_PARSING; } if (len == 0) { parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; if (! isFinal) return XML_STATUS_OK; parser->m_positionPtr = parser->m_bufferPtr; parser->m_parseEndPtr = parser->m_bufferEnd; /* If data are left over from last buffer, and we now know that these data are the final chunk of input, then we have to check them again to detect errors based on that fact. */ parser->m_errorCode = parser->m_processor(parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr); if (parser->m_errorCode == XML_ERROR_NONE) { switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: /* It is hard to be certain, but it seems that this case * cannot occur. This code is cleaning up a previous parse * with no new data (since len == 0). Changing the parsing * state requires getting to execute a handler function, and * there doesn't seem to be an opportunity for that while in * this circumstance. * * Given the uncertainty, we retain the code but exclude it * from coverage tests. * * LCOV_EXCL_START */ XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position); parser->m_positionPtr = parser->m_bufferPtr; return XML_STATUS_SUSPENDED; /* LCOV_EXCL_STOP */ case XML_INITIALIZED: case XML_PARSING: parser->m_parsingStatus.parsing = XML_FINISHED; /* fall through */ default: return XML_STATUS_OK; } } parser->m_eventEndPtr = parser->m_eventPtr; parser->m_processor = errorProcessor; return XML_STATUS_ERROR; } #ifndef XML_CONTEXT_BYTES else if (parser->m_bufferPtr == parser->m_bufferEnd) { const char *end; int nLeftOver; enum XML_Status result; /* Detect overflow (a+b > MAX <==> b > MAX-a) */ if (len > ((XML_Size)-1) / 2 - parser->m_parseEndByteIndex) { parser->m_errorCode = XML_ERROR_NO_MEMORY; parser->m_eventPtr = parser->m_eventEndPtr = NULL; parser->m_processor = errorProcessor; return XML_STATUS_ERROR; } parser->m_parseEndByteIndex += len; parser->m_positionPtr = s; parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; parser->m_errorCode = parser->m_processor(parser, s, parser->m_parseEndPtr = s + len, &end); if (parser->m_errorCode != XML_ERROR_NONE) { parser->m_eventEndPtr = parser->m_eventPtr; parser->m_processor = errorProcessor; return XML_STATUS_ERROR; } else { switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: result = XML_STATUS_SUSPENDED; break; case XML_INITIALIZED: case XML_PARSING: if (isFinal) { parser->m_parsingStatus.parsing = XML_FINISHED; return XML_STATUS_OK; } /* fall through */ default: result = XML_STATUS_OK; } } XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end, &parser->m_position); nLeftOver = s + len - end; if (nLeftOver) { if (parser->m_buffer == NULL || nLeftOver > parser->m_bufferLim - parser->m_buffer) { /* avoid _signed_ integer overflow */ char *temp = NULL; const int bytesToAllocate = (int)((unsigned)len * 2U); if (bytesToAllocate > 0) { temp = (char *)REALLOC(parser, parser->m_buffer, bytesToAllocate); } if (temp == NULL) { parser->m_errorCode = XML_ERROR_NO_MEMORY; parser->m_eventPtr = parser->m_eventEndPtr = NULL; parser->m_processor = errorProcessor; return XML_STATUS_ERROR; } parser->m_buffer = temp; parser->m_bufferLim = parser->m_buffer + bytesToAllocate; } memcpy(parser->m_buffer, end, nLeftOver); } parser->m_bufferPtr = parser->m_buffer; parser->m_bufferEnd = parser->m_buffer + nLeftOver; parser->m_positionPtr = parser->m_bufferPtr; parser->m_parseEndPtr = parser->m_bufferEnd; parser->m_eventPtr = parser->m_bufferPtr; parser->m_eventEndPtr = parser->m_bufferPtr; return result; } #endif /* not defined XML_CONTEXT_BYTES */ else { void *buff = XML_GetBuffer(parser, len); if (buff == NULL) return XML_STATUS_ERROR; else { memcpy(buff, s, len); return XML_ParseBuffer(parser, len, isFinal); } } } enum XML_Status XMLCALL XML_ParseBuffer(XML_Parser parser, int len, int isFinal) { const char *start; enum XML_Status result = XML_STATUS_OK; if (parser == NULL) return XML_STATUS_ERROR; switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: parser->m_errorCode = XML_ERROR_SUSPENDED; return XML_STATUS_ERROR; case XML_FINISHED: parser->m_errorCode = XML_ERROR_FINISHED; return XML_STATUS_ERROR; case XML_INITIALIZED: if (parser->m_parentParser == NULL && ! startParsing(parser)) { parser->m_errorCode = XML_ERROR_NO_MEMORY; return XML_STATUS_ERROR; } /* fall through */ default: parser->m_parsingStatus.parsing = XML_PARSING; } start = parser->m_bufferPtr; parser->m_positionPtr = start; parser->m_bufferEnd += len; parser->m_parseEndPtr = parser->m_bufferEnd; parser->m_parseEndByteIndex += len; parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; parser->m_errorCode = parser->m_processor( parser, start, parser->m_parseEndPtr, &parser->m_bufferPtr); if (parser->m_errorCode != XML_ERROR_NONE) { parser->m_eventEndPtr = parser->m_eventPtr; parser->m_processor = errorProcessor; return XML_STATUS_ERROR; } else { switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: result = XML_STATUS_SUSPENDED; break; case XML_INITIALIZED: case XML_PARSING: if (isFinal) { parser->m_parsingStatus.parsing = XML_FINISHED; return result; } default:; /* should not happen */ } } XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position); parser->m_positionPtr = parser->m_bufferPtr; return result; } void *XMLCALL XML_GetBuffer(XML_Parser parser, int len) { if (parser == NULL) return NULL; if (len < 0) { parser->m_errorCode = XML_ERROR_NO_MEMORY; return NULL; } switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: parser->m_errorCode = XML_ERROR_SUSPENDED; return NULL; case XML_FINISHED: parser->m_errorCode = XML_ERROR_FINISHED; return NULL; default:; } if (len > EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd)) { #ifdef XML_CONTEXT_BYTES int keep; #endif /* defined XML_CONTEXT_BYTES */ /* Do not invoke signed arithmetic overflow: */ int neededSize = (int)((unsigned)len + (unsigned)EXPAT_SAFE_PTR_DIFF( parser->m_bufferEnd, parser->m_bufferPtr)); if (neededSize < 0) { parser->m_errorCode = XML_ERROR_NO_MEMORY; return NULL; } #ifdef XML_CONTEXT_BYTES keep = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer); if (keep > XML_CONTEXT_BYTES) keep = XML_CONTEXT_BYTES; neededSize += keep; #endif /* defined XML_CONTEXT_BYTES */ if (neededSize <= EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer)) { #ifdef XML_CONTEXT_BYTES if (keep < EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)) { int offset = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer) - keep; /* The buffer pointers cannot be NULL here; we have at least some bytes * in the buffer */ memmove(parser->m_buffer, &parser->m_buffer[offset], parser->m_bufferEnd - parser->m_bufferPtr + keep); parser->m_bufferEnd -= offset; parser->m_bufferPtr -= offset; } #else if (parser->m_buffer && parser->m_bufferPtr) { memmove(parser->m_buffer, parser->m_bufferPtr, EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)); parser->m_bufferEnd = parser->m_buffer + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr); parser->m_bufferPtr = parser->m_buffer; } #endif /* not defined XML_CONTEXT_BYTES */ } else { char *newBuf; int bufferSize = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferPtr); if (bufferSize == 0) bufferSize = INIT_BUFFER_SIZE; do { /* Do not invoke signed arithmetic overflow: */ bufferSize = (int)(2U * (unsigned)bufferSize); } while (bufferSize < neededSize && bufferSize > 0); if (bufferSize <= 0) { parser->m_errorCode = XML_ERROR_NO_MEMORY; return NULL; } newBuf = (char *)MALLOC(parser, bufferSize); if (newBuf == 0) { parser->m_errorCode = XML_ERROR_NO_MEMORY; return NULL; } parser->m_bufferLim = newBuf + bufferSize; #ifdef XML_CONTEXT_BYTES if (parser->m_bufferPtr) { memcpy(newBuf, &parser->m_bufferPtr[-keep], EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr) + keep); FREE(parser, parser->m_buffer); parser->m_buffer = newBuf; parser->m_bufferEnd = parser->m_buffer + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr) + keep; parser->m_bufferPtr = parser->m_buffer + keep; } else { /* This must be a brand new buffer with no data in it yet */ parser->m_bufferEnd = newBuf; parser->m_bufferPtr = parser->m_buffer = newBuf; } #else if (parser->m_bufferPtr) { memcpy(newBuf, parser->m_bufferPtr, EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)); FREE(parser, parser->m_buffer); parser->m_bufferEnd = newBuf + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr); } else { /* This must be a brand new buffer with no data in it yet */ parser->m_bufferEnd = newBuf; } parser->m_bufferPtr = parser->m_buffer = newBuf; #endif /* not defined XML_CONTEXT_BYTES */ } parser->m_eventPtr = parser->m_eventEndPtr = NULL; parser->m_positionPtr = NULL; } return parser->m_bufferEnd; } enum XML_Status XMLCALL XML_StopParser(XML_Parser parser, XML_Bool resumable) { if (parser == NULL) return XML_STATUS_ERROR; switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: if (resumable) { parser->m_errorCode = XML_ERROR_SUSPENDED; return XML_STATUS_ERROR; } parser->m_parsingStatus.parsing = XML_FINISHED; break; case XML_FINISHED: parser->m_errorCode = XML_ERROR_FINISHED; return XML_STATUS_ERROR; default: if (resumable) { #ifdef XML_DTD if (parser->m_isParamEntity) { parser->m_errorCode = XML_ERROR_SUSPEND_PE; return XML_STATUS_ERROR; } #endif parser->m_parsingStatus.parsing = XML_SUSPENDED; } else parser->m_parsingStatus.parsing = XML_FINISHED; } return XML_STATUS_OK; } enum XML_Status XMLCALL XML_ResumeParser(XML_Parser parser) { enum XML_Status result = XML_STATUS_OK; if (parser == NULL) return XML_STATUS_ERROR; if (parser->m_parsingStatus.parsing != XML_SUSPENDED) { parser->m_errorCode = XML_ERROR_NOT_SUSPENDED; return XML_STATUS_ERROR; } parser->m_parsingStatus.parsing = XML_PARSING; parser->m_errorCode = parser->m_processor( parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr); if (parser->m_errorCode != XML_ERROR_NONE) { parser->m_eventEndPtr = parser->m_eventPtr; parser->m_processor = errorProcessor; return XML_STATUS_ERROR; } else { switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: result = XML_STATUS_SUSPENDED; break; case XML_INITIALIZED: case XML_PARSING: if (parser->m_parsingStatus.finalBuffer) { parser->m_parsingStatus.parsing = XML_FINISHED; return result; } default:; } } XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position); parser->m_positionPtr = parser->m_bufferPtr; return result; } void XMLCALL XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) { if (parser == NULL) return; assert(status != NULL); *status = parser->m_parsingStatus; } enum XML_Error XMLCALL XML_GetErrorCode(XML_Parser parser) { if (parser == NULL) return XML_ERROR_INVALID_ARGUMENT; return parser->m_errorCode; } XML_Index XMLCALL XML_GetCurrentByteIndex(XML_Parser parser) { if (parser == NULL) return -1; if (parser->m_eventPtr) return (XML_Index)(parser->m_parseEndByteIndex - (parser->m_parseEndPtr - parser->m_eventPtr)); return -1; } int XMLCALL XML_GetCurrentByteCount(XML_Parser parser) { if (parser == NULL) return 0; if (parser->m_eventEndPtr && parser->m_eventPtr) return (int)(parser->m_eventEndPtr - parser->m_eventPtr); return 0; } const char *XMLCALL XML_GetInputContext(XML_Parser parser, int *offset, int *size) { #ifdef XML_CONTEXT_BYTES if (parser == NULL) return NULL; if (parser->m_eventPtr && parser->m_buffer) { if (offset != NULL) *offset = (int)(parser->m_eventPtr - parser->m_buffer); if (size != NULL) *size = (int)(parser->m_bufferEnd - parser->m_buffer); return parser->m_buffer; } #else (void)parser; (void)offset; (void)size; #endif /* defined XML_CONTEXT_BYTES */ return (char *)0; } XML_Size XMLCALL XML_GetCurrentLineNumber(XML_Parser parser) { if (parser == NULL) return 0; if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) { XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_eventPtr, &parser->m_position); parser->m_positionPtr = parser->m_eventPtr; } return parser->m_position.lineNumber + 1; } XML_Size XMLCALL XML_GetCurrentColumnNumber(XML_Parser parser) { if (parser == NULL) return 0; if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) { XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_eventPtr, &parser->m_position); parser->m_positionPtr = parser->m_eventPtr; } return parser->m_position.columnNumber; } void XMLCALL XML_FreeContentModel(XML_Parser parser, XML_Content *model) { if (parser != NULL) FREE(parser, model); } void *XMLCALL XML_MemMalloc(XML_Parser parser, size_t size) { if (parser == NULL) return NULL; return MALLOC(parser, size); } void *XMLCALL XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) { if (parser == NULL) return NULL; return REALLOC(parser, ptr, size); } void XMLCALL XML_MemFree(XML_Parser parser, void *ptr) { if (parser != NULL) FREE(parser, ptr); } void XMLCALL XML_DefaultCurrent(XML_Parser parser) { if (parser == NULL) return; if (parser->m_defaultHandler) { if (parser->m_openInternalEntities) reportDefault(parser, parser->m_internalEncoding, parser->m_openInternalEntities->internalEventPtr, parser->m_openInternalEntities->internalEventEndPtr); else reportDefault(parser, parser->m_encoding, parser->m_eventPtr, parser->m_eventEndPtr); } } const XML_LChar *XMLCALL XML_ErrorString(enum XML_Error code) { switch (code) { case XML_ERROR_NONE: return NULL; case XML_ERROR_NO_MEMORY: return XML_L("out of memory"); case XML_ERROR_SYNTAX: return XML_L("syntax error"); case XML_ERROR_NO_ELEMENTS: return XML_L("no element found"); case XML_ERROR_INVALID_TOKEN: return XML_L("not well-formed (invalid token)"); case XML_ERROR_UNCLOSED_TOKEN: return XML_L("unclosed token"); case XML_ERROR_PARTIAL_CHAR: return XML_L("partial character"); case XML_ERROR_TAG_MISMATCH: return XML_L("mismatched tag"); case XML_ERROR_DUPLICATE_ATTRIBUTE: return XML_L("duplicate attribute"); case XML_ERROR_JUNK_AFTER_DOC_ELEMENT: return XML_L("junk after document element"); case XML_ERROR_PARAM_ENTITY_REF: return XML_L("illegal parameter entity reference"); case XML_ERROR_UNDEFINED_ENTITY: return XML_L("undefined entity"); case XML_ERROR_RECURSIVE_ENTITY_REF: return XML_L("recursive entity reference"); case XML_ERROR_ASYNC_ENTITY: return XML_L("asynchronous entity"); case XML_ERROR_BAD_CHAR_REF: return XML_L("reference to invalid character number"); case XML_ERROR_BINARY_ENTITY_REF: return XML_L("reference to binary entity"); case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF: return XML_L("reference to external entity in attribute"); case XML_ERROR_MISPLACED_XML_PI: return XML_L("XML or text declaration not at start of entity"); case XML_ERROR_UNKNOWN_ENCODING: return XML_L("unknown encoding"); case XML_ERROR_INCORRECT_ENCODING: return XML_L("encoding specified in XML declaration is incorrect"); case XML_ERROR_UNCLOSED_CDATA_SECTION: return XML_L("unclosed CDATA section"); case XML_ERROR_EXTERNAL_ENTITY_HANDLING: return XML_L("error in processing external entity reference"); case XML_ERROR_NOT_STANDALONE: return XML_L("document is not standalone"); case XML_ERROR_UNEXPECTED_STATE: return XML_L("unexpected parser state - please send a bug report"); case XML_ERROR_ENTITY_DECLARED_IN_PE: return XML_L("entity declared in parameter entity"); case XML_ERROR_FEATURE_REQUIRES_XML_DTD: return XML_L("requested feature requires XML_DTD support in Expat"); case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING: return XML_L("cannot change setting once parsing has begun"); /* Added in 1.95.7. */ case XML_ERROR_UNBOUND_PREFIX: return XML_L("unbound prefix"); /* Added in 1.95.8. */ case XML_ERROR_UNDECLARING_PREFIX: return XML_L("must not undeclare prefix"); case XML_ERROR_INCOMPLETE_PE: return XML_L("incomplete markup in parameter entity"); case XML_ERROR_XML_DECL: return XML_L("XML declaration not well-formed"); case XML_ERROR_TEXT_DECL: return XML_L("text declaration not well-formed"); case XML_ERROR_PUBLICID: return XML_L("illegal character(s) in public id"); case XML_ERROR_SUSPENDED: return XML_L("parser suspended"); case XML_ERROR_NOT_SUSPENDED: return XML_L("parser not suspended"); case XML_ERROR_ABORTED: return XML_L("parsing aborted"); case XML_ERROR_FINISHED: return XML_L("parsing finished"); case XML_ERROR_SUSPEND_PE: return XML_L("cannot suspend in external parameter entity"); /* Added in 2.0.0. */ case XML_ERROR_RESERVED_PREFIX_XML: return XML_L( "reserved prefix (xml) must not be undeclared or bound to another namespace name"); case XML_ERROR_RESERVED_PREFIX_XMLNS: return XML_L("reserved prefix (xmlns) must not be declared or undeclared"); case XML_ERROR_RESERVED_NAMESPACE_URI: return XML_L( "prefix must not be bound to one of the reserved namespace names"); /* Added in 2.2.5. */ case XML_ERROR_INVALID_ARGUMENT: /* Constant added in 2.2.1, already */ return XML_L("invalid argument"); } return NULL; } const XML_LChar *XMLCALL XML_ExpatVersion(void) { /* V1 is used to string-ize the version number. However, it would string-ize the actual version macro *names* unless we get them substituted before being passed to V1. CPP is defined to expand a macro, then rescan for more expansions. Thus, we use V2 to expand the version macros, then CPP will expand the resulting V1() macro with the correct numerals. */ /* ### I'm assuming cpp is portable in this respect... */ #define V1(a, b, c) XML_L(#a) XML_L(".") XML_L(#b) XML_L(".") XML_L(#c) #define V2(a, b, c) XML_L("expat_") V1(a, b, c) return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION); #undef V1 #undef V2 } XML_Expat_Version XMLCALL XML_ExpatVersionInfo(void) { XML_Expat_Version version; version.major = XML_MAJOR_VERSION; version.minor = XML_MINOR_VERSION; version.micro = XML_MICRO_VERSION; return version; } const XML_Feature *XMLCALL XML_GetFeatureList(void) { static const XML_Feature features[] = {{XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"), sizeof(XML_Char)}, {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"), sizeof(XML_LChar)}, #ifdef XML_UNICODE {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0}, #endif #ifdef XML_UNICODE_WCHAR_T {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0}, #endif #ifdef XML_DTD {XML_FEATURE_DTD, XML_L("XML_DTD"), 0}, #endif #ifdef XML_CONTEXT_BYTES {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"), XML_CONTEXT_BYTES}, #endif #ifdef XML_MIN_SIZE {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0}, #endif #ifdef XML_NS {XML_FEATURE_NS, XML_L("XML_NS"), 0}, #endif #ifdef XML_LARGE_SIZE {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0}, #endif #ifdef XML_ATTR_INFO {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0}, #endif {XML_FEATURE_END, NULL, 0}}; return features; } /* Initially tag->rawName always points into the parse buffer; for those TAG instances opened while the current parse buffer was processed, and not yet closed, we need to store tag->rawName in a more permanent location, since the parse buffer is about to be discarded. */ static XML_Bool storeRawNames(XML_Parser parser) { TAG *tag = parser->m_tagStack; while (tag) { int bufSize; int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1); char *rawNameBuf = tag->buf + nameLen; /* Stop if already stored. Since m_tagStack is a stack, we can stop at the first entry that has already been copied; everything below it in the stack is already been accounted for in a previous call to this function. */ if (tag->rawName == rawNameBuf) break; /* For re-use purposes we need to ensure that the size of tag->buf is a multiple of sizeof(XML_Char). */ bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)); if (bufSize > tag->bufEnd - tag->buf) { char *temp = (char *)REALLOC(parser, tag->buf, bufSize); if (temp == NULL) return XML_FALSE; /* if tag->name.str points to tag->buf (only when namespace processing is off) then we have to update it */ if (tag->name.str == (XML_Char *)tag->buf) tag->name.str = (XML_Char *)temp; /* if tag->name.localPart is set (when namespace processing is on) then update it as well, since it will always point into tag->buf */ if (tag->name.localPart) tag->name.localPart = (XML_Char *)temp + (tag->name.localPart - (XML_Char *)tag->buf); tag->buf = temp; tag->bufEnd = temp + bufSize; rawNameBuf = temp + nameLen; } memcpy(rawNameBuf, tag->rawName, tag->rawNameLength); tag->rawName = rawNameBuf; tag = tag->parent; } return XML_TRUE; } static enum XML_Error PTRCALL contentProcessor(XML_Parser parser, const char *start, const char *end, const char **endPtr) { enum XML_Error result = doContent(parser, 0, parser->m_encoding, start, end, endPtr, (XML_Bool)! parser->m_parsingStatus.finalBuffer); if (result == XML_ERROR_NONE) { if (! storeRawNames(parser)) return XML_ERROR_NO_MEMORY; } return result; } static enum XML_Error PTRCALL externalEntityInitProcessor(XML_Parser parser, const char *start, const char *end, const char **endPtr) { enum XML_Error result = initializeEncoding(parser); if (result != XML_ERROR_NONE) return result; parser->m_processor = externalEntityInitProcessor2; return externalEntityInitProcessor2(parser, start, end, endPtr); } static enum XML_Error PTRCALL externalEntityInitProcessor2(XML_Parser parser, const char *start, const char *end, const char **endPtr) { const char *next = start; /* XmlContentTok doesn't always set the last arg */ int tok = XmlContentTok(parser->m_encoding, start, end, &next); switch (tok) { case XML_TOK_BOM: /* If we are at the end of the buffer, this would cause the next stage, i.e. externalEntityInitProcessor3, to pass control directly to doContent (by detecting XML_TOK_NONE) without processing any xml text declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent. */ if (next == end && ! parser->m_parsingStatus.finalBuffer) { *endPtr = next; return XML_ERROR_NONE; } start = next; break; case XML_TOK_PARTIAL: if (! parser->m_parsingStatus.finalBuffer) { *endPtr = start; return XML_ERROR_NONE; } parser->m_eventPtr = start; return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: if (! parser->m_parsingStatus.finalBuffer) { *endPtr = start; return XML_ERROR_NONE; } parser->m_eventPtr = start; return XML_ERROR_PARTIAL_CHAR; } parser->m_processor = externalEntityInitProcessor3; return externalEntityInitProcessor3(parser, start, end, endPtr); } static enum XML_Error PTRCALL externalEntityInitProcessor3(XML_Parser parser, const char *start, const char *end, const char **endPtr) { int tok; const char *next = start; /* XmlContentTok doesn't always set the last arg */ parser->m_eventPtr = start; tok = XmlContentTok(parser->m_encoding, start, end, &next); parser->m_eventEndPtr = next; switch (tok) { case XML_TOK_XML_DECL: { enum XML_Error result; result = processXmlDecl(parser, 1, start, next); if (result != XML_ERROR_NONE) return result; switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: *endPtr = next; return XML_ERROR_NONE; case XML_FINISHED: return XML_ERROR_ABORTED; default: start = next; } } break; case XML_TOK_PARTIAL: if (! parser->m_parsingStatus.finalBuffer) { *endPtr = start; return XML_ERROR_NONE; } return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: if (! parser->m_parsingStatus.finalBuffer) { *endPtr = start; return XML_ERROR_NONE; } return XML_ERROR_PARTIAL_CHAR; } parser->m_processor = externalEntityContentProcessor; parser->m_tagLevel = 1; return externalEntityContentProcessor(parser, start, end, endPtr); } static enum XML_Error PTRCALL externalEntityContentProcessor(XML_Parser parser, const char *start, const char *end, const char **endPtr) { enum XML_Error result = doContent(parser, 1, parser->m_encoding, start, end, endPtr, (XML_Bool)! parser->m_parsingStatus.finalBuffer); if (result == XML_ERROR_NONE) { if (! storeRawNames(parser)) return XML_ERROR_NO_MEMORY; } return result; } static enum XML_Error doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, const char *s, const char *end, const char **nextPtr, XML_Bool haveMore) { /* save one level of indirection */ DTD *const dtd = parser->m_dtd; const char **eventPP; const char **eventEndPP; if (enc == parser->m_encoding) { eventPP = &parser->m_eventPtr; eventEndPP = &parser->m_eventEndPtr; } else { eventPP = &(parser->m_openInternalEntities->internalEventPtr); eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); } *eventPP = s; for (;;) { const char *next = s; /* XmlContentTok doesn't always set the last arg */ int tok = XmlContentTok(enc, s, end, &next); *eventEndPP = next; switch (tok) { case XML_TOK_TRAILING_CR: if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } *eventEndPP = end; if (parser->m_characterDataHandler) { XML_Char c = 0xA; parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); } else if (parser->m_defaultHandler) reportDefault(parser, enc, s, end); /* We are at the end of the final buffer, should we check for XML_SUSPENDED, XML_FINISHED? */ if (startTagLevel == 0) return XML_ERROR_NO_ELEMENTS; if (parser->m_tagLevel != startTagLevel) return XML_ERROR_ASYNC_ENTITY; *nextPtr = end; return XML_ERROR_NONE; case XML_TOK_NONE: if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } if (startTagLevel > 0) { if (parser->m_tagLevel != startTagLevel) return XML_ERROR_ASYNC_ENTITY; *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_NO_ELEMENTS; case XML_TOK_INVALID: *eventPP = next; return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL: if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_PARTIAL_CHAR; case XML_TOK_ENTITY_REF: { const XML_Char *name; ENTITY *entity; XML_Char ch = (XML_Char)XmlPredefinedEntityName( enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (ch) { if (parser->m_characterDataHandler) parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1); else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); break; } name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (! name) return XML_ERROR_NO_MEMORY; entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0); poolDiscard(&dtd->pool); /* First, determine if a check for an existing declaration is needed; if yes, check that the entity exists, and that it is internal, otherwise call the skipped entity or default handler. */ if (! dtd->hasParamEntityRefs || dtd->standalone) { if (! entity) return XML_ERROR_UNDEFINED_ENTITY; else if (! entity->is_internal) return XML_ERROR_ENTITY_DECLARED_IN_PE; } else if (! entity) { if (parser->m_skippedEntityHandler) parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); break; } if (entity->open) return XML_ERROR_RECURSIVE_ENTITY_REF; if (entity->notation) return XML_ERROR_BINARY_ENTITY_REF; if (entity->textPtr) { enum XML_Error result; if (! parser->m_defaultExpandInternalEntities) { if (parser->m_skippedEntityHandler) parser->m_skippedEntityHandler(parser->m_handlerArg, entity->name, 0); else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); break; } result = processInternalEntity(parser, entity, XML_FALSE); if (result != XML_ERROR_NONE) return result; } else if (parser->m_externalEntityRefHandler) { const XML_Char *context; entity->open = XML_TRUE; context = getContext(parser); entity->open = XML_FALSE; if (! context) return XML_ERROR_NO_MEMORY; if (! parser->m_externalEntityRefHandler( parser->m_externalEntityRefHandlerArg, context, entity->base, entity->systemId, entity->publicId)) return XML_ERROR_EXTERNAL_ENTITY_HANDLING; poolDiscard(&parser->m_tempPool); } else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); break; } case XML_TOK_START_TAG_NO_ATTS: /* fall through */ case XML_TOK_START_TAG_WITH_ATTS: { TAG *tag; enum XML_Error result; XML_Char *toPtr; if (parser->m_freeTagList) { tag = parser->m_freeTagList; parser->m_freeTagList = parser->m_freeTagList->parent; } else { tag = (TAG *)MALLOC(parser, sizeof(TAG)); if (! tag) return XML_ERROR_NO_MEMORY; tag->buf = (char *)MALLOC(parser, INIT_TAG_BUF_SIZE); if (! tag->buf) { FREE(parser, tag); return XML_ERROR_NO_MEMORY; } tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE; } tag->bindings = NULL; tag->parent = parser->m_tagStack; parser->m_tagStack = tag; tag->name.localPart = NULL; tag->name.prefix = NULL; tag->rawName = s + enc->minBytesPerChar; tag->rawNameLength = XmlNameLength(enc, tag->rawName); ++parser->m_tagLevel; { const char *rawNameEnd = tag->rawName + tag->rawNameLength; const char *fromPtr = tag->rawName; toPtr = (XML_Char *)tag->buf; for (;;) { int bufSize; int convLen; const enum XML_Convert_Result convert_res = XmlConvert(enc, &fromPtr, rawNameEnd, (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1); convLen = (int)(toPtr - (XML_Char *)tag->buf); if ((fromPtr >= rawNameEnd) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) { tag->name.strLen = convLen; break; } bufSize = (int)(tag->bufEnd - tag->buf) << 1; { char *temp = (char *)REALLOC(parser, tag->buf, bufSize); if (temp == NULL) return XML_ERROR_NO_MEMORY; tag->buf = temp; tag->bufEnd = temp + bufSize; toPtr = (XML_Char *)temp + convLen; } } } tag->name.str = (XML_Char *)tag->buf; *toPtr = XML_T('\0'); result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings)); if (result) return result; if (parser->m_startElementHandler) parser->m_startElementHandler(parser->m_handlerArg, tag->name.str, (const XML_Char **)parser->m_atts); else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); poolClear(&parser->m_tempPool); break; } case XML_TOK_EMPTY_ELEMENT_NO_ATTS: /* fall through */ case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: { const char *rawName = s + enc->minBytesPerChar; enum XML_Error result; BINDING *bindings = NULL; XML_Bool noElmHandlers = XML_TRUE; TAG_NAME name; name.str = poolStoreString(&parser->m_tempPool, enc, rawName, rawName + XmlNameLength(enc, rawName)); if (! name.str) return XML_ERROR_NO_MEMORY; poolFinish(&parser->m_tempPool); result = storeAtts(parser, enc, s, &name, &bindings); if (result != XML_ERROR_NONE) { freeBindings(parser, bindings); return result; } poolFinish(&parser->m_tempPool); if (parser->m_startElementHandler) { parser->m_startElementHandler(parser->m_handlerArg, name.str, (const XML_Char **)parser->m_atts); noElmHandlers = XML_FALSE; } if (parser->m_endElementHandler) { if (parser->m_startElementHandler) *eventPP = *eventEndPP; parser->m_endElementHandler(parser->m_handlerArg, name.str); noElmHandlers = XML_FALSE; } if (noElmHandlers && parser->m_defaultHandler) reportDefault(parser, enc, s, next); poolClear(&parser->m_tempPool); freeBindings(parser, bindings); } if ((parser->m_tagLevel == 0) && (parser->m_parsingStatus.parsing != XML_FINISHED)) { if (parser->m_parsingStatus.parsing == XML_SUSPENDED) parser->m_processor = epilogProcessor; else return epilogProcessor(parser, next, end, nextPtr); } break; case XML_TOK_END_TAG: if (parser->m_tagLevel == startTagLevel) return XML_ERROR_ASYNC_ENTITY; else { int len; const char *rawName; TAG *tag = parser->m_tagStack; parser->m_tagStack = tag->parent; tag->parent = parser->m_freeTagList; parser->m_freeTagList = tag; rawName = s + enc->minBytesPerChar * 2; len = XmlNameLength(enc, rawName); if (len != tag->rawNameLength || memcmp(tag->rawName, rawName, len) != 0) { *eventPP = rawName; return XML_ERROR_TAG_MISMATCH; } --parser->m_tagLevel; if (parser->m_endElementHandler) { const XML_Char *localPart; const XML_Char *prefix; XML_Char *uri; localPart = tag->name.localPart; if (parser->m_ns && localPart) { /* localPart and prefix may have been overwritten in tag->name.str, since this points to the binding->uri buffer which gets re-used; so we have to add them again */ uri = (XML_Char *)tag->name.str + tag->name.uriLen; /* don't need to check for space - already done in storeAtts() */ while (*localPart) *uri++ = *localPart++; prefix = (XML_Char *)tag->name.prefix; if (parser->m_ns_triplets && prefix) { *uri++ = parser->m_namespaceSeparator; while (*prefix) *uri++ = *prefix++; } *uri = XML_T('\0'); } parser->m_endElementHandler(parser->m_handlerArg, tag->name.str); } else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); while (tag->bindings) { BINDING *b = tag->bindings; if (parser->m_endNamespaceDeclHandler) parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name); tag->bindings = tag->bindings->nextTagBinding; b->nextTagBinding = parser->m_freeBindingList; parser->m_freeBindingList = b; b->prefix->binding = b->prevPrefixBinding; } if ((parser->m_tagLevel == 0) && (parser->m_parsingStatus.parsing != XML_FINISHED)) { if (parser->m_parsingStatus.parsing == XML_SUSPENDED) parser->m_processor = epilogProcessor; else return epilogProcessor(parser, next, end, nextPtr); } } break; case XML_TOK_CHAR_REF: { int n = XmlCharRefNumber(enc, s); if (n < 0) return XML_ERROR_BAD_CHAR_REF; if (parser->m_characterDataHandler) { XML_Char buf[XML_ENCODE_MAX]; parser->m_characterDataHandler(parser->m_handlerArg, buf, XmlEncode(n, (ICHAR *)buf)); } else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); } break; case XML_TOK_XML_DECL: return XML_ERROR_MISPLACED_XML_PI; case XML_TOK_DATA_NEWLINE: if (parser->m_characterDataHandler) { XML_Char c = 0xA; parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); } else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); break; case XML_TOK_CDATA_SECT_OPEN: { enum XML_Error result; if (parser->m_startCdataSectionHandler) parser->m_startCdataSectionHandler(parser->m_handlerArg); /* BEGIN disabled code */ /* Suppose you doing a transformation on a document that involves changing only the character data. You set up a defaultHandler and a characterDataHandler. The defaultHandler simply copies characters through. The characterDataHandler does the transformation and writes the characters out escaping them as necessary. This case will fail to work if we leave out the following two lines (because & and < inside CDATA sections will be incorrectly escaped). However, now we have a start/endCdataSectionHandler, so it seems easier to let the user deal with this. */ else if (0 && parser->m_characterDataHandler) parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, 0); /* END disabled code */ else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore); if (result != XML_ERROR_NONE) return result; else if (! next) { parser->m_processor = cdataSectionProcessor; return result; } } break; case XML_TOK_TRAILING_RSQB: if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } if (parser->m_characterDataHandler) { if (MUST_CONVERT(enc, s)) { ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd); parser->m_characterDataHandler( parser->m_handlerArg, parser->m_dataBuf, (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); } else parser->m_characterDataHandler( parser->m_handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s)); } else if (parser->m_defaultHandler) reportDefault(parser, enc, s, end); /* We are at the end of the final buffer, should we check for XML_SUSPENDED, XML_FINISHED? */ if (startTagLevel == 0) { *eventPP = end; return XML_ERROR_NO_ELEMENTS; } if (parser->m_tagLevel != startTagLevel) { *eventPP = end; return XML_ERROR_ASYNC_ENTITY; } *nextPtr = end; return XML_ERROR_NONE; case XML_TOK_DATA_CHARS: { XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler; if (charDataHandler) { if (MUST_CONVERT(enc, s)) { for (;;) { ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; const enum XML_Convert_Result convert_res = XmlConvert( enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd); *eventEndPP = s; charDataHandler(parser->m_handlerArg, parser->m_dataBuf, (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) break; *eventPP = s; } } else charDataHandler(parser->m_handlerArg, (XML_Char *)s, (int)((XML_Char *)next - (XML_Char *)s)); } else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); } break; case XML_TOK_PI: if (! reportProcessingInstruction(parser, enc, s, next)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_COMMENT: if (! reportComment(parser, enc, s, next)) return XML_ERROR_NO_MEMORY; break; default: /* All of the tokens produced by XmlContentTok() have their own * explicit cases, so this default is not strictly necessary. * However it is a useful safety net, so we retain the code and * simply exclude it from the coverage tests. * * LCOV_EXCL_START */ if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); break; /* LCOV_EXCL_STOP */ } *eventPP = s = next; switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: *nextPtr = next; return XML_ERROR_NONE; case XML_FINISHED: return XML_ERROR_ABORTED; default:; } } /* not reached */ } /* This function does not call free() on the allocated memory, merely * moving it to the parser's m_freeBindingList where it can be freed or * reused as appropriate. */ static void freeBindings(XML_Parser parser, BINDING *bindings) { while (bindings) { BINDING *b = bindings; /* m_startNamespaceDeclHandler will have been called for this * binding in addBindings(), so call the end handler now. */ if (parser->m_endNamespaceDeclHandler) parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name); bindings = bindings->nextTagBinding; b->nextTagBinding = parser->m_freeBindingList; parser->m_freeBindingList = b; b->prefix->binding = b->prevPrefixBinding; } } /* Precondition: all arguments must be non-NULL; Purpose: - normalize attributes - check attributes for well-formedness - generate namespace aware attribute names (URI, prefix) - build list of attributes for startElementHandler - default attributes - process namespace declarations (check and report them) - generate namespace aware element name (URI, prefix) */ static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, TAG_NAME *tagNamePtr, BINDING **bindingsPtr) { DTD *const dtd = parser->m_dtd; /* save one level of indirection */ ELEMENT_TYPE *elementType; int nDefaultAtts; const XML_Char **appAtts; /* the attribute list for the application */ int attIndex = 0; int prefixLen; int i; int n; XML_Char *uri; int nPrefixes = 0; BINDING *binding; const XML_Char *localPart; /* lookup the element type name */ elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str, 0); if (! elementType) { const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str); if (! name) return XML_ERROR_NO_MEMORY; elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE)); if (! elementType) return XML_ERROR_NO_MEMORY; if (parser->m_ns && ! setElementTypePrefix(parser, elementType)) return XML_ERROR_NO_MEMORY; } nDefaultAtts = elementType->nDefaultAtts; /* get the attributes from the tokenizer */ n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts); if (n + nDefaultAtts > parser->m_attsSize) { int oldAttsSize = parser->m_attsSize; ATTRIBUTE *temp; #ifdef XML_ATTR_INFO XML_AttrInfo *temp2; #endif parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts, parser->m_attsSize * sizeof(ATTRIBUTE)); if (temp == NULL) { parser->m_attsSize = oldAttsSize; return XML_ERROR_NO_MEMORY; } parser->m_atts = temp; #ifdef XML_ATTR_INFO temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo, parser->m_attsSize * sizeof(XML_AttrInfo)); if (temp2 == NULL) { parser->m_attsSize = oldAttsSize; return XML_ERROR_NO_MEMORY; } parser->m_attInfo = temp2; #endif if (n > oldAttsSize) XmlGetAttributes(enc, attStr, n, parser->m_atts); } appAtts = (const XML_Char **)parser->m_atts; for (i = 0; i < n; i++) { ATTRIBUTE *currAtt = &parser->m_atts[i]; #ifdef XML_ATTR_INFO XML_AttrInfo *currAttInfo = &parser->m_attInfo[i]; #endif /* add the name and value to the attribute list */ ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name, currAtt->name + XmlNameLength(enc, currAtt->name)); if (! attId) return XML_ERROR_NO_MEMORY; #ifdef XML_ATTR_INFO currAttInfo->nameStart = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->name); currAttInfo->nameEnd = currAttInfo->nameStart + XmlNameLength(enc, currAtt->name); currAttInfo->valueStart = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->valuePtr); currAttInfo->valueEnd = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->valueEnd); #endif /* Detect duplicate attributes by their QNames. This does not work when namespace processing is turned on and different prefixes for the same namespace are used. For this case we have a check further down. */ if ((attId->name)[-1]) { if (enc == parser->m_encoding) parser->m_eventPtr = parser->m_atts[i].name; return XML_ERROR_DUPLICATE_ATTRIBUTE; } (attId->name)[-1] = 1; appAtts[attIndex++] = attId->name; if (! parser->m_atts[i].normalized) { enum XML_Error result; XML_Bool isCdata = XML_TRUE; /* figure out whether declared as other than CDATA */ if (attId->maybeTokenized) { int j; for (j = 0; j < nDefaultAtts; j++) { if (attId == elementType->defaultAtts[j].id) { isCdata = elementType->defaultAtts[j].isCdata; break; } } } /* normalize the attribute value */ result = storeAttributeValue( parser, enc, isCdata, parser->m_atts[i].valuePtr, parser->m_atts[i].valueEnd, &parser->m_tempPool); if (result) return result; appAtts[attIndex] = poolStart(&parser->m_tempPool); poolFinish(&parser->m_tempPool); } else { /* the value did not need normalizing */ appAtts[attIndex] = poolStoreString(&parser->m_tempPool, enc, parser->m_atts[i].valuePtr, parser->m_atts[i].valueEnd); if (appAtts[attIndex] == 0) return XML_ERROR_NO_MEMORY; poolFinish(&parser->m_tempPool); } /* handle prefixed attribute names */ if (attId->prefix) { if (attId->xmlns) { /* deal with namespace declarations here */ enum XML_Error result = addBinding(parser, attId->prefix, attId, appAtts[attIndex], bindingsPtr); if (result) return result; --attIndex; } else { /* deal with other prefixed names later */ attIndex++; nPrefixes++; (attId->name)[-1] = 2; } } else attIndex++; } /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */ parser->m_nSpecifiedAtts = attIndex; if (elementType->idAtt && (elementType->idAtt->name)[-1]) { for (i = 0; i < attIndex; i += 2) if (appAtts[i] == elementType->idAtt->name) { parser->m_idAttIndex = i; break; } } else parser->m_idAttIndex = -1; /* do attribute defaulting */ for (i = 0; i < nDefaultAtts; i++) { const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i; if (! (da->id->name)[-1] && da->value) { if (da->id->prefix) { if (da->id->xmlns) { enum XML_Error result = addBinding(parser, da->id->prefix, da->id, da->value, bindingsPtr); if (result) return result; } else { (da->id->name)[-1] = 2; nPrefixes++; appAtts[attIndex++] = da->id->name; appAtts[attIndex++] = da->value; } } else { (da->id->name)[-1] = 1; appAtts[attIndex++] = da->id->name; appAtts[attIndex++] = da->value; } } } appAtts[attIndex] = 0; /* expand prefixed attribute names, check for duplicates, and clear flags that say whether attributes were specified */ i = 0; if (nPrefixes) { int j; /* hash table index */ unsigned long version = parser->m_nsAttsVersion; int nsAttsSize = (int)1 << parser->m_nsAttsPower; unsigned char oldNsAttsPower = parser->m_nsAttsPower; /* size of hash table must be at least 2 * (# of prefixed attributes) */ if ((nPrefixes << 1) >> parser->m_nsAttsPower) { /* true for m_nsAttsPower = 0 */ NS_ATT *temp; /* hash table size must also be a power of 2 and >= 8 */ while (nPrefixes >> parser->m_nsAttsPower++) ; if (parser->m_nsAttsPower < 3) parser->m_nsAttsPower = 3; nsAttsSize = (int)1 << parser->m_nsAttsPower; temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts, nsAttsSize * sizeof(NS_ATT)); if (! temp) { /* Restore actual size of memory in m_nsAtts */ parser->m_nsAttsPower = oldNsAttsPower; return XML_ERROR_NO_MEMORY; } parser->m_nsAtts = temp; version = 0; /* force re-initialization of m_nsAtts hash table */ } /* using a version flag saves us from initializing m_nsAtts every time */ if (! version) { /* initialize version flags when version wraps around */ version = INIT_ATTS_VERSION; for (j = nsAttsSize; j != 0;) parser->m_nsAtts[--j].version = version; } parser->m_nsAttsVersion = --version; /* expand prefixed names and check for duplicates */ for (; i < attIndex; i += 2) { const XML_Char *s = appAtts[i]; if (s[-1] == 2) { /* prefixed */ ATTRIBUTE_ID *id; const BINDING *b; unsigned long uriHash; struct siphash sip_state; struct sipkey sip_key; copy_salt_to_sipkey(parser, &sip_key); sip24_init(&sip_state, &sip_key); ((XML_Char *)s)[-1] = 0; /* clear flag */ id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0); if (! id || ! id->prefix) { /* This code is walking through the appAtts array, dealing * with (in this case) a prefixed attribute name. To be in * the array, the attribute must have already been bound, so * has to have passed through the hash table lookup once * already. That implies that an entry for it already * exists, so the lookup above will return a pointer to * already allocated memory. There is no opportunaity for * the allocator to fail, so the condition above cannot be * fulfilled. * * Since it is difficult to be certain that the above * analysis is complete, we retain the test and merely * remove the code from coverage tests. */ return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */ } b = id->prefix->binding; if (! b) return XML_ERROR_UNBOUND_PREFIX; for (j = 0; j < b->uriLen; j++) { const XML_Char c = b->uri[j]; if (! poolAppendChar(&parser->m_tempPool, c)) return XML_ERROR_NO_MEMORY; } sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char)); while (*s++ != XML_T(ASCII_COLON)) ; sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char)); do { /* copies null terminator */ if (! poolAppendChar(&parser->m_tempPool, *s)) return XML_ERROR_NO_MEMORY; } while (*s++); uriHash = (unsigned long)sip24_final(&sip_state); { /* Check hash table for duplicate of expanded name (uriName). Derived from code in lookup(parser, HASH_TABLE *table, ...). */ unsigned char step = 0; unsigned long mask = nsAttsSize - 1; j = uriHash & mask; /* index into hash table */ while (parser->m_nsAtts[j].version == version) { /* for speed we compare stored hash values first */ if (uriHash == parser->m_nsAtts[j].hash) { const XML_Char *s1 = poolStart(&parser->m_tempPool); const XML_Char *s2 = parser->m_nsAtts[j].uriName; /* s1 is null terminated, but not s2 */ for (; *s1 == *s2 && *s1 != 0; s1++, s2++) ; if (*s1 == 0) return XML_ERROR_DUPLICATE_ATTRIBUTE; } if (! step) step = PROBE_STEP(uriHash, mask, parser->m_nsAttsPower); j < step ? (j += nsAttsSize - step) : (j -= step); } } if (parser->m_ns_triplets) { /* append namespace separator and prefix */ parser->m_tempPool.ptr[-1] = parser->m_namespaceSeparator; s = b->prefix->name; do { if (! poolAppendChar(&parser->m_tempPool, *s)) return XML_ERROR_NO_MEMORY; } while (*s++); } /* store expanded name in attribute list */ s = poolStart(&parser->m_tempPool); poolFinish(&parser->m_tempPool); appAtts[i] = s; /* fill empty slot with new version, uriName and hash value */ parser->m_nsAtts[j].version = version; parser->m_nsAtts[j].hash = uriHash; parser->m_nsAtts[j].uriName = s; if (! --nPrefixes) { i += 2; break; } } else /* not prefixed */ ((XML_Char *)s)[-1] = 0; /* clear flag */ } } /* clear flags for the remaining attributes */ for (; i < attIndex; i += 2) ((XML_Char *)(appAtts[i]))[-1] = 0; for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding) binding->attId->name[-1] = 0; if (! parser->m_ns) return XML_ERROR_NONE; /* expand the element type name */ if (elementType->prefix) { binding = elementType->prefix->binding; if (! binding) return XML_ERROR_UNBOUND_PREFIX; localPart = tagNamePtr->str; while (*localPart++ != XML_T(ASCII_COLON)) ; } else if (dtd->defaultPrefix.binding) { binding = dtd->defaultPrefix.binding; localPart = tagNamePtr->str; } else return XML_ERROR_NONE; prefixLen = 0; if (parser->m_ns_triplets && binding->prefix->name) { for (; binding->prefix->name[prefixLen++];) ; /* prefixLen includes null terminator */ } tagNamePtr->localPart = localPart; tagNamePtr->uriLen = binding->uriLen; tagNamePtr->prefix = binding->prefix->name; tagNamePtr->prefixLen = prefixLen; for (i = 0; localPart[i++];) ; /* i includes null terminator */ n = i + binding->uriLen + prefixLen; if (n > binding->uriAlloc) { TAG *p; uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char)); if (! uri) return XML_ERROR_NO_MEMORY; binding->uriAlloc = n + EXPAND_SPARE; memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char)); for (p = parser->m_tagStack; p; p = p->parent) if (p->name.str == binding->uri) p->name.str = uri; FREE(parser, binding->uri); binding->uri = uri; } /* if m_namespaceSeparator != '\0' then uri includes it already */ uri = binding->uri + binding->uriLen; memcpy(uri, localPart, i * sizeof(XML_Char)); /* we always have a namespace separator between localPart and prefix */ if (prefixLen) { uri += i - 1; *uri = parser->m_namespaceSeparator; /* replace null terminator */ memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char)); } tagNamePtr->str = binding->uri; return XML_ERROR_NONE; } /* addBinding() overwrites the value of prefix->binding without checking. Therefore one must keep track of the old value outside of addBinding(). */ static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr) { static const XML_Char xmlNamespace[] = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'}; static const int xmlLen = (int)sizeof(xmlNamespace) / sizeof(XML_Char) - 1; static const XML_Char xmlnsNamespace[] = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0, ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s, ASCII_SLASH, '\0'}; static const int xmlnsLen = (int)sizeof(xmlnsNamespace) / sizeof(XML_Char) - 1; XML_Bool mustBeXML = XML_FALSE; XML_Bool isXML = XML_TRUE; XML_Bool isXMLNS = XML_TRUE; BINDING *b; int len; /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */ if (*uri == XML_T('\0') && prefix->name) return XML_ERROR_UNDECLARING_PREFIX; if (prefix->name && prefix->name[0] == XML_T(ASCII_x) && prefix->name[1] == XML_T(ASCII_m) && prefix->name[2] == XML_T(ASCII_l)) { /* Not allowed to bind xmlns */ if (prefix->name[3] == XML_T(ASCII_n) && prefix->name[4] == XML_T(ASCII_s) && prefix->name[5] == XML_T('\0')) return XML_ERROR_RESERVED_PREFIX_XMLNS; if (prefix->name[3] == XML_T('\0')) mustBeXML = XML_TRUE; } for (len = 0; uri[len]; len++) { if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len])) isXML = XML_FALSE; if (! mustBeXML && isXMLNS && (len > xmlnsLen || uri[len] != xmlnsNamespace[len])) isXMLNS = XML_FALSE; } isXML = isXML && len == xmlLen; isXMLNS = isXMLNS && len == xmlnsLen; if (mustBeXML != isXML) return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML : XML_ERROR_RESERVED_NAMESPACE_URI; if (isXMLNS) return XML_ERROR_RESERVED_NAMESPACE_URI; if (parser->m_namespaceSeparator) len++; if (parser->m_freeBindingList) { b = parser->m_freeBindingList; if (len > b->uriAlloc) { XML_Char *temp = (XML_Char *)REALLOC( parser, b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE)); if (temp == NULL) return XML_ERROR_NO_MEMORY; b->uri = temp; b->uriAlloc = len + EXPAND_SPARE; } parser->m_freeBindingList = b->nextTagBinding; } else { b = (BINDING *)MALLOC(parser, sizeof(BINDING)); if (! b) return XML_ERROR_NO_MEMORY; b->uri = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE)); if (! b->uri) { FREE(parser, b); return XML_ERROR_NO_MEMORY; } b->uriAlloc = len + EXPAND_SPARE; } b->uriLen = len; memcpy(b->uri, uri, len * sizeof(XML_Char)); if (parser->m_namespaceSeparator) b->uri[len - 1] = parser->m_namespaceSeparator; b->prefix = prefix; b->attId = attId; b->prevPrefixBinding = prefix->binding; /* NULL binding when default namespace undeclared */ if (*uri == XML_T('\0') && prefix == &parser->m_dtd->defaultPrefix) prefix->binding = NULL; else prefix->binding = b; b->nextTagBinding = *bindingsPtr; *bindingsPtr = b; /* if attId == NULL then we are not starting a namespace scope */ if (attId && parser->m_startNamespaceDeclHandler) parser->m_startNamespaceDeclHandler(parser->m_handlerArg, prefix->name, prefix->binding ? uri : 0); return XML_ERROR_NONE; } /* The idea here is to avoid using stack for each CDATA section when the whole file is parsed with one call. */ static enum XML_Error PTRCALL cdataSectionProcessor(XML_Parser parser, const char *start, const char *end, const char **endPtr) { enum XML_Error result = doCdataSection(parser, parser->m_encoding, &start, end, endPtr, (XML_Bool)! parser->m_parsingStatus.finalBuffer); if (result != XML_ERROR_NONE) return result; if (start) { if (parser->m_parentParser) { /* we are parsing an external entity */ parser->m_processor = externalEntityContentProcessor; return externalEntityContentProcessor(parser, start, end, endPtr); } else { parser->m_processor = contentProcessor; return contentProcessor(parser, start, end, endPtr); } } return result; } /* startPtr gets set to non-null if the section is closed, and to null if the section is not yet closed. */ static enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr, const char *end, const char **nextPtr, XML_Bool haveMore) { const char *s = *startPtr; const char **eventPP; const char **eventEndPP; if (enc == parser->m_encoding) { eventPP = &parser->m_eventPtr; *eventPP = s; eventEndPP = &parser->m_eventEndPtr; } else { eventPP = &(parser->m_openInternalEntities->internalEventPtr); eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); } *eventPP = s; *startPtr = NULL; for (;;) { const char *next; int tok = XmlCdataSectionTok(enc, s, end, &next); *eventEndPP = next; switch (tok) { case XML_TOK_CDATA_SECT_CLOSE: if (parser->m_endCdataSectionHandler) parser->m_endCdataSectionHandler(parser->m_handlerArg); /* BEGIN disabled code */ /* see comment under XML_TOK_CDATA_SECT_OPEN */ else if (0 && parser->m_characterDataHandler) parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, 0); /* END disabled code */ else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); *startPtr = next; *nextPtr = next; if (parser->m_parsingStatus.parsing == XML_FINISHED) return XML_ERROR_ABORTED; else return XML_ERROR_NONE; case XML_TOK_DATA_NEWLINE: if (parser->m_characterDataHandler) { XML_Char c = 0xA; parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); } else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); break; case XML_TOK_DATA_CHARS: { XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler; if (charDataHandler) { if (MUST_CONVERT(enc, s)) { for (;;) { ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; const enum XML_Convert_Result convert_res = XmlConvert( enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd); *eventEndPP = next; charDataHandler(parser->m_handlerArg, parser->m_dataBuf, (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) break; *eventPP = s; } } else charDataHandler(parser->m_handlerArg, (XML_Char *)s, (int)((XML_Char *)next - (XML_Char *)s)); } else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); } break; case XML_TOK_INVALID: *eventPP = next; return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL_CHAR: if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_PARTIAL_CHAR; case XML_TOK_PARTIAL: case XML_TOK_NONE: if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_UNCLOSED_CDATA_SECTION; default: /* Every token returned by XmlCdataSectionTok() has its own * explicit case, so this default case will never be executed. * We retain it as a safety net and exclude it from the coverage * statistics. * * LCOV_EXCL_START */ *eventPP = next; return XML_ERROR_UNEXPECTED_STATE; /* LCOV_EXCL_STOP */ } *eventPP = s = next; switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: *nextPtr = next; return XML_ERROR_NONE; case XML_FINISHED: return XML_ERROR_ABORTED; default:; } } /* not reached */ } #ifdef XML_DTD /* The idea here is to avoid using stack for each IGNORE section when the whole file is parsed with one call. */ static enum XML_Error PTRCALL ignoreSectionProcessor(XML_Parser parser, const char *start, const char *end, const char **endPtr) { enum XML_Error result = doIgnoreSection(parser, parser->m_encoding, &start, end, endPtr, (XML_Bool)! parser->m_parsingStatus.finalBuffer); if (result != XML_ERROR_NONE) return result; if (start) { parser->m_processor = prologProcessor; return prologProcessor(parser, start, end, endPtr); } return result; } /* startPtr gets set to non-null is the section is closed, and to null if the section is not yet closed. */ static enum XML_Error doIgnoreSection(XML_Parser parser, const ENCODING *enc, const char **startPtr, const char *end, const char **nextPtr, XML_Bool haveMore) { const char *next; int tok; const char *s = *startPtr; const char **eventPP; const char **eventEndPP; if (enc == parser->m_encoding) { eventPP = &parser->m_eventPtr; *eventPP = s; eventEndPP = &parser->m_eventEndPtr; } else { /* It's not entirely clear, but it seems the following two lines * of code cannot be executed. The only occasions on which 'enc' * is not 'encoding' are when this function is called * from the internal entity processing, and IGNORE sections are an * error in internal entities. * * Since it really isn't clear that this is true, we keep the code * and just remove it from our coverage tests. * * LCOV_EXCL_START */ eventPP = &(parser->m_openInternalEntities->internalEventPtr); eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); /* LCOV_EXCL_STOP */ } *eventPP = s; *startPtr = NULL; tok = XmlIgnoreSectionTok(enc, s, end, &next); *eventEndPP = next; switch (tok) { case XML_TOK_IGNORE_SECT: if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); *startPtr = next; *nextPtr = next; if (parser->m_parsingStatus.parsing == XML_FINISHED) return XML_ERROR_ABORTED; else return XML_ERROR_NONE; case XML_TOK_INVALID: *eventPP = next; return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL_CHAR: if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_PARTIAL_CHAR; case XML_TOK_PARTIAL: case XML_TOK_NONE: if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */ default: /* All of the tokens that XmlIgnoreSectionTok() returns have * explicit cases to handle them, so this default case is never * executed. We keep it as a safety net anyway, and remove it * from our test coverage statistics. * * LCOV_EXCL_START */ *eventPP = next; return XML_ERROR_UNEXPECTED_STATE; /* LCOV_EXCL_STOP */ } /* not reached */ } #endif /* XML_DTD */ static enum XML_Error initializeEncoding(XML_Parser parser) { const char *s; #ifdef XML_UNICODE char encodingBuf[128]; /* See comments abount `protoclEncodingName` in parserInit() */ if (! parser->m_protocolEncodingName) s = NULL; else { int i; for (i = 0; parser->m_protocolEncodingName[i]; i++) { if (i == sizeof(encodingBuf) - 1 || (parser->m_protocolEncodingName[i] & ~0x7f) != 0) { encodingBuf[0] = '\0'; break; } encodingBuf[i] = (char)parser->m_protocolEncodingName[i]; } encodingBuf[i] = '\0'; s = encodingBuf; } #else s = parser->m_protocolEncodingName; #endif if ((parser->m_ns ? XmlInitEncodingNS : XmlInitEncoding)( &parser->m_initEncoding, &parser->m_encoding, s)) return XML_ERROR_NONE; return handleUnknownEncoding(parser, parser->m_protocolEncodingName); } static enum XML_Error processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *s, const char *next) { const char *encodingName = NULL; const XML_Char *storedEncName = NULL; const ENCODING *newEncoding = NULL; const char *version = NULL; const char *versionend; const XML_Char *storedversion = NULL; int standalone = -1; if (! (parser->m_ns ? XmlParseXmlDeclNS : XmlParseXmlDecl)( isGeneralTextEntity, parser->m_encoding, s, next, &parser->m_eventPtr, &version, &versionend, &encodingName, &newEncoding, &standalone)) { if (isGeneralTextEntity) return XML_ERROR_TEXT_DECL; else return XML_ERROR_XML_DECL; } if (! isGeneralTextEntity && standalone == 1) { parser->m_dtd->standalone = XML_TRUE; #ifdef XML_DTD if (parser->m_paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE) parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; #endif /* XML_DTD */ } if (parser->m_xmlDeclHandler) { if (encodingName != NULL) { storedEncName = poolStoreString( &parser->m_temp2Pool, parser->m_encoding, encodingName, encodingName + XmlNameLength(parser->m_encoding, encodingName)); if (! storedEncName) return XML_ERROR_NO_MEMORY; poolFinish(&parser->m_temp2Pool); } if (version) { storedversion = poolStoreString(&parser->m_temp2Pool, parser->m_encoding, version, versionend - parser->m_encoding->minBytesPerChar); if (! storedversion) return XML_ERROR_NO_MEMORY; } parser->m_xmlDeclHandler(parser->m_handlerArg, storedversion, storedEncName, standalone); } else if (parser->m_defaultHandler) reportDefault(parser, parser->m_encoding, s, next); if (parser->m_protocolEncodingName == NULL) { if (newEncoding) { /* Check that the specified encoding does not conflict with what * the parser has already deduced. Do we have the same number * of bytes in the smallest representation of a character? If * this is UTF-16, is it the same endianness? */ if (newEncoding->minBytesPerChar != parser->m_encoding->minBytesPerChar || (newEncoding->minBytesPerChar == 2 && newEncoding != parser->m_encoding)) { parser->m_eventPtr = encodingName; return XML_ERROR_INCORRECT_ENCODING; } parser->m_encoding = newEncoding; } else if (encodingName) { enum XML_Error result; if (! storedEncName) { storedEncName = poolStoreString( &parser->m_temp2Pool, parser->m_encoding, encodingName, encodingName + XmlNameLength(parser->m_encoding, encodingName)); if (! storedEncName) return XML_ERROR_NO_MEMORY; } result = handleUnknownEncoding(parser, storedEncName); poolClear(&parser->m_temp2Pool); if (result == XML_ERROR_UNKNOWN_ENCODING) parser->m_eventPtr = encodingName; return result; } } if (storedEncName || storedversion) poolClear(&parser->m_temp2Pool); return XML_ERROR_NONE; } static enum XML_Error handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) { if (parser->m_unknownEncodingHandler) { XML_Encoding info; int i; for (i = 0; i < 256; i++) info.map[i] = -1; info.convert = NULL; info.data = NULL; info.release = NULL; if (parser->m_unknownEncodingHandler(parser->m_unknownEncodingHandlerData, encodingName, &info)) { ENCODING *enc; parser->m_unknownEncodingMem = MALLOC(parser, XmlSizeOfUnknownEncoding()); if (! parser->m_unknownEncodingMem) { if (info.release) info.release(info.data); return XML_ERROR_NO_MEMORY; } enc = (parser->m_ns ? XmlInitUnknownEncodingNS : XmlInitUnknownEncoding)( parser->m_unknownEncodingMem, info.map, info.convert, info.data); if (enc) { parser->m_unknownEncodingData = info.data; parser->m_unknownEncodingRelease = info.release; parser->m_encoding = enc; return XML_ERROR_NONE; } } if (info.release != NULL) info.release(info.data); } return XML_ERROR_UNKNOWN_ENCODING; } static enum XML_Error PTRCALL prologInitProcessor(XML_Parser parser, const char *s, const char *end, const char **nextPtr) { enum XML_Error result = initializeEncoding(parser); if (result != XML_ERROR_NONE) return result; parser->m_processor = prologProcessor; return prologProcessor(parser, s, end, nextPtr); } #ifdef XML_DTD static enum XML_Error PTRCALL externalParEntInitProcessor(XML_Parser parser, const char *s, const char *end, const char **nextPtr) { enum XML_Error result = initializeEncoding(parser); if (result != XML_ERROR_NONE) return result; /* we know now that XML_Parse(Buffer) has been called, so we consider the external parameter entity read */ parser->m_dtd->paramEntityRead = XML_TRUE; if (parser->m_prologState.inEntityValue) { parser->m_processor = entityValueInitProcessor; return entityValueInitProcessor(parser, s, end, nextPtr); } else { parser->m_processor = externalParEntProcessor; return externalParEntProcessor(parser, s, end, nextPtr); } } static enum XML_Error PTRCALL entityValueInitProcessor(XML_Parser parser, const char *s, const char *end, const char **nextPtr) { int tok; const char *start = s; const char *next = start; parser->m_eventPtr = start; for (;;) { tok = XmlPrologTok(parser->m_encoding, start, end, &next); parser->m_eventEndPtr = next; if (tok <= 0) { if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { *nextPtr = s; return XML_ERROR_NONE; } switch (tok) { case XML_TOK_INVALID: return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL: return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: return XML_ERROR_PARTIAL_CHAR; case XML_TOK_NONE: /* start == end */ default: break; } /* found end of entity value - can store it now */ return storeEntityValue(parser, parser->m_encoding, s, end); } else if (tok == XML_TOK_XML_DECL) { enum XML_Error result; result = processXmlDecl(parser, 0, start, next); if (result != XML_ERROR_NONE) return result; /* At this point, m_parsingStatus.parsing cannot be XML_SUSPENDED. For * that to happen, a parameter entity parsing handler must have attempted * to suspend the parser, which fails and raises an error. The parser can * be aborted, but can't be suspended. */ if (parser->m_parsingStatus.parsing == XML_FINISHED) return XML_ERROR_ABORTED; *nextPtr = next; /* stop scanning for text declaration - we found one */ parser->m_processor = entityValueProcessor; return entityValueProcessor(parser, next, end, nextPtr); } /* If we are at the end of the buffer, this would cause XmlPrologTok to return XML_TOK_NONE on the next call, which would then cause the function to exit with *nextPtr set to s - that is what we want for other tokens, but not for the BOM - we would rather like to skip it; then, when this routine is entered the next time, XmlPrologTok will return XML_TOK_INVALID, since the BOM is still in the buffer */ else if (tok == XML_TOK_BOM && next == end && ! parser->m_parsingStatus.finalBuffer) { *nextPtr = next; return XML_ERROR_NONE; } /* If we get this token, we have the start of what might be a normal tag, but not a declaration (i.e. it doesn't begin with "m_eventPtr = start; } } static enum XML_Error PTRCALL externalParEntProcessor(XML_Parser parser, const char *s, const char *end, const char **nextPtr) { const char *next = s; int tok; tok = XmlPrologTok(parser->m_encoding, s, end, &next); if (tok <= 0) { if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { *nextPtr = s; return XML_ERROR_NONE; } switch (tok) { case XML_TOK_INVALID: return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL: return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: return XML_ERROR_PARTIAL_CHAR; case XML_TOK_NONE: /* start == end */ default: break; } } /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM. However, when parsing an external subset, doProlog will not accept a BOM as valid, and report a syntax error, so we have to skip the BOM */ else if (tok == XML_TOK_BOM) { s = next; tok = XmlPrologTok(parser->m_encoding, s, end, &next); } parser->m_processor = prologProcessor; return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE); } static enum XML_Error PTRCALL entityValueProcessor(XML_Parser parser, const char *s, const char *end, const char **nextPtr) { const char *start = s; const char *next = s; const ENCODING *enc = parser->m_encoding; int tok; for (;;) { tok = XmlPrologTok(enc, start, end, &next); if (tok <= 0) { if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { *nextPtr = s; return XML_ERROR_NONE; } switch (tok) { case XML_TOK_INVALID: return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL: return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: return XML_ERROR_PARTIAL_CHAR; case XML_TOK_NONE: /* start == end */ default: break; } /* found end of entity value - can store it now */ return storeEntityValue(parser, enc, s, end); } start = next; } } #endif /* XML_DTD */ static enum XML_Error PTRCALL prologProcessor(XML_Parser parser, const char *s, const char *end, const char **nextPtr) { const char *next = s; int tok = XmlPrologTok(parser->m_encoding, s, end, &next); return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE); } static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, int tok, const char *next, const char **nextPtr, XML_Bool haveMore, XML_Bool allowClosingDoctype) { #ifdef XML_DTD static const XML_Char externalSubsetName[] = {ASCII_HASH, '\0'}; #endif /* XML_DTD */ static const XML_Char atypeCDATA[] = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'}; static const XML_Char atypeID[] = {ASCII_I, ASCII_D, '\0'}; static const XML_Char atypeIDREF[] = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0'}; static const XML_Char atypeIDREFS[] = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0'}; static const XML_Char atypeENTITY[] = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0'}; static const XML_Char atypeENTITIES[] = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0'}; static const XML_Char atypeNMTOKEN[] = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0'}; static const XML_Char atypeNMTOKENS[] = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0'}; static const XML_Char notationPrefix[] = {ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0'}; static const XML_Char enumValueSep[] = {ASCII_PIPE, '\0'}; static const XML_Char enumValueStart[] = {ASCII_LPAREN, '\0'}; /* save one level of indirection */ DTD *const dtd = parser->m_dtd; const char **eventPP; const char **eventEndPP; enum XML_Content_Quant quant; if (enc == parser->m_encoding) { eventPP = &parser->m_eventPtr; eventEndPP = &parser->m_eventEndPtr; } else { eventPP = &(parser->m_openInternalEntities->internalEventPtr); eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); } for (;;) { int role; XML_Bool handleDefault = XML_TRUE; *eventPP = s; *eventEndPP = next; if (tok <= 0) { if (haveMore && tok != XML_TOK_INVALID) { *nextPtr = s; return XML_ERROR_NONE; } switch (tok) { case XML_TOK_INVALID: *eventPP = next; return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL: return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: return XML_ERROR_PARTIAL_CHAR; case -XML_TOK_PROLOG_S: tok = -tok; break; case XML_TOK_NONE: #ifdef XML_DTD /* for internal PE NOT referenced between declarations */ if (enc != parser->m_encoding && ! parser->m_openInternalEntities->betweenDecl) { *nextPtr = s; return XML_ERROR_NONE; } /* WFC: PE Between Declarations - must check that PE contains complete markup, not only for external PEs, but also for internal PEs if the reference occurs between declarations. */ if (parser->m_isParamEntity || enc != parser->m_encoding) { if (XmlTokenRole(&parser->m_prologState, XML_TOK_NONE, end, end, enc) == XML_ROLE_ERROR) return XML_ERROR_INCOMPLETE_PE; *nextPtr = s; return XML_ERROR_NONE; } #endif /* XML_DTD */ return XML_ERROR_NO_ELEMENTS; default: tok = -tok; next = end; break; } } role = XmlTokenRole(&parser->m_prologState, tok, s, next, enc); switch (role) { case XML_ROLE_XML_DECL: { enum XML_Error result = processXmlDecl(parser, 0, s, next); if (result != XML_ERROR_NONE) return result; enc = parser->m_encoding; handleDefault = XML_FALSE; } break; case XML_ROLE_DOCTYPE_NAME: if (parser->m_startDoctypeDeclHandler) { parser->m_doctypeName = poolStoreString(&parser->m_tempPool, enc, s, next); if (! parser->m_doctypeName) return XML_ERROR_NO_MEMORY; poolFinish(&parser->m_tempPool); parser->m_doctypePubid = NULL; handleDefault = XML_FALSE; } parser->m_doctypeSysid = NULL; /* always initialize to NULL */ break; case XML_ROLE_DOCTYPE_INTERNAL_SUBSET: if (parser->m_startDoctypeDeclHandler) { parser->m_startDoctypeDeclHandler( parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid, parser->m_doctypePubid, 1); parser->m_doctypeName = NULL; poolClear(&parser->m_tempPool); handleDefault = XML_FALSE; } break; #ifdef XML_DTD case XML_ROLE_TEXT_DECL: { enum XML_Error result = processXmlDecl(parser, 1, s, next); if (result != XML_ERROR_NONE) return result; enc = parser->m_encoding; handleDefault = XML_FALSE; } break; #endif /* XML_DTD */ case XML_ROLE_DOCTYPE_PUBLIC_ID: #ifdef XML_DTD parser->m_useForeignDTD = XML_FALSE; parser->m_declEntity = (ENTITY *)lookup( parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY)); if (! parser->m_declEntity) return XML_ERROR_NO_MEMORY; #endif /* XML_DTD */ dtd->hasParamEntityRefs = XML_TRUE; if (parser->m_startDoctypeDeclHandler) { XML_Char *pubId; if (! XmlIsPublicId(enc, s, next, eventPP)) return XML_ERROR_PUBLICID; pubId = poolStoreString(&parser->m_tempPool, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (! pubId) return XML_ERROR_NO_MEMORY; normalizePublicId(pubId); poolFinish(&parser->m_tempPool); parser->m_doctypePubid = pubId; handleDefault = XML_FALSE; goto alreadyChecked; } /* fall through */ case XML_ROLE_ENTITY_PUBLIC_ID: if (! XmlIsPublicId(enc, s, next, eventPP)) return XML_ERROR_PUBLICID; alreadyChecked: if (dtd->keepProcessing && parser->m_declEntity) { XML_Char *tem = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (! tem) return XML_ERROR_NO_MEMORY; normalizePublicId(tem); parser->m_declEntity->publicId = tem; poolFinish(&dtd->pool); /* Don't suppress the default handler if we fell through from * the XML_ROLE_DOCTYPE_PUBLIC_ID case. */ if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_PUBLIC_ID) handleDefault = XML_FALSE; } break; case XML_ROLE_DOCTYPE_CLOSE: if (allowClosingDoctype != XML_TRUE) { /* Must not close doctype from within expanded parameter entities */ return XML_ERROR_INVALID_TOKEN; } if (parser->m_doctypeName) { parser->m_startDoctypeDeclHandler( parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid, parser->m_doctypePubid, 0); poolClear(&parser->m_tempPool); handleDefault = XML_FALSE; } /* parser->m_doctypeSysid will be non-NULL in the case of a previous XML_ROLE_DOCTYPE_SYSTEM_ID, even if parser->m_startDoctypeDeclHandler was not set, indicating an external subset */ #ifdef XML_DTD if (parser->m_doctypeSysid || parser->m_useForeignDTD) { XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; dtd->hasParamEntityRefs = XML_TRUE; if (parser->m_paramEntityParsing && parser->m_externalEntityRefHandler) { ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY)); if (! entity) { /* The external subset name "#" will have already been * inserted into the hash table at the start of the * external entity parsing, so no allocation will happen * and lookup() cannot fail. */ return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */ } if (parser->m_useForeignDTD) entity->base = parser->m_curBase; dtd->paramEntityRead = XML_FALSE; if (! parser->m_externalEntityRefHandler( parser->m_externalEntityRefHandlerArg, 0, entity->base, entity->systemId, entity->publicId)) return XML_ERROR_EXTERNAL_ENTITY_HANDLING; if (dtd->paramEntityRead) { if (! dtd->standalone && parser->m_notStandaloneHandler && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) return XML_ERROR_NOT_STANDALONE; } /* if we didn't read the foreign DTD then this means that there is no external subset and we must reset dtd->hasParamEntityRefs */ else if (! parser->m_doctypeSysid) dtd->hasParamEntityRefs = hadParamEntityRefs; /* end of DTD - no need to update dtd->keepProcessing */ } parser->m_useForeignDTD = XML_FALSE; } #endif /* XML_DTD */ if (parser->m_endDoctypeDeclHandler) { parser->m_endDoctypeDeclHandler(parser->m_handlerArg); handleDefault = XML_FALSE; } break; case XML_ROLE_INSTANCE_START: #ifdef XML_DTD /* if there is no DOCTYPE declaration then now is the last chance to read the foreign DTD */ if (parser->m_useForeignDTD) { XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; dtd->hasParamEntityRefs = XML_TRUE; if (parser->m_paramEntityParsing && parser->m_externalEntityRefHandler) { ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY)); if (! entity) return XML_ERROR_NO_MEMORY; entity->base = parser->m_curBase; dtd->paramEntityRead = XML_FALSE; if (! parser->m_externalEntityRefHandler( parser->m_externalEntityRefHandlerArg, 0, entity->base, entity->systemId, entity->publicId)) return XML_ERROR_EXTERNAL_ENTITY_HANDLING; if (dtd->paramEntityRead) { if (! dtd->standalone && parser->m_notStandaloneHandler && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) return XML_ERROR_NOT_STANDALONE; } /* if we didn't read the foreign DTD then this means that there is no external subset and we must reset dtd->hasParamEntityRefs */ else dtd->hasParamEntityRefs = hadParamEntityRefs; /* end of DTD - no need to update dtd->keepProcessing */ } } #endif /* XML_DTD */ parser->m_processor = contentProcessor; return contentProcessor(parser, s, end, nextPtr); case XML_ROLE_ATTLIST_ELEMENT_NAME: parser->m_declElementType = getElementType(parser, enc, s, next); if (! parser->m_declElementType) return XML_ERROR_NO_MEMORY; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_NAME: parser->m_declAttributeId = getAttributeId(parser, enc, s, next); if (! parser->m_declAttributeId) return XML_ERROR_NO_MEMORY; parser->m_declAttributeIsCdata = XML_FALSE; parser->m_declAttributeType = NULL; parser->m_declAttributeIsId = XML_FALSE; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_TYPE_CDATA: parser->m_declAttributeIsCdata = XML_TRUE; parser->m_declAttributeType = atypeCDATA; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_TYPE_ID: parser->m_declAttributeIsId = XML_TRUE; parser->m_declAttributeType = atypeID; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_TYPE_IDREF: parser->m_declAttributeType = atypeIDREF; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_TYPE_IDREFS: parser->m_declAttributeType = atypeIDREFS; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_TYPE_ENTITY: parser->m_declAttributeType = atypeENTITY; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES: parser->m_declAttributeType = atypeENTITIES; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN: parser->m_declAttributeType = atypeNMTOKEN; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS: parser->m_declAttributeType = atypeNMTOKENS; checkAttListDeclHandler: if (dtd->keepProcessing && parser->m_attlistDeclHandler) handleDefault = XML_FALSE; break; case XML_ROLE_ATTRIBUTE_ENUM_VALUE: case XML_ROLE_ATTRIBUTE_NOTATION_VALUE: if (dtd->keepProcessing && parser->m_attlistDeclHandler) { const XML_Char *prefix; if (parser->m_declAttributeType) { prefix = enumValueSep; } else { prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE ? notationPrefix : enumValueStart); } if (! poolAppendString(&parser->m_tempPool, prefix)) return XML_ERROR_NO_MEMORY; if (! poolAppend(&parser->m_tempPool, enc, s, next)) return XML_ERROR_NO_MEMORY; parser->m_declAttributeType = parser->m_tempPool.start; handleDefault = XML_FALSE; } break; case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE: case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE: if (dtd->keepProcessing) { if (! defineAttribute(parser->m_declElementType, parser->m_declAttributeId, parser->m_declAttributeIsCdata, parser->m_declAttributeIsId, 0, parser)) return XML_ERROR_NO_MEMORY; if (parser->m_attlistDeclHandler && parser->m_declAttributeType) { if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN) || (*parser->m_declAttributeType == XML_T(ASCII_N) && parser->m_declAttributeType[1] == XML_T(ASCII_O))) { /* Enumerated or Notation type */ if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN)) || ! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) return XML_ERROR_NO_MEMORY; parser->m_declAttributeType = parser->m_tempPool.start; poolFinish(&parser->m_tempPool); } *eventEndPP = s; parser->m_attlistDeclHandler( parser->m_handlerArg, parser->m_declElementType->name, parser->m_declAttributeId->name, parser->m_declAttributeType, 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE); poolClear(&parser->m_tempPool); handleDefault = XML_FALSE; } } break; case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE: case XML_ROLE_FIXED_ATTRIBUTE_VALUE: if (dtd->keepProcessing) { const XML_Char *attVal; enum XML_Error result = storeAttributeValue( parser, enc, parser->m_declAttributeIsCdata, s + enc->minBytesPerChar, next - enc->minBytesPerChar, &dtd->pool); if (result) return result; attVal = poolStart(&dtd->pool); poolFinish(&dtd->pool); /* ID attributes aren't allowed to have a default */ if (! defineAttribute( parser->m_declElementType, parser->m_declAttributeId, parser->m_declAttributeIsCdata, XML_FALSE, attVal, parser)) return XML_ERROR_NO_MEMORY; if (parser->m_attlistDeclHandler && parser->m_declAttributeType) { if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN) || (*parser->m_declAttributeType == XML_T(ASCII_N) && parser->m_declAttributeType[1] == XML_T(ASCII_O))) { /* Enumerated or Notation type */ if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN)) || ! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) return XML_ERROR_NO_MEMORY; parser->m_declAttributeType = parser->m_tempPool.start; poolFinish(&parser->m_tempPool); } *eventEndPP = s; parser->m_attlistDeclHandler( parser->m_handlerArg, parser->m_declElementType->name, parser->m_declAttributeId->name, parser->m_declAttributeType, attVal, role == XML_ROLE_FIXED_ATTRIBUTE_VALUE); poolClear(&parser->m_tempPool); handleDefault = XML_FALSE; } } break; case XML_ROLE_ENTITY_VALUE: if (dtd->keepProcessing) { enum XML_Error result = storeEntityValue( parser, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (parser->m_declEntity) { parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool); parser->m_declEntity->textLen = (int)(poolLength(&dtd->entityValuePool)); poolFinish(&dtd->entityValuePool); if (parser->m_entityDeclHandler) { *eventEndPP = s; parser->m_entityDeclHandler( parser->m_handlerArg, parser->m_declEntity->name, parser->m_declEntity->is_param, parser->m_declEntity->textPtr, parser->m_declEntity->textLen, parser->m_curBase, 0, 0, 0); handleDefault = XML_FALSE; } } else poolDiscard(&dtd->entityValuePool); if (result != XML_ERROR_NONE) return result; } break; case XML_ROLE_DOCTYPE_SYSTEM_ID: #ifdef XML_DTD parser->m_useForeignDTD = XML_FALSE; #endif /* XML_DTD */ dtd->hasParamEntityRefs = XML_TRUE; if (parser->m_startDoctypeDeclHandler) { parser->m_doctypeSysid = poolStoreString(&parser->m_tempPool, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (parser->m_doctypeSysid == NULL) return XML_ERROR_NO_MEMORY; poolFinish(&parser->m_tempPool); handleDefault = XML_FALSE; } #ifdef XML_DTD else /* use externalSubsetName to make parser->m_doctypeSysid non-NULL for the case where no parser->m_startDoctypeDeclHandler is set */ parser->m_doctypeSysid = externalSubsetName; #endif /* XML_DTD */ if (! dtd->standalone #ifdef XML_DTD && ! parser->m_paramEntityParsing #endif /* XML_DTD */ && parser->m_notStandaloneHandler && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) return XML_ERROR_NOT_STANDALONE; #ifndef XML_DTD break; #else /* XML_DTD */ if (! parser->m_declEntity) { parser->m_declEntity = (ENTITY *)lookup( parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY)); if (! parser->m_declEntity) return XML_ERROR_NO_MEMORY; parser->m_declEntity->publicId = NULL; } #endif /* XML_DTD */ /* fall through */ case XML_ROLE_ENTITY_SYSTEM_ID: if (dtd->keepProcessing && parser->m_declEntity) { parser->m_declEntity->systemId = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (! parser->m_declEntity->systemId) return XML_ERROR_NO_MEMORY; parser->m_declEntity->base = parser->m_curBase; poolFinish(&dtd->pool); /* Don't suppress the default handler if we fell through from * the XML_ROLE_DOCTYPE_SYSTEM_ID case. */ if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_SYSTEM_ID) handleDefault = XML_FALSE; } break; case XML_ROLE_ENTITY_COMPLETE: if (dtd->keepProcessing && parser->m_declEntity && parser->m_entityDeclHandler) { *eventEndPP = s; parser->m_entityDeclHandler( parser->m_handlerArg, parser->m_declEntity->name, parser->m_declEntity->is_param, 0, 0, parser->m_declEntity->base, parser->m_declEntity->systemId, parser->m_declEntity->publicId, 0); handleDefault = XML_FALSE; } break; case XML_ROLE_ENTITY_NOTATION_NAME: if (dtd->keepProcessing && parser->m_declEntity) { parser->m_declEntity->notation = poolStoreString(&dtd->pool, enc, s, next); if (! parser->m_declEntity->notation) return XML_ERROR_NO_MEMORY; poolFinish(&dtd->pool); if (parser->m_unparsedEntityDeclHandler) { *eventEndPP = s; parser->m_unparsedEntityDeclHandler( parser->m_handlerArg, parser->m_declEntity->name, parser->m_declEntity->base, parser->m_declEntity->systemId, parser->m_declEntity->publicId, parser->m_declEntity->notation); handleDefault = XML_FALSE; } else if (parser->m_entityDeclHandler) { *eventEndPP = s; parser->m_entityDeclHandler( parser->m_handlerArg, parser->m_declEntity->name, 0, 0, 0, parser->m_declEntity->base, parser->m_declEntity->systemId, parser->m_declEntity->publicId, parser->m_declEntity->notation); handleDefault = XML_FALSE; } } break; case XML_ROLE_GENERAL_ENTITY_NAME: { if (XmlPredefinedEntityName(enc, s, next)) { parser->m_declEntity = NULL; break; } if (dtd->keepProcessing) { const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); if (! name) return XML_ERROR_NO_MEMORY; parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, sizeof(ENTITY)); if (! parser->m_declEntity) return XML_ERROR_NO_MEMORY; if (parser->m_declEntity->name != name) { poolDiscard(&dtd->pool); parser->m_declEntity = NULL; } else { poolFinish(&dtd->pool); parser->m_declEntity->publicId = NULL; parser->m_declEntity->is_param = XML_FALSE; /* if we have a parent parser or are reading an internal parameter entity, then the entity declaration is not considered "internal" */ parser->m_declEntity->is_internal = ! (parser->m_parentParser || parser->m_openInternalEntities); if (parser->m_entityDeclHandler) handleDefault = XML_FALSE; } } else { poolDiscard(&dtd->pool); parser->m_declEntity = NULL; } } break; case XML_ROLE_PARAM_ENTITY_NAME: #ifdef XML_DTD if (dtd->keepProcessing) { const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); if (! name) return XML_ERROR_NO_MEMORY; parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, sizeof(ENTITY)); if (! parser->m_declEntity) return XML_ERROR_NO_MEMORY; if (parser->m_declEntity->name != name) { poolDiscard(&dtd->pool); parser->m_declEntity = NULL; } else { poolFinish(&dtd->pool); parser->m_declEntity->publicId = NULL; parser->m_declEntity->is_param = XML_TRUE; /* if we have a parent parser or are reading an internal parameter entity, then the entity declaration is not considered "internal" */ parser->m_declEntity->is_internal = ! (parser->m_parentParser || parser->m_openInternalEntities); if (parser->m_entityDeclHandler) handleDefault = XML_FALSE; } } else { poolDiscard(&dtd->pool); parser->m_declEntity = NULL; } #else /* not XML_DTD */ parser->m_declEntity = NULL; #endif /* XML_DTD */ break; case XML_ROLE_NOTATION_NAME: parser->m_declNotationPublicId = NULL; parser->m_declNotationName = NULL; if (parser->m_notationDeclHandler) { parser->m_declNotationName = poolStoreString(&parser->m_tempPool, enc, s, next); if (! parser->m_declNotationName) return XML_ERROR_NO_MEMORY; poolFinish(&parser->m_tempPool); handleDefault = XML_FALSE; } break; case XML_ROLE_NOTATION_PUBLIC_ID: if (! XmlIsPublicId(enc, s, next, eventPP)) return XML_ERROR_PUBLICID; if (parser ->m_declNotationName) { /* means m_notationDeclHandler != NULL */ XML_Char *tem = poolStoreString(&parser->m_tempPool, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (! tem) return XML_ERROR_NO_MEMORY; normalizePublicId(tem); parser->m_declNotationPublicId = tem; poolFinish(&parser->m_tempPool); handleDefault = XML_FALSE; } break; case XML_ROLE_NOTATION_SYSTEM_ID: if (parser->m_declNotationName && parser->m_notationDeclHandler) { const XML_Char *systemId = poolStoreString(&parser->m_tempPool, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (! systemId) return XML_ERROR_NO_MEMORY; *eventEndPP = s; parser->m_notationDeclHandler( parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase, systemId, parser->m_declNotationPublicId); handleDefault = XML_FALSE; } poolClear(&parser->m_tempPool); break; case XML_ROLE_NOTATION_NO_SYSTEM_ID: if (parser->m_declNotationPublicId && parser->m_notationDeclHandler) { *eventEndPP = s; parser->m_notationDeclHandler( parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase, 0, parser->m_declNotationPublicId); handleDefault = XML_FALSE; } poolClear(&parser->m_tempPool); break; case XML_ROLE_ERROR: switch (tok) { case XML_TOK_PARAM_ENTITY_REF: /* PE references in internal subset are not allowed within declarations. */ return XML_ERROR_PARAM_ENTITY_REF; case XML_TOK_XML_DECL: return XML_ERROR_MISPLACED_XML_PI; default: return XML_ERROR_SYNTAX; } #ifdef XML_DTD case XML_ROLE_IGNORE_SECT: { enum XML_Error result; if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); handleDefault = XML_FALSE; result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore); if (result != XML_ERROR_NONE) return result; else if (! next) { parser->m_processor = ignoreSectionProcessor; return result; } } break; #endif /* XML_DTD */ case XML_ROLE_GROUP_OPEN: if (parser->m_prologState.level >= parser->m_groupSize) { if (parser->m_groupSize) { { char *const new_connector = (char *)REALLOC( parser, parser->m_groupConnector, parser->m_groupSize *= 2); if (new_connector == NULL) { parser->m_groupSize /= 2; return XML_ERROR_NO_MEMORY; } parser->m_groupConnector = new_connector; } if (dtd->scaffIndex) { int *const new_scaff_index = (int *)REALLOC( parser, dtd->scaffIndex, parser->m_groupSize * sizeof(int)); if (new_scaff_index == NULL) return XML_ERROR_NO_MEMORY; dtd->scaffIndex = new_scaff_index; } } else { parser->m_groupConnector = (char *)MALLOC(parser, parser->m_groupSize = 32); if (! parser->m_groupConnector) { parser->m_groupSize = 0; return XML_ERROR_NO_MEMORY; } } } parser->m_groupConnector[parser->m_prologState.level] = 0; if (dtd->in_eldecl) { int myindex = nextScaffoldPart(parser); if (myindex < 0) return XML_ERROR_NO_MEMORY; assert(dtd->scaffIndex != NULL); dtd->scaffIndex[dtd->scaffLevel] = myindex; dtd->scaffLevel++; dtd->scaffold[myindex].type = XML_CTYPE_SEQ; if (parser->m_elementDeclHandler) handleDefault = XML_FALSE; } break; case XML_ROLE_GROUP_SEQUENCE: if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_PIPE) return XML_ERROR_SYNTAX; parser->m_groupConnector[parser->m_prologState.level] = ASCII_COMMA; if (dtd->in_eldecl && parser->m_elementDeclHandler) handleDefault = XML_FALSE; break; case XML_ROLE_GROUP_CHOICE: if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_COMMA) return XML_ERROR_SYNTAX; if (dtd->in_eldecl && ! parser->m_groupConnector[parser->m_prologState.level] && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type != XML_CTYPE_MIXED)) { dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type = XML_CTYPE_CHOICE; if (parser->m_elementDeclHandler) handleDefault = XML_FALSE; } parser->m_groupConnector[parser->m_prologState.level] = ASCII_PIPE; break; case XML_ROLE_PARAM_ENTITY_REF: #ifdef XML_DTD case XML_ROLE_INNER_PARAM_ENTITY_REF: dtd->hasParamEntityRefs = XML_TRUE; if (! parser->m_paramEntityParsing) dtd->keepProcessing = dtd->standalone; else { const XML_Char *name; ENTITY *entity; name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (! name) return XML_ERROR_NO_MEMORY; entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0); poolDiscard(&dtd->pool); /* first, determine if a check for an existing declaration is needed; if yes, check that the entity exists, and that it is internal, otherwise call the skipped entity handler */ if (parser->m_prologState.documentEntity && (dtd->standalone ? ! parser->m_openInternalEntities : ! dtd->hasParamEntityRefs)) { if (! entity) return XML_ERROR_UNDEFINED_ENTITY; else if (! entity->is_internal) { /* It's hard to exhaustively search the code to be sure, * but there doesn't seem to be a way of executing the * following line. There are two cases: * * If 'standalone' is false, the DTD must have no * parameter entities or we wouldn't have passed the outer * 'if' statement. That measn the only entity in the hash * table is the external subset name "#" which cannot be * given as a parameter entity name in XML syntax, so the * lookup must have returned NULL and we don't even reach * the test for an internal entity. * * If 'standalone' is true, it does not seem to be * possible to create entities taking this code path that * are not internal entities, so fail the test above. * * Because this analysis is very uncertain, the code is * being left in place and merely removed from the * coverage test statistics. */ return XML_ERROR_ENTITY_DECLARED_IN_PE; /* LCOV_EXCL_LINE */ } } else if (! entity) { dtd->keepProcessing = dtd->standalone; /* cannot report skipped entities in declarations */ if ((role == XML_ROLE_PARAM_ENTITY_REF) && parser->m_skippedEntityHandler) { parser->m_skippedEntityHandler(parser->m_handlerArg, name, 1); handleDefault = XML_FALSE; } break; } if (entity->open) return XML_ERROR_RECURSIVE_ENTITY_REF; if (entity->textPtr) { enum XML_Error result; XML_Bool betweenDecl = (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE); result = processInternalEntity(parser, entity, betweenDecl); if (result != XML_ERROR_NONE) return result; handleDefault = XML_FALSE; break; } if (parser->m_externalEntityRefHandler) { dtd->paramEntityRead = XML_FALSE; entity->open = XML_TRUE; if (! parser->m_externalEntityRefHandler( parser->m_externalEntityRefHandlerArg, 0, entity->base, entity->systemId, entity->publicId)) { entity->open = XML_FALSE; return XML_ERROR_EXTERNAL_ENTITY_HANDLING; } entity->open = XML_FALSE; handleDefault = XML_FALSE; if (! dtd->paramEntityRead) { dtd->keepProcessing = dtd->standalone; break; } } else { dtd->keepProcessing = dtd->standalone; break; } } #endif /* XML_DTD */ if (! dtd->standalone && parser->m_notStandaloneHandler && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) return XML_ERROR_NOT_STANDALONE; break; /* Element declaration stuff */ case XML_ROLE_ELEMENT_NAME: if (parser->m_elementDeclHandler) { parser->m_declElementType = getElementType(parser, enc, s, next); if (! parser->m_declElementType) return XML_ERROR_NO_MEMORY; dtd->scaffLevel = 0; dtd->scaffCount = 0; dtd->in_eldecl = XML_TRUE; handleDefault = XML_FALSE; } break; case XML_ROLE_CONTENT_ANY: case XML_ROLE_CONTENT_EMPTY: if (dtd->in_eldecl) { if (parser->m_elementDeclHandler) { XML_Content *content = (XML_Content *)MALLOC(parser, sizeof(XML_Content)); if (! content) return XML_ERROR_NO_MEMORY; content->quant = XML_CQUANT_NONE; content->name = NULL; content->numchildren = 0; content->children = NULL; content->type = ((role == XML_ROLE_CONTENT_ANY) ? XML_CTYPE_ANY : XML_CTYPE_EMPTY); *eventEndPP = s; parser->m_elementDeclHandler( parser->m_handlerArg, parser->m_declElementType->name, content); handleDefault = XML_FALSE; } dtd->in_eldecl = XML_FALSE; } break; case XML_ROLE_CONTENT_PCDATA: if (dtd->in_eldecl) { dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type = XML_CTYPE_MIXED; if (parser->m_elementDeclHandler) handleDefault = XML_FALSE; } break; case XML_ROLE_CONTENT_ELEMENT: quant = XML_CQUANT_NONE; goto elementContent; case XML_ROLE_CONTENT_ELEMENT_OPT: quant = XML_CQUANT_OPT; goto elementContent; case XML_ROLE_CONTENT_ELEMENT_REP: quant = XML_CQUANT_REP; goto elementContent; case XML_ROLE_CONTENT_ELEMENT_PLUS: quant = XML_CQUANT_PLUS; elementContent: if (dtd->in_eldecl) { ELEMENT_TYPE *el; const XML_Char *name; int nameLen; const char *nxt = (quant == XML_CQUANT_NONE ? next : next - enc->minBytesPerChar); int myindex = nextScaffoldPart(parser); if (myindex < 0) return XML_ERROR_NO_MEMORY; dtd->scaffold[myindex].type = XML_CTYPE_NAME; dtd->scaffold[myindex].quant = quant; el = getElementType(parser, enc, s, nxt); if (! el) return XML_ERROR_NO_MEMORY; name = el->name; dtd->scaffold[myindex].name = name; nameLen = 0; for (; name[nameLen++];) ; dtd->contentStringLen += nameLen; if (parser->m_elementDeclHandler) handleDefault = XML_FALSE; } break; case XML_ROLE_GROUP_CLOSE: quant = XML_CQUANT_NONE; goto closeGroup; case XML_ROLE_GROUP_CLOSE_OPT: quant = XML_CQUANT_OPT; goto closeGroup; case XML_ROLE_GROUP_CLOSE_REP: quant = XML_CQUANT_REP; goto closeGroup; case XML_ROLE_GROUP_CLOSE_PLUS: quant = XML_CQUANT_PLUS; closeGroup: if (dtd->in_eldecl) { if (parser->m_elementDeclHandler) handleDefault = XML_FALSE; dtd->scaffLevel--; dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant; if (dtd->scaffLevel == 0) { if (! handleDefault) { XML_Content *model = build_model(parser); if (! model) return XML_ERROR_NO_MEMORY; *eventEndPP = s; parser->m_elementDeclHandler( parser->m_handlerArg, parser->m_declElementType->name, model); } dtd->in_eldecl = XML_FALSE; dtd->contentStringLen = 0; } } break; /* End element declaration stuff */ case XML_ROLE_PI: if (! reportProcessingInstruction(parser, enc, s, next)) return XML_ERROR_NO_MEMORY; handleDefault = XML_FALSE; break; case XML_ROLE_COMMENT: if (! reportComment(parser, enc, s, next)) return XML_ERROR_NO_MEMORY; handleDefault = XML_FALSE; break; case XML_ROLE_NONE: switch (tok) { case XML_TOK_BOM: handleDefault = XML_FALSE; break; } break; case XML_ROLE_DOCTYPE_NONE: if (parser->m_startDoctypeDeclHandler) handleDefault = XML_FALSE; break; case XML_ROLE_ENTITY_NONE: if (dtd->keepProcessing && parser->m_entityDeclHandler) handleDefault = XML_FALSE; break; case XML_ROLE_NOTATION_NONE: if (parser->m_notationDeclHandler) handleDefault = XML_FALSE; break; case XML_ROLE_ATTLIST_NONE: if (dtd->keepProcessing && parser->m_attlistDeclHandler) handleDefault = XML_FALSE; break; case XML_ROLE_ELEMENT_NONE: if (parser->m_elementDeclHandler) handleDefault = XML_FALSE; break; } /* end of big switch */ if (handleDefault && parser->m_defaultHandler) reportDefault(parser, enc, s, next); switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: *nextPtr = next; return XML_ERROR_NONE; case XML_FINISHED: return XML_ERROR_ABORTED; default: s = next; tok = XmlPrologTok(enc, s, end, &next); } } /* not reached */ } static enum XML_Error PTRCALL epilogProcessor(XML_Parser parser, const char *s, const char *end, const char **nextPtr) { parser->m_processor = epilogProcessor; parser->m_eventPtr = s; for (;;) { const char *next = NULL; int tok = XmlPrologTok(parser->m_encoding, s, end, &next); parser->m_eventEndPtr = next; switch (tok) { /* report partial linebreak - it might be the last token */ case -XML_TOK_PROLOG_S: if (parser->m_defaultHandler) { reportDefault(parser, parser->m_encoding, s, next); if (parser->m_parsingStatus.parsing == XML_FINISHED) return XML_ERROR_ABORTED; } *nextPtr = next; return XML_ERROR_NONE; case XML_TOK_NONE: *nextPtr = s; return XML_ERROR_NONE; case XML_TOK_PROLOG_S: if (parser->m_defaultHandler) reportDefault(parser, parser->m_encoding, s, next); break; case XML_TOK_PI: if (! reportProcessingInstruction(parser, parser->m_encoding, s, next)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_COMMENT: if (! reportComment(parser, parser->m_encoding, s, next)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_INVALID: parser->m_eventPtr = next; return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL: if (! parser->m_parsingStatus.finalBuffer) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: if (! parser->m_parsingStatus.finalBuffer) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_PARTIAL_CHAR; default: return XML_ERROR_JUNK_AFTER_DOC_ELEMENT; } parser->m_eventPtr = s = next; switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: *nextPtr = next; return XML_ERROR_NONE; case XML_FINISHED: return XML_ERROR_ABORTED; default:; } } } static enum XML_Error processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) { const char *textStart, *textEnd; const char *next; enum XML_Error result; OPEN_INTERNAL_ENTITY *openEntity; if (parser->m_freeInternalEntities) { openEntity = parser->m_freeInternalEntities; parser->m_freeInternalEntities = openEntity->next; } else { openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY)); if (! openEntity) return XML_ERROR_NO_MEMORY; } entity->open = XML_TRUE; entity->processed = 0; openEntity->next = parser->m_openInternalEntities; parser->m_openInternalEntities = openEntity; openEntity->entity = entity; openEntity->startTagLevel = parser->m_tagLevel; openEntity->betweenDecl = betweenDecl; openEntity->internalEventPtr = NULL; openEntity->internalEventEndPtr = NULL; textStart = (char *)entity->textPtr; textEnd = (char *)(entity->textPtr + entity->textLen); /* Set a safe default value in case 'next' does not get set */ next = textStart; #ifdef XML_DTD if (entity->is_param) { int tok = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, tok, next, &next, XML_FALSE, XML_FALSE); } else #endif /* XML_DTD */ result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding, textStart, textEnd, &next, XML_FALSE); if (result == XML_ERROR_NONE) { if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) { entity->processed = (int)(next - textStart); parser->m_processor = internalEntityProcessor; } else { entity->open = XML_FALSE; parser->m_openInternalEntities = openEntity->next; /* put openEntity back in list of free instances */ openEntity->next = parser->m_freeInternalEntities; parser->m_freeInternalEntities = openEntity; } } return result; } static enum XML_Error PTRCALL internalEntityProcessor(XML_Parser parser, const char *s, const char *end, const char **nextPtr) { ENTITY *entity; const char *textStart, *textEnd; const char *next; enum XML_Error result; OPEN_INTERNAL_ENTITY *openEntity = parser->m_openInternalEntities; if (! openEntity) return XML_ERROR_UNEXPECTED_STATE; entity = openEntity->entity; textStart = ((char *)entity->textPtr) + entity->processed; textEnd = (char *)(entity->textPtr + entity->textLen); /* Set a safe default value in case 'next' does not get set */ next = textStart; #ifdef XML_DTD if (entity->is_param) { int tok = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, tok, next, &next, XML_FALSE, XML_TRUE); } else #endif /* XML_DTD */ result = doContent(parser, openEntity->startTagLevel, parser->m_internalEncoding, textStart, textEnd, &next, XML_FALSE); if (result != XML_ERROR_NONE) return result; else if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) { entity->processed = (int)(next - (char *)entity->textPtr); return result; } else { entity->open = XML_FALSE; parser->m_openInternalEntities = openEntity->next; /* put openEntity back in list of free instances */ openEntity->next = parser->m_freeInternalEntities; parser->m_freeInternalEntities = openEntity; } #ifdef XML_DTD if (entity->is_param) { int tok; parser->m_processor = prologProcessor; tok = XmlPrologTok(parser->m_encoding, s, end, &next); return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE); } else #endif /* XML_DTD */ { parser->m_processor = contentProcessor; /* see externalEntityContentProcessor vs contentProcessor */ return doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding, s, end, nextPtr, (XML_Bool)! parser->m_parsingStatus.finalBuffer); } } static enum XML_Error PTRCALL errorProcessor(XML_Parser parser, const char *s, const char *end, const char **nextPtr) { UNUSED_P(s); UNUSED_P(end); UNUSED_P(nextPtr); return parser->m_errorCode; } static enum XML_Error storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, const char *ptr, const char *end, STRING_POOL *pool) { enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, end, pool); if (result) return result; if (! isCdata && poolLength(pool) && poolLastChar(pool) == 0x20) poolChop(pool); if (! poolAppendChar(pool, XML_T('\0'))) return XML_ERROR_NO_MEMORY; return XML_ERROR_NONE; } static enum XML_Error appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, const char *ptr, const char *end, STRING_POOL *pool) { DTD *const dtd = parser->m_dtd; /* save one level of indirection */ for (;;) { const char *next; int tok = XmlAttributeValueTok(enc, ptr, end, &next); switch (tok) { case XML_TOK_NONE: return XML_ERROR_NONE; case XML_TOK_INVALID: if (enc == parser->m_encoding) parser->m_eventPtr = next; return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL: if (enc == parser->m_encoding) parser->m_eventPtr = ptr; return XML_ERROR_INVALID_TOKEN; case XML_TOK_CHAR_REF: { XML_Char buf[XML_ENCODE_MAX]; int i; int n = XmlCharRefNumber(enc, ptr); if (n < 0) { if (enc == parser->m_encoding) parser->m_eventPtr = ptr; return XML_ERROR_BAD_CHAR_REF; } if (! isCdata && n == 0x20 /* space */ && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) break; n = XmlEncode(n, (ICHAR *)buf); /* The XmlEncode() functions can never return 0 here. That * error return happens if the code point passed in is either * negative or greater than or equal to 0x110000. The * XmlCharRefNumber() functions will all return a number * strictly less than 0x110000 or a negative value if an error * occurred. The negative value is intercepted above, so * XmlEncode() is never passed a value it might return an * error for. */ for (i = 0; i < n; i++) { if (! poolAppendChar(pool, buf[i])) return XML_ERROR_NO_MEMORY; } } break; case XML_TOK_DATA_CHARS: if (! poolAppend(pool, enc, ptr, next)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_TRAILING_CR: next = ptr + enc->minBytesPerChar; /* fall through */ case XML_TOK_ATTRIBUTE_VALUE_S: case XML_TOK_DATA_NEWLINE: if (! isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) break; if (! poolAppendChar(pool, 0x20)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_ENTITY_REF: { const XML_Char *name; ENTITY *entity; char checkEntityDecl; XML_Char ch = (XML_Char)XmlPredefinedEntityName( enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar); if (ch) { if (! poolAppendChar(pool, ch)) return XML_ERROR_NO_MEMORY; break; } name = poolStoreString(&parser->m_temp2Pool, enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar); if (! name) return XML_ERROR_NO_MEMORY; entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0); poolDiscard(&parser->m_temp2Pool); /* First, determine if a check for an existing declaration is needed; if yes, check that the entity exists, and that it is internal. */ if (pool == &dtd->pool) /* are we called from prolog? */ checkEntityDecl = #ifdef XML_DTD parser->m_prologState.documentEntity && #endif /* XML_DTD */ (dtd->standalone ? ! parser->m_openInternalEntities : ! dtd->hasParamEntityRefs); else /* if (pool == &parser->m_tempPool): we are called from content */ checkEntityDecl = ! dtd->hasParamEntityRefs || dtd->standalone; if (checkEntityDecl) { if (! entity) return XML_ERROR_UNDEFINED_ENTITY; else if (! entity->is_internal) return XML_ERROR_ENTITY_DECLARED_IN_PE; } else if (! entity) { /* Cannot report skipped entity here - see comments on parser->m_skippedEntityHandler. if (parser->m_skippedEntityHandler) parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); */ /* Cannot call the default handler because this would be out of sync with the call to the startElementHandler. if ((pool == &parser->m_tempPool) && parser->m_defaultHandler) reportDefault(parser, enc, ptr, next); */ break; } if (entity->open) { if (enc == parser->m_encoding) { /* It does not appear that this line can be executed. * * The "if (entity->open)" check catches recursive entity * definitions. In order to be called with an open * entity, it must have gone through this code before and * been through the recursive call to * appendAttributeValue() some lines below. That call * sets the local encoding ("enc") to the parser's * internal encoding (internal_utf8 or internal_utf16), * which can never be the same as the principle encoding. * It doesn't appear there is another code path that gets * here with entity->open being TRUE. * * Since it is not certain that this logic is watertight, * we keep the line and merely exclude it from coverage * tests. */ parser->m_eventPtr = ptr; /* LCOV_EXCL_LINE */ } return XML_ERROR_RECURSIVE_ENTITY_REF; } if (entity->notation) { if (enc == parser->m_encoding) parser->m_eventPtr = ptr; return XML_ERROR_BINARY_ENTITY_REF; } if (! entity->textPtr) { if (enc == parser->m_encoding) parser->m_eventPtr = ptr; return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF; } else { enum XML_Error result; const XML_Char *textEnd = entity->textPtr + entity->textLen; entity->open = XML_TRUE; result = appendAttributeValue(parser, parser->m_internalEncoding, isCdata, (char *)entity->textPtr, (char *)textEnd, pool); entity->open = XML_FALSE; if (result) return result; } } break; default: /* The only token returned by XmlAttributeValueTok() that does * not have an explicit case here is XML_TOK_PARTIAL_CHAR. * Getting that would require an entity name to contain an * incomplete XML character (e.g. \xE2\x82); however previous * tokenisers will have already recognised and rejected such * names before XmlAttributeValueTok() gets a look-in. This * default case should be retained as a safety net, but the code * excluded from coverage tests. * * LCOV_EXCL_START */ if (enc == parser->m_encoding) parser->m_eventPtr = ptr; return XML_ERROR_UNEXPECTED_STATE; /* LCOV_EXCL_STOP */ } ptr = next; } /* not reached */ } static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *entityTextPtr, const char *entityTextEnd) { DTD *const dtd = parser->m_dtd; /* save one level of indirection */ STRING_POOL *pool = &(dtd->entityValuePool); enum XML_Error result = XML_ERROR_NONE; #ifdef XML_DTD int oldInEntityValue = parser->m_prologState.inEntityValue; parser->m_prologState.inEntityValue = 1; #endif /* XML_DTD */ /* never return Null for the value argument in EntityDeclHandler, since this would indicate an external entity; therefore we have to make sure that entityValuePool.start is not null */ if (! pool->blocks) { if (! poolGrow(pool)) return XML_ERROR_NO_MEMORY; } for (;;) { const char *next; int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next); switch (tok) { case XML_TOK_PARAM_ENTITY_REF: #ifdef XML_DTD if (parser->m_isParamEntity || enc != parser->m_encoding) { const XML_Char *name; ENTITY *entity; name = poolStoreString(&parser->m_tempPool, enc, entityTextPtr + enc->minBytesPerChar, next - enc->minBytesPerChar); if (! name) { result = XML_ERROR_NO_MEMORY; goto endEntityValue; } entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0); poolDiscard(&parser->m_tempPool); if (! entity) { /* not a well-formedness error - see XML 1.0: WFC Entity Declared */ /* cannot report skipped entity here - see comments on parser->m_skippedEntityHandler if (parser->m_skippedEntityHandler) parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); */ dtd->keepProcessing = dtd->standalone; goto endEntityValue; } if (entity->open) { if (enc == parser->m_encoding) parser->m_eventPtr = entityTextPtr; result = XML_ERROR_RECURSIVE_ENTITY_REF; goto endEntityValue; } if (entity->systemId) { if (parser->m_externalEntityRefHandler) { dtd->paramEntityRead = XML_FALSE; entity->open = XML_TRUE; if (! parser->m_externalEntityRefHandler( parser->m_externalEntityRefHandlerArg, 0, entity->base, entity->systemId, entity->publicId)) { entity->open = XML_FALSE; result = XML_ERROR_EXTERNAL_ENTITY_HANDLING; goto endEntityValue; } entity->open = XML_FALSE; if (! dtd->paramEntityRead) dtd->keepProcessing = dtd->standalone; } else dtd->keepProcessing = dtd->standalone; } else { entity->open = XML_TRUE; result = storeEntityValue( parser, parser->m_internalEncoding, (char *)entity->textPtr, (char *)(entity->textPtr + entity->textLen)); entity->open = XML_FALSE; if (result) goto endEntityValue; } break; } #endif /* XML_DTD */ /* In the internal subset, PE references are not legal within markup declarations, e.g entity values in this case. */ parser->m_eventPtr = entityTextPtr; result = XML_ERROR_PARAM_ENTITY_REF; goto endEntityValue; case XML_TOK_NONE: result = XML_ERROR_NONE; goto endEntityValue; case XML_TOK_ENTITY_REF: case XML_TOK_DATA_CHARS: if (! poolAppend(pool, enc, entityTextPtr, next)) { result = XML_ERROR_NO_MEMORY; goto endEntityValue; } break; case XML_TOK_TRAILING_CR: next = entityTextPtr + enc->minBytesPerChar; /* fall through */ case XML_TOK_DATA_NEWLINE: if (pool->end == pool->ptr && ! poolGrow(pool)) { result = XML_ERROR_NO_MEMORY; goto endEntityValue; } *(pool->ptr)++ = 0xA; break; case XML_TOK_CHAR_REF: { XML_Char buf[XML_ENCODE_MAX]; int i; int n = XmlCharRefNumber(enc, entityTextPtr); if (n < 0) { if (enc == parser->m_encoding) parser->m_eventPtr = entityTextPtr; result = XML_ERROR_BAD_CHAR_REF; goto endEntityValue; } n = XmlEncode(n, (ICHAR *)buf); /* The XmlEncode() functions can never return 0 here. That * error return happens if the code point passed in is either * negative or greater than or equal to 0x110000. The * XmlCharRefNumber() functions will all return a number * strictly less than 0x110000 or a negative value if an error * occurred. The negative value is intercepted above, so * XmlEncode() is never passed a value it might return an * error for. */ for (i = 0; i < n; i++) { if (pool->end == pool->ptr && ! poolGrow(pool)) { result = XML_ERROR_NO_MEMORY; goto endEntityValue; } *(pool->ptr)++ = buf[i]; } } break; case XML_TOK_PARTIAL: if (enc == parser->m_encoding) parser->m_eventPtr = entityTextPtr; result = XML_ERROR_INVALID_TOKEN; goto endEntityValue; case XML_TOK_INVALID: if (enc == parser->m_encoding) parser->m_eventPtr = next; result = XML_ERROR_INVALID_TOKEN; goto endEntityValue; default: /* This default case should be unnecessary -- all the tokens * that XmlEntityValueTok() can return have their own explicit * cases -- but should be retained for safety. We do however * exclude it from the coverage statistics. * * LCOV_EXCL_START */ if (enc == parser->m_encoding) parser->m_eventPtr = entityTextPtr; result = XML_ERROR_UNEXPECTED_STATE; goto endEntityValue; /* LCOV_EXCL_STOP */ } entityTextPtr = next; } endEntityValue: #ifdef XML_DTD parser->m_prologState.inEntityValue = oldInEntityValue; #endif /* XML_DTD */ return result; } static void FASTCALL normalizeLines(XML_Char *s) { XML_Char *p; for (;; s++) { if (*s == XML_T('\0')) return; if (*s == 0xD) break; } p = s; do { if (*s == 0xD) { *p++ = 0xA; if (*++s == 0xA) s++; } else *p++ = *s++; } while (*s); *p = XML_T('\0'); } static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end) { const XML_Char *target; XML_Char *data; const char *tem; if (! parser->m_processingInstructionHandler) { if (parser->m_defaultHandler) reportDefault(parser, enc, start, end); return 1; } start += enc->minBytesPerChar * 2; tem = start + XmlNameLength(enc, start); target = poolStoreString(&parser->m_tempPool, enc, start, tem); if (! target) return 0; poolFinish(&parser->m_tempPool); data = poolStoreString(&parser->m_tempPool, enc, XmlSkipS(enc, tem), end - enc->minBytesPerChar * 2); if (! data) return 0; normalizeLines(data); parser->m_processingInstructionHandler(parser->m_handlerArg, target, data); poolClear(&parser->m_tempPool); return 1; } static int reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end) { XML_Char *data; if (! parser->m_commentHandler) { if (parser->m_defaultHandler) reportDefault(parser, enc, start, end); return 1; } data = poolStoreString(&parser->m_tempPool, enc, start + enc->minBytesPerChar * 4, end - enc->minBytesPerChar * 3); if (! data) return 0; normalizeLines(data); parser->m_commentHandler(parser->m_handlerArg, data); poolClear(&parser->m_tempPool); return 1; } static void reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, const char *end) { if (MUST_CONVERT(enc, s)) { enum XML_Convert_Result convert_res; const char **eventPP; const char **eventEndPP; if (enc == parser->m_encoding) { eventPP = &parser->m_eventPtr; eventEndPP = &parser->m_eventEndPtr; } else { /* To get here, two things must be true; the parser must be * using a character encoding that is not the same as the * encoding passed in, and the encoding passed in must need * conversion to the internal format (UTF-8 unless XML_UNICODE * is defined). The only occasions on which the encoding passed * in is not the same as the parser's encoding are when it is * the internal encoding (e.g. a previously defined parameter * entity, already converted to internal format). This by * definition doesn't need conversion, so the whole branch never * gets executed. * * For safety's sake we don't delete these lines and merely * exclude them from coverage statistics. * * LCOV_EXCL_START */ eventPP = &(parser->m_openInternalEntities->internalEventPtr); eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); /* LCOV_EXCL_STOP */ } do { ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd); *eventEndPP = s; parser->m_defaultHandler(parser->m_handlerArg, parser->m_dataBuf, (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); *eventPP = s; } while ((convert_res != XML_CONVERT_COMPLETED) && (convert_res != XML_CONVERT_INPUT_INCOMPLETE)); } else parser->m_defaultHandler(parser->m_handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s)); } static int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata, XML_Bool isId, const XML_Char *value, XML_Parser parser) { DEFAULT_ATTRIBUTE *att; if (value || isId) { /* The handling of default attributes gets messed up if we have a default which duplicates a non-default. */ int i; for (i = 0; i < type->nDefaultAtts; i++) if (attId == type->defaultAtts[i].id) return 1; if (isId && ! type->idAtt && ! attId->xmlns) type->idAtt = attId; } if (type->nDefaultAtts == type->allocDefaultAtts) { if (type->allocDefaultAtts == 0) { type->allocDefaultAtts = 8; type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC( parser, type->allocDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); if (! type->defaultAtts) { type->allocDefaultAtts = 0; return 0; } } else { DEFAULT_ATTRIBUTE *temp; int count = type->allocDefaultAtts * 2; temp = (DEFAULT_ATTRIBUTE *)REALLOC(parser, type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE))); if (temp == NULL) return 0; type->allocDefaultAtts = count; type->defaultAtts = temp; } } att = type->defaultAtts + type->nDefaultAtts; att->id = attId; att->value = value; att->isCdata = isCdata; if (! isCdata) attId->maybeTokenized = XML_TRUE; type->nDefaultAtts += 1; return 1; } static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) { DTD *const dtd = parser->m_dtd; /* save one level of indirection */ const XML_Char *name; for (name = elementType->name; *name; name++) { if (*name == XML_T(ASCII_COLON)) { PREFIX *prefix; const XML_Char *s; for (s = elementType->name; s != name; s++) { if (! poolAppendChar(&dtd->pool, *s)) return 0; } if (! poolAppendChar(&dtd->pool, XML_T('\0'))) return 0; prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool), sizeof(PREFIX)); if (! prefix) return 0; if (prefix->name == poolStart(&dtd->pool)) poolFinish(&dtd->pool); else poolDiscard(&dtd->pool); elementType->prefix = prefix; break; } } return 1; } static ATTRIBUTE_ID * getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end) { DTD *const dtd = parser->m_dtd; /* save one level of indirection */ ATTRIBUTE_ID *id; const XML_Char *name; if (! poolAppendChar(&dtd->pool, XML_T('\0'))) return NULL; name = poolStoreString(&dtd->pool, enc, start, end); if (! name) return NULL; /* skip quotation mark - its storage will be re-used (like in name[-1]) */ ++name; id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, sizeof(ATTRIBUTE_ID)); if (! id) return NULL; if (id->name != name) poolDiscard(&dtd->pool); else { poolFinish(&dtd->pool); if (! parser->m_ns) ; else if (name[0] == XML_T(ASCII_x) && name[1] == XML_T(ASCII_m) && name[2] == XML_T(ASCII_l) && name[3] == XML_T(ASCII_n) && name[4] == XML_T(ASCII_s) && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) { if (name[5] == XML_T('\0')) id->prefix = &dtd->defaultPrefix; else id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, sizeof(PREFIX)); id->xmlns = XML_TRUE; } else { int i; for (i = 0; name[i]; i++) { /* attributes without prefix are *not* in the default namespace */ if (name[i] == XML_T(ASCII_COLON)) { int j; for (j = 0; j < i; j++) { if (! poolAppendChar(&dtd->pool, name[j])) return NULL; } if (! poolAppendChar(&dtd->pool, XML_T('\0'))) return NULL; id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool), sizeof(PREFIX)); if (! id->prefix) return NULL; if (id->prefix->name == poolStart(&dtd->pool)) poolFinish(&dtd->pool); else poolDiscard(&dtd->pool); break; } } } } return id; } #define CONTEXT_SEP XML_T(ASCII_FF) static const XML_Char * getContext(XML_Parser parser) { DTD *const dtd = parser->m_dtd; /* save one level of indirection */ HASH_TABLE_ITER iter; XML_Bool needSep = XML_FALSE; if (dtd->defaultPrefix.binding) { int i; int len; if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS))) return NULL; len = dtd->defaultPrefix.binding->uriLen; if (parser->m_namespaceSeparator) len--; for (i = 0; i < len; i++) { if (! poolAppendChar(&parser->m_tempPool, dtd->defaultPrefix.binding->uri[i])) { /* Because of memory caching, I don't believe this line can be * executed. * * This is part of a loop copying the default prefix binding * URI into the parser's temporary string pool. Previously, * that URI was copied into the same string pool, with a * terminating NUL character, as part of setContext(). When * the pool was cleared, that leaves a block definitely big * enough to hold the URI on the free block list of the pool. * The URI copy in getContext() therefore cannot run out of * memory. * * If the pool is used between the setContext() and * getContext() calls, the worst it can do is leave a bigger * block on the front of the free list. Given that this is * all somewhat inobvious and program logic can be changed, we * don't delete the line but we do exclude it from the test * coverage statistics. */ return NULL; /* LCOV_EXCL_LINE */ } } needSep = XML_TRUE; } hashTableIterInit(&iter, &(dtd->prefixes)); for (;;) { int i; int len; const XML_Char *s; PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter); if (! prefix) break; if (! prefix->binding) { /* This test appears to be (justifiable) paranoia. There does * not seem to be a way of injecting a prefix without a binding * that doesn't get errored long before this function is called. * The test should remain for safety's sake, so we instead * exclude the following line from the coverage statistics. */ continue; /* LCOV_EXCL_LINE */ } if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP)) return NULL; for (s = prefix->name; *s; s++) if (! poolAppendChar(&parser->m_tempPool, *s)) return NULL; if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS))) return NULL; len = prefix->binding->uriLen; if (parser->m_namespaceSeparator) len--; for (i = 0; i < len; i++) if (! poolAppendChar(&parser->m_tempPool, prefix->binding->uri[i])) return NULL; needSep = XML_TRUE; } hashTableIterInit(&iter, &(dtd->generalEntities)); for (;;) { const XML_Char *s; ENTITY *e = (ENTITY *)hashTableIterNext(&iter); if (! e) break; if (! e->open) continue; if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP)) return NULL; for (s = e->name; *s; s++) if (! poolAppendChar(&parser->m_tempPool, *s)) return 0; needSep = XML_TRUE; } if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) return NULL; return parser->m_tempPool.start; } static XML_Bool setContext(XML_Parser parser, const XML_Char *context) { DTD *const dtd = parser->m_dtd; /* save one level of indirection */ const XML_Char *s = context; while (*context != XML_T('\0')) { if (*s == CONTEXT_SEP || *s == XML_T('\0')) { ENTITY *e; if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) return XML_FALSE; e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&parser->m_tempPool), 0); if (e) e->open = XML_TRUE; if (*s != XML_T('\0')) s++; context = s; poolDiscard(&parser->m_tempPool); } else if (*s == XML_T(ASCII_EQUALS)) { PREFIX *prefix; if (poolLength(&parser->m_tempPool) == 0) prefix = &dtd->defaultPrefix; else { if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) return XML_FALSE; prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&parser->m_tempPool), sizeof(PREFIX)); if (! prefix) return XML_FALSE; if (prefix->name == poolStart(&parser->m_tempPool)) { prefix->name = poolCopyString(&dtd->pool, prefix->name); if (! prefix->name) return XML_FALSE; } poolDiscard(&parser->m_tempPool); } for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); context++) if (! poolAppendChar(&parser->m_tempPool, *context)) return XML_FALSE; if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) return XML_FALSE; if (addBinding(parser, prefix, NULL, poolStart(&parser->m_tempPool), &parser->m_inheritedBindings) != XML_ERROR_NONE) return XML_FALSE; poolDiscard(&parser->m_tempPool); if (*context != XML_T('\0')) ++context; s = context; } else { if (! poolAppendChar(&parser->m_tempPool, *s)) return XML_FALSE; s++; } } return XML_TRUE; } static void FASTCALL normalizePublicId(XML_Char *publicId) { XML_Char *p = publicId; XML_Char *s; for (s = publicId; *s; s++) { switch (*s) { case 0x20: case 0xD: case 0xA: if (p != publicId && p[-1] != 0x20) *p++ = 0x20; break; default: *p++ = *s; } } if (p != publicId && p[-1] == 0x20) --p; *p = XML_T('\0'); } static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms) { DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD)); if (p == NULL) return p; poolInit(&(p->pool), ms); poolInit(&(p->entityValuePool), ms); hashTableInit(&(p->generalEntities), ms); hashTableInit(&(p->elementTypes), ms); hashTableInit(&(p->attributeIds), ms); hashTableInit(&(p->prefixes), ms); #ifdef XML_DTD p->paramEntityRead = XML_FALSE; hashTableInit(&(p->paramEntities), ms); #endif /* XML_DTD */ p->defaultPrefix.name = NULL; p->defaultPrefix.binding = NULL; p->in_eldecl = XML_FALSE; p->scaffIndex = NULL; p->scaffold = NULL; p->scaffLevel = 0; p->scaffSize = 0; p->scaffCount = 0; p->contentStringLen = 0; p->keepProcessing = XML_TRUE; p->hasParamEntityRefs = XML_FALSE; p->standalone = XML_FALSE; return p; } static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) { HASH_TABLE_ITER iter; hashTableIterInit(&iter, &(p->elementTypes)); for (;;) { ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); if (! e) break; if (e->allocDefaultAtts != 0) ms->free_fcn(e->defaultAtts); } hashTableClear(&(p->generalEntities)); #ifdef XML_DTD p->paramEntityRead = XML_FALSE; hashTableClear(&(p->paramEntities)); #endif /* XML_DTD */ hashTableClear(&(p->elementTypes)); hashTableClear(&(p->attributeIds)); hashTableClear(&(p->prefixes)); poolClear(&(p->pool)); poolClear(&(p->entityValuePool)); p->defaultPrefix.name = NULL; p->defaultPrefix.binding = NULL; p->in_eldecl = XML_FALSE; ms->free_fcn(p->scaffIndex); p->scaffIndex = NULL; ms->free_fcn(p->scaffold); p->scaffold = NULL; p->scaffLevel = 0; p->scaffSize = 0; p->scaffCount = 0; p->contentStringLen = 0; p->keepProcessing = XML_TRUE; p->hasParamEntityRefs = XML_FALSE; p->standalone = XML_FALSE; } static void dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) { HASH_TABLE_ITER iter; hashTableIterInit(&iter, &(p->elementTypes)); for (;;) { ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); if (! e) break; if (e->allocDefaultAtts != 0) ms->free_fcn(e->defaultAtts); } hashTableDestroy(&(p->generalEntities)); #ifdef XML_DTD hashTableDestroy(&(p->paramEntities)); #endif /* XML_DTD */ hashTableDestroy(&(p->elementTypes)); hashTableDestroy(&(p->attributeIds)); hashTableDestroy(&(p->prefixes)); poolDestroy(&(p->pool)); poolDestroy(&(p->entityValuePool)); if (isDocEntity) { ms->free_fcn(p->scaffIndex); ms->free_fcn(p->scaffold); } ms->free_fcn(p); } /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise. The new DTD has already been initialized. */ static int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms) { HASH_TABLE_ITER iter; /* Copy the prefix table. */ hashTableIterInit(&iter, &(oldDtd->prefixes)); for (;;) { const XML_Char *name; const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter); if (! oldP) break; name = poolCopyString(&(newDtd->pool), oldP->name); if (! name) return 0; if (! lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX))) return 0; } hashTableIterInit(&iter, &(oldDtd->attributeIds)); /* Copy the attribute id table. */ for (;;) { ATTRIBUTE_ID *newA; const XML_Char *name; const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter); if (! oldA) break; /* Remember to allocate the scratch byte before the name. */ if (! poolAppendChar(&(newDtd->pool), XML_T('\0'))) return 0; name = poolCopyString(&(newDtd->pool), oldA->name); if (! name) return 0; ++name; newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID)); if (! newA) return 0; newA->maybeTokenized = oldA->maybeTokenized; if (oldA->prefix) { newA->xmlns = oldA->xmlns; if (oldA->prefix == &oldDtd->defaultPrefix) newA->prefix = &newDtd->defaultPrefix; else newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes), oldA->prefix->name, 0); } } /* Copy the element type table. */ hashTableIterInit(&iter, &(oldDtd->elementTypes)); for (;;) { int i; ELEMENT_TYPE *newE; const XML_Char *name; const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter); if (! oldE) break; name = poolCopyString(&(newDtd->pool), oldE->name); if (! name) return 0; newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE)); if (! newE) return 0; if (oldE->nDefaultAtts) { newE->defaultAtts = (DEFAULT_ATTRIBUTE *)ms->malloc_fcn( oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); if (! newE->defaultAtts) { return 0; } } if (oldE->idAtt) newE->idAtt = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0); newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts; if (oldE->prefix) newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes), oldE->prefix->name, 0); for (i = 0; i < newE->nDefaultAtts; i++) { newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup( oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0); newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata; if (oldE->defaultAtts[i].value) { newE->defaultAtts[i].value = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value); if (! newE->defaultAtts[i].value) return 0; } else newE->defaultAtts[i].value = NULL; } } /* Copy the entity tables. */ if (! copyEntityTable(oldParser, &(newDtd->generalEntities), &(newDtd->pool), &(oldDtd->generalEntities))) return 0; #ifdef XML_DTD if (! copyEntityTable(oldParser, &(newDtd->paramEntities), &(newDtd->pool), &(oldDtd->paramEntities))) return 0; newDtd->paramEntityRead = oldDtd->paramEntityRead; #endif /* XML_DTD */ newDtd->keepProcessing = oldDtd->keepProcessing; newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs; newDtd->standalone = oldDtd->standalone; /* Don't want deep copying for scaffolding */ newDtd->in_eldecl = oldDtd->in_eldecl; newDtd->scaffold = oldDtd->scaffold; newDtd->contentStringLen = oldDtd->contentStringLen; newDtd->scaffSize = oldDtd->scaffSize; newDtd->scaffLevel = oldDtd->scaffLevel; newDtd->scaffIndex = oldDtd->scaffIndex; return 1; } /* End dtdCopy */ static int copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable, STRING_POOL *newPool, const HASH_TABLE *oldTable) { HASH_TABLE_ITER iter; const XML_Char *cachedOldBase = NULL; const XML_Char *cachedNewBase = NULL; hashTableIterInit(&iter, oldTable); for (;;) { ENTITY *newE; const XML_Char *name; const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter); if (! oldE) break; name = poolCopyString(newPool, oldE->name); if (! name) return 0; newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY)); if (! newE) return 0; if (oldE->systemId) { const XML_Char *tem = poolCopyString(newPool, oldE->systemId); if (! tem) return 0; newE->systemId = tem; if (oldE->base) { if (oldE->base == cachedOldBase) newE->base = cachedNewBase; else { cachedOldBase = oldE->base; tem = poolCopyString(newPool, cachedOldBase); if (! tem) return 0; cachedNewBase = newE->base = tem; } } if (oldE->publicId) { tem = poolCopyString(newPool, oldE->publicId); if (! tem) return 0; newE->publicId = tem; } } else { const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen); if (! tem) return 0; newE->textPtr = tem; newE->textLen = oldE->textLen; } if (oldE->notation) { const XML_Char *tem = poolCopyString(newPool, oldE->notation); if (! tem) return 0; newE->notation = tem; } newE->is_param = oldE->is_param; newE->is_internal = oldE->is_internal; } return 1; } #define INIT_POWER 6 static XML_Bool FASTCALL keyeq(KEY s1, KEY s2) { for (; *s1 == *s2; s1++, s2++) if (*s1 == 0) return XML_TRUE; return XML_FALSE; } static size_t keylen(KEY s) { size_t len = 0; for (; *s; s++, len++) ; return len; } static void copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key) { key->k[0] = 0; key->k[1] = get_hash_secret_salt(parser); } static unsigned long FASTCALL hash(XML_Parser parser, KEY s) { struct siphash state; struct sipkey key; (void)sip24_valid; copy_salt_to_sipkey(parser, &key); sip24_init(&state, &key); sip24_update(&state, s, keylen(s) * sizeof(XML_Char)); return (unsigned long)sip24_final(&state); } static NAMED * lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) { size_t i; if (table->size == 0) { size_t tsize; if (! createSize) return NULL; table->power = INIT_POWER; /* table->size is a power of 2 */ table->size = (size_t)1 << INIT_POWER; tsize = table->size * sizeof(NAMED *); table->v = (NAMED **)table->mem->malloc_fcn(tsize); if (! table->v) { table->size = 0; return NULL; } memset(table->v, 0, tsize); i = hash(parser, name) & ((unsigned long)table->size - 1); } else { unsigned long h = hash(parser, name); unsigned long mask = (unsigned long)table->size - 1; unsigned char step = 0; i = h & mask; while (table->v[i]) { if (keyeq(name, table->v[i]->name)) return table->v[i]; if (! step) step = PROBE_STEP(h, mask, table->power); i < step ? (i += table->size - step) : (i -= step); } if (! createSize) return NULL; /* check for overflow (table is half full) */ if (table->used >> (table->power - 1)) { unsigned char newPower = table->power + 1; size_t newSize = (size_t)1 << newPower; unsigned long newMask = (unsigned long)newSize - 1; size_t tsize = newSize * sizeof(NAMED *); NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize); if (! newV) return NULL; memset(newV, 0, tsize); for (i = 0; i < table->size; i++) if (table->v[i]) { unsigned long newHash = hash(parser, table->v[i]->name); size_t j = newHash & newMask; step = 0; while (newV[j]) { if (! step) step = PROBE_STEP(newHash, newMask, newPower); j < step ? (j += newSize - step) : (j -= step); } newV[j] = table->v[i]; } table->mem->free_fcn(table->v); table->v = newV; table->power = newPower; table->size = newSize; i = h & newMask; step = 0; while (table->v[i]) { if (! step) step = PROBE_STEP(h, newMask, newPower); i < step ? (i += newSize - step) : (i -= step); } } } table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize); if (! table->v[i]) return NULL; memset(table->v[i], 0, createSize); table->v[i]->name = name; (table->used)++; return table->v[i]; } static void FASTCALL hashTableClear(HASH_TABLE *table) { size_t i; for (i = 0; i < table->size; i++) { table->mem->free_fcn(table->v[i]); table->v[i] = NULL; } table->used = 0; } static void FASTCALL hashTableDestroy(HASH_TABLE *table) { size_t i; for (i = 0; i < table->size; i++) table->mem->free_fcn(table->v[i]); table->mem->free_fcn(table->v); } static void FASTCALL hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms) { p->power = 0; p->size = 0; p->used = 0; p->v = NULL; p->mem = ms; } static void FASTCALL hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) { iter->p = table->v; iter->end = iter->p + table->size; } static NAMED *FASTCALL hashTableIterNext(HASH_TABLE_ITER *iter) { while (iter->p != iter->end) { NAMED *tem = *(iter->p)++; if (tem) return tem; } return NULL; } static void FASTCALL poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms) { pool->blocks = NULL; pool->freeBlocks = NULL; pool->start = NULL; pool->ptr = NULL; pool->end = NULL; pool->mem = ms; } static void FASTCALL poolClear(STRING_POOL *pool) { if (! pool->freeBlocks) pool->freeBlocks = pool->blocks; else { BLOCK *p = pool->blocks; while (p) { BLOCK *tem = p->next; p->next = pool->freeBlocks; pool->freeBlocks = p; p = tem; } } pool->blocks = NULL; pool->start = NULL; pool->ptr = NULL; pool->end = NULL; } static void FASTCALL poolDestroy(STRING_POOL *pool) { BLOCK *p = pool->blocks; while (p) { BLOCK *tem = p->next; pool->mem->free_fcn(p); p = tem; } p = pool->freeBlocks; while (p) { BLOCK *tem = p->next; pool->mem->free_fcn(p); p = tem; } } static XML_Char * poolAppend(STRING_POOL *pool, const ENCODING *enc, const char *ptr, const char *end) { if (! pool->ptr && ! poolGrow(pool)) return NULL; for (;;) { const enum XML_Convert_Result convert_res = XmlConvert( enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end); if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) break; if (! poolGrow(pool)) return NULL; } return pool->start; } static const XML_Char *FASTCALL poolCopyString(STRING_POOL *pool, const XML_Char *s) { do { if (! poolAppendChar(pool, *s)) return NULL; } while (*s++); s = pool->start; poolFinish(pool); return s; } static const XML_Char * poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) { if (! pool->ptr && ! poolGrow(pool)) { /* The following line is unreachable given the current usage of * poolCopyStringN(). Currently it is called from exactly one * place to copy the text of a simple general entity. By that * point, the name of the entity is already stored in the pool, so * pool->ptr cannot be NULL. * * If poolCopyStringN() is used elsewhere as it well might be, * this line may well become executable again. Regardless, this * sort of check shouldn't be removed lightly, so we just exclude * it from the coverage statistics. */ return NULL; /* LCOV_EXCL_LINE */ } for (; n > 0; --n, s++) { if (! poolAppendChar(pool, *s)) return NULL; } s = pool->start; poolFinish(pool); return s; } static const XML_Char *FASTCALL poolAppendString(STRING_POOL *pool, const XML_Char *s) { while (*s) { if (! poolAppendChar(pool, *s)) return NULL; s++; } return pool->start; } static XML_Char * poolStoreString(STRING_POOL *pool, const ENCODING *enc, const char *ptr, const char *end) { if (! poolAppend(pool, enc, ptr, end)) return NULL; if (pool->ptr == pool->end && ! poolGrow(pool)) return NULL; *(pool->ptr)++ = 0; return pool->start; } static size_t poolBytesToAllocateFor(int blockSize) { /* Unprotected math would be: ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char); ** ** Detect overflow, avoiding _signed_ overflow undefined behavior ** For a + b * c we check b * c in isolation first, so that addition of a ** on top has no chance of making us accept a small non-negative number */ const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */ if (blockSize <= 0) return 0; if (blockSize > (int)(INT_MAX / stretch)) return 0; { const int stretchedBlockSize = blockSize * (int)stretch; const int bytesToAllocate = (int)(offsetof(BLOCK, s) + (unsigned)stretchedBlockSize); if (bytesToAllocate < 0) return 0; return (size_t)bytesToAllocate; } } static XML_Bool FASTCALL poolGrow(STRING_POOL *pool) { if (pool->freeBlocks) { if (pool->start == 0) { pool->blocks = pool->freeBlocks; pool->freeBlocks = pool->freeBlocks->next; pool->blocks->next = NULL; pool->start = pool->blocks->s; pool->end = pool->start + pool->blocks->size; pool->ptr = pool->start; return XML_TRUE; } if (pool->end - pool->start < pool->freeBlocks->size) { BLOCK *tem = pool->freeBlocks->next; pool->freeBlocks->next = pool->blocks; pool->blocks = pool->freeBlocks; pool->freeBlocks = tem; memcpy(pool->blocks->s, pool->start, (pool->end - pool->start) * sizeof(XML_Char)); pool->ptr = pool->blocks->s + (pool->ptr - pool->start); pool->start = pool->blocks->s; pool->end = pool->start + pool->blocks->size; return XML_TRUE; } } if (pool->blocks && pool->start == pool->blocks->s) { BLOCK *temp; int blockSize = (int)((unsigned)(pool->end - pool->start) * 2U); size_t bytesToAllocate; /* NOTE: Needs to be calculated prior to calling `realloc` to avoid dangling pointers: */ const ptrdiff_t offsetInsideBlock = pool->ptr - pool->start; if (blockSize < 0) { /* This condition traps a situation where either more than * INT_MAX/2 bytes have already been allocated. This isn't * readily testable, since it is unlikely that an average * machine will have that much memory, so we exclude it from the * coverage statistics. */ return XML_FALSE; /* LCOV_EXCL_LINE */ } bytesToAllocate = poolBytesToAllocateFor(blockSize); if (bytesToAllocate == 0) return XML_FALSE; temp = (BLOCK *)pool->mem->realloc_fcn(pool->blocks, (unsigned)bytesToAllocate); if (temp == NULL) return XML_FALSE; pool->blocks = temp; pool->blocks->size = blockSize; pool->ptr = pool->blocks->s + offsetInsideBlock; pool->start = pool->blocks->s; pool->end = pool->start + blockSize; } else { BLOCK *tem; int blockSize = (int)(pool->end - pool->start); size_t bytesToAllocate; if (blockSize < 0) { /* This condition traps a situation where either more than * INT_MAX bytes have already been allocated (which is prevented * by various pieces of program logic, not least this one, never * mind the unlikelihood of actually having that much memory) or * the pool control fields have been corrupted (which could * conceivably happen in an extremely buggy user handler * function). Either way it isn't readily testable, so we * exclude it from the coverage statistics. */ return XML_FALSE; /* LCOV_EXCL_LINE */ } if (blockSize < INIT_BLOCK_SIZE) blockSize = INIT_BLOCK_SIZE; else { /* Detect overflow, avoiding _signed_ overflow undefined behavior */ if ((int)((unsigned)blockSize * 2U) < 0) { return XML_FALSE; } blockSize *= 2; } bytesToAllocate = poolBytesToAllocateFor(blockSize); if (bytesToAllocate == 0) return XML_FALSE; tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate); if (! tem) return XML_FALSE; tem->size = blockSize; tem->next = pool->blocks; pool->blocks = tem; if (pool->ptr != pool->start) memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char)); pool->ptr = tem->s + (pool->ptr - pool->start); pool->start = tem->s; pool->end = tem->s + blockSize; } return XML_TRUE; } static int FASTCALL nextScaffoldPart(XML_Parser parser) { DTD *const dtd = parser->m_dtd; /* save one level of indirection */ CONTENT_SCAFFOLD *me; int next; if (! dtd->scaffIndex) { dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int)); if (! dtd->scaffIndex) return -1; dtd->scaffIndex[0] = 0; } if (dtd->scaffCount >= dtd->scaffSize) { CONTENT_SCAFFOLD *temp; if (dtd->scaffold) { temp = (CONTENT_SCAFFOLD *)REALLOC( parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD)); if (temp == NULL) return -1; dtd->scaffSize *= 2; } else { temp = (CONTENT_SCAFFOLD *)MALLOC(parser, INIT_SCAFFOLD_ELEMENTS * sizeof(CONTENT_SCAFFOLD)); if (temp == NULL) return -1; dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS; } dtd->scaffold = temp; } next = dtd->scaffCount++; me = &dtd->scaffold[next]; if (dtd->scaffLevel) { CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]]; if (parent->lastchild) { dtd->scaffold[parent->lastchild].nextsib = next; } if (! parent->childcnt) parent->firstchild = next; parent->lastchild = next; parent->childcnt++; } me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0; return next; } static void build_node(XML_Parser parser, int src_node, XML_Content *dest, XML_Content **contpos, XML_Char **strpos) { DTD *const dtd = parser->m_dtd; /* save one level of indirection */ dest->type = dtd->scaffold[src_node].type; dest->quant = dtd->scaffold[src_node].quant; if (dest->type == XML_CTYPE_NAME) { const XML_Char *src; dest->name = *strpos; src = dtd->scaffold[src_node].name; for (;;) { *(*strpos)++ = *src; if (! *src) break; src++; } dest->numchildren = 0; dest->children = NULL; } else { unsigned int i; int cn; dest->numchildren = dtd->scaffold[src_node].childcnt; dest->children = *contpos; *contpos += dest->numchildren; for (i = 0, cn = dtd->scaffold[src_node].firstchild; i < dest->numchildren; i++, cn = dtd->scaffold[cn].nextsib) { build_node(parser, cn, &(dest->children[i]), contpos, strpos); } dest->name = NULL; } } static XML_Content * build_model(XML_Parser parser) { DTD *const dtd = parser->m_dtd; /* save one level of indirection */ XML_Content *ret; XML_Content *cpos; XML_Char *str; int allocsize = (dtd->scaffCount * sizeof(XML_Content) + (dtd->contentStringLen * sizeof(XML_Char))); ret = (XML_Content *)MALLOC(parser, allocsize); if (! ret) return NULL; str = (XML_Char *)(&ret[dtd->scaffCount]); cpos = &ret[1]; build_node(parser, 0, ret, &cpos, &str); return ret; } static ELEMENT_TYPE * getElementType(XML_Parser parser, const ENCODING *enc, const char *ptr, const char *end) { DTD *const dtd = parser->m_dtd; /* save one level of indirection */ const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end); ELEMENT_TYPE *ret; if (! name) return NULL; ret = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE)); if (! ret) return NULL; if (ret->name != name) poolDiscard(&dtd->pool); else { poolFinish(&dtd->pool); if (! setElementTypePrefix(parser, ret)) return NULL; } return ret; } static XML_Char * copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) { int charsRequired = 0; XML_Char *result; /* First determine how long the string is */ while (s[charsRequired] != 0) { charsRequired++; } /* Include the terminator */ charsRequired++; /* Now allocate space for the copy */ result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char)); if (result == NULL) return NULL; /* Copy the original into place */ memcpy(result, s, charsRequired * sizeof(XML_Char)); return result; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/lib/xmlrole.c0000644000175100001710000010422400000000000017435 0ustar00vstsdocker/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000-2017 Expat development team Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #ifdef _WIN32 # include "winconfig.h" #else # ifdef HAVE_EXPAT_CONFIG_H # include # endif #endif /* ndef _WIN32 */ #include "expat_external.h" #include "internal.h" #include "xmlrole.h" #include "ascii.h" /* Doesn't check: that ,| are not mixed in a model group content of literals */ static const char KW_ANY[] = {ASCII_A, ASCII_N, ASCII_Y, '\0'}; static const char KW_ATTLIST[] = {ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0'}; static const char KW_CDATA[] = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'}; static const char KW_DOCTYPE[] = {ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0'}; static const char KW_ELEMENT[] = {ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0'}; static const char KW_EMPTY[] = {ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0'}; static const char KW_ENTITIES[] = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0'}; static const char KW_ENTITY[] = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0'}; static const char KW_FIXED[] = {ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0'}; static const char KW_ID[] = {ASCII_I, ASCII_D, '\0'}; static const char KW_IDREF[] = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0'}; static const char KW_IDREFS[] = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0'}; #ifdef XML_DTD static const char KW_IGNORE[] = {ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0'}; #endif static const char KW_IMPLIED[] = {ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0'}; #ifdef XML_DTD static const char KW_INCLUDE[] = {ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0'}; #endif static const char KW_NDATA[] = {ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'}; static const char KW_NMTOKEN[] = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0'}; static const char KW_NMTOKENS[] = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0'}; static const char KW_NOTATION[] = {ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, '\0'}; static const char KW_PCDATA[] = {ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'}; static const char KW_PUBLIC[] = {ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0'}; static const char KW_REQUIRED[] = {ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, ASCII_R, ASCII_E, ASCII_D, '\0'}; static const char KW_SYSTEM[] = {ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0'}; #ifndef MIN_BYTES_PER_CHAR # define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar) #endif #ifdef XML_DTD # define setTopLevel(state) \ ((state)->handler \ = ((state)->documentEntity ? internalSubset : externalSubset1)) #else /* not XML_DTD */ # define setTopLevel(state) ((state)->handler = internalSubset) #endif /* not XML_DTD */ typedef int PTRCALL PROLOG_HANDLER(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc); static PROLOG_HANDLER prolog0, prolog1, prolog2, doctype0, doctype1, doctype2, doctype3, doctype4, doctype5, internalSubset, entity0, entity1, entity2, entity3, entity4, entity5, entity6, entity7, entity8, entity9, entity10, notation0, notation1, notation2, notation3, notation4, attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6, attlist7, attlist8, attlist9, element0, element1, element2, element3, element4, element5, element6, element7, #ifdef XML_DTD externalSubset0, externalSubset1, condSect0, condSect1, condSect2, #endif /* XML_DTD */ declClose, error; static int FASTCALL common(PROLOG_STATE *state, int tok); static int PTRCALL prolog0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: state->handler = prolog1; return XML_ROLE_NONE; case XML_TOK_XML_DECL: state->handler = prolog1; return XML_ROLE_XML_DECL; case XML_TOK_PI: state->handler = prolog1; return XML_ROLE_PI; case XML_TOK_COMMENT: state->handler = prolog1; return XML_ROLE_COMMENT; case XML_TOK_BOM: return XML_ROLE_NONE; case XML_TOK_DECL_OPEN: if (! XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, KW_DOCTYPE)) break; state->handler = doctype0; return XML_ROLE_DOCTYPE_NONE; case XML_TOK_INSTANCE_START: state->handler = error; return XML_ROLE_INSTANCE_START; } return common(state, tok); } static int PTRCALL prolog1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_PI: return XML_ROLE_PI; case XML_TOK_COMMENT: return XML_ROLE_COMMENT; case XML_TOK_BOM: /* This case can never arise. To reach this role function, the * parse must have passed through prolog0 and therefore have had * some form of input, even if only a space. At that point, a * byte order mark is no longer a valid character (though * technically it should be interpreted as a non-breaking space), * so will be rejected by the tokenizing stages. */ return XML_ROLE_NONE; /* LCOV_EXCL_LINE */ case XML_TOK_DECL_OPEN: if (! XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, KW_DOCTYPE)) break; state->handler = doctype0; return XML_ROLE_DOCTYPE_NONE; case XML_TOK_INSTANCE_START: state->handler = error; return XML_ROLE_INSTANCE_START; } return common(state, tok); } static int PTRCALL prolog2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_PI: return XML_ROLE_PI; case XML_TOK_COMMENT: return XML_ROLE_COMMENT; case XML_TOK_INSTANCE_START: state->handler = error; return XML_ROLE_INSTANCE_START; } return common(state, tok); } static int PTRCALL doctype0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_DOCTYPE_NONE; case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = doctype1; return XML_ROLE_DOCTYPE_NAME; } return common(state, tok); } static int PTRCALL doctype1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_DOCTYPE_NONE; case XML_TOK_OPEN_BRACKET: state->handler = internalSubset; return XML_ROLE_DOCTYPE_INTERNAL_SUBSET; case XML_TOK_DECL_CLOSE: state->handler = prolog2; return XML_ROLE_DOCTYPE_CLOSE; case XML_TOK_NAME: if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { state->handler = doctype3; return XML_ROLE_DOCTYPE_NONE; } if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { state->handler = doctype2; return XML_ROLE_DOCTYPE_NONE; } break; } return common(state, tok); } static int PTRCALL doctype2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_DOCTYPE_NONE; case XML_TOK_LITERAL: state->handler = doctype3; return XML_ROLE_DOCTYPE_PUBLIC_ID; } return common(state, tok); } static int PTRCALL doctype3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_DOCTYPE_NONE; case XML_TOK_LITERAL: state->handler = doctype4; return XML_ROLE_DOCTYPE_SYSTEM_ID; } return common(state, tok); } static int PTRCALL doctype4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_DOCTYPE_NONE; case XML_TOK_OPEN_BRACKET: state->handler = internalSubset; return XML_ROLE_DOCTYPE_INTERNAL_SUBSET; case XML_TOK_DECL_CLOSE: state->handler = prolog2; return XML_ROLE_DOCTYPE_CLOSE; } return common(state, tok); } static int PTRCALL doctype5(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_DOCTYPE_NONE; case XML_TOK_DECL_CLOSE: state->handler = prolog2; return XML_ROLE_DOCTYPE_CLOSE; } return common(state, tok); } static int PTRCALL internalSubset(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_DECL_OPEN: if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, KW_ENTITY)) { state->handler = entity0; return XML_ROLE_ENTITY_NONE; } if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, KW_ATTLIST)) { state->handler = attlist0; return XML_ROLE_ATTLIST_NONE; } if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, KW_ELEMENT)) { state->handler = element0; return XML_ROLE_ELEMENT_NONE; } if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, KW_NOTATION)) { state->handler = notation0; return XML_ROLE_NOTATION_NONE; } break; case XML_TOK_PI: return XML_ROLE_PI; case XML_TOK_COMMENT: return XML_ROLE_COMMENT; case XML_TOK_PARAM_ENTITY_REF: return XML_ROLE_PARAM_ENTITY_REF; case XML_TOK_CLOSE_BRACKET: state->handler = doctype5; return XML_ROLE_DOCTYPE_NONE; case XML_TOK_NONE: return XML_ROLE_NONE; } return common(state, tok); } #ifdef XML_DTD static int PTRCALL externalSubset0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { state->handler = externalSubset1; if (tok == XML_TOK_XML_DECL) return XML_ROLE_TEXT_DECL; return externalSubset1(state, tok, ptr, end, enc); } static int PTRCALL externalSubset1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_COND_SECT_OPEN: state->handler = condSect0; return XML_ROLE_NONE; case XML_TOK_COND_SECT_CLOSE: if (state->includeLevel == 0) break; state->includeLevel -= 1; return XML_ROLE_NONE; case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_CLOSE_BRACKET: break; case XML_TOK_NONE: if (state->includeLevel) break; return XML_ROLE_NONE; default: return internalSubset(state, tok, ptr, end, enc); } return common(state, tok); } #endif /* XML_DTD */ static int PTRCALL entity0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; case XML_TOK_PERCENT: state->handler = entity1; return XML_ROLE_ENTITY_NONE; case XML_TOK_NAME: state->handler = entity2; return XML_ROLE_GENERAL_ENTITY_NAME; } return common(state, tok); } static int PTRCALL entity1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; case XML_TOK_NAME: state->handler = entity7; return XML_ROLE_PARAM_ENTITY_NAME; } return common(state, tok); } static int PTRCALL entity2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; case XML_TOK_NAME: if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { state->handler = entity4; return XML_ROLE_ENTITY_NONE; } if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { state->handler = entity3; return XML_ROLE_ENTITY_NONE; } break; case XML_TOK_LITERAL: state->handler = declClose; state->role_none = XML_ROLE_ENTITY_NONE; return XML_ROLE_ENTITY_VALUE; } return common(state, tok); } static int PTRCALL entity3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; case XML_TOK_LITERAL: state->handler = entity4; return XML_ROLE_ENTITY_PUBLIC_ID; } return common(state, tok); } static int PTRCALL entity4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; case XML_TOK_LITERAL: state->handler = entity5; return XML_ROLE_ENTITY_SYSTEM_ID; } return common(state, tok); } static int PTRCALL entity5(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; case XML_TOK_DECL_CLOSE: setTopLevel(state); return XML_ROLE_ENTITY_COMPLETE; case XML_TOK_NAME: if (XmlNameMatchesAscii(enc, ptr, end, KW_NDATA)) { state->handler = entity6; return XML_ROLE_ENTITY_NONE; } break; } return common(state, tok); } static int PTRCALL entity6(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; case XML_TOK_NAME: state->handler = declClose; state->role_none = XML_ROLE_ENTITY_NONE; return XML_ROLE_ENTITY_NOTATION_NAME; } return common(state, tok); } static int PTRCALL entity7(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; case XML_TOK_NAME: if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { state->handler = entity9; return XML_ROLE_ENTITY_NONE; } if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { state->handler = entity8; return XML_ROLE_ENTITY_NONE; } break; case XML_TOK_LITERAL: state->handler = declClose; state->role_none = XML_ROLE_ENTITY_NONE; return XML_ROLE_ENTITY_VALUE; } return common(state, tok); } static int PTRCALL entity8(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; case XML_TOK_LITERAL: state->handler = entity9; return XML_ROLE_ENTITY_PUBLIC_ID; } return common(state, tok); } static int PTRCALL entity9(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; case XML_TOK_LITERAL: state->handler = entity10; return XML_ROLE_ENTITY_SYSTEM_ID; } return common(state, tok); } static int PTRCALL entity10(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; case XML_TOK_DECL_CLOSE: setTopLevel(state); return XML_ROLE_ENTITY_COMPLETE; } return common(state, tok); } static int PTRCALL notation0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NOTATION_NONE; case XML_TOK_NAME: state->handler = notation1; return XML_ROLE_NOTATION_NAME; } return common(state, tok); } static int PTRCALL notation1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NOTATION_NONE; case XML_TOK_NAME: if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { state->handler = notation3; return XML_ROLE_NOTATION_NONE; } if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { state->handler = notation2; return XML_ROLE_NOTATION_NONE; } break; } return common(state, tok); } static int PTRCALL notation2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NOTATION_NONE; case XML_TOK_LITERAL: state->handler = notation4; return XML_ROLE_NOTATION_PUBLIC_ID; } return common(state, tok); } static int PTRCALL notation3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NOTATION_NONE; case XML_TOK_LITERAL: state->handler = declClose; state->role_none = XML_ROLE_NOTATION_NONE; return XML_ROLE_NOTATION_SYSTEM_ID; } return common(state, tok); } static int PTRCALL notation4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NOTATION_NONE; case XML_TOK_LITERAL: state->handler = declClose; state->role_none = XML_ROLE_NOTATION_NONE; return XML_ROLE_NOTATION_SYSTEM_ID; case XML_TOK_DECL_CLOSE: setTopLevel(state); return XML_ROLE_NOTATION_NO_SYSTEM_ID; } return common(state, tok); } static int PTRCALL attlist0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = attlist1; return XML_ROLE_ATTLIST_ELEMENT_NAME; } return common(state, tok); } static int PTRCALL attlist1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; case XML_TOK_DECL_CLOSE: setTopLevel(state); return XML_ROLE_ATTLIST_NONE; case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = attlist2; return XML_ROLE_ATTRIBUTE_NAME; } return common(state, tok); } static int PTRCALL attlist2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; case XML_TOK_NAME: { static const char *const types[] = { KW_CDATA, KW_ID, KW_IDREF, KW_IDREFS, KW_ENTITY, KW_ENTITIES, KW_NMTOKEN, KW_NMTOKENS, }; int i; for (i = 0; i < (int)(sizeof(types) / sizeof(types[0])); i++) if (XmlNameMatchesAscii(enc, ptr, end, types[i])) { state->handler = attlist8; return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i; } } if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) { state->handler = attlist5; return XML_ROLE_ATTLIST_NONE; } break; case XML_TOK_OPEN_PAREN: state->handler = attlist3; return XML_ROLE_ATTLIST_NONE; } return common(state, tok); } static int PTRCALL attlist3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; case XML_TOK_NMTOKEN: case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = attlist4; return XML_ROLE_ATTRIBUTE_ENUM_VALUE; } return common(state, tok); } static int PTRCALL attlist4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; case XML_TOK_CLOSE_PAREN: state->handler = attlist8; return XML_ROLE_ATTLIST_NONE; case XML_TOK_OR: state->handler = attlist3; return XML_ROLE_ATTLIST_NONE; } return common(state, tok); } static int PTRCALL attlist5(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; case XML_TOK_OPEN_PAREN: state->handler = attlist6; return XML_ROLE_ATTLIST_NONE; } return common(state, tok); } static int PTRCALL attlist6(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; case XML_TOK_NAME: state->handler = attlist7; return XML_ROLE_ATTRIBUTE_NOTATION_VALUE; } return common(state, tok); } static int PTRCALL attlist7(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; case XML_TOK_CLOSE_PAREN: state->handler = attlist8; return XML_ROLE_ATTLIST_NONE; case XML_TOK_OR: state->handler = attlist6; return XML_ROLE_ATTLIST_NONE; } return common(state, tok); } /* default value */ static int PTRCALL attlist8(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; case XML_TOK_POUND_NAME: if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end, KW_IMPLIED)) { state->handler = attlist1; return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE; } if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end, KW_REQUIRED)) { state->handler = attlist1; return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE; } if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end, KW_FIXED)) { state->handler = attlist9; return XML_ROLE_ATTLIST_NONE; } break; case XML_TOK_LITERAL: state->handler = attlist1; return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE; } return common(state, tok); } static int PTRCALL attlist9(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; case XML_TOK_LITERAL: state->handler = attlist1; return XML_ROLE_FIXED_ATTRIBUTE_VALUE; } return common(state, tok); } static int PTRCALL element0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ELEMENT_NONE; case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = element1; return XML_ROLE_ELEMENT_NAME; } return common(state, tok); } static int PTRCALL element1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ELEMENT_NONE; case XML_TOK_NAME: if (XmlNameMatchesAscii(enc, ptr, end, KW_EMPTY)) { state->handler = declClose; state->role_none = XML_ROLE_ELEMENT_NONE; return XML_ROLE_CONTENT_EMPTY; } if (XmlNameMatchesAscii(enc, ptr, end, KW_ANY)) { state->handler = declClose; state->role_none = XML_ROLE_ELEMENT_NONE; return XML_ROLE_CONTENT_ANY; } break; case XML_TOK_OPEN_PAREN: state->handler = element2; state->level = 1; return XML_ROLE_GROUP_OPEN; } return common(state, tok); } static int PTRCALL element2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ELEMENT_NONE; case XML_TOK_POUND_NAME: if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end, KW_PCDATA)) { state->handler = element3; return XML_ROLE_CONTENT_PCDATA; } break; case XML_TOK_OPEN_PAREN: state->level = 2; state->handler = element6; return XML_ROLE_GROUP_OPEN; case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = element7; return XML_ROLE_CONTENT_ELEMENT; case XML_TOK_NAME_QUESTION: state->handler = element7; return XML_ROLE_CONTENT_ELEMENT_OPT; case XML_TOK_NAME_ASTERISK: state->handler = element7; return XML_ROLE_CONTENT_ELEMENT_REP; case XML_TOK_NAME_PLUS: state->handler = element7; return XML_ROLE_CONTENT_ELEMENT_PLUS; } return common(state, tok); } static int PTRCALL element3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ELEMENT_NONE; case XML_TOK_CLOSE_PAREN: state->handler = declClose; state->role_none = XML_ROLE_ELEMENT_NONE; return XML_ROLE_GROUP_CLOSE; case XML_TOK_CLOSE_PAREN_ASTERISK: state->handler = declClose; state->role_none = XML_ROLE_ELEMENT_NONE; return XML_ROLE_GROUP_CLOSE_REP; case XML_TOK_OR: state->handler = element4; return XML_ROLE_ELEMENT_NONE; } return common(state, tok); } static int PTRCALL element4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ELEMENT_NONE; case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = element5; return XML_ROLE_CONTENT_ELEMENT; } return common(state, tok); } static int PTRCALL element5(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ELEMENT_NONE; case XML_TOK_CLOSE_PAREN_ASTERISK: state->handler = declClose; state->role_none = XML_ROLE_ELEMENT_NONE; return XML_ROLE_GROUP_CLOSE_REP; case XML_TOK_OR: state->handler = element4; return XML_ROLE_ELEMENT_NONE; } return common(state, tok); } static int PTRCALL element6(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ELEMENT_NONE; case XML_TOK_OPEN_PAREN: state->level += 1; return XML_ROLE_GROUP_OPEN; case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = element7; return XML_ROLE_CONTENT_ELEMENT; case XML_TOK_NAME_QUESTION: state->handler = element7; return XML_ROLE_CONTENT_ELEMENT_OPT; case XML_TOK_NAME_ASTERISK: state->handler = element7; return XML_ROLE_CONTENT_ELEMENT_REP; case XML_TOK_NAME_PLUS: state->handler = element7; return XML_ROLE_CONTENT_ELEMENT_PLUS; } return common(state, tok); } static int PTRCALL element7(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ELEMENT_NONE; case XML_TOK_CLOSE_PAREN: state->level -= 1; if (state->level == 0) { state->handler = declClose; state->role_none = XML_ROLE_ELEMENT_NONE; } return XML_ROLE_GROUP_CLOSE; case XML_TOK_CLOSE_PAREN_ASTERISK: state->level -= 1; if (state->level == 0) { state->handler = declClose; state->role_none = XML_ROLE_ELEMENT_NONE; } return XML_ROLE_GROUP_CLOSE_REP; case XML_TOK_CLOSE_PAREN_QUESTION: state->level -= 1; if (state->level == 0) { state->handler = declClose; state->role_none = XML_ROLE_ELEMENT_NONE; } return XML_ROLE_GROUP_CLOSE_OPT; case XML_TOK_CLOSE_PAREN_PLUS: state->level -= 1; if (state->level == 0) { state->handler = declClose; state->role_none = XML_ROLE_ELEMENT_NONE; } return XML_ROLE_GROUP_CLOSE_PLUS; case XML_TOK_COMMA: state->handler = element6; return XML_ROLE_GROUP_SEQUENCE; case XML_TOK_OR: state->handler = element6; return XML_ROLE_GROUP_CHOICE; } return common(state, tok); } #ifdef XML_DTD static int PTRCALL condSect0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_NAME: if (XmlNameMatchesAscii(enc, ptr, end, KW_INCLUDE)) { state->handler = condSect1; return XML_ROLE_NONE; } if (XmlNameMatchesAscii(enc, ptr, end, KW_IGNORE)) { state->handler = condSect2; return XML_ROLE_NONE; } break; } return common(state, tok); } static int PTRCALL condSect1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_OPEN_BRACKET: state->handler = externalSubset1; state->includeLevel += 1; return XML_ROLE_NONE; } return common(state, tok); } static int PTRCALL condSect2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_OPEN_BRACKET: state->handler = externalSubset1; return XML_ROLE_IGNORE_SECT; } return common(state, tok); } #endif /* XML_DTD */ static int PTRCALL declClose(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return state->role_none; case XML_TOK_DECL_CLOSE: setTopLevel(state); return state->role_none; } return common(state, tok); } /* This function will only be invoked if the internal logic of the * parser has broken down. It is used in two cases: * * 1: When the XML prolog has been finished. At this point the * processor (the parser level above these role handlers) should * switch from prologProcessor to contentProcessor and reinitialise * the handler function. * * 2: When an error has been detected (via common() below). At this * point again the processor should be switched to errorProcessor, * which will never call a handler. * * The result of this is that error() can only be called if the * processor switch failed to happen, which is an internal error and * therefore we shouldn't be able to provoke it simply by using the * library. It is a necessary backstop, however, so we merely exclude * it from the coverage statistics. * * LCOV_EXCL_START */ static int PTRCALL error(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(state); UNUSED_P(tok); UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); return XML_ROLE_NONE; } /* LCOV_EXCL_STOP */ static int FASTCALL common(PROLOG_STATE *state, int tok) { #ifdef XML_DTD if (! state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF) return XML_ROLE_INNER_PARAM_ENTITY_REF; #endif state->handler = error; return XML_ROLE_ERROR; } void XmlPrologStateInit(PROLOG_STATE *state) { state->handler = prolog0; #ifdef XML_DTD state->documentEntity = 1; state->includeLevel = 0; state->inEntityValue = 0; #endif /* XML_DTD */ } #ifdef XML_DTD void XmlPrologStateInitExternalEntity(PROLOG_STATE *state) { state->handler = externalSubset0; state->documentEntity = 0; state->includeLevel = 0; } #endif /* XML_DTD */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/lib/xmlrole.h0000644000175100001710000001052700000000000017444 0ustar00vstsdocker/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000-2017 Expat development team Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef XmlRole_INCLUDED #define XmlRole_INCLUDED 1 #ifdef __VMS /* 0 1 2 3 0 1 2 3 1234567890123456789012345678901 1234567890123456789012345678901 */ # define XmlPrologStateInitExternalEntity XmlPrologStateInitExternalEnt #endif #include "xmltok.h" #ifdef __cplusplus extern "C" { #endif enum { XML_ROLE_ERROR = -1, XML_ROLE_NONE = 0, XML_ROLE_XML_DECL, XML_ROLE_INSTANCE_START, XML_ROLE_DOCTYPE_NONE, XML_ROLE_DOCTYPE_NAME, XML_ROLE_DOCTYPE_SYSTEM_ID, XML_ROLE_DOCTYPE_PUBLIC_ID, XML_ROLE_DOCTYPE_INTERNAL_SUBSET, XML_ROLE_DOCTYPE_CLOSE, XML_ROLE_GENERAL_ENTITY_NAME, XML_ROLE_PARAM_ENTITY_NAME, XML_ROLE_ENTITY_NONE, XML_ROLE_ENTITY_VALUE, XML_ROLE_ENTITY_SYSTEM_ID, XML_ROLE_ENTITY_PUBLIC_ID, XML_ROLE_ENTITY_COMPLETE, XML_ROLE_ENTITY_NOTATION_NAME, XML_ROLE_NOTATION_NONE, XML_ROLE_NOTATION_NAME, XML_ROLE_NOTATION_SYSTEM_ID, XML_ROLE_NOTATION_NO_SYSTEM_ID, XML_ROLE_NOTATION_PUBLIC_ID, XML_ROLE_ATTRIBUTE_NAME, XML_ROLE_ATTRIBUTE_TYPE_CDATA, XML_ROLE_ATTRIBUTE_TYPE_ID, XML_ROLE_ATTRIBUTE_TYPE_IDREF, XML_ROLE_ATTRIBUTE_TYPE_IDREFS, XML_ROLE_ATTRIBUTE_TYPE_ENTITY, XML_ROLE_ATTRIBUTE_TYPE_ENTITIES, XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN, XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS, XML_ROLE_ATTRIBUTE_ENUM_VALUE, XML_ROLE_ATTRIBUTE_NOTATION_VALUE, XML_ROLE_ATTLIST_NONE, XML_ROLE_ATTLIST_ELEMENT_NAME, XML_ROLE_IMPLIED_ATTRIBUTE_VALUE, XML_ROLE_REQUIRED_ATTRIBUTE_VALUE, XML_ROLE_DEFAULT_ATTRIBUTE_VALUE, XML_ROLE_FIXED_ATTRIBUTE_VALUE, XML_ROLE_ELEMENT_NONE, XML_ROLE_ELEMENT_NAME, XML_ROLE_CONTENT_ANY, XML_ROLE_CONTENT_EMPTY, XML_ROLE_CONTENT_PCDATA, XML_ROLE_GROUP_OPEN, XML_ROLE_GROUP_CLOSE, XML_ROLE_GROUP_CLOSE_REP, XML_ROLE_GROUP_CLOSE_OPT, XML_ROLE_GROUP_CLOSE_PLUS, XML_ROLE_GROUP_CHOICE, XML_ROLE_GROUP_SEQUENCE, XML_ROLE_CONTENT_ELEMENT, XML_ROLE_CONTENT_ELEMENT_REP, XML_ROLE_CONTENT_ELEMENT_OPT, XML_ROLE_CONTENT_ELEMENT_PLUS, XML_ROLE_PI, XML_ROLE_COMMENT, #ifdef XML_DTD XML_ROLE_TEXT_DECL, XML_ROLE_IGNORE_SECT, XML_ROLE_INNER_PARAM_ENTITY_REF, #endif /* XML_DTD */ XML_ROLE_PARAM_ENTITY_REF }; typedef struct prolog_state { int(PTRCALL *handler)(struct prolog_state *state, int tok, const char *ptr, const char *end, const ENCODING *enc); unsigned level; int role_none; #ifdef XML_DTD unsigned includeLevel; int documentEntity; int inEntityValue; #endif /* XML_DTD */ } PROLOG_STATE; void XmlPrologStateInit(PROLOG_STATE *); #ifdef XML_DTD void XmlPrologStateInitExternalEntity(PROLOG_STATE *); #endif /* XML_DTD */ #define XmlTokenRole(state, tok, ptr, end, enc) \ (((state)->handler)(state, tok, ptr, end, enc)) #ifdef __cplusplus } #endif #endif /* not XmlRole_INCLUDED */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/lib/xmltok.c0000644000175100001710000015131100000000000017270 0ustar00vstsdocker/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000-2017 Expat development team Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include /* memcpy */ #if defined(_MSC_VER) && (_MSC_VER <= 1700) /* for vs2012/11.0/1700 and earlier Visual Studio compilers */ # define bool int # define false 0 # define true 1 #else # include #endif #ifdef _WIN32 # include "winconfig.h" #else # ifdef HAVE_EXPAT_CONFIG_H # include # endif #endif /* ndef _WIN32 */ #include "expat_external.h" #include "internal.h" #include "xmltok.h" #include "nametab.h" #ifdef XML_DTD # define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok) #else # define IGNORE_SECTION_TOK_VTABLE /* as nothing */ #endif #define VTABLE1 \ {PREFIX(prologTok), PREFIX(contentTok), \ PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE}, \ {PREFIX(attributeValueTok), PREFIX(entityValueTok)}, \ PREFIX(nameMatchesAscii), PREFIX(nameLength), PREFIX(skipS), \ PREFIX(getAtts), PREFIX(charRefNumber), PREFIX(predefinedEntityName), \ PREFIX(updatePosition), PREFIX(isPublicId) #define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16) #define UCS2_GET_NAMING(pages, hi, lo) \ (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1u << ((lo)&0x1F))) /* A 2 byte UTF-8 representation splits the characters 11 bits between the bottom 5 and 6 bits of the bytes. We need 8 bits to index into pages, 3 bits to add to that index and 5 bits to generate the mask. */ #define UTF8_GET_NAMING2(pages, byte) \ (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \ + ((((byte)[0]) & 3) << 1) + ((((byte)[1]) >> 5) & 1)] \ & (1u << (((byte)[1]) & 0x1F))) /* A 3 byte UTF-8 representation splits the characters 16 bits between the bottom 4, 6 and 6 bits of the bytes. We need 8 bits to index into pages, 3 bits to add to that index and 5 bits to generate the mask. */ #define UTF8_GET_NAMING3(pages, byte) \ (namingBitmap \ [((pages)[((((byte)[0]) & 0xF) << 4) + ((((byte)[1]) >> 2) & 0xF)] \ << 3) \ + ((((byte)[1]) & 3) << 1) + ((((byte)[2]) >> 5) & 1)] \ & (1u << (((byte)[2]) & 0x1F))) #define UTF8_GET_NAMING(pages, p, n) \ ((n) == 2 \ ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \ : ((n) == 3 ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) : 0)) /* Detection of invalid UTF-8 sequences is based on Table 3.1B of Unicode 3.2: http://www.unicode.org/unicode/reports/tr28/ with the additional restriction of not allowing the Unicode code points 0xFFFF and 0xFFFE (sequences EF,BF,BF and EF,BF,BE). Implementation details: (A & 0x80) == 0 means A < 0x80 and (A & 0xC0) == 0xC0 means A > 0xBF */ #define UTF8_INVALID2(p) \ ((*p) < 0xC2 || ((p)[1] & 0x80) == 0 || ((p)[1] & 0xC0) == 0xC0) #define UTF8_INVALID3(p) \ (((p)[2] & 0x80) == 0 \ || ((*p) == 0xEF && (p)[1] == 0xBF ? (p)[2] > 0xBD \ : ((p)[2] & 0xC0) == 0xC0) \ || ((*p) == 0xE0 \ ? (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0 \ : ((p)[1] & 0x80) == 0 \ || ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0))) #define UTF8_INVALID4(p) \ (((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 || ((p)[2] & 0x80) == 0 \ || ((p)[2] & 0xC0) == 0xC0 \ || ((*p) == 0xF0 \ ? (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0 \ : ((p)[1] & 0x80) == 0 \ || ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0))) static int PTRFASTCALL isNever(const ENCODING *enc, const char *p) { UNUSED_P(enc); UNUSED_P(p); return 0; } static int PTRFASTCALL utf8_isName2(const ENCODING *enc, const char *p) { UNUSED_P(enc); return UTF8_GET_NAMING2(namePages, (const unsigned char *)p); } static int PTRFASTCALL utf8_isName3(const ENCODING *enc, const char *p) { UNUSED_P(enc); return UTF8_GET_NAMING3(namePages, (const unsigned char *)p); } #define utf8_isName4 isNever static int PTRFASTCALL utf8_isNmstrt2(const ENCODING *enc, const char *p) { UNUSED_P(enc); return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p); } static int PTRFASTCALL utf8_isNmstrt3(const ENCODING *enc, const char *p) { UNUSED_P(enc); return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p); } #define utf8_isNmstrt4 isNever static int PTRFASTCALL utf8_isInvalid2(const ENCODING *enc, const char *p) { UNUSED_P(enc); return UTF8_INVALID2((const unsigned char *)p); } static int PTRFASTCALL utf8_isInvalid3(const ENCODING *enc, const char *p) { UNUSED_P(enc); return UTF8_INVALID3((const unsigned char *)p); } static int PTRFASTCALL utf8_isInvalid4(const ENCODING *enc, const char *p) { UNUSED_P(enc); return UTF8_INVALID4((const unsigned char *)p); } struct normal_encoding { ENCODING enc; unsigned char type[256]; #ifdef XML_MIN_SIZE int(PTRFASTCALL *byteType)(const ENCODING *, const char *); int(PTRFASTCALL *isNameMin)(const ENCODING *, const char *); int(PTRFASTCALL *isNmstrtMin)(const ENCODING *, const char *); int(PTRFASTCALL *byteToAscii)(const ENCODING *, const char *); int(PTRCALL *charMatches)(const ENCODING *, const char *, int); #endif /* XML_MIN_SIZE */ int(PTRFASTCALL *isName2)(const ENCODING *, const char *); int(PTRFASTCALL *isName3)(const ENCODING *, const char *); int(PTRFASTCALL *isName4)(const ENCODING *, const char *); int(PTRFASTCALL *isNmstrt2)(const ENCODING *, const char *); int(PTRFASTCALL *isNmstrt3)(const ENCODING *, const char *); int(PTRFASTCALL *isNmstrt4)(const ENCODING *, const char *); int(PTRFASTCALL *isInvalid2)(const ENCODING *, const char *); int(PTRFASTCALL *isInvalid3)(const ENCODING *, const char *); int(PTRFASTCALL *isInvalid4)(const ENCODING *, const char *); }; #define AS_NORMAL_ENCODING(enc) ((const struct normal_encoding *)(enc)) #ifdef XML_MIN_SIZE # define STANDARD_VTABLE(E) \ E##byteType, E##isNameMin, E##isNmstrtMin, E##byteToAscii, E##charMatches, #else # define STANDARD_VTABLE(E) /* as nothing */ #endif #define NORMAL_VTABLE(E) \ E##isName2, E##isName3, E##isName4, E##isNmstrt2, E##isNmstrt3, \ E##isNmstrt4, E##isInvalid2, E##isInvalid3, E##isInvalid4 #define NULL_VTABLE \ /* isName2 */ NULL, /* isName3 */ NULL, /* isName4 */ NULL, \ /* isNmstrt2 */ NULL, /* isNmstrt3 */ NULL, /* isNmstrt4 */ NULL, \ /* isInvalid2 */ NULL, /* isInvalid3 */ NULL, /* isInvalid4 */ NULL static int FASTCALL checkCharRefNumber(int); #include "xmltok_impl.h" #include "ascii.h" #ifdef XML_MIN_SIZE # define sb_isNameMin isNever # define sb_isNmstrtMin isNever #endif #ifdef XML_MIN_SIZE # define MINBPC(enc) ((enc)->minBytesPerChar) #else /* minimum bytes per character */ # define MINBPC(enc) 1 #endif #define SB_BYTE_TYPE(enc, p) \ (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)]) #ifdef XML_MIN_SIZE static int PTRFASTCALL sb_byteType(const ENCODING *enc, const char *p) { return SB_BYTE_TYPE(enc, p); } # define BYTE_TYPE(enc, p) (AS_NORMAL_ENCODING(enc)->byteType(enc, p)) #else # define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p) #endif #ifdef XML_MIN_SIZE # define BYTE_TO_ASCII(enc, p) (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p)) static int PTRFASTCALL sb_byteToAscii(const ENCODING *enc, const char *p) { UNUSED_P(enc); return *p; } #else # define BYTE_TO_ASCII(enc, p) (*(p)) #endif #define IS_NAME_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isName##n(enc, p)) #define IS_NMSTRT_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isNmstrt##n(enc, p)) #define IS_INVALID_CHAR(enc, p, n) \ (AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p)) #ifdef XML_MIN_SIZE # define IS_NAME_CHAR_MINBPC(enc, p) \ (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p)) # define IS_NMSTRT_CHAR_MINBPC(enc, p) \ (AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p)) #else # define IS_NAME_CHAR_MINBPC(enc, p) (0) # define IS_NMSTRT_CHAR_MINBPC(enc, p) (0) #endif #ifdef XML_MIN_SIZE # define CHAR_MATCHES(enc, p, c) \ (AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c)) static int PTRCALL sb_charMatches(const ENCODING *enc, const char *p, int c) { UNUSED_P(enc); return *p == c; } #else /* c is an ASCII character */ # define CHAR_MATCHES(enc, p, c) (*(p) == c) #endif #define PREFIX(ident) normal_##ident #define XML_TOK_IMPL_C #include "xmltok_impl.c" #undef XML_TOK_IMPL_C #undef MINBPC #undef BYTE_TYPE #undef BYTE_TO_ASCII #undef CHAR_MATCHES #undef IS_NAME_CHAR #undef IS_NAME_CHAR_MINBPC #undef IS_NMSTRT_CHAR #undef IS_NMSTRT_CHAR_MINBPC #undef IS_INVALID_CHAR enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */ UTF8_cval1 = 0x00, UTF8_cval2 = 0xc0, UTF8_cval3 = 0xe0, UTF8_cval4 = 0xf0 }; void _INTERNAL_trim_to_complete_utf8_characters(const char *from, const char **fromLimRef) { const char *fromLim = *fromLimRef; size_t walked = 0; for (; fromLim > from; fromLim--, walked++) { const unsigned char prev = (unsigned char)fromLim[-1]; if ((prev & 0xf8u) == 0xf0u) { /* 4-byte character, lead by 0b11110xxx byte */ if (walked + 1 >= 4) { fromLim += 4 - 1; break; } else { walked = 0; } } else if ((prev & 0xf0u) == 0xe0u) { /* 3-byte character, lead by 0b1110xxxx byte */ if (walked + 1 >= 3) { fromLim += 3 - 1; break; } else { walked = 0; } } else if ((prev & 0xe0u) == 0xc0u) { /* 2-byte character, lead by 0b110xxxxx byte */ if (walked + 1 >= 2) { fromLim += 2 - 1; break; } else { walked = 0; } } else if ((prev & 0x80u) == 0x00u) { /* 1-byte character, matching 0b0xxxxxxx */ break; } } *fromLimRef = fromLim; } static enum XML_Convert_Result PTRCALL utf8_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, char **toP, const char *toLim) { bool input_incomplete = false; bool output_exhausted = false; /* Avoid copying partial characters (due to limited space). */ const ptrdiff_t bytesAvailable = fromLim - *fromP; const ptrdiff_t bytesStorable = toLim - *toP; UNUSED_P(enc); if (bytesAvailable > bytesStorable) { fromLim = *fromP + bytesStorable; output_exhausted = true; } /* Avoid copying partial characters (from incomplete input). */ { const char *const fromLimBefore = fromLim; _INTERNAL_trim_to_complete_utf8_characters(*fromP, &fromLim); if (fromLim < fromLimBefore) { input_incomplete = true; } } { const ptrdiff_t bytesToCopy = fromLim - *fromP; memcpy(*toP, *fromP, bytesToCopy); *fromP += bytesToCopy; *toP += bytesToCopy; } if (output_exhausted) /* needs to go first */ return XML_CONVERT_OUTPUT_EXHAUSTED; else if (input_incomplete) return XML_CONVERT_INPUT_INCOMPLETE; else return XML_CONVERT_COMPLETED; } static enum XML_Convert_Result PTRCALL utf8_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, unsigned short **toP, const unsigned short *toLim) { enum XML_Convert_Result res = XML_CONVERT_COMPLETED; unsigned short *to = *toP; const char *from = *fromP; while (from < fromLim && to < toLim) { switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) { case BT_LEAD2: if (fromLim - from < 2) { res = XML_CONVERT_INPUT_INCOMPLETE; goto after; } *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f)); from += 2; break; case BT_LEAD3: if (fromLim - from < 3) { res = XML_CONVERT_INPUT_INCOMPLETE; goto after; } *to++ = (unsigned short)(((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f)); from += 3; break; case BT_LEAD4: { unsigned long n; if (toLim - to < 2) { res = XML_CONVERT_OUTPUT_EXHAUSTED; goto after; } if (fromLim - from < 4) { res = XML_CONVERT_INPUT_INCOMPLETE; goto after; } n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f); n -= 0x10000; to[0] = (unsigned short)((n >> 10) | 0xD800); to[1] = (unsigned short)((n & 0x3FF) | 0xDC00); to += 2; from += 4; } break; default: *to++ = *from++; break; } } if (from < fromLim) res = XML_CONVERT_OUTPUT_EXHAUSTED; after: *fromP = from; *toP = to; return res; } #ifdef XML_NS static const struct normal_encoding utf8_encoding_ns = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, { # include "asciitab.h" # include "utf8tab.h" }, STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; #endif static const struct normal_encoding utf8_encoding = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, { #define BT_COLON BT_NMSTRT #include "asciitab.h" #undef BT_COLON #include "utf8tab.h" }, STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; #ifdef XML_NS static const struct normal_encoding internal_utf8_encoding_ns = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, { # include "iasciitab.h" # include "utf8tab.h" }, STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; #endif static const struct normal_encoding internal_utf8_encoding = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, { #define BT_COLON BT_NMSTRT #include "iasciitab.h" #undef BT_COLON #include "utf8tab.h" }, STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; static enum XML_Convert_Result PTRCALL latin1_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, char **toP, const char *toLim) { UNUSED_P(enc); for (;;) { unsigned char c; if (*fromP == fromLim) return XML_CONVERT_COMPLETED; c = (unsigned char)**fromP; if (c & 0x80) { if (toLim - *toP < 2) return XML_CONVERT_OUTPUT_EXHAUSTED; *(*toP)++ = (char)((c >> 6) | UTF8_cval2); *(*toP)++ = (char)((c & 0x3f) | 0x80); (*fromP)++; } else { if (*toP == toLim) return XML_CONVERT_OUTPUT_EXHAUSTED; *(*toP)++ = *(*fromP)++; } } } static enum XML_Convert_Result PTRCALL latin1_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, unsigned short **toP, const unsigned short *toLim) { UNUSED_P(enc); while (*fromP < fromLim && *toP < toLim) *(*toP)++ = (unsigned char)*(*fromP)++; if ((*toP == toLim) && (*fromP < fromLim)) return XML_CONVERT_OUTPUT_EXHAUSTED; else return XML_CONVERT_COMPLETED; } #ifdef XML_NS static const struct normal_encoding latin1_encoding_ns = {{VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0}, { # include "asciitab.h" # include "latin1tab.h" }, STANDARD_VTABLE(sb_) NULL_VTABLE}; #endif static const struct normal_encoding latin1_encoding = {{VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0}, { #define BT_COLON BT_NMSTRT #include "asciitab.h" #undef BT_COLON #include "latin1tab.h" }, STANDARD_VTABLE(sb_) NULL_VTABLE}; static enum XML_Convert_Result PTRCALL ascii_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, char **toP, const char *toLim) { UNUSED_P(enc); while (*fromP < fromLim && *toP < toLim) *(*toP)++ = *(*fromP)++; if ((*toP == toLim) && (*fromP < fromLim)) return XML_CONVERT_OUTPUT_EXHAUSTED; else return XML_CONVERT_COMPLETED; } #ifdef XML_NS static const struct normal_encoding ascii_encoding_ns = {{VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0}, { # include "asciitab.h" /* BT_NONXML == 0 */ }, STANDARD_VTABLE(sb_) NULL_VTABLE}; #endif static const struct normal_encoding ascii_encoding = {{VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0}, { #define BT_COLON BT_NMSTRT #include "asciitab.h" #undef BT_COLON /* BT_NONXML == 0 */ }, STANDARD_VTABLE(sb_) NULL_VTABLE}; static int PTRFASTCALL unicode_byte_type(char hi, char lo) { switch ((unsigned char)hi) { /* 0xD800–0xDBFF first 16-bit code unit or high surrogate (W1) */ case 0xD8: case 0xD9: case 0xDA: case 0xDB: return BT_LEAD4; /* 0xDC00–0xDFFF second 16-bit code unit or low surrogate (W2) */ case 0xDC: case 0xDD: case 0xDE: case 0xDF: return BT_TRAIL; case 0xFF: switch ((unsigned char)lo) { case 0xFF: /* noncharacter-FFFF */ case 0xFE: /* noncharacter-FFFE */ return BT_NONXML; } break; } return BT_NONASCII; } #define DEFINE_UTF16_TO_UTF8(E) \ static enum XML_Convert_Result PTRCALL E##toUtf8( \ const ENCODING *enc, const char **fromP, const char *fromLim, \ char **toP, const char *toLim) { \ const char *from = *fromP; \ UNUSED_P(enc); \ fromLim = from + (((fromLim - from) >> 1) << 1); /* shrink to even */ \ for (; from < fromLim; from += 2) { \ int plane; \ unsigned char lo2; \ unsigned char lo = GET_LO(from); \ unsigned char hi = GET_HI(from); \ switch (hi) { \ case 0: \ if (lo < 0x80) { \ if (*toP == toLim) { \ *fromP = from; \ return XML_CONVERT_OUTPUT_EXHAUSTED; \ } \ *(*toP)++ = lo; \ break; \ } \ /* fall through */ \ case 0x1: \ case 0x2: \ case 0x3: \ case 0x4: \ case 0x5: \ case 0x6: \ case 0x7: \ if (toLim - *toP < 2) { \ *fromP = from; \ return XML_CONVERT_OUTPUT_EXHAUSTED; \ } \ *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \ *(*toP)++ = ((lo & 0x3f) | 0x80); \ break; \ default: \ if (toLim - *toP < 3) { \ *fromP = from; \ return XML_CONVERT_OUTPUT_EXHAUSTED; \ } \ /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \ *(*toP)++ = ((hi >> 4) | UTF8_cval3); \ *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \ *(*toP)++ = ((lo & 0x3f) | 0x80); \ break; \ case 0xD8: \ case 0xD9: \ case 0xDA: \ case 0xDB: \ if (toLim - *toP < 4) { \ *fromP = from; \ return XML_CONVERT_OUTPUT_EXHAUSTED; \ } \ if (fromLim - from < 4) { \ *fromP = from; \ return XML_CONVERT_INPUT_INCOMPLETE; \ } \ plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \ *(*toP)++ = (char)((plane >> 2) | UTF8_cval4); \ *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \ from += 2; \ lo2 = GET_LO(from); \ *(*toP)++ = (((lo & 0x3) << 4) | ((GET_HI(from) & 0x3) << 2) \ | (lo2 >> 6) | 0x80); \ *(*toP)++ = ((lo2 & 0x3f) | 0x80); \ break; \ } \ } \ *fromP = from; \ if (from < fromLim) \ return XML_CONVERT_INPUT_INCOMPLETE; \ else \ return XML_CONVERT_COMPLETED; \ } #define DEFINE_UTF16_TO_UTF16(E) \ static enum XML_Convert_Result PTRCALL E##toUtf16( \ const ENCODING *enc, const char **fromP, const char *fromLim, \ unsigned short **toP, const unsigned short *toLim) { \ enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \ UNUSED_P(enc); \ fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */ \ /* Avoid copying first half only of surrogate */ \ if (fromLim - *fromP > ((toLim - *toP) << 1) \ && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) { \ fromLim -= 2; \ res = XML_CONVERT_INPUT_INCOMPLETE; \ } \ for (; *fromP < fromLim && *toP < toLim; *fromP += 2) \ *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \ if ((*toP == toLim) && (*fromP < fromLim)) \ return XML_CONVERT_OUTPUT_EXHAUSTED; \ else \ return res; \ } #define SET2(ptr, ch) (((ptr)[0] = ((ch)&0xff)), ((ptr)[1] = ((ch) >> 8))) #define GET_LO(ptr) ((unsigned char)(ptr)[0]) #define GET_HI(ptr) ((unsigned char)(ptr)[1]) DEFINE_UTF16_TO_UTF8(little2_) DEFINE_UTF16_TO_UTF16(little2_) #undef SET2 #undef GET_LO #undef GET_HI #define SET2(ptr, ch) (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch)&0xFF))) #define GET_LO(ptr) ((unsigned char)(ptr)[1]) #define GET_HI(ptr) ((unsigned char)(ptr)[0]) DEFINE_UTF16_TO_UTF8(big2_) DEFINE_UTF16_TO_UTF16(big2_) #undef SET2 #undef GET_LO #undef GET_HI #define LITTLE2_BYTE_TYPE(enc, p) \ ((p)[1] == 0 ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \ : unicode_byte_type((p)[1], (p)[0])) #define LITTLE2_BYTE_TO_ASCII(p) ((p)[1] == 0 ? (p)[0] : -1) #define LITTLE2_CHAR_MATCHES(p, c) ((p)[1] == 0 && (p)[0] == c) #define LITTLE2_IS_NAME_CHAR_MINBPC(p) \ UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0]) #define LITTLE2_IS_NMSTRT_CHAR_MINBPC(p) \ UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0]) #ifdef XML_MIN_SIZE static int PTRFASTCALL little2_byteType(const ENCODING *enc, const char *p) { return LITTLE2_BYTE_TYPE(enc, p); } static int PTRFASTCALL little2_byteToAscii(const ENCODING *enc, const char *p) { UNUSED_P(enc); return LITTLE2_BYTE_TO_ASCII(p); } static int PTRCALL little2_charMatches(const ENCODING *enc, const char *p, int c) { UNUSED_P(enc); return LITTLE2_CHAR_MATCHES(p, c); } static int PTRFASTCALL little2_isNameMin(const ENCODING *enc, const char *p) { UNUSED_P(enc); return LITTLE2_IS_NAME_CHAR_MINBPC(p); } static int PTRFASTCALL little2_isNmstrtMin(const ENCODING *enc, const char *p) { UNUSED_P(enc); return LITTLE2_IS_NMSTRT_CHAR_MINBPC(p); } # undef VTABLE # define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16 #else /* not XML_MIN_SIZE */ # undef PREFIX # define PREFIX(ident) little2_##ident # define MINBPC(enc) 2 /* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ # define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p) # define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(p) # define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(p, c) # define IS_NAME_CHAR(enc, p, n) 0 # define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(p) # define IS_NMSTRT_CHAR(enc, p, n) (0) # define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(p) # define XML_TOK_IMPL_C # include "xmltok_impl.c" # undef XML_TOK_IMPL_C # undef MINBPC # undef BYTE_TYPE # undef BYTE_TO_ASCII # undef CHAR_MATCHES # undef IS_NAME_CHAR # undef IS_NAME_CHAR_MINBPC # undef IS_NMSTRT_CHAR # undef IS_NMSTRT_CHAR_MINBPC # undef IS_INVALID_CHAR #endif /* not XML_MIN_SIZE */ #ifdef XML_NS static const struct normal_encoding little2_encoding_ns = {{VTABLE, 2, 0, # if BYTEORDER == 1234 1 # else 0 # endif }, { # include "asciitab.h" # include "latin1tab.h" }, STANDARD_VTABLE(little2_) NULL_VTABLE}; #endif static const struct normal_encoding little2_encoding = {{VTABLE, 2, 0, #if BYTEORDER == 1234 1 #else 0 #endif }, { #define BT_COLON BT_NMSTRT #include "asciitab.h" #undef BT_COLON #include "latin1tab.h" }, STANDARD_VTABLE(little2_) NULL_VTABLE}; #if BYTEORDER != 4321 # ifdef XML_NS static const struct normal_encoding internal_little2_encoding_ns = {{VTABLE, 2, 0, 1}, { # include "iasciitab.h" # include "latin1tab.h" }, STANDARD_VTABLE(little2_) NULL_VTABLE}; # endif static const struct normal_encoding internal_little2_encoding = {{VTABLE, 2, 0, 1}, { # define BT_COLON BT_NMSTRT # include "iasciitab.h" # undef BT_COLON # include "latin1tab.h" }, STANDARD_VTABLE(little2_) NULL_VTABLE}; #endif #define BIG2_BYTE_TYPE(enc, p) \ ((p)[0] == 0 \ ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \ : unicode_byte_type((p)[0], (p)[1])) #define BIG2_BYTE_TO_ASCII(p) ((p)[0] == 0 ? (p)[1] : -1) #define BIG2_CHAR_MATCHES(p, c) ((p)[0] == 0 && (p)[1] == c) #define BIG2_IS_NAME_CHAR_MINBPC(p) \ UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1]) #define BIG2_IS_NMSTRT_CHAR_MINBPC(p) \ UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1]) #ifdef XML_MIN_SIZE static int PTRFASTCALL big2_byteType(const ENCODING *enc, const char *p) { return BIG2_BYTE_TYPE(enc, p); } static int PTRFASTCALL big2_byteToAscii(const ENCODING *enc, const char *p) { UNUSED_P(enc); return BIG2_BYTE_TO_ASCII(p); } static int PTRCALL big2_charMatches(const ENCODING *enc, const char *p, int c) { UNUSED_P(enc); return BIG2_CHAR_MATCHES(p, c); } static int PTRFASTCALL big2_isNameMin(const ENCODING *enc, const char *p) { UNUSED_P(enc); return BIG2_IS_NAME_CHAR_MINBPC(p); } static int PTRFASTCALL big2_isNmstrtMin(const ENCODING *enc, const char *p) { UNUSED_P(enc); return BIG2_IS_NMSTRT_CHAR_MINBPC(p); } # undef VTABLE # define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16 #else /* not XML_MIN_SIZE */ # undef PREFIX # define PREFIX(ident) big2_##ident # define MINBPC(enc) 2 /* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ # define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p) # define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(p) # define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(p, c) # define IS_NAME_CHAR(enc, p, n) 0 # define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(p) # define IS_NMSTRT_CHAR(enc, p, n) (0) # define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(p) # define XML_TOK_IMPL_C # include "xmltok_impl.c" # undef XML_TOK_IMPL_C # undef MINBPC # undef BYTE_TYPE # undef BYTE_TO_ASCII # undef CHAR_MATCHES # undef IS_NAME_CHAR # undef IS_NAME_CHAR_MINBPC # undef IS_NMSTRT_CHAR # undef IS_NMSTRT_CHAR_MINBPC # undef IS_INVALID_CHAR #endif /* not XML_MIN_SIZE */ #ifdef XML_NS static const struct normal_encoding big2_encoding_ns = {{VTABLE, 2, 0, # if BYTEORDER == 4321 1 # else 0 # endif }, { # include "asciitab.h" # include "latin1tab.h" }, STANDARD_VTABLE(big2_) NULL_VTABLE}; #endif static const struct normal_encoding big2_encoding = {{VTABLE, 2, 0, #if BYTEORDER == 4321 1 #else 0 #endif }, { #define BT_COLON BT_NMSTRT #include "asciitab.h" #undef BT_COLON #include "latin1tab.h" }, STANDARD_VTABLE(big2_) NULL_VTABLE}; #if BYTEORDER != 1234 # ifdef XML_NS static const struct normal_encoding internal_big2_encoding_ns = {{VTABLE, 2, 0, 1}, { # include "iasciitab.h" # include "latin1tab.h" }, STANDARD_VTABLE(big2_) NULL_VTABLE}; # endif static const struct normal_encoding internal_big2_encoding = {{VTABLE, 2, 0, 1}, { # define BT_COLON BT_NMSTRT # include "iasciitab.h" # undef BT_COLON # include "latin1tab.h" }, STANDARD_VTABLE(big2_) NULL_VTABLE}; #endif #undef PREFIX static int FASTCALL streqci(const char *s1, const char *s2) { for (;;) { char c1 = *s1++; char c2 = *s2++; if (ASCII_a <= c1 && c1 <= ASCII_z) c1 += ASCII_A - ASCII_a; if (ASCII_a <= c2 && c2 <= ASCII_z) /* The following line will never get executed. streqci() is * only called from two places, both of which guarantee to put * upper-case strings into s2. */ c2 += ASCII_A - ASCII_a; /* LCOV_EXCL_LINE */ if (c1 != c2) return 0; if (! c1) break; } return 1; } static void PTRCALL initUpdatePosition(const ENCODING *enc, const char *ptr, const char *end, POSITION *pos) { UNUSED_P(enc); normal_updatePosition(&utf8_encoding.enc, ptr, end, pos); } static int toAscii(const ENCODING *enc, const char *ptr, const char *end) { char buf[1]; char *p = buf; XmlUtf8Convert(enc, &ptr, end, &p, p + 1); if (p == buf) return -1; else return buf[0]; } static int FASTCALL isSpace(int c) { switch (c) { case 0x20: case 0xD: case 0xA: case 0x9: return 1; } return 0; } /* Return 1 if there's just optional white space or there's an S followed by name=val. */ static int parsePseudoAttribute(const ENCODING *enc, const char *ptr, const char *end, const char **namePtr, const char **nameEndPtr, const char **valPtr, const char **nextTokPtr) { int c; char open; if (ptr == end) { *namePtr = NULL; return 1; } if (! isSpace(toAscii(enc, ptr, end))) { *nextTokPtr = ptr; return 0; } do { ptr += enc->minBytesPerChar; } while (isSpace(toAscii(enc, ptr, end))); if (ptr == end) { *namePtr = NULL; return 1; } *namePtr = ptr; for (;;) { c = toAscii(enc, ptr, end); if (c == -1) { *nextTokPtr = ptr; return 0; } if (c == ASCII_EQUALS) { *nameEndPtr = ptr; break; } if (isSpace(c)) { *nameEndPtr = ptr; do { ptr += enc->minBytesPerChar; } while (isSpace(c = toAscii(enc, ptr, end))); if (c != ASCII_EQUALS) { *nextTokPtr = ptr; return 0; } break; } ptr += enc->minBytesPerChar; } if (ptr == *namePtr) { *nextTokPtr = ptr; return 0; } ptr += enc->minBytesPerChar; c = toAscii(enc, ptr, end); while (isSpace(c)) { ptr += enc->minBytesPerChar; c = toAscii(enc, ptr, end); } if (c != ASCII_QUOT && c != ASCII_APOS) { *nextTokPtr = ptr; return 0; } open = (char)c; ptr += enc->minBytesPerChar; *valPtr = ptr; for (;; ptr += enc->minBytesPerChar) { c = toAscii(enc, ptr, end); if (c == open) break; if (! (ASCII_a <= c && c <= ASCII_z) && ! (ASCII_A <= c && c <= ASCII_Z) && ! (ASCII_0 <= c && c <= ASCII_9) && c != ASCII_PERIOD && c != ASCII_MINUS && c != ASCII_UNDERSCORE) { *nextTokPtr = ptr; return 0; } } *nextTokPtr = ptr + enc->minBytesPerChar; return 1; } static const char KW_version[] = {ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0'}; static const char KW_encoding[] = {ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, ASCII_i, ASCII_n, ASCII_g, '\0'}; static const char KW_standalone[] = {ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, ASCII_l, ASCII_o, ASCII_n, ASCII_e, '\0'}; static const char KW_yes[] = {ASCII_y, ASCII_e, ASCII_s, '\0'}; static const char KW_no[] = {ASCII_n, ASCII_o, '\0'}; static int doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, const char *, const char *), int isGeneralTextEntity, const ENCODING *enc, const char *ptr, const char *end, const char **badPtr, const char **versionPtr, const char **versionEndPtr, const char **encodingName, const ENCODING **encoding, int *standalone) { const char *val = NULL; const char *name = NULL; const char *nameEnd = NULL; ptr += 5 * enc->minBytesPerChar; end -= 2 * enc->minBytesPerChar; if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr) || ! name) { *badPtr = ptr; return 0; } if (! XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) { if (! isGeneralTextEntity) { *badPtr = name; return 0; } } else { if (versionPtr) *versionPtr = val; if (versionEndPtr) *versionEndPtr = ptr; if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { *badPtr = ptr; return 0; } if (! name) { if (isGeneralTextEntity) { /* a TextDecl must have an EncodingDecl */ *badPtr = ptr; return 0; } return 1; } } if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) { int c = toAscii(enc, val, end); if (! (ASCII_a <= c && c <= ASCII_z) && ! (ASCII_A <= c && c <= ASCII_Z)) { *badPtr = val; return 0; } if (encodingName) *encodingName = val; if (encoding) *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar); if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { *badPtr = ptr; return 0; } if (! name) return 1; } if (! XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone) || isGeneralTextEntity) { *badPtr = name; return 0; } if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) { if (standalone) *standalone = 1; } else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) { if (standalone) *standalone = 0; } else { *badPtr = val; return 0; } while (isSpace(toAscii(enc, ptr, end))) ptr += enc->minBytesPerChar; if (ptr != end) { *badPtr = ptr; return 0; } return 1; } static int FASTCALL checkCharRefNumber(int result) { switch (result >> 8) { case 0xD8: case 0xD9: case 0xDA: case 0xDB: case 0xDC: case 0xDD: case 0xDE: case 0xDF: return -1; case 0: if (latin1_encoding.type[result] == BT_NONXML) return -1; break; case 0xFF: if (result == 0xFFFE || result == 0xFFFF) return -1; break; } return result; } int FASTCALL XmlUtf8Encode(int c, char *buf) { enum { /* minN is minimum legal resulting value for N byte sequence */ min2 = 0x80, min3 = 0x800, min4 = 0x10000 }; if (c < 0) return 0; /* LCOV_EXCL_LINE: this case is always eliminated beforehand */ if (c < min2) { buf[0] = (char)(c | UTF8_cval1); return 1; } if (c < min3) { buf[0] = (char)((c >> 6) | UTF8_cval2); buf[1] = (char)((c & 0x3f) | 0x80); return 2; } if (c < min4) { buf[0] = (char)((c >> 12) | UTF8_cval3); buf[1] = (char)(((c >> 6) & 0x3f) | 0x80); buf[2] = (char)((c & 0x3f) | 0x80); return 3; } if (c < 0x110000) { buf[0] = (char)((c >> 18) | UTF8_cval4); buf[1] = (char)(((c >> 12) & 0x3f) | 0x80); buf[2] = (char)(((c >> 6) & 0x3f) | 0x80); buf[3] = (char)((c & 0x3f) | 0x80); return 4; } return 0; /* LCOV_EXCL_LINE: this case too is eliminated before calling */ } int FASTCALL XmlUtf16Encode(int charNum, unsigned short *buf) { if (charNum < 0) return 0; if (charNum < 0x10000) { buf[0] = (unsigned short)charNum; return 1; } if (charNum < 0x110000) { charNum -= 0x10000; buf[0] = (unsigned short)((charNum >> 10) + 0xD800); buf[1] = (unsigned short)((charNum & 0x3FF) + 0xDC00); return 2; } return 0; } struct unknown_encoding { struct normal_encoding normal; CONVERTER convert; void *userData; unsigned short utf16[256]; char utf8[256][4]; }; #define AS_UNKNOWN_ENCODING(enc) ((const struct unknown_encoding *)(enc)) int XmlSizeOfUnknownEncoding(void) { return sizeof(struct unknown_encoding); } static int PTRFASTCALL unknown_isName(const ENCODING *enc, const char *p) { const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); int c = uenc->convert(uenc->userData, p); if (c & ~0xFFFF) return 0; return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF); } static int PTRFASTCALL unknown_isNmstrt(const ENCODING *enc, const char *p) { const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); int c = uenc->convert(uenc->userData, p); if (c & ~0xFFFF) return 0; return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF); } static int PTRFASTCALL unknown_isInvalid(const ENCODING *enc, const char *p) { const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); int c = uenc->convert(uenc->userData, p); return (c & ~0xFFFF) || checkCharRefNumber(c) < 0; } static enum XML_Convert_Result PTRCALL unknown_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, char **toP, const char *toLim) { const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); char buf[XML_UTF8_ENCODE_MAX]; for (;;) { const char *utf8; int n; if (*fromP == fromLim) return XML_CONVERT_COMPLETED; utf8 = uenc->utf8[(unsigned char)**fromP]; n = *utf8++; if (n == 0) { int c = uenc->convert(uenc->userData, *fromP); n = XmlUtf8Encode(c, buf); if (n > toLim - *toP) return XML_CONVERT_OUTPUT_EXHAUSTED; utf8 = buf; *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP] - (BT_LEAD2 - 2)); } else { if (n > toLim - *toP) return XML_CONVERT_OUTPUT_EXHAUSTED; (*fromP)++; } memcpy(*toP, utf8, n); *toP += n; } } static enum XML_Convert_Result PTRCALL unknown_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, unsigned short **toP, const unsigned short *toLim) { const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); while (*fromP < fromLim && *toP < toLim) { unsigned short c = uenc->utf16[(unsigned char)**fromP]; if (c == 0) { c = (unsigned short)uenc->convert(uenc->userData, *fromP); *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP] - (BT_LEAD2 - 2)); } else (*fromP)++; *(*toP)++ = c; } if ((*toP == toLim) && (*fromP < fromLim)) return XML_CONVERT_OUTPUT_EXHAUSTED; else return XML_CONVERT_COMPLETED; } ENCODING * XmlInitUnknownEncoding(void *mem, int *table, CONVERTER convert, void *userData) { int i; struct unknown_encoding *e = (struct unknown_encoding *)mem; memcpy(mem, &latin1_encoding, sizeof(struct normal_encoding)); for (i = 0; i < 128; i++) if (latin1_encoding.type[i] != BT_OTHER && latin1_encoding.type[i] != BT_NONXML && table[i] != i) return 0; for (i = 0; i < 256; i++) { int c = table[i]; if (c == -1) { e->normal.type[i] = BT_MALFORM; /* This shouldn't really get used. */ e->utf16[i] = 0xFFFF; e->utf8[i][0] = 1; e->utf8[i][1] = 0; } else if (c < 0) { if (c < -4) return 0; /* Multi-byte sequences need a converter function */ if (! convert) return 0; e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2)); e->utf8[i][0] = 0; e->utf16[i] = 0; } else if (c < 0x80) { if (latin1_encoding.type[c] != BT_OTHER && latin1_encoding.type[c] != BT_NONXML && c != i) return 0; e->normal.type[i] = latin1_encoding.type[c]; e->utf8[i][0] = 1; e->utf8[i][1] = (char)c; e->utf16[i] = (unsigned short)(c == 0 ? 0xFFFF : c); } else if (checkCharRefNumber(c) < 0) { e->normal.type[i] = BT_NONXML; /* This shouldn't really get used. */ e->utf16[i] = 0xFFFF; e->utf8[i][0] = 1; e->utf8[i][1] = 0; } else { if (c > 0xFFFF) return 0; if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff)) e->normal.type[i] = BT_NMSTRT; else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff)) e->normal.type[i] = BT_NAME; else e->normal.type[i] = BT_OTHER; e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1); e->utf16[i] = (unsigned short)c; } } e->userData = userData; e->convert = convert; if (convert) { e->normal.isName2 = unknown_isName; e->normal.isName3 = unknown_isName; e->normal.isName4 = unknown_isName; e->normal.isNmstrt2 = unknown_isNmstrt; e->normal.isNmstrt3 = unknown_isNmstrt; e->normal.isNmstrt4 = unknown_isNmstrt; e->normal.isInvalid2 = unknown_isInvalid; e->normal.isInvalid3 = unknown_isInvalid; e->normal.isInvalid4 = unknown_isInvalid; } e->normal.enc.utf8Convert = unknown_toUtf8; e->normal.enc.utf16Convert = unknown_toUtf16; return &(e->normal.enc); } /* If this enumeration is changed, getEncodingIndex and encodings must also be changed. */ enum { UNKNOWN_ENC = -1, ISO_8859_1_ENC = 0, US_ASCII_ENC, UTF_8_ENC, UTF_16_ENC, UTF_16BE_ENC, UTF_16LE_ENC, /* must match encodingNames up to here */ NO_ENC }; static const char KW_ISO_8859_1[] = {ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, ASCII_5, ASCII_9, ASCII_MINUS, ASCII_1, '\0'}; static const char KW_US_ASCII[] = {ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, ASCII_C, ASCII_I, ASCII_I, '\0'}; static const char KW_UTF_8[] = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0'}; static const char KW_UTF_16[] = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0'}; static const char KW_UTF_16BE[] = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_B, ASCII_E, '\0'}; static const char KW_UTF_16LE[] = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_L, ASCII_E, '\0'}; static int FASTCALL getEncodingIndex(const char *name) { static const char *const encodingNames[] = { KW_ISO_8859_1, KW_US_ASCII, KW_UTF_8, KW_UTF_16, KW_UTF_16BE, KW_UTF_16LE, }; int i; if (name == NULL) return NO_ENC; for (i = 0; i < (int)(sizeof(encodingNames) / sizeof(encodingNames[0])); i++) if (streqci(name, encodingNames[i])) return i; return UNKNOWN_ENC; } /* For binary compatibility, we store the index of the encoding specified at initialization in the isUtf16 member. */ #define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16) #define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i) /* This is what detects the encoding. encodingTable maps from encoding indices to encodings; INIT_ENC_INDEX(enc) is the index of the external (protocol) specified encoding; state is XML_CONTENT_STATE if we're parsing an external text entity, and XML_PROLOG_STATE otherwise. */ static int initScan(const ENCODING *const *encodingTable, const INIT_ENCODING *enc, int state, const char *ptr, const char *end, const char **nextTokPtr) { const ENCODING **encPtr; if (ptr >= end) return XML_TOK_NONE; encPtr = enc->encPtr; if (ptr + 1 == end) { /* only a single byte available for auto-detection */ #ifndef XML_DTD /* FIXME */ /* a well-formed document entity must have more than one byte */ if (state != XML_CONTENT_STATE) return XML_TOK_PARTIAL; #endif /* so we're parsing an external text entity... */ /* if UTF-16 was externally specified, then we need at least 2 bytes */ switch (INIT_ENC_INDEX(enc)) { case UTF_16_ENC: case UTF_16LE_ENC: case UTF_16BE_ENC: return XML_TOK_PARTIAL; } switch ((unsigned char)*ptr) { case 0xFE: case 0xFF: case 0xEF: /* possibly first byte of UTF-8 BOM */ if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE) break; /* fall through */ case 0x00: case 0x3C: return XML_TOK_PARTIAL; } } else { switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) { case 0xFEFF: if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE) break; *nextTokPtr = ptr + 2; *encPtr = encodingTable[UTF_16BE_ENC]; return XML_TOK_BOM; /* 00 3C is handled in the default case */ case 0x3C00: if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC || INIT_ENC_INDEX(enc) == UTF_16_ENC) && state == XML_CONTENT_STATE) break; *encPtr = encodingTable[UTF_16LE_ENC]; return XmlTok(*encPtr, state, ptr, end, nextTokPtr); case 0xFFFE: if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE) break; *nextTokPtr = ptr + 2; *encPtr = encodingTable[UTF_16LE_ENC]; return XML_TOK_BOM; case 0xEFBB: /* Maybe a UTF-8 BOM (EF BB BF) */ /* If there's an explicitly specified (external) encoding of ISO-8859-1 or some flavour of UTF-16 and this is an external text entity, don't look for the BOM, because it might be a legal data. */ if (state == XML_CONTENT_STATE) { int e = INIT_ENC_INDEX(enc); if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC || e == UTF_16LE_ENC || e == UTF_16_ENC) break; } if (ptr + 2 == end) return XML_TOK_PARTIAL; if ((unsigned char)ptr[2] == 0xBF) { *nextTokPtr = ptr + 3; *encPtr = encodingTable[UTF_8_ENC]; return XML_TOK_BOM; } break; default: if (ptr[0] == '\0') { /* 0 isn't a legal data character. Furthermore a document entity can only start with ASCII characters. So the only way this can fail to be big-endian UTF-16 if it it's an external parsed general entity that's labelled as UTF-16LE. */ if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC) break; *encPtr = encodingTable[UTF_16BE_ENC]; return XmlTok(*encPtr, state, ptr, end, nextTokPtr); } else if (ptr[1] == '\0') { /* We could recover here in the case: - parsing an external entity - second byte is 0 - no externally specified encoding - no encoding declaration by assuming UTF-16LE. But we don't, because this would mean when presented just with a single byte, we couldn't reliably determine whether we needed further bytes. */ if (state == XML_CONTENT_STATE) break; *encPtr = encodingTable[UTF_16LE_ENC]; return XmlTok(*encPtr, state, ptr, end, nextTokPtr); } break; } } *encPtr = encodingTable[INIT_ENC_INDEX(enc)]; return XmlTok(*encPtr, state, ptr, end, nextTokPtr); } #define NS(x) x #define ns(x) x #define XML_TOK_NS_C #include "xmltok_ns.c" #undef XML_TOK_NS_C #undef NS #undef ns #ifdef XML_NS # define NS(x) x##NS # define ns(x) x##_ns # define XML_TOK_NS_C # include "xmltok_ns.c" # undef XML_TOK_NS_C # undef NS # undef ns ENCODING * XmlInitUnknownEncodingNS(void *mem, int *table, CONVERTER convert, void *userData) { ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData); if (enc) ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON; return enc; } #endif /* XML_NS */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/lib/xmltok.h0000644000175100001710000003037500000000000017303 0ustar00vstsdocker/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000-2017 Expat development team Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef XmlTok_INCLUDED #define XmlTok_INCLUDED 1 #ifdef __cplusplus extern "C" { #endif /* The following token may be returned by XmlContentTok */ #define XML_TOK_TRAILING_RSQB \ -5 /* ] or ]] at the end of the scan; might be \ start of illegal ]]> sequence */ /* The following tokens may be returned by both XmlPrologTok and XmlContentTok. */ #define XML_TOK_NONE -4 /* The string to be scanned is empty */ #define XML_TOK_TRAILING_CR \ -3 /* A CR at the end of the scan; \ might be part of CRLF sequence */ #define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */ #define XML_TOK_PARTIAL -1 /* only part of a token */ #define XML_TOK_INVALID 0 /* The following tokens are returned by XmlContentTok; some are also returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok. */ #define XML_TOK_START_TAG_WITH_ATTS 1 #define XML_TOK_START_TAG_NO_ATTS 2 #define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag */ #define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4 #define XML_TOK_END_TAG 5 #define XML_TOK_DATA_CHARS 6 #define XML_TOK_DATA_NEWLINE 7 #define XML_TOK_CDATA_SECT_OPEN 8 #define XML_TOK_ENTITY_REF 9 #define XML_TOK_CHAR_REF 10 /* numeric character reference */ /* The following tokens may be returned by both XmlPrologTok and XmlContentTok. */ #define XML_TOK_PI 11 /* processing instruction */ #define XML_TOK_XML_DECL 12 /* XML decl or text decl */ #define XML_TOK_COMMENT 13 #define XML_TOK_BOM 14 /* Byte order mark */ /* The following tokens are returned only by XmlPrologTok */ #define XML_TOK_PROLOG_S 15 #define XML_TOK_DECL_OPEN 16 /* */ #define XML_TOK_NAME 18 #define XML_TOK_NMTOKEN 19 #define XML_TOK_POUND_NAME 20 /* #name */ #define XML_TOK_OR 21 /* | */ #define XML_TOK_PERCENT 22 #define XML_TOK_OPEN_PAREN 23 #define XML_TOK_CLOSE_PAREN 24 #define XML_TOK_OPEN_BRACKET 25 #define XML_TOK_CLOSE_BRACKET 26 #define XML_TOK_LITERAL 27 #define XML_TOK_PARAM_ENTITY_REF 28 #define XML_TOK_INSTANCE_START 29 /* The following occur only in element type declarations */ #define XML_TOK_NAME_QUESTION 30 /* name? */ #define XML_TOK_NAME_ASTERISK 31 /* name* */ #define XML_TOK_NAME_PLUS 32 /* name+ */ #define XML_TOK_COND_SECT_OPEN 33 /* */ #define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */ #define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */ #define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */ #define XML_TOK_COMMA 38 /* The following token is returned only by XmlAttributeValueTok */ #define XML_TOK_ATTRIBUTE_VALUE_S 39 /* The following token is returned only by XmlCdataSectionTok */ #define XML_TOK_CDATA_SECT_CLOSE 40 /* With namespace processing this is returned by XmlPrologTok for a name with a colon. */ #define XML_TOK_PREFIXED_NAME 41 #ifdef XML_DTD # define XML_TOK_IGNORE_SECT 42 #endif /* XML_DTD */ #ifdef XML_DTD # define XML_N_STATES 4 #else /* not XML_DTD */ # define XML_N_STATES 3 #endif /* not XML_DTD */ #define XML_PROLOG_STATE 0 #define XML_CONTENT_STATE 1 #define XML_CDATA_SECTION_STATE 2 #ifdef XML_DTD # define XML_IGNORE_SECTION_STATE 3 #endif /* XML_DTD */ #define XML_N_LITERAL_TYPES 2 #define XML_ATTRIBUTE_VALUE_LITERAL 0 #define XML_ENTITY_VALUE_LITERAL 1 /* The size of the buffer passed to XmlUtf8Encode must be at least this. */ #define XML_UTF8_ENCODE_MAX 4 /* The size of the buffer passed to XmlUtf16Encode must be at least this. */ #define XML_UTF16_ENCODE_MAX 2 typedef struct position { /* first line and first column are 0 not 1 */ XML_Size lineNumber; XML_Size columnNumber; } POSITION; typedef struct { const char *name; const char *valuePtr; const char *valueEnd; char normalized; } ATTRIBUTE; struct encoding; typedef struct encoding ENCODING; typedef int(PTRCALL *SCANNER)(const ENCODING *, const char *, const char *, const char **); enum XML_Convert_Result { XML_CONVERT_COMPLETED = 0, XML_CONVERT_INPUT_INCOMPLETE = 1, XML_CONVERT_OUTPUT_EXHAUSTED = 2 /* and therefore potentially input remaining as well */ }; struct encoding { SCANNER scanners[XML_N_STATES]; SCANNER literalScanners[XML_N_LITERAL_TYPES]; int(PTRCALL *nameMatchesAscii)(const ENCODING *, const char *, const char *, const char *); int(PTRFASTCALL *nameLength)(const ENCODING *, const char *); const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *); int(PTRCALL *getAtts)(const ENCODING *enc, const char *ptr, int attsMax, ATTRIBUTE *atts); int(PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr); int(PTRCALL *predefinedEntityName)(const ENCODING *, const char *, const char *); void(PTRCALL *updatePosition)(const ENCODING *, const char *ptr, const char *end, POSITION *); int(PTRCALL *isPublicId)(const ENCODING *enc, const char *ptr, const char *end, const char **badPtr); enum XML_Convert_Result(PTRCALL *utf8Convert)(const ENCODING *enc, const char **fromP, const char *fromLim, char **toP, const char *toLim); enum XML_Convert_Result(PTRCALL *utf16Convert)(const ENCODING *enc, const char **fromP, const char *fromLim, unsigned short **toP, const unsigned short *toLim); int minBytesPerChar; char isUtf8; char isUtf16; }; /* Scan the string starting at ptr until the end of the next complete token, but do not scan past eptr. Return an integer giving the type of token. Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set. Return XML_TOK_PARTIAL when the string does not contain a complete token; nextTokPtr will not be set. Return XML_TOK_INVALID when the string does not start a valid token; nextTokPtr will be set to point to the character which made the token invalid. Otherwise the string starts with a valid token; nextTokPtr will be set to point to the character following the end of that token. Each data character counts as a single token, but adjacent data characters may be returned together. Similarly for characters in the prolog outside literals, comments and processing instructions. */ #define XmlTok(enc, state, ptr, end, nextTokPtr) \ (((enc)->scanners[state])(enc, ptr, end, nextTokPtr)) #define XmlPrologTok(enc, ptr, end, nextTokPtr) \ XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr) #define XmlContentTok(enc, ptr, end, nextTokPtr) \ XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr) #define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \ XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr) #ifdef XML_DTD # define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \ XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr) #endif /* XML_DTD */ /* This is used for performing a 2nd-level tokenization on the content of a literal that has already been returned by XmlTok. */ #define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \ (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr)) #define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \ XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr) #define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \ XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr) #define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \ (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2)) #define XmlNameLength(enc, ptr) (((enc)->nameLength)(enc, ptr)) #define XmlSkipS(enc, ptr) (((enc)->skipS)(enc, ptr)) #define XmlGetAttributes(enc, ptr, attsMax, atts) \ (((enc)->getAtts)(enc, ptr, attsMax, atts)) #define XmlCharRefNumber(enc, ptr) (((enc)->charRefNumber)(enc, ptr)) #define XmlPredefinedEntityName(enc, ptr, end) \ (((enc)->predefinedEntityName)(enc, ptr, end)) #define XmlUpdatePosition(enc, ptr, end, pos) \ (((enc)->updatePosition)(enc, ptr, end, pos)) #define XmlIsPublicId(enc, ptr, end, badPtr) \ (((enc)->isPublicId)(enc, ptr, end, badPtr)) #define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \ (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim)) #define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \ (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim)) typedef struct { ENCODING initEnc; const ENCODING **encPtr; } INIT_ENCODING; int XmlParseXmlDecl(int isGeneralTextEntity, const ENCODING *enc, const char *ptr, const char *end, const char **badPtr, const char **versionPtr, const char **versionEndPtr, const char **encodingNamePtr, const ENCODING **namedEncodingPtr, int *standalonePtr); int XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name); const ENCODING *XmlGetUtf8InternalEncoding(void); const ENCODING *XmlGetUtf16InternalEncoding(void); int FASTCALL XmlUtf8Encode(int charNumber, char *buf); int FASTCALL XmlUtf16Encode(int charNumber, unsigned short *buf); int XmlSizeOfUnknownEncoding(void); typedef int(XMLCALL *CONVERTER)(void *userData, const char *p); ENCODING *XmlInitUnknownEncoding(void *mem, int *table, CONVERTER convert, void *userData); int XmlParseXmlDeclNS(int isGeneralTextEntity, const ENCODING *enc, const char *ptr, const char *end, const char **badPtr, const char **versionPtr, const char **versionEndPtr, const char **encodingNamePtr, const ENCODING **namedEncodingPtr, int *standalonePtr); int XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name); const ENCODING *XmlGetUtf8InternalEncodingNS(void); const ENCODING *XmlGetUtf16InternalEncodingNS(void); ENCODING *XmlInitUnknownEncodingNS(void *mem, int *table, CONVERTER convert, void *userData); #ifdef __cplusplus } #endif #endif /* not XmlTok_INCLUDED */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/lib/xmltok_impl.c0000644000175100001710000014650400000000000020321 0ustar00vstsdocker/* This file is included! __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000-2017 Expat development team Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifdef XML_TOK_IMPL_C # ifndef IS_INVALID_CHAR # define IS_INVALID_CHAR(enc, ptr, n) (0) # endif # define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \ case BT_LEAD##n: \ if (end - ptr < n) \ return XML_TOK_PARTIAL_CHAR; \ if (IS_INVALID_CHAR(enc, ptr, n)) { \ *(nextTokPtr) = (ptr); \ return XML_TOK_INVALID; \ } \ ptr += n; \ break; # define INVALID_CASES(ptr, nextTokPtr) \ INVALID_LEAD_CASE(2, ptr, nextTokPtr) \ INVALID_LEAD_CASE(3, ptr, nextTokPtr) \ INVALID_LEAD_CASE(4, ptr, nextTokPtr) \ case BT_NONXML: \ case BT_MALFORM: \ case BT_TRAIL: \ *(nextTokPtr) = (ptr); \ return XML_TOK_INVALID; # define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \ case BT_LEAD##n: \ if (end - ptr < n) \ return XML_TOK_PARTIAL_CHAR; \ if (! IS_NAME_CHAR(enc, ptr, n)) { \ *nextTokPtr = ptr; \ return XML_TOK_INVALID; \ } \ ptr += n; \ break; # define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \ case BT_NONASCII: \ if (! IS_NAME_CHAR_MINBPC(enc, ptr)) { \ *nextTokPtr = ptr; \ return XML_TOK_INVALID; \ } \ /* fall through */ \ case BT_NMSTRT: \ case BT_HEX: \ case BT_DIGIT: \ case BT_NAME: \ case BT_MINUS: \ ptr += MINBPC(enc); \ break; \ CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \ CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \ CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr) # define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \ case BT_LEAD##n: \ if (end - ptr < n) \ return XML_TOK_PARTIAL_CHAR; \ if (! IS_NMSTRT_CHAR(enc, ptr, n)) { \ *nextTokPtr = ptr; \ return XML_TOK_INVALID; \ } \ ptr += n; \ break; # define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \ case BT_NONASCII: \ if (! IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \ *nextTokPtr = ptr; \ return XML_TOK_INVALID; \ } \ /* fall through */ \ case BT_NMSTRT: \ case BT_HEX: \ ptr += MINBPC(enc); \ break; \ CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \ CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \ CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr) # ifndef PREFIX # define PREFIX(ident) ident # endif # define HAS_CHARS(enc, ptr, end, count) (end - ptr >= count * MINBPC(enc)) # define HAS_CHAR(enc, ptr, end) HAS_CHARS(enc, ptr, end, 1) # define REQUIRE_CHARS(enc, ptr, end, count) \ { \ if (! HAS_CHARS(enc, ptr, end, count)) { \ return XML_TOK_PARTIAL; \ } \ } # define REQUIRE_CHAR(enc, ptr, end) REQUIRE_CHARS(enc, ptr, end, 1) /* ptr points to character following " */ switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) { case BT_S: case BT_CR: case BT_LF: case BT_PERCNT: *nextTokPtr = ptr; return XML_TOK_INVALID; } /* fall through */ case BT_S: case BT_CR: case BT_LF: *nextTokPtr = ptr; return XML_TOK_DECL_OPEN; case BT_NMSTRT: case BT_HEX: ptr += MINBPC(enc); break; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } } return XML_TOK_PARTIAL; } static int PTRCALL PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr, const char *end, int *tokPtr) { int upper = 0; UNUSED_P(enc); *tokPtr = XML_TOK_PI; if (end - ptr != MINBPC(enc) * 3) return 1; switch (BYTE_TO_ASCII(enc, ptr)) { case ASCII_x: break; case ASCII_X: upper = 1; break; default: return 1; } ptr += MINBPC(enc); switch (BYTE_TO_ASCII(enc, ptr)) { case ASCII_m: break; case ASCII_M: upper = 1; break; default: return 1; } ptr += MINBPC(enc); switch (BYTE_TO_ASCII(enc, ptr)) { case ASCII_l: break; case ASCII_L: upper = 1; break; default: return 1; } if (upper) return 0; *tokPtr = XML_TOK_XML_DECL; return 1; } /* ptr points to character following "= end) return XML_TOK_NONE; if (MINBPC(enc) > 1) { size_t n = end - ptr; if (n & (MINBPC(enc) - 1)) { n &= ~(MINBPC(enc) - 1); if (n == 0) return XML_TOK_PARTIAL; end = ptr + n; } } switch (BYTE_TYPE(enc, ptr)) { case BT_RSQB: ptr += MINBPC(enc); REQUIRE_CHAR(enc, ptr, end); if (! CHAR_MATCHES(enc, ptr, ASCII_RSQB)) break; ptr += MINBPC(enc); REQUIRE_CHAR(enc, ptr, end); if (! CHAR_MATCHES(enc, ptr, ASCII_GT)) { ptr -= MINBPC(enc); break; } *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_CDATA_SECT_CLOSE; case BT_CR: ptr += MINBPC(enc); REQUIRE_CHAR(enc, ptr, end); if (BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc); *nextTokPtr = ptr; return XML_TOK_DATA_NEWLINE; case BT_LF: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_DATA_NEWLINE; INVALID_CASES(ptr, nextTokPtr) default: ptr += MINBPC(enc); break; } while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { # define LEAD_CASE(n) \ case BT_LEAD##n: \ if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ *nextTokPtr = ptr; \ return XML_TOK_DATA_CHARS; \ } \ ptr += n; \ break; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) # undef LEAD_CASE case BT_NONXML: case BT_MALFORM: case BT_TRAIL: case BT_CR: case BT_LF: case BT_RSQB: *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; default: ptr += MINBPC(enc); break; } } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; } /* ptr points to character following "= end) return XML_TOK_NONE; if (MINBPC(enc) > 1) { size_t n = end - ptr; if (n & (MINBPC(enc) - 1)) { n &= ~(MINBPC(enc) - 1); if (n == 0) return XML_TOK_PARTIAL; end = ptr + n; } } switch (BYTE_TYPE(enc, ptr)) { case BT_LT: return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_AMP: return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_CR: ptr += MINBPC(enc); if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_CR; if (BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc); *nextTokPtr = ptr; return XML_TOK_DATA_NEWLINE; case BT_LF: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_DATA_NEWLINE; case BT_RSQB: ptr += MINBPC(enc); if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_RSQB; if (! CHAR_MATCHES(enc, ptr, ASCII_RSQB)) break; ptr += MINBPC(enc); if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_RSQB; if (! CHAR_MATCHES(enc, ptr, ASCII_GT)) { ptr -= MINBPC(enc); break; } *nextTokPtr = ptr; return XML_TOK_INVALID; INVALID_CASES(ptr, nextTokPtr) default: ptr += MINBPC(enc); break; } while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { # define LEAD_CASE(n) \ case BT_LEAD##n: \ if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ *nextTokPtr = ptr; \ return XML_TOK_DATA_CHARS; \ } \ ptr += n; \ break; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) # undef LEAD_CASE case BT_RSQB: if (HAS_CHARS(enc, ptr, end, 2)) { if (! CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) { ptr += MINBPC(enc); break; } if (HAS_CHARS(enc, ptr, end, 3)) { if (! CHAR_MATCHES(enc, ptr + 2 * MINBPC(enc), ASCII_GT)) { ptr += MINBPC(enc); break; } *nextTokPtr = ptr + 2 * MINBPC(enc); return XML_TOK_INVALID; } } /* fall through */ case BT_AMP: case BT_LT: case BT_NONXML: case BT_MALFORM: case BT_TRAIL: case BT_CR: case BT_LF: *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; default: ptr += MINBPC(enc); break; } } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; } /* ptr points to character following "%" */ static int PTRCALL PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_LF: case BT_CR: case BT_PERCNT: *nextTokPtr = ptr; return XML_TOK_PERCENT; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_SEMI: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_PARAM_ENTITY_REF; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } } return XML_TOK_PARTIAL; } static int PTRCALL PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; } while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_CR: case BT_LF: case BT_S: case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR: *nextTokPtr = ptr; return XML_TOK_POUND_NAME; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } } return -XML_TOK_POUND_NAME; } static int PTRCALL PREFIX(scanLit)(int open, const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { while (HAS_CHAR(enc, ptr, end)) { int t = BYTE_TYPE(enc, ptr); switch (t) { INVALID_CASES(ptr, nextTokPtr) case BT_QUOT: case BT_APOS: ptr += MINBPC(enc); if (t != open) break; if (! HAS_CHAR(enc, ptr, end)) return -XML_TOK_LITERAL; *nextTokPtr = ptr; switch (BYTE_TYPE(enc, ptr)) { case BT_S: case BT_CR: case BT_LF: case BT_GT: case BT_PERCNT: case BT_LSQB: return XML_TOK_LITERAL; default: return XML_TOK_INVALID; } default: ptr += MINBPC(enc); break; } } return XML_TOK_PARTIAL; } static int PTRCALL PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { int tok; if (ptr >= end) return XML_TOK_NONE; if (MINBPC(enc) > 1) { size_t n = end - ptr; if (n & (MINBPC(enc) - 1)) { n &= ~(MINBPC(enc) - 1); if (n == 0) return XML_TOK_PARTIAL; end = ptr + n; } } switch (BYTE_TYPE(enc, ptr)) { case BT_QUOT: return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_APOS: return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_LT: { ptr += MINBPC(enc); REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { case BT_EXCL: return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_QUEST: return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_NMSTRT: case BT_HEX: case BT_NONASCII: case BT_LEAD2: case BT_LEAD3: case BT_LEAD4: *nextTokPtr = ptr - MINBPC(enc); return XML_TOK_INSTANCE_START; } *nextTokPtr = ptr; return XML_TOK_INVALID; } case BT_CR: if (ptr + MINBPC(enc) == end) { *nextTokPtr = end; /* indicate that this might be part of a CR/LF pair */ return -XML_TOK_PROLOG_S; } /* fall through */ case BT_S: case BT_LF: for (;;) { ptr += MINBPC(enc); if (! HAS_CHAR(enc, ptr, end)) break; switch (BYTE_TYPE(enc, ptr)) { case BT_S: case BT_LF: break; case BT_CR: /* don't split CR/LF pair */ if (ptr + MINBPC(enc) != end) break; /* fall through */ default: *nextTokPtr = ptr; return XML_TOK_PROLOG_S; } } *nextTokPtr = ptr; return XML_TOK_PROLOG_S; case BT_PERCNT: return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_COMMA: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_COMMA; case BT_LSQB: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_OPEN_BRACKET; case BT_RSQB: ptr += MINBPC(enc); if (! HAS_CHAR(enc, ptr, end)) return -XML_TOK_CLOSE_BRACKET; if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { REQUIRE_CHARS(enc, ptr, end, 2); if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) { *nextTokPtr = ptr + 2 * MINBPC(enc); return XML_TOK_COND_SECT_CLOSE; } } *nextTokPtr = ptr; return XML_TOK_CLOSE_BRACKET; case BT_LPAR: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_OPEN_PAREN; case BT_RPAR: ptr += MINBPC(enc); if (! HAS_CHAR(enc, ptr, end)) return -XML_TOK_CLOSE_PAREN; switch (BYTE_TYPE(enc, ptr)) { case BT_AST: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_CLOSE_PAREN_ASTERISK; case BT_QUEST: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_CLOSE_PAREN_QUESTION; case BT_PLUS: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_CLOSE_PAREN_PLUS; case BT_CR: case BT_LF: case BT_S: case BT_GT: case BT_COMMA: case BT_VERBAR: case BT_RPAR: *nextTokPtr = ptr; return XML_TOK_CLOSE_PAREN; } *nextTokPtr = ptr; return XML_TOK_INVALID; case BT_VERBAR: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_OR; case BT_GT: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_DECL_CLOSE; case BT_NUM: return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr); # define LEAD_CASE(n) \ case BT_LEAD##n: \ if (end - ptr < n) \ return XML_TOK_PARTIAL_CHAR; \ if (IS_NMSTRT_CHAR(enc, ptr, n)) { \ ptr += n; \ tok = XML_TOK_NAME; \ break; \ } \ if (IS_NAME_CHAR(enc, ptr, n)) { \ ptr += n; \ tok = XML_TOK_NMTOKEN; \ break; \ } \ *nextTokPtr = ptr; \ return XML_TOK_INVALID; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) # undef LEAD_CASE case BT_NMSTRT: case BT_HEX: tok = XML_TOK_NAME; ptr += MINBPC(enc); break; case BT_DIGIT: case BT_NAME: case BT_MINUS: # ifdef XML_NS case BT_COLON: # endif tok = XML_TOK_NMTOKEN; ptr += MINBPC(enc); break; case BT_NONASCII: if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { ptr += MINBPC(enc); tok = XML_TOK_NAME; break; } if (IS_NAME_CHAR_MINBPC(enc, ptr)) { ptr += MINBPC(enc); tok = XML_TOK_NMTOKEN; break; } /* fall through */ default: *nextTokPtr = ptr; return XML_TOK_INVALID; } while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_GT: case BT_RPAR: case BT_COMMA: case BT_VERBAR: case BT_LSQB: case BT_PERCNT: case BT_S: case BT_CR: case BT_LF: *nextTokPtr = ptr; return tok; # ifdef XML_NS case BT_COLON: ptr += MINBPC(enc); switch (tok) { case XML_TOK_NAME: REQUIRE_CHAR(enc, ptr, end); tok = XML_TOK_PREFIXED_NAME; switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) default: tok = XML_TOK_NMTOKEN; break; } break; case XML_TOK_PREFIXED_NAME: tok = XML_TOK_NMTOKEN; break; } break; # endif case BT_PLUS: if (tok == XML_TOK_NMTOKEN) { *nextTokPtr = ptr; return XML_TOK_INVALID; } *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_NAME_PLUS; case BT_AST: if (tok == XML_TOK_NMTOKEN) { *nextTokPtr = ptr; return XML_TOK_INVALID; } *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_NAME_ASTERISK; case BT_QUEST: if (tok == XML_TOK_NMTOKEN) { *nextTokPtr = ptr; return XML_TOK_INVALID; } *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_NAME_QUESTION; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } } return -tok; } static int PTRCALL PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { const char *start; if (ptr >= end) return XML_TOK_NONE; else if (! HAS_CHAR(enc, ptr, end)) { /* This line cannot be executed. The incoming data has already * been tokenized once, so incomplete characters like this have * already been eliminated from the input. Retaining the paranoia * check is still valuable, however. */ return XML_TOK_PARTIAL; /* LCOV_EXCL_LINE */ } start = ptr; while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { # define LEAD_CASE(n) \ case BT_LEAD##n: \ ptr += n; \ break; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) # undef LEAD_CASE case BT_AMP: if (ptr == start) return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_LT: /* this is for inside entity references */ *nextTokPtr = ptr; return XML_TOK_INVALID; case BT_LF: if (ptr == start) { *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_DATA_NEWLINE; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_CR: if (ptr == start) { ptr += MINBPC(enc); if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_CR; if (BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc); *nextTokPtr = ptr; return XML_TOK_DATA_NEWLINE; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_S: if (ptr == start) { *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_ATTRIBUTE_VALUE_S; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; default: ptr += MINBPC(enc); break; } } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; } static int PTRCALL PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { const char *start; if (ptr >= end) return XML_TOK_NONE; else if (! HAS_CHAR(enc, ptr, end)) { /* This line cannot be executed. The incoming data has already * been tokenized once, so incomplete characters like this have * already been eliminated from the input. Retaining the paranoia * check is still valuable, however. */ return XML_TOK_PARTIAL; /* LCOV_EXCL_LINE */ } start = ptr; while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { # define LEAD_CASE(n) \ case BT_LEAD##n: \ ptr += n; \ break; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) # undef LEAD_CASE case BT_AMP: if (ptr == start) return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_PERCNT: if (ptr == start) { int tok = PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr); return (tok == XML_TOK_PERCENT) ? XML_TOK_INVALID : tok; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_LF: if (ptr == start) { *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_DATA_NEWLINE; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_CR: if (ptr == start) { ptr += MINBPC(enc); if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_CR; if (BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc); *nextTokPtr = ptr; return XML_TOK_DATA_NEWLINE; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; default: ptr += MINBPC(enc); break; } } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; } # ifdef XML_DTD static int PTRCALL PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { int level = 0; if (MINBPC(enc) > 1) { size_t n = end - ptr; if (n & (MINBPC(enc) - 1)) { n &= ~(MINBPC(enc) - 1); end = ptr + n; } } while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { INVALID_CASES(ptr, nextTokPtr) case BT_LT: ptr += MINBPC(enc); REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) { ptr += MINBPC(enc); REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) { ++level; ptr += MINBPC(enc); } } break; case BT_RSQB: ptr += MINBPC(enc); REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { ptr += MINBPC(enc); REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { ptr += MINBPC(enc); if (level == 0) { *nextTokPtr = ptr; return XML_TOK_IGNORE_SECT; } --level; } } break; default: ptr += MINBPC(enc); break; } } return XML_TOK_PARTIAL; } # endif /* XML_DTD */ static int PTRCALL PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, const char **badPtr) { ptr += MINBPC(enc); end -= MINBPC(enc); for (; HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { case BT_DIGIT: case BT_HEX: case BT_MINUS: case BT_APOS: case BT_LPAR: case BT_RPAR: case BT_PLUS: case BT_COMMA: case BT_SOL: case BT_EQUALS: case BT_QUEST: case BT_CR: case BT_LF: case BT_SEMI: case BT_EXCL: case BT_AST: case BT_PERCNT: case BT_NUM: # ifdef XML_NS case BT_COLON: # endif break; case BT_S: if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) { *badPtr = ptr; return 0; } break; case BT_NAME: case BT_NMSTRT: if (! (BYTE_TO_ASCII(enc, ptr) & ~0x7f)) break; /* fall through */ default: switch (BYTE_TO_ASCII(enc, ptr)) { case 0x24: /* $ */ case 0x40: /* @ */ break; default: *badPtr = ptr; return 0; } break; } } return 1; } /* This must only be called for a well-formed start-tag or empty element tag. Returns the number of attributes. Pointers to the first attsMax attributes are stored in atts. */ static int PTRCALL PREFIX(getAtts)(const ENCODING *enc, const char *ptr, int attsMax, ATTRIBUTE *atts) { enum { other, inName, inValue } state = inName; int nAtts = 0; int open = 0; /* defined when state == inValue; initialization just to shut up compilers */ for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { # define START_NAME \ if (state == other) { \ if (nAtts < attsMax) { \ atts[nAtts].name = ptr; \ atts[nAtts].normalized = 1; \ } \ state = inName; \ } # define LEAD_CASE(n) \ case BT_LEAD##n: \ START_NAME ptr += (n - MINBPC(enc)); \ break; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) # undef LEAD_CASE case BT_NONASCII: case BT_NMSTRT: case BT_HEX: START_NAME break; # undef START_NAME case BT_QUOT: if (state != inValue) { if (nAtts < attsMax) atts[nAtts].valuePtr = ptr + MINBPC(enc); state = inValue; open = BT_QUOT; } else if (open == BT_QUOT) { state = other; if (nAtts < attsMax) atts[nAtts].valueEnd = ptr; nAtts++; } break; case BT_APOS: if (state != inValue) { if (nAtts < attsMax) atts[nAtts].valuePtr = ptr + MINBPC(enc); state = inValue; open = BT_APOS; } else if (open == BT_APOS) { state = other; if (nAtts < attsMax) atts[nAtts].valueEnd = ptr; nAtts++; } break; case BT_AMP: if (nAtts < attsMax) atts[nAtts].normalized = 0; break; case BT_S: if (state == inName) state = other; else if (state == inValue && nAtts < attsMax && atts[nAtts].normalized && (ptr == atts[nAtts].valuePtr || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open)) atts[nAtts].normalized = 0; break; case BT_CR: case BT_LF: /* This case ensures that the first attribute name is counted Apart from that we could just change state on the quote. */ if (state == inName) state = other; else if (state == inValue && nAtts < attsMax) atts[nAtts].normalized = 0; break; case BT_GT: case BT_SOL: if (state != inValue) return nAtts; break; default: break; } } /* not reached */ } static int PTRFASTCALL PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr) { int result = 0; /* skip &# */ UNUSED_P(enc); ptr += 2 * MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_x)) { for (ptr += MINBPC(enc); ! CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) { int c = BYTE_TO_ASCII(enc, ptr); switch (c) { case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4: case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9: result <<= 4; result |= (c - ASCII_0); break; case ASCII_A: case ASCII_B: case ASCII_C: case ASCII_D: case ASCII_E: case ASCII_F: result <<= 4; result += 10 + (c - ASCII_A); break; case ASCII_a: case ASCII_b: case ASCII_c: case ASCII_d: case ASCII_e: case ASCII_f: result <<= 4; result += 10 + (c - ASCII_a); break; } if (result >= 0x110000) return -1; } } else { for (; ! CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) { int c = BYTE_TO_ASCII(enc, ptr); result *= 10; result += (c - ASCII_0); if (result >= 0x110000) return -1; } } return checkCharRefNumber(result); } static int PTRCALL PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr, const char *end) { UNUSED_P(enc); switch ((end - ptr) / MINBPC(enc)) { case 2: if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) { switch (BYTE_TO_ASCII(enc, ptr)) { case ASCII_l: return ASCII_LT; case ASCII_g: return ASCII_GT; } } break; case 3: if (CHAR_MATCHES(enc, ptr, ASCII_a)) { ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_m)) { ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_p)) return ASCII_AMP; } } break; case 4: switch (BYTE_TO_ASCII(enc, ptr)) { case ASCII_q: ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_u)) { ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_o)) { ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_t)) return ASCII_QUOT; } } break; case ASCII_a: ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_p)) { ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_o)) { ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_s)) return ASCII_APOS; } } break; } } return 0; } static int PTRCALL PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1, const char *end1, const char *ptr2) { UNUSED_P(enc); for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) { if (end1 - ptr1 < MINBPC(enc)) { /* This line cannot be executed. The incoming data has already * been tokenized once, so incomplete characters like this have * already been eliminated from the input. Retaining the * paranoia check is still valuable, however. */ return 0; /* LCOV_EXCL_LINE */ } if (! CHAR_MATCHES(enc, ptr1, *ptr2)) return 0; } return ptr1 == end1; } static int PTRFASTCALL PREFIX(nameLength)(const ENCODING *enc, const char *ptr) { const char *start = ptr; for (;;) { switch (BYTE_TYPE(enc, ptr)) { # define LEAD_CASE(n) \ case BT_LEAD##n: \ ptr += n; \ break; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) # undef LEAD_CASE case BT_NONASCII: case BT_NMSTRT: # ifdef XML_NS case BT_COLON: # endif case BT_HEX: case BT_DIGIT: case BT_NAME: case BT_MINUS: ptr += MINBPC(enc); break; default: return (int)(ptr - start); } } } static const char *PTRFASTCALL PREFIX(skipS)(const ENCODING *enc, const char *ptr) { for (;;) { switch (BYTE_TYPE(enc, ptr)) { case BT_LF: case BT_CR: case BT_S: ptr += MINBPC(enc); break; default: return ptr; } } } static void PTRCALL PREFIX(updatePosition)(const ENCODING *enc, const char *ptr, const char *end, POSITION *pos) { while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { # define LEAD_CASE(n) \ case BT_LEAD##n: \ ptr += n; \ break; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) # undef LEAD_CASE case BT_LF: pos->columnNumber = (XML_Size)-1; pos->lineNumber++; ptr += MINBPC(enc); break; case BT_CR: pos->lineNumber++; ptr += MINBPC(enc); if (HAS_CHAR(enc, ptr, end) && BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc); pos->columnNumber = (XML_Size)-1; break; default: ptr += MINBPC(enc); break; } pos->columnNumber++; } } # undef DO_LEAD_CASE # undef MULTIBYTE_CASES # undef INVALID_CASES # undef CHECK_NAME_CASE # undef CHECK_NAME_CASES # undef CHECK_NMSTRT_CASE # undef CHECK_NMSTRT_CASES #endif /* XML_TOK_IMPL_C */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/lib/xmltok_impl.h0000644000175100001710000000641300000000000020320 0ustar00vstsdocker/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000-2017 Expat development team Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ enum { BT_NONXML, /* e.g. noncharacter-FFFF */ BT_MALFORM, /* illegal, with regard to encoding */ BT_LT, /* less than = "<" */ BT_AMP, /* ampersand = "&" */ BT_RSQB, /* right square bracket = "[" */ BT_LEAD2, /* lead byte of a 2-byte UTF-8 character */ BT_LEAD3, /* lead byte of a 3-byte UTF-8 character */ BT_LEAD4, /* lead byte of a 4-byte UTF-8 character */ BT_TRAIL, /* trailing unit, e.g. second 16-bit unit of a 4-byte char. */ BT_CR, /* carriage return = "\r" */ BT_LF, /* line feed = "\n" */ BT_GT, /* greater than = ">" */ BT_QUOT, /* quotation character = "\"" */ BT_APOS, /* aposthrophe = "'" */ BT_EQUALS, /* equal sign = "=" */ BT_QUEST, /* question mark = "?" */ BT_EXCL, /* exclamation mark = "!" */ BT_SOL, /* solidus, slash = "/" */ BT_SEMI, /* semicolon = ";" */ BT_NUM, /* number sign = "#" */ BT_LSQB, /* left square bracket = "[" */ BT_S, /* white space, e.g. "\t", " "[, "\r"] */ BT_NMSTRT, /* non-hex name start letter = "G".."Z" + "g".."z" + "_" */ BT_COLON, /* colon = ":" */ BT_HEX, /* hex letter = "A".."F" + "a".."f" */ BT_DIGIT, /* digit = "0".."9" */ BT_NAME, /* dot and middle dot = "." + chr(0xb7) */ BT_MINUS, /* minus = "-" */ BT_OTHER, /* known not to be a name or name start character */ BT_NONASCII, /* might be a name or name start character */ BT_PERCNT, /* percent sign = "%" */ BT_LPAR, /* left parenthesis = "(" */ BT_RPAR, /* right parenthesis = "(" */ BT_AST, /* asterisk = "*" */ BT_PLUS, /* plus sign = "+" */ BT_COMMA, /* comma = "," */ BT_VERBAR /* vertical bar = "|" */ }; #include ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/expat/lib/xmltok_ns.c0000644000175100001710000001036000000000000017766 0ustar00vstsdocker/* This file is included! __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000-2017 Expat development team Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifdef XML_TOK_NS_C const ENCODING * NS(XmlGetUtf8InternalEncoding)(void) { return &ns(internal_utf8_encoding).enc; } const ENCODING * NS(XmlGetUtf16InternalEncoding)(void) { # if BYTEORDER == 1234 return &ns(internal_little2_encoding).enc; # elif BYTEORDER == 4321 return &ns(internal_big2_encoding).enc; # else const short n = 1; return (*(const char *)&n ? &ns(internal_little2_encoding).enc : &ns(internal_big2_encoding).enc); # endif } static const ENCODING *const NS(encodings)[] = { &ns(latin1_encoding).enc, &ns(ascii_encoding).enc, &ns(utf8_encoding).enc, &ns(big2_encoding).enc, &ns(big2_encoding).enc, &ns(little2_encoding).enc, &ns(utf8_encoding).enc /* NO_ENC */ }; static int PTRCALL NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_PROLOG_STATE, ptr, end, nextTokPtr); } static int PTRCALL NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_CONTENT_STATE, ptr, end, nextTokPtr); } int NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr, const char *name) { int i = getEncodingIndex(name); if (i == UNKNOWN_ENC) return 0; SET_INIT_ENC_INDEX(p, i); p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog); p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent); p->initEnc.updatePosition = initUpdatePosition; p->encPtr = encPtr; *encPtr = &(p->initEnc); return 1; } static const ENCODING * NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end) { # define ENCODING_MAX 128 char buf[ENCODING_MAX]; char *p = buf; int i; XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1); if (ptr != end) return 0; *p = 0; if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2) return enc; i = getEncodingIndex(buf); if (i == UNKNOWN_ENC) return 0; return NS(encodings)[i]; } int NS(XmlParseXmlDecl)(int isGeneralTextEntity, const ENCODING *enc, const char *ptr, const char *end, const char **badPtr, const char **versionPtr, const char **versionEndPtr, const char **encodingName, const ENCODING **encoding, int *standalone) { return doParseXmlDecl(NS(findEncoding), isGeneralTextEntity, enc, ptr, end, badPtr, versionPtr, versionEndPtr, encodingName, encoding, standalone); } #endif /* XML_TOK_NS_C */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/trim_cfitsio.sh0000755000175100001710000000251600000000000016753 0ustar00vstsdocker#!/bin/sh set -euv # This script should be run every time cfitsio is updated. # This moves all the code needed for the actual library to lib # and deletes everything else (except License.txt and doc/changes.txt) # So, the standard update would be to execute, from this directory, # rm -rf cfitsio # tar xvf # (e.g., cfitsio3410.tar.gz) # ./trim_cfitsio.sh # This just gets CORE_SOURCES from Makefile.in, excluding anything beyond zlib lib_files=`make -f cfitsio/Makefile.in cfitsioLibSrcs | sed 's/zlib\/.*//'` # The include files cannot be directly inferred from Makefile.in inc_files='fitsio.h fitsio2.h longnam.h drvrsmem.h eval_defs.h eval_tab.h region.h group.h simplerng.h grparser.h' if [ ! -d cfitsio/lib ]; then mkdir cfitsio/lib fi for fil in $lib_files $inc_files; do if [ -f cfitsio/$fil ]; then mv cfitsio/$fil cfitsio/lib/ fi done rm -f cfitsio/README rm -f cfitsio/configure rm -f cfitsio/install-sh rm -f cfitsio/docs/*.tex rm -f cfitsio/docs/*.ps rm -f cfitsio/docs/*.pdf rm -f cfitsio/docs/*.doc rm -f cfitsio/docs/*.toc rm -rf cfitsio/[^L]*.* cat <cfitsio/README.txt Note: astropy only requires the CFITSIO library, and hence in this bundled version, we removed all other files except the required license (License.txt) and changelog (docs/changes.txt, which has the version number). EOF ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/trim_expat.sh0000755000175100001710000000175400000000000016437 0ustar00vstsdocker#!/bin/sh set -euv # This script should be run every time expat is updated. # So, the standard update would be to execute, from this directory: # # rm -rf expat # tar xvf # (e.g., expat-2.2.6.tar.bz2) # cd expat # ./buildconf.sh # ./configure --without-getrandom --without-sys-getrandom # cp expat_config.h ../../astropy/utils/xml/src/ # cd .. # ./trim_expat.sh # cd .. # git add . -u # # And if the trim script missed anything, try to remove the extra files # with a "git clean -xdf" command, do a local build, and run a full test suite # with "pytest --remote-data" to make sure we didn't accidentally deleted an # important file. rm -rf expat/{conftools,doc,examples,m4,test,win32,CMake*,configure*,Makefile*,lib/*vcxproj*,tests,*.cmake,aclocal.m4,run.sh.in,test-driver-wrapper.sh,expat.*,xmlwf} cat <expat/README.txt Note: astropy only requires the expat library, and hence in this bundled version, we removed all other files except the required license and changelog. EOF ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/trim_wcslib.sh0000755000175100001710000000042500000000000016573 0ustar00vstsdocker#!/bin/sh # This script should be run every time wcslib is updated. # This removes extra large files from wcslib that aren't needed. rm -rf wcslib/C/test rm -rf wcslib/doxygen rm -rf wcslib/Fortran rm -rf wcslib/html rm -rf wcslib/pgsbox rm -rf wcslib/utils rm wcslib/*.pdf ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2672603 astropy-5.0.2/cextern/wcslib/0000755000175100001710000000000000000000000015200 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2712607 astropy-5.0.2/cextern/wcslib/C/0000755000175100001710000000000000000000000015362 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/GNUmakefile0000644000175100001710000004333600000000000017445 0ustar00vstsdocker#----------------------------------------------------------------------------- # GNU makefile for building WCSLIB 7.7 and its test suite. # # Summary of the main targets # --------------------------- # build: Build the library. # # clean: Delete intermediate object files. # # cleaner: clean, and also delete the test executables. # # cleanest (distclean or realclean): cleaner, and also delete the object # library and the C source files generated by 'flex'. # # check (or test): Compile and run the test programs. By default they are # executed in batch mode, and non-graphical tests only report # "PASS" on success. Use # # make MODE=interactive check # # to run them interactively with full diagnostic output. To skip # graphical tests even if PGPLOT is available, use # # make CHECK=nopgplot check # # tests: Compile the test programs (but don't run them). # # Notes: # 1) If you need to make changes then preferably modify ../makedefs.in # instead and re-run configure. # # Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. # http://www.atnf.csiro.au/people/Mark.Calabretta # $Id: GNUmakefile,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ #----------------------------------------------------------------------------- # Get configure settings. SUBDIR := C include ../makedefs FLEXMODS := $(patsubst %.l,%.c,$(wildcard *.l)) MODULES := $(sort \ $(patsubst %.c,%.o, \ $(filter-out getwcstab.c,$(wildcard *.c)) $(FLEXMODS))) ifeq "$(WCSTRIG)" "MACRO" CPPFLAGS += -DWCSTRIG_MACRO MODULES := $(filter-out wcstrig.o, $(MODULES)) else ifeq "$(WCSTRIG)" "NATIVE" MODULES := $(filter-out wcstrig.o, $(MODULES)) endif endif LIBLOCK := lib.lock # For building the sharable library. PICLIB := libwcs-PIC.a CPPFLAGS += -I. -I.. vpath %.c test vpath %.h .. vpath %.in .. # For building and exercising the test suite # ------------------------------------------ # Test programs that don't require CFITSIO or PGPLOT... TEST_N := tlin tdis1 tdis2 tlog tprj1 tsph tsphdpa tspx ttab1 twcs twcssub \ tpih1 tbth1 tfitshdr tunits twcsfix twcscompare # ...and unofficial test programs. TEST_n := tdisiter tspcaips tspcspxe tspctrne twcs_locale # Test programs that require CFITSIO (they don't need PGPLOT). TEST_C := twcstab twcshdr tdis3 twcslint # Test programs that require PGPLOT but not PGSBOX. TEST_P := tspc tprj2 tcel1 tcel2 ttab2 ttab3 twcsmix # Test programs that require PGSBOX (and therefore PGPLOT). TEST_B := tpih2 # Test program for POSIX threads (code development only). TEST_T := tpthreads # Test programs that are compiled but not automatically exercised. TEST_X := tsphdpa twcshdr TESTS := $(TEST_N) # Do we have CFITSIO? DO_CFITSIO := 1 ifeq "$(CFITSIOINC)" "" DO_CFITSIO := 0 else ifeq "$(CFITSIOLIB)" "" DO_CFITSIO := 0 endif ifeq "$(DO_CFITSIO)" "1" # Yes, add test programs that use it. TESTS += $(TEST_C) CFITSIO_CFLAGS := $(filter-out -Wpadded,$(CFLAGS)) else # No, amend TEST_X. TEST_X := $(filter-out $(TEST_C),$(TEST_X)) endif # Do we have PGPLOT? DO_PGPLOT := 0 ifneq "$(CHECK)" "nopgplot" DO_PGPLOT := 1 ifeq "$(PGPLOTINC)" "" DO_PGPLOT := 0 else ifeq "$(PGPLOTLIB)" "" DO_PGPLOT := 0 endif ifeq "$(DO_PGPLOT)" "1" # Yes, add test programs that use it. TESTS += $(TEST_P) $(TEST_B) else # No, amend TEST_X. TEST_X := $(filter-out $(TEST_P) $(TEST_B),$(TEST_X)) endif endif # Remove tests that aren't automatically exercised. TESTS := $(filter-out $(TEST_X), $(TESTS)) PGSBOXLIB := ../pgsbox/libpgsbox-$(LIBVER).a ADDRE := 0x[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]* # Pattern rules #-------------- ifeq "$(FLEX)" "flex" %.c : %.l -@ echo '' -@ $(RM) $@ $(FLEX) $(FLFLAGS) -t $< | sed -e 's/^[ ]*#/#/' > $@ else %.c : %.l -@ echo '' -@ $(RM) $@ cp flexed/$@ . endif $(WCSLIB)(%.o) : %.c -@ echo '' $(CC) $(CPPFLAGS) $(CFLAGS) -c $< @ if [ ! -f $(LIBLOCK) ] ; then \ echo $(AR) r$(ARFLAGS) $(WCSLIB) $% ; \ $(AR) r$(ARFLAGS) $(WCSLIB) $% ; \ $(RM) $% ; \ fi $(PICLIB)(%.o) : $(WCSLIB)(%.o) -@ echo '' $(CC) $(CPPFLAGS) $(CFLAGS) $(SHRFLAGS) -c $(%:.o=.c) @ if [ ! -f $(LIBLOCK) ] ; then \ echo $(AR) r$(ARFLAGS) $(PICLIB) $% ; \ $(AR) r$(ARFLAGS) $(PICLIB) $% ; \ $(RM) $% ; \ fi # May need to create temporary symlinks to include file directories for # CFITSIO, etc. for the following two rules. %.i : %.c -@ echo '' -@ $(RM) $@ $(CPP) $(CPPFLAGS) $(CFLAGS) $< > $@ # Print out include file dependencies. %.d : %.c -@ echo '' -@ $(CPP) $(CPPFLAGS) $(CFLAGS) $< | \ sed -n -e 's|^# 1 "\([^/].*\.h\)".*|\1|p' | \ sed -e 's|.*/||' | \ sort -u %.fits : test/%.keyrec ../utils/tofits ../utils/tofits < $< > $@ # Use 'make VALGRIND=T run_%' to have VALGRIND defined (from flavours). # Use 'make VALGRIND=T check < /dev/null |& tee check_valgrind.log' to run # valgrind on the lot. run_% : % -@ echo '' -@ $(TIMER) @ if [ '$(MODE)' = interactive -o '$(VALGRIND)' ] ; then \ printf 'Press to run $<: ' ; \ read DUMMY ; \ fi ; \ if [ '$(VALGRIND)' ] ; then \ if [ '$<' = tunits ] ; then \ $(VALGRIND) ./$< < test/units_test ; \ else \ $(VALGRIND) ./$< ; \ fi ; \ else \ if [ '$(filter $<, $(TEST_N) $(TEST_C))' ] ; then \ if [ '$<' = tunits ] ; then \ if [ '$(MODE)' = interactive ] ; then \ ./$< < test/units_test 2>&1 | tee $<.out ; \ else \ ./$< < test/units_test > $<.out 2>&1 ; \ fi ; \ else \ if [ '$(MODE)' = interactive ] ; then \ ./$< < /dev/null 2>&1 | tee $<.out ; \ else \ ./$< < /dev/null > $<.out 2>&1 ; \ fi ; \ fi ; \ if grep 'FAIL:' $<.out > /dev/null ; then \ if [ '$(MODE)' != interactive ] ; then \ head -2 $<.out ; \ grep 'FAIL:' $<.out ; \ fi ; \ echo 'FAIL: C/$<' >> test_results ; \ elif grep 'PASS:' $<.out > /dev/null ; then \ if [ '$(MODE)' != interactive ] ; then \ head -2 $<.out ; \ grep 'PASS:' $<.out ; \ fi ; \ echo 'PASS: C/$<' >> test_results ; \ elif [ -f 'test/$<.out' ] ; then \ trap 'rm -f run_$<.tmp' 0 1 2 3 15 ; \ sed -e 's/$(ADDRE)/0x

/g' $<.out > \ run_$<.tmp ; \ mv -f run_$<.tmp $<.out ; \ if cmp -s $<.out test/$<.out ; then \ if [ '$(MODE)' != interactive ] ; then \ head -2 $<.out ; \ fi ; \ echo 'PASS: Output agrees with C/test/$<.out' ; \ echo 'PASS: C/$<' >> test_results ; \ else \ if [ '$(MODE)' != interactive ] ; then \ cat $<.out ; \ fi ; \ echo '' ; \ echo 'FAIL: Output disagrees with C/test/$<.out' ; \ echo 'FAIL: C/$<' >> test_results ; \ fi ; \ elif [ '$(MODE)' != interactive ] ; then \ cat $<.out ; \ echo 'FAIL: C/$<' >> test_results ; \ fi ; \ elif [ '$(MODE)' = interactive ] ; then \ ./$< ; \ else \ if [ '$<' = tcel2 ] ; then \ echo N | ./$< ; \ else \ ./$< < /dev/null 2>&1 ; \ fi ; \ fi ; \ fi -@ echo '' # Static and static pattern rules #-------------------------------- .PHONY : build check clean cleaner cleanest distclean install lib realclean \ run_% test tests uninstall build : lib lib : $(FLEXMODS) -@ echo '' -@ echo 'Building WCSLIB C library...' @ $(MAKE) --no-print-directory $(WCSLIB) $(WCSLIB) : $(LIBLOCK) $(MODULES:%=$(WCSLIB)(%)) -@ echo '' @ set *.o ; \ if [ "$$1" != "*.o" ] ; then \ echo $(AR) r$(ARFLAGS) $@ *.o ; \ $(AR) r$(ARFLAGS) $@ *.o ; \ echo $(RANLIB) $@ ; \ $(RANLIB) $@ ; \ $(RM) *.o ; \ fi -@ $(RM) $< @ if [ "$(SHRLIB)" != "" ] ; then \ $(MAKE) --no-print-directory $(SHRLIB) ; \ fi $(SHRLIB) : $(PICLIB) -@ echo '' -@ $(RM) -r tmp mkdir tmp && \ cd tmp && \ trap 'cd .. ; $(RM) -r tmp' 0 1 2 3 15 ; \ $(AR) x ../$(PICLIB) && \ $(SHRLD) -o $@ *.o $(LDFLAGS) $(LIBS) && \ mv $@ .. $(PICLIB) : $(LIBLOCK) $(MODULES:%=$(PICLIB)(%)) -@ echo '' @ set *.o ; \ if [ "$$1" != "*.o" ] ; then \ echo $(AR) r$(ARFLAGS) $@ *.o ; \ $(AR) r$(ARFLAGS) $@ *.o ; \ $(RM) *.o ; \ fi -@ $(RM) $< $(LIBLOCK) : FORCE @ $(RM) *.o @ touch $@ install : build - if [ ! -d "$(LIBDIR)" ] ; then \ $(INSTALL) -d -m 775 $(LIBDIR) ; \ fi if [ "$(ARFLAGS)" = U ] ; then \ $(RM) -r tmp ; \ mkdir tmp && \ cd tmp && \ trap 'cd .. ; $(RM) -r tmp' 0 1 2 3 15 ; \ $(AR) x ../$(WCSLIB) && \ $(AR) rD $(WCSLIB) *.o && \ $(INSTALL) -m 644 $(WCSLIB) $(LIBDIR) ; \ cd .. ; \ $(RM) -r tmp ; \ else \ $(INSTALL) -m 644 $(WCSLIB) $(LIBDIR) ; \ fi $(RANLIB) $(LIBDIR)/$(WCSLIB) - if [ -h "$(LIBDIR)/libwcs.a" ] ; then \ $(RM) $(LIBDIR)/libwcs.a ; \ fi $(LN_S) $(WCSLIB) $(LIBDIR)/libwcs.a if [ "$(SHRLIB)" != "" ] ; then \ $(INSTALL) -m 755 $(SHRLIB) $(LIBDIR) ; \ if [ -h "$(LIBDIR)/$(SONAME)" ] ; then \ $(RM) $(LIBDIR)/$(SONAME) ; \ fi ; \ $(LN_S) $(SHRLIB) $(LIBDIR)/$(SONAME) ; \ if [ "$(SHRLN)" != "" ] ; then \ if [ -h "$(LIBDIR)/$(SHRLN)" ] ; then \ $(RM) $(LIBDIR)/$(SHRLN) ; \ fi ; \ $(LN_S) $(SONAME) $(LIBDIR)/$(SHRLN) ; \ fi ; \ fi - if [ ! -d "$(INCDIR)" ] ; then \ $(INSTALL) -d -m 775 $(INCDIR) ; \ fi $(INSTALL) -m 444 *.h $(INCDIR) - $(RM) $(INCLINK) $(LN_S) $(notdir $(INCDIR)) $(INCLINK) uninstall : - cd $(LIBDIR) && $(RM) $(WCSLIB) $(SHRLN) $(SONAME) $(SHRLIB) - $(RM) $(INCDIR) - $(RM) $(INCLINK) clean : - $(RM) *.o $(LIBLOCK) *.i a.out t*.out core *.dSYM - $(RM) -r $(EXTRA_CLEAN) cleaner : clean - $(RM) .gdb_history - $(RM) $(TEST_N) $(TEST_n) $(TEST_T) $(TEST_X) - $(RM) $(TEST_P) tdis3 tpih2 twcshdr twcslint twcstab - $(RM) bth.fits fitshdr.fits pih.fits wcslint.fits wcspcx.fits - $(RM) wcstab.fits SIP.fits SIPTPV.fits TPV3.fits TPV5.fits - $(RM) TPV7.fits DSS.fits TNX.fits ZPX.fits - $(RM) t*_cfitsio test_results cleanest distclean realclean : cleaner - $(RM) ../wcsconfig.h ../wcsconfig_tests.h - $(RM) fitshdr.c wcsbth.c wcspih.c wcsulex.c wcsutrn.c - $(RM) $(PICLIB) libwcs-*.a libwcs.so.* libwcs.*.dylib check test : tests $(TESTS:%=run_%) tests : $(TESTS) $(TEST_X) # TEST_N and TEST_n programs (no special libraries required). $(TEST_N) $(TEST_n) : % : test/%.c $(WCSLIB) -@ echo '' $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< $(LDFLAGS) $(WCSLIB) $(LIBS) -@ $(RM) $@.o # TEST_N programs (optionally using CFITSIO). tpih1_cfitsio tbth1_cfitsio tfitshdr_cfitsio : %_cfitsio : test/%.c $(WCSLIB) -@ echo '' $(CC) -DDO_CFITSIO $(CPPFLAGS) $(CFITSIOINC) $(CFITSIO_CFLAGS) \ -o $@ $< $(LDFLAGS) $(CFITSIOLIB) $(WCSLIB) $(LIBS) -@ $(RM) $@.o # TEST_C programs (using CFITSIO). twcstab : test/twcstab.c $(WCSLIB) $(GETWCSTAB) -@ echo '' $(CC) $(CPPFLAGS) $(CFITSIOINC) $(CFITSIO_CFLAGS) -o $@ $< \ $(GETWCSTAB) $(LDFLAGS) $(CFITSIOLIB) $(WCSLIB) $(LIBS) -@ $(RM) $@.o $(GETWCSTAB) twcshdr : test/twcshdr.c $(WCSLIB) $(GETWCSTAB) -@ echo '' $(CC) $(CPPFLAGS) $(CFITSIOINC) $(CFITSIO_CFLAGS) -o $@ $< \ $(GETWCSTAB) $(LDFLAGS) $(CFITSIOLIB) $(WCSLIB) $(LIBS) -@ $(RM) $@.o $(GETWCSTAB) tdis3 : test/tdis3 -@ echo '' cp $< . -@ chmod a+x $@ twcslint : test/twcslint -@ echo '' cp $< . -@ chmod a+x $@ # TEST_P programs (using PGPLOT). $(TEST_P) : % : test/%.c $(WCSLIB) -@ echo '' $(CC) $(CPPFLAGS) $(PGPLOTINC) $(CFLAGS) -c -o $@.o $< $(LD) -o $@ $@.o $(LDFLAGS) $(PGPLOTLIB) $(WCSLIB) $(FLIBS) $(LIBS) -@ $(RM) $@.o # TEST_B programs (PGSBOX and PGPLOT). tpih2 : test/tpih2.c $(PGSBOXLIB) $(WCSLIB) -@ echo '' $(CC) $(CPPFLAGS) -I../pgsbox $(PGPLOTINC) $(CFLAGS) -c -o $@.o $< $(LD) -o $@ $@.o $(LDFLAGS) $(PGSBOXLIB) $(PGPLOTLIB) $(WCSLIB) \ $(FLIBS) $(LIBS) -@ $(RM) $@.o tpih2_cfitsio : test/tpih2.c $(PGSBOXLIB) $(WCSLIB) -@ echo '' $(CC) -DDO_CFITSIO $(CPPFLAGS) -I../pgsbox $(PGPLOTINC) \ $(CFITSIOINC) $(CFITSIO_CFLAGS) -c -o $@.o $< $(LD) -o $@ $@.o $(LDFLAGS) $(PGSBOXLIB) $(PGPLOTLIB) \ $(CFITSIOLIB) $(WCSLIB) $(FLIBS) $(LIBS) -@ $(RM) $@.o # TEST_T programs (using POSIX threads). tpthreads : test/tpthreads.c $(WCSLIB) -@ echo '' $(CC) $(CPPFLAGS) $(CFLAGS) -pthread -c -o $@.o $< $(LD) -o $@ $@.o $(LDFLAGS) -pthread $(WCSLIB) -lpthread $(LIBS) -@ $(RM) $@.o getwcstab.o : getwcstab.c getwcstab.h -@ echo '' $(CC) $(CPPFLAGS) $(CFITSIO_CFLAGS) $(CFITSIOINC) -c $< $(PGSBOXLIB) : -@ echo '' $(MAKE) -C ../pgsbox $(notdir $@) ../utils/tofits : ../utils/tofits.c $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $< GNUmakefile : ../makedefs ; ../makedefs ../wcsconfig.h ../wcsconfig_tests.h : makedefs.in wcsconfig.h.in \ wcsconfig_tests.h.in ../config.status -@ $(RM) ../wcsconfig.h ../wcsconfig_tests.h cd .. && ./config.status show :: -@ echo ' FLEXMODS := $(FLEXMODS)' -@ echo ' MODULES := $(MODULES)' -@ echo ' DO_CFITSIO := $(DO_CFITSIO)' -@ echo ' DO_PGPLOT := $(DO_PGPLOT)' -@ echo ' TESTS := $(TESTS)' -@ echo ' TEST_X := $(TEST_X)' # Dependencies (use the %.d pattern rule to list them) #----------------------------------------------------- $(WCSLIB)(cel.o) : cel.h prj.h sph.h wcsconfig.h wcserr.h wcsmath.h \ wcsprintf.h wcstrig.h $(WCSLIB)(dis.o) : dis.h wcserr.h wcsprintf.h wcsutil.h $(WCSLIB)(fitshdr.o) : fitshdr.h wcsconfig.h wcsutil.h $(WCSLIB)(lin.o) : dis.h lin.h wcserr.h wcsprintf.h $(WCSLIB)(log.o) : log.h $(WCSLIB)(prj.o) : prj.h wcsconfig.h wcserr.h wcsmath.h wcsprintf.h \ wcstrig.h wcsutil.h $(WCSLIB)(spc.o) : spc.h spx.h wcsconfig.h wcserr.h wcsmath.h \ wcsprintf.h wcstrig.h wcsutil.h $(WCSLIB)(sph.o) : sph.h wcsconfig.h wcstrig.h $(WCSLIB)(spx.o) : spx.h wcserr.h wcsmath.h $(WCSLIB)(tab.o) : tab.h wcserr.h wcsmath.h wcsprintf.h wcsutil.h $(WCSLIB)(wcs.o) : cel.h dis.h lin.h log.h prj.h spc.h sph.h spx.h \ tab.h wcs.h wcsconfig.h wcserr.h wcsmath.h \ wcsprintf.h wcstrig.h wcsunits.h wcsutil.h $(WCSLIB)(wcsbth.o) : cel.h lin.h prj.h spc.h spx.h wcs.h wcshdr.h \ wcsmath.h wcsprintf.h wcsutil.h $(WCSLIB)(wcserr.o) : wcserr.h wcsprintf.h $(WCSLIB)(wcsfix.o) : cel.h lin.h prj.h spc.h sph.h spx.h wcs.h wcserr.h \ wcsfix.h wcsmath.h wcsunits.h wcsutil.h $(WCSLIB)(wcshdr.o) : cel.h dis.h lin.h prj.h spc.h spx.h tab.h wcs.h \ wcserr.h wcshdr.h wcsmath.h wcsutil.h $(WCSLIB)(wcspih.o) : cel.h dis.h lin.h prj.h spc.h spx.h wcs.h wcshdr.h \ wcsmath.h wcsprintf.h wcsutil.h $(WCSLIB)(wcsprintf.o): wcsprintf.h $(WCSLIB)(wcstrig.o) : wcsconfig.h wcsmath.h wcstrig.h $(WCSLIB)(wcsulex.o) : wcserr.h wcsmath.h wcsunits.h wcsutil.h $(WCSLIB)(wcsunits.o) : wcserr.h wcsunits.h $(WCSLIB)(wcsutil.o) : wcsmath.h wcsutil.h $(WCSLIB)(wcsutrn.o) : wcserr.h wcsunits.h tbth1 tbth1_cfitsio : cel.h lin.h prj.h spc.h spx.h wcs.h wcsconfig.h \ wcsconfig_tests.h wcserr.h wcsfix.h wcshdr.h tcel1 : cel.h prj.h tcel2 : cel.h prj.h tfitshdr tfitshdr_cfitsio : cel.h fitshdr.h lin.h prj.h spc.h spx.h wcs.h \ wcsconfig.h wcsconfig_tests.h wcshdr.h tlin : lin.h tdis1 : cel.h dis.h lin.h prj.h spc.h spx.h wcs.h wcserr.h wcshdr.h \ wcsprintf.h tdis2 : cel.h lin.h prj.h spc.h spx.h wcs.h wcserr.h wcshdr.h wcsprintf.h tdisiter: cel.h dis.h lin.h prj.h spc.h spx.h wcs.h wcserr.h wcshdr.h \ wcsprintf.h tlog : log.h tpih1 tpih1_cfitsio : cel.h lin.h prj.h spc.h spx.h wcs.h wcsconfig.h \ wcsconfig_tests.h wcserr.h wcsfix.h wcshdr.h wcsprintf.h tpih2 tpih2_cfitsio : cel.h lin.h prj.h spc.h spx.h wcs.h wcsconfig.h \ wcsconfig_tests.h wcshdr.h tprj1 : prj.h wcsconfig.h wcstrig.h tprj2 : prj.h tspc : spc.h spx.h wcsconfig.h wcstrig.h tspcaips: spc.h spx.h tspctrne: spc.h spx.h wcserr.h tsph : sph.h wcsconfig.h wcstrig.h tsphdpa : sph.h tspx : spx.h ttab1 : tab.h ttab2 : tab.h ttab3 : prj.h tab.h tunits : wcserr.h wcsunits.h twcs : cel.h dis.h fitshdr.h lin.h log.h prj.h spc.h sph.h spx.h tab.h \ wcs.h wcsconfig.h wcsconfig_tests.h wcserr.h wcsfix.h wcshdr.h \ wcslib.h wcsmath.h wcsprintf.h wcstrig.h wcsunits.h wcsutil.h twcs_locale : cel.h lin.h prj.h spc.h spx.h wcs.h wcserr.h wcshdr.h \ wcsprintf.h twcsfix : cel.h lin.h prj.h spc.h spx.h wcs.h wcserr.h wcsfix.h \ wcsprintf.h wcsunits.h twcshdr : cel.h dis.h fitshdr.h getwcstab.h lin.h log.h prj.h spc.h sph.h \ spx.h tab.h wcs.h wcsconfig.h wcserr.h wcsfix.h wcshdr.h wcslib.h \ wcsmath.h wcsprintf.h wcstrig.h wcsunits.h wcsutil.h twcsmix : cel.h lin.h prj.h spc.h sph.h spx.h wcs.h twcssub : cel.h lin.h prj.h spc.h spx.h wcs.h wcserr.h twcstab : cel.h dis.h fitshdr.h getwcstab.h lin.h log.h prj.h spc.h sph.h \ spx.h tab.h wcs.h wcsconfig.h wcserr.h wcsfix.h wcshdr.h wcslib.h \ wcsmath.h wcsprintf.h wcstrig.h wcsunits.h wcsutil.h run_tdis1 : TPV3.fits TPV5.fits TPV7.fits run_tdis2 : SIP.fits run_tdis3 : DSS.fits SIPTPV.fits TNX.fits ZPX.fits run_tbth1 run_tbth1_cfitsio : bth.fits run_tfitshdr run_tfitshdr_cfitsio : fitshdr.fits run_tpih1 run_tpih1_cfitsio : pih.fits run_tpih2 run_tpih2_cfitsio : pih.fits run_twcslint : wcslint.fits run_twcs_locale : pih.fits ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/cel.c0000644000175100001710000003214300000000000016274 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: cel.c,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *===========================================================================*/ #include #include #include #include "wcserr.h" #include "wcsmath.h" #include "wcsprintf.h" #include "wcstrig.h" #include "sph.h" #include "cel.h" const int CELSET = 137; // Map status return value to message. const char *cel_errmsg[] = { "Success", "Null celprm pointer passed", "Invalid projection parameters", "Invalid coordinate transformation parameters", "Ill-conditioned coordinate transformation parameters", "One or more of the (x,y) coordinates were invalid", "One or more of the (lng,lat) coordinates were invalid"}; // Map error returns for lower-level routines. const int cel_prjerr[] = { CELERR_SUCCESS, // 0: PRJERR_SUCCESS CELERR_NULL_POINTER, // 1: PRJERR_NULL_POINTER CELERR_BAD_PARAM, // 2: PRJERR_BAD_PARAM CELERR_BAD_PIX, // 3: PRJERR_BAD_PIX CELERR_BAD_WORLD // 4: PRJERR_BAD_WORLD }; // Convenience macro for invoking wcserr_set(). #define CEL_ERRMSG(status) WCSERR_SET(status), cel_errmsg[status] //---------------------------------------------------------------------------- int celini(struct celprm *cel) { register int k; if (cel == 0x0) return CELERR_NULL_POINTER; cel->flag = 0; cel->offset = 0; cel->phi0 = UNDEFINED; cel->theta0 = UNDEFINED; cel->ref[0] = 0.0; cel->ref[1] = 0.0; cel->ref[2] = UNDEFINED; cel->ref[3] = +90.0; for (k = 0; k < 5; cel->euler[k++] = 0.0); cel->latpreq = -1; cel->err = 0x0; return cel_prjerr[prjini(&(cel->prj))]; } //---------------------------------------------------------------------------- int celfree(struct celprm *cel) { if (cel == 0x0) return CELERR_NULL_POINTER; wcserr_clear(&(cel->err)); return cel_prjerr[prjfree(&(cel->prj))]; } //---------------------------------------------------------------------------- int celsize(const struct celprm *cel, int sizes[2]) { if (cel == 0x0) { sizes[0] = sizes[1] = 0; return CELERR_SUCCESS; } // Base size, in bytes. sizes[0] = sizeof(struct celprm); // Total size of allocated memory, in bytes. sizes[1] = 0; int exsizes[2]; // celprm::prj. prjsize(&(cel->prj), exsizes); sizes[1] += exsizes[1]; // celprm::err. wcserr_size(cel->err, exsizes); sizes[1] += exsizes[0] + exsizes[1]; return CELERR_SUCCESS; } //---------------------------------------------------------------------------- int celprt(const struct celprm *cel) { int i; if (cel == 0x0) return CELERR_NULL_POINTER; wcsprintf(" flag: %d\n", cel->flag); wcsprintf(" offset: %d\n", cel->offset); if (undefined(cel->phi0)) { wcsprintf(" phi0: UNDEFINED\n"); } else { wcsprintf(" phi0: %9f\n", cel->phi0); } if (undefined(cel->theta0)) { wcsprintf(" theta0: UNDEFINED\n"); } else { wcsprintf(" theta0: %9f\n", cel->theta0); } wcsprintf(" ref:"); for (i = 0; i < 4; i++) { wcsprintf(" %#- 11.5g", cel->ref[i]); } wcsprintf("\n"); wcsprintf(" prj: (see below)\n"); wcsprintf(" euler:"); for (i = 0; i < 5; i++) { wcsprintf(" %#- 11.5g", cel->euler[i]); } wcsprintf("\n"); wcsprintf(" latpreq: %d", cel->latpreq); if (cel->latpreq == 0) { wcsprintf(" (not required)\n"); } else if (cel->latpreq == 1) { wcsprintf(" (disambiguation)\n"); } else if (cel->latpreq == 2) { wcsprintf(" (specification)\n"); } else { wcsprintf(" (UNDEFINED)\n"); } wcsprintf(" isolat: %d\n", cel->isolat); WCSPRINTF_PTR(" err: ", cel->err, "\n"); if (cel->err) { wcserr_prt(cel->err, " "); } wcsprintf("\n"); wcsprintf(" prj.*\n"); prjprt(&(cel->prj)); return 0; } //---------------------------------------------------------------------------- int celperr(const struct celprm *cel, const char *prefix) { if (cel == 0x0) return CELERR_NULL_POINTER; if (cel->err && wcserr_prt(cel->err, prefix) == 0) { wcserr_prt(cel->prj.err, prefix); } return 0; } //---------------------------------------------------------------------------- int celset(struct celprm *cel) { static const char *function = "celset"; int status; const double tol = 1.0e-10; double clat0, cphip, cthe0, lat0, lng0, phip, slat0, slz, sphip, sthe0; double latp, latp1, latp2, lngp; double u, v, x, y, z; struct prjprm *celprj; struct wcserr **err; if (cel == 0x0) return CELERR_NULL_POINTER; err = &(cel->err); // Initialize the projection driver routines. celprj = &(cel->prj); if (cel->offset) { celprj->phi0 = cel->phi0; celprj->theta0 = cel->theta0; } else { // Ensure that these are undefined - no fiducial offset. celprj->phi0 = UNDEFINED; celprj->theta0 = UNDEFINED; } if ((status = prjset(celprj))) { return wcserr_set(CEL_ERRMSG(cel_prjerr[status])); } // Defaults set by the projection routines. if (undefined(cel->phi0)) { cel->phi0 = celprj->phi0; } if (undefined(cel->theta0)) { cel->theta0 = celprj->theta0; } else if (fabs(cel->theta0) > 90.0) { if (fabs(cel->theta0) > 90.0 + tol) { return wcserr_set(WCSERR_SET(CELERR_BAD_COORD_TRANS), "Invalid coordinate transformation parameters: theta0 > 90"); } if (cel->theta0 > 90.0) { cel->theta0 = 90.0; } else { cel->theta0 = -90.0; } } lng0 = cel->ref[0]; lat0 = cel->ref[1]; phip = cel->ref[2]; latp = cel->ref[3]; // Set default for native longitude of the celestial pole? if (undefined(phip) || phip == 999.0) { phip = (lat0 < cel->theta0) ? 180.0 : 0.0; phip += cel->phi0; if (phip < -180.0) { phip += 360.0; } else if (phip > 180.0) { phip -= 360.0; } cel->ref[2] = phip; } // Compute celestial coordinates of the native pole. cel->latpreq = 0; if (cel->theta0 == 90.0) { // Fiducial point at the native pole. lngp = lng0; latp = lat0; } else { // Fiducial point away from the native pole. sincosd(lat0, &slat0, &clat0); sincosd(cel->theta0, &sthe0, &cthe0); if (phip == cel->phi0) { sphip = 0.0; cphip = 1.0; u = cel->theta0; v = 90.0 - lat0; } else { sincosd(phip - cel->phi0, &sphip, &cphip); x = cthe0*cphip; y = sthe0; z = sqrt(x*x + y*y); if (z == 0.0) { if (slat0 != 0.0) { return wcserr_set(WCSERR_SET(CELERR_BAD_COORD_TRANS), "Invalid coordinate description:\n" "lat0 == 0 is required for |phip - phi0| = 90 and theta0 == 0"); } // latp determined solely by LATPOLEa in this case. cel->latpreq = 2; if (latp > 90.0) { latp = 90.0; } else if (latp < -90.0) { latp = -90.0; } // Avert a spurious compiler warning. u = v = 0.0; } else { slz = slat0/z; if (fabs(slz) > 1.0) { if ((fabs(slz) - 1.0) < tol) { if (slz > 0.0) { slz = 1.0; } else { slz = -1.0; } } else { return wcserr_set(WCSERR_SET(CELERR_BAD_COORD_TRANS), "Invalid coordinate description:\n|lat0| <= %.3f is required " "for these values of phip, phi0, and theta0", asind(z)); } } u = atan2d(y,x); v = acosd(slz); } } if (cel->latpreq == 0) { latp1 = u + v; if (latp1 > 180.0) { latp1 -= 360.0; } else if (latp1 < -180.0) { latp1 += 360.0; } latp2 = u - v; if (latp2 > 180.0) { latp2 -= 360.0; } else if (latp2 < -180.0) { latp2 += 360.0; } if (fabs(latp1) < 90.0+tol && fabs(latp2) < 90.0+tol) { // There are two valid solutions for latp. cel->latpreq = 1; } if (fabs(latp-latp1) < fabs(latp-latp2)) { if (fabs(latp1) < 90.0+tol) { latp = latp1; } else { latp = latp2; } } else { if (fabs(latp2) < 90.0+tol) { latp = latp2; } else { latp = latp1; } } // Account for rounding error. if (fabs(latp) < 90.0+tol) { if (latp > 90.0) { latp = 90.0; } else if (latp < -90.0) { latp = -90.0; } } } z = cosd(latp)*clat0; if (fabs(z) < tol) { if (fabs(clat0) < tol) { // Celestial pole at the fiducial point. lngp = lng0; } else if (latp > 0.0) { // Celestial north pole at the native pole. lngp = lng0 + phip - cel->phi0 - 180.0; } else { // Celestial south pole at the native pole. lngp = lng0 - phip + cel->phi0; } } else { x = (sthe0 - sind(latp)*slat0)/z; y = sphip*cthe0/clat0; if (x == 0.0 && y == 0.0) { // Sanity check (shouldn't be possible). return wcserr_set(WCSERR_SET(CELERR_BAD_COORD_TRANS), "Invalid coordinate transformation parameters, internal error"); } lngp = lng0 - atan2d(y,x); } // Make celestial longitude of the native pole the same sign as at the // fiducial point. if (lng0 >= 0.0) { if (lngp < 0.0) { lngp += 360.0; } else if (lngp > 360.0) { lngp -= 360.0; } } else { if (lngp > 0.0) { lngp -= 360.0; } else if (lngp < -360.0) { lngp += 360.0; } } } // Reset LATPOLEa. cel->ref[3] = latp; // Set the Euler angles. cel->euler[0] = lngp; cel->euler[1] = 90.0 - latp; cel->euler[2] = phip; sincosd(cel->euler[1], &cel->euler[4], &cel->euler[3]); cel->isolat = (cel->euler[4] == 0.0); cel->flag = CELSET; // Check for ill-conditioned parameters. if (fabs(latp) > 90.0+tol) { return wcserr_set(WCSERR_SET(CELERR_ILL_COORD_TRANS), "Ill-conditioned coordinate transformation parameters\nNo valid " "solution for latp for these values of phip, phi0, and theta0"); } return 0; } //---------------------------------------------------------------------------- int celx2s( struct celprm *cel, int nx, int ny, int sxy, int sll, const double x[], const double y[], double phi[], double theta[], double lng[], double lat[], int stat[]) { static const char *function = "celx2s"; int istat, nphi, status = 0; struct prjprm *celprj; struct wcserr **err; // Initialize. if (cel == 0x0) return CELERR_NULL_POINTER; err = &(cel->err); if (cel->flag != CELSET) { if ((status = celset(cel))) return status; } // Apply spherical deprojection. celprj = &(cel->prj); if ((istat = celprj->prjx2s(celprj, nx, ny, sxy, 1, x, y, phi, theta, stat))) { if (istat) { status = wcserr_set(CEL_ERRMSG(cel_prjerr[istat])); if (status != CELERR_BAD_PIX) { return status; } } } nphi = (ny > 0) ? (nx*ny) : nx; // Compute celestial coordinates. sphx2s(cel->euler, nphi, 0, 1, sll, phi, theta, lng, lat); return status; } //---------------------------------------------------------------------------- int cels2x( struct celprm *cel, int nlng, int nlat, int sll, int sxy, const double lng[], const double lat[], double phi[], double theta[], double x[], double y[], int stat[]) { static const char *function = "cels2x"; int istat, nphi, ntheta, status = 0; struct prjprm *celprj; struct wcserr **err; // Initialize. if (cel == 0x0) return CELERR_NULL_POINTER; err = &(cel->err); if (cel->flag != CELSET) { if ((status = celset(cel))) return status; } // Compute native coordinates. sphs2x(cel->euler, nlng, nlat, sll, 1, lng, lat, phi, theta); if (cel->isolat) { // Constant celestial latitude -> constant native latitude. nphi = nlng; ntheta = nlat; } else { nphi = (nlat > 0) ? (nlng*nlat) : nlng; ntheta = 0; } // Apply the spherical projection. celprj = &(cel->prj); if ((istat = celprj->prjs2x(celprj, nphi, ntheta, 1, sxy, phi, theta, x, y, stat))) { if (istat) { status = wcserr_set(CEL_ERRMSG(cel_prjerr[istat])); if (status != CELERR_BAD_WORLD) { return status; } } } return status; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/cel.h0000644000175100001710000004600300000000000016301 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: cel.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the cel routines * --------------------------- * Routines in this suite implement the part of the FITS World Coordinate * System (WCS) standard that deals with celestial coordinates, as described in * = "Representations of world coordinates in FITS", = Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (WCS Paper I) = = "Representations of celestial coordinates in FITS", = Calabretta, M.R., & Greisen, E.W. 2002, A&A, 395, 1077 (WCS Paper II) * * These routines define methods to be used for computing celestial world * coordinates from intermediate world coordinates (a linear transformation * of image pixel coordinates), and vice versa. They are based on the celprm * struct which contains all information needed for the computations. This * struct contains some elements that must be set by the user, and others that * are maintained by these routines, somewhat like a C++ class but with no * encapsulation. * * Routine celini() is provided to initialize the celprm struct with default * values, celfree() reclaims any memory that may have been allocated to store * an error message, celsize() computes its total size including allocated * memory, and celprt() prints its contents. * * celperr() prints the error message(s), if any, stored in a celprm struct and * the prjprm struct that it contains. * * A setup routine, celset(), computes intermediate values in the celprm struct * from parameters in it that were supplied by the user. The struct always * needs to be set up by celset() but it need not be called explicitly - refer * to the explanation of celprm::flag. * * celx2s() and cels2x() implement the WCS celestial coordinate * transformations. In fact, they are high level driver routines for the lower * level spherical coordinate rotation and projection routines described in * sph.h and prj.h. * * * celini() - Default constructor for the celprm struct * ---------------------------------------------------- * celini() sets all members of a celprm struct to default values. It should * be used to initialize every celprm struct. * * PLEASE NOTE: If the celprm struct has already been initialized, then before * reinitializing, it celfree() should be used to free any memory that may have * been allocated to store an error message. A memory leak may otherwise * result. * * Returned: * cel struct celprm* * Celestial transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null celprm pointer passed. * * * celfree() - Destructor for the celprm struct * -------------------------------------------- * celfree() frees any memory that may have been allocated to store an error * message in the celprm struct. * * Given: * cel struct celprm* * Celestial transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null celprm pointer passed. * * * celsize() - Compute the size of a celprm struct * ----------------------------------------------- * celsize() computes the full size of a celprm struct, including allocated * memory. * * Given: * cel const struct celprm* * Celestial transformation parameters. * * If NULL, the base size of the struct and the allocated * size are both set to zero. * * Returned: * sizes int[2] The first element is the base size of the struct as * returned by sizeof(struct celprm). The second element * is the total allocated size, in bytes. This figure * includes memory allocated for the constituent struct, * celprm::err. * * It is not an error for the struct not to have been set * up via celset(). * * Function return value: * int Status return value: * 0: Success. * * * celprt() - Print routine for the celprm struct * ---------------------------------------------- * celprt() prints the contents of a celprm struct using wcsprintf(). Mainly * intended for diagnostic purposes. * * Given: * cel const struct celprm* * Celestial transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null celprm pointer passed. * * * celperr() - Print error messages from a celprm struct * ----------------------------------------------------- * celperr() prints the error message(s), if any, stored in a celprm struct and * the prjprm struct that it contains. If there are no errors then nothing is * printed. It uses wcserr_prt(), q.v. * * Given: * cel const struct celprm* * Coordinate transformation parameters. * * prefix const char * * If non-NULL, each output line will be prefixed with * this string. * * Function return value: * int Status return value: * 0: Success. * 1: Null celprm pointer passed. * * * celset() - Setup routine for the celprm struct * ---------------------------------------------- * celset() sets up a celprm struct according to information supplied within * it. * * Note that this routine need not be called directly; it will be invoked by * celx2s() and cels2x() if celprm::flag is anything other than a predefined * magic value. * * Given and returned: * cel struct celprm* * Celestial transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null celprm pointer passed. * 2: Invalid projection parameters. * 3: Invalid coordinate transformation parameters. * 4: Ill-conditioned coordinate transformation * parameters. * * For returns > 1, a detailed error message is set in * celprm::err if enabled, see wcserr_enable(). * * * celx2s() - Pixel-to-world celestial transformation * -------------------------------------------------- * celx2s() transforms (x,y) coordinates in the plane of projection to * celestial coordinates (lng,lat). * * Given and returned: * cel struct celprm* * Celestial transformation parameters. * * Given: * nx,ny int Vector lengths. * * sxy,sll int Vector strides. * * x,y const double[] * Projected coordinates in pseudo "degrees". * * Returned: * phi,theta double[] Longitude and latitude (phi,theta) in the native * coordinate system of the projection [deg]. * * lng,lat double[] Celestial longitude and latitude (lng,lat) of the * projected point [deg]. * * stat int[] Status return value for each vector element: * 0: Success. * 1: Invalid value of (x,y). * * Function return value: * int Status return value: * 0: Success. * 1: Null celprm pointer passed. * 2: Invalid projection parameters. * 3: Invalid coordinate transformation parameters. * 4: Ill-conditioned coordinate transformation * parameters. * 5: One or more of the (x,y) coordinates were * invalid, as indicated by the stat vector. * * For returns > 1, a detailed error message is set in * celprm::err if enabled, see wcserr_enable(). * * * cels2x() - World-to-pixel celestial transformation * -------------------------------------------------- * cels2x() transforms celestial coordinates (lng,lat) to (x,y) coordinates in * the plane of projection. * * Given and returned: * cel struct celprm* * Celestial transformation parameters. * * Given: * nlng,nlat int Vector lengths. * * sll,sxy int Vector strides. * * lng,lat const double[] * Celestial longitude and latitude (lng,lat) of the * projected point [deg]. * * Returned: * phi,theta double[] Longitude and latitude (phi,theta) in the native * coordinate system of the projection [deg]. * * x,y double[] Projected coordinates in pseudo "degrees". * * stat int[] Status return value for each vector element: * 0: Success. * 1: Invalid value of (lng,lat). * * Function return value: * int Status return value: * 0: Success. * 1: Null celprm pointer passed. * 2: Invalid projection parameters. * 3: Invalid coordinate transformation parameters. * 4: Ill-conditioned coordinate transformation * parameters. * 6: One or more of the (lng,lat) coordinates were * invalid, as indicated by the stat vector. * * For returns > 1, a detailed error message is set in * celprm::err if enabled, see wcserr_enable(). * * * celprm struct - Celestial transformation parameters * --------------------------------------------------- * The celprm struct contains information required to transform celestial * coordinates. It consists of certain members that must be set by the user * ("given") and others that are set by the WCSLIB routines ("returned"). Some * of the latter are supplied for informational purposes and others are for * internal use only. * * Returned celprm struct members must not be modified by the user. * * int flag * (Given and returned) This flag must be set to zero whenever any of the * following celprm struct members are set or changed: * * - celprm::offset, * - celprm::phi0, * - celprm::theta0, * - celprm::ref[4], * - celprm::prj: * - prjprm::code, * - prjprm::r0, * - prjprm::pv[], * - prjprm::phi0, * - prjprm::theta0. * * This signals the initialization routine, celset(), to recompute the * returned members of the celprm struct. celset() will reset flag to * indicate that this has been done. * * int offset * (Given) If true (non-zero), an offset will be applied to (x,y) to * force (x,y) = (0,0) at the fiducial point, (phi_0,theta_0). * Default is 0 (false). * * double phi0 * (Given) The native longitude, phi_0 [deg], and ... * * double theta0 * (Given) ... the native latitude, theta_0 [deg], of the fiducial point, * i.e. the point whose celestial coordinates are given in * celprm::ref[1:2]. If undefined (set to a magic value by prjini()) the * initialization routine, celset(), will set this to a projection-specific * default. * * double ref[4] * (Given) The first pair of values should be set to the celestial * longitude and latitude of the fiducial point [deg] - typically right * ascension and declination. These are given by the CRVALia keywords in * FITS. * * (Given and returned) The second pair of values are the native longitude, * phi_p [deg], and latitude, theta_p [deg], of the celestial pole (the * latter is the same as the celestial latitude of the native pole, * delta_p) and these are given by the FITS keywords LONPOLEa and LATPOLEa * (or by PVi_2a and PVi_3a attached to the longitude axis which take * precedence if defined). * * LONPOLEa defaults to phi_0 (see above) if the celestial latitude of the * fiducial point of the projection is greater than or equal to the native * latitude, otherwise phi_0 + 180 [deg]. (This is the condition for the * celestial latitude to increase in the same direction as the native * latitude at the fiducial point.) ref[2] may be set to UNDEFINED (from * wcsmath.h) or 999.0 to indicate that the correct default should be * substituted. * * theta_p, the native latitude of the celestial pole (or equally the * celestial latitude of the native pole, delta_p) is often determined * uniquely by CRVALia and LONPOLEa in which case LATPOLEa is ignored. * However, in some circumstances there are two valid solutions for theta_p * and LATPOLEa is used to choose between them. LATPOLEa is set in ref[3] * and the solution closest to this value is used to reset ref[3]. It is * therefore legitimate, for example, to set ref[3] to +90.0 to choose the * more northerly solution - the default if the LATPOLEa keyword is omitted * from the FITS header. For the special case where the fiducial point of * the projection is at native latitude zero, its celestial latitude is * zero, and LONPOLEa = +/- 90.0 then the celestial latitude of the native * pole is not determined by the first three reference values and LATPOLEa * specifies it completely. * * The returned value, celprm::latpreq, specifies how LATPOLEa was actually * used. * * struct prjprm prj * (Given and returned) Projection parameters described in the prologue to * prj.h. * * double euler[5] * (Returned) Euler angles and associated intermediaries derived from the * coordinate reference values. The first three values are the Z-, X-, and * Z'-Euler angles [deg], and the remaining two are the cosine and sine of * the X-Euler angle. * * int latpreq * (Returned) For informational purposes, this indicates how the LATPOLEa * keyword was used * - 0: Not required, theta_p (== delta_p) was determined uniquely by the * CRVALia and LONPOLEa keywords. * - 1: Required to select between two valid solutions of theta_p. * - 2: theta_p was specified solely by LATPOLEa. * * int isolat * (Returned) True if the spherical rotation preserves the magnitude of the * latitude, which occurs iff the axes of the native and celestial * coordinates are coincident. It signals an opportunity to cache * intermediate calculations common to all elements in a vector * computation. * * struct wcserr *err * (Returned) If enabled, when an error status is returned, this struct * contains detailed information about the error, see wcserr_enable(). * * void *padding * (An unused variable inserted for alignment purposes only.) * * Global variable: const char *cel_errmsg[] - Status return messages * ------------------------------------------------------------------ * Status messages to match the status value returned from each function. * *===========================================================================*/ #ifndef WCSLIB_CEL #define WCSLIB_CEL #include "prj.h" #ifdef __cplusplus extern "C" { #endif extern const char *cel_errmsg[]; enum cel_errmsg_enum { CELERR_SUCCESS = 0, // Success. CELERR_NULL_POINTER = 1, // Null celprm pointer passed. CELERR_BAD_PARAM = 2, // Invalid projection parameters. CELERR_BAD_COORD_TRANS = 3, // Invalid coordinate transformation // parameters. CELERR_ILL_COORD_TRANS = 4, // Ill-conditioned coordinated transformation // parameters. CELERR_BAD_PIX = 5, // One or more of the (x,y) coordinates were // invalid. CELERR_BAD_WORLD = 6 // One or more of the (lng,lat) coordinates // were invalid. }; struct celprm { // Initialization flag (see the prologue above). //-------------------------------------------------------------------------- int flag; // Set to zero to force initialization. // Parameters to be provided (see the prologue above). //-------------------------------------------------------------------------- int offset; // Force (x,y) = (0,0) at (phi_0,theta_0). double phi0, theta0; // Native coordinates of fiducial point. double ref[4]; // Celestial coordinates of fiducial // point and native coordinates of // celestial pole. struct prjprm prj; // Projection parameters (see prj.h). // Information derived from the parameters supplied. //-------------------------------------------------------------------------- double euler[5]; // Euler angles and functions thereof. int latpreq; // LATPOLEa requirement. int isolat; // True if |latitude| is preserved. // Error handling //-------------------------------------------------------------------------- struct wcserr *err; // Private //-------------------------------------------------------------------------- void *padding; // (Dummy inserted for alignment purposes.) }; // Size of the celprm struct in int units, used by the Fortran wrappers. #define CELLEN (sizeof(struct celprm)/sizeof(int)) int celini(struct celprm *cel); int celfree(struct celprm *cel); int celsize(const struct celprm *cel, int sizes[2]); int celprt(const struct celprm *cel); int celperr(const struct celprm *cel, const char *prefix); int celset(struct celprm *cel); int celx2s(struct celprm *cel, int nx, int ny, int sxy, int sll, const double x[], const double y[], double phi[], double theta[], double lng[], double lat[], int stat[]); int cels2x(struct celprm *cel, int nlng, int nlat, int sll, int sxy, const double lng[], const double lat[], double phi[], double theta[], double x[], double y[], int stat[]); // Deprecated. #define celini_errmsg cel_errmsg #define celprt_errmsg cel_errmsg #define celset_errmsg cel_errmsg #define celx2s_errmsg cel_errmsg #define cels2x_errmsg cel_errmsg #ifdef __cplusplus } #endif #endif // WCSLIB_CEL ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/dis.c0000644000175100001710000027044600000000000016322 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: dis.c,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *===========================================================================*/ #include #include #include #include #include "wcserr.h" #include "wcsprintf.h" #include "wcsutil.h" #include "dis.h" const int DISSET = 137; const int DIS_TPD = 1; const int DIS_POLYNOMIAL = 2; const int DIS_DOTPD = 1024; // Maximum number of DPja or DQia keywords. int NDPMAX = 256; // Map status return value to message. const char *dis_errmsg[] = { "Success", "Null disprm pointer passed", "Memory allocation failed", "Invalid parameter value", "Distort error", "De-distort error"}; // Convenience macro for invoking wcserr_set(). #define DIS_ERRMSG(status) WCSERR_SET(status), dis_errmsg[status] // Internal helper functions, not for general use. static int polyset(int j, struct disprm *dis); static int tpdset(int j, struct disprm *dis); static int pol2tpd(int j, struct disprm *dis); static int tpvset(int j, struct disprm *dis); static int sipset(int j, struct disprm *dis); static int dssset(int j, struct disprm *dis); static int watset(int j, struct disprm *dis); static int cheleg(int type, int m, int n, double coeffm[], double coeffn[]); static int dispoly(DISP2X_ARGS); static int tpd1(DISP2X_ARGS); static int tpd2(DISP2X_ARGS); static int tpd3(DISP2X_ARGS); static int tpd4(DISP2X_ARGS); static int tpd5(DISP2X_ARGS); static int tpd6(DISP2X_ARGS); static int tpd7(DISP2X_ARGS); static int tpd8(DISP2X_ARGS); static int tpd9(DISP2X_ARGS); // The first three iparm indices have meanings common to all distortion // functions. They are used by disp2x(), disx2p(), disprt(), and dishdo(). #define I_DTYPE 0 // Distortion type code. #define I_NIPARM 1 // Full (allocated) length of iparm[]. #define I_NDPARM 2 // No. of parameters in dparm[], excl. work space. //---------------------------------------------------------------------------- int disndp(int ndpmax) { if (ndpmax >= 0) NDPMAX = ndpmax; return NDPMAX; } //---------------------------------------------------------------------------- int dpfill( struct dpkey *dp, const char *keyword, const char *field, int j, int type, int i, double f) { if (keyword) { if (field) { if (j && 2 <= strlen(keyword)) { // Fill in the axis number from the value given. if (keyword[2] == '\0') { sprintf(dp->field, "%s%d.%s", keyword, j, field); } else { // Take care not to overwrite any alternate code. char axno[8]; sprintf(dp->field, "%s.%s", keyword, field); sprintf(axno, "%d", j); dp->field[2] = axno[0]; } } else { sprintf(dp->field, "%s.%s", keyword, field); } } else { strcpy(dp->field, keyword); } } else if (field) { strcpy(dp->field, field); } if (j) { dp->j = j; } else { // The field name must either be given or preset. char *cp; if ((cp = strpbrk(dp->field, "0123456789")) != 0x0) { sscanf(cp, "%d.", &(dp->j)); } } if ((dp->type = type)) { dp->value.f = f; } else { dp->value.i = i; } return 0; } //---------------------------------------------------------------------------- int dpkeyi(const struct dpkey *dp) { if (dp->type != 0) { return (int)dp->value.f; } return dp->value.i; } //---------------------------------------------------------------------------- double dpkeyd(const struct dpkey *dp) { if (dp->type == 0) { return (double)dp->value.i; } return dp->value.f; } //---------------------------------------------------------------------------- int disini(int alloc, int naxis, struct disprm *dis) { return disinit(alloc, naxis, dis, -1); } //---------------------------------------------------------------------------- int disinit(int alloc, int naxis, struct disprm *dis, int ndpmax) { static const char *function = "disinit"; // Check inputs. if (dis == 0x0) return DISERR_NULL_POINTER; if (ndpmax < 0) ndpmax = disndp(-1); // Initialize error message handling. if (dis->flag == -1) { dis->err = 0x0; } struct wcserr **err = &(dis->err); wcserr_clear(err); // Initialize pointers. if (dis->flag == -1 || dis->m_flag != DISSET) { if (dis->flag == -1) { dis->docorr = 0x0; dis->Nhat = 0x0; dis->axmap = 0x0; dis->offset = 0x0; dis->scale = 0x0; dis->iparm = 0x0; dis->dparm = 0x0; dis->disp2x = 0x0; dis->disx2p = 0x0; dis->tmpmem = 0x0; dis->i_naxis = 0; } // Initialize memory management. dis->m_flag = 0; dis->m_naxis = 0; dis->m_dtype = 0x0; dis->m_dp = 0x0; dis->m_maxdis = 0x0; } if (naxis < 0) { return wcserr_set(WCSERR_SET(DISERR_MEMORY), "naxis must not be negative (got %d)", naxis); } // Allocate memory for arrays if required. if (alloc || dis->dtype == 0x0 || (ndpmax && dis->dp == 0x0) || dis->maxdis == 0x0) { // Was sufficient allocated previously? if (dis->m_flag == DISSET && (dis->m_naxis < naxis || dis->ndpmax < ndpmax)) { // No, free it. disfree(dis); } if (alloc || dis->dtype == 0x0) { if (dis->m_dtype) { // In case the caller fiddled with it. dis->dtype = dis->m_dtype; } else { if ((dis->dtype = calloc(naxis, sizeof(char [72]))) == 0x0) { disfree(dis); return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } dis->m_flag = DISSET; dis->m_naxis = naxis; dis->m_dtype = dis->dtype; } } if (alloc || dis->dp == 0x0) { if (dis->m_dp) { // In case the caller fiddled with it. dis->dp = dis->m_dp; } else { if (ndpmax) { if ((dis->dp = calloc(ndpmax, sizeof(struct dpkey))) == 0x0) { disfree(dis); return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } } else { dis->dp = 0x0; } dis->ndpmax = ndpmax; dis->m_flag = DISSET; dis->m_naxis = naxis; dis->m_dp = dis->dp; } } if (alloc || dis->maxdis == 0x0) { if (dis->m_maxdis) { // In case the caller fiddled with it. dis->maxdis = dis->m_maxdis; } else { if ((dis->maxdis = calloc(naxis, sizeof(double))) == 0x0) { disfree(dis); return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } dis->m_flag = DISSET; dis->m_naxis = naxis; dis->m_maxdis = dis->maxdis; } } } // Set defaults. dis->flag = 0; dis->naxis = naxis; if (naxis) { memset(dis->dtype, 0, naxis*sizeof(char [72])); } dis->ndp = 0; if (ndpmax) { memset(dis->dp, 0, ndpmax*sizeof(struct dpkey)); } if (naxis) { memset(dis->maxdis, 0, naxis*sizeof(double)); } dis->totdis = 0.0; return 0; } //---------------------------------------------------------------------------- int discpy(int alloc, const struct disprm *dissrc, struct disprm *disdst) { static const char *function = "discpy"; if (dissrc == 0x0) return DISERR_NULL_POINTER; if (disdst == 0x0) return DISERR_NULL_POINTER; struct wcserr **err = &(disdst->err); int naxis = dissrc->naxis; if (naxis < 1) { return wcserr_set(WCSERR_SET(DISERR_MEMORY), "naxis must be positive (got %d)", naxis); } int status; if ((status = disinit(alloc, naxis, disdst, dissrc->ndpmax))) { return status; } memcpy(disdst->dtype, dissrc->dtype, naxis*sizeof(char [72])); disdst->ndp = dissrc->ndp; memcpy(disdst->dp, dissrc->dp, dissrc->ndpmax*sizeof(struct dpkey)); memcpy(disdst->maxdis, dissrc->maxdis, naxis*sizeof(double)); disdst->totdis = dissrc->totdis; return 0; } //---------------------------------------------------------------------------- int disfree(struct disprm *dis) { if (dis == 0x0) return DISERR_NULL_POINTER; if (dis->flag != -1) { // Optionally allocated by disinit() for given parameters. if (dis->m_flag == DISSET) { if (dis->dtype == dis->m_dtype) dis->dtype = 0x0; if (dis->dp == dis->m_dp) dis->dp = 0x0; if (dis->maxdis == dis->m_maxdis) dis->maxdis = 0x0; if (dis->m_dtype) free(dis->m_dtype); if (dis->m_dp) free(dis->m_dp); if (dis->m_maxdis) free(dis->m_maxdis); } // The remainder were allocated by disset(). if (dis->docorr) free(dis->docorr); if (dis->Nhat) free(dis->Nhat); // Recall that axmap, offset, and scale were allocated in bulk. if (dis->axmap && dis->axmap[0]) free(dis->axmap[0]); if (dis->offset && dis->offset[0]) free(dis->offset[0]); if (dis->scale && dis->scale[0]) free(dis->scale[0]); if (dis->axmap) free(dis->axmap); if (dis->offset) free(dis->offset); if (dis->scale) free(dis->scale); if (dis->iparm) { for (int j = 0; j < dis->i_naxis; j++) { if (dis->iparm[j]) free(dis->iparm[j]); } free(dis->iparm); } if (dis->dparm) { for (int j = 0; j < dis->i_naxis; j++) { if (dis->dparm[j]) free(dis->dparm[j]); } free(dis->dparm); } if (dis->disp2x) free(dis->disp2x); if (dis->disx2p) free(dis->disx2p); if (dis->tmpmem) free(dis->tmpmem); } dis->m_flag = 0; dis->m_naxis = 0; dis->m_dtype = 0x0; dis->m_dp = 0x0; dis->m_maxdis = 0x0; dis->docorr = 0x0; dis->Nhat = 0x0; dis->axmap = 0x0; dis->offset = 0x0; dis->scale = 0x0; dis->iparm = 0x0; dis->dparm = 0x0; dis->disp2x = 0x0; dis->disx2p = 0x0; dis->tmpmem = 0x0; wcserr_clear(&(dis->err)); dis->flag = 0; return 0; } //---------------------------------------------------------------------------- int dissize(const struct disprm *dis, int sizes[2]) { if (dis == 0x0) { sizes[0] = sizes[1] = 0; return DISERR_NULL_POINTER; } // Base size, in bytes. sizes[0] = sizeof(struct disprm); // Total size of allocated memory, in bytes. sizes[1] = 0; int naxis = dis->naxis; // disprm::dtype[]. sizes[1] += naxis * sizeof(char [72]); // disprm::dp[]. sizes[1] += dis->ndpmax * sizeof(struct dpkey); // disprm::maxdis[]. sizes[1] += naxis * sizeof(double); // dis::err[]. int exsizes[2]; wcserr_size(dis->err, exsizes); sizes[1] += exsizes[0] + exsizes[1]; // The remaining arrays are allocated by disset(). if (dis->flag != DISSET) { return DISERR_SUCCESS; } // dis::docorr[]. sizes[1] += naxis * sizeof(int *); // dis::Nhat[]. sizes[1] += naxis * sizeof(int *); // dis::axmap[][]. sizes[1] += naxis * sizeof(int *); sizes[1] += naxis*naxis * sizeof(int); // dis::offset[][]. sizes[1] += naxis * sizeof(double *); sizes[1] += naxis*naxis * sizeof(double); // dis::scale[][]. sizes[1] += naxis * sizeof(double *); sizes[1] += naxis*naxis * sizeof(double); // dis::iparm[][]. sizes[1] += naxis * sizeof(int *); for (int j = 0; j < naxis; j++) { if (dis->iparm[j]) { sizes[1] += dis->iparm[j][I_NIPARM] * sizeof(int); } } // dis::dparm[][]. sizes[1] += naxis * sizeof(double *); for (int j = 0; j < naxis; j++) { if (dis->dparm[j]) { sizes[1] += dis->dparm[j][I_NDPARM] * sizeof(double); } } // dis::disp2x[]. sizes[1] += naxis * sizeof(int (*)(DISP2X_ARGS)); // dis::disx2p[]. sizes[1] += naxis * sizeof(int (*)(DISX2P_ARGS)); // dis::tmpmem[]. sizes[1] += 5*naxis * sizeof(double); return DISERR_SUCCESS; } //---------------------------------------------------------------------------- int disprt(const struct disprm *dis) { if (dis == 0x0) return DISERR_NULL_POINTER; if (dis->flag != DISSET) { wcsprintf("The disprm struct is UNINITIALIZED.\n"); return 0; } int naxis = dis->naxis; wcsprintf(" flag: %d\n", dis->flag); // Parameters supplied. wcsprintf(" naxis: %d\n", naxis); WCSPRINTF_PTR(" dtype: ", dis->dtype, "\n"); for (int j = 0; j < naxis; j++) { wcsprintf(" \"%s\"\n", dis->dtype[j]); } wcsprintf(" ndp: %d\n", dis->ndp); wcsprintf(" ndpmax: %d\n", dis->ndpmax); WCSPRINTF_PTR(" dp: ", dis->dp, "\n"); for (int i = 0; i < dis->ndp; i++) { if (dis->dp[i].type) { wcsprintf(" %3d%3d %#- 11.5g %.32s\n", dis->dp[i].j, dis->dp[i].type, dis->dp[i].value.f, dis->dp[i].field); } else { wcsprintf(" %3d%3d %11d %.32s\n", dis->dp[i].j, dis->dp[i].type, dis->dp[i].value.i, dis->dp[i].field); } } WCSPRINTF_PTR(" maxdis: ", dis->maxdis, "\n"); wcsprintf(" "); for (int j = 0; j < naxis; j++) { wcsprintf(" %#- 11.5g", dis->maxdis[j]); } wcsprintf("\n"); wcsprintf(" totdis: %#- 11.5g\n", dis->totdis); // Derived values. WCSPRINTF_PTR(" docorr: ", dis->docorr, "\n"); wcsprintf(" "); for (int j = 0; j < naxis; j++) { wcsprintf("%6d", dis->docorr[j]); } wcsprintf("\n"); WCSPRINTF_PTR(" Nhat: ", dis->Nhat, "\n"); wcsprintf(" "); for (int j = 0; j < naxis; j++) { wcsprintf("%6d", dis->Nhat[j]); } wcsprintf("\n"); WCSPRINTF_PTR(" axmap: ", dis->axmap, "\n"); for (int j = 0; j < naxis; j++) { wcsprintf(" axmap[%d][]:", j); for (int jhat = 0; jhat < naxis; jhat++) { wcsprintf("%6d", dis->axmap[j][jhat]); } wcsprintf("\n"); } WCSPRINTF_PTR(" offset: ", dis->offset, "\n"); for (int j = 0; j < naxis; j++) { wcsprintf("offset[%d][]:", j); for (int jhat = 0; jhat < naxis; jhat++) { wcsprintf(" %#- 11.5g", dis->offset[j][jhat]); } wcsprintf("\n"); } WCSPRINTF_PTR(" scale: ", dis->scale, "\n"); for (int j = 0; j < naxis; j++) { wcsprintf(" scale[%d][]:", j); for (int jhat = 0; jhat < naxis; jhat++) { wcsprintf(" %#- 11.5g", dis->scale[j][jhat]); } wcsprintf("\n"); } WCSPRINTF_PTR(" iparm: ", dis->iparm, "\n"); for (int j = 0; j < naxis; j++) { wcsprintf(" iparm[%d] : ", j); WCSPRINTF_PTR("", dis->iparm[j], "\n"); if (dis->iparm[j]) { wcsprintf(" iparm[%d][]:", j); for (int k = 0; k < dis->iparm[j][I_NIPARM]; k++) { if (k && k%5 == 0) { wcsprintf("\n "); } wcsprintf(" %11d", dis->iparm[j][k]); } wcsprintf("\n"); } } WCSPRINTF_PTR(" dparm: ", dis->dparm, "\n"); for (int j = 0; j < naxis; j++) { wcsprintf(" dparm[%d] : ", j); WCSPRINTF_PTR("", dis->dparm[j], "\n"); if (dis->dparm[j]) { wcsprintf(" dparm[%d][]:", j); for (int k = 0; k < dis->iparm[j][I_NDPARM]; k++) { if (k && k%5 == 0) { wcsprintf("\n "); } wcsprintf(" %#- 11.5g", dis->dparm[j][k]); } wcsprintf("\n"); } } wcsprintf(" i_naxis: %d\n", dis->i_naxis); wcsprintf(" ndis: %d\n", dis->ndis); // Error handling. WCSPRINTF_PTR(" err: ", dis->err, "\n"); if (dis->err) { wcserr_prt(dis->err, " "); } // Work arrays. char hext[32]; WCSPRINTF_PTR(" disp2x: ", dis->disp2x, "\n"); for (int j = 0; j < naxis; j++) { wcsprintf(" disp2x[%d]: %s", j, wcsutil_fptr2str((void (*)(void))dis->disp2x[j], hext)); if (dis->disp2x[j] == dispoly) { wcsprintf(" (= dispoly)\n"); } else if (dis->disp2x[j] == tpd1) { wcsprintf(" (= tpd1)\n"); } else if (dis->disp2x[j] == tpd2) { wcsprintf(" (= tpd2)\n"); } else if (dis->disp2x[j] == tpd3) { wcsprintf(" (= tpd3)\n"); } else if (dis->disp2x[j] == tpd4) { wcsprintf(" (= tpd4)\n"); } else if (dis->disp2x[j] == tpd5) { wcsprintf(" (= tpd5)\n"); } else if (dis->disp2x[j] == tpd6) { wcsprintf(" (= tpd6)\n"); } else if (dis->disp2x[j] == tpd7) { wcsprintf(" (= tpd7)\n"); } else if (dis->disp2x[j] == tpd8) { wcsprintf(" (= tpd8)\n"); } else if (dis->disp2x[j] == tpd9) { wcsprintf(" (= tpd9)\n"); } else { wcsprintf("\n"); } } WCSPRINTF_PTR(" disx2p: ", dis->disx2p, "\n"); for (int j = 0; j < naxis; j++) { wcsprintf(" disx2p[%d]: %s\n", j, wcsutil_fptr2str((void (*)(void))dis->disx2p[j], hext)); } WCSPRINTF_PTR(" tmpmem: ", dis->tmpmem, "\n"); // Memory management. wcsprintf(" m_flag: %d\n", dis->m_flag); wcsprintf(" m_naxis: %d\n", dis->m_naxis); WCSPRINTF_PTR(" m_dtype: ", dis->m_dtype, ""); if (dis->m_dtype == dis->dtype) wcsprintf(" (= dtype)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_dp: ", dis->m_dp, ""); if (dis->m_dp == dis->dp) wcsprintf(" (= dp)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_maxdis: ", dis->m_maxdis, ""); if (dis->m_maxdis == dis->maxdis) wcsprintf(" (= maxdis)"); wcsprintf("\n"); return 0; } //---------------------------------------------------------------------------- int disperr(const struct disprm *dis, const char *prefix) { if (dis == 0x0) return DISERR_NULL_POINTER; if (dis->err) { wcserr_prt(dis->err, prefix); } return 0; } //---------------------------------------------------------------------------- int dishdo(struct disprm *dis) { static const char *function = "dishdo"; if (dis == 0x0) return DISERR_NULL_POINTER; struct wcserr **err = &(dis->err); int status = 0; for (int j = 0; j < dis->naxis; j++) { if (dis->iparm[j][I_DTYPE]) { if (dis->iparm[j][I_DTYPE] == DIS_TPD) { // Implemented as TPD... if (strcmp(dis->dtype[j], "TPD") != 0) { // ... but isn't TPD. dis->iparm[j][I_DTYPE] |= DIS_DOTPD; } } else { // Must be a Polynomial that can't be implemented as TPD. status = wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Translation of %s to TPD is not possible", dis->dtype[j]); } } } return status; } //---------------------------------------------------------------------------- int disset(struct disprm *dis) { static const char *function = "disset"; if (dis == 0x0) return DISERR_NULL_POINTER; struct wcserr **err = &(dis->err); int naxis = dis->naxis; // Do basic checks. if (dis->ndp < 0) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "disprm::ndp is negative (%d)", dis->ndp); } int ndis = 0; for (int j = 0; j < naxis; j++) { if (strlen(dis->dtype[j])) { ndis++; break; } } char *dpq; if (dis->ndp) { // Is it prior or sequent? if (dis->dp[0].field[1] == 'P') { dpq = "DPja"; } else if (dis->dp[0].field[1] == 'Q') { dpq = "DQia"; } else { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "disprm::dp[0].field (%s) is invalid", dis->dp[0].field); } } else { if (ndis) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "No DPja or DQia keywords, NAXES at least is required for each " "distortion"); } // A Clayton's distortion. Avert compiler warnings about possible use of // uninitialized variables. dpq = 0x0; } // Free memory allocated separately for each axis. for (int j = 0; j < dis->i_naxis; j++) { if (dis->iparm[j]) free(dis->iparm[j]); if (dis->dparm[j]) free(dis->dparm[j]); dis->iparm[j] = 0x0; dis->dparm[j] = 0x0; } // Allocate or reallocate memory, if necessary, for derived parameter and // work arrays sized according to the number of axes. if (dis->i_naxis < naxis) { if (dis->i_naxis) { free(dis->docorr); free(dis->Nhat); // Noting that axmap, offset, and scale are allocated in bulk. free(dis->axmap[0]); free(dis->axmap); free(dis->offset[0]); free(dis->offset); free(dis->scale[0]); free(dis->scale); free(dis->iparm); free(dis->dparm); free(dis->disp2x); free(dis->disx2p); free(dis->tmpmem); } if ((dis->docorr = calloc(naxis, sizeof(int *))) == 0x0) { disfree(dis); return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } if ((dis->Nhat = calloc(naxis, sizeof(int *))) == 0x0) { disfree(dis); return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } // Allocate axmap[][] in bulk and then carve it up. if ((dis->axmap = calloc(naxis, sizeof(int *))) == 0x0) { disfree(dis); return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } if ((dis->axmap[0] = calloc(naxis*naxis, sizeof(int))) == 0x0) { disfree(dis); return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } for (int j = 1; j < naxis; j++) { dis->axmap[j] = dis->axmap[j-1] + naxis; } // Allocate offset[][] in bulk and then carve it up. if ((dis->offset = calloc(naxis, sizeof(double *))) == 0x0) { disfree(dis); return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } if ((dis->offset[0] = calloc(naxis*naxis, sizeof(double))) == 0x0) { disfree(dis); return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } for (int j = 1; j < naxis; j++) { dis->offset[j] = dis->offset[j-1] + naxis; } // Allocate scale[][] in bulk and then carve it up. if ((dis->scale = calloc(naxis, sizeof(double *))) == 0x0) { disfree(dis); return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } if ((dis->scale[0] = calloc(naxis*naxis, sizeof(double))) == 0x0) { disfree(dis); return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } for (int j = 1; j < naxis; j++) { dis->scale[j] = dis->scale[j-1] + naxis; } if ((dis->iparm = calloc(naxis, sizeof(int *))) == 0x0) { disfree(dis); return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } if ((dis->dparm = calloc(naxis, sizeof(double *))) == 0x0) { disfree(dis); return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } if ((dis->disp2x = calloc(naxis, sizeof(int (*)(DISP2X_ARGS)))) == 0x0) { disfree(dis); return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } if ((dis->disx2p = calloc(naxis, sizeof(int (*)(DISX2P_ARGS)))) == 0x0) { disfree(dis); return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } if ((dis->tmpmem = calloc(5*naxis, sizeof(double))) == 0x0) { disfree(dis); return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } dis->i_naxis = naxis; } // Start with a clean slate. for (int j = 0; j < naxis; j++) { dis->docorr[j] = 1; } memset(dis->Nhat, 0, naxis*sizeof(int)); for (int jhat = 0; jhat < naxis*naxis; jhat++) { dis->axmap[0][jhat] = -1; } memset(dis->offset[0], 0, naxis*naxis*sizeof(double)); for (int jhat = 0; jhat < naxis*naxis; jhat++) { dis->scale[0][jhat] = 1.0; } // polyset() etc. must look after iparm[][] and dparm[][]. dis->i_naxis = naxis; dis->ndis = 0; memset(dis->disp2x, 0, naxis*sizeof(int (*)(DISP2X_ARGS))); memset(dis->disx2p, 0, naxis*sizeof(int (*)(DISX2P_ARGS))); memset(dis->tmpmem, 0, naxis*sizeof(double)); // Handle DPja or DQia keywords common to all distortions. struct dpkey *keyp = dis->dp; for (int idp = 0; idp < dis->ndp; idp++, keyp++) { // Check that they're all one kind or the other. if (keyp->field[1] != dpq[1]) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "disprm::dp appears to contain a mix of DPja and DQia keys"); } int j = keyp->j; if (j < 1 || naxis < j) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Invalid axis number (%d) in %s", j, keyp->field); } char *fp; if ((fp = strchr(keyp->field, '.')) == 0x0) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Invalid record field name: %s", j, keyp->field); } fp++; // Convert to 0-relative axis number. j--; if (strncmp(fp, "DOCORR", 7) == 0) { if (dpkeyi(keyp) == 0) { dis->docorr[j] = 0; } } else if (strncmp(fp, "NAXES", 6) == 0) { int Nhat = dpkeyi(keyp); if (Nhat < 0 || naxis < Nhat) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Invalid value of Nhat for %s distortion in %s: %d", dis->dtype[j], keyp->field, Nhat); } dis->Nhat[j] = Nhat; } else if (strncmp(fp, "AXIS.", 5) == 0) { int jhat; sscanf(fp+5, "%d", &jhat); if (jhat < 1 || naxis < jhat) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Invalid axis in axis map for %s distortion in %s: %d", dis->dtype[j], keyp->field, jhat); } // N.B. axis numbers in the map are 0-relative. dis->axmap[j][jhat-1] = dpkeyi(keyp) - 1; } else if (strncmp(fp, "OFFSET.", 7) == 0) { int jhat; sscanf(fp+7, "%d", &jhat); dis->offset[j][jhat-1] = dpkeyd(keyp); } else if (strncmp(fp, "SCALE.", 6) == 0) { int jhat; sscanf(fp+6, "%d", &jhat); dis->scale[j][jhat-1] = dpkeyd(keyp); } } // Set defaults and do sanity checks on axmap[][]. for (int j = 0; j < naxis; j++) { if (strlen(dis->dtype[j]) == 0) { // No distortion on this axis, check that there are no parameters. keyp = dis->dp; for (int idp = 0; idp < dis->ndp; idp++, keyp++) { if (keyp->j == j+1) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "No distortion type, yet %s keyvalues are present for axis %d", dpq, j+1); } } continue; } // N.B. NAXES (Nhat) has no default value. if (dis->Nhat[j] <= 0) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "%s.NAXES was not set (or bad) for %s distortion on axis %d", dpq, dis->dtype[j], j+1); } // Set defaults for axmap[][]. int Nhat = dis->Nhat[j]; for (int jhat = 0; jhat < Nhat; jhat++) { if (dis->axmap[j][jhat] == -1) { dis->axmap[j][jhat] = jhat; } } // Sanity check on the length of the axis map. Nhat = 0; for (int jhat = 0; jhat < naxis; jhat++) { if (dis->axmap[j][jhat] != -1) Nhat = jhat+1; } if (Nhat != dis->Nhat[j]) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Mismatch in length of axis map for %s distortion on axis %d", dis->dtype[j], j+1); } // Check uniqueness of entries in the axis map. for (int jhat = 0; jhat < Nhat; jhat++) { for (int k = 0; k < jhat; k++) { if (dis->axmap[j][jhat] == dis->axmap[j][k]) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Duplicated entry in axis map for %s distortion on axis %d", dis->dtype[j], j+1); } } } } // Identify the distortion functions. ndis = 0; for (int j = 0; j < naxis; j++) { if (strlen(dis->dtype[j]) == 0) { // No distortion on this axis. continue; } if (dis->Nhat[j] == 0) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Empty axis map for %s distortion on axis %d", dis->dtype[j], j+1); } // Invoke the specific setup functions for each distortion. int status; if (strcmp(dis->dtype[j], "TPD") == 0) { // Template Polynomial Distortion. if ((status = tpdset(j, dis))) { // (Preserve the error message set by tpdset().) return status; } } else if (strcmp(dis->dtype[j], "TPV") == 0) { // TPV "projection". if ((status = tpvset(j, dis))) { // (Preserve the error message set by tpvset().) return status; } } else if (strcmp(dis->dtype[j], "SIP") == 0) { // Simple Imaging Polynomial (SIP). if ((status = sipset(j, dis))) { // (Preserve the error message set by sipset().) return status; } } else if (strcmp(dis->dtype[j], "DSS") == 0) { // Digitized Sky Survey (DSS). if ((status = dssset(j, dis))) { // (Preserve the error message set by dssset().) return status; } } else if (strncmp(dis->dtype[j], "WAT", 3) == 0) { // WAT (TNX or ZPX "projections"). if ((status = watset(j, dis))) { // (Preserve the error message set by watset().) return status; } } else if (strcmp(dis->dtype[j], "Polynomial") == 0 || strcmp(dis->dtype[j], "Polynomial*") == 0) { // General polynomial distortion. if ((status = polyset(j, dis))) { // (Preserve the error message set by polyset().) return status; } } else { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Unrecognized/unimplemented distortion function: %s", dis->dtype[j]); } ndis++; } dis->ndis = ndis; dis->flag = DISSET; return 0; } //---------------------------------------------------------------------------- int disp2x( struct disprm *dis, const double rawcrd[], double discrd[]) { static const char *function = "disp2x"; // Initialize. if (dis == 0x0) return DISERR_NULL_POINTER; struct wcserr **err = &(dis->err); if (dis->flag != DISSET) { int status; if ((status = disset(dis))) return status; } int naxis = dis->naxis; // Invoke the distortion functions for each axis. double *tmpcrd = dis->tmpmem; for (int j = 0; j < naxis; j++) { if (dis->disp2x[j]) { double *offset = dis->offset[j]; double *scale = dis->scale[j]; int Nhat = dis->Nhat[j]; for (int jhat = 0; jhat < Nhat; jhat++) { int axisj = dis->axmap[j][jhat]; tmpcrd[jhat] = (rawcrd[axisj] - offset[jhat])*scale[jhat]; } double dtmp; if ((dis->disp2x[j])(0, dis->iparm[j], dis->dparm[j], Nhat, tmpcrd, &dtmp)) { return wcserr_set(DIS_ERRMSG(DISERR_DISTORT)); } if (dis->docorr[j]) { // Distortion function computes a correction to be applied. discrd[j] = rawcrd[j] + dtmp; } else { // Distortion function computes corrected coordinates directly. discrd[j] = dtmp; } } else { discrd[j] = rawcrd[j]; } } return 0; } //---------------------------------------------------------------------------- // This function is intended for debugging purposes only. // No documentation or prototype is provided in dis.h. int disitermax(int itermax) { static int ITERMAX = 30; if (itermax >= 0) { ITERMAX = itermax; } return ITERMAX; } //---------------------------------------------------------------------------- int disx2p( struct disprm *dis, const double discrd[], double rawcrd[]) { static const char *function = "disx2p"; const double TOL = 1.0e-13; int status; // Initialize. if (dis == 0x0) return DISERR_NULL_POINTER; struct wcserr **err = &(dis->err); int naxis = dis->naxis; // Carve up working memory, noting that disp2x() gets to it first. double *dcrd0 = dis->tmpmem + naxis; double *dcrd1 = dcrd0 + naxis; double *rcrd1 = dcrd1 + naxis; double *delta = rcrd1 + naxis; // Zeroth approximation. The assumption here and below is that the // distortion is small so that, to first order in the neighbourhood of // the solution, discrd[j] ~= a + b*rawcrd[j], i.e. independent of // rawcrd[i], where i != j. This is effectively equivalent to assuming // that the distortion functions are separable to first order. // Furthermore, a is assumed to be small, and b close to unity. memcpy(rawcrd, discrd, naxis*sizeof(double)); // If available, use disprm::disx2p to improve the zeroth approximation. for (int j = 0; j < naxis; j++) { if (dis->disx2p[j]) { double *offset = dis->offset[j]; double *scale = dis->scale[j]; double *tmpcrd = dis->tmpmem; int Nhat = dis->Nhat[j]; for (int jhat = 0; jhat < Nhat; jhat++) { int axisj = dis->axmap[j][jhat]; tmpcrd[jhat] = (discrd[axisj] - offset[jhat])*scale[jhat]; } double rtmp; if ((status = (dis->disx2p[j])(1, dis->iparm[j], dis->dparm[j], Nhat, tmpcrd, &rtmp))) { return wcserr_set(DIS_ERRMSG(DISERR_DEDISTORT)); } if (dis->docorr[j]) { // Inverse distortion function computes a correction to be applied. rawcrd[j] = discrd[j] + rtmp; } else { // Inverse distortion function computes corrected coordinates directly. rawcrd[j] = rtmp; } } } // Quick return debugging hook, assumes inverse functions were defined. int itermax; if ((itermax = disitermax(-1)) == 0) { return 0; } // Iteratively invert the (well-behaved!) distortion function. int convergence, iter; for (iter = 0; iter < itermax; iter++) { if ((status = disp2x(dis, rawcrd, dcrd0))) { return wcserr_set(DIS_ERRMSG(status)); } // Check for convergence. convergence = 1; for (int j = 0; j < naxis; j++) { delta[j] = discrd[j] - dcrd0[j]; double dd; if (fabs(discrd[j]) < 1.0) { dd = delta[j]; } else { // TOL may be below the precision achievable from floating point // subtraction, so switch to a fractional tolerance. dd = delta[j] / discrd[j]; } if (TOL < fabs(dd)) { // No convergence yet on this axis. convergence = 0; } } if (convergence) break; // Determine a suitable test point for computing the gradient. for (int j = 0; j < naxis; j++) { // Constrain the displacement. delta[j] /= 2.0; if (fabs(delta[j]) < 1.0e-6) { if (delta[j] < 0.0) { delta[j] = -1.0e-6; } else { delta[j] = 1.0e-6; } } else if (1.0 < fabs(delta[j])) { if (delta[j] < 0.0) { delta[j] = -1.0; } else { delta[j] = 1.0; } } } if (iter < itermax/2) { // With the assumption of small distortions (as above), the gradient // of discrd[j] should be dominated by the partial derivative with // respect to rawcrd[j], and we can neglect partials with respect // to rawcrd[i], where i != j. Thus only one test point is needed, // not one for each axis. for (int j = 0; j < naxis; j++) { rcrd1[j] = rawcrd[j] + delta[j]; } // Compute discrd[] at the test point. if ((status = disp2x(dis, rcrd1, dcrd1))) { return wcserr_set(DIS_ERRMSG(status)); } // Compute the next approximation. for (int j = 0; j < naxis; j++) { rawcrd[j] += (discrd[j] - dcrd0[j]) * (delta[j]/(dcrd1[j] - dcrd0[j])); } } else { // Convergence should not take more than seven or so iterations. As // it is slow, try computing the gradient in full. memcpy(rcrd1, rawcrd, naxis*sizeof(double)); for (int j = 0; j < naxis; j++) { rcrd1[j] += delta[j]; // Compute discrd[] at the test point. if ((status = disp2x(dis, rcrd1, dcrd1))) { return wcserr_set(DIS_ERRMSG(status)); } // Compute the next approximation. rawcrd[j] += (discrd[j] - dcrd0[j]) * (delta[j]/(dcrd1[j] - dcrd0[j])); rcrd1[j] -= delta[j]; } } } if (!convergence) { double residual = 0.0; for (int j = 0; j < naxis; j++) { double dd = discrd[j] - dcrd0[j] ; residual += dd*dd; } residual = sqrt(residual); return wcserr_set(WCSERR_SET(DISERR_DEDISTORT), "Convergence not achieved after %d iterations, residual %#7.2g", iter, residual); } return 0; } //---------------------------------------------------------------------------- int diswarp( struct disprm *dis, const double pixblc[], const double pixtrc[], const double pixsamp[], int *nsamp, double maxdis[], double *maxtot, double avgdis[], double *avgtot, double rmsdis[], double *rmstot) { static const char *function = "diswarp"; int status = 0; // Initialize. if (dis == 0x0) return DISERR_NULL_POINTER; struct wcserr **err = &(dis->err); int naxis = dis->naxis; if (nsamp) *nsamp = 0; for (int j = 0; j < naxis; j++) { if (maxdis) maxdis[j] = 0.0; if (avgdis) avgdis[j] = 0.0; if (rmsdis) rmsdis[j] = 0.0; } if (maxtot) *maxtot = 0.0; if (avgtot) *avgtot = 0.0; if (rmstot) *rmstot = 0.0; // Quick return if no distortions. if (dis->ndis == 0) return 0; // Carve up working memory, noting that disp2x() gets to it first. double *pixinc = dis->tmpmem + naxis; double *pixend = pixinc + naxis; double *sumdis = pixend + naxis; double *ssqdis = sumdis + naxis; // Work out increments on each axis. for (int j = 0; j < naxis; j++) { double pixspan = pixtrc[j] - (pixblc ? pixblc[j] : 1.0); if (pixsamp == 0x0) { pixinc[j] = 1.0; } else if (pixsamp[j] == 0.0) { pixinc[j] = 1.0; } else if (pixsamp[j] > 0.0) { pixinc[j] = pixsamp[j]; } else if (pixsamp[j] > -1.5) { pixinc[j] = 2.0*pixspan; } else { pixinc[j] = pixspan / ((int)(-pixsamp[j] - 0.5)); } } // Get some more memory for coordinate vectors. double *pix0, *pix1; if ((pix0 = calloc(2*naxis, sizeof(double))) == 0x0) { return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } pix1 = pix0 + naxis; // Set up the array of pixel coordinates. for (int j = 0; j < naxis; j++) { pix0[j] = pixblc ? pixblc[j] : 1.0; pixend[j] = pixtrc[j] + 0.5*pixinc[j]; } // Initialize accumulators. for (int j = 0; j < naxis; j++) { sumdis[j] = 0.0; ssqdis[j] = 0.0; } double sumtot = 0.0; double ssqtot = 0.0; // Loop over N dimensions. int carry = 0; while (carry == 0) { if ((status = disp2x(dis, pix0, pix1))) { // (Preserve the error message set by disp2x().) goto cleanup; } // Accumulate statistics. (*nsamp)++; double dssq = 0.0; for (int j = 0; j < naxis; j++) { double dpix = pix1[j] - pix0[j]; double dpx2 = dpix*dpix; sumdis[j] += dpix; ssqdis[j] += dpx2; if (maxdis && (dpix = fabs(dpix)) > maxdis[j]) { maxdis[j] = dpix; } dssq += dpx2; } double totdis = sqrt(dssq); sumtot += totdis; ssqtot += totdis*totdis; if (maxtot && *maxtot < totdis) { *maxtot = totdis; } // Next pixel. for (int j = 0; j < naxis; j++) { pix0[j] += pixinc[j]; if (pix0[j] < pixend[j]) { carry = 0; break; } pix0[j] = pixblc ? pixblc[j] : 1.0; carry = 1; } } // Compute the means and RMSs. for (int j = 0; j < naxis; j++) { ssqdis[j] /= *nsamp; sumdis[j] /= *nsamp; if (avgdis) avgdis[j] = sumdis[j]; if (rmsdis) rmsdis[j] = sqrt(ssqdis[j] - sumdis[j]*sumdis[j]); } ssqtot /= *nsamp; sumtot /= *nsamp; if (avgtot) *avgtot = sumtot; if (rmstot) *rmstot = sqrt(ssqtot - sumtot*sumtot); cleanup: free(pix0); return status; } //---------------------------------------------------------------------------- int polyset(int j, struct disprm *dis) { static const char *function = "polyset"; // Initialize. if (dis == 0x0) return DISERR_NULL_POINTER; struct wcserr **err = &(dis->err); int naxis = dis->naxis; char id[32]; sprintf(id, "Polynomial on axis %d", j+1); // Find the number of auxiliary variables and terms. int K = 0; int M = 0; struct dpkey *keyp = dis->dp; for (int idp = 0; idp < dis->ndp; idp++, keyp++) { if (keyp->j-1 != j) continue; char *fp; if ((fp = strchr(keyp->field, '.')) == 0x0) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Invalid field name for %s: %s", id, keyp->field); } fp++; if (strcmp(fp, "NAUX") == 0) { K = dpkeyi(keyp); } else if (strcmp(fp, "NTERMS") == 0) { M = dpkeyi(keyp); } } if (K < 0) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Invalid number of auxiliaries (%d) for %s", K, id); } if (M <= 0) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Invalid number of terms (%d) for %s", M, id); } int Nhat = dis->Nhat[j]; int nKparm = 2*(Nhat + 1); int nVar = Nhat + K; int nTparm = 1 + nVar; int ndparm = K*nKparm + M*nTparm; // These iparm indices are specific to Polynomial. #define I_NIDX 3 // No. of indexes in iparm[]. #define I_LENDP 4 // Full (allocated) length of dparm[]. #define I_K 5 // No. of auxiliary variables. #define I_M 6 // No. of terms in the polynomial. #define I_NKPARM 7 // No. of parameters used to define each auxiliary. #define I_NTPARM 8 // No. of parameters used to define each term. #define I_NVAR 9 // No. of independent + auxiliary variables. #define I_MNVAR 10 // No. of powers (exponents) in the polynomial. #define I_DPOLY 11 // dparm offset for polynomial coefficients. #define I_DAUX 12 // dparm offset for auxiliary coefficients. #define I_DVPOW 13 // dparm offset for integral powers of variables. #define I_MAXPOW 14 // iparm offset for max powers. #define I_DPOFF 15 // iparm offset for dparm offsets. #define I_FLAGS 16 // iparm offset for flags. #define I_IPOW 17 // iparm offset for integral powers. #define I_NPOLY 18 // Add extra for handling integer exponents. See "Optimization" below. int niparm = I_NPOLY + (2 + 2*M)*nVar; // Add extra memory for temporaries. int lendp = ndparm + K; // Allocate memory for the indexes and parameter array. if ((dis->iparm[j] = calloc(niparm, sizeof(int))) == 0x0) { return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } if ((dis->dparm[j] = calloc(lendp, sizeof(double))) == 0x0) { return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } // These help a bit to stop the code from turning into hieroglyphics. int *iparm = dis->iparm[j]; double *dparm = dis->dparm[j]; // Record the indexing parameters. The first three are more widely used. iparm[I_DTYPE] = DIS_POLYNOMIAL; iparm[I_NIPARM] = niparm; iparm[I_NDPARM] = ndparm; iparm[I_NIDX] = I_NPOLY; iparm[I_LENDP] = lendp; iparm[I_K] = K; iparm[I_M] = M; iparm[I_NKPARM] = nKparm; iparm[I_NTPARM] = nTparm; iparm[I_NVAR] = nVar; iparm[I_MNVAR] = M*nVar; iparm[I_DPOLY] = K*nKparm; iparm[I_DAUX] = ndparm; iparm[I_DVPOW] = ndparm + K; iparm[I_MAXPOW] = iparm[I_NIDX]; iparm[I_DPOFF] = iparm[I_MAXPOW] + nVar; iparm[I_FLAGS] = iparm[I_DPOFF] + nVar; iparm[I_IPOW] = iparm[I_FLAGS] + M*nVar; // Set default values of POWER for the auxiliary variables. double *dptr = dparm + (1 + Nhat); for (int k = 0; k < K; k++) { for (int jhat = 0; jhat <= Nhat; jhat++) { dptr[jhat] = 1.0; } dptr += nKparm; } // Set default values of COEFF for the independent variables. dptr = dparm + iparm[I_DPOLY]; for (int m = 0; m < M; m++) { *dptr = 1.0; dptr += nTparm; } // Extract parameter values from DPja or DQia. int i, k, m; k = m = 0; keyp = dis->dp; for (int idp = 0; idp < dis->ndp; idp++, keyp++) { // N.B. keyp->j is 1-relative, but j is 0-relative. if (keyp->j-1 != j) continue; char *fp = strchr(keyp->field, '.') + 1; if (strncmp(fp, "AUX.", 4) == 0) { // N.B. k here is 1-relative. fp += 4; sscanf(fp, "%d", &k); if (k < 1 || K < k) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Bad auxiliary variable (%d) for %s: %s", k, id, keyp->field); } if ((fp = strchr(fp, '.')) == 0x0) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Invalid field name for %s: %s", id, keyp->field); } fp++; int offset; if (strncmp(fp, "COEFF.", 6) == 0) { offset = 0; } else if (strncmp(fp, "POWER.", 6) == 0) { offset = 1 + Nhat; } else { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Unrecognized field name for %s: %s", id, keyp->field); } fp += 6; int jhat; sscanf(fp, "%d", &jhat); if (jhat < 0 || naxis < jhat) { // N.B. jhat == 0 is ok. return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Invalid axis number (%d) for %s: %s", jhat, id, keyp->field); } i = (k-1)*nKparm + offset + jhat; dparm[i] = dpkeyd(keyp); } else if (strncmp(fp, "TERM.", 5) == 0) { // N.B. m here is 1-relative. fp += 5; sscanf(fp, "%d", &m); if (m < 1 || M < m) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Bad term (%d) for %s: %s", m, id, keyp->field); } if ((fp = strchr(fp, '.')) == 0x0) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Invalid field name for %s: %s", id, keyp->field); } fp++; if (strcmp(fp, "COEFF") == 0) { i = iparm[I_DPOLY] + (m-1)*nTparm; dparm[i] = dpkeyd(keyp); } else if (strncmp(fp, "VAR.", 4) == 0) { // N.B. jhat here is 1-relative. fp += 4; int jhat; sscanf(fp, "%d", &jhat); if (jhat < 1 || naxis < jhat) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Invalid axis number (%d) for %s: %s", jhat, id, keyp->field); } i = iparm[I_DPOLY] + (m-1)*nTparm + 1 + (jhat-1); double power = dpkeyd(keyp); dparm[i] = power; } else if (strncmp(fp, "AUX.", 4) == 0) { // N.B. k here is 1-relative. fp += 4; sscanf(fp, "%d", &k); if (k < 1 || K < k) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Bad auxiliary variable (%d) for %s: %s", k, id, keyp->field); } i = iparm[I_DPOLY] + (m-1)*nTparm + 1 + Nhat + (k-1); double power = dpkeyd(keyp); dparm[i] = power; } else { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Unrecognized field name for %s: %s", id, keyp->field); } } else if (strcmp(fp, "DOCORR") && strcmp(fp, "NAXES") && strncmp(fp, "AXIS.", 5) && strncmp(fp, "OFFSET.", 7) && strncmp(fp, "SCALE.", 6) && strcmp(fp, "NAUX") && strcmp(fp, "NTERMS")) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Unrecognized field name for %s: %s", id, keyp->field); } } // Optimization: when the power is integral, it is faster to multiply // ------------ repeatedly than call pow(). iparm[] is constructed as // follows: // I_NPOLY indexing parameters, as above, // nVar elements record the largest integral power for each variable, // nVar elements record offsets into dparm for each variable, // M*nVar flags to signal whether the power is integral, // M*nVar integral powers. for (int ivar = 0; ivar < nVar; ivar++) { // Want at least the first degree power for all variables. i = iparm[I_MAXPOW] + ivar; iparm[i] = 1; } for (int ivar = 0; ivar < nVar; ivar++) { for (m = 0; m < M; m++) { i = iparm[I_DPOLY] + m*nTparm + 1 + ivar; double power = dparm[i]; // Is it integral? (Positive, negative, or zero.) int ipow = (int)power; if (power == (double)ipow) { // Signal that the power is integral. i = iparm[I_FLAGS] + m*nVar + ivar; if (ipow == 0) { iparm[i] = 3; } else { iparm[i] = 1; } // The integral power itself. i = iparm[I_IPOW] + m*nVar + ivar; iparm[i] = ipow; } // Record the largest integral power for each variable. i = iparm[I_MAXPOW] + ivar; if (iparm[i] < abs(ipow)) { iparm[i] = abs(ipow); } } } // How many of all powers of each variable will there be? int npow = 0; for (int ivar = 0; ivar < nVar; ivar++) { // Offset into dparm. i = iparm[I_DPOFF] + ivar; iparm[i] = lendp + npow; i = iparm[I_MAXPOW] + ivar; npow += iparm[i]; } // Expand dparm to store the extra powers. if (npow) { lendp += npow; iparm[I_LENDP] = lendp; if ((dis->dparm[j] = realloc(dparm, lendp*sizeof(double))) == 0x0) { return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } } // No specialist de-distortions. dis->disp2x[j] = dispoly; dis->disx2p[j] = 0x0; // Translate Polynomial to TPD if possible, it's much faster. // However don't do it if the name was given as "Polynomial*". if (strcmp(dis->dtype[j], "Polynomial") == 0) { pol2tpd(j, dis); } return 0; } //---------------------------------------------------------------------------- int tpdset(int j, struct disprm *dis) { static const char *function = "tpdset"; if (dis == 0x0) return DISERR_NULL_POINTER; struct wcserr **err = &(dis->err); char id[32]; sprintf(id, "TPD on axis %d", j+1); // TPD distortion. if (dis->Nhat[j] < 1 || 2 < dis->Nhat[j]) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Axis map for %s must contain 1 or 2 entries, not %d", id, dis->Nhat[j]); } // Find the number of parameters. int ncoeff[2] = {0, 0}; int doaux = 0; int doradial = 0; struct dpkey *keyp = dis->dp; for (int idp = 0; idp < dis->ndp; idp++, keyp++) { if (keyp->j-1 != j) continue; char *fp = strchr(keyp->field, '.') + 1; if (strncmp(fp, "TPD.", 4) == 0) { fp += 4; int idis; if (strncmp(fp, "FWD.", 4) == 0) { idis = 0; } else if (strncmp(fp, "REV.", 4) == 0) { // TPD may provide a polynomial approximation for the inverse. idis = 1; } else { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Unrecognized field name for %s: %s", id, keyp->field); } int k; sscanf(fp+4, "%d", &k); if (0 <= k && k <= 59) { if (ncoeff[idis] < k+1) ncoeff[idis] = k+1; // Any radial terms? if (k == 3 || k == 11 || k == 23 || k == 39 || k == 59) { doradial = 1; } } else { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Invalid parameter number (%d) for %s: %s", k, id, keyp->field); } } else if (strncmp(fp, "AUX.", 4) == 0) { // Flag usage of auxiliary variables. doaux = 1; } else if (strcmp(fp, "DOCORR") && strcmp(fp, "NAXES") && strncmp(fp, "AXIS.", 5) && strncmp(fp, "OFFSET.", 7) && strncmp(fp, "SCALE.", 6)) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Unrecognized field name for %s: %s", id, keyp->field); } } int (*(distpd[2]))(DISP2X_ARGS) = {0x0, 0x0}; for (int idis = 0; idis < 2; idis++) { if (ncoeff[idis] <= 4) { if (idis) { // No inverse polynomial. break; } // First degree. ncoeff[idis] = 4; distpd[idis] = tpd1; } else if (ncoeff[idis] <= 7) { // Second degree. ncoeff[idis] = 7; distpd[idis] = tpd2; } else if (ncoeff[idis] <= 12) { // Third degree. ncoeff[idis] = 12; distpd[idis] = tpd3; } else if (ncoeff[idis] <= 17) { // Fourth degree. ncoeff[idis] = 17; distpd[idis] = tpd4; } else if (ncoeff[idis] <= 24) { // Fifth degree. ncoeff[idis] = 24; distpd[idis] = tpd5; } else if (ncoeff[idis] <= 31) { // Sixth degree. ncoeff[idis] = 31; distpd[idis] = tpd6; } else if (ncoeff[idis] <= 40) { // Seventh degree. ncoeff[idis] = 40; distpd[idis] = tpd7; } else if (ncoeff[idis] <= 49) { // Eighth degree. ncoeff[idis] = 49; distpd[idis] = tpd8; } else if (ncoeff[idis] <= 60) { // Ninth degree. ncoeff[idis] = 60; distpd[idis] = tpd9; } else { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Invalid number of parameters (%d) for %s", ncoeff[idis], id); } } // disx2p() only uses the inverse TPD, if present, to provide a better // zeroth approximation. dis->disp2x[j] = distpd[0]; dis->disx2p[j] = distpd[1]; // These iparm indices are specific to TPD (matching definitions in wcshdr.c). #define I_TPDNCO 3 // No. of TPD coefficients, forward... #define I_TPDINV 4 // ...and inverse. #define I_TPDAUX 5 // True if auxiliary variables are used. #define I_TPDRAD 6 // True if the radial variable is used. #define I_NTPD 7 // Record indexing parameters. int niparm = I_NTPD; if ((dis->iparm[j] = calloc(niparm, sizeof(int))) == 0x0) { return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } int ndparm = (doaux?6:0) + ncoeff[0] + ncoeff[1]; // The first three are more widely used. dis->iparm[j][I_DTYPE] = DIS_TPD; dis->iparm[j][I_NIPARM] = niparm; dis->iparm[j][I_NDPARM] = ndparm; // Number of TPD coefficients. dis->iparm[j][I_TPDNCO] = ncoeff[0]; dis->iparm[j][I_TPDINV] = ncoeff[1]; // Flag for presence of auxiliary variables. dis->iparm[j][I_TPDAUX] = doaux; // Flag for presence of radial terms. dis->iparm[j][I_TPDRAD] = doradial; // Allocate memory for the polynomial coefficients and fill it. if ((dis->dparm[j] = calloc(ndparm, sizeof(double))) == 0x0) { return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } // Set default auxiliary coefficients. if (doaux) { dis->dparm[j][1] = 1.0; dis->dparm[j][5] = 1.0; } keyp = dis->dp; for (int idp = 0; idp < dis->ndp; idp++, keyp++) { if (keyp->j-1 != j) continue; char *fp = strchr(keyp->field, '.') + 1; if (strncmp(fp, "AUX.", 4) == 0) { // Auxiliary variables. fp += 4; int k; sscanf(fp, "%d", &k); if (k < 1 || 2 < k) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Bad auxiliary variable (%d) for %s: %s", k, id, keyp->field); } if ((fp = strchr(fp, '.')) == 0x0) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Invalid field name for %s: %s", id, keyp->field); } fp++; if (strncmp(fp, "COEFF.", 6) != 0) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Unrecognized field name for %s: %s", id, keyp->field); } fp += 6; int m; sscanf(fp, "%d", &m); if (m < 0 || 2 < m) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Invalid coefficient number (%d) for %s: %s", m, id, keyp->field); } int idis = 3*(k-1) + m; dis->dparm[j][idis] = dpkeyd(keyp); } else if (strncmp(fp, "TPD.", 4) == 0) { fp += 4; int idis = (doaux?6:0); if (strncmp(fp, "REV.", 4) == 0) { idis += ncoeff[0]; } int k; sscanf(fp+4, "%d", &k); dis->dparm[j][idis+k] = dpkeyd(keyp); } } return 0; } //---------------------------------------------------------------------------- int pol2tpd(int j, struct disprm *dis) { static const char *function = "pol2tpd"; static const int map[][10] = {{ 0, 2, 6, 10, 16, 22, 30, 38, 48, 58}, { 1, 5, 9, 15, 21, 29, 37, 47, 57, -1}, { 4, 8, 14, 20, 28, 36, 46, 56, -1, -1}, { 7, 13, 19, 27, 35, 45, 55, -1, -1, -1}, {12, 18, 26, 34, 44, 54, -1, -1, -1, -1}, {17, 25, 33, 43, 53, -1, -1, -1, -1, -1}, {24, 32, 42, 52, -1, -1, -1, -1, -1, -1}, {31, 41, 51, -1, -1, -1, -1, -1, -1, -1}, {40, 50, -1, -1, -1, -1, -1, -1, -1, -1}, {49, -1, -1, -1, -1, -1, -1, -1, -1, -1}}; // Initialize. if (dis == 0x0) return DISERR_NULL_POINTER; struct wcserr **err = &(dis->err); int *iparm = dis->iparm[j]; double *dparm = dis->dparm[j]; // Check the number of independent variables, no more than two. int Nhat = dis->Nhat[j]; if (2 < Nhat) return -1; // Check auxiliaries: only one is allowed... int K = iparm[I_K]; if (1 < K) return -1; if (K) { // ...and it must be radial. if (dparm[0] != 0.0) return -1; if (dparm[1] != 1.0) return -1; if (dparm[2] != 1.0) return -1; if (dparm[3] != 0.5) return -1; if (dparm[4] != 2.0) return -1; if (dparm[5] != 2.0) return -1; } // Check powers... int *iflgp = iparm + iparm[I_FLAGS]; int *ipowp = iparm + iparm[I_IPOW]; int degree = 0; for (int m = 0; m < iparm[I_M]; m++) { int deg = 0; for (int jhat = 0; jhat < Nhat; jhat++) { // ...they must be positive integral. if (*iflgp == 0) return -1; if (*ipowp < 0) return -1; deg += *ipowp; iflgp++; ipowp++; } // The polynomial degree can't be greater than 9. if (9 < deg) return -1; if (K) { // Likewise for the radial variable. if (*iflgp == 0) return -1; if (*ipowp) { if (*ipowp < 0) return -1; if (9 < *ipowp) return -1; // Can't mix the radial and other terms. if (deg) return -1; // Can't have even powers of the radial variable. deg = *ipowp; if (!(deg%2)) return -1; } iflgp++; ipowp++; } if (degree < deg) degree = deg; } // OK, it ticks all the boxes. Now translate it. int ndparm = 0; if (degree == 1) { ndparm = 4; dis->disp2x[j] = tpd1; } else if (degree == 2) { ndparm = 7; dis->disp2x[j] = tpd2; } else if (degree == 3) { ndparm = 12; dis->disp2x[j] = tpd3; } else if (degree == 4) { ndparm = 17; dis->disp2x[j] = tpd4; } else if (degree == 5) { ndparm = 24; dis->disp2x[j] = tpd5; } else if (degree == 6) { ndparm = 31; dis->disp2x[j] = tpd6; } else if (degree == 7) { ndparm = 40; dis->disp2x[j] = tpd7; } else if (degree == 8) { ndparm = 49; dis->disp2x[j] = tpd8; } else if (degree == 9) { ndparm = 60; dis->disp2x[j] = tpd9; } // No specialist de-distortions. dis->disx2p[j] = 0x0; // Record indexing parameters. int niparm = I_NTPD; int *tpd_iparm; if ((tpd_iparm = calloc(niparm, sizeof(int))) == 0x0) { return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } // The first three are more widely used. tpd_iparm[I_DTYPE] = DIS_TPD; tpd_iparm[I_NIPARM] = niparm; tpd_iparm[I_NDPARM] = ndparm; // Number of TPD coefficients. tpd_iparm[I_TPDNCO] = ndparm; tpd_iparm[I_TPDINV] = 0; // No auxiliary variables yet. tpd_iparm[I_TPDAUX] = 0; // Flag for presence of radial terms. tpd_iparm[I_TPDRAD] = K; // Allocate memory for the polynomial coefficients and fill it. double *tpd_dparm; if ((tpd_dparm = calloc(ndparm, sizeof(double))) == 0x0) { return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } ipowp = iparm + iparm[I_IPOW]; double *dpolp = dparm + iparm[I_DPOLY]; for (int m = 0; m < iparm[I_M]; m++) { if (K && ipowp[Nhat]) { // The radial variable. switch (ipowp[Nhat]) { case 1: tpd_dparm[3] = *dpolp; break; case 3: tpd_dparm[11] = *dpolp; break; case 5: tpd_dparm[23] = *dpolp; break; case 7: tpd_dparm[39] = *dpolp; break; case 9: tpd_dparm[59] = *dpolp; break; } } else { // The independent variables. int p[] = {0, 0}; for (int jhat = 0; jhat < Nhat; jhat++) { p[jhat] = ipowp[jhat]; } int n = map[p[0]][p[1]]; tpd_dparm[n] = *dpolp; } ipowp += iparm[I_NVAR]; dpolp += iparm[I_NVAR] + 1; } // Switch from Polynomial to TPD. free(iparm); free(dparm); dis->iparm[j] = tpd_iparm; dis->dparm[j] = tpd_dparm; return 0; } //---------------------------------------------------------------------------- int tpvset(int j, struct disprm *dis) { static const char *function = "tpvset"; // Initialize. if (dis == 0x0) return DISERR_NULL_POINTER; struct wcserr **err = &(dis->err); // TPV "projection". char id[32]; sprintf(id, "TPV on axis %d", j+1); // TPV is a sequent distortion, applied to intermediate world coordinates // (normally used with CDi_ja). It computes corrected coordinates directly. dis->docorr[j] = 0; if (dis->Nhat[j] != 2) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Axis map for %s must contain 2 entries, not %d", id, dis->Nhat[j]); } // Find the number of parameters. int ndparm = 0; int doradial = 0; struct dpkey *keyp = dis->dp; for (int idp = 0; idp < dis->ndp; idp++, keyp++) { if (keyp->j-1 != j) continue; char *fp = strchr(keyp->field, '.') + 1; if (strncmp(fp, "TPV.", 4) == 0) { int k; sscanf(fp+4, "%d", &k); if (0 <= k && k <= 39) { if (ndparm < k+1) ndparm = k+1; // Any radial terms? if (k == 3 || k == 11 || k == 23 || k == 39 || k == 59) { doradial = 1; } } else { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Invalid parameter number (%d) for %s: %s", k, id, keyp->field); } } else if (strcmp(fp, "NAXES") && strncmp(fp, "AXIS.", 5) && strncmp(fp, "OFFSET.", 7) && strncmp(fp, "SCALE.", 6)) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Unrecognized field name for %s: %s", id, keyp->field); } } // TPD is going to do the dirty work. if (ndparm <= 4) { // First degree. ndparm = 4; dis->disp2x[j] = tpd1; } else if (ndparm <= 7) { // Second degree. ndparm = 7; dis->disp2x[j] = tpd2; } else if (ndparm <= 12) { // Third degree. ndparm = 12; dis->disp2x[j] = tpd3; } else if (ndparm <= 17) { // Fourth degree. ndparm = 17; dis->disp2x[j] = tpd4; } else if (ndparm <= 24) { // Fifth degree. ndparm = 24; dis->disp2x[j] = tpd5; } else if (ndparm <= 31) { // Sixth degree. ndparm = 31; dis->disp2x[j] = tpd6; } else if (ndparm <= 40) { // Seventh degree. ndparm = 40; dis->disp2x[j] = tpd7; } else { // Could go to ninth degree, but that wouldn't be legit. return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Invalid number of parameters (%d) for %s", ndparm, id); } // No specialist de-distortions. dis->disx2p[j] = 0x0; // Record indexing parameters. int niparm = I_NTPD; if ((dis->iparm[j] = calloc(niparm, sizeof(int))) == 0x0) { return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } // The first three are more widely used. dis->iparm[j][I_DTYPE] = DIS_TPD; dis->iparm[j][I_NIPARM] = niparm; dis->iparm[j][I_NDPARM] = ndparm; // Number of TPD coefficients. dis->iparm[j][I_TPDNCO] = ndparm; dis->iparm[j][I_TPDINV] = 0; // TPV never needs auxiliary variables. dis->iparm[j][I_TPDAUX] = 0; // Flag for presence of radial terms. dis->iparm[j][I_TPDRAD] = doradial; // Allocate memory for the polynomial coefficients and fill it. if ((dis->dparm[j] = calloc(ndparm, sizeof(double))) == 0x0) { return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } keyp = dis->dp; for (int idp = 0; idp < dis->ndp; idp++, keyp++) { if (keyp->j-1 != j) continue; char *fp = strchr(keyp->field, '.') + 1; // One-to-one correspondence between TPV and TPD coefficients. if (strncmp(fp, "TPV.", 4) == 0) { int k; sscanf(fp+4, "%d", &k); dis->dparm[j][k] = dpkeyd(keyp); } } return 0; } //---------------------------------------------------------------------------- int sipset(int j, struct disprm *dis) { static const char *function = "sipset"; static const int map[][10] = {{ 0, 2, 6, 10, 16, 22, 30, 38, 48, 58}, { 1, 5, 9, 15, 21, 29, 37, 47, 57, -1}, { 4, 8, 14, 20, 28, 36, 46, 56, -1, -1}, { 7, 13, 19, 27, 35, 45, 55, -1, -1, -1}, {12, 18, 26, 34, 44, 54, -1, -1, -1, -1}, {17, 25, 33, 43, 53, -1, -1, -1, -1, -1}, {24, 32, 42, 52, -1, -1, -1, -1, -1, -1}, {31, 41, 51, -1, -1, -1, -1, -1, -1, -1}, {40, 50, -1, -1, -1, -1, -1, -1, -1, -1}, {49, -1, -1, -1, -1, -1, -1, -1, -1, -1}}; // Initialize. if (dis == 0x0) return DISERR_NULL_POINTER; struct wcserr **err = &(dis->err); // Simple Imaging Polynomial. char id[32]; sprintf(id, "SIP on axis %d", j+1); // SIP is a prior distortion that computes an additive correction. dis->docorr[j] = 1; if (dis->Nhat[j] != 2) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Axis map for %s must contain 2 entries, not %d", id, dis->Nhat[j]); } // Find the polynomial degree, at least 1 for the forward function. int degree[2] = {1, -1}; struct dpkey *keyp = dis->dp; for (int idp = 0; idp < dis->ndp; idp++, keyp++) { if (keyp->j-1 != j) continue; char *fp = strchr(keyp->field, '.') + 1; if (strncmp(fp, "SIP.", 4) == 0) { fp += 4; int idis; if (strncmp(fp, "FWD.", 4) == 0) { idis = 0; } else if (strncmp(fp, "REV.", 4) == 0) { // SIP uses a polynomial approximation for the inverse. idis = 1; } else { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Unrecognized field name for %s: %s", id, keyp->field); } fp += 4; int p, q; sscanf(fp, "%d_%d", &p, &q); int deg = p + q; if (p < 0 || 9 < p || q < 0 || 9 < q || 9 < deg) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Invalid powers (%d, %d) for %s: %s", p, q, id, keyp->field); } if (degree[idis] < deg) degree[idis] = deg; } else if (strcmp(fp, "NAXES") && strncmp(fp, "AXIS.", 5) && strncmp(fp, "OFFSET.", 7) && strncmp(fp, "SCALE.", 6)) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Unrecognized field name for %s: %s", id, keyp->field); } } if (degree[1] == 0 ) degree[1] = 1; // TPD is going to do the dirty work. int (*(distpd[2]))(DISP2X_ARGS) = {0x0, 0x0}, ncoeff[2]; for (int idis = 0; idis < 2; idis++) { ncoeff[idis] = 0; if (degree[idis] == 1) { ncoeff[idis] = 4; distpd[idis] = tpd1; } else if (degree[idis] == 2) { ncoeff[idis] = 7; distpd[idis] = tpd2; } else if (degree[idis] == 3) { ncoeff[idis] = 12; distpd[idis] = tpd3; } else if (degree[idis] == 4) { ncoeff[idis] = 17; distpd[idis] = tpd4; } else if (degree[idis] == 5) { ncoeff[idis] = 24; distpd[idis] = tpd5; } else if (degree[idis] == 6) { ncoeff[idis] = 31; distpd[idis] = tpd6; } else if (degree[idis] == 7) { ncoeff[idis] = 40; distpd[idis] = tpd7; } else if (degree[idis] == 8) { ncoeff[idis] = 49; distpd[idis] = tpd8; } else if (degree[idis] == 9) { ncoeff[idis] = 60; distpd[idis] = tpd9; } } // SIP uses a polynomial approximation to the inverse. It's not very // accurate but may provide disx2p() with a better zeroth approximation. dis->disp2x[j] = distpd[0]; dis->disx2p[j] = distpd[1]; // Record indexing parameters. int niparm = I_NTPD; if ((dis->iparm[j] = calloc(niparm, sizeof(int))) == 0x0) { return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } int ndparm = ncoeff[0] + ncoeff[1]; // The first three are more widely used. dis->iparm[j][I_DTYPE] = DIS_TPD; dis->iparm[j][I_NIPARM] = niparm; dis->iparm[j][I_NDPARM] = ndparm; // Number of TPD coefficients. dis->iparm[j][I_TPDNCO] = ncoeff[0]; dis->iparm[j][I_TPDINV] = ncoeff[1]; // SIP never needs auxiliary variables. dis->iparm[j][I_TPDAUX] = 0; // SIP never needs the radial terms. dis->iparm[j][I_TPDRAD] = 0; // Allocate memory for the polynomial coefficients and fill it. if ((dis->dparm[j] = calloc(ndparm, sizeof(double))) == 0x0) { return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } keyp = dis->dp; for (int idp = 0; idp < dis->ndp; idp++, keyp++) { if (keyp->j-1 != j) continue; char *fp = strchr(keyp->field, '.') + 1; if (strncmp(fp, "SIP.", 4) == 0) { fp += 4; int idis; if (strncmp(fp, "FWD.", 4) == 0) { idis = 0; } else { idis = ncoeff[0]; } int p, q; sscanf(fp+4, "%d_%d", &p, &q); // Map to TPD coefficient number. idis += map[p][q]; dis->dparm[j][idis] = dpkeyd(keyp); } } return 0; } //---------------------------------------------------------------------------- int dssset(int j, struct disprm *dis) { static const char *function = "dssset"; // Initialize. if (dis == 0x0) return DISERR_NULL_POINTER; struct wcserr **err = &(dis->err); // Digitized Sky Survey. char id[32]; sprintf(id, "DSS on axis %d", j+1); // DSS is translated into a sequent distortion, applied to intermediate // pixel coordinates. It computes corrected coordinates directly. dis->docorr[j] = 0; if (dis->Nhat[j] != 2) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Axis map for %s must contain 2 entries, not %d", id, dis->Nhat[j]); } // Safe to assume the polynomial degree is 5 (or less). int ncoeff = 24; dis->disp2x[j] = tpd5; // No specialist de-distortions. dis->disx2p[j] = 0x0; // Record indexing parameters. int niparm = I_NTPD; if ((dis->iparm[j] = calloc(niparm, sizeof(int))) == 0x0) { return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } int ndparm = 6 + ncoeff; // The first three are more widely used. dis->iparm[j][I_DTYPE] = DIS_TPD; dis->iparm[j][I_NIPARM] = niparm; dis->iparm[j][I_NDPARM] = ndparm; // Number of TPD coefficients. dis->iparm[j][I_TPDNCO] = ncoeff; dis->iparm[j][I_TPDINV] = 0; // DSS always needs auxiliary variables. dis->iparm[j][I_TPDAUX] = 1; // DSS never needs the radial terms. dis->iparm[j][I_TPDRAD] = 0; // Allocate memory for the polynomial coefficients and fill it. if ((dis->dparm[j] = calloc(ndparm, sizeof(double))) == 0x0) { return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } // This translation follows WCS Paper IV, Sect. 5.2 using the same // variable names. Find A1, A2, A3, B1, B2, and B3. double A1, A2, A3, B1, B2, B3; A1 = A2 = A3 = 0.0; B1 = B2 = B3 = 0.0; struct dpkey *keyp = dis->dp; for (int idp = 0; idp < dis->ndp; idp++, keyp++) { char *fp = strchr(keyp->field, '.') + 1; if (strncmp(fp, "DSS.AMD.", 8) == 0) { fp += 8; int m; sscanf(fp, "%d", &m); if (m == 1) { if (keyp->j == 1) { A1 = dpkeyd(keyp); } else { B1 = dpkeyd(keyp); } } else if (m == 2) { if (keyp->j == 1) { A2 = dpkeyd(keyp); } else { B2 = dpkeyd(keyp); } } else if (m == 3) { if (keyp->j == 1) { A3 = dpkeyd(keyp); } else { B3 = dpkeyd(keyp); } } } } double X0 = (A2*B3 - A3*B1) / (A1*B1 - A2*B2); double Y0 = (A3*B2 - A1*B3) / (A1*B1 - A2*B2); double S = sqrt(fabs(A1*B1 - A2*B2)); if (S == 0.0) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Coefficient scale for %s is zero.", id); } // Coefficients for the auxiliary variables. double *dparm = dis->dparm[j]; if (j == 0) { dparm[0] = X0; dparm[1] = -B1/S; dparm[2] = -A2/S; dparm[3] = Y0; dparm[4] = B2/S; dparm[5] = A1/S; // Change the sign of S for scaling the A coefficients. S *= -1.0; } else { dparm[0] = Y0; dparm[1] = B2/S; dparm[2] = A1/S; dparm[3] = X0; dparm[4] = -B1/S; dparm[5] = -A2/S; } // Translate DSS coefficients to TPD. dparm += 6; int degree = 3; keyp = dis->dp; for (int idp = 0; idp < dis->ndp; idp++, keyp++) { if (keyp->j-1 != j) continue; char *fp = strchr(keyp->field, '.') + 1; if (strncmp(fp, "DSS.AMD.", 8) == 0) { // Skip zero coefficients. double coeff = dpkeyd(keyp); if (coeff == 0.0) continue; fp += 8; int m; sscanf(fp, "%d", &m); // Apply the coefficient scale factor. coeff /= S; if (m == 1) { dparm[1] = coeff; } else if (m == 2) { dparm[2] = coeff; } else if (m == 3) { dparm[0] = coeff; } else if (m == 4) { dparm[4] += coeff; } else if (m == 5) { dparm[5] = coeff; } else if (m == 6) { dparm[6] += coeff; } else if (m == 7) { dparm[4] += coeff; dparm[6] += coeff; } else if (m == 8) { dparm[7] += coeff; } else if (m == 9) { dparm[8] = coeff; } else if (m == 10) { dparm[9] += coeff; } else if (m == 11) { dparm[10] = coeff; } else if (m == 12) { dparm[7] += coeff; dparm[9] += coeff; } else if (m == 13) { dparm[17] = coeff; dparm[19] = coeff * 2.0; dparm[21] = coeff; degree = 5; } else if (coeff != 0.0) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Invalid parameter for %s: %s", m, id, keyp->field); } } else if (strcmp(fp, "NAXES") && strncmp(fp, "AXIS.", 5) && strncmp(fp, "OFFSET.", 7) && strncmp(fp, "SCALE.", 6)) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Unrecognized field name for %s: %s", id, keyp->field); } } // The DSS polynomial doesn't have 4th degree terms, and the 5th degree // coefficient is often zero. if (degree == 3) { dis->iparm[j][I_TPDNCO] = 12; dis->disp2x[j] = tpd3; } return 0; } //---------------------------------------------------------------------------- #define CHEBYSHEV 1 #define LEGENDRE 2 #define MONOMIAL 3 int watset(int j, struct disprm *dis) { static const char *function = "watset"; static const int map[][10] = {{ 0, 2, 6, 10, 16, 22, 30, 38, 48, 58}, { 1, 5, 9, 15, 21, 29, 37, 47, 57, -1}, { 4, 8, 14, 20, 28, 36, 46, 56, -1, -1}, { 7, 13, 19, 27, 35, 45, 55, -1, -1, -1}, {12, 18, 26, 34, 44, 54, -1, -1, -1, -1}, {17, 25, 33, 43, 53, -1, -1, -1, -1, -1}, {24, 32, 42, 52, -1, -1, -1, -1, -1, -1}, {31, 41, 51, -1, -1, -1, -1, -1, -1, -1}, {40, 50, -1, -1, -1, -1, -1, -1, -1, -1}, {49, -1, -1, -1, -1, -1, -1, -1, -1, -1}}; // Initialize. if (dis == 0x0) return DISERR_NULL_POINTER; struct wcserr **err = &(dis->err); // WAT (TNX or ZPX) Polynomial. char id[32]; sprintf(id, "WAT (%s) on axis %d", dis->dtype[0]+4, j+1); // WAT is a sequent distortion, applied to intermediate world coordinates // (normally used with CDi_ja). It computes an additive correction. dis->docorr[j] = 1; if (dis->Nhat[j] != 2) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Axis map for %s must contain 2 entries, not %d", id, dis->Nhat[j]); } // Find the polynomial degree (at least 1), kind, and domain. int degree = 1; int kind = 0; double xmin = 0.0; double xmax = 0.0; double ymin = 0.0; double ymax = 0.0; struct dpkey *keyp = dis->dp; for (int idp = 0; idp < dis->ndp; idp++, keyp++) { if (keyp->j-1 != j) continue; char *fp = strchr(keyp->field, '.') + 1; if (strncmp(fp, "WAT.", 4) == 0) { fp += 4; if (strncmp(fp, "CHBY.", 5) == 0 || strncmp(fp, "LEGR.", 5) == 0 || strncmp(fp, "MONO.", 5) == 0) { fp += 5; int m, n; sscanf(fp, "%d_%d", &m, &n); int deg = m + n; if (m < 0 || 9 < m || n < 0 || 9 < n || 9 < deg) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Invalid powers (%d, %d) for %s: %s", m, n, id, keyp->field); } if (degree < deg) degree = deg; } else if (strcmp(fp, "POLY") == 0) { kind = dpkeyi(keyp); } else if (strcmp(fp, "XMIN") == 0) { xmin = dpkeyd(keyp); } else if (strcmp(fp, "XMAX") == 0) { xmax = dpkeyd(keyp); } else if (strcmp(fp, "YMIN") == 0) { ymin = dpkeyd(keyp); } else if (strcmp(fp, "YMAX") == 0) { ymax = dpkeyd(keyp); } } else if (strcmp(fp, "NAXES") && strncmp(fp, "AXIS.", 5) && strncmp(fp, "OFFSET.", 7) && strncmp(fp, "SCALE.", 6)) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Unrecognized field name for %s: %s", id, keyp->field); } } int doaux = (kind == 1 || kind == 2); // TPD is going to do the dirty work. int ncoeff = 0; if (degree == 1) { // First degree. ncoeff = 4; dis->disp2x[j] = tpd1; } else if (degree == 2) { // Second degree. ncoeff = 7; dis->disp2x[j] = tpd2; } else if (degree == 3) { // Third degree. ncoeff = 12; dis->disp2x[j] = tpd3; } else if (degree == 4) { // Fourth degree. ncoeff = 17; dis->disp2x[j] = tpd4; } else if (degree == 5) { // Fifth degree. ncoeff = 24; dis->disp2x[j] = tpd5; } else if (degree == 6) { // Sixth degree. ncoeff = 31; dis->disp2x[j] = tpd6; } else if (degree == 7) { // Seventh degree. ncoeff = 40; dis->disp2x[j] = tpd7; } else if (degree == 8) { // Eighth degree. ncoeff = 49; dis->disp2x[j] = tpd8; } else if (degree == 9) { // Ninth degree. ncoeff = 60; dis->disp2x[j] = tpd9; } // No specialist de-distortions. dis->disx2p[j] = 0x0; // Record indexing parameters. int niparm = I_NTPD; if ((dis->iparm[j] = calloc(niparm, sizeof(int))) == 0x0) { return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } int *iparm = dis->iparm[j]; int ndparm = 6 + ncoeff; // The first three are more widely used. iparm[I_DTYPE] = DIS_TPD; iparm[I_NIPARM] = niparm; iparm[I_NDPARM] = ndparm; // Number of TPD coefficients. iparm[I_TPDNCO] = ncoeff; iparm[I_TPDINV] = 0; // The Chebyshev and Legendre polynomials use auxiliary variables. iparm[I_TPDAUX] = doaux; // WAT never needs the radial terms. iparm[I_TPDRAD] = 0; // Allocate memory for the polynomial coefficients and fill it. if ((dis->dparm[j] = calloc(ndparm, sizeof(double))) == 0x0) { return wcserr_set(DIS_ERRMSG(DISERR_MEMORY)); } double *dparm = dis->dparm[j]; // Coefficients for the auxiliary variables. if (doaux) { double x0 = (xmax + xmin)/2.0; double dx = (xmax - xmin)/2.0; if (dx == 0.0) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "X-span for %s is zero", id); } dparm[0] = -x0/dx; dparm[1] = 1.0/dx; dparm[2] = 0.0; double y0 = (ymax + ymin)/2.0; double dy = (ymax - ymin)/2.0; if (dy == 0.0) { return wcserr_set(WCSERR_SET(DISERR_BAD_PARAM), "Y-span for %s is zero", id); } dparm[3] = -y0/dy; dparm[4] = 0.0; dparm[5] = 1.0/dy; dparm += 6; } // Unpack the polynomial coefficients. keyp = dis->dp; for (int idp = 0; idp < dis->ndp; idp++, keyp++) { if (keyp->j-1 != j) continue; char *fp = strchr(keyp->field, '.') + 1; if ((kind == CHEBYSHEV && strncmp(fp, "WAT.CHBY.", 9) == 0) || (kind == LEGENDRE && strncmp(fp, "WAT.LEGR.", 9) == 0) || (kind == MONOMIAL && strncmp(fp, "WAT.MONO.", 9) == 0)) { fp += 9; int m, n; sscanf(fp, "%d_%d", &m, &n); if (kind == MONOMIAL) { // Monomial coefficient, maps simply to TPD coefficient number. int idis = map[m][n]; dparm[idis] = dpkeyd(keyp); } else { // Coefficient of the product of two Chebyshev or two Legendre // polynomials. Find the corresponding monomial coefficients. double coeff = dpkeyd(keyp); double coeffm[10], coeffn[10]; cheleg(kind, m, n, coeffm, coeffn); for (int im = 0; im <= m; im++) { if (coeffm[im] == 0.0) continue; for (int in = 0; in <= n; in++) { if (coeffn[in] == 0.0) continue; int idis = map[im][in]; dparm[idis] += coeff*coeffm[im]*coeffn[in]; } } } } } return 0; } //---------------------------------------------------------------------------- // Compute the coefficients of Chebyshev or Legendre polynomials of degree // m and n. int cheleg(int kind, int m, int n, double coeffm[], double coeffn[]) { int N = (m > n) ? m : n; // Allocate work arrays. double *coeff[3]; coeff[0] = calloc(3*(N+1), sizeof(double)); coeff[1] = coeff[0] + (N+1); coeff[2] = coeff[1] + (N+1); for (int j = 0; j <= N; j++) { int j0 = j%3; if (j == 0) { coeff[0][0] = 1.0; } else if (j == 1) { coeff[1][1] = 1.0; } else { // Cyclic buffer indices. int j1 = (j-1)%3; int j2 = (j-2)%3; memset(coeff[j0], 0, (N+1)*sizeof(double)); double d = (double)j; for (int k = 0; k < N; k++) { if (kind == CHEBYSHEV) { coeff[j0][k+1] = 2.0 * coeff[j1][k]; coeff[j0][k] -= coeff[j2][k]; } else if (kind == LEGENDRE) { coeff[j0][k+1] = ((2.0*d - 1.0) * coeff[j1][k]) / d; coeff[j0][k] -= ((d - 1.0) * coeff[j2][k]) / d; } } } if (j == m) memcpy(coeffm, coeff[j0], (m+1)*sizeof(double)); if (j == n) memcpy(coeffn, coeff[j0], (n+1)*sizeof(double)); } free(coeff[0]); return 0; } //---------------------------------------------------------------------------- int dispoly( int dummy, const int iparm[], const double dparm[], int Nhat, const double rawcrd[], double *discrd) { // Avert nuisance compiler warnings about unused parameters. (void)dummy; // Check for zeroes. for (int jhat = 0; jhat < Nhat; jhat++) { if (rawcrd[jhat] == 0.0) { *discrd = 0.0; return 0; } } // Working memory for auxiliaries &c. was allocated at the end of p[]. double *aux = (double *)(dparm + iparm[I_DAUX]); // Compute the auxiliary variables. for (int k = 0; k < iparm[I_K]; k++) { const double *cptr = dparm + k*iparm[I_NKPARM]; const double *pptr = cptr + (1+Nhat); aux[k] = *(cptr++); double auxp0 = *(pptr++); for (int jhat = 0; jhat < Nhat; jhat++) { aux[k] += *(cptr++)*pow(rawcrd[jhat], *(pptr++)); } aux[k] = pow(aux[k], auxp0); // Check for zeroes. if (aux[k] == 0.0) { *discrd = 0.0; return 0; } } // Compute all required integral powers of the variables. const int *imaxpow = iparm + iparm[I_MAXPOW]; double *dvarpow = (double *)(dparm + iparm[I_DVPOW]); const int *imaxp = imaxpow; double *dpowp = dvarpow; for (int jhat = 0; jhat < Nhat; jhat++, imaxp++) { double var = 1.0; for (int ip = 0; ip < *imaxp; ip++, dpowp++) { var *= rawcrd[jhat]; *dpowp = var; } } for (int k = 0; k < iparm[I_K]; k++, imaxp++) { double var = 1.0; for (int ip = 0; ip < *imaxp; ip++, dpowp++) { var *= aux[k]; *dpowp = var; } } // Loop for each term of the polynomial. *discrd = 0.0; const int *iflgp = iparm + iparm[I_FLAGS]; const int *ipowp = iparm + iparm[I_IPOW]; const double *dpolp = dparm + iparm[I_DPOLY]; for (int m = 0; m < iparm[I_M]; m++) { double term = *(dpolp++); // Loop over all variables. imaxp = imaxpow; dpowp = dvarpow - 1; for (int ivar = 0; ivar < iparm[I_NVAR]; ivar++) { if (*iflgp & 2) { // Nothing (zero power). } else if (*iflgp) { // Integral power. if (*ipowp < 0) { // Negative. term /= dpowp[*ipowp]; } else { // Positive. term *= dpowp[*ipowp]; } } else { // Fractional power. term *= pow(dpowp[0], *dpolp); } iflgp++; ipowp++; dpolp++; dpowp += *imaxp; imaxp++; } *discrd += term; } return 0; } //---------------------------------------------------------------------------- int tpd1( int inverse, const int i[], const double p[], int Nhat, const double rawcrd[], double *discrd) { if (i[I_TPDNCO+inverse] != 4 || 2 < Nhat) { return 1; } double r, s; double u = rawcrd[0]; double v = rawcrd[1]; // Auxiliary variables? if (i[I_TPDAUX]) { r = p[0] + p[1]*u + p[2]*v; v = p[3] + p[4]*u + p[5]*v; u = r; p += 6; } if (inverse) p += i[I_TPDNCO]; // First degree. *discrd = p[0] + u*p[1]; if (Nhat == 1) return 0; *discrd += v*p[2]; // Radial terms? if (i[I_TPDRAD]) { s = u*u + v*v; r = sqrt(s); *discrd += r*p[3]; } return 0; } //---------------------------------------------------------------------------- int tpd2( int inverse, const int i[], const double p[], int Nhat, const double rawcrd[], double *discrd) { if (i[I_TPDNCO+inverse] != 7 || 2 < Nhat) { return 1; } double r, s; double u = rawcrd[0]; double v = rawcrd[1]; // Auxiliary variables? if (i[I_TPDAUX]) { r = p[0] + p[1]*u + p[2]*v; v = p[3] + p[4]*u + p[5]*v; u = r; p += 6; } if (inverse) p += i[I_TPDNCO]; // Second degree. *discrd = p[0] + u*(p[1] + u*(p[4])); if (Nhat == 1) return 0; *discrd += v*(p[2] + v*(p[6])) + u*(p[5])*v; // Radial terms? if (i[I_TPDRAD]) { s = u*u + v*v; r = sqrt(s); *discrd += r*p[3]; } return 0; } //---------------------------------------------------------------------------- int tpd3( int inverse, const int i[], const double p[], int Nhat, const double rawcrd[], double *discrd) { if (i[I_TPDNCO+inverse] != 12 || 2 < Nhat) { return 1; } double r, s; double u = rawcrd[0]; double v = rawcrd[1]; // Auxiliary variables? if (i[I_TPDAUX]) { r = p[0] + p[1]*u + p[2]*v; v = p[3] + p[4]*u + p[5]*v; u = r; p += 6; } if (inverse) p += i[I_TPDNCO]; // Third degree. *discrd = p[0] + u*(p[1] + u*(p[4] + u*(p[7]))); if (Nhat == 1) return 0; *discrd += v*(p[2] + v*(p[6] + v*(p[10]))) + u*(p[5] + v*(p[9]) + u*(p[8]))*v; // Radial terms? if (i[I_TPDRAD]) { s = u*u + v*v; r = sqrt(s); *discrd += r*(p[3] + s*(p[11])); } return 0; } //---------------------------------------------------------------------------- int tpd4( int inverse, const int i[], const double p[], int Nhat, const double rawcrd[], double *discrd) { if (i[I_TPDNCO+inverse] != 17 || 2 < Nhat) { return 1; } double r, s; double u = rawcrd[0]; double v = rawcrd[1]; // Auxiliary variables? if (i[I_TPDAUX]) { r = p[0] + p[1]*u + p[2]*v; v = p[3] + p[4]*u + p[5]*v; u = r; p += 6; } if (inverse) p += i[I_TPDNCO]; // Fourth degree. *discrd = p[0] + u*(p[1] + u*(p[4] + u*(p[7] + u*(p[12])))); if (Nhat == 1) return 0; *discrd += v*(p[2] + v*(p[6] + v*(p[10] + v*(p[16])))) + u*(p[5] + v*(p[9] + v*(p[15])) + u*(p[8] + v*(p[14]) + u*(p[13])))*v; // Radial terms? if (i[I_TPDRAD]) { s = u*u + v*v; r = sqrt(s); *discrd += r*(p[3] + s*(p[11])); } return 0; } //---------------------------------------------------------------------------- int tpd5( int inverse, const int i[], const double p[], int Nhat, const double rawcrd[], double *discrd) { if (i[I_TPDNCO+inverse] != 24 || 2 < Nhat) { return 1; } double r, s; double u = rawcrd[0]; double v = rawcrd[1]; // Auxiliary variables? if (i[I_TPDAUX]) { r = p[0] + p[1]*u + p[2]*v; v = p[3] + p[4]*u + p[5]*v; u = r; p += 6; } if (inverse) p += i[I_TPDNCO]; // Fifth degree. *discrd = p[0] + u*(p[1] + u*(p[4] + u*(p[7] + u*(p[12] + u*(p[17]))))); if (Nhat == 1) return 0; *discrd += v*(p[2] + v*(p[6] + v*(p[10] + v*(p[16] + v*(p[22]))))) + u*(p[5] + v*(p[9] + v*(p[15] + v*(p[21]))) + u*(p[8] + v*(p[14] + v*(p[20])) + u*(p[13] + v*(p[19]) + u*(p[18]))))*v; // Radial terms? if (i[I_TPDRAD]) { s = u*u + v*v; r = sqrt(s); *discrd += r*(p[3] + s*(p[11] + s*(p[23]))); } return 0; } //---------------------------------------------------------------------------- int tpd6( int inverse, const int i[], const double p[], int Nhat, const double rawcrd[], double *discrd) { if (i[I_TPDNCO+inverse] != 31 || 2 < Nhat) { return 1; } double r, s; double u = rawcrd[0]; double v = rawcrd[1]; // Auxiliary variables? if (i[I_TPDAUX]) { r = p[0] + p[1]*u + p[2]*v; v = p[3] + p[4]*u + p[5]*v; u = r; p += 6; } if (inverse) p += i[I_TPDNCO]; // Sixth degree. *discrd = p[0] + u*(p[1] + u*(p[4] + u*(p[7] + u*(p[12] + u*(p[17] + u*(p[24])))))); if (Nhat == 1) return 0; *discrd += v*(p[2] + v*(p[6] + v*(p[10] + v*(p[16] + v*(p[22] + v*(p[30])))))) + u*(p[5] + v*(p[9] + v*(p[15] + v*(p[21] + v*(p[29])))) + u*(p[8] + v*(p[14] + v*(p[20] + v*(p[28]))) + u*(p[13] + v*(p[19] + v*(p[27])) + u*(p[18] + v*(p[26]) + u*(p[25])))))*v; // Radial terms? if (i[I_TPDRAD]) { s = u*u + v*v; r = sqrt(s); *discrd += r*(p[3] + s*(p[11] + s*(p[23]))); } return 0; } //---------------------------------------------------------------------------- int tpd7( int inverse, const int i[], const double p[], int Nhat, const double rawcrd[], double *discrd) { if (i[I_TPDNCO+inverse] != 40 || 2 < Nhat) { return 1; } double r, s; double u = rawcrd[0]; double v = rawcrd[1]; // Auxiliary variables? if (i[I_TPDAUX]) { r = p[0] + p[1]*u + p[2]*v; v = p[3] + p[4]*u + p[5]*v; u = r; p += 6; } if (inverse) p += i[I_TPDNCO]; // Seventh degree. *discrd = p[0] + u*(p[1] + u*(p[4] + u*(p[7] + u*(p[12] + u*(p[17] + u*(p[24] + u*(p[31]))))))); if (Nhat == 1) return 0; *discrd += v*(p[2] + v*(p[6] + v*(p[10] + v*(p[16] + v*(p[22] + v*(p[30] + v*(p[38]))))))) + u*(p[5] + v*(p[9] + v*(p[15] + v*(p[21] + v*(p[29] + v*(p[37]))))) + u*(p[8] + v*(p[14] + v*(p[20] + v*(p[28] + v*(p[36])))) + u*(p[13] + v*(p[19] + v*(p[27] + v*(p[35]))) + u*(p[18] + v*(p[26] + v*(p[34])) + u*(p[25] + v*(p[33]) + u*(p[32]))))))*v; // Radial terms? if (i[I_TPDRAD]) { s = u*u + v*v; r = sqrt(s); *discrd += r*(p[3] + s*(p[11] + s*(p[23] + s*(p[39])))); } return 0; } //---------------------------------------------------------------------------- int tpd8( int inverse, const int i[], const double p[], int Nhat, const double rawcrd[], double *discrd) { if (i[I_TPDNCO+inverse] != 49 || 2 < Nhat) { return 1; } double r, s; double u = rawcrd[0]; double v = rawcrd[1]; // Auxiliary variables? if (i[I_TPDAUX]) { r = p[0] + p[1]*u + p[2]*v; v = p[3] + p[4]*u + p[5]*v; u = r; p += 6; } if (inverse) p += i[I_TPDNCO]; // Eighth degree. *discrd = p[0] + u*(p[1] + u*(p[4] + u*(p[7] + u*(p[12] + u*(p[17] + u*(p[24] + u*(p[31] + u*(p[40])))))))); if (Nhat == 1) return 0; *discrd += v*(p[2] + v*(p[6] + v*(p[10] + v*(p[16] + v*(p[22] + v*(p[30] + v*(p[38] + v*(p[48])))))))) + u*(p[5] + v*(p[9] + v*(p[15] + v*(p[21] + v*(p[29] + v*(p[37] + v*(p[47])))))) + u*(p[8] + v*(p[14] + v*(p[20] + v*(p[28] + v*(p[36] + v*(p[46]))))) + u*(p[13] + v*(p[19] + v*(p[27] + v*(p[35] + v*(p[45])))) + u*(p[18] + v*(p[26] + v*(p[34] + v*(p[44]))) + u*(p[25] + v*(p[33] + v*(p[43])) + u*(p[32] + v*(p[42]) + u*(p[41])))))))*v; // Radial terms? if (i[I_TPDRAD]) { s = u*u + v*v; r = sqrt(s); *discrd += r*(p[3] + s*(p[11] + s*(p[23] + s*(p[39])))); } return 0; } //---------------------------------------------------------------------------- int tpd9( int inverse, const int i[], const double p[], int Nhat, const double rawcrd[], double *discrd) { if (i[I_TPDNCO+inverse] != 60 || 2 < Nhat) { return 1; } double r, s; double u = rawcrd[0]; double v = rawcrd[1]; // Auxiliary variables? if (i[I_TPDAUX]) { r = p[0] + p[1]*u + p[2]*v; v = p[3] + p[4]*u + p[5]*v; u = r; p += 6; } if (inverse) p += i[I_TPDNCO]; // Ninth degree. *discrd = p[0] + u*(p[1] + u*(p[4] + u*(p[7] + u*(p[12] + u*(p[17] + u*(p[24] + u*(p[31] + u*(p[40] + u*(p[49]))))))))); if (Nhat == 1) return 0; *discrd += v*(p[2] + v*(p[6] + v*(p[10] + v*(p[16] + v*(p[22] + v*(p[30] + v*(p[38] + v*(p[48] + v*(p[58]))))))))) + u*(p[5] + v*(p[9] + v*(p[15] + v*(p[21] + v*(p[29] + v*(p[37] + v*(p[47] + v*(p[57]))))))) + u*(p[8] + v*(p[14] + v*(p[20] + v*(p[28] + v*(p[36] + v*(p[46] + v*(p[56])))))) + u*(p[13] + v*(p[19] + v*(p[27] + v*(p[35] + v*(p[45] + v*(p[55]))))) + u*(p[18] + v*(p[26] + v*(p[34] + v*(p[44] + v*(p[54])))) + u*(p[25] + v*(p[33] + v*(p[43] + v*(p[53]))) + u*(p[32] + v*(p[42] + v*(p[52])) + u*(p[41] + v*(p[51]) + u*(p[50]))))))))*v; // Radial terms? if (i[I_TPDRAD]) { s = u*u + v*v; r = sqrt(s); *discrd += r*(p[3] + s*(p[11] + s*(p[23] + s*(p[39] + s*(p[59]))))); } return 0; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/dis.h0000644000175100001710000014214100000000000016315 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: dis.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the dis routines * --------------------------- * Routines in this suite implement extensions to the FITS World Coordinate * System (WCS) standard proposed by * = "Representations of distortions in FITS world coordinate systems", = Calabretta, M.R. et al. (WCS Paper IV, draft dated 2004/04/22), = available from http://www.atnf.csiro.au/people/Mark.Calabretta * * In brief, a distortion function may occupy one of two positions in the WCS * algorithm chain. Prior distortions precede the linear transformation * matrix, whether it be PCi_ja or CDi_ja, and sequent distortions follow it. * WCS Paper IV defines FITS keywords used to specify parameters for predefined * distortion functions. The following are used for prior distortions: * = CPDISja ...(string-valued, identifies the distortion function) = DPja ...(record-valued, parameters) = CPERRja ...(floating-valued, maximum value) * * Their counterparts for sequent distortions are CQDISia, DQia, and CQERRia. * An additional floating-valued keyword, DVERRa, records the maximum value of * the combined distortions. * * DPja and DQia are "record-valued". Syntactically, the keyvalues are * standard FITS strings, but they are to be interpreted in a special way. * The general form is * = DPja = ': ' * * where the field-specifier consists of a sequence of fields separated by * periods, and the ': ' between the field-specifier and the floating-point * value is part of the record syntax. For example: * = DP1 = 'AXIS.1: 1' * * Certain field-specifiers are defined for all distortion functions, while * others are defined only for particular distortions. Refer to WCS Paper IV * for further details. wcspih() parses all distortion keywords and loads them * into a disprm struct for analysis by disset() which knows (or possibly does * not know) how to interpret them. Of the Paper IV distortion functions, only * the general Polynomial distortion is currently implemented here. * * TPV - the TPV "projection": * --------------------------- * The distortion function component of the TPV celestial "projection" is also * supported. The TPV projection, originally proposed in a draft of WCS Paper * II, consists of a TAN projection with sequent polynomial distortion, the * coefficients of which are encoded in PVi_ma keyrecords. Full details may be * found at the registry of FITS conventions: * = http://fits.gsfc.nasa.gov/registry/tpvwcs/tpv.html * * Internally, wcsset() changes TPV to a TAN projection, translates the PVi_ma * keywords to DQia and loads them into a disprm struct. These DQia keyrecords * have the form * = DQia = 'TPV.m: ' * * where i, a, m, and the value for each DQia match each PVi_ma. Consequently, * WCSLIB would handle a FITS header containing these keywords, along with * CQDISia = 'TPV' and the required DQia.NAXES and DQia.AXIS.ihat keywords. * * Note that, as defined, TPV assumes that CDi_ja is used to define the linear * transformation. The section on historical idiosyncrasies (below) cautions * about translating CDi_ja to PCi_ja plus CDELTia in this case. * * SIP - Simple Imaging Polynomial: * -------------------------------- * These routines also support the Simple Imaging Polynomial (SIP), whose * design was influenced by early drafts of WCS Paper IV. It is described in * detail in * = http://fits.gsfc.nasa.gov/registry/sip.html * * SIP, which is defined only as a prior distortion for 2-D celestial images, * has the interesting feature that it records an approximation to the inverse * polynomial distortion function. This is used by disx2p() to provide an * initial estimate for its more precise iterative inversion. The * special-purpose keywords used by SIP are parsed and translated by wcspih() * as follows: * = A_p_q = -> DP1 = 'SIP.FWD.p_q: ' = AP_p_q = -> DP1 = 'SIP.REV.p_q: ' = B_p_q = -> DP2 = 'SIP.FWD.p_q: ' = BP_p_q = -> DP2 = 'SIP.REV.p_q: ' = A_DMAX = -> DPERR1 = = B_DMAX = -> DPERR2 = * * SIP's A_ORDER and B_ORDER keywords are not used. WCSLIB would recognise a * FITS header containing the above keywords, along with CPDISja = 'SIP' and * the required DPja.NAXES keywords. * * DSS - Digitized Sky Survey: * --------------------------- * The Digitized Sky Survey resulted from the production of the Guide Star * Catalogue for the Hubble Space Telescope. Plate solutions based on a * polynomial distortion function were encoded in FITS using non-standard * keywords. Sect. 5.2 of WCS Paper IV describes how DSS coordinates may be * translated to a sequent Polynomial distortion using two auxiliary variables. * That translation is based on optimising the non-distortion component of the * plate solution. * * Following Paper IV, wcspih() translates the non-distortion component of DSS * coordinates to standard WCS keywords (CRPIXja, PCi_ja, CRVALia, etc), and * fills a wcsprm struct with their values. It encodes the DSS polynomial * coefficients as * = AMDXm = -> DQ1 = 'AMD.m: ' = AMDYm = -> DQ2 = 'AMD.m: ' * * WCSLIB would recognise a FITS header containing the above keywords, along * with CQDISia = 'DSS' and the required DQia.NAXES keywords. * * WAT - the TNX and ZPX "projections": * ------------------------------------ * The TNX and ZPX "projections" add a polynomial distortion function to the * standard TAN and ZPN projections respectively. Unusually, the polynomial * may be expressed as the sum of Chebyshev or Legendre polynomials, or as a * simple sum of monomials, as described in * = http://fits.gsfc.nasa.gov/registry/tnx/tnx-doc.html = http://fits.gsfc.nasa.gov/registry/zpxwcs/zpx.html * * The polynomial coefficients are encoded in special-purpose WATi_n keywords * as a set of continued strings, thus providing the name for this distortion * type. WATi_n are parsed and translated by wcspih() into the following set: * = DQi = 'WAT.POLY: ' = DQi = 'WAT.XMIN: ' = DQi = 'WAT.XMAX: ' = DQi = 'WAT.YMIN: ' = DQi = 'WAT.YMAX: ' = DQi = 'WAT.CHBY.m_n: ' or = DQi = 'WAT.LEGR.m_n: ' or = DQi = 'WAT.MONO.m_n: ' * * along with CQDISia = 'WAT' and the required DPja.NAXES keywords. For ZPX, * the ZPN projection parameters are also encoded in WATi_n, and wcspih() * translates these to standard PVi_ma. * * Note that, as defined, TNX and ZPX assume that CDi_ja is used to define the * linear transformation. The section on historical idiosyncrasies (below) * cautions about translating CDi_ja to PCi_ja plus CDELTia in this case. * * TPD - Template Polynomial Distortion: * ------------------------------------- * The "Template Polynomial Distortion" (TPD) is a superset of the TPV, SIP, * DSS, and WAT (TNX & ZPX) polynomial distortions that also supports 1-D usage * and inversions. Like TPV, SIP, and DSS, the form of the polynomial is fixed * (the "template") and only the coefficients for the required terms are set * non-zero. TPD generalizes TPV in going to 9th degree, SIP by accomodating * TPV's linear and radial terms, and DSS in both respects. While in theory * the degree of the WAT polynomial distortion in unconstrained, in practice it * is limited to values that can be handled by TPD. * * Within WCSLIB, TPV, SIP, DSS, and WAT are all implemented as special cases * of TPD. Indeed, TPD was developed precisely for that purpose. WAT * distortions expressed as the sum of Chebyshev or Legendre polynomials are * expanded for TPD as a simple sum of monomials. Moreover, the general * Polynomial distortion is translated and implemented internally as TPD * whenever possible. * * However, WCSLIB also recognizes 'TPD' as a distortion function in its own * right (i.e. a recognized value of CPDISja or CQDISia), for use as both prior * and sequent distortions. Its DPja and DQia keyrecords have the form * = DPja = 'TPD.FWD.m: ' = DPja = 'TPD.REV.m: ' * * for the forward and reverse distortion functions. Moreover, like the * general Polynomial distortion, TPD supports auxiliary variables, though only * as a linear transformation of pixel coordinates (p1,p2): * = x = a0 + a1*p1 + a2*p2 = y = b0 + b1*p1 + b2*p2 * * where the coefficients of the auxiliary variables (x,y) are recorded as * = DPja = 'AUX.1.COEFF.0: a0' ...default 0.0 = DPja = 'AUX.1.COEFF.1: a1' ...default 1.0 = DPja = 'AUX.1.COEFF.2: a2' ...default 0.0 = DPja = 'AUX.2.COEFF.0: b0' ...default 0.0 = DPja = 'AUX.2.COEFF.1: b1' ...default 0.0 = DPja = 'AUX.2.COEFF.2: b2' ...default 1.0 * * Though nowhere near as powerful, in typical applications TPD is considerably * faster than the general Polynomial distortion. As TPD has a finite and not * too large number of possible terms (60), the coefficients for each can be * stored (by disset()) in a fixed location in the disprm::dparm[] array. A * large part of the speedup then arises from evaluating the polynomial using * Horner's scheme. * * Separate implementations for polynomials of each degree, and conditionals * for 1-D polynomials and 2-D polynomials with and without the radial * variable, ensure that unused terms mostly do not impose a significant * computational overhead. * * The TPD terms are as follows * = 0: 1 4: xx 12: xxxx 24: xxxxxx 40: xxxxxxxx = 5: xy 13: xxxy 25: xxxxxy 41: xxxxxxxy = 1: x 6: yy 14: xxyy 26: xxxxyy 42: xxxxxxyy = 2: y 15: xyyy 27: xxxyyy 43: xxxxxyyy = 3: r 7: xxx 16: yyyy 28: xxyyyy 44: xxxxyyyy = 8: xxy 29: xyyyyy 45: xxxyyyyy = 9: xyy 17: xxxxx 30: yyyyyy 46: xxyyyyyy = 10: yyy 18: xxxxy 47: xyyyyyyy = 11: rrr 19: xxxyy 31: xxxxxxx 48: yyyyyyyy = 20: xxyyy 32: xxxxxxy = 21: xyyyy 33: xxxxxyy 49: xxxxxxxxx = 22: yyyyy 34: xxxxyyy 50: xxxxxxxxy = 23: rrrrr 35: xxxyyyy 51: xxxxxxxyy = 36: xxyyyyy 52: xxxxxxyyy = 37: xyyyyyy 53: xxxxxyyyy = 38: yyyyyyy 54: xxxxyyyyy = 39: rrrrrrr 55: xxxyyyyyy = 56: xxyyyyyyy = 57: xyyyyyyyy = 58: yyyyyyyyy = 59: rrrrrrrrr * * where r = sqrt(xx + yy). Note that even powers of r are excluded since they * can be accomodated by powers of (xx + yy). * * Note here that "x" refers to the axis to which the distortion function is * attached, with "y" being the complementary axis. So, for example, with * longitude on axis 1 and latitude on axis 2, for TPD attached to axis 1, "x" * refers to axis 1 and "y" to axis 2. For TPD attached to axis 2, "x" refers * to axis 2, and "y" to axis 1. * * TPV uses all terms up to 39. The m in its PVi_ma keywords translates * directly to the TPD coefficient number. * * SIP uses all terms except for 0, 3, 11, 23, 39, and 59, with terms 1 and 2 * only used for the inverse. Its A_p_q, etc. keywords must be translated * using a map. * * DSS uses terms 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 17, 19, and 21. The presence * of a non-zero constant term arises through the use of auxiliary variables * with origin offset from the reference point of the TAN projection. However, * in the translation given by WCS Paper IV, the distortion polynomial is zero, * or very close to zero, at the reference pixel itself. The mapping between * DSS's AMDXm (or AMDYm) keyvalues and TPD coefficients, while still simple, * is not quite as straightforward as for TPV and SIP. * * WAT uses all but the radial terms, namely 3, 11, 23, 39, and 59. While the * mapping between WAT's monomial coefficients and TPD is fairly simple, for * its expression in terms of a sum of Chebyshev or Legendre polynomials it is * much less so. * * Historical idiosyncrasies: * -------------------------- * In addition to the above, some historical distortion functions have further * idiosyncrasies that must be taken into account when translating them to TPD. * * WCS Paper IV specifies that a distortion function returns a correction to be * added to pixel coordinates (prior distortion) or intermediate pixel * coordinates (sequent distortion). The correction is meant to be small so * that ignoring the distortion function, i.e. setting the correction to zero, * produces a commensurately small error. * * However, rather than an additive correction, some historical distortion * functions (TPV, DSS) define a polynomial that returns the corrected * coordinates directly. * * The difference between the two approaches is readily accounted for simply by * adding or subtracting 1 from the coefficient of the first degree term of the * polynomial. However, it opens the way for considerable confusion. * * Additional to the formalism of WCS Paper IV, both the Polynomial and TPD * distortion functions recognise a keyword * = DPja = 'DOCORR: 0' * * which is meant to apply generally to indicate that the distortion function * returns the corrected coordinates directly. Any other value for DOCORR (or * its absence) indicates that the distortion function returns an additive * correction. * * WCS Paper IV also specifies that the independent variables of a distortion * function are pixel coordinates (prior distortion) or intermediate pixel * coordinates (sequent distortion). * * On the contrary, the independent variables of the SIP polynomial are pixel * coordinate offsets from the reference pixel. This is readily handled via * the renormalisation parameters * = DPja = 'OFFSET.jhat: ' * * where the value corresponds to CRPIXja. * * Likewise, because TPV, TNX, and ZPX are defined in terms of CDi_ja, the * independent variables of the polynomial are intermediate world coordinates * rather than intermediate pixel coordinates. Because sequent distortions * are always applied before CDELTia, if CDi_ja is translated to PCi_ja plus * CDELTia, then either CDELTia must be unity, or the distortion polynomial * coefficients must be adjusted to account for the change of scale. * * Summary of the dis routines: * ---------------------------- * These routines apply the distortion functions defined by the extension to * the FITS WCS standard proposed in Paper IV. They are based on the disprm * struct which contains all information needed for the computations. The * struct contains some members that must be set by the user, and others that * are maintained by these routines, somewhat like a C++ class but with no * encapsulation. * * dpfill(), dpkeyi(), and dpkeyd() are provided to manage the dpkey struct. * * disndp(), disini(), disinit(), discpy(), and disfree() are provided to * manage the disprm struct, dissize() computes its total size including * allocated memory, and disprt() prints its contents. * * disperr() prints the error message(s) (if any) stored in a disprm struct. * * wcshdo() normally writes SIP and TPV headers in their native form if at all * possible. However, dishdo() may be used to set a flag that tells it to * write the header in the form of the TPD translation used internally. * * A setup routine, disset(), computes intermediate values in the disprm struct * from parameters in it that were supplied by the user. The struct always * needs to be set up by disset(), though disset() need not be called * explicitly - refer to the explanation of disprm::flag. * * disp2x() and disx2p() implement the WCS distortion functions, disp2x() using * separate functions, such as dispoly() and tpd7(), to do the computation. * * An auxiliary routine, diswarp(), computes various measures of the distortion * over a specified range of coordinates. * * PLEASE NOTE: Distortions are not yet handled by wcsbth(), or wcscompare(). * * * disndp() - Memory allocation for DPja and DQia * ---------------------------------------------- * disndp() sets or gets the value of NDPMAX (default 256). This global * variable controls the maximum number of dpkey structs, for holding DPja or * DQia keyvalues, that disini() should allocate space for. It is also used by * disinit() as the default value of ndpmax. * * PLEASE NOTE: This function is not thread-safe. * * Given: * n int Value of NDPMAX; ignored if < 0. Use a value less * than zero to get the current value. * * Function return value: * int Current value of NDPMAX. * * * dpfill() - Fill the contents of a dpkey struct * ---------------------------------------------- * dpfill() is a utility routine to aid in filling the contents of the dpkey * struct. No checks are done on the validity of the inputs. * * WCS Paper IV specifies the syntax of a record-valued keyword as * = keyword = ': ' * * However, some DPja and DQia record values, such as those of DPja.NAXES and * DPja.AXIS.j, are intrinsically integer-valued. While FITS header parsers * are not expected to know in advance which of DPja and DQia are integral and * which are floating point, if the record's value parses as an integer (i.e. * without decimal point or exponent), then preferably enter it into the dpkey * struct as an integer. Either way, it doesn't matter as disset() accepts * either data type for all record values. * * Given and returned: * dp struct dpkey* * Store for DPja and DQia keyvalues. * * Given: * keyword const char * * field const char * * These arguments are concatenated with an intervening * "." to construct the full record field name, i.e. * including the keyword name, DPja or DQia (but * excluding the colon delimiter which is NOT part of the * name). Either may be given as a NULL pointer. Set * both NULL to omit setting this component of the * struct. * * j int Axis number (1-relative), i.e. the j in DPja or * i in DQia. Can be given as 0, in which case the axis * number will be obtained from the keyword component of * the field name which must either have been given or * preset. * * If j is non-zero, and keyword was given, then the * value of j will be used to fill in the axis number. * * type int Data type of the record's value * 0: Integer, * 1: Floating point. * * i int For type == 0, the integer value of the record. * * f double For type == 1, the floating point value of the record. * * Function return value: * int Status return value: * 0: Success. * * * dpkeyi() - Get the data value in a dpkey struct as int * ------------------------------------------------------ * dpkeyi() returns the data value in a dpkey struct as an integer value. * * Given and returned: * dp const struct dpkey * * Parsed contents of a DPja or DQia keyrecord. * * Function return value: * int The record's value as int. * * * dpkeyd() - Get the data value in a dpkey struct as double * --------------------------------------------------------- * dpkeyd() returns the data value in a dpkey struct as a floating point * value. * * Given and returned: * dp const struct dpkey * * Parsed contents of a DPja or DQia keyrecord. * * Function return value: * double The record's value as double. * * * disini() - Default constructor for the disprm struct * ---------------------------------------------------- * disini() is a thin wrapper on disinit(). It invokes it with ndpmax set * to -1 which causes it to use the value of the global variable NDPMAX. It * is thereby potentially thread-unsafe if NDPMAX is altered dynamically via * disndp(). Use disinit() for a thread-safe alternative in this case. * * * disinit() - Default constructor for the disprm struct * ---------------------------------------------------- * disinit() allocates memory for arrays in a disprm struct and sets all * members of the struct to default values. * * PLEASE NOTE: every disprm struct must be initialized by disinit(), possibly * repeatedly. On the first invokation, and only the first invokation, * disprm::flag must be set to -1 to initialize memory management, regardless * of whether disinit() will actually be used to allocate memory. * * Given: * alloc int If true, allocate memory unconditionally for arrays in * the disprm struct. * * If false, it is assumed that pointers to these arrays * have been set by the user except if they are null * pointers in which case memory will be allocated for * them regardless. (In other words, setting alloc true * saves having to initalize these pointers to zero.) * * naxis int The number of world coordinate axes, used to determine * array sizes. * * Given and returned: * dis struct disprm* * Distortion function parameters. Note that, in order * to initialize memory management disprm::flag must be * set to -1 when dis is initialized for the first time * (memory leaks may result if it had already been * initialized). * * Given: * ndpmax int The number of DPja or DQia keywords to allocate space * for. If set to -1, the value of the global variable * NDPMAX will be used. This is potentially * thread-unsafe if disndp() is being used dynamically to * alter its value. * * Function return value: * int Status return value: * 0: Success. * 1: Null disprm pointer passed. * 2: Memory allocation failed. * * For returns > 1, a detailed error message is set in * disprm::err if enabled, see wcserr_enable(). * * * discpy() - Copy routine for the disprm struct * --------------------------------------------- * discpy() does a deep copy of one disprm struct to another, using disinit() * to allocate memory unconditionally for its arrays if required. Only the * "information to be provided" part of the struct is copied; a call to * disset() is required to initialize the remainder. * * Given: * alloc int If true, allocate memory unconditionally for arrays in * the destination. Otherwise, it is assumed that * pointers to these arrays have been set by the user * except if they are null pointers in which case memory * will be allocated for them regardless. * * dissrc const struct disprm* * Struct to copy from. * * Given and returned: * disdst struct disprm* * Struct to copy to. disprm::flag should be set to -1 * if disdst was not previously initialized (memory leaks * may result if it was previously initialized). * * Function return value: * int Status return value: * 0: Success. * 1: Null disprm pointer passed. * 2: Memory allocation failed. * * For returns > 1, a detailed error message is set in * disprm::err if enabled, see wcserr_enable(). * * * disfree() - Destructor for the disprm struct * -------------------------------------------- * disfree() frees memory allocated for the disprm arrays by disinit(). * disinit() keeps a record of the memory it allocates and disfree() will only * attempt to free this. * * PLEASE NOTE: disfree() must not be invoked on a disprm struct that was not * initialized by disinit(). * * Given: * dis struct disprm* * Distortion function parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null disprm pointer passed. * * * dissize() - Compute the size of a disprm struct * ----------------------------------------------- * dissize() computes the full size of a disprm struct, including allocated * memory. * * Given: * dis const struct disprm* * Distortion function parameters. * * If NULL, the base size of the struct and the allocated * size are both set to zero. * * Returned: * sizes int[2] The first element is the base size of the struct as * returned by sizeof(struct disprm). The second element * is the total allocated size, in bytes, assuming that * the allocation was done by disini(). This figure * includes memory allocated for members of constituent * structs, such as disprm::dp. * * It is not an error for the struct not to have been set * up via tabset(), which normally results in additional * memory allocation. * * Function return value: * int Status return value: * 0: Success. * * * disprt() - Print routine for the disprm struct * ---------------------------------------------- * disprt() prints the contents of a disprm struct using wcsprintf(). Mainly * intended for diagnostic purposes. * * Given: * dis const struct disprm* * Distortion function parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null disprm pointer passed. * * * disperr() - Print error messages from a disprm struct * ----------------------------------------------------- * disperr() prints the error message(s) (if any) stored in a disprm struct. * If there are no errors then nothing is printed. It uses wcserr_prt(), q.v. * * Given: * dis const struct disprm* * Distortion function parameters. * * prefix const char * * If non-NULL, each output line will be prefixed with * this string. * * Function return value: * int Status return value: * 0: Success. * 1: Null disprm pointer passed. * * * dishdo() - write FITS headers using TPD * --------------------------------------- * dishdo() sets a flag that tells wcshdo() to write FITS headers in the form * of the TPD translation used internally. Normally SIP and TPV would be * written in their native form if at all possible. * * Given and returned: * dis struct disprm* * Distortion function parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null disprm pointer passed. * 3: No TPD translation. * * * disset() - Setup routine for the disprm struct * ---------------------------------------------- * disset(), sets up the disprm struct according to information supplied within * it - refer to the explanation of disprm::flag. * * Note that this routine need not be called directly; it will be invoked by * disp2x() and disx2p() if the disprm::flag is anything other than a * predefined magic value. * * Given and returned: * dis struct disprm* * Distortion function parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null disprm pointer passed. * 2: Memory allocation failed. * 3: Invalid parameter. * * For returns > 1, a detailed error message is set in * disprm::err if enabled, see wcserr_enable(). * * * disp2x() - Apply distortion function * ------------------------------------ * disp2x() applies the distortion functions. By definition, the distortion * is in the pixel-to-world direction. * * Depending on the point in the algorithm chain at which it is invoked, * disp2x() may transform pixel coordinates to corrected pixel coordinates, or * intermediate pixel coordinates to corrected intermediate pixel coordinates, * or image coordinates to corrected image coordinates. * * * Given and returned: * dis struct disprm* * Distortion function parameters. * * Given: * rawcrd const double[naxis] * Array of coordinates. * * Returned: * discrd double[naxis] * Array of coordinates to which the distortion functions * have been applied. * * Function return value: * int Status return value: * 0: Success. * 1: Null disprm pointer passed. * 2: Memory allocation failed. * 3: Invalid parameter. * 4: Distort error. * * For returns > 1, a detailed error message is set in * disprm::err if enabled, see wcserr_enable(). * * * disx2p() - Apply de-distortion function * --------------------------------------- * disx2p() applies the inverse of the distortion functions. By definition, * the de-distortion is in the world-to-pixel direction. * * Depending on the point in the algorithm chain at which it is invoked, * disx2p() may transform corrected pixel coordinates to pixel coordinates, or * corrected intermediate pixel coordinates to intermediate pixel coordinates, * or corrected image coordinates to image coordinates. * * disx2p() iteratively solves for the inverse using disp2x(). It assumes * that the distortion is small and the functions are well-behaved, being * continuous and with continuous derivatives. Also that, to first order * in the neighbourhood of the solution, discrd[j] ~= a + b*rawcrd[j], i.e. * independent of rawcrd[i], where i != j. This is effectively equivalent to * assuming that the distortion functions are separable to first order. * Furthermore, a is assumed to be small, and b close to unity. * * If disprm::disx2p() is defined, then disx2p() uses it to provide an initial * estimate for its more precise iterative inversion. * * Given and returned: * dis struct disprm* * Distortion function parameters. * * Given: * discrd const double[naxis] * Array of coordinates. * * Returned: * rawcrd double[naxis] * Array of coordinates to which the inverse distortion * functions have been applied. * * Function return value: * int Status return value: * 0: Success. * 1: Null disprm pointer passed. * 2: Memory allocation failed. * 3: Invalid parameter. * 5: De-distort error. * * For returns > 1, a detailed error message is set in * disprm::err if enabled, see wcserr_enable(). * * * diswarp() - Compute measures of distortion * ------------------------------------------ * diswarp() computes various measures of the distortion over a specified range * of coordinates. * * For prior distortions, the measures may be interpreted simply as an offset * in pixel coordinates. For sequent distortions, the interpretation depends * on the nature of the linear transformation matrix (PCi_ja or CDi_ja). If * the latter introduces a scaling, then the measures will also be scaled. * Note also that the image domain, which is rectangular in pixel coordinates, * may be rotated, skewed, and/or stretched in intermediate pixel coordinates, * and in general cannot be defined using pixblc[] and pixtrc[]. * * PLEASE NOTE: the measures of total distortion may be essentially meaningless * if there are multiple sequent distortions with different scaling. * * See also linwarp(). * * Given and returned: * dis struct disprm* * Distortion function parameters. * * Given: * pixblc const double[naxis] * Start of the range of pixel coordinates (for prior * distortions), or intermediate pixel coordinates (for * sequent distortions). May be specified as a NULL * pointer which is interpreted as (1,1,...). * * pixtrc const double[naxis] * End of the range of pixel coordinates (prior) or * intermediate pixel coordinates (sequent). * * pixsamp const double[naxis] * If positive or zero, the increment on the particular * axis, starting at pixblc[]. Zero is interpreted as a * unit increment. pixsamp may also be specified as a * NULL pointer which is interpreted as all zeroes, i.e. * unit increments on all axes. * * If negative, the grid size on the particular axis (the * absolute value being rounded to the nearest integer). * For example, if pixsamp is (-128.0,-128.0,...) then * each axis will be sampled at 128 points between * pixblc[] and pixtrc[] inclusive. Use caution when * using this option on non-square images. * * Returned: * nsamp int* The number of pixel coordinates sampled. * * Can be specified as a NULL pointer if not required. * * maxdis double[naxis] * For each individual distortion function, the * maximum absolute value of the distortion. * * Can be specified as a NULL pointer if not required. * * maxtot double* For the combination of all distortion functions, the * maximum absolute value of the distortion. * * Can be specified as a NULL pointer if not required. * * avgdis double[naxis] * For each individual distortion function, the * mean value of the distortion. * * Can be specified as a NULL pointer if not required. * * avgtot double* For the combination of all distortion functions, the * mean value of the distortion. * * Can be specified as a NULL pointer if not required. * * rmsdis double[naxis] * For each individual distortion function, the * root mean square deviation of the distortion. * * Can be specified as a NULL pointer if not required. * * rmstot double* For the combination of all distortion functions, the * root mean square deviation of the distortion. * * Can be specified as a NULL pointer if not required. * * Function return value: * int Status return value: * 0: Success. * 1: Null disprm pointer passed. * 2: Memory allocation failed. * 3: Invalid parameter. * 4: Distort error. * * * disprm struct - Distortion parameters * ------------------------------------- * The disprm struct contains all of the information required to apply a set of * distortion functions. It consists of certain members that must be set by * the user ("given") and others that are set by the WCSLIB routines * ("returned"). While the addresses of the arrays themselves may be set by * disinit() if it (optionally) allocates memory, their contents must be set by * the user. * * int flag * (Given and returned) This flag must be set to zero whenever any of the * following members of the disprm struct are set or modified: * * - disprm::naxis, * - disprm::dtype, * - disprm::ndp, * - disprm::dp. * * This signals the initialization routine, disset(), to recompute the * returned members of the disprm struct. disset() will reset flag to * indicate that this has been done. * * PLEASE NOTE: flag must be set to -1 when disinit() is called for the * first time for a particular disprm struct in order to initialize memory * management. It must ONLY be used on the first initialization otherwise * memory leaks may result. * * int naxis * (Given or returned) Number of pixel and world coordinate elements. * * If disinit() is used to initialize the disprm struct (as would normally * be the case) then it will set naxis from the value passed to it as a * function argument. The user should not subsequently modify it. * * char (*dtype)[72] * (Given) Pointer to the first element of an array of char[72] containing * the name of the distortion function for each axis. * * int ndp * (Given) The number of entries in the disprm::dp[] array. * * int ndpmax * (Given) The length of the disprm::dp[] array. * * ndpmax will be set by disinit() if it allocates memory for disprm::dp[], * otherwise it must be set by the user. See also disndp(). * * struct dpkey dp * (Given) Address of the first element of an array of length ndpmax of * dpkey structs. * * As a FITS header parser encounters each DPja or DQia keyword it should * load it into a dpkey struct in the array and increment ndp. However, * note that a single disprm struct must hold only DPja or DQia keyvalues, * not both. disset() interprets them as required by the particular * distortion function. * * double *maxdis * (Given) Pointer to the first element of an array of double specifying * the maximum absolute value of the distortion for each axis computed over * the whole image. * * It is not necessary to reset the disprm struct (via disset()) when * disprm::maxdis is changed. * * double totdis * (Given) The maximum absolute value of the combination of all distortion * functions specified as an offset in pixel coordinates computed over the * whole image. * * It is not necessary to reset the disprm struct (via disset()) when * disprm::totdis is changed. * * int *docorr * (Returned) Pointer to the first element of an array of int containing * flags that indicate the mode of correction for each axis. * * If docorr is zero, the distortion function returns the corrected * coordinates directly. Any other value indicates that the distortion * function computes a correction to be added to pixel coordinates (prior * distortion) or intermediate pixel coordinates (sequent distortion). * * int *Nhat * (Returned) Pointer to the first element of an array of int containing * the number of coordinate axes that form the independent variables of the * distortion function for each axis. * * int **axmap * (Returned) Pointer to the first element of an array of int* containing * pointers to the first elements of the axis mapping arrays for each axis. * * An axis mapping associates the independent variables of a distortion * function with the 0-relative image axis number. For example, consider * an image with a spectrum on the first axis (axis 0), followed by RA * (axis 1), Dec (axis2), and time (axis 3) axes. For a distortion in * (RA,Dec) and no distortion on the spectral or time axes, the axis * mapping arrays, axmap[j][], would be * = j=0: [-1, -1, -1, -1] ...no distortion on spectral axis, = 1: [ 1, 2, -1, -1] ...RA distortion depends on RA and Dec, = 2: [ 2, 1, -1, -1] ...Dec distortion depends on Dec and RA, = 3: [-1, -1, -1, -1] ...no distortion on time axis, * * where -1 indicates that there is no corresponding independent * variable. * * double **offset * (Returned) Pointer to the first element of an array of double* * containing pointers to the first elements of arrays of offsets used to * renormalize the independent variables of the distortion function for * each axis. * * The offsets are subtracted from the independent variables before * scaling. * * double **scale * (Returned) Pointer to the first element of an array of double* * containing pointers to the first elements of arrays of scales used to * renormalize the independent variables of the distortion function for * each axis. * * The scale is applied to the independent variables after the offsets are * subtracted. * * int **iparm * (Returned) Pointer to the first element of an array of int* * containing pointers to the first elements of the arrays of integer * distortion parameters for each axis. * * double **dparm * (Returned) Pointer to the first element of an array of double* * containing pointers to the first elements of the arrays of floating * point distortion parameters for each axis. * * int i_naxis * (Returned) Dimension of the internal arrays (normally equal to naxis). * * int ndis * (Returned) The number of distortion functions. * * struct wcserr *err * (Returned) If enabled, when an error status is returned, this struct * contains detailed information about the error, see wcserr_enable(). * * int (**disp2x)(DISP2X_ARGS) * (For internal use only.) * int (**disx2p)(DISX2P_ARGS) * (For internal use only.) * double *tmpmem * (For internal use only.) * int m_flag * (For internal use only.) * int m_naxis * (For internal use only.) * char (*m_dtype)[72] * (For internal use only.) * double **m_dp * (For internal use only.) * double *m_maxdis * (For internal use only.) * * * dpkey struct - Store for DPja and DQia keyvalues * ------------------------------------------------ * The dpkey struct is used to pass the parsed contents of DPja or DQia * keyrecords to disset() via the disprm struct. A disprm struct must hold * only DPja or DQia keyvalues, not both. * * All members of this struct are to be set by the user. * * char field[72] * (Given) The full field name of the record, including the keyword name. * Note that the colon delimiter separating the field name and the value in * record-valued keyvalues is not part of the field name. For example, in * the following: * = DP3A = 'AXIS.1: 2' * * the full record field name is "DP3A.AXIS.1", and the record's value * is 2. * * int j * (Given) Axis number (1-relative), i.e. the j in DPja or i in DQia. * * int type * (Given) The data type of the record's value * - 0: Integer (stored as an int), * - 1: Floating point (stored as a double). * * union value * (Given) A union comprised of * - dpkey::i, * - dpkey::f, * * the record's value. * * * Global variable: const char *dis_errmsg[] - Status return messages * ------------------------------------------------------------------ * Error messages to match the status value returned from each function. * *===========================================================================*/ #ifndef WCSLIB_DIS #define WCSLIB_DIS #ifdef __cplusplus extern "C" { #endif extern const char *dis_errmsg[]; enum dis_errmsg_enum { DISERR_SUCCESS = 0, // Success. DISERR_NULL_POINTER = 1, // Null disprm pointer passed. DISERR_MEMORY = 2, // Memory allocation failed. DISERR_BAD_PARAM = 3, // Invalid parameter value. DISERR_DISTORT = 4, // Distortion error. DISERR_DEDISTORT = 5 // De-distortion error. }; // For use in declaring distortion function prototypes (= DISX2P_ARGS). #define DISP2X_ARGS int inverse, const int iparm[], const double dparm[], \ int ncrd, const double rawcrd[], double *discrd // For use in declaring de-distortion function prototypes (= DISP2X_ARGS). #define DISX2P_ARGS int inverse, const int iparm[], const double dparm[], \ int ncrd, const double discrd[], double *rawcrd // Struct used for storing DPja and DQia keyvalues. struct dpkey { char field[72]; // Full record field name (no colon). int j; // Axis number, as in DPja (1-relative). int type; // Data type of value. union { int i; // Integer record value. double f; // Floating point record value. } value; // Record value. }; // Size of the dpkey struct in int units, used by the Fortran wrappers. #define DPLEN (sizeof(struct dpkey)/sizeof(int)) struct disprm { // Initialization flag (see the prologue above). //-------------------------------------------------------------------------- int flag; // Set to zero to force initialization. // Parameters to be provided (see the prologue above). //-------------------------------------------------------------------------- int naxis; // The number of pixel coordinate elements, // given by NAXIS. char (*dtype)[72]; // For each axis, the distortion type. int ndp; // Number of DPja or DQia keywords, and the int ndpmax; // number for which space was allocated. struct dpkey *dp; // DPja or DQia keyvalues (not both). double *maxdis; // For each axis, the maximum distortion. double totdis; // The maximum combined distortion. // Information derived from the parameters supplied. //-------------------------------------------------------------------------- int *docorr; // For each axis, the mode of correction. int *Nhat; // For each axis, the number of coordinate // axes that form the independent variables // of the distortion function. int **axmap; // For each axis, the axis mapping array. double **offset; // For each axis, renormalization offsets. double **scale; // For each axis, renormalization scales. int **iparm; // For each axis, the array of integer // distortion parameters. double **dparm; // For each axis, the array of floating // point distortion parameters. int i_naxis; // Dimension of the internal arrays. int ndis; // The number of distortion functions. // Error handling, if enabled. //-------------------------------------------------------------------------- struct wcserr *err; // Private - the remainder are for internal use. //-------------------------------------------------------------------------- int (**disp2x)(DISP2X_ARGS); // For each axis, pointers to the int (**disx2p)(DISX2P_ARGS); // distortion function and its inverse. double *tmpmem; int m_flag, m_naxis; // The remainder are for memory management. char (*m_dtype)[72]; struct dpkey *m_dp; double *m_maxdis; }; // Size of the disprm struct in int units, used by the Fortran wrappers. #define DISLEN (sizeof(struct disprm)/sizeof(int)) int disndp(int n); int dpfill(struct dpkey *dp, const char *keyword, const char *field, int j, int type, int i, double f); int dpkeyi(const struct dpkey *dp); double dpkeyd(const struct dpkey *dp); int disini(int alloc, int naxis, struct disprm *dis); int disinit(int alloc, int naxis, struct disprm *dis, int ndpmax); int discpy(int alloc, const struct disprm *dissrc, struct disprm *disdst); int disfree(struct disprm *dis); int dissize(const struct disprm *dis, int sizes[2]); int disprt(const struct disprm *dis); int disperr(const struct disprm *dis, const char *prefix); int dishdo(struct disprm *dis); int disset(struct disprm *dis); int disp2x(struct disprm *dis, const double rawcrd[], double discrd[]); int disx2p(struct disprm *dis, const double discrd[], double rawcrd[]); int diswarp(struct disprm *dis, const double pixblc[], const double pixtrc[], const double pixsamp[], int *nsamp, double maxdis[], double *maxtot, double avgdis[], double *avgtot, double rmsdis[], double *rmstot); #ifdef __cplusplus } #endif #endif // WCSLIB_DIS ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/fitshdr.h0000644000175100001710000004303700000000000017205 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: fitshdr.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the fitshdr routines * ------------------------------- * The Flexible Image Transport System (FITS), is a data format widely used in * astronomy for data interchange and archive. It is described in * = "Definition of the Flexible Image Transport System (FITS), version 3.0", = Pence, W.D., Chiappetti, L., Page, C.G., Shaw, R.A., & Stobie, E. 2010, = A&A, 524, A42 - http://dx.doi.org/10.1051/0004-6361/201015362 * * See also http://fits.gsfc.nasa.gov * * fitshdr() is a generic FITS header parser provided to handle keyrecords that * are ignored by the WCS header parsers, wcspih() and wcsbth(). Typically the * latter may be set to remove WCS keyrecords from a header leaving fitshdr() * to handle the remainder. * * * fitshdr() - FITS header parser routine * -------------------------------------- * fitshdr() parses a character array containing a FITS header, extracting * all keywords and their values into an array of fitskey structs. * * Given: * header const char [] * Character array containing the (entire) FITS header, * for example, as might be obtained conveniently via the * CFITSIO routine fits_hdr2str(). * * Each header "keyrecord" (formerly "card image") * consists of exactly 80 7-bit ASCII printing characters * in the range 0x20 to 0x7e (which excludes NUL, BS, * TAB, LF, FF and CR) especially noting that the * keyrecords are NOT null-terminated. * * nkeyrec int Number of keyrecords in header[]. * * nkeyids int Number of entries in keyids[]. * * Given and returned: * keyids struct fitskeyid [] * While all keywords are extracted from the header, * keyids[] provides a convienient way of indexing them. * The fitskeyid struct contains three members; * fitskeyid::name must be set by the user while * fitskeyid::count and fitskeyid::idx are returned by * fitshdr(). All matched keywords will have their * fitskey::keyno member negated. * * Returned: * nreject int* Number of header keyrecords rejected for syntax * errors. * * keys struct fitskey** * Pointer to an array of nkeyrec fitskey structs * containing all keywords and keyvalues extracted from * the header. * * Memory for the array is allocated by fitshdr() and * this must be freed by the user. See wcsdealloc(). * * Function return value: * int Status return value: * 0: Success. * 1: Null fitskey pointer passed. * 2: Memory allocation failed. * 3: Fatal error returned by Flex parser. * 4: Unrecognised data type. * * Notes: * 1: Keyword parsing is done in accordance with the syntax defined by * NOST 100-2.0, noting the following points in particular: * * a: Sect. 5.1.2.1 specifies that keywords be left-justified in columns * 1-8, blank-filled with no embedded spaces, composed only of the * ASCII characters ABCDEFGHJKLMNOPQRSTUVWXYZ0123456789-_ * * fitshdr() accepts any characters in columns 1-8 but flags keywords * that do not conform to standard syntax. * * b: Sect. 5.1.2.2 defines the "value indicator" as the characters "= " * occurring in columns 9 and 10. If these are absent then the * keyword has no value and columns 9-80 may contain any ASCII text * (but see note 2 for CONTINUE keyrecords). This is copied to the * comment member of the fitskey struct. * * c: Sect. 5.1.2.3 states that a keyword may have a null (undefined) * value if the value/comment field, columns 11-80, consists entirely * of spaces, possibly followed by a comment. * * d: Sect. 5.1.1 states that trailing blanks in a string keyvalue are * not significant and the parser always removes them. A string * containing nothing but blanks will be replaced with a single * blank. * * Sect. 5.2.1 also states that a quote character (') in a string * value is to be represented by two successive quote characters and * the parser removes the repeated quote. * * e: The parser recognizes free-format character (NOST 100-2.0, * Sect. 5.2.1), integer (Sect. 5.2.3), and floating-point values * (Sect. 5.2.4) for all keywords. * * f: Sect. 5.2.3 offers no comment on the size of an integer keyvalue * except indirectly in limiting it to 70 digits. The parser will * translate an integer keyvalue to a 32-bit signed integer if it * lies in the range -2147483648 to +2147483647, otherwise it * interprets it as a 64-bit signed integer if possible, or else a * "very long" integer (see fitskey::type). * * g: END not followed by 77 blanks is not considered to be a legitimate * end keyrecord. * * 2: The parser supports a generalization of the OGIP Long String Keyvalue * Convention (v1.0) whereby strings may be continued onto successive * header keyrecords. A keyrecord contains a segment of a continued * string if and only if * * a: it contains the pseudo-keyword CONTINUE, * * b: columns 9 and 10 are both blank, * * c: columns 11 to 80 contain what would be considered a valid string * keyvalue, including optional keycomment, if column 9 had contained * '=', * * d: the previous keyrecord contained either a valid string keyvalue or * a valid CONTINUE keyrecord. * * If any of these conditions is violated, the keyrecord is considered in * isolation. * * Syntax errors in keycomments in a continued string are treated more * permissively than usual; the '/' delimiter may be omitted provided that * parsing of the string keyvalue is not compromised. However, the * FITSHDR_COMMENT status bit will be set for the keyrecord (see * fitskey::status). * * As for normal strings, trailing blanks in a continued string are not * significant. * * In the OGIP convention "the '&' character is used as the last non-blank * character of the string to indicate that the string is (probably) * continued on the following keyword". This additional syntax is not * required by fitshdr(), but if '&' does occur as the last non-blank * character of a continued string keyvalue then it will be removed, along * with any trailing blanks. However, blanks that occur before the '&' * will be preserved. * * * fitskeyid struct - Keyword indexing * ----------------------------------- * fitshdr() uses the fitskeyid struct to return indexing information for * specified keywords. The struct contains three members, the first of which, * fitskeyid::name, must be set by the user with the remainder returned by * fitshdr(). * * char name[12]: * (Given) Name of the required keyword. This is to be set by the user; * the '.' character may be used for wildcarding. Trailing blanks will be * replaced with nulls. * * int count: * (Returned) The number of matches found for the keyword. * * int idx[2]: * (Returned) Indices into keys[], the array of fitskey structs returned by * fitshdr(). Note that these are 0-relative array indices, not keyrecord * numbers. * * If the keyword is found in the header the first index will be set to the * array index of its first occurrence, otherwise it will be set to -1. * * If multiples of the keyword are found, the second index will be set to * the array index of its last occurrence, otherwise it will be set to -1. * * * fitskey struct - Keyword/value information * ------------------------------------------ * fitshdr() returns an array of fitskey structs, each of which contains the * result of parsing one FITS header keyrecord. All members of the fitskey * struct are returned by fitshdr(), none are given by the user. * * int keyno * (Returned) Keyrecord number (1-relative) in the array passed as input to * fitshdr(). This will be negated if the keyword matched any specified in * the keyids[] index. * * int keyid * (Returned) Index into the first entry in keyids[] with which the * keyrecord matches, else -1. * * int status * (Returned) Status flag bit-vector for the header keyrecord employing the * following bit masks defined as preprocessor macros: * * - FITSHDR_KEYWORD: Illegal keyword syntax. * - FITSHDR_KEYVALUE: Illegal keyvalue syntax. * - FITSHDR_COMMENT: Illegal keycomment syntax. * - FITSHDR_KEYREC: Illegal keyrecord, e.g. an END keyrecord with * trailing text. * - FITSHDR_TRAILER: Keyrecord following a valid END keyrecord. * * The header keyrecord is syntactically correct if no bits are set. * * char keyword[12] * (Returned) Keyword name, null-filled for keywords of less than eight * characters (trailing blanks replaced by nulls). * * Use * = sprintf(dst, "%.8s", keyword) * * to copy it to a character array with null-termination, or * = sprintf(dst, "%8.8s", keyword) * * to blank-fill to eight characters followed by null-termination. * * int type * (Returned) Keyvalue data type: * - 0: No keyvalue (both the value and type are undefined). * - 1: Logical, represented as int. * - 2: 32-bit signed integer. * - 3: 64-bit signed integer (see below). * - 4: Very long integer (see below). * - 5: Floating point (stored as double). * - 6: Integer complex (stored as double[2]). * - 7: Floating point complex (stored as double[2]). * - 8: String. * - 8+10*n: Continued string (described below and in fitshdr() note 2). * * A negative type indicates that a syntax error was encountered when * attempting to parse a keyvalue of the particular type. * * Comments on particular data types: * - 64-bit signed integers lie in the range * = (-9223372036854775808 <= int64 < -2147483648) || = (+2147483647 < int64 <= +9223372036854775807) * * A native 64-bit data type may be defined via preprocessor macro * WCSLIB_INT64 defined in wcsconfig.h, e.g. as 'long long int'; this * will be typedef'd to 'int64' here. If WCSLIB_INT64 is not set, then * int64 is typedef'd to int[3] instead and fitskey::keyvalue is to be * computed as * = ((keyvalue.k[2]) * 1000000000 + = keyvalue.k[1]) * 1000000000 + = keyvalue.k[0] * * and may reported via * = if (keyvalue.k[2]) { = printf("%d%09d%09d", keyvalue.k[2], abs(keyvalue.k[1]), = abs(keyvalue.k[0])); = } else { = printf("%d%09d", keyvalue.k[1], abs(keyvalue.k[0])); = } * * where keyvalue.k[0] and keyvalue.k[1] range from -999999999 to * +999999999. * * - Very long integers, up to 70 decimal digits in length, are encoded * in keyvalue.l as an array of int[8], each of which stores 9 decimal * digits. fitskey::keyvalue is to be computed as * = (((((((keyvalue.l[7]) * 1000000000 + = keyvalue.l[6]) * 1000000000 + = keyvalue.l[5]) * 1000000000 + = keyvalue.l[4]) * 1000000000 + = keyvalue.l[3]) * 1000000000 + = keyvalue.l[2]) * 1000000000 + = keyvalue.l[1]) * 1000000000 + = keyvalue.l[0] * * - Continued strings are not reconstructed, they remain split over * successive fitskey structs in the keys[] array returned by * fitshdr(). fitskey::keyvalue data type, 8 + 10n, indicates the * segment number, n, in the continuation. * * int padding * (An unused variable inserted for alignment purposes only.) * * union keyvalue * (Returned) A union comprised of * * - fitskey::i, * - fitskey::k, * - fitskey::l, * - fitskey::f, * - fitskey::c, * - fitskey::s, * * used by the fitskey struct to contain the value associated with a * keyword. * * int i * (Returned) Logical (fitskey::type == 1) and 32-bit signed integer * (fitskey::type == 2) data types in the fitskey::keyvalue union. * * int64 k * (Returned) 64-bit signed integer (fitskey::type == 3) data type in the * fitskey::keyvalue union. * * int l[8] * (Returned) Very long integer (fitskey::type == 4) data type in the * fitskey::keyvalue union. * * double f * (Returned) Floating point (fitskey::type == 5) data type in the * fitskey::keyvalue union. * * double c[2] * (Returned) Integer and floating point complex (fitskey::type == 6 || 7) * data types in the fitskey::keyvalue union. * * char s[72] * (Returned) Null-terminated string (fitskey::type == 8) data type in the * fitskey::keyvalue union. * * int ulen * (Returned) Where a keycomment contains a units string in the standard * form, e.g. [m/s], the ulen member indicates its length, inclusive of * square brackets. Otherwise ulen is zero. * * char comment[84] * (Returned) Keycomment, i.e. comment associated with the keyword or, for * keyrecords rejected because of syntax errors, the compete keyrecord * itself with null-termination. * * Comments are null-terminated with trailing spaces removed. Leading * spaces are also removed from keycomments (i.e. those immediately * following the '/' character), but not from COMMENT or HISTORY keyrecords * or keyrecords without a value indicator ("= " in columns 9-80). * * * Global variable: const char *fitshdr_errmsg[] - Status return messages * ---------------------------------------------------------------------- * Error messages to match the status value returned from each function. * *===========================================================================*/ #ifndef WCSLIB_FITSHDR #define WCSLIB_FITSHDR #include "wcsconfig.h" #ifdef __cplusplus extern "C" { #endif #define FITSHDR_KEYWORD 0x01 #define FITSHDR_KEYVALUE 0x02 #define FITSHDR_COMMENT 0x04 #define FITSHDR_KEYREC 0x08 #define FITSHDR_CARD 0x08 // Alias for backwards compatibility. #define FITSHDR_TRAILER 0x10 extern const char *fitshdr_errmsg[]; enum fitshdr_errmsg_enum { FITSHDRERR_SUCCESS = 0, // Success. FITSHDRERR_NULL_POINTER = 1, // Null fitskey pointer passed. FITSHDRERR_MEMORY = 2, // Memory allocation failed. FITSHDRERR_FLEX_PARSER = 3, // Fatal error returned by Flex parser. FITSHDRERR_DATA_TYPE = 4 // Unrecognised data type. }; #ifdef WCSLIB_INT64 typedef WCSLIB_INT64 int64; #else typedef int int64[3]; #endif // Struct used for indexing the keywords. struct fitskeyid { char name[12]; // Keyword name, null-terminated. int count; // Number of occurrences of keyword. int idx[2]; // Indices into fitskey array. }; // Size of the fitskeyid struct in int units, used by the Fortran wrappers. #define KEYIDLEN (sizeof(struct fitskeyid)/sizeof(int)) // Struct used for storing FITS keywords. struct fitskey { int keyno; // Header keyrecord sequence number (1-rel). int keyid; // Index into fitskeyid[]. int status; // Header keyrecord status bit flags. char keyword[12]; // Keyword name, null-filled. int type; // Keyvalue type (see above). int padding; // (Dummy inserted for alignment purposes.) union { int i; // 32-bit integer and logical values. int64 k; // 64-bit integer values. int l[8]; // Very long signed integer values. double f; // Floating point values. double c[2]; // Complex values. char s[72]; // String values, null-terminated. } keyvalue; // Keyvalue. int ulen; // Length of units string. char comment[84]; // Comment (or keyrecord), null-terminated. }; // Size of the fitskey struct in int units, used by the Fortran wrappers. #define KEYLEN (sizeof(struct fitskey)/sizeof(int)) int fitshdr(const char header[], int nkeyrec, int nkeyids, struct fitskeyid keyids[], int *nreject, struct fitskey **keys); #ifdef __cplusplus } #endif #endif // WCSLIB_FITSHDR ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/fitshdr.l0000644000175100001710000003360400000000000017210 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: fitshdr.l,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * fitshdr.l is a Flex description file containing a lexical scanner * definition for extracting keywords and keyvalues from a FITS header. * * It requires Flex v2.5.4 or later. * * Refer to fitshdr.h for a description of the user interface and operating * notes. * *===========================================================================*/ /* Options. */ %option full %option never-interactive %option noinput %option nounput %option noyywrap %option outfile="fitshdr.c" %option prefix="fitshdr" %option reentrant %option extra-type="struct fitshdr_extra *" /* Keywords. */ KEYCHR [-_A-Z0-9] KW1 {KEYCHR}{1}" "{7} KW2 {KEYCHR}{2}" "{6} KW3 {KEYCHR}{3}" "{5} KW4 {KEYCHR}{4}" "{4} KW5 {KEYCHR}{5}" "{3} KW6 {KEYCHR}{6}" "{2} KW7 {KEYCHR}{7}" "{1} KW8 {KEYCHR}{8} KEYWORD ({KW1}|{KW2}|{KW3}|{KW4}|{KW5}|{KW6}|{KW7}|{KW8}) /* Keyvalue data types. */ LOGICAL [TF] INT32 [+-]?0*[0-9]{1,9} INT64 [+-]?0*[0-9]{10,18} INTVL [+-]?0*[0-9]{19,} INTEGER [+-]?[0-9]+ FLOAT [+-]?([0-9]+\.?[0-9]*|\.[0-9]+)([eEdD][+-]?[0-9]+)? ICOMPLX \(" "*{INTEGER}" "*," "*{INTEGER}" "*\) FCOMPLX \(" "*{FLOAT}" "*," "*{FLOAT}" "*\) STRING '([^']|'')*' /* Characters forming standard unit strings (jwBIQX are not used). */ UNITSTR \[[-+*/^(). 0-9a-zA-Z]+\] /* Exclusive start states. */ %x VALUE INLINE UNITS COMMENT ERROR FLUSH %{ #include #include #include #include #include #include "fitshdr.h" #include "wcsutil.h" // User data associated with yyscanner. struct fitshdr_extra { // Values passed to YY_INPUT. const char *hdr; int nkeyrec; // Used in preempting the call to exit() by yy_fatal_error(). jmp_buf abort_jmp_env; }; #define YY_DECL int fitshdr_scanner(const char header[], int nkeyrec, \ int nkeyids, struct fitskeyid keyids[], int *nreject, \ struct fitskey **keys, yyscan_t yyscanner) #define YY_INPUT(inbuff, count, bufsize) \ { \ if (yyextra->nkeyrec) { \ strncpy(inbuff, yyextra->hdr, 80); \ inbuff[80] = '\n'; \ yyextra->hdr += 80; \ yyextra->nkeyrec--; \ count = 81; \ } else { \ count = YY_NULL; \ } \ } // Preempt the call to exit() by yy_fatal_error(). #define exit(status) longjmp(yyextra->abort_jmp_env, status); // Internal helper functions. static YY_DECL; static void nullfill(char cptr[], int len); // Map status return value to message. const char *fitshdr_errmsg[] = { "Success", "Null fitskey pointer-pointer passed", "Memory allocation failed", "Fatal error returned by Flex parser"}; %} %% char ctmp[72]; if (keys == 0x0) { return FITSHDRERR_NULL_POINTER; } // Allocate memory for the required number of fitskey structs. // Recall that calloc() initializes allocated memory to zero. struct fitskey *kptr; if (!(kptr = *keys = calloc(nkeyrec, sizeof(struct fitskey)))) { return FITSHDRERR_MEMORY; } // Initialize returned values. *nreject = 0; // Initialize keyids[]. struct fitskeyid *iptr = keyids; for (int j = 0; j < nkeyids; j++, iptr++) { iptr->count = 0; iptr->idx[0] = -1; iptr->idx[1] = -1; } int keyno = 0; int blank = 0; int continuation = 0; int end = 0; #ifdef WCSLIB_INT64 #define asString(S) stringize(S) #define stringize(S) #S const char *int64fmt; if (strcmp(asString(WCSLIB_INT64), "long long int") == 0) { int64fmt = "%lld"; } else if (strcmp(asString(WCSLIB_INT64), "long int") == 0) { int64fmt = "%ld"; } else if (strcmp(asString(WCSLIB_INT64), "int") == 0) { int64fmt = "%d"; } else { return FITSHDRERR_DATA_TYPE; } #endif // User data associated with yyscanner. yyextra->hdr = header; yyextra->nkeyrec = nkeyrec; // Return here via longjmp() invoked by yy_fatal_error(). if (setjmp(yyextra->abort_jmp_env)) { return FITSHDRERR_FLEX_PARSER; } BEGIN(INITIAL); ^" "{80} { // A completely blank keyrecord. strncpy(kptr->keyword, yytext, 8); yyless(0); blank = 1; BEGIN(COMMENT); } ^(COMMENT|HISTORY|" "{8}) { strncpy(kptr->keyword, yytext, 8); BEGIN(COMMENT); } ^END" "{77} { strncpy(kptr->keyword, yytext, 8); end = 1; BEGIN(FLUSH); } ^END" "{5}=" "+ { // Illegal END keyrecord. strncpy(kptr->keyword, yytext, 8); kptr->status |= FITSHDR_KEYREC; BEGIN(VALUE); } ^END" "{5} { // Illegal END keyrecord. strncpy(kptr->keyword, yytext, 8); kptr->status |= FITSHDR_KEYREC; BEGIN(COMMENT); } ^{KEYWORD}=" "+ { strncpy(kptr->keyword, yytext, 8); BEGIN(VALUE); } ^CONTINUE" "+{STRING} { // Continued string keyvalue. strncpy(kptr->keyword, yytext, 8); if (keyno > 0 && (kptr-1)->type%10 == 8) { // Put back the string keyvalue. int k; for (k = 10; yytext[k] != '\''; k++); yyless(k); continuation = 1; BEGIN(VALUE); } else { // Not a valid continuation. yyless(8); BEGIN(COMMENT); } } ^{KEYWORD} { // Keyword without value. strncpy(kptr->keyword, yytext, 8); BEGIN(COMMENT); } ^.{8}=" "+ { // Illegal keyword, carry on regardless. strncpy(kptr->keyword, yytext, 8); kptr->status |= FITSHDR_KEYWORD; BEGIN(VALUE); } ^.{8} { // Illegal keyword, carry on regardless. strncpy(kptr->keyword, yytext, 8); kptr->status |= FITSHDR_KEYWORD; BEGIN(COMMENT); } " "*/\/ { // Null keyvalue. BEGIN(INLINE); } {LOGICAL} { // Logical keyvalue. kptr->type = 1; kptr->keyvalue.i = (*yytext == 'T'); BEGIN(INLINE); } {INT32} { // 32-bit signed integer keyvalue. kptr->type = 2; if (sscanf(yytext, "%d", &(kptr->keyvalue.i)) < 1) { kptr->status |= FITSHDR_KEYVALUE; BEGIN(ERROR); } BEGIN(INLINE); } {INT64} { // 64-bit signed integer keyvalue (up to 18 digits). double dtmp; if (wcsutil_str2double(yytext, &dtmp)) { kptr->status |= FITSHDR_KEYVALUE; BEGIN(ERROR); } else if (INT_MIN <= dtmp && dtmp <= INT_MAX) { // Can be accomodated as a 32-bit signed integer. kptr->type = 2; if (sscanf(yytext, "%d", &(kptr->keyvalue.i)) < 1) { kptr->status |= FITSHDR_KEYVALUE; BEGIN(ERROR); } } else { // 64-bit signed integer. kptr->type = 3; #ifdef WCSLIB_INT64 // Native 64-bit integer is available. if (sscanf(yytext, int64fmt, &(kptr->keyvalue.k)) < 1) { kptr->status |= FITSHDR_KEYVALUE; BEGIN(ERROR); } #else // 64-bit integer (up to 18 digits) implemented as int[3]. kptr->keyvalue.k[2] = 0; sprintf(ctmp, "%%%dd%%9d", yyleng-9); if (sscanf(yytext, ctmp, kptr->keyvalue.k+1, kptr->keyvalue.k) < 1) { kptr->status |= FITSHDR_KEYVALUE; BEGIN(ERROR); } else if (*yytext == '-') { kptr->keyvalue.k[0] *= -1; } #endif } BEGIN(INLINE); } {INTVL} { // Very long integer keyvalue (and 19-digit int64). kptr->type = 4; strcpy(ctmp, yytext); int j, k = yyleng; for (j = 0; j < 8; j++) { // Read it backwards. k -= 9; if (k < 0) k = 0; if (sscanf(ctmp+k, "%d", kptr->keyvalue.l+j) < 1) { kptr->status |= FITSHDR_KEYVALUE; BEGIN(ERROR); } if (*yytext == '-') { kptr->keyvalue.l[j] = -abs(kptr->keyvalue.l[j]); } if (k == 0) break; ctmp[k] = '\0'; } // Can it be accomodated as a 64-bit signed integer? if (j == 2 && abs(kptr->keyvalue.l[2]) <= 9 && abs(kptr->keyvalue.l[1]) <= 223372036 && kptr->keyvalue.l[0] <= 854775807 && kptr->keyvalue.l[0] >= -854775808) { kptr->type = 3; #ifdef WCSLIB_INT64 // Native 64-bit integer is available. kptr->keyvalue.l[2] = 0; if (sscanf(yytext, int64fmt, &(kptr->keyvalue.k)) < 1) { kptr->status |= FITSHDR_KEYVALUE; BEGIN(ERROR); } #endif } BEGIN(INLINE); } {FLOAT} { // Float keyvalue. kptr->type = 5; if (wcsutil_str2double(yytext, &(kptr->keyvalue.f))) { kptr->status |= FITSHDR_KEYVALUE; BEGIN(ERROR); } BEGIN(INLINE); } {ICOMPLX} { // Integer complex keyvalue. kptr->type = 6; if (sscanf(yytext, "(%lf,%lf)", kptr->keyvalue.c, kptr->keyvalue.c+1) < 2) { kptr->status |= FITSHDR_KEYVALUE; BEGIN(ERROR); } BEGIN(INLINE); } {FCOMPLX} { // Floating point complex keyvalue. kptr->type = 7; char *cptr; int k; for (cptr = ctmp, k = 1; yytext[k] != ','; cptr++, k++) { *cptr = yytext[k]; } *cptr = '\0'; if (wcsutil_str2double(ctmp, kptr->keyvalue.c)) { kptr->status |= FITSHDR_KEYVALUE; BEGIN(ERROR); } for (cptr = ctmp, k++; yytext[k] != ')'; cptr++, k++) { *cptr = yytext[k]; } *cptr = '\0'; if (wcsutil_str2double(ctmp, kptr->keyvalue.c+1)) { kptr->status |= FITSHDR_KEYVALUE; BEGIN(ERROR); } BEGIN(INLINE); } {STRING} { // String keyvalue. kptr->type = 8; char *cptr = kptr->keyvalue.s; strcpy(cptr, yytext+1); // Squeeze out repeated quotes. int k = 0; for (int j = 0; j < 72; j++) { if (k < j) { cptr[k] = cptr[j]; } if (cptr[j] == '\0') { if (k) cptr[k-1] = '\0'; break; } else if (cptr[j] == '\'' && cptr[j+1] == '\'') { j++; } k++; } if (*cptr) { // Retain the initial blank in all-blank strings. nullfill(cptr+1, 71); } else { nullfill(cptr, 72); } BEGIN(INLINE); } . { kptr->status |= FITSHDR_KEYVALUE; BEGIN(ERROR); } " "*$ { BEGIN(FLUSH); } " "*\/" "*$ { BEGIN(FLUSH); } " "*\/" "* { BEGIN(UNITS); } " " { kptr->status |= FITSHDR_COMMENT; BEGIN(ERROR); } . { // Keyvalue parsing must now also be suspect. kptr->status |= FITSHDR_COMMENT; kptr->type = 0; BEGIN(ERROR); } {UNITSTR} { kptr->ulen = yyleng; yymore(); BEGIN(COMMENT); } . { yymore(); BEGIN(COMMENT); } .* { strcpy(kptr->comment, yytext); nullfill(kptr->comment, 84); BEGIN(FLUSH); } .* { if (!continuation) kptr->type = -abs(kptr->type); sprintf(kptr->comment, "%.80s", yyextra->hdr-80); kptr->comment[80] = '\0'; nullfill(kptr->comment+80, 4); BEGIN(FLUSH); } .*\n { // Discard the rest of the input line. kptr->keyno = ++keyno; // Null-fill the keyword. kptr->keyword[8] = '\0'; nullfill(kptr->keyword, 12); // Do indexing. iptr = keyids; kptr->keyid = -1; for (int j = 0; j < nkeyids; j++, iptr++) { int k; char *cptr = iptr->name; cptr[8] = '\0'; nullfill(cptr, 12); for (k = 0; k < 8; k++, cptr++) { if (*cptr != '.' && *cptr != kptr->keyword[k]) break; } if (k == 8) { // Found a match. iptr->count++; if (iptr->idx[0] == -1) { iptr->idx[0] = keyno-1; } else { iptr->idx[1] = keyno-1; } kptr->keyno = -abs(kptr->keyno); if (kptr->keyid < 0) kptr->keyid = j; } } // Deal with continued strings. if (continuation) { // Tidy up the previous string keyvalue. if ((kptr-1)->type == 8) (kptr-1)->type += 10; char *cptr = (kptr-1)->keyvalue.s; if (cptr[strlen(cptr)-1] == '&') cptr[strlen(cptr)-1] = '\0'; kptr->type = (kptr-1)->type + 10; } // Check for keyrecords following the END keyrecord. if (end && (end++ > 1) && !blank) { kptr->status |= FITSHDR_TRAILER; } if (kptr->status) (*nreject)++; kptr++; blank = 0; continuation = 0; BEGIN(INITIAL); } <> { // End-of-input. return 0; } %% /*---------------------------------------------------------------------------- * External interface to the scanner. *---------------------------------------------------------------------------*/ int fitshdr( const char header[], int nkeyrec, int nkeyids, struct fitskeyid keyids[], int *nreject, struct fitskey **keys) { // Function prototypes. int yylex_init_extra(YY_EXTRA_TYPE extra, yyscan_t *yyscanner); int yylex_destroy(yyscan_t yyscanner); struct fitshdr_extra extra; yyscan_t yyscanner; yylex_init_extra(&extra, &yyscanner); int status = fitshdr_scanner(header, nkeyrec, nkeyids, keyids, nreject, keys, yyscanner); yylex_destroy(yyscanner); return status; } /*---------------------------------------------------------------------------- * Pad a string with null characters. *---------------------------------------------------------------------------*/ void nullfill(char cptr[], int len) { // Propagate the terminating null to the end of the string. int j; for (j = 0; j < len; j++) { if (cptr[j] == '\0') { for (int k = j+1; k < len; k++) { cptr[k] = '\0'; } break; } } // Remove trailing blanks. for (int k = j-1; k >= 0; k--) { if (cptr[k] != ' ') break; cptr[k] = '\0'; } return; } ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1646921593.275261 astropy-5.0.2/cextern/wcslib/C/flexed/0000755000175100001710000000000000000000000016631 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/flexed/README0000644000175100001710000000044400000000000017513 0ustar00vstsdockerThis directory contains C code generated by flex 2.6.4 under KDE Neon User Edition 5.19 (Kubuntu 18.04) from the Flex description files (*.l) in the parent directory. These pre-generated source files may be used during installation if Flex 2.5.9 or later is not available on the build host. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/flexed/fitshdr.c0000644000175100001710000204342100000000000020446 0ustar00vstsdocker#line 2 "fitshdr.c" #line 4 "fitshdr.c" #define _POSIX_C_SOURCE 1 #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 6 #define YY_FLEX_SUBMINOR_VERSION 4 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif #ifdef yy_create_buffer #define fitshdr_create_buffer_ALREADY_DEFINED #else #define yy_create_buffer fitshdr_create_buffer #endif #ifdef yy_delete_buffer #define fitshdr_delete_buffer_ALREADY_DEFINED #else #define yy_delete_buffer fitshdr_delete_buffer #endif #ifdef yy_scan_buffer #define fitshdr_scan_buffer_ALREADY_DEFINED #else #define yy_scan_buffer fitshdr_scan_buffer #endif #ifdef yy_scan_string #define fitshdr_scan_string_ALREADY_DEFINED #else #define yy_scan_string fitshdr_scan_string #endif #ifdef yy_scan_bytes #define fitshdr_scan_bytes_ALREADY_DEFINED #else #define yy_scan_bytes fitshdr_scan_bytes #endif #ifdef yy_init_buffer #define fitshdr_init_buffer_ALREADY_DEFINED #else #define yy_init_buffer fitshdr_init_buffer #endif #ifdef yy_flush_buffer #define fitshdr_flush_buffer_ALREADY_DEFINED #else #define yy_flush_buffer fitshdr_flush_buffer #endif #ifdef yy_load_buffer_state #define fitshdr_load_buffer_state_ALREADY_DEFINED #else #define yy_load_buffer_state fitshdr_load_buffer_state #endif #ifdef yy_switch_to_buffer #define fitshdr_switch_to_buffer_ALREADY_DEFINED #else #define yy_switch_to_buffer fitshdr_switch_to_buffer #endif #ifdef yypush_buffer_state #define fitshdrpush_buffer_state_ALREADY_DEFINED #else #define yypush_buffer_state fitshdrpush_buffer_state #endif #ifdef yypop_buffer_state #define fitshdrpop_buffer_state_ALREADY_DEFINED #else #define yypop_buffer_state fitshdrpop_buffer_state #endif #ifdef yyensure_buffer_stack #define fitshdrensure_buffer_stack_ALREADY_DEFINED #else #define yyensure_buffer_stack fitshdrensure_buffer_stack #endif #ifdef yylex #define fitshdrlex_ALREADY_DEFINED #else #define yylex fitshdrlex #endif #ifdef yyrestart #define fitshdrrestart_ALREADY_DEFINED #else #define yyrestart fitshdrrestart #endif #ifdef yylex_init #define fitshdrlex_init_ALREADY_DEFINED #else #define yylex_init fitshdrlex_init #endif #ifdef yylex_init_extra #define fitshdrlex_init_extra_ALREADY_DEFINED #else #define yylex_init_extra fitshdrlex_init_extra #endif #ifdef yylex_destroy #define fitshdrlex_destroy_ALREADY_DEFINED #else #define yylex_destroy fitshdrlex_destroy #endif #ifdef yyget_debug #define fitshdrget_debug_ALREADY_DEFINED #else #define yyget_debug fitshdrget_debug #endif #ifdef yyset_debug #define fitshdrset_debug_ALREADY_DEFINED #else #define yyset_debug fitshdrset_debug #endif #ifdef yyget_extra #define fitshdrget_extra_ALREADY_DEFINED #else #define yyget_extra fitshdrget_extra #endif #ifdef yyset_extra #define fitshdrset_extra_ALREADY_DEFINED #else #define yyset_extra fitshdrset_extra #endif #ifdef yyget_in #define fitshdrget_in_ALREADY_DEFINED #else #define yyget_in fitshdrget_in #endif #ifdef yyset_in #define fitshdrset_in_ALREADY_DEFINED #else #define yyset_in fitshdrset_in #endif #ifdef yyget_out #define fitshdrget_out_ALREADY_DEFINED #else #define yyget_out fitshdrget_out #endif #ifdef yyset_out #define fitshdrset_out_ALREADY_DEFINED #else #define yyset_out fitshdrset_out #endif #ifdef yyget_leng #define fitshdrget_leng_ALREADY_DEFINED #else #define yyget_leng fitshdrget_leng #endif #ifdef yyget_text #define fitshdrget_text_ALREADY_DEFINED #else #define yyget_text fitshdrget_text #endif #ifdef yyget_lineno #define fitshdrget_lineno_ALREADY_DEFINED #else #define yyget_lineno fitshdrget_lineno #endif #ifdef yyset_lineno #define fitshdrset_lineno_ALREADY_DEFINED #else #define yyset_lineno fitshdrset_lineno #endif #ifdef yyget_column #define fitshdrget_column_ALREADY_DEFINED #else #define yyget_column fitshdrget_column #endif #ifdef yyset_column #define fitshdrset_column_ALREADY_DEFINED #else #define yyset_column fitshdrset_column #endif #ifdef yywrap #define fitshdrwrap_ALREADY_DEFINED #else #define yywrap fitshdrwrap #endif #ifdef yyalloc #define fitshdralloc_ALREADY_DEFINED #else #define yyalloc fitshdralloc #endif #ifdef yyrealloc #define fitshdrrealloc_ALREADY_DEFINED #else #define yyrealloc fitshdrrealloc #endif #ifdef yyfree #define fitshdrfree_ALREADY_DEFINED #else #define yyfree fitshdrfree #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #ifndef SIZE_MAX #define SIZE_MAX (~(size_t)0) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ /* TODO: this is always defined, so inline it */ #define yyconst const #if defined(__GNUC__) && __GNUC__ >= 3 #define yynoreturn __attribute__((__noreturn__)) #else #define yynoreturn #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an * integer in range [0..255] for use as an array index. */ #define YY_SC_TO_UI(c) ((YY_CHAR) (c)) /* An opaque pointer. */ #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; #endif /* For convenience, these vars (plus the bison vars far below) are macros in the reentrant scanner. */ #define yyin yyg->yyin_r #define yyout yyg->yyout_r #define yyextra yyg->yyextra_r #define yyleng yyg->yyleng_r #define yytext yyg->yytext_r #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) #define yy_flex_debug yyg->yy_flex_debug_r /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN yyg->yy_start = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START ((yyg->yy_start - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin , yyscanner ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) #define YY_LINENO_REWIND_TO(ptr) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = yyg->yy_hold_char; \ YY_RESTORE_YY_MORE_OFFSET \ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] void yyrestart ( FILE *input_file , yyscan_t yyscanner ); void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner ); void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); void yypop_buffer_state ( yyscan_t yyscanner ); static void yyensure_buffer_stack ( yyscan_t yyscanner ); static void yy_load_buffer_state ( yyscan_t yyscanner ); static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner ); #define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner) YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner ); void *yyalloc ( yy_size_t , yyscan_t yyscanner ); void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner ); void yyfree ( void * , yyscan_t yyscanner ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define fitshdrwrap(yyscanner) (/*CONSTCOND*/1) #define YY_SKIP_YYWRAP typedef flex_uint8_t YY_CHAR; typedef int yy_state_type; #define yytext_ptr yytext_r static const flex_int16_t yy_nxt[][128] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 }, { 15, 17, 17, 17, 17, 17, 17, 17, 17, 17, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 19, 17, 17, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 17, 17, 17, 17, 17, 17, 17, 19, 19, 20, 19, 21, 19, 19, 22, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 17, 17, 17, 17, 19, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17 }, { 15, 23, 23, 23, 23, 23, 23, 23, 23, 23, 16, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 23, 23, 23, 23, 23, 23, 25, 26, 23, 23, 27, 23, 27, 28, 29, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 32, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 32, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23 }, { 15, 23, 23, 23, 23, 23, 23, 23, 23, 23, 16, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 23, 23, 23, 23, 23, 23, 25, 26, 23, 23, 27, 23, 27, 28, 29, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 32, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 32, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23 }, { 15, 33, 33, 33, 33, 33, 33, 33, 33, 33, 34, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 35, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 36, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33 }, { 15, 33, 33, 33, 33, 33, 33, 33, 33, 33, 34, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 35, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 36, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33 }, { 15, 37, 37, 37, 37, 37, 37, 37, 37, 37, 16, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 38, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37 }, { 15, 37, 37, 37, 37, 37, 37, 37, 37, 37, 16, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 38, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37 }, { 15, 39, 39, 39, 39, 39, 39, 39, 39, 39, 16, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39 }, { 15, 39, 39, 39, 39, 39, 39, 39, 39, 39, 16, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39 }, { 15, 40, 40, 40, 40, 40, 40, 40, 40, 40, 16, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40 }, { 15, 40, 40, 40, 40, 40, 40, 40, 40, 40, 16, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40 }, { 15, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41 }, { 15, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41 }, { -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15 }, { 15, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16 }, { 15, 43, 43, 43, 43, 43, 43, 43, 43, 43, -17, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43 }, { 15, 43, 43, 43, 43, 43, 43, 43, 43, 43, -18, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 44, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43 }, { 15, 43, 43, 43, 43, 43, 43, 43, 43, 43, -19, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 45, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 46, 43, 43, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 43, 43, 43, 43, 43, 43, 43, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 43, 43, 43, 43, 46, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43 }, { 15, 43, 43, 43, 43, 43, 43, 43, 43, 43, -20, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 45, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 46, 43, 43, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 43, 43, 43, 43, 43, 43, 43, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 43, 43, 43, 43, 46, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43 }, { 15, 43, 43, 43, 43, 43, 43, 43, 43, 43, -21, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 45, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 46, 43, 43, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 43, 43, 43, 43, 43, 43, 43, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 48, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 43, 43, 43, 43, 46, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43 }, { 15, 43, 43, 43, 43, 43, 43, 43, 43, 43, -22, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 45, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 46, 43, 43, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 43, 43, 43, 43, 43, 43, 43, 46, 46, 46, 46, 46, 46, 46, 46, 49, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 43, 43, 43, 43, 46, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43 }, { 15, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23 }, { 15, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, 50, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, 51, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24 }, { 15, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52 }, { 15, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, 54, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, 55, -26, 55, 56, -26, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26 }, { 15, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, 58, -27, 59, 60, 60, 60, 60, 60, 60, 60, 60, 60, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27 }, { 15, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28 }, { 15, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29 }, { 15, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, 62, -30, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, 65, 65, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, 65, 65, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30 }, { 15, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, 62, -31, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, 65, 65, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, 65, 65, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31 }, { 15, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32 }, { 15, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33 }, { 15, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34 }, { 15, -35, -35, -35, -35, -35, -35, -35, -35, -35, 67, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, 68, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, 69, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35 }, { 15, -36, -36, -36, -36, -36, -36, -36, -36, -36, 70, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, 71, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36 }, { 15, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37 }, { 15, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, 72, -38, -38, -38, -38, -38, -38, -38, 72, 72, 72, 72, -38, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, -38, -38, -38, -38, -38, -38, -38, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, -38, -38, -38, 72, -38, -38, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, -38, -38, -38, -38, -38 }, { 15, 73, 73, 73, 73, 73, 73, 73, 73, 73, -39, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73 }, { 15, 74, 74, 74, 74, 74, 74, 74, 74, 74, -40, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74 }, { 15, 75, 75, 75, 75, 75, 75, 75, 75, 75, 76, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75 }, { 15, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42 }, { 15, 77, 77, 77, 77, 77, 77, 77, 77, 77, -43, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77 }, { 15, 77, 77, 77, 77, 77, 77, 77, 77, 77, -44, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 78, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77 }, { 15, 77, 77, 77, 77, 77, 77, 77, 77, 77, -45, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 79, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77 }, { 15, 77, 77, 77, 77, 77, 77, 77, 77, 77, -46, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 80, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 81, 77, 77, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 77, 77, 77, 77, 77, 77, 77, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 77, 77, 77, 77, 81, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77 }, { 15, 77, 77, 77, 77, 77, 77, 77, 77, 77, -47, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 80, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 81, 77, 77, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 77, 77, 77, 77, 77, 77, 77, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 82, 83, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 77, 77, 77, 77, 81, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77 }, { 15, 77, 77, 77, 77, 77, 77, 77, 77, 77, -48, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 80, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 81, 77, 77, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 77, 77, 77, 77, 77, 77, 77, 81, 81, 81, 84, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 77, 77, 77, 77, 81, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77 }, { 15, 77, 77, 77, 77, 77, 77, 77, 77, 77, -49, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 80, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 81, 77, 77, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 77, 77, 77, 77, 77, 77, 77, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 85, 81, 81, 81, 81, 81, 81, 81, 77, 77, 77, 77, 81, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77 }, { 15, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, 50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, 51, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50 }, { 15, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51 }, { 15, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52 }, { 15, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, 52, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53 }, { 15, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, 54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, 55, -54, 55, 56, -54, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54 }, { 15, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, 56, -55, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55 }, { 15, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56 }, { 15, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, 87, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, 88, -57, 89, -57, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, 91, 91, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, 91, 91, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57 }, { 15, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58 }, { 15, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, 62, -59, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, 65, 65, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, 65, 65, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59 }, { 15, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, 62, -60, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, 65, 65, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, 65, 65, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60 }, { 15, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, 65, 65, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, 65, 65, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61 }, { 15, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, 65, 65, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, 65, 65, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62 }, { 15, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, 62, -63, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, 65, 65, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, 65, 65, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63 }, { 15, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, 62, -64, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, 65, 65, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, 65, 65, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64 }, { 15, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, 96, -65, 96, -65, -65, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65 }, { 15, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, 62, -66, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, 65, 65, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, 65, 65, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66 }, { 15, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67 }, { 15, -68, -68, -68, -68, -68, -68, -68, -68, -68, 67, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, 68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, 69, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68 }, { 15, -69, -69, -69, -69, -69, -69, -69, -69, -69, 70, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, 71, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69 }, { 15, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70 }, { 15, -71, -71, -71, -71, -71, -71, -71, -71, -71, 70, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, 71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71 }, { 15, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, 72, -72, -72, -72, -72, -72, -72, -72, 72, 72, 72, 72, -72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, -72, -72, -72, -72, -72, -72, -72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, -72, -72, 99, 72, -72, -72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, -72, -72, -72, -72, -72 }, { 15, 73, 73, 73, 73, 73, 73, 73, 73, 73, -73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73 }, { 15, 74, 74, 74, 74, 74, 74, 74, 74, 74, -74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74 }, { 15, 75, 75, 75, 75, 75, 75, 75, 75, 75, 76, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75 }, { 15, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76 }, { 15, 100, 100, 100, 100, 100, 100, 100, 100, 100, -77, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 }, { 15, 100, 100, 100, 100, 100, 100, 100, 100, 100, -78, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 101, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 }, { 15, 100, 100, 100, 100, 100, 100, 100, 100, 100, -79, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 102, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 }, { 15, 100, 100, 100, 100, 100, 100, 100, 100, 100, -80, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 103, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 }, { 15, 100, 100, 100, 100, 100, 100, 100, 100, 100, -81, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 104, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 105, 100, 100, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 100, 100, 100, 100, 100, 100, 100, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 100, 100, 100, 100, 105, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 }, { 15, 100, 100, 100, 100, 100, 100, 100, 100, 100, -82, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 104, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 105, 100, 100, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 100, 100, 100, 100, 100, 100, 100, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 106, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 100, 100, 100, 100, 105, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 }, { 15, 100, 100, 100, 100, 100, 100, 100, 100, 100, -83, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 104, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 105, 100, 100, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 100, 100, 100, 100, 100, 100, 100, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 107, 105, 105, 105, 105, 105, 105, 100, 100, 100, 100, 105, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 }, { 15, 100, 100, 100, 100, 100, 100, 100, 100, 100, -84, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 108, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 105, 100, 100, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 100, 100, 100, 100, 100, 100, 100, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 100, 100, 100, 100, 105, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 }, { 15, 100, 100, 100, 100, 100, 100, 100, 100, 100, -85, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 104, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 105, 100, 100, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 100, 100, 100, 100, 100, 100, 100, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 109, 105, 105, 105, 105, 105, 105, 100, 100, 100, 100, 105, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 }, { 15, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, 110, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, 111, -86, -86, -86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, 91, 91, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, 91, 91, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86 }, { 15, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, 87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, 88, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87 }, { 15, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, 112, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, 113, -88, 113, 114, -88, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88 }, { 15, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, 110, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, 111, -89, -89, -89, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, 91, 91, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, 91, 91, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89 }, { 15, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, 87, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, 88, -90, 89, -90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, 91, 91, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, 91, 91, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90 }, { 15, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, 117, -91, 117, -91, -91, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91 }, { 15, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, 65, 65, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, 65, 65, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92 }, { 15, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, 62, -93, 119, 120, 120, 120, 120, 120, 120, 120, 120, 120, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, 65, 65, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, 65, 65, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93 }, { 15, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, 62, -94, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, 65, 65, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, 65, 65, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94 }, { 15, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, 62, -95, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, 65, 65, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, 65, 65, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95 }, { 15, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96 }, { 15, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97 }, { 15, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, 62, -98, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, 65, 65, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, 65, 65, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98 }, { 15, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99 }, { 15, 124, 124, 124, 124, 124, 124, 124, 124, 124, -100, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124 }, { 15, 124, 124, 124, 124, 124, 124, 124, 124, 124, -101, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 125, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124 }, { 15, 124, 124, 124, 124, 124, 124, 124, 124, 124, -102, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 126, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124 }, { 15, 124, 124, 124, 124, 124, 124, 124, 124, 124, -103, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 127, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124 }, { 15, 124, 124, 124, 124, 124, 124, 124, 124, 124, -104, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 128, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124 }, { 15, 124, 124, 124, 124, 124, 124, 124, 124, 124, -105, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 129, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 130, 124, 124, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 124, 124, 124, 124, 124, 124, 124, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 124, 124, 124, 124, 130, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124 }, { 15, 124, 124, 124, 124, 124, 124, 124, 124, 124, -106, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 129, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 130, 124, 124, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 124, 124, 124, 124, 124, 124, 124, 130, 130, 130, 130, 131, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 124, 124, 124, 124, 130, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124 }, { 15, 124, 124, 124, 124, 124, 124, 124, 124, 124, -107, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 129, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 130, 124, 124, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 124, 124, 124, 124, 124, 124, 124, 130, 130, 130, 130, 130, 130, 130, 130, 132, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 124, 124, 124, 124, 130, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124 }, { 15, 124, 124, 124, 124, 124, 124, 124, 124, 124, -108, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 133, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124 }, { 15, 124, 124, 124, 124, 124, 124, 124, 124, 124, -109, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 129, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 130, 124, 124, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 124, 124, 124, 124, 124, 124, 124, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 134, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 124, 124, 124, 124, 130, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124 }, { 15, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, 110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, 111, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110 }, { 15, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, 135, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, 136, -111, 136, 114, -111, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111 }, { 15, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, 112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, 113, -112, 113, 114, -112, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112 }, { 15, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, 114, -113, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113 }, { 15, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114 }, { 15, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, 139, -115, -115, -115, -115, -115, -115, -115, -115, 140, -115, -115, -115, -115, 141, -115, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, 143, 143, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, 143, 143, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115 }, { 15, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, 110, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, 111, -116, -116, -116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, 91, 91, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, 91, 91, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116 }, { 15, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117 }, { 15, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, 110, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, 111, -118, -118, -118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118 }, { 15, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, 62, -119, 144, 145, 145, 145, 145, 145, 145, 145, 145, 145, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, 65, 65, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, 65, 65, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119 }, { 15, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, 62, -120, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, 65, 65, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, 65, 65, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120 }, { 15, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, 62, -121, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, 65, 65, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, 65, 65, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121 }, { 15, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, 62, -122, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, 65, 65, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, 65, 65, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122 }, { 15, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, 62, -123, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, 65, 65, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, 65, 65, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123 }, { 15, 150, 150, 150, 150, 150, 150, 150, 150, 150, -124, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 }, { 15, 150, 150, 150, 150, 150, 150, 150, 150, 150, -125, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 151, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 }, { 15, 150, 150, 150, 150, 150, 150, 150, 150, 150, -126, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 152, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 }, { 15, 150, 150, 150, 150, 150, 150, 150, 150, 150, -127, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 153, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 }, { 15, 150, 150, 150, 150, 150, 150, 150, 150, 150, -128, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 154, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 }, { 15, 150, 150, 150, 150, 150, 150, 150, 150, 150, -129, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 155, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 }, { 15, 150, 150, 150, 150, 150, 150, 150, 150, 150, -130, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 156, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 157, 150, 150, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 150, 150, 150, 150, 150, 150, 150, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 150, 150, 150, 150, 157, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 }, { 15, 150, 150, 150, 150, 150, 150, 150, 150, 150, -131, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 156, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 157, 150, 150, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 150, 150, 150, 150, 150, 150, 150, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 158, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 150, 150, 150, 150, 157, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 }, { 15, 150, 150, 150, 150, 150, 150, 150, 150, 150, -132, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 156, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 157, 150, 150, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 150, 150, 150, 150, 150, 150, 150, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 159, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 150, 150, 150, 150, 157, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 }, { 15, 150, 150, 150, 150, 150, 150, 150, 150, 150, -133, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 160, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 }, { 15, 150, 150, 150, 150, 150, 150, 150, 150, 150, -134, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 156, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 157, 150, 150, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 150, 150, 150, 150, 150, 150, 150, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 161, 157, 157, 157, 157, 157, 157, 157, 157, 150, 150, 150, 150, 157, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 }, { 15, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, 135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, 136, -135, 136, 114, -135, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135 }, { 15, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, 114, -136, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136 }, { 15, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, 162, -137, -137, -137, -137, -137, -137, -137, -137, 163, -137, -137, -137, -137, 141, -137, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, 143, 143, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, 143, 143, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137 }, { 15, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, 162, -138, -138, -138, -138, -138, -138, -138, -138, 163, -138, -138, -138, -138, -138, -138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, 143, 143, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, 143, 143, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138 }, { 15, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, 139, -139, -139, -139, -139, -139, -139, -139, -139, 140, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139 }, { 15, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140 }, { 15, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, 162, -141, -141, -141, -141, -141, -141, -141, -141, 163, -141, -141, -141, -141, -141, -141, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, 143, 143, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, 143, 143, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141 }, { 15, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, 139, -142, -142, -142, -142, -142, -142, -142, -142, 140, -142, -142, -142, -142, 141, -142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, 143, 143, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, 143, 143, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142 }, { 15, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, 166, -143, 166, -143, -143, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143 }, { 15, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, 62, -144, 168, 169, 169, 169, 169, 169, 169, 169, 169, 169, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, 65, 65, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, 65, 65, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144 }, { 15, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, 62, -145, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, 65, 65, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, 65, 65, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145 }, { 15, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, 62, -146, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, 65, 65, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, 65, 65, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146 }, { 15, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, 62, -147, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, 65, 65, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, 65, 65, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147 }, { 15, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, 62, -148, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, 65, 65, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, 65, 65, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148 }, { 15, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, 62, -149, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, 65, 65, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, 65, 65, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149 }, { 15, 175, 175, 175, 175, 175, 175, 175, 175, 175, -150, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175 }, { 15, 175, 175, 175, 175, 175, 175, 175, 175, 175, -151, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 176, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175 }, { 15, 175, 175, 175, 175, 175, 175, 175, 175, 175, -152, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 177, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175 }, { 15, 175, 175, 175, 175, 175, 175, 175, 175, 175, -153, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 178, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175 }, { 15, 175, 175, 175, 175, 175, 175, 175, 175, 175, -154, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 179, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175 }, { 15, 175, 175, 175, 175, 175, 175, 175, 175, 175, -155, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 180, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175 }, { 15, 175, 175, 175, 175, 175, 175, 175, 175, 175, -156, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 181, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175 }, { 15, 175, 175, 175, 175, 175, 175, 175, 175, 175, -157, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 182, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 183, 175, 175, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 175, 175, 175, 175, 175, 175, 175, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 175, 175, 175, 175, 183, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175 }, { 15, 175, 175, 175, 175, 175, 175, 175, 175, 175, -158, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 182, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 183, 175, 175, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 175, 175, 175, 175, 175, 175, 175, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 184, 183, 183, 183, 183, 183, 183, 175, 175, 175, 175, 183, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175 }, { 15, 175, 175, 175, 175, 175, 175, 175, 175, 175, -159, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 182, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 183, 175, 175, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 175, 175, 175, 175, 175, 175, 175, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 185, 183, 183, 183, 183, 183, 175, 175, 175, 175, 183, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175 }, { 15, 175, 175, 175, 175, 175, 175, 175, 175, 175, -160, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 186, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175 }, { 15, 175, 175, 175, 175, 175, 175, 175, 175, 175, -161, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 182, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 183, 175, 175, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 175, 175, 175, 175, 175, 175, 175, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 184, 183, 175, 175, 175, 175, 183, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175 }, { 15, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, 162, -162, -162, -162, -162, -162, -162, -162, -162, 163, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162 }, { 15, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163 }, { 15, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, 162, -164, -164, -164, -164, -164, -164, -164, -164, 163, -164, -164, -164, -164, 141, -164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, 143, 143, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, 143, 143, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164 }, { 15, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, 162, -165, -165, -165, -165, -165, -165, -165, -165, 163, -165, -165, -165, -165, -165, -165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, 143, 143, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, 143, 143, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165 }, { 15, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166 }, { 15, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, 162, -167, -167, -167, -167, -167, -167, -167, -167, 163, -167, -167, -167, -167, -167, -167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167 }, { 15, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, 62, -168, 187, 188, 188, 188, 188, 188, 188, 188, 188, 188, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, 65, 65, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, 65, 65, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168 }, { 15, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, 62, -169, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, 65, 65, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, 65, 65, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169 }, { 15, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, 62, -170, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, 65, 65, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, 65, 65, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170 }, { 15, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, 62, -171, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, 65, 65, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, 65, 65, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171 }, { 15, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, 62, -172, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, 65, 65, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, 65, 65, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172 }, { 15, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, 62, -173, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, 65, 65, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, 65, 65, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173 }, { 15, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, 62, -174, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, 65, 65, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, 65, 65, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174 }, { 15, 195, 195, 195, 195, 195, 195, 195, 195, 195, -175, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195 }, { 15, 195, 195, 195, 195, 195, 195, 195, 195, 195, -176, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 196, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195 }, { 15, 195, 195, 195, 195, 195, 195, 195, 195, 195, -177, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 197, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195 }, { 15, 195, 195, 195, 195, 195, 195, 195, 195, 195, -178, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 197, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195 }, { 15, 195, 195, 195, 195, 195, 195, 195, 195, 195, -179, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 197, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195 }, { 15, 195, 195, 195, 195, 195, 195, 195, 195, 195, -180, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 197, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195 }, { 15, 195, 195, 195, 195, 195, 195, 195, 195, 195, -181, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 197, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195 }, { 15, 195, 195, 195, 195, 195, 195, 195, 195, 195, -182, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 197, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195 }, { 15, 195, 195, 195, 195, 195, 195, 195, 195, 195, -183, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 198, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 197, 195, 195, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 195, 195, 195, 195, 195, 195, 195, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 195, 195, 195, 195, 197, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195 }, { 15, 195, 195, 195, 195, 195, 195, 195, 195, 195, -184, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 198, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 197, 195, 195, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 195, 195, 195, 195, 195, 195, 195, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 195, 195, 195, 195, 197, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195 }, { 15, 195, 195, 195, 195, 195, 195, 195, 195, 195, -185, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 198, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 197, 195, 195, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 195, 195, 195, 195, 195, 195, 195, 197, 197, 197, 197, 199, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 195, 195, 195, 195, 197, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195 }, { 15, 195, 195, 195, 195, 195, 195, 195, 195, 195, -186, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 200, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195 }, { 15, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, 62, -187, 201, 202, 202, 202, 202, 202, 202, 202, 202, 202, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, 65, 65, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, 65, 65, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187 }, { 15, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, 62, -188, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, 65, 65, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, 65, 65, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188 }, { 15, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, 62, -189, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, 65, 65, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, 65, 65, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189 }, { 15, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, 62, -190, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, 65, 65, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, 65, 65, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190 }, { 15, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, 62, -191, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, 65, 65, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, 65, 65, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191 }, { 15, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, 62, -192, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, 65, 65, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, 65, 65, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192 }, { 15, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, 62, -193, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, 65, 65, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, 65, 65, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193 }, { 15, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, 62, -194, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, 65, 65, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, 65, 65, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194 }, { 15, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, 210, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195 }, { 15, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, 211, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, 210, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196 }, { 15, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, 212, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197 }, { 15, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, 212, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198 }, { 15, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, 213, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, 212, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199 }, { 15, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, 214, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, 215, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200 }, { 15, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, 62, -201, 216, 217, 217, 217, 217, 217, 217, 217, 217, 217, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, 65, 65, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, 65, 65, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201 }, { 15, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, 62, -202, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, 65, 65, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, 65, 65, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202 }, { 15, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, 62, -203, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, 65, 65, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, 65, 65, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203 }, { 15, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, 62, -204, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, 65, 65, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, 65, 65, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204 }, { 15, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, 62, -205, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, 65, 65, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, 65, 65, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205 }, { 15, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, 62, -206, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, 65, 65, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, 65, 65, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206 }, { 15, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, 62, -207, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, 65, 65, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, 65, 65, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207 }, { 15, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, 62, -208, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, 65, 65, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, 65, 65, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208 }, { 15, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, 62, -209, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, 65, 65, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, 65, 65, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209 }, { 15, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, 226, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210 }, { 15, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, 227, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211 }, { 15, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, 228, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212 }, { 15, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, 229, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213 }, { 15, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, 230, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214 }, { 15, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, 231, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215 }, { 15, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, 62, -216, 232, 233, 233, 233, 233, 233, 233, 233, 233, 233, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, 65, 65, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, 65, 65, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216 }, { 15, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, 62, -217, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, 65, 65, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, 65, 65, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217 }, { 15, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, 62, -218, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, 65, 65, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, 65, 65, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218 }, { 15, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, 62, -219, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, 65, 65, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, 65, 65, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219 }, { 15, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, 62, -220, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, 65, 65, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, 65, 65, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220 }, { 15, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, 62, -221, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, 65, 65, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, 65, 65, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221 }, { 15, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, 62, -222, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, 65, 65, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, 65, 65, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222 }, { 15, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, 62, -223, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, 65, 65, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, 65, 65, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223 }, { 15, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, 62, -224, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, 65, 65, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, 65, 65, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224 }, { 15, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, 62, -225, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, 65, 65, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, 65, 65, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225 }, { 15, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, 226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226 }, { 15, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, 243, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227 }, { 15, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, 228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228 }, { 15, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, 213, -229, -229, -229, -229, -229, -229, 244, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229 }, { 15, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, 245, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230 }, { 15, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, 231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231 }, { 15, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, 62, -232, 246, 247, 247, 247, 247, 247, 247, 247, 247, 247, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, 65, 65, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, 65, 65, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232 }, { 15, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, 62, -233, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, 65, 65, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, 65, 65, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233 }, { 15, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, 62, -234, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, 65, 65, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, 65, 65, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234 }, { 15, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, 62, -235, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, 65, 65, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, 65, 65, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235 }, { 15, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, 62, -236, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, 65, 65, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, 65, 65, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236 }, { 15, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, 62, -237, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, 65, 65, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, 65, 65, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237 }, { 15, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, 62, -238, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, 65, 65, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, 65, 65, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238 }, { 15, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, 62, -239, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, 65, 65, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, 65, 65, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239 }, { 15, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, 62, -240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, 65, 65, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, 65, 65, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240 }, { 15, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, 62, -241, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, 65, 65, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, 65, 65, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241 }, { 15, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, 62, -242, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, 65, 65, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, 65, 65, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242 }, { 15, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, 258, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243 }, { 15, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 260, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259 }, { 15, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, 261, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245 }, { 15, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, 62, -246, 262, 263, 263, 263, 263, 263, 263, 263, 263, 263, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, 65, 65, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, 65, 65, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246 }, { 15, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, 62, -247, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, 65, 65, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, 65, 65, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247 }, { 15, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, 62, -248, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, 65, 65, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, 65, 65, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248 }, { 15, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, 62, -249, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, 65, 65, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, 65, 65, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249 }, { 15, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, 62, -250, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, 65, 65, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, 65, 65, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250 }, { 15, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, 62, -251, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, 65, 65, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, 65, 65, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251 }, { 15, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, 62, -252, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, 65, 65, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, 65, 65, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252 }, { 15, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, 62, -253, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, 65, 65, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, 65, 65, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253 }, { 15, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, 62, -254, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, 65, 65, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, 65, 65, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254 }, { 15, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, 62, -255, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, 65, 65, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, 65, 65, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255 }, { 15, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, 62, -256, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, 65, 65, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, 65, 65, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256 }, { 15, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, 62, -257, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, 65, 65, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, 65, 65, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257 }, { 15, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, 275, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258 }, { 15, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 260, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259 }, { 15, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, 259, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260 }, { 15, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, 276, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261 }, { 15, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, 62, -262, 277, 278, 278, 278, 278, 278, 278, 278, 278, 278, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, 65, 65, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, 65, 65, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262 }, { 15, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, 62, -263, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, 65, 65, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, 65, 65, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263 }, { 15, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, 62, -264, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, 65, 65, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, 65, 65, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264 }, { 15, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, 62, -265, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, 65, 65, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, 65, 65, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265 }, { 15, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, 62, -266, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, 65, 65, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, 65, 65, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266 }, { 15, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, 62, -267, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, 65, 65, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, 65, 65, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267 }, { 15, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, 62, -268, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, 65, 65, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, 65, 65, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268 }, { 15, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, 62, -269, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, 65, 65, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, 65, 65, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269 }, { 15, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, 62, -270, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, 65, 65, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, 65, 65, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270 }, { 15, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, 62, -271, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, 65, 65, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, 65, 65, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271 }, { 15, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, 62, -272, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, 65, 65, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, 65, 65, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272 }, { 15, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, 62, -273, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, 65, 65, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, 65, 65, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273 }, { 15, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, 62, -274, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, 65, 65, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, 65, 65, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274 }, { 15, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, 291, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275 }, { 15, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, 292, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276 }, { 15, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, 62, -277, 293, 294, 294, 294, 294, 294, 294, 294, 294, 294, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, 65, 65, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, 65, 65, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277 }, { 15, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, 62, -278, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, 65, 65, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, 65, 65, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278 }, { 15, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, 62, -279, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, 65, 65, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, 65, 65, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279 }, { 15, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, 62, -280, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, 65, 65, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, 65, 65, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280 }, { 15, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, 62, -281, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, 65, 65, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, 65, 65, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281 }, { 15, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, 62, -282, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, 65, 65, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, 65, 65, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282 }, { 15, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, 62, -283, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, 65, 65, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, 65, 65, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283 }, { 15, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, 62, -284, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, 65, 65, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, 65, 65, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284 }, { 15, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, 62, -285, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, 65, 65, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, 65, 65, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285 }, { 15, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, 62, -286, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, 65, 65, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, 65, 65, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286 }, { 15, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, 62, -287, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, 65, 65, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, 65, 65, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287 }, { 15, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, 62, -288, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, 65, 65, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, 65, 65, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288 }, { 15, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, 62, -289, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, 65, 65, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, 65, 65, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289 }, { 15, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, 62, -290, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, 65, 65, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, 65, 65, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290 }, { 15, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, 308, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291 }, { 15, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, 309, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292 }, { 15, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, 62, -293, 310, 311, 311, 311, 311, 311, 311, 311, 311, 311, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, 65, 65, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, 65, 65, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293 }, { 15, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, 62, -294, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, 65, 65, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, 65, 65, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294 }, { 15, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, 62, -295, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, 65, 65, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, 65, 65, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295 }, { 15, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, 62, -296, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, 65, 65, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, 65, 65, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296 }, { 15, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, 62, -297, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, 65, 65, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, 65, 65, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297 }, { 15, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, 62, -298, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, 65, 65, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, 65, 65, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298 }, { 15, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, 62, -299, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, 65, 65, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, 65, 65, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299 }, { 15, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, 62, -300, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, 65, 65, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, 65, 65, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300 }, { 15, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, 62, -301, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, 65, 65, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, 65, 65, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301 }, { 15, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, 62, -302, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, 65, 65, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, 65, 65, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302 }, { 15, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, 62, -303, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, 65, 65, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, 65, 65, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303 }, { 15, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, 62, -304, 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, 65, 65, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, 65, 65, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304 }, { 15, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, 62, -305, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, 65, 65, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, 65, 65, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305 }, { 15, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, 62, -306, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, 65, 65, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, 65, 65, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306 }, { 15, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, 62, -307, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, 65, 65, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, 65, 65, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307 }, { 15, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, 326, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308 }, { 15, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, 327, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309 }, { 15, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, 62, -310, 328, 329, 329, 329, 329, 329, 329, 329, 329, 329, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, 65, 65, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, 65, 65, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310 }, { 15, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, 62, -311, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, 65, 65, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, 65, 65, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311 }, { 15, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, 62, -312, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, 65, 65, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, 65, 65, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312 }, { 15, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, 62, -313, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, 65, 65, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, 65, 65, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313 }, { 15, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, 62, -314, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, 65, 65, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, 65, 65, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314 }, { 15, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, 62, -315, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, 65, 65, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, 65, 65, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315 }, { 15, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, 62, -316, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, 65, 65, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, 65, 65, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316 }, { 15, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, 62, -317, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, 65, 65, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, 65, 65, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317 }, { 15, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, 62, -318, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, 65, 65, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, 65, 65, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318 }, { 15, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, 62, -319, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, 65, 65, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, 65, 65, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319 }, { 15, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, 62, -320, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, 65, 65, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, 65, 65, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320 }, { 15, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, 62, -321, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, 65, 65, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, 65, 65, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321 }, { 15, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, 62, -322, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, 65, 65, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, 65, 65, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322 }, { 15, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, 62, -323, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, 65, 65, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, 65, 65, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323 }, { 15, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, 62, -324, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, 65, 65, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, 65, 65, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324 }, { 15, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, 62, -325, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, 65, 65, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, 65, 65, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325 }, { 15, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, 345, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326 }, { 15, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, 346, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327 }, { 15, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, 62, -328, 347, 348, 348, 348, 348, 348, 348, 348, 348, 348, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, 65, 65, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, 65, 65, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328 }, { 15, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, 62, -329, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, 65, 65, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, 65, 65, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329 }, { 15, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, 62, -330, 350, 350, 350, 350, 350, 350, 350, 350, 350, 350, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, 65, 65, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, 65, 65, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330 }, { 15, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, 62, -331, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, 65, 65, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, 65, 65, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331 }, { 15, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, 62, -332, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, 65, 65, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, 65, 65, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332 }, { 15, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, 62, -333, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, 65, 65, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, 65, 65, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333 }, { 15, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, 62, -334, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, 65, 65, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, 65, 65, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334 }, { 15, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, 62, -335, 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, 65, 65, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, 65, 65, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335 }, { 15, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, 62, -336, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, 65, 65, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, 65, 65, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336 }, { 15, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, 62, -337, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, 65, 65, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, 65, 65, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337 }, { 15, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, 62, -338, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, 65, 65, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, 65, 65, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338 }, { 15, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, 62, -339, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, 65, 65, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, 65, 65, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339 }, { 15, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, 62, -340, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, 65, 65, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, 65, 65, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340 }, { 15, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, 62, -341, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, 65, 65, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, 65, 65, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341 }, { 15, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, 62, -342, 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, 65, 65, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, 65, 65, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342 }, { 15, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, 62, -343, 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, 65, 65, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, 65, 65, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343 }, { 15, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, 62, -344, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, 65, 65, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, 65, 65, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344 }, { 15, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, 365, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345 }, { 15, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, 366, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346 }, { 15, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, 62, -347, 367, 368, 368, 368, 368, 368, 368, 368, 368, 368, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, 65, 65, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, 65, 65, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347 }, { 15, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, 62, -348, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, 65, 65, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, 65, 65, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348 }, { 15, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, 62, -349, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, 65, 65, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, 65, 65, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349 }, { 15, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, 62, -350, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, 65, 65, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, 65, 65, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350 }, { 15, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, 62, -351, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, 65, 65, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, 65, 65, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351 }, { 15, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, 62, -352, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, 65, 65, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, 65, 65, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352 }, { 15, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, 62, -353, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, 65, 65, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, 65, 65, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353 }, { 15, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, 62, -354, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, 65, 65, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, 65, 65, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354 }, { 15, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, 62, -355, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, 65, 65, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, 65, 65, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355 }, { 15, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, 62, -356, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, 65, 65, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, 65, 65, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356 }, { 15, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, 62, -357, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, 65, 65, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, 65, 65, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357 }, { 15, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, 62, -358, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, 65, 65, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, 65, 65, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358 }, { 15, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, 62, -359, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, 65, 65, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, 65, 65, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359 }, { 15, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, 62, -360, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, 65, 65, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, 65, 65, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360 }, { 15, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, 62, -361, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, 65, 65, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, 65, 65, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361 }, { 15, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, 62, -362, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, 65, 65, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, 65, 65, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362 }, { 15, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, 62, -363, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, 65, 65, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, 65, 65, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363 }, { 15, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, 62, -364, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, 65, 65, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, 65, 65, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364 }, { 15, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, 386, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365 }, { 15, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, 387, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366 }, { 15, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, 62, -367, 388, 389, 389, 389, 389, 389, 389, 389, 389, 389, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, 65, 65, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, 65, 65, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367 }, { 15, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, 62, -368, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, 65, 65, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, 65, 65, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368 }, { 15, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, 62, -369, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, 65, 65, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, 65, 65, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369 }, { 15, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, 62, -370, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, 65, 65, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, 65, 65, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370 }, { 15, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, 62, -371, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, 65, 65, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, 65, 65, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371 }, { 15, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, 62, -372, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, 65, 65, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, 65, 65, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372 }, { 15, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, 62, -373, 395, 395, 395, 395, 395, 395, 395, 395, 395, 395, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, 65, 65, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, 65, 65, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373 }, { 15, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, 62, -374, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, 65, 65, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, 65, 65, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374 }, { 15, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, 62, -375, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, 65, 65, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, 65, 65, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375 }, { 15, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, 62, -376, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, 65, 65, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, 65, 65, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376 }, { 15, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, 62, -377, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, 65, 65, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, 65, 65, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377 }, { 15, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, 62, -378, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, 65, 65, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, 65, 65, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378 }, { 15, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, 62, -379, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, 65, 65, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, 65, 65, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379 }, { 15, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, 62, -380, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, 65, 65, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, 65, 65, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380 }, { 15, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, 62, -381, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, 65, 65, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, 65, 65, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381 }, { 15, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, 62, -382, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, 65, 65, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, 65, 65, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382 }, { 15, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, 62, -383, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, 65, 65, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, 65, 65, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383 }, { 15, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, 62, -384, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, 65, 65, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, 65, 65, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384 }, { 15, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, 62, -385, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, 65, 65, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, 65, 65, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385 }, { 15, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, 408, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386 }, { 15, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, 409, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387 }, { 15, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, 62, -388, 410, 411, 411, 411, 411, 411, 411, 411, 411, 411, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, 65, 65, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, 65, 65, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388 }, { 15, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, 62, -389, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, 65, 65, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, 65, 65, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389 }, { 15, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, 62, -390, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, 65, 65, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, 65, 65, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390 }, { 15, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, 62, -391, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, 65, 65, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, 65, 65, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391 }, { 15, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, 62, -392, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, 65, 65, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, 65, 65, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392 }, { 15, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, 62, -393, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, 65, 65, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, 65, 65, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393 }, { 15, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, 62, -394, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, 65, 65, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, 65, 65, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394 }, { 15, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, 62, -395, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, 65, 65, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, 65, 65, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395 }, { 15, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, 62, -396, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, 65, 65, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, 65, 65, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396 }, { 15, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, 62, -397, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, 65, 65, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, 65, 65, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397 }, { 15, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, 62, -398, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, 65, 65, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, 65, 65, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398 }, { 15, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, 62, -399, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, 65, 65, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, 65, 65, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399 }, { 15, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, 62, -400, 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, 65, 65, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, 65, 65, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400 }, { 15, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, 62, -401, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, 65, 65, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, 65, 65, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401 }, { 15, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, 62, -402, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, 65, 65, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, 65, 65, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402 }, { 15, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, 62, -403, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, 65, 65, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, 65, 65, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403 }, { 15, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, 62, -404, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, 65, 65, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, 65, 65, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404 }, { 15, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, 62, -405, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, 65, 65, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, 65, 65, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405 }, { 15, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, 62, -406, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, 65, 65, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, 65, 65, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406 }, { 15, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, 62, -407, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, 65, 65, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, 65, 65, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407 }, { 15, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, 431, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408 }, { 15, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, 432, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409 }, { 15, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, 62, -410, 410, 411, 411, 411, 411, 411, 411, 411, 411, 411, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, 65, 65, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, 65, 65, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410 }, { 15, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, 62, -411, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, 65, 65, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, 65, 65, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411 }, { 15, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, 62, -412, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, 65, 65, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, 65, 65, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412 }, { 15, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, 62, -413, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, 65, 65, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, 65, 65, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413 }, { 15, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, 62, -414, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, 65, 65, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, 65, 65, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414 }, { 15, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, 62, -415, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, 65, 65, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, 65, 65, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415 }, { 15, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, 62, -416, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, 65, 65, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, 65, 65, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416 }, { 15, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, 62, -417, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, 65, 65, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, 65, 65, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417 }, { 15, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, 62, -418, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, 65, 65, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, 65, 65, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418 }, { 15, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, 62, -419, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, 65, 65, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, 65, 65, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419 }, { 15, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, 62, -420, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, 65, 65, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, 65, 65, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420 }, { 15, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, 62, -421, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, 65, 65, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, 65, 65, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421 }, { 15, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, 62, -422, 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, 65, 65, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, 65, 65, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422 }, { 15, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, 62, -423, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, 65, 65, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, 65, 65, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423 }, { 15, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, 62, -424, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, 65, 65, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, 65, 65, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424 }, { 15, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, 62, -425, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, 65, 65, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, 65, 65, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425 }, { 15, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, 62, -426, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, 65, 65, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, 65, 65, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426 }, { 15, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, 62, -427, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, 65, 65, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, 65, 65, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427 }, { 15, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, 62, -428, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, 65, 65, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, 65, 65, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428 }, { 15, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, 62, -429, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, 65, 65, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, 65, 65, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429 }, { 15, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, 62, -430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, 65, 65, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, 65, 65, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430 }, { 15, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, 433, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431 }, { 15, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, 434, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432 }, { 15, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, 435, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433 }, { 15, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, 436, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434 }, { 15, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, 437, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435 }, { 15, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, 438, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436 }, { 15, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, 439, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437 }, { 15, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, 440, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438 }, { 15, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, 441, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439 }, { 15, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, 442, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440 }, { 15, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, 443, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441 }, { 15, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, 444, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442 }, { 15, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, 445, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443 }, { 15, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, 446, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444 }, { 15, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, 447, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445 }, { 15, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, 448, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446 }, { 15, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, 449, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447 }, { 15, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, 450, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448 }, { 15, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, 451, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449 }, { 15, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, 452, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450 }, { 15, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, 453, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451 }, { 15, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, 454, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452 }, { 15, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, 455, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453 }, { 15, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, 456, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454 }, { 15, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, 457, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455 }, { 15, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, 458, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456 }, { 15, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, 459, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457 }, { 15, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, 460, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458 }, { 15, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, 461, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459 }, { 15, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, 462, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460 }, { 15, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, 463, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461 }, { 15, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, 464, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462 }, { 15, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, 465, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463 }, { 15, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, 466, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464 }, { 15, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, 467, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465 }, { 15, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, 468, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466 }, { 15, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, 469, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467 }, { 15, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, 470, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468 }, { 15, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, 471, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469 }, { 15, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, 472, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470 }, { 15, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, 473, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471 }, { 15, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, 474, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472 }, { 15, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, 475, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473 }, { 15, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, 476, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474 }, { 15, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, 477, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475 }, { 15, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, 478, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476 }, { 15, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, 479, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477 }, { 15, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, 480, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478 }, { 15, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, 481, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479 }, { 15, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, 482, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480 }, { 15, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, 483, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481 }, { 15, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, 484, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482 }, { 15, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, 485, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483 }, { 15, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, 486, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484 }, { 15, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, 487, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485 }, { 15, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, 488, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486 }, { 15, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, 489, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487 }, { 15, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, 490, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488 }, { 15, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, 491, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489 }, { 15, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, 492, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490 }, { 15, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, 493, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491 }, { 15, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, 494, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492 }, { 15, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, 495, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493 }, { 15, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, 496, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494 }, { 15, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, 497, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495 }, { 15, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, 498, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496 }, { 15, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, 499, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497 }, { 15, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, 500, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498 }, { 15, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, 501, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499 }, { 15, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, 502, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500 }, { 15, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, 503, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501 }, { 15, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, 504, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502 }, { 15, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, 505, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503 }, { 15, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, 506, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504 }, { 15, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, 507, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505 }, { 15, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, 508, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506 }, { 15, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, 509, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507 }, { 15, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, 510, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508 }, { 15, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, 511, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509 }, { 15, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, 512, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510 }, { 15, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, 513, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511 }, { 15, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, 514, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512 }, { 15, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, 515, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513 }, { 15, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, 516, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514 }, { 15, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, 517, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515 }, { 15, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, 518, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516 }, { 15, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, 519, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517 }, { 15, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, 520, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518 }, { 15, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, 521, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519 }, { 15, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, 522, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520 }, { 15, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, 523, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521 }, { 15, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, 524, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522 }, { 15, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, 525, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523 }, { 15, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, 526, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524 }, { 15, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, 527, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525 }, { 15, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, 528, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526 }, { 15, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, 529, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527 }, { 15, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, 530, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528 }, { 15, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, 531, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529 }, { 15, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, 532, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530 }, { 15, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, 533, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531 }, { 15, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, 534, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532 }, { 15, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, 535, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533 }, { 15, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, 536, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534 }, { 15, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, 537, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535 }, { 15, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, 538, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536 }, { 15, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, 539, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537 }, { 15, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, 540, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538 }, { 15, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, 541, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539 }, { 15, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, 542, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540 }, { 15, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, 543, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541 }, { 15, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, 544, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542 }, { 15, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, 545, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543 }, { 15, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, 546, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544 }, { 15, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, 547, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545 }, { 15, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, 548, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546 }, { 15, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, 549, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547 }, { 15, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, 550, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548 }, { 15, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549 }, { 15, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550 }, } ; static yy_state_type yy_get_previous_state ( yyscan_t yyscanner ); static yy_state_type yy_try_NUL_trans ( yy_state_type current_state , yyscan_t yyscanner); static int yy_get_next_buffer ( yyscan_t yyscanner ); static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ yyg->yytext_ptr = yy_bp; \ yyg->yytext_ptr -= yyg->yy_more_len; \ yyleng = (int) (yy_cp - yyg->yytext_ptr); \ yyg->yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; #define YY_NUM_RULES 31 #define YY_END_OF_BUFFER 32 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static const flex_int16_t yy_accept[551] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 28, 29, 29, 0, 0, 32, 31, 31, 31, 31, 31, 31, 31, 20, 20, 20, 20, 20, 20, 11, 13, 13, 12, 25, 21, 24, 23, 27, 27, 28, 29, 31, 30, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 19, 0, 0, 0, 0, 0, 13, 13, 16, 16, 13, 13, 0, 13, 21, 0, 23, 22, 23, 0, 28, 29, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 13, 13, 13, 0, 16, 13, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 13, 13, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 10, 2, 8, 8, 8, 5, 13, 13, 13, 13, 13, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 9, 0, 6, 0, 0, 4, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 0, 0, 7, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3 } ; static const yy_state_type yy_NUL_trans[551] = { 0, 16, 17, 23, 23, 33, 33, 37, 37, 39, 39, 40, 40, 41, 41, 0, 0, 43, 43, 43, 43, 43, 43, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 74, 75, 0, 77, 77, 77, 77, 77, 77, 77, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 74, 75, 0, 100, 100, 100, 100, 100, 100, 100, 100, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() (yyg->yy_more_flag = 1) #define YY_MORE_ADJ yyg->yy_more_len #define YY_RESTORE_YY_MORE_OFFSET #line 1 "fitshdr.l" /*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: fitshdr.c,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * fitshdr.l is a Flex description file containing a lexical scanner * definition for extracting keywords and keyvalues from a FITS header. * * It requires Flex v2.5.4 or later. * * Refer to fitshdr.h for a description of the user interface and operating * notes. * *===========================================================================*/ /* Options. */ #define YY_NO_INPUT 1 /* Keywords. */ /* Keyvalue data types. */ /* Characters forming standard unit strings (jwBIQX are not used). */ /* Exclusive start states. */ #line 76 "fitshdr.l" #include #include #include #include #include #include "fitshdr.h" #include "wcsutil.h" // User data associated with yyscanner. struct fitshdr_extra { // Values passed to YY_INPUT. const char *hdr; int nkeyrec; // Used in preempting the call to exit() by yy_fatal_error(). jmp_buf abort_jmp_env; }; #define YY_DECL int fitshdr_scanner(const char header[], int nkeyrec, \ int nkeyids, struct fitskeyid keyids[], int *nreject, \ struct fitskey **keys, yyscan_t yyscanner) #define YY_INPUT(inbuff, count, bufsize) \ { \ if (yyextra->nkeyrec) { \ strncpy(inbuff, yyextra->hdr, 80); \ inbuff[80] = '\n'; \ yyextra->hdr += 80; \ yyextra->nkeyrec--; \ count = 81; \ } else { \ count = YY_NULL; \ } \ } // Preempt the call to exit() by yy_fatal_error(). #define exit(status) longjmp(yyextra->abort_jmp_env, status); // Internal helper functions. static YY_DECL; static void nullfill(char cptr[], int len); // Map status return value to message. const char *fitshdr_errmsg[] = { "Success", "Null fitskey pointer-pointer passed", "Memory allocation failed", "Fatal error returned by Flex parser"}; #line 10327 "fitshdr.c" #line 10328 "fitshdr.c" #define INITIAL 0 #define VALUE 1 #define INLINE 2 #define UNITS 3 #define COMMENT 4 #define ERROR 5 #define FLUSH 6 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #define YY_EXTRA_TYPE struct fitshdr_extra * /* Holds the entire state of the reentrant scanner. */ struct yyguts_t { /* User-defined. Not touched by flex. */ YY_EXTRA_TYPE yyextra_r; /* The rest are the same as the globals declared in the non-reentrant scanner. */ FILE *yyin_r, *yyout_r; size_t yy_buffer_stack_top; /**< index of top of stack. */ size_t yy_buffer_stack_max; /**< capacity of stack. */ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ char yy_hold_char; int yy_n_chars; int yyleng_r; char *yy_c_buf_p; int yy_init; int yy_start; int yy_did_buffer_switch_on_eof; int yy_start_stack_ptr; int yy_start_stack_depth; int *yy_start_stack; yy_state_type yy_last_accepting_state; char* yy_last_accepting_cpos; int yylineno_r; int yy_flex_debug_r; char *yytext_r; int yy_more_flag; int yy_more_len; }; /* end struct yyguts_t */ static int yy_init_globals ( yyscan_t yyscanner ); int yylex_init (yyscan_t* scanner); int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy ( yyscan_t yyscanner ); int yyget_debug ( yyscan_t yyscanner ); void yyset_debug ( int debug_flag , yyscan_t yyscanner ); YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner ); void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner ); FILE *yyget_in ( yyscan_t yyscanner ); void yyset_in ( FILE * _in_str , yyscan_t yyscanner ); FILE *yyget_out ( yyscan_t yyscanner ); void yyset_out ( FILE * _out_str , yyscan_t yyscanner ); int yyget_leng ( yyscan_t yyscanner ); char *yyget_text ( yyscan_t yyscanner ); int yyget_lineno ( yyscan_t yyscanner ); void yyset_lineno ( int _line_number , yyscan_t yyscanner ); int yyget_column ( yyscan_t yyscanner ); void yyset_column ( int _column_no , yyscan_t yyscanner ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap ( yyscan_t yyscanner ); #else extern int yywrap ( yyscan_t yyscanner ); #endif #endif #ifndef YY_NO_UNPUT #endif #ifndef yytext_ptr static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen ( const char * , yyscan_t yyscanner); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput ( yyscan_t yyscanner ); #else static int input ( yyscan_t yyscanner ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ errno=0; \ while ( (result = (int) read( fileno(yyin), buf, (yy_size_t) max_size )) < 0 ) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex (yyscan_t yyscanner); #define YY_DECL int yylex (yyscan_t yyscanner) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK /*LINTED*/break; #endif #define YY_RULE_SETUP \ if ( yyleng > 0 ) \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ (yytext[yyleng - 1] == '\n'); \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { yy_state_type yy_current_state; char *yy_cp, *yy_bp; int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( !yyg->yy_init ) { yyg->yy_init = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! yyg->yy_start ) yyg->yy_start = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } yy_load_buffer_state( yyscanner ); } { #line 128 "fitshdr.l" #line 130 "fitshdr.l" char ctmp[72]; if (keys == 0x0) { return FITSHDRERR_NULL_POINTER; } // Allocate memory for the required number of fitskey structs. // Recall that calloc() initializes allocated memory to zero. struct fitskey *kptr; if (!(kptr = *keys = calloc(nkeyrec, sizeof(struct fitskey)))) { return FITSHDRERR_MEMORY; } // Initialize returned values. *nreject = 0; // Initialize keyids[]. struct fitskeyid *iptr = keyids; for (int j = 0; j < nkeyids; j++, iptr++) { iptr->count = 0; iptr->idx[0] = -1; iptr->idx[1] = -1; } int keyno = 0; int blank = 0; int continuation = 0; int end = 0; #ifdef WCSLIB_INT64 #define asString(S) stringize(S) #define stringize(S) #S const char *int64fmt; if (strcmp(asString(WCSLIB_INT64), "long long int") == 0) { int64fmt = "%lld"; } else if (strcmp(asString(WCSLIB_INT64), "long int") == 0) { int64fmt = "%ld"; } else if (strcmp(asString(WCSLIB_INT64), "int") == 0) { int64fmt = "%d"; } else { return FITSHDRERR_DATA_TYPE; } #endif // User data associated with yyscanner. yyextra->hdr = header; yyextra->nkeyrec = nkeyrec; // Return here via longjmp() invoked by yy_fatal_error(). if (setjmp(yyextra->abort_jmp_env)) { return FITSHDRERR_FLEX_PARSER; } BEGIN(INITIAL); #line 10637 "fitshdr.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { yyg->yy_more_len = 0; if ( yyg->yy_more_flag ) { yyg->yy_more_len = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr); yyg->yy_more_flag = 0; } yy_cp = yyg->yy_c_buf_p; /* Support of yytext. */ *yy_cp = yyg->yy_hold_char; /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = yyg->yy_start; yy_current_state += YY_AT_BOL(); yy_match: while ( (yy_current_state = yy_nxt[yy_current_state][ YY_SC_TO_UI(*yy_cp) ]) > 0 ) { if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } ++yy_cp; } yy_current_state = -yy_current_state; yy_find_action: yy_act = yy_accept[yy_current_state]; YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = yyg->yy_hold_char; yy_cp = yyg->yy_last_accepting_cpos + 1; yy_current_state = yyg->yy_last_accepting_state; goto yy_find_action; case 1: YY_RULE_SETUP #line 187 "fitshdr.l" { // A completely blank keyrecord. strncpy(kptr->keyword, yytext, 8); yyless(0); blank = 1; BEGIN(COMMENT); } YY_BREAK case 2: YY_RULE_SETUP #line 195 "fitshdr.l" { strncpy(kptr->keyword, yytext, 8); BEGIN(COMMENT); } YY_BREAK case 3: YY_RULE_SETUP #line 200 "fitshdr.l" { strncpy(kptr->keyword, yytext, 8); end = 1; BEGIN(FLUSH); } YY_BREAK case 4: YY_RULE_SETUP #line 206 "fitshdr.l" { // Illegal END keyrecord. strncpy(kptr->keyword, yytext, 8); kptr->status |= FITSHDR_KEYREC; BEGIN(VALUE); } YY_BREAK case 5: YY_RULE_SETUP #line 213 "fitshdr.l" { // Illegal END keyrecord. strncpy(kptr->keyword, yytext, 8); kptr->status |= FITSHDR_KEYREC; BEGIN(COMMENT); } YY_BREAK case 6: YY_RULE_SETUP #line 220 "fitshdr.l" { strncpy(kptr->keyword, yytext, 8); BEGIN(VALUE); } YY_BREAK case 7: /* rule 7 can match eol */ YY_RULE_SETUP #line 225 "fitshdr.l" { // Continued string keyvalue. strncpy(kptr->keyword, yytext, 8); if (keyno > 0 && (kptr-1)->type%10 == 8) { // Put back the string keyvalue. int k; for (k = 10; yytext[k] != '\''; k++); yyless(k); continuation = 1; BEGIN(VALUE); } else { // Not a valid continuation. yyless(8); BEGIN(COMMENT); } } YY_BREAK case 8: YY_RULE_SETUP #line 244 "fitshdr.l" { // Keyword without value. strncpy(kptr->keyword, yytext, 8); BEGIN(COMMENT); } YY_BREAK case 9: YY_RULE_SETUP #line 250 "fitshdr.l" { // Illegal keyword, carry on regardless. strncpy(kptr->keyword, yytext, 8); kptr->status |= FITSHDR_KEYWORD; BEGIN(VALUE); } YY_BREAK case 10: YY_RULE_SETUP #line 257 "fitshdr.l" { // Illegal keyword, carry on regardless. strncpy(kptr->keyword, yytext, 8); kptr->status |= FITSHDR_KEYWORD; BEGIN(COMMENT); } YY_BREAK case 11: *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ yyg->yy_c_buf_p = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 264 "fitshdr.l" { // Null keyvalue. BEGIN(INLINE); } YY_BREAK case 12: YY_RULE_SETUP #line 269 "fitshdr.l" { // Logical keyvalue. kptr->type = 1; kptr->keyvalue.i = (*yytext == 'T'); BEGIN(INLINE); } YY_BREAK case 13: YY_RULE_SETUP #line 276 "fitshdr.l" { // 32-bit signed integer keyvalue. kptr->type = 2; if (sscanf(yytext, "%d", &(kptr->keyvalue.i)) < 1) { kptr->status |= FITSHDR_KEYVALUE; BEGIN(ERROR); } BEGIN(INLINE); } YY_BREAK case 14: YY_RULE_SETUP #line 287 "fitshdr.l" { // 64-bit signed integer keyvalue (up to 18 digits). double dtmp; if (wcsutil_str2double(yytext, &dtmp)) { kptr->status |= FITSHDR_KEYVALUE; BEGIN(ERROR); } else if (INT_MIN <= dtmp && dtmp <= INT_MAX) { // Can be accomodated as a 32-bit signed integer. kptr->type = 2; if (sscanf(yytext, "%d", &(kptr->keyvalue.i)) < 1) { kptr->status |= FITSHDR_KEYVALUE; BEGIN(ERROR); } } else { // 64-bit signed integer. kptr->type = 3; #ifdef WCSLIB_INT64 // Native 64-bit integer is available. if (sscanf(yytext, int64fmt, &(kptr->keyvalue.k)) < 1) { kptr->status |= FITSHDR_KEYVALUE; BEGIN(ERROR); } #else // 64-bit integer (up to 18 digits) implemented as int[3]. kptr->keyvalue.k[2] = 0; sprintf(ctmp, "%%%dd%%9d", yyleng-9); if (sscanf(yytext, ctmp, kptr->keyvalue.k+1, kptr->keyvalue.k) < 1) { kptr->status |= FITSHDR_KEYVALUE; BEGIN(ERROR); } else if (*yytext == '-') { kptr->keyvalue.k[0] *= -1; } #endif } BEGIN(INLINE); } YY_BREAK case 15: YY_RULE_SETUP #line 329 "fitshdr.l" { // Very long integer keyvalue (and 19-digit int64). kptr->type = 4; strcpy(ctmp, yytext); int j, k = yyleng; for (j = 0; j < 8; j++) { // Read it backwards. k -= 9; if (k < 0) k = 0; if (sscanf(ctmp+k, "%d", kptr->keyvalue.l+j) < 1) { kptr->status |= FITSHDR_KEYVALUE; BEGIN(ERROR); } if (*yytext == '-') { kptr->keyvalue.l[j] = -abs(kptr->keyvalue.l[j]); } if (k == 0) break; ctmp[k] = '\0'; } // Can it be accomodated as a 64-bit signed integer? if (j == 2 && abs(kptr->keyvalue.l[2]) <= 9 && abs(kptr->keyvalue.l[1]) <= 223372036 && kptr->keyvalue.l[0] <= 854775807 && kptr->keyvalue.l[0] >= -854775808) { kptr->type = 3; #ifdef WCSLIB_INT64 // Native 64-bit integer is available. kptr->keyvalue.l[2] = 0; if (sscanf(yytext, int64fmt, &(kptr->keyvalue.k)) < 1) { kptr->status |= FITSHDR_KEYVALUE; BEGIN(ERROR); } #endif } BEGIN(INLINE); } YY_BREAK case 16: YY_RULE_SETUP #line 370 "fitshdr.l" { // Float keyvalue. kptr->type = 5; if (wcsutil_str2double(yytext, &(kptr->keyvalue.f))) { kptr->status |= FITSHDR_KEYVALUE; BEGIN(ERROR); } BEGIN(INLINE); } YY_BREAK case 17: YY_RULE_SETUP #line 381 "fitshdr.l" { // Integer complex keyvalue. kptr->type = 6; if (sscanf(yytext, "(%lf,%lf)", kptr->keyvalue.c, kptr->keyvalue.c+1) < 2) { kptr->status |= FITSHDR_KEYVALUE; BEGIN(ERROR); } BEGIN(INLINE); } YY_BREAK case 18: YY_RULE_SETUP #line 393 "fitshdr.l" { // Floating point complex keyvalue. kptr->type = 7; char *cptr; int k; for (cptr = ctmp, k = 1; yytext[k] != ','; cptr++, k++) { *cptr = yytext[k]; } *cptr = '\0'; if (wcsutil_str2double(ctmp, kptr->keyvalue.c)) { kptr->status |= FITSHDR_KEYVALUE; BEGIN(ERROR); } for (cptr = ctmp, k++; yytext[k] != ')'; cptr++, k++) { *cptr = yytext[k]; } *cptr = '\0'; if (wcsutil_str2double(ctmp, kptr->keyvalue.c+1)) { kptr->status |= FITSHDR_KEYVALUE; BEGIN(ERROR); } BEGIN(INLINE); } YY_BREAK case 19: /* rule 19 can match eol */ YY_RULE_SETUP #line 422 "fitshdr.l" { // String keyvalue. kptr->type = 8; char *cptr = kptr->keyvalue.s; strcpy(cptr, yytext+1); // Squeeze out repeated quotes. int k = 0; for (int j = 0; j < 72; j++) { if (k < j) { cptr[k] = cptr[j]; } if (cptr[j] == '\0') { if (k) cptr[k-1] = '\0'; break; } else if (cptr[j] == '\'' && cptr[j+1] == '\'') { j++; } k++; } if (*cptr) { // Retain the initial blank in all-blank strings. nullfill(cptr+1, 71); } else { nullfill(cptr, 72); } BEGIN(INLINE); } YY_BREAK case 20: YY_RULE_SETUP #line 455 "fitshdr.l" { kptr->status |= FITSHDR_KEYVALUE; BEGIN(ERROR); } YY_BREAK case 21: *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ yyg->yy_c_buf_p = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 460 "fitshdr.l" { BEGIN(FLUSH); } YY_BREAK case 22: *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ yyg->yy_c_buf_p = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 464 "fitshdr.l" { BEGIN(FLUSH); } YY_BREAK case 23: YY_RULE_SETUP #line 468 "fitshdr.l" { BEGIN(UNITS); } YY_BREAK case 24: YY_RULE_SETUP #line 472 "fitshdr.l" { kptr->status |= FITSHDR_COMMENT; BEGIN(ERROR); } YY_BREAK case 25: YY_RULE_SETUP #line 477 "fitshdr.l" { // Keyvalue parsing must now also be suspect. kptr->status |= FITSHDR_COMMENT; kptr->type = 0; BEGIN(ERROR); } YY_BREAK case 26: YY_RULE_SETUP #line 484 "fitshdr.l" { kptr->ulen = yyleng; yymore(); BEGIN(COMMENT); } YY_BREAK case 27: YY_RULE_SETUP #line 490 "fitshdr.l" { yymore(); BEGIN(COMMENT); } YY_BREAK case 28: YY_RULE_SETUP #line 495 "fitshdr.l" { strcpy(kptr->comment, yytext); nullfill(kptr->comment, 84); BEGIN(FLUSH); } YY_BREAK case 29: YY_RULE_SETUP #line 501 "fitshdr.l" { if (!continuation) kptr->type = -abs(kptr->type); sprintf(kptr->comment, "%.80s", yyextra->hdr-80); kptr->comment[80] = '\0'; nullfill(kptr->comment+80, 4); BEGIN(FLUSH); } YY_BREAK case 30: /* rule 30 can match eol */ YY_RULE_SETUP #line 511 "fitshdr.l" { // Discard the rest of the input line. kptr->keyno = ++keyno; // Null-fill the keyword. kptr->keyword[8] = '\0'; nullfill(kptr->keyword, 12); // Do indexing. iptr = keyids; kptr->keyid = -1; for (int j = 0; j < nkeyids; j++, iptr++) { int k; char *cptr = iptr->name; cptr[8] = '\0'; nullfill(cptr, 12); for (k = 0; k < 8; k++, cptr++) { if (*cptr != '.' && *cptr != kptr->keyword[k]) break; } if (k == 8) { // Found a match. iptr->count++; if (iptr->idx[0] == -1) { iptr->idx[0] = keyno-1; } else { iptr->idx[1] = keyno-1; } kptr->keyno = -abs(kptr->keyno); if (kptr->keyid < 0) kptr->keyid = j; } } // Deal with continued strings. if (continuation) { // Tidy up the previous string keyvalue. if ((kptr-1)->type == 8) (kptr-1)->type += 10; char *cptr = (kptr-1)->keyvalue.s; if (cptr[strlen(cptr)-1] == '&') cptr[strlen(cptr)-1] = '\0'; kptr->type = (kptr-1)->type + 10; } // Check for keyrecords following the END keyrecord. if (end && (end++ > 1) && !blank) { kptr->status |= FITSHDR_TRAILER; } if (kptr->status) (*nreject)++; kptr++; blank = 0; continuation = 0; BEGIN(INITIAL); } YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(VALUE): case YY_STATE_EOF(INLINE): case YY_STATE_EOF(UNITS): case YY_STATE_EOF(COMMENT): case YY_STATE_EOF(ERROR): case YY_STATE_EOF(FLUSH): #line 568 "fitshdr.l" { // End-of-input. return 0; } YY_BREAK case 31: YY_RULE_SETUP #line 573 "fitshdr.l" ECHO; YY_BREAK #line 11190 "fitshdr.c" case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = yyg->yy_hold_char; YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) { /* This was really a NUL. */ yy_state_type yy_next_state; yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++yyg->yy_c_buf_p; yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = yyg->yy_c_buf_p; goto yy_find_action; } } else switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_END_OF_FILE: { yyg->yy_did_buffer_switch_on_eof = 0; if ( yywrap( yyscanner ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: yyg->yy_c_buf_p = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of user's declarations */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; char *source = yyg->yytext_ptr; int number_to_move, i; int ret_val; if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1); for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) (yyg->yy_c_buf_p - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yyrealloc( (void *) b->yy_ch_buf, (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = NULL; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), yyg->yy_n_chars, num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } if ( yyg->yy_n_chars == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin , yyscanner); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); /* "- 2" to take care of EOB's */ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); } yyg->yy_n_chars += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (yyscan_t yyscanner) { yy_state_type yy_current_state; char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_current_state = yyg->yy_start; yy_current_state += YY_AT_BOL(); for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) { if ( *yy_cp ) { yy_current_state = yy_nxt[yy_current_state][YY_SC_TO_UI(*yy_cp)]; } else yy_current_state = yy_NUL_trans[yy_current_state]; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) { int yy_is_jam; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ char *yy_cp = yyg->yy_c_buf_p; yy_current_state = yy_NUL_trans[yy_current_state]; yy_is_jam = (yy_current_state == 0); if ( ! yy_is_jam ) { if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } } (void)yyg; return yy_is_jam ? 0 : yy_current_state; } #ifndef YY_NO_UNPUT #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (yyscan_t yyscanner) #else static int input (yyscan_t yyscanner) #endif { int c; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; *yyg->yy_c_buf_p = yyg->yy_hold_char; if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) /* This was really a NUL. */ *yyg->yy_c_buf_p = '\0'; else { /* need more input */ int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr); ++yyg->yy_c_buf_p; switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin , yyscanner); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( yyscanner ) ) return 0; if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(yyscanner); #else return input(yyscanner); #endif } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + offset; break; } } } c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ yyg->yy_hold_char = *++yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * @param yyscanner The scanner object. * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } yy_init_buffer( YY_CURRENT_BUFFER, input_file , yyscanner); yy_load_buffer_state( yyscanner ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * @param yyscanner The scanner object. */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (yyscanner); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( yyscanner ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ yyg->yy_did_buffer_switch_on_eof = 1; } static void yy_load_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; yyg->yy_hold_char = *yyg->yy_c_buf_p; } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * @param yyscanner The scanner object. * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file , yyscanner); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * @param yyscanner The scanner object. */ void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree( (void *) b->yy_ch_buf , yyscanner ); yyfree( (void *) b , yyscanner ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) { int oerrno = errno; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_flush_buffer( b , yyscanner); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * @param yyscanner The scanner object. */ void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( yyscanner ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * @param yyscanner The scanner object. */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (new_buffer == NULL) return; yyensure_buffer_stack(yyscanner); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) yyg->yy_buffer_stack_top++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * @param yyscanner The scanner object. */ void yypop_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER , yyscanner); YY_CURRENT_BUFFER_LVALUE = NULL; if (yyg->yy_buffer_stack_top > 0) --yyg->yy_buffer_stack_top; if (YY_CURRENT_BUFFER) { yy_load_buffer_state( yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (yyscan_t yyscanner) { yy_size_t num_to_alloc; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!yyg->yy_buffer_stack) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; yyg->yy_buffer_stack_top = 0; return; } if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ /* Increase the buffer to prepare for a possible push. */ yy_size_t grow_size = 8 /* arbitrary grow size */; num_to_alloc = yyg->yy_buffer_stack_max + grow_size; yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc (yyg->yy_buffer_stack, num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return NULL; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = NULL; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer( b , yyscanner ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * @param yyscanner The scanner object. * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (const char * yystr , yyscan_t yyscanner) { return yy_scan_bytes( yystr, (int) strlen(yystr) , yyscanner); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len , yyscan_t yyscanner) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = (yy_size_t) (_yybytes_len + 2); buf = (char *) yyalloc( n , yyscanner ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer( buf, n , yyscanner); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yynoreturn yy_fatal_error (const char* msg , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = yyg->yy_hold_char; \ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ yyg->yy_hold_char = *yyg->yy_c_buf_p; \ *yyg->yy_c_buf_p = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the user-defined data for this scanner. * @param yyscanner The scanner object. */ YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyextra; } /** Get the current line number. * @param yyscanner The scanner object. */ int yyget_lineno (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yylineno; } /** Get the current column number. * @param yyscanner The scanner object. */ int yyget_column (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yycolumn; } /** Get the input stream. * @param yyscanner The scanner object. */ FILE *yyget_in (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyin; } /** Get the output stream. * @param yyscanner The scanner object. */ FILE *yyget_out (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyout; } /** Get the length of the current token. * @param yyscanner The scanner object. */ int yyget_leng (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyleng; } /** Get the current token. * @param yyscanner The scanner object. */ char *yyget_text (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yytext; } /** Set the user-defined data. This data is never touched by the scanner. * @param user_defined The data to be associated with this scanner. * @param yyscanner The scanner object. */ void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyextra = user_defined ; } /** Set the current line number. * @param _line_number line number * @param yyscanner The scanner object. */ void yyset_lineno (int _line_number , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* lineno is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "yyset_lineno called with no buffer" ); yylineno = _line_number; } /** Set the current column. * @param _column_no column number * @param yyscanner The scanner object. */ void yyset_column (int _column_no , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* column is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "yyset_column called with no buffer" ); yycolumn = _column_no; } /** Set the input stream. This does not discard the current * input buffer. * @param _in_str A readable stream. * @param yyscanner The scanner object. * @see yy_switch_to_buffer */ void yyset_in (FILE * _in_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyin = _in_str ; } void yyset_out (FILE * _out_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyout = _out_str ; } int yyget_debug (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yy_flex_debug; } void yyset_debug (int _bdebug , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_flex_debug = _bdebug ; } /* Accessor methods for yylval and yylloc */ /* User-visible API */ /* yylex_init is special because it creates the scanner itself, so it is * the ONLY reentrant function that doesn't take the scanner as the last argument. * That's why we explicitly handle the declaration, instead of using our macros. */ int yylex_init(yyscan_t* ptr_yy_globals) { if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); return yy_init_globals ( *ptr_yy_globals ); } /* yylex_init_extra has the same functionality as yylex_init, but follows the * convention of taking the scanner as the last argument. Note however, that * this is a *pointer* to a scanner, as it will be allocated by this call (and * is the reason, too, why this function also must handle its own declaration). * The user defined value in the first argument will be available to yyalloc in * the yyextra field. */ int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals ) { struct yyguts_t dummy_yyguts; yyset_extra (yy_user_defined, &dummy_yyguts); if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); yyset_extra (yy_user_defined, *ptr_yy_globals); return yy_init_globals ( *ptr_yy_globals ); } static int yy_init_globals (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ yyg->yy_buffer_stack = NULL; yyg->yy_buffer_stack_top = 0; yyg->yy_buffer_stack_max = 0; yyg->yy_c_buf_p = NULL; yyg->yy_init = 0; yyg->yy_start = 0; yyg->yy_start_stack_ptr = 0; yyg->yy_start_stack_depth = 0; yyg->yy_start_stack = NULL; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = NULL; yyout = NULL; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer( YY_CURRENT_BUFFER , yyscanner ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(yyscanner); } /* Destroy the stack itself. */ yyfree(yyg->yy_buffer_stack , yyscanner); yyg->yy_buffer_stack = NULL; /* Destroy the start condition stack. */ yyfree( yyg->yy_start_stack , yyscanner ); yyg->yy_start_stack = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( yyscanner); /* Destroy the main struct (reentrant only). */ yyfree ( yyscanner , yyscanner ); yyscanner = NULL; return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (const char * s , yyscan_t yyscanner) { int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; return malloc(size); } void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return realloc(ptr, size); } void yyfree (void * ptr , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 573 "fitshdr.l" /*---------------------------------------------------------------------------- * External interface to the scanner. *---------------------------------------------------------------------------*/ int fitshdr( const char header[], int nkeyrec, int nkeyids, struct fitskeyid keyids[], int *nreject, struct fitskey **keys) { // Function prototypes. int yylex_init_extra(YY_EXTRA_TYPE extra, yyscan_t *yyscanner); int yylex_destroy(yyscan_t yyscanner); struct fitshdr_extra extra; yyscan_t yyscanner; yylex_init_extra(&extra, &yyscanner); int status = fitshdr_scanner(header, nkeyrec, nkeyids, keyids, nreject, keys, yyscanner); yylex_destroy(yyscanner); return status; } /*---------------------------------------------------------------------------- * Pad a string with null characters. *---------------------------------------------------------------------------*/ void nullfill(char cptr[], int len) { // Propagate the terminating null to the end of the string. int j; for (j = 0; j < len; j++) { if (cptr[j] == '\0') { for (int k = j+1; k < len; k++) { cptr[k] = '\0'; } break; } } // Remove trailing blanks. for (int k = j-1; k >= 0; k--) { if (cptr[k] != ' ') break; cptr[k] = '\0'; } return; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/flexed/wcsbth.c0000644000175100001710000514552600000000000020311 0ustar00vstsdocker#line 2 "wcsbth.c" #line 4 "wcsbth.c" #define _POSIX_C_SOURCE 1 #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 6 #define YY_FLEX_SUBMINOR_VERSION 4 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif #ifdef yy_create_buffer #define wcsbth_create_buffer_ALREADY_DEFINED #else #define yy_create_buffer wcsbth_create_buffer #endif #ifdef yy_delete_buffer #define wcsbth_delete_buffer_ALREADY_DEFINED #else #define yy_delete_buffer wcsbth_delete_buffer #endif #ifdef yy_scan_buffer #define wcsbth_scan_buffer_ALREADY_DEFINED #else #define yy_scan_buffer wcsbth_scan_buffer #endif #ifdef yy_scan_string #define wcsbth_scan_string_ALREADY_DEFINED #else #define yy_scan_string wcsbth_scan_string #endif #ifdef yy_scan_bytes #define wcsbth_scan_bytes_ALREADY_DEFINED #else #define yy_scan_bytes wcsbth_scan_bytes #endif #ifdef yy_init_buffer #define wcsbth_init_buffer_ALREADY_DEFINED #else #define yy_init_buffer wcsbth_init_buffer #endif #ifdef yy_flush_buffer #define wcsbth_flush_buffer_ALREADY_DEFINED #else #define yy_flush_buffer wcsbth_flush_buffer #endif #ifdef yy_load_buffer_state #define wcsbth_load_buffer_state_ALREADY_DEFINED #else #define yy_load_buffer_state wcsbth_load_buffer_state #endif #ifdef yy_switch_to_buffer #define wcsbth_switch_to_buffer_ALREADY_DEFINED #else #define yy_switch_to_buffer wcsbth_switch_to_buffer #endif #ifdef yypush_buffer_state #define wcsbthpush_buffer_state_ALREADY_DEFINED #else #define yypush_buffer_state wcsbthpush_buffer_state #endif #ifdef yypop_buffer_state #define wcsbthpop_buffer_state_ALREADY_DEFINED #else #define yypop_buffer_state wcsbthpop_buffer_state #endif #ifdef yyensure_buffer_stack #define wcsbthensure_buffer_stack_ALREADY_DEFINED #else #define yyensure_buffer_stack wcsbthensure_buffer_stack #endif #ifdef yylex #define wcsbthlex_ALREADY_DEFINED #else #define yylex wcsbthlex #endif #ifdef yyrestart #define wcsbthrestart_ALREADY_DEFINED #else #define yyrestart wcsbthrestart #endif #ifdef yylex_init #define wcsbthlex_init_ALREADY_DEFINED #else #define yylex_init wcsbthlex_init #endif #ifdef yylex_init_extra #define wcsbthlex_init_extra_ALREADY_DEFINED #else #define yylex_init_extra wcsbthlex_init_extra #endif #ifdef yylex_destroy #define wcsbthlex_destroy_ALREADY_DEFINED #else #define yylex_destroy wcsbthlex_destroy #endif #ifdef yyget_debug #define wcsbthget_debug_ALREADY_DEFINED #else #define yyget_debug wcsbthget_debug #endif #ifdef yyset_debug #define wcsbthset_debug_ALREADY_DEFINED #else #define yyset_debug wcsbthset_debug #endif #ifdef yyget_extra #define wcsbthget_extra_ALREADY_DEFINED #else #define yyget_extra wcsbthget_extra #endif #ifdef yyset_extra #define wcsbthset_extra_ALREADY_DEFINED #else #define yyset_extra wcsbthset_extra #endif #ifdef yyget_in #define wcsbthget_in_ALREADY_DEFINED #else #define yyget_in wcsbthget_in #endif #ifdef yyset_in #define wcsbthset_in_ALREADY_DEFINED #else #define yyset_in wcsbthset_in #endif #ifdef yyget_out #define wcsbthget_out_ALREADY_DEFINED #else #define yyget_out wcsbthget_out #endif #ifdef yyset_out #define wcsbthset_out_ALREADY_DEFINED #else #define yyset_out wcsbthset_out #endif #ifdef yyget_leng #define wcsbthget_leng_ALREADY_DEFINED #else #define yyget_leng wcsbthget_leng #endif #ifdef yyget_text #define wcsbthget_text_ALREADY_DEFINED #else #define yyget_text wcsbthget_text #endif #ifdef yyget_lineno #define wcsbthget_lineno_ALREADY_DEFINED #else #define yyget_lineno wcsbthget_lineno #endif #ifdef yyset_lineno #define wcsbthset_lineno_ALREADY_DEFINED #else #define yyset_lineno wcsbthset_lineno #endif #ifdef yyget_column #define wcsbthget_column_ALREADY_DEFINED #else #define yyget_column wcsbthget_column #endif #ifdef yyset_column #define wcsbthset_column_ALREADY_DEFINED #else #define yyset_column wcsbthset_column #endif #ifdef yywrap #define wcsbthwrap_ALREADY_DEFINED #else #define yywrap wcsbthwrap #endif #ifdef yyalloc #define wcsbthalloc_ALREADY_DEFINED #else #define yyalloc wcsbthalloc #endif #ifdef yyrealloc #define wcsbthrealloc_ALREADY_DEFINED #else #define yyrealloc wcsbthrealloc #endif #ifdef yyfree #define wcsbthfree_ALREADY_DEFINED #else #define yyfree wcsbthfree #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #ifndef SIZE_MAX #define SIZE_MAX (~(size_t)0) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ /* TODO: this is always defined, so inline it */ #define yyconst const #if defined(__GNUC__) && __GNUC__ >= 3 #define yynoreturn __attribute__((__noreturn__)) #else #define yynoreturn #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an * integer in range [0..255] for use as an array index. */ #define YY_SC_TO_UI(c) ((YY_CHAR) (c)) /* An opaque pointer. */ #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; #endif /* For convenience, these vars (plus the bison vars far below) are macros in the reentrant scanner. */ #define yyin yyg->yyin_r #define yyout yyg->yyout_r #define yyextra yyg->yyextra_r #define yyleng yyg->yyleng_r #define yytext yyg->yytext_r #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) #define yy_flex_debug yyg->yy_flex_debug_r /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN yyg->yy_start = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START ((yyg->yy_start - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin , yyscanner ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) #define YY_LINENO_REWIND_TO(ptr) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = yyg->yy_hold_char; \ YY_RESTORE_YY_MORE_OFFSET \ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] void yyrestart ( FILE *input_file , yyscan_t yyscanner ); void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner ); void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); void yypop_buffer_state ( yyscan_t yyscanner ); static void yyensure_buffer_stack ( yyscan_t yyscanner ); static void yy_load_buffer_state ( yyscan_t yyscanner ); static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner ); #define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner) YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner ); void *yyalloc ( yy_size_t , yyscan_t yyscanner ); void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner ); void yyfree ( void * , yyscan_t yyscanner ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define wcsbthwrap(yyscanner) (/*CONSTCOND*/1) #define YY_SKIP_YYWRAP typedef flex_uint8_t YY_CHAR; typedef int yy_state_type; #define yytext_ptr yytext_r static const flex_int16_t yy_nxt[][128] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 69, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70 }, { 69, 71, 71, 71, 71, 71, 71, 71, 71, 71, 70, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 72, 72, 72, 72, 72, 72, 72, 72, 72, 71, 71, 71, 71, 71, 71, 71, 71, 73, 74, 75, 76, 71, 71, 77, 71, 78, 71, 79, 80, 71, 81, 82, 71, 83, 84, 85, 71, 86, 87, 88, 71, 89, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71 }, { 69, 90, 90, 90, 90, 90, 90, 90, 90, 90, 70, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 92, 92, 92, 92, 92, 92, 92, 92, 92, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90 }, { 69, 90, 90, 90, 90, 90, 90, 90, 90, 90, 70, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 92, 92, 92, 92, 92, 92, 92, 92, 92, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90 }, { 69, 93, 93, 93, 93, 93, 93, 93, 93, 93, 70, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93 }, { 69, 93, 93, 93, 93, 93, 93, 93, 93, 93, 70, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93 }, { 69, 95, 95, 95, 95, 95, 95, 95, 95, 95, 70, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95 }, { 69, 95, 95, 95, 95, 95, 95, 95, 95, 95, 70, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95 }, { 69, 97, 97, 97, 97, 97, 97, 97, 97, 97, 70, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 98, 98, 98, 98, 98, 98, 98, 98, 98, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97 }, { 69, 97, 97, 97, 97, 97, 97, 97, 97, 97, 70, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 98, 98, 98, 98, 98, 98, 98, 98, 98, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97 }, { 69, 99, 99, 99, 99, 99, 99, 99, 99, 99, 70, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 100, 100, 100, 100, 100, 100, 100, 100, 100, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 }, { 69, 99, 99, 99, 99, 99, 99, 99, 99, 99, 70, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 100, 100, 100, 100, 100, 100, 100, 100, 100, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 }, { 69, 101, 101, 101, 101, 101, 101, 101, 101, 101, 70, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 102, 103, 103, 103, 103, 103, 103, 103, 103, 103, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101 }, { 69, 101, 101, 101, 101, 101, 101, 101, 101, 101, 70, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 102, 103, 103, 103, 103, 103, 103, 103, 103, 103, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101 }, { 69, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 104, 104, 104, 104, 104, 104, 104, 104, 104, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70 }, { 69, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 104, 104, 104, 104, 104, 104, 104, 104, 104, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70 }, { 69, 105, 105, 105, 105, 105, 105, 105, 105, 105, 70, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 106, 106, 106, 106, 106, 106, 106, 106, 106, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105 }, { 69, 105, 105, 105, 105, 105, 105, 105, 105, 105, 70, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 106, 106, 106, 106, 106, 106, 106, 106, 106, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105 }, { 69, 107, 107, 107, 107, 107, 107, 107, 107, 107, 70, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 108, 108, 108, 108, 108, 108, 108, 108, 108, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107 }, { 69, 107, 107, 107, 107, 107, 107, 107, 107, 107, 70, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 108, 108, 108, 108, 108, 108, 108, 108, 108, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107 }, { 69, 109, 109, 109, 109, 109, 109, 109, 109, 109, 70, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109 }, { 69, 109, 109, 109, 109, 109, 109, 109, 109, 109, 70, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109 }, { 69, 111, 111, 111, 111, 111, 111, 111, 111, 111, 70, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 112, 112, 112, 112, 112, 112, 112, 112, 112, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111 }, { 69, 111, 111, 111, 111, 111, 111, 111, 111, 111, 70, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 112, 112, 112, 112, 112, 112, 112, 112, 112, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111 }, { 69, 113, 113, 113, 113, 113, 113, 113, 113, 113, 70, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 114, 114, 114, 114, 114, 114, 114, 114, 114, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113 }, { 69, 113, 113, 113, 113, 113, 113, 113, 113, 113, 70, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 114, 114, 114, 114, 114, 114, 114, 114, 114, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113 }, { 69, 115, 115, 115, 115, 115, 115, 115, 115, 115, 70, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 116, 117, 117, 117, 117, 117, 117, 117, 117, 117, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115 }, { 69, 115, 115, 115, 115, 115, 115, 115, 115, 115, 70, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 116, 117, 117, 117, 117, 117, 117, 117, 117, 117, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115 }, { 69, 118, 118, 118, 118, 118, 118, 118, 118, 118, 70, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 119, 119, 119, 119, 119, 119, 119, 119, 119, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118 }, { 69, 118, 118, 118, 118, 118, 118, 118, 118, 118, 70, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 119, 119, 119, 119, 119, 119, 119, 119, 119, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118 }, { 69, 120, 120, 120, 120, 120, 120, 120, 120, 120, 70, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 121, 121, 121, 121, 121, 121, 121, 121, 121, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120 }, { 69, 120, 120, 120, 120, 120, 120, 120, 120, 120, 70, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 121, 121, 121, 121, 121, 121, 121, 121, 121, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120 }, { 69, 122, 122, 122, 122, 122, 122, 122, 122, 122, 70, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 123, 123, 123, 123, 123, 123, 123, 123, 123, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122 }, { 69, 122, 122, 122, 122, 122, 122, 122, 122, 122, 70, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 123, 123, 123, 123, 123, 123, 123, 123, 123, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122 }, { 69, 124, 124, 124, 124, 124, 124, 124, 124, 124, 70, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 125, 125, 125, 125, 125, 125, 125, 125, 125, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124 }, { 69, 124, 124, 124, 124, 124, 124, 124, 124, 124, 70, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 125, 125, 125, 125, 125, 125, 125, 125, 125, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124 }, { 69, 126, 126, 126, 126, 126, 126, 126, 126, 126, 70, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126 }, { 69, 126, 126, 126, 126, 126, 126, 126, 126, 126, 70, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126 }, { 69, 128, 128, 128, 128, 128, 128, 128, 128, 128, 70, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }, { 69, 128, 128, 128, 128, 128, 128, 128, 128, 128, 70, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }, { 69, 129, 129, 129, 129, 129, 129, 129, 129, 129, 70, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 130, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129 }, { 69, 129, 129, 129, 129, 129, 129, 129, 129, 129, 70, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 130, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129 }, { 69, 131, 131, 131, 131, 131, 131, 131, 131, 131, 70, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 132, 132, 132, 132, 132, 132, 132, 132, 132, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131 }, { 69, 131, 131, 131, 131, 131, 131, 131, 131, 131, 70, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 132, 132, 132, 132, 132, 132, 132, 132, 132, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131 }, { 69, 133, 133, 133, 133, 133, 133, 133, 133, 133, 70, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 134, 134, 134, 134, 134, 134, 134, 134, 134, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133 }, { 69, 133, 133, 133, 133, 133, 133, 133, 133, 133, 70, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 134, 134, 134, 134, 134, 134, 134, 134, 134, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133 }, { 69, 135, 135, 135, 135, 135, 135, 135, 135, 135, 70, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 136, 136, 136, 136, 136, 136, 136, 136, 136, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135 }, { 69, 135, 135, 135, 135, 135, 135, 135, 135, 135, 70, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 136, 136, 136, 136, 136, 136, 136, 136, 136, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135 }, { 69, 137, 137, 137, 137, 137, 137, 137, 137, 137, 70, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 138, 138, 138, 138, 138, 138, 138, 138, 138, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137 }, { 69, 137, 137, 137, 137, 137, 137, 137, 137, 137, 70, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 138, 138, 138, 138, 138, 138, 138, 138, 138, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137 }, { 69, 139, 139, 139, 139, 139, 139, 139, 139, 139, 70, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 140, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139 }, { 69, 139, 139, 139, 139, 139, 139, 139, 139, 139, 70, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 140, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139 }, { 69, 141, 141, 141, 141, 141, 141, 141, 141, 141, 70, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 142, 141, 142, 141, 141, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141 }, { 69, 141, 141, 141, 141, 141, 141, 141, 141, 141, 70, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 142, 141, 142, 141, 141, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141 }, { 69, 144, 144, 144, 144, 144, 144, 144, 144, 144, 70, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 145, 144, 145, 146, 144, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144 }, { 69, 144, 144, 144, 144, 144, 144, 144, 144, 144, 70, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 145, 144, 145, 146, 144, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144 }, { 69, 148, 148, 148, 148, 148, 148, 148, 148, 148, 70, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 149, 148, 149, 150, 148, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148 }, { 69, 148, 148, 148, 148, 148, 148, 148, 148, 148, 70, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 149, 148, 149, 150, 148, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148 }, { 69, 152, 152, 152, 152, 152, 152, 152, 152, 152, 70, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 153, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152 }, { 69, 152, 152, 152, 152, 152, 152, 152, 152, 152, 70, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 153, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152 }, { 69, 154, 154, 154, 154, 154, 154, 154, 154, 154, 155, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 156, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 157, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154 }, { 69, 154, 154, 154, 154, 154, 154, 154, 154, 154, 155, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 156, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 157, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154 }, { 69, 158, 158, 158, 158, 158, 158, 158, 158, 158, 159, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158 }, { 69, 158, 158, 158, 158, 158, 158, 158, 158, 158, 159, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158 }, { 69, 160, 160, 160, 160, 160, 160, 160, 160, 160, 161, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160 }, { 69, 160, 160, 160, 160, 160, 160, 160, 160, 160, 161, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160 }, { 69, 162, 162, 162, 162, 162, 162, 162, 162, 162, 163, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162 }, { 69, 162, 162, 162, 162, 162, 162, 162, 162, 162, 163, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162 }, { -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69 }, { 69, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70 }, { 69, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71 }, { 69, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -72, -72, -72, -72, -72, -72, -72, -72, -72, 165, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, 166, -72, -72, 167, -72, -72, 168, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72 }, { 69, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, 169, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73 }, { 69, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, 170, -74, -74, -74, -74, -74, -74, -74, -74, -74, 171, -74, 172, -74, 173, 174, 175, 176, -74, -74, -74, -74, 177, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74 }, { 69, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, 178, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, 179, -75, -75, -75, 180, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75 }, { 69, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, 181, -76, 182, 183, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76 }, { 69, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, 184, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77 }, { 69, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, 185, 186, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78 }, { 69, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, 187, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, 188, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79 }, { 69, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, 189, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80 }, { 69, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, 190, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81 }, { 69, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, 191, -82, -82, -82, -82, -82, -82, -82, -82, 192, -82, -82, -82, -82, -82, 193, 194, -82, -82, 195, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82 }, { 69, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, 196, -83, -83, -83, 197, 198, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, 199, -83, -83, -83, 200, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83 }, { 69, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, 201, 202, -84, -84, 203, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84 }, { 69, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, 204, -85, 205, 206, -85, -85, 207, -85, -85, -85, -85, -85, -85, 208, -85, 209, 210, -85, -85, 211, 212, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85 }, { 69, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, 213, -86, -86, -86, 214, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, 215, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86 }, { 69, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, 216, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87 }, { 69, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, 217, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88 }, { 69, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, 218, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89 }, { 69, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90 }, { 69, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, 219, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, 220, 221, 221, 221, 221, 221, 221, 221, 221, 221, -91, -91, -91, -91, -91, -91, -91, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91 }, { 69, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, 222, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, -92, -92, -92, -92, -92, -92, -92, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92 }, { 69, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93 }, { 69, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, 224, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, -94, -94, -94, -94, -94, -94, -94, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94 }, { 69, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95 }, { 69, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, 226, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, -96, -96, -96, -96, -96, -96, -96, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96 }, { 69, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97 }, { 69, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, 229, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, -98, -98, -98, -98, -98, -98, -98, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98 }, { 69, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99 }, { 69, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, 231, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, -100, -100, -100, -100, -100, -100, -100, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100 }, { 69, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101 }, { 69, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, 234, -102, -102, 235, 236, 236, 236, 236, 236, 236, 236, 236, 236, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, 237, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102 }, { 69, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, 234, -103, -103, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, 239, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103 }, { 69, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, 240, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, -104, -104, -104, -104, -104, -104, -104, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104 }, { 69, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105 }, { 69, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, 243, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106 }, { 69, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107 }, { 69, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, 245, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108 }, { 69, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109 }, { 69, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, 246, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, -110, -110, -110, -110, -110, -110, -110, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110 }, { 69, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111 }, { 69, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, 248, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, -112, -112, -112, -112, -112, -112, -112, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112 }, { 69, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113 }, { 69, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, 251, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, -114, -114, -114, -114, -114, -114, -114, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114 }, { 69, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115 }, { 69, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, 254, -116, -116, 255, 256, 256, 256, 256, 256, 256, 256, 256, 256, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, 257, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116 }, { 69, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, 254, -117, -117, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, 259, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117 }, { 69, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118 }, { 69, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, 261, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119 }, { 69, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120 }, { 69, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, 263, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121 }, { 69, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122 }, { 69, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, 265, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123 }, { 69, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124 }, { 69, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, 267, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125 }, { 69, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126 }, { 69, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, 268, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127 }, { 69, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128 }, { 69, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129 }, { 69, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130 }, { 69, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131 }, { 69, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, 270, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, -132, -132, -132, -132, -132, -132, -132, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132 }, { 69, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133 }, { 69, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, 272, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, -134, -134, -134, -134, -134, -134, -134, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134 }, { 69, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135 }, { 69, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, 274, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136 }, { 69, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137 }, { 69, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, 276, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138 }, { 69, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139 }, { 69, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, 278, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140 }, { 69, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141 }, { 69, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142 }, { 69, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143 }, { 69, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144 }, { 69, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, 280, -145, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145 }, { 69, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146 }, { 69, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, 283, -147, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, 285, 285, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, 285, 285, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147 }, { 69, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148 }, { 69, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, 286, -149, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149 }, { 69, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150 }, { 69, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, 289, -151, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, 291, 291, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, 291, 291, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151 }, { 69, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152 }, { 69, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 293, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292 }, { 69, 294, 294, 294, 294, 294, 294, 294, 294, 294, 295, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 296, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 297, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294 }, { 69, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155 }, { 69, 298, 298, 298, 298, 298, 298, 298, 298, 298, 299, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 300, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 301, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298 }, { 69, 302, 302, 302, 302, 302, 302, 302, 302, 302, 303, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 304, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 305, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302 }, { 69, 306, 306, 306, 306, 306, 306, 306, 306, 306, 307, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306 }, { 69, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159 }, { 69, 308, 308, 308, 308, 308, 308, 308, 308, 308, 309, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308 }, { 69, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161 }, { 69, 310, 310, 310, 310, 310, 310, 310, 310, 310, 311, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310 }, { 69, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163 }, { 69, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, 312, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, 313, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164 }, { 69, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, 314, -165, -165, -165, -165, -165, -165, -165, -165, -165, 315, -165, 316, -165, 317, 318, 319, 320, -165, -165, -165, -165, 321, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165 }, { 69, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, 322, -166, -166, 323, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166 }, { 69, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167 }, { 69, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168 }, { 69, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, 324, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169 }, { 69, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, 325, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170 }, { 69, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, 326, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171 }, { 69, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, 327, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172 }, { 69, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, 328, -173, -173, -173, -173, -173, -173, -173, 329, -173, -173, 330, 331, -173, -173, -173, -173, -173, 332, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173 }, { 69, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, 333, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174 }, { 69, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, 334, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175 }, { 69, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, 335, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176 }, { 69, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, 336, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177 }, { 69, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, 337, -178, 338, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178 }, { 69, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, 339, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179 }, { 69, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, 340, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180 }, { 69, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, 341, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181 }, { 69, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, 342, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182 }, { 69, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, 343, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183 }, { 69, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, 344, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184 }, { 69, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, 345, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, 346, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185 }, { 69, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, 347, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186 }, { 69, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, 348, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187 }, { 69, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, 349, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188 }, { 69, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, 350, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189 }, { 69, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, 351, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190 }, { 69, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191 }, { 69, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, 352, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192 }, { 69, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, 353, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193 }, { 69, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194 }, { 69, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195 }, { 69, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, 354, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196 }, { 69, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, 355, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197 }, { 69, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, 356, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198 }, { 69, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, 357, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199 }, { 69, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, 358, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200 }, { 69, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, 359, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201 }, { 69, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, 360, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202 }, { 69, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, 361, -203, -203, -203, -203, -203, -203, 362, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203 }, { 69, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, 363, -204, -204, -204, -204, -204, -204, -204, -204, -204, 364, -204, 365, -204, 366, 367, 368, 369, -204, -204, -204, -204, 370, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204 }, { 69, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, 371, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205 }, { 69, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, 372, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206 }, { 69, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, 373, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207 }, { 69, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, 374, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, 375, -208, -208, 376, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208 }, { 69, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, 377, 378, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, 379, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209 }, { 69, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, 380, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210 }, { 69, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211 }, { 69, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, 381, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212 }, { 69, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, 382, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213 }, { 69, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, 383, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214 }, { 69, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, 384, -215, -215, -215, -215, -215, -215, -215, -215, -215, 385, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215 }, { 69, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, 386, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, 387, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216 }, { 69, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, 388, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217 }, { 69, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, 389, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218 }, { 69, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, 390, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219 }, { 69, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, 391, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, 392, 393, 393, 393, 393, 393, 393, 393, 393, 393, -220, -220, -220, -220, -220, -220, -220, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220 }, { 69, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, 394, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, -221, -221, -221, -221, -221, -221, -221, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221 }, { 69, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, 395, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222 }, { 69, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, 396, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, -223, -223, -223, -223, -223, -223, -223, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223 }, { 69, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, 397, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224 }, { 69, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, 398, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, -225, -225, -225, -225, -225, -225, -225, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225 }, { 69, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, 400, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226 }, { 69, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, 401, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, -227, -227, -227, -227, -227, -227, -227, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227 }, { 69, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, 404, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228 }, { 69, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, 405, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229 }, { 69, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, 406, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, -230, -230, -230, -230, -230, -230, -230, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230 }, { 69, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, 408, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231 }, { 69, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, 409, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, -232, -232, -232, -232, -232, -232, -232, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232 }, { 69, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, 412, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233 }, { 69, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234 }, { 69, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, 414, -235, -235, 415, 416, 416, 416, 416, 416, 416, 416, 416, 416, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, 417, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235 }, { 69, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, 414, -236, -236, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, 419, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236 }, { 69, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237 }, { 69, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, 414, -238, -238, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, 422, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238 }, { 69, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, 423, 424, 424, 424, 424, 424, 424, 424, 424, 424, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239 }, { 69, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, 425, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240 }, { 69, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, 426, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, -241, -241, -241, -241, -241, -241, -241, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241 }, { 69, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, 429, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242 }, { 69, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, 430, 430, 430, 430, 430, 430, 430, 430, 430, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243 }, { 69, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, 432, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244 }, { 69, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, 433, 433, 433, 433, 433, 433, 433, 433, 433, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245 }, { 69, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, 434, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246 }, { 69, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, 435, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, -247, -247, -247, -247, -247, -247, -247, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247 }, { 69, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, 437, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248 }, { 69, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, 438, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, -249, -249, -249, -249, -249, -249, -249, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249 }, { 69, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, 441, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250 }, { 69, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, 442, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251 }, { 69, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, 443, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, -252, -252, -252, -252, -252, -252, -252, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252 }, { 69, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, 446, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253 }, { 69, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254 }, { 69, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, 448, -255, -255, 449, 450, 450, 450, 450, 450, 450, 450, 450, 450, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, 451, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255 }, { 69, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, 448, -256, -256, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, 453, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256 }, { 69, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257 }, { 69, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, 448, -258, -258, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, 456, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258 }, { 69, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, 457, 458, 458, 458, 458, 458, 458, 458, 458, 458, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259 }, { 69, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, 460, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260 }, { 69, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, 461, 462, 462, 462, 462, 462, 462, 462, 462, 462, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261 }, { 69, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, 464, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262 }, { 69, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, 465, 466, 466, 466, 466, 466, 466, 466, 466, 466, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263 }, { 69, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, 468, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264 }, { 69, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, 469, 470, 470, 470, 470, 470, 470, 470, 470, 470, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265 }, { 69, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, 472, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266 }, { 69, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, 473, 474, 474, 474, 474, 474, 474, 474, 474, 474, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267 }, { 69, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, 475, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268 }, { 69, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, 476, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, 477, 477, 477, 477, 477, 477, 477, 477, 477, 477, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269 }, { 69, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, 478, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270 }, { 69, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, 479, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, -271, -271, -271, -271, -271, -271, -271, 479, 479, 479, 479, 479, 479, 479, 479, 479, 479, 479, 479, 479, 479, 479, 479, 479, 479, 479, 479, 479, 479, 479, 479, 479, 479, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271 }, { 69, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, 481, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272 }, { 69, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, 482, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, -273, -273, -273, -273, -273, -273, -273, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273 }, { 69, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, 484, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274 }, { 69, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, 485, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275 }, { 69, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, 487, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276 }, { 69, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, 488, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277 }, { 69, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, 278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278 }, { 69, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279 }, { 69, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280 }, { 69, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, 283, -281, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, 285, 285, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, 285, 285, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281 }, { 69, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, 285, 285, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, 285, 285, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282 }, { 69, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, 490, 490, 490, 490, 490, 490, 490, 490, 490, 490, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, 285, 285, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, 285, 285, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283 }, { 69, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, 283, -284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, 285, 285, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, 285, 285, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284 }, { 69, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, 491, -285, 491, -285, -285, 492, 492, 492, 492, 492, 492, 492, 492, 492, 492, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285 }, { 69, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286 }, { 69, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, 289, -287, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, 291, 291, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, 291, 291, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287 }, { 69, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, 291, 291, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, 291, 291, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288 }, { 69, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, 291, 291, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, 291, 291, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289 }, { 69, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, 289, -290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, 291, 291, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, 291, 291, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290 }, { 69, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, 494, -291, 494, -291, -291, 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291 }, { 69, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 293, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292 }, { 69, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, 292, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293 }, { 69, 294, 294, 294, 294, 294, 294, 294, 294, 294, 295, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 296, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 297, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294 }, { 69, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295 }, { 69, 496, 496, 496, 496, 496, 496, 496, 496, 496, 295, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 296, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 297, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496 }, { 69, 497, 497, 497, 497, 497, 497, 497, 497, 497, 498, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 499, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 500, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497 }, { 69, 501, 501, 501, 501, 501, 501, 501, 501, 501, 502, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 503, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 504, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501 }, { 69, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299 }, { 69, 505, 505, 505, 505, 505, 505, 505, 505, 505, 506, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 507, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 508, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505 }, { 69, 302, 302, 302, 302, 302, 302, 302, 302, 302, 303, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 304, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 305, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302 }, { 69, 302, 302, 302, 302, 302, 302, 302, 302, 302, 303, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 304, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 305, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302 }, { 69, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303 }, { 69, 302, 302, 302, 302, 302, 302, 302, 302, 302, 303, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 304, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 305, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302 }, { 69, 302, 302, 302, 302, 302, 302, 302, 302, 302, 303, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 304, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 305, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302 }, { 69, 306, 306, 306, 306, 306, 306, 306, 306, 306, 307, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306 }, { 69, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307 }, { 69, 308, 308, 308, 308, 308, 308, 308, 308, 308, 309, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308 }, { 69, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309 }, { 69, 310, 310, 310, 310, 310, 310, 310, 310, 310, 311, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310 }, { 69, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311 }, { 69, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, 509, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312 }, { 69, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, 510, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313 }, { 69, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, 511, -314, -314, -314, -314, -314, -314, 512, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314 }, { 69, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, 513, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315 }, { 69, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, 514, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, 515, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316 }, { 69, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, 516, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, 517, 518, -317, -317, -317, -317, -317, 519, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317 }, { 69, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, 520, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318 }, { 69, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, 521, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319 }, { 69, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, 522, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320 }, { 69, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, 523, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321 }, { 69, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322 }, { 69, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323 }, { 69, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, 524, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324 }, { 69, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, 525, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325 }, { 69, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, 526, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326 }, { 69, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, 527, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327 }, { 69, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, 528, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328 }, { 69, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, 529, -329, -329, -329, -329, -329, 530, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329 }, { 69, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, 531, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330 }, { 69, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, 532, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331 }, { 69, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, 533, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332 }, { 69, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, 534, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333 }, { 69, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, 535, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334 }, { 69, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, 536, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335 }, { 69, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, 537, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336 }, { 69, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, 538, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337 }, { 69, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, 539, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338 }, { 69, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, 540, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339 }, { 69, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, 541, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340 }, { 69, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, 542, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341 }, { 69, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, 543, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342 }, { 69, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, 544, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343 }, { 69, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, 545, -344, -344, -344, -344, -344, 546, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344 }, { 69, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, 547, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345 }, { 69, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, 548, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346 }, { 69, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, 549, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347 }, { 69, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, 550, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348 }, { 69, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, 551, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349 }, { 69, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, 552, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, 553, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, 554, -350, -350, 555, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350 }, { 69, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, 556, -351, -351, -351, -351, -351, -351, -351, 557, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351 }, { 69, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, 558, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352 }, { 69, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, 559, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353 }, { 69, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, 560, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354 }, { 69, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, 561, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355 }, { 69, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, 562, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356 }, { 69, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, 563, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357 }, { 69, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, 564, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358 }, { 69, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, 565, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359 }, { 69, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, 566, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360 }, { 69, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, 567, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361 }, { 69, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, 568, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362 }, { 69, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, 569, -363, -363, -363, -363, -363, -363, 570, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363 }, { 69, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, 571, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364 }, { 69, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, 572, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, 573, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365 }, { 69, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, 574, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, 575, 576, -366, -366, -366, -366, -366, 577, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366 }, { 69, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, 578, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367 }, { 69, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, 579, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368 }, { 69, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, 580, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369 }, { 69, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, 581, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370 }, { 69, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, 582, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371 }, { 69, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, 583, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372 }, { 69, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, 584, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, 585, 586, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373 }, { 69, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374 }, { 69, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375 }, { 69, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376 }, { 69, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, 587, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377 }, { 69, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, 588, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378 }, { 69, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, 589, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379 }, { 69, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, 590, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, 591, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380 }, { 69, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, 592, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381, -381 }, { 69, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, 593, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382 }, { 69, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, 594, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, 595, -383, -383, 596, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383 }, { 69, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, 597, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384 }, { 69, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, 598, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385 }, { 69, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, 599, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386 }, { 69, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, 600, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, 601, -387, -387, -387, -387, -387, 602, -387, -387, -387, 603, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387 }, { 69, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, 604, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388 }, { 69, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, 605, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389 }, { 69, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390 }, { 69, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391, -391 }, { 69, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392, -392 }, { 69, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393 }, { 69, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394 }, { 69, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395, -395 }, { 69, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, -396 }, { 69, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, 606, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397 }, { 69, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, 607, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, -398 }, { 69, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, 608, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399, -399 }, { 69, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400, -400 }, { 69, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401 }, { 69, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402, -402 }, { 69, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403, -403 }, { 69, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404 }, { 69, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, 609, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405 }, { 69, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, 610, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406 }, { 69, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, 611, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, 611, 611, 611, 611, 611, 611, 611, 611, 611, 611, 611, 611, 611, 611, 611, 611, 611, 611, 611, 611, 611, 611, 611, 611, 611, 611, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407 }, { 69, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408 }, { 69, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409 }, { 69, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410 }, { 69, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411 }, { 69, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412 }, { 69, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, 612, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, 613, 613, 613, 613, 613, 613, 613, 613, 613, 613, -413, -413, -413, -413, -413, -413, -413, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413 }, { 69, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414 }, { 69, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, 615, -415, -415, 616, 617, 617, 617, 617, 617, 617, 617, 617, 617, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, 618, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415 }, { 69, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, 615, -416, -416, 619, 619, 619, 619, 619, 619, 619, 619, 619, 619, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, 620, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416 }, { 69, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417 }, { 69, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, 615, -418, -418, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, 622, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418 }, { 69, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, 623, 624, 624, 624, 624, 624, 624, 624, 624, 624, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419 }, { 69, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, 625, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, -420, -420, -420, -420, -420, -420, -420, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420 }, { 69, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, 615, -421, -421, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, 618, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421 }, { 69, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, 627, 628, 628, 628, 628, 628, 628, 628, 628, 628, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422 }, { 69, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, 625, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, 629, 630, 630, 630, 630, 630, 630, 630, 630, 630, -423, -423, -423, -423, -423, -423, -423, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423 }, { 69, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, 631, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, -424, -424, -424, -424, -424, -424, -424, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424 }, { 69, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, 633, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425 }, { 69, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, 634, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426 }, { 69, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, 635, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427 }, { 69, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, 637, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428 }, { 69, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, 638, 638, 638, 638, 638, 638, 638, 638, 638, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429 }, { 69, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, 639, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, -430, -430, -430, -430, -430, -430, -430, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430 }, { 69, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, 641, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431 }, { 69, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, 642, 642, 642, 642, 642, 642, 642, 642, 642, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432 }, { 69, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, 643, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, -433, -433, -433, -433, -433, -433, -433, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433 }, { 69, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434 }, { 69, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435 }, { 69, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436 }, { 69, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437 }, { 69, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438 }, { 69, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439 }, { 69, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440 }, { 69, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441 }, { 69, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442 }, { 69, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443 }, { 69, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444 }, { 69, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445 }, { 69, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446 }, { 69, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, 645, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, -447, -447, -447, -447, -447, -447, -447, 645, 645, 645, 645, 645, 645, 645, 645, 645, 645, 645, 645, 645, 645, 645, 645, 645, 645, 645, 645, 645, 645, 645, 645, 645, 645, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447 }, { 69, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448 }, { 69, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, 648, -449, -449, 649, 650, 650, 650, 650, 650, 650, 650, 650, 650, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, 651, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449 }, { 69, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, 648, -450, -450, 652, 652, 652, 652, 652, 652, 652, 652, 652, 652, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, 653, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450 }, { 69, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, 654, 654, 654, 654, 654, 654, 654, 654, 654, 654, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451 }, { 69, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, 648, -452, -452, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, 655, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452 }, { 69, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, 656, 657, 657, 657, 657, 657, 657, 657, 657, 657, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453 }, { 69, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, 658, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, 659, 659, 659, 659, 659, 659, 659, 659, 659, 659, -454, -454, -454, -454, -454, -454, -454, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454 }, { 69, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, 648, -455, -455, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, 651, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455 }, { 69, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, 660, 661, 661, 661, 661, 661, 661, 661, 661, 661, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456 }, { 69, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, 662, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, 663, 664, 664, 664, 664, 664, 664, 664, 664, 664, -457, -457, -457, -457, -457, -457, -457, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457 }, { 69, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, 662, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, 665, 665, 665, 665, 665, 665, 665, 665, 665, 665, -458, -458, -458, -458, -458, -458, -458, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458 }, { 69, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, 667, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459 }, { 69, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, 668, 669, 669, 669, 669, 669, 669, 669, 669, 669, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460 }, { 69, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, 670, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461 }, { 69, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, 670, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, -462, -462, -462, -462, -462, -462, -462, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462 }, { 69, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, 672, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463 }, { 69, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, 673, 674, 674, 674, 674, 674, 674, 674, 674, 674, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464 }, { 69, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, 675, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465 }, { 69, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, 675, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, -466, -466, -466, -466, -466, -466, -466, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466 }, { 69, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, 678, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467 }, { 69, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, 679, 680, 680, 680, 680, 680, 680, 680, 680, 680, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468 }, { 69, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, 681, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469 }, { 69, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, 681, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, -470, -470, -470, -470, -470, -470, -470, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470 }, { 69, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, 683, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471 }, { 69, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, 684, 685, 685, 685, 685, 685, 685, 685, 685, 685, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472 }, { 69, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, 686, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473 }, { 69, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, 686, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, 687, 687, 687, 687, 687, 687, 687, 687, 687, 687, -474, -474, -474, -474, -474, -474, -474, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474 }, { 69, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475 }, { 69, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476 }, { 69, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477 }, { 69, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, 688, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478 }, { 69, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, 689, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479 }, { 69, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, 690, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480 }, { 69, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481 }, { 69, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482 }, { 69, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483 }, { 69, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, 691, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484 }, { 69, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, 692, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485 }, { 69, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, 693, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, 694, 694, 694, 694, 694, 694, 694, 694, 694, 694, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486 }, { 69, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487 }, { 69, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488 }, { 69, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489 }, { 69, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, 490, 490, 490, 490, 490, 490, 490, 490, 490, 490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, 285, 285, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, 285, 285, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490 }, { 69, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, 492, 492, 492, 492, 492, 492, 492, 492, 492, 492, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491 }, { 69, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, 492, 492, 492, 492, 492, 492, 492, 492, 492, 492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492 }, { 69, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, 291, 291, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, 291, 291, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493 }, { 69, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494 }, { 69, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495 }, { 69, 496, 496, 496, 496, 496, 496, 496, 496, 496, 695, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 696, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 697, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496 }, { 69, 497, 497, 497, 497, 497, 497, 497, 497, 497, 498, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 499, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 500, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497 }, { 69, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498 }, { 69, 497, 497, 497, 497, 497, 497, 497, 497, 497, 498, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 499, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 500, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497 }, { 69, 497, 497, 497, 497, 497, 497, 497, 497, 497, 498, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 499, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 500, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497 }, { 69, 501, 501, 501, 501, 501, 501, 501, 501, 501, 502, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 503, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 504, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501 }, { 69, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502 }, { 69, 501, 501, 501, 501, 501, 501, 501, 501, 501, 502, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 503, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 504, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501 }, { 69, 698, 698, 698, 698, 698, 698, 698, 698, 698, 699, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 700, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 701, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698 }, { 69, 501, 501, 501, 501, 501, 501, 501, 501, 501, 502, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 503, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 504, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501 }, { 69, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506 }, { 69, 505, 505, 505, 505, 505, 505, 505, 505, 505, 506, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 507, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 508, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505 }, { 69, 702, 702, 702, 702, 702, 702, 702, 702, 702, 703, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 704, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 705, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702 }, { 69, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509 }, { 69, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510 }, { 69, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511 }, { 69, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, 706, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512 }, { 69, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, 707, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513 }, { 69, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, 708, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514 }, { 69, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515 }, { 69, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, 709, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516 }, { 69, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, 710, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517 }, { 69, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, 711, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518 }, { 69, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, 712, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519 }, { 69, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, 713, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520 }, { 69, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, 714, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521 }, { 69, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, 715, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522 }, { 69, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, 716, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523 }, { 69, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, 717, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524 }, { 69, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, 718, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525 }, { 69, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, 719, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526 }, { 69, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, 720, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527 }, { 69, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, 721, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528 }, { 69, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, 722, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529 }, { 69, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, 723, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530 }, { 69, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, 724, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531 }, { 69, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, 725, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532 }, { 69, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, 726, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533 }, { 69, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, 727, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534 }, { 69, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, 728, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, -535 }, { 69, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, 729, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536 }, { 69, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, 730, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537 }, { 69, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, 731, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, 732, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, -538 }, { 69, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, -539 }, { 69, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, 733, 733, 733, 733, 733, 733, 733, 733, 733, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540 }, { 69, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, 734, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541 }, { 69, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, 735, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542, -542 }, { 69, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, 736, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543, -543 }, { 69, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, 737, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544, -544 }, { 69, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, 738, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545 }, { 69, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, 739, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, -546 }, { 69, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, 740, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547, -547 }, { 69, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, 741, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548 }, { 69, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, 742, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549 }, { 69, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, 743, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550 }, { 69, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, 744, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551 }, { 69, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, 745, 746, -552, -552, 747, -552, -552, -552, -552, -552, -552, -552, -552, -552, 748, -552, -552, 749, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552 }, { 69, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553 }, { 69, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, 750, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554 }, { 69, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, 751, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555 }, { 69, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, 752, -556, -556, 753, -556, -556, 754, -556, -556, -556, 755, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, 756, 757, 758, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556 }, { 69, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, 759, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557 }, { 69, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, 760, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558 }, { 69, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, 761, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559 }, { 69, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, 762, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, 763, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560 }, { 69, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, 764, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, 765, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561 }, { 69, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562 }, { 69, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, 766, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563 }, { 69, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564 }, { 69, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565 }, { 69, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, 767, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566 }, { 69, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567 }, { 69, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, 768, -568, -568, -568, 769, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568 }, { 69, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569 }, { 69, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, 770, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570 }, { 69, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, 771, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571 }, { 69, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, 772, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572 }, { 69, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573 }, { 69, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, 773, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574 }, { 69, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, 774, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575 }, { 69, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, 775, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576 }, { 69, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, 776, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577 }, { 69, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, 777, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578 }, { 69, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, 778, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579 }, { 69, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, 779, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580 }, { 69, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, 780, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581 }, { 69, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, 781, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582 }, { 69, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, 782, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583 }, { 69, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, 783, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, 784, 785, -584, -584, 786, -584, 787, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584 }, { 69, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, 788, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585 }, { 69, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, 789, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586 }, { 69, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, 790, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587 }, { 69, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, 791, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, 792, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588 }, { 69, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, 793, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589 }, { 69, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, 794, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590 }, { 69, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, 795, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591 }, { 69, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592 }, { 69, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593 }, { 69, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, 796, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594 }, { 69, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, 797, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595 }, { 69, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, 798, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596 }, { 69, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, 799, 799, 799, 799, 799, 799, 799, 799, 799, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, 800, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597 }, { 69, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598 }, { 69, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, 801, 801, 801, 801, 801, 801, 801, 801, 801, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599 }, { 69, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, 802, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600 }, { 69, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, 803, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601 }, { 69, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, 804, 804, 804, 804, 804, 804, 804, 804, 804, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602 }, { 69, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, 805, 805, 805, 805, 805, 805, 805, 805, 805, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603 }, { 69, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, 806, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604 }, { 69, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, 807, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605 }, { 69, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606 }, { 69, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607 }, { 69, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608 }, { 69, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609 }, { 69, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610 }, { 69, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611 }, { 69, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, 808, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612 }, { 69, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, 809, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, 810, 810, 810, 810, 810, 810, 810, 810, 810, 810, -613, -613, -613, -613, -613, -613, -613, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613 }, { 69, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, 811, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, 812, 812, 812, 812, 812, 812, 812, 812, 812, 812, -614, -614, -614, -614, -614, -614, -614, 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614 }, { 69, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615 }, { 69, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, 814, -616, -616, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, 816, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616 }, { 69, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, 814, -617, -617, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, 817, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617 }, { 69, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, 818, 818, 818, 818, 818, 818, 818, 818, 818, 818, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618 }, { 69, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, 814, -619, -619, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, 819, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619 }, { 69, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, 820, 821, 821, 821, 821, 821, 821, 821, 821, 821, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620 }, { 69, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, 822, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, 823, 823, 823, 823, 823, 823, 823, 823, 823, 823, -621, -621, -621, -621, -621, -621, -621, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621 }, { 69, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, 824, 825, 825, 825, 825, 825, 825, 825, 825, 825, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622 }, { 69, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, 822, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, 826, 827, 827, 827, 827, 827, 827, 827, 827, 827, -623, -623, -623, -623, -623, -623, -623, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623 }, { 69, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, 828, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, 829, 829, 829, 829, 829, 829, 829, 829, 829, 829, -624, -624, -624, -624, -624, -624, -624, 828, 828, 828, 828, 828, 828, 828, 828, 828, 828, 828, 828, 828, 828, 828, 828, 828, 828, 828, 828, 828, 828, 828, 828, 828, 828, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624 }, { 69, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, 830, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625 }, { 69, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, 831, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, -626, -626, -626, -626, -626, -626, -626, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626 }, { 69, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, 822, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, 833, 834, 834, 834, 834, 834, 834, 834, 834, 834, -627, -627, -627, -627, -627, -627, -627, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627 }, { 69, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, 835, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, 836, 836, 836, 836, 836, 836, 836, 836, 836, 836, -628, -628, -628, -628, -628, -628, -628, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628 }, { 69, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, 831, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, 837, 838, 838, 838, 838, 838, 838, 838, 838, 838, -629, -629, -629, -629, -629, -629, -629, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629 }, { 69, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, 839, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, 840, 840, 840, 840, 840, 840, 840, 840, 840, 840, -630, -630, -630, -630, -630, -630, -630, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630 }, { 69, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, 841, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631 }, { 69, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, 842, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, -632, -632, -632, -632, -632, -632, -632, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632 }, { 69, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633 }, { 69, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634 }, { 69, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635 }, { 69, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, 843, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636 }, { 69, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, 844, 844, 844, 844, 844, 844, 844, 844, 844, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637 }, { 69, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, 845, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, -638, -638, -638, -638, -638, -638, -638, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638 }, { 69, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, 847, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639 }, { 69, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, 848, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, -640, -640, -640, -640, -640, -640, -640, 848, 848, 848, 848, 848, 848, 848, 848, 848, 848, 848, 848, 848, 848, 848, 848, 848, 848, 848, 848, 848, 848, 848, 848, 848, 848, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640 }, { 69, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, 850, 850, 850, 850, 850, 850, 850, 850, 850, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641 }, { 69, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, 851, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, -642, -642, -642, -642, -642, -642, -642, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642 }, { 69, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, 853, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643 }, { 69, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, 854, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, -644, -644, -644, -644, -644, -644, -644, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644 }, { 69, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, 856, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645 }, { 69, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, 857, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, -646, -646, -646, -646, -646, -646, -646, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646 }, { 69, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, 859, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, -647, -647, -647, -647, -647, -647, -647, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647 }, { 69, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648 }, { 69, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, 862, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, 863, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649 }, { 69, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, 862, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, 864, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650 }, { 69, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651 }, { 69, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, 862, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, 866, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652 }, { 69, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, 867, 868, 868, 868, 868, 868, 868, 868, 868, 868, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653 }, { 69, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, 869, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, -654, -654, -654, -654, -654, -654, -654, 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654 }, { 69, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, 871, 872, 872, 872, 872, 872, 872, 872, 872, 872, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655 }, { 69, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, 873, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, 874, 875, 875, 875, 875, 875, 875, 875, 875, 875, -656, -656, -656, -656, -656, -656, -656, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656 }, { 69, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, 873, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, 876, 876, 876, 876, 876, 876, 876, 876, 876, 876, -657, -657, -657, -657, -657, -657, -657, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657 }, { 69, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, 877, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658 }, { 69, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, 878, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, -659, -659, -659, -659, -659, -659, -659, 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659 }, { 69, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, 880, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, 881, 882, 882, 882, 882, 882, 882, 882, 882, 882, -660, -660, -660, -660, -660, -660, -660, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660 }, { 69, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, 880, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, -661, -661, -661, -661, -661, -661, -661, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661 }, { 69, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, 884, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662 }, { 69, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, 885, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, 886, 887, 887, 887, 887, 887, 887, 887, 887, 887, -663, -663, -663, -663, -663, -663, -663, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663 }, { 69, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, 885, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, -664, -664, -664, -664, -664, -664, -664, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664 }, { 69, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, 889, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, -665, -665, -665, -665, -665, -665, -665, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665 }, { 69, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, 890, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666 }, { 69, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, 891, 892, 892, 892, 892, 892, 892, 892, 892, 892, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667 }, { 69, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, 893, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668 }, { 69, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, 893, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, -669, -669, -669, -669, -669, -669, -669, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669 }, { 69, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, 895, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670 }, { 69, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, 896, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, -671, -671, -671, -671, -671, -671, -671, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671 }, { 69, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672 }, { 69, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, 899, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673 }, { 69, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, 899, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, -674, -674, -674, -674, -674, -674, -674, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674 }, { 69, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, 901, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675 }, { 69, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, 902, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, -676, -676, -676, -676, -676, -676, -676, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676 }, { 69, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, 904, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677 }, { 69, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, 905, 906, 906, 906, 906, 906, 906, 906, 906, 906, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678 }, { 69, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, 907, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679 }, { 69, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, 907, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, 908, 908, 908, 908, 908, 908, 908, 908, 908, 908, -680, -680, -680, -680, -680, -680, -680, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680 }, { 69, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, 909, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681 }, { 69, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, 910, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, 911, 911, 911, 911, 911, 911, 911, 911, 911, 911, -682, -682, -682, -682, -682, -682, -682, 910, 910, 910, 910, 910, 910, 910, 910, 910, 910, 910, 910, 910, 910, 910, 910, 910, 910, 910, 910, 910, 910, 910, 910, 910, 910, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682 }, { 69, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, 912, 912, 912, 912, 912, 912, 912, 912, 912, 912, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683 }, { 69, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, 913, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684 }, { 69, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, 913, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, 914, 914, 914, 914, 914, 914, 914, 914, 914, 914, -685, -685, -685, -685, -685, -685, -685, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685 }, { 69, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, 915, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686 }, { 69, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, 916, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, 917, 917, 917, 917, 917, 917, 917, 917, 917, 917, -687, -687, -687, -687, -687, -687, -687, 916, 916, 916, 916, 916, 916, 916, 916, 916, 916, 916, 916, 916, 916, 916, 916, 916, 916, 916, 916, 916, 916, 916, 916, 916, 916, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687 }, { 69, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688 }, { 69, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689 }, { 69, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690 }, { 69, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691 }, { 69, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692 }, { 69, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693 }, { 69, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694 }, { 69, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695 }, { 69, 496, 496, 496, 496, 496, 496, 496, 496, 496, 695, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 696, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 697, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496 }, { 69, 918, 918, 918, 918, 918, 918, 918, 918, 918, 919, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 920, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 921, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918 }, { 69, 698, 698, 698, 698, 698, 698, 698, 698, 698, 699, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 700, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 701, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698 }, { 69, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699 }, { 69, 698, 698, 698, 698, 698, 698, 698, 698, 698, 699, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 700, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 701, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698 }, { 69, 698, 698, 698, 698, 698, 698, 698, 698, 698, 699, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 700, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 701, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698 }, { 69, 702, 702, 702, 702, 702, 702, 702, 702, 702, 703, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 704, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 705, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702 }, { 69, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703 }, { 69, 702, 702, 702, 702, 702, 702, 702, 702, 702, 703, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 704, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 705, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702 }, { 69, 702, 702, 702, 702, 702, 702, 702, 702, 702, 703, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 704, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 705, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702 }, { 69, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706 }, { 69, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707 }, { 69, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708 }, { 69, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709 }, { 69, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710 }, { 69, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711 }, { 69, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712 }, { 69, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713 }, { 69, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714 }, { 69, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715 }, { 69, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716 }, { 69, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, 922, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717, -717 }, { 69, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718 }, { 69, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719, -719 }, { 69, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720 }, { 69, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721 }, { 69, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, 923, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722 }, { 69, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, 924, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723 }, { 69, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724 }, { 69, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725 }, { 69, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726 }, { 69, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727 }, { 69, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728 }, { 69, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729 }, { 69, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730 }, { 69, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, 925, 926, -731, -731, 927, -731, -731, -731, -731, -731, -731, -731, -731, -731, 928, -731, -731, 929, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731 }, { 69, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, 930, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732 }, { 69, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, 931, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, 932, 932, 932, 932, 932, 932, 932, 932, 932, 932, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733 }, { 69, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, 933, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734 }, { 69, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, 934, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735 }, { 69, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, 935, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, 935, 935, 935, 935, 935, 935, 935, 935, 935, 935, 935, 935, 935, 935, 935, 935, 935, 935, 935, 935, 935, 935, 935, 935, 935, 935, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736 }, { 69, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, 936, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737 }, { 69, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, 937, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738 }, { 69, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, 938, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739 }, { 69, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, 939, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740 }, { 69, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, 940, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, 941, -741, -741, 942, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741 }, { 69, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, 943, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742 }, { 69, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, 944, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743 }, { 69, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, 945, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744 }, { 69, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, 946, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745 }, { 69, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, 947, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746 }, { 69, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, 948, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747 }, { 69, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, 949, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748 }, { 69, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, 950, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749 }, { 69, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750 }, { 69, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, 951, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751 }, { 69, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, 952, 952, 952, 952, 952, 952, 952, 952, 952, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752 }, { 69, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, 953, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753 }, { 69, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, 954, 954, 954, 954, 954, 954, 954, 954, 954, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754 }, { 69, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, 955, 955, 955, 955, 955, 955, 955, 955, 955, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755 }, { 69, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756 }, { 69, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757 }, { 69, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758 }, { 69, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, 956, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759 }, { 69, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, 957, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760 }, { 69, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761 }, { 69, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, 958, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762 }, { 69, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, 959, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763 }, { 69, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, 960, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764 }, { 69, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, 961, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765 }, { 69, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, 962, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766 }, { 69, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, 963, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767 }, { 69, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, 964, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768 }, { 69, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, 965, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769 }, { 69, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770 }, { 69, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771 }, { 69, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772 }, { 69, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773 }, { 69, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774 }, { 69, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775 }, { 69, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776 }, { 69, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777 }, { 69, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778 }, { 69, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779 }, { 69, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780 }, { 69, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, 966, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781 }, { 69, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, 967, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782 }, { 69, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, 968, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783 }, { 69, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, 969, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784 }, { 69, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, 970, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785 }, { 69, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, 971, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786 }, { 69, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, 972, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787 }, { 69, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, 973, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788 }, { 69, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, 974, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789 }, { 69, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790 }, { 69, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, 975, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791 }, { 69, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, 976, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792 }, { 69, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793 }, { 69, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, 977, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794 }, { 69, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, 978, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795 }, { 69, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, 979, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796 }, { 69, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, 980, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797 }, { 69, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, 981, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798 }, { 69, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, 982, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, -799, -799, -799, -799, -799, -799, -799, 982, 982, 982, 982, 982, 982, 982, 982, 982, 982, 982, 982, 982, 982, 982, 982, 982, 982, 982, 982, 982, 982, 982, 982, 982, 982, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799 }, { 69, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, 984, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800 }, { 69, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, 985, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, -801, -801, -801, -801, -801, -801, -801, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801 }, { 69, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, 987, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802 }, { 69, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, 988, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803 }, { 69, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, 989, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, -804, -804, -804, -804, -804, -804, -804, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804 }, { 69, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, 991, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, -805, -805, -805, -805, -805, -805, -805, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805 }, { 69, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, 993, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806 }, { 69, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, 994, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807 }, { 69, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, 995, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808 }, { 69, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, 996, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809 }, { 69, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, 997, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, -810, -810, -810, -810, -810, -810, -810, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810 }, { 69, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, 999, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811 }, { 69, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, 1000, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, -812, -812, -812, -812, -812, -812, -812, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812 }, { 69, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, 1002, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, -813, -813, -813, -813, -813, -813, -813, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813 }, { 69, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814 }, { 69, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815 }, { 69, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, 1006, 1006, 1006, 1006, 1006, 1006, 1006, 1006, 1006, 1006, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816 }, { 69, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, 1006, 1007, 1007, 1007, 1007, 1007, 1007, 1007, 1007, 1007, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817 }, { 69, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, 1008, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, 1009, 1009, 1009, 1009, 1009, 1009, 1009, 1009, 1009, 1009, -818, -818, -818, -818, -818, -818, -818, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818 }, { 69, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, 1006, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819 }, { 69, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, 1008, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, 1009, 1011, 1011, 1011, 1011, 1011, 1011, 1011, 1011, 1011, -820, -820, -820, -820, -820, -820, -820, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820 }, { 69, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, 1012, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, 1013, 1013, 1013, 1013, 1013, 1013, 1013, 1013, 1013, 1013, -821, -821, -821, -821, -821, -821, -821, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1012, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821 }, { 69, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, 1014, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822 }, { 69, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, 1015, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, -823, -823, -823, -823, -823, -823, -823, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823 }, { 69, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, 1008, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, 1009, 1017, 1017, 1017, 1017, 1017, 1017, 1017, 1017, 1017, -824, -824, -824, -824, -824, -824, -824, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824 }, { 69, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, 1018, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1019, -825, -825, -825, -825, -825, -825, -825, 1018, 1018, 1018, 1018, 1018, 1018, 1018, 1018, 1018, 1018, 1018, 1018, 1018, 1018, 1018, 1018, 1018, 1018, 1018, 1018, 1018, 1018, 1018, 1018, 1018, 1018, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825 }, { 69, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, 1015, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, 1016, 1020, 1020, 1020, 1020, 1020, 1020, 1020, 1020, 1020, -826, -826, -826, -826, -826, -826, -826, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826 }, { 69, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, 1021, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, 1022, 1022, 1022, 1022, 1022, 1022, 1022, 1022, 1022, 1022, -827, -827, -827, -827, -827, -827, -827, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827 }, { 69, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, 1023, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828 }, { 69, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, 1024, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, -829, -829, -829, -829, -829, -829, -829, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829 }, { 69, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, 1025, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830 }, { 69, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, 1026, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831 }, { 69, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, 1027, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, -832, -832, -832, -832, -832, -832, -832, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832 }, { 69, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, 1015, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, 1016, 1029, 1029, 1029, 1029, 1029, 1029, 1029, 1029, 1029, -833, -833, -833, -833, -833, -833, -833, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833 }, { 69, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, 1030, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, 1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, -834, -834, -834, -834, -834, -834, -834, 1030, 1030, 1030, 1030, 1030, 1030, 1030, 1030, 1030, 1030, 1030, 1030, 1030, 1030, 1030, 1030, 1030, 1030, 1030, 1030, 1030, 1030, 1030, 1030, 1030, 1030, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834 }, { 69, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, 1032, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835 }, { 69, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, 1033, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, -836, -836, -836, -836, -836, -836, -836, 1033, 1033, 1033, 1033, 1033, 1033, 1033, 1033, 1033, 1033, 1033, 1033, 1033, 1033, 1033, 1033, 1033, 1033, 1033, 1033, 1033, 1033, 1033, 1033, 1033, 1033, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836 }, { 69, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, 1027, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, 1028, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034, -837, -837, -837, -837, -837, -837, -837, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837 }, { 69, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, 1035, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, -838, -838, -838, -838, -838, -838, -838, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838 }, { 69, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, 1037, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839 }, { 69, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, 1038, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, -840, -840, -840, -840, -840, -840, -840, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840 }, { 69, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, 1039, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841 }, { 69, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, 1040, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842 }, { 69, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843 }, { 69, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, 1042, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, 1043, 1043, 1043, 1043, 1043, 1043, 1043, 1043, 1043, 1043, -844, -844, -844, -844, -844, -844, -844, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844 }, { 69, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, 1044, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845 }, { 69, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, 1045, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, -846, -846, -846, -846, -846, -846, -846, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846 }, { 69, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, 1047, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847 }, { 69, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, 1048, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848 }, { 69, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, 1049, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050, -849, -849, -849, -849, -849, -849, -849, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849 }, { 69, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850 }, { 69, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851 }, { 69, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852 }, { 69, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853 }, { 69, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854 }, { 69, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855 }, { 69, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, 1051, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856 }, { 69, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, 1052, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857 }, { 69, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, 1053, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, -858, -858, -858, -858, -858, -858, -858, 1053, 1053, 1053, 1053, 1053, 1053, 1053, 1053, 1053, 1053, 1053, 1053, 1053, 1053, 1053, 1053, 1053, 1053, 1053, 1053, 1053, 1053, 1053, 1053, 1053, 1053, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858 }, { 69, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, 1055, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859 }, { 69, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, 1056, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, -860, -860, -860, -860, -860, -860, -860, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860 }, { 69, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, 1058, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, -861, -861, -861, -861, -861, -861, -861, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861 }, { 69, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862 }, { 69, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863 }, { 69, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864 }, { 69, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, 1063, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, 1064, 1064, 1064, 1064, 1064, 1064, 1064, 1064, 1064, 1064, -865, -865, -865, -865, -865, -865, -865, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865 }, { 69, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, 1065, 1065, 1065, 1065, 1065, 1065, 1065, 1065, 1065, 1065, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866 }, { 69, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, 1066, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, 1067, 1067, 1067, 1067, 1067, 1067, 1067, 1067, 1067, 1067, -867, -867, -867, -867, -867, -867, -867, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867 }, { 69, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, 1066, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, 1068, 1068, 1068, 1068, 1068, 1068, 1068, 1068, 1068, 1068, -868, -868, -868, -868, -868, -868, -868, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868 }, { 69, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, 1069, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869 }, { 69, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, 1070, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, 1071, 1071, 1071, 1071, 1071, 1071, 1071, 1071, 1071, 1071, -870, -870, -870, -870, -870, -870, -870, 1070, 1070, 1070, 1070, 1070, 1070, 1070, 1070, 1070, 1070, 1070, 1070, 1070, 1070, 1070, 1070, 1070, 1070, 1070, 1070, 1070, 1070, 1070, 1070, 1070, 1070, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870 }, { 69, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, 1072, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, -871, -871, -871, -871, -871, -871, -871, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871 }, { 69, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, 1072, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, 1074, 1074, 1074, 1074, 1074, 1074, 1074, 1074, 1074, 1074, -872, -872, -872, -872, -872, -872, -872, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, 1072, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872 }, { 69, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, 1075, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873 }, { 69, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, 1076, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, 1077, 1077, 1077, 1077, 1077, 1077, 1077, 1077, 1077, 1077, -874, -874, -874, -874, -874, -874, -874, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874 }, { 69, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, 1076, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, 1078, 1078, 1078, 1078, 1078, 1078, 1078, 1078, 1078, 1078, -875, -875, -875, -875, -875, -875, -875, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875 }, { 69, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, 1079, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, 1071, 1071, 1071, 1071, 1071, 1071, 1071, 1071, 1071, 1071, -876, -876, -876, -876, -876, -876, -876, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876 }, { 69, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, 1080, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877 }, { 69, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, 1081, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878 }, { 69, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, 1082, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, -879, -879, -879, -879, -879, -879, -879, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879 }, { 69, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, 1084, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880 }, { 69, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, 1085, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, -881, -881, -881, -881, -881, -881, -881, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881 }, { 69, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, 1085, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, -882, -882, -882, -882, -882, -882, -882, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882 }, { 69, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, 1088, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, 1071, 1071, 1071, 1071, 1071, 1071, 1071, 1071, 1071, 1071, -883, -883, -883, -883, -883, -883, -883, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883 }, { 69, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, 1089, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884 }, { 69, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, 1090, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885 }, { 69, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, 1091, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, -886, -886, -886, -886, -886, -886, -886, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886 }, { 69, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, 1091, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, -887, -887, -887, -887, -887, -887, -887, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887 }, { 69, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, 1094, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, -888, -888, -888, -888, -888, -888, -888, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888 }, { 69, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, 1095, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889 }, { 69, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890 }, { 69, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, 1097, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891 }, { 69, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, 1097, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, -892, -892, -892, -892, -892, -892, -892, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892 }, { 69, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, 1099, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893 }, { 69, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, 1100, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, -894, -894, -894, -894, -894, -894, -894, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894 }, { 69, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, 1102, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895 }, { 69, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, 1103, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896 }, { 69, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, 1104, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, -897, -897, -897, -897, -897, -897, -897, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897 }, { 69, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898 }, { 69, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899 }, { 69, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900 }, { 69, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901 }, { 69, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902 }, { 69, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903 }, { 69, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904 }, { 69, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, 1107, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905 }, { 69, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, 1107, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, -906, -906, -906, -906, -906, -906, -906, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906 }, { 69, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, 1109, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907 }, { 69, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, 1110, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, -908, -908, -908, -908, -908, -908, -908, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908 }, { 69, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, 1112, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909 }, { 69, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, 1113, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910 }, { 69, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, 1114, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, -911, -911, -911, -911, -911, -911, -911, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911 }, { 69, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912 }, { 69, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913 }, { 69, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914 }, { 69, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915 }, { 69, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916 }, { 69, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917 }, { 69, 918, 918, 918, 918, 918, 918, 918, 918, 918, 919, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 920, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 921, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918 }, { 69, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919 }, { 69, 918, 918, 918, 918, 918, 918, 918, 918, 918, 919, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 920, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 921, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918 }, { 69, 918, 918, 918, 918, 918, 918, 918, 918, 918, 919, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 920, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 921, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918 }, { 69, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, 1116, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922 }, { 69, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, 1117, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923 }, { 69, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, 1118, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924 }, { 69, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, 1119, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925 }, { 69, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, 1120, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926 }, { 69, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, 1121, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927 }, { 69, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, 1122, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928 }, { 69, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, 1123, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929 }, { 69, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, 1124, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930 }, { 69, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, 1125, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931 }, { 69, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, 1126, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932 }, { 69, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, 1128, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933 }, { 69, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, 1129, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934 }, { 69, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, 1130, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935 }, { 69, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, 1131, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936 }, { 69, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, 1132, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937 }, { 69, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, 1133, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938 }, { 69, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, 1134, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, 1135, -939, -939, 1136, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939 }, { 69, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, 1137, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940 }, { 69, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, 1138, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941 }, { 69, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, 1139, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942 }, { 69, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, 1140, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943 }, { 69, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, 1141, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944 }, { 69, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, 1142, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945 }, { 69, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, 1143, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946 }, { 69, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, 1144, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947 }, { 69, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, 1145, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948 }, { 69, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, 1146, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949 }, { 69, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, 1147, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950 }, { 69, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, 1148, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, 1149, -951, -951, 1150, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951 }, { 69, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, 1151, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952 }, { 69, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, 1153, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953 }, { 69, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, 1154, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, 1155, 1155, 1155, 1155, 1155, 1155, 1155, 1155, 1155, 1155, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954 }, { 69, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, 1156, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955 }, { 69, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, 1158, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956 }, { 69, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, 1159, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957 }, { 69, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, 1160, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958 }, { 69, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, 1161, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959 }, { 69, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, 1162, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, 1163, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960 }, { 69, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, 1164, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961 }, { 69, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, 1165, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962 }, { 69, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, 1166, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963 }, { 69, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, 1167, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964 }, { 69, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, 1168, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965 }, { 69, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, 1169, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966 }, { 69, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, 1170, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967 }, { 69, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, 1171, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968 }, { 69, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, 1172, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969 }, { 69, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, 1173, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970 }, { 69, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, 1174, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971 }, { 69, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, 1175, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972 }, { 69, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, 1176, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973 }, { 69, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, 1177, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974 }, { 69, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, 1178, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975 }, { 69, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, 1179, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976 }, { 69, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, 1180, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977 }, { 69, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, 1181, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978 }, { 69, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, 1182, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979 }, { 69, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, 1183, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980 }, { 69, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, 1184, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981 }, { 69, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, 1185, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982 }, { 69, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, 1186, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, -983, -983, -983, -983, -983, -983, -983, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983 }, { 69, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, 1188, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984 }, { 69, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, 1189, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985 }, { 69, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, 1190, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, -986, -986, -986, -986, -986, -986, -986, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986 }, { 69, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, 1192, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987 }, { 69, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, 1193, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988 }, { 69, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, 1194, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989 }, { 69, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, 1195, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, -990, -990, -990, -990, -990, -990, -990, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990 }, { 69, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, 1197, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991 }, { 69, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, 1198, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, -992, -992, -992, -992, -992, -992, -992, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992 }, { 69, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, 1200, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993 }, { 69, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, 1201, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994 }, { 69, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995 }, { 69, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996 }, { 69, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997 }, { 69, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998 }, { 69, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999 }, { 69,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000 }, { 69,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001, -1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001, -1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001, -1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001, -1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001, -1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001, -1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001, -1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001, -1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001, -1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001, -1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001, -1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001, -1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001 }, { 69,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002, -1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002, -1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002, -1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002, -1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002, -1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002, -1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002, -1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002, -1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002, -1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002, -1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002, -1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002, -1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002 }, { 69,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003, -1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003, -1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003, -1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003, -1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003, -1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003, -1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003, -1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003, -1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003, -1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003, -1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003, -1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003, -1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003 }, { 69,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004, -1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004, -1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004, -1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004, -1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004, -1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004, -1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004, -1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004, -1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004, -1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004, -1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004, -1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004, -1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004 }, { 69,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005, -1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005, -1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005, -1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005, -1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005, -1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005, -1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005, -1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005, -1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005, -1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005, -1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005, -1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005, -1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005 }, { 69,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006, -1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006, -1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006, -1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006, -1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006, -1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006, -1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006, -1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006, -1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006, -1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006, -1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006, -1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006, -1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006 }, { 69,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007, -1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007, -1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007, -1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007, -1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007, -1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007, -1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007, -1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007, -1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007, -1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007, -1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007, -1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007, -1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007 }, { 69,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008, -1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008, -1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008, -1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008, -1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008, -1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008, -1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008, -1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008, -1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008, -1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008, -1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008, -1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008, -1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008 }, { 69,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009, -1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009, -1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009, -1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009, -1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009, -1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009, -1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009, -1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009, -1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009, -1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009, -1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009, -1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009, -1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009 }, { 69,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010, -1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010, -1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010, -1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010, -1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010, -1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010, -1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010, -1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010, -1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010, -1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010, -1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010, -1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010, -1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010 }, { 69,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011, -1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011, -1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011, -1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011, -1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011, -1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011, -1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011, -1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011, -1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011, -1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011, -1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011, -1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011, -1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011 }, { 69,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012, -1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012, -1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012, -1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012, -1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012, -1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012, -1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012, -1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012, -1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012, -1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012, -1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012, -1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012, -1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012 }, { 69,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013, -1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013, -1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013, -1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013, -1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013, -1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013, -1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013, -1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013, -1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013, -1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013, -1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013, -1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013, -1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013 }, { 69,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014, -1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014, -1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014, -1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014, -1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014, -1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014, -1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014, -1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014, -1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014, -1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014, -1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014, -1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014, -1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014 }, { 69,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015, -1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015, -1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015, -1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015, -1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015, -1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015, -1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015, -1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015, -1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015, -1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015, -1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015, -1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015, -1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015 }, { 69,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016, -1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016, -1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016, -1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016, -1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016, -1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016, -1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016, -1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016, -1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016, -1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016, -1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016, -1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016, -1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016 }, { 69,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017, -1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017, -1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017, -1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017, -1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017, -1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017, -1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017, -1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017, -1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017, -1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017, -1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017, -1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017, -1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017 }, { 69,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018, -1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018, -1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018, -1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018, -1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018, -1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018, -1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018, -1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018, -1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018, -1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018, -1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018, -1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018, -1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018 }, { 69,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019, -1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019, -1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019, -1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019, -1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019, -1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019, -1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019, -1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019, -1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019, -1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019, -1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019, -1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019, -1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019 }, { 69,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020, -1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020, -1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020, -1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020, -1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020, -1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020, -1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020, -1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020, -1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020, -1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020, -1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020, -1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020, -1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020 }, { 69,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021, -1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021, -1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021, -1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021, -1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021, -1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021, -1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021, -1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021, -1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021, -1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021, -1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021, -1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021, -1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021 }, { 69,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022, -1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022, -1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022, -1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022, -1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022, -1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022, -1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022, -1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022, -1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022, -1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022, -1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022, -1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022, -1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022 }, { 69,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023, -1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023, -1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023, -1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023, -1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023, -1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023, -1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023, -1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023, -1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023, -1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023, -1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023, -1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023, -1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023 }, { 69,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024, -1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024, -1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024, -1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024, -1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024, -1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024, -1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024, -1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024, -1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024, -1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024, -1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024, -1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024, -1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024 }, { 69,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025, -1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025, -1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025, -1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025, -1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025, -1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025, -1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025, -1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025, -1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025, -1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025, -1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025, -1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025, -1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025 }, { 69,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026, -1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026, -1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026, -1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026, -1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026, -1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026, -1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026, -1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026, -1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026, -1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026, -1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026, -1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026, -1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026 }, { 69,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027, -1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027, -1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027, -1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027, -1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027, -1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027, -1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027, -1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027, -1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027, -1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027, -1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027, -1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027, -1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027 }, { 69,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028, -1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028, -1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028, -1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028, -1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028, -1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028, -1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028, -1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028, -1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028, -1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028, -1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028, -1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028, -1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028 }, { 69,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029, -1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029, -1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029, -1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029, -1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029, -1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029, -1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029, -1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029, -1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029, -1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029, -1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029, -1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029, -1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029 }, { 69,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030, -1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030, -1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030, -1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030, -1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030, -1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030, -1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030, -1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030, -1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030, -1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030, -1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030, -1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030, -1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030 }, { 69,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031, -1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031, -1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031, -1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031, -1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031, -1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031, -1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031, -1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031, -1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031, -1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031, -1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031, -1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031, -1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031 }, { 69,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032, -1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032, -1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032, -1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032, -1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032, -1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032, -1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032, -1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032, -1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032, -1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032, -1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032, -1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032, -1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032 }, { 69,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033, -1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033, -1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033, -1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033, -1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033, -1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033, -1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033, -1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033, -1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033, -1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033, -1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033, -1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033, -1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033 }, { 69,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034, -1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034, -1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034, -1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034, -1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034, -1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034, -1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034, -1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034, -1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034, -1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034, -1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034, -1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034, -1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034 }, { 69,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035, -1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035, -1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035, -1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035, -1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035, -1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035, -1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035, -1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035, -1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035, -1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035, -1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035, -1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035, -1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035 }, { 69,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036, -1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036, -1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036, -1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036, -1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036, -1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036, -1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036, -1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036, -1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036, -1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036, -1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036, -1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036, -1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036 }, { 69,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037, -1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037, -1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037, -1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037, -1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037, -1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037, -1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037, -1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037, -1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037, -1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037, -1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037, -1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037, -1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037 }, { 69,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038, -1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038, -1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038, -1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038, -1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038, -1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038, -1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038, -1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038, -1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038, -1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038, -1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038, -1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038, -1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038 }, { 69,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039, -1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039, -1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039, -1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039, -1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039, -1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039, -1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039, -1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039, -1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039, -1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039, -1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039, -1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039, -1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039 }, { 69,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040, -1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040, -1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040, -1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040, -1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040, -1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040, -1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040, -1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040, -1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040, -1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040, -1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040, -1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040, -1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040 }, { 69,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041, -1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041, -1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041, -1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041, -1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041, -1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041, -1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041, -1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041, -1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041, -1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041, -1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041, -1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041, -1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041 }, { 69,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042, -1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042, -1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042, -1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042, -1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042, -1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042, -1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042, -1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042, -1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042, -1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042, -1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042, -1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042, -1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042 }, { 69,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043, -1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043, -1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043, -1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043, -1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043, -1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043, -1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043, -1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043, -1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043, -1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043, -1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043, -1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043, -1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043 }, { 69,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044, -1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044, -1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044, -1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044, -1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044, -1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044, -1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044, -1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044, -1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044, -1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044, -1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044, -1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044, -1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044 }, { 69,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045, -1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045, -1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045, -1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045, -1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045, -1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045, -1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045, -1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045, -1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045, -1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045, -1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045, -1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045, -1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045 }, { 69,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046, -1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046, -1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046, -1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046, -1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046, -1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046, -1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046, -1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046, -1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046, -1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046, -1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046, -1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046, -1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046 }, { 69,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047, -1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047, -1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047, -1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047, -1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047, -1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047, -1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047, -1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047, -1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047, -1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047, -1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047, -1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047, -1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047 }, { 69,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048, -1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048, -1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048, -1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048, -1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048, -1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048, -1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048, -1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048, -1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048, -1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048, -1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048, -1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048, -1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048 }, { 69,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049, -1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049, -1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049, -1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049, -1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049, -1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049, -1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049, -1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049, -1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049, -1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049, -1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049, -1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049, -1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049 }, { 69,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050, -1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050, -1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050, -1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050, -1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050, -1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050, -1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050, -1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050, -1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050, -1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050, -1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050, -1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050, -1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050 }, { 69,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051, -1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051, -1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051, -1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051, -1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051, -1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051, -1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051, -1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051, -1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051, -1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051, -1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051, -1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051, -1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051 }, { 69,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052, -1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052, -1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052, -1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052, -1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052, -1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052, -1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052, -1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052, -1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052, -1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052, -1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052, -1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052, -1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052 }, { 69,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053, -1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053, -1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053, -1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053, -1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053, -1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053, -1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053, -1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053, -1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053, -1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053, -1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053, -1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053, -1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053 }, { 69,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054, -1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054, -1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054, -1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054, -1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054, -1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054, -1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054, -1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054, -1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054, -1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054, -1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054, -1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054, -1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054 }, { 69,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055, -1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055, -1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055, -1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055, -1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055, -1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055, -1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055, -1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055, -1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055, -1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055, -1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055, -1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055, -1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055 }, { 69,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056, -1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056, -1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056, -1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056, -1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056, -1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056, -1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056, -1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056, -1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056, -1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056, -1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056, -1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056, -1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056 }, { 69,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057, -1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057, -1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057, -1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057, -1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057, -1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057, -1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057, -1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057, -1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057, -1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057, -1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057, -1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057, -1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057 }, { 69,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058, -1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058, -1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058, -1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058, -1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058, -1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058, -1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058, -1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058, -1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058, -1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058, -1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058, -1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058, -1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058 }, { 69,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059, -1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059, -1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059, -1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059, -1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059, -1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059, -1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059, -1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059, -1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059, -1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059, -1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059, -1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059, -1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059 }, { 69,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060, -1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060, -1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060, -1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060, -1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060, -1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060, -1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060, -1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060, -1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060, -1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060, -1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060, -1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060, -1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060 }, { 69,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061, -1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061, -1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061, -1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061, -1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061, -1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061, -1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061, -1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061, -1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061, -1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061, -1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061, -1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061, -1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061 }, { 69,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062, -1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062, -1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062, -1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062, -1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062, -1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062, -1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062, -1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062, -1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062, -1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062, -1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062, -1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062, -1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062 }, { 69,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063, -1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063, -1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063, -1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063, -1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063, -1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063, -1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063, -1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063, -1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063, -1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063, -1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063, -1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063, -1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063 }, { 69,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064, -1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064, -1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064, -1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064, -1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064, -1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064, -1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064, -1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064, -1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064, -1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064, -1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064, -1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064, -1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064 }, { 69,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065, -1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065, -1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065, -1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065, -1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065, -1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065, -1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065, -1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065, -1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065, -1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065, -1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065, -1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065, -1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065 }, { 69,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066, -1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066, -1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066, -1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066, -1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066, -1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066, -1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066, -1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066, -1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066, -1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066, -1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066, -1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066, -1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066 }, { 69,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067, -1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067, -1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067, -1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067, -1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067, -1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067, -1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067, -1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067, -1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067, -1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067, -1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067, -1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067, -1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067 }, { 69,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068, -1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068, -1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068, -1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068, -1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068, -1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068, -1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068, -1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068, -1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068, -1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068, -1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068, -1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068, -1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068 }, { 69,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069, -1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069, -1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069, -1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069, -1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069, -1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069, -1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069, -1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069, -1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069, -1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069, -1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069, -1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069, -1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069 }, { 69,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070, -1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070, -1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070, -1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070, -1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070, -1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070, -1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070, -1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070, -1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070, -1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070, -1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070, -1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070, -1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070 }, { 69,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071, -1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071, -1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071, -1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071, -1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071, -1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071, -1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071, -1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071, -1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071, -1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071, -1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071, -1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071, -1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071 }, { 69,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072, -1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072, -1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072, -1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072, -1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072, -1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072, -1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072, -1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072, -1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072, -1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072, -1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072, -1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072, -1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072 }, { 69,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073, -1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073, -1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073, -1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073, -1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073, -1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073, -1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073, -1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073, -1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073, -1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073, -1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073, -1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073, -1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073 }, { 69,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074, -1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074, -1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074, -1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074, -1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074, -1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074, -1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074, -1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074, -1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074, -1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074, -1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074, -1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074, -1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074 }, { 69,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075, -1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075, -1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075, -1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075, -1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075, -1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075, -1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075, -1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075, -1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075, -1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075, -1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075, -1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075, -1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075 }, { 69,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076, -1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076, -1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076, -1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076, -1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076, -1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076, -1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076, -1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076, -1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076, -1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076, -1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076, -1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076, -1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076 }, { 69,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077, -1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077, -1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077, -1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077, -1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077, -1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077, -1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077, -1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077, -1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077, -1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077, -1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077, -1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077, -1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077 }, { 69,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078, -1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078, -1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078, -1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078, -1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078, -1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078, -1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078, -1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078, -1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078, -1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078, -1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078, -1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078, -1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078 }, { 69,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079, -1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079, -1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079, -1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079, -1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079, -1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079, -1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079, -1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079, -1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079, -1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079, -1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079, -1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079, -1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079 }, { 69,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080, -1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080, -1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080, -1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080, -1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080, -1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080, -1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080, -1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080, -1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080, -1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080, -1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080, -1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080, -1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080 }, { 69,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081, -1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081, -1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081, -1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081, -1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081, -1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081, -1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081, -1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081, -1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081, -1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081, -1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081, -1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081, -1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081 }, { 69,-1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082, -1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082, -1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082, -1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082, -1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082, -1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082, -1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082, -1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082, -1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082, -1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082, -1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082, -1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082, -1082,-1082,-1082,-1082,-1082,-1082,-1082,-1082 }, { 69,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083, -1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083, -1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083, -1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083, -1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083, -1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083, -1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083, -1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083, -1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083, -1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083, -1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083, -1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083, -1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083 }, { 69,-1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084, -1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084, -1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084, -1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084, -1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084, -1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084, -1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084, -1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084, -1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084, -1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084, -1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084, -1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084, -1084,-1084,-1084,-1084,-1084,-1084,-1084,-1084 }, { 69,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085, -1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085, -1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085, -1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085, -1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085, -1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085, -1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085, -1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085, -1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085, -1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085, -1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085, -1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085, -1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085 }, { 69,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086, -1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086, -1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086, -1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086, -1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086, -1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086, -1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086, -1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086, -1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086, -1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086, -1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086, -1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086, -1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086 }, { 69,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087, -1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087, -1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087, -1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087, -1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087, -1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087, -1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087, -1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087, -1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087, -1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087, -1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087, -1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087, -1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087 }, { 69,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088, -1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088, -1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088, -1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088, -1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088, -1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088, -1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088, -1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088, -1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088, -1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088, -1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088, -1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088, -1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088 }, { 69,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089, -1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089, -1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089, -1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089, -1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089, -1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089, -1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089, -1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089, -1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089, -1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089, -1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089, -1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089, -1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089 }, { 69,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090, -1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090, -1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090, -1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090, -1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090, -1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090, -1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090, -1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090, -1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090, -1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090, -1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090, -1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090, -1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090 }, { 69,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091, -1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091, -1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091, -1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091, -1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091, -1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091, -1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091, -1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091, -1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091, -1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091, -1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091, -1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091, -1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091 }, { 69,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092, -1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092, -1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092, -1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092, -1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092, -1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092, -1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092, -1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092, -1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092, -1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092, -1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092, -1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092, -1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092 }, { 69,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093, -1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093, -1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093, -1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093, -1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093, -1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093, -1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093, -1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093, -1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093, -1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093, -1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093, -1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093, -1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093 }, { 69,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094, -1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094, -1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094, -1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094, -1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094, -1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094, -1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094, -1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094, -1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094, -1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094, -1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094, -1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094, -1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094 }, { 69,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095, -1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095, -1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095, -1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095, -1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095, -1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095, -1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095, -1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095, -1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095, -1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095, -1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095, -1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095, -1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095 }, { 69,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096, -1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096, -1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096, -1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096, -1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096, -1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096, -1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096, -1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096, -1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096, -1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096, -1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096, -1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096, -1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096 }, { 69,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097, -1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097, -1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097, -1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097, -1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097, -1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097, -1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097, -1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097, -1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097, -1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097, -1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097, -1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097, -1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097 }, { 69,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098, -1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098, -1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098, -1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098, -1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098, -1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098, -1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098, -1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098, -1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098, -1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098, -1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098, -1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098, -1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098 }, { 69,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099, -1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099, -1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099, -1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099, -1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099, -1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099, -1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099, -1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099, -1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099, -1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099, -1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099, -1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099, -1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099 }, { 69,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100, -1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100, -1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100, -1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100, -1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100, -1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100, -1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100, -1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100, -1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100, -1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100, -1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100, -1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100, -1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100 }, { 69,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101, -1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101, -1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101, -1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101, -1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101, -1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101, -1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101, -1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101, -1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101, -1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101, -1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101, -1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101, -1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101 }, { 69,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102, -1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102, -1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102, -1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102, -1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102, -1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102, -1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102, -1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102, -1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102, -1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102, -1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102, -1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102, -1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102 }, { 69,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103, -1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103, -1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103, -1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103, -1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103, -1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103, -1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103, -1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103, -1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103, -1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103, -1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103, -1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103, -1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103 }, { 69,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104, -1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104, -1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104, -1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104, -1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104, -1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104, -1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104, -1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104, -1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104, -1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104, -1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104, -1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104, -1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104 }, { 69,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105, -1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105, -1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105, -1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105, -1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105, -1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105, -1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105, -1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105, -1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105, -1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105, -1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105, -1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105, -1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105 }, { 69,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106, -1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106, -1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106, -1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106, -1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106, -1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106, -1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106, -1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106, -1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106, -1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106, -1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106, -1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106, -1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106 }, { 69,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107, -1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107, -1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107, -1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107, -1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107, -1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107, -1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107, -1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107, -1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107, -1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107, -1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107, -1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107, -1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107 }, { 69,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108, -1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108, -1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108, -1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108, -1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108, -1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108, -1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108, -1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108, -1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108, -1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108, -1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108, -1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108, -1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108 }, { 69,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109, -1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109, -1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109, -1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109, -1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109, -1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109, -1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109, -1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109, -1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109, -1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109, -1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109, -1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109, -1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109 }, { 69,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110, -1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110, -1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110, -1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110, -1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110, -1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110, -1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110, -1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110, -1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110, -1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110, -1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110, -1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110, -1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110 }, { 69,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111, -1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111, -1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111, -1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111, -1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111, -1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111, -1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111, -1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111, -1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111, -1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111, -1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111, -1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111, -1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111 }, { 69,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112, -1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112, -1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112, -1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112, -1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112, -1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112, -1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112, -1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112, -1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112, -1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112, -1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112, -1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112, -1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112 }, { 69,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113, -1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113, -1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113, -1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113, -1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113, -1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113, -1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113, -1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113, -1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113, -1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113, -1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113, -1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113, -1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113 }, { 69,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114, -1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114, -1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114, -1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114, -1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114, -1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114, -1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114, -1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114, -1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114, -1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114, -1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114, -1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114, -1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114 }, { 69,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115, -1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115, -1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115, -1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115, -1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115, -1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115, -1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115, -1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115, -1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115, -1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115, -1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115, -1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115, -1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115 }, { 69,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116, -1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116, -1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116, -1116,-1116, 1202,-1116,-1116,-1116,-1116,-1116,-1116,-1116, -1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116, -1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116, -1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116, -1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116, -1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116, -1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116, -1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116, -1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116, -1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116 }, { 69,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117, -1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117, -1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117, -1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117, -1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117, -1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117, -1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117, -1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117, -1117,-1117,-1117, 1203,-1117,-1117,-1117,-1117,-1117,-1117, -1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117, -1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117, -1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117, -1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117 }, { 69,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118, -1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118, -1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118, -1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118, -1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118, -1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118, -1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118, -1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118, -1118,-1118,-1118, 1204,-1118,-1118,-1118,-1118,-1118,-1118, -1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118, -1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118, -1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118, -1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118 }, { 69,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119, -1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119, -1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119, -1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119, -1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119, -1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119, -1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119, -1119, 1205,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119, -1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119, -1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119, -1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119, -1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119, -1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119 }, { 69,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120, -1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120, -1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120, -1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120, -1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120, -1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120, -1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120, -1120, 1206,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120, -1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120, -1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120, -1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120, -1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120, -1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120 }, { 69,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121, -1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121, -1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121, -1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121, -1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121, -1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121, -1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121, 1207,-1121, -1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121, -1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121, -1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121, -1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121, -1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121, -1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121 }, { 69,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122, -1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122, -1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122, -1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122, -1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122, -1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122, -1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122, -1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122, -1122,-1122,-1122, 1208,-1122,-1122,-1122,-1122,-1122,-1122, -1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122, -1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122, -1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122, -1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122 }, { 69,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123, -1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123, -1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123, -1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123, -1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123, -1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123, -1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123, 1209,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123, -1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123, -1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123, -1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123, -1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123, -1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123 }, { 69,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124, -1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124, -1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124, -1124,-1124, 1210,-1124,-1124,-1124,-1124,-1124,-1124,-1124, -1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124, -1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124, -1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124, -1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124, -1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124, -1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124, -1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124, -1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124, -1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124 }, { 69,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125, -1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125, -1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125, -1125,-1125, 1211,-1125,-1125,-1125,-1125,-1125,-1125,-1125, -1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125, -1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125, -1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125, -1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125, -1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125, -1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125, -1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125, -1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125, -1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125 }, { 69,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126, -1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126, -1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126, -1126,-1126, 1212,-1126,-1126,-1126,-1126,-1126,-1126,-1126, -1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126, -1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126, -1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126, -1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126, -1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126, -1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126, -1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126, -1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126, -1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126 }, { 69,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127, -1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127, -1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127, -1127,-1127, 1213,-1127,-1127,-1127,-1127,-1127,-1127,-1127, -1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127, -1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127, -1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127, -1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127, -1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127, -1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127, -1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127, -1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127, -1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127 }, { 69,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128, -1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128, -1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128, -1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128, -1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128, -1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128, -1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128, -1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128, -1128,-1128,-1128, 1214,-1128,-1128,-1128,-1128,-1128,-1128, -1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128, -1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128, -1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128, -1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128 }, { 69,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129, -1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129, -1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129, -1129,-1129, 1215,-1129,-1129,-1129,-1129,-1129,-1129,-1129, -1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129, -1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129, -1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129, -1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129, -1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129, -1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129, -1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129, -1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129, -1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129 }, { 69,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130, -1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130, -1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130, -1130,-1130, 1216,-1130,-1130,-1130,-1130,-1130,-1130,-1130, -1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130, -1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130, -1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130, -1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130, -1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130, -1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130, -1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130, -1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130, -1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130 }, { 69,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131, -1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131, -1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131, -1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131, -1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131, -1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131, -1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131, -1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131, -1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131, -1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131, -1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131, -1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131, -1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131 }, { 69,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132, -1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132, -1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132, -1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132, -1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132, -1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132, -1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132, -1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132, -1132,-1132,-1132, 1217,-1132,-1132,-1132,-1132,-1132,-1132, -1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132, -1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132, -1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132, -1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132 }, { 69,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133, -1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133, -1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133, -1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133, -1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133, -1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133, -1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133, -1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133, -1133,-1133,-1133, 1218,-1133,-1133,-1133,-1133,-1133,-1133, -1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133, -1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133, -1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133, -1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133 }, { 69,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134, -1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134, -1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134, -1134,-1134, 1219,-1134,-1134,-1134,-1134,-1134,-1134,-1134, -1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134, -1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134, -1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134, -1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134, -1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134, -1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134, -1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134, -1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134, -1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134 }, { 69,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135, -1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135, -1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135, -1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135, -1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135, -1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135, -1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135, -1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135, -1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135, -1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135, -1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135, -1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135, -1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135 }, { 69,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136, -1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136, -1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136, -1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136, -1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136, -1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136, -1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136, -1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136, -1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136, -1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136, -1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136, -1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136, -1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136 }, { 69,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137, -1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137, -1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137, -1137,-1137, 1220,-1137,-1137,-1137,-1137,-1137,-1137,-1137, -1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137, -1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137, -1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137, -1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137, -1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137, -1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137, -1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137, -1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137, -1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137 }, { 69,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138, -1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138, -1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138, -1138,-1138, 1221,-1138,-1138,-1138,-1138,-1138,-1138,-1138, -1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138, -1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138, -1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138, -1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138, -1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138, -1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138, -1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138, -1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138, -1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138 }, { 69,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139, -1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139, -1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139, -1139,-1139, 1222,-1139,-1139,-1139,-1139,-1139,-1139,-1139, -1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139, -1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139, -1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139, -1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139, -1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139, -1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139, -1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139, -1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139, -1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139 }, { 69,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140, -1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140, -1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140, -1140,-1140, 1223,-1140,-1140,-1140,-1140,-1140,-1140,-1140, -1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140, -1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140, -1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140, -1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140, -1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140, -1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140, -1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140, -1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140, -1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140 }, { 69,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141, -1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141, -1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141, -1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141, -1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141, -1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141, -1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141, -1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141, -1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141, -1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141, -1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141, -1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141, -1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141 }, { 69,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142, -1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142, -1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142, -1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142, -1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142, -1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142, -1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142, -1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142, -1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142, -1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142, -1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142, -1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142, -1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142 }, { 69,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143, -1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143, -1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143, -1143,-1143, 1224,-1143,-1143,-1143,-1143,-1143,-1143,-1143, -1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143, -1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143, -1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143, -1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143, -1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143, -1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143, -1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143, -1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143, -1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143 }, { 69,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144, -1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144, -1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144, -1144,-1144, 1225,-1144,-1144,-1144,-1144,-1144,-1144,-1144, -1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144, -1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144, -1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144, -1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144, -1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144, -1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144, -1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144, -1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144, -1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144 }, { 69,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145, -1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145, -1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145, -1145,-1145, 1226,-1145,-1145,-1145,-1145,-1145,-1145,-1145, -1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145, -1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145, -1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145, -1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145, -1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145, -1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145, -1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145, -1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145, -1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145 }, { 69,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146, -1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146, -1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146, -1146,-1146, 1227,-1146,-1146,-1146,-1146,-1146,-1146,-1146, -1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146, -1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146, -1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146, -1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146, -1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146, -1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146, -1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146, -1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146, -1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146 }, { 69,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147, -1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147, -1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147, -1147,-1147, 1228,-1147,-1147,-1147,-1147,-1147,-1147,-1147, -1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147, -1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147, -1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147, 1229,-1147,-1147, 1230,-1147,-1147,-1147,-1147,-1147,-1147, -1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147, -1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147, -1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147, -1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147, -1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147 }, { 69,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148, -1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148, -1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148, -1148,-1148, 1231,-1148,-1148,-1148,-1148,-1148,-1148,-1148, -1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148, -1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148, -1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148, -1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148, -1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148, -1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148, -1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148, -1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148, -1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148 }, { 69,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149, -1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149, -1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149, -1149,-1149, 1232,-1149,-1149,-1149,-1149,-1149,-1149,-1149, -1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149, -1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149, -1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149, -1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149, -1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149, -1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149, -1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149, -1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149, -1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149 }, { 69,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150, -1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150, -1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150, -1150,-1150, 1233,-1150,-1150,-1150,-1150,-1150,-1150,-1150, -1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150, -1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150, -1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150, -1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150, -1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150, -1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150, -1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150, -1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150, -1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150 }, { 69,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151, -1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151, -1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151, -1151,-1151, 1234,-1151,-1151,-1151,-1151,-1151,-1151,-1151, -1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151, -1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151, -1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151, -1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151, -1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151, -1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151, -1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151, -1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151, -1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151 }, { 69,-1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152, -1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152, -1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152, -1152,-1152, 1235,-1152,-1152,-1152,-1152,-1152,-1152,-1152, -1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236,-1152,-1152, -1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152, -1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152, -1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152, -1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152, -1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152, -1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152, -1152,-1152,-1152,-1152,-1152,-1152,-1152,-1152 }, { 69,-1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153, -1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153, -1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153, -1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153, -1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153, -1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153, -1153,-1153,-1153,-1153,-1153,-1153, 1237,-1153,-1153,-1153, -1153,-1153, 1238,-1153,-1153,-1153, 1239,-1153,-1153,-1153, -1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153, 1240, 1241, 1242,-1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153, -1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153, -1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153, -1153,-1153,-1153,-1153,-1153,-1153,-1153,-1153 }, { 69,-1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154, -1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154, -1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154, -1154,-1154, 1243,-1154,-1154,-1154,-1154,-1154,-1154,-1154, -1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154, -1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154, -1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154, -1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154, -1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154, -1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154, -1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154, -1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154, -1154,-1154,-1154,-1154,-1154,-1154,-1154,-1154 }, { 69,-1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155, -1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155, -1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155, -1155,-1155, 1244,-1155,-1155,-1155,-1155,-1155,-1155,-1155, -1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245,-1155,-1155, -1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155, -1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155, -1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155, -1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155, -1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155, -1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155, -1155,-1155,-1155,-1155,-1155,-1155,-1155,-1155 }, { 69,-1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156, -1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156, -1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156, -1156,-1156, 1246,-1156,-1156,-1156,-1156,-1156,-1156,-1156, -1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156, -1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156, -1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156, -1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156, -1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156, -1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156, -1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156, -1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156, -1156,-1156,-1156,-1156,-1156,-1156,-1156,-1156 }, { 69,-1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157, -1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157, -1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157, -1157,-1157, 1247,-1157,-1157,-1157,-1157,-1157,-1157,-1157, -1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248,-1157,-1157, -1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157, -1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157, -1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157, -1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157, -1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157, -1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157, -1157,-1157,-1157,-1157,-1157,-1157,-1157,-1157 }, { 69,-1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158, -1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158, -1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158, -1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158, -1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158, -1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158, -1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158, -1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158, -1158,-1158,-1158,-1158, 1249,-1158,-1158,-1158,-1158,-1158, -1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158, -1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158, -1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158, -1158,-1158,-1158,-1158,-1158,-1158,-1158,-1158 }, { 69,-1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159, -1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159, -1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159, -1159,-1159, 1250,-1159,-1159,-1159,-1159,-1159,-1159,-1159, -1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159, -1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159, -1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159, -1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159, -1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159, -1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159, -1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159, -1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159, -1159,-1159,-1159,-1159,-1159,-1159,-1159,-1159 }, { 69,-1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160, -1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160, -1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160, -1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160, -1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160, -1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160, -1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160, -1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160, -1160,-1160,-1160, 1251,-1160,-1160,-1160,-1160,-1160,-1160, -1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160, -1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160, -1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160, -1160,-1160,-1160,-1160,-1160,-1160,-1160,-1160 }, { 69,-1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161, -1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161, -1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161, -1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161, -1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161, -1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161, -1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161, -1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161, -1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161, -1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161, -1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161, -1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161, -1161,-1161,-1161,-1161,-1161,-1161,-1161,-1161 }, { 69,-1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162, -1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162, -1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162, -1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162, -1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162, -1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162, -1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162, -1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162, -1162, 1252,-1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162, -1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162, -1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162, -1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162, -1162,-1162,-1162,-1162,-1162,-1162,-1162,-1162 }, { 69,-1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163, -1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163, -1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163, -1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163, -1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163, -1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163, -1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163, -1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163, -1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163, -1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163, -1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163, -1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163, -1163,-1163,-1163,-1163,-1163,-1163,-1163,-1163 }, { 69,-1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164, -1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164, -1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164, -1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164, -1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164, -1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164, -1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164, -1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164, -1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164, -1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164, -1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164, -1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164, -1164,-1164,-1164,-1164,-1164,-1164,-1164,-1164 }, { 69,-1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165, -1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165, -1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165, -1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165, -1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165, -1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165, -1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165, 1253,-1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165, -1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165, -1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165, -1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165, -1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165, -1165,-1165,-1165,-1165,-1165,-1165,-1165,-1165 }, { 69,-1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166, -1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166, -1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166, -1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166, -1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166, -1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166, -1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166, -1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166, -1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166, -1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166, -1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166, -1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166, -1166,-1166,-1166,-1166,-1166,-1166,-1166,-1166 }, { 69,-1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167, -1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167, -1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167, -1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167, -1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167, -1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167, -1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167, -1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167, -1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167, -1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167, -1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167, -1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167, -1167,-1167,-1167,-1167,-1167,-1167,-1167,-1167 }, { 69,-1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168, -1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168, -1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168, -1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168, -1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168, -1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168, -1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168, -1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168, -1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168, -1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168, -1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168, -1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168, -1168,-1168,-1168,-1168,-1168,-1168,-1168,-1168 }, { 69,-1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169, -1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169, -1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169, -1169,-1169, 1254,-1169,-1169,-1169,-1169,-1169,-1169,-1169, -1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169, -1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169, -1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169, -1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169, -1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169, -1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169, -1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169, -1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169, -1169,-1169,-1169,-1169,-1169,-1169,-1169,-1169 }, { 69,-1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170, -1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170, -1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170, -1170,-1170, 1255,-1170,-1170,-1170,-1170,-1170,-1170,-1170, -1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170, -1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170, -1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170, -1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170, -1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170, -1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170, -1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170, -1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170, -1170,-1170,-1170,-1170,-1170,-1170,-1170,-1170 }, { 69,-1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171, -1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171, -1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171, -1171,-1171, 1256,-1171,-1171,-1171,-1171,-1171,-1171,-1171, -1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171, -1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171, -1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171, -1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171, -1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171, -1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171, -1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171, -1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171, -1171,-1171,-1171,-1171,-1171,-1171,-1171,-1171 }, { 69,-1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172, -1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172, -1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172, -1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172, -1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172, -1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172, -1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172, -1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172, -1172,-1172,-1172, 1257,-1172,-1172,-1172,-1172,-1172,-1172, -1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172, -1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172, -1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172, -1172,-1172,-1172,-1172,-1172,-1172,-1172,-1172 }, { 69,-1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173, -1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173, -1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173, -1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173, -1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173, -1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173, -1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173, -1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173, -1173,-1173, 1258,-1173,-1173,-1173,-1173,-1173,-1173,-1173, -1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173, -1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173, -1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173, -1173,-1173,-1173,-1173,-1173,-1173,-1173,-1173 }, { 69,-1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174, -1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174, -1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174, -1174,-1174, 1259,-1174,-1174,-1174,-1174,-1174,-1174,-1174, -1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174, -1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174, -1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174, -1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174, -1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174, -1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174, -1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174, -1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174, -1174,-1174,-1174,-1174,-1174,-1174,-1174,-1174 }, { 69,-1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175, -1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175, -1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175, -1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175, -1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175, -1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175, -1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175, -1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175, -1175,-1175,-1175,-1175, 1260,-1175,-1175,-1175,-1175,-1175, -1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175, -1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175, -1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175, -1175,-1175,-1175,-1175,-1175,-1175,-1175,-1175 }, { 69,-1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176, -1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176, -1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176, -1176,-1176, 1261,-1176,-1176,-1176,-1176,-1176,-1176,-1176, -1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176, -1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176, -1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176, -1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176, -1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176, -1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176, -1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176, -1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176, -1176,-1176,-1176,-1176,-1176,-1176,-1176,-1176 }, { 69,-1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177, -1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177, -1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177, -1177,-1177, 1262,-1177,-1177,-1177,-1177,-1177,-1177,-1177, -1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177, -1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177, -1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177, -1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177, -1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177, -1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177, -1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177, -1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177, -1177,-1177,-1177,-1177,-1177,-1177,-1177,-1177 }, { 69,-1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178, -1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178, -1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178, -1178,-1178, 1263,-1178,-1178,-1178,-1178,-1178,-1178,-1178, -1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178, -1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178, -1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178, -1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178, -1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178, -1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178, -1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178, -1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178, -1178,-1178,-1178,-1178,-1178,-1178,-1178,-1178 }, { 69,-1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179, -1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179, -1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179, -1179,-1179, 1264,-1179,-1179,-1179,-1179,-1179,-1179,-1179, -1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179, -1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179, -1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179, -1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179, -1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179, -1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179, -1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179, -1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179, -1179,-1179,-1179,-1179,-1179,-1179,-1179,-1179 }, { 69,-1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180, -1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180, -1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180, -1180,-1180, 1265,-1180,-1180,-1180,-1180,-1180,-1180,-1180, -1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180, -1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180, -1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180, -1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180, -1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180, -1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180, -1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180, -1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180, -1180,-1180,-1180,-1180,-1180,-1180,-1180,-1180 }, { 69,-1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181, -1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181, -1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181, -1181,-1181, 1266,-1181,-1181,-1181,-1181,-1181,-1181,-1181, -1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181, -1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181, -1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181, -1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181, -1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181, -1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181, -1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181, -1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181, -1181,-1181,-1181,-1181,-1181,-1181,-1181,-1181 }, { 69,-1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182, -1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182, -1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182, -1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182, -1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182, -1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182, -1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182, -1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182, -1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182, -1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182, -1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182, -1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182, -1182,-1182,-1182,-1182,-1182,-1182,-1182,-1182 }, { 69,-1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183, -1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183, -1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183, -1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183, -1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183, -1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183, -1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183, -1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183, -1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183, -1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183, -1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183, -1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183, -1183,-1183,-1183,-1183,-1183,-1183,-1183,-1183 }, { 69,-1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184, -1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184, -1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184, -1184,-1184, 1267,-1184,-1184,-1184,-1184,-1184,-1184,-1184, -1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184, -1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184, -1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184, -1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184, -1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184, -1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184, -1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184, -1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184, -1184,-1184,-1184,-1184,-1184,-1184,-1184,-1184 }, { 69,-1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185, -1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185, -1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185, -1185,-1185, 1268,-1185,-1185,-1185,-1185,-1185,-1185,-1185, -1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185, -1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185, -1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185, -1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185, -1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185, -1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185, -1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185, -1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185, -1185,-1185,-1185,-1185,-1185,-1185,-1185,-1185 }, { 69,-1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186, -1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186, -1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186, -1186,-1186, 1269,-1186,-1186,-1186,-1186,-1186,-1186,-1186, -1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186, -1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186, -1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186, -1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186, -1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186, -1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186, -1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186, -1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186, -1186,-1186,-1186,-1186,-1186,-1186,-1186,-1186 }, { 69,-1187,-1187,-1187,-1187,-1187,-1187,-1187,-1187,-1187, -1187,-1187,-1187,-1187,-1187,-1187,-1187,-1187,-1187,-1187, -1187,-1187,-1187,-1187,-1187,-1187,-1187,-1187,-1187,-1187, -1187,-1187, 1270,-1187,-1187,-1187,-1187,-1187,-1187,-1187, -1187,-1187,-1187,-1187,-1187,-1187,-1187,-1187,-1187,-1187, -1187,-1187,-1187,-1187,-1187,-1187,-1187,-1187,-1187,-1187, -1187,-1187,-1187,-1187,-1187, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270,-1187,-1187,-1187,-1187,-1187,-1187,-1187,-1187,-1187, -1187,-1187,-1187,-1187,-1187,-1187,-1187,-1187,-1187,-1187, -1187,-1187,-1187,-1187,-1187,-1187,-1187,-1187,-1187,-1187, -1187,-1187,-1187,-1187,-1187,-1187,-1187,-1187 }, { 69,-1188,-1188,-1188,-1188,-1188,-1188,-1188,-1188,-1188, -1188,-1188,-1188,-1188,-1188,-1188,-1188,-1188,-1188,-1188, -1188,-1188,-1188,-1188,-1188,-1188,-1188,-1188,-1188,-1188, -1188,-1188, 1271,-1188,-1188,-1188,-1188,-1188,-1188,-1188, -1188,-1188,-1188,-1188,-1188,-1188,-1188,-1188,-1188,-1188, -1188,-1188,-1188,-1188,-1188,-1188,-1188,-1188,-1188,-1188, -1188,-1188,-1188,-1188,-1188, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271,-1188,-1188,-1188,-1188,-1188,-1188,-1188,-1188,-1188, -1188,-1188,-1188,-1188,-1188,-1188,-1188,-1188,-1188,-1188, -1188,-1188,-1188,-1188,-1188,-1188,-1188,-1188,-1188,-1188, -1188,-1188,-1188,-1188,-1188,-1188,-1188,-1188 }, { 69,-1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189, -1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189, -1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189, -1189,-1189, 1272,-1189,-1189,-1189,-1189,-1189,-1189,-1189, -1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189, -1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189, -1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189, -1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189, -1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189, -1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189, -1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189, -1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189, -1189,-1189,-1189,-1189,-1189,-1189,-1189,-1189 }, { 69,-1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190, -1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190, -1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190, -1190,-1190, 1273,-1190,-1190,-1190,-1190,-1190,-1190,-1190, -1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190, -1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190, -1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190, -1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190, -1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190, -1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190, -1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190, -1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190, -1190,-1190,-1190,-1190,-1190,-1190,-1190,-1190 }, { 69,-1191,-1191,-1191,-1191,-1191,-1191,-1191,-1191,-1191, -1191,-1191,-1191,-1191,-1191,-1191,-1191,-1191,-1191,-1191, -1191,-1191,-1191,-1191,-1191,-1191,-1191,-1191,-1191,-1191, -1191,-1191, 1274,-1191,-1191,-1191,-1191,-1191,-1191,-1191, -1191,-1191,-1191,-1191,-1191,-1191,-1191,-1191,-1191,-1191, -1191,-1191,-1191,-1191,-1191,-1191,-1191,-1191,-1191,-1191, -1191,-1191,-1191,-1191,-1191, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,-1191,-1191,-1191,-1191,-1191,-1191,-1191,-1191,-1191, -1191,-1191,-1191,-1191,-1191,-1191,-1191,-1191,-1191,-1191, -1191,-1191,-1191,-1191,-1191,-1191,-1191,-1191,-1191,-1191, -1191,-1191,-1191,-1191,-1191,-1191,-1191,-1191 }, { 69,-1192,-1192,-1192,-1192,-1192,-1192,-1192,-1192,-1192, -1192,-1192,-1192,-1192,-1192,-1192,-1192,-1192,-1192,-1192, -1192,-1192,-1192,-1192,-1192,-1192,-1192,-1192,-1192,-1192, -1192,-1192, 1275,-1192,-1192,-1192,-1192,-1192,-1192,-1192, -1192,-1192,-1192,-1192,-1192,-1192,-1192,-1192,-1192,-1192, -1192,-1192,-1192,-1192,-1192,-1192,-1192,-1192,-1192,-1192, -1192,-1192,-1192,-1192,-1192, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275,-1192,-1192,-1192,-1192,-1192,-1192,-1192,-1192,-1192, -1192,-1192,-1192,-1192,-1192,-1192,-1192,-1192,-1192,-1192, -1192,-1192,-1192,-1192,-1192,-1192,-1192,-1192,-1192,-1192, -1192,-1192,-1192,-1192,-1192,-1192,-1192,-1192 }, { 69,-1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193, -1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193, -1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193, -1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193, -1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193, -1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193, -1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193, -1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193, -1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193, -1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193, -1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193, -1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193, -1193,-1193,-1193,-1193,-1193,-1193,-1193,-1193 }, { 69,-1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194, -1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194, -1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194, -1194,-1194, 1276,-1194,-1194,-1194,-1194,-1194,-1194,-1194, -1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194, -1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194, -1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194, -1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194, -1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194, -1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194, -1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194, -1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194, -1194,-1194,-1194,-1194,-1194,-1194,-1194,-1194 }, { 69,-1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195, -1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195, -1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195, -1195,-1195, 1277,-1195,-1195,-1195,-1195,-1195,-1195,-1195, -1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195, -1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195, -1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195, -1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195, -1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195, -1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195, -1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195, -1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195, -1195,-1195,-1195,-1195,-1195,-1195,-1195,-1195 }, { 69,-1196,-1196,-1196,-1196,-1196,-1196,-1196,-1196,-1196, -1196,-1196,-1196,-1196,-1196,-1196,-1196,-1196,-1196,-1196, -1196,-1196,-1196,-1196,-1196,-1196,-1196,-1196,-1196,-1196, -1196,-1196, 1278,-1196,-1196,-1196,-1196,-1196,-1196,-1196, -1196,-1196,-1196,-1196,-1196,-1196,-1196,-1196,-1196,-1196, -1196,-1196,-1196,-1196,-1196,-1196,-1196,-1196,-1196,-1196, -1196,-1196,-1196,-1196,-1196, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278,-1196,-1196,-1196,-1196,-1196,-1196,-1196,-1196,-1196, -1196,-1196,-1196,-1196,-1196,-1196,-1196,-1196,-1196,-1196, -1196,-1196,-1196,-1196,-1196,-1196,-1196,-1196,-1196,-1196, -1196,-1196,-1196,-1196,-1196,-1196,-1196,-1196 }, { 69,-1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197, -1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197, -1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197, -1197,-1197, 1279,-1197,-1197,-1197,-1197,-1197,-1197,-1197, -1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197, -1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197, -1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197, -1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197, -1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197, -1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197, -1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197, -1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197, -1197,-1197,-1197,-1197,-1197,-1197,-1197,-1197 }, { 69,-1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198, -1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198, -1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198, -1198,-1198, 1280,-1198,-1198,-1198,-1198,-1198,-1198,-1198, -1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198, -1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198, -1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198, -1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198, -1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198, -1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198, -1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198, -1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198, -1198,-1198,-1198,-1198,-1198,-1198,-1198,-1198 }, { 69,-1199,-1199,-1199,-1199,-1199,-1199,-1199,-1199,-1199, -1199,-1199,-1199,-1199,-1199,-1199,-1199,-1199,-1199,-1199, -1199,-1199,-1199,-1199,-1199,-1199,-1199,-1199,-1199,-1199, -1199,-1199, 1281,-1199,-1199,-1199,-1199,-1199,-1199,-1199, -1199,-1199,-1199,-1199,-1199,-1199,-1199,-1199,-1199,-1199, -1199,-1199,-1199,-1199,-1199,-1199,-1199,-1199,-1199,-1199, -1199,-1199,-1199,-1199,-1199, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281,-1199,-1199,-1199,-1199,-1199,-1199,-1199,-1199,-1199, -1199,-1199,-1199,-1199,-1199,-1199,-1199,-1199,-1199,-1199, -1199,-1199,-1199,-1199,-1199,-1199,-1199,-1199,-1199,-1199, -1199,-1199,-1199,-1199,-1199,-1199,-1199,-1199 }, { 69,-1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200, -1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200, -1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200, -1200,-1200, 1282,-1200,-1200,-1200,-1200,-1200,-1200,-1200, -1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200, -1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200, -1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200, -1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200, -1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200, -1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200, -1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200, -1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200, -1200,-1200,-1200,-1200,-1200,-1200,-1200,-1200 }, { 69,-1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201, -1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201, -1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201, -1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201, -1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201, -1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201, -1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201, -1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201, -1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201, -1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201, -1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201, -1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201, -1201,-1201,-1201,-1201,-1201,-1201,-1201,-1201 }, { 69,-1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202, -1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202, -1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202, -1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202, -1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202, -1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202, -1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202, -1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202, -1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202, -1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202, -1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202, -1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202, -1202,-1202,-1202,-1202,-1202,-1202,-1202,-1202 }, { 69,-1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203, -1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203, -1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203, -1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203, -1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203, -1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203, -1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203, -1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203, -1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203, -1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203, -1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203, -1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203, -1203,-1203,-1203,-1203,-1203,-1203,-1203,-1203 }, { 69,-1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204, -1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204, -1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204, -1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204, -1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204, -1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204, -1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204, -1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204, -1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204, -1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204, -1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204, -1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204, -1204,-1204,-1204,-1204,-1204,-1204,-1204,-1204 }, { 69,-1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205, -1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205, -1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205, -1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205, -1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205, -1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205, -1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205, -1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205, -1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205, -1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205, -1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205, -1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205, -1205,-1205,-1205,-1205,-1205,-1205,-1205,-1205 }, { 69,-1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206, -1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206, -1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206, -1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206, -1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206, -1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206, -1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206, -1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206, -1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206, -1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206, -1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206, -1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206, -1206,-1206,-1206,-1206,-1206,-1206,-1206,-1206 }, { 69,-1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207, -1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207, -1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207, -1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207, -1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207, -1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207, -1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207, -1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207, -1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207, -1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207, -1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207, -1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207, -1207,-1207,-1207,-1207,-1207,-1207,-1207,-1207 }, { 69,-1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208, -1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208, -1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208, -1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208, -1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208, -1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208, -1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208, -1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208, -1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208, -1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208, -1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208, -1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208, -1208,-1208,-1208,-1208,-1208,-1208,-1208,-1208 }, { 69,-1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209, -1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209, -1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209, -1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209, -1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209, -1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209, -1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209, -1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209, -1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209, -1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209, -1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209, -1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209, -1209,-1209,-1209,-1209,-1209,-1209,-1209,-1209 }, { 69,-1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210, -1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210, -1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210, -1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210, -1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210, -1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210, -1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210, -1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210, -1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210, -1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210, -1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210, -1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210, -1210,-1210,-1210,-1210,-1210,-1210,-1210,-1210 }, { 69,-1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211, -1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211, -1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211, -1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211, -1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211, -1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211, -1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211, -1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211, -1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211, -1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211, -1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211, -1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211, -1211,-1211,-1211,-1211,-1211,-1211,-1211,-1211 }, { 69,-1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212, -1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212, -1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212, -1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212, -1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212, -1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212, -1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212, -1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212, -1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212, -1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212, -1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212, -1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212, -1212,-1212,-1212,-1212,-1212,-1212,-1212,-1212 }, { 69,-1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213, -1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213, -1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213, -1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213, -1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213, -1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213, -1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213, -1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213, -1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213, -1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213, -1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213, -1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213, -1213,-1213,-1213,-1213,-1213,-1213,-1213,-1213 }, { 69,-1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214, -1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214, -1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214, -1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214, -1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214, -1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214, -1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214, -1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214, -1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214, -1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214, -1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214, -1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214, -1214,-1214,-1214,-1214,-1214,-1214,-1214,-1214 }, { 69,-1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215, -1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215, -1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215, -1215,-1215, 1283,-1215,-1215,-1215,-1215,-1215,-1215,-1215, -1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215, -1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215, -1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215, -1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215, -1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215, -1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215, -1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215, -1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215, -1215,-1215,-1215,-1215,-1215,-1215,-1215,-1215 }, { 69,-1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216, -1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216, -1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216, -1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216, -1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216, -1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216, -1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216, -1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216, -1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216, -1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216, -1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216, -1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216, -1216,-1216,-1216,-1216,-1216,-1216,-1216,-1216 }, { 69,-1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217, -1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217, -1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217, -1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217, -1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217, -1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217, -1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217, -1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217, -1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217, -1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217, -1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217, -1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217, -1217,-1217,-1217,-1217,-1217,-1217,-1217,-1217 }, { 69,-1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218, -1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218, -1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218, -1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218, -1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218, -1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218, -1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218, -1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218, -1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218, -1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218, -1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218, -1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218, -1218,-1218,-1218,-1218,-1218,-1218,-1218,-1218 }, { 69,-1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219, -1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219, -1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219, -1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219, -1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219, -1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219, -1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219, -1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219, -1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219, -1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219, -1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219, -1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219, -1219,-1219,-1219,-1219,-1219,-1219,-1219,-1219 }, { 69,-1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220, -1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220, -1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220, -1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220, -1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220, -1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220, -1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220, -1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220, -1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220, -1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220, -1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220, -1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220, -1220,-1220,-1220,-1220,-1220,-1220,-1220,-1220 }, { 69,-1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221, -1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221, -1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221, -1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221, -1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221, -1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221, -1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221, -1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221, -1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221, -1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221, -1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221, -1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221, -1221,-1221,-1221,-1221,-1221,-1221,-1221,-1221 }, { 69,-1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222, -1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222, -1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222, -1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222, -1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222, -1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222, -1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222, -1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222, -1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222, -1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222, -1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222, -1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222, -1222,-1222,-1222,-1222,-1222,-1222,-1222,-1222 }, { 69,-1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223, -1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223, -1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223, -1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223, -1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223, -1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223, -1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223, -1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223, -1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223, -1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223, -1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223, -1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223, -1223,-1223,-1223,-1223,-1223,-1223,-1223,-1223 }, { 69,-1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224, -1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224, -1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224, -1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224, -1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224, -1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224, -1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224, -1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224, -1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224, -1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224, -1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224, -1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224, -1224,-1224,-1224,-1224,-1224,-1224,-1224,-1224 }, { 69,-1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225, -1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225, -1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225, -1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225, -1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225, -1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225, -1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225, -1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225, -1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225, -1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225, -1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225, -1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225, -1225,-1225,-1225,-1225,-1225,-1225,-1225,-1225 }, { 69,-1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226, -1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226, -1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226, -1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226, -1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226, -1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226, -1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226, -1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226, -1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226, -1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226, -1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226, -1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226, -1226,-1226,-1226,-1226,-1226,-1226,-1226,-1226 }, { 69,-1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227, -1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227, -1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227, -1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227, -1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227, -1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227, -1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227, -1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227, -1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227, -1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227, -1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227, -1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227, -1227,-1227,-1227,-1227,-1227,-1227,-1227,-1227 }, { 69,-1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228, -1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228, -1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228, -1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228, -1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228, -1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228, -1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228, -1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228, -1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228, -1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228, -1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228, -1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228, -1228,-1228,-1228,-1228,-1228,-1228,-1228,-1228 }, { 69,-1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229, -1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229, -1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229, -1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229, -1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229, -1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229, -1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229, -1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229, -1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229, -1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229, -1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229, -1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229, -1229,-1229,-1229,-1229,-1229,-1229,-1229,-1229 }, { 69,-1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230, -1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230, -1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230, -1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230, -1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230, -1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230, -1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230, -1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230, -1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230, -1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230, -1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230, -1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230, -1230,-1230,-1230,-1230,-1230,-1230,-1230,-1230 }, { 69,-1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231, -1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231, -1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231, -1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231, -1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231, -1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231, -1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231, -1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231, -1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231, -1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231, -1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231, -1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231, -1231,-1231,-1231,-1231,-1231,-1231,-1231,-1231 }, { 69,-1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232, -1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232, -1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232, -1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232, -1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232, -1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232, -1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232, -1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232, -1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232, -1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232, -1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232, -1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232, -1232,-1232,-1232,-1232,-1232,-1232,-1232,-1232 }, { 69,-1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233, -1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233, -1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233, -1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233, -1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233, -1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233, -1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233, -1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233, -1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233, -1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233, -1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233, -1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233, -1233,-1233,-1233,-1233,-1233,-1233,-1233,-1233 }, { 69,-1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234, -1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234, -1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234, -1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234, -1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234, -1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234, -1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234, -1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234, -1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234, -1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234, -1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234, -1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234, -1234,-1234,-1234,-1234,-1234,-1234,-1234,-1234 }, { 69,-1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235, -1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235, -1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235, -1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235, -1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235, -1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235, -1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235, -1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235, -1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235, -1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235, -1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235, -1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235, -1235,-1235,-1235,-1235,-1235,-1235,-1235,-1235 }, { 69,-1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236, -1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236, -1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236, -1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236, -1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236, -1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236, -1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236, -1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236, -1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236, -1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236, -1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236, -1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236, -1236,-1236,-1236,-1236,-1236,-1236,-1236,-1236 }, { 69,-1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237, -1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237, -1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237, -1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237, -1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237, -1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237, -1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237, -1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237, -1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237, -1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237, -1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237, -1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237, -1237,-1237,-1237,-1237,-1237,-1237,-1237,-1237 }, { 69,-1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238, -1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238, -1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238, -1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238, -1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238, -1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238, -1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238, -1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238, -1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238, -1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238, -1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238, -1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238, -1238,-1238,-1238,-1238,-1238,-1238,-1238,-1238 }, { 69,-1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239, -1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239, -1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239, -1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239, -1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239, -1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239, -1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239, -1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239, -1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239, -1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239, -1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239, -1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239, -1239,-1239,-1239,-1239,-1239,-1239,-1239,-1239 }, { 69,-1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240, -1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240, -1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240, -1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240, -1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240, -1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240, -1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240, -1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240, -1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240, -1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240, -1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240, -1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240, -1240,-1240,-1240,-1240,-1240,-1240,-1240,-1240 }, { 69,-1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241, -1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241, -1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241, -1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241, -1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241, -1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241, -1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241, -1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241, -1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241, -1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241, -1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241, -1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241, -1241,-1241,-1241,-1241,-1241,-1241,-1241,-1241 }, { 69,-1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242, -1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242, -1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242, -1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242, -1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242, -1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242, -1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242, -1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242, -1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242, -1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242, -1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242, -1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242, -1242,-1242,-1242,-1242,-1242,-1242,-1242,-1242 }, { 69,-1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243, -1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243, -1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243, -1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243, -1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243, -1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243, -1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243, -1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243, -1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243, -1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243, -1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243, -1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243, -1243,-1243,-1243,-1243,-1243,-1243,-1243,-1243 }, { 69,-1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244, -1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244, -1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244, -1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244, -1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244, -1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244, -1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244, -1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244, -1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244, -1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244, -1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244, -1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244, -1244,-1244,-1244,-1244,-1244,-1244,-1244,-1244 }, { 69,-1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245, -1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245, -1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245, -1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245, -1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245, -1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245, -1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245, -1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245, -1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245, -1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245, -1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245, -1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245, -1245,-1245,-1245,-1245,-1245,-1245,-1245,-1245 }, { 69,-1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246, -1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246, -1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246, -1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246, -1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246, -1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246, -1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246, -1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246, -1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246, -1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246, -1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246, -1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246, -1246,-1246,-1246,-1246,-1246,-1246,-1246,-1246 }, { 69,-1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247, -1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247, -1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247, -1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247, -1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247, -1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247, -1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247, -1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247, -1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247, -1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247, -1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247, -1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247, -1247,-1247,-1247,-1247,-1247,-1247,-1247,-1247 }, { 69,-1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248, -1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248, -1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248, -1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248, -1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248, -1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248, -1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248, -1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248, -1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248, -1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248, -1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248, -1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248, -1248,-1248,-1248,-1248,-1248,-1248,-1248,-1248 }, { 69,-1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249, -1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249, -1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249, -1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249, -1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249, -1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249, -1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249, -1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249, -1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249, -1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249, -1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249, -1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249, -1249,-1249,-1249,-1249,-1249,-1249,-1249,-1249 }, { 69,-1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250, -1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250, -1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250, -1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250, -1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250, -1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250, -1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250, -1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250, -1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250, -1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250, -1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250, -1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250, -1250,-1250,-1250,-1250,-1250,-1250,-1250,-1250 }, { 69,-1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251, -1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251, -1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251, -1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251, -1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251, -1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251, -1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251, -1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251, -1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251, -1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251, -1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251, -1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251, -1251,-1251,-1251,-1251,-1251,-1251,-1251,-1251 }, { 69,-1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252, -1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252, -1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252, -1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252, -1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252, -1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252, -1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252, -1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252, -1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252, -1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252, -1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252, -1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252, -1252,-1252,-1252,-1252,-1252,-1252,-1252,-1252 }, { 69,-1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253, -1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253, -1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253, -1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253, -1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253, -1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253, -1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253, -1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253, -1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253, -1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253, -1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253, -1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253, -1253,-1253,-1253,-1253,-1253,-1253,-1253,-1253 }, { 69,-1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254, -1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254, -1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254, -1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254, -1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254, -1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254, -1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254, -1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254, -1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254, -1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254, -1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254, -1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254, -1254,-1254,-1254,-1254,-1254,-1254,-1254,-1254 }, { 69,-1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255, -1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255, -1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255, -1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255, -1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255, -1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255, -1255, 1284,-1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255, -1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255, -1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255, -1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255, -1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255, -1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255, -1255,-1255,-1255,-1255,-1255,-1255,-1255,-1255 }, { 69,-1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256, -1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256, -1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256, -1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256, -1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256, -1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256, -1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256, -1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256, -1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256, -1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256, -1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256, -1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256, -1256,-1256,-1256,-1256,-1256,-1256,-1256,-1256 }, { 69,-1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257, -1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257, -1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257, -1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257, -1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257, -1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257, -1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257, -1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257, -1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257, -1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257, -1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257, -1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257, -1257,-1257,-1257,-1257,-1257,-1257,-1257,-1257 }, { 69,-1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258, -1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258, -1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258, -1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258, -1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258, -1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258, -1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258, -1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258, -1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258, -1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258, -1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258, -1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258, -1258,-1258,-1258,-1258,-1258,-1258,-1258,-1258 }, { 69,-1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259, -1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259, -1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259, -1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259, -1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259, -1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259, -1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259, -1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259, -1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259, -1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259, -1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259, -1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259, -1259,-1259,-1259,-1259,-1259,-1259,-1259,-1259 }, { 69,-1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260, -1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260, -1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260, -1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260, -1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260, -1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260, -1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260, -1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260, -1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260, -1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260, -1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260, -1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260, -1260,-1260,-1260,-1260,-1260,-1260,-1260,-1260 }, { 69,-1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261, -1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261, -1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261, -1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261, -1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261, -1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261, -1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261, -1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261, -1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261, -1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261, -1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261, -1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261, -1261,-1261,-1261,-1261,-1261,-1261,-1261,-1261 }, { 69,-1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262, -1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262, -1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262, -1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262, -1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262, -1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262, -1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262, -1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262, -1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262, -1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262, -1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262, -1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262, -1262,-1262,-1262,-1262,-1262,-1262,-1262,-1262 }, { 69,-1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263, -1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263, -1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263, -1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263, -1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263, -1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263, -1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263, -1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263, -1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263, -1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263, -1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263, -1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263, -1263,-1263,-1263,-1263,-1263,-1263,-1263,-1263 }, { 69,-1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264, -1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264, -1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264, -1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264, -1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264, -1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264, -1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264, -1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264, -1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264, -1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264, -1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264, -1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264, -1264,-1264,-1264,-1264,-1264,-1264,-1264,-1264 }, { 69,-1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265, -1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265, -1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265, -1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265, -1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265, -1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265, -1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265, -1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265, -1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265, -1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265, -1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265, -1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265, -1265,-1265,-1265,-1265,-1265,-1265,-1265,-1265 }, { 69,-1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266, -1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266, -1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266, -1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266, -1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266, -1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266, -1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266, -1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266, -1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266, -1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266, -1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266, -1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266, -1266,-1266,-1266,-1266,-1266,-1266,-1266,-1266 }, { 69,-1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267, -1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267, -1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267, -1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267, -1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267, -1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267, -1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267, -1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267, -1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267, -1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267, -1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267, -1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267, -1267,-1267,-1267,-1267,-1267,-1267,-1267,-1267 }, { 69,-1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268, -1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268, -1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268, -1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268, -1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268, -1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268, -1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268, -1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268, -1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268, -1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268, -1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268, -1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268, -1268,-1268,-1268,-1268,-1268,-1268,-1268,-1268 }, { 69,-1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269, -1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269, -1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269, -1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269, -1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269, -1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269, -1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269, -1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269, -1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269, -1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269, -1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269, -1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269, -1269,-1269,-1269,-1269,-1269,-1269,-1269,-1269 }, { 69,-1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270, -1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270, -1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270, -1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270, -1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270, -1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270, -1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270, -1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270, -1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270, -1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270, -1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270, -1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270, -1270,-1270,-1270,-1270,-1270,-1270,-1270,-1270 }, { 69,-1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271, -1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271, -1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271, -1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271, -1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271, -1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271, -1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271, -1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271, -1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271, -1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271, -1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271, -1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271, -1271,-1271,-1271,-1271,-1271,-1271,-1271,-1271 }, { 69,-1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272, -1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272, -1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272, -1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272, -1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272, -1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272, -1272, 1285,-1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272, -1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272, -1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272, -1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272, -1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272, -1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272, -1272,-1272,-1272,-1272,-1272,-1272,-1272,-1272 }, { 69,-1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273, -1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273, -1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273, -1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273, -1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273, -1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273, -1273, 1286,-1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273, -1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273, -1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273, -1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273, -1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273, -1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273, -1273,-1273,-1273,-1273,-1273,-1273,-1273,-1273 }, { 69,-1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274, -1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274, -1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274, -1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274, -1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274, -1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274, -1274, 1287,-1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274, -1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274, -1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274, -1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274, -1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274, -1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274, -1274,-1274,-1274,-1274,-1274,-1274,-1274,-1274 }, { 69,-1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275, -1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275, -1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275, -1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275, -1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275, -1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275, -1275, 1288,-1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275, -1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275, -1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275, -1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275, -1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275, -1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275, -1275,-1275,-1275,-1275,-1275,-1275,-1275,-1275 }, { 69,-1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276, -1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276, -1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276, -1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276, -1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276, -1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276, -1276, 1289,-1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276, -1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276, -1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276, -1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276, -1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276, -1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276, -1276,-1276,-1276,-1276,-1276,-1276,-1276,-1276 }, { 69,-1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277, -1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277, -1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277, -1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277, -1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277, -1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277, -1277, 1290,-1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277, -1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277, -1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277, -1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277, -1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277, -1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277, -1277,-1277,-1277,-1277,-1277,-1277,-1277,-1277 }, { 69,-1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278, -1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278, -1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278, -1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278, -1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278, -1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278, -1278, 1291,-1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278, -1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278, -1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278, -1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278, -1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278, -1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278, -1278,-1278,-1278,-1278,-1278,-1278,-1278,-1278 }, { 69,-1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279, -1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279, -1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279, -1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279, -1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279, -1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279, -1279, 1292,-1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279, -1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279, -1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279, -1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279, -1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279, -1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279, -1279,-1279,-1279,-1279,-1279,-1279,-1279,-1279 }, { 69,-1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280, -1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280, -1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280, -1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280, -1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280, -1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280, -1280, 1293,-1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280, -1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280, -1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280, -1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280, -1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280, -1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280, -1280,-1280,-1280,-1280,-1280,-1280,-1280,-1280 }, { 69,-1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281, -1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281, -1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281, -1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281, -1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281, -1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281, -1281, 1294,-1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281, -1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281, -1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281, -1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281, -1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281, -1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281, -1281,-1281,-1281,-1281,-1281,-1281,-1281,-1281 }, { 69,-1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282, -1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282, -1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282, -1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282, -1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282, -1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282, -1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282, -1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282, -1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282, -1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282, -1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282, -1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282, -1282,-1282,-1282,-1282,-1282,-1282,-1282,-1282 }, { 69,-1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283, -1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283, -1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283, -1283,-1283, 1295,-1283,-1283,-1283,-1283,-1283,-1283,-1283, -1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283, -1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283, -1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283, -1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283, -1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283, -1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283, -1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283, -1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283, -1283,-1283,-1283,-1283,-1283,-1283,-1283,-1283 }, { 69,-1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284, -1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284, -1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284, -1284,-1284, 1296,-1284,-1284,-1284,-1284,-1284,-1284,-1284, -1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284, -1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284, -1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284, -1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284, -1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284, -1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284, -1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284, -1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284, -1284,-1284,-1284,-1284,-1284,-1284,-1284,-1284 }, { 69,-1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285, -1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285, -1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285, -1285,-1285, 1297,-1285,-1285,-1285,-1285,-1285,-1285,-1285, -1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285, -1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285, -1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285, -1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285, -1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285, -1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285, -1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285, -1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285, -1285,-1285,-1285,-1285,-1285,-1285,-1285,-1285 }, { 69,-1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286, -1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286, -1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286, -1286,-1286, 1298,-1286,-1286,-1286,-1286,-1286,-1286,-1286, -1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286, -1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286, -1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286, -1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286, -1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286, -1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286, -1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286, -1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286, -1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286 }, { 69,-1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287, -1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287, -1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287, -1287,-1287, 1299,-1287,-1287,-1287,-1287,-1287,-1287,-1287, -1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287, -1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287, -1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287, -1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287, -1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287, -1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287, -1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287, -1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287, -1287,-1287,-1287,-1287,-1287,-1287,-1287,-1287 }, { 69,-1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288, -1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288, -1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288, -1288,-1288, 1300,-1288,-1288,-1288,-1288,-1288,-1288,-1288, -1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288, -1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288, -1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288, -1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288, -1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288, -1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288, -1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288, -1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288, -1288,-1288,-1288,-1288,-1288,-1288,-1288,-1288 }, { 69,-1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289, -1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289, -1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289, -1289,-1289, 1301,-1289,-1289,-1289,-1289,-1289,-1289,-1289, -1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289, -1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289, -1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289, -1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289, -1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289, -1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289, -1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289, -1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289, -1289,-1289,-1289,-1289,-1289,-1289,-1289,-1289 }, { 69,-1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290, -1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290, -1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290, -1290,-1290, 1302,-1290,-1290,-1290,-1290,-1290,-1290,-1290, -1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290, -1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290, -1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290, -1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290, -1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290, -1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290, -1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290, -1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290, -1290,-1290,-1290,-1290,-1290,-1290,-1290,-1290 }, { 69,-1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291, -1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291, -1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291, -1291,-1291, 1303,-1291,-1291,-1291,-1291,-1291,-1291,-1291, -1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291, -1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291, -1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291, -1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291, -1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291, -1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291, -1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291, -1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291, -1291,-1291,-1291,-1291,-1291,-1291,-1291,-1291 }, { 69,-1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292, -1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292, -1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292, -1292,-1292, 1304,-1292,-1292,-1292,-1292,-1292,-1292,-1292, -1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292, -1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292, -1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292, -1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292, -1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292, -1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292, -1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292, -1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292, -1292,-1292,-1292,-1292,-1292,-1292,-1292,-1292 }, { 69,-1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293, -1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293, -1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293, -1293,-1293, 1305,-1293,-1293,-1293,-1293,-1293,-1293,-1293, -1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293, -1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293, -1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293, -1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293, -1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293, -1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293, -1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293, -1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293, -1293,-1293,-1293,-1293,-1293,-1293,-1293,-1293 }, { 69,-1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294, -1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294, -1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294, -1294,-1294, 1306,-1294,-1294,-1294,-1294,-1294,-1294,-1294, -1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294, -1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294, -1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294, -1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294, -1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294, -1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294, -1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294, -1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294, -1294,-1294,-1294,-1294,-1294,-1294,-1294,-1294 }, { 69,-1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295, -1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295, -1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295, -1295,-1295, 1307,-1295,-1295,-1295,-1295,-1295,-1295,-1295, -1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295, -1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295, -1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295, -1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295, -1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295, -1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295, -1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295, -1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295, -1295,-1295,-1295,-1295,-1295,-1295,-1295,-1295 }, { 69,-1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296, -1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296, -1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296, -1296,-1296, 1308,-1296,-1296,-1296,-1296,-1296,-1296,-1296, -1296,-1296,-1296, 1309,-1296, 1309,-1296,-1296, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310,-1296,-1296, -1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296, -1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296, -1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296, -1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296, -1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296, -1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296, -1296,-1296,-1296,-1296,-1296,-1296,-1296,-1296 }, { 69,-1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297, -1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297, -1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297, -1297,-1297, 1311,-1297,-1297,-1297,-1297,-1297,-1297,-1297, -1297,-1297,-1297, 1312,-1297, 1312,-1297,-1297, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,-1297,-1297, -1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297, -1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297, -1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297, -1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297, -1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297, -1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297, -1297,-1297,-1297,-1297,-1297,-1297,-1297,-1297 }, { 69,-1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298, -1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298, -1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298, -1298,-1298, 1314,-1298,-1298,-1298,-1298,-1298,-1298,-1298, -1298,-1298,-1298, 1315,-1298, 1315,-1298,-1298, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316,-1298,-1298, -1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298, -1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298, -1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298, -1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298, -1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298, -1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298, -1298,-1298,-1298,-1298,-1298,-1298,-1298,-1298 }, { 69,-1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299, -1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299, -1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299, -1299,-1299, 1317,-1299,-1299,-1299,-1299,-1299,-1299,-1299, -1299,-1299,-1299, 1318,-1299, 1318,-1299,-1299, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319,-1299,-1299, -1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299, -1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299, -1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299, -1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299, -1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299, -1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299, -1299,-1299,-1299,-1299,-1299,-1299,-1299,-1299 }, { 69,-1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300, -1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300, -1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300, -1300,-1300, 1320,-1300,-1300,-1300,-1300,-1300,-1300,-1300, -1300,-1300,-1300, 1321,-1300, 1321,-1300,-1300, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,-1300,-1300, -1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300, -1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300, -1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300, -1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300, -1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300, -1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300, -1300,-1300,-1300,-1300,-1300,-1300,-1300,-1300 }, { 69,-1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301, -1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301, -1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301, -1301,-1301, 1323,-1301,-1301,-1301,-1301,-1301,-1301, 1324, -1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301, -1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301, -1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301, -1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301, -1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301, -1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301, -1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301, -1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301, -1301,-1301,-1301,-1301,-1301,-1301,-1301,-1301 }, { 69,-1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302, -1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302, -1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302, -1302,-1302, 1325,-1302,-1302,-1302,-1302,-1302,-1302, 1326, -1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302, -1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302, -1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302, -1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302, -1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302, -1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302, -1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302, -1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302, -1302,-1302,-1302,-1302,-1302,-1302,-1302,-1302 }, { 69,-1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303, -1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303, -1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303, -1303,-1303, 1327,-1303,-1303,-1303,-1303,-1303,-1303, 1328, -1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303, -1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303, -1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303, -1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303, -1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303, -1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303, -1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303, -1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303, -1303,-1303,-1303,-1303,-1303,-1303,-1303,-1303 }, { 69,-1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304, -1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304, -1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304, -1304,-1304, 1329,-1304,-1304,-1304,-1304,-1304,-1304, 1330, -1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304, -1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304, -1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304, -1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304, -1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304, -1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304, -1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304, -1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304, -1304,-1304,-1304,-1304,-1304,-1304,-1304,-1304 }, { 69,-1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305, -1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305, -1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305, -1305,-1305, 1331,-1305,-1305,-1305,-1305,-1305,-1305, 1332, -1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305, -1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305, -1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305, -1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305, -1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305, -1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305, -1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305, -1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305, -1305,-1305,-1305,-1305,-1305,-1305,-1305,-1305 }, { 69,-1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306, -1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306, -1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306, -1306,-1306, 1333,-1306,-1306,-1306,-1306,-1306,-1306, 1334, -1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306, -1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306, -1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306, -1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306, -1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306, -1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306, -1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306, -1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306, -1306,-1306,-1306,-1306,-1306,-1306,-1306,-1306 }, { 69,-1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307, -1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307, -1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307, -1307,-1307, 1335,-1307,-1307,-1307,-1307,-1307,-1307,-1307, -1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307, -1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307, -1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307, -1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307, -1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307, -1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307, -1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307, -1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307, -1307,-1307,-1307,-1307,-1307,-1307,-1307,-1307 }, { 69,-1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308, -1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308, -1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308, -1308,-1308, 1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308, -1308,-1308,-1308, 1309,-1308, 1309,-1308,-1308, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310,-1308,-1308, -1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308, -1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308, -1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308, -1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308, -1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308, -1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308, -1308,-1308,-1308,-1308,-1308,-1308,-1308,-1308 }, { 69,-1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309, -1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309, -1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309, -1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309, -1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310,-1309,-1309, -1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309, -1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309, -1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309, -1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309, -1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309, -1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309, -1309,-1309,-1309,-1309,-1309,-1309,-1309,-1309 }, { 69,-1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310, -1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310, -1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310, -1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310, -1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310,-1310,-1310, -1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310, -1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310, -1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310, -1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310, -1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310, -1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310, -1310,-1310,-1310,-1310,-1310,-1310,-1310,-1310 }, { 69,-1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311, -1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311, -1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311, -1311,-1311, 1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311, -1311,-1311,-1311, 1312,-1311, 1312,-1311,-1311, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,-1311,-1311, -1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311, -1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311, -1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311, -1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311, -1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311, -1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311, -1311,-1311,-1311,-1311,-1311,-1311,-1311,-1311 }, { 69,-1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312, -1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312, -1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312, -1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312, -1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,-1312,-1312, -1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312, -1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312, -1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312, -1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312, -1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312, -1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312, -1312,-1312,-1312,-1312,-1312,-1312,-1312,-1312 }, { 69,-1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313, -1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313, -1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313, -1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313, -1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,-1313,-1313, -1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313, -1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313, -1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313, -1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313, -1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313, -1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313, -1313,-1313,-1313,-1313,-1313,-1313,-1313,-1313 }, { 69,-1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314, -1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314, -1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314, -1314,-1314, 1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314, -1314,-1314,-1314, 1315,-1314, 1315,-1314,-1314, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316,-1314,-1314, -1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314, -1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314, -1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314, -1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314, -1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314, -1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314, -1314,-1314,-1314,-1314,-1314,-1314,-1314,-1314 }, { 69,-1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315, -1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315, -1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315, -1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315, -1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316,-1315,-1315, -1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315, -1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315, -1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315, -1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315, -1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315, -1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315, -1315,-1315,-1315,-1315,-1315,-1315,-1315,-1315 }, { 69,-1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316, -1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316, -1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316, -1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316, -1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316,-1316,-1316, -1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316, -1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316, -1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316, -1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316, -1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316, -1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316, -1316,-1316,-1316,-1316,-1316,-1316,-1316,-1316 }, { 69,-1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317, -1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317, -1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317, -1317,-1317, 1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317, -1317,-1317,-1317, 1318,-1317, 1318,-1317,-1317, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319,-1317,-1317, -1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317, -1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317, -1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317, -1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317, -1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317, -1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317, -1317,-1317,-1317,-1317,-1317,-1317,-1317,-1317 }, { 69,-1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318, -1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318, -1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318, -1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318, -1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319,-1318,-1318, -1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318, -1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318, -1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318, -1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318, -1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318, -1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318, -1318,-1318,-1318,-1318,-1318,-1318,-1318,-1318 }, { 69,-1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319, -1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319, -1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319, -1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319, -1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319,-1319,-1319, -1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319, -1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319, -1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319, -1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319, -1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319, -1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319, -1319,-1319,-1319,-1319,-1319,-1319,-1319,-1319 }, { 69,-1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320, -1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320, -1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320, -1320,-1320, 1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320, -1320,-1320,-1320, 1321,-1320, 1321,-1320,-1320, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,-1320,-1320, -1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320, -1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320, -1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320, -1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320, -1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320, -1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320, -1320,-1320,-1320,-1320,-1320,-1320,-1320,-1320 }, { 69,-1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321, -1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321, -1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321, -1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321, -1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,-1321,-1321, -1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321, -1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321, -1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321, -1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321, -1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321, -1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321, -1321,-1321,-1321,-1321,-1321,-1321,-1321,-1321 }, { 69,-1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322, -1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322, -1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322, -1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322, -1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,-1322,-1322, -1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322, -1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322, -1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322, -1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322, -1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322, -1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322, -1322,-1322,-1322,-1322,-1322,-1322,-1322,-1322 }, { 69,-1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323, -1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323, -1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323, -1323,-1323, 1323,-1323,-1323,-1323,-1323,-1323,-1323, 1324, -1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323, -1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323, -1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323, -1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323, -1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323, -1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323, -1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323, -1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323, -1323,-1323,-1323,-1323,-1323,-1323,-1323,-1323 }, { 69, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1337, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336 }, { 69,-1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325, -1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325, -1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325, -1325,-1325, 1325,-1325,-1325,-1325,-1325,-1325,-1325, 1326, -1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325, -1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325, -1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325, -1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325, -1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325, -1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325, -1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325, -1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325, -1325,-1325,-1325,-1325,-1325,-1325,-1325,-1325 }, { 69, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1339, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338 }, { 69,-1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327, -1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327, -1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327, -1327,-1327, 1327,-1327,-1327,-1327,-1327,-1327,-1327, 1328, -1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327, -1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327, -1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327, -1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327, -1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327, -1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327, -1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327, -1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327, -1327,-1327,-1327,-1327,-1327,-1327,-1327,-1327 }, { 69, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1341, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340 }, { 69,-1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329, -1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329, -1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329, -1329,-1329, 1329,-1329,-1329,-1329,-1329,-1329,-1329, 1330, -1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329, -1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329, -1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329, -1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329, -1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329, -1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329, -1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329, -1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329, -1329,-1329,-1329,-1329,-1329,-1329,-1329,-1329 }, { 69, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1343, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342 }, { 69,-1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331, -1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331, -1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331, -1331,-1331, 1331,-1331,-1331,-1331,-1331,-1331,-1331, 1332, -1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331, -1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331, -1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331, -1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331, -1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331, -1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331, -1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331, -1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331, -1331,-1331,-1331,-1331,-1331,-1331,-1331,-1331 }, { 69, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1345, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344 }, { 69,-1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333, -1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333, -1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333, -1333,-1333, 1333,-1333,-1333,-1333,-1333,-1333,-1333, 1334, -1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333, -1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333, -1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333, -1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333, -1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333, -1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333, -1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333, -1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333, -1333,-1333,-1333,-1333,-1333,-1333,-1333,-1333 }, { 69, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1347, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346 }, { 69,-1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335, -1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335, -1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335, -1335,-1335, 1348,-1335,-1335,-1335,-1335,-1335,-1335,-1335, -1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335, -1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335, -1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335, -1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335, -1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335, -1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335, -1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335, -1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335, -1335,-1335,-1335,-1335,-1335,-1335,-1335,-1335 }, { 69, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1337, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336 }, { 69,-1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337, -1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337, -1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337, -1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337, 1336, -1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337, -1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337, -1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337, -1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337, -1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337, -1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337, -1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337, -1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337, -1337,-1337,-1337,-1337,-1337,-1337,-1337,-1337 }, { 69, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1339, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338 }, { 69,-1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339, -1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339, -1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339, -1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339, 1338, -1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339, -1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339, -1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339, -1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339, -1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339, -1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339, -1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339, -1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339, -1339,-1339,-1339,-1339,-1339,-1339,-1339,-1339 }, { 69, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1341, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340 }, { 69,-1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341, -1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341, -1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341, -1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341, 1340, -1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341, -1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341, -1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341, -1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341, -1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341, -1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341, -1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341, -1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341, -1341,-1341,-1341,-1341,-1341,-1341,-1341,-1341 }, { 69, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1343, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342, 1342 }, { 69,-1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343, -1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343, -1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343, -1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343, 1342, -1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343, -1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343, -1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343, -1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343, -1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343, -1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343, -1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343, -1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343, -1343,-1343,-1343,-1343,-1343,-1343,-1343,-1343 }, { 69, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1345, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344 }, { 69,-1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345, -1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345, -1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345, -1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345, 1344, -1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345, -1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345, -1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345, -1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345, -1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345, -1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345, -1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345, -1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345, -1345,-1345,-1345,-1345,-1345,-1345,-1345,-1345 }, { 69, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1347, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346 }, { 69,-1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347, -1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347, -1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347, -1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347, 1346, -1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347, -1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347, -1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347, -1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347, -1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347, -1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347, -1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347, -1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347, -1347,-1347,-1347,-1347,-1347,-1347,-1347,-1347 }, { 69,-1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348, -1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348, -1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348, -1348,-1348, 1349,-1348,-1348,-1348,-1348,-1348,-1348,-1348, -1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348, -1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348, -1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348, -1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348, -1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348, -1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348, -1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348, -1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348, -1348,-1348,-1348,-1348,-1348,-1348,-1348,-1348 }, { 69,-1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349, -1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349, -1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349, -1349,-1349, 1350,-1349,-1349,-1349,-1349,-1349,-1349,-1349, -1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349, -1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349, -1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349, -1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349, -1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349, -1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349, -1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349, -1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349, -1349,-1349,-1349,-1349,-1349,-1349,-1349,-1349 }, { 69,-1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350, -1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350, -1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350, -1350,-1350, 1351,-1350,-1350,-1350,-1350,-1350,-1350,-1350, -1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350, -1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350, -1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350, -1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350, -1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350, -1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350, -1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350, -1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350, -1350,-1350,-1350,-1350,-1350,-1350,-1350,-1350 }, { 69,-1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351, -1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351, -1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351, -1351,-1351, 1352,-1351,-1351,-1351,-1351,-1351,-1351,-1351, -1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351, -1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351, -1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351, -1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351, -1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351, -1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351, -1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351, -1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351, -1351,-1351,-1351,-1351,-1351,-1351,-1351,-1351 }, { 69,-1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352, -1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352, -1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352, -1352,-1352, 1353,-1352,-1352,-1352,-1352,-1352,-1352,-1352, -1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352, -1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352, -1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352, -1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352, -1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352, -1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352, -1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352, -1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352, -1352,-1352,-1352,-1352,-1352,-1352,-1352,-1352 }, { 69,-1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353, -1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353, -1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353, -1353,-1353, 1354,-1353,-1353,-1353,-1353,-1353,-1353,-1353, -1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353, -1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353, -1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353, -1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353, -1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353, -1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353, -1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353, -1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353, -1353,-1353,-1353,-1353,-1353,-1353,-1353,-1353 }, { 69,-1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354, -1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354, -1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354, -1354,-1354, 1355,-1354,-1354,-1354,-1354,-1354,-1354,-1354, -1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354, -1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354, -1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354, -1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354, -1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354, -1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354, -1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354, -1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354, -1354,-1354,-1354,-1354,-1354,-1354,-1354,-1354 }, { 69,-1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355, -1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355, -1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355, -1355,-1355, 1356,-1355,-1355,-1355,-1355,-1355,-1355,-1355, -1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355, -1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355, -1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355, -1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355, -1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355, -1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355, -1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355, -1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355, -1355,-1355,-1355,-1355,-1355,-1355,-1355,-1355 }, { 69,-1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356, -1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356, -1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356, -1356,-1356, 1357,-1356,-1356,-1356,-1356,-1356,-1356,-1356, -1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356, -1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356, -1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356, -1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356, -1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356, -1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356, -1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356, -1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356, -1356,-1356,-1356,-1356,-1356,-1356,-1356,-1356 }, { 69,-1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357, -1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357, -1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357, -1357,-1357, 1358,-1357,-1357,-1357,-1357,-1357,-1357,-1357, -1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357, -1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357, -1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357, -1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357, -1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357, -1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357, -1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357, -1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357, -1357,-1357,-1357,-1357,-1357,-1357,-1357,-1357 }, { 69,-1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358, -1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358, -1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358, -1358,-1358, 1359,-1358,-1358,-1358,-1358,-1358,-1358,-1358, -1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358, -1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358, -1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358, -1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358, -1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358, -1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358, -1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358, -1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358, -1358,-1358,-1358,-1358,-1358,-1358,-1358,-1358 }, { 69,-1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359, -1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359, -1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359, -1359,-1359, 1360,-1359,-1359,-1359,-1359,-1359,-1359,-1359, -1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359, -1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359, -1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359, -1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359, -1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359, -1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359, -1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359, -1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359, -1359,-1359,-1359,-1359,-1359,-1359,-1359,-1359 }, { 69,-1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360, -1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360, -1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360, -1360,-1360, 1361,-1360,-1360,-1360,-1360,-1360,-1360,-1360, -1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360, -1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360, -1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360, -1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360, -1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360, -1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360, -1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360, -1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360, -1360,-1360,-1360,-1360,-1360,-1360,-1360,-1360 }, { 69,-1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361, -1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361, -1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361, -1361,-1361, 1362,-1361,-1361,-1361,-1361,-1361,-1361,-1361, -1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361, -1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361, -1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361, -1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361, -1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361, -1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361, -1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361, -1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361, -1361,-1361,-1361,-1361,-1361,-1361,-1361,-1361 }, { 69,-1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362, -1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362, -1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362, -1362,-1362, 1363,-1362,-1362,-1362,-1362,-1362,-1362,-1362, -1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362, -1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362, -1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362, -1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362, -1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362, -1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362, -1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362, -1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362, -1362,-1362,-1362,-1362,-1362,-1362,-1362,-1362 }, { 69,-1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363, -1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363, -1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363, -1363,-1363, 1364,-1363,-1363,-1363,-1363,-1363,-1363,-1363, -1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363, -1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363, -1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363, -1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363, -1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363, -1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363, -1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363, -1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363, -1363,-1363,-1363,-1363,-1363,-1363,-1363,-1363 }, { 69,-1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364, -1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364, -1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364, -1364,-1364, 1365,-1364,-1364,-1364,-1364,-1364,-1364,-1364, -1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364, -1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364, -1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364, -1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364, -1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364, -1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364, -1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364, -1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364, -1364,-1364,-1364,-1364,-1364,-1364,-1364,-1364 }, { 69,-1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365, -1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365, -1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365, -1365,-1365, 1366,-1365,-1365,-1365,-1365,-1365,-1365,-1365, -1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365, -1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365, -1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365, -1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365, -1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365, -1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365, -1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365, -1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365, -1365,-1365,-1365,-1365,-1365,-1365,-1365,-1365 }, { 69,-1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366, -1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366, -1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366, -1366,-1366, 1367,-1366,-1366,-1366,-1366,-1366,-1366,-1366, -1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366, -1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366, -1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366, -1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366, -1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366, -1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366, -1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366, -1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366, -1366,-1366,-1366,-1366,-1366,-1366,-1366,-1366 }, { 69,-1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367, -1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367, -1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367, -1367,-1367, 1368,-1367,-1367,-1367,-1367,-1367,-1367,-1367, -1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367, -1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367, -1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367, -1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367, -1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367, -1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367, -1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367, -1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367, -1367,-1367,-1367,-1367,-1367,-1367,-1367,-1367 }, { 69,-1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368, -1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368, -1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368, -1368,-1368, 1369,-1368,-1368,-1368,-1368,-1368,-1368,-1368, -1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368, -1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368, -1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368, -1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368, -1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368, -1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368, -1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368, -1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368, -1368,-1368,-1368,-1368,-1368,-1368,-1368,-1368 }, { 69,-1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369, -1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369, -1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369, -1369,-1369, 1370,-1369,-1369,-1369,-1369,-1369,-1369,-1369, -1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369, -1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369, -1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369, -1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369, -1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369, -1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369, -1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369, -1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369, -1369,-1369,-1369,-1369,-1369,-1369,-1369,-1369 }, { 69,-1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370, -1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370, -1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370, -1370,-1370, 1371,-1370,-1370,-1370,-1370,-1370,-1370,-1370, -1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370, -1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370, -1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370, -1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370, -1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370, -1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370, -1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370, -1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370, -1370,-1370,-1370,-1370,-1370,-1370,-1370,-1370 }, { 69,-1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371, -1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371, -1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371, -1371,-1371, 1372,-1371,-1371,-1371,-1371,-1371,-1371,-1371, -1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371, -1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371, -1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371, -1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371, -1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371, -1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371, -1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371, -1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371, -1371,-1371,-1371,-1371,-1371,-1371,-1371,-1371 }, { 69,-1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372, -1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372, -1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372, -1372,-1372, 1373,-1372,-1372,-1372,-1372,-1372,-1372,-1372, -1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372, -1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372, -1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372, -1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372, -1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372, -1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372, -1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372, -1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372, -1372,-1372,-1372,-1372,-1372,-1372,-1372,-1372 }, { 69,-1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373, -1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373, -1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373, -1373,-1373, 1374,-1373,-1373,-1373,-1373,-1373,-1373,-1373, -1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373, -1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373, -1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373, -1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373, -1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373, -1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373, -1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373, -1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373, -1373,-1373,-1373,-1373,-1373,-1373,-1373,-1373 }, { 69,-1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374, -1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374, -1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374, -1374,-1374, 1375,-1374,-1374,-1374,-1374,-1374,-1374,-1374, -1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374, -1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374, -1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374, -1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374, -1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374, -1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374, -1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374, -1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374, -1374,-1374,-1374,-1374,-1374,-1374,-1374,-1374 }, { 69,-1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375, -1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375, -1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375, -1375,-1375, 1376,-1375,-1375,-1375,-1375,-1375,-1375,-1375, -1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375, -1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375, -1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375, -1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375, -1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375, -1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375, -1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375, -1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375, -1375,-1375,-1375,-1375,-1375,-1375,-1375,-1375 }, { 69,-1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376, -1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376, -1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376, -1376,-1376, 1377,-1376,-1376,-1376,-1376,-1376,-1376,-1376, -1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376, -1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376, -1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376, -1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376, -1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376, -1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376, -1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376, -1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376, -1376,-1376,-1376,-1376,-1376,-1376,-1376,-1376 }, { 69,-1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377, -1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377, -1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377, -1377,-1377, 1378,-1377,-1377,-1377,-1377,-1377,-1377,-1377, -1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377, -1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377, -1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377, -1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377, -1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377, -1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377, -1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377, -1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377, -1377,-1377,-1377,-1377,-1377,-1377,-1377,-1377 }, { 69,-1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378, -1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378, -1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378, -1378,-1378, 1379,-1378,-1378,-1378,-1378,-1378,-1378,-1378, -1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378, -1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378, -1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378, -1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378, -1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378, -1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378, -1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378, -1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378, -1378,-1378,-1378,-1378,-1378,-1378,-1378,-1378 }, { 69,-1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379, -1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379, -1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379, -1379,-1379, 1380,-1379,-1379,-1379,-1379,-1379,-1379,-1379, -1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379, -1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379, -1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379, -1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379, -1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379, -1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379, -1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379, -1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379, -1379,-1379,-1379,-1379,-1379,-1379,-1379,-1379 }, { 69,-1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380, -1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380, -1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380, -1380,-1380, 1381,-1380,-1380,-1380,-1380,-1380,-1380,-1380, -1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380, -1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380, -1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380, -1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380, -1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380, -1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380, -1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380, -1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380, -1380,-1380,-1380,-1380,-1380,-1380,-1380,-1380 }, { 69,-1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381, -1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381, -1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381, -1381,-1381, 1382,-1381,-1381,-1381,-1381,-1381,-1381,-1381, -1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381, -1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381, -1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381, -1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381, -1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381, -1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381, -1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381, -1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381, -1381,-1381,-1381,-1381,-1381,-1381,-1381,-1381 }, { 69,-1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382, -1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382, -1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382, -1382,-1382, 1383,-1382,-1382,-1382,-1382,-1382,-1382,-1382, -1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382, -1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382, -1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382, -1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382, -1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382, -1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382, -1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382, -1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382, -1382,-1382,-1382,-1382,-1382,-1382,-1382,-1382 }, { 69,-1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383, -1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383, -1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383, -1383,-1383, 1384,-1383,-1383,-1383,-1383,-1383,-1383,-1383, -1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383, -1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383, -1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383, -1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383, -1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383, -1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383, -1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383, -1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383, -1383,-1383,-1383,-1383,-1383,-1383,-1383,-1383 }, { 69,-1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384, -1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384, -1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384, -1384,-1384, 1385,-1384,-1384,-1384,-1384,-1384,-1384,-1384, -1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384, -1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384, -1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384, -1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384, -1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384, -1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384, -1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384, -1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384, -1384,-1384,-1384,-1384,-1384,-1384,-1384,-1384 }, { 69,-1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385, -1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385, -1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385, -1385,-1385, 1386,-1385,-1385,-1385,-1385,-1385,-1385,-1385, -1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385, -1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385, -1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385, -1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385, -1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385, -1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385, -1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385, -1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385, -1385,-1385,-1385,-1385,-1385,-1385,-1385,-1385 }, { 69,-1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386, -1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386, -1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386, -1386,-1386, 1387,-1386,-1386,-1386,-1386,-1386,-1386,-1386, -1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386, -1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386, -1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386, -1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386, -1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386, -1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386, -1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386, -1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386, -1386,-1386,-1386,-1386,-1386,-1386,-1386,-1386 }, { 69,-1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387, -1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387, -1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387, -1387,-1387, 1388,-1387,-1387,-1387,-1387,-1387,-1387,-1387, -1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387, -1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387, -1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387, -1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387, -1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387, -1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387, -1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387, -1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387, -1387,-1387,-1387,-1387,-1387,-1387,-1387,-1387 }, { 69,-1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388, -1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388, -1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388, -1388,-1388, 1389,-1388,-1388,-1388,-1388,-1388,-1388,-1388, -1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388, -1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388, -1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388, -1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388, -1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388, -1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388, -1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388, -1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388, -1388,-1388,-1388,-1388,-1388,-1388,-1388,-1388 }, { 69,-1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389, -1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389, -1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389, -1389,-1389, 1390,-1389,-1389,-1389,-1389,-1389,-1389,-1389, -1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389, -1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389, -1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389, -1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389, -1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389, -1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389, -1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389, -1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389, -1389,-1389,-1389,-1389,-1389,-1389,-1389,-1389 }, { 69,-1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390, -1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390, -1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390, -1390,-1390, 1391,-1390,-1390,-1390,-1390,-1390,-1390,-1390, -1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390, -1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390, -1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390, -1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390, -1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390, -1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390, -1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390, -1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390, -1390,-1390,-1390,-1390,-1390,-1390,-1390,-1390 }, { 69,-1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391, -1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391, -1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391, -1391,-1391, 1392,-1391,-1391,-1391,-1391,-1391,-1391,-1391, -1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391, -1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391, -1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391, -1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391, -1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391, -1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391, -1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391, -1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391, -1391,-1391,-1391,-1391,-1391,-1391,-1391,-1391 }, { 69,-1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392, -1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392, -1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392, -1392,-1392, 1393,-1392,-1392,-1392,-1392,-1392,-1392,-1392, -1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392, -1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392, -1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392, -1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392, -1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392, -1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392, -1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392, -1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392, -1392,-1392,-1392,-1392,-1392,-1392,-1392,-1392 }, { 69,-1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393, -1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393, -1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393, -1393,-1393, 1394,-1393,-1393,-1393,-1393,-1393,-1393,-1393, -1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393, -1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393, -1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393, -1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393, -1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393, -1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393, -1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393, -1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393, -1393,-1393,-1393,-1393,-1393,-1393,-1393,-1393 }, { 69,-1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394, -1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394, -1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394, -1394,-1394, 1395,-1394,-1394,-1394,-1394,-1394,-1394,-1394, -1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394, -1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394, -1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394, -1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394, -1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394, -1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394, -1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394, -1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394, -1394,-1394,-1394,-1394,-1394,-1394,-1394,-1394 }, { 69,-1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395, -1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395, -1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395, -1395,-1395, 1396,-1395,-1395,-1395,-1395,-1395,-1395,-1395, -1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395, -1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395, -1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395, -1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395, -1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395, -1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395, -1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395, -1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395, -1395,-1395,-1395,-1395,-1395,-1395,-1395,-1395 }, { 69,-1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396, -1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396, -1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396, -1396,-1396, 1397,-1396,-1396,-1396,-1396,-1396,-1396,-1396, -1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396, -1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396, -1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396, -1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396, -1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396, -1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396, -1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396, -1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396, -1396,-1396,-1396,-1396,-1396,-1396,-1396,-1396 }, { 69,-1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397, -1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397, -1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397, -1397,-1397, 1398,-1397,-1397,-1397,-1397,-1397,-1397,-1397, -1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397, -1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397, -1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397, -1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397, -1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397, -1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397, -1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397, -1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397, -1397,-1397,-1397,-1397,-1397,-1397,-1397,-1397 }, { 69,-1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398, -1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398, -1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398, -1398,-1398, 1399,-1398,-1398,-1398,-1398,-1398,-1398,-1398, -1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398, -1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398, -1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398, -1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398, -1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398, -1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398, -1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398, -1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398, -1398,-1398,-1398,-1398,-1398,-1398,-1398,-1398 }, { 69,-1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399, -1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399, -1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399, -1399,-1399, 1400,-1399,-1399,-1399,-1399,-1399,-1399,-1399, -1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399, -1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399, -1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399, -1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399, -1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399, -1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399, -1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399, -1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399, -1399,-1399,-1399,-1399,-1399,-1399,-1399,-1399 }, { 69,-1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400, -1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400, -1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400, -1400,-1400, 1401,-1400,-1400,-1400,-1400,-1400,-1400,-1400, -1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400, -1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400, -1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400, -1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400, -1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400, -1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400, -1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400, -1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400, -1400,-1400,-1400,-1400,-1400,-1400,-1400,-1400 }, { 69,-1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401, -1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401, -1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401, -1401,-1401, 1402,-1401,-1401,-1401,-1401,-1401,-1401,-1401, -1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401, -1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401, -1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401, -1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401, -1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401, -1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401, -1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401, -1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401, -1401,-1401,-1401,-1401,-1401,-1401,-1401,-1401 }, { 69,-1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402, -1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402, -1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402, -1402,-1402, 1403,-1402,-1402,-1402,-1402,-1402,-1402,-1402, -1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402, -1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402, -1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402, -1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402, -1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402, -1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402, -1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402, -1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402, -1402,-1402,-1402,-1402,-1402,-1402,-1402,-1402 }, { 69,-1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403, -1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403, -1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403, -1403,-1403, 1404,-1403,-1403,-1403,-1403,-1403,-1403,-1403, -1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403, -1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403, -1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403, -1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403, -1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403, -1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403, -1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403, -1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403, -1403,-1403,-1403,-1403,-1403,-1403,-1403,-1403 }, { 69,-1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404, -1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404, -1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404, -1404,-1404, 1405,-1404,-1404,-1404,-1404,-1404,-1404,-1404, -1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404, -1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404, -1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404, -1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404, -1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404, -1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404, -1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404, -1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404, -1404,-1404,-1404,-1404,-1404,-1404,-1404,-1404 }, { 69,-1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405, -1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405, -1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405, -1405,-1405, 1406,-1405,-1405,-1405,-1405,-1405,-1405,-1405, -1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405, -1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405, -1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405, -1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405, -1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405, -1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405, -1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405, -1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405, -1405,-1405,-1405,-1405,-1405,-1405,-1405,-1405 }, { 69,-1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406, -1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406, -1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406, -1406,-1406, 1407,-1406,-1406,-1406,-1406,-1406,-1406,-1406, -1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406, -1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406, -1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406, -1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406, -1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406, -1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406, -1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406, -1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406, -1406,-1406,-1406,-1406,-1406,-1406,-1406,-1406 }, { 69,-1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407, -1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407, -1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407, -1407,-1407, 1408,-1407,-1407,-1407,-1407,-1407,-1407,-1407, -1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407, -1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407, -1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407, -1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407, -1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407, -1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407, -1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407, -1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407, -1407,-1407,-1407,-1407,-1407,-1407,-1407,-1407 }, { 69,-1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408, -1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408, -1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408, -1408,-1408, 1409,-1408,-1408,-1408,-1408,-1408,-1408,-1408, -1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408, -1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408, -1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408, -1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408, -1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408, -1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408, -1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408, -1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408, -1408,-1408,-1408,-1408,-1408,-1408,-1408,-1408 }, { 69,-1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409, -1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409, -1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409, -1409,-1409, 1410,-1409,-1409,-1409,-1409,-1409,-1409,-1409, -1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409, -1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409, -1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409, -1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409, -1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409, -1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409, -1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409, -1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409, -1409,-1409,-1409,-1409,-1409,-1409,-1409,-1409 }, { 69,-1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410, -1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410, -1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410, -1410,-1410, 1411,-1410,-1410,-1410,-1410,-1410,-1410,-1410, -1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410, -1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410, -1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410, -1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410, -1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410, -1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410, -1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410, -1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410, -1410,-1410,-1410,-1410,-1410,-1410,-1410,-1410 }, { 69,-1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411, -1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411, -1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411, -1411,-1411, 1412,-1411,-1411,-1411,-1411,-1411,-1411,-1411, -1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411, -1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411, -1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411, -1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411, -1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411, -1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411, -1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411, -1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411, -1411,-1411,-1411,-1411,-1411,-1411,-1411,-1411 }, { 69,-1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412, -1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412, -1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412, -1412,-1412, 1413,-1412,-1412,-1412,-1412,-1412,-1412,-1412, -1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412, -1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412, -1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412, -1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412, -1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412, -1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412, -1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412, -1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412, -1412,-1412,-1412,-1412,-1412,-1412,-1412,-1412 }, { 69,-1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413, -1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413, -1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413, -1413,-1413, 1414,-1413,-1413,-1413,-1413,-1413,-1413,-1413, -1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413, -1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413, -1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413, -1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413, -1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413, -1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413, -1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413, -1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413, -1413,-1413,-1413,-1413,-1413,-1413,-1413,-1413 }, { 69,-1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414, -1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414, -1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414, -1414,-1414, 1415,-1414,-1414,-1414,-1414,-1414,-1414,-1414, -1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414, -1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414, -1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414, -1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414, -1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414, -1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414, -1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414, -1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414, -1414,-1414,-1414,-1414,-1414,-1414,-1414,-1414 }, { 69,-1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415, -1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415, -1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415, -1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415, -1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415, -1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415, -1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415, -1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415, -1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415, -1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415, -1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415, -1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415, -1415,-1415,-1415,-1415,-1415,-1415,-1415,-1415 }, } ; static yy_state_type yy_get_previous_state ( yyscan_t yyscanner ); static yy_state_type yy_try_NUL_trans ( yy_state_type current_state , yyscan_t yyscanner); static int yy_get_next_buffer ( yyscan_t yyscanner ); static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ yyg->yytext_ptr = yy_bp; \ yyleng = (int) (yy_cp - yy_bp); \ yyg->yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; #define YY_NUM_RULES 428 #define YY_END_OF_BUFFER 429 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static const flex_int16_t yy_accept[1416] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 429, 428, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 199, 199, 199, 218, 218, 210, 210, 219, 219, 211, 211, 266, 266, 266, 428, 287, 287, 276, 276, 291, 291, 302, 302, 303, 303, 369, 369, 369, 404, 404, 382, 382, 405, 405, 383, 383, 409, 409, 305, 306, 304, 313, 313, 314, 314, 322, 322, 323, 323, 411, 411, 413, 413, 412, 415, 415, 415, 414, 417, 417, 417, 416, 419, 419, 428, 420, 428, 428, 428, 425, 428, 426, 428, 427, 0, 0, 0, 64, 58, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 63, 57, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 19, 0, 66, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 410, 412, 0, 414, 414, 414, 414, 0, 0, 416, 416, 416, 416, 0, 0, 418, 0, 422, 0, 0, 0, 420, 0, 0, 0, 420, 0, 0, 0, 425, 0, 426, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 67, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 196, 197, 198, 195, 194, 192, 193, 0, 0, 0, 200, 201, 202, 207, 206, 0, 0, 0, 203, 204, 205, 209, 208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 288, 289, 290, 292, 293, 294, 299, 298, 295, 296, 297, 301, 300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 406, 407, 408, 0, 0, 0, 310, 311, 312, 0, 0, 0, 319, 320, 321, 414, 0, 414, 416, 0, 416, 0, 0, 421, 0, 0, 0, 423, 0, 0, 0, 420, 0, 0, 22, 18, 26, 0, 70, 0, 90, 75, 0, 13, 44, 80, 39, 34, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 125, 0, 0, 0, 0, 167, 0, 0, 0, 0, 0, 51, 49, 0, 131, 0, 0, 0, 0, 0, 0, 163, 0, 54, 0, 56, 171, 169, 181, 0, 28, 0, 72, 0, 92, 77, 0, 15, 46, 82, 41, 36, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 183, 0, 0, 0, 0, 173, 0, 0, 95, 0, 0, 0, 179, 212, 213, 214, 215, 216, 217, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 267, 268, 269, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 307, 308, 309, 315, 316, 317, 318, 424, 0, 0, 0, 421, 0, 0, 0, 420, 0, 0, 27, 71, 91, 76, 31, 14, 45, 81, 40, 35, 86, 0, 25, 69, 89, 74, 0, 0, 30, 12, 43, 79, 38, 33, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 144, 146, 148, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 29, 73, 93, 78, 32, 16, 47, 83, 42, 37, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 272, 274, 270, 271, 273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 375, 373, 374, 370, 371, 372, 0, 0, 0, 0, 0, 0, 0, 0, 381, 379, 380, 376, 377, 378, 0, 421, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 257, 260, 264, 256, 259, 263, 258, 262, 261, 265, 251, 229, 248, 252, 240, 230, 226, 235, 246, 249, 253, 241, 238, 243, 231, 227, 236, 224, 233, 245, 247, 250, 254, 242, 239, 244, 222, 223, 232, 228, 237, 225, 234, 220, 221, 286, 282, 285, 279, 281, 284, 277, 278, 280, 283, 359, 361, 364, 368, 360, 363, 367, 362, 366, 365, 355, 333, 352, 356, 344, 330, 334, 339, 350, 353, 357, 342, 345, 347, 328, 331, 335, 340, 337, 349, 351, 354, 358, 326, 343, 346, 348, 327, 324, 329, 332, 336, 341, 338, 325, 399, 389, 398, 387, 388, 397, 384, 385, 386, 396, 403, 395, 402, 393, 394, 401, 390, 391, 392, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 0, 0, 0, 117, 115, 0, 0, 0, 0, 50, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 162, 0, 53, 55, 0, 168, 170, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 182, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 178, 134, 186, 188, 124, 123, 126, 119, 105, 104, 120, 121, 122, 185, 0, 165, 187, 189, 113, 112, 116, 114, 133, 130, 129, 132, 127, 107, 111, 109, 106, 110, 108, 154, 155, 156, 153, 157, 149, 143, 145, 147, 158, 159, 160, 150, 151, 152, 161, 102, 164, 52, 184, 138, 0, 141, 118, 142, 97, 103, 140, 139, 100, 98, 135, 136, 68, 175, 176, 177, 174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 0, 0, 4, 0, 0, 5, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 10, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 190 } ; static const yy_state_type yy_NUL_trans[1416] = { 0, 70, 71, 90, 90, 93, 93, 95, 95, 97, 97, 99, 99, 101, 101, 70, 70, 105, 105, 107, 107, 109, 109, 111, 111, 113, 113, 115, 115, 118, 118, 120, 120, 122, 122, 124, 124, 126, 126, 128, 128, 129, 129, 131, 131, 133, 133, 135, 135, 137, 137, 139, 139, 141, 141, 144, 144, 148, 148, 152, 152, 154, 154, 158, 158, 160, 160, 162, 162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 292, 294, 0, 298, 302, 306, 0, 308, 0, 310, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 292, 0, 294, 0, 496, 497, 501, 0, 505, 302, 302, 0, 302, 302, 306, 0, 308, 0, 310, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 496, 497, 0, 497, 497, 501, 0, 501, 698, 501, 0, 505, 702, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 496, 918, 698, 0, 698, 698, 702, 0, 702, 702, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 918, 0, 918, 918, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1336, 0, 1338, 0, 1340, 0, 1342, 0, 1344, 0, 1346, 0, 1336, 0, 1338, 0, 1340, 0, 1342, 0, 1344, 0, 1346, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "wcsbth.l" /*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcsbth.c,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * wcsbth.l is a Flex description file containing the definition of a lexical * scanner for parsing the WCS keyrecords for one or more image arrays and/or * pixel lists in a FITS binary table header. It can also handle primary image * and image extension headers. * * wcsbth.l requires Flex v2.5.4 or later. Refer to wcshdr.h for a description * of the user interface and operating notes. * * Implementation notes * -------------------- * wcsbth() may be invoked with an option that causes it to recognize the * image-header form of WCS keywords as defaults for each alternate coordinate * representation (up to 27). By design, with this option enabled wcsbth() can * also handle primary image and image extension headers, effectively treating * them as a single-column binary table though with WCS keywords of a different * form. * * NAXIS is always 2 for binary tables, it refers to the two-dimensional nature * of the table. Thus NAXIS does not count the number of image axes in either * image arrays or pixels lists and for the latter there is not even a formal * equivalent of WCSAXESa. Hence NAXIS is always ignored and a first pass * through the header is required to determine the number of images, the number * of alternate coordinate representations for each image (up to 27), and the * number of coordinate axes in each representation; this pass also counts the * number of iPVn_ma and iPSn_ma or TVk_ma and TSk_ma keywords in each * representation. * * On completion of the first pass, the association between column number and * axis number is defined for each representation of a pixel list. Memory is * allocated for an array of the required number of wcsprm structs and each of * these is initialized appropriately. These structs are filled in the second * pass. * * It is permissible for a scalar table column to contain degenerate (single- * point) image arrays and simultaneously form one axis of a pixel list. * * The parser does not check for duplicated keywords, for most keywords it * accepts the last encountered. * * wcsbth() does not currently handle the Green Bank convention. * *===========================================================================*/ /* Options. */ #define YY_NO_INPUT 1 /* Indices for parameterized keywords. */ /* Alternate coordinate system identifier. */ /* Keyvalue data types. */ /* Inline comment syntax. */ /* Exclusive start states. */ #line 113 "wcsbth.l" #include #include #include #include #include #include #include "wcs.h" #include "wcshdr.h" #include "wcsmath.h" #include "wcsprintf.h" #include "wcsutil.h" // Codes used for keyvalue data types. #define INTEGER 0 #define FLOAT 1 #define FLOAT2 2 #define STRING 3 // Bit masks used for keyword types: #define IMGAUX 0x1 // Auxiliary image header, e.g. LONPOLEa or // DATE-OBS. #define IMGAXIS 0x2 // Image header with axis number, e.g. // CTYPEia. #define IMGHEAD 0x3 // IMGAUX | IMGAXIS, i.e. image header of // either type. #define BIMGARR 0x4 // Binary table image array, e.g. iCTYna. #define PIXLIST 0x8 // Pixel list, e.g. TCTYna. #define BINTAB 0xC // BIMGARR | PIXLIST, i.e. binary table // image array (without axis number) or // pixel list, e.g. LONPna or OBSGXn. // User data associated with yyscanner. struct wcsbth_extra { // Values passed to YY_INPUT. char *hdr; int nkeyrec; // Used in preempting the call to exit() by yy_fatal_error(). jmp_buf abort_jmp_env; }; #define YY_DECL int wcsbth_scanner(char *header, int nkeyrec, int relax, \ int ctrl, int keysel, int *colsel, int *nreject, int *nwcs, \ struct wcsprm **wcs, yyscan_t yyscanner) #define YY_INPUT(inbuff, count, bufsize) \ { \ if (yyextra->nkeyrec) { \ strncpy(inbuff, yyextra->hdr, 80); \ inbuff[80] = '\n'; \ yyextra->hdr += 80; \ yyextra->nkeyrec--; \ count = 81; \ } else { \ count = YY_NULL; \ } \ } // Preempt the call to exit() by yy_fatal_error(). #define exit(status) longjmp(yyextra->abort_jmp_env, status); // A convenience macro to get around incompatibilities between unput() and // yyless(): put yytext followed by a blank back onto the input stream. #define WCSBTH_PUTBACK \ sprintf(strtmp, "%s ", yytext); \ size_t iz = strlen(strtmp); \ while (iz) unput(strtmp[--iz]); // Struct used internally for header bookkeeping. struct wcsbth_alts { int ncol, ialt, icol, imgherit; short int (*arridx)[27]; short int pixidx[27]; short int pad1; unsigned int *pixlist; unsigned char (*npv)[27]; unsigned char (*nps)[27]; unsigned char pixnpv[27]; unsigned char pixnps[27]; unsigned char pad2[2]; }; // Internal helper functions. static YY_DECL; static int wcsbth_colax(struct wcsprm *wcs, struct wcsbth_alts *alts, int k, char a); static int wcsbth_final(struct wcsbth_alts *alts, int *nwcs, struct wcsprm **wcs); static struct wcsprm *wcsbth_idx(struct wcsprm *wcs, struct wcsbth_alts *alts, int keytype, int n, char a); static int wcsbth_init1(struct wcsbth_alts *alts, int auxprm, int *nwcs, struct wcsprm **wcs); static int wcsbth_pass1(int keytype, int i, int j, int n, int k, char a, char ptype, struct wcsbth_alts *alts); // Helper functions for keywords that require special handling. static int wcsbth_jdref(double *wptr, const double *jdref); static int wcsbth_jdrefi(double *wptr, const double *jdrefi); static int wcsbth_jdreff(double *wptr, const double *jdreff); static int wcsbth_epoch(double *wptr, const double *epoch); static int wcsbth_vsource(double *wptr, const double *vsource); // Helper functions for keyvalue validity checking. static int wcsbth_timepixr(double timepixr); #line 25582 "wcsbth.c" #line 25583 "wcsbth.c" #define INITIAL 0 #define CCCCCia 1 #define iCCCna 2 #define iCCCCn 3 #define TCCCna 4 #define TCCCCn 5 #define CCi_ja 6 #define ijCCna 7 #define TCn_ka 8 #define TCCn_ka 9 #define CROTAi 10 #define iCROTn 11 #define TCROTn 12 #define CCi_ma 13 #define iCn_ma 14 #define iCCn_ma 15 #define TCn_ma 16 #define TCCn_ma 17 #define PROJPm 18 #define CCCCCCCC 19 #define CCCCCCCa 20 #define CCCCna 21 #define CCCCCna 22 #define CCCCn 23 #define CCCCCn 24 #define VALUE 25 #define INTEGER_VAL 26 #define FLOAT_VAL 27 #define FLOAT2_VAL 28 #define STRING_VAL 29 #define COMMENT 30 #define DISCARD 31 #define ERROR 32 #define FLUSH 33 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #define YY_EXTRA_TYPE struct wcsbth_extra * /* Holds the entire state of the reentrant scanner. */ struct yyguts_t { /* User-defined. Not touched by flex. */ YY_EXTRA_TYPE yyextra_r; /* The rest are the same as the globals declared in the non-reentrant scanner. */ FILE *yyin_r, *yyout_r; size_t yy_buffer_stack_top; /**< index of top of stack. */ size_t yy_buffer_stack_max; /**< capacity of stack. */ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ char yy_hold_char; int yy_n_chars; int yyleng_r; char *yy_c_buf_p; int yy_init; int yy_start; int yy_did_buffer_switch_on_eof; int yy_start_stack_ptr; int yy_start_stack_depth; int *yy_start_stack; yy_state_type yy_last_accepting_state; char* yy_last_accepting_cpos; int yylineno_r; int yy_flex_debug_r; char *yytext_r; int yy_more_flag; int yy_more_len; }; /* end struct yyguts_t */ static int yy_init_globals ( yyscan_t yyscanner ); int yylex_init (yyscan_t* scanner); int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy ( yyscan_t yyscanner ); int yyget_debug ( yyscan_t yyscanner ); void yyset_debug ( int debug_flag , yyscan_t yyscanner ); YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner ); void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner ); FILE *yyget_in ( yyscan_t yyscanner ); void yyset_in ( FILE * _in_str , yyscan_t yyscanner ); FILE *yyget_out ( yyscan_t yyscanner ); void yyset_out ( FILE * _out_str , yyscan_t yyscanner ); int yyget_leng ( yyscan_t yyscanner ); char *yyget_text ( yyscan_t yyscanner ); int yyget_lineno ( yyscan_t yyscanner ); void yyset_lineno ( int _line_number , yyscan_t yyscanner ); int yyget_column ( yyscan_t yyscanner ); void yyset_column ( int _column_no , yyscan_t yyscanner ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap ( yyscan_t yyscanner ); #else extern int yywrap ( yyscan_t yyscanner ); #endif #endif #ifndef YY_NO_UNPUT static void yyunput ( int c, char *buf_ptr , yyscan_t yyscanner); #endif #ifndef yytext_ptr static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen ( const char * , yyscan_t yyscanner); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput ( yyscan_t yyscanner ); #else static int input ( yyscan_t yyscanner ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ errno=0; \ while ( (result = (int) read( fileno(yyin), buf, (yy_size_t) max_size )) < 0 ) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex (yyscan_t yyscanner); #define YY_DECL int yylex (yyscan_t yyscanner) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK /*LINTED*/break; #endif #define YY_RULE_SETUP \ if ( yyleng > 0 ) \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ (yytext[yyleng - 1] == '\n'); \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { yy_state_type yy_current_state; char *yy_cp, *yy_bp; int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( !yyg->yy_init ) { yyg->yy_init = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! yyg->yy_start ) yyg->yy_start = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } yy_load_buffer_state( yyscanner ); } { #line 222 "wcsbth.l" #line 224 "wcsbth.l" char *errmsg, errtxt[80], *keyname, strtmp[80]; int inttmp; double dbltmp, dbl2tmp[2]; struct auxprm auxtem; struct wcsprm wcstem; // Initialize returned values. *nreject = 0; *nwcs = 0; *wcs = 0x0; // Our handle on the input stream. char *keyrec = header; char *hptr = header; char *keep = 0x0; // For keeping tallies of keywords found. int nvalid = 0; int nother = 0; // Used to flag image header keywords that are always inherited. int imherit = 1; // If strict, then also reject. if (relax & WCSHDR_strict) relax |= WCSHDR_reject; // Keyword indices, as used in the WCS papers, e.g. iVn_ma, TPn_ka. int i = 0; int j = 0; int k = 0; int n = 0; int m = 0; char a = ' '; // Header bookkeeping. struct wcsbth_alts alts; alts.ncol = 0; alts.arridx = 0x0; alts.pixlist = 0x0; alts.npv = 0x0; alts.nps = 0x0; for (int ialt = 0; ialt < 27; ialt++) { alts.pixidx[ialt] = 0; alts.pixnpv[ialt] = 0; alts.pixnps[ialt] = 0; } // For decoding the keyvalue. int keytype = 0; int valtype = -1; void *vptr = 0x0; // For keywords that require special handling. int altlin = 0; char ptype = ' '; int (*chekval)(double) = 0x0; int (*special)(double *, const double *) = 0x0; struct auxprm *auxp = 0x0; int auxprm = 0; int naux = 0; // Selection by column number. int nsel = colsel ? colsel[0] : 0; int incl = (nsel > 0); char exclude[1000]; for (int icol = 0; icol < 1000; icol++) { exclude[icol] = incl; } for (int icol = 1; icol <= abs(nsel); icol++) { int itmp = colsel[icol]; if (0 < itmp && itmp < 1000) { exclude[itmp] = !incl; } } exclude[0] = 0; // Selection by keyword type. if (keysel) { int itmp = keysel; keysel = 0; if (itmp & WCSHDR_IMGHEAD) keysel |= IMGHEAD; if (itmp & WCSHDR_BIMGARR) keysel |= BIMGARR; if (itmp & WCSHDR_PIXLIST) keysel |= PIXLIST; } if (keysel == 0) { keysel = IMGHEAD | BINTAB; } // Control variables. int ipass = 1; int npass = 2; // User data associated with yyscanner. yyextra->hdr = header; yyextra->nkeyrec = nkeyrec; // Return here via longjmp() invoked by yy_fatal_error(). if (setjmp(yyextra->abort_jmp_env)) { return WCSHDRERR_PARSER; } BEGIN(INITIAL); #line 25969 "wcsbth.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { yy_cp = yyg->yy_c_buf_p; /* Support of yytext. */ *yy_cp = yyg->yy_hold_char; /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = yyg->yy_start; yy_current_state += YY_AT_BOL(); yy_match: while ( (yy_current_state = yy_nxt[yy_current_state][ YY_SC_TO_UI(*yy_cp) ]) > 0 ) { if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } ++yy_cp; } yy_current_state = -yy_current_state; yy_find_action: yy_act = yy_accept[yy_current_state]; YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = yyg->yy_hold_char; yy_cp = yyg->yy_last_accepting_cpos + 1; yy_current_state = yyg->yy_last_accepting_state; goto yy_find_action; case 1: YY_RULE_SETUP #line 329 "wcsbth.l" { if (ipass == 1) { if (alts.ncol == 0) { sscanf(yytext, "TFIELDS = %d", &(alts.ncol)); BEGIN(FLUSH); } else { errmsg = "duplicate or out-of-sequence TFIELDS keyword"; BEGIN(ERROR); } } else { BEGIN(FLUSH); } } YY_BREAK case 2: YY_RULE_SETUP #line 344 "wcsbth.l" { if (!(keysel & IMGAXIS)) { // Ignore this key type. BEGIN(DISCARD); } else { if (relax & WCSHDR_ALLIMG) { sscanf(yytext, "WCSAXES%c= %d", &a, &i); if (i < 0) { errmsg = "negative value of WCSAXESa ignored"; BEGIN(ERROR); } else { valtype = INTEGER; vptr = 0x0; keyname = "WCSAXESa"; keytype = IMGAXIS; BEGIN(COMMENT); } } else if (relax & WCSHDR_reject) { errmsg = "image-header keyword WCSAXESa in binary table"; BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } } YY_BREAK case 3: #line 378 "wcsbth.l" case 4: #line 379 "wcsbth.l" case 5: YY_RULE_SETUP #line 379 "wcsbth.l" { keyname = "WCAXna"; // Note that a blank in the sscanf() format string matches zero or // more of them in the input. sscanf(yytext, "WCAX%d%c = %d", &n, &a, &i); if (!(keysel & BIMGARR) || exclude[n]) { // Ignore this key type or column. BEGIN(DISCARD); } else if (i < 0) { errmsg = "negative value of WCSAXESa ignored"; BEGIN(ERROR); } else { valtype = INTEGER; vptr = 0x0; keyname = "WCAXna"; keytype = IMGAXIS; BEGIN(COMMENT); } } YY_BREAK case 6: /* rule 6 can match eol */ #line 405 "wcsbth.l" case 7: /* rule 7 can match eol */ #line 406 "wcsbth.l" case 8: /* rule 8 can match eol */ YY_RULE_SETUP #line 406 "wcsbth.l" { // Cross-reference supplier. keyname = "WCSTna"; errmsg = "cross-references are not implemented"; BEGIN(ERROR); } YY_BREAK case 9: /* rule 9 can match eol */ #line 414 "wcsbth.l" case 10: /* rule 10 can match eol */ #line 415 "wcsbth.l" case 11: /* rule 11 can match eol */ YY_RULE_SETUP #line 415 "wcsbth.l" { // Cross-reference consumer. keyname = "WCSXna"; errmsg = "cross-references are not implemented"; BEGIN(ERROR); } YY_BREAK case 12: YY_RULE_SETUP #line 422 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.crpix); keyname = "CRPIXja"; BEGIN(CCCCCia); } YY_BREAK case 13: #line 431 "wcsbth.l" case 14: YY_RULE_SETUP #line 431 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.crpix); sscanf(yytext, "%d", &i); if (yyleng == 4) { keyname = "jCRPna"; BEGIN(iCCCna); } else { keyname = "jCRPXn"; BEGIN(iCCCCn); } } YY_BREAK case 15: #line 447 "wcsbth.l" case 16: YY_RULE_SETUP #line 447 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.crpix); if (yyleng == 4) { keyname = "TCRPna"; BEGIN(TCCCna); } else { keyname = "TCRPXn"; BEGIN(TCCCCn); } } YY_BREAK case 17: YY_RULE_SETUP #line 460 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.pc); altlin = 1; keyname = "PCi_ja"; BEGIN(CCi_ja); } YY_BREAK case 18: YY_RULE_SETUP #line 469 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.pc); altlin = 1; sscanf(yytext, "%1d%1d", &i, &j); keyname = "ijPCna"; BEGIN(ijCCna); } YY_BREAK case 19: #line 481 "wcsbth.l" case 20: YY_RULE_SETUP #line 481 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.pc); altlin = 1; if (yyleng == 2) { keyname = "TPn_ka"; BEGIN(TCn_ka); } else { keyname = "TPCn_ka"; BEGIN(TCCn_ka); } } YY_BREAK case 21: YY_RULE_SETUP #line 495 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.cd); altlin = 2; keyname = "CDi_ja"; BEGIN(CCi_ja); } YY_BREAK case 22: YY_RULE_SETUP #line 504 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.cd); altlin = 2; sscanf(yytext, "%1d%1d", &i, &j); keyname = "ijCDna"; BEGIN(ijCCna); } YY_BREAK case 23: #line 516 "wcsbth.l" case 24: YY_RULE_SETUP #line 516 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.cd); altlin = 2; if (yyleng == 2) { keyname = "TCn_ka"; BEGIN(TCn_ka); } else { keyname = "TCDn_ka"; BEGIN(TCCn_ka); } } YY_BREAK case 25: YY_RULE_SETUP #line 530 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.cdelt); keyname = "CDELTia"; BEGIN(CCCCCia); } YY_BREAK case 26: #line 539 "wcsbth.l" case 27: YY_RULE_SETUP #line 539 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.cdelt); sscanf(yytext, "%d", &i); if (yyleng == 4) { keyname = "iCDEna"; BEGIN(iCCCna); } else { keyname = "iCDLTn"; BEGIN(iCCCCn); } } YY_BREAK case 28: #line 555 "wcsbth.l" case 29: YY_RULE_SETUP #line 555 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.cdelt); if (yyleng == 4) { keyname = "TCDEna"; BEGIN(TCCCna); } else { keyname = "TCDLTn"; BEGIN(TCCCCn); } } YY_BREAK case 30: YY_RULE_SETUP #line 568 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.crota); altlin = 4; keyname = "CROTAi"; BEGIN(CROTAi); } YY_BREAK case 31: YY_RULE_SETUP #line 577 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.crota); altlin = 4; sscanf(yytext, "%d", &i); keyname = "iCROTn"; BEGIN(iCROTn); } YY_BREAK case 32: YY_RULE_SETUP #line 588 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.crota); altlin = 4; keyname = "TCROTn"; BEGIN(TCROTn); } YY_BREAK case 33: YY_RULE_SETUP #line 597 "wcsbth.l" { valtype = STRING; vptr = &(wcstem.cunit); keyname = "CUNITia"; BEGIN(CCCCCia); } YY_BREAK case 34: #line 606 "wcsbth.l" case 35: YY_RULE_SETUP #line 606 "wcsbth.l" { valtype = STRING; vptr = &(wcstem.cunit); sscanf(yytext, "%d", &i); if (yyleng == 4) { keyname = "iCUNna"; BEGIN(iCCCna); } else { keyname = "iCUNIn"; BEGIN(iCCCCn); } } YY_BREAK case 36: #line 622 "wcsbth.l" case 37: YY_RULE_SETUP #line 622 "wcsbth.l" { valtype = STRING; vptr = &(wcstem.cunit); if (yyleng == 4) { keyname = "TCUNna"; BEGIN(TCCCna); } else { keyname = "TCUNIn"; BEGIN(TCCCCn); } } YY_BREAK case 38: YY_RULE_SETUP #line 635 "wcsbth.l" { valtype = STRING; vptr = &(wcstem.ctype); keyname = "CTYPEia"; BEGIN(CCCCCia); } YY_BREAK case 39: #line 644 "wcsbth.l" case 40: YY_RULE_SETUP #line 644 "wcsbth.l" { valtype = STRING; vptr = &(wcstem.ctype); sscanf(yytext, "%d", &i); if (yyleng == 4) { keyname = "iCTYna"; BEGIN(iCCCna); } else { keyname = "iCTYPn"; BEGIN(iCCCCn); } } YY_BREAK case 41: #line 660 "wcsbth.l" case 42: YY_RULE_SETUP #line 660 "wcsbth.l" { valtype = STRING; vptr = &(wcstem.ctype); if (yyleng == 4) { keyname = "TCTYna"; BEGIN(TCCCna); } else { keyname = "TCTYPn"; BEGIN(TCCCCn); } } YY_BREAK case 43: YY_RULE_SETUP #line 673 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.crval); keyname = "CRVALia"; BEGIN(CCCCCia); } YY_BREAK case 44: #line 682 "wcsbth.l" case 45: YY_RULE_SETUP #line 682 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.crval); sscanf(yytext, "%d", &i); if (yyleng == 4) { keyname = "iCRVna"; BEGIN(iCCCna); } else { keyname = "iCRVLn"; BEGIN(iCCCCn); } } YY_BREAK case 46: #line 698 "wcsbth.l" case 47: YY_RULE_SETUP #line 698 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.crval); if (yyleng == 4) { keyname = "TCRVna"; BEGIN(TCCCna); } else { keyname = "TCRVLn"; BEGIN(TCCCCn); } } YY_BREAK case 48: #line 712 "wcsbth.l" case 49: YY_RULE_SETUP #line 712 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.lonpole); if (yyleng == 7) { keyname = "LONPOLEa"; imherit = 0; BEGIN(CCCCCCCa); } else { keyname = "LONPna"; BEGIN(CCCCna); } } YY_BREAK case 50: #line 727 "wcsbth.l" case 51: YY_RULE_SETUP #line 727 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.latpole); if (yyleng == 7) { keyname = "LATPOLEa"; imherit = 0; BEGIN(CCCCCCCa); } else { keyname = "LATPna"; BEGIN(CCCCna); } } YY_BREAK case 52: #line 742 "wcsbth.l" case 53: #line 743 "wcsbth.l" case 54: YY_RULE_SETUP #line 743 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.restfrq); if (yyleng == 8) { if (relax & WCSHDR_strict) { errmsg = "the RESTFREQ keyword is deprecated, use RESTFRQa"; BEGIN(ERROR); } else { unput(' '); keyname = "RESTFREQ"; BEGIN(CCCCCCCa); } } else if (yyleng == 7) { keyname = "RESTFRQa"; BEGIN(CCCCCCCa); } else { keyname = "RFRQna"; BEGIN(CCCCna); } } YY_BREAK case 55: #line 770 "wcsbth.l" case 56: YY_RULE_SETUP #line 770 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.restwav); if (yyleng == 7) { keyname = "RESTWAVa"; BEGIN(CCCCCCCa); } else { keyname = "RWAVna"; BEGIN(CCCCna); } } YY_BREAK case 57: YY_RULE_SETUP #line 783 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.pv); ptype = 'v'; keyname = "PVi_ma"; BEGIN(CCi_ma); } YY_BREAK case 58: #line 793 "wcsbth.l" case 59: YY_RULE_SETUP #line 793 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.pv); ptype = 'v'; sscanf(yytext, "%d", &i); if (yyleng == 2) { keyname = "iVn_ma"; BEGIN(iCn_ma); } else { keyname = "iPVn_ma"; BEGIN(iCCn_ma); } } YY_BREAK case 60: #line 810 "wcsbth.l" case 61: YY_RULE_SETUP #line 810 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.pv); ptype = 'v'; if (yyleng == 2) { keyname = "TVn_ma"; BEGIN(TCn_ma); } else { keyname = "TPVn_ma"; BEGIN(TCCn_ma); } } YY_BREAK case 62: YY_RULE_SETUP #line 824 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.pv); ptype = 'v'; keyname = "PROJPm"; BEGIN(PROJPm); } YY_BREAK case 63: YY_RULE_SETUP #line 833 "wcsbth.l" { valtype = STRING; vptr = &(wcstem.ps); ptype = 's'; keyname = "PSi_ma"; BEGIN(CCi_ma); } YY_BREAK case 64: #line 843 "wcsbth.l" case 65: YY_RULE_SETUP #line 843 "wcsbth.l" { valtype = STRING; vptr = &(wcstem.ps); ptype = 's'; sscanf(yytext, "%d", &i); if (yyleng == 2) { keyname = "iSn_ma"; BEGIN(iCn_ma); } else { keyname = "iPSn_ma"; BEGIN(iCCn_ma); } } YY_BREAK case 66: #line 860 "wcsbth.l" case 67: YY_RULE_SETUP #line 860 "wcsbth.l" { valtype = STRING; vptr = &(wcstem.ps); ptype = 's'; if (yyleng == 2) { keyname = "TSn_ma"; BEGIN(TCn_ma); } else { keyname = "TPSn_ma"; BEGIN(TCCn_ma); } } YY_BREAK case 68: YY_RULE_SETUP #line 874 "wcsbth.l" { sscanf(yytext, "VELREF%c", &a); if (relax & WCSHDR_strict) { errmsg = "the VELREF keyword is deprecated, use SPECSYSa"; BEGIN(ERROR); } else if (a == ' ' || (relax & WCSHDR_VELREFa)) { valtype = INTEGER; vptr = &(wcstem.velref); unput(a); keyname = "VELREF"; imherit = 0; BEGIN(CCCCCCCa); } else if (relax & WCSHDR_reject) { errmsg = "VELREF keyword may not have an alternate version code"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 69: YY_RULE_SETUP #line 900 "wcsbth.l" { valtype = STRING; vptr = &(wcstem.cname); keyname = "CNAMEia"; BEGIN(CCCCCia); } YY_BREAK case 70: #line 909 "wcsbth.l" case 71: YY_RULE_SETUP #line 909 "wcsbth.l" { valtype = STRING; vptr = &(wcstem.cname); sscanf(yytext, "%d", &i); if (yyleng == 4) { keyname = "iCNAna"; BEGIN(iCCCna); } else { if (!(relax & WCSHDR_CNAMn)) vptr = 0x0; keyname = "iCNAMn"; BEGIN(iCCCCn); } } YY_BREAK case 72: #line 926 "wcsbth.l" case 73: YY_RULE_SETUP #line 926 "wcsbth.l" { valtype = STRING; vptr = &(wcstem.cname); if (yyleng == 4) { keyname = "TCNAna"; BEGIN(TCCCna); } else { if (!(relax & WCSHDR_CNAMn)) vptr = 0x0; keyname = "TCNAMn"; BEGIN(TCCCCn); } } YY_BREAK case 74: YY_RULE_SETUP #line 940 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.crder); keyname = "CRDERia"; BEGIN(CCCCCia); } YY_BREAK case 75: #line 949 "wcsbth.l" case 76: YY_RULE_SETUP #line 949 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.crder); sscanf(yytext, "%d", &i); if (yyleng == 4) { keyname = "iCRDna"; BEGIN(iCCCna); } else { if (!(relax & WCSHDR_CNAMn)) vptr = 0x0; keyname = "iCRDEn"; BEGIN(iCCCCn); } } YY_BREAK case 77: #line 966 "wcsbth.l" case 78: YY_RULE_SETUP #line 966 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.crder); if (yyleng == 4) { keyname = "TCRDna"; BEGIN(TCCCna); } else { if (!(relax & WCSHDR_CNAMn)) vptr = 0x0; keyname = "TCRDEn"; BEGIN(TCCCCn); } } YY_BREAK case 79: YY_RULE_SETUP #line 980 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.csyer); keyname = "CSYERia"; BEGIN(CCCCCia); } YY_BREAK case 80: #line 989 "wcsbth.l" case 81: YY_RULE_SETUP #line 989 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.csyer); sscanf(yytext, "%d", &i); if (yyleng == 4) { keyname = "iCSYna"; BEGIN(iCCCna); } else { if (!(relax & WCSHDR_CNAMn)) vptr = 0x0; keyname = "iCSYEn"; BEGIN(iCCCCn); } } YY_BREAK case 82: #line 1006 "wcsbth.l" case 83: YY_RULE_SETUP #line 1006 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.csyer); if (yyleng == 4) { keyname = "TCSYna"; BEGIN(TCCCna); } else { if (!(relax & WCSHDR_CNAMn)) vptr = 0x0; keyname = "TCSYEn"; BEGIN(TCCCCn); } } YY_BREAK case 84: YY_RULE_SETUP #line 1020 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.czphs); keyname = "CZPHSia"; BEGIN(CCCCCia); } YY_BREAK case 85: #line 1029 "wcsbth.l" case 86: YY_RULE_SETUP #line 1029 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.czphs); sscanf(yytext, "%d", &i); if (yyleng == 4) { keyname = "iCZPna"; BEGIN(iCCCna); } else { if (!(relax & WCSHDR_CNAMn)) vptr = 0x0; keyname = "iCZPHn"; BEGIN(iCCCCn); } } YY_BREAK case 87: #line 1046 "wcsbth.l" case 88: YY_RULE_SETUP #line 1046 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.czphs); if (yyleng == 4) { keyname = "TCZPna"; BEGIN(TCCCna); } else { if (!(relax & WCSHDR_CNAMn)) vptr = 0x0; keyname = "TCZPHn"; BEGIN(TCCCCn); } } YY_BREAK case 89: YY_RULE_SETUP #line 1060 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.cperi); keyname = "CPERIia"; BEGIN(CCCCCia); } YY_BREAK case 90: #line 1069 "wcsbth.l" case 91: YY_RULE_SETUP #line 1069 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.cperi); sscanf(yytext, "%d", &i); if (yyleng == 4) { keyname = "iCPRna"; BEGIN(iCCCna); } else { if (!(relax & WCSHDR_CNAMn)) vptr = 0x0; keyname = "iCPERn"; BEGIN(iCCCCn); } } YY_BREAK case 92: #line 1086 "wcsbth.l" case 93: YY_RULE_SETUP #line 1086 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.cperi); if (yyleng == 4) { keyname = "TCPRna"; BEGIN(TCCCna); } else { if (!(relax & WCSHDR_CNAMn)) vptr = 0x0; keyname = "TCPERn"; BEGIN(TCCCCn); } } YY_BREAK case 94: #line 1101 "wcsbth.l" case 95: #line 1102 "wcsbth.l" case 96: YY_RULE_SETUP #line 1102 "wcsbth.l" { valtype = STRING; vptr = wcstem.wcsname; if (yyleng == 7) { keyname = "WCSNAMEa"; imherit = 0; BEGIN(CCCCCCCa); } else { if (*yytext == 'W') { keyname = "WCSNna"; } else { keyname = "TWCSna"; } BEGIN(CCCCna); } } YY_BREAK case 97: YY_RULE_SETUP #line 1121 "wcsbth.l" { valtype = STRING; vptr = wcstem.timesys; keyname = "TIMESYS"; BEGIN(CCCCCCCC); } YY_BREAK case 98: #line 1130 "wcsbth.l" case 99: YY_RULE_SETUP #line 1130 "wcsbth.l" { valtype = STRING; vptr = wcstem.trefpos; if (yyleng == 8) { if (ctrl < -10) keep = keyrec; keyname = "TREFPOS"; BEGIN(CCCCCCCC); } else { keyname = "TRPOSn"; BEGIN(CCCCCn); } } YY_BREAK case 100: #line 1145 "wcsbth.l" case 101: YY_RULE_SETUP #line 1145 "wcsbth.l" { valtype = STRING; vptr = wcstem.trefdir; if (yyleng == 8) { if (ctrl < -10) keep = keyrec; keyname = "TREFDIR"; BEGIN(CCCCCCCC); } else { keyname = "TRDIRn"; BEGIN(CCCCCn); } } YY_BREAK case 102: YY_RULE_SETUP #line 1159 "wcsbth.l" { valtype = STRING; vptr = wcstem.plephem; keyname = "PLEPHEM"; BEGIN(CCCCCCCC); } YY_BREAK case 103: YY_RULE_SETUP #line 1167 "wcsbth.l" { valtype = STRING; vptr = wcstem.timeunit; keyname = "TIMEUNIT"; BEGIN(CCCCCCCC); } YY_BREAK case 104: #line 1176 "wcsbth.l" case 105: YY_RULE_SETUP #line 1176 "wcsbth.l" { if ((yytext[4] == 'R') || (relax & WCSHDR_DATEREF)) { valtype = STRING; vptr = wcstem.dateref; keyname = "DATEREF"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the DATE-REF keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 106: #line 1194 "wcsbth.l" case 107: YY_RULE_SETUP #line 1194 "wcsbth.l" { if ((yytext[3] == 'R') || (relax & WCSHDR_DATEREF)) { valtype = FLOAT2; vptr = wcstem.mjdref; keyname = "MJDREF"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the MJD-REF keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 108: #line 1212 "wcsbth.l" case 109: YY_RULE_SETUP #line 1212 "wcsbth.l" { if ((yytext[3] == 'R') || (relax & WCSHDR_DATEREF)) { // Actually integer, but treated as float. valtype = FLOAT; vptr = wcstem.mjdref; keyname = "MJDREFI"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the MJD-REFI keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 110: #line 1231 "wcsbth.l" case 111: YY_RULE_SETUP #line 1231 "wcsbth.l" { if ((yytext[3] == 'R') || (relax & WCSHDR_DATEREF)) { valtype = FLOAT; vptr = wcstem.mjdref + 1; keyname = "MJDREFF"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the MJD-REFF keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 112: #line 1249 "wcsbth.l" case 113: YY_RULE_SETUP #line 1249 "wcsbth.l" { if ((yytext[2] == 'R') || (relax & WCSHDR_DATEREF)) { valtype = FLOAT2; vptr = wcstem.mjdref; special = wcsbth_jdref; keyname = "JDREF"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the JD-REF keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 114: #line 1268 "wcsbth.l" case 115: YY_RULE_SETUP #line 1268 "wcsbth.l" { if ((yytext[2] == 'R') || (relax & WCSHDR_DATEREF)) { // Actually integer, but treated as float. valtype = FLOAT; vptr = wcstem.mjdref; special = wcsbth_jdrefi; keyname = "JDREFI"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the JD-REFI keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 116: #line 1288 "wcsbth.l" case 117: YY_RULE_SETUP #line 1288 "wcsbth.l" { if ((yytext[2] == 'R') || (relax & WCSHDR_DATEREF)) { valtype = FLOAT; vptr = wcstem.mjdref; special = wcsbth_jdreff; keyname = "JDREFF"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the JD-REFF keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 118: YY_RULE_SETUP #line 1306 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.timeoffs); keyname = "TIMEOFFS"; BEGIN(CCCCCCCC); } YY_BREAK case 119: YY_RULE_SETUP #line 1314 "wcsbth.l" { valtype = STRING; vptr = wcstem.dateobs; if (ctrl < -10) keep = keyrec; keyname = "DATE-OBS"; imherit = 0; BEGIN(CCCCCCCC); } YY_BREAK case 120: #line 1325 "wcsbth.l" case 121: #line 1326 "wcsbth.l" case 122: YY_RULE_SETUP #line 1326 "wcsbth.l" { valtype = STRING; vptr = wcstem.dateobs; if (relax & WCSHDR_DOBSn) { yyless(4); keyname = "DOBSn"; BEGIN(CCCCn); } else if (relax & WCSHDR_reject) { errmsg = "DOBSn keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 123: YY_RULE_SETUP #line 1345 "wcsbth.l" { valtype = STRING; vptr = wcstem.datebeg; if (ctrl < -10) keep = keyrec; keyname = "DATE-BEG"; BEGIN(CCCCCCCC); } YY_BREAK case 124: #line 1355 "wcsbth.l" case 125: YY_RULE_SETUP #line 1355 "wcsbth.l" { valtype = STRING; vptr = wcstem.dateavg; if (yyleng == 8) { if (ctrl < -10) keep = keyrec; keyname = "DATE-AVG"; BEGIN(CCCCCCCC); } else { keyname = "DAVGn"; BEGIN(CCCCn); } } YY_BREAK case 126: YY_RULE_SETUP #line 1369 "wcsbth.l" { valtype = STRING; vptr = wcstem.dateend; if (ctrl < -10) keep = keyrec; keyname = "DATE-END"; BEGIN(CCCCCCCC); } YY_BREAK case 127: #line 1379 "wcsbth.l" case 128: YY_RULE_SETUP #line 1379 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.mjdobs); if (yyleng == 8) { if (ctrl < -10) keep = keyrec; keyname = "MJD-OBS"; imherit = 0; BEGIN(CCCCCCCC); } else { keyname = "MJDOBn"; BEGIN(CCCCCn); } } YY_BREAK case 129: YY_RULE_SETUP #line 1394 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.mjdbeg); if (ctrl < -10) keep = keyrec; keyname = "MJD-BEG"; BEGIN(CCCCCCCC); } YY_BREAK case 130: #line 1404 "wcsbth.l" case 131: YY_RULE_SETUP #line 1404 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.mjdavg); if (yyleng == 8) { if (ctrl < -10) keep = keyrec; keyname = "MJD-AVG"; BEGIN(CCCCCCCC); } else { keyname = "MJDAn"; BEGIN(CCCCn); } } YY_BREAK case 132: YY_RULE_SETUP #line 1418 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.mjdend); if (ctrl < -10) keep = keyrec; keyname = "MJD-END"; BEGIN(CCCCCCCC); } YY_BREAK case 133: YY_RULE_SETUP #line 1427 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.jepoch); if (ctrl < -10) keep = keyrec; keyname = "JEPOCH"; BEGIN(CCCCCCCC); } YY_BREAK case 134: YY_RULE_SETUP #line 1436 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.bepoch); if (ctrl < -10) keep = keyrec; keyname = "BEPOCH"; BEGIN(CCCCCCCC); } YY_BREAK case 135: YY_RULE_SETUP #line 1445 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.tstart); if (ctrl < -10) keep = keyrec; keyname = "TSTART"; BEGIN(CCCCCCCC); } YY_BREAK case 136: YY_RULE_SETUP #line 1454 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.tstop); if (ctrl < -10) keep = keyrec; keyname = "TSTOP"; BEGIN(CCCCCCCC); } YY_BREAK case 137: YY_RULE_SETUP #line 1463 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.xposure); if (ctrl < -10) keep = keyrec; keyname = "XPOSURE"; BEGIN(CCCCCCCC); } YY_BREAK case 138: YY_RULE_SETUP #line 1472 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.telapse); if (ctrl < -10) keep = keyrec; keyname = "TELAPSE"; BEGIN(CCCCCCCC); } YY_BREAK case 139: YY_RULE_SETUP #line 1481 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.timsyer); if (ctrl < -10) keep = keyrec; keyname = "TIMSYER"; BEGIN(CCCCCCCC); } YY_BREAK case 140: YY_RULE_SETUP #line 1490 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.timrder); if (ctrl < -10) keep = keyrec; keyname = "TIMRDER"; BEGIN(CCCCCCCC); } YY_BREAK case 141: YY_RULE_SETUP #line 1499 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.timedel); if (ctrl < -10) keep = keyrec; keyname = "TIMEDEL"; BEGIN(CCCCCCCC); } YY_BREAK case 142: YY_RULE_SETUP #line 1508 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.timepixr); chekval = wcsbth_timepixr; if (ctrl < -10) keep = keyrec; keyname = "TIMEPIXR"; BEGIN(CCCCCCCC); } YY_BREAK case 143: #line 1519 "wcsbth.l" case 144: YY_RULE_SETUP #line 1519 "wcsbth.l" { valtype = FLOAT; vptr = wcstem.obsgeo; if (yyleng == 8) { if (ctrl < -10) keep = keyrec; keyname = "OBSGEO-X"; BEGIN(CCCCCCCC); } else { keyname = "OBSGXn"; BEGIN(CCCCCn); } } YY_BREAK case 145: #line 1534 "wcsbth.l" case 146: YY_RULE_SETUP #line 1534 "wcsbth.l" { valtype = FLOAT; vptr = wcstem.obsgeo + 1; if (yyleng == 8) { if (ctrl < -10) keep = keyrec; keyname = "OBSGEO-Y"; BEGIN(CCCCCCCC); } else { keyname = "OBSGYn"; BEGIN(CCCCCn); } } YY_BREAK case 147: #line 1549 "wcsbth.l" case 148: YY_RULE_SETUP #line 1549 "wcsbth.l" { valtype = FLOAT; vptr = wcstem.obsgeo + 2; if (yyleng == 8) { if (ctrl < -10) keep = keyrec; keyname = "OBSGEO-Z"; BEGIN(CCCCCCCC); } else { keyname = "OBSGZn"; BEGIN(CCCCCn); } } YY_BREAK case 149: YY_RULE_SETUP #line 1563 "wcsbth.l" { valtype = FLOAT; vptr = wcstem.obsgeo + 3; if (ctrl < -10) keep = keyrec; keyname = "OBSGEO-L"; BEGIN(CCCCCCCC); } YY_BREAK case 150: #line 1573 "wcsbth.l" case 151: #line 1574 "wcsbth.l" case 152: YY_RULE_SETUP #line 1574 "wcsbth.l" { valtype = STRING; vptr = wcstem.obsgeo + 3; if (relax & WCSHDR_OBSGLBHn) { yyless(5); keyname = "OBSGLn"; BEGIN(CCCCCn); } else if (relax & WCSHDR_reject) { errmsg = "OBSGLn keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 153: YY_RULE_SETUP #line 1593 "wcsbth.l" { valtype = FLOAT; vptr = wcstem.obsgeo + 4; if (ctrl < -10) keep = keyrec; keyname = "OBSGEO-B"; BEGIN(CCCCCCCC); } YY_BREAK case 154: #line 1603 "wcsbth.l" case 155: #line 1604 "wcsbth.l" case 156: YY_RULE_SETUP #line 1604 "wcsbth.l" { valtype = STRING; vptr = wcstem.obsgeo + 3; if (relax & WCSHDR_OBSGLBHn) { yyless(5); keyname = "OBSGBn"; BEGIN(CCCCCn); } else if (relax & WCSHDR_reject) { errmsg = "OBSGBn keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 157: YY_RULE_SETUP #line 1623 "wcsbth.l" { valtype = FLOAT; vptr = wcstem.obsgeo + 5; if (ctrl < -10) keep = keyrec; keyname = "OBSGEO-H"; BEGIN(CCCCCCCC); } YY_BREAK case 158: #line 1633 "wcsbth.l" case 159: #line 1634 "wcsbth.l" case 160: YY_RULE_SETUP #line 1634 "wcsbth.l" { valtype = STRING; vptr = wcstem.obsgeo + 3; if (relax & WCSHDR_OBSGLBHn) { yyless(5); keyname = "OBSGHn"; BEGIN(CCCCCn); } else if (relax & WCSHDR_reject) { errmsg = "OBSGHn keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 161: YY_RULE_SETUP #line 1653 "wcsbth.l" { valtype = STRING; vptr = wcstem.obsorbit; keyname = "OBSORBIT"; BEGIN(CCCCCCCC); } YY_BREAK case 162: #line 1662 "wcsbth.l" case 163: YY_RULE_SETUP #line 1662 "wcsbth.l" { valtype = STRING; vptr = wcstem.radesys; if (yyleng == 7) { keyname = "RADESYSa"; imherit = 0; BEGIN(CCCCCCCa); } else { keyname = "RADEna"; BEGIN(CCCCna); } } YY_BREAK case 164: YY_RULE_SETUP #line 1676 "wcsbth.l" { if (relax & WCSHDR_RADECSYS) { valtype = STRING; vptr = wcstem.radesys; unput(' '); keyname = "RADECSYS"; imherit = 0; BEGIN(CCCCCCCa); } else if (relax & WCSHDR_reject) { errmsg = "the RADECSYS keyword is deprecated, use RADESYSa"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 165: YY_RULE_SETUP #line 1696 "wcsbth.l" { sscanf(yytext, "EPOCH%c", &a); if (relax & WCSHDR_strict) { errmsg = "the EPOCH keyword is deprecated, use EQUINOXa"; BEGIN(ERROR); } else if (a == ' ' || (relax & WCSHDR_EPOCHa)) { valtype = FLOAT; vptr = &(wcstem.equinox); special = wcsbth_epoch; unput(a); keyname = "EPOCH"; imherit = 0; BEGIN(CCCCCCCa); } else if (relax & WCSHDR_reject) { errmsg = "EPOCH keyword may not have an alternate version code"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 166: #line 1724 "wcsbth.l" case 167: YY_RULE_SETUP #line 1724 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.equinox); if (yyleng == 7) { keyname = "EQUINOXa"; imherit = 0; BEGIN(CCCCCCCa); } else { keyname = "EQUIna"; BEGIN(CCCCna); } } YY_BREAK case 168: #line 1739 "wcsbth.l" case 169: YY_RULE_SETUP #line 1739 "wcsbth.l" { valtype = STRING; vptr = wcstem.specsys; if (yyleng == 7) { keyname = "SPECSYSa"; BEGIN(CCCCCCCa); } else { keyname = "SPECna"; BEGIN(CCCCna); } } YY_BREAK case 170: #line 1753 "wcsbth.l" case 171: YY_RULE_SETUP #line 1753 "wcsbth.l" { valtype = STRING; vptr = wcstem.ssysobs; if (yyleng == 7) { keyname = "SSYSOBSa"; BEGIN(CCCCCCCa); } else { keyname = "SOBSna"; BEGIN(CCCCna); } } YY_BREAK case 172: #line 1767 "wcsbth.l" case 173: YY_RULE_SETUP #line 1767 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.velosys); if (yyleng == 7) { keyname = "VELOSYSa"; BEGIN(CCCCCCCa); } else { keyname = "VSYSna"; BEGIN(CCCCna); } } YY_BREAK case 174: YY_RULE_SETUP #line 1780 "wcsbth.l" { if (relax & WCSHDR_VSOURCE) { valtype = FLOAT; vptr = &(wcstem.zsource); special = wcsbth_vsource; yyless(7); keyname = "VSOURCEa"; BEGIN(CCCCCCCa); } else if (relax & WCSHDR_reject) { errmsg = "the VSOURCEa keyword is deprecated, use ZSOURCEa"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 175: #line 1801 "wcsbth.l" case 176: #line 1802 "wcsbth.l" case 177: YY_RULE_SETUP #line 1802 "wcsbth.l" { if (relax & WCSHDR_VSOURCE) { valtype = FLOAT; vptr = &(wcstem.zsource); special = wcsbth_vsource; yyless(4); keyname = "VSOUna"; BEGIN(CCCCna); } else if (relax & WCSHDR_reject) { errmsg = "VSOUna keyword is deprecated, use ZSOUna"; BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 178: #line 1823 "wcsbth.l" case 179: YY_RULE_SETUP #line 1823 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.zsource); if (yyleng == 7) { keyname = "ZSOURCEa"; BEGIN(CCCCCCCa); } else { keyname = "ZSOUna"; BEGIN(CCCCna); } } YY_BREAK case 180: #line 1837 "wcsbth.l" case 181: YY_RULE_SETUP #line 1837 "wcsbth.l" { valtype = STRING; vptr = wcstem.ssyssrc; if (yyleng == 7) { keyname = "SSYSSRCa"; BEGIN(CCCCCCCa); } else { keyname = "SSRCna"; BEGIN(CCCCna); } } YY_BREAK case 182: #line 1851 "wcsbth.l" case 183: YY_RULE_SETUP #line 1851 "wcsbth.l" { valtype = FLOAT; vptr = &(wcstem.velangl); if (yyleng == 7) { keyname = "VELANGLa"; BEGIN(CCCCCCCa); } else { keyname = "VANGna"; BEGIN(CCCCna); } } YY_BREAK case 184: YY_RULE_SETUP #line 1864 "wcsbth.l" { valtype = FLOAT; auxprm = 1; vptr = &(auxtem.rsun_ref); keyname = "RSUN_REF"; BEGIN(CCCCCCCC); } YY_BREAK case 185: YY_RULE_SETUP #line 1873 "wcsbth.l" { valtype = FLOAT; auxprm = 1; vptr = &(auxtem.dsun_obs); keyname = "DSUN_OBS"; BEGIN(CCCCCCCC); } YY_BREAK case 186: YY_RULE_SETUP #line 1882 "wcsbth.l" { valtype = FLOAT; auxprm = 1; vptr = &(auxtem.crln_obs); keyname = "CRLN_OBS"; BEGIN(CCCCCCCC); } YY_BREAK case 187: YY_RULE_SETUP #line 1891 "wcsbth.l" { valtype = FLOAT; auxprm = 1; vptr = &(auxtem.hgln_obs); keyname = "HGLN_OBS"; BEGIN(CCCCCCCC); } YY_BREAK case 188: #line 1901 "wcsbth.l" case 189: YY_RULE_SETUP #line 1901 "wcsbth.l" { valtype = FLOAT; auxprm = 1; vptr = &(auxtem.hglt_obs); keyname = "HGLT_OBS"; BEGIN(CCCCCCCC); } YY_BREAK case 190: YY_RULE_SETUP #line 1910 "wcsbth.l" { if (yyextra->nkeyrec) { yyextra->nkeyrec = 0; errmsg = "keyrecords following the END keyrecord were ignored"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 191: YY_RULE_SETUP #line 1920 "wcsbth.l" { BEGIN(DISCARD); } YY_BREAK case 192: #line 1925 "wcsbth.l" case 193: YY_RULE_SETUP #line 1925 "wcsbth.l" { if (relax & WCSHDR_ALLIMG) { sscanf(yytext, "%d%c", &i, &a); keytype = IMGAXIS; BEGIN(VALUE); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 194: #line 1944 "wcsbth.l" case 195: YY_RULE_SETUP #line 1944 "wcsbth.l" { if (relax & WCSHDR_ALLIMG) { if (relax & WCSHDR_reject) { // Violates the basic FITS standard. errmsg = "indices in parameterized keywords must not have " "leading zeroes"; BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "invalid image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 196: #line 1970 "wcsbth.l" case 197: #line 1971 "wcsbth.l" case 198: YY_RULE_SETUP #line 1971 "wcsbth.l" { // Anything that has fallen through to this point must contain // an invalid axis number. if (relax & WCSHDR_ALLIMG) { errmsg = "axis number must exceed 0"; BEGIN(ERROR); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "invalid image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 199: YY_RULE_SETUP #line 1990 "wcsbth.l" { if (relax & WCSHDR_reject) { // Looks too much like a FITS WCS keyword not to flag it. errmsg = errtxt; sprintf(errmsg, "keyword looks very much like %s but isn't", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 200: #line 2005 "wcsbth.l" case 201: #line 2006 "wcsbth.l" case 202: #line 2007 "wcsbth.l" case 203: #line 2008 "wcsbth.l" case 204: #line 2009 "wcsbth.l" case 205: YY_RULE_SETUP #line 2009 "wcsbth.l" { if (vptr) { WCSBTH_PUTBACK; BEGIN((YY_START == iCCCCn) ? iCCCna : TCCCna); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "%s keyword is non-standard", keyname); BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 206: #line 2025 "wcsbth.l" case 207: #line 2026 "wcsbth.l" case 208: #line 2027 "wcsbth.l" case 209: YY_RULE_SETUP #line 2027 "wcsbth.l" { if (vptr && (relax & WCSHDR_LONGKEY)) { WCSBTH_PUTBACK; BEGIN((YY_START == iCCCCn) ? iCCCna : TCCCna); } else if (relax & WCSHDR_reject) { errmsg = errtxt; if (!vptr) { sprintf(errmsg, "%s keyword is non-standard", keyname); } else { sprintf(errmsg, "%s keyword may not have an alternate version code", keyname); } BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 210: #line 2049 "wcsbth.l" case 211: YY_RULE_SETUP #line 2049 "wcsbth.l" { BEGIN(DISCARD); } YY_BREAK case 212: #line 2054 "wcsbth.l" case 213: #line 2055 "wcsbth.l" case 214: #line 2056 "wcsbth.l" case 215: #line 2057 "wcsbth.l" case 216: #line 2058 "wcsbth.l" case 217: YY_RULE_SETUP #line 2058 "wcsbth.l" { sscanf(yytext, "%d%c", &n, &a); if (YY_START == TCCCna) i = wcsbth_colax(*wcs, &alts, n, a); keytype = (YY_START == iCCCna) ? BIMGARR : PIXLIST; BEGIN(VALUE); } YY_BREAK case 218: #line 2066 "wcsbth.l" case 219: YY_RULE_SETUP #line 2066 "wcsbth.l" { BEGIN(DISCARD); } YY_BREAK case 220: #line 2071 "wcsbth.l" case 221: #line 2072 "wcsbth.l" case 222: #line 2073 "wcsbth.l" case 223: YY_RULE_SETUP #line 2073 "wcsbth.l" { if (relax & WCSHDR_ALLIMG) { sscanf(yytext, "%d_%d%c", &i, &j, &a); keytype = IMGAXIS; BEGIN(VALUE); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 224: #line 2092 "wcsbth.l" case 225: #line 2093 "wcsbth.l" case 226: #line 2094 "wcsbth.l" case 227: #line 2095 "wcsbth.l" case 228: #line 2096 "wcsbth.l" case 229: #line 2097 "wcsbth.l" case 230: #line 2098 "wcsbth.l" case 231: #line 2099 "wcsbth.l" case 232: #line 2100 "wcsbth.l" case 233: #line 2101 "wcsbth.l" case 234: #line 2102 "wcsbth.l" case 235: #line 2103 "wcsbth.l" case 236: #line 2104 "wcsbth.l" case 237: #line 2105 "wcsbth.l" case 238: #line 2106 "wcsbth.l" case 239: #line 2107 "wcsbth.l" case 240: #line 2108 "wcsbth.l" case 241: #line 2109 "wcsbth.l" case 242: #line 2110 "wcsbth.l" case 243: #line 2111 "wcsbth.l" case 244: YY_RULE_SETUP #line 2111 "wcsbth.l" { if (relax & WCSHDR_ALLIMG) { if (((altlin == 1) && (relax & WCSHDR_PC0i_0ja)) || ((altlin == 2) && (relax & WCSHDR_CD0i_0ja))) { sscanf(yytext, "%d_%d%c", &i, &j, &a); keytype = IMGAXIS; BEGIN(VALUE); } else if (relax & WCSHDR_reject) { errmsg = "indices in parameterized keywords must not have " "leading zeroes"; BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "invalid image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 245: #line 2142 "wcsbth.l" case 246: #line 2143 "wcsbth.l" case 247: #line 2144 "wcsbth.l" case 248: #line 2145 "wcsbth.l" case 249: #line 2146 "wcsbth.l" case 250: #line 2147 "wcsbth.l" case 251: #line 2148 "wcsbth.l" case 252: #line 2149 "wcsbth.l" case 253: #line 2150 "wcsbth.l" case 254: YY_RULE_SETUP #line 2150 "wcsbth.l" { // Anything that has fallen through to this point must contain // an invalid axis number. if (relax & WCSHDR_ALLIMG) { errmsg = "axis number must exceed 0"; BEGIN(ERROR); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "invalid image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 255: #line 2170 "wcsbth.l" case 256: #line 2171 "wcsbth.l" case 257: #line 2172 "wcsbth.l" case 258: #line 2173 "wcsbth.l" case 259: #line 2174 "wcsbth.l" case 260: #line 2175 "wcsbth.l" case 261: #line 2176 "wcsbth.l" case 262: #line 2177 "wcsbth.l" case 263: #line 2178 "wcsbth.l" case 264: YY_RULE_SETUP #line 2178 "wcsbth.l" { if (relax & WCSHDR_ALLIMG) { errmsg = errtxt; sprintf(errmsg, "%s keyword must use an underscore, not a dash", keyname); BEGIN(ERROR); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "invalid image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 265: YY_RULE_SETUP #line 2197 "wcsbth.l" { // This covers the defunct forms CD00i00j and PC00i00j. if (relax & WCSHDR_ALLIMG) { if (((altlin == 1) && (relax & WCSHDR_PC00i00j)) || ((altlin == 2) && (relax & WCSHDR_CD00i00j))) { sscanf(yytext, "%3d%3d", &i, &j); a = ' '; keytype = IMGAXIS; BEGIN(VALUE); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "this form of the %s keyword is deprecated, use %s", keyname, keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "deprecated image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 266: YY_RULE_SETUP #line 2231 "wcsbth.l" { BEGIN(DISCARD); } YY_BREAK case 267: #line 2236 "wcsbth.l" case 268: #line 2237 "wcsbth.l" case 269: YY_RULE_SETUP #line 2237 "wcsbth.l" { sscanf(yytext, "%d%c", &n, &a); keytype = BIMGARR; BEGIN(VALUE); } YY_BREAK case 270: #line 2244 "wcsbth.l" case 271: #line 2245 "wcsbth.l" case 272: #line 2246 "wcsbth.l" case 273: #line 2247 "wcsbth.l" case 274: #line 2248 "wcsbth.l" case 275: YY_RULE_SETUP #line 2248 "wcsbth.l" { if (relax & WCSHDR_LONGKEY) { WCSBTH_PUTBACK; BEGIN(TCn_ka); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "%s keyword is non-standard", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 276: YY_RULE_SETUP #line 2264 "wcsbth.l" { BEGIN(DISCARD); } YY_BREAK case 277: #line 2269 "wcsbth.l" case 278: #line 2270 "wcsbth.l" case 279: #line 2271 "wcsbth.l" case 280: #line 2272 "wcsbth.l" case 281: #line 2273 "wcsbth.l" case 282: YY_RULE_SETUP #line 2273 "wcsbth.l" { sscanf(yytext, "%d_%d%c", &n, &k, &a); i = wcsbth_colax(*wcs, &alts, n, a); j = wcsbth_colax(*wcs, &alts, k, a); keytype = PIXLIST; BEGIN(VALUE); } YY_BREAK case 283: #line 2282 "wcsbth.l" case 284: #line 2283 "wcsbth.l" case 285: #line 2284 "wcsbth.l" case 286: YY_RULE_SETUP #line 2284 "wcsbth.l" { sscanf(yytext, "%d_%d", &n, &k); a = ' '; i = wcsbth_colax(*wcs, &alts, n, a); j = wcsbth_colax(*wcs, &alts, k, a); keytype = PIXLIST; BEGIN(VALUE); } YY_BREAK case 287: YY_RULE_SETUP #line 2293 "wcsbth.l" { BEGIN(DISCARD); } YY_BREAK case 288: #line 2298 "wcsbth.l" case 289: #line 2299 "wcsbth.l" case 290: YY_RULE_SETUP #line 2299 "wcsbth.l" { if (relax & WCSHDR_ALLIMG) { a = ' '; sscanf(yytext, "%d%c", &i, &a); if (relax & WCSHDR_strict) { errmsg = "the CROTAn keyword is deprecated, use PCi_ja"; BEGIN(ERROR); } else if (a == ' ' || relax & WCSHDR_CROTAia) { yyless(0); BEGIN(CCCCCia); } else if (relax & WCSHDR_reject) { errmsg = "CROTAn keyword may not have an alternate version code"; BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "deprecated image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 291: YY_RULE_SETUP #line 2333 "wcsbth.l" { if (relax & WCSHDR_ALLIMG) { yyless(0); BEGIN(CCCCCia); } else { // Let it go. BEGIN(DISCARD); } } YY_BREAK case 292: #line 2344 "wcsbth.l" case 293: #line 2345 "wcsbth.l" case 294: #line 2346 "wcsbth.l" case 295: #line 2347 "wcsbth.l" case 296: #line 2348 "wcsbth.l" case 297: YY_RULE_SETUP #line 2348 "wcsbth.l" { WCSBTH_PUTBACK; BEGIN((YY_START == iCROTn) ? iCCCna : TCCCna); } YY_BREAK case 298: #line 2354 "wcsbth.l" case 299: #line 2355 "wcsbth.l" case 300: #line 2356 "wcsbth.l" case 301: YY_RULE_SETUP #line 2356 "wcsbth.l" { if (relax & WCSHDR_CROTAia) { WCSBTH_PUTBACK; BEGIN((YY_START == iCROTn) ? iCCCna : TCCCna); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "%s keyword may not have an alternate version code", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 302: #line 2374 "wcsbth.l" case 303: YY_RULE_SETUP #line 2374 "wcsbth.l" { BEGIN(DISCARD); } YY_BREAK case 304: #line 2379 "wcsbth.l" case 305: YY_RULE_SETUP #line 2379 "wcsbth.l" { // Image-header keyword. if (imherit || (relax & (WCSHDR_AUXIMG | WCSHDR_ALLIMG))) { if (YY_START == CCCCCCCa) { sscanf(yytext, "%c", &a); } else { a = 0; unput(yytext[0]); } keytype = IMGAUX; BEGIN(VALUE); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 306: YY_RULE_SETUP #line 2403 "wcsbth.l" { if (relax & WCSHDR_reject) { // Looks too much like a FITS WCS keyword not to flag it. errmsg = errtxt; sprintf(errmsg, "invalid alternate code, keyword resembles %s " "but isn't", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 307: #line 2418 "wcsbth.l" case 308: #line 2419 "wcsbth.l" case 309: #line 2420 "wcsbth.l" case 310: #line 2421 "wcsbth.l" case 311: YY_RULE_SETUP #line 2421 "wcsbth.l" { sscanf(yytext, "%d%c", &n, &a); keytype = BINTAB; BEGIN(VALUE); } YY_BREAK case 312: YY_RULE_SETUP #line 2427 "wcsbth.l" { sscanf(yytext, "%d", &n); a = ' '; keytype = BINTAB; BEGIN(VALUE); } YY_BREAK case 313: #line 2435 "wcsbth.l" case 314: YY_RULE_SETUP #line 2435 "wcsbth.l" { BEGIN(DISCARD); } YY_BREAK case 315: #line 2440 "wcsbth.l" case 316: #line 2441 "wcsbth.l" case 317: #line 2442 "wcsbth.l" case 318: #line 2443 "wcsbth.l" case 319: #line 2444 "wcsbth.l" case 320: #line 2445 "wcsbth.l" case 321: YY_RULE_SETUP #line 2445 "wcsbth.l" { sscanf(yytext, "%d", &n); a = 0; keytype = BINTAB; BEGIN(VALUE); } YY_BREAK case 322: #line 2453 "wcsbth.l" case 323: YY_RULE_SETUP #line 2453 "wcsbth.l" { BEGIN(DISCARD); } YY_BREAK case 324: #line 2458 "wcsbth.l" case 325: #line 2459 "wcsbth.l" case 326: #line 2460 "wcsbth.l" case 327: YY_RULE_SETUP #line 2460 "wcsbth.l" { // Image-header keyword. if (relax & WCSHDR_ALLIMG) { sscanf(yytext, "%d_%d%c", &i, &m, &a); keytype = IMGAXIS; BEGIN(VALUE); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 328: #line 2480 "wcsbth.l" case 329: #line 2481 "wcsbth.l" case 330: #line 2482 "wcsbth.l" case 331: #line 2483 "wcsbth.l" case 332: #line 2484 "wcsbth.l" case 333: #line 2485 "wcsbth.l" case 334: #line 2486 "wcsbth.l" case 335: #line 2487 "wcsbth.l" case 336: #line 2488 "wcsbth.l" case 337: #line 2489 "wcsbth.l" case 338: #line 2490 "wcsbth.l" case 339: #line 2491 "wcsbth.l" case 340: #line 2492 "wcsbth.l" case 341: #line 2493 "wcsbth.l" case 342: #line 2494 "wcsbth.l" case 343: #line 2495 "wcsbth.l" case 344: #line 2496 "wcsbth.l" case 345: #line 2497 "wcsbth.l" case 346: #line 2498 "wcsbth.l" case 347: #line 2499 "wcsbth.l" case 348: YY_RULE_SETUP #line 2499 "wcsbth.l" { if (relax & WCSHDR_ALLIMG) { if (((valtype == FLOAT) && (relax & WCSHDR_PV0i_0ma)) || ((valtype == STRING) && (relax & WCSHDR_PS0i_0ma))) { sscanf(yytext, "%d_%d%c", &i, &m, &a); keytype = IMGAXIS; BEGIN(VALUE); } else if (relax & WCSHDR_reject) { errmsg = "indices in parameterized keywords must not have " "leading zeroes"; BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "invalid image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 349: #line 2530 "wcsbth.l" case 350: #line 2531 "wcsbth.l" case 351: #line 2532 "wcsbth.l" case 352: #line 2533 "wcsbth.l" case 353: #line 2534 "wcsbth.l" case 354: #line 2535 "wcsbth.l" case 355: #line 2536 "wcsbth.l" case 356: #line 2537 "wcsbth.l" case 357: #line 2538 "wcsbth.l" case 358: YY_RULE_SETUP #line 2538 "wcsbth.l" { if (relax & WCSHDR_ALLIMG) { // Anything that has fallen through to this point must contain // an invalid parameter. errmsg = "axis number must exceed 0"; BEGIN(ERROR); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "invalid image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 359: #line 2558 "wcsbth.l" case 360: #line 2559 "wcsbth.l" case 361: #line 2560 "wcsbth.l" case 362: #line 2561 "wcsbth.l" case 363: #line 2562 "wcsbth.l" case 364: #line 2563 "wcsbth.l" case 365: #line 2564 "wcsbth.l" case 366: #line 2565 "wcsbth.l" case 367: #line 2566 "wcsbth.l" case 368: YY_RULE_SETUP #line 2566 "wcsbth.l" { errmsg = errtxt; sprintf(errmsg, "%s keyword must use an underscore, not a dash", keyname); BEGIN(ERROR); } YY_BREAK case 369: YY_RULE_SETUP #line 2573 "wcsbth.l" { BEGIN(DISCARD); } YY_BREAK case 370: #line 2578 "wcsbth.l" case 371: #line 2579 "wcsbth.l" case 372: #line 2580 "wcsbth.l" case 373: #line 2581 "wcsbth.l" case 374: #line 2582 "wcsbth.l" case 375: #line 2583 "wcsbth.l" case 376: #line 2584 "wcsbth.l" case 377: #line 2585 "wcsbth.l" case 378: #line 2586 "wcsbth.l" case 379: #line 2587 "wcsbth.l" case 380: #line 2588 "wcsbth.l" case 381: YY_RULE_SETUP #line 2588 "wcsbth.l" { if (relax & WCSHDR_LONGKEY) { WCSBTH_PUTBACK; BEGIN((YY_START == iCCn_ma) ? iCn_ma : TCn_ma); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "the %s keyword is non-standard", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 382: #line 2605 "wcsbth.l" case 383: YY_RULE_SETUP #line 2605 "wcsbth.l" { BEGIN(DISCARD); } YY_BREAK case 384: #line 2610 "wcsbth.l" case 385: #line 2611 "wcsbth.l" case 386: #line 2612 "wcsbth.l" case 387: #line 2613 "wcsbth.l" case 388: #line 2614 "wcsbth.l" case 389: #line 2615 "wcsbth.l" case 390: #line 2616 "wcsbth.l" case 391: #line 2617 "wcsbth.l" case 392: #line 2618 "wcsbth.l" case 393: #line 2619 "wcsbth.l" case 394: #line 2620 "wcsbth.l" case 395: YY_RULE_SETUP #line 2620 "wcsbth.l" { sscanf(yytext, "%d_%d%c", &n, &m, &a); if (YY_START == TCn_ma) i = wcsbth_colax(*wcs, &alts, n, a); keytype = (YY_START == iCn_ma) ? BIMGARR : PIXLIST; BEGIN(VALUE); } YY_BREAK case 396: #line 2628 "wcsbth.l" case 397: #line 2629 "wcsbth.l" case 398: #line 2630 "wcsbth.l" case 399: #line 2631 "wcsbth.l" case 400: #line 2632 "wcsbth.l" case 401: #line 2633 "wcsbth.l" case 402: #line 2634 "wcsbth.l" case 403: YY_RULE_SETUP #line 2634 "wcsbth.l" { // Invalid combinations will be flagged by . sscanf(yytext, "%d_%d", &n, &m); a = ' '; if (YY_START == TCn_ma) i = wcsbth_colax(*wcs, &alts, n, a); keytype = (YY_START == iCn_ma) ? BIMGARR : PIXLIST; BEGIN(VALUE); } YY_BREAK case 404: #line 2644 "wcsbth.l" case 405: YY_RULE_SETUP #line 2644 "wcsbth.l" { BEGIN(DISCARD); } YY_BREAK case 406: YY_RULE_SETUP #line 2648 "wcsbth.l" { if (relax & WCSHDR_PROJPn) { sscanf(yytext, "%d", &m); i = 0; a = ' '; keytype = IMGAXIS; BEGIN(VALUE); } else if (relax & WCSHDR_reject) { errmsg = "the PROJPn keyword is deprecated, use PVi_ma"; BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 407: #line 2667 "wcsbth.l" case 408: YY_RULE_SETUP #line 2667 "wcsbth.l" { if (relax & (WCSHDR_PROJPn | WCSHDR_reject)) { errmsg = "invalid PROJPn keyword"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 409: YY_RULE_SETUP #line 2677 "wcsbth.l" { BEGIN(DISCARD); } YY_BREAK case 410: YY_RULE_SETUP #line 2681 "wcsbth.l" { // Do checks on i, j, m, n, k. if (!(keytype & keysel)) { // Selection by keyword type. BEGIN(DISCARD); } else if (exclude[n] || exclude[k]) { // One or other column is not selected. if (k && (exclude[n] != exclude[k])) { // For keywords such as TCn_ka, both columns must be excluded. // User error, so return immediately. return WCSHDRERR_BAD_COLUMN; } else { BEGIN(DISCARD); } } else if (i > 99 || j > 99 || m > 99 || n > 999 || k > 999) { if (relax & WCSHDR_reject) { errmsg = errtxt; if (i > 99 || j > 99) { sprintf(errmsg, "axis number exceeds 99"); } else if (m > 99) { sprintf(errmsg, "parameter number exceeds 99"); } else if (n > 999 || k > 999) { sprintf(errmsg, "column number exceeds 999"); } BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } else if (ipass == 2 && npass == 3 && (keytype & BINTAB)) { // Skip keyvalues that won't be inherited. BEGIN(FLUSH); } else { if (ipass == 3 && (keytype & IMGHEAD)) { // IMGHEAD keytypes are always dealt with on the second pass. // However, they must be re-parsed in order to report errors. vptr = 0x0; } if (valtype == INTEGER) { BEGIN(INTEGER_VAL); } else if (valtype == FLOAT) { BEGIN(FLOAT_VAL); } else if (valtype == FLOAT2) { BEGIN(FLOAT2_VAL); } else if (valtype == STRING) { BEGIN(STRING_VAL); } else { errmsg = errtxt; sprintf(errmsg, "internal parser ERROR, bad data type: %d", valtype); BEGIN(ERROR); } } } YY_BREAK case 411: YY_RULE_SETUP #line 2743 "wcsbth.l" { errmsg = "invalid KEYWORD = VALUE syntax"; BEGIN(ERROR); } YY_BREAK case 412: YY_RULE_SETUP #line 2748 "wcsbth.l" { if (ipass == 1) { BEGIN(COMMENT); } else { // Read the keyvalue. sscanf(yytext, "%d", &inttmp); BEGIN(COMMENT); } } YY_BREAK case 413: YY_RULE_SETUP #line 2760 "wcsbth.l" { errmsg = "an integer value was expected"; BEGIN(ERROR); } YY_BREAK case 414: YY_RULE_SETUP #line 2765 "wcsbth.l" { if (ipass == 1) { BEGIN(COMMENT); } else { // Read the keyvalue. wcsutil_str2double(yytext, &dbltmp); if (chekval && chekval(dbltmp)) { errmsg = "invalid keyvalue"; BEGIN(ERROR); } else { BEGIN(COMMENT); } } } YY_BREAK case 415: YY_RULE_SETUP #line 2782 "wcsbth.l" { errmsg = "a floating-point value was expected"; BEGIN(ERROR); } YY_BREAK case 416: YY_RULE_SETUP #line 2787 "wcsbth.l" { if (ipass == 1) { BEGIN(COMMENT); } else { // Read the keyvalue as integer and fractional parts. wcsutil_str2double2(yytext, dbl2tmp); BEGIN(COMMENT); } } YY_BREAK case 417: YY_RULE_SETUP #line 2799 "wcsbth.l" { errmsg = "a floating-point value was expected"; BEGIN(ERROR); } YY_BREAK case 418: /* rule 418 can match eol */ YY_RULE_SETUP #line 2804 "wcsbth.l" { if (ipass == 1) { BEGIN(COMMENT); } else { // Read the keyvalue. strcpy(strtmp, yytext+1); // Squeeze out repeated quotes. int ix = 0; for (int jx = 0; jx < 72; jx++) { if (ix < jx) { strtmp[ix] = strtmp[jx]; } if (strtmp[jx] == '\0') { if (ix) strtmp[ix-1] = '\0'; break; } else if (strtmp[jx] == '\'' && strtmp[jx+1] == '\'') { jx++; } ix++; } BEGIN(COMMENT); } } YY_BREAK case 419: YY_RULE_SETUP #line 2833 "wcsbth.l" { errmsg = "a string value was expected"; BEGIN(ERROR); } YY_BREAK case 420: *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ yyg->yy_c_buf_p = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 2838 "wcsbth.l" { if (ipass == 1) { // Do first-pass bookkeeping. wcsbth_pass1(keytype, i, j, n, k, a, ptype, &alts); BEGIN(FLUSH); } else if (*wcs) { // Store the value now that the keyrecord has been validated. alts.icol = 0; alts.ialt = 0; // Update each coordinate representation. int gotone = 0; struct wcsprm *wcsp; while ((wcsp = wcsbth_idx(*wcs, &alts, keytype, n, a))) { gotone = 1; if (vptr) { void *wptr; if (auxprm) { // Additional auxiliary parameter. auxp = wcsp->aux; ptrdiff_t voff = (char *)vptr - (char *)(&auxtem); wptr = (void *)((char *)auxp + voff); } else { // A parameter that lives directly in wcsprm. ptrdiff_t voff = (char *)vptr - (char *)(&wcstem); wptr = (void *)((char *)wcsp + voff); } if (valtype == INTEGER) { *((int *)wptr) = inttmp; } else if (valtype == FLOAT) { // Apply keyword parameterization. if (ptype == 'v') { int ipx = (wcsp->npv)++; wcsp->pv[ipx].i = i; wcsp->pv[ipx].m = m; wptr = &(wcsp->pv[ipx].value); } else if (j) { wptr = *((double **)wptr) + (i - 1)*(wcsp->naxis) + (j - 1); } else if (i) { wptr = *((double **)wptr) + (i - 1); } if (special) { special(wptr, &dbltmp); } else { *((double *)wptr) = dbltmp; } // Flag the presence of PCi_ja, or CDi_ja and/or CROTAia. if (altlin) { wcsp->altlin |= altlin; altlin = 0; } } else if (valtype == FLOAT2) { // Split MJDREF and JDREF into integer and fraction. if (special) { special(wptr, dbl2tmp); } else { *((double *)wptr) = dbl2tmp[0]; *((double *)wptr + 1) = dbl2tmp[1]; } } else if (valtype == STRING) { // Apply keyword parameterization. if (ptype == 's') { int ipx = wcsp->nps++; wcsp->ps[ipx].i = i; wcsp->ps[ipx].m = m; wptr = wcsp->ps[ipx].value; } else if (j) { wptr = *((char (**)[72])wptr) + (i - 1)*(wcsp->naxis) + (j - 1); } else if (i) { wptr = *((char (**)[72])wptr) + (i - 1); } char *cptr = (char *)wptr; strcpy(cptr, strtmp); } } } if (ipass == npass) { if (gotone) { nvalid++; if (ctrl == 4) { wcsfprintf(stderr, "%.80s\n Accepted (%d) as a valid WCS keyrecord.\n", keyrec, nvalid); } BEGIN(FLUSH); } else { errmsg = "syntactically valid WCS keyrecord has no effect"; BEGIN(ERROR); } } else { BEGIN(FLUSH); } } else { BEGIN(FLUSH); } } YY_BREAK case 421: *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ yyg->yy_c_buf_p = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 2955 "wcsbth.l" { errmsg = "invalid keyvalue"; BEGIN(ERROR); } YY_BREAK case 422: *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ yyg->yy_c_buf_p = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 2960 "wcsbth.l" { errmsg = "invalid keyvalue"; BEGIN(ERROR); } YY_BREAK case 423: *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ yyg->yy_c_buf_p = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 2965 "wcsbth.l" { errmsg = "invalid keyvalue or malformed keycomment"; BEGIN(ERROR); } YY_BREAK case 424: *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ yyg->yy_c_buf_p = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 2970 "wcsbth.l" { errmsg = "malformed keycomment"; BEGIN(ERROR); } YY_BREAK case 425: *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ yyg->yy_c_buf_p = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 2975 "wcsbth.l" { if (ipass == npass) { if (ctrl < 0) { // Preserve discards. keep = keyrec; } else if (2 < ctrl) { nother++; wcsfprintf(stderr, "%.80s\n Not a recognized WCS keyword.\n", keyrec); } } BEGIN(FLUSH); } YY_BREAK case 426: *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ yyg->yy_c_buf_p = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 2990 "wcsbth.l" { if (ipass == npass) { (*nreject)++; if (ctrl%10 == -1) { keep = keyrec; } if (1 < abs(ctrl%10)) { wcsfprintf(stderr, "%.80s\n Rejected (%d), %s.\n", keyrec, *nreject, errmsg); } } BEGIN(FLUSH); } YY_BREAK case 427: /* rule 427 can match eol */ YY_RULE_SETUP #line 3006 "wcsbth.l" { if (ipass == npass && keep) { if (hptr < keep) { strncpy(hptr, keep, 80); } hptr += 80; } naux += auxprm; auxprm = 0; // Throw away the rest of the line and reset for the next one. i = j = 0; n = k = 0; m = 0; a = ' '; keyrec += 80; keytype = 0; valtype = -1; vptr = 0x0; keep = 0x0; altlin = 0; ptype = ' '; chekval = 0x0; special = 0x0; BEGIN(INITIAL); } YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(CCCCCia): case YY_STATE_EOF(iCCCna): case YY_STATE_EOF(iCCCCn): case YY_STATE_EOF(TCCCna): case YY_STATE_EOF(TCCCCn): case YY_STATE_EOF(CCi_ja): case YY_STATE_EOF(ijCCna): case YY_STATE_EOF(TCn_ka): case YY_STATE_EOF(TCCn_ka): case YY_STATE_EOF(CROTAi): case YY_STATE_EOF(iCROTn): case YY_STATE_EOF(TCROTn): case YY_STATE_EOF(CCi_ma): case YY_STATE_EOF(iCn_ma): case YY_STATE_EOF(iCCn_ma): case YY_STATE_EOF(TCn_ma): case YY_STATE_EOF(TCCn_ma): case YY_STATE_EOF(PROJPm): case YY_STATE_EOF(CCCCCCCC): case YY_STATE_EOF(CCCCCCCa): case YY_STATE_EOF(CCCCna): case YY_STATE_EOF(CCCCCna): case YY_STATE_EOF(CCCCn): case YY_STATE_EOF(CCCCCn): case YY_STATE_EOF(VALUE): case YY_STATE_EOF(INTEGER_VAL): case YY_STATE_EOF(FLOAT_VAL): case YY_STATE_EOF(FLOAT2_VAL): case YY_STATE_EOF(STRING_VAL): case YY_STATE_EOF(COMMENT): case YY_STATE_EOF(DISCARD): case YY_STATE_EOF(ERROR): case YY_STATE_EOF(FLUSH): #line 3038 "wcsbth.l" { // End-of-input. if (ipass == 1) { int status; if ((status = wcsbth_init1(&alts, naux, nwcs, wcs)) || (*nwcs == 0 && ctrl == 0)) { return status; } if (2 < abs(ctrl%10)) { if (*nwcs == 1) { if (strcmp(wcs[0]->wcsname, "DEFAULTS") != 0) { wcsfprintf(stderr, "Found one coordinate representation.\n"); } } else { wcsfprintf(stderr, "Found %d coordinate representations.\n", *nwcs); } } if (alts.imgherit) npass = 3; } if (ipass++ < npass) { yyextra->hdr = header; yyextra->nkeyrec = nkeyrec; keyrec = header; *nreject = 0; imherit = 1; i = j = 0; k = n = 0; m = 0; a = ' '; keytype = 0; valtype = -1; vptr = 0x0; altlin = 0; ptype = ' '; chekval = 0x0; special = 0x0; yyrestart(yyin, yyscanner); } else { if (ctrl < 0) { *hptr = '\0'; } else if (ctrl == 1) { wcsfprintf(stderr, "%d WCS keyrecord%s rejected.\n", *nreject, (*nreject==1)?" was":"s were"); } else if (ctrl == 4) { wcsfprintf(stderr, "\n"); wcsfprintf(stderr, "%5d keyrecord%s rejected for syntax or " "other errors,\n", *nreject, (*nreject==1)?" was":"s were"); wcsfprintf(stderr, "%5d %s recognized as syntactically valid, " "and\n", nvalid, (nvalid==1)?"was":"were"); wcsfprintf(stderr, "%5d other%s were not recognized as WCS " "keyrecords.\n", nother, (nother==1)?"":"s"); } return wcsbth_final(&alts, nwcs, wcs); } } YY_BREAK case 428: YY_RULE_SETUP #line 3106 "wcsbth.l" ECHO; YY_BREAK #line 29652 "wcsbth.c" case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = yyg->yy_hold_char; YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) { /* This was really a NUL. */ yy_state_type yy_next_state; yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++yyg->yy_c_buf_p; yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = yyg->yy_c_buf_p; goto yy_find_action; } } else switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_END_OF_FILE: { yyg->yy_did_buffer_switch_on_eof = 0; if ( yywrap( yyscanner ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: yyg->yy_c_buf_p = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of user's declarations */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; char *source = yyg->yytext_ptr; int number_to_move, i; int ret_val; if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1); for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) (yyg->yy_c_buf_p - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yyrealloc( (void *) b->yy_ch_buf, (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = NULL; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), yyg->yy_n_chars, num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } if ( yyg->yy_n_chars == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin , yyscanner); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); /* "- 2" to take care of EOB's */ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); } yyg->yy_n_chars += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (yyscan_t yyscanner) { yy_state_type yy_current_state; char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_current_state = yyg->yy_start; yy_current_state += YY_AT_BOL(); for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) { if ( *yy_cp ) { yy_current_state = yy_nxt[yy_current_state][YY_SC_TO_UI(*yy_cp)]; } else yy_current_state = yy_NUL_trans[yy_current_state]; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) { int yy_is_jam; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ char *yy_cp = yyg->yy_c_buf_p; yy_current_state = yy_NUL_trans[yy_current_state]; yy_is_jam = (yy_current_state == 0); if ( ! yy_is_jam ) { if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } } (void)yyg; return yy_is_jam ? 0 : yy_current_state; } #ifndef YY_NO_UNPUT static void yyunput (int c, char * yy_bp , yyscan_t yyscanner) { char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_cp = yyg->yy_c_buf_p; /* undo effects of setting up yytext */ *yy_cp = yyg->yy_hold_char; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ int number_to_move = yyg->yy_n_chars + 2; char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; yyg->yytext_ptr = yy_bp; yyg->yy_hold_char = *yy_cp; yyg->yy_c_buf_p = yy_cp; } #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (yyscan_t yyscanner) #else static int input (yyscan_t yyscanner) #endif { int c; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; *yyg->yy_c_buf_p = yyg->yy_hold_char; if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) /* This was really a NUL. */ *yyg->yy_c_buf_p = '\0'; else { /* need more input */ int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr); ++yyg->yy_c_buf_p; switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin , yyscanner); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( yyscanner ) ) return 0; if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(yyscanner); #else return input(yyscanner); #endif } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + offset; break; } } } c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ yyg->yy_hold_char = *++yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * @param yyscanner The scanner object. * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } yy_init_buffer( YY_CURRENT_BUFFER, input_file , yyscanner); yy_load_buffer_state( yyscanner ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * @param yyscanner The scanner object. */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (yyscanner); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( yyscanner ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ yyg->yy_did_buffer_switch_on_eof = 1; } static void yy_load_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; yyg->yy_hold_char = *yyg->yy_c_buf_p; } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * @param yyscanner The scanner object. * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file , yyscanner); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * @param yyscanner The scanner object. */ void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree( (void *) b->yy_ch_buf , yyscanner ); yyfree( (void *) b , yyscanner ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) { int oerrno = errno; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_flush_buffer( b , yyscanner); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * @param yyscanner The scanner object. */ void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( yyscanner ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * @param yyscanner The scanner object. */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (new_buffer == NULL) return; yyensure_buffer_stack(yyscanner); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) yyg->yy_buffer_stack_top++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * @param yyscanner The scanner object. */ void yypop_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER , yyscanner); YY_CURRENT_BUFFER_LVALUE = NULL; if (yyg->yy_buffer_stack_top > 0) --yyg->yy_buffer_stack_top; if (YY_CURRENT_BUFFER) { yy_load_buffer_state( yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (yyscan_t yyscanner) { yy_size_t num_to_alloc; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!yyg->yy_buffer_stack) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; yyg->yy_buffer_stack_top = 0; return; } if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ /* Increase the buffer to prepare for a possible push. */ yy_size_t grow_size = 8 /* arbitrary grow size */; num_to_alloc = yyg->yy_buffer_stack_max + grow_size; yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc (yyg->yy_buffer_stack, num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return NULL; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = NULL; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer( b , yyscanner ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * @param yyscanner The scanner object. * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (const char * yystr , yyscan_t yyscanner) { return yy_scan_bytes( yystr, (int) strlen(yystr) , yyscanner); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len , yyscan_t yyscanner) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = (yy_size_t) (_yybytes_len + 2); buf = (char *) yyalloc( n , yyscanner ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer( buf, n , yyscanner); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yynoreturn yy_fatal_error (const char* msg , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = yyg->yy_hold_char; \ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ yyg->yy_hold_char = *yyg->yy_c_buf_p; \ *yyg->yy_c_buf_p = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the user-defined data for this scanner. * @param yyscanner The scanner object. */ YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyextra; } /** Get the current line number. * @param yyscanner The scanner object. */ int yyget_lineno (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yylineno; } /** Get the current column number. * @param yyscanner The scanner object. */ int yyget_column (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yycolumn; } /** Get the input stream. * @param yyscanner The scanner object. */ FILE *yyget_in (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyin; } /** Get the output stream. * @param yyscanner The scanner object. */ FILE *yyget_out (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyout; } /** Get the length of the current token. * @param yyscanner The scanner object. */ int yyget_leng (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyleng; } /** Get the current token. * @param yyscanner The scanner object. */ char *yyget_text (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yytext; } /** Set the user-defined data. This data is never touched by the scanner. * @param user_defined The data to be associated with this scanner. * @param yyscanner The scanner object. */ void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyextra = user_defined ; } /** Set the current line number. * @param _line_number line number * @param yyscanner The scanner object. */ void yyset_lineno (int _line_number , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* lineno is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "yyset_lineno called with no buffer" ); yylineno = _line_number; } /** Set the current column. * @param _column_no column number * @param yyscanner The scanner object. */ void yyset_column (int _column_no , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* column is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "yyset_column called with no buffer" ); yycolumn = _column_no; } /** Set the input stream. This does not discard the current * input buffer. * @param _in_str A readable stream. * @param yyscanner The scanner object. * @see yy_switch_to_buffer */ void yyset_in (FILE * _in_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyin = _in_str ; } void yyset_out (FILE * _out_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyout = _out_str ; } int yyget_debug (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yy_flex_debug; } void yyset_debug (int _bdebug , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_flex_debug = _bdebug ; } /* Accessor methods for yylval and yylloc */ /* User-visible API */ /* yylex_init is special because it creates the scanner itself, so it is * the ONLY reentrant function that doesn't take the scanner as the last argument. * That's why we explicitly handle the declaration, instead of using our macros. */ int yylex_init(yyscan_t* ptr_yy_globals) { if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); return yy_init_globals ( *ptr_yy_globals ); } /* yylex_init_extra has the same functionality as yylex_init, but follows the * convention of taking the scanner as the last argument. Note however, that * this is a *pointer* to a scanner, as it will be allocated by this call (and * is the reason, too, why this function also must handle its own declaration). * The user defined value in the first argument will be available to yyalloc in * the yyextra field. */ int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals ) { struct yyguts_t dummy_yyguts; yyset_extra (yy_user_defined, &dummy_yyguts); if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); yyset_extra (yy_user_defined, *ptr_yy_globals); return yy_init_globals ( *ptr_yy_globals ); } static int yy_init_globals (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ yyg->yy_buffer_stack = NULL; yyg->yy_buffer_stack_top = 0; yyg->yy_buffer_stack_max = 0; yyg->yy_c_buf_p = NULL; yyg->yy_init = 0; yyg->yy_start = 0; yyg->yy_start_stack_ptr = 0; yyg->yy_start_stack_depth = 0; yyg->yy_start_stack = NULL; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = NULL; yyout = NULL; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer( YY_CURRENT_BUFFER , yyscanner ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(yyscanner); } /* Destroy the stack itself. */ yyfree(yyg->yy_buffer_stack , yyscanner); yyg->yy_buffer_stack = NULL; /* Destroy the start condition stack. */ yyfree( yyg->yy_start_stack , yyscanner ); yyg->yy_start_stack = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( yyscanner); /* Destroy the main struct (reentrant only). */ yyfree ( yyscanner , yyscanner ); yyscanner = NULL; return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (const char * s , yyscan_t yyscanner) { int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; return malloc(size); } void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return realloc(ptr, size); } void yyfree (void * ptr , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 3106 "wcsbth.l" /*---------------------------------------------------------------------------- * External interface to the scanner. *---------------------------------------------------------------------------*/ int wcsbth( char *header, int nkeyrec, int relax, int ctrl, int keysel, int *colsel, int *nreject, int *nwcs, struct wcsprm **wcs) { // Function prototypes. int yylex_init_extra(YY_EXTRA_TYPE extra, yyscan_t *yyscanner); int yylex_destroy(yyscan_t yyscanner); struct wcsbth_extra extra; yyscan_t yyscanner; yylex_init_extra(&extra, &yyscanner); int status = wcsbth_scanner(header, nkeyrec, relax, ctrl, keysel, colsel, nreject, nwcs, wcs, yyscanner); yylex_destroy(yyscanner); return status; } /*---------------------------------------------------------------------------- * Perform first-pass tasks: * * 1) Count the number of coordinate axes in each of the 27 possible alternate * image-header coordinate representations. Also count the number of PVi_ma * and PSi_ma keywords in each representation. * * 2) Determine the number of binary table columns that have an image array * with a coordinate representation (up to 999), and count the number of * coordinate axes in each of the 27 possible alternates. Also count the * number of iVn_ma and iSn_ma keywords in each representation. * * 3) Determine the number of alternate pixel list coordinate representations * (up to 27) and the table columns associated with each. Also count the * number of TVn_ma and TSn_ma keywords in each representation. * * In the first pass alts->arridx[icol][27] is used to determine the number of * axes in each of 27 possible image-header coordinate descriptions (icol == 0) * and each of the 27 possible coordinate representations for an image array in * each column. * * The elements of alts->pixlist[icol] are used as bit arrays to flag which of * the 27 possible pixel list coordinate representations are associated with * each table column. *---------------------------------------------------------------------------*/ int wcsbth_pass1( int keytype, int i, int j, int n, int k, char a, char ptype, struct wcsbth_alts *alts) { if (a == 0) { // Keywords such as DATE-OBS go along for the ride. return 0; } int ncol = alts->ncol; // Do we need to allocate memory for alts? if (alts->arridx == 0x0) { if (ncol == 0) { // Can only happen if TFIELDS is missing or out-of-sequence. If n and // k are both zero then we may be processing an image header so leave // ncol alone - the array will be realloc'd later if required. if (n || k) { // The header is mangled, assume the worst. ncol = 999; } } if (!(alts->arridx = calloc((1 + ncol)*27, sizeof(short int))) || !(alts->npv = calloc((1 + ncol)*27, sizeof(unsigned char))) || !(alts->nps = calloc((1 + ncol)*27, sizeof(unsigned char))) || !(alts->pixlist = calloc((1 + ncol), sizeof(unsigned int)))) { if (alts->arridx) free(alts->arridx); if (alts->npv) free(alts->npv); if (alts->nps) free(alts->nps); if (alts->pixlist) free(alts->pixlist); return WCSHDRERR_MEMORY; } alts->ncol = ncol; } else if (n > ncol || k > ncol) { // Can only happen if TFIELDS or the WCS keyword is wrong; carry on. ncol = 999; if (!(alts->arridx = realloc(alts->arridx, 27*(1 + ncol)*sizeof(short int))) || !(alts->npv = realloc(alts->npv, 27*(1 + ncol)*sizeof(unsigned char))) || !(alts->nps = realloc(alts->nps, 27*(1 + ncol)*sizeof(unsigned char))) || !(alts->pixlist = realloc(alts->pixlist, (1 + ncol)*sizeof(unsigned int)))) { if (alts->arridx) free(alts->arridx); if (alts->npv) free(alts->npv); if (alts->nps) free(alts->nps); if (alts->pixlist) free(alts->pixlist); return WCSHDRERR_MEMORY; } // Since realloc() doesn't initialize the extra memory. for (int icol = (1 + alts->ncol); icol < (1 + ncol); icol++) { for (int ialt = 0; ialt < 27; ialt++) { alts->arridx[icol][ialt] = 0; alts->npv[icol][ialt] = 0; alts->nps[icol][ialt] = 0; alts->pixlist[icol] = 0; } } alts->ncol = ncol; } int ialt = 0; if (a != ' ') { ialt = a - 'A' + 1; } // A BINTAB keytype such as LONPna, in conjunction with an IMGAXIS keytype // causes a table column to be recognized as an image array. if (keytype & IMGHEAD || keytype & BIMGARR) { // n == 0 is expected for IMGHEAD keywords. if (i == 0 && j == 0) { if (alts->arridx[n][ialt] == 0) { // Flag that an auxiliary keyword was seen. alts->arridx[n][ialt] = -1; } } else { // Record the maximum axis number found. if (alts->arridx[n][ialt] < i) { alts->arridx[n][ialt] = i; } if (alts->arridx[n][ialt] < j) { alts->arridx[n][ialt] = j; } } if (ptype == 'v') { alts->npv[n][ialt]++; } else if (ptype == 's') { alts->nps[n][ialt]++; } } // BINTAB keytypes, which apply both to pixel lists as well as binary table // image arrays, never contribute to recognizing a table column as a pixel // list axis. A PIXLIST keytype is required for that. if (keytype == PIXLIST) { int mask = 1 << ialt; // n > 0 for PIXLIST keytypes. alts->pixlist[n] |= mask; if (k) alts->pixlist[k] |= mask; // Used as a flag over all columns. alts->pixlist[0] |= mask; if (ptype == 'v') { alts->pixnpv[ialt]++; } else if (ptype == 's') { alts->pixnps[ialt]++; } } return 0; } /*---------------------------------------------------------------------------- * Perform initializations at the end of the first pass: * * 1) Determine the required number of wcsprm structs, allocate memory for * an array of them and initialize each one. *---------------------------------------------------------------------------*/ int wcsbth_init1( struct wcsbth_alts *alts, int naux, int *nwcs, struct wcsprm **wcs) { int status = 0; if (alts->arridx == 0x0) { *nwcs = 0; return 0; } // Determine the number of axes in each pixel list representation. int ialt, mask, ncol = alts->ncol; for (ialt = 0, mask = 1; ialt < 27; ialt++, mask <<= 1) { alts->pixidx[ialt] = 0; if (alts->pixlist[0] | mask) { for (int icol = 1; icol <= ncol; icol++) { if (alts->pixlist[icol] & mask) { alts->pixidx[ialt]++; } } } } // Find the total number of coordinate representations. *nwcs = 0; alts->imgherit = 0; int inherit[27]; for (int ialt = 0; ialt < 27; ialt++) { inherit[ialt] = 0; for (int icol = 1; icol <= ncol; icol++) { if (alts->arridx[icol][ialt] < 0) { // No BIMGARR keytype but there's at least one BINTAB. if (alts->arridx[0][ialt] > 0) { // There is an IMGAXIS keytype that we will inherit, so count this // representation. alts->arridx[icol][ialt] = alts->arridx[0][ialt]; } else { alts->arridx[icol][ialt] = 0; } } if (alts->arridx[icol][ialt]) { if (alts->arridx[0][ialt]) { // All IMGHEAD keywords are inherited for this ialt. inherit[ialt] = 1; if (alts->arridx[icol][ialt] < alts->arridx[0][ialt]) { // The extra axes are also inherited. alts->arridx[icol][ialt] = alts->arridx[0][ialt]; } } (*nwcs)++; } } // Count every "a" found in any IMGHEAD keyword... if (alts->arridx[0][ialt]) { if (inherit[ialt]) { // ...but not if the IMGHEAD keywords will be inherited. alts->arridx[0][ialt] = 0; alts->imgherit = 1; } else if (alts->arridx[0][ialt] > 0) { (*nwcs)++; } } // We need a struct for every "a" found in a PIXLIST keyword. if (alts->pixidx[ialt]) { (*nwcs)++; } } if (*nwcs) { // Allocate memory for the required number of wcsprm structs. if (!(*wcs = calloc(*nwcs, sizeof(struct wcsprm)))) { return WCSHDRERR_MEMORY; } // Initialize each wcsprm struct. struct wcsprm *wcsp = *wcs; *nwcs = 0; for (int icol = 0; icol <= ncol; icol++) { for (int ialt = 0; ialt < 27; ialt++) { if (alts->arridx[icol][ialt] > 0) { // Image-header representations that are not for inheritance // (icol == 0) or binary table image array representations. wcsp->flag = -1; int npvmax = alts->npv[icol][ialt]; int npsmax = alts->nps[icol][ialt]; if ((status = wcsinit(1, (int)(alts->arridx[icol][ialt]), wcsp, npvmax, npsmax, -1))) { wcsvfree(nwcs, wcs); break; } // Record the alternate version code. if (ialt) { wcsp->alt[0] = 'A' + ialt - 1; } // Any additional auxiliary keywords present? if (naux) { if (wcsauxi(1, wcsp)) { return WCSHDRERR_MEMORY; } } // Record the table column number. wcsp->colnum = icol; // On the second pass alts->arridx[icol][27] indexes the array of // wcsprm structs. alts->arridx[icol][ialt] = (*nwcs)++; wcsp++; } else { // Signal that this column has no WCS for this "a". alts->arridx[icol][ialt] = -1; } } } for (int ialt = 0; ialt < 27; ialt++) { if (alts->pixidx[ialt]) { // Pixel lists representations. wcsp->flag = -1; int npvmax = alts->pixnpv[ialt]; int npsmax = alts->pixnps[ialt]; if ((status = wcsinit(1, (int)(alts->pixidx[ialt]), wcsp, npvmax, npsmax, -1))) { wcsvfree(nwcs, wcs); break; } // Record the alternate version code. if (ialt) { wcsp->alt[0] = 'A' + ialt - 1; } // Any additional auxiliary keywords present? if (naux) { if (wcsauxi(1, wcsp)) { return WCSHDRERR_MEMORY; } } // Record the pixel list column numbers. int icol, ix, mask = (1 << ialt); for (icol = 1, ix = 0; icol <= ncol; icol++) { if (alts->pixlist[icol] & mask) { wcsp->colax[ix++] = icol; } } // alts->pixidx[] indexes the array of wcsprm structs. alts->pixidx[ialt] = (*nwcs)++; wcsp++; } else { // Signal that this column is not a pixel list axis for this "a". alts->pixidx[ialt] = -1; } } } return status; } /*---------------------------------------------------------------------------- * Return a pointer to the next wcsprm struct for a particular column number * and alternate. *---------------------------------------------------------------------------*/ struct wcsprm *wcsbth_idx( struct wcsprm *wcs, struct wcsbth_alts *alts, int keytype, int n, char a) { const char as[] = " ABCDEFGHIJKLMNOPQRSTUVWXYZ"; if (!wcs) return 0x0; int iwcs = -1; for (; iwcs < 0 && alts->ialt < 27; alts->ialt++) { // Note that a == 0 applies to every alternate, otherwise this // loop simply determines the appropriate value of alts->ialt. if (a && a != as[alts->ialt]) continue; if (keytype & (IMGHEAD | BIMGARR)) { for (; iwcs < 0 && alts->icol <= alts->ncol; alts->icol++) { // Image header keywords, n == 0, apply to all columns, otherwise this // loop simply determines the appropriate value of alts->icol. if (n && n != alts->icol) continue; iwcs = alts->arridx[alts->icol][alts->ialt]; } // Break out of the loop to stop alts->ialt from being incremented. if (iwcs >= 0) break; // Start from scratch for the next alts->ialt. alts->icol = 0; } if (keytype & (IMGAUX | PIXLIST)) { iwcs = alts->pixidx[alts->ialt]; } } return (iwcs >= 0) ? (wcs + iwcs) : 0x0; } /*---------------------------------------------------------------------------- * Return the axis number associated with the specified column number in a * particular pixel list coordinate representation. *---------------------------------------------------------------------------*/ int wcsbth_colax( struct wcsprm *wcs, struct wcsbth_alts *alts, int n, char a) { if (!wcs) return 0; struct wcsprm *wcsp = wcs; if (a != ' ') { wcsp += alts->pixidx[a-'A'+1]; } for (int ix = 0; ix < wcsp->naxis; ix++) { if (wcsp->colax[ix] == n) { return ++ix; } } return 0; } /*---------------------------------------------------------------------------- * Interpret the JDREF, JDREFI, and JDREFF keywords. *---------------------------------------------------------------------------*/ int wcsbth_jdref(double *mjdref, const double *jdref) { // Set MJDREF from JDREF. if (undefined(mjdref[0] && undefined(mjdref[1]))) { mjdref[0] = jdref[0] - 2400000.0; mjdref[1] = jdref[1] - 0.5; if (mjdref[1] < 0.0) { mjdref[0] -= 1.0; mjdref[1] += 1.0; } } return 0; } int wcsbth_jdrefi(double *mjdref, const double *jdrefi) { // Set the integer part of MJDREF from JDREFI. if (undefined(mjdref[0])) { mjdref[0] = *jdrefi - 2400000.5; } return 0; } int wcsbth_jdreff(double *mjdref, const double *jdreff) { // Set the fractional part of MJDREF from JDREFF. if (undefined(mjdref[1])) { mjdref[1] = *jdreff; } return 0; } /*---------------------------------------------------------------------------- * Interpret EPOCHa keywords. *---------------------------------------------------------------------------*/ int wcsbth_epoch(double *equinox, const double *epoch) { // If EQUINOXa is currently undefined then set it from EPOCHa. if (undefined(*equinox)) { *equinox = *epoch; } return 0; } /*---------------------------------------------------------------------------- * Interpret VSOURCEa keywords. *---------------------------------------------------------------------------*/ int wcsbth_vsource(double *zsource, const double *vsource) { const double c = 299792458.0; // If ZSOURCEa is currently undefined then set it from VSOURCEa. if (undefined(*zsource)) { // Convert relativistic Doppler velocity to redshift. double beta = *vsource/c; *zsource = (1.0 + beta)/sqrt(1.0 - beta*beta) - 1.0; } return 0; } /*---------------------------------------------------------------------------- * Check validity of a TIMEPIXR keyvalue. *---------------------------------------------------------------------------*/ int wcsbth_timepixr(double timepixr) { return (timepixr < 0.0 || 1.0 < timepixr); } /*---------------------------------------------------------------------------- * Tie up loose ends. *---------------------------------------------------------------------------*/ int wcsbth_final( struct wcsbth_alts *alts, int *nwcs, struct wcsprm **wcs) { if (alts->arridx) free(alts->arridx); if (alts->npv) free(alts->npv); if (alts->nps) free(alts->nps); if (alts->pixlist) free(alts->pixlist); for (int ialt = 0; ialt < *nwcs; ialt++) { // Interpret -TAB header keywords. int status; if ((status = wcstab(*wcs+ialt))) { wcsvfree(nwcs, wcs); return status; } } return 0; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/flexed/wcspih.c0000644000175100001710000421134600000000000020305 0ustar00vstsdocker#line 2 "wcspih.c" #line 4 "wcspih.c" #define _POSIX_C_SOURCE 1 #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 6 #define YY_FLEX_SUBMINOR_VERSION 4 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif #ifdef yy_create_buffer #define wcspih_create_buffer_ALREADY_DEFINED #else #define yy_create_buffer wcspih_create_buffer #endif #ifdef yy_delete_buffer #define wcspih_delete_buffer_ALREADY_DEFINED #else #define yy_delete_buffer wcspih_delete_buffer #endif #ifdef yy_scan_buffer #define wcspih_scan_buffer_ALREADY_DEFINED #else #define yy_scan_buffer wcspih_scan_buffer #endif #ifdef yy_scan_string #define wcspih_scan_string_ALREADY_DEFINED #else #define yy_scan_string wcspih_scan_string #endif #ifdef yy_scan_bytes #define wcspih_scan_bytes_ALREADY_DEFINED #else #define yy_scan_bytes wcspih_scan_bytes #endif #ifdef yy_init_buffer #define wcspih_init_buffer_ALREADY_DEFINED #else #define yy_init_buffer wcspih_init_buffer #endif #ifdef yy_flush_buffer #define wcspih_flush_buffer_ALREADY_DEFINED #else #define yy_flush_buffer wcspih_flush_buffer #endif #ifdef yy_load_buffer_state #define wcspih_load_buffer_state_ALREADY_DEFINED #else #define yy_load_buffer_state wcspih_load_buffer_state #endif #ifdef yy_switch_to_buffer #define wcspih_switch_to_buffer_ALREADY_DEFINED #else #define yy_switch_to_buffer wcspih_switch_to_buffer #endif #ifdef yypush_buffer_state #define wcspihpush_buffer_state_ALREADY_DEFINED #else #define yypush_buffer_state wcspihpush_buffer_state #endif #ifdef yypop_buffer_state #define wcspihpop_buffer_state_ALREADY_DEFINED #else #define yypop_buffer_state wcspihpop_buffer_state #endif #ifdef yyensure_buffer_stack #define wcspihensure_buffer_stack_ALREADY_DEFINED #else #define yyensure_buffer_stack wcspihensure_buffer_stack #endif #ifdef yylex #define wcspihlex_ALREADY_DEFINED #else #define yylex wcspihlex #endif #ifdef yyrestart #define wcspihrestart_ALREADY_DEFINED #else #define yyrestart wcspihrestart #endif #ifdef yylex_init #define wcspihlex_init_ALREADY_DEFINED #else #define yylex_init wcspihlex_init #endif #ifdef yylex_init_extra #define wcspihlex_init_extra_ALREADY_DEFINED #else #define yylex_init_extra wcspihlex_init_extra #endif #ifdef yylex_destroy #define wcspihlex_destroy_ALREADY_DEFINED #else #define yylex_destroy wcspihlex_destroy #endif #ifdef yyget_debug #define wcspihget_debug_ALREADY_DEFINED #else #define yyget_debug wcspihget_debug #endif #ifdef yyset_debug #define wcspihset_debug_ALREADY_DEFINED #else #define yyset_debug wcspihset_debug #endif #ifdef yyget_extra #define wcspihget_extra_ALREADY_DEFINED #else #define yyget_extra wcspihget_extra #endif #ifdef yyset_extra #define wcspihset_extra_ALREADY_DEFINED #else #define yyset_extra wcspihset_extra #endif #ifdef yyget_in #define wcspihget_in_ALREADY_DEFINED #else #define yyget_in wcspihget_in #endif #ifdef yyset_in #define wcspihset_in_ALREADY_DEFINED #else #define yyset_in wcspihset_in #endif #ifdef yyget_out #define wcspihget_out_ALREADY_DEFINED #else #define yyget_out wcspihget_out #endif #ifdef yyset_out #define wcspihset_out_ALREADY_DEFINED #else #define yyset_out wcspihset_out #endif #ifdef yyget_leng #define wcspihget_leng_ALREADY_DEFINED #else #define yyget_leng wcspihget_leng #endif #ifdef yyget_text #define wcspihget_text_ALREADY_DEFINED #else #define yyget_text wcspihget_text #endif #ifdef yyget_lineno #define wcspihget_lineno_ALREADY_DEFINED #else #define yyget_lineno wcspihget_lineno #endif #ifdef yyset_lineno #define wcspihset_lineno_ALREADY_DEFINED #else #define yyset_lineno wcspihset_lineno #endif #ifdef yyget_column #define wcspihget_column_ALREADY_DEFINED #else #define yyget_column wcspihget_column #endif #ifdef yyset_column #define wcspihset_column_ALREADY_DEFINED #else #define yyset_column wcspihset_column #endif #ifdef yywrap #define wcspihwrap_ALREADY_DEFINED #else #define yywrap wcspihwrap #endif #ifdef yyalloc #define wcspihalloc_ALREADY_DEFINED #else #define yyalloc wcspihalloc #endif #ifdef yyrealloc #define wcspihrealloc_ALREADY_DEFINED #else #define yyrealloc wcspihrealloc #endif #ifdef yyfree #define wcspihfree_ALREADY_DEFINED #else #define yyfree wcspihfree #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #ifndef SIZE_MAX #define SIZE_MAX (~(size_t)0) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ /* TODO: this is always defined, so inline it */ #define yyconst const #if defined(__GNUC__) && __GNUC__ >= 3 #define yynoreturn __attribute__((__noreturn__)) #else #define yynoreturn #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an * integer in range [0..255] for use as an array index. */ #define YY_SC_TO_UI(c) ((YY_CHAR) (c)) /* An opaque pointer. */ #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; #endif /* For convenience, these vars (plus the bison vars far below) are macros in the reentrant scanner. */ #define yyin yyg->yyin_r #define yyout yyg->yyout_r #define yyextra yyg->yyextra_r #define yyleng yyg->yyleng_r #define yytext yyg->yytext_r #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) #define yy_flex_debug yyg->yy_flex_debug_r /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN yyg->yy_start = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START ((yyg->yy_start - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin , yyscanner ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) #define YY_LINENO_REWIND_TO(ptr) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = yyg->yy_hold_char; \ YY_RESTORE_YY_MORE_OFFSET \ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] void yyrestart ( FILE *input_file , yyscan_t yyscanner ); void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner ); void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); void yypop_buffer_state ( yyscan_t yyscanner ); static void yyensure_buffer_stack ( yyscan_t yyscanner ); static void yy_load_buffer_state ( yyscan_t yyscanner ); static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner ); #define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner) YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner ); void *yyalloc ( yy_size_t , yyscan_t yyscanner ); void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner ); void yyfree ( void * , yyscan_t yyscanner ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define wcspihwrap(yyscanner) (/*CONSTCOND*/1) #define YY_SKIP_YYWRAP typedef flex_uint8_t YY_CHAR; typedef int yy_state_type; #define yytext_ptr yytext_r static const flex_int16_t yy_nxt[][128] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56 }, { 55, 57, 57, 57, 57, 57, 57, 57, 57, 57, 56, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 58, 59, 60, 61, 62, 57, 57, 63, 57, 64, 57, 65, 66, 67, 68, 69, 57, 70, 71, 72, 57, 73, 74, 75, 76, 77, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57 }, { 55, 78, 78, 78, 78, 78, 78, 78, 78, 78, 56, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 79, 80, 80, 80, 80, 80, 80, 80, 80, 80, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78 }, { 55, 78, 78, 78, 78, 78, 78, 78, 78, 78, 56, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 79, 80, 80, 80, 80, 80, 80, 80, 80, 80, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78 }, { 55, 81, 81, 81, 81, 81, 81, 81, 81, 81, 56, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 82, 83, 83, 83, 83, 83, 83, 83, 83, 83, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81 }, { 55, 81, 81, 81, 81, 81, 81, 81, 81, 81, 56, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 82, 83, 83, 83, 83, 83, 83, 83, 83, 83, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81 }, { 55, 84, 84, 84, 84, 84, 84, 84, 84, 84, 56, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 85, 86, 86, 86, 86, 86, 86, 86, 86, 86, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84 }, { 55, 84, 84, 84, 84, 84, 84, 84, 84, 84, 56, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 85, 86, 86, 86, 86, 86, 86, 86, 86, 86, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84 }, { 55, 87, 87, 87, 87, 87, 87, 87, 87, 87, 56, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87 }, { 55, 87, 87, 87, 87, 87, 87, 87, 87, 87, 56, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87 }, { 55, 90, 90, 90, 90, 90, 90, 90, 90, 90, 56, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90 }, { 55, 90, 90, 90, 90, 90, 90, 90, 90, 90, 56, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90 }, { 55, 92, 92, 92, 92, 92, 92, 92, 92, 92, 56, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92 }, { 55, 92, 92, 92, 92, 92, 92, 92, 92, 92, 56, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92 }, { 55, 93, 93, 93, 93, 93, 93, 93, 93, 93, 56, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93 }, { 55, 93, 93, 93, 93, 93, 93, 93, 93, 93, 56, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93 }, { 55, 95, 95, 95, 95, 95, 95, 95, 95, 95, 56, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95 }, { 55, 95, 95, 95, 95, 95, 95, 95, 95, 95, 56, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95 }, { 55, 97, 97, 97, 97, 97, 97, 97, 97, 97, 56, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97 }, { 55, 97, 97, 97, 97, 97, 97, 97, 97, 97, 56, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97 }, { 55, 99, 99, 99, 99, 99, 99, 99, 99, 99, 56, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 }, { 55, 99, 99, 99, 99, 99, 99, 99, 99, 99, 56, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 }, { 55, 101, 101, 101, 101, 101, 101, 101, 101, 101, 56, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 102, 102, 102, 102, 102, 102, 102, 102, 102, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101 }, { 55, 101, 101, 101, 101, 101, 101, 101, 101, 101, 56, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 102, 102, 102, 102, 102, 102, 102, 102, 102, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101 }, { 55, 103, 103, 103, 103, 103, 103, 103, 103, 103, 56, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 104, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103 }, { 55, 103, 103, 103, 103, 103, 103, 103, 103, 103, 56, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 104, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103 }, { 55, 105, 105, 105, 105, 105, 105, 105, 105, 105, 56, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 106, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105 }, { 55, 105, 105, 105, 105, 105, 105, 105, 105, 105, 56, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 106, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105 }, { 55, 107, 107, 107, 107, 107, 107, 107, 107, 107, 56, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 108, 107, 108, 107, 107, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107 }, { 55, 107, 107, 107, 107, 107, 107, 107, 107, 107, 56, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 108, 107, 108, 107, 107, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107 }, { 55, 110, 110, 110, 110, 110, 110, 110, 110, 110, 56, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 111, 110, 111, 112, 110, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110 }, { 55, 110, 110, 110, 110, 110, 110, 110, 110, 110, 56, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 111, 110, 111, 112, 110, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110 }, { 55, 114, 114, 114, 114, 114, 114, 114, 114, 114, 56, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 115, 114, 115, 116, 114, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114 }, { 55, 114, 114, 114, 114, 114, 114, 114, 114, 114, 56, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 115, 114, 115, 116, 114, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114 }, { 55, 118, 118, 118, 118, 118, 118, 118, 118, 118, 56, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 119, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118 }, { 55, 118, 118, 118, 118, 118, 118, 118, 118, 118, 56, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 119, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118 }, { 55, 120, 120, 120, 120, 120, 120, 120, 120, 120, 56, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 121, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120 }, { 55, 120, 120, 120, 120, 120, 120, 120, 120, 120, 56, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 121, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120 }, { 55, 122, 122, 122, 122, 122, 122, 122, 122, 122, 56, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 122, 122, 122, 122, 123, 122, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 122, 122, 122, 122, 122 }, { 55, 122, 122, 122, 122, 122, 122, 122, 122, 122, 56, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 122, 122, 122, 122, 123, 122, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 122, 122, 122, 122, 122 }, { 55, 124, 124, 124, 124, 124, 124, 124, 124, 124, 56, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 125, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124 }, { 55, 124, 124, 124, 124, 124, 124, 124, 124, 124, 56, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 125, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124 }, { 55, 126, 126, 126, 126, 126, 126, 126, 126, 126, 56, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 127, 126, 127, 128, 126, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126 }, { 55, 126, 126, 126, 126, 126, 126, 126, 126, 126, 56, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 127, 126, 127, 128, 126, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126 }, { 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 130, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56 }, { 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 130, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56 }, { 55, 131, 131, 131, 131, 131, 131, 131, 131, 131, 132, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 133, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 134, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131 }, { 55, 131, 131, 131, 131, 131, 131, 131, 131, 131, 132, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 133, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 134, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131 }, { 55, 135, 135, 135, 135, 135, 135, 135, 135, 135, 136, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135 }, { 55, 135, 135, 135, 135, 135, 135, 135, 135, 135, 136, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135 }, { 55, 137, 137, 137, 137, 137, 137, 137, 137, 137, 138, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137 }, { 55, 137, 137, 137, 137, 137, 137, 137, 137, 137, 138, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137 }, { 55, 139, 139, 139, 139, 139, 139, 139, 139, 139, 140, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139 }, { 55, 139, 139, 139, 139, 139, 139, 139, 139, 139, 140, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139 }, { -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55 }, { 55, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56 }, { 55, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57 }, { 55, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, 141, -58, -58, 142, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, 143, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58 }, { 55, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, 144, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, 145, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, 146, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59 }, { 55, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, 147, -60, -60, -60, -60, -60, -60, -60, -60, -60, 148, -60, 149, 150, 151, 152, 153, 154, -60, -60, -60, -60, 155, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60 }, { 55, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, 156, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, 157, 158, -61, 159, -61, -61, 160, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61 }, { 55, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, 161, -62, 162, 163, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62 }, { 55, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, 164, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63 }, { 55, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, 165, 166, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64 }, { 55, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, 167, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, 168, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65 }, { 55, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, 169, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66 }, { 55, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, 170, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67 }, { 55, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, 171, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68 }, { 55, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, 172, -69, -69, -69, -69, -69, -69, -69, -69, 173, -69, -69, -69, 174, -69, 175, 176, -69, -69, 177, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69 }, { 55, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, 178, -70, -70, -70, 179, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, 180, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70 }, { 55, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, 181, -71, -71, 182, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71 }, { 55, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, 183, -72, -72, -72, 184, -72, -72, -72, -72, -72, -72, -72, -72, 185, 186, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72 }, { 55, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, 187, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, 188, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73 }, { 55, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, 189, -74, 190, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74 }, { 55, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, 191, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75 }, { 55, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, 192, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76 }, { 55, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, 193, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77 }, { 55, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78 }, { 55, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, 194, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, 195, 196, 196, 196, 196, 196, 196, 196, 196, 196, -79, -79, -79, -79, -79, -79, -79, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79 }, { 55, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, 197, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, -80, -80, -80, -80, -80, -80, -80, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80 }, { 55, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81 }, { 55, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, 199, -82, -82, 200, 201, 201, 201, 201, 201, 201, 201, 201, 201, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, 202, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82 }, { 55, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, 199, -83, -83, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, 204, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83 }, { 55, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84 }, { 55, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, 205, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, 206, 207, 207, 207, 207, 207, 207, 207, 207, 207, -85, -85, -85, -85, -85, -85, -85, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85 }, { 55, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, 208, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, -86, -86, -86, -86, -86, -86, -86, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86 }, { 55, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87 }, { 55, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, 210, -88, -88, 211, 212, 212, 212, 212, 212, 212, 212, 212, 212, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, 213, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88 }, { 55, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, 210, -89, -89, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, 215, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89 }, { 55, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90 }, { 55, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91 }, { 55, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92 }, { 55, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93 }, { 55, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, 216, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, -94, -94, -94, -94, -94, -94, -94, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94 }, { 55, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95 }, { 55, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, 218, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96 }, { 55, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97 }, { 55, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, 220, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98 }, { 55, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99 }, { 55, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, 221, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100 }, { 55, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101 }, { 55, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, 222, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102 }, { 55, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103 }, { 55, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, 224, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104 }, { 55, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105 }, { 55, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, 225, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106 }, { 55, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107 }, { 55, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108 }, { 55, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109 }, { 55, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110 }, { 55, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, 227, -111, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111 }, { 55, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112 }, { 55, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, 230, -113, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, 232, 232, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, 232, 232, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113 }, { 55, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114 }, { 55, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, 233, -115, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115 }, { 55, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116 }, { 55, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, 236, -117, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, 238, 238, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, 238, 238, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117 }, { 55, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118 }, { 55, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 240, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239 }, { 55, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120 }, { 55, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 242, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241 }, { 55, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122 }, { 55, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, 243, -123, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, -123, -123, -123, -123, -123, -123, -123, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, -123, -123, -123, -123, 243, -123, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, -123, -123, -123, -123, -123 }, { 55, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124 }, { 55, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, 244, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125 }, { 55, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126 }, { 55, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, 245, -127, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127 }, { 55, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128 }, { 55, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, 248, -129, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, 250, 250, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, 250, 250, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129 }, { 55, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130 }, { 55, 251, 251, 251, 251, 251, 251, 251, 251, 251, 252, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 253, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 254, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251 }, { 55, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132 }, { 55, 255, 255, 255, 255, 255, 255, 255, 255, 255, 256, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 257, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 258, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 55, 259, 259, 259, 259, 259, 259, 259, 259, 259, 260, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 261, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 262, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259 }, { 55, 263, 263, 263, 263, 263, 263, 263, 263, 263, 264, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263 }, { 55, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136 }, { 55, 265, 265, 265, 265, 265, 265, 265, 265, 265, 266, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265 }, { 55, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138 }, { 55, 267, 267, 267, 267, 267, 267, 267, 267, 267, 268, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267 }, { 55, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140 }, { 55, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, 269, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141 }, { 55, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, 270, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142 }, { 55, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, 271, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, 272, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143 }, { 55, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, 273, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144 }, { 55, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, 274, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145 }, { 55, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, 275, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, 276, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146 }, { 55, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, 277, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147 }, { 55, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, 278, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, 279, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148 }, { 55, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, 280, 281, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149 }, { 55, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, 282, 283, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150 }, { 55, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, 284, -151, -151, -151, -151, -151, -151, -151, 285, -151, -151, 286, 287, -151, -151, -151, -151, -151, 288, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151 }, { 55, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, 289, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152 }, { 55, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, 290, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153 }, { 55, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, 291, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154 }, { 55, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, 292, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155 }, { 55, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, 293, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156 }, { 55, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157 }, { 55, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158 }, { 55, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, 294, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159 }, { 55, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, 295, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160 }, { 55, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, 296, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161 }, { 55, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, 297, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162 }, { 55, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, 298, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163 }, { 55, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, 299, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164 }, { 55, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, 300, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, 301, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165 }, { 55, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, 302, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166 }, { 55, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, 303, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167 }, { 55, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, 304, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168 }, { 55, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, 305, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169 }, { 55, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, 306, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170 }, { 55, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, 307, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171 }, { 55, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172 }, { 55, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, 308, -173, -173, -173, 309, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, 310, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173 }, { 55, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, 311, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174 }, { 55, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, 312, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175 }, { 55, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176 }, { 55, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177 }, { 55, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, 313, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178 }, { 55, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, 314, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179 }, { 55, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, 315, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180 }, { 55, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, 316, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181 }, { 55, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, 317, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182 }, { 55, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, 318, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183 }, { 55, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, 319, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184 }, { 55, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, 320, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185 }, { 55, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, 321, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186 }, { 55, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, 322, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187 }, { 55, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, 323, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188 }, { 55, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, 324, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189 }, { 55, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, 325, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190 }, { 55, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, 326, -191, -191, -191, -191, -191, 327, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191 }, { 55, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, 328, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192 }, { 55, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, 329, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193 }, { 55, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, 330, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194 }, { 55, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, 331, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, 332, 333, 333, 333, 333, 333, 333, 333, 333, 333, -195, -195, -195, -195, -195, -195, -195, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195 }, { 55, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, 334, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, 332, 333, 333, 333, 333, 333, 333, 333, 333, 333, -196, -196, -196, -196, -196, -196, -196, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196 }, { 55, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, 335, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197 }, { 55, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, 336, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, -198, -198, -198, -198, -198, -198, -198, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198 }, { 55, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199 }, { 55, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, 339, -200, -200, 340, 341, 341, 341, 341, 341, 341, 341, 341, 341, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, 342, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200 }, { 55, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, 339, -201, -201, 343, 344, 344, 344, 344, 344, 344, 344, 344, 344, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, 345, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201 }, { 55, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202 }, { 55, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, 339, -203, -203, 347, 348, 348, 348, 348, 348, 348, 348, 348, 348, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, 349, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203 }, { 55, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, 350, 351, 351, 351, 351, 351, 351, 351, 351, 351, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204 }, { 55, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, 352, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205 }, { 55, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, 353, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, 354, 355, 355, 355, 355, 355, 355, 355, 355, 355, -206, -206, -206, -206, -206, -206, -206, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206 }, { 55, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, 356, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, 354, 355, 355, 355, 355, 355, 355, 355, 355, 355, -207, -207, -207, -207, -207, -207, -207, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207 }, { 55, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, 357, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208 }, { 55, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, 358, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, -209, -209, -209, -209, -209, -209, -209, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209 }, { 55, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210 }, { 55, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, 360, -211, -211, 361, 362, 362, 362, 362, 362, 362, 362, 362, 362, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, 363, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211 }, { 55, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, 360, -212, -212, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, 365, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212 }, { 55, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213 }, { 55, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, 360, -214, -214, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, 368, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214 }, { 55, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, 369, 370, 370, 370, 370, 370, 370, 370, 370, 370, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215 }, { 55, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, 371, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216 }, { 55, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, 372, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, -217, -217, -217, -217, -217, -217, -217, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217 }, { 55, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, 374, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218 }, { 55, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, 375, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219 }, { 55, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220 }, { 55, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221 }, { 55, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, 379, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222 }, { 55, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, 380, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223 }, { 55, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, 224, -224, -224, -224, -224, -224, -224, 381, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224 }, { 55, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, 225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225 }, { 55, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226 }, { 55, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227 }, { 55, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, 230, -228, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, 232, 232, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, 232, 232, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228 }, { 55, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, 232, 232, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, 232, 232, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229 }, { 55, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, 232, 232, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, 232, 232, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230 }, { 55, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, 230, -231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, 232, 232, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, 232, 232, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231 }, { 55, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, 383, -232, 383, -232, -232, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232 }, { 55, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233 }, { 55, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, 236, -234, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, 238, 238, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, 238, 238, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234 }, { 55, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, 238, 238, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, 238, 238, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235 }, { 55, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, 238, 238, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, 238, 238, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236 }, { 55, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, 236, -237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, 238, 238, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, 238, 238, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237 }, { 55, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, 386, -238, 386, -238, -238, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238 }, { 55, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 240, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239 }, { 55, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, 239, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240 }, { 55, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 242, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241 }, { 55, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242 }, { 55, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, 243, -243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, -243, -243, -243, -243, -243, -243, -243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, -243, -243, -243, -243, 243, -243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, -243, -243, -243, -243, -243 }, { 55, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, 244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244 }, { 55, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245, -245 }, { 55, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, 248, -246, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, 250, 250, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, 250, 250, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246 }, { 55, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, 250, 250, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, 250, 250, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247 }, { 55, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, 250, 250, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, 250, 250, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248 }, { 55, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, 248, -249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, 250, 250, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, 250, 250, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249 }, { 55, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, 389, -250, 389, -250, -250, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250 }, { 55, 251, 251, 251, 251, 251, 251, 251, 251, 251, 252, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 253, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 254, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251 }, { 55, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252 }, { 55, 391, 391, 391, 391, 391, 391, 391, 391, 391, 252, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 253, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 254, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391 }, { 55, 392, 392, 392, 392, 392, 392, 392, 392, 392, 393, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 394, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 395, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392 }, { 55, 396, 396, 396, 396, 396, 396, 396, 396, 396, 397, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 398, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 399, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396 }, { 55, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256 }, { 55, 400, 400, 400, 400, 400, 400, 400, 400, 400, 401, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 402, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 403, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400 }, { 55, 259, 259, 259, 259, 259, 259, 259, 259, 259, 260, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 261, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 262, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259 }, { 55, 259, 259, 259, 259, 259, 259, 259, 259, 259, 260, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 261, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 262, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259 }, { 55, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260 }, { 55, 259, 259, 259, 259, 259, 259, 259, 259, 259, 260, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 261, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 262, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259 }, { 55, 259, 259, 259, 259, 259, 259, 259, 259, 259, 260, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 261, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 262, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259 }, { 55, 263, 263, 263, 263, 263, 263, 263, 263, 263, 264, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263 }, { 55, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264 }, { 55, 265, 265, 265, 265, 265, 265, 265, 265, 265, 266, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265 }, { 55, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266 }, { 55, 267, 267, 267, 267, 267, 267, 267, 267, 267, 268, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267 }, { 55, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268 }, { 55, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, 404, 405, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269 }, { 55, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, 406, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270 }, { 55, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, 407, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271 }, { 55, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, 408, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272 }, { 55, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, 409, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273 }, { 55, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, 410, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274 }, { 55, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, 411, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275 }, { 55, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, 412, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276 }, { 55, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, 413, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277 }, { 55, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, 414, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278 }, { 55, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, 415, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279 }, { 55, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, 416, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280 }, { 55, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, 417, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281 }, { 55, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, 418, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282 }, { 55, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, 419, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283 }, { 55, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, 420, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284 }, { 55, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, 421, -285, -285, -285, -285, -285, 422, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285 }, { 55, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, 423, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286 }, { 55, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, 424, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287 }, { 55, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, 425, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288 }, { 55, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, 426, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289 }, { 55, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, 427, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290 }, { 55, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, 428, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291 }, { 55, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, 429, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292 }, { 55, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, 430, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293 }, { 55, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, 431, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294 }, { 55, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, 432, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295 }, { 55, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, 433, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296 }, { 55, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, 434, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297 }, { 55, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, 435, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298 }, { 55, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, 436, -299, -299, -299, -299, -299, 437, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299 }, { 55, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, 438, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300 }, { 55, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, 439, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301 }, { 55, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, 440, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302 }, { 55, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, 441, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303 }, { 55, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, 442, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304 }, { 55, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, 443, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, 444, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305 }, { 55, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, 445, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306 }, { 55, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, 446, -307, -307, -307, -307, -307, -307, -307, 447, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307 }, { 55, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, 448, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308 }, { 55, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, 449, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309 }, { 55, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, 450, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, 451, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310 }, { 55, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, 452, -311, -311, 453, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311 }, { 55, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, 454, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312 }, { 55, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, 455, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313 }, { 55, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, 456, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314 }, { 55, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, 457, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315 }, { 55, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, 458, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316 }, { 55, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, 459, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317 }, { 55, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, 460, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318 }, { 55, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, 461, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, 462, 463, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319 }, { 55, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, 464, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320 }, { 55, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, 465, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, 466, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321 }, { 55, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, 467, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, 468, -322, -322, 469, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322 }, { 55, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, 470, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323 }, { 55, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, 471, 471, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324 }, { 55, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, 472, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, 473, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325 }, { 55, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, 474, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326 }, { 55, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, 475, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327 }, { 55, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, 476, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328 }, { 55, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, 477, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329 }, { 55, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, 478, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330 }, { 55, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, 479, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331 }, { 55, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, 480, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, 481, 482, 482, 482, 482, 482, 482, 482, 482, 482, -332, -332, -332, -332, -332, -332, -332, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332 }, { 55, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, 483, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, 481, 482, 482, 482, 482, 482, 482, 482, 482, 482, -333, -333, -333, -333, -333, -333, -333, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333 }, { 55, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, 484, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334 }, { 55, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, 485, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335 }, { 55, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, 486, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336 }, { 55, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, 480, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, -337, -337, -337, -337, -337, -337, -337, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337 }, { 55, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, 488, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, -338, -338, -338, -338, -338, -338, -338, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338 }, { 55, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, 490, 490, 490, 490, 490, 490, 490, 490, 490, 490, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339 }, { 55, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, 491, -340, -340, 492, 493, 493, 493, 493, 493, 493, 493, 493, 493, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, 494, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340 }, { 55, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, 491, -341, -341, 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, 496, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341 }, { 55, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342 }, { 55, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, 491, -343, -343, 492, 492, 492, 492, 492, 492, 492, 492, 492, 492, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, 498, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343 }, { 55, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, 491, -344, -344, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, 498, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344 }, { 55, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, 500, 501, 501, 501, 501, 501, 501, 501, 501, 501, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345 }, { 55, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, 502, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, -346, -346, -346, -346, -346, -346, -346, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346 }, { 55, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, 491, -347, -347, 492, 492, 492, 492, 492, 492, 492, 492, 492, 492, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, 494, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347 }, { 55, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, 491, -348, -348, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, 494, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348 }, { 55, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, 504, 505, 505, 505, 505, 505, 505, 505, 505, 505, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349 }, { 55, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, 502, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, 506, 507, 507, 507, 507, 507, 507, 507, 507, 507, -350, -350, -350, -350, -350, -350, -350, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350 }, { 55, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, 508, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, 509, 509, 509, 509, 509, 509, 509, 509, 509, 509, -351, -351, -351, -351, -351, -351, -351, 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351 }, { 55, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352 }, { 55, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353 }, { 55, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354 }, { 55, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355 }, { 55, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356 }, { 55, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357 }, { 55, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358 }, { 55, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, 510, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, -359, -359, -359, -359, -359, -359, -359, 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359 }, { 55, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360 }, { 55, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, 513, -361, -361, 514, 515, 515, 515, 515, 515, 515, 515, 515, 515, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, 516, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361 }, { 55, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, 513, -362, -362, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, 518, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362 }, { 55, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363 }, { 55, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, 513, -364, -364, 514, 514, 514, 514, 514, 514, 514, 514, 514, 514, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, 520, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364 }, { 55, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, 521, 522, 522, 522, 522, 522, 522, 522, 522, 522, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365 }, { 55, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, 523, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, 524, 524, 524, 524, 524, 524, 524, 524, 524, 524, -366, -366, -366, -366, -366, -366, -366, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366 }, { 55, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, 513, -367, -367, 514, 514, 514, 514, 514, 514, 514, 514, 514, 514, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, 516, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367 }, { 55, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, 525, 526, 526, 526, 526, 526, 526, 526, 526, 526, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368 }, { 55, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, 527, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, 528, 529, 529, 529, 529, 529, 529, 529, 529, 529, -369, -369, -369, -369, -369, -369, -369, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369 }, { 55, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, 527, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, -370, -370, -370, -370, -370, -370, -370, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370 }, { 55, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371 }, { 55, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372 }, { 55, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373 }, { 55, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374 }, { 55, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375, -375 }, { 55, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, -376 }, { 55, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, 531, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377, -377 }, { 55, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, 532, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378, -378 }, { 55, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, 533, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379, -379 }, { 55, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, 534, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380, -380 }, { 55, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 536, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535 }, { 55, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, 232, 232, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, 232, 232, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382, -382 }, { 55, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383 }, { 55, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384, -384 }, { 55, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, 238, 238, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, 238, 238, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385, -385 }, { 55, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386, -386 }, { 55, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387 }, { 55, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, 250, 250, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, 250, 250, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388 }, { 55, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389, -389 }, { 55, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390 }, { 55, 391, 391, 391, 391, 391, 391, 391, 391, 391, 537, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 538, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 539, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391 }, { 55, 392, 392, 392, 392, 392, 392, 392, 392, 392, 393, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 394, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 395, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392 }, { 55, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393 }, { 55, 392, 392, 392, 392, 392, 392, 392, 392, 392, 393, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 394, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 395, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392 }, { 55, 392, 392, 392, 392, 392, 392, 392, 392, 392, 393, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 394, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 395, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392 }, { 55, 396, 396, 396, 396, 396, 396, 396, 396, 396, 397, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 398, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 399, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396 }, { 55, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397 }, { 55, 396, 396, 396, 396, 396, 396, 396, 396, 396, 397, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 398, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 399, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396 }, { 55, 540, 540, 540, 540, 540, 540, 540, 540, 540, 541, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 542, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 543, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540 }, { 55, 396, 396, 396, 396, 396, 396, 396, 396, 396, 397, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 398, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 399, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396 }, { 55, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, -401 }, { 55, 400, 400, 400, 400, 400, 400, 400, 400, 400, 401, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 402, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 403, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400 }, { 55, 544, 544, 544, 544, 544, 544, 544, 544, 544, 545, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 546, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 547, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544 }, { 55, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404, -404 }, { 55, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405 }, { 55, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, 548, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, -406 }, { 55, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, 549, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407, -407 }, { 55, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, 550, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408, -408 }, { 55, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, 551, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409, -409 }, { 55, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, 552, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410, -410 }, { 55, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, 553, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411, -411 }, { 55, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, 554, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412, -412 }, { 55, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, 555, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413 }, { 55, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, 556, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414 }, { 55, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, 557, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415, -415 }, { 55, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, 558, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416, -416 }, { 55, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, 559, -417, -417, -417, -417, -417, -417, -417, -417, 560, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, -417 }, { 55, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, 561, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, -418 }, { 55, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, 562, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, -419 }, { 55, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, 563, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, -420 }, { 55, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, 564, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421 }, { 55, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, 565, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422, -422 }, { 55, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, 566, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423, -423 }, { 55, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, 567, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, -424 }, { 55, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, 568, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, -425 }, { 55, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, 569, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426, -426 }, { 55, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, 570, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, -427 }, { 55, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, 571, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428, -428 }, { 55, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, 572, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429, -429 }, { 55, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, 573, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, 574, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430 }, { 55, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, 575, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431, -431 }, { 55, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, 576, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432, -432 }, { 55, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, 577, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433, -433 }, { 55, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, 578, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434, -434 }, { 55, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, 579, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, -435 }, { 55, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, 580, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436 }, { 55, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, 581, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437, -437 }, { 55, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, 582, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438, -438 }, { 55, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, 583, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439, -439 }, { 55, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, 584, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440, -440 }, { 55, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, 585, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441, -441 }, { 55, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, 586, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442, -442 }, { 55, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, 587, 588, -443, -443, 589, -443, -443, -443, -443, -443, -443, -443, -443, -443, 590, -443, -443, 591, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443, -443 }, { 55, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, 592, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444, -444 }, { 55, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, 593, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445, -445 }, { 55, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, 594, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446 }, { 55, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, 595, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447, -447 }, { 55, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, 596, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448, -448 }, { 55, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, 597, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, -449 }, { 55, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, 598, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450 }, { 55, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, 599, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451, -451 }, { 55, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, 600, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452, -452 }, { 55, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, 601, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, -453 }, { 55, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, 602, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, -454 }, { 55, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, 603, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, 604, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, -455 }, { 55, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, 605, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, 606, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, -456 }, { 55, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, 607, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, -457 }, { 55, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, 608, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458 }, { 55, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, 609, -459, -459, -459, 610, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459 }, { 55, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, 611, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, -460 }, { 55, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, 612, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, 613, 614, -461, -461, 615, -461, 616, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461, -461 }, { 55, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, 617, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462, -462 }, { 55, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, 618, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, -463 }, { 55, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, 619, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, 620, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464, -464 }, { 55, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, 621, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465, -465 }, { 55, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, 622, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466, -466 }, { 55, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, 623, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467, -467 }, { 55, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, 624, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468 }, { 55, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, 625, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469, -469 }, { 55, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, 626, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470, -470 }, { 55, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, 627, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471, -471 }, { 55, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, 628, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, -472 }, { 55, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, 629, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473, -473 }, { 55, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, 630, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474, -474 }, { 55, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, 631, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, -475 }, { 55, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, 632, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, -476 }, { 55, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, 633, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477, -477 }, { 55, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, 634, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478, -478 }, { 55, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, 635, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, -479 }, { 55, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, 636, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, -480 }, { 55, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, 637, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, 638, 639, 639, 639, 639, 639, 639, 639, 639, 639, -481, -481, -481, -481, -481, -481, -481, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, -481 }, { 55, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, 640, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, 638, 639, 639, 639, 639, 639, 639, 639, 639, 639, -482, -482, -482, -482, -482, -482, -482, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, -482 }, { 55, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, 641, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483, -483 }, { 55, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, 642, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484, -484 }, { 55, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, 643, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, -485 }, { 55, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, 644, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, -486 }, { 55, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, 637, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, 645, 645, 645, 645, 645, 645, 645, 645, 645, 645, -487, -487, -487, -487, -487, -487, -487, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487, -487 }, { 55, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, 646, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, -488 }, { 55, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, 647, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, -489, -489, -489, -489, -489, -489, -489, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, -489 }, { 55, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, 649, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, -490, -490, -490, -490, -490, -490, -490, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490, -490 }, { 55, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, 651, 651, 651, 651, 651, 651, 651, 651, 651, 651, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491, -491 }, { 55, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, 652, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, 653, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, -492 }, { 55, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, 652, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, 654, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493, -493 }, { 55, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, 655, 655, 655, 655, 655, 655, 655, 655, 655, 655, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494, -494 }, { 55, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, 652, -495, -495, 656, 656, 656, 656, 656, 656, 656, 656, 656, 656, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, 657, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495 }, { 55, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, 658, 659, 659, 659, 659, 659, 659, 659, 659, 659, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496, -496 }, { 55, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, 660, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, 661, 661, 661, 661, 661, 661, 661, 661, 661, 661, -497, -497, -497, -497, -497, -497, -497, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497, -497 }, { 55, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, 662, 663, 663, 663, 663, 663, 663, 663, 663, 663, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498, -498 }, { 55, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, 652, -499, -499, 656, 656, 656, 656, 656, 656, 656, 656, 656, 656, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, 653, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, -499 }, { 55, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, 660, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, 664, 665, 665, 665, 665, 665, 665, 665, 665, 665, -500, -500, -500, -500, -500, -500, -500, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500, -500 }, { 55, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, 666, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, 667, 667, 667, 667, 667, 667, 667, 667, 667, 667, -501, -501, -501, -501, -501, -501, -501, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501, -501 }, { 55, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, 668, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502, -502 }, { 55, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, 669, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, -503, -503, -503, -503, -503, -503, -503, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503, -503 }, { 55, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, 660, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, 671, 672, 672, 672, 672, 672, 672, 672, 672, 672, -504, -504, -504, -504, -504, -504, -504, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504, -504 }, { 55, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, 673, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, -505, -505, -505, -505, -505, -505, -505, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505, -505 }, { 55, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, 669, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, 675, 676, 676, 676, 676, 676, 676, 676, 676, 676, -506, -506, -506, -506, -506, -506, -506, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506, -506 }, { 55, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, 677, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, -507, -507, -507, -507, -507, -507, -507, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507, -507 }, { 55, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, 679, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508, -508 }, { 55, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, 680, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, -509, -509, -509, -509, -509, -509, -509, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509, -509 }, { 55, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, 681, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510, -510 }, { 55, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, 682, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, -511, -511, -511, -511, -511, -511, -511, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511 }, { 55, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, 684, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, 685, 685, 685, 685, 685, 685, 685, 685, 685, 685, -512, -512, -512, -512, -512, -512, -512, 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512 }, { 55, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513, -513 }, { 55, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, 687, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, 688, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514, -514 }, { 55, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, 687, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, 689, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515, -515 }, { 55, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516, -516 }, { 55, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, 687, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, 691, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517, -517 }, { 55, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, 692, 693, 693, 693, 693, 693, 693, 693, 693, 693, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518 }, { 55, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, 694, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, 695, 695, 695, 695, 695, 695, 695, 695, 695, 695, -519, -519, -519, -519, -519, -519, -519, 694, 694, 694, 694, 694, 694, 694, 694, 694, 694, 694, 694, 694, 694, 694, 694, 694, 694, 694, 694, 694, 694, 694, 694, 694, 694, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519 }, { 55, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, 696, 697, 697, 697, 697, 697, 697, 697, 697, 697, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520 }, { 55, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, 698, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, 699, 700, 700, 700, 700, 700, 700, 700, 700, 700, -521, -521, -521, -521, -521, -521, -521, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521 }, { 55, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, 698, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, 701, 701, 701, 701, 701, 701, 701, 701, 701, 701, -522, -522, -522, -522, -522, -522, -522, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522, -522 }, { 55, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, 702, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523, -523 }, { 55, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, 703, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, 704, 704, 704, 704, 704, 704, 704, 704, 704, 704, -524, -524, -524, -524, -524, -524, -524, 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, -524 }, { 55, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, 705, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, 706, 707, 707, 707, 707, 707, 707, 707, 707, 707, -525, -525, -525, -525, -525, -525, -525, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, -525 }, { 55, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, 705, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, -526, -526, -526, -526, -526, -526, -526, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526, -526 }, { 55, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, 709, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527, -527 }, { 55, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, 710, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, 711, 712, 712, 712, 712, 712, 712, 712, 712, 712, -528, -528, -528, -528, -528, -528, -528, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528, -528 }, { 55, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, 710, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, -529, -529, -529, -529, -529, -529, -529, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529, -529 }, { 55, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, 714, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, 704, 704, 704, 704, 704, 704, 704, 704, 704, 704, -530, -530, -530, -530, -530, -530, -530, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530, -530 }, { 55, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, 715, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, -531 }, { 55, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, 716, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532, -532 }, { 55, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, -533 }, { 55, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, -534 }, { 55, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 536, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535 }, { 55, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, 535, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536, -536 }, { 55, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537, -537 }, { 55, 391, 391, 391, 391, 391, 391, 391, 391, 391, 537, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 538, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 539, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391 }, { 55, 717, 717, 717, 717, 717, 717, 717, 717, 717, 718, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 719, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 720, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717 }, { 55, 540, 540, 540, 540, 540, 540, 540, 540, 540, 541, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 542, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 543, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540 }, { 55, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, -541 }, { 55, 540, 540, 540, 540, 540, 540, 540, 540, 540, 541, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 542, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 543, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540 }, { 55, 540, 540, 540, 540, 540, 540, 540, 540, 540, 541, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 542, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 543, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 540 }, { 55, 544, 544, 544, 544, 544, 544, 544, 544, 544, 545, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 546, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 547, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544 }, { 55, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545, -545 }, { 55, 544, 544, 544, 544, 544, 544, 544, 544, 544, 545, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 546, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 547, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544 }, { 55, 544, 544, 544, 544, 544, 544, 544, 544, 544, 545, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 546, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 547, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544 }, { 55, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, 721, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548, -548 }, { 55, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, 722, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549, -549 }, { 55, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, 723, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550, -550 }, { 55, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, 724, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551, -551 }, { 55, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, 725, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, -552 }, { 55, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, 726, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553 }, { 55, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, 727, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554, -554 }, { 55, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555, -555 }, { 55, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556, -556 }, { 55, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, 728, 729, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, -557 }, { 55, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558, -558 }, { 55, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559, -559 }, { 55, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560, -560 }, { 55, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561, -561 }, { 55, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562, -562 }, { 55, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563, -563 }, { 55, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, 730, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564, -564 }, { 55, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, 731, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565, -565 }, { 55, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566, -566 }, { 55, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567, -567 }, { 55, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568, -568 }, { 55, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569, -569 }, { 55, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570 }, { 55, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571, -571 }, { 55, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572, -572 }, { 55, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, 732, 733, -573, -573, 734, -573, -573, -573, -573, -573, -573, -573, -573, -573, 735, -573, -573, 736, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, -573 }, { 55, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, 737, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574, -574 }, { 55, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, 738, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575, -575 }, { 55, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576, -576 }, { 55, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, 739, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577, -577 }, { 55, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, 740, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, 740, 740, 740, 740, 740, 740, 740, 740, 740, 740, 740, 740, 740, 740, 740, 740, 740, 740, 740, 740, 740, 740, 740, 740, 740, 740, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578, -578 }, { 55, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, 741, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, -579 }, { 55, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, 742, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, -580 }, { 55, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, 743, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, -581 }, { 55, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, 744, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, -582 }, { 55, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, 745, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, 746, -583, -583, 747, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583, -583 }, { 55, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, 748, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584, -584 }, { 55, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, 749, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585 }, { 55, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, 750, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, -586 }, { 55, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, 751, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, -587 }, { 55, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, 752, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, -588 }, { 55, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, 753, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, -589 }, { 55, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, 754, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, -590 }, { 55, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, 755, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, -591 }, { 55, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, 756, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, -592 }, { 55, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, 757, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593, -593 }, { 55, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, 758, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594, -594 }, { 55, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, 759, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595, -595 }, { 55, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, 760, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596, -596 }, { 55, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, 761, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597, -597 }, { 55, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, 762, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, -598 }, { 55, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, 763, -599, -599, -599, -599, 764, -599, -599, -599, -599, -599, 765, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, -599 }, { 55, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, 766, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, -600 }, { 55, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, 767, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, -601 }, { 55, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, -602 }, { 55, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, 768, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603 }, { 55, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, 769, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604, -604 }, { 55, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, 770, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605, -605 }, { 55, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, 771, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606, -606 }, { 55, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, 772, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, -607 }, { 55, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, 773, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, -608 }, { 55, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, 774, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, -609 }, { 55, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, 775, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610, -610 }, { 55, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, 776, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, -611 }, { 55, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, 777, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612, -612 }, { 55, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, 778, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, -613 }, { 55, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, 779, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, -614 }, { 55, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, 780, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615 }, { 55, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, 781, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, -616 }, { 55, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, 782, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, -617 }, { 55, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, 783, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618, -618 }, { 55, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, 784, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, -619 }, { 55, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, 785, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620, -620 }, { 55, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, 786, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621, -621 }, { 55, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, 787, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622, -622 }, { 55, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, 788, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623, -623 }, { 55, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, 789, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624, -624 }, { 55, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, 790, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625, -625 }, { 55, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, 791, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626, -626 }, { 55, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, 792, 792, 792, 792, 792, 792, 792, 792, 792, 792, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627, -627 }, { 55, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, 793, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628, -628 }, { 55, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, 794, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629, -629 }, { 55, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, 795, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630 }, { 55, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, 796, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631, -631 }, { 55, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, 797, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632, -632 }, { 55, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, 798, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633, -633 }, { 55, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, 799, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, -634 }, { 55, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, 800, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635, -635 }, { 55, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, 801, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636, -636 }, { 55, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, 802, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637, -637 }, { 55, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, 803, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, 804, 805, 805, 805, 805, 805, 805, 805, 805, 805, -638, -638, -638, -638, -638, -638, -638, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638 }, { 55, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, 806, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, 804, 805, 805, 805, 805, 805, 805, 805, 805, 805, -639, -639, -639, -639, -639, -639, -639, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639, -639 }, { 55, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, 807, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640, -640 }, { 55, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, 808, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641, -641 }, { 55, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, 809, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642, -642 }, { 55, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, 810, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643, -643 }, { 55, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, 811, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644, -644 }, { 55, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, 803, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, 804, 804, 804, 804, 804, 804, 804, 804, 804, 804, -645, -645, -645, -645, -645, -645, -645, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645, -645 }, { 55, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, 812, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646, -646 }, { 55, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, 813, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647, -647 }, { 55, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, 814, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, -648, -648, -648, -648, -648, -648, -648, 814, 814, 814, 814, 814, 814, 814, 814, 814, 814, 814, 814, 814, 814, 814, 814, 814, 814, 814, 814, 814, 814, 814, 814, 814, 814, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648, -648 }, { 55, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, 816, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649, -649 }, { 55, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, 817, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, 818, 818, 818, 818, 818, 818, 818, 818, 818, 818, -650, -650, -650, -650, -650, -650, -650, 817, 817, 817, 817, 817, 817, 817, 817, 817, 817, 817, 817, 817, 817, 817, 817, 817, 817, 817, 817, 817, 817, 817, 817, 817, 817, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650, -650 }, { 55, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, 819, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, -651, -651, -651, -651, -651, -651, -651, 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651, -651 }, { 55, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, 821, 821, 821, 821, 821, 821, 821, 821, 821, 821, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652, -652 }, { 55, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653, -653 }, { 55, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, 822, 823, 823, 823, 823, 823, 823, 823, 823, 823, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, -654 }, { 55, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, 824, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, 825, 825, 825, 825, 825, 825, 825, 825, 825, 825, -655, -655, -655, -655, -655, -655, -655, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655, -655 }, { 55, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, 826, 826, 826, 826, 826, 826, 826, 826, 826, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656, -656 }, { 55, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, 822, 827, 827, 827, 827, 827, 827, 827, 827, 827, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657, -657 }, { 55, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, 824, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, 825, 828, 828, 828, 828, 828, 828, 828, 828, 828, -658, -658, -658, -658, -658, -658, -658, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658, -658 }, { 55, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, 829, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, 830, 830, 830, 830, 830, 830, 830, 830, 830, 830, -659, -659, -659, -659, -659, -659, -659, 829, 829, 829, 829, 829, 829, 829, 829, 829, 829, 829, 829, 829, 829, 829, 829, 829, 829, 829, 829, 829, 829, 829, 829, 829, 829, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, -659 }, { 55, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, 831, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660, -660 }, { 55, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, 832, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, 833, 833, 833, 833, 833, 833, 833, 833, 833, 833, -661, -661, -661, -661, -661, -661, -661, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661, -661 }, { 55, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, 824, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, 825, 834, 834, 834, 834, 834, 834, 834, 834, 834, -662, -662, -662, -662, -662, -662, -662, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662, -662 }, { 55, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, 835, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, 836, 836, 836, 836, 836, 836, 836, 836, 836, 836, -663, -663, -663, -663, -663, -663, -663, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663, -663 }, { 55, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, 832, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, 833, 837, 837, 837, 837, 837, 837, 837, 837, 837, -664, -664, -664, -664, -664, -664, -664, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664, -664 }, { 55, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, 838, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, -665, -665, -665, -665, -665, -665, -665, 838, 838, 838, 838, 838, 838, 838, 838, 838, 838, 838, 838, 838, 838, 838, 838, 838, 838, 838, 838, 838, 838, 838, 838, 838, 838, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665, -665 }, { 55, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, 840, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666, -666 }, { 55, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, 841, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, 833, 833, 833, 833, 833, 833, 833, 833, 833, 833, -667, -667, -667, -667, -667, -667, -667, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667, -667 }, { 55, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, 842, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668, -668 }, { 55, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, 843, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669, -669 }, { 55, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, 844, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, -670, -670, -670, -670, -670, -670, -670, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670, -670 }, { 55, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, 832, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, 833, 846, 846, 846, 846, 846, 846, 846, 846, 846, -671, -671, -671, -671, -671, -671, -671, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671, -671 }, { 55, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, 847, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, 848, 848, 848, 848, 848, 848, 848, 848, 848, 848, -672, -672, -672, -672, -672, -672, -672, 847, 847, 847, 847, 847, 847, 847, 847, 847, 847, 847, 847, 847, 847, 847, 847, 847, 847, 847, 847, 847, 847, 847, 847, 847, 847, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672, -672 }, { 55, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, 849, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673, -673 }, { 55, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, 850, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, 833, 833, 833, 833, 833, 833, 833, 833, 833, 833, -674, -674, -674, -674, -674, -674, -674, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674, -674 }, { 55, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, 844, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, 845, 851, 851, 851, 851, 851, 851, 851, 851, 851, -675, -675, -675, -675, -675, -675, -675, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675 }, { 55, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, 852, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, -676, -676, -676, -676, -676, -676, -676, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676, -676 }, { 55, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, 854, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677, -677 }, { 55, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, 855, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, -678, -678, -678, -678, -678, -678, -678, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678, -678 }, { 55, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, 856, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679, -679 }, { 55, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, 857, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680, -680 }, { 55, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, 858, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681, -681 }, { 55, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, 859, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682, -682 }, { 55, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, 860, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, -683, -683, -683, -683, -683, -683, -683, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683, -683 }, { 55, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, 862, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684, -684 }, { 55, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, 863, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, -685, -685, -685, -685, -685, -685, -685, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685, -685 }, { 55, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, 865, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, -686, -686, -686, -686, -686, -686, -686, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686, -686 }, { 55, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687, -687 }, { 55, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688, -688 }, { 55, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689, -689 }, { 55, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, 870, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, 871, 871, 871, 871, 871, 871, 871, 871, 871, 871, -690, -690, -690, -690, -690, -690, -690, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690, -690 }, { 55, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, 872, 872, 872, 872, 872, 872, 872, 872, 872, 872, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691, -691 }, { 55, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, 873, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, 874, 874, 874, 874, 874, 874, 874, 874, 874, 874, -692, -692, -692, -692, -692, -692, -692, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692, -692 }, { 55, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, 873, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, 875, 875, 875, 875, 875, 875, 875, 875, 875, 875, -693, -693, -693, -693, -693, -693, -693, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693, -693 }, { 55, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, 876, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, -694 }, { 55, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, 877, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, -695, -695, -695, -695, -695, -695, -695, 877, 877, 877, 877, 877, 877, 877, 877, 877, 877, 877, 877, 877, 877, 877, 877, 877, 877, 877, 877, 877, 877, 877, 877, 877, 877, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695, -695 }, { 55, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, 879, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, -696, -696, -696, -696, -696, -696, -696, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, -696 }, { 55, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, 879, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, -697, -697, -697, -697, -697, -697, -697, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697, -697 }, { 55, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, 882, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698, -698 }, { 55, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, 883, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, -699, -699, -699, -699, -699, -699, -699, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699, -699 }, { 55, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, 883, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, -700, -700, -700, -700, -700, -700, -700, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700, -700 }, { 55, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, 886, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, -701, -701, -701, -701, -701, -701, -701, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701, -701 }, { 55, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, 887, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702, -702 }, { 55, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, 888, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703, -703 }, { 55, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, 889, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, -704, -704, -704, -704, -704, -704, -704, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704, -704 }, { 55, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, 891, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705, -705 }, { 55, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, 892, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, -706, -706, -706, -706, -706, -706, -706, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706, -706 }, { 55, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, 892, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, -707, -707, -707, -707, -707, -707, -707, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, -707 }, { 55, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, 895, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, -708, -708, -708, -708, -708, -708, -708, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708, -708 }, { 55, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, 896, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, -709 }, { 55, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, 897, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710, -710 }, { 55, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, 898, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, -711, -711, -711, -711, -711, -711, -711, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711, -711 }, { 55, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, 898, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, -712, -712, -712, -712, -712, -712, -712, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712, -712 }, { 55, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, 901, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, -713, -713, -713, -713, -713, -713, -713, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713, -713 }, { 55, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, 902, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714, -714 }, { 55, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, 903, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715, -715 }, { 55, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, -716 }, { 55, 717, 717, 717, 717, 717, 717, 717, 717, 717, 718, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 719, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 720, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717 }, { 55, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718, -718 }, { 55, 717, 717, 717, 717, 717, 717, 717, 717, 717, 718, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 719, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 720, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717 }, { 55, 717, 717, 717, 717, 717, 717, 717, 717, 717, 718, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 719, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 720, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717 }, { 55, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, 904, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, -721 }, { 55, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, 905, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, -722 }, { 55, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, 906, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723 }, { 55, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, 907, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724, -724 }, { 55, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, 908, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, -725 }, { 55, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, 909, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726, -726 }, { 55, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, 910, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727, -727 }, { 55, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, 911, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728, -728 }, { 55, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, 912, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, -729 }, { 55, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, 913, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730, -730 }, { 55, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, 914, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731, -731 }, { 55, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, 915, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732, -732 }, { 55, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, 916, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733, -733 }, { 55, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, 917, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734, -734 }, { 55, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, 918, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735, -735 }, { 55, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, 919, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736, -736 }, { 55, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, 920, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737, -737 }, { 55, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, 921, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738, -738 }, { 55, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, 922, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739 }, { 55, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, 923, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740 }, { 55, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, 924, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, -741 }, { 55, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, 925, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, -742 }, { 55, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, 926, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743, -743 }, { 55, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, 927, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, 928, -744, -744, 929, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, -744 }, { 55, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, 930, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, -745 }, { 55, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, 931, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746, -746 }, { 55, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, 932, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747, -747 }, { 55, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, 933, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748, -748 }, { 55, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, 934, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749, -749 }, { 55, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, 935, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750, -750 }, { 55, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, 936, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751, -751 }, { 55, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, 937, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752, -752 }, { 55, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, 938, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753, -753 }, { 55, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, 939, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754, -754 }, { 55, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, 940, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755, -755 }, { 55, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, 941, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, 942, -756, -756, 943, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756, -756 }, { 55, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, 944, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757, -757 }, { 55, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, 945, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758, -758 }, { 55, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, 946, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759, -759 }, { 55, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, 947, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760, -760 }, { 55, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, 948, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761, -761 }, { 55, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, 949, -762, -762, -762, -762, -762, -762, -762, -762, 950, -762, -762, -762, -762, -762, 951, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762, -762 }, { 55, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, 952, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763, -763 }, { 55, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, 953, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764 }, { 55, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, 954, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765 }, { 55, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, 955, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766 }, { 55, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, 956, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767, -767 }, { 55, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, 957, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768, -768 }, { 55, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, 958, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769, -769 }, { 55, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, 959, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, 960, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770, -770 }, { 55, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, 961, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771, -771 }, { 55, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, 962, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772, -772 }, { 55, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, 963, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773, -773 }, { 55, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, 964, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774, -774 }, { 55, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, 965, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775 }, { 55, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, 966, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776, -776 }, { 55, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, 967, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777, -777 }, { 55, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, 968, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778, -778 }, { 55, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, 969, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779, -779 }, { 55, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, 970, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780, -780 }, { 55, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, 971, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781, -781 }, { 55, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, 972, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782, -782 }, { 55, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, 973, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783, -783 }, { 55, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, 974, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784, -784 }, { 55, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, 975, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785, -785 }, { 55, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, 976, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786, -786 }, { 55, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, 977, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787, -787 }, { 55, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, 978, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788, -788 }, { 55, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, 979, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789 }, { 55, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, 980, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, 980, 980, 980, 980, 980, 980, 980, 980, 980, 980, 980, 980, 980, 980, 980, 980, 980, 980, 980, 980, 980, 980, 980, 980, 980, 980, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790 }, { 55, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, 981, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791 }, { 55, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, 982, 982, 982, 982, 982, 982, 982, 982, 982, 982, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792, -792 }, { 55, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, 983, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793, -793 }, { 55, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, 984, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794, -794 }, { 55, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, 985, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795, -795 }, { 55, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, 986, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796, -796 }, { 55, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, 987, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797, -797 }, { 55, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, 988, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798, -798 }, { 55, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799, -799 }, { 55, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800, -800 }, { 55, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801, -801 }, { 55, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802, -802 }, { 55, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803, -803 }, { 55, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804, -804 }, { 55, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805, -805 }, { 55, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806, -806 }, { 55, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807, -807 }, { 55, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808 }, { 55, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809, -809 }, { 55, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810 }, { 55, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811, -811 }, { 55, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812, -812 }, { 55, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813, -813 }, { 55, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814, -814 }, { 55, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815, -815 }, { 55, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816, -816 }, { 55, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817, -817 }, { 55, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818, -818 }, { 55, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819, -819 }, { 55, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820, -820 }, { 55, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821, -821 }, { 55, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822, -822 }, { 55, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823 }, { 55, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824 }, { 55, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825 }, { 55, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826 }, { 55, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827 }, { 55, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828 }, { 55, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829 }, { 55, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830, -830 }, { 55, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831, -831 }, { 55, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832, -832 }, { 55, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833 }, { 55, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834, -834 }, { 55, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835 }, { 55, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836 }, { 55, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837 }, { 55, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838 }, { 55, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839 }, { 55, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840 }, { 55, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841 }, { 55, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842, -842 }, { 55, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843, -843 }, { 55, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844, -844 }, { 55, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845, -845 }, { 55, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846, -846 }, { 55, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847, -847 }, { 55, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848 }, { 55, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849, -849 }, { 55, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850, -850 }, { 55, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851, -851 }, { 55, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852, -852 }, { 55, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853, -853 }, { 55, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854 }, { 55, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855 }, { 55, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856 }, { 55, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857 }, { 55, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858 }, { 55, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859 }, { 55, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860 }, { 55, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861 }, { 55, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, -862 }, { 55, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863, -863 }, { 55, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864, -864 }, { 55, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865, -865 }, { 55, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866, -866 }, { 55, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867, -867 }, { 55, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, -868 }, { 55, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869, -869 }, { 55, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870 }, { 55, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871, -871 }, { 55, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, -872 }, { 55, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, -873 }, { 55, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874, -874 }, { 55, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875, -875 }, { 55, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876, -876 }, { 55, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877, -877 }, { 55, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878, -878 }, { 55, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879, -879 }, { 55, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880, -880 }, { 55, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881, -881 }, { 55, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882, -882 }, { 55, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883, -883 }, { 55, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884, -884 }, { 55, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885, -885 }, { 55, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886, -886 }, { 55, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887, -887 }, { 55, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888, -888 }, { 55, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889, -889 }, { 55, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890, -890 }, { 55, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891, -891 }, { 55, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892, -892 }, { 55, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893 }, { 55, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894, -894 }, { 55, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895 }, { 55, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896 }, { 55, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897, -897 }, { 55, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898, -898 }, { 55, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899, -899 }, { 55, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900 }, { 55, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901, -901 }, { 55, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902, -902 }, { 55, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903, -903 }, { 55, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, 989, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904, -904 }, { 55, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, 990, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905, -905 }, { 55, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, 991, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906, -906 }, { 55, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, 992, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907, -907 }, { 55, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, 993, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908, -908 }, { 55, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, 994, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909, -909 }, { 55, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, 995, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910, -910 }, { 55, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, 996, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911, -911 }, { 55, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, 997, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912, -912 }, { 55, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, 998, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913, -913 }, { 55, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, 999, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914, -914 }, { 55, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, 1000, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915, -915 }, { 55, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, 1001, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916, -916 }, { 55, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, 1002, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917, -917 }, { 55, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, 1003, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918, -918 }, { 55, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, 1004, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919, -919 }, { 55, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, 1005, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920, -920 }, { 55, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, 1006, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921, -921 }, { 55, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, 1007, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922, -922 }, { 55, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, 1008, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923, -923 }, { 55, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924, -924 }, { 55, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, 1009, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925, -925 }, { 55, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, 1010, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926, -926 }, { 55, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, 1011, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927, -927 }, { 55, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928, -928 }, { 55, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929, -929 }, { 55, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, 1012, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930, -930 }, { 55, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, 1013, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931, -931 }, { 55, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, 1014, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932, -932 }, { 55, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, 1015, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933, -933 }, { 55, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934, -934 }, { 55, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935, -935 }, { 55, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, 1016, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936, -936 }, { 55, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, 1017, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937 }, { 55, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, 1018, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938, -938 }, { 55, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, 1019, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939, -939 }, { 55, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, 1020, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, 1021, -940, -940, 1022, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940, -940 }, { 55, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, 1023, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941, -941 }, { 55, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, 1024, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942, -942 }, { 55, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, 1025, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943, -943 }, { 55, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, 1026, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944, -944 }, { 55, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, 1027, -945, -945, -945, -945, -945, 1028, -945, -945, -945, 1029, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, 1030, 1031, 1032, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945 }, { 55, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, 1033, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946, -946 }, { 55, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, 1034, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947, -947 }, { 55, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, 1035, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948, -948 }, { 55, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, 1036, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949, -949 }, { 55, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, 1037, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950, -950 }, { 55, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, 1038, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, 1039, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951, -951 }, { 55, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, 1040, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952, -952 }, { 55, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, 1041, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953, -953 }, { 55, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, 1042, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954, -954 }, { 55, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, 1043, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955, -955 }, { 55, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, 1044, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956, -956 }, { 55, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, 1045, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957, -957 }, { 55, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958, -958 }, { 55, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, 1046, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959, -959 }, { 55, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960, -960 }, { 55, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961, -961 }, { 55, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, 1047, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962, -962 }, { 55, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963, -963 }, { 55, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964, -964 }, { 55, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965, -965 }, { 55, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, 1048, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966, -966 }, { 55, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, 1049, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967, -967 }, { 55, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, 1050, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968, -968 }, { 55, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, 1051, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969, -969 }, { 55, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, 1052, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970, -970 }, { 55, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, 1053, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971, -971 }, { 55, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, 1054, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972, -972 }, { 55, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, 1055, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973, -973 }, { 55, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, 1056, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974, -974 }, { 55, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, 1057, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975, -975 }, { 55, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, 1058, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976, -976 }, { 55, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, 1059, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977, -977 }, { 55, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978, -978 }, { 55, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979, -979 }, { 55, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, 1060, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980, -980 }, { 55, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, 1061, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981, -981 }, { 55, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982, -982 }, { 55, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, 1063, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983, -983 }, { 55, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984, -984 }, { 55, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, 1064, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985, -985 }, { 55, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, 1065, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986, -986 }, { 55, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, 1066, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987, -987 }, { 55, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988, -988 }, { 55, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989, -989 }, { 55, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990 }, { 55, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991, -991 }, { 55, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992, -992 }, { 55, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993, -993 }, { 55, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994, -994 }, { 55, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995, -995 }, { 55, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996, -996 }, { 55, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997, -997 }, { 55, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998, -998 }, { 55, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999 }, { 55,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000 }, { 55,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001, -1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001, -1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001, -1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001, -1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001, -1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001, -1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001, -1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001, -1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001, -1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001, -1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001, -1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001, -1001,-1001,-1001,-1001,-1001,-1001,-1001,-1001 }, { 55,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002, -1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002, -1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002, -1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002, -1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002, -1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002, -1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002, -1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002, -1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002, -1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002, -1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002, -1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002, -1002,-1002,-1002,-1002,-1002,-1002,-1002,-1002 }, { 55,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003, -1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003, -1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003, -1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003, -1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003, -1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003, -1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003, -1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003, -1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003, -1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003, -1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003, -1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003, -1003,-1003,-1003,-1003,-1003,-1003,-1003,-1003 }, { 55,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004, -1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004, -1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004, -1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004, -1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004, -1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004, -1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004, -1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004, -1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004, -1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004, -1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004, -1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004, -1004,-1004,-1004,-1004,-1004,-1004,-1004,-1004 }, { 55,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005, -1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005, -1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005, -1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005, -1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005, -1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005, -1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005, -1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005, -1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005, -1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005, -1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005, -1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005, -1005,-1005,-1005,-1005,-1005,-1005,-1005,-1005 }, { 55,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006, -1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006, -1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006, -1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006, -1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006, -1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006, -1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006, -1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006, -1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006, -1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006, -1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006, -1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006, -1006,-1006,-1006,-1006,-1006,-1006,-1006,-1006 }, { 55,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007, -1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007, -1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007, -1007,-1007, 1067,-1007,-1007,-1007,-1007,-1007,-1007,-1007, -1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007, -1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007, -1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007, -1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007, -1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007, -1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007, -1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007, -1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007, -1007,-1007,-1007,-1007,-1007,-1007,-1007,-1007 }, { 55,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008, -1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008, -1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008, -1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008, -1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008, -1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008, -1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008, -1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008, -1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008, -1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008, -1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008, -1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008, -1008,-1008,-1008,-1008,-1008,-1008,-1008,-1008 }, { 55,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009, -1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009, -1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009, -1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009, -1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009, -1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009, -1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009, -1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009, -1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009, -1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009, -1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009, -1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009, -1009,-1009,-1009,-1009,-1009,-1009,-1009,-1009 }, { 55,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010, -1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010, -1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010, -1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010, -1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010, -1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010, -1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010, -1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010, -1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010, -1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010, -1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010, -1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010, -1010,-1010,-1010,-1010,-1010,-1010,-1010,-1010 }, { 55,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011, -1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011, -1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011, -1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011, -1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011, -1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011, -1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011, -1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011, -1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011, -1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011, -1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011, -1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011, -1011,-1011,-1011,-1011,-1011,-1011,-1011,-1011 }, { 55,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012, -1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012, -1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012, -1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012, -1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012, -1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012, -1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012, -1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012, -1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012, -1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012, -1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012, -1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012, -1012,-1012,-1012,-1012,-1012,-1012,-1012,-1012 }, { 55,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013, -1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013, -1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013, -1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013, -1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013, -1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013, -1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013, -1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013, -1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013, -1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013, -1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013, -1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013, -1013,-1013,-1013,-1013,-1013,-1013,-1013,-1013 }, { 55,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014, -1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014, -1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014, -1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014, -1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014, -1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014, -1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014, -1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014, -1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014, -1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014, -1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014, -1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014, -1014,-1014,-1014,-1014,-1014,-1014,-1014,-1014 }, { 55,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015, -1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015, -1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015, -1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015, -1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015, -1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015, -1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015, -1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015, -1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015, -1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015, -1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015, -1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015, -1015,-1015,-1015,-1015,-1015,-1015,-1015,-1015 }, { 55,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016, -1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016, -1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016, -1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016, -1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016, -1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016, -1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016, -1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016, -1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016, -1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016, -1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016, -1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016, -1016,-1016,-1016,-1016,-1016,-1016,-1016,-1016 }, { 55,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017, -1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017, -1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017, -1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017, -1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017, -1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017, -1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017, -1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017, -1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017, -1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017, -1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017, -1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017, -1017,-1017,-1017,-1017,-1017,-1017,-1017,-1017 }, { 55,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018, -1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018, -1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018, -1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018, -1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018, -1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018, -1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018, -1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018, -1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018, -1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018, -1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018, -1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018, -1018,-1018,-1018,-1018,-1018,-1018,-1018,-1018 }, { 55,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019, -1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019, -1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019, -1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019, -1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019, -1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019, -1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019, -1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019, -1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019, -1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019, -1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019, -1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019, -1019,-1019,-1019,-1019,-1019,-1019,-1019,-1019 }, { 55,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020, -1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020, -1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020, -1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020, -1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020, -1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020, -1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020, -1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020, -1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020, -1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020, -1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020, -1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020, -1020,-1020,-1020,-1020,-1020,-1020,-1020,-1020 }, { 55,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021, -1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021, -1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021, -1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021, -1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021, -1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021, -1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021, -1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021, -1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021, -1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021, -1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021, -1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021, -1021,-1021,-1021,-1021,-1021,-1021,-1021,-1021 }, { 55,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022, -1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022, -1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022, -1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022, -1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022, -1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022, -1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022, -1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022, -1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022, -1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022, -1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022, -1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022, -1022,-1022,-1022,-1022,-1022,-1022,-1022,-1022 }, { 55,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023, -1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023, -1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023, -1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023, -1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023, -1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023, -1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023, -1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023, -1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023, -1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023, -1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023, -1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023, -1023,-1023,-1023,-1023,-1023,-1023,-1023,-1023 }, { 55,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024, -1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024, -1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024, -1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024, -1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024, -1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024, -1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024, -1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024, -1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024, -1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024, -1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024, -1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024, -1024,-1024,-1024,-1024,-1024,-1024,-1024,-1024 }, { 55,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025, -1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025, -1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025, -1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025, -1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025, -1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025, -1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025, -1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025, -1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025, -1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025, -1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025, -1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025, -1025,-1025,-1025,-1025,-1025,-1025,-1025,-1025 }, { 55,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026, -1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026, -1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026, -1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026, -1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026, -1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026, -1026, 1068,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026, -1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026, -1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026, -1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026, -1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026, -1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026, -1026,-1026,-1026,-1026,-1026,-1026,-1026,-1026 }, { 55,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027, -1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027, -1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027, -1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027, -1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027, -1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027, -1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027, -1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027, -1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027, -1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027, -1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027, -1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027, -1027,-1027,-1027,-1027,-1027,-1027,-1027,-1027 }, { 55,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028, -1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028, -1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028, -1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028, -1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028, -1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028, -1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028, -1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028, -1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028, -1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028, -1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028, -1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028, -1028,-1028,-1028,-1028,-1028,-1028,-1028,-1028 }, { 55,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029, -1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029, -1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029, -1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029, -1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029, -1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029, -1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029, -1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029, -1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029, -1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029, -1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029, -1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029, -1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029 }, { 55,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030, -1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030, -1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030, -1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030, -1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030, -1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030, -1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030, -1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030, -1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030, -1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030, -1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030, -1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030, -1030,-1030,-1030,-1030,-1030,-1030,-1030,-1030 }, { 55,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031, -1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031, -1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031, -1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031, -1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031, -1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031, -1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031, -1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031, -1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031, -1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031, -1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031, -1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031, -1031,-1031,-1031,-1031,-1031,-1031,-1031,-1031 }, { 55,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032, -1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032, -1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032, -1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032, -1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032, -1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032, -1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032, -1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032, -1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032, -1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032, -1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032, -1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032, -1032,-1032,-1032,-1032,-1032,-1032,-1032,-1032 }, { 55,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033, -1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033, -1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033, -1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033, -1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033, -1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033, -1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033, -1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033, -1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033, -1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033, -1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033, -1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033, -1033,-1033,-1033,-1033,-1033,-1033,-1033,-1033 }, { 55,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034, -1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034, -1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034, -1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034, -1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034, -1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034, -1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034, -1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034, -1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034, -1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034, -1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034, -1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034, -1034,-1034,-1034,-1034,-1034,-1034,-1034,-1034 }, { 55,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035, -1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035, -1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035, -1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035, -1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035, -1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035, -1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035, -1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035, -1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035, -1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035, -1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035, -1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035, -1035,-1035,-1035,-1035,-1035,-1035,-1035,-1035 }, { 55,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036, -1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036, -1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036, -1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036, -1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036, -1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036, -1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036, -1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036, -1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036, -1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036, -1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036, -1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036, -1036,-1036,-1036,-1036,-1036,-1036,-1036,-1036 }, { 55,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037, -1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037, -1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037, -1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037, -1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037, -1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037, -1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037, -1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037, -1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037, -1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037, -1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037, -1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037, -1037,-1037,-1037,-1037,-1037,-1037,-1037,-1037 }, { 55,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038, -1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038, -1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038, -1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038, -1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038, -1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038, -1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038, -1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038, -1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038, -1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038, -1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038, -1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038, -1038,-1038,-1038,-1038,-1038,-1038,-1038,-1038 }, { 55,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039, -1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039, -1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039, -1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039, -1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039, -1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039, -1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039, -1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039, -1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039, -1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039, -1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039, -1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039, -1039,-1039,-1039,-1039,-1039,-1039,-1039,-1039 }, { 55,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040, -1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040, -1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040, -1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040, -1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040, -1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040, -1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040, -1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040, -1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040, -1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040, -1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040, -1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040, -1040,-1040,-1040,-1040,-1040,-1040,-1040,-1040 }, { 55,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041, -1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041, -1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041, -1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041, -1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041, -1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041, -1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041, -1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041, -1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041, -1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041, -1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041, -1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041, -1041,-1041,-1041,-1041,-1041,-1041,-1041,-1041 }, { 55,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042, -1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042, -1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042, -1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042, -1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042, -1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042, -1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042, -1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042, -1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042, -1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042, -1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042, -1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042, -1042,-1042,-1042,-1042,-1042,-1042,-1042,-1042 }, { 55,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043, -1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043, -1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043, -1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043, -1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043, -1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043, -1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043, -1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043, -1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043, -1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043, -1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043, -1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043, -1043,-1043,-1043,-1043,-1043,-1043,-1043,-1043 }, { 55,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044, -1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044, -1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044, -1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044, -1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044, -1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044, -1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044, -1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044, -1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044, -1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044, -1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044, -1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044, -1044,-1044,-1044,-1044,-1044,-1044,-1044,-1044 }, { 55,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045, -1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045, -1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045, -1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045, -1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045, -1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045, -1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045, -1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045, -1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045, -1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045, -1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045, -1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045, -1045,-1045,-1045,-1045,-1045,-1045,-1045,-1045 }, { 55,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046, -1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046, -1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046, -1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046, -1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046, -1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046, -1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046, -1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046, -1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046, -1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046, -1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046, -1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046, -1046,-1046,-1046,-1046,-1046,-1046,-1046,-1046 }, { 55,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047, -1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047, -1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047, -1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047, -1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047, -1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047, -1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047, -1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047, -1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047, -1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047, -1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047, -1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047, -1047,-1047,-1047,-1047,-1047,-1047,-1047,-1047 }, { 55,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048, -1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048, -1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048, -1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048, -1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048, -1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048, -1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048, -1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048, -1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048, -1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048, -1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048, -1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048, -1048,-1048,-1048,-1048,-1048,-1048,-1048,-1048 }, { 55,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049, -1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049, -1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049, -1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049, -1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049, -1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049, -1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049, -1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049, -1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049, -1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049, -1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049, -1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049, -1049,-1049,-1049,-1049,-1049,-1049,-1049,-1049 }, { 55,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050, -1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050, -1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050, -1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050, -1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050, -1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050, -1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050, -1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050, -1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050, -1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050, -1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050, -1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050, -1050,-1050,-1050,-1050,-1050,-1050,-1050,-1050 }, { 55,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051, -1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051, -1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051, -1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051, -1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051, -1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051, -1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051, -1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051, -1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051, -1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051, -1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051, -1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051, -1051,-1051,-1051,-1051,-1051,-1051,-1051,-1051 }, { 55,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052, -1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052, -1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052, -1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052, -1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052, -1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052, -1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052, -1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052, -1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052, -1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052, -1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052, -1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052, -1052,-1052,-1052,-1052,-1052,-1052,-1052,-1052 }, { 55,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053, -1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053, -1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053, -1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053, -1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053, -1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053, -1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053, -1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053, -1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053, -1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053, -1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053, -1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053, -1053,-1053,-1053,-1053,-1053,-1053,-1053,-1053 }, { 55,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054, -1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054, -1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054, -1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054, -1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054, -1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054, -1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054, -1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054, -1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054, -1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054, -1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054, -1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054, -1054,-1054,-1054,-1054,-1054,-1054,-1054,-1054 }, { 55,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055, -1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055, -1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055, -1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055, -1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055, -1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055, -1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055, -1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055, -1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055, -1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055, -1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055, -1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055, -1055,-1055,-1055,-1055,-1055,-1055,-1055,-1055 }, { 55,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056, -1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056, -1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056, -1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056, -1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056, -1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056, -1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056, -1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056, -1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056, -1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056, -1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056, -1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056, -1056,-1056,-1056,-1056,-1056,-1056,-1056,-1056 }, { 55,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057, -1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057, -1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057, -1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057, -1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057, -1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057, -1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057, -1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057, -1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057, -1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057, -1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057, -1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057, -1057,-1057,-1057,-1057,-1057,-1057,-1057,-1057 }, { 55,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058, -1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058, -1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058, -1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058, -1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058, -1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058, -1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058, -1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058, -1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058, -1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058, -1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058, -1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058, -1058,-1058,-1058,-1058,-1058,-1058,-1058,-1058 }, { 55,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059, -1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059, -1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059, -1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059, -1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059, -1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059, -1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059, -1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059, -1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059, -1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059, -1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059, -1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059, -1059,-1059,-1059,-1059,-1059,-1059,-1059,-1059 }, { 55,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060, -1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060, -1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060, -1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060, -1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060, -1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060, -1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060, -1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060, -1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060, -1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060, -1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060, -1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060, -1060,-1060,-1060,-1060,-1060,-1060,-1060,-1060 }, { 55,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061, -1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061, -1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061, -1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061, -1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061, -1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061, -1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061, -1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061, -1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061, -1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061, -1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061, -1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061, -1061,-1061,-1061,-1061,-1061,-1061,-1061,-1061 }, { 55,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062, -1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062, -1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062, -1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062, -1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062, -1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062, -1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062, -1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062, -1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062, -1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062, -1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062, -1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062, -1062,-1062,-1062,-1062,-1062,-1062,-1062,-1062 }, { 55,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063, -1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063, -1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063, -1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063, -1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063, -1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063, -1063, 1069,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063, -1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063, -1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063, -1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063, -1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063, -1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063, -1063,-1063,-1063,-1063,-1063,-1063,-1063,-1063 }, { 55,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064, -1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064, -1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064, -1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064, -1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064, -1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064, -1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064, -1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064, -1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064, -1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064, -1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064, -1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064, -1064,-1064,-1064,-1064,-1064,-1064,-1064,-1064 }, { 55,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065, -1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065, -1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065, -1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065, -1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065, -1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065, -1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065, -1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065, -1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065, -1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065, -1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065, -1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065, -1065,-1065,-1065,-1065,-1065,-1065,-1065,-1065 }, { 55,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066, -1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066, -1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066, -1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066, -1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066, -1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066, -1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066, -1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066, -1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066, -1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066, -1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066, -1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066, -1066,-1066,-1066,-1066,-1066,-1066,-1066,-1066 }, { 55,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067, -1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067, -1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067, -1067,-1067, 1070,-1067,-1067,-1067,-1067,-1067,-1067,-1067, -1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067, -1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067, -1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067, -1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067, -1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067, -1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067, -1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067, -1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067, -1067,-1067,-1067,-1067,-1067,-1067,-1067,-1067 }, { 55,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068, -1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068, -1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068, -1068,-1068, 1071,-1068,-1068,-1068,-1068,-1068,-1068,-1068, -1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068, -1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068, -1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068, -1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068, -1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068, -1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068, -1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068, -1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068, -1068,-1068,-1068,-1068,-1068,-1068,-1068,-1068 }, { 55,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069, -1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069, -1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069, -1069,-1069, 1072,-1069,-1069,-1069,-1069,-1069,-1069,-1069, -1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069, -1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069, -1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069, -1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069, -1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069, -1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069, -1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069, -1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069, -1069,-1069,-1069,-1069,-1069,-1069,-1069,-1069 }, { 55,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070, -1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070, -1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070, -1070,-1070, 1073,-1070,-1070,-1070,-1070,-1070,-1070,-1070, -1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070, -1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070, -1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070, -1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070, -1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070, -1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070, -1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070, -1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070, -1070,-1070,-1070,-1070,-1070,-1070,-1070,-1070 }, { 55,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071, -1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071, -1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071, -1071,-1071, 1074,-1071,-1071,-1071,-1071,-1071,-1071,-1071, -1071,-1071,-1071, 1075,-1071, 1075,-1071,-1071, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076,-1071,-1071, -1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071, -1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071, -1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071, -1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071, -1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071, -1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071, -1071,-1071,-1071,-1071,-1071,-1071,-1071,-1071 }, { 55,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072, -1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072, -1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072, -1072,-1072, 1077,-1072,-1072,-1072,-1072,-1072,-1072,-1072, -1072,-1072,-1072, 1078,-1072, 1078,-1072,-1072, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079,-1072,-1072, -1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072, -1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072, -1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072, -1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072, -1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072, -1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072, -1072,-1072,-1072,-1072,-1072,-1072,-1072,-1072 }, { 55,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073, -1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073, -1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073, -1073,-1073, 1080,-1073,-1073,-1073,-1073,-1073,-1073,-1073, -1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073, -1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073, -1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073, -1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073, -1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073, -1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073, -1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073, -1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073, -1073,-1073,-1073,-1073,-1073,-1073,-1073,-1073 }, { 55,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074, -1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074, -1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074, -1074,-1074, 1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074, -1074,-1074,-1074, 1075,-1074, 1075,-1074,-1074, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076,-1074,-1074, -1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074, -1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074, -1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074, -1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074, -1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074, -1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074, -1074,-1074,-1074,-1074,-1074,-1074,-1074,-1074 }, { 55,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075, -1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075, -1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075, -1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075, -1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076,-1075,-1075, -1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075, -1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075, -1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075, -1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075, -1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075, -1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075, -1075,-1075,-1075,-1075,-1075,-1075,-1075,-1075 }, { 55,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076, -1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076, -1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076, -1076,-1076, 1081,-1076,-1076,-1076,-1076,-1076,-1076,-1076, -1076,-1076,-1076,-1076,-1076,-1076,-1076, 1082, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076,-1076,-1076, -1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076, -1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076, -1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076, -1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076, -1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076, -1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076, -1076,-1076,-1076,-1076,-1076,-1076,-1076,-1076 }, { 55,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077, -1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077, -1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077, -1077,-1077, 1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077, -1077,-1077,-1077, 1078,-1077, 1078,-1077,-1077, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079,-1077,-1077, -1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077, -1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077, -1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077, -1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077, -1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077, -1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077, -1077,-1077,-1077,-1077,-1077,-1077,-1077,-1077 }, { 55,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078, -1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078, -1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078, -1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078, -1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079,-1078,-1078, -1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078, -1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078, -1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078, -1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078, -1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078, -1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078, -1078,-1078,-1078,-1078,-1078,-1078,-1078,-1078 }, { 55,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079, -1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079, -1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079, -1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079, -1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079,-1079,-1079, -1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079, -1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079, -1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079, -1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079, -1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079, -1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079, -1079,-1079,-1079,-1079,-1079,-1079,-1079,-1079 }, { 55,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080, -1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080, -1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080, -1080,-1080, 1083,-1080,-1080,-1080,-1080,-1080,-1080,-1080, -1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080, -1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080, -1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080, -1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080, -1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080, -1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080, -1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080, -1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080, -1080,-1080,-1080,-1080,-1080,-1080,-1080,-1080 }, { 55,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081, -1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081, -1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081, -1081,-1081, 1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081, -1081,-1081,-1081,-1081,-1081,-1081,-1081, 1082,-1081,-1081, -1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081, -1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081, -1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081, -1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081, -1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081, -1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081, -1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081, -1081,-1081,-1081,-1081,-1081,-1081,-1081,-1081 }, { 55, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, -1082, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084 }, { 55,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083, -1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083, -1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083, -1083,-1083, 1085,-1083,-1083,-1083,-1083,-1083,-1083,-1083, -1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083, -1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083, -1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083, -1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083, -1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083, -1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083, -1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083, -1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083, -1083,-1083,-1083,-1083,-1083,-1083,-1083,-1083 }, { 55, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, -1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084 }, { 55,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085, -1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085, -1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085, -1085,-1085, 1086,-1085,-1085,-1085,-1085,-1085,-1085,-1085, -1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085, -1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085, -1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085, -1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085, -1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085, -1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085, -1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085, -1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085, -1085,-1085,-1085,-1085,-1085,-1085,-1085,-1085 }, { 55,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086, -1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086, -1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086, -1086,-1086, 1087,-1086,-1086,-1086,-1086,-1086,-1086,-1086, -1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086, -1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086, -1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086, -1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086, -1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086, -1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086, -1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086, -1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086, -1086,-1086,-1086,-1086,-1086,-1086,-1086,-1086 }, { 55,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087, -1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087, -1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087, -1087,-1087, 1088,-1087,-1087,-1087,-1087,-1087,-1087,-1087, -1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087, -1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087, -1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087, -1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087, -1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087, -1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087, -1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087, -1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087, -1087,-1087,-1087,-1087,-1087,-1087,-1087,-1087 }, { 55,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088, -1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088, -1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088, -1088,-1088, 1089,-1088,-1088,-1088,-1088,-1088,-1088,-1088, -1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088, -1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088, -1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088, -1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088, -1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088, -1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088, -1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088, -1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088, -1088,-1088,-1088,-1088,-1088,-1088,-1088,-1088 }, { 55,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089, -1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089, -1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089, -1089,-1089, 1090,-1089,-1089,-1089,-1089,-1089,-1089,-1089, -1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089, -1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089, -1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089, -1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089, -1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089, -1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089, -1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089, -1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089, -1089,-1089,-1089,-1089,-1089,-1089,-1089,-1089 }, { 55,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090, -1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090, -1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090, -1090,-1090, 1091,-1090,-1090,-1090,-1090,-1090,-1090,-1090, -1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090, -1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090, -1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090, -1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090, -1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090, -1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090, -1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090, -1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090, -1090,-1090,-1090,-1090,-1090,-1090,-1090,-1090 }, { 55,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091, -1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091, -1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091, -1091,-1091, 1092,-1091,-1091,-1091,-1091,-1091,-1091,-1091, -1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091, -1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091, -1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091, -1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091, -1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091, -1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091, -1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091, -1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091, -1091,-1091,-1091,-1091,-1091,-1091,-1091,-1091 }, { 55,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092, -1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092, -1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092, -1092,-1092, 1093,-1092,-1092,-1092,-1092,-1092,-1092,-1092, -1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092, -1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092, -1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092, -1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092, -1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092, -1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092, -1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092, -1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092, -1092,-1092,-1092,-1092,-1092,-1092,-1092,-1092 }, { 55,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093, -1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093, -1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093, -1093,-1093, 1094,-1093,-1093,-1093,-1093,-1093,-1093,-1093, -1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093, -1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093, -1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093, -1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093, -1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093, -1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093, -1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093, -1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093, -1093,-1093,-1093,-1093,-1093,-1093,-1093,-1093 }, { 55,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094, -1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094, -1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094, -1094,-1094, 1095,-1094,-1094,-1094,-1094,-1094,-1094,-1094, -1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094, -1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094, -1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094, -1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094, -1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094, -1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094, -1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094, -1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094, -1094,-1094,-1094,-1094,-1094,-1094,-1094,-1094 }, { 55,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095, -1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095, -1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095, -1095,-1095, 1096,-1095,-1095,-1095,-1095,-1095,-1095,-1095, -1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095, -1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095, -1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095, -1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095, -1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095, -1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095, -1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095, -1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095, -1095,-1095,-1095,-1095,-1095,-1095,-1095,-1095 }, { 55,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096, -1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096, -1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096, -1096,-1096, 1097,-1096,-1096,-1096,-1096,-1096,-1096,-1096, -1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096, -1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096, -1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096, -1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096, -1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096, -1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096, -1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096, -1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096, -1096,-1096,-1096,-1096,-1096,-1096,-1096,-1096 }, { 55,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097, -1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097, -1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097, -1097,-1097, 1098,-1097,-1097,-1097,-1097,-1097,-1097,-1097, -1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097, -1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097, -1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097, -1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097, -1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097, -1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097, -1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097, -1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097, -1097,-1097,-1097,-1097,-1097,-1097,-1097,-1097 }, { 55,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098, -1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098, -1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098, -1098,-1098, 1099,-1098,-1098,-1098,-1098,-1098,-1098,-1098, -1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098, -1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098, -1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098, -1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098, -1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098, -1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098, -1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098, -1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098, -1098,-1098,-1098,-1098,-1098,-1098,-1098,-1098 }, { 55,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099, -1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099, -1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099, -1099,-1099, 1100,-1099,-1099,-1099,-1099,-1099,-1099,-1099, -1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099, -1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099, -1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099, -1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099, -1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099, -1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099, -1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099, -1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099, -1099,-1099,-1099,-1099,-1099,-1099,-1099,-1099 }, { 55,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100, -1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100, -1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100, -1100,-1100, 1101,-1100,-1100,-1100,-1100,-1100,-1100,-1100, -1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100, -1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100, -1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100, -1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100, -1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100, -1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100, -1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100, -1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100, -1100,-1100,-1100,-1100,-1100,-1100,-1100,-1100 }, { 55,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101, -1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101, -1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101, -1101,-1101, 1102,-1101,-1101,-1101,-1101,-1101,-1101,-1101, -1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101, -1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101, -1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101, -1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101, -1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101, -1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101, -1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101, -1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101, -1101,-1101,-1101,-1101,-1101,-1101,-1101,-1101 }, { 55,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102, -1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102, -1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102, -1102,-1102, 1103,-1102,-1102,-1102,-1102,-1102,-1102,-1102, -1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102, -1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102, -1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102, -1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102, -1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102, -1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102, -1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102, -1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102, -1102,-1102,-1102,-1102,-1102,-1102,-1102,-1102 }, { 55,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103, -1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103, -1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103, -1103,-1103, 1104,-1103,-1103,-1103,-1103,-1103,-1103,-1103, -1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103, -1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103, -1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103, -1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103, -1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103, -1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103, -1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103, -1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103, -1103,-1103,-1103,-1103,-1103,-1103,-1103,-1103 }, { 55,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104, -1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104, -1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104, -1104,-1104, 1105,-1104,-1104,-1104,-1104,-1104,-1104,-1104, -1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104, -1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104, -1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104, -1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104, -1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104, -1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104, -1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104, -1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104, -1104,-1104,-1104,-1104,-1104,-1104,-1104,-1104 }, { 55,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105, -1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105, -1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105, -1105,-1105, 1106,-1105,-1105,-1105,-1105,-1105,-1105,-1105, -1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105, -1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105, -1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105, -1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105, -1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105, -1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105, -1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105, -1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105, -1105,-1105,-1105,-1105,-1105,-1105,-1105,-1105 }, { 55,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106, -1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106, -1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106, -1106,-1106, 1107,-1106,-1106,-1106,-1106,-1106,-1106,-1106, -1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106, -1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106, -1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106, -1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106, -1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106, -1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106, -1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106, -1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106, -1106,-1106,-1106,-1106,-1106,-1106,-1106,-1106 }, { 55,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107, -1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107, -1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107, -1107,-1107, 1108,-1107,-1107,-1107,-1107,-1107,-1107,-1107, -1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107, -1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107, -1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107, -1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107, -1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107, -1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107, -1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107, -1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107, -1107,-1107,-1107,-1107,-1107,-1107,-1107,-1107 }, { 55,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108, -1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108, -1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108, -1108,-1108, 1109,-1108,-1108,-1108,-1108,-1108,-1108,-1108, -1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108, -1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108, -1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108, -1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108, -1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108, -1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108, -1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108, -1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108, -1108,-1108,-1108,-1108,-1108,-1108,-1108,-1108 }, { 55,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109, -1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109, -1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109, -1109,-1109, 1110,-1109,-1109,-1109,-1109,-1109,-1109,-1109, -1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109, -1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109, -1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109, -1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109, -1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109, -1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109, -1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109, -1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109, -1109,-1109,-1109,-1109,-1109,-1109,-1109,-1109 }, { 55,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110, -1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110, -1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110, -1110,-1110, 1111,-1110,-1110,-1110,-1110,-1110,-1110,-1110, -1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110, -1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110, -1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110, -1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110, -1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110, -1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110, -1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110, -1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110, -1110,-1110,-1110,-1110,-1110,-1110,-1110,-1110 }, { 55,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111, -1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111, -1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111, -1111,-1111, 1112,-1111,-1111,-1111,-1111,-1111,-1111,-1111, -1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111, -1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111, -1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111, -1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111, -1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111, -1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111, -1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111, -1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111, -1111,-1111,-1111,-1111,-1111,-1111,-1111,-1111 }, { 55,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112, -1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112, -1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112, -1112,-1112, 1113,-1112,-1112,-1112,-1112,-1112,-1112,-1112, -1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112, -1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112, -1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112, -1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112, -1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112, -1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112, -1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112, -1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112, -1112,-1112,-1112,-1112,-1112,-1112,-1112,-1112 }, { 55,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113, -1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113, -1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113, -1113,-1113, 1114,-1113,-1113,-1113,-1113,-1113,-1113,-1113, -1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113, -1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113, -1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113, -1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113, -1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113, -1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113, -1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113, -1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113, -1113,-1113,-1113,-1113,-1113,-1113,-1113,-1113 }, { 55,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114, -1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114, -1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114, -1114,-1114, 1115,-1114,-1114,-1114,-1114,-1114,-1114,-1114, -1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114, -1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114, -1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114, -1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114, -1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114, -1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114, -1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114, -1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114, -1114,-1114,-1114,-1114,-1114,-1114,-1114,-1114 }, { 55,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115, -1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115, -1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115, -1115,-1115, 1116,-1115,-1115,-1115,-1115,-1115,-1115,-1115, -1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115, -1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115, -1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115, -1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115, -1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115, -1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115, -1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115, -1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115, -1115,-1115,-1115,-1115,-1115,-1115,-1115,-1115 }, { 55,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116, -1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116, -1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116, -1116,-1116, 1117,-1116,-1116,-1116,-1116,-1116,-1116,-1116, -1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116, -1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116, -1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116, -1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116, -1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116, -1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116, -1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116, -1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116, -1116,-1116,-1116,-1116,-1116,-1116,-1116,-1116 }, { 55,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117, -1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117, -1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117, -1117,-1117, 1118,-1117,-1117,-1117,-1117,-1117,-1117,-1117, -1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117, -1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117, -1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117, -1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117, -1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117, -1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117, -1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117, -1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117, -1117,-1117,-1117,-1117,-1117,-1117,-1117,-1117 }, { 55,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118, -1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118, -1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118, -1118,-1118, 1119,-1118,-1118,-1118,-1118,-1118,-1118,-1118, -1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118, -1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118, -1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118, -1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118, -1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118, -1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118, -1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118, -1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118, -1118,-1118,-1118,-1118,-1118,-1118,-1118,-1118 }, { 55,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119, -1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119, -1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119, -1119,-1119, 1120,-1119,-1119,-1119,-1119,-1119,-1119,-1119, -1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119, -1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119, -1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119, -1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119, -1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119, -1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119, -1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119, -1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119, -1119,-1119,-1119,-1119,-1119,-1119,-1119,-1119 }, { 55,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120, -1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120, -1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120, -1120,-1120, 1121,-1120,-1120,-1120,-1120,-1120,-1120,-1120, -1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120, -1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120, -1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120, -1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120, -1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120, -1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120, -1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120, -1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120, -1120,-1120,-1120,-1120,-1120,-1120,-1120,-1120 }, { 55,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121, -1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121, -1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121, -1121,-1121, 1122,-1121,-1121,-1121,-1121,-1121,-1121,-1121, -1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121, -1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121, -1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121, -1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121, -1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121, -1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121, -1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121, -1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121, -1121,-1121,-1121,-1121,-1121,-1121,-1121,-1121 }, { 55,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122, -1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122, -1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122, -1122,-1122, 1123,-1122,-1122,-1122,-1122,-1122,-1122,-1122, -1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122, -1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122, -1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122, -1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122, -1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122, -1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122, -1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122, -1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122, -1122,-1122,-1122,-1122,-1122,-1122,-1122,-1122 }, { 55,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123, -1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123, -1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123, -1123,-1123, 1124,-1123,-1123,-1123,-1123,-1123,-1123,-1123, -1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123, -1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123, -1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123, -1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123, -1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123, -1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123, -1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123, -1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123, -1123,-1123,-1123,-1123,-1123,-1123,-1123,-1123 }, { 55,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124, -1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124, -1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124, -1124,-1124, 1125,-1124,-1124,-1124,-1124,-1124,-1124,-1124, -1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124, -1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124, -1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124, -1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124, -1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124, -1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124, -1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124, -1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124, -1124,-1124,-1124,-1124,-1124,-1124,-1124,-1124 }, { 55,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125, -1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125, -1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125, -1125,-1125, 1126,-1125,-1125,-1125,-1125,-1125,-1125,-1125, -1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125, -1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125, -1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125, -1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125, -1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125, -1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125, -1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125, -1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125, -1125,-1125,-1125,-1125,-1125,-1125,-1125,-1125 }, { 55,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126, -1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126, -1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126, -1126,-1126, 1127,-1126,-1126,-1126,-1126,-1126,-1126,-1126, -1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126, -1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126, -1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126, -1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126, -1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126, -1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126, -1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126, -1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126, -1126,-1126,-1126,-1126,-1126,-1126,-1126,-1126 }, { 55,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127, -1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127, -1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127, -1127,-1127, 1128,-1127,-1127,-1127,-1127,-1127,-1127,-1127, -1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127, -1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127, -1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127, -1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127, -1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127, -1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127, -1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127, -1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127, -1127,-1127,-1127,-1127,-1127,-1127,-1127,-1127 }, { 55,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128, -1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128, -1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128, -1128,-1128, 1129,-1128,-1128,-1128,-1128,-1128,-1128,-1128, -1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128, -1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128, -1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128, -1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128, -1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128, -1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128, -1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128, -1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128, -1128,-1128,-1128,-1128,-1128,-1128,-1128,-1128 }, { 55,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129, -1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129, -1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129, -1129,-1129, 1130,-1129,-1129,-1129,-1129,-1129,-1129,-1129, -1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129, -1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129, -1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129, -1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129, -1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129, -1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129, -1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129, -1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129, -1129,-1129,-1129,-1129,-1129,-1129,-1129,-1129 }, { 55,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130, -1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130, -1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130, -1130,-1130, 1131,-1130,-1130,-1130,-1130,-1130,-1130,-1130, -1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130, -1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130, -1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130, -1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130, -1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130, -1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130, -1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130, -1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130, -1130,-1130,-1130,-1130,-1130,-1130,-1130,-1130 }, { 55,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131, -1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131, -1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131, -1131,-1131, 1132,-1131,-1131,-1131,-1131,-1131,-1131,-1131, -1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131, -1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131, -1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131, -1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131, -1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131, -1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131, -1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131, -1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131, -1131,-1131,-1131,-1131,-1131,-1131,-1131,-1131 }, { 55,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132, -1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132, -1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132, -1132,-1132, 1133,-1132,-1132,-1132,-1132,-1132,-1132,-1132, -1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132, -1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132, -1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132, -1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132, -1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132, -1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132, -1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132, -1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132, -1132,-1132,-1132,-1132,-1132,-1132,-1132,-1132 }, { 55,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133, -1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133, -1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133, -1133,-1133, 1134,-1133,-1133,-1133,-1133,-1133,-1133,-1133, -1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133, -1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133, -1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133, -1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133, -1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133, -1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133, -1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133, -1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133, -1133,-1133,-1133,-1133,-1133,-1133,-1133,-1133 }, { 55,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134, -1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134, -1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134, -1134,-1134, 1135,-1134,-1134,-1134,-1134,-1134,-1134,-1134, -1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134, -1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134, -1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134, -1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134, -1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134, -1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134, -1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134, -1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134, -1134,-1134,-1134,-1134,-1134,-1134,-1134,-1134 }, { 55,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135, -1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135, -1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135, -1135,-1135, 1136,-1135,-1135,-1135,-1135,-1135,-1135,-1135, -1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135, -1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135, -1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135, -1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135, -1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135, -1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135, -1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135, -1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135, -1135,-1135,-1135,-1135,-1135,-1135,-1135,-1135 }, { 55,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136, -1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136, -1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136, -1136,-1136, 1137,-1136,-1136,-1136,-1136,-1136,-1136,-1136, -1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136, -1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136, -1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136, -1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136, -1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136, -1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136, -1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136, -1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136, -1136,-1136,-1136,-1136,-1136,-1136,-1136,-1136 }, { 55,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137, -1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137, -1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137, -1137,-1137, 1138,-1137,-1137,-1137,-1137,-1137,-1137,-1137, -1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137, -1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137, -1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137, -1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137, -1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137, -1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137, -1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137, -1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137, -1137,-1137,-1137,-1137,-1137,-1137,-1137,-1137 }, { 55,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138, -1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138, -1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138, -1138,-1138, 1139,-1138,-1138,-1138,-1138,-1138,-1138,-1138, -1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138, -1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138, -1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138, -1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138, -1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138, -1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138, -1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138, -1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138, -1138,-1138,-1138,-1138,-1138,-1138,-1138,-1138 }, { 55,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139, -1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139, -1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139, -1139,-1139, 1140,-1139,-1139,-1139,-1139,-1139,-1139,-1139, -1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139, -1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139, -1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139, -1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139, -1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139, -1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139, -1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139, -1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139, -1139,-1139,-1139,-1139,-1139,-1139,-1139,-1139 }, { 55,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140, -1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140, -1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140, -1140,-1140, 1141,-1140,-1140,-1140,-1140,-1140,-1140,-1140, -1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140, -1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140, -1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140, -1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140, -1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140, -1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140, -1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140, -1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140, -1140,-1140,-1140,-1140,-1140,-1140,-1140,-1140 }, { 55,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141, -1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141, -1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141, -1141,-1141, 1142,-1141,-1141,-1141,-1141,-1141,-1141,-1141, -1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141, -1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141, -1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141, -1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141, -1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141, -1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141, -1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141, -1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141, -1141,-1141,-1141,-1141,-1141,-1141,-1141,-1141 }, { 55,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142, -1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142, -1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142, -1142,-1142, 1143,-1142,-1142,-1142,-1142,-1142,-1142,-1142, -1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142, -1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142, -1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142, -1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142, -1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142, -1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142, -1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142, -1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142, -1142,-1142,-1142,-1142,-1142,-1142,-1142,-1142 }, { 55,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143, -1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143, -1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143, -1143,-1143, 1144,-1143,-1143,-1143,-1143,-1143,-1143,-1143, -1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143, -1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143, -1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143, -1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143, -1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143, -1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143, -1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143, -1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143, -1143,-1143,-1143,-1143,-1143,-1143,-1143,-1143 }, { 55,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144, -1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144, -1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144, -1144,-1144, 1145,-1144,-1144,-1144,-1144,-1144,-1144,-1144, -1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144, -1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144, -1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144, -1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144, -1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144, -1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144, -1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144, -1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144, -1144,-1144,-1144,-1144,-1144,-1144,-1144,-1144 }, { 55,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145, -1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145, -1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145, -1145,-1145, 1146,-1145,-1145,-1145,-1145,-1145,-1145,-1145, -1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145, -1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145, -1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145, -1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145, -1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145, -1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145, -1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145, -1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145, -1145,-1145,-1145,-1145,-1145,-1145,-1145,-1145 }, { 55,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146, -1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146, -1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146, -1146,-1146, 1147,-1146,-1146,-1146,-1146,-1146,-1146,-1146, -1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146, -1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146, -1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146, -1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146, -1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146, -1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146, -1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146, -1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146, -1146,-1146,-1146,-1146,-1146,-1146,-1146,-1146 }, { 55,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147, -1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147, -1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147, -1147,-1147, 1148,-1147,-1147,-1147,-1147,-1147,-1147,-1147, -1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147, -1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147, -1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147, -1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147, -1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147, -1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147, -1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147, -1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147, -1147,-1147,-1147,-1147,-1147,-1147,-1147,-1147 }, { 55,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148, -1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148, -1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148, -1148,-1148, 1149,-1148,-1148,-1148,-1148,-1148,-1148,-1148, -1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148, -1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148, -1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148, -1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148, -1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148, -1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148, -1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148, -1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148, -1148,-1148,-1148,-1148,-1148,-1148,-1148,-1148 }, { 55,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149, -1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149, -1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149, -1149,-1149, 1150,-1149,-1149,-1149,-1149,-1149,-1149,-1149, -1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149, -1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149, -1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149, -1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149, -1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149, -1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149, -1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149, -1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149, -1149,-1149,-1149,-1149,-1149,-1149,-1149,-1149 }, { 55,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150, -1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150, -1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150, -1150,-1150, 1151,-1150,-1150,-1150,-1150,-1150,-1150,-1150, -1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150, -1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150, -1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150, -1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150, -1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150, -1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150, -1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150, -1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150, -1150,-1150,-1150,-1150,-1150,-1150,-1150,-1150 }, { 55,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151, -1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151, -1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151, -1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151, -1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151, -1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151, -1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151, -1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151, -1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151, -1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151, -1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151, -1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151, -1151,-1151,-1151,-1151,-1151,-1151,-1151,-1151 }, } ; static yy_state_type yy_get_previous_state ( yyscan_t yyscanner ); static yy_state_type yy_try_NUL_trans ( yy_state_type current_state , yyscan_t yyscanner); static int yy_get_next_buffer ( yyscan_t yyscanner ); static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ yyg->yytext_ptr = yy_bp; \ yyleng = (int) (yy_cp - yy_bp); \ yyg->yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; #define YY_NUM_RULES 287 #define YY_END_OF_BUFFER 288 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static const flex_int16_t yy_accept[1152] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 288, 287, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 144, 144, 144, 192, 192, 192, 145, 145, 145, 241, 241, 241, 195, 193, 194, 245, 245, 249, 249, 252, 252, 253, 253, 256, 256, 258, 258, 260, 260, 262, 262, 261, 264, 264, 264, 263, 266, 266, 266, 265, 268, 268, 270, 270, 272, 271, 274, 274, 277, 277, 277, 275, 278, 287, 279, 287, 287, 287, 284, 287, 285, 287, 286, 0, 0, 101, 0, 0, 102, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 18, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, 261, 0, 263, 263, 263, 263, 0, 0, 265, 265, 265, 265, 0, 0, 267, 0, 269, 271, 273, 0, 275, 276, 276, 275, 0, 0, 281, 0, 0, 0, 279, 0, 0, 0, 279, 0, 0, 0, 284, 0, 285, 0, 286, 0, 103, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 141, 142, 143, 134, 133, 126, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 242, 243, 244, 246, 247, 248, 0, 0, 0, 0, 0, 263, 0, 263, 265, 0, 265, 276, 0, 276, 0, 0, 280, 0, 0, 0, 282, 0, 0, 0, 279, 0, 0, 119, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 255, 0, 257, 283, 0, 0, 0, 280, 0, 0, 0, 279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 20, 0, 88, 24, 92, 89, 93, 21, 0, 0, 7, 3, 10, 22, 9, 8, 23, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 251, 0, 280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 136, 137, 138, 139, 140, 132, 131, 130, 129, 128, 124, 125, 181, 183, 186, 190, 182, 185, 189, 184, 188, 187, 177, 155, 174, 178, 191, 166, 156, 152, 161, 172, 175, 179, 167, 164, 169, 157, 153, 162, 150, 159, 171, 173, 176, 180, 168, 165, 170, 148, 149, 158, 154, 163, 151, 160, 146, 147, 231, 233, 236, 240, 232, 235, 239, 234, 238, 237, 227, 205, 224, 228, 216, 202, 206, 211, 222, 225, 229, 214, 217, 219, 200, 203, 207, 212, 209, 221, 223, 226, 230, 198, 215, 218, 220, 199, 196, 201, 204, 208, 213, 210, 197, 250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 44, 42, 0, 0, 0, 0, 12, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 13, 15, 0, 75, 76, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 77, 0, 0, 0, 0, 25, 0, 0, 0, 79, 97, 99, 95, 55, 98, 100, 96, 105, 106, 84, 86, 48, 47, 49, 46, 32, 31, 83, 0, 73, 85, 87, 40, 39, 43, 41, 54, 52, 51, 53, 50, 34, 38, 36, 33, 37, 35, 0, 68, 69, 67, 64, 65, 66, 70, 118, 29, 115, 116, 117, 114, 111, 112, 113, 107, 108, 72, 14, 82, 59, 62, 45, 63, 26, 30, 61, 60, 28, 27, 56, 57, 19, 78, 121, 0, 109, 58, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122 } ; static const yy_state_type yy_NUL_trans[1152] = { 0, 56, 57, 78, 78, 81, 81, 84, 84, 87, 87, 90, 90, 92, 92, 93, 93, 95, 95, 97, 97, 99, 99, 101, 101, 103, 103, 105, 105, 107, 107, 110, 110, 114, 114, 118, 118, 120, 120, 122, 122, 124, 124, 126, 126, 56, 56, 131, 131, 135, 135, 137, 137, 139, 139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 251, 0, 255, 259, 263, 0, 265, 0, 267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 251, 0, 391, 392, 396, 0, 400, 259, 259, 0, 259, 259, 263, 0, 265, 0, 267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 535, 0, 0, 0, 0, 0, 0, 0, 0, 0, 391, 392, 0, 392, 392, 396, 0, 396, 540, 396, 0, 400, 544, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 535, 0, 0, 391, 717, 540, 0, 540, 540, 544, 0, 544, 544, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 717, 0, 717, 717, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1084, 0, 1084, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "wcspih.l" /*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcspih.c,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * wcspih.l is a Flex description file containing the definition of a lexical * scanner for parsing the WCS keyrecords from a FITS primary image or image * extension header. * * wcspih.l requires Flex v2.5.4 or later. Refer to wcshdr.h for a description * of the user interface and operating notes. * * Implementation notes * -------------------- * Use of the WCSAXESa keyword is not mandatory. Its default value is "the * larger of NAXIS and the largest index of these keywords [i.e. CRPIXj, PCi_j * or CDi_j, CDELTi, CTYPEi, CRVALi, and CUNITi] found in the FITS header". * Consequently the definition of WCSAXESa effectively invalidates the use of * NAXIS for determining the number of coordinate axes and forces a preliminary * pass through the header to determine the "largest index" in headers where * WCSAXESa was omitted. * * Furthermore, since the use of WCSAXESa is optional, there is no way to * determine the number of coordinate representations (the "a" value) other * than by parsing all of the WCS keywords in the header; even if WCSAXESa was * specified for some representations it cannot be known in advance whether it * was specified for all of those present in the header. * * Hence the definition of WCSAXESa forces the scanner to be implemented in two * passes. The first pass is used to determine the number of coordinate * representations (up to 27) and the number of coordinate axes in each. * Effectively WCSAXESa is ignored unless it exceeds the "largest index" in * which case the keywords for the extra axes assume their default values. The * number of PVi_ma and PSi_ma keywords in each representation is also counted * in the first pass. * * On completion of the first pass, memory is allocated for an array of the * required number of wcsprm structs and each of these is initialized * appropriately. These structs are filled in the second pass. * * The parser does not check for duplicated keywords, it accepts the last * encountered. * *===========================================================================*/ /* Options. */ #define YY_NO_INPUT 1 /* Indices for parameterized keywords. */ /* Alternate coordinate system identifier. */ /* Keyvalue data types. */ /* Inline comment syntax. */ /* Exclusive start states. */ #line 110 "wcspih.l" #include #include #include #include #include #include #include "wcsmath.h" #include "wcsprintf.h" #include "wcsutil.h" #include "dis.h" #include "wcs.h" #include "wcshdr.h" #define INTEGER 0 #define FLOAT 1 #define FLOAT2 2 #define STRING 3 #define RECORD 4 #define PRIOR 1 #define SEQUENT 2 #define SIP 1 #define DSS 2 #define WAT 3 // User data associated with yyscanner. struct wcspih_extra { // Values passed to YY_INPUT. char *hdr; int nkeyrec; // Used in preempting the call to exit() by yy_fatal_error(). jmp_buf abort_jmp_env; }; #define YY_DECL int wcspih_scanner(char *header, int nkeyrec, int relax, \ int ctrl, int *nreject, int *nwcs, struct wcsprm **wcs, yyscan_t yyscanner) #define YY_INPUT(inbuff, count, bufsize) \ { \ if (yyextra->nkeyrec) { \ strncpy(inbuff, yyextra->hdr, 80); \ inbuff[80] = '\n'; \ yyextra->hdr += 80; \ yyextra->nkeyrec--; \ count = 81; \ } else { \ count = YY_NULL; \ } \ } // Preempt the call to exit() by yy_fatal_error(). #define exit(status) longjmp(yyextra->abort_jmp_env, status); // Internal helper functions. static YY_DECL; static int wcspih_final(int ndp[], int ndq[], int distran, double dsstmp[], char *wat[], int *nwcs, struct wcsprm **wcs); static int wcspih_init1(int naxis, int alts[], int dpq[], int npv[], int nps[], int ndp[], int ndq[], int auxprm, int distran, int *nwcs, struct wcsprm **wcs); static void wcspih_pass1(int naxis, int i, int j, char a, int distype, int alts[], int dpq[], int *npptr); static int wcspih_jdref(double *wptr, const double *jdref); static int wcspih_jdrefi(double *wptr, const double *jdrefi); static int wcspih_jdreff(double *wptr, const double *jdreff); static int wcspih_epoch(double *wptr, const double *epoch); static int wcspih_vsource(double *wptr, const double *vsource); static int wcspih_timepixr(double timepixr); #line 20918 "wcspih.c" #line 20919 "wcspih.c" #define INITIAL 0 #define CCia 1 #define CCi_ja 2 #define CCCCCia 3 #define CCi_ma 4 #define CCCCCCCa 5 #define CCCCCCCC 6 #define CROTAi 7 #define PROJPn 8 #define SIP2 9 #define SIP3 10 #define DSSAMDXY 11 #define PLTDECSN 12 #define VALUE 13 #define INTEGER_VAL 14 #define FLOAT_VAL 15 #define FLOAT2_VAL 16 #define STRING_VAL 17 #define RECORD_VAL 18 #define RECFIELD 19 #define RECCOLON 20 #define RECVALUE 21 #define RECEND 22 #define COMMENT 23 #define DISCARD 24 #define ERROR 25 #define FLUSH 26 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #define YY_EXTRA_TYPE struct wcspih_extra * /* Holds the entire state of the reentrant scanner. */ struct yyguts_t { /* User-defined. Not touched by flex. */ YY_EXTRA_TYPE yyextra_r; /* The rest are the same as the globals declared in the non-reentrant scanner. */ FILE *yyin_r, *yyout_r; size_t yy_buffer_stack_top; /**< index of top of stack. */ size_t yy_buffer_stack_max; /**< capacity of stack. */ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ char yy_hold_char; int yy_n_chars; int yyleng_r; char *yy_c_buf_p; int yy_init; int yy_start; int yy_did_buffer_switch_on_eof; int yy_start_stack_ptr; int yy_start_stack_depth; int *yy_start_stack; yy_state_type yy_last_accepting_state; char* yy_last_accepting_cpos; int yylineno_r; int yy_flex_debug_r; char *yytext_r; int yy_more_flag; int yy_more_len; }; /* end struct yyguts_t */ static int yy_init_globals ( yyscan_t yyscanner ); int yylex_init (yyscan_t* scanner); int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy ( yyscan_t yyscanner ); int yyget_debug ( yyscan_t yyscanner ); void yyset_debug ( int debug_flag , yyscan_t yyscanner ); YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner ); void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner ); FILE *yyget_in ( yyscan_t yyscanner ); void yyset_in ( FILE * _in_str , yyscan_t yyscanner ); FILE *yyget_out ( yyscan_t yyscanner ); void yyset_out ( FILE * _out_str , yyscan_t yyscanner ); int yyget_leng ( yyscan_t yyscanner ); char *yyget_text ( yyscan_t yyscanner ); int yyget_lineno ( yyscan_t yyscanner ); void yyset_lineno ( int _line_number , yyscan_t yyscanner ); int yyget_column ( yyscan_t yyscanner ); void yyset_column ( int _column_no , yyscan_t yyscanner ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap ( yyscan_t yyscanner ); #else extern int yywrap ( yyscan_t yyscanner ); #endif #endif #ifndef YY_NO_UNPUT static void yyunput ( int c, char *buf_ptr , yyscan_t yyscanner); #endif #ifndef yytext_ptr static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen ( const char * , yyscan_t yyscanner); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput ( yyscan_t yyscanner ); #else static int input ( yyscan_t yyscanner ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ errno=0; \ while ( (result = (int) read( fileno(yyin), buf, (yy_size_t) max_size )) < 0 ) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex (yyscan_t yyscanner); #define YY_DECL int yylex (yyscan_t yyscanner) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK /*LINTED*/break; #endif #define YY_RULE_SETUP \ if ( yyleng > 0 ) \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ (yytext[yyleng - 1] == '\n'); \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { yy_state_type yy_current_state; char *yy_cp, *yy_bp; int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( !yyg->yy_init ) { yyg->yy_init = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! yyg->yy_start ) yyg->yy_start = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } yy_load_buffer_state( yyscanner ); } { #line 187 "wcspih.l" #line 189 "wcspih.l" int p, q; char *errmsg, errtxt[80], *keyname, strtmp[80], *wat[2], *watstr; int alts[27], dpq[27], inttmp, ndp[27], ndq[27], nps[27], npv[27], rectype; double dbltmp, dbl2tmp[2], dsstmp[20]; struct auxprm auxtem; struct disprm distem; struct wcsprm wcstem; int naxis = 0; for (int ialt = 0; ialt < 27; ialt++) { alts[ialt] = 0; dpq[ialt] = 0; npv[ialt] = 0; nps[ialt] = 0; ndp[ialt] = 0; ndq[ialt] = 0; } // Our handle on the input stream. char *keyrec = header; char *hptr = header; char *keep = 0x0; // For keeping tallies of keywords found. *nreject = 0; int nvalid = 0; int nother = 0; // If strict, then also reject. if (relax & WCSHDR_strict) relax |= WCSHDR_reject; // Keyword indices, as used in the WCS papers, e.g. PCi_ja, PVi_ma. int i = 0; int j = 0; int m = 0; char a = ' '; // For decoding the keyvalue. int valtype = -1; int distype = 0; void *vptr = 0x0; // For keywords that require special handling. int altlin = 0; int *npptr = 0x0; int (*chekval)(double) = 0x0; int (*special)(double *, const double *) = 0x0; int auxprm = 0; int naux = 0; int distran = 0; int sipflag = 0; int dssflag = 0; int watflag = 0; int watn = 0; // The data structures produced. *nwcs = 0; *wcs = 0x0; // Control variables. int ipass = 1; int npass = 2; // User data associated with yyscanner. yyextra->hdr = header; yyextra->nkeyrec = nkeyrec; // Return here via longjmp() invoked by yy_fatal_error(). if (setjmp(yyextra->abort_jmp_env)) { return WCSHDRERR_PARSER; } BEGIN(INITIAL); #line 21269 "wcspih.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { yy_cp = yyg->yy_c_buf_p; /* Support of yytext. */ *yy_cp = yyg->yy_hold_char; /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = yyg->yy_start; yy_current_state += YY_AT_BOL(); yy_match: while ( (yy_current_state = yy_nxt[yy_current_state][ YY_SC_TO_UI(*yy_cp) ]) > 0 ) { if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } ++yy_cp; } yy_current_state = -yy_current_state; yy_find_action: yy_act = yy_accept[yy_current_state]; YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = yyg->yy_hold_char; yy_cp = yyg->yy_last_accepting_cpos + 1; yy_current_state = yyg->yy_last_accepting_state; goto yy_find_action; case 1: YY_RULE_SETUP #line 265 "wcspih.l" { keyname = "NAXISn"; if (ipass == 1) { sscanf(yytext, "NAXIS = %d", &naxis); if (naxis < 0) naxis = 0; BEGIN(FLUSH); } else { sscanf(yytext, "NAXIS = %d", &i); if (i < 0) { errmsg = "negative value of NAXIS ignored"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } } YY_BREAK case 2: YY_RULE_SETUP #line 285 "wcspih.l" { sscanf(yytext, "WCSAXES%c= %d", &a, &i); if (i < 0) { errmsg = "negative value of WCSAXESa ignored"; BEGIN(ERROR); } else { valtype = INTEGER; vptr = 0x0; keyname = "WCSAXESa"; BEGIN(COMMENT); } } YY_BREAK case 3: YY_RULE_SETUP #line 301 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.crpix); keyname = "CRPIXja"; BEGIN(CCCCCia); } YY_BREAK case 4: YY_RULE_SETUP #line 309 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.pc); altlin = 1; keyname = "PCi_ja"; BEGIN(CCi_ja); } YY_BREAK case 5: YY_RULE_SETUP #line 318 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.cd); altlin = 2; keyname = "CDi_ja"; BEGIN(CCi_ja); } YY_BREAK case 6: YY_RULE_SETUP #line 327 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.cdelt); keyname = "CDELTia"; BEGIN(CCCCCia); } YY_BREAK case 7: YY_RULE_SETUP #line 335 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.crota); altlin = 4; keyname = "CROTAn"; BEGIN(CROTAi); } YY_BREAK case 8: YY_RULE_SETUP #line 344 "wcspih.l" { valtype = STRING; vptr = &(wcstem.cunit); keyname = "CUNITia"; BEGIN(CCCCCia); } YY_BREAK case 9: YY_RULE_SETUP #line 352 "wcspih.l" { valtype = STRING; vptr = &(wcstem.ctype); keyname = "CTYPEia"; BEGIN(CCCCCia); } YY_BREAK case 10: YY_RULE_SETUP #line 360 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.crval); keyname = "CRVALia"; BEGIN(CCCCCia); } YY_BREAK case 11: YY_RULE_SETUP #line 368 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.lonpole); keyname = "LONPOLEa"; BEGIN(CCCCCCCa); } YY_BREAK case 12: YY_RULE_SETUP #line 376 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.latpole); keyname = "LATPOLEa"; BEGIN(CCCCCCCa); } YY_BREAK case 13: YY_RULE_SETUP #line 384 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.restfrq); keyname = "RESTFRQa"; BEGIN(CCCCCCCa); } YY_BREAK case 14: YY_RULE_SETUP #line 392 "wcspih.l" { if (relax & WCSHDR_strict) { errmsg = "the RESTFREQ keyword is deprecated, use RESTFRQa"; BEGIN(ERROR); } else { valtype = FLOAT; vptr = &(wcstem.restfrq); unput(' '); keyname = "RESTFREQ"; BEGIN(CCCCCCCa); } } YY_BREAK case 15: YY_RULE_SETUP #line 408 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.restwav); keyname = "RESTWAVa"; BEGIN(CCCCCCCa); } YY_BREAK case 16: YY_RULE_SETUP #line 416 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.pv); npptr = npv; keyname = "PVi_ma"; BEGIN(CCi_ma); } YY_BREAK case 17: YY_RULE_SETUP #line 425 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.pv); npptr = npv; keyname = "PROJPn"; BEGIN(PROJPn); } YY_BREAK case 18: YY_RULE_SETUP #line 434 "wcspih.l" { valtype = STRING; vptr = &(wcstem.ps); npptr = nps; keyname = "PSi_ma"; BEGIN(CCi_ma); } YY_BREAK case 19: YY_RULE_SETUP #line 443 "wcspih.l" { sscanf(yytext, "VELREF%c", &a); if (relax & WCSHDR_strict) { errmsg = "the VELREF keyword is deprecated, use SPECSYSa"; BEGIN(ERROR); } else if ((a == ' ') || (relax & WCSHDR_VELREFa)) { valtype = INTEGER; vptr = &(wcstem.velref); unput(a); keyname = "VELREF"; BEGIN(CCCCCCCa); } else if (relax & WCSHDR_reject) { errmsg = "VELREF keyword may not have an alternate version code"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 20: YY_RULE_SETUP #line 468 "wcspih.l" { valtype = STRING; vptr = &(wcstem.cname); keyname = "CNAMEia"; BEGIN(CCCCCia); } YY_BREAK case 21: YY_RULE_SETUP #line 476 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.crder); keyname = "CRDERia"; BEGIN(CCCCCia); } YY_BREAK case 22: YY_RULE_SETUP #line 484 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.csyer); keyname = "CSYERia"; BEGIN(CCCCCia); } YY_BREAK case 23: YY_RULE_SETUP #line 492 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.czphs); keyname = "CZPHSia"; BEGIN(CCCCCia); } YY_BREAK case 24: YY_RULE_SETUP #line 500 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.cperi); keyname = "CPERIia"; BEGIN(CCCCCia); } YY_BREAK case 25: YY_RULE_SETUP #line 508 "wcspih.l" { valtype = STRING; vptr = wcstem.wcsname; keyname = "WCSNAMEa"; BEGIN(CCCCCCCa); } YY_BREAK case 26: YY_RULE_SETUP #line 516 "wcspih.l" { valtype = STRING; vptr = wcstem.timesys; keyname = "TIMESYS"; BEGIN(CCCCCCCC); } YY_BREAK case 27: YY_RULE_SETUP #line 524 "wcspih.l" { valtype = STRING; vptr = wcstem.trefpos; keyname = "TREFPOS"; BEGIN(CCCCCCCC); } YY_BREAK case 28: YY_RULE_SETUP #line 532 "wcspih.l" { valtype = STRING; vptr = wcstem.trefdir; keyname = "TREFDIR"; BEGIN(CCCCCCCC); } YY_BREAK case 29: YY_RULE_SETUP #line 540 "wcspih.l" { valtype = STRING; vptr = wcstem.plephem; keyname = "PLEPHEM"; BEGIN(CCCCCCCC); } YY_BREAK case 30: YY_RULE_SETUP #line 548 "wcspih.l" { valtype = STRING; vptr = wcstem.timeunit; keyname = "TIMEUNIT"; BEGIN(CCCCCCCC); } YY_BREAK case 31: #line 557 "wcspih.l" case 32: YY_RULE_SETUP #line 557 "wcspih.l" { if ((yytext[4] == 'R') || (relax & WCSHDR_DATEREF)) { valtype = STRING; vptr = wcstem.dateref; keyname = "DATEREF"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the DATE-REF keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 33: #line 575 "wcspih.l" case 34: YY_RULE_SETUP #line 575 "wcspih.l" { if ((yytext[3] == 'R') || (relax & WCSHDR_DATEREF)) { valtype = FLOAT2; vptr = wcstem.mjdref; keyname = "MJDREF"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the MJD-REF keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 35: #line 593 "wcspih.l" case 36: YY_RULE_SETUP #line 593 "wcspih.l" { if ((yytext[3] == 'R') || (relax & WCSHDR_DATEREF)) { // Actually integer, but treated as float. valtype = FLOAT; vptr = wcstem.mjdref; keyname = "MJDREFI"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the MJD-REFI keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 37: #line 612 "wcspih.l" case 38: YY_RULE_SETUP #line 612 "wcspih.l" { if ((yytext[3] == 'R') || (relax & WCSHDR_DATEREF)) { valtype = FLOAT; vptr = wcstem.mjdref + 1; keyname = "MJDREFF"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the MJD-REFF keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 39: #line 630 "wcspih.l" case 40: YY_RULE_SETUP #line 630 "wcspih.l" { if ((yytext[2] == 'R') || (relax & WCSHDR_DATEREF)) { valtype = FLOAT2; vptr = wcstem.mjdref; special = wcspih_jdref; keyname = "JDREF"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the JD-REF keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 41: #line 649 "wcspih.l" case 42: YY_RULE_SETUP #line 649 "wcspih.l" { if ((yytext[2] == 'R') || (relax & WCSHDR_DATEREF)) { // Actually integer, but treated as float. valtype = FLOAT; vptr = wcstem.mjdref; special = wcspih_jdrefi; keyname = "JDREFI"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the JD-REFI keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 43: #line 669 "wcspih.l" case 44: YY_RULE_SETUP #line 669 "wcspih.l" { if ((yytext[2] == 'R') || (relax & WCSHDR_DATEREF)) { valtype = FLOAT; vptr = wcstem.mjdref; special = wcspih_jdreff; keyname = "JDREFF"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the JD-REFF keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 45: YY_RULE_SETUP #line 687 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.timeoffs); keyname = "TIMEOFFS"; BEGIN(CCCCCCCC); } YY_BREAK case 46: YY_RULE_SETUP #line 695 "wcspih.l" { valtype = STRING; vptr = wcstem.dateobs; if (ctrl < -10) keep = keyrec; keyname = "DATE-OBS"; BEGIN(CCCCCCCC); } YY_BREAK case 47: YY_RULE_SETUP #line 704 "wcspih.l" { valtype = STRING; vptr = wcstem.datebeg; if (ctrl < -10) keep = keyrec; keyname = "DATE-BEG"; BEGIN(CCCCCCCC); } YY_BREAK case 48: YY_RULE_SETUP #line 713 "wcspih.l" { valtype = STRING; vptr = wcstem.dateavg; if (ctrl < -10) keep = keyrec; keyname = "DATE-AVG"; BEGIN(CCCCCCCC); } YY_BREAK case 49: YY_RULE_SETUP #line 722 "wcspih.l" { valtype = STRING; vptr = wcstem.dateend; if (ctrl < -10) keep = keyrec; keyname = "DATE-END"; BEGIN(CCCCCCCC); } YY_BREAK case 50: YY_RULE_SETUP #line 731 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.mjdobs); if (ctrl < -10) keep = keyrec; keyname = "MJD-OBS"; BEGIN(CCCCCCCC); } YY_BREAK case 51: YY_RULE_SETUP #line 740 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.mjdbeg); if (ctrl < -10) keep = keyrec; keyname = "MJD-BEG"; BEGIN(CCCCCCCC); } YY_BREAK case 52: YY_RULE_SETUP #line 749 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.mjdavg); if (ctrl < -10) keep = keyrec; keyname = "MJD-AVG"; BEGIN(CCCCCCCC); } YY_BREAK case 53: YY_RULE_SETUP #line 758 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.mjdend); if (ctrl < -10) keep = keyrec; keyname = "MJD-END"; BEGIN(CCCCCCCC); } YY_BREAK case 54: YY_RULE_SETUP #line 767 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.jepoch); if (ctrl < -10) keep = keyrec; keyname = "JEPOCH"; BEGIN(CCCCCCCC); } YY_BREAK case 55: YY_RULE_SETUP #line 776 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.bepoch); if (ctrl < -10) keep = keyrec; keyname = "BEPOCH"; BEGIN(CCCCCCCC); } YY_BREAK case 56: YY_RULE_SETUP #line 785 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.tstart); if (ctrl < -10) keep = keyrec; keyname = "TSTART"; BEGIN(CCCCCCCC); } YY_BREAK case 57: YY_RULE_SETUP #line 794 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.tstop); if (ctrl < -10) keep = keyrec; keyname = "TSTOP"; BEGIN(CCCCCCCC); } YY_BREAK case 58: YY_RULE_SETUP #line 803 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.xposure); if (ctrl < -10) keep = keyrec; keyname = "XPOSURE"; BEGIN(CCCCCCCC); } YY_BREAK case 59: YY_RULE_SETUP #line 812 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.telapse); if (ctrl < -10) keep = keyrec; keyname = "TELAPSE"; BEGIN(CCCCCCCC); } YY_BREAK case 60: YY_RULE_SETUP #line 821 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.timsyer); if (ctrl < -10) keep = keyrec; keyname = "TIMSYER"; BEGIN(CCCCCCCC); } YY_BREAK case 61: YY_RULE_SETUP #line 830 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.timrder); if (ctrl < -10) keep = keyrec; keyname = "TIMRDER"; BEGIN(CCCCCCCC); } YY_BREAK case 62: YY_RULE_SETUP #line 839 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.timedel); if (ctrl < -10) keep = keyrec; keyname = "TIMEDEL"; BEGIN(CCCCCCCC); } YY_BREAK case 63: YY_RULE_SETUP #line 848 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.timepixr); chekval = wcspih_timepixr; if (ctrl < -10) keep = keyrec; keyname = "TIMEPIXR"; BEGIN(CCCCCCCC); } YY_BREAK case 64: YY_RULE_SETUP #line 858 "wcspih.l" { valtype = FLOAT; vptr = wcstem.obsgeo; if (ctrl < -10) keep = keyrec; keyname = "OBSGEO-X"; BEGIN(CCCCCCCC); } YY_BREAK case 65: YY_RULE_SETUP #line 867 "wcspih.l" { valtype = FLOAT; vptr = wcstem.obsgeo + 1; if (ctrl < -10) keep = keyrec; keyname = "OBSGEO-Y"; BEGIN(CCCCCCCC); } YY_BREAK case 66: YY_RULE_SETUP #line 876 "wcspih.l" { valtype = FLOAT; vptr = wcstem.obsgeo + 2; if (ctrl < -10) keep = keyrec; keyname = "OBSGEO-Z"; BEGIN(CCCCCCCC); } YY_BREAK case 67: YY_RULE_SETUP #line 885 "wcspih.l" { valtype = FLOAT; vptr = wcstem.obsgeo + 3; if (ctrl < -10) keep = keyrec; keyname = "OBSGEO-L"; BEGIN(CCCCCCCC); } YY_BREAK case 68: YY_RULE_SETUP #line 894 "wcspih.l" { valtype = FLOAT; vptr = wcstem.obsgeo + 4; if (ctrl < -10) keep = keyrec; keyname = "OBSGEO-B"; BEGIN(CCCCCCCC); } YY_BREAK case 69: YY_RULE_SETUP #line 903 "wcspih.l" { valtype = FLOAT; vptr = wcstem.obsgeo + 5; if (ctrl < -10) keep = keyrec; keyname = "OBSGEO-H"; BEGIN(CCCCCCCC); } YY_BREAK case 70: YY_RULE_SETUP #line 912 "wcspih.l" { valtype = STRING; vptr = wcstem.obsorbit; keyname = "OBSORBIT"; BEGIN(CCCCCCCC); } YY_BREAK case 71: YY_RULE_SETUP #line 920 "wcspih.l" { valtype = STRING; vptr = wcstem.radesys; keyname = "RADESYSa"; BEGIN(CCCCCCCa); } YY_BREAK case 72: YY_RULE_SETUP #line 928 "wcspih.l" { if (relax & WCSHDR_RADECSYS) { valtype = STRING; vptr = wcstem.radesys; unput(' '); keyname = "RADECSYS"; BEGIN(CCCCCCCa); } else if (relax & WCSHDR_reject) { errmsg = "the RADECSYS keyword is deprecated, use RADESYSa"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 73: YY_RULE_SETUP #line 947 "wcspih.l" { sscanf(yytext, "EPOCH%c", &a); if (relax & WCSHDR_strict) { errmsg = "the EPOCH keyword is deprecated, use EQUINOXa"; BEGIN(ERROR); } else if (a == ' ' || relax & WCSHDR_EPOCHa) { valtype = FLOAT; vptr = &(wcstem.equinox); special = wcspih_epoch; unput(a); keyname = "EPOCH"; BEGIN(CCCCCCCa); } else if (relax & WCSHDR_reject) { errmsg = "EPOCH keyword may not have an alternate version code"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 74: YY_RULE_SETUP #line 973 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.equinox); keyname = "EQUINOXa"; BEGIN(CCCCCCCa); } YY_BREAK case 75: YY_RULE_SETUP #line 981 "wcspih.l" { valtype = STRING; vptr = wcstem.specsys; keyname = "SPECSYSa"; BEGIN(CCCCCCCa); } YY_BREAK case 76: YY_RULE_SETUP #line 989 "wcspih.l" { valtype = STRING; vptr = wcstem.ssysobs; keyname = "SSYSOBSa"; BEGIN(CCCCCCCa); } YY_BREAK case 77: YY_RULE_SETUP #line 997 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.velosys); keyname = "VELOSYSa"; BEGIN(CCCCCCCa); } YY_BREAK case 78: YY_RULE_SETUP #line 1005 "wcspih.l" { if (relax & WCSHDR_VSOURCE) { valtype = FLOAT; vptr = &(wcstem.zsource); special = wcspih_vsource; yyless(7); keyname = "VSOURCEa"; BEGIN(CCCCCCCa); } else if (relax & WCSHDR_reject) { errmsg = "the VSOURCEa keyword is deprecated, use ZSOURCEa"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 79: YY_RULE_SETUP #line 1025 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.zsource); keyname = "ZSOURCEa"; BEGIN(CCCCCCCa); } YY_BREAK case 80: YY_RULE_SETUP #line 1033 "wcspih.l" { valtype = STRING; vptr = wcstem.ssyssrc; keyname = "SSYSSRCa"; BEGIN(CCCCCCCa); } YY_BREAK case 81: YY_RULE_SETUP #line 1041 "wcspih.l" { valtype = FLOAT; vptr = &(wcstem.velangl); keyname = "VELANGLa"; BEGIN(CCCCCCCa); } YY_BREAK case 82: YY_RULE_SETUP #line 1049 "wcspih.l" { valtype = FLOAT; auxprm = 1; vptr = &(auxtem.rsun_ref); keyname = "RSUN_REF"; BEGIN(CCCCCCCC); } YY_BREAK case 83: YY_RULE_SETUP #line 1058 "wcspih.l" { valtype = FLOAT; auxprm = 1; vptr = &(auxtem.dsun_obs); keyname = "DSUN_OBS"; BEGIN(CCCCCCCC); } YY_BREAK case 84: YY_RULE_SETUP #line 1067 "wcspih.l" { valtype = FLOAT; auxprm = 1; vptr = &(auxtem.crln_obs); keyname = "CRLN_OBS"; BEGIN(CCCCCCCC); } YY_BREAK case 85: YY_RULE_SETUP #line 1076 "wcspih.l" { valtype = FLOAT; auxprm = 1; vptr = &(auxtem.hgln_obs); keyname = "HGLN_OBS"; BEGIN(CCCCCCCC); } YY_BREAK case 86: #line 1086 "wcspih.l" case 87: YY_RULE_SETUP #line 1086 "wcspih.l" { valtype = FLOAT; auxprm = 1; vptr = &(auxtem.hglt_obs); keyname = "HGLT_OBS"; BEGIN(CCCCCCCC); } YY_BREAK case 88: YY_RULE_SETUP #line 1095 "wcspih.l" { valtype = STRING; distype = PRIOR; vptr = &(distem.dtype); keyname = "CPDISja"; BEGIN(CCCCCia); } YY_BREAK case 89: YY_RULE_SETUP #line 1104 "wcspih.l" { valtype = STRING; distype = SEQUENT; vptr = &(distem.dtype); keyname = "CQDISia"; BEGIN(CCCCCia); } YY_BREAK case 90: YY_RULE_SETUP #line 1113 "wcspih.l" { valtype = RECORD; distype = PRIOR; vptr = &(distem.dp); npptr = ndp; keyname = "DPja"; BEGIN(CCia); } YY_BREAK case 91: YY_RULE_SETUP #line 1123 "wcspih.l" { valtype = RECORD; distype = SEQUENT; vptr = &(distem.dp); npptr = ndq; keyname = "DQia"; BEGIN(CCia); } YY_BREAK case 92: YY_RULE_SETUP #line 1133 "wcspih.l" { valtype = FLOAT; distype = PRIOR; vptr = &(distem.maxdis); keyname = "CPERRja"; BEGIN(CCCCCia); } YY_BREAK case 93: YY_RULE_SETUP #line 1142 "wcspih.l" { valtype = FLOAT; distype = SEQUENT; vptr = &(distem.maxdis); keyname = "CQERRia"; BEGIN(CCCCCia); } YY_BREAK case 94: YY_RULE_SETUP #line 1151 "wcspih.l" { valtype = FLOAT; distype = PRIOR; vptr = &(distem.totdis); keyname = "DVERRa"; BEGIN(CCCCCCCa); } YY_BREAK case 95: YY_RULE_SETUP #line 1160 "wcspih.l" { // SIP: axis 1 polynomial degree (not stored). valtype = INTEGER; distype = PRIOR; vptr = 0x0; i = 1; a = ' '; keyname = "A_ORDER"; BEGIN(VALUE); } YY_BREAK case 96: YY_RULE_SETUP #line 1173 "wcspih.l" { // SIP: axis 2 polynomial degree (not stored). valtype = INTEGER; distype = PRIOR; vptr = 0x0; i = 2; a = ' '; keyname = "B_ORDER"; BEGIN(VALUE); } YY_BREAK case 97: YY_RULE_SETUP #line 1186 "wcspih.l" { // SIP: axis 1 inverse polynomial degree (not stored). valtype = INTEGER; distype = PRIOR; vptr = 0x0; i = 1; a = ' '; keyname = "AP_ORDER"; BEGIN(VALUE); } YY_BREAK case 98: YY_RULE_SETUP #line 1199 "wcspih.l" { // SIP: axis 2 inverse polynomial degree (not stored). valtype = INTEGER; distype = PRIOR; vptr = 0x0; i = 2; a = ' '; keyname = "BP_ORDER"; BEGIN(VALUE); } YY_BREAK case 99: YY_RULE_SETUP #line 1212 "wcspih.l" { // SIP: axis 1 maximum distortion. valtype = FLOAT; distype = PRIOR; vptr = &(distem.maxdis); i = 1; a = ' '; keyname = "A_DMAX"; BEGIN(VALUE); } YY_BREAK case 100: YY_RULE_SETUP #line 1225 "wcspih.l" { // SIP: axis 2 maximum distortion. valtype = FLOAT; distype = PRIOR; vptr = &(distem.maxdis); i = 2; a = ' '; keyname = "B_DMAX"; BEGIN(VALUE); } YY_BREAK case 101: YY_RULE_SETUP #line 1238 "wcspih.l" { // SIP: axis 1 polynomial coefficient. i = 1; sipflag = 2; keyname = "A_p_q"; BEGIN(SIP2); } YY_BREAK case 102: YY_RULE_SETUP #line 1247 "wcspih.l" { // SIP: axis 2 polynomial coefficient. i = 2; sipflag = 2; keyname = "B_p_q"; BEGIN(SIP2); } YY_BREAK case 103: YY_RULE_SETUP #line 1256 "wcspih.l" { // SIP: axis 1 inverse polynomial coefficient. i = 1; sipflag = 3; keyname = "AP_p_q"; BEGIN(SIP3); } YY_BREAK case 104: YY_RULE_SETUP #line 1265 "wcspih.l" { // SIP: axis 2 inverse polynomial coefficient. i = 2; sipflag = 3; keyname = "BP_p_q"; BEGIN(SIP3); } YY_BREAK case 105: YY_RULE_SETUP #line 1274 "wcspih.l" { // DSS: LLH corner pixel coordinate 1. valtype = FLOAT; distype = SEQUENT; vptr = dsstmp; dssflag = 1; distran = DSS; keyname = "CNPIX1"; BEGIN(VALUE); } YY_BREAK case 106: YY_RULE_SETUP #line 1286 "wcspih.l" { // DSS: LLH corner pixel coordinate 2. valtype = FLOAT; distype = SEQUENT; vptr = dsstmp+1; dssflag = 1; distran = DSS; keyname = "CNPIX1"; BEGIN(VALUE); } YY_BREAK case 107: YY_RULE_SETUP #line 1298 "wcspih.l" { // DSS: plate centre x-coordinate in micron. valtype = FLOAT; distype = SEQUENT; vptr = dsstmp+2; dssflag = 1; distran = DSS; keyname = "PPO3"; BEGIN(VALUE); } YY_BREAK case 108: YY_RULE_SETUP #line 1310 "wcspih.l" { // DSS: plate centre y-coordinate in micron. valtype = FLOAT; distype = SEQUENT; vptr = dsstmp+3; dssflag = 1; distran = DSS; keyname = "PPO6"; BEGIN(VALUE); } YY_BREAK case 109: YY_RULE_SETUP #line 1322 "wcspih.l" { // DSS: pixel x-dimension in micron. valtype = FLOAT; distype = SEQUENT; vptr = dsstmp+4; dssflag = 1; distran = DSS; keyname = "XPIXELSZ"; BEGIN(VALUE); } YY_BREAK case 110: YY_RULE_SETUP #line 1334 "wcspih.l" { // DSS: pixel y-dimension in micron. valtype = FLOAT; distype = SEQUENT; vptr = dsstmp+5; dssflag = 1; distran = DSS; keyname = "YPIXELSZ"; BEGIN(VALUE); } YY_BREAK case 111: YY_RULE_SETUP #line 1346 "wcspih.l" { // DSS: plate centre, right ascension - hours. valtype = FLOAT; distype = SEQUENT; vptr = dsstmp+6; dssflag = 1; distran = DSS; keyname = "PLTRAH"; BEGIN(VALUE); } YY_BREAK case 112: YY_RULE_SETUP #line 1358 "wcspih.l" { // DSS: plate centre, right ascension - minutes. valtype = FLOAT; distype = SEQUENT; vptr = dsstmp+7; dssflag = 1; distran = DSS; keyname = "PLTRAM"; BEGIN(VALUE); } YY_BREAK case 113: YY_RULE_SETUP #line 1370 "wcspih.l" { // DSS: plate centre, right ascension - seconds. valtype = FLOAT; distype = SEQUENT; vptr = dsstmp+8; dssflag = 1; distran = DSS; keyname = "PLTRAS"; BEGIN(VALUE); } YY_BREAK case 114: YY_RULE_SETUP #line 1382 "wcspih.l" { // DSS: plate centre, declination - sign. valtype = STRING; distype = SEQUENT; vptr = dsstmp+9; dssflag = 1; distran = DSS; keyname = "PLTDECSN"; BEGIN(PLTDECSN); } YY_BREAK case 115: YY_RULE_SETUP #line 1394 "wcspih.l" { // DSS: plate centre, declination - degrees. valtype = FLOAT; distype = SEQUENT; vptr = dsstmp+10; dssflag = 1; distran = DSS; keyname = "PLTDECD"; BEGIN(VALUE); } YY_BREAK case 116: YY_RULE_SETUP #line 1406 "wcspih.l" { // DSS: plate centre, declination - arcmin. valtype = FLOAT; distype = SEQUENT; vptr = dsstmp+11; dssflag = 1; distran = DSS; keyname = "PLTDECM"; BEGIN(VALUE); } YY_BREAK case 117: YY_RULE_SETUP #line 1418 "wcspih.l" { // DSS: plate centre, declination - arcsec. valtype = FLOAT; distype = SEQUENT; vptr = dsstmp+12; dssflag = 1; distran = DSS; keyname = "PLTDECS"; BEGIN(VALUE); } YY_BREAK case 118: YY_RULE_SETUP #line 1430 "wcspih.l" { // DSS: plate identification (insufficient to trigger DSS). valtype = STRING; distype = SEQUENT; vptr = dsstmp+13; dssflag = 2; distran = 0; keyname = "PLATEID"; BEGIN(VALUE); } YY_BREAK case 119: YY_RULE_SETUP #line 1442 "wcspih.l" { // DSS: axis 1 polynomial coefficient. i = 1; dssflag = 3; keyname = "AMDXm"; BEGIN(DSSAMDXY); } YY_BREAK case 120: YY_RULE_SETUP #line 1451 "wcspih.l" { // DSS: axis 2 polynomial coefficient. i = 2; dssflag = 3; keyname = "AMDYm"; BEGIN(DSSAMDXY); } YY_BREAK case 121: YY_RULE_SETUP #line 1460 "wcspih.l" { // TNX or ZPX: string-encoded data array. sscanf(yytext, "WAT%d_%d", &i, &m); if (watn < m) watn = m; watflag = 1; valtype = STRING; distype = SEQUENT; vptr = wat[i-1] + 68*(m-1); a = ' '; distran = WAT; keyname = "WATi_m"; BEGIN(VALUE); } YY_BREAK case 122: YY_RULE_SETUP #line 1477 "wcspih.l" { if (yyextra->nkeyrec) { yyextra->nkeyrec = 0; errmsg = "keyrecords following the END keyrecord were ignored"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 123: YY_RULE_SETUP #line 1487 "wcspih.l" { BEGIN(DISCARD); } YY_BREAK case 124: #line 1492 "wcspih.l" case 125: #line 1493 "wcspih.l" case 126: #line 1494 "wcspih.l" case 127: YY_RULE_SETUP #line 1494 "wcspih.l" { sscanf(yytext, "%d%c", &i, &a); BEGIN(VALUE); } YY_BREAK case 128: #line 1500 "wcspih.l" case 129: #line 1501 "wcspih.l" case 130: #line 1502 "wcspih.l" case 131: #line 1503 "wcspih.l" case 132: #line 1504 "wcspih.l" case 133: #line 1505 "wcspih.l" case 134: YY_RULE_SETUP #line 1505 "wcspih.l" { if (relax & WCSHDR_reject) { // Violates the basic FITS standard. errmsg = "indices in parameterized keywords must not have " "leading zeroes"; BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 135: #line 1519 "wcspih.l" case 136: #line 1520 "wcspih.l" case 137: #line 1521 "wcspih.l" case 138: #line 1522 "wcspih.l" case 139: #line 1523 "wcspih.l" case 140: #line 1524 "wcspih.l" case 141: #line 1525 "wcspih.l" case 142: #line 1526 "wcspih.l" case 143: YY_RULE_SETUP #line 1526 "wcspih.l" { // Anything that has fallen through to this point must contain // an invalid axis number. errmsg = "axis number must exceed 0"; BEGIN(ERROR); } YY_BREAK case 144: YY_RULE_SETUP #line 1533 "wcspih.l" { // Let it go. BEGIN(DISCARD); } YY_BREAK case 145: YY_RULE_SETUP #line 1538 "wcspih.l" { if (relax & WCSHDR_reject) { // Looks too much like a FITS WCS keyword not to flag it. errmsg = errtxt; sprintf(errmsg, "keyword looks very much like %s but isn't", keyname); BEGIN(ERROR); } else { // Let it go. BEGIN(DISCARD); } } YY_BREAK case 146: #line 1553 "wcspih.l" case 147: #line 1554 "wcspih.l" case 148: #line 1555 "wcspih.l" case 149: YY_RULE_SETUP #line 1555 "wcspih.l" { sscanf(yytext, "%d_%d%c", &i, &j, &a); BEGIN(VALUE); } YY_BREAK case 150: #line 1562 "wcspih.l" case 151: #line 1563 "wcspih.l" case 152: #line 1564 "wcspih.l" case 153: #line 1565 "wcspih.l" case 154: #line 1566 "wcspih.l" case 155: #line 1567 "wcspih.l" case 156: #line 1568 "wcspih.l" case 157: #line 1569 "wcspih.l" case 158: #line 1570 "wcspih.l" case 159: #line 1571 "wcspih.l" case 160: #line 1572 "wcspih.l" case 161: #line 1573 "wcspih.l" case 162: #line 1574 "wcspih.l" case 163: #line 1575 "wcspih.l" case 164: #line 1576 "wcspih.l" case 165: #line 1577 "wcspih.l" case 166: #line 1578 "wcspih.l" case 167: #line 1579 "wcspih.l" case 168: #line 1580 "wcspih.l" case 169: #line 1581 "wcspih.l" case 170: YY_RULE_SETUP #line 1581 "wcspih.l" { if (((altlin == 1) && (relax & WCSHDR_PC0i_0ja)) || ((altlin == 2) && (relax & WCSHDR_CD0i_0ja))) { sscanf(yytext, "%d_%d%c", &i, &j, &a); BEGIN(VALUE); } else if (relax & WCSHDR_reject) { errmsg = "indices in parameterized keywords must not have " "leading zeroes"; BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 171: #line 1599 "wcspih.l" case 172: #line 1600 "wcspih.l" case 173: #line 1601 "wcspih.l" case 174: #line 1602 "wcspih.l" case 175: #line 1603 "wcspih.l" case 176: #line 1604 "wcspih.l" case 177: #line 1605 "wcspih.l" case 178: #line 1606 "wcspih.l" case 179: #line 1607 "wcspih.l" case 180: YY_RULE_SETUP #line 1607 "wcspih.l" { // Anything that has fallen through to this point must contain // an invalid axis number. errmsg = "axis number must exceed 0"; BEGIN(ERROR); } YY_BREAK case 181: #line 1615 "wcspih.l" case 182: #line 1616 "wcspih.l" case 183: #line 1617 "wcspih.l" case 184: #line 1618 "wcspih.l" case 185: #line 1619 "wcspih.l" case 186: #line 1620 "wcspih.l" case 187: #line 1621 "wcspih.l" case 188: #line 1622 "wcspih.l" case 189: #line 1623 "wcspih.l" case 190: YY_RULE_SETUP #line 1623 "wcspih.l" { errmsg = errtxt; sprintf(errmsg, "%s keyword must use an underscore, not a dash", keyname); BEGIN(ERROR); } YY_BREAK case 191: YY_RULE_SETUP #line 1630 "wcspih.l" { // This covers the defunct forms CD00i00j and PC00i00j. if (((altlin == 1) && (relax & WCSHDR_PC00i00j)) || ((altlin == 2) && (relax & WCSHDR_CD00i00j))) { sscanf(yytext, "%3d%3d", &i, &j); a = ' '; BEGIN(VALUE); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "this form of the %s keyword is deprecated, use %s", keyname, keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 192: YY_RULE_SETUP #line 1651 "wcspih.l" { BEGIN(DISCARD); } YY_BREAK case 193: #line 1656 "wcspih.l" case 194: YY_RULE_SETUP #line 1656 "wcspih.l" { if (YY_START == CCCCCCCa) { sscanf(yytext, "%c", &a); } else { unput(yytext[0]); a = 0; } BEGIN(VALUE); } YY_BREAK case 195: YY_RULE_SETUP #line 1667 "wcspih.l" { if (relax & WCSHDR_reject) { // Looks too much like a FITS WCS keyword not to flag it. errmsg = errtxt; sprintf(errmsg, "invalid alternate code, keyword resembles %s " "but isn't", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 196: #line 1682 "wcspih.l" case 197: #line 1683 "wcspih.l" case 198: #line 1684 "wcspih.l" case 199: YY_RULE_SETUP #line 1684 "wcspih.l" { sscanf(yytext, "%d_%d%c", &i, &m, &a); BEGIN(VALUE); } YY_BREAK case 200: #line 1690 "wcspih.l" case 201: #line 1691 "wcspih.l" case 202: #line 1692 "wcspih.l" case 203: #line 1693 "wcspih.l" case 204: #line 1694 "wcspih.l" case 205: #line 1695 "wcspih.l" case 206: #line 1696 "wcspih.l" case 207: #line 1697 "wcspih.l" case 208: #line 1698 "wcspih.l" case 209: #line 1699 "wcspih.l" case 210: #line 1700 "wcspih.l" case 211: #line 1701 "wcspih.l" case 212: #line 1702 "wcspih.l" case 213: #line 1703 "wcspih.l" case 214: #line 1704 "wcspih.l" case 215: #line 1705 "wcspih.l" case 216: #line 1706 "wcspih.l" case 217: #line 1707 "wcspih.l" case 218: #line 1708 "wcspih.l" case 219: #line 1709 "wcspih.l" case 220: YY_RULE_SETUP #line 1709 "wcspih.l" { if (((valtype == FLOAT) && (relax & WCSHDR_PV0i_0ma)) || ((valtype == STRING) && (relax & WCSHDR_PS0i_0ma))) { sscanf(yytext, "%d_%d%c", &i, &m, &a); BEGIN(VALUE); } else if (relax & WCSHDR_reject) { errmsg = "indices in parameterized keywords must not have " "leading zeroes"; BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 221: #line 1727 "wcspih.l" case 222: #line 1728 "wcspih.l" case 223: #line 1729 "wcspih.l" case 224: #line 1730 "wcspih.l" case 225: #line 1731 "wcspih.l" case 226: #line 1732 "wcspih.l" case 227: #line 1733 "wcspih.l" case 228: #line 1734 "wcspih.l" case 229: #line 1735 "wcspih.l" case 230: YY_RULE_SETUP #line 1735 "wcspih.l" { // Anything that has fallen through to this point must contain // an invalid axis number. errmsg = "axis number must exceed 0"; BEGIN(ERROR); } YY_BREAK case 231: #line 1743 "wcspih.l" case 232: #line 1744 "wcspih.l" case 233: #line 1745 "wcspih.l" case 234: #line 1746 "wcspih.l" case 235: #line 1747 "wcspih.l" case 236: #line 1748 "wcspih.l" case 237: #line 1749 "wcspih.l" case 238: #line 1750 "wcspih.l" case 239: #line 1751 "wcspih.l" case 240: YY_RULE_SETUP #line 1751 "wcspih.l" { errmsg = errtxt; sprintf(errmsg, "%s keyword must use an underscore, not a dash", keyname); BEGIN(ERROR); } YY_BREAK case 241: YY_RULE_SETUP #line 1758 "wcspih.l" { BEGIN(DISCARD); } YY_BREAK case 242: #line 1763 "wcspih.l" case 243: #line 1764 "wcspih.l" case 244: YY_RULE_SETUP #line 1764 "wcspih.l" { a = ' '; sscanf(yytext, "%d%c", &i, &a); if (relax & WCSHDR_strict) { errmsg = "the CROTAn keyword is deprecated, use PCi_ja"; BEGIN(ERROR); } else if ((a == ' ') || (relax & WCSHDR_CROTAia)) { yyless(0); BEGIN(CCCCCia); } else if (relax & WCSHDR_reject) { errmsg = "CROTAn keyword may not have an alternate version code"; BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } YY_BREAK case 245: YY_RULE_SETUP #line 1786 "wcspih.l" { yyless(0); BEGIN(CCCCCia); } YY_BREAK case 246: YY_RULE_SETUP #line 1791 "wcspih.l" { if (relax & WCSHDR_PROJPn) { sscanf(yytext, "%d", &m); i = 0; a = ' '; BEGIN(VALUE); } else if (relax & WCSHDR_reject) { errmsg = "the PROJPn keyword is deprecated, use PVi_ma"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 247: #line 1808 "wcspih.l" case 248: YY_RULE_SETUP #line 1808 "wcspih.l" { if (relax & (WCSHDR_PROJPn | WCSHDR_reject)) { errmsg = "invalid PROJPn keyword"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } YY_BREAK case 249: YY_RULE_SETUP #line 1818 "wcspih.l" { BEGIN(DISCARD); } YY_BREAK case 250: #line 1823 "wcspih.l" case 251: YY_RULE_SETUP #line 1823 "wcspih.l" { // SIP keywords. valtype = FLOAT; distype = PRIOR; vptr = &(distem.dp); npptr = ndp; a = ' '; distran = SIP; sscanf(yytext, "%d_%d", &p, &q); BEGIN(VALUE); } YY_BREAK case 252: #line 1838 "wcspih.l" case 253: YY_RULE_SETUP #line 1838 "wcspih.l" { BEGIN(DISCARD); } YY_BREAK case 254: #line 1843 "wcspih.l" case 255: YY_RULE_SETUP #line 1843 "wcspih.l" { // DSS keywords. valtype = FLOAT; distype = SEQUENT; vptr = &(distem.dp); npptr = ndq; a = ' '; distran = DSS; sscanf(yytext, "%d", &m); BEGIN(VALUE); } YY_BREAK case 256: YY_RULE_SETUP #line 1857 "wcspih.l" { BEGIN(DISCARD); } YY_BREAK case 257: /* rule 257 can match eol */ YY_RULE_SETUP #line 1861 "wcspih.l" { // Special handling for this iconic DSS keyword. if (1 < ipass) { // Look for a minus sign. sscanf(yytext, "= '%s", strtmp); dbltmp = strcmp(strtmp, "-") ? 1.0 : -1.0; } BEGIN(COMMENT); } YY_BREAK case 258: YY_RULE_SETUP #line 1872 "wcspih.l" { BEGIN(DISCARD); } YY_BREAK case 259: YY_RULE_SETUP #line 1876 "wcspih.l" { // Do checks on i, j & m. if (99 < i || 99 < j || 99 < m) { if (relax & WCSHDR_reject) { if (99 < i || 99 < j) { errmsg = "axis number exceeds 99"; } else if (m > 99) { errmsg = "parameter number exceeds 99"; } BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } else { if (valtype == INTEGER) { BEGIN(INTEGER_VAL); } else if (valtype == FLOAT) { BEGIN(FLOAT_VAL); } else if (valtype == FLOAT2) { BEGIN(FLOAT2_VAL); } else if (valtype == STRING) { BEGIN(STRING_VAL); } else if (valtype == RECORD) { BEGIN(RECORD_VAL); } else { errmsg = errtxt; sprintf(errmsg, "internal parser ERROR, bad data type: %d", valtype); BEGIN(ERROR); } } } YY_BREAK case 260: YY_RULE_SETUP #line 1912 "wcspih.l" { errmsg = "invalid KEYWORD = VALUE syntax"; BEGIN(ERROR); } YY_BREAK case 261: YY_RULE_SETUP #line 1917 "wcspih.l" { if (ipass == 1) { BEGIN(COMMENT); } else { // Read the keyvalue. sscanf(yytext, "%d", &inttmp); BEGIN(COMMENT); } } YY_BREAK case 262: YY_RULE_SETUP #line 1929 "wcspih.l" { errmsg = "an integer value was expected"; BEGIN(ERROR); } YY_BREAK case 263: YY_RULE_SETUP #line 1934 "wcspih.l" { if (ipass == 1) { BEGIN(COMMENT); } else { // Read the keyvalue. wcsutil_str2double(yytext, &dbltmp); if (chekval && chekval(dbltmp)) { errmsg = "invalid keyvalue"; BEGIN(ERROR); } else { BEGIN(COMMENT); } } } YY_BREAK case 264: YY_RULE_SETUP #line 1951 "wcspih.l" { errmsg = "a floating-point value was expected"; BEGIN(ERROR); } YY_BREAK case 265: YY_RULE_SETUP #line 1956 "wcspih.l" { if (ipass == 1) { BEGIN(COMMENT); } else { // Read the keyvalue as integer and fractional parts. wcsutil_str2double2(yytext, dbl2tmp); BEGIN(COMMENT); } } YY_BREAK case 266: YY_RULE_SETUP #line 1968 "wcspih.l" { errmsg = "a floating-point value was expected"; BEGIN(ERROR); } YY_BREAK case 267: /* rule 267 can match eol */ YY_RULE_SETUP #line 1973 "wcspih.l" { if (ipass == 1) { BEGIN(COMMENT); } else { // Read the keyvalue. strcpy(strtmp, yytext+1); // Squeeze out repeated quotes. int ix = 0; for (int jx = 0; jx < 72; jx++) { if (ix < jx) { strtmp[ix] = strtmp[jx]; } if (strtmp[jx] == '\0') { if (ix) strtmp[ix-1] = '\0'; break; } else if (strtmp[jx] == '\'' && strtmp[jx+1] == '\'') { jx++; } ix++; } BEGIN(COMMENT); } } YY_BREAK case 268: YY_RULE_SETUP #line 2002 "wcspih.l" { errmsg = "a string value was expected"; BEGIN(ERROR); } YY_BREAK case 269: /* rule 269 can match eol */ YY_RULE_SETUP #line 2007 "wcspih.l" { if (ipass == 1) { BEGIN(COMMENT); } else { yyless(1); BEGIN(RECFIELD); } } YY_BREAK case 270: YY_RULE_SETUP #line 2018 "wcspih.l" { errmsg = "a record was expected"; BEGIN(ERROR); } YY_BREAK case 271: YY_RULE_SETUP #line 2023 "wcspih.l" { strcpy(strtmp, yytext); BEGIN(RECCOLON); } YY_BREAK case 272: YY_RULE_SETUP #line 2028 "wcspih.l" { errmsg = "invalid record field"; BEGIN(ERROR); } YY_BREAK case 273: YY_RULE_SETUP #line 2033 "wcspih.l" { BEGIN(RECVALUE); } YY_BREAK case 274: YY_RULE_SETUP #line 2037 "wcspih.l" { errmsg = "invalid record syntax"; BEGIN(ERROR); } YY_BREAK case 275: YY_RULE_SETUP #line 2042 "wcspih.l" { rectype = 0; sscanf(yytext, "%d", &inttmp); BEGIN(RECEND); } YY_BREAK case 276: YY_RULE_SETUP #line 2048 "wcspih.l" { rectype = 1; wcsutil_str2double(yytext, &dbltmp); BEGIN(RECEND); } YY_BREAK case 277: YY_RULE_SETUP #line 2054 "wcspih.l" { errmsg = "invalid record value"; BEGIN(ERROR); } YY_BREAK case 278: YY_RULE_SETUP #line 2059 "wcspih.l" { BEGIN(COMMENT); } YY_BREAK case 279: *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ yyg->yy_c_buf_p = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 2063 "wcspih.l" { if (ipass == 1) { // Do first-pass bookkeeping. wcspih_pass1(naxis, i, j, a, distype, alts, dpq, npptr); BEGIN(FLUSH); } else if (*wcs) { // Store the value now that the keyrecord has been validated. int gotone = 0; for (int ialt = 0; ialt < *nwcs; ialt++) { // The loop here is for keywords that apply // to every alternate; these have a == 0. if (a >= 'A') { ialt = alts[a-'A'+1]; if (ialt < 0) break; } gotone = 1; if (vptr) { if (sipflag) { // Translate a SIP keyword into DPja. struct disprm *disp = (*wcs)->lin.dispre; int ipx = (disp->ndp)++; // SIP doesn't have alternates. char keyword[16]; sprintf(keyword, "DP%d", i); sprintf(strtmp, "SIP.%s.%d_%d", (sipflag==2)?"FWD":"REV", p, q); if (valtype == INTEGER) { dpfill(disp->dp+ipx, keyword, strtmp, i, 0, inttmp, 0.0); } else { dpfill(disp->dp+ipx, keyword, strtmp, i, 1, 0, dbltmp); } } else if (dssflag) { // All DSS keywords require special handling. if (dssflag == 1) { // Temporary parameter for DSS used by wcspih_final(). *((double *)vptr) = dbltmp; } else if (dssflag == 2) { // Temporary parameter for DSS used by wcspih_final(). strcpy((char *)vptr, strtmp); } else { // Translate a DSS keyword into DQia. if (m <= 13 || dbltmp != 0.0) { struct disprm *disp = (*wcs)->lin.disseq; int ipx = (disp->ndp)++; // DSS doesn't have alternates. char keyword[16]; sprintf(keyword, "DQ%d", i); sprintf(strtmp, "DSS.AMD.%d", m); dpfill(disp->dp+ipx, keyword, strtmp, i, 1, 0, dbltmp); // Also required by wcspih_final(). if (m <= 3) { dsstmp[13+(i-1)*3+m] = dbltmp; } } } } else if (watflag) { // String array for TNX and ZPX used by wcspih_final(). strcpy((char *)vptr, strtmp); } else { // An "ordinary" keyword. struct wcsprm *wcsp = *wcs + ialt; struct disprm *disp; void *wptr; ptrdiff_t voff; if (auxprm) { // Additional auxiliary parameter. struct auxprm *auxp = wcsp->aux; voff = (char *)vptr - (char *)(&auxtem); wptr = (void *)((char *)auxp + voff); } else if (distype) { // Distortion parameter of some kind. if (distype == PRIOR) { // Prior distortion. disp = wcsp->lin.dispre; } else { // Sequent distortion. disp = wcsp->lin.disseq; } voff = (char *)vptr - (char *)(&distem); wptr = (void *)((char *)disp + voff); } else { // A parameter that lives directly in wcsprm. voff = (char *)vptr - (char *)(&wcstem); wptr = (void *)((char *)wcsp + voff); } if (valtype == INTEGER) { *((int *)wptr) = inttmp; } else if (valtype == FLOAT) { // Apply keyword parameterization. if (npptr == npv) { int ipx = (wcsp->npv)++; wcsp->pv[ipx].i = i; wcsp->pv[ipx].m = m; wptr = &(wcsp->pv[ipx].value); } else if (j) { wptr = *((double **)wptr) + (i - 1)*(wcsp->naxis) + (j - 1); } else if (i) { wptr = *((double **)wptr) + (i - 1); } if (special) { special(wptr, &dbltmp); } else { *((double *)wptr) = dbltmp; } // Flag presence of PCi_ja, or CDi_ja and/or CROTAia. if (altlin) { wcsp->altlin |= altlin; altlin = 0; } } else if (valtype == FLOAT2) { // Split MJDREF and JDREF into integer and fraction. if (special) { special(wptr, dbl2tmp); } else { *((double *)wptr) = dbl2tmp[0]; *((double *)wptr + 1) = dbl2tmp[1]; } } else if (valtype == STRING) { // Apply keyword parameterization. if (npptr == nps) { int ipx = (wcsp->nps)++; wcsp->ps[ipx].i = i; wcsp->ps[ipx].m = m; wptr = wcsp->ps[ipx].value; } else if (j) { wptr = *((char (**)[72])wptr) + (i - 1)*(wcsp->naxis) + (j - 1); } else if (i) { wptr = *((char (**)[72])wptr) + (i - 1); } char *cptr = (char *)wptr; strcpy(cptr, strtmp); } else if (valtype == RECORD) { int ipx = (disp->ndp)++; char keyword[16]; if (a == ' ') { sprintf(keyword, "%.2s%d", keyname, i); } else { sprintf(keyword, "%.2s%d%c", keyname, i, a); } dpfill(disp->dp+ipx, keyword, strtmp, i, rectype, inttmp, dbltmp); } } } if (a) break; } if (gotone) { nvalid++; if (ctrl == 4) { if (distran || dssflag) { wcsfprintf(stderr, "%.80s\n Accepted (%d) as a " "recognized WCS convention.\n", keyrec, nvalid); } else { wcsfprintf(stderr, "%.80s\n Accepted (%d) as a " "valid WCS keyrecord.\n", keyrec, nvalid); } } BEGIN(FLUSH); } else { errmsg = "syntactically valid WCS keyrecord has no effect"; BEGIN(ERROR); } } else { BEGIN(FLUSH); } } YY_BREAK case 280: *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ yyg->yy_c_buf_p = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 2263 "wcspih.l" { errmsg = "invalid keyvalue"; BEGIN(ERROR); } YY_BREAK case 281: *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ yyg->yy_c_buf_p = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 2268 "wcspih.l" { errmsg = "invalid keyvalue"; BEGIN(ERROR); } YY_BREAK case 282: *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ yyg->yy_c_buf_p = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 2273 "wcspih.l" { errmsg = "invalid keyvalue or malformed keycomment"; BEGIN(ERROR); } YY_BREAK case 283: *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ yyg->yy_c_buf_p = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 2278 "wcspih.l" { errmsg = "malformed keycomment"; BEGIN(ERROR); } YY_BREAK case 284: *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ yyg->yy_c_buf_p = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 2283 "wcspih.l" { if (ipass == npass) { if (ctrl < 0) { // Preserve discards. keep = keyrec; } else if (2 < ctrl) { nother++; wcsfprintf(stderr, "%.80s\n Not a recognized WCS keyword.\n", keyrec); } } BEGIN(FLUSH); } YY_BREAK case 285: *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ yyg->yy_c_buf_p = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 2298 "wcspih.l" { if (ipass == npass) { (*nreject)++; if (ctrl%10 == -1) { // Preserve rejects. keep = keyrec; } if (1 < abs(ctrl%10)) { wcsfprintf(stderr, "%.80s\n Rejected (%d), %s.\n", keyrec, *nreject, errmsg); } } BEGIN(FLUSH); } YY_BREAK case 286: /* rule 286 can match eol */ YY_RULE_SETUP #line 2315 "wcspih.l" { if (ipass == npass && keep) { if (hptr < keep) { strncpy(hptr, keep, 80); } hptr += 80; } naux += auxprm; // Throw away the rest of the line and reset for the next one. i = j = 0; m = 0; a = ' '; keyrec += 80; valtype = -1; distype = 0; vptr = 0x0; keep = 0x0; altlin = 0; npptr = 0x0; chekval = 0x0; special = 0x0; auxprm = 0; sipflag = 0; dssflag = 0; watflag = 0; BEGIN(INITIAL); } YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(CCia): case YY_STATE_EOF(CCi_ja): case YY_STATE_EOF(CCCCCia): case YY_STATE_EOF(CCi_ma): case YY_STATE_EOF(CCCCCCCa): case YY_STATE_EOF(CCCCCCCC): case YY_STATE_EOF(CROTAi): case YY_STATE_EOF(PROJPn): case YY_STATE_EOF(SIP2): case YY_STATE_EOF(SIP3): case YY_STATE_EOF(DSSAMDXY): case YY_STATE_EOF(PLTDECSN): case YY_STATE_EOF(VALUE): case YY_STATE_EOF(INTEGER_VAL): case YY_STATE_EOF(FLOAT_VAL): case YY_STATE_EOF(FLOAT2_VAL): case YY_STATE_EOF(STRING_VAL): case YY_STATE_EOF(RECORD_VAL): case YY_STATE_EOF(RECFIELD): case YY_STATE_EOF(RECCOLON): case YY_STATE_EOF(RECVALUE): case YY_STATE_EOF(RECEND): case YY_STATE_EOF(COMMENT): case YY_STATE_EOF(DISCARD): case YY_STATE_EOF(ERROR): case YY_STATE_EOF(FLUSH): #line 2349 "wcspih.l" { // End-of-input. int status; if (ipass == 1) { if ((status = wcspih_init1(naxis, alts, dpq, npv, nps, ndp, ndq, naux, distran, nwcs, wcs)) || (*nwcs == 0 && ctrl == 0)) { return status; } if (2 < abs(ctrl%10)) { if (*nwcs == 1) { if (strcmp(wcs[0]->wcsname, "DEFAULTS") != 0) { wcsfprintf(stderr, "Found one coordinate representation.\n"); } } else { wcsfprintf(stderr, "Found %d coordinate representations.\n", *nwcs); } } watstr = calloc(2*(watn*68 + 1), sizeof(char)); wat[0] = watstr; wat[1] = watstr + watn*68 + 1; } if (ipass++ < npass) { yyextra->hdr = header; yyextra->nkeyrec = nkeyrec; keyrec = header; *nreject = 0; i = j = 0; m = 0; a = ' '; valtype = -1; distype = 0; vptr = 0x0; altlin = 0; npptr = 0x0; chekval = 0x0; special = 0x0; auxprm = 0; sipflag = 0; dssflag = 0; watflag = 0; yyrestart(yyin, yyscanner); } else { if (ctrl < 0) { *hptr = '\0'; } else if (ctrl == 1) { wcsfprintf(stderr, "%d WCS keyrecord%s rejected.\n", *nreject, (*nreject==1)?" was":"s were"); } else if (ctrl == 4) { wcsfprintf(stderr, "\n"); wcsfprintf(stderr, "%5d keyrecord%s rejected for syntax or " "other errors,\n", *nreject, (*nreject==1)?" was":"s were"); wcsfprintf(stderr, "%5d %s recognized as syntactically valid, " "and\n", nvalid, (nvalid==1)?"was":"were"); wcsfprintf(stderr, "%5d other%s were not recognized as WCS " "keyrecords.\n", nother, (nother==1)?"":"s"); } status = wcspih_final(ndp, ndq, distran, dsstmp, wat, nwcs, wcs); free(watstr); return status; } } YY_BREAK case 287: YY_RULE_SETUP #line 2423 "wcspih.l" ECHO; YY_BREAK #line 24160 "wcspih.c" case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = yyg->yy_hold_char; YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) { /* This was really a NUL. */ yy_state_type yy_next_state; yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++yyg->yy_c_buf_p; yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = yyg->yy_c_buf_p; goto yy_find_action; } } else switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_END_OF_FILE: { yyg->yy_did_buffer_switch_on_eof = 0; if ( yywrap( yyscanner ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: yyg->yy_c_buf_p = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of user's declarations */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; char *source = yyg->yytext_ptr; int number_to_move, i; int ret_val; if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1); for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) (yyg->yy_c_buf_p - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yyrealloc( (void *) b->yy_ch_buf, (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = NULL; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), yyg->yy_n_chars, num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } if ( yyg->yy_n_chars == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin , yyscanner); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); /* "- 2" to take care of EOB's */ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); } yyg->yy_n_chars += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (yyscan_t yyscanner) { yy_state_type yy_current_state; char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_current_state = yyg->yy_start; yy_current_state += YY_AT_BOL(); for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) { if ( *yy_cp ) { yy_current_state = yy_nxt[yy_current_state][YY_SC_TO_UI(*yy_cp)]; } else yy_current_state = yy_NUL_trans[yy_current_state]; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) { int yy_is_jam; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ char *yy_cp = yyg->yy_c_buf_p; yy_current_state = yy_NUL_trans[yy_current_state]; yy_is_jam = (yy_current_state == 0); if ( ! yy_is_jam ) { if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } } (void)yyg; return yy_is_jam ? 0 : yy_current_state; } #ifndef YY_NO_UNPUT static void yyunput (int c, char * yy_bp , yyscan_t yyscanner) { char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_cp = yyg->yy_c_buf_p; /* undo effects of setting up yytext */ *yy_cp = yyg->yy_hold_char; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ int number_to_move = yyg->yy_n_chars + 2; char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; yyg->yytext_ptr = yy_bp; yyg->yy_hold_char = *yy_cp; yyg->yy_c_buf_p = yy_cp; } #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (yyscan_t yyscanner) #else static int input (yyscan_t yyscanner) #endif { int c; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; *yyg->yy_c_buf_p = yyg->yy_hold_char; if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) /* This was really a NUL. */ *yyg->yy_c_buf_p = '\0'; else { /* need more input */ int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr); ++yyg->yy_c_buf_p; switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin , yyscanner); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( yyscanner ) ) return 0; if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(yyscanner); #else return input(yyscanner); #endif } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + offset; break; } } } c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ yyg->yy_hold_char = *++yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * @param yyscanner The scanner object. * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } yy_init_buffer( YY_CURRENT_BUFFER, input_file , yyscanner); yy_load_buffer_state( yyscanner ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * @param yyscanner The scanner object. */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (yyscanner); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( yyscanner ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ yyg->yy_did_buffer_switch_on_eof = 1; } static void yy_load_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; yyg->yy_hold_char = *yyg->yy_c_buf_p; } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * @param yyscanner The scanner object. * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file , yyscanner); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * @param yyscanner The scanner object. */ void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree( (void *) b->yy_ch_buf , yyscanner ); yyfree( (void *) b , yyscanner ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) { int oerrno = errno; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_flush_buffer( b , yyscanner); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * @param yyscanner The scanner object. */ void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( yyscanner ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * @param yyscanner The scanner object. */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (new_buffer == NULL) return; yyensure_buffer_stack(yyscanner); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) yyg->yy_buffer_stack_top++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * @param yyscanner The scanner object. */ void yypop_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER , yyscanner); YY_CURRENT_BUFFER_LVALUE = NULL; if (yyg->yy_buffer_stack_top > 0) --yyg->yy_buffer_stack_top; if (YY_CURRENT_BUFFER) { yy_load_buffer_state( yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (yyscan_t yyscanner) { yy_size_t num_to_alloc; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!yyg->yy_buffer_stack) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; yyg->yy_buffer_stack_top = 0; return; } if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ /* Increase the buffer to prepare for a possible push. */ yy_size_t grow_size = 8 /* arbitrary grow size */; num_to_alloc = yyg->yy_buffer_stack_max + grow_size; yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc (yyg->yy_buffer_stack, num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return NULL; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = NULL; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer( b , yyscanner ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * @param yyscanner The scanner object. * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (const char * yystr , yyscan_t yyscanner) { return yy_scan_bytes( yystr, (int) strlen(yystr) , yyscanner); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len , yyscan_t yyscanner) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = (yy_size_t) (_yybytes_len + 2); buf = (char *) yyalloc( n , yyscanner ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer( buf, n , yyscanner); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yynoreturn yy_fatal_error (const char* msg , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = yyg->yy_hold_char; \ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ yyg->yy_hold_char = *yyg->yy_c_buf_p; \ *yyg->yy_c_buf_p = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the user-defined data for this scanner. * @param yyscanner The scanner object. */ YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyextra; } /** Get the current line number. * @param yyscanner The scanner object. */ int yyget_lineno (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yylineno; } /** Get the current column number. * @param yyscanner The scanner object. */ int yyget_column (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yycolumn; } /** Get the input stream. * @param yyscanner The scanner object. */ FILE *yyget_in (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyin; } /** Get the output stream. * @param yyscanner The scanner object. */ FILE *yyget_out (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyout; } /** Get the length of the current token. * @param yyscanner The scanner object. */ int yyget_leng (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyleng; } /** Get the current token. * @param yyscanner The scanner object. */ char *yyget_text (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yytext; } /** Set the user-defined data. This data is never touched by the scanner. * @param user_defined The data to be associated with this scanner. * @param yyscanner The scanner object. */ void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyextra = user_defined ; } /** Set the current line number. * @param _line_number line number * @param yyscanner The scanner object. */ void yyset_lineno (int _line_number , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* lineno is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "yyset_lineno called with no buffer" ); yylineno = _line_number; } /** Set the current column. * @param _column_no column number * @param yyscanner The scanner object. */ void yyset_column (int _column_no , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* column is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "yyset_column called with no buffer" ); yycolumn = _column_no; } /** Set the input stream. This does not discard the current * input buffer. * @param _in_str A readable stream. * @param yyscanner The scanner object. * @see yy_switch_to_buffer */ void yyset_in (FILE * _in_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyin = _in_str ; } void yyset_out (FILE * _out_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyout = _out_str ; } int yyget_debug (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yy_flex_debug; } void yyset_debug (int _bdebug , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_flex_debug = _bdebug ; } /* Accessor methods for yylval and yylloc */ /* User-visible API */ /* yylex_init is special because it creates the scanner itself, so it is * the ONLY reentrant function that doesn't take the scanner as the last argument. * That's why we explicitly handle the declaration, instead of using our macros. */ int yylex_init(yyscan_t* ptr_yy_globals) { if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); return yy_init_globals ( *ptr_yy_globals ); } /* yylex_init_extra has the same functionality as yylex_init, but follows the * convention of taking the scanner as the last argument. Note however, that * this is a *pointer* to a scanner, as it will be allocated by this call (and * is the reason, too, why this function also must handle its own declaration). * The user defined value in the first argument will be available to yyalloc in * the yyextra field. */ int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals ) { struct yyguts_t dummy_yyguts; yyset_extra (yy_user_defined, &dummy_yyguts); if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); yyset_extra (yy_user_defined, *ptr_yy_globals); return yy_init_globals ( *ptr_yy_globals ); } static int yy_init_globals (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ yyg->yy_buffer_stack = NULL; yyg->yy_buffer_stack_top = 0; yyg->yy_buffer_stack_max = 0; yyg->yy_c_buf_p = NULL; yyg->yy_init = 0; yyg->yy_start = 0; yyg->yy_start_stack_ptr = 0; yyg->yy_start_stack_depth = 0; yyg->yy_start_stack = NULL; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = NULL; yyout = NULL; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer( YY_CURRENT_BUFFER , yyscanner ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(yyscanner); } /* Destroy the stack itself. */ yyfree(yyg->yy_buffer_stack , yyscanner); yyg->yy_buffer_stack = NULL; /* Destroy the start condition stack. */ yyfree( yyg->yy_start_stack , yyscanner ); yyg->yy_start_stack = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( yyscanner); /* Destroy the main struct (reentrant only). */ yyfree ( yyscanner , yyscanner ); yyscanner = NULL; return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (const char * s , yyscan_t yyscanner) { int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; return malloc(size); } void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return realloc(ptr, size); } void yyfree (void * ptr , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 2423 "wcspih.l" /*---------------------------------------------------------------------------- * External interface to the scanner. *---------------------------------------------------------------------------*/ int wcspih( char *header, int nkeyrec, int relax, int ctrl, int *nreject, int *nwcs, struct wcsprm **wcs) { // Function prototypes. int yylex_init_extra(YY_EXTRA_TYPE extra, yyscan_t *yyscanner); int yylex_destroy(yyscan_t yyscanner); struct wcspih_extra extra; yyscan_t yyscanner; yylex_init_extra(&extra, &yyscanner); int status = wcspih_scanner(header, nkeyrec, relax, ctrl, nreject, nwcs, wcs, yyscanner); yylex_destroy(yyscanner); return status; } /*---------------------------------------------------------------------------- * Determine the number of coordinate representations (up to 27) and the * number of coordinate axes in each, which distortions are present, and the * number of PVi_ma, PSi_ma, DPja, and DQia keywords in each representation. *---------------------------------------------------------------------------*/ void wcspih_pass1( int naxis, int i, int j, char a, int distype, int alts[], int dpq[], int *npptr) { // On the first pass alts[] is used to determine the number of axes // for each of the 27 possible alternate coordinate descriptions. if (a == 0) { return; } int ialt = 0; if (a != ' ') { ialt = a - 'A' + 1; } int *ip = alts + ialt; if (*ip < naxis) { *ip = naxis; } // i or j can be greater than naxis. if (*ip < i) { *ip = i; } if (*ip < j) { *ip = j; } // Type of distortions present. dpq[ialt] |= distype; // Count PVi_ma, PSi_ma, DPja, or DQia keywords. if (npptr) { npptr[ialt]++; } } /*---------------------------------------------------------------------------- * Allocate memory for an array of the required number of wcsprm structs and * initialize each of them. *---------------------------------------------------------------------------*/ int wcspih_init1( int naxis, int alts[], int dpq[], int npv[], int nps[], int ndp[], int ndq[], int naux, int distran, int *nwcs, struct wcsprm **wcs) { int status = 0; // Find the number of coordinate descriptions. *nwcs = 0; for (int ialt = 0; ialt < 27; ialt++) { if (alts[ialt]) (*nwcs)++; } int defaults; if ((defaults = !(*nwcs) && naxis)) { // NAXIS is non-zero but there were no WCS keywords with an alternate // version code; create a default WCS with blank alternate version. wcspih_pass1(naxis, 0, 0, ' ', 0, alts, dpq, 0x0); *nwcs = 1; } if (*nwcs) { // Allocate memory for the required number of wcsprm structs. if ((*wcs = calloc(*nwcs, sizeof(struct wcsprm))) == 0x0) { return WCSHDRERR_MEMORY; } int ndis = 0; if (distran == SIP) { // DPja.NAXES and DPja.OFFSET.j to be added for SIP (see below and // wcspih_final()). ndp[0] += 6; } else if (distran == DSS) { // DPja.NAXES to be added for DSS (see below and wcspih_final()). ndq[0] += 2; } // Initialize each wcsprm struct. struct wcsprm *wcsp = *wcs; *nwcs = 0; for (int ialt = 0; ialt < 27; ialt++) { if (alts[ialt]) { wcsp->flag = -1; int npvmax = npv[ialt]; int npsmax = nps[ialt]; if ((status = wcsinit(1, alts[ialt], wcsp, npvmax, npsmax, -1))) { wcsvfree(nwcs, wcs); break; } // Record the alternate version code. if (ialt) { wcsp->alt[0] = 'A' + ialt - 1; } // Record in wcsname whether this is a default description. if (defaults) { strcpy(wcsp->wcsname, "DEFAULTS"); } // Any additional auxiliary keywords present? if (naux) { if (wcsauxi(1, wcsp)) { return WCSHDRERR_MEMORY; } } // Any distortions present? struct disprm *disp; if (dpq[ialt] & 1) { if ((disp = calloc(1, sizeof(struct disprm))) == 0x0) { return WCSHDRERR_MEMORY; } // Attach it to linprm. Also inits it. ndis++; int ndpmax = ndp[ialt]; disp->flag = -1; lindist(1, &(wcsp->lin), disp, ndpmax); } if (dpq[ialt] & 2) { if ((disp = calloc(1, sizeof(struct disprm))) == 0x0) { return WCSHDRERR_MEMORY; } // Attach it to linprm. Also inits it. ndis++; int ndpmax = ndq[ialt]; disp->flag = -1; lindist(2, &(wcsp->lin), disp, ndpmax); } // On the second pass alts[] indexes the array of wcsprm structs. alts[ialt] = (*nwcs)++; wcsp++; } else { // Signal that there is no wcsprm for this alt. alts[ialt] = -1; } } // Translated distortion? Neither SIP nor DSS have alternates, so the // presence of keywords for either (not both together), as flagged by // distran, necessarily refers to the primary representation. if (distran == SIP) { strcpy((*wcs)->lin.dispre->dtype[0], "SIP"); strcpy((*wcs)->lin.dispre->dtype[1], "SIP"); // SIP doesn't have axis mapping. (*wcs)->lin.dispre->ndp = 6; dpfill((*wcs)->lin.dispre->dp, "DP1", "NAXES", 0, 0, 2, 0.0); dpfill((*wcs)->lin.dispre->dp+3, "DP2", "NAXES", 0, 0, 2, 0.0); } else if (distran == DSS) { strcpy((*wcs)->lin.disseq->dtype[0], "DSS"); strcpy((*wcs)->lin.disseq->dtype[1], "DSS"); // The Paper IV translation of DSS doesn't require an axis mapping. (*wcs)->lin.disseq->ndp = 2; dpfill((*wcs)->lin.disseq->dp, "DQ1", "NAXES", 0, 0, 2, 0.0); dpfill((*wcs)->lin.disseq->dp+1, "DQ2", "NAXES", 0, 0, 2, 0.0); } } return status; } /*---------------------------------------------------------------------------- * Interpret the JDREF, JDREFI, and JDREFF keywords. *---------------------------------------------------------------------------*/ int wcspih_jdref(double *mjdref, const double *jdref) { // Set MJDREF from JDREF. if (undefined(mjdref[0] && undefined(mjdref[1]))) { mjdref[0] = jdref[0] - 2400000.0; mjdref[1] = jdref[1] - 0.5; if (mjdref[1] < 0.0) { mjdref[0] -= 1.0; mjdref[1] += 1.0; } } return 0; } int wcspih_jdrefi(double *mjdref, const double *jdrefi) { // Set the integer part of MJDREF from JDREFI. if (undefined(mjdref[0])) { mjdref[0] = *jdrefi - 2400000.5; } return 0; } int wcspih_jdreff(double *mjdref, const double *jdreff) { // Set the fractional part of MJDREF from JDREFF. if (undefined(mjdref[1])) { mjdref[1] = *jdreff; } return 0; } /*---------------------------------------------------------------------------- * Interpret EPOCHa keywords. *---------------------------------------------------------------------------*/ int wcspih_epoch(double *equinox, const double *epoch) { // If EQUINOXa is currently undefined then set it from EPOCHa. if (undefined(*equinox)) { *equinox = *epoch; } return 0; } /*---------------------------------------------------------------------------- * Interpret VSOURCEa keywords. *---------------------------------------------------------------------------*/ int wcspih_vsource(double *zsource, const double *vsource) { const double c = 299792458.0; // If ZSOURCEa is currently undefined then set it from VSOURCEa. if (undefined(*zsource)) { // Convert relativistic Doppler velocity to redshift. double beta = *vsource/c; *zsource = (1.0 + beta)/sqrt(1.0 - beta*beta) - 1.0; } return 0; } /*---------------------------------------------------------------------------- * Check validity of a TIMEPIXR keyvalue. *---------------------------------------------------------------------------*/ int wcspih_timepixr(double timepixr) { return (timepixr < 0.0 || 1.0 < timepixr); } /*---------------------------------------------------------------------------- * Interpret special keywords encountered for each coordinate representation. *---------------------------------------------------------------------------*/ int wcspih_final( int ndp[], int ndq[], int distran, double dsstmp[], char *wat[], int *nwcs, struct wcsprm **wcs) { for (int ialt = 0; ialt < *nwcs; ialt++) { // Interpret -TAB header keywords. int status; if ((status = wcstab(*wcs+ialt))) { wcsvfree(nwcs, wcs); return status; } if (ndp[ialt] && ndq[ialt]) { // Prior and sequent distortions co-exist in this representation; // ensure the latter gets DVERRa. (*wcs+ialt)->lin.disseq->totdis = (*wcs+ialt)->lin.dispre->totdis; } } // Translated distortion functions; apply only to the primary WCS. struct wcsprm *wcsp = *wcs; if (distran == SIP) { // SIP doesn't have alternates, nor axis mapping. struct disprm *disp = wcsp->lin.dispre; dpfill(disp->dp+1, "DP1", "OFFSET.1", 0, 1, 0, wcsp->crpix[0]); dpfill(disp->dp+2, "DP1", "OFFSET.2", 0, 1, 0, wcsp->crpix[1]); dpfill(disp->dp+4, "DP2", "OFFSET.1", 0, 1, 0, wcsp->crpix[0]); dpfill(disp->dp+5, "DP2", "OFFSET.2", 0, 1, 0, wcsp->crpix[1]); } else if (distran == DSS) { // DSS doesn't have alternates, nor axis mapping. This translation // follows Paper IV, Sect. 5.2 using the same variable names. double CNPIX1 = dsstmp[0]; double CNPIX2 = dsstmp[1]; double Xc = dsstmp[2]/1000.0; double Yc = dsstmp[3]/1000.0; double Rx = dsstmp[4]/1000.0; double Ry = dsstmp[5]/1000.0; double A1 = dsstmp[14]; double A2 = dsstmp[15]; double A3 = dsstmp[16]; double B1 = dsstmp[17]; double B2 = dsstmp[18]; double B3 = dsstmp[19]; double S = sqrt(fabs(A1*B1 - A2*B2)); double X0 = (A2*B3 - A3*B1) / (A1*B1 - A2*B2); double Y0 = (A3*B2 - A1*B3) / (A1*B1 - A2*B2); wcsp->crpix[0] = (Xc - X0)/Rx - (CNPIX1 - 0.5); wcsp->crpix[1] = (Yc + Y0)/Ry - (CNPIX2 - 0.5); wcsp->pc[0] = A1*Rx/S; wcsp->pc[1] = -A2*Ry/S; wcsp->pc[2] = -B2*Rx/S; wcsp->pc[3] = B1*Ry/S; wcsp->altlin = 1; wcsp->cdelt[0] = -S/3600.0; wcsp->cdelt[1] = S/3600.0; double *crval = wcsp->crval; crval[0] = (dsstmp[6] + (dsstmp[7] + dsstmp[8] /60.0)/60.0)*15.0; crval[1] = dsstmp[10] + (dsstmp[11] + dsstmp[12]/60.0)/60.0; if (dsstmp[9] == -1.0) crval[1] *= -1.0; strcpy(wcsp->ctype[0], "RA---TAN"); strcpy(wcsp->ctype[1], "DEC--TAN"); sprintf(wcsp->wcsname, "DSS PLATEID %.4s", (char *)(dsstmp+13)); // Erase the approximate WCS provided in modern DSS headers. wcsp->cd[0] = 0.0; wcsp->cd[1] = 0.0; wcsp->cd[2] = 0.0; wcsp->cd[3] = 0.0; } else if (distran == WAT) { // TNX and ZPX don't have alternates, nor axis mapping. char *wp; int omax, omin, wctrl[4]; double wval; struct disprm *disp = wcsp->lin.disseq; // Disassemble the core dump stored in the WATi_m strings. int i, nterms = 0; for (i = 0; i < 2; i++) { char wtype[8]; sscanf(wat[i], "wtype=%s", wtype); if (strcmp(wtype, "tnx") == 0) { strcpy(disp->dtype[i], "WAT-TNX"); } else if (strcmp(wtype, "zpx") == 0) { strcpy(disp->dtype[i], "WAT-ZPX"); } else { // Could contain "tan" or something else to be ignored. lindist(2, &(wcsp->lin), 0x0, 0); return 0; } // The PROJPn parameters are duplicated on each ZPX axis. if (i == 1 && strcmp(wtype, "zpx") == 0) { // Take those on the second (latitude) axis ignoring the other. // First we have to count them and allocate space in wcsprm. wp = wat[i]; int npv; for (npv = 0; npv < 30; npv++) { if ((wp = strstr(wp, "projp")) == 0x0) break; wp += 5; } // Allocate space. if (npv) { wcsp->npvmax += npv; wcsp->pv = realloc(wcsp->pv, wcsp->npvmax*sizeof(struct pvcard)); if (wcsp->pv == 0x0) { return WCSHDRERR_MEMORY; } wcsp->m_pv = wcsp->pv; } // Copy the values. wp = wat[i]; for (int ipv = wcsp->npv; ipv < wcsp->npvmax; ipv++) { if ((wp = strstr(wp, "projp")) == 0x0) break; int m; sscanf(wp, "projp%d=%lf", &m, &wval); wcsp->pv[ipv].i = 2; wcsp->pv[ipv].m = m; wcsp->pv[ipv].value = wval; wp += 5; } wcsp->npv += npv; } // Read the control parameters. if ((wp = strchr(wat[i], '"')) == 0x0) { return WCSHDRERR_PARSER; } wp++; for (int m = 0; m < 4; m++) { sscanf(wp, "%d", wctrl+m); if ((wp = strchr(wp, ' ')) == 0x0) { return WCSHDRERR_PARSER; } wp++; } // How many coefficients are we expecting? omin = (wctrl[1] < wctrl[2]) ? wctrl[1] : wctrl[2]; omax = (wctrl[1] < wctrl[2]) ? wctrl[2] : wctrl[1]; if (wctrl[3] == 0) { // No cross terms. nterms += omin + omax; } else if (wctrl[3] == 1) { // Full cross terms. nterms += omin*omax; } else if (wctrl[3] == 2) { // Half cross terms. nterms += omin*omax - omin*(omin-1)/2; } } // Allocate memory for dpkeys. ndq[0] += 2*(1 + 1 + 4) + nterms; disp->ndpmax += ndq[0]; disp->dp = realloc(disp->dp, disp->ndpmax*sizeof(struct dpkey)); if (disp->dp == 0x0) { return WCSHDRERR_MEMORY; } disp->m_dp = disp->dp; // Populate dpkeys. int idp = disp->ndp; for (i = 0; i < 2; i++) { dpfill(disp->dp+(idp++), "DQ", "NAXES", i+1, 0, 2, 0.0); // Read the control parameters. if ((wp = strchr(wat[i], '"')) == 0x0) { return WCSHDRERR_PARSER; } wp++; for (int m = 0; m < 4; m++) { sscanf(wp, "%d", wctrl+m); if ((wp = strchr(wp, ' ')) == 0x0) { return WCSHDRERR_PARSER; } wp++; } // Polynomial type. char wpoly[12]; dpfill(disp->dp+(idp++), "DQ", "WAT.POLY", i+1, 0, wctrl[0], 0.0); if (wctrl[0] == 1) { // Chebyshev polynomial. strcpy(wpoly, "CHBY"); } else if (wctrl[0] == 2) { // Legendre polynomial. strcpy(wpoly, "LEGR"); } else if (wctrl[0] == 3) { // Polynomial is the sum of monomials. strcpy(wpoly, "MONO"); } else { // Unknown code. strcpy(wpoly, "UNKN"); } // Read the scaling parameters. char field[40]; for (int m = 0; m < 4; m++) { sscanf(wp, "%lf", &wval); sprintf(field, "WAT.%c%s", (m<2)?'X':'Y', (m%2)?"MAX":"MIN"); dpfill(disp->dp+(idp++), "DQ", field, i+1, 1, 0, wval); if ((wp = strchr(wp, ' ')) == 0x0) { return WCSHDRERR_PARSER; } wp++; } // Read the coefficients. for (int n = 0; n < wctrl[2]; n++) { for (int m = 0; m < wctrl[1]; m++) { if (wctrl[3] == 0) { if (m && n) continue; } else if (wctrl[3] == 2) { if (m+n > omax-1) continue; } sscanf(wp, "%lf", &wval); if (wval == 0.0) continue; sprintf(field, "WAT.%s.%d_%d", wpoly, m, n); dpfill(disp->dp+(idp++), "DQ", field, i+1, 1, 0, wval); if ((wp = strchr(wp, ' ')) == 0x0) { return WCSHDRERR_PARSER; } wp++; } } } disp->ndp = idp; } return 0; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/flexed/wcsulex.c0000644000175100001710000141701100000000000020474 0ustar00vstsdocker#line 2 "wcsulex.c" #line 4 "wcsulex.c" #define _POSIX_C_SOURCE 1 #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 6 #define YY_FLEX_SUBMINOR_VERSION 4 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif #ifdef yy_create_buffer #define wcsulex_create_buffer_ALREADY_DEFINED #else #define yy_create_buffer wcsulex_create_buffer #endif #ifdef yy_delete_buffer #define wcsulex_delete_buffer_ALREADY_DEFINED #else #define yy_delete_buffer wcsulex_delete_buffer #endif #ifdef yy_scan_buffer #define wcsulex_scan_buffer_ALREADY_DEFINED #else #define yy_scan_buffer wcsulex_scan_buffer #endif #ifdef yy_scan_string #define wcsulex_scan_string_ALREADY_DEFINED #else #define yy_scan_string wcsulex_scan_string #endif #ifdef yy_scan_bytes #define wcsulex_scan_bytes_ALREADY_DEFINED #else #define yy_scan_bytes wcsulex_scan_bytes #endif #ifdef yy_init_buffer #define wcsulex_init_buffer_ALREADY_DEFINED #else #define yy_init_buffer wcsulex_init_buffer #endif #ifdef yy_flush_buffer #define wcsulex_flush_buffer_ALREADY_DEFINED #else #define yy_flush_buffer wcsulex_flush_buffer #endif #ifdef yy_load_buffer_state #define wcsulex_load_buffer_state_ALREADY_DEFINED #else #define yy_load_buffer_state wcsulex_load_buffer_state #endif #ifdef yy_switch_to_buffer #define wcsulex_switch_to_buffer_ALREADY_DEFINED #else #define yy_switch_to_buffer wcsulex_switch_to_buffer #endif #ifdef yypush_buffer_state #define wcsulexpush_buffer_state_ALREADY_DEFINED #else #define yypush_buffer_state wcsulexpush_buffer_state #endif #ifdef yypop_buffer_state #define wcsulexpop_buffer_state_ALREADY_DEFINED #else #define yypop_buffer_state wcsulexpop_buffer_state #endif #ifdef yyensure_buffer_stack #define wcsulexensure_buffer_stack_ALREADY_DEFINED #else #define yyensure_buffer_stack wcsulexensure_buffer_stack #endif #ifdef yylex #define wcsulexlex_ALREADY_DEFINED #else #define yylex wcsulexlex #endif #ifdef yyrestart #define wcsulexrestart_ALREADY_DEFINED #else #define yyrestart wcsulexrestart #endif #ifdef yylex_init #define wcsulexlex_init_ALREADY_DEFINED #else #define yylex_init wcsulexlex_init #endif #ifdef yylex_init_extra #define wcsulexlex_init_extra_ALREADY_DEFINED #else #define yylex_init_extra wcsulexlex_init_extra #endif #ifdef yylex_destroy #define wcsulexlex_destroy_ALREADY_DEFINED #else #define yylex_destroy wcsulexlex_destroy #endif #ifdef yyget_debug #define wcsulexget_debug_ALREADY_DEFINED #else #define yyget_debug wcsulexget_debug #endif #ifdef yyset_debug #define wcsulexset_debug_ALREADY_DEFINED #else #define yyset_debug wcsulexset_debug #endif #ifdef yyget_extra #define wcsulexget_extra_ALREADY_DEFINED #else #define yyget_extra wcsulexget_extra #endif #ifdef yyset_extra #define wcsulexset_extra_ALREADY_DEFINED #else #define yyset_extra wcsulexset_extra #endif #ifdef yyget_in #define wcsulexget_in_ALREADY_DEFINED #else #define yyget_in wcsulexget_in #endif #ifdef yyset_in #define wcsulexset_in_ALREADY_DEFINED #else #define yyset_in wcsulexset_in #endif #ifdef yyget_out #define wcsulexget_out_ALREADY_DEFINED #else #define yyget_out wcsulexget_out #endif #ifdef yyset_out #define wcsulexset_out_ALREADY_DEFINED #else #define yyset_out wcsulexset_out #endif #ifdef yyget_leng #define wcsulexget_leng_ALREADY_DEFINED #else #define yyget_leng wcsulexget_leng #endif #ifdef yyget_text #define wcsulexget_text_ALREADY_DEFINED #else #define yyget_text wcsulexget_text #endif #ifdef yyget_lineno #define wcsulexget_lineno_ALREADY_DEFINED #else #define yyget_lineno wcsulexget_lineno #endif #ifdef yyset_lineno #define wcsulexset_lineno_ALREADY_DEFINED #else #define yyset_lineno wcsulexset_lineno #endif #ifdef yyget_column #define wcsulexget_column_ALREADY_DEFINED #else #define yyget_column wcsulexget_column #endif #ifdef yyset_column #define wcsulexset_column_ALREADY_DEFINED #else #define yyset_column wcsulexset_column #endif #ifdef yywrap #define wcsulexwrap_ALREADY_DEFINED #else #define yywrap wcsulexwrap #endif #ifdef yyalloc #define wcsulexalloc_ALREADY_DEFINED #else #define yyalloc wcsulexalloc #endif #ifdef yyrealloc #define wcsulexrealloc_ALREADY_DEFINED #else #define yyrealloc wcsulexrealloc #endif #ifdef yyfree #define wcsulexfree_ALREADY_DEFINED #else #define yyfree wcsulexfree #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #ifndef SIZE_MAX #define SIZE_MAX (~(size_t)0) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ /* TODO: this is always defined, so inline it */ #define yyconst const #if defined(__GNUC__) && __GNUC__ >= 3 #define yynoreturn __attribute__((__noreturn__)) #else #define yynoreturn #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an * integer in range [0..255] for use as an array index. */ #define YY_SC_TO_UI(c) ((YY_CHAR) (c)) /* An opaque pointer. */ #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; #endif /* For convenience, these vars (plus the bison vars far below) are macros in the reentrant scanner. */ #define yyin yyg->yyin_r #define yyout yyg->yyout_r #define yyextra yyg->yyextra_r #define yyleng yyg->yyleng_r #define yytext yyg->yytext_r #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) #define yy_flex_debug yyg->yy_flex_debug_r /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN yyg->yy_start = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START ((yyg->yy_start - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin , yyscanner ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) #define YY_LINENO_REWIND_TO(ptr) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = yyg->yy_hold_char; \ YY_RESTORE_YY_MORE_OFFSET \ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] void yyrestart ( FILE *input_file , yyscan_t yyscanner ); void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner ); void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); void yypop_buffer_state ( yyscan_t yyscanner ); static void yyensure_buffer_stack ( yyscan_t yyscanner ); static void yy_load_buffer_state ( yyscan_t yyscanner ); static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner ); #define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner) YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner ); void *yyalloc ( yy_size_t , yyscan_t yyscanner ); void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner ); void yyfree ( void * , yyscan_t yyscanner ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define wcsulexwrap(yyscanner) (/*CONSTCOND*/1) #define YY_SKIP_YYWRAP typedef flex_uint8_t YY_CHAR; typedef int yy_state_type; #define yytext_ptr yytext_r static const flex_int16_t yy_nxt[][128] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 16, 14, 14, 14, 14, 14, 14, 14, 17, 14, 18, 14, 14, 14, 18, 19, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 20, 21, 22, 23, 24, 22, 25, 26, 14, 27, 28, 14, 24, 22, 29, 30, 14, 31, 32, 33, 14, 22, 34, 14, 24, 24, 14, 14, 35, 14, 14, 14, 36, 37, 38, 39, 40, 41, 28, 42, 14, 14, 24, 43, 44, 41, 29, 45, 14, 46, 47, 48, 49, 50, 14, 14, 51, 41, 14, 14, 14, 14, 14 }, { 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 52, 14, 14, 14, 14, 14, 14, 14, 17, 14, 53, 14, 14, 14, 53, 19, 14, 54, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 20, 21, 22, 23, 24, 22, 25, 26, 14, 27, 28, 14, 24, 22, 29, 30, 14, 31, 32, 33, 14, 22, 34, 14, 24, 24, 55, 14, 35, 14, 14, 14, 36, 37, 38, 39, 56, 41, 28, 42, 14, 14, 24, 57, 44, 41, 29, 45, 14, 46, 47, 48, 49, 50, 14, 14, 51, 41, 14, 14, 14, 14, 14 }, { 13, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 59, 60, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58 }, { 13, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 59, 60, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58 }, { 13, 61, 61, 61, 61, 61, 61, 61, 61, 61, 15, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 62, 61, 63, 61, 61, 61, 61, 61, 64, 61, 61, 65, 61, 61, 61, 66, 61, 61, 61, 61, 67, 68, 61, 61, 61, 61, 61, 61, 69, 61, 70, 71, 61, 72, 61, 73, 61, 61, 74, 61, 75, 76, 61, 77, 61, 61, 61, 61, 78, 61, 61, 61, 79, 80, 61, 61, 61, 61, 61 }, { 13, 61, 61, 61, 61, 61, 61, 61, 61, 61, 15, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 62, 61, 63, 61, 61, 61, 61, 61, 64, 61, 61, 65, 61, 61, 61, 66, 61, 61, 61, 61, 67, 68, 61, 61, 61, 61, 61, 61, 69, 61, 70, 71, 61, 72, 61, 73, 61, 61, 74, 61, 75, 76, 61, 77, 61, 61, 61, 61, 78, 61, 61, 61, 79, 80, 61, 61, 61, 61, 61 }, { 13, 81, 81, 81, 81, 81, 81, 81, 81, 81, 15, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 82, 83, 84, 85, 81, 86, 87, 88, 81, 89, 90, 81, 81, 91, 92, 93, 81, 94, 95, 96, 81, 97, 98, 81, 81, 81, 81, 81, 81, 81, 81, 81, 99, 100, 101, 102, 103, 81, 104, 105, 81, 81, 81, 106, 107, 81, 92, 108, 81, 109, 110, 111, 112, 113, 81, 81, 114, 81, 81, 81, 81, 81, 81 }, { 13, 81, 81, 81, 81, 81, 81, 81, 81, 81, 15, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 82, 83, 84, 85, 81, 86, 87, 88, 81, 89, 90, 81, 81, 91, 92, 93, 81, 94, 95, 96, 81, 97, 98, 81, 81, 81, 81, 81, 81, 81, 81, 81, 99, 100, 101, 102, 103, 81, 104, 105, 81, 81, 81, 106, 107, 81, 92, 108, 81, 109, 110, 111, 112, 113, 81, 81, 114, 81, 81, 81, 81, 81, 81 }, { 13, 115, 115, 115, 115, 115, 115, 115, 115, 115, 15, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 116, 115, 115, 115, 115, 115, 115, 115, 117, 115, 118, 119, 115, 119, 120, 121, 115, 122, 122, 122, 122, 122, 122, 122, 122, 122, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 123, 124, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115 }, { 13, 115, 115, 115, 115, 115, 115, 115, 115, 115, 15, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 116, 115, 115, 115, 115, 115, 115, 115, 117, 115, 118, 119, 115, 119, 120, 121, 115, 122, 122, 122, 122, 122, 122, 122, 122, 122, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 123, 124, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115 }, { 13, 125, 125, 125, 125, 125, 125, 125, 125, 125, 15, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125 }, { 13, 125, 125, 125, 125, 125, 125, 125, 125, 125, 15, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125 }, { -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13 }, { 13, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14 }, { 13, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15 }, { 13, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, 126, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16 }, { 13, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17 }, { 13, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18 }, { 13, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19 }, { 13, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, 127, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, 128, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20 }, { 13, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, 129, -21, -21, -21, -21, -21, -21 }, { 13, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22 }, { 13, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23 }, { 13, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, 130, 131, 132, -24, -24, 132, 133, 134, -24, 135, 130, -24, -24, 132, 136, 137, -24, 133, 132, 132, -24, 132, 138, -24, -24, -24, -24, -24, -24, -24, -24, -24, 139, 140, 141, -24, 142, -24, 130, -24, -24, -24, -24, 143, 144, -24, 136, 145, -24, 146, 147, -24, -24, -24, -24, -24, 148, -24, -24, -24, -24, -24, -24 }, { 13, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, 130, 131, 132, -25, -25, 132, 133, 134, -25, 135, 130, -25, -25, 132, 136, 137, -25, 133, 132, 132, -25, 132, 138, -25, -25, -25, -25, -25, -25, -25, -25, -25, 139, 140, 141, -25, 142, -25, 130, -25, -25, -25, -25, 143, 144, -25, 136, 145, -25, 146, 147, -25, -25, -25, -25, -25, 148, -25, -25, -25, -25, -25, -25 }, { 13, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, 149, -26, -26, -26, -26, -26 }, { 13, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, 150, -27, -27, -27, -27, -27, -27 }, { 13, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28 }, { 13, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, 151, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29 }, { 13, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, 130, 131, 132, -30, -30, 132, 133, 134, -30, 135, 130, -30, -30, 132, 136, 137, -30, 133, 132, 132, -30, 132, 138, -30, -30, -30, -30, -30, -30, -30, -30, -30, 152, 140, 141, -30, 142, -30, 130, -30, -30, -30, -30, 143, 144, -30, 136, 145, -30, 146, 147, -30, -30, -30, -30, -30, 148, -30, -30, -30, -30, -30, -30 }, { 13, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, 153, -31, -31, -31, -31, -31, -31 }, { 13, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, 154, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32 }, { 13, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, 130, 131, 132, -33, -33, 132, 133, 134, -33, 135, 130, -33, -33, 132, 136, 137, -33, 133, 132, 132, -33, 132, 138, -33, -33, -33, -33, -33, -33, -33, -33, -33, 139, 140, 141, -33, 142, -33, 130, -33, -33, -33, -33, 143, 144, -33, 136, 145, -33, 146, 147, -33, -33, -33, -33, -33, 148, -33, -33, -33, -33, -33, -33 }, { 13, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, 149, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34 }, { 13, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35 }, { 13, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, 130, -36, 132, -36, -36, 132, 133, 134, -36, 135, 130, -36, -36, 132, 136, 137, -36, 133, 132, 132, -36, 132, 138, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, 155, 141, 156, 142, -36, 130, -36, -36, -36, -36, 143, 157, 128, 136, -36, -36, 158, 147, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36 }, { 13, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, 159, -37, -37, -37, 160, -37, -37, -37, 161, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, 129, -37, -37, -37, -37, -37, -37 }, { 13, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, 130, -38, 132, -38, -38, 132, 133, 134, -38, 135, 130, -38, -38, 132, 136, 137, -38, 133, 132, 132, -38, 132, 138, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, 155, 141, 162, 142, -38, 130, 163, -38, -38, -38, 143, 157, -38, 164, -38, -38, 146, 147, 165, -38, -38, -38, -38, 153, -38, -38, -38, -38, -38, -38 }, { 13, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, 130, -39, 132, -39, -39, 132, 133, 134, -39, 135, 130, -39, -39, 132, 136, 137, -39, 133, 132, 132, -39, 132, 138, -39, -39, -39, -39, -39, -39, -39, -39, -39, 166, 155, 141, -39, 167, -39, 130, -39, -39, -39, -39, 143, 157, -39, 136, -39, -39, 146, 147, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39 }, { 13, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, 150, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, 168, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40 }, { 13, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, 130, -41, 132, -41, -41, 132, 133, 134, -41, 135, 130, -41, -41, 132, 136, 137, -41, 133, 132, 132, -41, 132, 138, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, 155, 141, -41, 142, -41, 130, -41, -41, -41, -41, 143, 157, -41, 136, -41, -41, 146, 147, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, -41 }, { 13, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, 130, 131, 132, -42, -42, 132, 133, 134, -42, 135, 130, -42, -42, 132, 136, 137, -42, 133, 132, 132, -42, 132, 138, -42, -42, -42, -42, -42, -42, -42, -42, -42, 139, 140, 141, -42, 142, -42, 130, -42, -42, -42, -42, 143, 144, -42, 136, 145, -42, 146, 147, -42, -42, -42, -42, -42, 148, -42, -42, -42, -42, -42, -42 }, { 13, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, 149, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, 149, 169, -43, -43, -43, -43, -43, -43 }, { 13, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, 130, -44, 132, -44, -44, 132, 133, 134, -44, 135, 130, -44, -44, 132, 136, 137, -44, 133, 132, 132, -44, 132, 138, -44, -44, -44, -44, -44, -44, -44, -44, -44, 170, 155, 141, -44, 142, -44, 130, -44, 171, -44, -44, 143, 157, -44, 172, -44, -44, 146, 147, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44 }, { 13, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, 130, -45, 132, -45, -45, 132, 133, 134, -45, 135, 130, -45, -45, 132, 136, 137, -45, 133, 132, 132, -45, 132, 138, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, 155, 173, -45, 142, -45, 130, 174, 175, -45, -45, 143, 157, -45, 136, -45, -45, 146, 147, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45 }, { 13, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, 176, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46 }, { 13, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, 177, -47, 178, 162, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47 }, { 13, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, 179, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48 }, { 13, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, 130, -49, 132, -49, -49, 132, 133, 134, -49, 135, 130, -49, -49, 132, 136, 137, -49, 133, 132, 132, -49, 132, 138, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, 155, 141, -49, 142, -49, 130, -49, -49, -49, -49, 143, 157, -49, 136, -49, -49, 146, 147, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49 }, { 13, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, 180, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50 }, { 13, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, 130, -51, 132, -51, -51, 132, 133, 134, -51, 135, 130, -51, -51, 132, 136, 137, -51, 133, 132, 132, -51, 132, 138, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, 155, 141, -51, 142, -51, 130, -51, -51, -51, -51, 143, 157, -51, 136, -51, -51, 181, 147, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51 }, { 13, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, 182, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52 }, { 13, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53 }, { 13, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, 183, 184, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54 }, { 13, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55 }, { 13, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, 150, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, 168, -56, -56, -56, -56, -56, 185, -56, -56, -56, -56, -56, -56, -56 }, { 13, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, 149, 186, 187, -57, -57, -57, -57, -57, -57, -57, -57, 149, 169, -57, -57, -57, -57, -57, -57 }, { 13, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, -58, -58, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188 }, { 13, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59 }, { 13, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60 }, { 13, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61 }, { 13, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62 }, { 13, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63 }, { 13, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64 }, { 13, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65 }, { 13, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66 }, { 13, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67 }, { 13, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68 }, { 13, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69 }, { 13, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70 }, { 13, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, 189, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71 }, { 13, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72 }, { 13, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73 }, { 13, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74 }, { 13, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75 }, { 13, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76 }, { 13, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77 }, { 13, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78 }, { 13, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79 }, { 13, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80 }, { 13, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81 }, { 13, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, 190, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, 191, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82 }, { 13, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, 192, -83, -83, -83, -83, -83, -83 }, { 13, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84 }, { 13, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85 }, { 13, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86 }, { 13, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87 }, { 13, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, 193, -88, -88, -88, -88, -88 }, { 13, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, 194, -89, -89, -89, -89, -89, -89 }, { 13, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90 }, { 13, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91 }, { 13, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, 195, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92 }, { 13, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, 196, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93 }, { 13, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, 197, -94, -94, -94, -94, -94, -94 }, { 13, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, 198, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95 }, { 13, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96 }, { 13, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97 }, { 13, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, 199, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98 }, { 13, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, 200, -99, -99, -99, -99, -99, -99, -99, -99, -99, 191, -99, -99, -99, 201, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99 }, { 13, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, 202, -100, -100, -100, 203, -100, -100, -100, 204, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, 192, -100, -100, -100, -100, -100, -100 }, { 13, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, 205, -101, -101, -101, 206, -101, -101, -101, -101, -101, -101, 207, -101, -101, -101, -101, 208, -101, -101, -101, -101, 209, -101, -101, -101, -101, -101, -101 }, { 13, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, 210, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102 }, { 13, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, 211, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, 212, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103 }, { 13, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104 }, { 13, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105 }, { 13, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, 213, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, 214, 215, -106, -106, -106, -106, -106, -106 }, { 13, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, 216, -107, -107, -107, -107, -107, -107, -107, 217, -107, -107, -107, -107, -107, 218, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107 }, { 13, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, 219, -108, -108, -108, -108, 220, 221, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108 }, { 13, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, 222, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109 }, { 13, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, 223, -110, -110, 224, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110 }, { 13, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, 225, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111 }, { 13, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112 }, { 13, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, 226, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113 }, { 13, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, 227, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114 }, { 13, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115 }, { 13, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, 228, -116, -116, -116, -116, -116, -116, -116, 229, -116, 230, 231, -116, 231, 232, 233, -116, 234, 234, 234, 234, 234, 234, 234, 234, 234, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, 235, 236, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116 }, { 13, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, 237, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, 238, -117, 238, 239, -117, 240, 241, 241, 241, 241, 241, 241, 241, 241, 241, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117 }, { 13, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, 242, -118, -118, -118, -118, -118, -118, -118, -118, -118, 236, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118 }, { 13, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, 234, 234, 234, 234, 234, 234, 234, 234, 234, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119 }, { 13, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, 242, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120 }, { 13, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, 243, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121 }, { 13, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122 }, { 13, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123 }, { 13, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124 }, { 13, 245, 245, 245, 245, 245, 245, 245, 245, 245, -125, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245 }, { 13, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, 126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126 }, { 13, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127 }, { 13, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, 246, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128 }, { 13, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, 247, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129 }, { 13, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130 }, { 13, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, 248, -131, -131, -131, -131, -131, -131 }, { 13, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132 }, { 13, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133 }, { 13, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, 132, -134, -134, -134, -134, -134 }, { 13, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, 133, -135, -135, -135, -135, -135, -135 }, { 13, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, 249, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136 }, { 13, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, 132, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137 }, { 13, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, 132, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138 }, { 13, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139 }, { 13, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, 250, -140, -140, -140, -140, -140, -140, -140, 251, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, 248, -140, -140, -140, -140, -140, -140 }, { 13, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, 130, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141 }, { 13, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, 133, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142 }, { 13, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, 132, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, 132, -143, -143, -143, -143, -143, -143, -143 }, { 13, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, 252, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144 }, { 13, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, 139, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145 }, { 13, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, 253, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146 }, { 13, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, 130, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147 }, { 13, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, 139, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148 }, { 13, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149 }, { 13, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150 }, { 13, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, 149, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151 }, { 13, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152 }, { 13, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153 }, { 13, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, 127, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154 }, { 13, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, 250, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155 }, { 13, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, 165, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156 }, { 13, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, 254, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, 252, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157 }, { 13, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, 253, -158, 255, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158 }, { 13, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, 256, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159 }, { 13, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, 257, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160 }, { 13, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, 165, -161, -161, -161, -161, -161, 258, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161 }, { 13, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162 }, { 13, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, 259, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163 }, { 13, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, 249, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, 260, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164 }, { 13, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165 }, { 13, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, 130, 131, 132, -166, -166, 132, 133, 134, -166, 135, 130, -166, -166, 132, 136, 137, -166, 133, 132, 132, -166, 132, 138, -166, -166, -166, -166, -166, -166, -166, -166, -166, 139, 140, 141, -166, 142, -166, 130, -166, -166, -166, -166, 143, 144, -166, 136, 145, -166, 146, 147, -166, -166, -166, -166, -166, 148, -166, -166, -166, -166, -166, -166 }, { 13, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, 133, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, 153, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167 }, { 13, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, 153, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168 }, { 13, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, 127, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169 }, { 13, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, 150, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, 153, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170 }, { 13, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, 153, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171 }, { 13, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, 249, -172, -172, -172, 162, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172 }, { 13, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, 130, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173 }, { 13, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, 261, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174 }, { 13, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, 262, -175, -175, -175, -175, -175, -175, -175 }, { 13, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, 162, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176 }, { 13, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, 263, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177 }, { 13, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, 264, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178 }, { 13, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, 265, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179 }, { 13, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, 266, -180, -180, -180, -180, -180, -180, -180 }, { 13, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, 253, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181 }, { 13, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, 182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182 }, { 13, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183 }, { 13, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184 }, { 13, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, 268, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185 }, { 13, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, 269, -186, -186, -186, -186, -186, -186, -186, 270, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186 }, { 13, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, 271, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187 }, { 13, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, -188, -188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188 }, { 13, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189 }, { 13, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190 }, { 13, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, 272, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191 }, { 13, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, 273, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192 }, { 13, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193 }, { 13, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194 }, { 13, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, 274, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195 }, { 13, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196 }, { 13, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197 }, { 13, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, 275, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198 }, { 13, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199 }, { 13, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, 276, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200 }, { 13, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, 277, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201 }, { 13, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, 278, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202 }, { 13, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, 279, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203 }, { 13, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, 280, -204, -204, -204, -204, -204, 281, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204 }, { 13, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205 }, { 13, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, 282, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206 }, { 13, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, 283, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207 }, { 13, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208 }, { 13, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209 }, { 13, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, 284, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210 }, { 13, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211 }, { 13, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, 285, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212 }, { 13, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213 }, { 13, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214 }, { 13, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, 286, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215 }, { 13, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, 287, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, 288, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216 }, { 13, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, 289, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217, -217 }, { 13, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, 290, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218, -218 }, { 13, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219, -219 }, { 13, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, 291, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220, -220 }, { 13, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, -221, 292, -221, -221, -221, -221, -221, -221, -221 }, { 13, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, 293, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, -222 }, { 13, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, 294, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223, -223 }, { 13, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224, -224 }, { 13, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, 295, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225 }, { 13, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, -226, 296, -226, -226, -226, -226, -226, -226, -226 }, { 13, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227, -227 }, { 13, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, 228, -228, -228, -228, -228, -228, -228, -228, 229, -228, 230, 231, -228, 231, 232, 233, -228, 234, 234, 234, 234, 234, 234, 234, 234, 234, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, 235, 236, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228, -228 }, { 13, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, 237, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, 238, -229, 238, 239, -229, 240, 241, 241, 241, 241, 241, 241, 241, 241, 241, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229, -229 }, { 13, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, 242, -230, -230, -230, -230, -230, -230, -230, -230, -230, 236, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230 }, { 13, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, 234, 234, 234, 234, 234, 234, 234, 234, 234, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, -231 }, { 13, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, 242, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, -232 }, { 13, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, 243, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233 }, { 13, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -234 }, { 13, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, -235 }, { 13, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -236 }, { 13, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, 237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, 238, -237, 238, 239, -237, 240, 241, 241, 241, 241, 241, 241, 241, 241, 241, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237, -237 }, { 13, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, 239, -238, 240, 241, 241, 241, 241, 241, 241, 241, 241, 241, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238, -238 }, { 13, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239 }, { 13, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, 298, -240, -240, -240, -240, -240, -240, -240, -240, 299, -240, -240, -240, -240, 300, -240, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240 }, { 13, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, 302, -241, -241, -241, -241, -241, -241, -241, -241, 303, -241, -241, -241, -241, 300, 304, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241 }, { 13, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, 242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242 }, { 13, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, 243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243 }, { 13, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, -244 }, { 13, 245, 245, 245, 245, 245, 245, 245, 245, 245, -245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245 }, { 13, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, 306, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, -246 }, { 13, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, 258, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247 }, { 13, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, 307, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248 }, { 13, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, 132, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249 }, { 13, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, 308, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250, -250 }, { 13, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, 139, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251, -251 }, { 13, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, 130, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, -252 }, { 13, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, 130, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253, -253 }, { 13, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, 309, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, -254 }, { 13, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, 310, -255, -255, -255, -255, -255, 311, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255 }, { 13, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, 150, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, -256 }, { 13, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, 127, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257, -257 }, { 13, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258, -258 }, { 13, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, 165, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, -259 }, { 13, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, 312, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, -260 }, { 13, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, 313, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, -261 }, { 13, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, 314, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, -262 }, { 13, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, 315, 316, -263, -263, -263, -263, 317, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263, -263 }, { 13, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, 318, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, -264 }, { 13, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, 153, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265, -265 }, { 13, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, 319, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, -266 }, { 13, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, -267 }, { 13, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, 320, -268, -268, -268, -268, -268, -268, -268, 321, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, -268 }, { 13, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, 269, -269, -269, -269, -269, -269, -269, -269, 270, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, -269 }, { 13, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270, -270 }, { 13, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, 322, -271, -271, -271, -271, -271, -271, -271, 323, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, -271 }, { 13, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, 324, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272, -272 }, { 13, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, 325, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273, -273 }, { 13, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, -274 }, { 13, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275, -275 }, { 13, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276, -276 }, { 13, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, 326, -277, -277, -277, -277, -277, 327, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, -277 }, { 13, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, 328, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, -278 }, { 13, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, 329, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, -279 }, { 13, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, -280 }, { 13, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, -281 }, { 13, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, 330, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282, -282 }, { 13, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, 331, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283, -283 }, { 13, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284, -284 }, { 13, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285 }, { 13, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, -286 }, { 13, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287, -287 }, { 13, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, -288 }, { 13, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, -289 }, { 13, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, -290 }, { 13, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, 332, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291, -291 }, { 13, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, 333, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292, -292 }, { 13, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293, -293 }, { 13, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, 334, 335, -294, -294, -294, -294, 336, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, -294 }, { 13, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, 337, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295, -295 }, { 13, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, 338, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, -296 }, { 13, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, 298, -297, -297, -297, -297, -297, -297, -297, -297, 299, -297, -297, -297, -297, -297, -297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297 }, { 13, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, 298, -298, -298, -298, -298, -298, -298, -298, -298, 299, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, -298 }, { 13, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, -299 }, { 13, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, 298, -300, -300, -300, -300, -300, -300, -300, -300, 299, -300, -300, -300, -300, -300, -300, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300, -300 }, { 13, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, 298, -301, -301, -301, -301, -301, -301, -301, -301, 299, -301, -301, -301, -301, 300, -301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, -301 }, { 13, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, 302, -302, -302, -302, -302, -302, -302, -302, -302, 303, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, -302 }, { 13, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, -303 }, { 13, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, 340, 340, 340, 340, 340, 340, 340, 340, 340, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, -304 }, { 13, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, 302, -305, -305, -305, -305, -305, -305, -305, -305, 303, -305, -305, -305, -305, 300, 304, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305, -305 }, { 13, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, 341, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306, -306 }, { 13, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, 139, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307, -307 }, { 13, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, 133, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, -308 }, { 13, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, -309 }, { 13, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, 342, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, -310 }, { 13, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, 343, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311, -311 }, { 13, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, 165, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312, -312 }, { 13, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, 344, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313, -313 }, { 13, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, 165, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, -314 }, { 13, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, 345, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315 }, { 13, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, 346, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316, -316 }, { 13, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, 347, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317, -317 }, { 13, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, 348, -318, -318, -318, -318, -318, -318, -318, 349, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318, -318 }, { 13, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, 165, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319, -319 }, { 13, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, 320, -320, -320, -320, -320, -320, -320, -320, 321, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320 }, { 13, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321 }, { 13, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, 322, -322, -322, -322, -322, -322, -322, -322, 323, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322 }, { 13, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323 }, { 13, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, 350, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324, -324 }, { 13, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325, -325 }, { 13, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, 351, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326, -326 }, { 13, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, 352, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327, -327 }, { 13, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328, -328 }, { 13, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, -329 }, { 13, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330, -330 }, { 13, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, 208, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331, -331 }, { 13, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, 353, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332, -332 }, { 13, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, 354, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333, -333 }, { 13, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, 355, -334, -334, -334, -334, -334, -334, -334, -334, -334, -334 }, { 13, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, 356, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335, -335 }, { 13, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, 357, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336, -336 }, { 13, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337, -337 }, { 13, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, 358, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338, -338 }, { 13, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, 298, -339, -339, -339, -339, -339, -339, -339, -339, 299, -339, -339, -339, -339, -339, -339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339, -339 }, { 13, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, 359, -340, -340, -340, -340, -340, -340, -340, -340, 360, -340, -340, -340, -340, -340, -340, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340, -340 }, { 13, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, 362, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341, -341 }, { 13, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, 153, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342, -342 }, { 13, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, 153, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, -343 }, { 13, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, 165, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, -344 }, { 13, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, 127, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, -345 }, { 13, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, 363, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, -346 }, { 13, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, 127, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, -347 }, { 13, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, 348, -348, -348, -348, -348, -348, -348, -348, 349, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348 }, { 13, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349, -349 }, { 13, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, 364, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350, -350 }, { 13, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, 365, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351, -351 }, { 13, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, 366, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, -352 }, { 13, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, 367, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353, -353 }, { 13, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, -354 }, { 13, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, 368, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355, -355 }, { 13, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, 369, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356, -356 }, { 13, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, 370, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357, -357 }, { 13, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358, -358 }, { 13, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, 359, -359, -359, -359, -359, -359, -359, -359, -359, 360, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, -359 }, { 13, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360 }, { 13, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, 359, -361, -361, -361, -361, -361, -361, -361, -361, 360, -361, -361, -361, -361, -361, -361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, -361 }, { 13, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, 371, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362, -362 }, { 13, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, 127, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363, -363 }, { 13, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, 372, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364, -364 }, { 13, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365, -365 }, { 13, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366 }, { 13, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367 }, { 13, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368, -368 }, { 13, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, 373, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369, -369 }, { 13, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370 }, { 13, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, 127, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371 }, { 13, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, 374, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372 }, { 13, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373 }, { 13, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374, -374 }, } ; static yy_state_type yy_get_previous_state ( yyscan_t yyscanner ); static yy_state_type yy_try_NUL_trans ( yy_state_type current_state , yyscan_t yyscanner); static int yy_get_next_buffer ( yyscan_t yyscanner ); static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ yyg->yytext_ptr = yy_bp; \ yyg->yytext_ptr -= yyg->yy_more_len; \ yyleng = (int) (yy_cp - yyg->yytext_ptr); \ yyg->yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; #define YY_NUM_RULES 120 #define YY_END_OF_BUFFER 121 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static const flex_int16_t yy_accept[375] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 119, 119, 121, 20, 120, 9, 11, 12, 14, 15, 20, 15, 15, 20, 15, 15, 15, 15, 20, 20, 15, 15, 15, 15, 19, 15, 20, 20, 15, 20, 20, 15, 20, 15, 20, 20, 15, 20, 15, 20, 20, 1, 8, 20, 2, 20, 20, 23, 21, 22, 44, 41, 38, 37, 40, 39, 43, 42, 31, 25, 24, 30, 35, 36, 26, 28, 29, 27, 33, 32, 107, 45, 107, 57, 62, 67, 68, 70, 73, 75, 84, 107, 107, 90, 93, 100, 103, 105, 46, 107, 107, 63, 107, 69, 71, 107, 79, 107, 107, 94, 107, 102, 107, 107, 118, 115, 114, 113, 118, 113, 116, 109, 117, 108, 119, 9, 15, 0, 0, 16, 0, 16, 16, 16, 16, 0, 0, 16, 17, 0, 0, 0, 0, 16, 0, 0, 16, 0, 15, 15, 0, 15, 15, 0, 0, 0, 16, 0, 0, 0, 0, 15, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 15, 1, 13, 4, 0, 0, 0, 23, 34, 51, 0, 0, 72, 74, 0, 86, 92, 0, 106, 0, 0, 0, 0, 0, 58, 0, 0, 60, 61, 0, 66, 0, 76, 77, 0, 0, 0, 0, 87, 88, 0, 0, 0, 98, 0, 0, 46, 115, 114, 113, 0, 113, 116, 109, 117, 108, 0, 0, 0, 0, 0, 113, 116, 109, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 0, 3, 0, 0, 6, 0, 0, 0, 85, 99, 47, 0, 0, 0, 54, 55, 0, 0, 64, 65, 78, 80, 81, 82, 83, 0, 89, 91, 0, 0, 0, 0, 0, 112, 0, 0, 0, 110, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 5, 0, 56, 0, 0, 52, 53, 59, 0, 0, 0, 0, 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 89, 0, 0, 0, 104, 0, 111, 0, 0, 0, 0, 49, 50, 88, 95, 0, 97, 0, 0, 96, 48 } ; static const yy_state_type yy_NUL_trans[375] = { 0, 14, 14, 58, 58, 61, 61, 81, 81, 115, 115, 125, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() (yyg->yy_more_flag = 1) #define YY_MORE_ADJ yyg->yy_more_len #define YY_RESTORE_YY_MORE_OFFSET #line 1 "wcsulex.l" /*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcsulex.c,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * wcsulex.l is a Flex description file containing the definition of a * recursive, multi-buffered lexical scanner and parser for FITS units * specifications. * * It requires Flex v2.5.4 or later. * * Refer to wcsunits.h for a description of the user interface and operating * notes. * *===========================================================================*/ /* Options. */ #define YY_NO_INPUT 1 /* Exponents. */ /* Metric prefixes. */ /* Basic and derived SI units. */ /* Additional recognized units: all metric prefixes allowed. */ /* Additional recognized units: only super-metric prefixes allowed. */ /* Additional recognized units: only sub-metric prefixes allowed. */ /* Additional recognized units for which NO metric prefixes are allowed. */ /* All additional recognized units. */ /* Exclusive start states. */ #line 85 "wcsulex.l" #include #include #include #include #include "wcserr.h" #include "wcsmath.h" #include "wcsunits.h" #include "wcsutil.h" // User data associated with yyscanner. struct wcsulex_extra { // Used in preempting the call to exit() by yy_fatal_error(). jmp_buf abort_jmp_env; }; #define YY_DECL int wcsulexe_scanner(const char unitstr[], int *func, \ double *scale, double units[WCSUNITS_NTYPE], struct wcserr **err, \ yyscan_t yyscanner) // Dummy definition to circumvent compiler warnings. #define YY_INPUT(inbuff, count, bufsize) { count = YY_NULL; } // Preempt the call to exit() by yy_fatal_error(). #define exit(status) longjmp(yyextra->abort_jmp_env, status); // Internal helper functions. static YY_DECL; #line 7229 "wcsulex.c" #line 7230 "wcsulex.c" #define INITIAL 0 #define PAREN 1 #define PREFIX 2 #define UNITS 3 #define EXPON 4 #define FLUSH 5 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #define YY_EXTRA_TYPE struct wcsulex_extra * /* Holds the entire state of the reentrant scanner. */ struct yyguts_t { /* User-defined. Not touched by flex. */ YY_EXTRA_TYPE yyextra_r; /* The rest are the same as the globals declared in the non-reentrant scanner. */ FILE *yyin_r, *yyout_r; size_t yy_buffer_stack_top; /**< index of top of stack. */ size_t yy_buffer_stack_max; /**< capacity of stack. */ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ char yy_hold_char; int yy_n_chars; int yyleng_r; char *yy_c_buf_p; int yy_init; int yy_start; int yy_did_buffer_switch_on_eof; int yy_start_stack_ptr; int yy_start_stack_depth; int *yy_start_stack; yy_state_type yy_last_accepting_state; char* yy_last_accepting_cpos; int yylineno_r; int yy_flex_debug_r; char *yytext_r; int yy_more_flag; int yy_more_len; }; /* end struct yyguts_t */ static int yy_init_globals ( yyscan_t yyscanner ); int yylex_init (yyscan_t* scanner); int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy ( yyscan_t yyscanner ); int yyget_debug ( yyscan_t yyscanner ); void yyset_debug ( int debug_flag , yyscan_t yyscanner ); YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner ); void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner ); FILE *yyget_in ( yyscan_t yyscanner ); void yyset_in ( FILE * _in_str , yyscan_t yyscanner ); FILE *yyget_out ( yyscan_t yyscanner ); void yyset_out ( FILE * _out_str , yyscan_t yyscanner ); int yyget_leng ( yyscan_t yyscanner ); char *yyget_text ( yyscan_t yyscanner ); int yyget_lineno ( yyscan_t yyscanner ); void yyset_lineno ( int _line_number , yyscan_t yyscanner ); int yyget_column ( yyscan_t yyscanner ); void yyset_column ( int _column_no , yyscan_t yyscanner ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap ( yyscan_t yyscanner ); #else extern int yywrap ( yyscan_t yyscanner ); #endif #endif #ifndef YY_NO_UNPUT static void yyunput ( int c, char *buf_ptr , yyscan_t yyscanner); #endif #ifndef yytext_ptr static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen ( const char * , yyscan_t yyscanner); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput ( yyscan_t yyscanner ); #else static int input ( yyscan_t yyscanner ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ errno=0; \ while ( (result = (int) read( fileno(yyin), buf, (yy_size_t) max_size )) < 0 ) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex (yyscan_t yyscanner); #define YY_DECL int yylex (yyscan_t yyscanner) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK /*LINTED*/break; #endif #define YY_RULE_SETUP \ if ( yyleng > 0 ) \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ (yytext[yyleng - 1] == '\n'); \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { yy_state_type yy_current_state; char *yy_cp, *yy_bp; int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( !yyg->yy_init ) { yyg->yy_init = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! yyg->yy_start ) yyg->yy_start = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } yy_load_buffer_state( yyscanner ); } { #line 116 "wcsulex.l" #line 118 "wcsulex.l" static const char *function = "wcsulexe_scanner"; void add(double *factor, double types[], double *expon, double *scale, double units[]); // Initialise returned values. *func = 0; *scale = 1.0; for (int i = 0; i < WCSUNITS_NTYPE; i++) { units[i] = 0.0; } if (err) *err = 0x0; double types[WCSUNITS_NTYPE]; for (int i = 0; i < WCSUNITS_NTYPE; i++) { types[i] = 0.0; } double expon = 1.0; double factor = 1.0; int bracket = 0; int operator = 0; int paren = 0; int status = 0; // Avert a flex-induced memory leak. if (YY_CURRENT_BUFFER && YY_CURRENT_BUFFER->yy_input_file == stdin) { yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner); } yy_scan_string(unitstr, yyscanner); // Return here via longjmp() invoked by yy_fatal_error(). if (setjmp(yyextra->abort_jmp_env)) { return wcserr_set(WCSERR_SET(UNITSERR_PARSER_ERROR), "Internal units parser error parsing '%s'", unitstr); } BEGIN(INITIAL); #ifdef DEBUG fprintf(stderr, "\n%s ->\n", unitstr); #endif #line 7529 "wcsulex.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { yyg->yy_more_len = 0; if ( yyg->yy_more_flag ) { yyg->yy_more_len = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr); yyg->yy_more_flag = 0; } yy_cp = yyg->yy_c_buf_p; /* Support of yytext. */ *yy_cp = yyg->yy_hold_char; /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = yyg->yy_start; yy_current_state += YY_AT_BOL(); yy_match: while ( (yy_current_state = yy_nxt[yy_current_state][ YY_SC_TO_UI(*yy_cp) ]) > 0 ) { if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } ++yy_cp; } yy_current_state = -yy_current_state; yy_find_action: yy_act = yy_accept[yy_current_state]; YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = yyg->yy_hold_char; yy_cp = yyg->yy_last_accepting_cpos + 1; yy_current_state = yyg->yy_last_accepting_state; goto yy_find_action; case 1: YY_RULE_SETUP #line 164 "wcsulex.l" { // Pretend initial whitespace doesn't exist. yy_set_bol(1); } YY_BREAK case 2: YY_RULE_SETUP #line 169 "wcsulex.l" { if (bracket++) { BEGIN(FLUSH); } else { yy_set_bol(1); } } YY_BREAK case 3: YY_RULE_SETUP #line 177 "wcsulex.l" { status = wcserr_set(WCSERR_SET(UNITSERR_BAD_NUM_MULTIPLIER), "Invalid exponent in '%s'", unitstr); BEGIN(FLUSH); } YY_BREAK case 4: YY_RULE_SETUP #line 183 "wcsulex.l" { factor = 10.0; BEGIN(EXPON); } YY_BREAK case 5: YY_RULE_SETUP #line 188 "wcsulex.l" { *func = 1; unput('('); BEGIN(PAREN); } YY_BREAK case 6: YY_RULE_SETUP #line 194 "wcsulex.l" { *func = 2; unput('('); BEGIN(PAREN); } YY_BREAK case 7: YY_RULE_SETUP #line 200 "wcsulex.l" { *func = 3; unput('('); BEGIN(PAREN); } YY_BREAK case 8: YY_RULE_SETUP #line 206 "wcsulex.l" { // Leading binary multiply. status = wcserr_set(WCSERR_SET(UNITSERR_DANGLING_BINOP), "Dangling binary operator in '%s'", unitstr); BEGIN(FLUSH); } YY_BREAK case 9: YY_RULE_SETUP #line 213 "wcsulex.l" // Discard whitespace in INITIAL context. YY_BREAK case 10: YY_RULE_SETUP #line 215 "wcsulex.l" { expon /= 2.0; unput('('); BEGIN(PAREN); } YY_BREAK case 11: YY_RULE_SETUP #line 221 "wcsulex.l" { // Gather terms in parentheses. yyless(0); BEGIN(PAREN); } YY_BREAK case 12: YY_RULE_SETUP #line 227 "wcsulex.l" { if (operator++) { BEGIN(FLUSH); } } YY_BREAK case 13: #line 234 "wcsulex.l" case 14: YY_RULE_SETUP #line 234 "wcsulex.l" { if (operator++) { BEGIN(FLUSH); } else { expon *= -1.0; } } YY_BREAK case 15: YY_RULE_SETUP #line 242 "wcsulex.l" { operator = 0; yyless(0); BEGIN(UNITS); } YY_BREAK case 16: #line 249 "wcsulex.l" case 17: #line 250 "wcsulex.l" case 18: YY_RULE_SETUP #line 250 "wcsulex.l" { operator = 0; yyless(0); BEGIN(PREFIX); } YY_BREAK case 19: YY_RULE_SETUP #line 256 "wcsulex.l" { bracket = !bracket; BEGIN(FLUSH); } YY_BREAK case 20: YY_RULE_SETUP #line 261 "wcsulex.l" { status = wcserr_set(WCSERR_SET(UNITSERR_BAD_INITIAL_SYMBOL), "Invalid symbol in INITIAL context in '%s'", unitstr); BEGIN(FLUSH); } YY_BREAK case 21: YY_RULE_SETUP #line 267 "wcsulex.l" { paren++; operator = 0; yymore(); } YY_BREAK case 22: YY_RULE_SETUP #line 273 "wcsulex.l" { paren--; if (paren) { // Not balanced yet. yymore(); } else { // Balanced; strip off the outer parentheses and recurse. yytext[yyleng-1] = '\0'; int func_r; double factor_r; status = wcsulexe(yytext+1, &func_r, &factor_r, types, err); YY_BUFFER_STATE buf = YY_CURRENT_BUFFER; yy_switch_to_buffer(buf, yyscanner); if (func_r) { status = wcserr_set(WCSERR_SET(UNITSERR_FUNCTION_CONTEXT), "Function in invalid context in '%s'", unitstr); } if (status) { BEGIN(FLUSH); } else { factor *= factor_r; BEGIN(EXPON); } } } YY_BREAK case 23: /* rule 23 can match eol */ YY_RULE_SETUP #line 304 "wcsulex.l" { yymore(); } YY_BREAK case 24: YY_RULE_SETUP #line 308 "wcsulex.l" { factor = 1e-1; BEGIN(UNITS); } YY_BREAK case 25: YY_RULE_SETUP #line 313 "wcsulex.l" { factor = 1e-2; BEGIN(UNITS); } YY_BREAK case 26: YY_RULE_SETUP #line 318 "wcsulex.l" { factor = 1e-3; BEGIN(UNITS); } YY_BREAK case 27: YY_RULE_SETUP #line 323 "wcsulex.l" { factor = 1e-6; BEGIN(UNITS); } YY_BREAK case 28: YY_RULE_SETUP #line 328 "wcsulex.l" { factor = 1e-9; BEGIN(UNITS); } YY_BREAK case 29: YY_RULE_SETUP #line 333 "wcsulex.l" { factor = 1e-12; BEGIN(UNITS); } YY_BREAK case 30: YY_RULE_SETUP #line 338 "wcsulex.l" { factor = 1e-15; BEGIN(UNITS); } YY_BREAK case 31: YY_RULE_SETUP #line 343 "wcsulex.l" { factor = 1e-18; BEGIN(UNITS); } YY_BREAK case 32: YY_RULE_SETUP #line 348 "wcsulex.l" { factor = 1e-21; BEGIN(UNITS); } YY_BREAK case 33: YY_RULE_SETUP #line 353 "wcsulex.l" { factor = 1e-24; BEGIN(UNITS); } YY_BREAK case 34: YY_RULE_SETUP #line 358 "wcsulex.l" { factor = 1e+1; BEGIN(UNITS); } YY_BREAK case 35: YY_RULE_SETUP #line 363 "wcsulex.l" { factor = 1e+2; BEGIN(UNITS); } YY_BREAK case 36: YY_RULE_SETUP #line 368 "wcsulex.l" { factor = 1e+3; BEGIN(UNITS); } YY_BREAK case 37: YY_RULE_SETUP #line 373 "wcsulex.l" { factor = 1e+6; BEGIN(UNITS); } YY_BREAK case 38: YY_RULE_SETUP #line 378 "wcsulex.l" { factor = 1e+9; BEGIN(UNITS); } YY_BREAK case 39: YY_RULE_SETUP #line 383 "wcsulex.l" { factor = 1e+12; BEGIN(UNITS); } YY_BREAK case 40: YY_RULE_SETUP #line 388 "wcsulex.l" { factor = 1e+15; BEGIN(UNITS); } YY_BREAK case 41: YY_RULE_SETUP #line 393 "wcsulex.l" { factor = 1e+18; BEGIN(UNITS); } YY_BREAK case 42: YY_RULE_SETUP #line 398 "wcsulex.l" { factor = 1e+21; BEGIN(UNITS); } YY_BREAK case 43: YY_RULE_SETUP #line 403 "wcsulex.l" { factor = 1e+24; BEGIN(UNITS); } YY_BREAK case 44: YY_RULE_SETUP #line 408 "wcsulex.l" { // Internal parser error. status = wcserr_set(WCSERR_SET(UNITSERR_PARSER_ERROR), "Internal units parser error parsing '%s'", unitstr); BEGIN(FLUSH); } YY_BREAK case 45: YY_RULE_SETUP #line 415 "wcsulex.l" { // Ampere. types[WCSUNITS_CHARGE] += 1.0; types[WCSUNITS_TIME] -= 1.0; BEGIN(EXPON); } YY_BREAK case 46: YY_RULE_SETUP #line 422 "wcsulex.l" { // Julian year (annum). factor *= 31557600.0; types[WCSUNITS_TIME] += 1.0; BEGIN(EXPON); } YY_BREAK case 47: YY_RULE_SETUP #line 429 "wcsulex.l" { // Analogue-to-digital converter units. types[WCSUNITS_COUNT] += 1.0; BEGIN(EXPON); } YY_BREAK case 48: YY_RULE_SETUP #line 435 "wcsulex.l" { // Angstrom. factor *= 1e-10; types[WCSUNITS_LENGTH] += 1.0; BEGIN(EXPON); } YY_BREAK case 49: YY_RULE_SETUP #line 442 "wcsulex.l" { // Minute of arc. factor /= 60.0; types[WCSUNITS_PLANE_ANGLE] += 1.0; BEGIN(EXPON); } YY_BREAK case 50: YY_RULE_SETUP #line 449 "wcsulex.l" { // Second of arc. factor /= 3600.0; types[WCSUNITS_PLANE_ANGLE] += 1.0; BEGIN(EXPON); } YY_BREAK case 51: YY_RULE_SETUP #line 456 "wcsulex.l" { // Astronomical unit. factor *= 1.49598e+11; types[WCSUNITS_LENGTH] += 1.0; BEGIN(EXPON); } YY_BREAK case 52: YY_RULE_SETUP #line 463 "wcsulex.l" { // Barn. factor *= 1e-28; types[WCSUNITS_LENGTH] += 2.0; BEGIN(EXPON); } YY_BREAK case 53: YY_RULE_SETUP #line 470 "wcsulex.l" { // Beam, as in Jy/beam. types[WCSUNITS_BEAM] += 1.0; BEGIN(EXPON); } YY_BREAK case 54: YY_RULE_SETUP #line 476 "wcsulex.l" { // Bin (e.g. histogram). types[WCSUNITS_BIN] += 1.0; BEGIN(EXPON); } YY_BREAK case 55: YY_RULE_SETUP #line 482 "wcsulex.l" { // Bit. types[WCSUNITS_BIT] += 1.0; BEGIN(EXPON); } YY_BREAK case 56: YY_RULE_SETUP #line 488 "wcsulex.l" { // Byte. factor *= 8.0; types[WCSUNITS_BIT] += 1.0; BEGIN(EXPON); } YY_BREAK case 57: YY_RULE_SETUP #line 495 "wcsulex.l" { // Coulomb. types[WCSUNITS_CHARGE] += 1.0; BEGIN(EXPON); } YY_BREAK case 58: YY_RULE_SETUP #line 501 "wcsulex.l" { // Candela. types[WCSUNITS_LUMINTEN] += 1.0; BEGIN(EXPON); } YY_BREAK case 59: YY_RULE_SETUP #line 507 "wcsulex.l" { // Channel. types[WCSUNITS_BIN] += 1.0; BEGIN(EXPON); } YY_BREAK case 60: YY_RULE_SETUP #line 513 "wcsulex.l" { // Count. types[WCSUNITS_COUNT] += 1.0; BEGIN(EXPON); } YY_BREAK case 61: YY_RULE_SETUP #line 519 "wcsulex.l" { // Julian century. factor *= 3155760000.0; types[WCSUNITS_TIME] += 1.0; BEGIN(EXPON); } YY_BREAK case 62: YY_RULE_SETUP #line 526 "wcsulex.l" { // Debye. factor *= 1e-29 / 3.0; types[WCSUNITS_CHARGE] += 1.0; types[WCSUNITS_LENGTH] += 1.0; BEGIN(EXPON); } YY_BREAK case 63: YY_RULE_SETUP #line 534 "wcsulex.l" { // Day. factor *= 86400.0; types[WCSUNITS_TIME] += 1.0; BEGIN(EXPON); } YY_BREAK case 64: YY_RULE_SETUP #line 541 "wcsulex.l" { // Degree. types[WCSUNITS_PLANE_ANGLE] += 1.0; BEGIN(EXPON); } YY_BREAK case 65: YY_RULE_SETUP #line 547 "wcsulex.l" { // Erg. factor *= 1e-7; types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_LENGTH] += 2.0; types[WCSUNITS_TIME] -= 2.0; BEGIN(EXPON); } YY_BREAK case 66: YY_RULE_SETUP #line 556 "wcsulex.l" { // Electron volt. factor *= 1.6021765e-19; types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_LENGTH] += 2.0; types[WCSUNITS_TIME] -= 2.0; BEGIN(EXPON); } YY_BREAK case 67: YY_RULE_SETUP #line 565 "wcsulex.l" { // Farad. types[WCSUNITS_MASS] -= 1.0; types[WCSUNITS_LENGTH] -= 2.0; types[WCSUNITS_TIME] += 3.0; types[WCSUNITS_CHARGE] += 2.0; BEGIN(EXPON); } YY_BREAK case 68: YY_RULE_SETUP #line 574 "wcsulex.l" { // Gauss. factor *= 1e-4; types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_TIME] += 1.0; types[WCSUNITS_CHARGE] -= 1.0; BEGIN(EXPON); } YY_BREAK case 69: YY_RULE_SETUP #line 583 "wcsulex.l" { // Gram. factor *= 1e-3; types[WCSUNITS_MASS] += 1.0; BEGIN(EXPON); } YY_BREAK case 70: YY_RULE_SETUP #line 590 "wcsulex.l" { // Henry. types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_LENGTH] += 2.0; types[WCSUNITS_TIME] += 2.0; types[WCSUNITS_CHARGE] -= 2.0; BEGIN(EXPON); } YY_BREAK case 71: YY_RULE_SETUP #line 599 "wcsulex.l" { // Hour. factor *= 3600.0; types[WCSUNITS_TIME] += 1.0; BEGIN(EXPON); } YY_BREAK case 72: YY_RULE_SETUP #line 606 "wcsulex.l" { // Hertz. types[WCSUNITS_TIME] -= 1.0; BEGIN(EXPON); } YY_BREAK case 73: YY_RULE_SETUP #line 612 "wcsulex.l" { // Joule. types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_LENGTH] += 2.0; types[WCSUNITS_TIME] -= 2.0; BEGIN(EXPON); } YY_BREAK case 74: YY_RULE_SETUP #line 620 "wcsulex.l" { // Jansky. factor *= 1e-26; types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_TIME] -= 2.0; BEGIN(EXPON); } YY_BREAK case 75: YY_RULE_SETUP #line 628 "wcsulex.l" { // Kelvin. types[WCSUNITS_TEMPERATURE] += 1.0; BEGIN(EXPON); } YY_BREAK case 76: YY_RULE_SETUP #line 634 "wcsulex.l" { // Lumen. types[WCSUNITS_LUMINTEN] += 1.0; types[WCSUNITS_SOLID_ANGLE] += 1.0; BEGIN(EXPON); } YY_BREAK case 77: YY_RULE_SETUP #line 641 "wcsulex.l" { // Lux. types[WCSUNITS_LUMINTEN] += 1.0; types[WCSUNITS_SOLID_ANGLE] += 1.0; types[WCSUNITS_LENGTH] -= 2.0; BEGIN(EXPON); } YY_BREAK case 78: YY_RULE_SETUP #line 649 "wcsulex.l" { // Light year. factor *= 2.99792458e8 * 31557600.0; types[WCSUNITS_LENGTH] += 1.0; BEGIN(EXPON); } YY_BREAK case 79: YY_RULE_SETUP #line 656 "wcsulex.l" { // Metre. types[WCSUNITS_LENGTH] += 1.0; BEGIN(EXPON); } YY_BREAK case 80: YY_RULE_SETUP #line 662 "wcsulex.l" { // Stellar magnitude. types[WCSUNITS_MAGNITUDE] += 1.0; BEGIN(EXPON); } YY_BREAK case 81: YY_RULE_SETUP #line 668 "wcsulex.l" { // Milli-arcsec. factor /= 3600e+3; types[WCSUNITS_PLANE_ANGLE] += 1.0; BEGIN(EXPON); } YY_BREAK case 82: YY_RULE_SETUP #line 675 "wcsulex.l" { // Minute. factor *= 60.0; types[WCSUNITS_TIME] += 1.0; BEGIN(EXPON); } YY_BREAK case 83: YY_RULE_SETUP #line 682 "wcsulex.l" { // Mole. types[WCSUNITS_MOLE] += 1.0; BEGIN(EXPON); } YY_BREAK case 84: YY_RULE_SETUP #line 688 "wcsulex.l" { // Newton. types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_LENGTH] += 1.0; types[WCSUNITS_TIME] -= 2.0; BEGIN(EXPON); } YY_BREAK case 85: YY_RULE_SETUP #line 696 "wcsulex.l" { // Ohm. types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_LENGTH] += 2.0; types[WCSUNITS_TIME] -= 1.0; types[WCSUNITS_CHARGE] -= 2.0; BEGIN(EXPON); } YY_BREAK case 86: YY_RULE_SETUP #line 705 "wcsulex.l" { // Pascal. types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_LENGTH] -= 1.0; types[WCSUNITS_TIME] -= 2.0; BEGIN(EXPON); } YY_BREAK case 87: YY_RULE_SETUP #line 713 "wcsulex.l" { // Parsec. factor *= 3.0857e16; types[WCSUNITS_LENGTH] += 1.0; BEGIN(EXPON); } YY_BREAK case 88: YY_RULE_SETUP #line 720 "wcsulex.l" { // Photon. types[WCSUNITS_COUNT] += 1.0; BEGIN(EXPON); } YY_BREAK case 89: YY_RULE_SETUP #line 726 "wcsulex.l" { // Pixel. types[WCSUNITS_PIXEL] += 1.0; BEGIN(EXPON); } YY_BREAK case 90: YY_RULE_SETUP #line 732 "wcsulex.l" { // Rayleigh. factor *= 1e10 / (4.0 * PI); types[WCSUNITS_LENGTH] -= 2.0; types[WCSUNITS_TIME] -= 1.0; types[WCSUNITS_SOLID_ANGLE] -= 1.0; BEGIN(EXPON); } YY_BREAK case 91: YY_RULE_SETUP #line 741 "wcsulex.l" { // Radian. factor *= 180.0 / PI; types[WCSUNITS_PLANE_ANGLE] += 1.0; BEGIN(EXPON); } YY_BREAK case 92: YY_RULE_SETUP #line 748 "wcsulex.l" { // Rydberg. factor *= 13.605692 * 1.6021765e-19; types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_LENGTH] += 2.0; types[WCSUNITS_TIME] -= 2.0; BEGIN(EXPON); } YY_BREAK case 93: YY_RULE_SETUP #line 757 "wcsulex.l" { // Siemen. types[WCSUNITS_MASS] -= 1.0; types[WCSUNITS_LENGTH] -= 2.0; types[WCSUNITS_TIME] += 1.0; types[WCSUNITS_CHARGE] += 2.0; BEGIN(EXPON); } YY_BREAK case 94: YY_RULE_SETUP #line 766 "wcsulex.l" { // Second. types[WCSUNITS_TIME] += 1.0; BEGIN(EXPON); } YY_BREAK case 95: YY_RULE_SETUP #line 772 "wcsulex.l" { // Solar luminosity. factor *= 3.8268e26; types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_LENGTH] += 2.0; types[WCSUNITS_TIME] -= 3.0; BEGIN(EXPON); } YY_BREAK case 96: YY_RULE_SETUP #line 781 "wcsulex.l" { // Solar mass. factor *= 1.9891e30; types[WCSUNITS_MASS] += 1.0; BEGIN(EXPON); } YY_BREAK case 97: YY_RULE_SETUP #line 788 "wcsulex.l" { // Solar radius. factor *= 6.9599e8; types[WCSUNITS_LENGTH] += 1.0; BEGIN(EXPON); } YY_BREAK case 98: YY_RULE_SETUP #line 795 "wcsulex.l" { // Steradian. types[WCSUNITS_SOLID_ANGLE] += 1.0; BEGIN(EXPON); } YY_BREAK case 99: YY_RULE_SETUP #line 801 "wcsulex.l" { // Sun (with respect to). types[WCSUNITS_SOLRATIO] += 1.0; BEGIN(EXPON); } YY_BREAK case 100: YY_RULE_SETUP #line 807 "wcsulex.l" { // Tesla. types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_TIME] += 1.0; types[WCSUNITS_CHARGE] -= 1.0; BEGIN(EXPON); } YY_BREAK case 101: YY_RULE_SETUP #line 815 "wcsulex.l" { // Turn. factor *= 360.0; types[WCSUNITS_PLANE_ANGLE] += 1.0; BEGIN(EXPON); } YY_BREAK case 102: YY_RULE_SETUP #line 822 "wcsulex.l" { // Unified atomic mass unit. factor *= 1.6605387e-27; types[WCSUNITS_MASS] += 1.0; BEGIN(EXPON); } YY_BREAK case 103: YY_RULE_SETUP #line 829 "wcsulex.l" { // Volt. types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_LENGTH] += 1.0; types[WCSUNITS_TIME] -= 2.0; types[WCSUNITS_CHARGE] -= 1.0; BEGIN(EXPON); } YY_BREAK case 104: YY_RULE_SETUP #line 838 "wcsulex.l" { // Voxel. types[WCSUNITS_VOXEL] += 1.0; BEGIN(EXPON); } YY_BREAK case 105: YY_RULE_SETUP #line 844 "wcsulex.l" { // Watt. types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_LENGTH] += 2.0; types[WCSUNITS_TIME] -= 3.0; BEGIN(EXPON); } YY_BREAK case 106: YY_RULE_SETUP #line 852 "wcsulex.l" { // Weber. types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_LENGTH] += 2.0; types[WCSUNITS_TIME] += 1.0; types[WCSUNITS_CHARGE] -= 1.0; BEGIN(EXPON); } YY_BREAK case 107: YY_RULE_SETUP #line 861 "wcsulex.l" { // Internal parser error. status = wcserr_set(WCSERR_SET(UNITSERR_PARSER_ERROR), "Internal units parser error parsing '%s'", unitstr); BEGIN(FLUSH); } YY_BREAK case 108: YY_RULE_SETUP #line 868 "wcsulex.l" { // Exponentiation. if (operator++) { BEGIN(FLUSH); } } YY_BREAK case 109: YY_RULE_SETUP #line 875 "wcsulex.l" { int i; sscanf(yytext, " %d", &i); expon *= (double)i; add(&factor, types, &expon, scale, units); operator = 0; BEGIN(INITIAL); } YY_BREAK case 110: YY_RULE_SETUP #line 884 "wcsulex.l" { int i; sscanf(yytext, " (%d)", &i); expon *= (double)i; add(&factor, types, &expon, scale, units); operator = 0; BEGIN(INITIAL); } YY_BREAK case 111: YY_RULE_SETUP #line 893 "wcsulex.l" { int i, j; sscanf(yytext, " (%d/%d)", &i, &j); expon *= (double)i / (double)j; add(&factor, types, &expon, scale, units); operator = 0; BEGIN(INITIAL); } YY_BREAK case 112: YY_RULE_SETUP #line 902 "wcsulex.l" { char ctmp[72]; sscanf(yytext, " (%s)", ctmp); double dexp; wcsutil_str2double(ctmp, &dexp); expon *= dexp; add(&factor, types, &expon, scale, units); operator = 0; BEGIN(INITIAL); } YY_BREAK case 113: YY_RULE_SETUP #line 913 "wcsulex.l" { // Multiply. if (operator++) { BEGIN(FLUSH); } else { add(&factor, types, &expon, scale, units); BEGIN(INITIAL); } } YY_BREAK case 114: YY_RULE_SETUP #line 923 "wcsulex.l" { // Multiply. if (operator) { BEGIN(FLUSH); } else { add(&factor, types, &expon, scale, units); unput('('); BEGIN(INITIAL); } } YY_BREAK case 115: YY_RULE_SETUP #line 934 "wcsulex.l" { // Multiply. if (operator) { BEGIN(FLUSH); } else { add(&factor, types, &expon, scale, units); BEGIN(INITIAL); } } YY_BREAK case 116: YY_RULE_SETUP #line 944 "wcsulex.l" { // Divide. if (operator++) { BEGIN(FLUSH); } else { add(&factor, types, &expon, scale, units); expon = -1.0; BEGIN(INITIAL); } } YY_BREAK case 117: YY_RULE_SETUP #line 955 "wcsulex.l" { add(&factor, types, &expon, scale, units); bracket = !bracket; BEGIN(FLUSH); } YY_BREAK case 118: YY_RULE_SETUP #line 961 "wcsulex.l" { status = wcserr_set(WCSERR_SET(UNITSERR_BAD_EXPON_SYMBOL), "Invalid symbol in EXPON context in '%s'", unitstr); BEGIN(FLUSH); } YY_BREAK case 119: YY_RULE_SETUP #line 967 "wcsulex.l" { // Discard any remaining input. } YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(PAREN): case YY_STATE_EOF(PREFIX): case YY_STATE_EOF(UNITS): case YY_STATE_EOF(EXPON): case YY_STATE_EOF(FLUSH): #line 971 "wcsulex.l" { // End-of-string. if (YY_START == EXPON) { add(&factor, types, &expon, scale, units); } if (bracket) { status = wcserr_set(WCSERR_SET(UNITSERR_UNBAL_BRACKET), "Unbalanced bracket in '%s'", unitstr); } else if (paren) { status = wcserr_set(WCSERR_SET(UNITSERR_UNBAL_PAREN), "Unbalanced parenthesis in '%s'", unitstr); } else if (operator == 1) { status = wcserr_set(WCSERR_SET(UNITSERR_DANGLING_BINOP), "Dangling binary operator in '%s'", unitstr); } else if (operator) { status = wcserr_set(WCSERR_SET(UNITSERR_CONSEC_BINOPS), "Consecutive binary operators in '%s'", unitstr); #ifdef DEBUG } else { fprintf(stderr, "EOS\n"); #endif } if (status) { for (int i = 0; i < WCSUNITS_NTYPE; i++) { units[i] = 0.0; *scale = 0.0; } } return status; } YY_BREAK case 120: YY_RULE_SETUP #line 1005 "wcsulex.l" ECHO; YY_BREAK #line 8786 "wcsulex.c" case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = yyg->yy_hold_char; YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) { /* This was really a NUL. */ yy_state_type yy_next_state; yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++yyg->yy_c_buf_p; yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = yyg->yy_c_buf_p; goto yy_find_action; } } else switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_END_OF_FILE: { yyg->yy_did_buffer_switch_on_eof = 0; if ( yywrap( yyscanner ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: yyg->yy_c_buf_p = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of user's declarations */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; char *source = yyg->yytext_ptr; int number_to_move, i; int ret_val; if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1); for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) (yyg->yy_c_buf_p - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yyrealloc( (void *) b->yy_ch_buf, (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = NULL; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), yyg->yy_n_chars, num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } if ( yyg->yy_n_chars == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin , yyscanner); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); /* "- 2" to take care of EOB's */ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); } yyg->yy_n_chars += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (yyscan_t yyscanner) { yy_state_type yy_current_state; char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_current_state = yyg->yy_start; yy_current_state += YY_AT_BOL(); for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) { if ( *yy_cp ) { yy_current_state = yy_nxt[yy_current_state][YY_SC_TO_UI(*yy_cp)]; } else yy_current_state = yy_NUL_trans[yy_current_state]; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) { int yy_is_jam; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ char *yy_cp = yyg->yy_c_buf_p; yy_current_state = yy_NUL_trans[yy_current_state]; yy_is_jam = (yy_current_state == 0); if ( ! yy_is_jam ) { if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } } (void)yyg; return yy_is_jam ? 0 : yy_current_state; } #ifndef YY_NO_UNPUT static void yyunput (int c, char * yy_bp , yyscan_t yyscanner) { char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_cp = yyg->yy_c_buf_p; /* undo effects of setting up yytext */ *yy_cp = yyg->yy_hold_char; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ int number_to_move = yyg->yy_n_chars + 2; char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; yyg->yytext_ptr = yy_bp; yyg->yy_hold_char = *yy_cp; yyg->yy_c_buf_p = yy_cp; } #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (yyscan_t yyscanner) #else static int input (yyscan_t yyscanner) #endif { int c; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; *yyg->yy_c_buf_p = yyg->yy_hold_char; if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) /* This was really a NUL. */ *yyg->yy_c_buf_p = '\0'; else { /* need more input */ int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr); ++yyg->yy_c_buf_p; switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin , yyscanner); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( yyscanner ) ) return 0; if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(yyscanner); #else return input(yyscanner); #endif } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + offset; break; } } } c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ yyg->yy_hold_char = *++yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * @param yyscanner The scanner object. * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } yy_init_buffer( YY_CURRENT_BUFFER, input_file , yyscanner); yy_load_buffer_state( yyscanner ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * @param yyscanner The scanner object. */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (yyscanner); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( yyscanner ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ yyg->yy_did_buffer_switch_on_eof = 1; } static void yy_load_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; yyg->yy_hold_char = *yyg->yy_c_buf_p; } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * @param yyscanner The scanner object. * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file , yyscanner); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * @param yyscanner The scanner object. */ void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree( (void *) b->yy_ch_buf , yyscanner ); yyfree( (void *) b , yyscanner ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) { int oerrno = errno; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_flush_buffer( b , yyscanner); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * @param yyscanner The scanner object. */ void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( yyscanner ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * @param yyscanner The scanner object. */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (new_buffer == NULL) return; yyensure_buffer_stack(yyscanner); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) yyg->yy_buffer_stack_top++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * @param yyscanner The scanner object. */ void yypop_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER , yyscanner); YY_CURRENT_BUFFER_LVALUE = NULL; if (yyg->yy_buffer_stack_top > 0) --yyg->yy_buffer_stack_top; if (YY_CURRENT_BUFFER) { yy_load_buffer_state( yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (yyscan_t yyscanner) { yy_size_t num_to_alloc; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!yyg->yy_buffer_stack) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; yyg->yy_buffer_stack_top = 0; return; } if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ /* Increase the buffer to prepare for a possible push. */ yy_size_t grow_size = 8 /* arbitrary grow size */; num_to_alloc = yyg->yy_buffer_stack_max + grow_size; yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc (yyg->yy_buffer_stack, num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return NULL; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = NULL; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer( b , yyscanner ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * @param yyscanner The scanner object. * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (const char * yystr , yyscan_t yyscanner) { return yy_scan_bytes( yystr, (int) strlen(yystr) , yyscanner); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len , yyscan_t yyscanner) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = (yy_size_t) (_yybytes_len + 2); buf = (char *) yyalloc( n , yyscanner ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer( buf, n , yyscanner); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yynoreturn yy_fatal_error (const char* msg , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = yyg->yy_hold_char; \ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ yyg->yy_hold_char = *yyg->yy_c_buf_p; \ *yyg->yy_c_buf_p = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the user-defined data for this scanner. * @param yyscanner The scanner object. */ YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyextra; } /** Get the current line number. * @param yyscanner The scanner object. */ int yyget_lineno (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yylineno; } /** Get the current column number. * @param yyscanner The scanner object. */ int yyget_column (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yycolumn; } /** Get the input stream. * @param yyscanner The scanner object. */ FILE *yyget_in (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyin; } /** Get the output stream. * @param yyscanner The scanner object. */ FILE *yyget_out (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyout; } /** Get the length of the current token. * @param yyscanner The scanner object. */ int yyget_leng (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyleng; } /** Get the current token. * @param yyscanner The scanner object. */ char *yyget_text (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yytext; } /** Set the user-defined data. This data is never touched by the scanner. * @param user_defined The data to be associated with this scanner. * @param yyscanner The scanner object. */ void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyextra = user_defined ; } /** Set the current line number. * @param _line_number line number * @param yyscanner The scanner object. */ void yyset_lineno (int _line_number , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* lineno is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "yyset_lineno called with no buffer" ); yylineno = _line_number; } /** Set the current column. * @param _column_no column number * @param yyscanner The scanner object. */ void yyset_column (int _column_no , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* column is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "yyset_column called with no buffer" ); yycolumn = _column_no; } /** Set the input stream. This does not discard the current * input buffer. * @param _in_str A readable stream. * @param yyscanner The scanner object. * @see yy_switch_to_buffer */ void yyset_in (FILE * _in_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyin = _in_str ; } void yyset_out (FILE * _out_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyout = _out_str ; } int yyget_debug (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yy_flex_debug; } void yyset_debug (int _bdebug , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_flex_debug = _bdebug ; } /* Accessor methods for yylval and yylloc */ /* User-visible API */ /* yylex_init is special because it creates the scanner itself, so it is * the ONLY reentrant function that doesn't take the scanner as the last argument. * That's why we explicitly handle the declaration, instead of using our macros. */ int yylex_init(yyscan_t* ptr_yy_globals) { if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); return yy_init_globals ( *ptr_yy_globals ); } /* yylex_init_extra has the same functionality as yylex_init, but follows the * convention of taking the scanner as the last argument. Note however, that * this is a *pointer* to a scanner, as it will be allocated by this call (and * is the reason, too, why this function also must handle its own declaration). * The user defined value in the first argument will be available to yyalloc in * the yyextra field. */ int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals ) { struct yyguts_t dummy_yyguts; yyset_extra (yy_user_defined, &dummy_yyguts); if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); yyset_extra (yy_user_defined, *ptr_yy_globals); return yy_init_globals ( *ptr_yy_globals ); } static int yy_init_globals (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ yyg->yy_buffer_stack = NULL; yyg->yy_buffer_stack_top = 0; yyg->yy_buffer_stack_max = 0; yyg->yy_c_buf_p = NULL; yyg->yy_init = 0; yyg->yy_start = 0; yyg->yy_start_stack_ptr = 0; yyg->yy_start_stack_depth = 0; yyg->yy_start_stack = NULL; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = NULL; yyout = NULL; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer( YY_CURRENT_BUFFER , yyscanner ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(yyscanner); } /* Destroy the stack itself. */ yyfree(yyg->yy_buffer_stack , yyscanner); yyg->yy_buffer_stack = NULL; /* Destroy the start condition stack. */ yyfree( yyg->yy_start_stack , yyscanner ); yyg->yy_start_stack = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( yyscanner); /* Destroy the main struct (reentrant only). */ yyfree ( yyscanner , yyscanner ); yyscanner = NULL; return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (const char * s , yyscan_t yyscanner) { int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; return malloc(size); } void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return realloc(ptr, size); } void yyfree (void * ptr , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 1005 "wcsulex.l" /*---------------------------------------------------------------------------- * External interface to the scanner. *---------------------------------------------------------------------------*/ int wcsulexe( const char unitstr[], int *func, double *scale, double units[WCSUNITS_NTYPE], struct wcserr **err) { // Function prototypes. int yylex_init_extra(YY_EXTRA_TYPE extra, yyscan_t *yyscanner); int yylex_destroy(yyscan_t yyscanner); struct wcsulex_extra extra; yyscan_t yyscanner; yylex_init_extra(&extra, &yyscanner); int status = wcsulexe_scanner(unitstr, func, scale, units, err, yyscanner); yylex_destroy(yyscanner); return status; } /*---------------------------------------------------------------------------- * Accumulate a term in a units specification and reset work variables. *---------------------------------------------------------------------------*/ void add( double *factor, double types[], double *expon, double *scale, double units[]) { *scale *= pow(*factor, *expon); for (int i = 0; i < WCSUNITS_NTYPE; i++) { units[i] += *expon * types[i]; types[i] = 0.0; } *expon = 1.0; *factor = 1.0; return; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/flexed/wcsutrn.c0000644000175100001710000074552200000000000020521 0ustar00vstsdocker#line 2 "wcsutrn.c" #line 4 "wcsutrn.c" #define _POSIX_C_SOURCE 1 #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 6 #define YY_FLEX_SUBMINOR_VERSION 4 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif #ifdef yy_create_buffer #define wcsutrn_create_buffer_ALREADY_DEFINED #else #define yy_create_buffer wcsutrn_create_buffer #endif #ifdef yy_delete_buffer #define wcsutrn_delete_buffer_ALREADY_DEFINED #else #define yy_delete_buffer wcsutrn_delete_buffer #endif #ifdef yy_scan_buffer #define wcsutrn_scan_buffer_ALREADY_DEFINED #else #define yy_scan_buffer wcsutrn_scan_buffer #endif #ifdef yy_scan_string #define wcsutrn_scan_string_ALREADY_DEFINED #else #define yy_scan_string wcsutrn_scan_string #endif #ifdef yy_scan_bytes #define wcsutrn_scan_bytes_ALREADY_DEFINED #else #define yy_scan_bytes wcsutrn_scan_bytes #endif #ifdef yy_init_buffer #define wcsutrn_init_buffer_ALREADY_DEFINED #else #define yy_init_buffer wcsutrn_init_buffer #endif #ifdef yy_flush_buffer #define wcsutrn_flush_buffer_ALREADY_DEFINED #else #define yy_flush_buffer wcsutrn_flush_buffer #endif #ifdef yy_load_buffer_state #define wcsutrn_load_buffer_state_ALREADY_DEFINED #else #define yy_load_buffer_state wcsutrn_load_buffer_state #endif #ifdef yy_switch_to_buffer #define wcsutrn_switch_to_buffer_ALREADY_DEFINED #else #define yy_switch_to_buffer wcsutrn_switch_to_buffer #endif #ifdef yypush_buffer_state #define wcsutrnpush_buffer_state_ALREADY_DEFINED #else #define yypush_buffer_state wcsutrnpush_buffer_state #endif #ifdef yypop_buffer_state #define wcsutrnpop_buffer_state_ALREADY_DEFINED #else #define yypop_buffer_state wcsutrnpop_buffer_state #endif #ifdef yyensure_buffer_stack #define wcsutrnensure_buffer_stack_ALREADY_DEFINED #else #define yyensure_buffer_stack wcsutrnensure_buffer_stack #endif #ifdef yylex #define wcsutrnlex_ALREADY_DEFINED #else #define yylex wcsutrnlex #endif #ifdef yyrestart #define wcsutrnrestart_ALREADY_DEFINED #else #define yyrestart wcsutrnrestart #endif #ifdef yylex_init #define wcsutrnlex_init_ALREADY_DEFINED #else #define yylex_init wcsutrnlex_init #endif #ifdef yylex_init_extra #define wcsutrnlex_init_extra_ALREADY_DEFINED #else #define yylex_init_extra wcsutrnlex_init_extra #endif #ifdef yylex_destroy #define wcsutrnlex_destroy_ALREADY_DEFINED #else #define yylex_destroy wcsutrnlex_destroy #endif #ifdef yyget_debug #define wcsutrnget_debug_ALREADY_DEFINED #else #define yyget_debug wcsutrnget_debug #endif #ifdef yyset_debug #define wcsutrnset_debug_ALREADY_DEFINED #else #define yyset_debug wcsutrnset_debug #endif #ifdef yyget_extra #define wcsutrnget_extra_ALREADY_DEFINED #else #define yyget_extra wcsutrnget_extra #endif #ifdef yyset_extra #define wcsutrnset_extra_ALREADY_DEFINED #else #define yyset_extra wcsutrnset_extra #endif #ifdef yyget_in #define wcsutrnget_in_ALREADY_DEFINED #else #define yyget_in wcsutrnget_in #endif #ifdef yyset_in #define wcsutrnset_in_ALREADY_DEFINED #else #define yyset_in wcsutrnset_in #endif #ifdef yyget_out #define wcsutrnget_out_ALREADY_DEFINED #else #define yyget_out wcsutrnget_out #endif #ifdef yyset_out #define wcsutrnset_out_ALREADY_DEFINED #else #define yyset_out wcsutrnset_out #endif #ifdef yyget_leng #define wcsutrnget_leng_ALREADY_DEFINED #else #define yyget_leng wcsutrnget_leng #endif #ifdef yyget_text #define wcsutrnget_text_ALREADY_DEFINED #else #define yyget_text wcsutrnget_text #endif #ifdef yyget_lineno #define wcsutrnget_lineno_ALREADY_DEFINED #else #define yyget_lineno wcsutrnget_lineno #endif #ifdef yyset_lineno #define wcsutrnset_lineno_ALREADY_DEFINED #else #define yyset_lineno wcsutrnset_lineno #endif #ifdef yyget_column #define wcsutrnget_column_ALREADY_DEFINED #else #define yyget_column wcsutrnget_column #endif #ifdef yyset_column #define wcsutrnset_column_ALREADY_DEFINED #else #define yyset_column wcsutrnset_column #endif #ifdef yywrap #define wcsutrnwrap_ALREADY_DEFINED #else #define yywrap wcsutrnwrap #endif #ifdef yyalloc #define wcsutrnalloc_ALREADY_DEFINED #else #define yyalloc wcsutrnalloc #endif #ifdef yyrealloc #define wcsutrnrealloc_ALREADY_DEFINED #else #define yyrealloc wcsutrnrealloc #endif #ifdef yyfree #define wcsutrnfree_ALREADY_DEFINED #else #define yyfree wcsutrnfree #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #ifndef SIZE_MAX #define SIZE_MAX (~(size_t)0) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ /* TODO: this is always defined, so inline it */ #define yyconst const #if defined(__GNUC__) && __GNUC__ >= 3 #define yynoreturn __attribute__((__noreturn__)) #else #define yynoreturn #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an * integer in range [0..255] for use as an array index. */ #define YY_SC_TO_UI(c) ((YY_CHAR) (c)) /* An opaque pointer. */ #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; #endif /* For convenience, these vars (plus the bison vars far below) are macros in the reentrant scanner. */ #define yyin yyg->yyin_r #define yyout yyg->yyout_r #define yyextra yyg->yyextra_r #define yyleng yyg->yyleng_r #define yytext yyg->yytext_r #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) #define yy_flex_debug yyg->yy_flex_debug_r /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN yyg->yy_start = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START ((yyg->yy_start - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin , yyscanner ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) #define YY_LINENO_REWIND_TO(ptr) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = yyg->yy_hold_char; \ YY_RESTORE_YY_MORE_OFFSET \ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] void yyrestart ( FILE *input_file , yyscan_t yyscanner ); void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner ); void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); void yypop_buffer_state ( yyscan_t yyscanner ); static void yyensure_buffer_stack ( yyscan_t yyscanner ); static void yy_load_buffer_state ( yyscan_t yyscanner ); static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner ); #define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner) YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner ); void *yyalloc ( yy_size_t , yyscan_t yyscanner ); void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner ); void yyfree ( void * , yyscan_t yyscanner ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define wcsutrnwrap(yyscanner) (/*CONSTCOND*/1) #define YY_SKIP_YYWRAP typedef flex_uint8_t YY_CHAR; typedef int yy_state_type; #define yytext_ptr yytext_r static const flex_int16_t yy_nxt[][128] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 10, 11, 12, 13, 12, 12, 14, 15, 12, 16, 17, 12, 18, 12, 19, 20, 12, 21, 22, 12, 12, 23, 12, 12, 24, 12, 8, 8, 8, 8, 8, 8, 25, 12, 12, 26, 12, 12, 12, 27, 12, 12, 28, 12, 29, 12, 12, 30, 12, 31, 32, 12, 12, 33, 12, 12, 34, 12, 8, 8, 8, 8, 8 }, { 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 35, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 10, 11, 12, 13, 12, 12, 14, 15, 12, 16, 17, 12, 18, 12, 19, 20, 12, 21, 22, 12, 12, 23, 12, 12, 24, 12, 36, 8, 8, 8, 8, 8, 25, 12, 12, 26, 12, 12, 12, 27, 12, 12, 28, 12, 29, 12, 12, 30, 12, 31, 32, 12, 12, 33, 12, 12, 34, 12, 8, 8, 8, 8, 8 }, { 7, 37, 37, 37, 37, 37, 37, 37, 37, 37, 38, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 39, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 37, 37, 37, 37, 37, 37, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 37, 37, 37, 37, 37 }, { 7, 37, 37, 37, 37, 37, 37, 37, 37, 37, 38, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 39, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 37, 37, 37, 37, 37, 37, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 37, 37, 37, 37, 37 }, { 7, 41, 41, 41, 41, 41, 41, 41, 41, 41, 38, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41 }, { 7, 41, 41, 41, 41, 41, 41, 41, 41, 41, 38, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41 }, { -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7 }, { 7, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8 }, { 7, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 42, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9 }, { 7, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 44, 43, 43, 43, 43, 43, 43, 43, 43, -10, -10, -10, -10, -10, -10, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 45, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -10, -10, -10, -10, -10 }, { 7, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, 43, 43, 43, 43, 46, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -11, -11, -11, -11, -11, -11, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 47, 43, -11, -11, -11, -11, -11 }, { 7, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -12, -12, -12, -12, -12, -12, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -12, -12, -12, -12, -12 }, { 7, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, 48, 43, 43, 43, 49, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -13, -13, -13, -13, -13, -13, 43, 43, 43, 43, 50, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -13, -13, -13, -13, -13 }, { 7, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, 43, 43, 43, 43, 43, 43, 43, 51, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -14, -14, -14, -14, -14, -14, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -14, -14, -14, -14, -14 }, { 7, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 52, 43, 43, 43, 43, 43, 43, 43, 53, -15, -15, -15, -15, -15, -15, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -15, -15, -15, -15, -15 }, { 7, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 54, 43, -16, -16, -16, -16, -16, -16, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -16, -16, -16, -16, -16 }, { 7, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, 43, 43, 43, 43, 55, 43, 43, 56, 43, 43, 43, 43, 57, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -17, -17, -17, -17, -17, -17, 43, 43, 43, 43, 58, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -17, -17, -17, -17, -17 }, { 7, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, 43, 43, 43, 43, 59, 43, 43, 60, 61, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -18, -18, -18, -18, -18, -18, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -18, -18, -18, -18, -18 }, { 7, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -19, -19, -19, -19, -19, -19, 43, 43, 43, 43, 43, 43, 43, 62, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -19, -19, -19, -19, -19 }, { 7, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, 63, 43, 43, 43, 43, 43, 43, 43, 64, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -20, -20, -20, -20, -20, -20, 65, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -20, -20, -20, -20, -20 }, { 7, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, 66, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -21, -21, -21, -21, -21, -21, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -21, -21, -21, -21, -21 }, { 7, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, 43, 43, 43, 43, 67, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -22, -22, -22, -22, -22, -22, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -22, -22, -22, -22, -22 }, { 7, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 68, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -23, -23, -23, -23, -23, -23, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 69, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -23, -23, -23, -23, -23 }, { 7, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, 43, 43, 43, 43, 70, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 71, 43, 43, 43, 43, 43, 43, 43, 43, -24, -24, -24, -24, -24, -24, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -24, -24, -24, -24, -24 }, { 7, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -25, -25, -25, -25, -25, -25, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 72, 43, 43, 43, 73, 43, 43, 43, 43, 43, 43, 43, 43, -25, -25, -25, -25, -25 }, { 7, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -26, -26, -26, -26, -26, -26, 74, 43, 43, 43, 75, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -26, -26, -26, -26, -26 }, { 7, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -27, -27, -27, -27, -27, -27, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 52, 43, 43, 43, 43, 43, 43, 43, 53, -27, -27, -27, -27, -27 }, { 7, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -28, -28, -28, -28, -28, -28, 43, 43, 43, 43, 58, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -28, -28, -28, -28, -28 }, { 7, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -29, -29, -29, -29, -29, -29, 43, 43, 43, 43, 76, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -29, -29, -29, -29, -29 }, { 7, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -30, -30, -30, -30, -30, -30, 65, 43, 43, 43, 43, 43, 43, 43, 77, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -30, -30, -30, -30, -30 }, { 7, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -31, -31, -31, -31, -31, -31, 78, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -31, -31, -31, -31, -31 }, { 7, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -32, -32, -32, -32, -32, -32, 43, 43, 43, 43, 79, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -32, -32, -32, -32, -32 }, { 7, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -33, -33, -33, -33, -33, -33, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 69, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -33, -33, -33, -33, -33 }, { 7, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -34, -34, -34, -34, -34, -34, 43, 43, 43, 43, 80, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -34, -34, -34, -34, -34 }, { 7, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, 81, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, 82, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35 }, { 7, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36 }, { 7, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37 }, { 7, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38 }, { 7, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 84, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 83, 83, 83, 83, 83, 83, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 83, 83, 83, 83, 83 }, { 7, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, -40, -40, -40, -40, -40, -40, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, -40, -40, -40, -40, -40 }, { 7, 87, 87, 87, 87, 87, 87, 87, 87, 87, -41, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87 }, { 7, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, 42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42 }, { 7, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -43, -43, -43, -43, -43, -43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -43, -43, -43, -43, -43 }, { 7, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, 43, 43, 88, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -44, -44, -44, -44, -44, -44, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -44, -44, -44, -44, -44 }, { 7, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -45, -45, -45, -45, -45, -45, 43, 43, 43, 43, 43, 43, 89, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -45, -45, -45, -45, -45 }, { 7, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, 90, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -46, -46, -46, -46, -46, -46, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -46, -46, -46, -46, -46 }, { 7, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -47, -47, -47, -47, -47, -47, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 91, 43, 43, 43, 43, 43, 43, -47, -47, -47, -47, -47 }, { 7, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 92, 43, -48, -48, -48, -48, -48, -48, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -48, -48, -48, -48, -48 }, { 7, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, 43, 43, 43, 43, 43, 43, 93, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -49, -49, -49, -49, -49, -49, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -49, -49, -49, -49, -49 }, { 7, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -50, -50, -50, -50, -50, -50, 43, 43, 43, 43, 43, 43, 94, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -50, -50, -50, -50, -50 }, { 7, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 95, -51, -51, -51, -51, -51, -51, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -51, -51, -51, -51, -51 }, { 7, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -52, -52, -52, -52, -52, -52, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -52, -52, -52, -52, -52 }, { 7, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -53, -53, -53, -53, -53, -53, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -53, -53, -53, -53, -53 }, { 7, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -54, -54, -54, -54, -54, -54, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -54, -54, -54, -54, -54 }, { 7, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 96, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -55, -55, -55, -55, -55, -55, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -55, -55, -55, -55, -55 }, { 7, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 97, -56, -56, -56, -56, -56, -56, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -56, -56, -56, -56, -56 }, { 7, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -57, -57, -57, -57, -57, -57, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -57, -57, -57, -57, -57 }, { 7, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -58, -58, -58, -58, -58, -58, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 98, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -58, -58, -58, -58, -58 }, { 7, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 99, 43, 43, 43, 43, 43, 43, -59, -59, -59, -59, -59, -59, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -59, -59, -59, -59, -59 }, { 7, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 100, -60, -60, -60, -60, -60, -60, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -60, -60, -60, -60, -60 }, { 7, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 101, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -61, -61, -61, -61, -61, -61, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -61, -61, -61, -61, -61 }, { 7, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -62, -62, -62, -62, -62, -62, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 102, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -62, -62, -62, -62, -62 }, { 7, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 103, 43, 43, 43, 43, 43, 43, 43, -63, -63, -63, -63, -63, -63, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -63, -63, -63, -63, -63 }, { 7, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 104, 43, 43, -64, -64, -64, -64, -64, -64, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -64, -64, -64, -64, -64 }, { 7, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -65, -65, -65, -65, -65, -65, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 105, 43, 43, 43, 43, 43, 43, 43, -65, -65, -65, -65, -65 }, { 7, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, 43, 43, 43, 106, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -66, -66, -66, -66, -66, -66, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -66, -66, -66, -66, -66 }, { 7, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, 43, 43, 107, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -67, -67, -67, -67, -67, -67, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -67, -67, -67, -67, -67 }, { 7, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 108, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -68, -68, -68, -68, -68, -68, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -68, -68, -68, -68, -68 }, { 7, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -69, -69, -69, -69, -69, -69, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 109, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -69, -69, -69, -69, -69 }, { 7, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, 110, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -70, -70, -70, -70, -70, -70, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -70, -70, -70, -70, -70 }, { 7, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -71, -71, -71, -71, -71, -71, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -71, -71, -71, -71, -71 }, { 7, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -72, -72, -72, -72, -72, -72, 43, 43, 43, 43, 43, 43, 111, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -72, -72, -72, -72, -72 }, { 7, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -73, -73, -73, -73, -73, -73, 43, 43, 112, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -73, -73, -73, -73, -73 }, { 7, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -74, -74, -74, -74, -74, -74, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 113, 43, -74, -74, -74, -74, -74 }, { 7, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -75, -75, -75, -75, -75, -75, 43, 43, 43, 43, 43, 43, 114, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -75, -75, -75, -75, -75 }, { 7, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -76, -76, -76, -76, -76, -76, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 115, 43, 43, 43, 43, 43, 43, -76, -76, -76, -76, -76 }, { 7, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -77, -77, -77, -77, -77, -77, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 116, 43, 43, -77, -77, -77, -77, -77 }, { 7, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -78, -78, -78, -78, -78, -78, 43, 43, 43, 117, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -78, -78, -78, -78, -78 }, { 7, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -79, -79, -79, -79, -79, -79, 43, 43, 118, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -79, -79, -79, -79, -79 }, { 7, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -80, -80, -80, -80, -80, -80, 119, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -80, -80, -80, -80, -80 }, { 7, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, 81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, 82, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81 }, { 7, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82 }, { 7, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83 }, { 7, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 84, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 83, 83, 83, 83, 83, 83, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 83, 83, 83, 83, 83 }, { 7, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85 }, { 7, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, -86, -86, -86, -86, -86, -86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, -86, -86, -86, -86, -86 }, { 7, 87, 87, 87, 87, 87, 87, 87, 87, 87, -87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87 }, { 7, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 120, 43, 43, 43, 43, 43, 121, 43, 43, 43, 43, 43, 43, 43, -88, -88, -88, -88, -88, -88, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -88, -88, -88, -88, -88 }, { 7, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -89, -89, -89, -89, -89, -89, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 122, 43, 43, 43, 43, 43, 43, 43, -89, -89, -89, -89, -89 }, { 7, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 123, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -90, -90, -90, -90, -90, -90, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -90, -90, -90, -90, -90 }, { 7, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -91, -91, -91, -91, -91, -91, 43, 43, 43, 43, 124, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -91, -91, -91, -91, -91 }, { 7, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 125, 43, 43, 43, 43, 43, 43, 43, -92, -92, -92, -92, -92, -92, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -92, -92, -92, -92, -92 }, { 7, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 126, 43, 43, 43, 43, 43, 43, 43, 43, -93, -93, -93, -93, -93, -93, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -93, -93, -93, -93, -93 }, { 7, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -94, -94, -94, -94, -94, -94, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 127, 43, 43, 43, 43, 43, 43, 43, 43, -94, -94, -94, -94, -94 }, { 7, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -95, -95, -95, -95, -95, -95, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -95, -95, -95, -95, -95 }, { 7, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 128, 43, 43, 43, 43, -96, -96, -96, -96, -96, -96, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -96, -96, -96, -96, -96 }, { 7, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -97, -97, -97, -97, -97, -97, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -97, -97, -97, -97, -97 }, { 7, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, -98, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -98, -98, -98, -98, -98, -98, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 129, 43, 43, 43, 43, -98, -98, -98, -98, -98 }, { 7, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, 43, 43, 43, 43, 130, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 131, 43, 43, 43, 43, 43, 43, 43, 43, -99, -99, -99, -99, -99, -99, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -99, -99, -99, -99, -99 }, { 7, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -100, -100, -100, -100, -100, -100, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -100, -100, -100, -100, -100 }, { 7, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -101, -101, -101, -101, -101, -101, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -101, -101, -101, -101, -101 }, { 7, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -102, -102, -102, -102, -102, -102, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -102, -102, -102, -102, -102 }, { 7, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, 43, 43, 132, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -103, -103, -103, -103, -103, -103, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -103, -103, -103, -103, -103 }, { 7, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, -104, 43, 43, 43, 43, 133, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -104, -104, -104, -104, -104, -104, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -104, -104, -104, -104, -104 }, { 7, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -105, -105, -105, -105, -105, -105, 43, 43, 134, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -105, -105, -105, -105, -105 }, { 7, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, 43, 43, 43, 43, 43, 43, 43, 43, 135, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -106, -106, -106, -106, -106, -106, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -106, -106, -106, -106, -106 }, { 7, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 136, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -107, -107, -107, -107, -107, -107, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -107, -107, -107, -107, -107 }, { 7, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 137, 43, 43, 43, 43, 43, 43, -108, -108, -108, -108, -108, -108, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -108, -108, -108, -108, -108 }, { 7, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, -109, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -109, -109, -109, -109, -109, -109, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 138, 43, 43, 43, 43, 43, 43, -109, -109, -109, -109, -109 }, { 7, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 139, 43, 43, 43, 43, 43, 43, 43, 43, -110, -110, -110, -110, -110, -110, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -110, -110, -110, -110, -110 }, { 7, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -111, -111, -111, -111, -111, -111, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 140, 43, 43, 43, 43, 43, 43, 43, -111, -111, -111, -111, -111 }, { 7, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, -112, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -112, -112, -112, -112, -112, -112, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 141, 43, 43, 43, 43, 43, 142, 43, 43, 43, 43, 43, 43, 43, -112, -112, -112, -112, -112 }, { 7, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, -113, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -113, -113, -113, -113, -113, -113, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 143, 43, 43, 43, 43, 43, 43, 43, -113, -113, -113, -113, -113 }, { 7, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, -114, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -114, -114, -114, -114, -114, -114, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 144, 43, 43, 43, 43, 43, 43, 43, 43, -114, -114, -114, -114, -114 }, { 7, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -115, -115, -115, -115, -115, -115, 43, 43, 43, 43, 145, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 146, 43, 43, 43, 43, 43, 43, 43, 43, -115, -115, -115, -115, -115 }, { 7, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -116, -116, -116, -116, -116, -116, 43, 43, 43, 43, 147, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -116, -116, -116, -116, -116 }, { 7, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, -117, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -117, -117, -117, -117, -117, -117, 43, 43, 43, 43, 43, 43, 43, 43, 148, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -117, -117, -117, -117, -117 }, { 7, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, -118, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -118, -118, -118, -118, -118, -118, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 149, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -118, -118, -118, -118, -118 }, { 7, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -119, -119, -119, -119, -119, -119, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 150, 43, 43, 43, 43, 43, 43, 43, 43, -119, -119, -119, -119, -119 }, { 7, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, -120, 43, 43, 43, 43, 43, 43, 43, 43, 151, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -120, -120, -120, -120, -120, -120, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -120, -120, -120, -120, -120 }, { 7, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, 43, 43, 43, 43, 152, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -121, -121, -121, -121, -121, -121, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -121, -121, -121, -121, -121 }, { 7, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, -122, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -122, -122, -122, -122, -122, -122, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 153, 43, 43, 43, 43, 43, 43, -122, -122, -122, -122, -122 }, { 7, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, -123, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -123, -123, -123, -123, -123, -123, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -123, -123, -123, -123, -123 }, { 7, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, -124, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -124, -124, -124, -124, -124, -124, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -124, -124, -124, -124, -124 }, { 7, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -125, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -125, -125, -125, -125, -125, -125, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -125, -125, -125, -125, -125 }, { 7, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, 43, 43, 43, 43, 154, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -126, -126, -126, -126, -126, -126, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -126, -126, -126, -126, -126 }, { 7, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -127, -127, -127, -127, -127, -127, 43, 43, 43, 43, 155, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -127, -127, -127, -127, -127 }, { 7, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, 43, 43, 43, 43, 43, 43, 43, 43, 156, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -128, -128, -128, -128, -128, -128, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -128, -128, -128, -128, -128 }, { 7, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -129, -129, -129, -129, -129, -129, 43, 43, 43, 43, 43, 43, 43, 43, 157, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -129, -129, -129, -129, -129 }, { 7, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, -130, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 158, 43, 43, 43, 43, 43, 43, 43, 43, -130, -130, -130, -130, -130, -130, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -130, -130, -130, -130, -130 }, { 7, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, 43, 43, 43, 43, 159, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -131, -131, -131, -131, -131, -131, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -131, -131, -131, -131, -131 }, { 7, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, 160, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -132, -132, -132, -132, -132, -132, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -132, -132, -132, -132, -132 }, { 7, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, -133, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 161, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -133, -133, -133, -133, -133, -133, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -133, -133, -133, -133, -133 }, { 7, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, -134, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -134, -134, -134, -134, -134, -134, 162, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -134, -134, -134, -134, -134 }, { 7, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, 163, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -135, -135, -135, -135, -135, -135, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -135, -135, -135, -135, -135 }, { 7, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 164, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -136, -136, -136, -136, -136, -136, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -136, -136, -136, -136, -136 }, { 7, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, -137, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 165, 43, 43, 43, 43, 43, 43, 43, -137, -137, -137, -137, -137, -137, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -137, -137, -137, -137, -137 }, { 7, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -138, -138, -138, -138, -138, -138, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 166, 43, 43, 43, 43, 43, 43, 43, -138, -138, -138, -138, -138 }, { 7, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 167, 43, 43, 43, 43, 43, 43, 43, -139, -139, -139, -139, -139, -139, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -139, -139, -139, -139, -139 }, { 7, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -140, -140, -140, -140, -140, -140, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 168, 43, 43, 43, 43, 43, 43, -140, -140, -140, -140, -140 }, { 7, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, -141, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -141, -141, -141, -141, -141, -141, 43, 43, 43, 43, 43, 43, 43, 43, 169, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -141, -141, -141, -141, -141 }, { 7, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, -142, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -142, -142, -142, -142, -142, -142, 43, 43, 43, 43, 170, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -142, -142, -142, -142, -142 }, { 7, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, -143, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -143, -143, -143, -143, -143, -143, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -143, -143, -143, -143, -143 }, { 7, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -144, -144, -144, -144, -144, -144, 43, 43, 43, 43, 171, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -144, -144, -144, -144, -144 }, { 7, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -145, -145, -145, -145, -145, -145, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 172, 43, 43, 43, 43, 43, 43, 43, 43, -145, -145, -145, -145, -145 }, { 7, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -146, -146, -146, -146, -146, -146, 43, 43, 43, 43, 173, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -146, -146, -146, -146, -146 }, { 7, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -147, -147, -147, -147, -147, -147, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 174, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -147, -147, -147, -147, -147 }, { 7, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -148, -148, -148, -148, -148, -148, 175, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -148, -148, -148, -148, -148 }, { 7, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, -149, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -149, -149, -149, -149, -149, -149, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 176, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -149, -149, -149, -149, -149 }, { 7, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, -150, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -150, -150, -150, -150, -150, -150, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 71, 43, 43, 43, 43, 43, 43, 43, -150, -150, -150, -150, -150 }, { 7, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, -151, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 177, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -151, -151, -151, -151, -151, -151, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -151, -151, -151, -151, -151 }, { 7, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, 43, 43, 178, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -152, -152, -152, -152, -152, -152, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -152, -152, -152, -152, -152 }, { 7, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, -153, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -153, -153, -153, -153, -153, -153, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 179, 43, 43, 43, 43, 43, 43, 43, 43, -153, -153, -153, -153, -153 }, { 7, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, -154, 43, 43, 43, 43, 180, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -154, -154, -154, -154, -154, -154, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -154, -154, -154, -154, -154 }, { 7, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, -155, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -155, -155, -155, -155, -155, -155, 43, 43, 43, 43, 181, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -155, -155, -155, -155, -155 }, { 7, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 182, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -156, -156, -156, -156, -156, -156, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -156, -156, -156, -156, -156 }, { 7, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, -157, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -157, -157, -157, -157, -157, -157, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 183, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -157, -157, -157, -157, -157 }, { 7, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, -158, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 184, 43, 43, 43, 43, 43, 43, 43, -158, -158, -158, -158, -158, -158, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -158, -158, -158, -158, -158 }, { 7, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, -159, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 185, 43, 43, 43, 43, 43, 43, 43, -159, -159, -159, -159, -159, -159, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -159, -159, -159, -159, -159 }, { 7, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 186, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -160, -160, -160, -160, -160, -160, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -160, -160, -160, -160, -160 }, { 7, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 187, 43, 43, 43, 43, 43, 43, 43, -161, -161, -161, -161, -161, -161, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -161, -161, -161, -161, -161 }, { 7, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -162, -162, -162, -162, -162, -162, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 188, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -162, -162, -162, -162, -162 }, { 7, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 189, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -163, -163, -163, -163, -163, -163, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -163, -163, -163, -163, -163 }, { 7, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, 43, 43, 43, 190, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -164, -164, -164, -164, -164, -164, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -164, -164, -164, -164, -164 }, { 7, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -165, -165, -165, -165, -165, -165, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -165, -165, -165, -165, -165 }, { 7, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -166, -166, -166, -166, -166, -166, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -166, -166, -166, -166, -166 }, { 7, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -167, -167, -167, -167, -167, -167, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -167, -167, -167, -167, -167 }, { 7, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -168, -168, -168, -168, -168, -168, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 191, 43, 43, 43, 43, 43, 43, 43, 43, -168, -168, -168, -168, -168 }, { 7, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -169, -169, -169, -169, -169, -169, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 192, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -169, -169, -169, -169, -169 }, { 7, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -170, -170, -170, -170, -170, -170, 43, 43, 193, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -170, -170, -170, -170, -170 }, { 7, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -171, -171, -171, -171, -171, -171, 43, 43, 43, 43, 194, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -171, -171, -171, -171, -171 }, { 7, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, -172, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -172, -172, -172, -172, -172, -172, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 195, 43, 43, 43, 43, 43, 43, 43, -172, -172, -172, -172, -172 }, { 7, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -173, -173, -173, -173, -173, -173, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 196, 43, 43, 43, 43, 43, 43, 43, -173, -173, -173, -173, -173 }, { 7, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -174, -174, -174, -174, -174, -174, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 187, 43, 43, 43, 43, 43, 43, 43, -174, -174, -174, -174, -174 }, { 7, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -175, -175, -175, -175, -175, -175, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 197, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -175, -175, -175, -175, -175 }, { 7, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -176, -176, -176, -176, -176, -176, 43, 43, 43, 198, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -176, -176, -176, -176, -176 }, { 7, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 199, 43, 43, 43, 43, 43, 43, 43, -177, -177, -177, -177, -177, -177, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -177, -177, -177, -177, -177 }, { 7, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, -178, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 200, 43, 43, 43, 43, 43, 43, 43, -178, -178, -178, -178, -178, -178, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -178, -178, -178, -178, -178 }, { 7, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -179, -179, -179, -179, -179, -179, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 201, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -179, -179, -179, -179, -179 }, { 7, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 202, 43, 43, 43, 43, 43, 43, 43, -180, -180, -180, -180, -180, -180, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -180, -180, -180, -180, -180 }, { 7, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, -181, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -181, -181, -181, -181, -181, -181, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 203, 43, 43, 43, 43, 43, 43, 43, -181, -181, -181, -181, -181 }, { 7, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, -182, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 204, 43, 43, 43, 43, 43, 43, 43, -182, -182, -182, -182, -182, -182, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -182, -182, -182, -182, -182 }, { 7, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -183, -183, -183, -183, -183, -183, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 205, 43, 43, 43, 43, 43, 43, 43, -183, -183, -183, -183, -183 }, { 7, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -184, -184, -184, -184, -184, -184, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -184, -184, -184, -184, -184 }, { 7, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -185, -185, -185, -185, -185, -185, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -185, -185, -185, -185, -185 }, { 7, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 206, 43, 43, 43, 43, 43, 43, 43, -186, -186, -186, -186, -186, -186, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -186, -186, -186, -186, -186 }, { 7, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -187, -187, -187, -187, -187, -187, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -187, -187, -187, -187, -187 }, { 7, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -188, -188, -188, -188, -188, -188, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 207, 43, 43, 43, 43, 43, 43, 43, -188, -188, -188, -188, -188 }, { 7, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 208, 43, 43, 43, 43, 43, 43, 43, -189, -189, -189, -189, -189, -189, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -189, -189, -189, -189, -189 }, { 7, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 209, 43, 43, 43, 43, 43, 43, 43, -190, -190, -190, -190, -190, -190, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -190, -190, -190, -190, -190 }, { 7, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -191, -191, -191, -191, -191, -191, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 210, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -191, -191, -191, -191, -191 }, { 7, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -192, -192, -192, -192, -192, -192, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 199, 43, 43, 43, 43, 43, 43, 43, -192, -192, -192, -192, -192 }, { 7, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -193, -193, -193, -193, -193, -193, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 200, 43, 43, 43, 43, 43, 43, 43, -193, -193, -193, -193, -193 }, { 7, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -194, -194, -194, -194, -194, -194, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 211, 43, 43, 43, 43, 43, 43, 43, -194, -194, -194, -194, -194 }, { 7, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -195, -195, -195, -195, -195, -195, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -195, -195, -195, -195, -195 }, { 7, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -196, -196, -196, -196, -196, -196, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -196, -196, -196, -196, -196 }, { 7, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -197, -197, -197, -197, -197, -197, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 212, 43, 43, 43, 43, 43, 43, 43, -197, -197, -197, -197, -197 }, { 7, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -198, -198, -198, -198, -198, -198, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 213, 43, 43, 43, 43, 43, 43, 43, -198, -198, -198, -198, -198 }, { 7, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -199, -199, -199, -199, -199, -199, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -199, -199, -199, -199, -199 }, { 7, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -200, -200, -200, -200, -200, -200, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -200, -200, -200, -200, -200 }, { 7, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -201, -201, -201, -201, -201, -201, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 214, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -201, -201, -201, -201, -201 }, { 7, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -202, -202, -202, -202, -202, -202, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -202, -202, -202, -202, -202 }, { 7, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -203, -203, -203, -203, -203, -203, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -203, -203, -203, -203, -203 }, { 7, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -204, -204, -204, -204, -204, -204, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -204, -204, -204, -204, -204 }, { 7, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -205, -205, -205, -205, -205, -205, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -205, -205, -205, -205, -205 }, { 7, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -206, -206, -206, -206, -206, -206, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -206, -206, -206, -206, -206 }, { 7, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -207, -207, -207, -207, -207, -207, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -207, -207, -207, -207, -207 }, { 7, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -208, -208, -208, -208, -208, -208, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -208, -208, -208, -208, -208 }, { 7, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -209, -209, -209, -209, -209, -209, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -209, -209, -209, -209, -209 }, { 7, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -210, -210, -210, -210, -210, -210, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 215, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -210, -210, -210, -210, -210 }, { 7, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -211, -211, -211, -211, -211, -211, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -211, -211, -211, -211, -211 }, { 7, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -212, -212, -212, -212, -212, -212, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -212, -212, -212, -212, -212 }, { 7, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, -213, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -213, -213, -213, -213, -213, -213, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -213, -213, -213, -213, -213 }, { 7, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, -214, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -214, -214, -214, -214, -214, -214, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 216, 43, 43, 43, 43, 43, 43, 43, -214, -214, -214, -214, -214 }, { 7, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -215, -215, -215, -215, -215, -215, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 216, 43, 43, 43, 43, 43, 43, 43, -215, -215, -215, -215, -215 }, { 7, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -216, -216, -216, -216, -216, -216, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -216, -216, -216, -216, -216 }, } ; static yy_state_type yy_get_previous_state ( yyscan_t yyscanner ); static yy_state_type yy_try_NUL_trans ( yy_state_type current_state , yyscan_t yyscanner); static int yy_get_next_buffer ( yyscan_t yyscanner ); static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ yyg->yytext_ptr = yy_bp; \ yyleng = (int) (yy_cp - yy_bp); \ yyg->yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; #define YY_NUM_RULES 37 #define YY_END_OF_BUFFER 38 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static const flex_int16_t yy_accept[217] = { 0, 0, 0, 0, 0, 36, 36, 38, 3, 2, 31, 31, 31, 10, 31, 14, 31, 31, 20, 31, 31, 31, 28, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 2, 1, 35, 37, 35, 32, 36, 2, 31, 31, 31, 31, 31, 31, 31, 31, 31, 13, 15, 17, 31, 31, 19, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 2, 1, 33, 33, 34, 32, 36, 31, 31, 31, 31, 9, 11, 11, 12, 31, 16, 31, 31, 22, 21, 23, 31, 31, 31, 26, 27, 31, 31, 31, 31, 31, 9, 31, 31, 31, 31, 27, 31, 31, 31, 31, 7, 8, 9, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 29, 29, 30, 31, 31, 31, 9, 31, 31, 31, 31, 31, 31, 30, 31, 31, 31, 31, 31, 31, 31, 20, 20, 31, 25, 31, 31, 31, 29, 29, 30, 31, 31, 31, 31, 20, 20, 31, 31, 31, 5, 6, 31, 11, 11, 18, 18, 20, 20, 24, 25, 24, 26, 27, 31, 31, 31, 11, 20, 20, 26, 27, 5, 6, 31, 11, 11, 18, 18, 24, 24, 26, 27, 31, 11, 26, 27, 31, 4, 4 } ; static const yy_state_type yy_NUL_trans[217] = { 0, 8, 8, 37, 37, 41, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "wcsutrn.l" /*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcsutrn.c,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * wcsutrn.l is a Flex description file containing the definition of a lexical * scanner that translates non-standard FITS units specifications. * * It requires Flex v2.5.4 or later. * * Refer to wcsunits.h for a description of the user interface and operating * notes. * *===========================================================================*/ /* Options. */ #define YY_NO_INPUT 1 /* Exclusive start states. */ #line 49 "wcsutrn.l" #include #include #include #include #include "wcserr.h" #include "wcsunits.h" // User data associated with yyscanner. struct wcsutrn_extra { // Used in preempting the call to exit() by yy_fatal_error(). jmp_buf abort_jmp_env; }; #define YY_DECL int wcsutrne_scanner(int ctrl, char unitstr[], \ struct wcserr **err, yyscan_t yyscanner) // Dummy definition to circumvent compiler warnings. #define YY_INPUT(inbuff, count, bufsize) { count = YY_NULL; } // Preempt the call to exit() by yy_fatal_error(). #define exit(status) longjmp(yyextra->abort_jmp_env, status); // Internal helper functions. static YY_DECL; #line 4449 "wcsutrn.c" #line 4450 "wcsutrn.c" #define INITIAL 0 #define NEXT 1 #define FLUSH 2 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #define YY_EXTRA_TYPE struct wcsutrn_extra * /* Holds the entire state of the reentrant scanner. */ struct yyguts_t { /* User-defined. Not touched by flex. */ YY_EXTRA_TYPE yyextra_r; /* The rest are the same as the globals declared in the non-reentrant scanner. */ FILE *yyin_r, *yyout_r; size_t yy_buffer_stack_top; /**< index of top of stack. */ size_t yy_buffer_stack_max; /**< capacity of stack. */ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ char yy_hold_char; int yy_n_chars; int yyleng_r; char *yy_c_buf_p; int yy_init; int yy_start; int yy_did_buffer_switch_on_eof; int yy_start_stack_ptr; int yy_start_stack_depth; int *yy_start_stack; yy_state_type yy_last_accepting_state; char* yy_last_accepting_cpos; int yylineno_r; int yy_flex_debug_r; char *yytext_r; int yy_more_flag; int yy_more_len; }; /* end struct yyguts_t */ static int yy_init_globals ( yyscan_t yyscanner ); int yylex_init (yyscan_t* scanner); int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy ( yyscan_t yyscanner ); int yyget_debug ( yyscan_t yyscanner ); void yyset_debug ( int debug_flag , yyscan_t yyscanner ); YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner ); void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner ); FILE *yyget_in ( yyscan_t yyscanner ); void yyset_in ( FILE * _in_str , yyscan_t yyscanner ); FILE *yyget_out ( yyscan_t yyscanner ); void yyset_out ( FILE * _out_str , yyscan_t yyscanner ); int yyget_leng ( yyscan_t yyscanner ); char *yyget_text ( yyscan_t yyscanner ); int yyget_lineno ( yyscan_t yyscanner ); void yyset_lineno ( int _line_number , yyscan_t yyscanner ); int yyget_column ( yyscan_t yyscanner ); void yyset_column ( int _column_no , yyscan_t yyscanner ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap ( yyscan_t yyscanner ); #else extern int yywrap ( yyscan_t yyscanner ); #endif #endif #ifndef YY_NO_UNPUT static void yyunput ( int c, char *buf_ptr , yyscan_t yyscanner); #endif #ifndef yytext_ptr static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen ( const char * , yyscan_t yyscanner); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput ( yyscan_t yyscanner ); #else static int input ( yyscan_t yyscanner ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ errno=0; \ while ( (result = (int) read( fileno(yyin), buf, (yy_size_t) max_size )) < 0 ) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex (yyscan_t yyscanner); #define YY_DECL int yylex (yyscan_t yyscanner) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK /*LINTED*/break; #endif #define YY_RULE_SETUP \ if ( yyleng > 0 ) \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ (yytext[yyleng - 1] == '\n'); \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { yy_state_type yy_current_state; char *yy_cp, *yy_bp; int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( !yyg->yy_init ) { yyg->yy_init = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! yyg->yy_start ) yyg->yy_start = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } yy_load_buffer_state( yyscanner ); } { #line 77 "wcsutrn.l" #line 79 "wcsutrn.l" static const char *function = "wcsutrne_scanner"; if (err) *err = 0x0; char orig[80], subs[80]; *orig = '\0'; *subs = '\0'; int bracket = 0; int unsafe = 0; int status = -1; yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner); yy_scan_string(unitstr, yyscanner); *unitstr = '\0'; // Return here via longjmp() invoked by yy_fatal_error(). if (setjmp(yyextra->abort_jmp_env)) { return wcserr_set(WCSERR_SET(UNITSERR_PARSER_ERROR), "Internal units translator error"); } BEGIN(INITIAL); #ifdef DEBUG fprintf(stderr, "\n%s ->\n", unitstr); #endif #line 4728 "wcsutrn.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { yy_cp = yyg->yy_c_buf_p; /* Support of yytext. */ *yy_cp = yyg->yy_hold_char; /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = yyg->yy_start; yy_current_state += YY_AT_BOL(); yy_match: while ( (yy_current_state = yy_nxt[yy_current_state][ YY_SC_TO_UI(*yy_cp) ]) > 0 ) ++yy_cp; yy_current_state = -yy_current_state; yy_find_action: yy_act = yy_accept[yy_current_state]; YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 1: YY_RULE_SETUP #line 107 "wcsutrn.l" { // Looks like a keycomment. strcat(unitstr, "["); bracket = 1; } YY_BREAK case 2: YY_RULE_SETUP #line 113 "wcsutrn.l" // Discard leading whitespace. YY_BREAK case 3: /* rule 3 can match eol */ YY_RULE_SETUP #line 115 "wcsutrn.l" { // Non-alphabetic character. strcat(unitstr, yytext); if (bracket && *yytext == ']') { BEGIN(FLUSH); } } YY_BREAK case 4: YY_RULE_SETUP #line 123 "wcsutrn.l" { strcpy(orig, yytext); strcpy(subs, "Angstrom"); BEGIN(NEXT); } YY_BREAK case 5: YY_RULE_SETUP #line 129 "wcsutrn.l" { strcpy(orig, yytext); strcpy(subs, "arcmin"); BEGIN(NEXT); } YY_BREAK case 6: YY_RULE_SETUP #line 135 "wcsutrn.l" { strcpy(orig, yytext); strcpy(subs, "arcsec"); BEGIN(NEXT); } YY_BREAK case 7: YY_RULE_SETUP #line 141 "wcsutrn.l" { strcpy(orig, yytext); strcpy(subs, "beam"); BEGIN(NEXT); } YY_BREAK case 8: YY_RULE_SETUP #line 147 "wcsutrn.l" { strcpy(orig, yytext); strcpy(subs, "byte"); BEGIN(NEXT); } YY_BREAK case 9: YY_RULE_SETUP #line 153 "wcsutrn.l" { strcpy(orig, yytext); strcpy(subs, "d"); BEGIN(NEXT); } YY_BREAK case 10: YY_RULE_SETUP #line 159 "wcsutrn.l" { unsafe = 1; strcpy(orig, yytext); strcpy(subs, (ctrl & 4) ? "d" : "D"); BEGIN(NEXT); } YY_BREAK case 11: YY_RULE_SETUP #line 166 "wcsutrn.l" { strcpy(orig, yytext); strcpy(subs, "deg"); BEGIN(NEXT); } YY_BREAK case 12: YY_RULE_SETUP #line 172 "wcsutrn.l" { strcpy(orig, yytext); strcpy(subs, "GHz"); BEGIN(NEXT); } YY_BREAK case 13: YY_RULE_SETUP #line 178 "wcsutrn.l" { strcpy(orig, yytext); strcpy(subs, "h"); BEGIN(NEXT); } YY_BREAK case 14: YY_RULE_SETUP #line 184 "wcsutrn.l" { unsafe = 1; strcpy(orig, yytext); strcpy(subs, (ctrl & 2) ? "h" : "H"); BEGIN(NEXT); } YY_BREAK case 15: YY_RULE_SETUP #line 191 "wcsutrn.l" { strcpy(orig, yytext); strcpy(subs, "Hz"); BEGIN(NEXT); } YY_BREAK case 16: YY_RULE_SETUP #line 197 "wcsutrn.l" { strcpy(orig, yytext); strcpy(subs, "kHz"); BEGIN(NEXT); } YY_BREAK case 17: YY_RULE_SETUP #line 203 "wcsutrn.l" { strcpy(orig, yytext); strcpy(subs, "Jy"); BEGIN(NEXT); } YY_BREAK case 18: YY_RULE_SETUP #line 209 "wcsutrn.l" { strcpy(orig, yytext); strcpy(subs, "K"); BEGIN(NEXT); } YY_BREAK case 19: YY_RULE_SETUP #line 215 "wcsutrn.l" { strcpy(orig, yytext); strcpy(subs, "km"); BEGIN(NEXT); } YY_BREAK case 20: YY_RULE_SETUP #line 221 "wcsutrn.l" { strcpy(orig, yytext); strcpy(subs, "m"); BEGIN(NEXT); } YY_BREAK case 21: YY_RULE_SETUP #line 227 "wcsutrn.l" { strcpy(orig, yytext); strcpy(subs, "min"); BEGIN(NEXT); } YY_BREAK case 22: YY_RULE_SETUP #line 233 "wcsutrn.l" { strcpy(orig, yytext); strcpy(subs, "MHz"); BEGIN(NEXT); } YY_BREAK case 23: YY_RULE_SETUP #line 239 "wcsutrn.l" { strcpy(orig, yytext); strcpy(subs, "ohm"); BEGIN(NEXT); } YY_BREAK case 24: YY_RULE_SETUP #line 245 "wcsutrn.l" { strcpy(orig, yytext); strcpy(subs, "Pa"); BEGIN(NEXT); } YY_BREAK case 25: YY_RULE_SETUP #line 251 "wcsutrn.l" { strcpy(orig, yytext); strcpy(subs, "pixel"); BEGIN(NEXT); } YY_BREAK case 26: YY_RULE_SETUP #line 257 "wcsutrn.l" { strcpy(orig, yytext); strcpy(subs, "rad"); BEGIN(NEXT); } YY_BREAK case 27: YY_RULE_SETUP #line 263 "wcsutrn.l" { strcpy(orig, yytext); strcpy(subs, "s"); BEGIN(NEXT); } YY_BREAK case 28: YY_RULE_SETUP #line 269 "wcsutrn.l" { unsafe = 1; strcpy(orig, yytext); strcpy(subs, (ctrl & 1) ? "s" : "S"); BEGIN(NEXT); } YY_BREAK case 29: YY_RULE_SETUP #line 276 "wcsutrn.l" { strcpy(orig, yytext); strcpy(subs, "V"); BEGIN(NEXT); } YY_BREAK case 30: YY_RULE_SETUP #line 282 "wcsutrn.l" { strcpy(orig, yytext); strcpy(subs, "yr"); BEGIN(NEXT); } YY_BREAK case 31: YY_RULE_SETUP #line 288 "wcsutrn.l" { // Not a recognized alias. strcpy(orig, yytext); strcpy(subs, orig); BEGIN(NEXT); } YY_BREAK case 32: YY_RULE_SETUP #line 295 "wcsutrn.l" { // Reject the alias match. strcat(orig, yytext); strcpy(subs, orig); } YY_BREAK case 33: /* rule 33 can match eol */ YY_RULE_SETUP #line 301 "wcsutrn.l" { // Discard separating whitespace. unput(yytext[yyleng-1]); } YY_BREAK case 34: YY_RULE_SETUP #line 306 "wcsutrn.l" { // Compress separating whitespace. strcat(unitstr, subs); strcat(unitstr, " "); if (strcmp(orig, subs)) status = 0; unput(yytext[yyleng-1]); *subs = '\0'; BEGIN(INITIAL); } YY_BREAK case 35: YY_RULE_SETUP #line 316 "wcsutrn.l" { // Copy anything else unchanged. strcat(unitstr, subs); if (strcmp(orig, subs)) status = 0; unput(*yytext); *subs = '\0'; BEGIN(INITIAL); } YY_BREAK case 36: YY_RULE_SETUP #line 325 "wcsutrn.l" { // Copy out remaining input. strcat(unitstr, yytext); } YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(NEXT): case YY_STATE_EOF(FLUSH): #line 330 "wcsutrn.l" { // End-of-string. if (*subs) { strcat(unitstr, subs); if (strcmp(orig, subs)) status = 0; } if (unsafe) { return wcserr_set(WCSERR_SET(UNITSERR_UNSAFE_TRANS), "Unsafe unit translation in '%s'", unitstr); } return status; } YY_BREAK case 37: YY_RULE_SETUP #line 344 "wcsutrn.l" ECHO; YY_BREAK #line 5115 "wcsutrn.c" case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = yyg->yy_hold_char; YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) { /* This was really a NUL. */ yy_state_type yy_next_state; yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++yyg->yy_c_buf_p; yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = yyg->yy_c_buf_p; goto yy_find_action; } } else switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_END_OF_FILE: { yyg->yy_did_buffer_switch_on_eof = 0; if ( yywrap( yyscanner ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: yyg->yy_c_buf_p = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of user's declarations */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; char *source = yyg->yytext_ptr; int number_to_move, i; int ret_val; if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1); for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) (yyg->yy_c_buf_p - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yyrealloc( (void *) b->yy_ch_buf, (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = NULL; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), yyg->yy_n_chars, num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } if ( yyg->yy_n_chars == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin , yyscanner); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); /* "- 2" to take care of EOB's */ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); } yyg->yy_n_chars += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (yyscan_t yyscanner) { yy_state_type yy_current_state; char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_current_state = yyg->yy_start; yy_current_state += YY_AT_BOL(); for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) { if ( *yy_cp ) { yy_current_state = yy_nxt[yy_current_state][YY_SC_TO_UI(*yy_cp)]; } else yy_current_state = yy_NUL_trans[yy_current_state]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) { int yy_is_jam; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ yy_current_state = yy_NUL_trans[yy_current_state]; yy_is_jam = (yy_current_state == 0); (void)yyg; return yy_is_jam ? 0 : yy_current_state; } #ifndef YY_NO_UNPUT static void yyunput (int c, char * yy_bp , yyscan_t yyscanner) { char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_cp = yyg->yy_c_buf_p; /* undo effects of setting up yytext */ *yy_cp = yyg->yy_hold_char; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ int number_to_move = yyg->yy_n_chars + 2; char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; yyg->yytext_ptr = yy_bp; yyg->yy_hold_char = *yy_cp; yyg->yy_c_buf_p = yy_cp; } #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (yyscan_t yyscanner) #else static int input (yyscan_t yyscanner) #endif { int c; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; *yyg->yy_c_buf_p = yyg->yy_hold_char; if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) /* This was really a NUL. */ *yyg->yy_c_buf_p = '\0'; else { /* need more input */ int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr); ++yyg->yy_c_buf_p; switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin , yyscanner); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( yyscanner ) ) return 0; if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(yyscanner); #else return input(yyscanner); #endif } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + offset; break; } } } c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ yyg->yy_hold_char = *++yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * @param yyscanner The scanner object. * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } yy_init_buffer( YY_CURRENT_BUFFER, input_file , yyscanner); yy_load_buffer_state( yyscanner ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * @param yyscanner The scanner object. */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (yyscanner); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( yyscanner ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ yyg->yy_did_buffer_switch_on_eof = 1; } static void yy_load_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; yyg->yy_hold_char = *yyg->yy_c_buf_p; } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * @param yyscanner The scanner object. * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file , yyscanner); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * @param yyscanner The scanner object. */ void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree( (void *) b->yy_ch_buf , yyscanner ); yyfree( (void *) b , yyscanner ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) { int oerrno = errno; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_flush_buffer( b , yyscanner); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * @param yyscanner The scanner object. */ void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( yyscanner ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * @param yyscanner The scanner object. */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (new_buffer == NULL) return; yyensure_buffer_stack(yyscanner); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) yyg->yy_buffer_stack_top++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * @param yyscanner The scanner object. */ void yypop_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER , yyscanner); YY_CURRENT_BUFFER_LVALUE = NULL; if (yyg->yy_buffer_stack_top > 0) --yyg->yy_buffer_stack_top; if (YY_CURRENT_BUFFER) { yy_load_buffer_state( yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (yyscan_t yyscanner) { yy_size_t num_to_alloc; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!yyg->yy_buffer_stack) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; yyg->yy_buffer_stack_top = 0; return; } if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ /* Increase the buffer to prepare for a possible push. */ yy_size_t grow_size = 8 /* arbitrary grow size */; num_to_alloc = yyg->yy_buffer_stack_max + grow_size; yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc (yyg->yy_buffer_stack, num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return NULL; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = NULL; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer( b , yyscanner ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * @param yyscanner The scanner object. * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (const char * yystr , yyscan_t yyscanner) { return yy_scan_bytes( yystr, (int) strlen(yystr) , yyscanner); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len , yyscan_t yyscanner) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = (yy_size_t) (_yybytes_len + 2); buf = (char *) yyalloc( n , yyscanner ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer( buf, n , yyscanner); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yynoreturn yy_fatal_error (const char* msg , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = yyg->yy_hold_char; \ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ yyg->yy_hold_char = *yyg->yy_c_buf_p; \ *yyg->yy_c_buf_p = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the user-defined data for this scanner. * @param yyscanner The scanner object. */ YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyextra; } /** Get the current line number. * @param yyscanner The scanner object. */ int yyget_lineno (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yylineno; } /** Get the current column number. * @param yyscanner The scanner object. */ int yyget_column (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yycolumn; } /** Get the input stream. * @param yyscanner The scanner object. */ FILE *yyget_in (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyin; } /** Get the output stream. * @param yyscanner The scanner object. */ FILE *yyget_out (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyout; } /** Get the length of the current token. * @param yyscanner The scanner object. */ int yyget_leng (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyleng; } /** Get the current token. * @param yyscanner The scanner object. */ char *yyget_text (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yytext; } /** Set the user-defined data. This data is never touched by the scanner. * @param user_defined The data to be associated with this scanner. * @param yyscanner The scanner object. */ void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyextra = user_defined ; } /** Set the current line number. * @param _line_number line number * @param yyscanner The scanner object. */ void yyset_lineno (int _line_number , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* lineno is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "yyset_lineno called with no buffer" ); yylineno = _line_number; } /** Set the current column. * @param _column_no column number * @param yyscanner The scanner object. */ void yyset_column (int _column_no , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* column is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "yyset_column called with no buffer" ); yycolumn = _column_no; } /** Set the input stream. This does not discard the current * input buffer. * @param _in_str A readable stream. * @param yyscanner The scanner object. * @see yy_switch_to_buffer */ void yyset_in (FILE * _in_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyin = _in_str ; } void yyset_out (FILE * _out_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyout = _out_str ; } int yyget_debug (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yy_flex_debug; } void yyset_debug (int _bdebug , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_flex_debug = _bdebug ; } /* Accessor methods for yylval and yylloc */ /* User-visible API */ /* yylex_init is special because it creates the scanner itself, so it is * the ONLY reentrant function that doesn't take the scanner as the last argument. * That's why we explicitly handle the declaration, instead of using our macros. */ int yylex_init(yyscan_t* ptr_yy_globals) { if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); return yy_init_globals ( *ptr_yy_globals ); } /* yylex_init_extra has the same functionality as yylex_init, but follows the * convention of taking the scanner as the last argument. Note however, that * this is a *pointer* to a scanner, as it will be allocated by this call (and * is the reason, too, why this function also must handle its own declaration). * The user defined value in the first argument will be available to yyalloc in * the yyextra field. */ int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals ) { struct yyguts_t dummy_yyguts; yyset_extra (yy_user_defined, &dummy_yyguts); if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); yyset_extra (yy_user_defined, *ptr_yy_globals); return yy_init_globals ( *ptr_yy_globals ); } static int yy_init_globals (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ yyg->yy_buffer_stack = NULL; yyg->yy_buffer_stack_top = 0; yyg->yy_buffer_stack_max = 0; yyg->yy_c_buf_p = NULL; yyg->yy_init = 0; yyg->yy_start = 0; yyg->yy_start_stack_ptr = 0; yyg->yy_start_stack_depth = 0; yyg->yy_start_stack = NULL; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = NULL; yyout = NULL; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer( YY_CURRENT_BUFFER , yyscanner ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(yyscanner); } /* Destroy the stack itself. */ yyfree(yyg->yy_buffer_stack , yyscanner); yyg->yy_buffer_stack = NULL; /* Destroy the start condition stack. */ yyfree( yyg->yy_start_stack , yyscanner ); yyg->yy_start_stack = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( yyscanner); /* Destroy the main struct (reentrant only). */ yyfree ( yyscanner , yyscanner ); yyscanner = NULL; return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (const char * s , yyscan_t yyscanner) { int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; return malloc(size); } void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return realloc(ptr, size); } void yyfree (void * ptr , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 344 "wcsutrn.l" /*---------------------------------------------------------------------------- * External interface to the scanner. *---------------------------------------------------------------------------*/ int wcsutrne( int ctrl, char unitstr[], struct wcserr **err) { // Function prototypes. int yylex_init_extra(YY_EXTRA_TYPE extra, yyscan_t *yyscanner); int yylex_destroy(yyscan_t yyscanner); struct wcsutrn_extra extra; yyscan_t yyscanner; yylex_init_extra(&extra, &yyscanner); int status = wcsutrne_scanner(ctrl, unitstr, err, yyscanner); yylex_destroy(yyscanner); return status; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/getwcstab.c0000644000175100001710000000764600000000000017526 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: getwcstab.c,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *===========================================================================*/ #include #include #include #include "getwcstab.h" //---------------------------------------------------------------------------- int fits_read_wcstab( fitsfile *fptr, int nwtb, wtbarr *wtb, int *status) { int anynul, colnum, hdunum, iwtb, m, naxis, nostat; long *naxes = 0, nelem; wtbarr *wtbp; if (*status) return *status; if (fptr == 0) { return (*status = NULL_INPUT_PTR); } if (nwtb == 0) return 0; // Zero the array pointers. wtbp = wtb; for (iwtb = 0; iwtb < nwtb; iwtb++, wtbp++) { *wtbp->arrayp = 0x0; } // Save HDU number so that we can move back to it later. fits_get_hdu_num(fptr, &hdunum); wtbp = wtb; for (iwtb = 0; iwtb < nwtb; iwtb++, wtbp++) { // Move to the required binary table extension. if (fits_movnam_hdu(fptr, BINARY_TBL, (char *)(wtbp->extnam), wtbp->extver, status)) { goto cleanup; } // Locate the table column. if (fits_get_colnum(fptr, CASEINSEN, (char *)(wtbp->ttype), &colnum, status)) { goto cleanup; } // Get the array dimensions and check for consistency. if (wtbp->ndim < 1) { *status = NEG_AXIS; goto cleanup; } if (!(naxes = calloc(wtbp->ndim, sizeof(long)))) { *status = MEMORY_ALLOCATION; goto cleanup; } if (fits_read_tdim(fptr, colnum, wtbp->ndim, &naxis, naxes, status)) { goto cleanup; } if (naxis != wtbp->ndim) { if (wtbp->kind == 'c' && wtbp->ndim == 2) { // Allow TDIMn to be omitted for degenerate coordinate arrays. naxis = 2; naxes[1] = naxes[0]; naxes[0] = 1; } else { *status = BAD_TDIM; goto cleanup; } } if (wtbp->kind == 'c') { // Coordinate array; calculate the array size. nelem = naxes[0]; for (m = 0; m < naxis-1; m++) { *(wtbp->dimlen + m) = naxes[m+1]; nelem *= naxes[m+1]; } } else { // Index vector; check length. if ((nelem = naxes[0]) != *(wtbp->dimlen)) { // N.B. coordinate array precedes the index vectors. *status = BAD_TDIM; goto cleanup; } } free(naxes); naxes = 0; // Allocate memory for the array. if (!(*wtbp->arrayp = calloc((size_t)nelem, sizeof(double)))) { *status = MEMORY_ALLOCATION; goto cleanup; } // Read the array from the table. if (fits_read_col_dbl(fptr, colnum, wtbp->row, 1L, nelem, 0.0, *wtbp->arrayp, &anynul, status)) { goto cleanup; } } cleanup: // Move back to the starting HDU. nostat = 0; fits_movabs_hdu(fptr, hdunum, 0, &nostat); // Release allocated memory. if (naxes) free(naxes); if (*status) { wtbp = wtb; for (iwtb = 0; iwtb < nwtb; iwtb++, wtbp++) { if (*wtbp->arrayp) free(*wtbp->arrayp); } } return *status; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/getwcstab.h0000644000175100001710000001616100000000000017523 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: getwcstab.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * Summary of the getwcstab routines * --------------------------------- * fits_read_wcstab(), an implementation of a FITS table reading routine for * 'TAB' coordinates, is provided for CFITSIO programmers. It has been * incorporated into CFITSIO as of v3.006 with the definitions in this file, * getwcstab.h, moved into fitsio.h. * * fits_read_wcstab() is not included in the WCSLIB object library but the * source code is presented here as it may be useful for programmers using an * older version of CFITSIO than 3.006, or as a programming template for * non-CFITSIO programmers. * * * fits_read_wcstab() - FITS 'TAB' table reading routine * ---------------------------------------------------- * fits_read_wcstab() extracts arrays from a binary table required in * constructing 'TAB' coordinates. * * Given: * fptr fitsfile * * Pointer to the file handle returned, for example, by * the fits_open_file() routine in CFITSIO. * * nwtb int Number of arrays to be read from the binary table(s). * * Given and returned: * wtb wtbarr * Address of the first element of an array of wtbarr * typedefs. This wtbarr typedef is defined to match the * wtbarr struct defined in WCSLIB. An array of such * structs returned by the WCSLIB function wcstab() as * discussed in the notes below. * * Returned: * status int * CFITSIO status value. * * Function return value: * int CFITSIO status value. * * Notes: * 1: In order to maintain WCSLIB and CFITSIO as independent libraries it is * not permissible for any CFITSIO library code to include WCSLIB header * files, or vice versa. However, the CFITSIO function fits_read_wcstab() * accepts an array of wtbarr structs defined in wcs.h within WCSLIB. * * The problem therefore is to define the wtbarr struct within fitsio.h * without including wcs.h, especially noting that wcs.h will often (but * not always) be included together with fitsio.h in an applications * program that uses fits_read_wcstab(). * * The solution adopted is for WCSLIB to define "struct wtbarr" while * fitsio.h defines "typedef wtbarr" as an untagged struct with identical * members. This allows both wcs.h and fitsio.h to define a wtbarr data * type without conflict by virtue of the fact that structure tags and * typedef names share different name spaces in C; Appendix A, Sect. A11.1 * (p227) of the K&R ANSI edition states that: * = Identifiers fall into several name spaces that do not interfere with = one another; the same identifier may be used for different purposes, = even in the same scope, if the uses are in different name spaces. = These classes are: objects, functions, typedef names, and enum = constants; labels; tags of structures, unions, and enumerations; and = members of each structure or union individually. * * Therefore, declarations within WCSLIB look like * = struct wtbarr *w; * * while within CFITSIO they are simply * = wtbarr *w; * * As suggested by the commonality of the names, these are really the same * aggregate data type. However, in passing a (struct wtbarr *) to * fits_read_wcstab() a cast to (wtbarr *) is formally required. * * When using WCSLIB and CFITSIO together in C++ the situation is * complicated by the fact that typedefs and structs share the same * namespace; C++ Annotated Reference Manual, Sect. 7.1.3 (p105). In that * case the wtbarr struct in wcs.h is renamed by preprocessor macro * substitution to wtbarr_s to distinguish it from the typedef defined in * fitsio.h. However, the scope of this macro substitution is limited to * wcs.h itself and CFITSIO programmer code, whether in C++ or C, should * always use the wtbarr typedef. * * * wtbarr typedef * -------------- * The wtbarr typedef is defined as a struct containing the following members: * * int i * Image axis number. * * int m * Array axis number for index vectors. * * int kind * Character identifying the array type: * - c: coordinate array, * - i: index vector. * * char extnam[72] * EXTNAME identifying the binary table extension. * * int extver * EXTVER identifying the binary table extension. * * int extlev * EXTLEV identifying the binary table extension. * * char ttype[72] * TTYPEn identifying the column of the binary table that contains the * array. * * long row * Table row number. * * int ndim * Expected dimensionality of the array. * * int *dimlen * Address of the first element of an array of int of length ndim into * which the array axis lengths are to be written. * * double **arrayp * Pointer to an array of double which is to be allocated by the user * and into which the array is to be written. * *===========================================================================*/ #ifndef WCSLIB_GETWCSTAB #define WCSLIB_GETWCSTAB #ifdef __cplusplus extern "C" { #endif #include typedef struct { int i; // Image axis number. int m; // Array axis number for index vectors. int kind; // Array type, 'c' (coord) or 'i' (index). char extnam[72]; // EXTNAME of binary table extension. int extver; // EXTVER of binary table extension. int extlev; // EXTLEV of binary table extension. char ttype[72]; // TTYPEn of column containing the array. long row; // Table row number. int ndim; // Expected array dimensionality. int *dimlen; // Where to write the array axis lengths. double **arrayp; // Where to write the address of the array // allocated to store the array. } wtbarr; int fits_read_wcstab(fitsfile *fptr, int nwtb, wtbarr *wtb, int *status); #ifdef __cplusplus } #endif #endif // WCSLIB_GETWCSTAB ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/lin.c0000644000175100001710000007734100000000000016324 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: lin.c,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *===========================================================================*/ #include #include #include #include #include "wcserr.h" #include "wcsprintf.h" #include "lin.h" #include "dis.h" const int LINSET = 137; // Map status return value to message. const char *lin_errmsg[] = { "Success", "Null linprm pointer passed", "Memory allocation failed", "PCi_ja matrix is singular", "Failed to initialize distortion functions", "Distort error", "De-distort error"}; // Map error returns for lower-level routines. const int lin_diserr[] = { LINERR_SUCCESS, // 0: DISERR_SUCCESS LINERR_NULL_POINTER, // 1: DISERR_NULL_POINTER LINERR_MEMORY, // 2: DISERR_MEMORY LINERR_DISTORT_INIT, // 3: DISERR_BAD_PARAM LINERR_DISTORT, // 4: DISERR_DISTORT LINERR_DEDISTORT // 5: DISERR_DEDISTORT }; // Convenience macro for invoking wcserr_set(). #define LIN_ERRMSG(status) WCSERR_SET(status), lin_errmsg[status] //---------------------------------------------------------------------------- int linini(int alloc, int naxis, struct linprm *lin) { return lininit(alloc, naxis, lin, -1); } //---------------------------------------------------------------------------- int lininit(int alloc, int naxis, struct linprm *lin, int ndpmax) { static const char *function = "lininit"; if (lin == 0x0) return LINERR_NULL_POINTER; // Initialize error message handling. if (lin->flag == -1) { lin->err = 0x0; } struct wcserr **err = &(lin->err); wcserr_clear(err); // Initialize memory management. if (lin->flag == -1 || lin->m_flag != LINSET) { if (lin->flag == -1) { lin->dispre = 0x0; lin->disseq = 0x0; lin->tmpcrd = 0x0; } lin->m_flag = 0; lin->m_naxis = 0; lin->m_crpix = 0x0; lin->m_pc = 0x0; lin->m_cdelt = 0x0; lin->m_dispre = 0x0; lin->m_disseq = 0x0; } if (naxis < 0) { return wcserr_set(WCSERR_SET(LINERR_MEMORY), "naxis must not be negative (got %d)", naxis); } // Allocate memory for arrays if required. if (alloc || lin->crpix == 0x0 || lin->pc == 0x0 || lin->cdelt == 0x0) { // Was sufficient allocated previously? if (lin->m_flag == LINSET && lin->m_naxis < naxis) { // No, free it. linfree(lin); } if (alloc || lin->crpix == 0x0) { if (lin->m_crpix) { // In case the caller fiddled with it. lin->crpix = lin->m_crpix; } else { if ((lin->crpix = calloc(naxis, sizeof(double))) == 0x0) { return wcserr_set(LIN_ERRMSG(LINERR_MEMORY)); } lin->m_flag = LINSET; lin->m_naxis = naxis; lin->m_crpix = lin->crpix; } } if (alloc || lin->pc == 0x0) { if (lin->m_pc) { // In case the caller fiddled with it. lin->pc = lin->m_pc; } else { if ((lin->pc = calloc(naxis*naxis, sizeof(double))) == 0x0) { linfree(lin); return wcserr_set(LIN_ERRMSG(LINERR_MEMORY)); } lin->m_flag = LINSET; lin->m_naxis = naxis; lin->m_pc = lin->pc; } } if (alloc || lin->cdelt == 0x0) { if (lin->m_cdelt) { // In case the caller fiddled with it. lin->cdelt = lin->m_cdelt; } else { if ((lin->cdelt = calloc(naxis, sizeof(double))) == 0x0) { linfree(lin); return wcserr_set(LIN_ERRMSG(LINERR_MEMORY)); } lin->m_flag = LINSET; lin->m_naxis = naxis; lin->m_cdelt = lin->cdelt; } } } // Reinitialize disprm structs if we are managing them. if (lin->m_dispre) { disinit(1, naxis, lin->dispre, ndpmax); } if (lin->m_disseq) { disinit(1, naxis, lin->disseq, ndpmax); } // Free memory allocated by linset(). if (lin->flag == LINSET) { if (lin->piximg) free(lin->piximg); if (lin->imgpix) free(lin->imgpix); if (lin->tmpcrd) free(lin->tmpcrd); } lin->piximg = 0x0; lin->imgpix = 0x0; lin->i_naxis = 0; lin->unity = 0; lin->affine = 0; lin->simple = 0; lin->tmpcrd = 0x0; lin->flag = 0; lin->naxis = naxis; // CRPIXja defaults to 0.0. for (int j = 0; j < naxis; j++) { lin->crpix[j] = 0.0; } // PCi_ja defaults to the unit matrix. double *pc = lin->pc; for (int i = 0; i < naxis; i++) { for (int j = 0; j < naxis; j++) { if (j == i) { *pc = 1.0; } else { *pc = 0.0; } pc++; } } // CDELTia defaults to 1.0. for (int i = 0; i < naxis; i++) { lin->cdelt[i] = 1.0; } return 0; } //---------------------------------------------------------------------------- int lindis(int sequence, struct linprm *lin, struct disprm *dis) { return lindist(sequence, lin, dis, -1); } //---------------------------------------------------------------------------- int lindist(int sequence, struct linprm *lin, struct disprm *dis, int ndpmax) { static const char *function = "lindist"; if (lin == 0x0) return LINERR_NULL_POINTER; struct wcserr **err = &(lin->err); if (sequence == 1) { if (lin->m_dispre) { disfree(lin->m_dispre); free(lin->m_dispre); } lin->dispre = dis; lin->m_flag = LINSET; lin->m_dispre = dis; } else if (sequence == 2) { if (lin->m_disseq) { disfree(lin->m_disseq); free(lin->m_disseq); } lin->disseq = dis; lin->m_flag = LINSET; lin->m_disseq = dis; } else { return wcserr_set(WCSERR_SET(LINERR_DISTORT_INIT), "Invalid sequence (%d)", sequence); } if (dis) { int status = disinit(1, lin->naxis, dis, ndpmax); if (status) { return wcserr_set(LIN_ERRMSG(lin_diserr[status])); } } return 0; } //---------------------------------------------------------------------------- int lincpy(int alloc, const struct linprm *linsrc, struct linprm *lindst) { static const char *function = "lincpy"; if (linsrc == 0x0) return LINERR_NULL_POINTER; if (lindst == 0x0) return LINERR_NULL_POINTER; struct wcserr **err = &(lindst->err); int naxis = linsrc->naxis; if (naxis < 1) { return wcserr_set(WCSERR_SET(LINERR_MEMORY), "naxis must be positive (got %d)", naxis); } int status = lininit(alloc, naxis, lindst, 0); if (status) { return status; } const double *srcp = linsrc->crpix; double *dstp = lindst->crpix; for (int j = 0; j < naxis; j++) { *(dstp++) = *(srcp++); } srcp = linsrc->pc; dstp = lindst->pc; for (int i = 0; i < naxis; i++) { for (int j = 0; j < naxis; j++) { *(dstp++) = *(srcp++); } } srcp = linsrc->cdelt; dstp = lindst->cdelt; for (int i = 0; i < naxis; i++) { *(dstp++) = *(srcp++); } if (linsrc->dispre) { if (!lindst->dispre) { if ((lindst->dispre = calloc(1, sizeof(struct disprm))) == 0x0) { return wcserr_set(LIN_ERRMSG(LINERR_MEMORY)); } lindst->m_dispre = lindst->dispre; } if ((status = discpy(alloc, linsrc->dispre, lindst->dispre))) { status = wcserr_set(LIN_ERRMSG(lin_diserr[status])); goto cleanup; } } if (linsrc->disseq) { if (!lindst->disseq) { if ((lindst->disseq = calloc(1, sizeof(struct disprm))) == 0x0) { return wcserr_set(LIN_ERRMSG(LINERR_MEMORY)); } lindst->m_disseq = lindst->disseq; } if ((status = discpy(alloc, linsrc->disseq, lindst->disseq))) { status = wcserr_set(LIN_ERRMSG(lin_diserr[status])); goto cleanup; } } cleanup: if (status) { if (lindst->m_dispre) { disfree(lindst->m_dispre); free(lindst->m_dispre); lindst->m_dispre = 0x0; lindst->dispre = 0x0; } if (lindst->m_disseq) { disfree(lindst->m_disseq); free(lindst->m_disseq); lindst->m_disseq = 0x0; lindst->disseq = 0x0; } } return status; } //---------------------------------------------------------------------------- int linfree(struct linprm *lin) { if (lin == 0x0) return LINERR_NULL_POINTER; if (lin->flag != -1) { // Optionally allocated by lininit() for given parameters. if (lin->m_flag == LINSET) { if (lin->crpix == lin->m_crpix) lin->crpix = 0x0; if (lin->pc == lin->m_pc) lin->pc = 0x0; if (lin->cdelt == lin->m_cdelt) lin->cdelt = 0x0; if (lin->dispre == lin->m_dispre) lin->dispre = 0x0; if (lin->disseq == lin->m_disseq) lin->disseq = 0x0; if (lin->m_crpix) free(lin->m_crpix); if (lin->m_pc) free(lin->m_pc); if (lin->m_cdelt) free(lin->m_cdelt); if (lin->m_dispre) { disfree(lin->m_dispre); free(lin->m_dispre); } if (lin->m_disseq) { disfree(lin->m_disseq); free(lin->m_disseq); } } // Allocated unconditionally by linset(). if (lin->piximg) free(lin->piximg); if (lin->imgpix) free(lin->imgpix); if (lin->tmpcrd) free(lin->tmpcrd); } lin->m_flag = 0; lin->m_naxis = 0; lin->m_crpix = 0x0; lin->m_pc = 0x0; lin->m_cdelt = 0x0; lin->m_dispre = 0x0; lin->m_disseq = 0x0; lin->piximg = 0x0; lin->imgpix = 0x0; lin->i_naxis = 0; lin->tmpcrd = 0x0; wcserr_clear(&(lin->err)); lin->flag = 0; return 0; } //---------------------------------------------------------------------------- int linsize(const struct linprm *lin, int sizes[2]) { if (lin == 0x0) { sizes[0] = sizes[1] = 0; return LINERR_SUCCESS; } // Base size, in bytes. sizes[0] = sizeof(struct linprm); // Total size of allocated memory, in bytes. sizes[1] = 0; int naxis = lin->naxis; // linprm::crpix[]. sizes[1] += naxis * sizeof(double); // linprm::pc[]. sizes[1] += naxis*naxis * sizeof(double); // linprm::cdelt[]. sizes[1] += naxis * sizeof(double); // linprm::dispre[]. int exsizes[2]; dissize(lin->dispre, exsizes); sizes[1] += exsizes[0] + exsizes[1]; // linprm::disseq[]. dissize(lin->disseq, exsizes); sizes[1] += exsizes[0] + exsizes[1]; // linprm::err[]. wcserr_size(lin->err, exsizes); sizes[1] += exsizes[0] + exsizes[1]; // The remaining arrays are allocated unconditionally by linset(). if (lin->flag != LINSET) { return LINERR_SUCCESS; } // linprm::piximg[]. sizes[1] += naxis*naxis * sizeof(double); // linprm::imgpix[]. sizes[1] += naxis*naxis * sizeof(double); // linprm::tmpcrd[]. sizes[1] += naxis * sizeof(double); return LINERR_SUCCESS; } //---------------------------------------------------------------------------- int linprt(const struct linprm *lin) { if (lin == 0x0) return LINERR_NULL_POINTER; if (lin->flag != LINSET) { wcsprintf("The linprm struct is UNINITIALIZED.\n"); return 0; } wcsprintf(" flag: %d\n", lin->flag); // Parameters supplied. wcsprintf(" naxis: %d\n", lin->naxis); WCSPRINTF_PTR(" crpix: ", lin->crpix, "\n"); wcsprintf(" "); for (int j = 0; j < lin->naxis; j++) { wcsprintf(" %#- 11.5g", lin->crpix[j]); } wcsprintf("\n"); int k = 0; WCSPRINTF_PTR(" pc: ", lin->pc, "\n"); for (int i = 0; i < lin->naxis; i++) { wcsprintf(" pc[%d][]:", i); for (int j = 0; j < lin->naxis; j++) { wcsprintf(" %#- 11.5g", lin->pc[k++]); } wcsprintf("\n"); } WCSPRINTF_PTR(" cdelt: ", lin->cdelt, "\n"); wcsprintf(" "); for (int i = 0; i < lin->naxis; i++) { wcsprintf(" %#- 11.5g", lin->cdelt[i]); } wcsprintf("\n"); WCSPRINTF_PTR(" dispre: ", lin->dispre, ""); if (lin->dispre != 0x0) wcsprintf(" (see below)"); wcsprintf("\n"); WCSPRINTF_PTR(" disseq: ", lin->disseq, ""); if (lin->disseq != 0x0) wcsprintf(" (see below)"); wcsprintf("\n"); // Derived values. if (lin->piximg == 0x0) { wcsprintf(" piximg: (nil)\n"); } else { int k = 0; for (int i = 0; i < lin->naxis; i++) { wcsprintf("piximg[%d][]:", i); for (int j = 0; j < lin->naxis; j++) { wcsprintf(" %#- 11.5g", lin->piximg[k++]); } wcsprintf("\n"); } } if (lin->imgpix == 0x0) { wcsprintf(" imgpix: (nil)\n"); } else { int k = 0; for (int i = 0; i < lin->naxis; i++) { wcsprintf("imgpix[%d][]:", i); for (int j = 0; j < lin->naxis; j++) { wcsprintf(" %#- 11.5g", lin->imgpix[k++]); } wcsprintf("\n"); } } wcsprintf(" i_naxis: %d\n", lin->i_naxis); wcsprintf(" unity: %d\n", lin->unity); wcsprintf(" affine: %d\n", lin->affine); wcsprintf(" simple: %d\n", lin->simple); // Error handling. WCSPRINTF_PTR(" err: ", lin->err, "\n"); if (lin->err) { wcserr_prt(lin->err, " "); } // Work arrays. WCSPRINTF_PTR(" tmpcrd: ", lin->tmpcrd, "\n"); // Memory management. wcsprintf(" m_flag: %d\n", lin->m_flag); wcsprintf(" m_naxis: %d\n", lin->m_naxis); WCSPRINTF_PTR(" m_crpix: ", lin->m_crpix, ""); if (lin->m_crpix == lin->crpix) wcsprintf(" (= crpix)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_pc: ", lin->m_pc, ""); if (lin->m_pc == lin->pc) wcsprintf(" (= pc)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_cdelt: ", lin->m_cdelt, ""); if (lin->m_cdelt == lin->cdelt) wcsprintf(" (= cdelt)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_dispre: ", lin->m_dispre, ""); if (lin->dispre && lin->m_dispre == lin->dispre) wcsprintf(" (= dispre)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_disseq: ", lin->m_disseq, ""); if (lin->disseq && lin->m_disseq == lin->disseq) wcsprintf(" (= disseq)"); wcsprintf("\n"); // Distortion parameters (from above). if (lin->dispre) { wcsprintf("\n"); wcsprintf("dispre.*\n"); disprt(lin->dispre); } if (lin->disseq) { wcsprintf("\n"); wcsprintf("disseq.*\n"); disprt(lin->disseq); } return 0; } //---------------------------------------------------------------------------- int linperr(const struct linprm *lin, const char *prefix) { if (lin == 0x0) return LINERR_NULL_POINTER; if (lin->err && wcserr_prt(lin->err, prefix) == 0) { if (lin->dispre) wcserr_prt(lin->dispre->err, prefix); if (lin->disseq) wcserr_prt(lin->disseq->err, prefix); } return 0; } //---------------------------------------------------------------------------- int linset(struct linprm *lin) { static const char *function = "linset"; if (lin == 0x0) return LINERR_NULL_POINTER; struct wcserr **err = &(lin->err); int naxis = lin->naxis; // Check for a unit matrix. lin->unity = 1; double *pc = lin->pc; for (int i = 0; i < naxis; i++) { for (int j = 0; j < naxis; j++) { if (j == i) { if (*(pc++) != 1.0) { lin->unity = 0; break; } } else { if (*(pc++) != 0.0) { lin->unity = 0; break; } } } } if (lin->unity) { if (lin->flag == LINSET) { // Free memory that may have been allocated previously. if (lin->piximg) free(lin->piximg); if (lin->imgpix) free(lin->imgpix); } lin->piximg = 0x0; lin->imgpix = 0x0; lin->i_naxis = 0; // Check cdelt. for (int i = 0; i < naxis; i++) { if (lin->cdelt[i] == 0.0) { return wcserr_set(LIN_ERRMSG(LINERR_SINGULAR_MTX)); } } } else { if (lin->flag != LINSET || lin->i_naxis < naxis) { if (lin->flag == LINSET) { // Free memory that may have been allocated previously. if (lin->piximg) free(lin->piximg); if (lin->imgpix) free(lin->imgpix); } // Allocate memory for internal arrays. if ((lin->piximg = calloc(naxis*naxis, sizeof(double))) == 0x0) { return wcserr_set(LIN_ERRMSG(LINERR_MEMORY)); } if ((lin->imgpix = calloc(naxis*naxis, sizeof(double))) == 0x0) { free(lin->piximg); return wcserr_set(LIN_ERRMSG(LINERR_MEMORY)); } lin->i_naxis = naxis; } // Compute the pixel-to-image transformation matrix. pc = lin->pc; double *piximg = lin->piximg; for (int i = 0; i < naxis; i++) { if (lin->disseq == 0x0) { // No sequent distortions. Incorporate cdelt into piximg. for (int j = 0; j < naxis; j++) { *(piximg++) = lin->cdelt[i] * (*(pc++)); } } else { for (int j = 0; j < naxis; j++) { *(piximg++) = *(pc++); } } } // Compute the image-to-pixel transformation matrix. int status = matinv(naxis, lin->piximg, lin->imgpix); if (status) { return wcserr_set(LIN_ERRMSG(status)); } } // Set up the distortion functions. lin->affine = 1; if (lin->dispre) { int status = disset(lin->dispre); if (status) { return wcserr_set(LIN_ERRMSG(lin_diserr[status])); } lin->affine = 0; } if (lin->disseq) { int status = disset(lin->disseq); if (status) { return wcserr_set(LIN_ERRMSG(lin_diserr[status])); } lin->affine = 0; } lin->simple = lin->unity && lin->affine; // Create work arrays. if (lin->tmpcrd) free(lin->tmpcrd); if ((lin->tmpcrd = calloc(naxis, sizeof(double))) == 0x0) { linfree(lin); return wcserr_set(LIN_ERRMSG(LINERR_MEMORY)); } lin->flag = LINSET; return 0; } //---------------------------------------------------------------------------- int linp2x( struct linprm *lin, int ncoord, int nelem, const double pixcrd[], double imgcrd[]) { static const char *function = "linp2x"; // Initialize. if (lin == 0x0) return LINERR_NULL_POINTER; struct wcserr **err = &(lin->err); if (lin->flag != LINSET) { int status = linset(lin); if (status) { return status; } } int naxis = lin->naxis; // Convert pixel coordinates to intermediate world coordinates. register const double *pix = pixcrd; register double *img = imgcrd; if (lin->simple) { // Handle the simplest and most common case with maximum efficiency. int nelemn = nelem - naxis; for (int k = 0; k < ncoord; k++) { for (int i = 0; i < naxis; i++) { *(img++) = lin->cdelt[i] * (*(pix++) - lin->crpix[i]); } pix += nelemn; img += nelemn; } } else if (lin->affine) { // No distortions. int ndbl = naxis * sizeof(double); int nelemn = nelem - naxis; for (int k = 0; k < ncoord; k++) { memset(img, 0, ndbl); for (int j = 0; j < naxis; j++) { // cdelt will have been incorporated into piximg. register double *piximg = lin->piximg + j; // Column-wise multiplication allows this to be cached. double temp = *(pix++) - lin->crpix[j]; for (int i = 0; i < naxis; i++, piximg += naxis) { img[i] += *piximg * temp; } } pix += nelemn; img += nelem; } } else { // Distortions are present. int ndbl = naxis * sizeof(double); register double *tmp = lin->tmpcrd; for (int k = 0; k < ncoord; k++) { if (lin->dispre) { int status = disp2x(lin->dispre, pix, tmp); if (status) { return wcserr_set(LIN_ERRMSG(lin_diserr[status])); } } else { memcpy(tmp, pix, ndbl); } if (lin->unity) { for (int i = 0; i < naxis; i++) { img[i] = tmp[i] - lin->crpix[i]; } } else { for (int j = 0; j < naxis; j++) { tmp[j] -= lin->crpix[j]; } register double *piximg = lin->piximg; for (int i = 0; i < naxis; i++) { img[i] = 0.0; for (int j = 0; j < naxis; j++) { img[i] += *(piximg++) * tmp[j]; } } } if (lin->disseq) { int status = disp2x(lin->disseq, img, tmp); if (status) { return wcserr_set(LIN_ERRMSG(lin_diserr[status])); } // With sequent distortions, cdelt is not incorporated into piximg... for (int i = 0; i < naxis; i++) { img[i] = lin->cdelt[i] * tmp[i]; } } else if (lin->unity) { // ...nor if the matrix is unity. for (int i = 0; i < naxis; i++) { img[i] *= lin->cdelt[i]; } } pix += nelem; img += nelem; } } return 0; } //---------------------------------------------------------------------------- int linx2p( struct linprm *lin, int ncoord, int nelem, const double imgcrd[], double pixcrd[]) { static const char *function = "linx2p"; // Initialize. if (lin == 0x0) return LINERR_NULL_POINTER; struct wcserr **err = &(lin->err); if (lin->flag != LINSET) { int status = linset(lin); if (status) { return status; } } int naxis = lin->naxis; // Convert intermediate world coordinates to pixel coordinates. register const double *img = imgcrd; register double *pix = pixcrd; if (lin->simple) { // Handle the simplest and most common case with maximum efficiency. int nelemn = nelem - naxis; for (int k = 0; k < ncoord; k++) { for (int j = 0; j < naxis; j++) { *(pix++) = (*(img++) / lin->cdelt[j]) + lin->crpix[j]; } img += nelemn; pix += nelemn; } } else if (lin->affine) { // No distortions. int nelemn = nelem - naxis; for (int k = 0; k < ncoord; k++) { // cdelt will have been incorporated into imgpix. register double *imgpix = lin->imgpix; for (int j = 0; j < naxis; j++) { *pix = 0.0; for (int i = 0; i < naxis; i++) { *pix += *imgpix * img[i]; imgpix++; } *(pix++) += lin->crpix[j]; } img += nelem; pix += nelemn; } } else { // Distortions are present. int ndbl = naxis * sizeof(double); register double *tmp = lin->tmpcrd; for (int k = 0; k < ncoord; k++) { if (lin->disseq) { // With sequent distortions, cdelt is not incorporated into imgpix... for (int i = 0; i < naxis; i++) { tmp[i] = img[i] / lin->cdelt[i]; } int status = disx2p(lin->disseq, tmp, pix); if (status) { return wcserr_set(LIN_ERRMSG(lin_diserr[status])); } memcpy(tmp, pix, ndbl); } else if (lin->unity) { // ...nor if the matrix is unity. for (int i = 0; i < naxis; i++) { tmp[i] = img[i] / lin->cdelt[i]; } } else { // cdelt will have been incorporated into imgpix. memcpy(tmp, img, ndbl); } if (lin->unity) { for (int j = 0; j < naxis; j++) { pix[j] = tmp[j] + lin->crpix[j]; } } else { register double *imgpix = lin->imgpix; for (int j = 0; j < naxis; j++) { pix[j] = lin->crpix[j]; for (int i = 0; i < naxis; i++) { pix[j] += *(imgpix++) * tmp[i]; } } } if (lin->dispre) { memcpy(tmp, pix, ndbl); int status = disx2p(lin->dispre, tmp, pix); if (status) { return wcserr_set(LIN_ERRMSG(lin_diserr[status])); } } img += nelem; pix += nelem; } } return 0; } //---------------------------------------------------------------------------- int linwarp( struct linprm *lin, const double pixblc[], const double pixtrc[], const double pixsamp[], int *nsamp, double maxdis[], double *maxtot, double avgdis[], double *avgtot, double rmsdis[], double *rmstot) { static const char *function = "linwarp"; // Initialize. if (lin == 0x0) return LINERR_NULL_POINTER; struct wcserr **err = &(lin->err); int naxis = lin->naxis; if (nsamp) *nsamp = 0; for (int j = 0; j < naxis; j++) { if (maxdis) maxdis[j] = 0.0; if (avgdis) avgdis[j] = 0.0; if (rmsdis) rmsdis[j] = 0.0; } if (maxtot) *maxtot = 0.0; if (avgtot) *avgtot = 0.0; if (rmstot) *rmstot = 0.0; // Quick return if no distortions. if (lin->affine) return 0; // It's easier if there are no sequent distortions! if (lin->disseq == 0x0) { int status = diswarp(lin->dispre, pixblc, pixtrc, pixsamp, nsamp, maxdis, maxtot, avgdis, avgtot, rmsdis, rmstot); return wcserr_set(LIN_ERRMSG(lin_diserr[status])); } // Make a reference copy of lin without distortions. struct linprm affine; affine.flag = -1; int status = lincpy(1, lin, &affine) || lindist(1, &affine, 0x0, 0) || lindist(2, &affine, 0x0, 0) || linset(&affine); if (status) { return wcserr_set(LIN_ERRMSG(status)); } // Work out increments on each axis. int ncoord = 0; for (int j = 0; j < naxis; j++) { double *pixinc = lin->tmpcrd; double pixspan = pixtrc[j] - (pixblc ? pixblc[j] : 1.0); if (pixsamp == 0x0) { pixinc[j] = 1.0; } else if (pixsamp[j] == 0.0) { pixinc[j] = 1.0; } else if (pixsamp[j] > 0.0) { pixinc[j] = pixsamp[j]; } else if (pixsamp[j] > -1.5) { pixinc[j] = 2.0*pixspan; } else { pixinc[j] = pixspan / ((int)(-pixsamp[j] - 0.5)); } if (j == 0) { // Number of samples on axis 1. ncoord = 1 + (int)((pixspan/pixinc[0]) + 0.5); } } // Allocate memory in bulk for processing the image row by row. double *pix0 = calloc((3*ncoord+4)*naxis, sizeof(double)); if (pix0 == 0x0) { return wcserr_set(LIN_ERRMSG(LINERR_MEMORY)); } // Carve up the allocated memory. double *img = pix0 + naxis*ncoord; double *pix1 = img + naxis*ncoord; double *pixinc = pix1 + naxis*ncoord; double *pixend = pixinc + naxis; double *sumdis = pixend + naxis; double *ssqdis = sumdis + naxis; // Copy tmpcrd since linp2x() will overwrite it. memcpy(pixinc, lin->tmpcrd, naxis*sizeof(double)); // Set up the array of pixel coordinates. for (int j = 0; j < naxis; j++) { pix0[j] = pixblc ? pixblc[j] : 1.0; pixend[j] = pixtrc[j] + 0.5*pixinc[j]; } double *pix0p = pix0 + naxis; for (int i = 1; i < ncoord; i++) { *(pix0p++) = pix0[0] + i*pixinc[0]; for (int j = 1; j < naxis; j++) { *(pix0p++) = pix0[j]; } } // Initialize accumulators. for (int j = 0; j < naxis; j++) { sumdis[j] = 0.0; ssqdis[j] = 0.0; } double sumtot = 0.0; double ssqtot = 0.0; // Loop over N dimensions. int carry = 0; while (carry == 0) { int status; if ((status = linp2x(lin, ncoord, naxis, pix0, img))) { // (Preserve the error message set by linp2x().) goto cleanup; } if ((status = linx2p(&affine, ncoord, naxis, img, pix1))) { // (Preserve the error message set by linx2p().) goto cleanup; } // Accumulate statistics. double *pix0p = pix0; double *pix1p = pix1; for (int i = 0; i < ncoord; i++) { (*nsamp)++; double dssq = 0.0; for (int j = 0; j < naxis; j++) { double dpix = *(pix1p++) - *(pix0p++); double dpx2 = dpix*dpix; sumdis[j] += dpix; ssqdis[j] += dpx2; if (maxdis && (dpix = fabs(dpix)) > maxdis[j]) maxdis[j] = dpix; dssq += dpx2; } double totdis = sqrt(dssq); sumtot += totdis; ssqtot += totdis*totdis; if (maxtot && *maxtot < totdis) *maxtot = totdis; } // Next array of pixel coordinates. for (int j = 1; j < naxis; j++) { pix0[j] += pixinc[j]; if ((carry = (pix0[j] > pixend[j]))) { pix0[j] = pixblc ? pixblc[j] : 1.0; } pix0p = pix0 + naxis + j; for (int i = 1; i < ncoord; i++) { *pix0p = pix0[j]; pix0p += naxis; } if (carry == 0) break; } } // Compute the means and RMSs. for (int j = 0; j < naxis; j++) { ssqdis[j] /= *nsamp; sumdis[j] /= *nsamp; if (avgdis) avgdis[j] = sumdis[j]; if (rmsdis) rmsdis[j] = sqrt(ssqdis[j] - sumdis[j]*sumdis[j]); } ssqtot /= *nsamp; sumtot /= *nsamp; if (avgtot) *avgtot = sumtot; if (rmstot) *rmstot = sqrt(ssqtot - sumtot*sumtot); cleanup: linfree(&affine); free(pix0); return status; } //---------------------------------------------------------------------------- int matinv(int n, const double mat[], double inv[]) { // Allocate memory for internal arrays. int *mxl = calloc(n, sizeof(int)); if (mxl == 0x0) { return LINERR_MEMORY; } int *lxm = calloc(n, sizeof(int)); if (lxm == 0x0) { free(mxl); return LINERR_MEMORY; } double *rowmax = calloc(n, sizeof(double)); if (rowmax == 0x0) { free(mxl); free(lxm); return LINERR_MEMORY; } double *lu = calloc(n*n, sizeof(double)); if (lu == 0x0) { free(mxl); free(lxm); free(rowmax); return LINERR_MEMORY; } // Initialize arrays. register int ij = 0; for (int i = 0; i < n; i++) { // Vector that records row interchanges. mxl[i] = i; rowmax[i] = 0.0; for (int j = 0; j < n; j++, ij++) { double dtemp = fabs(mat[ij]); if (dtemp > rowmax[i]) rowmax[i] = dtemp; lu[ij] = mat[ij]; } // A row of zeroes indicates a singular matrix. if (rowmax[i] == 0.0) { free(mxl); free(lxm); free(rowmax); free(lu); return LINERR_SINGULAR_MTX; } } // Form the LU triangular factorization using scaled partial pivoting. for (int k = 0; k < n; k++) { // Decide whether to pivot. int pivot = k; double colmax = fabs(lu[k*n+k]) / rowmax[k]; for (int i = k+1; i < n; i++) { register int ik = i*n + k; double dtemp = fabs(lu[ik]) / rowmax[i]; if (dtemp > colmax) { colmax = dtemp; pivot = i; } } if (pivot > k) { // We must pivot, interchange the rows of the design matrix. register int kj = k*n; register int pj = pivot*n; for (int j = 0; j < n; j++, pj++, kj++) { double dtemp = lu[pj]; lu[pj] = lu[kj]; lu[kj] = dtemp; } // Amend the vector of row maxima. double dtemp = rowmax[pivot]; rowmax[pivot] = rowmax[k]; rowmax[k] = dtemp; // Record the interchange for later use. int itemp = mxl[pivot]; mxl[pivot] = mxl[k]; mxl[k] = itemp; } // Gaussian elimination. for (int i = k+1; i < n; i++) { register int ik = i*n + k; // Nothing to do if lu[ik] is zero. if (lu[ik] != 0.0) { // Save the scaling factor. lu[ik] /= lu[k*n+k]; // Subtract rows. for (int j = k+1; j < n; j++) { lu[i*n+j] -= lu[ik]*lu[k*n+j]; } } } } // mxl[i] records which row of mat corresponds to row i of lu. // lxm[i] records which row of lu corresponds to row i of mat. for (int i = 0; i < n; i++) { lxm[mxl[i]] = i; } // Determine the inverse matrix. ij = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++, ij++) { inv[ij] = 0.0; } } for (int k = 0; k < n; k++) { inv[lxm[k]*n+k] = 1.0; // Forward substitution. for (int i = lxm[k]+1; i < n; i++) { for (int j = lxm[k]; j < i; j++) { inv[i*n+k] -= lu[i*n+j]*inv[j*n+k]; } } // Backward substitution. for (int i = n-1; i >= 0; i--) { for (int j = i+1; j < n; j++) { inv[i*n+k] -= lu[i*n+j]*inv[j*n+k]; } inv[i*n+k] /= lu[i*n+i]; } } free(mxl); free(lxm); free(rowmax); free(lu); return 0; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/lin.h0000644000175100001710000007051300000000000016323 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: lin.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the lin routines * --------------------------- * Routines in this suite apply the linear transformation defined by the FITS * World Coordinate System (WCS) standard, as described in * = "Representations of world coordinates in FITS", = Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (WCS Paper I) * * These routines are based on the linprm struct which contains all information * needed for the computations. The struct contains some members that must be * set by the user, and others that are maintained by these routines, somewhat * like a C++ class but with no encapsulation. * * Six routines, linini(), lininit(), lindis(), lindist() lincpy(), and * linfree() are provided to manage the linprm struct, linsize() computes its * total size including allocated memory, and linprt() prints its contents. * * linperr() prints the error message(s) (if any) stored in a linprm struct, * and the disprm structs that it may contain. * * A setup routine, linset(), computes intermediate values in the linprm struct * from parameters in it that were supplied by the user. The struct always * needs to be set up by linset() but need not be called explicitly - refer to * the explanation of linprm::flag. * * linp2x() and linx2p() implement the WCS linear transformations. * * An auxiliary routine, linwarp(), computes various measures of the distortion * over a specified range of pixel coordinates. * * An auxiliary matrix inversion routine, matinv(), is included. It uses * LU-triangular factorization with scaled partial pivoting. * * * linini() - Default constructor for the linprm struct * ---------------------------------------------------- * linini() is a thin wrapper on lininit(). It invokes it with ndpmax set * to -1 which causes it to use the value of the global variable NDPMAX. It * is thereby potentially thread-unsafe if NDPMAX is altered dynamically via * disndp(). Use lininit() for a thread-safe alternative in this case. * * * lininit() - Default constructor for the linprm struct * ----------------------------------------------------- * lininit() allocates memory for arrays in a linprm struct and sets all * members of the struct to default values. * * PLEASE NOTE: every linprm struct must be initialized by lininit(), possibly * repeatedly. On the first invokation, and only the first invokation, * linprm::flag must be set to -1 to initialize memory management, regardless * of whether lininit() will actually be used to allocate memory. * * Given: * alloc int If true, allocate memory unconditionally for arrays in * the linprm struct. * * If false, it is assumed that pointers to these arrays * have been set by the user except if they are null * pointers in which case memory will be allocated for * them regardless. (In other words, setting alloc true * saves having to initalize these pointers to zero.) * * naxis int The number of world coordinate axes, used to determine * array sizes. * * Given and returned: * lin struct linprm* * Linear transformation parameters. Note that, in order * to initialize memory management linprm::flag should be * set to -1 when lin is initialized for the first time * (memory leaks may result if it had already been * initialized). * * Given: * ndpmax int The number of DPja or DQia keywords to allocate space * for. If set to -1, the value of the global variable * NDPMAX will be used. This is potentially * thread-unsafe if disndp() is being used dynamically to * alter its value. * * Function return value: * int Status return value: * 0: Success. * 1: Null linprm pointer passed. * 2: Memory allocation failed. * * For returns > 1, a detailed error message is set in * linprm::err if enabled, see wcserr_enable(). * * * lindis() - Assign a distortion to a linprm struct * ------------------------------------------------- * lindis() is a thin wrapper on lindist(). It invokes it with ndpmax set * to -1 which causes the value of the global variable NDPMAX to be used (by * disinit()). It is thereby potentially thread-unsafe if NDPMAX is altered * dynamically via disndp(). Use lindist() for a thread-safe alternative in * this case. * * * lindist() - Assign a distortion to a linprm struct * -------------------------------------------------- * lindist() may be used to assign the address of a disprm struct to * linprm::dispre or linprm::disseq. The linprm struct must already have been * initialized by lininit(). * * The disprm struct must have been allocated from the heap (e.g. using * malloc(), calloc(), etc.). lindist() will immediately initialize it via a * call to disini() using the value of linprm::naxis. Subsequently, it will be * reinitialized by calls to lininit(), and freed by linfree(), neither of * which would happen if the disprm struct was assigned directly. * * If the disprm struct had previously been assigned via lindist(), it will be * freed before reassignment. It is also permissable for a null disprm pointer * to be assigned to disable the distortion correction. * * Given: * sequence int Is it a prior or sequent distortion? * 1: Prior, the assignment is to linprm::dispre. * 2: Sequent, the assignment is to linprm::disseq. * * Anything else is an error. * * Given and returned: * lin struct linprm* * Linear transformation parameters. * * dis struct disprm* * Distortion function parameters. * * Given: * ndpmax int The number of DPja or DQia keywords to allocate space * for. If set to -1, the value of the global variable * NDPMAX will be used. This is potentially * thread-unsafe if disndp() is being used dynamically to * alter its value. * * Function return value: * int Status return value: * 0: Success. * 1: Null linprm pointer passed. * 4: Invalid sequence. * * * lincpy() - Copy routine for the linprm struct * --------------------------------------------- * lincpy() does a deep copy of one linprm struct to another, using lininit() * to allocate memory for its arrays if required. Only the "information to be * provided" part of the struct is copied; a call to linset() is required to * initialize the remainder. * * Given: * alloc int If true, allocate memory for the crpix, pc, and cdelt * arrays in the destination. Otherwise, it is assumed * that pointers to these arrays have been set by the * user except if they are null pointers in which case * memory will be allocated for them regardless. * * linsrc const struct linprm* * Struct to copy from. * * Given and returned: * lindst struct linprm* * Struct to copy to. linprm::flag should be set to -1 * if lindst was not previously initialized (memory leaks * may result if it was previously initialized). * * Function return value: * int Status return value: * 0: Success. * 1: Null linprm pointer passed. * 2: Memory allocation failed. * * For returns > 1, a detailed error message is set in * linprm::err if enabled, see wcserr_enable(). * * * linfree() - Destructor for the linprm struct * -------------------------------------------- * linfree() frees memory allocated for the linprm arrays by lininit() and/or * linset(). lininit() keeps a record of the memory it allocates and linfree() * will only attempt to free this. * * PLEASE NOTE: linfree() must not be invoked on a linprm struct that was not * initialized by lininit(). * * Given: * lin struct linprm* * Linear transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null linprm pointer passed. * * * linsize() - Compute the size of a linprm struct * ----------------------------------------------- * linsize() computes the full size of a linprm struct, including allocated * memory. * * Given: * lin const struct linprm* * Linear transformation parameters. * * If NULL, the base size of the struct and the allocated * size are both set to zero. * * Returned: * sizes int[2] The first element is the base size of the struct as * returned by sizeof(struct linprm). * * The second element is the total size of memory * allocated in the struct, in bytes, assuming that the * allocation was done by linini(). This figure includes * memory allocated for members of constituent structs, * such as linprm::dispre. * * It is not an error for the struct not to have been set * up via linset(), which normally results in additional * memory allocation. * * Function return value: * int Status return value: * 0: Success. * * * linprt() - Print routine for the linprm struct * ---------------------------------------------- * linprt() prints the contents of a linprm struct using wcsprintf(). Mainly * intended for diagnostic purposes. * * Given: * lin const struct linprm* * Linear transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null linprm pointer passed. * * * linperr() - Print error messages from a linprm struct * ----------------------------------------------------- * linperr() prints the error message(s) (if any) stored in a linprm struct, * and the disprm structs that it may contain. If there are no errors then * nothing is printed. It uses wcserr_prt(), q.v. * * Given: * lin const struct linprm* * Coordinate transformation parameters. * * prefix const char * * If non-NULL, each output line will be prefixed with * this string. * * Function return value: * int Status return value: * 0: Success. * 1: Null linprm pointer passed. * * * linset() - Setup routine for the linprm struct * ---------------------------------------------- * linset(), if necessary, allocates memory for the linprm::piximg and * linprm::imgpix arrays and sets up the linprm struct according to information * supplied within it - refer to the explanation of linprm::flag. * * Note that this routine need not be called directly; it will be invoked by * linp2x() and linx2p() if the linprm::flag is anything other than a * predefined magic value. * * Given and returned: * lin struct linprm* * Linear transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null linprm pointer passed. * 2: Memory allocation failed. * 3: PCi_ja matrix is singular. * * For returns > 1, a detailed error message is set in * linprm::err if enabled, see wcserr_enable(). * * * linp2x() - Pixel-to-world linear transformation * ----------------------------------------------- * linp2x() transforms pixel coordinates to intermediate world coordinates. * * Given and returned: * lin struct linprm* * Linear transformation parameters. * * Given: * ncoord, * nelem int The number of coordinates, each of vector length nelem * but containing lin.naxis coordinate elements. * * pixcrd const double[ncoord][nelem] * Array of pixel coordinates. * * Returned: * imgcrd double[ncoord][nelem] * Array of intermediate world coordinates. * * Function return value: * int Status return value: * 0: Success. * 1: Null linprm pointer passed. * 2: Memory allocation failed. * 3: PCi_ja matrix is singular. * * For returns > 1, a detailed error message is set in * linprm::err if enabled, see wcserr_enable(). * * * linx2p() - World-to-pixel linear transformation * ----------------------------------------------- * linx2p() transforms intermediate world coordinates to pixel coordinates. * * Given and returned: * lin struct linprm* * Linear transformation parameters. * * Given: * ncoord, * nelem int The number of coordinates, each of vector length nelem * but containing lin.naxis coordinate elements. * * imgcrd const double[ncoord][nelem] * Array of intermediate world coordinates. * * Returned: * pixcrd double[ncoord][nelem] * Array of pixel coordinates. * * int Status return value: * 0: Success. * 1: Null linprm pointer passed. * 2: Memory allocation failed. * 3: PCi_ja matrix is singular. * * For returns > 1, a detailed error message is set in * linprm::err if enabled, see wcserr_enable(). * * * linwarp() - Compute measures of distortion * ------------------------------------------ * linwarp() computes various measures of the distortion over a specified range * of pixel coordinates. * * All distortion measures are specified as an offset in pixel coordinates, * as given directly by prior distortions. The offset in intermediate pixel * coordinates given by sequent distortions is translated back to pixel * coordinates by applying the inverse of the linear transformation matrix * (PCi_ja or CDi_ja). The difference may be significant if the matrix * introduced a scaling. * * If all distortions are prior, then linwarp() uses diswarp(), q.v. * * Given and returned: * lin struct linprm* * Linear transformation parameters plus distortions. * * Given: * pixblc const double[naxis] * Start of the range of pixel coordinates (i.e. "bottom * left-hand corner" in the conventional FITS image * display orientation). May be specified as a NULL * pointer which is interpreted as (1,1,...). * * pixtrc const double[naxis] * End of the range of pixel coordinates (i.e. "top * right-hand corner" in the conventional FITS image * display orientation). * * pixsamp const double[naxis] * If positive or zero, the increment on the particular * axis, starting at pixblc[]. Zero is interpreted as a * unit increment. pixsamp may also be specified as a * NULL pointer which is interpreted as all zeroes, i.e. * unit increments on all axes. * * If negative, the grid size on the particular axis (the * absolute value being rounded to the nearest integer). * For example, if pixsamp is (-128.0,-128.0,...) then * each axis will be sampled at 128 points between * pixblc[] and pixtrc[] inclusive. Use caution when * using this option on non-square images. * * Returned: * nsamp int* The number of pixel coordinates sampled. * * Can be specified as a NULL pointer if not required. * * maxdis double[naxis] * For each individual distortion function, the * maximum absolute value of the distortion. * * Can be specified as a NULL pointer if not required. * * maxtot double* For the combination of all distortion functions, the * maximum absolute value of the distortion. * * Can be specified as a NULL pointer if not required. * * avgdis double[naxis] * For each individual distortion function, the * mean value of the distortion. * * Can be specified as a NULL pointer if not required. * * avgtot double* For the combination of all distortion functions, the * mean value of the distortion. * * Can be specified as a NULL pointer if not required. * * rmsdis double[naxis] * For each individual distortion function, the * root mean square deviation of the distortion. * * Can be specified as a NULL pointer if not required. * * rmstot double* For the combination of all distortion functions, the * root mean square deviation of the distortion. * * Can be specified as a NULL pointer if not required. * * Function return value: * int Status return value: * 0: Success. * 1: Null linprm pointer passed. * 2: Memory allocation failed. * 3: Invalid parameter. * 4: Distort error. * * * linprm struct - Linear transformation parameters * ------------------------------------------------ * The linprm struct contains all of the information required to perform a * linear transformation. It consists of certain members that must be set by * the user ("given") and others that are set by the WCSLIB routines * ("returned"). * * int flag * (Given and returned) This flag must be set to zero whenever any of the * following members of the linprm struct are set or modified: * * - linprm::naxis (q.v., not normally set by the user), * - linprm::pc, * - linprm::cdelt, * - linprm::dispre. * - linprm::disseq. * * This signals the initialization routine, linset(), to recompute the * returned members of the linprm struct. linset() will reset flag to * indicate that this has been done. * * PLEASE NOTE: flag should be set to -1 when lininit() is called for the * first time for a particular linprm struct in order to initialize memory * management. It must ONLY be used on the first initialization otherwise * memory leaks may result. * * int naxis * (Given or returned) Number of pixel and world coordinate elements. * * If lininit() is used to initialize the linprm struct (as would normally * be the case) then it will set naxis from the value passed to it as a * function argument. The user should not subsequently modify it. * * double *crpix * (Given) Pointer to the first element of an array of double containing * the coordinate reference pixel, CRPIXja. * * It is not necessary to reset the linprm struct (via linset()) when * linprm::crpix is changed. * * double *pc * (Given) Pointer to the first element of the PCi_ja (pixel coordinate) * transformation matrix. The expected order is * = struct linprm lin; = lin.pc = {PC1_1, PC1_2, PC2_1, PC2_2}; * * This may be constructed conveniently from a 2-D array via * = double m[2][2] = {{PC1_1, PC1_2}, = {PC2_1, PC2_2}}; * * which is equivalent to * = double m[2][2]; = m[0][0] = PC1_1; = m[0][1] = PC1_2; = m[1][0] = PC2_1; = m[1][1] = PC2_2; * * The storage order for this 2-D array is the same as for the 1-D array, * whence * = lin.pc = *m; * * would be legitimate. * * double *cdelt * (Given) Pointer to the first element of an array of double containing * the coordinate increments, CDELTia. * * struct disprm *dispre * (Given) Pointer to a disprm struct holding parameters for prior * distortion functions, or a null (0x0) pointer if there are none. * * Function lindist() may be used to assign a disprm pointer to a linprm * struct, allowing it to take control of any memory allocated for it, as * in the following example: * = void add_distortion(struct linprm *lin) = { = struct disprm *dispre; = = dispre = malloc(sizeof(struct disprm)); = dispre->flag = -1; = lindist(1, lin, dispre, ndpmax); = : = (Set up dispre.) = : = = return; = } * * Here, after the distortion function parameters etc. are copied into * dispre, dispre is assigned using lindist() which takes control of the * allocated memory. It will be freed later when linfree() is invoked on * the linprm struct. * * Consider also the following erroneous code: * = void bad_code(struct linprm *lin) = { = struct disprm dispre; = = dispre.flag = -1; = lindist(1, lin, &dispre, ndpmax); // WRONG. = : = = return; = } * * Here, dispre is declared as a struct, rather than a pointer. When the * function returns, dispre will go out of scope and its memory will most * likely be reused, thereby trashing its contents. Later, a segfault will * occur when linfree() tries to free dispre's stale address. * * struct disprm *disseq * (Given) Pointer to a disprm struct holding parameters for sequent * distortion functions, or a null (0x0) pointer if there are none. * * Refer to the comments and examples given for disprm::dispre. * * double *piximg * (Returned) Pointer to the first element of the matrix containing the * product of the CDELTia diagonal matrix and the PCi_ja matrix. * * double *imgpix * (Returned) Pointer to the first element of the inverse of the * linprm::piximg matrix. * * int i_naxis * (Returned) The dimension of linprm::piximg and linprm::imgpix (normally * equal to naxis). * * int unity * (Returned) True if the linear transformation matrix is unity. * * int affine * (Returned) True if there are no distortions. * * int simple * (Returned) True if unity and no distortions. * * struct wcserr *err * (Returned) If enabled, when an error status is returned, this struct * contains detailed information about the error, see wcserr_enable(). * * double *tmpcrd * (For internal use only.) * int m_flag * (For internal use only.) * int m_naxis * (For internal use only.) * double *m_crpix * (For internal use only.) * double *m_pc * (For internal use only.) * double *m_cdelt * (For internal use only.) * struct disprm *m_dispre * (For internal use only.) * struct disprm *m_disseq * (For internal use only.) * * * Global variable: const char *lin_errmsg[] - Status return messages * ------------------------------------------------------------------ * Error messages to match the status value returned from each function. * *===========================================================================*/ #ifndef WCSLIB_LIN #define WCSLIB_LIN #ifdef __cplusplus extern "C" { #endif extern const char *lin_errmsg[]; enum lin_errmsg_enum { LINERR_SUCCESS = 0, // Success. LINERR_NULL_POINTER = 1, // Null linprm pointer passed. LINERR_MEMORY = 2, // Memory allocation failed. LINERR_SINGULAR_MTX = 3, // PCi_ja matrix is singular. LINERR_DISTORT_INIT = 4, // Failed to initialise distortions. LINERR_DISTORT = 5, // Distort error. LINERR_DEDISTORT = 6 // De-distort error. }; struct linprm { // Initialization flag (see the prologue above). //-------------------------------------------------------------------------- int flag; // Set to zero to force initialization. // Parameters to be provided (see the prologue above). //-------------------------------------------------------------------------- int naxis; // The number of axes, given by NAXIS. double *crpix; // CRPIXja keywords for each pixel axis. double *pc; // PCi_ja linear transformation matrix. double *cdelt; // CDELTia keywords for each coord axis. struct disprm *dispre; // Prior distortion parameters, if any. struct disprm *disseq; // Sequent distortion parameters, if any. // Information derived from the parameters supplied. //-------------------------------------------------------------------------- double *piximg; // Product of CDELTia and PCi_ja matrices. double *imgpix; // Inverse of the piximg matrix. int i_naxis; // Dimension of piximg and imgpix. int unity; // True if the PCi_ja matrix is unity. int affine; // True if there are no distortions. int simple; // True if unity and no distortions. // Error handling, if enabled. //-------------------------------------------------------------------------- struct wcserr *err; // Private - the remainder are for internal use. //-------------------------------------------------------------------------- double *tmpcrd; int m_flag, m_naxis; double *m_crpix, *m_pc, *m_cdelt; struct disprm *m_dispre, *m_disseq; }; // Size of the linprm struct in int units, used by the Fortran wrappers. #define LINLEN (sizeof(struct linprm)/sizeof(int)) int linini(int alloc, int naxis, struct linprm *lin); int lininit(int alloc, int naxis, struct linprm *lin, int ndpmax); int lindis(int sequence, struct linprm *lin, struct disprm *dis); int lindist(int sequence, struct linprm *lin, struct disprm *dis, int ndpmax); int lincpy(int alloc, const struct linprm *linsrc, struct linprm *lindst); int linfree(struct linprm *lin); int linsize(const struct linprm *lin, int sizes[2]); int linprt(const struct linprm *lin); int linperr(const struct linprm *lin, const char *prefix); int linset(struct linprm *lin); int linp2x(struct linprm *lin, int ncoord, int nelem, const double pixcrd[], double imgcrd[]); int linx2p(struct linprm *lin, int ncoord, int nelem, const double imgcrd[], double pixcrd[]); int linwarp(struct linprm *lin, const double pixblc[], const double pixtrc[], const double pixsamp[], int *nsamp, double maxdis[], double *maxtot, double avgdis[], double *avgtot, double rmsdis[], double *rmstot); int matinv(int n, const double mat[], double inv[]); // Deprecated. #define linini_errmsg lin_errmsg #define lincpy_errmsg lin_errmsg #define linfree_errmsg lin_errmsg #define linprt_errmsg lin_errmsg #define linset_errmsg lin_errmsg #define linp2x_errmsg lin_errmsg #define linx2p_errmsg lin_errmsg #ifdef __cplusplus } #endif #endif // WCSLIB_LIN ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/log.c0000644000175100001710000000505500000000000016314 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: log.c,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *===========================================================================*/ #include #include "log.h" // Map status return value to message. const char *log_errmsg[] = { "Success", "", "Invalid log-coordinate reference value", "One or more of the x coordinates were invalid", "One or more of the world coordinates were invalid"}; //---------------------------------------------------------------------------- int logx2s( double crval, int nx, int sx, int slogc, const double x[], double logc[], int stat[]) { register int ix; register int *statp; register const double *xp; register double *logcp; if (crval <= 0.0) { return LOGERR_BAD_LOG_REF_VAL; } xp = x; logcp = logc; statp = stat; for (ix = 0; ix < nx; ix++, xp += sx, logcp += slogc) { *logcp = crval * exp((*xp) / crval); *(statp++) = 0; } return 0; } //---------------------------------------------------------------------------- int logs2x( double crval, int nlogc, int slogc, int sx, const double logc[], double x[], int stat[]) { int status; register int ilogc; register int *statp; register const double *logcp; register double *xp; if (crval <= 0.0) { return LOGERR_BAD_LOG_REF_VAL; } xp = x; logcp = logc; statp = stat; status = 0; for (ilogc = 0; ilogc < nlogc; ilogc++, logcp += slogc, xp += sx) { if (*logcp > 0.0) { *xp = crval * log(*logcp / crval); *(statp++) = 0; } else { *(statp++) = 1; status = LOGERR_BAD_WORLD; } } return status; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/log.h0000644000175100001710000001303700000000000016320 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: log.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the log routines * --------------------------- * Routines in this suite implement the part of the FITS World Coordinate * System (WCS) standard that deals with logarithmic coordinates, as described * in * * "Representations of world coordinates in FITS", * Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (WCS Paper I) * * "Representations of spectral coordinates in FITS", * Greisen, E.W., Calabretta, M.R., Valdes, F.G., & Allen, S.L. * 2006, A&A, 446, 747 (WCS Paper III) * * These routines define methods to be used for computing logarithmic world * coordinates from intermediate world coordinates (a linear transformation of * image pixel coordinates), and vice versa. * * logx2s() and logs2x() implement the WCS logarithmic coordinate * transformations. * * Argument checking: * ------------------ * The input log-coordinate values are only checked for values that would * result in floating point exceptions and the same is true for the * log-coordinate reference value. * * Accuracy: * --------- * No warranty is given for the accuracy of these routines (refer to the * copyright notice); intending users must satisfy for themselves their * adequacy for the intended purpose. However, closure effectively to within * double precision rounding error was demonstrated by test routine tlog.c * which accompanies this software. * * * logx2s() - Transform to logarithmic coordinates * ----------------------------------------------- * logx2s() transforms intermediate world coordinates to logarithmic * coordinates. * * Given and returned: * crval double Log-coordinate reference value (CRVALia). * * Given: * nx int Vector length. * * sx int Vector stride. * * slogc int Vector stride. * * x const double[] * Intermediate world coordinates, in SI units. * * Returned: * logc double[] Logarithmic coordinates, in SI units. * * stat int[] Status return value status for each vector element: * 0: Success. * * Function return value: * int Status return value: * 0: Success. * 2: Invalid log-coordinate reference value. * * * logs2x() - Transform logarithmic coordinates * -------------------------------------------- * logs2x() transforms logarithmic world coordinates to intermediate world * coordinates. * * Given and returned: * crval double Log-coordinate reference value (CRVALia). * * Given: * nlogc int Vector length. * * slogc int Vector stride. * * sx int Vector stride. * * logc const double[] * Logarithmic coordinates, in SI units. * * Returned: * x double[] Intermediate world coordinates, in SI units. * * stat int[] Status return value status for each vector element: * 0: Success. * 1: Invalid value of logc. * * Function return value: * int Status return value: * 0: Success. * 2: Invalid log-coordinate reference value. * 4: One or more of the world-coordinate values * are incorrect, as indicated by the stat vector. * * * Global variable: const char *log_errmsg[] - Status return messages * ------------------------------------------------------------------ * Error messages to match the status value returned from each function. * *===========================================================================*/ #ifndef WCSLIB_LOG #define WCSLIB_LOG #ifdef __cplusplus extern "C" { #endif extern const char *log_errmsg[]; enum log_errmsg_enum { LOGERR_SUCCESS = 0, // Success. LOGERR_NULL_POINTER = 1, // Null pointer passed. LOGERR_BAD_LOG_REF_VAL = 2, // Invalid log-coordinate reference value. LOGERR_BAD_X = 3, // One or more of the x coordinates were // invalid. LOGERR_BAD_WORLD = 4 // One or more of the world coordinates were // invalid. }; int logx2s(double crval, int nx, int sx, int slogc, const double x[], double logc[], int stat[]); int logs2x(double crval, int nlogc, int slogc, int sx, const double logc[], double x[], int stat[]); #ifdef __cplusplus } #endif #endif // WCSLIB_LOG ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/prj.c0000644000175100001710000056444600000000000016344 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: prj.c,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *===========================================================================*/ #include #include #include #include #include "wcserr.h" #include "wcsmath.h" #include "wcsprintf.h" #include "wcstrig.h" #include "wcsutil.h" #include "prj.h" // Projection categories. const int ZENITHAL = 1; const int CYLINDRICAL = 2; const int PSEUDOCYLINDRICAL = 3; const int CONVENTIONAL = 4; const int CONIC = 5; const int POLYCONIC = 6; const int QUADCUBE = 7; const int HEALPIX = 8; const char prj_categories[9][32] = {"undefined", "zenithal", "cylindrical", "pseudocylindrical", "conventional", "conic", "polyconic", "quadcube", "HEALPix"}; // Projection codes. const int prj_ncode = 28; const char prj_codes[28][4] = {"AZP", "SZP", "TAN", "STG", "SIN", "ARC", "ZPN", "ZEA", "AIR", "CYP", "CEA", "CAR", "MER", "COP", "COE", "COD", "COO", "SFL", "PAR", "MOL", "AIT", "BON", "PCO", "TSC", "CSC", "QSC", "HPX", "XPH"}; const int AZP = 101; const int SZP = 102; const int TAN = 103; const int STG = 104; const int SIN = 105; const int ARC = 106; const int ZPN = 107; const int ZEA = 108; const int AIR = 109; const int CYP = 201; const int CEA = 202; const int CAR = 203; const int MER = 204; const int SFL = 301; const int PAR = 302; const int MOL = 303; const int AIT = 401; const int COP = 501; const int COE = 502; const int COD = 503; const int COO = 504; const int BON = 601; const int PCO = 602; const int TSC = 701; const int CSC = 702; const int QSC = 703; const int HPX = 801; const int XPH = 802; // Map status return value to message. const char *prj_errmsg[] = { "Success", "Null prjprm pointer passed", "Invalid projection parameters", "One or more of the (x,y) coordinates were invalid", "One or more of the (phi,theta) coordinates were invalid"}; // Convenience macros for generating common error messages. #define PRJERR_BAD_PARAM_SET(function) \ wcserr_set(&(prj->err), PRJERR_BAD_PARAM, function, __FILE__, __LINE__, \ "Invalid parameters for %s projection", prj->name); #define PRJERR_BAD_PIX_SET(function) \ wcserr_set(&(prj->err), PRJERR_BAD_PIX, function, __FILE__, __LINE__, \ "One or more of the (x, y) coordinates were invalid for %s projection", \ prj->name); #define PRJERR_BAD_WORLD_SET(function) \ wcserr_set(&(prj->err), PRJERR_BAD_WORLD, function, __FILE__, __LINE__, \ "One or more of the (lat, lng) coordinates were invalid for " \ "%s projection", prj->name); #define copysign(X, Y) ((Y) < 0.0 ? -fabs(X) : fabs(X)) /*============================================================================ * Generic routines: * * prjini initializes a prjprm struct to default values. * * prjfree frees any memory that may have been allocated to store an error * message in the prjprm struct. * * prjsize computed the size of a prjprm struct. * * prjprt prints the contents of a prjprm struct. * * prjbchk performs bounds checking on the native coordinates returned by the * *x2s() routines. * * prjset invokes the specific initialization routine based on the projection * code in the prjprm struct. * * prjx2s invokes the specific deprojection routine based on the pointer-to- * function stored in the prjprm struct. * * prjs2x invokes the specific projection routine based on the pointer-to- * function stored in the prjprm struct. * *---------------------------------------------------------------------------*/ int prjini(struct prjprm *prj) { register int k; if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = 0; strcpy(prj->code, " "); prj->pv[0] = 0.0; prj->pv[1] = UNDEFINED; prj->pv[2] = UNDEFINED; prj->pv[3] = UNDEFINED; for (k = 4; k < PVN; prj->pv[k++] = 0.0); prj->r0 = 0.0; prj->phi0 = UNDEFINED; prj->theta0 = UNDEFINED; prj->bounds = 7; strcpy(prj->name, "undefined"); for (k = 9; k < 40; prj->name[k++] = '\0'); prj->category = 0; prj->pvrange = 0; prj->simplezen = 0; prj->equiareal = 0; prj->conformal = 0; prj->global = 0; prj->divergent = 0; prj->x0 = 0.0; prj->y0 = 0.0; prj->err = 0x0; prj->padding = 0x0; for (k = 0; k < 10; prj->w[k++] = 0.0); prj->m = 0; prj->n = 0; prj->prjx2s = 0x0; prj->prjs2x = 0x0; return 0; } //---------------------------------------------------------------------------- int prjfree(struct prjprm *prj) { if (prj == 0x0) return PRJERR_NULL_POINTER; wcserr_clear(&(prj->err)); return 0; } //---------------------------------------------------------------------------- int prjsize(const struct prjprm *prj, int sizes[2]) { if (prj == 0x0) { sizes[0] = sizes[1] = 0; return PRJERR_SUCCESS; } // Base size, in bytes. sizes[0] = sizeof(struct prjprm); // Total size of allocated memory, in bytes. sizes[1] = 0; int exsizes[2]; // prjprm::err. wcserr_size(prj->err, exsizes); sizes[1] += exsizes[0] + exsizes[1]; return PRJERR_SUCCESS; } //---------------------------------------------------------------------------- int prjprt(const struct prjprm *prj) { char hext[32]; int i, n; if (prj == 0x0) return PRJERR_NULL_POINTER; wcsprintf(" flag: %d\n", prj->flag); wcsprintf(" code: \"%s\"\n", prj->code); wcsprintf(" r0: %9f\n", prj->r0); wcsprintf(" pv:"); if (prj->pvrange) { n = (prj->pvrange)%100; if (prj->pvrange/100) { wcsprintf(" (0)"); } else { wcsprintf(" %#- 11.5g", prj->pv[0]); n--; } for (i = 1; i <= n; i++) { if (i%5 == 1) { wcsprintf("\n "); } if (undefined(prj->pv[i])) { wcsprintf(" UNDEFINED "); } else { wcsprintf(" %#- 11.5g", prj->pv[i]); } } wcsprintf("\n"); } else { wcsprintf(" (not used)\n"); } if (undefined(prj->phi0)) { wcsprintf(" phi0: UNDEFINED\n"); } else { wcsprintf(" phi0: %9f\n", prj->phi0); } if (undefined(prj->theta0)) { wcsprintf(" theta0: UNDEFINED\n"); } else { wcsprintf(" theta0: %9f\n", prj->theta0); } wcsprintf(" bounds: %d\n", prj->bounds); wcsprintf("\n"); wcsprintf(" name: \"%s\"\n", prj->name); wcsprintf(" category: %d (%s)\n", prj->category, prj_categories[prj->category]); wcsprintf(" pvrange: %d\n", prj->pvrange); wcsprintf(" simplezen: %d\n", prj->simplezen); wcsprintf(" equiareal: %d\n", prj->equiareal); wcsprintf(" conformal: %d\n", prj->conformal); wcsprintf(" global: %d\n", prj->global); wcsprintf(" divergent: %d\n", prj->divergent); wcsprintf(" x0: %f\n", prj->x0); wcsprintf(" y0: %f\n", prj->y0); WCSPRINTF_PTR(" err: ", prj->err, "\n"); if (prj->err) { wcserr_prt(prj->err, " "); } wcsprintf(" w[]:"); for (i = 0; i < 5; i++) { wcsprintf(" %#- 11.5g", prj->w[i]); } wcsprintf("\n "); for (i = 5; i < 10; i++) { wcsprintf(" %#- 11.5g", prj->w[i]); } wcsprintf("\n"); wcsprintf(" m: %d\n", prj->m); wcsprintf(" n: %d\n", prj->n); wcsprintf(" prjx2s: %s\n", wcsutil_fptr2str((void (*)(void))prj->prjx2s, hext)); wcsprintf(" prjs2x: %s\n", wcsutil_fptr2str((void (*)(void))prj->prjs2x, hext)); return 0; } //---------------------------------------------------------------------------- int prjperr(const struct prjprm *prj, const char *prefix) { if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->err) { wcserr_prt(prj->err, prefix); } return 0; } //---------------------------------------------------------------------------- int prjbchk( double tol, int nphi, int ntheta, int spt, double phi[], double theta[], int stat[]) { int status = 0; register int iphi, itheta, *statp; register double *phip, *thetap; phip = phi; thetap = theta; statp = stat; for (itheta = 0; itheta < ntheta; itheta++) { for (iphi = 0; iphi < nphi; iphi++, phip += spt, thetap += spt, statp++) { // Skip values already marked as illegal. if (*statp == 0) { if (*phip < -180.0) { if (*phip < -180.0-tol) { *statp = 1; status = 1; } else { *phip = -180.0; } } else if (180.0 < *phip) { if (180.0+tol < *phip) { *statp = 1; status = 1; } else { *phip = 180.0; } } if (*thetap < -90.0) { if (*thetap < -90.0-tol) { *statp = 1; status = 1; } else { *thetap = -90.0; } } else if (90.0 < *thetap) { if (90.0+tol < *thetap) { *statp = 1; status = 1; } else { *thetap = 90.0; } } } } } return status; } //---------------------------------------------------------------------------- int prjset(struct prjprm *prj) { static const char *function = "prjset"; int status; struct wcserr **err; if (prj == 0x0) return PRJERR_NULL_POINTER; err = &(prj->err); // Invoke the relevant initialization routine. prj->code[3] = '\0'; if (strcmp(prj->code, "AZP") == 0) { status = azpset(prj); } else if (strcmp(prj->code, "SZP") == 0) { status = szpset(prj); } else if (strcmp(prj->code, "TAN") == 0) { status = tanset(prj); } else if (strcmp(prj->code, "STG") == 0) { status = stgset(prj); } else if (strcmp(prj->code, "SIN") == 0) { status = sinset(prj); } else if (strcmp(prj->code, "ARC") == 0) { status = arcset(prj); } else if (strcmp(prj->code, "ZPN") == 0) { status = zpnset(prj); } else if (strcmp(prj->code, "ZEA") == 0) { status = zeaset(prj); } else if (strcmp(prj->code, "AIR") == 0) { status = airset(prj); } else if (strcmp(prj->code, "CYP") == 0) { status = cypset(prj); } else if (strcmp(prj->code, "CEA") == 0) { status = ceaset(prj); } else if (strcmp(prj->code, "CAR") == 0) { status = carset(prj); } else if (strcmp(prj->code, "MER") == 0) { status = merset(prj); } else if (strcmp(prj->code, "SFL") == 0) { status = sflset(prj); } else if (strcmp(prj->code, "PAR") == 0) { status = parset(prj); } else if (strcmp(prj->code, "MOL") == 0) { status = molset(prj); } else if (strcmp(prj->code, "AIT") == 0) { status = aitset(prj); } else if (strcmp(prj->code, "COP") == 0) { status = copset(prj); } else if (strcmp(prj->code, "COE") == 0) { status = coeset(prj); } else if (strcmp(prj->code, "COD") == 0) { status = codset(prj); } else if (strcmp(prj->code, "COO") == 0) { status = cooset(prj); } else if (strcmp(prj->code, "BON") == 0) { status = bonset(prj); } else if (strcmp(prj->code, "PCO") == 0) { status = pcoset(prj); } else if (strcmp(prj->code, "TSC") == 0) { status = tscset(prj); } else if (strcmp(prj->code, "CSC") == 0) { status = cscset(prj); } else if (strcmp(prj->code, "QSC") == 0) { status = qscset(prj); } else if (strcmp(prj->code, "HPX") == 0) { status = hpxset(prj); } else if (strcmp(prj->code, "XPH") == 0) { status = xphset(prj); } else { // Unrecognized projection code. status = wcserr_set(WCSERR_SET(PRJERR_BAD_PARAM), "Unrecognized projection code '%s'", prj->code); } return status; } //---------------------------------------------------------------------------- int prjx2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int status; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag == 0) { if ((status = prjset(prj))) return status; } return prj->prjx2s(prj, nx, ny, sxy, spt, x, y, phi, theta, stat); } //---------------------------------------------------------------------------- int prjs2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int status; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag == 0) { if ((status = prjset(prj))) return status; } return prj->prjs2x(prj, nphi, ntheta, spt, sxy, phi, theta, x, y, stat); } /*============================================================================ * Internal helper routine used by the *set() routines - not intended for * outside use. It forces (x,y) = (0,0) at (phi0,theta0). *---------------------------------------------------------------------------*/ int prjoff( struct prjprm *prj, const double phi0, const double theta0) { int stat; double x0, y0; if (prj == 0x0) return PRJERR_NULL_POINTER; prj->x0 = 0.0; prj->y0 = 0.0; if (undefined(prj->phi0) || undefined(prj->theta0)) { // Set both to the projection-specific default if either undefined. prj->phi0 = phi0; prj->theta0 = theta0; } else { if (prj->prjs2x(prj, 1, 1, 1, 1, &(prj->phi0), &(prj->theta0), &x0, &y0, &stat)) { return PRJERR_BAD_PARAM_SET("prjoff"); } prj->x0 = x0; prj->y0 = y0; } return 0; } /*============================================================================ * AZP: zenithal/azimuthal perspective projection. * * Given: * prj->pv[1] Distance parameter, mu in units of r0. * prj->pv[2] Tilt angle, gamma in degrees. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to 0.0 if undefined. * prj->theta0 Reset to 90.0 if undefined. * * Returned: * prj->flag AZP * prj->code "AZP" * prj->x0 Offset in x. * prj->y0 Offset in y. * prj->w[0] r0*(mu+1) * prj->w[1] tan(gamma) * prj->w[2] sec(gamma) * prj->w[3] cos(gamma) * prj->w[4] sin(gamma) * prj->w[5] asin(-1/mu) for |mu| >= 1, -90 otherwise * prj->w[6] mu*cos(gamma) * prj->w[7] 1 if |mu*cos(gamma)| < 1, 0 otherwise * prj->prjx2s Pointer to azpx2s(). * prj->prjs2x Pointer to azps2x(). *===========================================================================*/ int azpset(struct prjprm *prj) { if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = AZP; strcpy(prj->code, "AZP"); if (undefined(prj->pv[1])) prj->pv[1] = 0.0; if (undefined(prj->pv[2])) prj->pv[2] = 0.0; if (prj->r0 == 0.0) prj->r0 = R2D; strcpy(prj->name, "zenithal/azimuthal perspective"); prj->category = ZENITHAL; prj->pvrange = 102; prj->simplezen = prj->pv[2] == 0.0; prj->equiareal = 0; prj->conformal = 0; prj->global = 0; prj->divergent = prj->pv[1] <= 1.0; prj->w[0] = prj->r0*(prj->pv[1] + 1.0); if (prj->w[0] == 0.0) { return PRJERR_BAD_PARAM_SET("azpset"); } prj->w[3] = cosd(prj->pv[2]); if (prj->w[3] == 0.0) { return PRJERR_BAD_PARAM_SET("azpset"); } prj->w[2] = 1.0/prj->w[3]; prj->w[4] = sind(prj->pv[2]); prj->w[1] = prj->w[4] / prj->w[3]; if (fabs(prj->pv[1]) > 1.0) { prj->w[5] = asind(-1.0/prj->pv[1]); } else { prj->w[5] = -90.0; } prj->w[6] = prj->pv[1] * prj->w[3]; prj->w[7] = (fabs(prj->w[6]) < 1.0) ? 1.0 : 0.0; prj->prjx2s = azpx2s; prj->prjs2x = azps2x; return prjoff(prj, 0.0, 90.0); } //---------------------------------------------------------------------------- int azpx2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int mx, my, rowlen, rowoff, status; double a, b, q, r, s, t, xj, yj, yc, yc2; const double tol = 1.0e-13; register int ix, iy, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != AZP) { if ((status = azpset(prj))) return status; } if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { xj = *xp + prj->x0; phip = phi + rowoff; for (iy = 0; iy < my; iy++) { *phip = xj; phip += rowlen; } } // Do y dependence. yp = y; phip = phi; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { yj = *yp + prj->y0; yc = yj*prj->w[3]; yc2 = yc*yc; q = prj->w[0] + yj*prj->w[4]; for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { xj = *phip; r = sqrt(xj*xj + yc2); if (r == 0.0) { *phip = 0.0; *thetap = 90.0; *(statp++) = 0; } else { *phip = atan2d(xj, -yc); s = r / q; t = s*prj->pv[1]/sqrt(s*s + 1.0); s = atan2d(1.0, s); if (fabs(t) > 1.0) { if (fabs(t) > 1.0+tol) { *thetap = 0.0; *(statp++) = 1; if (!status) status = PRJERR_BAD_PIX_SET("azpx2s"); continue; } t = copysign(90.0, t); } else { t = asind(t); } a = s - t; b = s + t + 180.0; if (a > 90.0) a -= 360.0; if (b > 90.0) b -= 360.0; *thetap = (a > b) ? a : b; *(statp++) = 0; } } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-13, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("azpx2s"); } return status; } //---------------------------------------------------------------------------- int azps2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int mphi, mtheta, rowlen, rowoff, status; double a, b, cosphi, costhe, r, s, sinphi, sinthe, t; register int iphi, itheta, istat, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != AZP) { if ((status = azpset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } status = 0; // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { sincosd(*phip, &sinphi, &cosphi); xp = x + rowoff; yp = y + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = sinphi; *yp = cosphi; xp += rowlen; yp += rowlen; } } // Do theta dependence. thetap = theta; xp = x; yp = y; statp = stat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { sincosd(*thetap, &sinthe, &costhe); for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { s = prj->w[1]*(*yp); t = (prj->pv[1] + sinthe) + costhe*s; if (t == 0.0) { *xp = 0.0; *yp = 0.0; *(statp++) = 1; if (!status) status = PRJERR_BAD_WORLD_SET("azps2x"); } else { r = prj->w[0]*costhe/t; // Bounds checking. istat = 0; if (prj->bounds&1) { if (*thetap < prj->w[5]) { // Overlap. istat = 1; if (!status) status = PRJERR_BAD_WORLD_SET("azps2x"); } else if (prj->w[7] > 0.0) { // Divergence. t = prj->pv[1] / sqrt(1.0 + s*s); if (fabs(t) <= 1.0) { s = atand(-s); t = asind(t); a = s - t; b = s + t + 180.0; if (a > 90.0) a -= 360.0; if (b > 90.0) b -= 360.0; if (*thetap < ((a > b) ? a : b)) { istat = 1; if (!status) status = PRJERR_BAD_WORLD_SET("azps2x"); } } } } *xp = r*(*xp) - prj->x0; *yp = -r*(*yp)*prj->w[2] - prj->y0; *(statp++) = istat; } } } return status; } /*============================================================================ * SZP: slant zenithal perspective projection. * * Given: * prj->pv[1] Distance of the point of projection from the centre of the * generating sphere, mu in units of r0. * prj->pv[2] Native longitude, phi_c, and ... * prj->pv[3] Native latitude, theta_c, on the planewards side of the * intersection of the line through the point of projection * and the centre of the generating sphere, phi_c in degrees. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to 0.0 if undefined. * prj->theta0 Reset to 90.0 if undefined. * * Returned: * prj->flag SZP * prj->code "SZP" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->w[0] 1/r0 * prj->w[1] xp = -mu*cos(theta_c)*sin(phi_c) * prj->w[2] yp = mu*cos(theta_c)*cos(phi_c) * prj->w[3] zp = mu*sin(theta_c) + 1 * prj->w[4] r0*xp * prj->w[5] r0*yp * prj->w[6] r0*zp * prj->w[7] (zp - 1)^2 * prj->w[8] asin(1-zp) if |1 - zp| < 1, -90 otherwise * prj->prjx2s Pointer to szpx2s(). * prj->prjs2x Pointer to szps2x(). *===========================================================================*/ int szpset(struct prjprm *prj) { if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = SZP; strcpy(prj->code, "SZP"); if (undefined(prj->pv[1])) prj->pv[1] = 0.0; if (undefined(prj->pv[2])) prj->pv[2] = 0.0; if (undefined(prj->pv[3])) prj->pv[3] = 90.0; if (prj->r0 == 0.0) prj->r0 = R2D; strcpy(prj->name, "slant zenithal perspective"); prj->category = ZENITHAL; prj->pvrange = 103; prj->simplezen = prj->pv[3] == 90.0; prj->equiareal = 0; prj->conformal = 0; prj->global = 0; prj->divergent = prj->pv[1] <= 1.0; prj->w[0] = 1.0/prj->r0; prj->w[3] = prj->pv[1] * sind(prj->pv[3]) + 1.0; if (prj->w[3] == 0.0) { return PRJERR_BAD_PARAM_SET("szpset"); } prj->w[1] = -prj->pv[1] * cosd(prj->pv[3]) * sind(prj->pv[2]); prj->w[2] = prj->pv[1] * cosd(prj->pv[3]) * cosd(prj->pv[2]); prj->w[4] = prj->r0 * prj->w[1]; prj->w[5] = prj->r0 * prj->w[2]; prj->w[6] = prj->r0 * prj->w[3]; prj->w[7] = (prj->w[3] - 1.0) * prj->w[3] - 1.0; if (fabs(prj->w[3] - 1.0) < 1.0) { prj->w[8] = asind(1.0 - prj->w[3]); } else { prj->w[8] = -90.0; } prj->prjx2s = szpx2s; prj->prjs2x = szps2x; return prjoff(prj, 0.0, 90.0); } //---------------------------------------------------------------------------- int szpx2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int mx, my, rowlen, rowoff, status; double a, b, c, d, r2, sinth1, sinth2, sinthe, t, x1, xr, xy, y1, yr, z; const double tol = 1.0e-13; register int ix, iy, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != SZP) { if ((status = szpset(prj))) return status; } if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { xr = (*xp + prj->x0)*prj->w[0]; phip = phi + rowoff; for (iy = 0; iy < my; iy++) { *phip = xr; phip += rowlen; } } // Do y dependence. yp = y; phip = phi; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { yr = (*yp + prj->y0)*prj->w[0]; for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { xr = *phip; r2 = xr*xr + yr*yr; x1 = (xr - prj->w[1])/prj->w[3]; y1 = (yr - prj->w[2])/prj->w[3]; xy = xr*x1 + yr*y1; if (r2 < 1.0e-10) { // Use small angle formula. z = r2/2.0; *thetap = 90.0 - R2D*sqrt(r2/(1.0 + xy)); } else { t = x1*x1 + y1*y1; a = t + 1.0; b = xy - t; c = r2 - xy - xy + t - 1.0; d = b*b - a*c; // Check for a solution. if (d < 0.0) { *phip = 0.0; *thetap = 0.0; *(statp++) = 1; if (!status) status = PRJERR_BAD_PIX_SET("szpx2s"); continue; } d = sqrt(d); // Choose solution closest to pole. sinth1 = (-b + d)/a; sinth2 = (-b - d)/a; sinthe = (sinth1 > sinth2) ? sinth1 : sinth2; if (sinthe > 1.0) { if (sinthe-1.0 < tol) { sinthe = 1.0; } else { sinthe = (sinth1 < sinth2) ? sinth1 : sinth2; } } if (sinthe < -1.0) { if (sinthe+1.0 > -tol) { sinthe = -1.0; } } if (sinthe > 1.0 || sinthe < -1.0) { *phip = 0.0; *thetap = 0.0; *(statp++) = 1; if (!status) status = PRJERR_BAD_PIX_SET("szpx2s"); continue; } *thetap = asind(sinthe); z = 1.0 - sinthe; } *phip = atan2d(xr - x1*z, -(yr - y1*z)); *(statp++) = 0; } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-13, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("szpx2s"); } return status; } //---------------------------------------------------------------------------- int szps2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int mphi, mtheta, rowlen, rowoff, status; double a, b, cosphi, r, s, sinphi, t, u, v; register int iphi, itheta, istat, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != SZP) { if ((status = szpset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } status = 0; // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { sincosd(*phip, &sinphi, &cosphi); xp = x + rowoff; yp = y + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = sinphi; *yp = cosphi; xp += rowlen; yp += rowlen; } } // Do theta dependence. thetap = theta; xp = x; yp = y; statp = stat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { s = 1.0 - sind(*thetap); t = prj->w[3] - s; if (t == 0.0) { for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { *xp = 0.0; *yp = 0.0; *(statp++) = 1; } if (!status) status = PRJERR_BAD_WORLD_SET("szps2x"); } else { r = prj->w[6]*cosd(*thetap)/t; u = prj->w[4]*s/t + prj->x0; v = prj->w[5]*s/t + prj->y0; for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { // Bounds checking. istat = 0; if (prj->bounds&1) { if (*thetap < prj->w[8]) { // Divergence. istat = 1; if (!status) status = PRJERR_BAD_WORLD_SET("szps2x"); } else if (fabs(prj->pv[1]) > 1.0) { // Overlap. s = prj->w[1]*(*xp) - prj->w[2]*(*yp); t = 1.0/sqrt(prj->w[7] + s*s); if (fabs(t) <= 1.0) { s = atan2d(s, prj->w[3] - 1.0); t = asind(t); a = s - t; b = s + t + 180.0; if (a > 90.0) a -= 360.0; if (b > 90.0) b -= 360.0; if (*thetap < ((a > b) ? a : b)) { istat = 1; if (!status) status = PRJERR_BAD_WORLD_SET("szps2x"); } } } } *xp = r*(*xp) - u; *yp = -r*(*yp) - v; *(statp++) = istat; } } } return status; } /*============================================================================ * TAN: gnomonic projection. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to 0.0 if undefined. * prj->theta0 Reset to 90.0 if undefined. * * Returned: * prj->flag TAN * prj->code "TAN" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->prjx2s Pointer to tanx2s(). * prj->prjs2x Pointer to tans2x(). *===========================================================================*/ int tanset(struct prjprm *prj) { if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = TAN; strcpy(prj->code, "TAN"); if (prj->r0 == 0.0) prj->r0 = R2D; strcpy(prj->name, "gnomonic"); prj->category = ZENITHAL; prj->pvrange = 0; prj->simplezen = 1; prj->equiareal = 0; prj->conformal = 0; prj->global = 0; prj->divergent = 1; prj->prjx2s = tanx2s; prj->prjs2x = tans2x; return prjoff(prj, 0.0, 90.0); } //---------------------------------------------------------------------------- int tanx2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int mx, my, rowlen, rowoff, status; double r, xj, yj, yj2; register int ix, iy, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != TAN) { if ((status = tanset(prj))) return status; } if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { xj = *xp + prj->x0; phip = phi + rowoff; for (iy = 0; iy < my; iy++) { *phip = xj; phip += rowlen; } } // Do y dependence. yp = y; phip = phi; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { yj = *yp + prj->y0; yj2 = yj*yj; for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { xj = *phip; r = sqrt(xj*xj + yj2); if (r == 0.0) { *phip = 0.0; } else { *phip = atan2d(xj, -yj); } *thetap = atan2d(prj->r0, r); *(statp++) = 0; } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-13, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("tanx2s"); } return status; } //---------------------------------------------------------------------------- int tans2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int mphi, mtheta, rowlen, rowoff, status; double cosphi, r, s, sinphi; register int iphi, itheta, istat, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != TAN) { if ((status = tanset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } status = 0; // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { sincosd(*phip, &sinphi, &cosphi); xp = x + rowoff; yp = y + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = sinphi; *yp = cosphi; xp += rowlen; yp += rowlen; } } // Do theta dependence. thetap = theta; xp = x; yp = y; statp = stat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { s = sind(*thetap); if (s == 0.0) { for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { *xp = 0.0; *yp = 0.0; *(statp++) = 1; } if (!status) status = PRJERR_BAD_WORLD_SET("tans2x"); } else { r = prj->r0*cosd(*thetap)/s; // Bounds checking. istat = 0; if (prj->bounds&1) { if (s < 0.0) { istat = 1; if (!status) status = PRJERR_BAD_WORLD_SET("tans2x"); } } for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { *xp = r*(*xp) - prj->x0; *yp = -r*(*yp) - prj->y0; *(statp++) = istat; } } } return status; } /*============================================================================ * STG: stereographic projection. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to 0.0 if undefined. * prj->theta0 Reset to 90.0 if undefined. * * Returned: * prj->flag STG * prj->code "STG" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->w[0] 2*r0 * prj->w[1] 1/(2*r0) * prj->prjx2s Pointer to stgx2s(). * prj->prjs2x Pointer to stgs2x(). *===========================================================================*/ int stgset(struct prjprm *prj) { if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = STG; strcpy(prj->code, "STG"); strcpy(prj->name, "stereographic"); prj->category = ZENITHAL; prj->pvrange = 0; prj->simplezen = 1; prj->equiareal = 0; prj->conformal = 1; prj->global = 0; prj->divergent = 1; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 360.0/PI; prj->w[1] = PI/360.0; } else { prj->w[0] = 2.0*prj->r0; prj->w[1] = 1.0/prj->w[0]; } prj->prjx2s = stgx2s; prj->prjs2x = stgs2x; return prjoff(prj, 0.0, 90.0); } //---------------------------------------------------------------------------- int stgx2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int mx, my, rowlen, rowoff, status; double r, xj, yj, yj2; register int ix, iy, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != STG) { if ((status = stgset(prj))) return status; } if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { xj = *xp + prj->x0; phip = phi + rowoff; for (iy = 0; iy < my; iy++) { *phip = xj; phip += rowlen; } } // Do y dependence. yp = y; phip = phi; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { yj = *yp + prj->y0; yj2 = yj*yj; for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { xj = *phip; r = sqrt(xj*xj + yj2); if (r == 0.0) { *phip = 0.0; } else { *phip = atan2d(xj, -yj); } *thetap = 90.0 - 2.0*atand(r*prj->w[1]); *(statp++) = 0; } } return 0; } //---------------------------------------------------------------------------- int stgs2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int mphi, mtheta, rowlen, rowoff, status; double cosphi, r, s, sinphi; register int iphi, itheta, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != STG) { if ((status = stgset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } status = 0; // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { sincosd(*phip, &sinphi, &cosphi); xp = x + rowoff; yp = y + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = sinphi; *yp = cosphi; xp += rowlen; yp += rowlen; } } // Do theta dependence. thetap = theta; xp = x; yp = y; statp = stat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { s = 1.0 + sind(*thetap); if (s == 0.0) { for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { *xp = 0.0; *yp = 0.0; *(statp++) = 1; } if (!status) status = PRJERR_BAD_WORLD_SET("stgs2x"); } else { r = prj->w[0]*cosd(*thetap)/s; for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { *xp = r*(*xp) - prj->x0; *yp = -r*(*yp) - prj->y0; *(statp++) = 0; } } } return status; } /*============================================================================ * SIN: orthographic/synthesis projection. * * Given: * prj->pv[1:2] Obliqueness parameters, xi and eta. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to 0.0 if undefined. * prj->theta0 Reset to 90.0 if undefined. * * Returned: * prj->flag SIN * prj->code "SIN" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->w[0] 1/r0 * prj->w[1] xi**2 + eta**2 * prj->w[2] xi**2 + eta**2 + 1 * prj->w[3] xi**2 + eta**2 - 1 * prj->prjx2s Pointer to sinx2s(). * prj->prjs2x Pointer to sins2x(). *===========================================================================*/ int sinset(struct prjprm *prj) { if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = SIN; strcpy(prj->code, "SIN"); if (undefined(prj->pv[1])) prj->pv[1] = 0.0; if (undefined(prj->pv[2])) prj->pv[2] = 0.0; if (prj->r0 == 0.0) prj->r0 = R2D; strcpy(prj->name, "orthographic/synthesis"); prj->category = ZENITHAL; prj->pvrange = 102; prj->simplezen = (prj->pv[1] == 0.0 && prj->pv[2] == 0.0); prj->equiareal = 0; prj->conformal = 0; prj->global = 0; prj->divergent = 0; prj->w[0] = 1.0/prj->r0; prj->w[1] = prj->pv[1]*prj->pv[1] + prj->pv[2]*prj->pv[2]; prj->w[2] = prj->w[1] + 1.0; prj->w[3] = prj->w[1] - 1.0; prj->prjx2s = sinx2s; prj->prjs2x = sins2x; return prjoff(prj, 0.0, 90.0); } //---------------------------------------------------------------------------- int sinx2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int mx, my, rowlen, rowoff, status; const double tol = 1.0e-13; double a, b, c, d, eta, r2, sinth1, sinth2, sinthe, x0, xi, x1, xy, y0, y02, y1, z; register int ix, iy, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != SIN) { if ((status = sinset(prj))) return status; } xi = prj->pv[1]; eta = prj->pv[2]; if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { x0 = (*xp + prj->x0)*prj->w[0]; phip = phi + rowoff; for (iy = 0; iy < my; iy++) { *phip = x0; phip += rowlen; } } // Do y dependence. yp = y; phip = phi; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { y0 = (*yp + prj->y0)*prj->w[0]; y02 = y0*y0; for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { // Compute intermediaries. x0 = *phip; r2 = x0*x0 + y02; if (prj->w[1] == 0.0) { // Orthographic projection. if (r2 != 0.0) { *phip = atan2d(x0, -y0); } else { *phip = 0.0; } if (r2 < 0.5) { *thetap = acosd(sqrt(r2)); } else if (r2 <= 1.0) { *thetap = asind(sqrt(1.0 - r2)); } else { *(statp++) = 1; if (!status) status = PRJERR_BAD_PIX_SET("sinx2s") continue; } } else { // "Synthesis" projection. xy = x0*xi + y0*eta; if (r2 < 1.0e-10) { // Use small angle formula. z = r2/2.0; *thetap = 90.0 - R2D*sqrt(r2/(1.0 + xy)); } else { a = prj->w[2]; b = xy - prj->w[1]; c = r2 - xy - xy + prj->w[3]; d = b*b - a*c; // Check for a solution. if (d < 0.0) { *phip = 0.0; *thetap = 0.0; *(statp++) = 1; if (!status) status = PRJERR_BAD_PIX_SET("sinx2s") continue; } d = sqrt(d); // Choose solution closest to pole. sinth1 = (-b + d)/a; sinth2 = (-b - d)/a; sinthe = (sinth1 > sinth2) ? sinth1 : sinth2; if (sinthe > 1.0) { if (sinthe-1.0 < tol) { sinthe = 1.0; } else { sinthe = (sinth1 < sinth2) ? sinth1 : sinth2; } } if (sinthe < -1.0) { if (sinthe+1.0 > -tol) { sinthe = -1.0; } } if (sinthe > 1.0 || sinthe < -1.0) { *phip = 0.0; *thetap = 0.0; *(statp++) = 1; if (!status) status = PRJERR_BAD_PIX_SET("sinx2s") continue; } *thetap = asind(sinthe); z = 1.0 - sinthe; } x1 = -y0 + eta*z; y1 = x0 - xi*z; if (x1 == 0.0 && y1 == 0.0) { *phip = 0.0; } else { *phip = atan2d(y1,x1); } } *(statp++) = 0; } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-13, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("sinx2s"); } return status; } //---------------------------------------------------------------------------- int sins2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int mphi, mtheta, rowlen, rowoff, status; double cosphi, costhe, sinphi, r, t, z, z1, z2; register int iphi, itheta, istat, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != SIN) { if ((status = sinset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } status = 0; // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { sincosd(*phip, &sinphi, &cosphi); xp = x + rowoff; yp = y + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = sinphi; *yp = cosphi; xp += rowlen; yp += rowlen; } } // Do theta dependence. thetap = theta; xp = x; yp = y; statp = stat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { t = (90.0 - fabs(*thetap))*D2R; if (t < 1.0e-5) { if (*thetap > 0.0) { z = t*t/2.0; } else { z = 2.0 - t*t/2.0; } costhe = t; } else { z = 1.0 - sind(*thetap); costhe = cosd(*thetap); } r = prj->r0*costhe; if (prj->w[1] == 0.0) { // Orthographic projection. istat = 0; if (prj->bounds&1) { if (*thetap < 0.0) { istat = 1; if (!status) status = PRJERR_BAD_WORLD_SET("sins2x"); } } for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { *xp = r*(*xp) - prj->x0; *yp = -r*(*yp) - prj->y0; *(statp++) = istat; } } else { // "Synthesis" projection. z *= prj->r0; z1 = prj->pv[1]*z - prj->x0; z2 = prj->pv[2]*z - prj->y0; for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { istat = 0; if (prj->bounds&1) { t = -atand(prj->pv[1]*(*xp) - prj->pv[2]*(*yp)); if (*thetap < t) { istat = 1; if (!status) status = PRJERR_BAD_WORLD_SET("sins2x"); } } *xp = r*(*xp) + z1; *yp = -r*(*yp) + z2; *(statp++) = istat; } } } return status; } /*============================================================================ * ARC: zenithal/azimuthal equidistant projection. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to 0.0 if undefined. * prj->theta0 Reset to 90.0 if undefined. * * Returned: * prj->flag ARC * prj->code "ARC" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->w[0] r0*(pi/180) * prj->w[1] (180/pi)/r0 * prj->prjx2s Pointer to arcx2s(). * prj->prjs2x Pointer to arcs2x(). *===========================================================================*/ int arcset(struct prjprm *prj) { if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = ARC; strcpy(prj->code, "ARC"); strcpy(prj->name, "zenithal/azimuthal equidistant"); prj->category = ZENITHAL; prj->pvrange = 0; prj->simplezen = 1; prj->equiareal = 0; prj->conformal = 0; prj->global = 1; prj->divergent = 0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 1.0; prj->w[1] = 1.0; } else { prj->w[0] = prj->r0*D2R; prj->w[1] = 1.0/prj->w[0]; } prj->prjx2s = arcx2s; prj->prjs2x = arcs2x; return prjoff(prj, 0.0, 90.0); } //---------------------------------------------------------------------------- int arcx2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int mx, my, rowlen, rowoff, status; double r, xj, yj, yj2; register int ix, iy, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != ARC) { if ((status = arcset(prj))) return status; } if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { xj = *xp + prj->x0; phip = phi + rowoff; for (iy = 0; iy < my; iy++) { *phip = xj; phip += rowlen; } } // Do y dependence. yp = y; phip = phi; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { yj = *yp + prj->y0; yj2 = yj*yj; for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { xj = *phip; r = sqrt(xj*xj + yj2); if (r == 0.0) { *phip = 0.0; *thetap = 90.0; } else { *phip = atan2d(xj, -yj); *thetap = 90.0 - r*prj->w[1]; } *(statp++) = 0; } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-13, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("arcx2s"); } return status; } //---------------------------------------------------------------------------- int arcs2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int mphi, mtheta, rowlen, rowoff, status; double cosphi, r, sinphi; register int iphi, itheta, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != ARC) { if ((status = arcset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { sincosd(*phip, &sinphi, &cosphi); xp = x + rowoff; yp = y + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = sinphi; *yp = cosphi; xp += rowlen; yp += rowlen; } } // Do theta dependence. thetap = theta; xp = x; yp = y; statp = stat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { r = prj->w[0]*(90.0 - *thetap); for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { *xp = r*(*xp) - prj->x0; *yp = -r*(*yp) - prj->y0; *(statp++) = 0; } } return 0; } /*============================================================================ * ZPN: zenithal/azimuthal polynomial projection. * * Given: * prj->pv[] Polynomial coefficients. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to 0.0 if undefined. * prj->theta0 Reset to 90.0 if undefined. * * Returned: * prj->flag ZPN * prj->code "ZPN" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->n Degree of the polynomial, N. * prj->w[0] Co-latitude of the first point of inflection, radian. * prj->w[1] Radius of the first point of inflection (N > 1), radian. * prj->prjx2s Pointer to zpnx2s(). * prj->prjs2x Pointer to zpns2x(). *===========================================================================*/ int zpnset(struct prjprm *prj) { int j, k, m; double d, d1, d2, r, zd, zd1, zd2; const double tol = 1.0e-13; if (prj == 0x0) return PRJERR_NULL_POINTER; strcpy(prj->code, "ZPN"); prj->flag = ZPN; if (undefined(prj->pv[1])) prj->pv[1] = 0.0; if (undefined(prj->pv[2])) prj->pv[2] = 0.0; if (undefined(prj->pv[3])) prj->pv[3] = 0.0; if (prj->r0 == 0.0) prj->r0 = R2D; strcpy(prj->name, "zenithal/azimuthal polynomial"); prj->category = ZENITHAL; prj->pvrange = 30; prj->simplezen = 1; prj->equiareal = 0; prj->conformal = 0; prj->global = 0; prj->divergent = 0; // Find the highest non-zero coefficient. for (k = PVN-1; k >= 0 && prj->pv[k] == 0.0; k--); if (k < 0) { return PRJERR_BAD_PARAM_SET("zpnset"); } prj->n = k; if (k < 2) { // No point of inflection. prj->w[0] = PI; } else { // Find the point of inflection closest to the pole. zd1 = 0.0; d1 = prj->pv[1]; if (d1 <= 0.0) { return PRJERR_BAD_PARAM_SET("zpnset"); } // Find the point where the derivative first goes negative. for (j = 0; j < 180; j++) { zd2 = j*D2R; d2 = 0.0; for (m = k; m > 0; m--) { d2 = d2*zd2 + m*prj->pv[m]; } if (d2 <= 0.0) break; zd1 = zd2; d1 = d2; } if (j == 180) { // No negative derivative -> no point of inflection. zd = PI; prj->global = 1; } else { // Find where the derivative is zero. for (j = 1; j <= 10; j++) { zd = zd1 - d1*(zd2-zd1)/(d2-d1); d = 0.0; for (m = k; m > 0; m--) { d = d*zd + m*prj->pv[m]; } if (fabs(d) < tol) break; if (d < 0.0) { zd2 = zd; d2 = d; } else { zd1 = zd; d1 = d; } } } r = 0.0; for (m = k; m >= 0; m--) { r = r*zd + prj->pv[m]; } prj->w[0] = zd; prj->w[1] = r; } prj->prjx2s = zpnx2s; prj->prjs2x = zpns2x; return prjoff(prj, 0.0, 90.0); } //---------------------------------------------------------------------------- int zpnx2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int j, k, m, mx, my, rowlen, rowoff, status; double a, b, c, d, lambda, r, r1, r2, rt, xj, yj, yj2, zd, zd1, zd2; const double tol = 1.0e-13; register int ix, iy, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != ZPN) { if ((status = zpnset(prj))) return status; } k = prj->n; if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { xj = *xp + prj->x0; phip = phi + rowoff; for (iy = 0; iy < my; iy++) { *phip = xj; phip += rowlen; } } // Do y dependence. yp = y; phip = phi; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { yj = *yp + prj->y0; yj2 = yj*yj; for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { xj = *phip; r = sqrt(xj*xj + yj2)/prj->r0; if (r == 0.0) { *phip = 0.0; } else { *phip = atan2d(xj, -yj); } if (k < 1) { // Constant - no solution. return PRJERR_BAD_PARAM_SET("zpnx2s"); } else if (k == 1) { // Linear. zd = (r - prj->pv[0])/prj->pv[1]; } else if (k == 2) { // Quadratic. a = prj->pv[2]; b = prj->pv[1]; c = prj->pv[0] - r; d = b*b - 4.0*a*c; if (d < 0.0) { *thetap = 0.0; *(statp++) = 1; if (!status) status = PRJERR_BAD_PIX_SET("zpnx2s"); continue; } d = sqrt(d); // Choose solution closest to pole. zd1 = (-b + d)/(2.0*a); zd2 = (-b - d)/(2.0*a); zd = (zd1zd2) ? zd1 : zd2; if (zd < 0.0) { if (zd < -tol) { *thetap = 0.0; *(statp++) = 1; if (!status) status = PRJERR_BAD_PIX_SET("zpnx2s"); continue; } zd = 0.0; } else if (zd > PI) { if (zd > PI+tol) { *thetap = 0.0; *(statp++) = 1; if (!status) status = PRJERR_BAD_PIX_SET("zpnx2s"); continue; } zd = PI; } } else { // Higher order - solve iteratively. zd1 = 0.0; r1 = prj->pv[0]; zd2 = prj->w[0]; r2 = prj->w[1]; if (r < r1) { if (r < r1-tol) { *thetap = 0.0; *(statp++) = 1; if (!status) status = PRJERR_BAD_PIX_SET("zpnx2s"); continue; } zd = zd1; } else if (r > r2) { if (r > r2+tol) { *thetap = 0.0; *(statp++) = 1; if (!status) status = PRJERR_BAD_PIX_SET("zpnx2s"); continue; } zd = zd2; } else { // Dissect the interval. for (j = 0; j < 100; j++) { lambda = (r2 - r)/(r2 - r1); if (lambda < 0.1) { lambda = 0.1; } else if (lambda > 0.9) { lambda = 0.9; } zd = zd2 - lambda*(zd2 - zd1); rt = 0.0; for (m = k; m >= 0; m--) { rt = (rt * zd) + prj->pv[m]; } if (rt < r) { if (r-rt < tol) break; r1 = rt; zd1 = zd; } else { if (rt-r < tol) break; r2 = rt; zd2 = zd; } if (fabs(zd2-zd1) < tol) break; } } } *thetap = 90.0 - zd*R2D; *(statp++) = 0; } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-13, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("zpnx2s"); } return status; } //---------------------------------------------------------------------------- int zpns2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int m, mphi, mtheta, rowlen, rowoff, status; double cosphi, r, s, sinphi; register int iphi, itheta, istat, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != ZPN) { if ((status = zpnset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } status = 0; // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { sincosd(*phip, &sinphi, &cosphi); xp = x + rowoff; yp = y + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = sinphi; *yp = cosphi; xp += rowlen; yp += rowlen; } } // Do theta dependence. thetap = theta; xp = x; yp = y; statp = stat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { s = (90.0 - *thetap)*D2R; r = 0.0; for (m = prj->n; m >= 0; m--) { r = r*s + prj->pv[m]; } r *= prj->r0; // Bounds checking. istat = 0; if (prj->bounds&1) { if (s > prj->w[0]) { istat = 1; if (!status) status = PRJERR_BAD_WORLD_SET("zpns2x"); } } for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { *xp = r*(*xp) - prj->x0; *yp = -r*(*yp) - prj->y0; *(statp++) = istat; } } return status; } /*============================================================================ * ZEA: zenithal/azimuthal equal area projection. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to 0.0 if undefined. * prj->theta0 Reset to 90.0 if undefined. * * Returned: * prj->flag ZEA * prj->code "ZEA" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->w[0] 2*r0 * prj->w[1] 1/(2*r0) * prj->prjx2s Pointer to zeax2s(). * prj->prjs2x Pointer to zeas2x(). *===========================================================================*/ int zeaset(struct prjprm *prj) { if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = ZEA; strcpy(prj->code, "ZEA"); strcpy(prj->name, "zenithal/azimuthal equal area"); prj->category = ZENITHAL; prj->pvrange = 0; prj->simplezen = 1; prj->equiareal = 1; prj->conformal = 0; prj->global = 1; prj->divergent = 0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 360.0/PI; prj->w[1] = PI/360.0; } else { prj->w[0] = 2.0*prj->r0; prj->w[1] = 1.0/prj->w[0]; } prj->prjx2s = zeax2s; prj->prjs2x = zeas2x; return prjoff(prj, 0.0, 90.0); } //---------------------------------------------------------------------------- int zeax2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int mx, my, rowlen, rowoff, status; double r, s, xj, yj, yj2; const double tol = 1.0e-12; register int ix, iy, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != ZEA) { if ((status = zeaset(prj))) return status; } if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { xj = *xp + prj->x0; phip = phi + rowoff; for (iy = 0; iy < my; iy++) { *phip = xj; phip += rowlen; } } // Do y dependence. yp = y; phip = phi; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { yj = *yp + prj->y0; yj2 = yj*yj; for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { xj = *phip; r = sqrt(xj*xj + yj2); if (r == 0.0) { *phip = 0.0; } else { *phip = atan2d(xj, -yj); } s = r*prj->w[1]; if (fabs(s) > 1.0) { if (fabs(r - prj->w[0]) < tol) { *thetap = -90.0; } else { *thetap = 0.0; *(statp++) = 1; if (!status) status = PRJERR_BAD_PIX_SET("zeax2s"); continue; } } else { *thetap = 90.0 - 2.0*asind(s); } *(statp++) = 0; } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-13, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("zeax2s"); } return status; } //---------------------------------------------------------------------------- int zeas2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int mphi, mtheta, rowlen, rowoff, status; double cosphi, r, sinphi; register int iphi, itheta, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != ZEA) { if ((status = zeaset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { sincosd(*phip, &sinphi, &cosphi); xp = x + rowoff; yp = y + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = sinphi; *yp = cosphi; xp += rowlen; yp += rowlen; } } // Do theta dependence. thetap = theta; xp = x; yp = y; statp = stat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { r = prj->w[0]*sind((90.0 - *thetap)/2.0); for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { *xp = r*(*xp) - prj->x0; *yp = -r*(*yp) - prj->y0; *(statp++) = 0; } } return 0; } /*============================================================================ * AIR: Airy's projection. * * Given: * prj->pv[1] Latitude theta_b within which the error is minimized, in * degrees. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to 0.0 if undefined. * prj->theta0 Reset to 90.0 if undefined. * * Returned: * prj->flag AIR * prj->code "AIR" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->w[0] 2*r0 * prj->w[1] ln(cos(xi_b))/tan(xi_b)**2, where xi_b = (90-theta_b)/2 * prj->w[2] 1/2 - prj->w[1] * prj->w[3] 2*r0*prj->w[2] * prj->w[4] tol, cutoff for using small angle approximation, in * radians. * prj->w[5] prj->w[2]*tol * prj->w[6] (180/pi)/prj->w[2] * prj->prjx2s Pointer to airx2s(). * prj->prjs2x Pointer to airs2x(). *===========================================================================*/ int airset(struct prjprm *prj) { const double tol = 1.0e-4; double cosxi; if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = AIR; strcpy(prj->code, "AIR"); if (undefined(prj->pv[1])) prj->pv[1] = 90.0; if (prj->r0 == 0.0) prj->r0 = R2D; strcpy(prj->name, "Airy's zenithal"); prj->category = ZENITHAL; prj->pvrange = 101; prj->simplezen = 1; prj->equiareal = 0; prj->conformal = 0; prj->global = 0; prj->divergent = 1; prj->w[0] = 2.0*prj->r0; if (prj->pv[1] == 90.0) { prj->w[1] = -0.5; prj->w[2] = 1.0; } else if (prj->pv[1] > -90.0) { cosxi = cosd((90.0 - prj->pv[1])/2.0); prj->w[1] = log(cosxi)*(cosxi*cosxi)/(1.0-cosxi*cosxi); prj->w[2] = 0.5 - prj->w[1]; } else { return PRJERR_BAD_PARAM_SET("airset"); } prj->w[3] = prj->w[0] * prj->w[2]; prj->w[4] = tol; prj->w[5] = prj->w[2]*tol; prj->w[6] = R2D/prj->w[2]; prj->prjx2s = airx2s; prj->prjs2x = airs2x; return prjoff(prj, 0.0, 90.0); } //---------------------------------------------------------------------------- int airx2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int k, mx, my, rowlen, rowoff, status; double cosxi, lambda, r, r1, r2, rt, tanxi, x1, x2, xi, xj, yj, yj2; const double tol = 1.0e-12; register int ix, iy, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != AIR) { if ((status = airset(prj))) return status; } if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { xj = *xp + prj->x0; phip = phi + rowoff; for (iy = 0; iy < my; iy++) { *phip = xj; phip += rowlen; } } // Do y dependence. yp = y; phip = phi; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { yj = *yp + prj->y0; yj2 = yj*yj; for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { xj = *phip; r = sqrt(xj*xj + yj2)/prj->w[0]; if (r == 0.0) { *phip = 0.0; } else { *phip = atan2d(xj, -yj); } if (r == 0.0) { xi = 0.0; } else if (r < prj->w[5]) { xi = r*prj->w[6]; } else { // Find a solution interval. x1 = x2 = 1.0; r1 = r2 = 0.0; for (k = 0; k < 30; k++) { x2 = x1/2.0; tanxi = sqrt(1.0-x2*x2)/x2; r2 = -(log(x2)/tanxi + prj->w[1]*tanxi); if (r2 >= r) break; x1 = x2; r1 = r2; } if (k == 30) { *thetap = 0.0; *(statp++) = 1; if (!status) status = PRJERR_BAD_PIX_SET("airx2s"); continue; } for (k = 0; k < 100; k++) { // Weighted division of the interval. lambda = (r2-r)/(r2-r1); if (lambda < 0.1) { lambda = 0.1; } else if (lambda > 0.9) { lambda = 0.9; } cosxi = x2 - lambda*(x2-x1); tanxi = sqrt(1.0-cosxi*cosxi)/cosxi; rt = -(log(cosxi)/tanxi + prj->w[1]*tanxi); if (rt < r) { if (r-rt < tol) break; r1 = rt; x1 = cosxi; } else { if (rt-r < tol) break; r2 = rt; x2 = cosxi; } } if (k == 100) { *thetap = 0.0; *(statp++) = 1; if (!status) status = PRJERR_BAD_PIX_SET("airx2s"); continue; } xi = acosd(cosxi); } *thetap = 90.0 - 2.0*xi; *(statp++) = 0; } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-13, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("airx2s"); } return status; } //---------------------------------------------------------------------------- int airs2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int mphi, mtheta, rowlen, rowoff, status; double cosphi, cosxi, r, tanxi, xi, sinphi; register int iphi, itheta, istat, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != AIR) { if ((status = airset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } status = 0; // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { sincosd(*phip, &sinphi, &cosphi); xp = x + rowoff; yp = y + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = sinphi; *yp = cosphi; xp += rowlen; yp += rowlen; } } // Do theta dependence. thetap = theta; xp = x; yp = y; statp = stat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { istat = 0; if (*thetap == 90.0) { r = 0.0; } else if (*thetap > -90.0) { xi = D2R*(90.0 - *thetap)/2.0; if (xi < prj->w[4]) { r = xi*prj->w[3]; } else { cosxi = cosd((90.0 - *thetap)/2.0); tanxi = sqrt(1.0 - cosxi*cosxi)/cosxi; r = -prj->w[0]*(log(cosxi)/tanxi + prj->w[1]*tanxi); } } else { r = 0.0; istat = 1; if (!status) status = PRJERR_BAD_WORLD_SET("airs2x"); } for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { *xp = r*(*xp) - prj->x0; *yp = -r*(*yp) - prj->y0; *(statp++) = istat; } } return status; } /*============================================================================ * CYP: cylindrical perspective projection. * * Given: * prj->pv[1] Distance of point of projection from the centre of the * generating sphere, mu, in units of r0. * prj->pv[2] Radius of the cylinder of projection, lambda, in units of * r0. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to 0.0 if undefined. * prj->theta0 Reset to 0.0 if undefined. * * Returned: * prj->flag CYP * prj->code "CYP" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->w[0] r0*lambda*(pi/180) * prj->w[1] (180/pi)/(r0*lambda) * prj->w[2] r0*(mu + lambda) * prj->w[3] 1/(r0*(mu + lambda)) * prj->prjx2s Pointer to cypx2s(). * prj->prjs2x Pointer to cyps2x(). *===========================================================================*/ int cypset(struct prjprm *prj) { if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = CYP; strcpy(prj->code, "CYP"); if (undefined(prj->pv[1])) prj->pv[1] = 1.0; if (undefined(prj->pv[2])) prj->pv[2] = 1.0; strcpy(prj->name, "cylindrical perspective"); prj->category = CYLINDRICAL; prj->pvrange = 102; prj->simplezen = 0; prj->equiareal = 0; prj->conformal = 0; prj->global = prj->pv[1] < -1.0 || 0.0 < prj->pv[1]; prj->divergent = !prj->global; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = prj->pv[2]; if (prj->w[0] == 0.0) { return PRJERR_BAD_PARAM_SET("cypset"); } prj->w[1] = 1.0/prj->w[0]; prj->w[2] = R2D*(prj->pv[1] + prj->pv[2]); if (prj->w[2] == 0.0) { return PRJERR_BAD_PARAM_SET("cypset"); } prj->w[3] = 1.0/prj->w[2]; } else { prj->w[0] = prj->r0*prj->pv[2]*D2R; if (prj->w[0] == 0.0) { return PRJERR_BAD_PARAM_SET("cypset"); } prj->w[1] = 1.0/prj->w[0]; prj->w[2] = prj->r0*(prj->pv[1] + prj->pv[2]); if (prj->w[2] == 0.0) { return PRJERR_BAD_PARAM_SET("cypset"); } prj->w[3] = 1.0/prj->w[2]; } prj->prjx2s = cypx2s; prj->prjs2x = cyps2x; return prjoff(prj, 0.0, 0.0); } //---------------------------------------------------------------------------- int cypx2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int mx, my, rowlen, rowoff, status; double eta, s, t; register int ix, iy, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != CYP) { if ((status = cypset(prj))) return status; } if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { s = prj->w[1]*(*xp + prj->x0); phip = phi + rowoff; for (iy = 0; iy < my; iy++) { *phip = s; phip += rowlen; } } // Do y dependence. yp = y; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { eta = prj->w[3]*(*yp + prj->y0); t = atan2d(eta,1.0) + asind(eta*prj->pv[1]/sqrt(eta*eta+1.0)); for (ix = 0; ix < mx; ix++, thetap += spt) { *thetap = t; *(statp++) = 0; } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-13, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("cypx2s"); } return status; } //---------------------------------------------------------------------------- int cyps2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int mphi, mtheta, rowlen, rowoff, status; double eta, xi; register int iphi, itheta, istat, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != CYP) { if ((status = cypset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } status = 0; // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { xi = prj->w[0]*(*phip) - prj->x0; xp = x + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = xi; xp += rowlen; } } // Do theta dependence. thetap = theta; yp = y; statp = stat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { eta = prj->pv[1] + cosd(*thetap); istat = 0; if (eta == 0.0) { istat = 1; if (!status) status = PRJERR_BAD_WORLD_SET("cyps2x"); } else { eta = prj->w[2]*sind(*thetap)/eta; } eta -= prj->y0; for (iphi = 0; iphi < mphi; iphi++, yp += sxy) { *yp = eta; *(statp++) = istat; } } return status; } /*============================================================================ * CEA: cylindrical equal area projection. * * Given: * prj->pv[1] Square of the cosine of the latitude at which the * projection is conformal, lambda. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to 0.0 if undefined. * prj->theta0 Reset to 0.0 if undefined. * * Returned: * prj->flag CEA * prj->code "CEA" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->w[0] r0*(pi/180) * prj->w[1] (180/pi)/r0 * prj->w[2] r0/lambda * prj->w[3] lambda/r0 * prj->prjx2s Pointer to ceax2s(). * prj->prjs2x Pointer to ceas2x(). *===========================================================================*/ int ceaset(struct prjprm *prj) { if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = CEA; strcpy(prj->code, "CEA"); if (undefined(prj->pv[1])) prj->pv[1] = 1.0; strcpy(prj->name, "cylindrical equal area"); prj->category = CYLINDRICAL; prj->pvrange = 101; prj->simplezen = 0; prj->equiareal = 1; prj->conformal = 0; prj->global = 1; prj->divergent = 0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 1.0; prj->w[1] = 1.0; if (prj->pv[1] <= 0.0 || prj->pv[1] > 1.0) { return PRJERR_BAD_PARAM_SET("ceaset"); } prj->w[2] = prj->r0/prj->pv[1]; prj->w[3] = prj->pv[1]/prj->r0; } else { prj->w[0] = prj->r0*D2R; prj->w[1] = R2D/prj->r0; if (prj->pv[1] <= 0.0 || prj->pv[1] > 1.0) { return PRJERR_BAD_PARAM_SET("ceaset"); } prj->w[2] = prj->r0/prj->pv[1]; prj->w[3] = prj->pv[1]/prj->r0; } prj->prjx2s = ceax2s; prj->prjs2x = ceas2x; return prjoff(prj, 0.0, 0.0); } //---------------------------------------------------------------------------- int ceax2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int mx, my, rowlen, rowoff, status; double s; const double tol = 1.0e-13; register int istat, ix, iy, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != CEA) { if ((status = ceaset(prj))) return status; } if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { s = prj->w[1]*(*xp + prj->x0); phip = phi + rowoff; for (iy = 0; iy < my; iy++) { *phip = s; phip += rowlen; } } // Do y dependence. yp = y; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { s = prj->w[3]*(*yp + prj->y0); istat = 0; if (fabs(s) > 1.0) { if (fabs(s) > 1.0+tol) { s = 0.0; istat = 1; if (!status) status = PRJERR_BAD_PIX_SET("ceax2s"); } else { s = copysign(90.0, s); } } else { s = asind(s); } for (ix = 0; ix < mx; ix++, thetap += spt) { *thetap = s; *(statp++) = istat; } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-13, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("ceax2s"); } return status; } //---------------------------------------------------------------------------- int ceas2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int mphi, mtheta, rowlen, rowoff, status; double eta, xi; register int iphi, itheta, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != CEA) { if ((status = ceaset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { xi = prj->w[0]*(*phip) - prj->x0; xp = x + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = xi; xp += rowlen; } } // Do theta dependence. thetap = theta; yp = y; statp = stat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { eta = prj->w[2]*sind(*thetap) - prj->y0; for (iphi = 0; iphi < mphi; iphi++, yp += sxy) { *yp = eta; *(statp++) = 0; } } return 0; } /*============================================================================ * CAR: Plate carree projection. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to 0.0 if undefined. * prj->theta0 Reset to 0.0 if undefined. * * Returned: * prj->flag CAR * prj->code "CAR" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->w[0] r0*(pi/180) * prj->w[1] (180/pi)/r0 * prj->prjx2s Pointer to carx2s(). * prj->prjs2x Pointer to cars2x(). *===========================================================================*/ int carset(struct prjprm *prj) { if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = CAR; strcpy(prj->code, "CAR"); strcpy(prj->name, "plate caree"); prj->category = CYLINDRICAL; prj->pvrange = 0; prj->simplezen = 0; prj->equiareal = 0; prj->conformal = 0; prj->global = 1; prj->divergent = 0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 1.0; prj->w[1] = 1.0; } else { prj->w[0] = prj->r0*D2R; prj->w[1] = 1.0/prj->w[0]; } prj->prjx2s = carx2s; prj->prjs2x = cars2x; return prjoff(prj, 0.0, 0.0); } //---------------------------------------------------------------------------- int carx2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int mx, my, rowlen, rowoff, status; double s, t; register int ix, iy, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != CAR) { if ((status = carset(prj))) return status; } if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { s = prj->w[1]*(*xp + prj->x0); phip = phi + rowoff; for (iy = 0; iy < my; iy++) { *phip = s; phip += rowlen; } } // Do y dependence. yp = y; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { t = prj->w[1]*(*yp + prj->y0); for (ix = 0; ix < mx; ix++, thetap += spt) { *thetap = t; *(statp++) = 0; } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-13, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("carx2s"); } return status; } //---------------------------------------------------------------------------- int cars2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int mphi, mtheta, rowlen, rowoff, status; double eta, xi; register int iphi, itheta, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != CAR) { if ((status = carset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { xi = prj->w[0]*(*phip) - prj->x0; xp = x + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = xi; xp += rowlen; } } // Do theta dependence. thetap = theta; yp = y; statp = stat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { eta = prj->w[0]*(*thetap) - prj->y0; for (iphi = 0; iphi < mphi; iphi++, yp += sxy) { *yp = eta; *(statp++) = 0; } } return 0; } /*============================================================================ * MER: Mercator's projection. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to 0.0 if undefined. * prj->theta0 Reset to 0.0 if undefined. * * Returned: * prj->flag MER * prj->code "MER" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->w[0] r0*(pi/180) * prj->w[1] (180/pi)/r0 * prj->prjx2s Pointer to merx2s(). * prj->prjs2x Pointer to mers2x(). *===========================================================================*/ int merset(struct prjprm *prj) { if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = MER; strcpy(prj->code, "MER"); strcpy(prj->name, "Mercator's"); prj->category = CYLINDRICAL; prj->pvrange = 0; prj->simplezen = 0; prj->equiareal = 0; prj->conformal = 1; prj->global = 0; prj->divergent = 1; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 1.0; prj->w[1] = 1.0; } else { prj->w[0] = prj->r0*D2R; prj->w[1] = 1.0/prj->w[0]; } prj->prjx2s = merx2s; prj->prjs2x = mers2x; return prjoff(prj, 0.0, 0.0); } //---------------------------------------------------------------------------- int merx2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int mx, my, rowlen, rowoff, status; double s, t; register int ix, iy, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != MER) { if ((status = merset(prj))) return status; } if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { s = prj->w[1]*(*xp + prj->x0); phip = phi + rowoff; for (iy = 0; iy < my; iy++) { *phip = s; phip += rowlen; } } // Do y dependence. yp = y; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { t = 2.0*atand(exp((*yp + prj->y0)/prj->r0)) - 90.0; for (ix = 0; ix < mx; ix++, thetap += spt) { *thetap = t; *(statp++) = 0; } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-13, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("merx2s"); } return status; } //---------------------------------------------------------------------------- int mers2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int mphi, mtheta, rowlen, rowoff, status; double eta, xi; register int iphi, itheta, istat, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != MER) { if ((status = merset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } status = 0; // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { xi = prj->w[0]*(*phip) - prj->x0; xp = x + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = xi; xp += rowlen; } } // Do theta dependence. thetap = theta; yp = y; statp = stat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { istat = 0; if (*thetap <= -90.0 || *thetap >= 90.0) { eta = 0.0; istat = 1; if (!status) status = PRJERR_BAD_WORLD_SET("mers2x"); } else { eta = prj->r0*log(tand((*thetap+90.0)/2.0)) - prj->y0; } for (iphi = 0; iphi < mphi; iphi++, yp += sxy) { *yp = eta; *(statp++) = istat; } } return status; } /*============================================================================ * SFL: Sanson-Flamsteed ("global sinusoid") projection. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to 0.0 if undefined. * prj->theta0 Reset to 0.0 if undefined. * * Returned: * prj->flag SFL * prj->code "SFL" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->w[0] r0*(pi/180) * prj->w[1] (180/pi)/r0 * prj->prjx2s Pointer to sflx2s(). * prj->prjs2x Pointer to sfls2x(). *===========================================================================*/ int sflset(struct prjprm *prj) { if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = SFL; strcpy(prj->code, "SFL"); strcpy(prj->name, "Sanson-Flamsteed"); prj->category = PSEUDOCYLINDRICAL; prj->pvrange = 0; prj->simplezen = 0; prj->equiareal = 1; prj->conformal = 0; prj->global = 1; prj->divergent = 0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 1.0; prj->w[1] = 1.0; } else { prj->w[0] = prj->r0*D2R; prj->w[1] = 1.0/prj->w[0]; } prj->prjx2s = sflx2s; prj->prjs2x = sfls2x; return prjoff(prj, 0.0, 0.0); } //---------------------------------------------------------------------------- int sflx2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int mx, my, rowlen, rowoff, status; double s, t, yj; register int istat, ix, iy, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != SFL) { if ((status = sflset(prj))) return status; } if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { s = prj->w[1]*(*xp + prj->x0); phip = phi + rowoff; for (iy = 0; iy < my; iy++) { *phip = s; phip += rowlen; } } // Do y dependence. yp = y; phip = phi; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { yj = *yp + prj->y0; s = cos(yj/prj->r0); istat = 0; if (s == 0.0) { istat = 1; if (!status) status = PRJERR_BAD_PIX_SET("sflx2s"); } else { s = 1.0/s; } t = prj->w[1]*yj; for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { *phip *= s; *thetap = t; *(statp++) = istat; } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-12, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("sflx2s"); } return status; } //---------------------------------------------------------------------------- int sfls2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int mphi, mtheta, rowlen, rowoff, status; double eta, xi; register int iphi, itheta, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != SFL) { if ((status = sflset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { xi = prj->w[0]*(*phip); xp = x + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = xi; xp += rowlen; } } // Do theta dependence. thetap = theta; xp = x; yp = y; statp = stat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { xi = cosd(*thetap); eta = prj->w[0]*(*thetap) - prj->y0; for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { *xp = xi*(*xp) - prj->x0; *yp = eta; *(statp++) = 0; } } return 0; } /*============================================================================ * PAR: parabolic projection. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to 0.0 if undefined. * prj->theta0 Reset to 0.0 if undefined. * * Returned: * prj->flag PAR * prj->code "PAR" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->w[0] r0*(pi/180) * prj->w[1] (180/pi)/r0 * prj->w[2] pi*r0 * prj->w[3] 1/(pi*r0) * prj->prjx2s Pointer to parx2s(). * prj->prjs2x Pointer to pars2x(). *===========================================================================*/ int parset(struct prjprm *prj) { if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = PAR; strcpy(prj->code, "PAR"); strcpy(prj->name, "parabolic"); prj->category = PSEUDOCYLINDRICAL; prj->pvrange = 0; prj->simplezen = 0; prj->equiareal = 1; prj->conformal = 0; prj->global = 1; prj->divergent = 0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 1.0; prj->w[1] = 1.0; prj->w[2] = 180.0; prj->w[3] = 1.0/prj->w[2]; } else { prj->w[0] = prj->r0*D2R; prj->w[1] = 1.0/prj->w[0]; prj->w[2] = PI*prj->r0; prj->w[3] = 1.0/prj->w[2]; } prj->prjx2s = parx2s; prj->prjs2x = pars2x; return prjoff(prj, 0.0, 0.0); } //---------------------------------------------------------------------------- int parx2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int mx, my, rowlen, rowoff, status; double r, s, t, xj; const double tol = 1.0e-13; register int istat, ix, iy, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != PAR) { if ((status = parset(prj))) return status; } if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { xj = *xp + prj->x0; s = prj->w[1]*xj; t = fabs(xj) - tol; phip = phi + rowoff; thetap = theta + rowoff; for (iy = 0; iy < my; iy++) { *phip = s; *thetap = t; phip += rowlen; thetap += rowlen; } } // Do y dependence. yp = y; phip = phi; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { r = prj->w[3]*(*yp + prj->y0); istat = 0; if (r > 1.0 || r < -1.0) { s = 0.0; t = 0.0; istat = 1; if (!status) status = PRJERR_BAD_PIX_SET("parx2s"); } else { s = 1.0 - 4.0*r*r; if (s == 0.0) { // Deferred test. istat = -1; } else { s = 1.0/s; } t = 3.0*asind(r); } for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { if (istat < 0) { if (*thetap < 0.0) { *(statp++) = 0; } else { *(statp++) = 1; if (!status) status = PRJERR_BAD_PIX_SET("parx2s"); } } else { *(statp++) = istat; } *phip *= s; *thetap = t; } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-12, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("parx2s"); } return status; } //---------------------------------------------------------------------------- int pars2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int mphi, mtheta, rowlen, rowoff, status; double eta, s, xi; register int iphi, itheta, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != PAR) { if ((status = parset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { xi = prj->w[0]*(*phip); xp = x + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = xi; xp += rowlen; } } // Do theta dependence. thetap = theta; xp = x; yp = y; statp = stat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { s = sind((*thetap)/3.0); xi = (1.0 - 4.0*s*s); eta = prj->w[2]*s - prj->y0; for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { *xp = xi*(*xp) - prj->x0; *yp = eta; *(statp++) = 0; } } return 0; } /*============================================================================ * MOL: Mollweide's projection. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to 0.0 if undefined. * prj->theta0 Reset to 0.0 if undefined. * * Returned: * prj->flag MOL * prj->code "MOL" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->w[0] sqrt(2)*r0 * prj->w[1] sqrt(2)*r0/90 * prj->w[2] 1/(sqrt(2)*r0) * prj->w[3] 90/r0 * prj->prjx2s Pointer to molx2s(). * prj->prjs2x Pointer to mols2x(). *===========================================================================*/ int molset(struct prjprm *prj) { if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = MOL; strcpy(prj->code, "MOL"); if (prj->r0 == 0.0) prj->r0 = R2D; strcpy(prj->name, "Mollweide's"); prj->category = PSEUDOCYLINDRICAL; prj->pvrange = 0; prj->simplezen = 0; prj->equiareal = 1; prj->conformal = 0; prj->global = 1; prj->divergent = 0; prj->w[0] = SQRT2*prj->r0; prj->w[1] = prj->w[0]/90.0; prj->w[2] = 1.0/prj->w[0]; prj->w[3] = 90.0/prj->r0; prj->w[4] = 2.0/PI; prj->prjx2s = molx2s; prj->prjs2x = mols2x; return prjoff(prj, 0.0, 0.0); } //---------------------------------------------------------------------------- int molx2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int mx, my, rowlen, rowoff, status; double r, s, t, xj, y0, yj, z; const double tol = 1.0e-12; register int istat, ix, iy, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != MOL) { if ((status = molset(prj))) return status; } if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { xj = *xp + prj->x0; s = prj->w[3]*xj; t = fabs(xj) - tol; phip = phi + rowoff; thetap = theta + rowoff; for (iy = 0; iy < my; iy++) { *phip = s; *thetap = t; phip += rowlen; thetap += rowlen; } } // Do y dependence. yp = y; phip = phi; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { yj = *yp + prj->y0; y0 = yj/prj->r0; r = 2.0 - y0*y0; istat = 0; if (r <= tol) { if (r < -tol) { istat = 1; if (!status) status = PRJERR_BAD_PIX_SET("molx2s"); } else { // OK if fabs(x) < tol whence phi = 0.0. istat = -1; } r = 0.0; s = 0.0; } else { r = sqrt(r); s = 1.0/r; } z = yj*prj->w[2]; if (fabs(z) > 1.0) { if (fabs(z) > 1.0+tol) { z = 0.0; istat = 1; if (!status) status = PRJERR_BAD_PIX_SET("molx2s"); } else { z = copysign(1.0, z) + y0*r/PI; } } else { z = asin(z)*prj->w[4] + y0*r/PI; } if (fabs(z) > 1.0) { if (fabs(z) > 1.0+tol) { z = 0.0; istat = 1; if (!status) status = PRJERR_BAD_PIX_SET("molx2s"); } else { z = copysign(1.0, z); } } t = asind(z); for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { if (istat < 0) { if (*thetap < 0.0) { *(statp++) = 0; } else { *(statp++) = 1; if (!status) status = PRJERR_BAD_PIX_SET("molx2s"); } } else { *(statp++) = istat; } *phip *= s; *thetap = t; } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-11, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("molx2s"); } return status; } //---------------------------------------------------------------------------- int mols2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int k, mphi, mtheta, rowlen, rowoff, status; double eta, gamma, resid, u, v, v0, v1, xi; const double tol = 1.0e-13; register int iphi, itheta, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != MOL) { if ((status = molset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { xi = prj->w[1]*(*phip); xp = x + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = xi; xp += rowlen; } } // Do theta dependence. thetap = theta; xp = x; yp = y; statp = stat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { if (fabs(*thetap) == 90.0) { xi = 0.0; eta = copysign(prj->w[0], *thetap); } else if (*thetap == 0.0) { xi = 1.0; eta = 0.0; } else { u = PI*sind(*thetap); v0 = -PI; v1 = PI; v = u; for (k = 0; k < 100; k++) { resid = (v - u) + sin(v); if (resid < 0.0) { if (resid > -tol) break; v0 = v; } else { if (resid < tol) break; v1 = v; } v = (v0 + v1)/2.0; } gamma = v/2.0; xi = cos(gamma); eta = prj->w[0]*sin(gamma); } eta -= prj->y0; for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { *xp = xi*(*xp) - prj->x0; *yp = eta; *(statp++) = 0; } } return 0; } /*============================================================================ * AIT: Hammer-Aitoff projection. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to 0.0 if undefined. * prj->theta0 Reset to 0.0 if undefined. * * Returned: * prj->flag AIT * prj->code "AIT" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->w[0] 2*r0**2 * prj->w[1] 1/(2*r0)**2 * prj->w[2] 1/(4*r0)**2 * prj->w[3] 1/(2*r0) * prj->prjx2s Pointer to aitx2s(). * prj->prjs2x Pointer to aits2x(). *===========================================================================*/ int aitset(struct prjprm *prj) { if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = AIT; strcpy(prj->code, "AIT"); if (prj->r0 == 0.0) prj->r0 = R2D; strcpy(prj->name, "Hammer-Aitoff"); prj->category = CONVENTIONAL; prj->pvrange = 0; prj->simplezen = 0; prj->equiareal = 1; prj->conformal = 0; prj->global = 1; prj->divergent = 0; prj->w[0] = 2.0*prj->r0*prj->r0; prj->w[1] = 1.0/(2.0*prj->w[0]); prj->w[2] = prj->w[1]/4.0; prj->w[3] = 1.0/(2.0*prj->r0); prj->prjx2s = aitx2s; prj->prjs2x = aits2x; return prjoff(prj, 0.0, 0.0); } //---------------------------------------------------------------------------- int aitx2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int mx, my, rowlen, rowoff, status; double s, t, x0, xj, y0, yj, yj2, z; const double tol = 1.0e-13; register int ix, iy, istat, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != AIT) { if ((status = aitset(prj))) return status; } if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { xj = *xp + prj->x0; s = 1.0 - xj*xj*prj->w[2]; t = xj*prj->w[3]; phip = phi + rowoff; thetap = theta + rowoff; for (iy = 0; iy < my; iy++) { *phip = s; *thetap = t; phip += rowlen; thetap += rowlen; } } // Do y dependence. yp = y; phip = phi; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { yj = *yp + prj->y0; yj2 = yj*yj*prj->w[1]; for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { s = *phip - yj2; istat = 0; if (s < 0.5) { if (s < 0.5-tol) { istat = 1; if (!status) status = PRJERR_BAD_PIX_SET("aitx2s"); } s = 0.5; } z = sqrt(s); x0 = 2.0*z*z - 1.0; y0 = z*(*thetap); if (x0 == 0.0 && y0 == 0.0) { *phip = 0.0; } else { *phip = 2.0*atan2d(y0, x0); } t = z*yj/prj->r0; if (fabs(t) > 1.0) { if (fabs(t) > 1.0+tol) { istat = 1; if (!status) status = PRJERR_BAD_PIX_SET("aitx2s"); } t = copysign(90.0, t); } else { t = asind(t); } *thetap = t; *(statp++) = istat; } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-13, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("aitx2s"); } return status; } //---------------------------------------------------------------------------- int aits2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int mphi, mtheta, rowlen, rowoff, status; double cosphi, costhe, sinphi, sinthe, w; register int iphi, itheta, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != AIT) { if ((status = aitset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { w = (*phip)/2.0; sincosd(w, &sinphi, &cosphi); xp = x + rowoff; yp = y + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = sinphi; *yp = cosphi; xp += rowlen; yp += rowlen; } } // Do theta dependence. thetap = theta; xp = x; yp = y; statp = stat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { sincosd(*thetap, &sinthe, &costhe); for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { w = sqrt(prj->w[0]/(1.0 + costhe*(*yp))); *xp = 2.0*w*costhe*(*xp) - prj->x0; *yp = w*sinthe - prj->y0; *(statp++) = 0; } } return 0; } /*============================================================================ * COP: conic perspective projection. * * Given: * prj->pv[1] sigma = (theta2+theta1)/2 * prj->pv[2] delta = (theta2-theta1)/2, where theta1 and theta2 are the * latitudes of the standard parallels, in degrees. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to sigma if undefined. * prj->theta0 Reset to sigma if undefined. * * Returned: * prj->flag COP * prj->code "COP" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->w[0] C = sin(sigma) * prj->w[1] 1/C * prj->w[2] Y0 = r0*cos(delta)*cot(sigma) * prj->w[3] r0*cos(delta) * prj->w[4] 1/(r0*cos(delta) * prj->w[5] cot(sigma) * prj->prjx2s Pointer to copx2s(). * prj->prjs2x Pointer to cops2x(). *===========================================================================*/ int copset(struct prjprm *prj) { if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = COP; strcpy(prj->code, "COP"); strcpy(prj->name, "conic perspective"); if (undefined(prj->pv[1])) { return PRJERR_BAD_PARAM_SET("copset"); } if (undefined(prj->pv[2])) prj->pv[2] = 0.0; if (prj->r0 == 0.0) prj->r0 = R2D; prj->category = CONIC; prj->pvrange = 102; prj->simplezen = 0; prj->equiareal = 0; prj->conformal = 0; prj->global = 0; prj->divergent = 1; prj->w[0] = sind(prj->pv[1]); if (prj->w[0] == 0.0) { return PRJERR_BAD_PARAM_SET("copset"); } prj->w[1] = 1.0/prj->w[0]; prj->w[3] = prj->r0*cosd(prj->pv[2]); if (prj->w[3] == 0.0) { return PRJERR_BAD_PARAM_SET("copset"); } prj->w[4] = 1.0/prj->w[3]; prj->w[5] = 1.0/tand(prj->pv[1]); prj->w[2] = prj->w[3]*prj->w[5]; prj->prjx2s = copx2s; prj->prjs2x = cops2x; return prjoff(prj, 0.0, prj->pv[1]); } //---------------------------------------------------------------------------- int copx2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int mx, my, rowlen, rowoff, status; double alpha, dy, dy2, r, xj; register int ix, iy, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != COP) { if ((status = copset(prj))) return status; } if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { xj = *xp + prj->x0; phip = phi + rowoff; for (iy = 0; iy < my; iy++) { *phip = xj; phip += rowlen; } } // Do y dependence. yp = y; phip = phi; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { dy = prj->w[2] - (*yp + prj->y0); dy2 = dy*dy; for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { xj = *phip; r = sqrt(xj*xj + dy2); if (prj->pv[1] < 0.0) r = -r; if (r == 0.0) { alpha = 0.0; } else { alpha = atan2d(xj/r, dy/r); } *phip = alpha*prj->w[1]; *thetap = prj->pv[1] + atand(prj->w[5] - r*prj->w[4]); *(statp++) = 0; } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-13, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("copx2s"); } return status; } //---------------------------------------------------------------------------- int cops2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int mphi, mtheta, rowlen, rowoff, status; double alpha, cosalpha, r, s, t, sinalpha, y0; register int iphi, itheta, istat, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != COP) { if ((status = copset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } status = 0; // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { alpha = prj->w[0]*(*phip); sincosd(alpha, &sinalpha, &cosalpha); xp = x + rowoff; yp = y + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = sinalpha; *yp = cosalpha; xp += rowlen; yp += rowlen; } } // Do theta dependence. thetap = theta; xp = x; yp = y; statp = stat; y0 = prj->y0 - prj->w[2]; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { t = *thetap - prj->pv[1]; s = cosd(t); istat = 0; if (s == 0.0) { // Latitude of divergence. r = 0.0; istat = 1; if (!status) status = PRJERR_BAD_WORLD_SET("cops2x"); } else if (fabs(*thetap) == 90.0) { // Return an exact value at the poles. r = 0.0; // Bounds checking. if (prj->bounds&1) { if ((*thetap < 0.0) != (prj->pv[1] < 0.0)) { istat = 1; if (!status) status = PRJERR_BAD_WORLD_SET("cops2x"); } } } else { r = prj->w[2] - prj->w[3]*sind(t)/s; // Bounds checking. if (prj->bounds&1) { if (r*prj->w[0] < 0.0) { istat = 1; if (!status) status = PRJERR_BAD_WORLD_SET("cops2x"); } } } for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { *xp = r*(*xp) - prj->x0; *yp = -r*(*yp) - y0; *(statp++) = istat; } } return status; } /*============================================================================ * COE: conic equal area projection. * * Given: * prj->pv[1] sigma = (theta2+theta1)/2 * prj->pv[2] delta = (theta2-theta1)/2, where theta1 and theta2 are the * latitudes of the standard parallels, in degrees. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to sigma if undefined. * prj->theta0 Reset to sigma if undefined. * * Returned: * prj->flag COE * prj->code "COE" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->w[0] C = (sin(theta1) + sin(theta2))/2 * prj->w[1] 1/C * prj->w[2] Y0 = chi*sqrt(psi - 2C*sind(sigma)) * prj->w[3] chi = r0/C * prj->w[4] psi = 1 + sin(theta1)*sin(theta2) * prj->w[5] 2C * prj->w[6] (1 + sin(theta1)*sin(theta2))*(r0/C)**2 * prj->w[7] C/(2*r0**2) * prj->w[8] chi*sqrt(psi + 2C) * prj->prjx2s Pointer to coex2s(). * prj->prjs2x Pointer to coes2x(). *===========================================================================*/ int coeset(struct prjprm *prj) { double theta1, theta2; if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = COE; strcpy(prj->code, "COE"); strcpy(prj->name, "conic equal area"); if (undefined(prj->pv[1])) { return PRJERR_BAD_PARAM_SET("coeset"); } if (undefined(prj->pv[2])) prj->pv[2] = 0.0; if (prj->r0 == 0.0) prj->r0 = R2D; prj->category = CONIC; prj->pvrange = 102; prj->simplezen = 0; prj->equiareal = 1; prj->conformal = 0; prj->global = 1; prj->divergent = 0; theta1 = prj->pv[1] - prj->pv[2]; theta2 = prj->pv[1] + prj->pv[2]; prj->w[0] = (sind(theta1) + sind(theta2))/2.0; if (prj->w[0] == 0.0) { return PRJERR_BAD_PARAM_SET("coeset"); } prj->w[1] = 1.0/prj->w[0]; prj->w[3] = prj->r0/prj->w[0]; prj->w[4] = 1.0 + sind(theta1)*sind(theta2); prj->w[5] = 2.0*prj->w[0]; prj->w[6] = prj->w[3]*prj->w[3]*prj->w[4]; prj->w[7] = 1.0/(2.0*prj->r0*prj->w[3]); prj->w[8] = prj->w[3]*sqrt(prj->w[4] + prj->w[5]); prj->w[2] = prj->w[3]*sqrt(prj->w[4] - prj->w[5]*sind(prj->pv[1])); prj->prjx2s = coex2s; prj->prjs2x = coes2x; return prjoff(prj, 0.0, prj->pv[1]); } //---------------------------------------------------------------------------- int coex2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int mx, my, rowlen, rowoff, status; double alpha, dy, dy2, r, t, w, xj; const double tol = 1.0e-12; register int ix, iy, istat, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != COE) { if ((status = coeset(prj))) return status; } if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { xj = *xp + prj->x0; phip = phi + rowoff; for (iy = 0; iy < my; iy++) { *phip = xj; phip += rowlen; } } // Do y dependence. yp = y; phip = phi; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { dy = prj->w[2] - (*yp + prj->y0); dy2 = dy*dy; for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { xj = *phip; r = sqrt(xj*xj + dy2); if (prj->pv[1] < 0.0) r = -r; if (r == 0.0) { alpha = 0.0; } else { alpha = atan2d(xj/r, dy/r); } istat = 0; if (fabs(r - prj->w[8]) < tol) { t = -90.0; } else { w = (prj->w[6] - r*r)*prj->w[7]; if (fabs(w) > 1.0) { if (fabs(w-1.0) < tol) { t = 90.0; } else if (fabs(w+1.0) < tol) { t = -90.0; } else { t = 0.0; istat = 1; if (!status) status = PRJERR_BAD_PIX_SET("coex2s"); } } else { t = asind(w); } } *phip = alpha*prj->w[1]; *thetap = t; *(statp++) = istat; } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-13, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("coex2s"); } return status; } //---------------------------------------------------------------------------- int coes2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int mphi, mtheta, rowlen, rowoff, status; double alpha, cosalpha, r, sinalpha, y0; register int iphi, itheta, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != COE) { if ((status = coeset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { alpha = prj->w[0]*(*phip); sincosd(alpha, &sinalpha, &cosalpha); xp = x + rowoff; yp = y + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = sinalpha; *yp = cosalpha; xp += rowlen; yp += rowlen; } } // Do theta dependence. thetap = theta; xp = x; yp = y; statp = stat; y0 = prj->y0 - prj->w[2]; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { if (*thetap == -90.0) { r = prj->w[8]; } else { r = prj->w[3]*sqrt(prj->w[4] - prj->w[5]*sind(*thetap)); } for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { *xp = r*(*xp) - prj->x0; *yp = -r*(*yp) - y0; *(statp++) = 0; } } return 0; } /*============================================================================ * COD: conic equidistant projection. * * Given: * prj->pv[1] sigma = (theta2+theta1)/2 * prj->pv[2] delta = (theta2-theta1)/2, where theta1 and theta2 are the * latitudes of the standard parallels, in degrees. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to sigma if undefined. * prj->theta0 Reset to sigma if undefined. * * Returned: * prj->flag COD * prj->code "COD" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->w[0] C = r0*sin(sigma)*sin(delta)/delta * prj->w[1] 1/C * prj->w[2] Y0 = delta*cot(delta)*cot(sigma) * prj->w[3] Y0 + sigma * prj->prjx2s Pointer to codx2s(). * prj->prjs2x Pointer to cods2x(). *===========================================================================*/ int codset(struct prjprm *prj) { if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = COD; strcpy(prj->code, "COD"); strcpy(prj->name, "conic equidistant"); if (undefined(prj->pv[1])) { return PRJERR_BAD_PARAM_SET("codset"); } if (undefined(prj->pv[2])) prj->pv[2] = 0.0; if (prj->r0 == 0.0) prj->r0 = R2D; prj->category = CONIC; prj->pvrange = 102; prj->simplezen = 0; prj->equiareal = 0; prj->conformal = 0; prj->global = 1; prj->divergent = 0; if (prj->pv[2] == 0.0) { prj->w[0] = prj->r0*sind(prj->pv[1])*D2R; } else { prj->w[0] = prj->r0*sind(prj->pv[1])*sind(prj->pv[2])/prj->pv[2]; } if (prj->w[0] == 0.0) { return PRJERR_BAD_PARAM_SET("codset"); } prj->w[1] = 1.0/prj->w[0]; prj->w[2] = prj->r0*cosd(prj->pv[2])*cosd(prj->pv[1])/prj->w[0]; prj->w[3] = prj->w[2] + prj->pv[1]; prj->prjx2s = codx2s; prj->prjs2x = cods2x; return prjoff(prj, 0.0, prj->pv[1]); } //---------------------------------------------------------------------------- int codx2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int mx, my, rowlen, rowoff, status; double alpha, dy, dy2, r, xj; register int ix, iy, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != COD) { if ((status = codset(prj))) return status; } if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { xj = *xp + prj->x0; phip = phi + rowoff; for (iy = 0; iy < my; iy++) { *phip = xj; phip += rowlen; } } // Do y dependence. yp = y; phip = phi; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { dy = prj->w[2] - (*yp + prj->y0); dy2 = dy*dy; for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { xj = *phip; r = sqrt(xj*xj + dy2); if (prj->pv[1] < 0.0) r = -r; if (r == 0.0) { alpha = 0.0; } else { alpha = atan2d(xj/r, dy/r); } *phip = alpha*prj->w[1]; *thetap = prj->w[3] - r; *(statp++) = 0; } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-13, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("codx2s"); } return status; } //---------------------------------------------------------------------------- int cods2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int mphi, mtheta, rowlen, rowoff, status; double alpha, cosalpha, r, sinalpha, y0; register int iphi, itheta, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != COD) { if ((status = codset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { alpha = prj->w[0]*(*phip); sincosd(alpha, &sinalpha, &cosalpha); xp = x + rowoff; yp = y + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = sinalpha; *yp = cosalpha; xp += rowlen; yp += rowlen; } } // Do theta dependence. thetap = theta; xp = x; yp = y; statp = stat; y0 = prj->y0 - prj->w[2]; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { r = prj->w[3] - *thetap; for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { *xp = r*(*xp) - prj->x0; *yp = -r*(*yp) - y0; *(statp++) = 0; } } return 0; } /*============================================================================ * COO: conic orthomorphic projection. * * Given: * prj->pv[1] sigma = (theta2+theta1)/2 * prj->pv[2] delta = (theta2-theta1)/2, where theta1 and theta2 are the * latitudes of the standard parallels, in degrees. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to sigma if undefined. * prj->theta0 Reset to sigma if undefined. * * Returned: * prj->flag COO * prj->code "COO" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->w[0] C = ln(cos(theta2)/cos(theta1))/ln(tan(tau2)/tan(tau1)) * where tau1 = (90 - theta1)/2 * tau2 = (90 - theta2)/2 * prj->w[1] 1/C * prj->w[2] Y0 = psi*tan((90-sigma)/2)**C * prj->w[3] psi = (r0*cos(theta1)/C)/tan(tau1)**C * prj->w[4] 1/psi * prj->prjx2s Pointer to coox2s(). * prj->prjs2x Pointer to coos2x(). *===========================================================================*/ int cooset(struct prjprm *prj) { double cos1, cos2, tan1, tan2, theta1, theta2; if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = COO; strcpy(prj->code, "COO"); strcpy(prj->name, "conic orthomorphic"); if (undefined(prj->pv[1])) { return PRJERR_BAD_PARAM_SET("cooset"); } if (undefined(prj->pv[2])) prj->pv[2] = 0.0; if (prj->r0 == 0.0) prj->r0 = R2D; prj->category = CONIC; prj->pvrange = 102; prj->simplezen = 0; prj->equiareal = 0; prj->conformal = 1; prj->global = 0; prj->divergent = 1; theta1 = prj->pv[1] - prj->pv[2]; theta2 = prj->pv[1] + prj->pv[2]; tan1 = tand((90.0 - theta1)/2.0); cos1 = cosd(theta1); if (theta1 == theta2) { prj->w[0] = sind(theta1); } else { tan2 = tand((90.0 - theta2)/2.0); cos2 = cosd(theta2); prj->w[0] = log(cos2/cos1)/log(tan2/tan1); } if (prj->w[0] == 0.0) { return PRJERR_BAD_PARAM_SET("cooset"); } prj->w[1] = 1.0/prj->w[0]; prj->w[3] = prj->r0*(cos1/prj->w[0])/pow(tan1,prj->w[0]); if (prj->w[3] == 0.0) { return PRJERR_BAD_PARAM_SET("cooset"); } prj->w[2] = prj->w[3]*pow(tand((90.0 - prj->pv[1])/2.0),prj->w[0]); prj->w[4] = 1.0/prj->w[3]; prj->prjx2s = coox2s; prj->prjs2x = coos2x; return prjoff(prj, 0.0, prj->pv[1]); } //---------------------------------------------------------------------------- int coox2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int mx, my, rowlen, rowoff, status; double alpha, dy, dy2, r, t, xj; register int ix, iy, istat, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != COO) { if ((status = cooset(prj))) return status; } if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { xj = *xp + prj->x0; phip = phi + rowoff; for (iy = 0; iy < my; iy++) { *phip = xj; phip += rowlen; } } // Do y dependence. yp = y; phip = phi; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { dy = prj->w[2] - (*yp + prj->y0); dy2 = dy*dy; for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { xj = *phip; r = sqrt(xj*xj + dy2); if (prj->pv[1] < 0.0) r = -r; if (r == 0.0) { alpha = 0.0; } else { alpha = atan2d(xj/r, dy/r); } istat = 0; if (r == 0.0) { if (prj->w[0] < 0.0) { t = -90.0; } else { t = 0.0; istat = 1; if (!status) status = PRJERR_BAD_PIX_SET("coox2s"); } } else { t = 90.0 - 2.0*atand(pow(r*prj->w[4],prj->w[1])); } *phip = alpha*prj->w[1]; *thetap = t; *(statp++) = istat; } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-13, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("coox2s"); } return status; } //---------------------------------------------------------------------------- int coos2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int mphi, mtheta, rowlen, rowoff, status; double alpha, cosalpha, r, sinalpha, y0; register int iphi, itheta, istat, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != COO) { if ((status = cooset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } status = 0; // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { alpha = prj->w[0]*(*phip); sincosd(alpha, &sinalpha, &cosalpha); xp = x + rowoff; yp = y + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = sinalpha; *yp = cosalpha; xp += rowlen; yp += rowlen; } } // Do theta dependence. thetap = theta; xp = x; yp = y; statp = stat; y0 = prj->y0 - prj->w[2]; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { istat = 0; if (*thetap == -90.0) { r = 0.0; if (prj->w[0] >= 0.0) { istat = 1; if (!status) status = PRJERR_BAD_WORLD_SET("coos2x"); } } else { r = prj->w[3]*pow(tand((90.0 - *thetap)/2.0),prj->w[0]); } for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { *xp = r*(*xp) - prj->x0; *yp = -r*(*yp) - y0; *(statp++) = istat; } } return status; } /*============================================================================ * BON: Bonne's projection. * * Given: * prj->pv[1] Bonne conformal latitude, theta1, in degrees. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to 0.0 if undefined. * prj->theta0 Reset to 0.0 if undefined. * * Returned: * prj->flag BON * prj->code "BON" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->w[1] r0*pi/180 * prj->w[2] Y0 = r0*(cot(theta1) + theta1*pi/180) * prj->prjx2s Pointer to bonx2s(). * prj->prjs2x Pointer to bons2x(). *===========================================================================*/ int bonset(struct prjprm *prj) { if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = BON; strcpy(prj->code, "BON"); strcpy(prj->name, "Bonne's"); if (undefined(prj->pv[1])) { return PRJERR_BAD_PARAM_SET("bonset"); } if (prj->pv[1] == 0.0) { // Sanson-Flamsteed. return sflset(prj); } prj->category = POLYCONIC; prj->pvrange = 101; prj->simplezen = 0; prj->equiareal = 1; prj->conformal = 0; prj->global = 1; prj->divergent = 0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[1] = 1.0; prj->w[2] = prj->r0*cosd(prj->pv[1])/sind(prj->pv[1]) + prj->pv[1]; } else { prj->w[1] = prj->r0*D2R; prj->w[2] = prj->r0*(cosd(prj->pv[1])/sind(prj->pv[1]) + prj->pv[1]*D2R); } prj->prjx2s = bonx2s; prj->prjs2x = bons2x; return prjoff(prj, 0.0, 0.0); } //---------------------------------------------------------------------------- int bonx2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int mx, my, rowlen, rowoff, status; double alpha, dy, dy2, costhe, r, s, t, xj; register int ix, iy, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->pv[1] == 0.0) { // Sanson-Flamsteed. return sflx2s(prj, nx, ny, sxy, spt, x, y, phi, theta, stat); } if (prj->flag != BON) { if ((status = bonset(prj))) return status; } if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { xj = *xp + prj->x0; phip = phi + rowoff; for (iy = 0; iy < my; iy++) { *phip = xj; phip += rowlen; } } // Do y dependence. yp = y; phip = phi; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { dy = prj->w[2] - (*yp + prj->y0); dy2 = dy*dy; for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { xj = *phip; r = sqrt(xj*xj + dy2); if (prj->pv[1] < 0.0) r = -r; if (r == 0.0) { alpha = 0.0; } else { alpha = atan2d(xj/r, dy/r); } t = (prj->w[2] - r)/prj->w[1]; costhe = cosd(t); if (costhe == 0.0) { s = 0.0; } else { s = alpha*(r/prj->r0)/costhe; } *phip = s; *thetap = t; *(statp++) = 0; } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-11, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("bonx2s"); } return status; } //---------------------------------------------------------------------------- int bons2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int mphi, mtheta, rowlen, rowoff, status; double alpha, cosalpha, r, s, sinalpha, y0; register int iphi, itheta, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->pv[1] == 0.0) { // Sanson-Flamsteed. return sfls2x(prj, nphi, ntheta, spt, sxy, phi, theta, x, y, stat); } if (prj->flag != BON) { if ((status = bonset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } y0 = prj->y0 - prj->w[2]; // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { s = prj->r0*(*phip); xp = x + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = s; xp += rowlen; } } // Do theta dependence. thetap = theta; xp = x; yp = y; statp = stat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { r = prj->w[2] - prj->w[1]*(*thetap); s = cosd(*thetap)/r; for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { alpha = s*(*xp); sincosd(alpha, &sinalpha, &cosalpha); *xp = r*sinalpha - prj->x0; *yp = -r*cosalpha - y0; *(statp++) = 0; } } return 0; } /*============================================================================ * PCO: polyconic projection. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to 0.0 if undefined. * prj->theta0 Reset to 0.0 if undefined. * * Returned: * prj->flag PCO * prj->code "PCO" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->w[0] r0*(pi/180) * prj->w[1] (180/pi)/r0 * prj->w[2] 2*r0 * prj->w[3] (pi/180)/(2*r0) * prj->prjx2s Pointer to pcox2s(). * prj->prjs2x Pointer to pcos2x(). *===========================================================================*/ int pcoset(struct prjprm *prj) { if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = PCO; strcpy(prj->code, "PCO"); strcpy(prj->name, "polyconic"); prj->category = POLYCONIC; prj->pvrange = 0; prj->simplezen = 0; prj->equiareal = 0; prj->conformal = 0; prj->global = 1; prj->divergent = 0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 1.0; prj->w[1] = 1.0; prj->w[2] = 360.0/PI; } else { prj->w[0] = prj->r0*D2R; prj->w[1] = 1.0/prj->w[0]; prj->w[2] = 2.0*prj->r0; } prj->w[3] = D2R/prj->w[2]; prj->prjx2s = pcox2s; prj->prjs2x = pcos2x; return prjoff(prj, 0.0, 0.0); } //---------------------------------------------------------------------------- int pcox2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int mx, my, rowlen, rowoff, status; double f, fneg, fpos, lambda, tanthe, the, theneg, thepos, w, x1, xj, xx, yj, ymthe, y1; const double tol = 1.0e-12; register int ix, iy, k, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != PCO) { if ((status = pcoset(prj))) return status; } if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { xj = *xp + prj->x0; phip = phi + rowoff; for (iy = 0; iy < my; iy++) { *phip = xj; phip += rowlen; } } // Do y dependence. yp = y; phip = phi; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { yj = *yp + prj->y0; w = fabs(yj*prj->w[1]); for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { xj = *phip; if (w < tol) { *phip = xj*prj->w[1]; *thetap = 0.0; } else if (fabs(w-90.0) < tol) { *phip = 0.0; *thetap = copysign(90.0, yj); } else { if (w < 1.0e-4) { // To avoid cot(theta) blowing up near theta == 0. the = yj / (prj->w[0] + prj->w[3]*xj*xj); ymthe = yj - prj->w[0]*the; tanthe = tand(the); } else { // Iterative solution using weighted division of the interval. thepos = yj / prj->w[0]; theneg = 0.0; // Setting fneg = -fpos halves the interval in the first iter. xx = xj*xj; fpos = xx; fneg = -xx; for (k = 0; k < 64; k++) { // Weighted division of the interval. lambda = fpos/(fpos-fneg); if (lambda < 0.1) { lambda = 0.1; } else if (lambda > 0.9) { lambda = 0.9; } the = thepos - lambda*(thepos-theneg); // Compute the residue. ymthe = yj - prj->w[0]*the; tanthe = tand(the); f = xx + ymthe*(ymthe - prj->w[2]/tanthe); // Check for convergence. if (fabs(f) < tol) break; if (fabs(thepos-theneg) < tol) break; // Redefine the interval. if (f > 0.0) { thepos = the; fpos = f; } else { theneg = the; fneg = f; } } } x1 = prj->r0 - ymthe*tanthe; y1 = xj*tanthe; if (x1 == 0.0 && y1 == 0.0) { *phip = 0.0; } else { *phip = atan2d(y1, x1)/sind(the); } *thetap = the; } *(statp++) = 0; } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-12, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("pcox2s"); } return status; } //---------------------------------------------------------------------------- int pcos2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int mphi, mtheta, rowlen, rowoff, status; double cospsi, costhe, cotthe, sinpsi, sinthe, therad; register int iphi, itheta, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != PCO) { if ((status = pcoset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { xp = x + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = *phip; xp += rowlen; } } // Do theta dependence. thetap = theta; xp = x; yp = y; statp = stat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { if (*thetap == 0.0) { for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { *xp = prj->w[0]*(*xp) - prj->x0; *yp = -prj->y0; *(statp++) = 0; } } else if (fabs(*thetap) < 1.0e-4) { // To avoid cot(theta) blowing up near theta == 0. for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { *xp = prj->w[0]*(*xp)*cosd(*thetap) - prj->x0; *yp = (prj->w[0] + prj->w[3]*(*xp)*(*xp))*(*thetap) - prj->y0; *(statp++) = 0; } } else { therad = (*thetap)*D2R; sincosd(*thetap, &sinthe, &costhe); for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { sincosd((*xp)*sinthe, &sinpsi, &cospsi); cotthe = costhe/sinthe; *xp = prj->r0*cotthe*sinpsi - prj->x0; *yp = prj->r0*(cotthe*(1.0 - cospsi) + therad) - prj->y0; *(statp++) = 0; } } } return 0; } /*============================================================================ * TSC: tangential spherical cube projection. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to 0.0 if undefined. * prj->theta0 Reset to 0.0 if undefined. * * Returned: * prj->flag TSC * prj->code "TSC" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->w[0] r0*(pi/4) * prj->w[1] (4/pi)/r0 * prj->prjx2s Pointer to tscx2s(). * prj->prjs2x Pointer to tscs2x(). *===========================================================================*/ int tscset(struct prjprm *prj) { if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = TSC; strcpy(prj->code, "TSC"); strcpy(prj->name, "tangential spherical cube"); prj->category = QUADCUBE; prj->pvrange = 0; prj->simplezen = 0; prj->equiareal = 0; prj->conformal = 0; prj->global = 1; prj->divergent = 0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 45.0; prj->w[1] = 1.0/45.0; } else { prj->w[0] = prj->r0*PI/4.0; prj->w[1] = 1.0/prj->w[0]; } prj->prjx2s = tscx2s; prj->prjs2x = tscs2x; return prjoff(prj, 0.0, 0.0); } //---------------------------------------------------------------------------- int tscx2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int mx, my, rowlen, rowoff, status; double l, m, n, xf, yf; register int ix, iy, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != TSC) { if ((status = tscset(prj))) return status; } if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { xf = (*xp + prj->x0)*prj->w[1]; phip = phi + rowoff; for (iy = 0; iy < my; iy++) { *phip = xf; phip += rowlen; } } // Do y dependence. yp = y; phip = phi; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { yf = (*yp + prj->y0)*prj->w[1]; for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { xf = *phip; // Bounds checking. if (fabs(xf) <= 1.0) { if (fabs(yf) > 3.0) { *phip = 0.0; *thetap = 0.0; *(statp++) = 1; if (!status) status = PRJERR_BAD_PIX_SET("tscx2s"); continue; } } else { if (fabs(xf) > 7.0 || fabs(yf) > 1.0) { *phip = 0.0; *thetap = 0.0; *(statp++) = 1; if (!status) status = PRJERR_BAD_PIX_SET("tscx2s"); continue; } } // Map negative faces to the other side. if (xf < -1.0) xf += 8.0; // Determine the face. if (xf > 5.0) { // face = 4 xf = xf - 6.0; m = -1.0/sqrt(1.0 + xf*xf + yf*yf); l = -m*xf; n = -m*yf; } else if (xf > 3.0) { // face = 3 xf = xf - 4.0; l = -1.0/sqrt(1.0 + xf*xf + yf*yf); m = l*xf; n = -l*yf; } else if (xf > 1.0) { // face = 2 xf = xf - 2.0; m = 1.0/sqrt(1.0 + xf*xf + yf*yf); l = -m*xf; n = m*yf; } else if (yf > 1.0) { // face = 0 yf = yf - 2.0; n = 1.0/sqrt(1.0 + xf*xf + yf*yf); l = -n*yf; m = n*xf; } else if (yf < -1.0) { // face = 5 yf = yf + 2.0; n = -1.0/sqrt(1.0 + xf*xf + yf*yf); l = -n*yf; m = -n*xf; } else { // face = 1 l = 1.0/sqrt(1.0 + xf*xf + yf*yf); m = l*xf; n = l*yf; } if (l == 0.0 && m == 0.0) { *phip = 0.0; } else { *phip = atan2d(m, l); } *thetap = asind(n); *(statp++) = 0; } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-13, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("tscx2s"); } return status; } //---------------------------------------------------------------------------- int tscs2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int face, mphi, mtheta, rowlen, rowoff, status; double cosphi, costhe, l, m, n, sinphi, sinthe, x0, xf, y0, yf, zeta; const double tol = 1.0e-12; register int iphi, istat, itheta, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != TSC) { if ((status = tscset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } status = 0; // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { sincosd(*phip, &sinphi, &cosphi); xp = x + rowoff; yp = y + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = cosphi; *yp = sinphi; xp += rowlen; yp += rowlen; } } // Do theta dependence. thetap = theta; xp = x; yp = y; statp = stat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { sincosd(*thetap, &sinthe, &costhe); for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { l = costhe*(*xp); m = costhe*(*yp); n = sinthe; face = 0; zeta = n; if (l > zeta) { face = 1; zeta = l; } if (m > zeta) { face = 2; zeta = m; } if (-l > zeta) { face = 3; zeta = -l; } if (-m > zeta) { face = 4; zeta = -m; } if (-n > zeta) { face = 5; zeta = -n; } switch (face) { case 1: xf = m/zeta; yf = n/zeta; x0 = 0.0; y0 = 0.0; break; case 2: xf = -l/zeta; yf = n/zeta; x0 = 2.0; y0 = 0.0; break; case 3: xf = -m/zeta; yf = n/zeta; x0 = 4.0; y0 = 0.0; break; case 4: xf = l/zeta; yf = n/zeta; x0 = 6.0; y0 = 0.0; break; case 5: xf = m/zeta; yf = l/zeta; x0 = 0.0; y0 = -2.0; break; default: // face == 0 xf = m/zeta; yf = -l/zeta; x0 = 0.0; y0 = 2.0; break; } istat = 0; if (fabs(xf) > 1.0) { if (fabs(xf) > 1.0+tol) { istat = 1; if (!status) status = PRJERR_BAD_WORLD_SET("tscs2x"); } xf = copysign(1.0, xf); } if (fabs(yf) > 1.0) { if (fabs(yf) > 1.0+tol) { istat = 1; if (!status) status = PRJERR_BAD_WORLD_SET("tscs2x"); } yf = copysign(1.0, yf); } *xp = prj->w[0]*(xf + x0) - prj->x0; *yp = prj->w[0]*(yf + y0) - prj->y0; *(statp++) = istat; } } return status; } /*============================================================================ * CSC: COBE quadrilateralized spherical cube projection. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to 0.0 if undefined. * prj->theta0 Reset to 0.0 if undefined. * * Returned: * prj->flag CSC * prj->code "CSC" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->w[0] r0*(pi/4) * prj->w[1] (4/pi)/r0 * prj->prjx2s Pointer to cscx2s(). * prj->prjs2x Pointer to cscs2x(). *===========================================================================*/ int cscset(struct prjprm *prj) { if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = CSC; strcpy(prj->code, "CSC"); strcpy(prj->name, "COBE quadrilateralized spherical cube"); prj->category = QUADCUBE; prj->pvrange = 0; prj->simplezen = 0; prj->equiareal = 0; prj->conformal = 0; prj->global = 1; prj->divergent = 0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 45.0; prj->w[1] = 1.0/45.0; } else { prj->w[0] = prj->r0*PI/4.0; prj->w[1] = 1.0/prj->w[0]; } prj->prjx2s = cscx2s; prj->prjs2x = cscs2x; return prjoff(prj, 0.0, 0.0); } //---------------------------------------------------------------------------- int cscx2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int face, mx, my, rowlen, rowoff, status; double l, m, n, t; register int ix, iy, *statp; register const double *xp, *yp; register double *phip, *thetap; float chi, psi, xf, xx, yf, yy, z0, z1, z2, z3, z4, z5, z6; const float p00 = -0.27292696f; const float p10 = -0.07629969f; const float p20 = -0.22797056f; const float p30 = 0.54852384f; const float p40 = -0.62930065f; const float p50 = 0.25795794f; const float p60 = 0.02584375f; const float p01 = -0.02819452f; const float p11 = -0.01471565f; const float p21 = 0.48051509f; const float p31 = -1.74114454f; const float p41 = 1.71547508f; const float p51 = -0.53022337f; const float p02 = 0.27058160f; const float p12 = -0.56800938f; const float p22 = 0.30803317f; const float p32 = 0.98938102f; const float p42 = -0.83180469f; const float p03 = -0.60441560f; const float p13 = 1.50880086f; const float p23 = -0.93678576f; const float p33 = 0.08693841f; const float p04 = 0.93412077f; const float p14 = -1.41601920f; const float p24 = 0.33887446f; const float p05 = -0.63915306f; const float p15 = 0.52032238f; const float p06 = 0.14381585f; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != CSC) { if ((status = cscset(prj))) return status; } if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { xf = (float)((*xp + prj->x0)*prj->w[1]); phip = phi + rowoff; for (iy = 0; iy < my; iy++) { *phip = xf; phip += rowlen; } } // Do y dependence. yp = y; phip = phi; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { yf = (float)((*yp + prj->y0)*prj->w[1]); for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { xf = (float)(*phip); // Bounds checking. if (fabs((double)xf) <= 1.0) { if (fabs((double)yf) > 3.0) { *phip = 0.0; *thetap = 0.0; *(statp++) = 1; if (!status) status = PRJERR_BAD_PIX_SET("cscx2s"); continue; } } else { if (fabs((double)xf) > 7.0 || fabs((double)yf) > 1.0) { *phip = 0.0; *thetap = 0.0; *(statp++) = 1; if (!status) status = PRJERR_BAD_PIX_SET("cscx2s"); continue; } } // Map negative faces to the other side. if (xf < -1.0f) xf += 8.0f; // Determine the face. if (xf > 5.0f) { face = 4; xf = xf - 6.0f; } else if (xf > 3.0f) { face = 3; xf = xf - 4.0f; } else if (xf > 1.0f) { face = 2; xf = xf - 2.0f; } else if (yf > 1.0f) { face = 0; yf = yf - 2.0f; } else if (yf < -1.0f) { face = 5; yf = yf + 2.0f; } else { face = 1; } xx = xf*xf; yy = yf*yf; z0 = p00 + xx*(p10 + xx*(p20 + xx*(p30 + xx*(p40 + xx*(p50 + xx*(p60)))))); z1 = p01 + xx*(p11 + xx*(p21 + xx*(p31 + xx*(p41 + xx*(p51))))); z2 = p02 + xx*(p12 + xx*(p22 + xx*(p32 + xx*(p42)))); z3 = p03 + xx*(p13 + xx*(p23 + xx*(p33))); z4 = p04 + xx*(p14 + xx*(p24)); z5 = p05 + xx*(p15); z6 = p06; chi = z0 + yy*(z1 + yy*(z2 + yy*(z3 + yy*(z4 + yy*(z5 + yy*z6))))); chi = xf + xf*(1.0f - xx)*chi; z0 = p00 + yy*(p10 + yy*(p20 + yy*(p30 + yy*(p40 + yy*(p50 + yy*(p60)))))); z1 = p01 + yy*(p11 + yy*(p21 + yy*(p31 + yy*(p41 + yy*(p51))))); z2 = p02 + yy*(p12 + yy*(p22 + yy*(p32 + yy*(p42)))); z3 = p03 + yy*(p13 + yy*(p23 + yy*(p33))); z4 = p04 + yy*(p14 + yy*(p24)); z5 = p05 + yy*(p15); z6 = p06; psi = z0 + xx*(z1 + xx*(z2 + xx*(z3 + xx*(z4 + xx*(z5 + xx*z6))))); psi = yf + yf*(1.0f - yy)*psi; t = 1.0/sqrt((double)(chi*chi + psi*psi) + 1.0); switch (face) { case 1: l = t; m = chi*l; n = psi*l; break; case 2: m = t; l = -chi*m; n = psi*m; break; case 3: l = -t; m = chi*l; n = -psi*l; break; case 4: m = -t; l = -chi*m; n = -psi*m; break; case 5: n = -t; l = -psi*n; m = -chi*n; break; default: // face == 0 n = t; l = -psi*n; m = chi*n; break; } if (l == 0.0 && m == 0.0) { *phip = 0.0; } else { *phip = atan2d(m, l); } *thetap = asind(n); *(statp++) = 0; } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-13, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("cscx2s"); } return status; } //---------------------------------------------------------------------------- int cscs2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int face, mphi, mtheta, rowlen, rowoff, status; double cosphi, costhe, eta, l, m, n, sinphi, sinthe, xi, zeta; const double tol = 1.0e-7; register int iphi, istat, itheta, *statp; register const double *phip, *thetap; register double *xp, *yp; float chi, chi2, chi2psi2, chi4, chipsi, psi, psi2, psi4, chi2co, psi2co, x0, xf, y0, yf; const float gstar = 1.37484847732f; const float mm = 0.004869491981f; const float gamma = -0.13161671474f; const float omega1 = -0.159596235474f; const float d0 = 0.0759196200467f; const float d1 = -0.0217762490699f; const float c00 = 0.141189631152f; const float c10 = 0.0809701286525f; const float c01 = -0.281528535557f; const float c11 = 0.15384112876f; const float c20 = -0.178251207466f; const float c02 = 0.106959469314f; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != CSC) { if ((status = cscset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } status = 0; // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { sincosd(*phip, &sinphi, &cosphi); xp = x + rowoff; yp = y + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = cosphi; *yp = sinphi; xp += rowlen; yp += rowlen; } } // Do theta dependence. thetap = theta; xp = x; yp = y; statp = stat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { sincosd(*thetap, &sinthe, &costhe); for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { l = costhe*(*xp); m = costhe*(*yp); n = sinthe; face = 0; zeta = n; if (l > zeta) { face = 1; zeta = l; } if (m > zeta) { face = 2; zeta = m; } if (-l > zeta) { face = 3; zeta = -l; } if (-m > zeta) { face = 4; zeta = -m; } if (-n > zeta) { face = 5; zeta = -n; } switch (face) { case 1: xi = m; eta = n; x0 = 0.0; y0 = 0.0; break; case 2: xi = -l; eta = n; x0 = 2.0; y0 = 0.0; break; case 3: xi = -m; eta = n; x0 = 4.0; y0 = 0.0; break; case 4: xi = l; eta = n; x0 = 6.0; y0 = 0.0; break; case 5: xi = m; eta = l; x0 = 0.0; y0 = -2.0; break; default: // face == 0 xi = m; eta = -l; x0 = 0.0; y0 = 2.0; break; } chi = (float)( xi/zeta); psi = (float)(eta/zeta); chi2 = chi*chi; psi2 = psi*psi; chi2co = 1.0f - chi2; psi2co = 1.0f - psi2; // Avoid floating underflows. chipsi = (float)fabs((double)(chi*psi)); chi4 = (chi2 > 1.0e-16f) ? chi2*chi2 : 0.0f; psi4 = (psi2 > 1.0e-16f) ? psi2*psi2 : 0.0f; chi2psi2 = (chipsi > 1.0e-16f) ? chi2*psi2 : 0.0f; xf = chi*(chi2 + chi2co*(gstar + psi2*(gamma*chi2co + mm*chi2 + psi2co*(c00 + c10*chi2 + c01*psi2 + c11*chi2psi2 + c20*chi4 + c02*psi4)) + chi2*(omega1 - chi2co*(d0 + d1*chi2)))); yf = psi*(psi2 + psi2co*(gstar + chi2*(gamma*psi2co + mm*psi2 + chi2co*(c00 + c10*psi2 + c01*chi2 + c11*chi2psi2 + c20*psi4 + c02*chi4)) + psi2*(omega1 - psi2co*(d0 + d1*psi2)))); istat = 0; if (fabs((double)xf) > 1.0) { if (fabs((double)xf) > 1.0+tol) { istat = 1; if (!status) status = PRJERR_BAD_WORLD_SET("cscs2x"); } xf = (float)copysign(1.0, (double)xf); } if (fabs((double)yf) > 1.0) { if (fabs((double)yf) > 1.0+tol) { istat = 1; if (!status) status = PRJERR_BAD_WORLD_SET("cscs2x"); } yf = (float)copysign(1.0, (double)yf); } *xp = prj->w[0]*(xf + x0) - prj->x0; *yp = prj->w[0]*(yf + y0) - prj->y0; *(statp++) = istat; } } return status; } /*============================================================================ * QSC: quadrilaterilized spherical cube projection. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to 0.0 if undefined. * prj->theta0 Reset to 0.0 if undefined. * * Returned: * prj->flag QSC * prj->code "QSC" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->w[0] r0*(pi/4) * prj->w[1] (4/pi)/r0 * prj->prjx2s Pointer to qscx2s(). * prj->prjs2x Pointer to qscs2x(). *===========================================================================*/ int qscset(struct prjprm *prj) { if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = QSC; strcpy(prj->code, "QSC"); strcpy(prj->name, "quadrilateralized spherical cube"); prj->category = QUADCUBE; prj->pvrange = 0; prj->simplezen = 0; prj->equiareal = 1; prj->conformal = 0; prj->global = 1; prj->divergent = 0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 45.0; prj->w[1] = 1.0/45.0; } else { prj->w[0] = prj->r0*PI/4.0; prj->w[1] = 1.0/prj->w[0]; } prj->prjx2s = qscx2s; prj->prjs2x = qscs2x; return prjoff(prj, 0.0, 0.0); } //---------------------------------------------------------------------------- int qscx2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int direct, face, mx, my, rowlen, rowoff, status; double cosw, l, m, n, omega, sinw, tau, xf, yf, w, zeco, zeta; const double tol = 1.0e-12; register int ix, iy, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != QSC) { if ((status = qscset(prj))) return status; } if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { xf = (*xp + prj->x0)*prj->w[1]; phip = phi + rowoff; for (iy = 0; iy < my; iy++) { *phip = xf; phip += rowlen; } } // Do y dependence. yp = y; phip = phi; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { yf = (*yp + prj->y0)*prj->w[1]; for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { xf = *phip; // Bounds checking. if (fabs(xf) <= 1.0) { if (fabs(yf) > 3.0) { *phip = 0.0; *thetap = 0.0; *(statp++) = 1; if (!status) status = PRJERR_BAD_PIX_SET("qscx2s"); continue; } } else { if (fabs(xf) > 7.0 || fabs(yf) > 1.0) { *phip = 0.0; *thetap = 0.0; *(statp++) = 1; if (!status) status = PRJERR_BAD_PIX_SET("qscx2s"); continue; } } // Map negative faces to the other side. if (xf < -1.0) xf += 8.0; // Determine the face. if (xf > 5.0) { face = 4; xf -= 6.0; } else if (xf > 3.0) { face = 3; xf -= 4.0; } else if (xf > 1.0) { face = 2; xf -= 2.0; } else if (yf > 1.0) { face = 0; yf -= 2.0; } else if (yf < -1.0) { face = 5; yf += 2.0; } else { face = 1; } direct = (fabs(xf) > fabs(yf)); if (direct) { if (xf == 0.0) { omega = 0.0; tau = 1.0; zeta = 1.0; zeco = 0.0; } else { w = 15.0*yf/xf; omega = sind(w)/(cosd(w) - SQRT2INV); tau = 1.0 + omega*omega; zeco = xf*xf*(1.0 - 1.0/sqrt(1.0 + tau)); zeta = 1.0 - zeco; } } else { if (yf == 0.0) { omega = 0.0; tau = 1.0; zeta = 1.0; zeco = 0.0; } else { w = 15.0*xf/yf; sincosd(w, &sinw, &cosw); omega = sinw/(cosw - SQRT2INV); tau = 1.0 + omega*omega; zeco = yf*yf*(1.0 - 1.0/sqrt(1.0 + tau)); zeta = 1.0 - zeco; } } if (zeta < -1.0) { if (zeta < -1.0-tol) { *phip = 0.0; *thetap = 0.0; *(statp++) = 1; if (!status) status = PRJERR_BAD_PIX_SET("qscx2s"); continue; } zeta = -1.0; zeco = 2.0; w = 0.0; } else { w = sqrt(zeco*(2.0-zeco)/tau); } switch (face) { case 1: l = zeta; if (direct) { m = w; if (xf < 0.0) m = -m; n = m*omega; } else { n = w; if (yf < 0.0) n = -n; m = n*omega; } break; case 2: m = zeta; if (direct) { l = w; if (xf > 0.0) l = -l; n = -l*omega; } else { n = w; if (yf < 0.0) n = -n; l = -n*omega; } break; case 3: l = -zeta; if (direct) { m = w; if (xf > 0.0) m = -m; n = -m*omega; } else { n = w; if (yf < 0.0) n = -n; m = -n*omega; } break; case 4: m = -zeta; if (direct) { l = w; if (xf < 0.0) l = -l; n = l*omega; } else { n = w; if (yf < 0.0) n = -n; l = n*omega; } break; case 5: n = -zeta; if (direct) { m = w; if (xf < 0.0) m = -m; l = m*omega; } else { l = w; if (yf < 0.0) l = -l; m = l*omega; } break; default: // face == 0 n = zeta; if (direct) { m = w; if (xf < 0.0) m = -m; l = -m*omega; } else { l = w; if (yf > 0.0) l = -l; m = -l*omega; } break; } if (l == 0.0 && m == 0.0) { *phip = 0.0; } else { *phip = atan2d(m, l); } *thetap = asind(n); *(statp++) = 0; } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-13, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("qscx2s"); } return status; } //---------------------------------------------------------------------------- int qscs2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int face, mphi, mtheta, rowlen, rowoff, status; double cosphi, costhe, eta, l, m, n, omega, p, sinphi, sinthe, t, tau, x0, xf, xi, y0, yf, zeco, zeta; const double tol = 1.0e-12; register int iphi, istat, itheta, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != QSC) { if ((status = qscset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } status = 0; // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { sincosd(*phip, &sinphi, &cosphi); xp = x + rowoff; yp = y + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *xp = cosphi; *yp = sinphi; xp += rowlen; yp += rowlen; } } // Do theta dependence. thetap = theta; xp = x; yp = y; statp = stat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { sincosd(*thetap, &sinthe, &costhe); for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { if (fabs(*thetap) == 90.0) { *xp = -prj->x0; *yp = copysign(2.0*prj->w[0], *thetap) - prj->y0; *(statp++) = 0; continue; } l = costhe*(*xp); m = costhe*(*yp); n = sinthe; face = 0; zeta = n; if (l > zeta) { face = 1; zeta = l; } if (m > zeta) { face = 2; zeta = m; } if (-l > zeta) { face = 3; zeta = -l; } if (-m > zeta) { face = 4; zeta = -m; } if (-n > zeta) { face = 5; zeta = -n; } zeco = 1.0 - zeta; switch (face) { case 1: xi = m; eta = n; if (zeco < 1.0e-8) { // Small angle formula. t = (*thetap)*D2R; p = atan2(*yp, *xp); zeco = (p*p + t*t)/2.0; } x0 = 0.0; y0 = 0.0; break; case 2: xi = -l; eta = n; if (zeco < 1.0e-8) { // Small angle formula. t = (*thetap)*D2R; p = atan2(*yp, *xp) - PI/2.0; zeco = (p*p + t*t)/2.0; } x0 = 2.0; y0 = 0.0; break; case 3: xi = -m; eta = n; if (zeco < 1.0e-8) { // Small angle formula. t = (*thetap)*D2R; p = atan2(*yp, *xp); p -= copysign(PI, p); zeco = (p*p + t*t)/2.0; } x0 = 4.0; y0 = 0.0; break; case 4: xi = l; eta = n; if (zeco < 1.0e-8) { // Small angle formula. t = (*thetap)*D2R; p = atan2(*yp, *xp) + PI/2.0; zeco = (p*p + t*t)/2.0; } x0 = 6; y0 = 0.0; break; case 5: xi = m; eta = l; if (zeco < 1.0e-8) { // Small angle formula. t = (*thetap + 90.0)*D2R; zeco = t*t/2.0; } x0 = 0.0; y0 = -2; break; default: // face == 0 xi = m; eta = -l; if (zeco < 1.0e-8) { // Small angle formula. t = (90.0 - *thetap)*D2R; zeco = t*t/2.0; } x0 = 0.0; y0 = 2.0; break; } xf = 0.0; yf = 0.0; if (xi != 0.0 || eta != 0.0) { if (-xi > fabs(eta)) { omega = eta/xi; tau = 1.0 + omega*omega; xf = -sqrt(zeco/(1.0 - 1.0/sqrt(1.0+tau))); yf = (xf/15.0)*(atand(omega) - asind(omega/sqrt(tau+tau))); } else if (xi > fabs(eta)) { omega = eta/xi; tau = 1.0 + omega*omega; xf = sqrt(zeco/(1.0 - 1.0/sqrt(1.0+tau))); yf = (xf/15.0)*(atand(omega) - asind(omega/sqrt(tau+tau))); } else if (-eta >= fabs(xi)) { omega = xi/eta; tau = 1.0 + omega*omega; yf = -sqrt(zeco/(1.0 - 1.0/sqrt(1.0+tau))); xf = (yf/15.0)*(atand(omega) - asind(omega/sqrt(tau+tau))); } else if (eta >= fabs(xi)) { omega = xi/eta; tau = 1.0 + omega*omega; yf = sqrt(zeco/(1.0 - 1.0/sqrt(1.0+tau))); xf = (yf/15.0)*(atand(omega) - asind(omega/sqrt(tau+tau))); } } istat = 0; if (fabs(xf) > 1.0) { if (fabs(xf) > 1.0+tol) { istat = 1; if (!status) status = PRJERR_BAD_WORLD_SET("qscs2x"); } xf = copysign(1.0, xf); } if (fabs(yf) > 1.0) { if (fabs(yf) > 1.0+tol) { istat = 1; if (!status) status = PRJERR_BAD_WORLD_SET("qscs2x"); } yf = copysign(1.0, yf); } *xp = prj->w[0]*(xf + x0) - prj->x0; *yp = prj->w[0]*(yf + y0) - prj->y0; *(statp++) = istat; } } return status; } /*============================================================================ * HPX: HEALPix projection. * * Given: * prj->pv[1] H - the number of facets in longitude. * prj->pv[2] K - the number of facets in latitude * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to 0.0 if undefined. * prj->theta0 Reset to 0.0 if undefined. * * Returned: * prj->flag HPX * prj->code "HPX" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->m True if H is odd. * prj->n True if K is odd. * prj->w[0] r0*(pi/180) * prj->w[1] (180/pi)/r0 * prj->w[2] (K-1)/K * prj->w[3] 90*K/H * prj->w[4] (K+1)/2 * prj->w[5] 90*(K-1)/H * prj->w[6] 180/H * prj->w[7] H/360 * prj->w[8] r0*(pi/180)*(90*K/H) * prj->w[9] r0*(pi/180)*(180/H) * prj->prjx2s Pointer to hpxx2s(). * prj->prjs2x Pointer to hpxs2x(). *===========================================================================*/ int hpxset(struct prjprm *prj) { if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = HPX; strcpy(prj->code, "HPX"); if (undefined(prj->pv[1])) prj->pv[1] = 4.0; if (undefined(prj->pv[2])) prj->pv[2] = 3.0; strcpy(prj->name, "HEALPix"); prj->category = HEALPIX; prj->pvrange = 102; prj->simplezen = 0; prj->equiareal = 1; prj->conformal = 0; prj->global = 1; prj->divergent = 0; if (prj->pv[1] <= 0.0 || prj->pv[2] <= 0.0) { return PRJERR_BAD_PARAM_SET("hpxset"); } prj->m = ((int)(prj->pv[1]+0.5))%2; prj->n = ((int)(prj->pv[2]+0.5))%2; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 1.0; prj->w[1] = 1.0; } else { prj->w[0] = prj->r0*D2R; prj->w[1] = R2D/prj->r0; } prj->w[2] = (prj->pv[2] - 1.0) / prj->pv[2]; prj->w[3] = 90.0 * prj->pv[2] / prj->pv[1]; prj->w[4] = (prj->pv[2] + 1.0) / 2.0; prj->w[5] = 90.0 * (prj->pv[2] - 1.0) / prj->pv[1]; prj->w[6] = 180.0 / prj->pv[1]; prj->w[7] = prj->pv[1] / 360.0; prj->w[8] = prj->w[3] * prj->w[0]; prj->w[9] = prj->w[6] * prj->w[0]; prj->prjx2s = hpxx2s; prj->prjs2x = hpxs2x; return prjoff(prj, 0.0, 0.0); } //---------------------------------------------------------------------------- int hpxx2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int h, mx, my, offset, rowlen, rowoff, status; double absy, r, s, sigma, slim, t, ylim, yr; register int istat, ix, iy, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != HPX) { if ((status = hpxset(prj))) return status; } slim = prj->w[6] + 1e-12; ylim = prj->w[9] * prj->w[4]; if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { s = prj->w[1] * (*xp + prj->x0); // x_c for K odd or theta > 0. t = -180.0 + (2.0 * floor((*xp + 180.0) * prj->w[7]) + 1.0) * prj->w[6]; t = prj->w[1] * (*xp - t); phip = phi + rowoff; thetap = theta + rowoff; for (iy = 0; iy < my; iy++) { // theta[] is used to hold (x - x_c). *phip = s; *thetap = t; phip += rowlen; thetap += rowlen; } } // Do y dependence. yp = y; phip = phi; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { yr = prj->w[1]*(*yp + prj->y0); absy = fabs(yr); istat = 0; if (absy <= prj->w[5]) { // Equatorial regime. t = asind(yr/prj->w[3]); for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { *thetap = t; *(statp++) = 0; } } else if (absy <= ylim) { // Polar regime. offset = (prj->n || *yp > 0.0) ? 0 : 1; sigma = prj->w[4] - absy / prj->w[6]; if (sigma == 0.0) { s = 1e9; t = 90.0; } else { t = 1.0 - sigma*sigma/prj->pv[2]; if (t < -1.0) { s = 0.0; t = 0.0; istat = 1; if (!status) status = PRJERR_BAD_PIX_SET("hpxx2s"); } else { s = 1.0/sigma; t = asind(t); } } if (*yp < 0.0) t = -t; for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { if (offset) { // Offset the southern polar half-facets for even K. h = (int)floor(*phip / prj->w[6]) + prj->m; if (h%2) { *thetap -= prj->w[6]; } else { *thetap += prj->w[6]; } } // Recall that theta[] holds (x - x_c). r = s * *thetap; // Bounds checking. if (prj->bounds&2) { if (slim <= fabs(r)) { istat = 1; if (!status) status = PRJERR_BAD_PIX_SET("hpxx2s"); } } if (r != 0.0) r -= *thetap; *phip += r; *thetap = t; *(statp++) = istat; } } else { // Beyond latitude range. for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { *phip = 0.0; *thetap = 0.0; *(statp++) = 1; } if (!status) status = PRJERR_BAD_PIX_SET("hpxx2s"); } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-12, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("hpxx2s"); } return status; } //---------------------------------------------------------------------------- int hpxs2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int h, mphi, mtheta, offset, rowlen, rowoff, status; double abssin, eta, sigma, sinthe, t, xi; register int iphi, itheta, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != HPX) { if ((status = hpxset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { xi = prj->w[0] * (*phip) - prj->x0; // phi_c for K odd or theta > 0. t = -180.0 + (2.0*floor((*phip+180.0) * prj->w[7]) + 1.0) * prj->w[6]; t = prj->w[0] * (*phip - t); xp = x + rowoff; yp = y + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { // y[] is used to hold (phi - phi_c). *xp = xi; *yp = t; xp += rowlen; yp += rowlen; } } // Do theta dependence. thetap = theta; xp = x; yp = y; statp = stat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { sinthe = sind(*thetap); abssin = fabs(sinthe); if (abssin <= prj->w[2]) { // Equatorial regime. eta = prj->w[8] * sinthe - prj->y0; for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { *yp = eta; *(statp++) = 0; } } else { // Polar regime. offset = (prj->n || *thetap > 0.0) ? 0 : 1; sigma = sqrt(prj->pv[2]*(1.0 - abssin)); xi = sigma - 1.0; eta = prj->w[9] * (prj->w[4] - sigma); if (*thetap < 0) eta = -eta; eta -= prj->y0; for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { if (offset) { // Offset the southern polar half-facets for even K. h = (int)floor((*xp + prj->x0) / prj->w[9]) + prj->m; if (h%2) { *yp -= prj->w[9]; } else { *yp += prj->w[9]; } } // Recall that y[] holds (phi - phi_c). *xp += *yp * xi; *yp = eta; *(statp++) = 0; // Put the phi = 180 meridian in the expected place. if (180.0 < *xp) *xp = 360.0 - *xp; } } } return 0; } /*============================================================================ * XPH: HEALPix polar, aka "butterfly" projection. * * Given and/or returned: * prj->r0 Reset to 180/pi if 0. * prj->phi0 Reset to 0.0 if undefined. * prj->theta0 Reset to 0.0 if undefined. * * Returned: * prj->flag XPH * prj->code "XPH" * prj->x0 Fiducial offset in x. * prj->y0 Fiducial offset in y. * prj->w[0] r0*(pi/180)/sqrt(2) * prj->w[1] (180/pi)/r0/sqrt(2) * prj->w[2] 2/3 * prj->w[3] tol (= 1e-4) * prj->w[4] sqrt(2/3)*(180/pi) * prj->w[5] 90 - tol*sqrt(2/3)*(180/pi) * prj->w[6] sqrt(3/2)*(pi/180) * prj->prjx2s Pointer to xphx2s(). * prj->prjs2x Pointer to xphs2x(). *===========================================================================*/ int xphset(struct prjprm *prj) { if (prj == 0x0) return PRJERR_NULL_POINTER; prj->flag = XPH; strcpy(prj->code, "XPH"); strcpy(prj->name, "butterfly"); prj->category = HEALPIX; prj->pvrange = 0; prj->simplezen = 0; prj->equiareal = 1; prj->conformal = 0; prj->global = 1; prj->divergent = 0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 1.0; prj->w[1] = 1.0; } else { prj->w[0] = prj->r0*D2R; prj->w[1] = R2D/prj->r0; } prj->w[0] /= sqrt(2.0); prj->w[1] /= sqrt(2.0); prj->w[2] = 2.0/3.0; prj->w[3] = 1e-4; prj->w[4] = sqrt(prj->w[2])*R2D; prj->w[5] = 90.0 - prj->w[3]*prj->w[4]; prj->w[6] = sqrt(1.5)*D2R; prj->prjx2s = xphx2s; prj->prjs2x = xphs2x; return prjoff(prj, 0.0, 90.0); } //---------------------------------------------------------------------------- int xphx2s( struct prjprm *prj, int nx, int ny, int sxy, int spt, const double x[], const double y[], double phi[], double theta[], int stat[]) { int mx, my, rowlen, rowoff, status; double abseta, eta, eta1, sigma, xi, xi1, xr, yr; const double tol = 1.0e-12; register int istat, ix, iy, *statp; register const double *xp, *yp; register double *phip, *thetap; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != XPH) { if ((status = xphset(prj))) return status; } if (ny > 0) { mx = nx; my = ny; } else { mx = 1; my = 1; ny = nx; } status = 0; // Do x dependence. xp = x; rowoff = 0; rowlen = nx*spt; for (ix = 0; ix < nx; ix++, rowoff += spt, xp += sxy) { xr = (*xp + prj->x0)*prj->w[1]; phip = phi + rowoff; for (iy = 0; iy < my; iy++) { *phip = xr; phip += rowlen; } } // Do y dependence. yp = y; phip = phi; thetap = theta; statp = stat; for (iy = 0; iy < ny; iy++, yp += sxy) { yr = (*yp + prj->y0)*prj->w[1]; for (ix = 0; ix < mx; ix++, phip += spt, thetap += spt) { xr = *phip; if (xr <= 0.0 && 0.0 < yr) { xi1 = -xr - yr; eta1 = xr - yr; *phip = -180.0; } else if (xr < 0.0 && yr <= 0.0) { xi1 = xr - yr; eta1 = xr + yr; *phip = -90.0; } else if (0.0 <= xr && yr < 0.0) { xi1 = xr + yr; eta1 = -xr + yr; *phip = 0.0; } else { xi1 = -xr + yr; eta1 = -xr - yr; *phip = 90.0; } xi = xi1 + 45.0; eta = eta1 + 90.0; abseta = fabs(eta); if (abseta <= 90.0) { if (abseta <= 45.0) { // Equatorial regime. *phip += xi; *thetap = asind(eta/67.5); istat = 0; // Bounds checking. if (prj->bounds&2) { if (45.0+tol < fabs(xi1)) { istat = 1; if (!status) status = PRJERR_BAD_PIX_SET("xphx2s"); } } *(statp++) = istat; } else { // Polar regime. sigma = (90.0 - abseta) / 45.0; // Ensure an exact result for points on the boundary. if (xr == 0.0) { if (yr <= 0.0) { *phip = 0.0; } else { *phip = 180.0; } } else if (yr == 0.0) { if (xr < 0.0) { *phip = -90.0; } else { *phip = 90.0; } } else { *phip += 45.0 + xi1/sigma; } if (sigma < prj->w[3]) { *thetap = 90.0 - sigma*prj->w[4]; } else { *thetap = asind(1.0 - sigma*sigma/3.0); } if (eta < 0.0) *thetap = -(*thetap); // Bounds checking. istat = 0; if (prj->bounds&2) { if (eta < -45.0 && eta+90.0+tol < fabs(xi1)) { istat = 1; if (!status) status = PRJERR_BAD_PIX_SET("xphx2s"); } } *(statp++) = istat; } } else { // Beyond latitude range. *phip = 0.0; *thetap = 0.0; *(statp++) = 1; if (!status) status = PRJERR_BAD_PIX_SET("xphx2s"); } } } // Do bounds checking on the native coordinates. if (prj->bounds&4 && prjbchk(1.0e-12, nx, my, spt, phi, theta, stat)) { if (!status) status = PRJERR_BAD_PIX_SET("xphx2s"); } return status; } //---------------------------------------------------------------------------- int xphs2x( struct prjprm *prj, int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double x[], double y[], int stat[]) { int mphi, mtheta, rowlen, rowoff, status; double abssin, chi, eta, psi, sigma, sinthe, xi; register int iphi, itheta, *statp; register const double *phip, *thetap; register double *xp, *yp; // Initialize. if (prj == 0x0) return PRJERR_NULL_POINTER; if (prj->flag != XPH) { if ((status = xphset(prj))) return status; } if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } // Do phi dependence. phip = phi; rowoff = 0; rowlen = nphi*sxy; for (iphi = 0; iphi < nphi; iphi++, rowoff += sxy, phip += spt) { chi = *phip; if (180.0 <= fabs(chi)) { chi = fmod(chi, 360.0); if (chi < -180.0) { chi += 360.0; } else if (180.0 <= chi) { chi -= 360.0; } } // phi is also recomputed from chi to avoid rounding problems. chi += 180.0; psi = fmod(chi, 90.0); xp = x + rowoff; yp = y + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { // y[] is used to hold phi (rounded). *xp = psi; *yp = chi - 180.0; xp += rowlen; yp += rowlen; } } // Do theta dependence. thetap = theta; xp = x; yp = y; statp = stat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { sinthe = sind(*thetap); abssin = fabs(sinthe); for (iphi = 0; iphi < mphi; iphi++, xp += sxy, yp += sxy) { if (abssin <= prj->w[2]) { // Equatorial regime. xi = *xp; eta = 67.5 * sinthe; } else { // Polar regime. if (*thetap < prj->w[5]) { sigma = sqrt(3.0*(1.0 - abssin)); } else { sigma = (90.0 - *thetap)*prj->w[6]; } xi = 45.0 + (*xp - 45.0)*sigma; eta = 45.0 * (2.0 - sigma); if (*thetap < 0.0) eta = -eta; } xi -= 45.0; eta -= 90.0; // Recall that y[] holds phi. if (*yp < -90.0) { *xp = prj->w[0]*(-xi + eta) - prj->x0; *yp = prj->w[0]*(-xi - eta) - prj->y0; } else if (*yp < 0.0) { *xp = prj->w[0]*(+xi + eta) - prj->x0; *yp = prj->w[0]*(-xi + eta) - prj->y0; } else if (*yp < 90.0) { *xp = prj->w[0]*( xi - eta) - prj->x0; *yp = prj->w[0]*( xi + eta) - prj->y0; } else { *xp = prj->w[0]*(-xi - eta) - prj->x0; *yp = prj->w[0]*( xi - eta) - prj->y0; } *(statp++) = 0; } } return 0; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/prj.h0000644000175100001710000007713500000000000016343 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: prj.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the prj routines * --------------------------- * Routines in this suite implement the spherical map projections defined by * the FITS World Coordinate System (WCS) standard, as described in * = "Representations of world coordinates in FITS", = Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (WCS Paper I) = = "Representations of celestial coordinates in FITS", = Calabretta, M.R., & Greisen, E.W. 2002, A&A, 395, 1077 (WCS Paper II) = = "Mapping on the HEALPix grid", = Calabretta, M.R., & Roukema, B.F. 2007, MNRAS, 381, 865 (WCS Paper V) = = "Representing the 'Butterfly' Projection in FITS -- Projection Code XPH", = Calabretta, M.R., & Lowe, S.R. 2013, PASA, 30, e050 (WCS Paper VI) * * These routines are based on the prjprm struct which contains all information * needed for the computations. The struct contains some members that must be * set by the user, and others that are maintained by these routines, somewhat * like a C++ class but with no encapsulation. * * Routine prjini() is provided to initialize the prjprm struct with default * values, prjfree() reclaims any memory that may have been allocated to store * an error message, prjsize() computes its total size including allocated * memory, and prjprt() prints its contents. * * prjperr() prints the error message(s) (if any) stored in a prjprm struct. * prjbchk() performs bounds checking on native spherical coordinates. * * Setup routines for each projection with names of the form ???set(), where * "???" is the down-cased three-letter projection code, compute intermediate * values in the prjprm struct from parameters in it that were supplied by the * user. The struct always needs to be set by the projection's setup routine * but that need not be called explicitly - refer to the explanation of * prjprm::flag. * * Each map projection is implemented via separate functions for the spherical * projection, ???s2x(), and deprojection, ???x2s(). * * A set of driver routines, prjset(), prjx2s(), and prjs2x(), provides a * generic interface to the specific projection routines which they invoke * via pointers-to-functions stored in the prjprm struct. * * In summary, the routines are: * - prjini() Initialization routine for the prjprm struct. * - prjfree() Reclaim memory allocated for error messages. * - prjsize() Compute total size of a prjprm struct. * - prjprt() Print a prjprm struct. * - prjperr() Print error message (if any). * - prjbchk() Bounds checking on native coordinates. * * - prjset(), prjx2s(), prjs2x(): Generic driver routines * * - azpset(), azpx2s(), azps2x(): AZP (zenithal/azimuthal perspective) * - szpset(), szpx2s(), szps2x(): SZP (slant zenithal perspective) * - tanset(), tanx2s(), tans2x(): TAN (gnomonic) * - stgset(), stgx2s(), stgs2x(): STG (stereographic) * - sinset(), sinx2s(), sins2x(): SIN (orthographic/synthesis) * - arcset(), arcx2s(), arcs2x(): ARC (zenithal/azimuthal equidistant) * - zpnset(), zpnx2s(), zpns2x(): ZPN (zenithal/azimuthal polynomial) * - zeaset(), zeax2s(), zeas2x(): ZEA (zenithal/azimuthal equal area) * - airset(), airx2s(), airs2x(): AIR (Airy) * - cypset(), cypx2s(), cyps2x(): CYP (cylindrical perspective) * - ceaset(), ceax2s(), ceas2x(): CEA (cylindrical equal area) * - carset(), carx2s(), cars2x(): CAR (Plate carree) * - merset(), merx2s(), mers2x(): MER (Mercator) * - sflset(), sflx2s(), sfls2x(): SFL (Sanson-Flamsteed) * - parset(), parx2s(), pars2x(): PAR (parabolic) * - molset(), molx2s(), mols2x(): MOL (Mollweide) * - aitset(), aitx2s(), aits2x(): AIT (Hammer-Aitoff) * - copset(), copx2s(), cops2x(): COP (conic perspective) * - coeset(), coex2s(), coes2x(): COE (conic equal area) * - codset(), codx2s(), cods2x(): COD (conic equidistant) * - cooset(), coox2s(), coos2x(): COO (conic orthomorphic) * - bonset(), bonx2s(), bons2x(): BON (Bonne) * - pcoset(), pcox2s(), pcos2x(): PCO (polyconic) * - tscset(), tscx2s(), tscs2x(): TSC (tangential spherical cube) * - cscset(), cscx2s(), cscs2x(): CSC (COBE spherical cube) * - qscset(), qscx2s(), qscs2x(): QSC (quadrilateralized spherical cube) * - hpxset(), hpxx2s(), hpxs2x(): HPX (HEALPix) * - xphset(), xphx2s(), xphs2x(): XPH (HEALPix polar, aka "butterfly") * * Argument checking (projection routines): * ---------------------------------------- * The values of phi and theta (the native longitude and latitude) normally lie * in the range [-180,180] for phi, and [-90,90] for theta. However, all * projection routines will accept any value of phi and will not normalize it. * * The projection routines do not explicitly check that theta lies within the * range [-90,90]. They do check for any value of theta that produces an * invalid argument to the projection equations (e.g. leading to division by * zero). The projection routines for AZP, SZP, TAN, SIN, ZPN, and COP also * return error 2 if (phi,theta) corresponds to the overlapped (far) side of * the projection but also return the corresponding value of (x,y). This * strict bounds checking may be relaxed at any time by setting * prjprm::bounds%2 to 0 (rather than 1); the projections need not be * reinitialized. * * Argument checking (deprojection routines): * ------------------------------------------ * Error checking on the projected coordinates (x,y) is limited to that * required to ascertain whether a solution exists. Where a solution does * exist, an optional check is made that the value of phi and theta obtained * lie within the ranges [-180,180] for phi, and [-90,90] for theta. This * check, performed by prjbchk(), is enabled by default. It may be disabled by * setting prjprm::bounds%4 to 0 (rather than 1); the projections need not be * reinitialized. * * Accuracy: * --------- * No warranty is given for the accuracy of these routines (refer to the * copyright notice); intending users must satisfy for themselves their * adequacy for the intended purpose. However, closure to a precision of at * least 1E-10 degree of longitude and latitude has been verified for typical * projection parameters on the 1 degree graticule of native longitude and * latitude (to within 5 degrees of any latitude where the projection may * diverge). Refer to the tprj1.c and tprj2.c test routines that accompany * this software. * * * prjini() - Default constructor for the prjprm struct * ---------------------------------------------------- * prjini() sets all members of a prjprm struct to default values. It should * be used to initialize every prjprm struct. * * PLEASE NOTE: If the prjprm struct has already been initialized, then before * reinitializing, it prjfree() should be used to free any memory that may have * been allocated to store an error message. A memory leak may otherwise * result. * * Returned: * prj struct prjprm* * Projection parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null prjprm pointer passed. * * * prjfree() - Destructor for the prjprm struct * -------------------------------------------- * prjfree() frees any memory that may have been allocated to store an error * message in the prjprm struct. * * Given: * prj struct prjprm* * Projection parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null prjprm pointer passed. * * * prjsize() - Compute the size of a prjprm struct * ----------------------------------------------- * prjsize() computes the full size of a prjprm struct, including allocated * memory. * * Given: * prj const struct prjprm* * Projection parameters. * * If NULL, the base size of the struct and the allocated * size are both set to zero. * * Returned: * sizes int[2] The first element is the base size of the struct as * returned by sizeof(struct prjprm). The second element * is the total allocated size, in bytes. This figure * includes memory allocated for the constituent struct, * prjprm::err. * * It is not an error for the struct not to have been set * up via prjset(). * * Function return value: * int Status return value: * 0: Success. * * * prjprt() - Print routine for the prjprm struct * ---------------------------------------------- * prjprt() prints the contents of a prjprm struct using wcsprintf(). Mainly * intended for diagnostic purposes. * * Given: * prj const struct prjprm* * Projection parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null prjprm pointer passed. * * * prjperr() - Print error messages from a prjprm struct * ----------------------------------------------------- * prjperr() prints the error message(s) (if any) stored in a prjprm struct. * If there are no errors then nothing is printed. It uses wcserr_prt(), q.v. * * Given: * prj const struct prjprm* * Projection parameters. * * prefix const char * * If non-NULL, each output line will be prefixed with * this string. * * Function return value: * int Status return value: * 0: Success. * 1: Null prjprm pointer passed. * * * prjbchk() - Bounds checking on native coordinates * ------------------------------------------------- * prjbchk() performs bounds checking on native spherical coordinates. As * returned by the deprojection (x2s) routines, native longitude is expected * to lie in the closed interval [-180,180], with latitude in [-90,90]. * * A tolerance may be specified to provide a small allowance for numerical * imprecision. Values that lie outside the allowed range by not more than * the specified tolerance will be adjusted back into range. * * If prjprm::bounds&4 is set, as it is by prjini(), then prjbchk() will be * invoked automatically by the Cartesian-to-spherical deprojection (x2s) * routines with an appropriate tolerance set for each projection. * * Given: * tol double Tolerance for the bounds check [deg]. * * nphi, * ntheta int Vector lengths. * * spt int Vector stride. * * Given and returned: * phi,theta double[] Native longitude and latitude (phi,theta) [deg]. * * Returned: * stat int[] Status value for each vector element: * 0: Valid value of (phi,theta). * 1: Invalid value. * * Function return value: * int Status return value: * 0: Success. * 1: One or more of the (phi,theta) coordinates * were, invalid, as indicated by the stat vector. * * * prjset() - Generic setup routine for the prjprm struct * ------------------------------------------------------ * prjset() sets up a prjprm struct according to information supplied within * it. * * Note that this routine need not be called directly; it will be invoked by * prjx2s() and prjs2x() if prj.flag is anything other than a predefined magic * value. * * The one important distinction between prjset() and the setup routines for * the specific projections is that the projection code must be defined in the * prjprm struct in order for prjset() to identify the required projection. * Once prjset() has initialized the prjprm struct, prjx2s() and prjs2x() use * the pointers to the specific projection and deprojection routines contained * therein. * * Given and returned: * prj struct prjprm* * Projection parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null prjprm pointer passed. * 2: Invalid projection parameters. * * For returns > 1, a detailed error message is set in * prjprm::err if enabled, see wcserr_enable(). * * * prjx2s() - Generic Cartesian-to-spherical deprojection * ------------------------------------------------------ * Deproject Cartesian (x,y) coordinates in the plane of projection to native * spherical coordinates (phi,theta). * * The projection is that specified by prjprm::code. * * Given and returned: * prj struct prjprm* * Projection parameters. * * Given: * nx,ny int Vector lengths. * * sxy,spt int Vector strides. * * x,y const double[] * Projected coordinates. * * Returned: * phi,theta double[] Longitude and latitude (phi,theta) of the projected * point in native spherical coordinates [deg]. * * stat int[] Status value for each vector element: * 0: Success. * 1: Invalid value of (x,y). * * Function return value: * int Status return value: * 0: Success. * 1: Null prjprm pointer passed. * 2: Invalid projection parameters. * 3: One or more of the (x,y) coordinates were * invalid, as indicated by the stat vector. * * For returns > 1, a detailed error message is set in * prjprm::err if enabled, see wcserr_enable(). * * * prjs2x() - Generic spherical-to-Cartesian projection * ---------------------------------------------------- * Project native spherical coordinates (phi,theta) to Cartesian (x,y) * coordinates in the plane of projection. * * The projection is that specified by prjprm::code. * * Given and returned: * prj struct prjprm* * Projection parameters. * * Given: * nphi, * ntheta int Vector lengths. * * spt,sxy int Vector strides. * * phi,theta const double[] * Longitude and latitude (phi,theta) of the projected * point in native spherical coordinates [deg]. * * Returned: * x,y double[] Projected coordinates. * * stat int[] Status value for each vector element: * 0: Success. * 1: Invalid value of (phi,theta). * * Function return value: * int Status return value: * 0: Success. * 1: Null prjprm pointer passed. * 2: Invalid projection parameters. * 4: One or more of the (phi,theta) coordinates * were, invalid, as indicated by the stat vector. * * For returns > 1, a detailed error message is set in * prjprm::err if enabled, see wcserr_enable(). * * * ???set() - Specific setup routines for the prjprm struct * -------------------------------------------------------- * Set up a prjprm struct for a particular projection according to information * supplied within it. * * Given and returned: * prj struct prjprm* * Projection parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null prjprm pointer passed. * 2: Invalid projection parameters. * * For returns > 1, a detailed error message is set in * prjprm::err if enabled, see wcserr_enable(). * * * ???x2s() - Specific Cartesian-to-spherical deprojection routines * ---------------------------------------------------------------- * Transform (x,y) coordinates in the plane of projection to native spherical * coordinates (phi,theta). * * Given and returned: * prj struct prjprm* * Projection parameters. * * Given: * nx,ny int Vector lengths. * * sxy,spt int Vector strides. * * x,y const double[] * Projected coordinates. * * Returned: * phi,theta double[] Longitude and latitude of the projected point in * native spherical coordinates [deg]. * * stat int[] Status value for each vector element: * 0: Success. * 1: Invalid value of (x,y). * * Function return value: * int Status return value: * 0: Success. * 1: Null prjprm pointer passed. * 2: Invalid projection parameters. * 3: One or more of the (x,y) coordinates were * invalid, as indicated by the stat vector. * * For returns > 1, a detailed error message is set in * prjprm::err if enabled, see wcserr_enable(). * * * ???s2x() - Specific spherical-to-Cartesian projection routines *--------------------------------------------------------------- * Transform native spherical coordinates (phi,theta) to (x,y) coordinates in * the plane of projection. * * Given and returned: * prj struct prjprm* * Projection parameters. * * Given: * nphi, * ntheta int Vector lengths. * * spt,sxy int Vector strides. * * phi,theta const double[] * Longitude and latitude of the projected point in * native spherical coordinates [deg]. * * Returned: * x,y double[] Projected coordinates. * * stat int[] Status value for each vector element: * 0: Success. * 1: Invalid value of (phi,theta). * * Function return value: * int Status return value: * 0: Success. * 1: Null prjprm pointer passed. * 2: Invalid projection parameters. * 4: One or more of the (phi,theta) coordinates * were, invalid, as indicated by the stat vector. * * For returns > 1, a detailed error message is set in * prjprm::err if enabled, see wcserr_enable(). * * * prjprm struct - Projection parameters * ------------------------------------- * The prjprm struct contains all information needed to project or deproject * native spherical coordinates. It consists of certain members that must be * set by the user ("given") and others that are set by the WCSLIB routines * ("returned"). Some of the latter are supplied for informational purposes * while others are for internal use only. * * int flag * (Given and returned) This flag must be set to zero whenever any of the * following prjprm struct members are set or changed: * * - prjprm::code, * - prjprm::r0, * - prjprm::pv[], * - prjprm::phi0, * - prjprm::theta0. * * This signals the initialization routine (prjset() or ???set()) to * recompute the returned members of the prjprm struct. flag will then be * reset to indicate that this has been done. * * Note that flag need not be reset when prjprm::bounds is changed. * * char code[4] * (Given) Three-letter projection code defined by the FITS standard. * * double r0 * (Given) The radius of the generating sphere for the projection, a linear * scaling parameter. If this is zero, it will be reset to its default * value of 180/pi (the value for FITS WCS). * * double pv[30] * (Given) Projection parameters. These correspond to the PVi_ma keywords * in FITS, so pv[0] is PVi_0a, pv[1] is PVi_1a, etc., where i denotes the * latitude-like axis. Many projections use pv[1] (PVi_1a), some also use * pv[2] (PVi_2a) and SZP uses pv[3] (PVi_3a). ZPN is currently the only * projection that uses any of the others. * * Usage of the pv[] array as it applies to each projection is described in * the prologue to each trio of projection routines in prj.c. * * double phi0 * (Given) The native longitude, phi_0 [deg], and ... * double theta0 * (Given) ... the native latitude, theta_0 [deg], of the reference point, * i.e. the point (x,y) = (0,0). If undefined (set to a magic value by * prjini()) the initialization routine will set this to a * projection-specific default. * * int bounds * (Given) Controls bounds checking. If bounds&1 then enable strict bounds * checking for the spherical-to-Cartesian (s2x) transformation for the * AZP, SZP, TAN, SIN, ZPN, and COP projections. If bounds&2 then enable * strict bounds checking for the Cartesian-to-spherical transformation * (x2s) for the HPX and XPH projections. If bounds&4 then the Cartesian- * to-spherical transformations (x2s) will invoke prjbchk() to perform * bounds checking on the computed native coordinates, with a tolerance set * to suit each projection. bounds is set to 7 by prjini() by default * which enables all checks. Zero it to disable all checking. * * It is not necessary to reset the prjprm struct (via prjset() or * ???set()) when prjprm::bounds is changed. * * The remaining members of the prjprm struct are maintained by the setup * routines and must not be modified elsewhere: * * char name[40] * (Returned) Long name of the projection. * * Provided for information only, not used by the projection routines. * * int category * (Returned) Projection category matching the value of the relevant global * variable: * * - ZENITHAL, * - CYLINDRICAL, * - PSEUDOCYLINDRICAL, * - CONVENTIONAL, * - CONIC, * - POLYCONIC, * - QUADCUBE, and * - HEALPIX. * * The category name may be identified via the prj_categories character * array, e.g. * = struct prjprm prj; = ... = printf("%s\n", prj_categories[prj.category]); * * Provided for information only, not used by the projection routines. * * int pvrange * (Returned) Range of projection parameter indices: 100 times the first * allowed index plus the number of parameters, e.g. TAN is 0 (no * parameters), SZP is 103 (1 to 3), and ZPN is 30 (0 to 29). * * Provided for information only, not used by the projection routines. * * int simplezen * (Returned) True if the projection is a radially-symmetric zenithal * projection. * * Provided for information only, not used by the projection routines. * * int equiareal * (Returned) True if the projection is equal area. * * Provided for information only, not used by the projection routines. * * int conformal * (Returned) True if the projection is conformal. * * Provided for information only, not used by the projection routines. * * int global * (Returned) True if the projection can represent the whole sphere in a * finite, non-overlapped mapping. * * Provided for information only, not used by the projection routines. * * int divergent * (Returned) True if the projection diverges in latitude. * * Provided for information only, not used by the projection routines. * * double x0 * (Returned) The offset in x, and ... * double y0 * (Returned) ... the offset in y used to force (x,y) = (0,0) at * (phi_0,theta_0). * * struct wcserr *err * (Returned) If enabled, when an error status is returned, this struct * contains detailed information about the error, see wcserr_enable(). * * void *padding * (An unused variable inserted for alignment purposes only.) * * double w[10] * (Returned) Intermediate floating-point values derived from the * projection parameters, cached here to save recomputation. * * Usage of the w[] array as it applies to each projection is described in * the prologue to each trio of projection routines in prj.c. * * int n * (Returned) Intermediate integer value (used only for the ZPN and HPX * projections). * * int (*prjx2s)(PRJX2S_ARGS) * (Returned) Pointer to the spherical projection ... * int (*prjs2x)(PRJ_ARGS) * (Returned) ... and deprojection routines. * * * Global variable: const char *prj_errmsg[] - Status return messages * ------------------------------------------------------------------ * Error messages to match the status value returned from each function. * *===========================================================================*/ #ifndef WCSLIB_PROJ #define WCSLIB_PROJ #ifdef __cplusplus extern "C" { #endif // Total number of projection parameters; 0 to PVN-1. #define PVN 30 extern const char *prj_errmsg[]; enum prj_errmsg_enum { PRJERR_SUCCESS = 0, // Success. PRJERR_NULL_POINTER = 1, // Null prjprm pointer passed. PRJERR_BAD_PARAM = 2, // Invalid projection parameters. PRJERR_BAD_PIX = 3, // One or more of the (x, y) coordinates were // invalid. PRJERR_BAD_WORLD = 4 // One or more of the (phi, theta) coordinates // were invalid. }; extern const int CONIC, CONVENTIONAL, CYLINDRICAL, POLYCONIC, PSEUDOCYLINDRICAL, QUADCUBE, ZENITHAL, HEALPIX; extern const char prj_categories[9][32]; extern const int prj_ncode; extern const char prj_codes[28][4]; #ifdef PRJX2S_ARGS #undef PRJX2S_ARGS #endif #ifdef PRJS2X_ARGS #undef PRJS2X_ARGS #endif // For use in declaring deprojection function prototypes. #define PRJX2S_ARGS struct prjprm *prj, int nx, int ny, int sxy, int spt, \ const double x[], const double y[], double phi[], double theta[], int stat[] // For use in declaring projection function prototypes. #define PRJS2X_ARGS struct prjprm *prj, int nx, int ny, int sxy, int spt, \ const double phi[], const double theta[], double x[], double y[], int stat[] struct prjprm { // Initialization flag (see the prologue above). //-------------------------------------------------------------------------- int flag; // Set to zero to force initialization. // Parameters to be provided (see the prologue above). //-------------------------------------------------------------------------- char code[4]; // Three-letter projection code. double r0; // Radius of the generating sphere. double pv[PVN]; // Projection parameters. double phi0, theta0; // Fiducial native coordinates. int bounds; // Controls bounds checking. // Information derived from the parameters supplied. //-------------------------------------------------------------------------- char name[40]; // Projection name. int category; // Projection category. int pvrange; // Range of projection parameter indices. int simplezen; // Is it a simple zenithal projection? int equiareal; // Is it an equal area projection? int conformal; // Is it a conformal projection? int global; // Can it map the whole sphere? int divergent; // Does the projection diverge in latitude? double x0, y0; // Fiducial offsets. // Error handling //-------------------------------------------------------------------------- struct wcserr *err; // Private //-------------------------------------------------------------------------- void *padding; // (Dummy inserted for alignment purposes.) double w[10]; // Intermediate values. int m, n; // Intermediate values. int (*prjx2s)(PRJX2S_ARGS); // Pointers to the spherical projection and int (*prjs2x)(PRJS2X_ARGS); // deprojection functions. }; // Size of the prjprm struct in int units, used by the Fortran wrappers. #define PRJLEN (sizeof(struct prjprm)/sizeof(int)) int prjini(struct prjprm *prj); int prjfree(struct prjprm *prj); int prjsize(const struct prjprm *prj, int sizes[2]); int prjprt(const struct prjprm *prj); int prjperr(const struct prjprm *prj, const char *prefix); int prjbchk(double tol, int nphi, int ntheta, int spt, double phi[], double theta[], int stat[]); // Use the preprocessor to help declare function prototypes (see above). int prjset(struct prjprm *prj); int prjx2s(PRJX2S_ARGS); int prjs2x(PRJS2X_ARGS); int azpset(struct prjprm *prj); int azpx2s(PRJX2S_ARGS); int azps2x(PRJS2X_ARGS); int szpset(struct prjprm *prj); int szpx2s(PRJX2S_ARGS); int szps2x(PRJS2X_ARGS); int tanset(struct prjprm *prj); int tanx2s(PRJX2S_ARGS); int tans2x(PRJS2X_ARGS); int stgset(struct prjprm *prj); int stgx2s(PRJX2S_ARGS); int stgs2x(PRJS2X_ARGS); int sinset(struct prjprm *prj); int sinx2s(PRJX2S_ARGS); int sins2x(PRJS2X_ARGS); int arcset(struct prjprm *prj); int arcx2s(PRJX2S_ARGS); int arcs2x(PRJS2X_ARGS); int zpnset(struct prjprm *prj); int zpnx2s(PRJX2S_ARGS); int zpns2x(PRJS2X_ARGS); int zeaset(struct prjprm *prj); int zeax2s(PRJX2S_ARGS); int zeas2x(PRJS2X_ARGS); int airset(struct prjprm *prj); int airx2s(PRJX2S_ARGS); int airs2x(PRJS2X_ARGS); int cypset(struct prjprm *prj); int cypx2s(PRJX2S_ARGS); int cyps2x(PRJS2X_ARGS); int ceaset(struct prjprm *prj); int ceax2s(PRJX2S_ARGS); int ceas2x(PRJS2X_ARGS); int carset(struct prjprm *prj); int carx2s(PRJX2S_ARGS); int cars2x(PRJS2X_ARGS); int merset(struct prjprm *prj); int merx2s(PRJX2S_ARGS); int mers2x(PRJS2X_ARGS); int sflset(struct prjprm *prj); int sflx2s(PRJX2S_ARGS); int sfls2x(PRJS2X_ARGS); int parset(struct prjprm *prj); int parx2s(PRJX2S_ARGS); int pars2x(PRJS2X_ARGS); int molset(struct prjprm *prj); int molx2s(PRJX2S_ARGS); int mols2x(PRJS2X_ARGS); int aitset(struct prjprm *prj); int aitx2s(PRJX2S_ARGS); int aits2x(PRJS2X_ARGS); int copset(struct prjprm *prj); int copx2s(PRJX2S_ARGS); int cops2x(PRJS2X_ARGS); int coeset(struct prjprm *prj); int coex2s(PRJX2S_ARGS); int coes2x(PRJS2X_ARGS); int codset(struct prjprm *prj); int codx2s(PRJX2S_ARGS); int cods2x(PRJS2X_ARGS); int cooset(struct prjprm *prj); int coox2s(PRJX2S_ARGS); int coos2x(PRJS2X_ARGS); int bonset(struct prjprm *prj); int bonx2s(PRJX2S_ARGS); int bons2x(PRJS2X_ARGS); int pcoset(struct prjprm *prj); int pcox2s(PRJX2S_ARGS); int pcos2x(PRJS2X_ARGS); int tscset(struct prjprm *prj); int tscx2s(PRJX2S_ARGS); int tscs2x(PRJS2X_ARGS); int cscset(struct prjprm *prj); int cscx2s(PRJX2S_ARGS); int cscs2x(PRJS2X_ARGS); int qscset(struct prjprm *prj); int qscx2s(PRJX2S_ARGS); int qscs2x(PRJS2X_ARGS); int hpxset(struct prjprm *prj); int hpxx2s(PRJX2S_ARGS); int hpxs2x(PRJS2X_ARGS); int xphset(struct prjprm *prj); int xphx2s(PRJX2S_ARGS); int xphs2x(PRJS2X_ARGS); // Deprecated. #define prjini_errmsg prj_errmsg #define prjprt_errmsg prj_errmsg #define prjset_errmsg prj_errmsg #define prjx2s_errmsg prj_errmsg #define prjs2x_errmsg prj_errmsg #ifdef __cplusplus } #endif #endif // WCSLIB_PROJ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/spc.c0000644000175100001710000010727600000000000016330 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: spc.c,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *===========================================================================*/ #include #include #include #include #include "wcserr.h" #include "wcsmath.h" #include "wcsprintf.h" #include "wcstrig.h" #include "wcsutil.h" #include "spc.h" #include "spx.h" // Spectral algorithm codes. #define F2S 100; // Axis linear in frequency. #define W2S 200; // Axis linear in vacuum wavelengths. #define A2S 300; // Axis linear in air wavelengths. #define V2S 400; // Axis linear in velocity. #define GRI 500; // Grism in vacuum. #define GRA 600; // Grism in air. // S-type spectral variables. #define FREQ 0; // Frequency-like. #define AFRQ 1; // Frequency-like. #define ENER 2; // Frequency-like. #define WAVN 3; // Frequency-like. #define VRAD 4; // Frequency-like. #define WAVE 10; // Vacuum wavelength-like. #define VOPT 11; // Vacuum wavelength-like. #define ZOPT 12; // Vacuum wavelength-like. #define AWAV 20; // Air wavelength-like. #define VELO 30; // Velocity-like. #define BETA 31; // Velocity-like. // Map status return value to message. const char *spc_errmsg[] = { "Success", "Null spcprm pointer passed", "Invalid spectral parameters", "One or more of x coordinates were invalid", "One or more of the spec coordinates were invalid"}; // Map error returns for lower-level routines. SPXERR_BAD_INSPEC_COORD // maps to either SPCERR_BAD_X or SPCERR_BAD_SPEC depending on context. const int spc_spxerr[] = { SPCERR_SUCCESS, // 0: SPXERR_SUCCESS SPCERR_NULL_POINTER, // 1: SPXERR_NULL_POINTER SPCERR_BAD_SPEC_PARAMS, // 2: SPXERR_BAD_SPEC_PARAMS SPCERR_BAD_SPEC_PARAMS // 3: SPXERR_BAD_SPEC_VAR // 4: SPXERR_BAD_INSPEC_COORD }; // Convenience macro for invoking wcserr_set(). #define SPC_ERRMSG(status) WCSERR_SET(status), spc_errmsg[status] #define C 2.99792458e8 //---------------------------------------------------------------------------- int spcini(struct spcprm *spc) { register int k; if (spc == 0x0) return SPCERR_NULL_POINTER; spc->flag = 0; memset(spc->type, 0, 8); strcpy(spc->type, " "); strcpy(spc->code, " "); spc->crval = UNDEFINED; spc->restfrq = 0.0; spc->restwav = 0.0; for (k = 0; k < 7; k++) { spc->pv[k] = UNDEFINED; } for (k = 0; k < 6; k++) { spc->w[k] = 0.0; } spc->isGrism = 0; spc->padding1 = 0; spc->err = 0x0; spc->padding2 = 0x0; spc->spxX2P = 0x0; spc->spxP2S = 0x0; spc->spxS2P = 0x0; spc->spxP2X = 0x0; return 0; } //---------------------------------------------------------------------------- int spcfree(struct spcprm *spc) { if (spc == 0x0) return SPCERR_NULL_POINTER; wcserr_clear(&(spc->err)); return 0; } //---------------------------------------------------------------------------- int spcsize(const struct spcprm *spc, int sizes[2]) { if (spc == 0x0) { sizes[0] = sizes[1] = 0; return SPCERR_SUCCESS; } // Base size, in bytes. sizes[0] = sizeof(struct spcprm); // Total size of allocated memory, in bytes. sizes[1] = 0; int exsizes[2]; // spcprm::err. wcserr_size(spc->err, exsizes); sizes[1] += exsizes[0] + exsizes[1]; return SPCERR_SUCCESS; } //---------------------------------------------------------------------------- int spcprt(const struct spcprm *spc) { char hext[32]; int i; if (spc == 0x0) return SPCERR_NULL_POINTER; wcsprintf(" flag: %d\n", spc->flag); wcsprintf(" type: \"%s\"\n", spc->type); wcsprintf(" code: \"%s\"\n", spc->code); if (undefined(spc->crval)) { wcsprintf(" crval: UNDEFINED\n"); } else { wcsprintf(" crval: %#- 11.5g\n", spc->crval); } wcsprintf(" restfrq: %f\n", spc->restfrq); wcsprintf(" restwav: %f\n", spc->restwav); wcsprintf(" pv:"); if (spc->isGrism) { for (i = 0; i < 5; i++) { if (undefined(spc->pv[i])) { wcsprintf(" UNDEFINED "); } else { wcsprintf(" %#- 11.5g", spc->pv[i]); } } wcsprintf("\n "); for (i = 5; i < 7; i++) { if (undefined(spc->pv[i])) { wcsprintf(" UNDEFINED "); } else { wcsprintf(" %#- 11.5g", spc->pv[i]); } } wcsprintf("\n"); } else { wcsprintf(" (not used)\n"); } wcsprintf(" w:"); for (i = 0; i < 3; i++) { wcsprintf(" %#- 11.5g", spc->w[i]); } if (spc->isGrism) { wcsprintf("\n "); for (i = 3; i < 6; i++) { wcsprintf(" %#- 11.5g", spc->w[i]); } wcsprintf("\n"); } else { wcsprintf(" (remainder unused)\n"); } wcsprintf(" isGrism: %d\n", spc->isGrism); WCSPRINTF_PTR(" err: ", spc->err, "\n"); if (spc->err) { wcserr_prt(spc->err, " "); } wcsprintf(" spxX2P: %s\n", wcsutil_fptr2str((void (*)(void))spc->spxX2P, hext)); wcsprintf(" spxP2S: %s\n", wcsutil_fptr2str((void (*)(void))spc->spxP2S, hext)); wcsprintf(" spxS2P: %s\n", wcsutil_fptr2str((void (*)(void))spc->spxS2P, hext)); wcsprintf(" spxP2X: %s\n", wcsutil_fptr2str((void (*)(void))spc->spxP2X, hext)); return 0; } //---------------------------------------------------------------------------- int spcperr(const struct spcprm *spc, const char *prefix) { if (spc == 0x0) return SPCERR_NULL_POINTER; if (spc->err) { wcserr_prt(spc->err, prefix); } return 0; } //---------------------------------------------------------------------------- int spcset(struct spcprm *spc) { static const char *function = "spcset"; char ctype[9], ptype, xtype; int restreq, status; double alpha, beta_r, crvalX, dn_r, dXdS, epsilon, G, m, lambda_r, n_r, t, restfrq, restwav, theta; struct wcserr **err; if (spc == 0x0) return SPCERR_NULL_POINTER; err = &(spc->err); if (undefined(spc->crval)) { return wcserr_set(WCSERR_SET(SPCERR_BAD_SPEC_PARAMS), "Spectral crval is undefined"); } memset((spc->type)+4, 0, 4); spc->code[3] = '\0'; wcsutil_blank_fill(4, spc->type); wcsutil_blank_fill(3, spc->code); spc->w[0] = 0.0; // Analyse the spectral axis type. memset(ctype, 0, 9); memcpy(ctype, spc->type, 4); if (*(spc->code) != ' ') { sprintf(ctype+4, "-%s", spc->code); } restfrq = spc->restfrq; restwav = spc->restwav; if ((status = spcspxe(ctype, spc->crval, restfrq, restwav, &ptype, &xtype, &restreq, &crvalX, &dXdS, &(spc->err)))) { return status; } // Satisfy rest frequency/wavelength requirements. if (restreq) { if (restreq == 3 && restfrq == 0.0 && restwav == 0.0) { // VRAD-V2F, VOPT-V2W, and ZOPT-V2W require the rest frequency or // wavelength for the S-P and P-X transformations but not for S-X // so supply a phoney value. restwav = 1.0; } if (restfrq == 0.0) { restfrq = C/restwav; } else { restwav = C/restfrq; } if (ptype == 'F') { spc->w[0] = restfrq; } else if (ptype != 'V') { spc->w[0] = restwav; } else { if (xtype == 'F') { spc->w[0] = restfrq; } else { spc->w[0] = restwav; } } } spc->w[1] = crvalX; spc->w[2] = dXdS; // Set pointers-to-functions for the linear part of the transformation. if (ptype == 'F') { if (strcmp(spc->type, "FREQ") == 0) { // Frequency. spc->flag = FREQ; spc->spxP2S = 0x0; spc->spxS2P = 0x0; } else if (strcmp(spc->type, "AFRQ") == 0) { // Angular frequency. spc->flag = AFRQ; spc->spxP2S = freqafrq; spc->spxS2P = afrqfreq; } else if (strcmp(spc->type, "ENER") == 0) { // Photon energy. spc->flag = ENER; spc->spxP2S = freqener; spc->spxS2P = enerfreq; } else if (strcmp(spc->type, "WAVN") == 0) { // Wave number. spc->flag = WAVN; spc->spxP2S = freqwavn; spc->spxS2P = wavnfreq; } else if (strcmp(spc->type, "VRAD") == 0) { // Radio velocity. spc->flag = VRAD; spc->spxP2S = freqvrad; spc->spxS2P = vradfreq; } } else if (ptype == 'W') { if (strcmp(spc->type, "WAVE") == 0) { // Vacuum wavelengths. spc->flag = WAVE; spc->spxP2S = 0x0; spc->spxS2P = 0x0; } else if (strcmp(spc->type, "VOPT") == 0) { // Optical velocity. spc->flag = VOPT; spc->spxP2S = wavevopt; spc->spxS2P = voptwave; } else if (strcmp(spc->type, "ZOPT") == 0) { // Redshift. spc->flag = ZOPT; spc->spxP2S = wavezopt; spc->spxS2P = zoptwave; } } else if (ptype == 'A') { if (strcmp(spc->type, "AWAV") == 0) { // Air wavelengths. spc->flag = AWAV; spc->spxP2S = 0x0; spc->spxS2P = 0x0; } } else if (ptype == 'V') { if (strcmp(spc->type, "VELO") == 0) { // Relativistic velocity. spc->flag = VELO; spc->spxP2S = 0x0; spc->spxS2P = 0x0; } else if (strcmp(spc->type, "BETA") == 0) { // Velocity ratio (v/c). spc->flag = BETA; spc->spxP2S = velobeta; spc->spxS2P = betavelo; } } // Set pointers-to-functions for the non-linear part of the spectral // transformation. spc->isGrism = 0; if (xtype == 'F') { // Axis is linear in frequency. if (ptype == 'F') { spc->spxX2P = 0x0; spc->spxP2X = 0x0; } else if (ptype == 'W') { spc->spxX2P = freqwave; spc->spxP2X = wavefreq; } else if (ptype == 'A') { spc->spxX2P = freqawav; spc->spxP2X = awavfreq; } else if (ptype == 'V') { spc->spxX2P = freqvelo; spc->spxP2X = velofreq; } spc->flag += F2S; } else if (xtype == 'W' || xtype == 'w') { // Axis is linear in vacuum wavelengths. if (ptype == 'F') { spc->spxX2P = wavefreq; spc->spxP2X = freqwave; } else if (ptype == 'W') { spc->spxX2P = 0x0; spc->spxP2X = 0x0; } else if (ptype == 'A') { spc->spxX2P = waveawav; spc->spxP2X = awavwave; } else if (ptype == 'V') { spc->spxX2P = wavevelo; spc->spxP2X = velowave; } if (xtype == 'W') { spc->flag += W2S; } else { // Grism in vacuum. spc->isGrism = 1; spc->flag += GRI; } } else if (xtype == 'A' || xtype == 'a') { // Axis is linear in air wavelengths. if (ptype == 'F') { spc->spxX2P = awavfreq; spc->spxP2X = freqawav; } else if (ptype == 'W') { spc->spxX2P = awavwave; spc->spxP2X = waveawav; } else if (ptype == 'A') { spc->spxX2P = 0x0; spc->spxP2X = 0x0; } else if (ptype == 'V') { spc->spxX2P = awavvelo; spc->spxP2X = veloawav; } if (xtype == 'A') { spc->flag += A2S; } else { // Grism in air. spc->isGrism = 2; spc->flag += GRA; } } else if (xtype == 'V') { // Axis is linear in relativistic velocity. if (ptype == 'F') { spc->spxX2P = velofreq; spc->spxP2X = freqvelo; } else if (ptype == 'W') { spc->spxX2P = velowave; spc->spxP2X = wavevelo; } else if (ptype == 'A') { spc->spxX2P = veloawav; spc->spxP2X = awavvelo; } else if (ptype == 'V') { spc->spxX2P = 0x0; spc->spxP2X = 0x0; } spc->flag += V2S; } // Check for grism axes. if (spc->isGrism) { // Axis is linear in "grism parameter"; work in wavelength. lambda_r = crvalX; // Set defaults. if (undefined(spc->pv[0])) spc->pv[0] = 0.0; if (undefined(spc->pv[1])) spc->pv[1] = 0.0; if (undefined(spc->pv[2])) spc->pv[2] = 0.0; if (undefined(spc->pv[3])) spc->pv[3] = 1.0; if (undefined(spc->pv[4])) spc->pv[4] = 0.0; if (undefined(spc->pv[5])) spc->pv[5] = 0.0; if (undefined(spc->pv[6])) spc->pv[6] = 0.0; // Compute intermediaries. G = spc->pv[0]; m = spc->pv[1]; alpha = spc->pv[2]; n_r = spc->pv[3]; dn_r = spc->pv[4]; epsilon = spc->pv[5]; theta = spc->pv[6]; t = G*m/cosd(epsilon); beta_r = asind(t*lambda_r - n_r*sind(alpha)); t -= dn_r*sind(alpha); spc->w[1] = -tand(theta); spc->w[2] *= t / (cosd(beta_r)*cosd(theta)*cosd(theta)); spc->w[3] = beta_r + theta; spc->w[4] = (n_r - dn_r*lambda_r)*sind(alpha); spc->w[5] = 1.0 / t; } return 0; } //---------------------------------------------------------------------------- int spcx2s( struct spcprm *spc, int nx, int sx, int sspec, const double x[], double spec[], int stat[]) { static const char *function = "spcx2s"; int statP2S, status = 0, statX2P; double beta; register int ix; register int *statp; register const double *xp; register double *specp; struct wcserr **err; // Initialize. if (spc == 0x0) return SPCERR_NULL_POINTER; err = &(spc->err); if (spc->flag == 0) { if ((status = spcset(spc))) return status; } // Convert intermediate world coordinate x to X. xp = x; specp = spec; statp = stat; for (ix = 0; ix < nx; ix++, xp += sx, specp += sspec) { *specp = spc->w[1] + (*xp)*spc->w[2]; *(statp++) = 0; } // If X is the grism parameter then convert it to wavelength. if (spc->isGrism) { specp = spec; for (ix = 0; ix < nx; ix++, specp += sspec) { beta = atand(*specp) + spc->w[3]; *specp = (sind(beta) + spc->w[4]) * spc->w[5]; } } // Apply the non-linear step of the algorithm chain to convert the // X-type spectral variable to P-type intermediate spectral variable. if (spc->spxX2P) { if ((statX2P = spc->spxX2P(spc->w[0], nx, sspec, sspec, spec, spec, stat))) { if (statX2P == SPXERR_BAD_INSPEC_COORD) { status = SPCERR_BAD_X; } else if (statX2P == SPXERR_BAD_SPEC_PARAMS) { return wcserr_set(WCSERR_SET(SPCERR_BAD_SPEC_PARAMS), "Invalid spectral parameters: Frequency or wavelength is 0"); } else { return wcserr_set(SPC_ERRMSG(spc_spxerr[statX2P])); } } } // Apply the linear step of the algorithm chain to convert P-type // intermediate spectral variable to the required S-type variable. if (spc->spxP2S) { if ((statP2S = spc->spxP2S(spc->w[0], nx, sspec, sspec, spec, spec, stat))) { if (statP2S == SPXERR_BAD_INSPEC_COORD) { status = SPCERR_BAD_X; } else if (statP2S == SPXERR_BAD_SPEC_PARAMS) { return wcserr_set(WCSERR_SET(SPCERR_BAD_SPEC_PARAMS), "Invalid spectral parameters: Frequency or wavelength is 0"); } else { return wcserr_set(SPC_ERRMSG(spc_spxerr[statP2S])); } } } if (status) { wcserr_set(SPC_ERRMSG(status)); } return status; } //---------------------------------------------------------------------------- int spcs2x( struct spcprm *spc, int nspec, int sspec, int sx, const double spec[], double x[], int stat[]) { static const char *function = "spcs2x"; int statP2X, status = 0, statS2P; double beta, s; register int ispec; register int *statp; register const double *specp; register double *xp; struct wcserr **err; // Initialize. if (spc == 0x0) return SPCERR_NULL_POINTER; err = &(spc->err); if (spc->flag == 0) { if ((status = spcset(spc))) return status; } // Apply the linear step of the algorithm chain to convert the S-type // spectral variable to P-type intermediate spectral variable. if (spc->spxS2P) { if ((statS2P = spc->spxS2P(spc->w[0], nspec, sspec, sx, spec, x, stat))) { if (statS2P == SPXERR_BAD_INSPEC_COORD) { status = SPCERR_BAD_SPEC; } else if (statS2P == SPXERR_BAD_SPEC_PARAMS) { return wcserr_set(WCSERR_SET(SPCERR_BAD_SPEC_PARAMS), "Invalid spectral parameters: Frequency or wavelength is 0"); } else { return wcserr_set(SPC_ERRMSG(spc_spxerr[statS2P])); } } } else { // Just a copy. xp = x; specp = spec; statp = stat; for (ispec = 0; ispec < nspec; ispec++, specp += sspec, xp += sx) { *xp = *specp; *(statp++) = 0; } } // Apply the non-linear step of the algorithm chain to convert P-type // intermediate spectral variable to X-type spectral variable. if (spc->spxP2X) { if ((statP2X = spc->spxP2X(spc->w[0], nspec, sx, sx, x, x, stat))) { if (statP2X == SPCERR_BAD_SPEC) { status = SPCERR_BAD_SPEC; } else if (statP2X == SPXERR_BAD_SPEC_PARAMS) { return wcserr_set(WCSERR_SET(SPCERR_BAD_SPEC_PARAMS), "Invalid spectral parameters: Frequency or wavelength is 0"); } else { return wcserr_set(SPC_ERRMSG(spc_spxerr[statP2X])); } } } if (spc->isGrism) { // Convert X-type spectral variable (wavelength) to grism parameter. xp = x; statp = stat; for (ispec = 0; ispec < nspec; ispec++, xp += sx, statp++) { if (*statp) continue; s = *xp/spc->w[5] - spc->w[4]; if (fabs(s) <= 1.0) { beta = asind(s); *xp = tand(beta - spc->w[3]); } else { *statp = 1; } } } // Convert X-type spectral variable to intermediate world coordinate x. xp = x; statp = stat; for (ispec = 0; ispec < nspec; ispec++, xp += sx) { if (*(statp++)) continue; *xp -= spc->w[1]; *xp /= spc->w[2]; } if (status) { wcserr_set(SPC_ERRMSG(status)); } return status; } //---------------------------------------------------------------------------- int spctyp( const char ctypei[9], char stype[], char scode[], char sname[], char units[], char *ptype, char *xtype, int *restreq) { return spctype( ctypei, stype, scode, sname, units, ptype, xtype, restreq, NULL); } // : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : int spctype( const char ctypei[9], char stype[], char scode[], char sname[], char units[], char *ptype, char *xtype, int *restreq, struct wcserr **err) { static const char *function = "spctype"; char ctype[9], ptype_t, sname_t[32], units_t[8], xtype_t; int restreq_t = 0; if (err) *err = 0x0; // Copy with blank padding. sprintf(ctype, "%-8.8s", ctypei); ctype[8] = '\0'; // Validate the S-type spectral variable. if (strncmp(ctype, "FREQ", 4) == 0) { strcpy(sname_t, "Frequency"); strcpy(units_t, "Hz"); ptype_t = 'F'; } else if (strncmp(ctype, "AFRQ", 4) == 0) { strcpy(sname_t, "Angular frequency"); strcpy(units_t, "rad/s"); ptype_t = 'F'; } else if (strncmp(ctype, "ENER", 4) == 0) { strcpy(sname_t, "Photon energy"); strcpy(units_t, "J"); ptype_t = 'F'; } else if (strncmp(ctype, "WAVN", 4) == 0) { strcpy(sname_t, "Wavenumber"); strcpy(units_t, "/m"); ptype_t = 'F'; } else if (strncmp(ctype, "VRAD", 4) == 0) { strcpy(sname_t, "Radio velocity"); strcpy(units_t, "m/s"); ptype_t = 'F'; restreq_t = 1; } else if (strncmp(ctype, "WAVE", 4) == 0) { strcpy(sname_t, "Vacuum wavelength"); strcpy(units_t, "m"); ptype_t = 'W'; } else if (strncmp(ctype, "VOPT", 4) == 0) { strcpy(sname_t, "Optical velocity"); strcpy(units_t, "m/s"); ptype_t = 'W'; restreq_t = 1; } else if (strncmp(ctype, "ZOPT", 4) == 0) { strcpy(sname_t, "Redshift"); strcpy(units_t, ""); ptype_t = 'W'; restreq_t = 1; } else if (strncmp(ctype, "AWAV", 4) == 0) { strcpy(sname_t, "Air wavelength"); strcpy(units_t, "m"); ptype_t = 'A'; } else if (strncmp(ctype, "VELO", 4) == 0) { strcpy(sname_t, "Relativistic velocity"); strcpy(units_t, "m/s"); ptype_t = 'V'; } else if (strncmp(ctype, "BETA", 4) == 0) { strcpy(sname_t, "Velocity ratio (v/c)"); strcpy(units_t, ""); ptype_t = 'V'; } else { return wcserr_set(WCSERR_SET(SPCERR_BAD_SPEC_PARAMS), "Unknown spectral type '%s'", ctype); } // Determine X-type and validate the spectral algorithm code. if ((xtype_t = ctype[5]) == ' ') { // The algorithm code must be completely blank. if (strcmp(ctype+4, " ") != 0) { return wcserr_set(WCSERR_SET(SPCERR_BAD_SPEC_PARAMS), "Invalid spectral algorithm '%s'", ctype+4); } xtype_t = ptype_t; } else if (ctype[4] != '-') { return wcserr_set(WCSERR_SET(SPCERR_BAD_SPEC_PARAMS), "Invalid spectral type '%s'", ctype); } else if (strcmp(ctype+5, "LOG") == 0 || strcmp(ctype+5, "TAB") == 0) { // Logarithmic or tabular axis, not linear in any spectral type. } else if (xtype_t == 'G') { // Validate the algorithm code. if (ctype[6] != 'R') { return wcserr_set(WCSERR_SET(SPCERR_BAD_SPEC_PARAMS), "Invalid spectral algorithm '%s'", xtype_t); } // Grism coordinates... if (ctype[7] == 'I') { // ...in vacuum. xtype_t = 'w'; } else if (ctype[7] == 'A') { // ...in air. xtype_t = 'a'; } else { return wcserr_set(WCSERR_SET(SPCERR_BAD_SPEC_PARAMS), "Invalid spectral algorithm '%s'", xtype_t); } } else if (ctype[6] != '2') { // Algorithm code has invalid syntax. return wcserr_set(WCSERR_SET(SPCERR_BAD_SPEC_PARAMS), "Invalid spectral algorithm syntax '%s'", xtype_t); } else if (ctype[7] != ptype_t && ctype[7] != '?') { // The P-, and S-type variables are inconsistent. return wcserr_set(WCSERR_SET(SPCERR_BAD_SPEC_PARAMS), "In spectral type '%s', P- and S-type variables are inconsistent", ctype); } else if (ctype[7] == ctype[5]) { // Degenerate algorithm code. sprintf(ctype+4, " "); } // Rest freq/wavelength required for transformation between P and X? if (strchr("FWAwa", (int)xtype_t)) { if (ptype_t == 'V') { restreq_t += 2; } } else if (xtype_t == 'V') { if (strchr("FWAwa", (int)ptype_t)) { restreq_t += 2; } } else if (strchr("LT", (int)xtype_t) == 0) { // Invalid X-type variable code. return wcserr_set(WCSERR_SET(SPCERR_BAD_SPEC_PARAMS), "In spectral type '%s', invalid X-type variable code", ctype); } // Copy results. if (stype) { memcpy(stype, ctype, 4); stype[4] = '\0'; } if (scode) strcpy(scode, ctype+5); if (sname) strcpy(sname, sname_t); if (units) strcpy(units, units_t); if (ptype) *ptype = ptype_t; if (xtype) *xtype = xtype_t; if (restreq) *restreq = restreq_t; return 0; } //---------------------------------------------------------------------------- int spcspx( const char ctypeS[9], double crvalS, double restfrq, double restwav, char *ptype, char *xtype, int *restreq, double *crvalX, double *dXdS) { return spcspxe(ctypeS, crvalS, restfrq, restwav, ptype, xtype, restreq, crvalX, dXdS, 0x0); } // : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : int spcspxe( const char ctypeS[9], double crvalS, double restfrq, double restwav, char *ptype, char *xtype, int *restreq, double *crvalX, double *dXdS, struct wcserr **err) { static const char *function = "spcspxe"; char scode[4], stype[5], type[8]; int status; double dPdS, dXdP; struct spxprm spx; // Analyse the spectral axis code. if ((status = spctype(ctypeS, stype, scode, 0x0, 0x0, ptype, xtype, restreq, err))) { return status; } if (strchr("LT", (int)(*xtype))) { // Can't handle logarithmic or tabular coordinates. return wcserr_set(WCSERR_SET(SPCERR_BAD_SPEC_PARAMS), "Can't handle logarithmic or tabular coordinates"); } // Do we have rest frequency and/or wavelength as required? if ((*restreq)%3 && restfrq == 0.0 && restwav == 0.0) { return wcserr_set(WCSERR_SET(SPCERR_BAD_SPEC_PARAMS), "Missing required rest frequency or wavelength"); } // Compute all spectral parameters and their derivatives. strcpy(type, stype); spx.err = (err ? *err : 0x0); if ((status = specx(type, crvalS, restfrq, restwav, &spx))) { status = spc_spxerr[status]; if (err) { if ((*err = spx.err)) { (*err)->status = status; } } else { wcserr_clear(&(spx.err)); } return status; } // Transform S-P (linear) and P-X (non-linear). dPdS = 0.0; dXdP = 0.0; if (*ptype == 'F') { if (strcmp(stype, "FREQ") == 0) { dPdS = 1.0; } else if (strcmp(stype, "AFRQ") == 0) { dPdS = spx.dfreqafrq; } else if (strcmp(stype, "ENER") == 0) { dPdS = spx.dfreqener; } else if (strcmp(stype, "WAVN") == 0) { dPdS = spx.dfreqwavn; } else if (strcmp(stype, "VRAD") == 0) { dPdS = spx.dfreqvrad; } if (*xtype == 'F') { *crvalX = spx.freq; dXdP = 1.0; } else if (*xtype == 'W' || *xtype == 'w') { *crvalX = spx.wave; dXdP = spx.dwavefreq; } else if (*xtype == 'A' || *xtype == 'a') { *crvalX = spx.awav; dXdP = spx.dawavfreq; } else if (*xtype == 'V') { *crvalX = spx.velo; dXdP = spx.dvelofreq; } } else if (*ptype == 'W' || *ptype == 'w') { if (strcmp(stype, "WAVE") == 0) { dPdS = 1.0; } else if (strcmp(stype, "VOPT") == 0) { dPdS = spx.dwavevopt; } else if (strcmp(stype, "ZOPT") == 0) { dPdS = spx.dwavezopt; } if (*xtype == 'F') { *crvalX = spx.freq; dXdP = spx.dfreqwave; } else if (*xtype == 'W' || *xtype == 'w') { *crvalX = spx.wave; dXdP = 1.0; } else if (*xtype == 'A' || *xtype == 'a') { *crvalX = spx.awav; dXdP = spx.dawavwave; } else if (*xtype == 'V') { *crvalX = spx.velo; dXdP = spx.dvelowave; } } else if (*ptype == 'A' || *ptype == 'a') { if (strcmp(stype, "AWAV") == 0) { dPdS = 1.0; } if (*xtype == 'F') { *crvalX = spx.freq; dXdP = spx.dfreqawav; } else if (*xtype == 'W' || *xtype == 'w') { *crvalX = spx.wave; dXdP = spx.dwaveawav; } else if (*xtype == 'A' || *xtype == 'a') { *crvalX = spx.awav; dXdP = 1.0; } else if (*xtype == 'V') { *crvalX = spx.velo; dXdP = spx.dveloawav; } } else if (*ptype == 'V') { if (strcmp(stype, "VELO") == 0) { dPdS = 1.0; } else if (strcmp(stype, "BETA") == 0) { dPdS = spx.dvelobeta; } if (*xtype == 'F') { *crvalX = spx.freq; dXdP = spx.dfreqvelo; } else if (*xtype == 'W' || *xtype == 'w') { *crvalX = spx.wave; dXdP = spx.dwavevelo; } else if (*xtype == 'A' || *xtype == 'a') { *crvalX = spx.awav; dXdP = spx.dawavvelo; } else if (*xtype == 'V') { *crvalX = spx.velo; dXdP = 1.0; } } *dXdS = dXdP * dPdS; return 0; } //---------------------------------------------------------------------------- int spcxps( const char ctypeS[9], double crvalX, double restfrq, double restwav, char *ptype, char *xtype, int *restreq, double *crvalS, double *dSdX) { return spcxpse(ctypeS, crvalX, restfrq, restwav, ptype, xtype, restreq, crvalS, dSdX, NULL); } // : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : int spcxpse( const char ctypeS[9], double crvalX, double restfrq, double restwav, char *ptype, char *xtype, int *restreq, double *crvalS, double *dSdX, struct wcserr **err) { static const char *function = "spcxpse"; char scode[4], stype[5], type[8]; int status; double dPdX, dSdP; struct spxprm spx; // Analyse the spectral axis type. if ((status = spctype(ctypeS, stype, scode, 0x0, 0x0, ptype, xtype, restreq, err))) { return status; } if (strchr("LT", (int)(*xtype))) { // Can't handle logarithmic or tabular coordinates. return wcserr_set(WCSERR_SET(SPCERR_BAD_SPEC_PARAMS), "Can't handle logarithmic or tabular coordinates"); } // Do we have rest frequency and/or wavelength as required? if ((*restreq)%3 && restfrq == 0.0 && restwav == 0.0) { return wcserr_set(WCSERR_SET(SPCERR_BAD_SPEC_PARAMS), "Missing required rest frequency or wavelength"); } // Compute all spectral parameters and their derivatives. if (*xtype == 'F') { strcpy(type, "FREQ"); } else if (*xtype == 'W' || *xtype == 'w') { strcpy(type, "WAVE"); } else if (*xtype == 'A' || *xtype == 'a') { strcpy(type, "AWAV"); } else if (*xtype == 'V') { strcpy(type, "VELO"); } spx.err = (err ? *err : 0x0); if (specx(type, crvalX, restfrq, restwav, &spx)) { status = spc_spxerr[status]; if (err) { if ((*err = spx.err)) { (*err)->status = status; } } else { wcserr_clear(&(spx.err)); } return status; } // Transform X-P (non-linear) and P-S (linear). dPdX = 0.0; dSdP = 0.0; if (*ptype == 'F') { if (*xtype == 'F') { dPdX = 1.0; } else if (*xtype == 'W' || *xtype == 'w') { dPdX = spx.dfreqwave; } else if (*xtype == 'A' || *xtype == 'a') { dPdX = spx.dfreqawav; } else if (*xtype == 'V') { dPdX = spx.dfreqvelo; } if (strcmp(stype, "FREQ") == 0) { *crvalS = spx.freq; dSdP = 1.0; } else if (strcmp(stype, "AFRQ") == 0) { *crvalS = spx.afrq; dSdP = spx.dafrqfreq; } else if (strcmp(stype, "ENER") == 0) { *crvalS = spx.ener; dSdP = spx.denerfreq; } else if (strcmp(stype, "WAVN") == 0) { *crvalS = spx.wavn; dSdP = spx.dwavnfreq; } else if (strcmp(stype, "VRAD") == 0) { *crvalS = spx.vrad; dSdP = spx.dvradfreq; } } else if (*ptype == 'W') { if (*xtype == 'F') { dPdX = spx.dwavefreq; } else if (*xtype == 'W' || *xtype == 'w') { dPdX = 1.0; } else if (*xtype == 'A' || *xtype == 'a') { dPdX = spx.dwaveawav; } else if (*xtype == 'V') { dPdX = spx.dwavevelo; } if (strcmp(stype, "WAVE") == 0) { *crvalS = spx.wave; dSdP = 1.0; } else if (strcmp(stype, "VOPT") == 0) { *crvalS = spx.vopt; dSdP = spx.dvoptwave; } else if (strcmp(stype, "ZOPT") == 0) { *crvalS = spx.zopt; dSdP = spx.dzoptwave; } } else if (*ptype == 'A') { if (*xtype == 'F') { dPdX = spx.dawavfreq; } else if (*xtype == 'W' || *xtype == 'w') { dPdX = spx.dawavwave; } else if (*xtype == 'A' || *xtype == 'a') { dPdX = 1.0; } else if (*xtype == 'V') { dPdX = spx.dawavvelo; } if (strcmp(stype, "AWAV") == 0) { *crvalS = spx.awav; dSdP = 1.0; } } else if (*ptype == 'V') { if (*xtype == 'F') { dPdX = spx.dvelofreq; } else if (*xtype == 'W' || *xtype == 'w') { dPdX = spx.dvelowave; } else if (*xtype == 'A' || *xtype == 'a') { dPdX = spx.dveloawav; } else if (*xtype == 'V') { dPdX = 1.0; } if (strcmp(stype, "VELO") == 0) { *crvalS = spx.velo; dSdP = 1.0; } else if (strcmp(stype, "BETA") == 0) { *crvalS = spx.beta; dSdP = spx.dbetavelo; } } *dSdX = dSdP * dPdX; return 0; } //---------------------------------------------------------------------------- int spctrn( const char ctypeS1[9], double crvalS1, double cdeltS1, double restfrq, double restwav, char ctypeS2[9], double *crvalS2, double *cdeltS2) { return spctrne(ctypeS1, crvalS1, cdeltS1, restfrq, restwav, ctypeS2, crvalS2, cdeltS2, NULL); } // : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : int spctrne( const char ctypeS1[9], double crvalS1, double cdeltS1, double restfrq, double restwav, char ctypeS2[9], double *crvalS2, double *cdeltS2, struct wcserr **err) { static const char *function = "spctrne"; char *cp, ptype1, ptype2, stype1[5], stype2[5], xtype1, xtype2; int restreq, status; double crvalX, dS2dX, dXdS1; if (restfrq == 0.0 && restwav == 0.0) { // If translating between two velocity-characteristic types, or between // two wave-characteristic types, then we may need to set a dummy rest // frequency or wavelength to perform the calculations. strncpy(stype1, ctypeS1, 4); strncpy(stype2, ctypeS2, 4); stype1[4] = stype2[4] = '\0'; if ((strstr("VRAD VOPT ZOPT VELO BETA", stype1) != 0x0) == (strstr("VRAD VOPT ZOPT VELO BETA", stype2) != 0x0)) { restwav = 1.0; } } if ((status = spcspxe(ctypeS1, crvalS1, restfrq, restwav, &ptype1, &xtype1, &restreq, &crvalX, &dXdS1, err))) { return status; } // Pad with blanks. ctypeS2[8] = '\0'; for (cp = ctypeS2; *cp; cp++); while (cp < ctypeS2+8) *(cp++) = ' '; if (strncmp(ctypeS2+5, "???", 3) == 0) { // Set the algorithm code if required. if (xtype1 == 'w') { strcpy(ctypeS2+5, "GRI"); } else if (xtype1 == 'a') { strcpy(ctypeS2+5, "GRA"); } else { ctypeS2[5] = xtype1; ctypeS2[6] = '2'; } } if ((status = spcxpse(ctypeS2, crvalX, restfrq, restwav, &ptype2, &xtype2, &restreq, crvalS2, &dS2dX, err))) { return status; } // Are the X-types compatible? if (xtype2 != xtype1) { return wcserr_set(WCSERR_SET(SPCERR_BAD_SPEC_PARAMS), "Incompatible X-types '%c' and '%c'", xtype1, xtype2); } if (ctypeS2[7] == '?') { if (ptype2 == xtype2) { strcpy(ctypeS2+4, " "); } else { ctypeS2[7] = ptype2; } } *cdeltS2 = dS2dX * dXdS1 * cdeltS1; return 0; } //---------------------------------------------------------------------------- int spcaips( const char ctypeA[9], int velref, char ctype[9], char specsys[9]) { const char *frames[] = {"LSRK", "BARYCENT", "TOPOCENT", "LSRD", "GEOCENTR", "SOURCE", "GALACTOC"}; char *fcode; int ivf, status; // Make a null-filled copy of ctypeA. if (ctype != ctypeA) strncpy(ctype, ctypeA, 8); ctype[8] = '\0'; wcsutil_null_fill(9, ctype); *specsys = '\0'; // Is it a recognized AIPS-convention type? status = SPCERR_NO_CHANGE; if (strncmp(ctype, "FREQ", 4) == 0 || strncmp(ctype, "VELO", 4) == 0 || strncmp(ctype, "FELO", 4) == 0) { // Look for the Doppler frame. if (*(fcode = ctype+4)) { if (strcmp(fcode, "-LSR") == 0) { strcpy(specsys, "LSRK"); } else if (strcmp(fcode, "-HEL") == 0) { strcpy(specsys, "BARYCENT"); } else if (strcmp(fcode, "-OBS") == 0) { strcpy(specsys, "TOPOCENT"); } else { // Not a recognized AIPS spectral type. return SPCERR_NO_CHANGE; } *fcode = '\0'; status = 0; } // VELREF takes precedence if present. ivf = velref%256; if (0 < ivf && ivf <= 7) { strcpy(specsys, frames[ivf-1]); status = 0; } else if (ivf) { status = SPCERR_BAD_SPEC_PARAMS; } if (strcmp(ctype, "VELO") == 0) { // Check that we found an AIPS-convention Doppler frame. if (*specsys) { // 'VELO' in AIPS means radio or optical depending on VELREF. ivf = velref/256; if (ivf == 0) { strcpy(ctype, "VOPT"); } else if (ivf == 1) { strcpy(ctype, "VRAD"); } else { status = SPCERR_BAD_SPEC_PARAMS; } } } else if (strcmp(ctype, "FELO") == 0) { // Uniform in frequency but expressed as an optical velocity (strictly // we should also have found an AIPS-convention Doppler frame). strcpy(ctype, "VOPT-F2W"); if (status < 0) status = 0; } } return status; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/spc.h0000644000175100001710000011643700000000000016334 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: spc.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the spc routines * --------------------------- * Routines in this suite implement the part of the FITS World Coordinate * System (WCS) standard that deals with spectral coordinates, as described in * = "Representations of world coordinates in FITS", = Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (WCS Paper I) = = "Representations of spectral coordinates in FITS", = Greisen, E.W., Calabretta, M.R., Valdes, F.G., & Allen, S.L. = 2006, A&A, 446, 747 (WCS Paper III) * * These routines define methods to be used for computing spectral world * coordinates from intermediate world coordinates (a linear transformation * of image pixel coordinates), and vice versa. They are based on the spcprm * struct which contains all information needed for the computations. The * struct contains some members that must be set by the user, and others that * are maintained by these routines, somewhat like a C++ class but with no * encapsulation. * * Routine spcini() is provided to initialize the spcprm struct with default * values, spcfree() reclaims any memory that may have been allocated to store * an error message, spcsize() computes its total size including allocated * memory, and spcprt() prints its contents. * * spcperr() prints the error message(s) (if any) stored in a spcprm struct. * * A setup routine, spcset(), computes intermediate values in the spcprm struct * from parameters in it that were supplied by the user. The struct always * needs to be set up by spcset() but it need not be called explicitly - refer * to the explanation of spcprm::flag. * * spcx2s() and spcs2x() implement the WCS spectral coordinate transformations. * In fact, they are high level driver routines for the lower level spectral * coordinate transformation routines described in spx.h. * * A number of routines are provided to aid in analysing or synthesising sets * of FITS spectral axis keywords: * * - spctype() checks a spectral CTYPEia keyword for validity and returns * information derived from it. * * - Spectral keyword analysis routine spcspxe() computes the values of the * X-type spectral variables for the S-type variables supplied. * * - Spectral keyword synthesis routine, spcxpse(), computes the S-type * variables for the X-types supplied. * * - Given a set of spectral keywords, a translation routine, spctrne(), * produces the corresponding set for the specified spectral CTYPEia. * * - spcaips() translates AIPS-convention spectral CTYPEia and VELREF * keyvalues. * * Spectral variable types - S, P, and X: * -------------------------------------- * A few words of explanation are necessary regarding spectral variable types * in FITS. * * Every FITS spectral axis has three associated spectral variables: * * S-type: the spectral variable in which coordinates are to be * expressed. Each S-type is encoded as four characters and is * linearly related to one of four basic types as follows: * * F (Frequency): * - 'FREQ': frequency * - 'AFRQ': angular frequency * - 'ENER': photon energy * - 'WAVN': wave number * - 'VRAD': radio velocity * * W (Wavelength in vacuo): * - 'WAVE': wavelength * - 'VOPT': optical velocity * - 'ZOPT': redshift * * A (wavelength in Air): * - 'AWAV': wavelength in air * * V (Velocity): * - 'VELO': relativistic velocity * - 'BETA': relativistic beta factor * * The S-type forms the first four characters of the CTYPEia keyvalue, * and CRVALia and CDELTia are expressed as S-type quantities so that * they provide a first-order approximation to the S-type variable at * the reference point. * * Note that 'AFRQ', angular frequency, is additional to the variables * defined in WCS Paper III. * * P-type: the basic spectral variable (F, W, A, or V) with which the * S-type variable is associated (see list above). * * For non-grism axes, the P-type is encoded as the eighth character of * CTYPEia. * * X-type: the basic spectral variable (F, W, A, or V) for which the * spectral axis is linear, grisms excluded (see below). * * For non-grism axes, the X-type is encoded as the sixth character of * CTYPEia. * * Grisms: Grism axes have normal S-, and P-types but the axis is linear, * not in any spectral variable, but in a special "grism parameter". * The X-type spectral variable is either W or A for grisms in vacuo or * air respectively, but is encoded as 'w' or 'a' to indicate that an * additional transformation is required to convert to or from the * grism parameter. The spectral algorithm code for grisms also has a * special encoding in CTYPEia, either 'GRI' (in vacuo) or 'GRA' (in air). * * In the algorithm chain, the non-linear transformation occurs between the * X-type and the P-type variables; the transformation between P-type and * S-type variables is always linear. * * When the P-type and X-type variables are the same, the spectral axis is * linear in the S-type variable and the second four characters of CTYPEia * are blank. This can never happen for grism axes. * * As an example, correlating radio spectrometers always produce spectra that * are regularly gridded in frequency; a redshift scale on such a spectrum is * non-linear. The required value of CTYPEia would be 'ZOPT-F2W', where the * desired S-type is 'ZOPT' (redshift), the P-type is necessarily 'W' * (wavelength), and the X-type is 'F' (frequency) by the nature of the * instrument. * * Air-to-vacuum wavelength conversion: * ------------------------------------ * Please refer to the prologue of spx.h for important comments relating to the * air-to-vacuum wavelength conversion. * * Argument checking: * ------------------ * The input spectral values are only checked for values that would result in * floating point exceptions. In particular, negative frequencies and * wavelengths are allowed, as are velocities greater than the speed of * light. The same is true for the spectral parameters - rest frequency and * wavelength. * * Accuracy: * --------- * No warranty is given for the accuracy of these routines (refer to the * copyright notice); intending users must satisfy for themselves their * adequacy for the intended purpose. However, closure effectively to within * double precision rounding error was demonstrated by test routine tspc.c * which accompanies this software. * * * spcini() - Default constructor for the spcprm struct * ---------------------------------------------------- * spcini() sets all members of a spcprm struct to default values. It should * be used to initialize every spcprm struct. * * PLEASE NOTE: If the spcprm struct has already been initialized, then before * reinitializing, it spcfree() should be used to free any memory that may have * been allocated to store an error message. A memory leak may otherwise * result. * * Given and returned: * spc struct spcprm* * Spectral transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null spcprm pointer passed. * * * spcfree() - Destructor for the spcprm struct * -------------------------------------------- * spcfree() frees any memory that may have been allocated to store an error * message in the spcprm struct. * * Given: * spc struct spcprm* * Spectral transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null spcprm pointer passed. * * * spcsize() - Compute the size of a spcprm struct * ----------------------------------------------- * spcsize() computes the full size of a spcprm struct, including allocated * memory. * * Given: * spc const struct spcprm* * Spectral transformation parameters. * * If NULL, the base size of the struct and the allocated * size are both set to zero. * * Returned: * sizes int[2] The first element is the base size of the struct as * returned by sizeof(struct spcprm). The second element * is the total allocated size, in bytes. This figure * includes memory allocated for the constituent struct, * spcprm::err. * * It is not an error for the struct not to have been set * up via spcset(). * * Function return value: * int Status return value: * 0: Success. * * * spcprt() - Print routine for the spcprm struct * ---------------------------------------------- * spcprt() prints the contents of a spcprm struct using wcsprintf(). Mainly * intended for diagnostic purposes. * * Given: * spc const struct spcprm* * Spectral transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null spcprm pointer passed. * * * spcperr() - Print error messages from a spcprm struct * ----------------------------------------------------- * spcperr() prints the error message(s) (if any) stored in a spcprm struct. * If there are no errors then nothing is printed. It uses wcserr_prt(), q.v. * * Given: * spc const struct spcprm* * Spectral transformation parameters. * * prefix const char * * If non-NULL, each output line will be prefixed with * this string. * * Function return value: * int Status return value: * 0: Success. * 1: Null spcprm pointer passed. * * * spcset() - Setup routine for the spcprm struct * ---------------------------------------------- * spcset() sets up a spcprm struct according to information supplied within * it. * * Note that this routine need not be called directly; it will be invoked by * spcx2s() and spcs2x() if spcprm::flag is anything other than a predefined * magic value. * * Given and returned: * spc struct spcprm* * Spectral transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null spcprm pointer passed. * 2: Invalid spectral parameters. * * For returns > 1, a detailed error message is set in * spcprm::err if enabled, see wcserr_enable(). * * * spcx2s() - Transform to spectral coordinates * -------------------------------------------- * spcx2s() transforms intermediate world coordinates to spectral coordinates. * * Given and returned: * spc struct spcprm* * Spectral transformation parameters. * * Given: * nx int Vector length. * * sx int Vector stride. * * sspec int Vector stride. * * x const double[] * Intermediate world coordinates, in SI units. * * Returned: * spec double[] Spectral coordinates, in SI units. * * stat int[] Status return value status for each vector element: * 0: Success. * 1: Invalid value of x. * * Function return value: * int Status return value: * 0: Success. * 1: Null spcprm pointer passed. * 2: Invalid spectral parameters. * 3: One or more of the x coordinates were invalid, * as indicated by the stat vector. * * For returns > 1, a detailed error message is set in * spcprm::err if enabled, see wcserr_enable(). * * * spcs2x() - Transform spectral coordinates * ----------------------------------------- * spcs2x() transforms spectral world coordinates to intermediate world * coordinates. * * Given and returned: * spc struct spcprm* * Spectral transformation parameters. * * Given: * nspec int Vector length. * * sspec int Vector stride. * * sx int Vector stride. * * spec const double[] * Spectral coordinates, in SI units. * * Returned: * x double[] Intermediate world coordinates, in SI units. * * stat int[] Status return value status for each vector element: * 0: Success. * 1: Invalid value of spec. * * Function return value: * int Status return value: * 0: Success. * 1: Null spcprm pointer passed. * 2: Invalid spectral parameters. * 4: One or more of the spec coordinates were * invalid, as indicated by the stat vector. * * For returns > 1, a detailed error message is set in * spcprm::err if enabled, see wcserr_enable(). * * * spctype() - Spectral CTYPEia keyword analysis * --------------------------------------------- * spctype() checks whether a CTYPEia keyvalue is a valid spectral axis type * and if so returns information derived from it relating to the associated S-, * P-, and X-type spectral variables (see explanation above). * * The return arguments are guaranteed not be modified if CTYPEia is not a * valid spectral type; zero-pointers may be specified for any that are not of * interest. * * A deprecated form of this function, spctyp(), lacks the wcserr** parameter. * * Given: * ctype const char[9] * The CTYPEia keyvalue, (eight characters with null * termination). * * Returned: * stype char[] The four-letter name of the S-type spectral variable * copied or translated from ctype. If a non-zero * pointer is given, the array must accomodate a null- * terminated string of length 5. * * scode char[] The three-letter spectral algorithm code copied or * translated from ctype. Logarithmic ('LOG') and * tabular ('TAB') codes are also recognized. If a * non-zero pointer is given, the array must accomodate a * null-terminated string of length 4. * * sname char[] Descriptive name of the S-type spectral variable. * If a non-zero pointer is given, the array must * accomodate a null-terminated string of length 22. * * units char[] SI units of the S-type spectral variable. If a * non-zero pointer is given, the array must accomodate a * null-terminated string of length 8. * * ptype char* Character code for the P-type spectral variable * derived from ctype, one of 'F', 'W', 'A', or 'V'. * * xtype char* Character code for the X-type spectral variable * derived from ctype, one of 'F', 'W', 'A', or 'V'. * Also, 'w' and 'a' are synonymous to 'W' and 'A' for * grisms in vacuo and air respectively. Set to 'L' or * 'T' for logarithmic ('LOG') and tabular ('TAB') axes. * * restreq int* Multivalued flag that indicates whether rest * frequency or wavelength is required to compute * spectral variables for this CTYPEia: * 0: Not required. * 1: Required for the conversion between S- and * P-types (e.g. 'ZOPT-F2W'). * 2: Required for the conversion between P- and * X-types (e.g. 'BETA-W2V'). * 3: Required for the conversion between S- and * P-types, and between P- and X-types, but not * between S- and X-types (this applies only for * 'VRAD-V2F', 'VOPT-V2W', and 'ZOPT-V2W'). * Thus the rest frequency or wavelength is required for * spectral coordinate computations (i.e. between S- and * X-types) only if restreq%3 != 0. * * err struct wcserr ** * If enabled, for function return values > 1, this * struct will contain a detailed error message, see * wcserr_enable(). May be NULL if an error message is * not desired. Otherwise, the user is responsible for * deleting the memory allocated for the wcserr struct. * * Function return value: * int Status return value: * 0: Success. * 2: Invalid spectral parameters (not a spectral * CTYPEia). * * * spcspxe() - Spectral keyword analysis * ------------------------------------ * spcspxe() analyses the CTYPEia and CRVALia FITS spectral axis keyword values * and returns information about the associated X-type spectral variable. * * A deprecated form of this function, spcspx(), lacks the wcserr** parameter. * * Given: * ctypeS const char[9] * Spectral axis type, i.e. the CTYPEia keyvalue, (eight * characters with null termination). For non-grism * axes, the character code for the P-type spectral * variable in the algorithm code (i.e. the eighth * character of CTYPEia) may be set to '?' (it will not * be reset). * * crvalS double Value of the S-type spectral variable at the reference * point, i.e. the CRVALia keyvalue, SI units. * * restfrq, * restwav double Rest frequency [Hz] and rest wavelength in vacuo [m], * only one of which need be given, the other should be * set to zero. * * Returned: * ptype char* Character code for the P-type spectral variable * derived from ctypeS, one of 'F', 'W', 'A', or 'V'. * * xtype char* Character code for the X-type spectral variable * derived from ctypeS, one of 'F', 'W', 'A', or 'V'. * Also, 'w' and 'a' are synonymous to 'W' and 'A' for * grisms in vacuo and air respectively; crvalX and dXdS * (see below) will conform to these. * * restreq int* Multivalued flag that indicates whether rest frequency * or wavelength is required to compute spectral * variables for this CTYPEia, as for spctype(). * * crvalX double* Value of the X-type spectral variable at the reference * point, SI units. * * dXdS double* The derivative, dX/dS, evaluated at the reference * point, SI units. Multiply the CDELTia keyvalue by * this to get the pixel spacing in the X-type spectral * coordinate. * * err struct wcserr ** * If enabled, for function return values > 1, this * struct will contain a detailed error message, see * wcserr_enable(). May be NULL if an error message is * not desired. Otherwise, the user is responsible for * deleting the memory allocated for the wcserr struct. * * Function return value: * int Status return value: * 0: Success. * 2: Invalid spectral parameters. * * * spcxpse() - Spectral keyword synthesis * ------------------------------------- * spcxpse(), for the spectral axis type specified and the value provided for * the X-type spectral variable at the reference point, deduces the value of * the FITS spectral axis keyword CRVALia and also the derivative dS/dX which * may be used to compute CDELTia. See above for an explanation of the S-, * P-, and X-type spectral variables. * * A deprecated form of this function, spcxps(), lacks the wcserr** parameter. * * Given: * ctypeS const char[9] * The required spectral axis type, i.e. the CTYPEia * keyvalue, (eight characters with null termination). * For non-grism axes, the character code for the P-type * spectral variable in the algorithm code (i.e. the * eighth character of CTYPEia) may be set to '?' (it * will not be reset). * * crvalX double Value of the X-type spectral variable at the reference * point (N.B. NOT the CRVALia keyvalue), SI units. * * restfrq, * restwav double Rest frequency [Hz] and rest wavelength in vacuo [m], * only one of which need be given, the other should be * set to zero. * * Returned: * ptype char* Character code for the P-type spectral variable * derived from ctypeS, one of 'F', 'W', 'A', or 'V'. * * xtype char* Character code for the X-type spectral variable * derived from ctypeS, one of 'F', 'W', 'A', or 'V'. * Also, 'w' and 'a' are synonymous to 'W' and 'A' for * grisms; crvalX and cdeltX must conform to these. * * restreq int* Multivalued flag that indicates whether rest frequency * or wavelength is required to compute spectral * variables for this CTYPEia, as for spctype(). * * crvalS double* Value of the S-type spectral variable at the reference * point (i.e. the appropriate CRVALia keyvalue), SI * units. * * dSdX double* The derivative, dS/dX, evaluated at the reference * point, SI units. Multiply this by the pixel spacing * in the X-type spectral coordinate to get the CDELTia * keyvalue. * * err struct wcserr ** * If enabled, for function return values > 1, this * struct will contain a detailed error message, see * wcserr_enable(). May be NULL if an error message is * not desired. Otherwise, the user is responsible for * deleting the memory allocated for the wcserr struct. * * Function return value: * int Status return value: * 0: Success. * 2: Invalid spectral parameters. * * * spctrne() - Spectral keyword translation * --------------------------------------- * spctrne() translates a set of FITS spectral axis keywords into the * corresponding set for the specified spectral axis type. For example, a * 'FREQ' axis may be translated into 'ZOPT-F2W' and vice versa. * * A deprecated form of this function, spctrn(), lacks the wcserr** parameter. * * Given: * ctypeS1 const char[9] * Spectral axis type, i.e. the CTYPEia keyvalue, (eight * characters with null termination). For non-grism * axes, the character code for the P-type spectral * variable in the algorithm code (i.e. the eighth * character of CTYPEia) may be set to '?' (it will not * be reset). * * crvalS1 double Value of the S-type spectral variable at the reference * point, i.e. the CRVALia keyvalue, SI units. * * cdeltS1 double Increment of the S-type spectral variable at the * reference point, SI units. * * restfrq, * restwav double Rest frequency [Hz] and rest wavelength in vacuo [m], * only one of which need be given, the other should be * set to zero. Neither are required if the translation * is between wave-characteristic types, or between * velocity-characteristic types. E.g., required for * 'FREQ' -> 'ZOPT-F2W', but not required for * 'VELO-F2V' -> 'ZOPT-F2W'. * * Given and returned: * ctypeS2 char[9] Required spectral axis type (eight characters with * null termination). The first four characters are * required to be given and are never modified. The * remaining four, the algorithm code, are completely * determined by, and must be consistent with, ctypeS1 * and the first four characters of ctypeS2. A non-zero * status value will be returned if they are inconsistent * (see below). However, if the final three characters * are specified as "???", or if just the eighth * character is specified as '?', the correct algorithm * code will be substituted (applies for grism axes as * well as non-grism). * * Returned: * crvalS2 double* Value of the new S-type spectral variable at the * reference point, i.e. the new CRVALia keyvalue, SI * units. * * cdeltS2 double* Increment of the new S-type spectral variable at the * reference point, i.e. the new CDELTia keyvalue, SI * units. * * err struct wcserr ** * If enabled, for function return values > 1, this * struct will contain a detailed error message, see * wcserr_enable(). May be NULL if an error message is * not desired. Otherwise, the user is responsible for * deleting the memory allocated for the wcserr struct. * * Function return value: * int Status return value: * 0: Success. * 2: Invalid spectral parameters. * * A status value of 2 will be returned if restfrq or * restwav are not specified when required, or if ctypeS1 * or ctypeS2 are self-inconsistent, or have different * spectral X-type variables. * * * spcaips() - Translate AIPS-convention spectral keywords * ------------------------------------------------------- * spcaips() translates AIPS-convention spectral CTYPEia and VELREF keyvalues. * * Given: * ctypeA const char[9] * CTYPEia keyvalue possibly containing an * AIPS-convention spectral code (eight characters, need * not be null-terminated). * * velref int AIPS-convention VELREF code. It has the following * integer values: * 1: LSR kinematic, originally described simply as * "LSR" without distinction between the kinematic * and dynamic definitions. * 2: Barycentric, originally described as "HEL" * meaning heliocentric. * 3: Topocentric, originally described as "OBS" * meaning geocentric but widely interpreted as * topocentric. * AIPS++ extensions to VELREF are also recognized: * 4: LSR dynamic. * 5: Geocentric. * 6: Source rest frame. * 7: Galactocentric. * * For an AIPS 'VELO' axis, a radio convention velocity * (VRAD) is denoted by adding 256 to VELREF, otherwise * an optical velocity (VOPT) is indicated (this is not * applicable to 'FREQ' or 'FELO' axes). Setting velref * to 0 or 256 chooses between optical and radio velocity * without specifying a Doppler frame, provided that a * frame is encoded in ctypeA. If not, i.e. for * ctypeA = 'VELO', ctype will be returned as 'VELO'. * * VELREF takes precedence over CTYPEia in defining the * Doppler frame, e.g. * = ctypeA = 'VELO-HEL' = velref = 1 * * returns ctype = 'VOPT' with specsys set to 'LSRK'. * * If omitted from the header, the default value of * VELREF is 0. * * Returned: * ctype char[9] Translated CTYPEia keyvalue, or a copy of ctypeA if no * translation was performed (in which case any trailing * blanks in ctypeA will be replaced with nulls). * * specsys char[9] Doppler reference frame indicated by VELREF or else * by CTYPEia with value corresponding to the SPECSYS * keyvalue in the FITS WCS standard. May be returned * blank if neither specifies a Doppler frame, e.g. * ctypeA = 'FELO' and velref%256 == 0. * * Function return value: * int Status return value: * -1: No translation required (not an error). * 0: Success. * 2: Invalid value of VELREF. * * * spcprm struct - Spectral transformation parameters * -------------------------------------------------- * The spcprm struct contains information required to transform spectral * coordinates. It consists of certain members that must be set by the user * ("given") and others that are set by the WCSLIB routines ("returned"). Some * of the latter are supplied for informational purposes while others are for * internal use only. * * int flag * (Given and returned) This flag must be set to zero whenever any of the * following spcprm structure members are set or changed: * * - spcprm::type, * - spcprm::code, * - spcprm::crval, * - spcprm::restfrq, * - spcprm::restwav, * - spcprm::pv[]. * * This signals the initialization routine, spcset(), to recompute the * returned members of the spcprm struct. spcset() will reset flag to * indicate that this has been done. * * char type[8] * (Given) Four-letter spectral variable type, e.g "ZOPT" for * CTYPEia = 'ZOPT-F2W'. (Declared as char[8] for alignment reasons.) * * char code[4] * (Given) Three-letter spectral algorithm code, e.g "F2W" for * CTYPEia = 'ZOPT-F2W'. * * double crval * (Given) Reference value (CRVALia), SI units. * * double restfrq * (Given) The rest frequency [Hz], and ... * * double restwav * (Given) ... the rest wavelength in vacuo [m], only one of which need be * given, the other should be set to zero. Neither are required if the * X and S spectral variables are both wave-characteristic, or both * velocity-characteristic, types. * * double pv[7] * (Given) Grism parameters for 'GRI' and 'GRA' algorithm codes: * - 0: G, grating ruling density. * - 1: m, interference order. * - 2: alpha, angle of incidence [deg]. * - 3: n_r, refractive index at the reference wavelength, lambda_r. * - 4: n'_r, dn/dlambda at the reference wavelength, lambda_r (/m). * - 5: epsilon, grating tilt angle [deg]. * - 6: theta, detector tilt angle [deg]. * * The remaining members of the spcprm struct are maintained by spcset() and * must not be modified elsewhere: * * double w[6] * (Returned) Intermediate values: * - 0: Rest frequency or wavelength (SI). * - 1: The value of the X-type spectral variable at the reference point * (SI units). * - 2: dX/dS at the reference point (SI units). * The remainder are grism intermediates. * * int isGrism * (Returned) Grism coordinates? * - 0: no, * - 1: in vacuum, * - 2: in air. * * int padding1 * (An unused variable inserted for alignment purposes only.) * * struct wcserr *err * (Returned) If enabled, when an error status is returned, this struct * contains detailed information about the error, see wcserr_enable(). * * void *padding2 * (An unused variable inserted for alignment purposes only.) * int (*spxX2P)(SPX_ARGS) * (Returned) The first and ... * int (*spxP2S)(SPX_ARGS) * (Returned) ... the second of the pointers to the transformation * functions in the two-step algorithm chain X -> P -> S in the * pixel-to-spectral direction where the non-linear transformation is from * X to P. The argument list, SPX_ARGS, is defined in spx.h. * * int (*spxS2P)(SPX_ARGS) * (Returned) The first and ... * int (*spxP2X)(SPX_ARGS) * (Returned) ... the second of the pointers to the transformation * functions in the two-step algorithm chain S -> P -> X in the * spectral-to-pixel direction where the non-linear transformation is from * P to X. The argument list, SPX_ARGS, is defined in spx.h. * * * Global variable: const char *spc_errmsg[] - Status return messages * ------------------------------------------------------------------ * Error messages to match the status value returned from each function. * *===========================================================================*/ #ifndef WCSLIB_SPC #define WCSLIB_SPC #include "spx.h" #ifdef __cplusplus extern "C" { #endif extern const char *spc_errmsg[]; enum spc_errmsg_enum { SPCERR_NO_CHANGE = -1, // No change. SPCERR_SUCCESS = 0, // Success. SPCERR_NULL_POINTER = 1, // Null spcprm pointer passed. SPCERR_BAD_SPEC_PARAMS = 2, // Invalid spectral parameters. SPCERR_BAD_X = 3, // One or more of x coordinates were // invalid. SPCERR_BAD_SPEC = 4 // One or more of the spec coordinates were // invalid. }; struct spcprm { // Initialization flag (see the prologue above). //-------------------------------------------------------------------------- int flag; // Set to zero to force initialization. // Parameters to be provided (see the prologue above). //-------------------------------------------------------------------------- char type[8]; // Four-letter spectral variable type. char code[4]; // Three-letter spectral algorithm code. double crval; // Reference value (CRVALia), SI units. double restfrq; // Rest frequency, Hz. double restwav; // Rest wavelength, m. double pv[7]; // Grism parameters: // 0: G, grating ruling density. // 1: m, interference order. // 2: alpha, angle of incidence. // 3: n_r, refractive index at lambda_r. // 4: n'_r, dn/dlambda at lambda_r. // 5: epsilon, grating tilt angle. // 6: theta, detector tilt angle. // Information derived from the parameters supplied. //-------------------------------------------------------------------------- double w[6]; // Intermediate values. // 0: Rest frequency or wavelength (SI). // 1: CRVALX (SI units). // 2: CDELTX/CDELTia = dX/dS (SI units). // The remainder are grism intermediates. int isGrism; // Grism coordinates? 1: vacuum, 2: air. int padding1; // (Dummy inserted for alignment purposes.) // Error handling //-------------------------------------------------------------------------- struct wcserr *err; // Private //-------------------------------------------------------------------------- void *padding2; // (Dummy inserted for alignment purposes.) int (*spxX2P)(SPX_ARGS); // Pointers to the transformation functions int (*spxP2S)(SPX_ARGS); // in the two-step algorithm chain in the // pixel-to-spectral direction. int (*spxS2P)(SPX_ARGS); // Pointers to the transformation functions int (*spxP2X)(SPX_ARGS); // in the two-step algorithm chain in the // spectral-to-pixel direction. }; // Size of the spcprm struct in int units, used by the Fortran wrappers. #define SPCLEN (sizeof(struct spcprm)/sizeof(int)) int spcini(struct spcprm *spc); int spcfree(struct spcprm *spc); int spcsize(const struct spcprm *spc, int sizes[2]); int spcprt(const struct spcprm *spc); int spcperr(const struct spcprm *spc, const char *prefix); int spcset(struct spcprm *spc); int spcx2s(struct spcprm *spc, int nx, int sx, int sspec, const double x[], double spec[], int stat[]); int spcs2x(struct spcprm *spc, int nspec, int sspec, int sx, const double spec[], double x[], int stat[]); int spctype(const char ctype[9], char stype[], char scode[], char sname[], char units[], char *ptype, char *xtype, int *restreq, struct wcserr **err); int spcspxe(const char ctypeS[9], double crvalS, double restfrq, double restwav, char *ptype, char *xtype, int *restreq, double *crvalX, double *dXdS, struct wcserr **err); int spcxpse(const char ctypeS[9], double crvalX, double restfrq, double restwav, char *ptype, char *xtype, int *restreq, double *crvalS, double *dSdX, struct wcserr **err); int spctrne(const char ctypeS1[9], double crvalS1, double cdeltS1, double restfrq, double restwav, char ctypeS2[9], double *crvalS2, double *cdeltS2, struct wcserr **err); int spcaips(const char ctypeA[9], int velref, char ctype[9], char specsys[9]); // Deprecated. #define spcini_errmsg spc_errmsg #define spcprt_errmsg spc_errmsg #define spcset_errmsg spc_errmsg #define spcx2s_errmsg spc_errmsg #define spcs2x_errmsg spc_errmsg int spctyp(const char ctype[9], char stype[], char scode[], char sname[], char units[], char *ptype, char *xtype, int *restreq); int spcspx(const char ctypeS[9], double crvalS, double restfrq, double restwav, char *ptype, char *xtype, int *restreq, double *crvalX, double *dXdS); int spcxps(const char ctypeS[9], double crvalX, double restfrq, double restwav, char *ptype, char *xtype, int *restreq, double *crvalS, double *dSdX); int spctrn(const char ctypeS1[9], double crvalS1, double cdeltS1, double restfrq, double restwav, char ctypeS2[9], double *crvalS2, double *cdeltS2); #ifdef __cplusplus } #endif #endif // WCSLIB_SPC ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/sph.c0000644000175100001710000002571400000000000016331 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: sph.c,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *===========================================================================*/ #include #include "wcstrig.h" #include "sph.h" #define copysign(X, Y) ((Y) < 0.0 ? -fabs(X) : fabs(X)) #define tol 1.0e-5 //---------------------------------------------------------------------------- int sphx2s( const double eul[5], int nphi, int ntheta, int spt, int sll, const double phi[], const double theta[], double lng[], double lat[]) { int jphi, mphi, mtheta, rowlen, rowoff; double cosphi, costhe, costhe3, costhe4, dlng, dphi, sinphi, sinthe, sinthe3, sinthe4, x, y, z; register int iphi, itheta; register const double *phip, *thetap; register double *latp, *lngp; if (ntheta > 0) { mphi = nphi; mtheta = ntheta; } else { mphi = 1; mtheta = 1; ntheta = nphi; } // Check for special-case rotations. if (eul[4] == 0.0) { if (eul[1] == 0.0) { // Simple change in origin of longitude. dlng = fmod(eul[0] + 180.0 - eul[2], 360.0); jphi = 0; thetap = theta; lngp = lng; latp = lat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { phip = phi + (jphi%nphi)*spt; for (iphi = 0; iphi < mphi; iphi++, phip += spt, jphi++) { *lngp = *phip + dlng; *latp = *thetap; // Normalize the celestial longitude. if (eul[0] >= 0.0) { if (*lngp < 0.0) *lngp += 360.0; } else { if (*lngp > 0.0) *lngp -= 360.0; } if (*lngp > 360.0) { *lngp -= 360.0; } else if (*lngp < -360.0) { *lngp += 360.0; } lngp += sll; latp += sll; } } } else { // Pole-flip with change in origin of longitude. dlng = fmod(eul[0] + eul[2], 360.0); jphi = 0; thetap = theta; lngp = lng; latp = lat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { phip = phi + (jphi%nphi)*spt; for (iphi = 0; iphi < mphi; iphi++, phip += spt, jphi++) { *lngp = dlng - *phip; *latp = -(*thetap); // Normalize the celestial longitude. if (eul[0] >= 0.0) { if (*lngp < 0.0) *lngp += 360.0; } else { if (*lngp > 0.0) *lngp -= 360.0; } if (*lngp > 360.0) { *lngp -= 360.0; } else if (*lngp < -360.0) { *lngp += 360.0; } lngp += sll; latp += sll; } } } return 0; } // Do phi dependency. phip = phi; rowoff = 0; rowlen = nphi*sll; for (iphi = 0; iphi < nphi; iphi++, rowoff += sll, phip += spt) { dphi = *phip - eul[2]; lngp = lng + rowoff; for (itheta = 0; itheta < mtheta; itheta++) { *lngp = dphi; lngp += rowlen; } } // Do theta dependency. thetap = theta; lngp = lng; latp = lat; for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) { sincosd(*thetap, &sinthe, &costhe); costhe3 = costhe*eul[3]; costhe4 = costhe*eul[4]; sinthe3 = sinthe*eul[3]; sinthe4 = sinthe*eul[4]; for (iphi = 0; iphi < mphi; iphi++, lngp += sll, latp += sll) { dphi = *lngp; sincosd(dphi, &sinphi, &cosphi); // Compute the celestial longitude. x = sinthe4 - costhe3*cosphi; if (fabs(x) < tol) { // Rearrange formula to reduce roundoff errors. x = -cosd(*thetap + eul[1]) + costhe3*(1.0 - cosphi); } y = -costhe*sinphi; if (x != 0.0 || y != 0.0) { dlng = atan2d(y, x); } else { // Change of origin of longitude. if (eul[1] < 90.0) { dlng = dphi + 180.0; } else { dlng = -dphi; } } *lngp = eul[0] + dlng; // Normalize the celestial longitude. if (eul[0] >= 0.0) { if (*lngp < 0.0) *lngp += 360.0; } else { if (*lngp > 0.0) *lngp -= 360.0; } if (*lngp > 360.0) { *lngp -= 360.0; } else if (*lngp < -360.0) { *lngp += 360.0; } // Compute the celestial latitude. if (fmod(dphi,180.0) == 0.0) { *latp = *thetap + cosphi*eul[1]; if (*latp > 90.0) *latp = 180.0 - *latp; if (*latp < -90.0) *latp = -180.0 - *latp; } else { z = sinthe3 + costhe4*cosphi; if (fabs(z) > 0.99) { // Use an alternative formula for greater accuracy. *latp = copysign(acosd(sqrt(x*x+y*y)), z); } else { *latp = asind(z); } } } } return 0; } //---------------------------------------------------------------------------- int sphs2x( const double eul[5], int nlng, int nlat, int sll, int spt, const double lng[], const double lat[], double phi[], double theta[]) { int jlng, mlat, mlng, rowlen, rowoff; double coslat, coslat3, coslat4, coslng, dlng, dphi, sinlat, sinlat3, sinlat4, sinlng, x, y, z; register int ilat, ilng; register const double *latp, *lngp; register double *phip, *thetap; if (nlat > 0) { mlng = nlng; mlat = nlat; } else { mlng = 1; mlat = 1; nlat = nlng; } // Check for special-case rotations. if (eul[4] == 0.0) { if (eul[1] == 0.0) { // Simple change in origin of longitude. dphi = fmod(eul[2] - 180.0 - eul[0], 360.0); jlng = 0; latp = lat; phip = phi; thetap = theta; for (ilat = 0; ilat < nlat; ilat++, latp += sll) { lngp = lng + (jlng%nlng)*sll; for (ilng = 0; ilng < mlng; ilng++, lngp += sll, jlng++) { *phip = fmod(*lngp + dphi, 360.0); *thetap = *latp; // Normalize the native longitude. if (*phip > 180.0) { *phip -= 360.0; } else if (*phip < -180.0) { *phip += 360.0; } phip += spt; thetap += spt; } } } else { // Pole-flip with change in origin of longitude. dphi = fmod(eul[2] + eul[0], 360.0); jlng = 0; latp = lat; phip = phi; thetap = theta; for (ilat = 0; ilat < nlat; ilat++, latp += sll) { lngp = lng + (jlng%nlng)*sll; for (ilng = 0; ilng < mlng; ilng++, lngp += sll, jlng++) { *phip = fmod(dphi - *lngp, 360.0); *thetap = -(*latp); // Normalize the native longitude. if (*phip > 180.0) { *phip -= 360.0; } else if (*phip < -180.0) { *phip += 360.0; } phip += spt; thetap += spt; } } } return 0; } // Do lng dependency. lngp = lng; rowoff = 0; rowlen = nlng*spt; for (ilng = 0; ilng < nlng; ilng++, rowoff += spt, lngp += sll) { dlng = *lngp - eul[0]; phip = phi + rowoff; thetap = theta; for (ilat = 0; ilat < mlat; ilat++) { *phip = dlng; phip += rowlen; } } // Do lat dependency. latp = lat; phip = phi; thetap = theta; for (ilat = 0; ilat < nlat; ilat++, latp += sll) { sincosd(*latp, &sinlat, &coslat); coslat3 = coslat*eul[3]; coslat4 = coslat*eul[4]; sinlat3 = sinlat*eul[3]; sinlat4 = sinlat*eul[4]; for (ilng = 0; ilng < mlng; ilng++, phip += spt, thetap += spt) { dlng = *phip; sincosd(dlng, &sinlng, &coslng); // Compute the native longitude. x = sinlat4 - coslat3*coslng; if (fabs(x) < tol) { // Rearrange formula to reduce roundoff errors. x = -cosd(*latp+eul[1]) + coslat3*(1.0 - coslng); } y = -coslat*sinlng; if (x != 0.0 || y != 0.0) { dphi = atan2d(y, x); } else { // Change of origin of longitude. if (eul[1] < 90.0) { dphi = dlng - 180.0; } else { dphi = -dlng; } } *phip = fmod(eul[2] + dphi, 360.0); // Normalize the native longitude. if (*phip > 180.0) { *phip -= 360.0; } else if (*phip < -180.0) { *phip += 360.0; } // Compute the native latitude. if (fmod(dlng,180.0) == 0.0) { *thetap = *latp + coslng*eul[1]; if (*thetap > 90.0) *thetap = 180.0 - *thetap; if (*thetap < -90.0) *thetap = -180.0 - *thetap; } else { z = sinlat3 + coslat4*coslng; if (fabs(z) > 0.99) { // Use an alternative formula for greater accuracy. *thetap = copysign(acosd(sqrt(x*x+y*y)), z); } else { *thetap = asind(z); } } } } return 0; } //---------------------------------------------------------------------------- int sphdpa( int nfield, double lng0, double lat0, const double lng[], const double lat[], double dist[], double pa[]) { int i; double eul[5]; // Set the Euler angles for the coordinate transformation. eul[0] = lng0; eul[1] = 90.0 - lat0; eul[2] = 0.0; eul[3] = cosd(eul[1]); eul[4] = sind(eul[1]); // Transform field points to the new system. sphs2x(eul, nfield, 0, 1, 1, lng, lat, pa, dist); for (i = 0; i < nfield; i++) { // Angular distance is obtained from latitude in the new frame. dist[i] = 90.0 - dist[i]; // Position angle is obtained from longitude in the new frame. pa[i] = -pa[i]; if (pa[i] < -180.0) pa[i] += 360.0; } return 0; } //---------------------------------------------------------------------------- int sphpad( int nfield, double lng0, double lat0, const double dist[], const double pa[], double lng[], double lat[]) { int i; double eul[5]; // Set the Euler angles for the coordinate transformation. eul[0] = lng0; eul[1] = 90.0 - lat0; eul[2] = 0.0; eul[3] = cosd(eul[1]); eul[4] = sind(eul[1]); for (i = 0; i < nfield; i++) { // Latitude in the new frame is obtained from angular distance. lat[i] = 90.0 - dist[i]; // Longitude in the new frame is obtained from position angle. lng[i] = -pa[i]; } // Transform field points to the old system. sphx2s(eul, nfield, 0, 1, 1, lng, lat, lng, lat); return 0; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/sph.h0000644000175100001710000002312400000000000016327 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: sph.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the sph routines * --------------------------- * Routines in this suite implement the spherical coordinate transformations * defined by the FITS World Coordinate System (WCS) standard * = "Representations of world coordinates in FITS", = Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (WCS Paper I) = = "Representations of celestial coordinates in FITS", = Calabretta, M.R., & Greisen, E.W. 2002, A&A, 395, 1077 (WCS Paper II) * * The transformations are implemented via separate functions, sphx2s() and * sphs2x(), for the spherical rotation in each direction. * * A utility function, sphdpa(), computes the angular distances and position * angles from a given point on the sky to a number of other points. sphpad() * does the complementary operation - computes the coordinates of points offset * by the given angular distances and position angles from a given point on the * sky. * * * sphx2s() - Rotation in the pixel-to-world direction * --------------------------------------------------- * sphx2s() transforms native coordinates of a projection to celestial * coordinates. * * Given: * eul const double[5] * Euler angles for the transformation: * 0: Celestial longitude of the native pole [deg]. * 1: Celestial colatitude of the native pole, or * native colatitude of the celestial pole [deg]. * 2: Native longitude of the celestial pole [deg]. * 3: cos(eul[1]) * 4: sin(eul[1]) * * nphi, * ntheta int Vector lengths. * * spt,sxy int Vector strides. * * phi,theta const double[] * Longitude and latitude in the native coordinate * system of the projection [deg]. * * Returned: * lng,lat double[] Celestial longitude and latitude [deg]. These may * refer to the same storage as phi and theta * respectively. * * Function return value: * int Status return value: * 0: Success. * * * sphs2x() - Rotation in the world-to-pixel direction * --------------------------------------------------- * sphs2x() transforms celestial coordinates to the native coordinates of a * projection. * * Given: * eul const double[5] * Euler angles for the transformation: * 0: Celestial longitude of the native pole [deg]. * 1: Celestial colatitude of the native pole, or * native colatitude of the celestial pole [deg]. * 2: Native longitude of the celestial pole [deg]. * 3: cos(eul[1]) * 4: sin(eul[1]) * * nlng,nlat int Vector lengths. * * sll,spt int Vector strides. * * lng,lat const double[] * Celestial longitude and latitude [deg]. * * Returned: * phi,theta double[] Longitude and latitude in the native coordinate system * of the projection [deg]. These may refer to the same * storage as lng and lat respectively. * * Function return value: * int Status return value: * 0: Success. * * * sphdpa() - Compute angular distance and position angle * ------------------------------------------------------ * sphdpa() computes the angular distance and generalized position angle (see * notes) from a "reference" point to a number of "field" points on the sphere. * The points must be specified consistently in any spherical coordinate * system. * * sphdpa() is complementary to sphpad(). * * Given: * nfield int The number of field points. * * lng0,lat0 double Spherical coordinates of the reference point [deg]. * * lng,lat const double[] * Spherical coordinates of the field points [deg]. * * Returned: * dist,pa double[] Angular distances and position angles [deg]. These * may refer to the same storage as lng and lat * respectively. * * Function return value: * int Status return value: * 0: Success. * * Notes: * 1. sphdpa() uses sphs2x() to rotate coordinates so that the reference * point is at the north pole of the new system with the north pole of the * old system at zero longitude in the new. The Euler angles required by * sphs2x() for this rotation are * = eul[0] = lng0; = eul[1] = 90.0 - lat0; = eul[2] = 0.0; * * The angular distance and generalized position angle are readily * obtained from the longitude and latitude of the field point in the new * system. This applies even if the reference point is at one of the * poles, in which case the "position angle" returned is as would be * computed for a reference point at (lng0,+90-epsilon) or * (lng0,-90+epsilon), in the limit as epsilon goes to zero. * * It is evident that the coordinate system in which the two points are * expressed is irrelevant to the determination of the angular separation * between the points. However, this is not true of the generalized * position angle. * * The generalized position angle is here defined as the angle of * intersection of the great circle containing the reference and field * points with that containing the reference point and the pole. It has * its normal meaning when the the reference and field points are * specified in equatorial coordinates (right ascension and declination). * * Interchanging the reference and field points changes the position angle * in a non-intuitive way (because the sum of the angles of a spherical * triangle normally exceeds 180 degrees). * * The position angle is undefined if the reference and field points are * coincident or antipodal. This may be detected by checking for a * distance of 0 or 180 degrees (within rounding tolerance). sphdpa() * will return an arbitrary position angle in such circumstances. * * * sphpad() - Compute field points offset from a given point * --------------------------------------------------------- * sphpad() computes the coordinates of a set of points that are offset by the * specified angular distances and position angles from a given "reference" * point on the sky. The distances and position angles must be specified * consistently in any spherical coordinate system. * * sphpad() is complementary to sphdpa(). * * Given: * nfield int The number of field points. * * lng0,lat0 double Spherical coordinates of the reference point [deg]. * * dist,pa const double[] * Angular distances and position angles [deg]. * * Returned: * lng,lat double[] Spherical coordinates of the field points [deg]. * These may refer to the same storage as dist and pa * respectively. * * Function return value: * int Status return value: * 0: Success. * * Notes: * 1: sphpad() is implemented analogously to sphdpa() although using sphx2s() * for the inverse transformation. In particular, when the reference * point is at one of the poles, "position angle" is interpreted as though * the reference point was at (lng0,+90-epsilon) or (lng0,-90+epsilon), in * the limit as epsilon goes to zero. * * Applying sphpad() with the distances and position angles computed by * sphdpa() should return the original field points. * *===========================================================================*/ #ifndef WCSLIB_SPH #define WCSLIB_SPH #ifdef __cplusplus extern "C" { #endif int sphx2s(const double eul[5], int nphi, int ntheta, int spt, int sxy, const double phi[], const double theta[], double lng[], double lat[]); int sphs2x(const double eul[5], int nlng, int nlat, int sll , int spt, const double lng[], const double lat[], double phi[], double theta[]); int sphdpa(int nfield, double lng0, double lat0, const double lng[], const double lat[], double dist[], double pa[]); int sphpad(int nfield, double lng0, double lat0, const double dist[], const double pa[], double lng[], double lat[]); #ifdef __cplusplus } #endif #endif // WCSLIB_SPH ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/spx.c0000644000175100001710000006160000000000000016343 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: spx.c,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *===========================================================================*/ #include #include #include #include "wcserr.h" #include "wcsmath.h" #include "spx.h" // Map status return value to message. const char *spx_errmsg[] = { "Success", "Null spxprm pointer passed", "Invalid spectral parameters", "Invalid spectral variable", "One or more of the inspec coordinates were invalid"}; // Convenience macro for invoking wcserr_set(). #define SPX_ERRMSG(status) WCSERR_SET(status), spx_errmsg[status] #define C 2.99792458e8 #define h 6.6260755e-34 /*============================================================================ * Spectral cross conversions; given one spectral coordinate it computes all * the others, plus the required derivatives of each with respect to the * others. *===========================================================================*/ int specx( const char *type, double spec, double restfrq, double restwav, struct spxprm *spx) { static const char *function = "specx"; register int k; int haverest; double beta, dwaveawav, gamma, n, s, t, u; struct wcserr **err; if (spx == 0x0) return SPXERR_NULL_POINTER; err = &(spx->err); haverest = 1; if (restfrq == 0.0) { if (restwav == 0.0) { // No line rest frequency supplied. haverest = 0; // Temporarily set a dummy value for conversions. spx->restwav = 1.0; } else { spx->restwav = restwav; } spx->restfrq = C/spx->restwav; } else { spx->restfrq = restfrq; spx->restwav = C/restfrq; } spx->err = 0x0; // Convert to frequency. spx->wavetype = 0; spx->velotype = 0; if (strcmp(type, "FREQ") == 0) { if (spec == 0.0) { return wcserr_set(WCSERR_SET(SPXERR_BAD_SPEC_VAR), "Invalid spectral variable: frequency == 0"); } spx->freq = spec; spx->wavetype = 1; } else if (strcmp(type, "AFRQ") == 0) { if (spec == 0.0) { return wcserr_set(WCSERR_SET(SPXERR_BAD_SPEC_VAR), "Invalid spectral variable: frequency == 0"); } spx->freq = spec/(2.0*PI); spx->wavetype = 1; } else if (strcmp(type, "ENER") == 0) { if (spec == 0.0) { return wcserr_set(WCSERR_SET(SPXERR_BAD_SPEC_VAR), "Invalid spectral variable: frequency == 0"); } spx->freq = spec/h; spx->wavetype = 1; } else if (strcmp(type, "WAVN") == 0) { if (spec == 0.0) { return wcserr_set(WCSERR_SET(SPXERR_BAD_SPEC_VAR), "Invalid spectral variable: frequency == 0"); } spx->freq = spec*C; spx->wavetype = 1; } else if (strcmp(type, "VRAD") == 0) { spx->freq = spx->restfrq*(1.0 - spec/C); spx->velotype = 1; } else if (strcmp(type, "WAVE") == 0) { if (spec == 0.0) { return wcserr_set(WCSERR_SET(SPXERR_BAD_SPEC_VAR), "Invalid spectral variable: frequency == 0"); } spx->freq = C/spec; spx->wavetype = 1; } else if (strcmp(type, "VOPT") == 0) { s = 1.0 + spec/C; if (s == 0.0) { return wcserr_set(WCSERR_SET(SPXERR_BAD_SPEC_VAR), "Invalid spectral variable"); } spx->freq = spx->restfrq/s; spx->velotype = 1; } else if (strcmp(type, "ZOPT") == 0) { s = 1.0 + spec; if (s == 0.0) { return wcserr_set(WCSERR_SET(SPXERR_BAD_SPEC_VAR), "Invalid spectral variable"); } spx->freq = spx->restfrq/s; spx->velotype = 1; } else if (strcmp(type, "AWAV") == 0) { if (spec == 0.0) { return wcserr_set(WCSERR_SET(SPXERR_BAD_SPEC_VAR), "Invalid spectral variable"); } s = 1.0/spec; s *= s; n = 2.554e8 / (0.41e14 - s); n += 294.981e8 / (1.46e14 - s); n += 1.000064328; spx->freq = C/(spec*n); spx->wavetype = 1; } else if (strcmp(type, "VELO") == 0) { beta = spec/C; if (fabs(beta) == 1.0) { return wcserr_set(WCSERR_SET(SPXERR_BAD_SPEC_VAR), "Invalid spectral variable"); } spx->freq = spx->restfrq*(1.0 - beta)/sqrt(1.0 - beta*beta); spx->velotype = 1; } else if (strcmp(type, "BETA") == 0) { if (fabs(spec) == 1.0) { return wcserr_set(WCSERR_SET(SPXERR_BAD_SPEC_VAR), "Invalid spectral variable"); } spx->freq = spx->restfrq*(1.0 - spec)/sqrt(1.0 - spec*spec); spx->velotype = 1; } else { // Unrecognized type. return wcserr_set(WCSERR_SET(SPXERR_BAD_SPEC_PARAMS), "Unrecognized spectral type '%s'", type); } // Convert frequency to the other spectral types. n = 1.0; for (k = 0; k < 4; k++) { s = n*spx->freq/C; s *= s; t = 0.41e14 - s; u = 1.46e14 - s; n = 1.000064328 + (2.554e8/t + 294.981e8/u); } dwaveawav = n - 2.0*s*(2.554e8/(t*t) + 294.981e8/(u*u)); s = spx->freq/spx->restfrq; spx->ener = spx->freq*h; spx->afrq = spx->freq*(2.0*PI); spx->wavn = spx->freq/C; spx->vrad = C*(1.0 - s); spx->wave = C/spx->freq; spx->awav = spx->wave/n; spx->vopt = C*(1.0/s - 1.0); spx->zopt = spx->vopt/C; spx->velo = C*(1.0 - s*s)/(1.0 + s*s); spx->beta = spx->velo/C; // Compute the required derivatives. gamma = 1.0/sqrt(1.0 - spx->beta*spx->beta); spx->dfreqafrq = 1.0/(2.0*PI); spx->dafrqfreq = 1.0/spx->dfreqafrq; spx->dfreqener = 1.0/h; spx->denerfreq = 1.0/spx->dfreqener; spx->dfreqwavn = C; spx->dwavnfreq = 1.0/spx->dfreqwavn; spx->dfreqvrad = -spx->restfrq/C; spx->dvradfreq = 1.0/spx->dfreqvrad; spx->dfreqwave = -spx->freq/spx->wave; spx->dwavefreq = 1.0/spx->dfreqwave; spx->dfreqawav = spx->dfreqwave * dwaveawav; spx->dawavfreq = 1.0/spx->dfreqawav; spx->dfreqvelo = -gamma*spx->restfrq/(C + spx->velo); spx->dvelofreq = 1.0/spx->dfreqvelo; spx->dwavevopt = spx->restwav/C; spx->dvoptwave = 1.0/spx->dwavevopt; spx->dwavezopt = spx->restwav; spx->dzoptwave = 1.0/spx->dwavezopt; spx->dwaveawav = dwaveawav; spx->dawavwave = 1.0/spx->dwaveawav; spx->dwavevelo = gamma*spx->restwav/(C - spx->velo); spx->dvelowave = 1.0/spx->dwavevelo; spx->dawavvelo = spx->dwavevelo/dwaveawav; spx->dveloawav = 1.0/spx->dawavvelo; spx->dvelobeta = C; spx->dbetavelo = 1.0/spx->dvelobeta; // Reset values if no line rest frequency was supplied. if (haverest) { spx->wavetype = 1; spx->velotype = 1; } else { spx->restfrq = 0.0; spx->restwav = 0.0; if (!spx->wavetype) { // Don't have wave characteristic types. spx->freq = 0.0; spx->afrq = 0.0; spx->ener = 0.0; spx->wavn = 0.0; spx->wave = 0.0; spx->awav = 0.0; spx->dfreqwave = 0.0; spx->dwavefreq = 0.0; spx->dfreqawav = 0.0; spx->dawavfreq = 0.0; spx->dwaveawav = 0.0; spx->dawavwave = 0.0; } else { // Don't have velocity types. spx->vrad = 0.0; spx->vopt = 0.0; spx->zopt = 0.0; spx->velo = 0.0; spx->beta = 0.0; } spx->dfreqvrad = 0.0; spx->dvradfreq = 0.0; spx->dfreqvelo = 0.0; spx->dvelofreq = 0.0; spx->dwavevopt = 0.0; spx->dvoptwave = 0.0; spx->dwavezopt = 0.0; spx->dzoptwave = 0.0; spx->dwavevelo = 0.0; spx->dvelowave = 0.0; spx->dawavvelo = 0.0; spx->dveloawav = 0.0; } return 0; } //---------------------------------------------------------------------------- int spxperr(const struct spxprm *spx, const char *prefix) { if (spx == 0x0) return SPXERR_NULL_POINTER; if (spx->err) { wcserr_prt(spx->err, prefix); } return 0; } /*============================================================================ * Conversions between frequency and vacuum wavelength. *===========================================================================*/ int freqwave( double dummy, int nfreq, int sfreq, int swave, const double freq[], double wave[], int stat[]) { int status = 0; register int ifreq, *statp; register const double *freqp; register double *wavep; // Avert nuisance compiler warnings about unused parameters. (void)dummy; freqp = freq; wavep = wave; statp = stat; for (ifreq = 0; ifreq < nfreq; ifreq++) { if (*freqp != 0.0) { *wavep = C/(*freqp); *(statp++) = 0; } else { *(statp++) = 1; status = SPXERR_BAD_INSPEC_COORD; } freqp += sfreq; wavep += swave; } return status; } //---------------------------------------------------------------------------- int wavefreq( double dummy, int nwave, int swave, int sfreq, const double wave[], double freq[], int stat[]) { int status = 0; register int iwave, *statp; register const double *wavep; register double *freqp; // Avert nuisance compiler warnings about unused parameters. (void)dummy; wavep = wave; freqp = freq; statp = stat; for (iwave = 0; iwave < nwave; iwave++) { if (*wavep != 0.0) { *freqp = C/(*wavep); *(statp++) = 0; } else { *(statp++) = 1; status = SPXERR_BAD_INSPEC_COORD; } wavep += swave; freqp += sfreq; } return status; } /*============================================================================ * Conversions between frequency and air wavelength. *===========================================================================*/ int freqawav( double dummy, int nfreq, int sfreq, int sawav, const double freq[], double awav[], int stat[]) { int status; if ((status = freqwave(dummy, nfreq, sfreq, sawav, freq, awav, stat))) { return status; } return waveawav(dummy, nfreq, sawav, sawav, awav, awav, stat); } //---------------------------------------------------------------------------- int awavfreq( double dummy, int nawav, int sawav, int sfreq, const double awav[], double freq[], int stat[]) { int status; if ((status = awavwave(dummy, nawav, sawav, sfreq, awav, freq, stat))) { return status; } return wavefreq(dummy, nawav, sfreq, sfreq, freq, freq, stat); } /*============================================================================ * Conversions between frequency and relativistic velocity. *===========================================================================*/ int freqvelo( double restfrq, int nfreq, int sfreq, int svelo, const double freq[], double velo[], int stat[]) { double r, s; register int ifreq, *statp; register const double *freqp; register double *velop; r = restfrq*restfrq; freqp = freq; velop = velo; statp = stat; for (ifreq = 0; ifreq < nfreq; ifreq++) { s = *freqp * *freqp; *velop = C*(r - s)/(r + s); *(statp++) = 0; freqp += sfreq; velop += svelo; } return 0; } //---------------------------------------------------------------------------- int velofreq( double restfrq, int nvelo, int svelo, int sfreq, const double velo[], double freq[], int stat[]) { int status = 0; double s; register int ivelo, *statp; register const double *velop; register double *freqp; velop = velo; freqp = freq; statp = stat; for (ivelo = 0; ivelo < nvelo; ivelo++) { s = C + *velop; if (s != 0.0) { *freqp = restfrq*sqrt((C - *velop)/s); *(statp++) = 0; } else { *(statp++) = 1; status = SPXERR_BAD_INSPEC_COORD; } velop += svelo; freqp += sfreq; } return status; } /*============================================================================ * Conversions between vacuum wavelength and air wavelength. *===========================================================================*/ int waveawav( double dummy, int nwave, int swave, int sawav, const double wave[], double awav[], int stat[]) { int status = 0; double n, s; register int iwave, k, *statp; register const double *wavep; register double *awavp; // Avert nuisance compiler warnings about unused parameters. (void)dummy; wavep = wave; awavp = awav; statp = stat; for (iwave = 0; iwave < nwave; iwave++) { if (*wavep != 0.0) { n = 1.0; for (k = 0; k < 4; k++) { s = n/(*wavep); s *= s; n = 2.554e8 / (0.41e14 - s); n += 294.981e8 / (1.46e14 - s); n += 1.000064328; } *awavp = (*wavep)/n; *(statp++) = 0; } else { *(statp++) = 1; status = SPXERR_BAD_INSPEC_COORD; } wavep += swave; awavp += sawav; } return status; } //---------------------------------------------------------------------------- int awavwave( double dummy, int nawav, int sawav, int swave, const double awav[], double wave[], int stat[]) { int status = 0; double n, s; register int iawav, *statp; register const double *awavp; register double *wavep; // Avert nuisance compiler warnings about unused parameters. (void)dummy; awavp = awav; wavep = wave; statp = stat; for (iawav = 0; iawav < nawav; iawav++) { if (*awavp != 0.0) { s = 1.0/(*awavp); s *= s; n = 2.554e8 / (0.41e14 - s); n += 294.981e8 / (1.46e14 - s); n += 1.000064328; *wavep = (*awavp)*n; *(statp++) = 0; } else { *(statp++) = 1; status = SPXERR_BAD_INSPEC_COORD; } awavp += sawav; wavep += swave; } return status; } /*============================================================================ * Conversions between vacuum wavelength and relativistic velocity. *===========================================================================*/ int wavevelo( double restwav, int nwave, int swave, int svelo, const double wave[], double velo[], int stat[]) { double r, s; register int iwave, *statp; register const double *wavep; register double *velop; r = restwav*restwav; wavep = wave; velop = velo; statp = stat; for (iwave = 0; iwave < nwave; iwave++) { s = *wavep * *wavep; *velop = C*(s - r)/(s + r); *(statp++) = 0; wavep += swave; velop += svelo; } return 0; } //---------------------------------------------------------------------------- int velowave( double restwav, int nvelo, int svelo, int swave, const double velo[], double wave[], int stat[]) { int status = 0; double s; register int ivelo, *statp; register const double *velop; register double *wavep; velop = velo; wavep = wave; statp = stat; for (ivelo = 0; ivelo < nvelo; ivelo++) { s = C - *velop; if (s != 0.0) { *wavep = restwav*sqrt((C + *velop)/s); *(statp++) = 0; } else { *(statp++) = 1; status = SPXERR_BAD_INSPEC_COORD; } velop += svelo; wavep += swave; } return status; } /*============================================================================ * Conversions between air wavelength and relativistic velocity. *===========================================================================*/ int awavvelo( double dummy, int nawav, int sawav, int svelo, const double awav[], double velo[], int stat[]) { int status; if ((status = awavwave(dummy, nawav, sawav, svelo, awav, velo, stat))) { return status; } return wavevelo(dummy, nawav, svelo, svelo, velo, velo, stat); } //---------------------------------------------------------------------------- int veloawav( double dummy, int nvelo, int svelo, int sawav, const double velo[], double awav[], int stat[]) { int status; if ((status = velowave(dummy, nvelo, svelo, sawav, velo, awav, stat))) { return status; } return waveawav(dummy, nvelo, sawav, sawav, awav, awav, stat); } /*============================================================================ * Conversions between frequency and angular frequency. *===========================================================================*/ int freqafrq( double dummy, int nfreq, int sfreq, int safrq, const double freq[], double afrq[], int stat[]) { register int ifreq, *statp; register const double *freqp; register double *afrqp; // Avert nuisance compiler warnings about unused parameters. (void)dummy; freqp = freq; afrqp = afrq; statp = stat; for (ifreq = 0; ifreq < nfreq; ifreq++) { *afrqp = (*freqp)*(2.0*PI); *(statp++) = 0; freqp += sfreq; afrqp += safrq; } return 0; } //---------------------------------------------------------------------------- int afrqfreq( double dummy, int nafrq, int safrq, int sfreq, const double afrq[], double freq[], int stat[]) { register int iafrq, *statp; register const double *afrqp; register double *freqp; // Avert nuisance compiler warnings about unused parameters. (void)dummy; afrqp = afrq; freqp = freq; statp = stat; for (iafrq = 0; iafrq < nafrq; iafrq++) { *freqp = (*afrqp)/(2.0*PI); *(statp++) = 0; afrqp += safrq; freqp += sfreq; } return 0; } /*============================================================================ * Conversions between frequency and energy. *===========================================================================*/ int freqener( double dummy, int nfreq, int sfreq, int sener, const double freq[], double ener[], int stat[]) { register int ifreq, *statp; register const double *freqp; register double *enerp; // Avert nuisance compiler warnings about unused parameters. (void)dummy; freqp = freq; enerp = ener; statp = stat; for (ifreq = 0; ifreq < nfreq; ifreq++) { *enerp = (*freqp)*h; *(statp++) = 0; freqp += sfreq; enerp += sener; } return 0; } //---------------------------------------------------------------------------- int enerfreq( double dummy, int nener, int sener, int sfreq, const double ener[], double freq[], int stat[]) { register int iener, *statp; register const double *enerp; register double *freqp; // Avert nuisance compiler warnings about unused parameters. (void)dummy; enerp = ener; freqp = freq; statp = stat; for (iener = 0; iener < nener; iener++) { *freqp = (*enerp)/h; *(statp++) = 0; enerp += sener; freqp += sfreq; } return 0; } /*============================================================================ * Conversions between frequency and wave number. *===========================================================================*/ int freqwavn( double dummy, int nfreq, int sfreq, int swavn, const double freq[], double wavn[], int stat[]) { register int ifreq, *statp; register const double *freqp; register double *wavnp; // Avert nuisance compiler warnings about unused parameters. (void)dummy; freqp = freq; wavnp = wavn; statp = stat; for (ifreq = 0; ifreq < nfreq; ifreq++) { *wavnp = (*freqp)/C; *(statp++) = 0; freqp += sfreq; wavnp += swavn; } return 0; } //---------------------------------------------------------------------------- int wavnfreq( double dummy, int nwavn, int swavn, int sfreq, const double wavn[], double freq[], int stat[]) { register int iwavn, *statp; register const double *wavnp; register double *freqp; // Avert nuisance compiler warnings about unused parameters. (void)dummy; wavnp = wavn; freqp = freq; statp = stat; for (iwavn = 0; iwavn < nwavn; iwavn++) { *freqp = (*wavnp)*C; *(statp++) = 0; wavnp += swavn; freqp += sfreq; } return 0; } /*============================================================================ * Conversions between frequency and radio velocity. *===========================================================================*/ int freqvrad( double restfrq, int nfreq, int sfreq, int svrad, const double freq[], double vrad[], int stat[]) { double r; register int ifreq, *statp; register const double *freqp; register double *vradp; if (restfrq == 0.0) { return SPXERR_BAD_SPEC_PARAMS; } r = C/restfrq; freqp = freq; vradp = vrad; statp = stat; for (ifreq = 0; ifreq < nfreq; ifreq++) { *vradp = r*(restfrq - *freqp); *(statp++) = 0; freqp += sfreq; vradp += svrad; } return 0; } //---------------------------------------------------------------------------- int vradfreq( double restfrq, int nvrad, int svrad, int sfreq, const double vrad[], double freq[], int stat[]) { double r; register int ivrad, *statp; register const double *vradp; register double *freqp; r = restfrq/C; vradp = vrad; freqp = freq; statp = stat; for (ivrad = 0; ivrad < nvrad; ivrad++) { *freqp = r*(C - *vradp); *(statp++) = 0; vradp += svrad; freqp += sfreq; } return 0; } /*============================================================================ * Conversions between vacuum wavelength and optical velocity. *===========================================================================*/ int wavevopt( double restwav, int nwave, int swave, int svopt, const double wave[], double vopt[], int stat[]) { double r; register int iwave, *statp; register const double *wavep; register double *voptp; if (restwav == 0.0) { return SPXERR_BAD_SPEC_PARAMS; } r = C/restwav; wavep = wave; voptp = vopt; statp = stat; for (iwave = 0; iwave < nwave; iwave++) { *voptp = r*(*wavep) - C; *(statp++) = 0; wavep += swave; voptp += svopt; } return 0; } //---------------------------------------------------------------------------- int voptwave( double restwav, int nvopt, int svopt, int swave, const double vopt[], double wave[], int stat[]) { double r; register int ivopt, *statp; register const double *voptp; register double *wavep; r = restwav/C; voptp = vopt; wavep = wave; statp = stat; for (ivopt = 0; ivopt < nvopt; ivopt++) { *wavep = r*(C + *voptp); *(statp++) = 0; voptp += svopt; wavep += swave; } return 0; } /*============================================================================ * Conversions between vacuum wavelength and redshift. *===========================================================================*/ int wavezopt( double restwav, int nwave, int swave, int szopt, const double wave[], double zopt[], int stat[]) { double r; register int iwave, *statp; register const double *wavep; register double *zoptp; if (restwav == 0.0) { return SPXERR_BAD_SPEC_PARAMS; } r = 1.0/restwav; wavep = wave; zoptp = zopt; statp = stat; for (iwave = 0; iwave < nwave; iwave++) { *zoptp = r*(*wavep) - 1.0; *(statp++) = 0; wavep += swave; zoptp += szopt; } return 0; } //---------------------------------------------------------------------------- int zoptwave( double restwav, int nzopt, int szopt, int swave, const double zopt[], double wave[], int stat[]) { register int izopt, *statp; register const double *zoptp; register double *wavep; zoptp = zopt; wavep = wave; statp = stat; for (izopt = 0; izopt < nzopt; izopt++) { *wavep = restwav*(1.0 + *zoptp); *(statp++) = 0; zoptp += szopt; wavep += swave; } return 0; } /*============================================================================ * Conversions between relativistic velocity and beta (= v/c). *===========================================================================*/ int velobeta( double dummy, int nvelo, int svelo, int sbeta, const double velo[], double beta[], int stat[]) { register int ivelo, *statp; register const double *velop; register double *betap; // Avert nuisance compiler warnings about unused parameters. (void)dummy; velop = velo; betap = beta; statp = stat; for (ivelo = 0; ivelo < nvelo; ivelo++) { *betap = (*velop)/C; *(statp++) = 0; velop += svelo; betap += sbeta; } return 0; } //---------------------------------------------------------------------------- int betavelo( double dummy, int nbeta, int sbeta, int svelo, const double beta[], double velo[], int stat[]) { register int ibeta, *statp; register const double *betap; register double *velop; // Avert nuisance compiler warnings about unused parameters. (void)dummy; betap = beta; velop = velo; statp = stat; for (ibeta = 0; ibeta < nbeta; ibeta++) { *velop = (*betap)*C; *(statp++) = 0; betap += sbeta; velop += svelo; } return 0; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/spx.h0000644000175100001710000005270400000000000016355 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: spx.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the spx routines * --------------------------- * Routines in this suite implement the spectral coordinate systems recognized * by the FITS World Coordinate System (WCS) standard, as described in * = "Representations of world coordinates in FITS", = Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (WCS Paper I) = = "Representations of spectral coordinates in FITS", = Greisen, E.W., Calabretta, M.R., Valdes, F.G., & Allen, S.L. = 2006, A&A, 446, 747 (WCS Paper III) * * specx() is a scalar routine that, given one spectral variable (e.g. * frequency), computes all the others (e.g. wavelength, velocity, etc.) plus * the required derivatives of each with respect to the others. The results * are returned in the spxprm struct. * * spxperr() prints the error message(s) (if any) stored in a spxprm struct. * * The remaining routines are all vector conversions from one spectral * variable to another. The API of these functions only differ in whether the * rest frequency or wavelength need be supplied. * * Non-linear: * - freqwave() frequency -> vacuum wavelength * - wavefreq() vacuum wavelength -> frequency * * - freqawav() frequency -> air wavelength * - awavfreq() air wavelength -> frequency * * - freqvelo() frequency -> relativistic velocity * - velofreq() relativistic velocity -> frequency * * - waveawav() vacuum wavelength -> air wavelength * - awavwave() air wavelength -> vacuum wavelength * * - wavevelo() vacuum wavelength -> relativistic velocity * - velowave() relativistic velocity -> vacuum wavelength * * - awavvelo() air wavelength -> relativistic velocity * - veloawav() relativistic velocity -> air wavelength * * Linear: * - freqafrq() frequency -> angular frequency * - afrqfreq() angular frequency -> frequency * * - freqener() frequency -> energy * - enerfreq() energy -> frequency * * - freqwavn() frequency -> wave number * - wavnfreq() wave number -> frequency * * - freqvrad() frequency -> radio velocity * - vradfreq() radio velocity -> frequency * * - wavevopt() vacuum wavelength -> optical velocity * - voptwave() optical velocity -> vacuum wavelength * * - wavezopt() vacuum wavelength -> redshift * - zoptwave() redshift -> vacuum wavelength * * - velobeta() relativistic velocity -> beta (= v/c) * - betavelo() beta (= v/c) -> relativistic velocity * * These are the workhorse routines, to be used for fast transformations. * Conversions may be done "in place" by calling the routine with the output * vector set to the input. * * Air-to-vacuum wavelength conversion: * ------------------------------------ * The air-to-vacuum wavelength conversion in early drafts of WCS Paper III * cites Cox (ed., 2000, Allen’s Astrophysical Quantities, AIP Press, * Springer-Verlag, New York), which itself derives from EdlÊn (1953, Journal * of the Optical Society of America, 43, 339). This is the IAU standard, * adopted in 1957 and again in 1991. No more recent IAU resolution replaces * this relation, and it is the one used by WCSLIB. * * However, the Cox relation was replaced in later drafts of Paper III, and as * eventually published, by the IUGG relation (1999, International Union of * Geodesy and Geophysics, comptes rendus of the 22nd General Assembly, * Birmingham UK, p111). There is a nearly constant ratio between the two, * with IUGG/Cox = 1.000015 over most of the range between 200nm and 10,000nm. * * The IUGG relation itself is derived from the work of Ciddor (1996, Applied * Optics, 35, 1566), which is used directly by the Sloan Digital Sky Survey. * It agrees closely with Cox; longwards of 2500nm, the ratio Ciddor/Cox is * fixed at 1.000000021, decreasing only slightly, to 1.000000018, at 1000nm. * * The Cox, IUGG, and Ciddor relations all accurately provide the wavelength * dependence of the air-to-vacuum wavelength conversion. However, for full * accuracy, the atmospheric temperature, pressure, and partial pressure of * water vapour must be taken into account. These will determine a small, * wavelength-independent scale factor and offset, which is not considered by * WCS Paper III. * * WCS Paper III is also silent on the question of the range of validity of the * air-to-vacuum wavelength conversion. Cox's relation would appear to be * valid in the range 200nm to 10,000nm. Both the Cox and the Ciddor relations * have singularities below 200nm, with Cox's at 156nm and 83nm. WCSLIB checks * neither the range of validity, nor for these singularities. * * Argument checking: * ------------------ * The input spectral values are only checked for values that would result * in floating point exceptions. In particular, negative frequencies and * wavelengths are allowed, as are velocities greater than the speed of * light. The same is true for the spectral parameters - rest frequency and * wavelength. * * Accuracy: * --------- * No warranty is given for the accuracy of these routines (refer to the * copyright notice); intending users must satisfy for themselves their * adequacy for the intended purpose. However, closure effectively to within * double precision rounding error was demonstrated by test routine tspec.c * which accompanies this software. * * * specx() - Spectral cross conversions (scalar) * --------------------------------------------- * Given one spectral variable specx() computes all the others, plus the * required derivatives of each with respect to the others. * * Given: * type const char* * The type of spectral variable given by spec, FREQ, * AFRQ, ENER, WAVN, VRAD, WAVE, VOPT, ZOPT, AWAV, VELO, * or BETA (case sensitive). * * spec double The spectral variable given, in SI units. * * restfrq, * restwav double Rest frequency [Hz] or rest wavelength in vacuo [m], * only one of which need be given. The other should be * set to zero. If both are zero, only a subset of the * spectral variables can be computed, the remainder are * set to zero. Specifically, given one of FREQ, AFRQ, * ENER, WAVN, WAVE, or AWAV the others can be computed * without knowledge of the rest frequency. Likewise, * VRAD, VOPT, ZOPT, VELO, and BETA. * * Given and returned: * specs struct spxprm* * Data structure containing all spectral variables and * their derivatives, in SI units. * * Function return value: * int Status return value: * 0: Success. * 1: Null spxprm pointer passed. * 2: Invalid spectral parameters. * 3: Invalid spectral variable. * * For returns > 1, a detailed error message is set in * spxprm::err if enabled, see wcserr_enable(). * * freqafrq(), afrqfreq(), freqener(), enerfreq(), freqwavn(), wavnfreq(), * freqwave(), wavefreq(), freqawav(), awavfreq(), waveawav(), awavwave(), * velobeta(), and betavelo() implement vector conversions between wave-like * or velocity-like spectral types (i.e. conversions that do not need the rest * frequency or wavelength). They all have the same API. * * * spxperr() - Print error messages from a spxprm struct * ----------------------------------------------------- * spxperr() prints the error message(s) (if any) stored in a spxprm struct. * If there are no errors then nothing is printed. It uses wcserr_prt(), q.v. * * Given: * spx const struct spxprm* * Spectral variables and their derivatives. * * prefix const char * * If non-NULL, each output line will be prefixed with * this string. * * Function return value: * int Status return value: * 0: Success. * 1: Null spxprm pointer passed. * * * freqafrq() - Convert frequency to angular frequency (vector) * ------------------------------------------------------------ * freqafrq() converts frequency to angular frequency. * * Given: * param double Ignored. * * nspec int Vector length. * * instep, * outstep int Vector strides. * * inspec const double[] * Input spectral variables, in SI units. * * Returned: * outspec double[] Output spectral variables, in SI units. * * stat int[] Status return value for each vector element: * 0: Success. * 1: Invalid value of inspec. * * Function return value: * int Status return value: * 0: Success. * 2: Invalid spectral parameters. * 4: One or more of the inspec coordinates were * invalid, as indicated by the stat vector. * * * freqvelo(), velofreq(), freqvrad(), and vradfreq() implement vector * conversions between frequency and velocity spectral types. They all have * the same API. * * * freqvelo() - Convert frequency to relativistic velocity (vector) * ---------------------------------------------------------------- * freqvelo() converts frequency to relativistic velocity. * * Given: * param double Rest frequency [Hz]. * * nspec int Vector length. * * instep, * outstep int Vector strides. * * inspec const double[] * Input spectral variables, in SI units. * * Returned: * outspec double[] Output spectral variables, in SI units. * * stat int[] Status return value for each vector element: * 0: Success. * 1: Invalid value of inspec. * * Function return value: * int Status return value: * 0: Success. * 2: Invalid spectral parameters. * 4: One or more of the inspec coordinates were * invalid, as indicated by the stat vector. * * * wavevelo(), velowave(), awavvelo(), veloawav(), wavevopt(), voptwave(), * wavezopt(), and zoptwave() implement vector conversions between wavelength * and velocity spectral types. They all have the same API. * * * wavevelo() - Conversions between wavelength and velocity types (vector) * ----------------------------------------------------------------------- * wavevelo() converts vacuum wavelength to relativistic velocity. * * Given: * param double Rest wavelength in vacuo [m]. * * nspec int Vector length. * * instep, * outstep int Vector strides. * * inspec const double[] * Input spectral variables, in SI units. * * Returned: * outspec double[] Output spectral variables, in SI units. * * stat int[] Status return value for each vector element: * 0: Success. * 1: Invalid value of inspec. * * Function return value: * int Status return value: * 0: Success. * 2: Invalid spectral parameters. * 4: One or more of the inspec coordinates were * invalid, as indicated by the stat vector. * * * spxprm struct - Spectral variables and their derivatives * -------------------------------------------------------- * The spxprm struct contains the value of all spectral variables and their * derivatives. It is used solely by specx() which constructs it from * information provided via its function arguments. * * This struct should be considered read-only, no members need ever be set nor * should ever be modified by the user. * * double restfrq * (Returned) Rest frequency [Hz]. * * double restwav * (Returned) Rest wavelength [m]. * * int wavetype * (Returned) True if wave types have been computed, and ... * * int velotype * (Returned) ... true if velocity types have been computed; types are * defined below. * * If one or other of spxprm::restfrq and spxprm::restwav is given * (non-zero) then all spectral variables may be computed. If both are * given, restfrq is used. If restfrq and restwav are both zero, only wave * characteristic xor velocity type spectral variables may be computed * depending on the variable given. These flags indicate what is * available. * * double freq * (Returned) Frequency [Hz] (wavetype). * * double afrq * (Returned) Angular frequency [rad/s] (wavetype). * * double ener * (Returned) Photon energy [J] (wavetype). * * double wavn * (Returned) Wave number [/m] (wavetype). * * double vrad * (Returned) Radio velocity [m/s] (velotype). * * double wave * (Returned) Vacuum wavelength [m] (wavetype). * * double vopt * (Returned) Optical velocity [m/s] (velotype). * * double zopt * (Returned) Redshift [dimensionless] (velotype). * * double awav * (Returned) Air wavelength [m] (wavetype). * * double velo * (Returned) Relativistic velocity [m/s] (velotype). * * double beta * (Returned) Relativistic beta [dimensionless] (velotype). * * double dfreqafrq * (Returned) Derivative of frequency with respect to angular frequency * [/rad] (constant, = 1 / 2*pi), and ... * double dafrqfreq * (Returned) ... vice versa [rad] (constant, = 2*pi, always available). * * double dfreqener * (Returned) Derivative of frequency with respect to photon energy * [/J/s] (constant, = 1/h), and ... * double denerfreq * (Returned) ... vice versa [Js] (constant, = h, Planck's constant, * always available). * * double dfreqwavn * (Returned) Derivative of frequency with respect to wave number [m/s] * (constant, = c, the speed of light in vacuo), and ... * double dwavnfreq * (Returned) ... vice versa [s/m] (constant, = 1/c, always available). * * double dfreqvrad * (Returned) Derivative of frequency with respect to radio velocity [/m], * and ... * double dvradfreq * (Returned) ... vice versa [m] (wavetype && velotype). * * double dfreqwave * (Returned) Derivative of frequency with respect to vacuum wavelength * [/m/s], and ... * double dwavefreq * (Returned) ... vice versa [m s] (wavetype). * * double dfreqawav * (Returned) Derivative of frequency with respect to air wavelength, * [/m/s], and ... * double dawavfreq * (Returned) ... vice versa [m s] (wavetype). * * double dfreqvelo * (Returned) Derivative of frequency with respect to relativistic * velocity [/m], and ... * double dvelofreq * (Returned) ... vice versa [m] (wavetype && velotype). * * double dwavevopt * (Returned) Derivative of vacuum wavelength with respect to optical * velocity [s], and ... * double dvoptwave * (Returned) ... vice versa [/s] (wavetype && velotype). * * double dwavezopt * (Returned) Derivative of vacuum wavelength with respect to redshift [m], * and ... * double dzoptwave * (Returned) ... vice versa [/m] (wavetype && velotype). * * double dwaveawav * (Returned) Derivative of vacuum wavelength with respect to air * wavelength [dimensionless], and ... * double dawavwave * (Returned) ... vice versa [dimensionless] (wavetype). * * double dwavevelo * (Returned) Derivative of vacuum wavelength with respect to relativistic * velocity [s], and ... * double dvelowave * (Returned) ... vice versa [/s] (wavetype && velotype). * * double dawavvelo * (Returned) Derivative of air wavelength with respect to relativistic * velocity [s], and ... * double dveloawav * (Returned) ... vice versa [/s] (wavetype && velotype). * * double dvelobeta * (Returned) Derivative of relativistic velocity with respect to * relativistic beta [m/s] (constant, = c, the speed of light in vacuo), * and ... * double dbetavelo * (Returned) ... vice versa [s/m] (constant, = 1/c, always available). * * struct wcserr *err * (Returned) If enabled, when an error status is returned, this struct * contains detailed information about the error, see wcserr_enable(). * * void *padding * (An unused variable inserted for alignment purposes only.) * * Global variable: const char *spx_errmsg[] - Status return messages * ------------------------------------------------------------------ * Error messages to match the status value returned from each function. * *===========================================================================*/ #ifndef WCSLIB_SPEC #define WCSLIB_SPEC #ifdef __cplusplus extern "C" { #endif extern const char *spx_errmsg[]; enum spx_errmsg { SPXERR_SUCCESS = 0, // Success. SPXERR_NULL_POINTER = 1, // Null spxprm pointer passed. SPXERR_BAD_SPEC_PARAMS = 2, // Invalid spectral parameters. SPXERR_BAD_SPEC_VAR = 3, // Invalid spectral variable. SPXERR_BAD_INSPEC_COORD = 4 // One or more of the inspec coordinates were // invalid. }; struct spxprm { double restfrq, restwav; // Rest frequency [Hz] and wavelength [m]. int wavetype, velotype; // True if wave/velocity types have been // computed; types are defined below. // Spectral variables computed by specx(). //-------------------------------------------------------------------------- double freq, // wavetype: Frequency [Hz]. afrq, // wavetype: Angular frequency [rad/s]. ener, // wavetype: Photon energy [J]. wavn, // wavetype: Wave number [/m]. vrad, // velotype: Radio velocity [m/s]. wave, // wavetype: Vacuum wavelength [m]. vopt, // velotype: Optical velocity [m/s]. zopt, // velotype: Redshift. awav, // wavetype: Air wavelength [m]. velo, // velotype: Relativistic velocity [m/s]. beta; // velotype: Relativistic beta. // Derivatives of spectral variables computed by specx(). //-------------------------------------------------------------------------- double dfreqafrq, dafrqfreq, // Constant, always available. dfreqener, denerfreq, // Constant, always available. dfreqwavn, dwavnfreq, // Constant, always available. dfreqvrad, dvradfreq, // wavetype && velotype. dfreqwave, dwavefreq, // wavetype. dfreqawav, dawavfreq, // wavetype. dfreqvelo, dvelofreq, // wavetype && velotype. dwavevopt, dvoptwave, // wavetype && velotype. dwavezopt, dzoptwave, // wavetype && velotype. dwaveawav, dawavwave, // wavetype. dwavevelo, dvelowave, // wavetype && velotype. dawavvelo, dveloawav, // wavetype && velotype. dvelobeta, dbetavelo; // Constant, always available. // Error handling //-------------------------------------------------------------------------- struct wcserr *err; // Private //-------------------------------------------------------------------------- void *padding; // (Dummy inserted for alignment purposes.) }; // Size of the spxprm struct in int units, used by the Fortran wrappers. #define SPXLEN (sizeof(struct spxprm)/sizeof(int)) int specx(const char *type, double spec, double restfrq, double restwav, struct spxprm *specs); int spxperr(const struct spxprm *spx, const char *prefix); // For use in declaring function prototypes, e.g. in spcprm. #define SPX_ARGS double param, int nspec, int instep, int outstep, \ const double inspec[], double outspec[], int stat[] int freqafrq(SPX_ARGS); int afrqfreq(SPX_ARGS); int freqener(SPX_ARGS); int enerfreq(SPX_ARGS); int freqwavn(SPX_ARGS); int wavnfreq(SPX_ARGS); int freqwave(SPX_ARGS); int wavefreq(SPX_ARGS); int freqawav(SPX_ARGS); int awavfreq(SPX_ARGS); int waveawav(SPX_ARGS); int awavwave(SPX_ARGS); int velobeta(SPX_ARGS); int betavelo(SPX_ARGS); int freqvelo(SPX_ARGS); int velofreq(SPX_ARGS); int freqvrad(SPX_ARGS); int vradfreq(SPX_ARGS); int wavevelo(SPX_ARGS); int velowave(SPX_ARGS); int awavvelo(SPX_ARGS); int veloawav(SPX_ARGS); int wavevopt(SPX_ARGS); int voptwave(SPX_ARGS); int wavezopt(SPX_ARGS); int zoptwave(SPX_ARGS); #ifdef __cplusplus } #endif #endif // WCSLIB_SPEC ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/tab.c0000644000175100001710000012612500000000000016303 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: tab.c,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *===========================================================================*/ #include #include #include #include #include "wcserr.h" #include "wcsmath.h" #include "wcsprintf.h" #include "wcsutil.h" #include "tab.h" const int TABSET = 137; // Map status return value to message. const char *tab_errmsg[] = { "Success", "Null tabprm pointer passed", "Memory allocation failed", "Invalid tabular parameters", "One or more of the x coordinates were invalid", "One or more of the world coordinates were invalid"}; // Convenience macro for invoking wcserr_set(). #define TAB_ERRMSG(status) WCSERR_SET(status), tab_errmsg[status] //---------------------------------------------------------------------------- int tabini(int alloc, int M, const int K[], struct tabprm *tab) { static const char *function = "tabini"; if (tab == 0x0) return TABERR_NULL_POINTER; // Initialize error message handling. if (tab->flag == -1) { tab->err = 0x0; } struct wcserr **err = &(tab->err); wcserr_clear(err); if (M <= 0) { return wcserr_set(WCSERR_SET(TABERR_BAD_PARAMS), "M must be positive, got %d", M); } // Determine the total number of elements in the coordinate array. int N; if (K) { N = M; for (int m = 0; m < M; m++) { if (K[m] < 0) { return wcserr_set(WCSERR_SET(TABERR_BAD_PARAMS), "Invalid tabular parameters: Each element of K must be " "non-negative, got %d", K[m]); } N *= K[m]; } } else { // Axis lengths as yet unknown. N = 0; } // Initialize memory management. if (tab->flag == -1 || tab->m_flag != TABSET) { if (tab->flag == -1) { tab->sense = 0x0; tab->p0 = 0x0; tab->delta = 0x0; tab->extrema = 0x0; tab->set_M = 0; } tab->m_flag = 0; tab->m_M = 0; tab->m_N = 0; tab->m_K = 0x0; tab->m_map = 0x0; tab->m_crval = 0x0; tab->m_index = 0x0; tab->m_indxs = 0x0; tab->m_coord = 0x0; } else { // Clear any outstanding signals set by wcstab(). for (int m = 0; m < tab->m_M; m++) { if (tab->m_indxs[m] == (double *)0x1) tab->m_indxs[m] = 0x0; } if (tab->m_coord == (double *)0x1) tab->m_coord = 0x0; } // Allocate memory for arrays if required. if (alloc || tab->K == 0x0 || tab->map == 0x0 || tab->crval == 0x0 || tab->index == 0x0 || tab->coord == 0x0) { // Was sufficient allocated previously? if (tab->m_flag == TABSET && (tab->m_M < M || tab->m_N < N)) { // No, free it. tabfree(tab); } if (alloc || tab->K == 0x0) { if (tab->m_K) { // In case the caller fiddled with it. tab->K = tab->m_K; } else { if (!(tab->K = calloc(M, sizeof(int)))) { return wcserr_set(TAB_ERRMSG(TABERR_MEMORY)); } tab->m_flag = TABSET; tab->m_M = M; tab->m_K = tab->K; } } if (alloc || tab->map == 0x0) { if (tab->m_map) { // In case the caller fiddled with it. tab->map = tab->m_map; } else { if (!(tab->map = calloc(M, sizeof(int)))) { return wcserr_set(TAB_ERRMSG(TABERR_MEMORY)); } tab->m_flag = TABSET; tab->m_M = M; tab->m_map = tab->map; } } if (alloc || tab->crval == 0x0) { if (tab->m_crval) { // In case the caller fiddled with it. tab->crval = tab->m_crval; } else { if (!(tab->crval = calloc(M, sizeof(double)))) { return wcserr_set(TAB_ERRMSG(TABERR_MEMORY)); } tab->m_flag = TABSET; tab->m_M = M; tab->m_crval = tab->crval; } } if (alloc || tab->index == 0x0) { if (tab->m_index) { // In case the caller fiddled with it. tab->index = tab->m_index; } else { if (!(tab->index = calloc(M, sizeof(double *)))) { return wcserr_set(TAB_ERRMSG(TABERR_MEMORY)); } tab->m_flag = TABSET; tab->m_M = M; tab->m_N = N; tab->m_index = tab->index; if (!(tab->m_indxs = calloc(M, sizeof(double *)))) { return wcserr_set(TAB_ERRMSG(TABERR_MEMORY)); } // Recall that calloc() initializes these pointers to zero. if (K) { for (int m = 0; m < M; m++) { if (K[m]) { if (!(tab->index[m] = calloc(K[m], sizeof(double)))) { return wcserr_set(TAB_ERRMSG(TABERR_MEMORY)); } tab->m_indxs[m] = tab->index[m]; } } } } } if (alloc || tab->coord == 0x0) { if (tab->m_coord) { // In case the caller fiddled with it. tab->coord = tab->m_coord; } else if (N) { if (!(tab->coord = calloc(N, sizeof(double)))) { return wcserr_set(TAB_ERRMSG(TABERR_MEMORY)); } tab->m_flag = TABSET; tab->m_M = M; tab->m_N = N; tab->m_coord = tab->coord; } } } tab->flag = 0; tab->M = M; // Set defaults. for (int m = 0; m < M; m++) { tab->map[m] = -1; tab->crval[m] = 0.0; if (K) { tab->K[m] = K[m]; double *dp; if ((dp = tab->index[m])) { for (int k = 0; k < K[m]; k++) { *(dp++) = k; } } } else { tab->K[m] = 0; } } // Initialize the coordinate array. for (double *dp = tab->coord; dp < tab->coord + N; dp++) { *dp = UNDEFINED; } return 0; } //---------------------------------------------------------------------------- int tabmem(struct tabprm *tab) { static const char *function = "tabmem"; if (tab == 0x0) return TABERR_NULL_POINTER; struct wcserr **err = &(tab->err); if (tab->M == 0 || tab->K == 0x0) { // Should have been set by this time. return wcserr_set(WCSERR_SET(TABERR_MEMORY), "Null pointers in tabprm struct"); } int M = tab->M; int N = tab->M; for (int m = 0; m < M; m++) { if (tab->K[m] < 0) { return wcserr_set(WCSERR_SET(TABERR_BAD_PARAMS), "Invalid tabular parameters: Each element of K must be " "non-negative, got %d", M); } N *= tab->K[m]; } if (tab->m_M == 0) { tab->m_M = M; } else if (tab->m_M < M) { // Only possible if the user changed M. return wcserr_set(WCSERR_SET(TABERR_MEMORY), "tabprm struct inconsistent"); } if (tab->m_N == 0) { tab->m_N = N; } else if (tab->m_N < N) { // Only possible if the user changed K[]. return wcserr_set(WCSERR_SET(TABERR_MEMORY), "tabprm struct inconsistent"); } if (tab->m_K == 0x0) { if ((tab->m_K = tab->K)) { tab->m_flag = TABSET; } } if (tab->m_map == 0x0) { if ((tab->m_map = tab->map)) { tab->m_flag = TABSET; } } if (tab->m_crval == 0x0) { if ((tab->m_crval = tab->crval)) { tab->m_flag = TABSET; } } if (tab->m_index == 0x0) { if ((tab->m_index = tab->index)) { tab->m_flag = TABSET; } } for (int m = 0; m < tab->m_M; m++) { if (tab->m_indxs[m] == 0x0 || tab->m_indxs[m] == (double *)0x1) { if ((tab->m_indxs[m] = tab->index[m])) { tab->m_flag = TABSET; } } } if (tab->m_coord == 0x0 || tab->m_coord == (double *)0x1) { if ((tab->m_coord = tab->coord)) { tab->m_flag = TABSET; } } tab->flag = 0; return 0; } //---------------------------------------------------------------------------- int tabcpy(int alloc, const struct tabprm *tabsrc, struct tabprm *tabdst) { static const char *function = "tabcpy"; int status; if (tabsrc == 0x0) return TABERR_NULL_POINTER; if (tabdst == 0x0) return TABERR_NULL_POINTER; struct wcserr **err = &(tabdst->err); int M = tabsrc->M; if (M <= 0) { return wcserr_set(WCSERR_SET(TABERR_BAD_PARAMS), "M must be positive, got %d", M); } if ((status = tabini(alloc, M, tabsrc->K, tabdst))) { return status; } int N = M; for (int m = 0; m < M; m++) { tabdst->map[m] = tabsrc->map[m]; tabdst->crval[m] = tabsrc->crval[m]; N *= tabsrc->K[m]; } double *dstp, *srcp; for (int m = 0; m < M; m++) { if ((srcp = tabsrc->index[m])) { dstp = tabdst->index[m]; for (int k = 0; k < tabsrc->K[m]; k++) { *(dstp++) = *(srcp++); } } } srcp = tabsrc->coord; dstp = tabdst->coord; for (int n = 0; n < N; n++) { *(dstp++) = *(srcp++); } return 0; } //---------------------------------------------------------------------------- int tabcmp( int dummy, double tol, const struct tabprm *tab1, const struct tabprm *tab2, int *equal) { // Avert nuisance compiler warnings about unused parameters. (void)dummy; if (tab1 == 0x0) return TABERR_NULL_POINTER; if (tab2 == 0x0) return TABERR_NULL_POINTER; if (equal == 0x0) return TABERR_NULL_POINTER; *equal = 0; if (tab1->M != tab2->M) { return 0; } int M = tab1->M; if (!wcsutil_intEq(M, tab1->K, tab2->K) || !wcsutil_intEq(M, tab1->map, tab2->map) || !wcsutil_dblEq(M, tol, tab1->crval, tab2->crval)) { return 0; } int N = M; for (int m = 0; m < M; m++) { if (!wcsutil_dblEq(tab1->K[m], tol, tab1->index[m], tab2->index[m])) { return 0; } N *= tab1->K[m]; } if (!wcsutil_dblEq(N, tol, tab1->coord, tab2->coord)) { return 0; } *equal = 1; return 0; } //---------------------------------------------------------------------------- int tabfree(struct tabprm *tab) { if (tab == 0x0) return TABERR_NULL_POINTER; if (tab->flag != -1) { // Clear any outstanding signals set by wcstab(). for (int m = 0; m < tab->m_M; m++) { if (tab->m_indxs[m] == (double *)0x1) tab->m_indxs[m] = 0x0; } if (tab->m_coord == (double *)0x1) tab->m_coord = 0x0; // Free memory allocated by tabini(). if (tab->m_flag == TABSET) { if (tab->K == tab->m_K) tab->K = 0x0; if (tab->map == tab->m_map) tab->map = 0x0; if (tab->crval == tab->m_crval) tab->crval = 0x0; if (tab->index == tab->m_index) tab->index = 0x0; if (tab->coord == tab->m_coord) tab->coord = 0x0; if (tab->m_K) free(tab->m_K); if (tab->m_map) free(tab->m_map); if (tab->m_crval) free(tab->m_crval); if (tab->m_index) { for (int m = 0; m < tab->m_M; m++) { if (tab->m_indxs[m]) free(tab->m_indxs[m]); } free(tab->m_index); free(tab->m_indxs); } if (tab->m_coord) free(tab->m_coord); } // Free memory allocated by tabset(). if (tab->sense) free(tab->sense); if (tab->p0) free(tab->p0); if (tab->delta) free(tab->delta); if (tab->extrema) free(tab->extrema); } tab->m_flag = 0; tab->m_M = 0; tab->m_N = 0; tab->m_K = 0x0; tab->m_map = 0x0; tab->m_crval = 0x0; tab->m_index = 0x0; tab->m_indxs = 0x0; tab->m_coord = 0x0; tab->sense = 0x0; tab->p0 = 0x0; tab->delta = 0x0; tab->extrema = 0x0; tab->set_M = 0; wcserr_clear(&(tab->err)); tab->flag = 0; return 0; } //---------------------------------------------------------------------------- int tabsize(const struct tabprm *tab, int sizes[2]) { if (tab == 0x0) { sizes[0] = sizes[1] = 0; return TABERR_SUCCESS; } // Base size, in bytes. sizes[0] = sizeof(struct tabprm); // Total size of allocated memory, in bytes. sizes[1] = 0; int exsizes[2]; int M = tab->M; // tabprm::K[]; sizes[1] += M * sizeof(int); // tabprm::map[]; sizes[1] += M * sizeof(int); // tabprm::crval[]; sizes[1] += M * sizeof(double); // tabprm::index[] and tabprm::m_indxs; sizes[1] += 2*M * sizeof(double *); for (int m = 0; m < M; m++) { if (tab->index[m]) { sizes[1] += tab->K[m] * sizeof(double); } } // tabprm::coord[]; sizes[1] += M * tab->nc * sizeof(double); // tab::err[]. wcserr_size(tab->err, exsizes); sizes[1] += exsizes[0] + exsizes[1]; // The remaining arrays are allocated by tabset(). if (tab->flag != TABSET) { return TABERR_SUCCESS; } // tabprm::sense[]. if (tab->sense) { sizes[1] += M * sizeof(int); } // tabprm::p0[]. if (tab->p0) { sizes[1] += M * sizeof(int); } // tabprm::delta[]. if (tab->delta) { sizes[1] += M * sizeof(double); } // tabprm::extrema[]. int ne = (tab->nc / tab->K[0]) * 2 * M; sizes[1] += ne * sizeof(double); return TABERR_SUCCESS; } //---------------------------------------------------------------------------- int tabprt(const struct tabprm *tab) { char *cp, text[128]; double *dp; if (tab == 0x0) return TABERR_NULL_POINTER; if (tab->flag != TABSET) { wcsprintf("The tabprm struct is UNINITIALIZED.\n"); return 0; } wcsprintf(" flag: %d\n", tab->flag); wcsprintf(" M: %d\n", tab->M); // Array dimensions. WCSPRINTF_PTR(" K: ", tab->K, "\n"); wcsprintf(" "); for (int m = 0; m < tab->M; m++) { wcsprintf("%6d", tab->K[m]); } wcsprintf("\n"); // Map vector. WCSPRINTF_PTR(" map: ", tab->map, "\n"); wcsprintf(" "); for (int m = 0; m < tab->M; m++) { wcsprintf("%6d", tab->map[m]); } wcsprintf("\n"); // Reference index value. WCSPRINTF_PTR(" crval: ", tab->crval, "\n"); wcsprintf(" "); for (int m = 0; m < tab->M; m++) { wcsprintf(" %#- 11.5g", tab->crval[m]); } wcsprintf("\n"); // Index vectors. WCSPRINTF_PTR(" index: ", tab->index, "\n"); for (int m = 0; m < tab->M; m++) { wcsprintf(" index[%d]: ", m); WCSPRINTF_PTR("", tab->index[m], ""); if (tab->index[m]) { for (int k = 0; k < tab->K[m]; k++) { if (k%5 == 0) { wcsprintf("\n "); } wcsprintf(" %#- 11.5g", tab->index[m][k]); } wcsprintf("\n"); } } // Coordinate array. WCSPRINTF_PTR(" coord: ", tab->coord, "\n"); dp = tab->coord; for (int n = 0; n < tab->nc; n++) { // Array index. int j = n; cp = text; for (int m = 0; m < tab->M; m++) { int nd = (tab->K[m] < 10) ? 1 : 2; sprintf(cp, ",%*d", nd, j % tab->K[m] + 1); j /= tab->K[m]; cp += strlen(cp); } wcsprintf(" (*%s)", text); for (int m = 0; m < tab->M; m++) { wcsprintf(" %#- 11.5g", *(dp++)); } wcsprintf("\n"); } wcsprintf(" nc: %d\n", tab->nc); WCSPRINTF_PTR(" sense: ", tab->sense, "\n"); if (tab->sense) { wcsprintf(" "); for (int m = 0; m < tab->M; m++) { wcsprintf("%6d", tab->sense[m]); } wcsprintf("\n"); } WCSPRINTF_PTR(" p0: ", tab->p0, "\n"); if (tab->p0) { wcsprintf(" "); for (int m = 0; m < tab->M; m++) { wcsprintf("%6d", tab->p0[m]); } wcsprintf("\n"); } WCSPRINTF_PTR(" delta: ", tab->delta, "\n"); if (tab->delta) { wcsprintf(" "); for (int m = 0; m < tab->M; m++) { wcsprintf(" %#- 11.5g", tab->delta[m]); } wcsprintf("\n"); } WCSPRINTF_PTR(" extrema: ", tab->extrema, "\n"); dp = tab->extrema; for (int n = 0; n < tab->nc/tab->K[0]; n++) { // Array index. int j = n; cp = text; *cp = '\0'; for (int m = 1; m < tab->M; m++) { int nd = (tab->K[m] < 10) ? 1 : 2; sprintf(cp, ",%*d", nd, j % tab->K[m] + 1); j /= tab->K[m]; cp += strlen(cp); } wcsprintf(" (*,*%s)", text); for (int m = 0; m < 2*tab->M; m++) { if (m == tab->M) wcsprintf("-> "); wcsprintf(" %#- 11.5g", *(dp++)); } wcsprintf("\n"); } WCSPRINTF_PTR(" err: ", tab->err, "\n"); if (tab->err) { wcserr_prt(tab->err, " "); } // Memory management. wcsprintf(" m_flag: %d\n", tab->m_flag); wcsprintf(" m_M: %d\n", tab->m_M); wcsprintf(" m_N: %d\n", tab->m_N); WCSPRINTF_PTR(" m_K: ", tab->m_K, ""); if (tab->m_K == tab->K) wcsprintf(" (= K)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_map: ", tab->m_map, ""); if (tab->m_map == tab->map) wcsprintf(" (= map)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_crval: ", tab->m_crval, ""); if (tab->m_crval == tab->crval) wcsprintf(" (= crval)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_index: ", tab->m_index, ""); if (tab->m_index == tab->index) wcsprintf(" (= index)"); wcsprintf("\n"); for (int m = 0; m < tab->M; m++) { wcsprintf(" m_indxs[%d]: ", m); WCSPRINTF_PTR("", tab->m_indxs[m], ""); if (tab->m_indxs[m] == tab->index[m]) wcsprintf(" (= index[%d])", m); wcsprintf("\n"); } WCSPRINTF_PTR(" m_coord: ", tab->m_coord, ""); if (tab->m_coord == tab->coord) wcsprintf(" (= coord)"); wcsprintf("\n"); return 0; } //---------------------------------------------------------------------------- int tabperr(const struct tabprm *tab, const char *prefix) { if (tab == 0x0) return TABERR_NULL_POINTER; if (tab->err) { wcserr_prt(tab->err, prefix); } return 0; } //---------------------------------------------------------------------------- int tabset(struct tabprm *tab) { static const char *function = "tabset"; if (tab == 0x0) return TABERR_NULL_POINTER; struct wcserr **err = &(tab->err); // Check the number of tabular coordinate axes. int M = tab->M; if (M < 1) { return wcserr_set(WCSERR_SET(TABERR_BAD_PARAMS), "Invalid tabular parameters: M must be positive, got %d", M); } // Check the axis lengths. if (!tab->K) { return wcserr_set(WCSERR_SET(TABERR_MEMORY), "Null pointers in tabprm struct"); } tab->nc = 1; for (int m = 0; m < M; m++) { if (tab->K[m] < 1) { return wcserr_set(WCSERR_SET(TABERR_BAD_PARAMS), "Invalid tabular parameters: Each element of K must be positive, " "got %d", tab->K[m]); } // Number of coordinate vectors in the coordinate array. tab->nc *= tab->K[m]; } // Check that the map vector is sensible. if (!tab->map) { return wcserr_set(WCSERR_SET(TABERR_MEMORY), "Null pointers in tabprm struct"); } for (int m = 0; m < M; m++) { int i = tab->map[m]; if (i < 0) { return wcserr_set(WCSERR_SET(TABERR_BAD_PARAMS), "Invalid tabular parameters: Each element of map must be " "non-negative, got %d", i); } } // Check memory allocation for the remaining vectors. if (!tab->crval || !tab->index || !tab->coord) { return wcserr_set(WCSERR_SET(TABERR_MEMORY), "Null pointers in tabprm struct"); } // Take memory if signalled to by wcstab(). for (int m = 0; m < tab->m_M; m++) { if (tab->m_indxs[m] == (double *)0x1 && (tab->m_indxs[m] = tab->index[m])) { tab->m_flag = TABSET; } } if (tab->m_coord == (double *)0x1 && (tab->m_coord = tab->coord)) { tab->m_flag = TABSET; } // Allocate memory for work vectors. if (tab->flag != TABSET || tab->set_M < M) { // Free memory that may have been allocated previously. if (tab->sense) free(tab->sense); if (tab->p0) free(tab->p0); if (tab->delta) free(tab->delta); if (tab->extrema) free(tab->extrema); // Allocate memory for internal arrays. if (!(tab->sense = calloc(M, sizeof(int)))) { return wcserr_set(TAB_ERRMSG(TABERR_MEMORY)); } if (!(tab->p0 = calloc(M, sizeof(int)))) { free(tab->sense); return wcserr_set(TAB_ERRMSG(TABERR_MEMORY)); } if (!(tab->delta = calloc(M, sizeof(double)))) { free(tab->sense); free(tab->p0); return wcserr_set(TAB_ERRMSG(TABERR_MEMORY)); } int ne = (tab->nc / tab->K[0]) * 2 * M; if (!(tab->extrema = calloc(ne, sizeof(double)))) { free(tab->sense); free(tab->p0); free(tab->delta); return wcserr_set(TAB_ERRMSG(TABERR_MEMORY)); } tab->set_M = M; } // Check that the index vectors are monotonic. int *Km = tab->K; for (int m = 0; m < M; m++, Km++) { tab->sense[m] = 0; if (*Km > 1) { double *Psi; if ((Psi = tab->index[m]) == 0x0) { // Default indexing. tab->sense[m] = 1; } else { for (int k = 0; k < *Km-1; k++) { switch (tab->sense[m]) { case 0: if (Psi[k] < Psi[k+1]) { // Monotonic increasing. tab->sense[m] = 1; } else if (Psi[k] > Psi[k+1]) { // Monotonic decreasing. tab->sense[m] = -1; } break; case 1: if (Psi[k] > Psi[k+1]) { // Should be monotonic increasing. free(tab->sense); free(tab->p0); free(tab->delta); free(tab->extrema); return wcserr_set(WCSERR_SET(TABERR_BAD_PARAMS), "Invalid tabular parameters: Index vectors are not " "monotonically increasing"); } break; case -1: if (Psi[k] < Psi[k+1]) { // Should be monotonic decreasing. free(tab->sense); free(tab->p0); free(tab->delta); free(tab->extrema); return wcserr_set(WCSERR_SET(TABERR_BAD_PARAMS), "Invalid tabular parameters: Index vectors are not " "monotonically decreasing"); } break; } } } if (tab->sense[m] == 0) { free(tab->sense); free(tab->p0); free(tab->delta); free(tab->extrema); return wcserr_set(WCSERR_SET(TABERR_BAD_PARAMS), "Invalid tabular parameters: Index vectors are not monotonic"); } } } // Find the extremal values of the coordinate elements in each row. double *dcrd = tab->coord; double *dmin = tab->extrema; double *dmax = tab->extrema + M; for (int ic = 0; ic < tab->nc; ic += tab->K[0]) { for (int m = 0; m < M; m++, dcrd++) { if (tab->K[0] > 1) { // Extrapolate a little before the start of the row. double dPsi; double *Psi = tab->index[0]; if (Psi == 0x0) { dPsi = 1.0; } else { dPsi = Psi[1] - Psi[0]; } double dval = *dcrd; if (dPsi != 0.0) { dval -= 0.5 * (*(dcrd+M) - *dcrd)/dPsi; } *(dmax+m) = *(dmin+m) = dval; } else { *(dmax+m) = *(dmin+m) = *dcrd; } } dcrd -= M; for (int i = 0; i < tab->K[0]; i++) { for (int m = 0; m < M; m++, dcrd++) { if (*(dmax+m) < *dcrd) *(dmax+m) = *dcrd; if (*(dmin+m) > *dcrd) *(dmin+m) = *dcrd; if (tab->K[0] > 1 && i == tab->K[0]-1) { // Extrapolate a little beyond the end of the row. double dPsi; double *Psi = tab->index[0]; if (Psi == 0x0) { dPsi = 1.0; } else { dPsi = Psi[i] - Psi[i-1]; } double dval = *dcrd; if (dPsi != 0.0) { dval += 0.5 * (*dcrd - *(dcrd-M))/dPsi; } if (*(dmax+m) < dval) *(dmax+m) = dval; if (*(dmin+m) > dval) *(dmin+m) = dval; } } } dmin += 2*M; dmax += 2*M; } tab->flag = TABSET; return 0; } //---------------------------------------------------------------------------- int tabx2s( struct tabprm *tab, int ncoord, int nelem, const double x[], double world[], int stat[]) { static const char *function = "tabx2s"; int status; if (tab == 0x0) return TABERR_NULL_POINTER; struct wcserr **err = &(tab->err); // Initialize if required. if (tab->flag != TABSET) { if ((status = tabset(tab))) return status; } // This is used a lot. int M = tab->M; status = 0; register const double *xp = x; register double *wp = world; register int *statp = stat; for (int n = 0; n < ncoord; n++) { // Determine the indexes. int *Km = tab->K; for (int m = 0; m < M; m++, Km++) { // N.B. psi_m and Upsilon_m are 1-relative FITS indexes. int i = tab->map[m]; double psi_m = *(xp+i) + tab->crval[m]; double *Psi = tab->index[m]; double upsilon; if (Psi == 0x0) { // Default indexing is simple. upsilon = psi_m; } else { // To ease confusion, decrement Psi so that we can use 1-relative // C array indexing to match the 1-relative FITS indexing. Psi--; if (*Km == 1) { // Index vector is degenerate. if (Psi[1]-0.5 <= psi_m && psi_m <= Psi[1]+0.5) { upsilon = psi_m; } else { *statp = 1; status = wcserr_set(TAB_ERRMSG(TABERR_BAD_X)); goto next; } } else { // Interpolate in the indexing vector. int k; if (tab->sense[m] == 1) { // Monotonic increasing index values. if (psi_m < Psi[1]) { if (Psi[1] - 0.5*(Psi[2]-Psi[1]) <= psi_m) { // Allow minor extrapolation. k = 1; } else { // Index is out of range. *statp = 1; status = wcserr_set(TAB_ERRMSG(TABERR_BAD_X)); goto next; } } else if (Psi[*Km] < psi_m) { if (psi_m <= Psi[*Km] + 0.5*(Psi[*Km]-Psi[*Km-1])) { // Allow minor extrapolation. k = *Km - 1; } else { // Index is out of range. *statp = 1; status = wcserr_set(TAB_ERRMSG(TABERR_BAD_X)); goto next; } } else { for (k = 1; k < *Km; k++) { if (psi_m < Psi[k]) { continue; } if (Psi[k] == psi_m && psi_m < Psi[k+1]) { break; } if (Psi[k] < psi_m && psi_m <= Psi[k+1]) { break; } } } } else { // Monotonic decreasing index values. if (psi_m > Psi[1]) { if (Psi[1] + 0.5*(Psi[1]-Psi[2]) >= psi_m) { // Allow minor extrapolation. k = 1; } else { // Index is out of range. *statp = 1; status = wcserr_set(TAB_ERRMSG(TABERR_BAD_X)); goto next; } } else if (psi_m < Psi[*Km]) { if (Psi[*Km] - 0.5*(Psi[*Km-1]-Psi[*Km]) <= psi_m) { // Allow minor extrapolation. k = *Km - 1; } else { // Index is out of range. *statp = 1; status = wcserr_set(TAB_ERRMSG(TABERR_BAD_X)); goto next; } } else { for (k = 1; k < *Km; k++) { if (psi_m > Psi[k]) { continue; } if (Psi[k] == psi_m && psi_m > Psi[k+1]) { break; } if (Psi[k] > psi_m && psi_m >= Psi[k+1]) { break; } } } } upsilon = k + (psi_m - Psi[k]) / (Psi[k+1] - Psi[k]); } } if (upsilon < 0.5 || upsilon > *Km + 0.5) { // Index out of range. *statp = 1; status = wcserr_set(TAB_ERRMSG(TABERR_BAD_X)); goto next; } // Fiducial array indices and fractional offset. // p1 is 1-relative while tab::p0 is 0-relative. int p1 = (int)floor(upsilon); tab->p0[m] = p1 - 1; tab->delta[m] = upsilon - p1; if (p1 == 0) { // Extrapolation below p1 == 1. tab->p0[m] += 1; tab->delta[m] -= 1.0; } else if (p1 == *Km && *Km > 1) { // Extrapolation above p1 == K_m. tab->p0[m] -= 1; tab->delta[m] += 1.0; } } // Now interpolate in the coordinate array; the M-dimensional linear // interpolation algorithm is described in Sect. 3.4 of WCS Paper IV. for (int m = 0; m < M; m++) { int i = tab->map[m]; *(wp+i) = 0.0; } // Loop over the 2^M vertices surrounding P. int nv = 1 << M; for (int iv = 0; iv < nv; iv++) { // Locate vertex in the coordinate array and compute its weight. int offset = 0; double wgt = 1.0; for (int m = M-1; m >= 0; m--) { offset *= tab->K[m]; offset += tab->p0[m]; if (iv & (1 << m)) { if (tab->K[m] > 1) offset++; wgt *= tab->delta[m]; } else { wgt *= 1.0 - tab->delta[m]; } } if (wgt == 0.0) continue; // Add the contribution from this vertex to each element. double *coord = tab->coord + offset*M; for (int m = 0; m < M; m++) { int i = tab->map[m]; *(wp+i) += *(coord++) * wgt; } if (wgt == 1.0) break; } *statp = 0; next: xp += nelem; wp += nelem; statp++; } return status; } //---------------------------------------------------------------------------- // Helper functions used only by tabs2x(). static int tabedge(struct tabprm *); static int tabrow(struct tabprm *, const double *); static int tabvox(struct tabprm *, const double *, int, double **, unsigned int *); int tabs2x( struct tabprm* tab, int ncoord, int nelem, const double world[], double x[], int stat[]) { static const char *function = "tabs2x"; int status; if (tab == 0x0) return TABERR_NULL_POINTER; struct wcserr **err = &(tab->err); // Initialize if required. if (tab->flag != TABSET) { if ((status = tabset(tab))) return status; } // This is used a lot. int M = tab->M; double **tabcoord = 0x0; int nv = 0; if (M > 1) { nv = 1 << M; tabcoord = calloc(nv, sizeof(double *)); } status = 0; register const double *wp = world; register double *xp = x; register int *statp = stat; for (int n = 0; n < ncoord; n++) { // Locate this coordinate in the coordinate array. int edge = 0; for (int m = 0; m < M; m++) { tab->p0[m] = 0; } int ic; for (ic = 0; ic < tab->nc; ic++) { if (tab->p0[0] == 0) { // New row, could it contain a solution? if (edge || tabrow(tab, wp)) { // No, skip it. ic += tab->K[0]; if (1 < M) { tab->p0[1]++; edge = tabedge(tab); } // Because ic will be incremented when the loop is reentered. ic--; continue; } } if (M == 1) { // Deal with the one-dimensional case separately for efficiency. double w = wp[tab->map[0]]; if (w == tab->coord[0]) { tab->p0[0] = 0; tab->delta[0] = 0.0; break; } else if (ic < tab->nc - 1) { if (((tab->coord[ic] <= w && w <= tab->coord[ic+1]) || (tab->coord[ic] >= w && w >= tab->coord[ic+1])) && (tab->index[0] == 0x0 || tab->index[0][ic] != tab->index[0][ic+1])) { tab->p0[0] = ic; tab->delta[0] = (w - tab->coord[ic]) / (tab->coord[ic+1] - tab->coord[ic]); break; } } } else { // Multi-dimensional tables are harder. if (!edge) { // Addresses of the coordinates for each corner of the "voxel". for (int iv = 0; iv < nv; iv++) { int offset = 0; for (int m = M-1; m >= 0; m--) { offset *= tab->K[m]; offset += tab->p0[m]; if ((iv & (1 << m)) && (tab->K[m] > 1)) offset++; } tabcoord[iv] = tab->coord + offset*M; } if (tabvox(tab, wp, 0, tabcoord, 0x0) == 0) { // Found a solution. break; } } // Next voxel. tab->p0[0]++; edge = tabedge(tab); } } if (ic == tab->nc) { // Coordinate not found; allow minor extrapolation. if (M == 1) { // Should there be a solution? double w = wp[tab->map[0]]; if (tab->extrema[0] <= w && w <= tab->extrema[1]) { double *dcrd = tab->coord; for (int i = 0; i < 2; i++) { if (i) dcrd += tab->K[0] - 2; double delta = (w - *dcrd) / (*(dcrd+1) - *dcrd); if (i == 0) { if (-0.5 <= delta && delta <= 0.0) { tab->p0[0] = 0; tab->delta[0] = delta; ic = 0; break; } } else { if (1.0 <= delta && delta <= 1.5) { tab->p0[0] = tab->K[0] - 1; tab->delta[0] = delta - 1.0; ic = 0; } } } } } else { // Multi-dimensional tables. // >>> TBD <<< } } if (ic == tab->nc) { // Coordinate not found. *statp = 1; status = wcserr_set(TAB_ERRMSG(TABERR_BAD_WORLD)); } else { // Determine the intermediate world coordinates. int *Km = tab->K; for (int m = 0; m < M; m++, Km++) { // N.B. Upsilon_m and psi_m are 1-relative FITS indexes. double upsilon = (tab->p0[m] + 1) + tab->delta[m]; if (upsilon < 0.5 || upsilon > *Km + 0.5) { // Index out of range. *statp = 1; status = wcserr_set(TAB_ERRMSG(TABERR_BAD_WORLD)); } else { // Do inverse lookup of the index vector. double *Psi = tab->index[m]; double psi_m; if (Psi == 0x0) { // Default indexing. psi_m = upsilon; } else { // Decrement Psi and use 1-relative C array indexing to match the // 1-relative FITS indexing. Psi--; if (*Km == 1) { // Degenerate index vector. psi_m = Psi[1]; } else { int k = (int)(upsilon); psi_m = Psi[k]; if (k < *Km) { psi_m += (upsilon - k) * (Psi[k+1] - Psi[k]); } } } xp[tab->map[m]] = psi_m - tab->crval[m]; } } *statp = 0; } wp += nelem; xp += nelem; statp++; } if (tabcoord) free(tabcoord); return status; } /*---------------------------------------------------------------------------- * Convenience routine to check whether tabprm::p0 has been incremented beyond * the end of an index vector and if so move it to the start of the next one. * Returns 1 if tabprm::p0 is sitting at the end of any non-degenerate index * vector. *---------------------------------------------------------------------------*/ int tabedge(struct tabprm* tab) { int edge = 0; for (int m = 0; m < tab->M; m++) { if (tab->p0[m] == tab->K[m]) { // p0 has been incremented beyond the end of an index vector, point it // to the next one. tab->p0[m] = 0; if (m < tab->M-1) { tab->p0[m+1]++; } } else if (tab->p0[m] == tab->K[m]-1 && tab->K[m] > 1) { // p0 is sitting at the end of a non-degenerate index vector. edge = 1; } } return edge; } /*---------------------------------------------------------------------------- * Quick test to see whether the world coordinate indicated by wp could lie * somewhere along (or near) the row of the image indexed by tabprm::p0. * Return 0 if so, 1 otherwise. * * tabprm::p0 selects a particular row of the image, p0[0] being ignored (i.e. * treated as zero). Adjacent rows that delimit a row of "voxels" are formed * by incrementing elements other than p0[0] in all binary combinations. N.B. * these are not the same as the voxels (pixels) that are indexed by, and * centred on, integral pixel coordinates in FITS. * * To see why it is necessary to examine the adjacent rows, consider the 2-D * case where the first world coordinate element is constant along each row. * If the first element of wp has value 0.5, and its value in the row indexed * by p0 has value 0, and in the next row it has value 1, then it is clear that * the solution lies in neither row but somewhere between them. Thus both rows * will be involved in finding the solution. * * tabprm::extrema is the address of the first element of a 1-D array that * records the minimum and maximum value of each element of the coordinate * vector in each row of the coordinate array, treated as though it were * defined as * * double extrema[K_M]...[K_2][2][M] * * The minimum is recorded in the first element of the compressed K_1 * dimension, then the maximum. *---------------------------------------------------------------------------*/ int tabrow(struct tabprm* tab, const double *wp) { const double tol = 1e-10; int M = tab->M; // The number of corners in a "voxel". We need examine only half this // number of rows. The extra factor of two will be used to select between // the minimal and maximal values in each row. unsigned int nv = 1 << M; unsigned int eq = 0; unsigned int lt = 0; unsigned int gt = 0; for (unsigned int iv = 0; iv < nv; iv++) { // Find the index into tabprm::extrema for this row. int offset = 0; for (int m = M-1; m > 0; m--) { offset *= tab->K[m]; offset += tab->p0[m]; // Select the row. if (iv & (1 << m)) { if (tab->K[m] > 1) offset++; } } // The K_1 dimension has length 2 (see prologue). offset *= 2; // Select the minimum on even numbered iterations, else the maximum. if (iv & 1) offset++; // The last dimension has length M (see prologue). offset *= M; // Address of the extremal elements (min or max) for this row. double *cp = tab->extrema + offset; // For each coordinate element, we only need to find one row where its // minimum value is less than that of wp, and one row where the maximum // value is greater. That doesn't mean that there is a solution, only // that there might be. for (int m = 0; m < M; m++, cp++) { // Apply the axis mapping. double w = wp[tab->map[m]]; // Finally the test itself; set bits in the bitmask. if (fabs(*cp - w) < tol) { eq |= (1 << m); } else if (*cp < w) { lt |= (1 << m); } else if (*cp > w) { gt |= (1 << m); } } // Have all bits been switched on? if ((lt | eq) == nv-1 && (gt | eq) == nv-1) { // A solution could lie within this row of voxels. return 0; } } // No solution in this row. return 1; } /*---------------------------------------------------------------------------- * Does the world coordinate indicated by wp lie within the voxel indexed by * tabprm::p0? If so, do a binary chop of the interior of the voxel to find * it and return 0, with tabprm::delta set to the solution. Else return 1. * * As in tabrow(), a "voxel" is formed by incrementing the elements of * tabprm::p0 in all binary combinations. Note that these are not the same as * the voxels (pixels) that are indexed by, and centred on, integral pixel * coordinates in FITS. * * tabvox() calls itself recursively. When called from outside, level, being * the level of recursion, should be given as zero. tabcoord is an array * holding the addresses of the coordinates for each corner of the voxel. * vox is the address of a work array (vox2) used during recursive calls to * dissect the voxel. It is ignored when tabvox() is called from outside * (level == 0). * * It is assumed that the image dimensions are no greater than 32. ----------------------------------------------------------------------------*/ int tabvox( struct tabprm* tab, const double *wp, int level, double **tabcoord, unsigned int *vox) { const double tol = 1e-10; int M = tab->M; // The number of corners in a voxel. unsigned int nv = 1 << M; double dv = 1.0; for (int i = 0; i < level; i++) { dv /= 2.0; } // Could the coordinate lie within this voxel (level == 0) or sub-voxel // (level > 0)? We use the fact that with linear interpolation the // coordinate elements are extremal in a corner and test each one. unsigned int lt = 0; unsigned int gt = 0; unsigned int eq = 0; for (unsigned int iv = 0; iv < nv; iv++) { // Select a corner of the sub-voxel. double coord[32]; for (int m = 0; m < M; m++) { coord[m] = 0.0; tab->delta[m] = level ? dv*vox[m] : 0.0; if (iv & (1 << m)) { tab->delta[m] += dv; } } // Compute the coordinates of this corner of the sub-voxel by linear // interpolation using the weighting algorithm described in Sect. 3.4 of // WCS Paper IV. for (unsigned int jv = 0; jv < nv; jv++) { // Find the weight for this corner of the parent voxel. double wgt = 1.0; for (int m = 0; m < M; m++) { if (jv & (1 << m)) { wgt *= tab->delta[m]; } else { wgt *= 1.0 - tab->delta[m]; } } if (wgt == 0.0) continue; // Add its contribution to each coordinate element. double *cp = tabcoord[jv]; for (int m = 0; m < M; m++) { coord[m] += *(cp++) * wgt; } if (wgt == 1.0) break; } // Coordinate elements are minimal or maximal in a corner. unsigned int et = 0; for (int m = 0; m < M; m++) { // Apply the axis mapping. double w = wp[tab->map[m]]; // Finally the test itself; set bits in the bitmask. if (fabs(coord[m] - w) < tol) { et |= (1 << m); } else if (coord[m] < w) { lt |= (1 << m); } else if (coord[m] > w) { gt |= (1 << m); } } if (et == nv-1) { // We've stumbled across a solution in this corner of the sub-voxel. return 0; } eq |= et; } // Could the coordinate lie within this sub-voxel? if ((lt | eq) == nv-1 && (gt | eq) == nv-1) { // Yes it could, but does it? // Is it time to stop the recursion? if (level == 31) { // We have a solution, squeeze out the last bit of juice. dv /= 2.0; for (int m = 0; m < M; m++) { tab->delta[m] = dv * (2.0*vox[m] + 1.0); } return 0; } // Subdivide the sub-voxel and try again for each subdivision. for (unsigned int iv = 0; iv < nv; iv++) { // Select the subdivision. unsigned int vox2[32]; for (int m = 0; m < M; m++) { vox2[m] = level ? 2*vox[m] : 0; if (iv & (1 << m)) { vox2[m]++; } } // Recurse. if (tabvox(tab, wp, level+1, tabcoord, vox2) == 0) { return 0; } } } // No solution in this sub-voxel. return 1; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/tab.h0000644000175100001710000006333500000000000016313 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: tab.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the tab routines * --------------------------- * Routines in this suite implement the part of the FITS World Coordinate * System (WCS) standard that deals with tabular coordinates, i.e. coordinates * that are defined via a lookup table, as described in * = "Representations of world coordinates in FITS", = Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (WCS Paper I) = = "Representations of spectral coordinates in FITS", = Greisen, E.W., Calabretta, M.R., Valdes, F.G., & Allen, S.L. = 2006, A&A, 446, 747 (WCS Paper III) * * These routines define methods to be used for computing tabular world * coordinates from intermediate world coordinates (a linear transformation * of image pixel coordinates), and vice versa. They are based on the tabprm * struct which contains all information needed for the computations. The * struct contains some members that must be set by the user, and others that * are maintained by these routines, somewhat like a C++ class but with no * encapsulation. * * tabini(), tabmem(), tabcpy(), and tabfree() are provided to manage the * tabprm struct, tabsize() computes its total size including allocated memory, * and tabprt() prints its contents. * * tabperr() prints the error message(s) (if any) stored in a tabprm struct. * * A setup routine, tabset(), computes intermediate values in the tabprm struct * from parameters in it that were supplied by the user. The struct always * needs to be set up by tabset() but it need not be called explicitly - refer * to the explanation of tabprm::flag. * * tabx2s() and tabs2x() implement the WCS tabular coordinate transformations. * * Accuracy: * --------- * No warranty is given for the accuracy of these routines (refer to the * copyright notice); intending users must satisfy for themselves their * adequacy for the intended purpose. However, closure effectively to within * double precision rounding error was demonstrated by test routine ttab.c * which accompanies this software. * * * tabini() - Default constructor for the tabprm struct * ---------------------------------------------------- * tabini() allocates memory for arrays in a tabprm struct and sets all members * of the struct to default values. * * PLEASE NOTE: every tabprm struct should be initialized by tabini(), possibly * repeatedly. On the first invokation, and only the first invokation, the * flag member of the tabprm struct must be set to -1 to initialize memory * management, regardless of whether tabini() will actually be used to allocate * memory. * * Given: * alloc int If true, allocate memory unconditionally for arrays in * the tabprm struct. * * If false, it is assumed that pointers to these arrays * have been set by the user except if they are null * pointers in which case memory will be allocated for * them regardless. (In other words, setting alloc true * saves having to initalize these pointers to zero.) * * M int The number of tabular coordinate axes. * * K const int[] * Vector of length M whose elements (K_1, K_2,... K_M) * record the lengths of the axes of the coordinate array * and of each indexing vector. M and K[] are used to * determine the length of the various tabprm arrays and * therefore the amount of memory to allocate for them. * Their values are copied into the tabprm struct. * * It is permissible to set K (i.e. the address of the * array) to zero which has the same effect as setting * each element of K[] to zero. In this case no memory * will be allocated for the index vectors or coordinate * array in the tabprm struct. These together with the * K vector must be set separately before calling * tabset(). * * Given and returned: * tab struct tabprm* * Tabular transformation parameters. Note that, in * order to initialize memory management tabprm::flag * should be set to -1 when tab is initialized for the * first time (memory leaks may result if it had already * been initialized). * * Function return value: * int Status return value: * 0: Success. * 1: Null tabprm pointer passed. * 2: Memory allocation failed. * 3: Invalid tabular parameters. * * For returns > 1, a detailed error message is set in * tabprm::err if enabled, see wcserr_enable(). * * * tabmem() - Acquire tabular memory * --------------------------------- * tabmem() takes control of memory allocated by the user for arrays in the * tabprm struct. * * Given and returned: * tab struct tabprm* * Tabular transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null tabprm pointer passed. * 2: Memory allocation failed. * * For returns > 1, a detailed error message is set in * tabprm::err if enabled, see wcserr_enable(). * * * tabcpy() - Copy routine for the tabprm struct * --------------------------------------------- * tabcpy() does a deep copy of one tabprm struct to another, using tabini() to * allocate memory for its arrays if required. Only the "information to be * provided" part of the struct is copied; a call to tabset() is required to * set up the remainder. * * Given: * alloc int If true, allocate memory unconditionally for arrays in * the tabprm struct. * * If false, it is assumed that pointers to these arrays * have been set by the user except if they are null * pointers in which case memory will be allocated for * them regardless. (In other words, setting alloc true * saves having to initalize these pointers to zero.) * * tabsrc const struct tabprm* * Struct to copy from. * * Given and returned: * tabdst struct tabprm* * Struct to copy to. tabprm::flag should be set to -1 * if tabdst was not previously initialized (memory leaks * may result if it was previously initialized). * * Function return value: * int Status return value: * 0: Success. * 1: Null tabprm pointer passed. * 2: Memory allocation failed. * * For returns > 1, a detailed error message is set in * tabprm::err (associated with tabdst) if enabled, see * wcserr_enable(). * * * tabcmp() - Compare two tabprm structs for equality * -------------------------------------------------- * tabcmp() compares two tabprm structs for equality. * * Given: * cmp int A bit field controlling the strictness of the * comparison. At present, this value must always be 0, * indicating a strict comparison. In the future, other * options may be added. * * tol double Tolerance for comparison of floating-point values. * For example, for tol == 1e-6, all floating-point * values in the structs must be equal to the first 6 * decimal places. A value of 0 implies exact equality. * * tab1 const struct tabprm* * The first tabprm struct to compare. * * tab2 const struct tabprm* * The second tabprm struct to compare. * * Returned: * equal int* Non-zero when the given structs are equal. * * Function return value: * int Status return value: * 0: Success. * 1: Null pointer passed. * * * tabfree() - Destructor for the tabprm struct * -------------------------------------------- * tabfree() frees memory allocated for the tabprm arrays by tabini(). * tabini() records the memory it allocates and tabfree() will only attempt to * free this. * * PLEASE NOTE: tabfree() must not be invoked on a tabprm struct that was not * initialized by tabini(). * * Returned: * tab struct tabprm* * Coordinate transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null tabprm pointer passed. * * * tabsize() - Compute the size of a tabprm struct * ----------------------------------------------- * tabsize() computes the full size of a tabprm struct, including allocated * memory. * * Given: * tab const struct tabprm* * Tabular transformation parameters. * * If NULL, the base size of the struct and the allocated * size are both set to zero. * * Returned: * sizes int[2] The first element is the base size of the struct as * returned by sizeof(struct tabprm). The second element * is the total allocated size, in bytes, assuming that * the allocation was done by tabini(). This figure * includes memory allocated for the constituent struct, * tabprm::err. * * It is not an error for the struct not to have been set * up via tabset(), which normally results in additional * memory allocation. * * Function return value: * int Status return value: * 0: Success. * * * tabprt() - Print routine for the tabprm struct * ---------------------------------------------- * tabprt() prints the contents of a tabprm struct using wcsprintf(). Mainly * intended for diagnostic purposes. * * Given: * tab const struct tabprm* * Tabular transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null tabprm pointer passed. * * * tabperr() - Print error messages from a tabprm struct * ----------------------------------------------------- * tabperr() prints the error message(s) (if any) stored in a tabprm struct. * If there are no errors then nothing is printed. It uses wcserr_prt(), q.v. * * Given: * tab const struct tabprm* * Tabular transformation parameters. * * prefix const char * * If non-NULL, each output line will be prefixed with * this string. * * Function return value: * int Status return value: * 0: Success. * 1: Null tabprm pointer passed. * * * tabset() - Setup routine for the tabprm struct * ----------------------------------------------- * tabset() allocates memory for work arrays in the tabprm struct and sets up * the struct according to information supplied within it. * * Note that this routine need not be called directly; it will be invoked by * tabx2s() and tabs2x() if tabprm::flag is anything other than a predefined * magic value. * * Given and returned: * tab struct tabprm* * Tabular transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null tabprm pointer passed. * 3: Invalid tabular parameters. * * For returns > 1, a detailed error message is set in * tabprm::err if enabled, see wcserr_enable(). * * * tabx2s() - Pixel-to-world transformation * ---------------------------------------- * tabx2s() transforms intermediate world coordinates to world coordinates * using coordinate lookup. * * Given and returned: * tab struct tabprm* * Tabular transformation parameters. * * Given: * ncoord, * nelem int The number of coordinates, each of vector length * nelem. * * x const double[ncoord][nelem] * Array of intermediate world coordinates, SI units. * * Returned: * world double[ncoord][nelem] * Array of world coordinates, in SI units. * * stat int[ncoord] * Status return value status for each coordinate: * 0: Success. * 1: Invalid intermediate world coordinate. * * Function return value: * int Status return value: * 0: Success. * 1: Null tabprm pointer passed. * 3: Invalid tabular parameters. * 4: One or more of the x coordinates were invalid, * as indicated by the stat vector. * * For returns > 1, a detailed error message is set in * tabprm::err if enabled, see wcserr_enable(). * * * tabs2x() - World-to-pixel transformation * ---------------------------------------- * tabs2x() transforms world coordinates to intermediate world coordinates. * * Given and returned: * tab struct tabprm* * Tabular transformation parameters. * * Given: * ncoord, * nelem int The number of coordinates, each of vector length * nelem. * world const double[ncoord][nelem] * Array of world coordinates, in SI units. * * Returned: * x double[ncoord][nelem] * Array of intermediate world coordinates, SI units. * stat int[ncoord] * Status return value status for each vector element: * 0: Success. * 1: Invalid world coordinate. * * Function return value: * int Status return value: * 0: Success. * 1: Null tabprm pointer passed. * 3: Invalid tabular parameters. * 5: One or more of the world coordinates were * invalid, as indicated by the stat vector. * * For returns > 1, a detailed error message is set in * tabprm::err if enabled, see wcserr_enable(). * * * tabprm struct - Tabular transformation parameters * ------------------------------------------------- * The tabprm struct contains information required to transform tabular * coordinates. It consists of certain members that must be set by the user * ("given") and others that are set by the WCSLIB routines ("returned"). Some * of the latter are supplied for informational purposes while others are for * internal use only. * * int flag * (Given and returned) This flag must be set to zero whenever any of the * following tabprm structure members are set or changed: * * - tabprm::M (q.v., not normally set by the user), * - tabprm::K (q.v., not normally set by the user), * - tabprm::map, * - tabprm::crval, * - tabprm::index, * - tabprm::coord. * * This signals the initialization routine, tabset(), to recompute the * returned members of the tabprm struct. tabset() will reset flag to * indicate that this has been done. * * PLEASE NOTE: flag should be set to -1 when tabini() is called for the * first time for a particular tabprm struct in order to initialize memory * management. It must ONLY be used on the first initialization otherwise * memory leaks may result. * * int M * (Given or returned) Number of tabular coordinate axes. * * If tabini() is used to initialize the tabprm struct (as would normally * be the case) then it will set M from the value passed to it as a * function argument. The user should not subsequently modify it. * * int *K * (Given or returned) Pointer to the first element of a vector of length * tabprm::M whose elements (K_1, K_2,... K_M) record the lengths of the * axes of the coordinate array and of each indexing vector. * * If tabini() is used to initialize the tabprm struct (as would normally * be the case) then it will set K from the array passed to it as a * function argument. The user should not subsequently modify it. * * int *map * (Given) Pointer to the first element of a vector of length tabprm::M * that defines the association between axis m in the M-dimensional * coordinate array (1 <= m <= M) and the indices of the intermediate world * coordinate and world coordinate arrays, x[] and world[], in the argument * lists for tabx2s() and tabs2x(). * * When x[] and world[] contain the full complement of coordinate elements * in image-order, as will usually be the case, then map[m-1] == i-1 for * axis i in the N-dimensional image (1 <= i <= N). In terms of the FITS * keywords * * map[PVi_3a - 1] == i - 1. * * However, a different association may result if x[], for example, only * contains a (relevant) subset of intermediate world coordinate elements. * For example, if M == 1 for an image with N > 1, it is possible to fill * x[] with the relevant coordinate element with nelem set to 1. In this * case map[0] = 0 regardless of the value of i. * * double *crval * (Given) Pointer to the first element of a vector of length tabprm::M * whose elements contain the index value for the reference pixel for each * of the tabular coordinate axes. * * double **index * (Given) Pointer to the first element of a vector of length tabprm::M of * pointers to vectors of lengths (K_1, K_2,... K_M) of 0-relative indexes * (see tabprm::K). * * The address of any or all of these index vectors may be set to zero, * i.e. * = index[m] == 0; * * this is interpreted as default indexing, i.e. * = index[m][k] = k; * * double *coord * (Given) Pointer to the first element of the tabular coordinate array, * treated as though it were defined as * = double coord[K_M]...[K_2][K_1][M]; * * (see tabprm::K) i.e. with the M dimension varying fastest so that the * M elements of a coordinate vector are stored contiguously in memory. * * int nc * (Returned) Total number of coordinate vectors in the coordinate array * being the product K_1 * K_2 * ... * K_M (see tabprm::K). * * int padding * (An unused variable inserted for alignment purposes only.) * * int *sense * (Returned) Pointer to the first element of a vector of length tabprm::M * whose elements indicate whether the corresponding indexing vector is * monotonic increasing (+1), or decreasing (-1). * * int *p0 * (Returned) Pointer to the first element of a vector of length tabprm::M * of interpolated indices into the coordinate array such that Upsilon_m, * as defined in Paper III, is equal to (p0[m] + 1) + tabprm::delta[m]. * * double *delta * (Returned) Pointer to the first element of a vector of length tabprm::M * of interpolated indices into the coordinate array such that Upsilon_m, * as defined in Paper III, is equal to (tabprm::p0[m] + 1) + delta[m]. * * double *extrema * (Returned) Pointer to the first element of an array that records the * minimum and maximum value of each element of the coordinate vector in * each row of the coordinate array, treated as though it were defined as * = double extrema[K_M]...[K_2][2][M] * * (see tabprm::K). The minimum is recorded in the first element of the * compressed K_1 dimension, then the maximum. This array is used by the * inverse table lookup function, tabs2x(), to speed up table searches. * * struct wcserr *err * (Returned) If enabled, when an error status is returned, this struct * contains detailed information about the error, see wcserr_enable(). * * int m_flag * (For internal use only.) * int m_M * (For internal use only.) * int m_N * (For internal use only.) * int set_M * (For internal use only.) * int m_K * (For internal use only.) * int m_map * (For internal use only.) * int m_crval * (For internal use only.) * int m_index * (For internal use only.) * int m_indxs * (For internal use only.) * int m_coord * (For internal use only.) * * * Global variable: const char *tab_errmsg[] - Status return messages * ------------------------------------------------------------------ * Error messages to match the status value returned from each function. * *===========================================================================*/ #ifndef WCSLIB_TAB #define WCSLIB_TAB #ifdef __cplusplus extern "C" { #endif extern const char *tab_errmsg[]; enum tab_errmsg_enum { TABERR_SUCCESS = 0, // Success. TABERR_NULL_POINTER = 1, // Null tabprm pointer passed. TABERR_MEMORY = 2, // Memory allocation failed. TABERR_BAD_PARAMS = 3, // Invalid tabular parameters. TABERR_BAD_X = 4, // One or more of the x coordinates were // invalid. TABERR_BAD_WORLD = 5 // One or more of the world coordinates were // invalid. }; struct tabprm { // Initialization flag (see the prologue above). //-------------------------------------------------------------------------- int flag; // Set to zero to force initialization. // Parameters to be provided (see the prologue above). //-------------------------------------------------------------------------- int M; // Number of tabular coordinate axes. int *K; // Vector of length M whose elements // (K_1, K_2,... K_M) record the lengths of // the axes of the coordinate array and of // each indexing vector. int *map; // Vector of length M usually such that // map[m-1] == i-1 for coordinate array // axis m and image axis i (see above). double *crval; // Vector of length M containing the index // value for the reference pixel for each // of the tabular coordinate axes. double **index; // Vector of pointers to M indexing vectors // of lengths (K_1, K_2,... K_M). double *coord; // (1+M)-dimensional tabular coordinate // array (see above). // Information derived from the parameters supplied. //-------------------------------------------------------------------------- int nc; // Number of coordinate vectors (of length // M) in the coordinate array. int padding; // (Dummy inserted for alignment purposes.) int *sense; // Vector of M flags that indicate whether // the Mth indexing vector is monotonic // increasing, or else decreasing. int *p0; // Vector of M indices. double *delta; // Vector of M increments. double *extrema; // (1+M)-dimensional array of coordinate // extrema. // Error handling //-------------------------------------------------------------------------- struct wcserr *err; // Private - the remainder are for memory management. //-------------------------------------------------------------------------- int m_flag, m_M, m_N; int set_M; int *m_K, *m_map; double *m_crval, **m_index, **m_indxs, *m_coord; }; // Size of the tabprm struct in int units, used by the Fortran wrappers. #define TABLEN (sizeof(struct tabprm)/sizeof(int)) int tabini(int alloc, int M, const int K[], struct tabprm *tab); int tabmem(struct tabprm *tab); int tabcpy(int alloc, const struct tabprm *tabsrc, struct tabprm *tabdst); int tabcmp(int cmp, double tol, const struct tabprm *tab1, const struct tabprm *tab2, int *equal); int tabfree(struct tabprm *tab); int tabsize(const struct tabprm *tab, int size[2]); int tabprt(const struct tabprm *tab); int tabperr(const struct tabprm *tab, const char *prefix); int tabset(struct tabprm *tab); int tabx2s(struct tabprm *tab, int ncoord, int nelem, const double x[], double world[], int stat[]); int tabs2x(struct tabprm *tab, int ncoord, int nelem, const double world[], double x[], int stat[]); // Deprecated. #define tabini_errmsg tab_errmsg #define tabcpy_errmsg tab_errmsg #define tabfree_errmsg tab_errmsg #define tabprt_errmsg tab_errmsg #define tabset_errmsg tab_errmsg #define tabx2s_errmsg tab_errmsg #define tabs2x_errmsg tab_errmsg #ifdef __cplusplus } #endif #endif // WCSLIB_TAB ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/wcs.c0000644000175100001710000036356700000000000016346 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcs.c,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *===========================================================================*/ #include #include #include #include #include "wcserr.h" #include "wcsmath.h" #include "wcsprintf.h" #include "wcstrig.h" #include "wcsunits.h" #include "wcsutil.h" #include "wtbarr.h" #include "lin.h" #include "dis.h" #include "log.h" #include "spc.h" #include "prj.h" #include "sph.h" #include "cel.h" #include "tab.h" #include "wcs.h" const int WCSSET = 137; // Maximum number of PVi_ma and PSi_ma keywords. int NPVMAX = 64; int NPSMAX = 8; // Map status return value to message. const char *wcs_errmsg[] = { "Success", "Null wcsprm pointer passed", "Memory allocation failed", "Linear transformation matrix is singular", "Inconsistent or unrecognized coordinate axis type", "Invalid parameter value", "Unrecognized coordinate transformation parameter", "Ill-conditioned coordinate transformation parameter", "One or more of the pixel coordinates were invalid", "One or more of the world coordinates were invalid", "Invalid world coordinate", "No solution found in the specified interval", "Invalid subimage specification", "Non-separable subimage coordinate system", "wcsprm struct is unset, use wcsset()"}; // Map error returns for lower-level routines. const int wcs_linerr[] = { WCSERR_SUCCESS, // 0: LINERR_SUCCESS WCSERR_NULL_POINTER, // 1: LINERR_NULL_POINTER WCSERR_MEMORY, // 2: LINERR_MEMORY WCSERR_SINGULAR_MTX, // 3: LINERR_SINGULAR_MTX WCSERR_BAD_PARAM, // 4: LINERR_DISTORT_INIT WCSERR_BAD_PIX, // 5: LINERR_DISTORT WCSERR_BAD_WORLD // 6: LINERR_DEDISTORT }; const int wcs_logerr[] = { WCSERR_SUCCESS, // 0: LOGERR_SUCCESS WCSERR_NULL_POINTER, // 1: LOGERR_NULL_POINTER WCSERR_BAD_PARAM, // 2: LOGERR_BAD_LOG_REF_VAL WCSERR_BAD_PIX, // 3: LOGERR_BAD_X WCSERR_BAD_WORLD // 4: LOGERR_BAD_WORLD }; const int wcs_spcerr[] = { // -1: SPCERR_NO_CHANGE WCSERR_SUCCESS, // 0: SPCERR_SUCCESS WCSERR_NULL_POINTER, // 1: SPCERR_NULL_POINTER WCSERR_BAD_PARAM, // 2: SPCERR_BAD_SPEC_PARAMS WCSERR_BAD_PIX, // 3: SPCERR_BAD_X WCSERR_BAD_WORLD // 4: SPCERR_BAD_SPEC }; const int wcs_celerr[] = { WCSERR_SUCCESS, // 0: CELERR_SUCCESS WCSERR_NULL_POINTER, // 1: CELERR_NULL_POINTER WCSERR_BAD_PARAM, // 2: CELERR_BAD_PARAM WCSERR_BAD_COORD_TRANS, // 3: CELERR_BAD_COORD_TRANS WCSERR_ILL_COORD_TRANS, // 4: CELERR_ILL_COORD_TRANS WCSERR_BAD_PIX, // 5: CELERR_BAD_PIX WCSERR_BAD_WORLD // 6: CELERR_BAD_WORLD }; const int wcs_taberr[] = { WCSERR_SUCCESS, // 0: TABERR_SUCCESS WCSERR_NULL_POINTER, // 1: TABERR_NULL_POINTER WCSERR_MEMORY, // 2: TABERR_MEMORY WCSERR_BAD_PARAM, // 3: TABERR_BAD_PARAMS WCSERR_BAD_PIX, // 4: TABERR_BAD_X WCSERR_BAD_WORLD // 5: TABERR_BAD_WORLD }; // Convenience macro for invoking wcserr_set(). #define WCS_ERRMSG(status) WCSERR_SET(status), wcs_errmsg[status] #ifndef signbit #define signbit(X) ((X) < 0.0 ? 1 : 0) #endif // Internal helper functions, not for general use. static int wcs_types(struct wcsprm *); static int wcs_units(struct wcsprm *); //---------------------------------------------------------------------------- int wcsnpv(int npvmax) { if (npvmax >= 0) NPVMAX = npvmax; return NPVMAX; } int wcsnps(int npsmax) { if (npsmax >= 0) NPSMAX = npsmax; return NPSMAX; } //---------------------------------------------------------------------------- int wcsini(int alloc, int naxis, struct wcsprm *wcs) { return wcsinit(alloc, naxis, wcs, -1, -1, -1); } //---------------------------------------------------------------------------- int wcsinit( int alloc, int naxis, struct wcsprm *wcs, int npvmax, int npsmax, int ndpmax) { static const char *function = "wcsinit"; int i, j, k, status; double *cd; struct wcserr **err; // Check inputs. if (wcs == 0x0) return WCSERR_NULL_POINTER; if (npvmax < 0) npvmax = wcsnpv(-1); if (npsmax < 0) npsmax = wcsnps(-1); // Initialize error message handling... if (wcs->flag == -1) { wcs->err = 0x0; } err = &(wcs->err); wcserr_clear(err); // ...and also in the contained structs in case we have to return due to // an error before they can be initialized by their specialized routines, // since wcsperr() assumes their wcserr pointers are valid. if (wcs->flag == -1) { wcs->lin.err = 0x0; wcs->cel.err = 0x0; wcs->spc.err = 0x0; } wcserr_clear(&(wcs->lin.err)); wcserr_clear(&(wcs->cel.err)); wcserr_clear(&(wcs->spc.err)); // Initialize pointers. if (wcs->flag == -1 || wcs->m_flag != WCSSET) { if (wcs->flag == -1) { wcs->tab = 0x0; wcs->types = 0x0; wcs->lin.flag = -1; } // Initialize memory management. wcs->m_flag = 0; wcs->m_naxis = 0; wcs->m_crpix = 0x0; wcs->m_pc = 0x0; wcs->m_cdelt = 0x0; wcs->m_crval = 0x0; wcs->m_cunit = 0x0; wcs->m_ctype = 0x0; wcs->m_pv = 0x0; wcs->m_ps = 0x0; wcs->m_cd = 0x0; wcs->m_crota = 0x0; wcs->m_colax = 0x0; wcs->m_cname = 0x0; wcs->m_crder = 0x0; wcs->m_csyer = 0x0; wcs->m_czphs = 0x0; wcs->m_cperi = 0x0; wcs->m_aux = 0x0; wcs->m_tab = 0x0; wcs->m_wtb = 0x0; } if (naxis < 0) { return wcserr_set(WCSERR_SET(WCSERR_MEMORY), "naxis must not be negative (got %d)", naxis); } // Allocate memory for arrays if required. if (alloc || wcs->crpix == 0x0 || wcs->pc == 0x0 || wcs->cdelt == 0x0 || wcs->crval == 0x0 || wcs->cunit == 0x0 || wcs->ctype == 0x0 || (npvmax && wcs->pv == 0x0) || (npsmax && wcs->ps == 0x0) || wcs->cd == 0x0 || wcs->crota == 0x0 || wcs->colax == 0x0 || wcs->cname == 0x0 || wcs->crder == 0x0 || wcs->csyer == 0x0 || wcs->czphs == 0x0 || wcs->cperi == 0x0) { // Was sufficient allocated previously? if (wcs->m_flag == WCSSET && (wcs->m_naxis < naxis || wcs->npvmax < npvmax || wcs->npsmax < npsmax)) { // No, free it. wcsfree(wcs); } if (alloc || wcs->crpix == 0x0) { if (wcs->m_crpix) { // In case the caller fiddled with it. wcs->crpix = wcs->m_crpix; } else { if ((wcs->crpix = calloc(naxis, sizeof(double))) == 0x0) { return wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); } wcs->m_flag = WCSSET; wcs->m_naxis = naxis; wcs->m_crpix = wcs->crpix; } } if (alloc || wcs->pc == 0x0) { if (wcs->m_pc) { // In case the caller fiddled with it. wcs->pc = wcs->m_pc; } else { if ((wcs->pc = calloc(naxis*naxis, sizeof(double))) == 0x0) { wcsfree(wcs); return wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); } wcs->m_flag = WCSSET; wcs->m_naxis = naxis; wcs->m_pc = wcs->pc; } } if (alloc || wcs->cdelt == 0x0) { if (wcs->m_cdelt) { // In case the caller fiddled with it. wcs->cdelt = wcs->m_cdelt; } else { if ((wcs->cdelt = calloc(naxis, sizeof(double))) == 0x0) { wcsfree(wcs); return wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); } wcs->m_flag = WCSSET; wcs->m_naxis = naxis; wcs->m_cdelt = wcs->cdelt; } } if (alloc || wcs->crval == 0x0) { if (wcs->m_crval) { // In case the caller fiddled with it. wcs->crval = wcs->m_crval; } else { if ((wcs->crval = calloc(naxis, sizeof(double))) == 0x0) { wcsfree(wcs); return wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); } wcs->m_flag = WCSSET; wcs->m_naxis = naxis; wcs->m_crval = wcs->crval; } } if (alloc || wcs->cunit == 0x0) { if (wcs->m_cunit) { // In case the caller fiddled with it. wcs->cunit = wcs->m_cunit; } else { if ((wcs->cunit = calloc(naxis, sizeof(char [72]))) == 0x0) { wcsfree(wcs); return wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); } wcs->m_flag = WCSSET; wcs->m_naxis = naxis; wcs->m_cunit = wcs->cunit; } } if (alloc || wcs->ctype == 0x0) { if (wcs->m_ctype) { // In case the caller fiddled with it. wcs->ctype = wcs->m_ctype; } else { if ((wcs->ctype = calloc(naxis, sizeof(char [72]))) == 0x0) { wcsfree(wcs); return wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); } wcs->m_flag = WCSSET; wcs->m_naxis = naxis; wcs->m_ctype = wcs->ctype; } } if (alloc || wcs->pv == 0x0) { if (wcs->m_pv) { // In case the caller fiddled with it. wcs->pv = wcs->m_pv; } else { if (npvmax) { if ((wcs->pv = calloc(npvmax, sizeof(struct pvcard))) == 0x0) { wcsfree(wcs); return wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); } } else { wcs->pv = 0x0; } wcs->npvmax = npvmax; wcs->m_flag = WCSSET; wcs->m_naxis = naxis; wcs->m_pv = wcs->pv; } } if (alloc || wcs->ps == 0x0) { if (wcs->m_ps) { // In case the caller fiddled with it. wcs->ps = wcs->m_ps; } else { if (npsmax) { if ((wcs->ps = calloc(npsmax, sizeof(struct pscard))) == 0x0) { wcsfree(wcs); return wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); } } else { wcs->ps = 0x0; } wcs->npsmax = npsmax; wcs->m_flag = WCSSET; wcs->m_naxis = naxis; wcs->m_ps = wcs->ps; } } if (alloc || wcs->cd == 0x0) { if (wcs->m_cd) { // In case the caller fiddled with it. wcs->cd = wcs->m_cd; } else { if ((wcs->cd = calloc(naxis*naxis, sizeof(double))) == 0x0) { wcsfree(wcs); return wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); } wcs->m_flag = WCSSET; wcs->m_naxis = naxis; wcs->m_cd = wcs->cd; } } if (alloc || wcs->crota == 0x0) { if (wcs->m_crota) { // In case the caller fiddled with it. wcs->crota = wcs->m_crota; } else { if ((wcs->crota = calloc(naxis, sizeof(double))) == 0x0) { wcsfree(wcs); return wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); } wcs->m_flag = WCSSET; wcs->m_naxis = naxis; wcs->m_crota = wcs->crota; } } if (alloc || wcs->colax == 0x0) { if (wcs->m_colax) { // In case the caller fiddled with it. wcs->colax = wcs->m_colax; } else { if ((wcs->colax = calloc(naxis, sizeof(int))) == 0x0) { wcsfree(wcs); return wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); } wcs->m_flag = WCSSET; wcs->m_naxis = naxis; wcs->m_colax = wcs->colax; } } if (alloc || wcs->cname == 0x0) { if (wcs->m_cname) { // In case the caller fiddled with it. wcs->cname = wcs->m_cname; } else { if ((wcs->cname = calloc(naxis, sizeof(char [72]))) == 0x0) { wcsfree(wcs); return wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); } wcs->m_flag = WCSSET; wcs->m_naxis = naxis; wcs->m_cname = wcs->cname; } } if (alloc || wcs->crder == 0x0) { if (wcs->m_crder) { // In case the caller fiddled with it. wcs->crder = wcs->m_crder; } else { if ((wcs->crder = calloc(naxis, sizeof(double))) == 0x0) { wcsfree(wcs); return wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); } wcs->m_flag = WCSSET; wcs->m_naxis = naxis; wcs->m_crder = wcs->crder; } } if (alloc || wcs->csyer == 0x0) { if (wcs->m_csyer) { // In case the caller fiddled with it. wcs->csyer = wcs->m_csyer; } else { if ((wcs->csyer = calloc(naxis, sizeof(double))) == 0x0) { wcsfree(wcs); return wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); } wcs->m_flag = WCSSET; wcs->m_naxis = naxis; wcs->m_csyer = wcs->csyer; } } if (alloc || wcs->czphs == 0x0) { if (wcs->m_czphs) { // In case the caller fiddled with it. wcs->czphs = wcs->m_czphs; } else { if ((wcs->czphs = calloc(naxis, sizeof(double))) == 0x0) { wcsfree(wcs); return wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); } wcs->m_flag = WCSSET; wcs->m_naxis = naxis; wcs->m_czphs = wcs->czphs; } } if (alloc || wcs->cperi == 0x0) { if (wcs->m_cperi) { // In case the caller fiddled with it. wcs->cperi = wcs->m_cperi; } else { if ((wcs->cperi = calloc(naxis, sizeof(double))) == 0x0) { wcsfree(wcs); return wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); } wcs->m_flag = WCSSET; wcs->m_naxis = naxis; wcs->m_cperi = wcs->cperi; } } } wcs->flag = 0; wcs->naxis = naxis; // Set defaults for the linear transformation. wcs->lin.crpix = wcs->crpix; wcs->lin.pc = wcs->pc; wcs->lin.cdelt = wcs->cdelt; if ((status = lininit(0, naxis, &(wcs->lin), ndpmax))) { return wcserr_set(WCS_ERRMSG(wcs_linerr[status])); } // CRVALia defaults to 0.0. for (i = 0; i < naxis; i++) { wcs->crval[i] = 0.0; } // CUNITia and CTYPEia are blank by default. for (i = 0; i < naxis; i++) { memset(wcs->cunit[i], 0, 72); memset(wcs->ctype[i], 0, 72); } // Set defaults for the celestial transformation parameters. wcs->lonpole = UNDEFINED; wcs->latpole = +90.0; // Set defaults for the spectral transformation parameters. wcs->restfrq = 0.0; wcs->restwav = 0.0; // Default parameter values. wcs->npv = 0; for (k = 0; k < wcs->npvmax; k++) { wcs->pv[k].i = 0; wcs->pv[k].m = 0; wcs->pv[k].value = 0.0; } wcs->nps = 0; for (k = 0; k < wcs->npsmax; k++) { wcs->ps[k].i = 0; wcs->ps[k].m = 0; memset(wcs->ps[k].value, 0, 72); } // Defaults for alternate linear transformations. cd = wcs->cd; for (i = 0; i < naxis; i++) { for (j = 0; j < naxis; j++) { *(cd++) = 0.0; } } for (i = 0; i < naxis; i++) { wcs->crota[i] = 0.0; } wcs->altlin = 0; wcs->velref = 0; // Defaults for auxiliary coordinate system information. memset(wcs->alt, 0, 4); wcs->alt[0] = ' '; wcs->colnum = 0; for (i = 0; i < naxis; i++) { wcs->colax[i] = 0; memset(wcs->cname[i], 0, 72); wcs->crder[i] = UNDEFINED; wcs->csyer[i] = UNDEFINED; wcs->czphs[i] = UNDEFINED; wcs->cperi[i] = UNDEFINED; } memset(wcs->wcsname, 0, 72); memset(wcs->timesys, 0, 72); memset(wcs->trefpos, 0, 72); memset(wcs->trefdir, 0, 72); memset(wcs->plephem, 0, 72); memset(wcs->timeunit, 0, 72); memset(wcs->dateref, 0, 72); wcs->mjdref[0] = UNDEFINED; wcs->mjdref[1] = UNDEFINED; wcs->timeoffs = UNDEFINED; memset(wcs->dateobs, 0, 72); memset(wcs->datebeg, 0, 72); memset(wcs->dateavg, 0, 72); memset(wcs->dateend, 0, 72); wcs->mjdobs = UNDEFINED; wcs->mjdbeg = UNDEFINED; wcs->mjdavg = UNDEFINED; wcs->mjdend = UNDEFINED; wcs->jepoch = UNDEFINED; wcs->bepoch = UNDEFINED; wcs->tstart = UNDEFINED; wcs->tstop = UNDEFINED; wcs->xposure = UNDEFINED; wcs->telapse = UNDEFINED; wcs->timsyer = UNDEFINED; wcs->timrder = UNDEFINED; wcs->timedel = UNDEFINED; wcs->timepixr = UNDEFINED; wcs->obsgeo[0] = UNDEFINED; wcs->obsgeo[1] = UNDEFINED; wcs->obsgeo[2] = UNDEFINED; wcs->obsgeo[3] = UNDEFINED; wcs->obsgeo[4] = UNDEFINED; wcs->obsgeo[5] = UNDEFINED; memset(wcs->obsorbit, 0, 72); memset(wcs->radesys, 0, 72); wcs->equinox = UNDEFINED; memset(wcs->specsys, 0, 72); memset(wcs->ssysobs, 0, 72); wcs->velosys = UNDEFINED; wcs->zsource = UNDEFINED; memset(wcs->ssyssrc, 0, 72); wcs->velangl = UNDEFINED; // No additional auxiliary coordinate system information. wcs->aux = 0x0; // Tabular parameters. wcs->ntab = 0; wcs->tab = 0x0; wcs->nwtb = 0; wcs->wtb = 0x0; // Reset derived values. strcpy(wcs->lngtyp, " "); strcpy(wcs->lattyp, " "); wcs->lng = -1; wcs->lat = -1; wcs->spec = -1; wcs->cubeface = -1; celini(&(wcs->cel)); spcini(&(wcs->spc)); return WCSERR_SUCCESS; } //---------------------------------------------------------------------------- int wcsauxi( int alloc, struct wcsprm *wcs) { static const char *function = "wcsauxi"; struct auxprm *aux; struct wcserr **err; // Check inputs. if (wcs == 0x0) return WCSERR_NULL_POINTER; err = &(wcs->err); // Allocate memory if required. if (alloc || wcs->aux == 0x0) { if (wcs->m_aux) { // In case the caller fiddled with it. wcs->aux = wcs->m_aux; } else { if ((wcs->aux = malloc(sizeof(struct auxprm))) == 0x0) { return wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); } wcs->m_aux = wcs->aux; } } aux = wcs->aux; aux->rsun_ref = UNDEFINED; aux->dsun_obs = UNDEFINED; aux->crln_obs = UNDEFINED; aux->hgln_obs = UNDEFINED; aux->hglt_obs = UNDEFINED; return WCSERR_SUCCESS; } //---------------------------------------------------------------------------- int wcssub( int alloc, const struct wcsprm *wcssrc, int *nsub, int axes[], struct wcsprm *wcsdst) { static const char *function = "wcssub"; const char *pq = "PQ"; char *c, ctypei[16], ctmp[16], *fp; int axis, axmap[32], cubeface, dealloc, dummy, i, idp, itab, *itmp = 0x0, j, jhat, k, latitude, longitude, m, *map, msub, naxis, ndp, ndpmax, Nhat, npv, npvmax, nps, npsmax, ntmp, other, spectral, status, stokes; const double *srcp; double *dstp; struct tabprm *tab; struct disprm *dissrc, *disdst; struct dpkey *dpsrc, *dpdst; struct wcserr **err; if (wcssrc == 0x0) return WCSERR_NULL_POINTER; if (wcsdst == 0x0) return WCSERR_NULL_POINTER; err = &(wcsdst->err); // N.B. we do not rely on the wcsprm struct having been set up. if ((naxis = wcssrc->naxis) <= 0) { return wcserr_set(WCSERR_SET(WCSERR_MEMORY), "naxis must be positive (got %d)", naxis); } if (nsub == 0x0) { nsub = &dummy; *nsub = naxis; } else if (*nsub == 0) { *nsub = naxis; } // Allocate enough temporary storage to hold either axes[] xor map[]. ntmp = (*nsub <= naxis) ? naxis : *nsub; if ((itmp = calloc(ntmp, sizeof(int))) == 0x0) { return wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); } if ((dealloc = (axes == 0x0))) { // Construct an index array. if ((axes = calloc(naxis, sizeof(int))) == 0x0) { free(itmp); return wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); } for (i = 0; i < naxis; i++) { axes[i] = i+1; } } // So that we don't try to free uninitialized pointers on cleanup. wcsdst->m_aux = 0x0; wcsdst->m_tab = 0x0; msub = 0; for (j = 0; j < *nsub; j++) { axis = axes[j]; if (abs(axis) > 0x1000) { // Subimage extraction by type. k = abs(axis) & 0xFF; longitude = k & WCSSUB_LONGITUDE; latitude = k & WCSSUB_LATITUDE; cubeface = k & WCSSUB_CUBEFACE; spectral = k & WCSSUB_SPECTRAL; stokes = k & WCSSUB_STOKES; if ((other = (axis < 0))) { longitude = !longitude; latitude = !latitude; cubeface = !cubeface; spectral = !spectral; stokes = !stokes; } for (i = 0; i < naxis; i++) { strncpy (ctypei, (char *)(wcssrc->ctype + i), 8); ctypei[8] = '\0'; // Find the last non-blank character. c = ctypei + 8; while (c-- > ctypei) { if (*c == ' ') *c = '\0'; if (*c != '\0') break; } if ( strcmp(ctypei, "RA") == 0 || strcmp(ctypei+1, "LON") == 0 || strcmp(ctypei+2, "LN") == 0 || strncmp(ctypei, "RA---", 5) == 0 || strncmp(ctypei+1, "LON-", 4) == 0 || strncmp(ctypei+2, "LN-", 3) == 0) { if (!longitude) { continue; } } else if ( strcmp(ctypei, "DEC") == 0 || strcmp(ctypei+1, "LAT") == 0 || strcmp(ctypei+2, "LT") == 0 || strncmp(ctypei, "DEC--", 5) == 0 || strncmp(ctypei+1, "LAT-", 4) == 0 || strncmp(ctypei+2, "LT-", 3) == 0) { if (!latitude) { continue; } } else if (strcmp(ctypei, "CUBEFACE") == 0) { if (!cubeface) { continue; } } else if (( strncmp(ctypei, "FREQ", 4) == 0 || strncmp(ctypei, "ENER", 4) == 0 || strncmp(ctypei, "WAVN", 4) == 0 || strncmp(ctypei, "VRAD", 4) == 0 || strncmp(ctypei, "WAVE", 4) == 0 || strncmp(ctypei, "VOPT", 4) == 0 || strncmp(ctypei, "ZOPT", 4) == 0 || strncmp(ctypei, "AWAV", 4) == 0 || strncmp(ctypei, "VELO", 4) == 0 || strncmp(ctypei, "BETA", 4) == 0) && (ctypei[4] == '\0' || ctypei[4] == '-')) { if (!spectral) { continue; } } else if (strcmp(ctypei, "STOKES") == 0) { if (!stokes) { continue; } } else if (!other) { continue; } // This axis is wanted, but has it already been added? for (k = 0; k < msub; k++) { if (itmp[k] == i+1) { break; } } if (k == msub) itmp[msub++] = i+1; } } else if (0 < axis && axis <= naxis) { // Check that the requested axis has not already been added. for (k = 0; k < msub; k++) { if (itmp[k] == axis) { break; } } if (k == msub) itmp[msub++] = axis; } else if (axis == 0) { // Graft on a new axis. itmp[msub++] = 0; } else { status = wcserr_set(WCS_ERRMSG(WCSERR_BAD_SUBIMAGE)); goto cleanup; } } if ((*nsub = msub) == 0) { // Zero out this struct. status = wcsinit(alloc, 0, wcsdst, 0, 0, 0); goto cleanup; } for (i = 0; i < *nsub; i++) { axes[i] = itmp[i]; } // Construct the inverse axis map (i is 0-relative, j is 1-relative): // axes[i] == j means that output axis i+1 comes from input axis j, // axes[i] == 0 means to create a new axis, // map[i] == j means that input axis i+1 goes to output axis j, // map[i] == 0 means that input axis i+1 is not used. map = itmp; for (i = 0; i < naxis; i++) { map[i] = 0; } for (i = 0; i < *nsub; i++) { if (axes[i] > 0) { map[axes[i]-1] = i+1; } } // Check that the subimage coordinate system is separable. First check // non-zero, off-diagonal elements of the linear transformation matrix. srcp = wcssrc->pc; for (i = 0; i < naxis; i++) { for (j = 0; j < naxis; j++) { if (*(srcp++) == 0.0 || j == i) continue; if ((map[i] == 0) != (map[j] == 0)) { status = wcserr_set(WCS_ERRMSG(WCSERR_NON_SEPARABLE)); goto cleanup; } } } // Now check for distortions that depend on other axes. As the disprm // struct may not have been initialized, we must parse the dpkey entries. ndpmax = 0; for (m = 0; m < 2; m++) { if (m == 0) { dissrc = wcssrc->lin.dispre; } else { dissrc = wcssrc->lin.disseq; } ndp = 0; if (dissrc != 0x0) { for (j = 0; j < naxis; j++) { if (map[j] == 0) continue; // Axis numbers in axmap[] are 0-relative. for (jhat = 0; jhat < 32; jhat++) { axmap[jhat] = -1; } Nhat = 0; dpsrc = dissrc->dp; for (idp = 0; idp < dissrc->ndp; idp++, dpsrc++) { // Thorough error checking will be done later by disset(). if (dpsrc->j != j+1) continue; if (dpsrc->field[1] != pq[m]) continue; if ((fp = strchr(dpsrc->field, '.')) == 0x0) continue; fp++; ndp++; if (strncmp(fp, "NAXES", 6) == 0) { Nhat = dpkeyi(dpsrc); } else if (strncmp(fp, "AXIS.", 5) == 0) { sscanf(fp+5, "%d", &jhat); axmap[jhat-1] = dpkeyi(dpsrc) - 1; } } if (Nhat < 0 || (Nhat == 0 && 1 < ndp) || naxis < Nhat || 32 < Nhat) { status = wcserr_set(WCSERR_SET(WCSERR_BAD_PARAM), "NAXES was not set (or bad) for %s distortion on axis %d", dissrc->dtype[j], j+1); goto cleanup; } for (jhat = 0; jhat < Nhat; jhat++) { if (axmap[jhat] < 0) { axmap[jhat] = jhat; // Make room for an additional DPja.AXIS.j record. ndp++; } if (map[axmap[jhat]] == 0) { // Distortion depends on an axis excluded from the subimage. status = wcserr_set(WCS_ERRMSG(WCSERR_NON_SEPARABLE)); goto cleanup; } } } } if (ndpmax < ndp) ndpmax = ndp; } // Number of PVi_ma records in the subimage. npvmax = 0; for (m = 0; m < wcssrc->npv; m++) { i = wcssrc->pv[m].i; if (i == 0 || (i > 0 && map[i-1])) { npvmax++; } } // Number of PSi_ma records in the subimage. npsmax = 0; for (m = 0; m < wcssrc->nps; m++) { i = wcssrc->ps[m].i; if (i > 0 && map[i-1]) { npsmax++; } } // Initialize the destination. status = wcsinit(alloc, *nsub, wcsdst, npvmax, npsmax, ndpmax); for (m = 0; m < 2; m++) { if (m == 0) { dissrc = wcssrc->lin.dispre; disdst = wcsdst->lin.dispre; } else { dissrc = wcssrc->lin.disseq; disdst = wcsdst->lin.disseq; } if (dissrc && !disdst) { if ((disdst = calloc(1, sizeof(struct disprm))) == 0x0) { return wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); } // Also inits disdst. disdst->flag = -1; lindist(m+1, &(wcsdst->lin), disdst, ndpmax); } } if (status) { goto cleanup; } // Linear transformation. srcp = wcssrc->crpix; dstp = wcsdst->crpix; for (j = 0; j < *nsub; j++, dstp++) { if (axes[j] > 0) { k = axes[j] - 1; *dstp = *(srcp+k); } } srcp = wcssrc->pc; dstp = wcsdst->pc; for (i = 0; i < *nsub; i++) { for (j = 0; j < *nsub; j++, dstp++) { if (axes[i] > 0 && axes[j] > 0) { k = (axes[i]-1)*naxis + (axes[j]-1); *dstp = *(srcp+k); } } } srcp = wcssrc->cdelt; dstp = wcsdst->cdelt; for (i = 0; i < *nsub; i++, dstp++) { if (axes[i] > 0) { k = axes[i] - 1; *dstp = *(srcp+k); } } // Coordinate reference value. srcp = wcssrc->crval; dstp = wcsdst->crval; for (i = 0; i < *nsub; i++, dstp++) { if (axes[i] > 0) { k = axes[i] - 1; *dstp = *(srcp+k); } } // Coordinate units and type. for (i = 0; i < *nsub; i++) { if (axes[i] > 0) { k = axes[i] - 1; strncpy(wcsdst->cunit[i], wcssrc->cunit[k], 72); strncpy(wcsdst->ctype[i], wcssrc->ctype[k], 72); } } // Celestial and spectral transformation parameters. wcsdst->lonpole = wcssrc->lonpole; wcsdst->latpole = wcssrc->latpole; wcsdst->restfrq = wcssrc->restfrq; wcsdst->restwav = wcssrc->restwav; // Parameter values. npv = 0; for (m = 0; m < wcssrc->npv; m++) { i = wcssrc->pv[m].i; if (i == 0) { // i == 0 is a special code that means "the latitude axis". wcsdst->pv[npv] = wcssrc->pv[m]; wcsdst->pv[npv].i = 0; npv++; } else if (i > 0 && map[i-1]) { wcsdst->pv[npv] = wcssrc->pv[m]; wcsdst->pv[npv].i = map[i-1]; npv++; } } wcsdst->npv = npv; nps = 0; for (m = 0; m < wcssrc->nps; m++) { i = wcssrc->ps[m].i; if (i > 0 && map[i-1]) { wcsdst->ps[nps] = wcssrc->ps[m]; wcsdst->ps[nps].i = map[i-1]; nps++; } } wcsdst->nps = nps; // Alternate linear transformations. if (wcssrc->cd) { srcp = wcssrc->cd; dstp = wcsdst->cd; for (i = 0; i < *nsub; i++) { for (j = 0; j < *nsub; j++, dstp++) { if (axes[i] > 0 && axes[j] > 0) { k = (axes[i]-1)*naxis + (axes[j]-1); *dstp = *(srcp+k); } else if (i == j && wcssrc->altlin & 2) { // A new axis is being created where CDi_ja was present in the input // header, so override the default value of 0 set by wcsinit(). *dstp = 1.0; } } } } if (wcssrc->crota) { srcp = wcssrc->crota; dstp = wcsdst->crota; for (i = 0; i < *nsub; i++, dstp++) { if (axes[i] > 0) { k = axes[i] - 1; *dstp = *(srcp+k); } } } wcsdst->altlin = wcssrc->altlin; wcsdst->velref = wcssrc->velref; // Auxiliary coordinate system information. strncpy(wcsdst->alt, wcssrc->alt, 4); wcsdst->colnum = wcssrc->colnum; for (i = 0; i < *nsub; i++) { if (axes[i] > 0) { k = axes[i] - 1; if (wcssrc->colax) wcsdst->colax[i] = wcssrc->colax[k]; if (wcssrc->cname) strncpy(wcsdst->cname[i], wcssrc->cname[k], 72); if (wcssrc->crder) wcsdst->crder[i] = wcssrc->crder[k]; if (wcssrc->csyer) wcsdst->csyer[i] = wcssrc->csyer[k]; if (wcssrc->czphs) wcsdst->czphs[i] = wcssrc->czphs[k]; if (wcssrc->cperi) wcsdst->cperi[i] = wcssrc->cperi[k]; } } strncpy(wcsdst->wcsname, wcssrc->wcsname, 72); strncpy(wcsdst->timesys, wcssrc->timesys, 72); strncpy(wcsdst->trefpos, wcssrc->trefpos, 72); strncpy(wcsdst->trefdir, wcssrc->trefdir, 72); strncpy(wcsdst->plephem, wcssrc->plephem, 72); strncpy(wcsdst->timeunit, wcssrc->timeunit, 72); strncpy(wcsdst->dateref, wcssrc->dateref, 72); wcsdst->mjdref[0] = wcssrc->mjdref[0]; wcsdst->mjdref[1] = wcssrc->mjdref[1]; wcsdst->timeoffs = wcssrc->timeoffs; strncpy(wcsdst->dateobs, wcssrc->dateobs, 72); strncpy(wcsdst->datebeg, wcssrc->datebeg, 72); strncpy(wcsdst->dateavg, wcssrc->dateavg, 72); strncpy(wcsdst->dateend, wcssrc->dateend, 72); wcsdst->mjdobs = wcssrc->mjdobs; wcsdst->mjdbeg = wcssrc->mjdbeg; wcsdst->mjdavg = wcssrc->mjdavg; wcsdst->mjdend = wcssrc->mjdend; wcsdst->jepoch = wcssrc->jepoch; wcsdst->bepoch = wcssrc->bepoch; wcsdst->tstart = wcssrc->tstart; wcsdst->tstop = wcssrc->tstop; wcsdst->xposure = wcssrc->xposure; wcsdst->telapse = wcssrc->telapse; wcsdst->timsyer = wcssrc->timsyer; wcsdst->timrder = wcssrc->timrder; wcsdst->timedel = wcssrc->timedel; wcsdst->timepixr = wcssrc->timepixr; wcsdst->obsgeo[0] = wcssrc->obsgeo[0]; wcsdst->obsgeo[1] = wcssrc->obsgeo[1]; wcsdst->obsgeo[2] = wcssrc->obsgeo[2]; wcsdst->obsgeo[3] = wcssrc->obsgeo[3]; wcsdst->obsgeo[4] = wcssrc->obsgeo[4]; wcsdst->obsgeo[5] = wcssrc->obsgeo[5]; strncpy(wcsdst->obsorbit, wcssrc->obsorbit, 72); strncpy(wcsdst->radesys, wcssrc->radesys, 72); wcsdst->equinox = wcssrc->equinox; strncpy(wcsdst->specsys, wcssrc->specsys, 72); strncpy(wcsdst->ssysobs, wcssrc->ssysobs, 72); wcsdst->velosys = wcssrc->velosys; wcsdst->zsource = wcssrc->zsource; strncpy(wcsdst->ssyssrc, wcssrc->ssyssrc, 72); wcsdst->velangl = wcssrc->velangl; // Additional auxiliary coordinate system information. if (wcssrc->aux && !wcsdst->aux) { if ((wcsdst->aux = calloc(1, sizeof(struct auxprm))) == 0x0) { status = wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); goto cleanup; } wcsdst->m_aux = wcsdst->aux; wcsdst->aux->rsun_ref = wcssrc->aux->rsun_ref; wcsdst->aux->dsun_obs = wcssrc->aux->dsun_obs; wcsdst->aux->crln_obs = wcssrc->aux->crln_obs; wcsdst->aux->hgln_obs = wcssrc->aux->hgln_obs; wcsdst->aux->hglt_obs = wcssrc->aux->hglt_obs; } // Coordinate lookup tables; only copy what's needed. wcsdst->ntab = 0; for (itab = 0; itab < wcssrc->ntab; itab++) { // Is this table wanted? for (m = 0; m < wcssrc->tab[itab].M; m++) { i = wcssrc->tab[itab].map[m]; if (map[i]) { wcsdst->ntab++; break; } } } if (wcsdst->ntab) { // Allocate memory for tabprm structs. if ((wcsdst->tab = calloc(wcsdst->ntab, sizeof(struct tabprm))) == 0x0) { wcsdst->ntab = 0; status = wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); goto cleanup; } wcsdst->m_tab = wcsdst->tab; } tab = wcsdst->tab; for (itab = 0; itab < wcssrc->ntab; itab++) { for (m = 0; m < wcssrc->tab[itab].M; m++) { i = wcssrc->tab[itab].map[m]; if (map[i]) { if ((status = tabcpy(1, wcssrc->tab + itab, tab))) { wcserr_set(WCS_ERRMSG(wcs_taberr[status])); goto cleanup; } tab++; break; } } } // Distortion parameters (in linprm). for (m = 0; m < 2; m++) { if (m == 0) { dissrc = wcssrc->lin.dispre; disdst = wcsdst->lin.dispre; } else { dissrc = wcssrc->lin.disseq; disdst = wcsdst->lin.disseq; } if (dissrc) { disdst->naxis = *nsub; // Distortion type and maximum distortion (but not total distortion). for (j = 0; j < *nsub; j++) { if (axes[j] > 0) { k = axes[j] - 1; strncpy(disdst->dtype[j], dissrc->dtype[k], 72); disdst->maxdis[j] = dissrc->maxdis[k]; } } // DPja or DQia keyvalues. ndp = 0; dpdst = disdst->dp; for (j = 0; j < *nsub; j++) { if (axes[j] == 0) continue; // Determine the axis mapping. for (jhat = 0; jhat < 32; jhat++) { axmap[jhat] = -1; } Nhat = 0; dpsrc = dissrc->dp; for (idp = 0; idp < dissrc->ndp; idp++, dpsrc++) { if (dpsrc->j != axes[j]) continue; if (dpsrc->field[1] != pq[m]) continue; if ((fp = strchr(dpsrc->field, '.')) == 0x0) continue; fp++; if (strncmp(fp, "NAXES", 6) == 0) { Nhat = dpkeyi(dpsrc); } else if (strncmp(fp, "AXIS.", 5) == 0) { sscanf(fp+5, "%d", &jhat); axmap[jhat-1] = dpkeyi(dpsrc) - 1; } } for (jhat = 0; jhat < Nhat; jhat++) { if (axmap[jhat] < 0) { axmap[jhat] = jhat; } } // Copy the DPja or DQia keyvalues. dpsrc = dissrc->dp; for (idp = 0; idp < dissrc->ndp; idp++, dpsrc++) { if (dpsrc->j != axes[j]) continue; if (dpsrc->field[1] != pq[m]) continue; if ((fp = strchr(dpsrc->field, '.')) == 0x0) continue; fp++; if (strncmp(fp, "AXIS.", 5) == 0) { // Skip it, we will create our own later. continue; } *dpdst = *dpsrc; sprintf(ctmp, "%d", j+1); dpdst->field[2] = ctmp[0]; dpdst->j = j+1; ndp++; dpdst++; if (strncmp(fp, "NAXES", 6) == 0) { for (jhat = 0; jhat < Nhat; jhat++) { strcpy(dpdst->field, dpsrc->field); dpdst->field[2] = ctmp[0]; fp = strchr(dpdst->field, '.') + 1; sprintf(fp, "AXIS.%d", jhat+1); dpdst->j = j+1; dpdst->type = 0; dpdst->value.i = map[axmap[jhat]]; ndp++; dpdst++; } } } } disdst->ndp = ndp; } } cleanup: if (itmp) free(itmp); if (dealloc) { free(axes); } if (status && wcsdst->m_aux) { free(wcsdst->m_aux); wcsdst->aux = 0x0; wcsdst->m_aux = 0x0; } if (status && wcsdst->m_tab) { free(wcsdst->m_tab); wcsdst->tab = 0x0; wcsdst->m_tab = 0x0; } return status; } //---------------------------------------------------------------------------- int wcscompare( int cmp, double tol, const struct wcsprm *wcs1, const struct wcsprm *wcs2, int *equal) { int i, j, naxis, naxis2; double diff; int tab_equal; int status; if (wcs1 == 0x0) return WCSERR_NULL_POINTER; if (wcs2 == 0x0) return WCSERR_NULL_POINTER; if (equal == 0x0) return WCSERR_NULL_POINTER; *equal = 0; if (wcs1->naxis != wcs2->naxis) { return 0; } naxis = wcs1->naxis; naxis2 = wcs1->naxis*wcs1->naxis; if (cmp & WCSCOMPARE_CRPIX) { // Don't compare crpix. } else if (cmp & WCSCOMPARE_TILING) { for (i = 0; i < naxis; ++i) { diff = wcs1->crpix[i] - wcs2->crpix[i]; if ((double)(int)(diff) != diff) { return 0; } } } else { if (!wcsutil_dblEq(naxis, tol, wcs1->crpix, wcs2->crpix)) { return 0; } } if (!wcsutil_dblEq(naxis2, tol, wcs1->pc, wcs2->pc) || !wcsutil_dblEq(naxis, tol, wcs1->cdelt, wcs2->cdelt) || !wcsutil_dblEq(naxis, tol, wcs1->crval, wcs2->crval) || !wcsutil_strEq(naxis, wcs1->cunit, wcs2->cunit) || !wcsutil_strEq(naxis, wcs1->ctype, wcs2->ctype) || !wcsutil_dblEq(1, tol, &wcs1->lonpole, &wcs2->lonpole) || !wcsutil_dblEq(1, tol, &wcs1->latpole, &wcs2->latpole) || !wcsutil_dblEq(1, tol, &wcs1->restfrq, &wcs2->restfrq) || !wcsutil_dblEq(1, tol, &wcs1->restwav, &wcs2->restwav) || wcs1->npv != wcs2->npv || wcs1->nps != wcs2->nps) { return 0; } // Compare pv cards, which may not be in the same order for (i = 0; i < wcs1->npv; ++i) { for (j = 0; j < wcs2->npv; ++j) { if (wcs1->pv[i].i == wcs2->pv[j].i && wcs1->pv[i].m == wcs2->pv[j].m) { if (!wcsutil_dblEq(1, tol, &wcs1->pv[i].value, &wcs2->pv[j].value)) { return 0; } break; } } // We didn't find a match, so they are not equal if (j == wcs2->npv) { return 0; } } // Compare ps cards, which may not be in the same order for (i = 0; i < wcs1->nps; ++i) { for (j = 0; j < wcs2->nps; ++j) { if (wcs1->ps[i].i == wcs2->ps[j].i && wcs1->ps[i].m == wcs2->ps[j].m) { if (strncmp(wcs1->ps[i].value, wcs2->ps[j].value, 72)) { return 0; } break; } } // We didn't find a match, so they are not equal if (j == wcs2->nps) { return 0; } } if (wcs1->flag != WCSSET || wcs2->flag != WCSSET) { if (!wcsutil_dblEq(naxis2, tol, wcs1->cd, wcs2->cd) || !wcsutil_dblEq(naxis, tol, wcs1->crota, wcs2->crota) || wcs1->altlin != wcs2->altlin || wcs1->velref != wcs2->velref) { return 0; } } if (!(cmp & WCSCOMPARE_ANCILLARY)) { if (strncmp(wcs1->alt, wcs2->alt, 4) || wcs1->colnum != wcs2->colnum || !wcsutil_intEq(naxis, wcs1->colax, wcs2->colax) || !wcsutil_strEq(naxis, wcs1->cname, wcs2->cname) || !wcsutil_dblEq(naxis, tol, wcs1->crder, wcs2->crder) || !wcsutil_dblEq(naxis, tol, wcs1->csyer, wcs2->csyer) || !wcsutil_dblEq(naxis, tol, wcs1->czphs, wcs2->czphs) || !wcsutil_dblEq(naxis, tol, wcs1->cperi, wcs2->cperi) || strncmp(wcs1->wcsname, wcs2->wcsname, 72) || strncmp(wcs1->timesys, wcs2->timesys, 72) || strncmp(wcs1->trefpos, wcs2->trefpos, 72) || strncmp(wcs1->trefdir, wcs2->trefdir, 72) || strncmp(wcs1->plephem, wcs2->plephem, 72) || strncmp(wcs1->timeunit, wcs2->timeunit, 72) || strncmp(wcs1->dateref, wcs2->dateref, 72) || !wcsutil_dblEq(2, tol, wcs1->mjdref, wcs2->mjdref) || !wcsutil_dblEq(1, tol, &wcs1->timeoffs, &wcs2->timeoffs) || strncmp(wcs1->dateobs, wcs2->dateobs, 72) || strncmp(wcs1->datebeg, wcs2->datebeg, 72) || strncmp(wcs1->dateavg, wcs2->dateavg, 72) || strncmp(wcs1->dateend, wcs2->dateend, 72) || !wcsutil_dblEq(1, tol, &wcs1->mjdobs, &wcs2->mjdobs) || !wcsutil_dblEq(1, tol, &wcs1->mjdbeg, &wcs2->mjdbeg) || !wcsutil_dblEq(1, tol, &wcs1->mjdavg, &wcs2->mjdavg) || !wcsutil_dblEq(1, tol, &wcs1->mjdend, &wcs2->mjdend) || !wcsutil_dblEq(1, tol, &wcs1->jepoch, &wcs2->jepoch) || !wcsutil_dblEq(1, tol, &wcs1->bepoch, &wcs2->bepoch) || !wcsutil_dblEq(1, tol, &wcs1->tstart, &wcs2->tstart) || !wcsutil_dblEq(1, tol, &wcs1->tstop, &wcs2->tstop) || !wcsutil_dblEq(1, tol, &wcs1->xposure, &wcs2->xposure) || !wcsutil_dblEq(1, tol, &wcs1->telapse, &wcs2->telapse) || !wcsutil_dblEq(1, tol, &wcs1->timsyer, &wcs2->timsyer) || !wcsutil_dblEq(1, tol, &wcs1->timrder, &wcs2->timrder) || !wcsutil_dblEq(1, tol, &wcs1->timedel, &wcs2->timedel) || !wcsutil_dblEq(1, tol, &wcs1->timepixr, &wcs2->timepixr) || !wcsutil_dblEq(6, tol, wcs1->obsgeo, wcs2->obsgeo) || strncmp(wcs1->obsorbit, wcs2->obsorbit, 72) || strncmp(wcs1->radesys, wcs2->radesys, 72) || !wcsutil_dblEq(1, tol, &wcs1->equinox, &wcs2->equinox) || strncmp(wcs1->specsys, wcs2->specsys, 72) || strncmp(wcs1->ssysobs, wcs2->ssysobs, 72) || !wcsutil_dblEq(1, tol, &wcs1->velosys, &wcs2->velosys) || !wcsutil_dblEq(1, tol, &wcs1->zsource, &wcs2->zsource) || strncmp(wcs1->ssyssrc, wcs2->ssyssrc, 72) || !wcsutil_dblEq(1, tol, &wcs1->velangl, &wcs2->velangl)) { return 0; } // Compare additional auxiliary parameters. if (wcs1->aux && wcs2->aux) { if (!wcsutil_dblEq(1, tol, &wcs1->aux->rsun_ref, &wcs2->aux->rsun_ref) || !wcsutil_dblEq(1, tol, &wcs1->aux->dsun_obs, &wcs2->aux->dsun_obs) || !wcsutil_dblEq(1, tol, &wcs1->aux->crln_obs, &wcs2->aux->crln_obs) || !wcsutil_dblEq(1, tol, &wcs1->aux->hgln_obs, &wcs2->aux->hgln_obs) || !wcsutil_dblEq(1, tol, &wcs1->aux->hglt_obs, &wcs2->aux->hglt_obs)) { return 0; } } else if (wcs1->aux || wcs2->aux) { return 0; } } // Compare tabular parameters if (wcs1->ntab != wcs2->ntab) { return 0; } for (i = 0; i < wcs1->ntab; ++i) { if ((status = tabcmp(0, tol, &wcs1->tab[i], &wcs2->tab[i], &tab_equal))) { return status; } if (!tab_equal) { return 0; } } *equal = 1; return 0; } //---------------------------------------------------------------------------- int wcsfree(struct wcsprm *wcs) { if (wcs == 0x0) return WCSERR_NULL_POINTER; if (wcs->flag == -1) { wcs->lin.flag = -1; } else { // Optionally allocated by wcsinit() for given parameters. if (wcs->m_flag == WCSSET) { // Start by cleaning the slate. if (wcs->crpix == wcs->m_crpix) wcs->crpix = 0x0; if (wcs->pc == wcs->m_pc) wcs->pc = 0x0; if (wcs->cdelt == wcs->m_cdelt) wcs->cdelt = 0x0; if (wcs->crval == wcs->m_crval) wcs->crval = 0x0; if (wcs->cunit == wcs->m_cunit) wcs->cunit = 0x0; if (wcs->ctype == wcs->m_ctype) wcs->ctype = 0x0; if (wcs->pv == wcs->m_pv) wcs->pv = 0x0; if (wcs->ps == wcs->m_ps) wcs->ps = 0x0; if (wcs->cd == wcs->m_cd) wcs->cd = 0x0; if (wcs->crota == wcs->m_crota) wcs->crota = 0x0; if (wcs->colax == wcs->m_colax) wcs->colax = 0x0; if (wcs->cname == wcs->m_cname) wcs->cname = 0x0; if (wcs->crder == wcs->m_crder) wcs->crder = 0x0; if (wcs->csyer == wcs->m_csyer) wcs->csyer = 0x0; if (wcs->czphs == wcs->m_czphs) wcs->czphs = 0x0; if (wcs->cperi == wcs->m_cperi) wcs->cperi = 0x0; if (wcs->aux == wcs->m_aux) wcs->aux = 0x0; if (wcs->tab == wcs->m_tab) wcs->tab = 0x0; if (wcs->wtb == wcs->m_wtb) wcs->wtb = 0x0; // Now release the memory. if (wcs->m_crpix) free(wcs->m_crpix); if (wcs->m_pc) free(wcs->m_pc); if (wcs->m_cdelt) free(wcs->m_cdelt); if (wcs->m_crval) free(wcs->m_crval); if (wcs->m_cunit) free(wcs->m_cunit); if (wcs->m_ctype) free(wcs->m_ctype); if (wcs->m_pv) free(wcs->m_pv); if (wcs->m_ps) free(wcs->m_ps); if (wcs->m_cd) free(wcs->m_cd); if (wcs->m_crota) free(wcs->m_crota); if (wcs->m_colax) free(wcs->m_colax); if (wcs->m_cname) free(wcs->m_cname); if (wcs->m_crder) free(wcs->m_crder); if (wcs->m_csyer) free(wcs->m_csyer); if (wcs->m_czphs) free(wcs->m_czphs); if (wcs->m_cperi) free(wcs->m_cperi); // May have been allocated by wcspih() or wcssub(). if (wcs->m_aux) free(wcs->m_aux); // Allocated unconditionally by wcstab(). if (wcs->m_tab) { for (int itab = 0; itab < wcs->ntab; itab++) { tabfree(wcs->m_tab + itab); } free(wcs->m_tab); } if (wcs->m_wtb) free(wcs->m_wtb); } // Allocated unconditionally by wcsset(). if (wcs->types) free(wcs->types); if (wcs->lin.crpix == wcs->m_crpix) wcs->lin.crpix = 0x0; if (wcs->lin.pc == wcs->m_pc) wcs->lin.pc = 0x0; if (wcs->lin.cdelt == wcs->m_cdelt) wcs->lin.cdelt = 0x0; } wcs->m_flag = 0; wcs->m_naxis = 0x0; wcs->m_crpix = 0x0; wcs->m_pc = 0x0; wcs->m_cdelt = 0x0; wcs->m_crval = 0x0; wcs->m_cunit = 0x0; wcs->m_ctype = 0x0; wcs->m_pv = 0x0; wcs->m_ps = 0x0; wcs->m_cd = 0x0; wcs->m_crota = 0x0; wcs->m_colax = 0x0; wcs->m_cname = 0x0; wcs->m_crder = 0x0; wcs->m_csyer = 0x0; wcs->m_czphs = 0x0; wcs->m_cperi = 0x0; wcs->m_aux = 0x0; wcs->ntab = 0; wcs->m_tab = 0x0; wcs->nwtb = 0; wcs->m_wtb = 0x0; wcs->types = 0x0; wcserr_clear(&(wcs->err)); wcs->flag = 0; linfree(&(wcs->lin)); celfree(&(wcs->cel)); spcfree(&(wcs->spc)); return WCSERR_SUCCESS; } //---------------------------------------------------------------------------- int wcstrim(struct wcsprm *wcs) { if (wcs == 0x0) return WCSERR_NULL_POINTER; if (wcs->m_flag != WCSSET) { // Nothing to do. return WCSERR_SUCCESS; } if (wcs->flag != WCSSET) { return WCSERR_UNSET; } if (wcs->npv < wcs->npvmax) { if (wcs->m_pv) { if (wcs->npv == 0) { free(wcs->m_pv); wcs->pv = wcs->m_pv = 0x0; } else { size_t size = wcs->npv * sizeof(struct pvcard); // No error if realloc() fails, it will leave the array untouched. if ((wcs->pv = wcs->m_pv = realloc(wcs->m_pv, size))) { wcs->npvmax = wcs->npv; } } } } if (wcs->nps < wcs->npsmax) { if (wcs->m_ps) { if (wcs->nps == 0) { free(wcs->m_ps); wcs->ps = wcs->m_ps = 0x0; } else { size_t size = wcs->nps * sizeof(struct pscard); // No error if realloc() fails, it will leave the array untouched. if ((wcs->ps = wcs->m_ps = realloc(wcs->m_ps, size))) { wcs->npsmax = wcs->nps; } } } } if (!(wcs->altlin & 2)) { if (wcs->m_cd) { free(wcs->m_cd); wcs->cd = wcs->m_cd = 0x0; } } if (!(wcs->altlin & 4)) { if (wcs->m_crota) { free(wcs->m_crota); wcs->crota = wcs->m_crota = 0x0; } } if (wcs->colax) { if (wcsutil_all_ival(wcs->naxis, 0, wcs->colax)) { free(wcs->m_colax); wcs->colax = wcs->m_colax = 0x0; } } if (wcs->cname) { if (wcsutil_all_sval(wcs->naxis, "", (const char (*)[72])wcs->cname)) { free(wcs->m_cname); wcs->cname = wcs->m_cname = 0x0; } } if (wcs->crder) { if (wcsutil_all_dval(wcs->naxis, UNDEFINED, wcs->crder)) { free(wcs->m_crder); wcs->crder = wcs->m_crder = 0x0; } } if (wcs->csyer) { if (wcsutil_all_dval(wcs->naxis, UNDEFINED, wcs->csyer)) { free(wcs->m_csyer); wcs->csyer = wcs->m_csyer = 0x0; } } if (wcs->czphs) { if (wcsutil_all_dval(wcs->naxis, UNDEFINED, wcs->czphs)) { free(wcs->m_czphs); wcs->czphs = wcs->m_czphs = 0x0; } } if (wcs->cperi) { if (wcsutil_all_dval(wcs->naxis, UNDEFINED, wcs->cperi)) { free(wcs->m_cperi); wcs->cperi = wcs->m_cperi = 0x0; } } return WCSERR_SUCCESS; } //---------------------------------------------------------------------------- int wcssize(const struct wcsprm *wcs, int sizes[2]) { if (wcs == 0x0) { sizes[0] = sizes[1] = 0; return WCSERR_SUCCESS; } // Base size, in bytes. sizes[0] = sizeof(struct wcsprm); // Total size of allocated memory, in bytes. sizes[1] = 0; int exsizes[2]; int naxis = wcs->naxis; // wcsprm::crpix[]. sizes[1] += naxis * sizeof(double); // wcsprm::pc[]. sizes[1] += naxis*naxis * sizeof(double); // wcsprm::cdelt[]. sizes[1] += naxis * sizeof(double); // wcsprm::crval[]. sizes[1] += naxis * sizeof(double); // wcsprm::cunit[]. if (wcs->cunit) { sizes[1] += naxis * sizeof(char [72]); } // wcsprm::ctype[]. sizes[1] += naxis * sizeof(char [72]); // wcsprm::pv[]. if (wcs->pv) { sizes[1] += wcs->npvmax * sizeof(struct pvcard); } // wcsprm::ps[]. if (wcs->ps) { sizes[1] += wcs->npsmax * sizeof(struct pscard); } // wcsprm::cd[]. if (wcs->cd) { sizes[1] += naxis*naxis * sizeof(double); } // wcsprm::crota[]. if (wcs->crota) { sizes[1] += naxis * sizeof(double); } // wcsprm::colax[]. if (wcs->colax) { sizes[1] += naxis * sizeof(int); } // wcsprm::cname[]. if (wcs->cname) { sizes[1] += naxis * sizeof(char [72]); } // wcsprm::crder[]. if (wcs->crder) { sizes[1] += naxis * sizeof(double); } // wcsprm::csyer[]. if (wcs->csyer) { sizes[1] += naxis * sizeof(double); } // wcsprm::czphs[]. if (wcs->czphs) { sizes[1] += naxis * sizeof(double); } // wcsprm::cperi[]. if (wcs->cperi) { sizes[1] += naxis * sizeof(double); } // wcsprm::aux. if (wcs->aux) { sizes[1] += sizeof(struct auxprm); } // wcsprm::tab. for (int itab = 0; itab < wcs->ntab; itab++) { tabsize(wcs->tab + itab, exsizes); sizes[1] += exsizes[0] + exsizes[1]; } // wcsprm::wtb. if (wcs->wtb) { sizes[1] += wcs->nwtb * sizeof(struct wtbarr); } // wcsprm::lin. linsize(&(wcs->lin), exsizes); sizes[1] += exsizes[1]; // wcsprm::err. wcserr_size(wcs->err, exsizes); sizes[1] += exsizes[0] + exsizes[1]; return WCSERR_SUCCESS; } //---------------------------------------------------------------------------- int auxsize(const struct auxprm *aux, int sizes[2]) { if (aux == 0x0) { sizes[0] = sizes[1] = 0; return WCSERR_SUCCESS; } // Base size, in bytes. sizes[0] = sizeof(struct auxprm); // Total size of allocated memory, in bytes. sizes[1] = 0; return WCSERR_SUCCESS; } //---------------------------------------------------------------------------- static void wcsprt_auxc(const char *name, const char *value) { if (value[0] == '\0') { wcsprintf(" %s: UNDEFINED\n", name); } else { wcsprintf(" %s: \"%s\"\n", name, value); } } static void wcsprt_auxd(const char *name, double value) { if (undefined(value)) { wcsprintf(" %s: UNDEFINED\n", name); } else { wcsprintf(" %s: %15.9f\n", name, value); } } int wcsprt(const struct wcsprm *wcs) { if (wcs == 0x0) return WCSERR_NULL_POINTER; if (wcs->flag != WCSSET) { wcsprintf("The wcsprm struct is UNINITIALIZED.\n"); return WCSERR_SUCCESS; } wcsprintf(" flag: %d\n", wcs->flag); wcsprintf(" naxis: %d\n", wcs->naxis); WCSPRINTF_PTR(" crpix: ", wcs->crpix, "\n"); wcsprintf(" "); for (int i = 0; i < wcs->naxis; i++) { wcsprintf(" %#- 11.5g", wcs->crpix[i]); } wcsprintf("\n"); // Linear transformation. int k = 0; WCSPRINTF_PTR(" pc: ", wcs->pc, "\n"); for (int i = 0; i < wcs->naxis; i++) { wcsprintf(" pc[%d][]:", i); for (int j = 0; j < wcs->naxis; j++) { wcsprintf(" %#- 11.5g", wcs->pc[k++]); } wcsprintf("\n"); } // Coordinate increment at reference point. WCSPRINTF_PTR(" cdelt: ", wcs->cdelt, "\n"); wcsprintf(" "); for (int i = 0; i < wcs->naxis; i++) { wcsprintf(" %#- 11.5g", wcs->cdelt[i]); } wcsprintf("\n"); // Coordinate value at reference point. WCSPRINTF_PTR(" crval: ", wcs->crval, "\n"); wcsprintf(" "); for (int i = 0; i < wcs->naxis; i++) { wcsprintf(" %#- 11.5g", wcs->crval[i]); } wcsprintf("\n"); // Coordinate units and type. WCSPRINTF_PTR(" cunit: ", wcs->cunit, "\n"); for (int i = 0; i < wcs->naxis; i++) { wcsprintf(" \"%s\"\n", wcs->cunit[i]); } WCSPRINTF_PTR(" ctype: ", wcs->ctype, "\n"); for (int i = 0; i < wcs->naxis; i++) { wcsprintf(" \"%s\"\n", wcs->ctype[i]); } // Celestial and spectral transformation parameters. if (undefined(wcs->lonpole)) { wcsprintf(" lonpole: UNDEFINED\n"); } else { wcsprintf(" lonpole: %9f\n", wcs->lonpole); } wcsprintf(" latpole: %9f\n", wcs->latpole); wcsprintf(" restfrq: %f\n", wcs->restfrq); wcsprintf(" restwav: %f\n", wcs->restwav); // Parameter values. wcsprintf(" npv: %d\n", wcs->npv); wcsprintf(" npvmax: %d\n", wcs->npvmax); WCSPRINTF_PTR(" pv: ", wcs->pv, "\n"); for (int k = 0; k < wcs->npv; k++) { wcsprintf(" %3d%4d %#- 11.5g\n", (wcs->pv[k]).i, (wcs->pv[k]).m, (wcs->pv[k]).value); } wcsprintf(" nps: %d\n", wcs->nps); wcsprintf(" npsmax: %d\n", wcs->npsmax); WCSPRINTF_PTR(" ps: ", wcs->ps, "\n"); for (int k = 0; k < wcs->nps; k++) { wcsprintf(" %3d%4d %s\n", (wcs->ps[k]).i, (wcs->ps[k]).m, (wcs->ps[k]).value); } // Alternate linear transformations. k = 0; WCSPRINTF_PTR(" cd: ", wcs->cd, "\n"); if (wcs->cd) { for (int i = 0; i < wcs->naxis; i++) { wcsprintf(" cd[%d][]:", i); for (int j = 0; j < wcs->naxis; j++) { wcsprintf(" %#- 11.5g", wcs->cd[k++]); } wcsprintf("\n"); } } WCSPRINTF_PTR(" crota: ", wcs->crota, "\n"); if (wcs->crota) { wcsprintf(" "); for (int i = 0; i < wcs->naxis; i++) { wcsprintf(" %#- 11.5g", wcs->crota[i]); } wcsprintf("\n"); } wcsprintf(" altlin: %d\n", wcs->altlin); wcsprintf(" velref: %d\n", wcs->velref); // Auxiliary coordinate system information. wcsprintf(" alt: '%c'\n", wcs->alt[0]); wcsprintf(" colnum: %d\n", wcs->colnum); WCSPRINTF_PTR(" colax: ", wcs->colax, "\n"); if (wcs->colax) { wcsprintf(" "); for (int i = 0; i < wcs->naxis; i++) { wcsprintf(" %5d", wcs->colax[i]); } wcsprintf("\n"); } WCSPRINTF_PTR(" cname: ", wcs->cname, "\n"); if (wcs->cname) { for (int i = 0; i < wcs->naxis; i++) { if (wcs->cname[i][0] == '\0') { wcsprintf(" UNDEFINED\n"); } else { wcsprintf(" \"%s\"\n", wcs->cname[i]); } } } WCSPRINTF_PTR(" crder: ", wcs->crder, "\n"); if (wcs->crder) { wcsprintf(" "); for (int i = 0; i < wcs->naxis; i++) { if (undefined(wcs->crder[i])) { wcsprintf(" UNDEFINED"); } else { wcsprintf(" %#- 11.5g", wcs->crder[i]); } } wcsprintf("\n"); } WCSPRINTF_PTR(" csyer: ", wcs->csyer, "\n"); if (wcs->csyer) { wcsprintf(" "); for (int i = 0; i < wcs->naxis; i++) { if (undefined(wcs->csyer[i])) { wcsprintf(" UNDEFINED"); } else { wcsprintf(" %#- 11.5g", wcs->csyer[i]); } } wcsprintf("\n"); } WCSPRINTF_PTR(" czphs: ", wcs->czphs, "\n"); if (wcs->czphs) { wcsprintf(" "); for (int i = 0; i < wcs->naxis; i++) { if (undefined(wcs->czphs[i])) { wcsprintf(" UNDEFINED"); } else { wcsprintf(" %#- 11.5g", wcs->czphs[i]); } } wcsprintf("\n"); } WCSPRINTF_PTR(" cperi: ", wcs->cperi, "\n"); if (wcs->cperi) { wcsprintf(" "); for (int i = 0; i < wcs->naxis; i++) { if (undefined(wcs->cperi[i])) { wcsprintf(" UNDEFINED"); } else { wcsprintf(" %#- 11.5g", wcs->cperi[i]); } } wcsprintf("\n"); } wcsprt_auxc(" wcsname", wcs->wcsname); wcsprt_auxc(" timesys", wcs->timesys); wcsprt_auxc(" trefpos", wcs->trefpos); wcsprt_auxc(" trefdir", wcs->trefdir); wcsprt_auxc(" plephem", wcs->plephem); wcsprt_auxc("timeunit", wcs->timeunit); wcsprt_auxc(" dateref", wcs->dateref); wcsprintf(" mjdref: "); for (int k = 0; k < 2; k++) { if (undefined(wcs->mjdref[k])) { wcsprintf(" UNDEFINED"); } else { wcsprintf(" %15.9f", wcs->mjdref[k]); } } wcsprintf("\n"); wcsprt_auxd("timeoffs", wcs->timeoffs); wcsprt_auxc(" dateobs", wcs->dateobs); wcsprt_auxc(" datebeg", wcs->datebeg); wcsprt_auxc(" dateavg", wcs->dateavg); wcsprt_auxc(" dateend", wcs->dateend); wcsprt_auxd(" mjdobs", wcs->mjdobs); wcsprt_auxd(" mjdbeg", wcs->mjdbeg); wcsprt_auxd(" mjdavg", wcs->mjdavg); wcsprt_auxd(" mjdend", wcs->mjdend); wcsprt_auxd(" jepoch", wcs->jepoch); wcsprt_auxd(" bepoch", wcs->bepoch); wcsprt_auxd(" tstart", wcs->tstart); wcsprt_auxd(" tstop", wcs->tstop); wcsprt_auxd(" xposure", wcs->xposure); wcsprt_auxd(" telapse", wcs->telapse); wcsprt_auxd(" timsyer", wcs->timsyer); wcsprt_auxd(" timrder", wcs->timrder); wcsprt_auxd(" timedel", wcs->timedel); wcsprt_auxd("timepixr", wcs->timepixr); wcsprintf(" obsgeo: "); for (int k = 0; k < 3; k++) { if (undefined(wcs->obsgeo[k])) { wcsprintf(" UNDEFINED"); } else { wcsprintf(" %15.6f", wcs->obsgeo[k]); } } wcsprintf("\n "); for (int k = 3; k < 6; k++) { if (undefined(wcs->obsgeo[k])) { wcsprintf(" UNDEFINED"); } else { wcsprintf(" %15.6f", wcs->obsgeo[k]); } } wcsprintf("\n"); wcsprt_auxc("obsorbit", wcs->obsorbit); wcsprt_auxc(" radesys", wcs->radesys); wcsprt_auxd(" equinox", wcs->equinox); wcsprt_auxc(" specsys", wcs->specsys); wcsprt_auxc(" ssysobs", wcs->ssysobs); wcsprt_auxd(" velosys", wcs->velosys); wcsprt_auxd(" zsource", wcs->zsource); wcsprt_auxc(" ssyssrc", wcs->ssyssrc); wcsprt_auxd(" velangl", wcs->velangl); // Additional auxiliary coordinate system information. WCSPRINTF_PTR(" aux: ", wcs->aux, "\n"); if (wcs->aux) { wcsprt_auxd("rsun_ref", wcs->aux->rsun_ref); wcsprt_auxd("dsun_obs", wcs->aux->dsun_obs); wcsprt_auxd("crln_obs", wcs->aux->crln_obs); wcsprt_auxd("hgln_obs", wcs->aux->hgln_obs); wcsprt_auxd("hglt_obs", wcs->aux->hglt_obs); } wcsprintf(" ntab: %d\n", wcs->ntab); WCSPRINTF_PTR(" tab: ", wcs->tab, ""); if (wcs->tab != 0x0) wcsprintf(" (see below)"); wcsprintf("\n"); wcsprintf(" nwtb: %d\n", wcs->nwtb); WCSPRINTF_PTR(" wtb: ", wcs->wtb, ""); if (wcs->wtb != 0x0) wcsprintf(" (see below)"); wcsprintf("\n"); // Derived values. WCSPRINTF_PTR(" types: ", wcs->types, "\n "); for (int i = 0; i < wcs->naxis; i++) { wcsprintf("%5d", wcs->types[i]); } wcsprintf("\n"); wcsprintf(" lngtyp: \"%s\"\n", wcs->lngtyp); wcsprintf(" lattyp: \"%s\"\n", wcs->lattyp); wcsprintf(" lng: %d\n", wcs->lng); wcsprintf(" lat: %d\n", wcs->lat); wcsprintf(" spec: %d\n", wcs->spec); wcsprintf(" cubeface: %d\n", wcs->cubeface); WCSPRINTF_PTR(" err: ", wcs->err, "\n"); if (wcs->err) { wcserr_prt(wcs->err, " "); } wcsprintf(" lin: (see below)\n"); wcsprintf(" cel: (see below)\n"); wcsprintf(" spc: (see below)\n"); // Memory management. wcsprintf(" m_flag: %d\n", wcs->m_flag); wcsprintf(" m_naxis: %d\n", wcs->m_naxis); WCSPRINTF_PTR(" m_crpix: ", wcs->m_crpix, ""); if (wcs->m_crpix == wcs->crpix) wcsprintf(" (= crpix)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_pc: ", wcs->m_pc, ""); if (wcs->m_pc == wcs->pc) wcsprintf(" (= pc)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_cdelt: ", wcs->m_cdelt, ""); if (wcs->m_cdelt == wcs->cdelt) wcsprintf(" (= cdelt)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_crval: ", wcs->m_crval, ""); if (wcs->m_crval == wcs->crval) wcsprintf(" (= crval)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_cunit: ", wcs->m_cunit, ""); if (wcs->m_cunit == wcs->cunit) wcsprintf(" (= cunit)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_ctype: ", wcs->m_ctype, ""); if (wcs->m_ctype == wcs->ctype) wcsprintf(" (= ctype)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_pv: ", wcs->m_pv, ""); if (wcs->m_pv == wcs->pv) wcsprintf(" (= pv)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_ps: ", wcs->m_ps, ""); if (wcs->m_ps == wcs->ps) wcsprintf(" (= ps)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_cd: ", wcs->m_cd, ""); if (wcs->m_cd == wcs->cd) wcsprintf(" (= cd)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_crota: ", wcs->m_crota, ""); if (wcs->m_crota == wcs->crota) wcsprintf(" (= crota)"); wcsprintf("\n"); wcsprintf("\n"); WCSPRINTF_PTR(" m_colax: ", wcs->m_colax, ""); if (wcs->m_colax == wcs->colax) wcsprintf(" (= colax)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_cname: ", wcs->m_cname, ""); if (wcs->m_cname == wcs->cname) wcsprintf(" (= cname)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_crder: ", wcs->m_crder, ""); if (wcs->m_crder == wcs->crder) wcsprintf(" (= crder)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_csyer: ", wcs->m_csyer, ""); if (wcs->m_csyer == wcs->csyer) wcsprintf(" (= csyer)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_czphs: ", wcs->m_czphs, ""); if (wcs->m_czphs == wcs->czphs) wcsprintf(" (= czphs)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_cperi: ", wcs->m_cperi, ""); if (wcs->m_cperi == wcs->cperi) wcsprintf(" (= cperi)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_aux: ", wcs->m_aux, ""); if (wcs->m_aux == wcs->aux) wcsprintf(" (= aux)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_tab: ", wcs->m_tab, ""); if (wcs->m_tab == wcs->tab) wcsprintf(" (= tab)"); wcsprintf("\n"); WCSPRINTF_PTR(" m_wtb: ", wcs->m_wtb, ""); if (wcs->m_wtb == wcs->wtb) wcsprintf(" (= wtb)"); wcsprintf("\n"); // Tabular transformation parameters. struct wtbarr *wtbp = wcs->wtb; if (wtbp) { for (int iwtb = 0; iwtb < wcs->nwtb; iwtb++, wtbp++) { wcsprintf("\n"); wcsprintf("wtb[%d].*\n", iwtb); wcsprintf(" i: %d\n", wtbp->i); wcsprintf(" m: %d\n", wtbp->m); wcsprintf(" kind: %c\n", wtbp->kind); wcsprintf(" extnam: %s\n", wtbp->extnam); wcsprintf(" extver: %d\n", wtbp->extver); wcsprintf(" extlev: %d\n", wtbp->extlev); wcsprintf(" ttype: %s\n", wtbp->ttype); wcsprintf(" row: %ld\n", wtbp->row); wcsprintf(" ndim: %d\n", wtbp->ndim); WCSPRINTF_PTR(" dimlen: ", wtbp->dimlen, "\n"); WCSPRINTF_PTR(" arrayp: ", wtbp->arrayp, " -> "); WCSPRINTF_PTR("", *(wtbp->arrayp), "\n"); } } if (wcs->tab) { for (int itab = 0; itab < wcs->ntab; itab++) { wcsprintf("\n"); wcsprintf("tab[%d].*\n", itab); tabprt(wcs->tab + itab); } } // Linear transformation parameters. wcsprintf("\n"); wcsprintf(" lin.*\n"); linprt(&(wcs->lin)); // Celestial transformation parameters. wcsprintf("\n"); wcsprintf(" cel.*\n"); celprt(&(wcs->cel)); // Spectral transformation parameters. wcsprintf("\n"); wcsprintf(" spc.*\n"); spcprt(&(wcs->spc)); return WCSERR_SUCCESS; } //---------------------------------------------------------------------------- int wcsperr(const struct wcsprm *wcs, const char *prefix) { if (wcs == 0x0) return WCSERR_NULL_POINTER; if (wcs->err && wcserr_prt(wcs->err, prefix) == 0) { linperr(&(wcs->lin), prefix); celperr(&(wcs->cel), prefix); wcserr_prt(wcs->spc.err, prefix); if (wcs->tab) { for (int itab = 0; itab < wcs->ntab; itab++) { wcserr_prt((wcs->tab + itab)->err, prefix); } } } return WCSERR_SUCCESS; } //---------------------------------------------------------------------------- int wcsbchk(struct wcsprm *wcs, int bounds) { if (wcs == 0x0) return WCSERR_NULL_POINTER; if (wcs->flag != WCSSET) { int status; if ((status = wcsset(wcs))) return status; } wcs->cel.prj.bounds = bounds; return WCSERR_SUCCESS; } //---------------------------------------------------------------------------- int wcsset(struct wcsprm *wcs) { static const char *function = "wcsset"; if (wcs == 0x0) return WCSERR_NULL_POINTER; struct wcserr **err = &(wcs->err); // Determine axis types from CTYPEia. int status; if ((status = wcs_types(wcs))) { return status; } // Convert to canonical units. if ((status = wcs_units(wcs))) { return status; } int naxis = wcs->naxis; if (32 < naxis) { return wcserr_set(WCSERR_SET(WCSERR_BAD_PARAM), "naxis must not exceed 32 (got %d)", naxis); } // Non-linear celestial axes present? if (wcs->lng >= 0 && wcs->types[wcs->lng] == 2200) { struct celprm *wcscel = &(wcs->cel); celini(wcscel); // CRVALia, LONPOLEa, and LATPOLEa keyvalues. wcscel->ref[0] = wcs->crval[wcs->lng]; wcscel->ref[1] = wcs->crval[wcs->lat]; wcscel->ref[2] = wcs->lonpole; wcscel->ref[3] = wcs->latpole; // Do alias translation for TPU/TPV before dealing with PVi_ma. struct prjprm *wcsprj = &(wcscel->prj); strncpy(wcsprj->code, wcs->ctype[wcs->lng]+5, 3); wcsprj->code[3] = '\0'; if (strncmp(wcsprj->code, "TPU", 3) == 0 || strncmp(wcsprj->code, "TPV", 3) == 0) { // Translate the PV parameters. struct disprm *dis; if ((dis = calloc(1, sizeof(struct disprm))) == 0x0) { return wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); } int ndpmax = 6 + wcs->npv; // Attach it to linprm. Also inits it. char dpq[16]; struct linprm *wcslin = &(wcs->lin); dis->flag = -1; if (strncmp(wcsprj->code, "TPU", 3) == 0) { // Prior distortion. lindist(1, wcslin, dis, ndpmax); strcpy(dpq, "DP"); } else { // Sequent distortion. lindist(2, wcslin, dis, ndpmax); strcpy(dpq, "DQ"); } // Yes, the distortion type is "TPV" even for TPU. strcpy(dis->dtype[wcs->lng], "TPV"); strcpy(dis->dtype[wcs->lat], "TPV"); // Keep the keywords in axis-order to aid debugging. struct dpkey *keyp = dis->dp; dis->ndp = 0; sprintf(dpq+2, "%d", wcs->lng+1); dpfill(keyp++, dpq, "NAXES", 0, 0, 2, 0.0); dpfill(keyp++, dpq, "AXIS.1", 0, 0, 1, 0.0); dpfill(keyp++, dpq, "AXIS.2", 0, 0, 2, 0.0); dis->ndp += 3; // Copy distortion parameters for the longitude axis. for (int k = 0; k < wcs->npv; k++) { if (wcs->pv[k].i != wcs->lng+1) continue; sprintf(keyp->field, "%s.TPV.%d", dpq, wcs->pv[k].m); dpfill(keyp++, 0x0, 0x0, 0, 1, 0, wcs->pv[k].value); dis->ndp++; } // Now the latitude axis. sprintf(dpq+2, "%d", wcs->lat+1); dpfill(keyp++, dpq, "NAXES", 0, 0, 2, 0.0); dpfill(keyp++, dpq, "AXIS.1", 0, 0, 2, 0.0); dpfill(keyp++, dpq, "AXIS.2", 0, 0, 1, 0.0); dis->ndp += 3; for (int k = 0; k < wcs->npv; k++) { if (wcs->pv[k].i != wcs->lat+1) continue; sprintf(keyp->field, "%s.TPV.%d", dpq, wcs->pv[k].m); dpfill(keyp++, 0x0, 0x0, 0, 1, 0, wcs->pv[k].value); dis->ndp++; } // Erase PVi_ma associated with the celestial axes. int n = 0; for (int k = 0; k < wcs->npv; k++) { int i = wcs->pv[k].i - 1; if (i == wcs->lng || i == wcs->lat) continue; wcs->pv[n].i = wcs->pv[k].i; wcs->pv[n].m = wcs->pv[k].m; wcs->pv[n].value = wcs->pv[k].value; n++; } wcs->npv = n; strcpy(wcsprj->code, "TAN"); // As the PVi_ma have now been erased, ctype must be reset to prevent // this translation from re-occurring if wcsset() is called again. strcpy(wcs->ctype[wcs->lng]+5, "TAN"); strcpy(wcs->ctype[wcs->lat]+5, "TAN"); } else if (strncmp(wcsprj->code, "TNX", 3) == 0) { // The WAT distortion should already have been encoded in disseq. strcpy(wcsprj->code, "TAN"); strcpy(wcs->ctype[wcs->lng]+5, "TAN"); strcpy(wcs->ctype[wcs->lat]+5, "TAN"); } else if (strncmp(wcsprj->code, "ZPX", 3) == 0) { // The WAT distortion should already have been encoded in disseq. strcpy(wcsprj->code, "ZPN"); strcpy(wcs->ctype[wcs->lng]+5, "ZPN"); strcpy(wcs->ctype[wcs->lat]+5, "ZPN"); } // PVi_ma keyvalues. for (int k = 0; k < wcs->npv; k++) { if (wcs->pv[k].i == 0) { // From a PROJPn keyword. wcs->pv[k].i = wcs->lat + 1; } int i = wcs->pv[k].i - 1; int m = wcs->pv[k].m; if (i == wcs->lat) { // PVi_ma associated with latitude axis. if (m < 30) { wcsprj->pv[m] = wcs->pv[k].value; } } else if (i == wcs->lng) { // PVi_ma associated with longitude axis. switch (m) { case 0: wcscel->offset = (wcs->pv[k].value != 0.0); break; case 1: wcscel->phi0 = wcs->pv[k].value; break; case 2: wcscel->theta0 = wcs->pv[k].value; break; case 3: // If present, overrides LONPOLEa. wcscel->ref[2] = wcs->pv[k].value; break; case 4: // If present, overrides LATPOLEa. wcscel->ref[3] = wcs->pv[k].value; break; default: return wcserr_set(WCSERR_SET(WCSERR_BAD_COORD_TRANS), "PV%i_%i%s: Unrecognized coordinate transformation parameter", i+1, m, wcs->alt); break; } } } // Do simple alias translations. if (strncmp(wcs->ctype[wcs->lng]+5, "GLS", 3) == 0) { wcscel->offset = 1; wcscel->phi0 = 0.0; wcscel->theta0 = wcs->crval[wcs->lat]; strcpy(wcsprj->code, "SFL"); } else if (strncmp(wcs->ctype[wcs->lng]+5, "NCP", 3) == 0) { // Convert NCP to SIN. if (wcscel->ref[1] == 0.0) { return wcserr_set(WCSERR_SET(WCSERR_BAD_PARAM), "Invalid projection: NCP blows up on the equator"); } strcpy(wcsprj->code, "SIN"); wcsprj->pv[1] = 0.0; wcsprj->pv[2] = cosd(wcscel->ref[1])/sind(wcscel->ref[1]); } // Initialize the celestial transformation routines. wcsprj->r0 = 0.0; if ((status = celset(wcscel))) { return wcserr_set(WCS_ERRMSG(wcs_celerr[status])); } // Update LONPOLE, LATPOLE, and PVi_ma keyvalues. wcs->lonpole = wcscel->ref[2]; wcs->latpole = wcscel->ref[3]; for (int k = 0; k < wcs->npv; k++) { int i = wcs->pv[k].i - 1; int m = wcs->pv[k].m; if (i == wcs->lng) { switch (m) { case 1: wcs->pv[k].value = wcscel->phi0; break; case 2: wcs->pv[k].value = wcscel->theta0; break; case 3: wcs->pv[k].value = wcscel->ref[2]; break; case 4: wcs->pv[k].value = wcscel->ref[3]; break; } } } } // Non-linear spectral axis present? if (wcs->spec >= 0 && wcs->types[wcs->spec] == 3300) { char scode[4], stype[5]; struct spcprm *wcsspc = &(wcs->spc); spcini(wcsspc); if ((status = spctype(wcs->ctype[wcs->spec], stype, scode, 0x0, 0x0, 0x0, 0x0, 0x0, err))) { return status; } strcpy(wcsspc->type, stype); strcpy(wcsspc->code, scode); // CRVALia, RESTFRQa, and RESTWAVa keyvalues. wcsspc->crval = wcs->crval[wcs->spec]; wcsspc->restfrq = wcs->restfrq; wcsspc->restwav = wcs->restwav; // PVi_ma keyvalues. for (int k = 0; k < wcs->npv; k++) { int i = wcs->pv[k].i - 1; int m = wcs->pv[k].m; if (i == wcs->spec) { // PVi_ma associated with grism axis. if (m < 7) { wcsspc->pv[m] = wcs->pv[k].value; } } } // Initialize the spectral transformation routines. if ((status = spcset(wcsspc))) { return wcserr_set(WCS_ERRMSG(wcs_spcerr[status])); } } // Tabular axes present? for (int itab = 0; itab < wcs->ntab; itab++) { if ((status = tabset(wcs->tab + itab))) { return wcserr_set(WCS_ERRMSG(wcs_taberr[status])); } } // Initialize the linear transformation. wcs->altlin &= 15; if (wcs->altlin > 1 && !(wcs->altlin & 1)) { double *pc = wcs->pc; if ((wcs->altlin & 2) && !(wcs->altlin & 8)) { // Copy CDi_ja to PCi_ja and reset CDELTia. double *cd = wcs->cd; for (int i = 0; i < naxis; i++) { for (int j = 0; j < naxis; j++) { *(pc++) = *(cd++); } wcs->cdelt[i] = 1.0; } } else if (wcs->altlin & 4) { // Construct PCi_ja from CROTAia. int i, j; if ((i = wcs->lng) >= 0 && (j = wcs->lat) >= 0) { double rho = wcs->crota[j]; if (wcs->cdelt[i] == 0.0) { return wcserr_set(WCSERR_SET(WCSERR_SINGULAR_MTX), "Singular transformation matrix, CDELT%d is zero", i+1); } double lambda = wcs->cdelt[j]/wcs->cdelt[i]; *(pc + i*naxis + i) = *(pc + j*naxis + j) = cosd(rho); *(pc + i*naxis + j) = *(pc + j*naxis + i) = sind(rho); *(pc + i*naxis + j) *= -lambda; *(pc + j*naxis + i) /= lambda; } } } wcs->lin.crpix = wcs->crpix; wcs->lin.pc = wcs->pc; wcs->lin.cdelt = wcs->cdelt; if ((status = linset(&(wcs->lin)))) { return wcserr_set(WCS_ERRMSG(wcs_linerr[status])); } // Set defaults for radesys and equinox for equatorial or ecliptic. if (strcmp(wcs->lngtyp, "RA") == 0 || strcmp(wcs->lngtyp, "ELON") == 0 || strcmp(wcs->lngtyp, "HLON") == 0) { if (wcs->radesys[0] == '\0') { if (undefined(wcs->equinox)) { strcpy(wcs->radesys, "ICRS"); } else if (wcs->equinox < 1984.0) { strcpy(wcs->radesys, "FK4"); } else { strcpy(wcs->radesys, "FK5"); } } else if (strcmp(wcs->radesys, "ICRS") == 0 || strcmp(wcs->radesys, "GAPPT") == 0) { // Equinox is not applicable for these coordinate systems. wcs->equinox = UNDEFINED; } else if (undefined(wcs->equinox)) { if (strcmp(wcs->radesys, "FK5") == 0) { wcs->equinox = 2000.0; } else if (strcmp(wcs->radesys, "FK4") == 0 || strcmp(wcs->radesys, "FK4-NO-E") == 0) { wcs->equinox = 1950.0; } } } else { // No celestial axes, ensure that radesys and equinox are unset. memset(wcs->radesys, 0, 72); wcs->equinox = UNDEFINED; } // Strip off trailing blanks and null-fill auxiliary string members. if (wcs->alt[0] == '\0') wcs->alt[0] = ' '; memset(wcs->alt+1, '\0', 3); for (int i = 0; i < naxis; i++) { wcsutil_null_fill(72, wcs->cname[i]); } wcsutil_null_fill(72, wcs->wcsname); wcsutil_null_fill(72, wcs->timesys); wcsutil_null_fill(72, wcs->trefpos); wcsutil_null_fill(72, wcs->trefdir); wcsutil_null_fill(72, wcs->plephem); wcsutil_null_fill(72, wcs->timeunit); wcsutil_null_fill(72, wcs->dateref); wcsutil_null_fill(72, wcs->dateobs); wcsutil_null_fill(72, wcs->datebeg); wcsutil_null_fill(72, wcs->dateavg); wcsutil_null_fill(72, wcs->dateend); wcsutil_null_fill(72, wcs->obsorbit); wcsutil_null_fill(72, wcs->radesys); wcsutil_null_fill(72, wcs->specsys); wcsutil_null_fill(72, wcs->ssysobs); wcsutil_null_fill(72, wcs->ssyssrc); // MJDREF defaults to zero if no reference date keywords were defined. if (wcs->dateref[0] == '\0') { if (undefined(wcs->mjdref[0])) { wcs->mjdref[0] = 0.0; } if (undefined(wcs->mjdref[1])) { wcs->mjdref[1] = 0.0; } } wcs->flag = WCSSET; return WCSERR_SUCCESS; } // : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : int wcs_types(struct wcsprm *wcs) { static const char *function = "wcs_types"; const int nalias = 6; const char aliases [6][4] = {"NCP", "GLS", "TPU", "TPV", "TNX", "ZPX"}; const char *alt = ""; char ctypei[16], pcode[4], requir[16], scode[4], specsys[9]; int i, j, m, naxis, *ndx = 0x0, type; if (wcs == 0x0) return WCSERR_NULL_POINTER; struct wcserr **err = &(wcs->err); // Parse the CTYPEia keyvalues. pcode[0] = '\0'; requir[0] = '\0'; wcs->lng = -1; wcs->lat = -1; wcs->spec = -1; wcs->cubeface = -1; if (*(wcs->alt) != ' ') alt = wcs->alt; naxis = wcs->naxis; if (wcs->types) free(wcs->types); if ((wcs->types = calloc(naxis, sizeof(int))) == 0x0) { return wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); } for (i = 0; i < naxis; i++) { // Null fill. wcsutil_null_fill(72, wcs->ctype[i]); strncpy(ctypei, wcs->ctype[i], 15); ctypei[15] = '\0'; // Check for early Paper IV syntax (e.g. '-SIP' used by Spitzer). if (strlen(ctypei) == 12 && ctypei[8] == '-') { // Excise the "4-3-3" or "8-3"-form distortion code. ctypei[8] = '\0'; // Remove trailing dashes from "8-3"-form codes. for (j = 7; j > 0; j--) { if (ctypei[j] != '-') break; ctypei[j] = '\0'; } } // Logarithmic or tabular axis? wcs->types[i] = 0; if (strcmp(ctypei+4, "-LOG") == 0) { // Logarithmic axis. wcs->types[i] = 400; } else if (strcmp(ctypei+4, "-TAB") == 0) { // Tabular axis. wcs->types[i] = 500; } if (wcs->types[i]) { // Could have -LOG or -TAB with celestial or spectral types. ctypei[4] = '\0'; // Take care of things like 'FREQ-LOG' or 'RA---TAB'. for (j = 3; j >= 0; j--) { if (ctypei[j] != '-') break; ctypei[j] = '\0'; } } // Translate AIPS spectral types for spctyp(). if (spcaips(ctypei, wcs->velref, ctypei, specsys) == 0) { strcpy(wcs->ctype[i], ctypei); if (wcs->specsys[0] == '\0') strcpy(wcs->specsys, specsys); } // Process linear axes. if (!(strlen(ctypei) == 8 && ctypei[4] == '-')) { // Identify Stokes, celestial and spectral types. if (strcmp(ctypei, "STOKES") == 0) { // STOKES axis. wcs->types[i] = 1100; } else if (strcmp(ctypei, "RA") == 0 || strcmp(ctypei+1, "LON") == 0 || strcmp(ctypei+2, "LN") == 0) { // Longitude axis. wcs->types[i] += 2000; if (wcs->lng < 0) { wcs->lng = i; strcpy(wcs->lngtyp, ctypei); } } else if (strcmp(ctypei, "DEC") == 0 || strcmp(ctypei+1, "LAT") == 0 || strcmp(ctypei+2, "LT") == 0) { // Latitude axis. wcs->types[i] += 2001; if (wcs->lat < 0) { wcs->lat = i; strcpy(wcs->lattyp, ctypei); } } else if (strcmp(ctypei, "CUBEFACE") == 0) { // CUBEFACE axis. if (wcs->cubeface == -1) { wcs->types[i] = 2102; wcs->cubeface = i; } else { // Multiple CUBEFACE axes! return wcserr_set(WCSERR_SET(WCSERR_BAD_CTYPE), "Multiple CUBEFACE axes (in CTYPE%d%.1s and CTYPE%d%.1s)", wcs->cubeface+1, alt, i+1, alt); } } else if (spctyp(ctypei, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0) == 0) { // Spectral axis. if (wcs->spec < 0) wcs->spec = i; wcs->types[i] += 3000; } continue; } // CTYPEia is in "4-3" form; is it a recognized spectral type? if (spctyp(ctypei, 0x0, scode, 0x0, 0x0, 0x0, 0x0, 0x0) == 0) { // Non-linear spectral axis found. wcs->types[i] = 3300; // Check uniqueness. if (wcs->spec >= 0) { return wcserr_set(WCSERR_SET(WCSERR_BAD_CTYPE), "Multiple spectral axes (in CTYPE%d%.1s and CTYPE%d%.1s)", wcs->spec+1, alt, i+1, alt); } wcs->spec = i; continue; } // Is it a recognized celestial projection? for (j = 0; j < prj_ncode; j++) { if (strncmp(ctypei+5, prj_codes[j], 3) == 0) break; } if (j == prj_ncode) { // Not a standard projection code, maybe it's an alias. for (j = 0; j < nalias; j++) { if (strncmp(ctypei+5, aliases[j], 3) == 0) break; } if (j == nalias) { // Not a recognized algorithm code of any type. wcs->types[i] = -1; return wcserr_set(WCSERR_SET(WCSERR_BAD_CTYPE), "Unrecognized projection code (%s in CTYPE%d%.1s)", ctypei+5, i+1, alt); } } // Parse the celestial axis type. wcs->types[i] = 2200; if (*pcode == '\0') { // The first of the two celestial axes. sprintf(pcode, "%.3s", ctypei+5); if (strncmp(ctypei, "RA--", 4) == 0) { wcs->lng = i; strcpy(wcs->lngtyp, "RA"); strcpy(wcs->lattyp, "DEC"); ndx = &wcs->lat; sprintf(requir, "DEC--%s", pcode); } else if (strncmp(ctypei, "DEC-", 4) == 0) { wcs->lat = i; strcpy(wcs->lngtyp, "RA"); strcpy(wcs->lattyp, "DEC"); ndx = &wcs->lng; sprintf(requir, "RA---%s", pcode); } else if (strncmp(ctypei+1, "LON", 3) == 0) { wcs->lng = i; sprintf(wcs->lngtyp, "%cLON", ctypei[0]); sprintf(wcs->lattyp, "%cLAT", ctypei[0]); ndx = &wcs->lat; sprintf(requir, "%s-%s", wcs->lattyp, pcode); } else if (strncmp(ctypei+1, "LAT", 3) == 0) { wcs->lat = i; sprintf(wcs->lngtyp, "%cLON", ctypei[0]); sprintf(wcs->lattyp, "%cLAT", ctypei[0]); ndx = &wcs->lng; sprintf(requir, "%s-%s", wcs->lngtyp, pcode); } else if (strncmp(ctypei+2, "LN", 2) == 0) { wcs->lng = i; sprintf(wcs->lngtyp, "%c%cLN", ctypei[0], ctypei[1]); sprintf(wcs->lattyp, "%c%cLT", ctypei[0], ctypei[1]); ndx = &wcs->lat; sprintf(requir, "%s-%s", wcs->lattyp, pcode); } else if (strncmp(ctypei+2, "LT", 2) == 0) { wcs->lat = i; sprintf(wcs->lngtyp, "%c%cLN", ctypei[0], ctypei[1]); sprintf(wcs->lattyp, "%c%cLT", ctypei[0], ctypei[1]); ndx = &wcs->lng; sprintf(requir, "%s-%s", wcs->lngtyp, pcode); } else { // Unrecognized celestial type. wcs->types[i] = -1; wcs->lng = -1; wcs->lat = -1; return wcserr_set(WCSERR_SET(WCSERR_BAD_CTYPE), "Unrecognized celestial type (%5s in CTYPE%d%.1s)", ctypei, i+1, alt); } if (wcs->lat >= 0) wcs->types[i]++; } else { // Looking for the complementary celestial axis. if (wcs->lat < 0) wcs->types[i]++; if (strncmp(ctypei, requir, 8) != 0) { // Inconsistent projection types. wcs->lng = -1; wcs->lat = -1; return wcserr_set(WCSERR_SET(WCSERR_BAD_CTYPE), "Inconsistent " "projection types (expected %s, got %s in CTYPE%d%.1s)", requir, ctypei, i+1, alt); } *ndx = i; requir[0] = '\0'; } } // Do we have a complementary pair of celestial axes? if (strcmp(requir, "")) { // Unmatched celestial axis. wcs->lng = -1; wcs->lat = -1; return wcserr_set(WCSERR_SET(WCSERR_BAD_CTYPE), "Unmatched celestial axes"); } // Table group numbers. for (j = 0; j < wcs->ntab; j++) { for (m = 0; m < wcs->tab[j].M; m++) { // Get image axis number. i = wcs->tab[j].map[m]; type = (wcs->types[i] / 100) % 10; if (type != 5) { return wcserr_set(WCSERR_SET(WCSERR_BAD_CTYPE), "Table parameters set for non-table axis type"); } wcs->types[i] += 10 * j; } } return WCSERR_SUCCESS; } // : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : int wcs_units(struct wcsprm *wcs) { static const char *function = "wcs_units"; char ctype[9], units[16]; int i, j, naxis; double scale, offset, power; struct wcserr *uniterr = 0x0, **err; if (wcs == 0x0) return WCSERR_NULL_POINTER; err = &(wcs->err); naxis = wcs->naxis; for (i = 0; i < naxis; i++) { // Squeeze out trailing blanks. wcsutil_null_fill(72, wcs->cunit[i]); // Use types set by wcs_types(). switch (wcs->types[i]/1000) { case 2: // Celestial axis. strcpy(units, "deg"); break; case 3: // Spectral axis. strncpy(ctype, wcs->ctype[i], 8); ctype[8] = '\0'; spctyp(ctype, 0x0, 0x0, 0x0, units, 0x0, 0x0, 0x0); break; default: continue; } // Tabular axis, CDELTia and CRVALia relate to indices. if ((wcs->types[i]/100)%10 == 5) { continue; } if (wcs->cunit[i][0]) { if (wcsunitse(wcs->cunit[i], units, &scale, &offset, &power, &uniterr)) { if (uniterr) { // uniterr will not be set if wcserr is not enabled. wcserr_set(WCSERR_SET(WCSERR_BAD_COORD_TRANS), "In CUNIT%d%.1s: %s", i+1, (*wcs->alt)?wcs->alt:"", uniterr->msg); free(uniterr); } return WCSERR_BAD_COORD_TRANS; } if (scale != 1.0) { wcs->cdelt[i] *= scale; wcs->crval[i] *= scale; for (j = 0; j < naxis; j++) { *(wcs->cd + i*naxis + j) *= scale; } strcpy(wcs->cunit[i], units); } } else { strcpy(wcs->cunit[i], units); } } return WCSERR_SUCCESS; } //---------------------------------------------------------------------------- int wcsp2s( struct wcsprm *wcs, int ncoord, int nelem, const double pixcrd[], double imgcrd[], double phi[], double theta[], double world[], int stat[]) { static const char *function = "wcsp2s"; int bits, face, i, iso_x, iso_y, istat, *istatp, itab, k, m, nx, ny, *statp, status, type; double crvali, offset; register double *img, *wrl; struct celprm *wcscel = &(wcs->cel); struct prjprm *wcsprj = &(wcscel->prj); struct wcserr **err; // Initialize if required. if (wcs == 0x0) return WCSERR_NULL_POINTER; err = &(wcs->err); if (wcs->flag != WCSSET) { if ((status = wcsset(wcs))) return status; } // Sanity check. if (ncoord < 1 || (ncoord > 1 && nelem < wcs->naxis)) { return wcserr_set(WCSERR_SET(WCSERR_BAD_CTYPE), "ncoord and/or nelem inconsistent with the wcsprm"); } // Apply pixel-to-world linear transformation. if ((status = linp2x(&(wcs->lin), ncoord, nelem, pixcrd, imgcrd))) { return wcserr_set(WCS_ERRMSG(wcs_linerr[status])); } // Initialize status vectors. if ((istatp = calloc(ncoord, sizeof(int))) == 0x0) { return wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); } stat[0] = 0; wcsutil_setAli(ncoord, 1, stat); // Convert intermediate world coordinates to world coordinates. for (i = 0; i < wcs->naxis; i++) { // Extract the second digit of the axis type code. type = (wcs->types[i] / 100) % 10; if (type <= 1) { // Linear or quantized coordinate axis. img = imgcrd + i; wrl = world + i; crvali = wcs->crval[i]; for (k = 0; k < ncoord; k++) { *wrl = *img + crvali; img += nelem; wrl += nelem; } } else if (wcs->types[i] == 2200) { // Convert celestial coordinates; do we have a CUBEFACE axis? if (wcs->cubeface != -1) { // Separation between faces. if (wcsprj->r0 == 0.0) { offset = 90.0; } else { offset = wcsprj->r0*PI/2.0; } // Lay out faces in a plane. img = imgcrd; statp = stat; bits = (1 << i) | (1 << wcs->lat); for (k = 0; k < ncoord; k++, statp++) { face = (int)(*(img+wcs->cubeface) + 0.5); if (fabs(*(img+wcs->cubeface) - face) > 1e-10) { *statp |= bits; status = wcserr_set(WCS_ERRMSG(WCSERR_BAD_PIX)); } else { *statp = 0; switch (face) { case 0: *(img+wcs->lat) += offset; break; case 1: break; case 2: *(img+i) += offset; break; case 3: *(img+i) += offset*2; break; case 4: *(img+i) += offset*3; break; case 5: *(img+wcs->lat) -= offset; break; default: *statp |= bits; status = wcserr_set(WCS_ERRMSG(WCSERR_BAD_PIX)); } } img += nelem; } } // Check for constant x and/or y. nx = ncoord; ny = 0; if ((iso_x = wcsutil_allEq(ncoord, nelem, imgcrd+i))) { nx = 1; ny = ncoord; } if ((iso_y = wcsutil_allEq(ncoord, nelem, imgcrd+wcs->lat))) { ny = 1; } // Transform projection plane coordinates to celestial coordinates. if ((istat = celx2s(wcscel, nx, ny, nelem, nelem, imgcrd+i, imgcrd+wcs->lat, phi, theta, world+i, world+wcs->lat, istatp))) { if (istat) { status = wcserr_set(WCS_ERRMSG(wcs_celerr[istat])); if (status != WCSERR_BAD_PIX) { goto cleanup; } } } // If x and y were both constant, replicate values. if (iso_x && iso_y) { wcsutil_setAll(ncoord, nelem, world+i); wcsutil_setAll(ncoord, nelem, world+wcs->lat); wcsutil_setAll(ncoord, 1, phi); wcsutil_setAll(ncoord, 1, theta); wcsutil_setAli(ncoord, 1, istatp); } if (istat == 5) { bits = (1 << i) | (1 << wcs->lat); wcsutil_setBit(ncoord, istatp, bits, stat); } } else if (type == 3 || type == 4) { // Check for constant x. nx = ncoord; if ((iso_x = wcsutil_allEq(ncoord, nelem, imgcrd+i))) { nx = 1; } istat = 0; if (wcs->types[i] == 3300) { // Spectral coordinates. istat = spcx2s(&(wcs->spc), nx, nelem, nelem, imgcrd+i, world+i, istatp); if (istat) { status = wcserr_set(WCS_ERRMSG(wcs_spcerr[istat])); if (status != WCSERR_BAD_PIX) { goto cleanup; } } } else if (type == 4) { // Logarithmic coordinates. istat = logx2s(wcs->crval[i], nx, nelem, nelem, imgcrd+i, world+i, istatp); if (istat) { status = wcserr_set(WCS_ERRMSG(wcs_logerr[istat])); if (status != WCSERR_BAD_PIX) { goto cleanup; } } } // If x was constant, replicate values. if (iso_x) { wcsutil_setAll(ncoord, nelem, world+i); wcsutil_setAli(ncoord, 1, istatp); } if (istat == 3) { wcsutil_setBit(ncoord, istatp, 1 << i, stat); } } } // Do tabular coordinates. for (itab = 0; itab < wcs->ntab; itab++) { istat = tabx2s(wcs->tab + itab, ncoord, nelem, imgcrd, world, istatp); if (istat) { status = wcserr_set(WCS_ERRMSG(wcs_taberr[istat])); if (status != WCSERR_BAD_PIX) { goto cleanup; } else { bits = 0; for (m = 0; m < wcs->tab[itab].M; m++) { bits |= 1 << wcs->tab[itab].map[m]; } wcsutil_setBit(ncoord, istatp, bits, stat); } } } // Zero the unused world coordinate elements. for (i = wcs->naxis; i < nelem; i++) { world[i] = 0.0; wcsutil_setAll(ncoord, nelem, world+i); } cleanup: free(istatp); return status; } //---------------------------------------------------------------------------- int wcss2p( struct wcsprm* wcs, int ncoord, int nelem, const double world[], double phi[], double theta[], double imgcrd[], double pixcrd[], int stat[]) { static const char *function = "wcss2p"; int bits, i, isolat, isolng, isospec, istat, *istatp, itab, k, m, nlat, nlng, nwrld, status, type; double crvali, offset; register const double *wrl; register double *img; struct celprm *wcscel = &(wcs->cel); struct prjprm *wcsprj = &(wcscel->prj); struct wcserr **err; // Initialize if required. if (wcs == 0x0) return WCSERR_NULL_POINTER; err = &(wcs->err); if (wcs->flag != WCSSET) { if ((status = wcsset(wcs))) return status; } // Sanity check. if (ncoord < 1 || (ncoord > 1 && nelem < wcs->naxis)) { return wcserr_set(WCSERR_SET(WCSERR_BAD_CTYPE), "ncoord and/or nelem inconsistent with the wcsprm"); } // Initialize status vectors. if ((istatp = calloc(ncoord, sizeof(int))) == 0x0) { return wcserr_set(WCS_ERRMSG(WCSERR_MEMORY)); } status = 0; stat[0] = 0; wcsutil_setAli(ncoord, 1, stat); // Convert world coordinates to intermediate world coordinates. for (i = 0; i < wcs->naxis; i++) { // Extract the second digit of the axis type code. type = (wcs->types[i] / 100) % 10; if (type <= 1) { // Linear or quantized coordinate axis. wrl = world + i; img = imgcrd + i; crvali = wcs->crval[i]; for (k = 0; k < ncoord; k++) { *img = *wrl - crvali; wrl += nelem; img += nelem; } } else if (wcs->types[i] == 2200) { // Celestial coordinates; check for constant lng and/or lat. nlng = ncoord; nlat = 0; if ((isolng = wcsutil_allEq(ncoord, nelem, world+i))) { nlng = 1; nlat = ncoord; } if ((isolat = wcsutil_allEq(ncoord, nelem, world+wcs->lat))) { nlat = 1; } // Transform celestial coordinates to projection plane coordinates. if ((istat = cels2x(wcscel, nlng, nlat, nelem, nelem, world+i, world+wcs->lat, phi, theta, imgcrd+i, imgcrd+wcs->lat, istatp))) { if (istat) { status = wcserr_set(WCS_ERRMSG(wcs_celerr[istat])); if (status != WCSERR_BAD_WORLD) { goto cleanup; } } } // If lng and lat were both constant, replicate values. if (isolng && isolat) { wcsutil_setAll(ncoord, nelem, imgcrd+i); wcsutil_setAll(ncoord, nelem, imgcrd+wcs->lat); wcsutil_setAll(ncoord, 1, phi); wcsutil_setAll(ncoord, 1, theta); wcsutil_setAli(ncoord, 1, istatp); } if (istat == CELERR_BAD_WORLD) { bits = (1 << i) | (1 << wcs->lat); wcsutil_setBit(ncoord, istatp, bits, stat); } // Do we have a CUBEFACE axis? if (wcs->cubeface != -1) { // Separation between faces. if (wcsprj->r0 == 0.0) { offset = 90.0; } else { offset = wcsprj->r0*PI/2.0; } // Stack faces in a cube. img = imgcrd; for (k = 0; k < ncoord; k++) { if (*(img+wcs->lat) < -0.5*offset) { *(img+wcs->lat) += offset; *(img+wcs->cubeface) = 5.0; } else if (*(img+wcs->lat) > 0.5*offset) { *(img+wcs->lat) -= offset; *(img+wcs->cubeface) = 0.0; } else if (*(img+i) > 2.5*offset) { *(img+i) -= 3.0*offset; *(img+wcs->cubeface) = 4.0; } else if (*(img+i) > 1.5*offset) { *(img+i) -= 2.0*offset; *(img+wcs->cubeface) = 3.0; } else if (*(img+i) > 0.5*offset) { *(img+i) -= offset; *(img+wcs->cubeface) = 2.0; } else { *(img+wcs->cubeface) = 1.0; } img += nelem; } } } else if (type == 3 || type == 4) { // Check for constancy. nwrld = ncoord; if ((isospec = wcsutil_allEq(ncoord, nelem, world+i))) { nwrld = 1; } istat = 0; if (wcs->types[i] == 3300) { // Spectral coordinates. istat = spcs2x(&(wcs->spc), nwrld, nelem, nelem, world+i, imgcrd+i, istatp); if (istat) { status = wcserr_set(WCS_ERRMSG(wcs_spcerr[istat])); if (status != WCSERR_BAD_WORLD) { goto cleanup; } } } else if (type == 4) { // Logarithmic coordinates. istat = logs2x(wcs->crval[i], nwrld, nelem, nelem, world+i, imgcrd+i, istatp); if (istat) { status = wcserr_set(WCS_ERRMSG(wcs_logerr[istat])); if (status != WCSERR_BAD_WORLD) { goto cleanup; } } } // If constant, replicate values. if (isospec) { wcsutil_setAll(ncoord, nelem, imgcrd+i); wcsutil_setAli(ncoord, 1, istatp); } if (istat == 4) { wcsutil_setBit(ncoord, istatp, 1 << i, stat); } } } // Do tabular coordinates. for (itab = 0; itab < wcs->ntab; itab++) { istat = tabs2x(wcs->tab + itab, ncoord, nelem, world, imgcrd, istatp); if (istat) { status = wcserr_set(WCS_ERRMSG(wcs_taberr[istat])); if (status == WCSERR_BAD_WORLD) { bits = 0; for (m = 0; m < wcs->tab[itab].M; m++) { bits |= 1 << wcs->tab[itab].map[m]; } wcsutil_setBit(ncoord, istatp, bits, stat); } else { goto cleanup; } } } // Zero the unused intermediate world coordinate elements. for (i = wcs->naxis; i < nelem; i++) { imgcrd[i] = 0.0; wcsutil_setAll(ncoord, nelem, imgcrd+i); } // Apply world-to-pixel linear transformation. if ((istat = linx2p(&(wcs->lin), ncoord, nelem, imgcrd, pixcrd))) { status = wcserr_set(WCS_ERRMSG(wcs_linerr[istat])); goto cleanup; } cleanup: free(istatp); return status; } //---------------------------------------------------------------------------- int wcsmix( struct wcsprm *wcs, int mixpix, int mixcel, const double vspan[2], double vstep, int viter, double world[], double phi[], double theta[], double imgcrd[], double pixcrd[]) { static const char *function = "wcsmix"; const int niter = 60; int crossed, istep, iter, j, k, nstep, retry, stat[1], status; const double tol = 1.0e-10; const double tol2 = 100.0*tol; double *worldlat, *worldlng; double lambda, span[2], step; double pixmix; double dlng, lng, lng0, lng0m, lng1, lng1m; double dlat, lat, lat0, lat0m, lat1, lat1m; double d, d0, d0m, d1, d1m, dx = 0.0; double dabs, dmin, lmin; double dphi, phi0, phi1; struct celprm *wcscel = &(wcs->cel); struct wcsprm wcs0; struct wcserr **err; // Initialize if required. if (wcs == 0x0) return WCSERR_NULL_POINTER; err = &(wcs->err); if (wcs->flag != WCSSET) { if ((status = wcsset(wcs))) return status; } if (wcs->lng < 0 || wcs->lat < 0) { return wcserr_set(WCSERR_SET(WCSERR_BAD_SUBIMAGE), "Image does not have celestial axes"); } worldlng = world + wcs->lng; worldlat = world + wcs->lat; // Check vspan. if (vspan[0] <= vspan[1]) { span[0] = vspan[0]; span[1] = vspan[1]; } else { // Swap them. span[0] = vspan[1]; span[1] = vspan[0]; } // Check vstep. step = fabs(vstep); if (step == 0.0) { step = (span[1] - span[0])/10.0; if (step > 1.0 || step == 0.0) step = 1.0; } // Check viter. nstep = viter; if (nstep < 5) { nstep = 5; } else if (nstep > 10) { nstep = 10; } // Given pixel element. pixmix = pixcrd[mixpix]; // Iterate on the step size. for (istep = 0; istep <= nstep; istep++) { if (istep) step /= 2.0; // Iterate on the sky coordinate between the specified range. if (mixcel == 1) { // Celestial longitude is given. // Check whether the solution interval is a crossing interval. lat0 = span[0]; *worldlat = lat0; if ((status = wcss2p(wcs, 1, 0, world, phi, theta, imgcrd, pixcrd, stat))) { if (status == WCSERR_BAD_WORLD) { status = wcserr_set(WCS_ERRMSG(WCSERR_BAD_WORLD_COORD)); } return status; } d0 = pixcrd[mixpix] - pixmix; dabs = fabs(d0); if (dabs < tol) return WCSERR_SUCCESS; lat1 = span[1]; *worldlat = lat1; if ((status = wcss2p(wcs, 1, 0, world, phi, theta, imgcrd, pixcrd, stat))) { if (status == WCSERR_BAD_WORLD) { status = wcserr_set(WCS_ERRMSG(WCSERR_BAD_WORLD_COORD)); } return status; } d1 = pixcrd[mixpix] - pixmix; dabs = fabs(d1); if (dabs < tol) return WCSERR_SUCCESS; lmin = lat1; dmin = dabs; // Check for a crossing point. if (signbit(d0) != signbit(d1)) { crossed = 1; dx = d1; } else { crossed = 0; lat0 = span[1]; } for (retry = 0; retry < 4; retry++) { // Refine the solution interval. while (lat0 > span[0]) { lat0 -= step; if (lat0 < span[0]) lat0 = span[0]; *worldlat = lat0; if ((status = wcss2p(wcs, 1, 0, world, phi, theta, imgcrd, pixcrd, stat))) { if (status == WCSERR_BAD_WORLD) { status = wcserr_set(WCS_ERRMSG(WCSERR_BAD_WORLD_COORD)); } return status; } d0 = pixcrd[mixpix] - pixmix; // Check for a solution. dabs = fabs(d0); if (dabs < tol) return WCSERR_SUCCESS; // Record the point of closest approach. if (dabs < dmin) { lmin = lat0; dmin = dabs; } // Check for a crossing point. if (signbit(d0) != signbit(d1)) { crossed = 2; dx = d0; break; } // Advance to the next subinterval. lat1 = lat0; d1 = d0; } if (crossed) { // A crossing point was found. for (iter = 0; iter < niter; iter++) { // Use regula falsi division of the interval. lambda = d0/(d0-d1); if (lambda < 0.1) { lambda = 0.1; } else if (lambda > 0.9) { lambda = 0.9; } dlat = lat1 - lat0; lat = lat0 + lambda*dlat; *worldlat = lat; if ((status = wcss2p(wcs, 1, 0, world, phi, theta, imgcrd, pixcrd, stat))) { if (status == WCSERR_BAD_WORLD) { status = wcserr_set(WCS_ERRMSG(WCSERR_BAD_WORLD_COORD)); } return status; } // Check for a solution. d = pixcrd[mixpix] - pixmix; dabs = fabs(d); if (dabs < tol) return WCSERR_SUCCESS; if (dlat < tol) { // An artifact of numerical imprecision. if (dabs < tol2) return WCSERR_SUCCESS; // Must be a discontinuity. break; } // Record the point of closest approach. if (dabs < dmin) { lmin = lat; dmin = dabs; } if (signbit(d0) == signbit(d)) { lat0 = lat; d0 = d; } else { lat1 = lat; d1 = d; } } // No convergence, must have been a discontinuity. if (crossed == 1) lat0 = span[1]; lat1 = lat0; d1 = dx; crossed = 0; } else { // No crossing point; look for a tangent point. if (lmin == span[0]) break; if (lmin == span[1]) break; lat = lmin; lat0 = lat - step; if (lat0 < span[0]) lat0 = span[0]; lat1 = lat + step; if (lat1 > span[1]) lat1 = span[1]; *worldlat = lat0; if ((status = wcss2p(wcs, 1, 0, world, phi, theta, imgcrd, pixcrd, stat))) { if (status == WCSERR_BAD_WORLD) { status = wcserr_set(WCS_ERRMSG(WCSERR_BAD_WORLD_COORD)); } return status; } d0 = fabs(pixcrd[mixpix] - pixmix); d = dmin; *worldlat = lat1; if ((status = wcss2p(wcs, 1, 0, world, phi, theta, imgcrd, pixcrd, stat))) { if (status == WCSERR_BAD_WORLD) { status = wcserr_set(WCS_ERRMSG(WCSERR_BAD_WORLD_COORD)); } return status; } d1 = fabs(pixcrd[mixpix] - pixmix); for (iter = 0; iter < niter; iter++) { lat0m = (lat0 + lat)/2.0; *worldlat = lat0m; if ((status = wcss2p(wcs, 1, 0, world, phi, theta, imgcrd, pixcrd, stat))) { if (status == WCSERR_BAD_WORLD) { status = wcserr_set(WCS_ERRMSG(WCSERR_BAD_WORLD_COORD)); } return status; } d0m = fabs(pixcrd[mixpix] - pixmix); if (d0m < tol) return WCSERR_SUCCESS; lat1m = (lat1 + lat)/2.0; *worldlat = lat1m; if ((status = wcss2p(wcs, 1, 0, world, phi, theta, imgcrd, pixcrd, stat))) { if (status == WCSERR_BAD_WORLD) { status = wcserr_set(WCS_ERRMSG(WCSERR_BAD_WORLD_COORD)); } return status; } d1m = fabs(pixcrd[mixpix] - pixmix); if (d1m < tol) return WCSERR_SUCCESS; if (d0m < d && d0m <= d1m) { lat1 = lat; d1 = d; lat = lat0m; d = d0m; } else if (d1m < d) { lat0 = lat; d0 = d; lat = lat1m; d = d1m; } else { lat0 = lat0m; d0 = d0m; lat1 = lat1m; d1 = d1m; } } } } } else { // Celestial latitude is given. // Check whether the solution interval is a crossing interval. lng0 = span[0]; *worldlng = lng0; if ((status = wcss2p(wcs, 1, 0, world, phi, theta, imgcrd, pixcrd, stat))) { if (status == WCSERR_BAD_WORLD) { status = wcserr_set(WCS_ERRMSG(WCSERR_BAD_WORLD_COORD)); } return status; } d0 = pixcrd[mixpix] - pixmix; dabs = fabs(d0); if (dabs < tol) return WCSERR_SUCCESS; lng1 = span[1]; *worldlng = lng1; if ((status = wcss2p(wcs, 1, 0, world, phi, theta, imgcrd, pixcrd, stat))) { if (status == WCSERR_BAD_WORLD) { status = wcserr_set(WCS_ERRMSG(WCSERR_BAD_WORLD_COORD)); } return status; } d1 = pixcrd[mixpix] - pixmix; dabs = fabs(d1); if (dabs < tol) return WCSERR_SUCCESS; lmin = lng1; dmin = dabs; // Check for a crossing point. if (signbit(d0) != signbit(d1)) { crossed = 1; dx = d1; } else { crossed = 0; lng0 = span[1]; } for (retry = 0; retry < 4; retry++) { // Refine the solution interval. while (lng0 > span[0]) { lng0 -= step; if (lng0 < span[0]) lng0 = span[0]; *worldlng = lng0; if ((status = wcss2p(wcs, 1, 0, world, phi, theta, imgcrd, pixcrd, stat))) { if (status == WCSERR_BAD_WORLD) { status = wcserr_set(WCS_ERRMSG(WCSERR_BAD_WORLD_COORD)); } return status; } d0 = pixcrd[mixpix] - pixmix; // Check for a solution. dabs = fabs(d0); if (dabs < tol) return WCSERR_SUCCESS; // Record the point of closest approach. if (dabs < dmin) { lmin = lng0; dmin = dabs; } // Check for a crossing point. if (signbit(d0) != signbit(d1)) { crossed = 2; dx = d0; break; } // Advance to the next subinterval. lng1 = lng0; d1 = d0; } if (crossed) { // A crossing point was found. for (iter = 0; iter < niter; iter++) { // Use regula falsi division of the interval. lambda = d0/(d0-d1); if (lambda < 0.1) { lambda = 0.1; } else if (lambda > 0.9) { lambda = 0.9; } dlng = lng1 - lng0; lng = lng0 + lambda*dlng; *worldlng = lng; if ((status = wcss2p(wcs, 1, 0, world, phi, theta, imgcrd, pixcrd, stat))) { if (status == WCSERR_BAD_WORLD) { status = wcserr_set(WCS_ERRMSG(WCSERR_BAD_WORLD_COORD)); } return status; } // Check for a solution. d = pixcrd[mixpix] - pixmix; dabs = fabs(d); if (dabs < tol) return WCSERR_SUCCESS; if (dlng < tol) { // An artifact of numerical imprecision. if (dabs < tol2) return WCSERR_SUCCESS; // Must be a discontinuity. break; } // Record the point of closest approach. if (dabs < dmin) { lmin = lng; dmin = dabs; } if (signbit(d0) == signbit(d)) { lng0 = lng; d0 = d; } else { lng1 = lng; d1 = d; } } // No convergence, must have been a discontinuity. if (crossed == 1) lng0 = span[1]; lng1 = lng0; d1 = dx; crossed = 0; } else { // No crossing point; look for a tangent point. if (lmin == span[0]) break; if (lmin == span[1]) break; lng = lmin; lng0 = lng - step; if (lng0 < span[0]) lng0 = span[0]; lng1 = lng + step; if (lng1 > span[1]) lng1 = span[1]; *worldlng = lng0; if ((status = wcss2p(wcs, 1, 0, world, phi, theta, imgcrd, pixcrd, stat))) { if (status == WCSERR_BAD_WORLD) { status = wcserr_set(WCS_ERRMSG(WCSERR_BAD_WORLD_COORD)); } return status; } d0 = fabs(pixcrd[mixpix] - pixmix); d = dmin; *worldlng = lng1; if ((status = wcss2p(wcs, 1, 0, world, phi, theta, imgcrd, pixcrd, stat))) { if (status == WCSERR_BAD_WORLD) { status = wcserr_set(WCS_ERRMSG(WCSERR_BAD_WORLD_COORD)); } return status; } d1 = fabs(pixcrd[mixpix] - pixmix); for (iter = 0; iter < niter; iter++) { lng0m = (lng0 + lng)/2.0; *worldlng = lng0m; if ((status = wcss2p(wcs, 1, 0, world, phi, theta, imgcrd, pixcrd, stat))) { if (status == WCSERR_BAD_WORLD) { status = wcserr_set(WCS_ERRMSG(WCSERR_BAD_WORLD_COORD)); } return status; } d0m = fabs(pixcrd[mixpix] - pixmix); if (d0m < tol) return WCSERR_SUCCESS; lng1m = (lng1 + lng)/2.0; *worldlng = lng1m; if ((status = wcss2p(wcs, 1, 0, world, phi, theta, imgcrd, pixcrd, stat))) { if (status == WCSERR_BAD_WORLD) { status = wcserr_set(WCS_ERRMSG(WCSERR_BAD_WORLD_COORD)); } return status; } d1m = fabs(pixcrd[mixpix] - pixmix); if (d1m < tol) return WCSERR_SUCCESS; if (d0m < d && d0m <= d1m) { lng1 = lng; d1 = d; lng = lng0m; d = d0m; } else if (d1m < d) { lng0 = lng; d0 = d; lng = lng1m; d = d1m; } else { lng0 = lng0m; d0 = d0m; lng1 = lng1m; d1 = d1m; } } } } } } // Set cel0 to the unity transformation. wcs0 = *wcs; wcs0.cel.euler[0] = -90.0; wcs0.cel.euler[1] = 0.0; wcs0.cel.euler[2] = 90.0; wcs0.cel.euler[3] = 1.0; wcs0.cel.euler[4] = 0.0; // No convergence, check for aberrant behaviour at a native pole. *theta = -90.0; for (j = 1; j <= 2; j++) { // Could the celestial coordinate element map to a native pole? *phi = 0.0; *theta = -*theta; sphx2s(wcscel->euler, 1, 1, 1, 1, phi, theta, &lng, &lat); if (mixcel == 1) { if (fabs(fmod(*worldlng-lng, 360.0)) > tol) continue; if (lat < span[0]) continue; if (lat > span[1]) continue; *worldlat = lat; } else { if (fabs(*worldlat-lat) > tol) continue; if (lng < span[0]) lng += 360.0; if (lng > span[1]) lng -= 360.0; if (lng < span[0]) continue; if (lng > span[1]) continue; *worldlng = lng; } // Is there a solution for the given pixel coordinate element? lng = *worldlng; lat = *worldlat; // Feed native coordinates to wcss2p() with cel0 set to unity. *worldlng = -180.0; *worldlat = *theta; if ((status = wcss2p(&wcs0, 1, 0, world, phi, theta, imgcrd, pixcrd, stat))) { wcserr_clear(err); wcs->err = wcs0.err; if (status == WCSERR_BAD_WORLD) { status = wcserr_set(WCS_ERRMSG(WCSERR_BAD_WORLD_COORD)); } return status; } d0 = pixcrd[mixpix] - pixmix; // Check for a solution. if (fabs(d0) < tol) { // Recall saved world coordinates. *worldlng = lng; *worldlat = lat; return WCSERR_SUCCESS; } // Search for a crossing interval. phi0 = -180.0; for (k = -179; k <= 180; k++) { phi1 = (double) k; *worldlng = phi1; if ((status = wcss2p(&wcs0, 1, 0, world, phi, theta, imgcrd, pixcrd, stat))) { wcserr_clear(err); wcs->err = wcs0.err; if (status == WCSERR_BAD_WORLD) { status = wcserr_set(WCS_ERRMSG(WCSERR_BAD_WORLD_COORD)); } return status; } d1 = pixcrd[mixpix] - pixmix; // Check for a solution. dabs = fabs(d1); if (dabs < tol) { // Recall saved world coordinates. *worldlng = lng; *worldlat = lat; return WCSERR_SUCCESS; } // Is it a crossing interval? if (signbit(d0) != signbit(d1)) break; phi0 = phi1; d0 = d1; } for (iter = 1; iter <= niter; iter++) { // Use regula falsi division of the interval. lambda = d0/(d0-d1); if (lambda < 0.1) { lambda = 0.1; } else if (lambda > 0.9) { lambda = 0.9; } dphi = phi1 - phi0; *worldlng = phi0 + lambda*dphi; if ((status = wcss2p(&wcs0, 1, 0, world, phi, theta, imgcrd, pixcrd, stat))) { wcserr_clear(err); wcs->err = wcs0.err; if (status == WCSERR_BAD_WORLD) { status = wcserr_set(WCS_ERRMSG(WCSERR_BAD_WORLD_COORD)); } return status; } // Check for a solution. d = pixcrd[mixpix] - pixmix; dabs = fabs(d); if (dabs < tol || (dphi < tol && dabs < tol2)) { // Recall saved world coordinates. *worldlng = lng; *worldlat = lat; return WCSERR_SUCCESS; } if (signbit(d0) == signbit(d)) { phi0 = *worldlng; d0 = d; } else { phi1 = *worldlng; d1 = d; } } } // No solution. return wcserr_set(WCS_ERRMSG(WCSERR_NO_SOLUTION)); } //---------------------------------------------------------------------------- int wcsccs( struct wcsprm *wcs, double lng2P1, double lat2P1, double lng1P2, const char *clng, const char *clat, const char *radesys, double equinox, const char *alt) { static const char *function = "wcsccs"; int status; // Initialize if required. if (wcs == 0x0) return WCSERR_NULL_POINTER; struct wcserr **err = &(wcs->err); if (wcs->flag != WCSSET) { if ((status = wcsset(wcs))) return status; } if (wcs->lng < 0 || wcs->lat < 0) { return wcserr_set(WCSERR_SET(WCSERR_BAD_SUBIMAGE), "Image does not have celestial axes"); } // (lng1XX,lat1XX) ...longitude and latitude of XX in the old system. // (lng2XX,lat2XX) ...longitude and latitude of XX in the new system. // XX = NP ...natuve pole, // P1 ...pole of the old system, // P2 ...pole of the new system, // FP ...fiducial point. // Set up the transformation from the old to the new system. double euler12[5]; euler12[0] = lng2P1; euler12[1] = 90.0 - lat2P1; euler12[2] = lng1P2; euler12[3] = cosd(euler12[1]); euler12[4] = sind(euler12[1]); // Transform coordinates of the fiducial point (FP) to the new system. double lng1FP = wcs->crval[wcs->lng]; double lat1FP = wcs->crval[wcs->lat]; double lng2FP, lat2FP; (void)sphx2s(euler12, 1, 1, 1, 1, &lng1FP, &lat1FP, &lng2FP, &lat2FP); // Compute native coordinates of the new pole (noting lat1P2 == lat2P1). double phiP2, thetaP2; (void)sphs2x(wcs->cel.euler, 1, 1, 1, 1, &lng1P2, &lat2P1, &phiP2, &thetaP2); if (fabs(lat2FP) == 90.0 || fabs(thetaP2) == 90.0) { // If one of the poles of the new system is at the fiducial point, then // lng2FP is indeterminate, and if one of them is at the native pole, then // phiP2 is indeterminate. We have to work harder to obtain these values. // Compute coordinates of the native pole (NP) in the old and new systems. double phiNP = 0.0, thetaNP = 90.0; double lng1NP, lat1NP; (void)sphx2s(wcs->cel.euler, 1, 1, 1, 1, &phiNP, &thetaNP, &lng1NP, &lat1NP); double lng2NP, lat2NP; (void)sphx2s(euler12, 1, 1, 1, 1, &lng1NP, &lat1NP, &lng2NP, &lat2NP); // Native latitude and longitude of the fiducial point, (phi0,theta0). double phiFP = wcs->cel.prj.phi0; double thetaFP = wcs->cel.prj.theta0; if (fabs(lat2NP) == 90.0) { // Following WCS Paper II equations (3) and (4), we are free to choose // phiP2 and set lng2NP accordingly. So set phiP2 to its default value // for the projection. if (thetaFP < lat2FP) { phiP2 = 0.0; } else { phiP2 = 180.0; } // Compute coordinates in the old system of test point X. double phiX = 0.0, thetaX = 0.0; double lng1X, lat1X; (void)sphx2s(wcs->cel.euler, 1, 1, 1, 1, &phiX, &thetaX, &lng1X, &lat1X); // Ensure that lng1X is not indeterminate. if (fabs(lat1X) == 90.0) { phiX = 90.0; (void)sphx2s(wcs->cel.euler, 1, 1, 1, 1, &phiX, &thetaX, &lng1X, &lat1X); } // Compute coordinates in the new system of test point X. double lng2X, lat2X; (void)sphx2s(euler12, 1, 1, 1, 1, &lng1X, &lat1X, &lng2X, &lat2X); // Apply WCS Paper II equations (3) and (4). if (lat2NP == +90.0) { lng2NP = lng2X + (phiP2 - phiX) + 180.0; } else { lng2NP = lng2X - (phiP2 - phiX); } } else { // For (lng2NP + 90, 0), WCS Paper II equation (5) reduces to // phi = phiP2 - 90. double lng2X = lng2NP + 90.0; double lat2X = 0.0; double lng1X, lat1X; (void)sphs2x(euler12, 1, 1, 1, 1, &lng2X, &lat2X, &lng1X, &lat1X); double phiX, thetaX; (void)sphs2x(wcs->cel.euler, 1, 1, 1, 1, &lng1X, &lat1X, &phiX, &thetaX); phiP2 = phiX + 90.0; } // Compute the longitude of the fiducial point in the new system. double eulerN2[5]; eulerN2[0] = lng2NP; eulerN2[1] = 90.0 - lat2NP; eulerN2[2] = phiP2; eulerN2[3] = cosd(eulerN2[1]); eulerN2[4] = sind(eulerN2[1]); (void)sphx2s(eulerN2, 1, 1, 1, 1, &phiFP, &thetaFP, &lng2FP, &lat2FP); } // Update reference values in wcsprm. wcs->flag = 0; wcs->crval[wcs->lng] = lng2FP; wcs->crval[wcs->lat] = lat2FP; wcs->lonpole = phiP2; wcs->latpole = thetaP2; // Update wcsprm::ctype. if (clng) { strncpy(wcs->ctype[wcs->lng], clng, 4); for (int i = 0; i < 4; i++) { if (wcs->ctype[wcs->lng][i] == '\0') { wcs->ctype[wcs->lng][i] = '-'; } } } if (clat) { strncpy(wcs->ctype[wcs->lat], clat, 4); for (int i = 0; i < 4; i++) { if (wcs->ctype[wcs->lat][i] == '\0') { wcs->ctype[wcs->lat][i] = '-'; } } } // Update auxiliary values. if (strncmp(wcs->ctype[wcs->lng], "RA--", 4) == 0 && strncmp(wcs->ctype[wcs->lat], "DEC-", 4) == 0) { // Transforming to equatorial coordinates. if (radesys) { strncpy(wcs->radesys, radesys, 71); } if (equinox != 0.0) { wcs->equinox = equinox; } } else { // Meaningless for other than equatorial coordinates. memset(wcs->radesys, 0, 72); wcs->equinox = UNDEFINED; } if (alt && *alt) { wcs->alt[0] = *alt; } // Reset the struct. if ((status = wcsset(wcs))) return status; return WCSERR_SUCCESS; } //---------------------------------------------------------------------------- int wcssptr( struct wcsprm *wcs, int *i, char ctype[9]) { static const char *function = "wcssptr"; int status; // Initialize if required. if (wcs == 0x0) return WCSERR_NULL_POINTER; struct wcserr **err = &(wcs->err); if (wcs->flag != WCSSET) { if ((status = wcsset(wcs))) return status; } int j; if ((j = *i) < 0) { if ((j = wcs->spec) < 0) { // Look for a linear spectral axis. for (j = 0; j < wcs->naxis; j++) { if (wcs->types[j]/100 == 30) { break; } } if (j >= wcs->naxis) { // No spectral axis. return wcserr_set(WCSERR_SET(WCSERR_BAD_SUBIMAGE), "No spectral axis found"); } } *i = j; } // Translate the spectral axis. double cdelt, crval; if ((status = spctrne(wcs->ctype[j], wcs->crval[j], wcs->cdelt[j], wcs->restfrq, wcs->restwav, ctype, &crval, &cdelt, &(wcs->spc.err)))) { return wcserr_set(WCS_ERRMSG(wcs_spcerr[status])); } // Translate keyvalues. wcs->flag = 0; wcs->cdelt[j] = cdelt; wcs->crval[j] = crval; spctyp(ctype, 0x0, 0x0, 0x0, wcs->cunit[j], 0x0, 0x0, 0x0); strcpy(wcs->ctype[j], ctype); // This keeps things tidy if the spectral axis is linear. spcfree(&(wcs->spc)); spcini(&(wcs->spc)); // Reset the struct. if ((status = wcsset(wcs))) return status; return WCSERR_SUCCESS; } //---------------------------------------------------------------------------- #define STRINGIZE(s) STRINGIFY(s) #define STRINGIFY(s) #s const char *wcslib_version( int vers[3]) { static const char *wcsver = STRINGIZE(WCSLIB_VERSION); if (vers != 0x0) { vers[2] = 0; sscanf(wcsver, "%d.%d.%d", vers, vers+1, vers+2); } return wcsver; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/wcs.h0000644000175100001710000026732100000000000016342 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcs.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the wcs routines * --------------------------- * Routines in this suite implement the FITS World Coordinate System (WCS) * standard which defines methods to be used for computing world coordinates * from image pixel coordinates, and vice versa. The standard, and proposed * extensions for handling distortions, are described in * = "Representations of world coordinates in FITS", = Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (WCS Paper I) = = "Representations of celestial coordinates in FITS", = Calabretta, M.R., & Greisen, E.W. 2002, A&A, 395, 1077 (WCS Paper II) = = "Representations of spectral coordinates in FITS", = Greisen, E.W., Calabretta, M.R., Valdes, F.G., & Allen, S.L. = 2006, A&A, 446, 747 (WCS Paper III) = = "Representations of distortions in FITS world coordinate systems", = Calabretta, M.R. et al. (WCS Paper IV, draft dated 2004/04/22), = available from http://www.atnf.csiro.au/people/Mark.Calabretta = = "Mapping on the HEALPix grid", = Calabretta, M.R., & Roukema, B.F. 2007, MNRAS, 381, 865 (WCS Paper V) = = "Representing the 'Butterfly' Projection in FITS -- Projection Code XPH", = Calabretta, M.R., & Lowe, S.R. 2013, PASA, 30, e050 (WCS Paper VI) = = "Representations of time coordinates in FITS - = Time and relative dimension in space", = Rots, A.H., Bunclark, P.S., Calabretta, M.R., Allen, S.L., = Manchester, R.N., & Thompson, W.T. 2015, A&A, 574, A36 (WCS Paper VII) * * These routines are based on the wcsprm struct which contains all information * needed for the computations. The struct contains some members that must be * set by the user, and others that are maintained by these routines, somewhat * like a C++ class but with no encapsulation. * * wcsnpv(), wcsnps(), wcsini(), wcsinit(), wcssub(), wcsfree(), and wcstrim(), * are provided to manage the wcsprm struct, wcssize() computes its total size * including allocated memory, and wcsprt() prints its contents. Refer to the * description of the wcsprm struct for an explanation of the anticipated usage * of these routines. wcscopy(), which does a deep copy of one wcsprm struct * to another, is defined as a preprocessor macro function that invokes * wcssub(). * * wcsperr() prints the error message(s) (if any) stored in a wcsprm struct, * and the linprm, celprm, prjprm, spcprm, and tabprm structs that it contains. * * A setup routine, wcsset(), computes intermediate values in the wcsprm struct * from parameters in it that were supplied by the user. The struct always * needs to be set up by wcsset() but this need not be called explicitly - * refer to the explanation of wcsprm::flag. * * wcsp2s() and wcss2p() implement the WCS world coordinate transformations. * In fact, they are high level driver routines for the WCS linear, * logarithmic, celestial, spectral and tabular transformation routines * described in lin.h, log.h, cel.h, spc.h and tab.h. * * Given either the celestial longitude or latitude plus an element of the * pixel coordinate a hybrid routine, wcsmix(), iteratively solves for the * unknown elements. * * wcsccs() changes the celestial coordinate system of a wcsprm struct, for * example, from equatorial to galactic, and wcssptr() translates the spectral * axis. For example, a 'FREQ' axis may be translated into 'ZOPT-F2W' and vice * versa. * * wcslib_version() returns the WCSLIB version number. * * Quadcube projections: * --------------------- * The quadcube projections (TSC, CSC, QSC) may be represented in FITS in * either of two ways: * * a: The six faces may be laid out in one plane and numbered as follows: * = 0 = = 4 3 2 1 4 3 2 = = 5 * * Faces 2, 3 and 4 may appear on one side or the other (or both). The * world-to-pixel routines map faces 2, 3 and 4 to the left but the * pixel-to-world routines accept them on either side. * * b: The "COBE" convention in which the six faces are stored in a * three-dimensional structure using a CUBEFACE axis indexed from * 0 to 5 as above. * * These routines support both methods; wcsset() determines which is being * used by the presence or absence of a CUBEFACE axis in ctype[]. wcsp2s() * and wcss2p() translate the CUBEFACE axis representation to the single * plane representation understood by the lower-level WCSLIB projection * routines. * * * wcsnpv() - Memory allocation for PVi_ma * --------------------------------------- * wcsnpv() sets or gets the value of NPVMAX (default 64). This global * variable controls the number of pvcard structs, for holding PVi_ma * keyvalues, that wcsini() should allocate space for. It is also used by * wcsinit() as the default value of npvmax. * * PLEASE NOTE: This function is not thread-safe. * * Given: * n int Value of NPVMAX; ignored if < 0. Use a value less * than zero to get the current value. * * Function return value: * int Current value of NPVMAX. * * * wcsnps() - Memory allocation for PSi_ma * --------------------------------------- * wcsnps() sets or gets the value of NPSMAX (default 8). This global variable * controls the number of pscard structs, for holding PSi_ma keyvalues, that * wcsini() should allocate space for. It is also used by wcsinit() as the * default value of npsmax. * * PLEASE NOTE: This function is not thread-safe. * * Given: * n int Value of NPSMAX; ignored if < 0. Use a value less * than zero to get the current value. * * Function return value: * int Current value of NPSMAX. * * * wcsini() - Default constructor for the wcsprm struct * ---------------------------------------------------- * wcsini() is a thin wrapper on wcsinit(). It invokes it with npvmax, * npsmax, and ndpmax set to -1 which causes it to use the values of the * global variables NDPMAX, NPSMAX, and NDPMAX. It is thereby potentially * thread-unsafe if these variables are altered dynamically via wcsnpv(), * wcsnps(), and disndp(). Use wcsinit() for a thread-safe alternative in * this case. * * * wcsinit() - Default constructor for the wcsprm struct * ----------------------------------------------------- * wcsinit() optionally allocates memory for arrays in a wcsprm struct and sets * all members of the struct to default values. * * PLEASE NOTE: every wcsprm struct should be initialized by wcsinit(), * possibly repeatedly. On the first invokation, and only the first * invokation, wcsprm::flag must be set to -1 to initialize memory management, * regardless of whether wcsinit() will actually be used to allocate memory. * * Given: * alloc int If true, allocate memory unconditionally for the * crpix, etc. arrays. Please note that memory is never * allocated by wcsinit() for the auxprm, tabprm, nor * wtbarr structs. * * If false, it is assumed that pointers to these arrays * have been set by the user except if they are null * pointers in which case memory will be allocated for * them regardless. (In other words, setting alloc true * saves having to initalize these pointers to zero.) * * naxis int The number of world coordinate axes. This is used to * determine the length of the various wcsprm vectors and * matrices and therefore the amount of memory to * allocate for them. * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. * * Note that, in order to initialize memory management, * wcsprm::flag should be set to -1 when wcs is * initialized for the first time (memory leaks may * result if it had already been initialized). * * Given: * npvmax int The number of PVi_ma keywords to allocate space for. * If set to -1, the value of the global variable NPVMAX * will be used. This is potentially thread-unsafe if * wcsnpv() is being used dynamically to alter its value. * * npsmax int The number of PSi_ma keywords to allocate space for. * If set to -1, the value of the global variable NPSMAX * will be used. This is potentially thread-unsafe if * wcsnps() is being used dynamically to alter its value. * * ndpmax int The number of DPja or DQia keywords to allocate space * for. If set to -1, the value of the global variable * NDPMAX will be used. This is potentially * thread-unsafe if disndp() is being used dynamically to * alter its value. * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * 2: Memory allocation failed. * * For returns > 1, a detailed error message is set in * wcsprm::err if enabled, see wcserr_enable(). * * * wcsauxi() - Default constructor for the auxprm struct * ----------------------------------------------------- * wcsauxi() optionally allocates memory for an auxprm struct, attaches it to * wcsprm, and sets all members of the struct to default values. * * Given: * alloc int If true, allocate memory unconditionally for the * auxprm struct. * * If false, it is assumed that wcsprm::aux has already * been set to point to an auxprm struct, in which case * the user is responsible for managing that memory. * However, if wcsprm::aux is a null pointer, memory will * be allocated regardless. (In other words, setting * alloc true saves having to initalize the pointer to * zero.) * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * 2: Memory allocation failed. * * * wcssub() - Subimage extraction routine for the wcsprm struct * ------------------------------------------------------------ * wcssub() extracts the coordinate description for a subimage from a wcsprm * struct. It does a deep copy, using wcsinit() to allocate memory for its * arrays if required. Only the "information to be provided" part of the * struct is extracted. Consequently, wcsset() need not have been, and won't * be invoked on the struct from which the subimage is extracted. A call to * wcsset() is required to set up the subimage struct. * * The world coordinate system of the subimage must be separable in the sense * that the world coordinates at any point in the subimage must depend only on * the pixel coordinates of the axes extracted. In practice, this means that * the linear transformation matrix of the original image must not contain * non-zero off-diagonal terms that associate any of the subimage axes with any * of the non-subimage axes. Likewise, if any distortions are associated with * the subimage axes, they must not depend on any of the axes that are not * being extracted. * * Note that while the required elements of the tabprm array are extracted, the * wtbarr array is not. (Thus it is not appropriate to call wcssub() after * wcstab() but before filling the tabprm structs - refer to wcshdr.h.) * * wcssub() can also add axes to a wcsprm struct. The new axes will be created * using the defaults set by wcsinit() which produce a simple, unnamed, linear * axis with world coordinate equal to the pixel coordinate. These default * values can be changed afterwards, before invoking wcsset(). * * Given: * alloc int If true, allocate memory for the crpix, etc. arrays in * the destination. Otherwise, it is assumed that * pointers to these arrays have been set by the user * except if they are null pointers in which case memory * will be allocated for them regardless. * * wcssrc const struct wcsprm* * Struct to extract from. * * Given and returned: * nsub int* * axes int[] Vector of length *nsub containing the image axis * numbers (1-relative) to extract. Order is * significant; axes[0] is the axis number of the input * image that corresponds to the first axis in the * subimage, etc. * * Use an axis number of 0 to create a new axis using * the defaults set by wcsinit(). They can be changed * later. * * nsub (the pointer) may be set to zero, and so also may * *nsub, which is interpreted to mean all axes in the * input image; the number of axes will be returned if * nsub != 0x0. axes itself (the pointer) may be set to * zero to indicate the first *nsub axes in their * original order. * * Set both nsub (or *nsub) and axes to zero to do a deep * copy of one wcsprm struct to another. * * Subimage extraction by coordinate axis type may be * done by setting the elements of axes[] to the * following special preprocessor macro values: * * WCSSUB_LONGITUDE: Celestial longitude. * WCSSUB_LATITUDE: Celestial latitude. * WCSSUB_CUBEFACE: Quadcube CUBEFACE axis. * WCSSUB_SPECTRAL: Spectral axis. * WCSSUB_STOKES: Stokes axis. * * Refer to the notes (below) for further usage examples. * * On return, *nsub will be set to the number of axes in * the subimage; this may be zero if there were no axes * of the required type(s) (in which case no memory will * be allocated). axes[] will contain the axis numbers * that were extracted, or 0 for newly created axes. The * vector length must be sufficient to contain all axis * numbers. No checks are performed to verify that the * coordinate axes are consistent, this is done by * wcsset(). * * wcsdst struct wcsprm* * Struct describing the subimage. wcsprm::flag should * be set to -1 if wcsdst was not previously initialized * (memory leaks may result if it was previously * initialized). * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * 2: Memory allocation failed. * 12: Invalid subimage specification. * 13: Non-separable subimage coordinate system. * * For returns > 1, a detailed error message is set in * wcsprm::err if enabled, see wcserr_enable(). * * Notes: * 1: Combinations of subimage axes of particular types may be extracted in * the same order as they occur in the input image by combining * preprocessor codes, for example * = *nsub = 1; = axes[0] = WCSSUB_LONGITUDE | WCSSUB_LATITUDE | WCSSUB_SPECTRAL; * * would extract the longitude, latitude, and spectral axes in the same * order as the input image. If one of each were present, *nsub = 3 would * be returned. * * For convenience, WCSSUB_CELESTIAL is defined as the combination * WCSSUB_LONGITUDE | WCSSUB_LATITUDE | WCSSUB_CUBEFACE. * * The codes may also be negated to extract all but the types specified, * for example * = *nsub = 4; = axes[0] = WCSSUB_LONGITUDE; = axes[1] = WCSSUB_LATITUDE; = axes[2] = WCSSUB_CUBEFACE; = axes[3] = -(WCSSUB_SPECTRAL | WCSSUB_STOKES); * * The last of these specifies all axis types other than spectral or * Stokes. Extraction is done in the order specified by axes[] a * longitude axis (if present) would be extracted first (via axes[0]) and * not subsequently (via axes[3]). Likewise for the latitude and cubeface * axes in this example. * * From the foregoing, it is apparent that the value of *nsub returned may * be less than or greater than that given. However, it will never exceed * the number of axes in the input image (plus the number of newly-created * axes if any were specified on input). * * * wcscompare() - Compare two wcsprm structs for equality * ------------------------------------------------------ * wcscompare() compares two wcsprm structs for equality. * * Given: * cmp int A bit field controlling the strictness of the * comparison. When 0, all fields must be identical. * * The following constants may be or'ed together to * relax the comparison: * WCSCOMPARE_ANCILLARY: Ignore ancillary keywords * that don't change the WCS transformation, such * as DATE-OBS or EQUINOX. * WCSCOMPARE_TILING: Ignore integral differences in * CRPIXja. This is the 'tiling' condition, where * two WCSes cover different regions of the same * map projection and align on the same map grid. * WCSCOMPARE_CRPIX: Ignore any differences at all in * CRPIXja. The two WCSes cover different regions * of the same map projection but may not align on * the same map grid. Overrides WCSCOMPARE_TILING. * * tol double Tolerance for comparison of floating-point values. * For example, for tol == 1e-6, all floating-point * values in the structs must be equal to the first 6 * decimal places. A value of 0 implies exact equality. * * wcs1 const struct wcsprm* * The first wcsprm struct to compare. * * wcs2 const struct wcsprm* * The second wcsprm struct to compare. * * Returned: * equal int* Non-zero when the given structs are equal. * * Function return value: * int Status return value: * 0: Success. * 1: Null pointer passed. * * * wcscopy() macro - Copy routine for the wcsprm struct * ---------------------------------------------------- * wcscopy() does a deep copy of one wcsprm struct to another. As of * WCSLIB 3.6, it is implemented as a preprocessor macro that invokes * wcssub() with the nsub and axes pointers both set to zero. * * * wcsfree() - Destructor for the wcsprm struct * -------------------------------------------- * wcsfree() frees memory allocated for the wcsprm arrays by wcsinit() and/or * wcsset(). wcsinit() records the memory it allocates and wcsfree() will only * attempt to free this. * * PLEASE NOTE: wcsfree() must not be invoked on a wcsprm struct that was not * initialized by wcsinit(). * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * * * wcstrim() - Free unused arrays in the wcsprm struct * --------------------------------------------------- * wcstrim() frees memory allocated by wcsinit() for arrays in the wcsprm * struct that remains unused after it has been set up by wcsset(). * * The free'd array members are associated with FITS WCS keyrecords that are * rarely used and usually just bloat the struct: wcsprm::crota, wcsprm::colax, * wcsprm::cname, wcsprm::crder, wcsprm::csyer, wcsprm::czphs, and * wcsprm::cperi. If unused, wcsprm::pv, wcsprm::ps, and wcsprm::cd are also * freed. * * Once these arrays have been freed, a test such as = = if (!undefined(wcs->cname[i])) {...} = * must be protected as follows = = if (wcs->cname && !undefined(wcs->cname[i])) {...} = * In addition, if wcsprm::npv is non-zero but less than wcsprm::npvmax, then * the unused space in wcsprm::pv will be recovered (using realloc()). * Likewise for wcsprm::ps. * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * 14: wcsprm struct is unset. * * * wcssize() - Compute the size of a wcsprm struct * ----------------------------------------------- * wcssize() computes the full size of a wcsprm struct, including allocated * memory. * * Given: * wcs const struct wcsprm* * Coordinate transformation parameters. * * If NULL, the base size of the struct and the allocated * size are both set to zero. * * Returned: * sizes int[2] The first element is the base size of the struct as * returned by sizeof(struct wcsprm). The second element * is the total allocated size, in bytes, assuming that * the allocation was done by wcsini(). This figure * includes memory allocated for members of constituent * structs, such as wcsprm::lin. * * It is not an error for the struct not to have been set * up via wcsset(), which normally results in additional * memory allocation. * * Function return value: * int Status return value: * 0: Success. * * * auxsize() - Compute the size of a auxprm struct * ----------------------------------------------- * auxsize() computes the full size of a auxprm struct, including allocated * memory. * * Given: * aux const struct auxprm* * Auxiliary coordinate information. * * If NULL, the base size of the struct and the allocated * size are both set to zero. * * Returned: * sizes int[2] The first element is the base size of the struct as * returned by sizeof(struct auxprm). The second element * is the total allocated size, in bytes, currently zero. * * Function return value: * int Status return value: * 0: Success. * * * wcsprt() - Print routine for the wcsprm struct * ---------------------------------------------- * wcsprt() prints the contents of a wcsprm struct using wcsprintf(). Mainly * intended for diagnostic purposes. * * Given: * wcs const struct wcsprm* * Coordinate transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * * * wcsperr() - Print error messages from a wcsprm struct * ----------------------------------------------------- * wcsperr() prints the error message(s), if any, stored in a wcsprm struct, * and the linprm, celprm, prjprm, spcprm, and tabprm structs that it contains. * If there are no errors then nothing is printed. It uses wcserr_prt(), q.v. * * Given: * wcs const struct wcsprm* * Coordinate transformation parameters. * * prefix const char * * If non-NULL, each output line will be prefixed with * this string. * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * * * wcsbchk() - Enable/disable bounds checking * ------------------------------------------ * wcsbchk() is used to control bounds checking in the projection routines. * Note that wcsset() always enables bounds checking. wcsbchk() will invoke * wcsset() on the wcsprm struct beforehand if necessary. * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. * * Given: * bounds int If bounds&1 then enable strict bounds checking for the * spherical-to-Cartesian (s2x) transformation for the * AZP, SZP, TAN, SIN, ZPN, and COP projections. * * If bounds&2 then enable strict bounds checking for the * Cartesian-to-spherical (x2s) transformation for the * HPX and XPH projections. * * If bounds&4 then enable bounds checking on the native * coordinates returned by the Cartesian-to-spherical * (x2s) transformations using prjchk(). * * Zero it to disable all checking. * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * * * wcsset() - Setup routine for the wcsprm struct * ---------------------------------------------- * wcsset() sets up a wcsprm struct according to information supplied within * it (refer to the description of the wcsprm struct). * * wcsset() recognizes the NCP projection and converts it to the equivalent SIN * projection and likewise translates GLS into SFL. It also translates the * AIPS spectral types ('FREQ-LSR', 'FELO-HEL', etc.), possibly changing the * input header keywords wcsprm::ctype and/or wcsprm::specsys if necessary. * * Note that this routine need not be called directly; it will be invoked by * wcsp2s() and wcss2p() if the wcsprm::flag is anything other than a * predefined magic value. * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * 2: Memory allocation failed. * 3: Linear transformation matrix is singular. * 4: Inconsistent or unrecognized coordinate axis * types. * 5: Invalid parameter value. * 6: Invalid coordinate transformation parameters. * 7: Ill-conditioned coordinate transformation * parameters. * * For returns > 1, a detailed error message is set in * wcsprm::err if enabled, see wcserr_enable(). * * Notes: * 1: wcsset() always enables strict bounds checking in the projection * routines (via a call to prjini()). Use wcsbchk() to modify * bounds-checking after wcsset() is invoked. * * * wcsp2s() - Pixel-to-world transformation * ---------------------------------------- * wcsp2s() transforms pixel coordinates to world coordinates. * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. * * Given: * ncoord, * nelem int The number of coordinates, each of vector length * nelem but containing wcs.naxis coordinate elements. * Thus nelem must equal or exceed the value of the * NAXIS keyword unless ncoord == 1, in which case nelem * is not used. * * pixcrd const double[ncoord][nelem] * Array of pixel coordinates. * * Returned: * imgcrd double[ncoord][nelem] * Array of intermediate world coordinates. For * celestial axes, imgcrd[][wcs.lng] and * imgcrd[][wcs.lat] are the projected x-, and * y-coordinates in pseudo "degrees". For spectral * axes, imgcrd[][wcs.spec] is the intermediate spectral * coordinate, in SI units. * * phi,theta double[ncoord] * Longitude and latitude in the native coordinate system * of the projection [deg]. * * world double[ncoord][nelem] * Array of world coordinates. For celestial axes, * world[][wcs.lng] and world[][wcs.lat] are the * celestial longitude and latitude [deg]. For * spectral axes, imgcrd[][wcs.spec] is the intermediate * spectral coordinate, in SI units. * * stat int[ncoord] * Status return value for each coordinate: * 0: Success. * 1+: A bit mask indicating invalid pixel coordinate * element(s). * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * 2: Memory allocation failed. * 3: Linear transformation matrix is singular. * 4: Inconsistent or unrecognized coordinate axis * types. * 5: Invalid parameter value. * 6: Invalid coordinate transformation parameters. * 7: Ill-conditioned coordinate transformation * parameters. * 8: One or more of the pixel coordinates were * invalid, as indicated by the stat vector. * * For returns > 1, a detailed error message is set in * wcsprm::err if enabled, see wcserr_enable(). * * * wcss2p() - World-to-pixel transformation * ---------------------------------------- * wcss2p() transforms world coordinates to pixel coordinates. * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. * * Given: * ncoord, * nelem int The number of coordinates, each of vector length nelem * but containing wcs.naxis coordinate elements. Thus * nelem must equal or exceed the value of the NAXIS * keyword unless ncoord == 1, in which case nelem is not * used. * * world const double[ncoord][nelem] * Array of world coordinates. For celestial axes, * world[][wcs.lng] and world[][wcs.lat] are the * celestial longitude and latitude [deg]. For spectral * axes, world[][wcs.spec] is the spectral coordinate, in * SI units. * * Returned: * phi,theta double[ncoord] * Longitude and latitude in the native coordinate * system of the projection [deg]. * * imgcrd double[ncoord][nelem] * Array of intermediate world coordinates. For * celestial axes, imgcrd[][wcs.lng] and * imgcrd[][wcs.lat] are the projected x-, and * y-coordinates in pseudo "degrees". For quadcube * projections with a CUBEFACE axis the face number is * also returned in imgcrd[][wcs.cubeface]. For * spectral axes, imgcrd[][wcs.spec] is the intermediate * spectral coordinate, in SI units. * * pixcrd double[ncoord][nelem] * Array of pixel coordinates. * * stat int[ncoord] * Status return value for each coordinate: * 0: Success. * 1+: A bit mask indicating invalid world coordinate * element(s). * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * 2: Memory allocation failed. * 3: Linear transformation matrix is singular. * 4: Inconsistent or unrecognized coordinate axis * types. * 5: Invalid parameter value. * 6: Invalid coordinate transformation parameters. * 7: Ill-conditioned coordinate transformation * parameters. * 9: One or more of the world coordinates were * invalid, as indicated by the stat vector. * * For returns > 1, a detailed error message is set in * wcsprm::err if enabled, see wcserr_enable(). * * * wcsmix() - Hybrid coordinate transformation * ------------------------------------------- * wcsmix(), given either the celestial longitude or latitude plus an element * of the pixel coordinate, solves for the remaining elements by iterating on * the unknown celestial coordinate element using wcss2p(). Refer also to the * notes below. * * Given and returned: * wcs struct wcsprm* * Indices for the celestial coordinates obtained * by parsing the wcsprm::ctype[]. * * Given: * mixpix int Which element of the pixel coordinate is given. * * mixcel int Which element of the celestial coordinate is given: * 1: Celestial longitude is given in * world[wcs.lng], latitude returned in * world[wcs.lat]. * 2: Celestial latitude is given in * world[wcs.lat], longitude returned in * world[wcs.lng]. * * vspan const double[2] * Solution interval for the celestial coordinate [deg]. * The ordering of the two limits is irrelevant. * Longitude ranges may be specified with any convenient * normalization, for example [-120,+120] is the same as * [240,480], except that the solution will be returned * with the same normalization, i.e. lie within the * interval specified. * * vstep const double * Step size for solution search [deg]. If zero, a * sensible, although perhaps non-optimal default will be * used. * * viter int If a solution is not found then the step size will be * halved and the search recommenced. viter controls how * many times the step size is halved. The allowed range * is 5 - 10. * * Given and returned: * world double[naxis] * World coordinate elements. world[wcs.lng] and * world[wcs.lat] are the celestial longitude and * latitude [deg]. Which is given and which returned * depends on the value of mixcel. All other elements * are given. * * Returned: * phi,theta double[naxis] * Longitude and latitude in the native coordinate * system of the projection [deg]. * * imgcrd double[naxis] * Image coordinate elements. imgcrd[wcs.lng] and * imgcrd[wcs.lat] are the projected x-, and * y-coordinates in pseudo "degrees". * * Given and returned: * pixcrd double[naxis] * Pixel coordinate. The element indicated by mixpix is * given and the remaining elements are returned. * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * 2: Memory allocation failed. * 3: Linear transformation matrix is singular. * 4: Inconsistent or unrecognized coordinate axis * types. * 5: Invalid parameter value. * 6: Invalid coordinate transformation parameters. * 7: Ill-conditioned coordinate transformation * parameters. * 10: Invalid world coordinate. * 11: No solution found in the specified interval. * * For returns > 1, a detailed error message is set in * wcsprm::err if enabled, see wcserr_enable(). * * Notes: * 1: Initially the specified solution interval is checked to see if it's a * "crossing" interval. If it isn't, a search is made for a crossing * solution by iterating on the unknown celestial coordinate starting at * the upper limit of the solution interval and decrementing by the * specified step size. A crossing is indicated if the trial value of the * pixel coordinate steps through the value specified. If a crossing * interval is found then the solution is determined by a modified form of * "regula falsi" division of the crossing interval. If no crossing * interval was found within the specified solution interval then a search * is made for a "non-crossing" solution as may arise from a point of * tangency. The process is complicated by having to make allowance for * the discontinuities that occur in all map projections. * * Once one solution has been determined others may be found by subsequent * invokations of wcsmix() with suitably restricted solution intervals. * * Note the circumstance that arises when the solution point lies at a * native pole of a projection in which the pole is represented as a * finite curve, for example the zenithals and conics. In such cases two * or more valid solutions may exist but wcsmix() only ever returns one. * * Because of its generality wcsmix() is very compute-intensive. For * compute-limited applications more efficient special-case solvers could * be written for simple projections, for example non-oblique cylindrical * projections. * * * wcsccs() - Change celestial coordinate system * --------------------------------------------- * wcsccs() changes the celestial coordinate system of a wcsprm struct. For * example, from equatorial to galactic coordinates. * * Parameters that define the spherical coordinate transformation, essentially * being three Euler angles, must be provided. Thereby wcsccs() does not need * prior knowledge of specific celestial coordinate systems. It also has the * advantage of making it completely general. * * Auxiliary members of the wcsprm struct relating to equatorial celestial * coordinate systems may also be changed. * * Only orthodox spherical coordinate systems are supported. That is, they * must be right-handed, with latitude increasing from zero at the equator to * +90 degrees at the pole. This precludes systems such as aziumuth and zenith * distance, which, however, could be handled as negative azimuth and * elevation. * * PLEASE NOTE: Information in the wcsprm struct relating to the original * coordinate system will be overwritten and therefore lost. If this is * undesirable, invoke wcsccs() on a copy of the struct made with wcssub(). * The wcsprm struct is reset on return with an explicit call to wcsset(). * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. Particular * "values to be given" elements of the wcsprm struct * are modified. * * Given: * lng2p1, * lat2p1 double Longitude and latitude in the new celestial coordinate * system of the pole (i.e. latitude +90) of the original * system [deg]. See notes 1 and 2 below. * * lng1p2 double Longitude in the original celestial coordinate system * of the pole (i.e. latitude +90) of the new system * [deg]. See note 1 below. * * clng,clat const char* * Longitude and latitude identifiers of the new CTYPEia * celestial axis codes, without trailing dashes. For * example, "RA" and "DEC" or "GLON" and "GLAT". Up to * four characters are used, longer strings need not be * null-terminated. * * radesys const char* * Used when transforming to equatorial coordinates, * identified by clng == "RA" and clat = "DEC". May be * set to the null pointer to preserve the current value. * Up to 71 characters are used, longer strings need not * be null-terminated. * * If the new coordinate system is anything other than * equatorial, then wcsprm::radesys will be cleared. * * equinox double Used when transforming to equatorial coordinates. May * be set to zero to preserve the current value. * * If the new coordinate system is not equatorial, then * wcsprm::equinox will be marked as undefined. * * alt const char* * Character code for alternate coordinate descriptions * (i.e. the 'a' in keyword names such as CTYPEia). This * is blank for the primary coordinate description, or * one of the 26 upper-case letters, A-Z. May be set to * the null pointer, or null string if no change is * required. * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * 12: Invalid subimage specification (no celestial * axes). * * Notes: * 1: Follows the prescription given in WCS Paper II, Sect. 2.7 for changing * celestial coordinates. * * The implementation takes account of indeterminacies that arise in that * prescription in the particular cases where one of the poles of the new * system is at the fiducial point, or one of them is at the native pole. * * 2: If lat2p1 == +90, i.e. where the poles of the two coordinate systems * coincide, then the spherical coordinate transformation becomes a simple * change in origin of longitude given by * lng2 = lng1 + (lng2p1 - lng1p2 - 180), and lat2 = lat1, where * (lng2,lat2) are coordinates in the new system, and (lng1,lat1) are * coordinates in the original system. * * Likewise, if lat2p1 == -90, then lng2 = -lng1 + (lng2p1 + lng1p2), and * lat2 = -lat1. * * 3: For example, if the original coordinate system is B1950 equatorial and * the desired new coordinate system is galactic, then * * - (lng2p1,lat2p1) are the galactic coordinates of the B1950 celestial * pole, defined by the IAU to be (123.0,+27.4), and lng1p2 is the B1950 * right ascension of the galactic pole, defined as 192.25. Clearly * these coordinates are fixed for a particular coordinate * transformation. * * - (clng,clat) would be 'GLON' and 'GLAT', these being the FITS standard * identifiers for galactic coordinates. * * - Since the new coordinate system is not equatorial, wcsprm::radesys * and wcsprm::equinox will be cleared. * * 4. The coordinates required for some common transformations (obtained from * https://ned.ipac.caltech.edu/coordinate_calculator) are as follows: * = (123.0000,+27.4000) galactic coordinates of B1950 celestial pole, = (192.2500,+27.4000) B1950 equatorial coordinates of galactic pole. * = (122.9319,+27.1283) galactic coordinates of J2000 celestial pole, = (192.8595,+27.1283) J2000 equatorial coordinates of galactic pole. * = (359.6774,+89.7217) B1950 equatorial coordinates of J2000 pole, = (180.3162,+89.7217) J2000 equatorial coordinates of B1950 pole. * = (270.0000,+66.5542) B1950 equatorial coordinates of B1950 ecliptic pole, = ( 90.0000,+66.5542) B1950 ecliptic coordinates of B1950 celestial pole. * = (270.0000,+66.5607) J2000 equatorial coordinates of J2000 ecliptic pole, = ( 90.0000,+66.5607) J2000 ecliptic coordinates of J2000 celestial pole. * = ( 26.7315,+15.6441) supergalactic coordinates of B1950 celestial pole, = (283.1894,+15.6441) B1950 equatorial coordinates of supergalactic pole. * = ( 26.4505,+15.7089) supergalactic coordinates of J2000 celestial pole, = (283.7542,+15.7089) J2000 equatorial coordinates of supergalactic pole. * * * wcssptr() - Spectral axis translation * ------------------------------------- * wcssptr() translates the spectral axis in a wcsprm struct. For example, a * 'FREQ' axis may be translated into 'ZOPT-F2W' and vice versa. * * PLEASE NOTE: Information in the wcsprm struct relating to the original * coordinate system will be overwritten and therefore lost. If this is * undesirable, invoke wcssptr() on a copy of the struct made with wcssub(). * The wcsprm struct is reset on return with an explicit call to wcsset(). * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. * * i int* Index of the spectral axis (0-relative). If given < 0 * it will be set to the first spectral axis identified * from the ctype[] keyvalues in the wcsprm struct. * * ctype char[9] Desired spectral CTYPEia. Wildcarding may be used as * for the ctypeS2 argument to spctrn() as described in * the prologue of spc.h, i.e. if the final three * characters are specified as "???", or if just the * eighth character is specified as '?', the correct * algorithm code will be substituted and returned. * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * 2: Memory allocation failed. * 3: Linear transformation matrix is singular. * 4: Inconsistent or unrecognized coordinate axis * types. * 5: Invalid parameter value. * 6: Invalid coordinate transformation parameters. * 7: Ill-conditioned coordinate transformation * parameters. * 12: Invalid subimage specification (no spectral * axis). * * For returns > 1, a detailed error message is set in * wcsprm::err if enabled, see wcserr_enable(). * * * wcslib_version() - WCSLIB version number * ---------------------------------------- * wcslib_version() returns the WCSLIB version number. * * The major version number changes when the ABI changes or when the license * conditions change. ABI changes typically result from a change to the * contents of one of the structs. The major version number is used to * distinguish between incompatible versions of the sharable library. * * The minor version number changes with new functionality or bug fixes that do * not involve a change in the ABI. * * The auxiliary version number (which is often absent) signals changes to the * documentation, test suite, build procedures, or any other change that does * not affect the compiled library. * * Returned: * vers[3] int[3] The broken-down version number: * 0: Major version number. * 1: Minor version number. * 2: Auxiliary version number (zero if absent). * May be given as a null pointer if not required. * * Function return value: * char* A null-terminated, statically allocated string * containing the version number in the usual form, i.e. * "..". * * * wcsprm struct - Coordinate transformation parameters * ---------------------------------------------------- * The wcsprm struct contains information required to transform world * coordinates. It consists of certain members that must be set by the user * ("given") and others that are set by the WCSLIB routines ("returned"). * While the addresses of the arrays themselves may be set by wcsinit() if it * (optionally) allocates memory, their contents must be set by the user. * * Some parameters that are given are not actually required for transforming * coordinates. These are described as "auxiliary"; the struct simply provides * a place to store them, though they may be used by wcshdo() in constructing a * FITS header from a wcsprm struct. Some of the returned values are supplied * for informational purposes and others are for internal use only as * indicated. * * In practice, it is expected that a WCS parser would scan the FITS header to * determine the number of coordinate axes. It would then use wcsinit() to * allocate memory for arrays in the wcsprm struct and set default values. * Then as it reread the header and identified each WCS keyrecord it would load * the value into the relevant wcsprm array element. This is essentially what * wcspih() does - refer to the prologue of wcshdr.h. As the final step, * wcsset() is invoked, either directly or indirectly, to set the derived * members of the wcsprm struct. wcsset() strips off trailing blanks in all * string members and null-fills the character array. * * int flag * (Given and returned) This flag must be set to zero whenever any of the * following wcsprm struct members are set or changed: * * - wcsprm::naxis (q.v., not normally set by the user), * - wcsprm::crpix, * - wcsprm::pc, * - wcsprm::cdelt, * - wcsprm::crval, * - wcsprm::cunit, * - wcsprm::ctype, * - wcsprm::lonpole, * - wcsprm::latpole, * - wcsprm::restfrq, * - wcsprm::restwav, * - wcsprm::npv, * - wcsprm::pv, * - wcsprm::nps, * - wcsprm::ps, * - wcsprm::cd, * - wcsprm::crota, * - wcsprm::altlin, * - wcsprm::ntab, * - wcsprm::nwtb, * - wcsprm::tab, * - wcsprm::wtb. * * This signals the initialization routine, wcsset(), to recompute the * returned members of the linprm, celprm, spcprm, and tabprm structs. * wcsset() will reset flag to indicate that this has been done. * * PLEASE NOTE: flag should be set to -1 when wcsinit() is called for the * first time for a particular wcsprm struct in order to initialize memory * management. It must ONLY be used on the first initialization otherwise * memory leaks may result. * * int naxis * (Given or returned) Number of pixel and world coordinate elements. * * If wcsinit() is used to initialize the linprm struct (as would normally * be the case) then it will set naxis from the value passed to it as a * function argument. The user should not subsequently modify it. * * double *crpix * (Given) Address of the first element of an array of double containing * the coordinate reference pixel, CRPIXja. * * double *pc * (Given) Address of the first element of the PCi_ja (pixel coordinate) * transformation matrix. The expected order is * = struct wcsprm wcs; = wcs.pc = {PC1_1, PC1_2, PC2_1, PC2_2}; * * This may be constructed conveniently from a 2-D array via * = double m[2][2] = {{PC1_1, PC1_2}, = {PC2_1, PC2_2}}; * * which is equivalent to * = double m[2][2]; = m[0][0] = PC1_1; = m[0][1] = PC1_2; = m[1][0] = PC2_1; = m[1][1] = PC2_2; * * The storage order for this 2-D array is the same as for the 1-D array, * whence * = wcs.pc = *m; * * would be legitimate. * * double *cdelt * (Given) Address of the first element of an array of double containing * the coordinate increments, CDELTia. * * double *crval * (Given) Address of the first element of an array of double containing * the coordinate reference values, CRVALia. * * char (*cunit)[72] * (Given) Address of the first element of an array of char[72] containing * the CUNITia keyvalues which define the units of measurement of the * CRVALia, CDELTia, and CDi_ja keywords. * * As CUNITia is an optional header keyword, cunit[][72] may be left blank * but otherwise is expected to contain a standard units specification as * defined by WCS Paper I. Utility function wcsutrn(), described in * wcsunits.h, is available to translate commonly used non-standard units * specifications but this must be done as a separate step before invoking * wcsset(). * * For celestial axes, if cunit[][72] is not blank, wcsset() uses * wcsunits() to parse it and scale cdelt[], crval[], and cd[][*] to * degrees. It then resets cunit[][72] to "deg". * * For spectral axes, if cunit[][72] is not blank, wcsset() uses wcsunits() * to parse it and scale cdelt[], crval[], and cd[][*] to SI units. It * then resets cunit[][72] accordingly. * * wcsset() ignores cunit[][72] for other coordinate types; cunit[][72] may * be used to label coordinate values. * * These variables accomodate the longest allowed string-valued FITS * keyword, being limited to 68 characters, plus the null-terminating * character. * * char (*ctype)[72] * (Given) Address of the first element of an array of char[72] containing * the coordinate axis types, CTYPEia. * * The ctype[][72] keyword values must be in upper case and there must be * zero or one pair of matched celestial axis types, and zero or one * spectral axis. The ctype[][72] strings should be padded with blanks on * the right and null-terminated so that they are at least eight characters * in length. * * These variables accomodate the longest allowed string-valued FITS * keyword, being limited to 68 characters, plus the null-terminating * character. * * double lonpole * (Given and returned) The native longitude of the celestial pole, phi_p, * given by LONPOLEa [deg] or by PVi_2a [deg] attached to the longitude * axis which takes precedence if defined, and ... * double latpole * (Given and returned) ... the native latitude of the celestial pole, * theta_p, given by LATPOLEa [deg] or by PVi_3a [deg] attached to the * longitude axis which takes precedence if defined. * * lonpole and latpole may be left to default to values set by wcsinit() * (see celprm::ref), but in any case they will be reset by wcsset() to * the values actually used. Note therefore that if the wcsprm struct is * reused without resetting them, whether directly or via wcsinit(), they * will no longer have their default values. * * double restfrq * (Given) The rest frequency [Hz], and/or ... * double restwav * (Given) ... the rest wavelength in vacuo [m], only one of which need be * given, the other should be set to zero. * * int npv * (Given) The number of entries in the wcsprm::pv[] array. * * int npvmax * (Given or returned) The length of the wcsprm::pv[] array. * * npvmax will be set by wcsinit() if it allocates memory for wcsprm::pv[], * otherwise it must be set by the user. See also wcsnpv(). * * struct pvcard *pv * (Given) Address of the first element of an array of length npvmax of * pvcard structs. * * As a FITS header parser encounters each PVi_ma keyword it should load it * into a pvcard struct in the array and increment npv. wcsset() * interprets these as required. * * Note that, if they were not given, wcsset() resets the entries for * PVi_1a, PVi_2a, PVi_3a, and PVi_4a for longitude axis i to match * phi_0 and theta_0 (the native longitude and latitude of the reference * point), LONPOLEa and LATPOLEa respectively. * * int nps * (Given) The number of entries in the wcsprm::ps[] array. * * int npsmax * (Given or returned) The length of the wcsprm::ps[] array. * * npsmax will be set by wcsinit() if it allocates memory for wcsprm::ps[], * otherwise it must be set by the user. See also wcsnps(). * * struct pscard *ps * (Given) Address of the first element of an array of length npsmax of * pscard structs. * * As a FITS header parser encounters each PSi_ma keyword it should load it * into a pscard struct in the array and increment nps. wcsset() * interprets these as required (currently no PSi_ma keyvalues are * recognized). * * double *cd * (Given) For historical compatibility, the wcsprm struct supports two * alternate specifications of the linear transformation matrix, those * associated with the CDi_ja keywords, and ... * double *crota * (Given) ... those associated with the CROTAi keywords. Although these * may not formally co-exist with PCi_ja, the approach taken here is simply * to ignore them if given in conjunction with PCi_ja. * * int altlin * (Given) altlin is a bit flag that denotes which of the PCi_ja, CDi_ja * and CROTAi keywords are present in the header: * * - Bit 0: PCi_ja is present. * * - Bit 1: CDi_ja is present. * * Matrix elements in the IRAF convention are equivalent to the product * CDi_ja = CDELTia * PCi_ja, but the defaults differ from that of the * PCi_ja matrix. If one or more CDi_ja keywords are present then all * unspecified CDi_ja default to zero. If no CDi_ja (or CROTAi) keywords * are present, then the header is assumed to be in PCi_ja form whether * or not any PCi_ja keywords are present since this results in an * interpretation of CDELTia consistent with the original FITS * specification. * * While CDi_ja may not formally co-exist with PCi_ja, it may co-exist * with CDELTia and CROTAi which are to be ignored. * * - Bit 2: CROTAi is present. * * In the AIPS convention, CROTAi may only be associated with the * latitude axis of a celestial axis pair. It specifies a rotation in * the image plane that is applied AFTER the CDELTia; any other CROTAi * keywords are ignored. * * CROTAi may not formally co-exist with PCi_ja. * * CROTAi and CDELTia may formally co-exist with CDi_ja but if so are to * be ignored. * * - Bit 3: PCi_ja + CDELTia was derived from CDi_ja by wcspcx(). * * This bit is set by wcspcx() when it derives PCi_ja and CDELTia from * CDi_ja via an orthonormal decomposition. In particular, it signals * wcsset() not to replace PCi_ja by a copy of CDi_ja with CDELTia set * to unity. * * CDi_ja and CROTAi keywords, if found, are to be stored in the wcsprm::cd * and wcsprm::crota arrays which are dimensioned similarly to wcsprm::pc * and wcsprm::cdelt. FITS header parsers should use the following * procedure: * * - Whenever a PCi_ja keyword is encountered: altlin |= 1; * * - Whenever a CDi_ja keyword is encountered: altlin |= 2; * * - Whenever a CROTAi keyword is encountered: altlin |= 4; * * If none of these bits are set the PCi_ja representation results, i.e. * wcsprm::pc and wcsprm::cdelt will be used as given. * * These alternate specifications of the linear transformation matrix are * translated immediately to PCi_ja by wcsset() and are invisible to the * lower-level WCSLIB routines. In particular, unless bit 3 is also set, * wcsset() resets wcsprm::cdelt to unity if CDi_ja is present (and no * PCi_ja). * * If CROTAi are present but none is associated with the latitude axis * (and no PCi_ja or CDi_ja), then wcsset() reverts to a unity PCi_ja * matrix. * * int velref * (Given) AIPS velocity code VELREF, refer to spcaips(). * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::velref is changed. * * char alt[4] * (Given, auxiliary) Character code for alternate coordinate descriptions * (i.e. the 'a' in keyword names such as CTYPEia). This is blank for the * primary coordinate description, or one of the 26 upper-case letters, * A-Z. * * An array of four characters is provided for alignment purposes, only the * first is used. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::alt is changed. * * int colnum * (Given, auxiliary) Where the coordinate representation is associated * with an image-array column in a FITS binary table, this variable may be * used to record the relevant column number. * * It should be set to zero for an image header or pixel list. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::colnum is changed. * * int *colax * (Given, auxiliary) Address of the first element of an array of int * recording the column numbers for each axis in a pixel list. * * The array elements should be set to zero for an image header or image * array in a binary table. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::colax is changed. * * char (*cname)[72] * (Given, auxiliary) The address of the first element of an array of * char[72] containing the coordinate axis names, CNAMEia. * * These variables accomodate the longest allowed string-valued FITS * keyword, being limited to 68 characters, plus the null-terminating * character. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::cname is changed. * * double *crder * (Given, auxiliary) Address of the first element of an array of double * recording the random error in the coordinate value, CRDERia. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::crder is changed. * * double *csyer * (Given, auxiliary) Address of the first element of an array of double * recording the systematic error in the coordinate value, CSYERia. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::csyer is changed. * * double *czphs * (Given, auxiliary) Address of the first element of an array of double * recording the time at the zero point of a phase axis, CZPHSia. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::czphs is changed. * * double *cperi * (Given, auxiliary) Address of the first element of an array of double * recording the period of a phase axis, CPERIia. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::cperi is changed. * * char wcsname[72] * (Given, auxiliary) The name given to the coordinate representation, * WCSNAMEa. This variable accomodates the longest allowed string-valued * FITS keyword, being limited to 68 characters, plus the null-terminating * character. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::wcsname is changed. * * char timesys[72] * (Given, auxiliary) TIMESYS keyvalue, being the time scale (UTC, TAI, * etc.) in which all other time-related auxiliary header values are * recorded. Also defines the time scale for an image axis with CTYPEia * set to 'TIME'. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::timesys is changed. * * char trefpos[72] * (Given, auxiliary) TREFPOS keyvalue, being the location in space where * the recorded time is valid. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::trefpos is changed. * * char trefdir[72] * (Given, auxiliary) TREFDIR keyvalue, being the reference direction used * in calculating a pathlength delay. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::trefdir is changed. * * char plephem[72] * (Given, auxiliary) PLEPHEM keyvalue, being the Solar System ephemeris * used for calculating a pathlength delay. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::plephem is changed. * * char timeunit[72] * (Given, auxiliary) TIMEUNIT keyvalue, being the time units in which * the following header values are expressed: TSTART, TSTOP, TIMEOFFS, * TIMSYER, TIMRDER, TIMEDEL. It also provides the default value for * CUNITia for time axes. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::timeunit is changed. * * char dateref[72] * (Given, auxiliary) DATEREF keyvalue, being the date of a reference epoch * relative to which other time measurements refer. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::dateref is changed. * * double mjdref[2] * (Given, auxiliary) MJDREF keyvalue, equivalent to DATEREF expressed as * a Modified Julian Date (MJD = JD - 2400000.5). The value is given as * the sum of the two-element vector, allowing increased precision. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::mjdref is changed. * * double timeoffs * (Given, auxiliary) TIMEOFFS keyvalue, being a time offset, which may be * used, for example, to provide a uniform clock correction for times * referenced to DATEREF. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::timeoffs is changed. * * char dateobs[72] * (Given, auxiliary) DATE-OBS keyvalue, being the date at the start of the * observation unless otherwise explained in the DATE-OBS keycomment, in * ISO format, yyyy-mm-ddThh:mm:ss. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::dateobs is changed. * * char datebeg[72] * (Given, auxiliary) DATE-BEG keyvalue, being the date at the start of the * observation in ISO format, yyyy-mm-ddThh:mm:ss. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::datebeg is changed. * * char dateavg[72] * (Given, auxiliary) DATE-AVG keyvalue, being the date at a representative * mid-point of the observation in ISO format, yyyy-mm-ddThh:mm:ss. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::dateavg is changed. * * char dateend[72] * (Given, auxiliary) DATE-END keyvalue, baing the date at the end of the * observation in ISO format, yyyy-mm-ddThh:mm:ss. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::dateend is changed. * * double mjdobs * (Given, auxiliary) MJD-OBS keyvalue, equivalent to DATE-OBS expressed * as a Modified Julian Date (MJD = JD - 2400000.5). * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::mjdobs is changed. * * double mjdbeg * (Given, auxiliary) MJD-BEG keyvalue, equivalent to DATE-BEG expressed * as a Modified Julian Date (MJD = JD - 2400000.5). * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::mjdbeg is changed. * * double mjdavg * (Given, auxiliary) MJD-AVG keyvalue, equivalent to DATE-AVG expressed * as a Modified Julian Date (MJD = JD - 2400000.5). * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::mjdavg is changed. * * double mjdend * (Given, auxiliary) MJD-END keyvalue, equivalent to DATE-END expressed * as a Modified Julian Date (MJD = JD - 2400000.5). * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::mjdend is changed. * * double jepoch * (Given, auxiliary) JEPOCH keyvalue, equivalent to DATE-OBS expressed * as a Julian epoch. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::jepoch is changed. * * double bepoch * (Given, auxiliary) BEPOCH keyvalue, equivalent to DATE-OBS expressed * as a Besselian epoch * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::bepoch is changed. * * double tstart * (Given, auxiliary) TSTART keyvalue, equivalent to DATE-BEG expressed * as a time in units of TIMEUNIT relative to DATEREF+TIMEOFFS. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::tstart is changed. * * double tstop * (Given, auxiliary) TSTOP keyvalue, equivalent to DATE-END expressed * as a time in units of TIMEUNIT relative to DATEREF+TIMEOFFS. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::tstop is changed. * * double xposure * (Given, auxiliary) XPOSURE keyvalue, being the effective exposure time * in units of TIMEUNIT. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::xposure is changed. * * double telapse * (Given, auxiliary) TELAPSE keyvalue, equivalent to the elapsed time * between DATE-BEG and DATE-END, in units of TIMEUNIT. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::telapse is changed. * * double timsyer * (Given, auxiliary) TIMSYER keyvalue, being the absolute error of the * time values, in units of TIMEUNIT. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::timsyer is changed. * * double timrder * (Given, auxiliary) TIMRDER keyvalue, being the accuracy of time stamps * relative to each other, in units of TIMEUNIT. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::timrder is changed. * * double timedel * (Given, auxiliary) TIMEDEL keyvalue, being the resolution of the time * stamps. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::timedel is changed. * * double timepixr * (Given, auxiliary) TIMEPIXR keyvalue, being the relative position of the * time stamps in binned time intervals, a value between 0.0 and 1.0. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::timepixr is changed. * * double obsgeo[6] * (Given, auxiliary) Location of the observer in a standard terrestrial * reference frame. The first three give ITRS Cartesian coordinates * OBSGEO-X [m], OBSGEO-Y [m], OBSGEO-Z [m], and the second three give * OBSGEO-L [deg], OBSGEO-B [deg], OBSGEO-H [m], which are related through * a standard transformation. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::obsgeo is changed. * * char obsorbit[72] * (Given, auxiliary) OBSORBIT keyvalue, being the URI, URL, or name of an * orbit ephemeris file giving spacecraft coordinates relating to TREFPOS. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::obsorbit is changed. * * char radesys[72] * (Given, auxiliary) The equatorial or ecliptic coordinate system type, * RADESYSa. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::radesys is changed. * * double equinox * (Given, auxiliary) The equinox associated with dynamical equatorial or * ecliptic coordinate systems, EQUINOXa (or EPOCH in older headers). Not * applicable to ICRS equatorial or ecliptic coordinates. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::equinox is changed. * * char specsys[72] * (Given, auxiliary) Spectral reference frame (standard of rest), * SPECSYSa. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::specsys is changed. * * char ssysobs[72] * (Given, auxiliary) The spectral reference frame in which there is no * differential variation in the spectral coordinate across the * field-of-view, SSYSOBSa. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::ssysobs is changed. * * double velosys * (Given, auxiliary) The relative radial velocity [m/s] between the * observer and the selected standard of rest in the direction of the * celestial reference coordinate, VELOSYSa. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::velosys is changed. * * double zsource * (Given, auxiliary) The redshift, ZSOURCEa, of the source. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::zsource is changed. * * char ssyssrc[72] * (Given, auxiliary) The spectral reference frame (standard of rest), * SSYSSRCa, in which wcsprm::zsource was measured. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::ssyssrc is changed. * * double velangl * (Given, auxiliary) The angle [deg] that should be used to decompose an * observed velocity into radial and transverse components. * * It is not necessary to reset the wcsprm struct (via wcsset()) when * wcsprm::velangl is changed. * * struct auxprm *aux * (Given, auxiliary) This struct holds auxiliary coordinate system * information of a specialist nature. While these parameters may be * widely recognized within particular fields of astronomy, they differ * from the above auxiliary parameters in not being defined by any of the * FITS WCS standards. Collecting them together in a separate struct that * is allocated only when required helps to control bloat in the size of * the wcsprm struct. * * int ntab * (Given) See wcsprm::tab. * * int nwtb * (Given) See wcsprm::wtb. * * struct tabprm *tab * (Given) Address of the first element of an array of ntab tabprm structs * for which memory has been allocated. These are used to store tabular * transformation parameters. * * Although technically wcsprm::ntab and tab are "given", they will * normally be set by invoking wcstab(), whether directly or indirectly. * * The tabprm structs contain some members that must be supplied and others * that are derived. The information to be supplied comes primarily from * arrays stored in one or more FITS binary table extensions. These * arrays, referred to here as "wcstab arrays", are themselves located by * parameters stored in the FITS image header. * * struct wtbarr *wtb * (Given) Address of the first element of an array of nwtb wtbarr structs * for which memory has been allocated. These are used in extracting * wcstab arrays from a FITS binary table. * * Although technically wcsprm::nwtb and wtb are "given", they will * normally be set by invoking wcstab(), whether directly or indirectly. * * char lngtyp[8] * (Returned) Four-character WCS celestial longitude and ... * char lattyp[8] * (Returned) ... latitude axis types. e.g. "RA", "DEC", "GLON", "GLAT", * etc. extracted from 'RA--', 'DEC-', 'GLON', 'GLAT', etc. in the first * four characters of CTYPEia but with trailing dashes removed. (Declared * as char[8] for alignment reasons.) * * int lng * (Returned) Index for the longitude coordinate, and ... * int lat * (Returned) ... index for the latitude coordinate, and ... * int spec * (Returned) ... index for the spectral coordinate in the imgcrd[][] and * world[][] arrays in the API of wcsp2s(), wcss2p() and wcsmix(). * * These may also serve as indices into the pixcrd[][] array provided that * the PCi_ja matrix does not transpose axes. * * int cubeface * (Returned) Index into the pixcrd[][] array for the CUBEFACE axis. This * is used for quadcube projections where the cube faces are stored on a * separate axis (see wcs.h). * * int *types * (Returned) Address of the first element of an array of int containing a * four-digit type code for each axis. * * - First digit (i.e. 1000s): * - 0: Non-specific coordinate type. * - 1: Stokes coordinate. * - 2: Celestial coordinate (including CUBEFACE). * - 3: Spectral coordinate. * * - Second digit (i.e. 100s): * - 0: Linear axis. * - 1: Quantized axis (STOKES, CUBEFACE). * - 2: Non-linear celestial axis. * - 3: Non-linear spectral axis. * - 4: Logarithmic axis. * - 5: Tabular axis. * * - Third digit (i.e. 10s): * - 0: Group number, e.g. lookup table number, being an index into the * tabprm array (see above). * * - The fourth digit is used as a qualifier depending on the axis type. * * - For celestial axes: * - 0: Longitude coordinate. * - 1: Latitude coordinate. * - 2: CUBEFACE number. * * - For lookup tables: the axis number in a multidimensional table. * * CTYPEia in "4-3" form with unrecognized algorithm code will have its * type set to -1 and generate an error. * * struct linprm lin * (Returned) Linear transformation parameters (usage is described in the * prologue to lin.h). * * struct celprm cel * (Returned) Celestial transformation parameters (usage is described in * the prologue to cel.h). * * struct spcprm spc * (Returned) Spectral transformation parameters (usage is described in the * prologue to spc.h). * * struct wcserr *err * (Returned) If enabled, when an error status is returned, this struct * contains detailed information about the error, see wcserr_enable(). * * int m_flag * (For internal use only.) * int m_naxis * (For internal use only.) * double *m_crpix * (For internal use only.) * double *m_pc * (For internal use only.) * double *m_cdelt * (For internal use only.) * double *m_crval * (For internal use only.) * char (*m_cunit)[72] * (For internal use only.) * char (*m_ctype)[72] * (For internal use only.) * struct pvcard *m_pv * (For internal use only.) * struct pscard *m_ps * (For internal use only.) * double *m_cd * (For internal use only.) * double *m_crota * (For internal use only.) * int *m_colax * (For internal use only.) * char (*m_cname)[72] * (For internal use only.) * double *m_crder * (For internal use only.) * double *m_csyer * (For internal use only.) * double *m_czphs * (For internal use only.) * double *m_cperi * (For internal use only.) * struct tabprm *m_tab * (For internal use only.) * struct wtbarr *m_wtb * (For internal use only.) * * * pvcard struct - Store for PVi_ma keyrecords * ------------------------------------------- * The pvcard struct is used to pass the parsed contents of PVi_ma keyrecords * to wcsset() via the wcsprm struct. * * All members of this struct are to be set by the user. * * int i * (Given) Axis number (1-relative), as in the FITS PVi_ma keyword. If * i == 0, wcsset() will replace it with the latitude axis number. * * int m * (Given) Parameter number (non-negative), as in the FITS PVi_ma keyword. * * double value * (Given) Parameter value. * * * pscard struct - Store for PSi_ma keyrecords * ------------------------------------------- * The pscard struct is used to pass the parsed contents of PSi_ma keyrecords * to wcsset() via the wcsprm struct. * * All members of this struct are to be set by the user. * * int i * (Given) Axis number (1-relative), as in the FITS PSi_ma keyword. * * int m * (Given) Parameter number (non-negative), as in the FITS PSi_ma keyword. * * char value[72] * (Given) Parameter value. * * * auxprm struct - Additional auxiliary parameters * ----------------------------------------------- * The auxprm struct holds auxiliary coordinate system information of a * specialist nature. It is anticipated that this struct will expand in future * to accomodate additional parameters. * * All members of this struct are to be set by the user. * * double rsun_ref * (Given, auxiliary) Reference radius of the Sun used in coordinate * calculations (m). * * double dsun_obs * (Given, auxiliary) Distance between the centre of the Sun and the * observer (m). * * double crln_obs * (Given, auxiliary) Carrington heliographic longitude of the observer * (deg). * * double hgln_obs * (Given, auxiliary) Stonyhurst heliographic longitude of the observer * (deg). * * double hglt_obs * (Given, auxiliary) Heliographic latitude (Carrington or Stonyhurst) of * the observer (deg). * * * Global variable: const char *wcs_errmsg[] - Status return messages * ------------------------------------------------------------------ * Error messages to match the status value returned from each function. * *===========================================================================*/ #ifndef WCSLIB_WCS #define WCSLIB_WCS #include "lin.h" #include "cel.h" #include "spc.h" #ifdef __cplusplus extern "C" { #define wtbarr wtbarr_s // See prologue of wtbarr.h. #endif #define WCSSUB_LONGITUDE 0x1001 #define WCSSUB_LATITUDE 0x1002 #define WCSSUB_CUBEFACE 0x1004 #define WCSSUB_CELESTIAL 0x1007 #define WCSSUB_SPECTRAL 0x1008 #define WCSSUB_STOKES 0x1010 #define WCSCOMPARE_ANCILLARY 0x0001 #define WCSCOMPARE_TILING 0x0002 #define WCSCOMPARE_CRPIX 0x0004 extern const char *wcs_errmsg[]; enum wcs_errmsg_enum { WCSERR_SUCCESS = 0, // Success. WCSERR_NULL_POINTER = 1, // Null wcsprm pointer passed. WCSERR_MEMORY = 2, // Memory allocation failed. WCSERR_SINGULAR_MTX = 3, // Linear transformation matrix is singular. WCSERR_BAD_CTYPE = 4, // Inconsistent or unrecognized coordinate // axis type. WCSERR_BAD_PARAM = 5, // Invalid parameter value. WCSERR_BAD_COORD_TRANS = 6, // Unrecognized coordinate transformation // parameter. WCSERR_ILL_COORD_TRANS = 7, // Ill-conditioned coordinate transformation // parameter. WCSERR_BAD_PIX = 8, // One or more of the pixel coordinates were // invalid. WCSERR_BAD_WORLD = 9, // One or more of the world coordinates were // invalid. WCSERR_BAD_WORLD_COORD = 10, // Invalid world coordinate. WCSERR_NO_SOLUTION = 11, // No solution found in the specified // interval. WCSERR_BAD_SUBIMAGE = 12, // Invalid subimage specification. WCSERR_NON_SEPARABLE = 13, // Non-separable subimage coordinate system. WCSERR_UNSET = 14 // wcsprm struct is unset. }; // Struct used for storing PVi_ma keywords. struct pvcard { int i; // Axis number, as in PVi_ma (1-relative). int m; // Parameter number, ditto (0-relative). double value; // Parameter value. }; // Size of the pvcard struct in int units, used by the Fortran wrappers. #define PVLEN (sizeof(struct pvcard)/sizeof(int)) // Struct used for storing PSi_ma keywords. struct pscard { int i; // Axis number, as in PSi_ma (1-relative). int m; // Parameter number, ditto (0-relative). char value[72]; // Parameter value. }; // Size of the pscard struct in int units, used by the Fortran wrappers. #define PSLEN (sizeof(struct pscard)/sizeof(int)) // Struct used to hold additional auxiliary parameters. struct auxprm { double rsun_ref; // Solar radius. double dsun_obs; // Distance from Sun centre to observer. double crln_obs; // Carrington heliographic lng of observer. double hgln_obs; // Stonyhurst heliographic lng of observer. double hglt_obs; // Heliographic latitude of observer. }; // Size of the auxprm struct in int units, used by the Fortran wrappers. #define AUXLEN (sizeof(struct auxprm)/sizeof(int)) struct wcsprm { // Initialization flag (see the prologue above). //-------------------------------------------------------------------------- int flag; // Set to zero to force initialization. // FITS header keyvalues to be provided (see the prologue above). //-------------------------------------------------------------------------- int naxis; // Number of axes (pixel and coordinate). double *crpix; // CRPIXja keyvalues for each pixel axis. double *pc; // PCi_ja linear transformation matrix. double *cdelt; // CDELTia keyvalues for each coord axis. double *crval; // CRVALia keyvalues for each coord axis. char (*cunit)[72]; // CUNITia keyvalues for each coord axis. char (*ctype)[72]; // CTYPEia keyvalues for each coord axis. double lonpole; // LONPOLEa keyvalue. double latpole; // LATPOLEa keyvalue. double restfrq; // RESTFRQa keyvalue. double restwav; // RESTWAVa keyvalue. int npv; // Number of PVi_ma keywords, and the int npvmax; // number for which space was allocated. struct pvcard *pv; // PVi_ma keywords for each i and m. int nps; // Number of PSi_ma keywords, and the int npsmax; // number for which space was allocated. struct pscard *ps; // PSi_ma keywords for each i and m. // Alternative header keyvalues (see the prologue above). //-------------------------------------------------------------------------- double *cd; // CDi_ja linear transformation matrix. double *crota; // CROTAi keyvalues for each coord axis. int altlin; // Alternative representations // Bit 0: PCi_ja is present, // Bit 1: CDi_ja is present, // Bit 2: CROTAi is present. int velref; // AIPS velocity code, VELREF. // Auxiliary coordinate system information of a general nature. Not // used by WCSLIB. Refer to the prologue comments above for a brief // explanation of these values. char alt[4]; int colnum; int *colax; // Auxiliary coordinate axis information. char (*cname)[72]; double *crder; double *csyer; double *czphs; double *cperi; char wcsname[72]; // Time reference system and measurement. char timesys[72], trefpos[72], trefdir[72], plephem[72]; char timeunit[72]; char dateref[72]; double mjdref[2]; double timeoffs; // Data timestamps and durations. char dateobs[72], datebeg[72], dateavg[72], dateend[72]; double mjdobs, mjdbeg, mjdavg, mjdend; double jepoch, bepoch; double tstart, tstop; double xposure, telapse; // Timing accuracy. double timsyer, timrder; double timedel, timepixr; // Spatial & celestial reference frame. double obsgeo[6]; char obsorbit[72]; char radesys[72]; double equinox; char specsys[72]; char ssysobs[72]; double velosys; double zsource; char ssyssrc[72]; double velangl; // Additional auxiliary coordinate system information of a specialist // nature. Not used by WCSLIB. Refer to the prologue comments above. struct auxprm *aux; // Coordinate lookup tables (see the prologue above). //-------------------------------------------------------------------------- int ntab; // Number of separate tables. int nwtb; // Number of wtbarr structs. struct tabprm *tab; // Tabular transformation parameters. struct wtbarr *wtb; // Array of wtbarr structs. //-------------------------------------------------------------------------- // Information derived from the FITS header keyvalues by wcsset(). //-------------------------------------------------------------------------- char lngtyp[8], lattyp[8]; // Celestial axis types, e.g. RA, DEC. int lng, lat, spec; // Longitude, latitude and spectral axis // indices (0-relative). int cubeface; // True if there is a CUBEFACE axis. int *types; // Coordinate type codes for each axis. struct linprm lin; // Linear transformation parameters. struct celprm cel; // Celestial transformation parameters. struct spcprm spc; // Spectral transformation parameters. //-------------------------------------------------------------------------- // THE REMAINDER OF THE WCSPRM STRUCT IS PRIVATE. //-------------------------------------------------------------------------- // Error handling, if enabled. //-------------------------------------------------------------------------- struct wcserr *err; // Memory management. //-------------------------------------------------------------------------- int m_flag, m_naxis; double *m_crpix, *m_pc, *m_cdelt, *m_crval; char (*m_cunit)[72], (*m_ctype)[72]; struct pvcard *m_pv; struct pscard *m_ps; double *m_cd, *m_crota; int *m_colax; char (*m_cname)[72]; double *m_crder, *m_csyer, *m_czphs, *m_cperi; struct auxprm *m_aux; struct tabprm *m_tab; struct wtbarr *m_wtb; }; // Size of the wcsprm struct in int units, used by the Fortran wrappers. #define WCSLEN (sizeof(struct wcsprm)/sizeof(int)) int wcsnpv(int n); int wcsnps(int n); int wcsini(int alloc, int naxis, struct wcsprm *wcs); int wcsinit(int alloc, int naxis, struct wcsprm *wcs, int npvmax, int npsmax, int ndpmax); int wcsauxi(int alloc, struct wcsprm *wcs); int wcssub(int alloc, const struct wcsprm *wcssrc, int *nsub, int axes[], struct wcsprm *wcsdst); int wcscompare(int cmp, double tol, const struct wcsprm *wcs1, const struct wcsprm *wcs2, int *equal); int wcsfree(struct wcsprm *wcs); int wcstrim(struct wcsprm *wcs); int wcssize(const struct wcsprm *wcs, int sizes[2]); int auxsize(const struct auxprm *aux, int sizes[2]); int wcsprt(const struct wcsprm *wcs); int wcsperr(const struct wcsprm *wcs, const char *prefix); int wcsbchk(struct wcsprm *wcs, int bounds); int wcsset(struct wcsprm *wcs); int wcsp2s(struct wcsprm *wcs, int ncoord, int nelem, const double pixcrd[], double imgcrd[], double phi[], double theta[], double world[], int stat[]); int wcss2p(struct wcsprm *wcs, int ncoord, int nelem, const double world[], double phi[], double theta[], double imgcrd[], double pixcrd[], int stat[]); int wcsmix(struct wcsprm *wcs, int mixpix, int mixcel, const double vspan[2], double vstep, int viter, double world[], double phi[], double theta[], double imgcrd[], double pixcrd[]); int wcsccs(struct wcsprm *wcs, double lng2p1, double lat2p1, double lng1p2, const char *clng, const char *clat, const char *radesys, double equinox, const char *alt); int wcssptr(struct wcsprm *wcs, int *i, char ctype[9]); const char* wcslib_version(int vers[3]); // Defined mainly for backwards compatibility, use wcssub() instead. #define wcscopy(alloc, wcssrc, wcsdst) wcssub(alloc, wcssrc, 0x0, 0x0, wcsdst) // Deprecated. #define wcsini_errmsg wcs_errmsg #define wcssub_errmsg wcs_errmsg #define wcscopy_errmsg wcs_errmsg #define wcsfree_errmsg wcs_errmsg #define wcsprt_errmsg wcs_errmsg #define wcsset_errmsg wcs_errmsg #define wcsp2s_errmsg wcs_errmsg #define wcss2p_errmsg wcs_errmsg #define wcsmix_errmsg wcs_errmsg #ifdef __cplusplus #undef wtbarr } #endif #endif // WCSLIB_WCS ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/wcsbth.l0000644000175100001710000023046400000000000017042 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcsbth.l,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * wcsbth.l is a Flex description file containing the definition of a lexical * scanner for parsing the WCS keyrecords for one or more image arrays and/or * pixel lists in a FITS binary table header. It can also handle primary image * and image extension headers. * * wcsbth.l requires Flex v2.5.4 or later. Refer to wcshdr.h for a description * of the user interface and operating notes. * * Implementation notes * -------------------- * wcsbth() may be invoked with an option that causes it to recognize the * image-header form of WCS keywords as defaults for each alternate coordinate * representation (up to 27). By design, with this option enabled wcsbth() can * also handle primary image and image extension headers, effectively treating * them as a single-column binary table though with WCS keywords of a different * form. * * NAXIS is always 2 for binary tables, it refers to the two-dimensional nature * of the table. Thus NAXIS does not count the number of image axes in either * image arrays or pixels lists and for the latter there is not even a formal * equivalent of WCSAXESa. Hence NAXIS is always ignored and a first pass * through the header is required to determine the number of images, the number * of alternate coordinate representations for each image (up to 27), and the * number of coordinate axes in each representation; this pass also counts the * number of iPVn_ma and iPSn_ma or TVk_ma and TSk_ma keywords in each * representation. * * On completion of the first pass, the association between column number and * axis number is defined for each representation of a pixel list. Memory is * allocated for an array of the required number of wcsprm structs and each of * these is initialized appropriately. These structs are filled in the second * pass. * * It is permissible for a scalar table column to contain degenerate (single- * point) image arrays and simultaneously form one axis of a pixel list. * * The parser does not check for duplicated keywords, for most keywords it * accepts the last encountered. * * wcsbth() does not currently handle the Green Bank convention. * *===========================================================================*/ /* Options. */ %option full %option never-interactive %option noinput %option noyywrap %option outfile="wcsbth.c" %option prefix="wcsbth" %option reentrant %option extra-type="struct wcsbth_extra *" /* Indices for parameterized keywords. */ Z1 [0-9] Z2 [0-9]{2} Z3 [0-9]{3} Z4 [0-9]{4} I1 [1-9] I2 [1-9][0-9] I3 [1-9][0-9]{2} I4 [1-9][0-9]{3} /* Alternate coordinate system identifier. */ ALT [ A-Z] /* Keyvalue data types. */ INTEGER [+-]?[0-9]+ FLOAT [+-]?([0-9]+\.?[0-9]*|\.[0-9]+)([eEdD][+-]?[0-9]+)? STRING '([^']|'')*' /* Inline comment syntax. */ INLINE " "*(\/.*)? /* Exclusive start states. */ %x CCCCCia iCCCna iCCCCn TCCCna TCCCCn %x CCi_ja ijCCna TCn_ka TCCn_ka %x CROTAi iCROTn TCROTn %x CCi_ma iCn_ma iCCn_ma TCn_ma TCCn_ma %x PROJPm %x CCCCCCCC CCCCCCCa %x CCCCna CCCCCna %x CCCCn CCCCCn %x VALUE INTEGER_VAL FLOAT_VAL FLOAT2_VAL STRING_VAL %x COMMENT DISCARD ERROR FLUSH %{ #include #include #include #include #include #include #include "wcs.h" #include "wcshdr.h" #include "wcsmath.h" #include "wcsprintf.h" #include "wcsutil.h" // Codes used for keyvalue data types. #define INTEGER 0 #define FLOAT 1 #define FLOAT2 2 #define STRING 3 // Bit masks used for keyword types: #define IMGAUX 0x1 // Auxiliary image header, e.g. LONPOLEa or // DATE-OBS. #define IMGAXIS 0x2 // Image header with axis number, e.g. // CTYPEia. #define IMGHEAD 0x3 // IMGAUX | IMGAXIS, i.e. image header of // either type. #define BIMGARR 0x4 // Binary table image array, e.g. iCTYna. #define PIXLIST 0x8 // Pixel list, e.g. TCTYna. #define BINTAB 0xC // BIMGARR | PIXLIST, i.e. binary table // image array (without axis number) or // pixel list, e.g. LONPna or OBSGXn. // User data associated with yyscanner. struct wcsbth_extra { // Values passed to YY_INPUT. char *hdr; int nkeyrec; // Used in preempting the call to exit() by yy_fatal_error(). jmp_buf abort_jmp_env; }; #define YY_DECL int wcsbth_scanner(char *header, int nkeyrec, int relax, \ int ctrl, int keysel, int *colsel, int *nreject, int *nwcs, \ struct wcsprm **wcs, yyscan_t yyscanner) #define YY_INPUT(inbuff, count, bufsize) \ { \ if (yyextra->nkeyrec) { \ strncpy(inbuff, yyextra->hdr, 80); \ inbuff[80] = '\n'; \ yyextra->hdr += 80; \ yyextra->nkeyrec--; \ count = 81; \ } else { \ count = YY_NULL; \ } \ } // Preempt the call to exit() by yy_fatal_error(). #define exit(status) longjmp(yyextra->abort_jmp_env, status); // A convenience macro to get around incompatibilities between unput() and // yyless(): put yytext followed by a blank back onto the input stream. #define WCSBTH_PUTBACK \ sprintf(strtmp, "%s ", yytext); \ size_t iz = strlen(strtmp); \ while (iz) unput(strtmp[--iz]); // Struct used internally for header bookkeeping. struct wcsbth_alts { int ncol, ialt, icol, imgherit; short int (*arridx)[27]; short int pixidx[27]; short int pad1; unsigned int *pixlist; unsigned char (*npv)[27]; unsigned char (*nps)[27]; unsigned char pixnpv[27]; unsigned char pixnps[27]; unsigned char pad2[2]; }; // Internal helper functions. static YY_DECL; static int wcsbth_colax(struct wcsprm *wcs, struct wcsbth_alts *alts, int k, char a); static int wcsbth_final(struct wcsbth_alts *alts, int *nwcs, struct wcsprm **wcs); static struct wcsprm *wcsbth_idx(struct wcsprm *wcs, struct wcsbth_alts *alts, int keytype, int n, char a); static int wcsbth_init1(struct wcsbth_alts *alts, int auxprm, int *nwcs, struct wcsprm **wcs); static int wcsbth_pass1(int keytype, int i, int j, int n, int k, char a, char ptype, struct wcsbth_alts *alts); // Helper functions for keywords that require special handling. static int wcsbth_jdref(double *wptr, const double *jdref); static int wcsbth_jdrefi(double *wptr, const double *jdrefi); static int wcsbth_jdreff(double *wptr, const double *jdreff); static int wcsbth_epoch(double *wptr, const double *epoch); static int wcsbth_vsource(double *wptr, const double *vsource); // Helper functions for keyvalue validity checking. static int wcsbth_timepixr(double timepixr); %} %% char *errmsg, errtxt[80], *keyname, strtmp[80]; int inttmp; double dbltmp, dbl2tmp[2]; struct auxprm auxtem; struct wcsprm wcstem; // Initialize returned values. *nreject = 0; *nwcs = 0; *wcs = 0x0; // Our handle on the input stream. char *keyrec = header; char *hptr = header; char *keep = 0x0; // For keeping tallies of keywords found. int nvalid = 0; int nother = 0; // Used to flag image header keywords that are always inherited. int imherit = 1; // If strict, then also reject. if (relax & WCSHDR_strict) relax |= WCSHDR_reject; // Keyword indices, as used in the WCS papers, e.g. iVn_ma, TPn_ka. int i = 0; int j = 0; int k = 0; int n = 0; int m = 0; char a = ' '; // Header bookkeeping. struct wcsbth_alts alts; alts.ncol = 0; alts.arridx = 0x0; alts.pixlist = 0x0; alts.npv = 0x0; alts.nps = 0x0; for (int ialt = 0; ialt < 27; ialt++) { alts.pixidx[ialt] = 0; alts.pixnpv[ialt] = 0; alts.pixnps[ialt] = 0; } // For decoding the keyvalue. int keytype = 0; int valtype = -1; void *vptr = 0x0; // For keywords that require special handling. int altlin = 0; char ptype = ' '; int (*chekval)(double) = 0x0; int (*special)(double *, const double *) = 0x0; struct auxprm *auxp = 0x0; int auxprm = 0; int naux = 0; // Selection by column number. int nsel = colsel ? colsel[0] : 0; int incl = (nsel > 0); char exclude[1000]; for (int icol = 0; icol < 1000; icol++) { exclude[icol] = incl; } for (int icol = 1; icol <= abs(nsel); icol++) { int itmp = colsel[icol]; if (0 < itmp && itmp < 1000) { exclude[itmp] = !incl; } } exclude[0] = 0; // Selection by keyword type. if (keysel) { int itmp = keysel; keysel = 0; if (itmp & WCSHDR_IMGHEAD) keysel |= IMGHEAD; if (itmp & WCSHDR_BIMGARR) keysel |= BIMGARR; if (itmp & WCSHDR_PIXLIST) keysel |= PIXLIST; } if (keysel == 0) { keysel = IMGHEAD | BINTAB; } // Control variables. int ipass = 1; int npass = 2; // User data associated with yyscanner. yyextra->hdr = header; yyextra->nkeyrec = nkeyrec; // Return here via longjmp() invoked by yy_fatal_error(). if (setjmp(yyextra->abort_jmp_env)) { return WCSHDRERR_PARSER; } BEGIN(INITIAL); ^TFIELDS" = "" "*{INTEGER} { if (ipass == 1) { if (alts.ncol == 0) { sscanf(yytext, "TFIELDS = %d", &(alts.ncol)); BEGIN(FLUSH); } else { errmsg = "duplicate or out-of-sequence TFIELDS keyword"; BEGIN(ERROR); } } else { BEGIN(FLUSH); } } ^WCSAXES{ALT}=" "" "*{INTEGER} { if (!(keysel & IMGAXIS)) { // Ignore this key type. BEGIN(DISCARD); } else { if (relax & WCSHDR_ALLIMG) { sscanf(yytext, "WCSAXES%c= %d", &a, &i); if (i < 0) { errmsg = "negative value of WCSAXESa ignored"; BEGIN(ERROR); } else { valtype = INTEGER; vptr = 0x0; keyname = "WCSAXESa"; keytype = IMGAXIS; BEGIN(COMMENT); } } else if (relax & WCSHDR_reject) { errmsg = "image-header keyword WCSAXESa in binary table"; BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } } ^WCAX{I1}{ALT}" = "" "*{INTEGER} | ^WCAX{I2}{ALT}" = "" "*{INTEGER} | ^WCAX{I3}{ALT}"= "" "*{INTEGER} { keyname = "WCAXna"; // Note that a blank in the sscanf() format string matches zero or // more of them in the input. sscanf(yytext, "WCAX%d%c = %d", &n, &a, &i); if (!(keysel & BIMGARR) || exclude[n]) { // Ignore this key type or column. BEGIN(DISCARD); } else if (i < 0) { errmsg = "negative value of WCSAXESa ignored"; BEGIN(ERROR); } else { valtype = INTEGER; vptr = 0x0; keyname = "WCAXna"; keytype = IMGAXIS; BEGIN(COMMENT); } } ^WCST{I1}{ALT}" = "" "*{STRING} | ^WCST{I2}{ALT}" = "" "*{STRING} | ^WCST{I3}{ALT}"= "" "*{STRING} { // Cross-reference supplier. keyname = "WCSTna"; errmsg = "cross-references are not implemented"; BEGIN(ERROR); } ^WCSX{I1}{ALT}" = "" "*{STRING} | ^WCSX{I2}{ALT}" = "" "*{STRING} | ^WCSX{I3}{ALT}"= "" "*{STRING} { // Cross-reference consumer. keyname = "WCSXna"; errmsg = "cross-references are not implemented"; BEGIN(ERROR); } ^CRPIX { valtype = FLOAT; vptr = &(wcstem.crpix); keyname = "CRPIXja"; BEGIN(CCCCCia); } ^{I1}CRP | ^{I1}CRPX { valtype = FLOAT; vptr = &(wcstem.crpix); sscanf(yytext, "%d", &i); if (yyleng == 4) { keyname = "jCRPna"; BEGIN(iCCCna); } else { keyname = "jCRPXn"; BEGIN(iCCCCn); } } ^TCRP | ^TCRPX { valtype = FLOAT; vptr = &(wcstem.crpix); if (yyleng == 4) { keyname = "TCRPna"; BEGIN(TCCCna); } else { keyname = "TCRPXn"; BEGIN(TCCCCn); } } ^PC { valtype = FLOAT; vptr = &(wcstem.pc); altlin = 1; keyname = "PCi_ja"; BEGIN(CCi_ja); } ^{I2}PC { valtype = FLOAT; vptr = &(wcstem.pc); altlin = 1; sscanf(yytext, "%1d%1d", &i, &j); keyname = "ijPCna"; BEGIN(ijCCna); } ^TP | ^TPC { valtype = FLOAT; vptr = &(wcstem.pc); altlin = 1; if (yyleng == 2) { keyname = "TPn_ka"; BEGIN(TCn_ka); } else { keyname = "TPCn_ka"; BEGIN(TCCn_ka); } } ^CD { valtype = FLOAT; vptr = &(wcstem.cd); altlin = 2; keyname = "CDi_ja"; BEGIN(CCi_ja); } ^{I2}CD { valtype = FLOAT; vptr = &(wcstem.cd); altlin = 2; sscanf(yytext, "%1d%1d", &i, &j); keyname = "ijCDna"; BEGIN(ijCCna); } ^TC | ^TCD { valtype = FLOAT; vptr = &(wcstem.cd); altlin = 2; if (yyleng == 2) { keyname = "TCn_ka"; BEGIN(TCn_ka); } else { keyname = "TCDn_ka"; BEGIN(TCCn_ka); } } ^CDELT { valtype = FLOAT; vptr = &(wcstem.cdelt); keyname = "CDELTia"; BEGIN(CCCCCia); } ^{I1}CDE | ^{I1}CDLT { valtype = FLOAT; vptr = &(wcstem.cdelt); sscanf(yytext, "%d", &i); if (yyleng == 4) { keyname = "iCDEna"; BEGIN(iCCCna); } else { keyname = "iCDLTn"; BEGIN(iCCCCn); } } ^TCDE | ^TCDLT { valtype = FLOAT; vptr = &(wcstem.cdelt); if (yyleng == 4) { keyname = "TCDEna"; BEGIN(TCCCna); } else { keyname = "TCDLTn"; BEGIN(TCCCCn); } } ^CROTA { valtype = FLOAT; vptr = &(wcstem.crota); altlin = 4; keyname = "CROTAi"; BEGIN(CROTAi); } ^{I1}CROT { valtype = FLOAT; vptr = &(wcstem.crota); altlin = 4; sscanf(yytext, "%d", &i); keyname = "iCROTn"; BEGIN(iCROTn); } ^TCROT { valtype = FLOAT; vptr = &(wcstem.crota); altlin = 4; keyname = "TCROTn"; BEGIN(TCROTn); } ^CUNIT { valtype = STRING; vptr = &(wcstem.cunit); keyname = "CUNITia"; BEGIN(CCCCCia); } ^{I1}CUN | ^{I1}CUNI { valtype = STRING; vptr = &(wcstem.cunit); sscanf(yytext, "%d", &i); if (yyleng == 4) { keyname = "iCUNna"; BEGIN(iCCCna); } else { keyname = "iCUNIn"; BEGIN(iCCCCn); } } ^TCUN | ^TCUNI { valtype = STRING; vptr = &(wcstem.cunit); if (yyleng == 4) { keyname = "TCUNna"; BEGIN(TCCCna); } else { keyname = "TCUNIn"; BEGIN(TCCCCn); } } ^CTYPE { valtype = STRING; vptr = &(wcstem.ctype); keyname = "CTYPEia"; BEGIN(CCCCCia); } ^{I1}CTY | ^{I1}CTYP { valtype = STRING; vptr = &(wcstem.ctype); sscanf(yytext, "%d", &i); if (yyleng == 4) { keyname = "iCTYna"; BEGIN(iCCCna); } else { keyname = "iCTYPn"; BEGIN(iCCCCn); } } ^TCTY | ^TCTYP { valtype = STRING; vptr = &(wcstem.ctype); if (yyleng == 4) { keyname = "TCTYna"; BEGIN(TCCCna); } else { keyname = "TCTYPn"; BEGIN(TCCCCn); } } ^CRVAL { valtype = FLOAT; vptr = &(wcstem.crval); keyname = "CRVALia"; BEGIN(CCCCCia); } ^{I1}CRV | ^{I1}CRVL { valtype = FLOAT; vptr = &(wcstem.crval); sscanf(yytext, "%d", &i); if (yyleng == 4) { keyname = "iCRVna"; BEGIN(iCCCna); } else { keyname = "iCRVLn"; BEGIN(iCCCCn); } } ^TCRV | ^TCRVL { valtype = FLOAT; vptr = &(wcstem.crval); if (yyleng == 4) { keyname = "TCRVna"; BEGIN(TCCCna); } else { keyname = "TCRVLn"; BEGIN(TCCCCn); } } ^LONPOLE | ^LONP { valtype = FLOAT; vptr = &(wcstem.lonpole); if (yyleng == 7) { keyname = "LONPOLEa"; imherit = 0; BEGIN(CCCCCCCa); } else { keyname = "LONPna"; BEGIN(CCCCna); } } ^LATPOLE | ^LATP { valtype = FLOAT; vptr = &(wcstem.latpole); if (yyleng == 7) { keyname = "LATPOLEa"; imherit = 0; BEGIN(CCCCCCCa); } else { keyname = "LATPna"; BEGIN(CCCCna); } } ^RESTFREQ | ^RESTFRQ | ^RFRQ { valtype = FLOAT; vptr = &(wcstem.restfrq); if (yyleng == 8) { if (relax & WCSHDR_strict) { errmsg = "the RESTFREQ keyword is deprecated, use RESTFRQa"; BEGIN(ERROR); } else { unput(' '); keyname = "RESTFREQ"; BEGIN(CCCCCCCa); } } else if (yyleng == 7) { keyname = "RESTFRQa"; BEGIN(CCCCCCCa); } else { keyname = "RFRQna"; BEGIN(CCCCna); } } ^RESTWAV | ^RWAV { valtype = FLOAT; vptr = &(wcstem.restwav); if (yyleng == 7) { keyname = "RESTWAVa"; BEGIN(CCCCCCCa); } else { keyname = "RWAVna"; BEGIN(CCCCna); } } ^PV { valtype = FLOAT; vptr = &(wcstem.pv); ptype = 'v'; keyname = "PVi_ma"; BEGIN(CCi_ma); } ^{I1}V | ^{I1}PV { valtype = FLOAT; vptr = &(wcstem.pv); ptype = 'v'; sscanf(yytext, "%d", &i); if (yyleng == 2) { keyname = "iVn_ma"; BEGIN(iCn_ma); } else { keyname = "iPVn_ma"; BEGIN(iCCn_ma); } } ^TV | ^TPV { valtype = FLOAT; vptr = &(wcstem.pv); ptype = 'v'; if (yyleng == 2) { keyname = "TVn_ma"; BEGIN(TCn_ma); } else { keyname = "TPVn_ma"; BEGIN(TCCn_ma); } } ^PROJP { valtype = FLOAT; vptr = &(wcstem.pv); ptype = 'v'; keyname = "PROJPm"; BEGIN(PROJPm); } ^PS { valtype = STRING; vptr = &(wcstem.ps); ptype = 's'; keyname = "PSi_ma"; BEGIN(CCi_ma); } ^{I1}S | ^{I1}PS { valtype = STRING; vptr = &(wcstem.ps); ptype = 's'; sscanf(yytext, "%d", &i); if (yyleng == 2) { keyname = "iSn_ma"; BEGIN(iCn_ma); } else { keyname = "iPSn_ma"; BEGIN(iCCn_ma); } } ^TS | ^TPS { valtype = STRING; vptr = &(wcstem.ps); ptype = 's'; if (yyleng == 2) { keyname = "TSn_ma"; BEGIN(TCn_ma); } else { keyname = "TPSn_ma"; BEGIN(TCCn_ma); } } ^VELREF{ALT}" " { sscanf(yytext, "VELREF%c", &a); if (relax & WCSHDR_strict) { errmsg = "the VELREF keyword is deprecated, use SPECSYSa"; BEGIN(ERROR); } else if (a == ' ' || (relax & WCSHDR_VELREFa)) { valtype = INTEGER; vptr = &(wcstem.velref); unput(a); keyname = "VELREF"; imherit = 0; BEGIN(CCCCCCCa); } else if (relax & WCSHDR_reject) { errmsg = "VELREF keyword may not have an alternate version code"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^CNAME { valtype = STRING; vptr = &(wcstem.cname); keyname = "CNAMEia"; BEGIN(CCCCCia); } ^{I1}CNA | ^{I1}CNAM { valtype = STRING; vptr = &(wcstem.cname); sscanf(yytext, "%d", &i); if (yyleng == 4) { keyname = "iCNAna"; BEGIN(iCCCna); } else { if (!(relax & WCSHDR_CNAMn)) vptr = 0x0; keyname = "iCNAMn"; BEGIN(iCCCCn); } } ^TCNA | ^TCNAM { valtype = STRING; vptr = &(wcstem.cname); if (yyleng == 4) { keyname = "TCNAna"; BEGIN(TCCCna); } else { if (!(relax & WCSHDR_CNAMn)) vptr = 0x0; keyname = "TCNAMn"; BEGIN(TCCCCn); } } ^CRDER { valtype = FLOAT; vptr = &(wcstem.crder); keyname = "CRDERia"; BEGIN(CCCCCia); } ^{I1}CRD | ^{I1}CRDE { valtype = FLOAT; vptr = &(wcstem.crder); sscanf(yytext, "%d", &i); if (yyleng == 4) { keyname = "iCRDna"; BEGIN(iCCCna); } else { if (!(relax & WCSHDR_CNAMn)) vptr = 0x0; keyname = "iCRDEn"; BEGIN(iCCCCn); } } ^TCRD | ^TCRDE { valtype = FLOAT; vptr = &(wcstem.crder); if (yyleng == 4) { keyname = "TCRDna"; BEGIN(TCCCna); } else { if (!(relax & WCSHDR_CNAMn)) vptr = 0x0; keyname = "TCRDEn"; BEGIN(TCCCCn); } } ^CSYER { valtype = FLOAT; vptr = &(wcstem.csyer); keyname = "CSYERia"; BEGIN(CCCCCia); } ^{I1}CSY | ^{I1}CSYE { valtype = FLOAT; vptr = &(wcstem.csyer); sscanf(yytext, "%d", &i); if (yyleng == 4) { keyname = "iCSYna"; BEGIN(iCCCna); } else { if (!(relax & WCSHDR_CNAMn)) vptr = 0x0; keyname = "iCSYEn"; BEGIN(iCCCCn); } } ^TCSY | ^TCSYE { valtype = FLOAT; vptr = &(wcstem.csyer); if (yyleng == 4) { keyname = "TCSYna"; BEGIN(TCCCna); } else { if (!(relax & WCSHDR_CNAMn)) vptr = 0x0; keyname = "TCSYEn"; BEGIN(TCCCCn); } } ^CZPHS { valtype = FLOAT; vptr = &(wcstem.czphs); keyname = "CZPHSia"; BEGIN(CCCCCia); } ^{I1}CZP | ^{I1}CZPH { valtype = FLOAT; vptr = &(wcstem.czphs); sscanf(yytext, "%d", &i); if (yyleng == 4) { keyname = "iCZPna"; BEGIN(iCCCna); } else { if (!(relax & WCSHDR_CNAMn)) vptr = 0x0; keyname = "iCZPHn"; BEGIN(iCCCCn); } } ^TCZP | ^TCZPH { valtype = FLOAT; vptr = &(wcstem.czphs); if (yyleng == 4) { keyname = "TCZPna"; BEGIN(TCCCna); } else { if (!(relax & WCSHDR_CNAMn)) vptr = 0x0; keyname = "TCZPHn"; BEGIN(TCCCCn); } } ^CPERI { valtype = FLOAT; vptr = &(wcstem.cperi); keyname = "CPERIia"; BEGIN(CCCCCia); } ^{I1}CPR | ^{I1}CPER { valtype = FLOAT; vptr = &(wcstem.cperi); sscanf(yytext, "%d", &i); if (yyleng == 4) { keyname = "iCPRna"; BEGIN(iCCCna); } else { if (!(relax & WCSHDR_CNAMn)) vptr = 0x0; keyname = "iCPERn"; BEGIN(iCCCCn); } } ^TCPR | ^TCPER { valtype = FLOAT; vptr = &(wcstem.cperi); if (yyleng == 4) { keyname = "TCPRna"; BEGIN(TCCCna); } else { if (!(relax & WCSHDR_CNAMn)) vptr = 0x0; keyname = "TCPERn"; BEGIN(TCCCCn); } } ^WCSNAME | ^WCSN | ^TWCS { valtype = STRING; vptr = wcstem.wcsname; if (yyleng == 7) { keyname = "WCSNAMEa"; imherit = 0; BEGIN(CCCCCCCa); } else { if (*yytext == 'W') { keyname = "WCSNna"; } else { keyname = "TWCSna"; } BEGIN(CCCCna); } } ^TIMESYS" " { valtype = STRING; vptr = wcstem.timesys; keyname = "TIMESYS"; BEGIN(CCCCCCCC); } ^TREFPOS" " | ^TRPOS { valtype = STRING; vptr = wcstem.trefpos; if (yyleng == 8) { if (ctrl < -10) keep = keyrec; keyname = "TREFPOS"; BEGIN(CCCCCCCC); } else { keyname = "TRPOSn"; BEGIN(CCCCCn); } } ^TREFDIR" " | ^TRDIR { valtype = STRING; vptr = wcstem.trefdir; if (yyleng == 8) { if (ctrl < -10) keep = keyrec; keyname = "TREFDIR"; BEGIN(CCCCCCCC); } else { keyname = "TRDIRn"; BEGIN(CCCCCn); } } ^PLEPHEM" " { valtype = STRING; vptr = wcstem.plephem; keyname = "PLEPHEM"; BEGIN(CCCCCCCC); } ^TIMEUNIT { valtype = STRING; vptr = wcstem.timeunit; keyname = "TIMEUNIT"; BEGIN(CCCCCCCC); } ^DATEREF" " | ^DATE-REF { if ((yytext[4] == 'R') || (relax & WCSHDR_DATEREF)) { valtype = STRING; vptr = wcstem.dateref; keyname = "DATEREF"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the DATE-REF keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^MJDREF" " | ^MJD-REF" " { if ((yytext[3] == 'R') || (relax & WCSHDR_DATEREF)) { valtype = FLOAT2; vptr = wcstem.mjdref; keyname = "MJDREF"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the MJD-REF keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^MJDREFI" " | ^MJD-REFI { if ((yytext[3] == 'R') || (relax & WCSHDR_DATEREF)) { // Actually integer, but treated as float. valtype = FLOAT; vptr = wcstem.mjdref; keyname = "MJDREFI"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the MJD-REFI keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^MJDREFF" " | ^MJD-REFF { if ((yytext[3] == 'R') || (relax & WCSHDR_DATEREF)) { valtype = FLOAT; vptr = wcstem.mjdref + 1; keyname = "MJDREFF"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the MJD-REFF keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^JDREF" " | ^JD-REF" " { if ((yytext[2] == 'R') || (relax & WCSHDR_DATEREF)) { valtype = FLOAT2; vptr = wcstem.mjdref; special = wcsbth_jdref; keyname = "JDREF"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the JD-REF keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^JDREFI" " | ^JD-REFI { if ((yytext[2] == 'R') || (relax & WCSHDR_DATEREF)) { // Actually integer, but treated as float. valtype = FLOAT; vptr = wcstem.mjdref; special = wcsbth_jdrefi; keyname = "JDREFI"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the JD-REFI keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^JDREFF" " | ^JD-REFF { if ((yytext[2] == 'R') || (relax & WCSHDR_DATEREF)) { valtype = FLOAT; vptr = wcstem.mjdref; special = wcsbth_jdreff; keyname = "JDREFF"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the JD-REFF keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^TIMEOFFS { valtype = FLOAT; vptr = &(wcstem.timeoffs); keyname = "TIMEOFFS"; BEGIN(CCCCCCCC); } ^DATE-OBS { valtype = STRING; vptr = wcstem.dateobs; if (ctrl < -10) keep = keyrec; keyname = "DATE-OBS"; imherit = 0; BEGIN(CCCCCCCC); } ^DOBS{I1}" " | ^DOBS{I2}" " | ^DOBS{I3}" " { valtype = STRING; vptr = wcstem.dateobs; if (relax & WCSHDR_DOBSn) { yyless(4); keyname = "DOBSn"; BEGIN(CCCCn); } else if (relax & WCSHDR_reject) { errmsg = "DOBSn keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^DATE-BEG { valtype = STRING; vptr = wcstem.datebeg; if (ctrl < -10) keep = keyrec; keyname = "DATE-BEG"; BEGIN(CCCCCCCC); } ^DATE-AVG | ^DAVG { valtype = STRING; vptr = wcstem.dateavg; if (yyleng == 8) { if (ctrl < -10) keep = keyrec; keyname = "DATE-AVG"; BEGIN(CCCCCCCC); } else { keyname = "DAVGn"; BEGIN(CCCCn); } } ^DATE-END { valtype = STRING; vptr = wcstem.dateend; if (ctrl < -10) keep = keyrec; keyname = "DATE-END"; BEGIN(CCCCCCCC); } ^MJD-OBS" " | ^MJDOB { valtype = FLOAT; vptr = &(wcstem.mjdobs); if (yyleng == 8) { if (ctrl < -10) keep = keyrec; keyname = "MJD-OBS"; imherit = 0; BEGIN(CCCCCCCC); } else { keyname = "MJDOBn"; BEGIN(CCCCCn); } } ^MJD-BEG" " { valtype = FLOAT; vptr = &(wcstem.mjdbeg); if (ctrl < -10) keep = keyrec; keyname = "MJD-BEG"; BEGIN(CCCCCCCC); } ^MJD-AVG" " | ^MJDA { valtype = FLOAT; vptr = &(wcstem.mjdavg); if (yyleng == 8) { if (ctrl < -10) keep = keyrec; keyname = "MJD-AVG"; BEGIN(CCCCCCCC); } else { keyname = "MJDAn"; BEGIN(CCCCn); } } ^MJD-END" " { valtype = FLOAT; vptr = &(wcstem.mjdend); if (ctrl < -10) keep = keyrec; keyname = "MJD-END"; BEGIN(CCCCCCCC); } ^JEPOCH" " { valtype = FLOAT; vptr = &(wcstem.jepoch); if (ctrl < -10) keep = keyrec; keyname = "JEPOCH"; BEGIN(CCCCCCCC); } ^BEPOCH" " { valtype = FLOAT; vptr = &(wcstem.bepoch); if (ctrl < -10) keep = keyrec; keyname = "BEPOCH"; BEGIN(CCCCCCCC); } ^TSTART" " { valtype = FLOAT; vptr = &(wcstem.tstart); if (ctrl < -10) keep = keyrec; keyname = "TSTART"; BEGIN(CCCCCCCC); } ^TSTOP" " { valtype = FLOAT; vptr = &(wcstem.tstop); if (ctrl < -10) keep = keyrec; keyname = "TSTOP"; BEGIN(CCCCCCCC); } ^XPOSURE" " { valtype = FLOAT; vptr = &(wcstem.xposure); if (ctrl < -10) keep = keyrec; keyname = "XPOSURE"; BEGIN(CCCCCCCC); } ^TELAPSE" " { valtype = FLOAT; vptr = &(wcstem.telapse); if (ctrl < -10) keep = keyrec; keyname = "TELAPSE"; BEGIN(CCCCCCCC); } ^TIMSYER" " { valtype = FLOAT; vptr = &(wcstem.timsyer); if (ctrl < -10) keep = keyrec; keyname = "TIMSYER"; BEGIN(CCCCCCCC); } ^TIMRDER" " { valtype = FLOAT; vptr = &(wcstem.timrder); if (ctrl < -10) keep = keyrec; keyname = "TIMRDER"; BEGIN(CCCCCCCC); } ^TIMEDEL" " { valtype = FLOAT; vptr = &(wcstem.timedel); if (ctrl < -10) keep = keyrec; keyname = "TIMEDEL"; BEGIN(CCCCCCCC); } ^TIMEPIXR { valtype = FLOAT; vptr = &(wcstem.timepixr); chekval = wcsbth_timepixr; if (ctrl < -10) keep = keyrec; keyname = "TIMEPIXR"; BEGIN(CCCCCCCC); } ^OBSGEO-X | ^OBSGX { valtype = FLOAT; vptr = wcstem.obsgeo; if (yyleng == 8) { if (ctrl < -10) keep = keyrec; keyname = "OBSGEO-X"; BEGIN(CCCCCCCC); } else { keyname = "OBSGXn"; BEGIN(CCCCCn); } } ^OBSGEO-Y | ^OBSGY { valtype = FLOAT; vptr = wcstem.obsgeo + 1; if (yyleng == 8) { if (ctrl < -10) keep = keyrec; keyname = "OBSGEO-Y"; BEGIN(CCCCCCCC); } else { keyname = "OBSGYn"; BEGIN(CCCCCn); } } ^OBSGEO-Z | ^OBSGZ { valtype = FLOAT; vptr = wcstem.obsgeo + 2; if (yyleng == 8) { if (ctrl < -10) keep = keyrec; keyname = "OBSGEO-Z"; BEGIN(CCCCCCCC); } else { keyname = "OBSGZn"; BEGIN(CCCCCn); } } ^OBSGEO-L { valtype = FLOAT; vptr = wcstem.obsgeo + 3; if (ctrl < -10) keep = keyrec; keyname = "OBSGEO-L"; BEGIN(CCCCCCCC); } ^OBSGL{I1}" " | ^OBSGL{I2}" " | ^OBSGL{I3} { valtype = STRING; vptr = wcstem.obsgeo + 3; if (relax & WCSHDR_OBSGLBHn) { yyless(5); keyname = "OBSGLn"; BEGIN(CCCCCn); } else if (relax & WCSHDR_reject) { errmsg = "OBSGLn keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^OBSGEO-B { valtype = FLOAT; vptr = wcstem.obsgeo + 4; if (ctrl < -10) keep = keyrec; keyname = "OBSGEO-B"; BEGIN(CCCCCCCC); } ^OBSGB{I1}" " | ^OBSGB{I2}" " | ^OBSGB{I3} { valtype = STRING; vptr = wcstem.obsgeo + 3; if (relax & WCSHDR_OBSGLBHn) { yyless(5); keyname = "OBSGBn"; BEGIN(CCCCCn); } else if (relax & WCSHDR_reject) { errmsg = "OBSGBn keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^OBSGEO-H { valtype = FLOAT; vptr = wcstem.obsgeo + 5; if (ctrl < -10) keep = keyrec; keyname = "OBSGEO-H"; BEGIN(CCCCCCCC); } ^OBSGH{I1}" " | ^OBSGH{I2}" " | ^OBSGH{I3} { valtype = STRING; vptr = wcstem.obsgeo + 3; if (relax & WCSHDR_OBSGLBHn) { yyless(5); keyname = "OBSGHn"; BEGIN(CCCCCn); } else if (relax & WCSHDR_reject) { errmsg = "OBSGHn keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^OBSORBIT { valtype = STRING; vptr = wcstem.obsorbit; keyname = "OBSORBIT"; BEGIN(CCCCCCCC); } ^RADESYS | ^RADE { valtype = STRING; vptr = wcstem.radesys; if (yyleng == 7) { keyname = "RADESYSa"; imherit = 0; BEGIN(CCCCCCCa); } else { keyname = "RADEna"; BEGIN(CCCCna); } } ^RADECSYS { if (relax & WCSHDR_RADECSYS) { valtype = STRING; vptr = wcstem.radesys; unput(' '); keyname = "RADECSYS"; imherit = 0; BEGIN(CCCCCCCa); } else if (relax & WCSHDR_reject) { errmsg = "the RADECSYS keyword is deprecated, use RADESYSa"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^EPOCH{ALT}" " { sscanf(yytext, "EPOCH%c", &a); if (relax & WCSHDR_strict) { errmsg = "the EPOCH keyword is deprecated, use EQUINOXa"; BEGIN(ERROR); } else if (a == ' ' || (relax & WCSHDR_EPOCHa)) { valtype = FLOAT; vptr = &(wcstem.equinox); special = wcsbth_epoch; unput(a); keyname = "EPOCH"; imherit = 0; BEGIN(CCCCCCCa); } else if (relax & WCSHDR_reject) { errmsg = "EPOCH keyword may not have an alternate version code"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^EQUINOX | ^EQUI { valtype = FLOAT; vptr = &(wcstem.equinox); if (yyleng == 7) { keyname = "EQUINOXa"; imherit = 0; BEGIN(CCCCCCCa); } else { keyname = "EQUIna"; BEGIN(CCCCna); } } ^SPECSYS | ^SPEC { valtype = STRING; vptr = wcstem.specsys; if (yyleng == 7) { keyname = "SPECSYSa"; BEGIN(CCCCCCCa); } else { keyname = "SPECna"; BEGIN(CCCCna); } } ^SSYSOBS | ^SOBS { valtype = STRING; vptr = wcstem.ssysobs; if (yyleng == 7) { keyname = "SSYSOBSa"; BEGIN(CCCCCCCa); } else { keyname = "SOBSna"; BEGIN(CCCCna); } } ^VELOSYS | ^VSYS { valtype = FLOAT; vptr = &(wcstem.velosys); if (yyleng == 7) { keyname = "VELOSYSa"; BEGIN(CCCCCCCa); } else { keyname = "VSYSna"; BEGIN(CCCCna); } } ^VSOURCE{ALT} { if (relax & WCSHDR_VSOURCE) { valtype = FLOAT; vptr = &(wcstem.zsource); special = wcsbth_vsource; yyless(7); keyname = "VSOURCEa"; BEGIN(CCCCCCCa); } else if (relax & WCSHDR_reject) { errmsg = "the VSOURCEa keyword is deprecated, use ZSOURCEa"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^VSOU{I1}{ALT}" " | ^VSOU{I2}{ALT}" " | ^VSOU{I3}{ALT} { if (relax & WCSHDR_VSOURCE) { valtype = FLOAT; vptr = &(wcstem.zsource); special = wcsbth_vsource; yyless(4); keyname = "VSOUna"; BEGIN(CCCCna); } else if (relax & WCSHDR_reject) { errmsg = "VSOUna keyword is deprecated, use ZSOUna"; BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } ^ZSOURCE | ^ZSOU { valtype = FLOAT; vptr = &(wcstem.zsource); if (yyleng == 7) { keyname = "ZSOURCEa"; BEGIN(CCCCCCCa); } else { keyname = "ZSOUna"; BEGIN(CCCCna); } } ^SSYSSRC | ^SSRC { valtype = STRING; vptr = wcstem.ssyssrc; if (yyleng == 7) { keyname = "SSYSSRCa"; BEGIN(CCCCCCCa); } else { keyname = "SSRCna"; BEGIN(CCCCna); } } ^VELANGL | ^VANG { valtype = FLOAT; vptr = &(wcstem.velangl); if (yyleng == 7) { keyname = "VELANGLa"; BEGIN(CCCCCCCa); } else { keyname = "VANGna"; BEGIN(CCCCna); } } ^RSUN_REF { valtype = FLOAT; auxprm = 1; vptr = &(auxtem.rsun_ref); keyname = "RSUN_REF"; BEGIN(CCCCCCCC); } ^DSUN_OBS { valtype = FLOAT; auxprm = 1; vptr = &(auxtem.dsun_obs); keyname = "DSUN_OBS"; BEGIN(CCCCCCCC); } ^CRLN_OBS { valtype = FLOAT; auxprm = 1; vptr = &(auxtem.crln_obs); keyname = "CRLN_OBS"; BEGIN(CCCCCCCC); } ^HGLN_OBS { valtype = FLOAT; auxprm = 1; vptr = &(auxtem.hgln_obs); keyname = "HGLN_OBS"; BEGIN(CCCCCCCC); } ^CRLT_OBS | ^HGLT_OBS { valtype = FLOAT; auxprm = 1; vptr = &(auxtem.hglt_obs); keyname = "HGLT_OBS"; BEGIN(CCCCCCCC); } ^END" "{77} { if (yyextra->nkeyrec) { yyextra->nkeyrec = 0; errmsg = "keyrecords following the END keyrecord were ignored"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^. { BEGIN(DISCARD); } {I1}{ALT}" " | {I2}{ALT} { if (relax & WCSHDR_ALLIMG) { sscanf(yytext, "%d%c", &i, &a); keytype = IMGAXIS; BEGIN(VALUE); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } 0{I1}{ALT} | 00{I1} { if (relax & WCSHDR_ALLIMG) { if (relax & WCSHDR_reject) { // Violates the basic FITS standard. errmsg = "indices in parameterized keywords must not have " "leading zeroes"; BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "invalid image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } 0{ALT}" " | 00{ALT} | {Z3} { // Anything that has fallen through to this point must contain // an invalid axis number. if (relax & WCSHDR_ALLIMG) { errmsg = "axis number must exceed 0"; BEGIN(ERROR); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "invalid image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } . { if (relax & WCSHDR_reject) { // Looks too much like a FITS WCS keyword not to flag it. errmsg = errtxt; sprintf(errmsg, "keyword looks very much like %s but isn't", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } {I1}" " | {I2}" " | {I3} | {I1}" " | {I2}" " | {I3} { if (vptr) { WCSBTH_PUTBACK; BEGIN((YY_START == iCCCCn) ? iCCCna : TCCCna); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "%s keyword is non-standard", keyname); BEGIN(ERROR); } else { BEGIN(DISCARD); } } {I1}[A-Z]" " | {I2}[A-Z] | {I1}[A-Z]" " | {I2}[A-Z] { if (vptr && (relax & WCSHDR_LONGKEY)) { WCSBTH_PUTBACK; BEGIN((YY_START == iCCCCn) ? iCCCna : TCCCna); } else if (relax & WCSHDR_reject) { errmsg = errtxt; if (!vptr) { sprintf(errmsg, "%s keyword is non-standard", keyname); } else { sprintf(errmsg, "%s keyword may not have an alternate version code", keyname); } BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } . | . { BEGIN(DISCARD); } {I1}{ALT}" " | {I2}{ALT}" " | {I3}{ALT} | {I1}{ALT}" " | {I2}{ALT}" " | {I3}{ALT} { sscanf(yytext, "%d%c", &n, &a); if (YY_START == TCCCna) i = wcsbth_colax(*wcs, &alts, n, a); keytype = (YY_START == iCCCna) ? BIMGARR : PIXLIST; BEGIN(VALUE); } . | . { BEGIN(DISCARD); } {I1}_{I1}{ALT}" " | {I1}_{I2}{ALT}" " | {I2}_{I1}{ALT}" " | {I2}_{I2}{ALT} { if (relax & WCSHDR_ALLIMG) { sscanf(yytext, "%d_%d%c", &i, &j, &a); keytype = IMGAXIS; BEGIN(VALUE); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } 0{I1}_{I1}{ALT}" " | {I1}_0{I1}{ALT}" " | 00{I1}_{I1}{ALT} | 0{I1}_0{I1}{ALT} | {I1}_00{I1}{ALT} | 000{I1}_{I1} | 00{I1}_0{I1} | 0{I1}_00{I1} | {I1}_000{I1} | 0{I1}_{I2}{ALT} | {I1}_0{I2}{ALT} | 00{I1}_{I2} | 0{I1}_0{I2} | {I1}_00{I2} | 0{I2}_{I1}{ALT} | {I2}_0{I1}{ALT} | 00{I2}_{I1} | 0{I2}_0{I1} | {I2}_00{I1} | 0{I2}_{I2} | {I2}_0{I2} { if (relax & WCSHDR_ALLIMG) { if (((altlin == 1) && (relax & WCSHDR_PC0i_0ja)) || ((altlin == 2) && (relax & WCSHDR_CD0i_0ja))) { sscanf(yytext, "%d_%d%c", &i, &j, &a); keytype = IMGAXIS; BEGIN(VALUE); } else if (relax & WCSHDR_reject) { errmsg = "indices in parameterized keywords must not have " "leading zeroes"; BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "invalid image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } {Z1}_{Z1}{ALT}" " | {Z2}_{Z1}{ALT}" " | {Z1}_{Z2}{ALT}" " | {Z3}_{Z1}{ALT} | {Z2}_{Z2}{ALT} | {Z1}_{Z3}{ALT} | {Z4}_{Z1} | {Z3}_{Z2} | {Z2}_{Z3} | {Z1}_{Z4} { // Anything that has fallen through to this point must contain // an invalid axis number. if (relax & WCSHDR_ALLIMG) { errmsg = "axis number must exceed 0"; BEGIN(ERROR); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "invalid image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } {Z1}-{Z1}{ALT}" " | {Z2}-{Z1}{ALT}" " | {Z1}-{Z2}{ALT}" " | {Z3}-{Z1}{ALT} | {Z2}-{Z2}{ALT} | {Z1}-{Z3}{ALT} | {Z4}-{Z1} | {Z3}-{Z2} | {Z2}-{Z3} | {Z1}-{Z4} { if (relax & WCSHDR_ALLIMG) { errmsg = errtxt; sprintf(errmsg, "%s keyword must use an underscore, not a dash", keyname); BEGIN(ERROR); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "invalid image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } {Z1}{6} { // This covers the defunct forms CD00i00j and PC00i00j. if (relax & WCSHDR_ALLIMG) { if (((altlin == 1) && (relax & WCSHDR_PC00i00j)) || ((altlin == 2) && (relax & WCSHDR_CD00i00j))) { sscanf(yytext, "%3d%3d", &i, &j); a = ' '; keytype = IMGAXIS; BEGIN(VALUE); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "this form of the %s keyword is deprecated, use %s", keyname, keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "deprecated image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } . { BEGIN(DISCARD); } {I1}{ALT}" " | {I2}{ALT}" " | {I3}{ALT} { sscanf(yytext, "%d%c", &n, &a); keytype = BIMGARR; BEGIN(VALUE); } {I1}_{I1}{ALT}" " | {I1}_{I2}{ALT} | {I2}_{I1}{ALT} | {I1}_{I3} | {I2}_{I2} | {I3}_{I1} { if (relax & WCSHDR_LONGKEY) { WCSBTH_PUTBACK; BEGIN(TCn_ka); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "%s keyword is non-standard", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } . { BEGIN(DISCARD); } {I1}_{I1}{ALT}" " | {I1}_{I2}{ALT}" " | {I2}_{I1}{ALT}" " | {I1}_{I3}{ALT} | {I2}_{I2}{ALT} | {I3}_{I1}{ALT} { sscanf(yytext, "%d_%d%c", &n, &k, &a); i = wcsbth_colax(*wcs, &alts, n, a); j = wcsbth_colax(*wcs, &alts, k, a); keytype = PIXLIST; BEGIN(VALUE); } {I1}_{I4} | {I2}_{I3} | {I3}_{I2} | {I4}_{I1} { sscanf(yytext, "%d_%d", &n, &k); a = ' '; i = wcsbth_colax(*wcs, &alts, n, a); j = wcsbth_colax(*wcs, &alts, k, a); keytype = PIXLIST; BEGIN(VALUE); } . { BEGIN(DISCARD); } {Z1}{ALT}" " | {Z2}{ALT} | {Z3} { if (relax & WCSHDR_ALLIMG) { a = ' '; sscanf(yytext, "%d%c", &i, &a); if (relax & WCSHDR_strict) { errmsg = "the CROTAn keyword is deprecated, use PCi_ja"; BEGIN(ERROR); } else if (a == ' ' || relax & WCSHDR_CROTAia) { yyless(0); BEGIN(CCCCCia); } else if (relax & WCSHDR_reject) { errmsg = "CROTAn keyword may not have an alternate version code"; BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "deprecated image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } . { if (relax & WCSHDR_ALLIMG) { yyless(0); BEGIN(CCCCCia); } else { // Let it go. BEGIN(DISCARD); } } {I1}" " | {I2}" " | {I3} | {I1}" " | {I2}" " | {I3} { WCSBTH_PUTBACK; BEGIN((YY_START == iCROTn) ? iCCCna : TCCCna); } {I1}[A-Z]" " | {I2}[A-Z] | {I1}[A-Z]" " | {I2}[A-Z] { if (relax & WCSHDR_CROTAia) { WCSBTH_PUTBACK; BEGIN((YY_START == iCROTn) ? iCCCna : TCCCna); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "%s keyword may not have an alternate version code", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } . | . { BEGIN(DISCARD); } {ALT} | . { // Image-header keyword. if (imherit || (relax & (WCSHDR_AUXIMG | WCSHDR_ALLIMG))) { if (YY_START == CCCCCCCa) { sscanf(yytext, "%c", &a); } else { a = 0; unput(yytext[0]); } keytype = IMGAUX; BEGIN(VALUE); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } . { if (relax & WCSHDR_reject) { // Looks too much like a FITS WCS keyword not to flag it. errmsg = errtxt; sprintf(errmsg, "invalid alternate code, keyword resembles %s " "but isn't", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } {I1}{ALT}" " | {I2}{ALT}" " | {I3}{ALT} | {I1}{ALT}" " | {I2}{ALT} { sscanf(yytext, "%d%c", &n, &a); keytype = BINTAB; BEGIN(VALUE); } {I3} { sscanf(yytext, "%d", &n); a = ' '; keytype = BINTAB; BEGIN(VALUE); } . | . { BEGIN(DISCARD); } {I1}" " | {I2}" " | {I3}" " | {I4} | {I1}" " | {I2}" " | {I3} { sscanf(yytext, "%d", &n); a = 0; keytype = BINTAB; BEGIN(VALUE); } . | . { BEGIN(DISCARD); } {I1}_{Z1}{ALT}" " | {I1}_{I2}{ALT}" " | {I2}_{Z1}{ALT}" " | {I2}_{I2}{ALT} { // Image-header keyword. if (relax & WCSHDR_ALLIMG) { sscanf(yytext, "%d_%d%c", &i, &m, &a); keytype = IMGAXIS; BEGIN(VALUE); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } 0{I1}_{Z1}{ALT}" " | {I1}_0{Z1}{ALT}" " | 00{I1}_{Z1}{ALT} | 0{I1}_0{Z1}{ALT} | {I1}_00{Z1}{ALT} | 000{I1}_{Z1} | 00{I1}_0{Z1} | 0{I1}_00{Z1} | {I1}_000{Z1} | 0{I1}_{I2}{ALT} | {I1}_0{I2}{ALT} | 00{I1}_{I2} | 0{I1}_0{I2} | {I1}_00{I2} | 0{I2}_{Z1}{ALT} | {I2}_0{Z1}{ALT} | 00{I2}_{Z1} | 0{I2}_0{Z1} | {I2}_00{Z1} | 0{I2}_{I2} | {I2}_0{I2} { if (relax & WCSHDR_ALLIMG) { if (((valtype == FLOAT) && (relax & WCSHDR_PV0i_0ma)) || ((valtype == STRING) && (relax & WCSHDR_PS0i_0ma))) { sscanf(yytext, "%d_%d%c", &i, &m, &a); keytype = IMGAXIS; BEGIN(VALUE); } else if (relax & WCSHDR_reject) { errmsg = "indices in parameterized keywords must not have " "leading zeroes"; BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "invalid image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } {Z1}_{Z1}{ALT}" " | {Z2}_{Z1}{ALT}" " | {Z1}_{Z2}{ALT}" " | {Z3}_{Z1}{ALT} | {Z2}_{Z2}{ALT} | {Z1}_{Z3}{ALT} | {Z4}_{Z1} | {Z3}_{Z2} | {Z2}_{Z3} | {Z1}_{Z4} { if (relax & WCSHDR_ALLIMG) { // Anything that has fallen through to this point must contain // an invalid parameter. errmsg = "axis number must exceed 0"; BEGIN(ERROR); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "invalid image-header keyword %s in binary table", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } {Z1}-{Z1}{ALT}" " | {Z2}-{Z1}{ALT}" " | {Z1}-{Z2}{ALT}" " | {Z3}-{Z1}{ALT} | {Z2}-{Z2}{ALT} | {Z1}-{Z3}{ALT} | {Z4}-{Z1} | {Z3}-{Z2} | {Z2}-{Z3} | {Z1}-{Z4} { errmsg = errtxt; sprintf(errmsg, "%s keyword must use an underscore, not a dash", keyname); BEGIN(ERROR); } . { BEGIN(DISCARD); } {I1}_{Z1}{ALT}" " | {I1}_{I2}{ALT} | {I1}_{I3} | {I2}_{Z1}{ALT} | {I2}_{I2} | {I3}_{Z1} | {I1}_{Z1}{ALT}" " | {I1}_{I2}{ALT} | {I1}_{I3} | {I2}_{Z1}{ALT} | {I2}_{I2} | {I3}_{Z1} { if (relax & WCSHDR_LONGKEY) { WCSBTH_PUTBACK; BEGIN((YY_START == iCCn_ma) ? iCn_ma : TCn_ma); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "the %s keyword is non-standard", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } . | . { BEGIN(DISCARD); } {I1}_{Z1}{ALT}" " | {I1}_{I2}{ALT}" " | {I1}_{I3}{ALT} | {I2}_{Z1}{ALT}" " | {I2}_{I2}{ALT} | {I3}_{Z1}{ALT} | {I1}_{Z1}{ALT}" " | {I1}_{I2}{ALT}" " | {I1}_{I3}{ALT} | {I2}_{Z1}{ALT}" " | {I2}_{I2}{ALT} | {I3}_{Z1}{ALT} { sscanf(yytext, "%d_%d%c", &n, &m, &a); if (YY_START == TCn_ma) i = wcsbth_colax(*wcs, &alts, n, a); keytype = (YY_START == iCn_ma) ? BIMGARR : PIXLIST; BEGIN(VALUE); } {I1}_{I4} | {I2}_{I3} | {I3}_{I2} | {I4}_{Z1} | {I1}_{I4} | {I2}_{I3} | {I3}_{I2} | {I4}_{Z1} { // Invalid combinations will be flagged by . sscanf(yytext, "%d_%d", &n, &m); a = ' '; if (YY_START == TCn_ma) i = wcsbth_colax(*wcs, &alts, n, a); keytype = (YY_START == iCn_ma) ? BIMGARR : PIXLIST; BEGIN(VALUE); } . | . { BEGIN(DISCARD); } {Z1}" " { if (relax & WCSHDR_PROJPn) { sscanf(yytext, "%d", &m); i = 0; a = ' '; keytype = IMGAXIS; BEGIN(VALUE); } else if (relax & WCSHDR_reject) { errmsg = "the PROJPn keyword is deprecated, use PVi_ma"; BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } {Z2}" " | {Z3} { if (relax & (WCSHDR_PROJPn | WCSHDR_reject)) { errmsg = "invalid PROJPn keyword"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } . { BEGIN(DISCARD); } =" "+ { // Do checks on i, j, m, n, k. if (!(keytype & keysel)) { // Selection by keyword type. BEGIN(DISCARD); } else if (exclude[n] || exclude[k]) { // One or other column is not selected. if (k && (exclude[n] != exclude[k])) { // For keywords such as TCn_ka, both columns must be excluded. // User error, so return immediately. return WCSHDRERR_BAD_COLUMN; } else { BEGIN(DISCARD); } } else if (i > 99 || j > 99 || m > 99 || n > 999 || k > 999) { if (relax & WCSHDR_reject) { errmsg = errtxt; if (i > 99 || j > 99) { sprintf(errmsg, "axis number exceeds 99"); } else if (m > 99) { sprintf(errmsg, "parameter number exceeds 99"); } else if (n > 999 || k > 999) { sprintf(errmsg, "column number exceeds 999"); } BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } else if (ipass == 2 && npass == 3 && (keytype & BINTAB)) { // Skip keyvalues that won't be inherited. BEGIN(FLUSH); } else { if (ipass == 3 && (keytype & IMGHEAD)) { // IMGHEAD keytypes are always dealt with on the second pass. // However, they must be re-parsed in order to report errors. vptr = 0x0; } if (valtype == INTEGER) { BEGIN(INTEGER_VAL); } else if (valtype == FLOAT) { BEGIN(FLOAT_VAL); } else if (valtype == FLOAT2) { BEGIN(FLOAT2_VAL); } else if (valtype == STRING) { BEGIN(STRING_VAL); } else { errmsg = errtxt; sprintf(errmsg, "internal parser ERROR, bad data type: %d", valtype); BEGIN(ERROR); } } } . { errmsg = "invalid KEYWORD = VALUE syntax"; BEGIN(ERROR); } {INTEGER} { if (ipass == 1) { BEGIN(COMMENT); } else { // Read the keyvalue. sscanf(yytext, "%d", &inttmp); BEGIN(COMMENT); } } . { errmsg = "an integer value was expected"; BEGIN(ERROR); } {FLOAT} { if (ipass == 1) { BEGIN(COMMENT); } else { // Read the keyvalue. wcsutil_str2double(yytext, &dbltmp); if (chekval && chekval(dbltmp)) { errmsg = "invalid keyvalue"; BEGIN(ERROR); } else { BEGIN(COMMENT); } } } . { errmsg = "a floating-point value was expected"; BEGIN(ERROR); } {FLOAT} { if (ipass == 1) { BEGIN(COMMENT); } else { // Read the keyvalue as integer and fractional parts. wcsutil_str2double2(yytext, dbl2tmp); BEGIN(COMMENT); } } . { errmsg = "a floating-point value was expected"; BEGIN(ERROR); } {STRING} { if (ipass == 1) { BEGIN(COMMENT); } else { // Read the keyvalue. strcpy(strtmp, yytext+1); // Squeeze out repeated quotes. int ix = 0; for (int jx = 0; jx < 72; jx++) { if (ix < jx) { strtmp[ix] = strtmp[jx]; } if (strtmp[jx] == '\0') { if (ix) strtmp[ix-1] = '\0'; break; } else if (strtmp[jx] == '\'' && strtmp[jx+1] == '\'') { jx++; } ix++; } BEGIN(COMMENT); } } . { errmsg = "a string value was expected"; BEGIN(ERROR); } {INLINE}$ { if (ipass == 1) { // Do first-pass bookkeeping. wcsbth_pass1(keytype, i, j, n, k, a, ptype, &alts); BEGIN(FLUSH); } else if (*wcs) { // Store the value now that the keyrecord has been validated. alts.icol = 0; alts.ialt = 0; // Update each coordinate representation. int gotone = 0; struct wcsprm *wcsp; while ((wcsp = wcsbth_idx(*wcs, &alts, keytype, n, a))) { gotone = 1; if (vptr) { void *wptr; if (auxprm) { // Additional auxiliary parameter. auxp = wcsp->aux; ptrdiff_t voff = (char *)vptr - (char *)(&auxtem); wptr = (void *)((char *)auxp + voff); } else { // A parameter that lives directly in wcsprm. ptrdiff_t voff = (char *)vptr - (char *)(&wcstem); wptr = (void *)((char *)wcsp + voff); } if (valtype == INTEGER) { *((int *)wptr) = inttmp; } else if (valtype == FLOAT) { // Apply keyword parameterization. if (ptype == 'v') { int ipx = (wcsp->npv)++; wcsp->pv[ipx].i = i; wcsp->pv[ipx].m = m; wptr = &(wcsp->pv[ipx].value); } else if (j) { wptr = *((double **)wptr) + (i - 1)*(wcsp->naxis) + (j - 1); } else if (i) { wptr = *((double **)wptr) + (i - 1); } if (special) { special(wptr, &dbltmp); } else { *((double *)wptr) = dbltmp; } // Flag the presence of PCi_ja, or CDi_ja and/or CROTAia. if (altlin) { wcsp->altlin |= altlin; altlin = 0; } } else if (valtype == FLOAT2) { // Split MJDREF and JDREF into integer and fraction. if (special) { special(wptr, dbl2tmp); } else { *((double *)wptr) = dbl2tmp[0]; *((double *)wptr + 1) = dbl2tmp[1]; } } else if (valtype == STRING) { // Apply keyword parameterization. if (ptype == 's') { int ipx = wcsp->nps++; wcsp->ps[ipx].i = i; wcsp->ps[ipx].m = m; wptr = wcsp->ps[ipx].value; } else if (j) { wptr = *((char (**)[72])wptr) + (i - 1)*(wcsp->naxis) + (j - 1); } else if (i) { wptr = *((char (**)[72])wptr) + (i - 1); } char *cptr = (char *)wptr; strcpy(cptr, strtmp); } } } if (ipass == npass) { if (gotone) { nvalid++; if (ctrl == 4) { wcsfprintf(stderr, "%.80s\n Accepted (%d) as a valid WCS keyrecord.\n", keyrec, nvalid); } BEGIN(FLUSH); } else { errmsg = "syntactically valid WCS keyrecord has no effect"; BEGIN(ERROR); } } else { BEGIN(FLUSH); } } else { BEGIN(FLUSH); } } .*" "*\/.*$ { errmsg = "invalid keyvalue"; BEGIN(ERROR); } [^ \/\n]*{INLINE}$ { errmsg = "invalid keyvalue"; BEGIN(ERROR); } " "+[^\/\n].*{INLINE}$ { errmsg = "invalid keyvalue or malformed keycomment"; BEGIN(ERROR); } .*$ { errmsg = "malformed keycomment"; BEGIN(ERROR); } .*$ { if (ipass == npass) { if (ctrl < 0) { // Preserve discards. keep = keyrec; } else if (2 < ctrl) { nother++; wcsfprintf(stderr, "%.80s\n Not a recognized WCS keyword.\n", keyrec); } } BEGIN(FLUSH); } .*$ { if (ipass == npass) { (*nreject)++; if (ctrl%10 == -1) { keep = keyrec; } if (1 < abs(ctrl%10)) { wcsfprintf(stderr, "%.80s\n Rejected (%d), %s.\n", keyrec, *nreject, errmsg); } } BEGIN(FLUSH); } .*\n { if (ipass == npass && keep) { if (hptr < keep) { strncpy(hptr, keep, 80); } hptr += 80; } naux += auxprm; auxprm = 0; // Throw away the rest of the line and reset for the next one. i = j = 0; n = k = 0; m = 0; a = ' '; keyrec += 80; keytype = 0; valtype = -1; vptr = 0x0; keep = 0x0; altlin = 0; ptype = ' '; chekval = 0x0; special = 0x0; BEGIN(INITIAL); } <> { // End-of-input. if (ipass == 1) { int status; if ((status = wcsbth_init1(&alts, naux, nwcs, wcs)) || (*nwcs == 0 && ctrl == 0)) { return status; } if (2 < abs(ctrl%10)) { if (*nwcs == 1) { if (strcmp(wcs[0]->wcsname, "DEFAULTS") != 0) { wcsfprintf(stderr, "Found one coordinate representation.\n"); } } else { wcsfprintf(stderr, "Found %d coordinate representations.\n", *nwcs); } } if (alts.imgherit) npass = 3; } if (ipass++ < npass) { yyextra->hdr = header; yyextra->nkeyrec = nkeyrec; keyrec = header; *nreject = 0; imherit = 1; i = j = 0; k = n = 0; m = 0; a = ' '; keytype = 0; valtype = -1; vptr = 0x0; altlin = 0; ptype = ' '; chekval = 0x0; special = 0x0; yyrestart(yyin, yyscanner); } else { if (ctrl < 0) { *hptr = '\0'; } else if (ctrl == 1) { wcsfprintf(stderr, "%d WCS keyrecord%s rejected.\n", *nreject, (*nreject==1)?" was":"s were"); } else if (ctrl == 4) { wcsfprintf(stderr, "\n"); wcsfprintf(stderr, "%5d keyrecord%s rejected for syntax or " "other errors,\n", *nreject, (*nreject==1)?" was":"s were"); wcsfprintf(stderr, "%5d %s recognized as syntactically valid, " "and\n", nvalid, (nvalid==1)?"was":"were"); wcsfprintf(stderr, "%5d other%s were not recognized as WCS " "keyrecords.\n", nother, (nother==1)?"":"s"); } return wcsbth_final(&alts, nwcs, wcs); } } %% /*---------------------------------------------------------------------------- * External interface to the scanner. *---------------------------------------------------------------------------*/ int wcsbth( char *header, int nkeyrec, int relax, int ctrl, int keysel, int *colsel, int *nreject, int *nwcs, struct wcsprm **wcs) { // Function prototypes. int yylex_init_extra(YY_EXTRA_TYPE extra, yyscan_t *yyscanner); int yylex_destroy(yyscan_t yyscanner); struct wcsbth_extra extra; yyscan_t yyscanner; yylex_init_extra(&extra, &yyscanner); int status = wcsbth_scanner(header, nkeyrec, relax, ctrl, keysel, colsel, nreject, nwcs, wcs, yyscanner); yylex_destroy(yyscanner); return status; } /*---------------------------------------------------------------------------- * Perform first-pass tasks: * * 1) Count the number of coordinate axes in each of the 27 possible alternate * image-header coordinate representations. Also count the number of PVi_ma * and PSi_ma keywords in each representation. * * 2) Determine the number of binary table columns that have an image array * with a coordinate representation (up to 999), and count the number of * coordinate axes in each of the 27 possible alternates. Also count the * number of iVn_ma and iSn_ma keywords in each representation. * * 3) Determine the number of alternate pixel list coordinate representations * (up to 27) and the table columns associated with each. Also count the * number of TVn_ma and TSn_ma keywords in each representation. * * In the first pass alts->arridx[icol][27] is used to determine the number of * axes in each of 27 possible image-header coordinate descriptions (icol == 0) * and each of the 27 possible coordinate representations for an image array in * each column. * * The elements of alts->pixlist[icol] are used as bit arrays to flag which of * the 27 possible pixel list coordinate representations are associated with * each table column. *---------------------------------------------------------------------------*/ int wcsbth_pass1( int keytype, int i, int j, int n, int k, char a, char ptype, struct wcsbth_alts *alts) { if (a == 0) { // Keywords such as DATE-OBS go along for the ride. return 0; } int ncol = alts->ncol; // Do we need to allocate memory for alts? if (alts->arridx == 0x0) { if (ncol == 0) { // Can only happen if TFIELDS is missing or out-of-sequence. If n and // k are both zero then we may be processing an image header so leave // ncol alone - the array will be realloc'd later if required. if (n || k) { // The header is mangled, assume the worst. ncol = 999; } } if (!(alts->arridx = calloc((1 + ncol)*27, sizeof(short int))) || !(alts->npv = calloc((1 + ncol)*27, sizeof(unsigned char))) || !(alts->nps = calloc((1 + ncol)*27, sizeof(unsigned char))) || !(alts->pixlist = calloc((1 + ncol), sizeof(unsigned int)))) { if (alts->arridx) free(alts->arridx); if (alts->npv) free(alts->npv); if (alts->nps) free(alts->nps); if (alts->pixlist) free(alts->pixlist); return WCSHDRERR_MEMORY; } alts->ncol = ncol; } else if (n > ncol || k > ncol) { // Can only happen if TFIELDS or the WCS keyword is wrong; carry on. ncol = 999; if (!(alts->arridx = realloc(alts->arridx, 27*(1 + ncol)*sizeof(short int))) || !(alts->npv = realloc(alts->npv, 27*(1 + ncol)*sizeof(unsigned char))) || !(alts->nps = realloc(alts->nps, 27*(1 + ncol)*sizeof(unsigned char))) || !(alts->pixlist = realloc(alts->pixlist, (1 + ncol)*sizeof(unsigned int)))) { if (alts->arridx) free(alts->arridx); if (alts->npv) free(alts->npv); if (alts->nps) free(alts->nps); if (alts->pixlist) free(alts->pixlist); return WCSHDRERR_MEMORY; } // Since realloc() doesn't initialize the extra memory. for (int icol = (1 + alts->ncol); icol < (1 + ncol); icol++) { for (int ialt = 0; ialt < 27; ialt++) { alts->arridx[icol][ialt] = 0; alts->npv[icol][ialt] = 0; alts->nps[icol][ialt] = 0; alts->pixlist[icol] = 0; } } alts->ncol = ncol; } int ialt = 0; if (a != ' ') { ialt = a - 'A' + 1; } // A BINTAB keytype such as LONPna, in conjunction with an IMGAXIS keytype // causes a table column to be recognized as an image array. if (keytype & IMGHEAD || keytype & BIMGARR) { // n == 0 is expected for IMGHEAD keywords. if (i == 0 && j == 0) { if (alts->arridx[n][ialt] == 0) { // Flag that an auxiliary keyword was seen. alts->arridx[n][ialt] = -1; } } else { // Record the maximum axis number found. if (alts->arridx[n][ialt] < i) { alts->arridx[n][ialt] = i; } if (alts->arridx[n][ialt] < j) { alts->arridx[n][ialt] = j; } } if (ptype == 'v') { alts->npv[n][ialt]++; } else if (ptype == 's') { alts->nps[n][ialt]++; } } // BINTAB keytypes, which apply both to pixel lists as well as binary table // image arrays, never contribute to recognizing a table column as a pixel // list axis. A PIXLIST keytype is required for that. if (keytype == PIXLIST) { int mask = 1 << ialt; // n > 0 for PIXLIST keytypes. alts->pixlist[n] |= mask; if (k) alts->pixlist[k] |= mask; // Used as a flag over all columns. alts->pixlist[0] |= mask; if (ptype == 'v') { alts->pixnpv[ialt]++; } else if (ptype == 's') { alts->pixnps[ialt]++; } } return 0; } /*---------------------------------------------------------------------------- * Perform initializations at the end of the first pass: * * 1) Determine the required number of wcsprm structs, allocate memory for * an array of them and initialize each one. *---------------------------------------------------------------------------*/ int wcsbth_init1( struct wcsbth_alts *alts, int naux, int *nwcs, struct wcsprm **wcs) { int status = 0; if (alts->arridx == 0x0) { *nwcs = 0; return 0; } // Determine the number of axes in each pixel list representation. int ialt, mask, ncol = alts->ncol; for (ialt = 0, mask = 1; ialt < 27; ialt++, mask <<= 1) { alts->pixidx[ialt] = 0; if (alts->pixlist[0] | mask) { for (int icol = 1; icol <= ncol; icol++) { if (alts->pixlist[icol] & mask) { alts->pixidx[ialt]++; } } } } // Find the total number of coordinate representations. *nwcs = 0; alts->imgherit = 0; int inherit[27]; for (int ialt = 0; ialt < 27; ialt++) { inherit[ialt] = 0; for (int icol = 1; icol <= ncol; icol++) { if (alts->arridx[icol][ialt] < 0) { // No BIMGARR keytype but there's at least one BINTAB. if (alts->arridx[0][ialt] > 0) { // There is an IMGAXIS keytype that we will inherit, so count this // representation. alts->arridx[icol][ialt] = alts->arridx[0][ialt]; } else { alts->arridx[icol][ialt] = 0; } } if (alts->arridx[icol][ialt]) { if (alts->arridx[0][ialt]) { // All IMGHEAD keywords are inherited for this ialt. inherit[ialt] = 1; if (alts->arridx[icol][ialt] < alts->arridx[0][ialt]) { // The extra axes are also inherited. alts->arridx[icol][ialt] = alts->arridx[0][ialt]; } } (*nwcs)++; } } // Count every "a" found in any IMGHEAD keyword... if (alts->arridx[0][ialt]) { if (inherit[ialt]) { // ...but not if the IMGHEAD keywords will be inherited. alts->arridx[0][ialt] = 0; alts->imgherit = 1; } else if (alts->arridx[0][ialt] > 0) { (*nwcs)++; } } // We need a struct for every "a" found in a PIXLIST keyword. if (alts->pixidx[ialt]) { (*nwcs)++; } } if (*nwcs) { // Allocate memory for the required number of wcsprm structs. if (!(*wcs = calloc(*nwcs, sizeof(struct wcsprm)))) { return WCSHDRERR_MEMORY; } // Initialize each wcsprm struct. struct wcsprm *wcsp = *wcs; *nwcs = 0; for (int icol = 0; icol <= ncol; icol++) { for (int ialt = 0; ialt < 27; ialt++) { if (alts->arridx[icol][ialt] > 0) { // Image-header representations that are not for inheritance // (icol == 0) or binary table image array representations. wcsp->flag = -1; int npvmax = alts->npv[icol][ialt]; int npsmax = alts->nps[icol][ialt]; if ((status = wcsinit(1, (int)(alts->arridx[icol][ialt]), wcsp, npvmax, npsmax, -1))) { wcsvfree(nwcs, wcs); break; } // Record the alternate version code. if (ialt) { wcsp->alt[0] = 'A' + ialt - 1; } // Any additional auxiliary keywords present? if (naux) { if (wcsauxi(1, wcsp)) { return WCSHDRERR_MEMORY; } } // Record the table column number. wcsp->colnum = icol; // On the second pass alts->arridx[icol][27] indexes the array of // wcsprm structs. alts->arridx[icol][ialt] = (*nwcs)++; wcsp++; } else { // Signal that this column has no WCS for this "a". alts->arridx[icol][ialt] = -1; } } } for (int ialt = 0; ialt < 27; ialt++) { if (alts->pixidx[ialt]) { // Pixel lists representations. wcsp->flag = -1; int npvmax = alts->pixnpv[ialt]; int npsmax = alts->pixnps[ialt]; if ((status = wcsinit(1, (int)(alts->pixidx[ialt]), wcsp, npvmax, npsmax, -1))) { wcsvfree(nwcs, wcs); break; } // Record the alternate version code. if (ialt) { wcsp->alt[0] = 'A' + ialt - 1; } // Any additional auxiliary keywords present? if (naux) { if (wcsauxi(1, wcsp)) { return WCSHDRERR_MEMORY; } } // Record the pixel list column numbers. int icol, ix, mask = (1 << ialt); for (icol = 1, ix = 0; icol <= ncol; icol++) { if (alts->pixlist[icol] & mask) { wcsp->colax[ix++] = icol; } } // alts->pixidx[] indexes the array of wcsprm structs. alts->pixidx[ialt] = (*nwcs)++; wcsp++; } else { // Signal that this column is not a pixel list axis for this "a". alts->pixidx[ialt] = -1; } } } return status; } /*---------------------------------------------------------------------------- * Return a pointer to the next wcsprm struct for a particular column number * and alternate. *---------------------------------------------------------------------------*/ struct wcsprm *wcsbth_idx( struct wcsprm *wcs, struct wcsbth_alts *alts, int keytype, int n, char a) { const char as[] = " ABCDEFGHIJKLMNOPQRSTUVWXYZ"; if (!wcs) return 0x0; int iwcs = -1; for (; iwcs < 0 && alts->ialt < 27; alts->ialt++) { // Note that a == 0 applies to every alternate, otherwise this // loop simply determines the appropriate value of alts->ialt. if (a && a != as[alts->ialt]) continue; if (keytype & (IMGHEAD | BIMGARR)) { for (; iwcs < 0 && alts->icol <= alts->ncol; alts->icol++) { // Image header keywords, n == 0, apply to all columns, otherwise this // loop simply determines the appropriate value of alts->icol. if (n && n != alts->icol) continue; iwcs = alts->arridx[alts->icol][alts->ialt]; } // Break out of the loop to stop alts->ialt from being incremented. if (iwcs >= 0) break; // Start from scratch for the next alts->ialt. alts->icol = 0; } if (keytype & (IMGAUX | PIXLIST)) { iwcs = alts->pixidx[alts->ialt]; } } return (iwcs >= 0) ? (wcs + iwcs) : 0x0; } /*---------------------------------------------------------------------------- * Return the axis number associated with the specified column number in a * particular pixel list coordinate representation. *---------------------------------------------------------------------------*/ int wcsbth_colax( struct wcsprm *wcs, struct wcsbth_alts *alts, int n, char a) { if (!wcs) return 0; struct wcsprm *wcsp = wcs; if (a != ' ') { wcsp += alts->pixidx[a-'A'+1]; } for (int ix = 0; ix < wcsp->naxis; ix++) { if (wcsp->colax[ix] == n) { return ++ix; } } return 0; } /*---------------------------------------------------------------------------- * Interpret the JDREF, JDREFI, and JDREFF keywords. *---------------------------------------------------------------------------*/ int wcsbth_jdref(double *mjdref, const double *jdref) { // Set MJDREF from JDREF. if (undefined(mjdref[0] && undefined(mjdref[1]))) { mjdref[0] = jdref[0] - 2400000.0; mjdref[1] = jdref[1] - 0.5; if (mjdref[1] < 0.0) { mjdref[0] -= 1.0; mjdref[1] += 1.0; } } return 0; } int wcsbth_jdrefi(double *mjdref, const double *jdrefi) { // Set the integer part of MJDREF from JDREFI. if (undefined(mjdref[0])) { mjdref[0] = *jdrefi - 2400000.5; } return 0; } int wcsbth_jdreff(double *mjdref, const double *jdreff) { // Set the fractional part of MJDREF from JDREFF. if (undefined(mjdref[1])) { mjdref[1] = *jdreff; } return 0; } /*---------------------------------------------------------------------------- * Interpret EPOCHa keywords. *---------------------------------------------------------------------------*/ int wcsbth_epoch(double *equinox, const double *epoch) { // If EQUINOXa is currently undefined then set it from EPOCHa. if (undefined(*equinox)) { *equinox = *epoch; } return 0; } /*---------------------------------------------------------------------------- * Interpret VSOURCEa keywords. *---------------------------------------------------------------------------*/ int wcsbth_vsource(double *zsource, const double *vsource) { const double c = 299792458.0; // If ZSOURCEa is currently undefined then set it from VSOURCEa. if (undefined(*zsource)) { // Convert relativistic Doppler velocity to redshift. double beta = *vsource/c; *zsource = (1.0 + beta)/sqrt(1.0 - beta*beta) - 1.0; } return 0; } /*---------------------------------------------------------------------------- * Check validity of a TIMEPIXR keyvalue. *---------------------------------------------------------------------------*/ int wcsbth_timepixr(double timepixr) { return (timepixr < 0.0 || 1.0 < timepixr); } /*---------------------------------------------------------------------------- * Tie up loose ends. *---------------------------------------------------------------------------*/ int wcsbth_final( struct wcsbth_alts *alts, int *nwcs, struct wcsprm **wcs) { if (alts->arridx) free(alts->arridx); if (alts->npv) free(alts->npv); if (alts->nps) free(alts->nps); if (alts->pixlist) free(alts->pixlist); for (int ialt = 0; ialt < *nwcs; ialt++) { // Interpret -TAB header keywords. int status; if ((status = wcstab(*wcs+ialt))) { wcsvfree(nwcs, wcs); return status; } } return 0; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/wcserr.c0000644000175100001710000001071200000000000017034 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. Module author: Michael Droettboom http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcserr.c,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *===========================================================================*/ #include #include #include #include #include "wcserr.h" #include "wcsprintf.h" static int wcserr_enabled = 0; //---------------------------------------------------------------------------- int wcserr_enable(int enable) { return wcserr_enabled = (enable ? 1 : 0); } //---------------------------------------------------------------------------- int wcserr_size(const struct wcserr *err, int sizes[2]) { if (err == 0x0) { sizes[0] = sizes[1] = 0; return 0; } // Base size, in bytes. sizes[0] = sizeof(struct wcserr); // Total size of allocated memory, in bytes. sizes[1] = 0; if (err->msg) { sizes[1] += strlen(err->msg) + 1; } return 0; } //---------------------------------------------------------------------------- int wcserr_prt(const struct wcserr *err, const char *prefix) { if (!wcserr_enabled) { wcsprintf("Error messaging is not enabled, use wcserr_enable().\n"); return 2; } if (err == 0x0) { return 0; } if (err->status) { if (prefix == 0x0) prefix = ""; if (err->status > 0) { wcsprintf("%sERROR %d in %s() at line %d of file %s:\n%s%s.\n", prefix, err->status, err->function, err->line_no, err->file, prefix, err->msg); } else { // An informative message only. wcsprintf("%sINFORMATIVE message from %s() at line %d of file " "%s:\n%s%s.\n", prefix, err->function, err->line_no, err->file, prefix, err->msg); } } return 0; } //---------------------------------------------------------------------------- int wcserr_clear(struct wcserr **errp) { if (*errp) { if ((*errp)->msg) { free((*errp)->msg); } free(*errp); *errp = 0x0; } return 0; } //---------------------------------------------------------------------------- int wcserr_set( struct wcserr **errp, int status, const char *function, const char *file, int line_no, const char *format, ...) { int msglen; struct wcserr *err; va_list argp; if (!wcserr_enabled) return status; if (errp == 0x0) { return status; } err = *errp; if (status) { if (err == 0x0) { *errp = err = calloc(1, sizeof(struct wcserr)); } if (err == 0x0) { return status; } err->status = status; err->function = function; err->file = file; err->line_no = line_no; err->msg = 0x0; // Determine the required message buffer size. va_start(argp, format); msglen = vsnprintf(0x0, 0, format, argp) + 1; va_end(argp); if (msglen <= 0 || (err->msg = malloc(msglen)) == 0x0) { wcserr_clear(errp); return status; } // Write the message. va_start(argp, format); msglen = vsnprintf(err->msg, msglen, format, argp); va_end(argp); if (msglen < 0) { wcserr_clear(errp); } } return status; } //---------------------------------------------------------------------------- int wcserr_copy(const struct wcserr *src, struct wcserr *dst) { size_t msglen; if (src == 0x0) { if (dst) { memset(dst, 0, sizeof(struct wcserr)); } return 0; } if (dst) { memcpy(dst, src, sizeof(struct wcserr)); if (src->msg) { msglen = strlen(src->msg) + 1; if ((dst->msg = malloc(msglen))) { strcpy(dst->msg, src->msg); } } } return src->status; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/wcserr.h0000644000175100001710000002312300000000000017041 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. Module author: Michael Droettboom http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcserr.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * Summary of the wcserr routines * ------------------------------ * Most of the structs in WCSLIB contain a pointer to a wcserr struct as a * member. Functions in WCSLIB that return an error status code can also * allocate and set a detailed error message in this struct, which also * identifies the function, source file, and line number where the error * occurred. * * For example: * = struct prjprm prj; = wcserr_enable(1); = if (prjini(&prj)) { = // Print the error message to stderr. = wcsprintf_set(stderr); = wcserr_prt(prj.err, 0x0); = } * * A number of utility functions used in managing the wcserr struct are for * internal use only. They are documented here solely as an aid to * understanding the code. They are not intended for external use - the API * may change without notice! * * * wcserr struct - Error message handling * -------------------------------------- * The wcserr struct contains the numeric error code, a textual description of * the error, and information about the function, source file, and line number * where the error was generated. * * int status * Numeric status code associated with the error, the meaning of which * depends on the function that generated it. See the documentation for * the particular function. * * int line_no * Line number where the error occurred as given by the __LINE__ * preprocessor macro. * * const char *function * Name of the function where the error occurred. * * const char *file * Name of the source file where the error occurred as given by the * __FILE__ preprocessor macro. * * char *msg * Informative error message. * * * wcserr_enable() - Enable/disable error messaging * ------------------------------------------------ * wcserr_enable() enables or disables wcserr error messaging. By default it * is disabled. * * PLEASE NOTE: This function is not thread-safe. * * Given: * enable int If true (non-zero), enable error messaging, else * disable it. * * Function return value: * int Status return value: * 0: Error messaging is disabled. * 1: Error messaging is enabled. * * * wcserr_size() - Compute the size of a wcserr struct * --------------------------------------------------- * wcserr_size() computes the full size of a wcserr struct, including allocated * memory. * * Given: * err const struct wcserr* * The error object. * * If NULL, the base size of the struct and the allocated * size are both set to zero. * * Returned: * sizes int[2] The first element is the base size of the struct as * returned by sizeof(struct wcserr). The second element * is the total allocated size of the message buffer, in * bytes. * * Function return value: * int Status return value: * 0: Success. * * * wcserr_prt() - Print a wcserr struct * ------------------------------------ * wcserr_prt() prints the error message (if any) contained in a wcserr struct. * It uses the wcsprintf() functions. * * Given: * err const struct wcserr* * The error object. If NULL, nothing is printed. * * prefix const char * * If non-NULL, each output line will be prefixed with * this string. * * Function return value: * int Status return value: * 0: Success. * 2: Error messaging is not enabled. * * * wcserr_clear() - Clear a wcserr struct * -------------------------------------- * wcserr_clear() clears (deletes) a wcserr struct. * * Given and returned: * err struct wcserr** * The error object. If NULL, nothing is done. Set to * NULL on return. * * Function return value: * int Status return value: * 0: Success. * * * wcserr_set() - Fill in the contents of an error object * ------------------------------------------------------ * INTERNAL USE ONLY. * * wcserr_set() fills a wcserr struct with information about an error. * * A convenience macro, WCSERR_SET, provides the source file and line number * information automatically. * * Given and returned: * err struct wcserr** * Error object. * * If err is NULL, returns the status code given without * setting an error message. * * If *err is NULL, allocates memory for a wcserr struct * (provided that status is non-zero). * * Given: * status int Numeric status code to set. If 0, then *err will be * deleted and *err will be returned as NULL. * * function const char * * Name of the function generating the error. This * must point to a constant string, i.e. in the * initialized read-only data section ("data") of the * executable. * * file const char * * Name of the source file generating the error. This * must point to a constant string, i.e. in the * initialized read-only data section ("data") of the * executable such as given by the __FILE__ preprocessor * macro. * * line_no int Line number in the source file generating the error * such as given by the __LINE__ preprocessor macro. * * format const char * * Format string of the error message. May contain * printf-style %-formatting codes. * * ... mixed The remaining variable arguments are applied (like * printf) to the format string to generate the error * message. * * Function return value: * int The status return code passed in. * * * wcserr_copy() - Copy an error object * ------------------------------------ * INTERNAL USE ONLY. * * wcserr_copy() copies one error object to another. Use of this function * should be avoided in general since the function, source file, and line * number information copied to the destination may lose its context. * * Given: * src const struct wcserr* * Source error object. If src is NULL, dst is cleared. * * Returned: * dst struct wcserr* * Destination error object. If NULL, no copy is made. * * Function return value: * int Numeric status code of the source error object. * * * WCSERR_SET() macro - Fill in the contents of an error object * ------------------------------------------------------------ * INTERNAL USE ONLY. * * WCSERR_SET() is a preprocessor macro that helps to fill in the argument list * of wcserr_set(). It takes status as an argument of its own and provides the * name of the source file and the line number at the point where invoked. It * assumes that the err and function arguments of wcserr_set() will be provided * by variables of the same names. * *===========================================================================*/ #ifndef WCSLIB_WCSERR #define WCSLIB_WCSERR #ifdef __cplusplus extern "C" { #endif struct wcserr { int status; // Status code for the error. int line_no; // Line number where the error occurred. const char *function; // Function name. const char *file; // Source file name. char *msg; // Informative error message. }; // Size of the wcserr struct in int units, used by the Fortran wrappers. #define ERRLEN (sizeof(struct wcserr)/sizeof(int)) int wcserr_enable(int enable); int wcserr_size(const struct wcserr *err, int sizes[2]); int wcserr_prt(const struct wcserr *err, const char *prefix); int wcserr_clear(struct wcserr **err); // INTERNAL USE ONLY ------------------------------------------------------- int wcserr_set(struct wcserr **err, int status, const char *function, const char *file, int line_no, const char *format, ...); int wcserr_copy(const struct wcserr *src, struct wcserr *dst); // Convenience macro for invoking wcserr_set(). #define WCSERR_SET(status) err, status, function, __FILE__, __LINE__ #ifdef __cplusplus } #endif #endif // WSCLIB_WCSERR ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/wcsfix.c0000644000175100001710000011666600000000000017051 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcsfix.c,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *===========================================================================*/ #include #include #include #include #include "lin.h" #include "sph.h" #include "tab.h" #include "wcs.h" #include "wcserr.h" #include "wcsfix.h" #include "wcsmath.h" #include "wcstrig.h" #include "wcsunits.h" #include "wcsutil.h" #include "wtbarr.h" extern const int WCSSET; // Maximum number of coordinate axes that can be handled. #define NMAX 16 // Map status return value to message. const char *wcsfix_errmsg[] = { "Success", "Null wcsprm pointer passed", "Memory allocation failed", "Linear transformation matrix is singular", "Inconsistent or unrecognized coordinate axis types", "Invalid parameter value", "Invalid coordinate transformation parameters", "Ill-conditioned coordinate transformation parameters", "All of the corner pixel coordinates are invalid", "Could not determine reference pixel coordinate", "Could not determine reference pixel value"}; // Map error returns for lower-level routines. const int fix_linerr[] = { FIXERR_SUCCESS, // 0: LINERR_SUCCESS FIXERR_NULL_POINTER, // 1: LINERR_NULL_POINTER FIXERR_MEMORY, // 2: LINERR_MEMORY FIXERR_SINGULAR_MTX, // 3: LINERR_SINGULAR_MTX FIXERR_BAD_PARAM, // 4: LINERR_DISTORT_INIT FIXERR_NO_REF_PIX_COORD, // 5: LINERR_DISTORT FIXERR_NO_REF_PIX_VAL // 6: LINERR_DEDISTORT }; const int fix_wcserr[] = { FIXERR_SUCCESS, // 0: WCSERR_SUCCESS FIXERR_NULL_POINTER, // 1: WCSERR_NULL_POINTER FIXERR_MEMORY, // 2: WCSERR_MEMORY FIXERR_SINGULAR_MTX, // 3: WCSERR_SINGULAR_MTX FIXERR_BAD_CTYPE, // 4: WCSERR_BAD_CTYPE FIXERR_BAD_PARAM, // 5: WCSERR_BAD_PARAM FIXERR_BAD_COORD_TRANS, // 6: WCSERR_BAD_COORD_TRANS FIXERR_ILL_COORD_TRANS, // 7: WCSERR_ILL_COORD_TRANS FIXERR_BAD_CORNER_PIX, // 8: WCSERR_BAD_PIX FIXERR_NO_REF_PIX_VAL, // 9: WCSERR_BAD_WORLD FIXERR_NO_REF_PIX_VAL // 10: WCSERR_BAD_WORLD_COORD // ...others not used }; // Convenience macro for invoking wcserr_set(). #define WCSFIX_ERRMSG(status) WCSERR_SET(status), wcsfix_errmsg[status] //---------------------------------------------------------------------------- int wcsfix(int ctrl, const int naxis[], struct wcsprm *wcs, int stat[]) { int status = 0; if ((stat[CDFIX] = cdfix(wcs)) > 0) { status = 1; } if ((stat[DATFIX] = datfix(wcs)) > 0) { status = 1; } if ((stat[OBSFIX] = obsfix(0, wcs)) > 0) { status = 1; } if ((stat[UNITFIX] = unitfix(ctrl, wcs)) > 0) { status = 1; } if ((stat[SPCFIX] = spcfix(wcs)) > 0) { status = 1; } if ((stat[CELFIX] = celfix(wcs)) > 0) { status = 1; } if ((stat[CYLFIX] = cylfix(naxis, wcs)) > 0) { status = 1; } return status; } //---------------------------------------------------------------------------- int wcsfixi( int ctrl, const int naxis[], struct wcsprm *wcs, int stat[], struct wcserr info[]) { int status = 0; // Handling the status values returned from the sub-fixers is trickier than // it might seem, especially considering that wcs->err may contain an error // status on input which should be preserved if no translation errors occur. // The simplest way seems to be to save a copy of wcs->err and clear it // before each sub-fixer. The last real error to occur, excluding // informative messages, is the one returned. // To get informative messages from spcfix() it must precede celfix() and // cylfix(). The latter call wcsset() which also translates AIPS-convention // spectral axes. struct wcserr err; wcserr_copy(wcs->err, &err); for (int ifix = CDFIX; ifix < NWCSFIX; ifix++) { // Clear (delete) wcs->err. wcserr_clear(&(wcs->err)); switch (ifix) { case CDFIX: stat[ifix] = cdfix(wcs); break; case DATFIX: stat[ifix] = datfix(wcs); break; case OBSFIX: stat[ifix] = obsfix(0, wcs); break; case UNITFIX: stat[ifix] = unitfix(ctrl, wcs); break; case SPCFIX: stat[ifix] = spcfix(wcs); break; case CELFIX: stat[ifix] = celfix(wcs); break; case CYLFIX: stat[ifix] = cylfix(naxis, wcs); break; default: continue; } if (stat[ifix] == FIXERR_NO_CHANGE) { // No change => no message. wcserr_copy(0x0, info+ifix); } else if (stat[ifix] == 0) { // Successful translation, but there may be an informative message. if (wcs->err && wcs->err->status < 0) { wcserr_copy(wcs->err, info+ifix); } else { wcserr_copy(0x0, info+ifix); } } else { // An informative message or error message. wcserr_copy(wcs->err, info+ifix); if ((status = (stat[ifix] > 0))) { // It was an error, replace the previous one. wcserr_copy(wcs->err, &err); } } } // Restore the last error to occur. if (err.status) { wcserr_copy(&err, wcs->err); } else { wcserr_clear(&(wcs->err)); } return status; } //---------------------------------------------------------------------------- int cdfix(struct wcsprm *wcs) { if (wcs == 0x0) return FIXERR_NULL_POINTER; if ((wcs->altlin & 1) || !(wcs->altlin & 2)) { // Either we have PCi_ja or there are no CDi_ja. return FIXERR_NO_CHANGE; } int naxis = wcs->naxis; int status = FIXERR_NO_CHANGE; for (int i = 0; i < naxis; i++) { // Row of zeros? double *cd = wcs->cd + i*naxis; for (int k = 0; k < naxis; k++, cd++) { if (*cd != 0.0) goto next; } // Column of zeros? cd = wcs->cd + i; for (int k = 0; k < naxis; k++, cd += naxis) { if (*cd != 0.0) goto next; } cd = wcs->cd + i * (naxis + 1); *cd = 1.0; status = FIXERR_SUCCESS; next: ; } return status; } //---------------------------------------------------------------------------- static int parse_date(const char *buf, int *hour, int *minute, double *sec) { char ctmp[72]; if (sscanf(buf, "%2d:%2d:%s", hour, minute, ctmp) < 3 || wcsutil_str2double(ctmp, sec)) { return 1; } return 0; } static void write_date(char *buf, int hour, int minute, double sec) { char ctmp[32]; wcsutil_double2str(ctmp, "%04.1f", sec); sprintf(buf, "T%.2d:%.2d:%s", hour, minute, ctmp); } static char *newline(char **cp) { size_t k; if ((k = strlen(*cp))) { *cp += k; strcat(*cp, ".\n"); *cp += 2; } return *cp; } int datfix(struct wcsprm *wcs) { static const char *function = "datfix"; // MJD of J2000.0 and B1900.0. const double mjd2000 = 51544.5; const double mjd1900 = 15019.81352; // Days per Julian year and per tropical year. const double djy = 365.25; const double dty = 365.242198781; int day, hour = 0, minute = 0, month, year; double sec = 0.0; if (wcs == 0x0) return FIXERR_NULL_POINTER; struct wcserr **err = &(wcs->err); char infomsg[512]; char *cp = infomsg; *cp = '\0'; int status = FIXERR_NO_CHANGE; for (int i = 0; i < 5; i++) { // MJDREF is split into integer and fractional parts, wheres MJDOBS and // the rest are a single value. const char *dateid; char *date; double *wcsmjd; if (i == 0) { // Note, DATEREF and MJDREF, not DATE-REF and MJD-REF (sigh). dateid = "REF"; date = wcs->dateref; wcsmjd = wcs->mjdref; } else if (i == 1) { dateid = "-OBS"; date = wcs->dateobs; wcsmjd = &(wcs->mjdobs); } else if (i == 2) { dateid = "-BEG"; date = wcs->datebeg; wcsmjd = &(wcs->mjdbeg); } else if (i == 3) { dateid = "-AVG"; date = wcs->dateavg; wcsmjd = &(wcs->mjdavg); } else if (i == 4) { dateid = "-END"; date = wcs->dateend; wcsmjd = &(wcs->mjdend); } char orig_date[72]; strncpy(orig_date, date, 72); if (date[0] == '\0') { // Fill in DATE from MJD if possible. if (i == 1 && undefined(*wcsmjd)) { // See if we have jepoch or bepoch. if (!undefined(wcs->jepoch)) { *wcsmjd = mjd2000 + (wcs->jepoch - 2000.0)*djy; sprintf(newline(&cp), "Set MJD-OBS to %.6f from JEPOCH", *wcsmjd); if (status == FIXERR_NO_CHANGE) status = FIXERR_SUCCESS; } else if (!undefined(wcs->bepoch)) { *wcsmjd = mjd1900 + (wcs->bepoch - 1900.0)*dty; sprintf(newline(&cp), "Set MJD-OBS to %.6f from BEPOCH", *wcsmjd); if (status == FIXERR_NO_CHANGE) status = FIXERR_SUCCESS; } } if (undefined(*wcsmjd)) { // No date information was provided. } else { // Calendar date from MJD, with allowance for MJD < 0. double mjd[2], t; if (i == 0) { // MJDREF is already split into integer and fractional parts. mjd[0] = wcsmjd[0]; mjd[1] = wcsmjd[1]; if (1.0 < mjd[1]) { // Ensure the fractional part lies between 0 and +1. t = floor(mjd[1]); mjd[0] += t; mjd[1] -= t; } } else { // Split it into integer and fractional parts. mjd[0] = floor(*wcsmjd); mjd[1] = *wcsmjd - mjd[0]; } int jd = 2400001 + (int)mjd[0]; int n4 = 4*(jd + ((2*((4*jd - 17918)/146097)*3)/4 + 1)/2 - 37); int dd = 10*(((n4-237)%1461)/4) + 5; year = n4/1461 - 4712; month = (2 + dd/306)%12 + 1; day = (dd%306)/10 + 1; sprintf(date, "%.4d-%.2d-%.2d", year, month, day); // Write time part only if non-zero. if (0.0 < (t = mjd[1])) { t *= 24.0; hour = (int)t; t = 60.0 * (t - hour); minute = (int)t; sec = 60.0 * (t - minute); // Round to 1ms. dd = 60000*(60*hour + minute) + (int)(1000*(sec+0.0005)); hour = dd / 3600000; dd -= 3600000 * hour; minute = dd / 60000; int msec = dd - 60000 * minute; sprintf(date+10, "T%.2d:%.2d:%.2d", hour, minute, msec/1000); // Write fractions of a second only if non-zero. if (msec%1000) { sprintf(date+19, ".%.3d", msec%1000); } } } } else { if (strlen(date) < 8) { // Can't be a valid date. status = FIXERR_BAD_PARAM; sprintf(newline(&cp), "Invalid DATE%s format '%s' is too short", dateid, date); continue; } // Identify the date format. if (date[4] == '-' && date[7] == '-') { // Standard year-2000 form: CCYY-MM-DD[Thh:mm:ss[.sss...]] if (sscanf(date, "%4d-%2d-%2d", &year, &month, &day) < 3) { status = FIXERR_BAD_PARAM; sprintf(newline(&cp), "Invalid DATE%s format '%s'", dateid, date); continue; } if (date[10] == 'T') { if (parse_date(date+11, &hour, &minute, &sec)) { status = FIXERR_BAD_PARAM; sprintf(newline(&cp), "Invalid time in DATE%s '%s'", dateid, date+11); continue; } } else if (date[10] == ' ') { hour = 0; minute = 0; sec = 0.0; if (parse_date(date+11, &hour, &minute, &sec)) { write_date(date+10, hour, minute, sec); } else { date[10] = 'T'; } } } else if (date[4] == '/' && date[7] == '/') { // Also allow CCYY/MM/DD[Thh:mm:ss[.sss...]] if (sscanf(date, "%4d/%2d/%2d", &year, &month, &day) < 3) { status = FIXERR_BAD_PARAM; sprintf(newline(&cp), "Invalid DATE%s format '%s'", dateid, date); continue; } if (date[10] == 'T') { if (parse_date(date+11, &hour, &minute, &sec)) { status = FIXERR_BAD_PARAM; sprintf(newline(&cp), "Invalid time in DATE%s '%s'", dateid, date+11); continue; } } else if (date[10] == ' ') { hour = 0; minute = 0; sec = 0.0; if (parse_date(date+11, &hour, &minute, &sec)) { write_date(date+10, hour, minute, sec); } else { date[10] = 'T'; } } // Looks ok, fix it up. date[4] = '-'; date[7] = '-'; } else { if (i == 1 && date[2] == '/' && date[5] == '/') { // Old format DATE-OBS date: DD/MM/YY, also allowing DD/MM/CCYY. if (sscanf(date, "%2d/%2d/%4d", &day, &month, &year) < 3) { status = FIXERR_BAD_PARAM; sprintf(newline(&cp), "Invalid DATE%s format '%s'", dateid, date); continue; } } else if (i == 1 && date[2] == '-' && date[5] == '-') { // Also recognize DD-MM-YY and DD-MM-CCYY if (sscanf(date, "%2d-%2d-%4d", &day, &month, &year) < 3) { status = FIXERR_BAD_PARAM; sprintf(newline(&cp), "Invalid DATE%s format '%s'", dateid, date); continue; } } else { // Not a valid date format. status = FIXERR_BAD_PARAM; sprintf(newline(&cp), "Invalid DATE%s format '%s'", dateid, date); continue; } if (year < 100) year += 1900; // Doesn't have a time. sprintf(date, "%.4d-%.2d-%.2d", year, month, day); } // Compute MJD. double mjd[2]; mjd[0] = (double)((1461*(year - (12-month)/10 + 4712))/4 + (306*((month+9)%12) + 5)/10 - (3*((year - (12-month)/10 + 4900)/100))/4 + day - 2399904); mjd[1] = (hour + (minute + sec/60.0)/60.0)/24.0; double mjdsum = mjd[0] + mjd[1]; if (undefined(*wcsmjd)) { if (i == 0) { wcsmjd[0] = mjd[0]; wcsmjd[1] = mjd[1]; } else { *wcsmjd = mjdsum; } sprintf(newline(&cp), "Set MJD%s to %.6f from DATE%s", dateid, mjdsum, dateid); if (status == FIXERR_NO_CHANGE) status = FIXERR_SUCCESS; } else { // Check for consistency. double mjdtmp; if (i == 0) { mjdtmp = wcsmjd[0] + wcsmjd[1]; } else { mjdtmp = *wcsmjd; } if (0.001 < fabs(mjdsum - mjdtmp)) { status = FIXERR_BAD_PARAM; sprintf(newline(&cp), "Invalid parameter values: MJD%s and DATE%s are inconsistent", dateid, dateid); } } if (i == 1) { if (!undefined(wcs->jepoch)) { // Check consistency of JEPOCH. double jepoch = 2000.0 + (*wcsmjd - mjd2000) / djy; if (0.000002 < fabs(jepoch - wcs->jepoch)) { // Informational only, no error. sprintf(newline(&cp), "JEPOCH is inconsistent with DATE-OBS"); } } if (!undefined(wcs->bepoch)) { // Check consistency of BEPOCH. double bepoch = 1900.0 + (*wcsmjd - mjd1900) / dty; if (0.000002 < fabs(bepoch - wcs->bepoch)) { // Informational only, no error. sprintf(newline(&cp), "BEPOCH is inconsistent with DATE-OBS"); } } } } if (strncmp(orig_date, date, 72)) { if (orig_date[0] == '\0') { sprintf(newline(&cp), "Set DATE%s to '%s' from MJD%s", dateid, date, dateid); } else { sprintf(newline(&cp), "Changed DATE%s from '%s' to '%s'", dateid, orig_date, date); } if (status == FIXERR_NO_CHANGE) status = FIXERR_SUCCESS; } } if (*infomsg) { wcserr_set(WCSERR_SET(FIXERR_DATE_FIX), infomsg); } return status; } //---------------------------------------------------------------------------- int obsfix(int ctrl, struct wcsprm *wcs) { static const char *function = "obsfix"; // IAU(1976) ellipsoid (as prescribed by WCS Paper VII). const double a = 6378140.0; const double f = 1.0 / 298.2577; const double e2 = (2.0 - f)*f; if (wcs == 0x0) return FIXERR_NULL_POINTER; struct wcserr **err = &(wcs->err); // Set masks for checking partially-defined coordinate triplets. int havexyz = 7; havexyz -= 1*undefined(wcs->obsgeo[0]); havexyz -= 2*undefined(wcs->obsgeo[1]); havexyz -= 4*undefined(wcs->obsgeo[2]); int havelbh = 7; havelbh -= 1*undefined(wcs->obsgeo[3]); havelbh -= 2*undefined(wcs->obsgeo[4]); havelbh -= 4*undefined(wcs->obsgeo[5]); if (ctrl == 2) { // Make no changes. if (0 < havexyz && havexyz < 7) { return wcserr_set(WCSERR_SET(FIXERR_BAD_PARAM), "Partially undefined Cartesian coordinate triplet"); } if (0 < havelbh && havelbh < 7) { return wcserr_set(WCSERR_SET(FIXERR_BAD_PARAM), "Partially undefined Geodetic coordinate triplet"); } if (havexyz == 0 || havelbh == 0) { return FIXERR_NO_CHANGE; } } if (havexyz == 0 && havelbh == 0) { return FIXERR_NO_CHANGE; } char infomsg[256]; infomsg[0] = '\0'; int status = FIXERR_NO_CHANGE; size_t k; double x, y, z; if (havelbh == 7) { // Compute (x,y,z) from (lng,lat,hgt). double coslat, coslng, sinlat, sinlng; sincosd(wcs->obsgeo[3], &sinlng, &coslng); sincosd(wcs->obsgeo[4], &sinlat, &coslat); double n = a / sqrt(1.0 - e2*sinlat*sinlat); double rho = n + wcs->obsgeo[5]; x = rho*coslng*coslat; y = rho*sinlng*coslat; z = (rho - n*e2)*sinlat; if (havexyz < 7) { // One or more of the Cartesian elements was undefined. status = FIXERR_SUCCESS; char *cp = infomsg; if (ctrl == 1 || !(havexyz & 1)) { wcs->obsgeo[0] = x; sprintf(cp, "%s OBSGEO-X to %12.3f from OBSGEO-[LBH]", (havexyz & 1) ? "Reset" : "Set", x); } if (ctrl == 1 || !(havexyz & 2)) { wcs->obsgeo[1] = y; if ((k = strlen(cp))) { strcat(cp+k, ".\n"); cp += k + 2; } sprintf(cp, "%s OBSGEO-Y to %12.3f from OBSGEO-[LBH]", (havexyz & 2) ? "Reset" : "Set", y); } if (ctrl == 1 || !(havexyz & 4)) { wcs->obsgeo[2] = z; if ((k = strlen(cp))) { strcat(cp+k, ".\n"); cp += k + 2; } sprintf(cp, "%s OBSGEO-Z to %12.3f from OBSGEO-[LBH]", (havexyz & 4) ? "Reset" : "Set", z); } wcserr_set(WCSERR_SET(FIXERR_OBSGEO_FIX), infomsg); if (havexyz == 0) { // Skip the consistency check. return status; } } } else if (havexyz == 7) { // Compute (lng,lat,hgt) from (x,y,z). x = wcs->obsgeo[0]; y = wcs->obsgeo[1]; z = wcs->obsgeo[2]; double r2 = x*x + y*y; // Iterate over the value of zeta. double coslat, coslng, sinlat, sinlng; double n, rho, zeta = z; for (int i = 0; i < 4; i++) { rho = sqrt(r2 + zeta*zeta); sinlat = zeta / rho; n = a / sqrt(1.0 - e2*sinlat*sinlat); zeta = z / (1.0 - n*e2/rho); } double lng = atan2d(y, x); double lat = asind(sinlat); double hgt = rho - n; if (havelbh < 7) { // One or more of the Geodetic elements was undefined. status = FIXERR_SUCCESS; char *cp = infomsg; if (ctrl == 1 || !(havelbh & 1)) { wcs->obsgeo[3] = lng; sprintf(cp, "%s OBSGEO-L to %12.6f from OBSGEO-[XYZ]", (havelbh & 1) ? "Reset" : "Set", lng); } if (ctrl == 1 || !(havelbh & 2)) { wcs->obsgeo[4] = lat; if ((k = strlen(cp))) { strcat(cp+k, ".\n"); cp += k + 2; } sprintf(cp, "%s OBSGEO-B to %12.6f from OBSGEO-[XYZ]", (havelbh & 2) ? "Reset" : "Set", lat); } if (ctrl == 1 || !(havelbh & 4)) { wcs->obsgeo[5] = hgt; if ((k = strlen(cp))) { strcat(cp+k, ".\n"); cp += k + 2; } sprintf(cp, "%s OBSGEO-H to %12.3f from OBSGEO-[XYZ]", (havelbh & 4) ? "Reset" : "Set", hgt); } wcserr_set(WCSERR_SET(FIXERR_OBSGEO_FIX), infomsg); if (havelbh == 0) { // Skip the consistency check. return status; } } // Compute (x,y,z) from (lng,lat,hgt) for consistency checking. sincosd(wcs->obsgeo[3], &sinlng, &coslng); sincosd(wcs->obsgeo[4], &sinlat, &coslat); n = a / sqrt(1.0 - e2*sinlat*sinlat); rho = n + wcs->obsgeo[5]; x = rho*coslng*coslat; y = rho*sinlng*coslat; z = (rho - n*e2)*sinlat; } else { return wcserr_set(WCSERR_SET(FIXERR_BAD_PARAM), "Observatory coordinates incomplete"); } // Check consistency. double d, r2 = 0.0; d = wcs->obsgeo[0] - x; r2 += d*d; d = wcs->obsgeo[1] - y; r2 += d*d; d = wcs->obsgeo[2] - z; r2 += d*d; if (1.0 < r2) { d = sqrt(r2); return wcserr_set(WCSERR_SET(FIXERR_BAD_PARAM), "Observatory coordinates inconsistent by %.1f metres", d); } return status; } //---------------------------------------------------------------------------- int unitfix(int ctrl, struct wcsprm *wcs) { const char *function = "unitfix"; if (wcs == 0x0) return FIXERR_NULL_POINTER; struct wcserr **err = &(wcs->err); int status = FIXERR_NO_CHANGE; char msg[512]; strncpy(msg, "Changed units:", 512); for (int i = 0; i < wcs->naxis; i++) { char orig_unit[72]; strncpy(orig_unit, wcs->cunit[i], 71); int result = wcsutrne(ctrl, wcs->cunit[i], &(wcs->err)); if (result == 0 || result == 12) { size_t msglen = strlen(msg); if (msglen < 511) { wcsutil_null_fill(72, orig_unit); char msgtmp[192]; sprintf(msgtmp, "\n '%s' -> '%s',", orig_unit, wcs->cunit[i]); strncpy(msg+msglen, msgtmp, 511-msglen); status = FIXERR_UNITS_ALIAS; } } } if (status == FIXERR_UNITS_ALIAS) { // Chop off the trailing ", ". size_t msglen = strlen(msg) - 2; msg[msglen] = '\0'; wcserr_set(WCSERR_SET(FIXERR_UNITS_ALIAS), msg); status = FIXERR_SUCCESS; } return status; } //---------------------------------------------------------------------------- int spcfix(struct wcsprm *wcs) { static const char *function = "spcfix"; if (wcs == 0x0) return FIXERR_NULL_POINTER; struct wcserr **err = &(wcs->err); for (int i = 0; i < wcs->naxis; i++) { // Translate an AIPS-convention spectral type if present. char ctype[9], specsys[9]; int status = spcaips(wcs->ctype[i], wcs->velref, ctype, specsys); if (status == FIXERR_SUCCESS) { // An AIPS type was found but it may match what we already have. status = FIXERR_NO_CHANGE; // Was specsys translated? if (wcs->specsys[0] == '\0' && *specsys) { strncpy(wcs->specsys, specsys, 9); wcserr_set(WCSERR_SET(FIXERR_SPC_UPDATE), "Changed SPECSYS to '%s'", specsys); status = FIXERR_SUCCESS; } // Was ctype translated? Have to null-fill for comparing them. wcsutil_null_fill(9, wcs->ctype[i]); if (strncmp(wcs->ctype[i], ctype, 9)) { // ctype was translated... if (status == FIXERR_SUCCESS) { // ...and specsys was also. wcserr_set(WCSERR_SET(FIXERR_SPC_UPDATE), "Changed CTYPE%d from '%s' to '%s', and SPECSYS to '%s' " "(VELREF=%d)", i+1, wcs->ctype[i], ctype, wcs->specsys, wcs->velref); } else { wcserr_set(WCSERR_SET(FIXERR_SPC_UPDATE), "Changed CTYPE%d from '%s' to '%s' (VELREF=%d)", i+1, wcs->ctype[i], ctype, wcs->velref); status = FIXERR_SUCCESS; } strncpy(wcs->ctype[i], ctype, 9); } // Tidy up. if (status == FIXERR_SUCCESS) { wcsutil_null_fill(72, wcs->ctype[i]); wcsutil_null_fill(72, wcs->specsys); } // No need to check for others, wcsset() will fail if so. return status; } else if (status == SPCERR_BAD_SPEC_PARAMS) { // An AIPS spectral type was found but with invalid velref. return wcserr_set(WCSERR_SET(FIXERR_BAD_PARAM), "Invalid parameter value: velref = %d", wcs->velref); } } return FIXERR_NO_CHANGE; } //---------------------------------------------------------------------------- int celfix(struct wcsprm *wcs) { static const char *function = "celfix"; if (wcs == 0x0) return FIXERR_NULL_POINTER; struct wcserr **err = &(wcs->err); // Initialize if required. int status; if (wcs->flag != WCSSET) { if ((status = wcsset(wcs))) return fix_wcserr[status]; } // Was an NCP or GLS projection code translated? if (wcs->lat >= 0) { // Check ctype. if (strcmp(wcs->ctype[wcs->lat]+5, "NCP") == 0) { strcpy(wcs->ctype[wcs->lng]+5, "SIN"); strcpy(wcs->ctype[wcs->lat]+5, "SIN"); if (wcs->npvmax < wcs->npv + 2) { // Allocate space for two more PVi_ma keyvalues. if (wcs->m_flag == WCSSET && wcs->pv == wcs->m_pv) { if (!(wcs->pv = calloc(wcs->npv+2, sizeof(struct pvcard)))) { wcs->pv = wcs->m_pv; return wcserr_set(WCSFIX_ERRMSG(FIXERR_MEMORY)); } wcs->npvmax = wcs->npv + 2; wcs->m_flag = WCSSET; for (int k = 0; k < wcs->npv; k++) { wcs->pv[k] = wcs->m_pv[k]; } if (wcs->m_pv) free(wcs->m_pv); wcs->m_pv = wcs->pv; } else { return wcserr_set(WCSFIX_ERRMSG(FIXERR_MEMORY)); } } struct celprm *wcscel = &(wcs->cel); struct prjprm *wcsprj = &(wcscel->prj); wcs->pv[wcs->npv].i = wcs->lat + 1; wcs->pv[wcs->npv].m = 1; wcs->pv[wcs->npv].value = wcsprj->pv[1]; (wcs->npv)++; wcs->pv[wcs->npv].i = wcs->lat + 1; wcs->pv[wcs->npv].m = 2; wcs->pv[wcs->npv].value = wcsprj->pv[2]; (wcs->npv)++; return FIXERR_SUCCESS; } else if (strcmp(wcs->ctype[wcs->lat]+5, "GLS") == 0) { strcpy(wcs->ctype[wcs->lng]+5, "SFL"); strcpy(wcs->ctype[wcs->lat]+5, "SFL"); if (wcs->crval[wcs->lng] != 0.0 || wcs->crval[wcs->lat] != 0.0) { // In the AIPS convention, setting the reference longitude and // latitude for GLS does not create an oblique graticule. A non-zero // reference longitude introduces an offset in longitude in the normal // way, whereas a non-zero reference latitude simply translates the // reference point (i.e. the map as a whole) to that latitude. This // might be effected by adjusting CRPIXja but that is complicated by // the linear transformation and instead is accomplished here by // setting theta_0. if (wcs->npvmax < wcs->npv + 3) { // Allocate space for three more PVi_ma keyvalues. if (wcs->m_flag == WCSSET && wcs->pv == wcs->m_pv) { if (!(wcs->pv = calloc(wcs->npv+3, sizeof(struct pvcard)))) { wcs->pv = wcs->m_pv; return wcserr_set(WCSFIX_ERRMSG(FIXERR_MEMORY)); } wcs->npvmax = wcs->npv + 3; wcs->m_flag = WCSSET; for (int k = 0; k < wcs->npv; k++) { wcs->pv[k] = wcs->m_pv[k]; } if (wcs->m_pv) free(wcs->m_pv); wcs->m_pv = wcs->pv; } else { return wcserr_set(WCSFIX_ERRMSG(FIXERR_MEMORY)); } } wcs->pv[wcs->npv].i = wcs->lng + 1; wcs->pv[wcs->npv].m = 0; wcs->pv[wcs->npv].value = 1.0; (wcs->npv)++; // Note that the reference longitude is still zero. wcs->pv[wcs->npv].i = wcs->lng + 1; wcs->pv[wcs->npv].m = 1; wcs->pv[wcs->npv].value = 0.0; (wcs->npv)++; wcs->pv[wcs->npv].i = wcs->lng + 1; wcs->pv[wcs->npv].m = 2; wcs->pv[wcs->npv].value = wcs->crval[wcs->lat]; (wcs->npv)++; } return FIXERR_SUCCESS; } } return FIXERR_NO_CHANGE; } //---------------------------------------------------------------------------- int cylfix(const int naxis[], struct wcsprm *wcs) { static const char *function = "cylfix"; if (naxis == 0x0) return FIXERR_NO_CHANGE; if (wcs == 0x0) return FIXERR_NULL_POINTER; struct wcserr **err = &(wcs->err); // Initialize if required. int status; if (wcs->flag != WCSSET) { if ((status = wcsset(wcs))) return fix_wcserr[status]; } // Check that we have a cylindrical projection. if (wcs->cel.prj.category != CYLINDRICAL) return FIXERR_NO_CHANGE; if (wcs->naxis < 2) return FIXERR_NO_CHANGE; // Compute the native longitude in each corner of the image. unsigned short ncnr = 1 << wcs->naxis; unsigned short indx[NMAX]; for (int k = 0; k < NMAX; k++) { indx[k] = 1 << k; } int stat[4]; double img[4][NMAX], phi[4], pix[4][NMAX], theta[4], world[4][NMAX]; double phimin = 1.0e99; double phimax = -1.0e99; for (unsigned short icnr = 0; icnr < ncnr;) { // Do four corners at a time. for (int j = 0; j < 4; j++, icnr++) { double *pixj = pix[j]; for (int k = 0; k < wcs->naxis; k++) { if (icnr & indx[k]) { *(pixj++) = naxis[k] + 0.5; } else { *(pixj++) = 0.5; } } } if (!(status = wcsp2s(wcs, 4, NMAX, pix[0], img[0], phi, theta, world[0], stat))) { for (int j = 0; j < 4; j++) { if (phi[j] < phimin) phimin = phi[j]; if (phi[j] > phimax) phimax = phi[j]; } } } if (phimin > phimax) return fix_wcserr[status]; // Any changes needed? if (phimin >= -180.0 && phimax <= 180.0) return FIXERR_NO_CHANGE; // Compute the new reference pixel coordinates. double phi0 = (phimin + phimax) / 2.0; double theta0 = 0.0; double x, y; if ((status = prjs2x(&(wcs->cel.prj), 1, 1, 1, 1, &phi0, &theta0, &x, &y, stat))) { if (status == PRJERR_BAD_PARAM) { status = FIXERR_BAD_PARAM; } else { status = FIXERR_NO_REF_PIX_COORD; } return wcserr_set(WCSFIX_ERRMSG(status)); } for (int k = 0; k < wcs->naxis; k++) { img[0][k] = 0.0; } img[0][wcs->lng] = x; img[0][wcs->lat] = y; if ((status = linx2p(&(wcs->lin), 1, 0, img[0], pix[0]))) { return wcserr_set(WCSFIX_ERRMSG(fix_linerr[status])); } // Compute celestial coordinates at the new reference pixel. if ((status = wcsp2s(wcs, 1, 0, pix[0], img[0], phi, theta, world[0], stat))) { return fix_wcserr[status]; } // Compute native coordinates of the celestial pole. double lng = 0.0; double lat = 90.0; (void)sphs2x(wcs->cel.euler, 1, 1, 1, 1, &lng, &lat, phi, theta); wcs->crpix[wcs->lng] = pix[0][wcs->lng]; wcs->crpix[wcs->lat] = pix[0][wcs->lat]; wcs->crval[wcs->lng] = world[0][wcs->lng]; wcs->crval[wcs->lat] = world[0][wcs->lat]; wcs->lonpole = phi[0] - phi0; return wcsset(wcs); } //---------------------------------------------------------------------------- // Helper function used only by wcspcx(). static int unscramble(int n, int mapto[], int step, int type, void *vptr); int wcspcx( struct wcsprm *wcs, int dopc, int permute, double rotn[2]) { static const char *function = "wcspcx"; // Initialize if required. if (wcs == 0x0) return FIXERR_NULL_POINTER; struct wcserr **err = &(wcs->err); int status; if (wcs->flag != WCSSET) { if ((status = wcsset(wcs))) return fix_wcserr[status]; } // Check for CDi_j usage. double *wcscd = wcs->cd; if ((wcs->altlin & 1) || !(wcs->altlin & 2)) { if ((wcs->altlin & 1) && dopc == 1) { // Recompose PCi_j + CDELTi. wcscd = wcs->pc; } else { return wcserr_set(WCSERR_SET(FIXERR_BAD_PARAM), "CDi_j is not used in this coordinate representation"); } } // Check for sequent distortions. if (wcs->lin.disseq) { return wcserr_set(WCSERR_SET(FIXERR_BAD_COORD_TRANS), "Cannot handle coordinate descriptions containing sequent distortions"); } // Allocate memory in bulk for two nxn matrices. int naxis = wcs->naxis; double *mem; if ((mem = calloc(2*naxis*naxis, sizeof(double))) == 0x0) { return wcserr_set(WCSFIX_ERRMSG(FIXERR_MEMORY)); } double *mat = mem; double *inv = mem + naxis*naxis; // Construct the transpose of CDi_j with each element squared. double *matij = mat; for (int i = 0; i < naxis; i++) { double *cdji = wcscd + i; for (int j = 0; j < naxis; j++) { *(matij++) = (*cdji) * (*cdji); cdji += naxis; } } // Invert the matrix. if ((status = matinv(naxis, mat, inv))) { return wcserr_set(WCSERR_SET(FIXERR_SINGULAR_MTX), "No solution for CDi_j matrix decomposition"); } // Apply scaling. double *invij = inv; double *pcij = wcs->pc; double *cdij = wcscd; for (int i = 0; i < naxis; i++) { double scl = 0.0; for (int j = 0; j < naxis; j++) { scl += *(invij++); } scl = sqrt(scl); wcs->cdelt[i] /= scl; for (int j = 0; j < naxis; j++) { *(pcij++) = *(cdij++) * scl; } } // mapto[i] records where row i of PCi_j should move to. int *mapto = 0x0; if ((mapto = (int*)malloc(naxis*sizeof(int))) == 0x0) { free(mem); return wcserr_set(WCSFIX_ERRMSG(FIXERR_MEMORY)); } for (int i = 0; i < naxis; i++) { mapto[i] = -1; } // Ensure that latitude always follows longitude. if (wcs->lng >= 0 && wcs->lat >= 0) { double *pci = wcs->pc + naxis*wcs->lng; // Take the first non-zero element in the row. for (int j = 0; j < naxis; j++) { if (fabs(pci[j]) != 0.0) { mapto[wcs->lng] = j; break; } } if (mapto[wcs->lng] == naxis-1) { mapto[wcs->lng]--; } mapto[wcs->lat] = mapto[wcs->lng] + 1; } // Fill in the rest of the row permutation map. for (int j = 0; j < naxis; j++) { // Column j. double *pcij = wcs->pc + j; double colmax = 0.0; // Look down the column to find the absolute maximum element. for (int i = 0; i < naxis; i++, pcij += naxis) { if (!(mapto[i] < 0)) { // This row is already mapped. continue; } if (fabs(*pcij) > colmax) { mapto[i] = j; colmax = fabs(*pcij); } } } // Fix the sign of CDELTi. Celestial axes are special, otherwise diagonal // elements of the correctly permuted matrix should be positive. for (int i = 0; i < naxis; i++) { int chsgn; double *pci = wcs->pc + naxis*i; // Celestial axes are special. if (i == wcs->lng) { // Longitude axis - force CDELTi < 0.0. chsgn = (wcs->cdelt[i] > 0.0); } else if (i == wcs->lat) { // Latitude axis - force CDELTi > 0.0. chsgn = (wcs->cdelt[i] < 0.0); } else { chsgn = (pci[mapto[i]] < 0.0); } if (chsgn) { wcs->cdelt[i] = -wcs->cdelt[i]; for (int j = 0; j < naxis; j++) { // Test needed to prevent negative zeros. if (pci[j] != 0.0) { pci[j] = -pci[j]; } } } } free(mem); // Setting bit 3 in wcsprm::altlin stops wcsset() from reconstructing // PCi_j and CDELTi from CDi_j. wcs->altlin |= 8; // Compute rotation angle of each basis vector of the celestial axes. if (rotn) { if (wcs->lng < 0 || wcs->lat < 0) { // No celestial axes. rotn[0] = 0.0; rotn[1] = 0.0; } else { double x, y; x = wcs->pc[naxis*wcs->lng + mapto[wcs->lng]]; y = wcs->pc[naxis*wcs->lat + mapto[wcs->lng]]; rotn[0] = atan2d(y, x); y = -wcs->pc[naxis*wcs->lng + mapto[wcs->lat]]; x = wcs->pc[naxis*wcs->lat + mapto[wcs->lat]]; rotn[1] = atan2d(y, x); } } // Permute rows? if (permute) { // Check whether there's anything to unscramble. int scrambled = 0; for (int i = 0; i < naxis; i++) { if (mapto[i] != i) { scrambled = 1; break; } } if (scrambled) { for (int i = 0; i < naxis; i++) { // Do columns of the PCi_ja matrix. if (unscramble(naxis, mapto, naxis, 1, wcs->pc + i)) goto cleanup; } if (unscramble(naxis, mapto, 1, 1, wcs->cdelt)) goto cleanup; if (unscramble(naxis, mapto, 1, 1, wcs->crval)) goto cleanup; if (unscramble(naxis, mapto, 1, 2, wcs->cunit)) goto cleanup; if (unscramble(naxis, mapto, 1, 2, wcs->ctype)) goto cleanup; for (int ipv = 0; ipv < wcs->npv; ipv++) { // Noting that PVi_ma axis numbers are 1-relative. int i = wcs->pv[ipv].i - 1; wcs->pv[ipv].i = mapto[i] + 1; } for (int ips = 0; ips < wcs->nps; ips++) { // Noting that PSi_ma axis numbers are 1-relative. int i = wcs->ps[ips].i - 1; wcs->ps[ips].i = mapto[i] + 1; } if (wcs->altlin & 2) { for (int i = 0; i < naxis; i++) { // Do columns of the CDi_ja matrix. if (unscramble(naxis, mapto, naxis, 1, wcs->cd + i)) goto cleanup; } } if (wcs->altlin & 4) { if (unscramble(naxis, mapto, 1, 1, wcs->crota)) goto cleanup; } if (unscramble(naxis, mapto, 1, 3, wcs->colax)) goto cleanup; if (unscramble(naxis, mapto, 1, 2, wcs->cname)) goto cleanup; if (unscramble(naxis, mapto, 1, 1, wcs->crder)) goto cleanup; if (unscramble(naxis, mapto, 1, 1, wcs->csyer)) goto cleanup; if (unscramble(naxis, mapto, 1, 1, wcs->czphs)) goto cleanup; if (unscramble(naxis, mapto, 1, 1, wcs->cperi)) goto cleanup; // Coordinate lookup tables. for (int itab = 0; itab < wcs->ntab; itab++) { for (int m = 0; m < wcs->tab[itab].M; m++) { int i = wcs->tab[itab].map[m]; wcs->tab[itab].map[m] = mapto[i]; } } for (int iwtb = 0; iwtb < wcs->nwtb; iwtb++) { int i = wcs->wtb[iwtb].i; wcs->wtb[iwtb].i = mapto[i]; } // Distortions? No. Prior distortions operate on pixel coordinates and // therefore are not permuted, and sequent distortions are not handled. } } free(mapto); // Reset the struct. if ((status = wcsset(wcs))) return fix_wcserr[status]; return FIXERR_SUCCESS; cleanup: if (mapto) free(mapto); return wcserr_set(WCSFIX_ERRMSG(FIXERR_MEMORY)); } int unscramble( int n, int mapto[], int step, int type, void *vptr) { if (step == 0) step = 1; if (type == 1) { double *dval = (double *)vptr; double *dtmp; if ((dtmp = (double *)malloc(n*sizeof(double))) == 0x0) { return 1; } for (int i = 0; i < n; i++) { dtmp[mapto[i]] = dval[i*step]; } for (int i = 0; i < n; i++) { dval[i*step] = dtmp[i]; } free(dtmp); } else if (type == 2) { char (*cval)[72] = (char (*)[72])vptr; char (*ctmp)[72]; if ((ctmp = (char (*)[72])malloc(n*72*sizeof(char))) == 0x0) { return 1; } for (int i = 0; i < n; i++) { memcpy(ctmp[mapto[i]], cval[i], 72); } for (int i = 0; i < n; i++) { memcpy(cval[i], ctmp[i], 72); } free(ctmp); } else if (type == 3) { int *ival = (int *)vptr; int *itmp; if ((itmp = (int *)malloc(n*sizeof(int))) == 0x0) { return 1; } for (int i = 0; i < n; i++) { itmp[mapto[i]] = ival[i]; } for (int i = 0; i < n; i++) { ival[i] = itmp[i]; } free(itmp); } return 0; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/wcsfix.h0000644000175100001710000007233700000000000017052 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcsfix.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the wcsfix routines * ------------------------------ * Routines in this suite identify and translate various forms of construct * known to occur in FITS headers that violate the FITS World Coordinate System * (WCS) standard described in * = "Representations of world coordinates in FITS", = Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (WCS Paper I) = = "Representations of celestial coordinates in FITS", = Calabretta, M.R., & Greisen, E.W. 2002, A&A, 395, 1077 (WCS Paper II) = = "Representations of spectral coordinates in FITS", = Greisen, E.W., Calabretta, M.R., Valdes, F.G., & Allen, S.L. = 2006, A&A, 446, 747 (WCS Paper III) = = "Representations of time coordinates in FITS - = Time and relative dimension in space", = Rots, A.H., Bunclark, P.S., Calabretta, M.R., Allen, S.L., = Manchester, R.N., & Thompson, W.T. 2015, A&A, 574, A36 (WCS Paper VII) * * Repairs effected by these routines range from the translation of * non-standard values for standard WCS keywords, to the repair of malformed * coordinate representations. Some routines are also provided to check the * consistency of pairs of keyvalues that define the same measure in two * different ways, for example, as a date and an MJD. * * A separate routine, wcspcx(), "regularizes" the linear transformation matrix * component (PCi_j) of the coordinate transformation to make it more human- * readable. Where a coordinate description was constructed from CDi_j, it * decomposes it into PCi_j + CDELTi in a meaningful way. Optionally, it can * also diagonalize the PCi_j matrix (as far as possible), i.e. undo a * transposition of axes in the intermediate pixel coordinate system. * * Non-standard keyvalues: * ----------------------- * AIPS-convention celestial projection types, NCP and GLS, and spectral * types, 'FREQ-LSR', 'FELO-HEL', etc., set in CTYPEia are translated * on-the-fly by wcsset() but without modifying the relevant ctype[], pv[] or * specsys members of the wcsprm struct. That is, only the information * extracted from ctype[] is translated when wcsset() fills in wcsprm::cel * (celprm struct) or wcsprm::spc (spcprm struct). * * On the other hand, these routines do change the values of wcsprm::ctype[], * wcsprm::pv[], wcsprm::specsys and other wcsprm struct members as * appropriate to produce the same result as if the FITS header itself had * been translated. * * Auxiliary WCS header information not used directly by WCSLIB may also be * translated. For example, the older DATE-OBS date format (wcsprm::dateobs) * is recast to year-2000 standard form, and MJD-OBS (wcsprm::mjdobs) will be * deduced from it if not already set. * * Certain combinations of keyvalues that result in malformed coordinate * systems, as described in Sect. 7.3.4 of Paper I, may also be repaired. * These are handled by cylfix(). * * Non-standard keywords: * ---------------------- * The AIPS-convention CROTAn keywords are recognized as quasi-standard * and as such are accomodated by wcsprm::crota[] and translated to * wcsprm::pc[][] by wcsset(). These are not dealt with here, nor are any * other non-standard keywords since these routines work only on the contents * of a wcsprm struct and do not deal with FITS headers per se. In * particular, they do not identify or translate CD00i00j, PC00i00j, PROJPn, * EPOCH, VELREF or VSOURCEa keywords; this may be done by the FITS WCS * header parser supplied with WCSLIB, refer to wcshdr.h. * * wcsfix() and wcsfixi() apply all of the corrections handled by the following * specific functions, which may also be invoked separately: * * - cdfix(): Sets the diagonal element of the CDi_ja matrix to 1.0 if all * CDi_ja keywords associated with a particular axis are omitted. * * - datfix(): recast an older DATE-OBS date format in dateobs to year-2000 * standard form. Derive dateref from mjdref if not already set. * Alternatively, if dateref is set and mjdref isn't, then derive mjdref * from it. If both are set, then check consistency. Likewise for dateobs * and mjdobs; datebeg and mjdbeg; dateavg and mjdavg; and dateend and * mjdend. * * - obsfix(): if only one half of obsgeo[] is set, then derive the other * half from it. If both halves are set, then check consistency. * * - unitfix(): translate some commonly used but non-standard unit strings in * the CUNITia keyvalues, e.g. 'DEG' -> 'deg'. * * - spcfix(): translate AIPS-convention spectral types, 'FREQ-LSR', * 'FELO-HEL', etc., in ctype[] as set from CTYPEia. * * - celfix(): translate AIPS-convention celestial projection types, NCP and * GLS, in ctype[] as set from CTYPEia. * * - cylfix(): fixes WCS keyvalues for malformed cylindrical projections that * suffer from the problem described in Sect. 7.3.4 of Paper I. * * * wcsfix() - Translate a non-standard WCS struct * ---------------------------------------------- * wcsfix() is identical to wcsfixi(), but lacks the info argument. * * * wcsfixi() - Translate a non-standard WCS struct * ----------------------------------------------- * wcsfixi() applies all of the corrections handled separately by cdfix(), * datfix(), obsfix(), unitfix(), spcfix(), celfix(), and cylfix(). * * Given: * ctrl int Do potentially unsafe translations of non-standard * unit strings as described in the usage notes to * wcsutrn(). * * naxis const int [] * Image axis lengths. If this array pointer is set to * zero then cylfix() will not be invoked. * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. * * Returned: * stat int [NWCSFIX] * Status returns from each of the functions. Use the * preprocessor macros NWCSFIX to dimension this vector * and CDFIX, DATFIX, OBSFIX, UNITFIX, SPCFIX, CELFIX, * and CYLFIX to access its elements. A status value * of -2 is set for functions that were not invoked. * * info struct wcserr [NWCSFIX] * Status messages from each of the functions. Use the * preprocessor macros NWCSFIX to dimension this vector * and CDFIX, DATFIX, OBSFIX, UNITFIX, SPCFIX, CELFIX, * and CYLFIX to access its elements. * * Note that the memory allocated by wcsfixi() for the * message in each wcserr struct (wcserr::msg, if * non-zero) must be freed by the user. See * wcsdealloc(). * * Function return value: * int Status return value: * 0: Success. * 1: One or more of the translation functions * returned an error. * * * cdfix() - Fix erroneously omitted CDi_ja keywords * ------------------------------------------------- * cdfix() sets the diagonal element of the CDi_ja matrix to unity if all * CDi_ja keywords associated with a given axis were omitted. According to WCS * Paper I, if any CDi_ja keywords at all are given in a FITS header then those * not given default to zero. This results in a singular matrix with an * intersecting row and column of zeros. * * cdfix() is expected to be invoked before wcsset(), which will fail if these * errors have not been corrected. * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. * * Function return value: * int Status return value: * -1: No change required (not an error). * 0: Success. * 1: Null wcsprm pointer passed. * * * datfix() - Translate DATE-OBS and derive MJD-OBS or vice versa * -------------------------------------------------------------- * datfix() translates the old DATE-OBS date format set in wcsprm::dateobs to * year-2000 standard form (yyyy-mm-ddThh:mm:ss). It derives wcsprm::dateref * from wcsprm::mjdref if not already set. Alternatively, if dateref is set * and mjdref isn't, then it derives mjdref from it. If both are set but * disagree by more than 0.001 day (86.4 seconds) then an error status is * returned. Likewise for wcsprm::dateobs and wcsprm::mjdobs; wcsprm::datebeg * and wcsprm::mjdbeg; wcsprm::dateavg and wcsprm::mjdavg; and wcsprm::dateend * and wcsprm::mjdend. * * If neither dateobs nor mjdobs are set, but wcsprm::jepoch (primarily) or * wcsprm::bepoch is, then both are derived from it. If jepoch and/or bepoch * are set but disagree with dateobs or mjdobs by more than 0.000002 year * (63.2 seconds), an informative message is produced. * * The translations done by datfix() do not affect and are not affected by * wcsset(). * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. * wcsprm::dateref and/or wcsprm::mjdref may be changed. * wcsprm::dateobs and/or wcsprm::mjdobs may be changed. * wcsprm::datebeg and/or wcsprm::mjdbeg may be changed. * wcsprm::dateavg and/or wcsprm::mjdavg may be changed. * wcsprm::dateend and/or wcsprm::mjdend may be changed. * * Function return value: * int Status return value: * -1: No change required (not an error). * 0: Success. * 1: Null wcsprm pointer passed. * 5: Invalid parameter value. * * For returns >= 0, a detailed message, whether * informative or an error message, may be set in * wcsprm::err if enabled, see wcserr_enable(), with * wcsprm::err.status set to FIXERR_DATE_FIX. * * Notes: * 1: The MJD algorithms used by datfix() are from D.A. Hatcher, 1984, QJRAS, * 25, 53-55, as modified by P.T. Wallace for use in SLALIB subroutines * CLDJ and DJCL. * * * obsfix() - complete the OBSGEO-[XYZLBH] vector of observatory coordinates * ------------------------------------------------------------------------- * obsfix() completes the wcsprm::obsgeo vector of observatory coordinates. * That is, if only the (x,y,z) Cartesian coordinate triplet or the (l,b,h) * geodetic coordinate triplet are set, then it derives the other triplet from * it. If both triplets are set, then it checks for consistency at the level * of 1 metre. * * The operations done by obsfix() do not affect and are not affected by * wcsset(). * * Given: * ctrl int Flag that controls behaviour if one triplet is * defined and the other is only partially defined: * 0: Reset only the undefined elements of an * incomplete coordinate triplet. * 1: Reset all elements of an incomplete triplet. * 2: Don't make any changes, check for consistency * only. Returns an error if either of the two * triplets is incomplete. * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. * wcsprm::obsgeo may be changed. * * Function return value: * int Status return value: * -1: No change required (not an error). * 0: Success. * 1: Null wcsprm pointer passed. * 5: Invalid parameter value. * * For returns >= 0, a detailed message, whether * informative or an error message, may be set in * wcsprm::err if enabled, see wcserr_enable(), with * wcsprm::err.status set to FIXERR_OBS_FIX. * * Notes: * 1: While the International Terrestrial Reference System (ITRS) is based * solely on Cartesian coordinates, it recommends the use of the GRS80 * ellipsoid in converting to geodetic coordinates. However, while WCS * Paper III recommends ITRS Cartesian coordinates, Paper VII prescribes * the use of the IAU(1976) ellipsoid for geodetic coordinates, and * consequently that is what is used here. * * 2: For reference, parameters of commonly used global reference ellipsoids: * = a (m) 1/f Standard = --------- ------------- -------------------------------- = 6378140 298.2577 IAU(1976) = 6378137 298.257222101 GRS80 = 6378137 298.257223563 WGS84 = 6378136 298.257 IERS(1989) = 6378136.6 298.25642 IERS(2003,2010), IAU(2009/2012) * * where f = (a - b) / a is the flattening, and a and b are the semi-major * and semi-minor radii in metres. * * 3: The transformation from geodetic (lng,lat,hgt) to Cartesian (x,y,z) is * = x = (n + hgt)*coslng*coslat, = y = (n + hgt)*sinlng*coslat, = z = (n*(1.0 - e^2) + hgt)*sinlat, * * where the "prime vertical radius", n, is a function of latitude * = n = a / sqrt(1 - (e*sinlat)^2), * * and a, the equatorial radius, and e^2 = (2 - f)*f, the (first) * eccentricity of the ellipsoid, are constants. obsfix() inverts these * iteratively by writing * = x = rho*coslng*coslat, = y = rho*sinlng*coslat, = zeta = rho*sinlat, * * where * = rho = n + hgt, = = sqrt(x^2 + y^2 + zeta^2), = zeta = z / (1 - n*e^2/rho), * * and iterating over the value of zeta. Since e is small, a good first * approximation is given by zeta = z. * * * unitfix() - Correct aberrant CUNITia keyvalues * ---------------------------------------------- * unitfix() applies wcsutrn() to translate non-standard CUNITia keyvalues, * e.g. 'DEG' -> 'deg', also stripping off unnecessary whitespace. * * unitfix() is expected to be invoked before wcsset(), which will fail if * non-standard CUNITia keyvalues have not been translated. * * Given: * ctrl int Do potentially unsafe translations described in the * usage notes to wcsutrn(). * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. * * Function return value: * int Status return value: * -1: No change required (not an error). * 0: Success (an alias was applied). * 1: Null wcsprm pointer passed. * * When units are translated (i.e. 0 is returned), an * informative message is set in wcsprm::err if enabled, * see wcserr_enable(), with wcsprm::err.status set to * FIXERR_UNITS_ALIAS. * * * spcfix() - Translate AIPS-convention spectral types * --------------------------------------------------- * spcfix() translates AIPS-convention spectral coordinate types, * '{FREQ,FELO,VELO}-{LSR,HEL,OBS}' (e.g. 'FREQ-OBS', 'FELO-HEL', 'VELO-LSR') * set in wcsprm::ctype[], subject to VELREF set in wcsprm::velref. * * Note that if wcs::specsys is already set then it will not be overridden. * * AIPS-convention spectral types set in CTYPEia are translated on-the-fly by * wcsset() but without modifying wcsprm::ctype[] or wcsprm::specsys. That is, * only the information extracted from wcsprm::ctype[] is translated when * wcsset() fills in wcsprm::spc (spcprm struct). spcfix() modifies * wcsprm::ctype[] so that if the header is subsequently written out, e.g. by * wcshdo(), then it will contain translated CTYPEia keyvalues. * * The operations done by spcfix() do not affect and are not affected by * wcsset(). * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. wcsprm::ctype[] * and/or wcsprm::specsys may be changed. * * Function return value: * int Status return value: * -1: No change required (not an error). * 0: Success. * 1: Null wcsprm pointer passed. * 2: Memory allocation failed. * 3: Linear transformation matrix is singular. * 4: Inconsistent or unrecognized coordinate axis * types. * 5: Invalid parameter value. * 6: Invalid coordinate transformation parameters. * 7: Ill-conditioned coordinate transformation * parameters. * * For returns >= 0, a detailed message, whether * informative or an error message, may be set in * wcsprm::err if enabled, see wcserr_enable(), with * wcsprm::err.status set to FIXERR_SPC_UPDTE. * * * celfix() - Translate AIPS-convention celestial projection types * --------------------------------------------------------------- * celfix() translates AIPS-convention celestial projection types, NCP and * GLS, set in the ctype[] member of the wcsprm struct. * * Two additional pv[] keyvalues are created when translating NCP, and three * are created when translating GLS with non-zero reference point. If the pv[] * array was initially allocated by wcsini() then the array will be expanded if * necessary. Otherwise, error 2 will be returned if sufficient empty slots * are not already available for use. * * AIPS-convention celestial projection types set in CTYPEia are translated * on-the-fly by wcsset() but without modifying wcsprm::ctype[], wcsprm::pv[], * or wcsprm::npv. That is, only the information extracted from * wcsprm::ctype[] is translated when wcsset() fills in wcsprm::cel (celprm * struct). celfix() modifies wcsprm::ctype[], wcsprm::pv[], and wcsprm::npv * so that if the header is subsequently written out, e.g. by wcshdo(), then it * will contain translated CTYPEia keyvalues and the relevant PVi_ma. * * The operations done by celfix() do not affect and are not affected by * wcsset(). However, it uses information in the wcsprm struct provided by * wcsset(), and will invoke it if necessary. * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. wcsprm::ctype[] * and/or wcsprm::pv[] may be changed. * * Function return value: * int Status return value: * -1: No change required (not an error). * 0: Success. * 1: Null wcsprm pointer passed. * 2: Memory allocation failed. * 3: Linear transformation matrix is singular. * 4: Inconsistent or unrecognized coordinate axis * types. * 5: Invalid parameter value. * 6: Invalid coordinate transformation parameters. * 7: Ill-conditioned coordinate transformation * parameters. * * For returns > 1, a detailed error message is set in * wcsprm::err if enabled, see wcserr_enable(). * * * cylfix() - Fix malformed cylindrical projections * ------------------------------------------------ * cylfix() fixes WCS keyvalues for malformed cylindrical projections that * suffer from the problem described in Sect. 7.3.4 of Paper I. * * cylfix() requires the wcsprm struct to have been set up by wcsset(), and * will invoke it if necessary. After modification, the struct is reset on * return with an explicit call to wcsset(). * * Given: * naxis const int [] * Image axis lengths. * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. * * Function return value: * int Status return value: * -1: No change required (not an error). * 0: Success. * 1: Null wcsprm pointer passed. * 2: Memory allocation failed. * 3: Linear transformation matrix is singular. * 4: Inconsistent or unrecognized coordinate axis * types. * 5: Invalid parameter value. * 6: Invalid coordinate transformation parameters. * 7: Ill-conditioned coordinate transformation * parameters. * 8: All of the corner pixel coordinates are invalid. * 9: Could not determine reference pixel coordinate. * 10: Could not determine reference pixel value. * * For returns > 1, a detailed error message is set in * wcsprm::err if enabled, see wcserr_enable(). * * * wcspcx() - regularize PCi_j * --------------------------- * wcspcx() "regularizes" the linear transformation matrix component of the * coordinate transformation (PCi_ja) to make it more human-readable. * * Normally, upon encountering a FITS header containing a CDi_ja matrix, * wcsset() simply treats it as PCi_ja and sets CDELTia to unity. However, * wcspcx() decomposes CDi_ja into PCi_ja and CDELTia in such a way that * CDELTia form meaningful scaling parameters. In practice, the residual * PCi_ja matrix will often then be orthogonal, i.e. unity, or describing a * pure rotation, axis permutation, or reflection, or a combination thereof. * * The decomposition is based on normalizing the length in the transformed * system (i.e. intermediate pixel coordinates) of the orthonormal basis * vectors of the pixel coordinate system. This deviates slightly from the * prescription given by Eq. (4) of WCS Paper I, namely Sum(j=1,N)(PCi_ja)² = 1, * in replacing the sum over j with the sum over i. Consequently, the columns * of PCi_ja will consist of unit vectors. In practice, especially in cubes * and higher dimensional images, at least some pairs of these unit vectors, if * not all, will often be orthogonal or close to orthogonal. * * The sign of CDELTia is chosen to make the PCi_ja matrix as close to the, * possibly permuted, unit matrix as possible, except that where the coordinate * description contains a pair of celestial axes, the sign of CDELTia is set * negative for the longitude axis and positive for the latitude axis. * * Optionally, rows of the PCi_ja matrix may also be permuted to diagonalize * it as far as possible, thus undoing any transposition of axes in the * intermediate pixel coordinate system. * * If the coordinate description contains a celestial plane, then the angle of * rotation of each of the basis vectors associated with the celestial axes is * returned. For a pure rotation the two angles should be identical. Any * difference between them is a measure of axis skewness. * * The decomposition is not performed for axes involving a sequent distortion * function that is defined in terms of CDi_ja, such as TPV, TNX, or ZPX, which * always are. The independent variables of the polynomial are therefore * intermediate world coordinates rather than intermediate pixel coordinates. * Because sequent distortions are always applied before CDELTia, if CDi_ja was * translated to PCi_ja plus CDELTia, then the distortion would be altered * unless the polynomial coefficients were also adjusted to account for the * change of scale. * * wcspcx() requires the wcsprm struct to have been set up by wcsset(), and * will invoke it if necessary. The wcsprm struct is reset on return with an * explicit call to wcsset(). * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters. * * Given: * dopc int If 1, then PCi_ja and CDELTia, as given, will be * recomposed according to the above prescription. If 0, * the operation is restricted to decomposing CDi_ja. * * permute int If 1, then after decomposition (or recomposition), * permute rows of PCi_ja to make the axes of the * intermediate pixel coordinate system match as closely * as possible those of the pixel coordinates. That is, * make it as close to a diagonal matrix as possible. * However, celestial axes are special in always being * paired, with the longitude axis preceding the latitude * axis. * * All WCS entities indexed by i, such as CTYPEia, * CRVALia, CDELTia, etc., including coordinate lookup * tables, will also be permuted as necessary to account * for the change to PCi_ja. This does not apply to * CRPIXja, nor prior distortion functions. These * operate on pixel coordinates, which are not affected * by the permutation. * * Returned: * rotn double[2] Rotation angle [deg] of each basis vector associated * with the celestial axes. For a pure rotation the two * angles should be identical. Any difference between * them is a measure of axis skewness. * * May be set to the NULL pointer if this information is * not required. * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * 2: Memory allocation failed. * 5: CDi_j matrix not used. * 6: Sequent distortion function present. * * * Global variable: const char *wcsfix_errmsg[] - Status return messages * --------------------------------------------------------------------- * Error messages to match the status value returned from each function. * *===========================================================================*/ #ifndef WCSLIB_WCSFIX #define WCSLIB_WCSFIX #include "wcs.h" #include "wcserr.h" #ifdef __cplusplus extern "C" { #endif #define CDFIX 0 #define DATFIX 1 #define OBSFIX 2 #define UNITFIX 3 #define SPCFIX 4 #define CELFIX 5 #define CYLFIX 6 #define NWCSFIX 7 extern const char *wcsfix_errmsg[]; #define cylfix_errmsg wcsfix_errmsg enum wcsfix_errmsg_enum { FIXERR_OBSGEO_FIX = -5, // Observatory coordinates amended. FIXERR_DATE_FIX = -4, // Date string reformatted. FIXERR_SPC_UPDATE = -3, // Spectral axis type modified. FIXERR_UNITS_ALIAS = -2, // Units alias translation. FIXERR_NO_CHANGE = -1, // No change. FIXERR_SUCCESS = 0, // Success. FIXERR_NULL_POINTER = 1, // Null wcsprm pointer passed. FIXERR_MEMORY = 2, // Memory allocation failed. FIXERR_SINGULAR_MTX = 3, // Linear transformation matrix is singular. FIXERR_BAD_CTYPE = 4, // Inconsistent or unrecognized coordinate // axis types. FIXERR_BAD_PARAM = 5, // Invalid parameter value. FIXERR_BAD_COORD_TRANS = 6, // Invalid coordinate transformation // parameters. FIXERR_ILL_COORD_TRANS = 7, // Ill-conditioned coordinate transformation // parameters. FIXERR_BAD_CORNER_PIX = 8, // All of the corner pixel coordinates are // invalid. FIXERR_NO_REF_PIX_COORD = 9, // Could not determine reference pixel // coordinate. FIXERR_NO_REF_PIX_VAL = 10 // Could not determine reference pixel value. }; int wcsfix(int ctrl, const int naxis[], struct wcsprm *wcs, int stat[]); int wcsfixi(int ctrl, const int naxis[], struct wcsprm *wcs, int stat[], struct wcserr info[]); int cdfix(struct wcsprm *wcs); int datfix(struct wcsprm *wcs); int obsfix(int ctrl, struct wcsprm *wcs); int unitfix(int ctrl, struct wcsprm *wcs); int spcfix(struct wcsprm *wcs); int celfix(struct wcsprm *wcs); int cylfix(const int naxis[], struct wcsprm *wcs); int wcspcx(struct wcsprm *wcs, int dopc, int permute, double rotn[2]); #ifdef __cplusplus } #endif #endif // WCSLIB_WCSFIX ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/wcshdr.c0000644000175100001710000021102500000000000017021 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcshdr.c,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *===========================================================================*/ #include #include #include #include #include #include "wcserr.h" #include "wcsmath.h" #include "wcsutil.h" #include "wcshdr.h" #include "wtbarr.h" #include "tab.h" #include "dis.h" #include "wcs.h" extern const int WCSSET; extern const int DIS_DOTPD; // Map status return value to message. const char *wcshdr_errmsg[] = { "Success", "Null wcsprm pointer passed", "Memory allocation failed", "Invalid column selection", "Fatal error returned by Flex parser", "Invalid tabular parameters"}; // Map error returns for lower-level routines. const int wcshdr_taberr[] = { WCSHDRERR_SUCCESS, // 0: TABERR_SUCCESS WCSHDRERR_NULL_POINTER, // 1: TABERR_NULL_POINTER WCSHDRERR_MEMORY, // 2: TABERR_MEMORY WCSHDRERR_BAD_TABULAR_PARAMS // 3: TABERR_BAD_PARAMS // 4: TABERR_BAD_X // 5: TABERR_BAD_WORLD }; // Convenience macro for invoking wcserr_set(). #define WCSHDR_ERRMSG(status) WCSERR_SET(status), wcshdr_errmsg[status] // Internal helper functions, not for general use. static void wcshdo_format(int, int, const double [], char *); static void wcshdo_tpdterm(int, int, char *); static void wcshdo_util(int, const char [], const char [], int, const char [], int, int, int, char, int, int [], char [], const char [], int *, char **, int *); //---------------------------------------------------------------------------- int wcstab(struct wcsprm *wcs) { static const char *function = "wcstab"; char (*PSi_0a)[72] = 0x0, (*PSi_1a)[72] = 0x0, (*PSi_2a)[72] = 0x0; int *PVi_1a = 0x0, *PVi_2a = 0x0, *PVi_3a = 0x0, *tabax, *tabidx = 0x0; int getcrd, i, ip, itab, itabax, j, jtabax, m, naxis, ntabax, status; struct wtbarr *wtbp; struct tabprm *tabp; struct wcserr **err; if (wcs == 0x0) return WCSHDRERR_NULL_POINTER; err = &(wcs->err); // Free memory previously allocated by wcstab(). if (wcs->flag != -1 && wcs->m_flag == WCSSET) { if (wcs->wtb == wcs->m_wtb) wcs->wtb = 0x0; if (wcs->tab == wcs->m_tab) wcs->tab = 0x0; if (wcs->m_wtb) free(wcs->m_wtb); if (wcs->m_tab) { for (j = 0; j < wcs->ntab; j++) { tabfree(wcs->m_tab + j); } free(wcs->m_tab); } } wcs->ntab = 0; wcs->nwtb = 0; wcs->wtb = 0x0; wcs->tab = 0x0; // Determine the number of -TAB axes. naxis = wcs->naxis; if (!(tabax = calloc(naxis, sizeof(int)))) { return wcserr_set(WCSHDR_ERRMSG(WCSHDRERR_MEMORY)); } ntabax = 0; for (i = 0; i < naxis; i++) { // Null fill. wcsutil_null_fill(72, wcs->ctype[i]); if (!strcmp(wcs->ctype[i]+4, "-TAB")) { tabax[i] = ntabax++; } else { tabax[i] = -1; } } if (ntabax == 0) { // No lookup tables. status = 0; goto cleanup; } // Collect information from the PSi_ma and PVi_ma keyvalues. if (!((PSi_0a = calloc(ntabax, sizeof(char[72]))) && (PVi_1a = calloc(ntabax, sizeof(int))) && (PVi_2a = calloc(ntabax, sizeof(int))) && (PSi_1a = calloc(ntabax, sizeof(char[72]))) && (PSi_2a = calloc(ntabax, sizeof(char[72]))) && (PVi_3a = calloc(ntabax, sizeof(int))) && (tabidx = calloc(ntabax, sizeof(int))))) { status = wcserr_set(WCSHDR_ERRMSG(WCSHDRERR_MEMORY)); goto cleanup; } for (itabax = 0; itabax < ntabax; itabax++) { // Remember that calloc() zeroes allocated memory. PVi_1a[itabax] = 1; PVi_2a[itabax] = 1; PVi_3a[itabax] = 1; } for (ip = 0; ip < wcs->nps; ip++) { itabax = tabax[wcs->ps[ip].i - 1]; if (itabax >= 0) { switch (wcs->ps[ip].m) { case 0: // EXTNAME. strcpy(PSi_0a[itabax], wcs->ps[ip].value); wcsutil_null_fill(72, PSi_0a[itabax]); break; case 1: // TTYPEn for coordinate array. strcpy(PSi_1a[itabax], wcs->ps[ip].value); wcsutil_null_fill(72, PSi_1a[itabax]); break; case 2: // TTYPEn for index vector. strcpy(PSi_2a[itabax], wcs->ps[ip].value); wcsutil_null_fill(72, PSi_2a[itabax]); break; } } } for (ip = 0; ip < wcs->npv; ip++) { itabax = tabax[wcs->pv[ip].i - 1]; if (itabax >= 0) { switch (wcs->pv[ip].m) { case 1: // EXTVER. PVi_1a[itabax] = (int)(wcs->pv[ip].value + 0.5); break; case 2: // EXTLEVEL. PVi_2a[itabax] = (int)(wcs->pv[ip].value + 0.5); break; case 3: // Table axis number. PVi_3a[itabax] = (int)(wcs->pv[ip].value + 0.5); break; } } } // Determine the number of independent tables. for (itabax = 0; itabax < ntabax; itabax++) { // These have no defaults. if (!PSi_0a[itabax][0] || !PSi_1a[itabax][0]) { status = wcserr_set(WCSERR_SET(WCSHDRERR_BAD_TABULAR_PARAMS), "Invalid tabular parameters: PSi_0a and PSi_1a must be specified"); goto cleanup; } tabidx[itabax] = -1; for (jtabax = 0; jtabax < i; jtabax++) { // EXTNAME, EXTVER, EXTLEVEL, and TTYPEn for the coordinate array // must match for each axis of a multi-dimensional lookup table. if (strcmp(PSi_0a[itabax], PSi_0a[jtabax]) == 0 && strcmp(PSi_1a[itabax], PSi_1a[jtabax]) == 0 && PVi_1a[itabax] == PVi_1a[jtabax] && PVi_2a[itabax] == PVi_2a[jtabax]) { tabidx[itabax] = tabidx[jtabax]; break; } } if (jtabax == itabax) { tabidx[itabax] = wcs->ntab; wcs->ntab++; } } if (!(wcs->tab = calloc(wcs->ntab, sizeof(struct tabprm)))) { status = wcserr_set(WCSHDR_ERRMSG(WCSHDRERR_MEMORY)); goto cleanup; } wcs->m_tab = wcs->tab; // Table dimensionality; find the largest axis number. for (itabax = 0; itabax < ntabax; itabax++) { tabp = wcs->tab + tabidx[itabax]; // PVi_3a records the 1-relative table axis number. if (PVi_3a[itabax] > tabp->M) { tabp->M = PVi_3a[itabax]; } } for (itab = 0; itab < wcs->ntab; itab++) { if ((status = tabini(1, wcs->tab[itab].M, 0, wcs->tab + itab))) { status = wcserr_set(WCSHDR_ERRMSG(wcshdr_taberr[status])); goto cleanup; } } // Copy parameters into the tabprm structs. for (i = 0; i < naxis; i++) { if ((itabax = tabax[i]) < 0) { // Not a -TAB axis. continue; } // PVi_3a records the 1-relative table axis number. m = PVi_3a[itabax] - 1; tabp = wcs->tab + tabidx[itabax]; tabp->map[m] = i; tabp->crval[m] = wcs->crval[i]; } // Check for completeness. for (itab = 0; itab < wcs->ntab; itab++) { for (m = 0; m < wcs->tab[itab].M; m++) { if (wcs->tab[itab].map[m] < 0) { status = wcserr_set(WCSERR_SET(WCSHDRERR_BAD_TABULAR_PARAMS), "Invalid tabular parameters: the axis mapping is undefined"); goto cleanup; } } } // Set up for reading the arrays; how many arrays are there? for (itabax = 0; itabax < ntabax; itabax++) { // Does this -TAB axis have a non-degenerate index array? if (PSi_2a[itabax][0]) { wcs->nwtb++; } } // Add one coordinate array for each table. wcs->nwtb += wcs->ntab; // Allocate memory for structs to be returned. if (!(wcs->wtb = calloc(wcs->nwtb, sizeof(struct wtbarr)))) { wcs->nwtb = 0; status = wcserr_set(WCSHDR_ERRMSG(WCSHDRERR_MEMORY)); goto cleanup; } wcs->m_wtb = wcs->wtb; // Set pointers for the index and coordinate arrays. wtbp = wcs->wtb; for (itab = 0; itab < wcs->ntab; itab++) { getcrd = 1; for (itabax = 0; itabax < ntabax; itabax++) { if (tabidx[itabax] != itab) continue; if (getcrd) { // Coordinate array. wtbp->i = itabax + 1; wtbp->m = PVi_3a[itabax]; wtbp->kind = 'c'; strcpy(wtbp->extnam, PSi_0a[itabax]); wtbp->extver = PVi_1a[itabax]; wtbp->extlev = PVi_2a[itabax]; strcpy(wtbp->ttype, PSi_1a[itabax]); wtbp->row = 1L; wtbp->ndim = wcs->tab[itab].M + 1; wtbp->dimlen = wcs->tab[itab].K; wtbp->arrayp = &(wcs->tab[itab].coord); // Signal for tabset() to take this memory. wcs->tab[itab].m_coord = (double *)0x1; wtbp++; getcrd = 0; } if (PSi_2a[itabax][0]) { // Index array. wtbp->i = itabax + 1; wtbp->m = PVi_3a[itabax]; wtbp->kind = 'i'; m = wtbp->m - 1; strcpy(wtbp->extnam, PSi_0a[itabax]); wtbp->extver = PVi_1a[itabax]; wtbp->extlev = PVi_2a[itabax]; strcpy(wtbp->ttype, PSi_2a[itabax]); wtbp->row = 1L; wtbp->ndim = 1; wtbp->dimlen = wcs->tab[itab].K + m; wtbp->arrayp = wcs->tab[itab].index + m; // Signal for tabset() to take this memory. wcs->tab[itab].m_indxs[m] = (double *)0x1; wtbp++; } } } status = 0; cleanup: if (tabax) free(tabax); if (tabidx) free(tabidx); if (PSi_0a) free(PSi_0a); if (PVi_1a) free(PVi_1a); if (PVi_2a) free(PVi_2a); if (PSi_1a) free(PSi_1a); if (PSi_2a) free(PSi_2a); if (PVi_3a) free(PVi_3a); if (status) { if (wcs->tab) free(wcs->tab); if (wcs->wtb) free(wcs->wtb); } return status; } //---------------------------------------------------------------------------- int wcsidx(int nwcs, struct wcsprm **wcs, int alts[27]) { int a, iwcs; struct wcsprm *wcsp; for (a = 0; a < 27; a++) { alts[a] = -1; } if (wcs == 0x0) { return WCSHDRERR_NULL_POINTER; } wcsp = *wcs; for (iwcs = 0; iwcs < nwcs; iwcs++, wcsp++) { if (wcsp->colnum || wcsp->colax[0]) continue; if (wcsp->alt[0] == ' ') { a = 0; } else { a = wcsp->alt[0] - 'A' + 1; } alts[a] = iwcs; } return 0; } //---------------------------------------------------------------------------- int wcsbdx(int nwcs, struct wcsprm **wcs, int type, short alts[1000][28]) { short *ip; int a, i, icol, iwcs; struct wcsprm *wcsp; for (ip = alts[0]; ip < alts[0] + 28*1000; ip++) { *ip = -1; } for (icol = 0; icol < 1000; icol++) { alts[icol][27] = 0; } if (wcs == 0x0) { return WCSHDRERR_NULL_POINTER; } wcsp = *wcs; for (iwcs = 0; iwcs < nwcs; iwcs++, wcsp++) { if (wcsp->alt[0] == ' ') { a = 0; } else { a = wcsp->alt[0] - 'A' + 1; } if (type) { // Pixel list. if (wcsp->colax[0]) { for (i = 0; i < wcsp->naxis; i++) { alts[wcsp->colax[i]][a] = iwcs; alts[wcsp->colax[i]][27]++; } } else if (!wcsp->colnum) { alts[0][a] = iwcs; alts[0][27]++; } } else { // Binary table image array. if (wcsp->colnum) { alts[wcsp->colnum][a] = iwcs; alts[wcsp->colnum][27]++; } else if (!wcsp->colax[0]) { alts[0][a] = iwcs; alts[0][27]++; } } } return 0; } //---------------------------------------------------------------------------- int wcsvfree(int *nwcs, struct wcsprm **wcs) { int a, status = 0; struct wcsprm *wcsp; if (wcs == 0x0) { return WCSHDRERR_NULL_POINTER; } wcsp = *wcs; for (a = 0; a < *nwcs; a++, wcsp++) { status |= wcsfree(wcsp); } free(*wcs); *nwcs = 0; *wcs = 0x0; return status; } //---------------------------------------------------------------------------- // Matching the definitions in dis.c. #define I_DTYPE 0 // Distortion type code. #define I_NIPARM 1 // Full (allocated) length of iparm[]. #define I_NDPARM 2 // No. of parameters in dparm[], excl. work space. #define I_TPDNCO 3 // No. of TPD coefficients, forward... #define I_TPDINV 4 // ...and inverse. #define I_TPDAUX 5 // True if auxiliary variables are used. #define I_TPDRAD 6 // True if the radial variable is used. int wcshdo(int ctrl, struct wcsprm *wcs, int *nkeyrec, char **header) // ::: CUBEFACE and STOKES handling? { static const char *function = "wcshdo"; const char axid[] = "xyxuvu", *cp; const int nTPD[] = {1, 4, 7, 12, 17, 24, 31, 40, 49, 60}; char alt, comment[72], ctemp[32], *ctypei, format[16], fmt01[8], keyvalue[96], keyword[16], *kp, obsg[8] = "OBSG?", obsgeo[8] = "OBSGEO-?", pq, ptype, xtype, term[16], timeunit[16], tpdsrc[24], xyz[] = "XYZ"; int *axmap, bintab, *colax, colnum, degree, direct = 0, doaux = 0, dofmt, dosip, dotpd, dotpv, i, idis, idp, *iparm, j, jhat, k, kp0, kpi, m, naxis, ncoeff, Nhat, p, pixlist, precision, primage, q, status = 0; double *dparm, keyval; struct auxprm *aux; struct disprm *dis; struct dpkey *keyp; struct wcserr **err; *nkeyrec = 0; *header = 0x0; if (wcs == 0x0) return WCSHDRERR_NULL_POINTER; err = &(wcs->err); if (wcs->flag != WCSSET) { if ((status = wcsset(wcs))) return status; } if ((naxis = wcs->naxis) == 0) { return 0; } // These are mainly for convenience. alt = wcs->alt[0]; if (alt == ' ') alt = '\0'; colnum = wcs->colnum; colax = wcs->colax; primage = 0; bintab = 0; pixlist = 0; if (colnum) { bintab = 1; } else if (colax[0]) { pixlist = 1; } else { primage = 1; } // Initialize floating point format control. *format = '\0'; if (ctrl & WCSHDO_P17) { strcpy(format, "% 20.17G"); } else if (ctrl & WCSHDO_P16) { strcpy(format, "% 20.16G"); } else if (ctrl & WCSHDO_P15) { strcpy(format, "% 20.15G"); } else if (ctrl & WCSHDO_P14) { strcpy(format, "% 20.14G"); } else if (ctrl & WCSHDO_P13) { strcpy(format, "% 20.13G"); } else if (ctrl & WCSHDO_P12) { strcpy(format, "%20.12G"); } if (*format && (ctrl & WCSHDO_EFMT)) { if (format[6] == 'G') { format[6] = 'E'; } else { format[7] = 'E'; } } dofmt = (*format == '\0'); // WCS dimension. if (!pixlist) { sprintf(keyvalue, "%20d", naxis); wcshdo_util(ctrl, "WCSAXES", "WCAX", 0, 0x0, 0, 0, 0, alt, colnum, colax, keyvalue, "Number of coordinate axes", nkeyrec, header, &status); } // Reference pixel coordinates. if (dofmt) wcshdo_format('G', naxis, wcs->crpix, format); for (j = 0; j < naxis; j++) { wcsutil_double2str(keyvalue, format, wcs->crpix[j]); wcshdo_util(ctrl, "CRPIX", "CRP", WCSHDO_CRPXna, "CRPX", 0, j+1, 0, alt, colnum, colax, keyvalue, "Pixel coordinate of reference point", nkeyrec, header, &status); } // Linear transformation matrix. if (dofmt) wcshdo_format('G', naxis*naxis, wcs->pc, format); k = 0; for (i = 0; i < naxis; i++) { for (j = 0; j < naxis; j++, k++) { if (i == j) { if (wcs->pc[k] == 1.0) continue; } else { if (wcs->pc[k] == 0.0) continue; } wcsutil_double2str(keyvalue, format, wcs->pc[k]); wcshdo_util(ctrl, "PC", bintab ? "PC" : "P", WCSHDO_TPCn_ka, bintab ? 0x0 : "PC", i+1, j+1, 0, alt, colnum, colax, keyvalue, "Coordinate transformation matrix element", nkeyrec, header, &status); } } // Coordinate increment at reference point. if (dofmt) wcshdo_format('G', naxis, wcs->cdelt, format); for (i = 0; i < naxis; i++) { wcsutil_double2str(keyvalue, format, wcs->cdelt[i]); comment[0] = '\0'; if (wcs->cunit[i][0]) sprintf(comment, "[%s] ", wcs->cunit[i]); strcat(comment, "Coordinate increment at reference point"); wcshdo_util(ctrl, "CDELT", "CDE", WCSHDO_CRPXna, "CDLT", i+1, 0, 0, alt, colnum, colax, keyvalue, comment, nkeyrec, header, &status); } // Units of coordinate increment and reference value. for (i = 0; i < naxis; i++) { if (wcs->cunit[i][0] == '\0') continue; sprintf(keyvalue, "'%s'", wcs->cunit[i]); wcshdo_util(ctrl, "CUNIT", "CUN", WCSHDO_CRPXna, "CUNI", i+1, 0, 0, alt, colnum, colax, keyvalue, "Units of coordinate increment and value", nkeyrec, header, &status); } // May need to alter ctype for particular distortions so do basic checks // now. Note that SIP, TPV, DSS, TNX, and ZPX are restricted to exactly // two axes and cannot coexist with other distortion types. dosip = 0; dotpv = 0; dotpd = 0; if ((dis = wcs->lin.dispre)) { for (i = 0; i < naxis; i++) { if (strcmp(dis->dtype[i], "SIP") == 0) { // Simple Imaging Polynomial (SIP). Write it in its native form // if possible, unless specifically requested to write it as TPD. dotpd = (dis->iparm[i][I_DTYPE] & DIS_DOTPD); if (!dotpd) {; if (alt || dis->Nhat[0] != 2 || dis->Nhat[1] != 2 || dis->axmap[0][0] != 0 || dis->axmap[0][1] != 1 || dis->axmap[1][0] != 0 || dis->axmap[1][1] != 1 || dis->offset[0][0] != wcs->crpix[0] || dis->offset[0][1] != wcs->crpix[1] || dis->offset[1][0] != wcs->crpix[0] || dis->offset[1][1] != wcs->crpix[1] || dis->scale[0][0] != 1.0 || dis->scale[0][1] != 1.0 || dis->scale[1][0] != 1.0 || dis->scale[1][1] != 1.0) { // Must have been read as a 'SIP' distortion, CPDISja = 'SIP'. // Cannot be written as native SIP so write it as TPD. dotpd = DIS_DOTPD; } else if (strncmp(wcs->ctype[0], "RA---TAN", 8) || strncmp(wcs->ctype[1], "DEC--TAN", 8)) { // Must have been permuted by wcssub(). // Native SIP doesn't have axis mapping so write it as TPD. dotpd = DIS_DOTPD; } if (dotpd) { strcpy(tpdsrc, "SIP coordinates"); } else { dosip = 1; } } break; } } } if ((dis = wcs->lin.disseq)) { for (i = 0; i < naxis; i++) { if (strcmp(dis->dtype[i], "TPV") == 0) { // TPV "projection". Write it in its native form if possible, // unless specifically requested to write it as TPD. dotpd = (dis->iparm[i][I_DTYPE] & DIS_DOTPD); if (!dotpd) {; if (dis->axmap[wcs->lng][0] != wcs->lng || dis->axmap[wcs->lng][1] != wcs->lat || dis->axmap[wcs->lat][0] != wcs->lat || dis->axmap[wcs->lat][1] != wcs->lng || dis->offset[wcs->lng][wcs->lng] != 0.0 || dis->offset[wcs->lng][wcs->lat] != 0.0 || dis->offset[wcs->lat][wcs->lng] != 0.0 || dis->offset[wcs->lat][wcs->lat] != 0.0 || dis->scale[wcs->lng][wcs->lng] != 1.0 || dis->scale[wcs->lng][wcs->lat] != 1.0 || dis->scale[wcs->lat][wcs->lng] != 1.0 || dis->scale[wcs->lat][wcs->lat] != 1.0) { // Must have been read as a 'TPV' distortion, CPDISja = 'TPV'. // Cannot be written as native TPV so write it as TPD. dotpd = DIS_DOTPD; } if (dotpd) { strcpy(tpdsrc, "TPV \"projection\""); } else { dotpv = 1; } } break; } else if (strcmp(dis->dtype[i], "DSS") == 0) { // Always written as TPD. dotpd = DIS_DOTPD; strcpy(tpdsrc, dis->dtype[i]); } else if (strncmp(dis->dtype[i], "WAT", 3) == 0) { // Always written as TPD. dotpd = DIS_DOTPD; strcpy(tpdsrc, dis->dtype[i]+4); if (strcmp(dis->dtype[i], "DSS") == 0) { strcpy(tpdsrc, wcs->wcsname); } else { strcat(tpdsrc, " \"projection\""); } break; } } } // Coordinate type. for (i = 0; i < naxis; i++) { if (wcs->ctype[i][0] == '\0') continue; sprintf(keyvalue, "'%s'", wcs->ctype[i]); strcpy(comment, "Coordinate type code"); ctypei = keyvalue + 1; if (i == wcs->lng || i == wcs->lat) { // Alter ctype for particular distortions. if (dosip) { // It could have come in as CPDISja = 'SIP'. strcpy(ctypei+8, "-SIP'"); } else if (dotpv) { // Reinstate projection code edited by wcsset(). strcpy(ctypei+4, "-TPV'"); } if (strncmp(ctypei+8, "-SIP", 4) == 0) { strcpy(comment, "TAN (gnomonic) projection + SIP distortions"); } else if (strncmp(ctypei+4, "-TPV", 4) == 0) { strcpy(comment, "TAN (gnomonic) projection + distortions"); } else { if (strncmp(ctypei, "RA--", 4) == 0) { strcpy(comment, "Right ascension, "); } else if (strncmp(ctypei, "DEC-", 4) == 0) { strcpy(comment, "Declination, "); } else if (strncmp(ctypei+1, "LON", 3) == 0 || strncmp(ctypei+1, "LAT", 3) == 0) { ctypei[0] = toupper(ctypei[0]); switch (ctypei[0]) { case 'G': strcpy(comment, "galactic "); break; case 'E': strcpy(comment, "ecliptic "); break; case 'H': strcpy(comment, "helioecliptic "); break; case 'S': strcpy(comment, "supergalactic "); break; } if (i == wcs->lng) { strcat(comment, "longitude, "); } else { strcat(comment, "latitude, "); } } strcat(comment, wcs->cel.prj.name); strcat(comment, " projection"); } } else if (i == wcs->spec) { spctyp(wcs->ctype[i], 0x0, 0x0, comment, 0x0, &ptype, &xtype, 0x0); if (ptype == xtype) { strcat(comment, " (linear)"); } else { switch (xtype) { case 'F': strcat(comment, " (linear in frequency)"); break; case 'V': strcat(comment, " (linear in velocity)"); break; case 'W': strcat(comment, " (linear in wavelength)"); break; } } } wcshdo_util(ctrl, "CTYPE", "CTY", WCSHDO_CRPXna, "CTYP", i+1, 0, 0, alt, colnum, colax, keyvalue, comment, nkeyrec, header, &status); } // Coordinate value at reference point. for (i = 0; i < naxis; i++) { if (dofmt) wcshdo_format('G', 1, wcs->crval+i, format); wcsutil_double2str(keyvalue, format, wcs->crval[i]); comment[0] = '\0'; if (wcs->cunit[i][0]) sprintf(comment, "[%s] ", wcs->cunit[i]); strcat(comment, "Coordinate value at reference point"); wcshdo_util(ctrl, "CRVAL", "CRV", WCSHDO_CRPXna, "CRVL", i+1, 0, 0, alt, colnum, colax, keyvalue, comment, nkeyrec, header, &status); } // Parameter values. if (dofmt) strcpy(format, "%20.12G"); for (k = 0; k < wcs->npv; k++) { wcsutil_double2str(keyvalue, format, (wcs->pv[k]).value); if ((wcs->pv[k]).i == (wcs->lng + 1)) { switch ((wcs->pv[k]).m) { case 1: strcpy(comment, "[deg] Native longitude of the reference point"); break; case 2: strcpy(comment, "[deg] Native latitude of the reference point"); break; case 3: if (primage) { sprintf(keyword, "LONPOLE%c", alt); } else if (bintab) { sprintf(keyword, "LONP%d%c", colnum, alt); } else { sprintf(keyword, "LONP%d%c", colax[(wcs->pv[k]).i - 1], alt); } sprintf(comment, "[deg] alias for %s (has precedence)", keyword); break; case 4: if (primage) { sprintf(keyword, "LATPOLE%c", alt); } else if (bintab) { sprintf(keyword, "LATP%d%c", colnum, alt); } else { sprintf(keyword, "LATP%d%c", colax[(wcs->pv[k]).i - 1], alt); } sprintf(comment, "[deg] alias for %s (has precedence)", keyword); break; } } else if ((wcs->pv[k]).i == (wcs->lat + 1)) { sprintf(comment, "%s projection parameter", wcs->cel.prj.code); } else { strcpy(comment, "Coordinate transformation parameter"); } wcshdo_util(ctrl, "PV", "V", WCSHDO_PVn_ma, "PV", wcs->pv[k].i, -1, wcs->pv[k].m, alt, colnum, colax, keyvalue, comment, nkeyrec, header, &status); } for (k = 0; k < wcs->nps; k++) { sprintf(keyvalue, "'%s'", (wcs->ps[k]).value); wcshdo_util(ctrl, "PS", "S", WCSHDO_PVn_ma, "PS", wcs->ps[k].i, -1, wcs->ps[k].m, alt, colnum, colax, keyvalue, "Coordinate transformation parameter", nkeyrec, header, &status); } // Celestial and spectral transformation parameters. if (!undefined(wcs->lonpole)) { wcsutil_double2str(keyvalue, format, wcs->lonpole); wcshdo_util(ctrl, "LONPOLE", "LONP", 0, 0x0, 0, 0, 0, alt, colnum, colax, keyvalue, "[deg] Native longitude of celestial pole", nkeyrec, header, &status); } if (!undefined(wcs->latpole)) { wcsutil_double2str(keyvalue, format, wcs->latpole); wcshdo_util(ctrl, "LATPOLE", "LATP", 0, 0x0, 0, 0, 0, alt, colnum, colax, keyvalue, "[deg] Native latitude of celestial pole", nkeyrec, header, &status); } if (wcs->restfrq != 0.0) { wcsutil_double2str(keyvalue, format, wcs->restfrq); wcshdo_util(ctrl, "RESTFRQ", "RFRQ", 0, 0x0, 0, 0, 0, alt, colnum, colax, keyvalue, "[Hz] Line rest frequency", nkeyrec, header, &status); } if (wcs->restwav != 0.0) { wcsutil_double2str(keyvalue, format, wcs->restwav); wcshdo_util(ctrl, "RESTWAV", "RWAV", 0, 0x0, 0, 0, 0, alt, colnum, colax, keyvalue, "[Hz] Line rest wavelength", nkeyrec, header, &status); } // - - - - - - - - - - - - - - - - - Auxiliary coordinate axis information. sprintf(timeunit, "%.15s", wcs->timeunit[0] ? wcs->timeunit : "s"); // Coordinate axis title. if (wcs->cname) { for (i = 0; i < naxis; i++) { if (wcs->cname[i][0] == '\0') continue; sprintf(keyvalue, "'%s'", wcs->cname[i]); wcshdo_util(ctrl, "CNAME", "CNA", WCSHDO_CNAMna, "CNAM", i+1, 0, 0, alt, colnum, colax, keyvalue, "Axis name for labelling purposes", nkeyrec, header, &status); } } // Random error in coordinate. if (wcs->crder) { for (i = 0; i < naxis; i++) { if (undefined(wcs->crder[i])) continue; wcsutil_double2str(keyvalue, format, wcs->crder[i]); comment[0] = '\0'; if (wcs->cunit[i][0]) sprintf(comment, "[%s] ", wcs->cunit[i]); strcat(comment, "Random error in coordinate"); wcshdo_util(ctrl, "CRDER", "CRD", WCSHDO_CNAMna, "CRDE", i+1, 0, 0, alt, colnum, colax, keyvalue, comment, nkeyrec, header, &status); } } // Systematic error in coordinate. if (wcs->csyer) { for (i = 0; i < naxis; i++) { if (undefined(wcs->csyer[i])) continue; wcsutil_double2str(keyvalue, format, wcs->csyer[i]); comment[0] = '\0'; if (wcs->cunit[i][0]) sprintf(comment, "[%s] ", wcs->cunit[i]); strcat(comment, "Systematic error in coordinate"); wcshdo_util(ctrl, "CSYER", "CSY", WCSHDO_CNAMna, "CSYE", i+1, 0, 0, alt, colnum, colax, keyvalue, comment, nkeyrec, header, &status); } } // Time at zero point of phase axis. if (wcs->czphs) { for (i = 0; i < naxis; i++) { if (undefined(wcs->czphs[i])) continue; wcsutil_double2str(keyvalue, format, wcs->czphs[i]); sprintf(comment, "[%s] Time at zero point of phase axis", timeunit); wcshdo_util(ctrl, "CZPHS", "CZP", WCSHDO_CNAMna, "CZPH", i+1, 0, 0, alt, colnum, colax, keyvalue, comment, nkeyrec, header, &status); } } // Period of phase axis. if (wcs->cperi) { for (i = 0; i < naxis; i++) { if (undefined(wcs->cperi[i])) continue; wcsutil_double2str(keyvalue, format, wcs->cperi[i]); sprintf(comment, "[%s] Period of phase axis", timeunit); wcshdo_util(ctrl, "CPERI", "CPR", WCSHDO_CNAMna, "CPER", i+1, 0, 0, alt, colnum, colax, keyvalue, comment, nkeyrec, header, &status); } } // - - - - - - - - - - - - - - - - - - - - - - - - Coordinate system title. // Coordinate system title. if (wcs->wcsname[0]) { sprintf(keyvalue, "'%s'", wcs->wcsname); if (bintab) { wcshdo_util(ctrl, "WCSNAME", "WCSN", 0, 0x0, 0, 0, 0, alt, colnum, colax, keyvalue, "Coordinate system title", nkeyrec, header, &status); } else { // TWCS was a mistake. wcshdo_util(ctrl, "WCSNAME", "TWCS", WCSHDO_WCSNna, "WCSN", 0, 0, 0, alt, colnum, colax, keyvalue, "Coordinate system title", nkeyrec, header, &status); } } // - - - - - - - - - - - - - - - - - Time reference system and measurement. // Time scale. if (wcs->timesys[0]) { sprintf(keyvalue, "'%s'", wcs->timesys); wcshdo_util(ctrl, "TIMESYS", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "Time scale", nkeyrec, header, &status); } // Time reference position. if (wcs->trefpos[0]) { sprintf(keyvalue, "'%s'", wcs->trefpos); wcshdo_util(ctrl, "TREFPOS", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "Time reference position", nkeyrec, header, &status); } // Time reference direction. if (wcs->trefdir[0]) { sprintf(keyvalue, "'%s'", wcs->trefdir); wcshdo_util(ctrl, "TREFDIR", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "Time reference direction", nkeyrec, header, &status); } // Ephemerides used for pathlength delay calculation. if (wcs->plephem[0]) { sprintf(keyvalue, "'%s'", wcs->plephem); wcshdo_util(ctrl, "PLEPHEM", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "Ephemerides used for pathlength delays", nkeyrec, header, &status); } // Time units. if (wcs->timeunit[0]) { sprintf(keyvalue, "'%s'", wcs->timeunit); wcshdo_util(ctrl, "TIMEUNIT", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "Time units", nkeyrec, header, &status); } // Fiducial (reference) time. if (wcs->mjdref[0] == 0.0 && wcs->mjdref[1] == 0.0) { // MJD of fiducial time (simplified if it takes its default value). wcsutil_double2str(keyvalue, format, 0.0); wcshdo_util(ctrl, "MJDREF", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "[d] MJD of fiducial time", nkeyrec, header, &status); } else { // ISO-8601 fiducial time. if (wcs->dateref[0]) { sprintf(keyvalue, "'%s'", wcs->dateref); wcshdo_util(ctrl, "DATEREF", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "ISO-8601 fiducial time", nkeyrec, header, &status); } if (wcs->mjdref[1] == 0.0) { // MJD of fiducial time (no fractional part). if (!undefined(wcs->mjdref[0])) { wcsutil_double2str(keyvalue, format, wcs->mjdref[0]); wcshdo_util(ctrl, "MJDREF", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "[d] MJD of fiducial time", nkeyrec, header, &status); } } else { // MJD of fiducial time, integer part. if (!undefined(wcs->mjdref[0])) { wcsutil_double2str(keyvalue, format, wcs->mjdref[0]); wcshdo_util(ctrl, "MJDREFI", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "[d] MJD of fiducial time, integer part", nkeyrec, header, &status); } // MJD of fiducial time, fractional part. if (!undefined(wcs->mjdref[1])) { wcsutil_double2str(keyvalue, format, wcs->mjdref[1]); wcshdo_util(ctrl, "MJDREFF", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "[d] MJD of fiducial time, fractional part", nkeyrec, header, &status); } } } // Clock correction. if (!undefined(wcs->timeoffs)) { wcsutil_double2str(keyvalue, format, wcs->timeoffs); sprintf(comment, "[%s] Clock correction", timeunit); wcshdo_util(ctrl, "TIMEOFFS", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, comment, nkeyrec, header, &status); } // - - - - - - - - - - - - - - - - - - - - - Data timestamps and durations. // ISO-8601 time of observation. if (wcs->dateobs[0]) { sprintf(keyvalue, "'%s'", wcs->dateobs); strcpy(comment, "ISO-8601 time of observation"); if (ctrl & 1) { // Allow DOBSn. wcshdo_util(ctrl, "DATE-OBS", "DOBS", WCSHDO_DOBSn, 0x0, 0, 0, 0, ' ', colnum, colax, keyvalue, comment, nkeyrec, header, &status); } else { // Force DATE-OBS. wcshdo_util(ctrl, "DATE-OBS", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, comment, nkeyrec, header, &status); } } // MJD of observation. if (!undefined(wcs->mjdobs)) { wcsutil_double2str(keyvalue, format, wcs->mjdobs); wcshdo_util(ctrl, "MJD-OBS", "MJDOB", 0, 0x0, 0, 0, 0, ' ', colnum, colax, keyvalue, "[d] MJD of observation", nkeyrec, header, &status); } // Julian epoch of observation. if (!undefined(wcs->jepoch)) { wcsutil_double2str(keyvalue, format, wcs->jepoch); wcshdo_util(ctrl, "JEPOCH", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "[a] Julian epoch of observation", nkeyrec, header, &status); } // Besselian epoch of observation. if (!undefined(wcs->bepoch)) { wcsutil_double2str(keyvalue, format, wcs->bepoch); wcshdo_util(ctrl, "BEPOCH", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "[a] Besselian epoch of observation", nkeyrec, header, &status); } // ISO-8601 time at start of observation. if (wcs->datebeg[0]) { sprintf(keyvalue, "'%s'", wcs->datebeg); wcshdo_util(ctrl, "DATE-BEG", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "ISO-8601 time at start of observation", nkeyrec, header, &status); } // MJD at start of observation. if (!undefined(wcs->mjdbeg)) { wcsutil_double2str(keyvalue, format, wcs->mjdbeg); wcshdo_util(ctrl, "MJD-BEG", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "[d] MJD at start of observation", nkeyrec, header, &status); } // Time elapsed at start since fiducial time. if (!undefined(wcs->tstart)) { wcsutil_double2str(keyvalue, format, wcs->tstart); sprintf(comment, "[%s] Time elapsed since fiducial time at start", timeunit); wcshdo_util(ctrl, "TSTART", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, comment, nkeyrec, header, &status); } // ISO-8601 time at midpoint of observation. if (wcs->dateavg[0]) { sprintf(keyvalue, "'%s'", wcs->dateavg); wcshdo_util(ctrl, "DATE-AVG", "DAVG", 0, 0x0, 0, 0, 0, ' ', colnum, colax, keyvalue, "ISO-8601 time at midpoint of observation", nkeyrec, header, &status); } // MJD at midpoint of observation. if (!undefined(wcs->mjdavg)) { wcsutil_double2str(keyvalue, format, wcs->mjdavg); wcshdo_util(ctrl, "MJD-AVG", "MJDA", 0, 0x0, 0, 0, 0, ' ', colnum, colax, keyvalue, "[d] MJD at midpoint of observation", nkeyrec, header, &status); } // ISO-8601 time at end of observation. if (wcs->dateend[0]) { sprintf(keyvalue, "'%s'", wcs->dateend); wcshdo_util(ctrl, "DATE-END", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "ISO-8601 time at end of observation", nkeyrec, header, &status); } // MJD at end of observation. if (!undefined(wcs->mjdend)) { wcsutil_double2str(keyvalue, format, wcs->mjdend); wcshdo_util(ctrl, "MJD-END", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "[d] MJD at end of observation", nkeyrec, header, &status); } // Time elapsed at end since fiducial time. if (!undefined(wcs->tstop)) { wcsutil_double2str(keyvalue, format, wcs->tstop); sprintf(comment, "[%s] Time elapsed since fiducial time at end", timeunit); wcshdo_util(ctrl, "TSTOP", "", 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, comment, nkeyrec, header, &status); } // Exposure (integration) time. if (!undefined(wcs->xposure)) { wcsutil_double2str(keyvalue, format, wcs->xposure); sprintf(comment, "[%s] Exposure (integration) time", timeunit); wcshdo_util(ctrl, "XPOSURE", "", 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, comment, nkeyrec, header, &status); } // Elapsed time (start to stop). if (!undefined(wcs->telapse)) { wcsutil_double2str(keyvalue, format, wcs->telapse); sprintf(comment, "[%s] Elapsed time (start to stop)", timeunit); wcshdo_util(ctrl, "TELAPSE", "", 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, comment, nkeyrec, header, &status); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - Timing accuracy. // Systematic error in time measurements. if (!undefined(wcs->timsyer)) { wcsutil_double2str(keyvalue, format, wcs->timsyer); sprintf(comment, "[%s] Systematic error in time measurements", timeunit); wcshdo_util(ctrl, "TIMSYER", "", 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, comment, nkeyrec, header, &status); } // Relative error in time measurements. if (!undefined(wcs->timrder)) { wcsutil_double2str(keyvalue, format, wcs->timrder); sprintf(comment, "[%s] Relative error in time measurements", timeunit); wcshdo_util(ctrl, "TIMRDER", "", 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, comment, nkeyrec, header, &status); } // Time resolution. if (!undefined(wcs->timedel)) { wcsutil_double2str(keyvalue, format, wcs->timedel); sprintf(comment, "[%s] Time resolution", timeunit); wcshdo_util(ctrl, "TIMEDEL", "", 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, comment, nkeyrec, header, &status); } // Reference position of timestamp in binned data. if (!undefined(wcs->timepixr)) { wcsutil_double2str(keyvalue, format, wcs->timepixr); wcshdo_util(ctrl, "TIMEPIXR", "", 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "Reference position of timestamp in binned data", nkeyrec, header, &status); } // - - - - - - - - - - - - - - - - - - Spatial & celestial reference frame. // Observatory coordinates. if (!undefined(wcs->obsgeo[0]) && !undefined(wcs->obsgeo[1]) && !undefined(wcs->obsgeo[2])) { for (k = 0; k < 3; k++) { wcsutil_double2str(keyvalue, format, wcs->obsgeo[k]); sprintf(comment, "[m] observatory %c-coordinate", xyz[k]); obsgeo[7] = xyz[k]; obsg[4] = xyz[k]; wcshdo_util(ctrl, obsgeo, obsg, 0, 0x0, 0, 0, 0, ' ', colnum, colax, keyvalue, comment, nkeyrec, header, &status); } } else if ( !undefined(wcs->obsgeo[3]) && !undefined(wcs->obsgeo[4]) && !undefined(wcs->obsgeo[5])) { wcsutil_double2str(keyvalue, format, wcs->obsgeo[3]); wcshdo_util(ctrl, "OBSGEO-L", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "[deg] IAU(1976) observatory longitude", nkeyrec, header, &status); wcsutil_double2str(keyvalue, format, wcs->obsgeo[4]); wcshdo_util(ctrl, "OBSGEO-B", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "[deg] IAU(1976) observatory latitude", nkeyrec, header, &status); wcsutil_double2str(keyvalue, format, wcs->obsgeo[5]); wcshdo_util(ctrl, "OBSGEO-L", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "[m] IAU(1976) observatory height", nkeyrec, header, &status); } // Spacecraft orbit ephemeris file. if (wcs->obsorbit[0]) { sprintf(keyvalue, "'%s'", wcs->obsorbit); wcshdo_util(ctrl, "OBSORBIT", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "Spacecraft orbit ephemeris file", nkeyrec, header, &status); } // Equatorial coordinate system type. if (wcs->radesys[0]) { sprintf(keyvalue, "'%s'", wcs->radesys); wcshdo_util(ctrl, "RADESYS", "RADE", 0, 0x0, 0, 0, 0, alt, colnum, colax, keyvalue, "Equatorial coordinate system", nkeyrec, header, &status); } // Equinox of equatorial coordinate system. if (!undefined(wcs->equinox)) { wcsutil_double2str(keyvalue, format, wcs->equinox); wcshdo_util(ctrl, "EQUINOX", "EQUI", 0, 0x0, 0, 0, 0, alt, colnum, colax, keyvalue, "[yr] Equinox of equatorial coordinates", nkeyrec, header, &status); } // Reference frame of spectral coordinates. if (wcs->specsys[0]) { sprintf(keyvalue, "'%s'", wcs->specsys); wcshdo_util(ctrl, "SPECSYS", "SPEC", 0, 0x0, 0, 0, 0, alt, colnum, colax, keyvalue, "Reference frame of spectral coordinates", nkeyrec, header, &status); } // Reference frame of spectral observation. if (wcs->ssysobs[0]) { sprintf(keyvalue, "'%s'", wcs->ssysobs); wcshdo_util(ctrl, "SSYSOBS", "SOBS", 0, 0x0, 0, 0, 0, alt, colnum, colax, keyvalue, "Reference frame of spectral observation", nkeyrec, header, &status); } // Observer's velocity towards source. if (!undefined(wcs->velosys)) { wcsutil_double2str(keyvalue, format, wcs->velosys); wcshdo_util(ctrl, "VELOSYS", "VSYS", 0, 0x0, 0, 0, 0, alt, colnum, colax, keyvalue, "[m/s] Velocity towards source", nkeyrec, header, &status); } // Redshift of the source. if (!undefined(wcs->zsource)) { wcsutil_double2str(keyvalue, format, wcs->zsource); wcshdo_util(ctrl, "ZSOURCE", "ZSOU", 0, 0x0, 0, 0, 0, alt, colnum, colax, keyvalue, "Redshift of the source", nkeyrec, header, &status); } // Reference frame of source redshift. if (wcs->ssyssrc[0]) { sprintf(keyvalue, "'%s'", wcs->ssyssrc); wcshdo_util(ctrl, "SSYSSRC", "SSRC", 0, 0x0, 0, 0, 0, alt, colnum, colax, keyvalue, "Reference frame of source redshift", nkeyrec, header, &status); } // Velocity orientation angle. if (!undefined(wcs->velangl)) { wcsutil_double2str(keyvalue, format, wcs->velangl); wcshdo_util(ctrl, "VELANGL", "VANG", 0, 0x0, 0, 0, 0, alt, colnum, colax, keyvalue, "[deg] Velocity orientation angle", nkeyrec, header, &status); } // - - - - - - - - - - - - - - - - - - - - Additional auxiliary parameters. if ((aux = wcs->aux)) { if (!undefined(aux->rsun_ref)) { wcsutil_double2str(keyvalue, format, aux->rsun_ref); wcshdo_util(ctrl, "RSUN_REF", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "[m] Solar radius", nkeyrec, header, &status); } if (!undefined(aux->dsun_obs)) { wcsutil_double2str(keyvalue, format, aux->dsun_obs); wcshdo_util(ctrl, "DSUN_OBS", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "[m] Distance from centre of Sun to observer", nkeyrec, header, &status); } if (!undefined(aux->crln_obs)) { wcsutil_double2str(keyvalue, format, aux->crln_obs); wcshdo_util(ctrl, "CRLN_OBS", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "[deg] Carrington heliographic lng of observer", nkeyrec, header, &status); if (!undefined(aux->hglt_obs)) { wcsutil_double2str(keyvalue, format, aux->hglt_obs); wcshdo_util(ctrl, "CRLT_OBS", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "[deg] Heliographic latitude of observer", nkeyrec, header, &status); } } if (!undefined(aux->hgln_obs)) { wcsutil_double2str(keyvalue, format, aux->hgln_obs); wcshdo_util(ctrl, "HGLN_OBS", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "[deg] Stonyhurst heliographic lng of observer", nkeyrec, header, &status); if (!undefined(aux->hglt_obs)) { wcsutil_double2str(keyvalue, format, aux->hglt_obs); wcshdo_util(ctrl, "HGLT_OBS", 0x0, 0, 0x0, 0, 0, 0, ' ', 0, 0x0, keyvalue, "[deg] Heliographic latitude of observer", nkeyrec, header, &status); } } } // - - - - - - - - - - - - - - - - - - - - - Distortion function parameters. if (dosip) { // Simple Imaging Polynomial (SIP) is handled by translating its dpkey // records. Determine a suitable numerical precision for the // polynomial coefficients to avoid trailing zeroes common to all of // them. dis = wcs->lin.dispre; if (dofmt) { keyp = dis->dp; kp0 = 2; for (idp = 0; idp < dis->ndp; idp++, keyp++) { cp = strchr(keyp->field, '.') + 1; if (strncmp(cp, "SIP.", 4) != 0) continue; wcsutil_double2str(keyvalue, "%20.13E", dpkeyd(keyp)); kpi = 15; while (kp0 < kpi && keyvalue[kpi] == '0') kpi--; kp0 = kpi; } precision = kp0 - 2; if (precision < 1) precision = 1; if (13 < precision) precision = 13; sprintf(format, "%%20.%dE", precision); } // Ensure the coefficients are written in a human-readable sequence. for (j = 0; j <= 1; j++) { // Distortion function polynomial coefficients. wcshdo_util(ctrl, "", "", 0, 0x0, 0, 0, 0, ' ', 0, 0, "", "", nkeyrec, header, &status); if (j == 0) { strcpy(keyword, "A_"); } else { strcpy(keyword, "B_"); } ncoeff = dis->iparm[j][I_TPDNCO]; for (degree = 0; degree <= 9; degree++) { if (ncoeff <= nTPD[degree]) break; } strcpy(keyword+2, "ORDER"); sprintf(keyvalue, "%20d", degree); sprintf(comment, "SIP polynomial degree, axis %d, pixel-to-sky", j+1); wcshdo_util(ctrl, keyword, "", 0, 0x0, 0, 0, 0, ' ', 0, 0, keyvalue, comment, nkeyrec, header, &status); keyp = dis->dp; for (idp = 0; idp < dis->ndp; idp++, keyp++) { if (keyp->j != j+1) continue; if ((keyval = dpkeyd(keyp)) == 0.0) continue; cp = strchr(keyp->field, '.') + 1; if (strncmp(cp, "SIP.FWD.", 8) != 0) continue; cp += 8; strcpy(keyword+2, cp); sscanf(cp, "%d_%d", &p, &q); strncpy(term, "xxxxxxxxx", p); strncpy(term+p, "yyyyyyyyy", q); term[p+q] = '\0'; wcsutil_double2str(keyvalue, format, keyval); sprintf(comment, "SIP distortion coefficient: %s", term); wcshdo_util(ctrl, keyword, "", 0, 0x0, 0, 0, 0, ' ', 0, 0, keyvalue, comment, nkeyrec, header, &status); } if (dis->maxdis[j] != 0.0) { strcpy(keyword+2, "DMAX"); wcsutil_double2str(keyvalue, "%20.3f", dis->maxdis[j]); wcshdo_util(ctrl, keyword, "", 0, 0x0, 0, 0, 0, ' ', 0, 0, keyvalue, "Maximum value of distortion function", nkeyrec, header, &status); } // Inverse distortion function polynomial coefficients. if (dis->disx2p == 0x0) continue; wcshdo_util(ctrl, "", "", 0, 0x0, 0, 0, 0, ' ', 0, 0, "", "", nkeyrec, header, &status); if (j == 0) { strcpy(keyword, "AP_"); } else { strcpy(keyword, "BP_"); } ncoeff = dis->iparm[j][I_NDPARM] - dis->iparm[j][I_TPDNCO]; for (degree = 0; degree <= 9; degree++) { if (ncoeff <= nTPD[degree]) break; } strcpy(keyword+3, "ORDER"); sprintf(keyvalue, "%20d", degree); sprintf(comment, "SIP polynomial degree, axis %d, sky-to-pixel", j+1); wcshdo_util(ctrl, keyword, "", 0, 0x0, 0, 0, 0, ' ', 0, 0, keyvalue, comment, nkeyrec, header, &status); keyp = dis->dp; for (idp = 0; idp < dis->ndp; idp++, keyp++) { if (keyp->j != j+1) continue; if ((keyval = dpkeyd(keyp)) == 0.0) continue; cp = strchr(keyp->field, '.') + 1; if (strncmp(cp, "SIP.REV.", 8) != 0) continue; cp += 8; strcpy(keyword+3, cp); sscanf(cp, "%d_%d", &p, &q); strncpy(term, "xxxxxxxxx", p); strncpy(term+p, "yyyyyyyyy", q); term[p+q] = '\0'; wcsutil_double2str(keyvalue, format, keyval); sprintf(comment, "SIP inverse coefficient: %s", term); wcshdo_util(ctrl, keyword, "", 0, 0x0, 0, 0, 0, ' ', 0, 0, keyvalue, comment, nkeyrec, header, &status); } } } for (idis = 0; idis < 2; idis++) { if (idis == 0 && (dis = wcs->lin.dispre) == 0x0) continue; if (idis == 1 && (dis = wcs->lin.disseq) == 0x0) continue; for (j = 0; j < naxis; j++) { if (dis->disp2x[j] == 0x0) continue; iparm = dis->iparm[j]; dparm = dis->dparm[j]; // Identify the distortion type. if (dotpv) { // TPV "projection" is handled by translating its dpkey records, // which were originally translated from PVi_ma by wcsset(), or // possibly input directly as a CQDISia = 'TPV' distortion type. // Determine a suitable numerical precision for the polynomial // coefficients to avoid trailing zeroes common to all of them. if (dofmt) wcshdo_format('E', iparm[I_NDPARM], dparm, format); sprintf(fmt01, "%.3ss", format); wcshdo_util(ctrl, "", "", 0, 0x0, 0, 0, 0, ' ', 0, 0, "", "", nkeyrec, header, &status); // Distortion function polynomial coefficients. sprintf(keyword, "PV%d_", j+1); kp = keyword + strlen(keyword); keyp = dis->dp; for (idp = 0; idp < dis->ndp; idp++, keyp++) { if (keyp->j != j+1) continue; if ((keyval = dpkeyd(keyp)) == 0.0) continue; cp = strchr(keyp->field, '.') + 1; if (strncmp(cp, "TPV.", 4) != 0) continue; strcpy(kp, cp+4); // Identify the term of the TPV polynomial for human readers. sscanf(cp+4, "%d", &m); wcshdo_tpdterm(m, j == wcs->lng, term); sprintf(comment, "TPV coefficient: %s", term); if (keyval == 1.0) { sprintf(keyvalue, fmt01, "1.0"); } else { wcsutil_double2str(keyvalue, format, keyval); } wcshdo_util(ctrl, keyword, "", 0, 0x0, 0, 0, 0, alt, 0, 0, keyvalue, comment, nkeyrec, header, &status); } } else if (strcmp(dis->dtype[j], "TPD") == 0 || dotpd || strcmp(dis->dtype[j], "Polynomial") == 0 || strcmp(dis->dtype[j], "Polynomial*") == 0) { // One of the Paper IV type polynomial distortions. wcshdo_util(ctrl, "", "", 0, 0x0, 0, 0, 0, ' ', 0, 0, "", "", nkeyrec, header, &status); if (strcmp(dis->dtype[j], "TPD") == 0) { // Pure TPD. dotpd = 1; } else if (strncmp(dis->dtype[j], "Polynomial", 10) == 0) { // Polynomial distortion. Write it as TPD by request? dotpd = (iparm[I_DTYPE] & DIS_DOTPD); strcpy(tpdsrc, "Polynomial distortion"); } pq = idis ? 'Q' : 'P'; Nhat = dis->Nhat[j]; // CPDISja/CQDISia sprintf(keyword, "C%cDIS%d", pq, j+1); if (idis == 0) { strcpy(comment, "P = prior, "); } else { strcpy(comment, "Q = sequent, "); } if (dotpd) { strcpy(keyvalue, "'TPD'"); strcat(comment, "Template Polynomial Distortion"); // For identifying terms of the TPD polynomial. axmap = dis->axmap[j]; direct = 1; doaux = iparm[I_TPDAUX]; if (Nhat == 2) { // Associate x with longitude, y with latitude. if (axmap[0] == wcs->lng && axmap[1] == wcs->lat) { direct = 1; } else if (axmap[0] == wcs->lat && axmap[1] == wcs->lng) { direct = 0; } else { // Non-celestial. direct = (axmap[0] < axmap[1]); } } } else { strcpy(keyvalue, "'Polynomial'"); strcat(comment, "general Polynomial distortion"); } wcshdo_util(ctrl, keyword, "", 0, 0x0, 0, 0, 0, alt, 0, 0, keyvalue, comment, nkeyrec, header, &status); // NAXES. sprintf(keyword, "D%c%d", pq, j+1); sprintf(keyvalue, "'NAXES: %d'", Nhat); if (Nhat == 1) { strcpy(comment, "One independent variable"); } else if (Nhat == 2) { strcpy(comment, "Two independent variables"); } else { strcpy(comment, "Number of independent variables"); } wcshdo_util(ctrl, keyword, "", 0, 0x0, 0, 0, 0, alt, 0, 0, keyvalue, comment, nkeyrec, header, &status); // AXIS.jhat for (jhat = 0; jhat < Nhat; jhat++) { axmap = dis->axmap[j]; sprintf(keyvalue, "'AXIS.%d: %d'", jhat+1, axmap[jhat]+1); if (jhat == 0) { strcpy(comment, "1st"); } else if (jhat == 1) { strcpy(comment, "2nd"); } else if (jhat == 2) { strcpy(comment, "3rd"); } else { sprintf(comment, "%dth", jhat+1); } sprintf(comment+strlen(comment), " independent variable: axis %d", axmap[jhat]+1); if (dotpd) { // axid is "xyxuvu". cp = axid; if (!direct) cp++; if (doaux) cp += 3; sprintf(comment+strlen(comment), " (= %c)", cp[jhat]); } wcshdo_util(ctrl, keyword, "", 0, 0x0, 0, 0, 0, alt, 0, 0, keyvalue, comment, nkeyrec, header, &status); } // OFFSET.jhat if (dofmt) wcshdo_format('f', Nhat, dis->offset[j], format); for (jhat = 0; jhat < Nhat; jhat++) { if (dis->offset[j][jhat] == 0.0) continue; wcsutil_double2str(ctemp, format, dis->offset[j][jhat]); sprintf(keyvalue, "'OFFSET.%d: %s'", jhat+1, ctemp); sprintf(comment, "Variable %d renormalization offset", jhat+1); wcshdo_util(ctrl, keyword, "", 0, 0x0, 0, 0, 0, alt, 0, 0, keyvalue, comment, nkeyrec, header, &status); } // SCALE.jhat if (dofmt) wcshdo_format('f', Nhat, dis->scale[j], format); for (jhat = 0; jhat < Nhat; jhat++) { if (dis->scale[j][jhat] == 1.0) continue; wcsutil_double2str(ctemp, format, dis->scale[j][jhat]); sprintf(keyvalue, "'SCALE.%d: %s'", jhat+1, ctemp); sprintf(comment, "Variable %d renormalization scale", jhat+1); wcshdo_util(ctrl, keyword, "", 0, 0x0, 0, 0, 0, alt, 0, 0, keyvalue, comment, nkeyrec, header, &status); } // Does the distortion function compute a correction? if (dis->docorr[j]) { wcshdo_util(ctrl, keyword, "", 0, 0x0, 0, 0, 0, alt, 0, 0, "'DOCORR: 1'", "Distortion function computes a correction", nkeyrec, header, &status); } else { wcshdo_util(ctrl, keyword, "", 0, 0x0, 0, 0, 0, alt, 0, 0, "'DOCORR: 0'", "Distortion function computes coordinates", nkeyrec, header, &status); } if (dotpd) { // Template Polynomial Distortion (TPD). As it may have been // translated from SIP, TPV, DSS, TNX, ZPX, or perhaps // Polynomial, the dpkey records may not relate to TPD. // Output is therefore handled via dparm. if (dofmt) wcshdo_format('E', iparm[I_NDPARM], dparm, format); sprintf(fmt01, "%.3ss", format); // AUX.jhat.COEFF.m if (doaux) { for (idp = 0; idp < 6; idp++) { if (dparm[idp] == 0.0) { sprintf(ctemp, fmt01, "0.0"); } else if (dparm[idp] == 1.0) { sprintf(ctemp, fmt01, "1.0"); } else { wcsutil_double2str(ctemp, format, dparm[idp]); } if (idp < 3) { sprintf(keyvalue, "'AUX.1.COEFF.%d: %s'", idp%3, ctemp); sprintf(comment, "TPD: x = c0 + c1*u + c2*v"); } else { sprintf(keyvalue, "'AUX.2.COEFF.%d: %s'", idp%3, ctemp); sprintf(comment, "TPD: y = d0 + d1*u + d2*v"); } wcshdo_util(ctrl, keyword, "", 0, 0x0, 0, 0, 0, alt, 0, 0, keyvalue, comment, nkeyrec, header, &status); } dparm += 6; } // TPD.FWD.m for (idp = 0; idp < iparm[I_TPDNCO]; idp++) { if (dparm[idp] == 0.0) continue; if (dparm[idp] == 1.0) { sprintf(ctemp, fmt01, "1.0"); } else { wcsutil_double2str(ctemp, format, dparm[idp]); } m = idp; sprintf(keyvalue, "'TPD.FWD.%d:%s %s'", m, (m<10)?" ":"", ctemp); wcshdo_tpdterm(m, direct, term); sprintf(comment, "TPD coefficient: %s", term); wcshdo_util(ctrl, keyword, "", 0, 0x0, 0, 0, 0, alt, 0, 0, keyvalue, comment, nkeyrec, header, &status); } // CPERRja/CQERRia if (dis->maxdis[j] != 0.0) { sprintf(keyword, "C%cERR%d", pq, j+1); sprintf(keyvalue, "%20.2f", dis->maxdis[j]); sprintf(comment, "%sMaximum absolute value of distortion", idis?"":"[pix] "); wcshdo_util(ctrl, keyword, "", 0, 0x0, 0, 0, 0, alt, 0, 0, keyvalue, comment, nkeyrec, header, &status); } // Inverse distortion function polynomial coefficients. if (dis->disx2p[j] == 0x0) continue; wcshdo_util(ctrl, "", "", 0, 0x0, 0, 0, 0, ' ', 0, 0, "", "", nkeyrec, header, &status); // TPD.REV.m sprintf(keyword, "D%c%d", pq, j+1); for (idp = iparm[I_TPDNCO]; idp < iparm[I_NDPARM]; idp++) { if (dparm[idp] == 0.0) continue; wcsutil_double2str(ctemp, format, dparm[idp]); m = idp - iparm[I_TPDNCO]; sprintf(keyvalue, "'TPD.REV.%d:%s %s'", m, (m<10)?" ":"", ctemp); wcshdo_tpdterm(m, direct, term); sprintf(comment, "TPD coefficient: %s", term); wcshdo_util(ctrl, keyword, "", 0, 0x0, 0, 0, 0, alt, 0, 0, keyvalue, comment, nkeyrec, header, &status); } } else { // General polynomial distortion, handled via its dpkey records // since iparm and dparm may hold a translation to TPD. // Do auxiliary variables first. keyp = dis->dp; for (idp = 0; idp < dis->ndp; idp++, keyp++) { if (keyp->j != j+1) continue; cp = strchr(keyp->field, '.') + 1; if (strncmp(cp, "NAUX", 4) != 0) continue; sprintf(keyvalue, "'%s: %d'", cp, dpkeyi(keyp)); wcshdo_util(ctrl, keyword, "", 0, 0x0, 0, 0, 0, alt, 0, 0, keyvalue, "Number of auxiliary variables", nkeyrec, header, &status); keyp = dis->dp; for (idp = 0; idp < dis->ndp; idp++, keyp++) { if (keyp->j != j+1) continue; keyval = dpkeyd(keyp); cp = strchr(keyp->field, '.') + 1; if (strncmp(cp, "AUX.", 4) != 0) continue; sscanf(cp+4, "%d", &m); sprintf(keyvalue, "'%s:", cp); cp = strchr(cp+4, '.') + 1; kp = keyvalue + strlen(keyvalue); if ((double)((int)keyval) == keyval) { sprintf(kp, "%4d'", (int)keyval); } else if (keyval == 0.5) { strcat(kp, " 0.5'"); } else { wcsutil_double2str(kp, "%21.13E", keyval); strcat(keyvalue, "'"); } sscanf(cp+6, "%d", &p); if (strncmp(cp, "POWER.", 4) == 0) { if (p) { sprintf(comment, "Aux %d: var %d power", m, p); } else { sprintf(comment, "Aux %d: power of sum of terms", m); } } else { if (p) { sprintf(comment, "Aux %d: var %d coefficient", m, p); } else { sprintf(comment, "Aux %d: offset term", m); } } wcshdo_util(ctrl, keyword, "", 0, 0x0, 0, 0, 0, alt, 0, 0, keyvalue, comment, nkeyrec, header, &status); } break; } // Do polynomial terms. keyp = dis->dp; for (idp = 0; idp < dis->ndp; idp++, keyp++) { if (keyp->j != j+1) continue; cp = strchr(keyp->field, '.') + 1; if (strncmp(cp, "NTERMS", 6) != 0) continue; sprintf(keyvalue, "'%s: %d'", cp, dpkeyi(keyp)); wcshdo_util(ctrl, keyword, "", 0, 0x0, 0, 0, 0, alt, 0, 0, keyvalue, "Number of terms in the polynomial", nkeyrec, header, &status); } keyp = dis->dp; for (idp = 0; idp < dis->ndp; idp++, keyp++) { if (keyp->j != j+1) continue; if ((keyval = dpkeyd(keyp)) == 0.0) continue; cp = strchr(keyp->field, '.') + 1; if (strncmp(cp, "TERM.", 5) != 0) continue; sscanf(cp+5, "%d", &m); sprintf(keyvalue, "'%s:%s ", cp, (m<10)?" ":""); cp = strchr(cp+5, '.') + 1; kp = keyvalue + strlen(keyvalue); if (strncmp(cp, "VAR.", 4) == 0) { if ((double)((int)keyval) == keyval) { sprintf(kp, "%20d", (int)keyval); } else { wcsutil_double2str(kp, "%20.13f", keyval); } sscanf(cp+4, "%d", &p); if (p <= Nhat) { sprintf(comment, "Poly term %d: var %d power", m, p); } else { sprintf(comment, "Poly term %d: aux %d power", m, p-Nhat); } } else { wcsutil_double2str(kp, "%20.13E", keyval); sprintf(comment, "Poly term %d: coefficient", m); } strcat(keyvalue, "'"); wcshdo_util(ctrl, keyword, "", 0, 0x0, 0, 0, 0, alt, 0, 0, keyvalue, comment, nkeyrec, header, &status); } // CPERRja/CQERRia if (dis->maxdis[j] != 0.0) { sprintf(keyword, "C%cERR%d", pq, j+1); sprintf(keyvalue, "%20.2f", dis->maxdis[j]); sprintf(comment, "%sMaximum absolute value of distortion", idis?"":"[pix] "); wcshdo_util(ctrl, keyword, "", 0, 0x0, 0, 0, 0, alt, 0, 0, keyvalue, comment, nkeyrec, header, &status); } } } } // DVERRa if (dis->totdis != 0.0) { sprintf(keyvalue, "%20.2f", dis->totdis); sprintf(comment, "Maximum combined distortion"); wcshdo_util(ctrl, "DVERR", "", 0, 0x0, 0, 0, 0, alt, 0, 0, keyvalue, comment, nkeyrec, header, &status); } } // Add identification. wcshdo_util(ctrl, "", "", 0, 0x0, 0, 0, 0, ' ', 0, 0, "", "", nkeyrec, header, &status); if (dotpd == DIS_DOTPD) { // TPD by translation. sprintf(comment, "Translated from %s to TPD by WCSLIB %s", tpdsrc, wcslib_version(0x0)); } else { sprintf(comment, "WCS header keyrecords produced by WCSLIB %s", wcslib_version(0x0)); } wcshdo_util(ctrl, "COMMENT", "", 0, 0x0, 0, 0, 0, ' ', 0, 0, "", comment, nkeyrec, header, &status); if (status == WCSHDRERR_MEMORY) { wcserr_set(WCSHDR_ERRMSG(status)); } return status; } //---------------------------------------------------------------------------- // Determine a suitable floating point format for a set of parameters. void wcshdo_format( int fmt, int nval, const double val[], char *format) { int emax = -999; int emin = +999; int precision = 0; for (int i = 0; i < nval; i++) { // Double precision has at least 15 significant digits, and up to 17: // http://en.wikipedia.org/wiki/Double-precision_floating-point_format char cval[24]; wcsutil_double2str(cval, "%21.14E", val[i]); int cpi = 16; while (2 < cpi && cval[cpi] == '0') cpi--; // Precision for 'E' format. cpi -= 2; if (precision < cpi) precision = cpi; // Range of significant digits for 'f' format. int expon; sscanf(cval+18, "%d", &expon); if (emax < expon) emax = expon; expon -= cpi; if (expon < emin) emin = expon; } if (fmt == 'G') { // Because e.g. writing 1e4 as 10000 requires an extra digit. emax++; if (emin < -15 || 15 < emax || 15 < (emax - emin)) { fmt = 'E'; } else { fmt = 'f'; } } if (fmt == 'f') { precision = -emin; if (precision < 1) precision = 1; if (17 < precision) precision = 17; sprintf(format, "%%20.%df", precision); } else { if (precision < 1) precision = 1; if (14 < precision) precision = 14; if (precision < 14) { sprintf(format, "%%20.%dE", precision); } else { sprintf(format, "%%21.%dE", precision); } } } //---------------------------------------------------------------------------- // Construct a string that identifies the term of a TPD or TPV polynomial. void wcshdo_tpdterm( int m, int direct, char *term) { const int nTPD[] = {1, 4, 7, 12, 17, 24, 31, 40, 49, 60}; int degree, k; for (degree = 0; degree <= 9; degree++) { if (m < nTPD[degree]) break; } if (degree == 0) { strcpy(term, "1"); } else { k = degree - (m - nTPD[degree-1]); if (k < 0) { memcpy(term, "rrrrrrrrr", degree); } else if (direct) { memcpy(term, "xxxxxxxxx", k); memcpy(term+k, "yyyyyyyyy", degree-k); } else { memcpy(term, "yyyyyyyyy", k); memcpy(term+k, "xxxxxxxxx", degree-k); } term[degree] = '\0'; } } //---------------------------------------------------------------------------- // Construct a keyrecord from the components given. void wcshdo_util( int relax, const char pikey[], const char tbkey[], int level, const char tlkey[], int i, int j, int m, char alt, int btcol, int plcol[], char keyvalue[], const char keycomment[], int *nkeyrec, char **header, int *status) { char ch0, ch1, *hptr, keyword[32], *kptr; int nbyte, nc = 47, nv; if (*status) return; // Reallocate memory in blocks of 2880 bytes. if ((*nkeyrec)%32 == 0) { nbyte = ((*nkeyrec)/32 + 1) * 2880; if (!(hptr = realloc(*header, nbyte))) { *status = WCSHDRERR_MEMORY; return; } *header = hptr; } // Construct the keyword. if (alt == ' ') alt = '\0'; if (btcol) { // Binary table image array. if (i > 0 && j) { if (j > 0) { sprintf(keyword, "%d%d%s%d%c", i, j, tbkey, btcol, alt); } else { sprintf(keyword, "%d%s%d_%d%c", i, tbkey, btcol, m, alt); } } else if (i > 0) { sprintf(keyword, "%d%s%d%c", i, tbkey, btcol, alt); } else if (j > 0) { sprintf(keyword, "%d%s%d%c", j, tbkey, btcol, alt); } else { sprintf(keyword, "%s%d%c", tbkey, btcol, alt); } if ((strlen(keyword) < 8) && tlkey && (relax & level)) { // Use the long form. if (i > 0 && j) { if (j > 0) { sprintf(keyword, "%d%d%s%d%c", i, j, tlkey, btcol, alt); } else { sprintf(keyword, "%d%s%d_%d%c", i, tlkey, btcol, m, alt); } } else if (i > 0) { sprintf(keyword, "%d%s%d%c", i, tlkey, btcol, alt); } else if (j > 0) { sprintf(keyword, "%d%s%d%c", j, tlkey, btcol, alt); } else { sprintf(keyword, "%s%d%c", tlkey, btcol, alt); } } } else if (plcol && plcol[0]) { // Pixel list. if (i > 0 && j) { if (j > 0) { sprintf(keyword, "T%s%d_%d%c", tbkey, plcol[i-1], plcol[j-1], alt); } else { sprintf(keyword, "T%s%d_%d%c", tbkey, plcol[i-1], m, alt); } } else if (i > 0) { sprintf(keyword, "T%s%d%c", tbkey, plcol[i-1], alt); } else if (j > 0) { sprintf(keyword, "T%s%d%c", tbkey, plcol[j-1], alt); } else { sprintf(keyword, "%s%d%c", tbkey, plcol[0], alt); } if ((strlen(keyword) < 8) && tlkey && (relax & level)) { // Use the long form. if (i > 0 && j) { if (j > 0) { sprintf(keyword, "T%s%d_%d%c", tlkey, plcol[i-1], plcol[j-1], alt); } else { sprintf(keyword, "T%s%d_%d%c", tlkey, plcol[i-1], m, alt); } } else if (i > 0) { sprintf(keyword, "T%s%d%c", tlkey, plcol[i-1], alt); } else if (j > 0) { sprintf(keyword, "T%s%d%c", tlkey, plcol[j-1], alt); } else { sprintf(keyword, "%s%d%c", tlkey, plcol[0], alt); } } } else { if (i > 0 && j) { if (j > 0) { sprintf(keyword, "%s%d_%d%c", pikey, i, j, alt); } else { sprintf(keyword, "%s%d_%d%c", pikey, i, m, alt); } } else if (i > 0) { sprintf(keyword, "%s%d%c", pikey, i, alt); } else if (j > 0) { sprintf(keyword, "%s%d%c", pikey, j, alt); } else { sprintf(keyword, "%s%c", pikey, alt); } } // Double-up single-quotes in string keyvalues. if (*keyvalue == '\'') { hptr = keyvalue + 1; while (*hptr) { if (*hptr == '\'') { kptr = hptr++; if (*hptr) { ch0 = *kptr; while (*kptr) { ch1 = *(++kptr); *kptr = ch0; ch0 = ch1; } } else { break; } } hptr++; } // Check length. if (strlen(keyvalue) > 70) { // Truncate. keyvalue[69] = '\''; keyvalue[70] = '\0'; } } else { // Check length. if (strlen(keyvalue) > 70) { // Truncate. keyvalue[70] = '\0'; } } if ((nv = strlen(keyvalue) > 20)) { // Rob the keycomment to make space for the keyvalue. nc -= (nv - 20); } hptr = *header + (80 * ((*nkeyrec)++)); if (*keyword == '\0') { sprintf(hptr, "%80.80s", " "); } else if (strcmp(keyword, "COMMENT") == 0) { sprintf(hptr, "%-8.8s %-71.71s", keyword, keycomment); } else { sprintf(hptr, "%-8.8s= %-20s / %-*.*s", keyword, keyvalue, nc, nc, keycomment); } } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/wcshdr.h0000644000175100001710000020171000000000000017026 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcshdr.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the wcshdr routines * ------------------------------ * Routines in this suite are aimed at extracting WCS information from a FITS * file. The information is encoded via keywords defined in * = "Representations of world coordinates in FITS", = Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (WCS Paper I) = = "Representations of celestial coordinates in FITS", = Calabretta, M.R., & Greisen, E.W. 2002, A&A, 395, 1077 (WCS Paper II) = = "Representations of spectral coordinates in FITS", = Greisen, E.W., Calabretta, M.R., Valdes, F.G., & Allen, S.L. = 2006, A&A, 446, 747 (WCS Paper III) = = "Representations of distortions in FITS world coordinate systems", = Calabretta, M.R. et al. (WCS Paper IV, draft dated 2004/04/22), = available from http://www.atnf.csiro.au/people/Mark.Calabretta = = "Representations of time coordinates in FITS - = Time and relative dimension in space", = Rots, A.H., Bunclark, P.S., Calabretta, M.R., Allen, S.L., = Manchester, R.N., & Thompson, W.T. 2015, A&A, 574, A36 (WCS Paper VII) * * These routines provide the high-level interface between the FITS file and * the WCS coordinate transformation routines. * * Additionally, function wcshdo() is provided to write out the contents of a * wcsprm struct as a FITS header. * * Briefly, the anticipated sequence of operations is as follows: * * - 1: Open the FITS file and read the image or binary table header, e.g. * using CFITSIO routine fits_hdr2str(). * * - 2: Parse the header using wcspih() or wcsbth(); they will automatically * interpret 'TAB' header keywords using wcstab(). * * - 3: Allocate memory for, and read 'TAB' arrays from the binary table * extension, e.g. using CFITSIO routine fits_read_wcstab() - refer to * the prologue of getwcstab.h. wcsset() will automatically take * control of this allocated memory, in particular causing it to be * freed by wcsfree(). * * - 4: Translate non-standard WCS usage using wcsfix(), see wcsfix.h. * * - 5: Initialize wcsprm struct(s) using wcsset() and calculate coordinates * using wcsp2s() and/or wcss2p(). Refer to the prologue of wcs.h for a * description of these and other high-level WCS coordinate * transformation routines. * * - 6: Clean up by freeing memory with wcsvfree(). * * In detail: * * - wcspih() is a high-level FITS WCS routine that parses an image header. It * returns an array of up to 27 wcsprm structs on each of which it invokes * wcstab(). * * - wcsbth() is the analogue of wcspih() for use with binary tables; it * handles image array and pixel list keywords. As an extension of the FITS * WCS standard, it also recognizes image header keywords which may be used * to provide default values via an inheritance mechanism. * * - wcstab() assists in filling in members of the wcsprm struct associated * with coordinate lookup tables ('TAB'). These are based on arrays stored * in a FITS binary table extension (BINTABLE) that are located by PVi_ma * keywords in the image header. * * - wcsidx() and wcsbdx() are utility routines that return the index for a * specified alternate coordinate descriptor in the array of wcsprm structs * returned by wcspih() or wcsbth(). * * - wcsvfree() deallocates memory for an array of wcsprm structs, such as * returned by wcspih() or wcsbth(). * * - wcshdo() writes out a wcsprm struct as a FITS header. * * * wcspih() - FITS WCS parser routine for image headers * ---------------------------------------------------- * wcspih() is a high-level FITS WCS routine that parses an image header, * either that of a primary HDU or of an image extension. All WCS keywords * defined in Papers I, II, III, IV, and VII are recognized, and also those * used by the AIPS convention and certain other keywords that existed in early * drafts of the WCS papers as explained in wcsbth() note 5. wcspih() also * handles keywords associated with non-standard distortion functions described * in the prologue of dis.h. * * Given a character array containing a FITS image header, wcspih() identifies * and reads all WCS keywords for the primary coordinate representation and up * to 26 alternate representations. It returns this information as an array of * wcsprm structs. * * wcspih() invokes wcstab() on each of the wcsprm structs that it returns. * * Use wcsbth() in preference to wcspih() for FITS headers of unknown type; * wcsbth() can parse image headers as well as binary table and pixel list * headers, although it cannot handle keywords relating to distortion * functions, which may only exist in a primary image header. * * Given and returned: * header char[] Character array containing the (entire) FITS image * header from which to identify and construct the * coordinate representations, for example, as might be * obtained conveniently via the CFITSIO routine * fits_hdr2str(). * * Each header "keyrecord" (formerly "card image") * consists of exactly 80 7-bit ASCII printing characters * in the range 0x20 to 0x7e (which excludes NUL, BS, * TAB, LF, FF and CR) especially noting that the * keyrecords are NOT null-terminated. * * For negative values of ctrl (see below), header[] is * modified so that WCS keyrecords processed by wcspih() * are removed from it. * * Given: * nkeyrec int Number of keyrecords in header[]. * * relax int Degree of permissiveness: * 0: Recognize only FITS keywords defined by the * published WCS standard. * WCSHDR_all: Admit all recognized informal * extensions of the WCS standard. * Fine-grained control of the degree of permissiveness * is also possible as explained in wcsbth() note 5. * * ctrl int Error reporting and other control options for invalid * WCS and other header keyrecords: * 0: Do not report any rejected header keyrecords. * 1: Produce a one-line message stating the number * of WCS keyrecords rejected (nreject). * 2: Report each rejected keyrecord and the reason * why it was rejected. * 3: As above, but also report all non-WCS * keyrecords that were discarded, and the number * of coordinate representations (nwcs) found. * 4: As above, but also report the accepted WCS * keyrecords, with a summary of the number * accepted as well as rejected. * The report is written to stderr by default, or the * stream set by wcsprintf_set(). * * For ctrl < 0, WCS keyrecords processed by wcspih() * are removed from header[]: * -1: Remove only valid WCS keyrecords whose values * were successfully extracted, nothing is * reported. * -2: As above, but also remove WCS keyrecords that * were rejected, reporting each one and the * reason that it was rejected. * -3: As above, and also report the number of * coordinate representations (nwcs) found. * -11: Same as -1 but preserving global WCS-related * keywords such as '{DATE,MJD}-{OBS,BEG,AVG,END}' * and the other basic time-related keywords, and * 'OBSGEO-{X,Y,Z,L,B,H}'. * If any keyrecords are removed from header[] it will * be null-terminated (NUL not being a legal FITS header * character), otherwise it will contain its original * complement of nkeyrec keyrecords and possibly not be * null-terminated. * * Returned: * nreject int* Number of WCS keywords rejected for syntax errors, * illegal values, etc. Keywords not recognized as WCS * keywords are simply ignored. Refer also to wcsbth() * note 5. * * nwcs int* Number of coordinate representations found. * * wcs struct wcsprm** * Pointer to an array of wcsprm structs containing up to * 27 coordinate representations. * * Memory for the array is allocated by wcspih() which * also invokes wcsini() for each struct to allocate * memory for internal arrays and initialize their * members to default values. Refer also to wcsbth() * note 8. Note that wcsset() is not invoked on these * structs. * * This allocated memory must be freed by the user, first * by invoking wcsfree() for each struct, and then by * freeing the array itself. A routine, wcsvfree(), is * provided to do this (see below). * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * 2: Memory allocation failed. * 4: Fatal error returned by Flex parser. * * Notes: * 1: Refer to wcsbth() notes 1, 2, 3, 5, 7, and 8. * * * wcsbth() - FITS WCS parser routine for binary table and image headers * --------------------------------------------------------------------- * wcsbth() is a high-level FITS WCS routine that parses a binary table header. * It handles image array and pixel list WCS keywords which may be present * together in one header. * * As an extension of the FITS WCS standard, wcsbth() also recognizes image * header keywords in a binary table header. These may be used to provide * default values via an inheritance mechanism discussed in note 5 (c.f. * WCSHDR_AUXIMG and WCSHDR_ALLIMG), or may instead result in wcsprm structs * that are not associated with any particular column. Thus wcsbth() can * handle primary image and image extension headers in addition to binary table * headers (it ignores NAXIS and does not rely on the presence of the TFIELDS * keyword). * * All WCS keywords defined in Papers I, II, III, and VII are recognized, and * also those used by the AIPS convention and certain other keywords that * existed in early drafts of the WCS papers as explained in note 5 below. * * wcsbth() sets the colnum or colax[] members of the wcsprm structs that it * returns with the column number of an image array or the column numbers * associated with each pixel coordinate element in a pixel list. wcsprm * structs that are not associated with any particular column, as may be * derived from image header keywords, have colnum == 0. * * Note 6 below discusses the number of wcsprm structs returned by wcsbth(), * and the circumstances in which image header keywords cause a struct to be * created. See also note 9 concerning the number of separate images that may * be stored in a pixel list. * * The API to wcsbth() is similar to that of wcspih() except for the addition * of extra arguments that may be used to restrict its operation. Like * wcspih(), wcsbth() invokes wcstab() on each of the wcsprm structs that it * returns. * * Given and returned: * header char[] Character array containing the (entire) FITS binary * table, primary image, or image extension header from * which to identify and construct the coordinate * representations, for example, as might be obtained * conveniently via the CFITSIO routine fits_hdr2str(). * * Each header "keyrecord" (formerly "card image") * consists of exactly 80 7-bit ASCII printing * characters in the range 0x20 to 0x7e (which excludes * NUL, BS, TAB, LF, FF and CR) especially noting that * the keyrecords are NOT null-terminated. * * For negative values of ctrl (see below), header[] is * modified so that WCS keyrecords processed by wcsbth() * are removed from it. * * Given: * nkeyrec int Number of keyrecords in header[]. * * relax int Degree of permissiveness: * 0: Recognize only FITS keywords defined by the * published WCS standard. * WCSHDR_all: Admit all recognized informal * extensions of the WCS standard. * Fine-grained control of the degree of permissiveness * is also possible, as explained in note 5 below. * * ctrl int Error reporting and other control options for invalid * WCS and other header keyrecords: * 0: Do not report any rejected header keyrecords. * 1: Produce a one-line message stating the number * of WCS keyrecords rejected (nreject). * 2: Report each rejected keyrecord and the reason * why it was rejected. * 3: As above, but also report all non-WCS * keyrecords that were discarded, and the number * of coordinate representations (nwcs) found. * 4: As above, but also report the accepted WCS * keyrecords, with a summary of the number * accepted as well as rejected. * The report is written to stderr by default, or the * stream set by wcsprintf_set(). * * For ctrl < 0, WCS keyrecords processed by wcsbth() * are removed from header[]: * -1: Remove only valid WCS keyrecords whose values * were successfully extracted, nothing is * reported. * -2: Also remove WCS keyrecords that were rejected, * reporting each one and the reason that it was * rejected. * -3: As above, and also report the number of * coordinate representations (nwcs) found. * -11: Same as -1 but preserving global WCS-related * keywords such as '{DATE,MJD}-{OBS,BEG,AVG,END}' * and the other basic time-related keywords, and * 'OBSGEO-{X,Y,Z,L,B,H}'. * If any keyrecords are removed from header[] it will * be null-terminated (NUL not being a legal FITS header * character), otherwise it will contain its original * complement of nkeyrec keyrecords and possibly not be * null-terminated. * * keysel int Vector of flag bits that may be used to restrict the * keyword types considered: * WCSHDR_IMGHEAD: Image header keywords. * WCSHDR_BIMGARR: Binary table image array. * WCSHDR_PIXLIST: Pixel list keywords. * If zero, there is no restriction. * * Keywords such as EQUIna or RFRQna that are common to * binary table image arrays and pixel lists (including * WCSNna and TWCSna, as explained in note 4 below) are * selected by both WCSHDR_BIMGARR and WCSHDR_PIXLIST. * Thus if inheritance via WCSHDR_ALLIMG is enabled as * discussed in note 5 and one of these shared keywords * is present, then WCSHDR_IMGHEAD and WCSHDR_PIXLIST * alone may be sufficient to cause the construction of * coordinate descriptions for binary table image arrays. * * colsel int* Pointer to an array of table column numbers used to * restrict the keywords considered by wcsbth(). * * A null pointer may be specified to indicate that there * is no restriction. Otherwise, the magnitude of * cols[0] specifies the length of the array: * cols[0] > 0: the columns are included, * cols[0] < 0: the columns are excluded. * * For the pixel list keywords TPn_ka and TCn_ka (and * TPCn_ka and TCDn_ka if WCSHDR_LONGKEY is enabled), it * is an error for one column to be selected but not the * other. This is unlike the situation with invalid * keyrecords, which are simply rejected, because the * error is not intrinsic to the header itself but * arises in the way that it is processed. * * Returned: * nreject int* Number of WCS keywords rejected for syntax errors, * illegal values, etc. Keywords not recognized as WCS * keywords are simply ignored, refer also to note 5 * below. * * nwcs int* Number of coordinate representations found. * * wcs struct wcsprm** * Pointer to an array of wcsprm structs containing up * to 27027 coordinate representations, refer to note 6 * below. * * Memory for the array is allocated by wcsbth() which * also invokes wcsini() for each struct to allocate * memory for internal arrays and initialize their * members to default values. Refer also to note 8 * below. Note that wcsset() is not invoked on these * structs. * * This allocated memory must be freed by the user, first * by invoking wcsfree() for each struct, and then by * freeing the array itself. A routine, wcsvfree(), is * provided to do this (see below). * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * 2: Memory allocation failed. * 3: Invalid column selection. * 4: Fatal error returned by Flex parser. * * Notes: * 1: wcspih() determines the number of coordinate axes independently for * each alternate coordinate representation (denoted by the "a" value in * keywords like CTYPEia) from the higher of * * a: NAXIS, * b: WCSAXESa, * c: The highest axis number in any parameterized WCS keyword. The * keyvalue, as well as the keyword, must be syntactically valid * otherwise it will not be considered. * * If none of these keyword types is present, i.e. if the header only * contains auxiliary WCS keywords for a particular coordinate * representation, then no coordinate description is constructed for it. * * wcsbth() is similar except that it ignores the NAXIS keyword if given * an image header to process. * * The number of axes, which is returned as a member of the wcsprm * struct, may differ for different coordinate representations of the * same image. * * 2: wcspih() and wcsbth() enforce correct FITS "keyword = value" syntax * with regard to "= " occurring in columns 9 and 10. * * However, they do recognize free-format character (NOST 100-2.0, * Sect. 5.2.1), integer (Sect. 5.2.3), and floating-point values * (Sect. 5.2.4) for all keywords. * * 3: Where CROTAn, CDi_ja, and PCi_ja occur together in one header wcspih() * and wcsbth() treat them as described in the prologue to wcs.h. * * 4: WCS Paper I mistakenly defined the pixel list form of WCSNAMEa as * TWCSna instead of WCSNna; the 'T' is meant to substitute for the axis * number in the binary table form of the keyword - note that keywords * defined in WCS Papers II, III, and VII that are not parameterized by * axis number have identical forms for binary tables and pixel lists. * Consequently wcsbth() always treats WCSNna and TWCSna as equivalent. * * 5: wcspih() and wcsbth() interpret the "relax" argument as a vector of * flag bits to provide fine-grained control over what non-standard WCS * keywords to accept. The flag bits are subject to change in future and * should be set by using the preprocessor macros (see below) for the * purpose. * * - WCSHDR_none: Don't accept any extensions (not even those in the * errata). Treat non-conformant keywords in the same way as * non-WCS keywords in the header, i.e. simply ignore them. * * - WCSHDR_all: Accept all extensions recognized by the parser. * * - WCSHDR_reject: Reject non-standard keyrecords (that are not otherwise * explicitly accepted by one of the flags below). A message will * optionally be printed on stderr by default, or the stream set * by wcsprintf_set(), as determined by the ctrl argument, and * nreject will be incremented. * * This flag may be used to signal the presence of non-standard * keywords, otherwise they are simply passed over as though they * did not exist in the header. It is mainly intended for testing * conformance of a FITS header to the WCS standard. * * Keyrecords may be non-standard in several ways: * * - The keyword may be syntactically valid but with keyvalue of * incorrect type or invalid syntax, or the keycomment may be * malformed. * * - The keyword may strongly resemble a WCS keyword but not, in * fact, be one because it does not conform to the standard. * For example, "CRPIX01" looks like a CRPIXja keyword, but in * fact the leading zero on the axis number violates the basic * FITS standard. Likewise, "LONPOLE2" is not a valid * LONPOLEa keyword in the WCS standard, and indeed there is * nothing the parser can sensibly do with it. * * - Use of the keyword may be deprecated by the standard. Such * will be rejected if not explicitly accepted via one of the * flags below. * * - WCSHDR_strict: As for WCSHDR_reject, but also reject AIPS-convention * keywords and all other deprecated usage that is not explicitly * accepted. * * - WCSHDR_CROTAia: Accept CROTAia (wcspih()), * iCROTna (wcsbth()), * TCROTna (wcsbth()). * - WCSHDR_VELREFa: Accept VELREFa. * wcspih() always recognizes the AIPS-convention keywords, * CROTAn, EPOCH, and VELREF for the primary representation * (a = ' ') but alternates are non-standard. * * wcsbth() accepts EPOCHa and VELREFa only if WCSHDR_AUXIMG is * also enabled. * * - WCSHDR_CD00i00j: Accept CD00i00j (wcspih()). * - WCSHDR_PC00i00j: Accept PC00i00j (wcspih()). * - WCSHDR_PROJPn: Accept PROJPn (wcspih()). * These appeared in early drafts of WCS Paper I+II (before they * were split) and are equivalent to CDi_ja, PCi_ja, and PVi_ma * for the primary representation (a = ' '). PROJPn is * equivalent to PVi_ma with m = n <= 9, and is associated * exclusively with the latitude axis. * * - WCSHDR_CD0i_0ja: Accept CD0i_0ja (wcspih()). * - WCSHDR_PC0i_0ja: Accept PC0i_0ja (wcspih()). * - WCSHDR_PV0i_0ma: Accept PV0i_0ja (wcspih()). * - WCSHDR_PS0i_0ma: Accept PS0i_0ja (wcspih()). * Allow the numerical index to have a leading zero in doubly- * parameterized keywords, for example, PC01_01. WCS Paper I * (Sects 2.1.2 & 2.1.4) explicitly disallows leading zeroes. * The FITS 3.0 standard document (Sect. 4.1.2.1) states that the * index in singly-parameterized keywords (e.g. CTYPEia) "shall * not have leading zeroes", and later in Sect. 8.1 that "leading * zeroes must not be used" on PVi_ma and PSi_ma. However, by an * oversight, it is silent on PCi_ja and CDi_ja. * * - WCSHDR_DOBSn (wcsbth() only): Allow DOBSn, the column-specific * analogue of DATE-OBS. By an oversight this was never formally * defined in the standard. * * - WCSHDR_OBSGLBHn (wcsbth() only): Allow OBSGLn, OBSGBn, and OBSGHn, * the column-specific analogues of OBSGEO-L, OBSGEO-B, and * OBSGEO-H. By an oversight these were never formally defined in * the standard. * * - WCSHDR_RADECSYS: Accept RADECSYS. This appeared in early drafts of * WCS Paper I+II and was subsequently replaced by RADESYSa. * * wcsbth() accepts RADECSYS only if WCSHDR_AUXIMG is also * enabled. * * - WCSHDR_EPOCHa: Accept EPOCHa. * * - WCSHDR_VSOURCE: Accept VSOURCEa or VSOUna (wcsbth()). This appeared * in early drafts of WCS Paper III and was subsequently dropped * in favour of ZSOURCEa and ZSOUna. * * wcsbth() accepts VSOURCEa only if WCSHDR_AUXIMG is also * enabled. * * - WCSHDR_DATEREF: Accept DATE-REF, MJD-REF, MJD-REFI, MJD-REFF, JDREF, * JD-REFI, and JD-REFF as synonyms for the standard keywords, * DATEREF, MJDREF, MJDREFI, MJDREFF, JDREF, JDREFI, and JDREFF. * The latter buck the pattern set by the other date keywords * ({DATE,MJD}-{OBS,BEG,AVG,END}), thereby increasing the * potential for confusion and error. * * - WCSHDR_LONGKEY (wcsbth() only): Accept long forms of the alternate * binary table and pixel list WCS keywords, i.e. with "a" non- * blank. Specifically * # jCRPXna TCRPXna : jCRPXn jCRPna TCRPXn TCRPna CRPIXja # - TPCn_ka : - ijPCna - TPn_ka PCi_ja # - TCDn_ka : - ijCDna - TCn_ka CDi_ja # iCDLTna TCDLTna : iCDLTn iCDEna TCDLTn TCDEna CDELTia # iCUNIna TCUNIna : iCUNIn iCUNna TCUNIn TCUNna CUNITia # iCTYPna TCTYPna : iCTYPn iCTYna TCTYPn TCTYna CTYPEia # iCRVLna TCRVLna : iCRVLn iCRVna TCRVLn TCRVna CRVALia # iPVn_ma TPVn_ma : - iVn_ma - TVn_ma PVi_ma # iPSn_ma TPSn_ma : - iSn_ma - TSn_ma PSi_ma * * where the primary and standard alternate forms together with * the image-header equivalent are shown rightwards of the colon. * * The long form of these keywords could be described as quasi- * standard. TPCn_ka, iPVn_ma, and TPVn_ma appeared by mistake * in the examples in WCS Paper II and subsequently these and * also TCDn_ka, iPSn_ma and TPSn_ma were legitimized by the * errata to the WCS papers. * * Strictly speaking, the other long forms are non-standard and * in fact have never appeared in any draft of the WCS papers nor * in the errata. However, as natural extensions of the primary * form they are unlikely to be written with any other intention. * Thus it should be safe to accept them provided, of course, * that the resulting keyword does not exceed the 8-character * limit. * * If WCSHDR_CNAMn is enabled then also accept * # iCNAMna TCNAMna : --- iCNAna --- TCNAna CNAMEia # iCRDEna TCRDEna : --- iCRDna --- TCRDna CRDERia # iCSYEna TCSYEna : --- iCSYna --- TCSYna CSYERia # iCZPHna TCZPHna : --- iCZPna --- TCZPna CZPHSia # iCPERna TCPERna : --- iCPRna --- TCPRna CPERIia * * Note that CNAMEia, CRDERia, CSYERia, CZPHSia, CPERIia, and * their variants are not used by WCSLIB but are stored in the * wcsprm struct as auxiliary information. * * - WCSHDR_CNAMn (wcsbth() only): Accept iCNAMn, iCRDEn, iCSYEn, iCZPHn, * iCPERn, TCNAMn, TCRDEn, TCSYEn, TCZPHn, and TCPERn, i.e. with * "a" blank. While non-standard, these are the obvious analogues * of iCTYPn, TCTYPn, etc. * * - WCSHDR_AUXIMG (wcsbth() only): Allow the image-header form of an * auxiliary WCS keyword with representation-wide scope to * provide a default value for all images. This default may be * overridden by the column-specific form of the keyword. * * For example, a keyword like EQUINOXa would apply to all image * arrays in a binary table, or all pixel list columns with * alternate representation "a" unless overridden by EQUIna. * * Specifically the keywords are: * # LONPOLEa for LONPna # LATPOLEa for LATPna # VELREF - ... (No column-specific form.) # VELREFa - ... Only if WCSHDR_VELREFa is set. * * whose keyvalues are actually used by WCSLIB, and also keywords * providing auxiliary information that is simply stored in the * wcsprm struct: * # WCSNAMEa for WCSNna ... Or TWCSna (see below). # # DATE-OBS for DOBSn # MJD-OBS for MJDOBn # # RADESYSa for RADEna # RADECSYS for RADEna ... Only if WCSHDR_RADECSYS is set. # EPOCH - ... (No column-specific form.) # EPOCHa - ... Only if WCSHDR_EPOCHa is set. # EQUINOXa for EQUIna * * where the image-header keywords on the left provide default * values for the column specific keywords on the right. * * Note that, according to Sect. 8.1 of WCS Paper III, and * Sect. 5.2 of WCS Paper VII, the following are always inherited: * # RESTFREQ for RFRQna # RESTFRQa for RFRQna # RESTWAVa for RWAVna * * being those actually used by WCSLIB, together with the * following auxiliary keywords, many of which do not have binary * table equivalents and therefore can only be inherited: * # TIMESYS - # TREFPOS for TRPOSn # TREFDIR for TRDIRn # PLEPHEM - # TIMEUNIT - # DATEREF - # MJDREF - # MJDREFI - # MJDREFF - # JDREF - # JDREFI - # JDREFF - # TIMEOFFS - # # DATE-BEG - # DATE-AVG for DAVGn # DATE-END - # MJD-BEG - # MJD-AVG for MJDAn # MJD-END - # JEPOCH - # BEPOCH - # TSTART - # TSTOP - # XPOSURE - # TELAPSE - # # TIMSYER - # TIMRDER - # TIMEDEL - # TIMEPIXR - # # OBSGEO-X for OBSGXn # OBSGEO-Y for OBSGYn # OBSGEO-Z for OBSGZn # OBSGEO-L for OBSGLn # OBSGEO-B for OBSGBn # OBSGEO-H for OBSGHn # OBSORBIT - # # SPECSYSa for SPECna # SSYSOBSa for SOBSna # VELOSYSa for VSYSna # VSOURCEa for VSOUna ... Only if WCSHDR_VSOURCE is set. # ZSOURCEa for ZSOUna # SSYSSRCa for SSRCna # VELANGLa for VANGna * * Global image-header keywords, such as MJD-OBS, apply to all * alternate representations, and would therefore provide a * default value for all images in the header. * * This auxiliary inheritance mechanism applies to binary table * image arrays and pixel lists alike. Most of these keywords * have no default value, the exceptions being LONPOLEa and * LATPOLEa, and also RADESYSa and EQUINOXa which provide * defaults for each other. Thus one potential difficulty in * using WCSHDR_AUXIMG is that of erroneously inheriting one of * these four keywords. * * Also, beware of potential inconsistencies that may arise where, * for example, DATE-OBS is inherited, but MJD-OBS is overridden * by MJDOBn and specifies a different time. Pairs in this * category are: * = DATE-OBS/DOBSn versus MJD-OBS/MJDOBn = DATE-AVG/DAVGn versus MJD-AVG/MJDAn = RESTFRQa/RFRQna versus RESTWAVa/RWAVna = OBSGEO-[XYZ]/OBSG[XYZ]n versus OBSGEO-[LBH]/OBSG[LBH]n * * The wcsfixi() routines datfix() and obsfix() are provided to * check the consistency of these and other such pairs of * keywords. * * Unlike WCSHDR_ALLIMG, the existence of one (or all) of these * auxiliary WCS image header keywords will not by itself cause a * wcsprm struct to be created for alternate representation "a". * This is because they do not provide sufficient information to * create a non-trivial coordinate representation when used in * conjunction with the default values of those keywords that are * parameterized by axis number, such as CTYPEia. * * - WCSHDR_ALLIMG (wcsbth() only): Allow the image-header form of *all* * image header WCS keywords to provide a default value for all * image arrays in a binary table (n.b. not pixel list). This * default may be overridden by the column-specific form of the * keyword. * * For example, a keyword like CRPIXja would apply to all image * arrays in a binary table with alternate representation "a" * unless overridden by jCRPna. * * Specifically the keywords are those listed above for * WCSHDR_AUXIMG plus * # WCSAXESa for WCAXna * * which defines the coordinate dimensionality, and the following * keywords that are parameterized by axis number: * # CRPIXja for jCRPna # PCi_ja for ijPCna # CDi_ja for ijCDna # CDELTia for iCDEna # CROTAi for iCROTn # CROTAia - ... Only if WCSHDR_CROTAia is set. # CUNITia for iCUNna # CTYPEia for iCTYna # CRVALia for iCRVna # PVi_ma for iVn_ma # PSi_ma for iSn_ma # # CNAMEia for iCNAna # CRDERia for iCRDna # CSYERia for iCSYna # CZPHSia for iCZPna # CPERIia for iCPRna * * where the image-header keywords on the left provide default * values for the column specific keywords on the right. * * This full inheritance mechanism only applies to binary table * image arrays, not pixel lists, because in the latter case * there is no well-defined association between coordinate axis * number and column number (see note 9 below). * * Note that CNAMEia, CRDERia, CSYERia, and their variants are * not used by WCSLIB but are stored in the wcsprm struct as * auxiliary information. * * Note especially that at least one wcsprm struct will be * returned for each "a" found in one of the image header * keywords listed above: * * - If the image header keywords for "a" ARE NOT inherited by a * binary table, then the struct will not be associated with * any particular table column number and it is up to the user * to provide an association. * * - If the image header keywords for "a" ARE inherited by a * binary table image array, then those keywords are considered * to be "exhausted" and do not result in a separate wcsprm * struct. * * For example, to accept CD00i00j and PC00i00j and reject all other * extensions, use * = relax = WCSHDR_reject | WCSHDR_CD00i00j | WCSHDR_PC00i00j; * * The parser always treats EPOCH as subordinate to EQUINOXa if both are * present, and VSOURCEa is always subordinate to ZSOURCEa. * * Likewise, VELREF is subordinate to the formalism of WCS Paper III, see * spcaips(). * * Neither wcspih() nor wcsbth() currently recognize the AIPS-convention * keywords ALTRPIX or ALTRVAL which effectively define an alternative * representation for a spectral axis. * * 6: Depending on what flags have been set in its "relax" argument, * wcsbth() could return as many as 27027 wcsprm structs: * * - Up to 27 unattached representations derived from image header * keywords. * * - Up to 27 structs for each of up to 999 columns containing an image * arrays. * * - Up to 27 structs for a pixel list. * * Note that it is considered legitimate for a column to contain an image * array and also form part of a pixel list, and in particular that * wcsbth() does not check the TFORM keyword for a pixel list column to * check that it is scalar. * * In practice, of course, a realistic binary table header is unlikely to * contain more than a handful of images. * * In order for wcsbth() to create a wcsprm struct for a particular * coordinate representation, at least one WCS keyword that defines an * axis number must be present, either directly or by inheritance if * WCSHDR_ALLIMG is set. * * When the image header keywords for an alternate representation are * inherited by a binary table image array via WCSHDR_ALLIMG, those * keywords are considered to be "exhausted" and do not result in a * separate wcsprm struct. Otherwise they do. * * 7: Neither wcspih() nor wcsbth() check for duplicated keywords, in most * cases they accept the last encountered. * * 8: wcspih() and wcsbth() use wcsnpv() and wcsnps() (refer to the prologue * of wcs.h) to match the size of the pv[] and ps[] arrays in the wcsprm * structs to the number in the header. Consequently there are no unused * elements in the pv[] and ps[] arrays, indeed they will often be of * zero length. * * 9: The FITS WCS standard for pixel lists assumes that a pixel list * defines one and only one image, i.e. that each row of the binary table * refers to just one event, e.g. the detection of a single photon or * neutrino, for which the device "pixel" coordinates are stored in * separate scalar columns of the table. * * In the absence of a standard for pixel lists - or even an informal * description! - let alone a formal mechanism for identifying the columns * containing pixel coordinates (as opposed to pixel values or metadata * recorded at the time the photon or neutrino was detected), WCS Paper I * discusses how the WCS keywords themselves may be used to identify them. * * In practice, however, pixel lists have been used to store multiple * images. Besides not specifying how to identify columns, the pixel list * convention is also silent on the method to be used to associate table * columns with image axes. * * An additional shortcoming is the absence of a formal method for * associating global binary-table WCS keywords, such as WCSNna or MJDOBn, * with a pixel list image, whether one or several. * * In light of these uncertainties, wcsbth() simply collects all WCS * keywords for a particular pixel list coordinate representation (i.e. * the "a" value in TCTYna) into one wcsprm struct. However, these * alternates need not be associated with the same table columns and this * allows a pixel list to contain up to 27 separate images. As usual, if * one of these representations happened to contain more than two * celestial axes, for example, then an error would result when wcsset() * is invoked on it. In this case the "colsel" argument could be used to * restrict the columns used to construct the representation so that it * only contained one pair of celestial axes. * * Global, binary-table WCS keywords are considered to apply to the pixel * list image with matching alternate (e.g. the "a" value in LONPna or * EQUIna), regardless of the table columns the image occupies. In other * words, the column number is ignored (the "n" value in LONPna or * EQUIna). This also applies for global, binary-table WCS keywords that * have no alternates, such as MJDOBn and OBSGXn, which match all images * in a pixel list. Take heed that this may lead to counterintuitive * behaviour, especially where such a keyword references a column that * does not store pixel coordinates, and moreso where the pixel list * stores only a single image. In fact, as the column number, n, is * ignored for such keywords, it would make no difference even if they * referenced non-existent columns. Moreover, there is no requirement for * consistency in the column numbers used for such keywords, even for * OBSGXn, OBSGYn, and OBSGZn which are meant to define the elements of a * coordinate vector. Although it would surely be perverse to construct a * pixel list like this, such a situation may still arise in practice * where columns are deleted from a binary table. * * The situation with global, binary-table WCS keywords becomes * potentially even more confusing when image arrays and pixel list images * coexist in one binary table. In that case, a keyword such as MJDOBn * may legitimately appear multiple times with n referencing different * image arrays. Which then is the one that applies to the pixel list * images? In this implementation, it is the last instance that appears * in the header, whether or not it is also associated with an image * array. * * * wcstab() - Tabular construction routine * --------------------------------------- * wcstab() assists in filling in the information in the wcsprm struct relating * to coordinate lookup tables. * * Tabular coordinates ('TAB') present certain difficulties in that the main * components of the lookup table - the multidimensional coordinate array plus * an index vector for each dimension - are stored in a FITS binary table * extension (BINTABLE). Information required to locate these arrays is stored * in PVi_ma and PSi_ma keywords in the image header. * * wcstab() parses the PVi_ma and PSi_ma keywords associated with each 'TAB' * axis and allocates memory in the wcsprm struct for the required number of * tabprm structs. It sets as much of the tabprm struct as can be gleaned from * the image header, and also sets up an array of wtbarr structs (described in * the prologue of wtbarr.h) to assist in extracting the required arrays from * the BINTABLE extension(s). * * It is then up to the user to allocate memory for, and copy arrays from the * BINTABLE extension(s) into the tabprm structs. A CFITSIO routine, * fits_read_wcstab(), has been provided for this purpose, see getwcstab.h. * wcsset() will automatically take control of this allocated memory, in * particular causing it to be freed by wcsfree(); the user must not attempt * to free it after wcsset() has been called. * * Note that wcspih() and wcsbth() automatically invoke wcstab() on each of the * wcsprm structs that they return. * * Given and returned: * wcs struct wcsprm* * Coordinate transformation parameters (see below). * * wcstab() sets ntab, tab, nwtb and wtb, allocating * memory for the tab and wtb arrays. This allocated * memory will be freed automatically by wcsfree(). * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * 2: Memory allocation failed. * 3: Invalid tabular parameters. * * For returns > 1, a detailed error message is set in * wcsprm::err if enabled, see wcserr_enable(). * * * wcsidx() - Index alternate coordinate representations * ----------------------------------------------------- * wcsidx() returns an array of 27 indices for the alternate coordinate * representations in the array of wcsprm structs returned by wcspih(). For * the array returned by wcsbth() it returns indices for the unattached * (colnum == 0) representations derived from image header keywords - use * wcsbdx() for those derived from binary table image arrays or pixel lists * keywords. * * Given: * nwcs int Number of coordinate representations in the array. * * wcs const struct wcsprm** * Pointer to an array of wcsprm structs returned by * wcspih() or wcsbth(). * * Returned: * alts int[27] Index of each alternate coordinate representation in * the array: alts[0] for the primary, alts[1] for 'A', * etc., set to -1 if not present. * * For example, if there was no 'P' representation then * = alts['P'-'A'+1] == -1; * * Otherwise, the address of its wcsprm struct would be * = wcs + alts['P'-'A'+1]; * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * * * wcsbdx() - Index alternate coordinate representions * --------------------------------------------------- * wcsbdx() returns an array of 999 x 27 indices for the alternate coordinate * representions for binary table image arrays xor pixel lists in the array of * wcsprm structs returned by wcsbth(). Use wcsidx() for the unattached * representations derived from image header keywords. * * Given: * nwcs int Number of coordinate representations in the array. * * wcs const struct wcsprm** * Pointer to an array of wcsprm structs returned by * wcsbth(). * * type int Select the type of coordinate representation: * 0: binary table image arrays, * 1: pixel lists. * * Returned: * alts short[1000][28] * Index of each alternate coordinate represention in the * array: alts[col][0] for the primary, alts[col][1] for * 'A', to alts[col][26] for 'Z', where col is the * 1-relative column number, and col == 0 is used for * unattached image headers. Set to -1 if not present. * * alts[col][27] counts the number of coordinate * representations of the chosen type for each column. * * For example, if there was no 'P' represention for * column 13 then * = alts[13]['P'-'A'+1] == -1; * * Otherwise, the address of its wcsprm struct would be * = wcs + alts[13]['P'-'A'+1]; * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * * * wcsvfree() - Free the array of wcsprm structs * --------------------------------------------- * wcsvfree() frees the memory allocated by wcspih() or wcsbth() for the array * of wcsprm structs, first invoking wcsfree() on each of the array members. * * Given and returned: * nwcs int* Number of coordinate representations found; set to 0 * on return. * * wcs struct wcsprm** * Pointer to the array of wcsprm structs; set to 0x0 on * return. * * Function return value: * int Status return value: * 0: Success. * 1: Null wcsprm pointer passed. * * * wcshdo() - Write out a wcsprm struct as a FITS header * ----------------------------------------------------- * wcshdo() translates a wcsprm struct into a FITS header. If the colnum * member of the struct is non-zero then a binary table image array header will * be produced. Otherwise, if the colax[] member of the struct is set non-zero * then a pixel list header will be produced. Otherwise, a primary image or * image extension header will be produced. * * If the struct was originally constructed from a header, e.g. by wcspih(), * the output header will almost certainly differ in a number of respects: * * - The output header only contains WCS-related keywords. In particular, it * does not contain syntactically-required keywords such as SIMPLE, NAXIS, * BITPIX, or END. * * - Elements of the PCi_ja matrix will be written if and only if they differ * from the unit matrix. Thus, if the matrix is unity then no elements * will be written. * * - The redundant keywords MJDREF, JDREF, JDREFI, JDREFF, all of which * duplicate MJDREFI + MJDREFF, are never written. OBSGEO-[LBH] are not * written if OBSGEO-[XYZ] are defined. * * - Deprecated (e.g. CROTAn, RESTFREQ, VELREF, RADECSYS, EPOCH, VSOURCEa) or * non-standard usage will be translated to standard (this is partially * dependent on whether wcsfix() was applied). * * - Additional keywords such as WCSAXESa, CUNITia, LONPOLEa and LATPOLEa may * appear. * * - Quantities will be converted to the units used internally, basically SI * with the addition of degrees. * * - Floating-point quantities may be given to a different decimal precision. * * - The original keycomments will be lost, although wcshdo() tries hard to * write meaningful comments. * * - Keyword order will almost certainly be changed. * * Keywords can be translated between the image array, binary table, and pixel * lists forms by manipulating the colnum or colax[] members of the wcsprm * struct. * * Given: * ctrl int Vector of flag bits that controls the degree of * permissiveness in departing from the published WCS * standard, and also controls the formatting of * floating-point keyvalues. Set it to zero to get the * default behaviour. * * Flag bits for the degree of permissiveness: * WCSHDO_none: Recognize only FITS keywords defined by * the published WCS standard. * WCSHDO_all: Admit all recognized informal extensions * of the WCS standard. * Fine-grained control of the degree of permissiveness * is also possible as explained in the notes below. * * As for controlling floating-point formatting, by * default wcshdo() uses "%20.12G" for non-parameterized * keywords such as LONPOLEa, and attempts to make the * header more human-readable by using the same "%f" * format for all values of each of the following * parameterized keywords: CRPIXja, PCi_ja, and CDELTia * (n.b. excluding CRVALia). Each has the same field * width and precision so that the decimal points line * up. The precision, allowing for up to 15 significant * digits, is chosen so that there are no excess trailing * zeroes. A similar formatting scheme applies by * default for distortion function parameters. * * However, where the values of, for example, CDELTia * differ by many orders of magnitude, the default * formatting scheme may cause unacceptable loss of * precision for the lower-valued keyvalues. Thus the * default behaviour may be overridden: * WCSHDO_P12: Use "%20.12G" format for all floating- * point keyvalues (12 significant digits). * WCSHDO_P13: Use "%21.13G" format for all floating- * point keyvalues (13 significant digits). * WCSHDO_P14: Use "%22.14G" format for all floating- * point keyvalues (14 significant digits). * WCSHDO_P15: Use "%23.15G" format for all floating- * point keyvalues (15 significant digits). * WCSHDO_P16: Use "%24.16G" format for all floating- * point keyvalues (16 significant digits). * WCSHDO_P17: Use "%25.17G" format for all floating- * point keyvalues (17 significant digits). * If more than one of the above flags are set, the * highest number of significant digits prevails. In * addition, there is an anciliary flag: * WCSHDO_EFMT: Use "%E" format instead of the default * "%G" format above. * Note that excess trailing zeroes are stripped off the * fractional part with "%G" (which never occurs with * "%E"). Note also that the higher-precision options * eat into the keycomment area. In this regard, * WCSHDO_P14 causes minimal disruption with "%G" format, * while WCSHDO_P13 is appropriate with "%E". * * Given and returned: * wcs struct wcsprm* * Pointer to a wcsprm struct containing coordinate * transformation parameters. Will be initialized if * necessary. * * Returned: * nkeyrec int* Number of FITS header keyrecords returned in the * "header" array. * * header char** Pointer to an array of char holding the header. * Storage for the array is allocated by wcshdo() in * blocks of 2880 bytes (32 x 80-character keyrecords) * and must be freed by the user to avoid memory leaks. * See wcsdealloc(). * * Each keyrecord is 80 characters long and is *NOT* * null-terminated, so the first keyrecord starts at * (*header)[0], the second at (*header)[80], etc. * * Function return value: * int Status return value (associated with wcs_errmsg[]): * 0: Success. * 1: Null wcsprm pointer passed. * 2: Memory allocation failed. * 3: Linear transformation matrix is singular. * 4: Inconsistent or unrecognized coordinate axis * types. * 5: Invalid parameter value. * 6: Invalid coordinate transformation parameters. * 7: Ill-conditioned coordinate transformation * parameters. * * For returns > 1, a detailed error message is set in * wcsprm::err if enabled, see wcserr_enable(). * * Notes: * 1: wcshdo() interprets the "relax" argument as a vector of flag bits to * provide fine-grained control over what non-standard WCS keywords to * write. The flag bits are subject to change in future and should be set * by using the preprocessor macros (see below) for the purpose. * * - WCSHDO_none: Don't use any extensions. * * - WCSHDO_all: Write all recognized extensions, equivalent to setting * each flag bit. * * - WCSHDO_safe: Write all extensions that are considered to be safe and * recommended. * * - WCSHDO_DOBSn: Write DOBSn, the column-specific analogue of DATE-OBS * for use in binary tables and pixel lists. WCS Paper III * introduced DATE-AVG and DAVGn but by an oversight DOBSn (the * obvious analogy) was never formally defined by the standard. * The alternative to using DOBSn is to write DATE-OBS which * applies to the whole table. This usage is considered to be * safe and is recommended. * * - WCSHDO_TPCn_ka: WCS Paper I defined * * - TPn_ka and TCn_ka for pixel lists * * but WCS Paper II uses TPCn_ka in one example and subsequently * the errata for the WCS papers legitimized the use of * * - TPCn_ka and TCDn_ka for pixel lists * * provided that the keyword does not exceed eight characters. * This usage is considered to be safe and is recommended because * of the non-mnemonic terseness of the shorter forms. * * - WCSHDO_PVn_ma: WCS Paper I defined * * - iVn_ma and iSn_ma for bintables and * - TVn_ma and TSn_ma for pixel lists * * but WCS Paper II uses iPVn_ma and TPVn_ma in the examples and * subsequently the errata for the WCS papers legitimized the use * of * * - iPVn_ma and iPSn_ma for bintables and * - TPVn_ma and TPSn_ma for pixel lists * * provided that the keyword does not exceed eight characters. * This usage is considered to be safe and is recommended because * of the non-mnemonic terseness of the shorter forms. * * - WCSHDO_CRPXna: For historical reasons WCS Paper I defined * * - jCRPXn, iCDLTn, iCUNIn, iCTYPn, and iCRVLn for bintables and * - TCRPXn, TCDLTn, TCUNIn, TCTYPn, and TCRVLn for pixel lists * * for use without an alternate version specifier. However, * because of the eight-character keyword constraint, in order to * accommodate column numbers greater than 99 WCS Paper I also * defined * * - jCRPna, iCDEna, iCUNna, iCTYna and iCRVna for bintables and * - TCRPna, TCDEna, TCUNna, TCTYna and TCRVna for pixel lists * * for use with an alternate version specifier (the "a"). Like * the PC, CD, PV, and PS keywords there is an obvious tendency to * confuse these two forms for column numbers up to 99. It is * very unlikely that any parser would reject keywords in the * first set with a non-blank alternate version specifier so this * usage is considered to be safe and is recommended. * * - WCSHDO_CNAMna: WCS Papers I and III defined * * - iCNAna, iCRDna, and iCSYna for bintables and * - TCNAna, TCRDna, and TCSYna for pixel lists * * By analogy with the above, the long forms would be * * - iCNAMna, iCRDEna, and iCSYEna for bintables and * - TCNAMna, TCRDEna, and TCSYEna for pixel lists * * Note that these keywords provide auxiliary information only, * none of them are needed to compute world coordinates. This * usage is potentially unsafe and is not recommended at this * time. * * - WCSHDO_WCSNna: In light of wcsbth() note 4, write WCSNna instead of * TWCSna for pixel lists. While wcsbth() treats WCSNna and * TWCSna as equivalent, other parsers may not. Consequently, * this usage is potentially unsafe and is not recommended at this * time. * * * Global variable: const char *wcshdr_errmsg[] - Status return messages * --------------------------------------------------------------------- * Error messages to match the status value returned from each function. * Use wcs_errmsg[] for status returns from wcshdo(). * *===========================================================================*/ #ifndef WCSLIB_WCSHDR #define WCSLIB_WCSHDR #include "wcs.h" #ifdef __cplusplus extern "C" { #endif #define WCSHDR_none 0x00000000 #define WCSHDR_all 0x000FFFFF #define WCSHDR_reject 0x10000000 #define WCSHDR_strict 0x20000000 #define WCSHDR_CROTAia 0x00000001 #define WCSHDR_VELREFa 0x00000002 #define WCSHDR_CD00i00j 0x00000004 #define WCSHDR_PC00i00j 0x00000008 #define WCSHDR_PROJPn 0x00000010 #define WCSHDR_CD0i_0ja 0x00000020 #define WCSHDR_PC0i_0ja 0x00000040 #define WCSHDR_PV0i_0ma 0x00000080 #define WCSHDR_PS0i_0ma 0x00000100 #define WCSHDR_DOBSn 0x00000200 #define WCSHDR_OBSGLBHn 0x00000400 #define WCSHDR_RADECSYS 0x00000800 #define WCSHDR_EPOCHa 0x00001000 #define WCSHDR_VSOURCE 0x00002000 #define WCSHDR_DATEREF 0x00004000 #define WCSHDR_LONGKEY 0x00008000 #define WCSHDR_CNAMn 0x00010000 #define WCSHDR_AUXIMG 0x00020000 #define WCSHDR_ALLIMG 0x00040000 #define WCSHDR_IMGHEAD 0x00100000 #define WCSHDR_BIMGARR 0x00200000 #define WCSHDR_PIXLIST 0x00400000 #define WCSHDO_none 0x00000 #define WCSHDO_all 0x000FF #define WCSHDO_safe 0x0000F #define WCSHDO_DOBSn 0x00001 #define WCSHDO_TPCn_ka 0x00002 #define WCSHDO_PVn_ma 0x00004 #define WCSHDO_CRPXna 0x00008 #define WCSHDO_CNAMna 0x00010 #define WCSHDO_WCSNna 0x00020 #define WCSHDO_P12 0x01000 #define WCSHDO_P13 0x02000 #define WCSHDO_P14 0x04000 #define WCSHDO_P15 0x08000 #define WCSHDO_P16 0x10000 #define WCSHDO_P17 0x20000 #define WCSHDO_EFMT 0x40000 extern const char *wcshdr_errmsg[]; enum wcshdr_errmsg_enum { WCSHDRERR_SUCCESS = 0, // Success. WCSHDRERR_NULL_POINTER = 1, // Null wcsprm pointer passed. WCSHDRERR_MEMORY = 2, // Memory allocation failed. WCSHDRERR_BAD_COLUMN = 3, // Invalid column selection. WCSHDRERR_PARSER = 4, // Fatal error returned by Flex // parser. WCSHDRERR_BAD_TABULAR_PARAMS = 5 // Invalid tabular parameters. }; int wcspih(char *header, int nkeyrec, int relax, int ctrl, int *nreject, int *nwcs, struct wcsprm **wcs); int wcsbth(char *header, int nkeyrec, int relax, int ctrl, int keysel, int *colsel, int *nreject, int *nwcs, struct wcsprm **wcs); int wcstab(struct wcsprm *wcs); int wcsidx(int nwcs, struct wcsprm **wcs, int alts[27]); int wcsbdx(int nwcs, struct wcsprm **wcs, int type, short alts[1000][28]); int wcsvfree(int *nwcs, struct wcsprm **wcs); int wcshdo(int ctrl, struct wcsprm *wcs, int *nkeyrec, char **header); #ifdef __cplusplus } #endif #endif // WCSLIB_WCSHDR ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/wcslib.h0000644000175100001710000000366200000000000017025 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcslib.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * Summary of wcslib.h * ------------------- * This header file is provided purely for convenience. Use it to include all * of the separate WCSLIB headers. * *===========================================================================*/ #ifndef WCSLIB_WCSLIB #define WCSLIB_WCSLIB #include "cel.h" #include "dis.h" #include "fitshdr.h" #include "lin.h" #include "log.h" #include "prj.h" #include "spc.h" #include "sph.h" #include "spx.h" #include "tab.h" #include "wcs.h" #include "wcserr.h" #include "wcsfix.h" #include "wcshdr.h" #include "wcsmath.h" #include "wcsprintf.h" #include "wcstrig.h" #include "wcsunits.h" #include "wcsutil.h" #include "wtbarr.h" #endif // WCSLIB_WCSLIB ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/wcsmath.h0000644000175100001710000000366100000000000017207 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcsmath.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of wcsmath.h * -------------------- * Definition of mathematical constants used by WCSLIB. * *===========================================================================*/ #ifndef WCSLIB_WCSMATH #define WCSLIB_WCSMATH #ifdef PI #undef PI #endif #ifdef D2R #undef D2R #endif #ifdef R2D #undef R2D #endif #ifdef SQRT2 #undef SQRT2 #endif #ifdef SQRT2INV #undef SQRT2INV #endif #define PI 3.141592653589793238462643 #define D2R PI/180.0 #define R2D 180.0/PI #define SQRT2 1.4142135623730950488 #define SQRT2INV 1.0/SQRT2 #ifdef UNDEFINED #undef UNDEFINED #endif #define UNDEFINED 987654321.0e99 #define undefined(value) (value == UNDEFINED) #endif // WCSLIB_WCSMATH ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/wcspih.l0000644000175100001710000017512000000000000017042 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcspih.l,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * wcspih.l is a Flex description file containing the definition of a lexical * scanner for parsing the WCS keyrecords from a FITS primary image or image * extension header. * * wcspih.l requires Flex v2.5.4 or later. Refer to wcshdr.h for a description * of the user interface and operating notes. * * Implementation notes * -------------------- * Use of the WCSAXESa keyword is not mandatory. Its default value is "the * larger of NAXIS and the largest index of these keywords [i.e. CRPIXj, PCi_j * or CDi_j, CDELTi, CTYPEi, CRVALi, and CUNITi] found in the FITS header". * Consequently the definition of WCSAXESa effectively invalidates the use of * NAXIS for determining the number of coordinate axes and forces a preliminary * pass through the header to determine the "largest index" in headers where * WCSAXESa was omitted. * * Furthermore, since the use of WCSAXESa is optional, there is no way to * determine the number of coordinate representations (the "a" value) other * than by parsing all of the WCS keywords in the header; even if WCSAXESa was * specified for some representations it cannot be known in advance whether it * was specified for all of those present in the header. * * Hence the definition of WCSAXESa forces the scanner to be implemented in two * passes. The first pass is used to determine the number of coordinate * representations (up to 27) and the number of coordinate axes in each. * Effectively WCSAXESa is ignored unless it exceeds the "largest index" in * which case the keywords for the extra axes assume their default values. The * number of PVi_ma and PSi_ma keywords in each representation is also counted * in the first pass. * * On completion of the first pass, memory is allocated for an array of the * required number of wcsprm structs and each of these is initialized * appropriately. These structs are filled in the second pass. * * The parser does not check for duplicated keywords, it accepts the last * encountered. * *===========================================================================*/ /* Options. */ %option full %option never-interactive %option noinput %option noyywrap %option outfile="wcspih.c" %option prefix="wcspih" %option reentrant %option extra-type="struct wcspih_extra *" /* Indices for parameterized keywords. */ Z1 [0-9] Z2 [0-9]{2} Z3 [0-9]{3} Z4 [0-9]{4} Z5 [0-9]{5} Z6 [0-9]{6} I1 [1-9] I2 [1-9][0-9] I3 [1-9][0-9]{2} I4 [1-9][0-9]{3} /* Alternate coordinate system identifier. */ ALT [ A-Z] /* Keyvalue data types. */ INTEGER [+-]?[0-9]+ FLOAT [+-]?([0-9]+\.?[0-9]*|\.[0-9]+)([eEdD][+-]?[0-9]+)? STRING '([^']|'')*' RECORD '[^']*' FIELD [a-zA-Z_][a-zA-Z_0-9.]* /* Inline comment syntax. */ INLINE " "*(\/.*)? /* Exclusive start states. */ %x CCia CCi_ja CCCCCia CCi_ma CCCCCCCa CCCCCCCC %x CROTAi PROJPn SIP2 SIP3 DSSAMDXY PLTDECSN %x VALUE INTEGER_VAL FLOAT_VAL FLOAT2_VAL STRING_VAL %x RECORD_VAL RECFIELD RECCOLON RECVALUE RECEND %x COMMENT %x DISCARD ERROR FLUSH %{ #include #include #include #include #include #include #include "wcsmath.h" #include "wcsprintf.h" #include "wcsutil.h" #include "dis.h" #include "wcs.h" #include "wcshdr.h" #define INTEGER 0 #define FLOAT 1 #define FLOAT2 2 #define STRING 3 #define RECORD 4 #define PRIOR 1 #define SEQUENT 2 #define SIP 1 #define DSS 2 #define WAT 3 // User data associated with yyscanner. struct wcspih_extra { // Values passed to YY_INPUT. char *hdr; int nkeyrec; // Used in preempting the call to exit() by yy_fatal_error(). jmp_buf abort_jmp_env; }; #define YY_DECL int wcspih_scanner(char *header, int nkeyrec, int relax, \ int ctrl, int *nreject, int *nwcs, struct wcsprm **wcs, yyscan_t yyscanner) #define YY_INPUT(inbuff, count, bufsize) \ { \ if (yyextra->nkeyrec) { \ strncpy(inbuff, yyextra->hdr, 80); \ inbuff[80] = '\n'; \ yyextra->hdr += 80; \ yyextra->nkeyrec--; \ count = 81; \ } else { \ count = YY_NULL; \ } \ } // Preempt the call to exit() by yy_fatal_error(). #define exit(status) longjmp(yyextra->abort_jmp_env, status); // Internal helper functions. static YY_DECL; static int wcspih_final(int ndp[], int ndq[], int distran, double dsstmp[], char *wat[], int *nwcs, struct wcsprm **wcs); static int wcspih_init1(int naxis, int alts[], int dpq[], int npv[], int nps[], int ndp[], int ndq[], int auxprm, int distran, int *nwcs, struct wcsprm **wcs); static void wcspih_pass1(int naxis, int i, int j, char a, int distype, int alts[], int dpq[], int *npptr); static int wcspih_jdref(double *wptr, const double *jdref); static int wcspih_jdrefi(double *wptr, const double *jdrefi); static int wcspih_jdreff(double *wptr, const double *jdreff); static int wcspih_epoch(double *wptr, const double *epoch); static int wcspih_vsource(double *wptr, const double *vsource); static int wcspih_timepixr(double timepixr); %} %% int p, q; char *errmsg, errtxt[80], *keyname, strtmp[80], *wat[2], *watstr; int alts[27], dpq[27], inttmp, ndp[27], ndq[27], nps[27], npv[27], rectype; double dbltmp, dbl2tmp[2], dsstmp[20]; struct auxprm auxtem; struct disprm distem; struct wcsprm wcstem; int naxis = 0; for (int ialt = 0; ialt < 27; ialt++) { alts[ialt] = 0; dpq[ialt] = 0; npv[ialt] = 0; nps[ialt] = 0; ndp[ialt] = 0; ndq[ialt] = 0; } // Our handle on the input stream. char *keyrec = header; char *hptr = header; char *keep = 0x0; // For keeping tallies of keywords found. *nreject = 0; int nvalid = 0; int nother = 0; // If strict, then also reject. if (relax & WCSHDR_strict) relax |= WCSHDR_reject; // Keyword indices, as used in the WCS papers, e.g. PCi_ja, PVi_ma. int i = 0; int j = 0; int m = 0; char a = ' '; // For decoding the keyvalue. int valtype = -1; int distype = 0; void *vptr = 0x0; // For keywords that require special handling. int altlin = 0; int *npptr = 0x0; int (*chekval)(double) = 0x0; int (*special)(double *, const double *) = 0x0; int auxprm = 0; int naux = 0; int distran = 0; int sipflag = 0; int dssflag = 0; int watflag = 0; int watn = 0; // The data structures produced. *nwcs = 0; *wcs = 0x0; // Control variables. int ipass = 1; int npass = 2; // User data associated with yyscanner. yyextra->hdr = header; yyextra->nkeyrec = nkeyrec; // Return here via longjmp() invoked by yy_fatal_error(). if (setjmp(yyextra->abort_jmp_env)) { return WCSHDRERR_PARSER; } BEGIN(INITIAL); ^NAXIS" = "" "*{INTEGER}{INLINE} { keyname = "NAXISn"; if (ipass == 1) { sscanf(yytext, "NAXIS = %d", &naxis); if (naxis < 0) naxis = 0; BEGIN(FLUSH); } else { sscanf(yytext, "NAXIS = %d", &i); if (i < 0) { errmsg = "negative value of NAXIS ignored"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } } ^WCSAXES{ALT}=" "" "*{INTEGER} { sscanf(yytext, "WCSAXES%c= %d", &a, &i); if (i < 0) { errmsg = "negative value of WCSAXESa ignored"; BEGIN(ERROR); } else { valtype = INTEGER; vptr = 0x0; keyname = "WCSAXESa"; BEGIN(COMMENT); } } ^CRPIX { valtype = FLOAT; vptr = &(wcstem.crpix); keyname = "CRPIXja"; BEGIN(CCCCCia); } ^PC { valtype = FLOAT; vptr = &(wcstem.pc); altlin = 1; keyname = "PCi_ja"; BEGIN(CCi_ja); } ^CD { valtype = FLOAT; vptr = &(wcstem.cd); altlin = 2; keyname = "CDi_ja"; BEGIN(CCi_ja); } ^CDELT { valtype = FLOAT; vptr = &(wcstem.cdelt); keyname = "CDELTia"; BEGIN(CCCCCia); } ^CROTA { valtype = FLOAT; vptr = &(wcstem.crota); altlin = 4; keyname = "CROTAn"; BEGIN(CROTAi); } ^CUNIT { valtype = STRING; vptr = &(wcstem.cunit); keyname = "CUNITia"; BEGIN(CCCCCia); } ^CTYPE { valtype = STRING; vptr = &(wcstem.ctype); keyname = "CTYPEia"; BEGIN(CCCCCia); } ^CRVAL { valtype = FLOAT; vptr = &(wcstem.crval); keyname = "CRVALia"; BEGIN(CCCCCia); } ^LONPOLE { valtype = FLOAT; vptr = &(wcstem.lonpole); keyname = "LONPOLEa"; BEGIN(CCCCCCCa); } ^LATPOLE { valtype = FLOAT; vptr = &(wcstem.latpole); keyname = "LATPOLEa"; BEGIN(CCCCCCCa); } ^RESTFRQ { valtype = FLOAT; vptr = &(wcstem.restfrq); keyname = "RESTFRQa"; BEGIN(CCCCCCCa); } ^RESTFREQ { if (relax & WCSHDR_strict) { errmsg = "the RESTFREQ keyword is deprecated, use RESTFRQa"; BEGIN(ERROR); } else { valtype = FLOAT; vptr = &(wcstem.restfrq); unput(' '); keyname = "RESTFREQ"; BEGIN(CCCCCCCa); } } ^RESTWAV { valtype = FLOAT; vptr = &(wcstem.restwav); keyname = "RESTWAVa"; BEGIN(CCCCCCCa); } ^PV { valtype = FLOAT; vptr = &(wcstem.pv); npptr = npv; keyname = "PVi_ma"; BEGIN(CCi_ma); } ^PROJP { valtype = FLOAT; vptr = &(wcstem.pv); npptr = npv; keyname = "PROJPn"; BEGIN(PROJPn); } ^PS { valtype = STRING; vptr = &(wcstem.ps); npptr = nps; keyname = "PSi_ma"; BEGIN(CCi_ma); } ^VELREF{ALT}" " { sscanf(yytext, "VELREF%c", &a); if (relax & WCSHDR_strict) { errmsg = "the VELREF keyword is deprecated, use SPECSYSa"; BEGIN(ERROR); } else if ((a == ' ') || (relax & WCSHDR_VELREFa)) { valtype = INTEGER; vptr = &(wcstem.velref); unput(a); keyname = "VELREF"; BEGIN(CCCCCCCa); } else if (relax & WCSHDR_reject) { errmsg = "VELREF keyword may not have an alternate version code"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^CNAME { valtype = STRING; vptr = &(wcstem.cname); keyname = "CNAMEia"; BEGIN(CCCCCia); } ^CRDER { valtype = FLOAT; vptr = &(wcstem.crder); keyname = "CRDERia"; BEGIN(CCCCCia); } ^CSYER { valtype = FLOAT; vptr = &(wcstem.csyer); keyname = "CSYERia"; BEGIN(CCCCCia); } ^CZPHS { valtype = FLOAT; vptr = &(wcstem.czphs); keyname = "CZPHSia"; BEGIN(CCCCCia); } ^CPERI { valtype = FLOAT; vptr = &(wcstem.cperi); keyname = "CPERIia"; BEGIN(CCCCCia); } ^WCSNAME { valtype = STRING; vptr = wcstem.wcsname; keyname = "WCSNAMEa"; BEGIN(CCCCCCCa); } ^TIMESYS" " { valtype = STRING; vptr = wcstem.timesys; keyname = "TIMESYS"; BEGIN(CCCCCCCC); } ^TREFPOS" " { valtype = STRING; vptr = wcstem.trefpos; keyname = "TREFPOS"; BEGIN(CCCCCCCC); } ^TREFDIR" " { valtype = STRING; vptr = wcstem.trefdir; keyname = "TREFDIR"; BEGIN(CCCCCCCC); } ^PLEPHEM" " { valtype = STRING; vptr = wcstem.plephem; keyname = "PLEPHEM"; BEGIN(CCCCCCCC); } ^TIMEUNIT { valtype = STRING; vptr = wcstem.timeunit; keyname = "TIMEUNIT"; BEGIN(CCCCCCCC); } ^DATEREF" " | ^DATE-REF { if ((yytext[4] == 'R') || (relax & WCSHDR_DATEREF)) { valtype = STRING; vptr = wcstem.dateref; keyname = "DATEREF"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the DATE-REF keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^MJDREF" " | ^MJD-REF" " { if ((yytext[3] == 'R') || (relax & WCSHDR_DATEREF)) { valtype = FLOAT2; vptr = wcstem.mjdref; keyname = "MJDREF"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the MJD-REF keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^MJDREFI" " | ^MJD-REFI { if ((yytext[3] == 'R') || (relax & WCSHDR_DATEREF)) { // Actually integer, but treated as float. valtype = FLOAT; vptr = wcstem.mjdref; keyname = "MJDREFI"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the MJD-REFI keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^MJDREFF" " | ^MJD-REFF { if ((yytext[3] == 'R') || (relax & WCSHDR_DATEREF)) { valtype = FLOAT; vptr = wcstem.mjdref + 1; keyname = "MJDREFF"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the MJD-REFF keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^JDREF" " | ^JD-REF" " { if ((yytext[2] == 'R') || (relax & WCSHDR_DATEREF)) { valtype = FLOAT2; vptr = wcstem.mjdref; special = wcspih_jdref; keyname = "JDREF"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the JD-REF keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^JDREFI" " | ^JD-REFI { if ((yytext[2] == 'R') || (relax & WCSHDR_DATEREF)) { // Actually integer, but treated as float. valtype = FLOAT; vptr = wcstem.mjdref; special = wcspih_jdrefi; keyname = "JDREFI"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the JD-REFI keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^JDREFF" " | ^JD-REFF { if ((yytext[2] == 'R') || (relax & WCSHDR_DATEREF)) { valtype = FLOAT; vptr = wcstem.mjdref; special = wcspih_jdreff; keyname = "JDREFF"; BEGIN(CCCCCCCC); } else if (relax & WCSHDR_reject) { errmsg = "the JD-REFF keyword is non-standard"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^TIMEOFFS { valtype = FLOAT; vptr = &(wcstem.timeoffs); keyname = "TIMEOFFS"; BEGIN(CCCCCCCC); } ^DATE-OBS { valtype = STRING; vptr = wcstem.dateobs; if (ctrl < -10) keep = keyrec; keyname = "DATE-OBS"; BEGIN(CCCCCCCC); } ^DATE-BEG { valtype = STRING; vptr = wcstem.datebeg; if (ctrl < -10) keep = keyrec; keyname = "DATE-BEG"; BEGIN(CCCCCCCC); } ^DATE-AVG { valtype = STRING; vptr = wcstem.dateavg; if (ctrl < -10) keep = keyrec; keyname = "DATE-AVG"; BEGIN(CCCCCCCC); } ^DATE-END { valtype = STRING; vptr = wcstem.dateend; if (ctrl < -10) keep = keyrec; keyname = "DATE-END"; BEGIN(CCCCCCCC); } ^MJD-OBS" " { valtype = FLOAT; vptr = &(wcstem.mjdobs); if (ctrl < -10) keep = keyrec; keyname = "MJD-OBS"; BEGIN(CCCCCCCC); } ^MJD-BEG" " { valtype = FLOAT; vptr = &(wcstem.mjdbeg); if (ctrl < -10) keep = keyrec; keyname = "MJD-BEG"; BEGIN(CCCCCCCC); } ^MJD-AVG" " { valtype = FLOAT; vptr = &(wcstem.mjdavg); if (ctrl < -10) keep = keyrec; keyname = "MJD-AVG"; BEGIN(CCCCCCCC); } ^MJD-END" " { valtype = FLOAT; vptr = &(wcstem.mjdend); if (ctrl < -10) keep = keyrec; keyname = "MJD-END"; BEGIN(CCCCCCCC); } ^JEPOCH" " { valtype = FLOAT; vptr = &(wcstem.jepoch); if (ctrl < -10) keep = keyrec; keyname = "JEPOCH"; BEGIN(CCCCCCCC); } ^BEPOCH" " { valtype = FLOAT; vptr = &(wcstem.bepoch); if (ctrl < -10) keep = keyrec; keyname = "BEPOCH"; BEGIN(CCCCCCCC); } ^TSTART" " { valtype = FLOAT; vptr = &(wcstem.tstart); if (ctrl < -10) keep = keyrec; keyname = "TSTART"; BEGIN(CCCCCCCC); } ^TSTOP" " { valtype = FLOAT; vptr = &(wcstem.tstop); if (ctrl < -10) keep = keyrec; keyname = "TSTOP"; BEGIN(CCCCCCCC); } ^XPOSURE" " { valtype = FLOAT; vptr = &(wcstem.xposure); if (ctrl < -10) keep = keyrec; keyname = "XPOSURE"; BEGIN(CCCCCCCC); } ^TELAPSE" " { valtype = FLOAT; vptr = &(wcstem.telapse); if (ctrl < -10) keep = keyrec; keyname = "TELAPSE"; BEGIN(CCCCCCCC); } ^TIMSYER" " { valtype = FLOAT; vptr = &(wcstem.timsyer); if (ctrl < -10) keep = keyrec; keyname = "TIMSYER"; BEGIN(CCCCCCCC); } ^TIMRDER" " { valtype = FLOAT; vptr = &(wcstem.timrder); if (ctrl < -10) keep = keyrec; keyname = "TIMRDER"; BEGIN(CCCCCCCC); } ^TIMEDEL" " { valtype = FLOAT; vptr = &(wcstem.timedel); if (ctrl < -10) keep = keyrec; keyname = "TIMEDEL"; BEGIN(CCCCCCCC); } ^TIMEPIXR { valtype = FLOAT; vptr = &(wcstem.timepixr); chekval = wcspih_timepixr; if (ctrl < -10) keep = keyrec; keyname = "TIMEPIXR"; BEGIN(CCCCCCCC); } ^OBSGEO-X { valtype = FLOAT; vptr = wcstem.obsgeo; if (ctrl < -10) keep = keyrec; keyname = "OBSGEO-X"; BEGIN(CCCCCCCC); } ^OBSGEO-Y { valtype = FLOAT; vptr = wcstem.obsgeo + 1; if (ctrl < -10) keep = keyrec; keyname = "OBSGEO-Y"; BEGIN(CCCCCCCC); } ^OBSGEO-Z { valtype = FLOAT; vptr = wcstem.obsgeo + 2; if (ctrl < -10) keep = keyrec; keyname = "OBSGEO-Z"; BEGIN(CCCCCCCC); } ^OBSGEO-L { valtype = FLOAT; vptr = wcstem.obsgeo + 3; if (ctrl < -10) keep = keyrec; keyname = "OBSGEO-L"; BEGIN(CCCCCCCC); } ^OBSGEO-B { valtype = FLOAT; vptr = wcstem.obsgeo + 4; if (ctrl < -10) keep = keyrec; keyname = "OBSGEO-B"; BEGIN(CCCCCCCC); } ^OBSGEO-H { valtype = FLOAT; vptr = wcstem.obsgeo + 5; if (ctrl < -10) keep = keyrec; keyname = "OBSGEO-H"; BEGIN(CCCCCCCC); } ^OBSORBIT { valtype = STRING; vptr = wcstem.obsorbit; keyname = "OBSORBIT"; BEGIN(CCCCCCCC); } ^RADESYS { valtype = STRING; vptr = wcstem.radesys; keyname = "RADESYSa"; BEGIN(CCCCCCCa); } ^RADECSYS { if (relax & WCSHDR_RADECSYS) { valtype = STRING; vptr = wcstem.radesys; unput(' '); keyname = "RADECSYS"; BEGIN(CCCCCCCa); } else if (relax & WCSHDR_reject) { errmsg = "the RADECSYS keyword is deprecated, use RADESYSa"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^EPOCH{ALT}" " { sscanf(yytext, "EPOCH%c", &a); if (relax & WCSHDR_strict) { errmsg = "the EPOCH keyword is deprecated, use EQUINOXa"; BEGIN(ERROR); } else if (a == ' ' || relax & WCSHDR_EPOCHa) { valtype = FLOAT; vptr = &(wcstem.equinox); special = wcspih_epoch; unput(a); keyname = "EPOCH"; BEGIN(CCCCCCCa); } else if (relax & WCSHDR_reject) { errmsg = "EPOCH keyword may not have an alternate version code"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^EQUINOX { valtype = FLOAT; vptr = &(wcstem.equinox); keyname = "EQUINOXa"; BEGIN(CCCCCCCa); } ^SPECSYS { valtype = STRING; vptr = wcstem.specsys; keyname = "SPECSYSa"; BEGIN(CCCCCCCa); } ^SSYSOBS { valtype = STRING; vptr = wcstem.ssysobs; keyname = "SSYSOBSa"; BEGIN(CCCCCCCa); } ^VELOSYS { valtype = FLOAT; vptr = &(wcstem.velosys); keyname = "VELOSYSa"; BEGIN(CCCCCCCa); } ^VSOURCE{ALT} { if (relax & WCSHDR_VSOURCE) { valtype = FLOAT; vptr = &(wcstem.zsource); special = wcspih_vsource; yyless(7); keyname = "VSOURCEa"; BEGIN(CCCCCCCa); } else if (relax & WCSHDR_reject) { errmsg = "the VSOURCEa keyword is deprecated, use ZSOURCEa"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^ZSOURCE { valtype = FLOAT; vptr = &(wcstem.zsource); keyname = "ZSOURCEa"; BEGIN(CCCCCCCa); } ^SSYSSRC { valtype = STRING; vptr = wcstem.ssyssrc; keyname = "SSYSSRCa"; BEGIN(CCCCCCCa); } ^VELANGL { valtype = FLOAT; vptr = &(wcstem.velangl); keyname = "VELANGLa"; BEGIN(CCCCCCCa); } ^RSUN_REF { valtype = FLOAT; auxprm = 1; vptr = &(auxtem.rsun_ref); keyname = "RSUN_REF"; BEGIN(CCCCCCCC); } ^DSUN_OBS { valtype = FLOAT; auxprm = 1; vptr = &(auxtem.dsun_obs); keyname = "DSUN_OBS"; BEGIN(CCCCCCCC); } ^CRLN_OBS { valtype = FLOAT; auxprm = 1; vptr = &(auxtem.crln_obs); keyname = "CRLN_OBS"; BEGIN(CCCCCCCC); } ^HGLN_OBS { valtype = FLOAT; auxprm = 1; vptr = &(auxtem.hgln_obs); keyname = "HGLN_OBS"; BEGIN(CCCCCCCC); } ^CRLT_OBS | ^HGLT_OBS { valtype = FLOAT; auxprm = 1; vptr = &(auxtem.hglt_obs); keyname = "HGLT_OBS"; BEGIN(CCCCCCCC); } ^CPDIS { valtype = STRING; distype = PRIOR; vptr = &(distem.dtype); keyname = "CPDISja"; BEGIN(CCCCCia); } ^CQDIS { valtype = STRING; distype = SEQUENT; vptr = &(distem.dtype); keyname = "CQDISia"; BEGIN(CCCCCia); } ^DP { valtype = RECORD; distype = PRIOR; vptr = &(distem.dp); npptr = ndp; keyname = "DPja"; BEGIN(CCia); } ^DQ { valtype = RECORD; distype = SEQUENT; vptr = &(distem.dp); npptr = ndq; keyname = "DQia"; BEGIN(CCia); } ^CPERR { valtype = FLOAT; distype = PRIOR; vptr = &(distem.maxdis); keyname = "CPERRja"; BEGIN(CCCCCia); } ^CQERR { valtype = FLOAT; distype = SEQUENT; vptr = &(distem.maxdis); keyname = "CQERRia"; BEGIN(CCCCCia); } ^DVERR { valtype = FLOAT; distype = PRIOR; vptr = &(distem.totdis); keyname = "DVERRa"; BEGIN(CCCCCCCa); } ^A_ORDER" " { // SIP: axis 1 polynomial degree (not stored). valtype = INTEGER; distype = PRIOR; vptr = 0x0; i = 1; a = ' '; keyname = "A_ORDER"; BEGIN(VALUE); } ^B_ORDER" " { // SIP: axis 2 polynomial degree (not stored). valtype = INTEGER; distype = PRIOR; vptr = 0x0; i = 2; a = ' '; keyname = "B_ORDER"; BEGIN(VALUE); } ^AP_ORDER { // SIP: axis 1 inverse polynomial degree (not stored). valtype = INTEGER; distype = PRIOR; vptr = 0x0; i = 1; a = ' '; keyname = "AP_ORDER"; BEGIN(VALUE); } ^BP_ORDER { // SIP: axis 2 inverse polynomial degree (not stored). valtype = INTEGER; distype = PRIOR; vptr = 0x0; i = 2; a = ' '; keyname = "BP_ORDER"; BEGIN(VALUE); } ^A_DMAX" " { // SIP: axis 1 maximum distortion. valtype = FLOAT; distype = PRIOR; vptr = &(distem.maxdis); i = 1; a = ' '; keyname = "A_DMAX"; BEGIN(VALUE); } ^B_DMAX" " { // SIP: axis 2 maximum distortion. valtype = FLOAT; distype = PRIOR; vptr = &(distem.maxdis); i = 2; a = ' '; keyname = "B_DMAX"; BEGIN(VALUE); } ^A_ { // SIP: axis 1 polynomial coefficient. i = 1; sipflag = 2; keyname = "A_p_q"; BEGIN(SIP2); } ^B_ { // SIP: axis 2 polynomial coefficient. i = 2; sipflag = 2; keyname = "B_p_q"; BEGIN(SIP2); } ^AP_ { // SIP: axis 1 inverse polynomial coefficient. i = 1; sipflag = 3; keyname = "AP_p_q"; BEGIN(SIP3); } ^BP_ { // SIP: axis 2 inverse polynomial coefficient. i = 2; sipflag = 3; keyname = "BP_p_q"; BEGIN(SIP3); } ^CNPIX1" " { // DSS: LLH corner pixel coordinate 1. valtype = FLOAT; distype = SEQUENT; vptr = dsstmp; dssflag = 1; distran = DSS; keyname = "CNPIX1"; BEGIN(VALUE); } ^CNPIX2" " { // DSS: LLH corner pixel coordinate 2. valtype = FLOAT; distype = SEQUENT; vptr = dsstmp+1; dssflag = 1; distran = DSS; keyname = "CNPIX1"; BEGIN(VALUE); } ^PPO3" " { // DSS: plate centre x-coordinate in micron. valtype = FLOAT; distype = SEQUENT; vptr = dsstmp+2; dssflag = 1; distran = DSS; keyname = "PPO3"; BEGIN(VALUE); } ^PPO6" " { // DSS: plate centre y-coordinate in micron. valtype = FLOAT; distype = SEQUENT; vptr = dsstmp+3; dssflag = 1; distran = DSS; keyname = "PPO6"; BEGIN(VALUE); } ^XPIXELSZ { // DSS: pixel x-dimension in micron. valtype = FLOAT; distype = SEQUENT; vptr = dsstmp+4; dssflag = 1; distran = DSS; keyname = "XPIXELSZ"; BEGIN(VALUE); } ^YPIXELSZ { // DSS: pixel y-dimension in micron. valtype = FLOAT; distype = SEQUENT; vptr = dsstmp+5; dssflag = 1; distran = DSS; keyname = "YPIXELSZ"; BEGIN(VALUE); } ^PLTRAH" " { // DSS: plate centre, right ascension - hours. valtype = FLOAT; distype = SEQUENT; vptr = dsstmp+6; dssflag = 1; distran = DSS; keyname = "PLTRAH"; BEGIN(VALUE); } ^PLTRAM" " { // DSS: plate centre, right ascension - minutes. valtype = FLOAT; distype = SEQUENT; vptr = dsstmp+7; dssflag = 1; distran = DSS; keyname = "PLTRAM"; BEGIN(VALUE); } ^PLTRAS" " { // DSS: plate centre, right ascension - seconds. valtype = FLOAT; distype = SEQUENT; vptr = dsstmp+8; dssflag = 1; distran = DSS; keyname = "PLTRAS"; BEGIN(VALUE); } ^PLTDECSN { // DSS: plate centre, declination - sign. valtype = STRING; distype = SEQUENT; vptr = dsstmp+9; dssflag = 1; distran = DSS; keyname = "PLTDECSN"; BEGIN(PLTDECSN); } ^PLTDECD" " { // DSS: plate centre, declination - degrees. valtype = FLOAT; distype = SEQUENT; vptr = dsstmp+10; dssflag = 1; distran = DSS; keyname = "PLTDECD"; BEGIN(VALUE); } ^PLTDECM" " { // DSS: plate centre, declination - arcmin. valtype = FLOAT; distype = SEQUENT; vptr = dsstmp+11; dssflag = 1; distran = DSS; keyname = "PLTDECM"; BEGIN(VALUE); } ^PLTDECS" " { // DSS: plate centre, declination - arcsec. valtype = FLOAT; distype = SEQUENT; vptr = dsstmp+12; dssflag = 1; distran = DSS; keyname = "PLTDECS"; BEGIN(VALUE); } ^PLATEID" " { // DSS: plate identification (insufficient to trigger DSS). valtype = STRING; distype = SEQUENT; vptr = dsstmp+13; dssflag = 2; distran = 0; keyname = "PLATEID"; BEGIN(VALUE); } ^AMDX { // DSS: axis 1 polynomial coefficient. i = 1; dssflag = 3; keyname = "AMDXm"; BEGIN(DSSAMDXY); } ^AMDY { // DSS: axis 2 polynomial coefficient. i = 2; dssflag = 3; keyname = "AMDYm"; BEGIN(DSSAMDXY); } ^WAT[12]_{Z3} { // TNX or ZPX: string-encoded data array. sscanf(yytext, "WAT%d_%d", &i, &m); if (watn < m) watn = m; watflag = 1; valtype = STRING; distype = SEQUENT; vptr = wat[i-1] + 68*(m-1); a = ' '; distran = WAT; keyname = "WATi_m"; BEGIN(VALUE); } ^END" "{77} { if (yyextra->nkeyrec) { yyextra->nkeyrec = 0; errmsg = "keyrecords following the END keyrecord were ignored"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } ^. { BEGIN(DISCARD); } {I1}{ALT}" " | {I2}{ALT}" " | {I1}{ALT}" " | {I2}{ALT} { sscanf(yytext, "%d%c", &i, &a); BEGIN(VALUE); } 0{I1}{ALT}" " | 0{Z1}{I1}{ALT}" " | 0{Z2}{I1}{ALT}" " | 0{Z3}{I1}{ALT} | 0{Z4}{I1} | 0{I1}{ALT} | 0{Z1}{I1} { if (relax & WCSHDR_reject) { // Violates the basic FITS standard. errmsg = "indices in parameterized keywords must not have " "leading zeroes"; BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } {Z1}{ALT}" " | {Z2}{ALT}" " | {Z3}{ALT}" " | {Z4}{ALT}" " | {Z5}{ALT} | {Z6} | {Z1}{ALT}" " | {Z2}{ALT} | {Z3} { // Anything that has fallen through to this point must contain // an invalid axis number. errmsg = "axis number must exceed 0"; BEGIN(ERROR); } . { // Let it go. BEGIN(DISCARD); } . { if (relax & WCSHDR_reject) { // Looks too much like a FITS WCS keyword not to flag it. errmsg = errtxt; sprintf(errmsg, "keyword looks very much like %s but isn't", keyname); BEGIN(ERROR); } else { // Let it go. BEGIN(DISCARD); } } {I1}_{I1}{ALT}" " | {I1}_{I2}{ALT}" " | {I2}_{I1}{ALT}" " | {I2}_{I2}{ALT} { sscanf(yytext, "%d_%d%c", &i, &j, &a); BEGIN(VALUE); } 0{I1}_{I1}{ALT}" " | {I1}_0{I1}{ALT}" " | 00{I1}_{I1}{ALT} | 0{I1}_0{I1}{ALT} | {I1}_00{I1}{ALT} | 000{I1}_{I1} | 00{I1}_0{I1} | 0{I1}_00{I1} | {I1}_000{I1} | 0{I1}_{I2}{ALT} | {I1}_0{I2}{ALT} | 00{I1}_{I2} | 0{I1}_0{I2} | {I1}_00{I2} | 0{I2}_{I1}{ALT} | {I2}_0{I1}{ALT} | 00{I2}_{I1} | 0{I2}_0{I1} | {I2}_00{I1} | 0{I2}_{I2} | {I2}_0{I2} { if (((altlin == 1) && (relax & WCSHDR_PC0i_0ja)) || ((altlin == 2) && (relax & WCSHDR_CD0i_0ja))) { sscanf(yytext, "%d_%d%c", &i, &j, &a); BEGIN(VALUE); } else if (relax & WCSHDR_reject) { errmsg = "indices in parameterized keywords must not have " "leading zeroes"; BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } {Z1}_{Z1}{ALT}" " | {Z2}_{Z1}{ALT}" " | {Z1}_{Z2}{ALT}" " | {Z3}_{Z1}{ALT} | {Z2}_{Z2}{ALT} | {Z1}_{Z3}{ALT} | {Z4}_{Z1} | {Z3}_{Z2} | {Z2}_{Z3} | {Z1}_{Z4} { // Anything that has fallen through to this point must contain // an invalid axis number. errmsg = "axis number must exceed 0"; BEGIN(ERROR); } {Z1}-{Z1}{ALT}" " | {Z2}-{Z1}{ALT}" " | {Z1}-{Z2}{ALT}" " | {Z3}-{Z1}{ALT} | {Z2}-{Z2}{ALT} | {Z1}-{Z3}{ALT} | {Z4}-{Z1} | {Z3}-{Z2} | {Z2}-{Z3} | {Z1}-{Z4} { errmsg = errtxt; sprintf(errmsg, "%s keyword must use an underscore, not a dash", keyname); BEGIN(ERROR); } {Z2}{I1}{Z2}{I1} { // This covers the defunct forms CD00i00j and PC00i00j. if (((altlin == 1) && (relax & WCSHDR_PC00i00j)) || ((altlin == 2) && (relax & WCSHDR_CD00i00j))) { sscanf(yytext, "%3d%3d", &i, &j); a = ' '; BEGIN(VALUE); } else if (relax & WCSHDR_reject) { errmsg = errtxt; sprintf(errmsg, "this form of the %s keyword is deprecated, use %s", keyname, keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } . { BEGIN(DISCARD); } {ALT} | . { if (YY_START == CCCCCCCa) { sscanf(yytext, "%c", &a); } else { unput(yytext[0]); a = 0; } BEGIN(VALUE); } . { if (relax & WCSHDR_reject) { // Looks too much like a FITS WCS keyword not to flag it. errmsg = errtxt; sprintf(errmsg, "invalid alternate code, keyword resembles %s " "but isn't", keyname); BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } {I1}_{Z1}{ALT}" " | {I1}_{I2}{ALT}" " | {I2}_{Z1}{ALT}" " | {I2}_{I2}{ALT} { sscanf(yytext, "%d_%d%c", &i, &m, &a); BEGIN(VALUE); } 0{I1}_{Z1}{ALT}" " | {I1}_0{Z1}{ALT}" " | 00{I1}_{Z1}{ALT} | 0{I1}_0{Z1}{ALT} | {I1}_00{Z1}{ALT} | 000{I1}_{Z1} | 00{I1}_0{Z1} | 0{I1}_00{Z1} | {I1}_000{Z1} | 0{I1}_{I2}{ALT} | {I1}_0{I2}{ALT} | 00{I1}_{I2} | 0{I1}_0{I2} | {I1}_00{I2} | 0{I2}_{Z1}{ALT} | {I2}_0{Z1}{ALT} | 00{I2}_{Z1} | 0{I2}_0{Z1} | {I2}_00{Z1} | 0{I2}_{I2} | {I2}_0{I2} { if (((valtype == FLOAT) && (relax & WCSHDR_PV0i_0ma)) || ((valtype == STRING) && (relax & WCSHDR_PS0i_0ma))) { sscanf(yytext, "%d_%d%c", &i, &m, &a); BEGIN(VALUE); } else if (relax & WCSHDR_reject) { errmsg = "indices in parameterized keywords must not have " "leading zeroes"; BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } {Z1}_{Z1}{ALT}" " | {Z2}_{Z1}{ALT}" " | {Z1}_{Z2}{ALT}" " | {Z3}_{Z1}{ALT} | {Z2}_{Z2}{ALT} | {Z1}_{Z3}{ALT} | {Z4}_{Z1} | {Z3}_{Z2} | {Z2}_{Z3} | {Z1}_{Z4} { // Anything that has fallen through to this point must contain // an invalid axis number. errmsg = "axis number must exceed 0"; BEGIN(ERROR); } {Z1}-{Z1}{ALT}" " | {Z2}-{Z1}{ALT}" " | {Z1}-{Z2}{ALT}" " | {Z3}-{Z1}{ALT} | {Z2}-{Z2}{ALT} | {Z1}-{Z3}{ALT} | {Z4}-{Z1} | {Z3}-{Z2} | {Z2}-{Z3} | {Z1}-{Z4} { errmsg = errtxt; sprintf(errmsg, "%s keyword must use an underscore, not a dash", keyname); BEGIN(ERROR); } . { BEGIN(DISCARD); } {Z1}{ALT}" " | {Z2}{ALT} | {Z3} { a = ' '; sscanf(yytext, "%d%c", &i, &a); if (relax & WCSHDR_strict) { errmsg = "the CROTAn keyword is deprecated, use PCi_ja"; BEGIN(ERROR); } else if ((a == ' ') || (relax & WCSHDR_CROTAia)) { yyless(0); BEGIN(CCCCCia); } else if (relax & WCSHDR_reject) { errmsg = "CROTAn keyword may not have an alternate version code"; BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } . { yyless(0); BEGIN(CCCCCia); } {Z1}" " { if (relax & WCSHDR_PROJPn) { sscanf(yytext, "%d", &m); i = 0; a = ' '; BEGIN(VALUE); } else if (relax & WCSHDR_reject) { errmsg = "the PROJPn keyword is deprecated, use PVi_ma"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } {Z2}" " | {Z3} { if (relax & (WCSHDR_PROJPn | WCSHDR_reject)) { errmsg = "invalid PROJPn keyword"; BEGIN(ERROR); } else { BEGIN(DISCARD); } } . { BEGIN(DISCARD); } {Z1}_{Z1}" " | {Z1}_{Z1}" " { // SIP keywords. valtype = FLOAT; distype = PRIOR; vptr = &(distem.dp); npptr = ndp; a = ' '; distran = SIP; sscanf(yytext, "%d_%d", &p, &q); BEGIN(VALUE); } . | . { BEGIN(DISCARD); } {I1}" " | {I2}" " { // DSS keywords. valtype = FLOAT; distype = SEQUENT; vptr = &(distem.dp); npptr = ndq; a = ' '; distran = DSS; sscanf(yytext, "%d", &m); BEGIN(VALUE); } . { BEGIN(DISCARD); } =" "+{STRING} { // Special handling for this iconic DSS keyword. if (1 < ipass) { // Look for a minus sign. sscanf(yytext, "= '%s", strtmp); dbltmp = strcmp(strtmp, "-") ? 1.0 : -1.0; } BEGIN(COMMENT); } . { BEGIN(DISCARD); } =" "+ { // Do checks on i, j & m. if (99 < i || 99 < j || 99 < m) { if (relax & WCSHDR_reject) { if (99 < i || 99 < j) { errmsg = "axis number exceeds 99"; } else if (m > 99) { errmsg = "parameter number exceeds 99"; } BEGIN(ERROR); } else { // Pretend we don't recognize it. BEGIN(DISCARD); } } else { if (valtype == INTEGER) { BEGIN(INTEGER_VAL); } else if (valtype == FLOAT) { BEGIN(FLOAT_VAL); } else if (valtype == FLOAT2) { BEGIN(FLOAT2_VAL); } else if (valtype == STRING) { BEGIN(STRING_VAL); } else if (valtype == RECORD) { BEGIN(RECORD_VAL); } else { errmsg = errtxt; sprintf(errmsg, "internal parser ERROR, bad data type: %d", valtype); BEGIN(ERROR); } } } . { errmsg = "invalid KEYWORD = VALUE syntax"; BEGIN(ERROR); } {INTEGER} { if (ipass == 1) { BEGIN(COMMENT); } else { // Read the keyvalue. sscanf(yytext, "%d", &inttmp); BEGIN(COMMENT); } } . { errmsg = "an integer value was expected"; BEGIN(ERROR); } {FLOAT} { if (ipass == 1) { BEGIN(COMMENT); } else { // Read the keyvalue. wcsutil_str2double(yytext, &dbltmp); if (chekval && chekval(dbltmp)) { errmsg = "invalid keyvalue"; BEGIN(ERROR); } else { BEGIN(COMMENT); } } } . { errmsg = "a floating-point value was expected"; BEGIN(ERROR); } {FLOAT} { if (ipass == 1) { BEGIN(COMMENT); } else { // Read the keyvalue as integer and fractional parts. wcsutil_str2double2(yytext, dbl2tmp); BEGIN(COMMENT); } } . { errmsg = "a floating-point value was expected"; BEGIN(ERROR); } {STRING} { if (ipass == 1) { BEGIN(COMMENT); } else { // Read the keyvalue. strcpy(strtmp, yytext+1); // Squeeze out repeated quotes. int ix = 0; for (int jx = 0; jx < 72; jx++) { if (ix < jx) { strtmp[ix] = strtmp[jx]; } if (strtmp[jx] == '\0') { if (ix) strtmp[ix-1] = '\0'; break; } else if (strtmp[jx] == '\'' && strtmp[jx+1] == '\'') { jx++; } ix++; } BEGIN(COMMENT); } } . { errmsg = "a string value was expected"; BEGIN(ERROR); } {RECORD} { if (ipass == 1) { BEGIN(COMMENT); } else { yyless(1); BEGIN(RECFIELD); } } . { errmsg = "a record was expected"; BEGIN(ERROR); } {FIELD} { strcpy(strtmp, yytext); BEGIN(RECCOLON); } . { errmsg = "invalid record field"; BEGIN(ERROR); } :" "+ { BEGIN(RECVALUE); } . { errmsg = "invalid record syntax"; BEGIN(ERROR); } {INTEGER} { rectype = 0; sscanf(yytext, "%d", &inttmp); BEGIN(RECEND); } {FLOAT} { rectype = 1; wcsutil_str2double(yytext, &dbltmp); BEGIN(RECEND); } . { errmsg = "invalid record value"; BEGIN(ERROR); } ' { BEGIN(COMMENT); } {INLINE}$ { if (ipass == 1) { // Do first-pass bookkeeping. wcspih_pass1(naxis, i, j, a, distype, alts, dpq, npptr); BEGIN(FLUSH); } else if (*wcs) { // Store the value now that the keyrecord has been validated. int gotone = 0; for (int ialt = 0; ialt < *nwcs; ialt++) { // The loop here is for keywords that apply // to every alternate; these have a == 0. if (a >= 'A') { ialt = alts[a-'A'+1]; if (ialt < 0) break; } gotone = 1; if (vptr) { if (sipflag) { // Translate a SIP keyword into DPja. struct disprm *disp = (*wcs)->lin.dispre; int ipx = (disp->ndp)++; // SIP doesn't have alternates. char keyword[16]; sprintf(keyword, "DP%d", i); sprintf(strtmp, "SIP.%s.%d_%d", (sipflag==2)?"FWD":"REV", p, q); if (valtype == INTEGER) { dpfill(disp->dp+ipx, keyword, strtmp, i, 0, inttmp, 0.0); } else { dpfill(disp->dp+ipx, keyword, strtmp, i, 1, 0, dbltmp); } } else if (dssflag) { // All DSS keywords require special handling. if (dssflag == 1) { // Temporary parameter for DSS used by wcspih_final(). *((double *)vptr) = dbltmp; } else if (dssflag == 2) { // Temporary parameter for DSS used by wcspih_final(). strcpy((char *)vptr, strtmp); } else { // Translate a DSS keyword into DQia. if (m <= 13 || dbltmp != 0.0) { struct disprm *disp = (*wcs)->lin.disseq; int ipx = (disp->ndp)++; // DSS doesn't have alternates. char keyword[16]; sprintf(keyword, "DQ%d", i); sprintf(strtmp, "DSS.AMD.%d", m); dpfill(disp->dp+ipx, keyword, strtmp, i, 1, 0, dbltmp); // Also required by wcspih_final(). if (m <= 3) { dsstmp[13+(i-1)*3+m] = dbltmp; } } } } else if (watflag) { // String array for TNX and ZPX used by wcspih_final(). strcpy((char *)vptr, strtmp); } else { // An "ordinary" keyword. struct wcsprm *wcsp = *wcs + ialt; struct disprm *disp; void *wptr; ptrdiff_t voff; if (auxprm) { // Additional auxiliary parameter. struct auxprm *auxp = wcsp->aux; voff = (char *)vptr - (char *)(&auxtem); wptr = (void *)((char *)auxp + voff); } else if (distype) { // Distortion parameter of some kind. if (distype == PRIOR) { // Prior distortion. disp = wcsp->lin.dispre; } else { // Sequent distortion. disp = wcsp->lin.disseq; } voff = (char *)vptr - (char *)(&distem); wptr = (void *)((char *)disp + voff); } else { // A parameter that lives directly in wcsprm. voff = (char *)vptr - (char *)(&wcstem); wptr = (void *)((char *)wcsp + voff); } if (valtype == INTEGER) { *((int *)wptr) = inttmp; } else if (valtype == FLOAT) { // Apply keyword parameterization. if (npptr == npv) { int ipx = (wcsp->npv)++; wcsp->pv[ipx].i = i; wcsp->pv[ipx].m = m; wptr = &(wcsp->pv[ipx].value); } else if (j) { wptr = *((double **)wptr) + (i - 1)*(wcsp->naxis) + (j - 1); } else if (i) { wptr = *((double **)wptr) + (i - 1); } if (special) { special(wptr, &dbltmp); } else { *((double *)wptr) = dbltmp; } // Flag presence of PCi_ja, or CDi_ja and/or CROTAia. if (altlin) { wcsp->altlin |= altlin; altlin = 0; } } else if (valtype == FLOAT2) { // Split MJDREF and JDREF into integer and fraction. if (special) { special(wptr, dbl2tmp); } else { *((double *)wptr) = dbl2tmp[0]; *((double *)wptr + 1) = dbl2tmp[1]; } } else if (valtype == STRING) { // Apply keyword parameterization. if (npptr == nps) { int ipx = (wcsp->nps)++; wcsp->ps[ipx].i = i; wcsp->ps[ipx].m = m; wptr = wcsp->ps[ipx].value; } else if (j) { wptr = *((char (**)[72])wptr) + (i - 1)*(wcsp->naxis) + (j - 1); } else if (i) { wptr = *((char (**)[72])wptr) + (i - 1); } char *cptr = (char *)wptr; strcpy(cptr, strtmp); } else if (valtype == RECORD) { int ipx = (disp->ndp)++; char keyword[16]; if (a == ' ') { sprintf(keyword, "%.2s%d", keyname, i); } else { sprintf(keyword, "%.2s%d%c", keyname, i, a); } dpfill(disp->dp+ipx, keyword, strtmp, i, rectype, inttmp, dbltmp); } } } if (a) break; } if (gotone) { nvalid++; if (ctrl == 4) { if (distran || dssflag) { wcsfprintf(stderr, "%.80s\n Accepted (%d) as a " "recognized WCS convention.\n", keyrec, nvalid); } else { wcsfprintf(stderr, "%.80s\n Accepted (%d) as a " "valid WCS keyrecord.\n", keyrec, nvalid); } } BEGIN(FLUSH); } else { errmsg = "syntactically valid WCS keyrecord has no effect"; BEGIN(ERROR); } } else { BEGIN(FLUSH); } } .*" "*\/.*$ { errmsg = "invalid keyvalue"; BEGIN(ERROR); } [^ \/\n]*{INLINE}$ { errmsg = "invalid keyvalue"; BEGIN(ERROR); } " "+[^\/\n].*{INLINE}$ { errmsg = "invalid keyvalue or malformed keycomment"; BEGIN(ERROR); } .*$ { errmsg = "malformed keycomment"; BEGIN(ERROR); } .*$ { if (ipass == npass) { if (ctrl < 0) { // Preserve discards. keep = keyrec; } else if (2 < ctrl) { nother++; wcsfprintf(stderr, "%.80s\n Not a recognized WCS keyword.\n", keyrec); } } BEGIN(FLUSH); } .*$ { if (ipass == npass) { (*nreject)++; if (ctrl%10 == -1) { // Preserve rejects. keep = keyrec; } if (1 < abs(ctrl%10)) { wcsfprintf(stderr, "%.80s\n Rejected (%d), %s.\n", keyrec, *nreject, errmsg); } } BEGIN(FLUSH); } .*\n { if (ipass == npass && keep) { if (hptr < keep) { strncpy(hptr, keep, 80); } hptr += 80; } naux += auxprm; // Throw away the rest of the line and reset for the next one. i = j = 0; m = 0; a = ' '; keyrec += 80; valtype = -1; distype = 0; vptr = 0x0; keep = 0x0; altlin = 0; npptr = 0x0; chekval = 0x0; special = 0x0; auxprm = 0; sipflag = 0; dssflag = 0; watflag = 0; BEGIN(INITIAL); } <> { // End-of-input. int status; if (ipass == 1) { if ((status = wcspih_init1(naxis, alts, dpq, npv, nps, ndp, ndq, naux, distran, nwcs, wcs)) || (*nwcs == 0 && ctrl == 0)) { return status; } if (2 < abs(ctrl%10)) { if (*nwcs == 1) { if (strcmp(wcs[0]->wcsname, "DEFAULTS") != 0) { wcsfprintf(stderr, "Found one coordinate representation.\n"); } } else { wcsfprintf(stderr, "Found %d coordinate representations.\n", *nwcs); } } watstr = calloc(2*(watn*68 + 1), sizeof(char)); wat[0] = watstr; wat[1] = watstr + watn*68 + 1; } if (ipass++ < npass) { yyextra->hdr = header; yyextra->nkeyrec = nkeyrec; keyrec = header; *nreject = 0; i = j = 0; m = 0; a = ' '; valtype = -1; distype = 0; vptr = 0x0; altlin = 0; npptr = 0x0; chekval = 0x0; special = 0x0; auxprm = 0; sipflag = 0; dssflag = 0; watflag = 0; yyrestart(yyin, yyscanner); } else { if (ctrl < 0) { *hptr = '\0'; } else if (ctrl == 1) { wcsfprintf(stderr, "%d WCS keyrecord%s rejected.\n", *nreject, (*nreject==1)?" was":"s were"); } else if (ctrl == 4) { wcsfprintf(stderr, "\n"); wcsfprintf(stderr, "%5d keyrecord%s rejected for syntax or " "other errors,\n", *nreject, (*nreject==1)?" was":"s were"); wcsfprintf(stderr, "%5d %s recognized as syntactically valid, " "and\n", nvalid, (nvalid==1)?"was":"were"); wcsfprintf(stderr, "%5d other%s were not recognized as WCS " "keyrecords.\n", nother, (nother==1)?"":"s"); } status = wcspih_final(ndp, ndq, distran, dsstmp, wat, nwcs, wcs); free(watstr); return status; } } %% /*---------------------------------------------------------------------------- * External interface to the scanner. *---------------------------------------------------------------------------*/ int wcspih( char *header, int nkeyrec, int relax, int ctrl, int *nreject, int *nwcs, struct wcsprm **wcs) { // Function prototypes. int yylex_init_extra(YY_EXTRA_TYPE extra, yyscan_t *yyscanner); int yylex_destroy(yyscan_t yyscanner); struct wcspih_extra extra; yyscan_t yyscanner; yylex_init_extra(&extra, &yyscanner); int status = wcspih_scanner(header, nkeyrec, relax, ctrl, nreject, nwcs, wcs, yyscanner); yylex_destroy(yyscanner); return status; } /*---------------------------------------------------------------------------- * Determine the number of coordinate representations (up to 27) and the * number of coordinate axes in each, which distortions are present, and the * number of PVi_ma, PSi_ma, DPja, and DQia keywords in each representation. *---------------------------------------------------------------------------*/ void wcspih_pass1( int naxis, int i, int j, char a, int distype, int alts[], int dpq[], int *npptr) { // On the first pass alts[] is used to determine the number of axes // for each of the 27 possible alternate coordinate descriptions. if (a == 0) { return; } int ialt = 0; if (a != ' ') { ialt = a - 'A' + 1; } int *ip = alts + ialt; if (*ip < naxis) { *ip = naxis; } // i or j can be greater than naxis. if (*ip < i) { *ip = i; } if (*ip < j) { *ip = j; } // Type of distortions present. dpq[ialt] |= distype; // Count PVi_ma, PSi_ma, DPja, or DQia keywords. if (npptr) { npptr[ialt]++; } } /*---------------------------------------------------------------------------- * Allocate memory for an array of the required number of wcsprm structs and * initialize each of them. *---------------------------------------------------------------------------*/ int wcspih_init1( int naxis, int alts[], int dpq[], int npv[], int nps[], int ndp[], int ndq[], int naux, int distran, int *nwcs, struct wcsprm **wcs) { int status = 0; // Find the number of coordinate descriptions. *nwcs = 0; for (int ialt = 0; ialt < 27; ialt++) { if (alts[ialt]) (*nwcs)++; } int defaults; if ((defaults = !(*nwcs) && naxis)) { // NAXIS is non-zero but there were no WCS keywords with an alternate // version code; create a default WCS with blank alternate version. wcspih_pass1(naxis, 0, 0, ' ', 0, alts, dpq, 0x0); *nwcs = 1; } if (*nwcs) { // Allocate memory for the required number of wcsprm structs. if ((*wcs = calloc(*nwcs, sizeof(struct wcsprm))) == 0x0) { return WCSHDRERR_MEMORY; } int ndis = 0; if (distran == SIP) { // DPja.NAXES and DPja.OFFSET.j to be added for SIP (see below and // wcspih_final()). ndp[0] += 6; } else if (distran == DSS) { // DPja.NAXES to be added for DSS (see below and wcspih_final()). ndq[0] += 2; } // Initialize each wcsprm struct. struct wcsprm *wcsp = *wcs; *nwcs = 0; for (int ialt = 0; ialt < 27; ialt++) { if (alts[ialt]) { wcsp->flag = -1; int npvmax = npv[ialt]; int npsmax = nps[ialt]; if ((status = wcsinit(1, alts[ialt], wcsp, npvmax, npsmax, -1))) { wcsvfree(nwcs, wcs); break; } // Record the alternate version code. if (ialt) { wcsp->alt[0] = 'A' + ialt - 1; } // Record in wcsname whether this is a default description. if (defaults) { strcpy(wcsp->wcsname, "DEFAULTS"); } // Any additional auxiliary keywords present? if (naux) { if (wcsauxi(1, wcsp)) { return WCSHDRERR_MEMORY; } } // Any distortions present? struct disprm *disp; if (dpq[ialt] & 1) { if ((disp = calloc(1, sizeof(struct disprm))) == 0x0) { return WCSHDRERR_MEMORY; } // Attach it to linprm. Also inits it. ndis++; int ndpmax = ndp[ialt]; disp->flag = -1; lindist(1, &(wcsp->lin), disp, ndpmax); } if (dpq[ialt] & 2) { if ((disp = calloc(1, sizeof(struct disprm))) == 0x0) { return WCSHDRERR_MEMORY; } // Attach it to linprm. Also inits it. ndis++; int ndpmax = ndq[ialt]; disp->flag = -1; lindist(2, &(wcsp->lin), disp, ndpmax); } // On the second pass alts[] indexes the array of wcsprm structs. alts[ialt] = (*nwcs)++; wcsp++; } else { // Signal that there is no wcsprm for this alt. alts[ialt] = -1; } } // Translated distortion? Neither SIP nor DSS have alternates, so the // presence of keywords for either (not both together), as flagged by // distran, necessarily refers to the primary representation. if (distran == SIP) { strcpy((*wcs)->lin.dispre->dtype[0], "SIP"); strcpy((*wcs)->lin.dispre->dtype[1], "SIP"); // SIP doesn't have axis mapping. (*wcs)->lin.dispre->ndp = 6; dpfill((*wcs)->lin.dispre->dp, "DP1", "NAXES", 0, 0, 2, 0.0); dpfill((*wcs)->lin.dispre->dp+3, "DP2", "NAXES", 0, 0, 2, 0.0); } else if (distran == DSS) { strcpy((*wcs)->lin.disseq->dtype[0], "DSS"); strcpy((*wcs)->lin.disseq->dtype[1], "DSS"); // The Paper IV translation of DSS doesn't require an axis mapping. (*wcs)->lin.disseq->ndp = 2; dpfill((*wcs)->lin.disseq->dp, "DQ1", "NAXES", 0, 0, 2, 0.0); dpfill((*wcs)->lin.disseq->dp+1, "DQ2", "NAXES", 0, 0, 2, 0.0); } } return status; } /*---------------------------------------------------------------------------- * Interpret the JDREF, JDREFI, and JDREFF keywords. *---------------------------------------------------------------------------*/ int wcspih_jdref(double *mjdref, const double *jdref) { // Set MJDREF from JDREF. if (undefined(mjdref[0] && undefined(mjdref[1]))) { mjdref[0] = jdref[0] - 2400000.0; mjdref[1] = jdref[1] - 0.5; if (mjdref[1] < 0.0) { mjdref[0] -= 1.0; mjdref[1] += 1.0; } } return 0; } int wcspih_jdrefi(double *mjdref, const double *jdrefi) { // Set the integer part of MJDREF from JDREFI. if (undefined(mjdref[0])) { mjdref[0] = *jdrefi - 2400000.5; } return 0; } int wcspih_jdreff(double *mjdref, const double *jdreff) { // Set the fractional part of MJDREF from JDREFF. if (undefined(mjdref[1])) { mjdref[1] = *jdreff; } return 0; } /*---------------------------------------------------------------------------- * Interpret EPOCHa keywords. *---------------------------------------------------------------------------*/ int wcspih_epoch(double *equinox, const double *epoch) { // If EQUINOXa is currently undefined then set it from EPOCHa. if (undefined(*equinox)) { *equinox = *epoch; } return 0; } /*---------------------------------------------------------------------------- * Interpret VSOURCEa keywords. *---------------------------------------------------------------------------*/ int wcspih_vsource(double *zsource, const double *vsource) { const double c = 299792458.0; // If ZSOURCEa is currently undefined then set it from VSOURCEa. if (undefined(*zsource)) { // Convert relativistic Doppler velocity to redshift. double beta = *vsource/c; *zsource = (1.0 + beta)/sqrt(1.0 - beta*beta) - 1.0; } return 0; } /*---------------------------------------------------------------------------- * Check validity of a TIMEPIXR keyvalue. *---------------------------------------------------------------------------*/ int wcspih_timepixr(double timepixr) { return (timepixr < 0.0 || 1.0 < timepixr); } /*---------------------------------------------------------------------------- * Interpret special keywords encountered for each coordinate representation. *---------------------------------------------------------------------------*/ int wcspih_final( int ndp[], int ndq[], int distran, double dsstmp[], char *wat[], int *nwcs, struct wcsprm **wcs) { for (int ialt = 0; ialt < *nwcs; ialt++) { // Interpret -TAB header keywords. int status; if ((status = wcstab(*wcs+ialt))) { wcsvfree(nwcs, wcs); return status; } if (ndp[ialt] && ndq[ialt]) { // Prior and sequent distortions co-exist in this representation; // ensure the latter gets DVERRa. (*wcs+ialt)->lin.disseq->totdis = (*wcs+ialt)->lin.dispre->totdis; } } // Translated distortion functions; apply only to the primary WCS. struct wcsprm *wcsp = *wcs; if (distran == SIP) { // SIP doesn't have alternates, nor axis mapping. struct disprm *disp = wcsp->lin.dispre; dpfill(disp->dp+1, "DP1", "OFFSET.1", 0, 1, 0, wcsp->crpix[0]); dpfill(disp->dp+2, "DP1", "OFFSET.2", 0, 1, 0, wcsp->crpix[1]); dpfill(disp->dp+4, "DP2", "OFFSET.1", 0, 1, 0, wcsp->crpix[0]); dpfill(disp->dp+5, "DP2", "OFFSET.2", 0, 1, 0, wcsp->crpix[1]); } else if (distran == DSS) { // DSS doesn't have alternates, nor axis mapping. This translation // follows Paper IV, Sect. 5.2 using the same variable names. double CNPIX1 = dsstmp[0]; double CNPIX2 = dsstmp[1]; double Xc = dsstmp[2]/1000.0; double Yc = dsstmp[3]/1000.0; double Rx = dsstmp[4]/1000.0; double Ry = dsstmp[5]/1000.0; double A1 = dsstmp[14]; double A2 = dsstmp[15]; double A3 = dsstmp[16]; double B1 = dsstmp[17]; double B2 = dsstmp[18]; double B3 = dsstmp[19]; double S = sqrt(fabs(A1*B1 - A2*B2)); double X0 = (A2*B3 - A3*B1) / (A1*B1 - A2*B2); double Y0 = (A3*B2 - A1*B3) / (A1*B1 - A2*B2); wcsp->crpix[0] = (Xc - X0)/Rx - (CNPIX1 - 0.5); wcsp->crpix[1] = (Yc + Y0)/Ry - (CNPIX2 - 0.5); wcsp->pc[0] = A1*Rx/S; wcsp->pc[1] = -A2*Ry/S; wcsp->pc[2] = -B2*Rx/S; wcsp->pc[3] = B1*Ry/S; wcsp->altlin = 1; wcsp->cdelt[0] = -S/3600.0; wcsp->cdelt[1] = S/3600.0; double *crval = wcsp->crval; crval[0] = (dsstmp[6] + (dsstmp[7] + dsstmp[8] /60.0)/60.0)*15.0; crval[1] = dsstmp[10] + (dsstmp[11] + dsstmp[12]/60.0)/60.0; if (dsstmp[9] == -1.0) crval[1] *= -1.0; strcpy(wcsp->ctype[0], "RA---TAN"); strcpy(wcsp->ctype[1], "DEC--TAN"); sprintf(wcsp->wcsname, "DSS PLATEID %.4s", (char *)(dsstmp+13)); // Erase the approximate WCS provided in modern DSS headers. wcsp->cd[0] = 0.0; wcsp->cd[1] = 0.0; wcsp->cd[2] = 0.0; wcsp->cd[3] = 0.0; } else if (distran == WAT) { // TNX and ZPX don't have alternates, nor axis mapping. char *wp; int omax, omin, wctrl[4]; double wval; struct disprm *disp = wcsp->lin.disseq; // Disassemble the core dump stored in the WATi_m strings. int i, nterms = 0; for (i = 0; i < 2; i++) { char wtype[8]; sscanf(wat[i], "wtype=%s", wtype); if (strcmp(wtype, "tnx") == 0) { strcpy(disp->dtype[i], "WAT-TNX"); } else if (strcmp(wtype, "zpx") == 0) { strcpy(disp->dtype[i], "WAT-ZPX"); } else { // Could contain "tan" or something else to be ignored. lindist(2, &(wcsp->lin), 0x0, 0); return 0; } // The PROJPn parameters are duplicated on each ZPX axis. if (i == 1 && strcmp(wtype, "zpx") == 0) { // Take those on the second (latitude) axis ignoring the other. // First we have to count them and allocate space in wcsprm. wp = wat[i]; int npv; for (npv = 0; npv < 30; npv++) { if ((wp = strstr(wp, "projp")) == 0x0) break; wp += 5; } // Allocate space. if (npv) { wcsp->npvmax += npv; wcsp->pv = realloc(wcsp->pv, wcsp->npvmax*sizeof(struct pvcard)); if (wcsp->pv == 0x0) { return WCSHDRERR_MEMORY; } wcsp->m_pv = wcsp->pv; } // Copy the values. wp = wat[i]; for (int ipv = wcsp->npv; ipv < wcsp->npvmax; ipv++) { if ((wp = strstr(wp, "projp")) == 0x0) break; int m; sscanf(wp, "projp%d=%lf", &m, &wval); wcsp->pv[ipv].i = 2; wcsp->pv[ipv].m = m; wcsp->pv[ipv].value = wval; wp += 5; } wcsp->npv += npv; } // Read the control parameters. if ((wp = strchr(wat[i], '"')) == 0x0) { return WCSHDRERR_PARSER; } wp++; for (int m = 0; m < 4; m++) { sscanf(wp, "%d", wctrl+m); if ((wp = strchr(wp, ' ')) == 0x0) { return WCSHDRERR_PARSER; } wp++; } // How many coefficients are we expecting? omin = (wctrl[1] < wctrl[2]) ? wctrl[1] : wctrl[2]; omax = (wctrl[1] < wctrl[2]) ? wctrl[2] : wctrl[1]; if (wctrl[3] == 0) { // No cross terms. nterms += omin + omax; } else if (wctrl[3] == 1) { // Full cross terms. nterms += omin*omax; } else if (wctrl[3] == 2) { // Half cross terms. nterms += omin*omax - omin*(omin-1)/2; } } // Allocate memory for dpkeys. ndq[0] += 2*(1 + 1 + 4) + nterms; disp->ndpmax += ndq[0]; disp->dp = realloc(disp->dp, disp->ndpmax*sizeof(struct dpkey)); if (disp->dp == 0x0) { return WCSHDRERR_MEMORY; } disp->m_dp = disp->dp; // Populate dpkeys. int idp = disp->ndp; for (i = 0; i < 2; i++) { dpfill(disp->dp+(idp++), "DQ", "NAXES", i+1, 0, 2, 0.0); // Read the control parameters. if ((wp = strchr(wat[i], '"')) == 0x0) { return WCSHDRERR_PARSER; } wp++; for (int m = 0; m < 4; m++) { sscanf(wp, "%d", wctrl+m); if ((wp = strchr(wp, ' ')) == 0x0) { return WCSHDRERR_PARSER; } wp++; } // Polynomial type. char wpoly[12]; dpfill(disp->dp+(idp++), "DQ", "WAT.POLY", i+1, 0, wctrl[0], 0.0); if (wctrl[0] == 1) { // Chebyshev polynomial. strcpy(wpoly, "CHBY"); } else if (wctrl[0] == 2) { // Legendre polynomial. strcpy(wpoly, "LEGR"); } else if (wctrl[0] == 3) { // Polynomial is the sum of monomials. strcpy(wpoly, "MONO"); } else { // Unknown code. strcpy(wpoly, "UNKN"); } // Read the scaling parameters. char field[40]; for (int m = 0; m < 4; m++) { sscanf(wp, "%lf", &wval); sprintf(field, "WAT.%c%s", (m<2)?'X':'Y', (m%2)?"MAX":"MIN"); dpfill(disp->dp+(idp++), "DQ", field, i+1, 1, 0, wval); if ((wp = strchr(wp, ' ')) == 0x0) { return WCSHDRERR_PARSER; } wp++; } // Read the coefficients. for (int n = 0; n < wctrl[2]; n++) { for (int m = 0; m < wctrl[1]; m++) { if (wctrl[3] == 0) { if (m && n) continue; } else if (wctrl[3] == 2) { if (m+n > omax-1) continue; } sscanf(wp, "%lf", &wval); if (wval == 0.0) continue; sprintf(field, "WAT.%s.%d_%d", wpoly, m, n); dpfill(disp->dp+(idp++), "DQ", field, i+1, 1, 0, wval); if ((wp = strchr(wp, ' ')) == 0x0) { return WCSHDRERR_PARSER; } wp++; } } } disp->ndp = idp; } return 0; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/wcsprintf.c0000644000175100001710000001037300000000000017551 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcsprintf.c,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *===========================================================================*/ #include #include #include #include "wcsprintf.h" static FILE *wcsprintf_file = 0x0; static char *wcsprintf_buff = 0x0; static char *wcsprintf_bufp = 0x0; static size_t wcsprintf_size = 0; //---------------------------------------------------------------------------- int wcsprintf_set(FILE *wcsout) { if (wcsout != 0x0) { // Output to file. wcsprintf_file = wcsout; if (wcsprintf_buff != 0x0) { // Release the buffer. free(wcsprintf_buff); wcsprintf_buff = 0x0; } } else { // Output to buffer. wcsprintf_file = 0x0; if (wcsprintf_buff == 0x0) { // Allocate a buffer. wcsprintf_buff = malloc(1024); if (wcsprintf_buff == NULL) { return 1; } wcsprintf_size = 1024; } // Reset pointer to the start of the buffer. wcsprintf_bufp = wcsprintf_buff; *wcsprintf_bufp = '\0'; } return 0; } //---------------------------------------------------------------------------- const char *wcsprintf_buf(void) { return wcsprintf_buff; } //---------------------------------------------------------------------------- int wcsprintf(const char *format, ...) { char *realloc_buff; int nbytes; size_t used; va_list arg_list; if (wcsprintf_buff == 0x0 && wcsprintf_file == 0x0) { // Send output to stdout if wcsprintf_set() hasn't been called. wcsprintf_file = stdout; } va_start(arg_list, format); if (wcsprintf_file) { // Output to file. nbytes = vfprintf(wcsprintf_file, format, arg_list); } else { // Output to buffer. used = wcsprintf_bufp - wcsprintf_buff; if (wcsprintf_size - used < 128) { // Expand the buffer. wcsprintf_size += 1024; realloc_buff = realloc(wcsprintf_buff, wcsprintf_size); if (realloc_buff == NULL) { free(wcsprintf_buff); wcsprintf_buff = 0x0; return 1; } wcsprintf_buff = realloc_buff; wcsprintf_bufp = wcsprintf_buff + used; } nbytes = vsprintf(wcsprintf_bufp, format, arg_list); wcsprintf_bufp += nbytes; } va_end(arg_list); return nbytes; } //---------------------------------------------------------------------------- int wcsfprintf(FILE *stream, const char *format, ...) { char *realloc_buff; int nbytes; size_t used; va_list arg_list; if (wcsprintf_buff == 0x0 && wcsprintf_file == 0x0) { // Send output to stream if wcsprintf_set() hasn't been called. wcsprintf_file = stream; } va_start(arg_list, format); if (wcsprintf_file) { // Output to file. nbytes = vfprintf(wcsprintf_file, format, arg_list); } else { // Output to buffer. used = wcsprintf_bufp - wcsprintf_buff; if (wcsprintf_size - used < 128) { // Expand the buffer. wcsprintf_size += 1024; realloc_buff = realloc(wcsprintf_buff, wcsprintf_size); if (realloc_buff == NULL) { free(wcsprintf_buff); wcsprintf_buff = 0x0; return 1; } wcsprintf_buff = realloc_buff; wcsprintf_bufp = wcsprintf_buff + used; } nbytes = vsprintf(wcsprintf_bufp, format, arg_list); wcsprintf_bufp += nbytes; } va_end(arg_list); return nbytes; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/wcsprintf.h0000644000175100001710000001364600000000000017564 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcsprintf.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the wcsprintf routines * --------------------------------- * Routines in this suite allow diagnostic output from celprt(), linprt(), * prjprt(), spcprt(), tabprt(), wcsprt(), and wcserr_prt() to be redirected to * a file or captured in a string buffer. Those routines all use wcsprintf() * for output. Likewise wcsfprintf() is used by wcsbth() and wcspih(). Both * functions may be used by application programmers to have other output go to * the same place. * * * wcsprintf() - Print function used by WCSLIB diagnostic routines * --------------------------------------------------------------- * wcsprintf() is used by celprt(), linprt(), prjprt(), spcprt(), tabprt(), * wcsprt(), and wcserr_prt() for diagnostic output which by default goes to * stdout. However, it may be redirected to a file or string buffer via * wcsprintf_set(). * * Given: * format char* Format string, passed to one of the printf(3) family * of stdio library functions. * * ... mixed Argument list matching format, as per printf(3). * * Function return value: * int Number of bytes written. * * * wcsfprintf() - Print function used by WCSLIB diagnostic routines * ---------------------------------------------------------------- * wcsfprintf() is used by wcsbth(), and wcspih() for diagnostic output which * they send to stderr. However, it may be redirected to a file or string * buffer via wcsprintf_set(). * * Given: * stream FILE* The output stream if not overridden by a call to * wcsprintf_set(). * * format char* Format string, passed to one of the printf(3) family * of stdio library functions. * * ... mixed Argument list matching format, as per printf(3). * * Function return value: * int Number of bytes written. * * * wcsprintf_set() - Set output disposition for wcsprintf() and wcsfprintf() * ------------------------------------------------------------------------- * wcsprintf_set() sets the output disposition for wcsprintf() which is used by * the celprt(), linprt(), prjprt(), spcprt(), tabprt(), wcsprt(), and * wcserr_prt() routines, and for wcsfprintf() which is used by wcsbth() and * wcspih(). * * Given: * wcsout FILE* Pointer to an output stream that has been opened for * writing, e.g. by the fopen() stdio library function, * or one of the predefined stdio output streams - stdout * and stderr. If zero (NULL), output is written to an * internally-allocated string buffer, the address of * which may be obtained by wcsprintf_buf(). * * Function return value: * int Status return value: * 0: Success. * * * wcsprintf_buf() - Get the address of the internal string buffer * --------------------------------------------------------------- * wcsprintf_buf() returns the address of the internal string buffer created * when wcsprintf_set() is invoked with its FILE* argument set to zero. * * Function return value: * const char * * Address of the internal string buffer. The user may * free this buffer by calling wcsprintf_set() with a * valid FILE*, e.g. stdout. The free() stdlib library * function must NOT be invoked on this const pointer. * * * WCSPRINTF_PTR() macro - Print addresses in a consistent way * ----------------------------------------------------------- * WCSPRINTF_PTR() is a preprocessor macro used to print addresses in a * consistent way. * * On some systems the "%p" format descriptor renders a NULL pointer as the * string "0x0". On others, however, it produces "0" or even "(nil)". On * some systems a non-zero address is prefixed with "0x", on others, not. * * The WCSPRINTF_PTR() macro ensures that a NULL pointer is always rendered as * "0x0" and that non-zero addresses are prefixed with "0x" thus providing * consistency, for example, for comparing the output of test programs. * *===========================================================================*/ #ifndef WCSLIB_WCSPRINTF #define WCSLIB_WCSPRINTF #include #include #ifdef __cplusplus extern "C" { #endif #define WCSPRINTF_PTR(str1, ptr, str2) \ if (ptr) { \ wcsprintf("%s%#" PRIxPTR "%s", (str1), (uintptr_t)(ptr), (str2)); \ } else { \ wcsprintf("%s0x0%s", (str1), (str2)); \ } int wcsprintf_set(FILE *wcsout); int wcsprintf(const char *format, ...); int wcsfprintf(FILE *stream, const char *format, ...); const char *wcsprintf_buf(void); #ifdef __cplusplus } #endif #endif // WCSLIB_WCSPRINTF ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/wcstrig.c0000644000175100001710000001004400000000000017207 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcstrig.c,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *===========================================================================*/ #include #include #include "wcsmath.h" #include "wcstrig.h" double cosd(double angle) { int i; if (fmod(angle,90.0) == 0.0) { i = abs((int)floor(angle/90.0 + 0.5))%4; switch (i) { case 0: return 1.0; case 1: return 0.0; case 2: return -1.0; case 3: return 0.0; } } return cos(angle*D2R); } //---------------------------------------------------------------------------- double sind(double angle) { int i; if (fmod(angle,90.0) == 0.0) { i = abs((int)floor(angle/90.0 - 0.5))%4; switch (i) { case 0: return 1.0; case 1: return 0.0; case 2: return -1.0; case 3: return 0.0; } } return sin(angle*D2R); } //---------------------------------------------------------------------------- void sincosd(double angle, double *s, double *c) { int i; if (fmod(angle,90.0) == 0.0) { i = abs((int)floor(angle/90.0 + 0.5))%4; switch (i) { case 0: *s = 0.0; *c = 1.0; return; case 1: *s = (angle > 0.0) ? 1.0 : -1.0; *c = 0.0; return; case 2: *s = 0.0; *c = -1.0; return; case 3: *s = (angle > 0.0) ? -1.0 : 1.0; *c = 0.0; return; } } #ifdef HAVE_SINCOS sincos(angle*D2R, s, c); #else *s = sin(angle*D2R); *c = cos(angle*D2R); #endif return; } //---------------------------------------------------------------------------- double tand(double angle) { double resid; resid = fmod(angle,360.0); if (resid == 0.0 || fabs(resid) == 180.0) { return 0.0; } else if (resid == 45.0 || resid == 225.0) { return 1.0; } else if (resid == -135.0 || resid == -315.0) { return -1.0; } return tan(angle*D2R); } //---------------------------------------------------------------------------- double acosd(double v) { if (v >= 1.0) { if (v-1.0 < WCSTRIG_TOL) return 0.0; } else if (v == 0.0) { return 90.0; } else if (v <= -1.0) { if (v+1.0 > -WCSTRIG_TOL) return 180.0; } return acos(v)*R2D; } //---------------------------------------------------------------------------- double asind(double v) { if (v <= -1.0) { if (v+1.0 > -WCSTRIG_TOL) return -90.0; } else if (v == 0.0) { return 0.0; } else if (v >= 1.0) { if (v-1.0 < WCSTRIG_TOL) return 90.0; } return asin(v)*R2D; } //---------------------------------------------------------------------------- double atand(double v) { if (v == -1.0) { return -45.0; } else if (v == 0.0) { return 0.0; } else if (v == 1.0) { return 45.0; } return atan(v)*R2D; } //---------------------------------------------------------------------------- double atan2d(double y, double x) { if (y == 0.0) { if (x >= 0.0) { return 0.0; } else if (x < 0.0) { return 180.0; } } else if (x == 0.0) { if (y > 0.0) { return 90.0; } else if (y < 0.0) { return -90.0; } } return atan2(y,x)*R2D; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/wcstrig.h0000644000175100001710000001405200000000000017217 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcstrig.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the wcstrig routines * ------------------------------- * When dealing with celestial coordinate systems and spherical projections * (some moreso than others) it is often desirable to use an angular measure * that provides an exact representation of the latitude of the north or south * pole. The WCSLIB routines use the following trigonometric functions that * take or return angles in degrees: * * - cosd() * - sind() * - tand() * - acosd() * - asind() * - atand() * - atan2d() * - sincosd() * * These "trigd" routines are expected to handle angles that are a multiple of * 90 degrees returning an exact result. Some C implementations provide these * as part of a system library and in such cases it may (or may not!) be * preferable to use them. WCSLIB provides wrappers on the standard trig * functions based on radian measure, adding tests for multiples of 90 degrees. * * However, wcstrig.h also provides the choice of using preprocessor macro * implementations of the trigd functions that don't test for multiples of * 90 degrees (compile with -DWCSTRIG_MACRO). These are typically 20% faster * but may lead to problems near the poles. * * * cosd() - Cosine of an angle in degrees * -------------------------------------- * cosd() returns the cosine of an angle given in degrees. * * Given: * angle double [deg]. * * Function return value: * double Cosine of the angle. * * * sind() - Sine of an angle in degrees * ------------------------------------ * sind() returns the sine of an angle given in degrees. * * Given: * angle double [deg]. * * Function return value: * double Sine of the angle. * * * sincosd() - Sine and cosine of an angle in degrees * -------------------------------------------------- * sincosd() returns the sine and cosine of an angle given in degrees. * * Given: * angle double [deg]. * * Returned: * sin *double Sine of the angle. * * cos *double Cosine of the angle. * * Function return value: * void * * * tand() - Tangent of an angle in degrees * --------------------------------------- * tand() returns the tangent of an angle given in degrees. * * Given: * angle double [deg]. * * Function return value: * double Tangent of the angle. * * * acosd() - Inverse cosine, returning angle in degrees * ---------------------------------------------------- * acosd() returns the inverse cosine in degrees. * * Given: * x double in the range [-1,1]. * * Function return value: * double Inverse cosine of x [deg]. * * * asind() - Inverse sine, returning angle in degrees * -------------------------------------------------- * asind() returns the inverse sine in degrees. * * Given: * y double in the range [-1,1]. * * Function return value: * double Inverse sine of y [deg]. * * * atand() - Inverse tangent, returning angle in degrees * ----------------------------------------------------- * atand() returns the inverse tangent in degrees. * * Given: * s double * * Function return value: * double Inverse tangent of s [deg]. * * * atan2d() - Polar angle of (x,y), in degrees * ------------------------------------------- * atan2d() returns the polar angle, beta, in degrees, of polar coordinates * (rho,beta) corresponding to Cartesian coordinates (x,y). It is equivalent * to the arg(x,y) function of WCS Paper II, though with transposed arguments. * * Given: * y double Cartesian y-coordinate. * * x double Cartesian x-coordinate. * * Function return value: * double Polar angle of (x,y) [deg]. * *===========================================================================*/ #ifndef WCSLIB_WCSTRIG #define WCSLIB_WCSTRIG #include #include "wcsconfig.h" #ifdef HAVE_SINCOS void sincos(double angle, double *sin, double *cos); #endif #ifdef __cplusplus extern "C" { #endif #ifdef WCSTRIG_MACRO // Macro implementation of the trigd functions. #include "wcsmath.h" #define cosd(X) cos((X)*D2R) #define sind(X) sin((X)*D2R) #define tand(X) tan((X)*D2R) #define acosd(X) acos(X)*R2D #define asind(X) asin(X)*R2D #define atand(X) atan(X)*R2D #define atan2d(Y,X) atan2(Y,X)*R2D #ifdef HAVE_SINCOS #define sincosd(X,S,C) sincos((X)*D2R,(S),(C)) #else #define sincosd(X,S,C) *(S) = sin((X)*D2R); *(C) = cos((X)*D2R); #endif #else // Use WCSLIB wrappers or native trigd functions. double cosd(double angle); double sind(double angle); void sincosd(double angle, double *sin, double *cos); double tand(double angle); double acosd(double x); double asind(double y); double atand(double s); double atan2d(double y, double x); // Domain tolerance for asin() and acos() functions. #define WCSTRIG_TOL 1e-10 #endif // WCSTRIG_MACRO #ifdef __cplusplus } #endif #endif // WCSLIB_WCSTRIG ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/wcsulex.l0000644000175100001710000004634600000000000017246 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcsulex.l,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * wcsulex.l is a Flex description file containing the definition of a * recursive, multi-buffered lexical scanner and parser for FITS units * specifications. * * It requires Flex v2.5.4 or later. * * Refer to wcsunits.h for a description of the user interface and operating * notes. * *===========================================================================*/ /* Options. */ %option full %option never-interactive %option noinput %option noyywrap %option outfile="wcsulex.c" %option prefix="wcsulex" %option reentrant %option extra-type="struct wcsulex_extra *" /* Exponents. */ INTEGER [+-]?[1-9][0-9]* FRAC {INTEGER}"/"[1-9][0-9]* FLOAT [+-]?([0-9]+\.?[0-9]*|\.[0-9]+) /* Metric prefixes. */ SUB3 [munpfazy] SUBPREFIX [dc]|{SUB3} SUP3 [kMGTPEZY] SUPPREFIX da|h|{SUP3} PREFIX {SUBPREFIX}|{SUPPREFIX} /* Basic and derived SI units. */ BASIC m|s|g|rad|sr|K|A|mol|cd DERIVED Hz|J|W|V|N|Pa|C|[Oo]hm|S|F|Wb|T|H|lm|lx SI_UNIT {BASIC}|{DERIVED} /* Additional recognized units: all metric prefixes allowed. */ ADD_ALL eV|Jy|R|G|barn /* Additional recognized units: only super-metric prefixes allowed. */ ADD_SUP a|yr|pc|bit|[bB]yte /* Additional recognized units: only sub-metric prefixes allowed. */ ADD_SUB mag /* Additional recognized units for which NO metric prefixes are allowed. */ GENERAL deg|arcmin|arcsec|mas|turn|min|h|d|cy|erg|Ry|u|D ASTRO [Aa]ngstrom|AU|lyr|beam|solRad|solMass|solLum|Sun DEVICE adu|bin|chan|count|ct|photon|ph|pixel|pix|voxel ADD_NONE {GENERAL}|{ASTRO}|{DEVICE} /* All additional recognized units. */ ADD_UNIT {ADD_ALL}|{ADD_SUP}|{ADD_SUB}|{ADD_NONE} /* Exclusive start states. */ %x PAREN PREFIX UNITS EXPON FLUSH %{ #include #include #include #include #include "wcserr.h" #include "wcsmath.h" #include "wcsunits.h" #include "wcsutil.h" // User data associated with yyscanner. struct wcsulex_extra { // Used in preempting the call to exit() by yy_fatal_error(). jmp_buf abort_jmp_env; }; #define YY_DECL int wcsulexe_scanner(const char unitstr[], int *func, \ double *scale, double units[WCSUNITS_NTYPE], struct wcserr **err, \ yyscan_t yyscanner) // Dummy definition to circumvent compiler warnings. #define YY_INPUT(inbuff, count, bufsize) { count = YY_NULL; } // Preempt the call to exit() by yy_fatal_error(). #define exit(status) longjmp(yyextra->abort_jmp_env, status); // Internal helper functions. static YY_DECL; %} %% static const char *function = "wcsulexe_scanner"; void add(double *factor, double types[], double *expon, double *scale, double units[]); // Initialise returned values. *func = 0; *scale = 1.0; for (int i = 0; i < WCSUNITS_NTYPE; i++) { units[i] = 0.0; } if (err) *err = 0x0; double types[WCSUNITS_NTYPE]; for (int i = 0; i < WCSUNITS_NTYPE; i++) { types[i] = 0.0; } double expon = 1.0; double factor = 1.0; int bracket = 0; int operator = 0; int paren = 0; int status = 0; // Avert a flex-induced memory leak. if (YY_CURRENT_BUFFER && YY_CURRENT_BUFFER->yy_input_file == stdin) { yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner); } yy_scan_string(unitstr, yyscanner); // Return here via longjmp() invoked by yy_fatal_error(). if (setjmp(yyextra->abort_jmp_env)) { return wcserr_set(WCSERR_SET(UNITSERR_PARSER_ERROR), "Internal units parser error parsing '%s'", unitstr); } BEGIN(INITIAL); #ifdef DEBUG fprintf(stderr, "\n%s ->\n", unitstr); #endif ^" "+ { // Pretend initial whitespace doesn't exist. yy_set_bol(1); } ^"[" { if (bracket++) { BEGIN(FLUSH); } else { yy_set_bol(1); } } ^10[0-9] { status = wcserr_set(WCSERR_SET(UNITSERR_BAD_NUM_MULTIPLIER), "Invalid exponent in '%s'", unitstr); BEGIN(FLUSH); } ^10 { factor = 10.0; BEGIN(EXPON); } ^log" "*"(" { *func = 1; unput('('); BEGIN(PAREN); } ^ln" "*"(" { *func = 2; unput('('); BEGIN(PAREN); } ^exp" "*"(" { *func = 3; unput('('); BEGIN(PAREN); } ^[*.] { // Leading binary multiply. status = wcserr_set(WCSERR_SET(UNITSERR_DANGLING_BINOP), "Dangling binary operator in '%s'", unitstr); BEGIN(FLUSH); } " "+ // Discard whitespace in INITIAL context. sqrt" "*"(" { expon /= 2.0; unput('('); BEGIN(PAREN); } "(" { // Gather terms in parentheses. yyless(0); BEGIN(PAREN); } [*.] { if (operator++) { BEGIN(FLUSH); } } ^1"/" | "/" { if (operator++) { BEGIN(FLUSH); } else { expon *= -1.0; } } {SI_UNIT}|{ADD_UNIT} { operator = 0; yyless(0); BEGIN(UNITS); } {PREFIX}({SI_UNIT}|{ADD_ALL}) | {SUPPREFIX}{ADD_SUP} | {SUBPREFIX}{ADD_SUB} { operator = 0; yyless(0); BEGIN(PREFIX); } "]" { bracket = !bracket; BEGIN(FLUSH); } . { status = wcserr_set(WCSERR_SET(UNITSERR_BAD_INITIAL_SYMBOL), "Invalid symbol in INITIAL context in '%s'", unitstr); BEGIN(FLUSH); } "(" { paren++; operator = 0; yymore(); } ")" { paren--; if (paren) { // Not balanced yet. yymore(); } else { // Balanced; strip off the outer parentheses and recurse. yytext[yyleng-1] = '\0'; int func_r; double factor_r; status = wcsulexe(yytext+1, &func_r, &factor_r, types, err); YY_BUFFER_STATE buf = YY_CURRENT_BUFFER; yy_switch_to_buffer(buf, yyscanner); if (func_r) { status = wcserr_set(WCSERR_SET(UNITSERR_FUNCTION_CONTEXT), "Function in invalid context in '%s'", unitstr); } if (status) { BEGIN(FLUSH); } else { factor *= factor_r; BEGIN(EXPON); } } } [^()]+ { yymore(); } d { factor = 1e-1; BEGIN(UNITS); } c { factor = 1e-2; BEGIN(UNITS); } m { factor = 1e-3; BEGIN(UNITS); } u { factor = 1e-6; BEGIN(UNITS); } n { factor = 1e-9; BEGIN(UNITS); } p { factor = 1e-12; BEGIN(UNITS); } f { factor = 1e-15; BEGIN(UNITS); } a { factor = 1e-18; BEGIN(UNITS); } z { factor = 1e-21; BEGIN(UNITS); } y { factor = 1e-24; BEGIN(UNITS); } da { factor = 1e+1; BEGIN(UNITS); } h { factor = 1e+2; BEGIN(UNITS); } k { factor = 1e+3; BEGIN(UNITS); } M { factor = 1e+6; BEGIN(UNITS); } G { factor = 1e+9; BEGIN(UNITS); } T { factor = 1e+12; BEGIN(UNITS); } P { factor = 1e+15; BEGIN(UNITS); } E { factor = 1e+18; BEGIN(UNITS); } Z { factor = 1e+21; BEGIN(UNITS); } Y { factor = 1e+24; BEGIN(UNITS); } . { // Internal parser error. status = wcserr_set(WCSERR_SET(UNITSERR_PARSER_ERROR), "Internal units parser error parsing '%s'", unitstr); BEGIN(FLUSH); } A { // Ampere. types[WCSUNITS_CHARGE] += 1.0; types[WCSUNITS_TIME] -= 1.0; BEGIN(EXPON); } a|yr { // Julian year (annum). factor *= 31557600.0; types[WCSUNITS_TIME] += 1.0; BEGIN(EXPON); } adu { // Analogue-to-digital converter units. types[WCSUNITS_COUNT] += 1.0; BEGIN(EXPON); } [Aa]ngstrom { // Angstrom. factor *= 1e-10; types[WCSUNITS_LENGTH] += 1.0; BEGIN(EXPON); } arcmin { // Minute of arc. factor /= 60.0; types[WCSUNITS_PLANE_ANGLE] += 1.0; BEGIN(EXPON); } arcsec { // Second of arc. factor /= 3600.0; types[WCSUNITS_PLANE_ANGLE] += 1.0; BEGIN(EXPON); } AU { // Astronomical unit. factor *= 1.49598e+11; types[WCSUNITS_LENGTH] += 1.0; BEGIN(EXPON); } barn { // Barn. factor *= 1e-28; types[WCSUNITS_LENGTH] += 2.0; BEGIN(EXPON); } beam { // Beam, as in Jy/beam. types[WCSUNITS_BEAM] += 1.0; BEGIN(EXPON); } bin { // Bin (e.g. histogram). types[WCSUNITS_BIN] += 1.0; BEGIN(EXPON); } bit { // Bit. types[WCSUNITS_BIT] += 1.0; BEGIN(EXPON); } [bB]yte { // Byte. factor *= 8.0; types[WCSUNITS_BIT] += 1.0; BEGIN(EXPON); } C { // Coulomb. types[WCSUNITS_CHARGE] += 1.0; BEGIN(EXPON); } cd { // Candela. types[WCSUNITS_LUMINTEN] += 1.0; BEGIN(EXPON); } chan { // Channel. types[WCSUNITS_BIN] += 1.0; BEGIN(EXPON); } count|ct { // Count. types[WCSUNITS_COUNT] += 1.0; BEGIN(EXPON); } cy { // Julian century. factor *= 3155760000.0; types[WCSUNITS_TIME] += 1.0; BEGIN(EXPON); } D { // Debye. factor *= 1e-29 / 3.0; types[WCSUNITS_CHARGE] += 1.0; types[WCSUNITS_LENGTH] += 1.0; BEGIN(EXPON); } d { // Day. factor *= 86400.0; types[WCSUNITS_TIME] += 1.0; BEGIN(EXPON); } deg { // Degree. types[WCSUNITS_PLANE_ANGLE] += 1.0; BEGIN(EXPON); } erg { // Erg. factor *= 1e-7; types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_LENGTH] += 2.0; types[WCSUNITS_TIME] -= 2.0; BEGIN(EXPON); } eV { // Electron volt. factor *= 1.6021765e-19; types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_LENGTH] += 2.0; types[WCSUNITS_TIME] -= 2.0; BEGIN(EXPON); } F { // Farad. types[WCSUNITS_MASS] -= 1.0; types[WCSUNITS_LENGTH] -= 2.0; types[WCSUNITS_TIME] += 3.0; types[WCSUNITS_CHARGE] += 2.0; BEGIN(EXPON); } G { // Gauss. factor *= 1e-4; types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_TIME] += 1.0; types[WCSUNITS_CHARGE] -= 1.0; BEGIN(EXPON); } g { // Gram. factor *= 1e-3; types[WCSUNITS_MASS] += 1.0; BEGIN(EXPON); } H { // Henry. types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_LENGTH] += 2.0; types[WCSUNITS_TIME] += 2.0; types[WCSUNITS_CHARGE] -= 2.0; BEGIN(EXPON); } h { // Hour. factor *= 3600.0; types[WCSUNITS_TIME] += 1.0; BEGIN(EXPON); } Hz { // Hertz. types[WCSUNITS_TIME] -= 1.0; BEGIN(EXPON); } J { // Joule. types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_LENGTH] += 2.0; types[WCSUNITS_TIME] -= 2.0; BEGIN(EXPON); } Jy { // Jansky. factor *= 1e-26; types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_TIME] -= 2.0; BEGIN(EXPON); } K { // Kelvin. types[WCSUNITS_TEMPERATURE] += 1.0; BEGIN(EXPON); } lm { // Lumen. types[WCSUNITS_LUMINTEN] += 1.0; types[WCSUNITS_SOLID_ANGLE] += 1.0; BEGIN(EXPON); } lx { // Lux. types[WCSUNITS_LUMINTEN] += 1.0; types[WCSUNITS_SOLID_ANGLE] += 1.0; types[WCSUNITS_LENGTH] -= 2.0; BEGIN(EXPON); } lyr { // Light year. factor *= 2.99792458e8 * 31557600.0; types[WCSUNITS_LENGTH] += 1.0; BEGIN(EXPON); } m { // Metre. types[WCSUNITS_LENGTH] += 1.0; BEGIN(EXPON); } mag { // Stellar magnitude. types[WCSUNITS_MAGNITUDE] += 1.0; BEGIN(EXPON); } mas { // Milli-arcsec. factor /= 3600e+3; types[WCSUNITS_PLANE_ANGLE] += 1.0; BEGIN(EXPON); } min { // Minute. factor *= 60.0; types[WCSUNITS_TIME] += 1.0; BEGIN(EXPON); } mol { // Mole. types[WCSUNITS_MOLE] += 1.0; BEGIN(EXPON); } N { // Newton. types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_LENGTH] += 1.0; types[WCSUNITS_TIME] -= 2.0; BEGIN(EXPON); } [Oo]hm { // Ohm. types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_LENGTH] += 2.0; types[WCSUNITS_TIME] -= 1.0; types[WCSUNITS_CHARGE] -= 2.0; BEGIN(EXPON); } Pa { // Pascal. types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_LENGTH] -= 1.0; types[WCSUNITS_TIME] -= 2.0; BEGIN(EXPON); } pc { // Parsec. factor *= 3.0857e16; types[WCSUNITS_LENGTH] += 1.0; BEGIN(EXPON); } photon|ph { // Photon. types[WCSUNITS_COUNT] += 1.0; BEGIN(EXPON); } pixel|pix { // Pixel. types[WCSUNITS_PIXEL] += 1.0; BEGIN(EXPON); } R { // Rayleigh. factor *= 1e10 / (4.0 * PI); types[WCSUNITS_LENGTH] -= 2.0; types[WCSUNITS_TIME] -= 1.0; types[WCSUNITS_SOLID_ANGLE] -= 1.0; BEGIN(EXPON); } rad { // Radian. factor *= 180.0 / PI; types[WCSUNITS_PLANE_ANGLE] += 1.0; BEGIN(EXPON); } Ry { // Rydberg. factor *= 13.605692 * 1.6021765e-19; types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_LENGTH] += 2.0; types[WCSUNITS_TIME] -= 2.0; BEGIN(EXPON); } S { // Siemen. types[WCSUNITS_MASS] -= 1.0; types[WCSUNITS_LENGTH] -= 2.0; types[WCSUNITS_TIME] += 1.0; types[WCSUNITS_CHARGE] += 2.0; BEGIN(EXPON); } s { // Second. types[WCSUNITS_TIME] += 1.0; BEGIN(EXPON); } solLum { // Solar luminosity. factor *= 3.8268e26; types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_LENGTH] += 2.0; types[WCSUNITS_TIME] -= 3.0; BEGIN(EXPON); } solMass { // Solar mass. factor *= 1.9891e30; types[WCSUNITS_MASS] += 1.0; BEGIN(EXPON); } solRad { // Solar radius. factor *= 6.9599e8; types[WCSUNITS_LENGTH] += 1.0; BEGIN(EXPON); } sr { // Steradian. types[WCSUNITS_SOLID_ANGLE] += 1.0; BEGIN(EXPON); } Sun { // Sun (with respect to). types[WCSUNITS_SOLRATIO] += 1.0; BEGIN(EXPON); } T { // Tesla. types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_TIME] += 1.0; types[WCSUNITS_CHARGE] -= 1.0; BEGIN(EXPON); } turn { // Turn. factor *= 360.0; types[WCSUNITS_PLANE_ANGLE] += 1.0; BEGIN(EXPON); } u { // Unified atomic mass unit. factor *= 1.6605387e-27; types[WCSUNITS_MASS] += 1.0; BEGIN(EXPON); } V { // Volt. types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_LENGTH] += 1.0; types[WCSUNITS_TIME] -= 2.0; types[WCSUNITS_CHARGE] -= 1.0; BEGIN(EXPON); } voxel { // Voxel. types[WCSUNITS_VOXEL] += 1.0; BEGIN(EXPON); } W { // Watt. types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_LENGTH] += 2.0; types[WCSUNITS_TIME] -= 3.0; BEGIN(EXPON); } Wb { // Weber. types[WCSUNITS_MASS] += 1.0; types[WCSUNITS_LENGTH] += 2.0; types[WCSUNITS_TIME] += 1.0; types[WCSUNITS_CHARGE] -= 1.0; BEGIN(EXPON); } . { // Internal parser error. status = wcserr_set(WCSERR_SET(UNITSERR_PARSER_ERROR), "Internal units parser error parsing '%s'", unitstr); BEGIN(FLUSH); } " "*("**"|^) { // Exponentiation. if (operator++) { BEGIN(FLUSH); } } " "*{INTEGER} { int i; sscanf(yytext, " %d", &i); expon *= (double)i; add(&factor, types, &expon, scale, units); operator = 0; BEGIN(INITIAL); } " "*"("" "*{INTEGER}" "*")" { int i; sscanf(yytext, " (%d)", &i); expon *= (double)i; add(&factor, types, &expon, scale, units); operator = 0; BEGIN(INITIAL); } " "*"("" "*{FRAC}" "*")" { int i, j; sscanf(yytext, " (%d/%d)", &i, &j); expon *= (double)i / (double)j; add(&factor, types, &expon, scale, units); operator = 0; BEGIN(INITIAL); } " "*"("" "*{FLOAT}" "*")" { char ctmp[72]; sscanf(yytext, " (%s)", ctmp); double dexp; wcsutil_str2double(ctmp, &dexp); expon *= dexp; add(&factor, types, &expon, scale, units); operator = 0; BEGIN(INITIAL); } " "*[.*]" "* { // Multiply. if (operator++) { BEGIN(FLUSH); } else { add(&factor, types, &expon, scale, units); BEGIN(INITIAL); } } " "*"(" { // Multiply. if (operator) { BEGIN(FLUSH); } else { add(&factor, types, &expon, scale, units); unput('('); BEGIN(INITIAL); } } " "+ { // Multiply. if (operator) { BEGIN(FLUSH); } else { add(&factor, types, &expon, scale, units); BEGIN(INITIAL); } } " "*"/"" "* { // Divide. if (operator++) { BEGIN(FLUSH); } else { add(&factor, types, &expon, scale, units); expon = -1.0; BEGIN(INITIAL); } } " "*"]" { add(&factor, types, &expon, scale, units); bracket = !bracket; BEGIN(FLUSH); } . { status = wcserr_set(WCSERR_SET(UNITSERR_BAD_EXPON_SYMBOL), "Invalid symbol in EXPON context in '%s'", unitstr); BEGIN(FLUSH); } .* { // Discard any remaining input. } <> { // End-of-string. if (YY_START == EXPON) { add(&factor, types, &expon, scale, units); } if (bracket) { status = wcserr_set(WCSERR_SET(UNITSERR_UNBAL_BRACKET), "Unbalanced bracket in '%s'", unitstr); } else if (paren) { status = wcserr_set(WCSERR_SET(UNITSERR_UNBAL_PAREN), "Unbalanced parenthesis in '%s'", unitstr); } else if (operator == 1) { status = wcserr_set(WCSERR_SET(UNITSERR_DANGLING_BINOP), "Dangling binary operator in '%s'", unitstr); } else if (operator) { status = wcserr_set(WCSERR_SET(UNITSERR_CONSEC_BINOPS), "Consecutive binary operators in '%s'", unitstr); #ifdef DEBUG } else { fprintf(stderr, "EOS\n"); #endif } if (status) { for (int i = 0; i < WCSUNITS_NTYPE; i++) { units[i] = 0.0; *scale = 0.0; } } return status; } %% /*---------------------------------------------------------------------------- * External interface to the scanner. *---------------------------------------------------------------------------*/ int wcsulexe( const char unitstr[], int *func, double *scale, double units[WCSUNITS_NTYPE], struct wcserr **err) { // Function prototypes. int yylex_init_extra(YY_EXTRA_TYPE extra, yyscan_t *yyscanner); int yylex_destroy(yyscan_t yyscanner); struct wcsulex_extra extra; yyscan_t yyscanner; yylex_init_extra(&extra, &yyscanner); int status = wcsulexe_scanner(unitstr, func, scale, units, err, yyscanner); yylex_destroy(yyscanner); return status; } /*---------------------------------------------------------------------------- * Accumulate a term in a units specification and reset work variables. *---------------------------------------------------------------------------*/ void add( double *factor, double types[], double *expon, double *scale, double units[]) { *scale *= pow(*factor, *expon); for (int i = 0; i < WCSUNITS_NTYPE; i++) { units[i] += *expon * types[i]; types[i] = 0.0; } *expon = 1.0; *factor = 1.0; return; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/wcsunits.c0000644000175100001710000001242700000000000017413 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcsunits.c,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *===========================================================================*/ #include #include "wcsunits.h" // Map status return value to message. const char *wcsunits_errmsg[] = { "Success", "Invalid numeric multiplier", "Dangling binary operator", "Invalid symbol in INITIAL context", "Function in invalid context", "Invalid symbol in EXPON context", "Unbalanced bracket", "Unbalanced parenthesis", "Consecutive binary operators", "Internal parser error", "Non-conformant unit specifications", "Non-conformant functions", "Potentially unsafe translation"}; // Unit types. const char *wcsunits_types[] = { "plane angle", "solid angle", "charge", "mole", "temperature", "luminous intensity", "mass", "length", "time", "beam", "bin", "bit", "count", "stellar magnitude", "pixel", "solar ratio", "voxel"}; const char *wcsunits_units[] = { "degree", "steradian", "Coulomb", "mole", "Kelvin", "candela", "kilogram", "metre", "second", "", "", "", "", "", "", "", ""}; const char *wcsunits_funcs[] = { "none", "log", "ln", "exp"}; //---------------------------------------------------------------------------- int wcsunits( const char have[], const char want[], double *scale, double *offset, double *power) { return wcsunitse(have, want, scale, offset, power, 0x0); } //---------------------------------------------------------------------------- int wcsunitse( const char have[], const char want[], double *scale, double *offset, double *power, struct wcserr **err) { static const char *function = "wcsunitse"; int status; int func1; double scale1, units1[WCSUNITS_NTYPE]; if ((status = wcsulexe(have, &func1, &scale1, units1, err))) { return status; } int func2; double scale2, units2[WCSUNITS_NTYPE]; if ((status = wcsulexe(want, &func2, &scale2, units2, err))) { return status; } // Check conformance. for (int i = 0; i < WCSUNITS_NTYPE; i++) { if (units1[i] != units2[i]) { return wcserr_set(WCSERR_SET(UNITSERR_BAD_UNIT_SPEC), "Mismatched units type '%s': have '%s', want '%s'", wcsunits_types[i], have, want); } } *scale = 0.0; *offset = 0.0; *power = 1.0; switch (func1) { case 0: // No function. if (func2) { return wcserr_set(WCSERR_SET(UNITSERR_BAD_FUNCS), "Mismatched unit functions: have '%s' (%s), want '%s' (%s)", have, wcsunits_funcs[func1], want, wcsunits_funcs[func2]); } *scale = scale1 / scale2; break; case 1: // log(). if (func2 == 1) { // log(). *scale = 1.0; *offset = log10(scale1 / scale2); } else if (func2 == 2) { // ln(). *scale = log(10.0); *offset = log(scale1 / scale2); } else { return wcserr_set(WCSERR_SET(UNITSERR_BAD_FUNCS), "Mismatched unit functions: have '%s' (%s), want '%s' (%s)", have, wcsunits_funcs[func1], want, wcsunits_funcs[func2]); } break; case 2: // ln(). if (func2 == 1) { // log(). *scale = 1.0 / log(10.0); *offset = log(scale1 / scale2); } else if (func2 == 2) { // ln(). *scale = 1.0; *offset = log(scale1 / scale2); } else { return wcserr_set(WCSERR_SET(UNITSERR_BAD_FUNCS), "Mismatched unit functions: have '%s' (%s), want '%s' (%s)", have, wcsunits_funcs[func1], want, wcsunits_funcs[func2]); } break; case 3: // exp(). if (func2 != 3) { return wcserr_set(WCSERR_SET(UNITSERR_BAD_FUNCS), "Mismatched unit functions: have '%s' (%s), want '%s' (%s)", have, wcsunits_funcs[func1], want, wcsunits_funcs[func2]); } *scale = 1.0; *power = scale1 / scale2; break; default: // Internal parser error. return wcserr_set(WCSERR_SET(UNITSERR_PARSER_ERROR), "Internal units parser error"); } return 0; } //---------------------------------------------------------------------------- int wcsutrn(int ctrl, char unitstr[]) { return wcsutrne(ctrl, unitstr, 0x0); } //---------------------------------------------------------------------------- int wcsulex( const char unitstr[], int *func, double *scale, double units[WCSUNITS_NTYPE]) { return wcsulexe(unitstr, func, scale, units, 0x0); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/wcsunits.h0000644000175100001710000004154600000000000017424 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcsunits.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the wcsunits routines * -------------------------------- * Routines in this suite deal with units specifications and conversions, as * described in * = "Representations of world coordinates in FITS", = Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (WCS Paper I) * * The Flexible Image Transport System (FITS), a data format widely used in * astronomy for data interchange and archive, is described in * = "Definition of the Flexible Image Transport System (FITS), version 3.0", = Pence, W.D., Chiappetti, L., Page, C.G., Shaw, R.A., & Stobie, E. 2010, = A&A, 524, A42 - http://dx.doi.org/10.1051/0004-6361/201015362 * * See also http://fits.gsfc.nasa.gov * * These routines perform basic units-related operations: * * - wcsunitse(): given two unit specifications, derive the conversion from * one to the other. * * - wcsutrne(): translates certain commonly used but non-standard unit * strings. It is intended to be called before wcsulexe() which only * handles standard FITS units specifications. * * - wcsulexe(): parses a standard FITS units specification of arbitrary * complexity, deriving the conversion to canonical units. * * * wcsunitse() - FITS units specification conversion * ------------------------------------------------- * wcsunitse() derives the conversion from one system of units to another. * * A deprecated form of this function, wcsunits(), lacks the wcserr** * parameter. * * Given: * have const char [] * FITS units specification to convert from (null- * terminated), with or without surrounding square * brackets (for inline specifications); text following * the closing bracket is ignored. * * want const char [] * FITS units specification to convert to (null- * terminated), with or without surrounding square * brackets (for inline specifications); text following * the closing bracket is ignored. * * Returned: * scale, * offset, * power double* Convert units using * = pow(scale*value + offset, power); * * Normally offset is zero except for log() or ln() * conversions, e.g. "log(MHz)" to "ln(Hz)". Likewise, * power is normally unity except for exp() conversions, * e.g. "exp(ms)" to "exp(/Hz)". Thus conversions * ordinarily consist of * = value *= scale; * * err struct wcserr ** * If enabled, for function return values > 1, this * struct will contain a detailed error message, see * wcserr_enable(). May be NULL if an error message is * not desired. Otherwise, the user is responsible for * deleting the memory allocated for the wcserr struct. * * Function return value: * int Status return value: * 0: Success. * 1-9: Status return from wcsulexe(). * 10: Non-conformant unit specifications. * 11: Non-conformant functions. * * scale is zeroed on return if an error occurs. * * * wcsutrne() - Translation of non-standard unit specifications * ------------------------------------------------------------ * wcsutrne() translates certain commonly used but non-standard unit strings, * e.g. "DEG", "MHZ", "KELVIN", that are not recognized by wcsulexe(), refer to * the notes below for a full list. Compounds are also recognized, e.g. * "JY/BEAM" and "KM/SEC/SEC". Extraneous embedded blanks are removed. * * A deprecated form of this function, wcsutrn(), lacks the wcserr** parameter. * * Given: * ctrl int Although "S" is commonly used to represent seconds, * its translation to "s" is potentially unsafe since the * standard recognizes "S" formally as Siemens, however * rarely that may be used. The same applies to "H" for * hours (Henry), and "D" for days (Debye). This * bit-flag controls what to do in such cases: * 1: Translate "S" to "s". * 2: Translate "H" to "h". * 4: Translate "D" to "d". * Thus ctrl == 0 doesn't do any unsafe translations, * whereas ctrl == 7 does all of them. * * Given and returned: * unitstr char [] Null-terminated character array containing the units * specification to be translated. * * Inline units specifications in a FITS header * keycomment are also handled. If the first non-blank * character in unitstr is '[' then the unit string is * delimited by its matching ']'. Blanks preceding '[' * will be stripped off, but text following the closing * bracket will be preserved without modification. * * err struct wcserr ** * If enabled, for function return values > 1, this * struct will contain a detailed error message, see * wcserr_enable(). May be NULL if an error message is * not desired. Otherwise, the user is responsible for * deleting the memory allocated for the wcserr struct. * * Function return value: * int Status return value: * -1: No change was made, other than stripping blanks * (not an error). * 0: Success. * 9: Internal parser error. * 12: Potentially unsafe translation, whether applied * or not (see notes). * * Notes: * 1: Translation of non-standard unit specifications: apart from leading and * trailing blanks, a case-sensitive match is required for the aliases * listed below, in particular the only recognized aliases with metric * prefixes are "KM", "KHZ", "MHZ", and "GHZ". Potentially unsafe * translations of "D", "H", and "S", shown in parentheses, are optional. * = Unit Recognized aliases = ---- ---------------------------------------------------------- = Angstrom Angstroms angstrom angstroms = arcmin arcmins, ARCMIN, ARCMINS = arcsec arcsecs, ARCSEC, ARCSECS = beam BEAM = byte Byte = d day, days, (D), DAY, DAYS = deg degree, degrees, Deg, Degree, Degrees, DEG, DEGREE, = DEGREES = GHz GHZ = h hr, (H), HR = Hz hz, HZ = kHz KHZ = Jy JY = K kelvin, kelvins, Kelvin, Kelvins, KELVIN, KELVINS = km KM = m metre, meter, metres, meters, M, METRE, METER, METRES, = METERS = min MIN = MHz MHZ = Ohm ohm = Pa pascal, pascals, Pascal, Pascals, PASCAL, PASCALS = pixel pixels, PIXEL, PIXELS = rad radian, radians, RAD, RADIAN, RADIANS = s sec, second, seconds, (S), SEC, SECOND, SECONDS = V volt, volts, Volt, Volts, VOLT, VOLTS = yr year, years, YR, YEAR, YEARS * * The aliases "angstrom", "ohm", and "Byte" for (Angstrom, Ohm, and byte) * are recognized by wcsulexe() itself as an unofficial extension of the * standard, but they are converted to the standard form here. * * * wcsulexe() - FITS units specification parser * -------------------------------------------- * wcsulexe() parses a standard FITS units specification of arbitrary * complexity, deriving the scale factor required to convert to canonical * units - basically SI with degrees and "dimensionless" additions such as * byte, pixel and count. * * A deprecated form of this function, wcsulex(), lacks the wcserr** parameter. * * Given: * unitstr const char [] * Null-terminated character array containing the units * specification, with or without surrounding square * brackets (for inline specifications); text following * the closing bracket is ignored. * * Returned: * func int* Special function type, see note 4: * 0: None * 1: log() ...base 10 * 2: ln() ...base e * 3: exp() * * scale double* Scale factor for the unit specification; multiply a * value expressed in the given units by this factor to * convert it to canonical units. * * units double[WCSUNITS_NTYPE] * A units specification is decomposed into powers of 16 * fundamental unit types: angle, mass, length, time, * count, pixel, etc. Preprocessor macro WCSUNITS_NTYPE * is defined to dimension this vector, and others such * WCSUNITS_PLANE_ANGLE, WCSUNITS_LENGTH, etc. to access * its elements. * * Corresponding character strings, wcsunits_types[] and * wcsunits_units[], are predefined to describe each * quantity and its canonical units. * * err struct wcserr ** * If enabled, for function return values > 1, this * struct will contain a detailed error message, see * wcserr_enable(). May be NULL if an error message is * not desired. Otherwise, the user is responsible for * deleting the memory allocated for the wcserr struct. * * Function return value: * int Status return value: * 0: Success. * 1: Invalid numeric multiplier. * 2: Dangling binary operator. * 3: Invalid symbol in INITIAL context. * 4: Function in invalid context. * 5: Invalid symbol in EXPON context. * 6: Unbalanced bracket. * 7: Unbalanced parenthesis. * 8: Consecutive binary operators. * 9: Internal parser error. * * scale and units[] are zeroed on return if an error * occurs. * * Notes: * 1: wcsulexe() is permissive in accepting whitespace in all contexts in a * units specification where it does not create ambiguity (e.g. not * between a metric prefix and a basic unit string), including in strings * like "log (m ** 2)" which is formally disallowed. * * 2: Supported extensions: * - "angstrom" (OGIP usage) is allowed in addition to "Angstrom". * - "ohm" (OGIP usage) is allowed in addition to "Ohm". * - "Byte" (common usage) is allowed in addition to "byte". * * 3: Table 6 of WCS Paper I lists eleven units for which metric prefixes are * allowed. However, in this implementation only prefixes greater than * unity are allowed for "a" (annum), "yr" (year), "pc" (parsec), "bit", * and "byte", and only prefixes less than unity are allowed for "mag" * (stellar magnitude). * * Metric prefix "P" (peta) is specifically forbidden for "a" (annum) to * avoid confusion with "Pa" (Pascal, not peta-annum). Note that metric * prefixes are specifically disallowed for "h" (hour) and "d" (day) so * that "ph" (photons) cannot be interpreted as pico-hours, nor "cd" * (candela) as centi-days. * * 4: Function types log(), ln() and exp() may only occur at the start of the * units specification. The scale and units[] returned for these refers * to the string inside the function "argument", e.g. to "MHz" in log(MHz) * for which a scale of 1e6 will be returned. * * * Global variable: const char *wcsunits_errmsg[] - Status return messages * ----------------------------------------------------------------------- * Error messages to match the status value returned from each function. * * * Global variable: const char *wcsunits_types[] - Names of physical quantities * ---------------------------------------------------------------------------- * Names for physical quantities to match the units vector returned by * wcsulexe(): * - 0: plane angle * - 1: solid angle * - 2: charge * - 3: mole * - 4: temperature * - 5: luminous intensity * - 6: mass * - 7: length * - 8: time * - 9: beam * - 10: bin * - 11: bit * - 12: count * - 13: stellar magnitude * - 14: pixel * - 15: solar ratio * - 16: voxel * * * Global variable: const char *wcsunits_units[] - Names of units * -------------------------------------------------------------- * Names for the units (SI) to match the units vector returned by wcsulexe(): * - 0: degree * - 1: steradian * - 2: Coulomb * - 3: mole * - 4: Kelvin * - 5: candela * - 6: kilogram * - 7: metre * - 8: second * * The remainder are dimensionless. *===========================================================================*/ #ifndef WCSLIB_WCSUNITS #define WCSLIB_WCSUNITS #include "wcserr.h" #ifdef __cplusplus extern "C" { #endif extern const char *wcsunits_errmsg[]; enum wcsunits_errmsg_enum { UNITSERR_SUCCESS = 0, // Success. UNITSERR_BAD_NUM_MULTIPLIER = 1, // Invalid numeric multiplier. UNITSERR_DANGLING_BINOP = 2, // Dangling binary operator. UNITSERR_BAD_INITIAL_SYMBOL = 3, // Invalid symbol in INITIAL context. UNITSERR_FUNCTION_CONTEXT = 4, // Function in invalid context. UNITSERR_BAD_EXPON_SYMBOL = 5, // Invalid symbol in EXPON context. UNITSERR_UNBAL_BRACKET = 6, // Unbalanced bracket. UNITSERR_UNBAL_PAREN = 7, // Unbalanced parenthesis. UNITSERR_CONSEC_BINOPS = 8, // Consecutive binary operators. UNITSERR_PARSER_ERROR = 9, // Internal parser error. UNITSERR_BAD_UNIT_SPEC = 10, // Non-conformant unit specifications. UNITSERR_BAD_FUNCS = 11, // Non-conformant functions. UNITSERR_UNSAFE_TRANS = 12 // Potentially unsafe translation. }; extern const char *wcsunits_types[]; extern const char *wcsunits_units[]; #define WCSUNITS_PLANE_ANGLE 0 #define WCSUNITS_SOLID_ANGLE 1 #define WCSUNITS_CHARGE 2 #define WCSUNITS_MOLE 3 #define WCSUNITS_TEMPERATURE 4 #define WCSUNITS_LUMINTEN 5 #define WCSUNITS_MASS 6 #define WCSUNITS_LENGTH 7 #define WCSUNITS_TIME 8 #define WCSUNITS_BEAM 9 #define WCSUNITS_BIN 10 #define WCSUNITS_BIT 11 #define WCSUNITS_COUNT 12 #define WCSUNITS_MAGNITUDE 13 #define WCSUNITS_PIXEL 14 #define WCSUNITS_SOLRATIO 15 #define WCSUNITS_VOXEL 16 #define WCSUNITS_NTYPE 17 int wcsunitse(const char have[], const char want[], double *scale, double *offset, double *power, struct wcserr **err); int wcsutrne(int ctrl, char unitstr[], struct wcserr **err); int wcsulexe(const char unitstr[], int *func, double *scale, double units[WCSUNITS_NTYPE], struct wcserr **err); // Deprecated. int wcsunits(const char have[], const char want[], double *scale, double *offset, double *power); int wcsutrn(int ctrl, char unitstr[]); int wcsulex(const char unitstr[], int *func, double *scale, double units[WCSUNITS_NTYPE]); #ifdef __cplusplus } #endif #endif // WCSLIB_WCSUNITS ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/wcsutil.c0000644000175100001710000002640100000000000017223 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcsutil.c,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *===========================================================================*/ #include #include #include #include #include #include #include "wcsutil.h" #include "wcsmath.h" //---------------------------------------------------------------------------- void wcsdealloc(void *ptr) { free(ptr); return; } //---------------------------------------------------------------------------- void wcsutil_strcvt(int n, char c, int nt, const char src[], char dst[]) { if (n <= 0) return; if (c != '\0') c = ' '; if (src == 0x0) { if (dst) { memset(dst, c, n); } } else { // Copy to the first NULL character. int j; for (j = 0; j < n; j++) { if ((dst[j] = src[j]) == '\0') { break; } } if (j < n) { // The given string is null-terminated. memset(dst+j, c, n-j); } else { // The given string is not null-terminated. if (c == '\0') { // Work backwards, looking for the first non-blank. for (j = n - 1; j >= 0; j--) { if (dst[j] != ' ') { break; } } j++; if (j == n && !nt) { dst[n-1] = '\0'; } else { memset(dst+j, '\0', n-j); } } } } if (nt) dst[n] = '\0'; return; } //---------------------------------------------------------------------------- void wcsutil_blank_fill(int n, char c[]) { if (n <= 0) return; if (c == 0x0) { return; } // Replace the terminating null and all successive characters. for (int j = 0; j < n; j++) { if (c[j] == '\0') { memset(c+j, ' ', n-j); break; } } return; } //---------------------------------------------------------------------------- void wcsutil_null_fill(int n, char c[]) { if (n <= 0) return; if (c == 0x0) { return; } // Find the first NULL character. int j; for (j = 0; j < n; j++) { if (c[j] == '\0') { break; } } // Ensure null-termination. if (j == n) { j = n - 1; c[j] = '\0'; } // Work backwards, looking for the first non-blank. j--; for (; j > 0; j--) { if (c[j] != ' ') { break; } } if (++j < n) { memset(c+j, '\0', n-j); } return; } //---------------------------------------------------------------------------- int wcsutil_all_ival(int nelem, int ival, const int iarr[]) { for (int i = 0; i < nelem; i++) { if (iarr[i] != ival) return 0; } return 1; } //---------------------------------------------------------------------------- int wcsutil_all_dval(int nelem, double dval, const double darr[]) { for (int i = 0; i < nelem; i++) { if (darr[i] != dval) return 0; } return 1; } //---------------------------------------------------------------------------- int wcsutil_all_sval(int nelem, const char *sval, const char (*sarr)[72]) { for (int i = 0; i < nelem; i++) { if (strncmp(sarr[i], sval, 72)) return 0; } return 1; } //---------------------------------------------------------------------------- int wcsutil_allEq(int nvec, int nelem, const double *first) { if (nvec <= 0 || nelem <= 0) return 0; double v0 = *first; for (const double *vp = first+nelem; vp < first + nvec*nelem; vp += nelem) { if (*vp != v0) return 0; } return 1; } //---------------------------------------------------------------------------- int wcsutil_dblEq( int nelem, double tol, const double *darr1, const double *darr2) { if (nelem == 0) return 1; if (nelem < 0) return 0; if (darr1 == 0x0 && darr2 == 0x0) return 1; if (tol == 0.0) { // Handled separately for speed of execution. for (int i = 0; i < nelem; i++) { double dval1 = (darr1 ? darr1[i] : UNDEFINED); double dval2 = (darr2 ? darr2[i] : UNDEFINED); // Undefined values must match exactly. if (dval1 == UNDEFINED && dval2 != UNDEFINED) return 0; if (dval1 != UNDEFINED && dval2 == UNDEFINED) return 0; if (dval1 != dval2) return 0; } } else { for (int i = 0; i < nelem; i++) { double dval1 = (darr1 ? darr1[i] : UNDEFINED); double dval2 = (darr2 ? darr2[i] : UNDEFINED); // Undefined values must match exactly. if (dval1 == UNDEFINED && dval2 != UNDEFINED) return 0; if (dval1 != UNDEFINED && dval2 == UNDEFINED) return 0; // Otherwise, compare within the specified tolerance. if (fabs(dval1 - dval2) > 0.5*tol) return 0; } } return 1; } //---------------------------------------------------------------------------- int wcsutil_intEq(int nelem, const int *iarr1, const int *iarr2) { if (nelem == 0) return 1; if (nelem < 0) return 0; if (iarr1 == 0x0 && iarr2 == 0x0) return 1; for (int i = 0; i < nelem; i++) { int ival1 = (iarr1 ? iarr1[i] : 0); int ival2 = (iarr2 ? iarr2[i] : 0); if (ival1 != ival2) return 0; } return 1; } //---------------------------------------------------------------------------- int wcsutil_strEq(int nelem, char (*sarr1)[72], char (*sarr2)[72]) { if (nelem == 0) return 1; if (nelem < 0) return 0; if (sarr1 == 0x0 && sarr2 == 0x0) return 1; for (int i = 0; i < nelem; i++) { char *sval1 = (sarr1 ? sarr1[i] : ""); char *sval2 = (sarr2 ? sarr2[i] : ""); if (strncmp(sval1, sval2, 72)) return 0; } return 1; } //---------------------------------------------------------------------------- void wcsutil_setAll(int nvec, int nelem, double *first) { if (nvec <= 0 || nelem <= 0) return; double v0 = *first; for (double *vp = first+nelem; vp < first + nvec*nelem; vp += nelem) { *vp = v0; } } //---------------------------------------------------------------------------- void wcsutil_setAli(int nvec, int nelem, int *first) { if (nvec <= 0 || nelem <= 0) return; int v0 = *first; for (int *vp = first+nelem; vp < first + nvec*nelem; vp += nelem) { *vp = v0; } } //---------------------------------------------------------------------------- void wcsutil_setBit(int nelem, const int *sel, int bits, int *array) { if (bits == 0 || nelem <= 0) return; if (sel == 0x0) { // All elements selected. for (int *arrp = array; arrp < array + nelem; arrp++) { *arrp |= bits; } } else { // Some elements selected. for (int *arrp = array; arrp < array + nelem; arrp++) { if (*(sel++)) *arrp |= bits; } } } //---------------------------------------------------------------------------- char *wcsutil_fptr2str(void (*fptr)(void), char hext[19]) { // Test for little-endian addresses. int *(ip[2]), j[2], le = 1; ip[0] = j; ip[1] = j + 1; unsigned char *p = (unsigned char *)(&fptr); if ((unsigned char *)ip[0] < (unsigned char *)ip[1]) { // Little-endian, reverse it. p += sizeof(fptr) - 1; le = -1; } char *t = hext; sprintf(t, "0x0"); t += 2; int gotone = 0; for (size_t i = 0; i < sizeof(fptr); i++) { // Skip leading zeroes. if (*p) gotone = 1; if (gotone) { sprintf(t, "%02x", *p); t += 2; } p += le; } return hext; } //---------------------------------------------------------------------------- static void wcsutil_locale_to_dot(char *buf) { struct lconv *locale_data = localeconv(); const char *decimal_point = locale_data->decimal_point; if (decimal_point[0] != '.' || decimal_point[1] != 0) { size_t decimal_point_len = strlen(decimal_point); char *inbuf = buf; char *outbuf = buf; for ( ; *inbuf; inbuf++) { if (strncmp(inbuf, decimal_point, decimal_point_len) == 0) { *outbuf++ = '.'; inbuf += decimal_point_len - 1; } else { *outbuf++ = *inbuf; } } *outbuf = '\0'; } } void wcsutil_double2str(char *buf, const char *format, double value) { sprintf(buf, format, value); wcsutil_locale_to_dot(buf); // Look for a decimal point or exponent. char *bp = buf; while (*bp) { if (*bp != ' ') { if (*bp == '.') return; if (*bp == 'e') return; if (*bp == 'E') return; } bp++; } // Not found, add a fractional part. bp = buf; if (*bp == ' ') { char *cp = buf + 1; if (*cp == ' ') cp++; while (*cp) { *bp = *cp; bp++; cp++; } *bp = '.'; bp++; if (bp < cp) *bp = '0'; } } //---------------------------------------------------------------------------- static const char *wcsutil_dot_to_locale(const char *inbuf, char *outbuf) { struct lconv *locale_data = localeconv(); const char *decimal_point = locale_data->decimal_point; if (decimal_point[0] != '.' || decimal_point[1] != 0) { char *out = outbuf; size_t decimal_point_len = strlen(decimal_point); for ( ; *inbuf; inbuf++) { if (*inbuf == '.') { memcpy(out, decimal_point, decimal_point_len); out += decimal_point_len; } else { *out++ = *inbuf; } } *out = '\0'; return outbuf; } else { return inbuf; } } int wcsutil_str2double(const char *buf, double *value) { char ctmp[72]; return sscanf(wcsutil_dot_to_locale(buf, ctmp), "%lf", value) < 1; } int wcsutil_str2double2(const char *buf, double *value) { value[0] = 0.0; value[1] = 0.0; // Get the integer part. char ltmp[72]; if (sscanf(wcsutil_dot_to_locale(buf, ltmp), "%lf", value) < 1) { return 1; } value[0] = floor(value[0]); char ctmp[72]; strcpy(ctmp, buf); // Look for a decimal point. char *dptr = strchr(ctmp, '.'); // Look for an exponent. char *eptr; if ((eptr = strchr(ctmp, 'E')) == NULL) { if ((eptr = strchr(ctmp, 'D')) == NULL) { if ((eptr = strchr(ctmp, 'e')) == NULL) { eptr = strchr(ctmp, 'd'); } } } int exp = 0; if (eptr) { // Get the exponent. if (sscanf(eptr+1, "%d", &exp) < 1) { return 1; } if (!dptr) { dptr = eptr; eptr++; } if (dptr+exp <= ctmp) { // There is only a fractional part. return sscanf(wcsutil_dot_to_locale(buf, ctmp), "%lf", value+1) < 1; } else if (eptr <= dptr+exp+1) { // There is no fractional part. return 0; } } // Get the fractional part. if (dptr) { char *cptr = ctmp; while (cptr <= dptr+exp) { if ('0' < *cptr && *cptr <= '9') *cptr = '0'; cptr++; } if (sscanf(wcsutil_dot_to_locale(ctmp, ltmp), "%lf", value+1) < 1) { return 1; } } return 0; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/wcsutil.h0000644000175100001710000004172400000000000017235 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcsutil.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the wcsutil routines * ------------------------------- * Simple utility functions. With the exception of wcsdealloc(), these * functions are intended for internal use only by WCSLIB. * * The internal-use functions are documented here solely as an aid to * understanding the code. They are not intended for external use - the API * may change without notice! * * * wcsdealloc() - free memory allocated by WCSLIB functions * -------------------------------------------------------- * wcsdealloc() invokes the free() system routine to free memory. * Specifically, it is intended to free memory allocated (using calloc()) by * certain WCSLIB functions (e.g. wcshdo(), wcsfixi(), fitshdr()), which it is * the user's responsibility to deallocate. * * In certain situations, for example multithreading, it may be important that * this be done within the WCSLIB sharable library's runtime environment. * * PLEASE NOTE: wcsdealloc() must not be used in place of the destructors for * particular structs, such as wcsfree(), celfree(), etc. * * Given and returned: * ptr void* Address of the allocated memory. * * Function return value: * void * * * wcsutil_strcvt() - Copy character string with padding * ----------------------------------------------------- * INTERNAL USE ONLY. * * wcsutil_strcvt() copies one character string to another up to the specified * maximum number of characters. * * If the given string is null-terminated, then the NULL character copied to * the returned string, and all characters following it up to the specified * maximum, are replaced with the specified substitute character, either blank * or NULL. * * If the source string is not null-terminated and the substitute character is * blank, then copy the maximum number of characters and do nothing further. * However, if the substitute character is NULL, then the last character and * all consecutive blank characters preceding it will be replaced with NULLs. * * Used by the Fortran wrapper functions in translating C strings into Fortran * CHARACTER variables and vice versa. * * Given: * n int Maximum number of characters to copy. * * c char Substitute character, either NULL or blank (anything * other than NULL). * * nt int If true, then dst is of length n+1, with the last * character always set to NULL. * * src char[] Character string to be copied. If null-terminated, * then need not be of length n, otherwise it must be. * * Returned: * dst char[] Destination character string, which must be long * enough to hold n characters. Note that this string * will not be null-terminated if the substitute * character is blank. * * Function return value: * void * * * wcsutil_blank_fill() - Fill a character string with blanks * ---------------------------------------------------------- * INTERNAL USE ONLY. * * wcsutil_blank_fill() pads a character sub-string with blanks starting with * the terminating NULL character (if any). * * Given: * n int Length of the sub-string. * * Given and returned: * c char[] The character sub-string, which will not be * null-terminated on return. * * Function return value: * void * * * wcsutil_null_fill() - Fill a character string with NULLs * -------------------------------------------------------- * INTERNAL USE ONLY. * * wcsutil_null_fill() strips trailing blanks from a string (or sub-string) and * propagates the terminating NULL character (if any) to the end of the string. * * If the string is not null-terminated, then the last character and all * consecutive blank characters preceding it will be replaced with NULLs. * * Mainly used in the C library to strip trailing blanks from FITS keyvalues. * Also used to make character strings intelligible in the GNU debugger, which * prints the rubbish following the terminating NULL character, thereby * obscuring the valid part of the string. * * Given: * n int Number of characters. * * Given and returned: * c char[] The character (sub-)string. * * Function return value: * void * * * wcsutil_all_ival() - Test if all elements an int array have a given value * ------------------------------------------------------------------------- * INTERNAL USE ONLY. * * wcsutil_all_ival() tests whether all elements of an array of type int all * have the specified value. * * Given: * nelem int The length of the array. * * ival int Value to be tested. * * iarr const int[] * Pointer to the first element of the array. * * Function return value: * int Status return value: * 0: Not all equal. * 1: All equal. * * * wcsutil_all_dval() - Test if all elements a double array have a given value * --------------------------------------------------------------------------- * INTERNAL USE ONLY. * * wcsutil_all_dval() tests whether all elements of an array of type double all * have the specified value. * * Given: * nelem int The length of the array. * * dval int Value to be tested. * * darr const double[] * Pointer to the first element of the array. * * Function return value: * int Status return value: * 0: Not all equal. * 1: All equal. * * * wcsutil_all_sval() - Test if all elements a string array have a given value * --------------------------------------------------------------------------- * INTERNAL USE ONLY. * * wcsutil_all_sval() tests whether the elements of an array of type * char (*)[72] all have the specified value. * * Given: * nelem int The length of the array. * * sval const char * * String to be tested. * * sarr const char (*)[72] * Pointer to the first element of the array. * * Function return value: * int Status return value: * 0: Not all equal. * 1: All equal. * * * wcsutil_allEq() - Test for equality of a particular vector element * ------------------------------------------------------------------ * INTERNAL USE ONLY. * * wcsutil_allEq() tests for equality of a particular element in a set of * vectors. * * Given: * nvec int The number of vectors. * * nelem int The length of each vector. * * first const double* * Pointer to the first element to test in the array. * The elements tested for equality are * = *first == *(first + nelem) = == *(first + nelem*2) = : = == *(first + nelem*(nvec-1)); * * The array might be dimensioned as * = double v[nvec][nelem]; * * Function return value: * int Status return value: * 0: Not all equal. * 1: All equal. * * * wcsutil_dblEq() - Test for equality of two arrays of type double * ---------------------------------------------------------------- * INTERNAL USE ONLY. * * wcsutil_dblEq() tests for equality of two double-precision arrays. * * Given: * nelem int The number of elements in each array. * * tol double Tolerance for comparison of the floating-point values. * For example, for tol == 1e-6, all floating-point * values in the arrays must be equal to the first 6 * decimal places. A value of 0 implies exact equality. * * arr1 const double* * The first array. * * arr2 const double* * The second array * * Function return value: * int Status return value: * 0: Not equal. * 1: Equal. * * * wcsutil_intEq() - Test for equality of two arrays of type int * ------------------------------------------------------------- * INTERNAL USE ONLY. * * wcsutil_intEq() tests for equality of two int arrays. * * Given: * nelem int The number of elements in each array. * * arr1 const int* * The first array. * * arr2 const int* * The second array * * Function return value: * int Status return value: * 0: Not equal. * 1: Equal. * * * wcsutil_strEq() - Test for equality of two string arrays * -------------------------------------------------------- * INTERNAL USE ONLY. * * wcsutil_strEq() tests for equality of two string arrays. * * Given: * nelem int The number of elements in each array. * * arr1 const char** * The first array. * * arr2 const char** * The second array * * Function return value: * int Status return value: * 0: Not equal. * 1: Equal. * * * wcsutil_setAll() - Set a particular vector element * -------------------------------------------------- * INTERNAL USE ONLY. * * wcsutil_setAll() sets the value of a particular element in a set of vectors * of type double. * * Given: * nvec int The number of vectors. * * nelem int The length of each vector. * * Given and returned: * first double* Pointer to the first element in the array, the value * of which is used to set the others * = *(first + nelem) = *first; = *(first + nelem*2) = *first; = : = *(first + nelem*(nvec-1)) = *first; * * The array might be dimensioned as * = double v[nvec][nelem]; * * Function return value: * void * * * wcsutil_setAli() - Set a particular vector element * -------------------------------------------------- * INTERNAL USE ONLY. * * wcsutil_setAli() sets the value of a particular element in a set of vectors * of type int. * * Given: * nvec int The number of vectors. * * nelem int The length of each vector. * * Given and returned: * first int* Pointer to the first element in the array, the value * of which is used to set the others * = *(first + nelem) = *first; = *(first + nelem*2) = *first; = : = *(first + nelem*(nvec-1)) = *first; * * The array might be dimensioned as * = int v[nvec][nelem]; * * Function return value: * void * * * wcsutil_setBit() - Set bits in selected elements of an array * ------------------------------------------------------------ * INTERNAL USE ONLY. * * wcsutil_setBit() sets bits in selected elements of an array. * * Given: * nelem int Number of elements in the array. * * sel const int* * Address of a selection array of length nelem. May * be specified as the null pointer in which case all * elements are selected. * * bits int Bit mask. * * Given and returned: * array int* Address of the array of length nelem. * * Function return value: * void * * * wcsutil_fptr2str() - Translate pointer-to-function to string * ------------------------------------------------------------ * INTERNAL USE ONLY. * * wcsutil_fptr2str() translates a pointer-to-function to hexadecimal string * representation for output. It is used by the various routines that print * the contents of WCSLIB structs, noting that it is not strictly legal to * type-pun a function pointer to void*. See * http://stackoverflow.com/questions/2741683/how-to-format-a-function-pointer * * Given: * fptr void(*)() Pointer to function. * * Returned: * hext char[19] Null-terminated string. Should be at least 19 bytes * in size to accomodate a 64-bit address (16 bytes in * hex), plus the leading "0x" and trailing '\0'. * * Function return value: * char * The address of hext. * * * wcsutil_double2str() - Translate double to string ignoring the locale * --------------------------------------------------------------------- * INTERNAL USE ONLY. * * wcsutil_double2str() converts a double to a string, but unlike sprintf() it * ignores the locale and always uses a '.' as the decimal separator. Also, * unless it includes an exponent, the formatted value will always have a * fractional part, ".0" being appended if necessary. * * Returned: * buf char * The buffer to write the string into. * * Given: * format char * The formatting directive, such as "%f". This * may be any of the forms accepted by sprintf(), but * should only include a formatting directive and * nothing else. For "%g" and "%G" formats, unless it * includes an exponent, the formatted value will always * have a fractional part, ".0" being appended if * necessary. * * value double The value to convert to a string. * * * wcsutil_str2double() - Translate string to a double, ignoring the locale * ------------------------------------------------------------------------ * INTERNAL USE ONLY. * * wcsutil_str2double() converts a string to a double, but unlike sscanf() it * ignores the locale and always expects a '.' as the decimal separator. * * Given: * buf char * The string containing the value * * Returned: * value double * The double value parsed from the string. * * * wcsutil_str2double2() - Translate string to doubles, ignoring the locale * ------------------------------------------------------------------------ * INTERNAL USE ONLY. * * wcsutil_str2double2() converts a string to a pair of doubles containing the * integer and fractional parts. Unlike sscanf() it ignores the locale and * always expects a '.' as the decimal separator. * * Given: * buf char * The string containing the value * * Returned: * value double[2] The double value, split into integer and fractional * parts, parsed from the string. * *===========================================================================*/ #ifndef WCSLIB_WCSUTIL #define WCSLIB_WCSUTIL #ifdef __cplusplus extern "C" { #endif void wcsdealloc(void *ptr); void wcsutil_strcvt(int n, char c, int nt, const char src[], char dst[]); void wcsutil_blank_fill(int n, char c[]); void wcsutil_null_fill (int n, char c[]); int wcsutil_all_ival(int nelem, int ival, const int iarr[]); int wcsutil_all_dval(int nelem, double dval, const double darr[]); int wcsutil_all_sval(int nelem, const char *sval, const char (*sarr)[72]); int wcsutil_allEq (int nvec, int nelem, const double *first); int wcsutil_dblEq(int nelem, double tol, const double *arr1, const double *arr2); int wcsutil_intEq(int nelem, const int *arr1, const int *arr2); int wcsutil_strEq(int nelem, char (*arr1)[72], char (*arr2)[72]); void wcsutil_setAll(int nvec, int nelem, double *first); void wcsutil_setAli(int nvec, int nelem, int *first); void wcsutil_setBit(int nelem, const int *sel, int bits, int *array); char *wcsutil_fptr2str(void (*fptr)(void), char hext[19]); void wcsutil_double2str(char *buf, const char *format, double value); int wcsutil_str2double(const char *buf, double *value); int wcsutil_str2double2(const char *buf, double *value); #ifdef __cplusplus } #endif #endif // WCSLIB_WCSUTIL ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/wcsutrn.l0000644000175100001710000001605500000000000017253 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wcsutrn.l,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * wcsutrn.l is a Flex description file containing the definition of a lexical * scanner that translates non-standard FITS units specifications. * * It requires Flex v2.5.4 or later. * * Refer to wcsunits.h for a description of the user interface and operating * notes. * *===========================================================================*/ /* Options. */ %option full %option never-interactive %option noinput %option noyywrap %option outfile="wcsutrn.c" %option prefix="wcsutrn" %option reentrant %option extra-type="struct wcsutrn_extra *" /* Exclusive start states. */ %x NEXT FLUSH %{ #include #include #include #include #include "wcserr.h" #include "wcsunits.h" // User data associated with yyscanner. struct wcsutrn_extra { // Used in preempting the call to exit() by yy_fatal_error(). jmp_buf abort_jmp_env; }; #define YY_DECL int wcsutrne_scanner(int ctrl, char unitstr[], \ struct wcserr **err, yyscan_t yyscanner) // Dummy definition to circumvent compiler warnings. #define YY_INPUT(inbuff, count, bufsize) { count = YY_NULL; } // Preempt the call to exit() by yy_fatal_error(). #define exit(status) longjmp(yyextra->abort_jmp_env, status); // Internal helper functions. static YY_DECL; %} %% static const char *function = "wcsutrne_scanner"; if (err) *err = 0x0; char orig[80], subs[80]; *orig = '\0'; *subs = '\0'; int bracket = 0; int unsafe = 0; int status = -1; yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner); yy_scan_string(unitstr, yyscanner); *unitstr = '\0'; // Return here via longjmp() invoked by yy_fatal_error(). if (setjmp(yyextra->abort_jmp_env)) { return wcserr_set(WCSERR_SET(UNITSERR_PARSER_ERROR), "Internal units translator error"); } BEGIN(INITIAL); #ifdef DEBUG fprintf(stderr, "\n%s ->\n", unitstr); #endif ^" "*"[" { // Looks like a keycomment. strcat(unitstr, "["); bracket = 1; } " "+ // Discard leading whitespace. [^A-Za-z] { // Non-alphabetic character. strcat(unitstr, yytext); if (bracket && *yytext == ']') { BEGIN(FLUSH); } } Angstroms|angstroms? { strcpy(orig, yytext); strcpy(subs, "Angstrom"); BEGIN(NEXT); } arcmins|ARCMINS? { strcpy(orig, yytext); strcpy(subs, "arcmin"); BEGIN(NEXT); } arcsecs|ARCSECS? { strcpy(orig, yytext); strcpy(subs, "arcsec"); BEGIN(NEXT); } BEAM { strcpy(orig, yytext); strcpy(subs, "beam"); BEGIN(NEXT); } Byte { strcpy(orig, yytext); strcpy(subs, "byte"); BEGIN(NEXT); } days?|DAYS? { strcpy(orig, yytext); strcpy(subs, "d"); BEGIN(NEXT); } D { unsafe = 1; strcpy(orig, yytext); strcpy(subs, (ctrl & 4) ? "d" : "D"); BEGIN(NEXT); } degrees?|Deg|Degrees?|DEG|DEGREES? { strcpy(orig, yytext); strcpy(subs, "deg"); BEGIN(NEXT); } GHZ { strcpy(orig, yytext); strcpy(subs, "GHz"); BEGIN(NEXT); } hr|HR { strcpy(orig, yytext); strcpy(subs, "h"); BEGIN(NEXT); } H { unsafe = 1; strcpy(orig, yytext); strcpy(subs, (ctrl & 2) ? "h" : "H"); BEGIN(NEXT); } hz|HZ { strcpy(orig, yytext); strcpy(subs, "Hz"); BEGIN(NEXT); } KHZ { strcpy(orig, yytext); strcpy(subs, "kHz"); BEGIN(NEXT); } JY { strcpy(orig, yytext); strcpy(subs, "Jy"); BEGIN(NEXT); } [kK]elvins?|KELVINS? { strcpy(orig, yytext); strcpy(subs, "K"); BEGIN(NEXT); } KM { strcpy(orig, yytext); strcpy(subs, "km"); BEGIN(NEXT); } metres?|meters?|M|METRES?|METERS? { strcpy(orig, yytext); strcpy(subs, "m"); BEGIN(NEXT); } MIN { strcpy(orig, yytext); strcpy(subs, "min"); BEGIN(NEXT); } MHZ { strcpy(orig, yytext); strcpy(subs, "MHz"); BEGIN(NEXT); } Ohm { strcpy(orig, yytext); strcpy(subs, "ohm"); BEGIN(NEXT); } [pP]ascals?|PASCALS? { strcpy(orig, yytext); strcpy(subs, "Pa"); BEGIN(NEXT); } pixels|PIXELS? { strcpy(orig, yytext); strcpy(subs, "pixel"); BEGIN(NEXT); } radians?|RAD|RADIANS? { strcpy(orig, yytext); strcpy(subs, "rad"); BEGIN(NEXT); } sec|seconds?|SEC|SECONDS? { strcpy(orig, yytext); strcpy(subs, "s"); BEGIN(NEXT); } S { unsafe = 1; strcpy(orig, yytext); strcpy(subs, (ctrl & 1) ? "s" : "S"); BEGIN(NEXT); } [vV]olts?|VOLTS? { strcpy(orig, yytext); strcpy(subs, "V"); BEGIN(NEXT); } years?|YR|YEARS? { strcpy(orig, yytext); strcpy(subs, "yr"); BEGIN(NEXT); } [A-Za-z]+ { // Not a recognized alias. strcpy(orig, yytext); strcpy(subs, orig); BEGIN(NEXT); } [A-Za-z]+ { // Reject the alias match. strcat(orig, yytext); strcpy(subs, orig); } " "+[^A-Za-z] { // Discard separating whitespace. unput(yytext[yyleng-1]); } " "+[A-Za-z] { // Compress separating whitespace. strcat(unitstr, subs); strcat(unitstr, " "); if (strcmp(orig, subs)) status = 0; unput(yytext[yyleng-1]); *subs = '\0'; BEGIN(INITIAL); } . { // Copy anything else unchanged. strcat(unitstr, subs); if (strcmp(orig, subs)) status = 0; unput(*yytext); *subs = '\0'; BEGIN(INITIAL); } .* { // Copy out remaining input. strcat(unitstr, yytext); } <> { // End-of-string. if (*subs) { strcat(unitstr, subs); if (strcmp(orig, subs)) status = 0; } if (unsafe) { return wcserr_set(WCSERR_SET(UNITSERR_UNSAFE_TRANS), "Unsafe unit translation in '%s'", unitstr); } return status; } %% /*---------------------------------------------------------------------------- * External interface to the scanner. *---------------------------------------------------------------------------*/ int wcsutrne( int ctrl, char unitstr[], struct wcserr **err) { // Function prototypes. int yylex_init_extra(YY_EXTRA_TYPE extra, yyscan_t *yyscanner); int yylex_destroy(yyscan_t yyscanner); struct wcsutrn_extra extra; yyscan_t yyscanner; yylex_init_extra(&extra, &yyscanner); int status = wcsutrne_scanner(ctrl, unitstr, err, yyscanner); yylex_destroy(yyscanner); return status; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/C/wtbarr.h0000644000175100001710000001041400000000000017034 0ustar00vstsdocker/*============================================================================ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: wtbarr.h,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *============================================================================= * * WCSLIB 7.7 - C routines that implement the FITS World Coordinate System * (WCS) standard. Refer to the README file provided with WCSLIB for an * overview of the library. * * * Summary of the wtbarr struct * ---------------------------- * The wtbarr struct is used by wcstab() in extracting coordinate lookup tables * from a binary table extension (BINTABLE) and copying them into the tabprm * structs stored in wcsprm. * * * wtbarr struct - Extraction of coordinate lookup tables from BINTABLE * -------------------------------------------------------------------- * Function wcstab(), which is invoked automatically by wcspih(), sets up an * array of wtbarr structs to assist in extracting coordinate lookup tables * from a binary table extension (BINTABLE) and copying them into the tabprm * structs stored in wcsprm. Refer to the usage notes for wcspih() and * wcstab() in wcshdr.h, and also the prologue to tab.h. * * For C++ usage, because of a name space conflict with the wtbarr typedef * defined in CFITSIO header fitsio.h, the wtbarr struct is renamed to wtbarr_s * by preprocessor macro substitution with scope limited to wtbarr.h itself, * and similarly in wcs.h. * * int i * (Given) Image axis number. * * int m * (Given) wcstab array axis number for index vectors. * * int kind * (Given) Character identifying the wcstab array type: * - c: coordinate array, * - i: index vector. * * char extnam[72] * (Given) EXTNAME identifying the binary table extension. * * int extver * (Given) EXTVER identifying the binary table extension. * * int extlev * (Given) EXTLEV identifying the binary table extension. * * char ttype[72] * (Given) TTYPEn identifying the column of the binary table that contains * the wcstab array. * * long row * (Given) Table row number. * * int ndim * (Given) Expected dimensionality of the wcstab array. * * int *dimlen * (Given) Address of the first element of an array of int of length ndim * into which the wcstab array axis lengths are to be written. * * double **arrayp * (Given) Pointer to an array of double which is to be allocated by the * user and into which the wcstab array is to be written. * *===========================================================================*/ #ifndef WCSLIB_WTBARR #define WCSLIB_WTBARR #ifdef __cplusplus extern "C" { #define wtbarr wtbarr_s // See prologue above. #endif // For extracting wcstab arrays. Matches // the wtbarr typedef defined in CFITSIO // header fitsio.h. struct wtbarr { int i; // Image axis number. int m; // Array axis number for index vectors. int kind; // wcstab array type. char extnam[72]; // EXTNAME of binary table extension. int extver; // EXTVER of binary table extension. int extlev; // EXTLEV of binary table extension. char ttype[72]; // TTYPEn of column containing the array. long row; // Table row number. int ndim; // Expected wcstab array dimensionality. int *dimlen; // Where to write the array axis lengths. double **arrayp; // Where to write the address of the array // allocated to store the wcstab array. }; #ifdef __cplusplus #undef wtbarr } #endif #endif // WCSLIB_WTBARR ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/CHANGES0000644000175100001710000033747500000000000016216 0ustar00vstsdockerWCSLIB version 7.7 (2021/07/12) ------------------------------- * C library - In disfree() and disset(), removed potential for double invokation of free() on allocated memory. Reported by Cyril Richard. - In wcsutil_fptr2str(), fixed a bug reported by Ralf Palsa (with fix) that caused it to be overly enthusiastic in stripping leading zeroes off addresses of function pointers. - In wcspcx(), replaced variable length arrays will allocated memory (portability issue). Reported by Mihai Cara with patch. - Fixed buglets in wcsbth() and linsize() uncovered by gcc 11.1.0. - Quelled inconsequential compiler warnings from gcc 11.1.0 concerning wcsmix() (function prototype in wcs.h), wcstrim(), wcseulexe(), wcsulex(), and wcsutrne(). - Defined _POSIX_C_SOURCE appropriately in tprj2.c and tspc.c to get the function prototype etc. for nanosleep() from time.h. * Fortran wrappers - Quelled numerous inconsequential compiler warnings from gfortran 11.1.0. - Fixed minor bugs uncovered by gfortran 11.1.0 in test programs tdis2 and ttab3. * Utilities - Moved 'tofits' from ./C/test/ into the utilities directory as it's generally useful, and added usage (converted to man page). Also made it a bit smarter in dealing with ISO/IEC 8859 and UTF-8 encoded byte streams, in particular translating non-breaking spaces into ordinary spaces. * Installation - Two patches for configure.ac provided by Mosč Giordano: 1. makes it possible to build the Windows library using the MinGW cross-compiler, 2. makes the soname of the MacOSX library consistent with other Unix systems. WCSLIB version 7.6 (2021/04/13) ------------------------------- * C library - Bug fix in tabs2x() triggered for 1-dimensional coordinate lookup tables on axes > 1. Reported by Mihai Cara. - In datfix(), don't return status 0 if no change was made (fix for change made at release 7.4). Reported by Derek Homeier. - New function wcspcx() in the wcsfix suite regularizes the linear transformation component of a coordinate description to make it more human-readable. It decomposes CDi_ja into PCi_ja and CDELTia in such a way that CDELTia forms meaningful scaling parameters, often leaving an orthogonal or near-orthogonal matrix. Optionally, it can then permute rows of this matrix to unscramble axis permutations. A test header may be generated from wcspcx.keyrec for input to wcsware (not exercised as part of the standard test suite). - New function wcstrim() frees memory allocated by wcsinit() for arrays in a wcsprm struct that remain unused after the struct has been set up. - New functions wcssize(), auxsize(), tabsize(), linsize(), dissize(), celsize(), prjsize(), spcsize(), and wcserr_size() compute the total size of the relevant structs, including allocated memory. - In the C test suite, inserted a brief pause in tprj2 and tspc, which otherwise have now become a blur. * Fortran wrappers - Added wrappers for wcspcx(), wcstrim(), wcssize(), auxsize(), tabsize(), linsize(), dissize(), celsize(), prjsize(), spcsize(), and wcserr_size(). * Utilities - Added -c, -cp, -C, and -Cp options to wcsware to apply wcspcx() in a variety of ways, -m to apply wcstrim(), and -z to report the total size of the wcsprm struct with a breakdown of the sizes of its constituent structs. - Fixed compiler warnings for sundazel (portability issue). * Installation - Upped the required version of Flex to 2.6.0 (was 2.5.9). Problems with Flex 2.5.39 reported by Derek Homeier. Also added '--disable-flex' as a new configure option to force the use of the pre-generated Flex sources. WCSLIB version 7.5 (2021/03/20) ------------------------------- The C code in WCSLIB is moving piecemeal to the C99 standard. In fact, various indispensible C99 constructs have been used in WCSLIB for many years: the long long int data type (in fitshdr() only); stdint.h, inttypes.h, and the use of PRI formatting control (in wcsprintf(), which is widely used by the library); and the C99-extended library function vsnprintf() (used by wcserr for a decade). Flex-generated C code also uses C99 extensions, though with workarounds if they are not available. Except in the header prologues, which are formatted in a special way for generating the user manual, comments were changed en masse to C99 style in release 7.3.1, and variable declarations in code that I have occasion to modify will transition to the more general placement allowed by C99. However, I have no plans to use any of the more esoteric features of C99. * C library - New function, wcsccs(), changes the celestial coordinate system of a wcsprm struct, for example, from equatorial to galactic coordinates. The parameters that define the spherical coordinate transformation must be provided. This allows WCSLIB to provide this functionality without needing to know anything about specific celestial coordinate systems, and has the advantage of making the routine completely general. Requested by Mohammad Akhlaghi. Modified test program twcsfix also to test wcsccs(). - Fixed a problem common to all of the Flex code (fitshdr, wcsbth, wcspih, wcsulex, and wcsutrn) that made it thread-unsafe. Reported by Cyril Richard. Added a new test program, tpthreads, to test thread safety. It is only used for code development, and not exercised as part of the standard test suite. - In fitshdr(), fixed a problem that potentially could arise on systems where sizeof(long long int) is greater than 8 (64 bits). * Fortran wrappers - Match changes to the C library: added a wrapper for wcsccs(), and modified twcsfix.f. - Because null addresses cannot be passed to functions in Fortran, wcssub_() now interprets *nsub == -1 && *axes == -1 as a signal to do a deep copy of one wcsprm struct to another. * Utilities - New utility, sundazel, computes the local time of the Sun's passage through the specified apparent longitude or latitude in a user- defined coordinate system. It can also perform several other Solar related calculations. (It is unrelated to FITS WCS, and does not use WCSLIB.) * Installation - Added an 'uninstall' rule to the makefiles. Suggested by Cyril Richard. WCSLIB version 7.4 (2021/01/31) ------------------------------- * C library - In wcshdo(), fixed a bug introduced in release 5.9 that potentially caused loss of numerical precision in the sprintf() formatting of floating point keyvalues. This was triggered when a large range of CRPIXja, PCi_ja, or CDELTia values (as three separate groups) were formatted using an 'f' format descriptor, the range not being so large that it would have forced wcshdo() to revert to 'E' format. Reported by Mohammad Akhlaghi. Also in wcshdo(), fixed a bug introduced in release 7.1 that caused the coefficients of the TPD distortion function not to be written to the header. TPD and Polynomial distortion function headers will now always include the DPja.DOCORR keyword. Reported by Derek Homeier with patch. - In wcsset(), fixed a segv generated in attempting to report a non- standard units string with wcserr message reporting disabled. Reported by Mohammad Akhlaghi. In wcsutrne(), allow 'Angstroms' and 'angstroms' as additional synonyms for 'Angstrom'. - In datfix(), ensure that 0 is returned if an informational message is set in wcsprm::err. Consequent on feedback independently from Mihai Cara and Bruce Merry. Clarified that informational messages may be set in wcsprm::err for returns of 0 from datfix(), obsfix(), unitfix(), and spcfix(). * User manual - Added cautions about translating CDi_ja to PCi_ja plus CDELTia for those historical distortion functions (TPV, TNX, ZPX) that expect to operate on intermediate world coordinates, rather than intermediate pixel coordinates. Consequent on feedback from Mohammad Akhlaghi. - Documentation generation moved to doxygen 1.9.1 (was 1.8.19). WCSLIB version 7.3.1 (2020/08/17) --------------------------------- There are no functional changes in this release. * C library * Fortran wrappers * PGSBOX * Utilities - Changed all C code, including within the flex sources, Fortran and PGSBOX wrappers, and test suite, to use C99 style commenting (i.e. using //), excluding the header prologues used to generate the user manual. * User manual - Documentation generation moved to doxygen 1.8.19 (was 1.8.18). WCSLIB version 7.3 (2020/06/03) ------------------------------- * C library - wcshdo() was writing MJD-OBS twice to the header, and MJD-BEG not at all. - In wcshdo(), if MJDREF assumes its default value, just write MJDREF = 0 (not MJDREFI & MJDREFF), and omit writing DATEREF, which, with a value of '1858-11-17', looks strange and is potentially confusing. Reported by Thomas Robitaille. If the fractional part of MJDREF is zero, then just write the integer part as MJDREF (i.e. not as MJDREFI & MJDREFF). - Bug fix in wcsfix() - it was writing error messages that referred to DATE-REF and MJD-REF rather then DATEREF and MJDREF. Reported by Mihai Cara. - Under control of a new flag, WCSHDR_DATEREF, added the option to wcspih() and wcsbth() to accept DATE-REF, MJD-REF, MJD-REFI, MJD-REFF, JDREF, JD-REFI, and JD-REFF as synonyms for the standard keywords, DATEREF, MJDREF, MJDREFI, MJDREFF, JDREF, JDREFI, and JDREFF. The latter buck the pattern set by the other date keywords ({DATE,MJD}-{OBS,BEG,AVG,END}), thereby increasing the potential for confusion and error. * Fortran wrappers - As compilers are becoming much stricter (gfortran 10), modified all Fortran test programs to use the type-specific equivalents of the various *PUT and *GET routines. Reported by Ole Streicher. - For the fitshdr wrappers, added type-specific equivalents of KEYGET: KEYGTI, KEYGTD, and KEYGTC. * PGSBOX - Modified pgtest to use the type-specific equivalents of WCSPUT. * User manual - In the section "WCSLIB Fortran wrappers", promoted use of the type- specific equivalents of the various *PUT and *GET routines. - In the section "FITS-WCS and related software", added ASCL and ADS codes, where they exist, for all software packages mentioned. - Documentation generation moved to doxygen 1.8.18 (was 1.8.17). WCSLIB version 7.2 (2020/03/09) ------------------------------- * C library - In wcssub(), fixed a bug relating to handling coordinate lookup tables. Reported by Mihai Cara with fix. Also increased the number of coordinate axes handled from 10 to 32. * Installation - New configure option, --disable-shared, defeats generation of the sharable library. WCSLIB version 7.1 (2020/01/01) ------------------------------- Changes in the contents of the wcsprm struct necessitated incrementing the major version number from 6 to 7 (i.e. the ABI changed). * C library - In wcsset(), set wcsprm::mjdref[] to zero if neither it nor wcsprm::dateref are defined, as per the standard. Reported by Thomas Robitaille. wcsset() now also checks that the number of coordinate axes does not exceed 32. - In tabs2x(), fixed an out-of-bounds array access produced by invalid world coordinates. Reported by Mihai Cara and Michael Seifert. In tab.c, declare static three helper functions, tabedge(), tabrow(), and tabvox(), used by tabs2x(). Increased the number of coordinate axes handled by tabvox() from 16 to 32. - Extended datfix() to handle MJDREF/DATEREF, overlooked in the changes in release 6.1. Also fixed the handling of MJD < 0. - Support Solar keywords RSUN_REF, DSUN_OBS, CRLN_OBS, CRLT_OBS, HGLN_OBS, and HGLT_OBS by accomodating them within an auxiliary struct, auxprm, within the wcsprm struct. Now filled by the header parsers, wcspih() and wcsbth() and handled routinely by wcsinit(), wcssub(), wcscompare(), wcsfree(), wcsprt(), wcsset(), and wcshdo(). Requested by Stuart Mumford (SunPy) with input from Bill Thompson. - Bug fix in wcsprintf_set() for resetting the output disposition. Reported by Mihai Cara with patch. - In dis.{h,c}, the DOCORR record is now handled as a first-class value via disprm::docorr. This required changing the struct. - In cel.c, spc.c, wcserr.c, wcsfix.c, wcshdr.c, and wcsutil.c, quelled compiler warnings from gcc 9.2.0 generated by -Wmaybe-uninitialized and -Wstringop-truncation (via -Wall). Similarly for various programs in the test suite. - In various functions, quelled warnings from the Microsoft Visual C++ compiler, mostly relating to pointer arithmetic. Reported by Michael Seifert. * Fortran wrappers - Handled compiler warnings from gcc 9.2.0 generated by -Wstringop-truncation (via -Wall). - Minor enhancements to character argument handling, including, in prjget_(), blank-filling the returned strings matching PRJ_CODE and PRJ_NAME, and likewise for SPC_TYPE and SPC_CODE in spcget_(). * Utilities - In wcsgrid, handled compiler warnings from gcc 9.2.0 generated by -Wstringop-truncation (via -Wall). * User manual - In the section on "FITS-WCS and related software", added mention of the R wrappers (Rwcs). Suggested by Aaron Robotham. - Added a new section detailing the limit on the number of image axes that WCSLIB can handle (currently 32), and how this could be increased if needed. Prompted by Thomas Robitaille. - Augmented the section on the Fortran wrappers, particularly with respect to character string handling in argument lists. - Documentation generation moved to doxygen 1.8.17 (was 1.8.16). WCSLIB version 6.4 (2019/08/15) ------------------------------- * Installation - The rule change to the Fortran makefile in v6.3 to add getwcstab_f.o to the sharable library causes it to depend on CFITSIO to resolve fits_get_wcstab(). Hence backed out of that change. * User manual - Documentation generation moved to doxygen 1.8.16 (was 1.8.14). WCSLIB version 6.3 (2019/07/12) ------------------------------- * C library - Fixed the Polynomial and TPD distortions so that, as stipulated in WCS Paper IV, they are now considered to return an additive correction to be applied to the given coordinates, rather than the corrected coordinates themselves. Added a new subsection to the prologue of dis.h entitled 'Historical idiosyncrasies', which discusses this issue and other vagueries. Amended components of the test suite accordingly: SIPTPV.keyrec, TPV7.keyrec, and tdis1.c. - Fixed memory leaks and other potential problems that arose in the wcserr system consequent on changes made in release 6.1. Memory allocated by wcsfixi() for messages in the array of wcserr structs must now be freed by the caller. Amended twcsfix.c accordingly. - Plugged memory leaks arising in disset(). - New function wcsdealloc() provided to free memory allocated within certain WCSLIB routines. Suggested by David Motl. - Eliminated a swag of inconsequential compiler warnings, particularly those emanating from the flex sources. * Validation - The library, Fortran wrappers, utilities, and test programs now pass runtime analysis using -fsanitize=address and -fsanitize=undefined in gcc 8.3.0, in addition to valgrind. Also compile-time strictures using -std=c99, -pedantic, -Wall, -Wextra, and -DFORTIFY_SOURCE=2. Prompted by feedback from Ole Streicher. * Installation - The non-graphical tests now run reliably in parallel builds (make CHECK=nopgplot -j8 check). Requested by Mohammed Akhlaghi. The graphical tests can also be run in parallel, but as PGPLOT can only handle one stream at a time, some graphics are likely to be lost. Nevertheless, it is a useful option, especially with runtime analysis via -fsanitize=address, etc. - As CFITSIO doesn't provide a Fortran wrapper for fits_read_wcstab(), getwcstab_f.o is now always included in the WCSLIB object library and sharable library if CFITSIO is available (and the WCSLIB Fortran wrappers are required). Use 'configure --without-cfitsio' to defeat this. - Tidied up some aspects of the build where CFITSIO is not available. * User manual - Fixed minor formatting problems in dis.h. WCSLIB version 6.2 (2018/10/20) ------------------------------- * C library - Consequent on the change in release 6.1, reapplied soothing balm to the wtbarr struct definition in wcs.h for C++ compilation (C and Fortran compilation being unaffected). While the object libraries themselves are unchanged, the modified wcs.h must be installed for compiling C++ applications. Reported by Corentin Schreiber. * User manual - Fixed minor formatting problems with the doxygen manual generation. WCSLIB version 6.1 (2018/10/19) ------------------------------- * C library - Added support for time-related WCS keywords (Paper VII) by expanding the wcsprm struct to store them as auxiliary values, now filled by the header parsers, wcspih() and wcsbth() and handled routinely by wcsinit(), wcssub(), wcscompare(), wcsfree(), wcsprt(), wcsset(), and wcshdo(). - Augmented datfix() to do various consistency checks on the new time-related keyvalues, and added a new routine, obsfix(), to check consistency of the OBSGEO-[XYZLBH] observatory coordinates. - In the usage notes for wcsbth(), clarified that, according to WCS Papers III and VII, certain global image header keywords are permitted in binary table headers and are expected to be inherited by image arrays and pixel lists, and elaborated on the difficulties that such inheritance may cause for pixel lists. - Revamped message string handling in the wcserr module to allow arbitrarily long messages while greatly reducing the sizeof the struct. - Extracted the definition of the wtbarr struct from wcs.h to a separate header file, wtbarr.h, in order to reduce the number of irrelevant warnings generated by 'gcc -Wpadded' (primarily for code development). Applications code that needs to access members of the struct (unlikely) must now include wtbarr.h (or wcslib.h). - The WCSLIB major version number was incremented as changes to the wcsprm struct makes the ABI of the sharable library incompatible with executables linked with that of older releases. * Fortran wrappers - Match changes to the C library, including adding a wrapper for obsfix(). * Installation - Several changes to configure and the makefiles aimed at facilitating code development. WCSLIB version 5.20 (2018/10/05) -------------------------------- * C library - Added utility functions dpkeyi() and dpkeyd() to dis.c, and removed the corresponding functions from wcsutil.c. * Fortran wrappers - New wrappers for dpkeyi() and dpkeyd(). * Installation - Reworked the makefiles to allow parallel library builds, as required by some software distributions. Reported by Dustin Lang with suggested patch, and Zaak Beekman. (Parallel execution of the test suite is not supported.) - The introduction of "deterministic" archiving (ar(1)) broke dependency analysis in the WCSLIB makefiles on the many systems where it is now enabled by default (i.e. binutils configured with --enable-deterministic-archives). Modified configure to force non-deterministic archiving during the library builds, thus repairing the dependency analysis. However, the static object libraries are now reconstructed using deterministic archiving in the process of installing them. - Fixed problems with the dependency analysis, solely affecting code development. WCSLIB version 5.19.1 (2018/07/28) ---------------------------------- * Installation - Updated ./config/config.{guess,sub} to the latest versions from the GIT repository, timestamped 2018-07-18 and 2018-07-25, respectively. The previous pair were dated 2012-02-10 and 2012-04-18. WCSLIB version 5.19 (2018/07/27) -------------------------------- * C library - In wcssub(), fixed a bug in handling distortion functions on axes with changed axis number in the subimage (i.e. via deletion or addition of an axis). - In various routines within dis.c, wcs.c, wcshdr.c, and wcspih.l, increased the size of various sprintf() output buffers to avert -Wformat-overflow warnings from gcc 8.1.0 (with -DFORTIFY_SOURCE=2). Reported by Simon Conseil. Also fixed other warnings in these routines from gcc 8.1.0 relating to -Wcast-function-type, -Wmaybe-uninitialized, and -Wunused-parameter. - In wcsutrn.l (the units alias translator used by wcsfix), recognise 'Deg', 'Degree', and 'Degrees' as aliases for 'deg'. Rogue header reported by Jim Lewis. - Added a note to the prologue of spx.h explaining WCSLIB's use of Cox's air-to-vacuum transformation equation rather than the IUGG relation cited in WCS Paper III. Noted by Benjamin Alan Weaver. - In the test suite, avert nuisance compiler warnings in tdis1. Made tsphdpa more robust in handling user coordinate input. * PGSBOX - In pgwcsl_(), avert nuisance warnings from gcc 8.1.0 relating to unused parameters (-Wunused-parameter). Also averted nuisance compiler warnings in cpgtest. * Utilities - wcsware was not reading the -TAB table from the FITS file for alternate descriptions, bug reported by Chiara Marmo. Nor was wcsfix() ever invoked for them. Made it more robust in handling user input of coordinates for the -x and -w options. - Fixed compiler warnings from gcc 8.1.0 in HPXcvt (-Wmaybe-uninitialized), and wcsgrid (-Wformat-overflow). * Installation - Amended configure.ac to allow cross-compilation, and also updated the auxiliary configure scripts in the config/ directory. Patch supplied by Mosč Giordano. WCSLIB version 5.18 (2018/01/10) -------------------------------- * C library - New routines introduced to preclude altering the global variables NPVMAX, NPSMAX, and NDPMAX, which determine how much memory to allocate for storing PVi_ma, PSi_ma, DPja, and DQia keyvalues: wcsinit(), lininit(), lindist(), and disinit(). These are now used by various WCSLIB routines, such as the header parsers, which previously temporarily altered the global variables, thus posing a thread hazard. Testing and feedback on thread-safety issues, with patches, from Rodrigo Tobar Carrizo. - The Flex scanners, fitshdr(), wcsbth(), wcspih(), wcsulexe(), and wcsutrne(), have been rewritten as thin wrappers (with the same API) over scanners that were modified (with changed API) as required to use Flex's "reentrant" option. Consequently, they are now reentrant and should be thread-safe. That also passes through to the deprecated wrappers, wcsulex() and wcsutrn(). - Fixed memory leaks in lindist() and lincpy() uncovered by valgrind. - Test programs tfitshdr, tpih1, tpih2, and ttab3 are now careful to free all allocated memory before exit to defeat spurious reports of memory leaks by valgrind. * Fortran wrappers - New wrappers for wcsinit(), lininit(), lindist(), and disinit(). * Installation - configure now recognises the value of ARFLAGS obtained from the environment. * User manual - Updates and amendments in line with the above changes. - Documentation generation moved to doxygen 1.8.14 (was 1.8.13). WCSLIB version 5.17 (2017/09/18) -------------------------------- * C library - Fixed a memory leak in wcspih(). Reported by Pim Schellart. - Fixed compiler warnings about comparison between signed and unsigned integers in tab.c (Pey-Lian Lim). Also fixed warnings in other functions about unused parameters. * Fortran wrappers - Fixed compiler warnings about comparison between signed and unsigned integers in several routines. * PGSBOX - Fixed a compiler warning about comparison between signed and unsigned ints. * Installation - Removed setgid permission on installation directories (for Fedora Linux, reported by Sergio Pascual). * User manual - Minor updates and amendments. - Documentation generation moved to doxygen 1.8.13 (was 1.8.10). WCSLIB version 5.16 (2017/01/15) -------------------------------- * C library - Bug fix in spcfix() for the previous change. Reported separately by Julian Taylor & Peter Williams. WCSLIB version 5.15 (2016/04/05) -------------------------------- * C library - Bug fix in wcsulex.l for the previous change. Reported, and fix supplied by Tammo Jan Dijkema. - In spcfix(), report the value of VELREF if ctype is translated from the AIPS convention. WCSLIB version 5.14 (2016/02/07) -------------------------------- * C library - In wcsulex.l and wcsutrn.l, applied a workaround for a memory leak introduced by a change (bug) in flex in Aug/2012. Reported, and fix supplied by Thomas Robitaille and Erik Bray. * Installation - In MacOSX, create symlink libwcs.dylib pointing to the dynamic library so that WCSLIB is linked dynamically by default. Requested by Paul Price. WCSLIB version 5.13 (2016/01/26) -------------------------------- * C library - In wcshdo(), provide floating-point format control via the 'ctrl' argument (formerly 'relax'). - In wcspih(), PLATEID by itself is no longer sufficient to trigger a DSS translation (reported by James Allen). - In unitfix(), ensure that the message buffer cannot be overrun, e.g. by blank-padded unit strings (reported by Vishal Kasliwal). WCSLIB version 5.12 (2015/11/15) -------------------------------- * C library - Bug fix in wcshdo() for CRVALia precision reported by Mihai Cara. WCSLIB version 5.11 (2015/10/18) -------------------------------- * C library - Bug fixes in wcspih.l and dis.c for WAT distortions provided by Ole Streicher. WCSLIB version 5.10 (2015/10/09) -------------------------------- * C library - In wcshdo(), allow output of floating point keyvalues to 15 significant digits (was 14), mainly for astropy. - In wcspih(), allow unrecognised WAT projection types (tan, etc.) to pass without returning an error. Reported by Michael Droettboom. Also fixed a bug triggered by SIP keywords in unconventional order, reported by Colin Slater, LSST. WCSLIB version 5.9 (2015/07/21) ------------------------------- * C library - In disx2p(), make proper allowance for the possibility that the TPD and SIP forward and inverse distortion polynomials may not be of the same degree, reported by Martin Kuemmel. - Fix-ups in wcshdo() reported by Michael Droettboom, and several tidy-ups as well. WCSLIB version 5.8 (2015/07/08) ------------------------------- * C library - DSS (Digitized Sky Survey) coordinates are now handled via TPD, as are the TNX and ZPX "projections". New test script tdis3 and headers DSS.keyrec, TNX.keyrec, and ZPX.keyrec. - New function dishdo() can be used to set a flag that causes wcshdo() to write headers in the form of the distortion function used internally (usually TPD). - Added the capability, via DPja.DOCORR, for a distortion function to to compute an additive correction to the undistorted coordinates (rather than computing the distorted coordinates themselves). - Added auxiliary variables to TPD via DPja.AUX.jhat.COEFF.m. - Bug fix in wcshdo() for TPV, diagnosed by Michael Droettboom. * Fortran wrappers - Wrapper for dishdo(). WCSLIB version 5.7 (2015/06/29) ------------------------------- * C library - Extended wcssub() to handle distortions (and thus wcscopy() also). This required axis mapping to be enabled for SIP distortions within WCSLIB. - wcshdo() now handles all distortions currently supported by WCSLIB: SIP, TPV, TPD, and Polynomial. - Bug fixes in sphx2s() and sphs2x() for non-unit vector strides for special-case rotations. - In wcsset(), modify wcsprm::ctype after translating TPV so that subsequent calls won't try to re-translate it, the PVi_ma records by then having been erased. Reported by Michael Droettboom. Also, restore NDPMAX after translating TPV. - Bug fixes in discpy(), disprt(), disset(), and disx2p(). - Added disperr(), prjperr(), spcperr(), spxperr(), and tabperr() to complete the set and make reporting errors slightly more convenient. * Utilities - wcsware has a new option, -o, to print the wcsprm struct in the form of a FITS header using wcshdo(). Also, the -a option has been extended to allow a 0-relative numeric index for selecting an alternate WCS, where the alternates are sequenced alphabetically (without gaps) following the primary representation. * User manual - Documentation generation moved to doxygen 1.8.10 (was 1.8.9.1). WCSLIB version 5.6 (2015/06/14) ------------------------------- * C library - Bug fixes in wcspih() and sipset() to account for the fact that the independent variables of the SIP polynomial are pixel coordinate offsets from CRPIXja, not pixel coordinates per se. Diagnosed by Michael Droettboom. Validated SIP and TPV handling by comparing the output of 'wcsware -x' with that of wcstools 'xy2sky -d -n6' using astropy's SIP test headers, and separate SIP and TPV headers originating from the Palomar Transient Factory provided by David Shupe. Changed SIP.keyrec so that CRPIX1 and CRPIX2 differ in value, thereby making tests sensitive to any confusion between the two. WCSLIB version 5.5 (2015/05/05) ------------------------------- * C library - Bug fixes in wcspih.l for headers with multiple distortions, and for distortion parameter look-alike keywords. - Bug fix in sipset() uncovered by valgrind. WCSLIB version 5.4.1 (2015/05/01) --------------------------------- * C library - Added a fairly lengthy section to the prologue of dis.h describing the Paper IV keywords and the distortion functions currently implemented. * User manual - Added a new section on WCSLIB version numbers. WCSLIB version 5.4 (2015/04/21) ------------------------------- * C library - Further work on distortions: wcspih() now parses Paper IV distortion keywords (CPDISja, CQDISia, DPja, DQia, etc.), thus handling record- valued keywords. SIP keywords are also parsed and translated into Paper IV keywords. - TPV, SIP, and whereever possible, the general Polynomial distortion function of Paper IV are now implemented by the Template Polynomial Distortion (TPD), that being a superset of TPV and SIP. TPD, which can also handle 1D distortions and be used for inversions, is also supported as a separate distortion type defined by Paper IV keywords. TPD efficiently handles 1D distortions and distortions without radial terms. - Specialized inverse distortions, such as defined by SIP, are implemented by TPD and recognized by disx2p(), which uses them to compute the initial approximation of its more precise iterative solution. - Generalized tdis1.c so that it can do closure tests for SIP headers, and added a SIP test header. WCSLIB version 5.3.1 (2015/04/21) --------------------------------- * C library - Bug fix in test program tdis1.c reported by Martin Kuemmel. WCSLIB version 5.3 (2015/04/21) ------------------------------- First public release of WCSLIB 5.x with distortions capability. * C library - Changed disprm::dtype from char[16] to char[72] for reasons relating to header parsing. - More armour plating for disset() and friends. They also use new utility functions wcsutil_dpkey_int() and wcsutil_dpkey_double() to extract numeric values from a dpkey struct. This ensures their independence of the data type, the appropriate reporting of dpkey values by disprt(), and (eventually) the appropriate writing of DPja and DQia keyvalues by wcshdo(). - Augmented the usage comments for dpfill() to explain how numeric values in a dpkey struct are handled. * Utilities - wcsware now uses wcserr to provide a backtrace on errors. Also fixed a couple of minor annoyances relating to alternate representations. WCSLIB version 5.2 beta release (2015/04/15) -------------------------------------------- * C library - Further development of disprm and related functions to implement the FITS keywords for distortions introduced in WCS Paper IV, thus changing disprm's ABI once again. disprm's model is now similar to wcsprm's handling of PVi_ma and PSi_ma, where the parsed keyrecords are loaded into a set of pvcard and pscard structs and wcsset() does the analysis. For disprm, the parsed DPja or DQia keyrecords are loaded into a set of dpkey structs for disset() to analyse. - New function dpfill() aids in filling a dpkey struct. Function disparms() has been removed. It was no longer needed as disprm::parms[][] is now a "returned" member of the struct. - Implementation of the general Polynomial distortion function defined in Sect. 3.1 of WCS Paper IV. The polynomial is defined in terms of Paper IV keywords. - Bug fixes in diswarp() and linwarp() reported by Michael Droettboom. - Test program tdis1 now tests a TPV header for closure in two ways: directly as a specialist TPV distortion (as before), then by translating it into a general polynomial distortion. It then also tests that the TPV and polynomial distortions produce the same results. * Fortran wrappers - Changes to the wrappers reflecting changes to disprm. - Bug fixes in fitshdr_f.c, and test programs tdis1.f, tfitshdr.f, twcsfix.f, and twcs.f. All reported and/or fixed by Ole Streicher. WCSLIB version 5.1 beta release (2015/04/07) -------------------------------------------- * C library - Distortions-related bug fixes to linset(), linp2x(), and linx2p(). - New functions diswarp() and linwarp() compute statistics of the distortion functions over a specified domain. Changed tdis1.c to test them. - Changes to disprm (so changed ABI). * Fortran wrappers - Wrappers for diswarp() and linwarp(). WCSLIB version 5.0 beta release (2015/04/05) -------------------------------------------- * C library - Implemented the framework of WCS Paper IV (the draft distortions proposal) based on a new struct, disprm, and suite of routines with header dis.h: disini(), disalloc(), discpy(), disfree(), disprt(), disset(), disp2x(), and disx2p(). New test program tdis1. Consequent changes to the linprm struct have altered its ABI, thus necessitating an increment in the WCSLIB major verion number. - wcsset() now recognises the "TPV" projection proposed in an early draft of WCS Paper II, and translates it into a disprm distortion - by request of Octavi Fors. Additionally, it recognises "TPU" as equivalent to "TPV" but using a prior distortion (coming before the linear transformation matrix) rather than sequent (coming after it). - In wcspih() and wcsbth(), added relaxation flags to allow PC0i_0ja, PV0j_0ma, and PS0j_0ma (i.e. with leading zeroes on the index). - Added wcslib_version() to return the WCSLIB version number, as suggested by Ole Streicher. - Fixed problems uncovered by valgrind in prjbchk() (reported by Ger van Diepen), sphx2s(), sphx2s(), spcspxe(), spcxpse(), tabini(), and wcshdo_util(). - Tidied up error reporting, particularly relating to translating status returns from lower-level functions. New functions linperr() and celperr() report error messages from the structs they contain in addition to their own. - Changed output formatting of floating point values in linprt(), celprt(), prjprt(), spcprt(), tabprt(), and wcsprt(). Updated the test output reference files for tbth1, tpih1, twcsfix, twcssub, and twcstab to suit. - Tidied up several of the test programs, mostly to free memory explicitly before exit so that valgrind doesn't report (non-)leaks. * Fortran wrappers - Wrappers for the new distortion functions. New test programs tdis1.f and tdis2.f. - Updates following changes to wcspih() and wcsbth(). - Added wrappers for linperr() and celperr(). Also added prjperr_(), spcperr_(), and tabperr_() as convenient wrappers on wcserr_prt(). - Wrapper for wcslib_version(). * Utilities - Added a "lint" function to wcsware to check a FITS header for conformance to the WCS standard. New test program twcslint. * PGSBOX - In PGCRLB, fixed an incorrect use of the MOD intrinsic reported by 'gfortran -std=f95' via Jean-Baptiste Marquette. WCSLIB version 4.25.1 (2015/01/05) ---------------------------------- * C library - Updated the test output reference files for tpih1, tbth1, twcsfix, and twcstab to account for the change to wcsset() in release 4.25. * Fortran wrappers - Updated the test output reference files for tpih1, twcsfix, and twcstab to account for the change to wcsset() in release 4.25. * User manual - Documentation generation moved to doxygen 1.8.9.1 (was 1.8.8). WCSLIB version 4.25 (2014/12/15) ---------------------------------- * C library - wcsset() now supplies default values for the auxiliary keywords EQUINOXa and RADESYSa if not present in the FITS header. WCSLIB version 4.24 (2014/09/19) ---------------------------------- * C library - Changed API to wcscompare() to allow a tolerance to be specified for floating-point comparisons. Contributed by Michael Droettboom. * Fortran wrappers Track the change to wcscompare(). * User manual - Documentation generation moved to doxygen 1.8.8 (was 1.8.4). - Added mention of WCSLIB in "homebrew-science" (MacOSX) in the section on other packages. WCSLIB version 4.23 (2014/05/11) -------------------------------- * C library - New function wcscompare() compares two wcsprm structs for equality with varying degrees of strictness. Test program twcscompare. Contributed by Michael Droettboom. - In wcssub(), fixed a bug uncovered by valgrind arising from allocation of insufficient memory for temporaries when a new axis is added. Reported by Michael Droettboom. - In wcshdo(), don't write RESTFRQ or RESTWAV if zero. Also, to distinguish them from integer keyvalues, floating- point values will now always be written with an exponent or fractional part, ".0" being appended if necessary to achieve this. Suggested by Peter Weilbacher. - Fixed the '-h' option in twcshdr. * Fortran wrappers - Wrapper for wcscompare(). WCSLIB version 4.22 (2014/04/13) -------------------------------- * C library - In pcox2s() and pcos2x(), use alternative projection equations for greater numerical precision near theta == 0. In cops2x(), return an exact result for theta at the poles. Relaxed the tolerance for bounds checking a little in sflx2s(). WCSLIB version 4.21 (2014/03/24) -------------------------------- * C library - New function prjbchk() performs bounds checking on native spherical coordinates. It is invoked automatically by the deprojection (x2s) routines if prjprm::bounds&4 is set. Documented the new bounds checking implemented by prjbchk() in the prologue entry for wcsbchk(). Improvements to tprj1 to test the vector API of prjx2s() and to deal better with out-of-bounds native coordinates returned by it. - Bug fixes in the projection routines: in hpxx2s() relating to bounds checking, bug introduced at 4.20, reported by Michael Droettboom; in parx2s() and molx2s() relating to setting the stat vector; in hpxx2s() relating to implementation of the vector API; and in xphx2s() relating to setting an out-of-bounds value of phi. * Fortran wrappers - Wrapper for prjbchk(). Modified tprj1.f to track changes to the C version. WCSLIB version 4.20 (2013/12/18) -------------------------------- * C library - New function, wcsbchk(), for controlling bounds checking in the projection routines. - Enable bounds checking in the pixel-to-sky (x2s) direction for HPX and XPH if prjprm::bounds&2. Tightened bounds checking in xphx2s(). prjini() now sets prjprm::bounds = 3 to enable all bounds checking by default. - Fixed an incorrect error message in wcs_units(). Also report potentially unsafe units translations in unitfix() - both contributed by Michael Droettboom. * Fortran wrappers - Wrapper for wcsbchk(). * PGSBOX - Fixed a few nuisance warnings from gfortran 4.7.2 relating to implicit type conversions in pgsbox.f. * User manual - Added mention of wcsjs (Javascript) in the section on other packages. WCSLIB version 4.19 (2013/09/30) -------------------------------- * C library - Bug fix in wcshdo(), uncovered by cppcheck and reported by David Binderman. Fixed additional minor inconsistencies in hpxx2s(), wcsprintf(), and wcsfprintf() reported by cppcheck. - Minor fix to twcstab reported by cppcheck. - Bug fix in wcssub() for handling (non-standard) PROJPn keywords (uncovered by valgrind, reported by Paul Price). WCSLIB version 4.18 (2013/07/13) -------------------------------- * C library - Implemented the butterfly projection (XPH), being the polar form of the HEALPix projection with (H,K) = (4,3). Augmented tprj1.c and tprj2.c to suit. - Bug fix in celfix() when translating GLS to SFL with non-zero reference point. * Fortran wrappers - Wrappers for the XPH projection functions and corresponding modifications to the test programs. - Fixed a few inconsequential warnings from gfortran 4.7.2 relating to implicit type conversions in the test programs. * Utilities - In HPXcvt, fixed incorrect axis scaling (CDELT1 and CDELT2) in the XPH header, and set the PCi_ja matrix in the HPX header to a pure 45 degree rotation with appropriate adjustment of CDELT1 and CDELT2 (matching XPH). Also set LONPOLE to 180 degree in the XPH header with adjustment of CRVAL1 as recommended in the errata. These changes prompted by Paddy Leahy. Also, modified the FITS header comment for XPH - it is no longer "experimental", and accept the '-x' option (i.e. without qualification) as equivalent to '-xn'. * User manual - Documentation generation moved to doxygen 1.8.4 (was 1.5.6). WCSLIB version 4.17 (2013/01/29) -------------------------------- * C library - Added wcsfprintf() to wcsprint.h. Now used in wcsbth() and wcspih() to allow diagnostic output to be redirected. Changes provided by Michael Droettboom. WCSLIB version 4.16 (2012/11/07) -------------------------------- * C library - When wcspih() constructs a default coordinate representation it will give it the special name "DEFAULTS", and will not report "Found one coordinate representation" (if reporting is enabled). * Utilities - wcsware has a new option, -P, which does the same as -p except that it won't print a wcsprm struct with the name "DEFAULTS". WCSLIB version 4.15 (2012/09/26) -------------------------------- * C library - Bug fixes in spctype(), spcspxe(), spcxpse, and spctrne() for propagating an error status correctly from lower-level routines. Amendments to the prologues of these routines. Reported by Hans Terlouw. - Similarly for wcsunitse(), wcsulexe(), and wcsutrne(). * PGSBOX - Bug fix in PGSBOX for handling cycles in angle when both world coordinate elements are angular. Reported by Thomas Robitaille. WCSLIB version 4.14 (2012/07/13) -------------------------------- * C library - Problems were caused for fitshdr(), wcsbth(), wcspih(), wcsulex(), datfix() and wcshdo(), by locales such as "fr_FR" in which commas are used to delimit the decimal part of floating point numbers. In particular, these locales adversely affect the behaviour of sscanf() and sprintf() when reading and writing FITS header keyvalues. Thread-safe fixes provided by Michael Droettboom. - Applied astropy patches from Michael Droettboom: attend to compiler warnings in prj.c, spc.c, tab.c, and wcsutil.c, including those for MS-Windows. WCSLIB version 4.13.4 (2012/04/02) ---------------------------------- * Installation - Relaxed the closure tolerance slightly in tlog.f as for tlog.c previously. WCSLIB version 4.13.3 (2012/03/26) ---------------------------------- * Installation - Relaxed the closure tolerance slightly in tlog.c for gcc 4.6.3 on Ubuntu 12.04 (reported by Ole Streicher). WCSLIB version 4.13.2 (2012/03/21) ---------------------------------- * Installation - Changes to configure.ac and the GNUmakefiles to put '-lm' strictly in the correct sequence when producing the sharable library (reported by Ole Streicher). WCSLIB version 4.13.1 (2012/03/15) ---------------------------------- * C library - Workaround in wcserr_set() for an unfortunate compiler segv from gcc 4.2.1 in MacOSX 10.7. WCSLIB version 4.13 (2012/03/14) -------------------------------- * C library - Allow naxis == 0 in wcsini() and linini() for a degenerate coordinate system as may be produced by wcssub(). In wcssub(), ensure that wcsini() is called for coordinate systems with naxis == 0. In wcssptr(), call spcfree() before spcini() to plug a memory leak. WCSLIB version 4.12 (2012/02/29) -------------------------------- * C library - In spctrne(), guard against restfrq == restwav == 0.0 when translating between two velocity-characteristic types, or between two wave-characteristic types (the translation is independent of restfrq and restwav, but a dummy value is needed for intermediate calculations). WCSLIB version 4.11 (2012/02/21) -------------------------------- * C library - Bug fix in spcset() for handling simple linear spectral axes. * Fortran wrappers - Bug fix in spctrne_() for handling ctypeS2. WCSLIB version 4.10 (2012/02/06) -------------------------------- * C library - datfix() and spcfix() now return informative messages when dates and AIPS-convention spectral axes are translated (changes contributed by Michael Droettboom). spcaips() now returns an error status for invalid values of VELREF. - wcssub() has been augmented with the ability to add new axes onto a wcsprm struct. WCSLIB version 4.9 (2012/01/24) ------------------------------- * C library - Fixes to wcsfixi() for collecting the messages properly in the info array (from Michael Droettboom). - Handle certain malformed date strings more gracefully in datfix(). - Make informative messages printed by wcserr_prt() a bit more informative. WCSLIB version 4.8.4 (2011/12/05) --------------------------------- * C library - Fixed the pseudo-random number generator in twcstab.c - gcc 4.6 with '-O2' baulked at testing for signed integer overflow. * Installation - In configure.ac, the Fortran compiler's libraries must be added to the link list when checking for the PGPLOT libraries since gcc is driving the linker. Likewise in C/GNUmakefile when linking test programs that use PGPLOT. - Use 'make CHECK=nopgplot check' to run only the non-graphical tests (even if PGPLOT is available). - After compiling and running the tests, 'make check' now summarizes the non-graphical test results and stops if any failed. WCSLIB version 4.8.3 (2011/11/17) --------------------------------- * C library - Minor generalization of the wcserr diagnostics to allow the return of informative messages, which are associated with negative status values. wcserr_prt() will now recognize and print them as such. Added wcserr_clear() to reset (clear) a wcserr struct. - Modified unitfix() to return an informative message if a units alias is applied, and wcsfixi() to allow such messages to be propagated through the info array (from Michael Droettboom). - Modified twcsfix.c to use wcserr diagnostics, in particular to report units alias translations. * Fortran wrappers - In wcsfix_(), interpret *naxis == 0 as meaning naxis == 0x0, thus causing cylfix() to be skipped. - Modified twcsfix.f to reflect changes made to twcsfix.c. WCSLIB version 4.8.2 (2011/10/04) --------------------------------- * Installation - Changes for Debian package generation contributed by Ole Streicher: - Corrections to 'configure' reported by 'lintian'. - Generate man pages for the utility programs and install them. WCSLIB version 4.8.1 (2011/09/19) --------------------------------- * Installation - Set SONAME in the sharable library in accordance with tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html (reported by Ole Streicher, Debian package maintainer). The sharable library will again be installed with full release number and with a symbolic link from SONAME pointing to it. If defined, SHRLN will point to SONAME. WCSLIB version 4.8 (2011/08/15) ------------------------------- * C library - New error diagnostics mechanism contributed by Michael Droettboom: Most functions that return a numeric status (error) code now also write a detailed error message to a wcserr struct attached to the passed-in *prm struct. See wcserr.h for more information. Functions that didn't have a *prm struct as an argument have no direct way to return an error message. Therefore, these functions now have duplicate versions with the suffix "e" that take an additional "struct wcserr *" parameter. These functions are: spcspx() -> spcspxe() spctrn() -> spctrne() spctyp() -> spctype() spcxps() -> spcxpse() wcsulex() -> wcsulexe() wcsunits() -> wcsunitse() wcsutrn() -> wcsutrne() A new function wcsfixi() was added which is identical to wcsfix() but in addition stores all of the detailed textual messages about the fixes that were performed. - In wcssub(), ensure that wcstab->m_tab has been initialized before trying to free it on status return 12 or 13 (reported by Hans Terlow). - Bug fixes: - In sphx2s() and sphs2x() for the case where |eul[1]| = 180.0. - For parsing AIPS-convention VELREF in wcsbth(). - In spcaips() for translating AIPS-convention CTYPEia without Doppler frame. - Non-graphical test programs now simply report "PASS" if they satisfy the reporting tolerance for closure residuals, etc. Their full output is reported otherwise. Run 'make MODE=interactive check' to revert to the previous behaviour of reporting the full output for tests that succeed. - Eliminated compiler warnings about type-punning of pointer-to- function. * Fortran wrappers Extensive modifications to track the new error handling mechanism in the C library. * Installation - configure now prefers gfortran over g77 if available. - Don't rely on "." being in the PATH if config.status needs to be run in the pgsbox and utils makefile (reported by Peter Teuben). WCSLIB version 4.7 (2011/02/07) ------------------------------- * C library - Bug fix in celset() for interpreting LATPOLEa when LONPOLEa = phi0. Crept in at version 4.4. - Fixed the bounds test on y in hpxx2s() (HEALPix projection) for unconventional values of H and K. In hpxx2s() and hpxs2x(), corrected the offset of the southern polar half-facets for even K. In hpxs2x(), put the phi = 180 meridian in the expected place. - Bug fixes in tabx2s() and tabs2x() for default indexes (reported by David Berry). In tabs2x(), if no solution is found then do minor extrapolation past the ends of each row (1-D case only). Sped up tabs2x() by about 50%. - New functions wcsprintf(), wcsprintf_set(), and wcsprintf_buf(), declared in wcsprintf.h, provide control over the disposition of output from celprt(), linprt(), prjprt(), spcprt(), tabprt(), and wcsprt() routines. Prompted by Michael Droettboom, with an initial implementation. * Fortran wrappers - In the various test programs, used EQUIVALENCEs to ensure that the CEL, LIN, PRJ, etc. arrays are aligned on a DOUBLE PRECISION boundary. * PGSBOX - Bug fix for the case where NG1 == 0 and GRID1(0) < 0, and likewise for NG2 and GRID2. * Utilities - In wcsware, added a '-w' option to convert world coordinates obtained from stdin to pixel coordinates using wcss2p(). Allow multiple sets of input coordinates with the '-x' and '-w' options and report the value of the intermediate world coordinates. * User manual - Fixed list formatting for function return values < 0 or > 9. - New section for wcsprintf() and related routines. * Installation - Changes prompted by Sébastien Fabbro for the Gentoo Linux package: a) autoconf updates, b) respect LDFLAGS when building the shared library, c) install documentation, d) recognise DESTDIR for doing a staged installation. - As of this release, the minor WCSLIB version number (second field) will be incremented if and only if a change is made that affects the library itself, not the documentation or utilities. The version number on the installed libraries and header files will omit the patch number (third field). WCSLIB version 4.6.3 (2010/11/24) --------------------------------- * C library - Bug fix in wcsbth() for handling the inheritance of image header keywords (uncovered by valgrind, reported by Jim Lewis). WCSLIB version 4.6.2 (2010/11/22) --------------------------------- * C library - Fixed a memory leak in wcsbth.l (reported by Jim Lewis). WCSLIB version 4.6.1 (2010/11/18) --------------------------------- * Fortran wrappers - Fixed typos in cel_f.c, celget[cdi] -> celgt[cdi]. WCSLIB version 4.6 (2010/11/16) ------------------------------- * C library - In wcsulex.l and wcsutrn.l, stdlib.h must be included explicitly before the redefinition of exit() - most versions of flex do include it upfront but some don't (reported by Peter Williams). * Fortran wrappers - Changes intended to avert nuisance compiler warnings that could potentially obscure warnings indicative of a genuine problem: - To stop messages about unused variables when the relevant compiler option is set, e.g. 'g77 -Wunused', the various *_ERRMSG arrays defined in the Fortran include files and (formerly) initialized therein via DATA statements, e.g. PRJ_ERRMSG in prj.inc, have now been placed into COMMON blocks with names such as PRJ_DATA, and are initialized via DATA statements in BLOCK DATA subprograms defined in separate files, e.g. prj_data.f. - To stop messages about subroutines being invoked with inconsistent argument lists if the relevant compiler option is not set, e.g. 'g77 -Wno-globals', the C wrapper functions that take 'void *' arguments now have separate forms for INTEGER, DOUBLE PRECISION, and CHARACTER arguments that simply invoke the generic function. Application code must be modified to take advantage of this. * User manual - In the section on the Fortran wrappers in the manual, warn about the need for the INTEGER array holding a data structure to be aligned on a DOUBLE PRECISION boundary. WCSLIB version 4.5.6 (2010/10/28) --------------------------------- * Installation - Fixed the search for CFITSIO and PGPLOT library and include directories. WCSLIB version 4.5.5 (2010/10/14) --------------------------------- * Installation - Build the PGSBOX sharable library. WCSLIB version 4.5.4 (2010/09/28) --------------------------------- * C library - In wcshdo(), according to the FITS standard, "Letters in the exponential form ('E' or 'D') shall be upper case" (reported by Michael Droettboom). WCSLIB version 4.5.3 (2010/09/23) --------------------------------- * Utilities - Various improvements to wcsgrid: correct the scaling set via cpgwnad(); label angles other than RA,Dec in decimal degrees; draw the projection boundary for projections other than zenithals. WCSLIB version 4.5.2 (2010/09/23) --------------------------------- * C library - Fixed the translation of GLS to SFL in wcsset() and celfix() when the reference longitude is non-zero - it introduces an offset in longitude in the normal way. (This undoes part of the change applied in version 4.4.) WCSLIB version 4.5.1 (2010/08/12) --------------------------------- * C library - New utility function, sphpad(), computes the coordinates of points offset by given angular distances and position angles from a given point on the sky (complementary to sphdpa()). * Fortran wrappers - New wrapper function: - SPHPAD for sphpad(). WCSLIB version 4.5 (2010/07/16) ------------------------------- * C library - Fixed the interpretation of VELREF when translating AIPS-convention spectral types. Such translation is now handled by a new special- purpose function, spcaips(). The wcsprm struct has been augmented with an entry for velref which is filled by wcspih() and wcsbth(). Previously, selection by VELREF of the radio or optical velocity convention for type VELO was not properly handled. * Fortran wrappers - New wrapper function: - SPCAIPS for spcaips(). - Changed spc.inc, spc_f.c, wcs.inc and wcs_f.c to track VELREF changes. - Declared functions external in the include files to avoid compiler warnings about unused variables (if the particular option is set). * Utilities - Added a '-q' option to fitshdr to quit after a specified number of HDUs. WCSLIB version 4.4.4 (2009/09/14) --------------------------------- * Installation - Added more configure options for controlling the build: --disable-fortran, --disable-utils, --without-cfitsio, and --without-pgplot. WCSLIB version 4.4.3 (2009/09/03) --------------------------------- * C library - Set wave number units to "/m" in spctyp(), was "1/m" which is not strictly legal and wasn't handled by wcsulex() (reported by Hans Terlow). Also fixed a number of units specifications in the prologue of spx.h to conform with Paper I usage. - In wcsulex(), allow unit strings like "1/m" in addition to "/m", provided that the superfluous "1" is the first non-blank character in the expression, or parenthesised sub-expression. - In wcssptr(), ensure that i is always reset if given < 0. * User manual - Augmented the list of FITS WCS and related software in the manual. WCSLIB version 4.4.2 (2009/08/13) --------------------------------- * C library - In sphx2s() and sphs2x(), handle the case where |eul[1]| = 180.0 separately for speed and accuracy. This change also fixes a rare and subtle bug in cels2x() that occurs when celprm::isolat is set and the magnitude of the first latitude in the lat[] vector exceeds 90 deg (reported by Hans Terlouw). * Installation - Fix relating to creation of symlinks when installing the libraries. WCSLIB version 4.4.1 (2009/08/11) --------------------------------- * Installation - Fixes for installation of the CHANGES file and for the creation of a symbolic link for the sharable library if one already exists. WCSLIB version 4.4 (2009/08/10) ------------------------------- * C library - Creation of WCSLIB user manual from the header file prologues using a special-purpose parser, doxextr, and sed scripts to generate input for doxygen. This required minor formatting changes to all prologues plus miscellaneous changes such as naming of arguments in function prototypes. - Bug fix in wcsset() that affected handling of PROJPn (deprecated) and PVi_ma attached to the longitude (not latitude) axis. Guard against long strings when copying the projection code. In wcs_types(), allow for early Paper IV distortion codes (e.g. "RA---TAN-SIP") when parsing CTYPEia. - Use sincos() whereever possible for a ~15% speedup (patches for cel.c, prj.c and sph.c supplied by Michael Droettboom). configure checks for, and uses it automatically if available. - Fixed the translation of GLS to SFL in wcsset() and celfix() when the reference longitude and latitude are non-zero. (In the AIPS convention, this simply translates the reference point, i.e. the map as a whole, to those coordinates without creating an oblique grid.) - Bug fix in prjoff(), a utility function used by the prj routines. It forces (x,y) = (0,0) at (phi_0,theta_0) when the latter are set by PVi_[012]a attached to the longitude (not latitude) axis. Rarely used in practice. - New utility function, sphdpa(), computes the distance and position angle from a point on the sphere to a set of field points. - In sphx2s() and sphx2s(), handle a simple change in origin of longitude using a short-cut calculation for speed and accuracy. Similarly in celset(), check whether phip == phi0 when computing latp and if so use a short-cut that ensures latp == 90.0 (exactly) if lat0 == theta0. The resulting spherical rotation then becomes a simple change in origin of longitude. In particular, these changes should assist PGSBOX in drawing grid lines of +/-180 longitude, to prevent flip-flopping between one and the other. - wcsbth() & wcspih(): resolved an inconsistency between the documentation and code by renamimg WCSHDR_VSOURCEa as WCSHDR_VSOURCE. - Flex code: moved declaration of helper functions out of global scope. - Fixed the call to wcss2p() in twcshdr (in a section of code not usually exercised). * Fortran wrappers - New wrapper functions: - WCSBTH for wcsbth(), - WCSBDX for wcsbdx(), - CDFIX for cdfix(), - SPHDPA for sphdpa(). - Updated WCSLEN (in wcs.inc) and added WCS_COLAX and WCS_VELANGL to match changes to wcsprm made in v4.3 with corresponding changes to the wrapper functions. Likewise updated TABLEN (in tab.inc) for changes to tabprm, and added CEL_LATPREQ for celprm. - Struct lengths (WCSLEN, PRJLEN, etc.) are now long enough to accomodate 64-bit machines. - Updated the flag bits for the RELAX argument in wcshdr.inc to reflect changes to wcshdr.h made in v4.3. Renamed WCSHDR_VSOURCEa to WCSHDR_VSOURCE for consistency with the C library. * PGSBOX - Improved grid labelling, particularly in minimizing the number of fields required in sexagesimal labels. * Utilities - New utility program: - wcsware extracts the WCS keywords for an image from the specified FITS file, constructs wcsprm structs for each coordinate representation found, and performs a variety of operations using them. - Old utility programs (first appeared in 4.3 but were not recorded): - HPXcvt reorganises HEALPix data into a 2-D FITS image with HPX coordinate system. - wcsgrid extracts the WCS keywords for an image from the specified FITS file and uses pgsbox() to plot a 2-D coordinate graticule for each alternate representation found. - fitshdr lists headers from a FITS file specified on the command line, or else on stdin, printing them as 80-character keyrecords without trailing blanks. * Installation - New configure options, --with-pgplotinc, --with-pgplotlib, --with-cfitsioinc and --with-cfitsiolib allow additional directories to be added to the library and include file search path. - Miscellaneous fixes and improvements to the installation process. - Generate a metadata file for pkg-config. - Added 'make MODE=interactive check' to run the test programs in interactive mode rather than batch. - Merged the separate CHANGES files for C, Fortran and PGSBOX into one (this), with a new section for utilities. WCSLIB version 4.3.3 (2009/04/30) --------------------------------- * C library - fitshdr.l, wcsbth.l, and wcspih.l: use setjmp/longjmp to preempt the call to exit() which is hard-coded in function yy_fatal_error() supplied by flex. - wcspih.l: if NAXIS is non-zero but there were no WCS keywords at all in the header then create a default WCS with blank alternate version. WCSLIB version 4.3.2 (2009/03/16) --------------------------------- * C library - utils/GNUmakefile: create BINDIR if necessary prior to installing utilities. WCSLIB version 4.3.1 (2008/09/08) --------------------------------- * Installation - Top-level GNUmakefile: install header files. WCSLIB version 4.3 (2007/12/27) ------------------------------- * C library - A new general WCS header parser wcsbth() handles binary table image arrays and pixel lists as well as image array headers. Added "colax" to the wcsprm struct to record the column numbers for each axis in a pixel list. - New function wcsbdx() is the analog of wcsidx() for the array of wcsprm structs returned by wcsbth(). - New function wcshdo() writes out a wcsprm struct as a FITS header. - Changes to wcspih(): - Bug fix, check for a == 0 (indication of a keyword that applies to all alternates) in internal helper function wcspih_naxes() (reported by Craig Markwardt). - Added a new ctrl option to remove valid WCS keyrecords except for those with a more general role, namely {DATE,MJD}-{OBS,AVG} and OBSGEO-{X,Y,Z} (suggested by Jim Lewis). - Added a rule for VELANGLa. Also added "velangl" to the wcsprm struct. - Do checks on the i, k & m keyword parameters in . - Fixed the test for repeated blanks in the NAXIS and WCSAXES patterns. - Fixed three rules to allow m == 0. - Reworked the implementation notes in the prologue. - The flex scanners, fitshdr.l, wcsbth.l, wcspih.l, wcsulex.l, and wcsutrn.l, invoke yylex_destroy() before returning to avoid a 16kiB memory leak. This was reported by several people, however it may be problematic depending on the version of flex used - version 2.5.9 or later is required. If this is not available, C sources pre- generated by flex 2.5.33 will be used. - In wcs.c, don't define the signbit macro if already defined (for MacOSX). - In wcs.h, documented wtbarr namespace issues in C++. - In wcsset(), always set wcsprm.cunit[i], if possible (primarily for use by wcshdo()). - In wcsfix.c, parenthesised a boolean expression that was otherwise incorrect. - Fixed an obscure floating point rounding error in celset() that appeared with -O2 optimization in gcc v3.3.5 (Linux). - prjset() now correctly propagates the status value returned by the specific projection-setting functions (reported by Bill Pence). - Bug fix in hpxx2s(), also added bounds checking. Minor efficiencies in carx2s() and merx2s(). - In the various functions that print the contents of the structs, use the "%p" printf conversion specifier to print addresses rather than casting the pointer to int and using "#x". The latter does not work on 64-bit machines where sizeof(int) != sizeof(void*). - Reorganized the various structs to get alignment on 64-bit machines. - All header file prologues now reference the README file for an overview of the library. - Miscellaneous portability fixes for 64-bit, MacOSX, OSF compiler, etc. - Elimination of compiler warnings, e.g. parenthesised assignments used as truth values (a favourite gcc gripe!), etc. - Process flex descriptions using a newer version of flex, primarily for MacOSX. However, the processed files are now only used when flex 2.5.9 or later is not available. - Removed WCSLIB 2.x backwards-compatibility measures from lin.h, prj.h, prj.c, and sph.h. * Fortran wrappers - (No substantive changes.) * PGSBOX - Miscellaneous improvements to PGSBOX. * General - Switched licensing to LGPL 3.0. - In comment text, replaced use of the obsolete term "card" with "keyrecord" which consists of a "keyword", "keyvalue", and "keycomment". * Installation - General improvements to the installation process: autoconf-related portability improvements, particularly relating to Fortran name mangling; makefile rules for building the shared library, for processing flex descriptions; don't rely on "." being in the PATH when running tests. WCSLIB version 4.2 (2005/09/23) ------------------------------- * C library - Brought the installation process under control of GNU autoconf, the top-level makefile now builds and tests everything, and the C library has a config.h in which WCS_INT64 is set. Added an INSTALL file. - Merged the FORTRAN, C and PGSBOX READMEs into one top-level README. - Extensions for -TAB coordinate handling: in tabx2s() and tabs2x(), allow extrapolation by half a cell at either end of the index and coordinate tables; fits_read_wcstab() (in getwcstab.{h,c}) allows TDIMn to be omitted for 1-D lookup tables for which it has the form '(1,K)', i.e. describing a degenerate 2-D array; wcsprt() now prints the wtbarr structs in wcsprm. - Bug fixes for -TAB coordinate handling: in tabx2s() and tabs2x() the incorrect indexing variable, m instead of i, was used for tab->crval[]; wcsp2s() and wcss2p() returned prematurely in the tabular coordinate loop; in wcstab(), removed an extraneous assignment to wtbp->kind for index arrays. - In wcsp2s() and wcss2p(), elements of the stat[] vector that had been set were being reset incorrectly to zero. The stat[] values are now set as flag bits for each coordinate element. - Added cdfix() to the wcsfix() suite to fix erroneously omitted CDi_ja cards. - PGSBOX is now compiled into a separate object library, and is installed alongside WCSLIB. - Eliminated several instances of non-ANSI C library functions and header files and some residual K&R C usage. The Sun C compiler complained about const int definitions of initializers used in variable declarations in some of the test programs; changed these to preprocessor macros. * Fortran wrappers - Fixed handling of 64-bit integer keyvalues in keyget_(). - Fixed output formatting of 64-bit integer keyvalues in tfitshdr.f. - Fixed minor syntax errors in twcsfix.f and tpih1.f reported by the Sun Fortran compiler. - The output of each test program now identifies the source file. * PGSBOX - (No substantive changes.) WCSLIB version 4.1 (2005/08/31) ------------------------------- * C library Summary of added functionality: - -TAB coordinate axes are now fully implemented in the WCSLIB driver functions (in wcs.{h,c}); multiple -TAB axes are supported. A new function, wcstab(), which is automatically invoked by wcspih(), parses -TAB-related header cards and sets up structs for a separate routine that reads the necessary arrays from a FITS binary table extension. An implementation of this routine in CFITSIO, fits_read_wcstab(), is provided. Note however that the interface of this function is experimental, and the code itself must be considered beta-release in WCSLIB 4.1. - Units specifications, either from CNAMEia or inline comments (with brackets), of arbitrary complexity are now fully implemented via a parser, wcsulex(), and converter, wcsunits(). This is invoked automatically by wcsset(). - Translators for non-standard WCS constructs are provided. These cover date formats, units specifications, defunct celestial projection types, AIPS spectral axis types, and the repair of malformed cylindrical coordinate systems. - wcspih() now has options to remove the WCS cards it has processed from the header and a new generic FITS header parser, fitshdr(), may be used to parse the remaining non-WCS cards. In addition to the more basic types, it handles 64-bit and 'very long' (70 digit) integer keyvalues, and also continued string keyvalues. It also does keyword matching and extracts units specifications in inline comments. - -LOG coordinates are now implemented independently of spectral coordinate types. Multiple -LOG axes are supported. - New function wcssptr() translates the spectral axis in a wcsprm struct to the required type. - The README file now gives an introduction to, and complete overview of, WCSLIB. It provides a point of entry to programming with WCSLIB. Complete descriptions and usage notes for all functions are contained in the header files. - The FORTRAN wrappers and test programs are now completely up-to-date with respect to the C implementation. - All code, including the FORTRAN wrappers, PGSBOX, and all test programs, now pass 'purify' without memory leaks, uninitialized memory reads, memory access violations, or other memory faults. Change notes: - Added options to wcspih() to remove WCS cards from the input header leaving only non-WCS cards behind. Modified test programs tpih1.c and tpih2.c to use CFITSIO optionally via preprocessor macro DO_CFITSIO. - New function wcstab() in wcshdr.{h,c} parses -TAB-related header cards and sets up structs for a separate routine that reads the necessary arrays from a FITS binary table extension. New test/demo program twcstab.c using header defined in wcstab.cards. - CFITSIO implementation, fits_read_wcstab() in getwcstab.{h,c}, of a function, independent of WCSLIB, for extracting arrays from a binary table as required in constructing -TAB coordinates. - New units specification parser, wcsulex() in wcsunits.h and wcsulex.l, and converter, wcsunits() in wcsunits.{h,c}. New test/demo program tunits.c. - New parser for non-standard units specifications, wcsutrn() in wcsunits.h and wcsutrn.l, also tested by tunits.c. - New functions datfix(), unitfix() (which applies wcsutrn()), celfix(), and spcfix() join cylfix() in wcsfix.{h,c} to translate various forms of non-standard or quasi-standard FITS WCS keyvalues in a wcsprm struct. wcsfix() applies all of these in sequence. New test/demo program twcsfix.c, with wcsfix() also now invoked by tpih1.c. - New generic FITS header parser, fitshdr() in fitshdr.{h,l}. New test/demo program tfitshdr.c uses wcs.cards with extra non-WCS cards added. - -LOG coordinates are now treated as a coordinate type separate from spectral coordinates, implemented via log.{h,c} and test program tlog.c. The logarithmic functions were removed from spx.{h,c}, and spc.c. - Extensive changes to wcs.{h,c} to support multiple -TAB and -LOG coordinate axes and units conversion. Substantially changed the test program, twcs.c, to test the more general functionality. - New function wcssptr() in wcs.{h,c} translates the spectral axis in a wcsprm struct. - Added DATE-AVG to wcsprm. Also ntab, tab, nwtb, and wtb required for -TAB implementation. Define struct wtbarr. - Added a types[] member to the wcsprm struct to identify axis coordinate types using a four-digit code. - Use memset() in wcsini() to null-fill character arrays in the wcsprm struct so that they don't appear to be padded with garbage when displayed by gdb. - Do alias translation for AIPS-convention spectral types in wcsset() using spctyp(). If wcsset() finds a CTYPEia in "4-3" form with an unrecognized algorithm code it now returns an error rather than assume that it's a linear axis. wcsset() now also resets lonpole and latpole to the values actually used. - Modified spctyp() to translate AIPS-convention spectral ctypes, and modified the argument list to return the parsed spectral type and algorithm code. The return arguments will not be modified if CTYPEia is not a valid spectral type; zero-pointers may be specified for any that are not of interest. Removed the external const variables, spc_codes and spc_ncode, as their function is now fulfilled by spctyp(). - Fixed a bug in spctrn() in resolving ctypeS2 wildcarding. - Added latpreq member to the celprm struct, set by celset() to indicate how LATPOLE is used. Augmented tcel2.c to report it. - New function tabmem() in tab.{h,c} takes control of user-allocated memory. - tabini() allows K == 0 and also K[m] == 0 to initialize partially the tabprm struct (for wcstab()). It now does fine-grained bookkeeping of memory allocation for the index arrays and allocates each individually. tabprm.index[] == 0x0 is recognized as default indexing in tabset(), tabx2s() and tabs2x(). - The *prt() functions report parameters to an extra decimal place. - tabprt() prints the array index for elements of the coordinate and index vectors. - Set the 0th element in all *_errmsg arrays to "Success". - Extracted string utility functions used by WCSLIB into wcsutil.{h,c}. - Removed support for K&R C. * Fortran wrappers - The FORTRAN wrappers and test programs are now completely up-to-date with respect to the C implementation. - New include files, wrappers, and test programs: fitshdr.inc, fitshdr_f.c, getwcstab.inc, getwcstab_f.c, log.inc, log_f.c, sph.inc, tab.inc, tab_f.c, tfitshdr.f, tlog.f, ttab1.f, ttab2.f, ttab3.f, tunits.f, twcsfix.f, twcstab.f, wcsfix.inc, wcsfix_f.c, wcsunits.inc, wcsunits_f.c. - Updates to reflect changes to the C library and test programs: cel.inc, cel_f.c, prj.inc, spc.inc, spc_f.c, spx.inc, spx_f.c, tlin.f, tpih1.f, tpih2.f, tprj1.f, tprj2.f, tspc.f, tsph.f, tspx.f, twcs.f, twcsmix.f, twcssub.f, wcs.inc, wcs_f.c, wcshdr.inc, wcshdr_f.c. - Added *_ERRMSG arrays containing status messages to all include files. - Removed support for K&R C. * PGSBOX - Fixed a subtle though benign memory fault identified by 'purify'. - Reset LATPOLE in the COE example in cpgtest.f when drawing the second (native) grid because it will have been set to a non-default value by wcsset() when the first grid was drawn; set wcs.flag to -1 before wcsinit() and call wcsfree() at the end. Similarly for pgtest.f. WCSLIB version 4.0 (2005/02/07) ------------------------------- * C library - Implemented tabular coordinates (-TAB). New files: tab.h and tab.c, and test programs ttab[123].c. These have not been incorporated into the higher-level (wcs.h) functions at this stage. - New spectral functions: spchek() checks a spectral algorithm code for legitimacy; from the spectral keywords given, spcspx() derives the corresponding CRVALi and CDELTi keywords for the underlying P-, and X-type spectral coordinates; spcxps() does the opposite; spctrn() combines spcspx() and spcxps() to translate one set of spectral keywords into another, e.g. 'FREQ' -> 'ZOPT-F2W'. - Implemented the HEALPix (HPX) projection in the prj functions. - Added a new function, wcsidx(), to return an array that indexes the alternate coordinate descriptions found by wcspih() (suggested by Bill Pence, NASA/Goddard). Modified tpih1.c to exercise it. - In wcsp2s() and wcss2p(), check that nelem equals or exceeds wcs.naxis; emphasised this in the usage notes for these functions in tab.h (suggested by Bill Pence, NASA/Goddard). - Moved the macros used for UNDEFINED values and the corresponding macro test function, undefined(), to wcsmath.h for general use. Previously, UNDEFINED values were only used internally, but they are now visible in some of the structs, particularly values of undefined auxiliary header cards in the wcsprm struct. - Remove const from the double args in the specx() prototype in spx.h to match the definition in spx.c (reported by Bryan Irby, NASA/Goddard). - Fixed the interaction between the FLAVOUR and PGPLOTLIB definitions in the C and FORTRAN Makefiles by introducing a separate variable, DO_PLOTS, to control whether to exercise test programs that require PGPLOT (reported by Bill Pence, NASA/Goddard). * Fortran wrappers - New wrapper defined in wcshdr_f.c: wcsidx_(). Modified test program tpih1.f to use it. * PGSBOX - (No substantive changes.) * General - Changed the copyright notice in all library routines from LGPL to GPL as recommended by the FSF (http://www.gnu.org/licenses/why-not- lgpl.html). * Installation - General improvements to the installation process: fixed the interaction between the FLAVOUR and PGPLOTLIB definitions in the Makefile by introducing a separate variable, DO_PLOTS, to control whether to exercise test programs that require PGPLOT (reported by Bill Pence, NASA/Goddard). Added an "install" target to the Makefile. WCSLIB version 3.6 (2004/08/25) ------------------------------- * C library - New service routine, wcssub() extracts the coordinate description for a subimage from a wcsprm struct. wcscopy() is now implemented as a preprocessor macro that invokes wcssub(). New test program, twcssub.c, tests wcssub(). - In wcspih(): 1) Fixed handling of string-valued keywords where the inline comment contains a single-quote character ('). 2) Fixed the address arithmetic for EPOCH and VELREF. 3) Translate VSOURCEa into ZSOURCEa if required. 4) Recognize SSYSSRCa. 5) Support free-format string keyvalues, as well as integer and floating-point keyvalues; documented this in the prologue of wcshdr.h. 6) Allow header cards without inline comments. 7) Fixed function prototyping in wcspih.l (i.e. ANSI and non-ANSI forms were potentially mixed). 8) Catch an unhandled newline character on the END card that was echoed to stdout. 9) In error messages, print "ERROR" (uppercase) - POSIX standard. - Modified wcs.cards to explain and test free-format keyvalues, and also augmented the inline comment on illegal WCS cards that are to be rejected, and WCS-like cards to be discarded. Added a header card with no inline comment. - Removed vsource from the wcsprm struct and added ssyssrc. - In wcsini(), fixed a problem with memory management for wcs.pv when NPVMAX is zero; likewise for wcs.ps and NPSMAX. - In wcsprt(), don't print auxiliary coordinate system information in arrays with zero address. - In wcss2p(), status == 9 (one or more invalid world coordinates) was not returned appropriately. - Renamed twcs1.c to twcs.c, and twcs2.c to twcsmix.c. - "Error status/code/number" is now referred to consistently as the "status return value". - Some vestiges of K&R C were removed: preprocessor definition of const, and K&R function prototypes. * Fortran wrappers - New wrapper defined in wcs_f.c: wcssub_(). New test program, twcssub.f. - Renamed twcs1.f to twcs.f, and twcs2.f to twcsmix.f. * PGSBOX - (No substantive changes.) * Installation - Worked over the C, FORTRAN, and PGSBOX makefiles, in particular to make them all consistent. WCSLIB version 3.5 (2004/06/28) ------------------------------- * C library - WCSLIB now provides a function, wcspih() implemented as a Flex description, that parses a FITS image header, either that of a primary HDU or an image extension. Given a character array containing the header it identifies and reads all WCS cards for the primary coordinate description and up to 26 alternate descriptions and returns this information as an array of wcsprm structs. A service routine, wcsvfree(), is provided to free the memory allocated by wcspih(). The relevant header file for these functions is wcshdr.h. Test programs, tpih1 and tpih2, are provided to verify wcspih. The first simply prints the contents of the structs using wcsprt(). The second uses cpgsbox() to draw coordinate graticules. A FITS WCS test header has been developed to provide input to these test programs. It is implemented as a list of card images, wcs.cards, one card per line, together with a program, tofits, that compiles these into a valid FITS file. tpih1 uses its own code to read this, whereas tpih2 uses the fits_hdr2str() function from CFITSIO. - Removed twcsprt, tpih exercises wcsprt() much more thoroughly than twcsprt ever did. Modified twcs1 to print the size of the various structs as twcsprt used to. - Although they are not used in any coordinate calculations, the wcsprm struct now provides data members for storing all of the auxiliary FITS WCS header cards defined in Papers I, II, and III, such as WCSNAMEa, EQUINOXa, and CNAMEia. Members are also provided for storing the alternate descriptor code (the "a" in CTYPEia), and the binary table column number. These are supported by the high level WCSLIB routines, wcsini(), wcscopy(), wcsfree(), and wcsprt(). Refer to wcs.h for details. - The number of PVi_ma cards for which wcsini() allocates memory is now set by a global variable, NPVMAX (previously a C-preprocessor macro). This defaults to 64 but may be changed by a new function, wcsnpv(). The wcsprm struct contains a new member, npvmax, that records the value of this number at the time the struct was initialized. This is in addition to npv which records the actual number of cards that were encountered. Similarly, NPSMAX (default 8) is used for the number of PSi_ma cards, and it may be changed via wcsnps(). The axis number, i, in the pvcard struct used for storing PVi_ma cards may now be set to 0 to indicate the latitude axis. - calloc() is now used in place of malloc() in allocating memory for arrays, and inclusion of malloc.h has been replaced with stdlib.h for all platforms. wcsfree() checks that wcs.flag != -1 before testing wcs.m_flag when freeing memory allocated by wcsini() in case the struct is uninitialized. Similarly for linfree(). - In prj.h, renamed C-preprocessor macros INI, PRT, SET, X2S and S2X to PRJINI, PRJPRT, PRJSET, PRJX2S and PRJS2X to reduce the likelihood of namespace clashes. Similarly in spc.h. Also, in prj.c, changed the name of helper routine offset() to prjoff() to reduce the likelihood of global namespace conflicts. - In line with bonx2s() and bons2x(), bonset() now recognizes the equatorial case of Bonne's projection as Sanson-Flamsteed, mainly so that the auxiliary information in the prjprm struct more accurately reflects the truth. Modified tcel2 to exercise this by using an equatorial Bonne projection in place of the Hammer-Aitov. - zpns2x() used prj.w[0] for bounds checking, though this had not been set by zpnset() for polynomials of degree N < 3. Consequently, bounds checking for N < 3 was unreliable (reported by David Berry, STARLINK). - Changed some variable names in tscs2x(), cscx2s(), cscs2x(), qscx2s(), and qscs2x() to match Paper II, and likewise changed some inequality tests in qscs2x() without changing the results. - Minor tidying up of output formatting in prjprt(). - Added the alternate version code to FITS WCS keywords mentioned in comments, e.g. CTYPEi changed to CTYPEia. * Fortran wrappers - New wrappers defined in wcshdr_f.c: wcspih_() and wcsvfree_(), and also a new service function, wcsvcopy_(). New test programs, TPIH1 and TPIH2, being analogues of tpih1 and tpih2. Removed TWCSPRT. - In wcs_f.c, new wrappers wcsnpv_() and wcsnps_(); modified wcsput_() and wcsget_() to handle new members of the wcsprm struct. Also modified wcsput_() to null-fill all char[] members of the wcsprm struct, and likewise wcsget_() to blank-fill them. - Modified wcs.inc to support changes to the wcsprm struct. * PGSBOX - In PGSBOX, increased the dimension of the WORLD and XY vectors from 2 to 9 to accomodate higher-dimensional coordinate representations of up to 9 elements. Similarly for pgwcsl(). The assumption (presently) is that the first two world, and pixel, coordinate elements are the relevant ones; the others are all set to zero when pgwcsl() initializes and otherwise ignored. Assigned some variables in DATA to stop compiler messages about uninitialized variables. - Generalized the Makefile, bringing it into line with the WCSLIB Makefile, and adding separate targets for compiling and running the test programs. The default target now simply compiles pgsbox.c and cpgsbox.c. A separate target compiles pgwcsl.c and inserts it into ../C/libwcs.a. WCSLIB version 3.4 (2004/02/11) ------------------------------- * C library - In aitx2s(), apply the boundary condition 0.5 <= Z^2 <= 1 given after Eq. (109) in WCS Paper II to detect outlying pixels. - Fixed several special-case bugs in celset(): 1) For theta_0 = 90, in substituting the default value for phi_p (LONPOLE), a) for the special case when delta_0 = 90, celset() provided the wrong value (180 instead of 0), b) celset() neglected to add phi_0 (normally 0). 2) For theta_0 != 90, a) for the special case when delta_0 = -90, celset() incorrectly computed delta_p (as theta_0 instead of -theta_0), b) for the special case when delta_p = +90 (or -90), celset() neglected to subtract (or add) phi_0 (normally 0). 3) For |delta_0| = 90, celset() incorrectly allowed the particular, invalid, value of phi_p (LONPOLE) that put the other pole at the fiducial point. 4) For theta_0 = 0, delta_0 = 0 LATPOLE determines delta_p completely. For LATPOLE > 90 celset() now sets delta_p to 90, and for LATPOLE < -90 it sets it to -90. - Additional refinements in celset(): 1) cel->ref[2] is normalized in the range [-180,180]. 2) Account for rounding error in the computation of delta_p. - sphx2s() and sphs2x() incorrectly handled the "change in the origin of longitude" special case that arises when delta_p = -90, in the even more restrictive case where |theta| = 90 also; it applied Eq. (3) instead of Eq. (4) of Paper II. - Added a new test program, tcel2.c, to exercise celset() more thoroughly. Renamed the original tcel.c to tcel1.c and modified the Makefile to suit. * Fortran wrappers - (No changes.) * PGSBOX - (No substantive changes.) WCSLIB version 3.3 (2003/10/21) ------------------------------- * C library - In celset(), the default value for phi_p (LONPOLE) is phi_p = phi_0 + ((delta_0 < theta_0) ? 180.0 : 0.0) Previously phi_0 (which is normally zero) was not added (reported by David Berry, STARLINK). - wcsprt() and linprt() now check that the structs have been initialized. - In wcsini(), when the wcsprm flag is -1 also set the linprm flag to -1 to force initialization of the memory managed by linset(). - wcsset() now explicitly initializes the celprm and spcprm structs via celini() and spcini(). - Fixed syntax errors in the macro definitions of linrev_errmsg and linfwd_errmsg. - In Makefile, added the -ansi option to gcc to force it to behave like a strict ANSI C compiler, specifically in setting the __STDC__ preprocessor macro. * Fortran wrappers - (No changes.) * PGSBOX - PGSBOX now recognizes status returns -1, -2, and -3 from NLFUNC for opcodes +2 and +1 which cause it to accept the returned (x,y) coordinates but not consider them as one end of a crossing segment for labelling world coordinate 1, 2, or both. - PGSBOX now takes care not to lose vertical tick marks (and hence labels) at the left or right edge of the frame. Likewise for horizontal tick marks at the top or bottom edge of the frame. - Tightened up the test in PGSBOX for cycles in angle to catch the case where the coordinate value spans a full 360 degrees. - PGSBOX will no longer accept frame crossings that are too oblique; floating point rounding errors may cause grid lines that should otherwise track along the frame to weave down it from side-to-side resulting in spurious crossing points. - Fixed a bug in pgwcsl_() for processing simple linear coordinates. - pgwcsl_() now returns error -2 if the latitude is outside -90 to +90 for opcodes +2 and +1. - Amended the translation of status return codes from WCSLIB in pgwcsl_(). - Provided a header file for pgwcsl_() (mainly for C++ usage). - Added extra test plots to PGTEST and cpgtest. - Added extra functionality to the Makefile. WCSLIB version 3.2 (2003/09/09) ------------------------------- * C library - Added the facility of setting the flag member of a wcsprm struct to -1 before calling wcsini() for the first time in order to initialize memory management. Likewise for linprm and linini(). - Renamed wcscpy() to wcscopy() to avoid a conflict with the Posix "wide character string" function of the same name (wchar.h). In particular, this is used by the GNU C++ string class. - The higher level functions (wcs, cel, spc) no longer return prematurely if some of the input coordinate values are invalid. - All functions now test whether a null pointer for the particular struct (wcsprm, celprm, etc.) has been passed to them. - Function return codes have been rationalized into a consistent set within each of the wcs, cel, lin, prj, spc, and spx suites of functions. Error messages to match these error codes are now encoded in a single character array, e.g. wcs_errmsg and prj_errmsg, instead of a separate array for each function. Macro definitions for the older character arrays (e.g. wcsini_errmsg) have been provided for backward compatibility. - Declared prj_stat as extern in prj.h. * Fortran wrappers - (No changes.) * PGSBOX - Added an ENTRY point, PGLBOX, that provides a simplified interface to PGSBOX for linear axes without having to specify an NLFUNC or the associated parameters. WCSLIB version 3.1 (2003/04/29) ------------------------------- * C library - Added "global" and "divergent" prjprm struct informational members to record whether the projection is capable of mapping the whole sphere, and whether it is divergent in latitude. - Function cylfix() provided to fix WCS FITS header cards for malformed cylindrical projections (c.f. Paper II, Sect. 7.3.4). - Added support for CUNITi cards to wcsprm (but not currently implemented). - Added macro implementations of the trigd functions to wcstrig.h, enabled if WCSTRIG_MACRO is defined. - Improved printing of the WCSLIB structs. - Added macro definitions for the lengths of the WCSLIB structs measured in sizeof(int) units (mainly for the FORTRAN wrappers). * Fortran wrappers - FORTRAN is now supported via a set of wrappers on the C library. Refer to the README file. * PGSBOX WCSLIB version 3.0 beta release (2003/04/01) -------------------------------------------- * C library - Fully vectorized function interfaces (C preprocessor macros are available to implement the scalar interfaces of the proj.c, sph.c, and lin.c routines from WCSLIB 2.x). - Implementation of Paper II, Sect. 2.5: User-specified (phi0, theta0). - Implementation of Paper III (excluding "-TAB"). - Memory management is now implemented in the upper-level (wcs.c) routines. - New extensible design should accomodate Paper IV (and any other) without further change to the function interfaces. * PGSBOX - Added a C wrapper function, cpgsbox(), and C test/demo program, cpgtest, that duplicates PGTEST and serves as a C coding template. - Added calendar date axes. - Sped up the max/min search - if only tickmarks are required there is no need to search the interior of the image. - Return margin widths in CACHE(,NC). - Fixed a buglet that caused ticks at the frame edges to be skipped. - Return error 3 if CACHE overflows. - Adapted PGWCSL for WCSLIB 3.x - it is now a C function (for interfacing to WCSLIB) with a FORTRAN-like interface (for PGSBOX). WCSLIB version 2.9 (2002/04/03) ------------------------------- * C library - Fixed a bug with alias translation in wcsset(). - Added a conditional compilation directive to lin.c for Apple's MacOSX. * Fortran library - Fixed CUBEFACE handling in WCSSET. WCSLIB version 2.8 (2001/11/16) ------------------------------- * C library - Added support for the SZP projection with szpset(), szpfwd() and szprev(), and generalized AZP with support for the tilt parameter, gamma. - Added phi0 to the prjprm struct, this is set by the projection initialization routines along with theta0. - Fixed a problem in wcsmix() caused by numerical imprecision that could cause it not to recognize when convergence was reached; break out of the loop early if a discontinuity is detected. - Clarified the usage of vspan in the prologue to wcsmix(). - Fixed comments relating to LATPOLE in the prologue to cel.c and tcel.c, and replaced references to LONGPOLE with LONPOLE. - Augmented the error reports in twcs2. - Modified projex() in tproj1 and prjplt() in tproj2 to make use of the information stored in the prjprm struct. * Fortran library - Added support for the SZP projection with SZPSET, SZPFWD and SZPREV, and generalized AZP with support for the tilt parameter, gamma. - Changed the call sequence to PRJSET to return PHI0 along with THETA0. - Fixed a problem in WCSMIX caused by numerical imprecision that could cause it not to recognize when convergence was reached; break out of the loop early if a discontinuity is detected. - Clarified the usage of VSPAN in the prologue to WCSMIX. - Fixed comments relating to LATPOLE in the prologue to CEL and TCEL, and replaced references to LONGPOLE with LONPOLE. - Augmented the error reports in TWCS2. - Modified PROJEX in TPROJ1 and PRJPLT in TPROJ2 to use the generic driver routines PRJSET, PRJFWD and PRJREV. PRJPLT also now uses the projection type encoded in PRJ(11). WCSLIB version 2.7 (2001/02/19) ------------------------------- * C library - Added generic driver routines prjset(), prjfwd() and prjrev(). These invoke specific projection routines via the pointer-to- function elements, prjfwd and prjrev, transferred to the prjprm struct from celprm. - Added code (3-letter projection code) and theta0 (reference latitude) elements to prjprm. - The projection code for the Sanson-Flamsteed projection is now SFL. The upper-level routines, wcsset(), wcsfwd(), and wcsrev(), recognize GLS as an alias for this. - wcsset() now recognizes 'xyLN/xyLT' axis pairs. - Two bugs in the translation from NCP to SIN in wcsfwd() and wcsrev() were fixed: (1) the projection parameter was computed incorrectly and (2) they did not honour prj->flag set to -1 to disable strict bounds checking. - A bug in wcsmix() was fixed - it was relying on the wcsprm struct to have been initialized beforehand. - The test programs now use the cpgplot interface to PGPLOT, the old tpgc.c and tpgf.f wrappers have been removed. * Fortran library - Added generic driver routines PRJSET, PRJFWD and PRJREV. These are keyed to specific projection routines via the value of PRJ(11) which now differs for each projection. - The projection code for the Sanson-Flamsteed projection is now SFL. The upper-level routines, WCSSET, WCSFWD, and WCSREV, recognize GLS as an alias for this. - WCSSET now recognizes 'xyLN/xyLT' axis pairs. - A bug in the translation from NCP to SIN in WCSFWD and WCSREV was fixed; they did not honour PRJ(11) set to -1 to disable strict bounds checking. - A bug in WCSMIX was fixed - it was relying on the WCS array to have been initialized beforehand. WCSLIB version 2.6 (2000/05/10) ------------------------------- * C library - Check for invalid (x,y) in zearev(). - In wcsmath.h, guard against prior definition of PI and other preprocessor variables. * Fortran library - Check for invalid (X,Y) in ZEAREV. - Declare COSD and SIND in WCSFWD and WCSREV, reported by Clive Page (cgp@star.le.ac.uk). WCSLIB version 2.5 (1999/12/14) ------------------------------- * C library - Added copyright notice to header files and prefixed include guard names with "WCSLIB_". - Fixed cube face handling in wcsfwd() and wcsrev() (reported by Doug Mink, CfA). Allow more general face layout in the inverse quadcube projections. - Fixed the problem in wcsmix() where it failed to find a valid solution when the solution point lay at a native pole of a projection in which the pole is represented as a finite interval. However, wcsmix() will only ever return one solution even when two or more valid solutions may exist. - wcsmix() now accepts viter in the range 5 - 10, the specified value will be pushed up or down into this range if necessary. - The projection routines for AZP, TAN, SIN, ZPN, and COP now return error 2 if (phi,theta) correspond to the overlapped (far) side of the projection. This strict bounds checking can be switched off by setting prj->flag to -1 (rather than 0) when the projections are initialized. - The upper level routines, wcsset(), wcsfwd(), wcsrev(), and wcsmix(), now recognize the NCP projection and convert it to the equivalent SIN projection. The lower level routines do not recognize NCP. - Extracted definitions of mathematical constants (PI etc.) from proj.h into wcsmath.h in order to avoid conflicts with their definition in math.h in some systems (such as Linux). - Describe the two alternate representations of the quadcube projections (i.e. faces laid out or stacked) in the prologue of wcs.c. * Fortran library - Fixed cube face handling in WCSFWD and WCSREV, reported by Doug Mink (dmink@cfa.harvard.edu). Allow more general face layout in the inverse quadcube projections. - Fixed the problem in WCSMIX where it failed to find a valid solution when the solution point lay at a native pole of a projection in which the pole is represented as a finite interval. However, WCSMIX will only ever return one solution even when two or more valid solutions may exist. - WCSMIX now accepts VITER in the range 5 - 10, the specified value will be pushed up or down into this range if necessary. - The projection routines for AZP, TAN, SIN, ZPN, and COP now return error 2 if (phi,theta) correspond to the overlapped (far) side of the projection. This strict bounds checking can be switched off by setting PRJ(11) to -1 (rather than 0) when the projections are initialized. - The upper level routines, WCSSET, WCSFWD, WCSREV, and WCSMIX, now recognize the NCP projection and convert it to the equivalent SIN projection. The lower level routines do not recognize NCP. - Describe the two alternate representations of the quadcube projections (i.e. faces laid out or stacked) in the prologue of wcs.f. WCSLIB version 2.4 (1996/09/23) ------------------------------- * C library - In sinrev(), cscrev(), qscrev(), and tscrev(), return error 2 if (x,y) do not lie within the perimeter of the projection. In sinrev(), stop the computation of phi for the "synthesis" projection being applied to the pure "orthographic" case (reported by David Berry, STARLINK). - (Internal change) Renamed variables l <-> m in the quadcube projections to accord with standard usage (and revised WCS draft paper). * Fortran library - In SINREV, CSCREV, QSCREV, and TSCREV, return error 2 if (X,Y) do not lie within the perimeter of the projection. In SINREV, stop the computation of PHI for the "synthesis" projection being applied to the pure "orthographic" case. Reported by David Berry (dsb@ast.man.ac.uk). - (Internal change) Renamed variables L <-> M in the quadcube projections to accord with standard usage (and revised WCS draft paper). - (Internal change) Stopped PRJ(11) doing double service in any projection. It is now set and tested for a specific magic value rather than simply being non-zero. WCSLIB version 2.3 (1996/06/24) ------------------------------- * C library - Fixed two bugs in zpnset(). The first led to an incorrect determination of the degree of the polynomial and would mainly have affected the efficiency of zpnrev(). The second affected the determination of the boundary of the projection but would only have been significant for projections with a point of inflection between 9 and 10 degrees of the pole. Reported by David Berry, STARLINK. - Replaced usage of alloca() in lin.c with malloc() and free() for portability as suggested by Klaus Banse, ESO (kbanse@eso.org). - Allow for C implementations that provide their own versions of cosd(), sind(), tand(), acosd(), asind(), atand(), and atan2d(). From Klaus Banse, ESO (kbanse@eso.org). - Implemented the CUBEFACE axis for quadcube projections. - Made all function prototypes const-correct. - Adapted the header files to C++ usage. - Added a new test program, twcs1, to verify closure of wcsfwd() and wcsrev(). The old twcs test program is now called twcs2. - Added external arrays of error messages indexed by function return value. For example, extern const char *wcsmix_errmsg[] for wcsmix(). Messages for the many proj.c functions are in prjfwd_errmsg[], etc. * Fortran library - Implemented the CUBEFACE axis for quadcube projections. - Added a new test program, TWCS1, to verify closure of WCSFWD and WCSREV. The old TWCS test program is now called TWCS2. WCSLIB version 2.2 (1996/01/18) ------------------------------- * C library - Amended the projection equations for the conics (COP, COD, COE, COO) and Bonne's projection (BON) to correctly handle southern hemisphere projections with PROJP1 < 0 (reported by Lindsay Davis, NOAO). Revised tproj1 and tproj2 to test such cases. * Fortran library - Amended the projection equations for the conics (COP, COD, COE, COO) and Bonne's projection (BON) to correctly handle southern hemisphere projections with PROJP1 < 0 (reported by Lindsay Davis, NOAO). Revised TPROJ1 and TPROJ2 to test such cases. - Increased the dimension of the WCS array from WCS(0:2) to WCS(0:3) to allow for future handling of the CUBEFACE keyword - WCS(3) will store an index to the CUBEFACE axis. This affects the call sequences of WCSSET, WCSFWD, WCSREV, and WCSMIX. WCSLIB version 2.1 (1995/11/17) ------------------------------- * C library The main change of interest to programmers is that of changed argument lists for wcsfwd() and wcsrev() as described below. - The WCS linear transformations are now implemented in WCSLIB, complete with matrix inverter. The new files are lin.c, lin.h, and test program tlin.c. - Given either the celestial longitude or latitude plus an element of the pixel coordinate a new routine, wcsmix(), solves for the remaining elements by iterating on the unknown celestial coordinate element using wcsfwd(). - The high level driver routines wcsfwd(), wcsrev(), and wcsmix() now apply the full WCS algorithm chain (except for pixel regularization table), including parsing the CTYPEn header cards and computing non- celestial elements of the world coordinate. This required a change to their argument lists which now more closely reflect the sequence of algorithms applied. A new routine, wcsset(), parses the CTYPEn. - The high level driver routines of WCSLIB 1.0 are available as intermediate level drivers celset(), celfwd(), and celrev(), but note that their argument lists have been extended to return native coordinates. The related struct is now called celprm instead of wcsprm. - The reference point for conic projections is now at the midpoint of the standard parallels. The FITS header cards PROJP1 and PROJP2 now give the half-sum (midpoint) and half-difference of the latitudes of the standard parallels; previously they gave the latitudes of the standard parallels themselves. The change is reflected in this release of WCSLIB. - A bug in celset() (formerly wcsset()) that misapplied WCS draft equations 7 has been fixed (thanks to Rick Ebert IPAC/JPL and Lindsey Davis, NOAO for reporting this). This affected the computation of Euler angles for the celestial coordinate transformation for those projections that have their reference point away from the native pole. In investigating this a deficiency with the formalism was discovered that led to the introduction of a LATPOLE FITS header card which may be used to disambiguate where CRVAL1, CRVAL2, and LONGPOLE do not uniquely determine the latitude of the native pole. The celprm struct (formerly wcsprm) has been extended to accomodate LATPOLE. - Default values of LONGPOLE and LATPOLE are now supported and their use is recommended where appropriate. - Numerical precision was being lost near the native poles in the SIN, AIR, and QSC projections and this has been recovered (reported by Lindsey Davis, NOAO). Floating underflows in CSC are now avoided. - Numerical precision was also lost in certain circumstances in the spherical coordinate transformation routines and this has been fixed. - The test programs have been enhanced in various ways and the library has been validated on an SGI machine using both 32-bit and 64-bit compilers. * Fortran library The main change of interest to programmers is that of changed call sequences for WCSFWD and WCSREV as described below. - The WCS linear transformations are now implemented in WCSLIB, complete with matrix inverter. The new files are lin.f and test program tlin.f. - Given either the celestial longitude or latitude plus an element of the pixel coordinate a new routine, WCSMIX, solves for the remaining elements by iterating on the unknown celestial coordinate element using WCSFWD. - The high level driver routines WCSFWD, WCSREV, and WCSMIX now apply the full WCS algorithm chain (except for pixel regularization table), including parsing the CTYPEn header cards and computing non- celestial elements of the world coordinate. This required a change to their call sequences which now more closely reflect the sequence of algorithms applied. A new routine, WCSSET, parses the CTYPEn. - The high level driver routines of WCSLIB 1.0 are available as intermediate level drivers CELSET, CELFWD, and CELREV, but note that their call sequences have been extended to return native coordinates. The related parameter array is now called CEL instead of WCS. - The reference point for conic projections is now at the midpoint of the standard parallels. The FITS header cards PROJP1 and PROJP2 now give the half-sum (midpoint) and half-difference of the latitudes of the standard parallels; previously they gave the latitudes of the standard parallels themselves. The change is reflected in this release of WCSLIB. - A bug in CELSET (formerly WCSSET) that misapplied WCS draft equations 7 has been fixed (thanks to Rick Ebert IPAC/JPL and Lindsey Davis, NOAO for reporting this). This affected the computation of Euler angles for the celestial coordinate transformation for those projections that have their reference point away from the native pole. In investigating this a deficiency with the formalism was discovered that led to the introduction of a LATPOLE FITS header card which may be used to disambiguate where CRVAL1, CRVAL2, and LONGPOLE do not uniquely determine the latitude of the native pole. The CEL parameter array (formerly WCS) has been extended to accomodate LATPOLE as CEL(4), and the flag variable is now CEL(5) (formerly WCS(4)). - Default values of LONGPOLE and LATPOLE are now supported and their use is recommended where appropriate. - Numerical precision was being lost near the native poles in the SIN, AIR, and QSC projections and this has been recovered (reported by Lindsey Davis, NOAO). Floating underflows in CSC are now avoided. - Numerical precision was also lost in certain circumstances in the spherical coordinate transformation routines and this has been fixed. - The test programs have been enhanced in various ways and the library has been validated on an SGI machine using both 32-bit and 64-bit compilers. WCSLIB version 1.0 (1995/01/31) ------------------------------- * C library Initial release. * Fortran library Initial release. ------------------------------------------------------------------------ $Id: CHANGES,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/COPYING0000644000175100001710000010451300000000000016237 0ustar00vstsdocker GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/COPYING.LESSER0000644000175100001710000001672500000000000017242 0ustar00vstsdocker GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/GNUmakefile0000644000175100001710000001602600000000000017257 0ustar00vstsdocker#----------------------------------------------------------------------------- # GNU makefile for building WCSLIB 7.7 # # Summary of the main targets # --------------------------- # all: Do 'make all' in each subdirectory (excluding ./doxygen). # check: Do 'make check' in each subdirectory (compile and run tests). # tests: Do 'make tests' in each subdirectory (compile test programs but # don't run them). # install: Do 'make install' in each subdirectory. # uninstall: Deletes installed files (this release only), including the # sharable library. # clean: Recursively delete intermediate files produced as part of the # build, e.g. object modules, core dumps, etc. # cleaner: Recursively clean, and also delete test executables, test # input and output, and intermediates produced in compiling the # programmers' manual. # distclean (or realclean): Recursively delete all platform-dependent files # generated during the build, preserving only the programmers' # manual and man pages (which are normally provided pre-built). # It is the one to use between builds for multiple platforms. # cleanest: Like distclean, but deletes everything that can be regenerated # from the source files, including the programmers' manual and # man pages, but excluding 'configure'. # show: Print the values of important variables used in this and the # other makefiles. # writable: Run chmod recursively to make all sources writable. # # Notes: # 1) If you need to make changes then preferably modify makedefs.in instead. # # 2) Refer also to the makefiles in subdirectories, particularly # C/GNUmakefile. # # Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. # http://www.atnf.csiro.au/people/Mark.Calabretta # $Id: GNUmakefile,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ #----------------------------------------------------------------------------- # Get configure settings. SUBDIR := . include makedefs ifeq "$(CHECK)" "nopgplot" TSTDIRS := $(filter-out pgsbox,$(TSTDIRS)) endif .PHONY : build check chmod clean cleaner cleanest distclean install \ realclean show tests uninstall writable build : -@ for DIR in $(SUBDIRS) ; do \ echo '' ; \ $(TIMER) ; \ $(MAKE) -k -C $$DIR build ; \ done check tests :: show -@ echo '' -@ $(TIMER) @ for DIR in $(SUBDIRS) ; do \ echo '' ; \ $(MAKE) -i -C $$DIR cleaner build ; \ done -@ echo '' @ for DIR in $(TSTDIRS) ; do \ echo '' ; \ $(TIMER) ; \ $(MAKE) -k -C $$DIR $@ ; \ done check :: -@ echo '' -@ echo 'Summary of results for non-graphical tests' -@ echo '------------------------------------------' -@ cat ./*/test_results @ if grep 'FAIL:' ./*/test_results > /dev/null ; then \ exit 1 ; \ else \ exit 0 ; \ fi install : @ for DIR in $(INSTDIR) ; do \ $(MAKE) -k -C $$DIR $@ ; \ done if [ ! -d "$(LIBDIR)/pkgconfig" ] ; then \ $(INSTALL) -d -m 775 $(LIBDIR)/pkgconfig ; \ fi $(INSTALL) -m 444 wcslib.pc $(LIBDIR)/pkgconfig/wcslib.pc $(INSTALL) -m 444 wcsconfig.h wcsconfig_f77.h $(INCDIR) - if [ ! -d "$(DOCDIR)" ] ; then \ $(INSTALL) -d -m 775 $(DOCDIR) ; \ fi $(INSTALL) -m 444 CHANGES COPYING* README $(DOCDIR) - if [ -h $(DOCLINK) ] ; then \ $(RM) $(DOCLINK) ; \ $(LN_S) $(notdir $(DOCDIR)) $(DOCLINK) ; \ fi - if [ ! -d "$(PDFDIR)" ] ; then \ $(INSTALL) -d -m 775 $(PDFDIR) ; \ fi $(INSTALL) -m 444 wcslib.pdf $(PDFDIR) - if [ ! -d "$(HTMLDIR)/html" ] ; then \ $(INSTALL) -d -m 775 $(HTMLDIR)/html ; \ fi $(INSTALL) -m 444 html/* $(HTMLDIR)/html uninstall : @ for DIR in $(INSTDIR) ; do \ $(MAKE) -k -C $$DIR $@ ; \ done - cd $(LIBDIR) && $(RM) pkgconfig/wcslib.pc - cd $(INCDIR) && $(RM) wcsconfig*.h - $(RM) $(DOCLINK) - $(RM) $(DOCDIR) - $(RM) $(PDFDIR) - $(RM) $(HTMLDIR) clean cleaner : for DIR in $(SUBDIRS) doxygen ; do \ $(MAKE) -C $$DIR $@ ; \ done cleanest distclean realclean : for DIR in $(SUBDIRS) doxygen ; do \ $(MAKE) -C $$DIR $@ ; \ done - $(RM) *.log - $(RM) -r autom4te.cache autoscan.log - $(RM) -r api-sanity-check - $(RM) confdefs.h conftest.* - $(RM) config.log config.status configure.lineno - $(RM) makedefs wcslib.pc - $(RM) wcsconfig.h wcsconfig_*.h - $(RM) wcslib-*.tar.gz show :: -@ echo 'Subdirectories to be built...' -@ echo ' SUBDIRS := $(SUBDIRS)' -@ echo ' TSTDIRS := $(TSTDIRS)' -@ echo '' writable : chmod -R u+w . GNUmakefile : makedefs ; makedefs : makedefs.in config.status -@ echo '' -@ $(TIMER) ./config.status config.status : configure -@ echo '' -@ $(TIMER) -@ echo '' -@ echo "Environment variables that affect 'configure':" -@ echo " FLEX = $${FLEX-(undefined)}" -@ echo " FLFLAGS = $${FLFLAGS-(undefined)}" -@ echo " CPP = $${CPP-(undefined)}" -@ echo " CPPFLAGS = $${CPPFLAGS-(undefined)}" -@ echo " CC = $${CC-(undefined)}" -@ echo " CFLAGS = $${CFLAGS-(undefined)}" -@ echo " F77 = $${F77-(undefined)}" -@ echo " FFLAGS = $${FFLAGS-(undefined)}" -@ echo " ARFLAGS = $${ARFLAGS-(undefined)}" -@ echo " LDFLAGS = $${LDFLAGS-(undefined)}" -@ echo '' ./configure --no-create #----------------------------------------------------------------------------- # These are for code management. .PHONY : dist dist : $(MAKE) -C doxygen cleanest build $(MAKE) -C utils man $(MAKE) distclean -@ echo $(WCSLIBPKG)/C/RCS > wcslib.X -@ echo $(WCSLIBPKG)/C/flexed/RCS >> wcslib.X -@ echo $(WCSLIBPKG)/C/test/RCS >> wcslib.X -@ echo $(WCSLIBPKG)/doxygen/RCS >> wcslib.X -@ echo $(WCSLIBPKG)/Fortran/RCS >> wcslib.X -@ echo $(WCSLIBPKG)/Fortran/test/RCS >> wcslib.X -@ echo $(WCSLIBPKG)/makedefs >> wcslib.X -@ echo $(WCSLIBPKG)/other >> wcslib.X -@ echo $(WCSLIBPKG)/pgsbox/RCS >> wcslib.X -@ echo $(WCSLIBPKG)/RCS >> wcslib.X -@ echo $(WCSLIBPKG)/TODO >> wcslib.X -@ echo $(WCSLIBPKG)/utils/RCS >> wcslib.X -@ echo $(WCSLIBPKG)/wcslib.T >> wcslib.X -@ echo $(WCSLIBPKG)/wcslib.X >> wcslib.X rm -f $(WCSLIBPKG).tar.bz2 tar cf - -C .. -X wcslib.X $(WCSLIBPKG) | \ tar t | \ grep -v '/$$' | \ sort > wcslib.T rm -f wcslib.X tar cvf $(WCSLIBPKG).tar -C .. -T wcslib.T rm -f wcslib.T bzip2 $(WCSLIBPKG).tar chmod 444 $(WCSLIBPKG).tar.bz2 install_dist : scp -p $(WCSLIBPKG).tar.bz2 cal103@venice:/nfs/ftp/software/wcslib/ mv -f $(WCSLIBPKG).tar.bz2 ../wcslib-releases/ ssh cal103@venice "cd /nfs/ftp/software/wcslib/ && \ rm -f wcslib.tar.bz2 && \ ln -s $(WCSLIBPKG).tar.bz2 wcslib.tar.bz2" cp -fp CHANGES wcslib.pdf ~/public_html/WCS/ rsync --archive --delete html/ ~/public_html/WCS/wcslib/ configure : configure.ac -@ echo '' -@ $(TIMER) autoconf # Code development overrides must be included specifically before 'configure' # generates makedefs. -include flavours ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/INSTALL0000644000175100001710000003143400000000000016236 0ustar00vstsdocker------------------------------------------------------------------------------ WCSLIB 7.7 and PGSBOX 7.7 INSTALLATION -------------------------------------- WCSLIB requires an ANSI C compiler with standard ANSI C environment, that is, a standard C library and header files as defined in Appendix B of Kernigan & Ritchie, 2nd ed. If you are running a typical Linux distro and have installed WCSLIB before, then all you should need to do is tar pxvf wcslib-7.7.tar.bz2 cd wcslib-7.7 make install Otherwise, read on. Installation of WCSLIB is handled by GNU autoconf; GNU make (referred to here as 'gmake') must be used. The WCSLIB distribution also includes PGSBOX (refer to the README file). To unpack the tar file, type bzcat wcslib-7.7.tar.bz2 | tar pvxf - cd wcslib-7.7 then if you do not need to specify any configuration options, simply run gmake This will run 'configure' to generate "makedefs" which is included by the top- level GNUmakefile and those in each subdirectory, and then build 'libwcs.a', which includes both the C library and Fortran wrappers, and also libpgsbox.a. (WARNING: The build may fail with gmake 3.79, upgrade to 3.79.1 or later.) configure tries to determine the location of the PGPLOT and CFITSIO libraries required by some utilities (wcsware, wcsgrid) and programs in the test suite. If it fails to find them you can, if you wish, tailor the few variables found at the start of "makedefs". Of course you do not need to exercise the test suite in order to build and install the library - if configure fails to find anything required for that it will issue an explicit error message. To build and exercise the test suite use gmake check To install the object libraries and header files, do gmake install TWEAKING THE INSTALLATION DEFAULTS ---------------------------------- By default the library and header files are installed in the lib and include subdirectories of /usr/local/. To change this, or any other options, run configure separately before gmake: ./configure --prefix=/some/other/dir gmake Use ./configure --help to list configure's options. Useful options are --with-pgplotinc --with-pgplotlib --with-cfitsioinc --with-cfitsiolib Which allow additional directories to be added to the library and include file search path. Installation of WCSLIB differs a little from most packages in that all configurable makefile variables are defined in a single file, "makedefs", which configure generates from "makedefs.in". If you need to redefine any of the makefile variables you can modify makedefs, or preferably makedefs.in. The makefile will automatically detect this and re-run config.status to re-generate a new makedefs. configure also creates four header files: wcsconfig.h: Contains general purpose preprocessor definitions. It is included by the other wcsconfig header files. wcsconfig_f77.h: By common convention the WCSLIB Fortran wrappers have been written (in C) using function names in lower case with an underscore ("_") suffix. wcsconfig_f77.h defines a preprocessor macro, F77_FUNC(name,NAME), that may redefine these to suit different name mangling schemes used by some Fortran compilers. wcsconfig_tests.h: Contains C preprocessor definitions for compiling the test/demo programs. wcsconfig_utils.h: Contains C preprocessor macro definitions for compiling the utility programs provided with WCSLIB. If you do have trouble building the library please send me config.log. The INSTALL file provided with GNU autoconf 2.53 is appended without change. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: INSTALL,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ ============================================================================== Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is free documentation; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. Basic Installation ================== These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. (Caching is disabled by default to prevent problems with accidental use of stale cache files.) If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You only need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for variables by setting them in the environment. You can do that on the command line like this: ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not support the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH', the package will use PATH as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=PATH' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the `--target=TYPE' option to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc will cause the specified gcc to be used as the C compiler (unless it is overridden in the site shell script). `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of the options to `configure', and exit. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/README0000644000175100001710000000335700000000000016070 0ustar00vstsdocker------------------------------------------------------------------------------ WCSLIB 7.7 and PGSBOX 7.7 ------------------------------------------------------------------------------ WCSLIB 7.7 - an implementation of the FITS WCS standard. Copyright (C) 1995-2021, Mark Calabretta This file is part of WCSLIB. WCSLIB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WCSLIB. If not, see http://www.gnu.org/licenses. Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. http://www.atnf.csiro.au/people/Mark.Calabretta $Id: README,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ ------------------------------------------------------------------------------ Please refer to ./INSTALL ...Installation instructions. ./html/index.html ...The WCSLIB programmer's manual in HTML format. ./wcslib.pdf ...The WCSLIB programmer's manual in PDF format. ./CHANGES ...Log of changes made to WCSLIB. ./THANKS ...List of contributors to WCSLIB. ./VALIDATION ...List of platforms on which the installation procedures and test suite were exercised. ./COPYING ...A copy of the GNU General Public License, v3.0. ./COPYING.LESSER ...A copy of the Lesser GNU General Public License. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/THANKS0000644000175100001710000000605100000000000016115 0ustar00vstsdockerI would like to acknowledge the following people who have contributed to WCSLIB and/or PGSBOX in some way since 1995 - via bug reports, patches, suggestions for improvements, positive feedback, etc. Mohammad Akhlaghi (IAC & GNUastro) James Allen (U. Sydney) James M. Anderson (MPIfR) Robbie Auld (Cardiff U.) Klaus Banse (ESO) David Barnes (ATNF/CSIRO) Zaak Beekman (Homebrew maintainer for MacOSX) David Berry (STARLINK & JAC) Emmanuel Bertin (IAP) David Binderman Erik M. Bray (STScI) Jeremy Brewer (U. Pittsburgh) Wim Brouw (ATNF/CSIRO) Peter Bunclark (IoA, U. Cambridge) Mihai Cara (STScI/Astropy) Rodrigo Tobar Carrizo (ICRAR/UWA) Pan Chai (GSFC/NASA) Charles Copley Simon Conseil (CRAL) Neil Crighton Cesar Enrique Garcia Dabo (ESO) Lindsey Davis (NOAO) Nadezhda (Nadia) Dencheva (STScI/Astropy) Ger van Diepen (ASTRON) Patrick Dowler (CADC/NRC) Michael Droettboom (STScI) Rick Ebert (IPAC/NASA) Ken Ebisawa (GSFC/NASA) Sébastien Fabbro (Gentoo linux maintainer) Octavi Fors (U. North Carolina) Bob Garwood (NRAO) Mosč Giordano (Julia wrappers) Brian Glendenning (NRAO) Eric Greisen (NRAO) Michael Halle (AM/Harvard) Booth Hartley (IPAC/NASA) Phil Hodge (STScI) Derek Homeier (Astropy) Bryan Irby (GSFC/NASA) Justin Jonas (Rhodes U.) Yves Jung (ESO) David Kaplan (KITP/UCSB) Vishal Kasliwal (U. Pennsylvania, LSST) Daniel S. Katz (JPL/NASA) Neil Killeen (ATNF/CSIRO) David King (NRAO) Martin Kuemmel (U.-Sternwarte Muenchen) Paul F. Kunz (SLAC/Stanford U.) Jonas Møller Larsen (ESO) Dustin Lang (Perimeter Inst.) Paddy Leahy (U. Manchester) Jim Lewis (IoA, U. Cambridge) Pey-Lian Lim (STScI) Marco Lombardi (ESO) Lars Kristian Lundin (ESO) Robert Lupton (Princeton U.) Craig Markwardt (GSFC/NASA) Chiara Marmo (U. Paris-Sud) Malte Marquarding (ATNF/CSIRO) Jean-Baptiste Marquette (IAP) Tom Marsh (U. Warwick) Sean Mattingly (IPAC/NASA) Dave McConnell (ATNF/CSIRO) Thomas A. McGlynn (GSFC/NASA) Bruce Merry (SARAO) Michelle Miller (NOAO) Jessica Mink (CfA) David Motl (var.astro.cz) August Muench (CfA) Fergal Mullally (Princeton U.) Stuart Mumford (SunPy) Clive Page (U. Leicester) Ralf Palsa (ESO) Sergio Pascual (U. Complutense de Madrid, Fedora maintainer) Bill Pence (GSFC/NASA) Olivier Perdereau (LAL/IN2P3) Dirk Petry (ESO) Ray Plante (NCSA/UIUC) Paul Price (Princeton U.) Niruj Mohan Ramanujam (Leiden Obs) Harold Ravlin (U. Illinois) Cyril Richard (CNRS) Thomas Robitaille (MPIA, STScI) Boud Roukema (TCfA) Keith A. Scollick (GSFC/NASA) Arno Schoenmakers (ASTRON) Pim Schellart (Princeton U.) Corentin Schreiber (Oxford U.) Michael Seifert (Astropy) Colin Slater (LSST) Hanno Spreeuw (ASTRON) Ole Streicher (Debian maintainer) Julian Taylor (ESO) Hans Terlouw (Kapteyn, Groningen) Peter Teuben (U. Maryland) Bill Thompson (GSFC/NASA) Harro Verkouter (JIVE) John C. Vernaleo (GSFC/NASA) Martin Vogelaar (Kapteyn, Groningen) Stephen Walton (CSUN) Boyd Waters (NRAO) Randall Wayth (Curtin U.) Benjamin Alan Weaver (LBL) Peter Weilbacher (AIP) Matthew Whiting (ATNF/CSIRO) Peter Williams (UCB, CfA) Daren Scot Wilson (NRAO) Tony Wong (ATNF/CSIRO) $Id: THANKS,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/VALIDATION0000644000175100001710000005560300000000000016566 0ustar00vstsdockerPlatforms on which the installation procedures and test suite were exercised. WCSLIB version 7.7 (2021/07/12) ------------------------------- * Dell Latitude E6530 (Intel Core i7-3740QM, 4 cores, 8 processors, x86_64) KDE Neon User Edition 5.22 (over Kubuntu 20.04, (focal)) uname -r (kernel version): 5.4.0-77-generic gcc --version: gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0 gfortran --version: GNU Fortran (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0 and gcc --version: gcc (GCC) 11.1.0 (local build) gfortran --version: GNU Fortran (GCC) 11.1.0 (local build) WCSLIB version 7.6 (2021/04/13) ------------------------------- * Dell Latitude E6530 (Intel Core i7-3740QM, 4 cores, 8 processors, x86_64) KDE Neon User Edition 5.21 (over Kubuntu 20.04, (focal)) uname -r (kernel version): 5.4.0-67-generic gcc --version: gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0 gfortran --version: GNU Fortran (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0 WCSLIB version 7.5 (2021/03/20) ------------------------------- * Dell Latitude XPS 15 9560 (Intel Core i7-7700HQ, 4 cores, 8 CPUs, x86_64) KDE Neon User Edition 5.20 (over Kubuntu 20.04, (focal)) uname -r (kernel version): 5.4.0-62-generic gcc --version: gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0 gfortran --version: GNU Fortran (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0 WCSLIB version 7.4 (2021/01/31) ------------------------------- * Dell Latitude XPS 15 9560 (Intel Core i7-7700HQ, 4 cores, 8 CPUs, x86_64) KDE Neon User Edition 5.20 (over Kubuntu 20.04, (focal)) uname -r (kernel version): 5.4.0-62-generic gcc --version: gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0 gfortran --version: GNU Fortran (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0 WCSLIB version 7.3.1 (2020/08/17) --------------------------------- * Dell Latitude XPS 15 9560 (Intel Core i7-7700HQ, 4 cores, 8 CPUs, x86_64) KDE Neon User Edition 5.19 (over Kubuntu 18.04, (bionic)) uname -r (kernel version): 4.15.0-112-generic gcc --version: gcc (GCC) 9.2.0 (local build) gfortran --version: GNU Fortran (GCC) 9.2.0 (local build) WCSLIB version 7.3 (2020/06/03) ------------------------------- * Dell Latitude XPS 15 9560 (Intel Core i7-7700HQ, 4 cores, 8 CPUs, x86_64) KDE Neon User Edition 5.18 (over Kubuntu 18.04, (bionic)) uname -r (kernel version): 4.15.0-88-generic gcc --version: gcc (GCC) 9.2.0 (local build) gfortran --version: GNU Fortran (GCC) 9.2.0 (local build) WCSLIB version 7.2 (2020/03/09) ------------------------------- * Dell Latitude XPS 15 9560 (Intel Core i7-7700HQ, 4 cores, 8 CPUs, x86_64) KDE Neon User Edition 5.18 (over Kubuntu 18.04, (bionic)) uname -r (kernel version): 4.15.0-88-generic gcc --version: gcc (GCC) 9.2.0 (local build) gfortran --version: GNU Fortran (GCC) 9.2.0 (local build) WCSLIB version 7.1 (2020/01/01) ------------------------------- * Dell Latitude XPS 15 9560 (Intel Core i7-7700HQ, 4 cores, 8 CPUs, x86_64) KDE Neon User Edition 5.17 (over Kubuntu 18.04, (bionic)) uname -r (kernel version): 4.15.0-70-generic gcc --version: gcc (GCC) 9.2.0 (local build) gfortran --version: GNU Fortran (GCC) 9.2.0 (local build) * Dell Latitude D610 (Intel Pentium M, 1 processor, i686) Debian linux 4.0 (etch) uname -r (kernel version): 2.6.18-6-686 gcc --version: gcc (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) gfortran --version: GNU Fortran 95 (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) WCSLIB version 6.3 (2019/07/12) ------------------------------- * Dell Latitude XPS 15 9560 (Intel Core i7-7700HQ, 4 cores, 8 CPUs, x86_64) KDE Neon User Edition 5.15 (over Kubuntu 18.04, (bionic)) uname -r (kernel version): 4.15.0-50-generic gcc-8 --version: gcc-8 (Ubuntu 8.3.0-6ubuntu1~18.04.1) 8.3.0 gfortran-8 --version: GNU Fortran (Ubuntu 8.3.0-6ubuntu1~18.04.1) 8.3.0 WCSLIB version 6.1 (2018/10/19) ------------------------------- * Dell Latitude XPS 15 9560 (Intel Core i7-7700HQ, 4 cores, 8 CPUs, x86_64) KDE Neon User Edition 5.13 (over Kubuntu 18.04, (bionic)) uname -r (kernel version): 4.15.0-29-generic gcc --version: gcc (Ubuntu 7.3.0-16ubuntu3) 7.3.0 gfortran --version: GNU Fortran (Ubuntu 7.3.0-16ubuntu3) 7.3.0 * Dell Latitude D610 (Intel Pentium M, 1 processor, i686) Debian linux 4.0 (etch) uname -r (kernel version): 2.6.18-6-686 gcc --version: gcc (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) gfortran --version: GNU Fortran 95 (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) WCSLIB version 5.20 (2018/10/05) -------------------------------- * Dell Latitude XPS 15 9560 (Intel Core i7-7700HQ, 4 cores, 8 CPUs, x86_64) KDE Neon User Edition 5.13 (over Kubuntu 18.04, (bionic)) uname -r (kernel version): 4.15.0-29-generic gcc --version: gcc (Ubuntu 7.3.0-16ubuntu3) 7.3.0 gfortran --version: GNU Fortran (Ubuntu 7.3.0-16ubuntu3) 7.3.0 WCSLIB version 5.19 (2018/07/27) -------------------------------- * Dell Latitude E6530 (Intel Core i7-3740QM, 4 cores, 8 processors, x86_64) Debian linux 8.10 (jessie) uname -r (kernel version): 3.16.0-4-amd64 gcc --version: gcc-8.1.0 (GCC) 8.1.0 (local build) gfortran --version: GNU Fortran (GCC) 8.1.0 (local build) and gcc --version: gcc (Debian 4.9.2-10) 4.9.2 gfortran --version: GNU Fortran (Debian 4.9.2-10) 4.9.2 WCSLIB version 5.18 (2018/01/10) -------------------------------- * Dell Latitude XPS 15 9560 (Intel Core i7-7700HQ, 4 cores, 8 CPUs, x86_64) KDE Neon User Edition 5.11 (over Kubuntu 16.04, (xenial)) uname -r (kernel version): 4.10.0-40-generic gcc --version: gcc (Ubuntu 5.4.0-6ubuntu1~16.04.5) 5.4.0 20160609 gfortran --version: GNU Fortran (Ubuntu 5.4.0-6ubuntu1~16.04.5) 5.4.0 20160609 WCSLIB version 5.17 (2017/09/18) -------------------------------- * Dell Latitude E6530 (Intel Core i7-3740QM, 4 cores, 8 processors, x86_64) Debian linux 8.9 (jessie) uname -r (kernel version): 3.16.0-4-amd64 gcc --version: gcc (Debian 4.9.2-10) 4.9.2 gfortran --version: GNU Fortran (Debian 4.9.2-10) 4.9.2 WCSLIB version 5.16 (2017/01/15) -------------------------------- * Dell Latitude D620 (Intel Centrino T2300, 2 processors, i686) Debian linux 8.6 (jessie) uname -r (kernel version): 3.16.0-4-686-pae gcc --version: gcc (Debian 4.9.2-10) 4.9.2 gfortran --version: GNU Fortran (Debian 4.9.2-10) 4.9.2 WCSLIB version 5.15 (2016/04/05) -------------------------------- * Dell Latitude D620 (Intel Centrino T2300, 2 processors, i686) Debian linux 8.3 (jessie) uname -r (kernel version): 3.16.0-4-686-pae gcc --version: gcc (Debian 4.9.2-10) 4.9.2 gfortran --version: GNU Fortran (Debian 4.9.2-10) 4.9.2 WCSLIB version 5.14 (2016/02/07) -------------------------------- * Dell Latitude D620 (Intel Centrino T2300, 2 processors, i686) Debian linux 8.3 (jessie) uname -r (kernel version): 3.16.0-4-686-pae gcc --version: gcc (Debian 4.9.2-10) 4.9.2 gfortran --version: GNU Fortran (Debian 4.9.2-10) 4.9.2 WCSLIB version 5.13 (2016/01/26) -------------------------------- * Dell Latitude D620 (Intel Centrino T2300, 2 processors, i686) Debian linux 8.3 (jessie) uname -r (kernel version): 3.16.0-4-686-pae gcc --version: gcc (Debian 4.9.2-10) 4.9.2 gfortran --version: GNU Fortran (Debian 4.9.2-10) 4.9.2 WCSLIB version 5.12 (2015/11/15) -------------------------------- * Dell Latitude D620 (Intel Centrino T2300, 2 processors, i686) Debian linux 8.0 (jessie) uname -r (kernel version): 3.16.0-4-686-pae gcc --version: gcc (Debian 4.9.2-10) 4.9.2 gfortran --version: GNU Fortran (Debian 4.9.2-10) 4.9.2 WCSLIB version 5.11 (2015/10/18) -------------------------------- * Dell Latitude D620 (Intel Centrino T2300, 2 processors, i686) Debian linux 8.0 (jessie) uname -r (kernel version): 3.16.0-4-686-pae gcc --version: gcc (Debian 4.9.2-10) 4.9.2 gfortran --version: GNU Fortran (Debian 4.9.2-10) 4.9.2 WCSLIB version 5.10 (2015/10/09) -------------------------------- * Dell Latitude D620 (Intel Centrino T2300, 2 processors, i686) Debian linux 8.0 (jessie) uname -r (kernel version): 3.16.0-4-686-pae gcc --version: gcc (Debian 4.9.2-10) 4.9.2 gfortran --version: GNU Fortran (Debian 4.9.2-10) 4.9.2 WCSLIB version 5.9 (2015/07/21) ------------------------------- * Dell Latitude D620 (Intel Centrino T2300, 2 processors, i686) Debian linux 8.0 (jessie) uname -r (kernel version): 3.16.0-4-686-pae gcc --version: gcc (Debian 4.9.2-10) 4.9.2 gfortran --version: GNU Fortran (Debian 4.9.2-10) 4.9.2 WCSLIB version 5.8 (2015/07/08) ------------------------------- * Dell Latitude D620 (Intel Centrino T2300, 2 processors, i686) Debian linux 8.0 (jessie) uname -r (kernel version): 3.16.0-4-686-pae gcc --version: gcc (Debian 4.9.2-10) 4.9.2 gfortran --version: GNU Fortran (Debian 4.9.2-10) 4.9.2 WCSLIB version 5.7 (2015/06/29) ------------------------------- * Dell Latitude D620 (Intel Centrino T2300, 2 processors, i686) Debian linux 8.0 (jessie) uname -r (kernel version): 3.16.0-4-686-pae gcc --version: gcc (Debian 4.9.2-10) 4.9.2 gfortran --version: GNU Fortran (Debian 4.9.2-10) 4.9.2 WCSLIB version 5.6 (2015/06/14) ------------------------------- * Dell Latitude D620 (Intel Centrino T2300, 2 processors, i686) Debian linux 8.0 (jessie) uname -r (kernel version): 3.16.0-4-686-pae gcc --version: gcc (Debian 4.9.2-10) 4.9.2 gfortran --version: GNU Fortran (Debian 4.9.2-10) 4.9.2 WCSLIB version 5.5 (2015/05/05) ------------------------------- * Dell Latitude D620 (Intel Centrino T2300, 2 processors, i686) Debian linux 7.8 (wheezy) uname -r (kernel version): 3.2.0-4-686-pae gcc --version: gcc (Debian 4.7.2-5) 4.7.2 gfortran --version: GNU Fortran (Debian 4.7.2-5) 4.7.2 WCSLIB version 5.4 (2015/04/21) ------------------------------- * Dell Latitude D620 (Intel Centrino T2300, 2 processors, i686) Debian linux 7.8 (wheezy) uname -r (kernel version): 3.2.0-4-686-pae gcc --version: gcc (Debian 4.7.2-5) 4.7.2 gfortran --version: GNU Fortran (Debian 4.7.2-5) 4.7.2 WCSLIB version 5.3 (2015/04/21) ------------------------------- * Dell Latitude D620 (Intel Centrino T2300, 2 processors, i686) Debian linux 7.8 (wheezy) uname -r (kernel version): 3.2.0-4-686-pae gcc --version: gcc (Debian 4.7.2-5) 4.7.2 gfortran --version: GNU Fortran (Debian 4.7.2-5) 4.7.2 WCSLIB version 5.2 beta release (2015/04/15) -------------------------------------------- * Dell Latitude D620 (Intel Centrino T2300, 2 processors, i686) Debian linux 7.8 (wheezy) uname -r (kernel version): 3.2.0-4-686-pae gcc --version: gcc (Debian 4.7.2-5) 4.7.2 gfortran --version: GNU Fortran (Debian 4.7.2-5) 4.7.2 * Dell PowerEdge R710 (Intel Xeon E5530, 8 processors, amd64) Debian linux 7.8 (wheezy) uname -r (kernel version): 3.2.0-4-amd64 gcc --version: gcc (Debian 4.7.2-5) 4.7.2 gfortran --version: GNU Fortran (Debian 4.7.2-5) 4.7.2 (Non-graphical tests only.) * Mac Mini (Intel Core i7, 4 cores, x86_64) MacOSX 10.9.5 (13F1066) uname -r (kernel version): Darwin 13.4.0 gcc --version: gcc (GCC) 4.8.3 gfortran --version: GNU Fortran (GCC) 4.8.3 (Non-graphical tests only.) WCSLIB version 5.1 beta release (2015/04/07) -------------------------------------------- * Dell Latitude D620 (Intel Centrino T2300, 2 processors, i686) Debian linux 7.8 (wheezy) uname -r (kernel version): 3.2.0-4-686-pae gcc --version: gcc (Debian 4.7.2-5) 4.7.2 gfortran --version: GNU Fortran (Debian 4.7.2-5) 4.7.2 WCSLIB version 5.0 beta release (2015/04/05) -------------------------------------------- * Dell Latitude D620 (Intel Centrino T2300, 2 processors, i686) Debian linux 7.8 (wheezy) uname -r (kernel version): 3.2.0-4-686-pae gcc --version: gcc (Debian 4.7.2-5) 4.7.2 gfortran --version: GNU Fortran (Debian 4.7.2-5) 4.7.2 * Dell PowerEdge R710 (Intel Xeon E5530, 8 processors, amd64) Debian linux 7.8 (wheezy) uname -r (kernel version): 3.2.0-4-amd64 gcc --version: gcc (Debian 4.7.2-5) 4.7.2 gfortran --version: GNU Fortran (Debian 4.7.2-5) 4.7.2 (Non-graphical tests only.) * Dell PowerEdge R820 (Intel Xeon E5-4620, 32 processors, amd64) Debian linux 6.0.10 (squeeze) uname -r (kernel version): 3.2.0-0.bpo.4-amd64 gcc --version: gcc (Debian 4.4.5-8) 4.4.5 gfortran --version: GNU Fortran (Debian 4.4.5-8) 4.4.5 (Non-graphical tests only.) * Mac Mini (Intel Core i7, 4 cores, x86_64) MacOSX 10.9.5 (13F1066) uname -r (kernel version): Darwin 13.4.0 gcc --version: gcc (GCC) 4.8.3 gfortran --version: GNU Fortran (GCC) 4.8.3 (Non-graphical tests only.) WCSLIB version 4.23 (2014/05/11) -------------------------------- * Dell Latitude D620 (Intel Centrino, i686) running Debian linux 7.0 (wheezy) uname -r (kernel version): 3.2.0-4-686-pae gcc --version: gcc (Debian 4.7.2-5) 4.7.2 gfortran --version: GNU Fortran (Debian 4.7.2-5) 4.7.2 WCSLIB version 4.22 (2014/04/13) -------------------------------- * Dell Latitude D620 (Intel Centrino, i686) running Debian linux 7.0 (wheezy) uname -r (kernel version): 3.2.0-4-686-pae gcc --version: gcc (Debian 4.7.2-5) 4.7.2 gfortran --version: GNU Fortran (Debian 4.7.2-5) 4.7.2 * Dell PowerEdge R710 (Intel Xeon, x86_64) running Debian linux 6.0.9 (squeeze) uname -r (kernel version): 2.6.32-5-amd64 gcc --version: gcc (Debian 4.4.5-8) 4.4.5 gfortran --version: GNU Fortran (Debian 4.4.5-8) 4.4.5 * Mac Mini (Intel Core 2 Duo) running MacOSX 10.6.8 (10K549) uname -r (kernel version): 10.8.0 gcc --version: i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3) gfortran --version: GNU Fortran (GCC) 4.5.0 20100107 (experimental) (Non-graphics tests only.) WCSLIB version 4.21 (2014/03/24) -------------------------------- * Dell Latitude D620 (Intel Centrino, i686) running Debian linux 7.0 (wheezy) uname -r (kernel version): 3.2.0-4-686-pae gcc --version: gcc (Debian 4.7.2-5) 4.7.2 gfortran --version: GNU Fortran (Debian 4.7.2-5) 4.7.2 WCSLIB version 4.20 (2013/12/18) -------------------------------- * Dell Latitude D620 (Intel Centrino, i686) running Debian linux 7.0 (wheezy) uname -r (kernel version): 3.2.0-4-686-pae gcc --version: gcc (Debian 4.7.2-5) 4.7.2 gfortran --version: GNU Fortran (Debian 4.7.2-5) 4.7.2 WCSLIB version 4.19 (2013/09/30) -------------------------------- * Dell Latitude D620 (Intel Centrino, i686) running Debian linux 7.0 (wheezy) uname -r (kernel version): 3.2.0-4-686-pae gcc --version: gcc (Debian 4.7.2-5) 4.7.2 gfortran --version: GNU Fortran (Debian 4.7.2-5) 4.7.2 WCSLIB version 4.18 (2013/07/12) -------------------------------- * Dell Latitude D620 (Intel Centrino, i686) running Debian linux 7.0 (wheezy) uname -r (kernel version): 3.2.0-4-686-pae gcc --version: gcc (Debian 4.7.2-5) 4.7.2 gfortran --version: GNU Fortran (Debian 4.7.2-5) 4.7.2 WCSLIB version 4.17 (2013/01/29) -------------------------------- * Dell Latitude D620 (Intel Centrino, i686) running Debian linux 5.0.9 (lenny) uname -r (kernel version): 2.6.26-2-686 gcc --version: gcc (Debian 4.3.2-1.1) 4.3.2 gfortran --version: GNU Fortran (Debian 4.3.2-1.1) 4.3.2 WCSLIB version 4.15 (2012/09/26) -------------------------------- * Dell Latitude D620 (Intel Centrino, i686) running Debian linux 5.0.9 (lenny) uname -r (kernel version): 2.6.26-2-686 gcc --version: gcc (Debian 4.3.2-1.1) 4.3.2 gfortran --version: GNU Fortran (Debian 4.3.2-1.1) 4.3.2 WCSLIB version 4.14 (2012/07/13) -------------------------------- * Dell Latitude D620 (Intel Centrino, i686) running Debian linux 5.0.9 (lenny) uname -r (kernel version): 2.6.26-2-686 gcc --version: gcc (Debian 4.3.2-1.1) 4.3.2 gfortran --version: GNU Fortran (Debian 4.3.2-1.1) 4.3.2 * MacBook Pro (Intel Core 2 Duo) running MacOSX 10.7.3 (11D50) uname -r (Darwin kernel version): 11.3.0 gcc --version: i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Apple Inc. build 5658) (LLVM build 2336.1.00) gfortran --version: GNU Fortran (GCC) 4.6.1 (Non-graphics tests only.) WCSLIB version 4.13.1 (2012/03/15) ---------------------------------- * Dell Latitude D630 (Intel Centrino, i686) running Debian linux 5.0.9 (lenny) uname -r (kernel version): 2.6.32-bpo.5-686 gcc --version: gcc (Debian 4.3.2-1.1) 4.3.2 gfortran --version: GNU Fortran (Debian 4.3.2-1.1) 4.3.2 * MacBook Pro (Intel Core 2 Duo) running MacOSX 10.7.3 (11D50) uname -r (Darwin kernel version): 11.3.0 gcc --version: i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Apple Inc. build 5658) (LLVM build 2336.1.00) gfortran --version: GNU Fortran (GCC) 4.6.1 (Non-graphics tests only.) WCSLIB version 4.10 (2012/02/06) -------------------------------- * Dell Latitude D630 (Intel Centrino, i686) running Debian linux 5.0.9 (lenny) uname -r (kernel version): 2.6.32-bpo.5-686 gcc --version: gcc (Debian 4.3.2-1.1) 4.3.2 gfortran --version: GNU Fortran (Debian 4.3.2-1.1) 4.3.2 WCSLIB version 4.8 (2011/08/15) ------------------------------- * Dell Latitude D620 (Intel Centrino Duo, i686), Debian linux 4.0 (etch) uname -r (kernel version): 2.6.24-1-686 (32-bit) gcc --version: gcc (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) g77 --version: GNU Fortran (GCC) 3.4.6 (Debian 3.4.6-5) * Dell PowerEdge 2950 (Intel Xeon, 8 x X5460), Debian linux 5.0.8 (lenny) uname -r (kernel version): 2.6.26-2-amd64 (64-bit) gcc --version: gcc (Debian 4.3.2-1.1) 4.3.2 gfortran --version: GNU Fortran (Debian 4.3.2-1.1) 4.3.2 * Marvell SheevaPlug (Feroceon 88FR131 rev 1 ARM v5L), Debian linux 6.0 (squeeze) uname -r (kernel version): 2.6.32-5-kirkwood gcc --version: gcc (Debian 4.4.5-8) 4.4.5 gfortran --version: GNU Fortran (Debian 4.4.5-8) 4.4.5 * Mac mini (Intel Core 2 Duo) running MacOSX 10.6.2 (10C540) uname -r (Darwin kernel version): 10.2.0 gcc --version: i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5646) gfortran --version: GNU Fortran (GCC) 4.5.0 20100107 (experimental) * Enterprise 450 Model 2250 (Sparc, sun4u 64-bit), SunOS 5.9 (Solaris 9) uname -r (SunOS version): 5.9 gcc --version: gcc (GCC) 4.5.1 gfortran --version: GNU Fortran (GCC) 4.5.1 WCSLIB version 4.7 (2011/02/07) ------------------------------- * Dell Latitude D630 (Intel Centrino, i686) running Debian linux 4.0 (etch) uname -r (kernel version): 2.6.24-1-686 gcc --version: gcc (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) g77 --version: GNU Fortran (GCC) 3.4.6 (Debian 3.4.6-5) * Sun SunFire V20z (AMD Opteron, x86_64) running Debian linux 4.0 (etch) uname -r (kernel version): 2.6.18-6-amd64 gcc --version: gcc (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) g77 --version: GNU Fortran (GCC) 3.4.6 (Debian 3.4.6-5) * Enterprise 450 Model 2250 (Sparc, sun4u 64-bit), SunOS 5.9 (Solaris 9) uname -r (SunOS version): 5.9 gcc --version: gcc (GCC) 4.5.1 gfortran --version: GNU Fortran (GCC) 4.5.1 and cc -V: cc: Sun WorkShop 6 update 2 C 5.3 Patch 111679-14 2004/02/20 f77 -V: f77: Sun WorkShop 6 update 2 FORTRAN 77 5.3 Patch 111691-07 2004/04/23 * Mac Xserve (Quad-Core Intel Xeon) running MacOSX 10.6.5 (10H575) uname -r (Darwin kernel version): 10.5.0 gcc --version: 4.2.1 (Apple Inc. build 5664) gfortran --version: GNU Fortran (GCC) 4.5.0 20100107 (experimental) * Mac mini (Intel Core 2 Duo) running MacOSX 10.6.2 (10C540) uname -r (Darwin kernel version): 10.2.0 gcc --version: i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5646) gfortran --version: GNU Fortran (GCC) 4.5.0 20100107 (experimental) * Mac mini (Intel Core Duo) running MacOSX 10.4.9 (8P2137) uname -r (Darwin kernel version): 8.9.1 gcc --version: gcc (GCC) 4.3.0 20070316 (experimental) g77 --version: GNU Fortran (GCC) 3.4.0 WCSLIB version 4.5 (2010/07/16) ------------------------------- * Dell Latitude D630 (Intel Centrino, i686) running Debian linux 4.0 (etch) uname -r (kernel version): 2.6.24-1-686 gcc --version: gcc (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) g77 --version: GNU Fortran (GCC) 3.4.6 (Debian 3.4.6-5) and gcc --version: gcc (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) ifort -V: Intel(R) Fortran Compiler for 32-bit applications, Version 8.1 Build 20041118Z Package ID: l_fc_pc_8.1.023 * Mac mini (Intel Core 2 Duo, i386) running MacOSX 10.6.2 (10C540) uname -r (Darwin kernel version): 10.2.0 gcc --version: i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5646) gfortran --version: GNU Fortran (GCC) 4.5.0 20100107 (experimental) * Mac mini (Intel Core Duo, i386) running MacOSX 10.4.9 (8P2137) uname -r (Darwin kernel version): 8.9.1 gcc --version: gcc (GCC) 4.3.0 20070316 (experimental) g77 --version: GNU Fortran (GCC) 3.4.0 and gcc --version: gcc (GCC) 4.3.0 20070316 (experimental) gfortran --version: GNU Fortran (GCC) 4.3.0 20070316 (experimental) * Sun SunFire V20z (AMD Opteron, x86_64) running Debian linux 4.0 (etch) uname -r (kernel version): 2.6.18-6-amd64 gcc --version: gcc (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) g77 --version: GNU Fortran (GCC) 3.4.6 (Debian 3.4.6-5) and gcc --version: gcc (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) gfortran --version: GNU Fortran 95 (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) * Sun Ultra-60 (Sparc, sun4u) running SunOS 5.6 (Solaris 2.6) uname -r (SunOS version): 5.6 gcc --version: 2.95.3 g77 --version: GNU Fortran 0.5.25 20010315 (release) and cc -V: cc: Sun WorkShop 6 update 2 C 5.3 Patch 111679-14 2004/02/20 f77 -V: f77: Sun WorkShop 6 update 2 FORTRAN 77 5.3 Patch 111691-07 2004/04/23 WCSLIB version 4.4 (2009/08/06) ------------------------------- * Dell Latitude D630 (Intel Centrino, i686) running Debian linux 4.0 (etch) uname -r (kernel version): 2.6.24-1-686 gcc --version: gcc (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) g77 --version: GNU Fortran (GCC) 3.4.6 (Debian 3.4.6-5) * Mac mini (Intel Core Duo, i386) running MacOSX 10.4.9 (8P2137) uname -r (Darwin kernel version): 8.9.1 gcc --version: gcc (GCC) 4.3.0 20070316 (experimental) g77 --version: GNU Fortran (GCC) 3.4.0 and gcc --version: gcc (GCC) 4.3.0 20070316 (experimental) gfortran --version: GNU Fortran (GCC) 4.3.0 20070316 (experimental) * Sun SunFire V20z (AMD Opteron, x86_64) running Debian linux 4.0 (etch) uname -r (kernel version): 2.6.18-6-amd64 gcc --version: gcc (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) g77 --version: GNU Fortran (GCC) 3.4.6 (Debian 3.4.6-5) and gcc --version: gcc (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) gfortran --version: GNU Fortran 95 (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) * Sun SunBlade 1000 (Sparc, sun4u) running SunOS 5.8 (Solaris 2.8) uname -r (SunOS version): 5.8 gcc --version: 2.95.3 g77 --version: GNU Fortran 0.5.25 20010315 (release) and cc -V: cc: Sun WorkShop 6 update 2 C 5.3 Patch 111679-14 2004/02/20 f77 -V: f77: Sun WorkShop 6 update 2 FORTRAN 77 5.3 Patch 111691-07 2004/04/23 ------------------------------------------------------------------------------ $Id: VALIDATION,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1646921593.275261 astropy-5.0.2/cextern/wcslib/config/0000755000175100001710000000000000000000000016445 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/config/config.guess0000644000175100001710000012621600000000000020772 0ustar00vstsdocker#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2018 Free Software Foundation, Inc. timestamp='2018-07-18' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # # Please send patches to . me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. tmp= # shellcheck disable=SC2172 trap 'test -z "$tmp" || rm -fr "$tmp"' 1 2 13 15 trap 'exitcode=$?; test -z "$tmp" || rm -fr "$tmp"; exit $exitcode' 0 set_cc_for_build() { : "${TMPDIR=/tmp}" # shellcheck disable=SC2039 { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } dummy=$tmp/dummy case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in ,,) echo "int x;" > "$dummy.c" for driver in cc gcc c89 c99 ; do if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD="$driver" break fi done if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac } # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "$UNAME_SYSTEM" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu set_cc_for_build cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" # If ldd exists, use it to detect musl libc. if command -v ldd >/dev/null && \ ldd --version 2>&1 | grep -q ^musl then LIBC=musl fi ;; esac # Note: order is significant - the case branches are not exclusive. case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ "/sbin/$sysctl" 2>/dev/null || \ "/usr/sbin/$sysctl" 2>/dev/null || \ echo unknown)` case "$UNAME_MACHINE_ARCH" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` machine="${arch}${endian}"-unknown ;; *) machine="$UNAME_MACHINE_ARCH"-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. case "$UNAME_MACHINE_ARCH" in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case "$UNAME_MACHINE_ARCH" in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "$UNAME_VERSION" in Debian*) release='-gnu' ;; *) release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "$machine-${os}${release}${abi-}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" exit ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" exit ;; *:MidnightBSD:*:*) echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" exit ;; *:ekkoBSD:*:*) echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" exit ;; *:SolidBSD:*:*) echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:MirBSD:*:*) echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:Sortix:*:*) echo "$UNAME_MACHINE"-unknown-sortix exit ;; *:Redox:*:*) echo "$UNAME_MACHINE"-unknown-redox exit ;; mips:OSF1:*.*) echo mips-dec-osf1 exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") UNAME_MACHINE=alpha ;; "EV5 (21164)") UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo "$UNAME_MACHINE"-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo "$UNAME_MACHINE"-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix"$UNAME_RELEASE" exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux"$UNAME_RELEASE" exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) UNAME_REL="`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" case `isainfo -b` in 32) echo i386-pc-solaris2"$UNAME_REL" ;; 64) echo x86_64-pc-solaris2"$UNAME_REL" ;; esac exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos"$UNAME_RELEASE" exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos"$UNAME_RELEASE" ;; sun4) echo sparc-sun-sunos"$UNAME_RELEASE" ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos"$UNAME_RELEASE" exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint"$UNAME_RELEASE" exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint"$UNAME_RELEASE" exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint"$UNAME_RELEASE" exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint"$UNAME_RELEASE" exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint"$UNAME_RELEASE" exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint"$UNAME_RELEASE" exit ;; m68k:machten:*:*) echo m68k-apple-machten"$UNAME_RELEASE" exit ;; powerpc:machten:*:*) echo powerpc-apple-machten"$UNAME_RELEASE" exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix"$UNAME_RELEASE" exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix"$UNAME_RELEASE" exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix"$UNAME_RELEASE" exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos"$UNAME_RELEASE" exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] then if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ [ "$TARGET_BINARY_INTERFACE"x = x ] then echo m88k-dg-dgux"$UNAME_RELEASE" else echo m88k-dg-dguxbcs"$UNAME_RELEASE" fi else echo i586-dg-dgux"$UNAME_RELEASE" fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/lslpp ] ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi echo "$IBM_ARCH"-ibm-aix"$IBM_REV" exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` case "$UNAME_MACHINE" in 9000/31?) HP_ARCH=m68000 ;; 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "$sc_cpu_version" in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "$sc_kernel_bits" in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi if [ "$HP_ARCH" = "" ]; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ "$HP_ARCH" = hppa2.0w ] then set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH=hppa2.0w else HP_ARCH=hppa64 fi fi echo "$HP_ARCH"-hp-hpux"$HPUX_REV" exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo "$UNAME_MACHINE"-unknown-osf1mk else echo "$UNAME_MACHINE"-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi"$UNAME_RELEASE" exit ;; *:BSD/OS:*:*) echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" exit ;; arm*:FreeBSD:*:*) UNAME_PROCESSOR=`uname -p` set_cc_for_build if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabi else echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabihf fi exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case "$UNAME_PROCESSOR" in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; i*:CYGWIN*:*) echo "$UNAME_MACHINE"-pc-cygwin exit ;; *:MINGW64*:*) echo "$UNAME_MACHINE"-pc-mingw64 exit ;; *:MINGW*:*) echo "$UNAME_MACHINE"-pc-mingw32 exit ;; *:MSYS*:*) echo "$UNAME_MACHINE"-pc-msys exit ;; i*:PW*:*) echo "$UNAME_MACHINE"-pc-pw32 exit ;; *:Interix*:*) case "$UNAME_MACHINE" in x86) echo i586-pc-interix"$UNAME_RELEASE" exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix"$UNAME_RELEASE" exit ;; IA64) echo ia64-unknown-interix"$UNAME_RELEASE" exit ;; esac ;; i*:UWIN*:*) echo "$UNAME_MACHINE"-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; *:GNU:*:*) # the GNU system echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" exit ;; *:Minix:*:*) echo "$UNAME_MACHINE"-unknown-minix exit ;; aarch64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arm*:Linux:*:*) set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi else echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf fi fi exit ;; avr32*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; cris:Linux:*:*) echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; crisv32:Linux:*:*) echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; e2k:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; frv:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; hexagon:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:Linux:*:*) echo "$UNAME_MACHINE"-pc-linux-"$LIBC" exit ;; ia64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; k1om:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m32r*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m68*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; mips:Linux:*:* | mips64:Linux:*:*) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`" test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; } ;; mips64el:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-"$LIBC" exit ;; or32:Linux:*:* | or1k*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; padre:Linux:*:*) echo sparc-unknown-linux-"$LIBC" exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-"$LIBC" exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; *) echo hppa-unknown-linux-"$LIBC" ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-"$LIBC" exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-"$LIBC" exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-"$LIBC" exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-"$LIBC" exit ;; riscv32:Linux:*:* | riscv64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" exit ;; sh64*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sh*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; tile*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; vax:Linux:*:*) echo "$UNAME_MACHINE"-dec-linux-"$LIBC" exit ;; x86_64:Linux:*:*) echo "$UNAME_MACHINE"-pc-linux-"$LIBC" exit ;; xtensa*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo "$UNAME_MACHINE"-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo "$UNAME_MACHINE"-unknown-stop exit ;; i*86:atheos:*:*) echo "$UNAME_MACHINE"-unknown-atheos exit ;; i*86:syllable:*:*) echo "$UNAME_MACHINE"-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos"$UNAME_RELEASE" exit ;; i*86:*DOS:*:*) echo "$UNAME_MACHINE"-pc-msdosdjgpp exit ;; i*86:*:4.*:*) UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" else echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}" exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" else echo "$UNAME_MACHINE"-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos"$UNAME_RELEASE" exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos"$UNAME_RELEASE" exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos"$UNAME_RELEASE" exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos"$UNAME_RELEASE" exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv"$UNAME_RELEASE" exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo "$UNAME_MACHINE"-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo "$UNAME_MACHINE"-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux"$UNAME_RELEASE" exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv"$UNAME_RELEASE" else echo mips-unknown-sysv"$UNAME_RELEASE" fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux"$UNAME_RELEASE" exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux"$UNAME_RELEASE" exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux"$UNAME_RELEASE" exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux"$UNAME_RELEASE" exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux"$UNAME_RELEASE" exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux"$UNAME_RELEASE" exit ;; SX-ACE:SUPER-UX:*:*) echo sxace-nec-superux"$UNAME_RELEASE" exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Rhapsody:*:*) echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown set_cc_for_build if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_PPC >/dev/null then UNAME_PROCESSOR=powerpc fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub # that puts up a graphical alert prompting to install # developer tools. Any system running Mac OS X 10.7 or # later (Darwin 11 and later) is required to have a 64-bit # processor. This is not true of the ARM version of Darwin # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-*:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk"$UNAME_RELEASE" exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk"$UNAME_RELEASE" exit ;; NSR-*:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk"$UNAME_RELEASE" exit ;; NSV-*:NONSTOP_KERNEL:*:*) echo nsv-tandem-nsk"$UNAME_RELEASE" exit ;; NSX-*:NONSTOP_KERNEL:*:*) echo nsx-tandem-nsk"$UNAME_RELEASE" exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. # shellcheck disable=SC2154 if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo "$UNAME_MACHINE"-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux"$UNAME_RELEASE" exit ;; *:DragonFly:*:*) echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "$UNAME_MACHINE" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" exit ;; i*86:rdos:*:*) echo "$UNAME_MACHINE"-pc-rdos exit ;; i*86:AROS:*:*) echo "$UNAME_MACHINE"-pc-aros exit ;; x86_64:VMkernel:*:*) echo "$UNAME_MACHINE"-unknown-esx exit ;; amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; esac echo "$0: unable to guess system type" >&2 case "$UNAME_MACHINE:$UNAME_SYSTEM" in mips:Linux | mips64:Linux) # If we got here on MIPS GNU/Linux, output extra information. cat >&2 <&2 </dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = "$UNAME_MACHINE" UNAME_RELEASE = "$UNAME_RELEASE" UNAME_SYSTEM = "$UNAME_SYSTEM" UNAME_VERSION = "$UNAME_VERSION" EOF exit 1 # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/config/config.sub0000644000175100001710000010555700000000000020442 0ustar00vstsdocker#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2018 Free Software Foundation, Inc. timestamp='2018-07-25' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo "$1" exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Split fields of configuration type IFS="-" read -r field1 field2 field3 field4 <&2 exit 1 ;; *-*-*-*) basic_machine=$field1-$field2 os=$field3-$field4 ;; *-*-*) # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two # parts maybe_os=$field2-$field3 case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc \ | linux-newlib* | linux-musl* | linux-uclibc* | uclinux-uclibc* \ | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ | storm-chaos* | os2-emx* | rtmk-nova*) basic_machine=$field1 os=$maybe_os ;; android-linux) basic_machine=$field1-unknown os=linux-android ;; *) basic_machine=$field1-$field2 os=$field3 ;; esac ;; *-*) # Second component is usually, but not always the OS case $field2 in # Prevent following clause from handling this valid os sun*os*) basic_machine=$field1 os=$field2 ;; # Manufacturers dec* | mips* | sequent* | encore* | pc532* | sgi* | sony* \ | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ | unicom* | ibm* | next | hp | isi* | apollo | altos* \ | convergent* | ncr* | news | 32* | 3600* | 3100* | hitachi* \ | c[123]* | convex* | sun | crds | omron* | dg | ultra | tti* \ | harris | dolphin | highlevel | gould | cbm | ns | masscomp \ | apple | axis | knuth | cray | microblaze* \ | sim | cisco | oki | wec | wrs | winbond) basic_machine=$field1-$field2 os= ;; *) basic_machine=$field1 os=$field2 ;; esac ;; *) # Convert single-component short-hands not valid as part of # multi-component configurations. case $field1 in 386bsd) basic_machine=i386-pc os=bsd ;; a29khif) basic_machine=a29k-amd os=udi ;; adobe68k) basic_machine=m68010-adobe os=scout ;; am29k) basic_machine=a29k-none os=bsd ;; amdahl) basic_machine=580-amdahl os=sysv ;; amigaos | amigados) basic_machine=m68k-unknown os=amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=sysv4 ;; apollo68) basic_machine=m68k-apollo os=sysv ;; apollo68bsd) basic_machine=m68k-apollo os=bsd ;; aros) basic_machine=i386-pc os=aros ;; aux) basic_machine=m68k-apple os=aux ;; balance) basic_machine=ns32k-sequent os=dynix ;; blackfin) basic_machine=bfin-unknown os=linux ;; cegcc) basic_machine=arm-unknown os=cegcc ;; cray) basic_machine=j90-cray os=unicos ;; craynv) basic_machine=craynv-cray os=unicosmp ;; delta88) basic_machine=m88k-motorola os=sysv3 ;; dicos) basic_machine=i686-pc os=dicos ;; djgpp) basic_machine=i586-pc os=msdosdjgpp ;; ebmon29k) basic_machine=a29k-amd os=ebmon ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=ose ;; gmicro) basic_machine=tron-gmicro os=sysv ;; go32) basic_machine=i386-pc os=go32 ;; h8300hms) basic_machine=h8300-hitachi os=hms ;; h8300xray) basic_machine=h8300-hitachi os=xray ;; h8500hms) basic_machine=h8500-hitachi os=hms ;; harris) basic_machine=m88k-harris os=sysv3 ;; hp300bsd) basic_machine=m68k-hp os=bsd ;; hp300hpux) basic_machine=m68k-hp os=hpux ;; hppaosf) basic_machine=hppa1.1-hp os=osf ;; hppro) basic_machine=hppa1.1-hp os=proelf ;; i386mach) basic_machine=i386-mach os=mach ;; vsta) basic_machine=i386-pc os=vsta ;; isi68 | isi) basic_machine=m68k-isi os=sysv ;; m68knommu) basic_machine=m68k-unknown os=linux ;; magnum | m3230) basic_machine=mips-mips os=sysv ;; merlin) basic_machine=ns32k-utek os=sysv ;; mingw64) basic_machine=x86_64-pc os=mingw64 ;; mingw32) basic_machine=i686-pc os=mingw32 ;; mingw32ce) basic_machine=arm-unknown os=mingw32ce ;; monitor) basic_machine=m68k-rom68k os=coff ;; morphos) basic_machine=powerpc-unknown os=morphos ;; moxiebox) basic_machine=moxie-unknown os=moxiebox ;; msdos) basic_machine=i386-pc os=msdos ;; msys) basic_machine=i686-pc os=msys ;; mvs) basic_machine=i370-ibm os=mvs ;; nacl) basic_machine=le32-unknown os=nacl ;; ncr3000) basic_machine=i486-ncr os=sysv4 ;; netbsd386) basic_machine=i386-pc os=netbsd ;; netwinder) basic_machine=armv4l-rebel os=linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=newsos ;; news1000) basic_machine=m68030-sony os=newsos ;; necv70) basic_machine=v70-nec os=sysv ;; nh3000) basic_machine=m68k-harris os=cxux ;; nh[45]000) basic_machine=m88k-harris os=cxux ;; nindy960) basic_machine=i960-intel os=nindy ;; mon960) basic_machine=i960-intel os=mon960 ;; nonstopux) basic_machine=mips-compaq os=nonstopux ;; os400) basic_machine=powerpc-ibm os=os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=ose ;; os68k) basic_machine=m68k-none os=os68k ;; paragon) basic_machine=i860-intel os=osf ;; parisc) basic_machine=hppa-unknown os=linux ;; pw32) basic_machine=i586-unknown os=pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=rdos ;; rdos32) basic_machine=i386-pc os=rdos ;; rom68k) basic_machine=m68k-rom68k os=coff ;; sa29200) basic_machine=a29k-amd os=udi ;; sei) basic_machine=mips-sei os=seiux ;; sps7) basic_machine=m68k-bull os=sysv2 ;; stratus) basic_machine=i860-stratus os=sysv4 ;; sun2os3) basic_machine=m68000-sun os=sunos3 ;; sun2os4) basic_machine=m68000-sun os=sunos4 ;; sun3os3) basic_machine=m68k-sun os=sunos3 ;; sun3os4) basic_machine=m68k-sun os=sunos4 ;; sun4os3) basic_machine=sparc-sun os=sunos3 ;; sun4os4) basic_machine=sparc-sun os=sunos4 ;; sun4sol2) basic_machine=sparc-sun os=solaris2 ;; sv1) basic_machine=sv1-cray os=unicos ;; symmetry) basic_machine=i386-sequent os=dynix ;; t3e) basic_machine=alphaev5-cray os=unicos ;; t90) basic_machine=t90-cray os=unicos ;; toad1) basic_machine=pdp10-xkl os=tops20 ;; tpf) basic_machine=s390x-ibm os=tpf ;; udi29k) basic_machine=a29k-amd os=udi ;; ultra3) basic_machine=a29k-nyu os=sym1 ;; v810 | necv810) basic_machine=v810-nec os=none ;; vaxv) basic_machine=vax-dec os=sysv ;; vms) basic_machine=vax-dec os=vms ;; vxworks960) basic_machine=i960-wrs os=vxworks ;; vxworks68) basic_machine=m68k-wrs os=vxworks ;; vxworks29k) basic_machine=a29k-wrs os=vxworks ;; xbox) basic_machine=i686-pc os=mingw32 ;; ymp) basic_machine=ymp-cray os=unicos ;; *) basic_machine=$1 os= ;; esac ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv6m | armv[78][arm] \ | avr | avr32 \ | ba \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper | csky \ | d10v | d30v | dlx | dsp16xx \ | e2k | epiphany \ | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia16 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nfp \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ | pdp10 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pru \ | pyramid \ | riscv | riscv32 | riscv64 \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | visium \ | wasm32 \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; leon|leon[3-9]) basic_machine=sparc-$basic_machine ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=${os:-none} ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65) ;; m9s12z | m68hcs12z | hcs12z | s12z) basic_machine=s12z-unknown os=${os:-none} ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=${os:-none} ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | ba-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | csky-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | e2k-* | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia16-* | ia64-* \ | ip2k-* | iq2000-* \ | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa32r6-* | mipsisa32r6el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64r6-* | mipsisa64r6el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | moxie-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nfp-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | or1k*-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pru-* \ | pyramid-* \ | riscv-* | riscv32-* | riscv64-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | visium-* \ | wasm32-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; abacus) basic_machine=abacus-unknown ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; amiga | amiga-*) basic_machine=m68k-unknown ;; asmjs) basic_machine=asmjs-unknown ;; blackfin-*) basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=linux ;; bluegene*) basic_machine=powerpc-ibm os=cnk ;; c54x-*) basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=${os:-unicos} ;; convex-c1) basic_machine=c1-convex os=bsd ;; convex-c2) basic_machine=c2-convex os=bsd ;; convex-c32) basic_machine=c32-convex os=bsd ;; convex-c34) basic_machine=c34-convex os=bsd ;; convex-c38) basic_machine=c38-convex os=bsd ;; cr16 | cr16-*) basic_machine=cr16-unknown os=${os:-elf} ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=${os:-elf} ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=${os:-bosx} ;; dpx2*) basic_machine=m68k-bull os=sysv3 ;; e500v[12]) basic_machine=powerpc-unknown os=$os"spe" ;; e500v[12]-*) basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=$os"spe" ;; encore | umax | mmax) basic_machine=ns32k-encore ;; elxsi) basic_machine=elxsi-elxsi os=${os:-bsd} ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=hiuxwe2 ;; hp300-*) basic_machine=m68k-hp ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=sysv32 ;; i*86v4*) basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=sysv4 ;; i*86v) basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=sysv ;; i*86sol2) basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=solaris2 ;; j90 | j90-cray) basic_machine=j90-cray os=${os:-unicos} ;; iris | iris4d) basic_machine=mips-sgi case $os in irix*) ;; *) os=irix4 ;; esac ;; leon-*|leon[3-9]-*) basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'` ;; m68knommu-*) basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=linux ;; microblaze*) basic_machine=microblaze-xilinx ;; miniframe) basic_machine=m68000-convergent ;; *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=mint ;; mips3*-*) basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown ;; ms1-*) basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'` ;; news-3600 | risc-news) basic_machine=mips-sony os=newsos ;; next | m*-next) basic_machine=m68k-next case $os in nextstep* ) ;; ns2*) os=nextstep2 ;; *) os=nextstep3 ;; esac ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; nsv-tandem) basic_machine=nsv-tandem ;; nsx-tandem) basic_machine=nsx-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=hiuxwe2 ;; parisc-*) basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=${os:-elf} ;; sequent) basic_machine=i386-sequent ;; sh5el) basic_machine=sh5le-unknown ;; simso-wrs) basic_machine=sparclite-wrs os=vxworks ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; strongarm-* | thumb-*) basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; tile*) basic_machine=$basic_machine-unknown os=linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; tower | tower-32) basic_machine=m68k-ncr ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; w65*) basic_machine=w65-wdc os=none ;; w89k-*) basic_machine=hppa1.1-winbond os=proelf ;; x64) basic_machine=x86_64-pc ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'` ;; none) basic_machine=none-none os=${os:-none} ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *) echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x$os != x ] then case $os in # First match some system type aliases that might get confused # with valid system types. # solaris* is a basic system type, with this one exception. auroraux) os=auroraux ;; bluegene*) os=cnk ;; solaris1 | solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; solaris) os=solaris2 ;; unixware*) os=sysv4.2uw ;; gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # es1800 is here to avoid being matched by es* (a different OS) es1800*) os=ose ;; # Some version numbers need modification chorusos*) os=chorusos ;; isc) os=isc2.2 ;; sco6) os=sco5v6 ;; sco5) os=sco3.2v5 ;; sco4) os=sco3.2v4 ;; sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` ;; sco3.2v[4-9]* | sco5v6*) # Don't forget version if it is 3.2v4 or newer. ;; scout) # Don't match below ;; sco*) os=sco3.2v2 ;; psos*) os=psos ;; # Now accept the basic system types. # The portable systems comes first. # Each alternative MUST end in a * to match a version number. # sysv* is not here because it comes later, after sysvr4. gnu* | bsd* | mach* | minix* | genix* | ultrix* | irix* \ | *vms* | esix* | aix* | cnk* | sunos | sunos[34]*\ | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ | sym* | kopensolaris* | plan9* \ | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ | aos* | aros* | cloudabi* | sortix* \ | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \ | clix* | riscos* | uniplus* | iris* | rtu* | xenix* \ | knetbsd* | mirbsd* | netbsd* \ | bitrig* | openbsd* | solidbsd* | libertybsd* \ | ekkobsd* | kfreebsd* | freebsd* | riscix* | lynxos* \ | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ | udi* | eabi* | lites* | ieee* | go32* | aux* | hcos* \ | chorusrdb* | cegcc* | glidix* \ | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ | midipix* | mingw32* | mingw64* | linux-gnu* | linux-android* \ | linux-newlib* | linux-musl* | linux-uclibc* \ | uxpv* | beos* | mpeix* | udk* | moxiebox* \ | interix* | uwin* | mks* | rhapsody* | darwin* \ | openstep* | oskit* | conix* | pw32* | nonstopux* \ | storm-chaos* | tops10* | tenex* | tops20* | its* \ | os2* | vos* | palmos* | uclinux* | nucleus* \ | morphos* | superux* | rtmk* | windiss* \ | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ | skyos* | haiku* | rdos* | toppers* | drops* | es* \ | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ | midnightbsd*) # Remember, each alternative MUST END IN *, to match a version number. ;; qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=nto-$os ;; esac ;; hiux*) os=hiuxwe2 ;; nto-qnx*) ;; nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; sim | xray | os68k* | v88r* \ | windows* | osx | abug | netware* | os9* \ | macos* | mpw* | magic* | mmixware* | mon960* | lnews*) ;; linux-dietlibc) os=linux-dietlibc ;; linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; lynx*178) os=lynxos178 ;; lynx*5) os=lynxos5 ;; lynx*) os=lynxos ;; mac*) os=`echo "$os" | sed -e 's|mac|macos|'` ;; opened*) os=openedition ;; os400*) os=os400 ;; sunos5*) os=`echo "$os" | sed -e 's|sunos5|solaris2|'` ;; sunos6*) os=`echo "$os" | sed -e 's|sunos6|solaris3|'` ;; wince*) os=wince ;; utek*) os=bsd ;; dynix*) os=bsd ;; acis*) os=aos ;; atheos*) os=atheos ;; syllable*) os=syllable ;; 386bsd) os=bsd ;; ctix* | uts*) os=sysv ;; nova*) os=rtmk-nova ;; ns2) os=nextstep2 ;; nsk*) os=nsk ;; # Preserve the version number of sinix5. sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; sinix*) os=sysv4 ;; tpf*) os=tpf ;; triton*) os=sysv3 ;; oss*) os=sysv3 ;; svr4*) os=sysv4 ;; svr3) os=sysv3 ;; sysvr4) os=sysv4 ;; # This must come after sysvr4. sysv*) ;; ose*) os=ose ;; *mint | mint[0-9]* | *MiNT | MiNT[0-9]*) os=mint ;; zvmoe) os=zvmoe ;; dicos*) os=dicos ;; pikeos*) # Until real need of OS specific support for # particular features comes up, bare metal # configurations are quite functional. case $basic_machine in arm*) os=eabi ;; *) os=elf ;; esac ;; nacl*) ;; ios) ;; none) ;; *-eabi) ;; *) echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=elf ;; spu-*) os=elf ;; *-acorn) os=riscix1.2 ;; arm*-rebel) os=linux ;; arm*-semi) os=aout ;; c4x-* | tic4x-*) os=coff ;; c8051-*) os=elf ;; clipper-intergraph) os=clix ;; hexagon-*) os=elf ;; tic54x-*) os=coff ;; tic55x-*) os=coff ;; tic6x-*) os=coff ;; # This must come before the *-dec entry. pdp10-*) os=tops20 ;; pdp11-*) os=none ;; *-dec | vax-*) os=ultrix4.2 ;; m68*-apollo) os=domain ;; i386-sun) os=sunos4.0.2 ;; m68000-sun) os=sunos3 ;; m68*-cisco) os=aout ;; mep-*) os=elf ;; mips*-cisco) os=elf ;; mips*-*) os=elf ;; or32-*) os=coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=sysv3 ;; sparc-* | *-sun) os=sunos4.1.1 ;; pru-*) os=elf ;; *-be) os=beos ;; *-ibm) os=aix ;; *-knuth) os=mmixware ;; *-wec) os=proelf ;; *-winbond) os=proelf ;; *-oki) os=proelf ;; *-hp) os=hpux ;; *-hitachi) os=hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=sysv ;; *-cbm) os=amigaos ;; *-dg) os=dgux ;; *-dolphin) os=sysv3 ;; m68k-ccur) os=rtu ;; m88k-omron*) os=luna ;; *-next) os=nextstep ;; *-sequent) os=ptx ;; *-crds) os=unos ;; *-ns) os=genix ;; i370-*) os=mvs ;; *-gould) os=sysv ;; *-highlevel) os=bsd ;; *-encore) os=bsd ;; *-sgi) os=irix ;; *-siemens) os=sysv4 ;; *-masscomp) os=rtu ;; f30[01]-fujitsu | f700-fujitsu) os=uxpv ;; *-rom68k) os=coff ;; *-*bug) os=coff ;; *-apple) os=macos ;; *-atari*) os=mint ;; *-wrs) os=vxworks ;; *) os=none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in riscix*) vendor=acorn ;; sunos*) vendor=sun ;; cnk*|-aix*) vendor=ibm ;; beos*) vendor=be ;; hpux*) vendor=hp ;; mpeix*) vendor=hp ;; hiux*) vendor=hitachi ;; unos*) vendor=crds ;; dgux*) vendor=dg ;; luna*) vendor=omron ;; genix*) vendor=ns ;; clix*) vendor=intergraph ;; mvs* | opened*) vendor=ibm ;; os400*) vendor=ibm ;; ptx*) vendor=sequent ;; tpf*) vendor=ibm ;; vxsim* | vxworks* | windiss*) vendor=wrs ;; aux*) vendor=apple ;; hms*) vendor=hitachi ;; mpw* | macos*) vendor=apple ;; *mint | mint[0-9]* | *MiNT | MiNT[0-9]*) vendor=atari ;; vos*) vendor=stratus ;; esac basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"` ;; esac echo "$basic_machine-$os" exit # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/config/install-sh0000755000175100001710000003325500000000000020461 0ustar00vstsdocker#!/bin/sh # install - install a program, script, or datafile scriptversion=2011-11-20.07; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/configure0000755000175100001710000103410700000000000017115 0ustar00vstsdocker#! /bin/sh # From configure.ac Revision: 7.7 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for WCSLIB 7.7. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and $0: mark@calabretta.id.au about your system, including any $0: error possibly output before this message. Then install $0: a modern shell, or manually run the script under such a $0: shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='WCSLIB' PACKAGE_TARNAME='wcslib-7.7' PACKAGE_VERSION='7.7' PACKAGE_STRING='WCSLIB 7.7' PACKAGE_BUGREPORT='mark@calabretta.id.au' PACKAGE_URL='' ac_unique_file="C/wcs.h" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='LTLIBOBJS FLAVOUR OBSTZ OBSLAT OBSLNG INSTDIR TSTDIRS SUBDIRS PGPLOTLIB PGPLOTINC GETWCSTAB CFITSIOLIB CFITSIOINC XMKMF MAKEFLAGS INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM LN_S SHRLN SHRSFX SHRLD SHRFLAGS SONAME SHRLIB RANLIB ARFLAGS FLIBS ac_ct_F77 FFLAGS F77 LIBOBJS FLFLAGS EGREP GREP CPP OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC FLEX ARCH host_os host_vendor host_cpu host build_os build_vendor build_cpu build LIBVER target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_flex enable_fortran enable_shared enable_largefile with_cfitsio with_cfitsiolib with_cfitsioinc with_pgplot with_pgplotlib with_pgplotinc with_x enable_utils ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP F77 FFLAGS XMKMF' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures WCSLIB 7.7 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/wcslib-7.7] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF X features: --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of WCSLIB 7.7:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-flex don't apply flex (use pre-generated sources) --enable-fortran=ARG Fortran compiler to use --disable-fortran don't build the Fortran wrappers or PGSBOX --disable-shared don't build the WCS shared libraries --disable-largefile omit support for large files --disable-utils don't build the WCS utilities Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --without-cfitsio eschew CFITSIO --with-cfitsiolib=DIR directory containing cfitsio library --with-cfitsioinc=DIR directory containing cfitsio header files --without-pgplot eschew PGPLOT --with-pgplotlib=DIR directory containing pgplot library --with-pgplotinc=DIR directory containing pgplot header files --with-x use the X Window System Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor F77 Fortran 77 compiler command FFLAGS Fortran 77 compiler flags XMKMF Path to xmkmf, Makefile generator for X Window System Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF WCSLIB configure 7.7 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_find_intX_t LINENO BITS VAR # ----------------------------------- # Finds a signed integer type with width BITS, setting cache variable VAR # accordingly. ac_fn_c_find_intX_t () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5 $as_echo_n "checking for int$2_t... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" # Order is important - never check a type that is potentially smaller # than half of the expected target width. for ac_type in int$2_t 'int' 'long int' \ 'long long int' 'short int' 'signed char'; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default enum { N = $2 / 2 - 1 }; int main () { static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default enum { N = $2 / 2 - 1 }; int main () { static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1) < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else case $ac_type in #( int$2_t) : eval "$3=yes" ;; #( *) : eval "$3=\$ac_type" ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if eval test \"x\$"$3"\" = x"no"; then : else break fi done fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_find_intX_t # ac_fn_c_find_uintX_t LINENO BITS VAR # ------------------------------------ # Finds an unsigned integer type with width BITS, setting cache variable VAR # accordingly. ac_fn_c_find_uintX_t () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5 $as_echo_n "checking for uint$2_t... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" # Order is important - never check a type that is potentially smaller # than half of the expected target width. for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \ 'unsigned long long int' 'unsigned short int' 'unsigned char'; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : case $ac_type in #( uint$2_t) : eval "$3=yes" ;; #( *) : eval "$3=\$ac_type" ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if eval test \"x\$"$3"\" = x"no"; then : else break fi done fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_find_uintX_t # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## ------------------------------------ ## ## Report this to mark@calabretta.id.au ## ## ------------------------------------ ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES # -------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes # INCLUDES, setting VAR accordingly. Returns whether the value could be # computed ac_fn_c_compute_int () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=0 ac_mid=0 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid; break else as_fn_arith $ac_mid + 1 && ac_lo=$as_val if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) < 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=-1 ac_mid=-1 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=$ac_mid; break else as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid else as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in #(( ?*) eval "$3=\$ac_lo"; ac_retval=0 ;; '') ac_retval=1 ;; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 static long int longval () { return $2; } static unsigned long int ulongval () { return $2; } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (($2) < 0) { long int i = longval (); if (i != ($2)) return 1; fprintf (f, "%ld", i); } else { unsigned long int i = ulongval (); if (i != ($2)) return 1; fprintf (f, "%lu", i); } /* Do not output a trailing newline, as this causes \r\n confusion on some platforms. */ return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : echo >>conftest.val; read $3 &5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_f77_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_f77_try_compile cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by WCSLIB $as_me 7.7, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat >>confdefs.h <<_ACEOF #define WCSLIB_VERSION $PACKAGE_VERSION _ACEOF # Library version number, same as package version. LIBVER="$PACKAGE_VERSION" ac_aux_dir= for ac_dir in config "$srcdir"/config; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in config \"$srcdir\"/config" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Get the system type. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac ARCH="${host_cpu}-$host_os" # Look for Flex. # Check whether --enable-flex was given. if test "${enable_flex+set}" = set; then : enableval=$enable_flex; fi if test "x$enable_flex" = xno ; then FLEX= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Generation of flex sources disabled by request, using pre-generated sources." >&5 $as_echo "$as_me: WARNING: Generation of flex sources disabled by request, using pre-generated sources." >&2;} else # Extract the first word of "flex", so it can be a program name with args. set dummy flex; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_FLEX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$FLEX"; then ac_cv_prog_FLEX="$FLEX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_FLEX="flex" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi FLEX=$ac_cv_prog_FLEX if test -n "$FLEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FLEX" >&5 $as_echo "$FLEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$FLEX" = xflex ; then # Version 2.6.0 or later is required. V=`flex --version | awk '{print $2}'` W=`echo $V | awk -F. '{if ((($1*100 + $2)*100 + $3) < 20600) print "no"}'` if test "x$W" != x ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Flex version $V is too old, ignored." >&5 $as_echo "$as_me: WARNING: Flex version $V is too old, ignored." >&2;} FLEX= else { $as_echo "$as_me:${as_lineno-$LINENO}: Using Flex version $V." >&5 $as_echo "$as_me: Using Flex version $V." >&6;} fi fi if test "x$FLEX" = x ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Flex version 2.6.0 or later does not appear to be available, will use pre-generated sources." >&5 $as_echo "$as_me: WARNING: Flex version 2.6.0 or later does not appear to be available, will use pre-generated sources." >&2;} fi fi # Look for an ANSI C compiler. ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu case $ac_cv_prog_cc_stdc in #( no) : ac_cv_prog_cc_c99=no; ac_cv_prog_cc_c89=no ;; #( *) : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5 $as_echo_n "checking for $CC option to accept ISO C99... " >&6; } if ${ac_cv_prog_cc_c99+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include #include // Check varargs macros. These examples are taken from C99 6.10.3.5. #define debug(...) fprintf (stderr, __VA_ARGS__) #define showlist(...) puts (#__VA_ARGS__) #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) static void test_varargs_macros (void) { int x = 1234; int y = 5678; debug ("Flag"); debug ("X = %d\n", x); showlist (The first, second, and third items.); report (x>y, "x is %d but y is %d", x, y); } // Check long long types. #define BIG64 18446744073709551615ull #define BIG32 4294967295ul #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) #if !BIG_OK your preprocessor is broken; #endif #if BIG_OK #else your preprocessor is broken; #endif static long long int bignum = -9223372036854775807LL; static unsigned long long int ubignum = BIG64; struct incomplete_array { int datasize; double data[]; }; struct named_init { int number; const wchar_t *name; double average; }; typedef const char *ccp; static inline int test_restrict (ccp restrict text) { // See if C++-style comments work. // Iterate through items via the restricted pointer. // Also check for declarations in for loops. for (unsigned int i = 0; *(text+i) != '\0'; ++i) continue; return 0; } // Check varargs and va_copy. static void test_varargs (const char *format, ...) { va_list args; va_start (args, format); va_list args_copy; va_copy (args_copy, args); const char *str; int number; float fnumber; while (*format) { switch (*format++) { case 's': // string str = va_arg (args_copy, const char *); break; case 'd': // int number = va_arg (args_copy, int); break; case 'f': // float fnumber = va_arg (args_copy, double); break; default: break; } } va_end (args_copy); va_end (args); } int main () { // Check bool. _Bool success = false; // Check restrict. if (test_restrict ("String literal") == 0) success = true; char *restrict newvar = "Another string"; // Check varargs. test_varargs ("s, d' f .", "string", 65, 34.234); test_varargs_macros (); // Check flexible array members. struct incomplete_array *ia = malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); ia->datasize = 10; for (int i = 0; i < ia->datasize; ++i) ia->data[i] = i * 1.234; // Check named initializers. struct named_init ni = { .number = 34, .name = L"Test wide string", .average = 543.34343, }; ni.number = 58; int dynamic_array[ni.number]; dynamic_array[ni.number - 1] = 543; // work around unused variable warnings return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x' || dynamic_array[ni.number - 1] != 543); ; return 0; } _ACEOF for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c99" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c99" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 $as_echo "$ac_cv_prog_cc_c99" >&6; } ;; esac if test "x$ac_cv_prog_cc_c99" != xno; then : ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 else ac_cv_prog_cc_stdc=no fi fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO Standard C" >&5 $as_echo_n "checking for $CC option to accept ISO Standard C... " >&6; } if ${ac_cv_prog_cc_stdc+:} false; then : $as_echo_n "(cached) " >&6 fi case $ac_cv_prog_cc_stdc in #( no) : { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; #( '') : { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; #( *) : { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_stdc" >&5 $as_echo "$ac_cv_prog_cc_stdc" >&6; } ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __cplusplus /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this sort of thing. */ char tx; char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi if test "x$ac_cv_prog_cc_stdc" = xno -o \ "x$ac_cv_c_const" = xno -o \ "x$ac_cv_type_size_t" = xno; then as_fn_error 1 " ------------------------------------------------------- An ANSI standard C library is required to build WCSLIB. ERROR: WCSLIB configuration failure. -------------------------------------------------------" "$LINENO" 5 fi # Check for data types (suggested by autoscan - off_t is only required by # fitshdr). ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default" if test "x$ac_cv_type_off_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define off_t long int _ACEOF fi ac_fn_c_find_intX_t "$LINENO" "8" "ac_cv_c_int8_t" case $ac_cv_c_int8_t in #( no|yes) ;; #( *) cat >>confdefs.h <<_ACEOF #define int8_t $ac_cv_c_int8_t _ACEOF ;; esac ac_fn_c_find_intX_t "$LINENO" "16" "ac_cv_c_int16_t" case $ac_cv_c_int16_t in #( no|yes) ;; #( *) cat >>confdefs.h <<_ACEOF #define int16_t $ac_cv_c_int16_t _ACEOF ;; esac ac_fn_c_find_intX_t "$LINENO" "32" "ac_cv_c_int32_t" case $ac_cv_c_int32_t in #( no|yes) ;; #( *) cat >>confdefs.h <<_ACEOF #define int32_t $ac_cv_c_int32_t _ACEOF ;; esac ac_fn_c_find_uintX_t "$LINENO" "8" "ac_cv_c_uint8_t" case $ac_cv_c_uint8_t in #( no|yes) ;; #( *) $as_echo "#define _UINT8_T 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define uint8_t $ac_cv_c_uint8_t _ACEOF ;; esac ac_fn_c_find_uintX_t "$LINENO" "16" "ac_cv_c_uint16_t" case $ac_cv_c_uint16_t in #( no|yes) ;; #( *) cat >>confdefs.h <<_ACEOF #define uint16_t $ac_cv_c_uint16_t _ACEOF ;; esac ac_fn_c_find_uintX_t "$LINENO" "32" "ac_cv_c_uint32_t" case $ac_cv_c_uint32_t in #( no|yes) ;; #( *) $as_echo "#define _UINT32_T 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define uint32_t $ac_cv_c_uint32_t _ACEOF ;; esac # Check for ANSI C headers. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi for ac_header in ctype.h errno.h limits.h locale.h math.h setjmp.h stdarg.h \ stdio.h stdlib.h string.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done if test "x$ac_cv_header_stdc" = xno; then as_fn_error 1 " ------------------------------------------------------------------- An ANSI standard C library is required to build WCSLIB. One of the ANSI C header files it requires is missing or unusable. ERROR: WCSLIB configuration failure. -------------------------------------------------------------------" "$LINENO" 5 fi # Flex uses fileno() and other POSIX features whose prototypes are only # available from glibc's stdio.h with an appropriate preprocessor macro # definition. This cannot be set within the flex description file itself # as stdio.h is included in the generated C code before any part of the # description. See fileno(3) and feature_test_macros(7). if test "x$ac_cv_c_compiler_gnu" = xyes ; then FLFLAGS="$FLFLAGS -D_POSIX_C_SOURCE=1" fi # Checks for ANSI C library functions (suggested by autoscan - fseeko and # stat are only required by fitshdr). { $as_echo "$as_me:${as_lineno-$LINENO}: checking for floor in -lm" >&5 $as_echo_n "checking for floor in -lm... " >&6; } if ${ac_cv_lib_m_floor+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char floor (); int main () { return floor (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_floor=yes else ac_cv_lib_m_floor=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_floor" >&5 $as_echo "$ac_cv_lib_m_floor" >&6; } if test "x$ac_cv_lib_m_floor" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5 $as_echo_n "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; } if ${ac_cv_sys_largefile_source+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* for off_t */ #include int main () { int (*fp) (FILE *, off_t, int) = fseeko; return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_sys_largefile_source=no; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _LARGEFILE_SOURCE 1 #include /* for off_t */ #include int main () { int (*fp) (FILE *, off_t, int) = fseeko; return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_sys_largefile_source=1; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_cv_sys_largefile_source=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_source" >&5 $as_echo "$ac_cv_sys_largefile_source" >&6; } case $ac_cv_sys_largefile_source in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source _ACEOF ;; esac rm -rf conftest* # We used to try defining _XOPEN_SOURCE=500 too, to work around a bug # in glibc 2.1.3, but that breaks too many other things. # If you want fseeko and ftello with glibc, upgrade to a fixed glibc. if test $ac_cv_sys_largefile_source != unknown; then $as_echo "#define HAVE_FSEEKO 1" >>confdefs.h fi for ac_header in stdlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" if test "x$ac_cv_header_stdlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDLIB_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5 $as_echo_n "checking for GNU libc compatible malloc... " >&6; } if ${ac_cv_func_malloc_0_nonnull+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_malloc_0_nonnull=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if defined STDC_HEADERS || defined HAVE_STDLIB_H # include #else char *malloc (); #endif int main () { return ! malloc (0); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_malloc_0_nonnull=yes else ac_cv_func_malloc_0_nonnull=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_malloc_0_nonnull" >&5 $as_echo "$ac_cv_func_malloc_0_nonnull" >&6; } if test $ac_cv_func_malloc_0_nonnull = yes; then : $as_echo "#define HAVE_MALLOC 1" >>confdefs.h else $as_echo "#define HAVE_MALLOC 0" >>confdefs.h case " $LIBOBJS " in *" malloc.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS malloc.$ac_objext" ;; esac $as_echo "#define malloc rpl_malloc" >>confdefs.h fi for ac_header in stdlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" if test "x$ac_cv_header_stdlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDLIB_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible realloc" >&5 $as_echo_n "checking for GNU libc compatible realloc... " >&6; } if ${ac_cv_func_realloc_0_nonnull+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_realloc_0_nonnull=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if defined STDC_HEADERS || defined HAVE_STDLIB_H # include #else char *realloc (); #endif int main () { return ! realloc (0, 0); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_realloc_0_nonnull=yes else ac_cv_func_realloc_0_nonnull=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_realloc_0_nonnull" >&5 $as_echo "$ac_cv_func_realloc_0_nonnull" >&6; } if test $ac_cv_func_realloc_0_nonnull = yes; then : $as_echo "#define HAVE_REALLOC 1" >>confdefs.h else $as_echo "#define HAVE_REALLOC 0" >>confdefs.h case " $LIBOBJS " in *" realloc.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS realloc.$ac_objext" ;; esac $as_echo "#define realloc rpl_realloc" >>confdefs.h fi if ${ac_cv_func_setvbuf_reversed+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_func_setvbuf_reversed=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether lstat correctly handles trailing slash" >&5 $as_echo_n "checking whether lstat correctly handles trailing slash... " >&6; } if ${ac_cv_func_lstat_dereferences_slashed_symlink+:} false; then : $as_echo_n "(cached) " >&6 else rm -f conftest.sym conftest.file echo >conftest.file if test "$as_ln_s" = "ln -s" && ln -s conftest.file conftest.sym; then if test "$cross_compiling" = yes; then : ac_cv_func_lstat_dereferences_slashed_symlink=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { struct stat sbuf; /* Linux will dereference the symlink and fail, as required by POSIX. That is better in the sense that it means we will not have to compile and use the lstat wrapper. */ return lstat ("conftest.sym/", &sbuf) == 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_lstat_dereferences_slashed_symlink=yes else ac_cv_func_lstat_dereferences_slashed_symlink=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # If the `ln -s' command failed, then we probably don't even # have an lstat function. ac_cv_func_lstat_dereferences_slashed_symlink=no fi rm -f conftest.sym conftest.file fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_lstat_dereferences_slashed_symlink" >&5 $as_echo "$ac_cv_func_lstat_dereferences_slashed_symlink" >&6; } test $ac_cv_func_lstat_dereferences_slashed_symlink = yes && cat >>confdefs.h <<_ACEOF #define LSTAT_FOLLOWS_SLASHED_SYMLINK 1 _ACEOF if test "x$ac_cv_func_lstat_dereferences_slashed_symlink" = xno; then case " $LIBOBJS " in *" lstat.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS lstat.$ac_objext" ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stat accepts an empty string" >&5 $as_echo_n "checking whether stat accepts an empty string... " >&6; } if ${ac_cv_func_stat_empty_string_bug+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_stat_empty_string_bug=yes else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { struct stat sbuf; return stat ("", &sbuf) == 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_stat_empty_string_bug=no else ac_cv_func_stat_empty_string_bug=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_stat_empty_string_bug" >&5 $as_echo "$ac_cv_func_stat_empty_string_bug" >&6; } if test $ac_cv_func_stat_empty_string_bug = yes; then case " $LIBOBJS " in *" stat.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS stat.$ac_objext" ;; esac cat >>confdefs.h <<_ACEOF #define HAVE_STAT_EMPTY_STRING_BUG 1 _ACEOF fi for ac_func in vprintf do : ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf" if test "x$ac_cv_func_vprintf" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_VPRINTF 1 _ACEOF ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt" if test "x$ac_cv_func__doprnt" = xyes; then : $as_echo "#define HAVE_DOPRNT 1" >>confdefs.h fi fi done for ac_func in floor memset pow setlocale sqrt strchr strstr do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done # System libraries that may be required by WCSLIB itself. # SunOS, extra maths functions. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cosd in -lsunmath" >&5 $as_echo_n "checking for cosd in -lsunmath... " >&6; } if ${ac_cv_lib_sunmath_cosd+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsunmath $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char cosd (); int main () { return cosd (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_sunmath_cosd=yes else ac_cv_lib_sunmath_cosd=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sunmath_cosd" >&5 $as_echo "$ac_cv_lib_sunmath_cosd" >&6; } if test "x$ac_cv_lib_sunmath_cosd" = xyes; then : LIBS="-lsunmath $LIBS" fi # See if we can find sincos(). for ac_func in sincos do : ac_fn_c_check_func "$LINENO" "sincos" "ac_cv_func_sincos" if test "x$ac_cv_func_sincos" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SINCOS 1 _ACEOF fi done # Check the size and availability of integer data types. # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 $as_echo_n "checking size of int... " >&6; } if ${ac_cv_sizeof_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then : else if test "$ac_cv_type_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 $as_echo "$ac_cv_sizeof_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_INT $ac_cv_sizeof_int _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long int" >&5 $as_echo_n "checking size of long int... " >&6; } if ${ac_cv_sizeof_long_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long int))" "ac_cv_sizeof_long_int" "$ac_includes_default"; then : else if test "$ac_cv_type_long_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_long_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_int" >&5 $as_echo "$ac_cv_sizeof_long_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG_INT $ac_cv_sizeof_long_int _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long int" >&5 $as_echo_n "checking size of long long int... " >&6; } if ${ac_cv_sizeof_long_long_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long int))" "ac_cv_sizeof_long_long_int" "$ac_includes_default"; then : else if test "$ac_cv_type_long_long_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long long int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_long_long_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long_int" >&5 $as_echo "$ac_cv_sizeof_long_long_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG_LONG_INT $ac_cv_sizeof_long_long_int _ACEOF # 64-bit integer data type; use long long int preferentially since that # accords with "%lld" formatting used in fitshdr.l, e.g. # int size_t long int long long int # --- ------ -------- ------------- # gcc x86: 32 32 32 64 # gcc x86_64: 32 64 64 64 if test "x$ac_cv_sizeof_long_long_int" = x8; then $as_echo "#define WCSLIB_INT64 long long int" >>confdefs.h elif test "x$ac_cv_sizeof_long_int" = x8; then $as_echo "#define WCSLIB_INT64 long int" >>confdefs.h elif test "x$ac_cv_sizeof_int" = x8; then $as_echo "#define WCSLIB_INT64 int" >>confdefs.h fi # Does printf() have the z modifier for size_t type? Important for 64-bit. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for printf z format modifier for size_t type" >&5 $as_echo_n "checking for printf z format modifier for size_t type... " >&6; } if test "$cross_compiling" = yes; then : $as_echo "#define MODZ \"\"" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: assumed not" >&5 $as_echo "assumed not" >&6; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { char buf[64]; if (sprintf(buf, "%zu", (size_t)1) != 1) return 1; else if (strcmp(buf, "1")) return 2; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : $as_echo "#define MODZ \"z\"" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else $as_echo "#define MODZ \"\"" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi # Starting values, may be augmented later. SUBDIRS="C" TSTDIRS="C" INSTDIR="C" # Ways of specifying the Fortran compiler, in order of precedence: # configure --enable-fortran= # F77= configure ...bash # # Ways of disabling Fortran: # configure --disable-fortran # configure --enable-fortran=no # F77=no configure ...bash # Check whether --enable-fortran was given. if test "${enable_fortran+set}" = set; then : enableval=$enable_fortran; fi # Check whether --enable-fortran was given. if test "${enable_fortran+set}" = set; then : enableval=$enable_fortran; fi if test "x$enable_fortran" != x -a "x$enable_fortran" != xyes ; then F77="$enable_fortran" fi if test "x$F77" = xno ; then F77= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Compilation of Fortran wrappers and PGSBOX disabled." >&5 $as_echo "$as_me: WARNING: Compilation of Fortran wrappers and PGSBOX disabled." >&2;} else if test "x$F77" = x ; then # Look for a Fortran compiler. ac_ext=f ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_f77_compiler_gnu if test -n "$ac_tool_prefix"; then for ac_prog in gfortran g77 f77 ifort xlf frt pgf77 fl32 af77 fort77 f90 \ xlf90 pgf90 epcf90 f95 fort xlf95 lf95 g95 do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_F77+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$F77"; then ac_cv_prog_F77="$F77" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_F77="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi F77=$ac_cv_prog_F77 if test -n "$F77"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $F77" >&5 $as_echo "$F77" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$F77" && break done fi if test -z "$F77"; then ac_ct_F77=$F77 for ac_prog in gfortran g77 f77 ifort xlf frt pgf77 fl32 af77 fort77 f90 \ xlf90 pgf90 epcf90 f95 fort xlf95 lf95 g95 do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_F77+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_F77"; then ac_cv_prog_ac_ct_F77="$ac_ct_F77" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_F77="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_F77=$ac_cv_prog_ac_ct_F77 if test -n "$ac_ct_F77"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_F77" >&5 $as_echo "$ac_ct_F77" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_F77" && break done if test "x$ac_ct_F77" = x; then F77="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac F77=$ac_ct_F77 fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran 77 compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done rm -f a.out # If we don't use `.F' as extension, the preprocessor is not run on the # input file. (Note that this only needs to work for GNU compilers.) ac_save_ext=$ac_ext ac_ext=F { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU Fortran 77 compiler" >&5 $as_echo_n "checking whether we are using the GNU Fortran 77 compiler... " >&6; } if ${ac_cv_f77_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat > conftest.$ac_ext <<_ACEOF program main #ifndef __GNUC__ choke me #endif end _ACEOF if ac_fn_f77_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_f77_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_f77_compiler_gnu" >&5 $as_echo "$ac_cv_f77_compiler_gnu" >&6; } ac_ext=$ac_save_ext ac_test_FFLAGS=${FFLAGS+set} ac_save_FFLAGS=$FFLAGS FFLAGS= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $F77 accepts -g" >&5 $as_echo_n "checking whether $F77 accepts -g... " >&6; } if ${ac_cv_prog_f77_g+:} false; then : $as_echo_n "(cached) " >&6 else FFLAGS=-g cat > conftest.$ac_ext <<_ACEOF program main end _ACEOF if ac_fn_f77_try_compile "$LINENO"; then : ac_cv_prog_f77_g=yes else ac_cv_prog_f77_g=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_f77_g" >&5 $as_echo "$ac_cv_prog_f77_g" >&6; } if test "$ac_test_FFLAGS" = set; then FFLAGS=$ac_save_FFLAGS elif test $ac_cv_prog_f77_g = yes; then if test "x$ac_cv_f77_compiler_gnu" = xyes; then FFLAGS="-g -O2" else FFLAGS="-g" fi else if test "x$ac_cv_f77_compiler_gnu" = xyes; then FFLAGS="-O2" else FFLAGS= fi fi if test $ac_compiler_gnu = yes; then G77=yes else G77= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi if test "x$F77" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ------------------------------------------------------------------ Fortran compiler not found, will skip Fortran wrappers and PGSBOX. ------------------------------------------------------------------" >&5 $as_echo "$as_me: WARNING: ------------------------------------------------------------------ Fortran compiler not found, will skip Fortran wrappers and PGSBOX. ------------------------------------------------------------------" >&2;} # Best guess at Fortran name mangling for use if a compiler does ever # become available. $as_echo "#define F77_FUNC(name,NAME) name ## _" >>confdefs.h else if test "x$ac_cv_f77_compiler_gnu" = xyes ; then if test "x$F77" = xg77 -o "x$F77" = xf77 ; then # Not recognized by gfortran. FFLAGS="$FFLAGS -Wno-globals" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $F77 accepts -I" >&5 $as_echo_n "checking whether $F77 accepts -I... " >&6; } ac_ext=f ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_f77_compiler_gnu FFLAGS_save=$FFLAGS FFLAGS=-I. cat > conftest.$ac_ext <<_ACEOF program main end _ACEOF if ac_fn_f77_try_compile "$LINENO"; then : FFLAGS="$FFLAGS_save -I."; { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else FFLAGS="$FFLAGS_save"; { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Libraries required by the Fortran compiler itself (sets FLIBS). # Required by utilities and test programs written in C that link to # Fortran object modules such as pgsbox. ac_ext=f ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_f77_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to get verbose linking output from $F77" >&5 $as_echo_n "checking how to get verbose linking output from $F77... " >&6; } if ${ac_cv_prog_f77_v+:} false; then : $as_echo_n "(cached) " >&6 else cat > conftest.$ac_ext <<_ACEOF program main end _ACEOF if ac_fn_f77_try_compile "$LINENO"; then : ac_cv_prog_f77_v= # Try some options frequently used verbose output for ac_verb in -v -verbose --verbose -V -\#\#\#; do cat > conftest.$ac_ext <<_ACEOF program main end _ACEOF # Compile and link our simple test program by passing a flag (argument # 1 to this macro) to the Fortran compiler in order to get # "verbose" output that we can then parse for the Fortran linker # flags. ac_save_FFLAGS=$FFLAGS FFLAGS="$FFLAGS $ac_verb" eval "set x $ac_link" shift $as_echo "$as_me:${as_lineno-$LINENO}: $*" >&5 # gfortran 4.3 outputs lines setting COLLECT_GCC_OPTIONS, COMPILER_PATH, # LIBRARY_PATH; skip all such settings. ac_f77_v_output=`eval $ac_link 5>&1 2>&1 | sed '/^Driving:/d; /^Configured with:/d; '"/^[_$as_cr_Letters][_$as_cr_alnum]*=/d"` $as_echo "$ac_f77_v_output" >&5 FFLAGS=$ac_save_FFLAGS rm -rf conftest* # On HP/UX there is a line like: "LPATH is: /foo:/bar:/baz" where # /foo, /bar, and /baz are search directories for the Fortran linker. # Here, we change these into -L/foo -L/bar -L/baz (and put it first): ac_f77_v_output="`echo $ac_f77_v_output | grep 'LPATH is:' | sed 's|.*LPATH is\(: *[^ ]*\).*|\1|;s|: */| -L/|g'` $ac_f77_v_output" # FIXME: we keep getting bitten by quoted arguments; a more general fix # that detects unbalanced quotes in FLIBS should be implemented # and (ugh) tested at some point. case $ac_f77_v_output in # With xlf replace commas with spaces, # and remove "-link" and closing parenthesis. *xlfentry*) ac_f77_v_output=`echo $ac_f77_v_output | sed ' s/,/ /g s/ -link / /g s/) *$// ' ` ;; # With Intel ifc, ignore the quoted -mGLOB_options_string stuff (quoted # $LIBS confuse us, and the libraries appear later in the output anyway). *mGLOB_options_string*) ac_f77_v_output=`echo $ac_f77_v_output | sed 's/"-mGLOB[^"]*"/ /g'` ;; # Portland Group compiler has singly- or doubly-quoted -cmdline argument # Singly-quoted arguments were reported for versions 5.2-4 and 6.0-4. # Doubly-quoted arguments were reported for "PGF90/x86 Linux/x86 5.0-2". *-cmdline\ * | *-ignore\ * | *-def\ *) ac_f77_v_output=`echo $ac_f77_v_output | sed "\ s/-cmdline *'[^']*'/ /g; s/-cmdline *\"[^\"]*\"/ /g s/-ignore *'[^']*'/ /g; s/-ignore *\"[^\"]*\"/ /g s/-def *'[^']*'/ /g; s/-def *\"[^\"]*\"/ /g"` ;; # If we are using fort77 (the f2c wrapper) then filter output and delete quotes. *fort77*f2c*gcc*) ac_f77_v_output=`echo "$ac_f77_v_output" | sed -n ' /:[ ]\+Running[ ]\{1,\}"gcc"/{ /"-c"/d /[.]c"*/d s/^.*"gcc"/"gcc"/ s/"//gp }'` ;; # If we are using Cray Fortran then delete quotes. *cft90*) ac_f77_v_output=`echo $ac_f77_v_output | sed 's/"//g'` ;; esac # look for -l* and *.a constructs in the output for ac_arg in $ac_f77_v_output; do case $ac_arg in [\\/]*.a | ?:[\\/]*.a | -[lLRu]*) ac_cv_prog_f77_v=$ac_verb break 2 ;; esac done done if test -z "$ac_cv_prog_f77_v"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot determine how to obtain linking information from $F77" >&5 $as_echo "$as_me: WARNING: cannot determine how to obtain linking information from $F77" >&2;} fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: compilation failed" >&5 $as_echo "$as_me: WARNING: compilation failed" >&2;} fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_f77_v" >&5 $as_echo "$ac_cv_prog_f77_v" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran 77 libraries of $F77" >&5 $as_echo_n "checking for Fortran 77 libraries of $F77... " >&6; } if ${ac_cv_f77_libs+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$FLIBS" != "x"; then ac_cv_f77_libs="$FLIBS" # Let the user override the test. else cat > conftest.$ac_ext <<_ACEOF program main end _ACEOF # Compile and link our simple test program by passing a flag (argument # 1 to this macro) to the Fortran compiler in order to get # "verbose" output that we can then parse for the Fortran linker # flags. ac_save_FFLAGS=$FFLAGS FFLAGS="$FFLAGS $ac_cv_prog_f77_v" eval "set x $ac_link" shift $as_echo "$as_me:${as_lineno-$LINENO}: $*" >&5 # gfortran 4.3 outputs lines setting COLLECT_GCC_OPTIONS, COMPILER_PATH, # LIBRARY_PATH; skip all such settings. ac_f77_v_output=`eval $ac_link 5>&1 2>&1 | sed '/^Driving:/d; /^Configured with:/d; '"/^[_$as_cr_Letters][_$as_cr_alnum]*=/d"` $as_echo "$ac_f77_v_output" >&5 FFLAGS=$ac_save_FFLAGS rm -rf conftest* # On HP/UX there is a line like: "LPATH is: /foo:/bar:/baz" where # /foo, /bar, and /baz are search directories for the Fortran linker. # Here, we change these into -L/foo -L/bar -L/baz (and put it first): ac_f77_v_output="`echo $ac_f77_v_output | grep 'LPATH is:' | sed 's|.*LPATH is\(: *[^ ]*\).*|\1|;s|: */| -L/|g'` $ac_f77_v_output" # FIXME: we keep getting bitten by quoted arguments; a more general fix # that detects unbalanced quotes in FLIBS should be implemented # and (ugh) tested at some point. case $ac_f77_v_output in # With xlf replace commas with spaces, # and remove "-link" and closing parenthesis. *xlfentry*) ac_f77_v_output=`echo $ac_f77_v_output | sed ' s/,/ /g s/ -link / /g s/) *$// ' ` ;; # With Intel ifc, ignore the quoted -mGLOB_options_string stuff (quoted # $LIBS confuse us, and the libraries appear later in the output anyway). *mGLOB_options_string*) ac_f77_v_output=`echo $ac_f77_v_output | sed 's/"-mGLOB[^"]*"/ /g'` ;; # Portland Group compiler has singly- or doubly-quoted -cmdline argument # Singly-quoted arguments were reported for versions 5.2-4 and 6.0-4. # Doubly-quoted arguments were reported for "PGF90/x86 Linux/x86 5.0-2". *-cmdline\ * | *-ignore\ * | *-def\ *) ac_f77_v_output=`echo $ac_f77_v_output | sed "\ s/-cmdline *'[^']*'/ /g; s/-cmdline *\"[^\"]*\"/ /g s/-ignore *'[^']*'/ /g; s/-ignore *\"[^\"]*\"/ /g s/-def *'[^']*'/ /g; s/-def *\"[^\"]*\"/ /g"` ;; # If we are using fort77 (the f2c wrapper) then filter output and delete quotes. *fort77*f2c*gcc*) ac_f77_v_output=`echo "$ac_f77_v_output" | sed -n ' /:[ ]\+Running[ ]\{1,\}"gcc"/{ /"-c"/d /[.]c"*/d s/^.*"gcc"/"gcc"/ s/"//gp }'` ;; # If we are using Cray Fortran then delete quotes. *cft90*) ac_f77_v_output=`echo $ac_f77_v_output | sed 's/"//g'` ;; esac ac_cv_f77_libs= # Save positional arguments (if any) ac_save_positional="$@" set X $ac_f77_v_output while test $# != 1; do shift ac_arg=$1 case $ac_arg in [\\/]*.a | ?:[\\/]*.a) ac_exists=false for ac_i in $ac_cv_f77_libs; do if test x"$ac_arg" = x"$ac_i"; then ac_exists=true break fi done if test x"$ac_exists" = xtrue; then : else ac_cv_f77_libs="$ac_cv_f77_libs $ac_arg" fi ;; -bI:*) ac_exists=false for ac_i in $ac_cv_f77_libs; do if test x"$ac_arg" = x"$ac_i"; then ac_exists=true break fi done if test x"$ac_exists" = xtrue; then : else if test "$ac_compiler_gnu" = yes; then for ac_link_opt in $ac_arg; do ac_cv_f77_libs="$ac_cv_f77_libs -Xlinker $ac_link_opt" done else ac_cv_f77_libs="$ac_cv_f77_libs $ac_arg" fi fi ;; # Ignore these flags. -lang* | -lcrt*.o | -lc | -lgcc* | -lSystem | -libmil | -little \ |-LANG:=* | -LIST:* | -LNO:* | -link) ;; -lkernel32) case $host_os in *cygwin*) ;; *) ac_cv_f77_libs="$ac_cv_f77_libs $ac_arg" ;; esac ;; -[LRuYz]) # These flags, when seen by themselves, take an argument. # We remove the space between option and argument and re-iterate # unless we find an empty arg or a new option (starting with -) case $2 in "" | -*);; *) ac_arg="$ac_arg$2" shift; shift set X $ac_arg "$@" ;; esac ;; -YP,*) for ac_j in `$as_echo "$ac_arg" | sed -e 's/-YP,/-L/;s/:/ -L/g'`; do ac_exists=false for ac_i in $ac_cv_f77_libs; do if test x"$ac_j" = x"$ac_i"; then ac_exists=true break fi done if test x"$ac_exists" = xtrue; then : else ac_arg="$ac_arg $ac_j" ac_cv_f77_libs="$ac_cv_f77_libs $ac_j" fi done ;; -[lLR]*) ac_exists=false for ac_i in $ac_cv_f77_libs; do if test x"$ac_arg" = x"$ac_i"; then ac_exists=true break fi done if test x"$ac_exists" = xtrue; then : else ac_cv_f77_libs="$ac_cv_f77_libs $ac_arg" fi ;; -zallextract*| -zdefaultextract) ac_cv_f77_libs="$ac_cv_f77_libs $ac_arg" ;; # Ignore everything else. esac done # restore positional arguments set X $ac_save_positional; shift # We only consider "LD_RUN_PATH" on Solaris systems. If this is seen, # then we insist that the "run path" must be an absolute path (i.e. it # must begin with a "/"). case `(uname -sr) 2>/dev/null` in "SunOS 5"*) ac_ld_run_path=`$as_echo "$ac_f77_v_output" | sed -n 's,^.*LD_RUN_PATH *= *\(/[^ ]*\).*$,-R\1,p'` test "x$ac_ld_run_path" != x && if test "$ac_compiler_gnu" = yes; then for ac_link_opt in $ac_ld_run_path; do ac_cv_f77_libs="$ac_cv_f77_libs -Xlinker $ac_link_opt" done else ac_cv_f77_libs="$ac_cv_f77_libs $ac_ld_run_path" fi ;; esac fi # test "x$[]_AC_LANG_PREFIX[]LIBS" = "x" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_f77_libs" >&5 $as_echo "$ac_cv_f77_libs" >&6; } FLIBS="$ac_cv_f77_libs" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Tidy up FLIBS. dirs= libs= for flib in $FLIBS do case "$flib" in -L*) dir=`echo "$flib" | sed -e 's/-L//'` dir=-L`cd "$dir" && pwd` dirs="$dirs $dir" ;; *) libs="$libs $flib" ;; esac done dirs=`for dir in $dirs ; do echo "$dir" ; done | sort -u | xargs` FLIBS="$dirs$libs" # F77 name mangling (defines the F77_FUNC preprocessor macro). ac_ext=f ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_f77_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dummy main to link with Fortran 77 libraries" >&5 $as_echo_n "checking for dummy main to link with Fortran 77 libraries... " >&6; } if ${ac_cv_f77_dummy_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_f77_dm_save_LIBS=$LIBS LIBS="$LIBS $FLIBS" ac_fortran_dm_var=F77_DUMMY_MAIN ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # First, try linking without a dummy main: cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_fortran_dummy_main=none else ac_cv_fortran_dummy_main=unknown fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test $ac_cv_fortran_dummy_main = unknown; then for ac_func in MAIN__ MAIN_ __main MAIN _MAIN __MAIN main_ main__ _main; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define $ac_fortran_dm_var $ac_func #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_fortran_dummy_main=$ac_func; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done fi ac_ext=f ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_f77_compiler_gnu ac_cv_f77_dummy_main=$ac_cv_fortran_dummy_main rm -rf conftest* LIBS=$ac_f77_dm_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_f77_dummy_main" >&5 $as_echo "$ac_cv_f77_dummy_main" >&6; } F77_DUMMY_MAIN=$ac_cv_f77_dummy_main if test "$F77_DUMMY_MAIN" != unknown; then : if test $F77_DUMMY_MAIN != none; then cat >>confdefs.h <<_ACEOF #define F77_DUMMY_MAIN $F77_DUMMY_MAIN _ACEOF if test "x$ac_cv_fc_dummy_main" = "x$ac_cv_f77_dummy_main"; then $as_echo "#define FC_DUMMY_MAIN_EQ_F77 1" >>confdefs.h fi fi else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "linking to Fortran libraries from C fails See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=f ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_f77_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran 77 name-mangling scheme" >&5 $as_echo_n "checking for Fortran 77 name-mangling scheme... " >&6; } if ${ac_cv_f77_mangling+:} false; then : $as_echo_n "(cached) " >&6 else cat > conftest.$ac_ext <<_ACEOF subroutine foobar() return end subroutine foo_bar() return end _ACEOF if ac_fn_f77_try_compile "$LINENO"; then : mv conftest.$ac_objext cfortran_test.$ac_objext ac_save_LIBS=$LIBS LIBS="cfortran_test.$ac_objext $LIBS $FLIBS" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_success=no for ac_foobar in foobar FOOBAR; do for ac_underscore in "" "_"; do ac_func="$ac_foobar$ac_underscore" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif int main () { return $ac_func (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_success=yes; break 2 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done done ac_ext=f ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_f77_compiler_gnu if test "$ac_success" = "yes"; then case $ac_foobar in foobar) ac_case=lower ac_foo_bar=foo_bar ;; FOOBAR) ac_case=upper ac_foo_bar=FOO_BAR ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_success_extra=no for ac_extra in "" "_"; do ac_func="$ac_foo_bar$ac_underscore$ac_extra" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif int main () { return $ac_func (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_success_extra=yes; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done ac_ext=f ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_f77_compiler_gnu if test "$ac_success_extra" = "yes"; then ac_cv_f77_mangling="$ac_case case" if test -z "$ac_underscore"; then ac_cv_f77_mangling="$ac_cv_f77_mangling, no underscore" else ac_cv_f77_mangling="$ac_cv_f77_mangling, underscore" fi if test -z "$ac_extra"; then ac_cv_f77_mangling="$ac_cv_f77_mangling, no extra underscore" else ac_cv_f77_mangling="$ac_cv_f77_mangling, extra underscore" fi else ac_cv_f77_mangling="unknown" fi else ac_cv_f77_mangling="unknown" fi LIBS=$ac_save_LIBS rm -rf conftest* rm -f cfortran_test* else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compile a simple Fortran program See \`config.log' for more details" "$LINENO" 5; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_f77_mangling" >&5 $as_echo "$ac_cv_f77_mangling" >&6; } ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=f ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_f77_compiler_gnu case $ac_cv_f77_mangling in "lower case, no underscore, no extra underscore") $as_echo "#define F77_FUNC(name,NAME) name" >>confdefs.h $as_echo "#define F77_FUNC_(name,NAME) name" >>confdefs.h ;; "lower case, no underscore, extra underscore") $as_echo "#define F77_FUNC(name,NAME) name" >>confdefs.h $as_echo "#define F77_FUNC_(name,NAME) name ## _" >>confdefs.h ;; "lower case, underscore, no extra underscore") $as_echo "#define F77_FUNC(name,NAME) name ## _" >>confdefs.h $as_echo "#define F77_FUNC_(name,NAME) name ## _" >>confdefs.h ;; "lower case, underscore, extra underscore") $as_echo "#define F77_FUNC(name,NAME) name ## _" >>confdefs.h $as_echo "#define F77_FUNC_(name,NAME) name ## __" >>confdefs.h ;; "upper case, no underscore, no extra underscore") $as_echo "#define F77_FUNC(name,NAME) NAME" >>confdefs.h $as_echo "#define F77_FUNC_(name,NAME) NAME" >>confdefs.h ;; "upper case, no underscore, extra underscore") $as_echo "#define F77_FUNC(name,NAME) NAME" >>confdefs.h $as_echo "#define F77_FUNC_(name,NAME) NAME ## _" >>confdefs.h ;; "upper case, underscore, no extra underscore") $as_echo "#define F77_FUNC(name,NAME) NAME ## _" >>confdefs.h $as_echo "#define F77_FUNC_(name,NAME) NAME ## _" >>confdefs.h ;; "upper case, underscore, extra underscore") $as_echo "#define F77_FUNC(name,NAME) NAME ## _" >>confdefs.h $as_echo "#define F77_FUNC_(name,NAME) NAME ## __" >>confdefs.h ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unknown Fortran name-mangling scheme" >&5 $as_echo "$as_me: WARNING: unknown Fortran name-mangling scheme" >&2;} ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu SUBDIRS="C Fortran" TSTDIRS="C Fortran" INSTDIR="Fortran" fi fi # System-dependent system libraries (for building the sharable library). #----------------------------------------------------------------------- # Darwin (contains stubs for long double). as_ac_Lib=`$as_echo "ac_cv_lib_SystemStubs_printf\\$LDBLStub" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for printf\$LDBLStub in -lSystemStubs" >&5 $as_echo_n "checking for printf\$LDBLStub in -lSystemStubs... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lSystemStubs $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char printf\$LDBLStub (); #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif int main () { return printf\$LDBLStub (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : LIBS="$LIBS -lSystemStubs" fi # Library and installation utilities. #------------------------------------ # Static library generation. # Ensure "non-deterministic" archives are produced during the build process. ar rU conftest.a > /dev/null 2>&1 && ARFLAGS="U" rm -f conftest.a if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi # Shared library generation - gcc only. # Ways of disabling shared libraries: # configure --disable-shared # configure --enable-shared=no # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; fi SHRLIB= SONAME= SHRFLAGS= SHRLD= SHRSFX= SHRLN= if test "x$ac_cv_c_compiler_gnu" = xyes ; then if test "x$enable_shared" = xno ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Generation of WCS shared libraries disabled." >&5 $as_echo "$as_me: WARNING: Generation of WCS shared libraries disabled." >&2;} else SHVER=`echo "$LIBVER" | sed -e 's/\..*$//'` # Note that -fPIC is on by default for Macs, this just makes it obvious. SHRFLAGS="-fPIC" SHRLD="\$(CC) \$(SHRFLAGS)" case "$host_os" in darwin*) SHRLIB="libwcs.$LIBVER.dylib" SONAME="libwcs.$SHVER.dylib" SHRLD="$SHRLD -dynamiclib -single_module" SHRLD="$SHRLD -compatibility_version $SHVER -current_version $LIBVER -install_name \$(SONAME)" SHRLN="libwcs.dylib" case "$host_cpu" in powerpc*) # Switch off -fPIC (not applicable for PowerPC Macs). CFLAGS="$CFLAGS -mdynamic-no-pic" ;; esac ;; *mingw*) SHRLIB="libwcs.dll.$LIBVER" SONAME="libwcs.dll.$SHVER" SHRLD="$SHRLD -shared -Wl,-h\$(SONAME)" SHRLN="libwcs.dll" ;; *) # Covers Linux and Solaris at least. SHRLIB="libwcs.so.$LIBVER" SONAME="libwcs.so.$SHVER" SHRLD="$SHRLD -shared -Wl,-h\$(SONAME)" SHRLN="libwcs.so" ;; esac fi fi # Installation utilities. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' # Older versions of GNU make do not have the -O option, which only facilitates # legibility of the output from parallel builds (make -j). make --help | grep '\-O' >/dev/null 2>&1 && MAKEFLAGS="-Otarget" { $as_echo "$as_me:${as_lineno-$LINENO}: End of primary configuration. " >&5 $as_echo "$as_me: End of primary configuration. " >&6;} # The following are required to build utilities and test programs. # ---------------------------------------------------------------- { $as_echo "$as_me:${as_lineno-$LINENO}: Looking for libraries etc. for utilities and test suite..." >&5 $as_echo "$as_me: Looking for libraries etc. for utilities and test suite..." >&6;} # Check for other quasi-standard header files. for ac_header in unistd.h do : ac_fn_c_check_header_mongrel "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default" if test "x$ac_cv_header_unistd_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UNISTD_H 1 _ACEOF fi done # Large file support. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5 $as_echo_n "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; } if ${ac_cv_sys_largefile_source+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* for off_t */ #include #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif int main () { int (*fp) (FILE *, off_t, int) = fseeko; return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_sys_largefile_source=no; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _LARGEFILE_SOURCE 1 #include /* for off_t */ #include #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif int main () { int (*fp) (FILE *, off_t, int) = fseeko; return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_sys_largefile_source=1; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_cv_sys_largefile_source=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_source" >&5 $as_echo "$ac_cv_sys_largefile_source" >&6; } case $ac_cv_sys_largefile_source in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source _ACEOF ;; esac rm -rf conftest* # We used to try defining _XOPEN_SOURCE=500 too, to work around a bug # in glibc 2.1.3, but that breaks too many other things. # If you want fseeko and ftello with glibc, upgrade to a fixed glibc. if test $ac_cv_sys_largefile_source != unknown; then $as_echo "#define HAVE_FSEEKO 1" >>confdefs.h fi # Check whether --enable-largefile was given. if test "${enable_largefile+set}" = set; then : enableval=$enable_largefile; fi if test "$enable_largefile" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 $as_echo_n "checking for special C compiler options needed for large files... " >&6; } if ${ac_cv_sys_largefile_CC+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_sys_largefile_CC=no if test "$GCC" != yes; then ac_save_CC=$CC while :; do # IRIX 6.2 and later do not support large files by default, # so use the C compiler's -n32 option if that helps. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : break fi rm -f core conftest.err conftest.$ac_objext CC="$CC -n32" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_largefile_CC=' -n32'; break fi rm -f core conftest.err conftest.$ac_objext break done CC=$ac_save_CC rm -f conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 $as_echo "$ac_cv_sys_largefile_CC" >&6; } if test "$ac_cv_sys_largefile_CC" != no; then CC=$CC$ac_cv_sys_largefile_CC fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 $as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } if ${ac_cv_sys_file_offset_bits+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_file_offset_bits=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _FILE_OFFSET_BITS 64 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_file_offset_bits=64; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_file_offset_bits=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 $as_echo "$ac_cv_sys_file_offset_bits" >&6; } case $ac_cv_sys_file_offset_bits in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits _ACEOF ;; esac rm -rf conftest* if test $ac_cv_sys_file_offset_bits = unknown; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 $as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } if ${ac_cv_sys_large_files+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_large_files=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _LARGE_FILES 1 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_large_files=1; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_large_files=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 $as_echo "$ac_cv_sys_large_files" >&6; } case $ac_cv_sys_large_files in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _LARGE_FILES $ac_cv_sys_large_files _ACEOF ;; esac rm -rf conftest* fi fi # Extra places to look for third-party libraries and header files. LIBDIRS= # Check whether --with-cfitsio was given. if test "${with_cfitsio+set}" = set; then : withval=$with_cfitsio; fi if test "x$with_cfitsio" = xno ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: CFITSIO disabled." >&5 $as_echo "$as_me: WARNING: CFITSIO disabled." >&2;} else # Check whether --with-cfitsiolib was given. if test "${with_cfitsiolib+set}" = set; then : withval=$with_cfitsiolib; fi if test "x$with_cfitsiolib" != x ; then LIBDIRS="$LIBDIRS $with_cfitsiolib" fi # Check whether --with-cfitsioinc was given. if test "${with_cfitsioinc+set}" = set; then : withval=$with_cfitsioinc; fi if test "x$with_cfitsioinc" != x ; then CFITSIO_INCDIRS="$with_cfitsioinc" fi CFITSIO_INCDIRS="$CFITSIO_INCDIRS \ /usr/local/cfitsio/include \ /local/cfitsio/include" LIBDIRS="$LIBDIRS \ /usr/local/cfitsio/lib \ /local/cfitsio/lib" fi # Check whether --with-pgplot was given. if test "${with_pgplot+set}" = set; then : withval=$with_pgplot; fi if test "x$with_pgplot" = xno ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: PGPLOT disabled." >&5 $as_echo "$as_me: WARNING: PGPLOT disabled." >&2;} else # Check whether --with-pgplotlib was given. if test "${with_pgplotlib+set}" = set; then : withval=$with_pgplotlib; fi if test "x$with_pgplotlib" != x ; then LIBDIRS="$LIBDIRS $with_pgplotlib" fi # Check whether --with-pgplotinc was given. if test "${with_pgplotinc+set}" = set; then : withval=$with_pgplotinc; fi if test "x$with_pgplotinc" != x ; then PGPLOT_INCDIRS="$with_pgplotinc" fi PGPLOT_INCDIRS="$PGPLOT_INCDIRS \ /usr/local/pgplot/include \ /local/pgplot/include" LIBDIRS="$LIBDIRS \ /usr/local/pgplot/lib \ /local/pgplot/lib" fi if test "x$with_cfitsio" != xno -o \ "x$with_pgplot" != xno ; then LIBDIRS="$LIBDIRS \ /usr/local/lib \ /local/lib \ /opt/local/lib \ /opt/SUNWspro/lib \ /sw/lib" for LIBDIR in $LIBDIRS ; do as_ac_File=`$as_echo "ac_cv_file_$LIBDIR" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LIBDIR" >&5 $as_echo_n "checking for $LIBDIR... " >&6; } if eval \${$as_ac_File+:} false; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r "$LIBDIR"; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : LDFLAGS="$LDFLAGS -L$LIBDIR" else continue fi done # Generic include directories. INCDIRS="/usr/local/include \ /local/include \ /opt/local/include \ /sw/include \ /local \ /usr/include" # CFITSIO. if test "x$with_cfitsio" != xno ; then # Search for CFITSIO. for INCDIR in $CFITSIO_INCDIRS $INCDIRS ; do as_ac_File=`$as_echo "ac_cv_file_$INCDIR/cfitsio/fitsio.h" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $INCDIR/cfitsio/fitsio.h" >&5 $as_echo_n "checking for $INCDIR/cfitsio/fitsio.h... " >&6; } if eval \${$as_ac_File+:} false; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r "$INCDIR/cfitsio/fitsio.h"; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : CFITSIOINC="-I$INCDIR/cfitsio"; break fi as_ac_File=`$as_echo "ac_cv_file_$INCDIR/fitsio.h" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $INCDIR/fitsio.h" >&5 $as_echo_n "checking for $INCDIR/fitsio.h... " >&6; } if eval \${$as_ac_File+:} false; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r "$INCDIR/fitsio.h"; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : CFITSIOINC="-I$INCDIR"; break fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for recv in -lsocket" >&5 $as_echo_n "checking for recv in -lsocket... " >&6; } if ${ac_cv_lib_socket_recv+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char recv (); #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif int main () { return recv (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_socket_recv=yes else ac_cv_lib_socket_recv=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_recv" >&5 $as_echo "$ac_cv_lib_socket_recv" >&6; } if test "x$ac_cv_lib_socket_recv" = xyes; then : CFITSIOLIB="-lsocket" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ffopen in -lcfitsio" >&5 $as_echo_n "checking for ffopen in -lcfitsio... " >&6; } if ${ac_cv_lib_cfitsio_ffopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcfitsio $CFITSIOLIB $LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char ffopen (); #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif int main () { return ffopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_cfitsio_ffopen=yes else ac_cv_lib_cfitsio_ffopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cfitsio_ffopen" >&5 $as_echo "$ac_cv_lib_cfitsio_ffopen" >&6; } if test "x$ac_cv_lib_cfitsio_ffopen" = xyes; then : CFITSIOLIB="-lcfitsio $CFITSIOLIB" fi if test "x$CFITSIOINC" = x -o "x$CFITSIOLIB" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: CFITSIO not found, skipping CFITSIO-dependent tests." >&5 $as_echo "$as_me: WARNING: CFITSIO not found, skipping CFITSIO-dependent tests." >&2;} else { $as_echo "$as_me:${as_lineno-$LINENO}: CFITSIO appears to be available." >&5 $as_echo "$as_me: CFITSIO appears to be available." >&6;} $as_echo "#define HAVE_CFITSIO 1" >>confdefs.h # Check for fits_read_wcstab, present in CFITSIO 3.004beta and later. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fits_read_wcstab in -lcfitsio" >&5 $as_echo_n "checking for fits_read_wcstab in -lcfitsio... " >&6; } if ${ac_cv_lib_cfitsio_fits_read_wcstab+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcfitsio $CFITSIOLIB $LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char fits_read_wcstab (); #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif int main () { return fits_read_wcstab (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_cfitsio_fits_read_wcstab=yes else ac_cv_lib_cfitsio_fits_read_wcstab=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cfitsio_fits_read_wcstab" >&5 $as_echo "$ac_cv_lib_cfitsio_fits_read_wcstab" >&6; } if test "x$ac_cv_lib_cfitsio_fits_read_wcstab" = xyes; then : GETWCSTAB= else GETWCSTAB=getwcstab.o fi if test "x$GETWCSTAB" != x ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: fits_read_wcstab not found in CFITSIO, will use getwcstab.c to compile test programs." >&5 $as_echo "$as_me: WARNING: fits_read_wcstab not found in CFITSIO, will use getwcstab.c to compile test programs." >&2;} fi fi fi # PGPLOT. if test "x$F77" != x -a "x$with_pgplot" != xno ; then # Search for PGPLOT. for INCDIR in $PGPLOT_INCDIRS $INCDIRS ; do as_ac_File=`$as_echo "ac_cv_file_$INCDIR/pgplot/cpgplot.h" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $INCDIR/pgplot/cpgplot.h" >&5 $as_echo_n "checking for $INCDIR/pgplot/cpgplot.h... " >&6; } if eval \${$as_ac_File+:} false; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r "$INCDIR/pgplot/cpgplot.h"; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : PGPLOTINC="-I$INCDIR/pgplot"; break fi as_ac_File=`$as_echo "ac_cv_file_$INCDIR/cpgplot.h" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $INCDIR/cpgplot.h" >&5 $as_echo_n "checking for $INCDIR/cpgplot.h... " >&6; } if eval \${$as_ac_File+:} false; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r "$INCDIR/cpgplot.h"; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : PGPLOTINC="-I$INCDIR"; break fi done # FLIBS (found above via AC_F77_LIBRARY_LDFLAGS) only helps if PGPLOT was # built using the same Fortran compiler that we are using here. # PGPLOT compiled by the SUN Fortran compiler but linked with something # else. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iand_ in -lM77" >&5 $as_echo_n "checking for iand_ in -lM77... " >&6; } if ${ac_cv_lib_M77_iand_+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lM77 $PGPLOTLIB $LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char iand_ (); #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif int main () { return iand_ (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_M77_iand_=yes else ac_cv_lib_M77_iand_=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_M77_iand_" >&5 $as_echo "$ac_cv_lib_M77_iand_" >&6; } if test "x$ac_cv_lib_M77_iand_" = xyes; then : PGPLOTLIB="-lM77 $PGPLOTLIB" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for f77_init in -lF77" >&5 $as_echo_n "checking for f77_init in -lF77... " >&6; } if ${ac_cv_lib_F77_f77_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lF77 $PGPLOTLIB $LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char f77_init (); #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif int main () { return f77_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_F77_f77_init=yes else ac_cv_lib_F77_f77_init=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_F77_f77_init" >&5 $as_echo "$ac_cv_lib_F77_f77_init" >&6; } if test "x$ac_cv_lib_F77_f77_init" = xyes; then : PGPLOTLIB="-lF77 $PGPLOTLIB" fi if test "x$F77" != xg77; then # For PGPLOT compiled with g77 but linked with something else. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lfrtbegin" >&5 $as_echo_n "checking for main in -lfrtbegin... " >&6; } if ${ac_cv_lib_frtbegin_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lfrtbegin $PGPLOTLIB $LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_frtbegin_main=yes else ac_cv_lib_frtbegin_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_frtbegin_main" >&5 $as_echo "$ac_cv_lib_frtbegin_main" >&6; } if test "x$ac_cv_lib_frtbegin_main" = xyes; then : PGPLOTLIB="-lfrtbegin $PGPLOTLIB" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gerror_ in -lg2c" >&5 $as_echo_n "checking for gerror_ in -lg2c... " >&6; } if ${ac_cv_lib_g2c_gerror_+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lg2c $PGPLOTLIB $LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gerror_ (); #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif int main () { return gerror_ (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_g2c_gerror_=yes else ac_cv_lib_g2c_gerror_=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_g2c_gerror_" >&5 $as_echo "$ac_cv_lib_g2c_gerror_" >&6; } if test "x$ac_cv_lib_g2c_gerror_" = xyes; then : PGPLOTLIB="-lg2c $PGPLOTLIB" fi fi if test "x$F77" != xgfortran; then # For PGPLOT compiled with gfortran but linked with something else. # Note that if gfortran itself is driving the linker it can be harmful # to add -lgfortran to the link list without also adding -lgfortranbegin. # Doing so stops gfortran from adding -lgfortranbegin which is needed to # resolve "main". { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _gfortran_abort in -lgfortran" >&5 $as_echo_n "checking for _gfortran_abort in -lgfortran... " >&6; } if ${ac_cv_lib_gfortran__gfortran_abort+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgfortran $PGPLOTLIB $LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char _gfortran_abort (); #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif int main () { return _gfortran_abort (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_gfortran__gfortran_abort=yes else ac_cv_lib_gfortran__gfortran_abort=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gfortran__gfortran_abort" >&5 $as_echo "$ac_cv_lib_gfortran__gfortran_abort" >&6; } if test "x$ac_cv_lib_gfortran__gfortran_abort" = xyes; then : PGPLOTLIB="-lgfortran $PGPLOTLIB" fi fi # Search for X11 includes and libraries. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5 $as_echo_n "checking for X... " >&6; } # Check whether --with-x was given. if test "${with_x+set}" = set; then : withval=$with_x; fi # $have_x is `yes', `no', `disabled', or empty when we do not yet know. if test "x$with_x" = xno; then # The user explicitly disabled X. have_x=disabled else case $x_includes,$x_libraries in #( *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #( *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then : $as_echo_n "(cached) " >&6 else # One or both of the vars are not set, and there is no cached value. ac_x_includes=no ac_x_libraries=no rm -f -r conftest.dir if mkdir conftest.dir; then cd conftest.dir cat >Imakefile <<'_ACEOF' incroot: @echo incroot='${INCROOT}' usrlibdir: @echo usrlibdir='${USRLIBDIR}' libdir: @echo libdir='${LIBDIR}' _ACEOF if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. for ac_var in incroot usrlibdir libdir; do eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`" done # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. for ac_extension in a so sl dylib la dll; do if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" && test -f "$ac_im_libdir/libX11.$ac_extension"; then ac_im_usrlibdir=$ac_im_libdir; break fi done # Screen out bogus values from the imake configuration. They are # bogus both because they are the default anyway, and because # using them would break gcc on systems where it needs fixed includes. case $ac_im_incroot in /usr/include) ac_x_includes= ;; *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; esac case $ac_im_usrlibdir in /usr/lib | /usr/lib64 | /lib | /lib64) ;; *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; esac fi cd .. rm -f -r conftest.dir fi # Standard set of common directories for X headers. # Check X11 before X11Rn because it is often a symlink to the current release. ac_x_header_dirs=' /usr/X11/include /usr/X11R7/include /usr/X11R6/include /usr/X11R5/include /usr/X11R4/include /usr/include/X11 /usr/include/X11R7 /usr/include/X11R6 /usr/include/X11R5 /usr/include/X11R4 /usr/local/X11/include /usr/local/X11R7/include /usr/local/X11R6/include /usr/local/X11R5/include /usr/local/X11R4/include /usr/local/include/X11 /usr/local/include/X11R7 /usr/local/include/X11R6 /usr/local/include/X11R5 /usr/local/include/X11R4 /usr/X386/include /usr/x386/include /usr/XFree86/include/X11 /usr/include /usr/local/include /usr/unsupported/include /usr/athena/include /usr/local/x11r5/include /usr/lpp/Xamples/include /usr/openwin/include /usr/openwin/share/include' if test "$ac_x_includes" = no; then # Guess where to find include files, by looking for Xlib.h. # First, try using that file with no special directory specified. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # We can compile using X headers with no special include directory. ac_x_includes= else for ac_dir in $ac_x_header_dirs; do if test -r "$ac_dir/X11/Xlib.h"; then ac_x_includes=$ac_dir break fi done fi rm -f conftest.err conftest.i conftest.$ac_ext fi # $ac_x_includes = no if test "$ac_x_libraries" = no; then # Check for the libraries. # See if we find them without any special options. # Don't add to $LIBS permanently. ac_save_LIBS=$LIBS LIBS="-lX11 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif int main () { XrmInitialize () ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : LIBS=$ac_save_LIBS # We can link X programs with no special library path. ac_x_libraries= else LIBS=$ac_save_LIBS for ac_dir in `$as_echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` do # Don't even attempt the hair of trying to link an X program! for ac_extension in a so sl dylib la dll; do if test -r "$ac_dir/libX11.$ac_extension"; then ac_x_libraries=$ac_dir break 2 fi done done fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi # $ac_x_libraries = no case $ac_x_includes,$ac_x_libraries in #( no,* | *,no | *\'*) # Didn't find X, or a directory has "'" in its name. ac_cv_have_x="have_x=no";; #( *) # Record where we found X for the cache. ac_cv_have_x="have_x=yes\ ac_x_includes='$ac_x_includes'\ ac_x_libraries='$ac_x_libraries'" esac fi ;; #( *) have_x=yes;; esac eval "$ac_cv_have_x" fi # $with_x != no if test "$have_x" != yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5 $as_echo "$have_x" >&6; } no_x=yes else # If each of the values was on the command line, it overrides each guess. test "x$x_includes" = xNONE && x_includes=$ac_x_includes test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries # Update the cache value to reflect the command line values. ac_cv_have_x="have_x=yes\ ac_x_includes='$x_includes'\ ac_x_libraries='$x_libraries'" { $as_echo "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5 $as_echo "libraries $x_libraries, headers $x_includes" >&6; } fi if test "x$no_x" = x; then if test "x$ac_x_libraries" != x ; then # Not needed for systems that keep the X11 libraries in /usr/lib. LDFLAGS="$LDFLAGS -L$ac_x_libraries" fi PGPLOTLIB="-lX11 $PGPLOTLIB" fi # It is possible that other libraries may be required depending on what # graphics drivers were installed with PGPLOT. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for deflate in -lz" >&5 $as_echo_n "checking for deflate in -lz... " >&6; } if ${ac_cv_lib_z_deflate+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lz $PGPLOTLIB $LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char deflate (); #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif int main () { return deflate (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_z_deflate=yes else ac_cv_lib_z_deflate=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_deflate" >&5 $as_echo "$ac_cv_lib_z_deflate" >&6; } if test "x$ac_cv_lib_z_deflate" = xyes; then : PGPLOTLIB="-lz $PGPLOTLIB" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for png_error in -lpng" >&5 $as_echo_n "checking for png_error in -lpng... " >&6; } if ${ac_cv_lib_png_png_error+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpng $PGPLOTLIB $LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char png_error (); #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif int main () { return png_error (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_png_png_error=yes else ac_cv_lib_png_png_error=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_png_png_error" >&5 $as_echo "$ac_cv_lib_png_png_error" >&6; } if test "x$ac_cv_lib_png_png_error" = xyes; then : PGPLOTLIB="-lpng $PGPLOTLIB" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pgbeg_ in -lpgplot" >&5 $as_echo_n "checking for pgbeg_ in -lpgplot... " >&6; } if ${ac_cv_lib_pgplot_pgbeg_+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpgplot $PGPLOTLIB $FLIBS $LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pgbeg_ (); #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif int main () { return pgbeg_ (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pgplot_pgbeg_=yes else ac_cv_lib_pgplot_pgbeg_=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pgplot_pgbeg_" >&5 $as_echo "$ac_cv_lib_pgplot_pgbeg_" >&6; } if test "x$ac_cv_lib_pgplot_pgbeg_" = xyes; then : PGPLOTLIB="-lpgplot $PGPLOTLIB" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cpgbeg in -lcpgplot" >&5 $as_echo_n "checking for cpgbeg in -lcpgplot... " >&6; } if ${ac_cv_lib_cpgplot_cpgbeg+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcpgplot $PGPLOTLIB $FLIBS $LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char cpgbeg (); #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif int main () { return cpgbeg (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_cpgplot_cpgbeg=yes else ac_cv_lib_cpgplot_cpgbeg=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cpgplot_cpgbeg" >&5 $as_echo "$ac_cv_lib_cpgplot_cpgbeg" >&6; } if test "x$ac_cv_lib_cpgplot_cpgbeg" = xyes; then : PGPLOTLIB="-lcpgplot $PGPLOTLIB" else PGPLOTLIB= fi # Only need the PGPLOT include file to build PGSBOX. if test "x$PGPLOTINC" != x; then SUBDIRS="$SUBDIRS pgsbox" INSTDIR="pgsbox" fi # Also need the PGPLOT library to build pgtest and cpgtest. if test "x$PGPLOTLIB" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: PGPLOT not found, skipping PGPLOT-dependent tests." >&5 $as_echo "$as_me: WARNING: PGPLOT not found, skipping PGPLOT-dependent tests." >&2;} else { $as_echo "$as_me:${as_lineno-$LINENO}: PGPLOT appears to be available." >&5 $as_echo "$as_me: PGPLOT appears to be available." >&6;} TSTDIRS="$TSTDIRS pgsbox" fi fi fi # Utilities are compiled last since they need the libraries. # Ways of disabling them: # configure --disable-utils # configure --enable-utils=no # Check whether --enable-utils was given. if test "${enable_utils+set}" = set; then : enableval=$enable_utils; fi if test "x$enable_utils" = xno ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Compilation of WCS utilities disabled." >&5 $as_echo "$as_me: WARNING: Compilation of WCS utilities disabled." >&2;} else SUBDIRS="$SUBDIRS utils" INSTDIR="$INSTDIR utils" fi # Default observer coordinates for sundazel. if test -f "$HOME/.sundazelrc"; then . "$HOME/.sundazelrc" fi if test "x$OBSLNG" = x; then OBSLNG=0.0 OBSLAT=0.0 OBSTZ=0.0 fi { $as_echo "$as_me:${as_lineno-$LINENO}: End of auxiliary configuration. " >&5 $as_echo "$as_me: End of auxiliary configuration. " >&6;} # Do it. { $as_echo "$as_me:${as_lineno-$LINENO}: Configuring files..." >&5 $as_echo "$as_me: Configuring files..." >&6;} ac_config_files="$ac_config_files makedefs wcslib.pc" ac_config_headers="$ac_config_headers wcsconfig.h wcsconfig_f77.h wcsconfig_tests.h wcsconfig_utils.h" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by WCSLIB $as_me 7.7, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ WCSLIB config.status 7.7 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "makedefs") CONFIG_FILES="$CONFIG_FILES makedefs" ;; "wcslib.pc") CONFIG_FILES="$CONFIG_FILES wcslib.pc" ;; "wcsconfig.h") CONFIG_HEADERS="$CONFIG_HEADERS wcsconfig.h" ;; "wcsconfig_f77.h") CONFIG_HEADERS="$CONFIG_HEADERS wcsconfig_f77.h" ;; "wcsconfig_tests.h") CONFIG_HEADERS="$CONFIG_HEADERS wcsconfig_tests.h" ;; "wcsconfig_utils.h") CONFIG_HEADERS="$CONFIG_HEADERS wcsconfig_utils.h" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/configure.ac0000644000175100001710000004450100000000000017472 0ustar00vstsdocker#----------------------------------------------------------------------------- # Process this file with autoconf-2.53 or later to produce a configure script. #----------------------------------------------------------------------------- # Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. # http://www.atnf.csiro.au/people/Mark.Calabretta # $Id: configure.ac,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ #----------------------------------------------------------------------------- AC_INIT([WCSLIB], [7.7], [mark@calabretta.id.au], [wcslib-7.7]) AC_PREREQ([2.53]) AC_REVISION([$Revision: 7.7 $]) AC_SUBST([PACKAGE_VERSION]) AC_DEFINE_UNQUOTED([WCSLIB_VERSION], [$PACKAGE_VERSION], [Define wcslib version]) # Library version number, same as package version. LIBVER="$PACKAGE_VERSION" AC_SUBST([LIBVER]) AC_CONFIG_SRCDIR([C/wcs.h]) AC_CONFIG_AUX_DIR([config]) # Get the system type. AC_CANONICAL_HOST ARCH="${host_cpu}-$host_os" AC_SUBST([ARCH]) # Look for Flex. AC_ARG_ENABLE([flex], [AS_HELP_STRING([--disable-flex], [don't apply flex (use pre-generated sources)])], []) if test "x$enable_flex" = xno ; then FLEX= AC_MSG_WARN([Generation of flex sources disabled by request, using pre-generated sources.]) else AC_CHECK_PROG([FLEX], [flex], [flex], [], [], []) if test "x$FLEX" = xflex ; then # Version 2.6.0 or later is required. V=`flex --version | awk '{print $2}'` W=`echo $V | awk -F. '{if ((($1*100 + $2)*100 + $3) < 20600) print "no"}'` if test "x$W" != x ; then AC_MSG_WARN([Flex version $V is too old, ignored.]) FLEX= else AC_MSG_NOTICE([Using Flex version $V.]) fi fi if test "x$FLEX" = x ; then AC_MSG_WARN([Flex version 2.6.0 or later does not appear to be available, will use pre-generated sources.]) fi fi # Look for an ANSI C compiler. AC_PROG_CPP AC_PROG_CC AC_PROG_CC_STDC AC_C_CONST AC_TYPE_SIZE_T if test "x$ac_cv_prog_cc_stdc" = xno -o \ "x$ac_cv_c_const" = xno -o \ "x$ac_cv_type_size_t" = xno; then AC_MSG_ERROR([ ------------------------------------------------------- An ANSI standard C library is required to build WCSLIB. ERROR: WCSLIB configuration failure. -------------------------------------------------------], [1]) fi # Check for data types (suggested by autoscan - off_t is only required by # fitshdr). AC_TYPE_OFF_T AC_TYPE_INT8_T AC_TYPE_INT16_T AC_TYPE_INT32_T AC_TYPE_UINT8_T AC_TYPE_UINT16_T AC_TYPE_UINT32_T # Check for ANSI C headers. AC_HEADER_STDC AC_CHECK_HEADERS([ctype.h errno.h limits.h locale.h math.h setjmp.h stdarg.h \ stdio.h stdlib.h string.h]) if test "x$ac_cv_header_stdc" = xno; then AC_MSG_ERROR([ ------------------------------------------------------------------- An ANSI standard C library is required to build WCSLIB. One of the ANSI C header files it requires is missing or unusable. ERROR: WCSLIB configuration failure. -------------------------------------------------------------------], [1]) fi # Flex uses fileno() and other POSIX features whose prototypes are only # available from glibc's stdio.h with an appropriate preprocessor macro # definition. This cannot be set within the flex description file itself # as stdio.h is included in the generated C code before any part of the # description. See fileno(3) and feature_test_macros(7). if test "x$ac_cv_c_compiler_gnu" = xyes ; then FLFLAGS="$FLFLAGS -D_POSIX_C_SOURCE=1" fi AC_SUBST([FLFLAGS]) # Checks for ANSI C library functions (suggested by autoscan - fseeko and # stat are only required by fitshdr). AC_CHECK_LIB([m], [floor]) AC_FUNC_FSEEKO AC_FUNC_MALLOC AC_FUNC_REALLOC AC_FUNC_SETVBUF_REVERSED AC_FUNC_STAT AC_FUNC_VPRINTF AC_CHECK_FUNCS([floor memset pow setlocale sqrt strchr strstr]) # System libraries that may be required by WCSLIB itself. # SunOS, extra maths functions. AC_CHECK_LIB([sunmath], [cosd], [LIBS="-lsunmath $LIBS"], [], []) # See if we can find sincos(). AC_CHECK_FUNCS([sincos]) # Check the size and availability of integer data types. AC_CHECK_SIZEOF([int]) AC_CHECK_SIZEOF([long int]) AC_CHECK_SIZEOF([long long int]) # 64-bit integer data type; use long long int preferentially since that # accords with "%lld" formatting used in fitshdr.l, e.g. # int size_t long int long long int # --- ------ -------- ------------- # gcc x86: 32 32 32 64 # gcc x86_64: 32 64 64 64 if test "x$ac_cv_sizeof_long_long_int" = x8; then AC_DEFINE([WCSLIB_INT64], [long long int], [64-bit integer data type.]) elif test "x$ac_cv_sizeof_long_int" = x8; then AC_DEFINE([WCSLIB_INT64], [long int], [64-bit integer data type.]) elif test "x$ac_cv_sizeof_int" = x8; then AC_DEFINE([WCSLIB_INT64], [int], [64-bit integer data type.]) fi # Does printf() have the z modifier for size_t type? Important for 64-bit. AC_MSG_CHECKING([for printf z format modifier for size_t type]) AC_RUN_IFELSE( [AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT], [[char buf[64]; if (sprintf(buf, "%zu", (size_t)1) != 1) return 1; else if (strcmp(buf, "1")) return 2;]])], AC_DEFINE([MODZ], ["z"], [printf format modifier for size_t type.]) AC_MSG_RESULT(yes), AC_DEFINE([MODZ], [""], [printf format modifier for size_t type.]) AC_MSG_RESULT(no), AC_DEFINE([MODZ], [""], [printf format modifier for size_t type.]) AC_MSG_RESULT(assumed not) ) # Starting values, may be augmented later. SUBDIRS="C" TSTDIRS="C" INSTDIR="C" # Ways of specifying the Fortran compiler, in order of precedence: # configure --enable-fortran= # F77= configure ...bash # # Ways of disabling Fortran: # configure --disable-fortran # configure --enable-fortran=no # F77=no configure ...bash AC_ARG_ENABLE([fortran], [AS_HELP_STRING([--enable-fortran=ARG], [Fortran compiler to use])], []) AC_ARG_ENABLE([fortran], [AS_HELP_STRING([--disable-fortran], [don't build the Fortran wrappers or PGSBOX])], []) if test "x$enable_fortran" != x -a "x$enable_fortran" != xyes ; then F77="$enable_fortran" fi if test "x$F77" = xno ; then F77= AC_MSG_WARN([Compilation of Fortran wrappers and PGSBOX disabled.]) else if test "x$F77" = x ; then # Look for a Fortran compiler. AC_PROG_F77([gfortran g77 f77 ifort xlf frt pgf77 fl32 af77 fort77 f90 \ xlf90 pgf90 epcf90 f95 fort xlf95 lf95 g95]) fi if test "x$F77" = x; then AC_MSG_WARN([ ------------------------------------------------------------------ Fortran compiler not found, will skip Fortran wrappers and PGSBOX. ------------------------------------------------------------------]) # Best guess at Fortran name mangling for use if a compiler does ever # become available. AC_DEFINE([F77_FUNC(name,NAME)], [name ## _]) else if test "x$ac_cv_f77_compiler_gnu" = xyes ; then if test "x$F77" = xg77 -o "x$F77" = xf77 ; then # Not recognized by gfortran. FFLAGS="$FFLAGS -Wno-globals" fi fi AC_MSG_CHECKING(whether $F77 accepts -I) AC_LANG_PUSH(Fortran 77) FFLAGS_save=$FFLAGS FFLAGS=-I. AC_COMPILE_IFELSE(AC_LANG_PROGRAM([], []), [FFLAGS="$FFLAGS_save -I."; AC_MSG_RESULT(yes)], [FFLAGS="$FFLAGS_save"; AC_MSG_RESULT(no)]) AC_LANG_POP() # Libraries required by the Fortran compiler itself (sets FLIBS). # Required by utilities and test programs written in C that link to # Fortran object modules such as pgsbox. AC_F77_LIBRARY_LDFLAGS # Tidy up FLIBS. dirs= libs= for flib in $FLIBS do case "$flib" in -L*) dir=`echo "$flib" | sed -e 's/-L//'` dir=-L`cd "$dir" && pwd` dirs="$dirs $dir" ;; *) libs="$libs $flib" ;; esac done dirs=`for dir in $dirs ; do echo "$dir" ; done | sort -u | xargs` FLIBS="$dirs$libs" # F77 name mangling (defines the F77_FUNC preprocessor macro). AC_F77_WRAPPERS SUBDIRS="C Fortran" TSTDIRS="C Fortran" INSTDIR="Fortran" fi fi # System-dependent system libraries (for building the sharable library). #----------------------------------------------------------------------- # Darwin (contains stubs for long double). AC_CHECK_LIB([SystemStubs], [printf\$LDBLStub], [LIBS="$LIBS -lSystemStubs"], [], []) # Library and installation utilities. #------------------------------------ # Static library generation. # Ensure "non-deterministic" archives are produced during the build process. ar rU conftest.a > /dev/null 2>&1 && ARFLAGS="U" rm -f conftest.a AC_SUBST([ARFLAGS]) AC_PROG_RANLIB # Shared library generation - gcc only. # Ways of disabling shared libraries: # configure --disable-shared # configure --enable-shared=no AC_ARG_ENABLE([shared], [AS_HELP_STRING([--disable-shared], [don't build the WCS shared libraries])], []) SHRLIB= SONAME= SHRFLAGS= SHRLD= SHRSFX= SHRLN= if test "x$ac_cv_c_compiler_gnu" = xyes ; then if test "x$enable_shared" = xno ; then AC_MSG_WARN([Generation of WCS shared libraries disabled.]) else SHVER=`echo "$LIBVER" | sed -e 's/\..*$//'` # Note that -fPIC is on by default for Macs, this just makes it obvious. SHRFLAGS="-fPIC" SHRLD="\$(CC) \$(SHRFLAGS)" case "$host_os" in darwin*) SHRLIB="libwcs.$LIBVER.dylib" SONAME="libwcs.$SHVER.dylib" SHRLD="$SHRLD -dynamiclib -single_module" SHRLD="$SHRLD -compatibility_version $SHVER -current_version $LIBVER -install_name \$(SONAME)" SHRLN="libwcs.dylib" case "$host_cpu" in powerpc*) # Switch off -fPIC (not applicable for PowerPC Macs). CFLAGS="$CFLAGS -mdynamic-no-pic" ;; esac ;; *mingw*) SHRLIB="libwcs.dll.$LIBVER" SONAME="libwcs.dll.$SHVER" SHRLD="$SHRLD -shared -Wl,-h\$(SONAME)" SHRLN="libwcs.dll" ;; *) # Covers Linux and Solaris at least. SHRLIB="libwcs.so.$LIBVER" SONAME="libwcs.so.$SHVER" SHRLD="$SHRLD -shared -Wl,-h\$(SONAME)" SHRLN="libwcs.so" ;; esac fi fi AC_SUBST([SHRLIB]) AC_SUBST([SONAME]) AC_SUBST([SHRFLAGS]) AC_SUBST([SHRLD]) AC_SUBST([SHRSFX]) AC_SUBST([SHRLN]) # Installation utilities. AC_PROG_LN_S AC_PROG_INSTALL # Older versions of GNU make do not have the -O option, which only facilitates # legibility of the output from parallel builds (make -j). make --help | grep '\-O' >/dev/null 2>&1 && MAKEFLAGS="-Otarget" AC_SUBST([MAKEFLAGS]) AC_MSG_NOTICE([End of primary configuration. ]) # The following are required to build utilities and test programs. # ---------------------------------------------------------------- AC_MSG_NOTICE([Looking for libraries etc. for utilities and test suite...]) # Check for other quasi-standard header files. AC_CHECK_HEADERS([unistd.h]) # Large file support. AC_FUNC_FSEEKO AC_SYS_LARGEFILE # Extra places to look for third-party libraries and header files. LIBDIRS= AC_ARG_WITH([cfitsio], [AS_HELP_STRING([--without-cfitsio], [eschew CFITSIO])], []) if test "x$with_cfitsio" = xno ; then AC_MSG_WARN([CFITSIO disabled.]) else AC_ARG_WITH([cfitsiolib], [AS_HELP_STRING([--with-cfitsiolib=DIR], [directory containing cfitsio library])], []) if test "x$with_cfitsiolib" != x ; then LIBDIRS="$LIBDIRS $with_cfitsiolib" fi AC_ARG_WITH([cfitsioinc], [AS_HELP_STRING([--with-cfitsioinc=DIR], [directory containing cfitsio header files])], []) if test "x$with_cfitsioinc" != x ; then CFITSIO_INCDIRS="$with_cfitsioinc" fi CFITSIO_INCDIRS="$CFITSIO_INCDIRS \ /usr/local/cfitsio/include \ /local/cfitsio/include" LIBDIRS="$LIBDIRS \ /usr/local/cfitsio/lib \ /local/cfitsio/lib" fi AC_ARG_WITH([pgplot], [AS_HELP_STRING([--without-pgplot], [eschew PGPLOT])], []) if test "x$with_pgplot" = xno ; then AC_MSG_WARN([PGPLOT disabled.]) else AC_ARG_WITH([pgplotlib], [AS_HELP_STRING([--with-pgplotlib=DIR], [directory containing pgplot library])], []) if test "x$with_pgplotlib" != x ; then LIBDIRS="$LIBDIRS $with_pgplotlib" fi AC_ARG_WITH([pgplotinc], [AS_HELP_STRING([--with-pgplotinc=DIR], [directory containing pgplot header files])], []) if test "x$with_pgplotinc" != x ; then PGPLOT_INCDIRS="$with_pgplotinc" fi PGPLOT_INCDIRS="$PGPLOT_INCDIRS \ /usr/local/pgplot/include \ /local/pgplot/include" LIBDIRS="$LIBDIRS \ /usr/local/pgplot/lib \ /local/pgplot/lib" fi if test "x$with_cfitsio" != xno -o \ "x$with_pgplot" != xno ; then LIBDIRS="$LIBDIRS \ /usr/local/lib \ /local/lib \ /opt/local/lib \ /opt/SUNWspro/lib \ /sw/lib" for LIBDIR in $LIBDIRS ; do AC_CHECK_FILE([$LIBDIR], [LDFLAGS="$LDFLAGS -L$LIBDIR"], [continue]) done # Generic include directories. INCDIRS="/usr/local/include \ /local/include \ /opt/local/include \ /sw/include \ /local \ /usr/include" # CFITSIO. if test "x$with_cfitsio" != xno ; then # Search for CFITSIO. for INCDIR in $CFITSIO_INCDIRS $INCDIRS ; do AC_CHECK_FILE([$INCDIR/cfitsio/fitsio.h], [CFITSIOINC="-I$INCDIR/cfitsio"; break]) AC_CHECK_FILE([$INCDIR/fitsio.h], [CFITSIOINC="-I$INCDIR"; break]) done AC_CHECK_LIB([socket], [recv], [CFITSIOLIB="-lsocket"], [], [$LIBS]) AC_CHECK_LIB([cfitsio], [ffopen], [CFITSIOLIB="-lcfitsio $CFITSIOLIB"], [], [$CFITSIOLIB $LIBS]) if test "x$CFITSIOINC" = x -o "x$CFITSIOLIB" = x; then AC_MSG_WARN([CFITSIO not found, skipping CFITSIO-dependent tests.]) else AC_MSG_NOTICE([CFITSIO appears to be available.]) AC_DEFINE([HAVE_CFITSIO], [1], [Define to 1 if CFITSIO is available.]) # Check for fits_read_wcstab, present in CFITSIO 3.004beta and later. AC_CHECK_LIB([cfitsio], [fits_read_wcstab], [GETWCSTAB=], [GETWCSTAB=getwcstab.o], [$CFITSIOLIB $LIBS]) if test "x$GETWCSTAB" != x ; then AC_MSG_WARN([fits_read_wcstab not found in CFITSIO, will use getwcstab.c to compile test programs.]) fi fi fi # PGPLOT. if test "x$F77" != x -a "x$with_pgplot" != xno ; then # Search for PGPLOT. for INCDIR in $PGPLOT_INCDIRS $INCDIRS ; do AC_CHECK_FILE([$INCDIR/pgplot/cpgplot.h], [PGPLOTINC="-I$INCDIR/pgplot"; break]) AC_CHECK_FILE([$INCDIR/cpgplot.h], [PGPLOTINC="-I$INCDIR"; break]) done # FLIBS (found above via AC_F77_LIBRARY_LDFLAGS) only helps if PGPLOT was # built using the same Fortran compiler that we are using here. # PGPLOT compiled by the SUN Fortran compiler but linked with something # else. AC_CHECK_LIB([M77], [iand_], [PGPLOTLIB="-lM77 $PGPLOTLIB"], [], [$PGPLOTLIB $LIBS]) AC_CHECK_LIB([F77], [f77_init], [PGPLOTLIB="-lF77 $PGPLOTLIB"], [], [$PGPLOTLIB $LIBS]) if test "x$F77" != xg77; then # For PGPLOT compiled with g77 but linked with something else. AC_CHECK_LIB([frtbegin], [main], [PGPLOTLIB="-lfrtbegin $PGPLOTLIB"], [], [$PGPLOTLIB $LIBS]) AC_CHECK_LIB([g2c], [gerror_], [PGPLOTLIB="-lg2c $PGPLOTLIB"], [], [$PGPLOTLIB $LIBS]) fi if test "x$F77" != xgfortran; then # For PGPLOT compiled with gfortran but linked with something else. # Note that if gfortran itself is driving the linker it can be harmful # to add -lgfortran to the link list without also adding -lgfortranbegin. # Doing so stops gfortran from adding -lgfortranbegin which is needed to # resolve "main". AC_CHECK_LIB([gfortran], [_gfortran_abort], [PGPLOTLIB="-lgfortran $PGPLOTLIB"], [], [$PGPLOTLIB $LIBS]) fi # Search for X11 includes and libraries. AC_PATH_X if test "x$no_x" = x; then if test "x$ac_x_libraries" != x ; then # Not needed for systems that keep the X11 libraries in /usr/lib. LDFLAGS="$LDFLAGS -L$ac_x_libraries" fi PGPLOTLIB="-lX11 $PGPLOTLIB" fi # It is possible that other libraries may be required depending on what # graphics drivers were installed with PGPLOT. AC_CHECK_LIB([z], [deflate], [PGPLOTLIB="-lz $PGPLOTLIB"], [], [$PGPLOTLIB $LIBS]) AC_CHECK_LIB([png], [png_error], [PGPLOTLIB="-lpng $PGPLOTLIB"], [], [$PGPLOTLIB $LIBS]) AC_CHECK_LIB([pgplot], [pgbeg_], [PGPLOTLIB="-lpgplot $PGPLOTLIB"], [], [$PGPLOTLIB $FLIBS $LIBS]) AC_CHECK_LIB([cpgplot], [cpgbeg], [PGPLOTLIB="-lcpgplot $PGPLOTLIB"], [PGPLOTLIB=], [$PGPLOTLIB $FLIBS $LIBS]) # Only need the PGPLOT include file to build PGSBOX. if test "x$PGPLOTINC" != x; then SUBDIRS="$SUBDIRS pgsbox" INSTDIR="pgsbox" fi # Also need the PGPLOT library to build pgtest and cpgtest. if test "x$PGPLOTLIB" = x; then AC_MSG_WARN([PGPLOT not found, skipping PGPLOT-dependent tests.]) else AC_MSG_NOTICE([PGPLOT appears to be available.]) TSTDIRS="$TSTDIRS pgsbox" fi fi fi # Utilities are compiled last since they need the libraries. # Ways of disabling them: # configure --disable-utils # configure --enable-utils=no AC_ARG_ENABLE([utils], [AS_HELP_STRING([--disable-utils], [don't build the WCS utilities])], []) if test "x$enable_utils" = xno ; then AC_MSG_WARN([Compilation of WCS utilities disabled.]) else SUBDIRS="$SUBDIRS utils" INSTDIR="$INSTDIR utils" fi # Default observer coordinates for sundazel. if test -f "$HOME/.sundazelrc"; then . "$HOME/.sundazelrc" fi if test "x$OBSLNG" = x; then OBSLNG=0.0 OBSLAT=0.0 OBSTZ=0.0 fi AC_SUBST([CFITSIOINC]) AC_SUBST([CFITSIOLIB]) AC_SUBST([GETWCSTAB]) AC_SUBST([PGPLOTINC]) AC_SUBST([PGPLOTLIB]) AC_SUBST([SUBDIRS]) AC_SUBST([TSTDIRS]) AC_SUBST([INSTDIR]) AC_SUBST([OBSLNG]) AC_SUBST([OBSLAT]) AC_SUBST([OBSTZ]) AC_MSG_NOTICE([End of auxiliary configuration. ]) AC_SUBST([FLAVOUR]) # Do it. AC_MSG_NOTICE([Configuring files...]) AC_CONFIG_FILES([makedefs wcslib.pc]) AC_CONFIG_HEADERS([wcsconfig.h wcsconfig_f77.h wcsconfig_tests.h wcsconfig_utils.h]) AC_OUTPUT ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/flavours0000644000175100001710000001462600000000000016775 0ustar00vstsdocker#----------------------------------------------------------------------------- # Makefile overrides for various combinations of architecture, operating # system and compiler. Used for development and testing only, not required # for building WCSLIB. # # Variables like CC and CFLAGS are exported into the environment so that they # will be seen by 'configure'. Thus, normal usage is as follows: # # make distclean # make FLAVOUR=Linux configure # make # # Reminder: add '-d' to FLFLAGS for debugging. # # $Id: flavours,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ #----------------------------------------------------------------------------- # The list of FLAVOURs can be set on the command line. F := $(shell echo $(FLAVOURS) | tr a-z A-Z) ifeq "$F" "" F := FLAVOURS := "" endif ifeq "$F" "LINUX" override FLAVOURS := "" Linux Linuxp endif ifeq "$F" "SUN" override FLAVOURS := "" SUN/GNU SUN/GNU3 SUN/GNUp SUN/ANSI endif ifeq "$F" "PURE" override FLAVOURS := SUN/Pure SUN/Quant endif F := # Quench warnings about padding in foreign structs, particularly in fitsio.h. ifneq "$(findstring $(SUBDIR),C Fortran pgsbox)" "" WPADDED := -Wpadded endif # Linux with gcc/gfortran (also works for Darwin). ifeq "$(FLAVOUR)" "Linux" F := $(FLAVOUR) INSTRUMENT := -fsanitize=address -fsanitize=undefined INSTRUMENT += -fstack-protector-strong CWARNINGS := -Wall -Wextra -Wno-clobbered -Wno-long-long ifeq "$(INSTRUMENT)" "" # The instrumentation options produce copious "padding" warnings. CWARNINGS += $(WPADDED) endif FWARNINGS := -Wall -Wno-surprising export CC := gcc -std=c99 -pedantic export CPPFLAGS := export CFLAGS := -g -O0 $(INSTRUMENT) $(CWARNINGS) export F77 := gfortran export FFLAGS := -g -O0 -fimplicit-none -I. $(INSTRUMENT) $(FWARNINGS) export LDFLAGS := $(INSTRUMENT) ifdef VALGRIND override VALGRIND := valgrind -v --leak-check=full --show-leak-kinds=all override VALGRIND += --track-origins=yes endif endif ifeq "$(FLAVOUR)" "Linux11" F := $(FLAVOUR) INSTRUMENT := -fsanitize=address -fsanitize=undefined INSTRUMENT += -fstack-protector-strong CWARNINGS := -Wall -Wextra -Wno-clobbered -Wno-long-long ifeq "$(INSTRUMENT)" "" # The instrumentation options produce copious "padding" warnings. CWARNINGS += $(WPADDED) endif FWARNINGS := -Wall -Wno-surprising export CC := gcc-11.1.0 -std=c99 -pedantic export CPPFLAGS := -D_FORTIFY_SOURCE=2 export CFLAGS := -g -O0 $(INSTRUMENT) $(CWARNINGS) export F77 := gfortran-11.1.0 export FFLAGS := -g -O0 -fimplicit-none -I. $(INSTRUMENT) $(FWARNINGS) export LDFLAGS := $(INSTRUMENT) export LD_RUN_PATH := /usr/local/lib64 ifdef VALGRIND override VALGRIND := valgrind -v --leak-check=full --show-leak-kinds=all override VALGRIND += --track-origins=yes endif endif ifeq "$(FLAVOUR)" "Linuxp" F := $(FLAVOUR) export CC := gcc -std=c99 -pedantic export CPPFLAGS := export CFLAGS := -pg -g -O -Wall -Wextra -Wno-long-long $(WPADDED) export FFLAGS := -pg -a -g -O -fimplicit-none -Wall -I. export LDFLAGS := -pg -g $(filter -L%, $(LDFLAGS)) override EXTRA_CLEAN := gmon.out bb.out endif # Solaris with gcc/gfortran 4.x (lynx). ifeq "$(FLAVOUR)" "SUN/GNU" F := $(FLAVOUR) export CC := gcc -std=c99 export CPPFLAGS := export CFLAGS := -g -Wall -Wno-long-long $(WPADDED) export F77 := gfortran export FFLAGS := -g -fimplicit-none -Wall -I. LD := gcc endif ifeq "$(FLAVOUR)" "SUN/GNU3" F := $(FLAVOUR) export CC := gcc-3.1.1 -std=c99 export CPPFLAGS := export CFLAGS := -g -Wall -Wno-long-long $(WPADDED) export F77 := g77-3.1.1 export FFLAGS := -g -Wimplicit -Wunused -Wno-globals -I. LD := gcc-3.1.1 endif ifeq "$(FLAVOUR)" "SUN/GNUp" F := $(FLAVOUR) export CC := gcc -std=c99 -pedantic export CPPFLAGS := export CFLAGS := -pg -a -g -O -Wall -Wno-long-long $(WPADDED) export FFLAGS := -pg -a -g -O -fimplicit-none -Wall -I. export LDFLAGS := -pg -a -g $(filter -L%, $(LDFLAGS)) override EXTRA_CLEAN := gmon.out bb.out endif # Solaris with SUN cc/f77. ifeq "$(FLAVOUR)" "SUN/ANSI" F := $(FLAVOUR) WCSTRIG := NATIVE export CC := cc export CFLAGS := -g -I/usr/local/include export F77 := f77 export FFLAGS := -g -erroff=WDECL_LOCAL_NOTUSED LD := f77 endif # Purify and quantify in Solaris. ifeq "$(FLAVOUR)" "SUN/Pure" F := $(FLAVOUR) WCSTRIG := NATIVE export CC := purify gcc export CFLAGS := -g export F77 := purify gcc export FFLAGS := -g -Wimplicit -Wno-globals -I. export LDFLAGS := $(filter -L%, $(LDFLAGS)) override EXTRA_CLEAN := *_pure_p*.[ao] *.pcv .pure ../C/*_pure_p*.[ao] endif ifeq "$(FLAVOUR)" "SUN/Quant" F := $(FLAVOUR) WCSTRIG := NATIVE export CC := quantify gcc export CFLAGS := -g export F77 := quantify gcc export FFLAGS := -g -Wimplicit -Wno-globals -I. export LDFLAGS := $(filter -L%, $(LDFLAGS)) override EXTRA_CLEAN := *_pure_q*.[ao] .pure endif # Check FLAVOUR. ifneq "$F" "$(FLAVOUR)" override FLAVOUR := unrecognised endif # Check VALGRIND. ifeq "$(findstring valgrind, $(VALGRIND))" "valgrind" override MODE := interactive else # Unrecognised. override VALGRIND := endif # Check MODE. ifeq "$(MODE)" "interactive" # Important not to have output batched when running the test programs. MAKEFLAGS := $(filter-out -Otarget,$(MAKEFLAGS)) -Onone else # Unrecognised. override MODE := endif # gmake uses FC in place of configure's F77. ifdef F77 FC := $(F77) endif ifndef TIMER TIMER := date +"%a %Y/%m/%d %X %z, executing on $$HOST" endif ifdef FLAVOUR TIMER := $(TIMER) ; echo " with $(FLAVOUR) FLAVOUR." endif # Experimental (see http://upstream-tracker.org/versions/wcslib.html). api-sanity-check : -@ $(RM) -r $@/ @ mkdir $@/ @ cp C/*.h C/$(SHRLIB) $@/ @ echo "$(LIBVER)" > $@/opts.xml @ echo "." >> $@/opts.xml @ echo "." >> $@/opts.xml @ echo "-Dwtbarr=wtbarr_s" >> $@/opts.xml cd $@ && api-sanity-checker -lib WCSLIB -d opts.xml \ -show-retval -gen -build -run show :: -@ echo 'For code development...' -@ echo ' FLAVOURS := $(FLAVOURS)' -@ echo ' FLAVOUR := $(FLAVOUR)' -@ echo ' MODE := $(MODE)' -@ echo ' VALGRIND := $(VALGRIND)' -@ echo ' EXTRA_CLEAN := $(EXTRA_CLEAN)' -@ echo '' ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/makedefs.in0000644000175100001710000002156700000000000017322 0ustar00vstsdocker#----------------------------------------------------------------------------- # GNU makefile definitions for building WCSLIB 7.7 # # makedefs is generated from makedefs.in by configure. It contains variable # definitions and some general-purpose rules for building WCSLIB. # # Targets defined here # -------------------- # printenv: Print the environment as seen within makefile rules. # show: Print the values of all makefile variables used. # # Notes: # 1) If you need to make changes then it may be preferable to modify # makedefs.in (not makedefs). The makefile will detect this and # automatically re-run config.status to regenerate makedefs. # # 2) There are three choices for trigd functions - cosd(), sind(), tand(), # acosd(), asind(), atand(), and atan2d(), made by setting WCSTRIG: # # 1: Use the wrapper functions supplied with WCSLIB (default): # WCSTRIG := WRAPPER # # 2: Use native trigd functions supplied in a mathematics library such # as libsunmath (you will also need to add the library to the LIBS # variable below): # WCSTRIG := NATIVE # # 3: Use C preprocessor macro implementations of the trigd functions # (this method is typically 20% faster but may lead to rounding # errors near the poles): # WCSTRIG := MACRO # # 3) Variables for creating the shared (dynamic) library are currently # only set by 'configure' if the GNU C compiler is used. However, # you can set these variables by hand, preferably in makedefs.in. # # Shared libraries require position-independent code (PIC) which imposes # a performance overhead. Consequently the static libraries are # compiled separately without this option. # # The shared library will be installed with version number, e.g. as # libwcs.so.7.7 or libwcs.7.7.dylib with or without the symlink # required to make it visible to the linker (controlled by the SHRLN # variable). On Macs it is deliberately not created because its very # existence precludes static linking with the cctools linker. You can # still link dynamically by using -lwcs.7.7. # # 4) PGPLOT is Tim Pearson's Fortran graphics library with separate C # interface available from astro.caltech.edu. It is only required by # one utility, wcsgrid, and the test programs that plot test grids # (tprj2, tcel1, tcel2, tspc, ttab2, ttab3, twcsmix, and tpih2). You can # skip these by setting PGPLOTLIB to blank. # # It is difficult for configure to deduce what auxiliary graphics # libraries may be needed for PGPLOT since it depends on which of many # possible graphics drivers were selected when PGPLOT was installed. # Therefore it is quite likely that you will need to add additional # libraries to PGPLOTLIB. # # 5) CFITSIO is Bill Pence's FITS I/O library written in C with Fortran # wrappers, available from http://heasarc.gsfc.nasa.gov/fitsio. # # CFITSIO is required by three utilities, HPXcvt, wcsgrid, and wcsware, # and also by the test programs twcstab and twcshdr. wcsware and the # test programs use fits_read_wcstab() which is implemented by # getwcstab.c. However, this implementation is included in CFITSIO post # 3.004beta, so getwcstab.c is required here only for older releases # (controlled by variable GETWCSTAB). getwcstab.o itself is not inserted # into the WCSLIB object library. # # If available, CFITSIO is also optionally used for test programs # tfitshdr, tbth1, tpih1 and tpih2 by setting preprocessor macro # -DDO_CFITSIO. # # Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. # http://www.atnf.csiro.au/people/Mark.Calabretta # $Id: makedefs.in,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ #----------------------------------------------------------------------------- # Version. LIBVER := @LIBVER@ WCSLIBPKG := wcslib-@PACKAGE_VERSION@ # Additional options for GNU make added by configure. MAKEFLAGS += @MAKEFLAGS@ # System architecture. ARCH := @ARCH@ # Flex and options. FLEX := @FLEX@ FLFLAGS := @FLFLAGS@ # C preprocessor and options. CPP := @CPP@ CPPFLAGS := @CPPFLAGS@ @DEFS@ WCSTRIG := WRAPPER # C compiler and options. CC := @CC@ CFLAGS := @CFLAGS@ # Fortran compiler and options. FC := @F77@ FFLAGS := @FFLAGS@ # Static object library. WCSLIB := libwcs-$(LIBVER).a ARFLAGS := @ARFLAGS@ RANLIB := @RANLIB@ # Shared (dynamic) library (see note 3 above). SHRLIB := @SHRLIB@ SONAME := @SONAME@ SHRFLAGS := @SHRFLAGS@ SHRLD := @SHRLD@ SHRLN := @SHRLN@ # What subdirectories to build. SUBDIRS := @SUBDIRS@ TSTDIRS := @TSTDIRS@ # Top of the 'make install' hierarchy: pgsbox -> Fortran -> C. INSTDIR := @INSTDIR@ # Installation utilities and locations. LN_S := @LN_S@ INSTALL := @INSTALL@ # Needed for the definitions provided by autoconf. prefix := @prefix@ exec_prefix := @exec_prefix@ datarootdir := @datarootdir@ PACKAGE_TARNAME := @PACKAGE_TARNAME@ docdir := @docdir@ LIBDIR := $(DESTDIR)@libdir@ BINDIR := $(DESTDIR)@bindir@ INCDIR := $(DESTDIR)@includedir@/wcslib-$(LIBVER) INCLINK := $(DESTDIR)@includedir@/wcslib DOCDIR := $(DESTDIR)@docdir@ DOCLINK := $(dir $(DESTDIR)@docdir@)wcslib HTMLDIR := $(DESTDIR)@htmldir@ PDFDIR := $(DESTDIR)@pdfdir@ MANDIR := $(DESTDIR)@mandir@ # For putting timestamps in the build log. TIMER := date +"%a %Y/%m/%d %X %z, executing on $$HOST" # The remaining options are for building utilities and test programs. # ------------------------------------------------------------------- # Linker options (use CC for linking). LD = $(CC) LDFLAGS := @LDFLAGS@ # PGPLOT (see note 4 above). PGPLOTINC := @PGPLOTINC@ PGPLOTLIB := @PGPLOTLIB@ # CFITSIO (see note 5 above). CFITSIOINC := @CFITSIOINC@ CFITSIOLIB := @CFITSIOLIB@ GETWCSTAB := @GETWCSTAB@ # Libraries required by the above Fortran compiler. FLIBS := @FLIBS@ # Libraries required by WCSLIB itself. LIBS := @LIBS@ # Default observer coordinates for sundazel. May be set as environment # variables, either generally or in $HOME/.sundazelrc, which is read by # configure. OBSLNG := @OBSLNG@ OBSLAT := @OBSLAT@ OBSTZ := @OBSTZ@ #----------------------------------------------------------------------------- # You shouldn't need to change anything below here. #----------------------------------------------------------------------------- SHELL := /bin/sh VPATH := .. # Common targets. .PHONY : all build FORCE printenv show all : show -@ echo '' @ $(MAKE) build FORCE : # Print the environment as seen by makefile rules. printenv : -@ printenv | sort # Print variable definitions. show :: wcsconfig.h -@ echo '' -@ uname -a -@ echo '' -@ $(MAKE) --version | head -1 -@ echo ' SUBDIR := $(SUBDIR)' -@ echo ' MAKEFLAGS := $(MAKEFLAGS)' -@ echo '' -@ echo 'For building and installing $(WCSLIBPKG)...' -@ echo ' ARCH := $(ARCH)' -@ echo ' FLEX := $(FLEX)' -@ echo ' FLFLAGS := $(FLFLAGS)' -@ echo ' CPP := $(CPP)' -@ echo ' CPPFLAGS := $(CPPFLAGS)' -@ echo ' WCSTRIG := $(WCSTRIG)' -@ echo ' CC := $(CC)' -@ echo ' CFLAGS := $(CFLAGS)' -@ echo ' FC := $(FC)' -@ echo ' FFLAGS := $(FFLAGS)' -@ echo ' WCSLIB := $(WCSLIB)' -@ echo ' ARFLAGS := $(ARFLAGS)' -@ echo ' RANLIB := $(RANLIB)' -@ echo ' SHRLIB := $(SHRLIB)' -@ echo ' SONAME := $(SONAME)' -@ echo ' SHRFLAGS := $(SHRFLAGS)' -@ echo ' SHRLD := $(SHRLD)' -@ echo ' SHRLN := $(SHRLN)' -@ echo ' LN_S := $(LN_S)' -@ echo ' INSTALL := $(INSTALL)' -@ echo ' LIBDIR := $(LIBDIR)' -@ echo ' BINDIR := $(BINDIR)' -@ echo ' INCDIR := $(INCDIR)' -@ echo ' INCLINK := $(INCLINK)' -@ echo ' DOCDIR := $(DOCDIR)' -@ echo ' DOCLINK := $(DOCLINK)' -@ echo ' HTMLDIR := $(HTMLDIR)' -@ echo ' PDFDIR := $(PDFDIR)' -@ echo ' MANDIR := $(MANDIR)' -@ echo ' TIMER := $(TIMER)' -@ echo '' -@ echo 'Important wcsconfig.h defines...' -@ echo " `grep HAVE_SINCOS $<`" -@ echo " `grep WCSLIB_INT64 $<`" -@ echo '' -@ echo 'To build utilities and test programs...' -@ echo ' LD := $(LD)' -@ echo ' LDFLAGS := $(LDFLAGS)' -@ echo ' PGPLOTINC := $(PGPLOTINC)' -@ echo ' PGPLOTLIB := $(PGPLOTLIB)' -@ echo ' CFITSIOINC := $(CFITSIOINC)' -@ echo ' CFITSIOLIB := $(CFITSIOLIB)' -@ echo ' GETWCSTAB := $(GETWCSTAB)' -@ echo ' FLIBS := $(FLIBS)' -@ echo ' LIBS := $(LIBS)' -@ echo '' -@ echo 'Default observer coordinates for sundazel...' -@ echo ' OBSLNG := $(OBSLNG)' -@ echo ' OBSLAT := $(OBSLAT)' -@ echo ' OBSTZ := $(OBSTZ)' -@ echo '' # Code development overrides, for use in the code subdirectories. FLAVOUR := @FLAVOUR@ -include ../flavours ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/wcsconfig.h.in0000644000175100001710000000134300000000000017741 0ustar00vstsdocker/*============================================================================ * * wcsconfig.h is generated from wcsconfig.h.in by 'configure'. It contains * C preprocessor macro definitions for compiling WCSLIB 7.7 * * Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. * http://www.atnf.csiro.au/people/Mark.Calabretta * $Id: wcsconfig.h.in,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *===========================================================================*/ /* wcslib_version() is available (as of 5.0). */ #define HAVE_WCSLIB_VERSION /* WCSLIB library version number. */ #undef WCSLIB_VERSION /* Define to 1 if sincos() is available. */ #undef HAVE_SINCOS /* 64-bit integer data type. */ #undef WCSLIB_INT64 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/wcsconfig_f77.h.in0000644000175100001710000000207200000000000020424 0ustar00vstsdocker/*============================================================================ * * wcsconfig_f77.h is generated from wcsconfig_f77.h.in by 'configure'. It * contains C preprocessor definitions for building the WCSLIB 7.7 Fortran * wrappers. * * Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. * http://www.atnf.csiro.au/people/Mark.Calabretta * $Id: wcsconfig_f77.h.in,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *===========================================================================*/ /* Integer array type large enough to hold an address. Set here to int[2] for * 64-bit addresses, but could be defined as int* on 32-bit machines. */ typedef int iptr[2]; /* Macro for mangling Fortran subroutine names that do not contain * underscores. Typically a name like "WCSINI" (case-insensitive) will become * something like "wcsini_" (case-sensitive). The Fortran wrappers, which are * written in C, are preprocessed into names that match the latter. The macro * takes two arguments which specify the name in lower and upper case. */ #undef F77_FUNC ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/wcsconfig_tests.h.in0000644000175100001710000000126500000000000021166 0ustar00vstsdocker/*============================================================================ * * wcsconfig_test.h is generated from wcsconfig_test.h.in by 'configure'. It * contains C preprocessor definitions for compiling the WCSLIB 7.7 test/demo * programs. * * Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. * http://www.atnf.csiro.au/people/Mark.Calabretta * $Id: wcsconfig_tests.h.in,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *===========================================================================*/ #include /* Define to 1 if the CFITSIO library is available. */ #undef HAVE_CFITSIO /* Define to the printf format modifier for size_t type. */ #undef MODZ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/wcsconfig_utils.h.in0000644000175100001710000000247600000000000021171 0ustar00vstsdocker/*============================================================================ * * wcsconfig_utils.h is generated from wcsconfig_utils.h.in by 'configure'. * It contains C preprocessor macro definitions for compiling the WCSLIB 7.7 * utilities. * * Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. * http://www.atnf.csiro.au/people/Mark.Calabretta * $Id: wcsconfig_utils.h.in,v 7.7 2021/07/12 06:36:49 mcalabre Exp $ *===========================================================================*/ #include /* Definitions for Large File Support (LFS), i.e. files larger than 2GiB, for * the fitshdr utility. */ /* Define to 1 if fseeko() is available (for small or large files). */ #undef HAVE_FSEEKO /* Define _LARGEFILE_SOURCE to get prototypes from stdio.h for the LFS * functions fseeko() and ftello() which use an off_t argument in place of a * long. */ #undef _LARGEFILE_SOURCE /* There seems to be a bug in autoconf that causes _LARGEFILE_SOURCE not to be * set in Linux. This dreadful kludge gets around it for now. */ #if (defined HAVE_FSEEKO && !defined _LARGEFILE_SOURCE) #define _LARGEFILE_SOURCE #endif /* Number of bits in a file offset (off_t) on systems where it can be set. */ #undef _FILE_OFFSET_BITS /* Define for large files needed on AIX-type systems. */ #undef _LARGE_FILES ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/cextern/wcslib/wcslib.pc.in0000644000175100001710000000041400000000000017413 0ustar00vstsdockerprefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@/wcslib Name: WCSLIB Description: An implementation of the FITS World Coordinate System standard Version: @PACKAGE_VERSION@ Requires: Libs: -L${libdir} -lwcs -lm Cflags: -I${includedir} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/codecov.yml0000644000175100001710000000001500000000000014406 0ustar00vstsdockercomment: off ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/conftest.py0000644000175100001710000000501000000000000014440 0ustar00vstsdocker# Licensed under a 3-clause BSD style license - see LICENSE.rst # This file is the main file used when running tests with pytest directly, # in particular if running e.g. ``pytest docs/``. import os import tempfile import hypothesis from astropy import __version__ try: from pytest_astropy_header.display import PYTEST_HEADER_MODULES, TESTED_VERSIONS except ImportError: PYTEST_HEADER_MODULES = {} TESTED_VERSIONS = {} # This has to be in the root dir or it will not display in CI. def pytest_configure(config): PYTEST_HEADER_MODULES['PyERFA'] = 'erfa' PYTEST_HEADER_MODULES['Cython'] = 'cython' PYTEST_HEADER_MODULES['Scikit-image'] = 'skimage' PYTEST_HEADER_MODULES['asdf'] = 'asdf' PYTEST_HEADER_MODULES['pyarrow'] = 'pyarrow' TESTED_VERSIONS['Astropy'] = __version__ # This has to be in the root dir or it will not display in CI. def pytest_report_header(config): # This gets added after the pytest-astropy-header output. return (f'ARCH_ON_CI: {os.environ.get("ARCH_ON_CI", "undefined")}\n' f'IS_CRON: {os.environ.get("IS_CRON", "undefined")}\n') # Tell Hypothesis that we might be running slow tests, to print the seed blob # so we can easily reproduce failures from CI, and derive a fuzzing profile # to try many more inputs when we detect a scheduled build or when specifically # requested using the HYPOTHESIS_PROFILE=fuzz environment variable or # `pytest --hypothesis-profile=fuzz ...` argument. hypothesis.settings.register_profile( 'ci', deadline=None, print_blob=True, derandomize=True ) hypothesis.settings.register_profile( 'fuzzing', deadline=None, print_blob=True, max_examples=1000 ) default = 'fuzzing' if (os.environ.get('IS_CRON') == 'true' and os.environ.get('ARCH_ON_CI') not in ('aarch64', 'ppc64le')) else 'ci' # noqa: E501 hypothesis.settings.load_profile(os.environ.get('HYPOTHESIS_PROFILE', default)) # Make sure we use temporary directories for the config and cache # so that the tests are insensitive to local configuration. os.environ['XDG_CONFIG_HOME'] = tempfile.mkdtemp('astropy_config') os.environ['XDG_CACHE_HOME'] = tempfile.mkdtemp('astropy_cache') os.mkdir(os.path.join(os.environ['XDG_CONFIG_HOME'], 'astropy')) os.mkdir(os.path.join(os.environ['XDG_CACHE_HOME'], 'astropy')) # Note that we don't need to change the environment variables back or remove # them after testing, because they are only changed for the duration of the # Python process, and this configuration only matters if running pytest # directly, not from e.g. an IPython session. ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2792614 astropy-5.0.2/docs/0000755000175100001710000000000000000000000013175 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/Makefile0000644000175100001710000001072700000000000014644 0ustar00vstsdocker# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest #This is needed with git because git doesn't create a dir if it's empty $(shell [ -d "_static" ] || mkdir -p _static) help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " text to make text files" @echo " man to make manual pages" @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" clean: -rm -rf $(BUILDDIR) -rm -rf api -rm -rf generated html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Astropy.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Astropy.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/Astropy" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Astropy" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." make -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: @echo "Run 'pytest' in the root directory to run doctests " \ @echo "in the documentation." ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/_pkgtemplate.rst0000644000175100001710000000470600000000000016412 0ustar00vstsdocker**************************************************** A description of the package (`astropy.packagename`) **************************************************** When creating a new subpackage's documentation, this file should be copied to a file "index.rst" in a directory corresponding to the name of the package. E.g., ``docs/packagename/index.rst``. And don't forget to delete this paragraph. Introduction ============ Include general content that might be useful for understanding the package here, as well as general scientific or mathematical background that might be necessary for the "big-picture" of this package. Getting Started =============== Short tutorial-like examples of how to do common-tasks - should be fairly quick, with any more detailed examples in the next section. Using `packagename` =================== .. THIS SECTION SHOULD BE EITHER This section is for the detailed documentation. For simpler packages, this should either by paragraphs or sub-divided into sub-sections like: Sub-topic 1 ----------- Content if needed A Complex example ----------------- Content if needed Sub-sub topic 1 ^^^^^^^^^^^^^^^^ Content if needed (note the use of ^^^^ at this level). Sub-sub-sub topic 1 """"""""""""""""""" Content if needed (note the use of """"" at this level). This is probably the deepest level that is practical. However, just in case, the next levels of detail should use the +, :, and ~ characters respectively. .. OR IF MORE COMPLICATED, For more complicated packages that require multiple documents, this should just be a table of contents referencing those documents: .. toctree:: subdoc1 subdoc2 subdoc3 Either a toctree or sub-sections should be used, *not* both. For example, if your toctree looks like the above example, this document should be ``docs/packagename/index.rst``, and the other documents should be ``docs/packagename/subdoc1.rst``, ``docs/packagename/subdoc2.rst``, and ``docs/packagename/subdoc3.rst``. In the "more complicated" case of using ``subdoc.rst`` files, each of those should likewise use the section character header order of ``* = - ^ " + : ~``. See Also (optional) =================== Include here any references to related packages, articles, or texts. Reference/API ============= .. automodapi:: packagename Acknowledgments and Licenses (optional) ======================================= Any acknowledgements or licenses needed for this package - remove the section if none are necessary. ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2792614 astropy-5.0.2/docs/_static/0000755000175100001710000000000000000000000014623 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/_static/astropy_banner.svg0000644000175100001710000005274100000000000020403 0ustar00vstsdocker ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/_static/astropy_banner_96.png0000644000175100001710000006432400000000000020706 0ustar00vstsdocker‰PNG  IHDRå`#:jŊgAMAą üasRGBŽÎébKGD˙˙˙ Ŋ§“ pHYs × ×B(›x vpAg `rügģIDATxÚíwœ$EŲĮŋÕ3ģ{ˇw{9įãā@‘ŗdQ‰ fE@A@AYD%‰¯‚=X $A2‚ä;sŪ0ĶõūņÔ3]ĶĶ3;ģˇÔ~î3×ŗ=Օģ~õÄ2ü‡’ŊšŨ$ÆO^1á×7ukRJ)Ĩ”RJЏ6[˛7ęWc‹Á`Ü_‹Ĩ<Ŋ]š/Æy4đC—z %SČ B,ÖĀ|cSˇ8Ĩ”RJ)Ĩ˙EÚ,AŲūš2ã lą„ä€!ĀB 0´’!OK7 ĐBĀZ˛äčKž5_k@@ƕ2Ë䍿ôMŨ#)Ĩ”RJ)ũ/ĐfĘöWîK´ƒČåf[€î ÖĐl ŒÆ0 zu@ ō@+°X ĖĮō0˜ŧƒaĻK')×7yfŖĖ›ē—Rhllėđ3MMM›ēÚ)Ĩ”RJíRvSWĀŪāžäPH„ã€ŌĐ@wö>J–Ũ°ėŒDuÅļC›‹Ãˆøđ,oĪO’å, €f`8r„ŦŊAž2gnę^KÉ#Uc$Q¸Š+—RJ)ĨÔÚdœ˛ũĨ˙`ČR‡%,ŊũŖ0 Œ"2؊ôÁō1T\œëÁtģTŸ×g"n\ķ] ü¸ƒ€g°´’B2îš‚Ņ˜9kSõŪ˙6•ã”Sn8Ĩ”RúO§Ęö:âĐ*`\%'ûu Į cåhC×@AŧÜ~; …‡ˆ@Û̊÷=ôĘ ŧûˇ`šË ,Æqåaa[˜ŗ7v/ūo“Ę5ĀÕĀDņ ķĀĩĀASSSĘ5§”RJ›=m4ņĩũ…û-ÂyŠYV-m|8 8ČbąˆžW˰dÁ͸gĢÜLd!Ÿƒ†ƒĄaĖŋŨeÆķȸō ÷[Wg×`ø-°Š€ĐA4`¯sÎÆęɔˆ$%=/ŊđÍŖ9sʛíDJ)Ĩ”R% Ö?‹öÉ^Cuh'ƒ!äXōŧ‚å/X%$CHÎņÅ!YBLėCU†ŠyמįÃ×ËR!Ŧ+MĢ+×Ŧģ†XrXF`ų–7Īē­EHāDÛØŸoęĄüŸ¤~G"¸œģæŨīšM]Á”RJ)ĨŽĐe{ĩ|<āÊÃČķO,÷b؁îģ”ÂŊ[°WÉ'Ĩ GNt­œīÄíMĨ(YwÍt*ķ”RJ)ĨML ”í•Dā ĒōĀVÔđWB%dOÆĄĀL ĢįŠ‹¸ŪūĀP ģ”ētŽ?āhčY ¨÷ą÷Ŧœķ XŪÄr †ŧĶ‹5=ŗWnęaũ¯'”!ĩ˛N)Ĩ”ūK¨ËAŲ^!Ÿ‚m´rĮ†ø6–a9Kہ\€%ŽqÄqP^ģV΃•ŗD|ũá]@ė">Đļ§K€íÖČëæĀēMƒˆ×-°Üå{Ž-QŨC°—oęĄũī$gaeÛšÜRJ)Ĩ”6/ęRC/{9Ī"1¸”;ŪËo€}užČxˡÅ^ĘĀf×ĀÉo@΁°v1´­\ŗüŪ0ŦjÛ ,äZ ;ė*°K*-ī~]ŗDzĖK-0œN mÔ8Oiƒ_k˙vW5ōJ)Ĩ”RúĻ.[ČėĨøđ8¯áÃW0üčŽ%į€Z}ƒ“Ëī ¤™Ŧpžĩ­pÂë0`K05Šc]i^ú#)ČKxø¤Ëß[ ƟA$å@š¤/ęI{Ī&ôT1>ėįvĮŊŖ}\-U°fbb:?\ŽMøÍT”×úÔĨŊ<ēēŨ)ĨÔU´ŪĀh‚ŋ\fœ“ĐĀ]öp!AÚįŽģ”˛`sŪ2P -­ĐŖķŒßV-„nŊ Ļ›<’o…šīÛMđÖå°b5tĪ@ˇ`›!\DŗŗHj°ÜF _ĄCāķÅoEl->Äōx+`œëķĄ@Ŋ4˜` ãûm÷iõōę`$,úÆËĢØØÆÕiĢc° ˜LŪæ{ų”p˛Un2^vĸ<(x Č455ĩË)w˛âä÷íX`?×'}]˙Īū…„u]YŽ­ cīƒZ/$ČÎG\}Ü8hŋ‡øg/ėLw–bVobÅgJ6Ղ]9āܐ œqJŠÖ íđ5à Čģ"F8qąb×r¯bÔ3F+BĐōŊ`ÁpúS°ÍæE¤­ĸmŒˆēW˃÷ū¯˙fü˛Y¨螚—Tƒ8Į|)†‹ÉЇuÚĐË^‚/t@9Yøû /ˆ.†×Įæ(‰a{@˰ī90v7šgcX Ö­}Ŋ†Â^'Â.0ũ xũ>xįZh  ÁHڈü ‡ŠI/´đ‚1í ėCčk¤š,Âŋģ˙-ā2dŗ&ô…æ3šŠ>Ö7ėPĀ÷ōęZ‘SĻúČFi2p9Đjdj™ā˜õškā?Ö¸$įcŽ/F¤7•6mČâįČÂkc.>ũ­ø0‰îvƒë§žë iY#Š‹JĸNūAÂæ6Ĩ”Ö‡:å^ ä!ėVjČ[ËŅÖō°ĩôą–ŧĩd­ÅZ‹q6ú'ô>ôĀŽ;|Gl]OCĮ%{k{ā1Ba5õ0~_8ūjė7§`ū9ä,Đ Ŧ‰û4Ģ?ŗÁ‚ąü†ō&+÷ÂvtËMMMūŠ ōXā&dáû.˛8hÔ*ŧ˛Ū5û"€č‰čúK ØĒ4pŌEh đ,p6xúÖéåęĸĪkļ@¸÷W‘\šBŸšŨ5į}*éˆĩų2ĐZŠLšX^>Đö‰•{3Xĩ.nÔ2Ū§Îåņž÷\šMO/„“äĐ̃Ÿw{}ŧĨËį ÷= zSũ¸û4čīōä`X˙|ŠbIFņˆƒX8xŲÔ÷#RA”ãáļ˙ĖÅĀ— ^oŒqã Čm]Ymˆę¤0~)ĨÔUÔaPŋ„ĸ‚5ËÉ žq‚ š×„Ô™ŧ ɘkBŒ a“}Ŧ÷É-Āԃyöģ˜eŗąAqÆāÄ×îOå AĀŲĖ q0nl+X[ĩĻôCŒ ą6$°!92†üŠž`ķXŖļ ÔØØč/}.ôM„CÖͤuAĘq->(ųāĻĪ€,*_ŽĢfxuRmbÕŧŗË˯OŅt!_bĸ€ĸā‘C¸Î'ŗ8WĨõ‹ƒņęå×Q˙Δų^žíÉ0‚X^~?ǟtđkākîģĄX UÄų3‘ŗŧĩâå…ā=‡Š’4îņ1÷ËĶ>VÉĀgÅzøŽŗ_įžŪØüx 0­Īkˆ¨ūãˆūgw=ø 2ŋĩoZÎûYü /hƒĢ[Ŋ1¨4tŧē‚´­Įx÷@ô÷*!I)Ĩ.Ŗrx!#A­˛ĩ|ÂZ~o-Įg8™hu-įÛáO 63ģpöšģ\‹ÜZ`ãëPļÆ@`?xū°/dąĘÃrQĀŦ‹ū•Ãr¤]Ä)ā$ !„ßkˇ›u19¸ˆŒu‘õAXÛ8čĄß0ĐsČA'-øí-ΚßMĀ֔Š“ĩnūæÁ˙XŠ9jƒ—ČŅ™Ū@””…Ĩ)ŽSR=“B˄^>!ŋ^Ē×=9LEU6žĨxIDvDdŋZķŠY™‡ˆNúI`{×/~čP_m‘$ČÅŌā=ŸC8܇‘ųÕY`ö׍:dsō,žuîū“ˆØ}ä´Žŋ™‰ŧc&2ÉLä-dS÷C`ā8`‘âGāëëĩ%Ėڗ/!›‡Ÿķį@GŨ˛ÆÚ"¤}ŧû÷ûe¤”RWRÕ ~ÂRf2ōaČŪ„ÜMH—hˊĢ;ĸ6Ŧņuذ›\mF8Ô΂znļ÷ė3įÌ7ÁŦĩW\‰&ŊŠ]ļf6ßZŠî>ĮŒ šK ¯öđģÉE8ŅĩŠe˙D¤¯ŒWPX-÷Y? JžŪ[¯:ö?zĶžČOīãNȡĀËÛW™Idų=“HĢēGë}¯EDę×PjđåsĩZ÷$.™Ø=˙Ėl˙ãsšQáčŗ=Žîr//0­wĪęWĘÖ6Bũ‘DzobũŦyûcWWäŊôžZ!į]ך§“j,G_F€qW÷÷,āXD§ü„ģ—{tô!šģ!pb úˆĢ[30Ņ—vūÄÂW“ˇģĢęßĮ‘Ŧé(iŋŽˆÅAæō ^y)ĨÔĨTũË  y˛­ ųŗ émCō6$č´ČÚ }0f&‹ ļÄØ!˜<˜| &׌Ɏal? Ŗ0Á8ŒŽa ÆÖv ŦļJ;˙ä։YQ;N>Xü˘Ũ΀åĶ1ÁĀbҏ˙‰ÄæÆXrÆ˛ yÎr|LĻ’ĀËãTT?ÖŠ\.Æ3{+ākßã€ķ§‰@/ ˜—ßVĀgŊrˑ.ō§iīÄŽÚĒø?Dē=˛¸N@t{?Ļ{eĩ"`ņ*ĸŸNĸ5.˙eîŗá4ũrã3DĸXûh>ÖåŨQŌ6E€ŖžÜ0•c^ĖņĘYØËŅ §ØFŠÕ¸˛ÎĸgM՗€/ ķāADoëģ$ųc¤soDôۓ΃K8Qg€XĶī„l*tuƒĄ™X$5đûj9đidŪvC8æĪ"bc­w9nų/ˆ•}āÆâ8w?HxĻ]ōŌkūŸö~~€Hz‘Z^§ÔåT(‡įŖËēÁ’§–?aâ€'c"C'Ēū˜žŒ;ģn9vų|ėüi؅S`Ũ\0­2õk‡BĻ´.ÂŽœ?ģdvÕ"lžcĀ .Í?Ip™[Šé1ûúÍØ?í ¯mŠŅ€ĩcD_Û>}Ļaļe%ØÚō‚Ņč ĀŨ;›áXō…ßČ3ōR|1˜QņŽrAG\ĸļCĀørāžĻĻχŽãjdą<˜G$õÔ_Ŧ?+ˇÜ<p4IsGķŋ‰! ¨´1Žų)Ō§#\U-X_B€Öį(Õ ęJ`8ĀžSĄÎúüЈžq×Wūg‚ËķĒXYՐÖq‘ūT7RÚ×÷ zÔmˆ|ŠwžŠˆ[ĩĪ ¯@ņĨū˜) ŋޏÃčúû˙nņr7/vBDÔqK÷,2ŸvA€\ëĐQŨ˛Ö¯ą{ø¯ũۖÁô,räüÂ2Y‹ŠŽũæŲ{á“ō.[ˇžZœRÜD†`F9éÁėwöųŸazĒPF‘˜ā XŽÃЊ…đŽ)}ȋĄŦœįŗČõĸgÖŧ´Ã„g•j˙9āŲ bc_÷Y‹ˆ–§AVæžęˇ_Gô…Åͤ¸UxYžâŨ+ä2ÁJtąŦÆĮž ‹nll,7G ÔŨ¸e¸öëŗˆ¨s‰×ĪaĖz]Õ žVᒷ#Úđøī•ē0MF¤kH(ŋN1@ÛąHŽëŽuÃØ ŗs´-ô]žČĐĒ­ųÄ*;rb 0ƒˆÕĪ"2¤;e›đœođõ4"!ÂõĶßĢm„RB]Žô~ūŗģVK=Ĩ”:CļđÛčžZFZ>Šˆ•3ĒngôS]ļj[1û]{#ˇÁdë„KUŖ+ek Áļ"+i/O#˙™>Caįa°ãĮ°‡|ķâŊØg/†|=Ļ×HČÍĮ[+"j›‹é3ûč0á`ˈmė—Ė„žÃ “õ6ōŸĩ!Æd°û2æĩŸE§OŲŠī§‚ÍvȎ"VĩĶÖĮ9¨"nÄ_@c`Ļ"Ųہķˆ|F‹†ŲåNĀ€•[”kÛŠoŋø ­K,Ž´n|WĄpŒÕÁz›ŋo*Q!mSS͆7ęXdîô8ÕēŊ@Ž-I~á:Ž_ņōÔkŧÎßEDũEų'ÄėÖM’Îö%Фˇ+ „ņ3W÷ŽrË%QÂ:ĒgõÖG?Ѝ4>ŠYTĻ~ ’ˇō‘¨Īëd›BäUĢëD__hkĒONiCPYrx6‘Ģ†:,7`ŠCÎA÷ŸHšü †a×Ö`ĪÁ|ô\Ėw?€“~Šŗ#djąĄøJŠøØƒ L€ 0&{&(Ü7Æx˛=‹ CŦ `øÖ˜c€9˙=Ėv'bįÍÂÚ!@¯„ē9īœVā‘›€ûÁ+pŅhxīŸ’wA×L¤_CĖā-āą‹W‚RIoŽį+[Į\ĐuWĐæ'ĸīRTÄ+ûGĘMg‰â_CŠŽQģrLÂīqZRæžr…!^ĘÉZŠu‹-]p@Æ&ĸ¸[ՙD!=‹ŗBlkퟝI…OIgË?}Ļ!úN7 ī":gHV'ä—ĻO–)ŋCÔY JxîwmE$4;iRåfŊgtÎ>ˆ?‚¸~)—[U›bq¸qĪ+ãō,‘ę!Õ'§´Á¨üd Ņ`™š˅„ėHHņš@.Htƒ`$vÁ\ĖđŊ0ŧŒųėOač–N",īQdĶãVãžäĨ58î!fø6đĩß`Nũ3fŨ,ls-KšmĻG=ö­kąˇ}nûÖ<ģl&˜ :fŊŽ{7böÅļÎ[Gō‰%pđŗ!tSžYõ8‰Š•<Vqp\Īëû*ĪōîõĻģņƊ“>ķalŪøâčYĀūŒ€ŗī/[¨—/’VĀō?˙a¤"áģŒjŅ^h_9rŋiß,öl<0DĒ‹LĨü6=wğMHsxėīMEZū[ˆš‚ĸnZL€+‡Ŋ”bƒ¯"ÆXaëæå(īž/ēNšä”6%‚rx&2ÍW8}™eg,8ĀÍā[Z'éų!ØEŗ0G_gũŗåîōļ…Ą šD+oųė¸fëֆŪĮ9Aûi}—<…›%SƒŲëĶđ‹ÅôŠE”`ĄŊSĶ€}áZlķ‡˜^#ąķہŋŪ‚ĩy1úŌ#ÖJūÖbú ƒūL–3°=nŲ2”=\?™ā—åĻ °R—ˆØw1‹ģœ\€„,;æH †rę ę×ÎˡæöBÜC|ގĨxsā×9ÎŲ˙'’úc_˙ĄĘÃ=€öАTËPũh‘Ž>‰ŧßüq{R˙oˆæÃ^D!@7 9 ķŦĖô귝ĻķÁÕGßāK77E|ąũvļGšn÷ą(×NM ŧRÚ ” ė|ˆhiķkÁfÚã–C×O‡+XWÃ)'ˆ¤•ëôõĘÃŖŸ 1“˜ĀO"zļËל¤1×FÕQyá Qâĩ^'ø¯ Ģ\˗KՇCū^ĩImüO!]œ_@ĩ(^8ūŅĶoéūN Ÿ íjFė^Eōę Fo&<ī—7 ēlâņĐ:ûî ÎĘŗŦ•nߞōō9Ékk5ܲöG#Qā–§ŲģëĨ”ŌĄ’E8< y4ĐE–Īa9ÄrP['OĻvM+Ļ{Ėo`v<:S­ yŊpÆéŽiY]ĩ ;:vÚØ^ÁÎxģt!vÍ2°š‚Ø[ē8S[ČˆyLŋáđõë1Ŗ?…]>‚~ĨŠÜB[_ˇR ęą[ąš–HŒmÕėĖ陇Ãė~vųR`@yßhé/íŗ}ą„ä+ŊŪ @åbJ— –¯“ņÚEˆnp,‘aOüđŠrĨé€HŊ[\õu…b‘šēéäĀ9ŲLBt›QlŊúŸ Îڏëb}P-iú>DVíIąÃAŦâõxˎŠų5ĪJKBdƏÖg6UÂ4ī{?"ßåâN,|Õųû{īįcwA7ƒ‰”`u틮īÕĸbåĨ”R—SЏRd$ĐE-†ķb)’'vĻvõ*Līmáœ{1Cˇ@ÔÃb­ÕSš‚@,Ɩ/€Šob§ūĻ=÷0ŦЁ\›üjBLŋ0æė6ûÂ6{Ā ‘˜ ã@3”ōlÄę #õč={Úo0??ģėyqŋ Ës —bzŽÆžx+æĐ/ÁvûDĸr×kCÉ{ĮƒāoW@īēö[ē`ŒÃ29€Ū„§bƒ›Š–9Â1Da: áBwĄØuFšP?ÔŖ–ÛÕģû¯"ž×E7Ōr´,u—ĶŰ?\â H`‘€ģP+zļƒ.9›šŠ62¨w‘Õz9ĐXä•ÕYWœ9îš4tŪ Özlâ1Đ~đ {!rŠĘ[Skß4!’…Ņ÷˙ XÛë?UÁėFdX6 āŠč:Ĩ@E JøuũBÆiO&d‚Į%'s‚Ôc›s˜î#á[w•ä YcÂôˇąwū.ž€ŊâãØŋ|;ųaLk€Šë‰é9Ķ{8ĻĮ@LMė˛ŲØūûĢS°…ß]ˆö–“,‹Û’”ãŒ˛Ŧ€yĀHøâĩ° Ŧm”ׇkExõü€)ĸB ÅnZ—ĩ/Â)C/BÆôʕYÁ*@"Ŋ‰Ũ؍Č0ČĨč͍œ­ķŲ¯yÕ;NŌ Á<ŽBŒTÄįviZ(=J0Dô|ˇ!ĸÆĪ-v…ēũrĖ%mk=É ã˙­!E;ÄÁÆŌŽôĘ-q.tÔc=ÛÔÕäīškŠÎ7=ãÚz¯wO žB¨(ÂÖž8Æûūwd6å’SÚĐTŒ4Ē .š–sŠ\{Ãhö†5Ģá›÷`F|DĐ?›Ā…Ģ´8Qöŧą˙w!ö°MW`[[0CFc ÃtëW@~>äæJŽp&¨Åôˆ<S7ûˇëąNĀŪw Ŧ]^ˆž…ņŦĻũ¨\[īŽ9é&˜?‚áå´m)Ļ×@xūJėœŠ‘nYEãČÁĻ˙Ėį`WŦ3 ’ÁÎ×,Ûēk~#ęū2gęŽBÎĶŊ‘č,e?<Ŗ/ÖöīŠĐĖįH§Éæ˙Úš4áƒl<`ˆĪÕo‰X߃ˆq;îŋ†ēW‘ĻEŋtdŗKW5(ų}^M]6&ų\mRô˛%|ŨAdđõq$Æ{âüЉŽkˆÜÃ@æfRŋĨ”ŌĄ(‡_A—ņŒãŊŽ#dģDãŽ"?äØšķ0_ģŗÕŽ|&đ8Uõ~ŽûĝØīŽÃ>~ĻīpĖ€>ŗZg@Û,Ņé†y91´Ū'„°Uôŋm3 ŋ͝/ĻßXė߁+NÂΙ,:ā0fĄ­nW‡vÍ, G]pL7ė2`ŌkÉŊg éø]EãW.v¤Wļîû–į\n\4xÁŗˆVUûš”KÎ!–ļ7 Q×öBb.īDä÷Ų)ņgĖ ÜFuú"Ä0GëÅĮ4ú‹šŋ™hC‚n<XnÎ˙ ny}¨šŠ4]ęzpĘņĶĻ”üS5uؘÔÍûŽG”ļG*!RCGiÄąî{9ģ ?äėŽîû "Ŗą4‚WJ…ĸ Û’wĸë/Į,ĢK93ģ`&æČaö;Ē™K@Đr`W.‚ĪÅūâdL÷‘˜~ũ!7ZįHlëĘĸßä mķ m:fÄ(ė´įą?ØûᛘÃH|n­pģaˆéŅ?ĮÅę_jôU0ūZ'¯ķŋŸ°MN”JĸQÛģg˛•ŒŊ|šA@Y9ÉÁˆņÖ(ĸÃ(üøÅ>ˇ<1úÚÍ}ÎBĸsŊJ#ēĢwúē!Đp™—"?|9ŊHmø•{ö m´‡•ŖoC€ũ”žŒôßJÚFŅÆĮĮ˙ģ§>ŗœ˛=įÅä›Ißôņî5“š/ĸv žNÄĶ)+wœ0äh‰BšĻ”ŌFĄeæyĪg1ä@A"hQƒm^Žéߎø˜lĕÚ@^0.;ûô¯1ŖĮB~´ÍM>eÉ €ĖhȌŒ}FIüljcõąĐ<Ķŗ;„Ŋą—†;ĩ˜52—rËģ€Ųá`ėę™@Īd Í/ÅÔ÷ÅžķėŌ……Ķ8ĀåŖ¯qŋū˜á`›§íV9ē—|úēk!ģ˜ÛH8ĶņD‡~@1 H8Â3NøGˆ˜Z#9ųu—Q‚ß´/6_…ø‰„{¸‰(,¤od×;kÜ䃐ČXšß˙ˇŧšČ ŠÜfd ģŽĄ‘¯˜4t4ģŨL í†{ß+×'gYpOp߃2ĪԟōîŨī——ę“SÚMÎaøG~ŲSŪŊÆÄփaū:8éNĖĀ‘N<]lÔUäEŗāŠS°Sà ÍĶ Ė•ú:C$,į˛ÅØ3°ŗfag{Ÿ™3ąķæBK+Ŗ$Äehĸû a_pĘß@ÄįßF‚A$ņĢâS†3ŠÂ…ĨJÚÔ_%ŌqYNy}ŋŽį–ˆĖĻ`Ū‰rv¨&@ôÖ_čMŧŌˇb īŪ|"ŖĮjH žūäŨûœģÆ}–5Īũų âBöĪX}RJiƒSž‚ Œ%$d0–F5DJ+Ķģ|6f¯S`īÃ"}­ãJ­ĩˆĢ—Âõgcg>‡é;Zæ”ąYČ Ã.^ƒ3ŗĮИ¯ßˆųé͘&cŽsåK˜ķîÁy ô‡5ģp>˜A õ€yfĀ8ėãˇĀķJ îXĻxŲÛnŅZåķ‚~d$dÆôwŧŊĩŪAúô^¯’EwôéS,u( ģø9’ĪƒU.x9â5ˆ‹.Xmː•e8g]<dKs-Š\ęĨKŌmæëģ{ÁzļŖPÆfĘq+Nņę›d=–(6yUØáĩH˙ĮŸ÷˛lœÂMÁ);Ôú 'ō›ĐĐ´w¤×6•ˆú’ Q Å7|~ŦkĨ&dlRŅuJ•ÄÅ@Hŋû 7žĪk1e`érøøį1ĩõŽ?&€ÍÃŊŋÆžōgˍ1Đ<ŊÔ!#čļvöĖ§ÎCO†-ļÃdk) Ŗi-|dė!Ŧũfę;đܟąŋru˜A܁Øjh™<øsėŽbúŧđÕ.ĪĄŖ0;|ûŪũ˜ž} ŋŧ´‡,bb˛b­w/Ē—Ä5؁ŖŨĢ_SÍžē„{¤aãܤŠ­ī@Â]—ˇ!Ōö@­ĖIEZwŸ‹nė&JÁGۗAÎĐŊŸĘū˛ÕH6ÛÕ$ĸãûÅēLŸôˆÔC1ĪšJ~ÄŪ¨äeg$ĸ[§ŠsęEDoĢĪl*ŌuhGœŗ!˛Š(œ!^åŲČjđõr^÷DoüŽbuJ1ĻSĢkKë:]§´Q)(üqnĘ%Ûd.švå,ĖnGĀ{Dbë~ē•^{{û0#Æ Į ¨Áļõ‡%s0ܧ_…ŋ3dj\ŦkëÅŊļ.r—ÁÔ÷Æė°/œvæšw1? ;k.ļĨ˛ƒ!ŋēÁžū–ĻŲq›QŊtĻŧ”RZo “#$Ņ÷$ä įœ$Î5}å€ēCŋ‚Šī…¸t†Tę‡lW-…?ü@„Em  ސoĀ4ΆË_Âp X§‡Æ;=Ę?ŽQcZƒ;eĘ˜`Îø9æŠg0=bį-€ėȡ ųÖķÉ-W0ģ¸3QSF¯Ü"P˛l:´U0ūėŪÛ9”´@BZ‹7'Å9!Ņ‹ ŧEî ˙Ļ‚ Ą*uŅŠ&đB"%,ô>מđ#á0  ō¤w„ī5$P ėËY-ãõĒo(´Y‰°][´ž˙^Ąü!r&ō‘D››’6%Œ{áŋāîų’ß~!đ×Xßm ō#×îŨ9åŦĒŪīžÁ×$÷ũ@`kŠí4@bĮ+ЁWz"TJ˛Á]~ްĐîŠčŽâVČÔb[į`†ÛēÃWâ|\čDģ˙xûęķ˜ņŖ ufiÉ5C°Ķgc.}ŗí‘ĄX!L&E'@áéŦ‹†rŌÆ`vÚ{åã˜?\ŊījĖV[ Ÿ4åUhYu=ˆG`Ȗ"vļåÄÎîfËZ ­éuŽŗ“ß3™ĘĻUÅ÷ZŊKJ]Ž[Ņ´>']l0ÛNI9„‰tË4š‰ˇũ+ĸ  !1!=ë9ęÛ)V7Eũã.—‰ģãœĨnD v‚S%`ŪDĮü6ÄGVÛĸĶĖoÛeˆ”d…÷\R›|)ƕČ&/‚Õ7üâ čĮ$ßh3¸Ę#ĩƉŽowŋw†‹Ī Ûå?#V$Ÿ.wŋ名đĄ.ũZÄu RJiŖR~Ÿ+Ū+fu7÷†%9Øũ,Ė î͎NO˛ÖqÉ+—Āƒ× ŸŌšĀ%g‡agĖÆ|õ˜}Į†žsė8ÆD*9ŽQ,Ēé;Nû æ´k°|€éšvæ}ØĩĢ‹Ũ™|Ęfäĩ·e¸ZÄ­ëH:‘ǤNe ÆđUKÄ×JÍD!ˉeđîųŽO÷ˇ–üD]GŠjGH÷ķˆô ˆ/´Îh𤺓¸ĩūŸđî'҇Iŋ;ĐÔČzŦāÎeüjŨ2Ņ Ëāî“—!%ßČë_Īc˙õ*ĻÛhȡÄĀŠšį `v…{ĩ€ėS œ CČÖaNüæœ[ą“?tÜk0ÍWųŦIagąm`ēõ)ŖOvuȇbĘT>xˆ˙™Q¤"pššëbĸ#ë|°ņ9ŌŖ˙dåÍÃĻĻ&-Yīí€DÉú1ÅqŠĢŪũĮ †Tz­ģ׆¸mŊœCyœŸĢ'žö{åÛĀūDâoŋíĘÅ˙Ã]“Ŧ€5í*g" üoĄŽžaSS“Ö1€Rĸ(x#“ēī¨uēī(čģŒåąîsˆ@ĮÛ˙„x?‚¸—ų€ėsÉĒ“˙ đ>Ĩ‡jÉ×Í\ĒįX‡ šĢĄE¯A6Ē5ÚSãļIDK늈ąĩîū&÷>¯=)Ĩ´ŅÉå,!ģz`a‹$­K0ƒ€ą‰r(X!;.9ßĪ=€ÜĘRË ÆÎķ™[0‡û7w}ԸցXŦYĖ‘_Ā|㠊’Šđ~åBgč¸PžÄ6YĸՐƒ-(Ã^­^ę 3_θK˙evŅÆ‡wĸ ™$š éÂzqčx`§ÆÆÆmÅæDDT÷2~y/ߐŗˆëf / å‘Ž~ޏŦ\ƒp§cë~;@‚_ė‹ˆ!¯Ļ˜ôĸWoĩ´ ËĨļįņXģ|RŽqwÄpį2ā¨ÆÆÆC€Ī gOŋF$ļ\_÷Ģ“WžēčÜL$ ™ę•ĖŊü‹ˆxútäĀ’!Āķ"ˆ{Pø€\ƒl¨~ęõag¸äĪ „6Š>) Î ÷k\>…HvrČVųIä¸OíŖéwŊ´Ú~ßāKõėŨˆæĀJä*ôGĒONicSÖšB…H€?ęOņ"Ô`׭Œœ}¸TžŋŽÕųŗāå[ĄĄrĢbËmĢEÃĩہÅ51ŪēaŊ{Ղĩđ„ !ČÂņߘ6čÖÃ5Ęs¯RjË9 ĻI†*ĶM^Õū[BļŽT„­u[šX– Š’Lē`ÍÕÆΤ$Ļ/Ŋá„}NŌÄŽ!âÂņIdÁRũ›oÁĢ€Ŧ‹žĻŗ]ruŌō.C‚+¨‹Ž‚„rk#ŗNxâK­ĮėõBļižH08úũ:/ī|;îP÷įSšĶ߸čÜ|7ÖēąØá*ƒÆÆÆMâŸŖĶí‘÷Ņīkmˇ?ž{"ĸפ NŌ1žĒGÎ"[ҝ ŗŋŗnPmˆâqd“s8k=lŽŲˇ{ØQ‡h÷刚DëŊ>ú]{?ŠpĖ[#§œõGæ­úp?…H_Öˇŧ”Rę4ž˜z,–nž(;&ēî'Ļ ;~FŦŽ­ˇ˛û@5k:v2˜ė ČįŠšÎ vÉRĖž_‚!˙}0v—dUkä3ÖB}ĻÎŲ%AŅüŠea.YÔlŗĸ‰0(jkŌ&aáL'o­ä •qÜōTåžÃã‹rŅ…ņȎ]ÅÆq@öŖ{å\ēîDĮ9ĒhR˙Î Ŗ7ĪËŖš.ִÁSŧō9n_ŦŽ"Ôdƒ7‰Ę4ĐĨUî¯Č^Ž(ļ÷}ˆî*ëĩü×`6”r–>0kŲqQ/ˆtíŗ-ŽY§nŒŽuW ŽíŅtĒ×vč˜û1Æũ͙>ĢsĨ͍į+ŪØu†´ŗ(˙8˜h.h›2$ëķ5Ũ—‘QŅ›÷EDúR̝'ךAL:īv÷uũü1¯Ô79č‚ōRJŠSxĄ‡T6ōĒŽqČhyRĪ-VŌīŧë€ŊAœ/ļßSĶ­āūTˆK ÜŖy…s—}Kéj(Î]wīũfcéŪ{Cā,ßZÖĐ  æåã9ģčeĖ›į ÆĘ€{¤X@Čûz/pÃy‹ŗrĮ =ž$ĘTŌÎoŪĶ/‹č ÷& 9XmK]Đį Á+^ĻôüäBWP|vr‘c™÷ģO (ĩ@|ÍË+‘8Ų –Ø*õ7šOāĘVC¨Œ×Ž]ēbš’bj‚ rÂŅ!WWCņ&"žĘÆ>J7=ž}Â%N$fmŨ )AxŒč$Ĩ]ņų㈅s/ŧ͚™X´! ÉË#ˆŪ_Į#D6 ĐÖā _wEøē‘HØ(<K›RJOĪ9ŌĶs–yŠąTCCôt 8…đÁ[Ęš–d€ŗĀČqĒd°ŋģ f(yú'=UKp1ÅĢŦËĮj}W,†7šD+Úļ2™ģmk!טR=zV-…9oē-å@9t×7Y…åXJjõĸ÷j!æøb‘d­Æ>ē8˙ ‰‘=(8Žbî ?g¨Ĩeŧƒč…ŋŖé P!@û\|ŌGĶh[ ˛˙ҁ.÷ŌĩʅMAņueúŠŧģ´š?ŅQ}&ĄĖĐK›Ôo]Ŋ€+`Ŋ‡Dvģ›â͎ß×ņöÅīųũœE6Uû"@¸ž€Ŧô>Âmū„("Ø!×ų"É88ÉÍqČÆëzÄ7ûI"Ũw ęķpDZRTŋ.āZunN" ”2‚He÷Â2¨d%Ĩ”6 ų]c¸:ī“—éÚHôtœš×ĘÁ Ē[/ųŧöĐą%y¨ģ’]žūz%\uvÅâØŒĐá÷E]­âœ÷;o`Ÿ{ S?ōkĨØeķ1ģž„é?Đeåe5ŸĨ‹ąīžŠé6BōI6ōŌī˙.ˆ˛Ë/į Ė‘8Ё`9QŦ.žĘ)Ģ…î7‰\A4Æ˛ęž•ŗž—ø'X`_‹œķü`6ÅŽ8$ÔËąÆÅ™3ŊæČiRÕåi?=‚ˆMÕĨ¨R?ų}Ĩ#°ŸÎ–ņĩrpqŽTû­KŦtc ¨íZ†Ä8oDDõ~_—k_R?ĪDtÕEBuú!&××?[Īzž96ô~¯_‡#"â+ Ŋ1<Ņãúˆˇ#R‹'čz@.dåŽjđåŨŊ~šTtŌĻ"˙‰N9éT¨0/KQŋa%™üW.…šA]„ëbēŲ@¸Îžˆopi&B˗cW…Ø×&•į{ĀŦ*ĒrÍ>ųe´6ÃwĀ ˇ:™Kęvv;ęęŖčeqš1E–=uËJæ”Õüų‚čúĄâlĘ,Ė˙@bøĀũĻ ā„ør :>~ŅÛ6!€˙w}ŅaįÚŠę3#VģÛ#áīA6ôę’M¨_€čļFšė€͈TŠ2ũô"bi}>ØÄRžŸ2ČFå=ā*‹-Ÿr}ú€ë/ũ<€ˆnõ$ĄõæŽڅkÛCˆA×'ņëėvæqcô0p˛§ßqáa™2;CšW­ëĪcnüwˆÚ#‰‹×ë,¤÷D¤BĘŠv) 'ˆ°G,Īĩīf‰āSŅuJ›”˛ŪŦ­˜2t–]™„h*jmÅŽĶŖ7„KJ-¯ÃņĒŋo’/oa˜=ļÃ>ú;˞Ũ‹oĀ å@Q šSĨ!ąĪ!‡ĄDßzîoØŋüŗŨ0h›đ‘ĨĄØ}ŋä|•k~ë ˜oKZš Ō‹ÚŖá‘â>ŊŸņ 'H5¸ö­E€î=d>Ŧw?WAžŪZ9Ī—Ũ§2W' bâZ$XÉLßBæ6DÜažn nU#|ũ‹č8ˇņŦĐS.9ĨMI&üdaá~ q¨7šø“‚=ķĐL˰‘ŅÉP›<ķėÉã1Ŋƒ] Ö[LÂZlÍZĖoį`“°•&–ĮÔIØCˇÁė0 ‚Vė‚ŘãáŋÂė~€XgëŲČēTr™ōŲ†!&“ÁN~ Nž€8Ãb Ą2‹ÚÛ;o)擧ÁÅ×a25ÅyĄzé%pæÁØ9obēu AŦDF6AB@”#û÷ÃŽ[ ?.˙)œp*ĻĪ€0›Å˛˛úŋ‹Įm2ė”wāâ¯aëÁ˜ĩ<$‰‚ž0m)u2ƝZe’ü˛'ŋ‹}äMĖŪ# u6퐎†ĻŊã!bœ ;¸…ļŒëNÁVžL>°žâšNÎ_đ+ÕMĶ—āúY…úTĒK‘ĨC;ũÕiŊõĨ2R đŒįÚi_—õsÉ÷E7€IđUÖúmP0Ž‘n*v"ä÷‰N]KE×)mrōÅוŅ6ˆāŠĩĩ|šÚZLo°m+0™ŒčĄ dEô=Ü)ā™žũá#{cgž€Šī -K1ŲVØoöŌīÃŖ÷ĀW/„}Áôáēē&y‡N5 äÚ°Ī= į‰í9ĶĐZWˇZ—ŪšØ31_?&ėVČOŌhūîũ~î && ŅÕåi÷wXÍë_fíđÂą!ãŽĒÛŦO§ë˛i¯>›lŖĐÅ@uŗ¨§ˇ!СŨĢų ĸbŲ$‡q¤”Rœüā!Ë*Ŋ2+Kį—dRā ë{Á€Ŋ`Ũ:°ĩ žÎÄΞûabeŦĩĐĢėđQņ4õÎÆt5Ŧ›‰Ųafųlė'b?ŋ?öwŋ€ˇ^ÅŽXâŽr¤pÄŖDæČc—/Á>ũ0öģ_Ğt$vĀpL6hY]ŧW÷=ké!šŽĪŸ†ÉÖz'XE–âƀ; ûĀ0cëĄuqšžĶ`,2 +nhÁ#¤”RJ—Tt´ûÛĶØJRJiŊÉį”—¸kōÎÖ:@]žØģ‹nÕŗ Ū Ū|zÔ&xŅb4e2ėypiú}ߏÃWÁV в0z~Ũ\ČvĮ|jŦ˜…=īXæĶ;ÁÖ`Ėxl˙Â‘Īž S߁éS°üvŦÅė< ÚEÜ~’—o1؇Ļcūp#f›ÅZ;î'mėšŸ|žë-ŗHČ ĸŨųoŨ]Ãֈ+Ĩ”RÚ äqÉĘ  9°䜿—Ũ÷TtŌfAYl4–z÷KĩŊ6pv´+Ŗ{ ‹ĢQ;f ąųR[:ÍÛV‰Mė[/BëĄļ…ĶĨ|pŸ°æķ‡b'˙ Ķŗ'äWGŋå×ÁڙPĶ ŗûp0ĩ؅īÂä7D4Ž[‹aHpĮ†zĖácäpŒæ$+k¯ÅŨ‡aߝŽ9˙TøĖÉÅŋ+—ŦiķįĀoĪ’ˆŊ- K>„ÔEč5Zų›ķÍŧ…SJ)ĨEúfžáŨģÃ]3HÄą”RÚäxâÛŪ÷?å6éšØJ¸G÷}üîrÜBPŸk9fP?ė_7["<Ä ĩlbúĀ×.įĄÚ!‘hŲ¯OŽÖ́uĶ0ĩYĖĐ~˜]‡b>1ķ‰1˜í†`ôÁÔXX;Z—–?J1Ô ÂΛ‹Ųv78÷û˜î=Šģ|}5Ā߯>Ũ†Š^ÅĢ8Xˆ^O – ™ĸ€‰)Ĩ”Ō#KV¯C‘“¨@\âîtßĶ72Ĩ͆|PžR1ĸWë ąYü÷ãØukÄHsņšÜQ#%ŽOë:áŽãa6ŗ âøĘ?+$á:Áė{ æēŸb˙:ęĮDáíKÂ"Q´Z—Âēy°fŦ™ÍķĄuyr îøķŨ†cį,Ä Ú~yfЈČåË3+y˙Mė…§b(e–uEÎNžŖjŗ‚'7õ°§”Ō/% šĄ‹ÕõˆåHgĪiN)Ĩ BŲ(“u Izå|3ĻØwŸĀŦY Ũå8ĂčYyÔ8ˁû`ß{ĶPáÚâ|ZK0ŊnÁvĻĄ€]áØ)=P"_>3åėŋĮ2VOīx +Ų~š:¨Šũ×tĖ~{Ã5ŋĮŒŪĒ2 ˇŦ…îz)'ŌÕ74@^ūe@†,ųMo‹šRJ˙ųTá8HŸ4ėlä=Ũũ!‘Ä į4§”Ō†¤Ā;(a*!K<.¯˜[Îį nŒDTžōž<=[‹éŪ8^Ļ}ļ_)gš[ƒé;{Į?áéĮĸ|Ô}ÉVŲ0Äôė?ēķ“ąN‡úqô.=ƒČįz+}4Í@Ũ0ƒ°MĮ|ũt¸ų/ŀŦŌM‚ļõÁûą×ŨŽ;Z–U:|"KȇXnuŅ–ÅūüéM=ä)Ĩô_Gz Xā}4Ühø*ĻVÃČ~ŸčđŒ”RÚŦȏ}ŊË$OšpR”;Úõß˙’k<ˆ×>Ę5Ÿ‡Đ”‚VķB‰ä{Í÷°‹æ:áōŅ{Ļī¸ėט_üûøTėęĐ}4ũ’AˇŌ'č ŨF°O˯ޜ…yđnøÁĪĄ˙`Cvm)„ÚvõyņėņŸĮ8ÖÎN>xĸøD¨kČŗK†ØâČŌ)Ĩ”R‘žžš‰E–"øÂë™Ũ?FB•… M)ĨͅĮ=fÜTūGYN9ZWĘų@˙x¸X¯ė‰yØr<æŒ/`§ĪƒLŸnyĻû ėĶĶā÷7 ?YĐZčŅ€9ķû˜>5ûÄ ėŧĩŨÆ ×›éĻ˜îō zBļŋ€pˇ1ˆŋ ûä<ėĸ˜ß\yxĻņ¨­ë‰Ŧu¯Ą{`§}§ öč ­ Ë鐍ëš,–—ąÜJrFužÛÔÝRJ˙U¤oęW‘ƒHöąGŗ rÖšĀĢĀĨH|øäĖR|BX*ēNiŗ"îYØ5~ņŧûØF֍Äūc&æÍW1;ėZXÃgh‚ûäŖØCĮ4ZŒ¯’¨~ö陘‡îĮ|ꘒŧ¤Č(R— ėĘåđŌŗ0ņØ;ī…•õĀZ Ļ/ØŦĢ}ræĖ2€nЧsܑđņcaīũ1ÃGa­‘¸×…č_ŪæÂZ‰Íd°sfĀ'`'ŋ„é×[ŒŪJãŸųNQ8Ë?0zHcđÂĻî”RęÅb_ߍœprãFu+Šé”_C,UԎÃ?uLƒų?āT  ”rJ›eÃŊ\a×ø:â*0ŽâøĩŽ,X'Â~ęqØaׄđ“îī=÷Å|ūėsa7@nUiékgaöŽũĖgā…0;ī%ĀŦų({>Â4ôÆڈŨ˙PĖw~īŊ3ĻÃäWą faÖŽ–S¨zö†á[Âøaø0ŋ †éVīáŽ6%€|ę)Øw_ ͋“NũU Î!"˛ë°üƒ€€fBę7õ0§”R—RĻĖ÷IēA؉~ ÷ôíT0ž…č˙@‹;Ū•ŌfKÂ)īØBě[1|Åi@ÕX"ĸ ›oÅYxx&fĐP0¸åįžÄîwf˙Q°ffr 2Ũ°ų˜UKā>Į}įķ"JöEÚîjŊ`#žąÍĩB.1i ÔÔb˛5ĨĪB1'ä/"ëÉpÖ׹˙~3j0Ŧ]PlR8ņĸ`mĻbؕ<+0ÔHĒāĨM=Ô)UKÔØėâb¯gÛJļ—åÚį8SM˙#āp÷÷_°OXjlläÁŒÔĶZĶÛû5 a-Ŋ!Xá{Æđ¨ĩÜcLáXÆB Ũ͐æŸŋŲčĘŗ°SÚ I@y WØy<éž?āBQŽĀ>7s˙1ĮœäôŽĻčõļŒÍaz1ö‡—aö kį%q™PĶ€]&gáÎŋÃÎ{\ –ĐåĀ .Y&Ļ“ļÆģ,ųbęxhOŨL#Ī=÷|ųcØ` ĻoÍK*‰ŦũīĀ_Á[ŋÚšÁŠJ•^Ė„į“ŽßH_n:{4e”UũˇŽU{}?1ĢŽVL0×fxÕvmÍŨ"TË`ČģąŠf{‰Q×(VĖ1öՎCJŽ"N9Gt$}ž€Ŋ(ÕŅuØæĖĐ đ§ŋaú@ƒŌp”3?„ÃĮaëúbĖN™˛@mOlŽŧ>ķĐ}˜ÃÆUŸ+.zΉžãX_x"Äąg­ĮyەËáî˙ÞúmØe&ģš——;C+.ļžø † ĩ˛4tĄķ \æŪxÔĸ"ÎĄ\^) %,”EÆBđåvĪPŽĸŽPúzÔ#Ā´ËÛËģJŋā vÚļ-Čqeđ,5ŦÆ‚yv {~øûŧÍö†íœY3īŦė-ŗÃ-í3%Šs´ëוmôh<°%2V¯ãôââ}í*PN8×;åđ̤,p„ģkŨâm¸ å¸ņ’PŽĶgö‰71Oũ Žũ\ @šĀY.ÚûĢĮā Ã`ßq°jjrMZVc˛v‰=âX¸üđÅĶ0ƒ‡b­}2Ū‰T*ĸ&ēV<{2Ļûļ~`ķ9ėk/ÂĨ—`xŗįH9ųiŨēd›Čņēah#΁Āß:?0eDX Ža•Īi—¨{Č` 0XKJ%äúOG|,đMā>āŊßÔÔÔ%GÆÆĒÆ]uķ?īš0 +.ląßŠęŲØØčŸ)ü"p!p›øč„HĪ(+ŪŪÉrlxĐg,ėd°W=ØíĄ•“ÖmĪ&ē…KŸ¤û^Ī5ž6x03Åū'€qŒtœž>h&“Ų.]e6힯U5÷ĘP Č lá›3(t– -ŒĄXŒҚy°].ũvß0CGŪPQ°ĩ˜…ß\‹=ílĖž[`W|˜Œ ­k hÆė1{áOāžá’áĀC1=œ]Ūū6Ąˆ#ö)ÎAĮŒŅL`smØ÷Ū†?܄Ŋę&7ŗįpėīÔ§2€lĸŖāĻa8Ct2ëãŧŅĨcuđ ā[ˆ%i5/Ĩj/!."[šûÍĀī€ ģoØÎčR;*‚­’ŗīT>ĄvĘÔ(P'į#P€|ccã0 đvÕ§rŽī6DA0ōČaН#'Œ=Išíaåļsų}ĐFŽ9ņYŋMfbĮu흘O:§ |ؘ^ĻŨp‰íÁŧxdsãÃCŒ%ÄÔ!‰ŨÚf82߈_•xŲ™ͧƒķCûa<Č/ n_}5Π˕בąHHĢ}= ņįŽŽA‚#­9Uö[׎IĀÚ8¨wUߡ—×úŽÕÆ\Ŗ (îˆ,C†Œĩä1œnāW@Kā†Ēõę‡Â+ķāǟaÎũŽč‘‹r7‘žļe\ņ#ė¯Āė3VL-_+ ô kōØwbŽÚžôMØįĖ€AŽÕ-ãĀV?ž´NÃŒ 45ØeKā×ā?a¯ģ zwÃlÕ_ÎnNvyĸ8cB,5,7đq,¯¸hâovj<â“ĀįjžF&ø ČŲT‰ēĻØäŠG qŽŪū„8Ší|qÛ?aNø*‹ÂiØ1 ŧ߃ØßĄ—&¨–Ĩœŧ…Ī!BdpŋīįĄácˆ=W$úÕ§\™ZÖpākĀ8Ö ÛŽ›ãÉCĢ—ž\=ĘÕEŠ;đ>Đøģ×áÔ÷zWzõm¯MķĸĢ×Č́6öFŽ.ŧ1ÜŌß*y|L 1ō*ŒĢ?~EąJtÅĘ­˙司~ šššB/ö÷áĀˆ[–J~~čÚ´¯kŸļĢ\]3Ū}m›ß~Ž”ë›rķXÕåÆ]ßŗøœÖ~8q?û2˛‰ŽK3::~Ũ ĄŒĘŒÁYĀÕȜŋ™#åÔ`IuĐ´ŸFæņŗDī$¯!ņwŧš6úõÖīí­_Iy'IŠ:ēFAņ¯´>ésEķ#˙Ųļ’–ũ¸) ø°ĖĨŽkæÁn#áŧ‹`˙1{ėS7Úį–ëēcĪŊŗv-öŠ_Â^caÅ4ĘŌęyéģĀžū2¸ ˇ;Œ-ō:yļŪC¸…ēúkh•¤ģļt "ޚ,šČHņÉú)dąxÍå ­üÅŨÃÕá툈ôQ"-ģæ5Q‘< B¸ŌĀ?‰ČŽēÂÕo‹ˆĐîB ÍcpÂúãęØ üŨĢ÷ÁȋõÄxæd_F@Īį|‡‡!Ō‰Iîī\ßoáÆ#‹H!–!ÜĀãČáĨ~e#ƒĒ§†ŧ˜æ~ߎčeWŊę9ČÆĒŅõíáŽ?ãådMØ<`6"š XāæL?÷üÛ'ų‘Nųx7ŽËû“ŧ˜€¨Qz/šqZK;ØÕåSëæĀˆčõ.Äw¸HŌS†SŪ§?qĘJûŖ‘5J9åKnygdķM7G^Gl–ÅęÚĖAĸõŠl€ŸtiA¤Gģš˛ *Í§ųŒC‚—üčœŽH?nA˜ššČ{Hėš] vĨ6Ûg_qķíeä}~‡čßĪͅā×+bíۍÅD—î4WĮĢ‘ĩÄ455ؘbŒ›'šųwŋëĪ7(Ä]]˙ rŋ߃lë\ÛŋˆˆŪ/vuĪ#ŠVäŊÍĪ ’œ“7[ŊrvEph€ûíĪZoWžž§ûģ|WŸus1"|ŋĖ\>yŋģ#ëĮšXÚņĀŽŽzšļŒrũ}/˛žÔŸsã9 9§{™{~[`wWˇ…ą1Žuķo!"E0€-Âp;16ƆXđ×YjĐTlôeƒą¯/Ā\t懗BM]ô# ˜[›ąˇŨˆ=íۘm‡C7ĢgĶ.ejĄŽdģc×Ŧ„ÉKĒ߃wŗÅčŪ g1ˇ,—cĢŖ8 Ā×,Üj2ų%ä3$EæŨjŗ,O1pŨYDOC8ܡŨDØÍÆf]Ø..G@į7vū./.: !‹ædqŽG&Îõˆ.['kY`ŸGīŸ /CƒËgd1û˛`ws埉ˆk‘—ōdŅ9¸Yč÷ûÕŽÜg1r›Œ"ųȆMDtæ×xíŦC8ĪyȂĸm|ŕ}›ëĪfD¤Vįî}ÅËãpÄŊí(oëîW¯VW§[‘MÆ\`Ž@YđËŲY\Îry\īÚĄā^‡ũĖŅ3Ž]Û"bFÃĩȂõ˛W×:āvŧךüzŸAdMžéĘ> ”ąî~=œhO<[†N€˛ŽåŸ\}FéZŒØJ܌ˆuÎöFĖ#€)^ß/qųLF¤P¸ë9nūžėÚģ ŲÔdŨ|ũ7Īrã0˛ Ú „Ŋ…žŽÍ/øoš9ŋĨô¤5ėŦAâx_îúņfš.´7˛ 9ŲxéX|ÃÕõcČģˇ ōNnįú,žŠË#›_¸q[€āO`õį›Ž1 \˙láŌëFd.dĘ-f‘wr`)˛Ų_ęÆûnW‡‰ČÆ(@Ūįoš>^‹čÔšv˙Íkc#˛ą˙‚{Wö÷æōrdķōļ7oęŨ؛˓Ũ\~ÛËû\÷Ž\‹l>rČZô;ä|ÂŊCëÜxžŒlđVš_îÆĪīŋŨ]ڋp° _rJŠ Ádå#žMČ$węQžSÛĢ`vũŲ5Ø?ß+ˆíšáū.Ä˛ŽŠ#8õ[O˙ Z–b˙5zŒšŪ•–Čĩšų°b&\‰Ųē7f Ė.Ŗ0ģo‰ŲmfW÷ŲÍũŊķHĖ1c{CÛrX>MDãmëÚ?UʏiíˇŨr –[!Cž|ĻŋÔ¯+Ų#ŨøëŽĘíŨėˇvÆ0ÆEėíŽēĢo_´… nã‘]hÎMęū‡q˛č|čå —ãX7ąwC^ž“Üo /ņ‘îÅØY<Î'rŧŲ•öBlžīž+‡˛¸ÜƒŧŒÃ€<Ė}â"θˆQEuq‰Ā„ÃēÔÕŋ/˛ˆž‰Áļ^^ÚgZßG˜‚넎Cĸ Üō Č.Ŋ'Q0Nd!D ›iš‡šë|üŪD6[5‹í´œ‡‘ ĮŽîˇ—÷§ņD:kĨī é0daú˛h}ĶũŽy˙Ā̐…Š?˛xsķϟW_ĩšž×ũÖßũū „Ģü‚ÎŖõ4ķuÅJ:fGšļ @æĪw‘wæÚX‹y{&˛1é‡ĖÅYxΆ ö;"@ķ3—NÛŠĸŲ?"˜ÁČFl*ŌC]UîāŌÜæūöՃōî(žîōŧÕũ~9L×ēûũ`âú{°7zŊ Ų° F8a傒Dų'!īātdsņ˛!Õ>‘÷āräũ‚ŧC[!īũ< ļ@æĄA6HCIËJ—× D:sÂQ÷E@đŋ…ŧ3Ã]īįęøgWV[ŦŪŋG6‰Ũ˜ŸëŽßđúWŪ1Žū]˙įę{ŋ{&>—l4{!›•—ÚˇÉŪäŊø#Âõéž{ygOFÖ>_ę|Œģę†Ä655•]–yå…DĮ˛ËŠXgđ%.w’T4¤+f`v=ņėã镋€Yũ˜­Åđ1Ė?§`ŽģûútėęZh Ô´–š6hYkŠ™°t ,› ËŨg™û{å,XģHŌæsåŋôŖ˙ –– !ë°CČއōēĪĖŧO—Ŧ:ŅŽGDkēģØ]uĐM™įē ĩÂĪŋŠŠŠđņŸG^€7U”˛‰<yIzYuC^؏#āiÜäz…h’7!‹Đ PD&žījō"Ūč&ë4DėW‹€õųČ ˛ŒPvLčē$Hp_Ń] "Nũ­ģŋm…<× ÜE‹ëįéŽžĒŗŊy9u+X‡é{zŋL€ˆ,č Čâ9Áĩų8dąø—K†ÆúņxdøĐõŲd÷Û:7VS‰|’uãņdÁœīŌŪ‚Ī>^ēmIÍSnLōŌ*HÍG8‚nîˇŧr5­ö›.Ū‡'ôΤØß+‘Åk°WīŽ&mßīžnĞp× Ūo=‘ąXëŲØØHccŖqû#īĮÅîŠ×Ÿ”“UŸķĮģą¨n”A8Ī!@_č‹m˙ ‘ė^Y:j˙s¤—^ûãv/}š ,ˆ„":7 ‘Ô.@¸ŋWÎø×6íˇ !ßŦ÷ˇ–_įęĢsVīīˆl”îGŪ ß3āi×§Ÿ"æÎ‡¨ü2V ƒ^ŪęmĸÜŠ?—u~ûƒ õWw!ÍG}f§ÄŌé}šŲ”úīë.ˆÔč˙ųDNš@!˛´æČcČs–k Šq@U ĖšÖ̓mFî0öŲ' ŗMmi‚ÂP¸æ}ĀÜ9s÷형 °ī.€äĪTĢâĒįx;úQî8Ē'$‹åm,ûay C†Ā%ĩų€.#ī…Œ‹#ŋ‚p›/";äˆčK9Fõ^č&\ßxúņĘ鍈‡æ-fžDv˜W?Kô‚ûæūĒ;Š[ëW:Mē֛u~Úneîû‹JGíŨU'^ģ¯ygÚyÖ'­—Ф–!‹ß‘ˆxĸEî/ągâųÔ"œ3Ũį d!ßŲšĢÄCUw!;í!îž.˜$ÔĪzĮÛP›đ[+Å--cRBڕČFlĨ‹d—^ûÉëoōõŖúˇŪ›įŽŊŊô†hė}•Žu}"ęŊ ŅËÖÅō÷ŠÅËĮīį[\_íūŪŲÜĪ+ļY‹DīāL/Ļ[ė>ƒŧzęģŌė×-&-ķËŌ:Ū‚0/!:w ŦqiÛņ냈aŨ,DˇķúĐ¯ģ¯nŌ{ę–ĨéŽē‘W#ƒĖˇ9Č|ĶõA)ž^čwŦt.Oõ~×r—!īŲâžIĨs9×Î}m-˛˙yGu3÷iw}0^ហœ™B´|…„d0´ņm,ˇbŠq"]°H”Ũڊi[ێ!Ü˙ė_›0#œq,ÔĨ ‚ˆkîŲ@pÂ)˜į§bžsöíšP?R ŧ6,gŦÜą¯?ļī"d/rŧƒ!CÆqČyČTpĩ^OŌIzŒ›$“Ũu1"ŪyÁMšOų ö’ŊčŽû搯Ęđ9¨V÷‰Or%]¸ã–qū‚§ŽpA듇Špŋ`ÛŪ¯–TG¨;Ŧ)ĩ O*3‹€Û¯1Üo ŸNō{z32.Ēoū "žK4ÖÕH’ęNõkõ ŋ× ŌŲÂSŌøuT˛!m$ׇÜuĩw¯Øp5rãÚˇ!Öãã.KÁĘų´&ĩ˙)„Ŗú’û[Ĩ Eĩ*õëjĨ]›đ[ãĸ1ķí@ʑļų#ˆÚâmø–"@5áŒwDė@æë\dĶ9ø%"’áæ“ÜČâdËÜ× DCBz\[)_ÕŦēqŌĩÎ/?‹ˆĶĢ™ËņMG9ŌßovųëØŸ€€y"č`”ĨĖT¯Ûō@-† §r§Į1‡EŗZZ0Íķ1ۍ&üԑ„wū“k… („ËŒ“F“Đœc0—^™x/öíiؚŠ[?š:qĩŒ#$㞟 |ÃZ˛Î<'}‘ų E:&ģ!Æ ×# î§Ü€ŧËN 7:ēhéāęė‡ÕĐyÚ+ÛIˆÛĮ÷œ/æR‘ŲäØDÛH9û^îĒ;\ŨRv%ų/ĸP×%íË×ĢŌcéÎDâš üũüô—Dč ôôĮ!ģī­‰D”žĻŋđЈēZŌ2ÕÉOįA†ˆCØĢģ‹˙Üú’/ž (æŪˑļUA)ëŨ;Ä]UĖYiĶđEDMr,"ÖÔÅŧŖmĶ6ÜčúoōŋLû>įI¤ī ? ĐÛ"bߡÚV(ŖL/ĩÅ RšO#ĸúO"Üķ.ÍQ^~ʅNAŦÕ÷C6hį'”ĢW<â¤iÔBG7Ņ|l^C,Ŧ;JšˇĪŦhŪq}ųNųT;f:/"NJciĮVÄD×$ũ‘D™i…â­$KžS°\ë8fëŒĀ”c–Ô-Ͱj6fûਓŋHxŅų°`~¤gŽƒs\×l‚ŖŽ%xæIˤ9ØLo0™ÎsÂåEÕú=-pĮ¯;qõ5Xgōf 5¯Ė46$é„UŊĐ#ŪXéZ‡ˆ)w"2LRKÖĐĨ}áļöF,f! v"/Zj‚˜÷D/ŸŠ¨ö@ŒfžCĀFķÅf>•ģoĢŧį߯†›ëŽ*Ę×Åø<×ļ5ągũŅ^™ņ{:6+h¯?uŒ@ā]ÅŠ•H¤\‰#ōë•GüĪķMMM6Á8Ī_č?Šá­D|—ņęĶLäʃĢKŧMļB]4Ÿŋ#âŌo bųV"NBƒüžĘņ+7?âi ųŧ3ŧŠ?›$ŠŅgļôŌä#›FdŋË#Š>ĒöYęŽmČø'ąëíĩD‡šqŲ‘]b•ų>€āŠŽūXœëŽŋĢĻn ÆĄĮ!Ō}Ī}iÚk÷ŦŒ@?4}‰ÁģČ|ķšx5Vė•å×).jáĘ˙‰p“{¸ž×ßž…û˙u ˙ũ÷ũ1dÍø"&o%Z3t.'å]ŽĒYŖô}Ŋ‘DœH<ōÛ­s ē]s4õ­Û,ß&äLĮaŽkÆã8!—‡eĶ1ێÄ^}=öČCą¯ŧT8+šÄĖQá÷0ÄėæÅįaĘBč>@\Ģ×ßĐËzuÍ;n?CH–‹ąėėlÄoĪFR€ĖŒĒzl}Hun_@—Ũũ6ŠŖPNøxí6ī%Ķ q˛PŸ‹ŧ0?qâÄucWĸčwˆ8í;ˆ|ņų|÷̧rŨņ]¯rxņš•dĨ\­‰]3 iũŋũß'!‹Čg=ؗ\ÛND¸Š¸Ŧ†dƒ'Ÿ›$Ą?Í#.Ÿë\9jt§cs˛˜_āŌ–ˆ¨Ę(Õc•#Ą_ƒXáū1ĐRc-õŖ~‘¸\ŽˆaÕPÉ7ŧ‰“ö‘Öw5â"ÕQœĖΧ\ŋ˙ ņį™¤2ÉĐžÃwÃē¸ģąąņîÆÆÆ{ÜßŖŧüĩīüēƒlXîsmžY[ˆ¸8ãĨOęƒ'ŨõW×ø%„UņŖ<ņyė“uųĪAtŗgģ{Eĩ27ôŌ ų7‘ áķˆņį#ļĪ! ˙#^’ŒÅ€hÛ' ~ŗČD}–u=jA֜q.íIČ{w+ÂaŽčMˆ< šr ˛ß Ú$*Wāúi˛!ü ōŽũYŸ$b"üļųãčÛø†w+Æc˛ÆŸG´f‰ĖšgbĪÄķöĮēÜ;ëß×1žËõãyޟQüž%”H™øÜĻBTË X>IČ\"?fß—Ų’ˇ°dfüėŧ…„{ėEøËk`ūÜ"‘uŠë”ķž{c~qvōhē>blßÍ)Oäæ•Áō4–=ŖÛ0X'Žļ™™™lhŌņĐ]ū-ûĩųü"*U÷Įǃŧ =‰,"ßG"CŽč-w! "/õŨŲí.ũsČîî5¯áÄ'Q 4Ķ÷ŸÖX]æģ˛|Îu.ĸ¯R=™ļmb”ŗ4–ĮÄRVãĄ*} K}ÕõŲjdyČRé„SŠŅŦBvõ‹ŧ´+\YzOûø:äûœģ~•bˇĻD–œz­Ä…Ž?ĢuŦĶ…~.ŅâŽÖ¤q]×÷ˇ nV%0k@ķŊôúĖ$dįë#›y1 q/ē ™ŸEäžĸ闸ņ[ģŸs}_ÎCĶÍquÛ ‘ėŲĶ}īîŌÍD€˛ÅËc)˛¨6"\ũ­Č"ø.â§‹øĸyßBĮø/Wģ ×ēąū(Q7ĨEˆŊ‡ē'•Û|)ûœĢ{P&­Ū[ėúBûQ}Ōsõøņˇ˙b`uâĶ‹š^} åŌ=wB¸äģÚ ß˙äÚúQdĶs1˛–<ˆl ÷@Ū…?qŲ/#›Æ­9ú3"ī‰iWėĢ=T ô*"b~q­ģ Äņ#Ü}ĩĖ dûīŽŌûĢ+ĕī ×/W"›ˆqŽīžãĨÕąCdhéoTįPüū€l„'!ë ŪWUÚB"8ĩh/ąęŅE~ů.dÉũą\čaTüĻģbëšhčŪęú`?˜ Ŗú\v qĻWī‚XŲ(`sgc?ļvö,L¯nĐÖ\}ÅŖŒ‹›?B7Kļ4čzfnÕåŦÅbWĢ&ŋ=ōęĮ)Ž€I,Ä;/–Ū">Ēåąß’ōϊûIy”ģיûY$HÃJĸ(Š.]U?ˆDr ‰€2ëúöf„ƒ,Ž…čUJí{\!­Ē2Úî¤Ņĩ=îŌO?g/‰•ŲŪŧIJ;1”™Gq\åjú-ąÕöEgEĮī ríŸīũ^í|1në‡,Î-eōĐ>.§ŖÖČl‡ œßI@…ÉU*ãÃ^î^d“2=R¨ą(Ķ—%#”!•Lø1ÃÕZy.åįC„‹žO$.Žö]ÔgPˇŊ~*W†Ÿv ˛Ūͧssšš2ũuáND˛0 /$j§AY)?”Hp”# ,h]@Ø˙-I@aûŽĀ6į`Æ<ĖĮĀüđ§˜ŊöÁꑊe€9üÕuØožŲj8,ŸĶ^5} ÖēXˇƒ3n—iš“€6w–ÖŲBf~{ElĒtĖZ5G°•95đēKOVåšËŪÛÎD­tˆzRÛēø¨Įĸ—Î[ätž%Šæt^˙wļeÚĢGâ]‹p#IãœX×õ(7>gJĘÜTķŖēV5Û™W%āķ÷‘ŽÅ‹u]mm¨ąčĖzC)8—ëŗ’{•ęTe cБšļŠæ˛w†šF+ŧQ)&Ž e€üüén°„äąÔ#úĻķÉW Š`DČWkč=잿/Â\úcĖ7ŋ…ič%~Ë ēf§w6A€}éEÂŊöÆl3MOĒV\äĸĸ_ėúp–‰֒Á`b“Ël@nĪåŖ—¤ĻB~‰;Ķ2ųVkōŋ9ŅÆŽsŧŧŨŽárĈd{<}rGĪņ-3–ãFbō6 "Öš~9x<ģ´ŸĢ™×›¸ŽĩöŸ‡ˆŅ?‹Äø2‘>4Ņđ¯ƒ}Ņáö•á”;ŽĘ:TUĪM°mč5#@lw†!ˇ}ü|ĘŦ e€üā’ĻžŪļ'đE,§!;„R7 K@}/č3ûÎÆ|įlĖO/ÃÔu+œÃ\Ę3g`GÁnĀØfČĩ%°vD@Ä-/Fô7ą”—é‹qC*Ķë‰Lü”RĒ@w\O¤ãŸü(œüëˇëöĒ^ˆNs8b…ûY$˛RŲE>ĨKąÃ5ŽGl:Z WPFœœŌyëBoÄÆfōžžŒd)ģ.Tkí™H™rÍGA•3ÍĢÉs–›ø¨ĢL#–Z †5+CÖŽ ÍÛX{õĩÆ|ņ+Ûmo âkˆŦŗā€Ŋ-Īŧ`Ō` ÛT§ߊw.b‘8q#XJ t›ļâķc3žĻ-Ĩ”Ē'¨ÍˆJwÄø¨Hŋۅ īZD‡\‡ÄZ^‡'–MøÍ†tmų9éj b”ō˙ųaĮ vo"īoÅuaŊ@Y)ãŽ#ÎËiIbče\@ʀ6ZxŠ€§ˆaoÄgp,€îX k×fΞlˇŊp¸~XN0&“ąļ[w'Š6Z–ûƒšČ"õ*âãö"Æüˆ;pŧ„„ĪTÎ8ã”Öƒŧ—*lll|ÃûМáĪú–“kll|}C•“ŌúSLí0‘œ@tĢ)ũg“7ļųÆÆÆ×ÜwUĨV|_씕āō}ĀĖ8—ĸŒ3ĸʲˆf$āAW9á<Žúž[[ĐŊûۈEĄ%Ÿ ž˛Ųŧ­ŠiŖOŋYĀ,jēMgíĘéȄw’ŅŦb6Â;ˆĶ„rĪâ•ė9e–’RJëM Æ# ŅEÆ"Ĩœ”ÖŸŒu!NĮę„*ŧ¯íJIÖK§Üåû¸/ję¸ *|pAtlĩa˛˛?°a¸ ‚ąäķkYąÜ°r…ĨļŽ™žũšm÷îë˜:uĒ7Ž 4Fœ4žMāDĶÅSAĖō =)Ĩ”RJ)ĨÔyÚ  §ŧF'VM°ē'é_YB–ēÄΐņ„tų]MĒÎÛ œÂ@feûuJ)Ĩ”RJ)Ĩ”€|ƒ|r@ū7ŋ–§Ë–ÖÚL˜Ëeėōe;{VÆ.˜ØææĀæsAūšŸKúO~ĸđ|ža=+’RJ)Ĩ”RJ›ũ?rŖō1̤܋%tEXtdate:create2012-10-18T20:57:32+02:00TŌ%tEXtdate:modify2012-10-18T20:57:32+02:00uZėntEXtSoftwarewww.inkscape.org›î<IENDŽB`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/_static/astropy_logo.pdf0000644000175100001710000001241000000000000020035 0ustar00vstsdocker%PDF-1.5 %ĩíŽû 3 0 obj << /Length 4 0 R /Filter /FlateDecode >> stream xœ}ššŽ,ĮEũúŠú.枸rAɐ!ČZȀ'ü}Ũ‘Y=CAž—ŲšDÆrãFŋáĘ!ÎĪßūå?žßũ+œ?ū|į9ÆŲķÕÚųqîņˆWŅÂ8ë•G?GŋĘ8SH—œZĶS>Ÿš˜WåÔ*{œ)ÎkÔzÎqͨõš\Ŋ–3†pÕ9ØpΤĢôlã—+­ą<4ŅėdļäĢÆ¤™~؊tõŌ4œWĒÜ!aB?cÔ#Ų†pĩŽQO‰:+Ĩye‰cēf™w“?F=ZĪŅ–¤Û&+ĘUJÔXbÔhã›Æ‘Ï{B[bŋfj¯%ú3Ījã˜t„äA‘\ÚŗŊ]¨ĶÄĘUg%Ŋ9G ōĻ/v{ĐSĘ/’)ĻI÷Ž)VgJœÆ†|•‰T)_Ŗëaa˜VcĒĻe¤ĖnG=š%­ˆãMÚJãĒĄ‡ĸ‚5>–žŋ,)K:Ô.)õ’æ4f:í(ķĒĻ-ũÂ%U&é‡Ŋ$Ë||ÎnÎķÜãZlõģnėē1žhWÍõl‰›Ž5d]Ÿą‰tœÎ:QĻ›XÖ~mL’ĩ•zÖzšą¤°YęqÖ|ĨQoãÕdށ–đ5tSÅūú]–™ŨLS/×K4ÔicŊ(Ό]$yҊĄÖåĄåübĪķíĀN(ŦWķņķžbJ˛°Âå›ÕqĨh^Šķ†<Ė­š›4ÜÚUbҏZØĩęŽ ŋ=ō×cšũŗl.?ÔŪ,Ĩ rõƒĶ—ŸJ—Õ.7?–ĸÃhˆÆÛvīĮėņ˜æĒīįÁvbxЙ)š…b™dN/@Š~ÂĘC‡L>ŊŒ*OJúÃĨS<)vG–ę†EYgš"¸âxéW0(^įLgW\`ū[ĪÍvũĘf=L ÉûЎLŖĩļ&\CķŠOmíg>i›šåēQīh({f™fxpk˜$ļÜį*éjŊ| ¯‰,¤ÄAeü8¸ÍlcĘʂ æe‘!~)Û=÷PÎXûZnRĻdaX“ü–įËͲđPčŨ”ö´ëøAo ‘ß…zuiĶe#5ô0IéĘAĻÍ‚J*i8Ž’:ōVŪNPɔ[),Đ´†Ā Š’f,īŽ1pĖiŽQ¤9­#¤qœ^LņvØØH‡a›Ë“UÃ8ČUCŌ!.Šõx°R—ü7éúînŽ7XŒ`ny¯žč!w$éŧEÁ"(-b,se“ā5n;CėE+ĻĮJm”ĮƒÉx–Á…BbŠT;2Pģß,įfo(–J-[žĐŖ•{‰–_dCđž3œ ŦëzH–4Qá“į)ãÅQHuWV˛Á)H:ÃĀ0 ~ē|’Î"Ā›V]lŸ(5Žō2“OXy÷ifkžõü=ÆČ7Ŋ"tYÉGd™§f†hōėWR2P¸ŗžh‚Ylį92ޚQ'N˛ qģCá,ęRŧŋGÄĒldLV¨!įkĖe„’^+ôP ;0˛ŠÂĢĖ`IéiÚ˛*3xÁRvæ% 6ŠŌPĨA yŪŽi”Nˎwqõv”ėø8ƒå6YvO4sÁ’E“ÁĐĒjU´7 ]RŒ8–hIMEŪííÕržŌ´t2Í螊Ü~OéÚÃEĀ@,cvíöÉ҈ŠcA‘+ƒŒFe”;Js.vÛ¸;•ūäŨ’ÔņZ"@vGYG {§;¤‚ë–BãUÄ씒ФkĨí~HUūõ~ƒ?ĩ**Riˇ**1Ašŧ•UŠ%ĄÉ[ĸĨæņKÛ÷0,ŗ'Dx-ûø~B“RfšN/ļmZvÛ CÚũ‚–göë´Dē4p#‰˜ĨĸZ[Ø*…ZKÅĶļ nĐ[FēAoqow#ŋN_^°/_N˛es/:^˛/7ÛOs7Üßnz+fûņŌÜōōc+öWaæ!Ī—Āđ1Å&ŌuúI”KD1o!$I:ëíŲJžfôū0]`¸FE{ĢĘG8ë0¤^ŋoMų^ŗDÖĪ>Ė͜b_>ŊŖļ$[Ŗû%÷„hî˜÷æÎ ļmžŧ<íyß™K:¸öįXķáķõ¸Ŋ`ŊũŪŋ”ķé†ĨŊ-‚köØ~Q<ĻøĪaũʨ´ÜÎ@Į˛Ę^f7?ōãžHŲ2ĮģœŽY$üfâEjn¤ŨãËTŋLôNWĘĮ6Ī=An-Ģã•h\íl’–ŗK$kQĻíØUž,(ö\ åhđPpȤ´Ķķ=ÔrØŧûĩBĩNíļßâ îēœMVú ŲļO‡6h"Q”[Ŋ՗{VZ(mY,ë8ƒ™ RØđl*Ąm|؁k@UäF˛ĀEœŨøčķžPq€Ŧl…Ļ›Ŗá>#PŽž"ūôTQĨoГq?8¸ļqŠbßŅΚ2 iHW›õ—ĐØ †\Îũ+ŦąrÁ„* n~VU#Ā—näRQ š>/ q`Če,͉„Ö,iŠŊB—铇N(zālûŨ!ŽŽ&HG[”&LYå2„âÛÉÃÅ[xæĮ‡÷.ė[ ´]`‚‹ˇhm¯({ŲąĶĖúô†°tũHÎ[šĩ$5"Žĸgēä™čy>ē-‹qƒS„č܁r\ÃÚ0muhžæ5°øú¨Öˇø•č<éīį@‰^[@]ō)Ā:‰w~Ę>ũ >€kĨäSĪÃ?ŸßũüVĪŸßŽÄšøį¯>ŠŌƒōe;9ÂųŊūũéøĮ?ux8˙}”ķ/į7ÎīąqRäīsčAÍfŗ.˜"mæķĮƒÆgRä?Ŧ˛‡ē= éâäĘiyáƒū"§H ŗ4Ņ­Č’ˆƒÄh}ë”ÛōĻÁŅ}zš ƒĨ÷Mƒ‘m‹eaM)†Hgt/C<M3e„,šMČÕ¸åoįրč&%6•jömíƒvmÎFāųÔDäŸæ‚ūģ`‚o?Fƒ@x:4Z:,›ËįŸđ(kZM§]‚rĐŨ?ˆ 5Ŋo¯|zŋøĮö+IēGŠvō°žq÷ų:Y.#süáÉĖ´­ÃJŋäfĮÅĘŲw˙ÎĐ †Ŧ’03ļ„Cūōģ€RŌũRņ‹C@*­ûRˇų L›Š&ļø)ßeétņ!ÜJ§nœ16ūßÚlÚkÔkÞÛvŠžo™“˜H RŠv‰% k|ŽJ­*ú¸{iU(?-~[57áŗҘ԰wú*´H'éhũČŗWŌÕĨú”3Ķíĸ+o~ÄŲčŧTøĀí Dyžķ!v4TųĸIPBTõjŦ/đ3ŒwBf™Ō3ŪÅj:Œ{)&›8ĨĢ!*øáø?3ĻËS endstream endobj 4 0 obj 3867 endobj 2 0 obj << /ExtGState << /a0 << /CA 1 /ca 1 >> >> /Shading << /sh5 5 0 R >> >> endobj 6 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 960 176 ] /Contents 3 0 R /Group << /Type /Group /S /Transparency /I true /CS /DeviceRGB >> /Resources 2 0 R >> endobj 7 0 obj << /FunctionType 2 /Domain [ 0 1 ] /C0 [ 1 0.662745 0 ] /C1 [ 0.992157 0 0 ] /N 1 >> endobj 8 0 obj << /FunctionType 3 /Domain [ -3 4 ] /Functions [ 7 0 R 7 0 R 7 0 R 7 0 R 7 0 R 7 0 R 7 0 R ] /Bounds [ -2 -1 0 1 2 3 ] /Encode [ 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ] >> endobj 5 0 obj << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [ 458.295892 -154.186282 -184.237871 621.778606 ] /Domain [ -2.348045 3.394022 ] /Extend [ true true ] /Function 8 0 R >> 1 0 obj << /Type /Pages /Kids [ 6 0 R ] /Count 1 >> endobj 9 0 obj << /Creator (cairo 1.12.2 (http://cairographics.org)) /Producer (cairo 1.12.2 (http://cairographics.org)) >> endobj 10 0 obj << /Type /Catalog /Pages 1 0 R >> endobj xref 0 11 0000000000 65535 f 0000004834 00000 n 0000003982 00000 n 0000000015 00000 n 0000003959 00000 n 0000004598 00000 n 0000004083 00000 n 0000004297 00000 n 0000004409 00000 n 0000004899 00000 n 0000005026 00000 n trailer << /Size 11 /Root 10 0 R /Info 9 0 R >> startxref 5079 %%EOF ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2792614 astropy-5.0.2/docs/_templates/0000755000175100001710000000000000000000000015332 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/_templates/layout.html0000644000175100001710000000212600000000000017536 0ustar00vstsdocker{# This extension of the 'layout.html' prevents documentation for previous versions of Astropy to be indexed by bots, e.g. googlebot or bing bot, by inserting a robots meta tag into pages that are not in the stable or latest branch. It assumes that the documentation is built by and hosted on readthedocs.org: 1. Readthedocs.org has a global robots.txt and no option for a custom one. 2. The readthedocs app passes additional variables to the template context, one of them being `version_slug`. This variable is a string computed from the tags of the branches that are selected to be built. It can be 'latest', 'stable' or even a unique stringified version number. For more information, please refer to: https://github.com/astropy/astropy/pull/7874 http://www.robotstxt.org/meta.html https://github.com/rtfd/readthedocs.org/blob/master/readthedocs/builds/version_slug.py #} {% extends "!layout.html" %} {%- block extrahead %} {% if not version_slug in to_be_indexed %} {% endif %} {{ super() }} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changelog.rst0000644000175100001710000000024000000000000015652 0ustar00vstsdocker.. _changelog: ************** Full Changelog ************** .. changelog:: :towncrier: ../ :towncrier-skip-if-empty: :changelog_file: ../CHANGES.rst ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2792614 astropy-5.0.2/docs/changes/0000755000175100001710000000000000000000000014605 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/README.rst0000644000175100001710000000257500000000000016305 0ustar00vstsdocker:orphan: Changelog ========= This directory contains "news fragments" which are short files that contain a small **ReST**-formatted text that will be added to the next what's new page. Make sure to use full sentences with correct case and punctuation. Each file should be named like ``..rst``, where ```` is a pull request number, and ```` is one of: * ``feature``: New feature. * ``api``: API change. * ``bugfix``: Bug fix. * ``other``: Other changes and additions. If the change concern a sub-package, the file should go in the sub-directory relative to this sub-package. It is possible to add two files with different categories (and text) if both are relevant. For example a change may add a new feature but introduce an API change. So for example: ``123.feature.rst`` would have the content:: The ``my_new_feature`` option is now available for ``my_favorite_function``. To use it, write ``np.my_favorite_function(..., my_new_feature=True)``. Note the use of double-backticks for code. If you are unsure what pull request type to use, don't hesitate to ask in your PR. You can install ``towncrier`` and run ``towncrier --draft --version 4.3`` if you want to get a preview of how your change will look in the final release notes. .. note:: This README was adapted from the Numpy changelog readme under the terms of the MIT licence. ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2792614 astropy-5.0.2/docs/changes/config/0000755000175100001710000000000000000000000016052 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/config/.gitkeep0000644000175100001710000000000000000000000017471 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2792614 astropy-5.0.2/docs/changes/constants/0000755000175100001710000000000000000000000016621 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/constants/.gitkeep0000644000175100001710000000000000000000000020240 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2792614 astropy-5.0.2/docs/changes/convolution/0000755000175100001710000000000000000000000017164 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/convolution/.gitkeep0000644000175100001710000000000000000000000020603 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2792614 astropy-5.0.2/docs/changes/coordinates/0000755000175100001710000000000000000000000017117 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/coordinates/.gitkeep0000644000175100001710000000000000000000000020536 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2792614 astropy-5.0.2/docs/changes/cosmology/0000755000175100001710000000000000000000000016620 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/cosmology/.gitkeep0000644000175100001710000000000000000000000020237 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2792614 astropy-5.0.2/docs/changes/extern/0000755000175100001710000000000000000000000016112 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/extern/.gitkeep0000644000175100001710000000000000000000000017531 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2792614 astropy-5.0.2/docs/changes/io.ascii/0000755000175100001710000000000000000000000016303 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/io.ascii/.gitkeep0000644000175100001710000000000000000000000017722 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2792614 astropy-5.0.2/docs/changes/io.fits/0000755000175100001710000000000000000000000016160 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/io.fits/.gitkeep0000644000175100001710000000000000000000000017577 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2792614 astropy-5.0.2/docs/changes/io.misc/0000755000175100001710000000000000000000000016146 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/io.misc/.gitkeep0000644000175100001710000000000000000000000017565 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2792614 astropy-5.0.2/docs/changes/io.registry/0000755000175100001710000000000000000000000017063 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/io.registry/.gitkeep0000644000175100001710000000000000000000000020502 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2792614 astropy-5.0.2/docs/changes/io.votable/0000755000175100001710000000000000000000000016647 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/io.votable/.gitkeep0000644000175100001710000000000000000000000020266 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2792614 astropy-5.0.2/docs/changes/modeling/0000755000175100001710000000000000000000000016403 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/modeling/.gitkeep0000644000175100001710000000000000000000000020022 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2792614 astropy-5.0.2/docs/changes/nddata/0000755000175100001710000000000000000000000016040 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/nddata/.gitkeep0000644000175100001710000000000000000000000017457 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2832618 astropy-5.0.2/docs/changes/samp/0000755000175100001710000000000000000000000015545 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/samp/.gitkeep0000644000175100001710000000000000000000000017164 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2832618 astropy-5.0.2/docs/changes/stats/0000755000175100001710000000000000000000000015743 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/stats/.gitkeep0000644000175100001710000000000000000000000017362 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2832618 astropy-5.0.2/docs/changes/table/0000755000175100001710000000000000000000000015674 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/table/.gitkeep0000644000175100001710000000000000000000000017313 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/template.rst0000644000175100001710000000234700000000000017160 0ustar00vstsdocker{% if top_line %} {{ top_line }} {{ top_underline * ((top_line)|length)}} {% elif versiondata.name %} {{ versiondata.name }} {{ versiondata.version }} ({{ versiondata.date }}) {{ top_underline * ((versiondata.name + versiondata.version + versiondata.date)|length + 4)}} {% else %} {{ versiondata.version }} ({{ versiondata.date }}) {{ top_underline * ((versiondata.version + versiondata.date)|length + 3)}} {% endif %} {% for category, val in definitions.items() %} {% set underline = underlines[0] %} {{ definitions[category]['name'] }} {{ underline * definitions[category]['name']|length }} {% set underline = underlines[1] %} {% for section, _ in sections.items() %} {% if section and category in sections[section] %} {{section}} {{ underline * section|length }} {% endif %} {% if sections[section] and category in sections[section] %} {% if definitions[category]['showcontent'] %} {% for text, values in sections[section][category].items() %} - {{ text }} [{{ values|join(', ') }}] {% endfor %} {% else %} - {{ sections[section][category]['']|join(', ') }} {% endif %} {% if sections[section][category]|length == 0 %} No significant changes. {% else %} {% endif %} {% else %} {# No significant changes. #} {% endif %} {% endfor %} {% endfor %} ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2832618 astropy-5.0.2/docs/changes/tests/0000755000175100001710000000000000000000000015747 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/tests/.gitkeep0000644000175100001710000000000000000000000017366 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2832618 astropy-5.0.2/docs/changes/time/0000755000175100001710000000000000000000000015543 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/time/.gitkeep0000644000175100001710000000000000000000000017162 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2832618 astropy-5.0.2/docs/changes/timeseries/0000755000175100001710000000000000000000000016756 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/timeseries/.gitkeep0000644000175100001710000000000000000000000020375 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2832618 astropy-5.0.2/docs/changes/uncertainty/0000755000175100001710000000000000000000000017152 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/uncertainty/.gitkeep0000644000175100001710000000000000000000000020571 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2832618 astropy-5.0.2/docs/changes/units/0000755000175100001710000000000000000000000015747 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/units/.gitkeep0000644000175100001710000000000000000000000017366 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2832618 astropy-5.0.2/docs/changes/utils/0000755000175100001710000000000000000000000015745 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/utils/.gitkeep0000644000175100001710000000000000000000000017364 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2832618 astropy-5.0.2/docs/changes/visualization/0000755000175100001710000000000000000000000017506 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/visualization/.gitkeep0000644000175100001710000000000000000000000021125 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1646921593.2832618 astropy-5.0.2/docs/changes/wcs/0000755000175100001710000000000000000000000015401 5ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/changes/wcs/.gitkeep0000644000175100001710000000000000000000000017020 0ustar00vstsdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/common_links.txt0000644000175100001710000001274600000000000016440 0ustar00vstsdocker.. These are ReST substitutions and links that can be used throughout the docs .. (and docstrings) because they are added to ``docs/conf.py::rst_epilog``. .. Some of the links are in curly braces for ``.format`` substitutions. .. ------------------------------------------------------------------ .. RST SUBSITUTIONS .. NumPy .. |ndarray| replace:: :class:`numpy.ndarray` .. Astropy .. Coordinates .. |EarthLocation| replace:: :class:`~astropy.coordinates.EarthLocation` .. |Angle| replace:: `~astropy.coordinates.Angle` .. |Latitude| replace:: `~astropy.coordinates.Latitude` .. |Longitude| replace:: :class:`~astropy.coordinates.Longitude` .. |BaseFrame| replace:: `~astropy.coordinates.BaseCoordinateFrame` .. |SkyCoord| replace:: :class:`~astropy.coordinates.SkyCoord` .. |SpectralCoord| replace:: `~astropy.coordinates.SpectralCoord` .. Cosmology .. |Cosmology| replace:: :class:`~astropy.cosmology.Cosmology` .. |Cosmology.read| replace:: :meth:`~astropy.cosmology.Cosmology.read` .. |Cosmology.write| replace:: :meth:`~astropy.cosmology.Cosmology.write` .. |Cosmology.from_format| replace:: :meth:`~astropy.cosmology.Cosmology.from_format` .. |Cosmology.to_format| replace:: :meth:`~astropy.cosmology.Cosmology.to_format` .. |FLRW| replace:: :class:`~astropy.cosmology.FLRW` .. |LambdaCDM| replace:: :class:`~astropy.cosmology.LambdaCDM` .. |FlatLambdaCDM| replace:: :class:`~astropy.cosmology.FlatLambdaCDM` .. |Planck18| replace:: :ref:`Planck18 ` .. |FlatCosmologyMixin| replace:: :class:`~astropy.cosmology.FlatCosmologyMixin` .. |FlatFLRWMixin| replace:: :class:`~astropy.cosmology.FlatFLRWMixin` .. |default_cosmology| replace:: :class:`~astropy.cosmology.default_cosmology` .. SAMP .. |SAMPClient| replace:: :class:`~astropy.samp.SAMPClient` .. |SAMPIntegratedClient| replace:: :class:`~astropy.samp.SAMPIntegratedClient` .. |SAMPHubServer| replace:: :class:`~astropy.samp.SAMPHubServer` .. |SAMPHubProxy| replace:: :class:`~astropy.samp.SAMPHubProxy` .. |SAMPMsgReplierWrapper| replace:: :class:`~astropy.samp.SAMPMsgReplierWrapper` .. Table .. |Column| replace:: :class:`~astropy.table.Column` .. |MaskedColumn| replace:: :class:`~astropy.table.MaskedColumn` .. |TableColumns| replace:: :class:`~astropy.table.TableColumns` .. |Row| replace:: :class:`~astropy.table.Row` .. |Table| replace:: :class:`~astropy.table.Table` .. |QTable| replace:: :class:`~astropy.table.QTable` .. Time .. |Time| replace:: :class:`~astropy.time.Time` .. |TimeDelta| replace:: :class:`~astropy.time.TimeDelta` .. Timeseries .. |TimeSeries| replace:: :class:`~astropy.timeseries.TimeSeries` .. |BinnedTimeSeries| replace:: :class:`~astropy.timeseries.BinnedTimeSeries` .. Distribution .. |Distribution| replace:: :class:`~astropy.uncertainty.Distribution` .. Units .. |PhysicalType| replace:: :class:`~astropy.units.PhysicalType` .. |Quantity| replace:: :class:`~astropy.units.Quantity` .. |Unit| replace:: :class:`~astropy.units.UnitBase` .. |StructuredUnit| replace:: :class:`~astropy.units.StructuredUnit` .. Utils .. |Masked| replace:: :class:`~astropy.utils.masked.Masked` .. ------------------------------------------------------------------ .. KNOWN PROJECTS .. _Python: https://www.python.org/ .. |minimum_python_version| replace:: {minimum_python} .. Astropy .. _`Astropy mailing list`: https://mail.python.org/mailman/listinfo/astropy .. _`astropy-dev mailing list`: http://groups.google.com/group/astropy-dev .. NumPy .. _NumPy: https://numpy.org/ .. _`numpy github`: https://github.com/numpy/numpy .. _`numpy mailing list`: http://mail.python.org/mailman/listinfo/numpy-discussion .. |minimum_numpy_version| replace:: {numpy} .. _numpydoc: https://pypi.org/project/numpydoc/ .. erfa .. _ERFA: https://github.com/liberfa/erfa .. _PyErfa: http://pyerfa.readthedocs.org/ .. _`pyerfa github`: https://github.com/liberfa/pyerfa/ .. |minimum_pyerfa_version| replace:: {pyerfa} .. matplotlib .. _Matplotlib: https://matplotlib.org/ .. |minimum_matplotlib_version| replace:: {matplotlib} .. sofa .. _SOFA: http://www.iausofa.org/index.html .. scipy .. _scipy: https://www.scipy.org/ .. _`scipy github`: https://github.com/scipy/scipy .. _`scipy mailing list`: http://mail.python.org/mailman/listinfo/scipy-dev .. |minimum_scipy_version| replace:: {scipy} .. asdf .. |minimum_asdf_version| replace:: {asdf} .. pyyaml .. |minimum_pyyaml_version| replace:: {pyyaml} .. packaging .. _packaging: https://packaging.pypa.io/ .. |minimum_packaging_version| replace:: {packaging} .. IPython .. _IPython: http://ipython.org/ .. _`ipython github`: https://github.com/ipython/ipython .. _`ipython mailing list`: http://mail.python.org/mailman/listinfo/IPython-dev .. |minimum_ipython_version| replace:: {ipython} .. pip .. _pip: https://pip.pypa.io .. pipenv .. _pipenv: https://pipenv.pypa.io/en/latest/ .. pyarrow .. |minimum_pyarrow_version| replace:: {pyarrow} .. virtualenv .. _virtualenv: https://pypi.org/project/virtualenv .. _virtualenvwrapper: https://pypi.org/project/virtualenvwrapper .. _virtualenvwrapper-win: https://github.com/davidmarble/virtualenvwrapper-win .. _venv: https://docs.python.org/dev/library/venv.html .. conda .. _conda: https://conda.io/docs/ .. py.test .. _pytest: https://pytest.org/en/latest/index.html .. _pytest-astropy: https://github.com/astropy/pytest-astropy .. _pytest-doctestplus: https://github.com/astropy/pytest-doctestplus .. _pytest-openfiles: https://github.com/astropy/pytest-openfiles .. _pytest-remotedata: https://github.com/astropy/pytest-remotedata ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/conf.py0000644000175100001710000004320600000000000014501 0ustar00vstsdocker# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst # # Astropy documentation build configuration file. # # This file is execfile()d with the current directory set to its containing dir. # # Note that not all possible configuration values are present in this file. # # All configuration values have a default. Some values are defined in # the global Astropy configuration which is loaded here before anything else. # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # sys.path.insert(0, os.path.abspath('..')) # IMPORTANT: the above commented section was generated by sphinx-quickstart, but # is *NOT* appropriate for astropy or Astropy affiliated packages. It is left # commented out with this explanation to make it clear why this should not be # done. If the sys.path entry above is added, when the astropy.sphinx.conf # import occurs, it will import the *source* version of astropy instead of the # version installed (if invoked as "make html" or directly with sphinx), or the # version in the build directory. # Thus, any C-extensions that are needed to build the documentation will *not* # be accessible, and the documentation will not build correctly. # See sphinx_astropy.conf for which values are set there. import os import sys import configparser from datetime import datetime from importlib import metadata import doctest from packaging.requirements import Requirement from packaging.specifiers import SpecifierSet # -- Check for missing dependencies ------------------------------------------- missing_requirements = {} for line in metadata.requires('astropy'): if 'extra == "docs"' in line: req = Requirement(line.split(';')[0]) req_package = req.name.lower() req_specifier = str(req.specifier) try: version = metadata.version(req_package) except metadata.PackageNotFoundError: missing_requirements[req_package] = req_specifier if version not in SpecifierSet(req_specifier, prereleases=True): missing_requirements[req_package] = req_specifier if missing_requirements: print('The following packages could not be found and are required to ' 'build the documentation:') for key, val in missing_requirements.items(): print(f' * {key} {val}') print('Please install the "docs" requirements.') sys.exit(1) from sphinx_astropy.conf.v1 import * # noqa # -- Plot configuration ------------------------------------------------------- plot_rcparams = {} plot_rcparams['figure.figsize'] = (6, 6) plot_rcparams['savefig.facecolor'] = 'none' plot_rcparams['savefig.bbox'] = 'tight' plot_rcparams['axes.labelsize'] = 'large' plot_rcparams['figure.subplot.hspace'] = 0.5 plot_apply_rcparams = True plot_html_show_source_link = False plot_formats = ['png', 'svg', 'pdf'] # Don't use the default - which includes a numpy and matplotlib import plot_pre_code = "" # -- General configuration ---------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. needs_sphinx = '1.7' # To perform a Sphinx version check that needs to be more specific than # major.minor, call `check_sphinx_version("X.Y.Z")` here. check_sphinx_version("1.2.1") # noqa: F405 # The intersphinx_mapping in sphinx_astropy.sphinx refers to astropy for # the benefit of other packages who want to refer to objects in the # astropy core. However, we don't want to cyclically reference astropy in its # own build so we remove it here. del intersphinx_mapping['astropy'] # noqa: F405 # add any custom intersphinx for astropy intersphinx_mapping['astropy-dev'] = ('https://docs.astropy.org/en/latest/', None) # noqa: F405 intersphinx_mapping['pyerfa'] = ('https://pyerfa.readthedocs.io/en/stable/', None) # noqa: F405 intersphinx_mapping['pytest'] = ('https://docs.pytest.org/en/stable/', None) # noqa: F405 intersphinx_mapping['ipython'] = ('https://ipython.readthedocs.io/en/stable/', None) # noqa: F405 intersphinx_mapping['pandas'] = ('https://pandas.pydata.org/pandas-docs/stable/', None) # noqa: F405, E501 intersphinx_mapping['sphinx_automodapi'] = ('https://sphinx-automodapi.readthedocs.io/en/stable/', None) # noqa: F405, E501 intersphinx_mapping['packagetemplate'] = ('https://docs.astropy.org/projects/package-template/en/latest/', None) # noqa: F405, E501 intersphinx_mapping['h5py'] = ('https://docs.h5py.org/en/stable/', None) # noqa: F405 # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns.append('_templates') # noqa: F405 exclude_patterns.append('changes') # noqa: F405 exclude_patterns.append('_pkgtemplate.rst') # noqa: F405 exclude_patterns.append('**/*.inc.rst') # .inc.rst mean *include* files, don't have sphinx process them # noqa: F405, E501 # Add any paths that contain templates here, relative to this directory. if 'templates_path' not in locals(): # in case parent conf.py defines it templates_path = [] templates_path.append('_templates') extensions += ["sphinx_changelog"] # noqa: F405 # Grab minversion from setup.cfg setup_cfg = configparser.ConfigParser() setup_cfg.read(os.path.join(os.path.pardir, 'setup.cfg')) __minimum_python_version__ = setup_cfg['options']['python_requires'].replace('>=', '') project = u'Astropy' min_versions = {} for line in metadata.requires('astropy'): req = Requirement(line.split(';')[0]) min_versions[req.name.lower()] = str(req.specifier) # This is added to the end of RST files - a good place to put substitutions to # be used globally. with open("common_links.txt", "r") as cl: rst_epilog += cl.read().format(minimum_python=__minimum_python_version__, **min_versions) # Manually register doctest options since matplotlib 3.5 messed up allowing them # from pytest-doctestplus IGNORE_OUTPUT = doctest.register_optionflag('IGNORE_OUTPUT') REMOTE_DATA = doctest.register_optionflag('REMOTE_DATA') FLOAT_CMP = doctest.register_optionflag('FLOAT_CMP') # Whether to create cross-references for the parameter types in the # Parameters, Other Parameters, Returns and Yields sections of the docstring. numpydoc_xref_param_type = True # Words not to cross-reference. Most likely, these are common words used in # parameter type descriptions that may be confused for classes of the same # name. The base set comes from sphinx-astropy. We add more here. numpydoc_xref_ignore.update({ "mixin", "Any", # aka something that would be annotated with `typing.Any` # needed in subclassing numpy # TODO! revisit "Arguments", "Path", # TODO! not need to ignore. "flag", "bits", }) # Mappings to fully qualified paths (or correct ReST references) for the # aliases/shortcuts used when specifying the types of parameters. # Numpy provides some defaults # https://github.com/numpy/numpydoc/blob/b352cd7635f2ea7748722f410a31f937d92545cc/numpydoc/xref.py#L62-L94 # and a base set comes from sphinx-astropy. # so here we mostly need to define Astropy-specific x-refs numpydoc_xref_aliases.update({ # python & adjacent "Any": "`~typing.Any`", "file-like": ":term:`python:file-like object`", "file": ":term:`python:file object`", "path-like": ":term:`python:path-like object`", "module": ":term:`python:module`", "buffer-like": ":term:buffer-like", "hashable": ":term:`python:hashable`", # for matplotlib "color": ":term:`color`", # for numpy "ints": ":class:`python:int`", # for astropy "number": ":term:`number`", "Representation": ":class:`~astropy.coordinates.BaseRepresentation`", "writable": ":term:`writable file-like object`", "readable": ":term:`readable file-like object`", "BaseHDU": ":doc:`HDU `" }) # Add from sphinx-astropy 1) glossary aliases 2) physical types. numpydoc_xref_aliases.update(numpydoc_xref_astropy_aliases) # -- Project information ------------------------------------------------------ author = u'The Astropy Developers' copyright = f'2011–{datetime.utcnow().year}, ' + author # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # The full version, including alpha/beta/rc tags. release = metadata.version(project) # The short X.Y version. version = '.'.join(release.split('.')[:2]) # Only include dev docs in dev version. dev = 'dev' in release if not dev: exclude_patterns.append('development/*') # noqa: F405 exclude_patterns.append('testhelpers.rst') # noqa: F405 # -- Options for the module index --------------------------------------------- modindex_common_prefix = ['astropy.'] # -- Options for HTML output --------------------------------------------------- # A NOTE ON HTML THEMES # # The global astropy configuration uses a custom theme, # 'bootstrap-astropy', which is installed along with astropy. The # theme has options for controlling the text of the logo in the upper # left corner. This is how you would specify the options in order to # override the theme defaults (The following options *are* the # defaults, so we do not actually need to set them here.) # html_theme_options = { # 'logotext1': 'astro', # white, semi-bold # 'logotext2': 'py', # orange, light # 'logotext3': ':docs' # white, light # } # A different theme can be used, or other parts of this theme can be # modified, by overriding some of the variables set in the global # configuration. The variables set in the global configuration are # listed below, commented out. # Add any paths that contain custom themes here, relative to this directory. # To use a different custom theme, add the directory containing the theme. # html_theme_path = [] # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. To override the custom theme, set this to the # name of a builtin theme or the name of a custom theme in html_theme_path. # html_theme = None # Custom sidebar templates, maps document names to template names. # html_sidebars = {} # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. # html_favicon = '' # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. # html_last_updated_fmt = '' # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". html_title = f'{project} v{release}' # Output file base name for HTML help builder. htmlhelp_basename = project + 'doc' # A dictionary of values to pass into the template engine’s context for all pages. html_context = { 'to_be_indexed': ['stable', 'latest'], 'is_development': dev } # -- Options for LaTeX output -------------------------------------------------- # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [('index', project + '.tex', project + u' Documentation', author, 'manual')] latex_logo = '_static/astropy_logo.pdf' # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [('index', project.lower(), project + u' Documentation', [author], 1)] # Setting this URL is requited by sphinx-astropy github_issues_url = 'https://github.com/astropy/astropy/issues/' edit_on_github_branch = 'main' # Enable nitpicky mode - which ensures that all references in the docs # resolve. nitpicky = True # This is not used. See docs/nitpick-exceptions file for the actual listing. nitpick_ignore = [] for line in open('nitpick-exceptions'): if line.strip() == "" or line.startswith("#"): continue dtype, target = line.split(None, 1) target = target.strip() nitpick_ignore.append((dtype, target)) # -- Options for the Sphinx gallery ------------------------------------------- try: import warnings import sphinx_gallery # noqa: F401 extensions += ["sphinx_gallery.gen_gallery"] # noqa: F405 sphinx_gallery_conf = { 'backreferences_dir': 'generated/modules', # path to store the module using example template # noqa: E501 'filename_pattern': '^((?!skip_).)*$', # execute all examples except those that start with "skip_" # noqa: E501 'examples_dirs': f'..{os.sep}examples', # path to the examples scripts 'gallery_dirs': 'generated/examples', # path to save gallery generated examples 'reference_url': { 'astropy': None, 'matplotlib': 'https://matplotlib.org/stable/', 'numpy': 'https://numpy.org/doc/stable/', }, 'abort_on_example_error': True } # Filter out backend-related warnings as described in # https://github.com/sphinx-gallery/sphinx-gallery/pull/564 warnings.filterwarnings("ignore", category=UserWarning, message='Matplotlib is currently using agg, which is a' ' non-GUI backend, so cannot show the figure.') except ImportError: sphinx_gallery = None # -- Options for linkcheck output ------------------------------------------- linkcheck_retry = 5 linkcheck_ignore = ['https://journals.aas.org/manuscript-preparation/', 'https://maia.usno.navy.mil/', 'https://www.usno.navy.mil/USNO/time/gps/usno-gps-time-transfer', 'https://aa.usno.navy.mil/publications/docs/Circular_179.php', 'http://data.astropy.org', 'https://doi.org/10.1017/S0251107X00002406', # internal server error 'https://doi.org/10.1017/pasa.2013.31', # internal server error 'https://pipenv.pypa.io/', # certificate error r'https://github\.com/astropy/astropy/(?:issues|pull)/\d+'] linkcheck_timeout = 180 linkcheck_anchors = False # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. html_extra_path = ['robots.txt'] def rstjinja(app, docname, source): """Render pages as a jinja template to hide/show dev docs. """ # Make sure we're outputting HTML if app.builder.format != 'html': return files_to_render = ["index", "install"] if docname in files_to_render: print(f"Jinja rendering {docname}") rendered = app.builder.templates.render_string( source[0], app.config.html_context) source[0] = rendered def resolve_astropy_and_dev_reference(app, env, node, contnode): """ Reference targets for ``astropy:`` and ``astropy-dev:`` are special cases. Documentation links in astropy can be set up as intersphinx links so that affiliate packages do not have to override the docstrings when building the docs. If we are building the development docs it is a local ref targeting the label ``astropy-dev:" If your frame has this class as an attribute:: >>> from astropy.coordinates import Attribute >>> class Egg(BaseCoordinateFrame): ... can = Attribute(default=Spam()) When it is displayed by the frame it will use the result of ``_astropy_repr_in_frame``:: >>> Egg() )> .. EXAMPLE END Defining Transformations between Frames --------------------------------------- As indicated by the point (3) in the :ref:`introduction above `, a frame class on its own is likely not very useful until transformations are defined between it and other coordinate frame classes. The key concept for defining transformations in ``astropy.coordinates`` is the "frame transform graph" (in the "graph theory" sense, not "plot"), which stores all of the transformations between the built-in frames, as well as tools for finding the shortest paths through this graph to transform from any frame to any other by composing the transformations. The power behind this concept is available to user-created frames as well, meaning that once you define even one transform from your frame to any frame in the graph, coordinates defined in your frame can be transformed to *any* other frame in the graph. The "frame transform graph" is available in code as ``astropy.coordinates.frame_transform_graph``, which is an instance of the `~astropy.coordinates.TransformGraph` class. The transformations themselves are represented as `~astropy.coordinates.CoordinateTransform` objects or their subclasses. The useful subclasses/types of transformations are: * `~astropy.coordinates.FunctionTransform` A transform that is defined as a function that takes a frame object of one frame class and returns an object of another class. * `~astropy.coordinates.AffineTransform` A transformation that includes a linear matrix operation and a translation (vector offset). These transformations are defined by a 3x3 matrix and a 3-vector for the offset (supplied as a Cartesian representation). The transformation is applied to the Cartesian representation of one frame and transforms into the Cartesian representation of the target frame. * `~astropy.coordinates.StaticMatrixTransform` * `~astropy.coordinates.DynamicMatrixTransform` The matrix transforms are `~astropy.coordinates.AffineTransform` transformations without a translation (i.e., only a rotation). The static version is for the case where the matrix is independent of the frame attributes (e.g., the ICRS->FK5 transformation, because ICRS has no frame attributes). The dynamic case is for transformations where the transformation matrix depends on the frame attributes of either the to or from frame. Generally, it is not necessary to use these classes directly. Instead, use methods on the ``frame_transform_graph`` that can be used as function decorators. Define functions that either do the actual transformation (for `~astropy.coordinates.FunctionTransform`), or that compute the necessary transformation matrices to transform. Then decorate the functions to register these transformations with the frame transform graph:: from astropy.coordinates import frame_transform_graph @frame_transform_graph.transform(DynamicMatrixTransform, ICRS, FK5) def icrs_to_fk5(icrscoord, fk5frame): ... @frame_transform_graph.transform(DynamicMatrixTransform, FK5, ICRS) def fk5_to_icrs(fk5coord, icrsframe): ... If the transformation to your coordinate frame of interest is not representable by a matrix operation, you can also specify a function to do the actual transformation, and pass the `~astropy.coordinates.FunctionTransform` class to the transform graph decorator instead:: @frame_transform_graph.transform(FunctionTransform, FK4NoETerms, FK4) def fk4_no_e_to_fk4(fk4noecoord, fk4frame): ... Furthermore, the ``frame_transform_graph`` does some caching and optimization to speed up transformations after the first attempt to go from one frame to another, and shortcuts steps where relevant (for example, combining multiple static matrix transforms into a single matrix). Hence, in general, it is better to define whatever are the most natural transformations for a user-defined frame, rather than worrying about optimizing or caching a transformation to speed up the process. For a demonstration of how to define transformation functions that also work for transforming velocity components, see :ref:`astropy-coordinate-transform-with-velocities`. Supporting Velocity Data in Frames ---------------------------------- As alluded to by point (4) in the :ref:`introduction above `, the examples we have seen above mostly deal with customizing frame behavior for positional information. (For some context about how velocities are handled in ``astropy.coordinates``, it may be useful to read the overview: :ref:`astropy-coordinate-custom-frame-with-velocities`.) When defining a frame class, it is also possible to set a ``default_differential`` (analogous to ``default_representation``), and to customize how velocity data components are named. Expanding on our custom frame example above, we can use `~astropy.coordinates.RepresentationMapping` to override ``Differential`` component names. The default ``Differential`` components are typically named after the corresponding ``Representation`` component, preceded by ``d_``. So, for example, the longitude ``Differential`` component is, by default, ``d_lon``. However, there are some defaults to be aware of. Here, if we set the default ``Differential`` class to also be Spherical, it will implement a set of default "nicer" names for the velocity components, mapping ``pm_R`` to ``d_lon``, ``pm_D`` to ``d_lat``, and ``radial_velocity`` to ``d_distance`` (taking the previously overridden longitude and latitude component names):: >>> class MyFrame4WithVelocity(BaseCoordinateFrame): ... # Specify how coordinate values are represented when outputted ... default_representation = r.SphericalRepresentation ... default_differential = r.SphericalDifferential ... ... # Override component names (e.g., "ra" instead of "lon") ... frame_specific_representation_info = { ... r.SphericalRepresentation: [RepresentationMapping('lon', 'R'), ... RepresentationMapping('lat', 'D')], ... r.CartesianRepresentation: [RepresentationMapping('x', 'a'), ... RepresentationMapping('y', 'b'), ... RepresentationMapping('z', 'c')] ... } >>> fr = MyFrame4WithVelocity(R=1*u.deg, D=2*u.deg, ... pm_R=3*u.mas/u.yr, pm_D=4*u.mas/u.yr) >>> fr # doctest: +FLOAT_CMP If you want to override the default "nicer" names, you can specify a new key in the ``frame_specific_representation_info`` for any of the ``Differential`` classes, for example:: >>> class MyFrame4WithVelocity2(BaseCoordinateFrame): ... # Specify how coordinate values are represented when outputted ... default_representation = r.SphericalRepresentation ... default_differential = r.SphericalDifferential ... ... # Override component names (e.g., "ra" instead of "lon") ... frame_specific_representation_info = { ... r.SphericalRepresentation: [RepresentationMapping('lon', 'R'), ... RepresentationMapping('lat', 'D')], ... r.CartesianRepresentation: [RepresentationMapping('x', 'a'), ... RepresentationMapping('y', 'b'), ... RepresentationMapping('z', 'c')], ... r.SphericalDifferential: [RepresentationMapping('d_lon', 'pm1'), ... RepresentationMapping('d_lat', 'pm2'), ... RepresentationMapping('d_distance', 'rv')] ... } >>> fr = MyFrame4WithVelocity2(R=1*u.deg, D=2*u.deg, ... pm1=3*u.mas/u.yr, pm2=4*u.mas/u.yr) >>> fr # doctest: +FLOAT_CMP Final Notes ----------- You can also define arbitrary methods for any added functionality you want your frame to have that is unique to that frame. These methods will be available in any |SkyCoord| that is created using your user-defined frame. For examples of defining frame classes, the first place to look is at the source code for the frames that are included in ``astropy`` (available at ``astropy.coordinates.builtin_frames``). These are not special-cased, but rather use all of the same API and features available to user-created frames. .. topic:: Examples: See also :ref:`sphx_glr_generated_examples_coordinates_plot_sgr-coordinate-frame.py` for a more annotated example of defining a new coordinate frame. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/coordinates/galactocentric.rst0000644000175100001710000002753600000000000021240 0ustar00vstsdocker.. _coordinates-galactocentric: ************************************************** Description of the Galactocentric Coordinate Frame ************************************************** While many other frames implemented in `astropy.coordinates` are standardized in some way (e.g., defined by the IAU), there is no standard Milky Way reference frame with the center of the Milky Way as its origin. (This is distinct from `~astropy.coordinates.Galactic` coordinates, which point toward the Galactic Center but have their origin in the Solar System). The `~astropy.coordinates.Galactocentric` frame class is meant to be flexible enough to support all common definitions of such a transformation, but with reasonable default parameter values, such as the solar velocity relative to the Galactic center, the solar height above the Galactic midplane, etc. Below, :ref:`we describe our generalized definition of the transformation ` from the ICRS to/from Galactocentric coordinates, and :ref:`describe how to customize the default Galactocentric parameters ` that are used when the `~astropy.coordinates.Galactocentric` frame is initialized without explicitly passing in parameter values. .. _astropy-coordinates-galactocentric-transformation: Definition of the Transformation ================================ This document describes the mathematics behind the transformation from `~astropy.coordinates.ICRS` to `~astropy.coordinates.Galactocentric` coordinates. This is described in detail here on account of the mathematical subtleties and the fact that there is no official standard/definition for this frame. For examples of how to use this transformation in code, see the the *Examples* section of the `~astropy.coordinates.Galactocentric` class documentation. We assume that we start with a 3D position in the ICRS reference frame: a Right Ascension, Declination, and heliocentric distance, :math:`(\alpha, \delta, d)`. We can convert this to a Cartesian position using the standard transformation from Cartesian to spherical coordinates: .. math:: \begin{aligned} x_{\rm icrs} &= d\cos{\alpha}\cos{\delta}\\ y_{\rm icrs} &= d\sin{\alpha}\cos{\delta}\\ z_{\rm icrs} &= d\sin{\delta}\\ \boldsymbol{r}_{\rm icrs} &= \begin{pmatrix} x_{\rm icrs}\\ y_{\rm icrs}\\ z_{\rm icrs} \end{pmatrix}\end{aligned} The first transformation rotates the :math:`x_{\rm icrs}` axis so that the new :math:`x'` axis points towards the Galactic Center (GC), specified by the ICRS position :math:`(\alpha_{\rm GC}, \delta_{\rm GC})` (in the `~astropy.coordinates.Galactocentric` frame, this is controlled by the frame attribute ``galcen_coord``): .. math:: \begin{aligned} \boldsymbol{R}_1 &= \begin{bmatrix} \cos\delta_{\rm GC}& 0 & \sin\delta_{\rm GC}\\ 0 & 1 & 0 \\ -\sin\delta_{\rm GC}& 0 & \cos\delta_{\rm GC}\end{bmatrix}\\ \boldsymbol{R}_2 &= \begin{bmatrix} \cos\alpha_{\rm GC}& \sin\alpha_{\rm GC}& 0\\ -\sin\alpha_{\rm GC}& \cos\alpha_{\rm GC}& 0\\ 0 & 0 & 1 \end{bmatrix}.\end{aligned} The transformation thus far has aligned the :math:`x'` axis with the vector pointing from the Sun to the GC, but the :math:`y'` and :math:`z'` axes point in arbitrary directions. We adopt the orientation of the Galactic plane as the normal to the north pole of Galactic coordinates defined by the IAU (`Blaauw et. al. 1960 `_). This extra “roll” angle, :math:`\eta`, was measured by transforming a grid of points along :math:`l=0` to this interim frame and minimizing the square of their :math:`y'` positions. We find: .. math:: \begin{aligned} \eta &= 58.5986320306^\circ\\ \boldsymbol{R}_3 &= \begin{bmatrix} 1 & 0 & 0\\ 0 & \cos\eta & \sin\eta\\ 0 & -\sin\eta & \cos\eta \end{bmatrix}\end{aligned} The full rotation matrix thus far is: .. math:: \begin{gathered} \boldsymbol{R} = \boldsymbol{R}_3 \boldsymbol{R}_1 \boldsymbol{R}_2 = \\ \begin{bmatrix} \cos\alpha_{\rm GC}\cos\delta_{\rm GC}& \cos\delta_{\rm GC}\sin\alpha_{\rm GC}& -\sin\delta_{\rm GC}\\ \cos\alpha_{\rm GC}\sin\delta_{\rm GC}\sin\eta - \sin\alpha_{\rm GC}\cos\eta & \sin\alpha_{\rm GC}\sin\delta_{\rm GC}\sin\eta + \cos\alpha_{\rm GC}\cos\eta & \cos\delta_{\rm GC}\sin\eta\\ \cos\alpha_{\rm GC}\sin\delta_{\rm GC}\cos\eta + \sin\alpha_{\rm GC}\sin\eta & \sin\alpha_{\rm GC}\sin\delta_{\rm GC}\cos\eta - \cos\alpha_{\rm GC}\sin\eta & \cos\delta_{\rm GC}\cos\eta \end{bmatrix}\end{gathered} With the rotated position vector :math:`\boldsymbol{R}\boldsymbol{r}_{\rm icrs}`, we can now subtract the distance to the GC, :math:`d_{\rm GC}`, which is purely along the :math:`x'` axis: .. math:: \begin{aligned} \boldsymbol{r}' &= \boldsymbol{R}\boldsymbol{r}_{\rm icrs} - d_{\rm GC}\hat{\boldsymbol{x}}_{\rm GC}.\end{aligned} where :math:`\hat{\boldsymbol{x}}_{\rm GC} = (1,0,0)^{\mathsf{T}}`. The final transformation accounts for the (specified) height of the Sun above the Galactic midplane by rotating about the final :math:`y''` axis by the angle :math:`\theta= \sin^{-1}(z_\odot / d_{\rm GC})`: .. math:: \begin{aligned} \boldsymbol{H} &= \begin{bmatrix} \cos\theta & 0 & \sin\theta\\ 0 & 1 & 0\\ -\sin\theta & 0 & \cos\theta \end{bmatrix}\end{aligned} where :math:`z_\odot` is the measured height of the Sun above the midplane. The full transformation is then: .. math:: \boldsymbol{r}_{\rm GC} = \boldsymbol{H} \left( \boldsymbol{R}\boldsymbol{r}_{\rm icrs} - d_{\rm GC}\hat{\boldsymbol{x}}_{\rm GC}\right). .. topic:: Examples: For an example of how to use the `~astropy.coordinates.Galactocentric` frame, see :ref:`sphx_glr_generated_examples_coordinates_plot_galactocentric-frame.py`. .. _astropy-coordinates-galactocentric-defaults: Controlling the Default Frame Parameters ======================================== All of the frame-defining parameters of the `~astropy.coordinates.Galactocentric` frame are customizable and can be set by passing arguments in to the `~astropy.coordinates.Galactocentric` initializer. However, it is often convenient to use the frame without having to pass in every parameter. Hence, the class comes with reasonable default values for these parameters, but more precise measurements of the solar position or motion in the Galaxy are constantly being made. The default values of the `~astropy.coordinates.Galactocentric` frame attributes will therefore be updated as necessary with subsequent releases of ``astropy``. We therefore provide a mechanism to globally or locally control the default parameter values used in this frame through the `~astropy.coordinates.galactocentric_frame_defaults` `~astropy.utils.state.ScienceState` class. The `~astropy.coordinates.galactocentric_frame_defaults` class controls the default parameter settings in `~astropy.coordinates.Galactocentric` by mapping a set of string names to particular choices of the parameter values. For an up-to-date list of valid names, see the docstring of `~astropy.coordinates.galactocentric_frame_defaults`, but these names are things like ``'pre-v4.0'``, which sets the default parameter values to their original definition (i.e. pre-astropy-v4.0) values, and ``'v4.0'``, which sets the default parameter values to a more modern set of measurements as updated in Astropy version 4.0. Also, custom sets of measurements can be registered to `~astropy.coordinates.galactocentric_frame_defaults` and used like the built-in options. `~astropy.coordinates.galactocentric_frame_defaults` also tracks the references (i.e. scientific papers that define the parameter values) for all parameter values, as well as any further specified metadata information. As with other `~astropy.utils.state.ScienceState` subclasses, the `~astropy.coordinates.galactocentric_frame_defaults` class can be used to globally set the frame defaults at runtime. Examples -------- .. EXAMPLE START Setting Galactocentric Coordinate Frame Defaults at Runtime The default parameter values can be seen by initializing the `~astropy.coordinates.Galactocentric` frame with no arguments: :: >>> from astropy.coordinates import Galactocentric >>> Galactocentric() , galcen_distance=8.122 kpc, galcen_v_sun=(12.9, 245.6, 7.78) km / s, z_sun=20.8 pc, roll=0.0 deg)> These default values can be modified using this class:: >>> from astropy.coordinates import galactocentric_frame_defaults >>> _ = galactocentric_frame_defaults.set('v4.0') # doctest: +SKIP >>> Galactocentric() # doctest: +SKIP , galcen_distance=8.122 kpc, galcen_v_sun=(12.9, 245.6, 7.78) km / s, z_sun=20.8 pc, roll=0.0 deg)> >>> _ = galactocentric_frame_defaults.set('pre-v4.0') # doctest: +SKIP >>> Galactocentric() # doctest: +SKIP , galcen_distance=8.3 kpc, galcen_v_sun=(11.1, 232.24, 7.25) km / s, z_sun=27.0 pc, roll=0.0 deg)> The default parameters can also be updated by using this class as a context manager to change the default parameter values locally to a piece of your code:: >>> with galactocentric_frame_defaults.set('pre-v4.0'): ... print(Galactocentric()) # doctest: +FLOAT_CMP , galcen_distance=8.3 kpc, galcen_v_sun=(11.1, 232.24, 7.25) km / s, z_sun=27.0 pc, roll=0.0 deg)> Again, changing the default parameter values will not affect frame attributes that are explicitly specified:: >>> import astropy.units as u >>> with galactocentric_frame_defaults.set('pre-v4.0'): ... print(Galactocentric(galcen_distance=8.0*u.kpc)) # doctest: +FLOAT_CMP , galcen_distance=8.0 kpc, galcen_v_sun=(11.1, 232.24, 7.25) km / s, z_sun=27.0 pc, roll=0.0 deg)> Additional parameter sets may be registered, for instance to use the Dehnen & Binney (1998) measurements of the solar motion. We can also add metadata, such as the 1-sigma errors:: >>> state = galactocentric_frame_defaults.get_from_registry("v4.0") >>> state["parameters"]["galcen_v_sun"] = (10.00, 225.25, 7.17) * (u.km / u.s) >>> state["references"]["galcen_v_sun"] = "http://www.adsabs.harvard.edu/full/1998MNRAS.298..387D" >>> state["error"] = {"galcen_v_sun": (0.36, 0.62, 0.38) * (u.km / u.s)} >>> galactocentric_frame_defaults.register(name="DB1998", **state) Just as in the previous examples, the new parameter set can be get / set:: >>> state = galactocentric_frame_defaults.get_from_registry("DB1998") >>> print(state["error"]["galcen_v_sun"]) # doctest: +FLOAT_CMP [0.36 0.62 0.38] km / s .. EXAMPLE END Unless set with the `~astropy.coordinates.galactocentric_frame_defaults` class, the default parameter values for the `~astropy.coordinates.Galactocentric` frame are set to ``'latest'``, meaning that the default parameter values may change if you update Astropy. If you use the `~astropy.coordinates.Galactocentric` frame without specifying all parameter values explicitly, we therefore suggest manually setting the frame default set manually in any science code that depends sensitively on the choice of, e.g., solar motion or the other frame parameters. For example, in such code, we recommend adding something like this to your import block (here using ``'v4.0'`` as an example):: >>> import astropy.coordinates as coord >>> coord.galactocentric_frame_defaults.set('v4.0') # doctest: +SKIP ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/coordinates/index.rst0000644000175100001710000005250700000000000017361 0ustar00vstsdocker.. We call EarthLocation.of_site here first to force the downloading .. of sites.json so that future doctest output isn't cluttered with .. "Downloading ... [done]". This can be removed once we have a better .. way of ignoring output lines based on pattern-matching, e.g.: .. https://github.com/astropy/pytest-doctestplus/issues/11 .. testsetup:: >>> from astropy.coordinates import EarthLocation >>> EarthLocation.of_site('greenwich') # doctest: +IGNORE_OUTPUT +IGNORE_WARNINGS .. _astropy-coordinates: ******************************************************* Astronomical Coordinate Systems (`astropy.coordinates`) ******************************************************* Introduction ============ The `~astropy.coordinates` package provides classes for representing a variety of celestial/spatial coordinates and their velocity components, as well as tools for converting between common coordinate systems in a uniform way. Getting Started =============== The best way to start using `~astropy.coordinates` is to use the |SkyCoord| class. |SkyCoord| objects are instantiated by passing in positions (and optional velocities) with specified units and a coordinate frame. Sky positions are commonly passed in as `~astropy.units.Quantity` objects and the frame is specified with the string name. Example ------- .. EXAMPLE START Using the SkyCoord Class To create a |SkyCoord| object to represent an ICRS (Right ascension [RA], Declination [Dec]) sky position:: >>> from astropy import units as u >>> from astropy.coordinates import SkyCoord >>> c = SkyCoord(ra=10.625*u.degree, dec=41.2*u.degree, frame='icrs') The initializer for |SkyCoord| is very flexible and supports inputs provided in a number of convenient formats. The following ways of initializing a coordinate are all equivalent to the above:: >>> c = SkyCoord(10.625, 41.2, frame='icrs', unit='deg') >>> c = SkyCoord('00h42m30s', '+41d12m00s', frame='icrs') >>> c = SkyCoord('00h42.5m', '+41d12m') >>> c = SkyCoord('00 42 30 +41 12 00', unit=(u.hourangle, u.deg)) >>> c = SkyCoord('00:42.5 +41:12', unit=(u.hourangle, u.deg)) >>> c # doctest: +FLOAT_CMP The examples above illustrate a few rules to follow when creating a coordinate object: - Coordinate values can be provided either as unnamed positional arguments or via keyword arguments like ``ra`` and ``dec``, or ``l`` and ``b`` (depending on the frame). - The coordinate ``frame`` keyword is optional because it defaults to `~astropy.coordinates.ICRS`. - Angle units must be specified for all components, either by passing in a `~astropy.units.Quantity` object (e.g., ``10.5*u.degree``), by including them in the value (e.g., ``'+41d12m00s'``), or via the ``unit`` keyword. .. EXAMPLE END |SkyCoord| and all other `~astropy.coordinates` objects also support array coordinates. These work in the same way as single-value coordinates, but they store multiple coordinates in a single object. When you are going to apply the same operation to many different coordinates (say, from a catalog), this is a better choice than a list of |SkyCoord| objects, because it will be *much* faster than applying the operation to each |SkyCoord| in a ``for`` loop. Like the underlying `~numpy.ndarray` instances that contain the data, |SkyCoord| objects can be sliced, reshaped, etc., and can be used with functions like `numpy.moveaxis`, etc., that affect the shape:: >>> import numpy as np >>> c = SkyCoord(ra=[10, 11, 12, 13]*u.degree, dec=[41, -5, 42, 0]*u.degree) >>> c >>> c[1] >>> c.reshape(2, 2) >>> np.roll(c, 1) Coordinate Access ----------------- Once you have a coordinate object you can access the components of that coordinate (e.g., RA, Dec) to get string representations of the full coordinate. The component values are accessed using (typically lowercase) named attributes that depend on the coordinate frame (e.g., ICRS, Galactic, etc.). For the default, ICRS, the coordinate component names are ``ra`` and ``dec``:: >>> c = SkyCoord(ra=10.68458*u.degree, dec=41.26917*u.degree) >>> c.ra # doctest: +FLOAT_CMP >>> c.ra.hour # doctest: +FLOAT_CMP 0.7123053333333335 >>> c.ra.hms # doctest: +FLOAT_CMP hms_tuple(h=0.0, m=42.0, s=44.299200000000525) >>> c.dec # doctest: +FLOAT_CMP >>> c.dec.degree # doctest: +FLOAT_CMP 41.26917 >>> c.dec.radian # doctest: +FLOAT_CMP 0.7202828960652683 Coordinates can be converted to strings using the :meth:`~astropy.coordinates.SkyCoord.to_string` method:: >>> c = SkyCoord(ra=10.68458*u.degree, dec=41.26917*u.degree) >>> c.to_string('decimal') '10.6846 41.2692' >>> c.to_string('dms') '10d41m04.488s 41d16m09.012s' >>> c.to_string('hmsdms') '00h42m44.2992s +41d16m09.012s' For additional information see the section on :ref:`working_with_angles`. Transformation -------------- One convenient way to transform to a new coordinate frame is by accessing the appropriately named attribute. Example ^^^^^^^ .. EXAMPLE START Transforming to a New Coordinate Frame To get the coordinate in the `~astropy.coordinates.Galactic` frame use:: >>> c_icrs = SkyCoord(ra=10.68458*u.degree, dec=41.26917*u.degree, frame='icrs') >>> c_icrs.galactic # doctest: +FLOAT_CMP For more control, you can use the `~astropy.coordinates.SkyCoord.transform_to` method, which accepts a frame name, frame class, or frame instance:: >>> c_fk5 = c_icrs.transform_to('fk5') # c_icrs.fk5 does the same thing >>> c_fk5 # doctest: +FLOAT_CMP >>> from astropy.coordinates import FK5 >>> c_fk5.transform_to(FK5(equinox='J1975')) # precess to a different equinox # doctest: +FLOAT_CMP .. EXAMPLE END This form of `~astropy.coordinates.SkyCoord.transform_to` also makes it possible to convert from celestial coordinates to `~astropy.coordinates.AltAz` coordinates, allowing the use of |SkyCoord| as a tool for planning observations. For a more complete example of this, see :ref:`sphx_glr_generated_examples_coordinates_plot_obs-planning.py`. Some coordinate frames such as `~astropy.coordinates.AltAz` require Earth rotation information (UT1-UTC offset and/or polar motion) when transforming to/from other frames. These Earth rotation values are automatically downloaded from the International Earth Rotation and Reference Systems (IERS) service when required. See :ref:`utils-iers` for details of this process. Representation -------------- So far we have been using a spherical coordinate representation in all of our examples, and this is the default for the built-in frames. Frequently it is convenient to initialize or work with a coordinate using a different representation such as Cartesian or Cylindrical. This can be done by setting the ``representation_type`` for either |SkyCoord| objects or low-level frame coordinate objects. Example ^^^^^^^ .. EXAMPLE START Working with Nonspherical Coordinate Representations To initialize or work with a coordinate using a different representation such as Cartesian or Cylindrical:: >>> c = SkyCoord(x=1, y=2, z=3, unit='kpc', representation_type='cartesian') >>> c # doctest: +FLOAT_CMP >>> c.x, c.y, c.z # doctest: +FLOAT_CMP (, , ) >>> c.representation_type = 'cylindrical' >>> c # doctest: +FLOAT_CMP For all of the details see :ref:`astropy-skycoord-representations`. .. EXAMPLE END Distance -------- |SkyCoord| and the individual frame classes also support specifying a distance from the frame origin. The origin depends on the particular coordinate frame; this can be, for example, centered on the earth, centered on the solar system barycenter, etc. Examples ^^^^^^^^ .. EXAMPLE START Specifying a Distance with SkyCoord Two angles and a distance specify a unique point in 3D space, which also allows converting the coordinates to a Cartesian representation:: >>> c = SkyCoord(ra=10.68458*u.degree, dec=41.26917*u.degree, distance=770*u.kpc) >>> c.cartesian.x # doctest: +FLOAT_CMP >>> c.cartesian.y # doctest: +FLOAT_CMP >>> c.cartesian.z # doctest: +FLOAT_CMP With distances assigned, |SkyCoord| convenience methods are more powerful, as they can make use of the 3D information. For example, to compute the physical, 3D separation between two points in space:: >>> c1 = SkyCoord(ra=10*u.degree, dec=9*u.degree, distance=10*u.pc, frame='icrs') >>> c2 = SkyCoord(ra=11*u.degree, dec=10*u.degree, distance=11.5*u.pc, frame='icrs') >>> c1.separation_3d(c2) # doctest: +FLOAT_CMP .. EXAMPLE END Convenience Methods ------------------- |SkyCoord| defines a number of convenience methods that support, for example, computing on-sky (i.e., angular) and 3D separations between two coordinates. Examples ^^^^^^^^ .. EXAMPLE START SkyCoord Convenience Methods To compute on-sky and 3D separations between two coordinates:: >>> c1 = SkyCoord(ra=10*u.degree, dec=9*u.degree, frame='icrs') >>> c2 = SkyCoord(ra=11*u.degree, dec=10*u.degree, frame='fk5') >>> c1.separation(c2) # Differing frames handled correctly # doctest: +FLOAT_CMP Or cross-matching catalog coordinates (detailed in :ref:`astropy-coordinates-matching`):: >>> target_c = SkyCoord(ra=10*u.degree, dec=9*u.degree, frame='icrs') >>> # read in coordinates from a catalog... >>> catalog_c = ... # doctest: +SKIP >>> idx, sep, _ = target_c.match_to_catalog_sky(catalog_c) # doctest: +SKIP .. EXAMPLE END The `astropy.coordinates` sub-package also provides a quick way to get coordinates for named objects, assuming you have an active internet connection. The `~astropy.coordinates.SkyCoord.from_name` method of |SkyCoord| uses `Sesame `_ to retrieve coordinates for a particular named object. .. EXAMPLE START Retrieving Coordinates for a Named Object with SkyCoord To retrieve coordinates for a particular named object:: >>> SkyCoord.from_name("PSR J1012+5307") # doctest: +REMOTE_DATA +FLOAT_CMP In some cases, the coordinates are embedded in the catalog name of the object. For such object names, `~astropy.coordinates.SkyCoord.from_name` is able to parse the coordinates from the name if given the ``parse=True`` option. For slow connections, this may be much faster than a sesame query for the same object name. It's worth noting, however, that the coordinates extracted in this way may differ from the database coordinates by a few deci-arcseconds, so only use this option if you do not need sub-arcsecond accuracy for your coordinates:: >>> SkyCoord.from_name("CRTS SSS100805 J194428-420209", parse=True) # doctest: +FLOAT_CMP .. EXAMPLE END .. testsetup:: >>> from astropy.coordinates import EarthLocation, SkyCoord >>> apo = EarthLocation(-1463969.30185172, -5166673.34223433, 3434985.71204565, unit='m') >>> keck = EarthLocation(-5464487.81759887, -2492806.59108569, 2151240.19451846, unit='m') >>> target = SkyCoord(10.68470833, 41.26875, unit='deg') # M31 For sites (primarily observatories) on the Earth, `astropy.coordinates` provides a quick way to get an `~astropy.coordinates.EarthLocation` - the `~astropy.coordinates.EarthLocation.of_site` method:: >>> from astropy.coordinates import EarthLocation >>> apo = EarthLocation.of_site('Apache Point Observatory') # doctest: +SKIP >>> apo # doctest: +FLOAT_CMP To see the list of site names available, use :func:`astropy.coordinates.EarthLocation.get_site_names`. For arbitrary Earth addresses (e.g., not observatory sites), use the `~astropy.coordinates.EarthLocation.of_address` classmethod. Any address passed to this function uses Google maps to retrieve the latitude and longitude and can also (optionally) query Google maps to get the height of the location. As with Google maps, this works with fully specified addresses, location names, city names, etc.: .. doctest-skip:: >>> EarthLocation.of_address('1002 Holy Grail Court, St. Louis, MO') >>> EarthLocation.of_address('1002 Holy Grail Court, St. Louis, MO', ... get_height=True) >>> EarthLocation.of_address('Danbury, CT') .. note:: `~astropy.coordinates.SkyCoord.from_name`, `~astropy.coordinates.EarthLocation.of_site`, and `~astropy.coordinates.EarthLocation.of_address` are for convenience, and hence are by design relatively low precision. If you need more precise coordinates for an object you should find the appropriate reference and input the coordinates manually, or use more specialized functionality like that in the `astroquery `_ or `astroplan `_ affiliated packages. Also note that these methods retrieve data from the internet to determine the celestial or Earth coordinates. The online data may be updated, so if you need to guarantee that your scripts are reproducible in the long term, see the :doc:`remote_methods` section. This functionality can be combined to do more complicated tasks like computing barycentric corrections to radial velocity observations (also a supported high-level |SkyCoord| method - see :ref:`astropy-coordinates-rv-corrs`):: >>> from astropy.time import Time >>> obstime = Time('2017-2-14') >>> target = SkyCoord.from_name('M31') # doctest: +SKIP >>> keck = EarthLocation.of_site('Keck') # doctest: +SKIP >>> target.radial_velocity_correction(obstime=obstime, location=keck).to('km/s') # doctest: +FLOAT_CMP +REMOTE_DATA While ``astropy.coordinates`` does not natively support converting an Earth location to a timezone, the longitude and latitude can be retrieved from any `~astropy.coordinates.EarthLocation` object, which could then be passed to any third-party package that supports timezone solving, such as `timezonefinder `_. For example, ``timezonefinder`` can be used to retrieve the timezone name for an address with: .. doctest-skip:: >>> loc = EarthLocation.of_address('Tucson, AZ') >>> from timezonefinder import TimezoneFinder >>> tz_name = TimezoneFinder().timezone_at(lng=loc.lon.degree, ... lat=loc.lat.degree) >>> tz_name 'America/Phoenix' The resulting timezone name could then be used with any packages that support time zone definitions, such as the (Python 3.9 default package) `zoneinfo `_: .. doctest-skip:: >>> from zoneinfo import ZoneInfo # requires Python 3.9 or greater >>> tz = ZoneInfo(tz_name) >>> dt = datetime.datetime(2021, 4, 12, 20, 0, 0, tzinfo=tz) (Please note that the above code is not tested regularly with the ``astropy`` test suite, so please raise an issue if this no longer works.) Velocities (Proper Motions and Radial Velocities) ------------------------------------------------- In addition to positional coordinates, `~astropy.coordinates` supports storing and transforming velocities. These are available both via the lower-level :doc:`coordinate frame classes `, and via |SkyCoord| objects:: >>> sc = SkyCoord(1*u.deg, 2*u.deg, radial_velocity=20*u.km/u.s) >>> sc # doctest: +FLOAT_CMP For more details on velocity support (and limitations), see the :doc:`velocities` page. .. _astropy-coordinates-overview: Overview of `astropy.coordinates` Concepts ========================================== .. note :: More detailed information and justification of the design is available in `APE (Astropy Proposal for Enhancement) 5 `_. Here we provide an overview of the package and associated framework. This background information is not necessary for using `~astropy.coordinates`, particularly if you use the |SkyCoord| high-level class, but it is helpful for more advanced usage, particularly creating your own frame, transformations, or representations. Another useful piece of background information are some :ref:`astropy-coordinates-definitions` as they are used in `~astropy.coordinates`. `~astropy.coordinates` is built on a three-tiered system of objects: representations, frames, and a high-level class. Representations classes are a particular way of storing a three-dimensional data point (or points), such as Cartesian coordinates or spherical polar coordinates. Frames are particular reference frames like FK5 or ICRS, which may store their data in different representations, but have well- defined transformations between each other. These transformations are all stored in the ``astropy.coordinates.frame_transform_graph``, and new transformations can be created by users. Finally, the high-level class (|SkyCoord|) uses the frame classes, but provides a more accessible interface to these objects as well as various convenience methods and more string-parsing capabilities. Separating these concepts makes it easier to extend the functionality of `~astropy.coordinates`. It allows representations, frames, and transformations to be defined or extended separately, while still preserving the high-level capabilities and ease-of-use of the |SkyCoord| class. .. topic:: Examples: See :ref:`sphx_glr_generated_examples_coordinates_plot_obs-planning.py` for an example of using the `~astropy.coordinates` functionality to prepare for an observing run. Using `astropy.coordinates` =========================== More detailed information on using the package is provided on separate pages, listed below. .. toctree:: :maxdepth: 1 angles skycoord transforming solarsystem satellites formatting matchsep representations frames velocities apply_space_motion spectralcoord galactocentric remote_methods common_errors definitions inplace In addition, another resource for the capabilities of this package is the ``astropy.coordinates.tests.test_api_ape5`` testing file. It showcases most of the major capabilities of the package, and hence is a useful supplement to this document. You can see it by either downloading a copy of the Astropy source code, or typing the following in an IPython session:: In [1]: from astropy.coordinates.tests import test_api_ape5 In [2]: test_api_ape5?? .. note that if this section gets too long, it should be moved to a separate doc page - see the top of performance.inc.rst for the instructions on how to do that .. include:: performance.inc.rst .. _astropy-coordinates-seealso: See Also ======== Some references that are particularly useful in understanding subtleties of the coordinate systems implemented here include: * `USNO Circular 179 `_ A useful guide to the IAU 2000/2003 work surrounding ICRS/IERS/CIRS and related problems in precision coordinate system work. * `Standards Of Fundamental Astronomy `_ The definitive implementation of IAU-defined algorithms. The "SOFA Tools for Earth Attitude" document is particularly valuable for understanding the latest IAU standards in detail. * `IERS Conventions (2010) `_ An exhaustive reference covering the ITRS, the IAU2000 celestial coordinates framework, and other related details of modern coordinate conventions. * Meeus, J. "Astronomical Algorithms" A valuable text describing details of a wide range of coordinate-related problems and concepts. * `Revisiting Spacetrack Report #3 `_ A discussion of the simplified general perturbation (SGP) for satellite orbits, with a description of the True Equator Mean Equinox (TEME) coordinate frame. Built-in Frame Classes ====================== .. automodapi:: astropy.coordinates.builtin_frames :skip: make_transform_graph_docs :no-inheritance-diagram: .. _astropy-coordinates-api: Reference/API ============= .. automodapi:: astropy.coordinates ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/coordinates/inplace.rst0000644000175100001710000000435600000000000017664 0ustar00vstsdocker.. _astropy-coordinates-fast-in-place: Fast In-Place Modification of Coordinates ***************************************** For some applications the recommended method of :ref:`astropy-coordinates-modifying-in-place` may not be fast enough due to the extensive validation performed in that process to ensure correctness. Likewise, you may find that creating another coordinate frame with different data using `~astropy.coordinates.BaseCoordinateFrame.realize_frame` does not meet your performance requirements. For these high-performance situations, you can directly modify in-place the representation data in the frame object as shown in this example:: >>> import astropy.units as u >>> from astropy.coordinates import SkyCoord >>> sc = SkyCoord([1,2],[3,4], unit='deg') >>> sc.data.lon[()] = [10, 20] * u.deg >>> sc.data.lat[1] = 40 * u.deg >>> sc.cache.clear() # IMPORTANT TO DO THIS! >>> sc # doctest: +FLOAT_CMP Notice that the ``.data`` representation object uses different names for the components than in the coordinate object. If you wish to inspect the mapping between frame attributes (e.g., ``.ra``) and representation attributes (e.g., ``.lon``) you can look at the following dictionary:: >>> sc.representation_component_names {'ra': 'lon', 'dec': 'lat', 'distance': 'distance'} .. warning:: You *must* include the step to clear the cache as shown. Failing to do so will cause the object to be inconsistent and likely result in incorrect results. `~astropy.coordinates.SkyCoord` and `~astropy.coordinates.BaseCoordinateFrame` cache various kinds of information for performance reasons, so you need clear the cache so that the new representation values are used when required. You should note that the only way to modify the data in a frame is by using the ``.data`` attribute directly and not the aliases for components on the frame. For example the following will *appear* to give a correct result but it does not actually modify the underlying representation data:: >>> sc.ra[1] = 20 * u.deg # THIS IS WRONG This problem is related to the current implementation of performance-based caching and cannot be easily resolved. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/coordinates/matchsep.rst0000644000175100001710000003411700000000000020053 0ustar00vstsdocker.. _astropy-coordinates-separations-matching: Separations, Offsets, Catalog Matching, and Related Functionality ***************************************************************** `astropy.coordinates` contains commonly-used tools for comparing or matching coordinate objects. Of particular importance are those for determining separations between coordinates and those for matching a coordinate (or coordinates) to a catalog. These are mainly implemented as methods on the coordinate objects. In the examples below, we will assume that the following imports have already been executed:: >>> import astropy.units as u >>> from astropy.coordinates import SkyCoord Separations =========== The on-sky separation can be computed with the :meth:`astropy.coordinates.BaseCoordinateFrame.separation` or :meth:`astropy.coordinates.SkyCoord.separation` methods, which computes the great-circle distance (*not* the small-angle approximation):: >>> c1 = SkyCoord('5h23m34.5s', '-69d45m22s', frame='icrs') >>> c2 = SkyCoord('0h52m44.8s', '-72d49m43s', frame='fk5') >>> sep = c1.separation(c2) >>> sep # doctest: +FLOAT_CMP The returned object is an `~astropy.coordinates.Angle` instance, so it is possible to access the angle in any of several equivalent angular units:: >>> sep.radian # doctest: +FLOAT_CMP 0.36208800460262563 >>> sep.hour # doctest: +FLOAT_CMP 1.3830742984029318 >>> sep.arcminute # doctest: +FLOAT_CMP 1244.7668685626384 >>> sep.arcsecond # doctest: +FLOAT_CMP 74686.0121137583 Also note that the two input coordinates were not in the same frame — one is automatically converted to match the other, ensuring that even though they are in different frames, the separation is determined consistently. In addition to the on-sky separation described above, :meth:`astropy.coordinates.BaseCoordinateFrame.separation_3d` or :meth:`astropy.coordinates.SkyCoord.separation_3d` methods will determine the 3D distance between two coordinates that have ``distance`` defined:: >>> c1 = SkyCoord('5h23m34.5s', '-69d45m22s', distance=70*u.kpc, frame='icrs') >>> c2 = SkyCoord('0h52m44.8s', '-72d49m43s', distance=80*u.kpc, frame='icrs') >>> sep = c1.separation_3d(c2) >>> sep # doctest: +FLOAT_CMP Offsets ======= Closely related to angular separations are offsets between coordinates. The key distinction for offsets is generally the concept of a "from" and "to" coordinate rather than the single scalar angular offset of a separation. `~astropy.coordinates` contains conveniences to compute some of the common offsets encountered in astronomy. The first piece of such functionality is the :meth:`~astropy.coordinates.SkyCoord.position_angle` method. This method computes the position angle between one |SkyCoord| instance and another (passed as the argument) following the astronomy convention (positive angles East of North):: >>> c1 = SkyCoord(1*u.deg, 1*u.deg, frame='icrs') >>> c2 = SkyCoord(2*u.deg, 2*u.deg, frame='icrs') >>> c1.position_angle(c2).to(u.deg) # doctest: +FLOAT_CMP The combination of :meth:`~astropy.coordinates.SkyCoord.separation` and :meth:`~astropy.coordinates.SkyCoord.position_angle` thus give a set of directional offsets. To do the inverse operation — determining the new "destination" coordinate given a separation and position angle — the :meth:`~astropy.coordinates.SkyCoord.directional_offset_by` method is provided:: >>> c1 = SkyCoord(1*u.deg, 1*u.deg, frame='icrs') >>> position_angle = 45 * u.deg >>> separation = 1.414 * u.deg >>> c1.directional_offset_by(position_angle, separation) # doctest: +FLOAT_CMP This technique is also useful for computing the midpoint (or indeed any point) between two coordinates in a way that accounts for spherical geometry (i.e., instead of averaging the RAs/Decs separately):: >>> coord1 = SkyCoord(0*u.deg, 0*u.deg, frame='icrs') >>> coord2 = SkyCoord(1*u.deg, 1*u.deg, frame='icrs') >>> pa = coord1.position_angle(coord2) >>> sep = coord1.separation(coord2) >>> coord1.directional_offset_by(pa, sep/2) # doctest: +FLOAT_CMP There is also a :meth:`~astropy.coordinates.SkyCoord.spherical_offsets_to` method for computing angular offsets (e.g., small shifts like you might give a telescope operator to move from a bright star to a fainter target):: >>> bright_star = SkyCoord('8h50m59.75s', '+11d39m22.15s', frame='icrs') >>> faint_galaxy = SkyCoord('8h50m47.92s', '+11d39m32.74s', frame='icrs') >>> dra, ddec = bright_star.spherical_offsets_to(faint_galaxy) >>> dra.to(u.arcsec) # doctest: +FLOAT_CMP >>> ddec.to(u.arcsec) # doctest: +FLOAT_CMP The conceptual inverse of :meth:`~astropy.coordinates.SkyCoord.spherical_offsets_to` is also available as a method on any |SkyCoord| object: :meth:`~astropy.coordinates.SkyCoord.spherical_offsets_by`, which accepts two angular offsets (in longitude and latitude) and returns the coordinates at the offset location:: >>> target_star = SkyCoord(86.75309*u.deg, -31.5633*u.deg, frame='icrs') >>> target_star.spherical_offsets_by(1.3*u.arcmin, -0.7*u.arcmin) # doctest: +FLOAT_CMP .. _astropy-skyoffset-frames: "Sky Offset" Frames ------------------- To extend the concept of spherical offsets, `~astropy.coordinates` has a frame class :class:`~astropy.coordinates.builtin_frames.skyoffset.SkyOffsetFrame` which creates distinct frames that are centered on a specific point. These are known as "sky offset frames," as they are a convenient way to create a frame centered on an arbitrary position on the sky suitable for computing positional offsets (e.g., for astrometry):: >>> from astropy.coordinates import SkyOffsetFrame, ICRS >>> center = ICRS(10*u.deg, 45*u.deg) >>> center.transform_to(SkyOffsetFrame(origin=center)) # doctest: +FLOAT_CMP ): (lon, lat) in deg (0., 0.)> >>> target = ICRS(11*u.deg, 46*u.deg) >>> target.transform_to(SkyOffsetFrame(origin=center)) # doctest: +FLOAT_CMP ): (lon, lat) in deg (0.69474685, 1.00428706)> Alternatively, the convenience method :meth:`~astropy.coordinates.SkyCoord.skyoffset_frame` lets you create a sky offset frame from an existing |SkyCoord|:: >>> center = SkyCoord(10*u.deg, 45*u.deg) >>> aframe = center.skyoffset_frame() >>> target.transform_to(aframe) # doctest: +FLOAT_CMP ): (lon, lat) in deg (0.69474685, 1.00428706)> >>> other = SkyCoord(9*u.deg, 44*u.deg, frame='fk5') >>> other.transform_to(aframe) # doctest: +FLOAT_CMP ): (lon, lat) in deg (-0.71943945, -0.99556216)> .. note :: While sky offset frames *appear* to be all the same class, this not the case: the sky offset frame for each different type of frame for ``origin`` is actually a distinct class. E.g., ``SkyOffsetFrame(origin=ICRS(...))`` yields an object of class ``SkyOffsetICRS``, *not* ``SkyOffsetFrame``. While this is not important for most uses of this class, it is important for things like type-checking, because something like ``SkyOffsetFrame(origin=ICRS(...)).__class__ is SkyOffsetFrame`` will *not* be ``True``, as it would be for most classes. This same frame is also useful as a tool for defining frames that are relative to a specific, known object useful for hierarchical physical systems like galaxy groups. For example, objects around M31 are sometimes shown in a coordinate frame aligned with standard ICRA RA/Dec, but on M31:: >>> m31 = SkyCoord(10.6847083*u.deg, 41.26875*u.deg, frame='icrs') >>> ngc147 = SkyCoord(8.3005*u.deg, 48.5087389*u.deg, frame='icrs') >>> ngc147_inm31 = ngc147.transform_to(m31.skyoffset_frame()) >>> xi, eta = ngc147_inm31.lon, ngc147_inm31.lat >>> xi # doctest: +FLOAT_CMP >>> eta # doctest: +FLOAT_CMP .. note:: Currently, distance information in the ``origin`` of a :class:`~astropy.coordinates.builtin_frames.skyoffset.SkyOffsetFrame` is not used to compute any part of the transform. The ``origin`` is only used for on-sky rotation. This may change in the future, however. .. _astropy-coordinates-matching: Matching Catalogs ================= `~astropy.coordinates` leverages the coordinate framework to make it possible to find the closest coordinates in a catalog to a desired set of other coordinates. For example, assuming ``ra1``/``dec1`` and ``ra2``/``dec2`` are NumPy arrays loaded from some file: .. testsetup:: >>> ra1 = [5.3517] >>> dec1 = [-5.2328] >>> distance1 = 1344 >>> ra2 = [6.459] >>> dec2 = [-16.4258] >>> distance2 = 8.611 .. doctest-requires:: scipy >>> c = SkyCoord(ra=ra1*u.degree, dec=dec1*u.degree) >>> catalog = SkyCoord(ra=ra2*u.degree, dec=dec2*u.degree) >>> idx, d2d, d3d = c.match_to_catalog_sky(catalog) The distances returned ``d3d`` are 3-dimensional distances. Unless both source (``c``) and catalog (``catalog``) coordinates have associated distances, this quantity assumes that all sources are at a distance of 1 (dimensionless). You can also find the nearest 3D matches, different from the on-sky separation shown above only when the coordinates were initialized with a ``distance``: .. doctest-requires:: scipy >>> c = SkyCoord(ra=ra1*u.degree, dec=dec1*u.degree, distance=distance1*u.kpc) >>> catalog = SkyCoord(ra=ra2*u.degree, dec=dec2*u.degree, distance=distance2*u.kpc) >>> idx, d2d, d3d = c.match_to_catalog_3d(catalog) Now ``idx`` are indices into ``catalog`` that are the closest objects to each of the coordinates in ``c``, ``d2d`` are the on-sky distances between them, and ``d3d`` are the 3-dimensional distances. Because coordinate objects support indexing, ``idx`` enables easy access to the matched set of coordinates in the catalog: .. doctest-requires:: scipy >>> matches = catalog[idx] >>> (matches.separation_3d(c) == d3d).all() True >>> dra, ddec = c.spherical_offsets_to(matches) This functionality can also be accessed from the :func:`~astropy.coordinates.match_coordinates_sky` and :func:`~astropy.coordinates.match_coordinates_3d` functions. These will work on either |SkyCoord| objects *or* the lower-level frame classes: .. doctest-requires:: scipy >>> from astropy.coordinates import match_coordinates_sky >>> idx, d2d, d3d = match_coordinates_sky(c, catalog) >>> idx, d2d, d3d = match_coordinates_sky(c.frame, catalog.frame) It is possible to impose a separation constraint (e.g., the maximum separation to be considered a match) by creating a boolean mask with ``d2d`` or ``d3d``. For example: .. doctest-requires:: scipy >>> max_sep = 1.0 * u.arcsec >>> idx, d2d, d3d = c.match_to_catalog_3d(catalog) >>> sep_constraint = d2d < max_sep >>> c_matches = c[sep_constraint] >>> catalog_matches = catalog[idx[sep_constraint]] Now, ``c_matches`` and ``catalog_matches`` are the matched sources in ``c`` and ``catalog``, respectively, which are separated by less than 1 arcsecond. .. _astropy-searching-coordinates: Searching around Coordinates ============================ Closely related functionality can be used to search for *all* coordinates within a certain distance (either 3D distance or on-sky) of another set of coordinates. The ``search_around_*`` methods (and functions) provide this functionality, with an interface very similar to ``match_coordinates_*``: .. doctest-requires:: scipy >>> import numpy as np >>> idxc, idxcatalog, d2d, d3d = catalog.search_around_sky(c, 1*u.deg) >>> np.all(d2d < 1*u.deg) True .. doctest-requires:: scipy >>> idxc, idxcatalog, d2d, d3d = catalog.search_around_3d(c, 1*u.kpc) >>> np.all(d3d < 1*u.kpc) True The key difference for these methods is that there can be multiple (or no) matches in ``catalog`` around any locations in ``c``. Hence, indices into both ``c`` and ``catalog`` are returned instead of just indices into ``catalog``. These can then be indexed back into the two |SkyCoord| objects, or, for that matter, any array with the same order: .. doctest-requires:: scipy >>> np.all(c[idxc].separation(catalog[idxcatalog]) == d2d) True >>> np.all(c[idxc].separation_3d(catalog[idxcatalog]) == d3d) True >>> print(catalog_objectnames[idxcatalog]) #doctest: +SKIP ['NGC 1234' 'NGC 4567' ...] Note, though, that this dual-indexing means that ``search_around_*`` does not work well if one of the coordinates is a scalar, because the returned index would not make sense for a scalar:: >>> scalarc = SkyCoord(ra=1*u.deg, dec=2*u.deg, distance=distance1*u.kpc) >>> idxscalarc, idxcatalog, d2d, d3d = catalog.search_around_sky(scalarc, 1*u.deg) # doctest: +SKIP ValueError: One of the inputs to search_around_sky is a scalar. As a result (and because the ``search_around_*`` algorithm is inefficient in the scalar case), the best approach for this scenario is to instead use the ``separation*`` methods: .. doctest-requires:: scipy >>> d2d = scalarc.separation(catalog) >>> catalogmsk = d2d < 1*u.deg >>> d3d = scalarc.separation_3d(catalog) >>> catalog3dmsk = d3d < 1*u.kpc The resulting ``catalogmsk`` or ``catalog3dmsk`` variables are boolean arrays rather than arrays of indices, but in practice they usually can be used in the same way as ``idxcatalog`` from the above examples. If you definitely do need indices instead of boolean masks, you can do: .. doctest-requires:: scipy >>> idxcatalog = np.where(catalogmsk)[0] >>> idxcatalog3d = np.where(catalog3dmsk)[0] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/coordinates/performance.inc.rst0000644000175100001710000001700500000000000021315 0ustar00vstsdocker.. note that if this is changed from the default approach of using an *include* (in index.rst) to a separate performance page, the header needs to be changed from === to ***, the filename extension needs to be changed from .inc.rst to .rst, and a link needs to be added in the subpackage toctree .. _astropy-coordinates-performance: Performance Tips ================ If you are using |SkyCoord| for many different coordinates, you will see much better performance if you create a single |SkyCoord| with arrays of coordinates as opposed to creating individual |SkyCoord| objects for each individual coordinate:: >>> coord = SkyCoord(ra_array, dec_array, unit='deg') # doctest: +SKIP In addition, looping over a |SkyCoord| object can be slow. If you need to transform the coordinates to a different frame, it is much faster to transform a single |SkyCoord| with arrays of values as opposed to looping over the |SkyCoord| and transforming them individually. Finally, for more advanced users, note that you can use broadcasting to transform |SkyCoord| objects into frames with vector properties. Example ------- .. EXAMPLE START Performance Tips for Transforming SkyCoord Objects To use broadcasting to transform |SkyCoord| objects into frames with vector properties:: >>> from astropy.coordinates import SkyCoord, EarthLocation >>> from astropy import coordinates as coord >>> from astropy.coordinates.angle_utilities import golden_spiral_grid >>> from astropy.time import Time >>> from astropy import units as u >>> import numpy as np >>> # 1000 locations in a grid on the sky >>> coos = SkyCoord(golden_spiral_grid(size=1000)) >>> # 300 times over the space of 10 hours >>> times = Time.now() + np.linspace(-5, 5, 300)*u.hour >>> # note the use of broadcasting so that 300 times are broadcast against 1000 positions >>> lapalma = EarthLocation.from_geocentric(5327448.9957829, -1718665.73869569, 3051566.90295403, unit='m') >>> aa_frame = coord.AltAz(obstime=times[:, np.newaxis], location=lapalma) >>> # calculate alt-az of each object at each time. >>> aa_coos = coos.transform_to(aa_frame) # doctest: +REMOTE_DATA +IGNORE_WARNINGS .. EXAMPLE END Improving Performance for Arrays of ``obstime`` ----------------------------------------------- The most expensive operations when transforming between observer-dependent coordinate frames (e.g. ``AltAz``) and sky-fixed frames (e.g. ``ICRS``) are the calculation of the orientation and position of Earth. If |SkyCoord| instances are transformed for a large number of closely spaced ``obstime``, these calculations can be sped up by factors up to 100, whilst still keeping micro-arcsecond precision, by utilizing interpolation instead of calculating Earth orientation parameters for each individual point. .. EXAMPLE START Improving performance for obstime arrays To use interpolation for the astrometric values in coordinate transformation, use:: >>> from astropy.coordinates import SkyCoord, EarthLocation, AltAz >>> from astropy.coordinates.erfa_astrom import erfa_astrom, ErfaAstromInterpolator >>> from astropy.time import Time >>> from time import perf_counter >>> import numpy as np >>> import astropy.units as u >>> # array with 10000 obstimes >>> obstime = Time('2010-01-01T20:00') + np.linspace(0, 6, 10000) * u.hour >>> location = location = EarthLocation(lon=-17.89 * u.deg, lat=28.76 * u.deg, height=2200 * u.m) >>> frame = AltAz(obstime=obstime, location=location) >>> crab = SkyCoord(ra='05h34m31.94s', dec='22d00m52.2s') >>> # transform with default transformation and print duration >>> t0 = perf_counter() >>> crab_altaz = crab.transform_to(frame) # doctest:+IGNORE_WARNINGS +REMOTE_DATA >>> print(f'Transformation took {perf_counter() - t0:.2f} s') # doctest:+IGNORE_OUTPUT Transformation took 1.77 s >>> # transform with interpolating astrometric values >>> t0 = perf_counter() >>> with erfa_astrom.set(ErfaAstromInterpolator(300 * u.s)): # doctest:+REMOTE_DATA ... crab_altaz_interpolated = crab.transform_to(frame) # doctest:+IGNORE_WARNINGS +REMOTE_DATA >>> print(f'Transformation took {perf_counter() - t0:.2f} s') # doctest:+IGNORE_OUTPUT Transformation took 0.03 s >>> err = crab_altaz.separation(crab_altaz_interpolated) # doctest:+IGNORE_WARNINGS +REMOTE_DATA >>> print(f'Mean error of interpolation: {err.to(u.microarcsecond).mean():.4f}') # doctest:+ELLIPSIS +REMOTE_DATA Mean error of interpolation: 0.0... uarcsec >>> # To set erfa_astrom for a whole session, use it without context manager: >>> erfa_astrom.set(ErfaAstromInterpolator(300 * u.s)) # doctest:+SKIP .. EXAMPLE END Here, we look into choosing an appropriate ``time_resolution``. We will transform a single sky coordinate for lots of observation times from ``ICRS`` to ``AltAz`` and evaluate precision and runtime for different values for ``time_resolution`` compared to the non-interpolating, default approach. .. plot:: :include-source: :context: reset from time import perf_counter import numpy as np import matplotlib.pyplot as plt from astropy.coordinates.erfa_astrom import erfa_astrom, ErfaAstromInterpolator from astropy.coordinates import SkyCoord, EarthLocation, AltAz from astropy.time import Time import astropy.units as u np.random.seed(1337) # 100_000 times randomly distributed over 12 hours t = Time('2020-01-01T20:00:00') + np.random.uniform(0, 1, 10_000) * u.hour location = location = EarthLocation( lon=-17.89 * u.deg, lat=28.76 * u.deg, height=2200 * u.m ) # A celestial object in ICRS crab = SkyCoord.from_name("Crab Nebula") # target horizontal coordinate frame altaz = AltAz(obstime=t, location=location) # the reference transform using no interpolation t0 = perf_counter() no_interp = crab.transform_to(altaz) reference = perf_counter() - t0 print(f'No Interpolation took {reference:.4f} s') # now the interpolating approach for different time resolutions resolutions = 10.0**np.arange(-1, 5) * u.s times = [] seps = [] for resolution in resolutions: with erfa_astrom.set(ErfaAstromInterpolator(resolution)): t0 = perf_counter() interp = crab.transform_to(altaz) duration = perf_counter() - t0 print( f'Interpolation with {resolution.value: 9.1f} {str(resolution.unit)}' f' resolution took {duration:.4f} s' f' ({reference / duration:5.1f}x faster) ' ) seps.append(no_interp.separation(interp)) times.append(duration) seps = u.Quantity(seps) fig = plt.figure() ax1, ax2 = fig.subplots(2, 1, gridspec_kw={'height_ratios': [2, 1]}, sharex=True) ax1.plot( resolutions.to_value(u.s), seps.mean(axis=1).to_value(u.microarcsecond), 'o', label='mean', ) for p in [25, 50, 75, 95]: ax1.plot( resolutions.to_value(u.s), np.percentile(seps.to_value(u.microarcsecond), p, axis=1), 'o', label=f'{p}%', color='C1', alpha=p / 100, ) ax1.set_title('Transformation of SkyCoord with 100.000 obstimes over 12 hours') ax1.legend() ax1.set_xscale('log') ax1.set_yscale('log') ax1.set_ylabel('Angular distance to no interpolation / Âĩas') ax2.plot(resolutions.to_value(u.s), reference / np.array(times), 's') ax2.set_yscale('log') ax2.set_ylabel('Speedup') ax2.set_xlabel('time resolution / s') ax2.yaxis.grid() fig.tight_layout() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/coordinates/remote_methods.rst0000644000175100001710000000635200000000000021265 0ustar00vstsdocker.. _astropy-coordinates-remote: Usage Tips/Suggestions for Methods That Access Remote Resources *************************************************************** There are currently two methods that rely on getting remote data to work. The first is the :class:`~astropy.coordinates.SkyCoord` :meth:`~astropy.coordinates.SkyCoord.from_name` method, which uses `Sesame `_ to retrieve coordinates for a particular named object:: >>> from astropy.coordinates import SkyCoord >>> SkyCoord.from_name("PSR J1012+5307") # doctest: +REMOTE_DATA +FLOAT_CMP .. testsetup:: >>> from astropy.coordinates import EarthLocation >>> apo = EarthLocation(-1463969.3018517173, -5166673.342234327, 3434985.7120456537, unit='m') The second is the :class:`~astropy.coordinates.EarthLocation` :meth:`~astropy.coordinates.EarthLocation.of_site` method, which provides a similar quick way to get an :class:`~astropy.coordinates.EarthLocation` from an observatory name:: >>> from astropy.coordinates import EarthLocation >>> apo = EarthLocation.of_site('Apache Point Observatory') # doctest: +SKIP >>> apo # doctest: +FLOAT_CMP The full list of available observatory names can be obtained with :meth:`astropy.coordinates.EarthLocation.get_site_names`. .. testsetup:: >>> loc = EarthLocation(-1994502.60430614, -5037538.54232911, 3358104.99690298, unit='m') While these methods are convenient, there are several considerations to take into account: * Since these methods access online data, the data may evolve over time (for example, the accuracy of coordinates might improve, and new observatories may be added). Therefore, this means that a script using these and currently running may give a different answer in five years. Therefore, users concerned with reproducibility should not use these methods in their final scripts, but can instead use them to get the values required, and then hard-code them into the scripts. For example, we can check the coordinates of the Kitt Peak Observatories using:: >>> loc = EarthLocation.of_site('Kitt Peak') # doctest: +SKIP Note that this command requires an internet connection. We can then view the actual Cartesian coordinates for the observatory: >>> loc # doctest: +FLOAT_CMP This can then be converted into code:: >>> loc = EarthLocation(-1994502.6043061386, -5037538.54232911, 3358104.9969029757, unit='m') This latter line can then be included in a script and will ensure that the results stay the same over time. * The online data may not be accurate enough for your purposes. If maximum accuracy is paramount, we recommend that you determine the celestial or Earth coordinates yourself and hard-code these, rather than using the convenience methods. * These methods will not function if an internet connection is not available. Therefore, if you need to work on a script while offline, follow the instructions in the first bullet point above to hard-code the coordinates before going offline. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/coordinates/representations.rst0000644000175100001710000006705700000000000021505 0ustar00vstsdocker.. _astropy-coordinates-representations: Using and Designing Coordinate Representations ********************************************** Points in a 3D vector space can be represented in different ways, such as Cartesian, spherical polar, cylindrical, and so on. These underlie the way coordinate data in `astropy.coordinates` is represented, as described in the :ref:`astropy-coordinates-overview`. Below, we describe how you can use them on their own as a way to convert between different representations, including ones not built-in, and to do simple vector arithmetic. The built-in representation classes are: * `~astropy.coordinates.CartesianRepresentation`: Cartesian coordinates ``x``, ``y``, and ``z``. * `~astropy.coordinates.SphericalRepresentation`: spherical polar coordinates represented by a longitude (``lon``), a latitude (``lat``), and a distance (``distance``). The latitude is a value ranging from -90 to 90 degrees. * `~astropy.coordinates.UnitSphericalRepresentation`: spherical polar coordinates on a unit sphere, represented by a longitude (``lon``) and latitude (``lat``). * `~astropy.coordinates.PhysicsSphericalRepresentation`: spherical polar coordinates, represented by an inclination (``theta``) and azimuthal angle (``phi``), and radius ``r``. The inclination goes from 0 to 180 degrees, and is related to the latitude in the `~astropy.coordinates.SphericalRepresentation` by ``theta = 90 deg - lat``. * `~astropy.coordinates.CylindricalRepresentation`: cylindrical polar coordinates, represented by a cylindrical radius (``rho``), azimuthal angle (``phi``), and height (``z``). .. Note:: For information about using and changing the representation of `~astropy.coordinates.SkyCoord` objects, see the :ref:`astropy-skycoord-representations` section. Instantiating and Converting ============================ Representation classes are instantiated with `~astropy.units.Quantity` objects:: >>> from astropy import units as u >>> from astropy.coordinates.representation import CartesianRepresentation >>> car = CartesianRepresentation(3 * u.kpc, 5 * u.kpc, 4 * u.kpc) >>> car # doctest: +FLOAT_CMP Array `~astropy.units.Quantity` objects can also be passed to representations. They will have the expected shape, which can be changed using methods with the same names as those for `~numpy.ndarray`, such as ``reshape``, ``ravel``, etc.:: >>> x = u.Quantity([[1., 0., 0.], [3., 5., 3.]], u.m) >>> y = u.Quantity([[0., 2., 0.], [4., 0., -4.]], u.m) >>> z = u.Quantity([[0., 0., 3.], [0., 12., -12.]], u.m) >>> car_array = CartesianRepresentation(x, y, z) >>> car_array # doctest: +FLOAT_CMP >>> car_array.shape (2, 3) >>> car_array.ravel() # doctest: +FLOAT_CMP Representations can be converted to other representations using the ``represent_as`` method:: >>> from astropy.coordinates.representation import SphericalRepresentation, CylindricalRepresentation >>> sph = car.represent_as(SphericalRepresentation) >>> sph # doctest: +FLOAT_CMP >>> cyl = car.represent_as(CylindricalRepresentation) >>> cyl # doctest: +FLOAT_CMP All representations can be converted to each other without loss of information, with the exception of `~astropy.coordinates.UnitSphericalRepresentation`. This class is used to store the longitude and latitude of points but does not contain any distance to the points, and assumes that they are located on a unit and dimensionless sphere:: >>> from astropy.coordinates.representation import UnitSphericalRepresentation >>> sph_unit = car.represent_as(UnitSphericalRepresentation) >>> sph_unit # doctest: +FLOAT_CMP Converting back to Cartesian, the absolute scaling information has been removed, and the points are still located on a unit sphere:: >>> sph_unit = car.represent_as(UnitSphericalRepresentation) >>> sph_unit.represent_as(CartesianRepresentation) # doctest: +FLOAT_CMP Array Values and NumPy Array Method Analogs =========================================== Array `~astropy.units.Quantity` objects can also be passed to representations, and such representations can be sliced, reshaped, etc., using the same methods as are available to `~numpy.ndarray`. Corresponding functions, as well as others that affect the shape, such as `~numpy.atleast_1d` and `~numpy.rollaxis`, work as expected. Example ------- .. EXAMPLE START Array Values and NumPy Array Method Analogs To pass array `~astropy.units.Quantity` objects to representations:: >>> import numpy as np >>> x = np.linspace(0., 5., 6) >>> y = np.linspace(10., 15., 6) >>> z = np.linspace(20., 25., 6) >>> car_array = CartesianRepresentation(x * u.m, y * u.m, z * u.m) >>> car_array To manipulate using methods and ``numpy`` functions:: >>> car_array.reshape(3, 2) >>> car_array[2] >>> car_array[2] = car_array[1] >>> car_array[:3] >>> np.roll(car_array, 1) And to set elements using other representation classes (as long as they are compatible in their units and number of dimensions):: >>> car_array[2] = SphericalRepresentation(0*u.deg, 0*u.deg, 99*u.m) >>> car_array[:3] # doctest: +FLOAT_CMP >>> car_array[0] = UnitSphericalRepresentation(0*u.deg, 0*u.deg) Traceback (most recent call last): ... ValueError: value must be representable as CartesianRepresentation without loss of information. .. EXAMPLE END .. _astropy-coordinates-representations-arithmetic: Vector Arithmetic ================= Representations support basic vector arithmetic such as taking the norm, multiplying with and dividing by quantities, and taking dot and cross products, as well as adding, subtracting, summing and taking averages of representations, and multiplying with matrices. .. Note:: All arithmetic except the matrix multiplication works with non-Cartesian representations as well. For taking the norm, multiplication, and division, this uses just the non-angular components, while for the other operations the representation is converted to Cartesian internally before the operation is done, and the result is converted back to the original representation. Hence, for optimal speed it may be best to work using Cartesian representations. Examples -------- .. EXAMPLE START Vector Arithmetic Operations with Representation Objects To see how vector arithmetic operations work with representation objects, consider the following examples:: >>> car_array = CartesianRepresentation([[1., 0., 0.], [3., 5., 3.]] * u.m, ... [[0., 2., 0.], [4., 0., -4.]] * u.m, ... [[0., 0., 3.], [0.,12.,-12.]] * u.m) >>> car_array # doctest: +FLOAT_CMP >>> car_array.norm() # doctest: +FLOAT_CMP >>> car_array / car_array.norm() # doctest: +FLOAT_CMP >>> (car_array[1] - car_array[0]) / (10. * u.s) # doctest: +FLOAT_CMP >>> car_array.sum() # doctest: +FLOAT_CMP >>> car_array.mean(axis=0) # doctest: +FLOAT_CMP >>> unit_x = UnitSphericalRepresentation(0.*u.deg, 0.*u.deg) >>> unit_y = UnitSphericalRepresentation(90.*u.deg, 0.*u.deg) >>> unit_z = UnitSphericalRepresentation(0.*u.deg, 90.*u.deg) >>> car_array.dot(unit_x) # doctest: +FLOAT_CMP >>> car_array.dot(unit_y) # doctest: +FLOAT_CMP >>> car_array.dot(unit_z) # doctest: +FLOAT_CMP >>> car_array.cross(unit_x) # doctest: +FLOAT_CMP >>> from astropy.coordinates.matrix_utilities import rotation_matrix >>> rotation = rotation_matrix(90 * u.deg, axis='z') >>> rotation # doctest: +FLOAT_CMP array([[ 6.12323400e-17, 1.00000000e+00, 0.00000000e+00], [-1.00000000e+00, 6.12323400e-17, 0.00000000e+00], [ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]]) >>> car_array.transform(rotation) # doctest: +FLOAT_CMP .. EXAMPLE END .. _astropy-coordinates-differentials: Differentials and Derivatives of Representations ================================================ In addition to positions in 3D space, coordinates also deal with proper motions and radial velocities, which require a way to represent differentials of coordinates (i.e., finite realizations) of derivatives. To support this, the representations all have corresponding ``Differential`` classes, which can hold offsets or derivatives in terms of the components of the representation class. Adding such an offset to a representation means the offset is taken in the direction of the corresponding coordinate. (Although for any representation other than Cartesian, this is only defined relative to a specific location, as the unit vectors are not invariant.) Examples -------- .. EXAMPLE START Differentials and Derivatives of Representations To see how the ``Differential`` classes of representations works, consider the following:: >>> from astropy.coordinates import SphericalRepresentation, SphericalDifferential >>> sph_coo = SphericalRepresentation(lon=0.*u.deg, lat=0.*u.deg, ... distance=1.*u.kpc) >>> sph_derivative = SphericalDifferential(d_lon=1.*u.arcsec/u.yr, ... d_lat=0.*u.arcsec/u.yr, ... d_distance=0.*u.km/u.s) >>> sph_derivative.to_cartesian(base=sph_coo) # doctest: +FLOAT_CMP Note how the conversion to Cartesian can only be done using a ``base``, since otherwise the code cannot know what direction an increase in longitude corresponds to. For ``lon=0``, this is in the ``y`` direction. Now, to get the coordinates at two later times:: >>> sph_coo + sph_derivative * [1., 3600*180/np.pi] * u.yr # doctest: +FLOAT_CMP The above shows how addition is not to longitude itself, but in the direction of increasing longitude: for the large shift, by the equivalent of one radian, the distance has increased as well (after all, a source will likely not move along a curve on the sky!). This also means that the order of operations is important:: >>> big_offset = SphericalDifferential(1.*u.radian, 0.*u.radian, 0.*u.kpc) >>> sph_coo + big_offset + big_offset # doctest: +FLOAT_CMP >>> sph_coo + (big_offset + big_offset) # doctest: +FLOAT_CMP .. EXAMPLE END .. EXAMPLE START Working with Proper Motions and Radial Velocities in Differential Objects Often, you may have just a proper motion or a radial velocity, but not both:: >>> from astropy.coordinates import UnitSphericalDifferential, RadialDifferential >>> radvel = RadialDifferential(1000*u.km/u.s) >>> sph_coo + radvel * 1. * u.Myr # doctest: +FLOAT_CMP >>> pm = UnitSphericalDifferential(1.*u.mas/u.yr, 0.*u.mas/u.yr) >>> sph_coo + pm * 1. * u.Myr # doctest: +FLOAT_CMP >>> pm + radvel # doctest: +FLOAT_CMP >>> sph_coo + (pm + radvel) * 1. * u.Myr # doctest: +FLOAT_CMP Note in the above that the proper motion is defined strictly as a change in longitude (i.e., it does not include a ``cos(latitude)`` term). There are special classes where this term is included:: >>> from astropy.coordinates import UnitSphericalCosLatDifferential >>> sph_lat60 = SphericalRepresentation(lon=0.*u.deg, lat=60.*u.deg, ... distance=1.*u.kpc) >>> pm = UnitSphericalDifferential(1.*u.mas/u.yr, 0.*u.mas/u.yr) >>> pm # doctest: +FLOAT_CMP >>> pm_coslat = UnitSphericalCosLatDifferential(1.*u.mas/u.yr, 0.*u.mas/u.yr) >>> pm_coslat # doctest: +FLOAT_CMP >>> sph_lat60 + pm * 1. * u.Myr # doctest: +FLOAT_CMP >>> sph_lat60 + pm_coslat * 1. * u.Myr # doctest: +FLOAT_CMP Close inspections shows that indeed the changes are as expected. The systems with and without ``cos(latitude)`` can be converted to each other, provided you supply the ``base`` (representation):: >>> usph_lat60 = sph_lat60.represent_as(UnitSphericalRepresentation) >>> pm_coslat2 = pm.represent_as(UnitSphericalCosLatDifferential, ... base=usph_lat60) >>> pm_coslat2 # doctest: +FLOAT_CMP >>> sph_lat60 + pm_coslat2 * 1. * u.Myr # doctest: +FLOAT_CMP .. Note:: At present, the differential classes are generally meant to work with first derivatives, but they do not check the units of the inputs to enforce this. Passing in second derivatives (e.g., acceleration values with acceleration units) will succeed, but any transformations that occur through re-representation of the differential will not necessarily be correct. .. EXAMPLE END Attaching ``Differential`` Objects to ``Representation`` Objects ================================================================ ``Differential`` objects can be attached to ``Representation`` objects as a way to encapsulate related information into a single object. ``Differential`` objects can be passed in to the initializer of any of the built-in ``Representation`` classes. Example ------- .. EXAMPLE START Attaching Differential Objects to Representation Objects To store a single velocity differential with a position:: >>> from astropy.coordinates import representation as r >>> dif = r.SphericalDifferential(d_lon=1 * u.mas/u.yr, ... d_lat=2 * u.mas/u.yr, ... d_distance=3 * u.km/u.s) >>> rep = r.SphericalRepresentation(lon=0.*u.deg, lat=0.*u.deg, ... distance=1.*u.kpc, ... differentials=dif) >>> rep # doctest: +FLOAT_CMP >>> rep.differentials # doctest: +FLOAT_CMP {'s': } .. EXAMPLE END The ``Differential`` objects are stored as a Python dictionary on the ``Representation`` object with keys equal to the (string) unit with which the differential derivatives are taken (converted to SI). .. EXAMPLE START Differential and Representation Object Storage In this case the key is ``'s'`` (second) because the ``Differential`` units are velocities, a time derivative. Passing a single differential to the ``Representation`` initializer will automatically generate the necessary key and store it in the differentials dictionary, but a dictionary is required to specify multiple differentials:: >>> dif2 = r.SphericalDifferential(d_lon=4 * u.mas/u.yr**2, ... d_lat=5 * u.mas/u.yr**2, ... d_distance=6 * u.km/u.s**2) >>> rep = r.SphericalRepresentation(lon=0.*u.deg, lat=0.*u.deg, ... distance=1.*u.kpc, ... differentials={'s': dif, 's2': dif2}) >>> rep.differentials['s'] # doctest: +FLOAT_CMP >>> rep.differentials['s2'] # doctest: +FLOAT_CMP .. EXAMPLE END .. EXAMPLE START Attaching Differential Objects to a Representation after Creation ``Differential`` objects can also be attached to a ``Representation`` after creation:: >>> rep = r.CartesianRepresentation(x=1 * u.kpc, y=2 * u.kpc, z=3 * u.kpc) >>> dif = r.CartesianDifferential(*[1, 2, 3] * u.km/u.s) >>> rep = rep.with_differentials(dif) >>> rep # doctest: +FLOAT_CMP This works for array data as well, as long as the shape of the ``Differential`` data is the same as that of the ``Representation``:: >>> xyz = np.arange(12).reshape(3, 4) * u.au >>> d_xyz = np.arange(12).reshape(3, 4) * u.km/u.s >>> rep = r.CartesianRepresentation(*xyz) >>> dif = r.CartesianDifferential(*d_xyz) >>> rep = rep.with_differentials(dif) >>> rep # doctest: +FLOAT_CMP .. EXAMPLE END .. EXAMPLE START Converting Positional Data to a New Representation As with a ``Representation`` instance without a differential, to convert the positional data to a new representation, use the ``.represent_as()``:: >>> rep.represent_as(r.SphericalRepresentation) # doctest: +FLOAT_CMP However, by passing just the desired representation class, only the ``Representation`` has changed, and the differentials are dropped. To re-represent both the ``Representation`` and any ``Differential`` objects, you must specify target classes for the ``Differential`` as well:: >>> rep2 = rep.represent_as(r.SphericalRepresentation, r.SphericalDifferential) >>> rep2 # doctest: +FLOAT_CMP >>> rep2.differentials['s'] # doctest: +FLOAT_CMP .. EXAMPLE END .. EXAMPLE START Shape-Changing Operations with Differential Objects Shape-changing operations (e.g., reshapes) are propagated to all ``Differential`` objects because they are guaranteed to have the same shape as their host ``Representation`` object:: >>> rep.shape (4,) >>> rep.differentials['s'].shape (4,) >>> new_rep = rep.reshape(2, 2) >>> new_rep.shape (2, 2) >>> new_rep.differentials['s'].shape (2, 2) This also works for slicing:: >>> new_rep = rep[:2] >>> new_rep.shape (2,) >>> new_rep.differentials['s'].shape (2,) Operations on representations that return `~astropy.units.Quantity` objects (as opposed to other ``Representation`` instances) still work, but only operate on the positional information, for example:: >>> rep.norm() # doctest: +FLOAT_CMP Operations that involve combining or scaling representations or pairs of representation objects that contain differentials will currently fail, but support for some operations may be added in future versions:: >>> rep + rep Traceback (most recent call last): ... TypeError: Operation 'add' is not supported when differentials are attached to a CartesianRepresentation. If you have a ``Representation`` with attached ``Differential`` objects, you can retrieve a copy of the ``Representation`` without the ``Differential`` object and use this ``Differential``-free object for any arithmetic operation:: >>> 15 * rep.without_differentials() # doctest: +FLOAT_CMP .. EXAMPLE END .. _astropy-coordinates-create-repr: Creating Your Own Representations ================================= To create your own representation class, your class must inherit from the `~astropy.coordinates.BaseRepresentation` class. This base has an ``__init__`` method that will put all arguments components through their initializers, verify they can be broadcast against each other, and store the components on ``self`` as the name prefixed with '_'. Furthermore, through its metaclass it provides default properties for the components so that they can be accessed using ``.``. For the machinery to work, the following must be defined: * ``attr_classes`` class attribute (``OrderedDict``): Defines through its keys the names of the components (as well as the default order), and through its values defines the class of which they should be instances (which should be `~astropy.units.Quantity` or a subclass, or anything that can initialize it). * ``from_cartesian`` class method: Takes a `~astropy.coordinates.CartesianRepresentation` object and returns an instance of your class. * ``to_cartesian`` method: Returns a `~astropy.coordinates.CartesianRepresentation` object. * ``__init__`` method (optional): If you want more than the basic initialization and checks provided by the base representation class, or just an explicit signature, you can define your own ``__init__``. In general, it is recommended to stay close to the signature assumed by the base representation, ``__init__(self, comp1, comp2, comp3, copy=True)``, and use ``super`` to call the base representation initializer. Once you do this, you will then automatically be able to call ``represent_as`` to convert other representations to/from your representation class. Your representation will also be available for use in |SkyCoord| and all frame classes. A representation class may also have a ``_unit_representation`` attribute (although it is not required). This attribute points to the appropriate "unit" representation (i.e., a representation that is dimensionless). This is probably only meaningful for subclasses of `~astropy.coordinates.SphericalRepresentation`, where it is assumed that it will be a subclass of `~astropy.coordinates.UnitSphericalRepresentation`. Finally, if you wish to also use offsets in your coordinate system, two further methods should be defined (please see `~astropy.coordinates.SphericalRepresentation` for an example): * ``unit_vectors`` method: Returns a ``dict`` with a `~astropy.coordinates.CartesianRepresentation` of unit vectors in the direction of each component. * ``scale_factors`` method: Returns a ``dict`` with a `~astropy.units.Quantity` for each component with the appropriate physical scale factor for a unit change in that direction. And furthermore you should define a ``Differential`` class based on `~astropy.coordinates.BaseDifferential`. This class only needs to define: * ``base_representation`` attribute: A link back to the representation for which this differential holds. In pseudo-code, this means that a class will look like:: class MyRepresentation(BaseRepresentation): attr_classes = OrderedDict([('comp1', ComponentClass1), ('comp2', ComponentClass2), ('comp3', ComponentClass3)]) # __init__ is optional def __init__(self, comp1, comp2, comp3, copy=True): super().__init__(comp1, comp2, comp3, copy=copy) ... @classmethod def from_cartesian(self, cartesian): ... return MyRepresentation(...) def to_cartesian(self): ... return CartesianRepresentation(...) # if differential motion is needed def unit_vectors(self): ... return {'comp1': CartesianRepresentation(...), 'comp2': CartesianRepresentation(...), 'comp3': CartesianRepresentation(...)} def scale_factors(self): ... return {'comp1': ..., 'comp2': ..., 'comp3': ...} class MyDifferential(BaseDifferential): base_representation = MyRepresentation ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/coordinates/satellites.rst0000644000175100001710000001132100000000000020410 0ustar00vstsdocker.. _astropy-coordinates-satellites: Working with Earth Satellites Using Astropy Coordinates ******************************************************* Satellite data is normally provided in the Two-Line Element (TLE) format (see `here `_ for a definition). These datasets are designed to be used in combination with a theory for orbital propagation model to predict the positions of satellites. The history of such models is discussed in detail in `Vallado et al (2006) `_ who also provide a reference implementation of the SGP4 orbital propagation code, designed to be compatible with the TLE sets provided by the United States Department of Defense, which are available from a source like `Celestrak `_. The output coordinate frame of the SGP4 model is the True Equator, Mean Equinox frame (TEME), which is one of the frames built-in to `astropy.coordinates`. TEME is an Earth-centered inertial frame (i.e., it does not rotate with respect to the stars). Several definitions exist; ``astropy`` uses the implementation described in `Vallado et al (2006) `_. Finding TEME Coordinates from TLE Data ====================================== There is currently no support in `astropy.coordinates` for computing satellite orbits from TLE orbital element sets. Full support for handling TLE files is available in the `Skyfield `_ library, but some advice for dealing with satellite data in ``astropy`` is below. .. EXAMPLE START Using sgp4 to get a TEME coordinate You will need some external library to compute the position and velocity of the satellite from the TLE orbital elements. The `SGP4 `_ library can do this. An example of using this library to find the `~astropy.coordinates.TEME` coordinates of a satellite is: .. doctest-requires:: sgp4 >>> from sgp4.api import Satrec >>> from sgp4.api import SGP4_ERRORS >>> s = '1 25544U 98067A 19343.69339541 .00001764 00000-0 38792-4 0 9991' >>> t = '2 25544 51.6439 211.2001 0007417 17.6667 85.6398 15.50103472202482' >>> satellite = Satrec.twoline2rv(s, t) The ``satellite`` object has a method, ``satellite.sgp4``, that will try to compute the TEME position and velocity at a given time: .. doctest-requires:: sgp4 >>> from astropy.time import Time >>> t = Time(2458827.362605, format='jd') >>> error_code, teme_p, teme_v = satellite.sgp4(t.jd1, t.jd2) # in km and km/s >>> if error_code != 0: ... raise RuntimeError(SGP4_ERRORS[error_code]) Now that we have the position and velocity in kilometers and kilometers per second, we can create a position in the `~astropy.coordinates.TEME` reference frame: .. doctest-requires:: sgp4 >>> from astropy.coordinates import TEME, CartesianDifferential, CartesianRepresentation >>> from astropy import units as u >>> teme_p = CartesianRepresentation(teme_p*u.km) >>> teme_v = CartesianDifferential(teme_v*u.km/u.s) >>> teme = TEME(teme_p.with_differentials(teme_v), obstime=t) .. EXAMPLE END Note how we are careful to set the observed time of the `~astropy.coordinates.TEME` frame to the time at which we calculated satellite position. Transforming TEME to Other Coordinate Systems ============================================= Once you have satellite positions in `~astropy.coordinates.TEME` coordinates they can be transformed into any `astropy.coordinates` frame. For example, to find the overhead latitude, longitude, and height of the satellite: .. EXAMPLE START Transforming TEME .. doctest-requires:: sgp4 >>> from astropy.coordinates import ITRS >>> itrs = teme.transform_to(ITRS(obstime=t)) # doctest: +IGNORE_WARNINGS >>> location = itrs.earth_location >>> location.geodetic # doctest: +FLOAT_CMP GeodeticLocation(lon=, lat=, height=) .. testsetup:: >>> from astropy.coordinates import EarthLocation >>> siding_spring = EarthLocation(-4680888.60272112, 2805218.44653429, -3292788.0804506, unit='m') Or, if you want to find the altitude and azimuth of the satellite from a particular location: .. doctest-requires:: sgp4 >>> from astropy.coordinates import EarthLocation, AltAz >>> siding_spring = EarthLocation.of_site('aao') # doctest: +SKIP >>> aa = teme.transform_to(AltAz(obstime=t, location=siding_spring)) # doctest: +IGNORE_WARNINGS >>> aa.alt # doctest: +FLOAT_CMP >>> aa.az # doctest: +FLOAT_CMP .. EXAMPLE END ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1646921560.0 astropy-5.0.2/docs/coordinates/skycoord.rst0000644000175100001710000014326300000000000020107 0ustar00vstsdocker.. _astropy-coordinates-high-level: Using the SkyCoord High-Level Class *********************************** The |SkyCoord| class provides a simple and flexible user interface for celestial coordinate representation, manipulation, and transformation between coordinate frames. This is a high-level class that serves as a wrapper around the low-level coordinate frame classes like `~astropy.coordinates.ICRS` and `~astropy.coordinates.FK5` which do most of the heavy lifting. The key distinctions between |SkyCoord| and the low-level classes (:doc:`frames`) are as follows: - The |SkyCoord| object can maintain the union of frame attributes for all built-in and user-defined coordinate frames in the ``astropy.coordinates.frame_transform_graph``. Individual frame classes hold only the required attributes (e.g., equinox, observation time, or observer location) for that frame. This means that a transformation from `~astropy.coordinates.FK4` (with equinox and observation time) to `~astropy.coordinates.ICRS` (with neither) and back to `~astropy.coordinates.FK4` via the low-level classes would not remember the original equinox and observation time. Since the |SkyCoord| object stores all attributes, such a round-trip transformation will return to the same coordinate object. - The |SkyCoord| class is more flexible with inputs to accommodate a wide variety of user preferences and available data formats, whereas the frame classes expect to receive quantity-like objects with angular units. - The |SkyCoord| class has a number of convenience methods that are useful in typical analysis. - At present, |SkyCoord| objects can use only coordinate frames that have transformations defined in the ``astropy.coordinates.frame_transform_graph`` transform graph object. Creating SkyCoord Objects ========================= The |SkyCoord| class accepts a wide variety of inputs for initialization. At a minimum, these must provide one or more celestial coordinate values with unambiguous units. Typically you must also specify the coordinate frame, though this is not required. Common patterns are shown below. In this description the values in upper case like ``COORD`` or ``FRAME`` represent inputs which are described in detail in the `Initialization Syntax`_ section. Elements in square brackets like ``[unit=UNIT]`` are optional. :: SkyCoord(COORD, [FRAME], keyword_args ...) SkyCoord(LON, LAT, [frame=FRAME], [unit=UNIT], keyword_args ...) SkyCoord([FRAME], =LON, =LAT, keyword_args ...) The examples below illustrate common ways of initializing a |SkyCoord| object. These all reflect initializing using spherical coordinates, which is the default for all built-in frames. In order to understand working with coordinates using a different representation, such as Cartesian or cylindrical, see the section on `Representations`_. First, some imports:: >>> from astropy.coordinates import SkyCoord # High-level coordinates >>> from astropy.coordinates import ICRS, Galactic, FK4, FK5 # Low-level frames >>> from astropy.coordinates import Angle, Latitude, Longitude # Angles >>> import astropy.units as u >>> import numpy as np Examples -------- .. EXAMPLE START Initializing SkyCoord Objects Using Spherical Coordinates The coordinate values and frame specification can be provided using positional and keyword arguments. First we show positional arguments for RA and Dec:: >>> SkyCoord(10, 20, unit='deg') # Defaults to ICRS # doctest: +FLOAT_CMP >>> SkyCoord([1, 2, 3], [-30, 45, 8], frame='icrs', unit='deg') # doctest: +FLOAT_CMP Notice that the first example above does not explicitly give a frame. In this case, the default is taken to be the ICRS system (approximately correct for "J2000" equatorial coordinates). It is always better to explicitly specify the frame when it is known to be ICRS, however, as anyone reading the code will be better able to understand the intent. String inputs in common formats are acceptable, and the frame can be supplied as either a class type like `~astropy.coordinates.FK4`, an instance of a frame class, a `~astropy.coordinates.SkyCoord` instance (from which the frame will be extracted), or the lowercase version of a frame name as a string, for example, ``"fk4"``:: >>> coords = ["1:12:43.2 +1:12:43", "1 12 43.2 +1 12 43"] >>> sc = SkyCoord(coords, frame=FK4, unit=(u.hourangle, u.deg), obstime="J1992.21") >>> sc = SkyCoord(coords, frame=FK4(obstime="J1992.21"), unit=(u.hourangle, u.deg)) >>> sc = SkyCoord(coords, frame='fk4', unit='hourangle,deg', obstime="J1992.21") >>> sc = SkyCoord("1h12m43.2s", "+1d12m43s", frame=Galactic) # Units from strings >>> sc = SkyCoord("1h12m43.2s +1d12m43s", frame=Galactic) # Units from string >>> sc = SkyCoord(l="1h12m43.2s", b="+1d12m43s", frame='galactic') >>> sc = SkyCoord("1h12.72m +1d12.71m", frame='galactic') Note that frame instances with data and `~astropy.coordinates.SkyCoord` instances can only be passed as frames using the ``frame=`` keyword argument and not as positional arguments. For representations that have ``ra`` and ``dec`` attributes you can supply a coordinate string in a number of other common formats. Examples include:: >>> sc = SkyCoord("15h17+89d15") >>> sc = SkyCoord("275d11m15.6954s+17d59m59.876s") >>> sc = SkyCoord("8 00 -5 00.6", unit=(u.hour, u.deg)) >>> sc = SkyCoord("J080000.00-050036.00", unit=(u.hour, u.deg)) >>> sc = SkyCoord("J1874221.31+122328.03", unit=u.deg) Astropy `~astropy.units.Quantity`-type objects are acceptable and encouraged as a form of input:: >>> ra = Longitude([1, 2, 3], unit=u.deg) # Could also use Angle >>> dec = np.array([4.5, 5.2, 6.3]) * u.deg # Astropy Quantity >>> sc = SkyCoord(ra, dec, frame='icrs') >>> sc = SkyCoord(ra=ra, dec=dec, frame=ICRS, obstime='2001-01-02T12:34:56') Finally, it is possible to initialize from a low-level coordinate frame object. >>> c = FK4(1 * u.deg, 2 * u.deg) >>> sc = SkyCoord(c, obstime='J2010.11', equinox='B1965') # Override defaults A key subtlety highlighted here is that when low-level objects are created they have certain default attribute values. For instance, the `~astropy.coordinates.FK4` frame uses ``equinox='B1950.0`` and ``obstime=equinox`` as defaults. If this object is used to initialize a |SkyCoord| it is possible to override the low-level object attributes that were not explicitly set. If the coordinate above were created with ``c = FK4(1 * u.deg, 2 * u.deg, equinox='B1960')`` then creating a |SkyCoord| with a different ``equinox`` would raise an exception. .. EXAMPLE END Initialization Syntax --------------------- For spherical representations, which are the most common and are the default input format for all built-in frames, the syntax for |SkyCoord| is given below:: SkyCoord(COORD, [FRAME | frame=FRAME], [unit=UNIT], keyword_args ...) SkyCoord(LON, LAT, [DISTANCE], [FRAME | frame=FRAME], [unit=UNIT], keyword_args ...) SkyCoord([FRAME | frame=FRAME], =LON, =LAT, [unit=UNIT], keyword_args ...) In the above description, elements in all capital letters (e.g., ``FRAME``) describe a user input of that element type. Elements in square brackets are optional. For nonspherical inputs, see the `Representations`_ section. **LON**, **LAT** Longitude and latitude value can be specified as separate positional arguments. The following options are available for longitude and latitude: - Single angle value: - |Quantity| object - Plain numeric value with ``unit`` keyword specifying the unit - Angle string which is formatted for :ref:`angle-creation` of |Longitude| or |Latitude| objects - List or |Quantity| array, or NumPy array of angle values - |Angle|, |Longitude|, or |Latitude| object, which can be scalar or array-valued .. note:: While |SkyCoord| is flexible with respect to specifying longitude and latitude component inputs, the frame classes expect to receive |Quantity|-like objects with angular units (i.e., |Angle| or |Quantity|). For example, when specifying components, the frame classes (e.g., ``ICRS``) must be created as >>> ICRS(0 * u.deg, 0 * u.deg) # doctest: +FLOAT_CMP and other methods of flexible initialization (that work with |SkyCoord|) will not work >>> ICRS(0, 0, unit=u.deg) # doctest: +SKIP UnitTypeError: Longitude instances require units equivalent to 'rad', but no unit was given. **DISTANCE** The distance to the object from the frame center can be optionally specified: - Single distance value: - |Quantity| or `~astropy.coordinates.Distance` object - Plain numeric value for a dimensionless distance - Plain numeric value with ``unit`` keyword specifying the unit - List, or |Quantity|, or `~astropy.coordinates.Distance` array, or NumPy array of angle values **COORD** This input form uses a single object to supply coordinate data. For the case of spherical coordinate frames, the coordinate can include one or more longitude and latitude pairs in one of the following ways: - Single coordinate string with a LON and LAT value separated by a space. The respective values can be any string which is formatted for :ref:`angle-creation` of |Longitude| or |Latitude| objects, respectively. - List or NumPy array of such coordinate strings. - List of (LON, LAT) tuples, where each LON and LAT are scalars (not arrays). - ``N x 2`` NumPy or |Quantity| array of values where the first column is longitude and the second column is latitude, for example, ``[[270, -30], [355, +85]] * u.deg``. - List of (LON, LAT, DISTANCE) tuples. - ``N x 3`` NumPy or |Quantity| array of values where columns are longitude, latitude, and distance, respectively. The input can also be more generalized objects that are not necessarily represented in the standard spherical coordinates: - Coordinate frame object (e.g., ``FK4(1*u.deg, 2*u.deg, obstime='J2012.2')``). - |SkyCoord| object (which just makes a copy of the object). - `~astropy.coordinates.BaseRepresentation` subclass object like `~astropy.coordinates.SphericalRepresentation`, `~astropy.coordinates.CylindricalRepresentation`, or `~astropy.coordinates.CartesianRepresentation`. **FRAME** This can be a `~astropy.coordinates.BaseCoordinateFrame` frame class, an instance of such a class, or the corresponding string alias. The frame classes that are built in to Astropy are `~astropy.coordinates.ICRS`, `~astropy.coordinates.FK5`, `~astropy.coordinates.FK4`, `~astropy.coordinates.FK4NoETerms`, `~astropy.coordinates.Galactic`, and `~astropy.coordinates.AltAz`. The string aliases are lowercase versions of the class name. If the frame is not supplied then you will see a special ``ICRS`` identifier. This indicates that the frame is unspecified and operations that require comparing coordinates (even within that object) are not allowed. **unit=UNIT** The unit specifier can be one of the following: - `~astropy.units.Unit` object, which is an angular unit that is equivalent to ``Unit('radian')``. - Single string with a valid angular unit name. - 2-tuple of `~astropy.units.Unit` objects or string unit names specifying the LON and LAT unit, respectively (e.g., ``('hourangle', 'degree')``). - Single string with two unit names separated by a comma (e.g., ``'hourangle,degree'``). If only a single unit is provided then it applies to both LON and LAT. **Other keyword arguments** In lieu of positional arguments to specify the longitude and latitude, the frame-specific names can be used as keyword arguments: *ra*, *dec*: **LON**, **LAT** values, optional RA and Dec for frames where these are representation, including [FIXME] `~astropy.coordinates.ICRS`, `~astropy.coordinates.FK5`, `~astropy.coordinates.FK4`, and `~astropy.coordinates.FK4NoETerms`. *l*, *b*: **LON**, **LAT** values, optional Galactic ``l`` and ``b`` for the `~astropy.coordinates.Galactic` frame. The following keywords can be specified for any frame: *distance*: distance quantity-like, optional Distance from reference from center to source *obstime*: time-like, optional Time of observation *equinox*: time-like, optional Coordinate frame equinox If custom user-defined frames are included in the transform graph and they have additional frame attributes, then those attributes can also be set via corresponding keyword arguments in the |SkyCoord| initialization. .. _astropy-coordinates-array-operations: Array Operations ================ It is possible to store arrays of coordinates in a |SkyCoord| object, and manipulations done in this way will be orders of magnitude faster than looping over a list of individual |SkyCoord| objects. Examples -------- .. EXAMPLE START Storing Arrays of Coordinates in a SkyCoord Object To store arrays of coordinates in a |SkyCoord| object:: >>> ra = np.linspace(0, 36000, 1001) * u.deg >>> dec = np.linspace(-90, 90, 1001) * u.deg >>> sc_list = [SkyCoord(r, d, frame='icrs') for r, d in zip(ra, dec)] # doctest: +SKIP >>> timeit sc_gal_list = [c.galactic for c in sc_list] # doctest: +SKIP 1 loops, best of 3: 20.4 s per loop >>> sc = SkyCoord(ra, dec, frame='icrs') >>> timeit sc_gal = sc.galactic # doctest: +SKIP 100 loops, best of 3: 21.8 ms per loop .. EXAMPLE END .. EXAMPLE START Array Operations Using SkyCoord In addition to vectorized transformations, you can do the usual array slicing, dicing, and selection using the same methods and attributes that you use for `~numpy.ndarray` instances. Corresponding functions, as well as others that affect the shape, such as `~numpy.atleast_1d` and `~numpy.rollaxis`, work as expected. (The relevant functions have to be explicitly enabled in ``astropy`` source code; let us know if a ``numpy`` function is not supported that you think should work.):: >>> north_mask = sc.dec > 0 >>> sc_north = sc[north_mask] >>> len(sc_north) 500 >>> sc[2:4] # doctest: +FLOAT_CMP >>> sc[500] >>> sc[0:-1:100].reshape(2, 5) >>> np.roll(sc[::100], 1) Note that similarly to the `~numpy.ndarray` methods, all but ``flatten`` try to use new views of the data, with the data copied only if that is impossible (as discussed, for example, in the documentation for NumPy :func:`~numpy.reshape`). .. EXAMPLE END .. _astropy-coordinates-modifying-in-place: Modifying Coordinate Objects In-place ------------------------------------- Coordinate values in a array-valued |SkyCoord| object can be modified in-place (added in astropy 4.1). This requires that the new values be set from an another |SkyCoord| object that is equivalent in all ways except for the actual coordinate data values. In this way, no frame transformations are required and the item setting operation is extremely robust. Specifically, the right hand ``value`` must be strictly consistent with the object being modified: - Identical class - Equivalent frames (`~astropy.coordinates.BaseCoordinateFrame.is_equivalent_frame`) - Identical representation_types - Identical representation differentials keys - Identical frame attributes - Identical "extra" frame attributes (e.g., ``obstime`` for an ICRS coord) .. EXAMPLE START Modifying an Array of Coordinates in a SkyCoord Object To modify an array of coordinates in a |SkyCoord| object use the same syntax for a numpy array:: >>> sc1 = SkyCoord([1, 2] * u.deg, [3, 4] * u.deg) >>> sc2 = SkyCoord(10 * u.deg, 20 * u.deg) >>> sc1[0] = sc2 >>> sc1 .. EXAMPLE END .. EXAMPLE START Inserting Coordinates into a SkyCoord Object You can insert a scalar or array-valued |SkyCoord| object into another compatible |SkyCoord| object:: >>> sc1 = SkyCoord([1, 2] * u.deg, [3, 4] * u.deg) >>> sc2 = SkyCoord(10 * u.deg, 20 * u.deg) >>> sc1.insert(1, sc2) .. EXAMPLE END With the ability to modify a |SkyCoord| object in-place, all of the :ref:`table_operations` such as joining, stacking, and inserting are functional with |SkyCoord| mixin columns (so long as no masking is required). These methods are relatively slow because they require setting from an existing |SkyCoord| object and they perform extensive validation to ensure that the operation is valid. For some applications it may be necessary to take a different lower-level approach which is described in the section :ref:`astropy-coordinates-fast-in-place`. .. warning:: You may be tempted to try an apparently obvious way of modifying a coordinate object in place by updating the component attributes directly, for example ``sc1.ra[1] = 40 * u.deg``. However, while this will *appear* to give a correct result it does not actually modify the underlying representation data. This is related to the current implementation of performance-based caching. The current cache implementation is similarly unable to handle in-place changes to the representation (``.data``) or frame attributes such as ``.obstime``. Attributes ========== The |SkyCoord| object has a number of useful attributes which come in handy. By digging through these we will learn a little bit about |SkyCoord| and how it works. To begin, one of the most important tools for learning about attributes and methods of objects is "TAB-discovery." From within IPython you can type an object name, the period, and then the key to see what is available. This can often be faster than reading the documentation:: >>> sc = SkyCoord(1, 2, frame='icrs', unit='deg', obstime='2013-01-02 14:25:36') >>> sc. # doctest: +SKIP sc.T sc.match_to_catalog_3d sc.altaz sc.match_to_catalog_sky sc.barycentrictrueecliptic sc.name sc.cartesian sc.ndim sc.cirs sc.obsgeoloc sc.copy sc.obsgeovel sc.data sc.obstime sc.dec sc.obswl sc.default_representation sc.position_angle sc.diagonal sc.precessedgeocentric sc.distance sc.pressure sc.equinox sc.ra sc.fk4 sc.ravel sc.fk4noeterms sc.realize_frame sc.fk5 sc.relative_humidity sc.flatten sc.represent_as sc.frame sc.representation_component_names sc.frame_attributes sc.representation_component_units sc.frame_specific_representation_info sc.representation_info sc.from_name sc.reshape sc.from_pixel sc.roll sc.galactic sc.search_around_3d sc.galactocentric sc.search_around_sky sc.galcen_distance sc.separation sc.gcrs sc.separation_3d sc.geocentrictrueecliptic sc.shape sc.get_constellation sc.size sc.get_frame_attr_names sc.skyoffset_frame sc.guess_from_table sc.spherical sc.has_data sc.spherical_offsets_to sc.hcrs sc.squeeze sc.heliocentrictrueecliptic sc.supergalactic sc.icrs sc.swapaxes sc.info sc.take sc.is_equivalent_frame sc.temperature sc.is_frame_attr_default sc.to_pixel sc.is_transformable_to sc.to_string sc.isscalar sc.transform_to sc.itrs sc.transpose sc.location sc.z_sun Here we see many attributes and methods. The most recognizable may be the longitude and latitude attributes which are named ``ra`` and ``dec`` for the ``ICRS`` frame:: >>> sc.ra # doctest: +FLOAT_CMP >>> sc.dec # doctest: +FLOAT_CMP Next, notice that all of the built-in frame names ``icrs``, ``galactic``, ``fk5``, ``fk4``, and ``fk4noeterms`` are there. Through the magic of Python properties, accessing these attributes calls the object `~astropy.coordinates.SkyCoord.transform_to` method appropriately and returns a new |SkyCoord| object in the requested frame:: >>> sc_gal = sc.galactic >>> sc_gal # doctest: +FLOAT_CMP Other attributes you may recognize are ``distance``, ``equinox``, ``obstime``, and ``shape``. Digging Deeper -------------- *[Casual users can skip this section]* After transforming to Galactic, the longitude and latitude values are now labeled ``l`` and ``b``, following the normal convention for Galactic coordinates. How does the object know what to call its values? The answer lies in some less obvious attributes:: >>> sc_gal.representation_component_names {'l': 'lon', 'b': 'lat', 'distance': 'distance'} >>> sc_gal.representation_component_units {'l': Unit("deg"), 'b': Unit("deg")} >>> sc_gal.representation_type Together these tell the object that ``l`` and ``b`` are the longitude and latitude, and that they should both be displayed in units of degrees as a spherical-type coordinate (and not, for example, a Cartesian coordinate). Furthermore, the frame's ``representation_component_names`` attribute defines the coordinate keyword arguments that |SkyCoord| will accept. Another important attribute is ``frame_attr_names``, which defines the additional attributes that are required to fully define the frame:: >>> sc_fk4 = SkyCoord(1, 2, frame='fk4', unit='deg') >>> sc_fk4.get_frame_attr_names() {'equinox':